summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/s390/net/qeth_core.h11
-rw-r--r--drivers/s390/net/qeth_core_main.c70
-rw-r--r--drivers/s390/net/qeth_ethtool.c8
-rw-r--r--drivers/s390/net/qeth_l2_main.c14
-rw-r--r--drivers/s390/net/qeth_l3_main.c12
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;