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_nic.c: Definition of common code for NIC. */
8 : :
9 : : #include "aq_nic.h"
10 : : #include "aq_ring.h"
11 : : #include "aq_vec.h"
12 : : #include "aq_hw.h"
13 : : #include "aq_pci_func.h"
14 : : #include "aq_main.h"
15 : : #include "aq_phy.h"
16 : : #include "aq_ptp.h"
17 : : #include "aq_filters.h"
18 : :
19 : : #include <linux/moduleparam.h>
20 : : #include <linux/netdevice.h>
21 : : #include <linux/etherdevice.h>
22 : : #include <linux/timer.h>
23 : : #include <linux/cpu.h>
24 : : #include <linux/ip.h>
25 : : #include <linux/tcp.h>
26 : : #include <net/ip.h>
27 : :
28 : : static unsigned int aq_itr = AQ_CFG_INTERRUPT_MODERATION_AUTO;
29 : : module_param_named(aq_itr, aq_itr, uint, 0644);
30 : : MODULE_PARM_DESC(aq_itr, "Interrupt throttling mode");
31 : :
32 : : static unsigned int aq_itr_tx;
33 : : module_param_named(aq_itr_tx, aq_itr_tx, uint, 0644);
34 : : MODULE_PARM_DESC(aq_itr_tx, "TX interrupt throttle rate");
35 : :
36 : : static unsigned int aq_itr_rx;
37 : : module_param_named(aq_itr_rx, aq_itr_rx, uint, 0644);
38 : : MODULE_PARM_DESC(aq_itr_rx, "RX interrupt throttle rate");
39 : :
40 : : static void aq_nic_update_ndev_stats(struct aq_nic_s *self);
41 : :
42 : 78 : static void aq_nic_rss_init(struct aq_nic_s *self, unsigned int num_rss_queues)
43 : : {
44 : 78 : static u8 rss_key[AQ_CFG_RSS_HASHKEY_SIZE] = {
45 : : 0x1e, 0xad, 0x71, 0x87, 0x65, 0xfc, 0x26, 0x7d,
46 : : 0x0d, 0x45, 0x67, 0x74, 0xcd, 0x06, 0x1a, 0x18,
47 : : 0xb6, 0xc1, 0xf0, 0xc7, 0xbb, 0x18, 0xbe, 0xf8,
48 : : 0x19, 0x13, 0x4b, 0xa9, 0xd0, 0x3e, 0xfe, 0x70,
49 : : 0x25, 0x03, 0xab, 0x50, 0x6a, 0x8b, 0x82, 0x0c
50 : : };
51 : 78 : struct aq_nic_cfg_s *cfg = &self->aq_nic_cfg;
52 : 78 : struct aq_rss_parameters *rss_params;
53 : 78 : int i = 0;
54 : :
55 : 78 : rss_params = &cfg->aq_rss;
56 : :
57 : 78 : rss_params->hash_secret_key_size = sizeof(rss_key);
58 : 78 : memcpy(rss_params->hash_secret_key, rss_key, sizeof(rss_key));
59 : 78 : rss_params->indirection_table_size = AQ_CFG_RSS_INDIRECTION_TABLE_MAX;
60 : :
61 [ + + ]: 5070 : for (i = rss_params->indirection_table_size; i--;)
62 : 4992 : rss_params->indirection_table[i] = i & (num_rss_queues - 1);
63 : 78 : }
64 : :
65 : : /* Checks hw_caps and 'corrects' aq_nic_cfg in runtime */
66 : 78 : void aq_nic_cfg_start(struct aq_nic_s *self)
67 : : {
68 : 78 : struct aq_nic_cfg_s *cfg = &self->aq_nic_cfg;
69 : :
70 : 78 : cfg->tcs = AQ_CFG_TCS_DEF;
71 : :
72 : 78 : cfg->is_polling = AQ_CFG_IS_POLLING_DEF;
73 : :
74 : 78 : cfg->itr = aq_itr;
75 : 78 : cfg->tx_itr = aq_itr_tx;
76 : 78 : cfg->rx_itr = aq_itr_rx;
77 : :
78 : 78 : cfg->rxpageorder = AQ_CFG_RX_PAGEORDER;
79 : 78 : cfg->is_rss = AQ_CFG_IS_RSS_DEF;
80 : 78 : cfg->num_rss_queues = AQ_CFG_NUM_RSS_QUEUES_DEF;
81 : 78 : cfg->aq_rss.base_cpu_number = AQ_CFG_RSS_BASE_CPU_NUM_DEF;
82 : 78 : cfg->fc.req = AQ_CFG_FC_MODE;
83 : 78 : cfg->wol = AQ_CFG_WOL_MODES;
84 : :
85 : 78 : cfg->mtu = AQ_CFG_MTU_DEF;
86 : 78 : cfg->link_speed_msk = AQ_CFG_SPEED_MSK;
87 : 78 : cfg->is_autoneg = AQ_CFG_IS_AUTONEG_DEF;
88 : :
89 : 78 : cfg->is_lro = AQ_CFG_IS_LRO_DEF;
90 : :
91 : : /*descriptors */
92 : 78 : cfg->rxds = min(cfg->aq_hw_caps->rxds_max, AQ_CFG_RXDS_DEF);
93 : 78 : cfg->txds = min(cfg->aq_hw_caps->txds_max, AQ_CFG_TXDS_DEF);
94 : :
95 : : /*rss rings */
96 : 78 : cfg->vecs = min(cfg->aq_hw_caps->vecs, AQ_CFG_VECS_DEF);
97 : 78 : cfg->vecs = min(cfg->vecs, num_online_cpus());
98 [ - + ]: 78 : if (self->irqvecs > AQ_HW_SERVICE_IRQS)
99 : 0 : cfg->vecs = min(cfg->vecs, self->irqvecs - AQ_HW_SERVICE_IRQS);
100 : : /* cfg->vecs should be power of 2 for RSS */
101 [ - + ]: 78 : if (cfg->vecs >= 8U)
102 : 0 : cfg->vecs = 8U;
103 [ - + ]: 78 : else if (cfg->vecs >= 4U)
104 : 0 : cfg->vecs = 4U;
105 [ - + ]: 78 : else if (cfg->vecs >= 2U)
106 : 0 : cfg->vecs = 2U;
107 : : else
108 : 78 : cfg->vecs = 1U;
109 : :
110 : 78 : cfg->num_rss_queues = min(cfg->vecs, AQ_CFG_NUM_RSS_QUEUES_DEF);
111 : :
112 : 78 : aq_nic_rss_init(self, cfg->num_rss_queues);
113 : :
114 : 78 : cfg->irq_type = aq_pci_func_get_irq_type(self);
115 : :
116 [ - + ]: 78 : if ((cfg->irq_type == AQ_HW_IRQ_LEGACY) ||
117 [ # # ]: 0 : (cfg->aq_hw_caps->vecs == 1U) ||
118 [ # # ]: 0 : (cfg->vecs == 1U)) {
119 : 78 : cfg->is_rss = 0U;
120 : 78 : cfg->vecs = 1U;
121 : : }
122 : :
123 : : /* Check if we have enough vectors allocated for
124 : : * link status IRQ. If no - we'll know link state from
125 : : * slower service task.
126 : : */
127 [ - + ]: 78 : if (AQ_HW_SERVICE_IRQS > 0 && cfg->vecs + 1 <= self->irqvecs)
128 : 0 : cfg->link_irq_vec = cfg->vecs;
129 : : else
130 : 78 : cfg->link_irq_vec = 0;
131 : :
132 : 78 : cfg->link_speed_msk &= cfg->aq_hw_caps->link_speed_msk;
133 : 78 : cfg->features = cfg->aq_hw_caps->hw_features;
134 : 78 : cfg->is_vlan_rx_strip = !!(cfg->features & NETIF_F_HW_VLAN_CTAG_RX);
135 : 78 : cfg->is_vlan_tx_insert = !!(cfg->features & NETIF_F_HW_VLAN_CTAG_TX);
136 : 78 : cfg->is_vlan_force_promisc = true;
137 : 78 : }
138 : :
139 : 97 : static int aq_nic_update_link_status(struct aq_nic_s *self)
140 : : {
141 : 97 : int err = self->aq_fw_ops->update_link_status(self->aq_hw);
142 : 97 : u32 fc = 0;
143 : :
144 [ + + ]: 97 : if (err)
145 : : return err;
146 : :
147 [ + - ]: 84 : if (self->aq_fw_ops->get_flow_control)
148 : 84 : self->aq_fw_ops->get_flow_control(self->aq_hw, &fc);
149 : 84 : self->aq_nic_cfg.fc.cur = fc;
150 : :
151 [ + + ]: 84 : if (self->link_status.mbps != self->aq_hw->aq_link_status.mbps) {
152 : 81 : netdev_info(self->ndev, "%s: link change old %d new %d\n",
153 : : AQ_CFG_DRV_NAME, self->link_status.mbps,
154 : : self->aq_hw->aq_link_status.mbps);
155 : 81 : aq_nic_update_interrupt_moderation_settings(self);
156 : :
157 [ - + ]: 81 : if (self->aq_ptp) {
158 : 0 : aq_ptp_clock_init(self);
159 : 0 : aq_ptp_tm_offset_set(self,
160 : 0 : self->aq_hw->aq_link_status.mbps);
161 : 0 : aq_ptp_link_change(self);
162 : : }
163 : :
164 : : /* Driver has to update flow control settings on RX block
165 : : * on any link event.
166 : : * We should query FW whether it negotiated FC.
167 : : */
168 [ + - ]: 81 : if (self->aq_hw_ops->hw_set_fc)
169 : 81 : self->aq_hw_ops->hw_set_fc(self->aq_hw, fc, 0);
170 : : }
171 : :
172 : 84 : self->link_status = self->aq_hw->aq_link_status;
173 [ + + + + ]: 84 : if (!netif_carrier_ok(self->ndev) && self->link_status.mbps) {
174 : 28 : aq_utils_obj_set(&self->flags,
175 : : AQ_NIC_FLAG_STARTED);
176 : 28 : aq_utils_obj_clear(&self->flags,
177 : : AQ_NIC_LINK_DOWN);
178 : 28 : netif_carrier_on(self->ndev);
179 : 28 : netif_tx_wake_all_queues(self->ndev);
180 : : }
181 [ + + - + ]: 84 : if (netif_carrier_ok(self->ndev) && !self->link_status.mbps) {
182 : 0 : netif_carrier_off(self->ndev);
183 : 0 : netif_tx_disable(self->ndev);
184 : 0 : aq_utils_obj_set(&self->flags, AQ_NIC_LINK_DOWN);
185 : : }
186 : :
187 : : return 0;
188 : : }
189 : :
190 : 0 : static irqreturn_t aq_linkstate_threaded_isr(int irq, void *private)
191 : : {
192 : 0 : struct aq_nic_s *self = private;
193 : :
194 [ # # ]: 0 : if (!self)
195 : : return IRQ_NONE;
196 : :
197 : 0 : aq_nic_update_link_status(self);
198 : :
199 : 0 : self->aq_hw_ops->hw_irq_enable(self->aq_hw,
200 : 0 : BIT(self->aq_nic_cfg.link_irq_vec));
201 : :
202 : 0 : return IRQ_HANDLED;
203 : : }
204 : :
205 : 97 : static void aq_nic_service_task(struct work_struct *work)
206 : : {
207 : 97 : struct aq_nic_s *self = container_of(work, struct aq_nic_s,
208 : : service_task);
209 : 97 : int err;
210 : :
211 : 97 : aq_ptp_service_task(self);
212 : :
213 [ + - ]: 97 : if (aq_utils_obj_test(&self->flags, AQ_NIC_FLAGS_IS_NOT_READY))
214 : : return;
215 : :
216 : 97 : err = aq_nic_update_link_status(self);
217 [ + + ]: 97 : if (err)
218 : : return;
219 : :
220 : 84 : mutex_lock(&self->fwreq_mutex);
221 [ + - ]: 84 : if (self->aq_fw_ops->update_stats)
222 : 84 : self->aq_fw_ops->update_stats(self->aq_hw);
223 : 84 : mutex_unlock(&self->fwreq_mutex);
224 : :
225 : 84 : aq_nic_update_ndev_stats(self);
226 : : }
227 : :
228 : 97 : static void aq_nic_service_timer_cb(struct timer_list *t)
229 : : {
230 : 97 : struct aq_nic_s *self = from_timer(self, t, service_timer);
231 : :
232 : 97 : mod_timer(&self->service_timer,
233 : : jiffies + AQ_CFG_SERVICE_TIMER_INTERVAL);
234 : :
235 : 97 : aq_ndev_schedule_work(&self->service_task);
236 : 97 : }
237 : :
238 : 0 : static void aq_nic_polling_timer_cb(struct timer_list *t)
239 : : {
240 : 0 : struct aq_nic_s *self = from_timer(self, t, polling_timer);
241 : 0 : struct aq_vec_s *aq_vec = NULL;
242 : 0 : unsigned int i = 0U;
243 : :
244 : 0 : for (i = 0U, aq_vec = self->aq_vec[0];
245 [ # # ]: 0 : self->aq_vecs > i; ++i, aq_vec = self->aq_vec[i])
246 : 0 : aq_vec_isr(i, (void *)aq_vec);
247 : :
248 : 0 : mod_timer(&self->polling_timer, jiffies +
249 : : AQ_CFG_POLLING_TIMER_INTERVAL);
250 : 0 : }
251 : :
252 : 78 : int aq_nic_ndev_register(struct aq_nic_s *self)
253 : : {
254 : 78 : int err = 0;
255 : :
256 [ - + ]: 78 : if (!self->ndev) {
257 : 0 : err = -EINVAL;
258 : 0 : goto err_exit;
259 : : }
260 : :
261 : 78 : err = hw_atl_utils_initfw(self->aq_hw, &self->aq_fw_ops);
262 [ + + ]: 78 : if (err)
263 : 35 : goto err_exit;
264 : :
265 : 43 : mutex_lock(&self->fwreq_mutex);
266 : 43 : err = self->aq_fw_ops->get_mac_permanent(self->aq_hw,
267 : 43 : self->ndev->dev_addr);
268 : 43 : mutex_unlock(&self->fwreq_mutex);
269 [ + + ]: 43 : if (err)
270 : 10 : goto err_exit;
271 : :
272 : : #if defined(AQ_CFG_MAC_ADDR_PERMANENT)
273 : : {
274 : : static u8 mac_addr_permanent[] = AQ_CFG_MAC_ADDR_PERMANENT;
275 : :
276 : : ether_addr_copy(self->ndev->dev_addr, mac_addr_permanent);
277 : : }
278 : : #endif
279 : :
280 : 33 : for (self->aq_vecs = 0; self->aq_vecs < aq_nic_get_cfg(self)->vecs;
281 : 33 : self->aq_vecs++) {
282 : 66 : self->aq_vec[self->aq_vecs] =
283 : 33 : aq_vec_alloc(self, self->aq_vecs, aq_nic_get_cfg(self));
284 [ - + ]: 33 : if (!self->aq_vec[self->aq_vecs]) {
285 : 0 : err = -ENOMEM;
286 : 0 : goto err_exit;
287 : : }
288 : : }
289 : :
290 : 33 : netif_carrier_off(self->ndev);
291 : :
292 : 33 : netif_tx_disable(self->ndev);
293 : :
294 : 33 : err = register_netdev(self->ndev);
295 [ + - ]: 33 : if (err)
296 : 0 : goto err_exit;
297 : :
298 : 33 : err_exit:
299 : 78 : return err;
300 : : }
301 : :
302 : 78 : void aq_nic_ndev_init(struct aq_nic_s *self)
303 : : {
304 : 78 : const struct aq_hw_caps_s *aq_hw_caps = self->aq_nic_cfg.aq_hw_caps;
305 : 78 : struct aq_nic_cfg_s *aq_nic_cfg = &self->aq_nic_cfg;
306 : :
307 : 78 : self->ndev->hw_features |= aq_hw_caps->hw_features;
308 : 78 : self->ndev->features = aq_hw_caps->hw_features;
309 : 78 : self->ndev->vlan_features |= NETIF_F_HW_CSUM | NETIF_F_RXCSUM |
310 : : NETIF_F_RXHASH | NETIF_F_SG |
311 : : NETIF_F_LRO | NETIF_F_TSO;
312 : 78 : self->ndev->gso_partial_features = NETIF_F_GSO_UDP_L4;
313 : 78 : self->ndev->priv_flags = aq_hw_caps->hw_priv_flags;
314 : 78 : self->ndev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
315 : :
316 : 78 : self->msg_enable = NETIF_MSG_DRV | NETIF_MSG_LINK;
317 : 78 : self->ndev->mtu = aq_nic_cfg->mtu - ETH_HLEN;
318 : 78 : self->ndev->max_mtu = aq_hw_caps->mtu - ETH_FCS_LEN - ETH_HLEN;
319 : :
320 : 78 : }
321 : :
322 : 33 : void aq_nic_set_tx_ring(struct aq_nic_s *self, unsigned int idx,
323 : : struct aq_ring_s *ring)
324 : : {
325 : 33 : self->aq_ring_tx[idx] = ring;
326 : 33 : }
327 : :
328 : 8701 : struct net_device *aq_nic_get_ndev(struct aq_nic_s *self)
329 : : {
330 : 8701 : return self->ndev;
331 : : }
332 : :
333 : 33 : int aq_nic_init(struct aq_nic_s *self)
334 : : {
335 : 33 : struct aq_vec_s *aq_vec = NULL;
336 : 33 : unsigned int i = 0U;
337 : 33 : int err = 0;
338 : :
339 : 33 : self->power_state = AQ_HW_POWER_STATE_D0;
340 : 33 : mutex_lock(&self->fwreq_mutex);
341 : 33 : err = self->aq_hw_ops->hw_reset(self->aq_hw);
342 : 33 : mutex_unlock(&self->fwreq_mutex);
343 [ - + ]: 33 : if (err < 0)
344 : 0 : goto err_exit;
345 : :
346 : 33 : err = self->aq_hw_ops->hw_init(self->aq_hw,
347 : 33 : aq_nic_get_ndev(self)->dev_addr);
348 [ - + ]: 33 : if (err < 0)
349 : 0 : goto err_exit;
350 : :
351 [ + - ]: 33 : if (self->aq_nic_cfg.aq_hw_caps->media_type == AQ_HW_MEDIA_TYPE_TP) {
352 : 33 : self->aq_hw->phy_id = HW_ATL_PHY_ID_MAX;
353 : 33 : err = aq_phy_init(self->aq_hw);
354 : : }
355 : :
356 : 33 : for (i = 0U, aq_vec = self->aq_vec[0];
357 [ + + ]: 66 : self->aq_vecs > i; ++i, aq_vec = self->aq_vec[i])
358 : 33 : aq_vec_init(aq_vec, self->aq_hw_ops, self->aq_hw);
359 : :
360 : 33 : err = aq_ptp_init(self, self->irqvecs - 1);
361 [ - + ]: 33 : if (err < 0)
362 : 0 : goto err_exit;
363 : :
364 : 33 : err = aq_ptp_ring_alloc(self);
365 [ - + ]: 33 : if (err < 0)
366 : 0 : goto err_exit;
367 : :
368 : 33 : err = aq_ptp_ring_init(self);
369 [ - + ]: 33 : if (err < 0)
370 : 0 : goto err_exit;
371 : :
372 : 33 : netif_carrier_off(self->ndev);
373 : :
374 : 33 : err_exit:
375 : 33 : return err;
376 : : }
377 : :
378 : 33 : int aq_nic_start(struct aq_nic_s *self)
379 : : {
380 : 33 : struct aq_vec_s *aq_vec = NULL;
381 : 33 : unsigned int i = 0U;
382 : 33 : int err = 0;
383 : :
384 : 33 : err = self->aq_hw_ops->hw_multicast_list_set(self->aq_hw,
385 : 33 : self->mc_list.ar,
386 : : self->mc_list.count);
387 [ - + ]: 33 : if (err < 0)
388 : 0 : goto err_exit;
389 : :
390 : 33 : err = self->aq_hw_ops->hw_packet_filter_set(self->aq_hw,
391 : : self->packet_filter);
392 [ - + ]: 33 : if (err < 0)
393 : 0 : goto err_exit;
394 : :
395 : 33 : for (i = 0U, aq_vec = self->aq_vec[0];
396 [ + + ]: 66 : self->aq_vecs > i; ++i, aq_vec = self->aq_vec[i]) {
397 : 33 : err = aq_vec_start(aq_vec);
398 [ - + ]: 33 : if (err < 0)
399 : 0 : goto err_exit;
400 : : }
401 : :
402 : 33 : err = aq_ptp_ring_start(self);
403 [ - + ]: 33 : if (err < 0)
404 : 0 : goto err_exit;
405 : :
406 : 33 : aq_nic_set_loopback(self);
407 : :
408 : 33 : err = self->aq_hw_ops->hw_start(self->aq_hw);
409 [ - + ]: 33 : if (err < 0)
410 : 0 : goto err_exit;
411 : :
412 : 33 : err = aq_nic_update_interrupt_moderation_settings(self);
413 [ - + ]: 33 : if (err)
414 : 0 : goto err_exit;
415 : :
416 : 33 : INIT_WORK(&self->service_task, aq_nic_service_task);
417 : :
418 : 33 : timer_setup(&self->service_timer, aq_nic_service_timer_cb, 0);
419 : 33 : aq_nic_service_timer_cb(&self->service_timer);
420 : :
421 [ - + ]: 33 : if (self->aq_nic_cfg.is_polling) {
422 : 0 : timer_setup(&self->polling_timer, aq_nic_polling_timer_cb, 0);
423 : 0 : mod_timer(&self->polling_timer, jiffies +
424 : : AQ_CFG_POLLING_TIMER_INTERVAL);
425 : : } else {
426 : 33 : for (i = 0U, aq_vec = self->aq_vec[0];
427 [ + + ]: 66 : self->aq_vecs > i; ++i, aq_vec = self->aq_vec[i]) {
428 : 33 : err = aq_pci_func_alloc_irq(self, i, self->ndev->name,
429 : : aq_vec_isr, aq_vec,
430 : : aq_vec_get_affinity_mask(aq_vec));
431 [ - + ]: 33 : if (err < 0)
432 : 0 : goto err_exit;
433 : : }
434 : :
435 : 33 : err = aq_ptp_irq_alloc(self);
436 [ - + ]: 33 : if (err < 0)
437 : 0 : goto err_exit;
438 : :
439 [ - + ]: 33 : if (self->aq_nic_cfg.link_irq_vec) {
440 : 0 : int irqvec = pci_irq_vector(self->pdev,
441 : : self->aq_nic_cfg.link_irq_vec);
442 : 0 : err = request_threaded_irq(irqvec, NULL,
443 : : aq_linkstate_threaded_isr,
444 : : IRQF_SHARED | IRQF_ONESHOT,
445 : 0 : self->ndev->name, self);
446 [ # # ]: 0 : if (err < 0)
447 : 0 : goto err_exit;
448 : 0 : self->msix_entry_mask |= (1 << self->aq_nic_cfg.link_irq_vec);
449 : : }
450 : :
451 : 33 : err = self->aq_hw_ops->hw_irq_enable(self->aq_hw,
452 : : AQ_CFG_IRQ_MASK);
453 [ - + ]: 33 : if (err < 0)
454 : 0 : goto err_exit;
455 : : }
456 : :
457 : 33 : err = netif_set_real_num_tx_queues(self->ndev, self->aq_vecs);
458 [ - + ]: 33 : if (err < 0)
459 : 0 : goto err_exit;
460 : :
461 : 33 : err = netif_set_real_num_rx_queues(self->ndev, self->aq_vecs);
462 [ - + ]: 33 : if (err < 0)
463 : 0 : goto err_exit;
464 : :
465 : 33 : netif_tx_start_all_queues(self->ndev);
466 : :
467 : 33 : err_exit:
468 : 33 : return err;
469 : : }
470 : :
471 : 156 : unsigned int aq_nic_map_skb(struct aq_nic_s *self, struct sk_buff *skb,
472 : : struct aq_ring_s *ring)
473 : : {
474 [ - + ]: 156 : unsigned int nr_frags = skb_shinfo(skb)->nr_frags;
475 : 156 : struct aq_ring_buff_s *first = NULL;
476 [ - + ]: 156 : u8 ipver = ip_hdr(skb)->version;
477 : 156 : struct aq_ring_buff_s *dx_buff;
478 : 156 : bool need_context_tag = false;
479 : 156 : unsigned int frag_count = 0U;
480 : 156 : unsigned int ret = 0U;
481 : 156 : unsigned int dx;
482 : 156 : u8 l4proto = 0;
483 : :
484 [ - + ]: 156 : if (ipver == 4)
485 : 0 : l4proto = ip_hdr(skb)->protocol;
486 [ + - ]: 156 : else if (ipver == 6)
487 : 156 : l4proto = ipv6_hdr(skb)->nexthdr;
488 : :
489 : 156 : dx = ring->sw_tail;
490 : 156 : dx_buff = &ring->buff_ring[dx];
491 : 156 : dx_buff->flags = 0U;
492 : :
493 [ - + ]: 156 : if (unlikely(skb_is_gso(skb))) {
494 [ # # ]: 0 : dx_buff->mss = skb_shinfo(skb)->gso_size;
495 [ # # ]: 0 : if (l4proto == IPPROTO_TCP) {
496 : 0 : dx_buff->is_gso_tcp = 1U;
497 : 0 : dx_buff->len_l4 = tcp_hdrlen(skb);
498 [ # # ]: 0 : } else if (l4proto == IPPROTO_UDP) {
499 : 0 : dx_buff->is_gso_udp = 1U;
500 : 0 : dx_buff->len_l4 = sizeof(struct udphdr);
501 : : /* UDP GSO Hardware does not replace packet length. */
502 : 0 : udp_hdr(skb)->len = htons(dx_buff->mss +
503 : : dx_buff->len_l4);
504 : : } else {
505 [ # # ]: 0 : WARN_ONCE(true, "Bad GSO mode");
506 : 0 : goto exit;
507 : : }
508 : 0 : dx_buff->len_pkt = skb->len;
509 : 0 : dx_buff->len_l2 = ETH_HLEN;
510 : 0 : dx_buff->len_l3 = skb_network_header_len(skb);
511 : 0 : dx_buff->eop_index = 0xffffU;
512 : 0 : dx_buff->is_ipv6 = (ipver == 6);
513 : 0 : need_context_tag = true;
514 : : }
515 : :
516 [ + - - + ]: 156 : if (self->aq_nic_cfg.is_vlan_tx_insert && skb_vlan_tag_present(skb)) {
517 : 0 : dx_buff->vlan_tx_tag = skb_vlan_tag_get(skb);
518 : 0 : dx_buff->len_pkt = skb->len;
519 : 0 : dx_buff->is_vlan = 1U;
520 : 0 : need_context_tag = true;
521 : : }
522 : :
523 [ - + ]: 156 : if (need_context_tag) {
524 [ # # ]: 0 : dx = aq_ring_next_dx(ring, dx);
525 : 0 : dx_buff = &ring->buff_ring[dx];
526 : 0 : dx_buff->flags = 0U;
527 : 0 : ++ret;
528 : : }
529 : :
530 : 156 : dx_buff->len = skb_headlen(skb);
531 : 156 : dx_buff->pa = dma_map_single(aq_nic_get_dev(self),
532 : : skb->data,
533 : : dx_buff->len,
534 : : DMA_TO_DEVICE);
535 : :
536 [ - + ]: 312 : if (unlikely(dma_mapping_error(aq_nic_get_dev(self), dx_buff->pa))) {
537 : 0 : ret = 0;
538 : 0 : goto exit;
539 : : }
540 : :
541 : 156 : first = dx_buff;
542 : 156 : dx_buff->len_pkt = skb->len;
543 : 156 : dx_buff->is_sop = 1U;
544 : 156 : dx_buff->is_mapped = 1U;
545 : 156 : ++ret;
546 : :
547 [ - + ]: 156 : if (skb->ip_summed == CHECKSUM_PARTIAL) {
548 : 0 : dx_buff->is_ip_cso = (htons(ETH_P_IP) == skb->protocol);
549 : 0 : dx_buff->is_tcp_cso = (l4proto == IPPROTO_TCP);
550 : 0 : dx_buff->is_udp_cso = (l4proto == IPPROTO_UDP);
551 : : }
552 : :
553 [ - + ]: 156 : for (; nr_frags--; ++frag_count) {
554 : 0 : unsigned int frag_len = 0U;
555 : 0 : unsigned int buff_offset = 0U;
556 : 0 : unsigned int buff_size = 0U;
557 : 0 : dma_addr_t frag_pa;
558 : 0 : skb_frag_t *frag = &skb_shinfo(skb)->frags[frag_count];
559 : :
560 : 0 : frag_len = skb_frag_size(frag);
561 : :
562 [ # # ]: 0 : while (frag_len) {
563 : 0 : if (frag_len > AQ_CFG_TX_FRAME_MAX)
564 : : buff_size = AQ_CFG_TX_FRAME_MAX;
565 : : else
566 : : buff_size = frag_len;
567 : :
568 : 0 : frag_pa = skb_frag_dma_map(aq_nic_get_dev(self),
569 : : frag,
570 : : buff_offset,
571 : : buff_size,
572 : : DMA_TO_DEVICE);
573 : :
574 [ # # ]: 0 : if (unlikely(dma_mapping_error(aq_nic_get_dev(self),
575 : : frag_pa)))
576 : 0 : goto mapping_error;
577 : :
578 [ # # ]: 0 : dx = aq_ring_next_dx(ring, dx);
579 : 0 : dx_buff = &ring->buff_ring[dx];
580 : :
581 : 0 : dx_buff->flags = 0U;
582 : 0 : dx_buff->len = buff_size;
583 : 0 : dx_buff->pa = frag_pa;
584 : 0 : dx_buff->is_mapped = 1U;
585 : 0 : dx_buff->eop_index = 0xffffU;
586 : :
587 : 0 : frag_len -= buff_size;
588 : 0 : buff_offset += buff_size;
589 : :
590 : 0 : ++ret;
591 : : }
592 : : }
593 : :
594 : 156 : first->eop_index = dx;
595 : 156 : dx_buff->is_eop = 1U;
596 : 156 : dx_buff->skb = skb;
597 : 156 : goto exit;
598 : :
599 : : mapping_error:
600 : 0 : for (dx = ring->sw_tail;
601 [ # # ]: 0 : ret > 0;
602 [ # # ]: 0 : --ret, dx = aq_ring_next_dx(ring, dx)) {
603 : 0 : dx_buff = &ring->buff_ring[dx];
604 : :
605 [ # # ]: 0 : if (!(dx_buff->is_gso_tcp || dx_buff->is_gso_udp) &&
606 [ # # # # ]: 0 : !dx_buff->is_vlan && dx_buff->pa) {
607 [ # # ]: 0 : if (unlikely(dx_buff->is_sop)) {
608 : 0 : dma_unmap_single(aq_nic_get_dev(self),
609 : : dx_buff->pa,
610 : : dx_buff->len,
611 : : DMA_TO_DEVICE);
612 : : } else {
613 : 0 : dma_unmap_page(aq_nic_get_dev(self),
614 : : dx_buff->pa,
615 : : dx_buff->len,
616 : : DMA_TO_DEVICE);
617 : : }
618 : : }
619 : : }
620 : :
621 : 0 : exit:
622 : 156 : return ret;
623 : : }
624 : :
625 : 156 : int aq_nic_xmit(struct aq_nic_s *self, struct sk_buff *skb)
626 : : {
627 : 156 : unsigned int vec = skb->queue_mapping % self->aq_nic_cfg.vecs;
628 : 156 : struct aq_ring_s *ring = NULL;
629 : 156 : unsigned int frags = 0U;
630 : 156 : int err = NETDEV_TX_OK;
631 : 156 : unsigned int tc = 0U;
632 : :
633 [ - + ]: 156 : frags = skb_shinfo(skb)->nr_frags + 1;
634 : :
635 : 156 : ring = self->aq_ring_tx[AQ_NIC_TCVEC2RING(self, tc, vec)];
636 : :
637 [ - + ]: 156 : if (frags > AQ_CFG_SKB_FRAGS_MAX) {
638 : 0 : dev_kfree_skb_any(skb);
639 : 0 : goto err_exit;
640 : : }
641 : :
642 : 156 : aq_ring_update_queue_state(ring);
643 : :
644 [ - + ]: 156 : if (self->aq_nic_cfg.priv_flags & BIT(AQ_HW_LOOPBACK_DMA_NET)) {
645 : 0 : err = NETDEV_TX_BUSY;
646 : 0 : goto err_exit;
647 : : }
648 : :
649 : : /* Above status update may stop the queue. Check this. */
650 [ - + ]: 156 : if (__netif_subqueue_stopped(self->ndev, ring->idx)) {
651 : 0 : err = NETDEV_TX_BUSY;
652 : 0 : goto err_exit;
653 : : }
654 : :
655 : 156 : frags = aq_nic_map_skb(self, skb, ring);
656 : :
657 [ + - ]: 156 : if (likely(frags)) {
658 : 156 : err = self->aq_hw_ops->hw_ring_tx_xmit(self->aq_hw,
659 : : ring, frags);
660 : : } else {
661 : : err = NETDEV_TX_BUSY;
662 : : }
663 : :
664 : 156 : err_exit:
665 : 156 : return err;
666 : : }
667 : :
668 : 114 : int aq_nic_update_interrupt_moderation_settings(struct aq_nic_s *self)
669 : : {
670 : 114 : return self->aq_hw_ops->hw_interrupt_moderation_set(self->aq_hw);
671 : : }
672 : :
673 : 94 : int aq_nic_set_packet_filter(struct aq_nic_s *self, unsigned int flags)
674 : : {
675 : 94 : int err = 0;
676 : :
677 : 0 : err = self->aq_hw_ops->hw_packet_filter_set(self->aq_hw, flags);
678 [ - + - - ]: 94 : if (err < 0)
679 : 0 : goto err_exit;
680 : :
681 : 94 : self->packet_filter = flags;
682 : :
683 : 0 : err_exit:
684 : 0 : return err;
685 : : }
686 : :
687 : 94 : int aq_nic_set_multicast_list(struct aq_nic_s *self, struct net_device *ndev)
688 : : {
689 : 94 : const struct aq_hw_ops *hw_ops = self->aq_hw_ops;
690 : 94 : struct aq_nic_cfg_s *cfg = &self->aq_nic_cfg;
691 : 94 : unsigned int packet_filter = ndev->flags;
692 : 94 : struct netdev_hw_addr *ha = NULL;
693 : 94 : unsigned int i = 0U;
694 : 94 : int err = 0;
695 : :
696 : 94 : self->mc_list.count = 0;
697 [ - + ]: 94 : if (netdev_uc_count(ndev) > AQ_HW_MULTICAST_ADDRESS_MAX) {
698 : 0 : packet_filter |= IFF_PROMISC;
699 : : } else {
700 [ - + ]: 94 : netdev_for_each_uc_addr(ha, ndev) {
701 : 0 : ether_addr_copy(self->mc_list.ar[i++], ha->addr);
702 : : }
703 : : }
704 : :
705 : 94 : cfg->is_mc_list_enabled = !!(packet_filter & IFF_MULTICAST);
706 [ + - ]: 94 : if (cfg->is_mc_list_enabled) {
707 [ - + ]: 94 : if (i + netdev_mc_count(ndev) > AQ_HW_MULTICAST_ADDRESS_MAX) {
708 : 0 : packet_filter |= IFF_ALLMULTI;
709 : : } else {
710 [ + + ]: 277 : netdev_for_each_mc_addr(ha, ndev) {
711 : 183 : ether_addr_copy(self->mc_list.ar[i++],
712 : : ha->addr);
713 : : }
714 : : }
715 : : }
716 : :
717 [ + - ]: 94 : if (i > 0 && i <= AQ_HW_MULTICAST_ADDRESS_MAX) {
718 : 94 : self->mc_list.count = i;
719 : 94 : err = hw_ops->hw_multicast_list_set(self->aq_hw,
720 : 94 : self->mc_list.ar,
721 : : self->mc_list.count);
722 [ + - ]: 94 : if (err < 0)
723 : : return err;
724 : : }
725 : :
726 : 94 : return aq_nic_set_packet_filter(self, packet_filter);
727 : : }
728 : :
729 : 0 : int aq_nic_set_mtu(struct aq_nic_s *self, int new_mtu)
730 : : {
731 : 0 : self->aq_nic_cfg.mtu = new_mtu;
732 : :
733 : 0 : return 0;
734 : : }
735 : :
736 : 0 : int aq_nic_set_mac(struct aq_nic_s *self, struct net_device *ndev)
737 : : {
738 : 0 : return self->aq_hw_ops->hw_set_mac_address(self->aq_hw, ndev->dev_addr);
739 : : }
740 : :
741 : 0 : unsigned int aq_nic_get_link_speed(struct aq_nic_s *self)
742 : : {
743 : 0 : return self->link_status.mbps;
744 : : }
745 : :
746 : 0 : int aq_nic_get_regs(struct aq_nic_s *self, struct ethtool_regs *regs, void *p)
747 : : {
748 : 0 : u32 *regs_buff = p;
749 : 0 : int err = 0;
750 : :
751 : 0 : regs->version = 1;
752 : :
753 : 0 : err = self->aq_hw_ops->hw_get_regs(self->aq_hw,
754 : : self->aq_nic_cfg.aq_hw_caps,
755 : : regs_buff);
756 : 0 : if (err < 0)
757 : : goto err_exit;
758 : :
759 : : err_exit:
760 : 0 : return err;
761 : : }
762 : :
763 : 66 : int aq_nic_get_regs_count(struct aq_nic_s *self)
764 : : {
765 : 66 : return self->aq_nic_cfg.aq_hw_caps->mac_regs_count;
766 : : }
767 : :
768 : 0 : void aq_nic_get_stats(struct aq_nic_s *self, u64 *data)
769 : : {
770 : 0 : struct aq_vec_s *aq_vec = NULL;
771 : 0 : struct aq_stats_s *stats;
772 : 0 : unsigned int count = 0U;
773 : 0 : unsigned int i = 0U;
774 : :
775 [ # # ]: 0 : if (self->aq_fw_ops->update_stats) {
776 : 0 : mutex_lock(&self->fwreq_mutex);
777 : 0 : self->aq_fw_ops->update_stats(self->aq_hw);
778 : 0 : mutex_unlock(&self->fwreq_mutex);
779 : : }
780 : 0 : stats = self->aq_hw_ops->hw_get_hw_stats(self->aq_hw);
781 : :
782 [ # # ]: 0 : if (!stats)
783 : 0 : goto err_exit;
784 : :
785 : 0 : data[i] = stats->uprc + stats->mprc + stats->bprc;
786 : 0 : data[++i] = stats->uprc;
787 : 0 : data[++i] = stats->mprc;
788 : 0 : data[++i] = stats->bprc;
789 : 0 : data[++i] = stats->erpt;
790 : 0 : data[++i] = stats->uptc + stats->mptc + stats->bptc;
791 : 0 : data[++i] = stats->uptc;
792 : 0 : data[++i] = stats->mptc;
793 : 0 : data[++i] = stats->bptc;
794 : 0 : data[++i] = stats->ubrc;
795 : 0 : data[++i] = stats->ubtc;
796 : 0 : data[++i] = stats->mbrc;
797 : 0 : data[++i] = stats->mbtc;
798 : 0 : data[++i] = stats->bbrc;
799 : 0 : data[++i] = stats->bbtc;
800 : 0 : data[++i] = stats->ubrc + stats->mbrc + stats->bbrc;
801 : 0 : data[++i] = stats->ubtc + stats->mbtc + stats->bbtc;
802 : 0 : data[++i] = stats->dma_pkt_rc;
803 : 0 : data[++i] = stats->dma_pkt_tc;
804 : 0 : data[++i] = stats->dma_oct_rc;
805 : 0 : data[++i] = stats->dma_oct_tc;
806 : 0 : data[++i] = stats->dpc;
807 : :
808 : 0 : i++;
809 : :
810 : 0 : data += i;
811 : :
812 : 0 : for (i = 0U, aq_vec = self->aq_vec[0];
813 [ # # # # ]: 0 : aq_vec && self->aq_vecs > i; ++i, aq_vec = self->aq_vec[i]) {
814 : 0 : data += count;
815 : 0 : aq_vec_get_sw_stats(aq_vec, data, &count);
816 : : }
817 : :
818 : 0 : err_exit:;
819 : 0 : }
820 : :
821 : 84 : static void aq_nic_update_ndev_stats(struct aq_nic_s *self)
822 : : {
823 : 84 : struct aq_stats_s *stats = self->aq_hw_ops->hw_get_hw_stats(self->aq_hw);
824 : 84 : struct net_device *ndev = self->ndev;
825 : :
826 : 84 : ndev->stats.rx_packets = stats->dma_pkt_rc;
827 : 84 : ndev->stats.rx_bytes = stats->dma_oct_rc;
828 : 84 : ndev->stats.rx_errors = stats->erpr;
829 : 84 : ndev->stats.rx_dropped = stats->dpc;
830 : 84 : ndev->stats.tx_packets = stats->dma_pkt_tc;
831 : 84 : ndev->stats.tx_bytes = stats->dma_oct_tc;
832 : 84 : ndev->stats.tx_errors = stats->erpt;
833 : 84 : ndev->stats.multicast = stats->mprc;
834 : 84 : }
835 : :
836 : 0 : void aq_nic_get_link_ksettings(struct aq_nic_s *self,
837 : : struct ethtool_link_ksettings *cmd)
838 : : {
839 [ # # ]: 0 : if (self->aq_nic_cfg.aq_hw_caps->media_type == AQ_HW_MEDIA_TYPE_FIBRE)
840 : 0 : cmd->base.port = PORT_FIBRE;
841 : : else
842 : 0 : cmd->base.port = PORT_TP;
843 : : /* This driver supports only 10G capable adapters, so DUPLEX_FULL */
844 : 0 : cmd->base.duplex = DUPLEX_FULL;
845 : 0 : cmd->base.autoneg = self->aq_nic_cfg.is_autoneg;
846 : :
847 [ # # ]: 0 : ethtool_link_ksettings_zero_link_mode(cmd, supported);
848 : :
849 [ # # ]: 0 : if (self->aq_nic_cfg.aq_hw_caps->link_speed_msk & AQ_NIC_RATE_10G)
850 : 0 : ethtool_link_ksettings_add_link_mode(cmd, supported,
851 : : 10000baseT_Full);
852 : :
853 [ # # ]: 0 : if (self->aq_nic_cfg.aq_hw_caps->link_speed_msk & AQ_NIC_RATE_5G)
854 : 0 : ethtool_link_ksettings_add_link_mode(cmd, supported,
855 : : 5000baseT_Full);
856 : :
857 [ # # ]: 0 : if (self->aq_nic_cfg.aq_hw_caps->link_speed_msk & AQ_NIC_RATE_2GS)
858 : 0 : ethtool_link_ksettings_add_link_mode(cmd, supported,
859 : : 2500baseT_Full);
860 : :
861 [ # # ]: 0 : if (self->aq_nic_cfg.aq_hw_caps->link_speed_msk & AQ_NIC_RATE_1G)
862 : 0 : ethtool_link_ksettings_add_link_mode(cmd, supported,
863 : : 1000baseT_Full);
864 : :
865 [ # # ]: 0 : if (self->aq_nic_cfg.aq_hw_caps->link_speed_msk & AQ_NIC_RATE_100M)
866 : 0 : ethtool_link_ksettings_add_link_mode(cmd, supported,
867 : : 100baseT_Full);
868 : :
869 [ # # ]: 0 : if (self->aq_nic_cfg.aq_hw_caps->flow_control) {
870 : 0 : ethtool_link_ksettings_add_link_mode(cmd, supported,
871 : : Pause);
872 : 0 : ethtool_link_ksettings_add_link_mode(cmd, supported,
873 : : Asym_Pause);
874 : : }
875 : :
876 : 0 : ethtool_link_ksettings_add_link_mode(cmd, supported, Autoneg);
877 : :
878 [ # # ]: 0 : if (self->aq_nic_cfg.aq_hw_caps->media_type == AQ_HW_MEDIA_TYPE_FIBRE)
879 : 0 : ethtool_link_ksettings_add_link_mode(cmd, supported, FIBRE);
880 : : else
881 : 0 : ethtool_link_ksettings_add_link_mode(cmd, supported, TP);
882 : :
883 [ # # ]: 0 : ethtool_link_ksettings_zero_link_mode(cmd, advertising);
884 : :
885 [ # # ]: 0 : if (self->aq_nic_cfg.is_autoneg)
886 : 0 : ethtool_link_ksettings_add_link_mode(cmd, advertising, Autoneg);
887 : :
888 [ # # ]: 0 : if (self->aq_nic_cfg.link_speed_msk & AQ_NIC_RATE_10G)
889 : 0 : ethtool_link_ksettings_add_link_mode(cmd, advertising,
890 : : 10000baseT_Full);
891 : :
892 [ # # ]: 0 : if (self->aq_nic_cfg.link_speed_msk & AQ_NIC_RATE_5G)
893 : 0 : ethtool_link_ksettings_add_link_mode(cmd, advertising,
894 : : 5000baseT_Full);
895 : :
896 [ # # ]: 0 : if (self->aq_nic_cfg.link_speed_msk & AQ_NIC_RATE_2GS)
897 : 0 : ethtool_link_ksettings_add_link_mode(cmd, advertising,
898 : : 2500baseT_Full);
899 : :
900 [ # # ]: 0 : if (self->aq_nic_cfg.link_speed_msk & AQ_NIC_RATE_1G)
901 : 0 : ethtool_link_ksettings_add_link_mode(cmd, advertising,
902 : : 1000baseT_Full);
903 : :
904 [ # # ]: 0 : if (self->aq_nic_cfg.link_speed_msk & AQ_NIC_RATE_100M)
905 : 0 : ethtool_link_ksettings_add_link_mode(cmd, advertising,
906 : : 100baseT_Full);
907 : :
908 [ # # ]: 0 : if (self->aq_nic_cfg.fc.cur & AQ_NIC_FC_RX)
909 : 0 : ethtool_link_ksettings_add_link_mode(cmd, advertising,
910 : : Pause);
911 : :
912 : : /* Asym is when either RX or TX, but not both */
913 : 0 : if (!!(self->aq_nic_cfg.fc.cur & AQ_NIC_FC_TX) ^
914 [ # # ]: 0 : !!(self->aq_nic_cfg.fc.cur & AQ_NIC_FC_RX))
915 : 0 : ethtool_link_ksettings_add_link_mode(cmd, advertising,
916 : : Asym_Pause);
917 : :
918 [ # # ]: 0 : if (self->aq_nic_cfg.aq_hw_caps->media_type == AQ_HW_MEDIA_TYPE_FIBRE)
919 : 0 : ethtool_link_ksettings_add_link_mode(cmd, advertising, FIBRE);
920 : : else
921 : 0 : ethtool_link_ksettings_add_link_mode(cmd, advertising, TP);
922 : 0 : }
923 : :
924 : 0 : int aq_nic_set_link_ksettings(struct aq_nic_s *self,
925 : : const struct ethtool_link_ksettings *cmd)
926 : : {
927 : 0 : u32 speed = 0U;
928 : 0 : u32 rate = 0U;
929 : 0 : int err = 0;
930 : :
931 [ # # ]: 0 : if (cmd->base.autoneg == AUTONEG_ENABLE) {
932 : 0 : rate = self->aq_nic_cfg.aq_hw_caps->link_speed_msk;
933 : 0 : self->aq_nic_cfg.is_autoneg = true;
934 : : } else {
935 : 0 : speed = cmd->base.speed;
936 : :
937 [ # # # # : 0 : switch (speed) {
# # ]
938 : : case SPEED_100:
939 : : rate = AQ_NIC_RATE_100M;
940 : : break;
941 : :
942 : 0 : case SPEED_1000:
943 : 0 : rate = AQ_NIC_RATE_1G;
944 : 0 : break;
945 : :
946 : 0 : case SPEED_2500:
947 : 0 : rate = AQ_NIC_RATE_2GS;
948 : 0 : break;
949 : :
950 : 0 : case SPEED_5000:
951 : 0 : rate = AQ_NIC_RATE_5G;
952 : 0 : break;
953 : :
954 : 0 : case SPEED_10000:
955 : 0 : rate = AQ_NIC_RATE_10G;
956 : 0 : break;
957 : :
958 : 0 : default:
959 : 0 : err = -1;
960 : 0 : goto err_exit;
961 : 0 : break;
962 : : }
963 [ # # ]: 0 : if (!(self->aq_nic_cfg.aq_hw_caps->link_speed_msk & rate)) {
964 : 0 : err = -1;
965 : 0 : goto err_exit;
966 : : }
967 : :
968 : 0 : self->aq_nic_cfg.is_autoneg = false;
969 : : }
970 : :
971 : 0 : mutex_lock(&self->fwreq_mutex);
972 : 0 : err = self->aq_fw_ops->set_link_speed(self->aq_hw, rate);
973 : 0 : mutex_unlock(&self->fwreq_mutex);
974 [ # # ]: 0 : if (err < 0)
975 : 0 : goto err_exit;
976 : :
977 : 0 : self->aq_nic_cfg.link_speed_msk = rate;
978 : :
979 : 0 : err_exit:
980 : 0 : return err;
981 : : }
982 : :
983 : 465 : struct aq_nic_cfg_s *aq_nic_get_cfg(struct aq_nic_s *self)
984 : : {
985 [ + + ]: 66 : return &self->aq_nic_cfg;
986 : : }
987 : :
988 : 33 : u32 aq_nic_get_fw_version(struct aq_nic_s *self)
989 : : {
990 : 33 : u32 fw_version = 0U;
991 : :
992 : 33 : self->aq_hw_ops->hw_get_fw_version(self->aq_hw, &fw_version);
993 : :
994 : 33 : return fw_version;
995 : : }
996 : :
997 : 33 : int aq_nic_set_loopback(struct aq_nic_s *self)
998 : : {
999 : 33 : struct aq_nic_cfg_s *cfg = &self->aq_nic_cfg;
1000 : :
1001 [ + - ]: 33 : if (!self->aq_hw_ops->hw_set_loopback ||
1002 [ + + ]: 33 : !self->aq_fw_ops->set_phyloopback)
1003 : : return -ENOTSUPP;
1004 : :
1005 : 28 : mutex_lock(&self->fwreq_mutex);
1006 : 28 : self->aq_hw_ops->hw_set_loopback(self->aq_hw,
1007 : : AQ_HW_LOOPBACK_DMA_SYS,
1008 : 28 : !!(cfg->priv_flags &
1009 : : BIT(AQ_HW_LOOPBACK_DMA_SYS)));
1010 : :
1011 : 28 : self->aq_hw_ops->hw_set_loopback(self->aq_hw,
1012 : : AQ_HW_LOOPBACK_PKT_SYS,
1013 : 28 : !!(cfg->priv_flags &
1014 : : BIT(AQ_HW_LOOPBACK_PKT_SYS)));
1015 : :
1016 : 28 : self->aq_hw_ops->hw_set_loopback(self->aq_hw,
1017 : : AQ_HW_LOOPBACK_DMA_NET,
1018 : 28 : !!(cfg->priv_flags &
1019 : : BIT(AQ_HW_LOOPBACK_DMA_NET)));
1020 : :
1021 : 28 : self->aq_fw_ops->set_phyloopback(self->aq_hw,
1022 : : AQ_HW_LOOPBACK_PHYINT_SYS,
1023 : 28 : !!(cfg->priv_flags &
1024 : : BIT(AQ_HW_LOOPBACK_PHYINT_SYS)));
1025 : :
1026 : 28 : self->aq_fw_ops->set_phyloopback(self->aq_hw,
1027 : : AQ_HW_LOOPBACK_PHYEXT_SYS,
1028 : 28 : !!(cfg->priv_flags &
1029 : : BIT(AQ_HW_LOOPBACK_PHYEXT_SYS)));
1030 : 28 : mutex_unlock(&self->fwreq_mutex);
1031 : :
1032 : 28 : return 0;
1033 : : }
1034 : :
1035 : 0 : int aq_nic_stop(struct aq_nic_s *self)
1036 : : {
1037 : 0 : struct aq_vec_s *aq_vec = NULL;
1038 : 0 : unsigned int i = 0U;
1039 : :
1040 : 0 : netif_tx_disable(self->ndev);
1041 : 0 : netif_carrier_off(self->ndev);
1042 : :
1043 : 0 : del_timer_sync(&self->service_timer);
1044 : 0 : cancel_work_sync(&self->service_task);
1045 : :
1046 : 0 : self->aq_hw_ops->hw_irq_disable(self->aq_hw, AQ_CFG_IRQ_MASK);
1047 : :
1048 [ # # ]: 0 : if (self->aq_nic_cfg.is_polling)
1049 : 0 : del_timer_sync(&self->polling_timer);
1050 : : else
1051 : 0 : aq_pci_func_free_irqs(self);
1052 : :
1053 : 0 : aq_ptp_irq_free(self);
1054 : :
1055 : 0 : for (i = 0U, aq_vec = self->aq_vec[0];
1056 [ # # ]: 0 : self->aq_vecs > i; ++i, aq_vec = self->aq_vec[i])
1057 : 0 : aq_vec_stop(aq_vec);
1058 : :
1059 : 0 : aq_ptp_ring_stop(self);
1060 : :
1061 : 0 : return self->aq_hw_ops->hw_stop(self->aq_hw);
1062 : : }
1063 : :
1064 : 0 : void aq_nic_set_power(struct aq_nic_s *self)
1065 : : {
1066 [ # # ]: 0 : if (self->power_state != AQ_HW_POWER_STATE_D0 ||
1067 [ # # ]: 0 : self->aq_hw->aq_nic_cfg->wol)
1068 [ # # ]: 0 : if (likely(self->aq_fw_ops->set_power)) {
1069 : 0 : mutex_lock(&self->fwreq_mutex);
1070 : 0 : self->aq_fw_ops->set_power(self->aq_hw,
1071 : : self->power_state,
1072 : 0 : self->ndev->dev_addr);
1073 : 0 : mutex_unlock(&self->fwreq_mutex);
1074 : : }
1075 : 0 : }
1076 : :
1077 : 0 : void aq_nic_deinit(struct aq_nic_s *self, bool link_down)
1078 : : {
1079 : 0 : struct aq_vec_s *aq_vec = NULL;
1080 : 0 : unsigned int i = 0U;
1081 : :
1082 [ # # ]: 0 : if (!self)
1083 : 0 : goto err_exit;
1084 : :
1085 : 0 : for (i = 0U, aq_vec = self->aq_vec[0];
1086 [ # # ]: 0 : self->aq_vecs > i; ++i, aq_vec = self->aq_vec[i])
1087 : 0 : aq_vec_deinit(aq_vec);
1088 : :
1089 : 0 : aq_ptp_unregister(self);
1090 : 0 : aq_ptp_ring_deinit(self);
1091 : 0 : aq_ptp_ring_free(self);
1092 : 0 : aq_ptp_free(self);
1093 : :
1094 [ # # # # ]: 0 : if (likely(self->aq_fw_ops->deinit) && link_down) {
1095 : 0 : mutex_lock(&self->fwreq_mutex);
1096 : 0 : self->aq_fw_ops->deinit(self->aq_hw);
1097 : 0 : mutex_unlock(&self->fwreq_mutex);
1098 : : }
1099 : :
1100 : 0 : err_exit:;
1101 : 0 : }
1102 : :
1103 : 45 : void aq_nic_free_vectors(struct aq_nic_s *self)
1104 : : {
1105 : 45 : unsigned int i = 0U;
1106 : :
1107 [ + - ]: 45 : if (!self)
1108 : 0 : goto err_exit;
1109 : :
1110 [ + + ]: 405 : for (i = ARRAY_SIZE(self->aq_vec); i--;) {
1111 [ - + ]: 360 : if (self->aq_vec[i]) {
1112 : 0 : aq_vec_free(self->aq_vec[i]);
1113 : 0 : self->aq_vec[i] = NULL;
1114 : : }
1115 : : }
1116 : :
1117 : 45 : err_exit:;
1118 : 45 : }
1119 : :
1120 : 0 : void aq_nic_shutdown(struct aq_nic_s *self)
1121 : : {
1122 : 0 : int err = 0;
1123 : :
1124 [ # # ]: 0 : if (!self->ndev)
1125 : : return;
1126 : :
1127 : 0 : rtnl_lock();
1128 : :
1129 : 0 : netif_device_detach(self->ndev);
1130 : :
1131 [ # # ]: 0 : if (netif_running(self->ndev)) {
1132 : 0 : err = aq_nic_stop(self);
1133 [ # # ]: 0 : if (err < 0)
1134 : 0 : goto err_exit;
1135 : : }
1136 : 0 : aq_nic_deinit(self, !self->aq_hw->aq_nic_cfg->wol);
1137 : 0 : aq_nic_set_power(self);
1138 : :
1139 : 0 : err_exit:
1140 : 0 : rtnl_unlock();
1141 : : }
1142 : :
1143 : 0 : u8 aq_nic_reserve_filter(struct aq_nic_s *self, enum aq_rx_filter_type type)
1144 : : {
1145 : 0 : u8 location = 0xFF;
1146 : 0 : u32 fltr_cnt;
1147 : 0 : u32 n_bit;
1148 : :
1149 [ # # # ]: 0 : switch (type) {
1150 : 0 : case aq_rx_filter_ethertype:
1151 : 0 : location = AQ_RX_LAST_LOC_FETHERT - AQ_RX_FIRST_LOC_FETHERT -
1152 : 0 : self->aq_hw_rx_fltrs.fet_reserved_count;
1153 : 0 : self->aq_hw_rx_fltrs.fet_reserved_count++;
1154 : 0 : break;
1155 : 0 : case aq_rx_filter_l3l4:
1156 : 0 : fltr_cnt = AQ_RX_LAST_LOC_FL3L4 - AQ_RX_FIRST_LOC_FL3L4;
1157 : 0 : n_bit = fltr_cnt - self->aq_hw_rx_fltrs.fl3l4.reserved_count;
1158 : :
1159 : 0 : self->aq_hw_rx_fltrs.fl3l4.active_ipv4 |= BIT(n_bit);
1160 : 0 : self->aq_hw_rx_fltrs.fl3l4.reserved_count++;
1161 : 0 : location = n_bit;
1162 : 0 : break;
1163 : : default:
1164 : : break;
1165 : : }
1166 : :
1167 : 0 : return location;
1168 : : }
1169 : :
1170 : 0 : void aq_nic_release_filter(struct aq_nic_s *self, enum aq_rx_filter_type type,
1171 : : u32 location)
1172 : : {
1173 [ # # # ]: 0 : switch (type) {
1174 : 0 : case aq_rx_filter_ethertype:
1175 : 0 : self->aq_hw_rx_fltrs.fet_reserved_count--;
1176 : 0 : break;
1177 : 0 : case aq_rx_filter_l3l4:
1178 : 0 : self->aq_hw_rx_fltrs.fl3l4.reserved_count--;
1179 : 0 : self->aq_hw_rx_fltrs.fl3l4.active_ipv4 &= ~BIT(location);
1180 : 0 : break;
1181 : : default:
1182 : : break;
1183 : : }
1184 : 0 : }
|