Commit 1d4e4ecc authored by Alexander Lobakin's avatar Alexander Lobakin Committed by David S. Miller

qede: populate supported link modes maps on module init

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: default avatarAlexander Lobakin <alobakin@marvell.com>
Signed-off-by: default avatarIgor Russkikh <irusskikh@marvell.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent bdb5d8ec
...@@ -557,6 +557,8 @@ void qede_update_rx_prod(struct qede_dev *edev, struct qede_rx_queue *rxq); ...@@ -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, int qede_add_tc_flower_fltr(struct qede_dev *edev, __be16 proto,
struct flow_cls_offload *f); struct flow_cls_offload *f);
void qede_forced_speed_maps_init(void);
#define RX_RING_SIZE_POW 13 #define RX_RING_SIZE_POW 13
#define RX_RING_SIZE ((u16)BIT(RX_RING_SIZE_POW)) #define RX_RING_SIZE ((u16)BIT(RX_RING_SIZE_POW))
#define NUM_RX_BDS_MAX (RX_RING_SIZE - 1) #define NUM_RX_BDS_MAX (RX_RING_SIZE - 1)
......
...@@ -196,6 +196,96 @@ static const char qede_tests_str_arr[QEDE_ETHTOOL_TEST_MAX][ETH_GSTRING_LEN] = { ...@@ -196,6 +196,96 @@ static const char qede_tests_str_arr[QEDE_ETHTOOL_TEST_MAX][ETH_GSTRING_LEN] = {
"Nvram (online)\t\t", "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, static void qede_get_strings_stats_txq(struct qede_dev *edev,
struct qede_tx_queue *txq, u8 **buf) struct qede_tx_queue *txq, u8 **buf)
{ {
...@@ -458,10 +548,11 @@ static int qede_set_link_ksettings(struct net_device *dev, ...@@ -458,10 +548,11 @@ static int qede_set_link_ksettings(struct net_device *dev,
const struct ethtool_link_ksettings *cmd) const struct ethtool_link_ksettings *cmd)
{ {
const struct ethtool_link_settings *base = &cmd->base; const struct ethtool_link_settings *base = &cmd->base;
__ETHTOOL_DECLARE_LINK_MODE_MASK(sup_caps);
struct qede_dev *edev = netdev_priv(dev); struct qede_dev *edev = netdev_priv(dev);
const struct qede_forced_speed_map *map;
struct qed_link_output current_link; struct qed_link_output current_link;
struct qed_link_params params; struct qed_link_params params;
u32 i;
if (!edev->ops || !edev->ops->common->can_link_change(edev->cdev)) { if (!edev->ops || !edev->ops->common->can_link_change(edev->cdev)) {
DP_INFO(edev, "Link settings are not allowed to be changed\n"); 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, ...@@ -489,65 +580,24 @@ static int qede_set_link_ksettings(struct net_device *dev,
params.autoneg = false; params.autoneg = false;
params.forced_speed = base->speed; 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) { if (base->speed != map->speed ||
case SPEED_1000: !linkmode_intersects(current_link.supported_caps,
phylink_set(sup_caps, 1000baseT_Full); map->caps))
phylink_set(sup_caps, 1000baseKX_Full); continue;
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 (!linkmode_intersects(current_link.supported_caps, linkmode_and(params.adv_speeds,
sup_caps)) { current_link.supported_caps, map->caps);
DP_INFO(edev, "%uG speed not supported\n", goto set_link;
base->speed / 1000);
return -EINVAL;
} }
linkmode_and(params.adv_speeds, current_link.supported_caps, DP_INFO(edev, "Unsupported speed %u\n", base->speed);
sup_caps); return -EINVAL;
} }
set_link:
params.link_up = true; params.link_up = true;
edev->ops->common->set_link(edev->cdev, &params); edev->ops->common->set_link(edev->cdev, &params);
......
...@@ -263,6 +263,8 @@ int __init qede_init(void) ...@@ -263,6 +263,8 @@ int __init qede_init(void)
pr_info("qede_init: %s\n", version); pr_info("qede_init: %s\n", version);
qede_forced_speed_maps_init();
qed_ops = qed_get_eth_ops(); qed_ops = qed_get_eth_ops();
if (!qed_ops) { if (!qed_ops) {
pr_notice("Failed to get qed ethtool operations\n"); pr_notice("Failed to get qed ethtool operations\n");
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment