Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

amd-xgbe: TX Flow Ctrl Registers are h/w ver dependent

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: c5aa9e3b8156 ("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>

authored by

Raju Rangoju and committed by
Jakub Kicinski
579923d8 0ea90f36

+15 -8
+15 -8
drivers/net/ethernet/amd/xgbe/xgbe-dev.c
··· 524 524 netif_dbg(pdata, drv, pdata->netdev, "VXLAN acceleration disabled\n"); 525 525 } 526 526 527 + static unsigned int xgbe_get_fc_queue_count(struct xgbe_prv_data *pdata) 528 + { 529 + unsigned int max_q_count = XGMAC_MAX_FLOW_CONTROL_QUEUES; 530 + 531 + /* From MAC ver 30H the TFCR is per priority, instead of per queue */ 532 + if (XGMAC_GET_BITS(pdata->hw_feat.version, MAC_VR, SNPSVER) >= 0x30) 533 + return max_q_count; 534 + else 535 + return min_t(unsigned int, pdata->tx_q_count, max_q_count); 536 + } 537 + 527 538 static int xgbe_disable_tx_flow_control(struct xgbe_prv_data *pdata) 528 539 { 529 - unsigned int max_q_count, q_count; 530 540 unsigned int reg, reg_val; 531 - unsigned int i; 541 + unsigned int i, q_count; 532 542 533 543 /* Clear MTL flow control */ 534 544 for (i = 0; i < pdata->rx_q_count; i++) 535 545 XGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_Q_RQOMR, EHFC, 0); 536 546 537 547 /* Clear MAC flow control */ 538 - max_q_count = XGMAC_MAX_FLOW_CONTROL_QUEUES; 539 - q_count = min_t(unsigned int, pdata->tx_q_count, max_q_count); 548 + q_count = xgbe_get_fc_queue_count(pdata); 540 549 reg = MAC_Q0TFCR; 541 550 for (i = 0; i < q_count; i++) { 542 551 reg_val = XGMAC_IOREAD(pdata, reg); ··· 562 553 { 563 554 struct ieee_pfc *pfc = pdata->pfc; 564 555 struct ieee_ets *ets = pdata->ets; 565 - unsigned int max_q_count, q_count; 566 556 unsigned int reg, reg_val; 567 - unsigned int i; 557 + unsigned int i, q_count; 568 558 569 559 /* Set MTL flow control */ 570 560 for (i = 0; i < pdata->rx_q_count; i++) { ··· 587 579 } 588 580 589 581 /* Set MAC flow control */ 590 - max_q_count = XGMAC_MAX_FLOW_CONTROL_QUEUES; 591 - q_count = min_t(unsigned int, pdata->tx_q_count, max_q_count); 582 + q_count = xgbe_get_fc_queue_count(pdata); 592 583 reg = MAC_Q0TFCR; 593 584 for (i = 0; i < q_count; i++) { 594 585 reg_val = XGMAC_IOREAD(pdata, reg);