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