netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH net-next 00/11] s390/qeth: updates 2020-03-18
@ 2020-03-18 12:54 Julian Wiedmann
  2020-03-18 12:54 ` [PATCH net-next 01/11] s390/qeth: use memory reserves to back RX buffers Julian Wiedmann
                   ` (11 more replies)
  0 siblings, 12 replies; 14+ messages in thread
From: Julian Wiedmann @ 2020-03-18 12:54 UTC (permalink / raw)
  To: David Miller
  Cc: netdev, linux-s390, Heiko Carstens, Ursula Braun, Julian Wiedmann

Hi Dave,

please apply the following patch series for qeth to netdev's net-next
tree.

This consists of three parts:
1) support for __GFP_MEMALLOC,
2) several ethtool enhancements (.set_channels, SW Timestamping),
3) the usual cleanups.

Thanks,
Julian

Julian Wiedmann (11):
  s390/qeth: use memory reserves to back RX buffers
  s390/qeth: use memory reserves in TX slow path
  s390/qeth: remove prio-queueing support for z/VM NICs
  s390/qeth: allow configuration of TX queues for z/VM NICs
  s390/qeth: allow configuration of TX queues for IQD devices
  s390/qeth: balance the TX queue selection for IQD devices
  s390/qeth: add SW timestamping support for IQD devices
  s390/qeth: don't report hard-coded driver version
  s390/qeth: add phys_to_virt() translation for AOB
  s390/qeth: remove gratuitous NULL checks
  s390/qeth: use dev->reg_state

 drivers/s390/net/qeth_core.h      |   7 +-
 drivers/s390/net/qeth_core_main.c | 131 ++++++++++++++++++++++--------
 drivers/s390/net/qeth_core_sys.c  |   2 +-
 drivers/s390/net/qeth_ethtool.c   |  43 +++++++++-
 drivers/s390/net/qeth_l2_main.c   |  32 ++++----
 drivers/s390/net/qeth_l3_main.c   |  29 +++----
 6 files changed, 174 insertions(+), 70 deletions(-)

-- 
2.17.1


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH net-next 01/11] s390/qeth: use memory reserves to back RX buffers
  2020-03-18 12:54 [PATCH net-next 00/11] s390/qeth: updates 2020-03-18 Julian Wiedmann
@ 2020-03-18 12:54 ` Julian Wiedmann
  2020-03-18 12:54 ` [PATCH net-next 02/11] s390/qeth: use memory reserves in TX slow path Julian Wiedmann
                   ` (10 subsequent siblings)
  11 siblings, 0 replies; 14+ messages in thread
From: Julian Wiedmann @ 2020-03-18 12:54 UTC (permalink / raw)
  To: David Miller
  Cc: netdev, linux-s390, Heiko Carstens, Ursula Braun, Julian Wiedmann

Use dev_alloc_page() for backing the RX buffers with pages. This way we
pick up __GFP_MEMALLOC.

Signed-off-by: Julian Wiedmann <jwi@linux.ibm.com>
---
 drivers/s390/net/qeth_core_main.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c
index 6caa78d51bd1..be3f6295309b 100644
--- a/drivers/s390/net/qeth_core_main.c
+++ b/drivers/s390/net/qeth_core_main.c
@@ -244,7 +244,7 @@ static struct qeth_buffer_pool_entry *qeth_alloc_pool_entry(unsigned int pages)
 		return NULL;
 
 	for (i = 0; i < pages; i++) {
-		entry->elements[i] = alloc_page(GFP_KERNEL);
+		entry->elements[i] = __dev_alloc_page(GFP_KERNEL);
 
 		if (!entry->elements[i]) {
 			qeth_free_pool_entry(entry);
@@ -2654,7 +2654,7 @@ static struct qeth_buffer_pool_entry *qeth_find_free_buffer_pool_entry(
 			struct qeth_buffer_pool_entry, list);
 	for (i = 0; i < QETH_MAX_BUFFER_ELEMENTS(card); ++i) {
 		if (page_count(entry->elements[i]) > 1) {
-			struct page *page = alloc_page(GFP_ATOMIC);
+			struct page *page = dev_alloc_page();
 
 			if (!page)
 				return NULL;
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH net-next 02/11] s390/qeth: use memory reserves in TX slow path
  2020-03-18 12:54 [PATCH net-next 00/11] s390/qeth: updates 2020-03-18 Julian Wiedmann
  2020-03-18 12:54 ` [PATCH net-next 01/11] s390/qeth: use memory reserves to back RX buffers Julian Wiedmann
