Skip to content

Commit 159cf95

Browse files
kadesai16rleon
authored andcommitted
RDMA/bnxt_re: Simplify the function that sends the FW commands
- Use __send_message_basic_sanity helper function. - Do not retry posting same command if there is a queue full detection. - ENXIO is used to indicate controller recovery. - In the case of ERR_DEVICE_DETACHED state, the driver should not post commands to the firmware, but also return fabricated written code. Signed-off-by: Kashyap Desai <kashyap.desai@broadcom.com> Signed-off-by: Selvin Xavier <selvin.xavier@broadcom.com> Link: https://lore.kernel.org/r/1686308514-11996-9-git-send-email-selvin.xavier@broadcom.com Signed-off-by: Leon Romanovsky <leon@kernel.org>
1 parent 65288a2 commit 159cf95

2 files changed

Lines changed: 86 additions & 61 deletions

File tree

drivers/infiniband/hw/bnxt_re/qplib_rcfw.c

Lines changed: 64 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -170,34 +170,22 @@ static int __block_for_resp(struct bnxt_qplib_rcfw *rcfw, u16 cookie, u8 opcode)
170170
static int __send_message(struct bnxt_qplib_rcfw *rcfw,
171171
struct bnxt_qplib_cmdqmsg *msg)
172172
{
173-
struct bnxt_qplib_cmdq_ctx *cmdq = &rcfw->cmdq;
174-
struct bnxt_qplib_hwq *hwq = &cmdq->hwq;
173+
u32 bsize, opcode, free_slots, required_slots;
174+
struct bnxt_qplib_cmdq_ctx *cmdq;
175175
struct bnxt_qplib_crsqe *crsqe;
176176
struct bnxt_qplib_cmdqe *cmdqe;
177+
struct bnxt_qplib_hwq *hwq;
177178
u32 sw_prod, cmdq_prod;
178179
struct pci_dev *pdev;
179180
unsigned long flags;
180-
u32 bsize, opcode;
181181
u16 cookie, cbit;
182182
u8 *preq;
183183

184+
cmdq = &rcfw->cmdq;
185+
hwq = &cmdq->hwq;
184186
pdev = rcfw->pdev;
185187

186188
opcode = __get_cmdq_base_opcode(msg->req, msg->req_sz);
187-
if (!test_bit(FIRMWARE_INITIALIZED_FLAG, &cmdq->flags) &&
188-
(opcode != CMDQ_BASE_OPCODE_QUERY_FUNC &&
189-
opcode != CMDQ_BASE_OPCODE_INITIALIZE_FW &&
190-
opcode != CMDQ_BASE_OPCODE_QUERY_VERSION)) {
191-
dev_err(&pdev->dev,
192-
"RCFW not initialized, reject opcode 0x%x\n", opcode);
193-
return -EINVAL;
194-
}
195-
196-
if (test_bit(FIRMWARE_INITIALIZED_FLAG, &cmdq->flags) &&
197-
opcode == CMDQ_BASE_OPCODE_INITIALIZE_FW) {
198-
dev_err(&pdev->dev, "RCFW already initialized!\n");
199-
return -EINVAL;
200-
}
201189

202190
if (test_bit(FIRMWARE_TIMED_OUT, &cmdq->flags))
203191
return -ETIMEDOUT;
@@ -206,52 +194,44 @@ static int __send_message(struct bnxt_qplib_rcfw *rcfw,
206194
* cmdqe
207195
*/
208196
spin_lock_irqsave(&hwq->lock, flags);
209-
if (msg->req->cmd_size >= HWQ_FREE_SLOTS(hwq)) {
210-
dev_err(&pdev->dev, "RCFW: CMDQ is full!\n");
197+
required_slots = bnxt_qplib_get_cmd_slots(msg->req);
198+
free_slots = HWQ_FREE_SLOTS(hwq);
199+
cookie = cmdq->seq_num & RCFW_MAX_COOKIE_VALUE;
200+
cbit = cookie % rcfw->cmdq_depth;
201+
202+
if (required_slots >= free_slots ||
203+
test_bit(cbit, cmdq->cmdq_bitmap)) {
204+
dev_info_ratelimited(&pdev->dev,
205+
"CMDQ is full req/free %d/%d!",
206+
required_slots, free_slots);
211207
spin_unlock_irqrestore(&hwq->lock, flags);
212208
return -EAGAIN;
213209
}
214-
215-
216-
cookie = cmdq->seq_num & RCFW_MAX_COOKIE_VALUE;
217-
cbit = cookie % rcfw->cmdq_depth;
218210
if (msg->block)
219211
cookie |= RCFW_CMD_IS_BLOCKING;
220-
221212
set_bit(cbit, cmdq->cmdq_bitmap);
222213
__set_cmdq_base_cookie(msg->req, msg->req_sz, cpu_to_le16(cookie));
223214
crsqe = &rcfw->crsqe_tbl[cbit];
224-
if (crsqe->resp) {
225-
spin_unlock_irqrestore(&hwq->lock, flags);
226-
return -EBUSY;
227-
}
228-
229-
/* change the cmd_size to the number of 16byte cmdq unit.
230-
* req->cmd_size is modified here
231-
*/
232215
bsize = bnxt_qplib_set_cmd_slots(msg->req);
233-
234-
memset(msg->resp, 0, sizeof(*msg->resp));
216+
crsqe->free_slots = free_slots;
235217
crsqe->resp = (struct creq_qp_event *)msg->resp;
236218
crsqe->resp->cookie = cpu_to_le16(cookie);
237219
crsqe->req_size = __get_cmdq_base_cmd_size(msg->req, msg->req_sz);
238220
if (__get_cmdq_base_resp_size(msg->req, msg->req_sz) && msg->sb) {
239221
struct bnxt_qplib_rcfw_sbuf *sbuf = msg->sb;
240-
__set_cmdq_base_resp_addr(msg->req, msg->req_sz, cpu_to_le64(sbuf->dma_addr));
222+
223+
__set_cmdq_base_resp_addr(msg->req, msg->req_sz,
224+
cpu_to_le64(sbuf->dma_addr));
241225
__set_cmdq_base_resp_size(msg->req, msg->req_sz,
242-
ALIGN(sbuf->size, BNXT_QPLIB_CMDQE_UNITS));
226+
ALIGN(sbuf->size,
227+
BNXT_QPLIB_CMDQE_UNITS));
243228
}
244229

245230
preq = (u8 *)msg->req;
246231
do {
247232
/* Locate the next cmdq slot */
248233
sw_prod = HWQ_CMP(hwq->prod, hwq);
249234
cmdqe = bnxt_qplib_get_qe(hwq, sw_prod, NULL);
250-
if (!cmdqe) {
251-
dev_err(&pdev->dev,
252-
"RCFW request failed with no cmdqe!\n");
253-
goto done;
254-
}
255235
/* Copy a segment of the req cmd to the cmdq */
256236
memset(cmdqe, 0, sizeof(*cmdqe));
257237
memcpy(cmdqe, preq, min_t(u32, bsize, sizeof(*cmdqe)));
@@ -275,12 +255,43 @@ static int __send_message(struct bnxt_qplib_rcfw *rcfw,
275255
wmb();
276256
writel(cmdq_prod, cmdq->cmdq_mbox.prod);
277257
writel(RCFW_CMDQ_TRIG_VAL, cmdq->cmdq_mbox.db);
278-
done:
279258
spin_unlock_irqrestore(&hwq->lock, flags);
280259
/* Return the CREQ response pointer */
281260
return 0;
282261
}
283262

263+
static int __send_message_basic_sanity(struct bnxt_qplib_rcfw *rcfw,
264+
struct bnxt_qplib_cmdqmsg *msg)
265+
{
266+
struct bnxt_qplib_cmdq_ctx *cmdq;
267+
u32 opcode;
268+
269+
cmdq = &rcfw->cmdq;
270+
opcode = __get_cmdq_base_opcode(msg->req, msg->req_sz);
271+
272+
/* Prevent posting if f/w is not in a state to process */
273+
if (test_bit(ERR_DEVICE_DETACHED, &rcfw->cmdq.flags))
274+
return -ENXIO;
275+
276+
if (test_bit(FIRMWARE_INITIALIZED_FLAG, &cmdq->flags) &&
277+
opcode == CMDQ_BASE_OPCODE_INITIALIZE_FW) {
278+
dev_err(&rcfw->pdev->dev, "QPLIB: RCFW already initialized!");
279+
return -EINVAL;
280+
}
281+
282+
if (!test_bit(FIRMWARE_INITIALIZED_FLAG, &cmdq->flags) &&
283+
(opcode != CMDQ_BASE_OPCODE_QUERY_FUNC &&
284+
opcode != CMDQ_BASE_OPCODE_INITIALIZE_FW &&
285+
opcode != CMDQ_BASE_OPCODE_QUERY_VERSION)) {
286+
dev_err(&rcfw->pdev->dev,
287+
"QPLIB: RCFW not initialized, reject opcode 0x%x",
288+
opcode);
289+
return -EOPNOTSUPP;
290+
}
291+
292+
return 0;
293+
}
294+
284295
/**
285296
* __bnxt_qplib_rcfw_send_message - qplib interface to send
286297
* and complete rcfw command.
@@ -299,29 +310,21 @@ static int __bnxt_qplib_rcfw_send_message(struct bnxt_qplib_rcfw *rcfw,
299310
{
300311
struct creq_qp_event *evnt = (struct creq_qp_event *)msg->resp;
301312
u16 cookie;
302-
u8 opcode, retry_cnt = 0xFF;
303313
int rc = 0;
314+
u8 opcode;
304315

305-
/* Prevent posting if f/w is not in a state to process */
306-
if (test_bit(ERR_DEVICE_DETACHED, &rcfw->cmdq.flags))
307-
return 0;
316+
opcode = __get_cmdq_base_opcode(msg->req, msg->req_sz);
308317

309-
do {
310-
opcode = __get_cmdq_base_opcode(msg->req, msg->req_sz);
311-
rc = __send_message(rcfw, msg);
312-
cookie = le16_to_cpu(__get_cmdq_base_cookie(msg->req, msg->req_sz)) &
313-
RCFW_MAX_COOKIE_VALUE;
314-
if (!rc)
315-
break;
316-
if (!retry_cnt || (rc != -EAGAIN && rc != -EBUSY)) {
317-
/* send failed */
318-
dev_err(&rcfw->pdev->dev, "cmdq[%#x]=%#x send failed\n",
319-
cookie, opcode);
320-
return rc;
321-
}
322-
msg->block ? mdelay(1) : usleep_range(500, 1000);
318+
rc = __send_message_basic_sanity(rcfw, msg);
319+
if (rc)
320+
return rc == -ENXIO ? bnxt_qplib_map_rc(opcode) : rc;
321+
322+
rc = __send_message(rcfw, msg);
323+
if (rc)
324+
return rc;
323325

324-
} while (retry_cnt--);
326+
cookie = le16_to_cpu(__get_cmdq_base_cookie(msg->req, msg->req_sz))
327+
& RCFW_MAX_COOKIE_VALUE;
325328

326329
if (msg->block)
327330
rc = __block_for_resp(rcfw, cookie, opcode);

drivers/infiniband/hw/bnxt_re/qplib_rcfw.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,26 @@ static inline u32 bnxt_qplib_cmdqe_page_size(u32 depth)
8989
return (bnxt_qplib_cmdqe_npages(depth) * PAGE_SIZE);
9090
}
9191

92+
/* Get the number of command units required for the req. The
93+
* function returns correct value only if called before
94+
* setting using bnxt_qplib_set_cmd_slots
95+
*/
96+
static inline u32 bnxt_qplib_get_cmd_slots(struct cmdq_base *req)
97+
{
98+
u32 cmd_units = 0;
99+
100+
if (HAS_TLV_HEADER(req)) {
101+
struct roce_tlv *tlv_req = (struct roce_tlv *)req;
102+
103+
cmd_units = tlv_req->total_size;
104+
} else {
105+
cmd_units = (req->cmd_size + BNXT_QPLIB_CMDQE_UNITS - 1) /
106+
BNXT_QPLIB_CMDQE_UNITS;
107+
}
108+
109+
return cmd_units;
110+
}
111+
92112
static inline u32 bnxt_qplib_set_cmd_slots(struct cmdq_base *req)
93113
{
94114
u32 cmd_byte = 0;
@@ -130,6 +150,8 @@ typedef int (*aeq_handler_t)(struct bnxt_qplib_rcfw *, void *, void *);
130150
struct bnxt_qplib_crsqe {
131151
struct creq_qp_event *resp;
132152
u32 req_size;
153+
/* Free slots at the time of submission */
154+
u32 free_slots;
133155
};
134156

135157
struct bnxt_qplib_rcfw_sbuf {

0 commit comments

Comments
 (0)