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