Skip to content

Commit 3c8c20d

Browse files
Edwin Peerdavem330
authored andcommitted
bnxt_en: move HWRM API implementation into separate file
Move all firmware messaging functions and definitions to new bnxt_hwrm.[ch]. The follow-on patches will make major modifications to these APIs. Signed-off-by: Edwin Peer <[email protected]> Signed-off-by: Michael Chan <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 7b370ad commit 3c8c20d

File tree

13 files changed

+407
-357
lines changed

13 files changed

+407
-357
lines changed
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# SPDX-License-Identifier: GPL-2.0-only
22
obj-$(CONFIG_BNXT) += bnxt_en.o
33

4-
bnxt_en-y := bnxt.o bnxt_sriov.o bnxt_ethtool.o bnxt_dcb.o bnxt_ulp.o bnxt_xdp.o bnxt_ptp.o bnxt_vfr.o bnxt_devlink.o bnxt_dim.o
4+
bnxt_en-y := bnxt.o bnxt_hwrm.o bnxt_sriov.o bnxt_ethtool.o bnxt_dcb.o bnxt_ulp.o bnxt_xdp.o bnxt_ptp.o bnxt_vfr.o bnxt_devlink.o bnxt_dim.o
55
bnxt_en-$(CONFIG_BNXT_FLOWER_OFFLOAD) += bnxt_tc.o
66
bnxt_en-$(CONFIG_DEBUG_FS) += bnxt_debugfs.o

drivers/net/ethernet/broadcom/bnxt/bnxt.c

Lines changed: 1 addition & 272 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@
6060

6161
#include "bnxt_hsi.h"
6262
#include "bnxt.h"
63+
#include "bnxt_hwrm.h"
6364
#include "bnxt_ulp.h"
6465
#include "bnxt_sriov.h"
6566
#include "bnxt_ethtool.h"
@@ -4549,278 +4550,6 @@ static void bnxt_enable_int(struct bnxt *bp)
45494550
}
45504551
}
45514552

