diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-05-21 00:43:21 +0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-05-21 00:43:21 +0400 |
commit | 06f4e926d256d902dd9a53dcb400fd74974ce087 (patch) | |
tree | 0b438b67f5f0eff6fd617bc497a9dace6164a488 /drivers/s390 | |
parent | 8e7bfcbab3825d1b404d615cb1b54f44ff81f981 (diff) | |
parent | d93515611bbc70c2fe4db232e5feb448ed8e4cc9 (diff) | |
download | linux-06f4e926d256d902dd9a53dcb400fd74974ce087.tar.xz |
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.
Diffstat (limited to 'drivers/s390')
-rw-r--r-- | drivers/s390/net/claw.c | 22 | ||||
-rw-r--r-- | drivers/s390/net/ctcm_main.c | 2 | ||||
-rw-r--r-- | drivers/s390/net/ctcm_mpc.c | 13 | ||||
-rw-r--r-- | drivers/s390/net/lcs.c | 10 | ||||
-rw-r--r-- | drivers/s390/net/netiucv.c | 2 | ||||
-rw-r--r-- | drivers/s390/net/qeth_core.h | 26 | ||||
-rw-r--r-- | drivers/s390/net/qeth_core_main.c | 150 | ||||
-rw-r--r-- | drivers/s390/net/qeth_core_mpc.h | 17 | ||||
-rw-r--r-- | drivers/s390/net/qeth_core_sys.c | 61 | ||||
-rw-r--r-- | drivers/s390/net/qeth_l2_main.c | 21 | ||||
-rw-r--r-- | drivers/s390/net/qeth_l3.h | 2 | ||||
-rw-r--r-- | drivers/s390/net/qeth_l3_main.c | 261 | ||||
-rw-r--r-- | drivers/s390/net/qeth_l3_sys.c | 103 |
13 files changed, 341 insertions, 349 deletions
diff --git a/drivers/s390/net/claw.c b/drivers/s390/net/claw.c index da8aa75bb20b..f1fa2483ae6b 100644 --- a/drivers/s390/net/claw.c +++ b/drivers/s390/net/claw.c @@ -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 diff --git a/drivers/s390/net/ctcm_main.c b/drivers/s390/net/ctcm_main.c index c189296763a4..426787efc492 100644 --- a/drivers/s390/net/ctcm_main.c +++ b/drivers/s390/net/ctcm_main.c @@ -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. diff --git a/drivers/s390/net/ctcm_mpc.c b/drivers/s390/net/ctcm_mpc.c index b64881f33f23..da4c747335e7 100644 --- a/drivers/s390/net/ctcm_mpc.c +++ b/drivers/s390/net/ctcm_mpc.c @@ -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 */ diff --git a/drivers/s390/net/lcs.c b/drivers/s390/net/lcs.c index 49d1cfc3217e..c3b8064a102d 100644 --- a/drivers/s390/net/lcs.c +++ b/drivers/s390/net/lcs.c @@ -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. */ diff --git a/drivers/s390/net/netiucv.c b/drivers/s390/net/netiucv.c index b6a6356d09b3..3251333a23df 100644 --- a/drivers/s390/net/netiucv.c +++ b/drivers/s390/net/netiucv.c @@ -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, diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h index af3f7b095647..55c6aa1c9704 100644 --- a/drivers/s390/net/qeth_core.h +++ b/drivers/s390/net/qeth_core.h @@ -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); diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index 85cc53117ea6..503678a30981 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -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 " diff --git a/drivers/s390/net/qeth_core_mpc.h b/drivers/s390/net/qeth_core_mpc.h index 07d588867b57..e5a9d1c03839 100644 --- a/drivers/s390/net/qeth_core_mpc.h +++ b/drivers/s390/net/qeth_core_mpc.h @@ -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 */ diff --git a/drivers/s390/net/qeth_core_sys.c b/drivers/s390/net/qeth_core_sys.c index b5e967cf7e2d..0a8e86c1b0ea 100644 --- a/drivers/s390/net/qeth_core_sys.c +++ b/drivers/s390/net/qeth_core_sys.c @@ -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, }; diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c index 6fbaacb21943..b70b47fbd6cd 100644 --- a/drivers/s390/net/qeth_l2_main.c +++ b/drivers/s390/net/qeth_l2_main.c @@ -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); diff --git a/drivers/s390/net/qeth_l3.h b/drivers/s390/net/qeth_l3.h index e705b27ec7dc..14a43aeb0c2a 100644 --- a/drivers/s390/net/qeth_l3.h +++ b/drivers/s390/net/qeth_l3.h @@ -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__ */ diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index 142e5f6ef4f3..fd69da3fa6b4 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c @@ -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->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; + 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(); } - 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); -} - -static int qeth_l3_ethtool_set_rx_csum(struct net_device *dev, u32 data) -{ - struct qeth_card *card = dev->ml_priv; - enum qeth_checksum_types csum_type; - - if (data) - csum_type = HW_CHECKSUMMING; - else - csum_type = SW_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 qeth_l3_set_rx_csum(card, csum_type); + return features; } -static int qeth_l3_ethtool_set_tso(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; - int rc = 0; + u32 changed = dev->features ^ features; + int err; - 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; -} + if (!(changed & NETIF_F_RXCSUM)) + return 0; -static int qeth_l3_ethtool_set_tx_csum(struct net_device *dev, u32 data) -{ - struct qeth_card *card = dev->ml_priv; + if (card->state == CARD_STATE_DOWN || + card->state == CARD_STATE_RECOVER) + return 0; - 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; + err = qeth_l3_set_rx_csum(card, features & NETIF_F_RXCSUM); + if (err) + dev->features = features ^ NETIF_F_RXCSUM; - 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); diff --git a/drivers/s390/net/qeth_l3_sys.c b/drivers/s390/net/qeth_l3_sys.c index 67cfa68dcf1b..cd99210296e2 100644 --- a/drivers/s390/net/qeth_l3_sys.c +++ b/drivers/s390/net/qeth_l3_sys.c @@ -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, }; |