Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6

* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6: (1446 commits)
  macvlan: fix panic if lowerdev in a bond
  tg3: Add braces around 5906 workaround.
  tg3: Fix NETIF_F_LOOPBACK error
  macvlan: remove one synchronize_rcu() call
  networking: NET_CLS_ROUTE4 depends on INET
  irda: Fix error propagation in ircomm_lmp_connect_response()
  irda: Kill set but unused variable 'bytes' in irlan_check_command_param()
  irda: Kill set but unused variable 'clen' in ircomm_connect_indication()
  rxrpc: Fix set but unused variable 'usage' in rxrpc_get_transport()
  be2net: Kill set but unused variable 'req' in lancer_fw_download()
  irda: Kill set but unused vars 'saddr' and 'daddr' in irlan_provider_connect_indication()
  atl1c: atl1c_resume() is only used when CONFIG_PM_SLEEP is defined.
  rxrpc: Fix set but unused variable 'usage' in rxrpc_get_peer().
  rxrpc: Kill set but unused variable 'local' in rxrpc_UDP_error_handler()
  rxrpc: Kill set but unused variable 'sp' in rxrpc_process_connection()
  rxrpc: Kill set but unused variable 'sp' in rxrpc_rotate_tx_window()
  pkt_sched: Kill set but unused variable 'protocol' in tc_classify()
  isdn: capi: Use pr_debug() instead of ifdefs.
  tg3: Update version to 3.119
  tg3: Apply rx_discards fix to 5719/5720
  ...

Fix up trivial conflicts in arch/x86/Kconfig and net/mac80211/agg-tx.c
as per Davem.
This commit is contained in:
Linus Torvalds 2011-05-20 13:43:21 -07:00
commit 06f4e926d2
1198 changed files with 126873 additions and 79635 deletions

View file