@ 2020-03-18 12:54 ` Julian Wiedmann
  2020-03-18 12:54 ` [PATCH net-next 03/11] s390/qeth: remove prio-queueing support for z/VM NICs Julian Wiedmann
                   ` (9 subsequent siblings)
  11 siblings, 0 replies; 14+ messages in thread
From: Julian Wiedmann @ 2020-03-18 12:54 UTC (permalink / raw)
  To: David Miller
  Cc: netdev, linux-s390, Heiko Carstens, Ursula Braun, Julian Wiedmann

When falling back to an allocation from the HW header cache, check if
the skb is eligible for using memory reserves.
This only makes a difference if the cache is empty and needs to be
refilled.

Signed-off-by: Julian Wiedmann <jwi@linux.ibm.com>
---
 drivers/s390/net/qeth_core_main.c | 6 ++++--
 drivers/s390/net/qeth_l2_main.c   | 3 ++-
 2 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c
index be3f6295309b..767cef04c9d8 100644
--- a/drivers/s390/net/qeth_core_main.c
+++ b/drivers/s390/net/qeth_core_main.c
@@ -3705,6 +3705,7 @@ static int qeth_add_hw_header(struct qeth_qdio_out_q *queue,
 			      unsigned int hdr_len, unsigned int proto_len,
 			      unsigned int *elements)
 {
+	gfp_t gfp = GFP_ATOMIC | (skb_pfmemalloc(skb) ? __GFP_MEMALLOC : 0);
 	const unsigned int contiguous = proto_len ? proto_len : 1;
 	const unsigned int max_elements = queue->max_elements;
 	unsigned int __elements;
@@ -3760,10 +3761,11 @@ static int qeth_add_hw_header(struct qeth_qdio_out_q *queue,
 		*hdr = skb_push(skb, hdr_len);
 		return hdr_len;
 	}
-	/* fall back */
+
+	/* Fall back to cache element with known-good alignment: */
 	if (hdr_len + proto_len > QETH_HDR_CACHE_OBJ_SIZE)
 		return -E2BIG;
-	*hdr = kmem_cache_alloc(qeth_core_header_cache, GFP_ATOMIC);
+	*hdr = kmem_cache_alloc(qeth_core_header_cache, gfp);
 	if (!*hdr)
 		return -ENOMEM;
 	/* Copy protocol headers behind HW header: */
diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c
index 4c8e93132e08..8ba4ac2a5b47 100644
--- a/drivers/s390/net/qeth_l2_main.c
+++ b/drivers/s390/net/qeth_l2_main.c
@@ -499,6 +499,7 @@ static void qeth_l2_rx_mode_work(struct work_struct *work)
 static int qeth_l2_xmit_osn(struct qeth_card *card, struct sk_buff *skb,
 			    struct qeth_qdio_out_q *queue)
 {
+	gfp_t gfp = GFP_ATOMIC | (skb_pfmemalloc(skb) ? __GFP_MEMALLOC : 0);
 	struct qeth_hdr *hdr = (struct qeth_hdr *)skb->data;
 	addr_t end = (addr_t)(skb->data + sizeof(*hdr));
 	addr_t start = (addr_t)skb->data;
@@ -511,7 +512,7 @@ static int qeth_l2_xmit_osn(struct qeth_card *card, struct sk_buff *skb,
 
 	if (qeth_get_elements_for_range(start, end) > 1) {
 		/* Misaligned HW header, move it to its own buffer element. */
-		hdr = kmem_cache_alloc(qeth_core_header_cache, GFP_ATOMIC);
+		hdr = kmem_cache_alloc(qeth_core_header_cache, gfp);
 		if (!hdr)
 			return -ENOMEM;
 		hd_len = sizeof(*hdr);
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH net-next 03/11] s390/qeth: remove prio-queueing support for z/VM NICs
  2020-03-18 12:54 [PATCH net-next 00/11] s390/qeth: updates 2020-03-18 Julian Wiedmann
  2020-03-18 12:54 ` [PATCH net-next 01/11] s390/qeth: use memory reserves to back RX buffers Julian Wiedmann
  2020-03-18 12:54 ` [PATCH net-next 02/11] s390/qeth: use memory reserves in TX slow path Julian Wiedmann
@ 2020-03-18 12:54 ` Julian Wiedmann
  2020-03-18 12:54 ` [PATCH net-next 04/11] s390/qeth: allow configuration of TX queues " Julian Wiedmann
                   ` (8 subsequent siblings)
  11 siblings, 0 replies; 14+ messages in thread
From: Julian Wiedmann @ 2020-03-18 12:54 UTC (permalink / raw)
  To: David Miller
  Cc: netdev, linux-s390, Heiko Carstens, Ursula Braun, Julian Wiedmann

z/VM NICs don't offer HW QoS for TX rings. So just use netdev_pick_tx()
to distribute the connections equally over all enabled TX queues.

We start with just 1 enabled TX queue (this matches the typical
configuration without prio-queueing). A follow-on patch will allow users
to enable additional TX queues.

Signed-off-by: Julian Wiedmann <jwi@linux.ibm.com>
---
 drivers/s390/net/qeth_core.h      |  1 +
 drivers/s390/net/qeth_core_main.c | 56 +++++++++++++++++++------------
 drivers/s390/net/qeth_core_sys.c  |  2 +-
 drivers/s390/net/qeth_l2_main.c   |  8 ++++-
 drivers/s390/net/qeth_l3_main.c   |  7 +++-
 5 files changed, 49 insertions(+), 25 deletions(-)

diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h
index 962be94ed3ca..94cd39631eee 100644
--- a/drivers/s390/net/qeth_core.h
+++ b/drivers/s390/net/qeth_core.h
@@ -1053,6 +1053,7 @@ int qeth_configure_cq(struct qeth_card *, enum qeth_cq);
 int qeth_hw_trap(struct qeth_card *, enum qeth_diags_trap_action);
 void qeth_trace_features(struct qeth_card *);
 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 767cef04c9d8..f13495d9209b 100644
--- a/drivers/s390/net/qeth_core_main.c
+++ b/drivers/s390/net/qeth_core_main.c
@@ -1244,9 +1244,12 @@ EXPORT_SYMBOL_GPL(qeth_drain_output_queues);
 
 static int qeth_osa_set_output_queues(struct qeth_card *card, bool single)
 {
-	unsigned int count = single ? 1 : card->dev->num_tx_queues;
+	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();
@@ -1254,16 +1257,16 @@ static int qeth_osa_set_output_queues(struct qeth_card *card, bool single)
 	if (rc)
 		return rc;
 
-	if (card->qdio.no_out_queues == count)
+	if (card->qdio.no_out_queues == max)
 		return 0;
 
 	if (atomic_read(&card->qdio.state) != QETH_QDIO_UNINITIALIZED)
 		qeth_free_qdio_queues(card);
 
-	if (count == 1)
+	if (max == 1 && card->qdio.do_prio_queueing != QETH_PRIOQ_DEFAULT)
 		dev_info(&card->gdev->dev, "Priority Queueing not supported\n");
 
-	card->qdio.no_out_queues = count;
+	card->qdio.no_out_queues = max;
 	return 0;
 }
 
@@ -5987,22 +5990,8 @@ static struct net_device *qeth_alloc_netdev(struct qeth_card *card)
 	SET_NETDEV_DEV(dev, &card->gdev->dev);
 	netif_carrier_off(dev);
 
-	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;
-			if (netif_set_real_num_tx_queues(dev,
-							 QETH_IQD_MIN_TXQ)) {
-				free_netdev(dev);
-				return NULL;
-			}
-		}
-	}
+	dev->ethtool_ops = IS_OSN(card) ? &qeth_osn_ethtool_ops :
+					  &qeth_ethtool_ops;
 
 	return dev;
 }
@@ -6018,6 +6007,28 @@ 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 netif_set_real_num_tx_queues(dev, num_tx_queues);
+}
+EXPORT_SYMBOL_GPL(qeth_setup_netdev);
+
 static int qeth_core_probe_device(struct ccwgroup_device *gdev)
 {
 	struct qeth_card *card;
@@ -6057,12 +6068,13 @@ static int qeth_core_probe_device(struct ccwgroup_device *gdev)
 		goto err_card;
 	}
 
