netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH net-next 0/9] s390/qeth: updates 2020-11-17
@ 2020-11-17 16:15 Julian Wiedmann
  2020-11-17 16:15 ` [PATCH net-next 1/9] s390/qeth: don't call INIT_LIST_HEAD() on iob's list entry Julian Wiedmann
                   ` (9 more replies)
  0 siblings, 10 replies; 13+ messages in thread
From: Julian Wiedmann @ 2020-11-17 16:15 UTC (permalink / raw)
  To: David Miller, Jakub Kicinski
  Cc: linux-netdev, linux-s390, Heiko Carstens, Karsten Graul, Julian Wiedmann

Hi Jakub,

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

This brings some cleanups, and a bunch of improvements for our
.get_link_ksettings() code.

Julian Wiedmann (8):
  s390/qeth: don't call INIT_LIST_HEAD() on iob's list entry
  s390/qeth: reduce rtnl locking for switchdev events
  s390/qeth: tolerate error when querying card info
  s390/qeth: improve QUERY CARD INFO processing
  s390/qeth: set static link info during initialization
  s390/qeth: clean up default cases for ethtool link mode
  s390/qeth: use QUERY OAT for initial link info
  s390/qeth: improve selection of ethtool link modes

Kaixu Xia (1):
  s390/qeth: remove useless if/else

 drivers/s390/net/qeth_core.h      |  24 ++-
 drivers/s390/net/qeth_core_main.c | 232 ++++++++++++++++++++++++++--
 drivers/s390/net/qeth_core_mpc.h  |  40 ++++-
 drivers/s390/net/qeth_ethtool.c   | 243 +++++++++++-------------------
 drivers/s390/net/qeth_l2_main.c   |  33 ++--
 drivers/s390/net/qeth_l3_main.c   |   5 +-
 6 files changed, 378 insertions(+), 199 deletions(-)

-- 
2.17.1


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

* [PATCH net-next 1/9] s390/qeth: don't call INIT_LIST_HEAD() on iob's list entry
  2020-11-17 16:15 [PATCH net-next 0/9] s390/qeth: updates 2020-11-17 Julian Wiedmann
@ 2020-11-17 16:15 ` Julian Wiedmann
  2020-11-17 16:15 ` [PATCH net-next 2/9] s390/qeth: reduce rtnl locking for switchdev events Julian Wiedmann
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 13+ messages in thread
From: Julian Wiedmann @ 2020-11-17 16:15 UTC (permalink / raw)
  To: David Miller, Jakub Kicinski
  Cc: linux-netdev, linux-s390, Heiko Carstens, Karsten Graul, Julian Wiedmann

INIT_LIST_HEAD() only needs to be called on actual list heads.
While at it clarify the naming of the field.

Suggested-by: Vasily Gorbik <gor@linux.ibm.com>
Signed-off-by: Julian Wiedmann <jwi@linux.ibm.com>
---
 drivers/s390/net/qeth_core.h      | 2 +-
 drivers/s390/net/qeth_core_main.c | 9 ++++-----
 2 files changed, 5 insertions(+), 6 deletions(-)

diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h
index f73b4756ed5e..ec4525bd62e1 100644
--- a/drivers/s390/net/qeth_core.h
+++ b/drivers/s390/net/qeth_core.h
@@ -621,7 +621,7 @@ struct qeth_reply {
 };
 
 struct qeth_cmd_buffer {
-	struct list_head list;
+	struct list_head list_entry;
 	struct completion done;
 	spinlock_t lock;
 	unsigned int length;
diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c
index 93c9b30ab17a..67e5c46e8373 100644
--- a/drivers/s390/net/qeth_core_main.c
+++ b/drivers/s390/net/qeth_core_main.c
@@ -609,7 +609,7 @@ static void qeth_enqueue_cmd(struct qeth_card *card,
 			     struct qeth_cmd_buffer *iob)
 {
 	spin_lock_irq(&card->lock);
-	list_add_tail(&iob->list, &card->cmd_waiter_list);
+	list_add_tail(&iob->list_entry, &card->cmd_waiter_list);
 	spin_unlock_irq(&card->lock);
 }
 
@@ -617,7 +617,7 @@ static void qeth_dequeue_cmd(struct qeth_card *card,
 			     struct qeth_cmd_buffer *iob)
 {
 	spin_lock_irq(&card->lock);
-	list_del(&iob->list);
+	list_del(&iob->list_entry);
 	spin_unlock_irq(&card->lock);
 }
 
@@ -971,7 +971,7 @@ static void qeth_clear_ipacmd_list(struct qeth_card *card)
 	QETH_CARD_TEXT(card, 4, "clipalst");
 
 	spin_lock_irqsave(&card->lock, flags);
-	list_for_each_entry(iob, &card->cmd_waiter_list, list)
+	list_for_each_entry(iob, &card->cmd_waiter_list, list_entry)
 		qeth_notify_cmd(iob, -ECANCELED);
 	spin_unlock_irqrestore(&card->lock, flags);
 }
