Skip to content

Commit 372cc85

Browse files
Dean Luickdledford
authored andcommitted
IB/hfi1: Extract RSM map table init from QOS
Refactor the allocation, tracking, and writing of the RSM map table into its own set of routines. This will allow the map table to be passed to multiple users to fill in as needed. Start with the original user, QOS. Reviewed-by: Dennis Dalessandro <[email protected]> Signed-off-by: Dean Luick <[email protected]> Signed-off-by: Doug Ledford <[email protected]>
1 parent 44306f1 commit 372cc85

File tree

2 files changed

+71
-21
lines changed

2 files changed

+71
-21
lines changed

drivers/staging/rdma/hfi1/chip.c

Lines changed: 70 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,8 @@ struct flag_table {
123123

124124
#define MIN_KERNEL_KCTXTS 2
125125
#define FIRST_KERNEL_KCTXT 1
126+
/* sizes for both the QP and RSM map tables */
127+
#define NUM_MAP_ENTRIES 256
126128
#define NUM_MAP_REGS 32
127129

128130
/* Bit offset into the GUID which carries HFI id information */
@@ -13422,9 +13424,52 @@ static void init_qpmap_table(struct hfi1_devdata *dd,
1342213424
| RCV_CTRL_RCV_BYPASS_ENABLE_SMASK);
1342313425
}
1342413426

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+
1342513469
/**
1342613470
* init_qos - init RX qos
1342713471
* @dd - device data
13472+
* @rmt - RSM map table
1342813473
*
1342913474
* This routine initializes Rule 0 and the RSM map table to implement
1343013475
* quality of service (qos).
@@ -13435,16 +13480,16 @@ static void init_qpmap_table(struct hfi1_devdata *dd,
1343513480
* The number of vl bits (n) and the number of qpn bits (m) are computed to
1343613481
* feed both the RSM map table and the single rule.
1343713482
*/
13438-
static void init_qos(struct hfi1_devdata *dd)
13483+
static void init_qos(struct hfi1_devdata *dd, struct rsm_map_table *rmt)
1343913484
{
1344013485
u8 max_by_vl = 0;
1344113486
unsigned qpns_per_vl, ctxt, i, qpn, n = 1, m;
13442-
u64 *rsmmap;
13487+
unsigned int rmt_entries;
1344313488
u64 reg;
13444-
u8 rxcontext = is_ax(dd) ? 0 : 0xff; /* 0 is default if a0 ver. */
1344513489

1344613490
/* validate */
13447-
if (dd->n_krcv_queues <= MIN_KERNEL_KCTXTS ||
13491+
if (!rmt ||
13492+
dd->n_krcv_queues <= MIN_KERNEL_KCTXTS ||
1344813493
num_vls == 1 ||
1344913494
krcvqsset <= 1)
1345013495
goto bail;
@@ -13460,38 +13505,36 @@ static void init_qos(struct hfi1_devdata *dd)
1346013505
m = ilog2(qpns_per_vl);
1346113506
if ((m + n) > 7)
1346213507
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)
1346513511
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 */
1346813513
for (i = 0, ctxt = FIRST_KERNEL_KCTXT; i < num_vls; i++) {
1346913514
unsigned tctxt;
1347013515

1347113516
for (qpn = 0, tctxt = ctxt;
1347213517
krcvqs[i] && qpn < qpns_per_vl; qpn++) {
1347313518
unsigned idx, regoff, regidx;
1347413519

13475-
/* generate index <= 128 */
13476-
idx = (qpn << n) ^ i;
13520+
/* generate the index the hardware will produce */
13521+
idx = rmt->used + ((qpn << n) ^ i);
1347713522
regoff = (idx % 8) * 8;
1347813523
regidx = idx / 8;
13479-
reg = rsmmap[regidx];
13480-
/* replace 0xff with context number */
13524+
/* replace default with context number */
13525+
reg = rmt->map[regidx];
1348113526
reg &= ~(RCV_RSM_MAP_TABLE_RCV_CONTEXT_A_MASK
1348213527
<< regoff);
1348313528
reg |= (u64)(tctxt++) << regoff;
13484-
rsmmap[regidx] = reg;
13529+
rmt->map[regidx] = reg;
1348513530
if (tctxt == ctxt + krcvqs[i])
1348613531
tctxt = ctxt;
1348713532
}
1348813533
ctxt += krcvqs[i];
1348913534
}
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]);
1349313535
/* add rule0 */
1349413536
write_csr(dd, RCV_RSM_CFG /* + (8 * 0) */,
13537+
(u64)rmt->used << RCV_RSM_CFG_OFFSET_SHIFT |
1349513538
RCV_RSM_CFG_ENABLE_OR_CHAIN_RSM0_MASK <<
1349613539
RCV_RSM_CFG_ENABLE_OR_CHAIN_RSM0_SHIFT |
1349713540
2ull << RCV_RSM_CFG_PACKET_TYPE_SHIFT);
@@ -13507,9 +13550,8 @@ static void init_qos(struct hfi1_devdata *dd)
1350713550
LRH_BTH_VALUE << RCV_RSM_MATCH_VALUE1_SHIFT |
1350813551
LRH_SC_MASK << RCV_RSM_MATCH_MASK2_SHIFT |
1350913552
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;
1351313555
/* map everything else to the mcast/err/vl15 context */
1351413556
init_qpmap_table(dd, HFI1_CTRL_CTXT, HFI1_CTRL_CTXT);
1351513557
dd->qos_shift = n + 1;
@@ -13521,10 +13563,17 @@ static void init_qos(struct hfi1_devdata *dd)
1352113563

1352213564
static void init_rxe(struct hfi1_devdata *dd)
1352313565
{
13566+
struct rsm_map_table *rmt;
13567+
1352413568
/* enable all receive errors */
1352513569
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+
1352813577
/*
1352913578
* make sure RcvCtrl.RcvWcb <= PCIe Device Control
1353013579
* Register Max_Payload_Size (PCI_EXP_DEVCTL in Linux PCIe config

drivers/staging/rdma/hfi1/chip_registers.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -771,6 +771,7 @@
771771
#define RCV_RSM_CFG_ENABLE_OR_CHAIN_RSM0_MASK 0x1ull
772772
#define RCV_RSM_CFG_ENABLE_OR_CHAIN_RSM0_SHIFT 0
773773
#define RCV_RSM_CFG_PACKET_TYPE_SHIFT 60
774+
#define RCV_RSM_CFG_OFFSET_SHIFT 32
774775
#define RCV_RSM_MAP_TABLE (RXE + 0x000000000900)
775776
#define RCV_RSM_MAP_TABLE_RCV_CONTEXT_A_MASK 0xFFull
776777
#define RCV_RSM_MATCH (RXE + 0x000000000800)

0 commit comments

Comments
 (0)