+	qeth_determine_capabilities(card);
+	qeth_set_blkt_defaults(card);
+
 	card->qdio.no_out_queues = card->dev->num_tx_queues;
 	rc = qeth_update_from_chp_desc(card);
 	if (rc)
 		goto err_chp_desc;
-	qeth_determine_capabilities(card);
-	qeth_set_blkt_defaults(card);
 
 	enforced_disc = qeth_enforce_discipline(card);
 	switch (enforced_disc) {
diff --git a/drivers/s390/net/qeth_core_sys.c b/drivers/s390/net/qeth_core_sys.c
index 78cae61bc924..533a7f26dbe1 100644
--- a/drivers/s390/net/qeth_core_sys.c
+++ b/drivers/s390/net/qeth_core_sys.c
@@ -176,7 +176,7 @@ static ssize_t qeth_dev_prioqing_store(struct device *dev,
 	struct qeth_card *card = dev_get_drvdata(dev);
 	int rc = 0;
 
-	if (IS_IQD(card))
+	if (IS_IQD(card) || IS_VM_NIC(card))
 		return -EOPNOTSUPP;
 
 	mutex_lock(&card->conf_mutex);
diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c
index 8ba4ac2a5b47..71eb2d9bfbb7 100644
--- a/drivers/s390/net/qeth_l2_main.c
+++ b/drivers/s390/net/qeth_l2_main.c
@@ -571,7 +571,9 @@ static u16 qeth_l2_select_queue(struct net_device *dev, struct sk_buff *skb,
 		return qeth_iqd_select_queue(dev, skb,
 					     qeth_get_ether_cast_type(skb),
 					     sb_dev);
-	return qeth_get_priority_queue(card, skb);
+
+	return IS_VM_NIC(card) ? netdev_pick_tx(dev, skb, sb_dev) :
+				 qeth_get_priority_queue(card, skb);
 }
 
 static const struct device_type qeth_l2_devtype = {
@@ -659,6 +661,10 @@ static int qeth_l2_setup_netdev(struct qeth_card *card, bool carrier_ok)
 		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;
diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c
index 8a803d6c9357..81ec0d2b7ea5 100644
--- a/drivers/s390/net/qeth_l3_main.c
+++ b/drivers/s390/net/qeth_l3_main.c
@@ -1880,7 +1880,8 @@ static u16 qeth_l3_osa_select_queue(struct net_device *dev, struct sk_buff *skb,
 {
 	struct qeth_card *card = dev->ml_priv;
 
-	return qeth_get_priority_queue(card, skb);
+	return IS_VM_NIC(card) ? netdev_pick_tx(dev, skb, sb_dev) :
+				 qeth_get_priority_queue(card, skb);
 }
 
 static const struct net_device_ops qeth_l3_netdev_ops = {
@@ -1922,6 +1923,10 @@ static int qeth_l3_setup_netdev(struct qeth_card *card, bool carrier_ok)
 	unsigned int headroom;
 	int rc;
 
+	rc = qeth_setup_netdev(card);
+	if (rc)
+		return rc;
+
 	if (IS_OSD(card) || IS_OSX(card)) {
 		if ((card->info.link_type == QETH_LINK_TYPE_LANE_TR) ||
 		    (card->info.link_type == QETH_LINK_TYPE_HSTR)) {
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH net-next 04/11] s390/qeth: allow configuration of TX queues for z/VM NICs
  2020-03-18 12:54 [PATCH net-next 00/11] s390/qeth: updates 2020-03-18 Julian Wiedmann
                   ` (2 preceding siblings ...)
  2020-03-18 12:54 ` [PATCH net-next 03/11] s390/qeth: remove prio-queueing support for z/VM NICs Julian Wiedmann
@ 2020-03-18 12:54 ` Julian Wiedmann
  2020-03-18 12:54 ` [PATCH net-next 05/11] s390/qeth: allow configuration of TX queues for IQD devices Julian Wiedmann
                   ` (7 subsequent siblings)
  11 siblings, 0 replies; 14+ messages in thread
From: Julian Wiedmann @ 2020-03-18 12:54 UTC (permalink / raw)
  To: David Miller
  Cc: netdev, linux-s390, Heiko Carstens, Ursula Braun, Julian Wiedmann

Add support for ETHTOOL_SCHANNELS to change the count of active
TX queues.

Since all TX queue structs are pre-allocated and -registered, we just
need to trivially adjust dev->real_num_tx_queues.

Signed-off-by: Julian Wiedmann <jwi@linux.ibm.com>
---
 drivers/s390/net/qeth_ethtool.c | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/drivers/s390/net/qeth_ethtool.c b/drivers/s390/net/qeth_ethtool.c
index 9052c72d5b8f..19b9c8302d36 100644
--- a/drivers/s390/net/qeth_ethtool.c
+++ b/drivers/s390/net/qeth_ethtool.c
@@ -175,6 +175,22 @@ static void qeth_get_channels(struct net_device *dev,
 	channels->combined_count = 0;
 }
 
+static int qeth_set_channels(struct net_device *dev,
+			     struct ethtool_channels *channels)
+{
+	struct qeth_card *card = dev->ml_priv;
+
+	if (IS_IQD(card) || !IS_VM_NIC(card))
+		return -EOPNOTSUPP;
+
+	if (channels->rx_count == 0 || channels->tx_count == 0)
+		return -EINVAL;
+	if (channels->tx_count > card->qdio.no_out_queues)
+		return -EINVAL;
+
+	return netif_set_real_num_tx_queues(dev, channels->tx_count);
+}
+
 static int qeth_get_tunable(struct net_device *dev,
 			    const struct ethtool_tunable *tuna, void *data)
 {
@@ -410,6 +426,7 @@ const struct ethtool_ops qeth_ethtool_ops = {
 	.get_sset_count = qeth_get_sset_count,
 	.get_drvinfo = qeth_get_drvinfo,
 	.get_channels = qeth_get_channels,
+	.set_channels = qeth_set_channels,
 	.get_tunable = qeth_get_tunable,
 	.set_tunable = qeth_set_tunable,
 	.get_link_ksettings = qeth_get_link_ksettings,
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH net-next 05/11] s390/qeth: allow configuration of TX queues for IQD devices
  2020-03-18 12:54 [PATCH net-next 00/11] s390/qeth: updates 2020-03-18 Julian Wiedmann
                   ` (3 preceding siblings ...)
  2020-03-18 12:54 ` [PATCH net-next 04/11] s390/qeth: allow configuration of TX queues " Julian Wiedmann
@ 2020-03-18 12:54 ` Julian Wiedmann
  2020-03-18 12:54 ` [PATCH net-next 06/11] s390/qeth: balance the TX queue selection " Julian Wiedmann
                   ` (6 subsequent siblings)
  11 siblings, 0 replies; 14+ messages in thread
From: Julian Wiedmann @ 2020-03-18 12:54 UTC (permalink / raw)
  To: David Miller
  Cc: netdev, linux-s390, Heiko Carstens, Ursula Braun, Julian Wiedmann

Similar to the support for z/VM NICs, but we need to take extra care
about the dedicated mcast queue:

1. netdev_pick_tx() is unaware of this limitation and might select the
   mcast txq. Catch this.
2. require at least _two_ TX queues - one for ucast, one for mcast.
3. when reducing the number of TX queues, there's a potential race
   where netdev_cap_txqueue() over-rules the selected txq index and
   falls back to index 0. This would place ucast traffic on the mcast
   queue, and result in TX errors.
   So for IQD, reject a reduction while the interface is running.

Signed-off-by: Julian Wiedmann <jwi@linux.ibm.com>
---
 drivers/s390/net/qeth_core_main.c |  6 +++++-
 drivers/s390/net/qeth_ethtool.c   | 19 ++++++++++++++++---
 2 files changed, 21 insertions(+), 4 deletions(-)

diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c
index f13495d9209b..aa493edc0082 100644
--- a/drivers/s390/net/qeth_core_main.c
+++ b/drivers/s390/net/qeth_core_main.c
@@ -6644,9 +6644,13 @@ EXPORT_SYMBOL_GPL(qeth_get_stats64);
 u16 qeth_iqd_select_queue(struct net_device *dev, struct sk_buff *skb,
 			  u8 cast_type, struct net_device *sb_dev)
 {
+	u16 txq;
+
 	if (cast_type != RTN_UNICAST)
 		return QETH_IQD_MCAST_TXQ;
-	return QETH_IQD_MIN_UCAST_TXQ;
+
+	txq = netdev_pick_tx(dev, skb, sb_dev);
+	return (txq == QETH_IQD_MCAST_TXQ) ? QETH_IQD_MIN_UCAST_TXQ : txq;
 }
 EXPORT_SYMBOL_GPL(qeth_iqd_select_queue);
 
diff --git a/drivers/s390/net/qeth_ethtool.c b/drivers/s390/net/qeth_ethtool.c
index 19b9c8302d36..715ee0015847 100644
--- a/drivers/s390/net/qeth_ethtool.c
+++ b/drivers/s390/net/qeth_ethtool.c
@@ -180,14 +180,27 @@ static int qeth_set_channels(struct net_device *dev,
 {
 	struct qeth_card *card = dev->ml_priv;
 
-	if (IS_IQD(card) || !IS_VM_NIC(card))
-		return -EOPNOTSUPP;
-
 	if (channels->rx_count == 0 || channels->tx_count == 0)
 		return -EINVAL;
 	if (channels->tx_count > card->qdio.no_out_queues)
 		return -EINVAL;
 
+	if (IS_IQD(card)) {
+		if (channels->tx_count < QETH_IQD_MIN_TXQ)
+			return -EINVAL;
+
+		/* Reject downgrade while running. It could push displaced
+		 * ucast flows onto txq0, which is reserved for mcast.
+		 */
+		if (netif_running(dev) &&
+		    channels->tx_count < dev->real_num_tx_queues)
+			return -EPERM;
+	} else {
+		/* OSA still uses the legacy prio-queue mechanism: */
+		if (!IS_VM_NIC(card))
+			return -EOPNOTSUPP;
+	}
+
 	return netif_set_real_num_tx_queues(dev, channels->tx_count);
 }
 
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH net-next 06/11] s390/qeth: balance the TX queue selection for IQD devices
  2020-03-18 12:54 [PATCH net-next 00/11] s390/qeth: updates 2020-03-18 Julian Wiedmann
                   ` (4 preceding siblings ...)
  2020-03-18 12:54 ` [PATCH net-next 05/11] s390/qeth: allow configuration of TX queues for IQD devices Julian Wiedmann
@ 2020-03-18 12:54 ` Julian Wiedmann
  2020-03-18 12:54 ` [PATCH net-next 07/11] s390/qeth: add SW timestamping support " Julian Wiedmann
                   ` (5 subsequent siblings)
  11 siblings, 0 replies; 14+ messages in thread
From: Julian Wiedmann @ 2020-03-18 12:54 UTC (permalink / raw)
  To: David Miller
  Cc: netdev, linux-s390, Heiko Carstens, Ursula Braun, Julian Wiedmann

For ucast traffic, qeth_iqd_select_queue() falls back to
netdev_pick_tx(). This will potentially use skb_tx_hash() to distribute
the flow over all active TX queues - so txq 0 is a valid selection, and
qeth_iqd_select_queue() needs to check for this and put it on some other
queue. As a result, the distribution for ucast flows is unbalanced and
hits QETH_IQD_MIN_UCAST_TXQ heavier than the other queues.

Open-coding a custom variant of skb_tx_hash() isn't an option, since
netdev_pick_tx() also gives us eg. access to XPS. But we can pull a
little trick: add a single TC class that excludes the mcast txq, and
thus encourage skb_tx_hash() to not pick the mcast txq.

Signed-off-by: Julian Wiedmann <jwi@linux.ibm.com>
---
 drivers/s390/net/qeth_core.h      |  1 +
 drivers/s390/net/qeth_core_main.c | 45 ++++++++++++++++++++++++++++++-
 drivers/s390/net/qeth_ethtool.c   |  2 +-
 3 files changed, 46 insertions(+), 2 deletions(-)

diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h
index 94cd39631eee..b8b356aca674 100644
--- a/drivers/s390/net/qeth_core.h
+++ b/drivers/s390/net/qeth_core.h
@@ -1061,6 +1061,7 @@ netdev_features_t qeth_features_check(struct sk_buff *skb,
 				      struct net_device *dev,
 				      netdev_features_t features);
 void qeth_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats);
+int qeth_set_real_num_tx_queues(struct qeth_card *card, unsigned int count);
 u16 qeth_iqd_select_queue(struct net_device *dev, struct sk_buff *skb,
 			  u8 cast_type, struct net_device *sb_dev);
 int qeth_open(struct net_device *dev);
diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c
index aa493edc0082..e1d984c29e1f 100644
--- a/drivers/s390/net/qeth_core_main.c
+++ b/drivers/s390/net/qeth_core_main.c
@@ -6025,7 +6025,7 @@ int qeth_setup_netdev(struct qeth_card *card)
 		num_tx_queues = dev->real_num_tx_queues;
 	}
 
-	return netif_set_real_num_tx_queues(dev, num_tx_queues);
+	return qeth_set_real_num_tx_queues(card, num_tx_queues);
 }
 EXPORT_SYMBOL_GPL(qeth_setup_netdev);
 
@@ -6641,6 +6641,47 @@ void qeth_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats)
 }
 EXPORT_SYMBOL_GPL(qeth_get_stats64);
 
+#define TC_IQD_UCAST   0
+static void qeth_iqd_set_prio_tc_map(struct net_device *dev,
+				     unsigned int ucast_txqs)
+{
+	unsigned int prio;
+
+	/* IQD requires mcast traffic to be placed on a dedicated queue, and
+	 * qeth_iqd_select_queue() deals with this.
+	 * For unicast traffic, we defer the queue selection to the stack.
+	 * By installing a trivial prio map that spans over only the unicast
+	 * queues, we can encourage the stack to spread the ucast traffic evenly
+	 * without selecting the mcast queue.
+	 */
+
+	/* One traffic class, spanning over all active ucast queues: */
+	netdev_set_num_tc(dev, 1);
+	netdev_set_tc_queue(dev, TC_IQD_UCAST, ucast_txqs,
+			    QETH_IQD_MIN_UCAST_TXQ);
+
+	/* Map all priorities to this traffic class: */
+	for (prio = 0; prio <= TC_BITMASK; prio++)
+		netdev_set_prio_tc_map(dev, prio, TC_IQD_UCAST);
+}
+
+int qeth_set_real_num_tx_queues(struct qeth_card *card, unsigned int count)
+{
+	struct net_device *dev = card->dev;
+	int rc;
+
+	/* Per netif_setup_tc(), adjust the mapping first: */
+	if (IS_IQD(card))
+		qeth_iqd_set_prio_tc_map(dev, count - 1);
+
+	rc = netif_set_real_num_tx_queues(dev, count);
+
+	if (rc && IS_IQD(card))
+		qeth_iqd_set_prio_tc_map(dev, dev->real_num_tx_queues - 1);
+
+	return rc;
+}
+
 u16 qeth_iqd_select_queue(struct net_device *dev, struct sk_buff *skb,
 			  u8 cast_type, struct net_device *sb_dev)
 {
@@ -6648,6 +6689,8 @@ u16 qeth_iqd_select_queue(struct net_device *dev, struct sk_buff *skb,
 
 	if (cast_type != RTN_UNICAST)
 		return QETH_IQD_MCAST_TXQ;
+	if (dev->real_num_tx_queues == QETH_IQD_MIN_TXQ)
+		return QETH_IQD_MIN_UCAST_TXQ;
 
 	txq = netdev_pick_tx(dev, skb, sb_dev);
 	return (txq == QETH_IQD_MCAST_TXQ) ? QETH_IQD_MIN_UCAST_TXQ : txq;
diff --git a/drivers/s390/net/qeth_ethtool.c b/drivers/s390/net/qeth_ethtool.c
index 715ee0015847..079b695032ef 100644
--- a/drivers/s390/net/qeth_ethtool.c
+++ b/drivers/s390/net/qeth_ethtool.c
@@ -201,7 +201,7 @@ static int qeth_set_channels(struct net_device *dev,
 			return -EOPNOTSUPP;
 	}
 
-	return netif_set_real_num_tx_queues(dev, channels->tx_count);
+	return qeth_set_real_num_tx_queues(card, channels->tx_count);
 }
 
 static int qeth_get_tunable(struct net_device *dev,
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH net-next 07/11] s390/qeth: add SW timestamping support for IQD devices
  2020-03-18 12:54 [PATCH net-next 00/11] s390/qeth: updates 2020-03-18 Julian Wiedmann
                   ` (5 preceding siblings ...)
  2020-03-18 12:54 ` [PATCH net-next 06/11] s390/qeth: balance the TX queue selection " Julian Wiedmann
@ 2020-03-18 12:54 ` Julian Wiedmann
  2020-03-18 12:54 ` [PATCH net-next 08/11] s390/qeth: don't report hard-coded driver version Julian Wiedmann
                   ` (4 subsequent siblings)
  11 siblings, 0 replies; 14+ messages in thread
From: Julian Wiedmann @ 2020-03-18 12:54 UTC (permalink / raw)
  To: David Miller
  Cc: netdev, linux-s390, Heiko Carstens, Ursula Braun, Julian Wiedmann

This adds support for SOF_TIMESTAMPING_TX_SOFTWARE.
No support for non-IQD devices, since they orphan the skb in their xmit
path.

To play nice with TX bulking, set the timestamp when the buffer that
contains the skb(s) is actually flushed out to HW.

Signed-off-by: Julian Wiedmann <jwi@linux.ibm.com>
---
 drivers/s390/net/qeth_core_main.c |  6 +++++-
 drivers/s390/net/qeth_ethtool.c   | 12 ++++++++++++
 2 files changed, 17 insertions(+), 1 deletion(-)

diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c
index e1d984c29e1f..33796fe80a63 100644
--- a/drivers/s390/net/qeth_core_main.c
+++ b/drivers/s390/net/qeth_core_main.c
@@ -3355,6 +3355,7 @@ static void qeth_flush_buffers(struct qeth_qdio_out_q *queue, int index,
 
 	for (i = index; i < index + count; ++i) {
 		unsigned int bidx = QDIO_BUFNR(i);
+		struct sk_buff *skb;
 
 		buf = queue->bufs[bidx];
 		buf->buffer->element[buf->next_element_to_fill - 1].eflags |=
@@ -3363,8 +3364,11 @@ static void qeth_flush_buffers(struct qeth_qdio_out_q *queue, int index,
 		if (queue->bufstates)
 			queue->bufstates[bidx].user = buf;
 
-		if (IS_IQD(queue->card))
+		if (IS_IQD(card)) {
+			skb_queue_walk(&buf->skb_list, skb)
+				skb_tx_timestamp(skb);
 			continue;
+		}
 
 		if (!queue->do_pack) {
 			if ((atomic_read(&queue->used_buffers) >=
diff --git a/drivers/s390/net/qeth_ethtool.c b/drivers/s390/net/qeth_ethtool.c
index 079b695032ef..5cfa371b7426 100644
--- a/drivers/s390/net/qeth_ethtool.c
+++ b/drivers/s390/net/qeth_ethtool.c
@@ -204,6 +204,17 @@ static int qeth_set_channels(struct net_device *dev,
 	return qeth_set_real_num_tx_queues(card, channels->tx_count);
 }
 
+static int qeth_get_ts_info(struct net_device *dev,
+			    struct ethtool_ts_info *info)
+{
+	struct qeth_card *card = dev->ml_priv;
+
+	if (!IS_IQD(card))
+		return -EOPNOTSUPP;
+
+	return ethtool_op_get_ts_info(dev, info);
+}
+
 static int qeth_get_tunable(struct net_device *dev,
 			    const struct ethtool_tunable *tuna, void *data)
 {
@@ -440,6 +451,7 @@ const struct ethtool_ops qeth_ethtool_ops = {
 	.get_drvinfo = qeth_get_drvinfo,
 	.get_channels = qeth_get_channels,
 	.set_channels = qeth_set_channels,
+	.get_ts_info = qeth_get_ts_info,
 	.get_tunable = qeth_get_tunable,
 	.set_tunable = qeth_set_tunable,
 	.get_link_ksettings = qeth_get_link_ksettings,
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH net-next 08/11] s390/qeth: don't report hard-coded driver version
  2020-03-18 12:54 [PATCH net-next 00/11] s390/qeth: updates 2020-03-18 Julian Wiedmann
                   ` (6 preceding siblings ...)
  2020-03-18 12:54 ` [PATCH net-next 07/11] s390/qeth: add SW timestamping support " Julian Wiedmann
@ 2020-03-18 12:54 ` Julian Wiedmann
  2020-03-18 13:07   ` Leon Romanovsky
  2020-03-18 12:54 ` [PATCH net-next 09/11] s390/qeth: add phys_to_virt() translation for AOB Julian Wiedmann
                   ` (3 subsequent siblings)
  11 siblings, 1 reply; 14+ messages in thread
From: Julian Wiedmann @ 2020-03-18 12:54 UTC (permalink / raw)
  To: David Miller
  Cc: netdev, linux-s390, Heiko Carstens, Ursula Braun,
	Julian Wiedmann, Leon Romanovsky

Versions are meaningless for an in-kernel driver.
Instead use the UTS_RELEASE that is set by ethtool_get_drvinfo().

Cc: Leon Romanovsky <leonro@mellanox.com>
Signed-off-by: Julian Wiedmann <jwi@linux.ibm.com>
---
 drivers/s390/net/qeth_ethtool.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/s390/net/qeth_ethtool.c b/drivers/s390/net/qeth_ethtool.c
index 5cfa371b7426..31e019085fc3 100644
--- a/drivers/s390/net/qeth_ethtool.c
+++ b/drivers/s390/net/qeth_ethtool.c
@@ -153,7 +153,6 @@ static void qeth_get_drvinfo(struct net_device *dev,
 
 	strlcpy(info->driver, IS_LAYER2(card) ? "qeth_l2" : "qeth_l3",
 		sizeof(info->driver));
-	strlcpy(info->version, "1.0", sizeof(info->version));
 	strlcpy(info->fw_version, card->info.mcl_level,
 		sizeof(info->fw_version));
 	snprintf(info->bus_info, sizeof(info->bus_info), "%s/%s/%s",
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH net-next 09/11] s390/qeth: add phys_to_virt() translation for AOB
  2020-03-18 12:54 [PATCH net-next 00/11] s390/qeth: updates 2020-03-18 Julian Wiedmann
                   ` (7 preceding siblings ...)
  2020-03-18 12:54 ` [PATCH net-next 08/11] s390/qeth: don't report hard-coded driver version Julian Wiedmann
@ 2020-03-18 12:54 ` Julian Wiedmann
  2020-03-18 12:54 ` [PATCH net-next 10/11] s390/qeth: remove gratuitous NULL checks Julian Wiedmann
                   ` (2 subsequent siblings)
  11 siblings, 0 replies; 14+ messages in thread
From: Julian Wiedmann @ 2020-03-18 12:54 UTC (permalink / raw)
  To: David Miller
  Cc: netdev, linux-s390, Heiko Carstens, Ursula Braun, Julian Wiedmann

Data addresses in the AOB are absolute, and need to be translated before
being fed into kmem_cache_free(). Currently this phys_to_virt() is a no-op.
Also see commit 2db01da8d25f ("s390/qdio: fill SBALEs with absolute addresses").

Signed-off-by: Julian Wiedmann <jwi@linux.ibm.com>
---
 drivers/s390/net/qeth_core_main.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c
index 33796fe80a63..3f0b13ff580e 100644
--- a/drivers/s390/net/qeth_core_main.c
+++ b/drivers/s390/net/qeth_core_main.c
@@ -538,9 +538,10 @@ static void qeth_qdio_handle_aob(struct qeth_card *card,
 	for (i = 0;
 	     i < aob->sb_count && i < QETH_MAX_BUFFER_ELEMENTS(card);
 	     i++) {
-		if (aob->sba[i] && buffer->is_header[i])
-			kmem_cache_free(qeth_core_header_cache,
-					(void *) aob->sba[i]);
+		void *data = phys_to_virt(aob->sba[i]);
+
+		if (data && buffer->is_header[i])
+			kmem_cache_free(qeth_core_header_cache, data);
 	}
 	atomic_set(&buffer->state, QETH_QDIO_BUF_HANDLED_DELAYED);
 
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH net-next 10/11] s390/qeth: remove gratuitous NULL checks
  2020-03-18 12:54 [PATCH net-next 00/11] s390/qeth: updates 2020-03-18 Julian Wiedmann
                   ` (8 preceding siblings ...)
  2020-03-18 12:54 ` [PATCH net-next 09/11] s390/qeth: add phys_to_virt() translation for AOB Julian Wiedmann
@ 2020-03-18 12:54 ` Julian Wiedmann
  2020-03-18 12:54 ` [PATCH net-next 11/11] s390/qeth: use dev->reg_state Julian Wiedmann
  2020-03-18 23:34 ` [PATCH net-next 00/11] s390/qeth: updates 2020-03-18 David Miller
  11 siblings, 0 replies; 14+ messages in thread
From: Julian Wiedmann @ 2020-03-18 12:54 UTC (permalink / raw)
  To: David Miller
  Cc: netdev, linux-s390, Heiko Carstens, Ursula Braun, Julian Wiedmann

qeth_do_ioctl() is only reached through our own net_device_ops, so we
can trust that dev->ml_priv still contains what we put there earlier.

qeth_bridgeport_an_set() is an internal function that doesn't require
such sanity checks.

Signed-off-by: Julian Wiedmann <jwi@linux.ibm.com>
---
 drivers/s390/net/qeth_core_main.c | 3 ---
 drivers/s390/net/qeth_l2_main.c   | 2 --
 2 files changed, 5 deletions(-)

diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c
index 3f0b13ff580e..bd3adbb6ad50 100644
--- a/drivers/s390/net/qeth_core_main.c
+++ b/drivers/s390/net/qeth_core_main.c
@@ -6264,9 +6264,6 @@ int qeth_do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 	struct mii_ioctl_data *mii_data;
 	int rc = 0;
 
-	if (!card)
-		return -ENODEV;
-
 	switch (cmd) {
 	case SIOC_QETH_ADP_SET_SNMP_CONTROL:
 		rc = qeth_snmp_command(card, rq->ifr_ifru.ifru_data);
diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c
index 71eb2d9bfbb7..2aaf5e3779ce 100644
--- a/drivers/s390/net/qeth_l2_main.c
+++ b/drivers/s390/net/qeth_l2_main.c
@@ -1519,8 +1519,6 @@ int qeth_bridgeport_an_set(struct qeth_card *card, int enable)
 	struct ccw_device *ddev;
 	struct subchannel_id schid;
 
-	if (!card)
-		return -EINVAL;
 	if (!card->options.sbp.supported_funcs)
 		return -EOPNOTSUPP;
 	ddev = CARD_DDEV(card);
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH net-next 11/11] s390/qeth: use dev->reg_state
  2020-03-18 12:54 [PATCH net-next 00/11] s390/qeth: updates 2020-03-18 Julian Wiedmann
                   ` (9 preceding siblings ...)
  2020-03-18 12:54 ` [PATCH net-next 10/11] s390/qeth: remove gratuitous NULL checks Julian Wiedmann
@ 2020-03-18 12:54 ` Julian Wiedmann
  2020-03-18 23:34 ` [PATCH net-next 00/11] s390/qeth: updates 2020-03-18 David Miller
  11 siblings, 0 replies; 14+ messages in thread
From: Julian Wiedmann @ 2020-03-18 12:54 UTC (permalink / raw)
  To: David Miller
  Cc: netdev, linux-s390, Heiko Carstens, Ursula Braun, Julian Wiedmann

To check whether a netdevice has already been registered, look at
NETREG_REGISTERED to replace some hacks I added a while ago.

Signed-off-by: Julian Wiedmann <jwi@linux.ibm.com>
---
 drivers/s390/net/qeth_core.h    |  5 -----
 drivers/s390/net/qeth_l2_main.c | 19 ++++++++-----------
 drivers/s390/net/qeth_l3_main.c | 22 +++++++++-------------
 3 files changed, 17 insertions(+), 29 deletions(-)

diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h
index b8b356aca674..6eb431c194bd 100644
--- a/drivers/s390/net/qeth_core.h
+++ b/drivers/s390/net/qeth_core.h
@@ -847,11 +847,6 @@ struct qeth_trap_id {
 /*some helper functions*/
 #define QETH_CARD_IFNAME(card) (((card)->dev)? (card)->dev->name : "")
 
-static inline bool qeth_netdev_is_registered(struct net_device *dev)
-{
-	return dev->netdev_ops != NULL;
-}
-
 static inline u16 qeth_iqd_translate_txq(struct net_device *dev, u16 txq)
 {
 	if (txq == QETH_IQD_MCAST_TXQ)
diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c
index 2aaf5e3779ce..73cb363b1fab 100644
--- a/drivers/s390/net/qeth_l2_main.c
+++ b/drivers/s390/net/qeth_l2_main.c
@@ -613,7 +613,7 @@ static void qeth_l2_remove_device(struct ccwgroup_device *cgdev)
 		qeth_set_offline(card, false);
 
 	cancel_work_sync(&card->close_dev_work);
-	if (qeth_netdev_is_registered(card->dev))
+	if (card->dev->reg_state == NETREG_REGISTERED)
 		unregister_netdev(card->dev);
 }
 
@@ -651,7 +651,7 @@ static const struct net_device_ops qeth_osn_netdev_ops = {
 	.ndo_tx_timeout		= qeth_tx_timeout,
 };
 
-static int qeth_l2_setup_netdev(struct qeth_card *card, bool carrier_ok)
+static int qeth_l2_setup_netdev(struct qeth_card *card)
 {
 	int rc;
 
@@ -711,13 +711,7 @@ static int qeth_l2_setup_netdev(struct qeth_card *card, bool carrier_ok)
 
 add_napi:
 	netif_napi_add(card->dev, &card->napi, qeth_poll, QETH_NAPI_WEIGHT);
-	rc = register_netdev(card->dev);
-	if (!rc && carrier_ok)
-		netif_carrier_on(card->dev);
-
-	if (rc)
-		card->dev->netdev_ops = NULL;
-	return rc;
+	return register_netdev(card->dev);
 }
 
 static void qeth_l2_trace_features(struct qeth_card *card)
@@ -790,10 +784,13 @@ static int qeth_l2_set_online(struct qeth_card *card)
 
 	qeth_set_allowed_threads(card, 0xffffffff, 0);
 
-	if (!qeth_netdev_is_registered(dev)) {
-		rc = qeth_l2_setup_netdev(card, carrier_ok);
+	if (dev->reg_state != NETREG_REGISTERED) {
+		rc = qeth_l2_setup_netdev(card);
 		if (rc)
 			goto out_remove;
+
+		if (carrier_ok)
+			netif_carrier_on(dev);
 	} else {
 		rtnl_lock();
 		if (carrier_ok)
diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c
index 81ec0d2b7ea5..83ae75cf1389 100644
--- a/drivers/s390/net/qeth_l3_main.c
+++ b/drivers/s390/net/qeth_l3_main.c
@@ -1918,7 +1918,7 @@ static const struct net_device_ops qeth_l3_osa_netdev_ops = {
 	.ndo_neigh_setup	= qeth_l3_neigh_setup,
 };
 
-static int qeth_l3_setup_netdev(struct qeth_card *card, bool carrier_ok)
+static int qeth_l3_setup_netdev(struct qeth_card *card)
 {
 	unsigned int headroom;
 	int rc;
@@ -1972,7 +1972,7 @@ static int qeth_l3_setup_netdev(struct qeth_card *card, bool carrier_ok)
 
 		rc = qeth_l3_iqd_read_initial_mac(card);
 		if (rc)
-			goto out;
+			return rc;
 	} else
 		return -ENODEV;
 
@@ -1987,14 +1987,7 @@ static int qeth_l3_setup_netdev(struct qeth_card *card, bool carrier_ok)
 				       PAGE_SIZE * (QETH_MAX_BUFFER_ELEMENTS(card) - 1));
 
 	netif_napi_add(card->dev, &card->napi, qeth_poll, QETH_NAPI_WEIGHT);
-	rc = register_netdev(card->dev);
-	if (!rc && carrier_ok)
-		netif_carrier_on(card->dev);
-
-out:
-	if (rc)
-		card->dev->netdev_ops = NULL;
-	return rc;
+	return register_netdev(card->dev);
 }
 
 static const struct device_type qeth_l3_devtype = {
@@ -2041,7 +2034,7 @@ static void qeth_l3_remove_device(struct ccwgroup_device *cgdev)
 		qeth_set_offline(card, false);
 
 	cancel_work_sync(&card->close_dev_work);
-	if (qeth_netdev_is_registered(card->dev))
+	if (card->dev->reg_state == NETREG_REGISTERED)
 		unregister_netdev(card->dev);
 
 	flush_workqueue(card->cmd_wq);
@@ -2088,10 +2081,13 @@ static int qeth_l3_set_online(struct qeth_card *card)
 	qeth_set_allowed_threads(card, 0xffffffff, 0);
 	qeth_l3_recover_ip(card);
 
-	if (!qeth_netdev_is_registered(dev)) {
-		rc = qeth_l3_setup_netdev(card, carrier_ok);
+	if (dev->reg_state != NETREG_REGISTERED) {
+		rc = qeth_l3_setup_netdev(card);
 		if (rc)
 			goto out_remove;
+
+		if (carrier_ok)
+			netif_carrier_on(dev);
 	} else {
 		rtnl_lock();
 		if (carrier_ok)
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [PATCH net-next 08/11] s390/qeth: don't report hard-coded driver version
  2020-03-18 12:54 ` [PATCH net-next 08/11] s390/qeth: don't report hard-coded driver version Julian Wiedmann
@ 2020-03-18 13:07   ` Leon Romanovsky
  0 siblings, 0 replies; 14+ messages in thread
From: Leon Romanovsky @ 2020-03-18 13:07 UTC (permalink / raw)
  To: Julian Wiedmann
  Cc: David Miller, netdev, linux-s390, Heiko Carstens, Ursula Braun

On Wed, Mar 18, 2020 at 01:54:52PM +0100, Julian Wiedmann wrote:
> Versions are meaningless for an in-kernel driver.
> Instead use the UTS_RELEASE that is set by ethtool_get_drvinfo().
>
> Cc: Leon Romanovsky <leonro@mellanox.com>
> Signed-off-by: Julian Wiedmann <jwi@linux.ibm.com>
> ---
>  drivers/s390/net/qeth_ethtool.c | 1 -
>  1 file changed, 1 deletion(-)
>

Thanks a lot for the patch,
Reviewed-by: Leon Romanovsky <leonro@mellanox.com>

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH net-next 00/11] s390/qeth: updates 2020-03-18
  2020-03-18 12:54 [PATCH net-next 00/11] s390/qeth: updates 2020-03-18 Julian Wiedmann
                   ` (10 preceding siblings ...)
  2020-03-18 12:54 ` [PATCH net-next 11/11] s390/qeth: use dev->reg_state Julian Wiedmann
@ 2020-03-18 23:34 ` David Miller
  11 siblings, 0 replies; 14+ messages in thread
From: David Miller @ 2020-03-18 23:34 UTC (permalink / raw)
  To: jwi; +Cc: netdev, linux-s390, heiko.carstens, ubraun

From: Julian Wiedmann <jwi@linux.ibm.com>
Date: Wed, 18 Mar 2020 13:54:44 +0100

> please apply the following patch series for qeth to netdev's net-next
> tree.
> 
> This consists of three parts:
> 1) support for __GFP_MEMALLOC,
> 2) several ethtool enhancements (.set_channels, SW Timestamping),
> 3) the usual cleanups.

Series applied, thanks.

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2020-03-18 23:34 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-03-18 12:54 [PATCH net-next 00/11] s390/qeth: updates 2020-03-18 Julian Wiedmann
2020-03-18 12:54 ` [PATCH net-next 01/11] s390/qeth: use memory reserves to back RX buffers Julian Wiedmann
2020-03-18 12:54 ` [PATCH net-next 02/11] s390/qeth: use memory reserves in TX slow path Julian Wiedmann
2020-03-18 12:54 ` [PATCH net-next 03/11] s390/qeth: remove prio-queueing support for z/VM NICs Julian Wiedmann
2020-03-18 12:54 ` [PATCH net-next 04/11] s390/qeth: allow configuration of TX queues " Julian Wiedmann
2020-03-18 12:54 ` [PATCH net-next 05/11] s390/qeth: allow configuration of TX queues for IQD devices Julian Wiedmann
2020-03-18 12:54 ` [PATCH net-next 06/11] s390/qeth: balance the TX queue selection " Julian Wiedmann
2020-03-18 12:54 ` [PATCH net-next 07/11] s390/qeth: add SW timestamping support " Julian Wiedmann
2020-03-18 12:54 ` [PATCH net-next 08/11] s390/qeth: don't report hard-coded driver version Julian Wiedmann
2020-03-18 13:07   ` Leon Romanovsky
2020-03-18 12:54 ` [PATCH net-next 09/11] s390/qeth: add phys_to_virt() translation for AOB Julian Wiedmann
2020-03-18 12:54 ` [PATCH net-next 10/11] s390/qeth: remove gratuitous NULL checks Julian Wiedmann
2020-03-18 12:54 ` [PATCH net-next 11/11] s390/qeth: use dev->reg_state Julian Wiedmann
2020-03-18 23:34 ` [PATCH net-next 00/11] s390/qeth: updates 2020-03-18 David Miller

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).