@@ -1041,7 +1041,6 @@ struct qeth_cmd_buffer *qeth_alloc_cmd(struct qeth_channel *channel,
 
 	init_completion(&iob->done);
 	spin_lock_init(&iob->lock);
-	INIT_LIST_HEAD(&iob->list);
 	refcount_set(&iob->ref_count, 1);
 	iob->channel = channel;
 	iob->timeout = timeout;
@@ -1088,7 +1087,7 @@ static void qeth_issue_next_read_cb(struct qeth_card *card,
 
 	/* match against pending cmd requests */
 	spin_lock_irqsave(&card->lock, flags);
-	list_for_each_entry(tmp, &card->cmd_waiter_list, list) {
+	list_for_each_entry(tmp, &card->cmd_waiter_list, list_entry) {
 		if (tmp->match && tmp->match(tmp, iob)) {
 			request = tmp;
 			/* take the object outside the lock */
-- 
2.17.1


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

* [PATCH net-next 2/9] s390/qeth: reduce rtnl locking for switchdev events
  2020-11-17 16:15 [PATCH net-next 0/9] s390/qeth: updates 2020-11-17 Julian Wiedmann
  2020-11-17 16:15 ` [PATCH net-next 1/9] s390/qeth: don't call INIT_LIST_HEAD() on iob's list entry Julian Wiedmann
@ 2020-11-17 16:15 ` Julian Wiedmann
  2020-11-17 16:15 ` [PATCH net-next 3/9] s390/qeth: remove useless if/else Julian Wiedmann
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 13+ messages in thread
From: Julian Wiedmann @ 2020-11-17 16:15 UTC (permalink / raw)
  To: David Miller, Jakub Kicinski
  Cc: linux-netdev, linux-s390, Heiko Carstens, Karsten Graul, Julian Wiedmann

call_switchdev_notifiers() doesn't require holding the RTNL lock since
commit ff5cf100110c ("net: switchdev: Change notifier chain to be atomic").

We still need it for the "lost event" slow path, to avoid racing against
a concurrent .ndo_bridge_setlink().

Signed-off-by: Julian Wiedmann <jwi@linux.ibm.com>
Reviewed-by: Alexandra Winter <wintera@linux.ibm.com>
---
 drivers/s390/net/qeth_l2_main.c | 33 +++++++++++++++------------------
 1 file changed, 15 insertions(+), 18 deletions(-)

diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c
index 28f6dda95736..daeb837abec3 100644
--- a/drivers/s390/net/qeth_l2_main.c
+++ b/drivers/s390/net/qeth_l2_main.c
@@ -737,8 +737,6 @@ static void qeth_l2_dev2br_an_set_cb(void *priv,
  *
  *	On enable, emits a series of address notifications for all
  *	currently registered hosts.
- *
- *	Must be called under rtnl_lock
  */
 static int qeth_l2_dev2br_an_set(struct qeth_card *card, bool enable)
 {
@@ -1289,16 +1287,19 @@ static void qeth_l2_dev2br_worker(struct work_struct *work)
 	if (READ_ONCE(card->info.pnso_mode) == QETH_PNSO_NONE)
 		goto free;
 
-	/* Potential re-config in progress, try again later: */
-	if (!rtnl_trylock()) {
-		queue_delayed_work(card->event_wq, dwork,
-				   msecs_to_jiffies(100));
-		return;
-	}
-	if (!netif_device_present(card->dev))
-		goto out_unlock;
-
 	if (data->ac_event.lost_event_mask) {
+		/* Potential re-config in progress, try again later: */
+		if (!rtnl_trylock()) {
+			queue_delayed_work(card->event_wq, dwork,
+					   msecs_to_jiffies(100));
+			return;
+		}
+
+		if (!netif_device_present(card->dev)) {
+			rtnl_unlock();
+			goto free;
+		}
+
 		QETH_DBF_MESSAGE(3,
 				 "Address change notification overflow on device %x\n",
 				 CARD_DEVID(card));
@@ -1328,6 +1329,8 @@ static void qeth_l2_dev2br_worker(struct work_struct *work)
 					 "Address Notification resynced on device %x\n",
 					 CARD_DEVID(card));
 		}
+
+		rtnl_unlock();
 	} else {
 		for (i = 0; i < data->ac_event.num_entries; i++) {
 			struct qeth_ipacmd_addr_change_entry *entry =
@@ -1339,9 +1342,6 @@ static void qeth_l2_dev2br_worker(struct work_struct *work)
 		}
 	}
 
-out_unlock:
-	rtnl_unlock();
-
 free:
 	kfree(data);
 }
@@ -2310,11 +2310,8 @@ static void qeth_l2_set_offline(struct qeth_card *card)
 		card->state = CARD_STATE_DOWN;
 
 	qeth_l2_set_pnso_mode(card, QETH_PNSO_NONE);
-	if (priv->brport_features & BR_LEARNING_SYNC) {
-		rtnl_lock();
+	if (priv->brport_features & BR_LEARNING_SYNC)
 		qeth_l2_dev2br_fdb_flush(card);
-		rtnl_unlock();
-	}
 }
 
 /* Returns zero if the command is successfully "consumed" */
-- 
2.17.1


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

* [PATCH net-next 3/9] s390/qeth: remove useless if/else
  2020-11-17 16:15 [PATCH net-next 0/9] s390/qeth: updates 2020-11-17 Julian Wiedmann
  2020-11-17 16:15 ` [PATCH net-next 1/9] s390/qeth: don't call INIT_LIST_HEAD() on iob's list entry Julian Wiedmann
  2020-11-17 16:15 ` [PATCH net-next 2/9] s390/qeth: reduce rtnl locking for switchdev events Julian Wiedmann
@ 2020-11-17 16:15 ` Julian Wiedmann
  2020-11-17 16:15 ` [PATCH net-next 4/9] s390/qeth: tolerate error when querying card info Julian Wiedmann
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 13+ messages in thread
From: Julian Wiedmann @ 2020-11-17 16:15 UTC (permalink / raw)
  To: David Miller, Jakub Kicinski
  Cc: linux-netdev, linux-s390, Heiko Carstens, Karsten Graul,
	Julian Wiedmann, Kaixu Xia

From: Kaixu Xia <kaixuxia@tencent.com>

Fix the following coccinelle report:

./drivers/s390/net/qeth_l3_main.c:107:2-4: WARNING: possible condition with no effect (if == else)

Both branches are the same since
commit ab29c480b194 ("s390/qeth: replace deprecated simple_stroul()"),
so remove them.

Reported-by: Tosk Robot <tencent_os_robot@tencent.com>
Signed-off-by: Kaixu Xia <kaixuxia@tencent.com>
[jwi: point to the commit that introduced this]
Signed-off-by: Julian Wiedmann <jwi@linux.ibm.com>
---
 drivers/s390/net/qeth_l3_main.c | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c
index b1c1d2510d55..264b6c782382 100644
--- a/drivers/s390/net/qeth_l3_main.c
+++ b/drivers/s390/net/qeth_l3_main.c
@@ -104,10 +104,7 @@ static bool qeth_l3_is_addr_covered_by_ipato(struct qeth_card *card,
 		qeth_l3_convert_addr_to_bits(ipatoe->addr, ipatoe_bits,
 					  (ipatoe->proto == QETH_PROT_IPV4) ?
 					  4 : 16);
-		if (addr->proto == QETH_PROT_IPV4)
-			rc = !memcmp(addr_bits, ipatoe_bits, ipatoe->mask_bits);
-		else
-			rc = !memcmp(addr_bits, ipatoe_bits, ipatoe->mask_bits);
+		rc = !memcmp(addr_bits, ipatoe_bits, ipatoe->mask_bits);
 		if (rc)
 			break;
 	}
-- 
2.17.1


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

* [PATCH net-next 4/9] s390/qeth: tolerate error when querying card info
  2020-11-17 16:15 [PATCH net-next 0/9] s390/qeth: updates 2020-11-17 Julian Wiedmann
                   ` (2 preceding siblings ...)
  2020-11-17 16:15 ` [PATCH net-next 3/9] s390/qeth: remove useless if/else Julian Wiedmann
@ 2020-11-17 16:15 ` Julian Wiedmann
  2020-11-17 16:15 ` [PATCH net-next 5/9] s390/qeth: improve QUERY CARD INFO processing Julian Wiedmann
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 13+ messages in thread
From: Julian Wiedmann @ 2020-11-17 16:15 UTC (permalink / raw)
  To: David Miller, Jakub Kicinski
  Cc: linux-netdev, linux-s390, Heiko Carstens, Karsten Graul, Julian Wiedmann

By the time that our .get_link_ksettings() code issues a QUERY CARD INFO
cmd to get link-related information, we already set up a good amount of
static link data.

Return this data when the cmd fails, same as when the cmd is not
supported.

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

diff --git a/drivers/s390/net/qeth_ethtool.c b/drivers/s390/net/qeth_ethtool.c
index b5caa723326e..b843df2c14b1 100644
--- a/drivers/s390/net/qeth_ethtool.c
+++ b/drivers/s390/net/qeth_ethtool.c
@@ -413,7 +413,6 @@ static int qeth_get_link_ksettings(struct net_device *netdev,
 	struct qeth_card *card = netdev->ml_priv;
 	enum qeth_link_types link_type;
 	struct carrier_info carrier_info;
-	int rc;
 
 	if (IS_IQD(card) || IS_VM_NIC(card))
 		link_type = QETH_LINK_TYPE_10GBIT_ETH;
@@ -455,12 +454,8 @@ static int qeth_get_link_ksettings(struct net_device *netdev,
 	/* Check if we can obtain more accurate information.	 */
 	/* If QUERY_CARD_INFO command is not supported or fails, */
 	/* just return the heuristics that was filled above.	 */
-	rc = qeth_query_card_info(card, &carrier_info);
-	if (rc == -EOPNOTSUPP) /* for old hardware, return heuristic */
+	if (qeth_query_card_info(card, &carrier_info))
 		return 0;
-	if (rc) /* report error from the hardware operation */
-		return rc;
-	/* on success, fill in the information got from the hardware */
 
 	netdev_dbg(netdev,
 	"card info: card_type=0x%02x, port_mode=0x%04x, port_speed=0x%08x\n",
-- 
2.17.1


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

* [PATCH net-next 5/9] s390/qeth: improve QUERY CARD INFO processing
  2020-11-17 16:15 [PATCH net-next 0/9] s390/qeth: updates 2020-11-17 Julian Wiedmann
                   ` (3 preceding siblings ...)
  2020-11-17 16:15 ` [PATCH net-next 4/9] s390/qeth: tolerate error when querying card info Julian Wiedmann
@ 2020-11-17 16:15 ` Julian Wiedmann
  2020-11-17 16:15 ` [PATCH net-next 6/9] s390/qeth: set static link info during initialization Julian Wiedmann
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 13+ messages in thread
From: Julian Wiedmann @ 2020-11-17 16:15 UTC (permalink / raw)
  To: David Miller, Jakub Kicinski
  Cc: linux-netdev, linux-s390, Heiko Carstens, Karsten Graul, Julian Wiedmann

Move all the HW reply data parsing into qeth_query_card_info_cb(), and
use common ethtool enums for transporting the information back to the
caller.

Also only look at the .port_speed field when we couldn't determine the
speed from the .card_type field, and introduce some 'default' cases for
SPEED_UNKNOWN, PORT_OTHER and DUPLEX_UNKNOWN.

Signed-off-by: Julian Wiedmann <jwi@linux.ibm.com>
---
 drivers/s390/net/qeth_core.h      | 14 +++---
 drivers/s390/net/qeth_core_main.c | 67 +++++++++++++++++++++++++---
 drivers/s390/net/qeth_ethtool.c   | 74 +++++--------------------------
 3 files changed, 79 insertions(+), 76 deletions(-)

diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h
index ec4525bd62e1..1c9ed498c2b6 100644
--- a/drivers/s390/net/qeth_core.h
+++ b/drivers/s390/net/qeth_core.h
@@ -701,6 +701,12 @@ enum qeth_pnso_mode {
 	QETH_PNSO_ADDR_INFO,
 };
 
+struct qeth_link_info {
+	u32 speed;
+	u8 duplex;
+	u8 port;
+};
+
 #define QETH_BROADCAST_WITH_ECHO    0x01
 #define QETH_BROADCAST_WITHOUT_ECHO 0x02
 struct qeth_card_info {
@@ -796,12 +802,6 @@ struct qeth_rx {
 	u8 bufs_refill;
 };
 
-struct carrier_info {
-	__u8  card_type;
-	__u16 port_mode;
-	__u32 port_speed;
-};
-
 struct qeth_switch_info {
 	__u32 capabilities;
 	__u32 settings;
@@ -1108,7 +1108,7 @@ void qeth_prepare_ipa_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob,
 int qeth_query_switch_attributes(struct qeth_card *card,
 				  struct qeth_switch_info *sw_info);
 int qeth_query_card_info(struct qeth_card *card,
-			 struct carrier_info *carrier_info);
+			 struct qeth_link_info *link_info);
 int qeth_setadpparms_set_access_ctrl(struct qeth_card *card,
 				     enum qeth_ipa_isolation_modes mode);
 
diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c
index 67e5c46e8373..e7c226c6c989 100644
--- a/drivers/s390/net/qeth_core_main.c
+++ b/drivers/s390/net/qeth_core_main.c
@@ -4867,8 +4867,8 @@ static int qeth_query_oat_command(struct qeth_card *card, char __user *udata)
 static int qeth_query_card_info_cb(struct qeth_card *card,
 				   struct qeth_reply *reply, unsigned long data)
 {
-	struct carrier_info *carrier_info = (struct carrier_info *)reply->param;
 	struct qeth_ipa_cmd *cmd = (struct qeth_ipa_cmd *)data;
+	struct qeth_link_info *link_info = reply->param;
 	struct qeth_query_card_info *card_info;
 
 	QETH_CARD_TEXT(card, 2, "qcrdincb");
@@ -4876,14 +4876,67 @@ static int qeth_query_card_info_cb(struct qeth_card *card,
 		return -EIO;
 
 	card_info = &cmd->data.setadapterparms.data.card_info;
-	carrier_info->card_type = card_info->card_type;
-	carrier_info->port_mode = card_info->port_mode;
-	carrier_info->port_speed = card_info->port_speed;
+	netdev_dbg(card->dev,
+		   "card info: card_type=0x%02x, port_mode=0x%04x, port_speed=0x%08x\n",
+		   card_info->card_type, card_info->port_mode,
+		   card_info->port_speed);
+
+	switch (card_info->port_mode) {
+	case CARD_INFO_PORTM_FULLDUPLEX:
+		link_info->duplex = DUPLEX_FULL;
+		break;
+	case CARD_INFO_PORTM_HALFDUPLEX:
+		link_info->duplex = DUPLEX_HALF;
+		break;
+	default:
+		link_info->duplex = DUPLEX_UNKNOWN;
+	}
+
+	switch (card_info->card_type) {
+	case CARD_INFO_TYPE_1G_COPPER_A:
+	case CARD_INFO_TYPE_1G_COPPER_B:
+		link_info->speed = SPEED_1000;
+		link_info->port = PORT_TP;
+		break;
+	case CARD_INFO_TYPE_1G_FIBRE_A:
+	case CARD_INFO_TYPE_1G_FIBRE_B:
+		link_info->speed = SPEED_1000;
+		link_info->port = PORT_FIBRE;
+		break;
+	case CARD_INFO_TYPE_10G_FIBRE_A:
+	case CARD_INFO_TYPE_10G_FIBRE_B:
+		link_info->speed = SPEED_10000;
+		link_info->port = PORT_FIBRE;
+		break;
+	default:
+		switch (card_info->port_speed) {
+		case CARD_INFO_PORTS_10M:
+			link_info->speed = SPEED_10;
+			break;
+		case CARD_INFO_PORTS_100M:
+			link_info->speed = SPEED_100;
+			break;
+		case CARD_INFO_PORTS_1G:
+			link_info->speed = SPEED_1000;
+			break;
+		case CARD_INFO_PORTS_10G:
+			link_info->speed = SPEED_10000;
+			break;
+		case CARD_INFO_PORTS_25G:
+			link_info->speed = SPEED_25000;
+			break;
+		default:
+			link_info->speed = SPEED_UNKNOWN;
+		}
+
+		link_info->port = PORT_OTHER;
+	}
+
 	return 0;
 }
 
 int qeth_query_card_info(struct qeth_card *card,
-			 struct carrier_info *carrier_info)
+			 struct qeth_link_info *link_info)
 {
 	struct qeth_cmd_buffer *iob;
 
@@ -4893,8 +4946,8 @@ int qeth_query_card_info(struct qeth_card *card,
 	iob = qeth_get_adapter_cmd(card, IPA_SETADP_QUERY_CARD_INFO, 0);
 	if (!iob)
 		return -ENOMEM;
-	return qeth_send_ipa_cmd(card, iob, qeth_query_card_info_cb,
-					(void *)carrier_info);
+
+	return qeth_send_ipa_cmd(card, iob, qeth_query_card_info_cb, link_info);
 }
 
 /**
diff --git a/drivers/s390/net/qeth_ethtool.c b/drivers/s390/net/qeth_ethtool.c
index b843df2c14b1..a6455819f403 100644
--- a/drivers/s390/net/qeth_ethtool.c
+++ b/drivers/s390/net/qeth_ethtool.c
@@ -324,8 +324,7 @@ static int qeth_set_per_queue_coalesce(struct net_device *dev, u32 queue,
 /* 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_cmd_adv_sup(struct ethtool_link_ksettings *cmd,
-				int maxspeed, int porttype)
+static void qeth_set_ethtool_link_modes(struct ethtool_link_ksettings *cmd)
 {
 	ethtool_link_ksettings_zero_link_mode(cmd, supported);
 	ethtool_link_ksettings_zero_link_mode(cmd, advertising);
@@ -334,7 +333,7 @@ static void qeth_set_cmd_adv_sup(struct ethtool_link_ksettings *cmd,
 	ethtool_link_ksettings_add_link_mode(cmd, supported, Autoneg);
 	ethtool_link_ksettings_add_link_mode(cmd, advertising, Autoneg);
 
-	switch (porttype) {
+	switch (cmd->base.port) {
 	case PORT_TP:
 		ethtool_link_ksettings_add_link_mode(cmd, supported, TP);
 		ethtool_link_ksettings_add_link_mode(cmd, advertising, TP);
@@ -350,7 +349,7 @@ static void qeth_set_cmd_adv_sup(struct ethtool_link_ksettings *cmd,
 	}
 
 	/* partially does fall through, to also select lower speeds */
-	switch (maxspeed) {
+	switch (cmd->base.speed) {
 	case SPEED_25000:
 		ethtool_link_ksettings_add_link_mode(cmd, supported,
 						     25000baseSR_Full);
@@ -406,13 +405,12 @@ static void qeth_set_cmd_adv_sup(struct ethtool_link_ksettings *cmd,
 	}
 }
 
-
 static int qeth_get_link_ksettings(struct net_device *netdev,
 				   struct ethtool_link_ksettings *cmd)
 {
 	struct qeth_card *card = netdev->ml_priv;
+	struct qeth_link_info link_info;
 	enum qeth_link_types link_type;
-	struct carrier_info carrier_info;
 
 	if (IS_IQD(card) || IS_VM_NIC(card))
 		link_type = QETH_LINK_TYPE_10GBIT_ETH;
@@ -449,66 +447,18 @@ static int qeth_get_link_ksettings(struct net_device *netdev,
 		cmd->base.speed = SPEED_10;
 		cmd->base.port = PORT_TP;
 	}
-	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, */
-	/* just return the heuristics that was filled above.	 */
-	if (qeth_query_card_info(card, &carrier_info))
-		return 0;
-
-	netdev_dbg(netdev,
-	"card info: card_type=0x%02x, port_mode=0x%04x, port_speed=0x%08x\n",
-			carrier_info.card_type,
-			carrier_info.port_mode,
-			carrier_info.port_speed);
-
-	/* Update attributes for which we've obtained more authoritative */
-	/* information, leave the rest the way they where filled above.  */
-	switch (carrier_info.card_type) {
-	case CARD_INFO_TYPE_1G_COPPER_A:
-	case CARD_INFO_TYPE_1G_COPPER_B:
-		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:
-		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:
-		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:
-		cmd->base.duplex = DUPLEX_FULL;
-		break;
-	case CARD_INFO_PORTM_HALFDUPLEX:
-		cmd->base.duplex = DUPLEX_HALF;
-		break;
+	if (!qeth_query_card_info(card, &link_info)) {
+		if (link_info.speed != SPEED_UNKNOWN)
+			cmd->base.speed = link_info.speed;
+		if (link_info.duplex != DUPLEX_UNKNOWN)
+			cmd->base.duplex = link_info.duplex;
+		if (link_info.port != PORT_OTHER)
+			cmd->base.port = link_info.port;
 	}
 
-	switch (carrier_info.port_speed) {
-	case CARD_INFO_PORTS_10M:
-		cmd->base.speed = SPEED_10;
-		break;
-	case CARD_INFO_PORTS_100M:
-		cmd->base.speed = SPEED_100;
-		break;
-	case CARD_INFO_PORTS_1G:
-		cmd->base.speed = SPEED_1000;
-		break;
-	case CARD_INFO_PORTS_10G:
-		cmd->base.speed = SPEED_10000;
-		break;
-	case CARD_INFO_PORTS_25G:
-		cmd->base.speed = SPEED_25000;
-		break;
-	}
+	qeth_set_ethtool_link_modes(cmd);
 
 	return 0;
 }
-- 
2.17.1


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

* [PATCH net-next 6/9] s390/qeth: set static link info during initialization
  2020-11-17 16:15 [PATCH net-next 0/9] s390/qeth: updates 2020-11-17 Julian Wiedmann
                   ` (4 preceding siblings ...)
  2020-11-17 16:15 ` [PATCH net-next 5/9] s390/qeth: improve QUERY CARD INFO processing Julian Wiedmann
@ 2020-11-17 16:15 ` Julian Wiedmann
  2020-11-17 16:15 ` [PATCH net-next 7/9] s390/qeth: clean up default cases for ethtool link mode Julian Wiedmann
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 13+ messages in thread
From: Julian Wiedmann @ 2020-11-17 16:15 UTC (permalink / raw)
  To: David Miller, Jakub Kicinski
  Cc: linux-netdev, linux-s390, Heiko Carstens, Karsten Graul, Julian Wiedmann

Hard-code the minimal link info at initialization time, after we
obtained the link_type. qeth_get_link_ksettings() can still override
this with more accurate data from QUERY CARD INFO later on.

Don't set arbitrary defaults for unknown OSA link types, they
certainly won't match any future type.

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

diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h
index 1c9ed498c2b6..c604e20a5e48 100644
--- a/drivers/s390/net/qeth_core.h
+++ b/drivers/s390/net/qeth_core.h
@@ -738,6 +738,7 @@ struct qeth_card_info {
 	struct qeth_card_blkt blkt;
 	__u32 diagass_support;
 	__u32 hwtrap;
+	struct qeth_link_info link_info;
 };
 
 enum qeth_discipline_id {
diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c
index e7c226c6c989..aac38ade024b 100644
--- a/drivers/s390/net/qeth_core_main.c
+++ b/drivers/s390/net/qeth_core_main.c
@@ -4950,6 +4950,42 @@ int qeth_query_card_info(struct qeth_card *card,
 	return qeth_send_ipa_cmd(card, iob, qeth_query_card_info_cb, link_info);
 }
 
+static void qeth_init_link_info(struct qeth_card *card)
+{
+	card->info.link_info.duplex = DUPLEX_FULL;
+
+	if (IS_IQD(card) || IS_VM_NIC(card)) {
+		card->info.link_info.speed = SPEED_10000;
+		card->info.link_info.port = PORT_FIBRE;
+	} else {
+		switch (card->info.link_type) {
+		case QETH_LINK_TYPE_FAST_ETH:
+		case QETH_LINK_TYPE_LANE_ETH100:
+			card->info.link_info.speed = SPEED_100;
+			card->info.link_info.port = PORT_TP;
+			break;
+		case QETH_LINK_TYPE_GBIT_ETH:
+		case QETH_LINK_TYPE_LANE_ETH1000:
+			card->info.link_info.speed = SPEED_1000;
+			card->info.link_info.port = PORT_FIBRE;
+			break;
+		case QETH_LINK_TYPE_10GBIT_ETH:
+			card->info.link_info.speed = SPEED_10000;
+			card->info.link_info.port = PORT_FIBRE;
+			break;
+		case QETH_LINK_TYPE_25GBIT_ETH:
+			card->info.link_info.speed = SPEED_25000;
+			card->info.link_info.port = PORT_FIBRE;
+			break;
+		default:
+			dev_info(&card->gdev->dev, "Unknown link type %x\n",
+				 card->info.link_type);
+			card->info.link_info.speed = SPEED_UNKNOWN;
+			card->info.link_info.port = PORT_OTHER;
+		}
+	}
+}
+
 /**
  * qeth_vm_request_mac() - Request a hypervisor-managed MAC address
  * @card: pointer to a qeth_card
@@ -5334,6 +5370,8 @@ static int qeth_hardsetup_card(struct qeth_card *card, bool *carrier_ok)
 			goto out;
 	}
 
+	qeth_init_link_info(card);
+
 	rc = qeth_init_qdio_queues(card);
 	if (rc) {
 		QETH_CARD_TEXT_(card, 2, "9err%d", rc);
diff --git a/drivers/s390/net/qeth_ethtool.c b/drivers/s390/net/qeth_ethtool.c
index a6455819f403..b8e74018b44f 100644
--- a/drivers/s390/net/qeth_ethtool.c
+++ b/drivers/s390/net/qeth_ethtool.c
@@ -410,44 +410,16 @@ static int qeth_get_link_ksettings(struct net_device *netdev,
 {
 	struct qeth_card *card = netdev->ml_priv;
 	struct qeth_link_info link_info;
-	enum qeth_link_types link_type;
 
-	if (IS_IQD(card) || IS_VM_NIC(card))
-		link_type = QETH_LINK_TYPE_10GBIT_ETH;
-	else
-		link_type = card->info.link_type;
-
-	cmd->base.duplex = DUPLEX_FULL;
+	cmd->base.speed = card->info.link_info.speed;
+	cmd->base.duplex = card->info.link_info.duplex;
+	cmd->base.port = card->info.link_info.port;
 	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:
-		cmd->base.speed = SPEED_100;
-		cmd->base.port = PORT_TP;
-		break;
-	case QETH_LINK_TYPE_GBIT_ETH:
-	case QETH_LINK_TYPE_LANE_ETH1000:
-		cmd->base.speed = SPEED_1000;
-		cmd->base.port = PORT_FIBRE;
-		break;
-	case QETH_LINK_TYPE_10GBIT_ETH:
-		cmd->base.speed = SPEED_10000;
-		cmd->base.port = PORT_FIBRE;
-		break;
-	case QETH_LINK_TYPE_25GBIT_ETH:
-		cmd->base.speed = SPEED_25000;
-		cmd->base.port = PORT_FIBRE;
-		break;
-	default:
-		cmd->base.speed = SPEED_10;
-		cmd->base.port = PORT_TP;
-	}
-
 	/* Check if we can obtain more accurate information.	 */
 	if (!qeth_query_card_info(card, &link_info)) {
 		if (link_info.speed != SPEED_UNKNOWN)
-- 
2.17.1


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

* [PATCH net-next 7/9] s390/qeth: clean up default cases for ethtool link mode
  2020-11-17 16:15 [PATCH net-next 0/9] s390/qeth: updates 2020-11-17 Julian Wiedmann
                   ` (5 preceding siblings ...)
  2020-11-17 16:15 ` [PATCH net-next 6/9] s390/qeth: set static link info during initialization Julian Wiedmann
@ 2020-11-17 16:15 ` Julian Wiedmann
  2020-11-17 16:15 ` [PATCH net-next 8/9] s390/qeth: use QUERY OAT for initial link info Julian Wiedmann
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 13+ messages in thread
From: Julian Wiedmann @ 2020-11-17 16:15 UTC (permalink / raw)
  To: David Miller, Jakub Kicinski
  Cc: linux-netdev, linux-s390, Heiko Carstens, Karsten Graul, Julian Wiedmann

Remove the default case for PORT_* and SPEED_* in our ethtool code.

The only time these could be hit is if qeth_init_link_info() was unable
to determine the port type from an OSA adapter's link_type.
We already throw a message in this case, so reduce the noise and don't
report bad data (ie. it's much more likely that any future link_type
will represent a PORT_FIBRE link ...).

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

diff --git a/drivers/s390/net/qeth_ethtool.c b/drivers/s390/net/qeth_ethtool.c
index b8e74018b44f..50b0c1810850 100644
--- a/drivers/s390/net/qeth_ethtool.c
+++ b/drivers/s390/net/qeth_ethtool.c
@@ -343,9 +343,7 @@ static void qeth_set_ethtool_link_modes(struct ethtool_link_ksettings *cmd)
 		ethtool_link_ksettings_add_link_mode(cmd, advertising, FIBRE);
 		break;
 	default:
-		ethtool_link_ksettings_add_link_mode(cmd, supported, TP);
-		ethtool_link_ksettings_add_link_mode(cmd, advertising, TP);
-		WARN_ON_ONCE(1);
+		break;
 	}
 
 	/* partially does fall through, to also select lower speeds */
@@ -393,15 +391,7 @@ static void qeth_set_ethtool_link_modes(struct ethtool_link_ksettings *cmd)
 						     10baseT_Half);
 		break;
 	default:
-		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);
+		break;
 	}
 }
 
-- 
2.17.1


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

* [PATCH net-next 8/9] s390/qeth: use QUERY OAT for initial link info
  2020-11-17 16:15 [PATCH net-next 0/9] s390/qeth: updates 2020-11-17 Julian Wiedmann
                   ` (6 preceding siblings ...)
  2020-11-17 16:15 ` [PATCH net-next 7/9] s390/qeth: clean up default cases for ethtool link mode Julian Wiedmann
@ 2020-11-17 16:15 ` Julian Wiedmann
  2020-11-17 16:15 ` [PATCH net-next 9/9] s390/qeth: improve selection of ethtool link modes Julian Wiedmann
  2020-11-19  1:35 ` [PATCH net-next 0/9] s390/qeth: updates 2020-11-17 Jakub Kicinski
  9 siblings, 0 replies; 13+ messages in thread
From: Julian Wiedmann @ 2020-11-17 16:15 UTC (permalink / raw)
  To: David Miller, Jakub Kicinski
  Cc: linux-netdev, linux-s390, Heiko Carstens, Karsten Graul, Julian Wiedmann

Improve the initial link info with data obtained from QUERY OAT.
Doing so _only_ at initialization time avoids
1. dealing with multi-part replies, and
2. sifting through all the data that may get returned at runtime.

This allows us to determine the correct port type for the 1000BT variant
of recent OSA adapter generations (where the .card_type field in
QUERY CARD INFO is no longer sufficient).

Signed-off-by: Julian Wiedmann <jwi@linux.ibm.com>
---
 drivers/s390/net/qeth_core_main.c | 107 ++++++++++++++++++++++++++++++
 drivers/s390/net/qeth_core_mpc.h  |  40 ++++++++++-
 2 files changed, 145 insertions(+), 2 deletions(-)

diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c
index aac38ade024b..57dad31aab4d 100644
--- a/drivers/s390/net/qeth_core_main.c
+++ b/drivers/s390/net/qeth_core_main.c
@@ -4950,6 +4950,86 @@ int qeth_query_card_info(struct qeth_card *card,
 	return qeth_send_ipa_cmd(card, iob, qeth_query_card_info_cb, link_info);
 }
 
+static int qeth_init_link_info_oat_cb(struct qeth_card *card,
+				      struct qeth_reply *reply_priv,
+				      unsigned long data)
+{
+	struct qeth_ipa_cmd *cmd = (struct qeth_ipa_cmd *)data;
+	struct qeth_link_info *link_info = reply_priv->param;
+	struct qeth_query_oat_physical_if *phys_if;
+	struct qeth_query_oat_reply *reply;
+
+	if (qeth_setadpparms_inspect_rc(cmd))
+		return -EIO;
+
+	/* Multi-part reply is unexpected, don't bother: */
+	if (cmd->data.setadapterparms.hdr.used_total > 1)
+		return -EINVAL;
+
+	/* Expect the reply to start with phys_if data: */
+	reply = &cmd->data.setadapterparms.data.query_oat.reply[0];
+	if (reply->type != QETH_QOAT_REPLY_TYPE_PHYS_IF ||
+	    reply->length < sizeof(*reply))
+		return -EINVAL;
+
+	phys_if = &reply->phys_if;
+
+	switch (phys_if->speed_duplex) {
+	case QETH_QOAT_PHYS_SPEED_10M_HALF:
+		link_info->speed = SPEED_10;
+		link_info->duplex = DUPLEX_HALF;
+		break;
+	case QETH_QOAT_PHYS_SPEED_10M_FULL:
+		link_info->speed = SPEED_10;
+		link_info->duplex = DUPLEX_FULL;
+		break;
+	case QETH_QOAT_PHYS_SPEED_100M_HALF:
+		link_info->speed = SPEED_100;
+		link_info->duplex = DUPLEX_HALF;
+		break;
+	case QETH_QOAT_PHYS_SPEED_100M_FULL:
+		link_info->speed = SPEED_100;
+		link_info->duplex = DUPLEX_FULL;
+		break;
+	case QETH_QOAT_PHYS_SPEED_1000M_HALF:
+		link_info->speed = SPEED_1000;
+		link_info->duplex = DUPLEX_HALF;
+		break;
+	case QETH_QOAT_PHYS_SPEED_1000M_FULL:
+		link_info->speed = SPEED_1000;
+		link_info->duplex = DUPLEX_FULL;
+		break;
+	case QETH_QOAT_PHYS_SPEED_10G_FULL:
+		link_info->speed = SPEED_10000;
+		link_info->duplex = DUPLEX_FULL;
+		break;
+	case QETH_QOAT_PHYS_SPEED_25G_FULL:
+		link_info->speed = SPEED_25000;
+		link_info->duplex = DUPLEX_FULL;
+		break;
+	case QETH_QOAT_PHYS_SPEED_UNKNOWN:
+	default:
+		link_info->speed = SPEED_UNKNOWN;
+		link_info->duplex = DUPLEX_UNKNOWN;
+		break;
+	}
+
+	switch (phys_if->media_type) {
+	case QETH_QOAT_PHYS_MEDIA_COPPER:
+		link_info->port = PORT_TP;
+		break;
+	case QETH_QOAT_PHYS_MEDIA_FIBRE_SHORT:
+	case QETH_QOAT_PHYS_MEDIA_FIBRE_LONG:
+		link_info->port = PORT_FIBRE;
+		break;
+	default:
+		link_info->port = PORT_OTHER;
+		break;
+	}
+
+	return 0;
+}
+
 static void qeth_init_link_info(struct qeth_card *card)
 {
 	card->info.link_info.duplex = DUPLEX_FULL;
@@ -4984,6 +5064,33 @@ static void qeth_init_link_info(struct qeth_card *card)
 			card->info.link_info.port = PORT_OTHER;
 		}
 	}
+
+	/* Get more accurate data via QUERY OAT: */
+	if (qeth_adp_supported(card, IPA_SETADP_QUERY_OAT)) {
+		struct qeth_link_info link_info;
+		struct qeth_cmd_buffer *iob;
+
+		iob = qeth_get_adapter_cmd(card, IPA_SETADP_QUERY_OAT,
+					   SETADP_DATA_SIZEOF(query_oat));
+		if (iob) {
+			struct qeth_ipa_cmd *cmd = __ipa_cmd(iob);
+			struct qeth_query_oat *oat_req;
+
+			oat_req = &cmd->data.setadapterparms.data.query_oat;
+			oat_req->subcmd_code = QETH_QOAT_SCOPE_INTERFACE;
+
+			if (!qeth_send_ipa_cmd(card, iob,
+					       qeth_init_link_info_oat_cb,
+					       &link_info)) {
+				if (link_info.speed != SPEED_UNKNOWN)
+					card->info.link_info.speed = link_info.speed;
+				if (link_info.duplex != DUPLEX_UNKNOWN)
+					card->info.link_info.duplex = link_info.duplex;
+				if (link_info.port != PORT_OTHER)
+					card->info.link_info.port = link_info.port;
+			}
+		}
+	}
 }
 
 /**
diff --git a/drivers/s390/net/qeth_core_mpc.h b/drivers/s390/net/qeth_core_mpc.h
index 6541bab96822..e4bde7daf083 100644
--- a/drivers/s390/net/qeth_core_mpc.h
+++ b/drivers/s390/net/qeth_core_mpc.h
@@ -489,9 +489,45 @@ struct qeth_set_access_ctrl {
 	__u8 reserved[8];
 } __attribute__((packed));
 
+#define QETH_QOAT_PHYS_SPEED_UNKNOWN		0x00
+#define QETH_QOAT_PHYS_SPEED_10M_HALF		0x01
+#define QETH_QOAT_PHYS_SPEED_10M_FULL		0x02
+#define QETH_QOAT_PHYS_SPEED_100M_HALF		0x03
+#define QETH_QOAT_PHYS_SPEED_100M_FULL		0x04
+#define QETH_QOAT_PHYS_SPEED_1000M_HALF		0x05
+#define QETH_QOAT_PHYS_SPEED_1000M_FULL		0x06
+// n/a						0x07
+#define QETH_QOAT_PHYS_SPEED_10G_FULL		0x08
+// n/a						0x09
+#define QETH_QOAT_PHYS_SPEED_25G_FULL		0x0A
+
+#define QETH_QOAT_PHYS_MEDIA_COPPER		0x01
+#define QETH_QOAT_PHYS_MEDIA_FIBRE_SHORT	0x02
+#define QETH_QOAT_PHYS_MEDIA_FIBRE_LONG		0x04
+
+struct qeth_query_oat_physical_if {
+	u8 res_head[33];
+	u8 speed_duplex;
+	u8 media_type;
+	u8 res_tail[29];
+};
+
+#define QETH_QOAT_REPLY_TYPE_PHYS_IF		0x0004
+
+struct qeth_query_oat_reply {
+	u16 type;
+	u16 length;
+	u16 version;
+	u8 res[10];
+	struct qeth_query_oat_physical_if phys_if;
+};
+
+#define QETH_QOAT_SCOPE_INTERFACE		0x00000001
+
 struct qeth_query_oat {
-	__u32 subcmd_code;
-	__u8 reserved[12];
+	u32 subcmd_code;
+	u8 reserved[12];
+	struct qeth_query_oat_reply reply[];
 } __packed;
 
 struct qeth_qoat_priv {
-- 
2.17.1


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

* [PATCH net-next 9/9] s390/qeth: improve selection of ethtool link modes
  2020-11-17 16:15 [PATCH net-next 0/9] s390/qeth: updates 2020-11-17 Julian Wiedmann
                   ` (7 preceding siblings ...)
  2020-11-17 16:15 ` [PATCH net-next 8/9] s390/qeth: use QUERY OAT for initial link info Julian Wiedmann
@ 2020-11-17 16:15 ` Julian Wiedmann
  2020-11-19  1:35 ` [PATCH net-next 0/9] s390/qeth: updates 2020-11-17 Jakub Kicinski
  9 siblings, 0 replies; 13+ messages in thread
From: Julian Wiedmann @ 2020-11-17 16:15 UTC (permalink / raw)
  To: David Miller, Jakub Kicinski
  Cc: linux-netdev, linux-s390, Heiko Carstens, Karsten Graul, Julian Wiedmann

The link mode is a combination of port speed and port mode. But we
currently only consider the speed, and then typically select the
corresponding TP-based link mode. For 1G and 10G Fibre links this means
we display the wrong link modes.

Move the SPEED_* switch statements inside the PORT_* cases, and only
consider valid combinations where we can select the corresponding
link mode. Add the relevant link modes (1000baseX, 10000baseSR and
1000baseLR) that were introduced back with
commit 5711a9822144 ("net: ethtool: add support for 1000BaseX and missing 10G link modes").

To differentiate between 10000baseSR and 10000baseLR, use the detailed
media_type information that QUERY OAT provides.

Signed-off-by: Julian Wiedmann <jwi@linux.ibm.com>
---
 drivers/s390/net/qeth_core.h      |   7 ++
 drivers/s390/net/qeth_core_main.c |  11 +++
 drivers/s390/net/qeth_ethtool.c   | 124 ++++++++++++++++++------------
 3 files changed, 93 insertions(+), 49 deletions(-)

diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h
index c604e20a5e48..9e00917286a5 100644
--- a/drivers/s390/net/qeth_core.h
+++ b/drivers/s390/net/qeth_core.h
@@ -701,10 +701,17 @@ enum qeth_pnso_mode {
 	QETH_PNSO_ADDR_INFO,
 };
 
+enum qeth_link_mode {
+	QETH_LINK_MODE_UNKNOWN,
+	QETH_LINK_MODE_FIBRE_SHORT,
+	QETH_LINK_MODE_FIBRE_LONG,
+};
+
 struct qeth_link_info {
 	u32 speed;
 	u8 duplex;
 	u8 port;
+	enum qeth_link_mode link_mode;
 };
 
 #define QETH_BROADCAST_WITH_ECHO    0x01
diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c
index 57dad31aab4d..2752a585849d 100644
--- a/drivers/s390/net/qeth_core_main.c
+++ b/drivers/s390/net/qeth_core_main.c
@@ -5017,13 +5017,19 @@ static int qeth_init_link_info_oat_cb(struct qeth_card *card,
 	switch (phys_if->media_type) {
 	case QETH_QOAT_PHYS_MEDIA_COPPER:
 		link_info->port = PORT_TP;
+		link_info->link_mode = QETH_LINK_MODE_UNKNOWN;
 		break;
 	case QETH_QOAT_PHYS_MEDIA_FIBRE_SHORT:
+		link_info->port = PORT_FIBRE;
+		link_info->link_mode = QETH_LINK_MODE_FIBRE_SHORT;
+		break;
 	case QETH_QOAT_PHYS_MEDIA_FIBRE_LONG:
 		link_info->port = PORT_FIBRE;
+		link_info->link_mode = QETH_LINK_MODE_FIBRE_LONG;
 		break;
 	default:
 		link_info->port = PORT_OTHER;
+		link_info->link_mode = QETH_LINK_MODE_UNKNOWN;
 		break;
 	}
 
@@ -5037,6 +5043,7 @@ static void qeth_init_link_info(struct qeth_card *card)
 	if (IS_IQD(card) || IS_VM_NIC(card)) {
 		card->info.link_info.speed = SPEED_10000;
 		card->info.link_info.port = PORT_FIBRE;
+		card->info.link_info.link_mode = QETH_LINK_MODE_FIBRE_SHORT;
 	} else {
 		switch (card->info.link_type) {
 		case QETH_LINK_TYPE_FAST_ETH:
@@ -5063,6 +5070,8 @@ static void qeth_init_link_info(struct qeth_card *card)
 			card->info.link_info.speed = SPEED_UNKNOWN;
 			card->info.link_info.port = PORT_OTHER;
 		}
+
+		card->info.link_info.link_mode = QETH_LINK_MODE_UNKNOWN;
 	}
 
 	/* Get more accurate data via QUERY OAT: */
@@ -5088,6 +5097,8 @@ static void qeth_init_link_info(struct qeth_card *card)
 					card->info.link_info.duplex = link_info.duplex;
 				if (link_info.port != PORT_OTHER)
 					card->info.link_info.port = link_info.port;
+				if (link_info.link_mode != QETH_LINK_MODE_UNKNOWN)
+					card->info.link_info.link_mode = link_info.link_mode;
 			}
 		}
 	}
