DPDK patches and discussions
 help / color / mirror / Atom feed
From: Jiawen Wu <jiawenwu@trustnetic.com>
To: dev@dpdk.org
Cc: Jiawen Wu <jiawenwu@trustnetic.com>
Subject: [dpdk-dev] [PATCH v1 37/42] net/txgbe: add FC auto negotiation support
Date: Tue,  1 Sep 2020 19:51:08 +0800	[thread overview]
Message-ID: <20200901115113.1529675-37-jiawenwu@trustnetic.com> (raw)
In-Reply-To: <20200901115113.1529675-1-jiawenwu@trustnetic.com>

Add flow control negotitation with link partner.

Signed-off-by: Jiawen Wu <jiawenwu@trustnetic.com>
---
 drivers/net/txgbe/base/txgbe_hw.c | 201 ++++++++++++++++++++++++++++++
 drivers/net/txgbe/base/txgbe_hw.h |   4 +-
 2 files changed, 204 insertions(+), 1 deletion(-)

diff --git a/drivers/net/txgbe/base/txgbe_hw.c b/drivers/net/txgbe/base/txgbe_hw.c
index 34e7c3d1e..164d3b5b8 100644
--- a/drivers/net/txgbe/base/txgbe_hw.c
+++ b/drivers/net/txgbe/base/txgbe_hw.c
@@ -1061,6 +1061,205 @@ s32 txgbe_fc_enable(struct txgbe_hw *hw)
 	return err;
 }
 
