Add GPIO configuration for Amber-Lite NICs to match design differences
from 10G NICs: The Amber-Lite NIC requires additional setup steps
compared to 10G NICs to ensure proper functionality of features
SFP module detection.

Signed-off-by: Zaiyu Wang <zaiyuw...@trustnetic.com>
---
 drivers/net/txgbe/base/txgbe_regs.h |   2 +
 drivers/net/txgbe/txgbe_ethdev.c    | 111 ++++++++++++++++++++++++++++
 2 files changed, 113 insertions(+)

diff --git a/drivers/net/txgbe/base/txgbe_regs.h 
b/drivers/net/txgbe/base/txgbe_regs.h
index 86f88e31fe..98d1070daa 100644
--- a/drivers/net/txgbe/base/txgbe_regs.h
+++ b/drivers/net/txgbe/base/txgbe_regs.h
@@ -1626,6 +1626,8 @@ enum txgbe_5tuple_protocol {
 #define TXGBE_GPIOINTEN                 0x014830
 #define TXGBE_GPIOINTMASK               0x014834
 #define TXGBE_GPIOINTTYPE               0x014838
+#define TXGBE_GPIO_INT_POLARITY         0x01483C
+#define   TXGBE_GPIO_INT_POLARITY_3     MS(3, 0x1)
 #define TXGBE_GPIOINTSTAT               0x014840
 #define TXGBE_GPIORAWINTSTAT            0x014844
 #define TXGBE_GPIOEOI                   0x01484C
diff --git a/drivers/net/txgbe/txgbe_ethdev.c b/drivers/net/txgbe/txgbe_ethdev.c
index 374d6452f4..9fd4923b6d 100644
--- a/drivers/net/txgbe/txgbe_ethdev.c
+++ b/drivers/net/txgbe/txgbe_ethdev.c
@@ -353,11 +353,33 @@ txgbe_enable_intr(struct rte_eth_dev *dev)
 {
        struct txgbe_interrupt *intr = TXGBE_DEV_INTR(dev);
        struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
+       uint32_t gpie;
 
        wr32(hw, TXGBE_IENMISC, intr->mask_misc);
        wr32(hw, TXGBE_IMC(0), TXGBE_IMC_MASK);
        wr32(hw, TXGBE_IMC(1), TXGBE_IMC_MASK);
        txgbe_flush(hw);
+
+       /* To avoid gpio intr lost, enable pcie intr first. Then enable gpio 
intr. */
+       if (hw->mac.type == txgbe_mac_aml) {
+               gpie = rd32(hw, TXGBE_GPIOINTEN);
+               gpie |= TXGBE_GPIOBIT_2 | TXGBE_GPIOBIT_3 | TXGBE_GPIOBIT_6;
+               wr32(hw, TXGBE_GPIOINTEN, gpie);
+
+               gpie = rd32(hw, TXGBE_GPIOINTTYPE);
+               gpie |= TXGBE_GPIOBIT_2 | TXGBE_GPIOBIT_3 | TXGBE_GPIOBIT_6;
+               wr32(hw, TXGBE_GPIOINTTYPE, gpie);
+       }
+
+       if (hw->mac.type == txgbe_mac_aml40) {
+               gpie = rd32(hw, TXGBE_GPIOINTEN);
+               gpie |= TXGBE_GPIOBIT_4;
+               wr32(hw, TXGBE_GPIOINTEN, gpie);
+
+               gpie = rd32(hw, TXGBE_GPIOINTTYPE);
+               gpie |= TXGBE_GPIOBIT_4;
+               wr32(hw, TXGBE_GPIOINTTYPE, gpie);
+       }
 }
 
 static void
@@ -1711,6 +1733,7 @@ txgbe_dev_start(struct rte_eth_dev *dev)
        uint16_t vf, idx;
        uint32_t *link_speeds;
        struct txgbe_tm_conf *tm_conf = TXGBE_DEV_TM_CONF(dev);
+       u32 links_reg;
 
        PMD_INIT_FUNC_TRACE();
 
@@ -1892,6 +1915,44 @@ txgbe_dev_start(struct rte_eth_dev *dev)
        if (err)
                goto error;
 
+       if (hw->mac.type == txgbe_mac_aml) {
+               links_reg = rd32(hw, TXGBE_PORT);
+               if (links_reg & TXGBE_PORT_LINKUP) {
+                       if (links_reg & TXGBE_CFG_PORT_ST_AML_LINK_25G) {
+                               wr32(hw, TXGBE_MACTXCFG,
+                                       (rd32(hw, TXGBE_MACTXCFG) &
+                                       ~TXGBE_MAC_TX_CFG_AML_SPEED_MASK) |
+                                       TXGBE_MAC_TX_CFG_AML_SPEED_25G);
+                       } else if (links_reg & TXGBE_CFG_PORT_ST_AML_LINK_10G) {
+                               wr32(hw, TXGBE_MACTXCFG,
+                                       (rd32(hw, TXGBE_MACTXCFG) &
+                                       ~TXGBE_MAC_TX_CFG_AML_SPEED_MASK) |
+                                       TXGBE_MAC_TX_CFG_AML_SPEED_10G);
+                       }
+               }
+
+               /* amlite: restart gpio */
+               wr32(hw, TXGBE_GPIODIR, TXGBE_GPIOBIT_0 | TXGBE_GPIOBIT_1 |
+                                       TXGBE_GPIOBIT_4 | TXGBE_GPIOBIT_5);
+               wr32(hw, TXGBE_GPIODATA, TXGBE_GPIOBIT_4 | TXGBE_GPIOBIT_5);
+               msleep(10);
+               wr32(hw, TXGBE_GPIODATA, TXGBE_GPIOBIT_0);
+               wr32m(hw, TXGBE_GPIO_INT_POLARITY, TXGBE_GPIO_INT_POLARITY_3, 
0x0);
+       } else if (hw->mac.type == txgbe_mac_aml40) {
+               links_reg = rd32(hw, TXGBE_PORT);
+               if (links_reg & TXGBE_PORT_LINKUP) {
+                       if (links_reg & TXGBE_CFG_PORT_ST_AML_LINK_40G) {
+                               wr32(hw, TXGBE_MACTXCFG,
+                                       (rd32(hw, TXGBE_MACTXCFG) &
+                                       ~TXGBE_MAC_TX_CFG_AML_SPEED_MASK) |
+                                       TXGBE_MAC_TX_CFG_AML_SPEED_40G);
+                       }
+               }
+
+               wr32(hw, TXGBE_GPIODIR, TXGBE_GPIOBIT_0 | TXGBE_GPIOBIT_1
+                                                       | TXGBE_GPIOBIT_3);
+               wr32(hw, TXGBE_GPIODATA, TXGBE_GPIOBIT_1);
+       }
 skip_link_setup:
 
        if (rte_intr_allow_others(intr_handle)) {
@@ -1989,6 +2050,10 @@ txgbe_dev_stop(struct rte_eth_dev *dev)
        for (vf = 0; vfinfo != NULL && vf < pci_dev->max_vfs; vf++)
                vfinfo[vf].clear_to_send = false;
 
+       if (hw->mac.type == txgbe_mac_aml)
+               wr32m(hw, TXGBE_AML_EPCS_MISC_CTL,
+                         TXGBE_AML_LINK_STATUS_OVRD_EN, 0x0);
+
        txgbe_dev_clear_queues(dev);
 
        /* Clear stored conf */
@@ -2867,6 +2932,27 @@ txgbe_dev_sfp_event(struct rte_eth_dev *dev)
                intr->flags |= TXGBE_FLAG_NEED_LINK_UPDATE;
        }
 
+       if (hw->mac.type == txgbe_mac_aml40) {
+               if (reg & TXGBE_GPIOBIT_4) {
+                       wr32(hw, TXGBE_GPIOEOI, TXGBE_GPIOBIT_4);
+                       rte_eal_alarm_set(1000 * 100, txgbe_dev_detect_sfp, 
dev);
+               }
+       } else if (hw->mac.type == txgbe_mac_raptor || hw->mac.type == 
txgbe_mac_aml) {
+               if (reg & TXGBE_GPIOBIT_0)
+                       wr32(hw, TXGBE_GPIOEOI, TXGBE_GPIOBIT_0);
+               if (reg & TXGBE_GPIOBIT_2) {
+                       wr32(hw, TXGBE_GPIOEOI, TXGBE_GPIOBIT_2);
+                       rte_eal_alarm_set(1000 * 100, txgbe_dev_detect_sfp, 
dev);
+               }
+               if (reg & TXGBE_GPIOBIT_3) {
+                       wr32(hw, TXGBE_GPIOEOI, TXGBE_GPIOBIT_3);
+                       intr->flags |= TXGBE_FLAG_NEED_LINK_UPDATE;
+               }
+               if (reg & TXGBE_GPIOBIT_6) {
+                       wr32(hw, TXGBE_GPIOEOI, TXGBE_GPIOBIT_6);
+                       intr->flags |= TXGBE_FLAG_NEED_LINK_UPDATE;
+               }
+       }
        wr32(hw, TXGBE_GPIOINTMASK, 0);
 }
 
