1 // SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0) 2 /* Copyright (C) 2014-2017 aQuantia Corporation. */ 3 4 /* File hw_atl_utils.c: Definition of common functions for Atlantic hardware 5 * abstraction layer. 6 */ 7 8 #include <stdio.h> 9 #include <errno.h> 10 #include <stdint.h> 11 #include <string.h> 12 #include <unistd.h> 13 #include <stdarg.h> 14 #include <inttypes.h> 15 #include <rte_ether.h> 16 #include "../atl_hw_regs.h" 17 18 #include "hw_atl_llh.h" 19 #include "hw_atl_llh_internal.h" 20 #include "../atl_logs.h" 21 22 #define HW_ATL_UCP_0X370_REG 0x0370U 23 24 #define HW_ATL_MIF_CMD 0x0200U 25 #define HW_ATL_MIF_ADDR 0x0208U 26 #define HW_ATL_MIF_VAL 0x020CU 27 28 #define HW_ATL_FW_SM_RAM 0x2U 29 #define HW_ATL_MPI_FW_VERSION 0x18 30 #define HW_ATL_MPI_CONTROL_ADR 0x0368U 31 #define HW_ATL_MPI_STATE_ADR 0x036CU 32 33 #define HW_ATL_MPI_STATE_MSK 0x00FFU 34 #define HW_ATL_MPI_STATE_SHIFT 0U 35 #define HW_ATL_MPI_SPEED_MSK 0x00FF0000U 36 #define HW_ATL_MPI_SPEED_SHIFT 16U 37 #define HW_ATL_MPI_DIRTY_WAKE_MSK 0x02000000U 38 39 #define HW_ATL_MPI_DAISY_CHAIN_STATUS 0x704 40 #define HW_ATL_MPI_BOOT_EXIT_CODE 0x388 41 42 #define HW_ATL_MAC_PHY_CONTROL 0x4000 43 #define HW_ATL_MAC_PHY_MPI_RESET_BIT 0x1D 44 45 #define HW_ATL_FW_VER_1X 0x01050006U 46 #define HW_ATL_FW_VER_2X 0x02000000U 47 #define HW_ATL_FW_VER_3X 0x03000000U 48 49 #define FORCE_FLASHLESS 0 50 51 static int hw_atl_utils_ver_match(u32 ver_expected, u32 ver_actual); 52 static int hw_atl_utils_mpi_set_state(struct aq_hw_s *self, 53 enum hal_atl_utils_fw_state_e state); 54 55 56 int hw_atl_utils_initfw(struct aq_hw_s *self, const struct aq_fw_ops **fw_ops) 57 { 58 int err = 0; 59 60 err = hw_atl_utils_soft_reset(self); 61 if (err) 62 return err; 63 64 hw_atl_utils_hw_chip_features_init(self, 65 &self->chip_features); 66 67 hw_atl_utils_get_fw_version(self, &self->fw_ver_actual); 68 69 if (hw_atl_utils_ver_match(HW_ATL_FW_VER_1X, 70 self->fw_ver_actual) == 0) { 71 *fw_ops = &aq_fw_1x_ops; 72 } else if (hw_atl_utils_ver_match(HW_ATL_FW_VER_2X, 73 self->fw_ver_actual) == 0) { 74 *fw_ops = &aq_fw_2x_ops; 75 } else if (hw_atl_utils_ver_match(HW_ATL_FW_VER_3X, 76 self->fw_ver_actual) == 0) { 77 *fw_ops = &aq_fw_2x_ops; 78 } else { 79 PMD_DRV_LOG(ERR, "Bad FW version detected: %x\n", 80 self->fw_ver_actual); 81 return -EOPNOTSUPP; 82 } 83 self->aq_fw_ops = *fw_ops; 84 err = self->aq_fw_ops->init(self); 85 return err; 86 } 87 88 static int hw_atl_utils_soft_reset_flb(struct aq_hw_s *self) 89 { 90 u32 gsr, val; 91 int k = 0; 92 93 aq_hw_write_reg(self, 0x404, 0x40e1); 94 AQ_HW_SLEEP(50); 95 96 /* Cleanup SPI */ 97 val = aq_hw_read_reg(self, 0x53C); 98 aq_hw_write_reg(self, 0x53C, val | 0x10); 99 100 gsr = aq_hw_read_reg(self, HW_ATL_GLB_SOFT_RES_ADR); 101 aq_hw_write_reg(self, HW_ATL_GLB_SOFT_RES_ADR, (gsr & 0xBFFF) | 0x8000); 102 103 /* Kickstart MAC */ 104 aq_hw_write_reg(self, 0x404, 0x80e0); 105 aq_hw_write_reg(self, 0x32a8, 0x0); 106 aq_hw_write_reg(self, 0x520, 0x1); 107 108 /* Reset SPI again because of possible interrupted SPI burst */ 109 val = aq_hw_read_reg(self, 0x53C); 110 aq_hw_write_reg(self, 0x53C, val | 0x10); 111 AQ_HW_SLEEP(10); 112 /* Clear SPI reset state */ 113 aq_hw_write_reg(self, 0x53C, val & ~0x10); 114 115 aq_hw_write_reg(self, 0x404, 0x180e0); 116 117 for (k = 0; k < 1000; k++) { 118 u32 flb_status = aq_hw_read_reg(self, 119 HW_ATL_MPI_DAISY_CHAIN_STATUS); 120 121 flb_status = flb_status & 0x10; 122 if (flb_status) 123 break; 124 AQ_HW_SLEEP(10); 125 } 126 if (k == 1000) { 127 PMD_DRV_LOG(ERR, "MAC kickstart failed\n"); 128 return -EIO; 129 } 130 131 /* FW reset */ 132 aq_hw_write_reg(self, 0x404, 0x80e0); 133 AQ_HW_SLEEP(50); 134 aq_hw_write_reg(self, 0x3a0, 0x1); 135 136 /* Kickstart PHY - skipped */ 137 138 /* Global software reset*/ 139 hw_atl_rx_rx_reg_res_dis_set(self, 0U); 140 hw_atl_tx_tx_reg_res_dis_set(self, 0U); 141 aq_hw_write_reg_bit(self, HW_ATL_MAC_PHY_CONTROL, 142 BIT(HW_ATL_MAC_PHY_MPI_RESET_BIT), 143 HW_ATL_MAC_PHY_MPI_RESET_BIT, 0x0); 144 gsr = aq_hw_read_reg(self, HW_ATL_GLB_SOFT_RES_ADR); 145 aq_hw_write_reg(self, HW_ATL_GLB_SOFT_RES_ADR, (gsr & 0xBFFF) | 0x8000); 146 147 for (k = 0; k < 1000; k++) { 148 u32 fw_state = aq_hw_read_reg(self, HW_ATL_MPI_FW_VERSION); 149 150 if (fw_state) 151 break; 152 AQ_HW_SLEEP(10); 153 } 154 if (k == 1000) { 155 PMD_DRV_LOG(ERR, "FW kickstart failed\n"); 156 return -EIO; 157 } 158 /* Old FW requires fixed delay after init */ 159 AQ_HW_SLEEP(15); 160 161 return 0; 162 } 163 164 static int hw_atl_utils_soft_reset_rbl(struct aq_hw_s *self) 165 { 166 u32 gsr, val, rbl_status; 167 int k; 168 169 aq_hw_write_reg(self, 0x404, 0x40e1); 170 aq_hw_write_reg(self, 0x3a0, 0x1); 171 aq_hw_write_reg(self, 0x32a8, 0x0); 172 173 /* Alter RBL status */ 174 aq_hw_write_reg(self, 0x388, 0xDEAD); 175 176 /* Cleanup SPI */ 177 val = aq_hw_read_reg(self, 0x53C); 178 aq_hw_write_reg(self, 0x53C, val | 0x10); 179 180 /* Global software reset*/ 181 hw_atl_rx_rx_reg_res_dis_set(self, 0U); 182 hw_atl_tx_tx_reg_res_dis_set(self, 0U); 183 aq_hw_write_reg_bit(self, HW_ATL_MAC_PHY_CONTROL, 184 BIT(HW_ATL_MAC_PHY_MPI_RESET_BIT), 185 HW_ATL_MAC_PHY_MPI_RESET_BIT, 0x0); 186 gsr = aq_hw_read_reg(self, HW_ATL_GLB_SOFT_RES_ADR); 187 aq_hw_write_reg(self, HW_ATL_GLB_SOFT_RES_ADR, 188 (gsr & 0xFFFFBFFF) | 0x8000); 189 190 if (FORCE_FLASHLESS) 191 aq_hw_write_reg(self, 0x534, 0x0); 192 193 aq_hw_write_reg(self, 0x404, 0x40e0); 194 195 /* Wait for RBL boot */ 196 for (k = 0; k < 1000; k++) { 197 rbl_status = aq_hw_read_reg(self, 0x388) & 0xFFFF; 198 if (rbl_status && rbl_status != 0xDEAD) 199 break; 200 AQ_HW_SLEEP(10); 201 } 202 if (!rbl_status || rbl_status == 0xDEAD) { 203 PMD_DRV_LOG(ERR, "RBL Restart failed"); 204 return -EIO; 205 } 206 207 /* Restore NVR */ 208 if (FORCE_FLASHLESS) 209 aq_hw_write_reg(self, 0x534, 0xA0); 210 211 if (rbl_status == 0xF1A7) { 212 PMD_DRV_LOG(ERR, "No FW detected. Dynamic FW load not implemented\n"); 213 return -EOPNOTSUPP; 214 } 215 216 for (k = 0; k < 1000; k++) { 217 u32 fw_state = aq_hw_read_reg(self, HW_ATL_MPI_FW_VERSION); 218 219 if (fw_state) 220 break; 221 AQ_HW_SLEEP(10); 222 } 223 if (k == 1000) { 224 PMD_DRV_LOG(ERR, "FW kickstart failed\n"); 225 return -EIO; 226 } 227 /* Old FW requires fixed delay after init */ 228 AQ_HW_SLEEP(15); 229 230 return 0; 231 } 232 233 int hw_atl_utils_soft_reset(struct aq_hw_s *self) 234 { 235 int err = 0; 236 int k; 237 u32 boot_exit_code = 0; 238 239 for (k = 0; k < 1000; ++k) { 240 u32 flb_status = aq_hw_read_reg(self, 241 HW_ATL_MPI_DAISY_CHAIN_STATUS); 242 boot_exit_code = aq_hw_read_reg(self, 243 HW_ATL_MPI_BOOT_EXIT_CODE); 244 if (flb_status != 0x06000000 || boot_exit_code != 0) 245 break; 246 } 247 248 if (k == 1000) { 249 PMD_DRV_LOG(ERR, "Neither RBL nor FLB firmware started\n"); 250 return -EOPNOTSUPP; 251 } 252 253 self->rbl_enabled = (boot_exit_code != 0); 254 255 /* FW 1.x may bootup in an invalid POWER state (WOL feature). 256 * We should work around this by forcing its state back to DEINIT 257 */ 258 if (!hw_atl_utils_ver_match(HW_ATL_FW_VER_1X, 259 aq_hw_read_reg(self, 260 HW_ATL_MPI_FW_VERSION))) { 261 hw_atl_utils_mpi_set_state(self, MPI_DEINIT); 262 AQ_HW_WAIT_FOR((aq_hw_read_reg(self, HW_ATL_MPI_STATE_ADR) & 263 HW_ATL_MPI_STATE_MSK) == MPI_DEINIT, 264 10, 1000U); 265 } 266 267 if (self->rbl_enabled) 268 err = hw_atl_utils_soft_reset_rbl(self); 269 else 270 err = hw_atl_utils_soft_reset_flb(self); 271 272 return err; 273 } 274 275 int hw_atl_utils_fw_downld_dwords(struct aq_hw_s *self, u32 a, 276 u32 *p, u32 cnt) 277 { 278 int err = 0; 279 280 AQ_HW_WAIT_FOR(hw_atl_reg_glb_cpu_sem_get(self, 281 HW_ATL_FW_SM_RAM) == 1U, 282 1U, 10000U); 283 284 if (err < 0) { 285 bool is_locked; 286 287 hw_atl_reg_glb_cpu_sem_set(self, 1U, HW_ATL_FW_SM_RAM); 288 is_locked = hw_atl_reg_glb_cpu_sem_get(self, HW_ATL_FW_SM_RAM); 289 if (!is_locked) { 290 err = -ETIMEDOUT; 291 goto err_exit; 292 } 293 } 294 295 aq_hw_write_reg(self, HW_ATL_MIF_ADDR, a); 296 297 for (++cnt; --cnt && !err;) { 298 aq_hw_write_reg(self, HW_ATL_MIF_CMD, 0x00008000U); 299 300 if (IS_CHIP_FEATURE(REVISION_B1)) 301 AQ_HW_WAIT_FOR(a != aq_hw_read_reg(self, 302 HW_ATL_MIF_ADDR), 303 1, 1000U); 304 else 305 AQ_HW_WAIT_FOR(!(0x100 & aq_hw_read_reg(self, 306 HW_ATL_MIF_CMD)), 307 1, 1000U); 308 if (err) { 309 err = -ETIMEDOUT; 310 goto err_exit; 311 } 312 313 *(p++) = aq_hw_read_reg(self, HW_ATL_MIF_VAL); 314 a += 4; 315 } 316 317 hw_atl_reg_glb_cpu_sem_set(self, 1U, HW_ATL_FW_SM_RAM); 318 319 err_exit: 320 return err; 321 } 322 323 int hw_atl_utils_fw_upload_dwords(struct aq_hw_s *self, u32 a, u32 *p, 324 u32 cnt) 325 { 326 int err = 0; 327 bool is_locked; 328 329 is_locked = hw_atl_reg_glb_cpu_sem_get(self, HW_ATL_FW_SM_RAM); 330 if (!is_locked) { 331 err = -ETIMEDOUT; 332 goto err_exit; 333 } 334 if (IS_CHIP_FEATURE(REVISION_B1)) { 335 u32 offset = 0; 336 337 for (; offset < cnt; ++offset) { 338 aq_hw_write_reg(self, 0x328, p[offset]); 339 aq_hw_write_reg(self, 0x32C, 340 (0x80000000 | (0xFFFF & (offset * 4)))); 341 hw_atl_mcp_up_force_intr_set(self, 1); 342 /* 1000 times by 10us = 10ms */ 343 AQ_HW_WAIT_FOR((aq_hw_read_reg(self, 344 0x32C) & 0xF0000000) != 0x80000000, 345 10, 1000); 346 } 347 } else { 348 u32 offset = 0; 349 350 aq_hw_write_reg(self, 0x208, a); 351 352 for (; offset < cnt; ++offset) { 353 aq_hw_write_reg(self, 0x20C, p[offset]); 354 aq_hw_write_reg(self, 0x200, 0xC000); 355 356 AQ_HW_WAIT_FOR((aq_hw_read_reg(self, 0x200U) 357 & 0x100) == 0, 10, 1000); 358 } 359 } 360 361 hw_atl_reg_glb_cpu_sem_set(self, 1U, HW_ATL_FW_SM_RAM); 362 363 err_exit: 364 return err; 365 } 366 367 static int hw_atl_utils_ver_match(u32 ver_expected, u32 ver_actual) 368 { 369 int err = 0; 370 const u32 dw_major_mask = 0xff000000U; 371 const u32 dw_minor_mask = 0x00ffffffU; 372 373 err = (dw_major_mask & (ver_expected ^ ver_actual)) ? -EOPNOTSUPP : 0; 374 if (err < 0) 375 goto err_exit; 376 err = ((dw_minor_mask & ver_expected) > (dw_minor_mask & ver_actual)) ? 377 -EOPNOTSUPP : 0; 378 err_exit: 379 return err; 380 } 381 382 static int hw_atl_utils_init_ucp(struct aq_hw_s *self) 383 { 384 int err = 0; 385 386 if (!aq_hw_read_reg(self, 0x370U)) { 387 unsigned int rnd = (uint32_t)rte_rand(); 388 unsigned int ucp_0x370 = 0U; 389 390 ucp_0x370 = 0x02020202U | (0xFEFEFEFEU & rnd); 391 aq_hw_write_reg(self, HW_ATL_UCP_0X370_REG, ucp_0x370); 392 } 393 394 hw_atl_reg_glb_cpu_scratch_scp_set(self, 0x00000000U, 25U); 395 396 /* check 10 times by 1ms */ 397 AQ_HW_WAIT_FOR(0U != (self->mbox_addr = 398 aq_hw_read_reg(self, 0x360U)), 1000U, 10U); 399 AQ_HW_WAIT_FOR(0U != (self->rpc_addr = 400 aq_hw_read_reg(self, 0x334U)), 1000U, 100U); 401 402 return err; 403 } 404 405 #define HW_ATL_RPC_CONTROL_ADR 0x0338U 406 #define HW_ATL_RPC_STATE_ADR 0x033CU 407 408 struct aq_hw_atl_utils_fw_rpc_tid_s { 409 union { 410 u32 val; 411 struct { 412 u16 tid; 413 u16 len; 414 }; 415 }; 416 }; 417 418 #define hw_atl_utils_fw_rpc_init(_H_) hw_atl_utils_fw_rpc_wait(_H_, NULL) 419 420 int hw_atl_utils_fw_rpc_call(struct aq_hw_s *self, unsigned int rpc_size) 421 { 422 int err = 0; 423 struct aq_hw_atl_utils_fw_rpc_tid_s sw; 424 425 if (!IS_CHIP_FEATURE(MIPS)) { 426 err = -1; 427 goto err_exit; 428 } 429 err = hw_atl_utils_fw_upload_dwords(self, self->rpc_addr, 430 (u32 *)(void *)&self->rpc, 431 (rpc_size + sizeof(u32) - 432 sizeof(u8)) / sizeof(u32)); 433 if (err < 0) 434 goto err_exit; 435 436 sw.tid = 0xFFFFU & (++self->rpc_tid); 437 sw.len = (u16)rpc_size; 438 aq_hw_write_reg(self, HW_ATL_RPC_CONTROL_ADR, sw.val); 439 440 err_exit: 441 return err; 442 } 443 444 int hw_atl_utils_fw_rpc_wait(struct aq_hw_s *self, 445 struct hw_aq_atl_utils_fw_rpc **rpc) 446 { 447 int err = 0; 448 struct aq_hw_atl_utils_fw_rpc_tid_s sw; 449 struct aq_hw_atl_utils_fw_rpc_tid_s fw; 450 451 do { 452 sw.val = aq_hw_read_reg(self, HW_ATL_RPC_CONTROL_ADR); 453 454 self->rpc_tid = sw.tid; 455 456 AQ_HW_WAIT_FOR(sw.tid == 457 (fw.val = 458 aq_hw_read_reg(self, HW_ATL_RPC_STATE_ADR), 459 fw.tid), 1000U, 100U); 460 if (err < 0) 461 goto err_exit; 462 463 if (fw.len == 0xFFFFU) { 464 err = hw_atl_utils_fw_rpc_call(self, sw.len); 465 if (err < 0) 466 goto err_exit; 467 } 468 } while (sw.tid != fw.tid || 0xFFFFU == fw.len); 469 470 if (rpc) { 471 if (fw.len) { 472 err = 473 hw_atl_utils_fw_downld_dwords(self, 474 self->rpc_addr, 475 (u32 *)(void *) 476 &self->rpc, 477 (fw.len + sizeof(u32) - 478 sizeof(u8)) / 479 sizeof(u32)); 480 if (err < 0) 481 goto err_exit; 482 } 483 484 *rpc = &self->rpc; 485 } 486 487 err_exit: 488 return err; 489 } 490 491 static int hw_atl_utils_mpi_create(struct aq_hw_s *self) 492 { 493 int err = 0; 494 495 err = hw_atl_utils_init_ucp(self); 496 if (err < 0) 497 goto err_exit; 498 499 err = hw_atl_utils_fw_rpc_init(self); 500 if (err < 0) 501 goto err_exit; 502 503 err_exit: 504 return err; 505 } 506 507 int hw_atl_utils_mpi_read_mbox(struct aq_hw_s *self, 508 struct hw_aq_atl_utils_mbox_header *pmbox) 509 { 510 return hw_atl_utils_fw_downld_dwords(self, 511 self->mbox_addr, 512 (u32 *)(void *)pmbox, 513 sizeof(*pmbox) / sizeof(u32)); 514 } 515 516 void hw_atl_utils_mpi_read_stats(struct aq_hw_s *self, 517 struct hw_aq_atl_utils_mbox *pmbox) 518 { 519 int err = 0; 520 521 err = hw_atl_utils_fw_downld_dwords(self, 522 self->mbox_addr, 523 (u32 *)(void *)pmbox, 524 sizeof(*pmbox) / sizeof(u32)); 525 if (err < 0) 526 goto err_exit; 527 528 if (IS_CHIP_FEATURE(REVISION_A0)) { 529 unsigned int mtu = 1514; 530 pmbox->stats.ubrc = pmbox->stats.uprc * mtu; 531 pmbox->stats.ubtc = pmbox->stats.uptc * mtu; 532 } else { 533 pmbox->stats.dpc = hw_atl_rpb_rx_dma_drop_pkt_cnt_get(self); 534 } 535 536 err_exit:; 537 } 538 539 static 540 int hw_atl_utils_mpi_set_speed(struct aq_hw_s *self, u32 speed) 541 { 542 u32 val = aq_hw_read_reg(self, HW_ATL_MPI_CONTROL_ADR); 543 544 val = val & ~HW_ATL_MPI_SPEED_MSK; 545 val |= speed << HW_ATL_MPI_SPEED_SHIFT; 546 aq_hw_write_reg(self, HW_ATL_MPI_CONTROL_ADR, val); 547 548 return 0; 549 } 550 551 int hw_atl_utils_mpi_set_state(struct aq_hw_s *self, 552 enum hal_atl_utils_fw_state_e state) 553 { 554 int err = 0; 555 u32 transaction_id = 0; 556 struct hw_aq_atl_utils_mbox_header mbox; 557 u32 val = aq_hw_read_reg(self, HW_ATL_MPI_CONTROL_ADR); 558 559 if (state == MPI_RESET) { 560 hw_atl_utils_mpi_read_mbox(self, &mbox); 561 562 transaction_id = mbox.transaction_id; 563 564 AQ_HW_WAIT_FOR(transaction_id != 565 (hw_atl_utils_mpi_read_mbox(self, &mbox), 566 mbox.transaction_id), 567 1000U, 100U); 568 if (err < 0) 569 goto err_exit; 570 } 571 /* On interface DEINIT we disable DW (raise bit) 572 * Otherwise enable DW (clear bit) 573 */ 574 if (state == MPI_DEINIT || state == MPI_POWER) 575 val |= HW_ATL_MPI_DIRTY_WAKE_MSK; 576 else 577 val &= ~HW_ATL_MPI_DIRTY_WAKE_MSK; 578 579 /* Set new state bits */ 580 val = val & ~HW_ATL_MPI_STATE_MSK; 581 val |= state & HW_ATL_MPI_STATE_MSK; 582 583 aq_hw_write_reg(self, HW_ATL_MPI_CONTROL_ADR, val); 584 err_exit: 585 return err; 586 } 587 588 int hw_atl_utils_mpi_get_link_status(struct aq_hw_s *self) 589 { 590 u32 cp0x036C = aq_hw_read_reg(self, HW_ATL_MPI_STATE_ADR); 591 u32 link_speed_mask = cp0x036C >> HW_ATL_MPI_SPEED_SHIFT; 592 struct aq_hw_link_status_s *link_status = &self->aq_link_status; 593 594 if (!link_speed_mask) { 595 link_status->mbps = 0U; 596 } else { 597 switch (link_speed_mask) { 598 case HAL_ATLANTIC_RATE_10G: 599 link_status->mbps = 10000U; 600 break; 601 602 case HAL_ATLANTIC_RATE_5G: 603 case HAL_ATLANTIC_RATE_5GSR: 604 link_status->mbps = 5000U; 605 break; 606 607 case HAL_ATLANTIC_RATE_2GS: 608 link_status->mbps = 2500U; 609 break; 610 611 case HAL_ATLANTIC_RATE_1G: 612 link_status->mbps = 1000U; 613 break; 614 615 case HAL_ATLANTIC_RATE_100M: 616 link_status->mbps = 100U; 617 break; 618 619 default: 620 return -EBUSY; 621 } 622 } 623 624 return 0; 625 } 626 627 static int hw_atl_utils_get_mac_permanent(struct aq_hw_s *self, 628 u8 *mac) 629 { 630 int err = 0; 631 u32 h = 0U; 632 u32 l = 0U; 633 u32 mac_addr[2]; 634 635 if (!aq_hw_read_reg(self, HW_ATL_UCP_0X370_REG)) { 636 unsigned int rnd = (uint32_t)rte_rand(); 637 unsigned int ucp_0x370 = 0; 638 639 //get_random_bytes(&rnd, sizeof(unsigned int)); 640 641 ucp_0x370 = 0x02020202 | (0xFEFEFEFE & rnd); 642 aq_hw_write_reg(self, HW_ATL_UCP_0X370_REG, ucp_0x370); 643 } 644 645 err = hw_atl_utils_fw_downld_dwords(self, 646 aq_hw_read_reg(self, 0x00000374U) + 647 (40U * 4U), 648 mac_addr, 649 ARRAY_SIZE(mac_addr)); 650 if (err < 0) { 651 mac_addr[0] = 0U; 652 mac_addr[1] = 0U; 653 err = 0; 654 } else { 655 mac_addr[0] = rte_constant_bswap32(mac_addr[0]); 656 mac_addr[1] = rte_constant_bswap32(mac_addr[1]); 657 } 658 659 ether_addr_copy((struct ether_addr *)mac_addr, 660 (struct ether_addr *)mac); 661 662 if ((mac[0] & 0x01U) || ((mac[0] | mac[1] | mac[2]) == 0x00U)) { 663 /* chip revision */ 664 l = 0xE3000000U 665 | (0xFFFFU & aq_hw_read_reg(self, HW_ATL_UCP_0X370_REG)) 666 | (0x00 << 16); 667 h = 0x8001300EU; 668 669 mac[5] = (u8)(0xFFU & l); 670 l >>= 8; 671 mac[4] = (u8)(0xFFU & l); 672 l >>= 8; 673 mac[3] = (u8)(0xFFU & l); 674 l >>= 8; 675 mac[2] = (u8)(0xFFU & l); 676 mac[1] = (u8)(0xFFU & h); 677 h >>= 8; 678 mac[0] = (u8)(0xFFU & h); 679 } 680 681 return err; 682 } 683 684 unsigned int hw_atl_utils_mbps_2_speed_index(unsigned int mbps) 685 { 686 unsigned int ret = 0U; 687 688 switch (mbps) { 689 case 100U: 690 ret = 5U; 691 break; 692 693 case 1000U: 694 ret = 4U; 695 break; 696 697 case 2500U: 698 ret = 3U; 699 break; 700 701 case 5000U: 702 ret = 1U; 703 break; 704 705 case 10000U: 706 ret = 0U; 707 break; 708 709 default: 710 break; 711 } 712 return ret; 713 } 714 715 void hw_atl_utils_hw_chip_features_init(struct aq_hw_s *self, u32 *p) 716 { 717 u32 chip_features = 0U; 718 u32 val = hw_atl_reg_glb_mif_id_get(self); 719 u32 mif_rev = val & 0xFFU; 720 721 if ((0xFU & mif_rev) == 1U) { 722 chip_features |= HAL_ATLANTIC_UTILS_CHIP_REVISION_A0 | 723 HAL_ATLANTIC_UTILS_CHIP_MPI_AQ | 724 HAL_ATLANTIC_UTILS_CHIP_MIPS; 725 } else if ((0xFU & mif_rev) == 2U) { 726 chip_features |= HAL_ATLANTIC_UTILS_CHIP_REVISION_B0 | 727 HAL_ATLANTIC_UTILS_CHIP_MPI_AQ | 728 HAL_ATLANTIC_UTILS_CHIP_MIPS | 729 HAL_ATLANTIC_UTILS_CHIP_TPO2 | 730 HAL_ATLANTIC_UTILS_CHIP_RPF2; 731 } else if ((0xFU & mif_rev) == 0xAU) { 732 chip_features |= HAL_ATLANTIC_UTILS_CHIP_REVISION_B1 | 733 HAL_ATLANTIC_UTILS_CHIP_MPI_AQ | 734 HAL_ATLANTIC_UTILS_CHIP_MIPS | 735 HAL_ATLANTIC_UTILS_CHIP_TPO2 | 736 HAL_ATLANTIC_UTILS_CHIP_RPF2; 737 } 738 739 *p = chip_features; 740 } 741 742 static int hw_atl_fw1x_deinit(struct aq_hw_s *self) 743 { 744 hw_atl_utils_mpi_set_speed(self, 0); 745 hw_atl_utils_mpi_set_state(self, MPI_DEINIT); 746 return 0; 747 } 748 749 int hw_atl_utils_update_stats(struct aq_hw_s *self) 750 { 751 struct hw_aq_atl_utils_mbox mbox; 752 753 hw_atl_utils_mpi_read_stats(self, &mbox); 754 755 #define AQ_SDELTA(_N_) (self->curr_stats._N_ += \ 756 mbox.stats._N_ - self->last_stats._N_) 757 758 if (1) {//self->aq_link_status.mbps) { 759 AQ_SDELTA(uprc); 760 AQ_SDELTA(mprc); 761 AQ_SDELTA(bprc); 762 AQ_SDELTA(erpt); 763 764 AQ_SDELTA(uptc); 765 AQ_SDELTA(mptc); 766 AQ_SDELTA(bptc); 767 AQ_SDELTA(erpr); 768 AQ_SDELTA(ubrc); 769 AQ_SDELTA(ubtc); 770 AQ_SDELTA(mbrc); 771 AQ_SDELTA(mbtc); 772 AQ_SDELTA(bbrc); 773 AQ_SDELTA(bbtc); 774 AQ_SDELTA(dpc); 775 } 776 #undef AQ_SDELTA 777 self->curr_stats.dma_pkt_rc = 778 hw_atl_stats_rx_dma_good_pkt_counterlsw_get(self) + 779 ((u64)hw_atl_stats_rx_dma_good_pkt_countermsw_get(self) << 32); 780 self->curr_stats.dma_pkt_tc = 781 hw_atl_stats_tx_dma_good_pkt_counterlsw_get(self) + 782 ((u64)hw_atl_stats_tx_dma_good_pkt_countermsw_get(self) << 32); 783 self->curr_stats.dma_oct_rc = 784 hw_atl_stats_rx_dma_good_octet_counterlsw_get(self) + 785 ((u64)hw_atl_stats_rx_dma_good_octet_countermsw_get(self) << 32); 786 self->curr_stats.dma_oct_tc = 787 hw_atl_stats_tx_dma_good_octet_counterlsw_get(self) + 788 ((u64)hw_atl_stats_tx_dma_good_octet_countermsw_get(self) << 32); 789 790 self->curr_stats.dpc = hw_atl_rpb_rx_dma_drop_pkt_cnt_get(self); 791 792 memcpy(&self->last_stats, &mbox.stats, sizeof(mbox.stats)); 793 794 return 0; 795 } 796 797 struct aq_stats_s *hw_atl_utils_get_hw_stats(struct aq_hw_s *self) 798 { 799 return &self->curr_stats; 800 } 801 802 static const u32 hw_atl_utils_hw_mac_regs[] = { 803 0x00005580U, 0x00005590U, 0x000055B0U, 0x000055B4U, 804 0x000055C0U, 0x00005B00U, 0x00005B04U, 0x00005B08U, 805 0x00005B0CU, 0x00005B10U, 0x00005B14U, 0x00005B18U, 806 0x00005B1CU, 0x00005B20U, 0x00005B24U, 0x00005B28U, 807 0x00005B2CU, 0x00005B30U, 0x00005B34U, 0x00005B38U, 808 0x00005B3CU, 0x00005B40U, 0x00005B44U, 0x00005B48U, 809 0x00005B4CU, 0x00005B50U, 0x00005B54U, 0x00005B58U, 810 0x00005B5CU, 0x00005B60U, 0x00005B64U, 0x00005B68U, 811 0x00005B6CU, 0x00005B70U, 0x00005B74U, 0x00005B78U, 812 0x00005B7CU, 0x00007C00U, 0x00007C04U, 0x00007C08U, 813 0x00007C0CU, 0x00007C10U, 0x00007C14U, 0x00007C18U, 814 0x00007C1CU, 0x00007C20U, 0x00007C40U, 0x00007C44U, 815 0x00007C48U, 0x00007C4CU, 0x00007C50U, 0x00007C54U, 816 0x00007C58U, 0x00007C5CU, 0x00007C60U, 0x00007C80U, 817 0x00007C84U, 0x00007C88U, 0x00007C8CU, 0x00007C90U, 818 0x00007C94U, 0x00007C98U, 0x00007C9CU, 0x00007CA0U, 819 0x00007CC0U, 0x00007CC4U, 0x00007CC8U, 0x00007CCCU, 820 0x00007CD0U, 0x00007CD4U, 0x00007CD8U, 0x00007CDCU, 821 0x00007CE0U, 0x00000300U, 0x00000304U, 0x00000308U, 822 0x0000030cU, 0x00000310U, 0x00000314U, 0x00000318U, 823 0x0000031cU, 0x00000360U, 0x00000364U, 0x00000368U, 824 0x0000036cU, 0x00000370U, 0x00000374U, 0x00006900U, 825 }; 826 827 unsigned int hw_atl_utils_hw_get_reg_length(void) 828 { 829 return ARRAY_SIZE(hw_atl_utils_hw_mac_regs); 830 } 831 832 int hw_atl_utils_hw_get_regs(struct aq_hw_s *self, 833 u32 *regs_buff) 834 { 835 unsigned int i = 0U; 836 unsigned int mac_regs_count = hw_atl_utils_hw_get_reg_length(); 837 838 for (i = 0; i < mac_regs_count; i++) 839 regs_buff[i] = aq_hw_read_reg(self, 840 hw_atl_utils_hw_mac_regs[i]); 841 return 0; 842 } 843 844 int hw_atl_utils_get_fw_version(struct aq_hw_s *self, u32 *fw_version) 845 { 846 *fw_version = aq_hw_read_reg(self, 0x18U); 847 return 0; 848 } 849 850 static int aq_fw1x_set_wol(struct aq_hw_s *self, bool wol_enabled, u8 *mac) 851 { 852 struct hw_aq_atl_utils_fw_rpc *prpc = NULL; 853 unsigned int rpc_size = 0U; 854 int err = 0; 855 856 err = hw_atl_utils_fw_rpc_wait(self, &prpc); 857 if (err < 0) 858 goto err_exit; 859 860 memset(prpc, 0, sizeof(*prpc)); 861 862 if (wol_enabled) { 863 rpc_size = sizeof(prpc->msg_id) + sizeof(prpc->msg_wol); 864 865 prpc->msg_id = HAL_ATLANTIC_UTILS_FW_MSG_WOL_ADD; 866 prpc->msg_wol.priority = 0x10000000; /* normal priority */ 867 prpc->msg_wol.pattern_id = 1U; 868 prpc->msg_wol.wol_packet_type = 2U; /* Magic Packet */ 869 870 ether_addr_copy((struct ether_addr *)mac, 871 (struct ether_addr *)&prpc->msg_wol.wol_pattern); 872 } else { 873 rpc_size = sizeof(prpc->msg_id) + sizeof(prpc->msg_del_id); 874 875 prpc->msg_id = HAL_ATLANTIC_UTILS_FW_MSG_WOL_DEL; 876 prpc->msg_wol.pattern_id = 1U; 877 } 878 879 err = hw_atl_utils_fw_rpc_call(self, rpc_size); 880 881 err_exit: 882 return err; 883 } 884 885 static 886 int aq_fw1x_set_power(struct aq_hw_s *self, 887 unsigned int power_state __rte_unused, 888 u8 *mac) 889 { 890 struct hw_aq_atl_utils_fw_rpc *prpc = NULL; 891 unsigned int rpc_size = 0U; 892 int err = 0; 893 if (self->aq_nic_cfg->wol & AQ_NIC_WOL_ENABLED) { 894 err = aq_fw1x_set_wol(self, 1, mac); 895 896 if (err < 0) 897 goto err_exit; 898 899 rpc_size = sizeof(prpc->msg_id) + 900 sizeof(prpc->msg_enable_wakeup); 901 902 err = hw_atl_utils_fw_rpc_wait(self, &prpc); 903 904 if (err < 0) 905 goto err_exit; 906 907 memset(prpc, 0, rpc_size); 908 909 prpc->msg_id = HAL_ATLANTIC_UTILS_FW_MSG_ENABLE_WAKEUP; 910 prpc->msg_enable_wakeup.pattern_mask = 0x00000002; 911 912 err = hw_atl_utils_fw_rpc_call(self, rpc_size); 913 if (err < 0) 914 goto err_exit; 915 } 916 917 hw_atl_utils_mpi_set_speed(self, 0); 918 hw_atl_utils_mpi_set_state(self, MPI_POWER); 919 err_exit: 920 return err; 921 } 922 923 924 925 const struct aq_fw_ops aq_fw_1x_ops = { 926 .init = hw_atl_utils_mpi_create, 927 .deinit = hw_atl_fw1x_deinit, 928 .reset = NULL, 929 .get_mac_permanent = hw_atl_utils_get_mac_permanent, 930 .set_link_speed = hw_atl_utils_mpi_set_speed, 931 .set_state = hw_atl_utils_mpi_set_state, 932 .update_link_status = hw_atl_utils_mpi_get_link_status, 933 .update_stats = hw_atl_utils_update_stats, 934 .set_power = aq_fw1x_set_power, 935 .get_temp = NULL, 936 .get_cable_len = NULL, 937 .set_eee_rate = NULL, 938 .get_eee_rate = NULL, 939 .set_flow_control = NULL, 940 .led_control = NULL, 941 .get_eeprom = NULL, 942 .set_eeprom = NULL, 943 }; 944