Commit | Line | Data |
---|---|---|
b3890e30 AD |
1 | /* Intel Ethernet Switch Host Interface Driver |
2 | * Copyright(c) 2013 - 2014 Intel Corporation. | |
3 | * | |
4 | * This program is free software; you can redistribute it and/or modify it | |
5 | * under the terms and conditions of the GNU General Public License, | |
6 | * version 2, as published by the Free Software Foundation. | |
7 | * | |
8 | * This program is distributed in the hope it will be useful, but WITHOUT | |
9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
10 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | |
11 | * more details. | |
12 | * | |
13 | * The full GNU General Public License is included in this distribution in | |
14 | * the file called "COPYING". | |
15 | * | |
16 | * Contact Information: | |
17 | * e1000-devel Mailing List <e1000-devel@lists.sourceforge.net> | |
18 | * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 | |
19 | */ | |
20 | ||
21 | #include <linux/module.h> | |
22 | ||
23 | #include "fm10k.h" | |
24 | ||
0e7b3644 AD |
25 | static const struct fm10k_info *fm10k_info_tbl[] = { |
26 | [fm10k_device_pf] = &fm10k_pf_info, | |
27 | }; | |
28 | ||
b3890e30 AD |
29 | /** |
30 | * fm10k_pci_tbl - PCI Device ID Table | |
31 | * | |
32 | * Wildcard entries (PCI_ANY_ID) should come last | |
33 | * Last entry must be all 0s | |
34 | * | |
35 | * { Vendor ID, Device ID, SubVendor ID, SubDevice ID, | |
36 | * Class, Class Mask, private data (not used) } | |
37 | */ | |
38 | static const struct pci_device_id fm10k_pci_tbl[] = { | |
0e7b3644 | 39 | { PCI_VDEVICE(INTEL, FM10K_DEV_ID_PF), fm10k_device_pf }, |
b3890e30 AD |
40 | /* required last entry */ |
41 | { 0, } | |
42 | }; | |
43 | MODULE_DEVICE_TABLE(pci, fm10k_pci_tbl); | |
44 | ||
04a5aefb AD |
45 | u16 fm10k_read_pci_cfg_word(struct fm10k_hw *hw, u32 reg) |
46 | { | |
47 | struct fm10k_intfc *interface = hw->back; | |
48 | u16 value = 0; | |
49 | ||
50 | if (FM10K_REMOVED(hw->hw_addr)) | |
51 | return ~value; | |
52 | ||
53 | pci_read_config_word(interface->pdev, reg, &value); | |
54 | if (value == 0xFFFF) | |
55 | fm10k_write_flush(hw); | |
56 | ||
57 | return value; | |
58 | } | |
59 | ||
60 | u32 fm10k_read_reg(struct fm10k_hw *hw, int reg) | |
61 | { | |
62 | u32 __iomem *hw_addr = ACCESS_ONCE(hw->hw_addr); | |
63 | u32 value = 0; | |
64 | ||
65 | if (FM10K_REMOVED(hw_addr)) | |
66 | return ~value; | |
67 | ||
68 | value = readl(&hw_addr[reg]); | |
0e7b3644 AD |
69 | if (!(~value) && (!reg || !(~readl(hw_addr)))) { |
70 | struct fm10k_intfc *interface = hw->back; | |
71 | struct net_device *netdev = interface->netdev; | |
72 | ||
04a5aefb | 73 | hw->hw_addr = NULL; |
0e7b3644 AD |
74 | netif_device_detach(netdev); |
75 | netdev_err(netdev, "PCIe link lost, device now detached\n"); | |
76 | } | |
04a5aefb AD |
77 | |
78 | return value; | |
79 | } | |
80 | ||
0e7b3644 AD |
81 | static int fm10k_hw_ready(struct fm10k_intfc *interface) |
82 | { | |
83 | struct fm10k_hw *hw = &interface->hw; | |
84 | ||
85 | fm10k_write_flush(hw); | |
86 | ||
87 | return FM10K_REMOVED(hw->hw_addr) ? -ENODEV : 0; | |
88 | } | |
89 | ||
18283cad AD |
90 | static void fm10k_napi_enable_all(struct fm10k_intfc *interface) |
91 | { | |
92 | struct fm10k_q_vector *q_vector; | |
93 | int q_idx; | |
94 | ||
95 | for (q_idx = 0; q_idx < interface->num_q_vectors; q_idx++) { | |
96 | q_vector = interface->q_vector[q_idx]; | |
97 | napi_enable(&q_vector->napi); | |
98 | } | |
99 | } | |
100 | ||
101 | static irqreturn_t fm10k_msix_clean_rings(int irq, void *data) | |
102 | { | |
103 | struct fm10k_q_vector *q_vector = data; | |
104 | ||
105 | if (q_vector->rx.count || q_vector->tx.count) | |
106 | napi_schedule(&q_vector->napi); | |
107 | ||
108 | return IRQ_HANDLED; | |
109 | } | |
110 | ||
111 | #define FM10K_ERR_MSG(type) case (type): error = #type; break | |
112 | static void fm10k_print_fault(struct fm10k_intfc *interface, int type, | |
113 | struct fm10k_fault *fault) | |
114 | { | |
115 | struct pci_dev *pdev = interface->pdev; | |
116 | char *error; | |
117 | ||
118 | switch (type) { | |
119 | case FM10K_PCA_FAULT: | |
120 | switch (fault->type) { | |
121 | default: | |
122 | error = "Unknown PCA error"; | |
123 | break; | |
124 | FM10K_ERR_MSG(PCA_NO_FAULT); | |
125 | FM10K_ERR_MSG(PCA_UNMAPPED_ADDR); | |
126 | FM10K_ERR_MSG(PCA_BAD_QACCESS_PF); | |
127 | FM10K_ERR_MSG(PCA_BAD_QACCESS_VF); | |
128 | FM10K_ERR_MSG(PCA_MALICIOUS_REQ); | |
129 | FM10K_ERR_MSG(PCA_POISONED_TLP); | |
130 | FM10K_ERR_MSG(PCA_TLP_ABORT); | |
131 | } | |
132 | break; | |
133 | case FM10K_THI_FAULT: | |
134 | switch (fault->type) { | |
135 | default: | |
136 | error = "Unknown THI error"; | |
137 | break; | |
138 | FM10K_ERR_MSG(THI_NO_FAULT); | |
139 | FM10K_ERR_MSG(THI_MAL_DIS_Q_FAULT); | |
140 | } | |
141 | break; | |
142 | case FM10K_FUM_FAULT: | |
143 | switch (fault->type) { | |
144 | default: | |
145 | error = "Unknown FUM error"; | |
146 | break; | |
147 | FM10K_ERR_MSG(FUM_NO_FAULT); | |
148 | FM10K_ERR_MSG(FUM_UNMAPPED_ADDR); | |
149 | FM10K_ERR_MSG(FUM_BAD_VF_QACCESS); | |
150 | FM10K_ERR_MSG(FUM_ADD_DECODE_ERR); | |
151 | FM10K_ERR_MSG(FUM_RO_ERROR); | |
152 | FM10K_ERR_MSG(FUM_QPRC_CRC_ERROR); | |
153 | FM10K_ERR_MSG(FUM_CSR_TIMEOUT); | |
154 | FM10K_ERR_MSG(FUM_INVALID_TYPE); | |
155 | FM10K_ERR_MSG(FUM_INVALID_LENGTH); | |
156 | FM10K_ERR_MSG(FUM_INVALID_BE); | |
157 | FM10K_ERR_MSG(FUM_INVALID_ALIGN); | |
158 | } | |
159 | break; | |
160 | default: | |
161 | error = "Undocumented fault"; | |
162 | break; | |
163 | } | |
164 | ||
165 | dev_warn(&pdev->dev, | |
166 | "%s Address: 0x%llx SpecInfo: 0x%x Func: %02x.%0x\n", | |
167 | error, fault->address, fault->specinfo, | |
168 | PCI_SLOT(fault->func), PCI_FUNC(fault->func)); | |
169 | } | |
170 | ||
171 | static void fm10k_report_fault(struct fm10k_intfc *interface, u32 eicr) | |
172 | { | |
173 | struct fm10k_hw *hw = &interface->hw; | |
174 | struct fm10k_fault fault = { 0 }; | |
175 | int type, err; | |
176 | ||
177 | for (eicr &= FM10K_EICR_FAULT_MASK, type = FM10K_PCA_FAULT; | |
178 | eicr; | |
179 | eicr >>= 1, type += FM10K_FAULT_SIZE) { | |
180 | /* only check if there is an error reported */ | |
181 | if (!(eicr & 0x1)) | |
182 | continue; | |
183 | ||
184 | /* retrieve fault info */ | |
185 | err = hw->mac.ops.get_fault(hw, type, &fault); | |
186 | if (err) { | |
187 | dev_err(&interface->pdev->dev, | |
188 | "error reading fault\n"); | |
189 | continue; | |
190 | } | |
191 | ||
192 | fm10k_print_fault(interface, type, &fault); | |
193 | } | |
194 | } | |
195 | ||
196 | static void fm10k_reset_drop_on_empty(struct fm10k_intfc *interface, u32 eicr) | |
197 | { | |
198 | struct fm10k_hw *hw = &interface->hw; | |
199 | const u32 rxdctl = FM10K_RXDCTL_WRITE_BACK_MIN_DELAY; | |
200 | u32 maxholdq; | |
201 | int q; | |
202 | ||
203 | if (!(eicr & FM10K_EICR_MAXHOLDTIME)) | |
204 | return; | |
205 | ||
206 | maxholdq = fm10k_read_reg(hw, FM10K_MAXHOLDQ(7)); | |
207 | if (maxholdq) | |
208 | fm10k_write_reg(hw, FM10K_MAXHOLDQ(7), maxholdq); | |
209 | for (q = 255;;) { | |
210 | if (maxholdq & (1 << 31)) { | |
211 | if (q < FM10K_MAX_QUEUES_PF) { | |
212 | interface->rx_overrun_pf++; | |
213 | fm10k_write_reg(hw, FM10K_RXDCTL(q), rxdctl); | |
214 | } else { | |
215 | interface->rx_overrun_vf++; | |
216 | } | |
217 | } | |
218 | ||
219 | maxholdq *= 2; | |
220 | if (!maxholdq) | |
221 | q &= ~(32 - 1); | |
222 | ||
223 | if (!q) | |
224 | break; | |
225 | ||
226 | if (q-- % 32) | |
227 | continue; | |
228 | ||
229 | maxholdq = fm10k_read_reg(hw, FM10K_MAXHOLDQ(q / 32)); | |
230 | if (maxholdq) | |
231 | fm10k_write_reg(hw, FM10K_MAXHOLDQ(q / 32), maxholdq); | |
232 | } | |
233 | } | |
234 | ||
235 | static irqreturn_t fm10k_msix_mbx_pf(int irq, void *data) | |
236 | { | |
237 | struct fm10k_intfc *interface = data; | |
238 | struct fm10k_hw *hw = &interface->hw; | |
239 | struct fm10k_mbx_info *mbx = &hw->mbx; | |
240 | u32 eicr; | |
241 | ||
242 | /* unmask any set bits related to this interrupt */ | |
243 | eicr = fm10k_read_reg(hw, FM10K_EICR); | |
244 | fm10k_write_reg(hw, FM10K_EICR, eicr & (FM10K_EICR_MAILBOX | | |
245 | FM10K_EICR_SWITCHREADY | | |
246 | FM10K_EICR_SWITCHNOTREADY)); | |
247 | ||
248 | /* report any faults found to the message log */ | |
249 | fm10k_report_fault(interface, eicr); | |
250 | ||
251 | /* reset any queues disabled due to receiver overrun */ | |
252 | fm10k_reset_drop_on_empty(interface, eicr); | |
253 | ||
254 | /* service mailboxes */ | |
255 | if (fm10k_mbx_trylock(interface)) { | |
256 | mbx->ops.process(hw, mbx); | |
257 | fm10k_mbx_unlock(interface); | |
258 | } | |
259 | ||
260 | /* re-enable mailbox interrupt and indicate 20us delay */ | |
261 | fm10k_write_reg(hw, FM10K_ITR(FM10K_MBX_VECTOR), | |
262 | FM10K_ITR_ENABLE | FM10K_MBX_INT_DELAY); | |
263 | ||
264 | return IRQ_HANDLED; | |
265 | } | |
266 | ||
267 | void fm10k_mbx_free_irq(struct fm10k_intfc *interface) | |
268 | { | |
269 | struct msix_entry *entry = &interface->msix_entries[FM10K_MBX_VECTOR]; | |
270 | struct fm10k_hw *hw = &interface->hw; | |
271 | int itr_reg; | |
272 | ||
273 | /* disconnect the mailbox */ | |
274 | hw->mbx.ops.disconnect(hw, &hw->mbx); | |
275 | ||
276 | /* disable Mailbox cause */ | |
277 | if (hw->mac.type == fm10k_mac_pf) { | |
278 | fm10k_write_reg(hw, FM10K_EIMR, | |
279 | FM10K_EIMR_DISABLE(PCA_FAULT) | | |
280 | FM10K_EIMR_DISABLE(FUM_FAULT) | | |
281 | FM10K_EIMR_DISABLE(MAILBOX) | | |
282 | FM10K_EIMR_DISABLE(SWITCHREADY) | | |
283 | FM10K_EIMR_DISABLE(SWITCHNOTREADY) | | |
284 | FM10K_EIMR_DISABLE(SRAMERROR) | | |
285 | FM10K_EIMR_DISABLE(VFLR) | | |
286 | FM10K_EIMR_DISABLE(MAXHOLDTIME)); | |
287 | itr_reg = FM10K_ITR(FM10K_MBX_VECTOR); | |
288 | } | |
289 | ||
290 | fm10k_write_reg(hw, itr_reg, FM10K_ITR_MASK_SET); | |
291 | ||
292 | free_irq(entry->vector, interface); | |
293 | } | |
294 | ||
295 | /* generic error handler for mailbox issues */ | |
296 | static s32 fm10k_mbx_error(struct fm10k_hw *hw, u32 **results, | |
297 | struct fm10k_mbx_info *mbx) | |
298 | { | |
299 | struct fm10k_intfc *interface; | |
300 | struct pci_dev *pdev; | |
301 | ||
302 | interface = container_of(hw, struct fm10k_intfc, hw); | |
303 | pdev = interface->pdev; | |
304 | ||
305 | dev_err(&pdev->dev, "Unknown message ID %u\n", | |
306 | **results & FM10K_TLV_ID_MASK); | |
307 | ||
308 | return 0; | |
309 | } | |
310 | ||
311 | static s32 fm10k_lport_map(struct fm10k_hw *hw, u32 **results, | |
312 | struct fm10k_mbx_info *mbx) | |
313 | { | |
314 | struct fm10k_intfc *interface; | |
315 | u32 dglort_map = hw->mac.dglort_map; | |
316 | s32 err; | |
317 | ||
318 | err = fm10k_msg_lport_map_pf(hw, results, mbx); | |
319 | if (err) | |
320 | return err; | |
321 | ||
322 | interface = container_of(hw, struct fm10k_intfc, hw); | |
323 | ||
324 | /* we need to reset if port count was just updated */ | |
325 | if (dglort_map != hw->mac.dglort_map) | |
326 | interface->flags |= FM10K_FLAG_RESET_REQUESTED; | |
327 | ||
328 | return 0; | |
329 | } | |
330 | ||
331 | static s32 fm10k_update_pvid(struct fm10k_hw *hw, u32 **results, | |
332 | struct fm10k_mbx_info *mbx) | |
333 | { | |
334 | struct fm10k_intfc *interface; | |
335 | u16 glort, pvid; | |
336 | u32 pvid_update; | |
337 | s32 err; | |
338 | ||
339 | err = fm10k_tlv_attr_get_u32(results[FM10K_PF_ATTR_ID_UPDATE_PVID], | |
340 | &pvid_update); | |
341 | if (err) | |
342 | return err; | |
343 | ||
344 | /* extract values from the pvid update */ | |
345 | glort = FM10K_MSG_HDR_FIELD_GET(pvid_update, UPDATE_PVID_GLORT); | |
346 | pvid = FM10K_MSG_HDR_FIELD_GET(pvid_update, UPDATE_PVID_PVID); | |
347 | ||
348 | /* if glort is not valid return error */ | |
349 | if (!fm10k_glort_valid_pf(hw, glort)) | |
350 | return FM10K_ERR_PARAM; | |
351 | ||
352 | /* verify VID is valid */ | |
353 | if (pvid >= FM10K_VLAN_TABLE_VID_MAX) | |
354 | return FM10K_ERR_PARAM; | |
355 | ||
356 | interface = container_of(hw, struct fm10k_intfc, hw); | |
357 | ||
358 | /* we need to reset if default VLAN was just updated */ | |
359 | if (pvid != hw->mac.default_vid) | |
360 | interface->flags |= FM10K_FLAG_RESET_REQUESTED; | |
361 | ||
362 | hw->mac.default_vid = pvid; | |
363 | ||
364 | return 0; | |
365 | } | |
366 | ||
367 | static const struct fm10k_msg_data pf_mbx_data[] = { | |
368 | FM10K_PF_MSG_ERR_HANDLER(XCAST_MODES, fm10k_msg_err_pf), | |
369 | FM10K_PF_MSG_ERR_HANDLER(UPDATE_MAC_FWD_RULE, fm10k_msg_err_pf), | |
370 | FM10K_PF_MSG_LPORT_MAP_HANDLER(fm10k_lport_map), | |
371 | FM10K_PF_MSG_ERR_HANDLER(LPORT_CREATE, fm10k_msg_err_pf), | |
372 | FM10K_PF_MSG_ERR_HANDLER(LPORT_DELETE, fm10k_msg_err_pf), | |
373 | FM10K_PF_MSG_UPDATE_PVID_HANDLER(fm10k_update_pvid), | |
374 | FM10K_TLV_MSG_ERROR_HANDLER(fm10k_mbx_error), | |
375 | }; | |
376 | ||
377 | static int fm10k_mbx_request_irq_pf(struct fm10k_intfc *interface) | |
378 | { | |
379 | struct msix_entry *entry = &interface->msix_entries[FM10K_MBX_VECTOR]; | |
380 | struct net_device *dev = interface->netdev; | |
381 | struct fm10k_hw *hw = &interface->hw; | |
382 | int err; | |
383 | ||
384 | /* Use timer0 for interrupt moderation on the mailbox */ | |
385 | u32 mbx_itr = FM10K_INT_MAP_TIMER0 | entry->entry; | |
386 | u32 other_itr = FM10K_INT_MAP_IMMEDIATE | entry->entry; | |
387 | ||
388 | /* register mailbox handlers */ | |
389 | err = hw->mbx.ops.register_handlers(&hw->mbx, pf_mbx_data); | |
390 | if (err) | |
391 | return err; | |
392 | ||
393 | /* request the IRQ */ | |
394 | err = request_irq(entry->vector, fm10k_msix_mbx_pf, 0, | |
395 | dev->name, interface); | |
396 | if (err) { | |
397 | netif_err(interface, probe, dev, | |
398 | "request_irq for msix_mbx failed: %d\n", err); | |
399 | return err; | |
400 | } | |
401 | ||
402 | /* Enable interrupts w/ no moderation for "other" interrupts */ | |
403 | fm10k_write_reg(hw, FM10K_INT_MAP(fm10k_int_PCIeFault), other_itr); | |
404 | fm10k_write_reg(hw, FM10K_INT_MAP(fm10k_int_SwitchUpDown), other_itr); | |
405 | fm10k_write_reg(hw, FM10K_INT_MAP(fm10k_int_SRAM), other_itr); | |
406 | fm10k_write_reg(hw, FM10K_INT_MAP(fm10k_int_MaxHoldTime), other_itr); | |
407 | fm10k_write_reg(hw, FM10K_INT_MAP(fm10k_int_VFLR), other_itr); | |
408 | ||
409 | /* Enable interrupts w/ moderation for mailbox */ | |
410 | fm10k_write_reg(hw, FM10K_INT_MAP(fm10k_int_Mailbox), mbx_itr); | |
411 | ||
412 | /* Enable individual interrupt causes */ | |
413 | fm10k_write_reg(hw, FM10K_EIMR, FM10K_EIMR_ENABLE(PCA_FAULT) | | |
414 | FM10K_EIMR_ENABLE(FUM_FAULT) | | |
415 | FM10K_EIMR_ENABLE(MAILBOX) | | |
416 | FM10K_EIMR_ENABLE(SWITCHREADY) | | |
417 | FM10K_EIMR_ENABLE(SWITCHNOTREADY) | | |
418 | FM10K_EIMR_ENABLE(SRAMERROR) | | |
419 | FM10K_EIMR_ENABLE(VFLR) | | |
420 | FM10K_EIMR_ENABLE(MAXHOLDTIME)); | |
421 | ||
422 | /* enable interrupt */ | |
423 | fm10k_write_reg(hw, FM10K_ITR(entry->entry), FM10K_ITR_ENABLE); | |
424 | ||
425 | return 0; | |
426 | } | |
427 | ||
428 | int fm10k_mbx_request_irq(struct fm10k_intfc *interface) | |
429 | { | |
430 | struct fm10k_hw *hw = &interface->hw; | |
431 | int err; | |
432 | ||
433 | /* enable Mailbox cause */ | |
434 | err = fm10k_mbx_request_irq_pf(interface); | |
435 | ||
436 | /* connect mailbox */ | |
437 | if (!err) | |
438 | err = hw->mbx.ops.connect(hw, &hw->mbx); | |
439 | ||
440 | return err; | |
441 | } | |
442 | ||
443 | /** | |
444 | * fm10k_qv_free_irq - release interrupts associated with queue vectors | |
445 | * @interface: board private structure | |
446 | * | |
447 | * Release all interrupts associated with this interface | |
448 | **/ | |
449 | void fm10k_qv_free_irq(struct fm10k_intfc *interface) | |
450 | { | |
451 | int vector = interface->num_q_vectors; | |
452 | struct fm10k_hw *hw = &interface->hw; | |
453 | struct msix_entry *entry; | |
454 | ||
455 | entry = &interface->msix_entries[NON_Q_VECTORS(hw) + vector]; | |
456 | ||
457 | while (vector) { | |
458 | struct fm10k_q_vector *q_vector; | |
459 | ||
460 | vector--; | |
461 | entry--; | |
462 | q_vector = interface->q_vector[vector]; | |
463 | ||
464 | if (!q_vector->tx.count && !q_vector->rx.count) | |
465 | continue; | |
466 | ||
467 | /* disable interrupts */ | |
468 | ||
469 | writel(FM10K_ITR_MASK_SET, q_vector->itr); | |
470 | ||
471 | free_irq(entry->vector, q_vector); | |
472 | } | |
473 | } | |
474 | ||
475 | /** | |
476 | * fm10k_qv_request_irq - initialize interrupts for queue vectors | |
477 | * @interface: board private structure | |
478 | * | |
479 | * Attempts to configure interrupts using the best available | |
480 | * capabilities of the hardware and kernel. | |
481 | **/ | |
482 | int fm10k_qv_request_irq(struct fm10k_intfc *interface) | |
483 | { | |
484 | struct net_device *dev = interface->netdev; | |
485 | struct fm10k_hw *hw = &interface->hw; | |
486 | struct msix_entry *entry; | |
487 | int ri = 0, ti = 0; | |
488 | int vector, err; | |
489 | ||
490 | entry = &interface->msix_entries[NON_Q_VECTORS(hw)]; | |
491 | ||
492 | for (vector = 0; vector < interface->num_q_vectors; vector++) { | |
493 | struct fm10k_q_vector *q_vector = interface->q_vector[vector]; | |
494 | ||
495 | /* name the vector */ | |
496 | if (q_vector->tx.count && q_vector->rx.count) { | |
497 | snprintf(q_vector->name, sizeof(q_vector->name) - 1, | |
498 | "%s-TxRx-%d", dev->name, ri++); | |
499 | ti++; | |
500 | } else if (q_vector->rx.count) { | |
501 | snprintf(q_vector->name, sizeof(q_vector->name) - 1, | |
502 | "%s-rx-%d", dev->name, ri++); | |
503 | } else if (q_vector->tx.count) { | |
504 | snprintf(q_vector->name, sizeof(q_vector->name) - 1, | |
505 | "%s-tx-%d", dev->name, ti++); | |
506 | } else { | |
507 | /* skip this unused q_vector */ | |
508 | continue; | |
509 | } | |
510 | ||
511 | /* Assign ITR register to q_vector */ | |
512 | q_vector->itr = &interface->uc_addr[FM10K_ITR(entry->entry)]; | |
513 | ||
514 | /* request the IRQ */ | |
515 | err = request_irq(entry->vector, &fm10k_msix_clean_rings, 0, | |
516 | q_vector->name, q_vector); | |
517 | if (err) { | |
518 | netif_err(interface, probe, dev, | |
519 | "request_irq failed for MSIX interrupt Error: %d\n", | |
520 | err); | |
521 | goto err_out; | |
522 | } | |
523 | ||
524 | /* Enable q_vector */ | |
525 | writel(FM10K_ITR_ENABLE, q_vector->itr); | |
526 | ||
527 | entry++; | |
528 | } | |
529 | ||
530 | return 0; | |
531 | ||
532 | err_out: | |
533 | /* wind through the ring freeing all entries and vectors */ | |
534 | while (vector) { | |
535 | struct fm10k_q_vector *q_vector; | |
536 | ||
537 | entry--; | |
538 | vector--; | |
539 | q_vector = interface->q_vector[vector]; | |
540 | ||
541 | if (!q_vector->tx.count && !q_vector->rx.count) | |
542 | continue; | |
543 | ||
544 | /* disable interrupts */ | |
545 | ||
546 | writel(FM10K_ITR_MASK_SET, q_vector->itr); | |
547 | ||
548 | free_irq(entry->vector, q_vector); | |
549 | } | |
550 | ||
551 | return err; | |
552 | } | |
553 | ||
504c5eac AD |
554 | void fm10k_up(struct fm10k_intfc *interface) |
555 | { | |
556 | struct fm10k_hw *hw = &interface->hw; | |
557 | ||
558 | /* Enable Tx/Rx DMA */ | |
559 | hw->mac.ops.start_hw(hw); | |
560 | ||
561 | /* configure interrupts */ | |
562 | hw->mac.ops.update_int_moderator(hw); | |
563 | ||
564 | /* clear down bit to indicate we are ready to go */ | |
565 | clear_bit(__FM10K_DOWN, &interface->state); | |
566 | ||
18283cad AD |
567 | /* enable polling cleanups */ |
568 | fm10k_napi_enable_all(interface); | |
569 | ||
504c5eac AD |
570 | /* re-establish Rx filters */ |
571 | fm10k_restore_rx_state(interface); | |
572 | ||
573 | /* enable transmits */ | |
574 | netif_tx_start_all_queues(interface->netdev); | |
575 | } | |
576 | ||
18283cad AD |
577 | static void fm10k_napi_disable_all(struct fm10k_intfc *interface) |
578 | { | |
579 | struct fm10k_q_vector *q_vector; | |
580 | int q_idx; | |
581 | ||
582 | for (q_idx = 0; q_idx < interface->num_q_vectors; q_idx++) { | |
583 | q_vector = interface->q_vector[q_idx]; | |
584 | napi_disable(&q_vector->napi); | |
585 | } | |
586 | } | |
587 | ||
504c5eac AD |
588 | void fm10k_down(struct fm10k_intfc *interface) |
589 | { | |
590 | struct net_device *netdev = interface->netdev; | |
591 | struct fm10k_hw *hw = &interface->hw; | |
592 | ||
593 | /* signal that we are down to the interrupt handler and service task */ | |
594 | set_bit(__FM10K_DOWN, &interface->state); | |
595 | ||
596 | /* call carrier off first to avoid false dev_watchdog timeouts */ | |
597 | netif_carrier_off(netdev); | |
598 | ||
599 | /* disable transmits */ | |
600 | netif_tx_stop_all_queues(netdev); | |
601 | netif_tx_disable(netdev); | |
602 | ||
603 | /* reset Rx filters */ | |
604 | fm10k_reset_rx_state(interface); | |
605 | ||
606 | /* allow 10ms for device to quiesce */ | |
607 | usleep_range(10000, 20000); | |
608 | ||
18283cad AD |
609 | /* disable polling routines */ |
610 | fm10k_napi_disable_all(interface); | |
611 | ||
504c5eac AD |
612 | /* Disable DMA engine for Tx/Rx */ |
613 | hw->mac.ops.stop_hw(hw); | |
614 | } | |
615 | ||
0e7b3644 AD |
616 | /** |
617 | * fm10k_sw_init - Initialize general software structures | |
618 | * @interface: host interface private structure to initialize | |
619 | * | |
620 | * fm10k_sw_init initializes the interface private data structure. | |
621 | * Fields are initialized based on PCI device information and | |
622 | * OS network device settings (MTU size). | |
623 | **/ | |
624 | static int fm10k_sw_init(struct fm10k_intfc *interface, | |
625 | const struct pci_device_id *ent) | |
626 | { | |
627 | static const u32 seed[FM10K_RSSRK_SIZE] = { 0xda565a6d, 0xc20e5b25, | |
628 | 0x3d256741, 0xb08fa343, | |
629 | 0xcb2bcad0, 0xb4307bae, | |
630 | 0xa32dcb77, 0x0cf23080, | |
631 | 0x3bb7426a, 0xfa01acbe }; | |
632 | const struct fm10k_info *fi = fm10k_info_tbl[ent->driver_data]; | |
633 | struct fm10k_hw *hw = &interface->hw; | |
634 | struct pci_dev *pdev = interface->pdev; | |
635 | struct net_device *netdev = interface->netdev; | |
636 | unsigned int rss; | |
637 | int err; | |
638 | ||
639 | /* initialize back pointer */ | |
640 | hw->back = interface; | |
641 | hw->hw_addr = interface->uc_addr; | |
642 | ||
643 | /* PCI config space info */ | |
644 | hw->vendor_id = pdev->vendor; | |
645 | hw->device_id = pdev->device; | |
646 | hw->revision_id = pdev->revision; | |
647 | hw->subsystem_vendor_id = pdev->subsystem_vendor; | |
648 | hw->subsystem_device_id = pdev->subsystem_device; | |
649 | ||
650 | /* Setup hw api */ | |
651 | memcpy(&hw->mac.ops, fi->mac_ops, sizeof(hw->mac.ops)); | |
652 | hw->mac.type = fi->mac; | |
653 | ||
654 | /* Set common capability flags and settings */ | |
655 | rss = min_t(int, FM10K_MAX_RSS_INDICES, num_online_cpus()); | |
656 | interface->ring_feature[RING_F_RSS].limit = rss; | |
657 | fi->get_invariants(hw); | |
658 | ||
659 | /* pick up the PCIe bus settings for reporting later */ | |
660 | if (hw->mac.ops.get_bus_info) | |
661 | hw->mac.ops.get_bus_info(hw); | |
662 | ||
663 | /* limit the usable DMA range */ | |
664 | if (hw->mac.ops.set_dma_mask) | |
665 | hw->mac.ops.set_dma_mask(hw, dma_get_mask(&pdev->dev)); | |
666 | ||
667 | /* update netdev with DMA restrictions */ | |
668 | if (dma_get_mask(&pdev->dev) > DMA_BIT_MASK(32)) { | |
669 | netdev->features |= NETIF_F_HIGHDMA; | |
670 | netdev->vlan_features |= NETIF_F_HIGHDMA; | |
671 | } | |
672 | ||
673 | /* reset and initialize the hardware so it is in a known state */ | |
674 | err = hw->mac.ops.reset_hw(hw) ? : hw->mac.ops.init_hw(hw); | |
675 | if (err) { | |
676 | dev_err(&pdev->dev, "init_hw failed: %d\n", err); | |
677 | return err; | |
678 | } | |
679 | ||
680 | /* initialize hardware statistics */ | |
681 | hw->mac.ops.update_hw_stats(hw, &interface->stats); | |
682 | ||
683 | /* Start with random Ethernet address */ | |
684 | eth_random_addr(hw->mac.addr); | |
685 | ||
686 | /* Initialize MAC address from hardware */ | |
687 | err = hw->mac.ops.read_mac_addr(hw); | |
688 | if (err) { | |
689 | dev_warn(&pdev->dev, | |
690 | "Failed to obtain MAC address defaulting to random\n"); | |
691 | /* tag address assignment as random */ | |
692 | netdev->addr_assign_type |= NET_ADDR_RANDOM; | |
693 | } | |
694 | ||
695 | memcpy(netdev->dev_addr, hw->mac.addr, netdev->addr_len); | |
696 | memcpy(netdev->perm_addr, hw->mac.addr, netdev->addr_len); | |
697 | ||
698 | if (!is_valid_ether_addr(netdev->perm_addr)) { | |
699 | dev_err(&pdev->dev, "Invalid MAC Address\n"); | |
700 | return -EIO; | |
701 | } | |
702 | ||
703 | /* Only the PF can support VXLAN and NVGRE offloads */ | |
704 | if (hw->mac.type != fm10k_mac_pf) { | |
705 | netdev->hw_enc_features = 0; | |
706 | netdev->features &= ~NETIF_F_GSO_UDP_TUNNEL; | |
707 | netdev->hw_features &= ~NETIF_F_GSO_UDP_TUNNEL; | |
708 | } | |
709 | ||
18283cad AD |
710 | /* set default interrupt moderation */ |
711 | interface->tx_itr = FM10K_ITR_10K; | |
712 | interface->rx_itr = FM10K_ITR_ADAPTIVE | FM10K_ITR_20K; | |
713 | ||
0e7b3644 AD |
714 | /* initialize vxlan_port list */ |
715 | INIT_LIST_HEAD(&interface->vxlan_port); | |
716 | ||
717 | /* initialize RSS key */ | |
718 | memcpy(interface->rssrk, seed, sizeof(seed)); | |
719 | ||
720 | /* Start off interface as being down */ | |
721 | set_bit(__FM10K_DOWN, &interface->state); | |
722 | ||
723 | return 0; | |
724 | } | |
725 | ||
726 | static void fm10k_slot_warn(struct fm10k_intfc *interface) | |
727 | { | |
728 | struct device *dev = &interface->pdev->dev; | |
729 | struct fm10k_hw *hw = &interface->hw; | |
730 | ||
731 | if (hw->mac.ops.is_slot_appropriate(hw)) | |
732 | return; | |
733 | ||
734 | dev_warn(dev, | |
735 | "For optimal performance, a %s %s slot is recommended.\n", | |
736 | (hw->bus_caps.width == fm10k_bus_width_pcie_x1 ? "x1" : | |
737 | hw->bus_caps.width == fm10k_bus_width_pcie_x4 ? "x4" : | |
738 | "x8"), | |
739 | (hw->bus_caps.speed == fm10k_bus_speed_2500 ? "2.5GT/s" : | |
740 | hw->bus_caps.speed == fm10k_bus_speed_5000 ? "5.0GT/s" : | |
741 | "8.0GT/s")); | |
742 | dev_warn(dev, | |
743 | "A slot with more lanes and/or higher speed is suggested.\n"); | |
744 | } | |
745 | ||
b3890e30 AD |
746 | /** |
747 | * fm10k_probe - Device Initialization Routine | |
748 | * @pdev: PCI device information struct | |
749 | * @ent: entry in fm10k_pci_tbl | |
750 | * | |
751 | * Returns 0 on success, negative on failure | |
752 | * | |
753 | * fm10k_probe initializes an interface identified by a pci_dev structure. | |
754 | * The OS initialization, configuring of the interface private structure, | |
755 | * and a hardware reset occur. | |
756 | **/ | |
757 | static int fm10k_probe(struct pci_dev *pdev, | |
758 | const struct pci_device_id *ent) | |
759 | { | |
0e7b3644 AD |
760 | struct net_device *netdev; |
761 | struct fm10k_intfc *interface; | |
762 | struct fm10k_hw *hw; | |
b3890e30 AD |
763 | int err; |
764 | u64 dma_mask; | |
765 | ||
766 | err = pci_enable_device_mem(pdev); | |
767 | if (err) | |
768 | return err; | |
769 | ||
770 | /* By default fm10k only supports a 48 bit DMA mask */ | |
771 | dma_mask = DMA_BIT_MASK(48) | dma_get_required_mask(&pdev->dev); | |
772 | ||
773 | if ((dma_mask <= DMA_BIT_MASK(32)) || | |
774 | dma_set_mask_and_coherent(&pdev->dev, dma_mask)) { | |
775 | dma_mask &= DMA_BIT_MASK(32); | |
776 | ||
777 | err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); | |
778 | err = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32)); | |
779 | if (err) { | |
780 | err = dma_set_coherent_mask(&pdev->dev, | |
781 | DMA_BIT_MASK(32)); | |
782 | if (err) { | |
783 | dev_err(&pdev->dev, | |
784 | "No usable DMA configuration, aborting\n"); | |
785 | goto err_dma; | |
786 | } | |
787 | } | |
788 | } | |
789 | ||
790 | err = pci_request_selected_regions(pdev, | |
791 | pci_select_bars(pdev, | |
792 | IORESOURCE_MEM), | |
793 | fm10k_driver_name); | |
794 | if (err) { | |
795 | dev_err(&pdev->dev, | |
796 | "pci_request_selected_regions failed 0x%x\n", err); | |
797 | goto err_pci_reg; | |
798 | } | |
799 | ||
800 | pci_set_master(pdev); | |
801 | pci_save_state(pdev); | |
802 | ||
0e7b3644 AD |
803 | netdev = fm10k_alloc_netdev(); |
804 | if (!netdev) { | |
805 | err = -ENOMEM; | |
806 | goto err_alloc_netdev; | |
807 | } | |
808 | ||
809 | SET_NETDEV_DEV(netdev, &pdev->dev); | |
810 | ||
811 | interface = netdev_priv(netdev); | |
812 | pci_set_drvdata(pdev, interface); | |
813 | ||
814 | interface->netdev = netdev; | |
815 | interface->pdev = pdev; | |
816 | hw = &interface->hw; | |
817 | ||
818 | interface->uc_addr = ioremap(pci_resource_start(pdev, 0), | |
819 | FM10K_UC_ADDR_SIZE); | |
820 | if (!interface->uc_addr) { | |
821 | err = -EIO; | |
822 | goto err_ioremap; | |
823 | } | |
824 | ||
825 | err = fm10k_sw_init(interface, ent); | |
826 | if (err) | |
827 | goto err_sw_init; | |
828 | ||
18283cad AD |
829 | err = fm10k_init_queueing_scheme(interface); |
830 | if (err) | |
831 | goto err_sw_init; | |
832 | ||
833 | err = fm10k_mbx_request_irq(interface); | |
834 | if (err) | |
835 | goto err_mbx_interrupt; | |
836 | ||
0e7b3644 AD |
837 | /* final check of hardware state before registering the interface */ |
838 | err = fm10k_hw_ready(interface); | |
839 | if (err) | |
840 | goto err_register; | |
841 | ||
842 | err = register_netdev(netdev); | |
843 | if (err) | |
844 | goto err_register; | |
845 | ||
846 | /* carrier off reporting is important to ethtool even BEFORE open */ | |
847 | netif_carrier_off(netdev); | |
848 | ||
849 | /* stop all the transmit queues from transmitting until link is up */ | |
850 | netif_tx_stop_all_queues(netdev); | |
851 | ||
852 | /* print bus type/speed/width info */ | |
853 | dev_info(&pdev->dev, "(PCI Express:%s Width: %s Payload: %s)\n", | |
854 | (hw->bus.speed == fm10k_bus_speed_8000 ? "8.0GT/s" : | |
855 | hw->bus.speed == fm10k_bus_speed_5000 ? "5.0GT/s" : | |
856 | hw->bus.speed == fm10k_bus_speed_2500 ? "2.5GT/s" : | |
857 | "Unknown"), | |
858 | (hw->bus.width == fm10k_bus_width_pcie_x8 ? "x8" : | |
859 | hw->bus.width == fm10k_bus_width_pcie_x4 ? "x4" : | |
860 | hw->bus.width == fm10k_bus_width_pcie_x1 ? "x1" : | |
861 | "Unknown"), | |
862 | (hw->bus.payload == fm10k_bus_payload_128 ? "128B" : | |
863 | hw->bus.payload == fm10k_bus_payload_256 ? "256B" : | |
864 | hw->bus.payload == fm10k_bus_payload_512 ? "512B" : | |
865 | "Unknown")); | |
866 | ||
867 | /* print warning for non-optimal configurations */ | |
868 | fm10k_slot_warn(interface); | |
869 | ||
b3890e30 AD |
870 | return 0; |
871 | ||
0e7b3644 | 872 | err_register: |
18283cad AD |
873 | fm10k_mbx_free_irq(interface); |
874 | err_mbx_interrupt: | |
875 | fm10k_clear_queueing_scheme(interface); | |
0e7b3644 AD |
876 | err_sw_init: |
877 | iounmap(interface->uc_addr); | |
878 | err_ioremap: | |
879 | free_netdev(netdev); | |
880 | err_alloc_netdev: | |
881 | pci_release_selected_regions(pdev, | |
882 | pci_select_bars(pdev, IORESOURCE_MEM)); | |
b3890e30 AD |
883 | err_pci_reg: |
884 | err_dma: | |
885 | pci_disable_device(pdev); | |
886 | return err; | |
887 | } | |
888 | ||
889 | /** | |
890 | * fm10k_remove - Device Removal Routine | |
891 | * @pdev: PCI device information struct | |
892 | * | |
893 | * fm10k_remove is called by the PCI subsystem to alert the driver | |
894 | * that it should release a PCI device. The could be caused by a | |
895 | * Hot-Plug event, or because the driver is going to be removed from | |
896 | * memory. | |
897 | **/ | |
898 | static void fm10k_remove(struct pci_dev *pdev) | |
899 | { | |
0e7b3644 AD |
900 | struct fm10k_intfc *interface = pci_get_drvdata(pdev); |
901 | struct net_device *netdev = interface->netdev; | |
902 | ||
903 | /* free netdev, this may bounce the interrupts due to setup_tc */ | |
904 | if (netdev->reg_state == NETREG_REGISTERED) | |
905 | unregister_netdev(netdev); | |
906 | ||
18283cad AD |
907 | /* disable mailbox interrupt */ |
908 | fm10k_mbx_free_irq(interface); | |
909 | ||
910 | /* free interrupts */ | |
911 | fm10k_clear_queueing_scheme(interface); | |
912 | ||
0e7b3644 AD |
913 | iounmap(interface->uc_addr); |
914 | ||
915 | free_netdev(netdev); | |
916 | ||
b3890e30 AD |
917 | pci_release_selected_regions(pdev, |
918 | pci_select_bars(pdev, IORESOURCE_MEM)); | |
919 | ||
920 | pci_disable_device(pdev); | |
921 | } | |
922 | ||
923 | static struct pci_driver fm10k_driver = { | |
924 | .name = fm10k_driver_name, | |
925 | .id_table = fm10k_pci_tbl, | |
926 | .probe = fm10k_probe, | |
927 | .remove = fm10k_remove, | |
928 | }; | |
929 | ||
930 | /** | |
931 | * fm10k_register_pci_driver - register driver interface | |
932 | * | |
933 | * This funciton is called on module load in order to register the driver. | |
934 | **/ | |
935 | int fm10k_register_pci_driver(void) | |
936 | { | |
937 | return pci_register_driver(&fm10k_driver); | |
938 | } | |
939 | ||
940 | /** | |
941 | * fm10k_unregister_pci_driver - unregister driver interface | |
942 | * | |
943 | * This funciton is called on module unload in order to remove the driver. | |
944 | **/ | |
945 | void fm10k_unregister_pci_driver(void) | |
946 | { | |
947 | pci_unregister_driver(&fm10k_driver); | |
948 | } |