+/**
+ *  txgbe_negotiate_fc - Negotiate flow control
+ *  @hw: pointer to hardware structure
+ *  @adv_reg: flow control advertised settings
+ *  @lp_reg: link partner's flow control settings
+ *  @adv_sym: symmetric pause bit in advertisement
+ *  @adv_asm: asymmetric pause bit in advertisement
+ *  @lp_sym: symmetric pause bit in link partner advertisement
+ *  @lp_asm: asymmetric pause bit in link partner advertisement
+ *
+ *  Find the intersection between advertised settings and link partner's
+ *  advertised settings
+ **/
+s32 txgbe_negotiate_fc(struct txgbe_hw *hw, u32 adv_reg, u32 lp_reg,
+		       u32 adv_sym, u32 adv_asm, u32 lp_sym, u32 lp_asm)
+{
+	if ((!(adv_reg)) ||  (!(lp_reg))) {
+		DEBUGOUT("Local or link partner's advertised flow control "
+			      "settings are NULL. Local: %x, link partner: %x\n",
+			      adv_reg, lp_reg);
+		return TXGBE_ERR_FC_NOT_NEGOTIATED;
+	}
+
+	if ((adv_reg & adv_sym) && (lp_reg & lp_sym)) {
+		/*
+		 * Now we need to check if the user selected Rx ONLY
+		 * of pause frames.  In this case, we had to advertise
+		 * FULL flow control because we could not advertise RX
+		 * ONLY. Hence, we must now check to see if we need to
+		 * turn OFF the TRANSMISSION of PAUSE frames.
+		 */
+		if (hw->fc.requested_mode == txgbe_fc_full) {
+			hw->fc.current_mode = txgbe_fc_full;
+			DEBUGOUT("Flow Control = FULL.\n");
+		} else {
+			hw->fc.current_mode = txgbe_fc_rx_pause;
+			DEBUGOUT("Flow Control=RX PAUSE frames only\n");
+		}
+	} else if (!(adv_reg & adv_sym) && (adv_reg & adv_asm) &&
+		   (lp_reg & lp_sym) && (lp_reg & lp_asm)) {
+		hw->fc.current_mode = txgbe_fc_tx_pause;
+		DEBUGOUT("Flow Control = TX PAUSE frames only.\n");
+	} else if ((adv_reg & adv_sym) && (adv_reg & adv_asm) &&
+		   !(lp_reg & lp_sym) && (lp_reg & lp_asm)) {
+		hw->fc.current_mode = txgbe_fc_rx_pause;
+		DEBUGOUT("Flow Control = RX PAUSE frames only.\n");
+	} else {
+		hw->fc.current_mode = txgbe_fc_none;
+		DEBUGOUT("Flow Control = NONE.\n");
+	}
+	return 0;
+}
+
+/**
+ *  txgbe_fc_autoneg_fiber - Enable flow control on 1 gig fiber
+ *  @hw: pointer to hardware structure
+ *
+ *  Enable flow control according on 1 gig fiber.
+ **/
+STATIC s32 txgbe_fc_autoneg_fiber(struct txgbe_hw *hw)
+{
+	u32 pcs_anadv_reg, pcs_lpab_reg;
+	s32 err = TXGBE_ERR_FC_NOT_NEGOTIATED;
+
+	/*
+	 * On multispeed fiber at 1g, bail out if
+	 * - link is up but AN did not complete, or if
+	 * - link is up and AN completed but timed out
+	 */
+
+	pcs_anadv_reg = rd32_epcs(hw, SR_MII_MMD_AN_ADV);
+	pcs_lpab_reg = rd32_epcs(hw, SR_MII_MMD_LP_BABL);
+
+	err =  txgbe_negotiate_fc(hw, pcs_anadv_reg,
+				      pcs_lpab_reg,
+				      SR_MII_MMD_AN_ADV_PAUSE_SYM,
+				      SR_MII_MMD_AN_ADV_PAUSE_ASM,
+				      SR_MII_MMD_AN_ADV_PAUSE_SYM,
+				      SR_MII_MMD_AN_ADV_PAUSE_ASM);
+
+	return err;
+}
+
+/**
+ *  txgbe_fc_autoneg_backplane - Enable flow control IEEE clause 37
+ *  @hw: pointer to hardware structure
+ *
+ *  Enable flow control according to IEEE clause 37.
+ **/
+STATIC s32 txgbe_fc_autoneg_backplane(struct txgbe_hw *hw)
+{
+	u32 anlp1_reg, autoc_reg;
+	s32 err = TXGBE_ERR_FC_NOT_NEGOTIATED;
+
+	/*
+	 * Read the 10g AN autoc and LP ability registers and resolve
+	 * local flow control settings accordingly
+	 */
+	autoc_reg = rd32_epcs(hw, SR_AN_MMD_ADV_REG1);
+	anlp1_reg = rd32_epcs(hw, SR_AN_MMD_LP_ABL1);
+
+	err = txgbe_negotiate_fc(hw, autoc_reg,
+		anlp1_reg,
+		SR_AN_MMD_ADV_REG1_PAUSE_SYM,
+		SR_AN_MMD_ADV_REG1_PAUSE_ASM,
+		SR_AN_MMD_ADV_REG1_PAUSE_SYM,
+		SR_AN_MMD_ADV_REG1_PAUSE_ASM);
+
+	return err;
+}
+
+/**
+ *  txgbe_fc_autoneg_copper - Enable flow control IEEE clause 37
+ *  @hw: pointer to hardware structure
+ *
+ *  Enable flow control according to IEEE clause 37.
+ **/
+STATIC s32 txgbe_fc_autoneg_copper(struct txgbe_hw *hw)
+{
+	u16 technology_ability_reg = 0;
+	u16 lp_technology_ability_reg = 0;
+
+	hw->phy.read_reg(hw, TXGBE_MD_AUTO_NEG_ADVT,
+			     TXGBE_MD_DEV_AUTO_NEG,
+			     &technology_ability_reg);
+	hw->phy.read_reg(hw, TXGBE_MD_AUTO_NEG_LP,
+			     TXGBE_MD_DEV_AUTO_NEG,
+			     &lp_technology_ability_reg);
+
+	return txgbe_negotiate_fc(hw, (u32)technology_ability_reg,
+				  (u32)lp_technology_ability_reg,
+				  TXGBE_TAF_SYM_PAUSE, TXGBE_TAF_ASM_PAUSE,
+				  TXGBE_TAF_SYM_PAUSE, TXGBE_TAF_ASM_PAUSE);
+}
+
+/**
+ *  txgbe_fc_autoneg - Configure flow control
+ *  @hw: pointer to hardware structure
+ *
+ *  Compares our advertised flow control capabilities to those advertised by
+ *  our link partner, and determines the proper flow control mode to use.
+ **/
+void txgbe_fc_autoneg(struct txgbe_hw *hw)
+{
+	s32 err = TXGBE_ERR_FC_NOT_NEGOTIATED;
+	u32 speed;
+	bool link_up;
+
+	DEBUGFUNC("txgbe_fc_autoneg");
+
+	/*
+	 * AN should have completed when the cable was plugged in.
+	 * Look for reasons to bail out.  Bail out if:
+	 * - FC autoneg is disabled, or if
+	 * - link is not up.
+	 */
+	if (hw->fc.disable_fc_autoneg) {
+		DEBUGOUT("Flow control autoneg is disabled");
+		goto out;
+	}
+
+	hw->mac.check_link(hw, &speed, &link_up, false);
+	if (!link_up) {
+		DEBUGOUT("The link is down");
+		goto out;
+	}
+
+	switch (hw->phy.media_type) {
+	/* Autoneg flow control on fiber adapters */
+	case txgbe_media_type_fiber_qsfp:
+	case txgbe_media_type_fiber:
+		if (speed == TXGBE_LINK_SPEED_1GB_FULL)
+			err = txgbe_fc_autoneg_fiber(hw);
+		break;
+
+	/* Autoneg flow control on backplane adapters */
+	case txgbe_media_type_backplane:
+		err = txgbe_fc_autoneg_backplane(hw);
+		break;
+
+	/* Autoneg flow control on copper adapters */
+	case txgbe_media_type_copper:
+		if (txgbe_device_supports_autoneg_fc(hw))
+			err = txgbe_fc_autoneg_copper(hw);
+		break;
+
+	default:
+		break;
+	}
+
+out:
+	if (err == 0) {
+		hw->fc.fc_was_autonegged = true;
+	} else {
+		hw->fc.fc_was_autonegged = false;
+		hw->fc.current_mode = hw->fc.requested_mode;
+	}
+}
+
 /**
  *  txgbe_acquire_swfw_sync - Acquire SWFW semaphore
  *  @hw: pointer to hardware structure
@@ -2146,6 +2345,8 @@ s32 txgbe_init_ops_pf(struct txgbe_hw *hw)
 	/* Flow Control */
 	mac->fc_enable = txgbe_fc_enable;
 	mac->setup_fc = txgbe_setup_fc;
