@@ -367,6 +367,107 @@ int cgx_lmac_tx_enable(void *cgxd, int lmac_id, bool enable)
367
367
return !!(last & DATA_PKT_TX_EN );
368
368
}
369
369
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
+
370
471
/* CGX Firmware interface low level support */
371
472
static int cgx_fwi_cmd_send (u64 req , u64 * resp , struct lmac * lmac )
372
473
{
@@ -787,6 +888,7 @@ static int cgx_lmac_init(struct cgx *cgx)
787
888
788
889
/* Add reference */
789
890
cgx -> lmac_idmap [i ] = lmac ;
891
+ cgx_lmac_pause_frm_config (cgx , i , true);
790
892
}
791
893
792
894
return cgx_lmac_verify_fwi_version (cgx );
@@ -805,6 +907,7 @@ static int cgx_lmac_exit(struct cgx *cgx)
805
907
806
908
/* Free all lmac related resources */
807
909
for (i = 0 ; i < cgx -> lmac_count ; i ++ ) {
910
+ cgx_lmac_pause_frm_config (cgx , i , false);
808
911
lmac = cgx -> lmac_idmap [i ];
809
912
if (!lmac )
810
913
continue ;
0 commit comments