diff --git a/drivers/s390/net/qeth_ethtool.c b/drivers/s390/net/qeth_ethtool.c
index 50b0c1810850..3a51bbff0ffe 100644
--- a/drivers/s390/net/qeth_ethtool.c
+++ b/drivers/s390/net/qeth_ethtool.c
@@ -324,7 +324,8 @@ static int qeth_set_per_queue_coalesce(struct net_device *dev, u32 queue,
 /* 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_ethtool_link_modes(struct ethtool_link_ksettings *cmd)
+static void qeth_set_ethtool_link_modes(struct ethtool_link_ksettings *cmd,
+					enum qeth_link_mode link_mode)
 {
 	ethtool_link_ksettings_zero_link_mode(cmd, supported);
 	ethtool_link_ksettings_zero_link_mode(cmd, advertising);
@@ -337,58 +338,83 @@ static void qeth_set_ethtool_link_modes(struct ethtool_link_ksettings *cmd)
 	case PORT_TP:
 		ethtool_link_ksettings_add_link_mode(cmd, supported, TP);
 		ethtool_link_ksettings_add_link_mode(cmd, advertising, TP);
+
+		switch (cmd->base.speed) {
+		case SPEED_10000:
+			ethtool_link_ksettings_add_link_mode(cmd, supported,
+							     10000baseT_Full);
+			ethtool_link_ksettings_add_link_mode(cmd, advertising,
+							     10000baseT_Full);
+			fallthrough;
+		case SPEED_1000:
+			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);
+			fallthrough;
+		case SPEED_100:
+			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);
+			fallthrough;
+		case SPEED_10:
+			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);
+			break;
+		default:
+			break;
+		}
+
 		break;
 	case PORT_FIBRE:
 		ethtool_link_ksettings_add_link_mode(cmd, supported, FIBRE);
 		ethtool_link_ksettings_add_link_mode(cmd, advertising, FIBRE);
-		break;
-	default:
-		break;
-	}
 
-	/* partially does fall through, to also select lower speeds */
-	switch (cmd->base.speed) {
-	case SPEED_25000:
-		ethtool_link_ksettings_add_link_mode(cmd, supported,
-						     25000baseSR_Full);
-		ethtool_link_ksettings_add_link_mode(cmd, advertising,
-						     25000baseSR_Full);
-		break;
-	case SPEED_10000:
-		ethtool_link_ksettings_add_link_mode(cmd, supported,
-						     10000baseT_Full);
-		ethtool_link_ksettings_add_link_mode(cmd, advertising,
-						     10000baseT_Full);
-		fallthrough;
-	case SPEED_1000:
-		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);
-		fallthrough;
-	case SPEED_100:
-		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);
-		fallthrough;
-	case SPEED_10:
-		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);
+		switch (cmd->base.speed) {
+		case SPEED_25000:
+			ethtool_link_ksettings_add_link_mode(cmd, supported,
+							     25000baseSR_Full);
+			ethtool_link_ksettings_add_link_mode(cmd, advertising,
+							     25000baseSR_Full);
+			break;
+		case SPEED_10000:
+			if (link_mode == QETH_LINK_MODE_FIBRE_LONG) {
+				ethtool_link_ksettings_add_link_mode(cmd, supported,
+								     10000baseLR_Full);
+				ethtool_link_ksettings_add_link_mode(cmd, advertising,
+								     10000baseLR_Full);
+			} else if (link_mode == QETH_LINK_MODE_FIBRE_SHORT) {
+				ethtool_link_ksettings_add_link_mode(cmd, supported,
+								     10000baseSR_Full);
+				ethtool_link_ksettings_add_link_mode(cmd, advertising,
+								     10000baseSR_Full);
+			}
+			break;
+		case SPEED_1000:
+			ethtool_link_ksettings_add_link_mode(cmd, supported,
+							     1000baseX_Full);
+			ethtool_link_ksettings_add_link_mode(cmd, advertising,
+							     1000baseX_Full);
+			break;
+		default:
+			break;
+		}
+
 		break;
 	default:
 		break;