+	mac->fc_autoneg = txgbe_fc_autoneg;
+
 	/* Link */
 	mac->get_link_capabilities = txgbe_get_link_capabilities_raptor;
 	mac->check_link = txgbe_check_mac_link;
diff --git a/drivers/net/txgbe/base/txgbe_hw.h b/drivers/net/txgbe/base/txgbe_hw.h
index 1604d1fca..047c71ecf 100644
--- a/drivers/net/txgbe/base/txgbe_hw.h
+++ b/drivers/net/txgbe/base/txgbe_hw.h
@@ -11,7 +11,6 @@ s32 txgbe_init_hw(struct txgbe_hw *hw);
 s32 txgbe_start_hw(struct txgbe_hw *hw);
 s32 txgbe_stop_hw(struct txgbe_hw *hw);
 s32 txgbe_start_hw_gen2(struct txgbe_hw *hw);
-s32 txgbe_start_hw_raptor(struct txgbe_hw *hw);
 s32 txgbe_clear_hw_cntrs(struct txgbe_hw *hw);
 s32 txgbe_get_mac_addr(struct txgbe_hw *hw, u8 *mac_addr);
 
@@ -34,6 +33,7 @@ s32 txgbe_enable_sec_tx_path(struct txgbe_hw *hw);
 
 s32 txgbe_fc_enable(struct txgbe_hw *hw);
 bool txgbe_device_supports_autoneg_fc(struct txgbe_hw *hw);
