root/drivers/net/ethernet/aquantia/atlantic/aq_main.c

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

DEFINITIONS

This source file includes following definitions.
  1. aq_ndev_schedule_work
  2. aq_ndev_alloc
  3. aq_ndev_open
  4. aq_ndev_close
  5. aq_ndev_start_xmit
  6. aq_ndev_change_mtu
  7. aq_ndev_set_features
  8. aq_ndev_set_mac_address
  9. aq_ndev_set_multicast_settings
  10. aq_ndo_vlan_rx_add_vid
  11. aq_ndo_vlan_rx_kill_vid
  12. aq_ndev_init_module
  13. aq_ndev_exit_module

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * aQuantia Corporation Network Driver
   4  * Copyright (C) 2014-2017 aQuantia Corporation. All rights reserved
   5  */
   6 
   7 /* File aq_main.c: Main file for aQuantia Linux driver. */
   8 
   9 #include "aq_main.h"
  10 #include "aq_nic.h"
  11 #include "aq_pci_func.h"
  12 #include "aq_ethtool.h"
  13 #include "aq_filters.h"
  14 
  15 #include <linux/netdevice.h>
  16 #include <linux/module.h>
  17 
  18 MODULE_LICENSE("GPL v2");
  19 MODULE_VERSION(AQ_CFG_DRV_VERSION);
  20 MODULE_AUTHOR(AQ_CFG_DRV_AUTHOR);
  21 MODULE_DESCRIPTION(AQ_CFG_DRV_DESC);
  22 
  23 static const char aq_ndev_driver_name[] = AQ_CFG_DRV_NAME;
  24 
  25 static const struct net_device_ops aq_ndev_ops;
  26 
  27 static struct workqueue_struct *aq_ndev_wq;
  28 
  29 void aq_ndev_schedule_work(struct work_struct *work)
  30 {
  31         queue_work(aq_ndev_wq, work);
  32 }
  33 
  34 struct net_device *aq_ndev_alloc(void)
  35 {
  36         struct net_device *ndev = NULL;
  37         struct aq_nic_s *aq_nic = NULL;
  38 
  39         ndev = alloc_etherdev_mq(sizeof(struct aq_nic_s), AQ_CFG_VECS_MAX);
  40         if (!ndev)
  41                 return NULL;
  42 
  43         aq_nic = netdev_priv(ndev);
  44         aq_nic->ndev = ndev;
  45         ndev->netdev_ops = &aq_ndev_ops;
  46         ndev->ethtool_ops = &aq_ethtool_ops;
  47 
  48         return ndev;
  49 }
  50 
  51 static int aq_ndev_open(struct net_device *ndev)
  52 {
  53         int err = 0;
  54         struct aq_nic_s *aq_nic = netdev_priv(ndev);
  55 
  56         err = aq_nic_init(aq_nic);
  57         if (err < 0)
  58                 goto err_exit;
  59 
  60         err = aq_reapply_rxnfc_all_rules(aq_nic);
  61         if (err < 0)
  62                 goto err_exit;
  63 
  64         err = aq_filters_vlans_update(aq_nic);
  65         if (err < 0)
  66                 goto err_exit;
  67 
  68         err = aq_nic_start(aq_nic);
  69         if (err < 0)
  70                 goto err_exit;
  71 
  72 err_exit:
  73         if (err < 0)
  74                 aq_nic_deinit(aq_nic);
  75         return err;
  76 }
  77 
  78 static int aq_ndev_close(struct net_device *ndev)
  79 {
  80         int err = 0;
  81         struct aq_nic_s *aq_nic = netdev_priv(ndev);
  82 
  83         err = aq_nic_stop(aq_nic);
  84         if (err < 0)
  85                 goto err_exit;
  86         aq_nic_deinit(aq_nic);
  87 
  88 err_exit:
  89         return err;
  90 }
  91 
  92 static int aq_ndev_start_xmit(struct sk_buff *skb, struct net_device *ndev)
  93 {
  94         struct aq_nic_s *aq_nic = netdev_priv(ndev);
  95 
  96         return aq_nic_xmit(aq_nic, skb);
  97 }
  98 
  99 static int aq_ndev_change_mtu(struct net_device *ndev, int new_mtu)
 100 {
 101         struct aq_nic_s *aq_nic = netdev_priv(ndev);
 102         int err = aq_nic_set_mtu(aq_nic, new_mtu + ETH_HLEN);
 103 
 104         if (err < 0)
 105                 goto err_exit;
 106         ndev->mtu = new_mtu;
 107 
 108 err_exit:
 109         return err;
 110 }
 111 
 112 static int aq_ndev_set_features(struct net_device *ndev,
 113                                 netdev_features_t features)
 114 {
 115         bool is_vlan_rx_strip = !!(features & NETIF_F_HW_VLAN_CTAG_RX);
 116         bool is_vlan_tx_insert = !!(features & NETIF_F_HW_VLAN_CTAG_TX);
 117         struct aq_nic_s *aq_nic = netdev_priv(ndev);
 118         bool need_ndev_restart = false;
 119         struct aq_nic_cfg_s *aq_cfg;
 120         bool is_lro = false;
 121         int err = 0;
 122 
 123         aq_cfg = aq_nic_get_cfg(aq_nic);
 124 
 125         if (!(features & NETIF_F_NTUPLE)) {
 126                 if (aq_nic->ndev->features & NETIF_F_NTUPLE) {
 127                         err = aq_clear_rxnfc_all_rules(aq_nic);
 128                         if (unlikely(err))
 129                                 goto err_exit;
 130                 }
 131         }
 132         if (!(features & NETIF_F_HW_VLAN_CTAG_FILTER)) {
 133                 if (aq_nic->ndev->features & NETIF_F_HW_VLAN_CTAG_FILTER) {
 134                         err = aq_filters_vlan_offload_off(aq_nic);
 135                         if (unlikely(err))
 136                                 goto err_exit;
 137                 }
 138         }
 139 
 140         aq_cfg->features = features;
 141 
 142         if (aq_cfg->aq_hw_caps->hw_features & NETIF_F_LRO) {
 143                 is_lro = features & NETIF_F_LRO;
 144 
 145                 if (aq_cfg->is_lro != is_lro) {
 146                         aq_cfg->is_lro = is_lro;
 147                         need_ndev_restart = true;
 148                 }
 149         }
 150 
 151         if ((aq_nic->ndev->features ^ features) & NETIF_F_RXCSUM) {
 152                 err = aq_nic->aq_hw_ops->hw_set_offload(aq_nic->aq_hw,
 153                                                         aq_cfg);
 154 
 155                 if (unlikely(err))
 156                         goto err_exit;
 157         }
 158 
 159         if (aq_cfg->is_vlan_rx_strip != is_vlan_rx_strip) {
 160                 aq_cfg->is_vlan_rx_strip = is_vlan_rx_strip;
 161                 need_ndev_restart = true;
 162         }
 163         if (aq_cfg->is_vlan_tx_insert != is_vlan_tx_insert) {
 164                 aq_cfg->is_vlan_tx_insert = is_vlan_tx_insert;
 165                 need_ndev_restart = true;
 166         }
 167 
 168         if (need_ndev_restart && netif_running(ndev)) {
 169                 aq_ndev_close(ndev);
 170                 aq_ndev_open(ndev);
 171         }
 172 
 173 err_exit:
 174         return err;
 175 }
 176 
 177 static int aq_ndev_set_mac_address(struct net_device *ndev, void *addr)
 178 {
 179         struct aq_nic_s *aq_nic = netdev_priv(ndev);
 180         int err = 0;
 181 
 182         err = eth_mac_addr(ndev, addr);
 183         if (err < 0)
 184                 goto err_exit;
 185         err = aq_nic_set_mac(aq_nic, ndev);
 186         if (err < 0)
 187                 goto err_exit;
 188 
 189 err_exit:
 190         return err;
 191 }
 192 
 193 static void aq_ndev_set_multicast_settings(struct net_device *ndev)
 194 {
 195         struct aq_nic_s *aq_nic = netdev_priv(ndev);
 196 
 197         (void)aq_nic_set_multicast_list(aq_nic, ndev);
 198 }
 199 
 200 static int aq_ndo_vlan_rx_add_vid(struct net_device *ndev, __be16 proto,
 201                                   u16 vid)
 202 {
 203         struct aq_nic_s *aq_nic = netdev_priv(ndev);
 204 
 205         if (!aq_nic->aq_hw_ops->hw_filter_vlan_set)
 206                 return -EOPNOTSUPP;
 207 
 208         set_bit(vid, aq_nic->active_vlans);
 209 
 210         return aq_filters_vlans_update(aq_nic);
 211 }
 212 
 213 static int aq_ndo_vlan_rx_kill_vid(struct net_device *ndev, __be16 proto,
 214                                    u16 vid)
 215 {
 216         struct aq_nic_s *aq_nic = netdev_priv(ndev);
 217 
 218         if (!aq_nic->aq_hw_ops->hw_filter_vlan_set)
 219                 return -EOPNOTSUPP;
 220 
 221         clear_bit(vid, aq_nic->active_vlans);
 222 
 223         if (-ENOENT == aq_del_fvlan_by_vlan(aq_nic, vid))
 224                 return aq_filters_vlans_update(aq_nic);
 225 
 226         return 0;
 227 }
 228 
 229 static const struct net_device_ops aq_ndev_ops = {
 230         .ndo_open = aq_ndev_open,
 231         .ndo_stop = aq_ndev_close,
 232         .ndo_start_xmit = aq_ndev_start_xmit,
 233         .ndo_set_rx_mode = aq_ndev_set_multicast_settings,
 234         .ndo_change_mtu = aq_ndev_change_mtu,
 235         .ndo_set_mac_address = aq_ndev_set_mac_address,
 236         .ndo_set_features = aq_ndev_set_features,
 237         .ndo_vlan_rx_add_vid = aq_ndo_vlan_rx_add_vid,
 238         .ndo_vlan_rx_kill_vid = aq_ndo_vlan_rx_kill_vid,
 239 };
 240 
 241 static int __init aq_ndev_init_module(void)
 242 {
 243         int ret;
 244 
 245         aq_ndev_wq = create_singlethread_workqueue(aq_ndev_driver_name);
 246         if (!aq_ndev_wq) {
 247                 pr_err("Failed to create workqueue\n");
 248                 return -ENOMEM;
 249         }
 250 
 251         ret = aq_pci_func_register_driver();
 252         if (ret) {
 253                 destroy_workqueue(aq_ndev_wq);
 254                 return ret;
 255         }
 256 
 257         return 0;
 258 }
 259 
 260 static void __exit aq_ndev_exit_module(void)
 261 {
 262         aq_pci_func_unregister_driver();
 263 
 264         if (aq_ndev_wq) {
 265                 destroy_workqueue(aq_ndev_wq);
 266                 aq_ndev_wq = NULL;
 267         }
 268 }
 269 
 270 module_init(aq_ndev_init_module);
 271 module_exit(aq_ndev_exit_module);

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