@@ -420,7 +446,7 @@ static int qeth_get_link_ksettings(struct net_device *netdev,
 			cmd->base.port = link_info.port;
 	}
 
-	qeth_set_ethtool_link_modes(cmd);
+	qeth_set_ethtool_link_modes(cmd, card->info.link_info.link_mode);
 
 	return 0;
 }
-- 
2.17.1


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

* Re: [PATCH net-next 0/9] s390/qeth: updates 2020-11-17
  2020-11-17 16:15 [PATCH net-next 0/9] s390/qeth: updates 2020-11-17 Julian Wiedmann
                   ` (8 preceding siblings ...)
  2020-11-17 16:15 ` [PATCH net-next 9/9] s390/qeth: improve selection of ethtool link modes Julian Wiedmann
@ 2020-11-19  1:35 ` Jakub Kicinski
  2020-11-19  9:25   ` Julian Wiedmann
  9 siblings, 1 reply; 13+ messages in thread
From: Jakub Kicinski @ 2020-11-19  1:35 UTC (permalink / raw)
  To: Julian Wiedmann
  Cc: David Miller, linux-netdev, linux-s390, Heiko Carstens, Karsten Graul

On Tue, 17 Nov 2020 17:15:11 +0100 Julian Wiedmann wrote:
> please apply the following patch series for qeth to netdev's net-next tree.
> 
> This brings some cleanups, and a bunch of improvements for our
> .get_link_ksettings() code.

