Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2018 Advanced Micro Devices, Inc. All rights reserved.
3 : : * Copyright(c) 2018 Synopsys, Inc. All rights reserved.
4 : : */
5 : :
6 : : #include "axgbe_ethdev.h"
7 : : #include "axgbe_common.h"
8 : : #include "axgbe_phy.h"
9 : : #include "axgbe_rxtx.h"
10 : :
11 : 0 : static uint32_t bitrev32(uint32_t x)
12 : : {
13 : 0 : x = (x >> 16) | (x << 16);
14 : 0 : x = (((x & 0xff00ff00) >> 8) | ((x & 0x00ff00ff) << 8));
15 : 0 : x = (((x & 0xf0f0f0f0) >> 4) | ((x & 0x0f0f0f0f) << 4));
16 : 0 : x = (((x & 0xcccccccc) >> 2) | ((x & 0x33333333) << 2));
17 : 0 : x = (((x & 0xaaaaaaaa) >> 1) | ((x & 0x55555555) << 1));
18 : 0 : return x;
19 : : }
20 : :
21 : : /*MSB set bit from 32 to 1*/
22 : 0 : static int get_lastbit_set(int x)
23 : : {
24 : : int r = 32;
25 : :
26 [ # # ]: 0 : if (!x)
27 : : return 0;
28 [ # # ]: 0 : if (!(x & 0xffff0000)) {
29 : 0 : x <<= 16;
30 : : r -= 16;
31 : : }
32 [ # # ]: 0 : if (!(x & 0xff000000)) {
33 : 0 : x <<= 8;
34 : 0 : r -= 8;
35 : : }
36 [ # # ]: 0 : if (!(x & 0xf0000000)) {
37 : 0 : x <<= 4;
38 : 0 : r -= 4;
39 : : }
40 [ # # ]: 0 : if (!(x & 0xc0000000)) {
41 : 0 : x <<= 2;
42 : 0 : r -= 2;
43 : : }
44 [ # # ]: 0 : if (!(x & 0x80000000)) {
45 : : x <<= 1;
46 : 0 : r -= 1;
47 : : }
48 : : return r;
49 : : }
50 : :
51 : : static inline unsigned int axgbe_get_max_frame(struct axgbe_port *pdata)
52 : : {
53 : 0 : return pdata->eth_dev->data->mtu + RTE_ETHER_HDR_LEN +
54 : : RTE_ETHER_CRC_LEN + RTE_VLAN_HLEN;
55 : : }
56 : :
57 : : /* query busy bit */
58 : : static int mdio_complete(struct axgbe_port *pdata)
59 : : {
60 [ # # # # ]: 0 : if (!AXGMAC_IOREAD_BITS(pdata, MAC_MDIOSCCDR, BUSY))
61 : : return 1;
62 : :
63 : : return 0;
64 : : }
65 : :
66 : : static unsigned int axgbe_create_mdio_sca_c22(int port, int reg)
67 : : {
68 : : unsigned int mdio_sca;
69 : :
70 : : mdio_sca = 0;
71 : 0 : AXGMAC_SET_BITS(mdio_sca, MAC_MDIOSCAR, RA, reg);
72 : 0 : AXGMAC_SET_BITS(mdio_sca, MAC_MDIOSCAR, PA, port);
73 : :
74 : : return mdio_sca;
75 : : }
76 : :
77 : : static unsigned int axgbe_create_mdio_sca_c45(int port, unsigned int da, int reg)
78 : : {
79 : : unsigned int mdio_sca;
80 : :
81 : : mdio_sca = 0;
82 : 0 : AXGMAC_SET_BITS(mdio_sca, MAC_MDIOSCAR, RA, reg);
83 : 0 : AXGMAC_SET_BITS(mdio_sca, MAC_MDIOSCAR, PA, port);
84 : 0 : AXGMAC_SET_BITS(mdio_sca, MAC_MDIOSCAR, DA, da);
85 : :
86 : : return mdio_sca;
87 : : }
88 : :
89 : 0 : static int axgbe_write_ext_mii_regs(struct axgbe_port *pdata,
90 : : unsigned int mdio_sca, u16 val)
91 : : {
92 : : unsigned int mdio_sccd;
93 : : uint64_t timeout;
94 : :
95 : 0 : AXGMAC_IOWRITE(pdata, MAC_MDIOSCAR, mdio_sca);
96 : :
97 : : mdio_sccd = 0;
98 : 0 : AXGMAC_SET_BITS(mdio_sccd, MAC_MDIOSCCDR, DATA, val);
99 : : AXGMAC_SET_BITS(mdio_sccd, MAC_MDIOSCCDR, CMD, 1);
100 : 0 : AXGMAC_SET_BITS(mdio_sccd, MAC_MDIOSCCDR, BUSY, 1);
101 : 0 : AXGMAC_IOWRITE(pdata, MAC_MDIOSCCDR, mdio_sccd);
102 : :
103 : 0 : timeout = rte_get_timer_cycles() + rte_get_timer_hz();
104 [ # # ]: 0 : while (time_before(rte_get_timer_cycles(), timeout)) {
105 : 0 : rte_delay_us(100);
106 : : if (mdio_complete(pdata))
107 : : return 0;
108 : : }
109 : :
110 : 0 : PMD_DRV_LOG_LINE(ERR, "Mdio write operation timed out");
111 : 0 : return -ETIMEDOUT;
112 : : }
113 : :
114 : :
115 : 0 : static int axgbe_write_ext_mii_regs_c22(struct axgbe_port *pdata,
116 : : int addr, int reg, u16 val)
117 : : {
118 : : unsigned int mdio_sca;
119 : :
120 : : mdio_sca = axgbe_create_mdio_sca_c22(addr, reg);
121 : :
122 : 0 : return axgbe_write_ext_mii_regs(pdata, mdio_sca, val);
123 : : }
124 : :
125 : 0 : static int axgbe_write_ext_mii_regs_c45(struct axgbe_port *pdata,
126 : : int addr, int devad, int reg, u16 val)
127 : : {
128 : : unsigned int mdio_sca;
129 : :
130 : 0 : mdio_sca = axgbe_create_mdio_sca_c45(addr, devad, reg);
131 : :
132 : 0 : return axgbe_write_ext_mii_regs(pdata, mdio_sca, val);
133 : : }
134 : :
135 : :
136 : 0 : static int axgbe_read_ext_mii_regs(struct axgbe_port *pdata,
137 : : unsigned int mdio_sca)
138 : : {
139 : : unsigned int mdio_sccd;
140 : : uint64_t timeout;
141 : :
142 : 0 : AXGMAC_IOWRITE(pdata, MAC_MDIOSCAR, mdio_sca);
143 : :
144 : : mdio_sccd = 0;
145 : : AXGMAC_SET_BITS(mdio_sccd, MAC_MDIOSCCDR, CMD, 3);
146 : : AXGMAC_SET_BITS(mdio_sccd, MAC_MDIOSCCDR, BUSY, 1);
147 : 0 : AXGMAC_IOWRITE(pdata, MAC_MDIOSCCDR, mdio_sccd);
148 : :
149 : 0 : timeout = rte_get_timer_cycles() + rte_get_timer_hz();
150 : :
151 [ # # ]: 0 : while (time_before(rte_get_timer_cycles(), timeout)) {
152 : 0 : rte_delay_us(100);
153 : : if (mdio_complete(pdata))
154 : 0 : goto success;
155 : : }
156 : :
157 : 0 : PMD_DRV_LOG_LINE(ERR, "Mdio read operation timed out");
158 : 0 : return -ETIMEDOUT;
159 : :
160 : : success:
161 : 0 : return AXGMAC_IOREAD_BITS(pdata, MAC_MDIOSCCDR, DATA);
162 : : }
163 : :
164 : 0 : static int axgbe_read_ext_mii_regs_c22(struct axgbe_port *pdata, int addr, int reg)
165 : : {
166 : : unsigned int mdio_sca;
167 : :
168 : : mdio_sca = axgbe_create_mdio_sca_c22(addr, reg);
169 : :
170 : 0 : return axgbe_read_ext_mii_regs(pdata, mdio_sca);
171 : : }
172 : :
173 : 0 : static int axgbe_read_ext_mii_regs_c45(struct axgbe_port *pdata, int addr,
174 : : int devad, int reg)
175 : : {
176 : : unsigned int mdio_sca;
177 : :
178 : 0 : mdio_sca = axgbe_create_mdio_sca_c45(addr, devad, reg);
179 : :
180 : 0 : return axgbe_read_ext_mii_regs(pdata, mdio_sca);
181 : : }
182 : :
183 : 0 : static int axgbe_set_ext_mii_mode(struct axgbe_port *pdata, unsigned int port,
184 : : enum axgbe_mdio_mode mode)
185 : : {
186 : : unsigned int reg_val = 0;
187 : :
188 [ # # # ]: 0 : switch (mode) {
189 : 0 : case AXGBE_MDIO_MODE_CL22:
190 [ # # ]: 0 : if (port > AXGMAC_MAX_C22_PORT)
191 : : return -EINVAL;
192 : 0 : reg_val |= (1 << port);
193 : 0 : break;
194 : : case AXGBE_MDIO_MODE_CL45:
195 : : break;
196 : : default:
197 : : return -EINVAL;
198 : : }
199 : 0 : AXGMAC_IOWRITE(pdata, MAC_MDIOCL22R, reg_val);
200 : :
201 : 0 : return 0;
202 : : }
203 : :
204 : 0 : static int axgbe_read_mmd_regs_v2(struct axgbe_port *pdata,
205 : : int prtad __rte_unused, int mmd_reg)
206 : : {
207 : : unsigned int mmd_address, index, offset;
208 : : int mmd_data;
209 : :
210 [ # # ]: 0 : if (mmd_reg & AXGBE_ADDR_C45)
211 : 0 : mmd_address = mmd_reg & ~AXGBE_ADDR_C45;
212 : : else
213 : 0 : mmd_address = (pdata->mdio_mmd << 16) | (mmd_reg & 0xffff);
214 : :
215 : : /* The PCS registers are accessed using mmio. The underlying
216 : : * management interface uses indirect addressing to access the MMD
217 : : * register sets. This requires accessing of the PCS register in two
218 : : * phases, an address phase and a data phase.
219 : : *
220 : : * The mmio interface is based on 16-bit offsets and values. All
221 : : * register offsets must therefore be adjusted by left shifting the
222 : : * offset 1 bit and reading 16 bits of data.
223 : : */
224 : 0 : mmd_address <<= 1;
225 : 0 : index = mmd_address & ~pdata->xpcs_window_mask;
226 : 0 : offset = pdata->xpcs_window + (mmd_address & pdata->xpcs_window_mask);
227 : :
228 : 0 : pthread_mutex_lock(&pdata->xpcs_mutex);
229 : :
230 : 0 : XPCS32_IOWRITE(pdata, pdata->xpcs_window_sel_reg, index);
231 : 0 : mmd_data = XPCS16_IOREAD(pdata, offset);
232 : :
233 : 0 : pthread_mutex_unlock(&pdata->xpcs_mutex);
234 : :
235 : 0 : return mmd_data;
236 : : }
237 : :
238 : 0 : static void axgbe_write_mmd_regs_v2(struct axgbe_port *pdata,
239 : : int prtad __rte_unused,
240 : : int mmd_reg, int mmd_data)
241 : : {
242 : : unsigned int mmd_address, index, offset;
243 : :
244 [ # # ]: 0 : if (mmd_reg & AXGBE_ADDR_C45)
245 : 0 : mmd_address = mmd_reg & ~AXGBE_ADDR_C45;
246 : : else
247 : 0 : mmd_address = (pdata->mdio_mmd << 16) | (mmd_reg & 0xffff);
248 : :
249 : : /* The PCS registers are accessed using mmio. The underlying
250 : : * management interface uses indirect addressing to access the MMD
251 : : * register sets. This requires accessing of the PCS register in two
252 : : * phases, an address phase and a data phase.
253 : : *
254 : : * The mmio interface is based on 16-bit offsets and values. All
255 : : * register offsets must therefore be adjusted by left shifting the
256 : : * offset 1 bit and writing 16 bits of data.
257 : : */
258 : 0 : mmd_address <<= 1;
259 : 0 : index = mmd_address & ~pdata->xpcs_window_mask;
260 : 0 : offset = pdata->xpcs_window + (mmd_address & pdata->xpcs_window_mask);
261 : :
262 : 0 : pthread_mutex_lock(&pdata->xpcs_mutex);
263 : :
264 : 0 : XPCS32_IOWRITE(pdata, pdata->xpcs_window_sel_reg, index);
265 : 0 : XPCS16_IOWRITE(pdata, offset, mmd_data);
266 : :
267 : 0 : pthread_mutex_unlock(&pdata->xpcs_mutex);
268 : 0 : }
269 : :
270 : 0 : static int axgbe_read_mmd_regs(struct axgbe_port *pdata, int prtad,
271 : : int mmd_reg)
272 : : {
273 [ # # ]: 0 : switch (pdata->vdata->xpcs_access) {
274 : 0 : case AXGBE_XPCS_ACCESS_V1:
275 : 0 : PMD_DRV_LOG_LINE(ERR, "PHY_Version 1 is not supported");
276 : 0 : return -1;
277 : 0 : case AXGBE_XPCS_ACCESS_V2:
278 : : default:
279 : 0 : return axgbe_read_mmd_regs_v2(pdata, prtad, mmd_reg);
280 : : }
281 : : }
282 : :
283 : 0 : static void axgbe_write_mmd_regs(struct axgbe_port *pdata, int prtad,
284 : : int mmd_reg, int mmd_data)
285 : : {
286 [ # # ]: 0 : switch (pdata->vdata->xpcs_access) {
287 : 0 : case AXGBE_XPCS_ACCESS_V1:
288 : 0 : PMD_DRV_LOG_LINE(ERR, "PHY_Version 1 is not supported");
289 : 0 : return;
290 : 0 : case AXGBE_XPCS_ACCESS_V2:
291 : : default:
292 : 0 : return axgbe_write_mmd_regs_v2(pdata, prtad, mmd_reg, mmd_data);
293 : : }
294 : : }
295 : :
296 : 0 : static int axgbe_set_speed(struct axgbe_port *pdata, int speed)
297 : : {
298 : : unsigned int ss;
299 : :
300 [ # # # # : 0 : switch (speed) {
# ]
301 : : case SPEED_10:
302 : : ss = 0x07;
303 : : break;
304 : 0 : case SPEED_1000:
305 : : ss = 0x03;
306 : 0 : break;
307 : 0 : case SPEED_2500:
308 : : ss = 0x02;
309 : 0 : break;
310 : 0 : case SPEED_10000:
311 : : ss = 0x00;
312 : 0 : break;
313 : : default:
314 : : return -EINVAL;
315 : : }
316 : :
317 [ # # ]: 0 : if (AXGMAC_IOREAD_BITS(pdata, MAC_TCR, SS) != ss)
318 : 0 : AXGMAC_IOWRITE_BITS(pdata, MAC_TCR, SS, ss);
319 : :
320 : : return 0;
321 : : }
322 : :
323 : : static unsigned int axgbe_get_fc_queue_count(struct axgbe_port *pdata)
324 : : {
325 : : unsigned int max_q_count = AXGMAC_MAX_FLOW_CONTROL_QUEUES;
326 : :
327 : : /* From MAC ver 30H the TFCR is per priority, instead of per queue */
328 [ # # # # ]: 0 : if (AXGMAC_GET_BITS(pdata->hw_feat.version, MAC_VR, SNPSVER) >= 0x30)
329 : : return max_q_count;
330 : : else
331 : 0 : return (RTE_MIN(pdata->tx_q_count, max_q_count));
332 : : }
333 : :
334 : 0 : static int axgbe_disable_tx_flow_control(struct axgbe_port *pdata)
335 : : {
336 : : unsigned int reg, reg_val;
337 : : unsigned int i, q_count;
338 : :
339 : : /* Clear MTL flow control */
340 [ # # ]: 0 : for (i = 0; i < pdata->rx_q_count; i++)
341 : 0 : AXGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_Q_RQOMR, EHFC, 0);
342 : :
343 : : /* Clear MAC flow control */
344 : : q_count = axgbe_get_fc_queue_count(pdata);
345 : : reg = MAC_Q0TFCR;
346 [ # # ]: 0 : for (i = 0; i < q_count; i++) {
347 : 0 : reg_val = AXGMAC_IOREAD(pdata, reg);
348 : 0 : AXGMAC_SET_BITS(reg_val, MAC_Q0TFCR, TFE, 0);
349 : 0 : AXGMAC_IOWRITE(pdata, reg, reg_val);
350 : :
351 : 0 : reg += MAC_QTFCR_INC;
352 : : }
353 : :
354 : 0 : return 0;
355 : : }
356 : :
357 : 0 : static int axgbe_enable_tx_flow_control(struct axgbe_port *pdata)
358 : : {
359 : : unsigned int reg, reg_val;
360 : : unsigned int i, q_count;
361 : :
362 : : /* Set MTL flow control */
363 [ # # ]: 0 : for (i = 0; i < pdata->rx_q_count; i++) {
364 : : unsigned int ehfc = 0;
365 : :
366 : : /* Flow control thresholds are established */
367 [ # # ]: 0 : if (pdata->rx_rfd[i])
368 : : ehfc = 1;
369 : :
370 : 0 : AXGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_Q_RQOMR, EHFC, ehfc);
371 : :
372 [ # # ]: 0 : PMD_DRV_LOG_LINE(DEBUG, "flow control %s for RXq%u",
373 : : ehfc ? "enabled" : "disabled", i);
374 : : }
375 : :
376 : : /* Set MAC flow control */
377 : : q_count = axgbe_get_fc_queue_count(pdata);
378 : : reg = MAC_Q0TFCR;
379 [ # # ]: 0 : for (i = 0; i < q_count; i++) {
380 : 0 : reg_val = AXGMAC_IOREAD(pdata, reg);
381 : :
382 : : /* Enable transmit flow control */
383 : : AXGMAC_SET_BITS(reg_val, MAC_Q0TFCR, TFE, 1);
384 : : /* Set pause time */
385 : 0 : AXGMAC_SET_BITS(reg_val, MAC_Q0TFCR, PT, 0xffff);
386 : :
387 : 0 : AXGMAC_IOWRITE(pdata, reg, reg_val);
388 : :
389 : 0 : reg += MAC_QTFCR_INC;
390 : : }
391 : :
392 : 0 : return 0;
393 : : }
394 : :
395 : : static int axgbe_disable_rx_flow_control(struct axgbe_port *pdata)
396 : : {
397 : 0 : AXGMAC_IOWRITE_BITS(pdata, MAC_RFCR, RFE, 0);
398 : :
399 : 0 : return 0;
400 : : }
401 : :
402 : : static int axgbe_enable_rx_flow_control(struct axgbe_port *pdata)
403 : : {
404 : 0 : AXGMAC_IOWRITE_BITS(pdata, MAC_RFCR, RFE, 1);
405 : :
406 : 0 : return 0;
407 : : }
408 : :
409 : 0 : static int axgbe_config_tx_flow_control(struct axgbe_port *pdata)
410 : : {
411 [ # # ]: 0 : if (pdata->tx_pause)
412 : 0 : axgbe_enable_tx_flow_control(pdata);
413 : : else
414 : 0 : axgbe_disable_tx_flow_control(pdata);
415 : :
416 : 0 : return 0;
417 : : }
418 : :
419 : 0 : static int axgbe_config_rx_flow_control(struct axgbe_port *pdata)
420 : : {
421 [ # # # # ]: 0 : if (pdata->rx_pause)
422 : : axgbe_enable_rx_flow_control(pdata);
423 : : else
424 : : axgbe_disable_rx_flow_control(pdata);
425 : :
426 : 0 : return 0;
427 : : }
428 : :
429 : 0 : static void axgbe_config_flow_control(struct axgbe_port *pdata)
430 : : {
431 : 0 : axgbe_config_tx_flow_control(pdata);
432 : : axgbe_config_rx_flow_control(pdata);
433 : :
434 : 0 : AXGMAC_IOWRITE_BITS(pdata, MAC_RFCR, PFCE, 0);
435 : 0 : }
436 : :
437 : 0 : static void axgbe_queue_flow_control_threshold(struct axgbe_port *pdata,
438 : : unsigned int queue,
439 : : unsigned int q_fifo_size)
440 : : {
441 : : unsigned int frame_fifo_size;
442 : : unsigned int rfa, rfd;
443 : :
444 : 0 : frame_fifo_size = AXGMAC_FLOW_CONTROL_ALIGN(axgbe_get_max_frame(pdata));
445 : :
446 : : /* This path deals with just maximum frame sizes which are
447 : : * limited to a jumbo frame of 9,000 (plus headers, etc.)
448 : : * so we can never exceed the maximum allowable RFA/RFD
449 : : * values.
450 : : */
451 [ # # ]: 0 : if (q_fifo_size <= 2048) {
452 : : /* rx_rfd to zero to signal no flow control */
453 : 0 : pdata->rx_rfa[queue] = 0;
454 : 0 : pdata->rx_rfd[queue] = 0;
455 : 0 : return;
456 : : }
457 : :
458 [ # # ]: 0 : if (q_fifo_size <= 4096) {
459 : : /* Between 2048 and 4096 */
460 : 0 : pdata->rx_rfa[queue] = 0; /* Full - 1024 bytes */
461 : 0 : pdata->rx_rfd[queue] = 1; /* Full - 1536 bytes */
462 : 0 : return;
463 : : }
464 : :
465 [ # # ]: 0 : if (q_fifo_size <= frame_fifo_size) {
466 : : /* Between 4096 and max-frame */
467 : 0 : pdata->rx_rfa[queue] = 2; /* Full - 2048 bytes */
468 : 0 : pdata->rx_rfd[queue] = 5; /* Full - 3584 bytes */
469 : 0 : return;
470 : : }
471 : :
472 [ # # ]: 0 : if (q_fifo_size <= (frame_fifo_size * 3)) {
473 : : /* Between max-frame and 3 max-frames,
474 : : * trigger if we get just over a frame of data and
475 : : * resume when we have just under half a frame left.
476 : : */
477 : 0 : rfa = q_fifo_size - frame_fifo_size;
478 : 0 : rfd = rfa + (frame_fifo_size / 2);
479 : : } else {
480 : : /* Above 3 max-frames - trigger when just over
481 : : * 2 frames of space available
482 : : */
483 : 0 : rfa = frame_fifo_size * 2;
484 : 0 : rfa += AXGMAC_FLOW_CONTROL_UNIT;
485 : 0 : rfd = rfa + frame_fifo_size;
486 : : }
487 : :
488 [ # # ]: 0 : pdata->rx_rfa[queue] = AXGMAC_FLOW_CONTROL_VALUE(rfa);
489 [ # # ]: 0 : pdata->rx_rfd[queue] = AXGMAC_FLOW_CONTROL_VALUE(rfd);
490 : : }
491 : :
492 : 0 : static void axgbe_calculate_flow_control_threshold(struct axgbe_port *pdata)
493 : : {
494 : : unsigned int q_fifo_size;
495 : : unsigned int i;
496 : :
497 [ # # ]: 0 : for (i = 0; i < pdata->rx_q_count; i++) {
498 : 0 : q_fifo_size = (pdata->fifo + 1) * AXGMAC_FIFO_UNIT;
499 : :
500 : 0 : axgbe_queue_flow_control_threshold(pdata, i, q_fifo_size);
501 : : }
502 : 0 : }
503 : :
504 : 0 : static void axgbe_config_flow_control_threshold(struct axgbe_port *pdata)
505 : : {
506 : : unsigned int i;
507 : :
508 [ # # ]: 0 : for (i = 0; i < pdata->rx_q_count; i++) {
509 : 0 : AXGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_Q_RQFCR, RFA,
510 : : pdata->rx_rfa[i]);
511 : 0 : AXGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_Q_RQFCR, RFD,
512 : : pdata->rx_rfd[i]);
513 : : }
514 : 0 : }
515 : :
516 : 0 : static int axgbe_enable_rx_vlan_stripping(struct axgbe_port *pdata)
517 : : {
518 : : /* Put the VLAN tag in the Rx descriptor */
519 : 0 : AXGMAC_IOWRITE_BITS(pdata, MAC_VLANTR, EVLRXS, 1);
520 : :
521 : : /* Don't check the VLAN type */
522 : 0 : AXGMAC_IOWRITE_BITS(pdata, MAC_VLANTR, DOVLTC, 1);
523 : :
524 : : /* Check only C-TAG (0x8100) packets */
525 : 0 : AXGMAC_IOWRITE_BITS(pdata, MAC_VLANTR, ERSVLM, 0);
526 : :
527 : : /* Don't consider an S-TAG (0x88A8) packet as a VLAN packet */
528 : 0 : AXGMAC_IOWRITE_BITS(pdata, MAC_VLANTR, ESVL, 0);
529 : :
530 : : /* Enable VLAN tag stripping */
531 : 0 : AXGMAC_IOWRITE_BITS(pdata, MAC_VLANTR, EVLS, 0x3);
532 : 0 : return 0;
533 : : }
534 : :
535 : 0 : static int axgbe_disable_rx_vlan_stripping(struct axgbe_port *pdata)
536 : : {
537 : 0 : AXGMAC_IOWRITE_BITS(pdata, MAC_VLANTR, EVLS, 0);
538 : 0 : return 0;
539 : : }
540 : :
541 : 0 : static int axgbe_enable_rx_vlan_filtering(struct axgbe_port *pdata)
542 : : {
543 : : /* Enable VLAN filtering */
544 : 0 : AXGMAC_IOWRITE_BITS(pdata, MAC_PFR, VTFE, 1);
545 : :
546 : : /* Enable VLAN Hash Table filtering */
547 : 0 : AXGMAC_IOWRITE_BITS(pdata, MAC_VLANTR, VTHM, 1);
548 : :
549 : : /* Disable VLAN tag inverse matching */
550 : 0 : AXGMAC_IOWRITE_BITS(pdata, MAC_VLANTR, VTIM, 0);
551 : :
552 : : /* Only filter on the lower 12-bits of the VLAN tag */
553 : 0 : AXGMAC_IOWRITE_BITS(pdata, MAC_VLANTR, ETV, 1);
554 : :
555 : : /* In order for the VLAN Hash Table filtering to be effective,
556 : : * the VLAN tag identifier in the VLAN Tag Register must not
557 : : * be zero. Set the VLAN tag identifier to "1" to enable the
558 : : * VLAN Hash Table filtering. This implies that a VLAN tag of
559 : : * 1 will always pass filtering.
560 : : */
561 : 0 : AXGMAC_IOWRITE_BITS(pdata, MAC_VLANTR, VL, 1);
562 : 0 : return 0;
563 : : }
564 : :
565 : 0 : static int axgbe_disable_rx_vlan_filtering(struct axgbe_port *pdata)
566 : : {
567 : : /* Disable VLAN filtering */
568 : 0 : AXGMAC_IOWRITE_BITS(pdata, MAC_PFR, VTFE, 0);
569 : 0 : return 0;
570 : : }
571 : :
572 : 0 : static u32 axgbe_vid_crc32_le(__le16 vid_le)
573 : : {
574 : : u32 poly = 0xedb88320; /* CRCPOLY_LE */
575 : : u32 crc = ~0;
576 : : u32 temp = 0;
577 : : unsigned char *data = (unsigned char *)&vid_le;
578 : : unsigned char data_byte = 0;
579 : : int i, bits;
580 : :
581 : 0 : bits = get_lastbit_set(VLAN_VID_MASK);
582 [ # # ]: 0 : for (i = 0; i < bits; i++) {
583 [ # # ]: 0 : if ((i % 8) == 0)
584 : 0 : data_byte = data[i / 8];
585 : :
586 : 0 : temp = ((crc & 1) ^ data_byte) & 1;
587 : 0 : crc >>= 1;
588 : 0 : data_byte >>= 1;
589 : :
590 [ # # ]: 0 : if (temp)
591 : 0 : crc ^= poly;
592 : : }
593 : 0 : return crc;
594 : : }
595 : :
596 : 0 : static int axgbe_update_vlan_hash_table(struct axgbe_port *pdata)
597 : : {
598 : : u32 crc = 0;
599 : : u16 vid;
600 : : __le16 vid_le = 0;
601 : : u16 vlan_hash_table = 0;
602 : : unsigned int reg = 0;
603 : : unsigned long vid_idx, vid_valid;
604 : :
605 : : /* Generate the VLAN Hash Table value */
606 [ # # ]: 0 : for (vid = 0; vid < VLAN_N_VID; vid++) {
607 : 0 : vid_idx = VLAN_TABLE_IDX(vid);
608 : 0 : vid_valid = pdata->active_vlans[vid_idx];
609 : 0 : vid_valid = (unsigned long)vid_valid >> (vid - (64 * vid_idx));
610 [ # # ]: 0 : if (vid_valid & 1)
611 : 0 : PMD_DRV_LOG_LINE(DEBUG,
612 : : "vid:%d pdata->active_vlans[%ld]=0x%lx",
613 : : vid, vid_idx, pdata->active_vlans[vid_idx]);
614 : : else
615 : 0 : continue;
616 : :
617 : : vid_le = rte_cpu_to_le_16(vid);
618 : 0 : crc = bitrev32(~axgbe_vid_crc32_le(vid_le)) >> 28;
619 : 0 : vlan_hash_table |= (1 << crc);
620 : 0 : PMD_DRV_LOG_LINE(DEBUG, "crc = %d vlan_hash_table = 0x%x",
621 : : crc, vlan_hash_table);
622 : : }
623 : : /* Set the VLAN Hash Table filtering register */
624 : 0 : AXGMAC_IOWRITE_BITS(pdata, MAC_VLANHTR, VLHT, vlan_hash_table);
625 : 0 : reg = AXGMAC_IOREAD(pdata, MAC_VLANHTR);
626 : 0 : PMD_DRV_LOG_LINE(DEBUG, "vlan_hash_table reg val = 0x%x", reg);
627 : 0 : return 0;
628 : : }
629 : :
630 : 0 : static int __axgbe_exit(struct axgbe_port *pdata)
631 : : {
632 : : unsigned int count = 2000;
633 : :
634 : : /* Issue a software reset */
635 : 0 : AXGMAC_IOWRITE_BITS(pdata, DMA_MR, SWR, 1);
636 : 0 : rte_delay_us(10);
637 : :
638 : : /* Poll Until Poll Condition */
639 [ # # # # ]: 0 : while (--count && AXGMAC_IOREAD_BITS(pdata, DMA_MR, SWR))
640 : 0 : rte_delay_us(500);
641 : :
642 [ # # ]: 0 : if (!count)
643 : 0 : return -EBUSY;
644 : :
645 : : return 0;
646 : : }
647 : :
648 : 0 : static int axgbe_exit(struct axgbe_port *pdata)
649 : : {
650 : : int ret;
651 : :
652 : : /* To guard against possible incorrectly generated interrupts,
653 : : * issue the software reset twice.
654 : : */
655 : 0 : ret = __axgbe_exit(pdata);
656 [ # # ]: 0 : if (ret)
657 : : return ret;
658 : :
659 : 0 : return __axgbe_exit(pdata);
660 : : }
661 : :
662 : 0 : static int axgbe_flush_tx_queues(struct axgbe_port *pdata)
663 : : {
664 : : unsigned int i, count;
665 : :
666 [ # # ]: 0 : if (AXGMAC_GET_BITS(pdata->hw_feat.version, MAC_VR, SNPSVER) < 0x21)
667 : : return 0;
668 : :
669 [ # # ]: 0 : for (i = 0; i < pdata->tx_q_count; i++)
670 : 0 : AXGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_Q_TQOMR, FTQ, 1);
671 : :
672 : : /* Poll Until Poll Condition */
673 [ # # ]: 0 : for (i = 0; i < pdata->tx_q_count; i++) {
674 : : count = 2000;
675 [ # # # # ]: 0 : while (--count && AXGMAC_MTL_IOREAD_BITS(pdata, i,
676 : : MTL_Q_TQOMR, FTQ))
677 : 0 : rte_delay_us(500);
678 : :
679 [ # # ]: 0 : if (!count)
680 : : return -EBUSY;
681 : : }
682 : :
683 : : return 0;
684 : : }
685 : :
686 : 0 : static void axgbe_config_dma_bus(struct axgbe_port *pdata)
687 : : {
688 : : /* Set enhanced addressing mode */
689 : 0 : AXGMAC_IOWRITE_BITS(pdata, DMA_SBMR, EAME, 1);
690 : :
691 : : /* Out standing read/write requests*/
692 : 0 : AXGMAC_IOWRITE_BITS(pdata, DMA_SBMR, RD_OSR, 0x3f);
693 : 0 : AXGMAC_IOWRITE_BITS(pdata, DMA_SBMR, WR_OSR, 0x3f);
694 : :
695 : : /* Set the System Bus mode */
696 : 0 : AXGMAC_IOWRITE_BITS(pdata, DMA_SBMR, UNDEF, 1);
697 : 0 : AXGMAC_IOWRITE_BITS(pdata, DMA_SBMR, BLEN_32, 1);
698 : 0 : AXGMAC_IOWRITE_BITS(pdata, DMA_SBMR, AAL, 1);
699 : 0 : }
700 : :
701 : : static void axgbe_config_dma_cache(struct axgbe_port *pdata)
702 : : {
703 : : unsigned int arcache, awcache, arwcache;
704 : :
705 : : arcache = 0;
706 : : AXGMAC_SET_BITS(arcache, DMA_AXIARCR, DRC, 0xf);
707 : : AXGMAC_SET_BITS(arcache, DMA_AXIARCR, TEC, 0xf);
708 : : AXGMAC_SET_BITS(arcache, DMA_AXIARCR, THC, 0xf);
709 : 0 : AXGMAC_IOWRITE(pdata, DMA_AXIARCR, arcache);
710 : :
711 : : awcache = 0;
712 : : AXGMAC_SET_BITS(awcache, DMA_AXIAWCR, DWC, 0xf);
713 : : AXGMAC_SET_BITS(awcache, DMA_AXIAWCR, RPC, 0xf);
714 : : AXGMAC_SET_BITS(awcache, DMA_AXIAWCR, RHC, 0xf);
715 : : AXGMAC_SET_BITS(awcache, DMA_AXIAWCR, RDC, 0xf);
716 : 0 : AXGMAC_IOWRITE(pdata, DMA_AXIAWCR, awcache);
717 : :
718 : : arwcache = 0;
719 : : AXGMAC_SET_BITS(arwcache, DMA_AXIAWRCR, TDWC, 0xf);
720 : : AXGMAC_SET_BITS(arwcache, DMA_AXIAWRCR, RDRC, 0xf);
721 : 0 : AXGMAC_IOWRITE(pdata, DMA_AXIAWRCR, arwcache);
722 : : }
723 : :
724 : : static void axgbe_config_edma_control(struct axgbe_port *pdata)
725 : : {
726 : 0 : AXGMAC_IOWRITE(pdata, EDMA_TX_CONTROL, 0x5);
727 : 0 : AXGMAC_IOWRITE(pdata, EDMA_RX_CONTROL, 0x5);
728 : : }
729 : :
730 : 0 : static int axgbe_config_osp_mode(struct axgbe_port *pdata)
731 : : {
732 : : /* Force DMA to operate on second packet before closing descriptors
733 : : * of first packet
734 : : */
735 : : struct axgbe_tx_queue *txq;
736 : : unsigned int i;
737 : :
738 [ # # ]: 0 : for (i = 0; i < pdata->eth_dev->data->nb_tx_queues; i++) {
739 : 0 : txq = pdata->eth_dev->data->tx_queues[i];
740 : 0 : AXGMAC_DMA_IOWRITE_BITS(txq, DMA_CH_TCR, OSP,
741 : : pdata->tx_osp_mode);
742 : : }
743 : :
744 : 0 : return 0;
745 : : }
746 : :
747 : 0 : static int axgbe_config_pblx8(struct axgbe_port *pdata)
748 : : {
749 : : struct axgbe_tx_queue *txq;
750 : : unsigned int i;
751 : :
752 [ # # ]: 0 : for (i = 0; i < pdata->eth_dev->data->nb_tx_queues; i++) {
753 : 0 : txq = pdata->eth_dev->data->tx_queues[i];
754 : 0 : AXGMAC_DMA_IOWRITE_BITS(txq, DMA_CH_CR, PBLX8,
755 : : pdata->pblx8);
756 : : }
757 : 0 : return 0;
758 : : }
759 : :
760 : 0 : static int axgbe_config_tx_pbl_val(struct axgbe_port *pdata)
761 : : {
762 : : struct axgbe_tx_queue *txq;
763 : : unsigned int i;
764 : :
765 [ # # ]: 0 : for (i = 0; i < pdata->eth_dev->data->nb_tx_queues; i++) {
766 : 0 : txq = pdata->eth_dev->data->tx_queues[i];
767 : 0 : AXGMAC_DMA_IOWRITE_BITS(txq, DMA_CH_TCR, PBL,
768 : : pdata->tx_pbl);
769 : : }
770 : :
771 : 0 : return 0;
772 : : }
773 : :
774 : 0 : static int axgbe_config_rx_pbl_val(struct axgbe_port *pdata)
775 : : {
776 : : struct axgbe_rx_queue *rxq;
777 : : unsigned int i;
778 : :
779 [ # # ]: 0 : for (i = 0; i < pdata->eth_dev->data->nb_rx_queues; i++) {
780 : 0 : rxq = pdata->eth_dev->data->rx_queues[i];
781 : 0 : AXGMAC_DMA_IOWRITE_BITS(rxq, DMA_CH_RCR, PBL,
782 : : pdata->rx_pbl);
783 : : }
784 : :
785 : 0 : return 0;
786 : : }
787 : :
788 : 0 : static void axgbe_config_rx_buffer_size(struct axgbe_port *pdata)
789 : : {
790 : : struct axgbe_rx_queue *rxq;
791 : : unsigned int i;
792 : :
793 [ # # ]: 0 : for (i = 0; i < pdata->eth_dev->data->nb_rx_queues; i++) {
794 : 0 : rxq = pdata->eth_dev->data->rx_queues[i];
795 : :
796 [ # # ]: 0 : rxq->buf_size = rte_pktmbuf_data_room_size(rxq->mb_pool) -
797 : : RTE_PKTMBUF_HEADROOM;
798 : 0 : rxq->buf_size = (rxq->buf_size + AXGBE_RX_BUF_ALIGN - 1) &
799 : : ~(AXGBE_RX_BUF_ALIGN - 1);
800 : :
801 [ # # ]: 0 : if (rxq->buf_size > pdata->rx_buf_size)
802 : 0 : pdata->rx_buf_size = rxq->buf_size;
803 : :
804 : 0 : AXGMAC_DMA_IOWRITE_BITS(rxq, DMA_CH_RCR, RBSZ,
805 : : rxq->buf_size);
806 : : }
807 : 0 : }
808 : :
809 : 0 : static int axgbe_write_rss_reg(struct axgbe_port *pdata, unsigned int type,
810 : : unsigned int index, unsigned int val)
811 : : {
812 : : unsigned int wait;
813 : :
814 [ # # ]: 0 : if (AXGMAC_IOREAD_BITS(pdata, MAC_RSSAR, OB))
815 : : return -EBUSY;
816 : :
817 : 0 : AXGMAC_IOWRITE(pdata, MAC_RSSDR, val);
818 : :
819 : 0 : AXGMAC_IOWRITE_BITS(pdata, MAC_RSSAR, RSSIA, index);
820 : 0 : AXGMAC_IOWRITE_BITS(pdata, MAC_RSSAR, ADDRT, type);
821 : 0 : AXGMAC_IOWRITE_BITS(pdata, MAC_RSSAR, CT, 0);
822 : 0 : AXGMAC_IOWRITE_BITS(pdata, MAC_RSSAR, OB, 1);
823 : :
824 : : wait = 1000;
825 [ # # ]: 0 : while (wait--) {
826 [ # # ]: 0 : if (!AXGMAC_IOREAD_BITS(pdata, MAC_RSSAR, OB))
827 : : return 0;
828 : :
829 : 0 : rte_delay_us(1500);
830 : : }
831 : :
832 : : return -EBUSY;
833 : : }
834 : :
835 : 0 : int axgbe_write_rss_hash_key(struct axgbe_port *pdata)
836 : : {
837 : : struct rte_eth_rss_conf *rss_conf;
838 : : unsigned int key_regs = sizeof(pdata->rss_key) / sizeof(u32);
839 : : unsigned int *key;
840 : : int ret;
841 : :
842 : 0 : rss_conf = &pdata->eth_dev->data->dev_conf.rx_adv_conf.rss_conf;
843 : :
844 [ # # ]: 0 : if (!rss_conf->rss_key)
845 : 0 : key = (unsigned int *)&pdata->rss_key;
846 : : else
847 : 0 : key = (unsigned int *)&rss_conf->rss_key;
848 : :
849 [ # # ]: 0 : while (key_regs--) {
850 : 0 : ret = axgbe_write_rss_reg(pdata, AXGBE_RSS_HASH_KEY_TYPE,
851 : 0 : key_regs, *key++);
852 [ # # ]: 0 : if (ret)
853 : 0 : return ret;
854 : : }
855 : :
856 : : return 0;
857 : : }
858 : :
859 : 0 : int axgbe_write_rss_lookup_table(struct axgbe_port *pdata)
860 : : {
861 : : unsigned int i;
862 : : int ret;
863 : :
864 [ # # ]: 0 : for (i = 0; i < ARRAY_SIZE(pdata->rss_table); i++) {
865 : 0 : ret = axgbe_write_rss_reg(pdata,
866 : : AXGBE_RSS_LOOKUP_TABLE_TYPE, i,
867 : : pdata->rss_table[i]);
868 [ # # ]: 0 : if (ret)
869 : 0 : return ret;
870 : : }
871 : :
872 : : return 0;
873 : : }
874 : :
875 : 0 : static int axgbe_enable_rss(struct axgbe_port *pdata)
876 : : {
877 : : int ret;
878 : :
879 : : /* Program the hash key */
880 : 0 : ret = axgbe_write_rss_hash_key(pdata);
881 [ # # ]: 0 : if (ret)
882 : : return ret;
883 : :
884 : : /* Program the lookup table */
885 : 0 : ret = axgbe_write_rss_lookup_table(pdata);
886 [ # # ]: 0 : if (ret)
887 : : return ret;
888 : :
889 : : /* Set the RSS options */
890 : 0 : AXGMAC_IOWRITE(pdata, MAC_RSSCR, pdata->rss_options);
891 : :
892 : : /* Enable RSS */
893 : 0 : AXGMAC_IOWRITE_BITS(pdata, MAC_RSSCR, RSSE, 1);
894 : :
895 : 0 : return 0;
896 : : }
897 : :
898 : 0 : static void axgbe_rss_options(struct axgbe_port *pdata)
899 : : {
900 : : struct rte_eth_rss_conf *rss_conf;
901 : : uint64_t rss_hf;
902 : :
903 : 0 : rss_conf = &pdata->eth_dev->data->dev_conf.rx_adv_conf.rss_conf;
904 : 0 : pdata->rss_hf = rss_conf->rss_hf;
905 : : rss_hf = rss_conf->rss_hf;
906 : :
907 [ # # ]: 0 : if (rss_hf & (RTE_ETH_RSS_IPV4 | RTE_ETH_RSS_IPV6))
908 : 0 : AXGMAC_SET_BITS(pdata->rss_options, MAC_RSSCR, IP2TE, 1);
909 [ # # ]: 0 : if (rss_hf & (RTE_ETH_RSS_NONFRAG_IPV4_TCP | RTE_ETH_RSS_NONFRAG_IPV6_TCP))
910 : 0 : AXGMAC_SET_BITS(pdata->rss_options, MAC_RSSCR, TCP4TE, 1);
911 [ # # ]: 0 : if (rss_hf & (RTE_ETH_RSS_NONFRAG_IPV4_UDP | RTE_ETH_RSS_NONFRAG_IPV6_UDP))
912 : 0 : AXGMAC_SET_BITS(pdata->rss_options, MAC_RSSCR, UDP4TE, 1);
913 : 0 : }
914 : :
915 : 0 : static int axgbe_config_rss(struct axgbe_port *pdata)
916 : : {
917 : : uint32_t i;
918 : :
919 [ # # ]: 0 : if (pdata->rss_enable) {
920 : : /* Initialize RSS hash key and lookup table */
921 : 0 : uint32_t *key = (uint32_t *)pdata->rss_key;
922 : :
923 [ # # ]: 0 : for (i = 0; i < sizeof(pdata->rss_key) / 4; i++)
924 : 0 : *key++ = (uint32_t)rte_rand();
925 [ # # ]: 0 : for (i = 0; i < AXGBE_RSS_MAX_TABLE_SIZE; i++)
926 : 0 : AXGMAC_SET_BITS(pdata->rss_table[i], MAC_RSSDR, DMCH,
927 : : i % pdata->eth_dev->data->nb_rx_queues);
928 : 0 : axgbe_rss_options(pdata);
929 [ # # ]: 0 : if (axgbe_enable_rss(pdata)) {
930 : 0 : PMD_DRV_LOG_LINE(ERR, "Error in enabling RSS support");
931 : 0 : return -1;
932 : : }
933 : : } else {
934 : 0 : AXGMAC_IOWRITE_BITS(pdata, MAC_RSSCR, RSSE, 0);
935 : : }
936 : :
937 : : return 0;
938 : : }
939 : :
940 : 0 : static void axgbe_enable_dma_interrupts(struct axgbe_port *pdata)
941 : : {
942 : : struct axgbe_tx_queue *txq;
943 : : unsigned int dma_ch_isr, dma_ch_ier;
944 : : unsigned int i;
945 : :
946 [ # # ]: 0 : for (i = 0; i < pdata->eth_dev->data->nb_tx_queues; i++) {
947 : 0 : txq = pdata->eth_dev->data->tx_queues[i];
948 : :
949 : : /* Clear all the interrupts which are set */
950 : 0 : dma_ch_isr = AXGMAC_DMA_IOREAD(txq, DMA_CH_SR);
951 : 0 : AXGMAC_DMA_IOWRITE(txq, DMA_CH_SR, dma_ch_isr);
952 : :
953 : : /* Clear all interrupt enable bits */
954 : : dma_ch_ier = 0;
955 : :
956 : : /* Enable following interrupts
957 : : * NIE - Normal Interrupt Summary Enable
958 : : * AIE - Abnormal Interrupt Summary Enable
959 : : * FBEE - Fatal Bus Error Enable
960 : : */
961 : : AXGMAC_SET_BITS(dma_ch_ier, DMA_CH_IER, NIE, 0);
962 : : AXGMAC_SET_BITS(dma_ch_ier, DMA_CH_IER, AIE, 1);
963 : : AXGMAC_SET_BITS(dma_ch_ier, DMA_CH_IER, FBEE, 1);
964 : :
965 : : /* Enable following Rx interrupts
966 : : * RBUE - Receive Buffer Unavailable Enable
967 : : * RIE - Receive Interrupt Enable (unless using
968 : : * per channel interrupts in edge triggered
969 : : * mode)
970 : : */
971 : : AXGMAC_SET_BITS(dma_ch_ier, DMA_CH_IER, RBUE, 0);
972 : :
973 : 0 : AXGMAC_DMA_IOWRITE(txq, DMA_CH_IER, dma_ch_ier);
974 : : }
975 : 0 : }
976 : :
977 : 0 : static void wrapper_tx_desc_init(struct axgbe_port *pdata)
978 : : {
979 : : struct axgbe_tx_queue *txq;
980 : : unsigned int i;
981 : :
982 [ # # ]: 0 : for (i = 0; i < pdata->eth_dev->data->nb_tx_queues; i++) {
983 : 0 : txq = pdata->eth_dev->data->tx_queues[i];
984 : 0 : txq->cur = 0;
985 : 0 : txq->dirty = 0;
986 : : /* Update the total number of Tx descriptors */
987 : 0 : AXGMAC_DMA_IOWRITE(txq, DMA_CH_TDRLR, txq->nb_desc - 1);
988 : : /* Update the starting address of descriptor ring */
989 : 0 : AXGMAC_DMA_IOWRITE(txq, DMA_CH_TDLR_HI,
990 : : high32_value(txq->ring_phys_addr));
991 : 0 : AXGMAC_DMA_IOWRITE(txq, DMA_CH_TDLR_LO,
992 : : low32_value(txq->ring_phys_addr));
993 : : }
994 : 0 : }
995 : :
996 : 0 : static int wrapper_rx_desc_init(struct axgbe_port *pdata)
997 : : {
998 : : struct axgbe_rx_queue *rxq;
999 : : struct rte_mbuf *mbuf;
1000 : : volatile union axgbe_rx_desc *desc;
1001 : : unsigned int i, j;
1002 : :
1003 [ # # ]: 0 : for (i = 0; i < pdata->eth_dev->data->nb_rx_queues; i++) {
1004 : 0 : rxq = pdata->eth_dev->data->rx_queues[i];
1005 : :
1006 : : /* Initialize software ring entries */
1007 : 0 : rxq->mbuf_alloc = 0;
1008 : 0 : rxq->cur = 0;
1009 : 0 : rxq->dirty = 0;
1010 : 0 : desc = AXGBE_GET_DESC_PT(rxq, 0);
1011 : :
1012 [ # # ]: 0 : for (j = 0; j < rxq->nb_desc; j++) {
1013 : 0 : mbuf = rte_mbuf_raw_alloc(rxq->mb_pool);
1014 [ # # ]: 0 : if (mbuf == NULL) {
1015 : 0 : PMD_DRV_LOG_LINE(ERR, "RX mbuf alloc failed queue_id = %u, idx = %d",
1016 : : (unsigned int)rxq->queue_id, j);
1017 : 0 : axgbe_dev_rx_queue_release(pdata->eth_dev, i);
1018 : 0 : return -ENOMEM;
1019 : : }
1020 : 0 : rxq->sw_ring[j] = mbuf;
1021 : : /* Mbuf populate */
1022 : 0 : mbuf->next = NULL;
1023 : 0 : mbuf->data_off = RTE_PKTMBUF_HEADROOM;
1024 : 0 : mbuf->nb_segs = 1;
1025 : 0 : mbuf->port = rxq->port_id;
1026 : 0 : desc->read.baddr =
1027 : : rte_cpu_to_le_64(
1028 : : rte_mbuf_data_iova_default(mbuf));
1029 : : rte_wmb();
1030 : 0 : AXGMAC_SET_BITS_LE(desc->read.desc3,
1031 : : RX_NORMAL_DESC3, OWN, 1);
1032 : : rte_wmb();
1033 : 0 : rxq->mbuf_alloc++;
1034 : 0 : desc++;
1035 : : }
1036 : : /* Update the total number of Rx descriptors */
1037 : 0 : AXGMAC_DMA_IOWRITE(rxq, DMA_CH_RDRLR,
1038 : : rxq->nb_desc - 1);
1039 : : /* Update the starting address of descriptor ring */
1040 : 0 : AXGMAC_DMA_IOWRITE(rxq, DMA_CH_RDLR_HI,
1041 : : high32_value(rxq->ring_phys_addr));
1042 : 0 : AXGMAC_DMA_IOWRITE(rxq, DMA_CH_RDLR_LO,
1043 : : low32_value(rxq->ring_phys_addr));
1044 : : /* Update the Rx Descriptor Tail Pointer */
1045 : 0 : AXGMAC_DMA_IOWRITE(rxq, DMA_CH_RDTR_LO,
1046 : : low32_value(rxq->ring_phys_addr +
1047 : : (rxq->nb_desc - 1) *
1048 : : sizeof(union axgbe_rx_desc)));
1049 : : }
1050 : : return 0;
1051 : : }
1052 : :
1053 : 0 : static void axgbe_config_mtl_mode(struct axgbe_port *pdata)
1054 : : {
1055 : : unsigned int i;
1056 : :
1057 : : /* Set Tx to weighted round robin scheduling algorithm */
1058 : 0 : AXGMAC_IOWRITE_BITS(pdata, MTL_OMR, ETSALG, MTL_ETSALG_WRR);
1059 : :
1060 : : /* Set Tx traffic classes to use WRR algorithm with equal weights */
1061 [ # # ]: 0 : for (i = 0; i < pdata->hw_feat.tc_cnt; i++) {
1062 : 0 : AXGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_TC_ETSCR, TSA,
1063 : : MTL_TSA_ETS);
1064 : 0 : AXGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_TC_QWR, QW, 1);
1065 : : }
1066 : :
1067 : : /* Set Rx to strict priority algorithm */
1068 : 0 : AXGMAC_IOWRITE_BITS(pdata, MTL_OMR, RAA, MTL_RAA_SP);
1069 : 0 : }
1070 : :
1071 : : static int axgbe_config_tsf_mode(struct axgbe_port *pdata, unsigned int val)
1072 : : {
1073 : : unsigned int i;
1074 : :
1075 [ # # ]: 0 : for (i = 0; i < pdata->tx_q_count; i++)
1076 : 0 : AXGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_Q_TQOMR, TSF, val);
1077 : :
1078 : : return 0;
1079 : : }
1080 : :
1081 : : static int axgbe_config_rsf_mode(struct axgbe_port *pdata, unsigned int val)
1082 : : {
1083 : : unsigned int i;
1084 : :
1085 [ # # ]: 0 : for (i = 0; i < pdata->rx_q_count; i++)
1086 : 0 : AXGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_Q_RQOMR, RSF, val);
1087 : :
1088 : : return 0;
1089 : : }
1090 : :
1091 : : static int axgbe_config_tx_threshold(struct axgbe_port *pdata,
1092 : : unsigned int val)
1093 : : {
1094 : : unsigned int i;
1095 : :
1096 [ # # ]: 0 : for (i = 0; i < pdata->tx_q_count; i++)
1097 : 0 : AXGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_Q_TQOMR, TTC, val);
1098 : :
1099 : : return 0;
1100 : : }
1101 : :
1102 : : static int axgbe_config_rx_threshold(struct axgbe_port *pdata,
1103 : : unsigned int val)
1104 : : {
1105 : : unsigned int i;
1106 : :
1107 [ # # ]: 0 : for (i = 0; i < pdata->rx_q_count; i++)
1108 : 0 : AXGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_Q_RQOMR, RTC, val);
1109 : :
1110 : : return 0;
1111 : : }
1112 : :
1113 : : /* Distributing FIFO size */
1114 : 0 : static void axgbe_config_rx_fifo_size(struct axgbe_port *pdata)
1115 : : {
1116 : : unsigned int fifo_size;
1117 : : unsigned int q_fifo_size;
1118 : : unsigned int p_fifo, i;
1119 : :
1120 : 0 : fifo_size = RTE_MIN(pdata->rx_max_fifo_size,
1121 : : pdata->hw_feat.rx_fifo_size);
1122 : 0 : q_fifo_size = fifo_size / pdata->rx_q_count;
1123 : :
1124 : : /* Calculate the fifo setting by dividing the queue's fifo size
1125 : : * by the fifo allocation increment (with 0 representing the
1126 : : * base allocation increment so decrement the result
1127 : : * by 1).
1128 : : */
1129 : 0 : p_fifo = q_fifo_size / AXGMAC_FIFO_UNIT;
1130 [ # # ]: 0 : if (p_fifo)
1131 : 0 : p_fifo--;
1132 : :
1133 [ # # ]: 0 : for (i = 0; i < pdata->rx_q_count; i++)
1134 : 0 : AXGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_Q_RQOMR, RQS, p_fifo);
1135 : 0 : pdata->fifo = p_fifo;
1136 : :
1137 : : /*Calculate and config Flow control threshold*/
1138 : 0 : axgbe_calculate_flow_control_threshold(pdata);
1139 : 0 : axgbe_config_flow_control_threshold(pdata);
1140 : :
1141 : 0 : PMD_DRV_LOG_LINE(DEBUG, "%d Rx hardware queues, %d byte fifo per queue",
1142 : : pdata->rx_q_count, q_fifo_size);
1143 : 0 : }
1144 : :
1145 : 0 : static void axgbe_config_tx_fifo_size(struct axgbe_port *pdata)
1146 : : {
1147 : : unsigned int fifo_size;
1148 : : unsigned int q_fifo_size;
1149 : : unsigned int p_fifo, i;
1150 : :
1151 : 0 : fifo_size = RTE_MIN(pdata->tx_max_fifo_size,
1152 : : pdata->hw_feat.tx_fifo_size);
1153 : 0 : q_fifo_size = fifo_size / pdata->tx_q_count;
1154 : :
1155 : : /* Calculate the fifo setting by dividing the queue's fifo size
1156 : : * by the fifo allocation increment (with 0 representing the
1157 : : * base allocation increment so decrement the result
1158 : : * by 1).
1159 : : */
1160 : 0 : p_fifo = q_fifo_size / AXGMAC_FIFO_UNIT;
1161 [ # # ]: 0 : if (p_fifo)
1162 : 0 : p_fifo--;
1163 : :
1164 [ # # ]: 0 : for (i = 0; i < pdata->tx_q_count; i++)
1165 : 0 : AXGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_Q_TQOMR, TQS, p_fifo);
1166 : :
1167 : 0 : PMD_DRV_LOG_LINE(DEBUG, "%d Tx hardware queues, %d byte fifo per queue",
1168 : : pdata->tx_q_count, q_fifo_size);
1169 : 0 : }
1170 : :
1171 : 0 : static void axgbe_config_queue_mapping(struct axgbe_port *pdata)
1172 : : {
1173 : : unsigned int qptc, qptc_extra, queue;
1174 : : unsigned int i, j, reg, reg_val;
1175 : :
1176 : : /* Map the MTL Tx Queues to Traffic Classes
1177 : : * Note: Tx Queues >= Traffic Classes
1178 : : */
1179 : 0 : qptc = pdata->tx_q_count / pdata->hw_feat.tc_cnt;
1180 : 0 : qptc_extra = pdata->tx_q_count % pdata->hw_feat.tc_cnt;
1181 : :
1182 [ # # ]: 0 : for (i = 0, queue = 0; i < pdata->hw_feat.tc_cnt; i++) {
1183 [ # # ]: 0 : for (j = 0; j < qptc; j++) {
1184 : 0 : PMD_DRV_LOG_LINE(DEBUG, "TXq%u mapped to TC%u", queue, i);
1185 : 0 : AXGMAC_MTL_IOWRITE_BITS(pdata, queue, MTL_Q_TQOMR,
1186 : : Q2TCMAP, i);
1187 : : }
1188 [ # # ]: 0 : if (i < qptc_extra) {
1189 : 0 : PMD_DRV_LOG_LINE(DEBUG, "TXq%u mapped to TC%u", queue, i);
1190 : 0 : AXGMAC_MTL_IOWRITE_BITS(pdata, queue, MTL_Q_TQOMR,
1191 : : Q2TCMAP, i);
1192 : : }
1193 : : }
1194 : :
1195 [ # # ]: 0 : if (pdata->rss_enable) {
1196 : : /* Select dynamic mapping of MTL Rx queue to DMA Rx channel */
1197 : : reg = MTL_RQDCM0R;
1198 : : reg_val = 0;
1199 [ # # ]: 0 : for (i = 0; i < pdata->rx_q_count;) {
1200 : 0 : reg_val |= (0x80 << ((i++ % MTL_RQDCM_Q_PER_REG) << 3));
1201 : :
1202 [ # # # # ]: 0 : if ((i % MTL_RQDCM_Q_PER_REG) &&
1203 : : (i != pdata->rx_q_count))
1204 : 0 : continue;
1205 : :
1206 : 0 : AXGMAC_IOWRITE(pdata, reg, reg_val);
1207 : :
1208 : 0 : reg += MTL_RQDCM_INC;
1209 : : reg_val = 0;
1210 : : }
1211 : : }
1212 : 0 : }
1213 : :
1214 : 0 : static void axgbe_enable_mtl_interrupts(struct axgbe_port *pdata)
1215 : : {
1216 : : unsigned int mtl_q_isr;
1217 : : unsigned int q_count, i;
1218 : :
1219 : 0 : q_count = RTE_MAX(pdata->hw_feat.tx_q_cnt, pdata->hw_feat.rx_q_cnt);
1220 [ # # ]: 0 : for (i = 0; i < q_count; i++) {
1221 : : /* Clear all the interrupts which are set */
1222 : 0 : mtl_q_isr = AXGMAC_MTL_IOREAD(pdata, i, MTL_Q_ISR);
1223 : 0 : AXGMAC_MTL_IOWRITE(pdata, i, MTL_Q_ISR, mtl_q_isr);
1224 : :
1225 : : /* No MTL interrupts to be enabled */
1226 : 0 : AXGMAC_MTL_IOWRITE(pdata, i, MTL_Q_IER, 0);
1227 : : }
1228 : 0 : }
1229 : :
1230 : : static uint32_t crc32_le(uint32_t crc, uint8_t *p, uint32_t len)
1231 : : {
1232 : : int i;
1233 [ # # ]: 0 : while (len--) {
1234 : 0 : crc ^= *p++;
1235 [ # # ]: 0 : for (i = 0; i < 8; i++)
1236 [ # # ]: 0 : crc = (crc >> 1) ^ ((crc & 1) ? 0xedb88320 : 0);
1237 : : }
1238 : : return crc;
1239 : : }
1240 : :
1241 : 0 : void axgbe_set_mac_hash_table(struct axgbe_port *pdata, u8 *addr, bool add)
1242 : : {
1243 : : uint32_t crc, htable_index, htable_bitmask;
1244 : :
1245 : 0 : crc = bitrev32(~crc32_le(~0, addr, RTE_ETHER_ADDR_LEN));
1246 : 0 : crc >>= pdata->hash_table_shift;
1247 : 0 : htable_index = crc >> 5;
1248 : 0 : htable_bitmask = 1 << (crc & 0x1f);
1249 : :
1250 [ # # ]: 0 : if (add) {
1251 : 0 : pdata->uc_hash_table[htable_index] |= htable_bitmask;
1252 : 0 : pdata->uc_hash_mac_addr++;
1253 : : } else {
1254 : 0 : pdata->uc_hash_table[htable_index] &= ~htable_bitmask;
1255 : 0 : pdata->uc_hash_mac_addr--;
1256 : : }
1257 [ # # ]: 0 : PMD_DRV_LOG_LINE(DEBUG, "%s MAC hash table Bit %d at Index %#x",
1258 : : add ? "set" : "clear", (crc & 0x1f), htable_index);
1259 : :
1260 : 0 : AXGMAC_IOWRITE(pdata, MAC_HTR(htable_index),
1261 : : pdata->uc_hash_table[htable_index]);
1262 : 0 : }
1263 : :
1264 : 0 : void axgbe_set_mac_addn_addr(struct axgbe_port *pdata, u8 *addr, uint32_t index)
1265 : : {
1266 : : unsigned int mac_addr_hi, mac_addr_lo;
1267 : : u8 *mac_addr;
1268 : :
1269 : 0 : mac_addr_lo = 0;
1270 : 0 : mac_addr_hi = 0;
1271 : :
1272 [ # # ]: 0 : if (addr) {
1273 : : mac_addr = (u8 *)&mac_addr_lo;
1274 : 0 : mac_addr[0] = addr[0];
1275 : 0 : mac_addr[1] = addr[1];
1276 : 0 : mac_addr[2] = addr[2];
1277 : 0 : mac_addr[3] = addr[3];
1278 : : mac_addr = (u8 *)&mac_addr_hi;
1279 : 0 : mac_addr[0] = addr[4];
1280 : 0 : mac_addr[1] = addr[5];
1281 : :
1282 : : /*Address Enable: Use this Addr for Perfect Filtering */
1283 : 0 : AXGMAC_SET_BITS(mac_addr_hi, MAC_MACA1HR, AE, 1);
1284 : : }
1285 : :
1286 [ # # ]: 0 : PMD_DRV_LOG_LINE(DEBUG, "%s mac address at %#x",
1287 : : addr ? "set" : "clear", index);
1288 : :
1289 : 0 : AXGMAC_IOWRITE(pdata, MAC_MACAHR(index), mac_addr_hi);
1290 : 0 : AXGMAC_IOWRITE(pdata, MAC_MACALR(index), mac_addr_lo);
1291 : 0 : }
1292 : :
1293 : : static int axgbe_set_mac_address(struct axgbe_port *pdata, u8 *addr)
1294 : : {
1295 : : unsigned int mac_addr_hi, mac_addr_lo;
1296 : :
1297 : 0 : mac_addr_hi = (addr[5] << 8) | (addr[4] << 0);
1298 : 0 : mac_addr_lo = (addr[3] << 24) | (addr[2] << 16) |
1299 : 0 : (addr[1] << 8) | (addr[0] << 0);
1300 : :
1301 : 0 : AXGMAC_IOWRITE(pdata, MAC_MACA0HR, mac_addr_hi);
1302 : 0 : AXGMAC_IOWRITE(pdata, MAC_MACA0LR, mac_addr_lo);
1303 : :
1304 : : return 0;
1305 : : }
1306 : :
1307 : 0 : static void axgbe_config_mac_hash_table(struct axgbe_port *pdata)
1308 : : {
1309 : : struct axgbe_hw_features *hw_feat = &pdata->hw_feat;
1310 : :
1311 : 0 : pdata->hash_table_shift = 0;
1312 : 0 : pdata->hash_table_count = 0;
1313 : 0 : pdata->uc_hash_mac_addr = 0;
1314 [ # # ]: 0 : memset(pdata->uc_hash_table, 0, sizeof(pdata->uc_hash_table));
1315 : :
1316 [ # # ]: 0 : if (hw_feat->hash_table_size) {
1317 : 0 : pdata->hash_table_shift = 26 - (hw_feat->hash_table_size >> 7);
1318 : 0 : pdata->hash_table_count = hw_feat->hash_table_size / 32;
1319 : : }
1320 : 0 : }
1321 : :
1322 : : static void axgbe_config_mac_address(struct axgbe_port *pdata)
1323 : : {
1324 : : axgbe_set_mac_address(pdata, pdata->mac_addr.addr_bytes);
1325 : : }
1326 : :
1327 : : static void axgbe_config_jumbo_enable(struct axgbe_port *pdata)
1328 : : {
1329 : : unsigned int val;
1330 : :
1331 : 0 : val = (pdata->rx_buf_size > AXGMAC_STD_PACKET_MTU) ? 1 : 0;
1332 : :
1333 : 0 : AXGMAC_IOWRITE_BITS(pdata, MAC_RCR, JE, val);
1334 : : }
1335 : :
1336 : : static void axgbe_config_mac_speed(struct axgbe_port *pdata)
1337 : : {
1338 : 0 : axgbe_set_speed(pdata, pdata->phy_speed);
1339 : : }
1340 : :
1341 : : static void axgbe_config_checksum_offload(struct axgbe_port *pdata)
1342 : : {
1343 [ # # ]: 0 : if (pdata->rx_csum_enable)
1344 : 0 : AXGMAC_IOWRITE_BITS(pdata, MAC_RCR, IPC, 1);
1345 : : else
1346 : 0 : AXGMAC_IOWRITE_BITS(pdata, MAC_RCR, IPC, 0);
1347 : : }
1348 : :
1349 : 0 : static void axgbe_config_mmc(struct axgbe_port *pdata)
1350 : : {
1351 : 0 : struct axgbe_mmc_stats *stats = &pdata->mmc_stats;
1352 : :
1353 : : /* Reset stats */
1354 : : memset(stats, 0, sizeof(*stats));
1355 : :
1356 : : /* Set counters to reset on read */
1357 : 0 : AXGMAC_IOWRITE_BITS(pdata, MMC_CR, ROR, 1);
1358 : :
1359 : : /* Reset the counters */
1360 : 0 : AXGMAC_IOWRITE_BITS(pdata, MMC_CR, CR, 1);
1361 : 0 : }
1362 : :
1363 : 0 : static int axgbe_init(struct axgbe_port *pdata)
1364 : : {
1365 : : int ret;
1366 : :
1367 : : /* Flush Tx queues */
1368 : 0 : ret = axgbe_flush_tx_queues(pdata);
1369 [ # # ]: 0 : if (ret)
1370 : : return ret;
1371 : : /* Initialize DMA related features */
1372 : 0 : axgbe_config_dma_bus(pdata);
1373 : : axgbe_config_dma_cache(pdata);
1374 : : axgbe_config_edma_control(pdata);
1375 : 0 : axgbe_config_osp_mode(pdata);
1376 : 0 : axgbe_config_pblx8(pdata);
1377 : 0 : axgbe_config_tx_pbl_val(pdata);
1378 : 0 : axgbe_config_rx_pbl_val(pdata);
1379 : 0 : axgbe_config_rx_buffer_size(pdata);
1380 : 0 : axgbe_config_rss(pdata);
1381 : 0 : wrapper_tx_desc_init(pdata);
1382 : 0 : ret = wrapper_rx_desc_init(pdata);
1383 [ # # ]: 0 : if (ret)
1384 : : return ret;
1385 : 0 : axgbe_enable_dma_interrupts(pdata);
1386 : :
1387 : : /* Initialize MTL related features */
1388 : 0 : axgbe_config_mtl_mode(pdata);
1389 : 0 : axgbe_config_queue_mapping(pdata);
1390 : 0 : axgbe_config_tsf_mode(pdata, pdata->tx_sf_mode);
1391 : 0 : axgbe_config_rsf_mode(pdata, pdata->rx_sf_mode);
1392 : 0 : axgbe_config_tx_threshold(pdata, pdata->tx_threshold);
1393 : 0 : axgbe_config_rx_threshold(pdata, pdata->rx_threshold);
1394 : 0 : axgbe_config_tx_fifo_size(pdata);
1395 : 0 : axgbe_config_rx_fifo_size(pdata);
1396 : :
1397 : 0 : axgbe_enable_mtl_interrupts(pdata);
1398 : :
1399 : : /* Initialize MAC related features */
1400 : 0 : axgbe_config_mac_hash_table(pdata);
1401 : : axgbe_config_mac_address(pdata);
1402 : : axgbe_config_jumbo_enable(pdata);
1403 : 0 : axgbe_config_flow_control(pdata);
1404 : : axgbe_config_mac_speed(pdata);
1405 : : axgbe_config_checksum_offload(pdata);
1406 : 0 : axgbe_config_mmc(pdata);
1407 : :
1408 : 0 : return 0;
1409 : : }
1410 : :
1411 : 0 : void axgbe_init_function_ptrs_dev(struct axgbe_hw_if *hw_if)
1412 : : {
1413 : 0 : hw_if->exit = axgbe_exit;
1414 : 0 : hw_if->config_flow_control = axgbe_config_flow_control;
1415 : :
1416 : 0 : hw_if->init = axgbe_init;
1417 : :
1418 : 0 : hw_if->read_mmd_regs = axgbe_read_mmd_regs;
1419 : 0 : hw_if->write_mmd_regs = axgbe_write_mmd_regs;
1420 : :
1421 : 0 : hw_if->set_speed = axgbe_set_speed;
1422 : :
1423 : 0 : hw_if->set_ext_mii_mode = axgbe_set_ext_mii_mode;
1424 : 0 : hw_if->read_ext_mii_regs_c22 = axgbe_read_ext_mii_regs_c22;
1425 : 0 : hw_if->write_ext_mii_regs_c22 = axgbe_write_ext_mii_regs_c22;
1426 : 0 : hw_if->read_ext_mii_regs_c45 = axgbe_read_ext_mii_regs_c45;
1427 : 0 : hw_if->write_ext_mii_regs_c45 = axgbe_write_ext_mii_regs_c45;
1428 : :
1429 : : /* For FLOW ctrl */
1430 : 0 : hw_if->config_tx_flow_control = axgbe_config_tx_flow_control;
1431 : 0 : hw_if->config_rx_flow_control = axgbe_config_rx_flow_control;
1432 : :
1433 : : /*vlan*/
1434 : 0 : hw_if->enable_rx_vlan_stripping = axgbe_enable_rx_vlan_stripping;
1435 : 0 : hw_if->disable_rx_vlan_stripping = axgbe_disable_rx_vlan_stripping;
1436 : 0 : hw_if->enable_rx_vlan_filtering = axgbe_enable_rx_vlan_filtering;
1437 : 0 : hw_if->disable_rx_vlan_filtering = axgbe_disable_rx_vlan_filtering;
1438 : 0 : hw_if->update_vlan_hash_table = axgbe_update_vlan_hash_table;
1439 : 0 : }
|