1 /* 2 * aQuantia Corporation Network Driver 3 * Copyright (C) 2014-2017 aQuantia Corporation. All rights reserved 4 * 5 * This program is free software; you can redistribute it and/or modify it 6 * under the terms and conditions of the GNU General Public License, 7 * version 2, as published by the Free Software Foundation. 8 */ 9 10 /* File hw_atl_a0.c: Definition of Atlantic hardware specific functions. */ 11 12 #include "../aq_hw.h" 13 #include "../aq_hw_utils.h" 14 #include "../aq_ring.h" 15 #include "../aq_nic.h" 16 #include "hw_atl_a0.h" 17 #include "hw_atl_utils.h" 18 #include "hw_atl_llh.h" 19 #include "hw_atl_a0_internal.h" 20 21 #define DEFAULT_A0_BOARD_BASIC_CAPABILITIES \ 22 .is_64_dma = true, \ 23 .msix_irqs = 4U, \ 24 .irq_mask = ~0U, \ 25 .vecs = HW_ATL_A0_RSS_MAX, \ 26 .tcs = HW_ATL_A0_TC_MAX, \ 27 .rxd_alignment = 1U, \ 28 .rxd_size = HW_ATL_A0_RXD_SIZE, \ 29 .rxds = 248U, \ 30 .txd_alignment = 1U, \ 31 .txd_size = HW_ATL_A0_TXD_SIZE, \ 32 .txds = 8U * 1024U, \ 33 .txhwb_alignment = 4096U, \ 34 .tx_rings = HW_ATL_A0_TX_RINGS, \ 35 .rx_rings = HW_ATL_A0_RX_RINGS, \ 36 .hw_features = NETIF_F_HW_CSUM | \ 37 NETIF_F_RXHASH | \ 38 NETIF_F_RXCSUM | \ 39 NETIF_F_SG | \ 40 NETIF_F_TSO, \ 41 .hw_priv_flags = IFF_UNICAST_FLT, \ 42 .flow_control = true, \ 43 .mtu = HW_ATL_A0_MTU_JUMBO, \ 44 .mac_regs_count = 88, \ 45 .hw_alive_check_addr = 0x10U 46 47 const struct aq_hw_caps_s hw_atl_a0_caps_aqc100 = { 48 DEFAULT_A0_BOARD_BASIC_CAPABILITIES, 49 .media_type = AQ_HW_MEDIA_TYPE_FIBRE, 50 .link_speed_msk = HW_ATL_A0_RATE_5G | 51 HW_ATL_A0_RATE_2G5 | 52 HW_ATL_A0_RATE_1G | 53 HW_ATL_A0_RATE_100M, 54 }; 55 56 const struct aq_hw_caps_s hw_atl_a0_caps_aqc107 = { 57 DEFAULT_A0_BOARD_BASIC_CAPABILITIES, 58 .media_type = AQ_HW_MEDIA_TYPE_TP, 59 .link_speed_msk = HW_ATL_A0_RATE_10G | 60 HW_ATL_A0_RATE_5G | 61 HW_ATL_A0_RATE_2G5 | 62 HW_ATL_A0_RATE_1G | 63 HW_ATL_A0_RATE_100M, 64 }; 65 66 const struct aq_hw_caps_s hw_atl_a0_caps_aqc108 = { 67 DEFAULT_A0_BOARD_BASIC_CAPABILITIES, 68 .media_type = AQ_HW_MEDIA_TYPE_TP, 69 .link_speed_msk = HW_ATL_A0_RATE_5G | 70 HW_ATL_A0_RATE_2G5 | 71 HW_ATL_A0_RATE_1G | 72 HW_ATL_A0_RATE_100M, 73 }; 74 75 const struct aq_hw_caps_s hw_atl_a0_caps_aqc109 = { 76 DEFAULT_A0_BOARD_BASIC_CAPABILITIES, 77 .media_type = AQ_HW_MEDIA_TYPE_TP, 78 .link_speed_msk = HW_ATL_A0_RATE_2G5 | 79 HW_ATL_A0_RATE_1G | 80 HW_ATL_A0_RATE_100M, 81 }; 82 83 static int hw_atl_a0_hw_reset(struct aq_hw_s *self) 84 { 85 int err = 0; 86 87 hw_atl_glb_glb_reg_res_dis_set(self, 1U); 88 hw_atl_pci_pci_reg_res_dis_set(self, 0U); 89 hw_atl_rx_rx_reg_res_dis_set(self, 0U); 90 hw_atl_tx_tx_reg_res_dis_set(self, 0U); 91 92 HW_ATL_FLUSH(); 93 hw_atl_glb_soft_res_set(self, 1); 94 95 /* check 10 times by 1ms */ 96 AQ_HW_WAIT_FOR(hw_atl_glb_soft_res_get(self) == 0, 1000U, 10U); 97 if (err < 0) 98 goto err_exit; 99 100 hw_atl_itr_irq_reg_res_dis_set(self, 0U); 101 hw_atl_itr_res_irq_set(self, 1U); 102 103 /* check 10 times by 1ms */ 104 AQ_HW_WAIT_FOR(hw_atl_itr_res_irq_get(self) == 0, 1000U, 10U); 105 if (err < 0) 106 goto err_exit; 107 108 self->aq_fw_ops->set_state(self, MPI_RESET); 109 110 err = aq_hw_err_from_flags(self); 111 112 err_exit: 113 return err; 114 } 115 116 static int hw_atl_a0_hw_qos_set(struct aq_hw_s *self) 117 { 118 u32 tc = 0U; 119 u32 buff_size = 0U; 120 unsigned int i_priority = 0U; 121 bool is_rx_flow_control = false; 122 123 /* TPS Descriptor rate init */ 124 hw_atl_tps_tx_pkt_shed_desc_rate_curr_time_res_set(self, 0x0U); 125 hw_atl_tps_tx_pkt_shed_desc_rate_lim_set(self, 0xA); 126 127 /* TPS VM init */ 128 hw_atl_tps_tx_pkt_shed_desc_vm_arb_mode_set(self, 0U); 129 130 /* TPS TC credits init */ 131 hw_atl_tps_tx_pkt_shed_desc_tc_arb_mode_set(self, 0U); 132 hw_atl_tps_tx_pkt_shed_data_arb_mode_set(self, 0U); 133 134 hw_atl_tps_tx_pkt_shed_tc_data_max_credit_set(self, 0xFFF, 0U); 135 hw_atl_tps_tx_pkt_shed_tc_data_weight_set(self, 0x64, 0U); 136 hw_atl_tps_tx_pkt_shed_desc_tc_max_credit_set(self, 0x50, 0U); 137 hw_atl_tps_tx_pkt_shed_desc_tc_weight_set(self, 0x1E, 0U); 138 139 /* Tx buf size */ 140 buff_size = HW_ATL_A0_TXBUF_MAX; 141 142 hw_atl_tpb_tx_pkt_buff_size_per_tc_set(self, buff_size, tc); 143 hw_atl_tpb_tx_buff_hi_threshold_per_tc_set(self, 144 (buff_size * 145 (1024 / 32U) * 66U) / 146 100U, tc); 147 hw_atl_tpb_tx_buff_lo_threshold_per_tc_set(self, 148 (buff_size * 149 (1024 / 32U) * 50U) / 150 100U, tc); 151 152 /* QoS Rx buf size per TC */ 153 tc = 0; 154 is_rx_flow_control = (AQ_NIC_FC_RX & self->aq_nic_cfg->flow_control); 155 buff_size = HW_ATL_A0_RXBUF_MAX; 156 157 hw_atl_rpb_rx_pkt_buff_size_per_tc_set(self, buff_size, tc); 158 hw_atl_rpb_rx_buff_hi_threshold_per_tc_set(self, 159 (buff_size * 160 (1024U / 32U) * 66U) / 161 100U, tc); 162 hw_atl_rpb_rx_buff_lo_threshold_per_tc_set(self, 163 (buff_size * 164 (1024U / 32U) * 50U) / 165 100U, tc); 166 hw_atl_rpb_rx_xoff_en_per_tc_set(self, is_rx_flow_control ? 1U : 0U, tc); 167 168 /* QoS 802.1p priority -> TC mapping */ 169 for (i_priority = 8U; i_priority--;) 170 hw_atl_rpf_rpb_user_priority_tc_map_set(self, i_priority, 0U); 171 172 return aq_hw_err_from_flags(self); 173 } 174 175 static int hw_atl_a0_hw_rss_hash_set(struct aq_hw_s *self, 176 struct aq_rss_parameters *rss_params) 177 { 178 struct aq_nic_cfg_s *cfg = self->aq_nic_cfg; 179 int err = 0; 180 unsigned int i = 0U; 181 unsigned int addr = 0U; 182 183 for (i = 10, addr = 0U; i--; ++addr) { 184 u32 key_data = cfg->is_rss ? 185 __swab32(rss_params->hash_secret_key[i]) : 0U; 186 hw_atl_rpf_rss_key_wr_data_set(self, key_data); 187 hw_atl_rpf_rss_key_addr_set(self, addr); 188 hw_atl_rpf_rss_key_wr_en_set(self, 1U); 189 AQ_HW_WAIT_FOR(hw_atl_rpf_rss_key_wr_en_get(self) == 0, 190 1000U, 10U); 191 if (err < 0) 192 goto err_exit; 193 } 194 195 err = aq_hw_err_from_flags(self); 196 197 err_exit: 198 return err; 199 } 200 201 static int hw_atl_a0_hw_rss_set(struct aq_hw_s *self, 202 struct aq_rss_parameters *rss_params) 203 { 204 u8 *indirection_table = rss_params->indirection_table; 205 u32 i = 0U; 206 u32 num_rss_queues = max(1U, self->aq_nic_cfg->num_rss_queues); 207 int err = 0; 208 u16 bitary[(HW_ATL_A0_RSS_REDIRECTION_MAX * 209 HW_ATL_A0_RSS_REDIRECTION_BITS / 16U)]; 210 211 memset(bitary, 0, sizeof(bitary)); 212 213 for (i = HW_ATL_A0_RSS_REDIRECTION_MAX; i--; ) { 214 (*(u32 *)(bitary + ((i * 3U) / 16U))) |= 215 ((indirection_table[i] % num_rss_queues) << 216 ((i * 3U) & 0xFU)); 217 } 218 219 for (i = ARRAY_SIZE(bitary); i--;) { 220 hw_atl_rpf_rss_redir_tbl_wr_data_set(self, bitary[i]); 221 hw_atl_rpf_rss_redir_tbl_addr_set(self, i); 222 hw_atl_rpf_rss_redir_wr_en_set(self, 1U); 223 AQ_HW_WAIT_FOR(hw_atl_rpf_rss_redir_wr_en_get(self) == 0, 224 1000U, 10U); 225 if (err < 0) 226 goto err_exit; 227 } 228 229 err = aq_hw_err_from_flags(self); 230 231 err_exit: 232 return err; 233 } 234 235 static int hw_atl_a0_hw_offload_set(struct aq_hw_s *self, 236 struct aq_nic_cfg_s *aq_nic_cfg) 237 { 238 /* TX checksums offloads*/ 239 hw_atl_tpo_ipv4header_crc_offload_en_set(self, 1); 240 hw_atl_tpo_tcp_udp_crc_offload_en_set(self, 1); 241 242 /* RX checksums offloads*/ 243 hw_atl_rpo_ipv4header_crc_offload_en_set(self, 1); 244 hw_atl_rpo_tcp_udp_crc_offload_en_set(self, 1); 245 246 /* LSO offloads*/ 247 hw_atl_tdm_large_send_offload_en_set(self, 0xFFFFFFFFU); 248 249 return aq_hw_err_from_flags(self); 250 } 251 252 static int hw_atl_a0_hw_init_tx_path(struct aq_hw_s *self) 253 { 254 hw_atl_thm_lso_tcp_flag_of_first_pkt_set(self, 0x0FF6U); 255 hw_atl_thm_lso_tcp_flag_of_middle_pkt_set(self, 0x0FF6U); 256 hw_atl_thm_lso_tcp_flag_of_last_pkt_set(self, 0x0F7FU); 257 258 /* Tx interrupts */ 259 hw_atl_tdm_tx_desc_wr_wb_irq_en_set(self, 1U); 260 261 /* misc */ 262 aq_hw_write_reg(self, 0x00007040U, IS_CHIP_FEATURE(TPO2) ? 263 0x00010000U : 0x00000000U); 264 hw_atl_tdm_tx_dca_en_set(self, 0U); 265 hw_atl_tdm_tx_dca_mode_set(self, 0U); 266 267 hw_atl_tpb_tx_path_scp_ins_en_set(self, 1U); 268 269 return aq_hw_err_from_flags(self); 270 } 271 272 static int hw_atl_a0_hw_init_rx_path(struct aq_hw_s *self) 273 { 274 struct aq_nic_cfg_s *cfg = self->aq_nic_cfg; 275 int i; 276 277 /* Rx TC/RSS number config */ 278 hw_atl_rpb_rpf_rx_traf_class_mode_set(self, 1U); 279 280 /* Rx flow control */ 281 hw_atl_rpb_rx_flow_ctl_mode_set(self, 1U); 282 283 /* RSS Ring selection */ 284 hw_atl_reg_rx_flr_rss_control1set(self, cfg->is_rss ? 285 0xB3333333U : 0x00000000U); 286 287 /* Multicast filters */ 288 for (i = HW_ATL_A0_MAC_MAX; i--;) { 289 hw_atl_rpfl2_uc_flr_en_set(self, (i == 0U) ? 1U : 0U, i); 290 hw_atl_rpfl2unicast_flr_act_set(self, 1U, i); 291 } 292 293 hw_atl_reg_rx_flr_mcst_flr_msk_set(self, 0x00000000U); 294 hw_atl_reg_rx_flr_mcst_flr_set(self, 0x00010FFFU, 0U); 295 296 /* Vlan filters */ 297 hw_atl_rpf_vlan_outer_etht_set(self, 0x88A8U); 298 hw_atl_rpf_vlan_inner_etht_set(self, 0x8100U); 299 hw_atl_rpf_vlan_prom_mode_en_set(self, 1); 300 301 /* Rx Interrupts */ 302 hw_atl_rdm_rx_desc_wr_wb_irq_en_set(self, 1U); 303 304 /* misc */ 305 hw_atl_rpfl2broadcast_flr_act_set(self, 1U); 306 hw_atl_rpfl2broadcast_count_threshold_set(self, 0xFFFFU & (~0U / 256U)); 307 308 hw_atl_rdm_rx_dca_en_set(self, 0U); 309 hw_atl_rdm_rx_dca_mode_set(self, 0U); 310 311 return aq_hw_err_from_flags(self); 312 } 313 314 static int hw_atl_a0_hw_mac_addr_set(struct aq_hw_s *self, u8 *mac_addr) 315 { 316 int err = 0; 317 unsigned int h = 0U; 318 unsigned int l = 0U; 319 320 if (!mac_addr) { 321 err = -EINVAL; 322 goto err_exit; 323 } 324 h = (mac_addr[0] << 8) | (mac_addr[1]); 325 l = (mac_addr[2] << 24) | (mac_addr[3] << 16) | 326 (mac_addr[4] << 8) | mac_addr[5]; 327 328 hw_atl_rpfl2_uc_flr_en_set(self, 0U, HW_ATL_A0_MAC); 329 hw_atl_rpfl2unicast_dest_addresslsw_set(self, l, HW_ATL_A0_MAC); 330 hw_atl_rpfl2unicast_dest_addressmsw_set(self, h, HW_ATL_A0_MAC); 331 hw_atl_rpfl2_uc_flr_en_set(self, 1U, HW_ATL_A0_MAC); 332 333 err = aq_hw_err_from_flags(self); 334 335 err_exit: 336 return err; 337 } 338 339 static int hw_atl_a0_hw_init(struct aq_hw_s *self, u8 *mac_addr) 340 { 341 static u32 aq_hw_atl_igcr_table_[4][2] = { 342 { 0x20000000U, 0x20000000U }, /* AQ_IRQ_INVALID */ 343 { 0x20000080U, 0x20000080U }, /* AQ_IRQ_LEGACY */ 344 { 0x20000021U, 0x20000025U }, /* AQ_IRQ_MSI */ 345 { 0x20000022U, 0x20000026U } /* AQ_IRQ_MSIX */ 346 }; 347 348 int err = 0; 349 350 struct aq_nic_cfg_s *aq_nic_cfg = self->aq_nic_cfg; 351 352 hw_atl_a0_hw_init_tx_path(self); 353 hw_atl_a0_hw_init_rx_path(self); 354 355 hw_atl_a0_hw_mac_addr_set(self, mac_addr); 356 357 self->aq_fw_ops->set_link_speed(self, aq_nic_cfg->link_speed_msk); 358 self->aq_fw_ops->set_state(self, MPI_INIT); 359 360 hw_atl_reg_tx_dma_debug_ctl_set(self, 0x800000b8U); 361 hw_atl_reg_tx_dma_debug_ctl_set(self, 0x000000b8U); 362 363 hw_atl_a0_hw_qos_set(self); 364 hw_atl_a0_hw_rss_set(self, &aq_nic_cfg->aq_rss); 365 hw_atl_a0_hw_rss_hash_set(self, &aq_nic_cfg->aq_rss); 366 367 /* Reset link status and read out initial hardware counters */ 368 self->aq_link_status.mbps = 0; 369 self->aq_fw_ops->update_stats(self); 370 371 err = aq_hw_err_from_flags(self); 372 if (err < 0) 373 goto err_exit; 374 375 /* Interrupts */ 376 hw_atl_reg_irq_glb_ctl_set(self, 377 aq_hw_atl_igcr_table_[aq_nic_cfg->irq_type] 378 [(aq_nic_cfg->vecs > 1U) ? 1 : 0]); 379 380 hw_atl_itr_irq_auto_masklsw_set(self, aq_nic_cfg->aq_hw_caps->irq_mask); 381 382 /* Interrupts */ 383 hw_atl_reg_gen_irq_map_set(self, 384 ((HW_ATL_A0_ERR_INT << 0x18) | (1U << 0x1F)) | 385 ((HW_ATL_A0_ERR_INT << 0x10) | (1U << 0x17)) | 386 ((HW_ATL_A0_ERR_INT << 8) | (1U << 0xF)) | 387 ((HW_ATL_A0_ERR_INT) | (1U << 0x7)), 0U); 388 389 hw_atl_a0_hw_offload_set(self, aq_nic_cfg); 390 391 err_exit: 392 return err; 393 } 394 395 static int hw_atl_a0_hw_ring_tx_start(struct aq_hw_s *self, 396 struct aq_ring_s *ring) 397 { 398 hw_atl_tdm_tx_desc_en_set(self, 1, ring->idx); 399 return aq_hw_err_from_flags(self); 400 } 401 402 static int hw_atl_a0_hw_ring_rx_start(struct aq_hw_s *self, 403 struct aq_ring_s *ring) 404 { 405 hw_atl_rdm_rx_desc_en_set(self, 1, ring->idx); 406 return aq_hw_err_from_flags(self); 407 } 408 409 static int hw_atl_a0_hw_start(struct aq_hw_s *self) 410 { 411 hw_atl_tpb_tx_buff_en_set(self, 1); 412 hw_atl_rpb_rx_buff_en_set(self, 1); 413 return aq_hw_err_from_flags(self); 414 } 415 416 static int hw_atl_a0_hw_tx_ring_tail_update(struct aq_hw_s *self, 417 struct aq_ring_s *ring) 418 { 419 hw_atl_reg_tx_dma_desc_tail_ptr_set(self, ring->sw_tail, ring->idx); 420 return 0; 421 } 422 423 static int hw_atl_a0_hw_ring_tx_xmit(struct aq_hw_s *self, 424 struct aq_ring_s *ring, 425 unsigned int frags) 426 { 427 struct aq_ring_buff_s *buff = NULL; 428 struct hw_atl_txd_s *txd = NULL; 429 unsigned int buff_pa_len = 0U; 430 unsigned int pkt_len = 0U; 431 unsigned int frag_count = 0U; 432 bool is_gso = false; 433 434 buff = &ring->buff_ring[ring->sw_tail]; 435 pkt_len = (buff->is_eop && buff->is_sop) ? buff->len : buff->len_pkt; 436 437 for (frag_count = 0; frag_count < frags; frag_count++) { 438 txd = (struct hw_atl_txd_s *)&ring->dx_ring[ring->sw_tail * 439 HW_ATL_A0_TXD_SIZE]; 440 txd->ctl = 0; 441 txd->ctl2 = 0; 442 txd->buf_addr = 0; 443 444 buff = &ring->buff_ring[ring->sw_tail]; 445 446 if (buff->is_txc) { 447 txd->ctl |= (buff->len_l3 << 31) | 448 (buff->len_l2 << 24) | 449 HW_ATL_A0_TXD_CTL_CMD_TCP | 450 HW_ATL_A0_TXD_CTL_DESC_TYPE_TXC; 451 txd->ctl2 |= (buff->mss << 16) | 452 (buff->len_l4 << 8) | 453 (buff->len_l3 >> 1); 454 455 pkt_len -= (buff->len_l4 + 456 buff->len_l3 + 457 buff->len_l2); 458 is_gso = true; 459 460 if (buff->is_ipv6) 461 txd->ctl |= HW_ATL_A0_TXD_CTL_CMD_IPV6; 462 } else { 463 buff_pa_len = buff->len; 464 465 txd->buf_addr = buff->pa; 466 txd->ctl |= (HW_ATL_A0_TXD_CTL_BLEN & 467 ((u32)buff_pa_len << 4)); 468 txd->ctl |= HW_ATL_A0_TXD_CTL_DESC_TYPE_TXD; 469 /* PAY_LEN */ 470 txd->ctl2 |= HW_ATL_A0_TXD_CTL2_LEN & (pkt_len << 14); 471 472 if (is_gso) { 473 txd->ctl |= HW_ATL_A0_TXD_CTL_CMD_LSO; 474 txd->ctl2 |= HW_ATL_A0_TXD_CTL2_CTX_EN; 475 } 476 477 /* Tx checksum offloads */ 478 if (buff->is_ip_cso) 479 txd->ctl |= HW_ATL_A0_TXD_CTL_CMD_IPCSO; 480 481 if (buff->is_udp_cso || buff->is_tcp_cso) 482 txd->ctl |= HW_ATL_A0_TXD_CTL_CMD_TUCSO; 483 484 if (unlikely(buff->is_eop)) { 485 txd->ctl |= HW_ATL_A0_TXD_CTL_EOP; 486 txd->ctl |= HW_ATL_A0_TXD_CTL_CMD_WB; 487 is_gso = false; 488 } 489 } 490 491 ring->sw_tail = aq_ring_next_dx(ring, ring->sw_tail); 492 } 493 494 hw_atl_a0_hw_tx_ring_tail_update(self, ring); 495 return aq_hw_err_from_flags(self); 496 } 497 498 static int hw_atl_a0_hw_ring_rx_init(struct aq_hw_s *self, 499 struct aq_ring_s *aq_ring, 500 struct aq_ring_param_s *aq_ring_param) 501 { 502 u32 dma_desc_addr_lsw = (u32)aq_ring->dx_ring_pa; 503 u32 dma_desc_addr_msw = (u32)(((u64)aq_ring->dx_ring_pa) >> 32); 504 505 hw_atl_rdm_rx_desc_en_set(self, false, aq_ring->idx); 506 507 hw_atl_rdm_rx_desc_head_splitting_set(self, 0U, aq_ring->idx); 508 509 hw_atl_reg_rx_dma_desc_base_addresslswset(self, dma_desc_addr_lsw, 510 aq_ring->idx); 511 512 hw_atl_reg_rx_dma_desc_base_addressmswset(self, 513 dma_desc_addr_msw, 514 aq_ring->idx); 515 516 hw_atl_rdm_rx_desc_len_set(self, aq_ring->size / 8U, aq_ring->idx); 517 518 hw_atl_rdm_rx_desc_data_buff_size_set(self, 519 AQ_CFG_RX_FRAME_MAX / 1024U, 520 aq_ring->idx); 521 522 hw_atl_rdm_rx_desc_head_buff_size_set(self, 0U, aq_ring->idx); 523 hw_atl_rdm_rx_desc_head_splitting_set(self, 0U, aq_ring->idx); 524 hw_atl_rpo_rx_desc_vlan_stripping_set(self, 0U, aq_ring->idx); 525 526 /* Rx ring set mode */ 527 528 /* Mapping interrupt vector */ 529 hw_atl_itr_irq_map_rx_set(self, aq_ring_param->vec_idx, aq_ring->idx); 530 hw_atl_itr_irq_map_en_rx_set(self, true, aq_ring->idx); 531 532 hw_atl_rdm_cpu_id_set(self, aq_ring_param->cpu, aq_ring->idx); 533 hw_atl_rdm_rx_desc_dca_en_set(self, 0U, aq_ring->idx); 534 hw_atl_rdm_rx_head_dca_en_set(self, 0U, aq_ring->idx); 535 hw_atl_rdm_rx_pld_dca_en_set(self, 0U, aq_ring->idx); 536 537 return aq_hw_err_from_flags(self); 538 } 539 540 static int hw_atl_a0_hw_ring_tx_init(struct aq_hw_s *self, 541 struct aq_ring_s *aq_ring, 542 struct aq_ring_param_s *aq_ring_param) 543 { 544 u32 dma_desc_lsw_addr = (u32)aq_ring->dx_ring_pa; 545 u32 dma_desc_msw_addr = (u32)(((u64)aq_ring->dx_ring_pa) >> 32); 546 547 hw_atl_reg_tx_dma_desc_base_addresslswset(self, dma_desc_lsw_addr, 548 aq_ring->idx); 549 550 hw_atl_reg_tx_dma_desc_base_addressmswset(self, dma_desc_msw_addr, 551 aq_ring->idx); 552 553 hw_atl_tdm_tx_desc_len_set(self, aq_ring->size / 8U, aq_ring->idx); 554 555 hw_atl_a0_hw_tx_ring_tail_update(self, aq_ring); 556 557 /* Set Tx threshold */ 558 hw_atl_tdm_tx_desc_wr_wb_threshold_set(self, 0U, aq_ring->idx); 559 560 /* Mapping interrupt vector */ 561 hw_atl_itr_irq_map_tx_set(self, aq_ring_param->vec_idx, aq_ring->idx); 562 hw_atl_itr_irq_map_en_tx_set(self, true, aq_ring->idx); 563 564 hw_atl_tdm_cpu_id_set(self, aq_ring_param->cpu, aq_ring->idx); 565 hw_atl_tdm_tx_desc_dca_en_set(self, 0U, aq_ring->idx); 566 567 return aq_hw_err_from_flags(self); 568 } 569 570 static int hw_atl_a0_hw_ring_rx_fill(struct aq_hw_s *self, 571 struct aq_ring_s *ring, 572 unsigned int sw_tail_old) 573 { 574 for (; sw_tail_old != ring->sw_tail; 575 sw_tail_old = aq_ring_next_dx(ring, sw_tail_old)) { 576 struct hw_atl_rxd_s *rxd = 577 (struct hw_atl_rxd_s *)&ring->dx_ring[sw_tail_old * 578 HW_ATL_A0_RXD_SIZE]; 579 580 struct aq_ring_buff_s *buff = &ring->buff_ring[sw_tail_old]; 581 582 rxd->buf_addr = buff->pa; 583 rxd->hdr_addr = 0U; 584 } 585 586 hw_atl_reg_rx_dma_desc_tail_ptr_set(self, sw_tail_old, ring->idx); 587 588 return aq_hw_err_from_flags(self); 589 } 590 591 static int hw_atl_a0_hw_ring_tx_head_update(struct aq_hw_s *self, 592 struct aq_ring_s *ring) 593 { 594 int err = 0; 595 unsigned int hw_head = hw_atl_tdm_tx_desc_head_ptr_get(self, ring->idx); 596 597 if (aq_utils_obj_test(&self->flags, AQ_HW_FLAG_ERR_UNPLUG)) { 598 err = -ENXIO; 599 goto err_exit; 600 } 601 ring->hw_head = hw_head; 602 err = aq_hw_err_from_flags(self); 603 604 err_exit: 605 return err; 606 } 607 608 static int hw_atl_a0_hw_ring_rx_receive(struct aq_hw_s *self, 609 struct aq_ring_s *ring) 610 { 611 struct device *ndev = aq_nic_get_dev(ring->aq_nic); 612 613 for (; ring->hw_head != ring->sw_tail; 614 ring->hw_head = aq_ring_next_dx(ring, ring->hw_head)) { 615 struct aq_ring_buff_s *buff = NULL; 616 struct hw_atl_rxd_wb_s *rxd_wb = (struct hw_atl_rxd_wb_s *) 617 &ring->dx_ring[ring->hw_head * HW_ATL_A0_RXD_SIZE]; 618 619 unsigned int is_err = 1U; 620 unsigned int is_rx_check_sum_enabled = 0U; 621 unsigned int pkt_type = 0U; 622 623 if (!(rxd_wb->status & 0x5U)) { /* RxD is not done */ 624 if ((1U << 4) & 625 hw_atl_reg_rx_dma_desc_status_get(self, ring->idx)) { 626 hw_atl_rdm_rx_desc_en_set(self, false, ring->idx); 627 hw_atl_rdm_rx_desc_res_set(self, true, ring->idx); 628 hw_atl_rdm_rx_desc_res_set(self, false, ring->idx); 629 hw_atl_rdm_rx_desc_en_set(self, true, ring->idx); 630 } 631 632 if (ring->hw_head || 633 (hw_atl_rdm_rx_desc_head_ptr_get(self, 634 ring->idx) < 2U)) { 635 break; 636 } else if (!(rxd_wb->status & 0x1U)) { 637 struct hw_atl_rxd_wb_s *rxd_wb1 = 638 (struct hw_atl_rxd_wb_s *) 639 (&ring->dx_ring[(1U) * 640 HW_ATL_A0_RXD_SIZE]); 641 642 if ((rxd_wb1->status & 0x1U)) { 643 rxd_wb->pkt_len = 1514U; 644 rxd_wb->status = 3U; 645 } else { 646 break; 647 } 648 } 649 } 650 651 buff = &ring->buff_ring[ring->hw_head]; 652 653 if (0x3U != (rxd_wb->status & 0x3U)) 654 rxd_wb->status |= 4; 655 656 is_err = (0x0000001CU & rxd_wb->status); 657 is_rx_check_sum_enabled = (rxd_wb->type) & (0x3U << 19); 658 pkt_type = 0xFFU & (rxd_wb->type >> 4); 659 660 if (is_rx_check_sum_enabled) { 661 if (0x0U == (pkt_type & 0x3U)) 662 buff->is_ip_cso = (is_err & 0x08U) ? 0 : 1; 663 664 if (0x4U == (pkt_type & 0x1CU)) 665 buff->is_udp_cso = (is_err & 0x10U) ? 0 : 1; 666 else if (0x0U == (pkt_type & 0x1CU)) 667 buff->is_tcp_cso = (is_err & 0x10U) ? 0 : 1; 668 669 /* Checksum offload workaround for small packets */ 670 if (rxd_wb->pkt_len <= 60) { 671 buff->is_ip_cso = 0U; 672 buff->is_cso_err = 0U; 673 } 674 } 675 676 is_err &= ~0x18U; 677 is_err &= ~0x04U; 678 679 dma_unmap_page(ndev, buff->pa, buff->len, DMA_FROM_DEVICE); 680 681 if (is_err || rxd_wb->type & 0x1000U) { 682 /* status error or DMA error */ 683 buff->is_error = 1U; 684 } else { 685 if (self->aq_nic_cfg->is_rss) { 686 /* last 4 byte */ 687 u16 rss_type = rxd_wb->type & 0xFU; 688 689 if (rss_type && rss_type < 0x8U) { 690 buff->is_hash_l4 = (rss_type == 0x4 || 691 rss_type == 0x5); 692 buff->rss_hash = rxd_wb->rss_hash; 693 } 694 } 695 696 if (HW_ATL_A0_RXD_WB_STAT2_EOP & rxd_wb->status) { 697 buff->len = rxd_wb->pkt_len % 698 AQ_CFG_RX_FRAME_MAX; 699 buff->len = buff->len ? 700 buff->len : AQ_CFG_RX_FRAME_MAX; 701 buff->next = 0U; 702 buff->is_eop = 1U; 703 } else { 704 /* jumbo */ 705 buff->next = aq_ring_next_dx(ring, 706 ring->hw_head); 707 ++ring->stats.rx.jumbo_packets; 708 } 709 } 710 } 711 712 return aq_hw_err_from_flags(self); 713 } 714 715 static int hw_atl_a0_hw_irq_enable(struct aq_hw_s *self, u64 mask) 716 { 717 hw_atl_itr_irq_msk_setlsw_set(self, LODWORD(mask) | 718 (1U << HW_ATL_A0_ERR_INT)); 719 return aq_hw_err_from_flags(self); 720 } 721 722 static int hw_atl_a0_hw_irq_disable(struct aq_hw_s *self, u64 mask) 723 { 724 hw_atl_itr_irq_msk_clearlsw_set(self, LODWORD(mask)); 725 hw_atl_itr_irq_status_clearlsw_set(self, LODWORD(mask)); 726 727 if ((1U << 16) & hw_atl_reg_gen_irq_status_get(self)) 728 atomic_inc(&self->dpc); 729 730 return aq_hw_err_from_flags(self); 731 } 732 733 static int hw_atl_a0_hw_irq_read(struct aq_hw_s *self, u64 *mask) 734 { 735 *mask = hw_atl_itr_irq_statuslsw_get(self); 736 return aq_hw_err_from_flags(self); 737 } 738 739 #define IS_FILTER_ENABLED(_F_) ((packet_filter & (_F_)) ? 1U : 0U) 740 741 static int hw_atl_a0_hw_packet_filter_set(struct aq_hw_s *self, 742 unsigned int packet_filter) 743 { 744 unsigned int i = 0U; 745 746 hw_atl_rpfl2promiscuous_mode_en_set(self, 747 IS_FILTER_ENABLED(IFF_PROMISC)); 748 hw_atl_rpfl2multicast_flr_en_set(self, 749 IS_FILTER_ENABLED(IFF_MULTICAST), 0); 750 hw_atl_rpfl2broadcast_en_set(self, IS_FILTER_ENABLED(IFF_BROADCAST)); 751 752 self->aq_nic_cfg->is_mc_list_enabled = 753 IS_FILTER_ENABLED(IFF_MULTICAST); 754 755 for (i = HW_ATL_A0_MAC_MIN; i < HW_ATL_A0_MAC_MAX; ++i) 756 hw_atl_rpfl2_uc_flr_en_set(self, 757 (self->aq_nic_cfg->is_mc_list_enabled && 758 (i <= self->aq_nic_cfg->mc_list_count)) ? 759 1U : 0U, i); 760 761 return aq_hw_err_from_flags(self); 762 } 763 764 #undef IS_FILTER_ENABLED 765 766 static int hw_atl_a0_hw_multicast_list_set(struct aq_hw_s *self, 767 u8 ar_mac 768 [AQ_HW_MULTICAST_ADDRESS_MAX] 769 [ETH_ALEN], 770 u32 count) 771 { 772 int err = 0; 773 774 if (count > (HW_ATL_A0_MAC_MAX - HW_ATL_A0_MAC_MIN)) { 775 err = EBADRQC; 776 goto err_exit; 777 } 778 for (self->aq_nic_cfg->mc_list_count = 0U; 779 self->aq_nic_cfg->mc_list_count < count; 780 ++self->aq_nic_cfg->mc_list_count) { 781 u32 i = self->aq_nic_cfg->mc_list_count; 782 u32 h = (ar_mac[i][0] << 8) | (ar_mac[i][1]); 783 u32 l = (ar_mac[i][2] << 24) | (ar_mac[i][3] << 16) | 784 (ar_mac[i][4] << 8) | ar_mac[i][5]; 785 786 hw_atl_rpfl2_uc_flr_en_set(self, 0U, HW_ATL_A0_MAC_MIN + i); 787 788 hw_atl_rpfl2unicast_dest_addresslsw_set(self, 789 l, 790 HW_ATL_A0_MAC_MIN + i); 791 792 hw_atl_rpfl2unicast_dest_addressmsw_set(self, 793 h, 794 HW_ATL_A0_MAC_MIN + i); 795 796 hw_atl_rpfl2_uc_flr_en_set(self, 797 (self->aq_nic_cfg->is_mc_list_enabled), 798 HW_ATL_A0_MAC_MIN + i); 799 } 800 801 err = aq_hw_err_from_flags(self); 802 803 err_exit: 804 return err; 805 } 806 807 static int hw_atl_a0_hw_interrupt_moderation_set(struct aq_hw_s *self) 808 { 809 unsigned int i = 0U; 810 u32 itr_rx; 811 812 if (self->aq_nic_cfg->itr) { 813 if (self->aq_nic_cfg->itr != AQ_CFG_INTERRUPT_MODERATION_AUTO) { 814 u32 itr_ = (self->aq_nic_cfg->itr >> 1); 815 816 itr_ = min(AQ_CFG_IRQ_MASK, itr_); 817 818 itr_rx = 0x80000000U | (itr_ << 0x10); 819 } else { 820 u32 n = 0xFFFFU & aq_hw_read_reg(self, 0x00002A00U); 821 822 if (n < self->aq_link_status.mbps) { 823 itr_rx = 0U; 824 } else { 825 static unsigned int hw_timers_tbl_[] = { 826 0x01CU, /* 10Gbit */ 827 0x039U, /* 5Gbit */ 828 0x039U, /* 5Gbit 5GS */ 829 0x073U, /* 2.5Gbit */ 830 0x120U, /* 1Gbit */ 831 0x1FFU, /* 100Mbit */ 832 }; 833 834 unsigned int speed_index = 835 hw_atl_utils_mbps_2_speed_index( 836 self->aq_link_status.mbps); 837 838 itr_rx = 0x80000000U | 839 (hw_timers_tbl_[speed_index] << 0x10U); 840 } 841 842 aq_hw_write_reg(self, 0x00002A00U, 0x40000000U); 843 aq_hw_write_reg(self, 0x00002A00U, 0x8D000000U); 844 } 845 } else { 846 itr_rx = 0U; 847 } 848 849 for (i = HW_ATL_A0_RINGS_MAX; i--;) 850 hw_atl_reg_irq_thr_set(self, itr_rx, i); 851 852 return aq_hw_err_from_flags(self); 853 } 854 855 static int hw_atl_a0_hw_stop(struct aq_hw_s *self) 856 { 857 hw_atl_a0_hw_irq_disable(self, HW_ATL_A0_INT_MASK); 858 return aq_hw_err_from_flags(self); 859 } 860 861 static int hw_atl_a0_hw_ring_tx_stop(struct aq_hw_s *self, 862 struct aq_ring_s *ring) 863 { 864 hw_atl_tdm_tx_desc_en_set(self, 0U, ring->idx); 865 return aq_hw_err_from_flags(self); 866 } 867 868 static int hw_atl_a0_hw_ring_rx_stop(struct aq_hw_s *self, 869 struct aq_ring_s *ring) 870 { 871 hw_atl_rdm_rx_desc_en_set(self, 0U, ring->idx); 872 return aq_hw_err_from_flags(self); 873 } 874 875 const struct aq_hw_ops hw_atl_ops_a0 = { 876 .hw_set_mac_address = hw_atl_a0_hw_mac_addr_set, 877 .hw_init = hw_atl_a0_hw_init, 878 .hw_deinit = hw_atl_utils_hw_deinit, 879 .hw_set_power = hw_atl_utils_hw_set_power, 880 .hw_reset = hw_atl_a0_hw_reset, 881 .hw_start = hw_atl_a0_hw_start, 882 .hw_ring_tx_start = hw_atl_a0_hw_ring_tx_start, 883 .hw_ring_tx_stop = hw_atl_a0_hw_ring_tx_stop, 884 .hw_ring_rx_start = hw_atl_a0_hw_ring_rx_start, 885 .hw_ring_rx_stop = hw_atl_a0_hw_ring_rx_stop, 886 .hw_stop = hw_atl_a0_hw_stop, 887 888 .hw_ring_tx_xmit = hw_atl_a0_hw_ring_tx_xmit, 889 .hw_ring_tx_head_update = hw_atl_a0_hw_ring_tx_head_update, 890 891 .hw_ring_rx_receive = hw_atl_a0_hw_ring_rx_receive, 892 .hw_ring_rx_fill = hw_atl_a0_hw_ring_rx_fill, 893 894 .hw_irq_enable = hw_atl_a0_hw_irq_enable, 895 .hw_irq_disable = hw_atl_a0_hw_irq_disable, 896 .hw_irq_read = hw_atl_a0_hw_irq_read, 897 898 .hw_ring_rx_init = hw_atl_a0_hw_ring_rx_init, 899 .hw_ring_tx_init = hw_atl_a0_hw_ring_tx_init, 900 .hw_packet_filter_set = hw_atl_a0_hw_packet_filter_set, 901 .hw_multicast_list_set = hw_atl_a0_hw_multicast_list_set, 902 .hw_interrupt_moderation_set = hw_atl_a0_hw_interrupt_moderation_set, 903 .hw_rss_set = hw_atl_a0_hw_rss_set, 904 .hw_rss_hash_set = hw_atl_a0_hw_rss_hash_set, 905 .hw_get_regs = hw_atl_utils_hw_get_regs, 906 .hw_get_hw_stats = hw_atl_utils_get_hw_stats, 907 .hw_get_fw_version = hw_atl_utils_get_fw_version, 908 }; 909