1 | /* Broadcom NetXtreme-C/E network driver. |
2 | * |
3 | * Copyright (c) 2020 Broadcom Limited |
4 | * |
5 | * This program is free software; you can redistribute it and/or modify |
6 | * it under the terms of the GNU General Public License as published by |
7 | * the Free Software Foundation. |
8 | */ |
9 | |
10 | #ifndef BNXT_HWRM_H |
11 | #define BNXT_HWRM_H |
12 | |
13 | #include "bnxt_hsi.h" |
14 | |
15 | enum bnxt_hwrm_ctx_flags { |
16 | /* Update the HWRM_API_FLAGS right below for any new non-internal bit added here */ |
17 | BNXT_HWRM_INTERNAL_CTX_OWNED = BIT(0), /* caller owns the context */ |
18 | BNXT_HWRM_INTERNAL_RESP_DIRTY = BIT(1), /* response contains data */ |
19 | BNXT_HWRM_CTX_SILENT = BIT(2), /* squelch firmware errors */ |
20 | BNXT_HWRM_FULL_WAIT = BIT(3), /* wait for full timeout of HWRM command */ |
21 | }; |
22 | |
23 | #define HWRM_API_FLAGS (BNXT_HWRM_CTX_SILENT | BNXT_HWRM_FULL_WAIT) |
24 | |
25 | struct bnxt_hwrm_ctx { |
26 | u64 sentinel; |
27 | dma_addr_t dma_handle; |
28 | struct output *resp; |
29 | struct input *req; |
30 | dma_addr_t slice_handle; |
31 | void *slice_addr; |
32 | u32 slice_size; |
33 | u32 req_len; |
34 | enum bnxt_hwrm_ctx_flags flags; |
35 | unsigned int timeout; |
36 | u32 allocated; |
37 | gfp_t gfp; |
38 | }; |
39 | |
40 | enum bnxt_hwrm_wait_state { |
41 | BNXT_HWRM_PENDING, |
42 | BNXT_HWRM_DEFERRED, |
43 | BNXT_HWRM_COMPLETE, |
44 | BNXT_HWRM_CANCELLED, |
45 | }; |
46 | |
47 | enum bnxt_hwrm_chnl { BNXT_HWRM_CHNL_CHIMP, BNXT_HWRM_CHNL_KONG }; |
48 | |
49 | struct bnxt_hwrm_wait_token { |
50 | struct rcu_head rcu; |
51 | struct hlist_node node; |
52 | enum bnxt_hwrm_wait_state state; |
53 | enum bnxt_hwrm_chnl dst; |
54 | u16 seq_id; |
55 | }; |
56 | |
57 | void hwrm_update_token(struct bnxt *bp, u16 seq, enum bnxt_hwrm_wait_state s); |
58 | |
59 | #define BNXT_HWRM_MAX_REQ_LEN (bp->hwrm_max_req_len) |
60 | #define BNXT_HWRM_SHORT_REQ_LEN sizeof(struct hwrm_short_input) |
61 | #define HWRM_CMD_MAX_TIMEOUT 40000U |
62 | #define SHORT_HWRM_CMD_TIMEOUT 20 |
63 | #define HWRM_CMD_TIMEOUT (bp->hwrm_cmd_timeout) |
64 | #define HWRM_RESET_TIMEOUT ((HWRM_CMD_TIMEOUT) * 4) |
65 | #define BNXT_HWRM_TARGET 0xffff |
66 | #define BNXT_HWRM_NO_CMPL_RING -1 |
67 | #define BNXT_HWRM_REQ_MAX_SIZE 128 |
68 | #define BNXT_HWRM_DMA_SIZE (2 * PAGE_SIZE) /* space for req+resp */ |
69 | #define BNXT_HWRM_RESP_RESERVED PAGE_SIZE |
70 | #define BNXT_HWRM_RESP_OFFSET (BNXT_HWRM_DMA_SIZE - \ |
71 | BNXT_HWRM_RESP_RESERVED) |
72 | #define BNXT_HWRM_CTX_OFFSET (BNXT_HWRM_RESP_OFFSET - \ |
73 | sizeof(struct bnxt_hwrm_ctx)) |
74 | #define BNXT_HWRM_DMA_ALIGN 16 |
75 | #define BNXT_HWRM_SENTINEL 0xb6e1f68a12e9a7eb /* arbitrary value */ |
76 | #define BNXT_HWRM_REQS_PER_PAGE (BNXT_PAGE_SIZE / \ |
77 | BNXT_HWRM_REQ_MAX_SIZE) |
78 | #define HWRM_SHORT_MIN_TIMEOUT 3 |
79 | #define HWRM_SHORT_MAX_TIMEOUT 10 |
80 | #define HWRM_SHORT_TIMEOUT_COUNTER 5 |
81 | |
82 | #define HWRM_MIN_TIMEOUT 25 |
83 | #define HWRM_MAX_TIMEOUT 40 |
84 | |
85 | static inline unsigned int hwrm_total_timeout(unsigned int n) |
86 | { |
87 | return n <= HWRM_SHORT_TIMEOUT_COUNTER ? n * HWRM_SHORT_MIN_TIMEOUT : |
88 | HWRM_SHORT_TIMEOUT_COUNTER * HWRM_SHORT_MIN_TIMEOUT + |
89 | (n - HWRM_SHORT_TIMEOUT_COUNTER) * HWRM_MIN_TIMEOUT; |
90 | } |
91 | |
92 | |
93 | #define HWRM_VALID_BIT_DELAY_USEC 50000 |
94 | |
95 | static inline bool bnxt_cfa_hwrm_message(u16 req_type) |
96 | { |
97 | switch (req_type) { |
98 | case HWRM_CFA_ENCAP_RECORD_ALLOC: |
99 | case HWRM_CFA_ENCAP_RECORD_FREE: |
100 | case HWRM_CFA_DECAP_FILTER_ALLOC: |
101 | case HWRM_CFA_DECAP_FILTER_FREE: |
102 | case HWRM_CFA_EM_FLOW_ALLOC: |
103 | case HWRM_CFA_EM_FLOW_FREE: |
104 | case HWRM_CFA_EM_FLOW_CFG: |
105 | case HWRM_CFA_FLOW_ALLOC: |
106 | case HWRM_CFA_FLOW_FREE: |
107 | case HWRM_CFA_FLOW_INFO: |
108 | case HWRM_CFA_FLOW_FLUSH: |
109 | case HWRM_CFA_FLOW_STATS: |
110 | case HWRM_CFA_METER_PROFILE_ALLOC: |
111 | case HWRM_CFA_METER_PROFILE_FREE: |
112 | case HWRM_CFA_METER_PROFILE_CFG: |
113 | case HWRM_CFA_METER_INSTANCE_ALLOC: |
114 | case HWRM_CFA_METER_INSTANCE_FREE: |
115 | return true; |
116 | default: |
117 | return false; |
118 | } |
119 | } |
120 | |
121 | static inline bool bnxt_kong_hwrm_message(struct bnxt *bp, struct input *req) |
122 | { |
123 | return (bp->fw_cap & BNXT_FW_CAP_KONG_MB_CHNL && |
124 | (bnxt_cfa_hwrm_message(le16_to_cpu(req->req_type)) || |
125 | le16_to_cpu(req->target_id) == HWRM_TARGET_ID_KONG)); |
126 | } |
127 | |
128 | int __hwrm_req_init(struct bnxt *bp, void **req, u16 req_type, u32 req_len); |
129 | #define hwrm_req_init(bp, req, req_type) \ |
130 | __hwrm_req_init((bp), (void **)&(req), (req_type), sizeof(*(req))) |
131 | void *hwrm_req_hold(struct bnxt *bp, void *req); |
132 | void hwrm_req_drop(struct bnxt *bp, void *req); |
133 | void hwrm_req_flags(struct bnxt *bp, void *req, enum bnxt_hwrm_ctx_flags flags); |
134 | void hwrm_req_timeout(struct bnxt *bp, void *req, unsigned int timeout); |
135 | int hwrm_req_send(struct bnxt *bp, void *req); |
136 | int hwrm_req_send_silent(struct bnxt *bp, void *req); |
137 | int hwrm_req_replace(struct bnxt *bp, void *req, void *new_req, u32 len); |
138 | void hwrm_req_alloc_flags(struct bnxt *bp, void *req, gfp_t flags); |
139 | void *hwrm_req_dma_slice(struct bnxt *bp, void *req, u32 size, dma_addr_t *dma); |
140 | |
141 | /* Older devices can only support req length of 128. |
142 | * HWRM_FUNC_CFG requests which don't need fields starting at |
143 | * num_quic_tx_key_ctxs can use this helper to avoid getting -E2BIG. |
144 | */ |
145 | static inline int |
146 | bnxt_hwrm_func_cfg_short_req_init(struct bnxt *bp, |
147 | struct hwrm_func_cfg_input **req) |
148 | { |
149 | u32 req_len; |
150 | |
151 | req_len = min_t(u32, sizeof(**req), bp->hwrm_max_ext_req_len); |
152 | return __hwrm_req_init(bp, req: (void **)req, HWRM_FUNC_CFG, req_len); |
153 | } |
154 | #endif |
155 | |