xref: /freebsd/sys/dev/aq/aq_hw.c (revision f9bc005b8ef3b507a5ecbc2d7fe4411ef70eff38)
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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