1
2
3
4
5
6#include "../atl_types.h"
7#include "hw_atl_b0.h"
8
9#include "../atl_hw_regs.h"
10#include "hw_atl_utils.h"
11#include "hw_atl_llh.h"
12#include "hw_atl_b0_internal.h"
13#include "hw_atl_llh_internal.h"
14#include "../atl_logs.h"
15
16int hw_atl_b0_hw_reset(struct aq_hw_s *self)
17{
18 int err = 0;
19
20 err = hw_atl_utils_soft_reset(self);
21 if (err)
22 return err;
23
24 self->aq_fw_ops->set_state(self, MPI_RESET);
25
26 return err;
27}
28
29int hw_atl_b0_set_fc(struct aq_hw_s *self, u32 fc, u32 tc)
30{
31 hw_atl_rpb_rx_xoff_en_per_tc_set(self, !!(fc & AQ_NIC_FC_RX), tc);
32 return 0;
33}
34
35static int hw_atl_b0_hw_qos_set(struct aq_hw_s *self)
36{
37 u32 tc = 0U;
38 u32 buff_size = 0U;
39 unsigned int i_priority = 0U;
40
41
42 hw_atl_tps_tx_pkt_shed_desc_rate_curr_time_res_set(self, 0x0U);
43 hw_atl_tps_tx_pkt_shed_desc_rate_lim_set(self, 0xA);
44
45
46 hw_atl_tps_tx_pkt_shed_desc_vm_arb_mode_set(self, 0U);
47
48
49 hw_atl_tps_tx_pkt_shed_desc_tc_arb_mode_set(self, 0U);
50 hw_atl_tps_tx_pkt_shed_data_arb_mode_set(self, 0U);
51
52 hw_atl_tps_tx_pkt_shed_tc_data_max_credit_set(self, 0xFFF, 0U);
53 hw_atl_tps_tx_pkt_shed_tc_data_weight_set(self, 0x64, 0U);
54 hw_atl_tps_tx_pkt_shed_desc_tc_max_credit_set(self, 0x50, 0U);
55 hw_atl_tps_tx_pkt_shed_desc_tc_weight_set(self, 0x1E, 0U);
56
57
58 buff_size = HW_ATL_B0_TXBUF_MAX;
59
60 hw_atl_tpb_tx_pkt_buff_size_per_tc_set(self, buff_size, tc);
61 hw_atl_tpb_tx_buff_hi_threshold_per_tc_set(self,
62 (buff_size *
63 (1024 / 32U) * 66U) /
64 100U, tc);
65 hw_atl_tpb_tx_buff_lo_threshold_per_tc_set(self,
66 (buff_size *
67 (1024 / 32U) * 50U) /
68 100U, tc);
69
70
71 tc = 0;
72 buff_size = HW_ATL_B0_RXBUF_MAX;
73
74 hw_atl_rpb_rx_pkt_buff_size_per_tc_set(self, buff_size, tc);
75 hw_atl_rpb_rx_buff_hi_threshold_per_tc_set(self,
76 (buff_size *
77 (1024U / 32U) * 66U) /
78 100U, tc);
79 hw_atl_rpb_rx_buff_lo_threshold_per_tc_set(self,
80 (buff_size *
81 (1024U / 32U) * 50U) /
82 100U, tc);
83 hw_atl_rpb_rx_xoff_en_per_tc_set(self, 0U, tc);
84
85
86 for (i_priority = 8U; i_priority--;)
87 hw_atl_rpf_rpb_user_priority_tc_map_set(self, i_priority, 0U);
88
89 return aq_hw_err_from_flags(self);
90}
91
92
93#define pif_rpf_rss_ipv4_hdr_only_i (1 << 4)
94
95#define pif_rpf_rss_ipv4_tcp_hdr_only_i (1 << 3)
96
97#define pif_rpf_rss_ipv6_hdr_only_i (1 << 2)
98
99#define pif_rpf_rss_ipv6_tcp_hdr_only_i (1 << 1)
100
101#define pif_rpf_rss_dont_use_udp_i (1 << 0)
102
103static int hw_atl_b0_hw_rss_hash_type_set(struct aq_hw_s *self)
104{
105
106 unsigned int control_reg_val =
107 IS_CHIP_FEATURE(RPF2) ? 0x000F0000U : 0x00000000U;
108
109
110 control_reg_val |= pif_rpf_rss_ipv4_hdr_only_i;
111
112 aq_hw_write_reg(self, 0x5040U, control_reg_val);
113
114 return aq_hw_err_from_flags(self);
115}
116
117int hw_atl_b0_hw_rss_hash_set(struct aq_hw_s *self,
118 struct aq_rss_parameters *rss_params)
119{
120 struct aq_hw_cfg_s *cfg = self->aq_nic_cfg;
121 int err = 0;
122 unsigned int i = 0U;
123 unsigned int addr = 0U;
124
125 for (i = 10, addr = 0U; i--; ++addr) {
126 u32 key_data = cfg->is_rss ?
127 htonl(rss_params->hash_secret_key[i]) : 0U;
128 hw_atl_rpf_rss_key_wr_data_set(self, key_data);
129 hw_atl_rpf_rss_key_addr_set(self, addr);
130 hw_atl_rpf_rss_key_wr_en_set(self, 1U);
131 AQ_HW_WAIT_FOR(hw_atl_rpf_rss_key_wr_en_get(self) == 0,
132 1000U, 10U);
133 if (err < 0)
134 goto err_exit;
135 }
136
137
138 hw_atl_reg_rx_flr_rss_control1set(self,
139 cfg->is_rss ? 0xB3333333U : 0x00000000U);
140 hw_atl_b0_hw_rss_hash_type_set(self);
141
142 err = aq_hw_err_from_flags(self);
143
144err_exit:
145 return err;
146}
147
148
149int hw_atl_b0_hw_rss_set(struct aq_hw_s *self,
150 struct aq_rss_parameters *rss_params)
151{
152 u8 *indirection_table = rss_params->indirection_table;
153 u32 num_rss_queues = max(1U, self->aq_nic_cfg->num_rss_queues);
154 u32 i = 0;
155 u32 addr = 0;
156 u32 val = 0;
157 u32 shift = 0;
158 int err = 0;
159
160 for (i = 0; i < HW_ATL_B0_RSS_REDIRECTION_MAX; i++) {
161 val |= (u32)(indirection_table[i] % num_rss_queues) << shift;
162 shift += 3;
163
164 if (shift < 16)
165 continue;
166
167 hw_atl_rpf_rss_redir_tbl_wr_data_set(self, val & 0xffff);
168 hw_atl_rpf_rss_redir_tbl_addr_set(self, addr);
169
170 hw_atl_rpf_rss_redir_wr_en_set(self, 1U);
171 AQ_HW_WAIT_FOR(hw_atl_rpf_rss_redir_wr_en_get(self) == 0,
172 1000U, 10U);
173
174 if (err < 0)
175 goto err_exit;
176
177 shift -= 16;
178 val >>= 16;
179 addr++;
180 }
181
182err_exit:
183 return err;
184}
185
186static int hw_atl_b0_hw_offload_set(struct aq_hw_s *self)
187
188{
189 unsigned int i;
190
191
192 hw_atl_tpo_ipv4header_crc_offload_en_set(self, 1);
193 hw_atl_tpo_tcp_udp_crc_offload_en_set(self, 1);
194
195
196 hw_atl_rpo_ipv4header_crc_offload_en_set(self, 1);
197 hw_atl_rpo_tcp_udp_crc_offload_en_set(self, 1);
198
199
200 hw_atl_tdm_large_send_offload_en_set(self, 0xFFFFFFFFU);
201
202
203 {
204 unsigned int val = (8U < HW_ATL_B0_LRO_RXD_MAX) ? 0x3U :
205 ((4U < HW_ATL_B0_LRO_RXD_MAX) ? 0x2U :
206 ((2U < HW_ATL_B0_LRO_RXD_MAX) ? 0x1U : 0x0));
207
208 for (i = 0; i < HW_ATL_B0_RINGS_MAX; i++)
209 hw_atl_rpo_lro_max_num_of_descriptors_set(self, val, i);
210
211 hw_atl_rpo_lro_time_base_divider_set(self, 0x61AU);
212 hw_atl_rpo_lro_inactive_interval_set(self, 0);
213 hw_atl_rpo_lro_max_coalescing_interval_set(self, 2);
214
215 hw_atl_rpo_lro_qsessions_lim_set(self, 1U);
216
217 hw_atl_rpo_lro_total_desc_lim_set(self, 2U);
218
219 hw_atl_rpo_lro_patch_optimization_en_set(self, 0U);
220
221 hw_atl_rpo_lro_min_pay_of_first_pkt_set(self, 10U);
222
223 hw_atl_rpo_lro_pkt_lim_set(self, 1U);
224
225 hw_atl_rpo_lro_en_set(self,
226 self->aq_nic_cfg->is_lro ? 0xFFFFFFFFU : 0U);
227 }
228 return aq_hw_err_from_flags(self);
229}
230
231static
232int hw_atl_b0_hw_init_tx_path(struct aq_hw_s *self)
233{
234
235 hw_atl_rpb_tps_tx_tc_mode_set(self, 1U);
236
237 hw_atl_thm_lso_tcp_flag_of_first_pkt_set(self, 0x0FF6U);
238 hw_atl_thm_lso_tcp_flag_of_middle_pkt_set(self, 0x0FF6U);
239 hw_atl_thm_lso_tcp_flag_of_last_pkt_set(self, 0x0F7FU);
240
241
242 hw_atl_tdm_tx_desc_wr_wb_irq_en_set(self, 0U);
243
244
245 aq_hw_write_reg(self, 0x00007040U, IS_CHIP_FEATURE(TPO2) ?
246 0x00010000U : 0x00000000U);
247 hw_atl_tdm_tx_dca_en_set(self, 0U);
248 hw_atl_tdm_tx_dca_mode_set(self, 0U);
249
250 hw_atl_tpb_tx_path_scp_ins_en_set(self, 1U);
251
252 return aq_hw_err_from_flags(self);
253}
254
255static
256int hw_atl_b0_hw_init_rx_path(struct aq_hw_s *self)
257{
258 struct aq_hw_cfg_s *cfg = self->aq_nic_cfg;
259 int i;
260
261
262 hw_atl_rpb_rpf_rx_traf_class_mode_set(self, 1U);
263
264
265 hw_atl_rpb_rx_flow_ctl_mode_set(self, 1U);
266
267
268 hw_atl_reg_rx_flr_rss_control1set(self, cfg->is_rss ?
269 0xB3333333U : 0x00000000U);
270
271
272 for (i = HW_ATL_B0_MAC_MAX; i--;) {
273 hw_atl_rpfl2_uc_flr_en_set(self, (i == 0U) ? 1U : 0U, i);
274 hw_atl_rpfl2unicast_flr_act_set(self, 1U, i);
275 }
276
277 hw_atl_reg_rx_flr_mcst_flr_msk_set(self, 0x00000000U);
278 hw_atl_reg_rx_flr_mcst_flr_set(self, 0x00010FFFU, 0U);
279
280
281 hw_atl_rpf_vlan_outer_etht_set(self, 0x88A8U);
282 hw_atl_rpf_vlan_inner_etht_set(self, 0x8100U);
283
284
285 hw_atl_rpf_vlan_prom_mode_en_set(self, 1);
286
287
288 hw_atl_rdm_rx_desc_wr_wb_irq_en_set(self, 0U);
289
290 hw_atl_b0_hw_rss_hash_type_set(self);
291
292 hw_atl_rpfl2broadcast_flr_act_set(self, 1U);
293 hw_atl_rpfl2broadcast_count_threshold_set(self, 0xFFFFU & (~0U / 256U));
294
295 hw_atl_rpfl2broadcast_en_set(self, 1U);
296
297 hw_atl_rdm_rx_dca_en_set(self, 0U);
298 hw_atl_rdm_rx_dca_mode_set(self, 0U);
299
300 return aq_hw_err_from_flags(self);
301}
302
303static int hw_atl_b0_hw_mac_addr_set(struct aq_hw_s *self, u8 *mac_addr)
304{
305 int err = 0;
306 unsigned int h = 0U;
307 unsigned int l = 0U;
308
309 if (!mac_addr) {
310 err = -EINVAL;
311 goto err_exit;
312 }
313 h = (mac_addr[0] << 8) | (mac_addr[1]);
314 l = (mac_addr[2] << 24) | (mac_addr[3] << 16) |
315 (mac_addr[4] << 8) | mac_addr[5];
316
317 hw_atl_rpfl2_uc_flr_en_set(self, 0U, HW_ATL_B0_MAC);
318 hw_atl_rpfl2unicast_dest_addresslsw_set(self, l, HW_ATL_B0_MAC);
319 hw_atl_rpfl2unicast_dest_addressmsw_set(self, h, HW_ATL_B0_MAC);
320 hw_atl_rpfl2_uc_flr_en_set(self, 1U, HW_ATL_B0_MAC);
321
322 err = aq_hw_err_from_flags(self);
323
324err_exit:
325 return err;
326}
327
328int hw_atl_b0_hw_init(struct aq_hw_s *self, u8 *mac_addr)
329{
330 static u32 aq_hw_atl_igcr_table_[4][2] = {
331 { 0x20000080U, 0x20000080U },
332 { 0x20000080U, 0x20000080U },
333 { 0x20000021U, 0x20000025U },
334 { 0x200000A2U, 0x200000A6U }
335 };
336
337 int err = 0;
338 u32 val;
339
340 struct aq_hw_cfg_s *aq_nic_cfg = self->aq_nic_cfg;
341
342 hw_atl_b0_hw_init_tx_path(self);
343 hw_atl_b0_hw_init_rx_path(self);
344
345 hw_atl_b0_hw_mac_addr_set(self, mac_addr);
346
347 self->aq_fw_ops->set_link_speed(self, aq_nic_cfg->link_speed_msk);
348 self->aq_fw_ops->set_state(self, MPI_INIT);
349
350 hw_atl_b0_hw_qos_set(self);
351 hw_atl_b0_hw_rss_set(self, &aq_nic_cfg->aq_rss);
352 hw_atl_b0_hw_rss_hash_set(self, &aq_nic_cfg->aq_rss);
353
354
355 val = aq_hw_read_reg(self, HW_ATL_PCI_REG_CONTROL6_ADR);
356 aq_hw_write_reg(self, HW_ATL_PCI_REG_CONTROL6_ADR,
357 (val & ~0x707) | 0x404);
358
359
360
361
362
363 aq_hw_write_reg(self, HW_ATL_TX_DMA_TOTAL_REQ_LIMIT_ADR, 24);
364
365
366 self->aq_link_status.mbps = 0;
367 self->aq_fw_ops->update_stats(self);
368
369 err = aq_hw_err_from_flags(self);
370 if (err < 0)
371 goto err_exit;
372
373
374 hw_atl_reg_irq_glb_ctl_set(self,
375 aq_hw_atl_igcr_table_[aq_nic_cfg->irq_type]
376 [(aq_nic_cfg->vecs > 1U) ?
377 1 : 0]);
378
379 hw_atl_itr_irq_auto_masklsw_set(self, 0xffffffff);
380
381
382 hw_atl_reg_gen_irq_map_set(self, 0, 0);
383 hw_atl_reg_gen_irq_map_set(self, 0x80 | ATL_IRQ_CAUSE_LINK, 3);
384
385 hw_atl_b0_hw_offload_set(self);
386
387err_exit:
388 return err;
389}
390
391int hw_atl_b0_hw_ring_tx_start(struct aq_hw_s *self, int index)
392{
393 hw_atl_tdm_tx_desc_en_set(self, 1, index);
394 return aq_hw_err_from_flags(self);
395}
396
397int hw_atl_b0_hw_ring_rx_start(struct aq_hw_s *self, int index)
398{
399 hw_atl_rdm_rx_desc_en_set(self, 1, index);
400 return aq_hw_err_from_flags(self);
401}
402
403int hw_atl_b0_hw_start(struct aq_hw_s *self)
404{
405 hw_atl_tpb_tx_buff_en_set(self, 1);
406 hw_atl_rpb_rx_buff_en_set(self, 1);
407 return aq_hw_err_from_flags(self);
408}
409
410int hw_atl_b0_hw_tx_ring_tail_update(struct aq_hw_s *self, int tail, int index)
411{
412 hw_atl_reg_tx_dma_desc_tail_ptr_set(self, tail, index);
413 return 0;
414}
415
416int hw_atl_b0_hw_ring_rx_init(struct aq_hw_s *self, uint64_t base_addr,
417 int index, int size, int buff_size, int cpu, int vec)
418{
419 u32 dma_desc_addr_lsw = (u32)base_addr;
420 u32 dma_desc_addr_msw = (u32)(base_addr >> 32);
421
422 hw_atl_rdm_rx_desc_en_set(self, false, index);
423
424 hw_atl_rdm_rx_desc_head_splitting_set(self, 0U, index);
425
426 hw_atl_reg_rx_dma_desc_base_addresslswset(self, dma_desc_addr_lsw,
427 index);
428
429 hw_atl_reg_rx_dma_desc_base_addressmswset(self, dma_desc_addr_msw,
430 index);
431
432 hw_atl_rdm_rx_desc_len_set(self, size / 8U, index);
433
434 hw_atl_rdm_rx_desc_data_buff_size_set(self, buff_size / 1024U, index);
435
436 hw_atl_rdm_rx_desc_head_buff_size_set(self, 0U, index);
437 hw_atl_rdm_rx_desc_head_splitting_set(self, 0U, index);
438 hw_atl_rpo_rx_desc_vlan_stripping_set(self, 0U, index);
439
440
441
442
443 hw_atl_itr_irq_map_rx_set(self, vec, index);
444 hw_atl_itr_irq_map_en_rx_set(self, true, index);
445
446 hw_atl_rdm_cpu_id_set(self, cpu, index);
447 hw_atl_rdm_rx_desc_dca_en_set(self, 0U, index);
448 hw_atl_rdm_rx_head_dca_en_set(self, 0U, index);
449 hw_atl_rdm_rx_pld_dca_en_set(self, 0U, index);
450
451 return aq_hw_err_from_flags(self);
452}
453
454int hw_atl_b0_hw_ring_tx_init(struct aq_hw_s *self, uint64_t base_addr,
455 int index, int size, int cpu, int vec)
456{
457 u32 dma_desc_lsw_addr = (u32)base_addr;
458 u32 dma_desc_msw_addr = (u32)(base_addr >> 32);
459
460 hw_atl_reg_tx_dma_desc_base_addresslswset(self, dma_desc_lsw_addr,
461 index);
462
463 hw_atl_reg_tx_dma_desc_base_addressmswset(self, dma_desc_msw_addr,
464 index);
465
466 hw_atl_tdm_tx_desc_len_set(self, size / 8U, index);
467
468 hw_atl_b0_hw_tx_ring_tail_update(self, 0, index);
469
470
471 hw_atl_tdm_tx_desc_wr_wb_threshold_set(self, 0U, index);
472
473
474 hw_atl_itr_irq_map_tx_set(self, vec, index);
475 hw_atl_itr_irq_map_en_tx_set(self, true, index);
476
477 hw_atl_tdm_cpu_id_set(self, cpu, index);
478 hw_atl_tdm_tx_desc_dca_en_set(self, 0U, index);
479
480 return aq_hw_err_from_flags(self);
481}
482
483int hw_atl_b0_hw_irq_enable(struct aq_hw_s *self, u64 mask)
484{
485 hw_atl_itr_irq_msk_setlsw_set(self, LODWORD(mask));
486 return aq_hw_err_from_flags(self);
487}
488
489int hw_atl_b0_hw_irq_disable(struct aq_hw_s *self, u64 mask)
490{
491 hw_atl_itr_irq_msk_clearlsw_set(self, LODWORD(mask));
492 hw_atl_itr_irq_status_clearlsw_set(self, LODWORD(mask));
493
494 return aq_hw_err_from_flags(self);
495}
496
497int hw_atl_b0_hw_irq_read(struct aq_hw_s *self, u64 *mask)
498{
499 *mask = hw_atl_itr_irq_statuslsw_get(self);
500 return aq_hw_err_from_flags(self);
501}
502
503int hw_atl_b0_hw_ring_tx_stop(struct aq_hw_s *self, int index)
504{
505 hw_atl_tdm_tx_desc_en_set(self, 0U, index);
506 return aq_hw_err_from_flags(self);
507}
508
509int hw_atl_b0_hw_ring_rx_stop(struct aq_hw_s *self, int index)
510{
511 hw_atl_rdm_rx_desc_en_set(self, 0U, index);
512 return aq_hw_err_from_flags(self);
513}
514