+void txgbe_fc_autoneg(struct txgbe_hw *hw);
 s32 txgbe_setup_fc(struct txgbe_hw *hw);
 
 s32 txgbe_validate_mac_addr(u8 *mac_addr);
@@ -62,6 +62,8 @@ s32 txgbe_setup_mac_link_multispeed_fiber(struct txgbe_hw *hw,
 					  u32 speed,
 					  bool autoneg_wait_to_complete);
 void txgbe_set_mta(struct txgbe_hw *hw, u8 *mc_addr);
+s32 txgbe_negotiate_fc(struct txgbe_hw *hw, u32 adv_reg, u32 lp_reg,
+			u32 adv_sym, u32 adv_asm, u32 lp_sym, u32 lp_asm);
 s32 txgbe_init_shared_code(struct txgbe_hw *hw);
 s32 txgbe_set_mac_type(struct txgbe_hw *hw);
 s32 txgbe_init_ops_pf(struct txgbe_hw *hw);
-- 
2.18.4




  parent reply	other threads:[~2020-09-01 11:58 UTC|newest]

Thread overview: 49+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-09-01 11:50 [dpdk-dev] [PATCH v1 01/42] net/txgbe: add build and doc infrastructure Jiawen Wu
2020-09-01 11:50 ` [dpdk-dev] [PATCH v1 02/42] net/txgbe: add ethdev probe and remove Jiawen Wu
2020-09-09 17:50   ` Ferruh Yigit
2020-09-01 11:50 ` [dpdk-dev] [PATCH v1 03/42] net/txgbe: add device init and uninit Jiawen Wu
2020-09-09 17:52   ` Ferruh Yigit
2020-09-01 11:50 ` [dpdk-dev] [PATCH v1 04/42] net/txgbe: add error types and dummy function Jiawen Wu
2020-09-01 11:50 ` [dpdk-dev] [PATCH v1 05/42] net/txgbe: add mac type and HW ops dummy Jiawen Wu
2020-09-01 11:50 ` [dpdk-dev] [PATCH v1 06/42] net/txgbe: add EEPROM functions Jiawen Wu
2020-09-01 11:50 ` [dpdk-dev] [PATCH v1 07/42] net/txgbe: add HW init function Jiawen Wu
2020-09-01 11:50 ` [dpdk-dev] [PATCH v1 08/42] net/txgbe: add HW reset operation Jiawen Wu
2020-09-01 11:50 ` [dpdk-dev] [PATCH v1 09/42] net/txgbe: add PHY init Jiawen Wu
2020-09-01 11:50 ` [dpdk-dev] [PATCH v1 10/42] net/txgbe: add module identify Jiawen Wu
2020-09-01 11:50 ` [dpdk-dev] [PATCH v1 11/42] net/txgbe: add PHY reset Jiawen Wu
2020-09-01 11:50 ` [dpdk-dev] [PATCH v1 12/42] net/txgbe: add device start and stop Jiawen Wu
2020-09-01 11:50 ` [dpdk-dev] [PATCH v1 13/42] net/txgbe: add interrupt operation Jiawen Wu
2020-09-01 11:50 ` [dpdk-dev] [PATCH v1 14/42] net/txgbe: add link status change Jiawen Wu
2020-09-01 11:50 ` [dpdk-dev] [PATCH v1 15/42] net/txgbe: add multi-speed link setup Jiawen Wu
2020-09-01 11:50 ` [dpdk-dev] [PATCH v1 16/42] net/txgbe: add autoc read and write Jiawen Wu
2020-09-01 11:50 ` [dpdk-dev] [PATCH v1 17/42] net/txgbe: support device LED on and off Jiawen Wu
2020-09-01 11:50 ` [dpdk-dev] [PATCH v1 18/42] net/txgbe: add rx and tx init Jiawen Wu
2020-09-01 11:50 ` [dpdk-dev] [PATCH v1 19/42] net/txgbe: add RX and TX start Jiawen Wu
2020-09-01 11:50 ` [dpdk-dev] [PATCH v1 20/42] net/txgbe: add RX and TX stop Jiawen Wu
2020-09-01 11:50 ` [dpdk-dev] [PATCH v1 21/42] net/txgbe: add RX and TX queues setup Jiawen Wu
2020-09-01 11:50 ` [dpdk-dev] [PATCH v1 22/42] net/txgbe: add packet type Jiawen Wu
2020-09-01 11:50 ` [dpdk-dev] [PATCH v1 23/42] net/txgbe: fill simple transmit function Jiawen Wu
2020-09-01 11:50 ` [dpdk-dev] [PATCH v1 24/42] net/txgbe: fill transmit function with hardware offload Jiawen Wu
2020-09-01 11:50 ` [dpdk-dev] [PATCH v1 25/42] net/txgbe: fill receive functions Jiawen Wu
2020-09-01 11:50 ` [dpdk-dev] [PATCH v1 26/42] net/txgbe: fill TX prepare funtion Jiawen Wu
2020-09-01 11:50 ` [dpdk-dev] [PATCH v1 27/42] net/txgbe: add device stats get Jiawen Wu
2020-09-01 11:50 ` [dpdk-dev] [PATCH v1 28/42] net/txgbe: add device xstats get Jiawen Wu
2020-09-09 17:53   ` Ferruh Yigit
2020-09-01 11:51 ` [dpdk-dev] [PATCH v1 29/42] net/txgbe: add queue stats mapping and enable RX DMA unit Jiawen Wu
2020-09-09 17:54   ` Ferruh Yigit
2020-09-01 11:51 ` [dpdk-dev] [PATCH v1 30/42] net/txgbe: add device info get Jiawen Wu
2020-09-09 17:54   ` Ferruh Yigit
2020-09-01 11:51 ` [dpdk-dev] [PATCH v1 31/42] net/txgbe: add MAC address operations Jiawen Wu
2020-09-01 11:51 ` [dpdk-dev] [PATCH v1 32/42] net/txgbe: add FW version get operation Jiawen Wu
2020-09-01 11:51 ` [dpdk-dev] [PATCH v1 33/42] net/txgbe: add EEPROM info " Jiawen Wu
2020-09-01 11:51 ` [dpdk-dev] [PATCH v1 34/42] net/txgbe: add remaining RX and TX queue operations Jiawen Wu
2020-09-09 18:15   ` Ferruh Yigit
2020-09-01 11:51 ` [dpdk-dev] [PATCH v1 35/42] net/txgbe: add VLAN handle support Jiawen Wu
2020-09-01 11:51 ` [dpdk-dev] [PATCH v1 36/42] net/txgbe: add flow control support Jiawen Wu
2020-09-01 11:51 ` Jiawen Wu [this message]
2020-09-01 11:51 ` [dpdk-dev] [PATCH v1 38/42] net/txgbe: add DCB packet buffer allocation Jiawen Wu
2020-09-01 11:51 ` [dpdk-dev] [PATCH v1 39/42] net/txgbe: configure DCB HW resources Jiawen Wu
2020-09-01 11:51 ` [dpdk-dev] [PATCH v1 40/42] net/txgbe: add device promiscuous and allmulticast mode Jiawen Wu
2020-09-01 11:51 ` [dpdk-dev] [PATCH v1 41/42] net/txgbe: add MTU set operation Jiawen Wu
2020-09-01 11:51 ` [dpdk-dev] [PATCH v1 42/42] net/txgbe: add register dump support Jiawen Wu
2020-09-09 17:48 ` [dpdk-dev] [PATCH v1 01/42] net/txgbe: add build and doc infrastructure Ferruh Yigit

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=20200901115113.1529675-37-jiawenwu@trustnetic.com \
    --to=jiawenwu@trustnetic.com \
    --cc=dev@dpdk.org \
    /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).