2017-11-14 20:38:04 +03:00
// SPDX-License-Identifier: GPL-2.0
2008-02-15 11:19:42 +03: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 23:36:53 +03:00
# define KMSG_COMPONENT "qeth"
# define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
2008-02-15 11:19:42 +03: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 ) ;
if ( ! card )
return - EINVAL ;
switch ( card - > state ) {
case CARD_STATE_DOWN :
return sprintf ( buf , " DOWN \n " ) ;
case CARD_STATE_HARDSETUP :
return sprintf ( buf , " HARDSETUP \n " ) ;
case CARD_STATE_SOFTSETUP :
return sprintf ( buf , " SOFTSETUP \n " ) ;
case CARD_STATE_UP :
2018-09-26 19:29:16 +03:00
return sprintf ( buf , " UP (LAN %s) \n " ,
netif_carrier_ok ( card - > dev ) ? " ONLINE " :
" OFFLINE " ) ;
2008-02-15 11:19:42 +03:00
case CARD_STATE_RECOVER :
return sprintf ( buf , " RECOVER \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 ) ;
if ( ! card )
return - EINVAL ;
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 ) ;
if ( ! card )
return - EINVAL ;
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 ) ;
if ( ! card )
return - EINVAL ;
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 18:02:46 +03:00
static const char * qeth_get_bufsize_str ( struct qeth_card * card )
2008-02-15 11:19:42 +03: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 ) ;
if ( ! card )
return - EINVAL ;
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 ) ;
if ( ! card )
return - EINVAL ;
2018-07-19 13:43:52 +03:00
return sprintf ( buf , " %i \n " , card - > dev - > dev_port ) ;
2008-02-15 11:19:42 +03: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 ) ;
char * tmp ;
2010-01-11 05:50:50 +03:00
unsigned int portno , limit ;
2010-05-11 23:34:47 +04:00
int rc = 0 ;
2008-02-15 11:19:42 +03:00
if ( ! card )
return - EINVAL ;
2010-05-11 23:34:47 +04:00
mutex_lock ( & card - > conf_mutex ) ;
2008-02-15 11:19:42 +03:00
if ( ( card - > state ! = CARD_STATE_DOWN ) & &
2010-05-11 23:34:47 +04:00
( card - > state ! = CARD_STATE_RECOVER ) ) {
rc = - EPERM ;
goto out ;
}
2008-02-15 11:19:42 +03:00
portno = simple_strtoul ( buf , & tmp , 16 ) ;
2010-05-11 23:34:47 +04:00
if ( portno > QETH_MAX_PORTNO ) {
rc = - EINVAL ;
goto out ;
}
2010-01-11 05:50:50 +03:00
limit = ( card - > ssqd . pcnt ? card - > ssqd . pcnt - 1 : card - > ssqd . pcnt ) ;
2010-05-11 23:34:47 +04:00
if ( portno > limit ) {
rc = - EINVAL ;
goto out ;
}
2018-07-19 13:43:51 +03:00
card - > dev - > dev_port = portno ;
2010-05-11 23:34:47 +04:00
out :
mutex_unlock ( & card - > conf_mutex ) ;
return rc ? rc : count ;
2008-02-15 11:19:42 +03: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 17:06:50 +03:00
return sprintf ( buf , " no portname required \n " ) ;
2008-02-15 11:19:42 +03: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 17:06:50 +03:00
dev_warn_once ( & card - > gdev - > dev ,
" portname is deprecated and is ignored \n " ) ;
return count ;
2008-02-15 11:19:42 +03: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 ) ;
if ( ! card )
return - EINVAL ;
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 12:05:09 +04: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 11:19:42 +03: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 23:34:47 +04:00
int rc = 0 ;
2008-02-15 11:19:42 +03:00
if ( ! card )
return - EINVAL ;
2010-05-11 23:34:47 +04:00
mutex_lock ( & card - > conf_mutex ) ;
2008-02-15 11:19:42 +03:00
if ( ( card - > state ! = CARD_STATE_DOWN ) & &
2010-05-11 23:34:47 +04:00
( card - > state ! = CARD_STATE_RECOVER ) ) {
rc = - EPERM ;
goto out ;
}
2008-02-15 11:19:42 +03: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 23:34:47 +04:00
rc = - EPERM ;
goto out ;
2008-02-15 11:19:42 +03:00
}
2015-01-16 16:05:48 +03:00
if ( sysfs_streq ( buf , " prio_queueing_prec " ) ) {
2008-02-15 11:19:42 +03:00
card - > qdio . do_prio_queueing = QETH_PRIO_Q_ING_PREC ;
2014-04-28 12:05:05 +04:00
card - > qdio . default_out_queue = QETH_DEFAULT_QUEUE ;
2015-01-16 16:05:48 +03:00
} else if ( sysfs_streq ( buf , " prio_queueing_skb " ) ) {
2014-04-28 12:05:09 +04:00
card - > qdio . do_prio_queueing = QETH_PRIO_Q_ING_SKB ;
card - > qdio . default_out_queue = QETH_DEFAULT_QUEUE ;
2015-01-16 16:05:48 +03:00
} else if ( sysfs_streq ( buf , " prio_queueing_tos " ) ) {
2008-02-15 11:19:42 +03:00
card - > qdio . do_prio_queueing = QETH_PRIO_Q_ING_TOS ;
2014-04-28 12:05:05 +04:00
card - > qdio . default_out_queue = QETH_DEFAULT_QUEUE ;
2015-01-16 16:05:48 +03:00
} else if ( sysfs_streq ( buf , " prio_queueing_vlan " ) ) {
2018-09-26 19:29:02 +03:00
if ( IS_LAYER3 ( card ) ) {
2014-04-28 12:05:09 +04:00
rc = - ENOTSUPP ;
goto out ;
}
card - > qdio . do_prio_queueing = QETH_PRIO_Q_ING_VLAN ;
card - > qdio . default_out_queue = QETH_DEFAULT_QUEUE ;
2015-01-16 16:05:48 +03:00
} else if ( sysfs_streq ( buf , " no_prio_queueing:0 " ) ) {
2008-02-15 11:19:42 +03:00
card - > qdio . do_prio_queueing = QETH_NO_PRIO_QUEUEING ;
card - > qdio . default_out_queue = 0 ;
2015-01-16 16:05:48 +03:00
} else if ( sysfs_streq ( buf , " no_prio_queueing:1 " ) ) {
2008-02-15 11:19:42 +03:00
card - > qdio . do_prio_queueing = QETH_NO_PRIO_QUEUEING ;
card - > qdio . default_out_queue = 1 ;
2015-01-16 16:05:48 +03:00
} else if ( sysfs_streq ( buf , " no_prio_queueing:2 " ) ) {
2008-02-15 11:19:42 +03:00
card - > qdio . do_prio_queueing = QETH_NO_PRIO_QUEUEING ;
card - > qdio . default_out_queue = 2 ;
2015-01-16 16:05:48 +03:00
} else if ( sysfs_streq ( buf , " no_prio_queueing:3 " ) ) {
2016-06-16 17:19:02 +03:00
if ( card - > info . type = = QETH_CARD_TYPE_IQD ) {
rc = - EPERM ;
goto out ;
}
2008-02-15 11:19:42 +03:00
card - > qdio . do_prio_queueing = QETH_NO_PRIO_QUEUEING ;
card - > qdio . default_out_queue = 3 ;
2015-01-16 16:05:48 +03:00
} else if ( sysfs_streq ( buf , " no_prio_queueing " ) ) {
2008-02-15 11:19:42 +03:00
card - > qdio . do_prio_queueing = QETH_NO_PRIO_QUEUEING ;
card - > qdio . default_out_queue = QETH_DEFAULT_QUEUE ;
2010-05-11 23:34:47 +04:00
} else
rc = - EINVAL ;
out :
mutex_unlock ( & card - > conf_mutex ) ;
return rc ? rc : count ;
2008-02-15 11:19:42 +03: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 ) ;
if ( ! card )
return - EINVAL ;
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 ) ;
char * tmp ;
int cnt , old_cnt ;
2010-05-11 23:34:47 +04:00
int rc = 0 ;
2008-02-15 11:19:42 +03:00
if ( ! card )
return - EINVAL ;
2010-05-11 23:34:47 +04:00
mutex_lock ( & card - > conf_mutex ) ;
2008-02-15 11:19:42 +03:00
if ( ( card - > state ! = CARD_STATE_DOWN ) & &
2010-05-11 23:34:47 +04:00
( card - > state ! = CARD_STATE_RECOVER ) ) {
rc = - EPERM ;
goto out ;
}
2008-02-15 11:19:42 +03:00
old_cnt = card - > qdio . in_buf_pool . buf_count ;
cnt = simple_strtoul ( buf , & tmp , 10 ) ;
cnt = ( cnt < QETH_IN_BUF_COUNT_MIN ) ? QETH_IN_BUF_COUNT_MIN :
( ( cnt > QETH_IN_BUF_COUNT_MAX ) ? QETH_IN_BUF_COUNT_MAX : cnt ) ;
if ( old_cnt ! = cnt ) {
rc = qeth_realloc_buffer_pool ( card , cnt ) ;
}
2010-05-11 23:34:47 +04:00
out :
mutex_unlock ( & card - > conf_mutex ) ;
return rc ? rc : count ;
2008-02-15 11:19:42 +03: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 ) ;
char * tmp ;
int i ;
if ( ! card )
return - EINVAL ;
if ( card - > state ! = CARD_STATE_UP )
return - EPERM ;
i = simple_strtoul ( buf , & tmp , 16 ) ;
if ( i = = 1 )
qeth_schedule_recovery ( card ) ;
return count ;
}
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 )
{
struct qeth_card * card = dev_get_drvdata ( dev ) ;
if ( ! card )
return - EINVAL ;
return sprintf ( buf , " %i \n " , card - > options . performance_stats ? 1 : 0 ) ;
}
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 ) ;
char * tmp ;
2010-05-11 23:34:47 +04:00
int i , rc = 0 ;
2008-02-15 11:19:42 +03:00
if ( ! card )
return - EINVAL ;
2010-05-11 23:34:47 +04:00
mutex_lock ( & card - > conf_mutex ) ;
2008-02-15 11:19:42 +03:00
i = simple_strtoul ( buf , & tmp , 16 ) ;
if ( ( i = = 0 ) | | ( i = = 1 ) ) {
if ( i = = card - > options . performance_stats )
2010-11-26 05:41:18 +03:00
goto out ;
2008-02-15 11:19:42 +03:00
card - > options . performance_stats = i ;
if ( i = = 0 )
memset ( & card - > perf_stats , 0 ,
sizeof ( struct qeth_perf_stats ) ) ;
card - > perf_stats . initial_rx_packets = card - > stats . rx_packets ;
card - > perf_stats . initial_tx_packets = card - > stats . tx_packets ;
2010-05-11 23:34:47 +04:00
} else
rc = - EINVAL ;
out :
mutex_unlock ( & card - > conf_mutex ) ;
return rc ? rc : count ;
2008-02-15 11:19:42 +03: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 ) ;
if ( ! card )
return - EINVAL ;
2018-09-26 19:29:02 +03:00
return sprintf ( buf , " %i \n " , card - > options . layer ) ;
2008-02-15 11:19:42 +03: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 13:43:51 +03:00
struct net_device * ndev ;
2008-02-15 11:19:42 +03:00
char * tmp ;
2010-05-11 23:34:47 +04:00
int i , rc = 0 ;
2008-02-15 11:19:42 +03:00
enum qeth_discipline_id newdis ;
if ( ! card )
return - EINVAL ;
2010-07-23 03:15:05 +04:00
mutex_lock ( & card - > discipline_mutex ) ;
2010-05-11 23:34:47 +04:00
if ( card - > state ! = CARD_STATE_DOWN ) {
rc = - EPERM ;
goto out ;
}
2008-02-15 11:19:42 +03:00
i = simple_strtoul ( buf , & tmp , 16 ) ;
switch ( i ) {
case 0 :
newdis = QETH_DISCIPLINE_LAYER3 ;
break ;
case 1 :
newdis = QETH_DISCIPLINE_LAYER2 ;
break ;
default :
2010-05-11 23:34:47 +04:00
rc = - EINVAL ;
goto out ;
2008-02-15 11:19:42 +03:00
}
2018-09-26 19:29:02 +03:00
if ( card - > options . layer = = newdis )
2010-05-11 23:34:47 +04:00
goto out ;
2017-06-06 15:33:50 +03:00
if ( card - > info . layer_enforced ) {
2017-05-10 20:07:52 +03:00
/* fixed layer, can't switch */
rc = - EOPNOTSUPP ;
goto out ;
}
card - > info . mac_bits = 0 ;
if ( card - > discipline ) {
2018-07-19 13:43:51 +03:00
/* start with a new, pristine netdevice: */
ndev = qeth_clone_netdev ( card - > dev ) ;
if ( ! ndev ) {
rc = - ENOMEM ;
goto out ;
}
2017-05-10 20:07:52 +03:00
card - > discipline - > remove ( card - > gdev ) ;
qeth_core_free_discipline ( card ) ;
2018-07-19 13:43:51 +03:00
free_netdev ( card - > dev ) ;
card - > dev = ndev ;
2008-02-15 11:19:42 +03:00
}
rc = qeth_core_load_discipline ( card , newdis ) ;
if ( rc )
2010-05-11 23:34:47 +04:00
goto out ;
2008-02-15 11:19:42 +03:00
2012-05-15 20:02:21 +04:00
rc = card - > discipline - > setup ( card - > gdev ) ;
2017-05-10 20:07:51 +03:00
if ( rc )
qeth_core_free_discipline ( card ) ;
2010-05-11 23:34:47 +04:00
out :
2010-07-23 03:15:05 +04:00
mutex_unlock ( & card - > discipline_mutex ) ;
2010-05-11 23:34:47 +04:00
return rc ? rc : count ;
2008-02-15 11:19:42 +03:00
}
static DEVICE_ATTR ( layer2 , 0644 , qeth_dev_layer2_show ,
qeth_dev_layer2_store ) ;
2009-11-12 03:11:41 +03: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 ) ;
if ( ! card )
return - EINVAL ;
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 23:34:47 +04:00
if ( ! card )
return - EINVAL ;
2009-11-12 03:11:41 +03:00
2010-05-11 23:34:47 +04:00
mutex_lock ( & card - > conf_mutex ) ;
2010-05-17 01:15:14 +04:00
if ( card - > info . type ! = QETH_CARD_TYPE_OSD & &
2017-10-18 18:40:15 +03:00
card - > info . type ! = QETH_CARD_TYPE_OSX ) {
2009-11-12 03:11:41 +03: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 16:05:48 +03:00
if ( sysfs_streq ( buf , ATTR_QETH_ISOLATION_NONE ) ) {
2009-11-12 03:11:41 +03:00
isolation = ISOLATION_MODE_NONE ;
2015-01-16 16:05:48 +03:00
} else if ( sysfs_streq ( buf , ATTR_QETH_ISOLATION_FWD ) ) {
2009-11-12 03:11:41 +03:00
isolation = ISOLATION_MODE_FWD ;
2015-01-16 16:05:48 +03:00
} else if ( sysfs_streq ( buf , ATTR_QETH_ISOLATION_DROP ) ) {
2009-11-12 03:11:41 +03:00
isolation = ISOLATION_MODE_DROP ;
} else {
rc = - EINVAL ;
goto out ;
}
rc = count ;
/* defer IP assist if device is offline (until discipline->set_online)*/
2013-01-21 06:30:20 +04:00
card - > options . prev_isolation = card - > options . isolation ;
2009-11-12 03:11:41 +03:00
card - > options . isolation = isolation ;
2015-01-16 16:05:47 +03:00
if ( qeth_card_hw_is_reachable ( card ) ) {
2013-01-21 06:30:20 +04:00
int ipa_rc = qeth_set_access_ctrl_online ( card , 1 ) ;
2009-11-12 03:11:41 +03:00
if ( ipa_rc ! = 0 )
rc = ipa_rc ;
}
out :
2010-05-11 23:34:47 +04:00
mutex_unlock ( & card - > conf_mutex ) ;
2009-11-12 03:11:41 +03:00
return rc ;
}
static DEVICE_ATTR ( isolation , 0644 , qeth_dev_isolation_show ,
2014-07-21 14:54:43 +04: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 ;
if ( ! card )
return - EINVAL ;
2015-01-16 16:05:47 +03:00
if ( ! qeth_card_hw_is_reachable ( card ) )
2014-07-21 14:54:43 +04: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 03:11:41 +03:00
2011-05-12 22:45:02 +04: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 )
return - EINVAL ;
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 ;
if ( ! card )
return - EINVAL ;
mutex_lock ( & card - > conf_mutex ) ;
2015-01-16 16:05:47 +03:00
if ( qeth_card_hw_is_reachable ( card ) )
2011-05-12 22:45:02 +04:00
state = 1 ;
2015-01-16 16:05:48 +03:00
if ( sysfs_streq ( buf , " arm " ) & & ! card - > info . hwtrap ) {
2011-05-12 22:45:02 +04: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 16:05:48 +03:00
} else if ( sysfs_streq ( buf , " disarm " ) & & card - > info . hwtrap ) {
2011-05-12 22:45:02 +04: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 16:05:48 +03:00
} else if ( sysfs_streq ( buf , " trap " ) & & state & & card - > info . hwtrap )
2011-05-12 22:45:02 +04: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 11:19:42 +03:00
static ssize_t qeth_dev_blkt_show ( char * buf , struct qeth_card * card , int value )
{
if ( ! card )
return - EINVAL ;
return sprintf ( buf , " %i \n " , value ) ;
}
static ssize_t qeth_dev_blkt_store ( struct qeth_card * card ,
const char * buf , size_t count , int * value , int max_value )
{
char * tmp ;
2010-05-11 23:34:47 +04:00
int i , rc = 0 ;
2008-02-15 11:19:42 +03:00
if ( ! card )
return - EINVAL ;
2010-05-11 23:34:47 +04:00
mutex_lock ( & card - > conf_mutex ) ;
2008-02-15 11:19:42 +03:00
if ( ( card - > state ! = CARD_STATE_DOWN ) & &
2010-05-11 23:34:47 +04:00
( card - > state ! = CARD_STATE_RECOVER ) ) {
rc = - EPERM ;
goto out ;
}
2008-02-15 11:19:42 +03:00
i = simple_strtoul ( buf , & tmp , 10 ) ;
2010-05-11 23:34:47 +04:00
if ( i < = max_value )
2008-02-15 11:19:42 +03:00
* value = i ;
2010-05-11 23:34:47 +04:00
else
rc = - EINVAL ;
out :
mutex_unlock ( & card - > conf_mutex ) ;
return rc ? rc : count ;
2008-02-15 11:19:42 +03: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 ) ;
return qeth_dev_blkt_show ( buf , card , card - > info . blkt . time_total ) ;
}
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 05:50:52 +03:00
& card - > info . blkt . time_total , 5000 ) ;
2008-02-15 11:19:42 +03: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 ) ;
return qeth_dev_blkt_show ( buf , card , card - > info . blkt . inter_packet ) ;
}
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 05:50:52 +03:00
& card - > info . blkt . inter_packet , 1000 ) ;
2008-02-15 11:19:42 +03: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 ) ;
return qeth_dev_blkt_show ( buf , card ,
card - > info . blkt . inter_packet_jumbo ) ;
}
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 05:50:52 +03:00
& card - > info . blkt . inter_packet_jumbo , 1000 ) ;
2008-02-15 11:19:42 +03: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 20:07:52 +03:00
const struct attribute_group qeth_device_blkt_group = {
2008-02-15 11:19:42 +03:00
. name = " blkt " ,
. attrs = qeth_blkt_device_attrs ,
} ;
2017-05-10 20:07:52 +03:00
EXPORT_SYMBOL_GPL ( qeth_device_blkt_group ) ;
2008-02-15 11:19:42 +03: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 03:11:41 +03:00
& dev_attr_isolation . attr ,
2011-05-12 22:45:02 +04:00
& dev_attr_hw_trap . attr ,
2014-07-21 14:54:43 +04:00
& dev_attr_switch_attrs . attr ,
2008-02-15 11:19:42 +03:00
NULL ,
} ;
2017-05-10 20:07:52 +03:00
const struct attribute_group qeth_device_attr_group = {
2008-02-15 11:19:42 +03:00
. attrs = qeth_device_attrs ,
} ;
2017-05-10 20:07:52 +03:00
EXPORT_SYMBOL_GPL ( qeth_device_attr_group ) ;
2008-02-15 11:19:42 +03:00
2012-05-15 20:01:46 +04:00
const struct attribute_group * qeth_generic_attr_groups [ ] = {
& qeth_device_attr_group ,
& qeth_device_blkt_group ,
NULL ,
} ;
2008-02-15 11:19:42 +03: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 20:01:46 +04:00
const struct attribute_group * qeth_osn_attr_groups [ ] = {
& qeth_osn_device_attr_group ,
NULL ,
} ;