Simplify and lighten qede_set_link_ksettings() by declaring static link
modes maps and populating them on module init. This way we save plenty
of text size at the low expense of __ro_after_init and __initconst data
(the latter will be purged after module init is done).

Signed-off-by: Alexander Lobakin <aloba...@marvell.com>
Signed-off-by: Igor Russkikh <irussk...@marvell.com>
---
 drivers/net/ethernet/qlogic/qede/qede.h       |   2 +
 .../net/ethernet/qlogic/qede/qede_ethtool.c   | 158 ++++++++++++------
 drivers/net/ethernet/qlogic/qede/qede_main.c  |   2 +
 3 files changed, 108 insertions(+), 54 deletions(-)

diff --git a/drivers/net/ethernet/qlogic/qede/qede.h 
b/drivers/net/ethernet/qlogic/qede/qede.h
index 8adda5dc9e88..f1d7f73de902 100644
--- a/drivers/net/ethernet/qlogic/qede/qede.h
+++ b/drivers/net/ethernet/qlogic/qede/qede.h
@@ -557,6 +557,8 @@ void qede_update_rx_prod(struct qede_dev *edev, struct 
qede_rx_queue *rxq);
 int qede_add_tc_flower_fltr(struct qede_dev *edev, __be16 proto,
                            struct flow_cls_offload *f);
 
+void qede_forced_speed_maps_init(void);
+
 #define RX_RING_SIZE_POW       13
 #define RX_RING_SIZE           ((u16)BIT(RX_RING_SIZE_POW))
 #define NUM_RX_BDS_MAX         (RX_RING_SIZE - 1)
diff --git a/drivers/net/ethernet/qlogic/qede/qede_ethtool.c 
b/drivers/net/ethernet/qlogic/qede/qede_ethtool.c
index 0a564b06d697..7a985307cdd5 100644
--- a/drivers/net/ethernet/qlogic/qede/qede_ethtool.c
+++ b/drivers/net/ethernet/qlogic/qede/qede_ethtool.c
@@ -196,6 +196,96 @@ static const char 
qede_tests_str_arr[QEDE_ETHTOOL_TEST_MAX][ETH_GSTRING_LEN] = {
        "Nvram (online)\t\t",
 };
 
