* [dpdk-dev] [PATCH 1/3] net/cxgbe: remove legacy 16-bit link capabilities
2020-12-20 22:47 [dpdk-dev] [PATCH 0/3] net/cxgbe: rework link config and add FEC support Rahul Lakkireddy
@ 2020-12-20 22:47 ` Rahul Lakkireddy
2020-12-20 22:47 ` [dpdk-dev] [PATCH 2/3] net/cxgbe: rework and simplify link handling code Rahul Lakkireddy
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Rahul Lakkireddy @ 2020-12-20 22:47 UTC (permalink / raw)
To: dev; +Cc: kaara.satwik
From: Karra Satwik <kaara.satwik@chelsio.com>
Remove legacy 16-bit link capabilities and always request for the
32-bit link capabilities from firmware.
Signed-off-by: Karra Satwik <kaara.satwik@chelsio.com>
Signed-off-by: Rahul Lakkireddy <rahul.lakkireddy@chelsio.com>
---
doc/guides/nics/cxgbe.rst | 14 +-
drivers/net/cxgbe/base/common.h | 9 -
drivers/net/cxgbe/base/t4_hw.c | 233 +++++-------------------
drivers/net/cxgbe/base/t4fw_interface.h | 70 +------
drivers/net/cxgbe/base/t4vf_hw.c | 79 +++-----
5 files changed, 78 insertions(+), 327 deletions(-)
diff --git a/doc/guides/nics/cxgbe.rst b/doc/guides/nics/cxgbe.rst
index f01cd6560..4b9913669 100644
--- a/doc/guides/nics/cxgbe.rst
+++ b/doc/guides/nics/cxgbe.rst
@@ -70,7 +70,7 @@ in :ref:`t5-nics` and :ref:`t6-nics`.
Prerequisites
-------------
-- Requires firmware version **1.24.11.0** and higher. Visit
+- Requires firmware version **1.24.17.0** and higher. Visit
`Chelsio Download Center <http://service.chelsio.com>`_ to get latest firmware
bundled with the latest Chelsio Unified Wire package.
@@ -404,7 +404,7 @@ Unified Wire package for Linux operating system are as follows:
.. code-block:: console
- firmware-version: 1.24.11.0, TP 0.1.23.2
+ firmware-version: 1.24.17.0, TP 0.1.23.2
Running testpmd
~~~~~~~~~~~~~~~
@@ -462,7 +462,7 @@ devices managed by librte_net_cxgbe in Linux operating system.
EAL: PCI memory mapped at 0x7fd7c0200000
EAL: PCI memory mapped at 0x7fd77cdfd000
EAL: PCI memory mapped at 0x7fd7c10b7000
- PMD: rte_cxgbe_pmd: fw: 1.24.11.0, TP: 0.1.23.2
+ PMD: rte_cxgbe_pmd: fw: 1.24.17.0, TP: 0.1.23.2
PMD: rte_cxgbe_pmd: Coming up as MASTER: Initializing adapter
Interactive-mode selected
Configuring Port 0 (socket 0)
@@ -568,7 +568,7 @@ virtual functions.
[...]
EAL: PCI device 0000:02:01.0 on NUMA socket 0
EAL: probe driver: 1425:5803 net_cxgbevf
- PMD: rte_cxgbe_pmd: Firmware version: 1.24.11.0
+ PMD: rte_cxgbe_pmd: Firmware version: 1.24.17.0
PMD: rte_cxgbe_pmd: TP Microcode version: 0.1.23.2
PMD: rte_cxgbe_pmd: Chelsio rev 0
PMD: rte_cxgbe_pmd: No bootstrap loaded
@@ -576,7 +576,7 @@ virtual functions.
PMD: rte_cxgbe_pmd: 0000:02:01.0 Chelsio rev 0 1G/10GBASE-SFP
EAL: PCI device 0000:02:01.1 on NUMA socket 0
EAL: probe driver: 1425:5803 net_cxgbevf
- PMD: rte_cxgbe_pmd: Firmware version: 1.24.11.0
+ PMD: rte_cxgbe_pmd: Firmware version: 1.24.17.0
PMD: rte_cxgbe_pmd: TP Microcode version: 0.1.23.2
PMD: rte_cxgbe_pmd: Chelsio rev 0
PMD: rte_cxgbe_pmd: No bootstrap loaded
@@ -654,7 +654,7 @@ Unified Wire package for FreeBSD operating system are as follows:
.. code-block:: console
- dev.t5nex.0.firmware_version: 1.24.11.0
+ dev.t5nex.0.firmware_version: 1.24.17.0
Running testpmd
~~~~~~~~~~~~~~~
@@ -772,7 +772,7 @@ devices managed by librte_net_cxgbe in FreeBSD operating system.
EAL: PCI memory mapped at 0x8007ec000
EAL: PCI memory mapped at 0x842800000
EAL: PCI memory mapped at 0x80086c000
- PMD: rte_cxgbe_pmd: fw: 1.24.11.0, TP: 0.1.23.2
+ PMD: rte_cxgbe_pmd: fw: 1.24.17.0, TP: 0.1.23.2
PMD: rte_cxgbe_pmd: Coming up as MASTER: Initializing adapter
Interactive-mode selected
Configuring Port 0 (socket 0)
diff --git a/drivers/net/cxgbe/base/common.h b/drivers/net/cxgbe/base/common.h
index 8fe8e2a36..86f3dc80b 100644
--- a/drivers/net/cxgbe/base/common.h
+++ b/drivers/net/cxgbe/base/common.h
@@ -274,7 +274,6 @@ struct adapter_params {
struct arch_specific_params arch; /* chip specific params */
bool ulptx_memwrite_dsgl; /* use of T5 DSGL allowed */
- u8 fw_caps_support; /* 32-bit Port Capabilities */
u8 filter2_wr_support; /* FW support for FILTER2_WR */
u32 viid_smt_extn_support:1; /* FW returns vin and smt index */
u32 max_tx_coalesce_num; /* Max # of Tx packets that can be coalesced */
@@ -282,15 +281,8 @@ struct adapter_params {
/* Firmware Port Capabilities types.
*/
-typedef u16 fw_port_cap16_t; /* 16-bit Port Capabilities integral value */
typedef u32 fw_port_cap32_t; /* 32-bit Port Capabilities integral value */
-enum fw_caps {
- FW_CAPS_UNKNOWN = 0, /* 0'ed out initial state */
- FW_CAPS16 = 1, /* old Firmware: 16-bit Port Capabilities */
- FW_CAPS32 = 2, /* new Firmware: 32-bit Port Capabilities */
-};
-
struct link_config {
fw_port_cap32_t pcaps; /* link capabilities */
fw_port_cap32_t acaps; /* advertised capabilities */
@@ -552,5 +544,4 @@ static inline int t4_memory_rw(struct adapter *adap, int win,
{
return t4_memory_rw_mtype(adap, win, mtype, maddr, len, hbuf, dir);
}
-fw_port_cap32_t fwcaps16_to_caps32(fw_port_cap16_t caps16);
#endif /* __CHELSIO_COMMON_H */
diff --git a/drivers/net/cxgbe/base/t4_hw.c b/drivers/net/cxgbe/base/t4_hw.c
index 9217956b4..44227740c 100644
--- a/drivers/net/cxgbe/base/t4_hw.c
+++ b/drivers/net/cxgbe/base/t4_hw.c
@@ -2811,81 +2811,6 @@ void t4_dump_version_info(struct adapter *adapter)
#define ADVERT_MASK (V_FW_PORT_CAP32_SPEED(M_FW_PORT_CAP32_SPEED) | \
FW_PORT_CAP32_ANEG)
-/**
- * fwcaps16_to_caps32 - convert 16-bit Port Capabilities to 32-bits
- * @caps16: a 16-bit Port Capabilities value
- *
- * Returns the equivalent 32-bit Port Capabilities value.
- */
-fw_port_cap32_t fwcaps16_to_caps32(fw_port_cap16_t caps16)
-{
- fw_port_cap32_t caps32 = 0;
-
-#define CAP16_TO_CAP32(__cap) \
- do { \
- if (caps16 & FW_PORT_CAP_##__cap) \
- caps32 |= FW_PORT_CAP32_##__cap; \
- } while (0)
-
- CAP16_TO_CAP32(SPEED_100M);
- CAP16_TO_CAP32(SPEED_1G);
- CAP16_TO_CAP32(SPEED_25G);
- CAP16_TO_CAP32(SPEED_10G);
- CAP16_TO_CAP32(SPEED_40G);
- CAP16_TO_CAP32(SPEED_100G);
- CAP16_TO_CAP32(FC_RX);
- CAP16_TO_CAP32(FC_TX);
- CAP16_TO_CAP32(ANEG);
- CAP16_TO_CAP32(MDIX);
- CAP16_TO_CAP32(MDIAUTO);
- CAP16_TO_CAP32(FEC_RS);
- CAP16_TO_CAP32(FEC_BASER_RS);
- CAP16_TO_CAP32(802_3_PAUSE);
- CAP16_TO_CAP32(802_3_ASM_DIR);
-
-#undef CAP16_TO_CAP32
-
- return caps32;
-}
-
-/**
- * fwcaps32_to_caps16 - convert 32-bit Port Capabilities to 16-bits
- * @caps32: a 32-bit Port Capabilities value
- *
- * Returns the equivalent 16-bit Port Capabilities value. Note that
- * not all 32-bit Port Capabilities can be represented in the 16-bit
- * Port Capabilities and some fields/values may not make it.
- */
-static fw_port_cap16_t fwcaps32_to_caps16(fw_port_cap32_t caps32)
-{
- fw_port_cap16_t caps16 = 0;
-
-#define CAP32_TO_CAP16(__cap) \
- do { \
- if (caps32 & FW_PORT_CAP32_##__cap) \
- caps16 |= FW_PORT_CAP_##__cap; \
- } while (0)
-
- CAP32_TO_CAP16(SPEED_100M);
- CAP32_TO_CAP16(SPEED_1G);
- CAP32_TO_CAP16(SPEED_10G);
- CAP32_TO_CAP16(SPEED_25G);
- CAP32_TO_CAP16(SPEED_40G);
- CAP32_TO_CAP16(SPEED_100G);
- CAP32_TO_CAP16(FC_RX);
- CAP32_TO_CAP16(FC_TX);
- CAP32_TO_CAP16(802_3_PAUSE);
- CAP32_TO_CAP16(802_3_ASM_DIR);
- CAP32_TO_CAP16(ANEG);
- CAP32_TO_CAP16(MDIX);
- CAP32_TO_CAP16(MDIAUTO);
- CAP32_TO_CAP16(FEC_RS);
- CAP32_TO_CAP16(FEC_BASER_RS);
-
-#undef CAP32_TO_CAP16
-
- return caps16;
-}
/* Translate Firmware Pause specification to Common Code */
static inline enum cc_pause fwcap_to_cc_pause(fw_port_cap32_t fw_pause)
@@ -2957,7 +2882,6 @@ int t4_link_l1cfg(struct adapter *adap, unsigned int mbox, unsigned int port,
struct link_config *lc)
{
unsigned int fw_mdi = V_FW_PORT_CAP32_MDI(FW_PORT_CAP32_MDI_AUTO);
- unsigned int fw_caps = adap->params.fw_caps_support;
fw_port_cap32_t fw_fc, cc_fec, fw_fec, rcap;
struct fw_port_cmd cmd;
@@ -2999,15 +2923,10 @@ int t4_link_l1cfg(struct adapter *adap, unsigned int mbox, unsigned int port,
F_FW_CMD_REQUEST | F_FW_CMD_EXEC |
V_FW_PORT_CMD_PORTID(port));
cmd.action_to_len16 =
- cpu_to_be32(V_FW_PORT_CMD_ACTION(fw_caps == FW_CAPS16 ?
- FW_PORT_ACTION_L1_CFG :
- FW_PORT_ACTION_L1_CFG32) |
+ cpu_to_be32(V_FW_PORT_CMD_ACTION(FW_PORT_ACTION_L1_CFG32) |
FW_LEN16(cmd));
- if (fw_caps == FW_CAPS16)
- cmd.u.l1cfg.rcap = cpu_to_be32(fwcaps32_to_caps16(rcap));
- else
- cmd.u.l1cfg32.rcap32 = cpu_to_be32(rcap);
+ cmd.u.l1cfg32.rcap32 = cpu_to_be32(rcap);
return t4_wr_mbox(adap, mbox, &cmd, sizeof(cmd), NULL);
}
@@ -4539,73 +4458,31 @@ static unsigned int fwcap_to_speed(fw_port_cap32_t caps)
static void t4_handle_get_port_info(struct port_info *pi, const __be64 *rpl)
{
const struct fw_port_cmd *cmd = (const void *)rpl;
- int action = G_FW_PORT_CMD_ACTION(be32_to_cpu(cmd->action_to_len16));
- fw_port_cap32_t pcaps, acaps, linkattr;
+ u8 link_ok, link_down_rc, mod_type, port_type;
+ u32 action, pcaps, acaps, linkattr, lstatus;
struct link_config *lc = &pi->link_cfg;
struct adapter *adapter = pi->adapter;
- enum fw_port_module_type mod_type;
- enum fw_port_type port_type;
unsigned int speed, fc, fec;
- int link_ok, linkdnrc;
/* Extract the various fields from the Port Information message.
*/
- switch (action) {
- case FW_PORT_ACTION_GET_PORT_INFO: {
- u32 lstatus = be32_to_cpu(cmd->u.info.lstatus_to_modtype);
-
- link_ok = (lstatus & F_FW_PORT_CMD_LSTATUS) != 0;
- linkdnrc = G_FW_PORT_CMD_LINKDNRC(lstatus);
- port_type = G_FW_PORT_CMD_PTYPE(lstatus);
- mod_type = G_FW_PORT_CMD_MODTYPE(lstatus);
- pcaps = fwcaps16_to_caps32(be16_to_cpu(cmd->u.info.pcap));
- acaps = fwcaps16_to_caps32(be16_to_cpu(cmd->u.info.acap));
-
- /* Unfortunately the format of the Link Status in the old
- * 16-bit Port Information message isn't the same as the
- * 16-bit Port Capabilities bitfield used everywhere else ...
- */
- linkattr = 0;
- if (lstatus & F_FW_PORT_CMD_RXPAUSE)
- linkattr |= FW_PORT_CAP32_FC_RX;
- if (lstatus & F_FW_PORT_CMD_TXPAUSE)
- linkattr |= FW_PORT_CAP32_FC_TX;
- if (lstatus & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_100M))
- linkattr |= FW_PORT_CAP32_SPEED_100M;
- if (lstatus & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_1G))
- linkattr |= FW_PORT_CAP32_SPEED_1G;
- if (lstatus & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_10G))
- linkattr |= FW_PORT_CAP32_SPEED_10G;
- if (lstatus & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_25G))
- linkattr |= FW_PORT_CAP32_SPEED_25G;
- if (lstatus & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_40G))
- linkattr |= FW_PORT_CAP32_SPEED_40G;
- if (lstatus & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_100G))
- linkattr |= FW_PORT_CAP32_SPEED_100G;
-
- break;
- }
-
- case FW_PORT_ACTION_GET_PORT_INFO32: {
- u32 lstatus32 =
- be32_to_cpu(cmd->u.info32.lstatus32_to_cbllen32);
-
- link_ok = (lstatus32 & F_FW_PORT_CMD_LSTATUS32) != 0;
- linkdnrc = G_FW_PORT_CMD_LINKDNRC32(lstatus32);
- port_type = G_FW_PORT_CMD_PORTTYPE32(lstatus32);
- mod_type = G_FW_PORT_CMD_MODTYPE32(lstatus32);
- pcaps = be32_to_cpu(cmd->u.info32.pcaps32);
- acaps = be32_to_cpu(cmd->u.info32.acaps32);
- linkattr = be32_to_cpu(cmd->u.info32.linkattr32);
- break;
- }
-
- default:
+ action = be32_to_cpu(cmd->action_to_len16);
+ if (G_FW_PORT_CMD_ACTION(action) != FW_PORT_ACTION_GET_PORT_INFO32) {
dev_warn(adapter, "Handle Port Information: Bad Command/Action %#x\n",
- be32_to_cpu(cmd->action_to_len16));
+ action);
return;
}
+ lstatus = be32_to_cpu(cmd->u.info32.lstatus32_to_cbllen32);
+ link_ok = (lstatus & F_FW_PORT_CMD_LSTATUS32) ? 1 : 0;
+ link_down_rc = G_FW_PORT_CMD_LINKDNRC32(lstatus);
+ port_type = G_FW_PORT_CMD_PORTTYPE32(lstatus);
+ mod_type = G_FW_PORT_CMD_MODTYPE32(lstatus);
+
+ pcaps = be32_to_cpu(cmd->u.info32.pcaps32);
+ acaps = be32_to_cpu(cmd->u.info32.acaps32);
+ linkattr = be32_to_cpu(cmd->u.info32.linkattr32);
+
fec = fwcap_to_cc_fec(acaps);
fc = fwcap_to_cc_pause(linkattr);
@@ -4620,9 +4497,10 @@ static void t4_handle_get_port_info(struct port_info *pi, const __be64 *rpl)
if (link_ok != lc->link_ok || speed != lc->speed ||
fc != lc->fc || fec != lc->fec) { /* something changed */
if (!link_ok && lc->link_ok) {
- lc->link_down_rc = linkdnrc;
+ lc->link_down_rc = link_down_rc;
dev_warn(adap, "Port %d link down, reason: %s\n",
- pi->tx_chan, t4_link_down_rc_str(linkdnrc));
+ pi->port_id,
+ t4_link_down_rc_str(link_down_rc));
}
lc->link_ok = link_ok;
lc->speed = speed;
@@ -4691,9 +4569,7 @@ int t4_handle_fw_rpl(struct adapter *adap, const __be64 *rpl)
unsigned int action =
G_FW_PORT_CMD_ACTION(be32_to_cpu(p->action_to_len16));
- if (opcode == FW_PORT_CMD &&
- (action == FW_PORT_ACTION_GET_PORT_INFO ||
- action == FW_PORT_ACTION_GET_PORT_INFO32)) {
+ if (opcode == FW_PORT_CMD && action == FW_PORT_ACTION_GET_PORT_INFO32) {
/* link/module state change message */
int chan = G_FW_PORT_CMD_PORTID(be32_to_cpu(p->op_to_portid));
struct port_info *pi = NULL;
@@ -5395,81 +5271,54 @@ int t4_init_rss_mode(struct adapter *adap, int mbox)
int t4_port_init(struct adapter *adap, int mbox, int pf, int vf)
{
- unsigned int fw_caps = adap->params.fw_caps_support;
fw_port_cap32_t pcaps, acaps;
enum fw_port_type port_type;
struct fw_port_cmd cmd;
u8 vivld = 0, vin = 0;
int ret, i, j = 0;
+ u32 param, val;
int mdio_addr;
- u32 action;
u8 addr[6];
+ param = (V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_PFVF) |
+ V_FW_PARAMS_PARAM_X(FW_PARAMS_PARAM_PFVF_PORT_CAPS32));
+ val = 1;
+ ret = t4_set_params(adap, mbox, pf, vf, 1, ¶m, &val);
+ if (ret < 0)
+ return ret;
+
memset(&cmd, 0, sizeof(cmd));
for_each_port(adap, i) {
struct port_info *pi = adap2pinfo(adap, i);
unsigned int rss_size = 0;
+ u32 lstatus32;
while ((adap->params.portvec & (1 << j)) == 0)
j++;
- /* If we haven't yet determined whether we're talking to
- * Firmware which knows the new 32-bit Port Capabilities, it's
- * time to find out now. This will also tell new Firmware to
- * send us Port Status Updates using the new 32-bit Port
- * Capabilities version of the Port Information message.
- */
- if (fw_caps == FW_CAPS_UNKNOWN) {
- u32 param, val, caps;
-
- caps = FW_PARAMS_PARAM_PFVF_PORT_CAPS32;
- param = (V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_PFVF) |
- V_FW_PARAMS_PARAM_X(caps));
- val = 1;
- ret = t4_set_params(adap, mbox, pf, vf, 1, ¶m,
- &val);
- fw_caps = ret == 0 ? FW_CAPS32 : FW_CAPS16;
- adap->params.fw_caps_support = fw_caps;
- }
-
memset(&cmd, 0, sizeof(cmd));
cmd.op_to_portid = cpu_to_be32(V_FW_CMD_OP(FW_PORT_CMD) |
F_FW_CMD_REQUEST |
F_FW_CMD_READ |
V_FW_PORT_CMD_PORTID(j));
- action = fw_caps == FW_CAPS16 ? FW_PORT_ACTION_GET_PORT_INFO :
- FW_PORT_ACTION_GET_PORT_INFO32;
- cmd.action_to_len16 = cpu_to_be32(V_FW_PORT_CMD_ACTION(action) |
+ val = FW_PORT_ACTION_GET_PORT_INFO32;
+ cmd.action_to_len16 = cpu_to_be32(V_FW_PORT_CMD_ACTION(val) |
FW_LEN16(cmd));
ret = t4_wr_mbox(pi->adapter, mbox, &cmd, sizeof(cmd), &cmd);
if (ret)
return ret;
- /* Extract the various fields from the Port Information message.
+ /* Extract the various fields from the Port Information
+ * message.
*/
- if (fw_caps == FW_CAPS16) {
- u32 lstatus =
- be32_to_cpu(cmd.u.info.lstatus_to_modtype);
-
- port_type = G_FW_PORT_CMD_PTYPE(lstatus);
- mdio_addr = (lstatus & F_FW_PORT_CMD_MDIOCAP) ?
- (int)G_FW_PORT_CMD_MDIOADDR(lstatus) : -1;
- pcaps = be16_to_cpu(cmd.u.info.pcap);
- acaps = be16_to_cpu(cmd.u.info.acap);
- pcaps = fwcaps16_to_caps32(pcaps);
- acaps = fwcaps16_to_caps32(acaps);
- } else {
- u32 lstatus32 =
- be32_to_cpu(cmd.u.info32.lstatus32_to_cbllen32);
-
- port_type = G_FW_PORT_CMD_PORTTYPE32(lstatus32);
- mdio_addr = (lstatus32 & F_FW_PORT_CMD_MDIOCAP32) ?
- (int)G_FW_PORT_CMD_MDIOADDR32(lstatus32) :
- -1;
- pcaps = be32_to_cpu(cmd.u.info32.pcaps32);
- acaps = be32_to_cpu(cmd.u.info32.acaps32);
- }
+ lstatus32 = be32_to_cpu(cmd.u.info32.lstatus32_to_cbllen32);
+
+ port_type = G_FW_PORT_CMD_PORTTYPE32(lstatus32);
+ mdio_addr = (lstatus32 & F_FW_PORT_CMD_MDIOCAP32) ?
+ (int)G_FW_PORT_CMD_MDIOADDR32(lstatus32) : -1;
+ pcaps = be32_to_cpu(cmd.u.info32.pcaps32);
+ acaps = be32_to_cpu(cmd.u.info32.acaps32);
ret = t4_alloc_vi(adap, mbox, j, pf, vf, 1, addr, &rss_size,
&vivld, &vin);
diff --git a/drivers/net/cxgbe/base/t4fw_interface.h b/drivers/net/cxgbe/base/t4fw_interface.h
index 109273a39..153141247 100644
--- a/drivers/net/cxgbe/base/t4fw_interface.h
+++ b/drivers/net/cxgbe/base/t4fw_interface.h
@@ -1598,41 +1598,6 @@ struct fw_vi_stats_cmd {
#define S_FW_VI_STATS_CMD_IX 0
#define V_FW_VI_STATS_CMD_IX(x) ((x) << S_FW_VI_STATS_CMD_IX)
-/* old 16-bit port capabilities bitmap */
-enum fw_port_cap {
- FW_PORT_CAP_SPEED_100M = 0x0001,
- FW_PORT_CAP_SPEED_1G = 0x0002,
- FW_PORT_CAP_SPEED_25G = 0x0004,
- FW_PORT_CAP_SPEED_10G = 0x0008,
- FW_PORT_CAP_SPEED_40G = 0x0010,
- FW_PORT_CAP_SPEED_100G = 0x0020,
- FW_PORT_CAP_FC_RX = 0x0040,
- FW_PORT_CAP_FC_TX = 0x0080,
- FW_PORT_CAP_ANEG = 0x0100,
- FW_PORT_CAP_MDIX = 0x0200,
- FW_PORT_CAP_MDIAUTO = 0x0400,
- FW_PORT_CAP_FEC_RS = 0x0800,
- FW_PORT_CAP_FEC_BASER_RS = 0x1000,
- FW_PORT_CAP_FEC_RESERVED = 0x2000,
- FW_PORT_CAP_802_3_PAUSE = 0x4000,
- FW_PORT_CAP_802_3_ASM_DIR = 0x8000,
-};
-
-#define S_FW_PORT_CAP_SPEED 0
-#define M_FW_PORT_CAP_SPEED 0x3f
-#define V_FW_PORT_CAP_SPEED(x) ((x) << S_FW_PORT_CAP_SPEED)
-#define G_FW_PORT_CAP_SPEED(x) \
- (((x) >> S_FW_PORT_CAP_SPEED) & M_FW_PORT_CAP_SPEED)
-
-enum fw_port_mdi {
- FW_PORT_CAP_MDI_AUTO,
-};
-
-#define S_FW_PORT_CAP_MDI 9
-#define M_FW_PORT_CAP_MDI 3
-#define V_FW_PORT_CAP_MDI(x) ((x) << S_FW_PORT_CAP_MDI)
-#define G_FW_PORT_CAP_MDI(x) (((x) >> S_FW_PORT_CAP_MDI) & M_FW_PORT_CAP_MDI)
-
/* new 32-bit port capabilities bitmap (fw_port_cap32_t) */
#define FW_PORT_CAP32_SPEED_100M 0x00000001UL
#define FW_PORT_CAP32_SPEED_1G 0x00000002UL
@@ -1668,8 +1633,6 @@ enum fw_port_mdi32 {
(((x) >> S_FW_PORT_CAP32_MDI) & M_FW_PORT_CAP32_MDI)
enum fw_port_action {
- FW_PORT_ACTION_L1_CFG = 0x0001,
- FW_PORT_ACTION_GET_PORT_INFO = 0x0003,
FW_PORT_ACTION_L1_CFG32 = 0x0009,
FW_PORT_ACTION_GET_PORT_INFO32 = 0x000a,
};
@@ -1814,37 +1777,12 @@ struct fw_port_cmd {
(((x) >> S_FW_PORT_CMD_RXPAUSE) & M_FW_PORT_CMD_RXPAUSE)
#define F_FW_PORT_CMD_RXPAUSE V_FW_PORT_CMD_RXPAUSE(1U)
-#define S_FW_PORT_CMD_MDIOCAP 21
-#define M_FW_PORT_CMD_MDIOCAP 0x1
-#define V_FW_PORT_CMD_MDIOCAP(x) ((x) << S_FW_PORT_CMD_MDIOCAP)
-#define G_FW_PORT_CMD_MDIOCAP(x) \
- (((x) >> S_FW_PORT_CMD_MDIOCAP) & M_FW_PORT_CMD_MDIOCAP)
-#define F_FW_PORT_CMD_MDIOCAP V_FW_PORT_CMD_MDIOCAP(1U)
-
-#define S_FW_PORT_CMD_MDIOADDR 16
-#define M_FW_PORT_CMD_MDIOADDR 0x1f
-#define V_FW_PORT_CMD_MDIOADDR(x) ((x) << S_FW_PORT_CMD_MDIOADDR)
-#define G_FW_PORT_CMD_MDIOADDR(x) \
- (((x) >> S_FW_PORT_CMD_MDIOADDR) & M_FW_PORT_CMD_MDIOADDR)
-
#define S_FW_PORT_CMD_PTYPE 8
#define M_FW_PORT_CMD_PTYPE 0x1f
#define V_FW_PORT_CMD_PTYPE(x) ((x) << S_FW_PORT_CMD_PTYPE)
#define G_FW_PORT_CMD_PTYPE(x) \
(((x) >> S_FW_PORT_CMD_PTYPE) & M_FW_PORT_CMD_PTYPE)
-#define S_FW_PORT_CMD_LINKDNRC 5
-#define M_FW_PORT_CMD_LINKDNRC 0x7
-#define V_FW_PORT_CMD_LINKDNRC(x) ((x) << S_FW_PORT_CMD_LINKDNRC)
-#define G_FW_PORT_CMD_LINKDNRC(x) \
- (((x) >> S_FW_PORT_CMD_LINKDNRC) & M_FW_PORT_CMD_LINKDNRC)
-
-#define S_FW_PORT_CMD_MODTYPE 0
-#define M_FW_PORT_CMD_MODTYPE 0x1f
-#define V_FW_PORT_CMD_MODTYPE(x) ((x) << S_FW_PORT_CMD_MODTYPE)
-#define G_FW_PORT_CMD_MODTYPE(x) \
- (((x) >> S_FW_PORT_CMD_MODTYPE) & M_FW_PORT_CMD_MODTYPE)
-
#define S_FW_PORT_CMD_LSTATUS32 31
#define M_FW_PORT_CMD_LSTATUS32 0x1
#define V_FW_PORT_CMD_LSTATUS32(x) ((x) << S_FW_PORT_CMD_LSTATUS32)
@@ -1924,10 +1862,10 @@ enum fw_port_module_type {
FW_PORT_MOD_TYPE_TWINAX_PASSIVE = 0x4,
FW_PORT_MOD_TYPE_TWINAX_ACTIVE = 0x5,
FW_PORT_MOD_TYPE_LRM = 0x6,
- FW_PORT_MOD_TYPE_ERROR = M_FW_PORT_CMD_MODTYPE - 3,
- FW_PORT_MOD_TYPE_UNKNOWN = M_FW_PORT_CMD_MODTYPE - 2,
- FW_PORT_MOD_TYPE_NOTSUPPORTED = M_FW_PORT_CMD_MODTYPE - 1,
- FW_PORT_MOD_TYPE_NONE = M_FW_PORT_CMD_MODTYPE
+ FW_PORT_MOD_TYPE_ERROR = M_FW_PORT_CMD_MODTYPE32 - 3,
+ FW_PORT_MOD_TYPE_UNKNOWN = M_FW_PORT_CMD_MODTYPE32 - 2,
+ FW_PORT_MOD_TYPE_NOTSUPPORTED = M_FW_PORT_CMD_MODTYPE32 - 1,
+ FW_PORT_MOD_TYPE_NONE = M_FW_PORT_CMD_MODTYPE32
};
/* used by FW and tools may use this to generate VPD */
diff --git a/drivers/net/cxgbe/base/t4vf_hw.c b/drivers/net/cxgbe/base/t4vf_hw.c
index 649bacfb2..6454029aa 100644
--- a/drivers/net/cxgbe/base/t4vf_hw.c
+++ b/drivers/net/cxgbe/base/t4vf_hw.c
@@ -766,35 +766,24 @@ static int t4vf_alloc_vi(struct adapter *adapter, int port_id)
int t4vf_port_init(struct adapter *adapter)
{
- unsigned int fw_caps = adapter->params.fw_caps_support;
- struct fw_port_cmd port_cmd, port_rpl;
+ struct fw_port_cmd port_cmd, port_rpl, rpl;
struct fw_vi_cmd vi_cmd, vi_rpl;
fw_port_cap32_t pcaps, acaps;
enum fw_port_type port_type;
+ u32 param, val;
int mdio_addr;
int ret, i;
+ param = (V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_PFVF) |
+ V_FW_PARAMS_PARAM_X(FW_PARAMS_PARAM_PFVF_PORT_CAPS32));
+ val = 1;
+ ret = t4vf_set_params(adapter, 1, ¶m, &val);
+ if (ret < 0)
+ return ret;
+
for_each_port(adapter, i) {
struct port_info *p = adap2pinfo(adapter, i);
-
- /*
- * If we haven't yet determined if we're talking to Firmware
- * which knows the new 32-bit Port Caps, it's time to find
- * out now. This will also tell new Firmware to send us Port
- * Status Updates using the new 32-bit Port Capabilities
- * version of the Port Information message.
- */
- if (fw_caps == FW_CAPS_UNKNOWN) {
- u32 param, val;
-
- param = (V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_PFVF) |
- V_FW_PARAMS_PARAM_X
- (FW_PARAMS_PARAM_PFVF_PORT_CAPS32));
- val = 1;
- ret = t4vf_set_params(adapter, 1, ¶m, &val);
- fw_caps = (ret == 0 ? FW_CAPS32 : FW_CAPS16);
- adapter->params.fw_caps_support = fw_caps;
- }
+ u32 lstatus32;
ret = t4vf_alloc_vi(adapter, p->port_id);
if (ret < 0) {
@@ -830,15 +819,14 @@ int t4vf_port_init(struct adapter *adapter)
return 0;
memset(&port_cmd, 0, sizeof(port_cmd));
- port_cmd.op_to_portid = cpu_to_be32
- (V_FW_CMD_OP(FW_PORT_CMD) | F_FW_CMD_REQUEST |
- F_FW_CMD_READ |
- V_FW_PORT_CMD_PORTID(p->port_id));
- port_cmd.action_to_len16 = cpu_to_be32
- (V_FW_PORT_CMD_ACTION(fw_caps == FW_CAPS16 ?
- FW_PORT_ACTION_GET_PORT_INFO :
- FW_PORT_ACTION_GET_PORT_INFO32) |
- FW_LEN16(port_cmd));
+ port_cmd.op_to_portid =
+ cpu_to_be32(V_FW_CMD_OP(FW_PORT_CMD) |
+ F_FW_CMD_REQUEST | F_FW_CMD_READ |
+ V_FW_PORT_CMD_PORTID(p->port_id));
+ val = FW_PORT_ACTION_GET_PORT_INFO32;
+ port_cmd.action_to_len16 =
+ cpu_to_be32(V_FW_PORT_CMD_ACTION(val) |
+ FW_LEN16(port_cmd));
ret = t4vf_wr_mbox(adapter, &port_cmd, sizeof(port_cmd),
&port_rpl);
if (ret != FW_SUCCESS)
@@ -847,29 +835,14 @@ int t4vf_port_init(struct adapter *adapter)
/*
* Extract the various fields from the Port Information message.
*/
- if (fw_caps == FW_CAPS16) {
- u32 lstatus = be32_to_cpu
- (port_rpl.u.info.lstatus_to_modtype);
-
- port_type = G_FW_PORT_CMD_PTYPE(lstatus);
- mdio_addr = ((lstatus & F_FW_PORT_CMD_MDIOCAP) ?
- (int)G_FW_PORT_CMD_MDIOADDR(lstatus) :
- -1);
- pcaps = fwcaps16_to_caps32
- (be16_to_cpu(port_rpl.u.info.pcap));
- acaps = fwcaps16_to_caps32
- (be16_to_cpu(port_rpl.u.info.acap));
- } else {
- u32 lstatus32 = be32_to_cpu
- (port_rpl.u.info32.lstatus32_to_cbllen32);
-
- port_type = G_FW_PORT_CMD_PORTTYPE32(lstatus32);
- mdio_addr = ((lstatus32 & F_FW_PORT_CMD_MDIOCAP32) ?
- (int)G_FW_PORT_CMD_MDIOADDR32(lstatus32) :
- -1);
- pcaps = be32_to_cpu(port_rpl.u.info32.pcaps32);
- acaps = be32_to_cpu(port_rpl.u.info32.acaps32);
- }
+ rpl = port_rpl;
+ lstatus32 = be32_to_cpu(rpl.u.info32.lstatus32_to_cbllen32);
+
+ port_type = G_FW_PORT_CMD_PORTTYPE32(lstatus32);
+ mdio_addr = (lstatus32 & F_FW_PORT_CMD_MDIOCAP32) ?
+ (int)G_FW_PORT_CMD_MDIOADDR32(lstatus32) : -1;
+ pcaps = be32_to_cpu(port_rpl.u.info32.pcaps32);
+ acaps = be32_to_cpu(port_rpl.u.info32.acaps32);
p->port_type = port_type;
p->mdio_addr = mdio_addr;
--
2.24.0
^ permalink raw reply [flat|nested] 5+ messages in thread
* [dpdk-dev] [PATCH 2/3] net/cxgbe: rework and simplify link handling code
2020-12-20 22:47 [dpdk-dev] [PATCH 0/3] net/cxgbe: rework link config and add FEC support Rahul Lakkireddy
2020-12-20 22:47 ` [dpdk-dev] [PATCH 1/3] net/cxgbe: remove legacy 16-bit link capabilities Rahul Lakkireddy
@ 2020-12-20 22:47 ` Rahul Lakkireddy
2020-12-20 22:47 ` [dpdk-dev] [PATCH 3/3] net/cxgbe: implement ethdev ops to configure link FEC Rahul Lakkireddy
2021-01-15 15:02 ` [dpdk-dev] [PATCH 0/3] net/cxgbe: rework link config and add FEC support Ferruh Yigit
3 siblings, 0 replies; 5+ messages in thread
From: Rahul Lakkireddy @ 2020-12-20 22:47 UTC (permalink / raw)
To: dev; +Cc: kaara.satwik
From: Karra Satwik <kaara.satwik@chelsio.com>
Rework and simplify link handling code. Remove redundant
variables in link configuration structure and directly
extract information from the 32-bit link capabilities.
Signed-off-by: Karra Satwik <kaara.satwik@chelsio.com>
Signed-off-by: Rahul Lakkireddy <rahul.lakkireddy@chelsio.com>
---
drivers/net/cxgbe/base/adapter.h | 10 -
drivers/net/cxgbe/base/common.h | 60 ++--
drivers/net/cxgbe/base/t4_hw.c | 350 +++++++++++++-----------
drivers/net/cxgbe/base/t4fw_interface.h | 11 +-
drivers/net/cxgbe/base/t4vf_hw.c | 9 +-
drivers/net/cxgbe/cxgbe_ethdev.c | 68 +++--
drivers/net/cxgbe/cxgbe_main.c | 21 +-
7 files changed, 275 insertions(+), 254 deletions(-)
diff --git a/drivers/net/cxgbe/base/adapter.h b/drivers/net/cxgbe/base/adapter.h
index 6ff009a5f..a5a3313c2 100644
--- a/drivers/net/cxgbe/base/adapter.h
+++ b/drivers/net/cxgbe/base/adapter.h
@@ -39,9 +39,6 @@ struct port_info {
short int xact_addr_filt; /* index of exact MAC address filter */
u16 viid; /* associated virtual interface id */
- s8 mdio_addr; /* address of the PHY */
- u8 port_type; /* firmware port type */
- u8 mod_type; /* firmware module type */
u8 port_id; /* physical port ID */
u8 pidx; /* port index for this PF */
u8 tx_chan; /* associated channel */
@@ -63,12 +60,6 @@ struct port_info {
u8 vivld;
};
-/* Enable or disable autonegotiation. If this is set to enable,
- * the forced link modes above are completely ignored.
- */
-#define AUTONEG_DISABLE 0x00
-#define AUTONEG_ENABLE 0x01
-
enum { /* adapter flags */
FULL_INIT_DONE = (1 << 0),
USING_MSI = (1 << 1),
@@ -801,7 +792,6 @@ void t4_free_mem(void *addr);
#define t4_os_free(_ptr) t4_free_mem((_ptr))
void t4_os_portmod_changed(const struct adapter *adap, int port_id);
-void t4_os_link_changed(struct adapter *adap, int port_id, int link_stat);
void reclaim_completed_tx(struct sge_txq *q);
void t4_free_sge_resources(struct adapter *adap);
diff --git a/drivers/net/cxgbe/base/common.h b/drivers/net/cxgbe/base/common.h
index 86f3dc80b..a244df7a0 100644
--- a/drivers/net/cxgbe/base/common.h
+++ b/drivers/net/cxgbe/base/common.h
@@ -38,18 +38,6 @@ enum dev_master { MASTER_CANT, MASTER_MAY, MASTER_MUST };
enum dev_state { DEV_STATE_UNINIT, DEV_STATE_INIT, DEV_STATE_ERR };
-enum cc_pause {
- PAUSE_RX = 1 << 0,
- PAUSE_TX = 1 << 1,
- PAUSE_AUTONEG = 1 << 2
-};
-
-enum cc_fec {
- FEC_AUTO = 1 << 0, /* IEEE 802.3 "automatic" */
- FEC_RS = 1 << 1, /* Reed-Solomon */
- FEC_BASER_RS = 1 << 2, /* BaseR/Reed-Solomon */
-};
-
enum { MEM_EDC0, MEM_EDC1, MEM_MC, MEM_MC0 = MEM_MC, MEM_MC1 };
struct port_stats {
@@ -281,28 +269,19 @@ struct adapter_params {
/* Firmware Port Capabilities types.
*/
-typedef u32 fw_port_cap32_t; /* 32-bit Port Capabilities integral value */
-
struct link_config {
- fw_port_cap32_t pcaps; /* link capabilities */
- fw_port_cap32_t acaps; /* advertised capabilities */
-
- u32 requested_speed; /* speed (Mb/s) user has requested */
- u32 speed; /* actual link speed (Mb/s) */
-
- enum cc_pause requested_fc; /* flow control user has requested */
- enum cc_pause fc; /* actual link flow control */
+ u32 pcaps; /* Physically supported link caps */
+ u32 acaps; /* Advertised link caps */
- enum cc_fec auto_fec; /* Forward Error Correction
- * "automatic" (IEEE 802.3)
- */
- enum cc_fec requested_fec; /* Forward Error Correction requested */
- enum cc_fec fec; /* Forward Error Correction actual */
+ u32 link_caps; /* Current link caps */
+ u32 admin_caps; /* Admin configured link caps */
- unsigned char autoneg; /* autonegotiating? */
+ u8 mdio_addr; /* Address of the PHY */
+ u8 port_type; /* Firmware port type */
+ u8 mod_type; /* Firmware module type */
- unsigned char link_ok; /* link up? */
- unsigned char link_down_rc; /* link down reason */
+ u8 link_ok; /* Link up? */
+ u8 link_down_rc; /* Link down reason */
};
#include "adapter.h"
@@ -338,8 +317,21 @@ void t4_tp_wr_bits_indirect(struct adapter *adap, unsigned int addr,
unsigned int mask, unsigned int val);
void t4_intr_enable(struct adapter *adapter);
void t4_intr_disable(struct adapter *adapter);
-int t4_link_l1cfg(struct adapter *adap, unsigned int mbox, unsigned int port,
- struct link_config *lc);
+int t4_link_l1cfg_core(struct port_info *pi, u32 caps, u8 sleep_ok);
+static inline int t4_link_l1cfg(struct port_info *pi, u32 caps)
+{
+ return t4_link_l1cfg_core(pi, caps, true);
+}
+
+static inline int t4_link_l1cfg_ns(struct port_info *pi, u32 caps)
+{
+ return t4_link_l1cfg_core(pi, caps, false);
+}
+
+int t4_set_link_speed(struct port_info *pi, u32 speed, u32 *new_caps);
+int t4_set_link_pause(struct port_info *pi, u8 autoneg, u8 pause_tx,
+ u8 pause_rx, u32 *new_caps);
+unsigned int t4_fwcap_to_speed(u32 caps);
void t4_load_mtus(struct adapter *adap, const unsigned short *mtus,
const unsigned short *alpha, const unsigned short *beta);
int t4_fw_hello(struct adapter *adap, unsigned int mbox, unsigned int evt_mbox,
@@ -496,8 +488,8 @@ void t4_get_port_stats_offset(struct adapter *adap, int idx,
struct port_stats *stats,
struct port_stats *offset);
void t4_clr_port_stats(struct adapter *adap, int idx);
-void init_link_config(struct link_config *lc, fw_port_cap32_t pcaps,
- fw_port_cap32_t acaps);
+void t4_init_link_config(struct port_info *pi, u32 pcaps, u32 acaps,
+ u8 mdio_addr, u8 port_type, u8 mod_type);
void t4_reset_link_config(struct adapter *adap, int idx);
int t4_get_version_info(struct adapter *adapter);
void t4_dump_version_info(struct adapter *adapter);
diff --git a/drivers/net/cxgbe/base/t4_hw.c b/drivers/net/cxgbe/base/t4_hw.c
index 44227740c..3c0990cb3 100644
--- a/drivers/net/cxgbe/base/t4_hw.c
+++ b/drivers/net/cxgbe/base/t4_hw.c
@@ -2809,67 +2809,11 @@ void t4_dump_version_info(struct adapter *adapter)
G_FW_HDR_FW_VER_BUILD(adapter->params.er_vers));
}
-#define ADVERT_MASK (V_FW_PORT_CAP32_SPEED(M_FW_PORT_CAP32_SPEED) | \
- FW_PORT_CAP32_ANEG)
-
-/* Translate Firmware Pause specification to Common Code */
-static inline enum cc_pause fwcap_to_cc_pause(fw_port_cap32_t fw_pause)
-{
- enum cc_pause cc_pause = 0;
-
- if (fw_pause & FW_PORT_CAP32_FC_RX)
- cc_pause |= PAUSE_RX;
- if (fw_pause & FW_PORT_CAP32_FC_TX)
- cc_pause |= PAUSE_TX;
-
- return cc_pause;
-}
-
-/* Translate Common Code Pause Frame specification into Firmware */
-static inline fw_port_cap32_t cc_to_fwcap_pause(enum cc_pause cc_pause)
-{
- fw_port_cap32_t fw_pause = 0;
-
- if (cc_pause & PAUSE_RX)
- fw_pause |= FW_PORT_CAP32_FC_RX;
- if (cc_pause & PAUSE_TX)
- fw_pause |= FW_PORT_CAP32_FC_TX;
-
- return fw_pause;
-}
-
-/* Translate Firmware Forward Error Correction specification to Common Code */
-static inline enum cc_fec fwcap_to_cc_fec(fw_port_cap32_t fw_fec)
-{
- enum cc_fec cc_fec = 0;
-
- if (fw_fec & FW_PORT_CAP32_FEC_RS)
- cc_fec |= FEC_RS;
- if (fw_fec & FW_PORT_CAP32_FEC_BASER_RS)
- cc_fec |= FEC_BASER_RS;
-
- return cc_fec;
-}
-
-/* Translate Common Code Forward Error Correction specification to Firmware */
-static inline fw_port_cap32_t cc_to_fwcap_fec(enum cc_fec cc_fec)
-{
- fw_port_cap32_t fw_fec = 0;
-
- if (cc_fec & FEC_RS)
- fw_fec |= FW_PORT_CAP32_FEC_RS;
- if (cc_fec & FEC_BASER_RS)
- fw_fec |= FW_PORT_CAP32_FEC_BASER_RS;
-
- return fw_fec;
-}
-
/**
- * t4_link_l1cfg - apply link configuration to MAC/PHY
- * @adapter: the adapter
- * @mbox: the Firmware Mailbox to use
- * @port: the Port ID
- * @lc: the Port's Link Configuration
+ * t4_link_l1cfg_core - apply link configuration to MAC/PHY
+ * @pi: the port info
+ * @caps: link capabilities to configure
+ * @sleep_ok: if true we may sleep while awaiting command completion
*
* Set up a port's MAC and PHY according to a desired link configuration.
* - If the PHY can auto-negotiate first decide what to advertise, then
@@ -2878,57 +2822,38 @@ static inline fw_port_cap32_t cc_to_fwcap_fec(enum cc_fec cc_fec)
* - If auto-negotiation is off set the MAC to the proper speed/duplex/FC,
* otherwise do it later based on the outcome of auto-negotiation.
*/
-int t4_link_l1cfg(struct adapter *adap, unsigned int mbox, unsigned int port,
- struct link_config *lc)
+int t4_link_l1cfg_core(struct port_info *pi, u32 caps, u8 sleep_ok)
{
- unsigned int fw_mdi = V_FW_PORT_CAP32_MDI(FW_PORT_CAP32_MDI_AUTO);
- fw_port_cap32_t fw_fc, cc_fec, fw_fec, rcap;
+ struct link_config *lc = &pi->link_cfg;
+ struct adapter *adap = pi->adapter;
struct fw_port_cmd cmd;
+ int ret;
- lc->link_ok = 0;
-
- fw_fc = cc_to_fwcap_pause(lc->requested_fc);
-
- /* Convert Common Code Forward Error Control settings into the
- * Firmware's API. If the current Requested FEC has "Automatic"
- * (IEEE 802.3) specified, then we use whatever the Firmware
- * sent us as part of it's IEEE 802.3-based interpratation of
- * the Transceiver Module EPROM FEC parameters. Otherwise we
- * use whatever is in the current Requested FEC settings.
- */
- if (lc->requested_fec & FEC_AUTO)
- cc_fec = lc->auto_fec;
- else
- cc_fec = lc->requested_fec;
- fw_fec = cc_to_fwcap_fec(cc_fec);
-
- /* Figure out what our Requested Port Capabilities are going to be.
- */
- if (!(lc->pcaps & FW_PORT_CAP32_ANEG)) {
- rcap = (lc->pcaps & ADVERT_MASK) | fw_fc | fw_fec;
- lc->fc = lc->requested_fc & ~PAUSE_AUTONEG;
- lc->fec = cc_fec;
- } else if (lc->autoneg == AUTONEG_DISABLE) {
- rcap = lc->requested_speed | fw_fc | fw_fec | fw_mdi;
- lc->fc = lc->requested_fc & ~PAUSE_AUTONEG;
- lc->fec = cc_fec;
- } else {
- rcap = lc->acaps | fw_fc | fw_fec | fw_mdi;
- }
-
- /* And send that on to the Firmware ...
- */
memset(&cmd, 0, sizeof(cmd));
cmd.op_to_portid = cpu_to_be32(V_FW_CMD_OP(FW_PORT_CMD) |
F_FW_CMD_REQUEST | F_FW_CMD_EXEC |
- V_FW_PORT_CMD_PORTID(port));
+ V_FW_PORT_CMD_PORTID(pi->port_id));
cmd.action_to_len16 =
cpu_to_be32(V_FW_PORT_CMD_ACTION(FW_PORT_ACTION_L1_CFG32) |
FW_LEN16(cmd));
- cmd.u.l1cfg32.rcap32 = cpu_to_be32(rcap);
+ cmd.u.l1cfg32.rcap32 = cpu_to_be32(caps);
- return t4_wr_mbox(adap, mbox, &cmd, sizeof(cmd), NULL);
+ if (sleep_ok)
+ ret = t4_wr_mbox(adap, adap->mbox, &cmd, sizeof(cmd), NULL);
+ else
+ ret = t4_wr_mbox_ns(adap, adap->mbox, &cmd, sizeof(cmd), NULL);
+
+ if (ret == FW_SUCCESS) {
+ lc->link_ok = 0;
+ lc->link_caps = caps;
+ } else {
+ dev_err(adap,
+ "Requested Port Capabilities %#x rejected, error %d\n",
+ caps, ret);
+ }
+
+ return ret;
}
/**
@@ -4426,8 +4351,32 @@ static const char *t4_link_down_rc_str(unsigned char link_down_rc)
return reason[link_down_rc];
}
+static u32 t4_speed_to_fwcap(u32 speed)
+{
+ switch (speed) {
+ case 100000:
+ return FW_PORT_CAP32_SPEED_100G;
+ case 50000:
+ return FW_PORT_CAP32_SPEED_50G;
+ case 40000:
+ return FW_PORT_CAP32_SPEED_40G;
+ case 25000:
+ return FW_PORT_CAP32_SPEED_25G;
+ case 10000:
+ return FW_PORT_CAP32_SPEED_10G;
+ case 1000:
+ return FW_PORT_CAP32_SPEED_1G;
+ case 100:
+ return FW_PORT_CAP32_SPEED_100M;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
/* Return the highest speed set in the port capabilities, in Mb/s. */
-static unsigned int fwcap_to_speed(fw_port_cap32_t caps)
+unsigned int t4_fwcap_to_speed(u32 caps)
{
#define TEST_SPEED_RETURN(__caps_speed, __speed) \
do { \
@@ -4448,6 +4397,84 @@ static unsigned int fwcap_to_speed(fw_port_cap32_t caps)
return 0;
}
+static void t4_set_link_autoneg_speed(struct port_info *pi, u32 *new_caps)
+{
+ struct link_config *lc = &pi->link_cfg;
+ u32 caps = *new_caps;
+
+ caps &= ~V_FW_PORT_CAP32_SPEED(M_FW_PORT_CAP32_SPEED);
+ caps |= G_FW_PORT_CAP32_SPEED(lc->acaps);
+
+ *new_caps = caps;
+}
+
+int t4_set_link_speed(struct port_info *pi, u32 speed, u32 *new_caps)
+{
+ u32 fw_speed_cap = t4_speed_to_fwcap(speed);
+ struct link_config *lc = &pi->link_cfg;
+ u32 caps = *new_caps;
+
+ if (!(lc->pcaps & fw_speed_cap))
+ return -EOPNOTSUPP;
+
+ caps &= ~V_FW_PORT_CAP32_SPEED(M_FW_PORT_CAP32_SPEED);
+ caps |= fw_speed_cap;
+
+ *new_caps = caps;
+
+ return 0;
+}
+
+int t4_set_link_pause(struct port_info *pi, u8 autoneg, u8 pause_tx,
+ u8 pause_rx, u32 *new_caps)
+{
+ struct link_config *lc = &pi->link_cfg;
+ u32 caps = *new_caps;
+ u32 max_speed;
+
+ max_speed = t4_fwcap_to_speed(lc->link_caps);
+
+ if (autoneg) {
+ if (!(lc->pcaps & FW_PORT_CAP32_ANEG))
+ return -EINVAL;
+
+ caps |= FW_PORT_CAP32_ANEG;
+ t4_set_link_autoneg_speed(pi, &caps);
+ } else {
+ if (!max_speed)
+ max_speed = t4_fwcap_to_speed(lc->acaps);
+
+ caps &= ~FW_PORT_CAP32_ANEG;
+ t4_set_link_speed(pi, max_speed, &caps);
+ }
+
+ if (lc->pcaps & FW_PORT_CAP32_MDIAUTO)
+ caps |= V_FW_PORT_CAP32_MDI(FW_PORT_CAP32_MDI_AUTO);
+
+ caps &= ~V_FW_PORT_CAP32_FC(M_FW_PORT_CAP32_FC);
+ caps &= ~V_FW_PORT_CAP32_802_3(M_FW_PORT_CAP32_802_3);
+ if (pause_tx && pause_rx) {
+ caps |= FW_PORT_CAP32_FC_TX | FW_PORT_CAP32_FC_RX;
+ if (lc->pcaps & FW_PORT_CAP32_802_3_PAUSE)
+ caps |= FW_PORT_CAP32_802_3_PAUSE;
+ } else if (pause_tx) {
+ caps |= FW_PORT_CAP32_FC_TX;
+ if (lc->pcaps & FW_PORT_CAP32_802_3_ASM_DIR)
+ caps |= FW_PORT_CAP32_802_3_ASM_DIR;
+ } else if (pause_rx) {
+ caps |= FW_PORT_CAP32_FC_RX;
+ if (lc->pcaps & FW_PORT_CAP32_802_3_PAUSE)
+ caps |= FW_PORT_CAP32_802_3_PAUSE;
+
+ if (lc->pcaps & FW_PORT_CAP32_802_3_ASM_DIR)
+ caps |= FW_PORT_CAP32_802_3_ASM_DIR;
+ }
+
+ *new_caps = caps;
+
+ return 0;
+}
+
/**
* t4_handle_get_port_info - process a FW reply message
* @pi: the port info
@@ -4459,10 +4486,10 @@ static void t4_handle_get_port_info(struct port_info *pi, const __be64 *rpl)
{
const struct fw_port_cmd *cmd = (const void *)rpl;
u8 link_ok, link_down_rc, mod_type, port_type;
- u32 action, pcaps, acaps, linkattr, lstatus;
+ u32 action, pcaps, acaps, link_caps, lstatus;
struct link_config *lc = &pi->link_cfg;
struct adapter *adapter = pi->adapter;
- unsigned int speed, fc, fec;
+ u8 mod_changed = 0;
/* Extract the various fields from the Port Information message.
*/
@@ -4481,21 +4508,16 @@ static void t4_handle_get_port_info(struct port_info *pi, const __be64 *rpl)
pcaps = be32_to_cpu(cmd->u.info32.pcaps32);
acaps = be32_to_cpu(cmd->u.info32.acaps32);
- linkattr = be32_to_cpu(cmd->u.info32.linkattr32);
-
- fec = fwcap_to_cc_fec(acaps);
-
- fc = fwcap_to_cc_pause(linkattr);
- speed = fwcap_to_speed(linkattr);
+ link_caps = be32_to_cpu(cmd->u.info32.linkattr32);
- if (mod_type != pi->mod_type) {
- lc->auto_fec = fec;
- pi->port_type = port_type;
- pi->mod_type = mod_type;
+ if (mod_type != lc->mod_type) {
+ t4_init_link_config(pi, pcaps, acaps, lc->mdio_addr,
+ port_type, mod_type);
t4_os_portmod_changed(adapter, pi->pidx);
+ mod_changed = 1;
}
- if (link_ok != lc->link_ok || speed != lc->speed ||
- fc != lc->fc || fec != lc->fec) { /* something changed */
+ if (link_ok != lc->link_ok || acaps != lc->acaps ||
+ link_caps != lc->link_caps) { /* something changed */
if (!link_ok && lc->link_ok) {
lc->link_down_rc = link_down_rc;
dev_warn(adap, "Port %d link down, reason: %s\n",
@@ -4503,23 +4525,19 @@ static void t4_handle_get_port_info(struct port_info *pi, const __be64 *rpl)
t4_link_down_rc_str(link_down_rc));
}
lc->link_ok = link_ok;
- lc->speed = speed;
- lc->fc = fc;
- lc->fec = fec;
- lc->pcaps = pcaps;
- lc->acaps = acaps & ADVERT_MASK;
-
- if (lc->acaps & FW_PORT_CAP32_ANEG) {
- lc->autoneg = AUTONEG_ENABLE;
- } else {
- /* When Autoneg is disabled, user needs to set
- * single speed.
- * Similar to cxgb4_ethtool.c: set_link_ksettings
- */
- lc->acaps = 0;
- lc->requested_speed = fwcap_to_speed(acaps);
- lc->autoneg = AUTONEG_DISABLE;
- }
+ lc->acaps = acaps;
+ lc->link_caps = link_caps;
+ }
+
+ if (mod_changed) {
+ u32 mod_caps = lc->admin_caps;
+ int ret;
+
+ ret = t4_link_l1cfg_ns(pi, mod_caps);
+ if (ret != FW_SUCCESS)
+ dev_warn(adapter,
+ "Attempt to update new Transceiver Module settings %#x failed with error: %d\n",
+ mod_caps, ret);
}
}
@@ -4595,45 +4613,49 @@ void t4_reset_link_config(struct adapter *adap, int idx)
struct link_config *lc = &pi->link_cfg;
lc->link_ok = 0;
- lc->requested_speed = 0;
- lc->requested_fc = 0;
- lc->speed = 0;
- lc->fc = 0;
+ lc->link_down_rc = 0;
+ lc->link_caps = 0;
}
/**
- * init_link_config - initialize a link's SW state
- * @lc: structure holding the link state
+ * t4_init_link_config - initialize a link's SW state
+ * @pi: the port info
* @pcaps: link Port Capabilities
* @acaps: link current Advertised Port Capabilities
+ * @mdio_addr : address of the PHY
+ * @port_type : firmware port type
+ * @mod_type : firmware module type
*
* Initializes the SW state maintained for each link, including the link's
* capabilities and default speed/flow-control/autonegotiation settings.
*/
-void init_link_config(struct link_config *lc, fw_port_cap32_t pcaps,
- fw_port_cap32_t acaps)
+void t4_init_link_config(struct port_info *pi, u32 pcaps, u32 acaps,
+ u8 mdio_addr, u8 port_type, u8 mod_type)
{
+ struct link_config *lc = &pi->link_cfg;
+
lc->pcaps = pcaps;
- lc->requested_speed = 0;
- lc->speed = 0;
- lc->requested_fc = 0;
- lc->fc = 0;
+ lc->acaps = acaps;
+ lc->admin_caps = acaps;
+ lc->link_caps = 0;
- /**
- * For Forward Error Control, we default to whatever the Firmware
- * tells us the Link is currently advertising.
- */
- lc->auto_fec = fwcap_to_cc_fec(acaps);
- lc->requested_fec = FEC_AUTO;
- lc->fec = lc->auto_fec;
-
- if (lc->pcaps & FW_PORT_CAP32_ANEG) {
- lc->acaps = lc->pcaps & ADVERT_MASK;
- lc->autoneg = AUTONEG_ENABLE;
- lc->requested_fc |= PAUSE_AUTONEG;
- } else {
- lc->acaps = 0;
- lc->autoneg = AUTONEG_DISABLE;
+ lc->mdio_addr = mdio_addr;
+ lc->port_type = port_type;
+ lc->mod_type = mod_type;
+
+ lc->link_ok = 0;
+ lc->link_down_rc = 0;
+
+ /* Turn Tx and Rx pause off by default */
+ lc->admin_caps &= ~V_FW_PORT_CAP32_FC(M_FW_PORT_CAP32_FC);
+ lc->admin_caps &= ~V_FW_PORT_CAP32_802_3(M_FW_PORT_CAP32_802_3);
+ if (lc->pcaps & FW_PORT_CAP32_FORCE_PAUSE)
+ lc->admin_caps &= ~FW_PORT_CAP32_FORCE_PAUSE;
+
+ /* Reset MDI to AUTO */
+ if (lc->pcaps & FW_PORT_CAP32_MDIAUTO) {
+ lc->admin_caps &= ~V_FW_PORT_CAP32_MDI(M_FW_PORT_CAP32_MDI);
+ lc->admin_caps |= V_FW_PORT_CAP32_MDI(FW_PORT_CAP32_MDI_AUTO);
}
}
@@ -5271,12 +5293,11 @@ int t4_init_rss_mode(struct adapter *adap, int mbox)
int t4_port_init(struct adapter *adap, int mbox, int pf, int vf)
{
- fw_port_cap32_t pcaps, acaps;
+ u32 param, val, pcaps, acaps;
enum fw_port_type port_type;
struct fw_port_cmd cmd;
u8 vivld = 0, vin = 0;
int ret, i, j = 0;
- u32 param, val;
int mdio_addr;
u8 addr[6];
@@ -5342,11 +5363,8 @@ int t4_port_init(struct adapter *adap, int mbox, int pf, int vf)
pi->vin = G_FW_VIID_VIN(pi->viid);
}
- pi->port_type = port_type;
- pi->mdio_addr = mdio_addr;
- pi->mod_type = FW_PORT_MOD_TYPE_NA;
-
- init_link_config(&pi->link_cfg, pcaps, acaps);
+ t4_init_link_config(pi, pcaps, acaps, mdio_addr, port_type,
+ FW_PORT_MOD_TYPE_NA);
j++;
}
return 0;
diff --git a/drivers/net/cxgbe/base/t4fw_interface.h b/drivers/net/cxgbe/base/t4fw_interface.h
index 153141247..cfd03cf34 100644
--- a/drivers/net/cxgbe/base/t4fw_interface.h
+++ b/drivers/net/cxgbe/base/t4fw_interface.h
@@ -1615,6 +1615,7 @@ struct fw_vi_stats_cmd {
#define FW_PORT_CAP32_MDIAUTO 0x00400000UL
#define FW_PORT_CAP32_FEC_RS 0x00800000UL
#define FW_PORT_CAP32_FEC_BASER_RS 0x01000000UL
+#define FW_PORT_CAP32_FORCE_PAUSE 0x10000000UL
#define S_FW_PORT_CAP32_SPEED 0
#define M_FW_PORT_CAP32_SPEED 0xfff
@@ -1622,8 +1623,16 @@ struct fw_vi_stats_cmd {
#define G_FW_PORT_CAP32_SPEED(x) \
(((x) >> S_FW_PORT_CAP32_SPEED) & M_FW_PORT_CAP32_SPEED)
+#define S_FW_PORT_CAP32_FC 16
+#define M_FW_PORT_CAP32_FC 0x3
+#define V_FW_PORT_CAP32_FC(x) ((x) << S_FW_PORT_CAP32_FC)
+
+#define S_FW_PORT_CAP32_802_3 18
+#define M_FW_PORT_CAP32_802_3 0x3
+#define V_FW_PORT_CAP32_802_3(x) ((x) << S_FW_PORT_CAP32_802_3)
+
enum fw_port_mdi32 {
- FW_PORT_CAP32_MDI_AUTO,
+ FW_PORT_CAP32_MDI_AUTO = 1,
};
#define S_FW_PORT_CAP32_MDI 21
diff --git a/drivers/net/cxgbe/base/t4vf_hw.c b/drivers/net/cxgbe/base/t4vf_hw.c
index 6454029aa..cd011bc1b 100644
--- a/drivers/net/cxgbe/base/t4vf_hw.c
+++ b/drivers/net/cxgbe/base/t4vf_hw.c
@@ -768,9 +768,8 @@ int t4vf_port_init(struct adapter *adapter)
{
struct fw_port_cmd port_cmd, port_rpl, rpl;
struct fw_vi_cmd vi_cmd, vi_rpl;
- fw_port_cap32_t pcaps, acaps;
+ u32 param, val, pcaps, acaps;
enum fw_port_type port_type;
- u32 param, val;
int mdio_addr;
int ret, i;
@@ -844,10 +843,8 @@ int t4vf_port_init(struct adapter *adapter)
pcaps = be32_to_cpu(port_rpl.u.info32.pcaps32);
acaps = be32_to_cpu(port_rpl.u.info32.acaps32);
- p->port_type = port_type;
- p->mdio_addr = mdio_addr;
- p->mod_type = FW_PORT_MOD_TYPE_NA;
- init_link_config(&p->link_cfg, pcaps, acaps);
+ t4_init_link_config(p, pcaps, acaps, mdio_addr, port_type,
+ FW_PORT_MOD_TYPE_NA);
}
return 0;
}
diff --git a/drivers/net/cxgbe/cxgbe_ethdev.c b/drivers/net/cxgbe/cxgbe_ethdev.c
index 98d0362fa..c58e63918 100644
--- a/drivers/net/cxgbe/cxgbe_ethdev.c
+++ b/drivers/net/cxgbe/cxgbe_ethdev.c
@@ -193,11 +193,12 @@ int cxgbe_dev_link_update(struct rte_eth_dev *eth_dev,
int wait_to_complete)
{
struct port_info *pi = eth_dev->data->dev_private;
+ unsigned int i, work_done, budget = 32;
+ struct link_config *lc = &pi->link_cfg;
struct adapter *adapter = pi->adapter;
- struct sge *s = &adapter->sge;
struct rte_eth_link new_link = { 0 };
- unsigned int i, work_done, budget = 32;
u8 old_link = pi->link_cfg.link_ok;
+ struct sge *s = &adapter->sge;
for (i = 0; i < CXGBE_LINK_STATUS_POLL_CNT; i++) {
if (!s->fw_evtq.desc)
@@ -218,9 +219,9 @@ int cxgbe_dev_link_update(struct rte_eth_dev *eth_dev,
new_link.link_status = cxgbe_force_linkup(adapter) ?
ETH_LINK_UP : pi->link_cfg.link_ok;
- new_link.link_autoneg = pi->link_cfg.autoneg;
+ new_link.link_autoneg = (lc->link_caps & FW_PORT_CAP32_ANEG) ? 1 : 0;
new_link.link_duplex = ETH_LINK_FULL_DUPLEX;
- new_link.link_speed = pi->link_cfg.speed;
+ new_link.link_speed = t4_fwcap_to_speed(lc->link_caps);
return rte_eth_linkstatus_set(eth_dev, &new_link);
}
@@ -787,11 +788,17 @@ static int cxgbe_flow_ctrl_get(struct rte_eth_dev *eth_dev,
{
struct port_info *pi = eth_dev->data->dev_private;
struct link_config *lc = &pi->link_cfg;
- int rx_pause, tx_pause;
+ u8 rx_pause = 0, tx_pause = 0;
+ u32 caps = lc->link_caps;
- fc_conf->autoneg = lc->fc & PAUSE_AUTONEG;
- rx_pause = lc->fc & PAUSE_RX;
- tx_pause = lc->fc & PAUSE_TX;
+ if (caps & FW_PORT_CAP32_ANEG)
+ fc_conf->autoneg = 1;
+
+ if (caps & FW_PORT_CAP32_FC_TX)
+ tx_pause = 1;
+
+ if (caps & FW_PORT_CAP32_FC_RX)
+ rx_pause = 1;
if (rx_pause && tx_pause)
fc_conf->mode = RTE_FC_FULL;
@@ -808,30 +815,39 @@ static int cxgbe_flow_ctrl_set(struct rte_eth_dev *eth_dev,
struct rte_eth_fc_conf *fc_conf)
{
struct port_info *pi = eth_dev->data->dev_private;
- struct adapter *adapter = pi->adapter;
struct link_config *lc = &pi->link_cfg;
+ u32 new_caps = lc->admin_caps;
+ u8 tx_pause = 0, rx_pause = 0;
+ int ret;
- if (lc->pcaps & FW_PORT_CAP32_ANEG) {
- if (fc_conf->autoneg)
- lc->requested_fc |= PAUSE_AUTONEG;
- else
- lc->requested_fc &= ~PAUSE_AUTONEG;
+ if (fc_conf->mode == RTE_FC_FULL) {
+ tx_pause = 1;
+ rx_pause = 1;
+ } else if (fc_conf->mode == RTE_FC_TX_PAUSE) {
+ tx_pause = 1;
+ } else if (fc_conf->mode == RTE_FC_RX_PAUSE) {
+ rx_pause = 1;
}
- if (((fc_conf->mode & RTE_FC_FULL) == RTE_FC_FULL) ||
- (fc_conf->mode & RTE_FC_RX_PAUSE))
- lc->requested_fc |= PAUSE_RX;
- else
- lc->requested_fc &= ~PAUSE_RX;
+ ret = t4_set_link_pause(pi, fc_conf->autoneg, tx_pause,
+ rx_pause, &new_caps);
+ if (ret != 0)
+ return ret;
- if (((fc_conf->mode & RTE_FC_FULL) == RTE_FC_FULL) ||
- (fc_conf->mode & RTE_FC_TX_PAUSE))
- lc->requested_fc |= PAUSE_TX;
- else
- lc->requested_fc &= ~PAUSE_TX;
+ if (!fc_conf->autoneg) {
+ if (lc->pcaps & FW_PORT_CAP32_FORCE_PAUSE)
+ new_caps |= FW_PORT_CAP32_FORCE_PAUSE;
+ } else {
+ new_caps &= ~FW_PORT_CAP32_FORCE_PAUSE;
+ }
+
+ if (new_caps != lc->admin_caps) {
+ ret = t4_link_l1cfg(pi, new_caps);
+ if (ret == 0)
+ lc->admin_caps = new_caps;
+ }
- return t4_link_l1cfg(adapter, adapter->mbox, pi->tx_chan,
- &pi->link_cfg);
+ return ret;
}
const uint32_t *
diff --git a/drivers/net/cxgbe/cxgbe_main.c b/drivers/net/cxgbe/cxgbe_main.c
index 53b08a64a..3b56eccfb 100644
--- a/drivers/net/cxgbe/cxgbe_main.c
+++ b/drivers/net/cxgbe/cxgbe_main.c
@@ -732,7 +732,7 @@ void cxgbe_print_port_info(struct adapter *adap)
--bufp;
sprintf(bufp, "BASE-%s",
t4_get_port_type_description(
- (enum fw_port_type)pi->port_type));
+ (enum fw_port_type)pi->link_cfg.port_type));
dev_info(adap,
" " PCI_PRI_FMT " Chelsio rev %d %s %s\n",
@@ -1575,23 +1575,23 @@ void t4_os_portmod_changed(const struct adapter *adap, int port_id)
const struct port_info *pi = adap2pinfo(adap, port_id);
- if (pi->mod_type == FW_PORT_MOD_TYPE_NONE)
+ if (pi->link_cfg.mod_type == FW_PORT_MOD_TYPE_NONE)
dev_info(adap, "Port%d: port module unplugged\n", pi->port_id);
- else if (pi->mod_type < ARRAY_SIZE(mod_str))
+ else if (pi->link_cfg.mod_type < ARRAY_SIZE(mod_str))
dev_info(adap, "Port%d: %s port module inserted\n", pi->port_id,
- mod_str[pi->mod_type]);
- else if (pi->mod_type == FW_PORT_MOD_TYPE_NOTSUPPORTED)
+ mod_str[pi->link_cfg.mod_type]);
+ else if (pi->link_cfg.mod_type == FW_PORT_MOD_TYPE_NOTSUPPORTED)
dev_info(adap, "Port%d: unsupported port module inserted\n",
pi->port_id);
- else if (pi->mod_type == FW_PORT_MOD_TYPE_UNKNOWN)
+ else if (pi->link_cfg.mod_type == FW_PORT_MOD_TYPE_UNKNOWN)
dev_info(adap, "Port%d: unknown port module inserted\n",
pi->port_id);
- else if (pi->mod_type == FW_PORT_MOD_TYPE_ERROR)
+ else if (pi->link_cfg.mod_type == FW_PORT_MOD_TYPE_ERROR)
dev_info(adap, "Port%d: transceiver module error\n",
pi->port_id);
else
dev_info(adap, "Port%d: unknown module type %d inserted\n",
- pi->port_id, pi->mod_type);
+ pi->port_id, pi->link_cfg.mod_type);
}
bool cxgbe_force_linkup(struct adapter *adap)
@@ -1636,8 +1636,7 @@ int cxgbe_link_start(struct port_info *pi)
}
}
if (ret == 0 && is_pf4(adapter))
- ret = t4_link_l1cfg(adapter, adapter->mbox, pi->tx_chan,
- &pi->link_cfg);
+ ret = t4_link_l1cfg(pi, pi->link_cfg.admin_caps);
if (ret == 0) {
/*
* Enabling a Virtual Interface can result in an interrupt
@@ -1905,7 +1904,7 @@ void cxgbe_get_speed_caps(struct port_info *pi, u32 *speed_caps)
{
*speed_caps = 0;
- fw_caps_to_speed_caps(pi->port_type, pi->link_cfg.pcaps,
+ fw_caps_to_speed_caps(pi->link_cfg.port_type, pi->link_cfg.pcaps,
speed_caps);
if (!(pi->link_cfg.pcaps & FW_PORT_CAP32_ANEG))
--
2.24.0
^ permalink raw reply [flat|nested] 5+ messages in thread
* [dpdk-dev] [PATCH 3/3] net/cxgbe: implement ethdev ops to configure link FEC
2020-12-20 22:47 [dpdk-dev] [PATCH 0/3] net/cxgbe: rework link config and add FEC support Rahul Lakkireddy
2020-12-20 22:47 ` [dpdk-dev] [PATCH 1/3] net/cxgbe: remove legacy 16-bit link capabilities Rahul Lakkireddy
2020-12-20 22:47 ` [dpdk-dev] [PATCH 2/3] net/cxgbe: rework and simplify link handling code Rahul Lakkireddy
@ 2020-12-20 22:47 ` Rahul Lakkireddy
2021-01-15 15:02 ` [dpdk-dev] [PATCH 0/3] net/cxgbe: rework link config and add FEC support Ferruh Yigit
3 siblings, 0 replies; 5+ messages in thread
From: Rahul Lakkireddy @ 2020-12-20 22:47 UTC (permalink / raw)
To: dev; +Cc: kaara.satwik
From: Karra Satwik <kaara.satwik@chelsio.com>
Add ethdev ops to query and configure link FEC.
Signed-off-by: Karra Satwik <kaara.satwik@chelsio.com>
Signed-off-by: Rahul Lakkireddy <rahul.lakkireddy@chelsio.com>
---
drivers/net/cxgbe/base/common.h | 2 +
drivers/net/cxgbe/base/t4_hw.c | 79 ++++++++++++++
drivers/net/cxgbe/base/t4fw_interface.h | 6 ++
drivers/net/cxgbe/cxgbe_ethdev.c | 133 ++++++++++++++++++++++++
4 files changed, 220 insertions(+)
diff --git a/drivers/net/cxgbe/base/common.h b/drivers/net/cxgbe/base/common.h
index a244df7a0..202a2f4ba 100644
--- a/drivers/net/cxgbe/base/common.h
+++ b/drivers/net/cxgbe/base/common.h
@@ -331,6 +331,8 @@ static inline int t4_link_l1cfg_ns(struct port_info *pi, u32 caps)
int t4_set_link_speed(struct port_info *pi, u32 speed, u32 *new_caps);
int t4_set_link_pause(struct port_info *pi, u8 autoneg, u8 pause_tx,
u8 pause_rx, u32 *new_caps);
+int t4_set_link_fec(struct port_info *pi, u8 fec_rs, u8 fec_baser,
+ u8 fec_none, u32 *new_caps);
unsigned int t4_fwcap_to_speed(u32 caps);
void t4_load_mtus(struct adapter *adap, const unsigned short *mtus,
const unsigned short *alpha, const unsigned short *beta);
diff --git a/drivers/net/cxgbe/base/t4_hw.c b/drivers/net/cxgbe/base/t4_hw.c
index 3c0990cb3..e87823f8f 100644
--- a/drivers/net/cxgbe/base/t4_hw.c
+++ b/drivers/net/cxgbe/base/t4_hw.c
@@ -4475,6 +4475,76 @@ int t4_set_link_pause(struct port_info *pi, u8 autoneg, u8 pause_tx,
return 0;
}
+int t4_set_link_fec(struct port_info *pi, u8 fec_rs, u8 fec_baser,
+ u8 fec_none, u32 *new_caps)
+{
+ struct link_config *lc = &pi->link_cfg;
+ u32 max_speed, caps = *new_caps;
+
+ if (!(lc->pcaps & V_FW_PORT_CAP32_FEC(M_FW_PORT_CAP32_FEC)))
+ return -EOPNOTSUPP;
+
+ /* Link might be down. In that case consider the max
+ * speed advertised
+ */
+ max_speed = t4_fwcap_to_speed(lc->link_caps);
+ if (!max_speed)
+ max_speed = t4_fwcap_to_speed(lc->acaps);
+
+ caps &= ~V_FW_PORT_CAP32_FEC(M_FW_PORT_CAP32_FEC);
+ if (fec_rs) {
+ switch (max_speed) {
+ case 100000:
+ case 25000:
+ caps |= FW_PORT_CAP32_FEC_RS;
+ break;
+ default:
+ return -EOPNOTSUPP;
+ }
+ }
+
+ if (fec_baser) {
+ switch (max_speed) {
+ case 50000:
+ case 25000:
+ caps |= FW_PORT_CAP32_FEC_BASER_RS;
+ break;
+ default:
+ return -EOPNOTSUPP;
+ }
+ }
+
+ if (fec_none)
+ caps |= FW_PORT_CAP32_FEC_NO_FEC;
+
+ if (!(caps & V_FW_PORT_CAP32_FEC(M_FW_PORT_CAP32_FEC))) {
+ /* No explicit encoding is requested.
+ * So, default back to AUTO.
+ */
+ switch (max_speed) {
+ case 100000:
+ caps |= FW_PORT_CAP32_FEC_RS |
+ FW_PORT_CAP32_FEC_NO_FEC;
+ break;
+ case 50000:
+ caps |= FW_PORT_CAP32_FEC_BASER_RS |
+ FW_PORT_CAP32_FEC_NO_FEC;
+ break;
+ case 25000:
+ caps |= FW_PORT_CAP32_FEC_RS |
+ FW_PORT_CAP32_FEC_BASER_RS |
+ FW_PORT_CAP32_FEC_NO_FEC;
+ break;
+ default:
+ return -EOPNOTSUPP;
+ }
+ }
+
+ *new_caps = caps;
+
+ return 0;
+}
+
/**
* t4_handle_get_port_info - process a FW reply message
* @pi: the port info
@@ -4652,6 +4722,15 @@ void t4_init_link_config(struct port_info *pi, u32 pcaps, u32 acaps,
if (lc->pcaps & FW_PORT_CAP32_FORCE_PAUSE)
lc->admin_caps &= ~FW_PORT_CAP32_FORCE_PAUSE;
+ /* Reset FEC caps to default values */
+ if (lc->pcaps & V_FW_PORT_CAP32_FEC(M_FW_PORT_CAP32_FEC)) {
+ lc->admin_caps &= ~V_FW_PORT_CAP32_FEC(M_FW_PORT_CAP32_FEC);
+ t4_set_link_fec(pi, 0, 0, 0, &lc->admin_caps);
+ }
+
+ if (lc->pcaps & FW_PORT_CAP32_FORCE_FEC)
+ lc->admin_caps &= ~FW_PORT_CAP32_FORCE_FEC;
+
/* Reset MDI to AUTO */
if (lc->pcaps & FW_PORT_CAP32_MDIAUTO) {
lc->admin_caps &= ~V_FW_PORT_CAP32_MDI(M_FW_PORT_CAP32_MDI);
diff --git a/drivers/net/cxgbe/base/t4fw_interface.h b/drivers/net/cxgbe/base/t4fw_interface.h
index cfd03cf34..240e0ee49 100644
--- a/drivers/net/cxgbe/base/t4fw_interface.h
+++ b/drivers/net/cxgbe/base/t4fw_interface.h
@@ -1615,7 +1615,9 @@ struct fw_vi_stats_cmd {
#define FW_PORT_CAP32_MDIAUTO 0x00400000UL
#define FW_PORT_CAP32_FEC_RS 0x00800000UL
#define FW_PORT_CAP32_FEC_BASER_RS 0x01000000UL
+#define FW_PORT_CAP32_FEC_NO_FEC 0x02000000UL
#define FW_PORT_CAP32_FORCE_PAUSE 0x10000000UL
+#define FW_PORT_CAP32_FORCE_FEC 0x20000000UL
#define S_FW_PORT_CAP32_SPEED 0
#define M_FW_PORT_CAP32_SPEED 0xfff
@@ -1641,6 +1643,10 @@ enum fw_port_mdi32 {
#define G_FW_PORT_CAP32_MDI(x) \
(((x) >> S_FW_PORT_CAP32_MDI) & M_FW_PORT_CAP32_MDI)
+#define S_FW_PORT_CAP32_FEC 23
+#define M_FW_PORT_CAP32_FEC 0x1f
+#define V_FW_PORT_CAP32_FEC(x) ((x) << S_FW_PORT_CAP32_FEC)
+
enum fw_port_action {
FW_PORT_ACTION_L1_CFG32 = 0x0009,
FW_PORT_ACTION_GET_PORT_INFO32 = 0x000a,
diff --git a/drivers/net/cxgbe/cxgbe_ethdev.c b/drivers/net/cxgbe/cxgbe_ethdev.c
index c58e63918..6f481551d 100644
--- a/drivers/net/cxgbe/cxgbe_ethdev.c
+++ b/drivers/net/cxgbe/cxgbe_ethdev.c
@@ -1193,6 +1193,136 @@ int cxgbe_mac_addr_set(struct rte_eth_dev *dev, struct rte_ether_addr *addr)
return 0;
}
+static int cxgbe_fec_get_capa_speed_to_fec(struct link_config *lc,
+ struct rte_eth_fec_capa *capa_arr)
+{
+ int num = 0;
+
+ if (lc->pcaps & FW_PORT_CAP32_SPEED_100G) {
+ if (capa_arr) {
+ capa_arr[num].speed = ETH_SPEED_NUM_100G;
+ capa_arr[num].capa = RTE_ETH_FEC_MODE_CAPA_MASK(NOFEC) |
+ RTE_ETH_FEC_MODE_CAPA_MASK(RS);
+ }
+ num++;
+ }
+
+ if (lc->pcaps & FW_PORT_CAP32_SPEED_50G) {
+ if (capa_arr) {
+ capa_arr[num].speed = ETH_SPEED_NUM_50G;
+ capa_arr[num].capa = RTE_ETH_FEC_MODE_CAPA_MASK(NOFEC) |
+ RTE_ETH_FEC_MODE_CAPA_MASK(BASER);
+ }
+ num++;
+ }
+
+ if (lc->pcaps & FW_PORT_CAP32_SPEED_25G) {
+ if (capa_arr) {
+ capa_arr[num].speed = ETH_SPEED_NUM_25G;
+ capa_arr[num].capa = RTE_ETH_FEC_MODE_CAPA_MASK(NOFEC) |
+ RTE_ETH_FEC_MODE_CAPA_MASK(BASER) |
+ RTE_ETH_FEC_MODE_CAPA_MASK(RS);
+ }
+ num++;
+ }
+
+ return num;
+}
+
+static int cxgbe_fec_get_capability(struct rte_eth_dev *dev,
+ struct rte_eth_fec_capa *speed_fec_capa,
+ unsigned int num)
+{
+ struct port_info *pi = dev->data->dev_private;
+ struct link_config *lc = &pi->link_cfg;
+ u8 num_entries;
+
+ if (!(lc->pcaps & V_FW_PORT_CAP32_FEC(M_FW_PORT_CAP32_FEC)))
+ return -EOPNOTSUPP;
+
+ num_entries = cxgbe_fec_get_capa_speed_to_fec(lc, NULL);
+ if (!speed_fec_capa || num < num_entries)
+ return num_entries;
+
+ return cxgbe_fec_get_capa_speed_to_fec(lc, speed_fec_capa);
+}
+
+static int cxgbe_fec_get(struct rte_eth_dev *dev, uint32_t *fec_capa)
+{
+ struct port_info *pi = dev->data->dev_private;
+ struct link_config *lc = &pi->link_cfg;
+ u32 fec_caps = 0, caps = lc->link_caps;
+
+ if (!(lc->pcaps & V_FW_PORT_CAP32_FEC(M_FW_PORT_CAP32_FEC)))
+ return -EOPNOTSUPP;
+
+ if (caps & FW_PORT_CAP32_FEC_NO_FEC) {
+ fec_caps = RTE_ETH_FEC_MODE_CAPA_MASK(NOFEC);
+ goto out;
+ }
+
+ if (caps & FW_PORT_CAP32_FEC_BASER_RS) {
+ fec_caps = RTE_ETH_FEC_MODE_CAPA_MASK(BASER);
+ goto out;
+ }
+
+ if (caps & FW_PORT_CAP32_FEC_RS) {
+ fec_caps = RTE_ETH_FEC_MODE_CAPA_MASK(RS);
+ goto out;
+ }
+
+ fec_caps = RTE_ETH_FEC_MODE_CAPA_MASK(AUTO);
+
+out:
+ *fec_capa = fec_caps;
+ return 0;
+}
+
+static int cxgbe_fec_set(struct rte_eth_dev *dev, uint32_t fec_capa)
+{
+ struct port_info *pi = dev->data->dev_private;
+ u8 fec_rs = 0, fec_baser = 0, fec_none = 0;
+ struct link_config *lc = &pi->link_cfg;
+ u32 new_caps = lc->admin_caps;
+ int ret;
+
+ if (!(lc->pcaps & V_FW_PORT_CAP32_FEC(M_FW_PORT_CAP32_FEC)))
+ return -EOPNOTSUPP;
+
+ if (!fec_capa)
+ return -EINVAL;
+
+ if (fec_capa & RTE_ETH_FEC_MODE_CAPA_MASK(AUTO))
+ goto set_fec;
+
+ if (fec_capa & RTE_ETH_FEC_MODE_CAPA_MASK(NOFEC))
+ fec_none = 1;
+
+ if (fec_capa & RTE_ETH_FEC_MODE_CAPA_MASK(BASER))
+ fec_baser = 1;
+
+ if (fec_capa & RTE_ETH_FEC_MODE_CAPA_MASK(RS))
+ fec_rs = 1;
+
+set_fec:
+ ret = t4_set_link_fec(pi, fec_rs, fec_baser, fec_none, &new_caps);
+ if (ret != 0)
+ return ret;
+
+ if (lc->pcaps & FW_PORT_CAP32_FORCE_FEC)
+ new_caps |= FW_PORT_CAP32_FORCE_FEC;
+ else
+ new_caps &= ~FW_PORT_CAP32_FORCE_FEC;
+
+ if (new_caps != lc->admin_caps) {
+ ret = t4_link_l1cfg(pi, new_caps);
+ if (ret == 0)
+ lc->admin_caps = new_caps;
+ }
+
+ return ret;
+}
+
static const struct eth_dev_ops cxgbe_eth_dev_ops = {
.dev_start = cxgbe_dev_start,
.dev_stop = cxgbe_dev_stop,
@@ -1230,6 +1360,9 @@ static const struct eth_dev_ops cxgbe_eth_dev_ops = {
.mac_addr_set = cxgbe_mac_addr_set,
.reta_update = cxgbe_dev_rss_reta_update,
.reta_query = cxgbe_dev_rss_reta_query,
+ .fec_get_capability = cxgbe_fec_get_capability,
+ .fec_get = cxgbe_fec_get,
+ .fec_set = cxgbe_fec_set,
};
/*
--
2.24.0
^ permalink raw reply [flat|nested] 5+ messages in thread