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