+/* Forced speed capabilities maps */
+
+struct qede_forced_speed_map {
+       u32             speed;
+       __ETHTOOL_DECLARE_LINK_MODE_MASK(caps);
+
+       const u32       *cap_arr;
+       u32             arr_size;
+};
+
+#define QEDE_FORCED_SPEED_MAP(value)                                   \
+{                                                                      \
+       .speed          = SPEED_##value,                                \
+       .cap_arr        = qede_forced_speed_##value,                    \
+       .arr_size       = ARRAY_SIZE(qede_forced_speed_##value),        \
+}
+
+static const u32 qede_forced_speed_1000[] __initconst = {
+       ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
+       ETHTOOL_LINK_MODE_1000baseKX_Full_BIT,
+       ETHTOOL_LINK_MODE_1000baseX_Full_BIT,
+};
+
+static const u32 qede_forced_speed_10000[] __initconst = {
+       ETHTOOL_LINK_MODE_10000baseT_Full_BIT,
+       ETHTOOL_LINK_MODE_10000baseKR_Full_BIT,
+       ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT,
+       ETHTOOL_LINK_MODE_10000baseR_FEC_BIT,
+       ETHTOOL_LINK_MODE_10000baseCR_Full_BIT,
+       ETHTOOL_LINK_MODE_10000baseSR_Full_BIT,
+       ETHTOOL_LINK_MODE_10000baseLR_Full_BIT,
+       ETHTOOL_LINK_MODE_10000baseLRM_Full_BIT,
+};
+
+static const u32 qede_forced_speed_20000[] __initconst = {
+       ETHTOOL_LINK_MODE_20000baseKR2_Full_BIT,
+};
+
+static const u32 qede_forced_speed_25000[] __initconst = {
+       ETHTOOL_LINK_MODE_25000baseKR_Full_BIT,
+       ETHTOOL_LINK_MODE_25000baseCR_Full_BIT,
+       ETHTOOL_LINK_MODE_25000baseSR_Full_BIT,
+};
+
+static const u32 qede_forced_speed_40000[] __initconst = {
+       ETHTOOL_LINK_MODE_40000baseLR4_Full_BIT,
+       ETHTOOL_LINK_MODE_40000baseKR4_Full_BIT,
+       ETHTOOL_LINK_MODE_40000baseCR4_Full_BIT,
+       ETHTOOL_LINK_MODE_40000baseSR4_Full_BIT,
+};
+
+static const u32 qede_forced_speed_50000[] __initconst = {
+       ETHTOOL_LINK_MODE_50000baseKR2_Full_BIT,
+       ETHTOOL_LINK_MODE_50000baseCR2_Full_BIT,
+       ETHTOOL_LINK_MODE_50000baseSR2_Full_BIT,
+};
+
+static const u32 qede_forced_speed_100000[] __initconst = {
+       ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT,
+       ETHTOOL_LINK_MODE_100000baseSR4_Full_BIT,
+       ETHTOOL_LINK_MODE_100000baseCR4_Full_BIT,
+       ETHTOOL_LINK_MODE_100000baseLR4_ER4_Full_BIT,
+};
+
+static struct qede_forced_speed_map qede_forced_speed_maps[] __ro_after_init = 
{
+       QEDE_FORCED_SPEED_MAP(1000),
+       QEDE_FORCED_SPEED_MAP(10000),
+       QEDE_FORCED_SPEED_MAP(20000),
+       QEDE_FORCED_SPEED_MAP(25000),
+       QEDE_FORCED_SPEED_MAP(40000),
+       QEDE_FORCED_SPEED_MAP(50000),
+       QEDE_FORCED_SPEED_MAP(100000),
+};
+
+void __init qede_forced_speed_maps_init(void)
+{
+       struct qede_forced_speed_map *map;
+       u32 i;
+
+       for (i = 0; i < ARRAY_SIZE(qede_forced_speed_maps); i++) {
+               map = qede_forced_speed_maps + i;
+
+               linkmode_set_bit_array(map->cap_arr, map->arr_size, map->caps);
+               map->cap_arr = NULL;
+               map->arr_size = 0;
+       }
+}
+
+/* Ethtool callbacks */
+
 static void qede_get_strings_stats_txq(struct qede_dev *edev,
                                       struct qede_tx_queue *txq, u8 **buf)
 {
@@ -458,10 +548,11 @@ static int qede_set_link_ksettings(struct net_device *dev,
                                   const struct ethtool_link_ksettings *cmd)
 {
        const struct ethtool_link_settings *base = &cmd->base;
-       __ETHTOOL_DECLARE_LINK_MODE_MASK(sup_caps);
        struct qede_dev *edev = netdev_priv(dev);
+       const struct qede_forced_speed_map *map;
        struct qed_link_output current_link;
        struct qed_link_params params;
+       u32 i;
 
        if (!edev->ops || !edev->ops->common->can_link_change(edev->cdev)) {
                DP_INFO(edev, "Link settings are not allowed to be changed\n");
@@ -489,65 +580,24 @@ static int qede_set_link_ksettings(struct net_device *dev,
                params.autoneg = false;
                params.forced_speed = base->speed;
 
-               phylink_zero(sup_caps);
+               for (i = 0; i < ARRAY_SIZE(qede_forced_speed_maps); i++) {
+                       map = qede_forced_speed_maps + i;
 
-               switch (base->speed) {
-               case SPEED_1000:
-                       phylink_set(sup_caps, 1000baseT_Full);
-                       phylink_set(sup_caps, 1000baseKX_Full);
-                       phylink_set(sup_caps, 1000baseX_Full);
-                       break;
-               case SPEED_10000:
-                       phylink_set(sup_caps, 10000baseT_Full);
-                       phylink_set(sup_caps, 10000baseKR_Full);
-                       phylink_set(sup_caps, 10000baseKX4_Full);
-                       phylink_set(sup_caps, 10000baseR_FEC);
-                       phylink_set(sup_caps, 10000baseCR_Full);
-                       phylink_set(sup_caps, 10000baseSR_Full);
-                       phylink_set(sup_caps, 10000baseLR_Full);
-                       phylink_set(sup_caps, 10000baseLRM_Full);
-                       break;
-               case SPEED_20000:
-                       phylink_set(sup_caps, 20000baseKR2_Full);
-                       break;
-               case SPEED_25000:
-                       phylink_set(sup_caps, 25000baseKR_Full);
-                       phylink_set(sup_caps, 25000baseCR_Full);
-                       phylink_set(sup_caps, 25000baseSR_Full);
-                       break;
-               case SPEED_40000:
-                       phylink_set(sup_caps, 40000baseLR4_Full);
-                       phylink_set(sup_caps, 40000baseKR4_Full);
-                       phylink_set(sup_caps, 40000baseCR4_Full);
-                       phylink_set(sup_caps, 40000baseSR4_Full);
-                       break;
-               case SPEED_50000:
-                       phylink_set(sup_caps, 50000baseKR2_Full);
-                       phylink_set(sup_caps, 50000baseCR2_Full);
-                       phylink_set(sup_caps, 50000baseSR2_Full);
-                       break;
-               case SPEED_100000:
-                       phylink_set(sup_caps, 100000baseKR4_Full);
-                       phylink_set(sup_caps, 100000baseSR4_Full);
-                       phylink_set(sup_caps, 100000baseCR4_Full);
-                       phylink_set(sup_caps, 100000baseLR4_ER4_Full);
-                       break;
-               default:
-                       DP_INFO(edev, "Unsupported speed %u\n", base->speed);
-                       return -EINVAL;
-               }
+                       if (base->speed != map->speed ||
+                           !linkmode_intersects(current_link.supported_caps,
+                                                map->caps))
+                               continue;
 
-               if (!linkmode_intersects(current_link.supported_caps,
-                                        sup_caps)) {
-                       DP_INFO(edev, "%uG speed not supported\n",
-                               base->speed / 1000);
-                       return -EINVAL;
+                       linkmode_and(params.adv_speeds,
+                                    current_link.supported_caps, map->caps);
+                       goto set_link;
                }
 
-               linkmode_and(params.adv_speeds, current_link.supported_caps,
-                            sup_caps);
+               DP_INFO(edev, "Unsupported speed %u\n", base->speed);
+               return -EINVAL;
        }
 
+set_link:
        params.link_up = true;
        edev->ops->common->set_link(edev->cdev, &params);
 
diff --git a/drivers/net/ethernet/qlogic/qede/qede_main.c 
b/drivers/net/ethernet/qlogic/qede/qede_main.c
index a653dd0e5c22..6f2171dc0dea 100644
--- a/drivers/net/ethernet/qlogic/qede/qede_main.c
+++ b/drivers/net/ethernet/qlogic/qede/qede_main.c
@@ -263,6 +263,8 @@ int __init qede_init(void)
 
        pr_info("qede_init: %s\n", version);
 
+       qede_forced_speed_maps_init();
+
        qed_ops = qed_get_eth_ops();
        if (!qed_ops) {
                pr_notice("Failed to get qed ethtool operations\n");
-- 
2.25.1

Reply via email to