From: Roopa Prabhu <roopa@cumulusnetworks.com>
To: davem@davemloft.net, linville@tuxdriver.com
Cc: netdev@vger.kernel.org, vidya.chowdary@gmail.com,
dustin@cumulusnetworks.com, olson@cumulusnetworks.com,
leedom@chelsio.com, manojmalviya@chelsio.com,
santosh@chelsio.com, yuval.mintz@qlogic.com, odedw@mellanox.com,
ariela@mellanox.com, galp@mellanox.com,
jeffrey.t.kirsher@intel.com
Subject: [PATCH net-next 2/3] cxgb4: core hardware/firmware support for Forward Error Correction on a link
Date: Sat, 24 Jun 2017 12:19:44 -0700 [thread overview]
Message-ID: <1498331985-8525-3-git-send-email-roopa@cumulusnetworks.com> (raw)
In-Reply-To: <1498331985-8525-1-git-send-email-roopa@cumulusnetworks.com>
From: Casey Leedom <leedom@chelsio.com>
Signed-off-by: Casey Leedom <leedom@chelsio.com>
---
drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | 152 ++++++++++++++++++++++-------
1 file changed, 117 insertions(+), 35 deletions(-)
diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
index d5e316d..095894e 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
@@ -3690,11 +3690,64 @@ void t4_ulprx_read_la(struct adapter *adap, u32 *la_buf)
FW_PORT_CAP_SPEED_40G | FW_PORT_CAP_SPEED_100G | \
FW_PORT_CAP_ANEG)
+/* Translate Firmware Port Capabilities Pause specification to Common Code */
+static inline unsigned int fwcap_to_cc_pause(unsigned int fw_pause)
+{
+ unsigned int cc_pause = 0;
+
+ if (fw_pause & FW_PORT_CAP_FC_RX)
+ cc_pause |= PAUSE_RX;
+ if (fw_pause & FW_PORT_CAP_FC_TX)
+ cc_pause |= PAUSE_TX;
+
+ return cc_pause;
+}
+
+/* Translate Common Code Pause specification into Firmware Port Capabilities */
+static inline unsigned int cc_to_fwcap_pause(unsigned int cc_pause)
+{
+ unsigned int fw_pause = 0;
+
+ if (cc_pause & PAUSE_RX)
+ fw_pause |= FW_PORT_CAP_FC_RX;
+ if (cc_pause & PAUSE_TX)
+ fw_pause |= FW_PORT_CAP_FC_TX;
+
+ return fw_pause;
+}
+
+/* Translate Firmware Forward Error Correction specification to Common Code */
+static inline unsigned int fwcap_to_cc_fec(unsigned int fw_fec)
+{
+ unsigned int cc_fec = 0;
+
+ if (fw_fec & FW_PORT_CAP_FEC_RS)
+ cc_fec |= FEC_RS;
+ if (fw_fec & FW_PORT_CAP_FEC_BASER_RS)
+ cc_fec |= FEC_BASER_RS;
+
+ return cc_fec;
+}
+
+/* Translate Common Code Forward Error Correction specification to Firmware */
+static inline unsigned int cc_to_fwcap_fec(unsigned int cc_fec)
+{
+ unsigned int fw_fec = 0;
+
+ if (cc_fec & FEC_RS)
+ fw_fec |= FW_PORT_CAP_FEC_RS;
+ if (cc_fec & FEC_BASER_RS)
+ fw_fec |= FW_PORT_CAP_FEC_BASER_RS;
+
+ return fw_fec;
+}
+
/**
* t4_link_l1cfg - apply link configuration to MAC/PHY
- * @phy: the PHY to setup
- * @mac: the MAC to setup
- * @lc: the requested link configuration
+ * @adapter: the adapter
+ * @mbox: the Firmware Mailbox to use
+ * @port: the Port ID
+ * @lc: the Port's Link Configuration
*
* 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
@@ -3707,22 +3760,46 @@ int t4_link_l1cfg(struct adapter *adap, unsigned int mbox, unsigned int port,
struct link_config *lc)
{
struct fw_port_cmd c;
- unsigned int mdi = FW_PORT_CAP_MDI_V(FW_PORT_CAP_MDI_AUTO);
- unsigned int fc = 0, fec = 0, fw_fec = 0;
+ unsigned int fw_mdi = FW_PORT_CAP_MDI_V(FW_PORT_CAP_MDI_AUTO);
+ unsigned int fw_fc, cc_fec, fw_fec;
+ unsigned int rcap;
lc->link_ok = 0;
- if (lc->requested_fc & PAUSE_RX)
- fc |= FW_PORT_CAP_FC_RX;
- if (lc->requested_fc & PAUSE_TX)
- fc |= FW_PORT_CAP_FC_TX;
- fec = lc->requested_fec & FEC_AUTO ? lc->auto_fec : lc->requested_fec;
+ /* Convert driver coding of Pause Frame Flow Control settings into the
+ * Firmware's API.
+ */
+ 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);
- if (fec & FEC_RS)
- fw_fec |= FW_PORT_CAP_FEC_RS;
- if (fec & FEC_BASER_RS)
- fw_fec |= FW_PORT_CAP_FEC_BASER_RS;
+ /* Figure out what our Requested Port Capabilities are going to be.
+ */
+ if (!(lc->supported & FW_PORT_CAP_ANEG)) {
+ rcap = (lc->supported & ADVERT_MASK) | fw_fc | fw_fec;
+ lc->fc = lc->requested_fc & (PAUSE_RX | PAUSE_TX);
+ 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_RX | PAUSE_TX);
+ lc->fec = cc_fec;
+ } else {
+ rcap = lc->advertising | fw_fc | fw_fec | fw_mdi;
+ }
+ /* And send that on to the Firmware ...
+ */
memset(&c, 0, sizeof(c));
c.op_to_portid = cpu_to_be32(FW_CMD_OP_V(FW_PORT_CMD) |
FW_CMD_REQUEST_F | FW_CMD_EXEC_F |
@@ -3730,19 +3807,7 @@ int t4_link_l1cfg(struct adapter *adap, unsigned int mbox, unsigned int port,
c.action_to_len16 =
cpu_to_be32(FW_PORT_CMD_ACTION_V(FW_PORT_ACTION_L1_CFG) |
FW_LEN16(c));
-
- if (!(lc->supported & FW_PORT_CAP_ANEG)) {
- c.u.l1cfg.rcap = cpu_to_be32((lc->supported & ADVERT_MASK) |
- fc | fw_fec);
- lc->fc = lc->requested_fc & (PAUSE_RX | PAUSE_TX);
- } else if (lc->autoneg == AUTONEG_DISABLE) {
- c.u.l1cfg.rcap = cpu_to_be32(lc->requested_speed | fc |
- fw_fec | mdi);
- lc->fc = lc->requested_fc & (PAUSE_RX | PAUSE_TX);
- } else
- c.u.l1cfg.rcap = cpu_to_be32(lc->advertising | fc |
- fw_fec | mdi);
-
+ c.u.l1cfg.rcap = cpu_to_be32(rcap);
return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
}
@@ -7345,19 +7410,28 @@ static const char *t4_link_down_rc_str(unsigned char link_down_rc)
void t4_handle_get_port_info(struct port_info *pi, const __be64 *rpl)
{
const struct fw_port_cmd *p = (const void *)rpl;
+ unsigned int acaps = be16_to_cpu(p->u.info.acap);
struct adapter *adap = pi->adapter;
/* link/module state change message */
- int speed = 0, fc = 0;
+ int speed = 0, fc, fec;
struct link_config *lc;
u32 stat = be32_to_cpu(p->u.info.lstatus_to_modtype);
int link_ok = (stat & FW_PORT_CMD_LSTATUS_F) != 0;
u32 mod = FW_PORT_CMD_MODTYPE_G(stat);
+ /* Unfortunately the format of the Link Status returned by the
+ * Firmware isn't the same as the Firmware Port Capabilities bitfield
+ * used everywhere else ...
+ */
+ fc = 0;
if (stat & FW_PORT_CMD_RXPAUSE_F)
fc |= PAUSE_RX;
if (stat & FW_PORT_CMD_TXPAUSE_F)
fc |= PAUSE_TX;
+
+ fec = fwcap_to_cc_fec(acaps);
+
if (stat & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_100M))
speed = 100;
else if (stat & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_1G))
@@ -7374,11 +7448,20 @@ void t4_handle_get_port_info(struct port_info *pi, const __be64 *rpl)
lc = &pi->link_cfg;
if (mod != pi->mod_type) {
+ /* When a new Transceiver Module is inserted, the Firmware
+ * will examine any Forward Error Correction parameters
+ * present in the Transceiver Module i2c EPROM and determine
+ * the supported and recommended FEC settings from those
+ * based on IEEE 802.3 standards. We always record the
+ * IEEE 802.3 recommended "automatic" settings.
+ */
+ lc->auto_fec = fec;
+
pi->mod_type = mod;
t4_os_portmod_changed(adap, pi->port_id);
}
if (link_ok != lc->link_ok || speed != lc->speed ||
- fc != lc->fc) { /* something changed */
+ fc != lc->fc || fec != lc->fec) { /* something changed */
if (!link_ok && lc->link_ok) {
unsigned char rc = FW_PORT_CMD_LINKDNRC_G(stat);
@@ -7390,6 +7473,8 @@ void t4_handle_get_port_info(struct port_info *pi, const __be64 *rpl)
lc->link_ok = link_ok;
lc->speed = speed;
lc->fc = fc;
+ lc->fec = fec;
+
lc->supported = be16_to_cpu(p->u.info.pcap);
lc->lp_advertising = be16_to_cpu(p->u.info.lpacap);
@@ -7479,7 +7564,8 @@ static void get_pci_mode(struct adapter *adapter, struct pci_params *p)
/**
* init_link_config - initialize a link's SW state
* @lc: structure holding the link state
- * @caps: link capabilities
+ * @pcaps: link Port Capabilities
+ * @acaps: link current Advertised Port Capabilities
*
* Initializes the SW state maintained for each link, including the link's
* capabilities and default speed/flow-control/autonegotiation settings.
@@ -7492,15 +7578,11 @@ static void init_link_config(struct link_config *lc, unsigned int pcaps,
lc->requested_speed = 0;
lc->speed = 0;
lc->requested_fc = lc->fc = PAUSE_RX | PAUSE_TX;
- lc->auto_fec = 0;
/* For Forward Error Control, we default to whatever the Firmware
* tells us the Link is currently advertising.
*/
- if (acaps & FW_PORT_CAP_FEC_RS)
- lc->auto_fec |= FEC_RS;
- if (acaps & FW_PORT_CAP_FEC_BASER_RS)
- lc->auto_fec |= FEC_BASER_RS;
+ lc->auto_fec = fwcap_to_cc_fec(acaps);
lc->requested_fec = FEC_AUTO;
lc->fec = lc->auto_fec;
--
2.1.4
next prev parent reply other threads:[~2017-06-24 19:19 UTC|newest]
Thread overview: 32+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-06-24 19:19 [PATCH net-next 0/3] ethtool: support for forward error correction mode setting on a link Roopa Prabhu
2017-06-24 19:19 ` [PATCH net-next 1/3] net: ethtool: add support for forward error correction modes Roopa Prabhu
2017-06-25 13:38 ` Gal Pressman
2017-06-28 5:46 ` Dustin Byford
2017-06-29 15:49 ` Gal Pressman
2017-06-27 10:22 ` Jakub Kicinski
2017-06-28 6:27 ` Dustin Byford
2017-06-28 6:41 ` Jakub Kicinski
2017-06-28 13:41 ` Andrew Lunn
2017-06-28 21:47 ` Dustin Byford
2017-06-29 1:00 ` Jakub Kicinski
2017-07-06 18:53 ` Casey Leedom
2017-07-06 19:02 ` Jakub Kicinski
2017-07-06 21:06 ` Wyborny, Carolyn
2017-07-06 21:53 ` Casey Leedom
2017-07-06 22:16 ` Wyborny, Carolyn
2017-07-06 22:36 ` Andrew Lunn
2017-07-06 22:37 ` Casey Leedom
2017-07-06 22:33 ` Andrew Lunn
2017-07-06 22:47 ` Casey Leedom
2017-07-06 23:15 ` Andrew Lunn
2017-07-06 23:27 ` Jakub Kicinski
2017-07-06 23:39 ` Casey Leedom
2017-07-07 0:56 ` Andrew Lunn
2017-07-07 1:38 ` Dave Olson
2017-07-06 22:43 ` Jakub Kicinski
2017-07-06 22:57 ` Casey Leedom
2017-06-29 13:30 ` Andrew Lunn
2017-06-24 19:19 ` Roopa Prabhu [this message]
2017-06-27 3:16 ` [PATCH net-next 2/3] cxgb4: core hardware/firmware support for Forward Error Correction on a link David Miller
2017-06-24 19:19 ` [PATCH net-next 3/3] cxgb4: ethtool forward error correction management support Roopa Prabhu
2017-06-24 21:47 ` [PATCH net-next 0/3] ethtool: support for forward error correction mode setting on a link Andrew Lunn
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1498331985-8525-3-git-send-email-roopa@cumulusnetworks.com \
--to=roopa@cumulusnetworks.com \
--cc=ariela@mellanox.com \
--cc=davem@davemloft.net \
--cc=dustin@cumulusnetworks.com \
--cc=galp@mellanox.com \
--cc=jeffrey.t.kirsher@intel.com \
--cc=leedom@chelsio.com \
--cc=linville@tuxdriver.com \
--cc=manojmalviya@chelsio.com \
--cc=netdev@vger.kernel.org \
--cc=odedw@mellanox.com \
--cc=olson@cumulusnetworks.com \
--cc=santosh@chelsio.com \
--cc=vidya.chowdary@gmail.com \
--cc=yuval.mintz@qlogic.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).