powerpc/tm: Fix restoring FP/VMX facility incorrectly on interrupts
[sfrench/cifs-2.6.git] / drivers / net / ethernet / aquantia / atlantic / aq_main.c
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_nic_start(aq_nic);
65         if (err < 0)
66                 goto err_exit;
67
68 err_exit:
69         if (err < 0)
70                 aq_nic_deinit(aq_nic);
71         return err;
72 }
73
74 static int aq_ndev_close(struct net_device *ndev)
75 {
76         int err = 0;
77         struct aq_nic_s *aq_nic = netdev_priv(ndev);
78
79         err = aq_nic_stop(aq_nic);
80         if (err < 0)
81                 goto err_exit;
82         aq_nic_deinit(aq_nic);
83
84 err_exit:
85         return err;
86 }
87
88 static int aq_ndev_start_xmit(struct sk_buff *skb, struct net_device *ndev)
89 {
90         struct aq_nic_s *aq_nic = netdev_priv(ndev);
91
92         return aq_nic_xmit(aq_nic, skb);
93 }
94
95 static int aq_ndev_change_mtu(struct net_device *ndev, int new_mtu)
96 {
97         struct aq_nic_s *aq_nic = netdev_priv(ndev);
98         int err = aq_nic_set_mtu(aq_nic, new_mtu + ETH_HLEN);
99
100         if (err < 0)
101                 goto err_exit;
102         ndev->mtu = new_mtu;
103
104 err_exit:
105         return err;
106 }
107
108 static int aq_ndev_set_features(struct net_device *ndev,
109                                 netdev_features_t features)
110 {
111         bool is_vlan_rx_strip = !!(features & NETIF_F_HW_VLAN_CTAG_RX);
112         bool is_vlan_tx_insert = !!(features & NETIF_F_HW_VLAN_CTAG_TX);
113         struct aq_nic_s *aq_nic = netdev_priv(ndev);
114         bool need_ndev_restart = false;
115         struct aq_nic_cfg_s *aq_cfg;
116         bool is_lro = false;
117         int err = 0;
118
119         aq_cfg = aq_nic_get_cfg(aq_nic);
120
121         if (!(features & NETIF_F_NTUPLE)) {
122                 if (aq_nic->ndev->features & NETIF_F_NTUPLE) {
123                         err = aq_clear_rxnfc_all_rules(aq_nic);
124                         if (unlikely(err))
125                                 goto err_exit;
126                 }
127         }
128         if (!(features & NETIF_F_HW_VLAN_CTAG_FILTER)) {
129                 if (aq_nic->ndev->features & NETIF_F_HW_VLAN_CTAG_FILTER) {
130                         err = aq_filters_vlan_offload_off(aq_nic);
131                         if (unlikely(err))
132                                 goto err_exit;
133                 }
134         }
135
136         aq_cfg->features = features;
137
138         if (aq_cfg->aq_hw_caps->hw_features & NETIF_F_LRO) {
139                 is_lro = features & NETIF_F_LRO;
140
141                 if (aq_cfg->is_lro != is_lro) {
142                         aq_cfg->is_lro = is_lro;
143                         need_ndev_restart = true;
144                 }
145         }
146
147         if ((aq_nic->ndev->features ^ features) & NETIF_F_RXCSUM) {
148                 err = aq_nic->aq_hw_ops->hw_set_offload(aq_nic->aq_hw,
149                                                         aq_cfg);
150
151                 if (unlikely(err))
152                         goto err_exit;
153         }
154
155         if (aq_cfg->is_vlan_rx_strip != is_vlan_rx_strip) {
156                 aq_cfg->is_vlan_rx_strip = is_vlan_rx_strip;
157                 need_ndev_restart = true;
158         }
159         if (aq_cfg->is_vlan_tx_insert != is_vlan_tx_insert) {
160                 aq_cfg->is_vlan_tx_insert = is_vlan_tx_insert;
161                 need_ndev_restart = true;
162         }
163
164         if (need_ndev_restart && netif_running(ndev)) {
165                 aq_ndev_close(ndev);
166                 aq_ndev_open(ndev);
167         }
168
169 err_exit:
170         return err;
171 }
172
173 static int aq_ndev_set_mac_address(struct net_device *ndev, void *addr)
174 {
175         struct aq_nic_s *aq_nic = netdev_priv(ndev);
176         int err = 0;
177
178         err = eth_mac_addr(ndev, addr);
179         if (err < 0)
180                 goto err_exit;
181         err = aq_nic_set_mac(aq_nic, ndev);
182         if (err < 0)
183                 goto err_exit;
184
185 err_exit:
186         return err;
187 }
188
189 static void aq_ndev_set_multicast_settings(struct net_device *ndev)
190 {
191         struct aq_nic_s *aq_nic = netdev_priv(ndev);
192
193         aq_nic_set_packet_filter(aq_nic, ndev->flags);
194
195         aq_nic_set_multicast_list(aq_nic, ndev);
196 }
197
198 static int aq_ndo_vlan_rx_add_vid(struct net_device *ndev, __be16 proto,
199                                   u16 vid)
200 {
201         struct aq_nic_s *aq_nic = netdev_priv(ndev);
202
203         if (!aq_nic->aq_hw_ops->hw_filter_vlan_set)
204                 return -EOPNOTSUPP;
205
206         set_bit(vid, aq_nic->active_vlans);
207
208         return aq_filters_vlans_update(aq_nic);
209 }
210
211 static int aq_ndo_vlan_rx_kill_vid(struct net_device *ndev, __be16 proto,
212                                    u16 vid)
213 {
214         struct aq_nic_s *aq_nic = netdev_priv(ndev);
215
216         if (!aq_nic->aq_hw_ops->hw_filter_vlan_set)
217                 return -EOPNOTSUPP;
218
219         clear_bit(vid, aq_nic->active_vlans);
220
221         if (-ENOENT == aq_del_fvlan_by_vlan(aq_nic, vid))
222                 return aq_filters_vlans_update(aq_nic);
223
224         return 0;
225 }
226
227 static const struct net_device_ops aq_ndev_ops = {
228         .ndo_open = aq_ndev_open,
229         .ndo_stop = aq_ndev_close,
230         .ndo_start_xmit = aq_ndev_start_xmit,
231         .ndo_set_rx_mode = aq_ndev_set_multicast_settings,
232         .ndo_change_mtu = aq_ndev_change_mtu,
233         .ndo_set_mac_address = aq_ndev_set_mac_address,
234         .ndo_set_features = aq_ndev_set_features,
235         .ndo_vlan_rx_add_vid = aq_ndo_vlan_rx_add_vid,
236         .ndo_vlan_rx_kill_vid = aq_ndo_vlan_rx_kill_vid,
237 };
238
239 static int __init aq_ndev_init_module(void)
240 {
241         int ret;
242
243         aq_ndev_wq = create_singlethread_workqueue(aq_ndev_driver_name);
244         if (!aq_ndev_wq) {
245                 pr_err("Failed to create workqueue\n");
246                 return -ENOMEM;
247         }
248
249         ret = aq_pci_func_register_driver();
250         if (ret) {
251                 destroy_workqueue(aq_ndev_wq);
252                 return ret;
253         }
254
255         return 0;
256 }
257
258 static void __exit aq_ndev_exit_module(void)
259 {
260         aq_pci_func_unregister_driver();
261
262         if (aq_ndev_wq) {
263                 destroy_workqueue(aq_ndev_wq);
264                 aq_ndev_wq = NULL;
265         }
266 }
267
268 module_init(aq_ndev_init_module);
269 module_exit(aq_ndev_exit_module);