2017-11-14 18:38:04 +01:00
// SPDX-License-Identifier: GPL-2.0
2008-02-15 09:19:42 +01:00
/*
* Copyright IBM Corp . 2007
* Author ( s ) : Utz Bacher < utz . bacher @ de . ibm . com > ,
* Frank Pavlic < fpavlic @ de . ibm . com > ,
* Thomas Spatzier < tspat @ de . ibm . com > ,
* Frank Blaschka < frank . blaschka @ de . ibm . com >
*/
2010-03-08 20:36:53 +00:00
# define KMSG_COMPONENT "qeth"
# define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
2008-02-15 09:19:42 +01:00
# include <linux/list.h>
# include <linux/rwsem.h>
# include <asm/ebcdic.h>
# include "qeth_core.h"
static ssize_t qeth_dev_state_show ( struct device * dev ,
struct device_attribute * attr , char * buf )
{
struct qeth_card * card = dev_get_drvdata ( dev ) ;
switch ( card - > state ) {
case CARD_STATE_DOWN :
return sprintf ( buf , " DOWN \n " ) ;
case CARD_STATE_SOFTSETUP :
2019-02-28 18:59:44 +01:00
if ( card - > dev - > flags & IFF_UP )
return sprintf ( buf , " UP (LAN %s) \n " ,
netif_carrier_ok ( card - > dev ) ? " ONLINE " :
" OFFLINE " ) ;
2008-02-15 09:19:42 +01:00
return sprintf ( buf , " SOFTSETUP \n " ) ;
default :
return sprintf ( buf , " UNKNOWN \n " ) ;
}
}
static DEVICE_ATTR ( state , 0444 , qeth_dev_state_show , NULL ) ;
static ssize_t qeth_dev_chpid_show ( struct device * dev ,
struct device_attribute * attr , char * buf )
{
struct qeth_card * card = dev_get_drvdata ( dev ) ;
return sprintf ( buf , " %02X \n " , card - > info . chpid ) ;
}
static DEVICE_ATTR ( chpid , 0444 , qeth_dev_chpid_show , NULL ) ;
static ssize_t qeth_dev_if_name_show ( struct device * dev ,
struct device_attribute * attr , char * buf )
{
struct qeth_card * card = dev_get_drvdata ( dev ) ;
2019-11-14 11:19:24 +01:00
2008-02-15 09:19:42 +01:00
return sprintf ( buf , " %s \n " , QETH_CARD_IFNAME ( card ) ) ;
}
static DEVICE_ATTR ( if_name , 0444 , qeth_dev_if_name_show , NULL ) ;
static ssize_t qeth_dev_card_type_show ( struct device * dev ,
struct device_attribute * attr , char * buf )
{
struct qeth_card * card = dev_get_drvdata ( dev ) ;
return sprintf ( buf , " %s \n " , qeth_get_cardname_short ( card ) ) ;
}
static DEVICE_ATTR ( card_type , 0444 , qeth_dev_card_type_show , NULL ) ;
2017-08-15 17:02:46 +02:00
static const char * qeth_get_bufsize_str ( struct qeth_card * card )
2008-02-15 09:19:42 +01:00
{
if ( card - > qdio . in_buf_size = = 16384 )
return " 16k " ;
else if ( card - > qdio . in_buf_size = = 24576 )
return " 24k " ;
else if ( card - > qdio . in_buf_size = = 32768 )
return " 32k " ;
else if ( card - > qdio . in_buf_size = = 40960 )
return " 40k " ;
else
return " 64k " ;
}
static ssize_t qeth_dev_inbuf_size_show ( struct device * dev ,
struct device_attribute * attr , char * buf )
{
struct qeth_card * card = dev_get_drvdata ( dev ) ;
return sprintf ( buf , " %s \n " , qeth_get_bufsize_str ( card ) ) ;
}
static DEVICE_ATTR ( inbuf_size , 0444 , qeth_dev_inbuf_size_show , NULL ) ;
static ssize_t qeth_dev_portno_show ( struct device * dev ,
struct device_attribute * attr , char * buf )
{
struct qeth_card * card = dev_get_drvdata ( dev ) ;
2018-07-19 12:43:52 +02:00
return sprintf ( buf , " %i \n " , card - > dev - > dev_port ) ;
2008-02-15 09:19:42 +01:00
}
static ssize_t qeth_dev_portno_store ( struct device * dev ,
struct device_attribute * attr , const char * buf , size_t count )
{
struct qeth_card * card = dev_get_drvdata ( dev ) ;
2010-01-11 02:50:50 +00:00
unsigned int portno , limit ;
2010-05-11 19:34:47 +00:00
int rc = 0 ;
2008-02-15 09:19:42 +01:00
2020-09-23 10:36:55 +02:00
rc = kstrtouint ( buf , 16 , & portno ) ;
if ( rc )
return rc ;
if ( portno > QETH_MAX_PORTNO )
return - EINVAL ;
2010-05-11 19:34:47 +00:00
mutex_lock ( & card - > conf_mutex ) ;
2019-02-28 18:59:36 +01:00
if ( card - > state ! = CARD_STATE_DOWN ) {
2010-05-11 19:34:47 +00:00
rc = - EPERM ;
goto out ;
}
2008-02-15 09:19:42 +01:00
2010-01-11 02:50:50 +00:00
limit = ( card - > ssqd . pcnt ? card - > ssqd . pcnt - 1 : card - > ssqd . pcnt ) ;
2010-05-11 19:34:47 +00:00
if ( portno > limit ) {
rc = - EINVAL ;
goto out ;
}
2018-07-19 12:43:51 +02:00
card - > dev - > dev_port = portno ;
2010-05-11 19:34:47 +00:00
out :
mutex_unlock ( & card - > conf_mutex ) ;
return rc ? rc : count ;
2008-02-15 09:19:42 +01:00
}
static DEVICE_ATTR ( portno , 0644 , qeth_dev_portno_show , qeth_dev_portno_store ) ;
static ssize_t qeth_dev_portname_show ( struct device * dev ,
struct device_attribute * attr , char * buf )
{
2015-09-18 16:06:50 +02:00
return sprintf ( buf , " no portname required \n " ) ;
2008-02-15 09:19:42 +01:00
}
static ssize_t qeth_dev_portname_store ( struct device * dev ,
struct device_attribute * attr , const char * buf , size_t count )
{
struct qeth_card * card = dev_get_drvdata ( dev ) ;
2015-09-18 16:06:50 +02:00
dev_warn_once ( & card - > gdev - > dev ,
" portname is deprecated and is ignored \n " ) ;
return count ;
2008-02-15 09:19:42 +01:00
}
static DEVICE_ATTR ( portname , 0644 , qeth_dev_portname_show ,
qeth_dev_portname_store ) ;
static ssize_t qeth_dev_prioqing_show ( struct device * dev ,
struct device_attribute * attr , char * buf )
{
struct qeth_card * card = dev_get_drvdata ( dev ) ;
switch ( card - > qdio . do_prio_queueing ) {
case QETH_PRIO_Q_ING_PREC :
return sprintf ( buf , " %s \n " , " by precedence " ) ;
case QETH_PRIO_Q_ING_TOS :
return sprintf ( buf , " %s \n " , " by type of service " ) ;
2014-04-28 10:05:09 +02:00
case QETH_PRIO_Q_ING_SKB :
return sprintf ( buf , " %s \n " , " by skb-priority " ) ;
case QETH_PRIO_Q_ING_VLAN :
return sprintf ( buf , " %s \n " , " by VLAN headers " ) ;
2008-02-15 09:19:42 +01:00
default :
return sprintf ( buf , " always queue %i \n " ,
card - > qdio . default_out_queue ) ;
}
}
static ssize_t qeth_dev_prioqing_store ( struct device * dev ,
struct device_attribute * attr , const char * buf , size_t count )
{
struct qeth_card * card = dev_get_drvdata ( dev ) ;
2010-05-11 19:34:47 +00:00
int rc = 0 ;
2008-02-15 09:19:42 +01:00
2020-03-18 13:54:47 +01:00
if ( IS_IQD ( card ) | | IS_VM_NIC ( card ) )
2019-04-17 18:17:32 +02:00
return - EOPNOTSUPP ;
2010-05-11 19:34:47 +00:00
mutex_lock ( & card - > conf_mutex ) ;
2019-02-28 18:59:36 +01:00
if ( card - > state ! = CARD_STATE_DOWN ) {
2010-05-11 19:34:47 +00:00
rc = - EPERM ;
goto out ;
}
2008-02-15 09:19:42 +01:00
/* check if 1920 devices are supported ,
* if though we have to permit priority queueing
*/
if ( card - > qdio . no_out_queues = = 1 ) {
card - > qdio . do_prio_queueing = QETH_PRIOQ_DEFAULT ;
2010-05-11 19:34:47 +00:00
rc = - EPERM ;
goto out ;
2008-02-15 09:19:42 +01:00
}
2015-01-16 14:05:48 +01:00
if ( sysfs_streq ( buf , " prio_queueing_prec " ) ) {
2008-02-15 09:19:42 +01:00
card - > qdio . do_prio_queueing = QETH_PRIO_Q_ING_PREC ;
2014-04-28 10:05:05 +02:00
card - > qdio . default_out_queue = QETH_DEFAULT_QUEUE ;
2015-01-16 14:05:48 +01:00
} else if ( sysfs_streq ( buf , " prio_queueing_skb " ) ) {
2014-04-28 10:05:09 +02:00
card - > qdio . do_prio_queueing = QETH_PRIO_Q_ING_SKB ;
card - > qdio . default_out_queue = QETH_DEFAULT_QUEUE ;
2015-01-16 14:05:48 +01:00
} else if ( sysfs_streq ( buf , " prio_queueing_tos " ) ) {
2008-02-15 09:19:42 +01:00
card - > qdio . do_prio_queueing = QETH_PRIO_Q_ING_TOS ;
2014-04-28 10:05:05 +02:00
card - > qdio . default_out_queue = QETH_DEFAULT_QUEUE ;
2015-01-16 14:05:48 +01:00
} else if ( sysfs_streq ( buf , " prio_queueing_vlan " ) ) {
2018-09-26 18:29:02 +02:00
if ( IS_LAYER3 ( card ) ) {
2019-12-18 16:32:28 +01:00
rc = - EOPNOTSUPP ;
2014-04-28 10:05:09 +02:00
goto out ;
}
card - > qdio . do_prio_queueing = QETH_PRIO_Q_ING_VLAN ;
card - > qdio . default_out_queue = QETH_DEFAULT_QUEUE ;
2015-01-16 14:05:48 +01:00
} else if ( sysfs_streq ( buf , " no_prio_queueing:0 " ) ) {
2020-03-25 10:35:06 +01:00
card - > qdio . do_prio_queueing = QETH_PRIO_Q_ING_FIXED ;
2008-02-15 09:19:42 +01:00
card - > qdio . default_out_queue = 0 ;
2015-01-16 14:05:48 +01:00
} else if ( sysfs_streq ( buf , " no_prio_queueing:1 " ) ) {
2020-03-25 10:35:06 +01:00
card - > qdio . do_prio_queueing = QETH_PRIO_Q_ING_FIXED ;
2008-02-15 09:19:42 +01:00
card - > qdio . default_out_queue = 1 ;
2015-01-16 14:05:48 +01:00
} else if ( sysfs_streq ( buf , " no_prio_queueing:2 " ) ) {
2020-03-25 10:35:06 +01:00
card - > qdio . do_prio_queueing = QETH_PRIO_Q_ING_FIXED ;
2008-02-15 09:19:42 +01:00
card - > qdio . default_out_queue = 2 ;
2015-01-16 14:05:48 +01:00
} else if ( sysfs_streq ( buf , " no_prio_queueing:3 " ) ) {
2020-03-25 10:35:06 +01:00
card - > qdio . do_prio_queueing = QETH_PRIO_Q_ING_FIXED ;
2008-02-15 09:19:42 +01:00
card - > qdio . default_out_queue = 3 ;
2015-01-16 14:05:48 +01:00
} else if ( sysfs_streq ( buf , " no_prio_queueing " ) ) {
2008-02-15 09:19:42 +01:00
card - > qdio . do_prio_queueing = QETH_NO_PRIO_QUEUEING ;
card - > qdio . default_out_queue = QETH_DEFAULT_QUEUE ;
2010-05-11 19:34:47 +00:00
} else
rc = - EINVAL ;
out :
mutex_unlock ( & card - > conf_mutex ) ;
return rc ? rc : count ;
2008-02-15 09:19:42 +01:00
}
static DEVICE_ATTR ( priority_queueing , 0644 , qeth_dev_prioqing_show ,
qeth_dev_prioqing_store ) ;
static ssize_t qeth_dev_bufcnt_show ( struct device * dev ,
struct device_attribute * attr , char * buf )
{
struct qeth_card * card = dev_get_drvdata ( dev ) ;
return sprintf ( buf , " %i \n " , card - > qdio . in_buf_pool . buf_count ) ;
}
static ssize_t qeth_dev_bufcnt_store ( struct device * dev ,
struct device_attribute * attr , const char * buf , size_t count )
{
struct qeth_card * card = dev_get_drvdata ( dev ) ;
2020-03-11 18:07:11 +01:00
unsigned int cnt ;
2010-05-11 19:34:47 +00:00
int rc = 0 ;
2008-02-15 09:19:42 +01:00
2020-09-23 10:36:55 +02:00
rc = kstrtouint ( buf , 10 , & cnt ) ;
if ( rc )
return rc ;
2010-05-11 19:34:47 +00:00
mutex_lock ( & card - > conf_mutex ) ;
2019-02-28 18:59:36 +01:00
if ( card - > state ! = CARD_STATE_DOWN ) {
2010-05-11 19:34:47 +00:00
rc = - EPERM ;
goto out ;
}
2008-02-15 09:19:42 +01:00
2020-09-23 10:36:55 +02:00
cnt = clamp ( cnt , QETH_IN_BUF_COUNT_MIN , QETH_IN_BUF_COUNT_MAX ) ;
2020-03-11 18:07:11 +01:00
rc = qeth_resize_buffer_pool ( card , cnt ) ;
2010-05-11 19:34:47 +00:00
out :
mutex_unlock ( & card - > conf_mutex ) ;
return rc ? rc : count ;
2008-02-15 09:19:42 +01:00
}
static DEVICE_ATTR ( buffer_count , 0644 , qeth_dev_bufcnt_show ,
qeth_dev_bufcnt_store ) ;
static ssize_t qeth_dev_recover_store ( struct device * dev ,
struct device_attribute * attr , const char * buf , size_t count )
{
struct qeth_card * card = dev_get_drvdata ( dev ) ;
2020-05-06 10:09:48 +02:00
bool reset ;
int rc ;
rc = kstrtobool ( buf , & reset ) ;
if ( rc )
return rc ;
2008-02-15 09:19:42 +01:00
2019-02-15 19:22:25 +01:00
if ( ! qeth_card_hw_is_reachable ( card ) )
2008-02-15 09:19:42 +01:00
return - EPERM ;
2020-05-06 10:09:48 +02:00
if ( reset )
rc = qeth_schedule_recovery ( card ) ;
2008-02-15 09:19:42 +01:00
2020-05-06 10:09:48 +02:00
return rc ? rc : count ;
2008-02-15 09:19:42 +01:00
}
static DEVICE_ATTR ( recover , 0200 , NULL , qeth_dev_recover_store ) ;
static ssize_t qeth_dev_performance_stats_show ( struct device * dev ,
struct device_attribute * attr , char * buf )
{
2019-02-15 19:22:29 +01:00
return sprintf ( buf , " 1 \n " ) ;
2008-02-15 09:19:42 +01:00
}
static ssize_t qeth_dev_performance_stats_store ( struct device * dev ,
struct device_attribute * attr , const char * buf , size_t count )
{
struct qeth_card * card = dev_get_drvdata ( dev ) ;
2019-02-15 19:22:29 +01:00
struct qeth_qdio_out_q * queue ;
unsigned int i ;
bool reset ;
int rc ;
2008-02-15 09:19:42 +01:00
2019-02-15 19:22:29 +01:00
rc = kstrtobool ( buf , & reset ) ;
if ( rc )
return rc ;
if ( reset ) {
memset ( & card - > stats , 0 , sizeof ( card - > stats ) ) ;
for ( i = 0 ; i < card - > qdio . no_out_queues ; i + + ) {
queue = card - > qdio . out_qs [ i ] ;
if ( ! queue )
break ;
memset ( & queue - > stats , 0 , sizeof ( queue - > stats ) ) ;
}
}
return count ;
2008-02-15 09:19:42 +01:00
}
static DEVICE_ATTR ( performance_stats , 0644 , qeth_dev_performance_stats_show ,
qeth_dev_performance_stats_store ) ;
static ssize_t qeth_dev_layer2_show ( struct device * dev ,
struct device_attribute * attr , char * buf )
{
struct qeth_card * card = dev_get_drvdata ( dev ) ;
2018-09-26 18:29:02 +02:00
return sprintf ( buf , " %i \n " , card - > options . layer ) ;
2008-02-15 09:19:42 +01:00
}
static ssize_t qeth_dev_layer2_store ( struct device * dev ,
struct device_attribute * attr , const char * buf , size_t count )
{
struct qeth_card * card = dev_get_drvdata ( dev ) ;
2018-07-19 12:43:51 +02:00
struct net_device * ndev ;
2008-02-15 09:19:42 +01:00
enum qeth_discipline_id newdis ;
2020-09-23 10:36:55 +02:00
unsigned int input ;
int rc ;
2008-02-15 09:19:42 +01:00
2020-09-23 10:36:55 +02:00
rc = kstrtouint ( buf , 16 , & input ) ;
if ( rc )
return rc ;
2008-02-15 09:19:42 +01:00
2020-09-23 10:36:55 +02:00
switch ( input ) {
2008-02-15 09:19:42 +01:00
case 0 :
newdis = QETH_DISCIPLINE_LAYER3 ;
break ;
case 1 :
newdis = QETH_DISCIPLINE_LAYER2 ;
break ;
default :
2020-09-23 10:36:55 +02:00
return - EINVAL ;
}
mutex_lock ( & card - > discipline_mutex ) ;
if ( card - > state ! = CARD_STATE_DOWN ) {
rc = - EPERM ;
2010-05-11 19:34:47 +00:00
goto out ;
2008-02-15 09:19:42 +01:00
}
2018-09-26 18:29:02 +02:00
if ( card - > options . layer = = newdis )
2010-05-11 19:34:47 +00:00
goto out ;
2017-06-06 14:33:50 +02:00
if ( card - > info . layer_enforced ) {
2017-05-10 19:07:52 +02:00
/* fixed layer, can't switch */
rc = - EOPNOTSUPP ;
goto out ;
}
if ( card - > discipline ) {
2018-07-19 12:43:51 +02:00
/* start with a new, pristine netdevice: */
ndev = qeth_clone_netdev ( card - > dev ) ;
if ( ! ndev ) {
rc = - ENOMEM ;
goto out ;
}
2017-05-10 19:07:52 +02:00
card - > discipline - > remove ( card - > gdev ) ;
qeth_core_free_discipline ( card ) ;
2018-07-19 12:43:51 +02:00
free_netdev ( card - > dev ) ;
card - > dev = ndev ;
2008-02-15 09:19:42 +01:00
}
rc = qeth_core_load_discipline ( card , newdis ) ;
if ( rc )
2010-05-11 19:34:47 +00:00
goto out ;
2008-02-15 09:19:42 +01:00
2012-05-15 18:02:21 +02:00
rc = card - > discipline - > setup ( card - > gdev ) ;
2017-05-10 19:07:51 +02:00
if ( rc )
qeth_core_free_discipline ( card ) ;
2010-05-11 19:34:47 +00:00
out :
2010-07-22 23:15:05 +00:00
mutex_unlock ( & card - > discipline_mutex ) ;
2010-05-11 19:34:47 +00:00
return rc ? rc : count ;
2008-02-15 09:19:42 +01:00
}
static DEVICE_ATTR ( layer2 , 0644 , qeth_dev_layer2_show ,
qeth_dev_layer2_store ) ;
2009-11-12 00:11:41 +00:00
# define ATTR_QETH_ISOLATION_NONE ("none")
# define ATTR_QETH_ISOLATION_FWD ("forward")
# define ATTR_QETH_ISOLATION_DROP ("drop")
static ssize_t qeth_dev_isolation_show ( struct device * dev ,
struct device_attribute * attr , char * buf )
{
struct qeth_card * card = dev_get_drvdata ( dev ) ;
switch ( card - > options . isolation ) {
case ISOLATION_MODE_NONE :
return snprintf ( buf , 6 , " %s \n " , ATTR_QETH_ISOLATION_NONE ) ;
case ISOLATION_MODE_FWD :
return snprintf ( buf , 9 , " %s \n " , ATTR_QETH_ISOLATION_FWD ) ;
case ISOLATION_MODE_DROP :
return snprintf ( buf , 6 , " %s \n " , ATTR_QETH_ISOLATION_DROP ) ;
default :
return snprintf ( buf , 5 , " %s \n " , " N/A " ) ;
}
}
static ssize_t qeth_dev_isolation_store ( struct device * dev ,
struct device_attribute * attr , const char * buf , size_t count )
{
struct qeth_card * card = dev_get_drvdata ( dev ) ;
enum qeth_ipa_isolation_modes isolation ;
int rc = 0 ;
2010-05-11 19:34:47 +00:00
mutex_lock ( & card - > conf_mutex ) ;
2019-04-25 18:25:57 +02:00
if ( ! IS_OSD ( card ) & & ! IS_OSX ( card ) ) {
2009-11-12 00:11:41 +00:00
rc = - EOPNOTSUPP ;
dev_err ( & card - > gdev - > dev , " Adapter does not "
" support QDIO data connection isolation \n " ) ;
goto out ;
}
/* parse input into isolation mode */
2015-01-16 14:05:48 +01:00
if ( sysfs_streq ( buf , ATTR_QETH_ISOLATION_NONE ) ) {
2009-11-12 00:11:41 +00:00
isolation = ISOLATION_MODE_NONE ;
2015-01-16 14:05:48 +01:00
} else if ( sysfs_streq ( buf , ATTR_QETH_ISOLATION_FWD ) ) {
2009-11-12 00:11:41 +00:00
isolation = ISOLATION_MODE_FWD ;
2015-01-16 14:05:48 +01:00
} else if ( sysfs_streq ( buf , ATTR_QETH_ISOLATION_DROP ) ) {
2009-11-12 00:11:41 +00:00
isolation = ISOLATION_MODE_DROP ;
} else {
rc = - EINVAL ;
goto out ;
}
2020-07-14 16:23:00 +02:00
if ( qeth_card_hw_is_reachable ( card ) )
rc = qeth_setadpparms_set_access_ctrl ( card , isolation ) ;
if ( ! rc )
WRITE_ONCE ( card - > options . isolation , isolation ) ;
2009-11-12 00:11:41 +00:00
out :
2010-05-11 19:34:47 +00:00
mutex_unlock ( & card - > conf_mutex ) ;
2020-07-14 16:23:00 +02:00
return rc ? rc : count ;
2009-11-12 00:11:41 +00:00
}
static DEVICE_ATTR ( isolation , 0644 , qeth_dev_isolation_show ,
2014-07-21 12:54:43 +02:00
qeth_dev_isolation_store ) ;
static ssize_t qeth_dev_switch_attrs_show ( struct device * dev ,
struct device_attribute * attr , char * buf )
{
struct qeth_card * card = dev_get_drvdata ( dev ) ;
struct qeth_switch_info sw_info ;
int rc = 0 ;
2015-01-16 14:05:47 +01:00
if ( ! qeth_card_hw_is_reachable ( card ) )
2014-07-21 12:54:43 +02:00
return sprintf ( buf , " n/a \n " ) ;
rc = qeth_query_switch_attributes ( card , & sw_info ) ;
if ( rc )
return rc ;
if ( ! sw_info . capabilities )
rc = sprintf ( buf , " unknown " ) ;
if ( sw_info . capabilities & QETH_SWITCH_FORW_802_1 )
rc = sprintf ( buf , ( sw_info . settings & QETH_SWITCH_FORW_802_1 ?
" [802.1] " : " 802.1 " ) ) ;
if ( sw_info . capabilities & QETH_SWITCH_FORW_REFL_RELAY )
rc + = sprintf ( buf + rc ,
( sw_info . settings & QETH_SWITCH_FORW_REFL_RELAY ?
" [rr] " : " rr " ) ) ;
rc + = sprintf ( buf + rc , " \n " ) ;
return rc ;
}
static DEVICE_ATTR ( switch_attrs , 0444 ,
qeth_dev_switch_attrs_show , NULL ) ;
2009-11-12 00:11:41 +00:00
2011-05-12 18:45:02 +00:00
static ssize_t qeth_hw_trap_show ( struct device * dev ,
struct device_attribute * attr , char * buf )
{
struct qeth_card * card = dev_get_drvdata ( dev ) ;
if ( card - > info . hwtrap )
return snprintf ( buf , 5 , " arm \n " ) ;
else
return snprintf ( buf , 8 , " disarm \n " ) ;
}
static ssize_t qeth_hw_trap_store ( struct device * dev ,
struct device_attribute * attr , const char * buf , size_t count )
{
struct qeth_card * card = dev_get_drvdata ( dev ) ;
int rc = 0 ;
int state = 0 ;
mutex_lock ( & card - > conf_mutex ) ;
2015-01-16 14:05:47 +01:00
if ( qeth_card_hw_is_reachable ( card ) )
2011-05-12 18:45:02 +00:00
state = 1 ;
2015-01-16 14:05:48 +01:00
if ( sysfs_streq ( buf , " arm " ) & & ! card - > info . hwtrap ) {
2011-05-12 18:45:02 +00:00
if ( state ) {
if ( qeth_is_diagass_supported ( card ,
QETH_DIAGS_CMD_TRAP ) ) {
rc = qeth_hw_trap ( card , QETH_DIAGS_TRAP_ARM ) ;
if ( ! rc )
card - > info . hwtrap = 1 ;
} else
rc = - EINVAL ;
} else
card - > info . hwtrap = 1 ;
2015-01-16 14:05:48 +01:00
} else if ( sysfs_streq ( buf , " disarm " ) & & card - > info . hwtrap ) {
2011-05-12 18:45:02 +00:00
if ( state ) {
rc = qeth_hw_trap ( card , QETH_DIAGS_TRAP_DISARM ) ;
if ( ! rc )
card - > info . hwtrap = 0 ;
} else
card - > info . hwtrap = 0 ;
2015-01-16 14:05:48 +01:00
} else if ( sysfs_streq ( buf , " trap " ) & & state & & card - > info . hwtrap )
2011-05-12 18:45:02 +00:00
rc = qeth_hw_trap ( card , QETH_DIAGS_TRAP_CAPTURE ) ;
else
rc = - EINVAL ;
mutex_unlock ( & card - > conf_mutex ) ;
return rc ? rc : count ;
}
static DEVICE_ATTR ( hw_trap , 0644 , qeth_hw_trap_show ,
qeth_hw_trap_store ) ;
2008-02-15 09:19:42 +01:00
static ssize_t qeth_dev_blkt_store ( struct qeth_card * card ,
const char * buf , size_t count , int * value , int max_value )
{
2020-09-23 10:36:55 +02:00
unsigned int input ;
int rc ;
rc = kstrtouint ( buf , 10 , & input ) ;
if ( rc )
return rc ;
if ( input > max_value )
return - EINVAL ;
2008-02-15 09:19:42 +01:00
2010-05-11 19:34:47 +00:00
mutex_lock ( & card - > conf_mutex ) ;
2020-09-23 10:36:55 +02:00
if ( card - > state ! = CARD_STATE_DOWN )
2010-05-11 19:34:47 +00:00
rc = - EPERM ;
else
2020-09-23 10:36:55 +02:00
* value = input ;
2010-05-11 19:34:47 +00:00
mutex_unlock ( & card - > conf_mutex ) ;
return rc ? rc : count ;
2008-02-15 09:19:42 +01:00
}
static ssize_t qeth_dev_blkt_total_show ( struct device * dev ,
struct device_attribute * attr , char * buf )
{
struct qeth_card * card = dev_get_drvdata ( dev ) ;
2019-11-14 11:19:24 +01:00
return sprintf ( buf , " %i \n " , card - > info . blkt . time_total ) ;
2008-02-15 09:19:42 +01:00
}
static ssize_t qeth_dev_blkt_total_store ( struct device * dev ,
struct device_attribute * attr , const char * buf , size_t count )
{
struct qeth_card * card = dev_get_drvdata ( dev ) ;
return qeth_dev_blkt_store ( card , buf , count ,
2010-01-11 02:50:52 +00:00
& card - > info . blkt . time_total , 5000 ) ;
2008-02-15 09:19:42 +01:00
}
static DEVICE_ATTR ( total , 0644 , qeth_dev_blkt_total_show ,
qeth_dev_blkt_total_store ) ;
static ssize_t qeth_dev_blkt_inter_show ( struct device * dev ,
struct device_attribute * attr , char * buf )
{
struct qeth_card * card = dev_get_drvdata ( dev ) ;
2019-11-14 11:19:24 +01:00
return sprintf ( buf , " %i \n " , card - > info . blkt . inter_packet ) ;
2008-02-15 09:19:42 +01:00
}
static ssize_t qeth_dev_blkt_inter_store ( struct device * dev ,
struct device_attribute * attr , const char * buf , size_t count )
{
struct qeth_card * card = dev_get_drvdata ( dev ) ;
return qeth_dev_blkt_store ( card , buf , count ,
2010-01-11 02:50:52 +00:00
& card - > info . blkt . inter_packet , 1000 ) ;
2008-02-15 09:19:42 +01:00
}
static DEVICE_ATTR ( inter , 0644 , qeth_dev_blkt_inter_show ,
qeth_dev_blkt_inter_store ) ;
static ssize_t qeth_dev_blkt_inter_jumbo_show ( struct device * dev ,
struct device_attribute * attr , char * buf )
{
struct qeth_card * card = dev_get_drvdata ( dev ) ;
2019-11-14 11:19:24 +01:00
return sprintf ( buf , " %i \n " , card - > info . blkt . inter_packet_jumbo ) ;
2008-02-15 09:19:42 +01:00
}
static ssize_t qeth_dev_blkt_inter_jumbo_store ( struct device * dev ,
struct device_attribute * attr , const char * buf , size_t count )
{
struct qeth_card * card = dev_get_drvdata ( dev ) ;
return qeth_dev_blkt_store ( card , buf , count ,
2010-01-11 02:50:52 +00:00
& card - > info . blkt . inter_packet_jumbo , 1000 ) ;
2008-02-15 09:19:42 +01:00
}
static DEVICE_ATTR ( inter_jumbo , 0644 , qeth_dev_blkt_inter_jumbo_show ,
qeth_dev_blkt_inter_jumbo_store ) ;
static struct attribute * qeth_blkt_device_attrs [ ] = {
& dev_attr_total . attr ,
& dev_attr_inter . attr ,
& dev_attr_inter_jumbo . attr ,
NULL ,
} ;
2017-05-10 19:07:52 +02:00
const struct attribute_group qeth_device_blkt_group = {
2008-02-15 09:19:42 +01:00
. name = " blkt " ,
. attrs = qeth_blkt_device_attrs ,
} ;
2017-05-10 19:07:52 +02:00
EXPORT_SYMBOL_GPL ( qeth_device_blkt_group ) ;
2008-02-15 09:19:42 +01:00
static struct attribute * qeth_device_attrs [ ] = {
& dev_attr_state . attr ,
& dev_attr_chpid . attr ,
& dev_attr_if_name . attr ,
& dev_attr_card_type . attr ,
& dev_attr_inbuf_size . attr ,
& dev_attr_portno . attr ,
& dev_attr_portname . attr ,
& dev_attr_priority_queueing . attr ,
& dev_attr_buffer_count . attr ,
& dev_attr_recover . attr ,
& dev_attr_performance_stats . attr ,
& dev_attr_layer2 . attr ,
2009-11-12 00:11:41 +00:00
& dev_attr_isolation . attr ,
2011-05-12 18:45:02 +00:00
& dev_attr_hw_trap . attr ,
2014-07-21 12:54:43 +02:00
& dev_attr_switch_attrs . attr ,
2008-02-15 09:19:42 +01:00
NULL ,
} ;
2017-05-10 19:07:52 +02:00
const struct attribute_group qeth_device_attr_group = {
2008-02-15 09:19:42 +01:00
. attrs = qeth_device_attrs ,
} ;
2017-05-10 19:07:52 +02:00
EXPORT_SYMBOL_GPL ( qeth_device_attr_group ) ;
2008-02-15 09:19:42 +01:00
2012-05-15 18:01:46 +02:00
const struct attribute_group * qeth_generic_attr_groups [ ] = {
& qeth_device_attr_group ,
& qeth_device_blkt_group ,
NULL ,
} ;
2008-02-15 09:19:42 +01:00
static struct attribute * qeth_osn_device_attrs [ ] = {
& dev_attr_state . attr ,
& dev_attr_chpid . attr ,
& dev_attr_if_name . attr ,
& dev_attr_card_type . attr ,
& dev_attr_buffer_count . attr ,
& dev_attr_recover . attr ,
NULL ,
} ;
static struct attribute_group qeth_osn_device_attr_group = {
. attrs = qeth_osn_device_attrs ,
} ;
2012-05-15 18:01:46 +02:00
const struct attribute_group * qeth_osn_attr_groups [ ] = {
& qeth_osn_device_attr_group ,
NULL ,
} ;