LCOV - code coverage report
Current view: top level - drivers/net/ethernet/aquantia/atlantic - aq_nic.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 319 679 47.0 %
Date: 2022-04-01 13:59:58 Functions: 20 37 54.1 %
Branches: 92 280 32.9 %

           Branch data     Line data    Source code
       1                 :            : // SPDX-License-Identifier: GPL-2.0-only
       2                 :            : /*
       3                 :            :  * aQuantia Corporation Network Driver
       4                 :            :  * Copyright (C) 2014-2019 aQuantia Corporation. All rights reserved
       5                 :            :  */
       6                 :            : 
       7                 :            : /* File aq_nic.c: Definition of common code for NIC. */
       8                 :            : 
       9                 :            : #include "aq_nic.h"
      10                 :            : #include "aq_ring.h"
      11                 :            : #include "aq_vec.h"
      12                 :            : #include "aq_hw.h"
      13                 :            : #include "aq_pci_func.h"
      14                 :            : #include "aq_main.h"
      15                 :            : #include "aq_phy.h"
      16                 :            : #include "aq_ptp.h"
      17                 :            : #include "aq_filters.h"
      18                 :            : 
      19                 :            : #include <linux/moduleparam.h>
      20                 :            : #include <linux/netdevice.h>
      21                 :            : #include <linux/etherdevice.h>
      22                 :            : #include <linux/timer.h>
      23                 :            : #include <linux/cpu.h>
      24                 :            : #include <linux/ip.h>
      25                 :            : #include <linux/tcp.h>
      26                 :            : #include <net/ip.h>
      27                 :            : 
      28                 :            : static unsigned int aq_itr = AQ_CFG_INTERRUPT_MODERATION_AUTO;
      29                 :            : module_param_named(aq_itr, aq_itr, uint, 0644);
      30                 :            : MODULE_PARM_DESC(aq_itr, "Interrupt throttling mode");
      31                 :            : 
      32                 :            : static unsigned int aq_itr_tx;
      33                 :            : module_param_named(aq_itr_tx, aq_itr_tx, uint, 0644);
      34                 :            : MODULE_PARM_DESC(aq_itr_tx, "TX interrupt throttle rate");
      35                 :            : 
      36                 :            : static unsigned int aq_itr_rx;
      37                 :            : module_param_named(aq_itr_rx, aq_itr_rx, uint, 0644);
      38                 :            : MODULE_PARM_DESC(aq_itr_rx, "RX interrupt throttle rate");
      39                 :            : 
      40                 :            : static void aq_nic_update_ndev_stats(struct aq_nic_s *self);
      41                 :            : 
      42                 :         78 : static void aq_nic_rss_init(struct aq_nic_s *self, unsigned int num_rss_queues)
      43                 :            : {
      44                 :         78 :         static u8 rss_key[AQ_CFG_RSS_HASHKEY_SIZE] = {
      45                 :            :                 0x1e, 0xad, 0x71, 0x87, 0x65, 0xfc, 0x26, 0x7d,
      46                 :            :                 0x0d, 0x45, 0x67, 0x74, 0xcd, 0x06, 0x1a, 0x18,
      47                 :            :                 0xb6, 0xc1, 0xf0, 0xc7, 0xbb, 0x18, 0xbe, 0xf8,
      48                 :            :                 0x19, 0x13, 0x4b, 0xa9, 0xd0, 0x3e, 0xfe, 0x70,
      49                 :            :                 0x25, 0x03, 0xab, 0x50, 0x6a, 0x8b, 0x82, 0x0c
      50                 :            :         };
      51                 :         78 :         struct aq_nic_cfg_s *cfg = &self->aq_nic_cfg;
      52                 :         78 :         struct aq_rss_parameters *rss_params;
      53                 :         78 :         int i = 0;
      54                 :            : 
      55                 :         78 :         rss_params = &cfg->aq_rss;
      56                 :            : 
      57                 :         78 :         rss_params->hash_secret_key_size = sizeof(rss_key);
      58                 :         78 :         memcpy(rss_params->hash_secret_key, rss_key, sizeof(rss_key));
      59                 :         78 :         rss_params->indirection_table_size = AQ_CFG_RSS_INDIRECTION_TABLE_MAX;
      60                 :            : 
      61         [ +  + ]:       5070 :         for (i = rss_params->indirection_table_size; i--;)
      62                 :       4992 :                 rss_params->indirection_table[i] = i & (num_rss_queues - 1);
      63                 :         78 : }
      64                 :            : 
      65                 :            : /* Checks hw_caps and 'corrects' aq_nic_cfg in runtime */
      66                 :         78 : void aq_nic_cfg_start(struct aq_nic_s *self)
      67                 :            : {
      68                 :         78 :         struct aq_nic_cfg_s *cfg = &self->aq_nic_cfg;
      69                 :            : 
      70                 :         78 :         cfg->tcs = AQ_CFG_TCS_DEF;
      71                 :            : 
      72                 :         78 :         cfg->is_polling = AQ_CFG_IS_POLLING_DEF;
      73                 :            : 
      74                 :         78 :         cfg->itr = aq_itr;
      75                 :         78 :         cfg->tx_itr = aq_itr_tx;
      76                 :         78 :         cfg->rx_itr = aq_itr_rx;
      77                 :            : 
      78                 :         78 :         cfg->rxpageorder = AQ_CFG_RX_PAGEORDER;
      79                 :         78 :         cfg->is_rss = AQ_CFG_IS_RSS_DEF;
      80                 :         78 :         cfg->num_rss_queues = AQ_CFG_NUM_RSS_QUEUES_DEF;
      81                 :         78 :         cfg->aq_rss.base_cpu_number = AQ_CFG_RSS_BASE_CPU_NUM_DEF;
      82                 :         78 :         cfg->fc.req = AQ_CFG_FC_MODE;
      83                 :         78 :         cfg->wol = AQ_CFG_WOL_MODES;
      84                 :            : 
      85                 :         78 :         cfg->mtu = AQ_CFG_MTU_DEF;
      86                 :         78 :         cfg->link_speed_msk = AQ_CFG_SPEED_MSK;
      87                 :         78 :         cfg->is_autoneg = AQ_CFG_IS_AUTONEG_DEF;
      88                 :            : 
      89                 :         78 :         cfg->is_lro = AQ_CFG_IS_LRO_DEF;
      90                 :            : 
      91                 :            :         /*descriptors */
      92                 :         78 :         cfg->rxds = min(cfg->aq_hw_caps->rxds_max, AQ_CFG_RXDS_DEF);
      93                 :         78 :         cfg->txds = min(cfg->aq_hw_caps->txds_max, AQ_CFG_TXDS_DEF);
      94                 :            : 
      95                 :            :         /*rss rings */
      96                 :         78 :         cfg->vecs = min(cfg->aq_hw_caps->vecs, AQ_CFG_VECS_DEF);
      97                 :         78 :         cfg->vecs = min(cfg->vecs, num_online_cpus());
      98         [ -  + ]:         78 :         if (self->irqvecs > AQ_HW_SERVICE_IRQS)
      99                 :          0 :                 cfg->vecs = min(cfg->vecs, self->irqvecs - AQ_HW_SERVICE_IRQS);
     100                 :            :         /* cfg->vecs should be power of 2 for RSS */
     101         [ -  + ]:         78 :         if (cfg->vecs >= 8U)
     102                 :          0 :                 cfg->vecs = 8U;
     103         [ -  + ]:         78 :         else if (cfg->vecs >= 4U)
     104                 :          0 :                 cfg->vecs = 4U;
     105         [ -  + ]:         78 :         else if (cfg->vecs >= 2U)
     106                 :          0 :                 cfg->vecs = 2U;
     107                 :            :         else
     108                 :         78 :                 cfg->vecs = 1U;
     109                 :            : 
     110                 :         78 :         cfg->num_rss_queues = min(cfg->vecs, AQ_CFG_NUM_RSS_QUEUES_DEF);
     111                 :            : 
     112                 :         78 :         aq_nic_rss_init(self, cfg->num_rss_queues);
     113                 :            : 
     114                 :         78 :         cfg->irq_type = aq_pci_func_get_irq_type(self);
     115                 :            : 
     116         [ -  + ]:         78 :         if ((cfg->irq_type == AQ_HW_IRQ_LEGACY) ||
     117         [ #  # ]:          0 :             (cfg->aq_hw_caps->vecs == 1U) ||
     118         [ #  # ]:          0 :             (cfg->vecs == 1U)) {
     119                 :         78 :                 cfg->is_rss = 0U;
     120                 :         78 :                 cfg->vecs = 1U;
     121                 :            :         }
     122                 :            : 
     123                 :            :         /* Check if we have enough vectors allocated for
     124                 :            :          * link status IRQ. If no - we'll know link state from
     125                 :            :          * slower service task.
     126                 :            :          */
     127         [ -  + ]:         78 :         if (AQ_HW_SERVICE_IRQS > 0 && cfg->vecs + 1 <= self->irqvecs)
     128                 :          0 :                 cfg->link_irq_vec = cfg->vecs;
     129                 :            :         else
     130                 :         78 :                 cfg->link_irq_vec = 0;
     131                 :            : 
     132                 :         78 :         cfg->link_speed_msk &= cfg->aq_hw_caps->link_speed_msk;
     133                 :         78 :         cfg->features = cfg->aq_hw_caps->hw_features;
     134                 :         78 :         cfg->is_vlan_rx_strip = !!(cfg->features & NETIF_F_HW_VLAN_CTAG_RX);
     135                 :         78 :         cfg->is_vlan_tx_insert = !!(cfg->features & NETIF_F_HW_VLAN_CTAG_TX);
     136                 :         78 :         cfg->is_vlan_force_promisc = true;
     137                 :         78 : }
     138                 :            : 
     139                 :         97 : static int aq_nic_update_link_status(struct aq_nic_s *self)
     140                 :            : {
     141                 :         97 :         int err = self->aq_fw_ops->update_link_status(self->aq_hw);
     142                 :         97 :         u32 fc = 0;
     143                 :            : 
     144         [ +  + ]:         97 :         if (err)
     145                 :            :                 return err;
     146                 :            : 
     147         [ +  - ]:         84 :         if (self->aq_fw_ops->get_flow_control)
     148                 :         84 :                 self->aq_fw_ops->get_flow_control(self->aq_hw, &fc);
     149                 :         84 :         self->aq_nic_cfg.fc.cur = fc;
     150                 :            : 
     151         [ +  + ]:         84 :         if (self->link_status.mbps != self->aq_hw->aq_link_status.mbps) {
     152                 :         81 :                 netdev_info(self->ndev, "%s: link change old %d new %d\n",
     153                 :            :                             AQ_CFG_DRV_NAME, self->link_status.mbps,
     154                 :            :                             self->aq_hw->aq_link_status.mbps);
     155                 :         81 :                 aq_nic_update_interrupt_moderation_settings(self);
     156                 :            : 
     157         [ -  + ]:         81 :                 if (self->aq_ptp) {
     158                 :          0 :                         aq_ptp_clock_init(self);
     159                 :          0 :                         aq_ptp_tm_offset_set(self,
     160                 :          0 :                                              self->aq_hw->aq_link_status.mbps);
     161                 :          0 :                         aq_ptp_link_change(self);
     162                 :            :                 }
     163                 :            : 
     164                 :            :                 /* Driver has to update flow control settings on RX block
     165                 :            :                  * on any link event.
     166                 :            :                  * We should query FW whether it negotiated FC.
     167                 :            :                  */
     168         [ +  - ]:         81 :                 if (self->aq_hw_ops->hw_set_fc)
     169                 :         81 :                         self->aq_hw_ops->hw_set_fc(self->aq_hw, fc, 0);
     170                 :            :         }
     171                 :            : 
     172                 :         84 :         self->link_status = self->aq_hw->aq_link_status;
     173   [ +  +  +  + ]:         84 :         if (!netif_carrier_ok(self->ndev) && self->link_status.mbps) {
     174                 :         28 :                 aq_utils_obj_set(&self->flags,
     175                 :            :                                  AQ_NIC_FLAG_STARTED);
     176                 :         28 :                 aq_utils_obj_clear(&self->flags,
     177                 :            :                                    AQ_NIC_LINK_DOWN);
     178                 :         28 :                 netif_carrier_on(self->ndev);
     179                 :         28 :                 netif_tx_wake_all_queues(self->ndev);
     180                 :            :         }
     181   [ +  +  -  + ]:         84 :         if (netif_carrier_ok(self->ndev) && !self->link_status.mbps) {
     182                 :          0 :                 netif_carrier_off(self->ndev);
     183                 :          0 :                 netif_tx_disable(self->ndev);
     184                 :          0 :                 aq_utils_obj_set(&self->flags, AQ_NIC_LINK_DOWN);
     185                 :            :         }
     186                 :            : 
     187                 :            :         return 0;
     188                 :            : }
     189                 :            : 
     190                 :          0 : static irqreturn_t aq_linkstate_threaded_isr(int irq, void *private)
     191                 :            : {
     192                 :          0 :         struct aq_nic_s *self = private;
     193                 :            : 
     194         [ #  # ]:          0 :         if (!self)
     195                 :            :                 return IRQ_NONE;
     196                 :            : 
     197                 :          0 :         aq_nic_update_link_status(self);
     198                 :            : 
     199                 :          0 :         self->aq_hw_ops->hw_irq_enable(self->aq_hw,
     200                 :          0 :                                        BIT(self->aq_nic_cfg.link_irq_vec));
     201                 :            : 
     202                 :          0 :         return IRQ_HANDLED;
     203                 :            : }
     204                 :            : 
     205                 :         97 : static void aq_nic_service_task(struct work_struct *work)
     206                 :            : {
     207                 :         97 :         struct aq_nic_s *self = container_of(work, struct aq_nic_s,
     208                 :            :                                              service_task);
     209                 :         97 :         int err;
     210                 :            : 
     211                 :         97 :         aq_ptp_service_task(self);
     212                 :            : 
     213         [ +  - ]:         97 :         if (aq_utils_obj_test(&self->flags, AQ_NIC_FLAGS_IS_NOT_READY))
     214                 :            :                 return;
     215                 :            : 
     216                 :         97 :         err = aq_nic_update_link_status(self);
     217         [ +  + ]:         97 :         if (err)
     218                 :            :                 return;
     219                 :            : 
     220                 :         84 :         mutex_lock(&self->fwreq_mutex);
     221         [ +  - ]:         84 :         if (self->aq_fw_ops->update_stats)
     222                 :         84 :                 self->aq_fw_ops->update_stats(self->aq_hw);
     223                 :         84 :         mutex_unlock(&self->fwreq_mutex);
     224                 :            : 
     225                 :         84 :         aq_nic_update_ndev_stats(self);
     226                 :            : }
     227                 :            : 
     228                 :         97 : static void aq_nic_service_timer_cb(struct timer_list *t)
     229                 :            : {
     230                 :         97 :         struct aq_nic_s *self = from_timer(self, t, service_timer);
     231                 :            : 
     232                 :         97 :         mod_timer(&self->service_timer,
     233                 :            :                   jiffies + AQ_CFG_SERVICE_TIMER_INTERVAL);
     234                 :            : 
     235                 :         97 :         aq_ndev_schedule_work(&self->service_task);
     236                 :         97 : }
     237                 :            : 
     238                 :          0 : static void aq_nic_polling_timer_cb(struct timer_list *t)
     239                 :            : {
     240                 :          0 :         struct aq_nic_s *self = from_timer(self, t, polling_timer);
     241                 :          0 :         struct aq_vec_s *aq_vec = NULL;
     242                 :          0 :         unsigned int i = 0U;
     243                 :            : 
     244                 :          0 :         for (i = 0U, aq_vec = self->aq_vec[0];
     245         [ #  # ]:          0 :                 self->aq_vecs > i; ++i, aq_vec = self->aq_vec[i])
     246                 :          0 :                 aq_vec_isr(i, (void *)aq_vec);
     247                 :            : 
     248                 :          0 :         mod_timer(&self->polling_timer, jiffies +
     249                 :            :                   AQ_CFG_POLLING_TIMER_INTERVAL);
     250                 :          0 : }
     251                 :            : 
     252                 :         78 : int aq_nic_ndev_register(struct aq_nic_s *self)
     253                 :            : {
     254                 :         78 :         int err = 0;
     255                 :            : 
     256         [ -  + ]:         78 :         if (!self->ndev) {
     257                 :          0 :                 err = -EINVAL;
     258                 :          0 :                 goto err_exit;
     259                 :            :         }
     260                 :            : 
     261                 :         78 :         err = hw_atl_utils_initfw(self->aq_hw, &self->aq_fw_ops);
     262         [ +  + ]:         78 :         if (err)
     263                 :         35 :                 goto err_exit;
     264                 :            : 
     265                 :         43 :         mutex_lock(&self->fwreq_mutex);
     266                 :         43 :         err = self->aq_fw_ops->get_mac_permanent(self->aq_hw,
     267                 :         43 :                             self->ndev->dev_addr);
     268                 :         43 :         mutex_unlock(&self->fwreq_mutex);
     269         [ +  + ]:         43 :         if (err)
     270                 :         10 :                 goto err_exit;
     271                 :            : 
     272                 :            : #if defined(AQ_CFG_MAC_ADDR_PERMANENT)
     273                 :            :         {
     274                 :            :                 static u8 mac_addr_permanent[] = AQ_CFG_MAC_ADDR_PERMANENT;
     275                 :            : 
     276                 :            :                 ether_addr_copy(self->ndev->dev_addr, mac_addr_permanent);
     277                 :            :         }
     278                 :            : #endif
     279                 :            : 
     280                 :         33 :         for (self->aq_vecs = 0; self->aq_vecs < aq_nic_get_cfg(self)->vecs;
     281                 :         33 :              self->aq_vecs++) {
     282                 :         66 :                 self->aq_vec[self->aq_vecs] =
     283                 :         33 :                     aq_vec_alloc(self, self->aq_vecs, aq_nic_get_cfg(self));
     284         [ -  + ]:         33 :                 if (!self->aq_vec[self->aq_vecs]) {
     285                 :          0 :                         err = -ENOMEM;
     286                 :          0 :                         goto err_exit;
     287                 :            :                 }
     288                 :            :         }
     289                 :            : 
     290                 :         33 :         netif_carrier_off(self->ndev);
     291                 :            : 
     292                 :         33 :         netif_tx_disable(self->ndev);
     293                 :            : 
     294                 :         33 :         err = register_netdev(self->ndev);
     295         [ +  - ]:         33 :         if (err)
     296                 :          0 :                 goto err_exit;
     297                 :            : 
     298                 :         33 : err_exit:
     299                 :         78 :         return err;
     300                 :            : }
     301                 :            : 
     302                 :         78 : void aq_nic_ndev_init(struct aq_nic_s *self)
     303                 :            : {
     304                 :         78 :         const struct aq_hw_caps_s *aq_hw_caps = self->aq_nic_cfg.aq_hw_caps;
     305                 :         78 :         struct aq_nic_cfg_s *aq_nic_cfg = &self->aq_nic_cfg;
     306                 :            : 
     307                 :         78 :         self->ndev->hw_features |= aq_hw_caps->hw_features;
     308                 :         78 :         self->ndev->features = aq_hw_caps->hw_features;
     309                 :         78 :         self->ndev->vlan_features |= NETIF_F_HW_CSUM | NETIF_F_RXCSUM |
     310                 :            :                                      NETIF_F_RXHASH | NETIF_F_SG |
     311                 :            :                                      NETIF_F_LRO | NETIF_F_TSO;
     312                 :         78 :         self->ndev->gso_partial_features = NETIF_F_GSO_UDP_L4;
     313                 :         78 :         self->ndev->priv_flags = aq_hw_caps->hw_priv_flags;
     314                 :         78 :         self->ndev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
     315                 :            : 
     316                 :         78 :         self->msg_enable = NETIF_MSG_DRV | NETIF_MSG_LINK;
     317                 :         78 :         self->ndev->mtu = aq_nic_cfg->mtu - ETH_HLEN;
     318                 :         78 :         self->ndev->max_mtu = aq_hw_caps->mtu - ETH_FCS_LEN - ETH_HLEN;
     319                 :            : 
     320                 :         78 : }
     321                 :            : 
     322                 :         33 : void aq_nic_set_tx_ring(struct aq_nic_s *self, unsigned int idx,
     323                 :            :                         struct aq_ring_s *ring)
     324                 :            : {
     325                 :         33 :         self->aq_ring_tx[idx] = ring;
     326                 :         33 : }
     327                 :            : 
     328                 :       8701 : struct net_device *aq_nic_get_ndev(struct aq_nic_s *self)
     329                 :            : {
     330                 :       8701 :         return self->ndev;
     331                 :            : }
     332                 :            : 
     333                 :         33 : int aq_nic_init(struct aq_nic_s *self)
     334                 :            : {
     335                 :         33 :         struct aq_vec_s *aq_vec = NULL;
     336                 :         33 :         unsigned int i = 0U;
     337                 :         33 :         int err = 0;
     338                 :            : 
     339                 :         33 :         self->power_state = AQ_HW_POWER_STATE_D0;
     340                 :         33 :         mutex_lock(&self->fwreq_mutex);
     341                 :         33 :         err = self->aq_hw_ops->hw_reset(self->aq_hw);
     342                 :         33 :         mutex_unlock(&self->fwreq_mutex);
     343         [ -  + ]:         33 :         if (err < 0)
     344                 :          0 :                 goto err_exit;
     345                 :            : 
     346                 :         33 :         err = self->aq_hw_ops->hw_init(self->aq_hw,
     347                 :         33 :                                        aq_nic_get_ndev(self)->dev_addr);
     348         [ -  + ]:         33 :         if (err < 0)
     349                 :          0 :                 goto err_exit;
     350                 :            : 
     351         [ +  - ]:         33 :         if (self->aq_nic_cfg.aq_hw_caps->media_type == AQ_HW_MEDIA_TYPE_TP) {
     352                 :         33 :                 self->aq_hw->phy_id = HW_ATL_PHY_ID_MAX;
     353                 :         33 :                 err = aq_phy_init(self->aq_hw);
     354                 :            :         }
     355                 :            : 
     356                 :         33 :         for (i = 0U, aq_vec = self->aq_vec[0];
     357         [ +  + ]:         66 :                 self->aq_vecs > i; ++i, aq_vec = self->aq_vec[i])
     358                 :         33 :                 aq_vec_init(aq_vec, self->aq_hw_ops, self->aq_hw);
     359                 :            : 
     360                 :         33 :         err = aq_ptp_init(self, self->irqvecs - 1);
     361         [ -  + ]:         33 :         if (err < 0)
     362                 :          0 :                 goto err_exit;
     363                 :            : 
     364                 :         33 :         err = aq_ptp_ring_alloc(self);
     365         [ -  + ]:         33 :         if (err < 0)
     366                 :          0 :                 goto err_exit;
     367                 :            : 
     368                 :         33 :         err = aq_ptp_ring_init(self);
     369         [ -  + ]:         33 :         if (err < 0)
     370                 :          0 :                 goto err_exit;
     371                 :            : 
     372                 :         33 :         netif_carrier_off(self->ndev);
     373                 :            : 
     374                 :         33 : err_exit:
     375                 :         33 :         return err;
     376                 :            : }
     377                 :            : 
     378                 :         33 : int aq_nic_start(struct aq_nic_s *self)
     379                 :            : {
     380                 :         33 :         struct aq_vec_s *aq_vec = NULL;
     381                 :         33 :         unsigned int i = 0U;
     382                 :         33 :         int err = 0;
     383                 :            : 
     384                 :         33 :         err = self->aq_hw_ops->hw_multicast_list_set(self->aq_hw,
     385                 :         33 :                                                      self->mc_list.ar,
     386                 :            :                                                      self->mc_list.count);
     387         [ -  + ]:         33 :         if (err < 0)
     388                 :          0 :                 goto err_exit;
     389                 :            : 
     390                 :         33 :         err = self->aq_hw_ops->hw_packet_filter_set(self->aq_hw,
     391                 :            :                                                     self->packet_filter);
     392         [ -  + ]:         33 :         if (err < 0)
     393                 :          0 :                 goto err_exit;
     394                 :            : 
     395                 :         33 :         for (i = 0U, aq_vec = self->aq_vec[0];
     396         [ +  + ]:         66 :                 self->aq_vecs > i; ++i, aq_vec = self->aq_vec[i]) {
     397                 :         33 :                 err = aq_vec_start(aq_vec);
     398         [ -  + ]:         33 :                 if (err < 0)
     399                 :          0 :                         goto err_exit;
     400                 :            :         }
     401                 :            : 
     402                 :         33 :         err = aq_ptp_ring_start(self);
     403         [ -  + ]:         33 :         if (err < 0)
     404                 :          0 :                 goto err_exit;
     405                 :            : 
     406                 :         33 :         aq_nic_set_loopback(self);
     407                 :            : 
     408                 :         33 :         err = self->aq_hw_ops->hw_start(self->aq_hw);
     409         [ -  + ]:         33 :         if (err < 0)
     410                 :          0 :                 goto err_exit;
     411                 :            : 
     412                 :         33 :         err = aq_nic_update_interrupt_moderation_settings(self);
     413         [ -  + ]:         33 :         if (err)
     414                 :          0 :                 goto err_exit;
     415                 :            : 
     416                 :         33 :         INIT_WORK(&self->service_task, aq_nic_service_task);
     417                 :            : 
     418                 :         33 :         timer_setup(&self->service_timer, aq_nic_service_timer_cb, 0);
     419                 :         33 :         aq_nic_service_timer_cb(&self->service_timer);
     420                 :            : 
     421         [ -  + ]:         33 :         if (self->aq_nic_cfg.is_polling) {
     422                 :          0 :                 timer_setup(&self->polling_timer, aq_nic_polling_timer_cb, 0);
     423                 :          0 :                 mod_timer(&self->polling_timer, jiffies +
     424                 :            :                           AQ_CFG_POLLING_TIMER_INTERVAL);
     425                 :            :         } else {
     426                 :         33 :                 for (i = 0U, aq_vec = self->aq_vec[0];
     427         [ +  + ]:         66 :                         self->aq_vecs > i; ++i, aq_vec = self->aq_vec[i]) {
     428                 :         33 :                         err = aq_pci_func_alloc_irq(self, i, self->ndev->name,
     429                 :            :                                                     aq_vec_isr, aq_vec,
     430                 :            :                                                     aq_vec_get_affinity_mask(aq_vec));
     431         [ -  + ]:         33 :                         if (err < 0)
     432                 :          0 :                                 goto err_exit;
     433                 :            :                 }
     434                 :            : 
     435                 :         33 :                 err = aq_ptp_irq_alloc(self);
     436         [ -  + ]:         33 :                 if (err < 0)
     437                 :          0 :                         goto err_exit;
     438                 :            : 
     439         [ -  + ]:         33 :                 if (self->aq_nic_cfg.link_irq_vec) {
     440                 :          0 :                         int irqvec = pci_irq_vector(self->pdev,
     441                 :            :                                                    self->aq_nic_cfg.link_irq_vec);
     442                 :          0 :                         err = request_threaded_irq(irqvec, NULL,
     443                 :            :                                                    aq_linkstate_threaded_isr,
     444                 :            :                                                    IRQF_SHARED | IRQF_ONESHOT,
     445                 :          0 :                                                    self->ndev->name, self);
     446         [ #  # ]:          0 :                         if (err < 0)
     447                 :          0 :                                 goto err_exit;
     448                 :          0 :                         self->msix_entry_mask |= (1 << self->aq_nic_cfg.link_irq_vec);
     449                 :            :                 }
     450                 :            : 
     451                 :         33 :                 err = self->aq_hw_ops->hw_irq_enable(self->aq_hw,
     452                 :            :                                                      AQ_CFG_IRQ_MASK);
     453         [ -  + ]:         33 :                 if (err < 0)
     454                 :          0 :                         goto err_exit;
     455                 :            :         }
     456                 :            : 
     457                 :         33 :         err = netif_set_real_num_tx_queues(self->ndev, self->aq_vecs);
     458         [ -  + ]:         33 :         if (err < 0)
     459                 :          0 :                 goto err_exit;
     460                 :            : 
     461                 :         33 :         err = netif_set_real_num_rx_queues(self->ndev, self->aq_vecs);
     462         [ -  + ]:         33 :         if (err < 0)
     463                 :          0 :                 goto err_exit;
     464                 :            : 
     465                 :         33 :         netif_tx_start_all_queues(self->ndev);
     466                 :            : 
     467                 :         33 : err_exit:
     468                 :         33 :         return err;
     469                 :            : }
     470                 :            : 
     471                 :        156 : unsigned int aq_nic_map_skb(struct aq_nic_s *self, struct sk_buff *skb,
     472                 :            :                             struct aq_ring_s *ring)
     473                 :            : {
     474         [ -  + ]:        156 :         unsigned int nr_frags = skb_shinfo(skb)->nr_frags;
     475                 :        156 :         struct aq_ring_buff_s *first = NULL;
     476         [ -  + ]:        156 :         u8 ipver = ip_hdr(skb)->version;
     477                 :        156 :         struct aq_ring_buff_s *dx_buff;
     478                 :        156 :         bool need_context_tag = false;
     479                 :        156 :         unsigned int frag_count = 0U;
     480                 :        156 :         unsigned int ret = 0U;
     481                 :        156 :         unsigned int dx;
     482                 :        156 :         u8 l4proto = 0;
     483                 :            : 
     484         [ -  + ]:        156 :         if (ipver == 4)
     485                 :          0 :                 l4proto = ip_hdr(skb)->protocol;
     486         [ +  - ]:        156 :         else if (ipver == 6)
     487                 :        156 :                 l4proto = ipv6_hdr(skb)->nexthdr;
     488                 :            : 
     489                 :        156 :         dx = ring->sw_tail;
     490                 :        156 :         dx_buff = &ring->buff_ring[dx];
     491                 :        156 :         dx_buff->flags = 0U;
     492                 :            : 
     493         [ -  + ]:        156 :         if (unlikely(skb_is_gso(skb))) {
     494         [ #  # ]:          0 :                 dx_buff->mss = skb_shinfo(skb)->gso_size;
     495         [ #  # ]:          0 :                 if (l4proto == IPPROTO_TCP) {
     496                 :          0 :                         dx_buff->is_gso_tcp = 1U;
     497                 :          0 :                         dx_buff->len_l4 = tcp_hdrlen(skb);
     498         [ #  # ]:          0 :                 } else if (l4proto == IPPROTO_UDP) {
     499                 :          0 :                         dx_buff->is_gso_udp = 1U;
     500                 :          0 :                         dx_buff->len_l4 = sizeof(struct udphdr);
     501                 :            :                         /* UDP GSO Hardware does not replace packet length. */
     502                 :          0 :                         udp_hdr(skb)->len = htons(dx_buff->mss +
     503                 :            :                                                   dx_buff->len_l4);
     504                 :            :                 } else {
     505         [ #  # ]:          0 :                         WARN_ONCE(true, "Bad GSO mode");
     506                 :          0 :                         goto exit;
     507                 :            :                 }
     508                 :          0 :                 dx_buff->len_pkt = skb->len;
     509                 :          0 :                 dx_buff->len_l2 = ETH_HLEN;
     510                 :          0 :                 dx_buff->len_l3 = skb_network_header_len(skb);
     511                 :          0 :                 dx_buff->eop_index = 0xffffU;
     512                 :          0 :                 dx_buff->is_ipv6 = (ipver == 6);
     513                 :          0 :                 need_context_tag = true;
     514                 :            :         }
     515                 :            : 
     516   [ +  -  -  + ]:        156 :         if (self->aq_nic_cfg.is_vlan_tx_insert && skb_vlan_tag_present(skb)) {
     517                 :          0 :                 dx_buff->vlan_tx_tag = skb_vlan_tag_get(skb);
     518                 :          0 :                 dx_buff->len_pkt = skb->len;
     519                 :          0 :                 dx_buff->is_vlan = 1U;
     520                 :          0 :                 need_context_tag = true;
     521                 :            :         }
     522                 :            : 
     523         [ -  + ]:        156 :         if (need_context_tag) {
     524         [ #  # ]:          0 :                 dx = aq_ring_next_dx(ring, dx);
     525                 :          0 :                 dx_buff = &ring->buff_ring[dx];
     526                 :          0 :                 dx_buff->flags = 0U;
     527                 :          0 :                 ++ret;
     528                 :            :         }
     529                 :            : 
     530                 :        156 :         dx_buff->len = skb_headlen(skb);
     531                 :        156 :         dx_buff->pa = dma_map_single(aq_nic_get_dev(self),
     532                 :            :                                      skb->data,
     533                 :            :                                      dx_buff->len,
     534                 :            :                                      DMA_TO_DEVICE);
     535                 :            : 
     536         [ -  + ]:        312 :         if (unlikely(dma_mapping_error(aq_nic_get_dev(self), dx_buff->pa))) {
     537                 :          0 :                 ret = 0;
     538                 :          0 :                 goto exit;
     539                 :            :         }
     540                 :            : 
     541                 :        156 :         first = dx_buff;
     542                 :        156 :         dx_buff->len_pkt = skb->len;
     543                 :        156 :         dx_buff->is_sop = 1U;
     544                 :        156 :         dx_buff->is_mapped = 1U;
     545                 :        156 :         ++ret;
     546                 :            : 
     547         [ -  + ]:        156 :         if (skb->ip_summed == CHECKSUM_PARTIAL) {
     548                 :          0 :                 dx_buff->is_ip_cso = (htons(ETH_P_IP) == skb->protocol);
     549                 :          0 :                 dx_buff->is_tcp_cso = (l4proto == IPPROTO_TCP);
     550                 :          0 :                 dx_buff->is_udp_cso = (l4proto == IPPROTO_UDP);
     551                 :            :         }
     552                 :            : 
     553         [ -  + ]:        156 :         for (; nr_frags--; ++frag_count) {
     554                 :          0 :                 unsigned int frag_len = 0U;
     555                 :          0 :                 unsigned int buff_offset = 0U;
     556                 :          0 :                 unsigned int buff_size = 0U;
     557                 :          0 :                 dma_addr_t frag_pa;
     558                 :          0 :                 skb_frag_t *frag = &skb_shinfo(skb)->frags[frag_count];
     559                 :            : 
     560                 :          0 :                 frag_len = skb_frag_size(frag);
     561                 :            : 
     562         [ #  # ]:          0 :                 while (frag_len) {
     563                 :          0 :                         if (frag_len > AQ_CFG_TX_FRAME_MAX)
     564                 :            :                                 buff_size = AQ_CFG_TX_FRAME_MAX;
     565                 :            :                         else
     566                 :            :                                 buff_size = frag_len;
     567                 :            : 
     568                 :          0 :                         frag_pa = skb_frag_dma_map(aq_nic_get_dev(self),
     569                 :            :                                                    frag,
     570                 :            :                                                    buff_offset,
     571                 :            :                                                    buff_size,
     572                 :            :                                                    DMA_TO_DEVICE);
     573                 :            : 
     574         [ #  # ]:          0 :                         if (unlikely(dma_mapping_error(aq_nic_get_dev(self),
     575                 :            :                                                        frag_pa)))
     576                 :          0 :                                 goto mapping_error;
     577                 :            : 
     578         [ #  # ]:          0 :                         dx = aq_ring_next_dx(ring, dx);
     579                 :          0 :                         dx_buff = &ring->buff_ring[dx];
     580                 :            : 
     581                 :          0 :                         dx_buff->flags = 0U;
     582                 :          0 :                         dx_buff->len = buff_size;
     583                 :          0 :                         dx_buff->pa = frag_pa;
     584                 :          0 :                         dx_buff->is_mapped = 1U;
     585                 :          0 :                         dx_buff->eop_index = 0xffffU;
     586                 :            : 
     587                 :          0 :                         frag_len -= buff_size;
     588                 :          0 :                         buff_offset += buff_size;
     589                 :            : 
     590                 :          0 :                         ++ret;
     591                 :            :                 }
     592                 :            :         }
     593                 :            : 
     594                 :        156 :         first->eop_index = dx;
     595                 :        156 :         dx_buff->is_eop = 1U;
     596                 :        156 :         dx_buff->skb = skb;
     597                 :        156 :         goto exit;
     598                 :            : 
     599                 :            : mapping_error:
     600                 :          0 :         for (dx = ring->sw_tail;
     601         [ #  # ]:          0 :              ret > 0;
     602         [ #  # ]:          0 :              --ret, dx = aq_ring_next_dx(ring, dx)) {
     603                 :          0 :                 dx_buff = &ring->buff_ring[dx];
     604                 :            : 
     605         [ #  # ]:          0 :                 if (!(dx_buff->is_gso_tcp || dx_buff->is_gso_udp) &&
     606   [ #  #  #  # ]:          0 :                     !dx_buff->is_vlan && dx_buff->pa) {
     607         [ #  # ]:          0 :                         if (unlikely(dx_buff->is_sop)) {
     608                 :          0 :                                 dma_unmap_single(aq_nic_get_dev(self),
     609                 :            :                                                  dx_buff->pa,
     610                 :            :                                                  dx_buff->len,
     611                 :            :                                                  DMA_TO_DEVICE);
     612                 :            :                         } else {
     613                 :          0 :                                 dma_unmap_page(aq_nic_get_dev(self),
     614                 :            :                                                dx_buff->pa,
     615                 :            :                                                dx_buff->len,
     616                 :            :                                                DMA_TO_DEVICE);
     617                 :            :                         }
     618                 :            :                 }
     619                 :            :         }
     620                 :            : 
     621                 :          0 : exit:
     622                 :        156 :         return ret;
     623                 :            : }
     624                 :            : 
     625                 :        156 : int aq_nic_xmit(struct aq_nic_s *self, struct sk_buff *skb)
     626                 :            : {
     627                 :        156 :         unsigned int vec = skb->queue_mapping % self->aq_nic_cfg.vecs;
     628                 :        156 :         struct aq_ring_s *ring = NULL;
     629                 :        156 :         unsigned int frags = 0U;
     630                 :        156 :         int err = NETDEV_TX_OK;
     631                 :        156 :         unsigned int tc = 0U;
     632                 :            : 
     633         [ -  + ]:        156 :         frags = skb_shinfo(skb)->nr_frags + 1;
     634                 :            : 
     635                 :        156 :         ring = self->aq_ring_tx[AQ_NIC_TCVEC2RING(self, tc, vec)];
     636                 :            : 
     637         [ -  + ]:        156 :         if (frags > AQ_CFG_SKB_FRAGS_MAX) {
     638                 :          0 :                 dev_kfree_skb_any(skb);
     639                 :          0 :                 goto err_exit;
     640                 :            :         }
     641                 :            : 
     642                 :        156 :         aq_ring_update_queue_state(ring);
     643                 :            : 
     644         [ -  + ]:        156 :         if (self->aq_nic_cfg.priv_flags & BIT(AQ_HW_LOOPBACK_DMA_NET)) {
     645                 :          0 :                 err = NETDEV_TX_BUSY;
     646                 :          0 :                 goto err_exit;
     647                 :            :         }
     648                 :            : 
     649                 :            :         /* Above status update may stop the queue. Check this. */
     650         [ -  + ]:        156 :         if (__netif_subqueue_stopped(self->ndev, ring->idx)) {
     651                 :          0 :                 err = NETDEV_TX_BUSY;
     652                 :          0 :                 goto err_exit;
     653                 :            :         }
     654                 :            : 
     655                 :        156 :         frags = aq_nic_map_skb(self, skb, ring);
     656                 :            : 
     657         [ +  - ]:        156 :         if (likely(frags)) {
     658                 :        156 :                 err = self->aq_hw_ops->hw_ring_tx_xmit(self->aq_hw,
     659                 :            :                                                        ring, frags);
     660                 :            :         } else {
     661                 :            :                 err = NETDEV_TX_BUSY;
     662                 :            :         }
     663                 :            : 
     664                 :        156 : err_exit:
     665                 :        156 :         return err;
     666                 :            : }
     667                 :            : 
     668                 :        114 : int aq_nic_update_interrupt_moderation_settings(struct aq_nic_s *self)
     669                 :            : {
     670                 :        114 :         return self->aq_hw_ops->hw_interrupt_moderation_set(self->aq_hw);
     671                 :            : }
     672                 :            : 
     673                 :         94 : int aq_nic_set_packet_filter(struct aq_nic_s *self, unsigned int flags)
     674                 :            : {
     675                 :         94 :         int err = 0;
     676                 :            : 
     677                 :          0 :         err = self->aq_hw_ops->hw_packet_filter_set(self->aq_hw, flags);
     678   [ -  +  -  - ]:         94 :         if (err < 0)
     679                 :          0 :                 goto err_exit;
     680                 :            : 
     681                 :         94 :         self->packet_filter = flags;
     682                 :            : 
     683                 :          0 : err_exit:
     684                 :          0 :         return err;
     685                 :            : }
     686                 :            : 
     687                 :         94 : int aq_nic_set_multicast_list(struct aq_nic_s *self, struct net_device *ndev)
     688                 :            : {
     689                 :         94 :         const struct aq_hw_ops *hw_ops = self->aq_hw_ops;
     690                 :         94 :         struct aq_nic_cfg_s *cfg = &self->aq_nic_cfg;
     691                 :         94 :         unsigned int packet_filter = ndev->flags;
     692                 :         94 :         struct netdev_hw_addr *ha = NULL;
     693                 :         94 :         unsigned int i = 0U;
     694                 :         94 :         int err = 0;
     695                 :            : 
     696                 :         94 :         self->mc_list.count = 0;
     697         [ -  + ]:         94 :         if (netdev_uc_count(ndev) > AQ_HW_MULTICAST_ADDRESS_MAX) {
     698                 :          0 :                 packet_filter |= IFF_PROMISC;
     699                 :            :         } else {
     700         [ -  + ]:         94 :                 netdev_for_each_uc_addr(ha, ndev) {
     701                 :          0 :                         ether_addr_copy(self->mc_list.ar[i++], ha->addr);
     702                 :            :                 }
     703                 :            :         }
     704                 :            : 
     705                 :         94 :         cfg->is_mc_list_enabled = !!(packet_filter & IFF_MULTICAST);
     706         [ +  - ]:         94 :         if (cfg->is_mc_list_enabled) {
     707         [ -  + ]:         94 :                 if (i + netdev_mc_count(ndev) > AQ_HW_MULTICAST_ADDRESS_MAX) {
     708                 :          0 :                         packet_filter |= IFF_ALLMULTI;
     709                 :            :                 } else {
     710         [ +  + ]:        277 :                         netdev_for_each_mc_addr(ha, ndev) {
     711                 :        183 :                                 ether_addr_copy(self->mc_list.ar[i++],
     712                 :            :                                                 ha->addr);
     713                 :            :                         }
     714                 :            :                 }
     715                 :            :         }
     716                 :            : 
     717         [ +  - ]:         94 :         if (i > 0 && i <= AQ_HW_MULTICAST_ADDRESS_MAX) {
     718                 :         94 :                 self->mc_list.count = i;
     719                 :         94 :                 err = hw_ops->hw_multicast_list_set(self->aq_hw,
     720                 :         94 :                                                     self->mc_list.ar,
     721                 :            :                                                     self->mc_list.count);
     722         [ +  - ]:         94 :                 if (err < 0)
     723                 :            :                         return err;
     724                 :            :         }
     725                 :            : 
     726                 :         94 :         return aq_nic_set_packet_filter(self, packet_filter);
     727                 :            : }
     728                 :            : 
     729                 :          0 : int aq_nic_set_mtu(struct aq_nic_s *self, int new_mtu)
     730                 :            : {
     731                 :          0 :         self->aq_nic_cfg.mtu = new_mtu;
     732                 :            : 
     733                 :          0 :         return 0;
     734                 :            : }
     735                 :            : 
     736                 :          0 : int aq_nic_set_mac(struct aq_nic_s *self, struct net_device *ndev)
     737                 :            : {
     738                 :          0 :         return self->aq_hw_ops->hw_set_mac_address(self->aq_hw, ndev->dev_addr);
     739                 :            : }
     740                 :            : 
     741                 :          0 : unsigned int aq_nic_get_link_speed(struct aq_nic_s *self)
     742                 :            : {
     743                 :          0 :         return self->link_status.mbps;
     744                 :            : }
     745                 :            : 
     746                 :          0 : int aq_nic_get_regs(struct aq_nic_s *self, struct ethtool_regs *regs, void *p)
     747                 :            : {
     748                 :          0 :         u32 *regs_buff = p;
     749                 :          0 :         int err = 0;
     750                 :            : 
     751                 :          0 :         regs->version = 1;
     752                 :            : 
     753                 :          0 :         err = self->aq_hw_ops->hw_get_regs(self->aq_hw,
     754                 :            :                                            self->aq_nic_cfg.aq_hw_caps,
     755                 :            :                                            regs_buff);
     756                 :          0 :         if (err < 0)
     757                 :            :                 goto err_exit;
     758                 :            : 
     759                 :            : err_exit:
     760                 :          0 :         return err;
     761                 :            : }
     762                 :            : 
     763                 :         66 : int aq_nic_get_regs_count(struct aq_nic_s *self)
     764                 :            : {
     765                 :         66 :         return self->aq_nic_cfg.aq_hw_caps->mac_regs_count;
     766                 :            : }
     767                 :            : 
     768                 :          0 : void aq_nic_get_stats(struct aq_nic_s *self, u64 *data)
     769                 :            : {
     770                 :          0 :         struct aq_vec_s *aq_vec = NULL;
     771                 :          0 :         struct aq_stats_s *stats;
     772                 :          0 :         unsigned int count = 0U;
     773                 :          0 :         unsigned int i = 0U;
     774                 :            : 
     775         [ #  # ]:          0 :         if (self->aq_fw_ops->update_stats) {
     776                 :          0 :                 mutex_lock(&self->fwreq_mutex);
     777                 :          0 :                 self->aq_fw_ops->update_stats(self->aq_hw);
     778                 :          0 :                 mutex_unlock(&self->fwreq_mutex);
     779                 :            :         }
     780                 :          0 :         stats = self->aq_hw_ops->hw_get_hw_stats(self->aq_hw);
     781                 :            : 
     782         [ #  # ]:          0 :         if (!stats)
     783                 :          0 :                 goto err_exit;
     784                 :            : 
     785                 :          0 :         data[i] = stats->uprc + stats->mprc + stats->bprc;
     786                 :          0 :         data[++i] = stats->uprc;
     787                 :          0 :         data[++i] = stats->mprc;
     788                 :          0 :         data[++i] = stats->bprc;
     789                 :          0 :         data[++i] = stats->erpt;
     790                 :          0 :         data[++i] = stats->uptc + stats->mptc + stats->bptc;
     791                 :          0 :         data[++i] = stats->uptc;
     792                 :          0 :         data[++i] = stats->mptc;
     793                 :          0 :         data[++i] = stats->bptc;
     794                 :          0 :         data[++i] = stats->ubrc;
     795                 :          0 :         data[++i] = stats->ubtc;
     796                 :          0 :         data[++i] = stats->mbrc;
     797                 :          0 :         data[++i] = stats->mbtc;
     798                 :          0 :         data[++i] = stats->bbrc;
     799                 :          0 :         data[++i] = stats->bbtc;
     800                 :          0 :         data[++i] = stats->ubrc + stats->mbrc + stats->bbrc;
     801                 :          0 :         data[++i] = stats->ubtc + stats->mbtc + stats->bbtc;
     802                 :          0 :         data[++i] = stats->dma_pkt_rc;
     803                 :          0 :         data[++i] = stats->dma_pkt_tc;
     804                 :          0 :         data[++i] = stats->dma_oct_rc;
     805                 :          0 :         data[++i] = stats->dma_oct_tc;
     806                 :          0 :         data[++i] = stats->dpc;
     807                 :            : 
     808                 :          0 :         i++;
     809                 :            : 
     810                 :          0 :         data += i;
     811                 :            : 
     812                 :          0 :         for (i = 0U, aq_vec = self->aq_vec[0];
     813   [ #  #  #  # ]:          0 :                 aq_vec && self->aq_vecs > i; ++i, aq_vec = self->aq_vec[i]) {
     814                 :          0 :                 data += count;
     815                 :          0 :                 aq_vec_get_sw_stats(aq_vec, data, &count);
     816                 :            :         }
     817                 :            : 
     818                 :          0 : err_exit:;
     819                 :          0 : }
     820                 :            : 
     821                 :         84 : static void aq_nic_update_ndev_stats(struct aq_nic_s *self)
     822                 :            : {
     823                 :         84 :         struct aq_stats_s *stats = self->aq_hw_ops->hw_get_hw_stats(self->aq_hw);
     824                 :         84 :         struct net_device *ndev = self->ndev;
     825                 :            : 
     826                 :         84 :         ndev->stats.rx_packets = stats->dma_pkt_rc;
     827                 :         84 :         ndev->stats.rx_bytes = stats->dma_oct_rc;
     828                 :         84 :         ndev->stats.rx_errors = stats->erpr;
     829                 :         84 :         ndev->stats.rx_dropped = stats->dpc;
     830                 :         84 :         ndev->stats.tx_packets = stats->dma_pkt_tc;
     831                 :         84 :         ndev->stats.tx_bytes = stats->dma_oct_tc;
     832                 :         84 :         ndev->stats.tx_errors = stats->erpt;
     833                 :         84 :         ndev->stats.multicast = stats->mprc;
     834                 :         84 : }
     835                 :            : 
     836                 :          0 : void aq_nic_get_link_ksettings(struct aq_nic_s *self,
     837                 :            :                                struct ethtool_link_ksettings *cmd)
     838                 :            : {
     839         [ #  # ]:          0 :         if (self->aq_nic_cfg.aq_hw_caps->media_type == AQ_HW_MEDIA_TYPE_FIBRE)
     840                 :          0 :                 cmd->base.port = PORT_FIBRE;
     841                 :            :         else
     842                 :          0 :                 cmd->base.port = PORT_TP;
     843                 :            :         /* This driver supports only 10G capable adapters, so DUPLEX_FULL */
     844                 :          0 :         cmd->base.duplex = DUPLEX_FULL;
     845                 :          0 :         cmd->base.autoneg = self->aq_nic_cfg.is_autoneg;
     846                 :            : 
     847         [ #  # ]:          0 :         ethtool_link_ksettings_zero_link_mode(cmd, supported);
     848                 :            : 
     849         [ #  # ]:          0 :         if (self->aq_nic_cfg.aq_hw_caps->link_speed_msk & AQ_NIC_RATE_10G)
     850                 :          0 :                 ethtool_link_ksettings_add_link_mode(cmd, supported,
     851                 :            :                                                      10000baseT_Full);
     852                 :            : 
     853         [ #  # ]:          0 :         if (self->aq_nic_cfg.aq_hw_caps->link_speed_msk & AQ_NIC_RATE_5G)
     854                 :          0 :                 ethtool_link_ksettings_add_link_mode(cmd, supported,
     855                 :            :                                                      5000baseT_Full);
     856                 :            : 
     857         [ #  # ]:          0 :         if (self->aq_nic_cfg.aq_hw_caps->link_speed_msk & AQ_NIC_RATE_2GS)
     858                 :          0 :                 ethtool_link_ksettings_add_link_mode(cmd, supported,
     859                 :            :                                                      2500baseT_Full);
     860                 :            : 
     861         [ #  # ]:          0 :         if (self->aq_nic_cfg.aq_hw_caps->link_speed_msk & AQ_NIC_RATE_1G)
     862                 :          0 :                 ethtool_link_ksettings_add_link_mode(cmd, supported,
     863                 :            :                                                      1000baseT_Full);
     864                 :            : 
     865         [ #  # ]:          0 :         if (self->aq_nic_cfg.aq_hw_caps->link_speed_msk & AQ_NIC_RATE_100M)
     866                 :          0 :                 ethtool_link_ksettings_add_link_mode(cmd, supported,
     867                 :            :                                                      100baseT_Full);
     868                 :            : 
     869         [ #  # ]:          0 :         if (self->aq_nic_cfg.aq_hw_caps->flow_control) {
     870                 :          0 :                 ethtool_link_ksettings_add_link_mode(cmd, supported,
     871                 :            :                                                      Pause);
     872                 :          0 :                 ethtool_link_ksettings_add_link_mode(cmd, supported,
     873                 :            :                                                      Asym_Pause);
     874                 :            :         }
     875                 :            : 
     876                 :          0 :         ethtool_link_ksettings_add_link_mode(cmd, supported, Autoneg);
     877                 :            : 
     878         [ #  # ]:          0 :         if (self->aq_nic_cfg.aq_hw_caps->media_type == AQ_HW_MEDIA_TYPE_FIBRE)
     879                 :          0 :                 ethtool_link_ksettings_add_link_mode(cmd, supported, FIBRE);
     880                 :            :         else
     881                 :          0 :                 ethtool_link_ksettings_add_link_mode(cmd, supported, TP);
     882                 :            : 
     883         [ #  # ]:          0 :         ethtool_link_ksettings_zero_link_mode(cmd, advertising);
     884                 :            : 
     885         [ #  # ]:          0 :         if (self->aq_nic_cfg.is_autoneg)
     886                 :          0 :                 ethtool_link_ksettings_add_link_mode(cmd, advertising, Autoneg);
     887                 :            : 
     888         [ #  # ]:          0 :         if (self->aq_nic_cfg.link_speed_msk  & AQ_NIC_RATE_10G)
     889                 :          0 :                 ethtool_link_ksettings_add_link_mode(cmd, advertising,
     890                 :            :                                                      10000baseT_Full);
     891                 :            : 
     892         [ #  # ]:          0 :         if (self->aq_nic_cfg.link_speed_msk  & AQ_NIC_RATE_5G)
     893                 :          0 :                 ethtool_link_ksettings_add_link_mode(cmd, advertising,
     894                 :            :                                                      5000baseT_Full);
     895                 :            : 
     896         [ #  # ]:          0 :         if (self->aq_nic_cfg.link_speed_msk  & AQ_NIC_RATE_2GS)
     897                 :          0 :                 ethtool_link_ksettings_add_link_mode(cmd, advertising,
     898                 :            :                                                      2500baseT_Full);
     899                 :            : 
     900         [ #  # ]:          0 :         if (self->aq_nic_cfg.link_speed_msk  & AQ_NIC_RATE_1G)
     901                 :          0 :                 ethtool_link_ksettings_add_link_mode(cmd, advertising,
     902                 :            :                                                      1000baseT_Full);
     903                 :            : 
     904         [ #  # ]:          0 :         if (self->aq_nic_cfg.link_speed_msk  & AQ_NIC_RATE_100M)
     905                 :          0 :                 ethtool_link_ksettings_add_link_mode(cmd, advertising,
     906                 :            :                                                      100baseT_Full);
     907                 :            : 
     908         [ #  # ]:          0 :         if (self->aq_nic_cfg.fc.cur & AQ_NIC_FC_RX)
     909                 :          0 :                 ethtool_link_ksettings_add_link_mode(cmd, advertising,
     910                 :            :                                                      Pause);
     911                 :            : 
     912                 :            :         /* Asym is when either RX or TX, but not both */
     913                 :          0 :         if (!!(self->aq_nic_cfg.fc.cur & AQ_NIC_FC_TX) ^
     914         [ #  # ]:          0 :             !!(self->aq_nic_cfg.fc.cur & AQ_NIC_FC_RX))
     915                 :          0 :                 ethtool_link_ksettings_add_link_mode(cmd, advertising,
     916                 :            :                                                      Asym_Pause);
     917                 :            : 
     918         [ #  # ]:          0 :         if (self->aq_nic_cfg.aq_hw_caps->media_type == AQ_HW_MEDIA_TYPE_FIBRE)
     919                 :          0 :                 ethtool_link_ksettings_add_link_mode(cmd, advertising, FIBRE);
     920                 :            :         else
     921                 :          0 :                 ethtool_link_ksettings_add_link_mode(cmd, advertising, TP);
     922                 :          0 : }
     923                 :            : 
     924                 :          0 : int aq_nic_set_link_ksettings(struct aq_nic_s *self,
     925                 :            :                               const struct ethtool_link_ksettings *cmd)
     926                 :            : {
     927                 :          0 :         u32 speed = 0U;
     928                 :          0 :         u32 rate = 0U;
     929                 :          0 :         int err = 0;
     930                 :            : 
     931         [ #  # ]:          0 :         if (cmd->base.autoneg == AUTONEG_ENABLE) {
     932                 :          0 :                 rate = self->aq_nic_cfg.aq_hw_caps->link_speed_msk;
     933                 :          0 :                 self->aq_nic_cfg.is_autoneg = true;
     934                 :            :         } else {
     935                 :          0 :                 speed = cmd->base.speed;
     936                 :            : 
     937   [ #  #  #  #  :          0 :                 switch (speed) {
                   #  # ]
     938                 :            :                 case SPEED_100:
     939                 :            :                         rate = AQ_NIC_RATE_100M;
     940                 :            :                         break;
     941                 :            : 
     942                 :          0 :                 case SPEED_1000:
     943                 :          0 :                         rate = AQ_NIC_RATE_1G;
     944                 :          0 :                         break;
     945                 :            : 
     946                 :          0 :                 case SPEED_2500:
     947                 :          0 :                         rate = AQ_NIC_RATE_2GS;
     948                 :          0 :                         break;
     949                 :            : 
     950                 :          0 :                 case SPEED_5000:
     951                 :          0 :                         rate = AQ_NIC_RATE_5G;
     952                 :          0 :                         break;
     953                 :            : 
     954                 :          0 :                 case SPEED_10000:
     955                 :          0 :                         rate = AQ_NIC_RATE_10G;
     956                 :          0 :                         break;
     957                 :            : 
     958                 :          0 :                 default:
     959                 :          0 :                         err = -1;
     960                 :          0 :                         goto err_exit;
     961                 :          0 :                 break;
     962                 :            :                 }
     963         [ #  # ]:          0 :                 if (!(self->aq_nic_cfg.aq_hw_caps->link_speed_msk & rate)) {
     964                 :          0 :                         err = -1;
     965                 :          0 :                         goto err_exit;
     966                 :            :                 }
     967                 :            : 
     968                 :          0 :                 self->aq_nic_cfg.is_autoneg = false;
     969                 :            :         }
     970                 :            : 
     971                 :          0 :         mutex_lock(&self->fwreq_mutex);
     972                 :          0 :         err = self->aq_fw_ops->set_link_speed(self->aq_hw, rate);
     973                 :          0 :         mutex_unlock(&self->fwreq_mutex);
     974         [ #  # ]:          0 :         if (err < 0)
     975                 :          0 :                 goto err_exit;
     976                 :            : 
     977                 :          0 :         self->aq_nic_cfg.link_speed_msk = rate;
     978                 :            : 
     979                 :          0 : err_exit:
     980                 :          0 :         return err;
     981                 :            : }
     982                 :            : 
     983                 :        465 : struct aq_nic_cfg_s *aq_nic_get_cfg(struct aq_nic_s *self)
     984                 :            : {
     985         [ +  + ]:         66 :         return &self->aq_nic_cfg;
     986                 :            : }
     987                 :            : 
     988                 :         33 : u32 aq_nic_get_fw_version(struct aq_nic_s *self)
     989                 :            : {
     990                 :         33 :         u32 fw_version = 0U;
     991                 :            : 
     992                 :         33 :         self->aq_hw_ops->hw_get_fw_version(self->aq_hw, &fw_version);
     993                 :            : 
     994                 :         33 :         return fw_version;
     995                 :            : }
     996                 :            : 
     997                 :         33 : int aq_nic_set_loopback(struct aq_nic_s *self)
     998                 :            : {
     999                 :         33 :         struct aq_nic_cfg_s *cfg = &self->aq_nic_cfg;
    1000                 :            : 
    1001         [ +  - ]:         33 :         if (!self->aq_hw_ops->hw_set_loopback ||
    1002         [ +  + ]:         33 :             !self->aq_fw_ops->set_phyloopback)
    1003                 :            :                 return -ENOTSUPP;
    1004                 :            : 
    1005                 :         28 :         mutex_lock(&self->fwreq_mutex);
    1006                 :         28 :         self->aq_hw_ops->hw_set_loopback(self->aq_hw,
    1007                 :            :                                          AQ_HW_LOOPBACK_DMA_SYS,
    1008                 :         28 :                                          !!(cfg->priv_flags &
    1009                 :            :                                             BIT(AQ_HW_LOOPBACK_DMA_SYS)));
    1010                 :            : 
    1011                 :         28 :         self->aq_hw_ops->hw_set_loopback(self->aq_hw,
    1012                 :            :                                          AQ_HW_LOOPBACK_PKT_SYS,
    1013                 :         28 :                                          !!(cfg->priv_flags &
    1014                 :            :                                             BIT(AQ_HW_LOOPBACK_PKT_SYS)));
    1015                 :            : 
    1016                 :         28 :         self->aq_hw_ops->hw_set_loopback(self->aq_hw,
    1017                 :            :                                          AQ_HW_LOOPBACK_DMA_NET,
    1018                 :         28 :                                          !!(cfg->priv_flags &
    1019                 :            :                                             BIT(AQ_HW_LOOPBACK_DMA_NET)));
    1020                 :            : 
    1021                 :         28 :         self->aq_fw_ops->set_phyloopback(self->aq_hw,
    1022                 :            :                                          AQ_HW_LOOPBACK_PHYINT_SYS,
    1023                 :         28 :                                          !!(cfg->priv_flags &
    1024                 :            :                                             BIT(AQ_HW_LOOPBACK_PHYINT_SYS)));
    1025                 :            : 
    1026                 :         28 :         self->aq_fw_ops->set_phyloopback(self->aq_hw,
    1027                 :            :                                          AQ_HW_LOOPBACK_PHYEXT_SYS,
    1028                 :         28 :                                          !!(cfg->priv_flags &
    1029                 :            :                                             BIT(AQ_HW_LOOPBACK_PHYEXT_SYS)));
    1030                 :         28 :         mutex_unlock(&self->fwreq_mutex);
    1031                 :            : 
    1032                 :         28 :         return 0;
    1033                 :            : }
    1034                 :            : 
    1035                 :          0 : int aq_nic_stop(struct aq_nic_s *self)
    1036                 :            : {
    1037                 :          0 :         struct aq_vec_s *aq_vec = NULL;
    1038                 :          0 :         unsigned int i = 0U;
    1039                 :            : 
    1040                 :          0 :         netif_tx_disable(self->ndev);
    1041                 :          0 :         netif_carrier_off(self->ndev);
    1042                 :            : 
    1043                 :          0 :         del_timer_sync(&self->service_timer);
    1044                 :          0 :         cancel_work_sync(&self->service_task);
    1045                 :            : 
    1046                 :          0 :         self->aq_hw_ops->hw_irq_disable(self->aq_hw, AQ_CFG_IRQ_MASK);
    1047                 :            : 
    1048         [ #  # ]:          0 :         if (self->aq_nic_cfg.is_polling)
    1049                 :          0 :                 del_timer_sync(&self->polling_timer);
    1050                 :            :         else
    1051                 :          0 :                 aq_pci_func_free_irqs(self);
    1052                 :            : 
    1053                 :          0 :         aq_ptp_irq_free(self);
    1054                 :            : 
    1055                 :          0 :         for (i = 0U, aq_vec = self->aq_vec[0];
    1056         [ #  # ]:          0 :                 self->aq_vecs > i; ++i, aq_vec = self->aq_vec[i])
    1057                 :          0 :                 aq_vec_stop(aq_vec);
    1058                 :            : 
    1059                 :          0 :         aq_ptp_ring_stop(self);
    1060                 :            : 
    1061                 :          0 :         return self->aq_hw_ops->hw_stop(self->aq_hw);
    1062                 :            : }
    1063                 :            : 
    1064                 :          0 : void aq_nic_set_power(struct aq_nic_s *self)
    1065                 :            : {
    1066         [ #  # ]:          0 :         if (self->power_state != AQ_HW_POWER_STATE_D0 ||
    1067         [ #  # ]:          0 :             self->aq_hw->aq_nic_cfg->wol)
    1068         [ #  # ]:          0 :                 if (likely(self->aq_fw_ops->set_power)) {
    1069                 :          0 :                         mutex_lock(&self->fwreq_mutex);
    1070                 :          0 :                         self->aq_fw_ops->set_power(self->aq_hw,
    1071                 :            :                                                    self->power_state,
    1072                 :          0 :                                                    self->ndev->dev_addr);
    1073                 :          0 :                         mutex_unlock(&self->fwreq_mutex);
    1074                 :            :                 }
    1075                 :          0 : }
    1076                 :            : 
    1077                 :          0 : void aq_nic_deinit(struct aq_nic_s *self, bool link_down)
    1078                 :            : {
    1079                 :          0 :         struct aq_vec_s *aq_vec = NULL;
    1080                 :          0 :         unsigned int i = 0U;
    1081                 :            : 
    1082         [ #  # ]:          0 :         if (!self)
    1083                 :          0 :                 goto err_exit;
    1084                 :            : 
    1085                 :          0 :         for (i = 0U, aq_vec = self->aq_vec[0];
    1086         [ #  # ]:          0 :                 self->aq_vecs > i; ++i, aq_vec = self->aq_vec[i])
    1087                 :          0 :                 aq_vec_deinit(aq_vec);
    1088                 :            : 
    1089                 :          0 :         aq_ptp_unregister(self);
    1090                 :          0 :         aq_ptp_ring_deinit(self);
    1091                 :          0 :         aq_ptp_ring_free(self);
    1092                 :          0 :         aq_ptp_free(self);
    1093                 :            : 
    1094   [ #  #  #  # ]:          0 :         if (likely(self->aq_fw_ops->deinit) && link_down) {
    1095                 :          0 :                 mutex_lock(&self->fwreq_mutex);
    1096                 :          0 :                 self->aq_fw_ops->deinit(self->aq_hw);
    1097                 :          0 :                 mutex_unlock(&self->fwreq_mutex);
    1098                 :            :         }
    1099                 :            : 
    1100                 :          0 : err_exit:;
    1101                 :          0 : }
    1102                 :            : 
    1103                 :         45 : void aq_nic_free_vectors(struct aq_nic_s *self)
    1104                 :            : {
    1105                 :         45 :         unsigned int i = 0U;
    1106                 :            : 
    1107         [ +  - ]:         45 :         if (!self)
    1108                 :          0 :                 goto err_exit;
    1109                 :            : 
    1110         [ +  + ]:        405 :         for (i = ARRAY_SIZE(self->aq_vec); i--;) {
    1111         [ -  + ]:        360 :                 if (self->aq_vec[i]) {
    1112                 :          0 :                         aq_vec_free(self->aq_vec[i]);
    1113                 :          0 :                         self->aq_vec[i] = NULL;
    1114                 :            :                 }
    1115                 :            :         }
    1116                 :            : 
    1117                 :         45 : err_exit:;
    1118                 :         45 : }
    1119                 :            : 
    1120                 :          0 : void aq_nic_shutdown(struct aq_nic_s *self)
    1121                 :            : {
    1122                 :          0 :         int err = 0;
    1123                 :            : 
    1124         [ #  # ]:          0 :         if (!self->ndev)
    1125                 :            :                 return;
    1126                 :            : 
    1127                 :          0 :         rtnl_lock();
    1128                 :            : 
    1129                 :          0 :         netif_device_detach(self->ndev);
    1130                 :            : 
    1131         [ #  # ]:          0 :         if (netif_running(self->ndev)) {
    1132                 :          0 :                 err = aq_nic_stop(self);
    1133         [ #  # ]:          0 :                 if (err < 0)
    1134                 :          0 :                         goto err_exit;
    1135                 :            :         }
    1136                 :          0 :         aq_nic_deinit(self, !self->aq_hw->aq_nic_cfg->wol);
    1137                 :          0 :         aq_nic_set_power(self);
    1138                 :            : 
    1139                 :          0 : err_exit:
    1140                 :          0 :         rtnl_unlock();
    1141                 :            : }
    1142                 :            : 
    1143                 :          0 : u8 aq_nic_reserve_filter(struct aq_nic_s *self, enum aq_rx_filter_type type)
    1144                 :            : {
    1145                 :          0 :         u8 location = 0xFF;
    1146                 :          0 :         u32 fltr_cnt;
    1147                 :          0 :         u32 n_bit;
    1148                 :            : 
    1149      [ #  #  # ]:          0 :         switch (type) {
    1150                 :          0 :         case aq_rx_filter_ethertype:
    1151                 :          0 :                 location = AQ_RX_LAST_LOC_FETHERT - AQ_RX_FIRST_LOC_FETHERT -
    1152                 :          0 :                            self->aq_hw_rx_fltrs.fet_reserved_count;
    1153                 :          0 :                 self->aq_hw_rx_fltrs.fet_reserved_count++;
    1154                 :          0 :                 break;
    1155                 :          0 :         case aq_rx_filter_l3l4:
    1156                 :          0 :                 fltr_cnt = AQ_RX_LAST_LOC_FL3L4 - AQ_RX_FIRST_LOC_FL3L4;
    1157                 :          0 :                 n_bit = fltr_cnt - self->aq_hw_rx_fltrs.fl3l4.reserved_count;
    1158                 :            : 
    1159                 :          0 :                 self->aq_hw_rx_fltrs.fl3l4.active_ipv4 |= BIT(n_bit);
    1160                 :          0 :                 self->aq_hw_rx_fltrs.fl3l4.reserved_count++;
    1161                 :          0 :                 location = n_bit;
    1162                 :          0 :                 break;
    1163                 :            :         default:
    1164                 :            :                 break;
    1165                 :            :         }
    1166                 :            : 
    1167                 :          0 :         return location;
    1168                 :            : }
    1169                 :            : 
    1170                 :          0 : void aq_nic_release_filter(struct aq_nic_s *self, enum aq_rx_filter_type type,
    1171                 :            :                            u32 location)
    1172                 :            : {
    1173      [ #  #  # ]:          0 :         switch (type) {
    1174                 :          0 :         case aq_rx_filter_ethertype:
    1175                 :          0 :                 self->aq_hw_rx_fltrs.fet_reserved_count--;
    1176                 :          0 :                 break;
    1177                 :          0 :         case aq_rx_filter_l3l4:
    1178                 :          0 :                 self->aq_hw_rx_fltrs.fl3l4.reserved_count--;
    1179                 :          0 :                 self->aq_hw_rx_fltrs.fl3l4.active_ipv4 &= ~BIT(location);
    1180                 :          0 :                 break;
    1181                 :            :         default:
    1182                 :            :                 break;
    1183                 :            :         }
    1184                 :          0 : }

Generated by: LCOV version 1.14