summaryrefslogtreecommitdiff
path: root/drivers/net/ethernet/marvell/octeontx2/af/cgx.c
diff options
context:
space:
mode:
authorSunil Kumar Kori <skori@marvell.com>2022-02-09 12:45:17 +0530
committerDavid S. Miller <davem@davemloft.net>2022-02-09 13:02:33 +0000
commit1121f6b02e7a1fdb4330c0fe53b69cfa80e7bceb (patch)
tree23505e8f88abd87a130f000981c1a7d2d97318c7 /drivers/net/ethernet/marvell/octeontx2/af/cgx.c
parentd957b51f7ed66dbe6102f1bba0587fdfc0119a94 (diff)
octeontx2-af: Priority flow control configuration support
Prirority based flow control (802.1Qbb) mechanism is similar to ethernet pause frames (802.3x) instead pausing all traffic on a link, PFC allows user to selectively pause traffic according to its class. Oceteontx2 MAC block (CGX) and CN10K Mac block (RPM) both supports PFC. As upper layer mbox handler is same for both the MACs, this patch configures PFC by calling apporopritate callbacks. Signed-off-by: Sunil Kumar Kori <skori@marvell.com> Signed-off-by: Hariprasad Kelam <hkelam@marvell.com> Signed-off-by: Sunil Kovvuri Goutham <sgoutham@marvell.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/marvell/octeontx2/af/cgx.c')
-rw-r--r--drivers/net/ethernet/marvell/octeontx2/af/cgx.c42
1 files changed, 42 insertions, 0 deletions
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/cgx.c b/drivers/net/ethernet/marvell/octeontx2/af/cgx.c
index fb7069c757f5..64e8211d14ba 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/cgx.c
+++ b/drivers/net/ethernet/marvell/octeontx2/af/cgx.c
@@ -817,6 +817,47 @@ static void cgx_lmac_pause_frm_config(void *cgxd, int lmac_id, bool enable)
cgx_write(cgx, lmac_id, CGXX_SMUX_TX_CTL, cfg);
}
+int cgx_lmac_pfc_config(void *cgxd, int lmac_id, u8 tx_pause,
+ u8 rx_pause, u16 pfc_en)
+{
+ struct cgx *cgx = cgxd;
+ u64 cfg;
+
+ if (!is_lmac_valid(cgx, lmac_id))
+ return -ENODEV;
+
+ /* Return as no traffic classes are requested */
+ if (tx_pause && !pfc_en)
+ return 0;
+
+ cfg = cgx_read(cgx, lmac_id, CGXX_SMUX_CBFC_CTL);
+
+ if (rx_pause) {
+ cfg |= (CGXX_SMUX_CBFC_CTL_RX_EN |
+ CGXX_SMUX_CBFC_CTL_BCK_EN |
+ CGXX_SMUX_CBFC_CTL_DRP_EN);
+ } else {
+ cfg &= ~(CGXX_SMUX_CBFC_CTL_RX_EN |
+ CGXX_SMUX_CBFC_CTL_BCK_EN |
+ CGXX_SMUX_CBFC_CTL_DRP_EN);
+ }
+
+ if (tx_pause)
+ cfg |= CGXX_SMUX_CBFC_CTL_TX_EN;
+ else
+ cfg &= ~CGXX_SMUX_CBFC_CTL_TX_EN;
+
+ cfg = FIELD_SET(CGX_PFC_CLASS_MASK, pfc_en, cfg);
+
+ cgx_write(cgx, lmac_id, CGXX_SMUX_CBFC_CTL, cfg);
+
+ /* Write source MAC address which will be filled into PFC packet */
+ cfg = cgx_lmac_addr_get(cgx->cgx_id, lmac_id);
+ cgx_write(cgx, lmac_id, CGXX_SMUX_SMAC, cfg);
+
+ return 0;
+}
+
void cgx_lmac_ptp_config(void *cgxd, int lmac_id, bool enable)
{
struct cgx *cgx = cgxd;
@@ -1559,6 +1600,7 @@ static struct mac_ops cgx_mac_ops = {
.mac_enadis_ptp_config = cgx_lmac_ptp_config,
.mac_rx_tx_enable = cgx_lmac_rx_tx_enable,
.mac_tx_enable = cgx_lmac_tx_enable,
+ .pfc_config = cgx_lmac_pfc_config,
};
static int cgx_probe(struct pci_dev *pdev, const struct pci_device_id *id)