Applied, thanks!

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

* Re: [PATCH net-next 0/9] s390/qeth: updates 2020-11-17
  2020-11-19  1:35 ` [PATCH net-next 0/9] s390/qeth: updates 2020-11-17 Jakub Kicinski
@ 2020-11-19  9:25   ` Julian Wiedmann
  2020-11-19 17:45     ` Jakub Kicinski
  0 siblings, 1 reply; 13+ messages in thread
From: Julian Wiedmann @ 2020-11-19  9:25 UTC (permalink / raw)
  To: Jakub Kicinski
  Cc: David Miller, linux-netdev, linux-s390, Heiko Carstens, Karsten Graul

On 19.11.20 03:35, Jakub Kicinski wrote:
> On Tue, 17 Nov 2020 17:15:11 +0100 Julian Wiedmann wrote:
>> please apply the following patch series for qeth to netdev's net-next tree.
>>
>> This brings some cleanups, and a bunch of improvements for our
>> .get_link_ksettings() code.
> 
> Applied, thanks!
> 

Thank you! Looks like you missed patch 1 in the series though... no biggie,
I'll resend it with the next batch of patches.

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

* Re: [PATCH net-next 0/9] s390/qeth: updates 2020-11-17
  2020-11-19  9:25   ` Julian Wiedmann
