aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-03-21 00:04:47 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-03-21 00:04:47 -0400
commit3b59bf081622b6446db77ad06c93fe23677bc533 (patch)
tree3f4bb5a27c90cc86994a1f6d3c53fbf9208003cb /drivers/s390
parente45836fafe157df137a837093037f741ad8f4c90 (diff)
parentbbdb32cb5b73597386913d052165423b9d736145 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next
Pull networking merge from David Miller: "1) Move ixgbe driver over to purely page based buffering on receive. From Alexander Duyck. 2) Add receive packet steering support to e1000e, from Bruce Allan. 3) Convert TCP MD5 support over to RCU, from Eric Dumazet. 4) Reduce cpu usage in handling out-of-order TCP packets on modern systems, also from Eric Dumazet. 5) Support the IP{,V6}_UNICAST_IF socket options, making the wine folks happy, from Erich Hoover. 6) Support VLAN trunking from guests in hyperv driver, from Haiyang Zhang. 7) Support byte-queue-limtis in r8169, from Igor Maravic. 8) Outline code intended for IP_RECVTOS in IP_PKTOPTIONS existed but was never properly implemented, Jiri Benc fixed that. 9) 64-bit statistics support in r8169 and 8139too, from Junchang Wang. 10) Support kernel side dump filtering by ctmark in netfilter ctnetlink, from Pablo Neira Ayuso. 11) Support byte-queue-limits in gianfar driver, from Paul Gortmaker. 12) Add new peek socket options to assist with socket migration, from Pavel Emelyanov. 13) Add sch_plug packet scheduler whose queue is controlled by userland daemons using explicit freeze and release commands. From Shriram Rajagopalan. 14) Fix FCOE checksum offload handling on transmit, from Yi Zou." * git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next: (1846 commits) Fix pppol2tp getsockname() Remove printk from rds_sendmsg ipv6: fix incorrent ipv6 ipsec packet fragment cpsw: Hook up default ndo_change_mtu. net: qmi_wwan: fix build error due to cdc-wdm dependecy netdev: driver: ethernet: Add TI CPSW driver netdev: driver: ethernet: add cpsw address lookup engine support phy: add am79c874 PHY support mlx4_core: fix race on comm channel bonding: send igmp report for its master fs_enet: Add MPC5125 FEC support and PHY interface selection net: bpf_jit: fix BPF_S_LDX_B_MSH compilation net: update the usage of CHECKSUM_UNNECESSARY fcoe: use CHECKSUM_UNNECESSARY instead of CHECKSUM_PARTIAL on tx net: do not do gso for CHECKSUM_UNNECESSARY in netif_needs_gso ixgbe: Fix issues with SR-IOV loopback when flow control is disabled net/hyperv: Fix the code handling tx busy ixgbe: fix namespace issues when FCoE/DCB is not enabled rtlwifi: Remove unused ETH_ADDR_LEN defines igbvf: Use ETH_ALEN ... Fix up fairly trivial conflicts in drivers/isdn/gigaset/interface.c and drivers/net/usb/{Kconfig,qmi_wwan.c} as per David.
Diffstat (limited to 'drivers/s390')
-rw-r--r--drivers/s390/net/ctcm_fsms.c11
-rw-r--r--drivers/s390/net/ctcm_main.c3
-rw-r--r--drivers/s390/net/ctcm_mpc.c12
-rw-r--r--drivers/s390/net/lcs.c12
-rw-r--r--drivers/s390/net/qeth_core.h1
-rw-r--r--drivers/s390/net/qeth_core_main.c110
-rw-r--r--drivers/s390/net/qeth_core_mpc.c1
-rw-r--r--drivers/s390/net/qeth_core_mpc.h14
-rw-r--r--drivers/s390/net/qeth_l2_main.c7
-rw-r--r--drivers/s390/net/qeth_l3_main.c40
10 files changed, 174 insertions, 37 deletions
diff --git a/drivers/s390/net/ctcm_fsms.c b/drivers/s390/net/ctcm_fsms.c
index 2d602207541b..a69766900a17 100644
--- a/drivers/s390/net/ctcm_fsms.c
+++ b/drivers/s390/net/ctcm_fsms.c
@@ -1341,6 +1341,12 @@ static void ctcmpc_chx_txdone(fsm_instance *fi, int event, void *arg)
1341 1341
1342 spin_unlock(&ch->collect_lock); 1342 spin_unlock(&ch->collect_lock);
1343 clear_normalized_cda(&ch->ccw[1]); 1343 clear_normalized_cda(&ch->ccw[1]);
1344
1345 CTCM_PR_DBGDATA("ccwcda=0x%p data=0x%p\n",
1346 (void *)(unsigned long)ch->ccw[1].cda,
1347 ch->trans_skb->data);
1348 ch->ccw[1].count = ch->max_bufsize;
1349
1344 if (set_normalized_cda(&ch->ccw[1], ch->trans_skb->data)) { 1350 if (set_normalized_cda(&ch->ccw[1], ch->trans_skb->data)) {
1345 dev_kfree_skb_any(ch->trans_skb); 1351 dev_kfree_skb_any(ch->trans_skb);
1346 ch->trans_skb = NULL; 1352 ch->trans_skb = NULL;
@@ -1350,6 +1356,11 @@ static void ctcmpc_chx_txdone(fsm_instance *fi, int event, void *arg)
1350 fsm_event(priv->mpcg->fsm, MPCG_EVENT_INOP, dev); 1356 fsm_event(priv->mpcg->fsm, MPCG_EVENT_INOP, dev);
1351 return; 1357 return;
1352 } 1358 }
1359
1360 CTCM_PR_DBGDATA("ccwcda=0x%p data=0x%p\n",
1361 (void *)(unsigned long)ch->ccw[1].cda,
1362 ch->trans_skb->data);
1363
1353 ch->ccw[1].count = ch->trans_skb->len; 1364 ch->ccw[1].count = ch->trans_skb->len;
1354 fsm_addtimer(&ch->timer, CTCM_TIME_5_SEC, CTC_EVENT_TIMER, ch); 1365 fsm_addtimer(&ch->timer, CTCM_TIME_5_SEC, CTC_EVENT_TIMER, ch);
1355 ch->prof.send_stamp = current_kernel_time(); /* xtime */ 1366 ch->prof.send_stamp = current_kernel_time(); /* xtime */
diff --git a/drivers/s390/net/ctcm_main.c b/drivers/s390/net/ctcm_main.c
index 5cb93a8e3403..11f3b071f305 100644
--- a/drivers/s390/net/ctcm_main.c
+++ b/drivers/s390/net/ctcm_main.c
@@ -562,6 +562,9 @@ static int ctcm_transmit_skb(struct channel *ch, struct sk_buff *skb)
562 skb_queue_tail(&ch->io_queue, skb); 562 skb_queue_tail(&ch->io_queue, skb);
563 ccw_idx = 3; 563 ccw_idx = 3;
564 } 564 }
565 if (do_debug_ccw)
566 ctcmpc_dumpit((char *)&ch->ccw[ccw_idx],
567 sizeof(struct ccw1) * 3);
565 ch->retry = 0; 568 ch->retry = 0;
566 fsm_newstate(ch->fsm, CTC_STATE_TX); 569 fsm_newstate(ch->fsm, CTC_STATE_TX);
567 fsm_addtimer(&ch->timer, CTCM_TIME_5_SEC, CTC_EVENT_TIMER, ch); 570 fsm_addtimer(&ch->timer, CTCM_TIME_5_SEC, CTC_EVENT_TIMER, ch);
diff --git a/drivers/s390/net/ctcm_mpc.c b/drivers/s390/net/ctcm_mpc.c
index da4c747335e7..ac7975b7a837 100644
--- a/drivers/s390/net/ctcm_mpc.c
+++ b/drivers/s390/net/ctcm_mpc.c
@@ -53,8 +53,8 @@
53#include <linux/moduleparam.h> 53#include <linux/moduleparam.h>
54#include <asm/idals.h> 54#include <asm/idals.h>
55 55
56#include "ctcm_mpc.h"
57#include "ctcm_main.h" 56#include "ctcm_main.h"
57#include "ctcm_mpc.h"
58#include "ctcm_fsms.h" 58#include "ctcm_fsms.h"
59 59
60static const struct xid2 init_xid = { 60static const struct xid2 init_xid = {
@@ -132,7 +132,7 @@ void ctcmpc_dumpit(char *buf, int len)
132 __u32 ct, sw, rm, dup; 132 __u32 ct, sw, rm, dup;
133 char *ptr, *rptr; 133 char *ptr, *rptr;
134 char tbuf[82], tdup[82]; 134 char tbuf[82], tdup[82];
135 #if (UTS_MACHINE == s390x) 135 #ifdef CONFIG_64BIT
136 char addr[22]; 136 char addr[22];
137 #else 137 #else
138 char addr[12]; 138 char addr[12];
@@ -149,8 +149,8 @@ void ctcmpc_dumpit(char *buf, int len)
149 149
150 for (ct = 0; ct < len; ct++, ptr++, rptr++) { 150 for (ct = 0; ct < len; ct++, ptr++, rptr++) {
151 if (sw == 0) { 151 if (sw == 0) {
152 #if (UTS_MACHINE == s390x) 152 #ifdef CONFIG_64BIT
153 sprintf(addr, "%16.16lx", (__u64)rptr); 153 sprintf(addr, "%16.16llx", (__u64)rptr);
154 #else 154 #else
155 sprintf(addr, "%8.8X", (__u32)rptr); 155 sprintf(addr, "%8.8X", (__u32)rptr);
156 #endif 156 #endif
@@ -164,8 +164,8 @@ void ctcmpc_dumpit(char *buf, int len)
164 if (sw == 8) 164 if (sw == 8)
165 strcat(bhex, " "); 165 strcat(bhex, " ");
166 166
167 #if (UTS_MACHINE == s390x) 167 #if CONFIG_64BIT
168 sprintf(tbuf, "%2.2lX", (__u64)*ptr); 168 sprintf(tbuf, "%2.2llX", (__u64)*ptr);
169 #else 169 #else
170 sprintf(tbuf, "%2.2X", (__u32)*ptr); 170 sprintf(tbuf, "%2.2X", (__u32)*ptr);
171 #endif 171 #endif
diff --git a/drivers/s390/net/lcs.c b/drivers/s390/net/lcs.c
index 863fc2197155..687efe4d589a 100644
--- a/drivers/s390/net/lcs.c
+++ b/drivers/s390/net/lcs.c
@@ -2240,7 +2240,7 @@ __lcs_shutdown_device(struct ccwgroup_device *ccwgdev, int recovery_mode)
2240{ 2240{
2241 struct lcs_card *card; 2241 struct lcs_card *card;
2242 enum lcs_dev_states recover_state; 2242 enum lcs_dev_states recover_state;
2243 int ret; 2243 int ret = 0, ret2 = 0, ret3 = 0;
2244 2244
2245 LCS_DBF_TEXT(3, setup, "shtdndev"); 2245 LCS_DBF_TEXT(3, setup, "shtdndev");
2246 card = dev_get_drvdata(&ccwgdev->dev); 2246 card = dev_get_drvdata(&ccwgdev->dev);
@@ -2255,13 +2255,15 @@ __lcs_shutdown_device(struct ccwgroup_device *ccwgdev, int recovery_mode)
2255 recover_state = card->state; 2255 recover_state = card->state;
2256 2256
2257 ret = lcs_stop_device(card->dev); 2257 ret = lcs_stop_device(card->dev);
2258 ret = ccw_device_set_offline(card->read.ccwdev); 2258 ret2 = ccw_device_set_offline(card->read.ccwdev);
2259 ret = ccw_device_set_offline(card->write.ccwdev); 2259 ret3 = ccw_device_set_offline(card->write.ccwdev);
2260 if (!ret)
2261 ret = (ret2) ? ret2 : ret3;
2262 if (ret)
2263 LCS_DBF_TEXT_(3, setup, "1err:%d", ret);
2260 if (recover_state == DEV_STATE_UP) { 2264 if (recover_state == DEV_STATE_UP) {
2261 card->state = DEV_STATE_RECOVER; 2265 card->state = DEV_STATE_RECOVER;
2262 } 2266 }
2263 if (ret)
2264 return ret;
2265 return 0; 2267 return 0;
2266} 2268}
2267 2269
diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h
index 4abc79d3963f..ec7921b5138e 100644
--- a/drivers/s390/net/qeth_core.h
+++ b/drivers/s390/net/qeth_core.h
@@ -906,6 +906,7 @@ void qeth_prepare_ipa_cmd(struct qeth_card *, struct qeth_cmd_buffer *, char);
906struct qeth_cmd_buffer *qeth_wait_for_buffer(struct qeth_channel *); 906struct qeth_cmd_buffer *qeth_wait_for_buffer(struct qeth_channel *);
907int qeth_mdio_read(struct net_device *, int, int); 907int qeth_mdio_read(struct net_device *, int, int);
908int qeth_snmp_command(struct qeth_card *, char __user *); 908int qeth_snmp_command(struct qeth_card *, char __user *);
909int qeth_query_oat_command(struct qeth_card *, char __user *);
909struct qeth_cmd_buffer *qeth_get_adapter_cmd(struct qeth_card *, __u32, __u32); 910struct qeth_cmd_buffer *qeth_get_adapter_cmd(struct qeth_card *, __u32, __u32);
910int qeth_default_setadapterparms_cb(struct qeth_card *, struct qeth_reply *, 911int qeth_default_setadapterparms_cb(struct qeth_card *, struct qeth_reply *,
911 unsigned long); 912 unsigned long);
diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c
index 9c3f38da4c01..120955c66410 100644
--- a/drivers/s390/net/qeth_core_main.c
+++ b/drivers/s390/net/qeth_core_main.c
@@ -26,6 +26,7 @@
26#include <asm/ebcdic.h> 26#include <asm/ebcdic.h>
27#include <asm/io.h> 27#include <asm/io.h>
28#include <asm/sysinfo.h> 28#include <asm/sysinfo.h>
29#include <asm/compat.h>
29 30
30#include "qeth_core.h" 31#include "qeth_core.h"
31 32
@@ -50,6 +51,7 @@ static struct kmem_cache *qeth_qdio_outbuf_cache;
50static struct device *qeth_core_root_dev; 51static struct device *qeth_core_root_dev;
51static unsigned int known_devices[][6] = QETH_MODELLIST_ARRAY; 52static unsigned int known_devices[][6] = QETH_MODELLIST_ARRAY;
52static struct lock_class_key qdio_out_skb_queue_key; 53static struct lock_class_key qdio_out_skb_queue_key;
54static struct mutex qeth_mod_mutex;
53 55
54static void qeth_send_control_data_cb(struct qeth_channel *, 56static void qeth_send_control_data_cb(struct qeth_channel *,
55 struct qeth_cmd_buffer *); 57 struct qeth_cmd_buffer *);
@@ -677,6 +679,7 @@ void qeth_release_buffer(struct qeth_channel *channel,
677 iob->callback = qeth_send_control_data_cb; 679 iob->callback = qeth_send_control_data_cb;
678 iob->rc = 0; 680 iob->rc = 0;
679 spin_unlock_irqrestore(&channel->iob_lock, flags); 681 spin_unlock_irqrestore(&channel->iob_lock, flags);
682 wake_up(&channel->wait_q);
680} 683}
681EXPORT_SYMBOL_GPL(qeth_release_buffer); 684EXPORT_SYMBOL_GPL(qeth_release_buffer);
682 685
@@ -2942,8 +2945,8 @@ static int qeth_query_ipassists_cb(struct qeth_card *card,
2942 card->options.ipa6.enabled_funcs = cmd->hdr.ipa_enabled; 2945 card->options.ipa6.enabled_funcs = cmd->hdr.ipa_enabled;
2943 } 2946 }
2944 QETH_DBF_TEXT(SETUP, 2, "suppenbl"); 2947 QETH_DBF_TEXT(SETUP, 2, "suppenbl");
2945 QETH_DBF_TEXT_(SETUP, 2, "%x", cmd->hdr.ipa_supported); 2948 QETH_DBF_TEXT_(SETUP, 2, "%08x", (__u32)cmd->hdr.ipa_supported);
2946 QETH_DBF_TEXT_(SETUP, 2, "%x", cmd->hdr.ipa_enabled); 2949 QETH_DBF_TEXT_(SETUP, 2, "%08x", (__u32)cmd->hdr.ipa_enabled);
2947 return 0; 2950 return 0;
2948} 2951}
2949 2952
@@ -4319,7 +4322,7 @@ static int qeth_snmp_command_cb(struct qeth_card *card,
4319 /* check if there is enough room in userspace */ 4322 /* check if there is enough room in userspace */
4320 if ((qinfo->udata_len - qinfo->udata_offset) < data_len) { 4323 if ((qinfo->udata_len - qinfo->udata_offset) < data_len) {
4321 QETH_CARD_TEXT_(card, 4, "scer3%i", -ENOMEM); 4324 QETH_CARD_TEXT_(card, 4, "scer3%i", -ENOMEM);
4322 cmd->hdr.return_code = -ENOMEM; 4325 cmd->hdr.return_code = IPA_RC_ENOMEM;
4323 return 0; 4326 return 0;
4324 } 4327 }
4325 QETH_CARD_TEXT_(card, 4, "snore%i", 4328 QETH_CARD_TEXT_(card, 4, "snore%i",
@@ -4402,6 +4405,104 @@ int qeth_snmp_command(struct qeth_card *card, char __user *udata)
4402} 4405}
4403EXPORT_SYMBOL_GPL(qeth_snmp_command); 4406EXPORT_SYMBOL_GPL(qeth_snmp_command);
4404 4407
4408static int qeth_setadpparms_query_oat_cb(struct qeth_card *card,
4409 struct qeth_reply *reply, unsigned long data)
4410{
4411 struct qeth_ipa_cmd *cmd;
4412 struct qeth_qoat_priv *priv;
4413 char *resdata;
4414 int resdatalen;
4415
4416 QETH_CARD_TEXT(card, 3, "qoatcb");
4417
4418 cmd = (struct qeth_ipa_cmd *)data;
4419 priv = (struct qeth_qoat_priv *)reply->param;
4420 resdatalen = cmd->data.setadapterparms.hdr.cmdlength;
4421 resdata = (char *)data + 28;
4422
4423 if (resdatalen > (priv->buffer_len - priv->response_len)) {
4424 cmd->hdr.return_code = IPA_RC_FFFF;
4425 return 0;
4426 }
4427
4428 memcpy((priv->buffer + priv->response_len), resdata,
4429 resdatalen);
4430 priv->response_len += resdatalen;
4431
4432 if (cmd->data.setadapterparms.hdr.seq_no <
4433 cmd->data.setadapterparms.hdr.used_total)
4434 return 1;
4435 return 0;
4436}
4437
4438int qeth_query_oat_command(struct qeth_card *card, char __user *udata)
4439{
4440 int rc = 0;
4441 struct qeth_cmd_buffer *iob;
4442 struct qeth_ipa_cmd *cmd;
4443 struct qeth_query_oat *oat_req;
4444 struct qeth_query_oat_data oat_data;
4445 struct qeth_qoat_priv priv;
4446 void __user *tmp;
4447
4448 QETH_CARD_TEXT(card, 3, "qoatcmd");
4449
4450 if (!qeth_adp_supported(card, IPA_SETADP_QUERY_OAT)) {
4451 rc = -EOPNOTSUPP;
4452 goto out;
4453 }
4454
4455 if (copy_from_user(&oat_data, udata,
4456 sizeof(struct qeth_query_oat_data))) {
4457 rc = -EFAULT;
4458 goto out;
4459 }
4460
4461 priv.buffer_len = oat_data.buffer_len;
4462 priv.response_len = 0;
4463 priv.buffer = kzalloc(oat_data.buffer_len, GFP_KERNEL);
4464 if (!priv.buffer) {
4465 rc = -ENOMEM;
4466 goto out;
4467 }
4468
4469 iob = qeth_get_adapter_cmd(card, IPA_SETADP_QUERY_OAT,
4470 sizeof(struct qeth_ipacmd_setadpparms_hdr) +
4471 sizeof(struct qeth_query_oat));
4472 cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
4473 oat_req = &cmd->data.setadapterparms.data.query_oat;
4474 oat_req->subcmd_code = oat_data.command;
4475
4476 rc = qeth_send_ipa_cmd(card, iob, qeth_setadpparms_query_oat_cb,
4477 &priv);
4478 if (!rc) {
4479 if (is_compat_task())
4480 tmp = compat_ptr(oat_data.ptr);
4481 else
4482 tmp = (void __user *)(unsigned long)oat_data.ptr;
4483
4484 if (copy_to_user(tmp, priv.buffer,
4485 priv.response_len)) {
4486 rc = -EFAULT;
4487 goto out_free;
4488 }
4489
4490 oat_data.response_len = priv.response_len;
4491
4492 if (copy_to_user(udata, &oat_data,
4493 sizeof(struct qeth_query_oat_data)))
4494 rc = -EFAULT;
4495 } else
4496 if (rc == IPA_RC_FFFF)
4497 rc = -EFAULT;
4498
4499out_free:
4500 kfree(priv.buffer);
4501out:
4502 return rc;
4503}
4504EXPORT_SYMBOL_GPL(qeth_query_oat_command);
4505
4405static inline int qeth_get_qdio_q_format(struct qeth_card *card) 4506static inline int qeth_get_qdio_q_format(struct qeth_card *card)
4406{ 4507{
4407 switch (card->info.type) { 4508 switch (card->info.type) {
@@ -4940,6 +5041,7 @@ int qeth_core_load_discipline(struct qeth_card *card,
4940 enum qeth_discipline_id discipline) 5041 enum qeth_discipline_id discipline)
4941{ 5042{
4942 int rc = 0; 5043 int rc = 0;
5044 mutex_lock(&qeth_mod_mutex);
4943 switch (discipline) { 5045 switch (discipline) {
4944 case QETH_DISCIPLINE_LAYER3: 5046 case QETH_DISCIPLINE_LAYER3:
4945 card->discipline.ccwgdriver = try_then_request_module( 5047 card->discipline.ccwgdriver = try_then_request_module(
@@ -4957,6 +5059,7 @@ int qeth_core_load_discipline(struct qeth_card *card,
4957 "support discipline %d\n", discipline); 5059 "support discipline %d\n", discipline);
4958 rc = -EINVAL; 5060 rc = -EINVAL;
4959 } 5061 }
5062 mutex_unlock(&qeth_mod_mutex);
4960 return rc; 5063 return rc;
4961} 5064}
4962 5065
@@ -5440,6 +5543,7 @@ static int __init qeth_core_init(void)
5440 pr_info("loading core functions\n"); 5543 pr_info("loading core functions\n");
5441 INIT_LIST_HEAD(&qeth_core_card_list.list); 5544 INIT_LIST_HEAD(&qeth_core_card_list.list);
5442 rwlock_init(&qeth_core_card_list.rwlock); 5545 rwlock_init(&qeth_core_card_list.rwlock);
5546 mutex_init(&qeth_mod_mutex);
5443 5547
5444 rc = qeth_register_dbf_views(); 5548 rc = qeth_register_dbf_views();
5445 if (rc) 5549 if (rc)
diff --git a/drivers/s390/net/qeth_core_mpc.c b/drivers/s390/net/qeth_core_mpc.c
index ec24901c802c..7fab6544def6 100644
--- a/drivers/s390/net/qeth_core_mpc.c
+++ b/drivers/s390/net/qeth_core_mpc.c
@@ -207,6 +207,7 @@ static struct ipa_rc_msg qeth_ipa_rc_msg[] = {
207 {IPA_RC_MC_ADDR_ALREADY_DEFINED, "Multicast address already defined"}, 207 {IPA_RC_MC_ADDR_ALREADY_DEFINED, "Multicast address already defined"},
208 {IPA_RC_LAN_OFFLINE, "STRTLAN_LAN_DISABLED - LAN offline"}, 208 {IPA_RC_LAN_OFFLINE, "STRTLAN_LAN_DISABLED - LAN offline"},
209 {IPA_RC_INVALID_IP_VERSION2, "Invalid IP version"}, 209 {IPA_RC_INVALID_IP_VERSION2, "Invalid IP version"},
210 {IPA_RC_ENOMEM, "Memory problem"},
210 {IPA_RC_FFFF, "Unknown Error"} 211 {IPA_RC_FFFF, "Unknown Error"}
211}; 212};
212 213
diff --git a/drivers/s390/net/qeth_core_mpc.h b/drivers/s390/net/qeth_core_mpc.h
index e5a9d1c03839..ff41e42004ac 100644
--- a/drivers/s390/net/qeth_core_mpc.h
+++ b/drivers/s390/net/qeth_core_mpc.h
@@ -190,6 +190,7 @@ enum qeth_ipa_return_codes {
190 IPA_RC_MC_ADDR_ALREADY_DEFINED = 0xe013, 190 IPA_RC_MC_ADDR_ALREADY_DEFINED = 0xe013,
191 IPA_RC_LAN_OFFLINE = 0xe080, 191 IPA_RC_LAN_OFFLINE = 0xe080,
192 IPA_RC_INVALID_IP_VERSION2 = 0xf001, 192 IPA_RC_INVALID_IP_VERSION2 = 0xf001,
193 IPA_RC_ENOMEM = 0xfffe,
193 IPA_RC_FFFF = 0xffff 194 IPA_RC_FFFF = 0xffff
194}; 195};
195/* for DELIP */ 196/* for DELIP */
@@ -249,6 +250,7 @@ enum qeth_ipa_setadp_cmd {
249 IPA_SETADP_SET_PROMISC_MODE = 0x00000800L, 250 IPA_SETADP_SET_PROMISC_MODE = 0x00000800L,
250 IPA_SETADP_SET_DIAG_ASSIST = 0x00002000L, 251 IPA_SETADP_SET_DIAG_ASSIST = 0x00002000L,
251 IPA_SETADP_SET_ACCESS_CONTROL = 0x00010000L, 252 IPA_SETADP_SET_ACCESS_CONTROL = 0x00010000L,
253 IPA_SETADP_QUERY_OAT = 0x00080000L,
252}; 254};
253enum qeth_ipa_mac_ops { 255enum qeth_ipa_mac_ops {
254 CHANGE_ADDR_READ_MAC = 0, 256 CHANGE_ADDR_READ_MAC = 0,
@@ -398,6 +400,17 @@ struct qeth_set_access_ctrl {
398 __u32 subcmd_code; 400 __u32 subcmd_code;
399} __attribute__((packed)); 401} __attribute__((packed));
400 402
403struct qeth_query_oat {
404 __u32 subcmd_code;
405 __u8 reserved[12];
406} __packed;
407
408struct qeth_qoat_priv {
409 __u32 buffer_len;
410 __u32 response_len;
411 char *buffer;
412};
413
401struct qeth_ipacmd_setadpparms_hdr { 414struct qeth_ipacmd_setadpparms_hdr {
402 __u32 supp_hw_cmds; 415 __u32 supp_hw_cmds;
403 __u32 reserved1; 416 __u32 reserved1;
@@ -417,6 +430,7 @@ struct qeth_ipacmd_setadpparms {
417 struct qeth_change_addr change_addr; 430 struct qeth_change_addr change_addr;
418 struct qeth_snmp_cmd snmp; 431 struct qeth_snmp_cmd snmp;
419 struct qeth_set_access_ctrl set_access_ctrl; 432 struct qeth_set_access_ctrl set_access_ctrl;
433 struct qeth_query_oat query_oat;
420 __u32 mode; 434 __u32 mode;
421 } data; 435 } data;
422} __attribute__ ((packed)); 436} __attribute__ ((packed));
diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c
index c12967133114..0e7c29d1d7ef 100644
--- a/drivers/s390/net/qeth_l2_main.c
+++ b/drivers/s390/net/qeth_l2_main.c
@@ -75,6 +75,9 @@ static int qeth_l2_do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
75 mii_data->val_out = qeth_mdio_read(dev, 75 mii_data->val_out = qeth_mdio_read(dev,
76 mii_data->phy_id, mii_data->reg_num); 76 mii_data->phy_id, mii_data->reg_num);
77 break; 77 break;
78 case SIOC_QETH_QUERY_OAT:
79 rc = qeth_query_oat_command(card, rq->ifr_ifru.ifru_data);
80 break;
78 default: 81 default:
79 rc = -EOPNOTSUPP; 82 rc = -EOPNOTSUPP;
80 } 83 }
@@ -573,7 +576,6 @@ static int qeth_l2_send_setmac_cb(struct qeth_card *card,
573 default: 576 default:
574 break; 577 break;
575 } 578 }
576 cmd->hdr.return_code = -EIO;
577 } else { 579 } else {
578 card->info.mac_bits |= QETH_LAYER2_MAC_REGISTERED; 580 card->info.mac_bits |= QETH_LAYER2_MAC_REGISTERED;
579 memcpy(card->dev->dev_addr, cmd->data.setdelmac.mac, 581 memcpy(card->dev->dev_addr, cmd->data.setdelmac.mac,
@@ -602,7 +604,6 @@ static int qeth_l2_send_delmac_cb(struct qeth_card *card,
602 cmd = (struct qeth_ipa_cmd *) data; 604 cmd = (struct qeth_ipa_cmd *) data;
603 if (cmd->hdr.return_code) { 605 if (cmd->hdr.return_code) {
604 QETH_CARD_TEXT_(card, 2, "err%d", cmd->hdr.return_code); 606 QETH_CARD_TEXT_(card, 2, "err%d", cmd->hdr.return_code);
605 cmd->hdr.return_code = -EIO;
606 return 0; 607 return 0;
607 } 608 }
608 card->info.mac_bits &= ~QETH_LAYER2_MAC_REGISTERED; 609 card->info.mac_bits &= ~QETH_LAYER2_MAC_REGISTERED;
@@ -679,7 +680,7 @@ static int qeth_l2_set_mac_address(struct net_device *dev, void *p)
679 rc = qeth_l2_send_delmac(card, &card->dev->dev_addr[0]); 680 rc = qeth_l2_send_delmac(card, &card->dev->dev_addr[0]);
680 if (!rc) 681 if (!rc)
681 rc = qeth_l2_send_setmac(card, addr->sa_data); 682 rc = qeth_l2_send_setmac(card, addr->sa_data);
682 return rc; 683 return rc ? -EINVAL : 0;
683} 684}
684 685
685static void qeth_l2_set_multicast_list(struct net_device *dev) 686static void qeth_l2_set_multicast_list(struct net_device *dev)
diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c
index 9648e4e68337..f85921607686 100644
--- a/drivers/s390/net/qeth_l3_main.c
+++ b/drivers/s390/net/qeth_l3_main.c
@@ -28,6 +28,8 @@
28 28
29#include <net/ip.h> 29#include <net/ip.h>
30#include <net/arp.h> 30#include <net/arp.h>
31#include <net/route.h>
32#include <net/ip6_fib.h>
31#include <net/ip6_checksum.h> 33#include <net/ip6_checksum.h>
32#include <net/iucv/af_iucv.h> 34#include <net/iucv/af_iucv.h>
33 35
@@ -2428,7 +2430,7 @@ static int qeth_l3_arp_query_cb(struct qeth_card *card,
2428 2430
2429 if ((qinfo->udata_len - qinfo->udata_offset) < esize) { 2431 if ((qinfo->udata_len - qinfo->udata_offset) < esize) {
2430 QETH_CARD_TEXT_(card, 4, "qaer3%i", -ENOMEM); 2432 QETH_CARD_TEXT_(card, 4, "qaer3%i", -ENOMEM);
2431 cmd->hdr.return_code = -ENOMEM; 2433 cmd->hdr.return_code = IPA_RC_ENOMEM;
2432 goto out_error; 2434 goto out_error;
2433 } 2435 }
2434 2436
@@ -2743,6 +2745,9 @@ static int qeth_l3_do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
2743 mii_data->phy_id, 2745 mii_data->phy_id,
2744 mii_data->reg_num); 2746 mii_data->reg_num);
2745 break; 2747 break;
2748 case SIOC_QETH_QUERY_OAT:
2749 rc = qeth_query_oat_command(card, rq->ifr_ifru.ifru_data);
2750 break;
2746 default: 2751 default:
2747 rc = -EOPNOTSUPP; 2752 rc = -EOPNOTSUPP;
2748 } 2753 }
@@ -2832,7 +2837,6 @@ static void qeth_l3_fill_af_iucv_hdr(struct qeth_card *card,
2832static void qeth_l3_fill_header(struct qeth_card *card, struct qeth_hdr *hdr, 2837static void qeth_l3_fill_header(struct qeth_card *card, struct qeth_hdr *hdr,
2833 struct sk_buff *skb, int ipv, int cast_type) 2838 struct sk_buff *skb, int ipv, int cast_type)
2834{ 2839{
2835 struct neighbour *n = NULL;
2836 struct dst_entry *dst; 2840 struct dst_entry *dst;
2837 2841
2838 memset(hdr, 0, sizeof(struct qeth_hdr)); 2842 memset(hdr, 0, sizeof(struct qeth_hdr));
@@ -2855,33 +2859,29 @@ static void qeth_l3_fill_header(struct qeth_card *card, struct qeth_hdr *hdr,
2855 2859
2856 rcu_read_lock(); 2860 rcu_read_lock();
2857 dst = skb_dst(skb); 2861 dst = skb_dst(skb);
2858 if (dst)
2859 n = dst_get_neighbour_noref(dst);
2860 if (ipv == 4) { 2862 if (ipv == 4) {
2863 struct rtable *rt = (struct rtable *) dst;
2864 __be32 *pkey = &ip_hdr(skb)->daddr;
2865
2866 if (rt->rt_gateway)
2867 pkey = &rt->rt_gateway;
2868
2861 /* IPv4 */ 2869 /* IPv4 */
2862 hdr->hdr.l3.flags = qeth_l3_get_qeth_hdr_flags4(cast_type); 2870 hdr->hdr.l3.flags = qeth_l3_get_qeth_hdr_flags4(cast_type);
2863 memset(hdr->hdr.l3.dest_addr, 0, 12); 2871 memset(hdr->hdr.l3.dest_addr, 0, 12);
2864 if (n) { 2872 *((__be32 *) (&hdr->hdr.l3.dest_addr[12])) = *pkey;
2865 *((u32 *) (&hdr->hdr.l3.dest_addr[12])) =
2866 *((u32 *) n->primary_key);
2867 } else {
2868 /* fill in destination address used in ip header */
2869 *((u32 *) (&hdr->hdr.l3.dest_addr[12])) =
2870 ip_hdr(skb)->daddr;
2871 }
2872 } else if (ipv == 6) { 2873 } else if (ipv == 6) {
2874 struct rt6_info *rt = (struct rt6_info *) dst;
2875 struct in6_addr *pkey = &ipv6_hdr(skb)->daddr;
2876
2877 if (!ipv6_addr_any(&rt->rt6i_gateway))
2878 pkey = &rt->rt6i_gateway;
2879
2873 /* IPv6 */ 2880 /* IPv6 */
2874 hdr->hdr.l3.flags = qeth_l3_get_qeth_hdr_flags6(cast_type); 2881 hdr->hdr.l3.flags = qeth_l3_get_qeth_hdr_flags6(cast_type);
2875 if (card->info.type == QETH_CARD_TYPE_IQD) 2882 if (card->info.type == QETH_CARD_TYPE_IQD)
2876 hdr->hdr.l3.flags &= ~QETH_HDR_PASSTHRU; 2883 hdr->hdr.l3.flags &= ~QETH_HDR_PASSTHRU;
2877 if (n) { 2884 memcpy(hdr->hdr.l3.dest_addr, pkey, 16);
2878 memcpy(hdr->hdr.l3.dest_addr,
2879 n->primary_key, 16);
2880 } else {
2881 /* fill in destination address used in ip header */
2882 memcpy(hdr->hdr.l3.dest_addr,
2883 &ipv6_hdr(skb)->daddr, 16);
2884 }
2885 } else { 2885 } else {
2886 /* passthrough */ 2886 /* passthrough */
2887 if ((skb->dev->type == ARPHRD_IEEE802_TR) && 2887 if ((skb->dev->type == ARPHRD_IEEE802_TR) &&