]> git.baikalelectronics.ru Git - kernel.git/commitdiff
amd-xgbe: TX Flow Ctrl Registers are h/w ver dependent
authorRaju Rangoju <Raju.Rangoju@amd.com>
Wed, 11 Jan 2023 17:28:51 +0000 (22:58 +0530)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 6 Feb 2023 06:52:36 +0000 (07:52 +0100)
[ Upstream commit 579923d84b04abb6cd4cd1fd9974096a2dd1832b ]

There is difference in the TX Flow Control registers (TFCR) between the
revisions of the hardware. The older revisions of hardware used to have
single register per queue. Whereas, the newer revision of hardware (from
ver 30H onwards) have one register per priority.

Update the driver to use the TFCR based on the reported version of the
hardware.

Fixes: 0756e71c9ef1 ("amd-xgbe: Initial AMD 10GbE platform driver")
Co-developed-by: Ajith Nayak <Ajith.Nayak@amd.com>
Signed-off-by: Ajith Nayak <Ajith.Nayak@amd.com>
Signed-off-by: Raju Rangoju <Raju.Rangoju@amd.com>
Acked-by: Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/net/ethernet/amd/xgbe/xgbe-dev.c

index d5fd49dd25f336aedbe166a8c6bdd74ef6296204..decc1c09a031b4b61e554e08e5480c66734034ae 100644 (file)
@@ -524,19 +524,28 @@ static void xgbe_disable_vxlan(struct xgbe_prv_data *pdata)
        netif_dbg(pdata, drv, pdata->netdev, "VXLAN acceleration disabled\n");
 }
 
+static unsigned int xgbe_get_fc_queue_count(struct xgbe_prv_data *pdata)
+{
+       unsigned int max_q_count = XGMAC_MAX_FLOW_CONTROL_QUEUES;
+
+       /* From MAC ver 30H the TFCR is per priority, instead of per queue */
+       if (XGMAC_GET_BITS(pdata->hw_feat.version, MAC_VR, SNPSVER) >= 0x30)
+               return max_q_count;
+       else
+               return min_t(unsigned int, pdata->tx_q_count, max_q_count);
+}
+
 static int xgbe_disable_tx_flow_control(struct xgbe_prv_data *pdata)
 {
-       unsigned int max_q_count, q_count;
        unsigned int reg, reg_val;
-       unsigned int i;
+       unsigned int i, q_count;
 
        /* Clear MTL flow control */
        for (i = 0; i < pdata->rx_q_count; i++)
                XGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_Q_RQOMR, EHFC, 0);
 
        /* Clear MAC flow control */
-       max_q_count = XGMAC_MAX_FLOW_CONTROL_QUEUES;
-       q_count = min_t(unsigned int, pdata->tx_q_count, max_q_count);
+       q_count = xgbe_get_fc_queue_count(pdata);
        reg = MAC_Q0TFCR;
        for (i = 0; i < q_count; i++) {
                reg_val = XGMAC_IOREAD(pdata, reg);
@@ -553,9 +562,8 @@ static int xgbe_enable_tx_flow_control(struct xgbe_prv_data *pdata)
 {
        struct ieee_pfc *pfc = pdata->pfc;
        struct ieee_ets *ets = pdata->ets;
-       unsigned int max_q_count, q_count;
        unsigned int reg, reg_val;
-       unsigned int i;
+       unsigned int i, q_count;
 
        /* Set MTL flow control */
        for (i = 0; i < pdata->rx_q_count; i++) {
@@ -579,8 +587,7 @@ static int xgbe_enable_tx_flow_control(struct xgbe_prv_data *pdata)
        }
 
        /* Set MAC flow control */
-       max_q_count = XGMAC_MAX_FLOW_CONTROL_QUEUES;
-       q_count = min_t(unsigned int, pdata->tx_q_count, max_q_count);
+       q_count = xgbe_get_fc_queue_count(pdata);
        reg = MAC_Q0TFCR;
        for (i = 0; i < q_count; i++) {
                reg_val = XGMAC_IOREAD(pdata, reg);