@@ -123,6 +123,8 @@ struct flag_table {
123
123
124
124
#define MIN_KERNEL_KCTXTS 2
125
125
#define FIRST_KERNEL_KCTXT 1
126
+ /* sizes for both the QP and RSM map tables */
127
+ #define NUM_MAP_ENTRIES 256
126
128
#define NUM_MAP_REGS 32
127
129
128
130
/* Bit offset into the GUID which carries HFI id information */
@@ -13422,9 +13424,52 @@ static void init_qpmap_table(struct hfi1_devdata *dd,
13422
13424
| RCV_CTRL_RCV_BYPASS_ENABLE_SMASK );
13423
13425
}
13424
13426
13427
+ struct rsm_map_table {
13428
+ u64 map [NUM_MAP_REGS ];
13429
+ unsigned int used ;
13430
+ };
13431
+
13432
+ /*
13433
+ * Return an initialized RMT map table for users to fill in. OK if it
13434
+ * returns NULL, indicating no table.
13435
+ */
13436
+ static struct rsm_map_table * alloc_rsm_map_table (struct hfi1_devdata * dd )
13437
+ {
13438
+ struct rsm_map_table * rmt ;
13439
+ u8 rxcontext = is_ax (dd ) ? 0 : 0xff ; /* 0 is default if a0 ver. */
13440
+
13441
+ rmt = kmalloc (sizeof (* rmt ), GFP_KERNEL );
13442
+ if (rmt ) {
13443
+ memset (rmt -> map , rxcontext , sizeof (rmt -> map ));
13444
+ rmt -> used = 0 ;
13445
+ }
13446
+
13447
+ return rmt ;
13448
+ }
13449
+
13450
+ /*
13451
+ * Write the final RMT map table to the chip and free the table. OK if
13452
+ * table is NULL.
13453
+ */
13454
+ static void complete_rsm_map_table (struct hfi1_devdata * dd ,
13455
+ struct rsm_map_table * rmt )
13456
+ {
13457
+ int i ;
13458
+
13459
+ if (rmt ) {
13460
+ /* write table to chip */
13461
+ for (i = 0 ; i < NUM_MAP_REGS ; i ++ )
13462
+ write_csr (dd , RCV_RSM_MAP_TABLE + (8 * i ), rmt -> map [i ]);
13463
+
13464
+ /* enable RSM */
13465
+ add_rcvctrl (dd , RCV_CTRL_RCV_RSM_ENABLE_SMASK );
13466
+ }
13467
+ }
13468
+
13425
13469
/**
13426
13470
* init_qos - init RX qos
13427
13471
* @dd - device data
13472
+ * @rmt - RSM map table
13428
13473
*
13429
13474
* This routine initializes Rule 0 and the RSM map table to implement
13430
13475
* quality of service (qos).
@@ -13435,16 +13480,16 @@ static void init_qpmap_table(struct hfi1_devdata *dd,
13435
13480
* The number of vl bits (n) and the number of qpn bits (m) are computed to
13436
13481
* feed both the RSM map table and the single rule.
13437
13482
*/
13438
- static void init_qos (struct hfi1_devdata * dd )
13483
+ static void init_qos (struct hfi1_devdata * dd , struct rsm_map_table * rmt )
13439
13484
{
13440
13485
u8 max_by_vl = 0 ;
13441
13486
unsigned qpns_per_vl , ctxt , i , qpn , n = 1 , m ;
13442
- u64 * rsmmap ;
13487
+ unsigned int rmt_entries ;
13443
13488
u64 reg ;
13444
- u8 rxcontext = is_ax (dd ) ? 0 : 0xff ; /* 0 is default if a0 ver. */
13445
13489
13446
13490
/* validate */
13447
- if (dd -> n_krcv_queues <= MIN_KERNEL_KCTXTS ||
13491
+ if (!rmt ||
13492
+ dd -> n_krcv_queues <= MIN_KERNEL_KCTXTS ||
13448
13493
num_vls == 1 ||
13449
13494
krcvqsset <= 1 )
13450
13495
goto bail ;
@@ -13460,38 +13505,36 @@ static void init_qos(struct hfi1_devdata *dd)
13460
13505
m = ilog2 (qpns_per_vl );
13461
13506
if ((m + n ) > 7 )
13462
13507
goto bail ;
13463
- rsmmap = kmalloc_array (NUM_MAP_REGS , sizeof (u64 ), GFP_KERNEL );
13464
- if (!rsmmap )
13508
+ /* enough room in the map table? */
13509
+ rmt_entries = 1 << (m + n );
13510
+ if (rmt -> used + rmt_entries >= NUM_MAP_ENTRIES )
13465
13511
goto bail ;
13466
- memset (rsmmap , rxcontext , NUM_MAP_REGS * sizeof (u64 ));
13467
- /* init the local copy of the table */
13512
+ /* add qos entries to the the RSM map table */
13468
13513
for (i = 0 , ctxt = FIRST_KERNEL_KCTXT ; i < num_vls ; i ++ ) {
13469
13514
unsigned tctxt ;
13470
13515
13471
13516
for (qpn = 0 , tctxt = ctxt ;
13472
13517
krcvqs [i ] && qpn < qpns_per_vl ; qpn ++ ) {
13473
13518
unsigned idx , regoff , regidx ;
13474
13519
13475
- /* generate index <= 128 */
13476
- idx = ( qpn << n ) ^ i ;
13520
+ /* generate the index the hardware will produce */
13521
+ idx = rmt -> used + (( qpn << n ) ^ i ) ;
13477
13522
regoff = (idx % 8 ) * 8 ;
13478
13523
regidx = idx / 8 ;
13479
- reg = rsmmap [ regidx ];
13480
- /* replace 0xff with context number */
13524
+ /* replace default with context number */
13525
+ reg = rmt -> map [ regidx ];
13481
13526
reg &= ~(RCV_RSM_MAP_TABLE_RCV_CONTEXT_A_MASK
13482
13527
<< regoff );
13483
13528
reg |= (u64 )(tctxt ++ ) << regoff ;
13484
- rsmmap [regidx ] = reg ;
13529
+ rmt -> map [regidx ] = reg ;
13485
13530
if (tctxt == ctxt + krcvqs [i ])
13486
13531
tctxt = ctxt ;
13487
13532
}
13488
13533
ctxt += krcvqs [i ];
13489
13534
}
13490
- /* flush cached copies to chip */
13491
- for (i = 0 ; i < NUM_MAP_REGS ; i ++ )
13492
- write_csr (dd , RCV_RSM_MAP_TABLE + (8 * i ), rsmmap [i ]);
13493
13535
/* add rule0 */
13494
13536
write_csr (dd , RCV_RSM_CFG /* + (8 * 0) */ ,
13537
+ (u64 )rmt -> used << RCV_RSM_CFG_OFFSET_SHIFT |
13495
13538
RCV_RSM_CFG_ENABLE_OR_CHAIN_RSM0_MASK <<
13496
13539
RCV_RSM_CFG_ENABLE_OR_CHAIN_RSM0_SHIFT |
13497
13540
2ull << RCV_RSM_CFG_PACKET_TYPE_SHIFT );
@@ -13507,9 +13550,8 @@ static void init_qos(struct hfi1_devdata *dd)
13507
13550
LRH_BTH_VALUE << RCV_RSM_MATCH_VALUE1_SHIFT |
13508
13551
LRH_SC_MASK << RCV_RSM_MATCH_MASK2_SHIFT |
13509
13552
LRH_SC_VALUE << RCV_RSM_MATCH_VALUE2_SHIFT );
13510
- /* Enable RSM */
13511
- add_rcvctrl (dd , RCV_CTRL_RCV_RSM_ENABLE_SMASK );
13512
- kfree (rsmmap );
13553
+ /* mark RSM map entries as used */
13554
+ rmt -> used += rmt_entries ;
13513
13555
/* map everything else to the mcast/err/vl15 context */
13514
13556
init_qpmap_table (dd , HFI1_CTRL_CTXT , HFI1_CTRL_CTXT );
13515
13557
dd -> qos_shift = n + 1 ;
@@ -13521,10 +13563,17 @@ static void init_qos(struct hfi1_devdata *dd)
13521
13563
13522
13564
static void init_rxe (struct hfi1_devdata * dd )
13523
13565
{
13566
+ struct rsm_map_table * rmt ;
13567
+
13524
13568
/* enable all receive errors */
13525
13569
write_csr (dd , RCV_ERR_MASK , ~0ull );
13526
- /* setup QPN map table - start where VL15 context leaves off */
13527
- init_qos (dd );
13570
+
13571
+ rmt = alloc_rsm_map_table (dd );
13572
+ /* set up QOS, including the QPN map table */
13573
+ init_qos (dd , rmt );
13574
+ complete_rsm_map_table (dd , rmt );
13575
+ kfree (rmt );
13576
+
13528
13577
/*
13529
13578
* make sure RcvCtrl.RcvWcb <= PCIe Device Control
13530
13579
* Register Max_Payload_Size (PCI_EXP_DEVCTL in Linux PCIe config
0 commit comments