@ -845,12 +845,10 @@ claw_irq_tasklet ( unsigned long data )
{
struct chbk * p_ch;
struct net_device *dev;
struct claw_privbk * privptr;
p_ch = (struct chbk *) data;
dev = (struct net_device *)p_ch->ndev;
CLAW_DBF_TEXT(4, trace, "IRQtask");
privptr = (struct claw_privbk *)dev->ml_priv;
unpack_read(dev);
clear_bit(CLAW_BH_ACTIVE, (void *)&p_ch->flag_a);
CLAW_DBF_TEXT(4, trace, "TskletXt");
@ -1026,7 +1024,6 @@ claw_write_next ( struct chbk * p_ch )
struct net_device *dev;
struct claw_privbk *privptr=NULL;
struct sk_buff *pk_skb;
int rc;
CLAW_DBF_TEXT(4, trace, "claw_wrt");
if (p_ch->claw_state == CLAW_STOP)
@ -1038,7 +1035,7 @@ claw_write_next ( struct chbk * p_ch )
!skb_queue_empty(&p_ch->collect_queue)) {
pk_skb = claw_pack_skb(privptr);
while (pk_skb != NULL) {
rc = claw_hw_tx( pk_skb, dev,1);
claw_hw_tx(pk_skb, dev, 1);
if (privptr->write_free_count > 0) {
pk_skb = claw_pack_skb(privptr);
} else
@ -1322,15 +1319,12 @@ claw_hw_tx(struct sk_buff *skb, struct net_device *dev, long linkid)
unsigned char *pDataAddress;
struct endccw *pEnd;
struct ccw1 tempCCW;
struct chbk *p_ch;
struct claw_env *p_env;
int lock;
struct clawph *pk_head;
struct chbk *ch;
CLAW_DBF_TEXT(4, trace, "hw_tx");
privptr = (struct claw_privbk *)(dev->ml_priv);
p_ch = (struct chbk *)&privptr->channel[WRITE_CHANNEL];
p_env =privptr->p_env;
claw_free_wrt_buf(dev); /* Clean up free chain if posible */
/* scan the write queue to free any completed write packets */
@ -1511,12 +1505,6 @@ claw_hw_tx(struct sk_buff *skb, struct net_device *dev, long linkid)
} /* endif (p_first_ccw!=NULL) */
dev_kfree_skb_any(skb);
if (linkid==0) {
lock=LOCK_NO;
}
else {
lock=LOCK_YES;
}
claw_strt_out_IO(dev );
/* if write free count is zero , set NOBUFFER */
if (privptr->write_free_count==0) {
@ -2821,15 +2809,11 @@ claw_free_wrt_buf( struct net_device *dev )
{
struct claw_privbk *privptr = (struct claw_privbk *)dev->ml_priv;
struct ccwbk*p_first_ccw;
struct ccwbk*p_last_ccw;
struct ccwbk*p_this_ccw;
struct ccwbk*p_next_ccw;
CLAW_DBF_TEXT(4, trace, "freewrtb");
/* scan the write queue to free any completed write packets */
p_first_ccw=NULL;
p_last_ccw=NULL;
p_this_ccw=privptr->p_write_active_first;
while ( (p_this_ccw!=NULL) && (p_this_ccw->header.flag!=CLAW_PENDING))
{
@ -3072,7 +3056,7 @@ claw_shutdown_device(struct ccwgroup_device *cgdev)
{
struct claw_privbk *priv;
struct net_device *ndev;
int ret;
int ret = 0;
CLAW_DBF_TEXT_(2, setup, "%s", dev_name(&cgdev->dev));
priv = dev_get_drvdata(&cgdev->dev);
@ -3095,7 +3079,7 @@ claw_shutdown_device(struct ccwgroup_device *cgdev)
}
ccw_device_set_offline(cgdev->cdev[1]);
ccw_device_set_offline(cgdev->cdev[0]);
return 0;
return ret;
}
static void

View file

@ -672,7 +672,6 @@ static int ctcmpc_transmit_skb(struct channel *ch, struct sk_buff *skb)
int ccw_idx;
unsigned long hi;
unsigned long saveflags = 0; /* avoids compiler warning */
__u16 block_len;
CTCM_PR_DEBUG("Enter %s: %s, cp=%i ch=0x%p id=%s state=%s\n",
__func__, dev->name, smp_processor_id(), ch,
@ -719,7 +718,6 @@ static int ctcmpc_transmit_skb(struct channel *ch, struct sk_buff *skb)
*/
atomic_inc(&skb->users);
block_len = skb->len + TH_HEADER_LENGTH + PDU_HEADER_LENGTH;
/*
* IDAL support in CTCM is broken, so we have to
* care about skb's above 2G ourselves.

View file

@ -653,7 +653,6 @@ static void ctcmpc_send_sweep_resp(struct channel *rch)
struct net_device *dev = rch->netdev;
struct ctcm_priv *priv = dev->ml_priv;
struct mpc_group *grp = priv->mpcg;
int rc = 0;
struct th_sweep *header;
struct sk_buff *sweep_skb;
struct channel *ch = priv->channel[CTCM_WRITE];
@ -665,16 +664,14 @@ static void ctcmpc_send_sweep_resp(struct channel *rch)
CTCM_DBF_TEXT_(MPC_ERROR, CTC_DBF_ERROR,
"%s(%s): sweep_skb allocation ERROR\n",
CTCM_FUNTAIL, rch->id);
rc = -ENOMEM;
goto done;
goto done;
}
header = kmalloc(sizeof(struct th_sweep), gfp_type());
if (!header) {
dev_kfree_skb_any(sweep_skb);
rc = -ENOMEM;
goto done;
goto done;
}
header->th.th_seg = 0x00 ;
@ -1370,8 +1367,7 @@ static void mpc_action_go_inop(fsm_instance *fi, int event, void *arg)
struct net_device *dev = arg;
struct ctcm_priv *priv;
struct mpc_group *grp;
int rc = 0;
struct channel *wch, *rch;
struct channel *wch;
BUG_ON(dev == NULL);
CTCM_PR_DEBUG("Enter %s: %s\n", __func__, dev->name);
@ -1396,7 +1392,6 @@ static void mpc_action_go_inop(fsm_instance *fi, int event, void *arg)
fsm_deltimer(&priv->restart_timer);
wch = priv->channel[CTCM_WRITE];
rch = priv->channel[CTCM_READ];
switch (grp->saved_state) {
case MPCG_STATE_RESET:
@ -1435,7 +1430,7 @@ static void mpc_action_go_inop(fsm_instance *fi, int event, void *arg)
if (grp->send_qllc_disc == 1) {
grp->send_qllc_disc = 0;
rc = mpc_send_qllc_discontact(dev);
mpc_send_qllc_discontact(dev);
}
/* DO NOT issue DEV_EVENT_STOP directly out of this code */

View file

@ -1483,7 +1483,6 @@ lcs_tasklet(unsigned long data)
struct lcs_channel *channel;
struct lcs_buffer *iob;
int buf_idx;
int rc;
channel = (struct lcs_channel *) data;
LCS_DBF_TEXT_(5, trace, "tlet%s", dev_name(&channel->ccwdev->dev));
@ -1500,14 +1499,11 @@ lcs_tasklet(unsigned long data)
channel->buf_idx = buf_idx;
if (channel->state == LCS_CH_STATE_STOPPED)
// FIXME: what if rc != 0 ??
rc = lcs_start_channel(channel);
lcs_start_channel(channel);
spin_lock_irqsave(get_ccwdev_lock(channel->ccwdev), flags);
if (channel->state == LCS_CH_STATE_SUSPENDED &&
channel->iob[channel->io_idx].state == LCS_BUF_STATE_READY) {
// FIXME: what if rc != 0 ??
rc = __lcs_resume_channel(channel);
}
channel->iob[channel->io_idx].state == LCS_BUF_STATE_READY)
__lcs_resume_channel(channel);
spin_unlock_irqrestore(get_ccwdev_lock(channel->ccwdev), flags);
/* Something happened on the channel. Wake up waiters. */

View file

@ -1994,8 +1994,6 @@ static struct net_device *netiucv_init_netdevice(char *username)
netiucv_setup_netdevice);
if (!dev)
return NULL;
if (dev_alloc_name(dev, dev->name) < 0)
goto out_netdev;
privptr = netdev_priv(dev);
privptr->fsm = init_fsm("netiucvdev", dev_state_names,

View file

@ -407,12 +407,6 @@ struct qeth_qdio_q {
int next_buf_to_init;
} __attribute__ ((aligned(256)));
/* possible types of qeth large_send support */
enum qeth_large_send_types {
QETH_LARGE_SEND_NO,
QETH_LARGE_SEND_TSO,
};
struct qeth_qdio_out_buffer {
struct qdio_buffer *buffer;
atomic_t state;
@ -637,6 +631,8 @@ struct qeth_card_info {
__u32 csum_mask;
__u32 tx_csum_mask;
enum qeth_ipa_promisc_modes promisc_mode;
__u32 diagass_support;
__u32 hwtrap;
};
struct qeth_card_options {
@ -645,13 +641,11 @@ struct qeth_card_options {
struct qeth_ipa_info adp; /*Adapter parameters*/
struct qeth_routing_info route6;
struct qeth_ipa_info ipa6;
enum qeth_checksum_types checksum_type;
int broadcast_mode;
int macaddr_mode;
int fake_broadcast;
int add_hhlen;
int layer2;
enum qeth_large_send_types large_send;
int performance_stats;
int rx_sg_cb;
enum qeth_ipa_isolation_modes isolation;
@ -760,6 +754,14 @@ struct qeth_card_list_struct {
rwlock_t rwlock;
};
struct qeth_trap_id {
__u16 lparnr;
char vmname[8];
__u8 chpid;
__u8 ssid;
__u16 devno;
} __packed;
/*some helper functions*/
#define QETH_CARD_IFNAME(card) (((card)->dev)? (card)->dev->name : "")
@ -794,6 +796,12 @@ static inline void qeth_put_buffer_pool_entry(struct qeth_card *card,
list_add_tail(&entry->list, &card->qdio.in_buf_pool.entry_list);
}
static inline int qeth_is_diagass_supported(struct qeth_card *card,
enum qeth_diags_cmds cmd)
{
return card->info.diagass_support & (__u32)cmd;
}
extern struct ccwgroup_driver qeth_l2_ccwgroup_driver;
extern struct ccwgroup_driver qeth_l3_ccwgroup_driver;
const char *qeth_get_cardname_short(struct qeth_card *);
@ -879,6 +887,8 @@ void qeth_dbf_longtext(debug_info_t *id, int level, char *text, ...);
int qeth_core_ethtool_get_settings(struct net_device *, struct ethtool_cmd *);
int qeth_set_access_ctrl_online(struct qeth_card *card);
int qeth_hdr_chk_and_bounce(struct sk_buff *, int);
int qeth_hw_trap(struct qeth_card *, enum qeth_diags_trap_action);
int qeth_query_ipassists(struct qeth_card *, enum qeth_prot_versions prot);
/* exports for OSN */
int qeth_osn_assist(struct net_device *, void *, int);

View file

@ -24,6 +24,7 @@
#include <asm/ebcdic.h>
#include <asm/io.h>
#include <asm/sysinfo.h>
#include "qeth_core.h"
@ -349,6 +350,8 @@ static struct qeth_ipa_cmd *qeth_check_ipa_data(struct qeth_card *card,
card->info.chpid);
netif_carrier_on(card->dev);
card->lan_online = 1;
if (card->info.hwtrap)
card->info.hwtrap = 2;
qeth_schedule_recovery(card);
return NULL;
case IPA_CMD_MODCCID:
@ -1039,7 +1042,6 @@ static void qeth_set_intial_options(struct qeth_card *card)
{
card->options.route4.type = NO_ROUTER;
card->options.route6.type = NO_ROUTER;
card->options.checksum_type = QETH_CHECKSUM_DEFAULT;
card->options.broadcast_mode = QETH_TR_BROADCAST_ALLRINGS;
card->options.macaddr_mode = QETH_TR_MACADDR_NONCANONICAL;
card->options.fake_broadcast = 0;
@ -2574,6 +2576,142 @@ int qeth_query_setadapterparms(struct qeth_card *card)
}
EXPORT_SYMBOL_GPL(qeth_query_setadapterparms);
static int qeth_query_ipassists_cb(struct qeth_card *card,
struct qeth_reply *reply, unsigned long data)
{
struct qeth_ipa_cmd *cmd;
QETH_DBF_TEXT(SETUP, 2, "qipasscb");
cmd = (struct qeth_ipa_cmd *) data;
if (cmd->hdr.prot_version == QETH_PROT_IPV4) {
card->options.ipa4.supported_funcs = cmd->hdr.ipa_supported;
card->options.ipa4.enabled_funcs = cmd->hdr.ipa_enabled;
} else {
card->options.ipa6.supported_funcs = cmd->hdr.ipa_supported;
card->options.ipa6.enabled_funcs = cmd->hdr.ipa_enabled;
}
QETH_DBF_TEXT(SETUP, 2, "suppenbl");
QETH_DBF_TEXT_(SETUP, 2, "%x", cmd->hdr.ipa_supported);
QETH_DBF_TEXT_(SETUP, 2, "%x", cmd->hdr.ipa_enabled);
return 0;
}
int qeth_query_ipassists(struct qeth_card *card, enum qeth_prot_versions prot)
{
int rc;
struct qeth_cmd_buffer *iob;
QETH_DBF_TEXT_(SETUP, 2, "qipassi%i", prot);
iob = qeth_get_ipacmd_buffer(card, IPA_CMD_QIPASSIST, prot);
rc = qeth_send_ipa_cmd(card, iob, qeth_query_ipassists_cb, NULL);
return rc;
}
EXPORT_SYMBOL_GPL(qeth_query_ipassists);
static int qeth_query_setdiagass_cb(struct qeth_card *card,
struct qeth_reply *reply, unsigned long data)
{
struct qeth_ipa_cmd *cmd;
__u16 rc;
cmd = (struct qeth_ipa_cmd *)data;
rc = cmd->hdr.return_code;
if (rc)
QETH_CARD_TEXT_(card, 2, "diagq:%x", rc);
else
card->info.diagass_support = cmd->data.diagass.ext;
return 0;
}
static int qeth_query_setdiagass(struct qeth_card *card)
{
struct qeth_cmd_buffer *iob;
struct qeth_ipa_cmd *cmd;
QETH_DBF_TEXT(SETUP, 2, "qdiagass");
iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SET_DIAG_ASS, 0);
cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
cmd->data.diagass.subcmd_len = 16;
cmd->data.diagass.subcmd = QETH_DIAGS_CMD_QUERY;
return qeth_send_ipa_cmd(card, iob, qeth_query_setdiagass_cb, NULL);
}
static void qeth_get_trap_id(struct qeth_card *card, struct qeth_trap_id *tid)
{
unsigned long info = get_zeroed_page(GFP_KERNEL);
struct sysinfo_2_2_2 *info222 = (struct sysinfo_2_2_2 *)info;
struct sysinfo_3_2_2 *info322 = (struct sysinfo_3_2_2 *)info;
struct ccw_dev_id ccwid;
int level, rc;
tid->chpid = card->info.chpid;
ccw_device_get_id(CARD_RDEV(card), &ccwid);
tid->ssid = ccwid.ssid;
tid->devno = ccwid.devno;
if (!info)
return;
rc = stsi(NULL, 0, 0, 0);
if (rc == -ENOSYS)
level = rc;
else
level = (((unsigned int) rc) >> 28);
if ((level >= 2) && (stsi(info222, 2, 2, 2) != -ENOSYS))
tid->lparnr = info222->lpar_number;
if ((level >= 3) && (stsi(info322, 3, 2, 2) != -ENOSYS)) {
EBCASC(info322->vm[0].name, sizeof(info322->vm[0].name));
memcpy(tid->vmname, info322->vm[0].name, sizeof(tid->vmname));
}
free_page(info);
return;
}
static int qeth_hw_trap_cb(struct qeth_card *card,
struct qeth_reply *reply, unsigned long data)
{
struct qeth_ipa_cmd *cmd;
__u16 rc;
cmd = (struct qeth_ipa_cmd *)data;
rc = cmd->hdr.return_code;
if (rc)
QETH_CARD_TEXT_(card, 2, "trapc:%x", rc);
return 0;
}
int qeth_hw_trap(struct qeth_card *card, enum qeth_diags_trap_action action)
{
struct qeth_cmd_buffer *iob;
struct qeth_ipa_cmd *cmd;
QETH_DBF_TEXT(SETUP, 2, "diagtrap");
iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SET_DIAG_ASS, 0);
cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
cmd->data.diagass.subcmd_len = 80;
cmd->data.diagass.subcmd = QETH_DIAGS_CMD_TRAP;
cmd->data.diagass.type = 1;
cmd->data.diagass.action = action;
switch (action) {
case QETH_DIAGS_TRAP_ARM:
cmd->data.diagass.options = 0x0003;
cmd->data.diagass.ext = 0x00010000 +
sizeof(struct qeth_trap_id);
qeth_get_trap_id(card,
(struct qeth_trap_id *)cmd->data.diagass.cdata);
break;
case QETH_DIAGS_TRAP_DISARM:
cmd->data.diagass.options = 0x0001;
break;
case QETH_DIAGS_TRAP_CAPTURE:
break;
}
return qeth_send_ipa_cmd(card, iob, qeth_hw_trap_cb, NULL);
}
EXPORT_SYMBOL_GPL(qeth_hw_trap);
int qeth_check_qdio_errors(struct qeth_card *card, struct qdio_buffer *buf,
unsigned int qdio_error, const char *dbftext)
{
@ -3903,6 +4041,7 @@ MODULE_DEVICE_TABLE(ccw, qeth_ids);
static struct ccw_driver qeth_ccw_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "qeth",
},
.ids = qeth_ids,
@ -3984,6 +4123,15 @@ retriable:
QETH_DBF_TEXT_(SETUP, 2, "5err%d", rc);
goto out;
}
card->options.ipa4.supported_funcs = 0;
card->options.adp.supported_funcs = 0;
card->info.diagass_support = 0;
qeth_query_ipassists(card, QETH_PROT_IPV4);
if (qeth_is_supported(card, IPA_SETADAPTERPARMS))
qeth_query_setadapterparms(card);
if (qeth_adp_supported(card, IPA_SETADP_SET_DIAG_ASSIST))
qeth_query_setdiagass(card);
return 0;
out:
dev_warn(&card->gdev->dev, "The qeth device driver failed to recover "

View file

@ -80,14 +80,6 @@ enum qeth_tr_broadcast_modes {
QETH_TR_BROADCAST_LOCAL = 1,
};
/* these values match CHECKSUM_* in include/linux/skbuff.h */
enum qeth_checksum_types {
SW_CHECKSUMMING = 0, /* TODO: set to bit flag used in IPA Command */
HW_CHECKSUMMING = 1,
NO_CHECKSUMMING = 2,
};
#define QETH_CHECKSUM_DEFAULT SW_CHECKSUMMING
/*
* Routing stuff
*/
@ -456,6 +448,12 @@ enum qeth_diags_trace_cmds {
QETH_DIAGS_CMD_TRACE_QUERY = 0x0010,
};
enum qeth_diags_trap_action {
QETH_DIAGS_TRAP_ARM = 0x01,
QETH_DIAGS_TRAP_DISARM = 0x02,
QETH_DIAGS_TRAP_CAPTURE = 0x04,
};
struct qeth_ipacmd_diagass {
__u32 host_tod2;
__u32:32;
@ -465,7 +463,8 @@ struct qeth_ipacmd_diagass {
__u8 type;
__u8 action;
__u16 options;
__u32:32;
__u32 ext;
__u8 cdata[64];
} __attribute__ ((packed));
/* Header for each IPA command */

View file

@ -530,6 +530,66 @@ out:
static DEVICE_ATTR(isolation, 0644, qeth_dev_isolation_show,
qeth_dev_isolation_store);
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;
char *tmp, *curtoken;
int state = 0;
curtoken = (char *)buf;
if (!card)
return -EINVAL;
mutex_lock(&card->conf_mutex);
if (card->state == CARD_STATE_SOFTSETUP || card->state == CARD_STATE_UP)
state = 1;
tmp = strsep(&curtoken, "\n");
if (!strcmp(tmp, "arm") && !card->info.hwtrap) {
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;
} else if (!strcmp(tmp, "disarm") && card->info.hwtrap) {
if (state) {
rc = qeth_hw_trap(card, QETH_DIAGS_TRAP_DISARM);
if (!rc)
card->info.hwtrap = 0;
} else
card->info.hwtrap = 0;
} else if (!strcmp(tmp, "trap") && state && card->info.hwtrap)
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);
static ssize_t qeth_dev_blkt_show(char *buf, struct qeth_card *card, int value)
{
@ -653,6 +713,7 @@ static struct attribute *qeth_device_attrs[] = {
&dev_attr_performance_stats.attr,
&dev_attr_layer2.attr,
&dev_attr_isolation.attr,
&dev_attr_hw_trap.attr,
NULL,
};

View file

@ -420,10 +420,7 @@ static int qeth_l2_process_inbound_buffer(struct qeth_card *card,
case QETH_HEADER_TYPE_LAYER2:
skb->pkt_type = PACKET_HOST;
skb->protocol = eth_type_trans(skb, skb->dev);
if (card->options.checksum_type == NO_CHECKSUMMING)
skb->ip_summed = CHECKSUM_UNNECESSARY;
else
skb->ip_summed = CHECKSUM_NONE;
skb->ip_summed = CHECKSUM_NONE;
if (skb->protocol == htons(ETH_P_802_2))
*((__u32 *)skb->cb) = ++card->seqno.pkt_seqno;
len = skb->len;
@ -879,6 +876,7 @@ static int qeth_l2_probe_device(struct ccwgroup_device *gdev)
INIT_LIST_HEAD(&card->vid_list);
INIT_LIST_HEAD(&card->mc_list);
card->options.layer2 = 1;
card->info.hwtrap = 0;
card->discipline.start_poll = qeth_qdio_start_poll;
card->discipline.input_handler = (qdio_handler_t *)
qeth_qdio_input_handler;
@ -997,6 +995,13 @@ static int __qeth_l2_set_online(struct ccwgroup_device *gdev, int recovery_mode)
if (card->info.type != QETH_CARD_TYPE_OSN)
qeth_l2_send_setmac(card, &card->dev->dev_addr[0]);
if (qeth_is_diagass_supported(card, QETH_DIAGS_CMD_TRAP)) {
if (card->info.hwtrap &&
qeth_hw_trap(card, QETH_DIAGS_TRAP_ARM))
card->info.hwtrap = 0;
} else
card->info.hwtrap = 0;
card->state = CARD_STATE_HARDSETUP;
memset(&card->rx, 0, sizeof(struct qeth_rx));
qeth_print_status_message(card);
@ -1095,6 +1100,10 @@ static int __qeth_l2_set_offline(struct ccwgroup_device *cgdev,
if (card->dev && netif_carrier_ok(card->dev))
netif_carrier_off(card->dev);
recover_flag = card->state;
if ((!recovery_mode && card->info.hwtrap) || card->info.hwtrap == 2) {
qeth_hw_trap(card, QETH_DIAGS_TRAP_DISARM);
card->info.hwtrap = 1;
}
qeth_l2_stop_card(card, recovery_mode);
rc = ccw_device_set_offline(CARD_DDEV(card));
rc2 = ccw_device_set_offline(CARD_WDEV(card));
@ -1160,6 +1169,8 @@ static void __exit qeth_l2_exit(void)
static void qeth_l2_shutdown(struct ccwgroup_device *gdev)
{
struct qeth_card *card = dev_get_drvdata(&gdev->dev);
if ((gdev->state == CCWGROUP_ONLINE) && card->info.hwtrap)
qeth_hw_trap(card, QETH_DIAGS_TRAP_DISARM);
qeth_qdio_clear_card(card, 0);
qeth_clear_qdio_buffers(card);
}
@ -1175,6 +1186,8 @@ static int qeth_l2_pm_suspend(struct ccwgroup_device *gdev)
if (gdev->state == CCWGROUP_OFFLINE)
return 0;
if (card->state == CARD_STATE_UP) {
if (card->info.hwtrap)
qeth_hw_trap(card, QETH_DIAGS_TRAP_DISARM);
__qeth_l2_set_offline(card->gdev, 1);
} else
__qeth_l2_set_offline(card->gdev, 0);

View file

@ -62,8 +62,6 @@ void qeth_l3_del_vipa(struct qeth_card *, enum qeth_prot_versions, const u8 *);
int qeth_l3_add_rxip(struct qeth_card *, enum qeth_prot_versions, const u8 *);
void qeth_l3_del_rxip(struct qeth_card *card, enum qeth_prot_versions,
const u8 *);
int qeth_l3_set_large_send(struct qeth_card *, enum qeth_large_send_types);
int qeth_l3_set_rx_csum(struct qeth_card *, enum qeth_checksum_types);
int qeth_l3_is_addr_covered_by_ipato(struct qeth_card *, struct qeth_ipaddr *);
#endif /* __QETH_L3_H__ */

View file

@ -43,33 +43,6 @@ static int qeth_l3_deregister_addr_entry(struct qeth_card *,
static int __qeth_l3_set_online(struct ccwgroup_device *, int);
static int __qeth_l3_set_offline(struct ccwgroup_device *, int);
int qeth_l3_set_large_send(struct qeth_card *card,
enum qeth_large_send_types type)
{
int rc = 0;
card->options.large_send = type;
if (card->dev == NULL)
return 0;
if (card->options.large_send == QETH_LARGE_SEND_TSO) {
if (qeth_is_supported(card, IPA_OUTBOUND_TSO)) {
card->dev->features |= NETIF_F_TSO | NETIF_F_SG |
NETIF_F_IP_CSUM;
} else {
card->dev->features &= ~(NETIF_F_TSO | NETIF_F_SG |
NETIF_F_IP_CSUM);
card->options.large_send = QETH_LARGE_SEND_NO;
rc = -EOPNOTSUPP;
}
} else {
card->dev->features &= ~(NETIF_F_TSO | NETIF_F_SG |
NETIF_F_IP_CSUM);
card->options.large_send = QETH_LARGE_SEND_NO;
}
return rc;
}
static int qeth_l3_isxdigit(char *buf)
{
while (*buf) {
@ -1304,39 +1277,6 @@ static int qeth_l3_start_ipa_multicast(struct qeth_card *card)
return rc;
}
static int qeth_l3_query_ipassists_cb(struct qeth_card *card,
struct qeth_reply *reply, unsigned long data)
{
struct qeth_ipa_cmd *cmd;
QETH_DBF_TEXT(SETUP, 2, "qipasscb");
cmd = (struct qeth_ipa_cmd *) data;
if (cmd->hdr.prot_version == QETH_PROT_IPV4) {
card->options.ipa4.supported_funcs = cmd->hdr.ipa_supported;
card->options.ipa4.enabled_funcs = cmd->hdr.ipa_enabled;
} else {
card->options.ipa6.supported_funcs = cmd->hdr.ipa_supported;
card->options.ipa6.enabled_funcs = cmd->hdr.ipa_enabled;
}
QETH_DBF_TEXT(SETUP, 2, "suppenbl");
QETH_DBF_TEXT_(SETUP, 2, "%x", cmd->hdr.ipa_supported);
QETH_DBF_TEXT_(SETUP, 2, "%x", cmd->hdr.ipa_enabled);
return 0;
}
static int qeth_l3_query_ipassists(struct qeth_card *card,
enum qeth_prot_versions prot)
{
int rc;
struct qeth_cmd_buffer *iob;
QETH_DBF_TEXT_(SETUP, 2, "qipassi%i", prot);
iob = qeth_get_ipacmd_buffer(card, IPA_CMD_QIPASSIST, prot);
rc = qeth_send_ipa_cmd(card, iob, qeth_l3_query_ipassists_cb, NULL);
return rc;
}
#ifdef CONFIG_QETH_IPV6
static int qeth_l3_softsetup_ipv6(struct qeth_card *card)
{
@ -1347,7 +1287,7 @@ static int qeth_l3_softsetup_ipv6(struct qeth_card *card)
if (card->info.type == QETH_CARD_TYPE_IQD)
goto out;
rc = qeth_l3_query_ipassists(card, QETH_PROT_IPV6);
rc = qeth_query_ipassists(card, QETH_PROT_IPV6);
if (rc) {
dev_err(&card->gdev->dev,
"Activating IPv6 support for %s failed\n",
@ -1472,68 +1412,38 @@ static int qeth_l3_send_checksum_command(struct qeth_card *card)
return 0;
}
int qeth_l3_set_rx_csum(struct qeth_card *card,
enum qeth_checksum_types csum_type)
int qeth_l3_set_rx_csum(struct qeth_card *card, int on)
{
int rc = 0;
if (card->options.checksum_type == HW_CHECKSUMMING) {
if ((csum_type != HW_CHECKSUMMING) &&
(card->state != CARD_STATE_DOWN)) {
rc = qeth_l3_send_simple_setassparms(card,
IPA_INBOUND_CHECKSUM, IPA_CMD_ASS_STOP, 0);
if (rc)
return -EIO;
}
if (on) {
rc = qeth_l3_send_checksum_command(card);
if (rc)
return -EIO;
dev_info(&card->gdev->dev,
"HW Checksumming (inbound) enabled\n");
} else {
if (csum_type == HW_CHECKSUMMING) {
if (card->state != CARD_STATE_DOWN) {
if (!qeth_is_supported(card,
IPA_INBOUND_CHECKSUM))
return -EPERM;
rc = qeth_l3_send_checksum_command(card);
if (rc)
return -EIO;
}
}
rc = qeth_l3_send_simple_setassparms(card,
IPA_INBOUND_CHECKSUM, IPA_CMD_ASS_STOP, 0);
if (rc)
return -EIO;
}
card->options.checksum_type = csum_type;
return rc;
return 0;
}
static int qeth_l3_start_ipa_checksum(struct qeth_card *card)
{
int rc = 0;
QETH_CARD_TEXT(card, 3, "strtcsum");
if (card->options.checksum_type == NO_CHECKSUMMING) {
dev_info(&card->gdev->dev,
"Using no checksumming on %s.\n",
QETH_CARD_IFNAME(card));
return 0;
if (card->dev->features & NETIF_F_RXCSUM) {
rtnl_lock();
/* force set_features call */
card->dev->features &= ~NETIF_F_RXCSUM;
netdev_update_features(card->dev);
rtnl_unlock();
}
if (card->options.checksum_type == SW_CHECKSUMMING) {
dev_info(&card->gdev->dev,
"Using SW checksumming on %s.\n",
QETH_CARD_IFNAME(card));
return 0;
}
if (!qeth_is_supported(card, IPA_INBOUND_CHECKSUM)) {
dev_info(&card->gdev->dev,
"Inbound HW Checksumming not "
"supported on %s,\ncontinuing "
"using Inbound SW Checksumming\n",
QETH_CARD_IFNAME(card));
card->options.checksum_type = SW_CHECKSUMMING;
return 0;
}
rc = qeth_l3_send_checksum_command(card);
if (!rc)
dev_info(&card->gdev->dev,
"HW Checksumming (inbound) enabled\n");
return rc;
return 0;
}
static int qeth_l3_start_ipa_tx_checksum(struct qeth_card *card)
@ -1580,10 +1490,8 @@ static int qeth_l3_start_ipa_tso(struct qeth_card *card)
dev_info(&card->gdev->dev,
"Outbound TSO enabled\n");
}
if (rc && (card->options.large_send == QETH_LARGE_SEND_TSO)) {
card->options.large_send = QETH_LARGE_SEND_NO;
card->dev->features &= ~(NETIF_F_TSO | NETIF_F_SG);
}
if (rc)
card->dev->features &= ~NETIF_F_TSO;
return rc;
}
@ -2064,14 +1972,7 @@ static inline int qeth_l3_rebuild_skb(struct qeth_card *card,
is_vlan = 1;
}
switch (card->options.checksum_type) {
case SW_CHECKSUMMING:
skb->ip_summed = CHECKSUM_NONE;
break;
case NO_CHECKSUMMING:
skb->ip_summed = CHECKSUM_UNNECESSARY;
break;
case HW_CHECKSUMMING:
if (card->dev->features & NETIF_F_RXCSUM) {
if ((hdr->hdr.l3.ext_flags &
(QETH_HDR_EXT_CSUM_HDR_REQ |
QETH_HDR_EXT_CSUM_TRANSP_REQ)) ==
@ -2080,7 +1981,8 @@ static inline int qeth_l3_rebuild_skb(struct qeth_card *card,
skb->ip_summed = CHECKSUM_UNNECESSARY;
else
skb->ip_summed = CHECKSUM_NONE;
}
} else
skb->ip_summed = CHECKSUM_NONE;
return is_vlan;
}
@ -3024,7 +2926,7 @@ static int qeth_l3_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
struct qeth_qdio_out_q *queue = card->qdio.out_qs
[qeth_get_priority_queue(card, skb, ipv, cast_type)];
int tx_bytes = skb->len;
enum qeth_large_send_types large_send = QETH_LARGE_SEND_NO;
bool large_send;
int data_offset = -1;
int nr_frags;
@ -3046,8 +2948,7 @@ static int qeth_l3_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
card->perf_stats.outbound_start_time = qeth_get_micros();
}
if (skb_is_gso(skb))
large_send = card->options.large_send;
large_send = skb_is_gso(skb);
if ((card->info.type == QETH_CARD_TYPE_IQD) && (!large_send) &&
(skb_shinfo(skb)->nr_frags == 0)) {
@ -3096,7 +2997,7 @@ static int qeth_l3_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
/* fix hardware limitation: as long as we do not have sbal
* chaining we can not send long frag lists
*/
if (large_send == QETH_LARGE_SEND_TSO) {
if (large_send) {
if (qeth_l3_tso_elements(new_skb) + 1 > 16) {
if (skb_linearize(new_skb))
goto tx_drop;
@ -3105,8 +3006,7 @@ static int qeth_l3_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
}
}
if ((large_send == QETH_LARGE_SEND_TSO) &&
(cast_type == RTN_UNSPEC)) {
if (large_send && (cast_type == RTN_UNSPEC)) {
hdr = (struct qeth_hdr *)skb_push(new_skb,
sizeof(struct qeth_hdr_tso));
memset(hdr, 0, sizeof(struct qeth_hdr_tso));
@ -3141,7 +3041,7 @@ static int qeth_l3_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
if (card->info.type != QETH_CARD_TYPE_IQD) {
int len;
if (large_send == QETH_LARGE_SEND_TSO)
if (large_send)
len = ((unsigned long)tcp_hdr(new_skb) +
tcp_hdr(new_skb)->doff * 4) -
(unsigned long)new_skb->data;
@ -3162,7 +3062,7 @@ static int qeth_l3_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
if (new_skb != skb)
dev_kfree_skb_any(skb);
if (card->options.performance_stats) {
if (large_send != QETH_LARGE_SEND_NO) {
if (large_send) {
card->perf_stats.large_send_bytes += tx_bytes;
card->perf_stats.large_send_cnt++;
}
@ -3248,65 +3148,42 @@ static int qeth_l3_stop(struct net_device *dev)
return 0;
}
static u32 qeth_l3_ethtool_get_rx_csum(struct net_device *dev)
static u32 qeth_l3_fix_features(struct net_device *dev, u32 features)
{
struct qeth_card *card = dev->ml_priv;
return (card->options.checksum_type == HW_CHECKSUMMING);
if (!qeth_is_supported(card, IPA_OUTBOUND_CHECKSUM))
features &= ~NETIF_F_IP_CSUM;
if (!qeth_is_supported(card, IPA_OUTBOUND_TSO))
features &= ~NETIF_F_TSO;
if (!qeth_is_supported(card, IPA_INBOUND_CHECKSUM))
features &= ~NETIF_F_RXCSUM;
return features;
}
static int qeth_l3_ethtool_set_rx_csum(struct net_device *dev, u32 data)
static int qeth_l3_set_features(struct net_device *dev, u32 features)
{
struct qeth_card *card = dev->ml_priv;
enum qeth_checksum_types csum_type;
u32 changed = dev->features ^ features;
int err;
if (data)
csum_type = HW_CHECKSUMMING;
else
csum_type = SW_CHECKSUMMING;
if (!(changed & NETIF_F_RXCSUM))
return 0;
return qeth_l3_set_rx_csum(card, csum_type);
}
if (card->state == CARD_STATE_DOWN ||
card->state == CARD_STATE_RECOVER)
return 0;
static int qeth_l3_ethtool_set_tso(struct net_device *dev, u32 data)
{
struct qeth_card *card = dev->ml_priv;
int rc = 0;
err = qeth_l3_set_rx_csum(card, features & NETIF_F_RXCSUM);
if (err)
dev->features = features ^ NETIF_F_RXCSUM;
if (data) {
rc = qeth_l3_set_large_send(card, QETH_LARGE_SEND_TSO);
} else {
dev->features &= ~NETIF_F_TSO;
card->options.large_send = QETH_LARGE_SEND_NO;
}
return rc;
}
static int qeth_l3_ethtool_set_tx_csum(struct net_device *dev, u32 data)
{
struct qeth_card *card = dev->ml_priv;
if (data) {
if (qeth_is_supported(card, IPA_OUTBOUND_CHECKSUM))
dev->features |= NETIF_F_IP_CSUM;
else
return -EPERM;
} else
dev->features &= ~NETIF_F_IP_CSUM;
return 0;
return err;
}
static const struct ethtool_ops qeth_l3_ethtool_ops = {
.get_link = ethtool_op_get_link,
.get_tx_csum = ethtool_op_get_tx_csum,
.set_tx_csum = qeth_l3_ethtool_set_tx_csum,
.get_rx_csum = qeth_l3_ethtool_get_rx_csum,
.set_rx_csum = qeth_l3_ethtool_set_rx_csum,
.get_sg = ethtool_op_get_sg,
.set_sg = ethtool_op_set_sg,
.get_tso = ethtool_op_get_tso,
.set_tso = qeth_l3_ethtool_set_tso,
.get_strings = qeth_core_get_strings,
.get_ethtool_stats = qeth_core_get_ethtool_stats,
.get_sset_count = qeth_core_get_sset_count,
@ -3347,6 +3224,8 @@ static const struct net_device_ops qeth_l3_netdev_ops = {
.ndo_set_multicast_list = qeth_l3_set_multicast_list,
.ndo_do_ioctl = qeth_l3_do_ioctl,
.ndo_change_mtu = qeth_change_mtu,
.ndo_fix_features = qeth_l3_fix_features,
.ndo_set_features = qeth_l3_set_features,
.ndo_vlan_rx_register = qeth_l3_vlan_rx_register,
.ndo_vlan_rx_add_vid = qeth_l3_vlan_rx_add_vid,
.ndo_vlan_rx_kill_vid = qeth_l3_vlan_rx_kill_vid,
@ -3362,6 +3241,8 @@ static const struct net_device_ops qeth_l3_osa_netdev_ops = {
.ndo_set_multicast_list = qeth_l3_set_multicast_list,
.ndo_do_ioctl = qeth_l3_do_ioctl,
.ndo_change_mtu = qeth_change_mtu,
.ndo_fix_features = qeth_l3_fix_features,
.ndo_set_features = qeth_l3_set_features,
.ndo_vlan_rx_register = qeth_l3_vlan_rx_register,
.ndo_vlan_rx_add_vid = qeth_l3_vlan_rx_add_vid,
.ndo_vlan_rx_kill_vid = qeth_l3_vlan_rx_kill_vid,
@ -3392,8 +3273,12 @@ static int qeth_l3_setup_netdev(struct qeth_card *card)
if (!(card->info.unique_id & UNIQUE_ID_NOT_BY_CARD))
card->dev->dev_id = card->info.unique_id &
0xffff;
if (!card->info.guestlan)
card->dev->features |= NETIF_F_GRO;
if (!card->info.guestlan) {
card->dev->hw_features = NETIF_F_SG |
NETIF_F_RXCSUM | NETIF_F_IP_CSUM |
NETIF_F_TSO;
card->dev->features = NETIF_F_RXCSUM;
}
}
} else if (card->info.type == QETH_CARD_TYPE_IQD) {
card->dev = alloc_netdev(0, "hsi%d", ether_setup);
@ -3426,15 +3311,13 @@ static int qeth_l3_probe_device(struct ccwgroup_device *gdev)
qeth_l3_create_device_attributes(&gdev->dev);
card->options.layer2 = 0;
card->info.hwtrap = 0;
card->discipline.start_poll = qeth_qdio_start_poll;
card->discipline.input_handler = (qdio_handler_t *)
qeth_qdio_input_handler;
card->discipline.output_handler = (qdio_handler_t *)
qeth_qdio_output_handler;
card->discipline.recover = qeth_l3_recover;
if ((card->info.type == QETH_CARD_TYPE_OSD) ||
(card->info.type == QETH_CARD_TYPE_OSX))
card->options.checksum_type = HW_CHECKSUMMING;
return 0;
}
@ -3480,13 +3363,18 @@ static int __qeth_l3_set_online(struct ccwgroup_device *gdev, int recovery_mode)
goto out_remove;
}
qeth_l3_query_ipassists(card, QETH_PROT_IPV4);
if (!card->dev && qeth_l3_setup_netdev(card)) {
rc = -ENODEV;
goto out_remove;
}
if (qeth_is_diagass_supported(card, QETH_DIAGS_CMD_TRAP)) {
if (card->info.hwtrap &&
qeth_hw_trap(card, QETH_DIAGS_TRAP_ARM))
card->info.hwtrap = 0;
} else
card->info.hwtrap = 0;
card->state = CARD_STATE_HARDSETUP;
memset(&card->rx, 0, sizeof(struct qeth_rx));
qeth_print_status_message(card);
@ -3516,7 +3404,6 @@ contin:
rc = qeth_l3_start_ipassists(card);
if (rc)
QETH_DBF_TEXT_(SETUP, 2, "3err%d", rc);
qeth_l3_set_large_send(card, card->options.large_send);
rc = qeth_l3_setrouting_v4(card);
if (rc)
QETH_DBF_TEXT_(SETUP, 2, "4err%d", rc);
@ -3589,6 +3476,10 @@ static int __qeth_l3_set_offline(struct ccwgroup_device *cgdev,
if (card->dev && netif_carrier_ok(card->dev))
netif_carrier_off(card->dev);
recover_flag = card->state;
if ((!recovery_mode && card->info.hwtrap) || card->info.hwtrap == 2) {
qeth_hw_trap(card, QETH_DIAGS_TRAP_DISARM);
card->info.hwtrap = 1;
}
qeth_l3_stop_card(card, recovery_mode);
rc = ccw_device_set_offline(CARD_DDEV(card));
rc2 = ccw_device_set_offline(CARD_WDEV(card));
@ -3644,6 +3535,8 @@ static int qeth_l3_recover(void *ptr)
static void qeth_l3_shutdown(struct ccwgroup_device *gdev)
{
struct qeth_card *card = dev_get_drvdata(&gdev->dev);
if ((gdev->state == CCWGROUP_ONLINE) && card->info.hwtrap)
qeth_hw_trap(card, QETH_DIAGS_TRAP_DISARM);
qeth_qdio_clear_card(card, 0);
qeth_clear_qdio_buffers(card);
}
@ -3659,6 +3552,8 @@ static int qeth_l3_pm_suspend(struct ccwgroup_device *gdev)
if (gdev->state == CCWGROUP_OFFLINE)
return 0;
if (card->state == CARD_STATE_UP) {
if (card->info.hwtrap)
qeth_hw_trap(card, QETH_DIAGS_TRAP_DISARM);
__qeth_l3_set_offline(card->gdev, 1);
} else
__qeth_l3_set_offline(card->gdev, 0);

View file

@ -15,16 +15,6 @@
#define QETH_DEVICE_ATTR(_id, _name, _mode, _show, _store) \
struct device_attribute dev_attr_##_id = __ATTR(_name, _mode, _show, _store)
static const char *qeth_l3_get_checksum_str(struct qeth_card *card)
{
if (card->options.checksum_type == SW_CHECKSUMMING)
return "sw";
else if (card->options.checksum_type == HW_CHECKSUMMING)
return "hw";
else
return "no";
}
static ssize_t qeth_l3_dev_route_show(struct qeth_card *card,
struct qeth_routing_info *route, char *buf)
{
@ -295,51 +285,6 @@ out:
static DEVICE_ATTR(canonical_macaddr, 0644, qeth_l3_dev_canonical_macaddr_show,
qeth_l3_dev_canonical_macaddr_store);
static ssize_t qeth_l3_dev_checksum_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 checksumming\n",
qeth_l3_get_checksum_str(card));
}
static ssize_t qeth_l3_dev_checksum_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
struct qeth_card *card = dev_get_drvdata(dev);
enum qeth_checksum_types csum_type;
char *tmp;
int rc = 0;
if (!card)
return -EINVAL;
mutex_lock(&card->conf_mutex);
tmp = strsep((char **) &buf, "\n");
if (!strcmp(tmp, "sw_checksumming"))
csum_type = SW_CHECKSUMMING;
else if (!strcmp(tmp, "hw_checksumming"))
csum_type = HW_CHECKSUMMING;
else if (!strcmp(tmp, "no_checksumming"))
csum_type = NO_CHECKSUMMING;
else {
rc = -EINVAL;
goto out;
}
rc = qeth_l3_set_rx_csum(card, csum_type);
out:
mutex_unlock(&card->conf_mutex);
return rc ? rc : count;
}
static DEVICE_ATTR(checksumming, 0644, qeth_l3_dev_checksum_show,
qeth_l3_dev_checksum_store);
static ssize_t qeth_l3_dev_sniffer_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
@ -402,61 +347,13 @@ out:
static DEVICE_ATTR(sniffer, 0644, qeth_l3_dev_sniffer_show,
qeth_l3_dev_sniffer_store);
static ssize_t qeth_l3_dev_large_send_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.large_send) {
case QETH_LARGE_SEND_NO:
return sprintf(buf, "%s\n", "no");
case QETH_LARGE_SEND_TSO:
return sprintf(buf, "%s\n", "TSO");
default:
return sprintf(buf, "%s\n", "N/A");
}
}
static ssize_t qeth_l3_dev_large_send_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
struct qeth_card *card = dev_get_drvdata(dev);
enum qeth_large_send_types type;
int rc = 0;
char *tmp;
if (!card)
return -EINVAL;
tmp = strsep((char **) &buf, "\n");
if (!strcmp(tmp, "no"))
type = QETH_LARGE_SEND_NO;
else if (!strcmp(tmp, "TSO"))
type = QETH_LARGE_SEND_TSO;
else
return -EINVAL;
mutex_lock(&card->conf_mutex);
if (card->options.large_send != type)
rc = qeth_l3_set_large_send(card, type);
mutex_unlock(&card->conf_mutex);
return rc ? rc : count;
}
static DEVICE_ATTR(large_send, 0644, qeth_l3_dev_large_send_show,
qeth_l3_dev_large_send_store);
static struct attribute *qeth_l3_device_attrs[] = {
&dev_attr_route4.attr,
&dev_attr_route6.attr,
&dev_attr_fake_broadcast.attr,
&dev_attr_broadcast_mode.attr,
&dev_attr_canonical_macaddr.attr,
&dev_attr_checksumming.attr,
&dev_attr_sniffer.attr,
&dev_attr_large_send.attr,
NULL,
};