1 /* 2 * aQuantia Corporation Network Driver 3 * Copyright (C) 2014-2017 aQuantia Corporation. All rights reserved 4 * 5 * This program is free software; you can redistribute it and/or modify it 6 * under the terms and conditions of the GNU General Public License, 7 * version 2, as published by the Free Software Foundation. 8 */ 9 10 /* File aq_main.c: Main file for aQuantia Linux driver. */ 11 12 #include "aq_main.h" 13 #include "aq_nic.h" 14 #include "aq_pci_func.h" 15 #include "aq_ethtool.h" 16 #include "aq_filters.h" 17 18 #include <linux/netdevice.h> 19 #include <linux/module.h> 20 21 MODULE_LICENSE("GPL v2"); 22 MODULE_VERSION(AQ_CFG_DRV_VERSION); 23 MODULE_AUTHOR(AQ_CFG_DRV_AUTHOR); 24 MODULE_DESCRIPTION(AQ_CFG_DRV_DESC); 25 26 static const struct net_device_ops aq_ndev_ops; 27 28 struct net_device *aq_ndev_alloc(void) 29 { 30 struct net_device *ndev = NULL; 31 struct aq_nic_s *aq_nic = NULL; 32 33 ndev = alloc_etherdev_mq(sizeof(struct aq_nic_s), AQ_CFG_VECS_MAX); 34 if (!ndev) 35 return NULL; 36 37 aq_nic = netdev_priv(ndev); 38 aq_nic->ndev = ndev; 39 ndev->netdev_ops = &aq_ndev_ops; 40 ndev->ethtool_ops = &aq_ethtool_ops; 41 42 return ndev; 43 } 44 45 static int aq_ndev_open(struct net_device *ndev) 46 { 47 int err = 0; 48 struct aq_nic_s *aq_nic = netdev_priv(ndev); 49 50 err = aq_nic_init(aq_nic); 51 if (err < 0) 52 goto err_exit; 53 54 err = aq_reapply_rxnfc_all_rules(aq_nic); 55 if (err < 0) 56 goto err_exit; 57 58 err = aq_nic_start(aq_nic); 59 if (err < 0) 60 goto err_exit; 61 62 err_exit: 63 if (err < 0) 64 aq_nic_deinit(aq_nic); 65 return err; 66 } 67 68 static int aq_ndev_close(struct net_device *ndev) 69 { 70 int err = 0; 71 struct aq_nic_s *aq_nic = netdev_priv(ndev); 72 73 err = aq_nic_stop(aq_nic); 74 if (err < 0) 75 goto err_exit; 76 aq_nic_deinit(aq_nic); 77 78 err_exit: 79 return err; 80 } 81 82 static int aq_ndev_start_xmit(struct sk_buff *skb, struct net_device *ndev) 83 { 84 struct aq_nic_s *aq_nic = netdev_priv(ndev); 85 86 return aq_nic_xmit(aq_nic, skb); 87 } 88 89 static int aq_ndev_change_mtu(struct net_device *ndev, int new_mtu) 90 { 91 struct aq_nic_s *aq_nic = netdev_priv(ndev); 92 int err = aq_nic_set_mtu(aq_nic, new_mtu + ETH_HLEN); 93 94 if (err < 0) 95 goto err_exit; 96 ndev->mtu = new_mtu; 97 98 err_exit: 99 return err; 100 } 101 102 static int aq_ndev_set_features(struct net_device *ndev, 103 netdev_features_t features) 104 { 105 struct aq_nic_s *aq_nic = netdev_priv(ndev); 106 struct aq_nic_cfg_s *aq_cfg = aq_nic_get_cfg(aq_nic); 107 bool is_lro = false; 108 int err = 0; 109 110 if (!(features & NETIF_F_NTUPLE)) { 111 if (aq_nic->ndev->features & NETIF_F_NTUPLE) { 112 err = aq_clear_rxnfc_all_rules(aq_nic); 113 if (unlikely(err)) 114 goto err_exit; 115 } 116 } 117 if (!(features & NETIF_F_HW_VLAN_CTAG_FILTER)) { 118 if (aq_nic->ndev->features & NETIF_F_HW_VLAN_CTAG_FILTER) { 119 err = aq_filters_vlan_offload_off(aq_nic); 120 if (unlikely(err)) 121 goto err_exit; 122 } 123 } 124 125 aq_cfg->features = features; 126 127 if (aq_cfg->aq_hw_caps->hw_features & NETIF_F_LRO) { 128 is_lro = features & NETIF_F_LRO; 129 130 if (aq_cfg->is_lro != is_lro) { 131 aq_cfg->is_lro = is_lro; 132 133 if (netif_running(ndev)) { 134 aq_ndev_close(ndev); 135 aq_ndev_open(ndev); 136 } 137 } 138 } 139 if ((aq_nic->ndev->features ^ features) & NETIF_F_RXCSUM) 140 err = aq_nic->aq_hw_ops->hw_set_offload(aq_nic->aq_hw, 141 aq_cfg); 142 143 err_exit: 144 return err; 145 } 146 147 static int aq_ndev_set_mac_address(struct net_device *ndev, void *addr) 148 { 149 struct aq_nic_s *aq_nic = netdev_priv(ndev); 150 int err = 0; 151 152 err = eth_mac_addr(ndev, addr); 153 if (err < 0) 154 goto err_exit; 155 err = aq_nic_set_mac(aq_nic, ndev); 156 if (err < 0) 157 goto err_exit; 158 159 err_exit: 160 return err; 161 } 162 163 static void aq_ndev_set_multicast_settings(struct net_device *ndev) 164 { 165 struct aq_nic_s *aq_nic = netdev_priv(ndev); 166 167 aq_nic_set_packet_filter(aq_nic, ndev->flags); 168 169 aq_nic_set_multicast_list(aq_nic, ndev); 170 } 171 172 static int aq_ndo_vlan_rx_add_vid(struct net_device *ndev, __be16 proto, 173 u16 vid) 174 { 175 struct aq_nic_s *aq_nic = netdev_priv(ndev); 176 177 if (!aq_nic->aq_hw_ops->hw_filter_vlan_set) 178 return -EOPNOTSUPP; 179 180 set_bit(vid, aq_nic->active_vlans); 181 182 return aq_filters_vlans_update(aq_nic); 183 } 184 185 static int aq_ndo_vlan_rx_kill_vid(struct net_device *ndev, __be16 proto, 186 u16 vid) 187 { 188 struct aq_nic_s *aq_nic = netdev_priv(ndev); 189 190 if (!aq_nic->aq_hw_ops->hw_filter_vlan_set) 191 return -EOPNOTSUPP; 192 193 clear_bit(vid, aq_nic->active_vlans); 194 195 if (-ENOENT == aq_del_fvlan_by_vlan(aq_nic, vid)) 196 return aq_filters_vlans_update(aq_nic); 197 198 return 0; 199 } 200 201 static const struct net_device_ops aq_ndev_ops = { 202 .ndo_open = aq_ndev_open, 203 .ndo_stop = aq_ndev_close, 204 .ndo_start_xmit = aq_ndev_start_xmit, 205 .ndo_set_rx_mode = aq_ndev_set_multicast_settings, 206 .ndo_change_mtu = aq_ndev_change_mtu, 207 .ndo_set_mac_address = aq_ndev_set_mac_address, 208 .ndo_set_features = aq_ndev_set_features, 209 .ndo_vlan_rx_add_vid = aq_ndo_vlan_rx_add_vid, 210 .ndo_vlan_rx_kill_vid = aq_ndo_vlan_rx_kill_vid, 211 }; 212