LCOV - code coverage report
Current view: top level - drivers/net/atlantic/hw_atl - hw_atl_utils_fw2x.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 0 301 0.0 %
Date: 2024-01-22 16:13:49 Functions: 0 21 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 185 0.0 %

           Branch data     Line data    Source code
       1                 :            : // SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0)
       2                 :            : /* Copyright (C) 2014-2017 aQuantia Corporation. */
       3                 :            : 
       4                 :            : /* File hw_atl_utils_fw2x.c: Definition of firmware 2.x functions for
       5                 :            :  * Atlantic hardware abstraction layer.
       6                 :            :  */
       7                 :            : 
       8                 :            : #include <rte_ether.h>
       9                 :            : #include <pthread.h>
      10                 :            : #include "../atl_hw_regs.h"
      11                 :            : 
      12                 :            : #include "../atl_types.h"
      13                 :            : #include "hw_atl_utils.h"
      14                 :            : #include "hw_atl_llh.h"
      15                 :            : 
      16                 :            : #define HW_ATL_FW2X_MPI_EFUSE_ADDR      0x364
      17                 :            : #define HW_ATL_FW2X_MPI_MBOX_ADDR       0x360
      18                 :            : #define HW_ATL_FW2X_MPI_RPC_ADDR        0x334
      19                 :            : 
      20                 :            : #define HW_ATL_FW2X_MPI_CONTROL_ADDR    0x368
      21                 :            : #define HW_ATL_FW2X_MPI_CONTROL2_ADDR   0x36C
      22                 :            : #define HW_ATL_FW2X_MPI_LED_ADDR        0x31c
      23                 :            : 
      24                 :            : #define HW_ATL_FW2X_MPI_STATE_ADDR      0x370
      25                 :            : #define HW_ATL_FW2X_MPI_STATE2_ADDR     0x374
      26                 :            : 
      27                 :            : #define HW_ATL_FW2X_CAP_SLEEP_PROXY BIT(CAPS_HI_SLEEP_PROXY)
      28                 :            : #define HW_ATL_FW2X_CAP_WOL BIT(CAPS_HI_WOL)
      29                 :            : 
      30                 :            : #define HW_ATL_FW2X_CAP_EEE_1G_MASK   BIT(CAPS_HI_1000BASET_FD_EEE)
      31                 :            : #define HW_ATL_FW2X_CAP_EEE_2G5_MASK  BIT(CAPS_HI_2P5GBASET_FD_EEE)
      32                 :            : #define HW_ATL_FW2X_CAP_EEE_5G_MASK   BIT(CAPS_HI_5GBASET_FD_EEE)
      33                 :            : #define HW_ATL_FW2X_CAP_EEE_10G_MASK  BIT(CAPS_HI_10GBASET_FD_EEE)
      34                 :            : 
      35                 :            : #define HAL_ATLANTIC_WOL_FILTERS_COUNT     8
      36                 :            : #define HAL_ATLANTIC_UTILS_FW2X_MSG_WOL    0x0E
      37                 :            : 
      38                 :            : #define HW_ATL_FW_FEATURE_LED 0x03010026
      39                 :            : 
      40                 :            : struct fw2x_msg_wol_pattern {
      41                 :            :         u8 mask[16];
      42                 :            :         u32 crc;
      43                 :            : } __rte_packed;
      44                 :            : 
      45                 :            : struct fw2x_msg_wol {
      46                 :            :         u32 msg_id;
      47                 :            :         u8 hw_addr[6];
      48                 :            :         u8 magic_packet_enabled;
      49                 :            :         u8 filter_count;
      50                 :            :         struct fw2x_msg_wol_pattern filter[HAL_ATLANTIC_WOL_FILTERS_COUNT];
      51                 :            :         u8 link_up_enabled;
      52                 :            :         u8 link_down_enabled;
      53                 :            :         u16 reserved;
      54                 :            :         u32 link_up_timeout;
      55                 :            :         u32 link_down_timeout;
      56                 :            : } __rte_packed;
      57                 :            : 
      58                 :            : static int aq_fw2x_set_link_speed(struct aq_hw_s *self, u32 speed);
      59                 :            : static int aq_fw2x_set_state(struct aq_hw_s *self,
      60                 :            :                              enum hal_atl_utils_fw_state_e state);
      61                 :            : 
      62                 :          0 : static int aq_fw2x_init(struct aq_hw_s *self)
      63                 :            : {
      64                 :            :         int err = 0;
      65                 :            :         struct hw_aq_atl_utils_mbox mbox;
      66                 :            : 
      67                 :            :         /* check 10 times by 1ms */
      68   [ #  #  #  #  :          0 :         AQ_HW_WAIT_FOR(0U != (self->mbox_addr =
                   #  # ]
      69                 :            :                        aq_hw_read_reg(self, HW_ATL_FW2X_MPI_MBOX_ADDR)),
      70                 :            :                        1000U, 10U);
      71   [ #  #  #  #  :          0 :         AQ_HW_WAIT_FOR(0U != (self->rpc_addr =
                   #  # ]
      72                 :            :                        aq_hw_read_reg(self, HW_ATL_FW2X_MPI_RPC_ADDR)),
      73                 :            :                        1000U, 100U);
      74                 :            : 
      75                 :            :         /* Read caps */
      76                 :          0 :         hw_atl_utils_mpi_read_stats(self, &mbox);
      77                 :            : 
      78                 :          0 :         self->caps_lo = mbox.info.caps_lo;
      79                 :            : 
      80                 :          0 :         return err;
      81                 :            : }
      82                 :            : 
      83                 :          0 : static int aq_fw2x_deinit(struct aq_hw_s *self)
      84                 :            : {
      85                 :          0 :         int err = aq_fw2x_set_link_speed(self, 0);
      86                 :            : 
      87         [ #  # ]:          0 :         if (!err)
      88                 :          0 :                 err = aq_fw2x_set_state(self, MPI_DEINIT);
      89                 :            : 
      90                 :          0 :         return err;
      91                 :            : }
      92                 :            : 
      93                 :          0 : static enum hw_atl_fw2x_rate link_speed_mask_2fw2x_ratemask(u32 speed)
      94                 :            : {
      95                 :            :         enum hw_atl_fw2x_rate rate = 0;
      96                 :            : 
      97         [ #  # ]:          0 :         if (speed & AQ_NIC_RATE_10G)
      98                 :            :                 rate |= FW2X_RATE_10G;
      99                 :            : 
     100         [ #  # ]:          0 :         if (speed & AQ_NIC_RATE_5G)
     101                 :          0 :                 rate |= FW2X_RATE_5G;
     102                 :            : 
     103         [ #  # ]:          0 :         if (speed & AQ_NIC_RATE_5G5R)
     104                 :          0 :                 rate |= FW2X_RATE_5G;
     105                 :            : 
     106         [ #  # ]:          0 :         if (speed & AQ_NIC_RATE_2G5)
     107                 :          0 :                 rate |= FW2X_RATE_2G5;
     108                 :            : 
     109         [ #  # ]:          0 :         if (speed & AQ_NIC_RATE_1G)
     110                 :          0 :                 rate |= FW2X_RATE_1G;
     111                 :            : 
     112         [ #  # ]:          0 :         if (speed & AQ_NIC_RATE_100M)
     113                 :          0 :                 rate |= FW2X_RATE_100M;
     114                 :            : 
     115                 :          0 :         return rate;
     116                 :            : }
     117                 :            : 
     118                 :            : static u32 fw2x_to_eee_mask(u32 speed)
     119                 :            : {
     120                 :            :         u32 rate = 0;
     121                 :            : 
     122         [ #  # ]:          0 :         if (speed & HW_ATL_FW2X_CAP_EEE_10G_MASK)
     123                 :            :                 rate |= AQ_NIC_RATE_EEE_10G;
     124                 :            : 
     125   [ #  #  #  # ]:          0 :         if (speed & HW_ATL_FW2X_CAP_EEE_5G_MASK)
     126                 :          0 :                 rate |= AQ_NIC_RATE_EEE_5G;
     127                 :            : 
     128   [ #  #  #  # ]:          0 :         if (speed & HW_ATL_FW2X_CAP_EEE_2G5_MASK)
     129                 :          0 :                 rate |= AQ_NIC_RATE_EEE_2G5;
     130                 :            : 
     131   [ #  #  #  # ]:          0 :         if (speed & HW_ATL_FW2X_CAP_EEE_1G_MASK)
     132                 :          0 :                 rate |= AQ_NIC_RATE_EEE_1G;
     133                 :            : 
     134                 :            :         return rate;
     135                 :            : }
     136                 :            : 
     137                 :          0 : static int aq_fw2x_set_link_speed(struct aq_hw_s *self, u32 speed)
     138                 :            : {
     139                 :          0 :         u32 rate_mask = link_speed_mask_2fw2x_ratemask(speed);
     140                 :          0 :         u32 reg_val = aq_hw_read_reg(self, HW_ATL_FW2X_MPI_CONTROL_ADDR);
     141                 :          0 :         u32 val = rate_mask | ((BIT(CAPS_LO_SMBUS_READ) |
     142                 :            :                                 BIT(CAPS_LO_SMBUS_WRITE) |
     143                 :            :                                 BIT(CAPS_LO_MACSEC)) & reg_val);
     144                 :            : 
     145                 :          0 :         aq_hw_write_reg(self, HW_ATL_FW2X_MPI_CONTROL_ADDR, val);
     146                 :            : 
     147                 :          0 :         return 0;
     148                 :            : }
     149                 :            : 
     150                 :            : static void aq_fw2x_set_mpi_flow_control(struct aq_hw_s *self, u32 *mpi_state)
     151                 :            : {
     152         [ #  # ]:          0 :         if (self->aq_nic_cfg->flow_control & AQ_NIC_FC_RX)
     153                 :          0 :                 *mpi_state |= BIT(CAPS_HI_PAUSE);
     154                 :            :         else
     155                 :          0 :                 *mpi_state &= ~BIT(CAPS_HI_PAUSE);
     156                 :            : 
     157   [ #  #  #  # ]:          0 :         if (self->aq_nic_cfg->flow_control & AQ_NIC_FC_TX)
     158                 :          0 :                 *mpi_state |= BIT(CAPS_HI_ASYMMETRIC_PAUSE);
     159                 :            :         else
     160                 :          0 :                 *mpi_state &= ~BIT(CAPS_HI_ASYMMETRIC_PAUSE);
     161                 :            : }
     162                 :            : 
     163                 :          0 : static int aq_fw2x_set_state(struct aq_hw_s *self,
     164                 :            :                              enum hal_atl_utils_fw_state_e state)
     165                 :            : {
     166                 :          0 :         u32 mpi_state = aq_hw_read_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR);
     167                 :            : 
     168      [ #  #  # ]:          0 :         switch (state) {
     169                 :          0 :         case MPI_INIT:
     170         [ #  # ]:          0 :                 mpi_state &= ~BIT(CAPS_HI_LINK_DROP);
     171                 :            :                 aq_fw2x_set_mpi_flow_control(self, &mpi_state);
     172                 :            :                 break;
     173                 :          0 :         case MPI_DEINIT:
     174                 :          0 :                 mpi_state |= BIT(CAPS_HI_LINK_DROP);
     175                 :          0 :                 break;
     176                 :            :         case MPI_RESET:
     177                 :            :         case MPI_POWER:
     178                 :            :                 /* No actions */
     179                 :            :                 break;
     180                 :            :         }
     181                 :          0 :         aq_hw_write_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR, mpi_state);
     182                 :          0 :         return 0;
     183                 :            : }
     184                 :            : 
     185                 :          0 : static int aq_fw2x_update_link_status(struct aq_hw_s *self)
     186                 :            : {
     187                 :          0 :         u32 mpi_state = aq_hw_read_reg(self, HW_ATL_FW2X_MPI_STATE_ADDR);
     188                 :          0 :         u32 speed = mpi_state & (FW2X_RATE_100M | FW2X_RATE_1G |
     189                 :            :                                 FW2X_RATE_2G5 | FW2X_RATE_5G | FW2X_RATE_10G);
     190                 :            :         struct aq_hw_link_status_s *link_status = &self->aq_link_status;
     191                 :            : 
     192         [ #  # ]:          0 :         if (speed) {
     193         [ #  # ]:          0 :                 if (speed & FW2X_RATE_10G)
     194                 :          0 :                         link_status->mbps = 10000;
     195         [ #  # ]:          0 :                 else if (speed & FW2X_RATE_5G)
     196                 :          0 :                         link_status->mbps = 5000;
     197         [ #  # ]:          0 :                 else if (speed & FW2X_RATE_2G5)
     198                 :          0 :                         link_status->mbps = 2500;
     199         [ #  # ]:          0 :                 else if (speed & FW2X_RATE_1G)
     200                 :          0 :                         link_status->mbps = 1000;
     201         [ #  # ]:          0 :                 else if (speed & FW2X_RATE_100M)
     202                 :          0 :                         link_status->mbps = 100;
     203                 :            :                 else
     204                 :          0 :                         link_status->mbps = 10000;
     205                 :            :         } else {
     206                 :          0 :                 link_status->mbps = 0;
     207                 :            :         }
     208                 :            : 
     209                 :          0 :         return 0;
     210                 :            : }
     211                 :            : 
     212                 :            : static
     213                 :          0 : int aq_fw2x_get_mac_permanent(struct aq_hw_s *self, u8 *mac)
     214                 :            : {
     215                 :            :         int err = 0;
     216                 :            :         u32 h = 0U;
     217                 :            :         u32 l = 0U;
     218                 :          0 :         u32 mac_addr[2] = { 0 };
     219                 :          0 :         u32 efuse_addr = aq_hw_read_reg(self, HW_ATL_FW2X_MPI_EFUSE_ADDR);
     220                 :            : 
     221                 :          0 :         pthread_mutex_lock(&self->mbox_mutex);
     222                 :            : 
     223         [ #  # ]:          0 :         if (efuse_addr != 0) {
     224                 :          0 :                 err = hw_atl_utils_fw_downld_dwords(self,
     225                 :            :                                                     efuse_addr + (40U * 4U),
     226                 :            :                                                     mac_addr,
     227                 :            :                                                     ARRAY_SIZE(mac_addr));
     228         [ #  # ]:          0 :                 if (err)
     229                 :          0 :                         goto exit;
     230                 :          0 :                 mac_addr[0] = rte_constant_bswap32(mac_addr[0]);
     231                 :          0 :                 mac_addr[1] = rte_constant_bswap32(mac_addr[1]);
     232                 :            :         }
     233                 :            : 
     234                 :            :         rte_ether_addr_copy((struct rte_ether_addr *)mac_addr,
     235                 :            :                         (struct rte_ether_addr *)mac);
     236                 :            : 
     237   [ #  #  #  # ]:          0 :         if ((mac[0] & 0x01U) || ((mac[0] | mac[1] | mac[2]) == 0x00U)) {
     238                 :          0 :                 unsigned int rnd = (uint32_t)rte_rand();
     239                 :            : 
     240                 :            :                 //get_random_bytes(&rnd, sizeof(unsigned int));
     241                 :            : 
     242                 :          0 :                 l = 0xE3000000U
     243                 :          0 :                         | (0xFFFFU & rnd)
     244                 :            :                         | (0x00 << 16);
     245                 :            :                 h = 0x8001300EU;
     246                 :            : 
     247                 :          0 :                 mac[5] = (u8)(0xFFU & l);
     248                 :          0 :                 l >>= 8;
     249                 :          0 :                 mac[4] = (u8)(0xFFU & l);
     250                 :            :                 l >>= 8;
     251                 :          0 :                 mac[3] = (u8)(0xFFU & l);
     252                 :            :                 l >>= 8;
     253                 :          0 :                 mac[2] = (u8)(0xFFU & l);
     254                 :          0 :                 mac[1] = (u8)(0xFFU & h);
     255                 :            :                 h >>= 8;
     256                 :          0 :                 mac[0] = (u8)(0xFFU & h);
     257                 :            :         }
     258                 :            : 
     259                 :          0 : exit:
     260                 :          0 :         pthread_mutex_unlock(&self->mbox_mutex);
     261                 :            : 
     262                 :          0 :         return err;
     263                 :            : }
     264                 :            : 
     265                 :          0 : static int aq_fw2x_update_stats(struct aq_hw_s *self)
     266                 :            : {
     267                 :            :         int err = 0;
     268                 :          0 :         u32 mpi_opts = aq_hw_read_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR);
     269                 :            :         u32 orig_stats_val = mpi_opts & BIT(CAPS_HI_STATISTICS);
     270                 :            : 
     271                 :            : 
     272                 :          0 :         pthread_mutex_lock(&self->mbox_mutex);
     273                 :            : 
     274                 :            :         /* Toggle statistics bit for FW to update */
     275                 :          0 :         mpi_opts = mpi_opts ^ BIT(CAPS_HI_STATISTICS);
     276                 :          0 :         aq_hw_write_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR, mpi_opts);
     277                 :            : 
     278                 :            :         /* Wait FW to report back */
     279   [ #  #  #  #  :          0 :         AQ_HW_WAIT_FOR(orig_stats_val !=
                   #  # ]
     280                 :            :                        (aq_hw_read_reg(self, HW_ATL_FW2X_MPI_STATE2_ADDR) &
     281                 :            :                                        BIT(CAPS_HI_STATISTICS)),
     282                 :            :                        1U, 10000U);
     283                 :            :         if (err)
     284                 :          0 :                 goto exit;
     285                 :            : 
     286                 :          0 :         err = hw_atl_utils_update_stats(self);
     287                 :            : 
     288                 :          0 : exit:
     289                 :          0 :         pthread_mutex_unlock(&self->mbox_mutex);
     290                 :            : 
     291                 :          0 :         return err;
     292                 :            : 
     293                 :            : }
     294                 :            : 
     295                 :          0 : static int aq_fw2x_get_temp(struct aq_hw_s *self, int *temp)
     296                 :            : {
     297                 :            :         int err = 0;
     298                 :          0 :         u32 mpi_opts = aq_hw_read_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR);
     299                 :            :         u32 temp_val = mpi_opts & BIT(CAPS_HI_TEMPERATURE);
     300                 :            :         u32 temp_res;
     301                 :            : 
     302                 :          0 :         pthread_mutex_lock(&self->mbox_mutex);
     303                 :            : 
     304                 :            :         /* Toggle statistics bit for FW to 0x36C.18 (CAPS_HI_TEMPERATURE) */
     305                 :          0 :         mpi_opts = mpi_opts ^ BIT(CAPS_HI_TEMPERATURE);
     306                 :          0 :         aq_hw_write_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR, mpi_opts);
     307                 :            : 
     308                 :            :         /* Wait FW to report back */
     309   [ #  #  #  # ]:          0 :         AQ_HW_WAIT_FOR(temp_val !=
     310                 :            :                         (aq_hw_read_reg(self, HW_ATL_FW2X_MPI_STATE2_ADDR) &
     311                 :            :                                         BIT(CAPS_HI_TEMPERATURE)), 1U, 10000U);
     312                 :          0 :         err = hw_atl_utils_fw_downld_dwords(self,
     313                 :          0 :                                 self->mbox_addr +
     314                 :            :                                 offsetof(struct hw_aq_atl_utils_mbox, info) +
     315                 :            :                                 offsetof(struct hw_aq_info, phy_temperature),
     316                 :            :                                 &temp_res,
     317                 :            :                                 sizeof(temp_res) / sizeof(u32));
     318                 :            : 
     319                 :            : 
     320                 :          0 :         pthread_mutex_unlock(&self->mbox_mutex);
     321                 :            : 
     322         [ #  # ]:          0 :         if (err)
     323                 :            :                 return err;
     324                 :            : 
     325                 :          0 :         *temp = temp_res  * 100 / 256;
     326                 :          0 :         return 0;
     327                 :            : }
     328                 :            : 
     329                 :          0 : static int aq_fw2x_get_cable_len(struct aq_hw_s *self, int *cable_len)
     330                 :            : {
     331                 :            :         int err = 0;
     332                 :            :         u32 cable_len_res;
     333                 :            : 
     334                 :          0 :         err = hw_atl_utils_fw_downld_dwords(self,
     335                 :          0 :                                 self->mbox_addr +
     336                 :            :                                 offsetof(struct hw_aq_atl_utils_mbox, info) +
     337                 :            :                                 offsetof(struct hw_aq_info, phy_temperature),
     338                 :            :                                 &cable_len_res,
     339                 :            :                                 sizeof(cable_len_res) / sizeof(u32));
     340                 :            : 
     341         [ #  # ]:          0 :         if (err)
     342                 :            :                 return err;
     343                 :            : 
     344                 :          0 :         *cable_len = (cable_len_res >> 16) & 0xFF;
     345                 :          0 :         return 0;
     346                 :            : }
     347                 :            : 
     348                 :            : #ifndef ETH_ALEN
     349                 :            : #define ETH_ALEN 6
     350                 :            : #endif
     351                 :            : 
     352                 :          0 : static int aq_fw2x_set_sleep_proxy(struct aq_hw_s *self, u8 *mac)
     353                 :            : {
     354                 :            :         int err = 0;
     355                 :          0 :         struct hw_aq_atl_utils_fw_rpc *rpc = NULL;
     356                 :            :         struct offload_info *cfg = NULL;
     357                 :            :         unsigned int rpc_size = 0U;
     358                 :            :         u32 mpi_opts;
     359                 :            : 
     360                 :            :         rpc_size = sizeof(rpc->msg_id) + sizeof(*cfg);
     361                 :            : 
     362                 :          0 :         err = hw_atl_utils_fw_rpc_wait(self, &rpc);
     363         [ #  # ]:          0 :         if (err < 0)
     364                 :          0 :                 goto err_exit;
     365                 :            : 
     366                 :          0 :         memset(rpc, 0, rpc_size);
     367                 :          0 :         cfg = (struct offload_info *)(&rpc->msg_id + 1);
     368                 :            : 
     369                 :          0 :         memcpy(cfg->mac_addr, mac, ETH_ALEN);
     370                 :          0 :         cfg->len = sizeof(*cfg);
     371                 :            : 
     372                 :            :         /* Clear bit 0x36C.23 */
     373                 :          0 :         mpi_opts = aq_hw_read_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR);
     374                 :          0 :         mpi_opts &= ~HW_ATL_FW2X_CAP_SLEEP_PROXY;
     375                 :            : 
     376                 :          0 :         aq_hw_write_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR, mpi_opts);
     377                 :            : 
     378                 :          0 :         err = hw_atl_utils_fw_rpc_call(self, rpc_size);
     379         [ #  # ]:          0 :         if (err < 0)
     380                 :          0 :                 goto err_exit;
     381                 :            : 
     382                 :            :         /* Set bit 0x36C.23 */
     383                 :          0 :         mpi_opts |= HW_ATL_FW2X_CAP_SLEEP_PROXY;
     384                 :          0 :         aq_hw_write_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR, mpi_opts);
     385                 :            : 
     386   [ #  #  #  #  :          0 :         AQ_HW_WAIT_FOR((aq_hw_read_reg(self, HW_ATL_FW2X_MPI_STATE2_ADDR) &
                   #  # ]
     387                 :            :                         HW_ATL_FW2X_CAP_SLEEP_PROXY), 1U, 10000U);
     388                 :          0 : err_exit:
     389                 :          0 :         return err;
     390                 :            : }
     391                 :            : 
     392                 :          0 : static int aq_fw2x_set_wol_params(struct aq_hw_s *self, u8 *mac)
     393                 :            : {
     394                 :            :         int err = 0;
     395                 :            :         struct fw2x_msg_wol *msg = NULL;
     396                 :            :         u32 mpi_opts;
     397                 :            : 
     398                 :          0 :         struct hw_aq_atl_utils_fw_rpc *rpc = NULL;
     399                 :            : 
     400                 :          0 :         err = hw_atl_utils_fw_rpc_wait(self, &rpc);
     401         [ #  # ]:          0 :         if (err < 0)
     402                 :          0 :                 goto err_exit;
     403                 :            : 
     404                 :          0 :         msg = (struct fw2x_msg_wol *)rpc;
     405                 :            : 
     406                 :          0 :         msg->msg_id = HAL_ATLANTIC_UTILS_FW2X_MSG_WOL;
     407                 :          0 :         msg->magic_packet_enabled = true;
     408                 :          0 :         memcpy(msg->hw_addr, mac, ETH_ALEN);
     409                 :            : 
     410                 :          0 :         mpi_opts = aq_hw_read_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR);
     411                 :          0 :         mpi_opts &= ~(HW_ATL_FW2X_CAP_SLEEP_PROXY | HW_ATL_FW2X_CAP_WOL);
     412                 :            : 
     413                 :          0 :         aq_hw_write_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR, mpi_opts);
     414                 :            : 
     415                 :          0 :         err = hw_atl_utils_fw_rpc_call(self, sizeof(*msg));
     416         [ #  # ]:          0 :         if (err < 0)
     417                 :          0 :                 goto err_exit;
     418                 :            : 
     419                 :            :         /* Set bit 0x36C.24 */
     420                 :          0 :         mpi_opts |= HW_ATL_FW2X_CAP_WOL;
     421                 :          0 :         aq_hw_write_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR, mpi_opts);
     422                 :            : 
     423   [ #  #  #  #  :          0 :         AQ_HW_WAIT_FOR((aq_hw_read_reg(self, HW_ATL_FW2X_MPI_STATE2_ADDR) &
                   #  # ]
     424                 :            :                         HW_ATL_FW2X_CAP_WOL), 1U, 10000U);
     425                 :          0 : err_exit:
     426                 :          0 :         return err;
     427                 :            : }
     428                 :            : 
     429                 :          0 : static int aq_fw2x_set_power(struct aq_hw_s *self,
     430                 :            :                              unsigned int power_state __rte_unused,
     431                 :            :                              u8 *mac)
     432                 :            : {
     433                 :            :         int err = 0;
     434                 :            : 
     435         [ #  # ]:          0 :         if (self->aq_nic_cfg->wol & AQ_NIC_WOL_ENABLED) {
     436                 :          0 :                 err = aq_fw2x_set_sleep_proxy(self, mac);
     437         [ #  # ]:          0 :                 if (err < 0)
     438                 :          0 :                         goto err_exit;
     439                 :          0 :                 err = aq_fw2x_set_wol_params(self, mac);
     440         [ #  # ]:          0 :                 if (err < 0)
     441                 :          0 :                         goto err_exit;
     442                 :            :         }
     443                 :          0 : err_exit:
     444                 :          0 :         return err;
     445                 :            : }
     446                 :            : 
     447                 :          0 : static int aq_fw2x_set_eee_rate(struct aq_hw_s *self, u32 speed)
     448                 :            : {
     449                 :          0 :         u32 mpi_opts = aq_hw_read_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR);
     450                 :          0 :         mpi_opts &= ~(HW_ATL_FW2X_CAP_EEE_1G_MASK |
     451                 :            :                 HW_ATL_FW2X_CAP_EEE_2G5_MASK | HW_ATL_FW2X_CAP_EEE_5G_MASK |
     452                 :            :                 HW_ATL_FW2X_CAP_EEE_10G_MASK);
     453                 :            : 
     454         [ #  # ]:          0 :         if (speed & AQ_NIC_RATE_EEE_10G)
     455                 :          0 :                 mpi_opts |= HW_ATL_FW2X_CAP_EEE_10G_MASK;
     456                 :            : 
     457         [ #  # ]:          0 :         if (speed & AQ_NIC_RATE_EEE_5G)
     458                 :          0 :                 mpi_opts |= HW_ATL_FW2X_CAP_EEE_5G_MASK;
     459                 :            : 
     460         [ #  # ]:          0 :         if (speed & AQ_NIC_RATE_EEE_2G5)
     461                 :          0 :                 mpi_opts |= HW_ATL_FW2X_CAP_EEE_2G5_MASK;
     462                 :            : 
     463         [ #  # ]:          0 :         if (speed & AQ_NIC_RATE_EEE_1G)
     464                 :          0 :                 mpi_opts |= HW_ATL_FW2X_CAP_EEE_1G_MASK;
     465                 :            : 
     466                 :          0 :         aq_hw_write_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR, mpi_opts);
     467                 :            : 
     468                 :          0 :         return 0;
     469                 :            : }
     470                 :            : 
     471                 :          0 : static int aq_fw2x_get_eee_rate(struct aq_hw_s *self, u32 *rate,
     472                 :            :                                         u32 *supported_rates)
     473                 :            : {
     474                 :            :         int err = 0;
     475                 :            :         u32 caps_hi;
     476                 :            :         u32 mpi_state;
     477                 :            : 
     478                 :          0 :         err = hw_atl_utils_fw_downld_dwords(self,
     479                 :          0 :                                 self->mbox_addr +
     480                 :            :                                 offsetof(struct hw_aq_atl_utils_mbox, info) +
     481                 :            :                                 offsetof(struct hw_aq_info, caps_hi),
     482                 :            :                                 &caps_hi,
     483                 :            :                                 sizeof(caps_hi) / sizeof(u32));
     484                 :            : 
     485         [ #  # ]:          0 :         if (err)
     486                 :            :                 return err;
     487                 :            : 
     488         [ #  # ]:          0 :         *supported_rates = fw2x_to_eee_mask(caps_hi);
     489                 :            : 
     490                 :          0 :         mpi_state = aq_hw_read_reg(self, HW_ATL_FW2X_MPI_STATE2_ADDR);
     491                 :          0 :         *rate = fw2x_to_eee_mask(mpi_state);
     492                 :            : 
     493                 :          0 :         return err;
     494                 :            : }
     495                 :            : 
     496                 :          0 : static int aq_fw2x_get_flow_control(struct aq_hw_s *self, u32 *fc)
     497                 :            : {
     498                 :          0 :         u32 mpi_state = aq_hw_read_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR);
     499                 :            : 
     500                 :          0 :         *fc = ((mpi_state & BIT(CAPS_HI_PAUSE)) ? AQ_NIC_FC_RX : 0) |
     501                 :          0 :               ((mpi_state & BIT(CAPS_HI_ASYMMETRIC_PAUSE)) ? AQ_NIC_FC_TX : 0);
     502                 :            : 
     503                 :          0 :         return 0;
     504                 :            : }
     505                 :            : 
     506                 :          0 : static int aq_fw2x_set_flow_control(struct aq_hw_s *self)
     507                 :            : {
     508                 :          0 :         u32 mpi_state = aq_hw_read_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR);
     509                 :            : 
     510                 :            :         aq_fw2x_set_mpi_flow_control(self, &mpi_state);
     511                 :            : 
     512                 :          0 :         aq_hw_write_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR, mpi_state);
     513                 :            : 
     514                 :          0 :         return 0;
     515                 :            : }
     516                 :            : 
     517                 :          0 : static int aq_fw2x_led_control(struct aq_hw_s *self, u32 mode)
     518                 :            : {
     519         [ #  # ]:          0 :         if (self->fw_ver_actual < HW_ATL_FW_FEATURE_LED)
     520                 :            :                 return -EOPNOTSUPP;
     521                 :            : 
     522                 :          0 :         aq_hw_write_reg(self, HW_ATL_FW2X_MPI_LED_ADDR, mode);
     523                 :          0 :         return 0;
     524                 :            : }
     525                 :            : 
     526                 :          0 : static int aq_fw2x_get_eeprom(struct aq_hw_s *self, int dev_addr,
     527                 :            :                               u32 *data, u32 len, u32 offset)
     528                 :            : {
     529                 :          0 :         u32 bytes_remains = len % sizeof(u32);
     530                 :          0 :         u32 num_dwords = len / sizeof(u32);
     531                 :            :         struct smbus_request request;
     532                 :          0 :         u32 result = 0;
     533                 :            :         u32 mpi_opts;
     534                 :            :         int err = 0;
     535                 :            : 
     536         [ #  # ]:          0 :         if ((self->caps_lo & BIT(CAPS_LO_SMBUS_READ)) == 0)
     537                 :            :                 return -EOPNOTSUPP;
     538                 :            : 
     539                 :          0 :         pthread_mutex_lock(&self->mbox_mutex);
     540                 :            : 
     541                 :          0 :         request.msg_id = 0;
     542                 :          0 :         request.device_id = dev_addr;
     543                 :          0 :         request.address = offset;
     544                 :          0 :         request.length = len;
     545                 :            : 
     546                 :            :         /* Write SMBUS request to cfg memory */
     547                 :          0 :         err = hw_atl_utils_fw_upload_dwords(self, self->rpc_addr,
     548                 :            :                                 (u32 *)(void *)&request,
     549                 :            :                                 sizeof(request) / sizeof(u32));
     550                 :            : 
     551         [ #  # ]:          0 :         if (err < 0)
     552                 :          0 :                 goto exit;
     553                 :            : 
     554                 :            :         /* Toggle 0x368.CAPS_LO_SMBUS_READ bit */
     555                 :          0 :         mpi_opts = aq_hw_read_reg(self, HW_ATL_FW2X_MPI_CONTROL_ADDR);
     556                 :          0 :         mpi_opts ^= BIT(CAPS_LO_SMBUS_READ);
     557                 :            : 
     558                 :          0 :         aq_hw_write_reg(self, HW_ATL_FW2X_MPI_CONTROL_ADDR, mpi_opts);
     559                 :            : 
     560                 :            :         /* Wait until REQUEST_BIT matched in 0x370 */
     561                 :            : 
     562   [ #  #  #  #  :          0 :         AQ_HW_WAIT_FOR((aq_hw_read_reg(self, HW_ATL_FW2X_MPI_STATE_ADDR) &
                   #  # ]
     563                 :            :                 BIT(CAPS_LO_SMBUS_READ)) == (mpi_opts & BIT(CAPS_LO_SMBUS_READ)),
     564                 :            :                 10U, 10000U);
     565                 :            : 
     566                 :            :         if (err < 0)
     567                 :          0 :                 goto exit;
     568                 :            : 
     569                 :          0 :         err = hw_atl_utils_fw_downld_dwords(self, self->rpc_addr + sizeof(u32),
     570                 :            :                         &result,
     571                 :            :                         sizeof(result) / sizeof(u32));
     572                 :            : 
     573         [ #  # ]:          0 :         if (err < 0)
     574                 :          0 :                 goto exit;
     575                 :            : 
     576         [ #  # ]:          0 :         if (result) {
     577                 :            :                 err = -EIO;
     578                 :          0 :                 goto exit;
     579                 :            :         }
     580                 :            : 
     581         [ #  # ]:          0 :         if (num_dwords) {
     582                 :          0 :                 err = hw_atl_utils_fw_downld_dwords(self,
     583                 :          0 :                         self->rpc_addr + sizeof(u32) * 2,
     584                 :            :                         data,
     585                 :            :                         num_dwords);
     586                 :            : 
     587         [ #  # ]:          0 :                 if (err < 0)
     588                 :          0 :                         goto exit;
     589                 :            :         }
     590                 :            : 
     591         [ #  # ]:          0 :         if (bytes_remains) {
     592                 :          0 :                 u32 val = 0;
     593                 :            : 
     594                 :          0 :                 err = hw_atl_utils_fw_downld_dwords(self,
     595                 :          0 :                         self->rpc_addr + (sizeof(u32) * 2) +
     596                 :          0 :                         (num_dwords * sizeof(u32)),
     597                 :            :                         &val,
     598                 :            :                         1);
     599                 :            : 
     600         [ #  # ]:          0 :                 if (err < 0)
     601                 :          0 :                         goto exit;
     602                 :            : 
     603         [ #  # ]:          0 :                 rte_memcpy((u8 *)data + len - bytes_remains,
     604                 :            :                                 &val, bytes_remains);
     605                 :            :         }
     606                 :            : 
     607                 :          0 : exit:
     608                 :          0 :         pthread_mutex_unlock(&self->mbox_mutex);
     609                 :            : 
     610                 :          0 :         return err;
     611                 :            : }
     612                 :            : 
     613                 :            : 
     614                 :          0 : static int aq_fw2x_set_eeprom(struct aq_hw_s *self, int dev_addr,
     615                 :            :                               u32 *data, u32 len, u32 offset)
     616                 :            : {
     617                 :            :         struct smbus_request request;
     618                 :          0 :         u32 mpi_opts, result = 0;
     619                 :            :         int err = 0;
     620                 :            : 
     621         [ #  # ]:          0 :         if ((self->caps_lo & BIT(CAPS_LO_SMBUS_WRITE)) == 0)
     622                 :            :                 return -EOPNOTSUPP;
     623                 :            : 
     624                 :          0 :         request.msg_id = 0;
     625                 :          0 :         request.device_id = dev_addr;
     626                 :          0 :         request.address = offset;
     627                 :          0 :         request.length = len;
     628                 :            : 
     629                 :          0 :         pthread_mutex_lock(&self->mbox_mutex);
     630                 :            : 
     631                 :            :         /* Write SMBUS request to cfg memory */
     632                 :          0 :         err = hw_atl_utils_fw_upload_dwords(self, self->rpc_addr,
     633                 :            :                                 (u32 *)(void *)&request,
     634                 :            :                                 sizeof(request) / sizeof(u32));
     635                 :            : 
     636         [ #  # ]:          0 :         if (err < 0)
     637                 :          0 :                 goto exit;
     638                 :            : 
     639                 :            :         /* Write SMBUS data to cfg memory */
     640                 :          0 :         u32 num_dwords = len / sizeof(u32);
     641                 :          0 :         u32 bytes_remains = len % sizeof(u32);
     642                 :            : 
     643         [ #  # ]:          0 :         if (num_dwords) {
     644                 :          0 :                 err = hw_atl_utils_fw_upload_dwords(self,
     645                 :          0 :                         self->rpc_addr + sizeof(request),
     646                 :            :                         (u32 *)(void *)data,
     647                 :            :                         num_dwords);
     648                 :            : 
     649         [ #  # ]:          0 :                 if (err < 0)
     650                 :          0 :                         goto exit;
     651                 :            :         }
     652                 :            : 
     653         [ #  # ]:          0 :         if (bytes_remains) {
     654                 :          0 :                 u32 val = 0;
     655                 :            : 
     656         [ #  # ]:          0 :                 rte_memcpy(&val, (u8 *)data + (sizeof(u32) * num_dwords),
     657                 :            :                            bytes_remains);
     658                 :            : 
     659                 :          0 :                 err = hw_atl_utils_fw_upload_dwords(self,
     660                 :          0 :                         self->rpc_addr + sizeof(request) +
     661                 :          0 :                         (num_dwords * sizeof(u32)),
     662                 :            :                         &val,
     663                 :            :                         1);
     664                 :            : 
     665         [ #  # ]:          0 :                 if (err < 0)
     666                 :          0 :                         goto exit;
     667                 :            :         }
     668                 :            : 
     669                 :            :         /* Toggle 0x368.CAPS_LO_SMBUS_WRITE bit */
     670                 :          0 :         mpi_opts = aq_hw_read_reg(self, HW_ATL_FW2X_MPI_CONTROL_ADDR);
     671                 :          0 :         mpi_opts ^= BIT(CAPS_LO_SMBUS_WRITE);
     672                 :            : 
     673                 :          0 :         aq_hw_write_reg(self, HW_ATL_FW2X_MPI_CONTROL_ADDR, mpi_opts);
     674                 :            : 
     675                 :            :         /* Wait until REQUEST_BIT matched in 0x370 */
     676   [ #  #  #  #  :          0 :         AQ_HW_WAIT_FOR((aq_hw_read_reg(self, HW_ATL_FW2X_MPI_STATE_ADDR) &
                   #  # ]
     677                 :            :                 BIT(CAPS_LO_SMBUS_WRITE)) == (mpi_opts & BIT(CAPS_LO_SMBUS_WRITE)),
     678                 :            :                 10U, 10000U);
     679                 :            : 
     680                 :            :         if (err < 0)
     681                 :          0 :                 goto exit;
     682                 :            : 
     683                 :            :         /* Read status of write operation */
     684                 :          0 :         err = hw_atl_utils_fw_downld_dwords(self, self->rpc_addr + sizeof(u32),
     685                 :            :                                 &result,
     686                 :            :                                 sizeof(result) / sizeof(u32));
     687                 :            : 
     688         [ #  # ]:          0 :         if (err < 0)
     689                 :          0 :                 goto exit;
     690                 :            : 
     691         [ #  # ]:          0 :         if (result) {
     692                 :            :                 err = -EIO;
     693                 :          0 :                 goto exit;
     694                 :            :         }
     695                 :            : 
     696                 :          0 : exit:
     697                 :          0 :         pthread_mutex_unlock(&self->mbox_mutex);
     698                 :            : 
     699                 :          0 :         return err;
     700                 :            : }
     701                 :            : 
     702                 :          0 : static int aq_fw2x_send_macsec_request(struct aq_hw_s *self,
     703                 :            :                                 struct macsec_msg_fw_request *req,
     704                 :            :                                 struct macsec_msg_fw_response *response)
     705                 :            : {
     706                 :            :         int err = 0;
     707                 :            :         u32 mpi_opts = 0;
     708                 :            : 
     709         [ #  # ]:          0 :         if (!req || !response)
     710                 :            :                 return 0;
     711                 :            : 
     712         [ #  # ]:          0 :         if ((self->caps_lo & BIT(CAPS_LO_MACSEC)) == 0)
     713                 :            :                 return -EOPNOTSUPP;
     714                 :            : 
     715                 :          0 :         pthread_mutex_lock(&self->mbox_mutex);
     716                 :            : 
     717                 :            :         /* Write macsec request to cfg memory */
     718                 :          0 :         err = hw_atl_utils_fw_upload_dwords(self, self->rpc_addr,
     719                 :            :                 (u32 *)(void *)req,
     720                 :            :                 RTE_ALIGN(sizeof(*req) / sizeof(u32), sizeof(u32)));
     721                 :            : 
     722         [ #  # ]:          0 :         if (err < 0)
     723                 :          0 :                 goto exit;
     724                 :            : 
     725                 :            :         /* Toggle 0x368.CAPS_LO_MACSEC bit */
     726                 :          0 :         mpi_opts = aq_hw_read_reg(self, HW_ATL_FW2X_MPI_CONTROL_ADDR);
     727                 :          0 :         mpi_opts ^= BIT(CAPS_LO_MACSEC);
     728                 :            : 
     729                 :          0 :         aq_hw_write_reg(self, HW_ATL_FW2X_MPI_CONTROL_ADDR, mpi_opts);
     730                 :            : 
     731                 :            :         /* Wait until REQUEST_BIT matched in 0x370 */
     732   [ #  #  #  #  :          0 :         AQ_HW_WAIT_FOR((aq_hw_read_reg(self, HW_ATL_FW2X_MPI_STATE_ADDR) &
                   #  # ]
     733                 :            :                 BIT(CAPS_LO_MACSEC)) == (mpi_opts & BIT(CAPS_LO_MACSEC)),
     734                 :            :                 1000U, 10000U);
     735                 :            : 
     736                 :            :         if (err < 0)
     737                 :          0 :                 goto exit;
     738                 :            : 
     739                 :            :         /* Read status of write operation */
     740                 :          0 :         err = hw_atl_utils_fw_downld_dwords(self, self->rpc_addr + sizeof(u32),
     741                 :            :                 (u32 *)(void *)response,
     742                 :            :                 RTE_ALIGN(sizeof(*response) / sizeof(u32), sizeof(u32)));
     743                 :            : 
     744                 :          0 : exit:
     745                 :          0 :         pthread_mutex_unlock(&self->mbox_mutex);
     746                 :            : 
     747                 :          0 :         return err;
     748                 :            : }
     749                 :            : 
     750                 :            : const struct aq_fw_ops aq_fw_2x_ops = {
     751                 :            :         .init = aq_fw2x_init,
     752                 :            :         .deinit = aq_fw2x_deinit,
     753                 :            :         .reset = NULL,
     754                 :            :         .get_mac_permanent = aq_fw2x_get_mac_permanent,
     755                 :            :         .set_link_speed = aq_fw2x_set_link_speed,
     756                 :            :         .set_state = aq_fw2x_set_state,
     757                 :            :         .update_link_status = aq_fw2x_update_link_status,
     758                 :            :         .update_stats = aq_fw2x_update_stats,
     759                 :            :         .set_power = aq_fw2x_set_power,
     760                 :            :         .get_temp = aq_fw2x_get_temp,
     761                 :            :         .get_cable_len = aq_fw2x_get_cable_len,
     762                 :            :         .set_eee_rate = aq_fw2x_set_eee_rate,
     763                 :            :         .get_eee_rate = aq_fw2x_get_eee_rate,
     764                 :            :         .get_flow_control = aq_fw2x_get_flow_control,
     765                 :            :         .set_flow_control = aq_fw2x_set_flow_control,
     766                 :            :         .led_control = aq_fw2x_led_control,
     767                 :            :         .get_eeprom = aq_fw2x_get_eeprom,
     768                 :            :         .set_eeprom = aq_fw2x_set_eeprom,
     769                 :            :         .send_macsec_req = aq_fw2x_send_macsec_request,
     770                 :            : };

Generated by: LCOV version 1.14