2021-08-29 03:34:58 -04:00
|
|
|
/* 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"
|
|
|
|
|
bnxt_en: introduce new firmware message API based on DMA pools
This change constitutes a major step towards supporting multiple
firmware commands in flight by maintaining a separate response buffer
for the duration of each request. These firmware commands are also
known as Hardware Resource Manager (HWRM) commands. Using separate
response buffers requires an API change in order for callers to be
able to free the buffer when done.
It is impossible to keep the existing APIs unchanged. The existing
usage for a simple HWRM message request such as the following:
struct input req = {0};
bnxt_hwrm_cmd_hdr_init(bp, &req, REQ_TYPE, -1, -1);
rc = hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
if (rc)
/* error */
changes to:
struct input *req;
rc = hwrm_req_init(bp, req, REQ_TYPE);
if (rc)
/* error */
rc = hwrm_req_send(bp, req); /* consumes req */
if (rc)
/* error */
The key changes are:
1. The req is no longer allocated on the stack.
2. The caller must call hwrm_req_init() to allocate a req buffer and
check for a valid buffer.
3. The req buffer is automatically released when hwrm_req_send() returns.
4. If the caller wants to check the firmware response, the caller must
call hwrm_req_hold() to take ownership of the response buffer and
release it afterwards using hwrm_req_drop(). The caller is no longer
required to explicitly hold the hwrm_cmd_lock mutex to read the
response.
5. Because the firmware commands and responses all have different sizes,
some safeguards are added to the code.
This patch maintains legacy API compatibiltiy, implementing the old
API in terms of the new. The follow-on patches will convert all
callers to use the new APIs.
v2: Fix redefined writeq with parisc .config
Fix "cast from pointer to integer of different size" warning in
hwrm_calc_sentinel()
Signed-off-by: Edwin Peer <edwin.peer@broadcom.com>
Signed-off-by: Michael Chan <michael.chan@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2021-08-29 03:34:59 -04:00
|
|
|
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;
|
2021-08-29 03:35:02 -04:00
|
|
|
dma_addr_t slice_handle;
|
|
|
|
void *slice_addr;
|
|
|
|
u32 slice_size;
|
bnxt_en: introduce new firmware message API based on DMA pools
This change constitutes a major step towards supporting multiple
firmware commands in flight by maintaining a separate response buffer
for the duration of each request. These firmware commands are also
known as Hardware Resource Manager (HWRM) commands. Using separate
response buffers requires an API change in order for callers to be
able to free the buffer when done.
It is impossible to keep the existing APIs unchanged. The existing
usage for a simple HWRM message request such as the following:
struct input req = {0};
bnxt_hwrm_cmd_hdr_init(bp, &req, REQ_TYPE, -1, -1);
rc = hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
if (rc)
/* error */
changes to:
struct input *req;
rc = hwrm_req_init(bp, req, REQ_TYPE);
if (rc)
/* error */
rc = hwrm_req_send(bp, req); /* consumes req */
if (rc)
/* error */
The key changes are:
1. The req is no longer allocated on the stack.
2. The caller must call hwrm_req_init() to allocate a req buffer and
check for a valid buffer.
3. The req buffer is automatically released when hwrm_req_send() returns.
4. If the caller wants to check the firmware response, the caller must
call hwrm_req_hold() to take ownership of the response buffer and
release it afterwards using hwrm_req_drop(). The caller is no longer
required to explicitly hold the hwrm_cmd_lock mutex to read the
response.
5. Because the firmware commands and responses all have different sizes,
some safeguards are added to the code.
This patch maintains legacy API compatibiltiy, implementing the old
API in terms of the new. The follow-on patches will convert all
callers to use the new APIs.
v2: Fix redefined writeq with parisc .config
Fix "cast from pointer to integer of different size" warning in
hwrm_calc_sentinel()
Signed-off-by: Edwin Peer <edwin.peer@broadcom.com>
Signed-off-by: Michael Chan <michael.chan@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2021-08-29 03:34:59 -04:00
|
|
|
u32 req_len;
|
|
|
|
enum bnxt_hwrm_ctx_flags flags;
|
|
|
|
unsigned int timeout;
|
2021-08-29 03:35:02 -04:00
|
|
|
u32 allocated;
|
|
|
|
gfp_t gfp;
|
bnxt_en: introduce new firmware message API based on DMA pools
This change constitutes a major step towards supporting multiple
firmware commands in flight by maintaining a separate response buffer
for the duration of each request. These firmware commands are also
known as Hardware Resource Manager (HWRM) commands. Using separate
response buffers requires an API change in order for callers to be
able to free the buffer when done.
It is impossible to keep the existing APIs unchanged. The existing
usage for a simple HWRM message request such as the following:
struct input req = {0};
bnxt_hwrm_cmd_hdr_init(bp, &req, REQ_TYPE, -1, -1);
rc = hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
if (rc)
/* error */
changes to:
struct input *req;
rc = hwrm_req_init(bp, req, REQ_TYPE);
if (rc)
/* error */
rc = hwrm_req_send(bp, req); /* consumes req */
if (rc)
/* error */
The key changes are:
1. The req is no longer allocated on the stack.
2. The caller must call hwrm_req_init() to allocate a req buffer and
check for a valid buffer.
3. The req buffer is automatically released when hwrm_req_send() returns.
4. If the caller wants to check the firmware response, the caller must
call hwrm_req_hold() to take ownership of the response buffer and
release it afterwards using hwrm_req_drop(). The caller is no longer
required to explicitly hold the hwrm_cmd_lock mutex to read the
response.
5. Because the firmware commands and responses all have different sizes,
some safeguards are added to the code.
This patch maintains legacy API compatibiltiy, implementing the old
API in terms of the new. The follow-on patches will convert all
callers to use the new APIs.
v2: Fix redefined writeq with parisc .config
Fix "cast from pointer to integer of different size" warning in
hwrm_calc_sentinel()
Signed-off-by: Edwin Peer <edwin.peer@broadcom.com>
Signed-off-by: Michael Chan <michael.chan@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2021-08-29 03:34:59 -04:00
|
|
|
};
|
|
|
|
|
2021-08-29 03:35:06 -04:00
|
|
|
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);
|
|
|
|
|
2021-08-29 03:34:58 -04:00
|
|
|
#define BNXT_HWRM_MAX_REQ_LEN (bp->hwrm_max_req_len)
|
|
|
|
#define BNXT_HWRM_SHORT_REQ_LEN sizeof(struct hwrm_short_input)
|
2022-01-09 18:54:44 -05:00
|
|
|
#define HWRM_CMD_MAX_TIMEOUT 40000U
|
2021-08-29 03:34:58 -04:00
|
|
|
#define SHORT_HWRM_CMD_TIMEOUT 20
|
|
|
|
#define HWRM_CMD_TIMEOUT (bp->hwrm_cmd_timeout)
|
|
|
|
#define HWRM_RESET_TIMEOUT ((HWRM_CMD_TIMEOUT) * 4)
|
bnxt_en: introduce new firmware message API based on DMA pools
This change constitutes a major step towards supporting multiple
firmware commands in flight by maintaining a separate response buffer
for the duration of each request. These firmware commands are also
known as Hardware Resource Manager (HWRM) commands. Using separate
response buffers requires an API change in order for callers to be
able to free the buffer when done.
It is impossible to keep the existing APIs unchanged. The existing
usage for a simple HWRM message request such as the following:
struct input req = {0};
bnxt_hwrm_cmd_hdr_init(bp, &req, REQ_TYPE, -1, -1);
rc = hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
if (rc)
/* error */
changes to:
struct input *req;
rc = hwrm_req_init(bp, req, REQ_TYPE);
if (rc)
/* error */
rc = hwrm_req_send(bp, req); /* consumes req */
if (rc)
/* error */
The key changes are:
1. The req is no longer allocated on the stack.
2. The caller must call hwrm_req_init() to allocate a req buffer and
check for a valid buffer.
3. The req buffer is automatically released when hwrm_req_send() returns.
4. If the caller wants to check the firmware response, the caller must
call hwrm_req_hold() to take ownership of the response buffer and
release it afterwards using hwrm_req_drop(). The caller is no longer
required to explicitly hold the hwrm_cmd_lock mutex to read the
response.
5. Because the firmware commands and responses all have different sizes,
some safeguards are added to the code.
This patch maintains legacy API compatibiltiy, implementing the old
API in terms of the new. The follow-on patches will convert all
callers to use the new APIs.
v2: Fix redefined writeq with parisc .config
Fix "cast from pointer to integer of different size" warning in
hwrm_calc_sentinel()
Signed-off-by: Edwin Peer <edwin.peer@broadcom.com>
Signed-off-by: Michael Chan <michael.chan@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2021-08-29 03:34:59 -04:00
|
|
|
#define BNXT_HWRM_TARGET 0xffff
|
|
|
|
#define BNXT_HWRM_NO_CMPL_RING -1
|
2021-08-29 03:34:58 -04:00
|
|
|
#define BNXT_HWRM_REQ_MAX_SIZE 128
|
bnxt_en: introduce new firmware message API based on DMA pools
This change constitutes a major step towards supporting multiple
firmware commands in flight by maintaining a separate response buffer
for the duration of each request. These firmware commands are also
known as Hardware Resource Manager (HWRM) commands. Using separate
response buffers requires an API change in order for callers to be
able to free the buffer when done.
It is impossible to keep the existing APIs unchanged. The existing
usage for a simple HWRM message request such as the following:
struct input req = {0};
bnxt_hwrm_cmd_hdr_init(bp, &req, REQ_TYPE, -1, -1);
rc = hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
if (rc)
/* error */
changes to:
struct input *req;
rc = hwrm_req_init(bp, req, REQ_TYPE);
if (rc)
/* error */
rc = hwrm_req_send(bp, req); /* consumes req */
if (rc)
/* error */
The key changes are:
1. The req is no longer allocated on the stack.
2. The caller must call hwrm_req_init() to allocate a req buffer and
check for a valid buffer.
3. The req buffer is automatically released when hwrm_req_send() returns.
4. If the caller wants to check the firmware response, the caller must
call hwrm_req_hold() to take ownership of the response buffer and
release it afterwards using hwrm_req_drop(). The caller is no longer
required to explicitly hold the hwrm_cmd_lock mutex to read the
response.
5. Because the firmware commands and responses all have different sizes,
some safeguards are added to the code.
This patch maintains legacy API compatibiltiy, implementing the old
API in terms of the new. The follow-on patches will convert all
callers to use the new APIs.
v2: Fix redefined writeq with parisc .config
Fix "cast from pointer to integer of different size" warning in
hwrm_calc_sentinel()
Signed-off-by: Edwin Peer <edwin.peer@broadcom.com>
Signed-off-by: Michael Chan <michael.chan@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2021-08-29 03:34:59 -04:00
|
|
|
#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 */
|
2021-08-29 03:34:58 -04:00
|
|
|
#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
|
|
|
|
|
bnxt_en: introduce new firmware message API based on DMA pools
This change constitutes a major step towards supporting multiple
firmware commands in flight by maintaining a separate response buffer
for the duration of each request. These firmware commands are also
known as Hardware Resource Manager (HWRM) commands. Using separate
response buffers requires an API change in order for callers to be
able to free the buffer when done.
It is impossible to keep the existing APIs unchanged. The existing
usage for a simple HWRM message request such as the following:
struct input req = {0};
bnxt_hwrm_cmd_hdr_init(bp, &req, REQ_TYPE, -1, -1);
rc = hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
if (rc)
/* error */
changes to:
struct input *req;
rc = hwrm_req_init(bp, req, REQ_TYPE);
if (rc)
/* error */
rc = hwrm_req_send(bp, req); /* consumes req */
if (rc)
/* error */
The key changes are:
1. The req is no longer allocated on the stack.
2. The caller must call hwrm_req_init() to allocate a req buffer and
check for a valid buffer.
3. The req buffer is automatically released when hwrm_req_send() returns.
4. If the caller wants to check the firmware response, the caller must
call hwrm_req_hold() to take ownership of the response buffer and
release it afterwards using hwrm_req_drop(). The caller is no longer
required to explicitly hold the hwrm_cmd_lock mutex to read the
response.
5. Because the firmware commands and responses all have different sizes,
some safeguards are added to the code.
This patch maintains legacy API compatibiltiy, implementing the old
API in terms of the new. The follow-on patches will convert all
callers to use the new APIs.
v2: Fix redefined writeq with parisc .config
Fix "cast from pointer to integer of different size" warning in
hwrm_calc_sentinel()
Signed-off-by: Edwin Peer <edwin.peer@broadcom.com>
Signed-off-by: Michael Chan <michael.chan@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2021-08-29 03:34:59 -04:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2021-08-29 03:34:58 -04:00
|
|
|
|
2022-02-20 04:05:52 -05:00
|
|
|
#define HWRM_VALID_BIT_DELAY_USEC 50000
|
2021-08-29 03:34:58 -04:00
|
|
|
|
|
|
|
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));
|
|
|
|
}
|
|
|
|
|
bnxt_en: introduce new firmware message API based on DMA pools
This change constitutes a major step towards supporting multiple
firmware commands in flight by maintaining a separate response buffer
for the duration of each request. These firmware commands are also
known as Hardware Resource Manager (HWRM) commands. Using separate
response buffers requires an API change in order for callers to be
able to free the buffer when done.
It is impossible to keep the existing APIs unchanged. The existing
usage for a simple HWRM message request such as the following:
struct input req = {0};
bnxt_hwrm_cmd_hdr_init(bp, &req, REQ_TYPE, -1, -1);
rc = hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
if (rc)
/* error */
changes to:
struct input *req;
rc = hwrm_req_init(bp, req, REQ_TYPE);
if (rc)
/* error */
rc = hwrm_req_send(bp, req); /* consumes req */
if (rc)
/* error */
The key changes are:
1. The req is no longer allocated on the stack.
2. The caller must call hwrm_req_init() to allocate a req buffer and
check for a valid buffer.
3. The req buffer is automatically released when hwrm_req_send() returns.
4. If the caller wants to check the firmware response, the caller must
call hwrm_req_hold() to take ownership of the response buffer and
release it afterwards using hwrm_req_drop(). The caller is no longer
required to explicitly hold the hwrm_cmd_lock mutex to read the
response.
5. Because the firmware commands and responses all have different sizes,
some safeguards are added to the code.
This patch maintains legacy API compatibiltiy, implementing the old
API in terms of the new. The follow-on patches will convert all
callers to use the new APIs.
v2: Fix redefined writeq with parisc .config
Fix "cast from pointer to integer of different size" warning in
hwrm_calc_sentinel()
Signed-off-by: Edwin Peer <edwin.peer@broadcom.com>
Signed-off-by: Michael Chan <michael.chan@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2021-08-29 03:34:59 -04:00
|
|
|
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);
|
2021-08-29 03:35:01 -04:00
|
|
|
int hwrm_req_replace(struct bnxt *bp, void *req, void *new_req, u32 len);
|
2021-08-29 03:35:02 -04:00
|
|
|
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);
|
2023-10-16 10:16:40 -07:00
|
|
|
|
|
|
|
/* Older devices can only support req length of 128.
|
|
|
|
* HWRM_FUNC_CFG requests which don't need fields starting at
|
|
|
|
* num_quic_tx_key_ctxs can use this helper to avoid getting -E2BIG.
|
|
|
|
*/
|
|
|
|
static inline int
|
|
|
|
bnxt_hwrm_func_cfg_short_req_init(struct bnxt *bp,
|
|
|
|
struct hwrm_func_cfg_input **req)
|
|
|
|
{
|
|
|
|
u32 req_len;
|
|
|
|
|
|
|
|
req_len = min_t(u32, sizeof(**req), bp->hwrm_max_ext_req_len);
|
|
|
|
return __hwrm_req_init(bp, (void **)req, HWRM_FUNC_CFG, req_len);
|
|
|
|
}
|
2021-08-29 03:34:58 -04:00
|
|
|
#endif
|