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_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_ptp.h"
14 : : #include "aq_filters.h"
15 : :
16 : : #include <linux/netdevice.h>
17 : : #include <linux/module.h>
18 : : #include <linux/ip.h>
19 : : #include <linux/udp.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 char aq_ndev_driver_name[] = AQ_CFG_DRV_NAME;
27 : :
28 : : static const struct net_device_ops aq_ndev_ops;
29 : :
30 : : static struct workqueue_struct *aq_ndev_wq;
31 : :
32 : 97 : void aq_ndev_schedule_work(struct work_struct *work)
33 : : {
34 : 97 : queue_work(aq_ndev_wq, work);
35 : 97 : }
36 : :
37 : 78 : struct net_device *aq_ndev_alloc(void)
38 : : {
39 : 78 : struct net_device *ndev = NULL;
40 : 78 : struct aq_nic_s *aq_nic = NULL;
41 : :
42 : 78 : ndev = alloc_etherdev_mq(sizeof(struct aq_nic_s), AQ_CFG_VECS_MAX);
43 [ + - ]: 78 : if (!ndev)
44 : : return NULL;
45 : :
46 : 78 : aq_nic = netdev_priv(ndev);
47 : 78 : aq_nic->ndev = ndev;
48 : 78 : ndev->netdev_ops = &aq_ndev_ops;
49 : 78 : ndev->ethtool_ops = &aq_ethtool_ops;
50 : :
51 : 78 : return ndev;
52 : : }
53 : :
54 : 33 : static int aq_ndev_open(struct net_device *ndev)
55 : : {
56 : 33 : struct aq_nic_s *aq_nic = netdev_priv(ndev);
57 : 33 : int err = 0;
58 : :
59 : 33 : err = aq_nic_init(aq_nic);
60 [ - + ]: 33 : if (err < 0)
61 : 0 : goto err_exit;
62 : :
63 : 33 : err = aq_reapply_rxnfc_all_rules(aq_nic);
64 [ - + ]: 33 : if (err < 0)
65 : 0 : goto err_exit;
66 : :
67 : 33 : err = aq_filters_vlans_update(aq_nic);
68 [ - + ]: 33 : if (err < 0)
69 : 0 : goto err_exit;
70 : :
71 : 33 : err = aq_nic_start(aq_nic);
72 [ + - ]: 33 : if (err < 0)
73 : 0 : goto err_exit;
74 : :
75 : 33 : err_exit:
76 [ - + ]: 33 : if (err < 0)
77 : 0 : aq_nic_deinit(aq_nic, true);
78 : :
79 : 33 : return err;
80 : : }
81 : :
82 : 0 : static int aq_ndev_close(struct net_device *ndev)
83 : : {
84 : 0 : struct aq_nic_s *aq_nic = netdev_priv(ndev);
85 : 0 : int err = 0;
86 : :
87 : 0 : err = aq_nic_stop(aq_nic);
88 [ # # ]: 0 : if (err < 0)
89 : 0 : goto err_exit;
90 : 0 : aq_nic_deinit(aq_nic, true);
91 : :
92 : 0 : err_exit:
93 : 0 : return err;
94 : : }
95 : :
96 : 156 : static int aq_ndev_start_xmit(struct sk_buff *skb, struct net_device *ndev)
97 : : {
98 : 156 : struct aq_nic_s *aq_nic = netdev_priv(ndev);
99 : :
100 [ - + ]: 156 : if (unlikely(aq_utils_obj_test(&aq_nic->flags, AQ_NIC_PTP_DPATH_UP))) {
101 : : /* Hardware adds the Timestamp for PTPv2 802.AS1
102 : : * and PTPv2 IPv4 UDP.
103 : : * We have to push even general 320 port messages to the ptp
104 : : * queue explicitly. This is a limitation of current firmware
105 : : * and hardware PTP design of the chip. Otherwise ptp stream
106 : : * will fail to sync
107 : : */
108 [ # # ]: 0 : if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) ||
109 [ # # # # : 0 : unlikely((ip_hdr(skb)->version == 4) &&
# # # # ]
110 : : (ip_hdr(skb)->protocol == IPPROTO_UDP) &&
111 : : ((udp_hdr(skb)->dest == htons(319)) ||
112 : 0 : (udp_hdr(skb)->dest == htons(320)))) ||
113 [ # # ]: 0 : unlikely(eth_hdr(skb)->h_proto == htons(ETH_P_1588)))
114 : 0 : return aq_ptp_xmit(aq_nic, skb);
115 : : }
116 : :
117 [ - + ]: 156 : skb_tx_timestamp(skb);
118 : 156 : return aq_nic_xmit(aq_nic, skb);
119 : : }
120 : :
121 : 0 : static int aq_ndev_change_mtu(struct net_device *ndev, int new_mtu)
122 : : {
123 : 0 : struct aq_nic_s *aq_nic = netdev_priv(ndev);
124 : 0 : int err;
125 : :
126 : 0 : err = aq_nic_set_mtu(aq_nic, new_mtu + ETH_HLEN);
127 : :
128 [ # # ]: 0 : if (err < 0)
129 : 0 : goto err_exit;
130 : 0 : ndev->mtu = new_mtu;
131 : :
132 : 0 : err_exit:
133 : 0 : return err;
134 : : }
135 : :
136 : 0 : static int aq_ndev_set_features(struct net_device *ndev,
137 : : netdev_features_t features)
138 : : {
139 : 0 : bool is_vlan_tx_insert = !!(features & NETIF_F_HW_VLAN_CTAG_TX);
140 : 0 : bool is_vlan_rx_strip = !!(features & NETIF_F_HW_VLAN_CTAG_RX);
141 : 0 : struct aq_nic_s *aq_nic = netdev_priv(ndev);
142 : 0 : bool need_ndev_restart = false;
143 : 0 : struct aq_nic_cfg_s *aq_cfg;
144 : 0 : bool is_lro = false;
145 : 0 : int err = 0;
146 : :
147 : 0 : aq_cfg = aq_nic_get_cfg(aq_nic);
148 : :
149 [ # # ]: 0 : if (!(features & NETIF_F_NTUPLE)) {
150 [ # # ]: 0 : if (aq_nic->ndev->features & NETIF_F_NTUPLE) {
151 : 0 : err = aq_clear_rxnfc_all_rules(aq_nic);
152 [ # # ]: 0 : if (unlikely(err))
153 : 0 : goto err_exit;
154 : : }
155 : : }
156 [ # # ]: 0 : if (!(features & NETIF_F_HW_VLAN_CTAG_FILTER)) {
157 [ # # ]: 0 : if (aq_nic->ndev->features & NETIF_F_HW_VLAN_CTAG_FILTER) {
158 : 0 : err = aq_filters_vlan_offload_off(aq_nic);
159 [ # # ]: 0 : if (unlikely(err))
160 : 0 : goto err_exit;
161 : : }
162 : : }
163 : :
164 : 0 : aq_cfg->features = features;
165 : :
166 [ # # ]: 0 : if (aq_cfg->aq_hw_caps->hw_features & NETIF_F_LRO) {
167 : 0 : is_lro = features & NETIF_F_LRO;
168 : :
169 [ # # ]: 0 : if (aq_cfg->is_lro != is_lro) {
170 : 0 : aq_cfg->is_lro = is_lro;
171 : 0 : need_ndev_restart = true;
172 : : }
173 : : }
174 : :
175 [ # # ]: 0 : if ((aq_nic->ndev->features ^ features) & NETIF_F_RXCSUM) {
176 : 0 : err = aq_nic->aq_hw_ops->hw_set_offload(aq_nic->aq_hw,
177 : : aq_cfg);
178 : :
179 [ # # ]: 0 : if (unlikely(err))
180 : 0 : goto err_exit;
181 : : }
182 : :
183 [ # # ]: 0 : if (aq_cfg->is_vlan_rx_strip != is_vlan_rx_strip) {
184 : 0 : aq_cfg->is_vlan_rx_strip = is_vlan_rx_strip;
185 : 0 : need_ndev_restart = true;
186 : : }
187 [ # # ]: 0 : if (aq_cfg->is_vlan_tx_insert != is_vlan_tx_insert) {
188 : 0 : aq_cfg->is_vlan_tx_insert = is_vlan_tx_insert;
189 : 0 : need_ndev_restart = true;
190 : : }
191 : :
192 [ # # # # ]: 0 : if (need_ndev_restart && netif_running(ndev)) {
193 : 0 : aq_ndev_close(ndev);
194 : 0 : aq_ndev_open(ndev);
195 : : }
196 : :
197 : 0 : err_exit:
198 : 0 : return err;
199 : : }
200 : :
201 : 0 : static int aq_ndev_set_mac_address(struct net_device *ndev, void *addr)
202 : : {
203 : 0 : struct aq_nic_s *aq_nic = netdev_priv(ndev);
204 : 0 : int err = 0;
205 : :
206 : 0 : err = eth_mac_addr(ndev, addr);
207 [ # # ]: 0 : if (err < 0)
208 : 0 : goto err_exit;
209 : 0 : err = aq_nic_set_mac(aq_nic, ndev);
210 [ # # ]: 0 : if (err < 0)
211 : 0 : goto err_exit;
212 : :
213 : 0 : err_exit:
214 : 0 : return err;
215 : : }
216 : :
217 : 94 : static void aq_ndev_set_multicast_settings(struct net_device *ndev)
218 : : {
219 : 94 : struct aq_nic_s *aq_nic = netdev_priv(ndev);
220 : :
221 : 94 : (void)aq_nic_set_multicast_list(aq_nic, ndev);
222 : 94 : }
223 : :
224 : : static int aq_ndev_config_hwtstamp(struct aq_nic_s *aq_nic,
225 : : struct hwtstamp_config *config)
226 : : {
227 : : if (config->flags)
228 : : return -EINVAL;
229 : :
230 : : switch (config->tx_type) {
231 : : case HWTSTAMP_TX_OFF:
232 : : case HWTSTAMP_TX_ON:
233 : : break;
234 : : default:
235 : : return -ERANGE;
236 : : }
237 : :
238 : : switch (config->rx_filter) {
239 : : case HWTSTAMP_FILTER_PTP_V2_L4_EVENT:
240 : : case HWTSTAMP_FILTER_PTP_V2_L4_SYNC:
241 : : case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
242 : : case HWTSTAMP_FILTER_PTP_V2_L2_EVENT:
243 : : case HWTSTAMP_FILTER_PTP_V2_L2_SYNC:
244 : : case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ:
245 : : case HWTSTAMP_FILTER_PTP_V2_SYNC:
246 : : case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
247 : : config->rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT;
248 : : break;
249 : : case HWTSTAMP_FILTER_PTP_V2_EVENT:
250 : : case HWTSTAMP_FILTER_NONE:
251 : : break;
252 : : default:
253 : : return -ERANGE;
254 : : }
255 : :
256 : : return aq_ptp_hwtstamp_config_set(aq_nic->aq_ptp, config);
257 : : }
258 : :
259 : : static int aq_ndev_hwtstamp_set(struct aq_nic_s *aq_nic, struct ifreq *ifr)
260 : : {
261 : : struct hwtstamp_config config;
262 : : int ret_val;
263 : :
264 : : if (!aq_nic->aq_ptp)
265 : : return -EOPNOTSUPP;
266 : :
267 : : if (copy_from_user(&config, ifr->ifr_data, sizeof(config)))
268 : : return -EFAULT;
269 : :
270 : : ret_val = aq_ndev_config_hwtstamp(aq_nic, &config);
271 : : if (ret_val)
272 : : return ret_val;
273 : :
274 : : return copy_to_user(ifr->ifr_data, &config, sizeof(config)) ?
275 : : -EFAULT : 0;
276 : : }
277 : :
278 : : static int aq_ndev_hwtstamp_get(struct aq_nic_s *aq_nic, struct ifreq *ifr)
279 : : {
280 : : struct hwtstamp_config config;
281 : :
282 : : if (!aq_nic->aq_ptp)
283 : : return -EOPNOTSUPP;
284 : :
285 : : aq_ptp_hwtstamp_config_get(aq_nic->aq_ptp, &config);
286 : : return copy_to_user(ifr->ifr_data, &config, sizeof(config)) ?
287 : : -EFAULT : 0;
288 : : }
289 : :
290 : 0 : static int aq_ndev_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
291 : : {
292 [ # # # ]: 0 : struct aq_nic_s *aq_nic = netdev_priv(netdev);
293 : :
294 [ # # # ]: 0 : switch (cmd) {
295 : 0 : case SIOCSHWTSTAMP:
296 : 0 : return aq_ndev_hwtstamp_set(aq_nic, ifr);
297 : :
298 : 0 : case SIOCGHWTSTAMP:
299 : 0 : return aq_ndev_hwtstamp_get(aq_nic, ifr);
300 : : }
301 : :
302 : : return -EOPNOTSUPP;
303 : : }
304 : :
305 : 0 : static int aq_ndo_vlan_rx_add_vid(struct net_device *ndev, __be16 proto,
306 : : u16 vid)
307 : : {
308 [ # # ]: 0 : struct aq_nic_s *aq_nic = netdev_priv(ndev);
309 : :
310 [ # # ]: 0 : if (!aq_nic->aq_hw_ops->hw_filter_vlan_set)
311 : : return -EOPNOTSUPP;
312 : :
313 : 0 : set_bit(vid, aq_nic->active_vlans);
314 : :
315 : 0 : return aq_filters_vlans_update(aq_nic);
316 : : }
317 : :
318 : 0 : static int aq_ndo_vlan_rx_kill_vid(struct net_device *ndev, __be16 proto,
319 : : u16 vid)
320 : : {
321 [ # # ]: 0 : struct aq_nic_s *aq_nic = netdev_priv(ndev);
322 : :
323 [ # # ]: 0 : if (!aq_nic->aq_hw_ops->hw_filter_vlan_set)
324 : : return -EOPNOTSUPP;
325 : :
326 : 0 : clear_bit(vid, aq_nic->active_vlans);
327 : :
328 [ # # ]: 0 : if (-ENOENT == aq_del_fvlan_by_vlan(aq_nic, vid))
329 : 0 : return aq_filters_vlans_update(aq_nic);
330 : :
331 : : return 0;
332 : : }
333 : :
334 : : static const struct net_device_ops aq_ndev_ops = {
335 : : .ndo_open = aq_ndev_open,
336 : : .ndo_stop = aq_ndev_close,
337 : : .ndo_start_xmit = aq_ndev_start_xmit,
338 : : .ndo_set_rx_mode = aq_ndev_set_multicast_settings,
339 : : .ndo_change_mtu = aq_ndev_change_mtu,
340 : : .ndo_set_mac_address = aq_ndev_set_mac_address,
341 : : .ndo_set_features = aq_ndev_set_features,
342 : : .ndo_do_ioctl = aq_ndev_ioctl,
343 : : .ndo_vlan_rx_add_vid = aq_ndo_vlan_rx_add_vid,
344 : : .ndo_vlan_rx_kill_vid = aq_ndo_vlan_rx_kill_vid,
345 : : };
346 : :
347 : 78 : static int __init aq_ndev_init_module(void)
348 : : {
349 : 78 : int ret;
350 : :
351 : 78 : aq_ndev_wq = create_singlethread_workqueue(aq_ndev_driver_name);
352 [ - + ]: 78 : if (!aq_ndev_wq) {
353 : 0 : pr_err("Failed to create workqueue\n");
354 : 0 : return -ENOMEM;
355 : : }
356 : :
357 : 78 : ret = aq_pci_func_register_driver();
358 [ - + ]: 78 : if (ret) {
359 : 0 : destroy_workqueue(aq_ndev_wq);
360 : 0 : return ret;
361 : : }
362 : :
363 : : return 0;
364 : : }
365 : :
366 : 0 : static void __exit aq_ndev_exit_module(void)
367 : : {
368 : 0 : aq_pci_func_unregister_driver();
369 : :
370 [ # # ]: 0 : if (aq_ndev_wq) {
371 : 0 : destroy_workqueue(aq_ndev_wq);
372 : 0 : aq_ndev_wq = NULL;
373 : : }
374 : 0 : }
375 : :
376 : : module_init(aq_ndev_init_module);
377 : : module_exit(aq_ndev_exit_module);
|