Skip to content

Commit f7e086e

Browse files
Geetha sowjanyadavem330
authored andcommitted
octeontx2-af: Pause frame configuration at cgx
CGX LMAC, the physical interface can generate pause frames when internal resources asserts backpressure due to exhaustion. This patch configures CGX to generate 802.3 pause frames. Also enabled processing of received pause frames on the line which will assert backpressure on the internal transmit path. Also added mailbox handlers for PF drivers to enable or disable pause frames anytime. Signed-off-by: Geetha sowjanya <[email protected]> Signed-off-by: Sunil Goutham <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 27150bc commit f7e086e

File tree

5 files changed

+157
-0
lines changed

5 files changed

+157
-0
lines changed

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

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,107 @@ int cgx_lmac_tx_enable(void *cgxd, int lmac_id, bool enable)
367367
return !!(last & DATA_PKT_TX_EN);
368368
}
369369

370+
int cgx_lmac_get_pause_frm(void *cgxd, int lmac_id,
371+
u8 *tx_pause, u8 *rx_pause)
372+
{
373+
struct cgx *cgx = cgxd;
374+
u64 cfg;
375+
376+
if (!cgx || lmac_id >= cgx->lmac_count)
377+
return -ENODEV;
378+
379+
cfg = cgx_read(cgx, lmac_id, CGXX_SMUX_RX_FRM_CTL);
380+
*rx_pause = !!(cfg & CGX_SMUX_RX_FRM_CTL_CTL_BCK);
381+
382+
cfg = cgx_read(cgx, lmac_id, CGXX_SMUX_TX_CTL);
383+
*tx_pause = !!(cfg & CGX_SMUX_TX_CTL_L2P_BP_CONV);
384+
return 0;
385+
}
386+
387+
int cgx_lmac_set_pause_frm(void *cgxd, int lmac_id,
388+
u8 tx_pause, u8 rx_pause)
389+
{
390+
struct cgx *cgx = cgxd;
391+
u64 cfg;
392+
393+
if (!cgx || lmac_id >= cgx->lmac_count)
394+
return -ENODEV;
395+
396+
cfg = cgx_read(cgx, lmac_id, CGXX_SMUX_RX_FRM_CTL);
397+
cfg &= ~CGX_SMUX_RX_FRM_CTL_CTL_BCK;
398+
cfg |= rx_pause ? CGX_SMUX_RX_FRM_CTL_CTL_BCK : 0x0;
399+
cgx_write(cgx, lmac_id, CGXX_SMUX_RX_FRM_CTL, cfg);
400+
401+
cfg = cgx_read(cgx, lmac_id, CGXX_SMUX_TX_CTL);
402+
cfg &= ~CGX_SMUX_TX_CTL_L2P_BP_CONV;
403+
cfg |= tx_pause ? CGX_SMUX_TX_CTL_L2P_BP_CONV : 0x0;
404+
cgx_write(cgx, lmac_id, CGXX_SMUX_TX_CTL, cfg);
405+
406+
cfg = cgx_read(cgx, 0, CGXX_CMR_RX_OVR_BP);
407+
if (tx_pause) {
408+
cfg &= ~CGX_CMR_RX_OVR_BP_EN(lmac_id);
409+
} else {
410+
cfg |= CGX_CMR_RX_OVR_BP_EN(lmac_id);
411+
cfg &= ~CGX_CMR_RX_OVR_BP_BP(lmac_id);
412+
}
413+
cgx_write(cgx, 0, CGXX_CMR_RX_OVR_BP, cfg);
414+
return 0;
415+
}
416+
417+
static void cgx_lmac_pause_frm_config(struct cgx *cgx, int lmac_id, bool enable)
418+
{
419+
u64 cfg;
420+
421+
if (!cgx || lmac_id >= cgx->lmac_count)
422+
return;
423+
if (enable) {
424+
/* Enable receive pause frames */
425+
cfg = cgx_read(cgx, lmac_id, CGXX_SMUX_RX_FRM_CTL);
426+
cfg |= CGX_SMUX_RX_FRM_CTL_CTL_BCK;
427+
cgx_write(cgx, lmac_id, CGXX_SMUX_RX_FRM_CTL, cfg);
428+
429+
cfg = cgx_read(cgx, lmac_id, CGXX_GMP_GMI_RXX_FRM_CTL);
430+
cfg |= CGX_GMP_GMI_RXX_FRM_CTL_CTL_BCK;
431+
cgx_write(cgx, lmac_id, CGXX_GMP_GMI_RXX_FRM_CTL, cfg);
432+
433+
/* Enable pause frames transmission */
434+
cfg = cgx_read(cgx, lmac_id, CGXX_SMUX_TX_CTL);
435+
cfg |= CGX_SMUX_TX_CTL_L2P_BP_CONV;
436+
cgx_write(cgx, lmac_id, CGXX_SMUX_TX_CTL, cfg);
437+
438+
/* Set pause time and interval */
439+
cgx_write(cgx, lmac_id, CGXX_SMUX_TX_PAUSE_PKT_TIME,
440+
DEFAULT_PAUSE_TIME);
441+
cfg = cgx_read(cgx, lmac_id, CGXX_SMUX_TX_PAUSE_PKT_INTERVAL);
442+
cfg &= ~0xFFFFULL;
443+
cgx_write(cgx, lmac_id, CGXX_SMUX_TX_PAUSE_PKT_INTERVAL,
444+
cfg | (DEFAULT_PAUSE_TIME / 2));
445+
446+
cgx_write(cgx, lmac_id, CGXX_GMP_GMI_TX_PAUSE_PKT_TIME,
447+
DEFAULT_PAUSE_TIME);
448+
449+
cfg = cgx_read(cgx, lmac_id,
450+
CGXX_GMP_GMI_TX_PAUSE_PKT_INTERVAL);
451+
cfg &= ~0xFFFFULL;
452+
cgx_write(cgx, lmac_id, CGXX_GMP_GMI_TX_PAUSE_PKT_INTERVAL,
453+
cfg | (DEFAULT_PAUSE_TIME / 2));
454+
} else {
455+
/* ALL pause frames received are completely ignored */
456+
cfg = cgx_read(cgx, lmac_id, CGXX_SMUX_RX_FRM_CTL);
457+
cfg &= ~CGX_SMUX_RX_FRM_CTL_CTL_BCK;
458+
cgx_write(cgx, lmac_id, CGXX_SMUX_RX_FRM_CTL, cfg);
459+
460+
cfg = cgx_read(cgx, lmac_id, CGXX_GMP_GMI_RXX_FRM_CTL);
461+
cfg &= ~CGX_GMP_GMI_RXX_FRM_CTL_CTL_BCK;
462+
cgx_write(cgx, lmac_id, CGXX_GMP_GMI_RXX_FRM_CTL, cfg);
463+
464+
/* Disable pause frames transmission */
465+
cfg = cgx_read(cgx, lmac_id, CGXX_SMUX_TX_CTL);
466+
cfg &= ~CGX_SMUX_TX_CTL_L2P_BP_CONV;
467+
cgx_write(cgx, lmac_id, CGXX_SMUX_TX_CTL, cfg);
468+
}
469+
}
470+
370471
/* CGX Firmware interface low level support */
371472
static int cgx_fwi_cmd_send(u64 req, u64 *resp, struct lmac *lmac)
372473
{
@@ -787,6 +888,7 @@ static int cgx_lmac_init(struct cgx *cgx)
787888

788889
/* Add reference */
789890
cgx->lmac_idmap[i] = lmac;
891+
cgx_lmac_pause_frm_config(cgx, i, true);
790892
}
791893