@@ -3044,6 +3130,9 @@ txgbe_dev_link_update_share(struct rte_eth_dev *dev,
        }
 
        if (link_up == 0) {
+               if (hw->mac.type == txgbe_mac_aml)
+                       wr32m(hw, TXGBE_GPIO_INT_POLARITY,
+                                 TXGBE_GPIO_INT_POLARITY_3, 0x0);
                if ((hw->subsystem_device_id & 0xFF) ==
                                TXGBE_DEV_ID_KR_KX_KX4) {
                        hw->mac.bp_down_event(hw);
@@ -3130,6 +3219,28 @@ txgbe_dev_link_update_share(struct rte_eth_dev *dev,
                wr32(hw, TXGBE_MAC_WDG_TIMEOUT, reg);
        }
 
+       if (hw->mac.type == txgbe_mac_aml || hw->mac.type == txgbe_mac_aml40) {
+               reg = rd32(hw, TXGBE_PORT);
+               if (reg & TXGBE_PORT_LINKUP) {
+                       if (reg & TXGBE_CFG_PORT_ST_AML_LINK_40G) {
+                               wr32(hw, TXGBE_MACTXCFG,
+                                       (rd32(hw, TXGBE_MACTXCFG) &
+                                       ~TXGBE_MAC_TX_CFG_AML_SPEED_MASK) | 
TXGBE_MACTXCFG_TXE |
+                                       TXGBE_MAC_TX_CFG_AML_SPEED_40G);
+                       } else if (reg & TXGBE_CFG_PORT_ST_AML_LINK_25G) {
+                               wr32(hw, TXGBE_MACTXCFG,
+                                       (rd32(hw, TXGBE_MACTXCFG) &
+                                       ~TXGBE_MAC_TX_CFG_AML_SPEED_MASK) | 
TXGBE_MACTXCFG_TXE |
+                                       TXGBE_MAC_TX_CFG_AML_SPEED_25G);
+                       } else if (reg & TXGBE_CFG_PORT_ST_AML_LINK_10G) {
+                               wr32(hw, TXGBE_MACTXCFG,
+                                       (rd32(hw, TXGBE_MACTXCFG) &
+                                       ~TXGBE_MAC_TX_CFG_AML_SPEED_MASK) | 
TXGBE_MACTXCFG_TXE |
+                                       TXGBE_MAC_TX_CFG_AML_SPEED_10G);
+                       }
+               }
+       }
+
        return rte_eth_linkstatus_set(dev, &link);
 }
 
-- 
2.21.0.windows.1

Reply via email to