@ 2020-11-19 17:45     ` Jakub Kicinski
  0 siblings, 0 replies; 13+ messages in thread
From: Jakub Kicinski @ 2020-11-19 17:45 UTC (permalink / raw)
  To: Julian Wiedmann
  Cc: David Miller, linux-netdev, linux-s390, Heiko Carstens, Karsten Graul

On Thu, 19 Nov 2020 11:25:31 +0200 Julian Wiedmann wrote:
> On 19.11.20 03:35, Jakub Kicinski wrote:
> > On Tue, 17 Nov 2020 17:15:11 +0100 Julian Wiedmann wrote:  
> >> please apply the following patch series for qeth to netdev's net-next tree.
> >>
> >> This brings some cleanups, and a bunch of improvements for our
> >> .get_link_ksettings() code.  
> > 
> > Applied, thanks!
> >   
> 
> Thank you! Looks like you missed patch 1 in the series though... no biggie,
> I'll resend it with the next batch of patches.

Ahhh, sorry, somehow patchwork did not fold it into the same series, 
and I didn't notice:

https://patchwork.kernel.org/project/netdevbpf/list/?series=386125&state=*

Let me add a big fat warning to my scripts so this doesn't happen again.

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

end of thread, other threads:[~2020-11-19 17:46 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-11-17 16:15 [PATCH net-next 0/9] s390/qeth: updates 2020-11-17 Julian Wiedmann
2020-11-17 16:15 ` [PATCH net-next 1/9] s390/qeth: don't call INIT_LIST_HEAD() on iob's list entry Julian Wiedmann
2020-11-17 16:15 ` [PATCH net-next 2/9] s390/qeth: reduce rtnl locking for switchdev events Julian Wiedmann
2020-11-17 16:15 ` [PATCH net-next 3/9] s390/qeth: remove useless if/else Julian Wiedmann
2020-11-17 16:15 ` [PATCH net-next 4/9] s390/qeth: tolerate error when querying card info Julian Wiedmann
2020-11-17 16:15 ` [PATCH net-next 5/9] s390/qeth: improve QUERY CARD INFO processing Julian Wiedmann
2020-11-17 16:15 ` [PATCH net-next 6/9] s390/qeth: set static link info during initialization Julian Wiedmann
2020-11-17 16:15 ` [PATCH net-next 7/9] s390/qeth: clean up default cases for ethtool link mode Julian Wiedmann
2020-11-17 16:15 ` [PATCH net-next 8/9] s390/qeth: use QUERY OAT for initial link info Julian Wiedmann
2020-11-17 16:15 ` [PATCH net-next 9/9] s390/qeth: improve selection of ethtool link modes Julian Wiedmann
2020-11-19  1:35 ` [PATCH net-next 0/9] s390/qeth: updates 2020-11-17 Jakub Kicinski
2020-11-19  9:25   ` Julian Wiedmann
2020-11-19 17:45     ` Jakub Kicinski

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).