diff options
Diffstat (limited to 'drivers/s390/net')
-rw-r--r-- | drivers/s390/net/claw.c | 2 | ||||
-rw-r--r-- | drivers/s390/net/ctcm_main.c | 6 | ||||
-rw-r--r-- | drivers/s390/net/netiucv.c | 2 | ||||
-rw-r--r-- | drivers/s390/net/qeth_core.h | 15 | ||||
-rw-r--r-- | drivers/s390/net/qeth_core_main.c | 200 | ||||
-rw-r--r-- | drivers/s390/net/qeth_core_mpc.h | 17 | ||||
-rw-r--r-- | drivers/s390/net/qeth_core_sys.c | 38 | ||||
-rw-r--r-- | drivers/s390/net/qeth_l2_main.c | 6 | ||||
-rw-r--r-- | drivers/s390/net/qeth_l3_main.c | 3 |
9 files changed, 213 insertions, 76 deletions
diff --git a/drivers/s390/net/claw.c b/drivers/s390/net/claw.c index d837c3c5330f..fbc6701bef30 100644 --- a/drivers/s390/net/claw.c +++ b/drivers/s390/net/claw.c @@ -2915,7 +2915,7 @@ claw_new_device(struct ccwgroup_device *cgdev) "failed with error code %d\n", ret); goto out; } - dev = alloc_netdev(0,"claw%d",claw_init_netdevice); + dev = alloc_netdev(0, "claw%d", NET_NAME_UNKNOWN, claw_init_netdevice); if (!dev) { dev_warn(&cgdev->dev, "Activating the CLAW device failed\n"); diff --git a/drivers/s390/net/ctcm_main.c b/drivers/s390/net/ctcm_main.c index 03b6ad035577..e056dd4fe44d 100644 --- a/drivers/s390/net/ctcm_main.c +++ b/drivers/s390/net/ctcm_main.c @@ -1137,9 +1137,11 @@ static struct net_device *ctcm_init_netdevice(struct ctcm_priv *priv) return NULL; if (IS_MPC(priv)) - dev = alloc_netdev(0, MPC_DEVICE_GENE, ctcm_dev_setup); + dev = alloc_netdev(0, MPC_DEVICE_GENE, NET_NAME_UNKNOWN, + ctcm_dev_setup); else - dev = alloc_netdev(0, CTC_DEVICE_GENE, ctcm_dev_setup); + dev = alloc_netdev(0, CTC_DEVICE_GENE, NET_NAME_UNKNOWN, + ctcm_dev_setup); if (!dev) { CTCM_DBF_TEXT_(ERROR, CTC_DBF_CRIT, diff --git a/drivers/s390/net/netiucv.c b/drivers/s390/net/netiucv.c index ce16d1bdb20a..0a87809c8af7 100644 --- a/drivers/s390/net/netiucv.c +++ b/drivers/s390/net/netiucv.c @@ -2015,7 +2015,7 @@ static struct net_device *netiucv_init_netdevice(char *username, char *userdata) struct net_device *dev; dev = alloc_netdev(sizeof(struct netiucv_priv), "iucv%d", - netiucv_setup_netdevice); + NET_NAME_UNKNOWN, netiucv_setup_netdevice); if (!dev) return NULL; rtnl_lock(); diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h index a2088af51cc5..97ef37b51068 100644 --- a/drivers/s390/net/qeth_core.h +++ b/drivers/s390/net/qeth_core.h @@ -439,10 +439,10 @@ struct qeth_qdio_buffer { }; struct qeth_qdio_q { - struct qdio_buffer qdio_bufs[QDIO_MAX_BUFFERS_PER_Q]; + struct qdio_buffer *qdio_bufs[QDIO_MAX_BUFFERS_PER_Q]; struct qeth_qdio_buffer bufs[QDIO_MAX_BUFFERS_PER_Q]; int next_buf_to_init; -} __attribute__ ((aligned(256))); +}; struct qeth_qdio_out_buffer { struct qdio_buffer *buffer; @@ -465,7 +465,7 @@ enum qeth_out_q_states { }; struct qeth_qdio_out_q { - struct qdio_buffer qdio_bufs[QDIO_MAX_BUFFERS_PER_Q]; + struct qdio_buffer *qdio_bufs[QDIO_MAX_BUFFERS_PER_Q]; struct qeth_qdio_out_buffer *bufs[QDIO_MAX_BUFFERS_PER_Q]; struct qdio_outbuf_state *bufstates; /* convenience pointer */ int queue_no; @@ -483,7 +483,7 @@ struct qeth_qdio_out_q { atomic_t used_buffers; /* indicates whether PCI flag must be set (or if one is outstanding) */ atomic_t set_pci_flags_count; -} __attribute__ ((aligned(256))); +}; struct qeth_qdio_info { atomic_t state; @@ -766,6 +766,11 @@ struct carrier_info { __u32 port_speed; }; +struct qeth_switch_info { + __u32 capabilities; + __u32 settings; +}; + #define QETH_NAPI_WEIGHT NAPI_POLL_WEIGHT struct qeth_card { @@ -946,6 +951,8 @@ struct qeth_cmd_buffer *qeth_wait_for_buffer(struct qeth_channel *); int qeth_mdio_read(struct net_device *, int, int); int qeth_snmp_command(struct qeth_card *, char __user *); int qeth_query_oat_command(struct qeth_card *, char __user *); +int qeth_query_switch_attributes(struct qeth_card *card, + struct qeth_switch_info *sw_info); int qeth_query_card_info(struct qeth_card *card, struct carrier_info *carrier_info); int qeth_send_control_data(struct qeth_card *, int, struct qeth_cmd_buffer *, diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index f54bec54d677..c0d6ba8655c7 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -292,14 +292,43 @@ int qeth_realloc_buffer_pool(struct qeth_card *card, int bufcnt) } EXPORT_SYMBOL_GPL(qeth_realloc_buffer_pool); +static void qeth_free_qdio_queue(struct qeth_qdio_q *q) +{ + if (!q) + return; + + qdio_free_buffers(q->qdio_bufs, QDIO_MAX_BUFFERS_PER_Q); + kfree(q); +} + +static struct qeth_qdio_q *qeth_alloc_qdio_queue(void) +{ + struct qeth_qdio_q *q = kzalloc(sizeof(*q), GFP_KERNEL); + int i; + + if (!q) + return NULL; + + if (qdio_alloc_buffers(q->qdio_bufs, QDIO_MAX_BUFFERS_PER_Q)) { + kfree(q); + return NULL; + } + + for (i = 0; i < QDIO_MAX_BUFFERS_PER_Q; ++i) + q->bufs[i].buffer = q->qdio_bufs[i]; + + QETH_DBF_HEX(SETUP, 2, &q, sizeof(void *)); + return q; +} + static inline int qeth_cq_init(struct qeth_card *card) { int rc; if (card->options.cq == QETH_CQ_ENABLED) { QETH_DBF_TEXT(SETUP, 2, "cqinit"); - memset(card->qdio.c_q->qdio_bufs, 0, - QDIO_MAX_BUFFERS_PER_Q * sizeof(struct qdio_buffer)); + qdio_reset_buffers(card->qdio.c_q->qdio_bufs, + QDIO_MAX_BUFFERS_PER_Q); card->qdio.c_q->next_buf_to_init = 127; rc = do_QDIO(CARD_DDEV(card), QDIO_FLAG_SYNC_INPUT, card->qdio.no_in_queues - 1, 0, @@ -323,21 +352,12 @@ static inline int qeth_alloc_cq(struct qeth_card *card) struct qdio_outbuf_state *outbuf_states; QETH_DBF_TEXT(SETUP, 2, "cqon"); - card->qdio.c_q = kzalloc(sizeof(struct qeth_qdio_q), - GFP_KERNEL); + card->qdio.c_q = qeth_alloc_qdio_queue(); if (!card->qdio.c_q) { rc = -1; goto kmsg_out; } - QETH_DBF_HEX(SETUP, 2, &card->qdio.c_q, sizeof(void *)); - - for (i = 0; i < QDIO_MAX_BUFFERS_PER_Q; ++i) { - card->qdio.c_q->bufs[i].buffer = - &card->qdio.c_q->qdio_bufs[i]; - } - card->qdio.no_in_queues = 2; - card->qdio.out_bufstates = kzalloc(card->qdio.no_out_queues * QDIO_MAX_BUFFERS_PER_Q * @@ -361,7 +381,7 @@ static inline int qeth_alloc_cq(struct qeth_card *card) out: return rc; free_cq_out: - kfree(card->qdio.c_q); + qeth_free_qdio_queue(card->qdio.c_q); card->qdio.c_q = NULL; kmsg_out: dev_err(&card->gdev->dev, "Failed to create completion queue\n"); @@ -372,7 +392,7 @@ static inline void qeth_free_cq(struct qeth_card *card) { if (card->qdio.c_q) { --card->qdio.no_in_queues; - kfree(card->qdio.c_q); + qeth_free_qdio_queue(card->qdio.c_q); card->qdio.c_q = NULL; } kfree(card->qdio.out_bufstates); @@ -1282,35 +1302,6 @@ static void qeth_free_buffer_pool(struct qeth_card *card) } } -static void qeth_free_qdio_buffers(struct qeth_card *card) -{ - int i, j; - - if (atomic_xchg(&card->qdio.state, QETH_QDIO_UNINITIALIZED) == - QETH_QDIO_UNINITIALIZED) - return; - - qeth_free_cq(card); - cancel_delayed_work_sync(&card->buffer_reclaim_work); - for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; ++j) { - if (card->qdio.in_q->bufs[j].rx_skb) - dev_kfree_skb_any(card->qdio.in_q->bufs[j].rx_skb); - } - kfree(card->qdio.in_q); - card->qdio.in_q = NULL; - /* inbound buffer pool */ - qeth_free_buffer_pool(card); - /* free outbound qdio_qs */ - if (card->qdio.out_qs) { - for (i = 0; i < card->qdio.no_out_queues; ++i) { - qeth_clear_outq_buffers(card->qdio.out_qs[i], 1); - kfree(card->qdio.out_qs[i]); - } - kfree(card->qdio.out_qs); - card->qdio.out_qs = NULL; - } -} - static void qeth_clean_channel(struct qeth_channel *channel) { int cnt; @@ -2392,7 +2383,7 @@ static int qeth_init_qdio_out_buf(struct qeth_qdio_out_q *q, int bidx) rc = -ENOMEM; goto out; } - newbuf->buffer = &q->qdio_bufs[bidx]; + newbuf->buffer = q->qdio_bufs[bidx]; skb_queue_head_init(&newbuf->skb_list); lockdep_set_class(&newbuf->skb_list.lock, &qdio_out_skb_queue_key); newbuf->q = q; @@ -2411,6 +2402,28 @@ out: return rc; } +static void qeth_free_qdio_out_buf(struct qeth_qdio_out_q *q) +{ + if (!q) + return; + + qdio_free_buffers(q->qdio_bufs, QDIO_MAX_BUFFERS_PER_Q); + kfree(q); +} + +static struct qeth_qdio_out_q *qeth_alloc_qdio_out_buf(void) +{ + struct qeth_qdio_out_q *q = kzalloc(sizeof(*q), GFP_KERNEL); + + if (!q) + return NULL; + + if (qdio_alloc_buffers(q->qdio_bufs, QDIO_MAX_BUFFERS_PER_Q)) { + kfree(q); + return NULL; + } + return q; +} static int qeth_alloc_qdio_buffers(struct qeth_card *card) { @@ -2422,19 +2435,11 @@ static int qeth_alloc_qdio_buffers(struct qeth_card *card) QETH_QDIO_ALLOCATED) != QETH_QDIO_UNINITIALIZED) return 0; - card->qdio.in_q = kzalloc(sizeof(struct qeth_qdio_q), - GFP_KERNEL); + QETH_DBF_TEXT(SETUP, 2, "inq"); + card->qdio.in_q = qeth_alloc_qdio_queue(); if (!card->qdio.in_q) goto out_nomem; - QETH_DBF_TEXT(SETUP, 2, "inq"); - QETH_DBF_HEX(SETUP, 2, &card->qdio.in_q, sizeof(void *)); - memset(card->qdio.in_q, 0, sizeof(struct qeth_qdio_q)); - /* give inbound qeth_qdio_buffers their qdio_buffers */ - for (i = 0; i < QDIO_MAX_BUFFERS_PER_Q; ++i) { - card->qdio.in_q->bufs[i].buffer = - &card->qdio.in_q->qdio_bufs[i]; - card->qdio.in_q->bufs[i].rx_skb = NULL; - } + /* inbound buffer pool */ if (qeth_alloc_buffer_pool(card)) goto out_freeinq; @@ -2446,8 +2451,7 @@ static int qeth_alloc_qdio_buffers(struct qeth_card *card) if (!card->qdio.out_qs) goto out_freepool; for (i = 0; i < card->qdio.no_out_queues; ++i) { - card->qdio.out_qs[i] = kzalloc(sizeof(struct qeth_qdio_out_q), - GFP_KERNEL); + card->qdio.out_qs[i] = qeth_alloc_qdio_out_buf(); if (!card->qdio.out_qs[i]) goto out_freeoutq; QETH_DBF_TEXT_(SETUP, 2, "outq %i", i); @@ -2476,7 +2480,7 @@ out_freeoutqbufs: } out_freeoutq: while (i > 0) { - kfree(card->qdio.out_qs[--i]); + qeth_free_qdio_out_buf(card->qdio.out_qs[--i]); qeth_clear_outq_buffers(card->qdio.out_qs[i], 1); } kfree(card->qdio.out_qs); @@ -2484,13 +2488,42 @@ out_freeoutq: out_freepool: qeth_free_buffer_pool(card); out_freeinq: - kfree(card->qdio.in_q); + qeth_free_qdio_queue(card->qdio.in_q); card->qdio.in_q = NULL; out_nomem: atomic_set(&card->qdio.state, QETH_QDIO_UNINITIALIZED); return -ENOMEM; } +static void qeth_free_qdio_buffers(struct qeth_card *card) +{ + int i, j; + + if (atomic_xchg(&card->qdio.state, QETH_QDIO_UNINITIALIZED) == + QETH_QDIO_UNINITIALIZED) + return; + + qeth_free_cq(card); + cancel_delayed_work_sync(&card->buffer_reclaim_work); + for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; ++j) { + if (card->qdio.in_q->bufs[j].rx_skb) + dev_kfree_skb_any(card->qdio.in_q->bufs[j].rx_skb); + } + qeth_free_qdio_queue(card->qdio.in_q); + card->qdio.in_q = NULL; + /* inbound buffer pool */ + qeth_free_buffer_pool(card); + /* free outbound qdio_qs */ + if (card->qdio.out_qs) { + for (i = 0; i < card->qdio.no_out_queues; ++i) { + qeth_clear_outq_buffers(card->qdio.out_qs[i], 1); + qeth_free_qdio_out_buf(card->qdio.out_qs[i]); + } + kfree(card->qdio.out_qs); + card->qdio.out_qs = NULL; + } +} + static void qeth_create_qib_param_field(struct qeth_card *card, char *param_field) { @@ -2788,8 +2821,8 @@ int qeth_init_qdio_queues(struct qeth_card *card) QETH_DBF_TEXT(SETUP, 2, "initqdqs"); /* inbound queue */ - memset(card->qdio.in_q->qdio_bufs, 0, - QDIO_MAX_BUFFERS_PER_Q * sizeof(struct qdio_buffer)); + qdio_reset_buffers(card->qdio.in_q->qdio_bufs, + QDIO_MAX_BUFFERS_PER_Q); qeth_initialize_working_pool_list(card); /*give only as many buffers to hardware as we have buffer pool entries*/ for (i = 0; i < card->qdio.in_buf_pool.buf_count - 1; ++i) @@ -2811,8 +2844,8 @@ int qeth_init_qdio_queues(struct qeth_card *card) /* outbound queue */ for (i = 0; i < card->qdio.no_out_queues; ++i) { - memset(card->qdio.out_qs[i]->qdio_bufs, 0, - QDIO_MAX_BUFFERS_PER_Q * sizeof(struct qdio_buffer)); + qdio_reset_buffers(card->qdio.out_qs[i]->qdio_bufs, + QDIO_MAX_BUFFERS_PER_Q); for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; ++j) { qeth_clear_output_buffer(card->qdio.out_qs[i], card->qdio.out_qs[i]->bufs[j], @@ -3037,6 +3070,45 @@ int qeth_query_ipassists(struct qeth_card *card, enum qeth_prot_versions prot) } EXPORT_SYMBOL_GPL(qeth_query_ipassists); +static int qeth_query_switch_attributes_cb(struct qeth_card *card, + struct qeth_reply *reply, unsigned long data) +{ + struct qeth_ipa_cmd *cmd; + struct qeth_switch_info *sw_info; + struct qeth_query_switch_attributes *attrs; + + QETH_CARD_TEXT(card, 2, "qswiatcb"); + cmd = (struct qeth_ipa_cmd *) data; + sw_info = (struct qeth_switch_info *)reply->param; + if (cmd->data.setadapterparms.hdr.return_code == 0) { + attrs = &cmd->data.setadapterparms.data.query_switch_attributes; + sw_info->capabilities = attrs->capabilities; + sw_info->settings = attrs->settings; + QETH_CARD_TEXT_(card, 2, "%04x%04x", sw_info->capabilities, + sw_info->settings); + } + qeth_default_setadapterparms_cb(card, reply, (unsigned long) cmd); + + return 0; +} + +int qeth_query_switch_attributes(struct qeth_card *card, + struct qeth_switch_info *sw_info) +{ + struct qeth_cmd_buffer *iob; + + QETH_CARD_TEXT(card, 2, "qswiattr"); + if (!qeth_adp_supported(card, IPA_SETADP_QUERY_SWITCH_ATTRIBUTES)) + return -EOPNOTSUPP; + if (!netif_carrier_ok(card->dev)) + return -ENOMEDIUM; + iob = qeth_get_adapter_cmd(card, IPA_SETADP_QUERY_SWITCH_ATTRIBUTES, + sizeof(struct qeth_ipacmd_setadpparms_hdr)); + return qeth_send_ipa_cmd(card, iob, + qeth_query_switch_attributes_cb, sw_info); +} +EXPORT_SYMBOL_GPL(qeth_query_switch_attributes); + static int qeth_query_setdiagass_cb(struct qeth_card *card, struct qeth_reply *reply, unsigned long data) { @@ -3530,7 +3602,7 @@ static void qeth_qdio_cq_handler(struct qeth_card *card, for (i = first_element; i < first_element + count; ++i) { int bidx = i % QDIO_MAX_BUFFERS_PER_Q; - struct qdio_buffer *buffer = &cq->qdio_bufs[bidx]; + struct qdio_buffer *buffer = cq->qdio_bufs[bidx]; int e; e = 0; diff --git a/drivers/s390/net/qeth_core_mpc.h b/drivers/s390/net/qeth_core_mpc.h index cf6a90ed42ae..1558be1af72d 100644 --- a/drivers/s390/net/qeth_core_mpc.h +++ b/drivers/s390/net/qeth_core_mpc.h @@ -242,6 +242,7 @@ enum qeth_ipa_setadp_cmd { IPA_SETADP_SET_DIAG_ASSIST = 0x00002000L, IPA_SETADP_SET_ACCESS_CONTROL = 0x00010000L, IPA_SETADP_QUERY_OAT = 0x00080000L, + IPA_SETADP_QUERY_SWITCH_ATTRIBUTES = 0x00100000L, }; enum qeth_ipa_mac_ops { CHANGE_ADDR_READ_MAC = 0, @@ -431,6 +432,21 @@ struct qeth_query_card_info { __u32 reserved2; }; +#define QETH_SWITCH_FORW_802_1 0x00000001 +#define QETH_SWITCH_FORW_REFL_RELAY 0x00000002 +#define QETH_SWITCH_CAP_RTE 0x00000004 +#define QETH_SWITCH_CAP_ECP 0x00000008 +#define QETH_SWITCH_CAP_VDP 0x00000010 + +struct qeth_query_switch_attributes { + __u8 version; + __u8 reserved1; + __u16 reserved2; + __u32 capabilities; + __u32 settings; + __u8 reserved3[8]; +}; + struct qeth_ipacmd_setadpparms_hdr { __u32 supp_hw_cmds; __u32 reserved1; @@ -452,6 +468,7 @@ struct qeth_ipacmd_setadpparms { struct qeth_set_access_ctrl set_access_ctrl; struct qeth_query_oat query_oat; struct qeth_query_card_info card_info; + struct qeth_query_switch_attributes query_switch_attributes; __u32 mode; } data; } __attribute__ ((packed)); diff --git a/drivers/s390/net/qeth_core_sys.c b/drivers/s390/net/qeth_core_sys.c index 8a25a2be9890..15523f0e4c03 100644 --- a/drivers/s390/net/qeth_core_sys.c +++ b/drivers/s390/net/qeth_core_sys.c @@ -543,7 +543,42 @@ out: } static DEVICE_ATTR(isolation, 0644, qeth_dev_isolation_show, - qeth_dev_isolation_store); + qeth_dev_isolation_store); + +static ssize_t qeth_dev_switch_attrs_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct qeth_card *card = dev_get_drvdata(dev); + struct qeth_switch_info sw_info; + int rc = 0; + + if (!card) + return -EINVAL; + + if (card->state != CARD_STATE_SOFTSETUP && card->state != CARD_STATE_UP) + return sprintf(buf, "n/a\n"); + + rc = qeth_query_switch_attributes(card, &sw_info); + if (rc) + return rc; + + if (!sw_info.capabilities) + rc = sprintf(buf, "unknown"); + + if (sw_info.capabilities & QETH_SWITCH_FORW_802_1) + rc = sprintf(buf, (sw_info.settings & QETH_SWITCH_FORW_802_1 ? + "[802.1]" : "802.1")); + if (sw_info.capabilities & QETH_SWITCH_FORW_REFL_RELAY) + rc += sprintf(buf + rc, + (sw_info.settings & QETH_SWITCH_FORW_REFL_RELAY ? + " [rr]" : " rr")); + rc += sprintf(buf + rc, "\n"); + + return rc; +} + +static DEVICE_ATTR(switch_attrs, 0444, + qeth_dev_switch_attrs_show, NULL); static ssize_t qeth_hw_trap_show(struct device *dev, struct device_attribute *attr, char *buf) @@ -728,6 +763,7 @@ static struct attribute *qeth_device_attrs[] = { &dev_attr_layer2.attr, &dev_attr_isolation.attr, &dev_attr_hw_trap.attr, + &dev_attr_switch_attrs.attr, NULL, }; static struct attribute_group qeth_device_attr_group = { diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c index 5ef5b4f45758..c2679bfe7f66 100644 --- a/drivers/s390/net/qeth_l2_main.c +++ b/drivers/s390/net/qeth_l2_main.c @@ -952,10 +952,12 @@ static int qeth_l2_setup_netdev(struct qeth_card *card) { switch (card->info.type) { case QETH_CARD_TYPE_IQD: - card->dev = alloc_netdev(0, "hsi%d", ether_setup); + card->dev = alloc_netdev(0, "hsi%d", NET_NAME_UNKNOWN, + ether_setup); break; case QETH_CARD_TYPE_OSN: - card->dev = alloc_netdev(0, "osn%d", ether_setup); + card->dev = alloc_netdev(0, "osn%d", NET_NAME_UNKNOWN, + ether_setup); card->dev->flags |= IFF_NOARP; break; default: diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index 14e0b5810e8c..f8427a2c4840 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c @@ -3287,7 +3287,8 @@ static int qeth_l3_setup_netdev(struct qeth_card *card) } } } else if (card->info.type == QETH_CARD_TYPE_IQD) { - card->dev = alloc_netdev(0, "hsi%d", ether_setup); + card->dev = alloc_netdev(0, "hsi%d", NET_NAME_UNKNOWN, + ether_setup); if (!card->dev) return -ENODEV; card->dev->flags |= IFF_NOARP; |