Skip to content

Commit 1121f6b

Browse files
SunilKumarKoridavem330
authored andcommitted
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 <[email protected]> Signed-off-by: Hariprasad Kelam <[email protected]> Signed-off-by: Sunil Kovvuri Goutham <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent d957b51 commit 1121f6b

File tree

7 files changed

+251
-15
lines changed

7 files changed

+251
-15
lines changed

drivers/net/ethernet/marvell/octeontx2/af/cgx.c

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -817,6 +817,47 @@ static void cgx_lmac_pause_frm_config(void *cgxd, int lmac_id, bool enable)
817817
cgx_write(cgx, lmac_id, CGXX_SMUX_TX_CTL, cfg);
818818
}
819819

820+
int cgx_lmac_pfc_config(void *cgxd, int lmac_id, u8 tx_pause,
821+
u8 rx_pause, u16 pfc_en)
822+
{
823+
struct cgx *cgx = cgxd;
824+
u64 cfg;
825+
826+
if (!is_lmac_valid(cgx, lmac_id))
827+
return -ENODEV;
828+
829+
/* Return as no traffic classes are requested */
830+
if (tx_pause && !pfc_en)
831+
return 0;
832+
833+
cfg = cgx_read(cgx, lmac_id, CGXX_SMUX_CBFC_CTL);
834+
835+
if (rx_pause) {
836+
cfg |= (CGXX_SMUX_CBFC_CTL_RX_EN |
837+
CGXX_SMUX_CBFC_CTL_BCK_EN |
838+
CGXX_SMUX_CBFC_CTL_DRP_EN);
839+
} else {
840+
cfg &= ~(CGXX_SMUX_CBFC_CTL_RX_EN |
841+
CGXX_SMUX_CBFC_CTL_BCK_EN |
842+
CGXX_SMUX_CBFC_CTL_DRP_EN);
843+
}
844+
845+
if (tx_pause)
846+
cfg |= CGXX_SMUX_CBFC_CTL_TX_EN;
847+
else
848+
cfg &= ~CGXX_SMUX_CBFC_CTL_TX_EN;
849+
850+
cfg = FIELD_SET(CGX_PFC_CLASS_MASK, pfc_en, cfg);
851+
852+
cgx_write(cgx, lmac_id, CGXX_SMUX_CBFC_CTL, cfg);
853+
854+
/* Write source MAC address which will be filled into PFC packet */
855+
cfg = cgx_lmac_addr_get(cgx->cgx_id, lmac_id);
856+
cgx_write(cgx, lmac_id, CGXX_SMUX_SMAC, cfg);
857+
858+
return 0;
859+
}
860+
820861
void cgx_lmac_ptp_config(void *cgxd, int lmac_id, bool enable)
821862
{
822863
struct cgx *cgx = cgxd;
@@ -1559,6 +1600,7 @@ static struct mac_ops cgx_mac_ops = {
15591600
.mac_enadis_ptp_config = cgx_lmac_ptp_config,
15601601
.mac_rx_tx_enable = cgx_lmac_rx_tx_enable,
15611602
.mac_tx_enable = cgx_lmac_tx_enable,
1603+
.pfc_config = cgx_lmac_pfc_config,
15621604
};
15631605

15641606
static int cgx_probe(struct pci_dev *pdev, const struct pci_device_id *id)

drivers/net/ethernet/marvell/octeontx2/af/cgx.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,13 @@
7676
#define CGXX_SMUX_TX_CTL 0x20178
7777
#define CGXX_SMUX_TX_PAUSE_PKT_TIME 0x20110
7878
#define CGXX_SMUX_TX_PAUSE_PKT_INTERVAL 0x20120
79+
#define CGXX_SMUX_SMAC 0x20108
80+
#define CGXX_SMUX_CBFC_CTL 0x20218
81+
#define CGXX_SMUX_CBFC_CTL_RX_EN BIT_ULL(0)
82+
#define CGXX_SMUX_CBFC_CTL_TX_EN BIT_ULL(1)
83+
#define CGXX_SMUX_CBFC_CTL_DRP_EN BIT_ULL(2)
84+
#define CGXX_SMUX_CBFC_CTL_BCK_EN BIT_ULL(3)
85+
#define CGX_PFC_CLASS_MASK GENMASK_ULL(47, 32)
7986
#define CGXX_GMP_GMI_TX_PAUSE_PKT_TIME 0x38230
8087
#define CGXX_GMP_GMI_TX_PAUSE_PKT_INTERVAL 0x38248
8188
#define CGX_SMUX_TX_CTL_L2P_BP_CONV BIT_ULL(7)
@@ -172,4 +179,6 @@ u64 cgx_lmac_read(int cgx_id, int lmac_id, u64 offset);
172179
int cgx_lmac_addr_update(u8 cgx_id, u8 lmac_id, u8 *mac_addr, u8 index);
173180
u64 cgx_read_dmac_ctrl(void *cgxd, int lmac_id);
174181
u64 cgx_read_dmac_entry(void *cgxd, int index);
182+
int cgx_lmac_pfc_config(void *cgxd, int lmac_id, u8 tx_pause, u8 rx_pause,
183+
u16 pfc_en);
175184
#endif /* CGX_H */

drivers/net/ethernet/marvell/octeontx2/af/lmac_common.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,9 @@ struct mac_ops {
110110

111111
int (*mac_rx_tx_enable)(void *cgxd, int lmac_id, bool enable);
112112
int (*mac_tx_enable)(void *cgxd, int lmac_id, bool enable);
113+
int (*pfc_config)(void *cgxd, int lmac_id,
114+
u8 tx_pause, u8 rx_pause, u16 pfc_en);
115+
113116
};
114117

115118
struct cgx {

drivers/net/ethernet/marvell/octeontx2/af/mbox.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,8 @@ M(RPM_STATS, 0x21C, rpm_stats, msg_req, rpm_stats_rsp) \
172172
M(CGX_MAC_ADDR_RESET, 0x21D, cgx_mac_addr_reset, msg_req, msg_rsp) \
173173
M(CGX_MAC_ADDR_UPDATE, 0x21E, cgx_mac_addr_update, cgx_mac_addr_update_req, \
174174
msg_rsp) \
175+
M(CGX_PRIO_FLOW_CTRL_CFG, 0x21F, cgx_prio_flow_ctrl_cfg, cgx_pfc_cfg, \
176+
cgx_pfc_rsp) \
175177
/* NPA mbox IDs (range 0x400 - 0x5FF) */ \
176178
M(NPA_LF_ALLOC, 0x400, npa_lf_alloc, \
177179
npa_lf_alloc_req, npa_lf_alloc_rsp) \
@@ -609,6 +611,21 @@ struct rpm_stats_rsp {
609611
u64 tx_stats[RPM_TX_STATS_COUNT];
610612
};
611613

614+
struct cgx_pfc_cfg {
615+
struct mbox_msghdr hdr;
616+
u8 rx_pause;
617+
u8 tx_pause;
618+
u16 pfc_en; /* bitmap indicating pfc enabled traffic classes */
619+
};
620+
621+
struct cgx_pfc_rsp {
622+
struct mbox_msghdr hdr;
623+
u8 rx_pause;
624+
u8 tx_pause;
625+
};
626+
627+
/* NPA mbox message formats */
628+
612629
struct npc_set_pkind {
613630
struct mbox_msghdr hdr;
614631
#define OTX2_PRIV_FLAGS_DEFAULT BIT_ULL(0)

drivers/net/ethernet/marvell/octeontx2/af/rpm.c

Lines changed: 129 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ static struct mac_ops rpm_mac_ops = {
3232
.mac_enadis_ptp_config = rpm_lmac_ptp_config,
3333
.mac_rx_tx_enable = rpm_lmac_rx_tx_enable,
3434
.mac_tx_enable = rpm_lmac_tx_enable,
35+
.pfc_config = rpm_lmac_pfc_config,
3536
};
3637

3738
struct mac_ops *rpm_get_mac_ops(void)
@@ -129,6 +130,85 @@ int rpm_lmac_get_pause_frm_status(void *rpmd, int lmac_id,
129130
return 0;
130131
}
131132

133+
static void rpm_cfg_pfc_quanta_thresh(rpm_t *rpm, int lmac_id, u16 pfc_en,
134+
bool enable)
135+
{
136+
u64 quanta_offset = 0, quanta_thresh = 0, cfg;
137+
int i, shift;
138+
139+
/* Set pause time and interval */
140+
for_each_set_bit(i, (unsigned long *)&pfc_en, 16) {
141+
switch (i) {
142+
case 0:
143+
case 1:
144+
quanta_offset = RPMX_MTI_MAC100X_CL01_PAUSE_QUANTA;
145+
quanta_thresh = RPMX_MTI_MAC100X_CL01_QUANTA_THRESH;
146+
break;
147+
case 2:
148+
case 3:
149+
quanta_offset = RPMX_MTI_MAC100X_CL23_PAUSE_QUANTA;
150+
quanta_thresh = RPMX_MTI_MAC100X_CL23_QUANTA_THRESH;
151+
break;
152+
case 4:
153+
case 5:
154+
quanta_offset = RPMX_MTI_MAC100X_CL45_PAUSE_QUANTA;
155+
quanta_thresh = RPMX_MTI_MAC100X_CL45_QUANTA_THRESH;
156+
break;
157+
case 6:
158+
case 7:
159+
quanta_offset = RPMX_MTI_MAC100X_CL67_PAUSE_QUANTA;
160+
quanta_thresh = RPMX_MTI_MAC100X_CL67_QUANTA_THRESH;
161+
break;
162+
case 8:
163+
case 9:
164+
quanta_offset = RPMX_MTI_MAC100X_CL89_PAUSE_QUANTA;
165+
quanta_thresh = RPMX_MTI_MAC100X_CL89_QUANTA_THRESH;
166+
break;
167+
case 10:
168+
case 11:
169+
quanta_offset = RPMX_MTI_MAC100X_CL1011_PAUSE_QUANTA;
170+
quanta_thresh = RPMX_MTI_MAC100X_CL1011_QUANTA_THRESH;
171+
break;
172+
case 12:
173+
case 13:
174+
quanta_offset = RPMX_MTI_MAC100X_CL1213_PAUSE_QUANTA;
175+
quanta_thresh = RPMX_MTI_MAC100X_CL1213_QUANTA_THRESH;
176+
break;
177+
case 14:
178+
case 15:
179+
quanta_offset = RPMX_MTI_MAC100X_CL1415_PAUSE_QUANTA;
180+
quanta_thresh = RPMX_MTI_MAC100X_CL1415_QUANTA_THRESH;
181+
break;
182+
}
183+
184+
if (!quanta_offset || !quanta_thresh)
185+
continue;
186+
187+
shift = (i % 2) ? 1 : 0;
188+
cfg = rpm_read(rpm, lmac_id, quanta_offset);
189+
if (enable) {
190+
cfg |= ((u64)RPM_DEFAULT_PAUSE_TIME << shift * 16);
191+
} else {
192+
if (!shift)
193+
cfg &= ~GENMASK_ULL(15, 0);
194+
else
195+
cfg &= ~GENMASK_ULL(31, 16);
196+
}
197+
rpm_write(rpm, lmac_id, quanta_offset, cfg);
198+
199+
cfg = rpm_read(rpm, lmac_id, quanta_thresh);
200+
if (enable) {
201+
cfg |= ((u64)(RPM_DEFAULT_PAUSE_TIME / 2) << shift * 16);
202+
} else {
203+
if (!shift)
204+
cfg &= ~GENMASK_ULL(15, 0);
205+
else
206+
cfg &= ~GENMASK_ULL(31, 16);
207+
}
208+
rpm_write(rpm, lmac_id, quanta_thresh, cfg);
209+
}
210+
}
211+
132212
int rpm_lmac_enadis_pause_frm(void *rpmd, int lmac_id, u8 tx_pause,
133213
u8 rx_pause)
134214
{
@@ -152,8 +232,12 @@ int rpm_lmac_enadis_pause_frm(void *rpmd, int lmac_id, u8 tx_pause,
152232

153233
cfg = rpm_read(rpm, 0, RPMX_CMR_RX_OVR_BP);
154234
if (tx_pause) {
235+
/* Configure CL0 Pause Quanta & threshold for 802.3X frames */
236+
rpm_cfg_pfc_quanta_thresh(rpm, lmac_id, 1, true);
155237
cfg &= ~RPMX_CMR_RX_OVR_BP_EN(lmac_id);
156238
} else {
239+
/* Disable all Pause Quanta & threshold values */
240+
rpm_cfg_pfc_quanta_thresh(rpm, lmac_id, 0xffff, false);
157241
cfg |= RPMX_CMR_RX_OVR_BP_EN(lmac_id);
158242
cfg &= ~RPMX_CMR_RX_OVR_BP_BP(lmac_id);
159243
}
@@ -166,21 +250,6 @@ void rpm_lmac_pause_frm_config(void *rpmd, int lmac_id, bool enable)
166250
rpm_t *rpm = rpmd;
167251
u64 cfg;
168252

169-
if (enable) {
170-
/* Set pause time and interval */
171-
cfg = rpm_read(rpm, lmac_id,
172-
RPMX_MTI_MAC100X_CL01_PAUSE_QUANTA);
173-
cfg &= ~0xFFFFULL;
174-
rpm_write(rpm, lmac_id, RPMX_MTI_MAC100X_CL01_PAUSE_QUANTA,
175-
cfg | RPM_DEFAULT_PAUSE_TIME);
176-
/* Set pause interval as the hardware default is too short */
177-
cfg = rpm_read(rpm, lmac_id,
178-
RPMX_MTI_MAC100X_CL01_QUANTA_THRESH);
179-
cfg &= ~0xFFFFULL;
180-
rpm_write(rpm, lmac_id, RPMX_MTI_MAC100X_CL01_QUANTA_THRESH,
181-
cfg | (RPM_DEFAULT_PAUSE_TIME / 2));
182-
}
183-
184253
/* ALL pause frames received are completely ignored */
185254
cfg = rpm_read(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG);
186255
cfg |= RPMX_MTI_MAC100X_COMMAND_CONFIG_RX_P_DISABLE;
@@ -302,3 +371,48 @@ void rpm_lmac_ptp_config(void *rpmd, int lmac_id, bool enable)
302371
cfg &= ~RPMX_RX_TS_PREPEND;
303372
rpm_write(rpm, lmac_id, RPMX_CMRX_CFG, cfg);
304373
}
374+
375+
int rpm_lmac_pfc_config(void *rpmd, int lmac_id, u8 tx_pause, u8 rx_pause, u16 pfc_en)
376+
{
377+
rpm_t *rpm = rpmd;
378+
u64 cfg;
379+
380+
if (!is_lmac_valid(rpm, lmac_id))
381+
return -ENODEV;
382+
383+
/* reset PFC class quanta and threshold */
384+
rpm_cfg_pfc_quanta_thresh(rpm, lmac_id, 0xffff, false);
385+
386+
cfg = rpm_read(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG);
387+
388+
if (rx_pause) {
389+
cfg &= ~(RPMX_MTI_MAC100X_COMMAND_CONFIG_RX_P_DISABLE |
390+
RPMX_MTI_MAC100X_COMMAND_CONFIG_PAUSE_IGNORE |
391+
RPMX_MTI_MAC100X_COMMAND_CONFIG_PAUSE_FWD);
392+
} else {
393+
cfg |= (RPMX_MTI_MAC100X_COMMAND_CONFIG_RX_P_DISABLE |
394+
RPMX_MTI_MAC100X_COMMAND_CONFIG_PAUSE_IGNORE |
395+
RPMX_MTI_MAC100X_COMMAND_CONFIG_PAUSE_FWD);
396+
}
397+
398+
if (tx_pause) {
399+
rpm_cfg_pfc_quanta_thresh(rpm, lmac_id, pfc_en, true);
400+
cfg &= ~RPMX_MTI_MAC100X_COMMAND_CONFIG_TX_P_DISABLE;
401+
} else {
402+
rpm_cfg_pfc_quanta_thresh(rpm, lmac_id, 0xfff, false);
403+
cfg |= RPMX_MTI_MAC100X_COMMAND_CONFIG_TX_P_DISABLE;
404+
}
405+
406+
if (!rx_pause && !tx_pause)
407+
cfg &= ~RPMX_MTI_MAC100X_COMMAND_CONFIG_PFC_MODE;
408+
else
409+
cfg |= RPMX_MTI_MAC100X_COMMAND_CONFIG_PFC_MODE;
410+
411+
rpm_write(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG, cfg);
412+
413+
cfg = rpm_read(rpm, lmac_id, RPMX_CMRX_PRT_CBFC_CTL);
414+
cfg = FIELD_SET(RPM_PFC_CLASS_MASK, pfc_en, cfg);
415+
rpm_write(rpm, lmac_id, RPMX_CMRX_PRT_CBFC_CTL, cfg);
416+
417+
return 0;
418+
}

drivers/net/ethernet/marvell/octeontx2/af/rpm.h

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,21 @@
3333
#define RPMX_MTI_MAC100X_COMMAND_CONFIG_PAUSE_IGNORE BIT_ULL(8)
3434
#define RPMX_MTI_MAC100X_COMMAND_CONFIG_PFC_MODE BIT_ULL(19)
3535
#define RPMX_MTI_MAC100X_CL01_PAUSE_QUANTA 0x80A8
36+
#define RPMX_MTI_MAC100X_CL23_PAUSE_QUANTA 0x80B0
37+
#define RPMX_MTI_MAC100X_CL45_PAUSE_QUANTA 0x80B8
38+
#define RPMX_MTI_MAC100X_CL67_PAUSE_QUANTA 0x80C0
3639
#define RPMX_MTI_MAC100X_CL01_QUANTA_THRESH 0x80C8
40+
#define RPMX_MTI_MAC100X_CL23_QUANTA_THRESH 0x80D0
41+
#define RPMX_MTI_MAC100X_CL45_QUANTA_THRESH 0x80D8
42+
#define RPMX_MTI_MAC100X_CL67_QUANTA_THRESH 0x80E0
43+
#define RPMX_MTI_MAC100X_CL89_PAUSE_QUANTA 0x8108
44+
#define RPMX_MTI_MAC100X_CL1011_PAUSE_QUANTA 0x8110
45+
#define RPMX_MTI_MAC100X_CL1213_PAUSE_QUANTA 0x8118
46+
#define RPMX_MTI_MAC100X_CL1415_PAUSE_QUANTA 0x8120
47+
#define RPMX_MTI_MAC100X_CL89_QUANTA_THRESH 0x8128
48+
#define RPMX_MTI_MAC100X_CL1011_QUANTA_THRESH 0x8130
49+
#define RPMX_MTI_MAC100X_CL1213_QUANTA_THRESH 0x8138
50+
#define RPMX_MTI_MAC100X_CL1415_QUANTA_THRESH 0x8140
3751
#define RPM_DEFAULT_PAUSE_TIME 0xFFFF
3852
#define RPMX_CMR_RX_OVR_BP 0x4120
3953
#define RPMX_CMR_RX_OVR_BP_EN(x) BIT_ULL((x) + 8)
@@ -45,6 +59,18 @@
4559
#define RPM_LMAC_FWI 0xa
4660
#define RPM_TX_EN BIT_ULL(0)
4761
#define RPM_RX_EN BIT_ULL(1)
62+
#define RPMX_CMRX_PRT_CBFC_CTL 0x5B08
63+
#define RPMX_CMRX_PRT_CBFC_CTL_LOGL_EN_RX_SHIFT 33
64+
#define RPMX_CMRX_PRT_CBFC_CTL_PHYS_BP_SHIFT 16
65+
#define RPMX_CMRX_PRT_CBFC_CTL_LOGL_EN_TX_SHIFT 0
66+
#define RPM_PFC_CLASS_MASK GENMASK_ULL(48, 33)
67+
#define RPMX_MTI_MAC100X_CL89_QUANTA_THRESH 0x8128
68+
#define RPMX_MTI_MAC100X_COMMAND_CONFIG_TX_PAD_EN BIT_ULL(11)
69+
#define RPMX_MTI_MAC100X_COMMAND_CONFIG_PAUSE_IGNORE BIT_ULL(8)
70+
#define RPMX_MTI_MAC100X_COMMAND_CONFIG_PAUSE_FWD BIT_ULL(7)
71+
#define RPMX_MTI_MAC100X_CL01_PAUSE_QUANTA 0x80A8
72+
#define RPMX_MTI_MAC100X_CL89_PAUSE_QUANTA 0x8108
73+
#define RPM_DEFAULT_PAUSE_TIME 0xFFFF
4874

4975
/* Function Declarations */
5076
int rpm_get_nr_lmacs(void *rpmd);
@@ -61,4 +87,6 @@ int rpm_get_rx_stats(void *rpmd, int lmac_id, int idx, u64 *rx_stat);
6187
void rpm_lmac_ptp_config(void *rpmd, int lmac_id, bool enable);
6288
int rpm_lmac_rx_tx_enable(void *rpmd, int lmac_id, bool enable);
6389
int rpm_lmac_tx_enable(void *rpmd, int lmac_id, bool enable);
90+
int rpm_lmac_pfc_config(void *rpmd, int lmac_id, u8 tx_pause, u8 rx_pause,
91+
u16 pfc_en);
6492
#endif /* RPM_H */

drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1079,3 +1079,26 @@ int rvu_mbox_handler_cgx_mac_addr_update(struct rvu *rvu,
10791079
rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);
10801080
return cgx_lmac_addr_update(cgx_id, lmac_id, req->mac_addr, req->index);
10811081
}
1082+
1083+
int rvu_mbox_handler_cgx_prio_flow_ctrl_cfg(struct rvu *rvu,
1084+
struct cgx_pfc_cfg *req,
1085+
struct cgx_pfc_rsp *rsp)
1086+
{
1087+
int pf = rvu_get_pf(req->hdr.pcifunc);
1088+
struct mac_ops *mac_ops;
1089+
u8 cgx_id, lmac_id;
1090+
void *cgxd;
1091+
1092+
/* This msg is expected only from PF/VFs that are mapped to CGX LMACs,
1093+
* if received from other PF/VF simply ACK, nothing to do.
1094+
*/
1095+
if (!is_pf_cgxmapped(rvu, pf))
1096+
return -ENODEV;
1097+
1098+
rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);
1099+
cgxd = rvu_cgx_pdata(cgx_id, rvu);
1100+
mac_ops = get_mac_ops(cgxd);
1101+
1102+
return mac_ops->pfc_config(cgxd, lmac_id, req->tx_pause, req->rx_pause,
1103+
req->pfc_en);
1104+
}

0 commit comments

Comments
 (0)