root/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. hw_atl_utils_initfw
  2. hw_atl_utils_soft_reset_flb
  3. hw_atl_utils_soft_reset_rbl
  4. hw_atl_utils_soft_reset
  5. hw_atl_utils_fw_downld_dwords
  6. hw_atl_utils_fw_upload_dwords
  7. hw_atl_utils_ver_match
  8. hw_atl_utils_init_ucp
  9. hw_atl_utils_fw_rpc_call
  10. hw_atl_utils_fw_rpc_wait
  11. hw_atl_utils_mpi_create
  12. hw_atl_utils_mpi_read_mbox
  13. hw_atl_utils_mpi_read_stats
  14. hw_atl_utils_mpi_set_speed
  15. hw_atl_utils_mpi_set_state
  16. hw_atl_utils_mpi_get_link_status
  17. hw_atl_utils_get_mac_permanent
  18. hw_atl_utils_mbps_2_speed_index
  19. hw_atl_utils_hw_chip_features_init
  20. hw_atl_fw1x_deinit
  21. hw_atl_utils_update_stats
  22. hw_atl_utils_get_hw_stats
  23. hw_atl_utils_hw_get_regs
  24. hw_atl_utils_get_fw_version
  25. aq_fw1x_set_wol
  26. aq_fw1x_set_power
  27. hw_atl_utils_get_mpi_mbox_tid
  28. hw_atl_utils_mpi_get_state
  29. hw_atl_utils_mif_cmd_get
  30. hw_atl_utils_mif_addr_get
  31. hw_atl_utils_rpc_state_get
  32. aq_fw1x_rpc_get

   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_MPI_RPC_ADDR     0x0334U
  26 #define HW_ATL_RPC_CONTROL_ADR  0x0338U
  27 #define HW_ATL_RPC_STATE_ADR    0x033CU
  28 
  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 static u32 hw_atl_utils_get_mpi_mbox_tid(struct aq_hw_s *self);
  55 static u32 hw_atl_utils_mpi_get_state(struct aq_hw_s *self);
  56 static u32 hw_atl_utils_mif_cmd_get(struct aq_hw_s *self);
  57 static u32 hw_atl_utils_mif_addr_get(struct aq_hw_s *self);
  58 static u32 hw_atl_utils_rpc_state_get(struct aq_hw_s *self);
  59 static u32 aq_fw1x_rpc_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         err = readx_poll_timeout_atomic(aq_fw1x_rpc_get, self,
 417                                         self->rpc_addr,
 418                                         self->rpc_addr != 0U,
 419                                         1000U, 100000U);
 420 
 421         return err;
 422 }
 423 
 424 struct aq_hw_atl_utils_fw_rpc_tid_s {
 425         union {
 426                 u32 val;
 427                 struct {
 428                         u16 tid;
 429                         u16 len;
 430                 };
 431         };
 432 };
 433 
 434 #define hw_atl_utils_fw_rpc_init(_H_) hw_atl_utils_fw_rpc_wait(_H_, NULL)
 435 
 436 int hw_atl_utils_fw_rpc_call(struct aq_hw_s *self, unsigned int rpc_size)
 437 {
 438         int err = 0;
 439         struct aq_hw_atl_utils_fw_rpc_tid_s sw;
 440 
 441         if (!IS_CHIP_FEATURE(MIPS)) {
 442                 err = -1;
 443                 goto err_exit;
 444         }
 445         err = hw_atl_utils_fw_upload_dwords(self, self->rpc_addr,
 446                                             (u32 *)(void *)&self->rpc,
 447                                             (rpc_size + sizeof(u32) -
 448                                              sizeof(u8)) / sizeof(u32));
 449         if (err < 0)
 450                 goto err_exit;
 451 
 452         sw.tid = 0xFFFFU & (++self->rpc_tid);
 453         sw.len = (u16)rpc_size;
 454         aq_hw_write_reg(self, HW_ATL_RPC_CONTROL_ADR, sw.val);
 455 
 456 err_exit:
 457         return err;
 458 }
 459 
 460 int hw_atl_utils_fw_rpc_wait(struct aq_hw_s *self,
 461                              struct hw_atl_utils_fw_rpc **rpc)
 462 {
 463         int err = 0;
 464         struct aq_hw_atl_utils_fw_rpc_tid_s sw;
 465         struct aq_hw_atl_utils_fw_rpc_tid_s fw;
 466 
 467         do {
 468                 sw.val = aq_hw_read_reg(self, HW_ATL_RPC_CONTROL_ADR);
 469 
 470                 self->rpc_tid = sw.tid;
 471 
 472                 err = readx_poll_timeout_atomic(hw_atl_utils_rpc_state_get,
 473                                                 self, fw.val,
 474                                                 sw.tid == fw.tid,
 475                                                 1000U, 100000U);
 476                 if (err < 0)
 477                         goto err_exit;
 478 
 479                 err = aq_hw_err_from_flags(self);
 480                 if (err < 0)
 481                         goto err_exit;
 482 
 483                 if (fw.len == 0xFFFFU) {
 484                         err = hw_atl_utils_fw_rpc_call(self, sw.len);
 485                         if (err < 0)
 486                                 goto err_exit;
 487                 }
 488         } while (sw.tid != fw.tid || 0xFFFFU == fw.len);
 489 
 490         if (rpc) {
 491                 if (fw.len) {
 492                         err =
 493                         hw_atl_utils_fw_downld_dwords(self,
 494                                                       self->rpc_addr,
 495                                                       (u32 *)(void *)
 496                                                       &self->rpc,
 497                                                       (fw.len + sizeof(u32) -
 498                                                        sizeof(u8)) /
 499                                                       sizeof(u32));
 500                         if (err < 0)
 501                                 goto err_exit;
 502                 }
 503 
 504                 *rpc = &self->rpc;
 505         }
 506 
 507 err_exit:
 508         return err;
 509 }
 510 
 511 static int hw_atl_utils_mpi_create(struct aq_hw_s *self)
 512 {
 513         int err = 0;
 514 
 515         err = hw_atl_utils_init_ucp(self, self->aq_nic_cfg->aq_hw_caps);
 516         if (err < 0)
 517                 goto err_exit;
 518 
 519         err = hw_atl_utils_fw_rpc_init(self);
 520         if (err < 0)
 521                 goto err_exit;
 522 
 523 err_exit:
 524         return err;
 525 }
 526 
 527 int hw_atl_utils_mpi_read_mbox(struct aq_hw_s *self,
 528                                struct hw_atl_utils_mbox_header *pmbox)
 529 {
 530         return hw_atl_utils_fw_downld_dwords(self,
 531                                              self->mbox_addr,
 532                                              (u32 *)(void *)pmbox,
 533                                              sizeof(*pmbox) / sizeof(u32));
 534 }
 535 
 536 void hw_atl_utils_mpi_read_stats(struct aq_hw_s *self,
 537                                  struct hw_atl_utils_mbox *pmbox)
 538 {
 539         int err = 0;
 540 
 541         err = hw_atl_utils_fw_downld_dwords(self,
 542                                             self->mbox_addr,
 543                                             (u32 *)(void *)pmbox,
 544                                             sizeof(*pmbox) / sizeof(u32));
 545         if (err < 0)
 546                 goto err_exit;
 547 
 548         if (IS_CHIP_FEATURE(REVISION_A0)) {
 549                 unsigned int mtu = self->aq_nic_cfg ?
 550                                         self->aq_nic_cfg->mtu : 1514U;
 551                 pmbox->stats.ubrc = pmbox->stats.uprc * mtu;
 552                 pmbox->stats.ubtc = pmbox->stats.uptc * mtu;
 553                 pmbox->stats.dpc = atomic_read(&self->dpc);
 554         } else {
 555                 pmbox->stats.dpc = hw_atl_rpb_rx_dma_drop_pkt_cnt_get(self);
 556         }
 557 
 558 err_exit:;
 559 }
 560 
 561 static int hw_atl_utils_mpi_set_speed(struct aq_hw_s *self, u32 speed)
 562 {
 563         u32 val = aq_hw_read_reg(self, HW_ATL_MPI_CONTROL_ADR);
 564 
 565         val = val & ~HW_ATL_MPI_SPEED_MSK;
 566         val |= speed << HW_ATL_MPI_SPEED_SHIFT;
 567         aq_hw_write_reg(self, HW_ATL_MPI_CONTROL_ADR, val);
 568 
 569         return 0;
 570 }
 571 
 572 static int hw_atl_utils_mpi_set_state(struct aq_hw_s *self,
 573                                       enum hal_atl_utils_fw_state_e state)
 574 {
 575         int err = 0;
 576         u32 transaction_id = 0;
 577         struct hw_atl_utils_mbox_header mbox;
 578         u32 val = aq_hw_read_reg(self, HW_ATL_MPI_CONTROL_ADR);
 579 
 580         if (state == MPI_RESET) {
 581                 hw_atl_utils_mpi_read_mbox(self, &mbox);
 582 
 583                 transaction_id = mbox.transaction_id;
 584 
 585                 err = readx_poll_timeout_atomic(hw_atl_utils_get_mpi_mbox_tid,
 586                                                 self, mbox.transaction_id,
 587                                                 transaction_id !=
 588                                                 mbox.transaction_id,
 589                                                 1000U, 100000U);
 590                 if (err < 0)
 591                         goto err_exit;
 592         }
 593         /* On interface DEINIT we disable DW (raise bit)
 594          * Otherwise enable DW (clear bit)
 595          */
 596         if (state == MPI_DEINIT || state == MPI_POWER)
 597                 val |= HW_ATL_MPI_DIRTY_WAKE_MSK;
 598         else
 599                 val &= ~HW_ATL_MPI_DIRTY_WAKE_MSK;
 600 
 601         /* Set new state bits */
 602         val = val & ~HW_ATL_MPI_STATE_MSK;
 603         val |= state & HW_ATL_MPI_STATE_MSK;
 604 
 605         aq_hw_write_reg(self, HW_ATL_MPI_CONTROL_ADR, val);
 606 err_exit:
 607         return err;
 608 }
 609 
 610 int hw_atl_utils_mpi_get_link_status(struct aq_hw_s *self)
 611 {
 612         u32 cp0x036C = hw_atl_utils_mpi_get_state(self);
 613         u32 link_speed_mask = cp0x036C >> HW_ATL_MPI_SPEED_SHIFT;
 614         struct aq_hw_link_status_s *link_status = &self->aq_link_status;
 615 
 616         if (!link_speed_mask) {
 617                 link_status->mbps = 0U;
 618         } else {
 619                 switch (link_speed_mask) {
 620                 case HAL_ATLANTIC_RATE_10G:
 621                         link_status->mbps = 10000U;
 622                         break;
 623 
 624                 case HAL_ATLANTIC_RATE_5G:
 625                 case HAL_ATLANTIC_RATE_5GSR:
 626                         link_status->mbps = 5000U;
 627                         break;
 628 
 629                 case HAL_ATLANTIC_RATE_2GS:
 630                         link_status->mbps = 2500U;
 631                         break;
 632 
 633                 case HAL_ATLANTIC_RATE_1G:
 634                         link_status->mbps = 1000U;
 635                         break;
 636 
 637                 case HAL_ATLANTIC_RATE_100M:
 638                         link_status->mbps = 100U;
 639                         break;
 640 
 641                 default:
 642                         return -EBUSY;
 643                 }
 644         }
 645 
 646         return 0;
 647 }
 648 
 649 int hw_atl_utils_get_mac_permanent(struct aq_hw_s *self,
 650                                    u8 *mac)
 651 {
 652         int err = 0;
 653         u32 h = 0U;
 654         u32 l = 0U;
 655         u32 mac_addr[2];
 656 
 657         if (!aq_hw_read_reg(self, HW_ATL_UCP_0X370_REG)) {
 658                 unsigned int rnd = 0;
 659                 unsigned int ucp_0x370 = 0;
 660 
 661                 get_random_bytes(&rnd, sizeof(unsigned int));
 662 
 663                 ucp_0x370 = 0x02020202 | (0xFEFEFEFE & rnd);
 664                 aq_hw_write_reg(self, HW_ATL_UCP_0X370_REG, ucp_0x370);
 665         }
 666 
 667         err = hw_atl_utils_fw_downld_dwords(self,
 668                                             aq_hw_read_reg(self, 0x00000374U) +
 669                                             (40U * 4U),
 670                                             mac_addr,
 671                                             ARRAY_SIZE(mac_addr));
 672         if (err < 0) {
 673                 mac_addr[0] = 0U;
 674                 mac_addr[1] = 0U;
 675                 err = 0;
 676         } else {
 677                 mac_addr[0] = __swab32(mac_addr[0]);
 678                 mac_addr[1] = __swab32(mac_addr[1]);
 679         }
 680 
 681         ether_addr_copy(mac, (u8 *)mac_addr);
 682 
 683         if ((mac[0] & 0x01U) || ((mac[0] | mac[1] | mac[2]) == 0x00U)) {
 684                 /* chip revision */
 685                 l = 0xE3000000U |
 686                     (0xFFFFU & aq_hw_read_reg(self, HW_ATL_UCP_0X370_REG)) |
 687                     (0x00 << 16);
 688                 h = 0x8001300EU;
 689 
 690                 mac[5] = (u8)(0xFFU & l);
 691                 l >>= 8;
 692                 mac[4] = (u8)(0xFFU & l);
 693                 l >>= 8;
 694                 mac[3] = (u8)(0xFFU & l);
 695                 l >>= 8;
 696                 mac[2] = (u8)(0xFFU & l);
 697                 mac[1] = (u8)(0xFFU & h);
 698                 h >>= 8;
 699                 mac[0] = (u8)(0xFFU & h);
 700         }
 701 
 702         return err;
 703 }
 704 
 705 unsigned int hw_atl_utils_mbps_2_speed_index(unsigned int mbps)
 706 {
 707         unsigned int ret = 0U;
 708 
 709         switch (mbps) {
 710         case 100U:
 711                 ret = 5U;
 712                 break;
 713 
 714         case 1000U:
 715                 ret = 4U;
 716                 break;
 717 
 718         case 2500U:
 719                 ret = 3U;
 720                 break;
 721 
 722         case 5000U:
 723                 ret = 1U;
 724                 break;
 725 
 726         case 10000U:
 727                 ret = 0U;
 728                 break;
 729 
 730         default:
 731                 break;
 732         }
 733         return ret;
 734 }
 735 
 736 void hw_atl_utils_hw_chip_features_init(struct aq_hw_s *self, u32 *p)
 737 {
 738         u32 chip_features = 0U;
 739         u32 val = hw_atl_reg_glb_mif_id_get(self);
 740         u32 mif_rev = val & 0xFFU;
 741 
 742         if ((0xFU & mif_rev) == 1U) {
 743                 chip_features |= HAL_ATLANTIC_UTILS_CHIP_REVISION_A0 |
 744                         HAL_ATLANTIC_UTILS_CHIP_MPI_AQ |
 745                         HAL_ATLANTIC_UTILS_CHIP_MIPS;
 746         } else if ((0xFU & mif_rev) == 2U) {
 747                 chip_features |= HAL_ATLANTIC_UTILS_CHIP_REVISION_B0 |
 748                         HAL_ATLANTIC_UTILS_CHIP_MPI_AQ |
 749                         HAL_ATLANTIC_UTILS_CHIP_MIPS |
 750                         HAL_ATLANTIC_UTILS_CHIP_TPO2 |
 751                         HAL_ATLANTIC_UTILS_CHIP_RPF2;
 752         } else if ((0xFU & mif_rev) == 0xAU) {
 753                 chip_features |= HAL_ATLANTIC_UTILS_CHIP_REVISION_B1 |
 754                         HAL_ATLANTIC_UTILS_CHIP_MPI_AQ |
 755                         HAL_ATLANTIC_UTILS_CHIP_MIPS |
 756                         HAL_ATLANTIC_UTILS_CHIP_TPO2 |
 757                         HAL_ATLANTIC_UTILS_CHIP_RPF2;
 758         }
 759 
 760         *p = chip_features;
 761 }
 762 
 763 static int hw_atl_fw1x_deinit(struct aq_hw_s *self)
 764 {
 765         hw_atl_utils_mpi_set_speed(self, 0);
 766         hw_atl_utils_mpi_set_state(self, MPI_DEINIT);
 767         return 0;
 768 }
 769 
 770 int hw_atl_utils_update_stats(struct aq_hw_s *self)
 771 {
 772         struct hw_atl_utils_mbox mbox;
 773         struct aq_stats_s *cs = &self->curr_stats;
 774 
 775         hw_atl_utils_mpi_read_stats(self, &mbox);
 776 
 777 #define AQ_SDELTA(_N_) (self->curr_stats._N_ += \
 778                         mbox.stats._N_ - self->last_stats._N_)
 779 
 780         if (self->aq_link_status.mbps) {
 781                 AQ_SDELTA(uprc);
 782                 AQ_SDELTA(mprc);
 783                 AQ_SDELTA(bprc);
 784                 AQ_SDELTA(erpt);
 785 
 786                 AQ_SDELTA(uptc);
 787                 AQ_SDELTA(mptc);
 788                 AQ_SDELTA(bptc);
 789                 AQ_SDELTA(erpr);
 790 
 791                 AQ_SDELTA(ubrc);
 792                 AQ_SDELTA(ubtc);
 793                 AQ_SDELTA(mbrc);
 794                 AQ_SDELTA(mbtc);
 795                 AQ_SDELTA(bbrc);
 796                 AQ_SDELTA(bbtc);
 797                 AQ_SDELTA(dpc);
 798         }
 799 #undef AQ_SDELTA
 800 
 801         cs->dma_pkt_rc = hw_atl_stats_rx_dma_good_pkt_counter_get(self);
 802         cs->dma_pkt_tc = hw_atl_stats_tx_dma_good_pkt_counter_get(self);
 803         cs->dma_oct_rc = hw_atl_stats_rx_dma_good_octet_counter_get(self);
 804         cs->dma_oct_tc = hw_atl_stats_tx_dma_good_octet_counter_get(self);
 805 
 806         memcpy(&self->last_stats, &mbox.stats, sizeof(mbox.stats));
 807 
 808         return 0;
 809 }
 810 
 811 struct aq_stats_s *hw_atl_utils_get_hw_stats(struct aq_hw_s *self)
 812 {
 813         return &self->curr_stats;
 814 }
 815 
 816 static const u32 hw_atl_utils_hw_mac_regs[] = {
 817         0x00005580U, 0x00005590U, 0x000055B0U, 0x000055B4U,
 818         0x000055C0U, 0x00005B00U, 0x00005B04U, 0x00005B08U,
 819         0x00005B0CU, 0x00005B10U, 0x00005B14U, 0x00005B18U,
 820         0x00005B1CU, 0x00005B20U, 0x00005B24U, 0x00005B28U,
 821         0x00005B2CU, 0x00005B30U, 0x00005B34U, 0x00005B38U,
 822         0x00005B3CU, 0x00005B40U, 0x00005B44U, 0x00005B48U,
 823         0x00005B4CU, 0x00005B50U, 0x00005B54U, 0x00005B58U,
 824         0x00005B5CU, 0x00005B60U, 0x00005B64U, 0x00005B68U,
 825         0x00005B6CU, 0x00005B70U, 0x00005B74U, 0x00005B78U,
 826         0x00005B7CU, 0x00007C00U, 0x00007C04U, 0x00007C08U,
 827         0x00007C0CU, 0x00007C10U, 0x00007C14U, 0x00007C18U,
 828         0x00007C1CU, 0x00007C20U, 0x00007C40U, 0x00007C44U,
 829         0x00007C48U, 0x00007C4CU, 0x00007C50U, 0x00007C54U,
 830         0x00007C58U, 0x00007C5CU, 0x00007C60U, 0x00007C80U,
 831         0x00007C84U, 0x00007C88U, 0x00007C8CU, 0x00007C90U,
 832         0x00007C94U, 0x00007C98U, 0x00007C9CU, 0x00007CA0U,
 833         0x00007CC0U, 0x00007CC4U, 0x00007CC8U, 0x00007CCCU,
 834         0x00007CD0U, 0x00007CD4U, 0x00007CD8U, 0x00007CDCU,
 835         0x00007CE0U, 0x00000300U, 0x00000304U, 0x00000308U,
 836         0x0000030cU, 0x00000310U, 0x00000314U, 0x00000318U,
 837         0x0000031cU, 0x00000360U, 0x00000364U, 0x00000368U,
 838         0x0000036cU, 0x00000370U, 0x00000374U, 0x00006900U,
 839 };
 840 
 841 int hw_atl_utils_hw_get_regs(struct aq_hw_s *self,
 842                              const struct aq_hw_caps_s *aq_hw_caps,
 843                              u32 *regs_buff)
 844 {
 845         unsigned int i = 0U;
 846 
 847         for (i = 0; i < aq_hw_caps->mac_regs_count; i++)
 848                 regs_buff[i] = aq_hw_read_reg(self,
 849                                               hw_atl_utils_hw_mac_regs[i]);
 850         return 0;
 851 }
 852 
 853 int hw_atl_utils_get_fw_version(struct aq_hw_s *self, u32 *fw_version)
 854 {
 855         *fw_version = aq_hw_read_reg(self, 0x18U);
 856         return 0;
 857 }
 858 
 859 static int aq_fw1x_set_wol(struct aq_hw_s *self, bool wol_enabled, u8 *mac)
 860 {
 861         struct hw_atl_utils_fw_rpc *prpc = NULL;
 862         unsigned int rpc_size = 0U;
 863         int err = 0;
 864 
 865         err = hw_atl_utils_fw_rpc_wait(self, &prpc);
 866         if (err < 0)
 867                 goto err_exit;
 868 
 869         memset(prpc, 0, sizeof(*prpc));
 870 
 871         if (wol_enabled) {
 872                 rpc_size = sizeof(prpc->msg_id) + sizeof(prpc->msg_wol);
 873 
 874                 prpc->msg_id = HAL_ATLANTIC_UTILS_FW_MSG_WOL_ADD;
 875                 prpc->msg_wol.priority =
 876                                 HAL_ATLANTIC_UTILS_FW_MSG_WOL_PRIOR;
 877                 prpc->msg_wol.pattern_id =
 878                                 HAL_ATLANTIC_UTILS_FW_MSG_WOL_PATTERN;
 879                 prpc->msg_wol.wol_packet_type =
 880                                 HAL_ATLANTIC_UTILS_FW_MSG_WOL_MAG_PKT;
 881 
 882                 ether_addr_copy((u8 *)&prpc->msg_wol.wol_pattern, mac);
 883         } else {
 884                 rpc_size = sizeof(prpc->msg_id) + sizeof(prpc->msg_del_id);
 885 
 886                 prpc->msg_id = HAL_ATLANTIC_UTILS_FW_MSG_WOL_DEL;
 887                 prpc->msg_wol.pattern_id =
 888                                 HAL_ATLANTIC_UTILS_FW_MSG_WOL_PATTERN;
 889         }
 890 
 891         err = hw_atl_utils_fw_rpc_call(self, rpc_size);
 892 
 893 err_exit:
 894         return err;
 895 }
 896 
 897 static int aq_fw1x_set_power(struct aq_hw_s *self, unsigned int power_state,
 898                              u8 *mac)
 899 {
 900         struct hw_atl_utils_fw_rpc *prpc = NULL;
 901         unsigned int rpc_size = 0U;
 902         int err = 0;
 903 
 904         if (self->aq_nic_cfg->wol & AQ_NIC_WOL_ENABLED) {
 905                 err = aq_fw1x_set_wol(self, 1, mac);
 906 
 907                 if (err < 0)
 908                         goto err_exit;
 909 
 910                 rpc_size = sizeof(prpc->msg_id) +
 911                            sizeof(prpc->msg_enable_wakeup);
 912 
 913                 err = hw_atl_utils_fw_rpc_wait(self, &prpc);
 914 
 915                 if (err < 0)
 916                         goto err_exit;
 917 
 918                 memset(prpc, 0, rpc_size);
 919 
 920                 prpc->msg_id = HAL_ATLANTIC_UTILS_FW_MSG_ENABLE_WAKEUP;
 921                 prpc->msg_enable_wakeup.pattern_mask = 0x00000002;
 922 
 923                 err = hw_atl_utils_fw_rpc_call(self, rpc_size);
 924                 if (err < 0)
 925                         goto err_exit;
 926         }
 927         hw_atl_utils_mpi_set_speed(self, 0);
 928         hw_atl_utils_mpi_set_state(self, MPI_POWER);
 929 
 930 err_exit:
 931         return err;
 932 }
 933 
 934 static u32 hw_atl_utils_get_mpi_mbox_tid(struct aq_hw_s *self)
 935 {
 936         struct hw_atl_utils_mbox_header mbox;
 937 
 938         hw_atl_utils_mpi_read_mbox(self, &mbox);
 939 
 940         return mbox.transaction_id;
 941 }
 942 
 943 static u32 hw_atl_utils_mpi_get_state(struct aq_hw_s *self)
 944 {
 945         return aq_hw_read_reg(self, HW_ATL_MPI_STATE_ADR);
 946 }
 947 
 948 static u32 hw_atl_utils_mif_cmd_get(struct aq_hw_s *self)
 949 {
 950         return aq_hw_read_reg(self, HW_ATL_MIF_CMD);
 951 }
 952 
 953 static u32 hw_atl_utils_mif_addr_get(struct aq_hw_s *self)
 954 {
 955         return aq_hw_read_reg(self, HW_ATL_MIF_ADDR);
 956 }
 957 
 958 static u32 hw_atl_utils_rpc_state_get(struct aq_hw_s *self)
 959 {
 960         return aq_hw_read_reg(self, HW_ATL_RPC_STATE_ADR);
 961 }
 962 
 963 static u32 aq_fw1x_rpc_get(struct aq_hw_s *self)
 964 {
 965         return aq_hw_read_reg(self, HW_ATL_MPI_RPC_ADDR);
 966 }
 967 
 968 const struct aq_fw_ops aq_fw_1x_ops = {
 969         .init = hw_atl_utils_mpi_create,
 970         .deinit = hw_atl_fw1x_deinit,
 971         .reset = NULL,
 972         .get_mac_permanent = hw_atl_utils_get_mac_permanent,
 973         .set_link_speed = hw_atl_utils_mpi_set_speed,
 974         .set_state = hw_atl_utils_mpi_set_state,
 975         .update_link_status = hw_atl_utils_mpi_get_link_status,
 976         .update_stats = hw_atl_utils_update_stats,
 977         .get_phy_temp = NULL,
 978         .set_power = aq_fw1x_set_power,
 979         .set_eee_rate = NULL,
 980         .get_eee_rate = NULL,
 981         .set_flow_control = NULL,
 982 };

/* [<][>][^][v][top][bottom][index][help] */