792894
return cgx_lmac_verify_fwi_version(cgx);
@@ -805,6 +907,7 @@ static int cgx_lmac_exit(struct cgx *cgx)
805907

806908
/* Free all lmac related resources */
807909
for (i = 0; i < cgx->lmac_count; i++) {
910+
cgx_lmac_pause_frm_config(cgx, i, false);
808911
lmac = cgx->lmac_idmap[i];
809912
if (!lmac)
810913
continue;

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

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,10 +60,20 @@
6060
#define CGX_SMUX_RX_FRM_CTL_CTL_BCK BIT_ULL(3)
6161
#define CGXX_GMP_GMI_RXX_FRM_CTL 0x38028
6262
#define CGX_GMP_GMI_RXX_FRM_CTL_CTL_BCK BIT_ULL(3)
63+
#define CGXX_SMUX_TX_CTL 0x20178
64+
#define CGXX_SMUX_TX_PAUSE_PKT_TIME 0x20110
65+
#define CGXX_SMUX_TX_PAUSE_PKT_INTERVAL 0x20120
66+
#define CGXX_GMP_GMI_TX_PAUSE_PKT_TIME 0x38230
67+
#define CGXX_GMP_GMI_TX_PAUSE_PKT_INTERVAL 0x38248
68+
#define CGX_SMUX_TX_CTL_L2P_BP_CONV BIT_ULL(7)
69+
#define CGXX_CMR_RX_OVR_BP 0x130
70+
#define CGX_CMR_RX_OVR_BP_EN(X) BIT_ULL(((X) + 8))
71+
#define CGX_CMR_RX_OVR_BP_BP(X) BIT_ULL(((X) + 4))
6372

6473
#define CGX_COMMAND_REG CGXX_SCRATCH1_REG
6574
#define CGX_EVENT_REG CGXX_SCRATCH0_REG
6675
#define CGX_CMD_TIMEOUT 2200 /* msecs */
76+
#define DEFAULT_PAUSE_TIME 0x7FF
6777

6878
#define CGX_NVEC 37
6979
#define CGX_LMAC_FWI 0
@@ -124,5 +134,9 @@ int cgx_lmac_internal_loopback(void *cgxd, int lmac_id, bool enable);
124134
int cgx_get_link_info(void *cgxd, int lmac_id,
125135
struct cgx_link_user_info *linfo);
126136
int cgx_lmac_linkup_start(void *cgxd);
137+
int cgx_lmac_get_pause_frm(void *cgxd, int lmac_id,
138+
u8 *tx_pause, u8 *rx_pause);
139+
int cgx_lmac_set_pause_frm(void *cgxd, int lmac_id,
140+
u8 tx_pause, u8 rx_pause);
127141
int cgx_get_mkex_prfl_info(u64 *addr, u64 *size);
128142
#endif /* CGX_H */

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,8 @@ M(CGX_STOP_LINKEVENTS, 0x208, cgx_stop_linkevents, msg_req, msg_rsp) \
143143
M(CGX_GET_LINKINFO, 0x209, cgx_get_linkinfo, msg_req, cgx_link_info_msg) \
144144
M(CGX_INTLBK_ENABLE, 0x20A, cgx_intlbk_enable, msg_req, msg_rsp) \
145145
M(CGX_INTLBK_DISABLE, 0x20B, cgx_intlbk_disable, msg_req, msg_rsp) \
146+
M(CGX_CFG_PAUSE_FRM, 0x20E, cgx_cfg_pause_frm, cgx_pause_frm_cfg, \
147+
cgx_pause_frm_cfg) \
146148
/* NPA mbox IDs (range 0x400 - 0x5FF) */ \
147149
M(NPA_LF_ALLOC, 0x400, npa_lf_alloc, \
148150
npa_lf_alloc_req, npa_lf_alloc_rsp) \
@@ -345,6 +347,15 @@ struct cgx_link_info_msg {
345347
struct cgx_link_user_info link_info;
346348
};
347349

350+
struct cgx_pause_frm_cfg {
351+
struct mbox_msghdr hdr;
352+
u8 set;
353+
/* set = 1 if the request is to config pause frames */
354+
/* set = 0 if the request is to fetch pause frames config */
355+
u8 rx_pause;
356+
u8 tx_pause;
357+
};
358+
348359
/* NPA mbox message formats */
349360

350361
/* NPA mailbox error codes

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

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -590,6 +590,30 @@ int rvu_mbox_handler_cgx_intlbk_disable(struct rvu *rvu, struct msg_req *req,
590590
return 0;
591591
}
592592

593+
int rvu_mbox_handler_cgx_cfg_pause_frm(struct rvu *rvu,
594+
struct cgx_pause_frm_cfg *req,
595+
struct cgx_pause_frm_cfg *rsp)
596+
{
597+
int pf = rvu_get_pf(req->hdr.pcifunc);
598+
u8 cgx_id, lmac_id;
599+
600+
/* This msg is expected only from PF/VFs that are mapped to CGX LMACs,
601+
* if received from other PF/VF simply ACK, nothing to do.
602+
*/
603+
if (!is_pf_cgxmapped(rvu, pf))
604+
return -ENODEV;
605+
606+
rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);
607+
608+
if (req->set)
609+
cgx_lmac_set_pause_frm(rvu_cgx_pdata(cgx_id, rvu), lmac_id,
610+
req->tx_pause, req->rx_pause);
611+
else
612+
cgx_lmac_get_pause_frm(rvu_cgx_pdata(cgx_id, rvu), lmac_id,
613+
&rsp->tx_pause, &rsp->rx_pause);
614+
return 0;
615+
}
616+
593617
/* Finds cumulative status of NIX rx/tx counters from LF of a PF and those
594618
* from its VFs as well. ie. NIX rx/tx counters at the CGX port level
595619
*/

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,11 @@ static int nix_interface_init(struct rvu *rvu, u16 pcifunc, int type, int nixlf)
213213
pfvf->tx_chan_cnt = 1;
214214
cgx_set_pkind(rvu_cgx_pdata(cgx_id, rvu), lmac_id, pkind);
215215
rvu_npc_set_pkind(rvu, pkind, pfvf);
216+
217+
/* By default we enable pause frames */
218+
if ((pcifunc & RVU_PFVF_FUNC_MASK) == 0)
219+
cgx_lmac_set_pause_frm(rvu_cgx_pdata(cgx_id, rvu),
220+
lmac_id, true, true);
216221
break;
217222
case NIX_INTF_TYPE_LBK:
218223
vf = (pcifunc & RVU_PFVF_FUNC_MASK) - 1;

0 commit comments

Comments
 (0)