diff options
-rw-r--r-- | drivers/s390/net/qeth_core.h | 11 | ||||
-rw-r--r-- | drivers/s390/net/qeth_core_main.c | 70 | ||||
-rw-r--r-- | drivers/s390/net/qeth_ethtool.c | 8 | ||||
-rw-r--r-- | drivers/s390/net/qeth_l2_main.c | 14 | ||||
-rw-r--r-- | drivers/s390/net/qeth_l3_main.c | 12 |
5 files changed, 61 insertions, 54 deletions
diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h index f321eabefbe4..f1c9a694873e 100644 --- a/drivers/s390/net/qeth_core.h +++ b/drivers/s390/net/qeth_core.h @@ -538,7 +538,7 @@ struct qeth_qdio_info { int in_buf_size; /* output */ - int no_out_queues; + unsigned int no_out_queues; struct qeth_qdio_out_q *out_qs[QETH_MAX_OUT_QUEUES]; struct qdio_outbuf_state *out_bufstates; @@ -788,6 +788,7 @@ struct qeth_switch_info { struct qeth_priv { unsigned int rx_copybreak; + unsigned int tx_wanted_queues; u32 brport_hw_features; u32 brport_features; }; @@ -873,6 +874,13 @@ struct qeth_trap_id { /*some helper functions*/ #define QETH_CARD_IFNAME(card) (((card)->dev)? (card)->dev->name : "") +static inline unsigned int qeth_tx_actual_queues(struct qeth_card *card) +{ + struct qeth_priv *priv = netdev_priv(card->dev); + + return min(priv->tx_wanted_queues, card->qdio.no_out_queues); +} + static inline u16 qeth_iqd_translate_txq(struct net_device *dev, u16 txq) { if (txq == QETH_IQD_MCAST_TXQ) @@ -1087,7 +1095,6 @@ void qeth_dbf_longtext(debug_info_t *id, int level, char *text, ...); int qeth_configure_cq(struct qeth_card *, enum qeth_cq); int qeth_hw_trap(struct qeth_card *, enum qeth_diags_trap_action); int qeth_setassparms_cb(struct qeth_card *, struct qeth_reply *, unsigned long); -int qeth_setup_netdev(struct qeth_card *card); int qeth_set_features(struct net_device *, netdev_features_t); void qeth_enable_hw_features(struct net_device *dev); netdev_features_t qeth_fix_features(struct net_device *, netdev_features_t); diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index fc2c3db9259f..b61078b27562 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -1511,23 +1511,12 @@ static void qeth_drain_output_queues(struct qeth_card *card) } } -static int qeth_osa_set_output_queues(struct qeth_card *card, bool single) +static void qeth_osa_set_output_queues(struct qeth_card *card, bool single) { unsigned int max = single ? 1 : card->dev->num_tx_queues; - unsigned int count; - int rc; - - count = IS_VM_NIC(card) ? min(max, card->dev->real_num_tx_queues) : max; - - rtnl_lock(); - rc = netif_set_real_num_tx_queues(card->dev, count); - rtnl_unlock(); - - if (rc) - return rc; if (card->qdio.no_out_queues == max) - return 0; + return; if (atomic_read(&card->qdio.state) != QETH_QDIO_UNINITIALIZED) qeth_free_qdio_queues(card); @@ -1536,14 +1525,12 @@ static int qeth_osa_set_output_queues(struct qeth_card *card, bool single) dev_info(&card->gdev->dev, "Priority Queueing not supported\n"); card->qdio.no_out_queues = max; - return 0; } static int qeth_update_from_chp_desc(struct qeth_card *card) { struct ccw_device *ccwdev; struct channel_path_desc_fmt0 *chp_dsc; - int rc = 0; QETH_CARD_TEXT(card, 2, "chp_desc"); @@ -1556,12 +1543,12 @@ static int qeth_update_from_chp_desc(struct qeth_card *card) if (IS_OSD(card) || IS_OSX(card)) /* CHPP field bit 6 == 1 -> single queue */ - rc = qeth_osa_set_output_queues(card, chp_dsc->chpp & 0x02); + qeth_osa_set_output_queues(card, chp_dsc->chpp & 0x02); kfree(chp_dsc); QETH_CARD_TEXT_(card, 2, "nr:%x", card->qdio.no_out_queues); QETH_CARD_TEXT_(card, 2, "lvl:%02x", card->info.func_level); - return rc; + return 0; } static void qeth_init_qdio_info(struct qeth_card *card) @@ -5316,6 +5303,20 @@ static int qeth_set_online(struct qeth_card *card) qeth_print_status_message(card); + if (card->dev->reg_state != NETREG_REGISTERED) { + struct qeth_priv *priv = netdev_priv(card->dev); + + if (IS_IQD(card)) + priv->tx_wanted_queues = QETH_IQD_MIN_TXQ; + else if (IS_VM_NIC(card)) + priv->tx_wanted_queues = 1; + else + priv->tx_wanted_queues = card->dev->num_tx_queues; + + /* no need for locking / error handling at this early stage: */ + qeth_set_real_num_tx_queues(card, qeth_tx_actual_queues(card)); + } + rc = card->discipline->set_online(card, carrier_ok); if (rc) goto err_online; @@ -6250,8 +6251,16 @@ static struct net_device *qeth_alloc_netdev(struct qeth_card *card) SET_NETDEV_DEV(dev, &card->gdev->dev); netif_carrier_off(dev); - dev->ethtool_ops = IS_OSN(card) ? &qeth_osn_ethtool_ops : - &qeth_ethtool_ops; + if (IS_OSN(card)) { + dev->ethtool_ops = &qeth_osn_ethtool_ops; + } else { + dev->ethtool_ops = &qeth_ethtool_ops; + dev->priv_flags &= ~IFF_TX_SKB_SHARING; + dev->hw_features |= NETIF_F_SG; + dev->vlan_features |= NETIF_F_SG; + if (IS_IQD(card)) + dev->features |= NETIF_F_SG; + } return dev; } @@ -6267,28 +6276,6 @@ struct net_device *qeth_clone_netdev(struct net_device *orig) return clone; } -int qeth_setup_netdev(struct qeth_card *card) -{ - struct net_device *dev = card->dev; - unsigned int num_tx_queues; - - dev->priv_flags &= ~IFF_TX_SKB_SHARING; - dev->hw_features |= NETIF_F_SG; - dev->vlan_features |= NETIF_F_SG; - - if (IS_IQD(card)) { - dev->features |= NETIF_F_SG; - num_tx_queues = QETH_IQD_MIN_TXQ; - } else if (IS_VM_NIC(card)) { - num_tx_queues = 1; - } else { - num_tx_queues = dev->real_num_tx_queues; - } - - return qeth_set_real_num_tx_queues(card, num_tx_queues); -} -EXPORT_SYMBOL_GPL(qeth_setup_netdev); - static int qeth_core_probe_device(struct ccwgroup_device *gdev) { struct qeth_card *card; @@ -6959,6 +6946,7 @@ int qeth_set_real_num_tx_queues(struct qeth_card *card, unsigned int count) return rc; } +EXPORT_SYMBOL_GPL(qeth_set_real_num_tx_queues); u16 qeth_iqd_select_queue(struct net_device *dev, struct sk_buff *skb, u8 cast_type, struct net_device *sb_dev) diff --git a/drivers/s390/net/qeth_ethtool.c b/drivers/s390/net/qeth_ethtool.c index f870c5322bfe..bc3ea0efb58b 100644 --- a/drivers/s390/net/qeth_ethtool.c +++ b/drivers/s390/net/qeth_ethtool.c @@ -211,7 +211,9 @@ static void qeth_get_channels(struct net_device *dev, static int qeth_set_channels(struct net_device *dev, struct ethtool_channels *channels) { + struct qeth_priv *priv = netdev_priv(dev); struct qeth_card *card = dev->ml_priv; + int rc; if (channels->rx_count == 0 || channels->tx_count == 0) return -EINVAL; @@ -234,7 +236,11 @@ static int qeth_set_channels(struct net_device *dev, return -EOPNOTSUPP; } - return qeth_set_real_num_tx_queues(card, channels->tx_count); + rc = qeth_set_real_num_tx_queues(card, channels->tx_count); + if (!rc) + priv->tx_wanted_queues = channels->tx_count; + + return rc; } static int qeth_get_ts_info(struct net_device *dev, diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c index 1852d0a3c10a..290389fc7e79 100644 --- a/drivers/s390/net/qeth_l2_main.c +++ b/drivers/s390/net/qeth_l2_main.c @@ -894,18 +894,12 @@ static const struct net_device_ops qeth_osn_netdev_ops = { static int qeth_l2_setup_netdev(struct qeth_card *card) { - int rc; - if (IS_OSN(card)) { card->dev->netdev_ops = &qeth_osn_netdev_ops; card->dev->flags |= IFF_NOARP; goto add_napi; } - rc = qeth_setup_netdev(card); - if (rc) - return rc; - card->dev->needed_headroom = sizeof(struct qeth_hdr); card->dev->netdev_ops = &qeth_l2_netdev_ops; card->dev->priv_flags |= IFF_UNICAST_FLT; @@ -2274,6 +2268,13 @@ static int qeth_l2_set_online(struct qeth_card *card, bool carrier_ok) netif_carrier_on(dev); } else { rtnl_lock(); + rc = qeth_set_real_num_tx_queues(card, + qeth_tx_actual_queues(card)); + if (rc) { + rtnl_unlock(); + goto err_set_queues; + } + if (carrier_ok) netif_carrier_on(dev); else @@ -2291,6 +2292,7 @@ static int qeth_l2_set_online(struct qeth_card *card, bool carrier_ok) } return 0; +err_set_queues: err_setup: qeth_set_allowed_threads(card, 0, 1); card->state = CARD_STATE_DOWN; diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index a6f8878b55c6..ea5f25857aff 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c @@ -1875,10 +1875,6 @@ static int qeth_l3_setup_netdev(struct qeth_card *card) unsigned int headroom; int rc; - rc = qeth_setup_netdev(card); - if (rc) - return rc; - if (IS_OSD(card) || IS_OSX(card)) { card->dev->netdev_ops = &qeth_l3_osa_netdev_ops; @@ -2022,6 +2018,13 @@ static int qeth_l3_set_online(struct qeth_card *card, bool carrier_ok) netif_carrier_on(dev); } else { rtnl_lock(); + rc = qeth_set_real_num_tx_queues(card, + qeth_tx_actual_queues(card)); + if (rc) { + rtnl_unlock(); + goto err_set_queues; + } + if (carrier_ok) netif_carrier_on(dev); else @@ -2038,6 +2041,7 @@ static int qeth_l3_set_online(struct qeth_card *card, bool carrier_ok) } return 0; +err_set_queues: err_setup: qeth_set_allowed_threads(card, 0, 1); card->state = CARD_STATE_DOWN; |