4552-
void bnxt_hwrm_cmd_hdr_init(struct bnxt *bp, void *request, u16 req_type,
4553-
u16 cmpl_ring, u16 target_id)
4554-
{
4555-
struct input *req = request;
4556-
4557-
req->req_type = cpu_to_le16(req_type);
4558-
req->cmpl_ring = cpu_to_le16(cmpl_ring);
4559-
req->target_id = cpu_to_le16(target_id);
4560-
req->resp_addr = cpu_to_le64(bp->hwrm_cmd_resp_dma_addr);
4561-
}
4562-
4563-
static int bnxt_hwrm_to_stderr(u32 hwrm_err)
4564-
{
4565-
switch (hwrm_err) {
4566-
case HWRM_ERR_CODE_SUCCESS:
4567-
return 0;
4568-
case HWRM_ERR_CODE_RESOURCE_LOCKED:
4569-
return -EROFS;
4570-
case HWRM_ERR_CODE_RESOURCE_ACCESS_DENIED:
4571-
return -EACCES;
4572-
case HWRM_ERR_CODE_RESOURCE_ALLOC_ERROR:
4573-
return -ENOSPC;
4574-
case HWRM_ERR_CODE_INVALID_PARAMS:
4575-
case HWRM_ERR_CODE_INVALID_FLAGS:
4576-
case HWRM_ERR_CODE_INVALID_ENABLES:
4577-
case HWRM_ERR_CODE_UNSUPPORTED_TLV:
4578-
case HWRM_ERR_CODE_UNSUPPORTED_OPTION_ERR:
4579-
return -EINVAL;
4580-
case HWRM_ERR_CODE_NO_BUFFER:
4581-
return -ENOMEM;
4582-
case HWRM_ERR_CODE_HOT_RESET_PROGRESS:
4583-
case HWRM_ERR_CODE_BUSY:
4584-
return -EAGAIN;
4585-
case HWRM_ERR_CODE_CMD_NOT_SUPPORTED:
4586-
return -EOPNOTSUPP;
4587-
default:
4588-
return -EIO;
4589-
}
4590-
}
4591-
4592-
static int bnxt_hwrm_do_send_msg(struct bnxt *bp, void *msg, u32 msg_len,
4593-
int timeout, bool silent)
4594-
{
4595-
int i, intr_process, rc, tmo_count;
4596-
struct input *req = msg;
4597-
u32 *data = msg;
4598-
u8 *valid;
4599-
u16 cp_ring_id, len = 0;
4600-
struct hwrm_err_output *resp = bp->hwrm_cmd_resp_addr;
4601-
u16 max_req_len = BNXT_HWRM_MAX_REQ_LEN;
4602-
struct hwrm_short_input short_input = {0};
4603-
u32 doorbell_offset = BNXT_GRCPF_REG_CHIMP_COMM_TRIGGER;
4604-
u32 bar_offset = BNXT_GRCPF_REG_CHIMP_COMM;
4605-
u16 dst = BNXT_HWRM_CHNL_CHIMP;
4606-
4607-
if (BNXT_NO_FW_ACCESS(bp) &&
4608-
le16_to_cpu(req->req_type) != HWRM_FUNC_RESET)
4609-
return -EBUSY;
4610-
4611-
if (msg_len > BNXT_HWRM_MAX_REQ_LEN) {
4612-
if (msg_len > bp->hwrm_max_ext_req_len ||
4613-
!bp->hwrm_short_cmd_req_addr)
4614-
return -EINVAL;
4615-
}
4616-
4617-
if (bnxt_kong_hwrm_message(bp, req)) {
4618-
dst = BNXT_HWRM_CHNL_KONG;
4619-
bar_offset = BNXT_GRCPF_REG_KONG_COMM;
4620-
doorbell_offset = BNXT_GRCPF_REG_KONG_COMM_TRIGGER;
4621-
}
4622-
4623-
memset(resp, 0, PAGE_SIZE);
4624-
cp_ring_id = le16_to_cpu(req->cmpl_ring);
4625-
intr_process = (cp_ring_id == INVALID_HW_RING_ID) ? 0 : 1;
4626-
4627-
req->seq_id = cpu_to_le16(bnxt_get_hwrm_seq_id(bp, dst));
4628-
/* currently supports only one outstanding message */
4629-
if (intr_process)
4630-
bp->hwrm_intr_seq_id = le16_to_cpu(req->seq_id);
4631-
4632-
if ((bp->fw_cap & BNXT_FW_CAP_SHORT_CMD) ||
4633-
msg_len > BNXT_HWRM_MAX_REQ_LEN) {
4634-
void *short_cmd_req = bp->hwrm_short_cmd_req_addr;
4635-
u16 max_msg_len;
4636-
4637-
/* Set boundary for maximum extended request length for short
4638-
* cmd format. If passed up from device use the max supported
4639-
* internal req length.
4640-
*/
4641-
max_msg_len = bp->hwrm_max_ext_req_len;
4642-
4643-
memcpy(short_cmd_req, req, msg_len);
4644-
if (msg_len < max_msg_len)
4645-
memset(short_cmd_req + msg_len, 0,
4646-
max_msg_len - msg_len);
4647-
4648-
short_input.req_type = req->req_type;
4649-
short_input.signature =
4650-
cpu_to_le16(SHORT_REQ_SIGNATURE_SHORT_CMD);
4651-
short_input.size = cpu_to_le16(msg_len);
4652-
short_input.req_addr =
4653-
cpu_to_le64(bp->hwrm_short_cmd_req_dma_addr);
4654-
4655-
data = (u32 *)&short_input;
4656-
msg_len = sizeof(short_input);
4657-
4658-
/* Sync memory write before updating doorbell */
4659-
wmb();
4660-
4661-
max_req_len = BNXT_HWRM_SHORT_REQ_LEN;
4662-
}
4663-
4664-
/* Write request msg to hwrm channel */
4665-
__iowrite32_copy(bp->bar0 + bar_offset, data, msg_len / 4);
4666-
4667-
for (i = msg_len; i < max_req_len; i += 4)
4668-
writel(0, bp->bar0 + bar_offset + i);
4669-
4670-
/* Ring channel doorbell */
4671-
writel(1, bp->bar0 + doorbell_offset);
4672-
4673-
if (!pci_is_enabled(bp->pdev))
4674-
return -ENODEV;
4675-
4676-
if (!timeout)
4677-
timeout = DFLT_HWRM_CMD_TIMEOUT;
4678-
/* Limit timeout to an upper limit */
4679-
timeout = min(timeout, HWRM_CMD_MAX_TIMEOUT);
4680-
/* convert timeout to usec */
4681-
timeout *= 1000;
4682-
4683-
i = 0;
4684-
/* Short timeout for the first few iterations:
4685-
* number of loops = number of loops for short timeout +
4686-
* number of loops for standard timeout.
4687-
*/
4688-
tmo_count = HWRM_SHORT_TIMEOUT_COUNTER;
4689-
timeout = timeout - HWRM_SHORT_MIN_TIMEOUT * HWRM_SHORT_TIMEOUT_COUNTER;
4690-
tmo_count += DIV_ROUND_UP(timeout, HWRM_MIN_TIMEOUT);
4691-
4692-
if (intr_process) {
4693-
u16 seq_id = bp->hwrm_intr_seq_id;
4694-
4695-
/* Wait until hwrm response cmpl interrupt is processed */
4696-
while (bp->hwrm_intr_seq_id != (u16)~seq_id &&
4697-
i++ < tmo_count) {
4698-
/* Abort the wait for completion if the FW health
4699-
* check has failed.
4700-
*/
4701-
if (test_bit(BNXT_STATE_FW_FATAL_COND, &bp->state))
4702-
return -EBUSY;
4703-
/* on first few passes, just barely sleep */
4704-
if (i < HWRM_SHORT_TIMEOUT_COUNTER) {
4705-
usleep_range(HWRM_SHORT_MIN_TIMEOUT,
4706-
HWRM_SHORT_MAX_TIMEOUT);
4707-
} else {
4708-
if (HWRM_WAIT_MUST_ABORT(bp, req))
4709-
break;
4710-
usleep_range(HWRM_MIN_TIMEOUT,
4711-
HWRM_MAX_TIMEOUT);
4712-
}
4713-
}
4714-
4715-
if (bp->hwrm_intr_seq_id != (u16)~seq_id) {
4716-
if (!silent)
4717-
netdev_err(bp->dev, "Resp cmpl intr err msg: 0x%x\n",
4718-
le16_to_cpu(req->req_type));
4719-
return -EBUSY;
4720-
}
4721-
len = le16_to_cpu(resp->resp_len);
4722-
valid = ((u8 *)resp) + len - 1;
4723-
} else {
4724-
int j;
4725-
4726-
/* Check if response len is updated */
4727-
for (i = 0; i < tmo_count; i++) {
4728-
/* Abort the wait for completion if the FW health
4729-
* check has failed.
4730-
*/
4731-
if (test_bit(BNXT_STATE_FW_FATAL_COND, &bp->state))
4732-
return -EBUSY;
4733-
len = le16_to_cpu(resp->resp_len);
4734-
if (len)
4735-
break;
4736-
/* on first few passes, just barely sleep */
4737-
if (i < HWRM_SHORT_TIMEOUT_COUNTER) {
4738-
usleep_range(HWRM_SHORT_MIN_TIMEOUT,
4739-
HWRM_SHORT_MAX_TIMEOUT);
4740-
} else {
4741-
if (HWRM_WAIT_MUST_ABORT(bp, req))
4742-
goto timeout_abort;
4743-
usleep_range(HWRM_MIN_TIMEOUT,
4744-
HWRM_MAX_TIMEOUT);
4745-
}
4746-
}
4747-
4748-
if (i >= tmo_count) {
4749-
timeout_abort:
4750-
if (!silent)
4751-
netdev_err(bp->dev, "Error (timeout: %d) msg {0x%x 0x%x} len:%d\n",
4752-
HWRM_TOTAL_TIMEOUT(i),
4753-
le16_to_cpu(req->req_type),
4754-
le16_to_cpu(req->seq_id), len);
4755-
return -EBUSY;
4756-
}
4757-
4758-
/* Last byte of resp contains valid bit */
4759-
valid = ((u8 *)resp) + len - 1;
4760-
for (j = 0; j < HWRM_VALID_BIT_DELAY_USEC; j++) {
4761-
/* make sure we read from updated DMA memory */
4762-
dma_rmb();
4763-
if (*valid)
4764-
break;
4765-
usleep_range(1, 5);
4766-
}
4767-
4768-
if (j >= HWRM_VALID_BIT_DELAY_USEC) {
4769-
if (!silent)
4770-
netdev_err(bp->dev, "Error (timeout: %d) msg {0x%x 0x%x} len:%d v:%d\n",
4771-
HWRM_TOTAL_TIMEOUT(i),
4772-
le16_to_cpu(req->req_type),
4773-
le16_to_cpu(req->seq_id), len,
4774-
*valid);
4775-
return -EBUSY;
4776-
}
4777-
}
4778-
4779-
/* Zero valid bit for compatibility. Valid bit in an older spec
4780-
* may become a new field in a newer spec. We must make sure that
4781-
* a new field not implemented by old spec will read zero.
4782-
*/
4783-
*valid = 0;
4784-
rc = le16_to_cpu(resp->error_code);
4785-
if (rc && !silent)
4786-
netdev_err(bp->dev, "hwrm req_type 0x%x seq id 0x%x error 0x%x\n",
4787-
le16_to_cpu(resp->req_type),
4788-
le16_to_cpu(resp->seq_id), rc);
4789-
return bnxt_hwrm_to_stderr(rc);
4790-
}
4791-
4792-
int _hwrm_send_message(struct bnxt *bp, void *msg, u32 msg_len, int timeout)
4793-
{
4794-
return bnxt_hwrm_do_send_msg(bp, msg, msg_len, timeout, false);
4795-
}
4796-
4797-
int _hwrm_send_message_silent(struct bnxt *bp, void *msg, u32 msg_len,
4798-
int timeout)
4799-
{
4800-
return bnxt_hwrm_do_send_msg(bp, msg, msg_len, timeout, true);
4801-
}
4802-
4803-
int hwrm_send_message(struct bnxt *bp, void *msg, u32 msg_len, int timeout)
4804-
{
4805-
int rc;
4806-
4807-
mutex_lock(&bp->hwrm_cmd_lock);
4808-
rc = _hwrm_send_message(bp, msg, msg_len, timeout);
4809-
mutex_unlock(&bp->hwrm_cmd_lock);
4810-
return rc;
4811-
}
4812-
4813-
int hwrm_send_message_silent(struct bnxt *bp, void *msg, u32 msg_len,
4814-
int timeout)
4815-
{
4816-
int rc;
4817-
4818-
mutex_lock(&bp->hwrm_cmd_lock);
4819-
rc = bnxt_hwrm_do_send_msg(bp, msg, msg_len, timeout, true);
4820-
mutex_unlock(&bp->hwrm_cmd_lock);
4821-
return rc;
4822-
}
4823-
48244553
int bnxt_hwrm_func_drv_rgtr(struct bnxt *bp, unsigned long *bmap, int bmap_size,
48254554
bool async_only)
48264555
{

0 commit comments

Comments
 (0)