1 /*
2 * aQuantia Corporation Network Driver
3 * Copyright (C) 2014-2017 aQuantia Corporation. All rights reserved
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * (1) Redistributions of source code must retain the above
10 * copyright notice, this list of conditions and the following
11 * disclaimer.
12 *
13 * (2) Redistributions in binary form must reproduce the above
14 * copyright notice, this list of conditions and the following
15 * disclaimer in the documentation and/or other materials provided
16 * with the distribution.
17 *
18 * (3)The name of the author may not be used to endorse or promote
19 * products derived from this software without specific prior
20 * written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
23 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
24 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
26 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
28 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
30 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 */
34
35 #include <sys/param.h>
36 #include <sys/systm.h>
37 #include <sys/endian.h>
38 #include <sys/socket.h>
39 #include <machine/cpu.h>
40 #include <net/rss_config.h>
41
42 #include "aq_hw.h"
43 #include "aq2_hw.h"
44 #include "aq_dbg.h"
45 #include "aq_hw_llh.h"
46 #include "aq_fw.h"
47
48 #define AQ_HW_FW_SM_RAM 0x2U
49 #define AQ_CFG_FW_MIN_VER_EXPECTED 0x01050006U
50
51 static uint32_t aq_hw_active_tcs(struct aq_hw *hw);
52
53 int
aq_hw_err_from_flags(struct aq_hw * hw)54 aq_hw_err_from_flags(struct aq_hw *hw)
55 {
56 if (atomic_load_acq_long(&hw->flags) & AQ_HW_FLAG_ERR_UNPLUG)
57 return (ENXIO);
58 return (0);
59 }
60
61 int
aq_hw_invalidate_descriptor_cache(struct aq_hw * hw)62 aq_hw_invalidate_descriptor_cache(struct aq_hw *hw)
63 {
64 int error;
65
66 /* Atlantic A0 does not implement this stop workaround. */
67 if (IS_CHIP_FEATURE(hw, REVISION_A0))
68 return (0);
69
70 /*
71 * Cached Rx descriptors retain both descriptor and data addresses.
72 * Toggle the global cache invalidation only after every ring is down.
73 */
74 rdm_rx_dma_desc_cache_init_tgl(hw);
75 error = aq_hw_err_from_flags(hw);
76 if (error != 0)
77 return (error);
78
79 error = AQ_HW_WAIT_FOR(rdm_rx_dma_desc_cache_init_done_get(hw) != 0,
80 1000, 10);
81 if (error != 0)
82 return (error);
83 return (aq_hw_err_from_flags(hw));
84 }
85
86 inline uint32_t
aq_hw_read_reg(struct aq_hw * hw,uint32_t reg)87 aq_hw_read_reg(struct aq_hw *hw, uint32_t reg)
88 {
89 uint32_t val = le32toh(bus_space_read_4(hw->hw_tag, hw->hw_handle, reg));
90
91 if (__predict_false(val == 0xFFFFFFFFU) &&
92 le32toh(bus_space_read_4(hw->hw_tag, hw->hw_handle, 0x10)) ==
93 0xFFFFFFFFU)
94 atomic_set_rel_long(&hw->flags, AQ_HW_FLAG_ERR_UNPLUG);
95
96 return (val);
97 }
98
99 static void
aq_hw_chip_features_init(struct aq_hw * hw,uint32_t * p)100 aq_hw_chip_features_init(struct aq_hw *hw, uint32_t *p)
101 {
102 uint32_t chip_features = 0U;
103 uint32_t val = reg_glb_mif_id_get(hw);
104 uint32_t mif_rev = val & 0xFFU;
105
106 if ((0xFU & mif_rev) == 1U) {
107 chip_features |= AQ_HW_CHIP_REVISION_A0 | AQ_HW_CHIP_MPI_AQ |
108 AQ_HW_CHIP_MIPS;
109 } else if ((0xFU & mif_rev) == 2U) {
110 chip_features |= AQ_HW_CHIP_REVISION_B0 | AQ_HW_CHIP_MPI_AQ |
111 AQ_HW_CHIP_MIPS | AQ_HW_CHIP_TPO2 | AQ_HW_CHIP_RPF2;
112 } else if ((0xFU & mif_rev) == 0xAU) {
113 chip_features |= AQ_HW_CHIP_REVISION_B1 | AQ_HW_CHIP_MPI_AQ |
114 AQ_HW_CHIP_MIPS | AQ_HW_CHIP_TPO2 | AQ_HW_CHIP_RPF2;
115 }
116
117 *p = chip_features;
118 }
119
120 int
aq_hw_fw_downld_dwords(struct aq_hw * hw,uint32_t a,uint32_t * p,uint32_t cnt)121 aq_hw_fw_downld_dwords(struct aq_hw *hw, uint32_t a, uint32_t *p, uint32_t cnt)
122 {
123 int err = 0;
124
125 err = AQ_HW_WAIT_FOR(reg_glb_cpu_sem_get(hw, AQ_HW_FW_SM_RAM) == 1U, 1U,
126 10000U);
127
128 if (err != 0) {
129 bool is_locked;
130
131 reg_glb_cpu_sem_set(hw, 1U, AQ_HW_FW_SM_RAM);
132 is_locked = reg_glb_cpu_sem_get(hw, AQ_HW_FW_SM_RAM);
133 if (!is_locked) {
134 err = ETIMEDOUT;
135 goto err_exit;
136 }
137 err = 0;
138 }
139
140 mif_mcp_up_mailbox_addr_set(hw, a);
141
142 for (++cnt; --cnt && !err;) {
143 mif_mcp_up_mailbox_execute_operation_set(hw, 1);
144
145 if (IS_CHIP_FEATURE(hw, REVISION_B1))
146 err = AQ_HW_WAIT_FOR(a != mif_mcp_up_mailbox_addr_get(hw),
147 1U, 1000U);
148 else
149 err = AQ_HW_WAIT_FOR(!mif_mcp_up_mailbox_busy_get(hw), 1,
150 1000U);
151
152 *(p++) = mif_mcp_up_mailbox_data_get(hw);
153 a += 4;
154 }
155
156 reg_glb_cpu_sem_set(hw, 1U, AQ_HW_FW_SM_RAM);
157
158 err_exit:
159 return (err);
160 }
161
162 int
aq_hw_ver_match(const struct aq_hw_fw_version * ver_expected,const struct aq_hw_fw_version * ver_actual)163 aq_hw_ver_match(const struct aq_hw_fw_version* ver_expected,
164 const struct aq_hw_fw_version* ver_actual)
165 {
166 AQ_DBG_ENTER();
167
168 if (ver_actual->major_version != ver_expected->major_version)
169 return (ver_actual->major_version > ver_expected->major_version);
170 if (ver_actual->minor_version != ver_expected->minor_version)
171 return (ver_actual->minor_version > ver_expected->minor_version);
172 return (ver_actual->build_number >= ver_expected->build_number);
173 }
174
175 static int
aq_hw_init_ucp(struct aq_hw * hw)176 aq_hw_init_ucp(struct aq_hw *hw)
177 {
178 int err = 0;
179 AQ_DBG_ENTER();
180
181 hw->fw_version.raw = 0;
182
183 /* Atlantic 2 uses a different reset/firmware handshake. */
184 if (IS_CHIP_FEATURE(hw, ATLANTIC2))
185 return (aq2_fw_reboot(hw));
186
187 err = aq_fw_reset(hw);
188 if (err != 0) {
189 device_printf(hw->dev, "aq_hw_init_ucp(): F/W reset failed, err %d\n", err);
190 return (err);
191 }
192
193 aq_hw_chip_features_init(hw, &hw->chip_features);
194 err = aq_fw_ops_init(hw);
195 if (err != 0) {
196 device_printf(hw->dev, "could not initialize F/W ops, err %d\n", err);
197 return (err);
198 }
199
200 if (hw->fw_version.major_version == 1) {
201 if (!AQ_READ_REG(hw, 0x370)) {
202 unsigned int rnd = 0;
203 unsigned int ucp_0x370 = 0;
204
205 rnd = arc4random();
206
207 ucp_0x370 = 0x02020202 | (0xFEFEFEFE & rnd);
208 AQ_WRITE_REG(hw, AQ_HW_UCP_0X370_REG, ucp_0x370);
209 }
210
211 reg_glb_cpu_scratch_scp_set(hw, 0, 25);
212 }
213
214 /* check 10 times by 1ms */
215 err = AQ_HW_WAIT_FOR((hw->mbox_addr = AQ_READ_REG(hw, 0x360)) != 0, 400U, 20);
216
217 struct aq_hw_fw_version ver_expected = { .raw = AQ_CFG_FW_MIN_VER_EXPECTED };
218 if (!aq_hw_ver_match(&ver_expected, &hw->fw_version))
219 device_printf(hw->dev, "aq_hw_init_ucp(), wrong FW version: expected:%x actual:%x\n",
220 AQ_CFG_FW_MIN_VER_EXPECTED, hw->fw_version.raw);
221
222 AQ_DBG_EXIT(err);
223 return (err);
224 }
225
226 int
aq_hw_mpi_create(struct aq_hw * hw)227 aq_hw_mpi_create(struct aq_hw *hw)
228 {
229 int err = 0;
230
231 AQ_DBG_ENTER();
232 err = aq_hw_init_ucp(hw);
233 if (err != 0)
234 goto err_exit;
235
236 err_exit:
237 AQ_DBG_EXIT(err);
238 return (err);
239 }
240
241 int
aq_hw_mpi_read_stats(struct aq_hw * hw,struct aq_hw_stats * stats)242 aq_hw_mpi_read_stats(struct aq_hw *hw, struct aq_hw_stats *stats)
243 {
244 int err;
245
246 err = hw->fw_ops->get_stats(hw, stats);
247 if (err != 0)
248 return (err);
249
250 /* No firmware interface reports the RPB drop count; read it directly. */
251 stats->dpc = reg_rx_dma_stat_counter7get(hw);
252
253 /* The LRO counter has no A2 counterpart in any reference driver. */
254 if (!IS_CHIP_FEATURE(hw, ATLANTIC2))
255 stats->cprc = stats_rx_lro_coalesced_pkt_count0_get(hw);
256
257 return (0);
258 }
259
260 static int
aq_hw_mpi_set(struct aq_hw * hw,enum aq_hw_fw_mpi_state state,uint32_t speed)261 aq_hw_mpi_set(struct aq_hw *hw, enum aq_hw_fw_mpi_state state, uint32_t speed)
262 {
263 int err;
264 AQ_DBG_ENTERA("speed %d", speed);
265
266 err = hw->fw_ops->set_mode(hw, state, speed);
267
268 AQ_DBG_EXIT(err);
269 return (err);
270 }
271
272 int
aq_hw_set_link_speed(struct aq_hw * hw,uint32_t speed)273 aq_hw_set_link_speed(struct aq_hw *hw, uint32_t speed)
274 {
275 return aq_hw_mpi_set(hw, MPI_INIT, speed);
276 }
277
278 int
aq_hw_get_link_state(struct aq_hw * hw,uint32_t * link_speed,struct aq_hw_fc_info * fc_neg)279 aq_hw_get_link_state(struct aq_hw *hw, uint32_t *link_speed, struct aq_hw_fc_info *fc_neg)
280 {
281 int err = 0;
282
283
284 enum aq_hw_fw_mpi_state mode;
285 enum aq_fw_link_speed speed = aq_fw_none;
286 enum aq_fw_link_fc fc;
287
288 *link_speed = 0;
289 fc_neg->fc_rx = false;
290 fc_neg->fc_tx = false;
291
292 err = hw->fw_ops->get_mode(hw, &mode, &speed, &fc);
293
294 if (err != 0) {
295 device_printf(hw->dev, "get_mode() failed, err %d\n", err);
296 AQ_DBG_EXIT(err);
297 return (err);
298 }
299 if (mode != MPI_INIT)
300 return (0);
301
302 hw->link_speed = speed; /* remember negotiated rate for interrupt moderation */
303
304 switch (speed) {
305 case aq_fw_10G:
306 *link_speed = 10000U;
307 break;
308 case aq_fw_5G:
309 *link_speed = 5000U;
310 break;
311 case aq_fw_2G5:
312 *link_speed = 2500U;
313 break;
314 case aq_fw_1G:
315 *link_speed = 1000U;
316 break;
317 case aq_fw_100M:
318 *link_speed = 100U;
319 break;
320 case aq_fw_10M:
321 *link_speed = 10U;
322 break;
323 default:
324 *link_speed = 0U;
325 break;
326 }
327
328 fc_neg->fc_rx = !!(fc & aq_fw_fc_ENABLE_RX);
329 fc_neg->fc_tx = !!(fc & aq_fw_fc_ENABLE_TX);
330
331 return (0);
332 }
333
334 int
aq_hw_get_mac_permanent(struct aq_hw * hw,uint8_t * mac)335 aq_hw_get_mac_permanent(struct aq_hw *hw, uint8_t *mac)
336 {
337 int err;
338 AQ_DBG_ENTER();
339
340 err = hw->fw_ops->get_mac_addr(hw, mac);
341 if (err != 0) {
342 /* A transient mailbox failure must not fail the attach. */
343 device_printf(hw->dev, "could not read the MAC address: %d\n",
344 err);
345 memset(mac, 0, ETHER_ADDR_LEN);
346 }
347
348 /* Couldn't get MAC address from HW. Use auto-generated one. */
349 if ((mac[0] & 1) || ((mac[0] | mac[1] | mac[2]) == 0)) {
350 uint16_t rnd;
351 uint32_t h = 0;
352 uint32_t l = 0;
353
354 device_printf(hw->dev,
355 "invalid (multicast/empty) HW MAC %6D; using random\n",
356 mac, ":");
357
358 rnd = arc4random();
359
360 /* chip revision */
361 l = 0xE3000000U | (0xFFFFU & rnd) | (0x00 << 16);
362 h = 0x8001300EU;
363
364 mac[5] = (uint8_t)(0xFFU & l);
365 l >>= 8;
366 mac[4] = (uint8_t)(0xFFU & l);
367 l >>= 8;
368 mac[3] = (uint8_t)(0xFFU & l);
369 l >>= 8;
370 mac[2] = (uint8_t)(0xFFU & l);
371 mac[1] = (uint8_t)(0xFFU & h);
372 h >>= 8;
373 mac[0] = (uint8_t)(0xFFU & h);
374
375 err = 0;
376 }
377
378 AQ_DBG_EXIT(err);
379 return (err);
380 }
381
382 int
aq_hw_deinit(struct aq_hw * hw)383 aq_hw_deinit(struct aq_hw *hw)
384 {
385 AQ_DBG_ENTER();
386 aq_hw_mpi_set(hw, MPI_DEINIT, 0);
387 AQ_DBG_EXIT(0);
388 return (0);
389 }
390
391 int
aq_hw_set_power(struct aq_hw * hw,unsigned int power_state)392 aq_hw_set_power(struct aq_hw *hw, unsigned int power_state)
393 {
394 AQ_DBG_ENTER();
395 aq_hw_mpi_set(hw, MPI_POWER, 0);
396 AQ_DBG_EXIT(0);
397 return (0);
398 }
399
400
401 /* HW NIC functions */
402
403 int
aq_hw_reset(struct aq_hw * hw,bool reboot)404 aq_hw_reset(struct aq_hw *hw, bool reboot)
405 {
406 int err = 0;
407
408 AQ_DBG_ENTER();
409
410 /*
411 * A2 resets by rebooting the MCP; A1 uses the RBL/FLB reset. At attach
412 * aq_hw_mpi_create() has already done this, so the caller passes
413 * reboot=false to skip the (costly, on A2) redundant MCP reboot.
414 */
415 if (reboot) {
416 if (IS_CHIP_FEATURE(hw, ATLANTIC2))
417 err = aq2_fw_reboot(hw);
418 else
419 err = aq_fw_reset(hw);
420 if (err != 0)
421 goto err_exit;
422 }
423
424 itr_irq_reg_res_dis_set(hw, 0);
425 itr_res_irq_set(hw, 1);
426
427 /* check 10 times by 1ms */
428 err = AQ_HW_WAIT_FOR(itr_res_irq_get(hw) == 0, 1000, 10);
429 if (err != 0) {
430 device_printf(hw->dev, "IRQ reset failed: %d\n", err);
431 goto err_exit;
432 }
433
434 err = hw->fw_ops->reset(hw);
435 if (err != 0)
436 goto err_exit;
437
438 err = aq_hw_err_from_flags(hw);
439
440 err_exit:
441 AQ_DBG_EXIT(err);
442 return (err);
443 }
444
445 static int
aq_hw_qos_set(struct aq_hw * hw)446 aq_hw_qos_set(struct aq_hw *hw)
447 {
448 uint32_t tc = 0U;
449 uint32_t buff_size = 0U;
450 uint32_t n_tcs;
451 unsigned int i_priority = 0U;
452 unsigned int i;
453 int err = 0;
454
455 AQ_DBG_ENTER();
456
457 /* TPS Descriptor rate init */
458 tps_tx_pkt_shed_desc_rate_curr_time_res_set(hw, 0x0U);
459 tps_tx_pkt_shed_desc_rate_lim_set(hw, 0xA);
460
461 /* TPS VM init */
462 tps_tx_pkt_shed_desc_vm_arb_mode_set(hw, 0U);
463
464 /* TPS TC credits init */
465 tps_tx_pkt_shed_desc_tc_arb_mode_set(hw, 0U);
466 tps_tx_pkt_shed_data_arb_mode_set(hw, 0U);
467
468 /* One TC per active 8-ring group; share the buffer across them. */
469 n_tcs = aq_hw_active_tcs(hw);
470 buff_size = (IS_CHIP_FEATURE(hw, ATLANTIC2) ?
471 AQ2_HW_TXBUF_MAX : AQ_HW_TXBUF_MAX) / n_tcs;
472
473 for (tc = 0; tc < n_tcs; tc++) {
474 if (IS_CHIP_FEATURE(hw, ATLANTIC2)) {
475 /* Atlantic 2's data-TC credit/weight fields are wider. */
476 AQ_WRITE_REG_BIT(hw, TPS_DATA_TCT_REG(tc),
477 TPS2_DATA_TCT_CREDIT_MAX,
478 TPS2_DATA_TCT_CREDIT_MAX_SHIFT, 0xfff0);
479 AQ_WRITE_REG_BIT(hw, TPS_DATA_TCT_REG(tc),
480 TPS2_DATA_TCT_WEIGHT,
481 TPS2_DATA_TCT_WEIGHT_SHIFT, 0x640);
482 } else {
483 tps_tx_pkt_shed_tc_data_max_credit_set(hw, 0xFFF, tc);
484 tps_tx_pkt_shed_tc_data_weight_set(hw, 0x64, tc);
485 }
486 tps_tx_pkt_shed_desc_tc_max_credit_set(hw, 0x50, tc);
487 tps_tx_pkt_shed_desc_tc_weight_set(hw, 0x1E, tc);
488
489 tpb_tx_pkt_buff_size_per_tc_set(hw, buff_size, tc);
490 tpb_tx_buff_hi_threshold_per_tc_set(hw,
491 AQ_BUF_THRESHOLD(buff_size, 66U), tc);
492 tpb_tx_buff_lo_threshold_per_tc_set(hw,
493 AQ_BUF_THRESHOLD(buff_size, 50U), tc);
494 }
495
496 /* QoS Rx buf size per TC */
497 tc = 0;
498 buff_size = IS_CHIP_FEATURE(hw, ATLANTIC2) ?
499 AQ2_HW_RXBUF_MAX : AQ_HW_RXBUF_MAX;
500
501 rpb_rx_pkt_buff_size_per_tc_set(hw, buff_size, tc);
502 rpb_rx_buff_hi_threshold_per_tc_set(hw,
503 AQ_BUF_THRESHOLD(buff_size, 66U), tc);
504 rpb_rx_buff_lo_threshold_per_tc_set(hw,
505 AQ_BUF_THRESHOLD(buff_size, 50U), tc);
506
507 /* QoS 802.1p priority -> TC mapping */
508 for (i_priority = 8U; i_priority--;)
509 rpf_rpb_user_priority_tc_map_set(hw, i_priority, 0U);
510
511 /* Atlantic 2 ring -> TC map (TC = ring / HW_ATL_B0_RINGS_PER_TC). */
512 if (IS_CHIP_FEATURE(hw, ATLANTIC2)) {
513 AQ_WRITE_REG_BIT(hw, TPB_TX_BUF_REG,
514 TPB_TX_BUF_TC_Q_RAND_MAP_EN,
515 TPB_TX_BUF_TC_Q_RAND_MAP_EN_SHIFT, 1);
516 /* TX packs a byte per ring (4/reg); RX a nibble (8/reg). */
517 for (i = 0; i < HW_ATL_B0_RINGS_MAX / 4; i++)
518 AQ_WRITE_REG(hw, AQ2_TX_Q_TC_MAP_REG(i),
519 (i / 2) * 0x01010101U);
520 for (i = 0; i < HW_ATL_B0_RINGS_MAX / 8; i++)
521 AQ_WRITE_REG(hw, AQ2_RX_Q_TC_MAP_REG(i),
522 i * 0x11111111U);
523 }
524
525 err = aq_hw_err_from_flags(hw);
526 AQ_DBG_EXIT(err);
527 return (err);
528 }
529
530 /* Tx traffic classes currently provisioned (one per active 8-ring group). */
531 static uint32_t
aq_hw_active_tcs(struct aq_hw * hw)532 aq_hw_active_tcs(struct aq_hw *hw)
533 {
534 uint32_t n = howmany(MAX(hw->tx_rings_count, 1U),
535 HW_ATL_B0_RINGS_PER_TC);
536
537 return (MIN(n, HW_ATL_B0_TCS_MAX));
538 }
539
540 static int
aq_hw_offload_set(struct aq_hw * hw)541 aq_hw_offload_set(struct aq_hw *hw)
542 {
543 int err;
544
545 AQ_DBG_ENTER();
546 /* TX checksums offloads*/
547 tpo_ipv4header_crc_offload_en_set(hw, 1);
548 tpo_tcp_udp_crc_offload_en_set(hw, 1);
549
550 /* RX checksums offloads*/
551 rpo_ipv4header_crc_offload_en_set(hw, 1);
552 rpo_tcp_udp_crc_offload_en_set(hw, 1);
553
554 /* LSO offloads*/
555 tdm_large_send_offload_en_set(hw, 0xFFFFFFFFU);
556
557 /* Outer (S-VLAN) tag parse mode */
558 rpo_outer_vlan_tag_mode_set(hw, 1U);
559
560 {
561 uint32_t i = 0;
562 uint32_t val = (8U < HW_ATL_B0_LRO_RXD_MAX) ? 0x3U :
563 ((4U < HW_ATL_B0_LRO_RXD_MAX) ? 0x2U :
564 ((2U < HW_ATL_B0_LRO_RXD_MAX) ? 0x1U : 0x0));
565
566 for (i = 0; i < HW_ATL_B0_RINGS_MAX; i++)
567 rpo_lro_max_num_of_descriptors_set(hw, val, i);
568
569 rpo_lro_time_base_divider_set(hw, 0x61AU);
570 rpo_lro_inactive_interval_set(hw, 0);
571 /* the LRO timebase divider is 5 uS (0x61a),
572 * to get a maximum coalescing interval of 250 uS,
573 * we need to multiply by 50(0x32) to get
574 * the default value 250 uS
575 */
576 rpo_lro_max_coalescing_interval_set(hw, 50);
577
578 rpo_lro_qsessions_lim_set(hw, 1U);
579
580 rpo_lro_total_desc_lim_set(hw, 2U);
581
582 rpo_lro_patch_optimization_en_set(hw, 0U);
583
584 rpo_lro_min_pay_of_first_pkt_set(hw, 10U);
585
586 rpo_lro_pkt_lim_set(hw, 1U);
587
588 rpo_lro_en_set(hw, (hw->lro_enabled ? 0xFFFFFFFFU : 0U));
589 }
590
591
592 err = aq_hw_err_from_flags(hw);
593
594 AQ_DBG_EXIT(err);
595 return (err);
596 }
597
598 static int
aq_hw_init_tx_path(struct aq_hw * hw)599 aq_hw_init_tx_path(struct aq_hw *hw)
600 {
601 int err = 0;
602
603 AQ_DBG_ENTER();
604
605 /* Tx TC/RSS number config */
606 tpb_tx_tc_mode_set(hw, 1U);
607
608 thm_lso_tcp_flag_of_first_pkt_set(hw, 0x0FF6U);
609 thm_lso_tcp_flag_of_middle_pkt_set(hw, 0x0FF6U);
610 thm_lso_tcp_flag_of_last_pkt_set(hw, 0x0F7FU);
611
612 /* Tx interrupts */
613 tdm_tx_desc_wr_wb_irq_en_set(hw, 1U);
614
615 /* misc (Atlantic 1 TPO register; absent on Atlantic 2) */
616 if (!IS_CHIP_FEATURE(hw, ATLANTIC2))
617 AQ_WRITE_REG(hw, 0x00007040U,
618 IS_CHIP_FEATURE(hw, TPO2) ? 0x00010000U : 0x00000000U);
619 tdm_tx_dca_en_set(hw, 0U);
620 tdm_tx_dca_mode_set(hw, 0U);
621
622 tpb_tx_path_scp_ins_en_set(hw, 1U);
623
624 err = aq_hw_err_from_flags(hw);
625 AQ_DBG_EXIT(err);
626 return (err);
627 }
628
629 /* Atlantic 2: install one action-resolver-table row under the ART semaphore. */
630 static int
aq2_art_filter_set(struct aq_hw * hw,uint32_t idx,uint32_t tag,uint32_t mask,uint32_t action)631 aq2_art_filter_set(struct aq_hw *hw, uint32_t idx, uint32_t tag,
632 uint32_t mask, uint32_t action)
633 {
634 idx += hw->art_filter_base_index;
635 if (idx >= AQ2_ART_TABLE_SIZE) {
636 device_printf(hw->dev,
637 "ART index %u out of range (firmware base %u)\n", idx,
638 hw->art_filter_base_index);
639 return (EINVAL);
640 }
641
642 if (AQ_HW_WAIT_FOR(reg_glb_cpu_sem_get(hw, AQ2_ART_SEM_INDEX) == 1U,
643 10U, 1000U) != 0) {
644 device_printf(hw->dev, "ART semaphore timeout, idx %u\n", idx);
645 return (EBUSY);
646 }
647
648 AQ_WRITE_REG(hw, AQ2_RPF_ACT_ART_REQ_TAG_REG(idx), tag);
649 AQ_WRITE_REG(hw, AQ2_RPF_ACT_ART_REQ_MASK_REG(idx), mask);
650 AQ_WRITE_REG(hw, AQ2_RPF_ACT_ART_REQ_ACTION_REG(idx), action);
651
652 reg_glb_cpu_sem_set(hw, 1U, AQ2_ART_SEM_INDEX);
653 return (0);
654 }
655
656 static int
aq_hw_init_rx_path(struct aq_hw * hw)657 aq_hw_init_rx_path(struct aq_hw *hw)
658 {
659 unsigned int control_reg_val = 0U;
660 int i;
661 int err = 0;
662
663 AQ_DBG_ENTER();
664 /* Rx TC/RSS number config */
665 rpb_rpf_rx_traf_class_mode_set(hw, 1U);
666
667 /*
668 * Atlantic 2: program the RSS hash types the kernel honors. UDP is
669 * excluded by default (see aq_rss_hashconfig()); clearing its per-cast
670 * bits keeps fragmented UDP on a single queue without the A1 L3L4
671 * flow-filter workaround.
672 */
673 if (IS_CHIP_FEATURE(hw, ATLANTIC2)) {
674 static const struct {
675 u_int kern;
676 uint32_t hw;
677 } ht_map[] = {
678 { RSS_HASHTYPE_RSS_IPV4, AQ2_RPF_REDIR2_HASHTYPE_IP },
679 { RSS_HASHTYPE_RSS_TCP_IPV4, AQ2_RPF_REDIR2_HASHTYPE_TCP4 },
680 { RSS_HASHTYPE_RSS_UDP_IPV4, AQ2_RPF_REDIR2_HASHTYPE_UDP4 },
681 { RSS_HASHTYPE_RSS_IPV6, AQ2_RPF_REDIR2_HASHTYPE_IP6 },
682 { RSS_HASHTYPE_RSS_TCP_IPV6, AQ2_RPF_REDIR2_HASHTYPE_TCP6 },
683 { RSS_HASHTYPE_RSS_UDP_IPV6, AQ2_RPF_REDIR2_HASHTYPE_UDP6 },
684 { RSS_HASHTYPE_RSS_IPV6_EX, AQ2_RPF_REDIR2_HASHTYPE_IP6EX },
685 { RSS_HASHTYPE_RSS_TCP_IPV6_EX, AQ2_RPF_REDIR2_HASHTYPE_TCP6EX },
686 { RSS_HASHTYPE_RSS_UDP_IPV6_EX, AQ2_RPF_REDIR2_HASHTYPE_UDP6EX },
687 };
688 u_int hc = aq_rss_hashconfig();
689 uint32_t ht = 0;
690
691 for (i = 0; i < (int)nitems(ht_map); i++)
692 if (hc & ht_map[i].kern)
693 ht |= ht_map[i].hw;
694 AQ_WRITE_REG_BIT(hw, AQ2_RPF_REDIR2_REG,
695 AQ2_RPF_REDIR2_HASHTYPE, 0, ht);
696 }
697
698 /* Rx flow control */
699 rpb_rx_flow_ctl_mode_set(hw, 1U);
700
701 /* RSS Ring selection */
702 reg_rx_flr_rss_control1set(hw, 0xB3333333U);
703
704 /* Multicast filters */
705 for (i = AQ_HW_MAC_MAX; i--;) {
706 rpfl2_uc_flr_en_set(hw, (i == 0U) ? 1U : 0U, i);
707 rpfl2unicast_flr_act_set(hw, 1U, i);
708 }
709
710 reg_rx_flr_mcst_flr_msk_set(hw, 0x00000000U);
711 reg_rx_flr_mcst_flr_set(hw, 0x00010FFFU, 0U);
712
713 /* Vlan filters */
714 rpf_vlan_outer_etht_set(hw, 0x88A8U);
715 rpf_vlan_inner_etht_set(hw, 0x8100U);
716 rpf_vlan_accept_untagged_packets_set(hw, true);
717 rpf_vlan_untagged_act_set(hw, HW_ATL_RX_HOST);
718
719 rpf_vlan_prom_mode_en_set(hw, 1);
720
721 /* Rx Interrupts */
722 rdm_rx_desc_wr_wb_irq_en_set(hw, 1U);
723
724 if (IS_CHIP_FEATURE(hw, ATLANTIC2)) {
725 /* Enable the resolver table and tag L2 unicast/broadcast. */
726 AQ_WRITE_REG_BIT(hw, AQ2_RPF_REC_TAB_ENABLE_REG,
727 AQ2_RPF_REC_TAB_ENABLE_MASK, 0, AQ2_RPF_REC_TAB_ENABLE_MASK);
728 AQ_WRITE_REG_BIT(hw, RPF_L2UC_MSW_REG(0),
729 RPF_L2UC_MSW_TAG, RPF_L2UC_MSW_TAG_SHIFT, 1);
730 AQ_WRITE_REG_BIT(hw, AQ2_RPF_L2BC_TAG_REG,
731 AQ2_RPF_L2BC_TAG_MASK, 0, 1);
732
733 /* Drop rows (promisc lifts them); all PCP -> TC 0. */
734 err = aq2_art_filter_set(hw, AQ2_RPF_INDEX_L2_PROMISC_OFF, 0,
735 AQ2_RPF_TAG_UC_MASK | AQ2_RPF_TAG_ALLMC_MASK,
736 AQ2_ART_ACTION_DROP);
737 if (err == 0)
738 err = aq2_art_filter_set(hw,
739 AQ2_RPF_INDEX_VLAN_PROMISC_OFF, 0,
740 AQ2_RPF_TAG_VLAN_MASK | AQ2_RPF_TAG_UNTAG_MASK,
741 AQ2_ART_ACTION_DROP);
742 for (i = 0; err == 0 && i < 8; i++)
743 err = aq2_art_filter_set(hw, AQ2_RPF_INDEX_PCP_TO_TC + i,
744 ((uint32_t)i << AQ2_RPF_TAG_PCP_SHIFT),
745 AQ2_RPF_TAG_PCP_MASK,
746 AQ2_ART_ACTION_ASSIGN_TC(0));
747 } else {
748 /* misc */
749 control_reg_val = 0x000F0000U; //RPF2
750
751 /* RSS hash type set for IP/TCP */
752 control_reg_val |= 0x1EU;
753
754 AQ_WRITE_REG(hw, 0x00005040U, control_reg_val);
755 }
756
757 rpfl2broadcast_en_set(hw, 1U);
758 rpfl2broadcast_flr_act_set(hw, 1U);
759 rpfl2broadcast_count_threshold_set(hw, 0xFFFFU & (~0U / 256U));
760
761 rdm_rx_dca_en_set(hw, 0U);
762 rdm_rx_dca_mode_set(hw, 0U);
763
764 if (err == 0)
765 err = aq_hw_err_from_flags(hw);
766 AQ_DBG_EXIT(err);
767 return (err);
768 }
769
770 int
aq_hw_mac_addr_set(struct aq_hw * hw,uint8_t * mac_addr,uint8_t index)771 aq_hw_mac_addr_set(struct aq_hw *hw, uint8_t *mac_addr, uint8_t index)
772 {
773 int err = 0;
774 unsigned int h = 0U;
775 unsigned int l = 0U;
776
777 AQ_DBG_ENTER();
778 if (!mac_addr) {
779 err = EINVAL;
780 goto err_exit;
781 }
782 if (index >= AQ_HW_MAC_MAX) {
783 err = EINVAL;
784 goto err_exit;
785 }
786 h = (mac_addr[0] << 8) | (mac_addr[1]);
787 l = (mac_addr[2] << 24) | (mac_addr[3] << 16) | (mac_addr[4] << 8) |
788 mac_addr[5];
789
790 rpfl2_uc_flr_en_set(hw, 0U, index);
791 rpfl2unicast_dest_addresslsw_set(hw, l, index);
792 rpfl2unicast_dest_addressmsw_set(hw, h, index);
793 /* Atlantic 2: classify this address into the resolver table. */
794 if (IS_CHIP_FEATURE(hw, ATLANTIC2))
795 AQ_WRITE_REG_BIT(hw, RPF_L2UC_MSW_REG(index),
796 RPF_L2UC_MSW_TAG, RPF_L2UC_MSW_TAG_SHIFT, 1);
797 rpfl2_uc_flr_en_set(hw, 1U, index);
798
799 err = aq_hw_err_from_flags(hw);
800
801 err_exit:
802 AQ_DBG_EXIT(err);
803 return (err);
804 }
805
806 int
aq_hw_init(struct aq_hw * hw,uint8_t * mac_addr,uint8_t adm_irq,bool msix)807 aq_hw_init(struct aq_hw *hw, uint8_t *mac_addr, uint8_t adm_irq, bool msix)
808 {
809
810 int err = 0;
811 uint32_t val = 0;
812
813 AQ_DBG_ENTER();
814
815 /* Atlantic 1 only: clamp MRRS and TX DMA total request limit. */
816 if (!IS_CHIP_FEATURE(hw, ATLANTIC2)) {
817 /* Force limit MRRS on RDM/TDM to 2K */
818 val = AQ_READ_REG(hw, AQ_HW_PCI_REG_CONTROL_6_ADR);
819 AQ_WRITE_REG(hw, AQ_HW_PCI_REG_CONTROL_6_ADR,
820 (val & ~0x707) | 0x404);
821
822 /* TX DMA total request limit. B0 hardware is not capable to
823 * handle more than (8K-MRRS) incoming DMA data.
824 * Value 24 in 256byte units
825 */
826 AQ_WRITE_REG(hw, AQ_HW_TX_DMA_TOTAL_REQ_LIMIT_ADR, 24);
827 } else {
828 /* Atlantic 2: launch-time clock ratio per FPGA version. */
829 uint32_t fpgaver = AQ_READ_REG(hw, AQ2_HW_FPGA_VERSION_REG);
830 uint32_t ratio;
831
832 if (fpgaver < 0x01000000U)
833 ratio = AQ2_LAUNCHTIME_CTRL_RATIO_SPEED_FULL;
834 else if (fpgaver >= 0x01008502U)
835 ratio = AQ2_LAUNCHTIME_CTRL_RATIO_SPEED_HALF;
836 else
837 ratio = AQ2_LAUNCHTIME_CTRL_RATIO_SPEED_QUARTER;
838 AQ_WRITE_REG_BIT(hw, AQ2_LAUNCHTIME_CTRL_REG,
839 AQ2_LAUNCHTIME_CTRL_RATIO, 8, ratio);
840 }
841
842 err = aq_hw_init_tx_path(hw);
843 if (err != 0)
844 goto err_exit;
845 err = aq_hw_init_rx_path(hw);
846 if (err != 0)
847 goto err_exit;
848
849 aq_hw_mac_addr_set(hw, mac_addr, AQ_HW_MAC);
850
851 /* A lost ack must not skip the setup that follows. */
852 err = aq_hw_mpi_set(hw, MPI_INIT, hw->link_rate);
853 if (err != 0)
854 device_printf(hw->dev, "could not set F/W link mode: %d\n", err);
855
856 aq_hw_qos_set(hw);
857
858 /* Atlantic 2: turn on the new RPF / action-resolver engine. */
859 if (IS_CHIP_FEATURE(hw, ATLANTIC2))
860 AQ_WRITE_REG_BIT(hw, AQ2_RPF_NEW_CTRL_REG,
861 AQ2_RPF_NEW_CTRL_ENABLE, 11, 1);
862
863 err = aq_hw_err_from_flags(hw);
864 if (err != 0)
865 goto err_exit;
866
867 /* Interrupts */
868 //Enable interrupt
869 itr_irq_status_cor_en_set(hw, 0); //Disable clear-on-read for status
870 itr_irq_auto_mask_clr_en_set(hw, 1); // Enable auto-mask clear.
871 if (msix)
872 itr_irq_mode_set(hw, 0x6); //MSIX + multi vector
873 else
874 itr_irq_mode_set(hw, 0x5); //MSI + multi vector
875
876 /* Route both hardware error causes (map reg 0) to the admin vector. */
877 reg_gen_irq_map_set(hw,
878 ((0x80U | adm_irq) << 24) | ((0x80U | adm_irq) << 16), 0);
879 reg_gen_irq_map_set(hw, 0x80 | adm_irq, 3);
880
881 err = aq_hw_offload_set(hw);
882
883 err_exit:
884 AQ_DBG_EXIT(err);
885 return (err);
886 }
887
888
889 int
aq_hw_start(struct aq_hw * hw)890 aq_hw_start(struct aq_hw *hw)
891 {
892 int err;
893
894 AQ_DBG_ENTER();
895 tpb_tx_buff_en_set(hw, 1U);
896 rpb_rx_buff_en_set(hw, 1U);
897 err = aq_hw_err_from_flags(hw);
898 AQ_DBG_EXIT(err);
899 return (err);
900 }
901
902
903 int
aq_hw_interrupt_moderation_set(struct aq_hw * hw)904 aq_hw_interrupt_moderation_set(struct aq_hw *hw)
905 {
906 /* Rows in enum aq_fw_link_speed bit order (10M=0 .. 10G=5); index = ffs(speed)-1. */
907 static unsigned int aq_itr_timers_rx[][2] = {
908 {0x4U, 0x50U}, /* 10Mbit */
909 {0x4U, 0x50U}, /* 100Mbit */
910 {0x30U, 0x80U}, /* 1Gbit */
911 {0x18U, 0xE0U}, /* 2.5Gbit */
912 {0xCU, 0x70U}, /* 5Gbit */
913 {80, 120}, /* 10Gbit */
914 };
915 static unsigned int aq_itr_timers_tx[][2] = {
916 {0x4fU, 0xffU}, /* 10Mbit */
917 {0x4fU, 0xffU}, /* 100Mbit */
918 {0x4fU, 0xffU}, /* 1Gbit */
919 {0x4fU, 0xffU}, /* 2.5Gbit */
920 {0x4fU, 0xffU}, /* 5Gbit */
921 {0x4fU, 0x1ff}, /* 10Gbit */
922 };
923
924 uint32_t speed_index = ffs(hw->link_speed ? hw->link_speed : aq_fw_10G) - 1;
925 uint32_t itr_rx = 2U;
926 uint32_t itr_tx = 2U;
927 int custom_itr = hw->itr;
928 int active = custom_itr != 0;
929 int err;
930
931
932 AQ_DBG_ENTER();
933
934 if (custom_itr == -1) {
935 /* set min timer value */
936 itr_rx |= aq_itr_timers_rx[speed_index][0] << 0x8U;
937 /* set max timer value */
938 itr_rx |= aq_itr_timers_rx[speed_index][1] << 0x10U;
939
940 /* set min timer value */
941 itr_tx |= aq_itr_timers_tx[speed_index][0] << 0x8U;
942 /* set max timer value */
943 itr_tx |= aq_itr_timers_tx[speed_index][1] << 0x10U;
944 } else {
945 if (custom_itr > 0x1FF)
946 custom_itr = 0x1FF;
947
948 itr_rx |= (custom_itr/2) << 0x8U; /* set min timer value */
949 itr_rx |= custom_itr << 0x10U; /* set max timer value */
950
951 itr_tx |= (custom_itr/2) << 0x8U; /* set min timer value */
952 itr_tx |= custom_itr << 0x10U; /* set max timer value */
953 }
954
955 tdm_tx_desc_wr_wb_irq_en_set(hw, !active);
956 tdm_tdm_intr_moder_en_set(hw, active);
957 rdm_rx_desc_wr_wb_irq_en_set(hw, !active);
958 rdm_rdm_intr_moder_en_set(hw, active);
959
960 for (int i = HW_ATL_B0_RINGS_MAX; i--;) {
961 /* A2 Tx moderation register moved; same layout. Rx is shared. */
962 if (IS_CHIP_FEATURE(hw, ATLANTIC2))
963 AQ_WRITE_REG(hw, AQ2_TX_INTR_MODERATION_CTL_REG(i),
964 itr_tx);
965 else
966 reg_tx_intr_moder_ctrl_set(hw, itr_tx, i);
967 reg_rx_intr_moder_ctrl_set(hw, itr_rx, i);
968 }
969
970 err = aq_hw_err_from_flags(hw);
971 AQ_DBG_EXIT(err);
972 return (err);
973 }
974
975 /**
976 * @brief Set VLAN filter table
977 * @details Configure VLAN filter table to accept (and assign the queue) traffic
978 * for the particular vlan ids.
979 * Note: use this function under vlan promisc mode not to lost the traffic
980 *
981 * @param aq_hw
982 * @param aq_rx_filter_vlan VLAN filter configuration
983 * @return 0 - OK, <0 - error
984 */
985 int
hw_atl_b0_hw_vlan_set(struct aq_hw * hw,struct aq_rx_filter_vlan * aq_vlans)986 hw_atl_b0_hw_vlan_set(struct aq_hw *hw, struct aq_rx_filter_vlan *aq_vlans)
987 {
988 int i;
989
990 for (i = 0; i < AQ_HW_VLAN_MAX_FILTERS; i++) {
991 hw_atl_rpf_vlan_flr_en_set(hw, 0U, i);
992 hw_atl_rpf_vlan_rxq_en_flr_set(hw, 0U, i);
993 if (aq_vlans[i].enable) {
994 hw_atl_rpf_vlan_id_flr_set(hw,
995 aq_vlans[i].vlan_id,
996 i);
997 hw_atl_rpf_vlan_flr_act_set(hw, 1U, i);
998 /* A2: tag the filter so the VLAN drop row passes it. */
999 if (IS_CHIP_FEATURE(hw, ATLANTIC2))
1000 AQ_WRITE_REG_BIT(hw,
1001 AQ2_RPF_VLAN_FLR_TAG_REG(i),
1002 AQ2_RPF_VLAN_FLR_TAG,
1003 AQ2_RPF_VLAN_FLR_TAG_SHIFT, 1U);
1004 hw_atl_rpf_vlan_flr_en_set(hw, 1U, i);
1005 if (aq_vlans[i].queue != 0xFF) {
1006 hw_atl_rpf_vlan_rxq_flr_set(hw,
1007 aq_vlans[i].queue,
1008 i);
1009 hw_atl_rpf_vlan_rxq_en_flr_set(hw, 1U, i);
1010 }
1011 }
1012 }
1013
1014 return aq_hw_err_from_flags(hw);
1015 }
1016
1017 int
hw_atl_b0_hw_vlan_promisc_set(struct aq_hw * hw,bool promisc)1018 hw_atl_b0_hw_vlan_promisc_set(struct aq_hw *hw, bool promisc)
1019 {
1020 int err;
1021
1022 /* A2: fallible ART write first; a timeout leaves the legacy bit as-is. */
1023 if (IS_CHIP_FEATURE(hw, ATLANTIC2)) {
1024 err = aq2_art_filter_set(hw, AQ2_RPF_INDEX_VLAN_PROMISC_OFF,
1025 0, AQ2_RPF_TAG_VLAN_MASK | AQ2_RPF_TAG_UNTAG_MASK,
1026 promisc ? AQ2_ART_ACTION_DISABLE : AQ2_ART_ACTION_DROP);
1027 if (err != 0)
1028 return (err);
1029 }
1030 hw_atl_rpf_vlan_prom_mode_en_set(hw, promisc);
1031 return aq_hw_err_from_flags(hw);
1032 }
1033
1034
1035 int
aq_hw_set_promisc(struct aq_hw * hw,bool l2_promisc,bool vlan_promisc,bool mc_promisc)1036 aq_hw_set_promisc(struct aq_hw *hw, bool l2_promisc, bool vlan_promisc,
1037 bool mc_promisc)
1038 {
1039 int err = 0;
1040
1041 AQ_DBG_ENTERA("promisc %d, vlan_promisc %d, allmulti %d", l2_promisc,
1042 vlan_promisc, mc_promisc);
1043
1044 rpfl2promiscuous_mode_en_set(hw, l2_promisc);
1045
1046 err = hw_atl_b0_hw_vlan_promisc_set(hw, l2_promisc | vlan_promisc);
1047
1048 /* A2: promisc toggles the unicast drop row. */
1049 if (err == 0 && IS_CHIP_FEATURE(hw, ATLANTIC2))
1050 err = aq2_art_filter_set(hw, AQ2_RPF_INDEX_L2_PROMISC_OFF, 0,
1051 AQ2_RPF_TAG_UC_MASK | AQ2_RPF_TAG_ALLMC_MASK,
1052 l2_promisc ? AQ2_ART_ACTION_DISABLE : AQ2_ART_ACTION_DROP);
1053
1054 rpfl2_accept_all_mc_packets_set(hw, mc_promisc);
1055 rpfl2multicast_flr_en_set(hw, mc_promisc, 0);
1056
1057 AQ_DBG_EXIT(err);
1058 return (err);
1059 }
1060
1061 int
aq_hw_rss_hash_set(struct aq_hw * hw,uint8_t rss_key[HW_ATL_RSS_HASHKEY_SIZE])1062 aq_hw_rss_hash_set(struct aq_hw *hw,
1063 uint8_t rss_key[HW_ATL_RSS_HASHKEY_SIZE])
1064 {
1065 uint32_t rss_key_dw[HW_ATL_RSS_HASHKEY_SIZE / 4];
1066 uint32_t addr = 0U;
1067 uint32_t i = 0U;
1068 int err = 0;
1069
1070 AQ_DBG_ENTER();
1071
1072 memcpy(rss_key_dw, rss_key, HW_ATL_RSS_HASHKEY_SIZE);
1073
1074 for (i = 10, addr = 0U; i--; ++addr) {
1075 uint32_t key_data = bswap32(rss_key_dw[i]);
1076 rpf_rss_key_wr_data_set(hw, key_data);
1077 rpf_rss_key_addr_set(hw, addr);
1078 rpf_rss_key_wr_en_set(hw, 1U);
1079 err = AQ_HW_WAIT_FOR(rpf_rss_key_wr_en_get(hw) == 0,
1080 1000U, 10U);
1081 if (err != 0)
1082 goto err_exit;
1083 }
1084
1085 err = aq_hw_err_from_flags(hw);
1086
1087 err_exit:
1088 AQ_DBG_EXIT(err);
1089 return (err);
1090 }
1091
1092 int
aq_hw_rss_hash_get(struct aq_hw * hw,uint8_t rss_key[HW_ATL_RSS_HASHKEY_SIZE])1093 aq_hw_rss_hash_get(struct aq_hw *hw,
1094 uint8_t rss_key[HW_ATL_RSS_HASHKEY_SIZE])
1095 {
1096 uint32_t rss_key_dw[HW_ATL_RSS_HASHKEY_SIZE / 4];
1097 uint32_t addr = 0U;
1098 uint32_t i = 0U;
1099 int err = 0;
1100
1101 AQ_DBG_ENTER();
1102
1103 for (i = 10, addr = 0U; i--; ++addr) {
1104 rpf_rss_key_addr_set(hw, addr);
1105 rss_key_dw[i] = bswap32(rpf_rss_key_rd_data_get(hw));
1106 }
1107 memcpy(rss_key, rss_key_dw, HW_ATL_RSS_HASHKEY_SIZE);
1108
1109 err = aq_hw_err_from_flags(hw);
1110
1111 AQ_DBG_EXIT(err);
1112 return (err);
1113 }
1114
1115 int
aq_hw_rss_set(struct aq_hw * hw,uint8_t rss_table[HW_ATL_RSS_INDIRECTION_TABLE_MAX])1116 aq_hw_rss_set(struct aq_hw *hw,
1117 uint8_t rss_table[HW_ATL_RSS_INDIRECTION_TABLE_MAX])
1118 {
1119 uint16_t bitary[(HW_ATL_RSS_INDIRECTION_TABLE_MAX *
1120 3 / 16U)];
1121 int err = 0;
1122 uint32_t i = 0U;
1123
1124 memset(bitary, 0, sizeof(bitary));
1125
1126 /* A2 per-TC redirection table; flat RX rings, same queue per TC. */
1127 if (IS_CHIP_FEATURE(hw, ATLANTIC2)) {
1128 uint32_t n_tcs = aq_hw_active_tcs(hw);
1129 int tc, slot, q;
1130 uint32_t word;
1131
1132 AQ_WRITE_REG_BIT(hw, AQ2_RPF_REDIR2_REG, AQ2_RPF_REDIR2_INDEX,
1133 12, 0);
1134 for (slot = 0; slot < AQ2_RPF_RSS_REDIR_MAX; slot++) {
1135 q = rss_table[slot] &
1136 (HW_ATL_RSS_INDIRECTION_QUEUES_MAX - 1U);
1137 word = 0U;
1138 for (tc = 0; (uint32_t)tc < n_tcs; tc++)
1139 word |= (uint32_t)q << (5 * tc);
1140 AQ_WRITE_REG(hw, AQ2_RPF_RSS_REDIR_REG(0, slot), word);
1141 }
1142 /* A2 uses this table only; skip the legacy indirection writes. */
1143 return (aq_hw_err_from_flags(hw));
1144 }
1145
1146 for (i = HW_ATL_RSS_INDIRECTION_TABLE_MAX; i--;) {
1147 uint32_t bit_pos = i * HW_ATL_RSS_INDIRECTION_ENTRY_BITS;
1148 uint32_t word = bit_pos / 16U;
1149 uint32_t shift = bit_pos % 16U;
1150 uint32_t field = (uint32_t)(rss_table[i] &
1151 (HW_ATL_RSS_INDIRECTION_QUEUES_MAX - 1U)) << shift;
1152
1153 bitary[word] |= (uint16_t)field;
1154 if (shift + HW_ATL_RSS_INDIRECTION_ENTRY_BITS > 16U &&
1155 word + 1U < nitems(bitary))
1156 bitary[word + 1U] |= (uint16_t)(field >> 16);
1157 }
1158
1159 for (i = nitems(bitary); i--;) {
1160 rpf_rss_redir_tbl_wr_data_set(hw, bitary[i]);
1161 rpf_rss_redir_tbl_addr_set(hw, i);
1162 rpf_rss_redir_wr_en_set(hw, 1U);
1163 err = AQ_HW_WAIT_FOR(rpf_rss_redir_wr_en_get(hw) == 0,
1164 1000U, 10U);
1165 if (err != 0)
1166 goto err_exit;
1167 }
1168
1169 err = aq_hw_err_from_flags(hw);
1170
1171 err_exit:
1172 return (err);
1173 }
1174
1175 int
aq_hw_udp_rss_enable(struct aq_hw * hw,bool enable)1176 aq_hw_udp_rss_enable(struct aq_hw *hw, bool enable)
1177 {
1178 int err = 0;
1179 if (!enable) {
1180 /* HW bug workaround:
1181 * Disable RSS for UDP using rx flow filter 0.
1182 * HW does not track RSS stream for fragmenged UDP,
1183 * 0x5040 control reg does not work.
1184 */
1185 hw_atl_rpf_l3_l4_enf_set(hw, true, 0);
1186 hw_atl_rpf_l4_protf_en_set(hw, true, 0);
1187 hw_atl_rpf_l3_l4_rxqf_en_set(hw, true, 0);
1188 hw_atl_rpf_l3_l4_actf_set(hw, L2_FILTER_ACTION_HOST, 0);
1189 hw_atl_rpf_l3_l4_rxqf_set(hw, 0, 0);
1190 hw_atl_rpf_l4_protf_set(hw, HW_ATL_RX_UDP, 0);
1191 } else {
1192 hw_atl_rpf_l3_l4_enf_set(hw, false, 0);
1193 }
1194
1195 err = aq_hw_err_from_flags(hw);
1196 return (err);
1197
1198 }
1199