aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFrank Blaschka <frank.blaschka@de.ibm.com>2012-02-07 19:19:49 -0500
committerDavid S. Miller <davem@davemloft.net>2012-02-08 18:50:20 -0500
commitc3ab96f36aa308fa5bf432d5a4dafc80b7373805 (patch)
tree8ab0bb57340bf267fd6921b8f8db008b1b352cbd
parent51363b8751a673a00ad48eea895266396d53fa52 (diff)
qeth: add query OSA address table support
Add qeth device private ioctl to query the OSA address table. This helps debugging hw related problems. Signed-off-by: Frank Blaschka <frank.blaschka@de.ibm.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--arch/s390/include/asm/qeth.h7
-rw-r--r--drivers/s390/net/qeth_core.h1
-rw-r--r--drivers/s390/net/qeth_core_main.c99
-rw-r--r--drivers/s390/net/qeth_core_mpc.h13
-rw-r--r--drivers/s390/net/qeth_l2_main.c3
-rw-r--r--drivers/s390/net/qeth_l3_main.c3
6 files changed, 126 insertions, 0 deletions
diff --git a/arch/s390/include/asm/qeth.h b/arch/s390/include/asm/qeth.h
index 90efda0b137d..2c7c898c03e4 100644
--- a/arch/s390/include/asm/qeth.h
+++ b/arch/s390/include/asm/qeth.h
@@ -20,6 +20,7 @@
20#define SIOC_QETH_ARP_FLUSH_CACHE (SIOCDEVPRIVATE + 4) 20#define SIOC_QETH_ARP_FLUSH_CACHE (SIOCDEVPRIVATE + 4)
21#define SIOC_QETH_ADP_SET_SNMP_CONTROL (SIOCDEVPRIVATE + 5) 21#define SIOC_QETH_ADP_SET_SNMP_CONTROL (SIOCDEVPRIVATE + 5)
22#define SIOC_QETH_GET_CARD_TYPE (SIOCDEVPRIVATE + 6) 22#define SIOC_QETH_GET_CARD_TYPE (SIOCDEVPRIVATE + 6)
23#define SIOC_QETH_QUERY_OAT (SIOCDEVPRIVATE + 7)
23 24
24struct qeth_arp_cache_entry { 25struct qeth_arp_cache_entry {
25 __u8 macaddr[6]; 26 __u8 macaddr[6];
@@ -107,4 +108,10 @@ struct qeth_arp_query_user_data {
107 char *entries; 108 char *entries;
108} __attribute__((packed)); 109} __attribute__((packed));
109 110
111struct qeth_query_oat_data {
112 __u32 command;
113 __u32 buffer_len;
114 __u32 response_len;
115 __u64 ptr;
116};
110#endif /* __ASM_S390_QETH_IOCTL_H__ */ 117#endif /* __ASM_S390_QETH_IOCTL_H__ */
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..0565584b52c3 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
@@ -4402,6 +4403,104 @@ int qeth_snmp_command(struct qeth_card *card, char __user *udata)
4402} 4403}
4403EXPORT_SYMBOL_GPL(qeth_snmp_command); 4404EXPORT_SYMBOL_GPL(qeth_snmp_command);
4404 4405
4406static int qeth_setadpparms_query_oat_cb(struct qeth_card *card,
4407 struct qeth_reply *reply, unsigned long data)
4408{
4409 struct qeth_ipa_cmd *cmd;
4410 struct qeth_qoat_priv *priv;
4411 char *resdata;
4412 int resdatalen;
4413
4414 QETH_CARD_TEXT(card, 3, "qoatcb");
4415
4416 cmd = (struct qeth_ipa_cmd *)data;
4417 priv = (struct qeth_qoat_priv *)reply->param;
4418 resdatalen = cmd->data.setadapterparms.hdr.cmdlength;
4419 resdata = (char *)data + 28;
4420
4421 if (resdatalen > (priv->buffer_len - priv->response_len)) {
4422 cmd->hdr.return_code = IPA_RC_FFFF;
4423 return 0;
4424 }
4425
4426 memcpy((priv->buffer + priv->response_len), resdata,
4427 resdatalen);
4428 priv->response_len += resdatalen;
4429
4430 if (cmd->data.setadapterparms.hdr.seq_no <
4431 cmd->data.setadapterparms.hdr.used_total)
4432 return 1;
4433 return 0;
4434}
4435
4436int qeth_query_oat_command(struct qeth_card *card, char __user *udata)
4437{
4438 int rc = 0;
4439 struct qeth_cmd_buffer *iob;
4440 struct qeth_ipa_cmd *cmd;
4441 struct qeth_query_oat *oat_req;
4442 struct qeth_query_oat_data oat_data;
4443 struct qeth_qoat_priv priv;
4444 void __user *tmp;
4445
4446 QETH_CARD_TEXT(card, 3, "qoatcmd");
4447
4448 if (!qeth_adp_supported(card, IPA_SETADP_QUERY_OAT)) {
4449 rc = -EOPNOTSUPP;
4450 goto out;
4451 }
4452
4453 if (copy_from_user(&oat_data, udata,
4454 sizeof(struct qeth_query_oat_data))) {
4455 rc = -EFAULT;
4456 goto out;
4457 }
4458
4459 priv.buffer_len = oat_data.buffer_len;
4460 priv.response_len = 0;
4461 priv.buffer = kzalloc(oat_data.buffer_len, GFP_KERNEL);
4462 if (!priv.buffer) {
4463 rc = -ENOMEM;
4464 goto out;
4465 }
4466
4467 iob = qeth_get_adapter_cmd(card, IPA_SETADP_QUERY_OAT,
4468 sizeof(struct qeth_ipacmd_setadpparms_hdr) +
4469 sizeof(struct qeth_query_oat));
4470 cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
4471 oat_req = &cmd->data.setadapterparms.data.query_oat;
4472 oat_req->subcmd_code = oat_data.command;
4473
4474 rc = qeth_send_ipa_cmd(card, iob, qeth_setadpparms_query_oat_cb,
4475 &priv);
4476 if (!rc) {
4477 if (is_compat_task())
4478 tmp = compat_ptr(oat_data.ptr);
4479 else
4480 tmp = (void __user *)(unsigned long)oat_data.ptr;
4481
4482 if (copy_to_user(tmp, priv.buffer,
4483 priv.response_len)) {
4484 rc = -EFAULT;
4485 goto out_free;
4486 }
4487
4488 oat_data.response_len = priv.response_len;
4489
4490 if (copy_to_user(udata, &oat_data,
4491 sizeof(struct qeth_query_oat_data)))
4492 rc = -EFAULT;
4493 } else
4494 if (rc == IPA_RC_FFFF)
4495 rc = -EFAULT;
4496
4497out_free:
4498 kfree(priv.buffer);
4499out:
4500 return rc;
4501}
4502EXPORT_SYMBOL_GPL(qeth_query_oat_command);
4503
4405static inline int qeth_get_qdio_q_format(struct qeth_card *card) 4504static inline int qeth_get_qdio_q_format(struct qeth_card *card)
4406{ 4505{
4407 switch (card->info.type) { 4506 switch (card->info.type) {
diff --git a/drivers/s390/net/qeth_core_mpc.h b/drivers/s390/net/qeth_core_mpc.h
index e5a9d1c03839..578e19a2de6b 100644
--- a/drivers/s390/net/qeth_core_mpc.h
+++ b/drivers/s390/net/qeth_core_mpc.h
@@ -249,6 +249,7 @@ enum qeth_ipa_setadp_cmd {
249 IPA_SETADP_SET_PROMISC_MODE = 0x00000800L, 249 IPA_SETADP_SET_PROMISC_MODE = 0x00000800L,
250 IPA_SETADP_SET_DIAG_ASSIST = 0x00002000L, 250 IPA_SETADP_SET_DIAG_ASSIST = 0x00002000L,
251 IPA_SETADP_SET_ACCESS_CONTROL = 0x00010000L, 251 IPA_SETADP_SET_ACCESS_CONTROL = 0x00010000L,
252 IPA_SETADP_QUERY_OAT = 0x00080000L,
252}; 253};
253enum qeth_ipa_mac_ops { 254enum qeth_ipa_mac_ops {
254 CHANGE_ADDR_READ_MAC = 0, 255 CHANGE_ADDR_READ_MAC = 0,
@@ -398,6 +399,17 @@ struct qeth_set_access_ctrl {
398 __u32 subcmd_code; 399 __u32 subcmd_code;
399} __attribute__((packed)); 400} __attribute__((packed));
400 401
402struct qeth_query_oat {
403 __u32 subcmd_code;
404 __u8 reserved[12];
405} __packed;
406
407struct qeth_qoat_priv {
408 __u32 buffer_len;
409 __u32 response_len;
410 char *buffer;
411};
412
401struct qeth_ipacmd_setadpparms_hdr { 413struct qeth_ipacmd_setadpparms_hdr {
402 __u32 supp_hw_cmds; 414 __u32 supp_hw_cmds;
403 __u32 reserved1; 415 __u32 reserved1;
@@ -417,6 +429,7 @@ struct qeth_ipacmd_setadpparms {
417 struct qeth_change_addr change_addr; 429 struct qeth_change_addr change_addr;
418 struct qeth_snmp_cmd snmp; 430 struct qeth_snmp_cmd snmp;
419 struct qeth_set_access_ctrl set_access_ctrl; 431 struct qeth_set_access_ctrl set_access_ctrl;
432 struct qeth_query_oat query_oat;
420 __u32 mode; 433 __u32 mode;
421 } data; 434 } data;
422} __attribute__ ((packed)); 435} __attribute__ ((packed));
diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c
index c12967133114..e5c9cf15e5c6 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 }
diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c
index 25cd3799a76c..73bf8889984b 100644
--- a/drivers/s390/net/qeth_l3_main.c
+++ b/drivers/s390/net/qeth_l3_main.c
@@ -2745,6 +2745,9 @@ static int qeth_l3_do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
2745 mii_data->phy_id, 2745 mii_data->phy_id,
2746 mii_data->reg_num); 2746 mii_data->reg_num);
2747 break; 2747 break;
2748 case SIOC_QETH_QUERY_OAT:
2749 rc = qeth_query_oat_command(card, rq->ifr_ifru.ifru_data);
2750 break;
2748 default: 2751 default:
2749 rc = -EOPNOTSUPP; 2752 rc = -EOPNOTSUPP;
2750 } 2753 }