linux/drivers/net/ethernet/aquantia/atlantic/aq_main.c
<<
>>
Prefs
   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
  18MODULE_LICENSE("GPL v2");
  19MODULE_VERSION(AQ_CFG_DRV_VERSION);
  20MODULE_AUTHOR(AQ_CFG_DRV_AUTHOR);
  21MODULE_DESCRIPTION(AQ_CFG_DRV_DESC);
  22
  23static const char aq_ndev_driver_name[] = AQ_CFG_DRV_NAME;
  24
  25static const struct net_device_ops aq_ndev_ops;
  26
  27static struct workqueue_struct *aq_ndev_wq;
  28
  29void aq_ndev_schedule_work(struct work_struct *work)
  30{
  31        queue_work(aq_ndev_wq, work);
  32}
  33
  34struct 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
  51static 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
  72err_exit:
  73        if (err < 0)
  74                aq_nic_deinit(aq_nic);
  75        return err;
  76}
  77
  78static 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
  88err_exit:
  89        return err;
  90}
  91
  92static 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
  99static 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
 108err_exit:
 109        return err;
 110}
 111
 112static 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
 173err_exit:
 174        return err;
 175}
 176
 177static 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
 189err_exit:
 190        return err;
 191}
 192
 193static void aq_ndev_set_multicast_settings(struct net_device *ndev)
 194{
 195        struct aq_nic_s *aq_nic = netdev_priv(ndev);
 196
 197        aq_nic_set_packet_filter(aq_nic, ndev->flags);
 198
 199        aq_nic_set_multicast_list(aq_nic, ndev);
 200}
 201
 202static int aq_ndo_vlan_rx_add_vid(struct net_device *ndev, __be16 proto,
 203                                  u16 vid)
 204{
 205        struct aq_nic_s *aq_nic = netdev_priv(ndev);
 206
 207        if (!aq_nic->aq_hw_ops->hw_filter_vlan_set)
 208                return -EOPNOTSUPP;
 209
 210        set_bit(vid, aq_nic->active_vlans);
 211
 212        return aq_filters_vlans_update(aq_nic);
 213}
 214
 215static int aq_ndo_vlan_rx_kill_vid(struct net_device *ndev, __be16 proto,
 216                                   u16 vid)
 217{
 218        struct aq_nic_s *aq_nic = netdev_priv(ndev);
 219
 220        if (!aq_nic->aq_hw_ops->hw_filter_vlan_set)
 221                return -EOPNOTSUPP;
 222
 223        clear_bit(vid, aq_nic->active_vlans);
 224
 225        if (-ENOENT == aq_del_fvlan_by_vlan(aq_nic, vid))
 226                return aq_filters_vlans_update(aq_nic);
 227
 228        return 0;
 229}
 230
 231static const struct net_device_ops aq_ndev_ops = {
 232        .ndo_open = aq_ndev_open,
 233        .ndo_stop = aq_ndev_close,
 234        .ndo_start_xmit = aq_ndev_start_xmit,
 235        .ndo_set_rx_mode = aq_ndev_set_multicast_settings,
 236        .ndo_change_mtu = aq_ndev_change_mtu,
 237        .ndo_set_mac_address = aq_ndev_set_mac_address,
 238        .ndo_set_features = aq_ndev_set_features,
 239        .ndo_vlan_rx_add_vid = aq_ndo_vlan_rx_add_vid,
 240        .ndo_vlan_rx_kill_vid = aq_ndo_vlan_rx_kill_vid,
 241};
 242
 243static int __init aq_ndev_init_module(void)
 244{
 245        int ret;
 246
 247        aq_ndev_wq = create_singlethread_workqueue(aq_ndev_driver_name);
 248        if (!aq_ndev_wq) {
 249                pr_err("Failed to create workqueue\n");
 250                return -ENOMEM;
 251        }
 252
 253        ret = aq_pci_func_register_driver();
 254        if (ret) {
 255                destroy_workqueue(aq_ndev_wq);
 256                return ret;
 257        }
 258
 259        return 0;
 260}
 261
 262static void __exit aq_ndev_exit_module(void)
 263{
 264        aq_pci_func_unregister_driver();
 265
 266        if (aq_ndev_wq) {
 267                destroy_workqueue(aq_ndev_wq);
 268                aq_ndev_wq = NULL;
 269        }
 270}
 271
 272module_init(aq_ndev_init_module);
 273module_exit(aq_ndev_exit_module);
 274