Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright (c) 2016 - 2018 Cavium Inc.
3 : : * All rights reserved.
4 : : * www.cavium.com
5 : : */
6 : :
7 : : #include <rte_memzone.h>
8 : : #include <rte_errno.h>
9 : :
10 : : #include "bcm_osal.h"
11 : : #include "ecore.h"
12 : : #include "ecore_hw.h"
13 : : #include "ecore_dev_api.h"
14 : : #include "ecore_iov_api.h"
15 : : #include "ecore_mcp_api.h"
16 : : #include "ecore_l2_api.h"
17 : : #include "../qede_sriov.h"
18 : :
19 : 0 : int osal_pf_vf_msg(struct ecore_hwfn *p_hwfn)
20 : : {
21 : : int rc;
22 : :
23 : 0 : rc = qed_schedule_iov(p_hwfn, QED_IOV_WQ_MSG_FLAG);
24 [ # # ]: 0 : if (rc) {
25 [ # # ]: 0 : DP_VERBOSE(p_hwfn, ECORE_MSG_IOV,
26 : : "Failed to schedule alarm handler rc=%d\n", rc);
27 : : }
28 : :
29 : 0 : return rc;
30 : : }
31 : :
32 : 0 : void osal_vf_flr_update(struct ecore_hwfn *p_hwfn)
33 : : {
34 : 0 : qed_schedule_iov(p_hwfn, QED_IOV_WQ_FLR_FLAG);
35 : 0 : }
36 : :
37 : 0 : void osal_poll_mode_dpc(osal_int_ptr_t hwfn_cookie)
38 : : {
39 : 0 : struct ecore_hwfn *p_hwfn = (struct ecore_hwfn *)hwfn_cookie;
40 : :
41 [ # # ]: 0 : if (!p_hwfn)
42 : : return;
43 : :
44 : 0 : OSAL_SPIN_LOCK(&p_hwfn->spq_lock);
45 : 0 : ecore_int_sp_dpc((osal_int_ptr_t)(p_hwfn));
46 : : OSAL_SPIN_UNLOCK(&p_hwfn->spq_lock);
47 : : }
48 : :
49 : : /* Array of memzone pointers */
50 : : static const struct rte_memzone **ecore_mz_mapping;
51 : : /* Counter to track current memzone allocated */
52 : : static uint16_t ecore_mz_count;
53 : :
54 : : static RTE_ATOMIC(uint32_t) ref_cnt;
55 : :
56 : 0 : int ecore_mz_mapping_alloc(void)
57 : : {
58 [ # # ]: 0 : if (rte_atomic_fetch_add_explicit(&ref_cnt, 1, rte_memory_order_relaxed) == 0) {
59 : 0 : ecore_mz_mapping = rte_calloc("ecore_mz_map",
60 : : rte_memzone_max_get(), sizeof(struct rte_memzone *), 0);
61 : : }
62 : :
63 [ # # ]: 0 : if (!ecore_mz_mapping)
64 : 0 : return -ENOMEM;
65 : :
66 : : return 0;
67 : : }
68 : :
69 : 0 : void ecore_mz_mapping_free(void)
70 : : {
71 [ # # ]: 0 : if (rte_atomic_fetch_sub_explicit(&ref_cnt, 1, rte_memory_order_relaxed) - 1 == 0) {
72 : 0 : rte_free(ecore_mz_mapping);
73 : 0 : ecore_mz_mapping = NULL;
74 : : }
75 : 0 : }
76 : :
77 : 0 : unsigned long qede_log2_align(unsigned long n)
78 : : {
79 : 0 : unsigned long ret = n ? 1 : 0;
80 : 0 : unsigned long _n = n >> 1;
81 : :
82 [ # # ]: 0 : while (_n) {
83 : 0 : _n >>= 1;
84 : 0 : ret <<= 1;
85 : : }
86 : :
87 [ # # ]: 0 : if (ret < n)
88 : 0 : ret <<= 1;
89 : :
90 : 0 : return ret;
91 : : }
92 : :
93 : 0 : u32 qede_osal_log2(u32 val)
94 : : {
95 : : u32 log = 0;
96 : :
97 [ # # ]: 0 : while (val >>= 1)
98 : 0 : log++;
99 : :
100 : 0 : return log;
101 : : }
102 : :
103 : : static inline u32 qede_ffb(unsigned long word)
104 : : {
105 : : unsigned long first_bit;
106 : :
107 : 0 : first_bit = __builtin_ffsl(word);
108 : 0 : return first_bit ? (first_bit - 1) : OSAL_BITS_PER_UL;
109 : : }
110 : :
111 : 0 : inline u32 qede_find_first_bit(unsigned long *addr, u32 limit)
112 : : {
113 : : u32 i;
114 : : u32 nwords = 0;
115 : : OSAL_BUILD_BUG_ON(!limit);
116 : 0 : nwords = (limit - 1) / OSAL_BITS_PER_UL + 1;
117 [ # # ]: 0 : for (i = 0; i < nwords; i++)
118 [ # # ]: 0 : if (addr[i] != 0)
119 : : break;
120 : :
121 [ # # # # ]: 0 : return (i == nwords) ? limit : i * OSAL_BITS_PER_UL + qede_ffb(addr[i]);
122 : : }
123 : :
124 : : static inline u32 qede_ffz(unsigned long word)
125 : : {
126 : : unsigned long first_zero;
127 : :
128 : 0 : first_zero = __builtin_ffsl(~word);
129 : 0 : return first_zero ? (first_zero - 1) : OSAL_BITS_PER_UL;
130 : : }
131 : :
132 : 0 : inline u32 qede_find_first_zero_bit(u32 *addr, u32 limit)
133 : : {
134 : : u32 i;
135 : : u32 nwords = 0;
136 : : OSAL_BUILD_BUG_ON(!limit);
137 : 0 : nwords = (limit - 1) / OSAL_BITS_PER_UL + 1;
138 [ # # # # ]: 0 : for (i = 0; i < nwords && ~(addr[i]) == 0; i++);
139 [ # # ]: 0 : return (i == nwords) ? limit : i * OSAL_BITS_PER_UL + qede_ffz(addr[i]);
140 : : }
141 : :
142 : 0 : void qede_vf_fill_driver_data(struct ecore_hwfn *hwfn,
143 : : __rte_unused struct vf_pf_resc_request *resc_req,
144 : : struct ecore_vf_acquire_sw_info *vf_sw_info)
145 : : {
146 : 0 : vf_sw_info->os_type = VFPF_ACQUIRE_OS_LINUX_USERSPACE;
147 : 0 : vf_sw_info->override_fw_version = 1;
148 : 0 : }
149 : :
150 : 0 : void *osal_dma_alloc_coherent(struct ecore_dev *p_dev,
151 : : dma_addr_t *phys, size_t size)
152 : : {
153 : : const struct rte_memzone *mz;
154 : : char mz_name[RTE_MEMZONE_NAMESIZE];
155 : : uint32_t core_id = rte_lcore_id();
156 : : unsigned int socket_id;
157 : :
158 [ # # ]: 0 : if (ecore_mz_count >= rte_memzone_max_get()) {
159 : 0 : DP_ERR(p_dev, "Memzone allocation count exceeds %zu\n",
160 : : rte_memzone_max_get());
161 : 0 : *phys = 0;
162 : 0 : return OSAL_NULL;
163 : : }
164 : :
165 : : OSAL_MEM_ZERO(mz_name, sizeof(*mz_name));
166 : : snprintf(mz_name, sizeof(mz_name), "%lx",
167 : : (unsigned long)rte_get_timer_cycles());
168 [ # # ]: 0 : if (core_id == (unsigned int)LCORE_ID_ANY)
169 : 0 : core_id = rte_get_main_lcore();
170 : 0 : socket_id = rte_lcore_to_socket_id(core_id);
171 : 0 : mz = rte_memzone_reserve_aligned(mz_name, size, socket_id,
172 : : RTE_MEMZONE_IOVA_CONTIG, RTE_CACHE_LINE_SIZE);
173 [ # # ]: 0 : if (!mz) {
174 : 0 : DP_ERR(p_dev, "Unable to allocate DMA memory "
175 : : "of size %zu bytes - %s\n",
176 : : size, rte_strerror(rte_errno));
177 : 0 : *phys = 0;
178 : 0 : return OSAL_NULL;
179 : : }
180 : 0 : *phys = mz->iova;
181 : 0 : ecore_mz_mapping[ecore_mz_count++] = mz;
182 [ # # ]: 0 : DP_VERBOSE(p_dev, ECORE_MSG_SP,
183 : : "Allocated dma memory size=%zu phys=0x%lx"
184 : : " virt=%p core=%d\n",
185 : : mz->len, (unsigned long)mz->iova, mz->addr, core_id);
186 : 0 : return mz->addr;
187 : : }
188 : :
189 : 0 : void *osal_dma_alloc_coherent_aligned(struct ecore_dev *p_dev,
190 : : dma_addr_t *phys, size_t size, int align)
191 : : {
192 : : const struct rte_memzone *mz;
193 : : char mz_name[RTE_MEMZONE_NAMESIZE];
194 : : uint32_t core_id = rte_lcore_id();
195 : : unsigned int socket_id;
196 : :
197 [ # # ]: 0 : if (ecore_mz_count >= rte_memzone_max_get()) {
198 : 0 : DP_ERR(p_dev, "Memzone allocation count exceeds %zu\n",
199 : : rte_memzone_max_get());
200 : 0 : *phys = 0;
201 : 0 : return OSAL_NULL;
202 : : }
203 : :
204 : : OSAL_MEM_ZERO(mz_name, sizeof(*mz_name));
205 : : snprintf(mz_name, sizeof(mz_name), "%lx",
206 : : (unsigned long)rte_get_timer_cycles());
207 [ # # ]: 0 : if (core_id == (unsigned int)LCORE_ID_ANY)
208 : 0 : core_id = rte_get_main_lcore();
209 : 0 : socket_id = rte_lcore_to_socket_id(core_id);
210 : 0 : mz = rte_memzone_reserve_aligned(mz_name, size, socket_id,
211 : : RTE_MEMZONE_IOVA_CONTIG, align);
212 [ # # ]: 0 : if (!mz) {
213 : 0 : DP_ERR(p_dev, "Unable to allocate DMA memory "
214 : : "of size %zu bytes - %s\n",
215 : : size, rte_strerror(rte_errno));
216 : 0 : *phys = 0;
217 : 0 : return OSAL_NULL;
218 : : }
219 : 0 : *phys = mz->iova;
220 : 0 : ecore_mz_mapping[ecore_mz_count++] = mz;
221 [ # # ]: 0 : DP_VERBOSE(p_dev, ECORE_MSG_SP,
222 : : "Allocated aligned dma memory size=%zu phys=0x%lx"
223 : : " virt=%p core=%d\n",
224 : : mz->len, (unsigned long)mz->iova, mz->addr, core_id);
225 : 0 : return mz->addr;
226 : : }
227 : :
228 : 0 : void osal_dma_free_mem(struct ecore_dev *p_dev, dma_addr_t phys)
229 : : {
230 : : uint16_t j;
231 : :
232 [ # # ]: 0 : for (j = 0 ; j < ecore_mz_count; j++) {
233 [ # # ]: 0 : if (phys == ecore_mz_mapping[j]->iova) {
234 [ # # ]: 0 : DP_VERBOSE(p_dev, ECORE_MSG_SP,
235 : : "Free memzone %s\n", ecore_mz_mapping[j]->name);
236 : 0 : rte_memzone_free(ecore_mz_mapping[j]);
237 [ # # ]: 0 : while (j < ecore_mz_count - 1) {
238 : 0 : ecore_mz_mapping[j] = ecore_mz_mapping[j + 1];
239 : 0 : j++;
240 : : }
241 : 0 : ecore_mz_count--;
242 : 0 : return;
243 : : }
244 : : }
245 : :
246 : 0 : DP_ERR(p_dev, "Unexpected memory free request\n");
247 : : }
248 : :
249 : : #ifdef CONFIG_ECORE_ZIPPED_FW
250 : : u32 qede_unzip_data(struct ecore_hwfn *p_hwfn, u32 input_len,
251 : : u8 *input_buf, u32 max_size, u8 *unzip_buf)
252 : : {
253 : : int rc;
254 : :
255 : : p_hwfn->stream->next_in = input_buf;
256 : : p_hwfn->stream->avail_in = input_len;
257 : : p_hwfn->stream->next_out = unzip_buf;
258 : : p_hwfn->stream->avail_out = max_size;
259 : :
260 : : rc = inflateInit2(p_hwfn->stream, MAX_WBITS);
261 : :
262 : : if (rc != Z_OK) {
263 : : DP_ERR(p_hwfn,
264 : : "zlib init failed, rc = %d\n", rc);
265 : : return 0;
266 : : }
267 : :
268 : : rc = inflate(p_hwfn->stream, Z_FINISH);
269 : : inflateEnd(p_hwfn->stream);
270 : :
271 : : if (rc != Z_OK && rc != Z_STREAM_END) {
272 : : DP_ERR(p_hwfn,
273 : : "FW unzip error: %s, rc=%d\n", p_hwfn->stream->msg,
274 : : rc);
275 : : return 0;
276 : : }
277 : :
278 : : return p_hwfn->stream->total_out / 4;
279 : : }
280 : : #endif
281 : :
282 : : void
283 : 0 : qede_get_mcp_proto_stats(struct ecore_dev *edev,
284 : : enum ecore_mcp_protocol_type type,
285 : : union ecore_mcp_protocol_stats *stats)
286 : : {
287 : : struct ecore_eth_stats lan_stats;
288 : :
289 [ # # ]: 0 : if (type == ECORE_MCP_LAN_STATS) {
290 : 0 : ecore_get_vport_stats(edev, &lan_stats);
291 : :
292 : : /* @DPDK */
293 : 0 : stats->lan_stats.ucast_rx_pkts = lan_stats.common.rx_ucast_pkts;
294 : 0 : stats->lan_stats.ucast_tx_pkts = lan_stats.common.tx_ucast_pkts;
295 : :
296 : 0 : stats->lan_stats.fcs_err = -1;
297 : : } else {
298 : 0 : DP_INFO(edev, "Statistics request type %d not supported\n",
299 : : type);
300 : : }
301 : 0 : }
302 : :
303 : 0 : static void qede_hw_err_handler(void *dev, enum ecore_hw_err_type err_type)
304 : : {
305 : : struct ecore_dev *edev = dev;
306 : :
307 [ # # # ]: 0 : switch (err_type) {
308 : : case ECORE_HW_ERR_FAN_FAIL:
309 : : break;
310 : :
311 : 0 : case ECORE_HW_ERR_MFW_RESP_FAIL:
312 : : case ECORE_HW_ERR_HW_ATTN:
313 : : case ECORE_HW_ERR_DMAE_FAIL:
314 : : case ECORE_HW_ERR_RAMROD_FAIL:
315 : : case ECORE_HW_ERR_FW_ASSERT:
316 : 0 : OSAL_SAVE_FW_DUMP(0); /* Using port 0 as default port_id */
317 : 0 : break;
318 : :
319 : : default:
320 : 0 : DP_NOTICE(edev, false, "Unknown HW error [%d]\n", err_type);
321 : 0 : return;
322 : : }
323 : : }
324 : :
325 : : void
326 : 0 : qede_hw_err_notify(struct ecore_hwfn *p_hwfn, enum ecore_hw_err_type err_type)
327 : : {
328 : : char err_str[64];
329 : :
330 [ # # # # : 0 : switch (err_type) {
# # # ]
331 : : case ECORE_HW_ERR_FAN_FAIL:
332 : : strcpy(err_str, "Fan Failure");
333 : : break;
334 : : case ECORE_HW_ERR_MFW_RESP_FAIL:
335 : : strcpy(err_str, "MFW Response Failure");
336 : : break;
337 : : case ECORE_HW_ERR_HW_ATTN:
338 : : strcpy(err_str, "HW Attention");
339 : : break;
340 : : case ECORE_HW_ERR_DMAE_FAIL:
341 : : strcpy(err_str, "DMAE Failure");
342 : : break;
343 : : case ECORE_HW_ERR_RAMROD_FAIL:
344 : : strcpy(err_str, "Ramrod Failure");
345 : : break;
346 : : case ECORE_HW_ERR_FW_ASSERT:
347 : : strcpy(err_str, "FW Assertion");
348 : : break;
349 : : default:
350 : : strcpy(err_str, "Unknown");
351 : : }
352 : :
353 : 0 : DP_ERR(p_hwfn, "HW error occurred [%s]\n", err_str);
354 : :
355 : 0 : qede_hw_err_handler(p_hwfn->p_dev, err_type);
356 : :
357 : 0 : ecore_int_attn_clr_enable(p_hwfn->p_dev, true);
358 : 0 : }
359 : :
360 : 0 : u32 qede_crc32(u32 crc, u8 *ptr, u32 length)
361 : : {
362 : : int i;
363 : :
364 [ # # ]: 0 : while (length--) {
365 : 0 : crc ^= *ptr++;
366 [ # # ]: 0 : for (i = 0; i < 8; i++)
367 [ # # ]: 0 : crc = (crc >> 1) ^ ((crc & 1) ? 0xedb88320 : 0);
368 : : }
369 : 0 : return crc;
370 : : }
371 : :
372 : 0 : void qed_set_platform_str(struct ecore_hwfn *p_hwfn,
373 : : char *buf_str, u32 buf_size)
374 : : {
375 : 0 : snprintf(buf_str, buf_size, "%s.", rte_version());
376 : 0 : }
|