From 942d6984aa0cb3974b99d302b566eaf0b8eccf54 Mon Sep 17 00:00:00 2001 From: Julian Wiedmann Date: Tue, 11 Apr 2017 16:11:10 +0200 Subject: [PATCH 01/10] s390/qeth: move common ioctl handling to core There's a number of layer-independent ioctls that we can handle in core, and reduce code duplication. For layer-specific ioctls, add a do_ioctl() discipline hook. Signed-off-by: Julian Wiedmann Acked-by: Ursula Braun Signed-off-by: David S. Miller --- drivers/s390/net/qeth_core.h | 5 +-- drivers/s390/net/qeth_core_main.c | 63 ++++++++++++++++++++++++++++--- drivers/s390/net/qeth_l2_main.c | 54 +------------------------- drivers/s390/net/qeth_l3_main.c | 41 ++------------------ 4 files changed, 64 insertions(+), 99 deletions(-) diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h index ed5b3582adba6..ee4d43f0c1491 100644 --- a/drivers/s390/net/qeth_core.h +++ b/drivers/s390/net/qeth_core.h @@ -716,6 +716,7 @@ struct qeth_discipline { int (*freeze)(struct ccwgroup_device *); int (*thaw) (struct ccwgroup_device *); int (*restore)(struct ccwgroup_device *); + int (*do_ioctl)(struct net_device *dev, struct ifreq *rq, int cmd); int (*control_event_handler)(struct qeth_card *card, struct qeth_ipa_cmd *cmd); }; @@ -936,9 +937,6 @@ void qeth_prepare_control_data(struct qeth_card *, int, void qeth_release_buffer(struct qeth_channel *, struct qeth_cmd_buffer *); void qeth_prepare_ipa_cmd(struct qeth_card *, struct qeth_cmd_buffer *, char); 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_send_control_data(struct qeth_card *, int, struct qeth_cmd_buffer *, @@ -956,6 +954,7 @@ int qeth_do_send_packet_fast(struct qeth_card *, struct qeth_qdio_out_q *, struct sk_buff *, struct qeth_hdr *, int, int, int); int qeth_do_send_packet(struct qeth_card *, struct qeth_qdio_out_q *, struct sk_buff *, struct qeth_hdr *, int); +int qeth_do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); int qeth_core_get_sset_count(struct net_device *, int); void qeth_core_get_ethtool_stats(struct net_device *, struct ethtool_stats *, u64 *); diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index 6b22b05a69539..c9fdf98e5e15a 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -4417,7 +4417,7 @@ void qeth_tx_timeout(struct net_device *dev) } EXPORT_SYMBOL_GPL(qeth_tx_timeout); -int qeth_mdio_read(struct net_device *dev, int phy_id, int regnum) +static int qeth_mdio_read(struct net_device *dev, int phy_id, int regnum) { struct qeth_card *card = dev->ml_priv; int rc = 0; @@ -4480,7 +4480,6 @@ int qeth_mdio_read(struct net_device *dev, int phy_id, int regnum) } return rc; } -EXPORT_SYMBOL_GPL(qeth_mdio_read); static int qeth_send_ipa_snmp_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob, int len, @@ -4570,7 +4569,7 @@ static int qeth_snmp_command_cb(struct qeth_card *card, return 0; } -int qeth_snmp_command(struct qeth_card *card, char __user *udata) +static int qeth_snmp_command(struct qeth_card *card, char __user *udata) { struct qeth_cmd_buffer *iob; struct qeth_ipa_cmd *cmd; @@ -4630,7 +4629,6 @@ int qeth_snmp_command(struct qeth_card *card, char __user *udata) kfree(qinfo.udata); return rc; } -EXPORT_SYMBOL_GPL(qeth_snmp_command); static int qeth_setadpparms_query_oat_cb(struct qeth_card *card, struct qeth_reply *reply, unsigned long data) @@ -4662,7 +4660,7 @@ static int qeth_setadpparms_query_oat_cb(struct qeth_card *card, return 0; } -int qeth_query_oat_command(struct qeth_card *card, char __user *udata) +static int qeth_query_oat_command(struct qeth_card *card, char __user *udata) { int rc = 0; struct qeth_cmd_buffer *iob; @@ -4732,7 +4730,6 @@ int qeth_query_oat_command(struct qeth_card *card, char __user *udata) out: return rc; } -EXPORT_SYMBOL_GPL(qeth_query_oat_command); static int qeth_query_card_info_cb(struct qeth_card *card, struct qeth_reply *reply, unsigned long data) @@ -5759,6 +5756,60 @@ static const struct attribute_group *qeth_drv_attr_groups[] = { NULL, }; +int qeth_do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) +{ + struct qeth_card *card = dev->ml_priv; + struct mii_ioctl_data *mii_data; + int rc = 0; + + if (!card) + return -ENODEV; + + if (!qeth_card_hw_is_reachable(card)) + return -ENODEV; + + if (card->info.type == QETH_CARD_TYPE_OSN) + return -EPERM; + + switch (cmd) { + case SIOC_QETH_ADP_SET_SNMP_CONTROL: + rc = qeth_snmp_command(card, rq->ifr_ifru.ifru_data); + break; + case SIOC_QETH_GET_CARD_TYPE: + if ((card->info.type == QETH_CARD_TYPE_OSD || + card->info.type == QETH_CARD_TYPE_OSM || + card->info.type == QETH_CARD_TYPE_OSX) && + !card->info.guestlan) + return 1; + else + return 0; + case SIOCGMIIPHY: + mii_data = if_mii(rq); + mii_data->phy_id = 0; + break; + case SIOCGMIIREG: + mii_data = if_mii(rq); + if (mii_data->phy_id != 0) + rc = -EINVAL; + else + mii_data->val_out = qeth_mdio_read(dev, + mii_data->phy_id, mii_data->reg_num); + break; + case SIOC_QETH_QUERY_OAT: + rc = qeth_query_oat_command(card, rq->ifr_ifru.ifru_data); + break; + default: + if (card->discipline->do_ioctl) + rc = card->discipline->do_ioctl(dev, rq, cmd); + else + rc = -EOPNOTSUPP; + } + if (rc) + QETH_CARD_TEXT_(card, 2, "ioce%x", rc); + return rc; +} +EXPORT_SYMBOL_GPL(qeth_do_ioctl); + static struct { const char str[ETH_GSTRING_LEN]; } qeth_ethtool_stats_keys[] = { diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c index cd0ba9e0d3e5b..30232076d8676 100644 --- a/drivers/s390/net/qeth_l2_main.c +++ b/drivers/s390/net/qeth_l2_main.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include #include @@ -34,56 +33,6 @@ static void qeth_bridge_state_change(struct qeth_card *card, static void qeth_bridge_host_event(struct qeth_card *card, struct qeth_ipa_cmd *cmd); -static int qeth_l2_do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) -{ - struct qeth_card *card = dev->ml_priv; - struct mii_ioctl_data *mii_data; - int rc = 0; - - if (!card) - return -ENODEV; - - if (!qeth_card_hw_is_reachable(card)) - return -ENODEV; - - if (card->info.type == QETH_CARD_TYPE_OSN) - return -EPERM; - - switch (cmd) { - case SIOC_QETH_ADP_SET_SNMP_CONTROL: - rc = qeth_snmp_command(card, rq->ifr_ifru.ifru_data); - break; - case SIOC_QETH_GET_CARD_TYPE: - if ((card->info.type == QETH_CARD_TYPE_OSD || - card->info.type == QETH_CARD_TYPE_OSM || - card->info.type == QETH_CARD_TYPE_OSX) && - !card->info.guestlan) - return 1; - return 0; - break; - case SIOCGMIIPHY: - mii_data = if_mii(rq); - mii_data->phy_id = 0; - break; - case SIOCGMIIREG: - mii_data = if_mii(rq); - if (mii_data->phy_id != 0) - rc = -EINVAL; - else - mii_data->val_out = qeth_mdio_read(dev, - mii_data->phy_id, mii_data->reg_num); - break; - case SIOC_QETH_QUERY_OAT: - rc = qeth_query_oat_command(card, rq->ifr_ifru.ifru_data); - break; - default: - rc = -EOPNOTSUPP; - } - if (rc) - QETH_CARD_TEXT_(card, 2, "ioce%d", rc); - return rc; -} - static int qeth_l2_verify_dev(struct net_device *dev) { struct qeth_card *card; @@ -1059,7 +1008,7 @@ static const struct net_device_ops qeth_l2_netdev_ops = { .ndo_start_xmit = qeth_l2_hard_start_xmit, .ndo_validate_addr = eth_validate_addr, .ndo_set_rx_mode = qeth_l2_set_rx_mode, - .ndo_do_ioctl = qeth_l2_do_ioctl, + .ndo_do_ioctl = qeth_do_ioctl, .ndo_set_mac_address = qeth_l2_set_mac_address, .ndo_change_mtu = qeth_change_mtu, .ndo_vlan_rx_add_vid = qeth_l2_vlan_rx_add_vid, @@ -1417,6 +1366,7 @@ struct qeth_discipline qeth_l2_discipline = { .freeze = qeth_l2_pm_suspend, .thaw = qeth_l2_pm_resume, .restore = qeth_l2_pm_resume, + .do_ioctl = NULL, .control_event_handler = qeth_l2_control_event, }; EXPORT_SYMBOL_GPL(qeth_l2_discipline); diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index c29525838b7cd..25b6823af1b24 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include #include @@ -2457,15 +2456,8 @@ static int qeth_l3_do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { struct qeth_card *card = dev->ml_priv; struct qeth_arp_cache_entry arp_entry; - struct mii_ioctl_data *mii_data; int rc = 0; - if (!card) - return -ENODEV; - - if (!qeth_card_hw_is_reachable(card)) - return -ENODEV; - switch (cmd) { case SIOC_QETH_ARP_SET_NO_ENTRIES: if (!capable(CAP_NET_ADMIN)) { @@ -2510,37 +2502,9 @@ static int qeth_l3_do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) } rc = qeth_l3_arp_flush_cache(card); break; - case SIOC_QETH_ADP_SET_SNMP_CONTROL: - rc = qeth_snmp_command(card, rq->ifr_ifru.ifru_data); - break; - case SIOC_QETH_GET_CARD_TYPE: - if ((card->info.type == QETH_CARD_TYPE_OSD || - card->info.type == QETH_CARD_TYPE_OSX) && - !card->info.guestlan) - return 1; - return 0; - break; - case SIOCGMIIPHY: - mii_data = if_mii(rq); - mii_data->phy_id = 0; - break; - case SIOCGMIIREG: - mii_data = if_mii(rq); - if (mii_data->phy_id != 0) - rc = -EINVAL; - else - mii_data->val_out = qeth_mdio_read(dev, - mii_data->phy_id, - mii_data->reg_num); - break; - case SIOC_QETH_QUERY_OAT: - rc = qeth_query_oat_command(card, rq->ifr_ifru.ifru_data); - break; default: rc = -EOPNOTSUPP; } - if (rc) - QETH_CARD_TEXT_(card, 2, "ioce%d", rc); return rc; } @@ -3056,7 +3020,7 @@ static const struct net_device_ops qeth_l3_netdev_ops = { .ndo_start_xmit = qeth_l3_hard_start_xmit, .ndo_validate_addr = eth_validate_addr, .ndo_set_rx_mode = qeth_l3_set_multicast_list, - .ndo_do_ioctl = qeth_l3_do_ioctl, + .ndo_do_ioctl = qeth_do_ioctl, .ndo_change_mtu = qeth_change_mtu, .ndo_fix_features = qeth_fix_features, .ndo_set_features = qeth_set_features, @@ -3072,7 +3036,7 @@ static const struct net_device_ops qeth_l3_osa_netdev_ops = { .ndo_start_xmit = qeth_l3_hard_start_xmit, .ndo_validate_addr = eth_validate_addr, .ndo_set_rx_mode = qeth_l3_set_multicast_list, - .ndo_do_ioctl = qeth_l3_do_ioctl, + .ndo_do_ioctl = qeth_do_ioctl, .ndo_change_mtu = qeth_change_mtu, .ndo_fix_features = qeth_fix_features, .ndo_set_features = qeth_set_features, @@ -3439,6 +3403,7 @@ struct qeth_discipline qeth_l3_discipline = { .freeze = qeth_l3_pm_suspend, .thaw = qeth_l3_pm_resume, .restore = qeth_l3_pm_resume, + .do_ioctl = qeth_l3_do_ioctl, .control_event_handler = qeth_l3_control_event, }; EXPORT_SYMBOL_GPL(qeth_l3_discipline); From d73ef3249356d78de3fd676bcf52448b950cb0bb Mon Sep 17 00:00:00 2001 From: Julian Wiedmann Date: Tue, 11 Apr 2017 16:11:11 +0200 Subject: [PATCH 02/10] s390/qeth: move NAPI poll routine to core Identical code, we just need to call a layer-specific hook to process any received buffer. qeth_buffer_reclaim_work() is shuffled around to avoid a forward declaration for qeth_queue_input_buffer(). Signed-off-by: Julian Wiedmann Acked-by: Ursula Braun Signed-off-by: David S. Miller --- drivers/s390/net/qeth_core.h | 5 +- drivers/s390/net/qeth_core_main.c | 105 ++++++++++++++++++++++++++---- drivers/s390/net/qeth_l2_main.c | 78 +--------------------- drivers/s390/net/qeth_l3_main.c | 78 +--------------------- 4 files changed, 97 insertions(+), 169 deletions(-) diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h index ee4d43f0c1491..196356e11077c 100644 --- a/drivers/s390/net/qeth_core.h +++ b/drivers/s390/net/qeth_core.h @@ -705,6 +705,7 @@ struct qeth_discipline { void (*start_poll)(struct ccw_device *, int, unsigned long); qdio_handler_t *input_handler; qdio_handler_t *output_handler; + int (*process_rx_buffer)(struct qeth_card *card, int budget, int *done); int (*recover)(void *ptr); int (*setup) (struct ccwgroup_device *); void (*remove) (struct ccwgroup_device *); @@ -909,14 +910,12 @@ int qeth_send_ipa_cmd(struct qeth_card *, struct qeth_cmd_buffer *, struct qeth_cmd_buffer *qeth_get_ipacmd_buffer(struct qeth_card *, enum qeth_ipa_cmds, enum qeth_prot_versions); int qeth_query_setadapterparms(struct qeth_card *); -int qeth_check_qdio_errors(struct qeth_card *, struct qdio_buffer *, - unsigned int, const char *); -void qeth_queue_input_buffer(struct qeth_card *, int); struct sk_buff *qeth_core_get_next_skb(struct qeth_card *, struct qeth_qdio_buffer *, struct qdio_buffer_element **, int *, struct qeth_hdr **); void qeth_schedule_recovery(struct qeth_card *); void qeth_qdio_start_poll(struct ccw_device *, int, unsigned long); +int qeth_poll(struct napi_struct *napi, int budget); void qeth_qdio_input_handler(struct ccw_device *, unsigned int, unsigned int, int, int, unsigned long); diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index c9fdf98e5e15a..b9063eb174360 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -3216,8 +3216,10 @@ int qeth_hw_trap(struct qeth_card *card, enum qeth_diags_trap_action action) } 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) +static int qeth_check_qdio_errors(struct qeth_card *card, + struct qdio_buffer *buf, + unsigned int qdio_error, + const char *dbftext) { if (qdio_error) { QETH_CARD_TEXT(card, 2, dbftext); @@ -3234,18 +3236,8 @@ int qeth_check_qdio_errors(struct qeth_card *card, struct qdio_buffer *buf, } return 0; } -EXPORT_SYMBOL_GPL(qeth_check_qdio_errors); -static void qeth_buffer_reclaim_work(struct work_struct *work) -{ - struct qeth_card *card = container_of(work, struct qeth_card, - buffer_reclaim_work.work); - - QETH_CARD_TEXT_(card, 2, "brw:%x", card->reclaim_index); - qeth_queue_input_buffer(card, card->reclaim_index); -} - -void qeth_queue_input_buffer(struct qeth_card *card, int index) +static void qeth_queue_input_buffer(struct qeth_card *card, int index) { struct qeth_qdio_q *queue = card->qdio.in_q; struct list_head *lh; @@ -3319,7 +3311,15 @@ void qeth_queue_input_buffer(struct qeth_card *card, int index) QDIO_MAX_BUFFERS_PER_Q; } } -EXPORT_SYMBOL_GPL(qeth_queue_input_buffer); + +static void qeth_buffer_reclaim_work(struct work_struct *work) +{ + struct qeth_card *card = container_of(work, struct qeth_card, + buffer_reclaim_work.work); + + QETH_CARD_TEXT_(card, 2, "brw:%x", card->reclaim_index); + qeth_queue_input_buffer(card, card->reclaim_index); +} static void qeth_handle_send_error(struct qeth_card *card, struct qeth_qdio_out_buffer *buffer, unsigned int qdio_err) @@ -5282,6 +5282,83 @@ struct sk_buff *qeth_core_get_next_skb(struct qeth_card *card, } EXPORT_SYMBOL_GPL(qeth_core_get_next_skb); +int qeth_poll(struct napi_struct *napi, int budget) +{ + struct qeth_card *card = container_of(napi, struct qeth_card, napi); + int work_done = 0; + struct qeth_qdio_buffer *buffer; + int done; + int new_budget = budget; + + if (card->options.performance_stats) { + card->perf_stats.inbound_cnt++; + card->perf_stats.inbound_start_time = qeth_get_micros(); + } + + while (1) { + if (!card->rx.b_count) { + card->rx.qdio_err = 0; + card->rx.b_count = qdio_get_next_buffers( + card->data.ccwdev, 0, &card->rx.b_index, + &card->rx.qdio_err); + if (card->rx.b_count <= 0) { + card->rx.b_count = 0; + break; + } + card->rx.b_element = + &card->qdio.in_q->bufs[card->rx.b_index] + .buffer->element[0]; + card->rx.e_offset = 0; + } + + while (card->rx.b_count) { + buffer = &card->qdio.in_q->bufs[card->rx.b_index]; + if (!(card->rx.qdio_err && + qeth_check_qdio_errors(card, buffer->buffer, + card->rx.qdio_err, "qinerr"))) + work_done += + card->discipline->process_rx_buffer( + card, new_budget, &done); + else + done = 1; + + if (done) { + if (card->options.performance_stats) + card->perf_stats.bufs_rec++; + qeth_put_buffer_pool_entry(card, + buffer->pool_entry); + qeth_queue_input_buffer(card, card->rx.b_index); + card->rx.b_count--; + if (card->rx.b_count) { + card->rx.b_index = + (card->rx.b_index + 1) % + QDIO_MAX_BUFFERS_PER_Q; + card->rx.b_element = + &card->qdio.in_q + ->bufs[card->rx.b_index] + .buffer->element[0]; + card->rx.e_offset = 0; + } + } + + if (work_done >= budget) + goto out; + else + new_budget = budget - work_done; + } + } + + napi_complete(napi); + if (qdio_start_irq(card->data.ccwdev, 0)) + napi_schedule(&card->napi); +out: + if (card->options.performance_stats) + card->perf_stats.inbound_time += qeth_get_micros() - + card->perf_stats.inbound_start_time; + return work_done; +} +EXPORT_SYMBOL_GPL(qeth_poll); + int qeth_setassparms_cb(struct qeth_card *card, struct qeth_reply *reply, unsigned long data) { diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c index 30232076d8676..572347d65c1de 100644 --- a/drivers/s390/net/qeth_l2_main.c +++ b/drivers/s390/net/qeth_l2_main.c @@ -500,81 +500,6 @@ static int qeth_l2_process_inbound_buffer(struct qeth_card *card, return work_done; } -static int qeth_l2_poll(struct napi_struct *napi, int budget) -{ - struct qeth_card *card = container_of(napi, struct qeth_card, napi); - int work_done = 0; - struct qeth_qdio_buffer *buffer; - int done; - int new_budget = budget; - - if (card->options.performance_stats) { - card->perf_stats.inbound_cnt++; - card->perf_stats.inbound_start_time = qeth_get_micros(); - } - - while (1) { - if (!card->rx.b_count) { - card->rx.qdio_err = 0; - card->rx.b_count = qdio_get_next_buffers( - card->data.ccwdev, 0, &card->rx.b_index, - &card->rx.qdio_err); - if (card->rx.b_count <= 0) { - card->rx.b_count = 0; - break; - } - card->rx.b_element = - &card->qdio.in_q->bufs[card->rx.b_index] - .buffer->element[0]; - card->rx.e_offset = 0; - } - - while (card->rx.b_count) { - buffer = &card->qdio.in_q->bufs[card->rx.b_index]; - if (!(card->rx.qdio_err && - qeth_check_qdio_errors(card, buffer->buffer, - card->rx.qdio_err, "qinerr"))) - work_done += qeth_l2_process_inbound_buffer( - card, new_budget, &done); - else - done = 1; - - if (done) { - if (card->options.performance_stats) - card->perf_stats.bufs_rec++; - qeth_put_buffer_pool_entry(card, - buffer->pool_entry); - qeth_queue_input_buffer(card, card->rx.b_index); - card->rx.b_count--; - if (card->rx.b_count) { - card->rx.b_index = - (card->rx.b_index + 1) % - QDIO_MAX_BUFFERS_PER_Q; - card->rx.b_element = - &card->qdio.in_q - ->bufs[card->rx.b_index] - .buffer->element[0]; - card->rx.e_offset = 0; - } - } - - if (work_done >= budget) - goto out; - else - new_budget = budget - work_done; - } - } - - napi_complete(napi); - if (qdio_start_irq(card->data.ccwdev, 0)) - napi_schedule(&card->napi); -out: - if (card->options.performance_stats) - card->perf_stats.inbound_time += qeth_get_micros() - - card->perf_stats.inbound_start_time; - return work_done; -} - static int qeth_l2_request_initial_mac(struct qeth_card *card) { int rc = 0; @@ -1065,7 +990,7 @@ static int qeth_l2_setup_netdev(struct qeth_card *card) card->dev->gso_max_size = (QETH_MAX_BUFFER_ELEMENTS(card) - 1) * PAGE_SIZE; SET_NETDEV_DEV(card->dev, &card->gdev->dev); - netif_napi_add(card->dev, &card->napi, qeth_l2_poll, QETH_NAPI_WEIGHT); + netif_napi_add(card->dev, &card->napi, qeth_poll, QETH_NAPI_WEIGHT); netif_carrier_off(card->dev); return register_netdev(card->dev); } @@ -1357,6 +1282,7 @@ struct qeth_discipline qeth_l2_discipline = { .start_poll = qeth_qdio_start_poll, .input_handler = (qdio_handler_t *) qeth_qdio_input_handler, .output_handler = (qdio_handler_t *) qeth_qdio_output_handler, + .process_rx_buffer = qeth_l2_process_inbound_buffer, .recover = qeth_l2_recover, .setup = qeth_l2_probe_device, .remove = qeth_l2_remove_device, diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index 25b6823af1b24..bd6ad9be92458 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c @@ -1829,81 +1829,6 @@ static int qeth_l3_process_inbound_buffer(struct qeth_card *card, return work_done; } -static int qeth_l3_poll(struct napi_struct *napi, int budget) -{ - struct qeth_card *card = container_of(napi, struct qeth_card, napi); - int work_done = 0; - struct qeth_qdio_buffer *buffer; - int done; - int new_budget = budget; - - if (card->options.performance_stats) { - card->perf_stats.inbound_cnt++; - card->perf_stats.inbound_start_time = qeth_get_micros(); - } - - while (1) { - if (!card->rx.b_count) { - card->rx.qdio_err = 0; - card->rx.b_count = qdio_get_next_buffers( - card->data.ccwdev, 0, &card->rx.b_index, - &card->rx.qdio_err); - if (card->rx.b_count <= 0) { - card->rx.b_count = 0; - break; - } - card->rx.b_element = - &card->qdio.in_q->bufs[card->rx.b_index] - .buffer->element[0]; - card->rx.e_offset = 0; - } - - while (card->rx.b_count) { - buffer = &card->qdio.in_q->bufs[card->rx.b_index]; - if (!(card->rx.qdio_err && - qeth_check_qdio_errors(card, buffer->buffer, - card->rx.qdio_err, "qinerr"))) - work_done += qeth_l3_process_inbound_buffer( - card, new_budget, &done); - else - done = 1; - - if (done) { - if (card->options.performance_stats) - card->perf_stats.bufs_rec++; - qeth_put_buffer_pool_entry(card, - buffer->pool_entry); - qeth_queue_input_buffer(card, card->rx.b_index); - card->rx.b_count--; - if (card->rx.b_count) { - card->rx.b_index = - (card->rx.b_index + 1) % - QDIO_MAX_BUFFERS_PER_Q; - card->rx.b_element = - &card->qdio.in_q - ->bufs[card->rx.b_index] - .buffer->element[0]; - card->rx.e_offset = 0; - } - } - - if (work_done >= budget) - goto out; - else - new_budget = budget - work_done; - } - } - - napi_complete(napi); - if (qdio_start_irq(card->data.ccwdev, 0)) - napi_schedule(&card->napi); -out: - if (card->options.performance_stats) - card->perf_stats.inbound_time += qeth_get_micros() - - card->perf_stats.inbound_start_time; - return work_done; -} - static int qeth_l3_verify_vlan_dev(struct net_device *dev, struct qeth_card *card) { @@ -3105,7 +3030,7 @@ static int qeth_l3_setup_netdev(struct qeth_card *card) PAGE_SIZE; SET_NETDEV_DEV(card->dev, &card->gdev->dev); - netif_napi_add(card->dev, &card->napi, qeth_l3_poll, QETH_NAPI_WEIGHT); + netif_napi_add(card->dev, &card->napi, qeth_poll, QETH_NAPI_WEIGHT); netif_carrier_off(card->dev); return register_netdev(card->dev); } @@ -3394,6 +3319,7 @@ struct qeth_discipline qeth_l3_discipline = { .start_poll = qeth_qdio_start_poll, .input_handler = (qdio_handler_t *) qeth_qdio_input_handler, .output_handler = (qdio_handler_t *) qeth_qdio_output_handler, + .process_rx_buffer = qeth_l3_process_inbound_buffer, .recover = qeth_l3_recover, .setup = qeth_l3_probe_device, .remove = qeth_l3_remove_device, From 96d1bb53ec8b219abdee883c24799ba68ad4d460 Mon Sep 17 00:00:00 2001 From: Julian Wiedmann Date: Tue, 11 Apr 2017 16:11:12 +0200 Subject: [PATCH 03/10] s390/qeth: move gdev shutdown handler to core Duplicated code. Signed-off-by: Julian Wiedmann Acked-by: Ursula Braun Signed-off-by: David S. Miller --- drivers/s390/net/qeth_core.h | 1 - drivers/s390/net/qeth_core_main.c | 8 ++++++-- drivers/s390/net/qeth_l2_main.c | 12 ------------ drivers/s390/net/qeth_l3_main.c | 12 ------------ 4 files changed, 6 insertions(+), 27 deletions(-) diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h index 196356e11077c..cc1a4baeba552 100644 --- a/drivers/s390/net/qeth_core.h +++ b/drivers/s390/net/qeth_core.h @@ -711,7 +711,6 @@ struct qeth_discipline { void (*remove) (struct ccwgroup_device *); int (*set_online) (struct ccwgroup_device *); int (*set_offline) (struct ccwgroup_device *); - void (*shutdown)(struct ccwgroup_device *); int (*prepare) (struct ccwgroup_device *); void (*complete) (struct ccwgroup_device *); int (*freeze)(struct ccwgroup_device *); diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index b9063eb174360..cf5493e525e8d 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -5749,8 +5749,12 @@ static int qeth_core_set_offline(struct ccwgroup_device *gdev) static void qeth_core_shutdown(struct ccwgroup_device *gdev) { struct qeth_card *card = dev_get_drvdata(&gdev->dev); - if (card->discipline && card->discipline->shutdown) - card->discipline->shutdown(gdev); + qeth_set_allowed_threads(card, 0, 1); + 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); + qdio_free(CARD_DDEV(card)); } static int qeth_core_prepare(struct ccwgroup_device *gdev) diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c index 572347d65c1de..2ad378b57f9fc 100644 --- a/drivers/s390/net/qeth_l2_main.c +++ b/drivers/s390/net/qeth_l2_main.c @@ -1200,17 +1200,6 @@ static void __exit qeth_l2_exit(void) pr_info("unregister layer 2 discipline\n"); } -static void qeth_l2_shutdown(struct ccwgroup_device *gdev) -{ - struct qeth_card *card = dev_get_drvdata(&gdev->dev); - qeth_set_allowed_threads(card, 0, 1); - 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); - qdio_free(CARD_DDEV(card)); -} - static int qeth_l2_pm_suspend(struct ccwgroup_device *gdev) { struct qeth_card *card = dev_get_drvdata(&gdev->dev); @@ -1288,7 +1277,6 @@ struct qeth_discipline qeth_l2_discipline = { .remove = qeth_l2_remove_device, .set_online = qeth_l2_set_online, .set_offline = qeth_l2_set_offline, - .shutdown = qeth_l2_shutdown, .freeze = qeth_l2_pm_suspend, .thaw = qeth_l2_pm_resume, .restore = qeth_l2_pm_resume, diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index bd6ad9be92458..ca21a2065a5de 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c @@ -3251,17 +3251,6 @@ static int qeth_l3_recover(void *ptr) return 0; } -static void qeth_l3_shutdown(struct ccwgroup_device *gdev) -{ - struct qeth_card *card = dev_get_drvdata(&gdev->dev); - qeth_set_allowed_threads(card, 0, 1); - 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); - qdio_free(CARD_DDEV(card)); -} - static int qeth_l3_pm_suspend(struct ccwgroup_device *gdev) { struct qeth_card *card = dev_get_drvdata(&gdev->dev); @@ -3325,7 +3314,6 @@ struct qeth_discipline qeth_l3_discipline = { .remove = qeth_l3_remove_device, .set_online = qeth_l3_set_online, .set_offline = qeth_l3_set_offline, - .shutdown = qeth_l3_shutdown, .freeze = qeth_l3_pm_suspend, .thaw = qeth_l3_pm_resume, .restore = qeth_l3_pm_resume, From 4e8d7e62560bba9772556ec6e11afcd20868d6a2 Mon Sep 17 00:00:00 2001 From: Julian Wiedmann Date: Tue, 11 Apr 2017 16:11:13 +0200 Subject: [PATCH 04/10] s390/qeth: remove unused parameter 'elements_needed' is not used in qeth_do_send_packet_fast(), so consequently remove it. Signed-off-by: Julian Wiedmann Acked-by: Ursula Braun Signed-off-by: David S. Miller --- drivers/s390/net/qeth_core.h | 2 +- drivers/s390/net/qeth_core_main.c | 3 +-- drivers/s390/net/qeth_l2_main.c | 2 +- drivers/s390/net/qeth_l3_main.c | 2 +- 4 files changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h index cc1a4baeba552..f575c7a566c87 100644 --- a/drivers/s390/net/qeth_core.h +++ b/drivers/s390/net/qeth_core.h @@ -949,7 +949,7 @@ int qeth_get_elements_no(struct qeth_card *card, struct sk_buff *skb, int extra_elems, int data_offset); int qeth_get_elements_for_frags(struct sk_buff *); int qeth_do_send_packet_fast(struct qeth_card *, struct qeth_qdio_out_q *, - struct sk_buff *, struct qeth_hdr *, int, int, int); + struct sk_buff *, struct qeth_hdr *, int, int); int qeth_do_send_packet(struct qeth_card *, struct qeth_qdio_out_q *, struct sk_buff *, struct qeth_hdr *, int); int qeth_do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index cf5493e525e8d..44d15c967c7d0 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -4024,8 +4024,7 @@ static inline int qeth_fill_buffer(struct qeth_qdio_out_q *queue, int qeth_do_send_packet_fast(struct qeth_card *card, struct qeth_qdio_out_q *queue, struct sk_buff *skb, - struct qeth_hdr *hdr, int elements_needed, - int offset, int hd_len) + struct qeth_hdr *hdr, int offset, int hd_len) { struct qeth_qdio_out_buffer *buffer; int index; diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c index 2ad378b57f9fc..ab0d065a9ba2f 100644 --- a/drivers/s390/net/qeth_l2_main.c +++ b/drivers/s390/net/qeth_l2_main.c @@ -783,7 +783,7 @@ static int qeth_l2_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) elements); } else rc = qeth_do_send_packet_fast(card, queue, new_skb, hdr, - elements, data_offset, hd_len); + data_offset, hd_len); if (!rc) { card->stats.tx_packets++; card->stats.tx_bytes += tx_bytes; diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index ca21a2065a5de..7d902b93fd5a6 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c @@ -2810,7 +2810,7 @@ static int qeth_l3_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) rc = qeth_do_send_packet(card, queue, new_skb, hdr, elements); } else rc = qeth_do_send_packet_fast(card, queue, new_skb, hdr, - elements, data_offset, 0); + data_offset, 0); if (!rc) { card->stats.tx_packets++; From e38db6beeed0eac14e21bf3963fdba80043211e3 Mon Sep 17 00:00:00 2001 From: Julian Wiedmann Date: Tue, 11 Apr 2017 16:11:14 +0200 Subject: [PATCH 05/10] s390/qeth: use correct return type for hard_start_xmit() ndo_start_xmit() expects us to return netdev_tx_t here... Signed-off-by: Julian Wiedmann Acked-by: Ursula Braun Signed-off-by: David S. Miller --- drivers/s390/net/qeth_l2_main.c | 3 ++- drivers/s390/net/qeth_l3_main.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c index ab0d065a9ba2f..11cf4a4b36a63 100644 --- a/drivers/s390/net/qeth_l2_main.c +++ b/drivers/s390/net/qeth_l2_main.c @@ -681,7 +681,8 @@ static void qeth_l2_set_rx_mode(struct net_device *dev) qeth_promisc_to_bridge(card); } -static int qeth_l2_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) +static netdev_tx_t qeth_l2_hard_start_xmit(struct sk_buff *skb, + struct net_device *dev) { int rc; struct qeth_hdr *hdr = NULL; diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index 7d902b93fd5a6..bea0bae0faf7e 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c @@ -2655,7 +2655,8 @@ static int qeth_l3_get_elements_no_tso(struct qeth_card *card, return elements; } -static int qeth_l3_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) +static netdev_tx_t qeth_l3_hard_start_xmit(struct sk_buff *skb, + struct net_device *dev) { int rc; __be16 *tag; From 2aedd56af13386fa9edfd5f0178f39b85f5f9d42 Mon Sep 17 00:00:00 2001 From: Julian Wiedmann Date: Tue, 11 Apr 2017 16:11:15 +0200 Subject: [PATCH 06/10] s390/qeth: use and remove some defines 1. a buffer has 16 is_header flags, because that's its # of elements 2. replace the last occurrence of QETH_HEADER_SIZE, and remove it Signed-off-by: Julian Wiedmann Acked-by: Ursula Braun Signed-off-by: David S. Miller --- drivers/s390/net/qeth_core.h | 3 +-- drivers/s390/net/qeth_l2_main.c | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h index f575c7a566c87..760f752034e4d 100644 --- a/drivers/s390/net/qeth_core.h +++ b/drivers/s390/net/qeth_core.h @@ -240,7 +240,6 @@ static inline int qeth_is_ipa_enabled(struct qeth_ipa_info *ipa, #define QETH_TX_TIMEOUT 100 * HZ #define QETH_RCD_TIMEOUT 60 * HZ #define QETH_RECLAIM_WORK_TIME HZ -#define QETH_HEADER_SIZE 32 #define QETH_MAX_PORTNO 15 /*IPv6 address autoconfiguration stuff*/ @@ -447,7 +446,7 @@ struct qeth_qdio_out_buffer { atomic_t state; int next_element_to_fill; struct sk_buff_head skb_list; - int is_header[16]; + int is_header[QDIO_MAX_ELEMENTS_PER_BUFFER]; struct qaob *aob; struct qeth_qdio_out_q *q; diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c index 11cf4a4b36a63..22f8eb007aa1d 100644 --- a/drivers/s390/net/qeth_l2_main.c +++ b/drivers/s390/net/qeth_l2_main.c @@ -280,7 +280,7 @@ static void qeth_l2_fill_header(struct qeth_card *card, struct qeth_hdr *hdr, else hdr->hdr.l2.flags[2] |= QETH_LAYER2_FLAG_UNICAST; - hdr->hdr.l2.pkt_length = skb->len-QETH_HEADER_SIZE; + hdr->hdr.l2.pkt_length = skb->len - sizeof(struct qeth_hdr); /* VSWITCH relies on the VLAN * information to be present in * the QDIO header */ From 774afb8e90685d6a12afa35d13a57113d7edebb4 Mon Sep 17 00:00:00 2001 From: Julian Wiedmann Date: Tue, 11 Apr 2017 16:11:16 +0200 Subject: [PATCH 07/10] s390/qeth: clean up qeth_set_ecmd_adv_sup() In preparation for moving to get_link_ksettings(), clean up how we build the supported and advertised port/speed masks. Signed-off-by: Julian Wiedmann Reviewed-by: Thomas Richter Reviewed-by: Ursula Braun Signed-off-by: David S. Miller --- drivers/s390/net/qeth_core_main.c | 57 +++++++++++++++---------------- 1 file changed, 28 insertions(+), 29 deletions(-) diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index 44d15c967c7d0..41fe9631e24e3 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -6024,57 +6024,56 @@ void qeth_core_get_drvinfo(struct net_device *dev, } EXPORT_SYMBOL_GPL(qeth_core_get_drvinfo); -/* Helper function to fill 'advertizing' and 'supported' which are the same. */ -/* Autoneg and full-duplex are supported and advertized uncondionally. */ -/* Always advertize and support all speeds up to specified, and only one */ +/* Helper function to fill 'advertising' and 'supported' which are the same. */ +/* Autoneg and full-duplex are supported and advertised unconditionally. */ +/* Always advertise and support all speeds up to specified, and only one */ /* specified port type. */ static void qeth_set_ecmd_adv_sup(struct ethtool_cmd *ecmd, int maxspeed, int porttype) { - int port_sup, port_adv, spd_sup, spd_adv; + u32 sup, adv; + + sup = SUPPORTED_Autoneg; + adv = ADVERTISED_Autoneg; switch (porttype) { case PORT_TP: - port_sup = SUPPORTED_TP; - port_adv = ADVERTISED_TP; + sup |= SUPPORTED_TP; + adv |= ADVERTISED_TP; break; case PORT_FIBRE: - port_sup = SUPPORTED_FIBRE; - port_adv = ADVERTISED_FIBRE; + sup |= SUPPORTED_FIBRE; + adv |= ADVERTISED_FIBRE; break; default: - port_sup = SUPPORTED_TP; - port_adv = ADVERTISED_TP; + sup |= SUPPORTED_TP; + adv |= ADVERTISED_TP; WARN_ON_ONCE(1); } - /* "Fallthrough" case'es ordered from high to low result in setting */ - /* flags cumulatively, starting from the specified speed and down to */ - /* the lowest possible. */ - spd_sup = 0; - spd_adv = 0; + /* fallthrough from high to low, to select all legal speeds: */ switch (maxspeed) { case SPEED_10000: - spd_sup |= SUPPORTED_10000baseT_Full; - spd_adv |= ADVERTISED_10000baseT_Full; + sup |= SUPPORTED_10000baseT_Full; + adv |= ADVERTISED_10000baseT_Full; case SPEED_1000: - spd_sup |= SUPPORTED_1000baseT_Half | SUPPORTED_1000baseT_Full; - spd_adv |= ADVERTISED_1000baseT_Half | - ADVERTISED_1000baseT_Full; + sup |= SUPPORTED_1000baseT_Half | SUPPORTED_1000baseT_Full; + adv |= ADVERTISED_1000baseT_Half | ADVERTISED_1000baseT_Full; case SPEED_100: - spd_sup |= SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full; - spd_adv |= ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full; + sup |= SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full; + adv |= ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full; case SPEED_10: - spd_sup |= SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full; - spd_adv |= ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full; - break; + sup |= SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full; + adv |= ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full; + /* end fallthrough */ + break; default: - spd_sup = SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full; - spd_adv = ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full; + sup |= SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full; + adv |= ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full; WARN_ON_ONCE(1); } - ecmd->advertising = ADVERTISED_Autoneg | port_adv | spd_adv; - ecmd->supported = SUPPORTED_Autoneg | port_sup | spd_sup; + ecmd->supported = sup; + ecmd->advertising = adv; } int qeth_core_ethtool_get_settings(struct net_device *netdev, From 993e19c0aeaaf4ad21e93a09110a782f4ef0c4d5 Mon Sep 17 00:00:00 2001 From: Julian Wiedmann Date: Tue, 11 Apr 2017 16:11:17 +0200 Subject: [PATCH 08/10] s390/qeth: convert to ETHTOOL_GLINKSETTINGS API get_settings() is deprecated and lacks support for higher link speeds, so implement get_link_ksettings() instead. Signed-off-by: Julian Wiedmann Reviewed-by: Thomas Richter Reviewed-by: Ursula Braun Signed-off-by: David S. Miller --- drivers/s390/net/qeth_core.h | 3 +- drivers/s390/net/qeth_core_main.c | 75 +++++++++++++++---------------- drivers/s390/net/qeth_l2_main.c | 2 +- drivers/s390/net/qeth_l3_main.c | 2 +- 4 files changed, 40 insertions(+), 42 deletions(-) diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h index 760f752034e4d..a634ec2a08f3b 100644 --- a/drivers/s390/net/qeth_core.h +++ b/drivers/s390/net/qeth_core.h @@ -958,7 +958,8 @@ void qeth_core_get_ethtool_stats(struct net_device *, void qeth_core_get_strings(struct net_device *, u32, u8 *); void qeth_core_get_drvinfo(struct net_device *, struct ethtool_drvinfo *); 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_core_ethtool_get_link_ksettings(struct net_device *netdev, + struct ethtool_link_ksettings *cmd); int qeth_set_access_ctrl_online(struct qeth_card *card, int fallback); int qeth_hdr_chk_and_bounce(struct sk_buff *, struct qeth_hdr **, int); int qeth_configure_cq(struct qeth_card *, enum qeth_cq); diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index 41fe9631e24e3..4304bc2a6620c 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -6028,7 +6028,7 @@ EXPORT_SYMBOL_GPL(qeth_core_get_drvinfo); /* Autoneg and full-duplex are supported and advertised unconditionally. */ /* Always advertise and support all speeds up to specified, and only one */ /* specified port type. */ -static void qeth_set_ecmd_adv_sup(struct ethtool_cmd *ecmd, +static void qeth_set_cmd_adv_sup(struct ethtool_link_ksettings *cmd, int maxspeed, int porttype) { u32 sup, adv; @@ -6072,55 +6072,53 @@ static void qeth_set_ecmd_adv_sup(struct ethtool_cmd *ecmd, adv |= ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full; WARN_ON_ONCE(1); } - ecmd->supported = sup; - ecmd->advertising = adv; + + ethtool_convert_legacy_u32_to_link_mode(cmd->link_modes.supported, + sup); + ethtool_convert_legacy_u32_to_link_mode(cmd->link_modes.advertising, + adv); } -int qeth_core_ethtool_get_settings(struct net_device *netdev, - struct ethtool_cmd *ecmd) +int qeth_core_ethtool_get_link_ksettings(struct net_device *netdev, + struct ethtool_link_ksettings *cmd) { struct qeth_card *card = netdev->ml_priv; enum qeth_link_types link_type; struct carrier_info carrier_info; int rc; - u32 speed; if ((card->info.type == QETH_CARD_TYPE_IQD) || (card->info.guestlan)) link_type = QETH_LINK_TYPE_10GBIT_ETH; else link_type = card->info.link_type; - ecmd->transceiver = XCVR_INTERNAL; - ecmd->duplex = DUPLEX_FULL; - ecmd->autoneg = AUTONEG_ENABLE; + cmd->base.duplex = DUPLEX_FULL; + cmd->base.autoneg = AUTONEG_ENABLE; + cmd->base.phy_address = 0; + cmd->base.mdio_support = 0; + cmd->base.eth_tp_mdix = ETH_TP_MDI_INVALID; + cmd->base.eth_tp_mdix_ctrl = ETH_TP_MDI_INVALID; switch (link_type) { case QETH_LINK_TYPE_FAST_ETH: case QETH_LINK_TYPE_LANE_ETH100: - qeth_set_ecmd_adv_sup(ecmd, SPEED_100, PORT_TP); - speed = SPEED_100; - ecmd->port = PORT_TP; + cmd->base.speed = SPEED_100; + cmd->base.port = PORT_TP; break; - case QETH_LINK_TYPE_GBIT_ETH: case QETH_LINK_TYPE_LANE_ETH1000: - qeth_set_ecmd_adv_sup(ecmd, SPEED_1000, PORT_FIBRE); - speed = SPEED_1000; - ecmd->port = PORT_FIBRE; + cmd->base.speed = SPEED_1000; + cmd->base.port = PORT_FIBRE; break; - case QETH_LINK_TYPE_10GBIT_ETH: - qeth_set_ecmd_adv_sup(ecmd, SPEED_10000, PORT_FIBRE); - speed = SPEED_10000; - ecmd->port = PORT_FIBRE; + cmd->base.speed = SPEED_10000; + cmd->base.port = PORT_FIBRE; break; - default: - qeth_set_ecmd_adv_sup(ecmd, SPEED_10, PORT_TP); - speed = SPEED_10; - ecmd->port = PORT_TP; + cmd->base.speed = SPEED_10; + cmd->base.port = PORT_TP; } - ethtool_cmd_speed_set(ecmd, speed); + qeth_set_cmd_adv_sup(cmd, cmd->base.speed, cmd->base.port); /* Check if we can obtain more accurate information. */ /* If QUERY_CARD_INFO command is not supported or fails, */ @@ -6145,49 +6143,48 @@ int qeth_core_ethtool_get_settings(struct net_device *netdev, switch (carrier_info.card_type) { case CARD_INFO_TYPE_1G_COPPER_A: case CARD_INFO_TYPE_1G_COPPER_B: - qeth_set_ecmd_adv_sup(ecmd, SPEED_1000, PORT_TP); - ecmd->port = PORT_TP; + cmd->base.port = PORT_TP; + qeth_set_cmd_adv_sup(cmd, SPEED_1000, cmd->base.port); break; case CARD_INFO_TYPE_1G_FIBRE_A: case CARD_INFO_TYPE_1G_FIBRE_B: - qeth_set_ecmd_adv_sup(ecmd, SPEED_1000, PORT_FIBRE); - ecmd->port = PORT_FIBRE; + cmd->base.port = PORT_FIBRE; + qeth_set_cmd_adv_sup(cmd, SPEED_1000, cmd->base.port); break; case CARD_INFO_TYPE_10G_FIBRE_A: case CARD_INFO_TYPE_10G_FIBRE_B: - qeth_set_ecmd_adv_sup(ecmd, SPEED_10000, PORT_FIBRE); - ecmd->port = PORT_FIBRE; + cmd->base.port = PORT_FIBRE; + qeth_set_cmd_adv_sup(cmd, SPEED_10000, cmd->base.port); break; } switch (carrier_info.port_mode) { case CARD_INFO_PORTM_FULLDUPLEX: - ecmd->duplex = DUPLEX_FULL; + cmd->base.duplex = DUPLEX_FULL; break; case CARD_INFO_PORTM_HALFDUPLEX: - ecmd->duplex = DUPLEX_HALF; + cmd->base.duplex = DUPLEX_HALF; break; } switch (carrier_info.port_speed) { case CARD_INFO_PORTS_10M: - speed = SPEED_10; + cmd->base.speed = SPEED_10; break; case CARD_INFO_PORTS_100M: - speed = SPEED_100; + cmd->base.speed = SPEED_100; break; case CARD_INFO_PORTS_1G: - speed = SPEED_1000; + cmd->base.speed = SPEED_1000; break; case CARD_INFO_PORTS_10G: - speed = SPEED_10000; + cmd->base.speed = SPEED_10000; break; } - ethtool_cmd_speed_set(ecmd, speed); return 0; } -EXPORT_SYMBOL_GPL(qeth_core_ethtool_get_settings); +EXPORT_SYMBOL_GPL(qeth_core_ethtool_get_link_ksettings); /* Callback to handle checksum offload command reply from OSA card. * Verify that required features have been enabled on the card. diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c index 22f8eb007aa1d..1b07f382d74c9 100644 --- a/drivers/s390/net/qeth_l2_main.c +++ b/drivers/s390/net/qeth_l2_main.c @@ -917,7 +917,7 @@ static const struct ethtool_ops qeth_l2_ethtool_ops = { .get_ethtool_stats = qeth_core_get_ethtool_stats, .get_sset_count = qeth_core_get_sset_count, .get_drvinfo = qeth_core_get_drvinfo, - .get_settings = qeth_core_ethtool_get_settings, + .get_link_ksettings = qeth_core_ethtool_get_link_ksettings, }; static const struct ethtool_ops qeth_l2_osn_ops = { diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index bea0bae0faf7e..6e0354ef4b862 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c @@ -2912,7 +2912,7 @@ static const struct ethtool_ops qeth_l3_ethtool_ops = { .get_ethtool_stats = qeth_core_get_ethtool_stats, .get_sset_count = qeth_core_get_sset_count, .get_drvinfo = qeth_core_get_drvinfo, - .get_settings = qeth_core_ethtool_get_settings, + .get_link_ksettings = qeth_core_ethtool_get_link_ksettings, }; /* From 41fc3b6567a5b072b45f654fab767457a740c637 Mon Sep 17 00:00:00 2001 From: Julian Wiedmann Date: Tue, 11 Apr 2017 16:11:18 +0200 Subject: [PATCH 09/10] s390/qeth: use LINK_MODE_* to report the link characteristics LINK_MODE_* replaces the u32-limited SUPPORTED_* / ENABLED_* definitions. Signed-off-by: Julian Wiedmann Reviewed-by: Thomas Richter Reviewed-by: Ursula Braun Signed-off-by: David S. Miller --- drivers/s390/net/qeth_core_main.c | 71 ++++++++++++++++++++----------- 1 file changed, 47 insertions(+), 24 deletions(-) diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index 4304bc2a6620c..88f4c6cff9a41 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -6031,52 +6031,75 @@ EXPORT_SYMBOL_GPL(qeth_core_get_drvinfo); static void qeth_set_cmd_adv_sup(struct ethtool_link_ksettings *cmd, int maxspeed, int porttype) { - u32 sup, adv; + ethtool_link_ksettings_zero_link_mode(cmd, supported); + ethtool_link_ksettings_zero_link_mode(cmd, advertising); + ethtool_link_ksettings_zero_link_mode(cmd, lp_advertising); - sup = SUPPORTED_Autoneg; - adv = ADVERTISED_Autoneg; + ethtool_link_ksettings_add_link_mode(cmd, supported, Autoneg); + ethtool_link_ksettings_add_link_mode(cmd, advertising, Autoneg); switch (porttype) { case PORT_TP: - sup |= SUPPORTED_TP; - adv |= ADVERTISED_TP; + ethtool_link_ksettings_add_link_mode(cmd, supported, TP); + ethtool_link_ksettings_add_link_mode(cmd, advertising, TP); break; case PORT_FIBRE: - sup |= SUPPORTED_FIBRE; - adv |= ADVERTISED_FIBRE; + ethtool_link_ksettings_add_link_mode(cmd, supported, FIBRE); + ethtool_link_ksettings_add_link_mode(cmd, advertising, FIBRE); break; default: - sup |= SUPPORTED_TP; - adv |= ADVERTISED_TP; + ethtool_link_ksettings_add_link_mode(cmd, supported, TP); + ethtool_link_ksettings_add_link_mode(cmd, advertising, TP); WARN_ON_ONCE(1); } /* fallthrough from high to low, to select all legal speeds: */ switch (maxspeed) { case SPEED_10000: - sup |= SUPPORTED_10000baseT_Full; - adv |= ADVERTISED_10000baseT_Full; + ethtool_link_ksettings_add_link_mode(cmd, supported, + 10000baseT_Full); + ethtool_link_ksettings_add_link_mode(cmd, advertising, + 10000baseT_Full); case SPEED_1000: - sup |= SUPPORTED_1000baseT_Half | SUPPORTED_1000baseT_Full; - adv |= ADVERTISED_1000baseT_Half | ADVERTISED_1000baseT_Full; + ethtool_link_ksettings_add_link_mode(cmd, supported, + 1000baseT_Full); + ethtool_link_ksettings_add_link_mode(cmd, advertising, + 1000baseT_Full); + ethtool_link_ksettings_add_link_mode(cmd, supported, + 1000baseT_Half); + ethtool_link_ksettings_add_link_mode(cmd, advertising, + 1000baseT_Half); case SPEED_100: - sup |= SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full; - adv |= ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full; + ethtool_link_ksettings_add_link_mode(cmd, supported, + 100baseT_Full); + ethtool_link_ksettings_add_link_mode(cmd, advertising, + 100baseT_Full); + ethtool_link_ksettings_add_link_mode(cmd, supported, + 100baseT_Half); + ethtool_link_ksettings_add_link_mode(cmd, advertising, + 100baseT_Half); case SPEED_10: - sup |= SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full; - adv |= ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full; + ethtool_link_ksettings_add_link_mode(cmd, supported, + 10baseT_Full); + ethtool_link_ksettings_add_link_mode(cmd, advertising, + 10baseT_Full); + ethtool_link_ksettings_add_link_mode(cmd, supported, + 10baseT_Half); + ethtool_link_ksettings_add_link_mode(cmd, advertising, + 10baseT_Half); /* end fallthrough */ break; default: - sup |= SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full; - adv |= ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full; + ethtool_link_ksettings_add_link_mode(cmd, supported, + 10baseT_Full); + ethtool_link_ksettings_add_link_mode(cmd, advertising, + 10baseT_Full); + ethtool_link_ksettings_add_link_mode(cmd, supported, + 10baseT_Half); + ethtool_link_ksettings_add_link_mode(cmd, advertising, + 10baseT_Half); WARN_ON_ONCE(1); } - - ethtool_convert_legacy_u32_to_link_mode(cmd->link_modes.supported, - sup); - ethtool_convert_legacy_u32_to_link_mode(cmd->link_modes.advertising, - adv); } int qeth_core_ethtool_get_link_ksettings(struct net_device *netdev, From 6ffa4d1bbe461b7b88e02feca98282a46cb6c33b Mon Sep 17 00:00:00 2001 From: Julian Wiedmann Date: Tue, 11 Apr 2017 16:11:19 +0200 Subject: [PATCH 10/10] s390/qeth: remove unimplemented gdev routines prepare() and complete() are not implemented by any discipline, so just drop all the indirection. Signed-off-by: Julian Wiedmann Reviewed-by: Hans Wippel Reviewed-by: Thomas Richter Signed-off-by: David S. Miller --- drivers/s390/net/qeth_core.h | 2 -- drivers/s390/net/qeth_core_main.c | 19 ++----------------- 2 files changed, 2 insertions(+), 19 deletions(-) diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h index a634ec2a08f3b..f6aa21176d897 100644 --- a/drivers/s390/net/qeth_core.h +++ b/drivers/s390/net/qeth_core.h @@ -710,8 +710,6 @@ struct qeth_discipline { void (*remove) (struct ccwgroup_device *); int (*set_online) (struct ccwgroup_device *); int (*set_offline) (struct ccwgroup_device *); - int (*prepare) (struct ccwgroup_device *); - void (*complete) (struct ccwgroup_device *); int (*freeze)(struct ccwgroup_device *); int (*thaw) (struct ccwgroup_device *); int (*restore)(struct ccwgroup_device *); diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index 88f4c6cff9a41..38114a8d56e00 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -5756,21 +5756,6 @@ static void qeth_core_shutdown(struct ccwgroup_device *gdev) qdio_free(CARD_DDEV(card)); } -static int qeth_core_prepare(struct ccwgroup_device *gdev) -{ - struct qeth_card *card = dev_get_drvdata(&gdev->dev); - if (card->discipline && card->discipline->prepare) - return card->discipline->prepare(gdev); - return 0; -} - -static void qeth_core_complete(struct ccwgroup_device *gdev) -{ - struct qeth_card *card = dev_get_drvdata(&gdev->dev); - if (card->discipline && card->discipline->complete) - card->discipline->complete(gdev); -} - static int qeth_core_freeze(struct ccwgroup_device *gdev) { struct qeth_card *card = dev_get_drvdata(&gdev->dev); @@ -5805,8 +5790,8 @@ static struct ccwgroup_driver qeth_core_ccwgroup_driver = { .set_online = qeth_core_set_online, .set_offline = qeth_core_set_offline, .shutdown = qeth_core_shutdown, - .prepare = qeth_core_prepare, - .complete = qeth_core_complete, + .prepare = NULL, + .complete = NULL, .freeze = qeth_core_freeze, .thaw = qeth_core_thaw, .restore = qeth_core_restore,