Commit 49f9df5b authored by David S. Miller's avatar David S. Miller

Merge branch 'bnxt_en-fw-messages'

Michael Chan says:

====================
bnxt_en: Implement new driver APIs to send FW messages

The current driver APIs to send messages to the firmware allow only one
outstanding message in flight.  There is only one buffer for the firmware
response for each firmware channel.  To send a firmware message, all
callers must take a mutex and it is released after the firmware response
has been read.  This scheme does not allow multiple firmware messages
in flight.  Firmware may take a long time to respond to some messages
(e.g. NVRAM related ones) and this causes the mutex to be held for
a long time, blocking other callers.

This patchset intoduces the new driver APIs to address the above
shortcomings.  The new APIs are compatible with new and old firmware.
But the new deferred firmware response mechanism will require newer
firmware in order to allow multiple outstanding firmware commands.

All callers are updated to use the new APIs.

v2: Patch 4 and patch 9 updated to fix issues reported by test robot
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents eaf2aaec 68f684e2
# SPDX-License-Identifier: GPL-2.0-only # SPDX-License-Identifier: GPL-2.0-only
obj-$(CONFIG_BNXT) += bnxt_en.o obj-$(CONFIG_BNXT) += bnxt_en.o
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 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
bnxt_en-$(CONFIG_BNXT_FLOWER_OFFLOAD) += bnxt_tc.o bnxt_en-$(CONFIG_BNXT_FLOWER_OFFLOAD) += bnxt_tc.o
bnxt_en-$(CONFIG_DEBUG_FS) += bnxt_debugfs.o bnxt_en-$(CONFIG_DEBUG_FS) += bnxt_debugfs.o
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -669,37 +669,7 @@ struct nqe_cn { ...@@ -669,37 +669,7 @@ struct nqe_cn {
#define RING_CMP(idx) ((idx) & bp->cp_ring_mask) #define RING_CMP(idx) ((idx) & bp->cp_ring_mask)
#define NEXT_CMP(idx) RING_CMP(ADV_RAW_CMP(idx, 1)) #define NEXT_CMP(idx) RING_CMP(ADV_RAW_CMP(idx, 1))
#define BNXT_HWRM_MAX_REQ_LEN (bp->hwrm_max_req_len)
#define BNXT_HWRM_SHORT_REQ_LEN sizeof(struct hwrm_short_input)
#define DFLT_HWRM_CMD_TIMEOUT 500 #define DFLT_HWRM_CMD_TIMEOUT 500
#define HWRM_CMD_MAX_TIMEOUT 40000
#define SHORT_HWRM_CMD_TIMEOUT 20
#define HWRM_CMD_TIMEOUT (bp->hwrm_cmd_timeout)
#define HWRM_RESET_TIMEOUT ((HWRM_CMD_TIMEOUT) * 4)
#define HWRM_COREDUMP_TIMEOUT ((HWRM_CMD_TIMEOUT) * 12)
#define BNXT_HWRM_REQ_MAX_SIZE 128
#define BNXT_HWRM_REQS_PER_PAGE (BNXT_PAGE_SIZE / \
BNXT_HWRM_REQ_MAX_SIZE)
#define HWRM_SHORT_MIN_TIMEOUT 3
#define HWRM_SHORT_MAX_TIMEOUT 10
#define HWRM_SHORT_TIMEOUT_COUNTER 5
#define HWRM_MIN_TIMEOUT 25
#define HWRM_MAX_TIMEOUT 40
#define HWRM_WAIT_MUST_ABORT(bp, req) \
(le16_to_cpu((req)->req_type) != HWRM_VER_GET && \
!bnxt_is_fw_healthy(bp))
#define HWRM_TOTAL_TIMEOUT(n) (((n) <= HWRM_SHORT_TIMEOUT_COUNTER) ? \
((n) * HWRM_SHORT_MIN_TIMEOUT) : \
(HWRM_SHORT_TIMEOUT_COUNTER * HWRM_SHORT_MIN_TIMEOUT + \
((n) - HWRM_SHORT_TIMEOUT_COUNTER) * HWRM_MIN_TIMEOUT))
#define HWRM_VALID_BIT_DELAY_USEC 150
#define BNXT_HWRM_CHNL_CHIMP 0
#define BNXT_HWRM_CHNL_KONG 1
#define BNXT_RX_EVENT 1 #define BNXT_RX_EVENT 1
#define BNXT_AGG_EVENT 2 #define BNXT_AGG_EVENT 2
...@@ -1910,13 +1880,8 @@ struct bnxt { ...@@ -1910,13 +1880,8 @@ struct bnxt {
u32 hwrm_spec_code; u32 hwrm_spec_code;
u16 hwrm_cmd_seq; u16 hwrm_cmd_seq;
u16 hwrm_cmd_kong_seq; u16 hwrm_cmd_kong_seq;
u16 hwrm_intr_seq_id; struct dma_pool *hwrm_dma_pool;
void *hwrm_short_cmd_req_addr; struct hlist_head hwrm_pending_list;
dma_addr_t hwrm_short_cmd_req_dma_addr;
void *hwrm_cmd_resp_addr;
dma_addr_t hwrm_cmd_resp_dma_addr;
void *hwrm_cmd_kong_resp_addr;
dma_addr_t hwrm_cmd_kong_resp_dma_addr;
struct rtnl_link_stats64 net_stats_prev; struct rtnl_link_stats64 net_stats_prev;
struct bnxt_stats_mem port_stats; struct bnxt_stats_mem port_stats;
...@@ -2016,7 +1981,7 @@ struct bnxt { ...@@ -2016,7 +1981,7 @@ struct bnxt {
struct mutex sriov_lock; struct mutex sriov_lock;
#endif #endif
#if BITS_PER_LONG == 32 #ifndef writeq
/* ensure atomic 64-bit doorbell writes on 32-bit systems. */ /* ensure atomic 64-bit doorbell writes on 32-bit systems. */
spinlock_t db_lock; spinlock_t db_lock;
#endif #endif
...@@ -2145,7 +2110,7 @@ static inline u32 bnxt_tx_avail(struct bnxt *bp, struct bnxt_tx_ring_info *txr) ...@@ -2145,7 +2110,7 @@ static inline u32 bnxt_tx_avail(struct bnxt *bp, struct bnxt_tx_ring_info *txr)
((txr->tx_prod - txr->tx_cons) & bp->tx_ring_mask); ((txr->tx_prod - txr->tx_cons) & bp->tx_ring_mask);
} }
#if BITS_PER_LONG == 32 #ifndef writeq
#define writeq(val64, db) \ #define writeq(val64, db) \
do { \ do { \
spin_lock(&bp->db_lock); \ spin_lock(&bp->db_lock); \
...@@ -2187,63 +2152,6 @@ static inline void bnxt_db_write(struct bnxt *bp, struct bnxt_db_info *db, ...@@ -2187,63 +2152,6 @@ static inline void bnxt_db_write(struct bnxt *bp, struct bnxt_db_info *db,
} }
} }
static inline bool bnxt_cfa_hwrm_message(u16 req_type)
{
switch (req_type) {
case HWRM_CFA_ENCAP_RECORD_ALLOC:
case HWRM_CFA_ENCAP_RECORD_FREE:
case HWRM_CFA_DECAP_FILTER_ALLOC:
case HWRM_CFA_DECAP_FILTER_FREE:
case HWRM_CFA_EM_FLOW_ALLOC:
case HWRM_CFA_EM_FLOW_FREE:
case HWRM_CFA_EM_FLOW_CFG:
case HWRM_CFA_FLOW_ALLOC:
case HWRM_CFA_FLOW_FREE:
case HWRM_CFA_FLOW_INFO:
case HWRM_CFA_FLOW_FLUSH:
case HWRM_CFA_FLOW_STATS:
case HWRM_CFA_METER_PROFILE_ALLOC:
case HWRM_CFA_METER_PROFILE_FREE:
case HWRM_CFA_METER_PROFILE_CFG:
case HWRM_CFA_METER_INSTANCE_ALLOC:
case HWRM_CFA_METER_INSTANCE_FREE:
return true;
default:
return false;
}
}
static inline bool bnxt_kong_hwrm_message(struct bnxt *bp, struct input *req)
{
return (bp->fw_cap & BNXT_FW_CAP_KONG_MB_CHNL &&
bnxt_cfa_hwrm_message(le16_to_cpu(req->req_type)));
}
static inline bool bnxt_hwrm_kong_chnl(struct bnxt *bp, struct input *req)
{
return (bp->fw_cap & BNXT_FW_CAP_KONG_MB_CHNL &&
req->resp_addr == cpu_to_le64(bp->hwrm_cmd_kong_resp_dma_addr));
}
static inline void *bnxt_get_hwrm_resp_addr(struct bnxt *bp, void *req)
{
if (bnxt_hwrm_kong_chnl(bp, (struct input *)req))
return bp->hwrm_cmd_kong_resp_addr;
else
return bp->hwrm_cmd_resp_addr;
}
static inline u16 bnxt_get_hwrm_seq_id(struct bnxt *bp, u16 dst)
{
u16 seq_id;
if (dst == BNXT_HWRM_CHNL_CHIMP)
seq_id = bp->hwrm_cmd_seq++;
else
seq_id = bp->hwrm_cmd_kong_seq++;
return seq_id;
}
extern const u16 bnxt_lhint_arr[]; extern const u16 bnxt_lhint_arr[];
int bnxt_alloc_rx_data(struct bnxt *bp, struct bnxt_rx_ring_info *rxr, int bnxt_alloc_rx_data(struct bnxt *bp, struct bnxt_rx_ring_info *rxr,
...@@ -2253,11 +2161,6 @@ u32 bnxt_fw_health_readl(struct bnxt *bp, int reg_idx); ...@@ -2253,11 +2161,6 @@ u32 bnxt_fw_health_readl(struct bnxt *bp, int reg_idx);
void bnxt_set_tpa_flags(struct bnxt *bp); void bnxt_set_tpa_flags(struct bnxt *bp);
void bnxt_set_ring_params(struct bnxt *); void bnxt_set_ring_params(struct bnxt *);
int bnxt_set_rx_skb_mode(struct bnxt *bp, bool page_mode); int bnxt_set_rx_skb_mode(struct bnxt *bp, bool page_mode);
void bnxt_hwrm_cmd_hdr_init(struct bnxt *, void *, u16, u16, u16);
int _hwrm_send_message(struct bnxt *, void *, u32, int);
int _hwrm_send_message_silent(struct bnxt *bp, void *msg, u32 len, int timeout);
int hwrm_send_message(struct bnxt *, void *, u32, int);
int hwrm_send_message_silent(struct bnxt *, void *, u32, int);
int bnxt_hwrm_func_drv_rgtr(struct bnxt *bp, unsigned long *bmap, int bnxt_hwrm_func_drv_rgtr(struct bnxt *bp, unsigned long *bmap,
int bmap_size, bool async_only); int bmap_size, bool async_only);
int bnxt_get_nr_rss_ctxs(struct bnxt *bp, int rx_rings); int bnxt_get_nr_rss_ctxs(struct bnxt *bp, int rx_rings);
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include <net/devlink.h> #include <net/devlink.h>
#include "bnxt_hsi.h" #include "bnxt_hsi.h"
#include "bnxt.h" #include "bnxt.h"
#include "bnxt_hwrm.h"
#include "bnxt_vfr.h" #include "bnxt_vfr.h"
#include "bnxt_devlink.h" #include "bnxt_devlink.h"
#include "bnxt_ethtool.h" #include "bnxt_ethtool.h"
...@@ -354,28 +355,34 @@ static void bnxt_copy_from_nvm_data(union devlink_param_value *dst, ...@@ -354,28 +355,34 @@ static void bnxt_copy_from_nvm_data(union devlink_param_value *dst,
static int bnxt_hwrm_get_nvm_cfg_ver(struct bnxt *bp, static int bnxt_hwrm_get_nvm_cfg_ver(struct bnxt *bp,
union devlink_param_value *nvm_cfg_ver) union devlink_param_value *nvm_cfg_ver)
{ {
struct hwrm_nvm_get_variable_input req = {0}; struct hwrm_nvm_get_variable_input *req;
union bnxt_nvm_data *data; union bnxt_nvm_data *data;
dma_addr_t data_dma_addr; dma_addr_t data_dma_addr;
int rc; int rc;
bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_NVM_GET_VARIABLE, -1, -1); rc = hwrm_req_init(bp, req, HWRM_NVM_GET_VARIABLE);
data = dma_alloc_coherent(&bp->pdev->dev, sizeof(*data), if (rc)
&data_dma_addr, GFP_KERNEL); return rc;
if (!data)
return -ENOMEM; data = hwrm_req_dma_slice(bp, req, sizeof(*data), &data_dma_addr);
if (!data) {
rc = -ENOMEM;
goto exit;
}
req.dest_data_addr = cpu_to_le64(data_dma_addr); hwrm_req_hold(bp, req);
req.data_len = cpu_to_le16(BNXT_NVM_CFG_VER_BITS); req->dest_data_addr = cpu_to_le64(data_dma_addr);
req.option_num = cpu_to_le16(NVM_OFF_NVM_CFG_VER); req->data_len = cpu_to_le16(BNXT_NVM_CFG_VER_BITS);
req->option_num = cpu_to_le16(NVM_OFF_NVM_CFG_VER);
rc = hwrm_send_message_silent(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT); rc = hwrm_req_send_silent(bp, req);
if (!rc) if (!rc)
bnxt_copy_from_nvm_data(nvm_cfg_ver, data, bnxt_copy_from_nvm_data(nvm_cfg_ver, data,
BNXT_NVM_CFG_VER_BITS, BNXT_NVM_CFG_VER_BITS,
BNXT_NVM_CFG_VER_BYTES); BNXT_NVM_CFG_VER_BYTES);
dma_free_coherent(&bp->pdev->dev, sizeof(*data), data, data_dma_addr); exit:
hwrm_req_drop(bp, req);
return rc; return rc;
} }
...@@ -562,17 +569,20 @@ static int bnxt_dl_info_get(struct devlink *dl, struct devlink_info_req *req, ...@@ -562,17 +569,20 @@ static int bnxt_dl_info_get(struct devlink *dl, struct devlink_info_req *req,
} }
static int bnxt_hwrm_nvm_req(struct bnxt *bp, u32 param_id, void *msg, static int bnxt_hwrm_nvm_req(struct bnxt *bp, u32 param_id, void *msg,
int msg_len, union devlink_param_value *val) union devlink_param_value *val)
{ {
struct hwrm_nvm_get_variable_input *req = msg; struct hwrm_nvm_get_variable_input *req = msg;
struct bnxt_dl_nvm_param nvm_param; struct bnxt_dl_nvm_param nvm_param;
struct hwrm_err_output *resp;
union bnxt_nvm_data *data; union bnxt_nvm_data *data;
dma_addr_t data_dma_addr; dma_addr_t data_dma_addr;
int idx = 0, rc, i; int idx = 0, rc, i;
/* Get/Set NVM CFG parameter is supported only on PFs */ /* Get/Set NVM CFG parameter is supported only on PFs */
if (BNXT_VF(bp)) if (BNXT_VF(bp)) {
hwrm_req_drop(bp, req);
return -EPERM; return -EPERM;
}
for (i = 0; i < ARRAY_SIZE(nvm_params); i++) { for (i = 0; i < ARRAY_SIZE(nvm_params); i++) {
if (nvm_params[i].id == param_id) { if (nvm_params[i].id == param_id) {
...@@ -581,18 +591,22 @@ static int bnxt_hwrm_nvm_req(struct bnxt *bp, u32 param_id, void *msg, ...@@ -581,18 +591,22 @@ static int bnxt_hwrm_nvm_req(struct bnxt *bp, u32 param_id, void *msg,
} }
} }
if (i == ARRAY_SIZE(nvm_params)) if (i == ARRAY_SIZE(nvm_params)) {
hwrm_req_drop(bp, req);
return -EOPNOTSUPP; return -EOPNOTSUPP;
}
if (nvm_param.dir_type == BNXT_NVM_PORT_CFG) if (nvm_param.dir_type == BNXT_NVM_PORT_CFG)
idx = bp->pf.port_id; idx = bp->pf.port_id;
else if (nvm_param.dir_type == BNXT_NVM_FUNC_CFG) else if (nvm_param.dir_type == BNXT_NVM_FUNC_CFG)
idx = bp->pf.fw_fid - BNXT_FIRST_PF_FID; idx = bp->pf.fw_fid - BNXT_FIRST_PF_FID;
data = dma_alloc_coherent(&bp->pdev->dev, sizeof(*data), data = hwrm_req_dma_slice(bp, req, sizeof(*data), &data_dma_addr);
&data_dma_addr, GFP_KERNEL);
if (!data) if (!data) {
hwrm_req_drop(bp, req);
return -ENOMEM; return -ENOMEM;
}
req->dest_data_addr = cpu_to_le64(data_dma_addr); req->dest_data_addr = cpu_to_le64(data_dma_addr);
req->data_len = cpu_to_le16(nvm_param.nvm_num_bits); req->data_len = cpu_to_le16(nvm_param.nvm_num_bits);
...@@ -601,26 +615,24 @@ static int bnxt_hwrm_nvm_req(struct bnxt *bp, u32 param_id, void *msg, ...@@ -601,26 +615,24 @@ static int bnxt_hwrm_nvm_req(struct bnxt *bp, u32 param_id, void *msg,
if (idx) if (idx)
req->dimensions = cpu_to_le16(1); req->dimensions = cpu_to_le16(1);
resp = hwrm_req_hold(bp, req);
if (req->req_type == cpu_to_le16(HWRM_NVM_SET_VARIABLE)) { if (req->req_type == cpu_to_le16(HWRM_NVM_SET_VARIABLE)) {
bnxt_copy_to_nvm_data(data, val, nvm_param.nvm_num_bits, bnxt_copy_to_nvm_data(data, val, nvm_param.nvm_num_bits,
nvm_param.dl_num_bytes); nvm_param.dl_num_bytes);
rc = hwrm_send_message(bp, msg, msg_len, HWRM_CMD_TIMEOUT); rc = hwrm_req_send(bp, msg);
} else { } else {
rc = hwrm_send_message_silent(bp, msg, msg_len, rc = hwrm_req_send_silent(bp, msg);
HWRM_CMD_TIMEOUT);
if (!rc) { if (!rc) {
bnxt_copy_from_nvm_data(val, data, bnxt_copy_from_nvm_data(val, data,
nvm_param.nvm_num_bits, nvm_param.nvm_num_bits,
nvm_param.dl_num_bytes); nvm_param.dl_num_bytes);
} else { } else {
struct hwrm_err_output *resp = bp->hwrm_cmd_resp_addr;
if (resp->cmd_err == if (resp->cmd_err ==
NVM_GET_VARIABLE_CMD_ERR_CODE_VAR_NOT_EXIST) NVM_GET_VARIABLE_CMD_ERR_CODE_VAR_NOT_EXIST)
rc = -EOPNOTSUPP; rc = -EOPNOTSUPP;
} }
} }
dma_free_coherent(&bp->pdev->dev, sizeof(*data), data, data_dma_addr); hwrm_req_drop(bp, req);
if (rc == -EACCES) if (rc == -EACCES)
netdev_err(bp->dev, "PF does not have admin privileges to modify NVM config\n"); netdev_err(bp->dev, "PF does not have admin privileges to modify NVM config\n");
return rc; return rc;
...@@ -629,15 +641,17 @@ static int bnxt_hwrm_nvm_req(struct bnxt *bp, u32 param_id, void *msg, ...@@ -629,15 +641,17 @@ static int bnxt_hwrm_nvm_req(struct bnxt *bp, u32 param_id, void *msg,
static int bnxt_dl_nvm_param_get(struct devlink *dl, u32 id, static int bnxt_dl_nvm_param_get(struct devlink *dl, u32 id,
struct devlink_param_gset_ctx *ctx) struct devlink_param_gset_ctx *ctx)
{ {
struct hwrm_nvm_get_variable_input req = {0};
struct bnxt *bp = bnxt_get_bp_from_dl(dl); struct bnxt *bp = bnxt_get_bp_from_dl(dl);
struct hwrm_nvm_get_variable_input *req;
int rc; int rc;
bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_NVM_GET_VARIABLE, -1, -1); rc = hwrm_req_init(bp, req, HWRM_NVM_GET_VARIABLE);
rc = bnxt_hwrm_nvm_req(bp, id, &req, sizeof(req), &ctx->val); if (rc)
if (!rc) return rc;
if (id == BNXT_DEVLINK_PARAM_ID_GRE_VER_CHECK)
ctx->val.vbool = !ctx->val.vbool; rc = bnxt_hwrm_nvm_req(bp, id, req, &ctx->val);
if (!rc && id == BNXT_DEVLINK_PARAM_ID_GRE_VER_CHECK)
ctx->val.vbool = !ctx->val.vbool;
return rc; return rc;
} }
...@@ -645,15 +659,18 @@ static int bnxt_dl_nvm_param_get(struct devlink *dl, u32 id, ...@@ -645,15 +659,18 @@ static int bnxt_dl_nvm_param_get(struct devlink *dl, u32 id,
static int bnxt_dl_nvm_param_set(struct devlink *dl, u32 id, static int bnxt_dl_nvm_param_set(struct devlink *dl, u32 id,
struct devlink_param_gset_ctx *ctx) struct devlink_param_gset_ctx *ctx)
{ {
struct hwrm_nvm_set_variable_input req = {0};
struct bnxt *bp = bnxt_get_bp_from_dl(dl); struct bnxt *bp = bnxt_get_bp_from_dl(dl);
struct hwrm_nvm_set_variable_input *req;
int rc;
bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_NVM_SET_VARIABLE, -1, -1); rc = hwrm_req_init(bp, req, HWRM_NVM_SET_VARIABLE);
if (rc)
return rc;
if (id == BNXT_DEVLINK_PARAM_ID_GRE_VER_CHECK) if (id == BNXT_DEVLINK_PARAM_ID_GRE_VER_CHECK)
ctx->val.vbool = !ctx->val.vbool; ctx->val.vbool = !ctx->val.vbool;
return bnxt_hwrm_nvm_req(bp, id, &req, sizeof(req), &ctx->val); return bnxt_hwrm_nvm_req(bp, id, req, &ctx->val);
} }
static int bnxt_dl_msix_validate(struct devlink *dl, u32 id, static int bnxt_dl_msix_validate(struct devlink *dl, u32 id,
......
This diff is collapsed.
/* Broadcom NetXtreme-C/E network driver.
*
* Copyright (c) 2020 Broadcom Limited
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation.
*/
#ifndef BNXT_HWRM_H
#define BNXT_HWRM_H
#include "bnxt_hsi.h"
enum bnxt_hwrm_ctx_flags {
/* Update the HWRM_API_FLAGS right below for any new non-internal bit added here */
BNXT_HWRM_INTERNAL_CTX_OWNED = BIT(0), /* caller owns the context */
BNXT_HWRM_INTERNAL_RESP_DIRTY = BIT(1), /* response contains data */
BNXT_HWRM_CTX_SILENT = BIT(2), /* squelch firmware errors */
BNXT_HWRM_FULL_WAIT = BIT(3), /* wait for full timeout of HWRM command */
};
#define HWRM_API_FLAGS (BNXT_HWRM_CTX_SILENT | BNXT_HWRM_FULL_WAIT)
struct bnxt_hwrm_ctx {
u64 sentinel;
dma_addr_t dma_handle;
struct output *resp;
struct input *req;
dma_addr_t slice_handle;
void *slice_addr;
u32 slice_size;
u32 req_len;
enum bnxt_hwrm_ctx_flags flags;
unsigned int timeout;
u32 allocated;
gfp_t gfp;
};
enum bnxt_hwrm_wait_state {
BNXT_HWRM_PENDING,
BNXT_HWRM_DEFERRED,
BNXT_HWRM_COMPLETE,
BNXT_HWRM_CANCELLED,
};
enum bnxt_hwrm_chnl { BNXT_HWRM_CHNL_CHIMP, BNXT_HWRM_CHNL_KONG };
struct bnxt_hwrm_wait_token {
struct rcu_head rcu;
struct hlist_node node;
enum bnxt_hwrm_wait_state state;
enum bnxt_hwrm_chnl dst;
u16 seq_id;
};
void hwrm_update_token(struct bnxt *bp, u16 seq, enum bnxt_hwrm_wait_state s);
#define BNXT_HWRM_MAX_REQ_LEN (bp->hwrm_max_req_len)
#define BNXT_HWRM_SHORT_REQ_LEN sizeof(struct hwrm_short_input)
#define HWRM_CMD_MAX_TIMEOUT 40000
#define SHORT_HWRM_CMD_TIMEOUT 20
#define HWRM_CMD_TIMEOUT (bp->hwrm_cmd_timeout)
#define HWRM_RESET_TIMEOUT ((HWRM_CMD_TIMEOUT) * 4)
#define HWRM_COREDUMP_TIMEOUT ((HWRM_CMD_TIMEOUT) * 12)
#define BNXT_HWRM_TARGET 0xffff
#define BNXT_HWRM_NO_CMPL_RING -1
#define BNXT_HWRM_REQ_MAX_SIZE 128
#define BNXT_HWRM_DMA_SIZE (2 * PAGE_SIZE) /* space for req+resp */
#define BNXT_HWRM_RESP_RESERVED PAGE_SIZE
#define BNXT_HWRM_RESP_OFFSET (BNXT_HWRM_DMA_SIZE - \
BNXT_HWRM_RESP_RESERVED)
#define BNXT_HWRM_CTX_OFFSET (BNXT_HWRM_RESP_OFFSET - \
sizeof(struct bnxt_hwrm_ctx))
#define BNXT_HWRM_DMA_ALIGN 16
#define BNXT_HWRM_SENTINEL 0xb6e1f68a12e9a7eb /* arbitrary value */
#define BNXT_HWRM_REQS_PER_PAGE (BNXT_PAGE_SIZE / \
BNXT_HWRM_REQ_MAX_SIZE)
#define HWRM_SHORT_MIN_TIMEOUT 3
#define HWRM_SHORT_MAX_TIMEOUT 10
#define HWRM_SHORT_TIMEOUT_COUNTER 5
#define HWRM_MIN_TIMEOUT 25
#define HWRM_MAX_TIMEOUT 40
#define HWRM_WAIT_MUST_ABORT(bp, ctx) \
(le16_to_cpu((ctx)->req->req_type) != HWRM_VER_GET && \
!bnxt_is_fw_healthy(bp))
static inline unsigned int hwrm_total_timeout(unsigned int n)
{
return n <= HWRM_SHORT_TIMEOUT_COUNTER ? n * HWRM_SHORT_MIN_TIMEOUT :
HWRM_SHORT_TIMEOUT_COUNTER * HWRM_SHORT_MIN_TIMEOUT +
(n - HWRM_SHORT_TIMEOUT_COUNTER) * HWRM_MIN_TIMEOUT;
}
#define HWRM_VALID_BIT_DELAY_USEC 150
static inline bool bnxt_cfa_hwrm_message(u16 req_type)
{
switch (req_type) {
case HWRM_CFA_ENCAP_RECORD_ALLOC:
case HWRM_CFA_ENCAP_RECORD_FREE:
case HWRM_CFA_DECAP_FILTER_ALLOC:
case HWRM_CFA_DECAP_FILTER_FREE:
case HWRM_CFA_EM_FLOW_ALLOC:
case HWRM_CFA_EM_FLOW_FREE:
case HWRM_CFA_EM_FLOW_CFG:
case HWRM_CFA_FLOW_ALLOC:
case HWRM_CFA_FLOW_FREE:
case HWRM_CFA_FLOW_INFO:
case HWRM_CFA_FLOW_FLUSH:
case HWRM_CFA_FLOW_STATS:
case HWRM_CFA_METER_PROFILE_ALLOC:
case HWRM_CFA_METER_PROFILE_FREE:
case HWRM_CFA_METER_PROFILE_CFG:
case HWRM_CFA_METER_INSTANCE_ALLOC:
case HWRM_CFA_METER_INSTANCE_FREE:
return true;
default:
return false;
}
}
static inline bool bnxt_kong_hwrm_message(struct bnxt *bp, struct input *req)
{
return (bp->fw_cap & BNXT_FW_CAP_KONG_MB_CHNL &&
(bnxt_cfa_hwrm_message(le16_to_cpu(req->req_type)) ||
le16_to_cpu(req->target_id) == HWRM_TARGET_ID_KONG));
}
int __hwrm_req_init(struct bnxt *bp, void **req, u16 req_type, u32 req_len);
#define hwrm_req_init(bp, req, req_type) \
__hwrm_req_init((bp), (void **)&(req), (req_type), sizeof(*(req)))
void *hwrm_req_hold(struct bnxt *bp, void *req);
void hwrm_req_drop(struct bnxt *bp, void *req);
void hwrm_req_flags(struct bnxt *bp, void *req, enum bnxt_hwrm_ctx_flags flags);
void hwrm_req_timeout(struct bnxt *bp, void *req, unsigned int timeout);
int hwrm_req_send(struct bnxt *bp, void *req);
int hwrm_req_send_silent(struct bnxt *bp, void *req);
int hwrm_req_replace(struct bnxt *bp, void *req, void *new_req, u32 len);
void hwrm_req_alloc_flags(struct bnxt *bp, void *req, gfp_t flags);
void *hwrm_req_dma_slice(struct bnxt *bp, void *req, u32 size, dma_addr_t *dma);
#endif
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include <linux/ptp_classify.h> #include <linux/ptp_classify.h>
#include "bnxt_hsi.h" #include "bnxt_hsi.h"
#include "bnxt.h" #include "bnxt.h"
#include "bnxt_hwrm.h"
#include "bnxt_ptp.h" #include "bnxt_ptp.h"
int bnxt_ptp_parse(struct sk_buff *skb, u16 *seq_id, u16 *hdr_off) int bnxt_ptp_parse(struct sk_buff *skb, u16 *seq_id, u16 *hdr_off)
...@@ -85,24 +86,28 @@ static void bnxt_ptp_get_current_time(struct bnxt *bp) ...@@ -85,24 +86,28 @@ static void bnxt_ptp_get_current_time(struct bnxt *bp)
static int bnxt_hwrm_port_ts_query(struct bnxt *bp, u32 flags, u64 *ts) static int bnxt_hwrm_port_ts_query(struct bnxt *bp, u32 flags, u64 *ts)
{ {
struct hwrm_port_ts_query_output *resp = bp->hwrm_cmd_resp_addr; struct hwrm_port_ts_query_output *resp;
struct hwrm_port_ts_query_input req = {0}; struct hwrm_port_ts_query_input *req;
int rc; int rc;
bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_PORT_TS_QUERY, -1, -1); rc = hwrm_req_init(bp, req, HWRM_PORT_TS_QUERY);
req.flags = cpu_to_le32(flags); if (rc)
return rc;
req->flags = cpu_to_le32(flags);
if ((flags & PORT_TS_QUERY_REQ_FLAGS_PATH) == if ((flags & PORT_TS_QUERY_REQ_FLAGS_PATH) ==
PORT_TS_QUERY_REQ_FLAGS_PATH_TX) { PORT_TS_QUERY_REQ_FLAGS_PATH_TX) {
req.enables = cpu_to_le16(BNXT_PTP_QTS_TX_ENABLES); req->enables = cpu_to_le16(BNXT_PTP_QTS_TX_ENABLES);
req.ptp_seq_id = cpu_to_le32(bp->ptp_cfg->tx_seqid); req->ptp_seq_id = cpu_to_le32(bp->ptp_cfg->tx_seqid);
req.ptp_hdr_offset = cpu_to_le16(bp->ptp_cfg->tx_hdr_off); req->ptp_hdr_offset = cpu_to_le16(bp->ptp_cfg->tx_hdr_off);
req.ts_req_timeout = cpu_to_le16(BNXT_PTP_QTS_TIMEOUT); req->ts_req_timeout = cpu_to_le16(BNXT_PTP_QTS_TIMEOUT);
} }
mutex_lock(&bp->hwrm_cmd_lock); resp = hwrm_req_hold(bp, req);
rc = _hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
rc = hwrm_req_send(bp, req);
if (!rc) if (!rc)
*ts = le64_to_cpu(resp->ptp_msg_ts); *ts = le64_to_cpu(resp->ptp_msg_ts);
mutex_unlock(&bp->hwrm_cmd_lock); hwrm_req_drop(bp, req);
return rc; return rc;
} }
...@@ -143,14 +148,17 @@ static int bnxt_ptp_adjfreq(struct ptp_clock_info *ptp_info, s32 ppb) ...@@ -143,14 +148,17 @@ static int bnxt_ptp_adjfreq(struct ptp_clock_info *ptp_info, s32 ppb)
{ {
struct bnxt_ptp_cfg *ptp = container_of(ptp_info, struct bnxt_ptp_cfg, struct bnxt_ptp_cfg *ptp = container_of(ptp_info, struct bnxt_ptp_cfg,
ptp_info); ptp_info);
struct hwrm_port_mac_cfg_input req = {0}; struct hwrm_port_mac_cfg_input *req;
struct bnxt *bp = ptp->bp; struct bnxt *bp = ptp->bp;
int rc; int rc;
bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_PORT_MAC_CFG, -1, -1); rc = hwrm_req_init(bp, req, HWRM_PORT_MAC_CFG);
req.ptp_freq_adj_ppb = cpu_to_le32(ppb); if (rc)
req.enables = cpu_to_le32(PORT_MAC_CFG_REQ_ENABLES_PTP_FREQ_ADJ_PPB); return rc;
rc = hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
req->ptp_freq_adj_ppb = cpu_to_le32(ppb);
req->enables = cpu_to_le32(PORT_MAC_CFG_REQ_ENABLES_PTP_FREQ_ADJ_PPB);
rc = hwrm_req_send(ptp->bp, req);
if (rc) if (rc)
netdev_err(ptp->bp->dev, netdev_err(ptp->bp->dev,
"ptp adjfreq failed. rc = %d\n", rc); "ptp adjfreq failed. rc = %d\n", rc);
...@@ -186,7 +194,7 @@ void bnxt_ptp_pps_event(struct bnxt *bp, u32 data1, u32 data2) ...@@ -186,7 +194,7 @@ void bnxt_ptp_pps_event(struct bnxt *bp, u32 data1, u32 data2)
static int bnxt_ptp_cfg_pin(struct bnxt *bp, u8 pin, u8 usage) static int bnxt_ptp_cfg_pin(struct bnxt *bp, u8 pin, u8 usage)
{ {
struct hwrm_func_ptp_pin_cfg_input req = {0}; struct hwrm_func_ptp_pin_cfg_input *req;
struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
u8 state = usage != BNXT_PPS_PIN_NONE; u8 state = usage != BNXT_PPS_PIN_NONE;
u8 *pin_state, *pin_usg; u8 *pin_state, *pin_usg;
...@@ -198,18 +206,21 @@ static int bnxt_ptp_cfg_pin(struct bnxt *bp, u8 pin, u8 usage) ...@@ -198,18 +206,21 @@ static int bnxt_ptp_cfg_pin(struct bnxt *bp, u8 pin, u8 usage)
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_FUNC_PTP_PIN_CFG, -1, -1); rc = hwrm_req_init(ptp->bp, req, HWRM_FUNC_PTP_PIN_CFG);
if (rc)
return rc;
enables = (FUNC_PTP_PIN_CFG_REQ_ENABLES_PIN0_STATE | enables = (FUNC_PTP_PIN_CFG_REQ_ENABLES_PIN0_STATE |
FUNC_PTP_PIN_CFG_REQ_ENABLES_PIN0_USAGE) << (pin * 2); FUNC_PTP_PIN_CFG_REQ_ENABLES_PIN0_USAGE) << (pin * 2);
req.enables = cpu_to_le32(enables); req->enables = cpu_to_le32(enables);
pin_state = &req.pin0_state; pin_state = &req->pin0_state;
pin_usg = &req.pin0_usage; pin_usg = &req->pin0_usage;
*(pin_state + (pin * 2)) = state; *(pin_state + (pin * 2)) = state;
*(pin_usg + (pin * 2)) = usage; *(pin_usg + (pin * 2)) = usage;
rc = hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT); rc = hwrm_req_send(ptp->bp, req);
if (rc) if (rc)
return rc; return rc;
...@@ -221,12 +232,16 @@ static int bnxt_ptp_cfg_pin(struct bnxt *bp, u8 pin, u8 usage) ...@@ -221,12 +232,16 @@ static int bnxt_ptp_cfg_pin(struct bnxt *bp, u8 pin, u8 usage)
static int bnxt_ptp_cfg_event(struct bnxt *bp, u8 event) static int bnxt_ptp_cfg_event(struct bnxt *bp, u8 event)
{ {
struct hwrm_func_ptp_cfg_input req = {0}; struct hwrm_func_ptp_cfg_input *req;
int rc;
rc = hwrm_req_init(bp, req, HWRM_FUNC_PTP_CFG);
if (rc)
return rc;
bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_FUNC_PTP_CFG, -1, -1); req->enables = cpu_to_le16(FUNC_PTP_CFG_REQ_ENABLES_PTP_PPS_EVENT);
req.enables = cpu_to_le16(FUNC_PTP_CFG_REQ_ENABLES_PTP_PPS_EVENT); req->ptp_pps_event = event;
req.ptp_pps_event = event; return hwrm_req_send(bp, req);
return hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
} }
void bnxt_ptp_reapply_pps(struct bnxt *bp) void bnxt_ptp_reapply_pps(struct bnxt *bp)
...@@ -277,7 +292,7 @@ static int bnxt_get_target_cycles(struct bnxt_ptp_cfg *ptp, u64 target_ns, ...@@ -277,7 +292,7 @@ static int bnxt_get_target_cycles(struct bnxt_ptp_cfg *ptp, u64 target_ns,
static int bnxt_ptp_perout_cfg(struct bnxt_ptp_cfg *ptp, static int bnxt_ptp_perout_cfg(struct bnxt_ptp_cfg *ptp,
struct ptp_clock_request *rq) struct ptp_clock_request *rq)
{ {
struct hwrm_func_ptp_cfg_input req = {0}; struct hwrm_func_ptp_cfg_input *req;
struct bnxt *bp = ptp->bp; struct bnxt *bp = ptp->bp;
struct timespec64 ts; struct timespec64 ts;
u64 target_ns, delta; u64 target_ns, delta;
...@@ -292,20 +307,22 @@ static int bnxt_ptp_perout_cfg(struct bnxt_ptp_cfg *ptp, ...@@ -292,20 +307,22 @@ static int bnxt_ptp_perout_cfg(struct bnxt_ptp_cfg *ptp,
if (rc) if (rc)
return rc; return rc;
bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_FUNC_PTP_CFG, -1, -1); rc = hwrm_req_init(bp, req, HWRM_FUNC_PTP_CFG);
if (rc)
return rc;
enables = FUNC_PTP_CFG_REQ_ENABLES_PTP_FREQ_ADJ_EXT_PERIOD | enables = FUNC_PTP_CFG_REQ_ENABLES_PTP_FREQ_ADJ_EXT_PERIOD |
FUNC_PTP_CFG_REQ_ENABLES_PTP_FREQ_ADJ_EXT_UP | FUNC_PTP_CFG_REQ_ENABLES_PTP_FREQ_ADJ_EXT_UP |
FUNC_PTP_CFG_REQ_ENABLES_PTP_FREQ_ADJ_EXT_PHASE; FUNC_PTP_CFG_REQ_ENABLES_PTP_FREQ_ADJ_EXT_PHASE;
req.enables = cpu_to_le16(enables); req->enables = cpu_to_le16(enables);
req.ptp_pps_event = 0; req->ptp_pps_event = 0;
req.ptp_freq_adj_dll_source = 0; req->ptp_freq_adj_dll_source = 0;
req.ptp_freq_adj_dll_phase = 0; req->ptp_freq_adj_dll_phase = 0;
req.ptp_freq_adj_ext_period = cpu_to_le32(NSEC_PER_SEC); req->ptp_freq_adj_ext_period = cpu_to_le32(NSEC_PER_SEC);
req.ptp_freq_adj_ext_up = 0; req->ptp_freq_adj_ext_up = 0;
req.ptp_freq_adj_ext_phase_lower = cpu_to_le32(delta); req->ptp_freq_adj_ext_phase_lower = cpu_to_le32(delta);
return hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT); return hwrm_req_send(bp, req);
} }
static int bnxt_ptp_enable(struct ptp_clock_info *ptp_info, static int bnxt_ptp_enable(struct ptp_clock_info *ptp_info,
...@@ -362,11 +379,15 @@ static int bnxt_ptp_enable(struct ptp_clock_info *ptp_info, ...@@ -362,11 +379,15 @@ static int bnxt_ptp_enable(struct ptp_clock_info *ptp_info,
static int bnxt_hwrm_ptp_cfg(struct bnxt *bp) static int bnxt_hwrm_ptp_cfg(struct bnxt *bp)
{ {
struct hwrm_port_mac_cfg_input req = {0};
struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
struct hwrm_port_mac_cfg_input *req;
u32 flags = 0; u32 flags = 0;
int rc;
rc = hwrm_req_init(bp, req, HWRM_PORT_MAC_CFG);
if (rc)
return rc;
bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_PORT_MAC_CFG, -1, -1);
if (ptp->rx_filter) if (ptp->rx_filter)
flags |= PORT_MAC_CFG_REQ_FLAGS_PTP_RX_TS_CAPTURE_ENABLE; flags |= PORT_MAC_CFG_REQ_FLAGS_PTP_RX_TS_CAPTURE_ENABLE;
else else
...@@ -375,11 +396,11 @@ static int bnxt_hwrm_ptp_cfg(struct bnxt *bp) ...@@ -375,11 +396,11 @@ static int bnxt_hwrm_ptp_cfg(struct bnxt *bp)
flags |= PORT_MAC_CFG_REQ_FLAGS_PTP_TX_TS_CAPTURE_ENABLE; flags |= PORT_MAC_CFG_REQ_FLAGS_PTP_TX_TS_CAPTURE_ENABLE;
else else
flags |= PORT_MAC_CFG_REQ_FLAGS_PTP_TX_TS_CAPTURE_DISABLE; flags |= PORT_MAC_CFG_REQ_FLAGS_PTP_TX_TS_CAPTURE_DISABLE;
req.flags = cpu_to_le32(flags); req->flags = cpu_to_le32(flags);
req.enables = cpu_to_le32(PORT_MAC_CFG_REQ_ENABLES_RX_TS_CAPTURE_PTP_MSG_TYPE); req->enables = cpu_to_le32(PORT_MAC_CFG_REQ_ENABLES_RX_TS_CAPTURE_PTP_MSG_TYPE);
req.rx_ts_capture_ptp_msg_type = cpu_to_le16(ptp->rxctl); req->rx_ts_capture_ptp_msg_type = cpu_to_le16(ptp->rxctl);
return hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT); return hwrm_req_send(bp, req);
} }
int bnxt_hwtstamp_set(struct net_device *dev, struct ifreq *ifr) int bnxt_hwtstamp_set(struct net_device *dev, struct ifreq *ifr)
...@@ -630,11 +651,10 @@ static int bnxt_ptp_verify(struct ptp_clock_info *ptp_info, unsigned int pin, ...@@ -630,11 +651,10 @@ static int bnxt_ptp_verify(struct ptp_clock_info *ptp_info, unsigned int pin,
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
/* bp->hwrm_cmd_lock held by the caller */
static int bnxt_ptp_pps_init(struct bnxt *bp) static int bnxt_ptp_pps_init(struct bnxt *bp)
{ {
struct hwrm_func_ptp_pin_qcfg_output *resp = bp->hwrm_cmd_resp_addr; struct hwrm_func_ptp_pin_qcfg_output *resp;
struct hwrm_func_ptp_pin_qcfg_input req = {0}; struct hwrm_func_ptp_pin_qcfg_input *req;
struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
struct ptp_clock_info *ptp_info; struct ptp_clock_info *ptp_info;
struct bnxt_pps *pps_info; struct bnxt_pps *pps_info;
...@@ -642,11 +662,16 @@ static int bnxt_ptp_pps_init(struct bnxt *bp) ...@@ -642,11 +662,16 @@ static int bnxt_ptp_pps_init(struct bnxt *bp)
u32 i, rc; u32 i, rc;
/* Query current/default PIN CFG */ /* Query current/default PIN CFG */
bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_FUNC_PTP_PIN_QCFG, -1, -1); rc = hwrm_req_init(bp, req, HWRM_FUNC_PTP_PIN_QCFG);
if (rc)
return rc;
rc = _hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT); resp = hwrm_req_hold(bp, req);
if (rc || !resp->num_pins) rc = hwrm_req_send(bp, req);
if (rc || !resp->num_pins) {
hwrm_req_drop(bp, req);
return -EOPNOTSUPP; return -EOPNOTSUPP;
}
ptp_info = &ptp->ptp_info; ptp_info = &ptp->ptp_info;
pps_info = &ptp->pps_info; pps_info = &ptp->pps_info;
...@@ -655,8 +680,10 @@ static int bnxt_ptp_pps_init(struct bnxt *bp) ...@@ -655,8 +680,10 @@ static int bnxt_ptp_pps_init(struct bnxt *bp)
ptp_info->pin_config = kcalloc(ptp_info->n_pins, ptp_info->pin_config = kcalloc(ptp_info->n_pins,
sizeof(*ptp_info->pin_config), sizeof(*ptp_info->pin_config),
GFP_KERNEL); GFP_KERNEL);
if (!ptp_info->pin_config) if (!ptp_info->pin_config) {
hwrm_req_drop(bp, req);
return -ENOMEM; return -ENOMEM;
}
/* Report the TSIO capability to kernel */ /* Report the TSIO capability to kernel */
pin_usg = &resp->pin0_usage; pin_usg = &resp->pin0_usage;
...@@ -674,6 +701,7 @@ static int bnxt_ptp_pps_init(struct bnxt *bp) ...@@ -674,6 +701,7 @@ static int bnxt_ptp_pps_init(struct bnxt *bp)
pps_info->pins[i].usage = *pin_usg; pps_info->pins[i].usage = *pin_usg;
} }
hwrm_req_drop(bp, req);
/* Only 1 each of ext_ts and per_out pins is available in HW */ /* Only 1 each of ext_ts and per_out pins is available in HW */
ptp_info->n_ext_ts = 1; ptp_info->n_ext_ts = 1;
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#include "bnxt_hsi.h" #include "bnxt_hsi.h"
#include "bnxt.h" #include "bnxt.h"
#include "bnxt_hwrm.h"
#include "bnxt_ulp.h" #include "bnxt_ulp.h"
static int bnxt_register_dev(struct bnxt_en_dev *edev, int ulp_id, static int bnxt_register_dev(struct bnxt_en_dev *edev, int ulp_id,
...@@ -237,27 +238,33 @@ static int bnxt_send_msg(struct bnxt_en_dev *edev, int ulp_id, ...@@ -237,27 +238,33 @@ static int bnxt_send_msg(struct bnxt_en_dev *edev, int ulp_id,
{ {
struct net_device *dev = edev->net; struct net_device *dev = edev->net;
struct bnxt *bp = netdev_priv(dev); struct bnxt *bp = netdev_priv(dev);
struct output *resp;
struct input *req; struct input *req;
u32 resp_len;
int rc; int rc;
if (ulp_id != BNXT_ROCE_ULP && bp->fw_reset_state) if (ulp_id != BNXT_ROCE_ULP && bp->fw_reset_state)
return -EBUSY; return -EBUSY;
mutex_lock(&bp->hwrm_cmd_lock); rc = hwrm_req_init(bp, req, 0 /* don't care */);
req = fw_msg->msg; if (rc)
req->resp_addr = cpu_to_le64(bp->hwrm_cmd_resp_dma_addr); return rc;
rc = _hwrm_send_message(bp, fw_msg->msg, fw_msg->msg_len,
fw_msg->timeout);
if (!rc) {
struct output *resp = bp->hwrm_cmd_resp_addr;
u32 len = le16_to_cpu(resp->resp_len);
if (fw_msg->resp_max_len < len) rc = hwrm_req_replace(bp, req, fw_msg->msg, fw_msg->msg_len);
len = fw_msg->resp_max_len; if (rc)
return rc;
memcpy(fw_msg->resp, resp, len); hwrm_req_timeout(bp, req, fw_msg->timeout);
resp = hwrm_req_hold(bp, req);
rc = hwrm_req_send(bp, req);
resp_len = le16_to_cpu(resp->resp_len);
if (resp_len) {
if (fw_msg->resp_max_len < resp_len)
resp_len = fw_msg->resp_max_len;
memcpy(fw_msg->resp, resp, resp_len);
} }
mutex_unlock(&bp->hwrm_cmd_lock); hwrm_req_drop(bp, req);
return rc; return rc;
} }
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include "bnxt_hsi.h" #include "bnxt_hsi.h"
#include "bnxt.h" #include "bnxt.h"
#include "bnxt_hwrm.h"
#include "bnxt_vfr.h" #include "bnxt_vfr.h"
#include "bnxt_devlink.h" #include "bnxt_devlink.h"
#include "bnxt_tc.h" #include "bnxt_tc.h"
...@@ -27,38 +28,40 @@ ...@@ -27,38 +28,40 @@
static int hwrm_cfa_vfr_alloc(struct bnxt *bp, u16 vf_idx, static int hwrm_cfa_vfr_alloc(struct bnxt *bp, u16 vf_idx,
u16 *tx_cfa_action, u16 *rx_cfa_code) u16 *tx_cfa_action, u16 *rx_cfa_code)
{ {
struct hwrm_cfa_vfr_alloc_output *resp = bp->hwrm_cmd_resp_addr; struct hwrm_cfa_vfr_alloc_output *resp;
struct hwrm_cfa_vfr_alloc_input req = { 0 }; struct hwrm_cfa_vfr_alloc_input *req;
int rc; int rc;
bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_CFA_VFR_ALLOC, -1, -1); rc = hwrm_req_init(bp, req, HWRM_CFA_VFR_ALLOC);
req.vf_id = cpu_to_le16(vf_idx);
sprintf(req.vfr_name, "vfr%d", vf_idx);
mutex_lock(&bp->hwrm_cmd_lock);
rc = _hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
if (!rc) { if (!rc) {
*tx_cfa_action = le16_to_cpu(resp->tx_cfa_action); req->vf_id = cpu_to_le16(vf_idx);
*rx_cfa_code = le16_to_cpu(resp->rx_cfa_code); sprintf(req->vfr_name, "vfr%d", vf_idx);
netdev_dbg(bp->dev, "tx_cfa_action=0x%x, rx_cfa_code=0x%x",
*tx_cfa_action, *rx_cfa_code); resp = hwrm_req_hold(bp, req);
} else { rc = hwrm_req_send(bp, req);
netdev_info(bp->dev, "%s error rc=%d\n", __func__, rc); if (!rc) {
*tx_cfa_action = le16_to_cpu(resp->tx_cfa_action);
*rx_cfa_code = le16_to_cpu(resp->rx_cfa_code);
netdev_dbg(bp->dev, "tx_cfa_action=0x%x, rx_cfa_code=0x%x",
*tx_cfa_action, *rx_cfa_code);
}
hwrm_req_drop(bp, req);
} }
if (rc)
mutex_unlock(&bp->hwrm_cmd_lock); netdev_info(bp->dev, "%s error rc=%d\n", __func__, rc);
return rc; return rc;
} }
static int hwrm_cfa_vfr_free(struct bnxt *bp, u16 vf_idx) static int hwrm_cfa_vfr_free(struct bnxt *bp, u16 vf_idx)
{ {
struct hwrm_cfa_vfr_free_input req = { 0 }; struct hwrm_cfa_vfr_free_input *req;
int rc; int rc;
bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_CFA_VFR_FREE, -1, -1); rc = hwrm_req_init(bp, req, HWRM_CFA_VFR_FREE);
sprintf(req.vfr_name, "vfr%d", vf_idx); if (!rc) {
sprintf(req->vfr_name, "vfr%d", vf_idx);
rc = hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT); rc = hwrm_req_send(bp, req);
}
if (rc) if (rc)
netdev_info(bp->dev, "%s error rc=%d\n", __func__, rc); netdev_info(bp->dev, "%s error rc=%d\n", __func__, rc);
return rc; return rc;
...@@ -67,17 +70,18 @@ static int hwrm_cfa_vfr_free(struct bnxt *bp, u16 vf_idx) ...@@ -67,17 +70,18 @@ static int hwrm_cfa_vfr_free(struct bnxt *bp, u16 vf_idx)
static int bnxt_hwrm_vfr_qcfg(struct bnxt *bp, struct bnxt_vf_rep *vf_rep, static int bnxt_hwrm_vfr_qcfg(struct bnxt *bp, struct bnxt_vf_rep *vf_rep,
u16 *max_mtu) u16 *max_mtu)
{ {
struct hwrm_func_qcfg_output *resp = bp->hwrm_cmd_resp_addr; struct hwrm_func_qcfg_output *resp;
struct hwrm_func_qcfg_input req = {0}; struct hwrm_func_qcfg_input *req;
u16 mtu; u16 mtu;
int rc; int rc;
bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_FUNC_QCFG, -1, -1); rc = hwrm_req_init(bp, req, HWRM_FUNC_QCFG);
req.fid = cpu_to_le16(bp->pf.vf[vf_rep->vf_idx].fw_fid); if (rc)
return rc;
mutex_lock(&bp->hwrm_cmd_lock);
rc = _hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT); req->fid = cpu_to_le16(bp->pf.vf[vf_rep->vf_idx].fw_fid);
resp = hwrm_req_hold(bp, req);
rc = hwrm_req_send(bp, req);
if (!rc) { if (!rc) {
mtu = le16_to_cpu(resp->max_mtu_configured); mtu = le16_to_cpu(resp->max_mtu_configured);
if (!mtu) if (!mtu)
...@@ -85,7 +89,7 @@ static int bnxt_hwrm_vfr_qcfg(struct bnxt *bp, struct bnxt_vf_rep *vf_rep, ...@@ -85,7 +89,7 @@ static int bnxt_hwrm_vfr_qcfg(struct bnxt *bp, struct bnxt_vf_rep *vf_rep,
else else
*max_mtu = mtu; *max_mtu = mtu;
} }
mutex_unlock(&bp->hwrm_cmd_lock); hwrm_req_drop(bp, req);
return rc; return rc;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment