diff options
Diffstat (limited to 'drivers/net/qlcnic/qlcnic_main.c')
-rw-r--r-- | drivers/net/qlcnic/qlcnic_main.c | 2720 |
1 files changed, 2720 insertions, 0 deletions
diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c new file mode 100644 index 00000000000..665e8e56b6a --- /dev/null +++ b/drivers/net/qlcnic/qlcnic_main.c | |||
@@ -0,0 +1,2720 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2009 - QLogic Corporation. | ||
3 | * All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU General Public License | ||
7 | * as published by the Free Software Foundation; either version 2 | ||
8 | * of the License, or (at your option) any later version. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, but | ||
11 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program; if not, write to the Free Software | ||
17 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, | ||
18 | * MA 02111-1307, USA. | ||
19 | * | ||
20 | * The full GNU General Public License is included in this distribution | ||
21 | * in the file called "COPYING". | ||
22 | * | ||
23 | */ | ||
24 | |||
25 | #include <linux/vmalloc.h> | ||
26 | #include <linux/interrupt.h> | ||
27 | |||
28 | #include "qlcnic.h" | ||
29 | |||
30 | #include <linux/dma-mapping.h> | ||
31 | #include <linux/if_vlan.h> | ||
32 | #include <net/ip.h> | ||
33 | #include <linux/ipv6.h> | ||
34 | #include <linux/inetdevice.h> | ||
35 | #include <linux/sysfs.h> | ||
36 | |||
37 | MODULE_DESCRIPTION("QLogic 10 GbE Converged Ethernet Driver"); | ||
38 | MODULE_LICENSE("GPL"); | ||
39 | MODULE_VERSION(QLCNIC_LINUX_VERSIONID); | ||
40 | MODULE_FIRMWARE(QLCNIC_UNIFIED_ROMIMAGE_NAME); | ||
41 | |||
42 | char qlcnic_driver_name[] = "qlcnic"; | ||
43 | static const char qlcnic_driver_string[] = "QLogic Converged Ethernet Driver v" | ||
44 | QLCNIC_LINUX_VERSIONID; | ||
45 | |||
46 | static int port_mode = QLCNIC_PORT_MODE_AUTO_NEG; | ||
47 | |||
48 | /* Default to restricted 1G auto-neg mode */ | ||
49 | static int wol_port_mode = 5; | ||
50 | |||
51 | static int use_msi = 1; | ||
52 | module_param(use_msi, int, 0644); | ||
53 | MODULE_PARM_DESC(use_msi, "MSI interrupt (0=disabled, 1=enabled"); | ||
54 | |||
55 | static int use_msi_x = 1; | ||
56 | module_param(use_msi_x, int, 0644); | ||
57 | MODULE_PARM_DESC(use_msi_x, "MSI-X interrupt (0=disabled, 1=enabled"); | ||
58 | |||
59 | static int auto_fw_reset = AUTO_FW_RESET_ENABLED; | ||
60 | module_param(auto_fw_reset, int, 0644); | ||
61 | MODULE_PARM_DESC(auto_fw_reset, "Auto firmware reset (0=disabled, 1=enabled"); | ||
62 | |||
63 | static int __devinit qlcnic_probe(struct pci_dev *pdev, | ||
64 | const struct pci_device_id *ent); | ||
65 | static void __devexit qlcnic_remove(struct pci_dev *pdev); | ||
66 | static int qlcnic_open(struct net_device *netdev); | ||
67 | static int qlcnic_close(struct net_device *netdev); | ||
68 | static void qlcnic_tx_timeout(struct net_device *netdev); | ||
69 | static void qlcnic_tx_timeout_task(struct work_struct *work); | ||
70 | static void qlcnic_attach_work(struct work_struct *work); | ||
71 | static void qlcnic_fwinit_work(struct work_struct *work); | ||
72 | static void qlcnic_fw_poll_work(struct work_struct *work); | ||
73 | static void qlcnic_schedule_work(struct qlcnic_adapter *adapter, | ||
74 | work_func_t func, int delay); | ||
75 | static void qlcnic_cancel_fw_work(struct qlcnic_adapter *adapter); | ||
76 | static int qlcnic_poll(struct napi_struct *napi, int budget); | ||
77 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
78 | static void qlcnic_poll_controller(struct net_device *netdev); | ||
79 | #endif | ||
80 | |||
81 | static void qlcnic_create_sysfs_entries(struct qlcnic_adapter *adapter); | ||
82 | static void qlcnic_remove_sysfs_entries(struct qlcnic_adapter *adapter); | ||
83 | static void qlcnic_create_diag_entries(struct qlcnic_adapter *adapter); | ||
84 | static void qlcnic_remove_diag_entries(struct qlcnic_adapter *adapter); | ||
85 | |||
86 | static void qlcnic_clr_all_drv_state(struct qlcnic_adapter *adapter); | ||
87 | static int qlcnic_can_start_firmware(struct qlcnic_adapter *adapter); | ||
88 | |||
89 | static irqreturn_t qlcnic_tmp_intr(int irq, void *data); | ||
90 | static irqreturn_t qlcnic_intr(int irq, void *data); | ||
91 | static irqreturn_t qlcnic_msi_intr(int irq, void *data); | ||
92 | static irqreturn_t qlcnic_msix_intr(int irq, void *data); | ||
93 | |||
94 | static struct net_device_stats *qlcnic_get_stats(struct net_device *netdev); | ||
95 | static void qlcnic_config_indev_addr(struct net_device *dev, unsigned long); | ||
96 | |||
97 | /* PCI Device ID Table */ | ||
98 | #define ENTRY(device) \ | ||
99 | {PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, (device)), \ | ||
100 | .class = PCI_CLASS_NETWORK_ETHERNET << 8, .class_mask = ~0} | ||
101 | |||
102 | #define PCI_DEVICE_ID_QLOGIC_QLE824X 0x8020 | ||
103 | |||
104 | static DEFINE_PCI_DEVICE_TABLE(qlcnic_pci_tbl) = { | ||
105 | ENTRY(PCI_DEVICE_ID_QLOGIC_QLE824X), | ||
106 | {0,} | ||
107 | }; | ||
108 | |||
109 | MODULE_DEVICE_TABLE(pci, qlcnic_pci_tbl); | ||
110 | |||
111 | |||
112 | void | ||
113 | qlcnic_update_cmd_producer(struct qlcnic_adapter *adapter, | ||
114 | struct qlcnic_host_tx_ring *tx_ring) | ||
115 | { | ||
116 | writel(tx_ring->producer, tx_ring->crb_cmd_producer); | ||
117 | |||
118 | if (qlcnic_tx_avail(tx_ring) <= TX_STOP_THRESH) { | ||
119 | netif_stop_queue(adapter->netdev); | ||
120 | smp_mb(); | ||
121 | } | ||
122 | } | ||
123 | |||
124 | static const u32 msi_tgt_status[8] = { | ||
125 | ISR_INT_TARGET_STATUS, ISR_INT_TARGET_STATUS_F1, | ||
126 | ISR_INT_TARGET_STATUS_F2, ISR_INT_TARGET_STATUS_F3, | ||
127 | ISR_INT_TARGET_STATUS_F4, ISR_INT_TARGET_STATUS_F5, | ||
128 | ISR_INT_TARGET_STATUS_F6, ISR_INT_TARGET_STATUS_F7 | ||
129 | }; | ||
130 | |||
131 | static const | ||
132 | struct qlcnic_legacy_intr_set legacy_intr[] = QLCNIC_LEGACY_INTR_CONFIG; | ||
133 | |||
134 | static inline void qlcnic_disable_int(struct qlcnic_host_sds_ring *sds_ring) | ||
135 | { | ||
136 | writel(0, sds_ring->crb_intr_mask); | ||
137 | } | ||
138 | |||
139 | static inline void qlcnic_enable_int(struct qlcnic_host_sds_ring *sds_ring) | ||
140 | { | ||
141 | struct qlcnic_adapter *adapter = sds_ring->adapter; | ||
142 | |||
143 | writel(0x1, sds_ring->crb_intr_mask); | ||
144 | |||
145 | if (!QLCNIC_IS_MSI_FAMILY(adapter)) | ||
146 | writel(0xfbff, adapter->tgt_mask_reg); | ||
147 | } | ||
148 | |||
149 | static int | ||
150 | qlcnic_alloc_sds_rings(struct qlcnic_recv_context *recv_ctx, int count) | ||
151 | { | ||
152 | int size = sizeof(struct qlcnic_host_sds_ring) * count; | ||
153 | |||
154 | recv_ctx->sds_rings = kzalloc(size, GFP_KERNEL); | ||
155 | |||
156 | return (recv_ctx->sds_rings == NULL); | ||
157 | } | ||
158 | |||
159 | static void | ||
160 | qlcnic_free_sds_rings(struct qlcnic_recv_context *recv_ctx) | ||
161 | { | ||
162 | if (recv_ctx->sds_rings != NULL) | ||
163 | kfree(recv_ctx->sds_rings); | ||
164 | |||
165 | recv_ctx->sds_rings = NULL; | ||
166 | } | ||
167 | |||
168 | static int | ||
169 | qlcnic_napi_add(struct qlcnic_adapter *adapter, struct net_device *netdev) | ||
170 | { | ||
171 | int ring; | ||
172 | struct qlcnic_host_sds_ring *sds_ring; | ||
173 | struct qlcnic_recv_context *recv_ctx = &adapter->recv_ctx; | ||
174 | |||
175 | if (qlcnic_alloc_sds_rings(recv_ctx, adapter->max_sds_rings)) | ||
176 | return -ENOMEM; | ||
177 | |||
178 | for (ring = 0; ring < adapter->max_sds_rings; ring++) { | ||
179 | sds_ring = &recv_ctx->sds_rings[ring]; | ||
180 | netif_napi_add(netdev, &sds_ring->napi, | ||
181 | qlcnic_poll, QLCNIC_NETDEV_WEIGHT); | ||
182 | } | ||
183 | |||
184 | return 0; | ||
185 | } | ||
186 | |||
187 | static void | ||
188 | qlcnic_napi_del(struct qlcnic_adapter *adapter) | ||
189 | { | ||
190 | int ring; | ||
191 | struct qlcnic_host_sds_ring *sds_ring; | ||
192 | struct qlcnic_recv_context *recv_ctx = &adapter->recv_ctx; | ||
193 | |||
194 | for (ring = 0; ring < adapter->max_sds_rings; ring++) { | ||
195 | sds_ring = &recv_ctx->sds_rings[ring]; | ||
196 | netif_napi_del(&sds_ring->napi); | ||
197 | } | ||
198 | |||
199 | qlcnic_free_sds_rings(&adapter->recv_ctx); | ||
200 | } | ||
201 | |||
202 | static void | ||
203 | qlcnic_napi_enable(struct qlcnic_adapter *adapter) | ||
204 | { | ||
205 | int ring; | ||
206 | struct qlcnic_host_sds_ring *sds_ring; | ||
207 | struct qlcnic_recv_context *recv_ctx = &adapter->recv_ctx; | ||
208 | |||
209 | for (ring = 0; ring < adapter->max_sds_rings; ring++) { | ||
210 | sds_ring = &recv_ctx->sds_rings[ring]; | ||
211 | napi_enable(&sds_ring->napi); | ||
212 | qlcnic_enable_int(sds_ring); | ||
213 | } | ||
214 | } | ||
215 | |||
216 | static void | ||
217 | qlcnic_napi_disable(struct qlcnic_adapter *adapter) | ||
218 | { | ||
219 | int ring; | ||
220 | struct qlcnic_host_sds_ring *sds_ring; | ||
221 | struct qlcnic_recv_context *recv_ctx = &adapter->recv_ctx; | ||
222 | |||
223 | for (ring = 0; ring < adapter->max_sds_rings; ring++) { | ||
224 | sds_ring = &recv_ctx->sds_rings[ring]; | ||
225 | qlcnic_disable_int(sds_ring); | ||
226 | napi_synchronize(&sds_ring->napi); | ||
227 | napi_disable(&sds_ring->napi); | ||
228 | } | ||
229 | } | ||
230 | |||
231 | static void qlcnic_clear_stats(struct qlcnic_adapter *adapter) | ||
232 | { | ||
233 | memset(&adapter->stats, 0, sizeof(adapter->stats)); | ||
234 | return; | ||
235 | } | ||
236 | |||
237 | static int qlcnic_set_dma_mask(struct qlcnic_adapter *adapter) | ||
238 | { | ||
239 | struct pci_dev *pdev = adapter->pdev; | ||
240 | u64 mask, cmask; | ||
241 | |||
242 | adapter->pci_using_dac = 0; | ||
243 | |||
244 | mask = DMA_BIT_MASK(39); | ||
245 | cmask = mask; | ||
246 | |||
247 | if (pci_set_dma_mask(pdev, mask) == 0 && | ||
248 | pci_set_consistent_dma_mask(pdev, cmask) == 0) { | ||
249 | adapter->pci_using_dac = 1; | ||
250 | return 0; | ||
251 | } | ||
252 | |||
253 | return -EIO; | ||
254 | } | ||
255 | |||
256 | /* Update addressable range if firmware supports it */ | ||
257 | static int | ||
258 | qlcnic_update_dma_mask(struct qlcnic_adapter *adapter) | ||
259 | { | ||
260 | int change, shift, err; | ||
261 | u64 mask, old_mask, old_cmask; | ||
262 | struct pci_dev *pdev = adapter->pdev; | ||
263 | |||
264 | change = 0; | ||
265 | |||
266 | shift = QLCRD32(adapter, CRB_DMA_SHIFT); | ||
267 | if (shift > 32) | ||
268 | return 0; | ||
269 | |||
270 | if (shift > 9) | ||
271 | change = 1; | ||
272 | |||
273 | if (change) { | ||
274 | old_mask = pdev->dma_mask; | ||
275 | old_cmask = pdev->dev.coherent_dma_mask; | ||
276 | |||
277 | mask = DMA_BIT_MASK(32+shift); | ||
278 | |||
279 | err = pci_set_dma_mask(pdev, mask); | ||
280 | if (err) | ||
281 | goto err_out; | ||
282 | |||
283 | err = pci_set_consistent_dma_mask(pdev, mask); | ||
284 | if (err) | ||
285 | goto err_out; | ||
286 | dev_info(&pdev->dev, "using %d-bit dma mask\n", 32+shift); | ||
287 | } | ||
288 | |||
289 | return 0; | ||
290 | |||
291 | err_out: | ||
292 | pci_set_dma_mask(pdev, old_mask); | ||
293 | pci_set_consistent_dma_mask(pdev, old_cmask); | ||
294 | return err; | ||
295 | } | ||
296 | |||
297 | static void qlcnic_set_port_mode(struct qlcnic_adapter *adapter) | ||
298 | { | ||
299 | u32 val, data; | ||
300 | |||
301 | val = adapter->ahw.board_type; | ||
302 | if ((val == QLCNIC_BRDTYPE_P3_HMEZ) || | ||
303 | (val == QLCNIC_BRDTYPE_P3_XG_LOM)) { | ||
304 | if (port_mode == QLCNIC_PORT_MODE_802_3_AP) { | ||
305 | data = QLCNIC_PORT_MODE_802_3_AP; | ||
306 | QLCWR32(adapter, QLCNIC_PORT_MODE_ADDR, data); | ||
307 | } else if (port_mode == QLCNIC_PORT_MODE_XG) { | ||
308 | data = QLCNIC_PORT_MODE_XG; | ||
309 | QLCWR32(adapter, QLCNIC_PORT_MODE_ADDR, data); | ||
310 | } else if (port_mode == QLCNIC_PORT_MODE_AUTO_NEG_1G) { | ||
311 | data = QLCNIC_PORT_MODE_AUTO_NEG_1G; | ||
312 | QLCWR32(adapter, QLCNIC_PORT_MODE_ADDR, data); | ||
313 | } else if (port_mode == QLCNIC_PORT_MODE_AUTO_NEG_XG) { | ||
314 | data = QLCNIC_PORT_MODE_AUTO_NEG_XG; | ||
315 | QLCWR32(adapter, QLCNIC_PORT_MODE_ADDR, data); | ||
316 | } else { | ||
317 | data = QLCNIC_PORT_MODE_AUTO_NEG; | ||
318 | QLCWR32(adapter, QLCNIC_PORT_MODE_ADDR, data); | ||
319 | } | ||
320 | |||
321 | if ((wol_port_mode != QLCNIC_PORT_MODE_802_3_AP) && | ||
322 | (wol_port_mode != QLCNIC_PORT_MODE_XG) && | ||
323 | (wol_port_mode != QLCNIC_PORT_MODE_AUTO_NEG_1G) && | ||
324 | (wol_port_mode != QLCNIC_PORT_MODE_AUTO_NEG_XG)) { | ||
325 | wol_port_mode = QLCNIC_PORT_MODE_AUTO_NEG; | ||
326 | } | ||
327 | QLCWR32(adapter, QLCNIC_WOL_PORT_MODE, wol_port_mode); | ||
328 | } | ||
329 | } | ||
330 | |||
331 | static void qlcnic_set_msix_bit(struct pci_dev *pdev, int enable) | ||
332 | { | ||
333 | u32 control; | ||
334 | int pos; | ||
335 | |||
336 | pos = pci_find_capability(pdev, PCI_CAP_ID_MSIX); | ||
337 | if (pos) { | ||
338 | pci_read_config_dword(pdev, pos, &control); | ||
339 | if (enable) | ||
340 | control |= PCI_MSIX_FLAGS_ENABLE; | ||
341 | else | ||
342 | control = 0; | ||
343 | pci_write_config_dword(pdev, pos, control); | ||
344 | } | ||
345 | } | ||
346 | |||
347 | static void qlcnic_init_msix_entries(struct qlcnic_adapter *adapter, int count) | ||
348 | { | ||
349 | int i; | ||
350 | |||
351 | for (i = 0; i < count; i++) | ||
352 | adapter->msix_entries[i].entry = i; | ||
353 | } | ||
354 | |||
355 | static int | ||
356 | qlcnic_read_mac_addr(struct qlcnic_adapter *adapter) | ||
357 | { | ||
358 | int i; | ||
359 | unsigned char *p; | ||
360 | u64 mac_addr; | ||
361 | struct net_device *netdev = adapter->netdev; | ||
362 | struct pci_dev *pdev = adapter->pdev; | ||
363 | |||
364 | if (qlcnic_get_mac_addr(adapter, &mac_addr) != 0) | ||
365 | return -EIO; | ||
366 | |||
367 | p = (unsigned char *)&mac_addr; | ||
368 | for (i = 0; i < 6; i++) | ||
369 | netdev->dev_addr[i] = *(p + 5 - i); | ||
370 | |||
371 | memcpy(netdev->perm_addr, netdev->dev_addr, netdev->addr_len); | ||
372 | memcpy(adapter->mac_addr, netdev->dev_addr, netdev->addr_len); | ||
373 | |||
374 | /* set station address */ | ||
375 | |||
376 | if (!is_valid_ether_addr(netdev->perm_addr)) | ||
377 | dev_warn(&pdev->dev, "Bad MAC address %pM.\n", | ||
378 | netdev->dev_addr); | ||
379 | |||
380 | return 0; | ||
381 | } | ||
382 | |||
383 | static int qlcnic_set_mac(struct net_device *netdev, void *p) | ||
384 | { | ||
385 | struct qlcnic_adapter *adapter = netdev_priv(netdev); | ||
386 | struct sockaddr *addr = p; | ||
387 | |||
388 | if (!is_valid_ether_addr(addr->sa_data)) | ||
389 | return -EINVAL; | ||
390 | |||
391 | if (netif_running(netdev)) { | ||
392 | netif_device_detach(netdev); | ||
393 | qlcnic_napi_disable(adapter); | ||
394 | } | ||
395 | |||
396 | memcpy(adapter->mac_addr, addr->sa_data, netdev->addr_len); | ||
397 | memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len); | ||
398 | qlcnic_set_multi(adapter->netdev); | ||
399 | |||
400 | if (netif_running(netdev)) { | ||
401 | netif_device_attach(netdev); | ||
402 | qlcnic_napi_enable(adapter); | ||
403 | } | ||
404 | return 0; | ||
405 | } | ||
406 | |||
407 | static const struct net_device_ops qlcnic_netdev_ops = { | ||
408 | .ndo_open = qlcnic_open, | ||
409 | .ndo_stop = qlcnic_close, | ||
410 | .ndo_start_xmit = qlcnic_xmit_frame, | ||
411 | .ndo_get_stats = qlcnic_get_stats, | ||
412 | .ndo_validate_addr = eth_validate_addr, | ||
413 | .ndo_set_multicast_list = qlcnic_set_multi, | ||
414 | .ndo_set_mac_address = qlcnic_set_mac, | ||
415 | .ndo_change_mtu = qlcnic_change_mtu, | ||
416 | .ndo_tx_timeout = qlcnic_tx_timeout, | ||
417 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
418 | .ndo_poll_controller = qlcnic_poll_controller, | ||
419 | #endif | ||
420 | }; | ||
421 | |||
422 | static void | ||
423 | qlcnic_setup_intr(struct qlcnic_adapter *adapter) | ||
424 | { | ||
425 | const struct qlcnic_legacy_intr_set *legacy_intrp; | ||
426 | struct pci_dev *pdev = adapter->pdev; | ||
427 | int err, num_msix; | ||
428 | |||
429 | if (adapter->rss_supported) { | ||
430 | num_msix = (num_online_cpus() >= MSIX_ENTRIES_PER_ADAPTER) ? | ||
431 | MSIX_ENTRIES_PER_ADAPTER : 2; | ||
432 | } else | ||
433 | num_msix = 1; | ||
434 | |||
435 | adapter->max_sds_rings = 1; | ||
436 | |||
437 | adapter->flags &= ~(QLCNIC_MSI_ENABLED | QLCNIC_MSIX_ENABLED); | ||
438 | |||
439 | legacy_intrp = &legacy_intr[adapter->ahw.pci_func]; | ||
440 | |||
441 | adapter->int_vec_bit = legacy_intrp->int_vec_bit; | ||
442 | adapter->tgt_status_reg = qlcnic_get_ioaddr(adapter, | ||
443 | legacy_intrp->tgt_status_reg); | ||
444 | adapter->tgt_mask_reg = qlcnic_get_ioaddr(adapter, | ||
445 | legacy_intrp->tgt_mask_reg); | ||
446 | adapter->isr_int_vec = qlcnic_get_ioaddr(adapter, ISR_INT_VECTOR); | ||
447 | |||
448 | adapter->crb_int_state_reg = qlcnic_get_ioaddr(adapter, | ||
449 | ISR_INT_STATE_REG); | ||
450 | |||
451 | qlcnic_set_msix_bit(pdev, 0); | ||
452 | |||
453 | if (adapter->msix_supported) { | ||
454 | |||
455 | qlcnic_init_msix_entries(adapter, num_msix); | ||
456 | err = pci_enable_msix(pdev, adapter->msix_entries, num_msix); | ||
457 | if (err == 0) { | ||
458 | adapter->flags |= QLCNIC_MSIX_ENABLED; | ||
459 | qlcnic_set_msix_bit(pdev, 1); | ||
460 | |||
461 | if (adapter->rss_supported) | ||
462 | adapter->max_sds_rings = num_msix; | ||
463 | |||
464 | dev_info(&pdev->dev, "using msi-x interrupts\n"); | ||
465 | return; | ||
466 | } | ||
467 | |||
468 | if (err > 0) | ||
469 | pci_disable_msix(pdev); | ||
470 | |||
471 | /* fall through for msi */ | ||
472 | } | ||
473 | |||
474 | if (use_msi && !pci_enable_msi(pdev)) { | ||
475 | adapter->flags |= QLCNIC_MSI_ENABLED; | ||
476 | adapter->tgt_status_reg = qlcnic_get_ioaddr(adapter, | ||
477 | msi_tgt_status[adapter->ahw.pci_func]); | ||
478 | dev_info(&pdev->dev, "using msi interrupts\n"); | ||
479 | adapter->msix_entries[0].vector = pdev->irq; | ||
480 | return; | ||
481 | } | ||
482 | |||
483 | dev_info(&pdev->dev, "using legacy interrupts\n"); | ||
484 | adapter->msix_entries[0].vector = pdev->irq; | ||
485 | } | ||
486 | |||
487 | static void | ||
488 | qlcnic_teardown_intr(struct qlcnic_adapter *adapter) | ||
489 | { | ||
490 | if (adapter->flags & QLCNIC_MSIX_ENABLED) | ||
491 | pci_disable_msix(adapter->pdev); | ||
492 | if (adapter->flags & QLCNIC_MSI_ENABLED) | ||
493 | pci_disable_msi(adapter->pdev); | ||
494 | } | ||
495 | |||
496 | static void | ||
497 | qlcnic_cleanup_pci_map(struct qlcnic_adapter *adapter) | ||
498 | { | ||
499 | if (adapter->ahw.pci_base0 != NULL) | ||
500 | iounmap(adapter->ahw.pci_base0); | ||
501 | } | ||
502 | |||
503 | static int | ||
504 | qlcnic_setup_pci_map(struct qlcnic_adapter *adapter) | ||
505 | { | ||
506 | void __iomem *mem_ptr0 = NULL; | ||
507 | resource_size_t mem_base; | ||
508 | unsigned long mem_len, pci_len0 = 0; | ||
509 | |||
510 | struct pci_dev *pdev = adapter->pdev; | ||
511 | int pci_func = adapter->ahw.pci_func; | ||
512 | |||
513 | /* | ||
514 | * Set the CRB window to invalid. If any register in window 0 is | ||
515 | * accessed it should set the window to 0 and then reset it to 1. | ||
516 | */ | ||
517 | adapter->ahw.crb_win = -1; | ||
518 | adapter->ahw.ocm_win = -1; | ||
519 | |||
520 | /* remap phys address */ | ||
521 | mem_base = pci_resource_start(pdev, 0); /* 0 is for BAR 0 */ | ||
522 | mem_len = pci_resource_len(pdev, 0); | ||
523 | |||
524 | if (mem_len == QLCNIC_PCI_2MB_SIZE) { | ||
525 | |||
526 | mem_ptr0 = pci_ioremap_bar(pdev, 0); | ||
527 | if (mem_ptr0 == NULL) { | ||
528 | dev_err(&pdev->dev, "failed to map PCI bar 0\n"); | ||
529 | return -EIO; | ||
530 | } | ||
531 | pci_len0 = mem_len; | ||
532 | } else { | ||
533 | return -EIO; | ||
534 | } | ||
535 | |||
536 | dev_info(&pdev->dev, "%dMB memory map\n", (int)(mem_len>>20)); | ||
537 | |||
538 | adapter->ahw.pci_base0 = mem_ptr0; | ||
539 | adapter->ahw.pci_len0 = pci_len0; | ||
540 | |||
541 | adapter->ahw.ocm_win_crb = qlcnic_get_ioaddr(adapter, | ||
542 | QLCNIC_PCIX_PS_REG(PCIX_OCM_WINDOW_REG(pci_func))); | ||
543 | |||
544 | return 0; | ||
545 | } | ||
546 | |||
547 | static void get_brd_name(struct qlcnic_adapter *adapter, char *name) | ||
548 | { | ||
549 | struct pci_dev *pdev = adapter->pdev; | ||
550 | int i, found = 0; | ||
551 | |||
552 | for (i = 0; i < NUM_SUPPORTED_BOARDS; ++i) { | ||
553 | if (qlcnic_boards[i].vendor == pdev->vendor && | ||
554 | qlcnic_boards[i].device == pdev->device && | ||
555 | qlcnic_boards[i].sub_vendor == pdev->subsystem_vendor && | ||
556 | qlcnic_boards[i].sub_device == pdev->subsystem_device) { | ||
557 | strcpy(name, qlcnic_boards[i].short_name); | ||
558 | found = 1; | ||
559 | break; | ||
560 | } | ||
561 | |||
562 | } | ||
563 | |||
564 | if (!found) | ||
565 | name = "Unknown"; | ||
566 | } | ||
567 | |||
568 | static void | ||
569 | qlcnic_check_options(struct qlcnic_adapter *adapter) | ||
570 | { | ||
571 | u32 fw_major, fw_minor, fw_build; | ||
572 | char brd_name[QLCNIC_MAX_BOARD_NAME_LEN]; | ||
573 | char serial_num[32]; | ||
574 | int i, offset, val; | ||
575 | int *ptr32; | ||
576 | struct pci_dev *pdev = adapter->pdev; | ||
577 | |||
578 | adapter->driver_mismatch = 0; | ||
579 | |||
580 | ptr32 = (int *)&serial_num; | ||
581 | offset = QLCNIC_FW_SERIAL_NUM_OFFSET; | ||
582 | for (i = 0; i < 8; i++) { | ||
583 | if (qlcnic_rom_fast_read(adapter, offset, &val) == -1) { | ||
584 | dev_err(&pdev->dev, "error reading board info\n"); | ||
585 | adapter->driver_mismatch = 1; | ||
586 | return; | ||
587 | } | ||
588 | ptr32[i] = cpu_to_le32(val); | ||
589 | offset += sizeof(u32); | ||
590 | } | ||
591 | |||
592 | fw_major = QLCRD32(adapter, QLCNIC_FW_VERSION_MAJOR); | ||
593 | fw_minor = QLCRD32(adapter, QLCNIC_FW_VERSION_MINOR); | ||
594 | fw_build = QLCRD32(adapter, QLCNIC_FW_VERSION_SUB); | ||
595 | |||
596 | adapter->fw_version = QLCNIC_VERSION_CODE(fw_major, fw_minor, fw_build); | ||
597 | |||
598 | if (adapter->portnum == 0) { | ||
599 | get_brd_name(adapter, brd_name); | ||
600 | |||
601 | pr_info("%s: %s Board Chip rev 0x%x\n", | ||
602 | module_name(THIS_MODULE), | ||
603 | brd_name, adapter->ahw.revision_id); | ||
604 | } | ||
605 | |||
606 | if (adapter->fw_version < QLCNIC_VERSION_CODE(3, 4, 216)) { | ||
607 | adapter->driver_mismatch = 1; | ||
608 | dev_warn(&pdev->dev, "firmware version %d.%d.%d unsupported\n", | ||
609 | fw_major, fw_minor, fw_build); | ||
610 | return; | ||
611 | } | ||
612 | |||
613 | i = QLCRD32(adapter, QLCNIC_SRE_MISC); | ||
614 | adapter->ahw.cut_through = (i & 0x8000) ? 1 : 0; | ||
615 | |||
616 | dev_info(&pdev->dev, "firmware v%d.%d.%d [%s]\n", | ||
617 | fw_major, fw_minor, fw_build, | ||
618 | adapter->ahw.cut_through ? "cut-through" : "legacy"); | ||
619 | |||
620 | if (adapter->fw_version >= QLCNIC_VERSION_CODE(4, 0, 222)) | ||
621 | adapter->capabilities = QLCRD32(adapter, CRB_FW_CAPABILITIES_1); | ||
622 | |||
623 | adapter->flags &= ~QLCNIC_LRO_ENABLED; | ||
624 | |||
625 | if (adapter->ahw.port_type == QLCNIC_XGBE) { | ||
626 | adapter->num_rxd = DEFAULT_RCV_DESCRIPTORS_10G; | ||
627 | adapter->num_jumbo_rxd = MAX_JUMBO_RCV_DESCRIPTORS_10G; | ||
628 | } else if (adapter->ahw.port_type == QLCNIC_GBE) { | ||
629 | adapter->num_rxd = DEFAULT_RCV_DESCRIPTORS_1G; | ||
630 | adapter->num_jumbo_rxd = MAX_JUMBO_RCV_DESCRIPTORS_1G; | ||
631 | } | ||
632 | |||
633 | adapter->msix_supported = !!use_msi_x; | ||
634 | adapter->rss_supported = !!use_msi_x; | ||
635 | |||
636 | adapter->num_txd = MAX_CMD_DESCRIPTORS; | ||
637 | |||
638 | adapter->num_lro_rxd = 0; | ||
639 | adapter->max_rds_rings = 2; | ||
640 | } | ||
641 | |||
642 | static int | ||
643 | qlcnic_start_firmware(struct qlcnic_adapter *adapter) | ||
644 | { | ||
645 | int val, err, first_boot; | ||
646 | |||
647 | err = qlcnic_set_dma_mask(adapter); | ||
648 | if (err) | ||
649 | return err; | ||
650 | |||
651 | if (!qlcnic_can_start_firmware(adapter)) | ||
652 | goto wait_init; | ||
653 | |||
654 | first_boot = QLCRD32(adapter, QLCNIC_CAM_RAM(0x1fc)); | ||
655 | if (first_boot == 0x55555555) | ||
656 | /* This is the first boot after power up */ | ||
657 | QLCWR32(adapter, QLCNIC_CAM_RAM(0x1fc), QLCNIC_BDINFO_MAGIC); | ||
658 | |||
659 | qlcnic_request_firmware(adapter); | ||
660 | |||
661 | err = qlcnic_need_fw_reset(adapter); | ||
662 | if (err < 0) | ||
663 | goto err_out; | ||
664 | if (err == 0) | ||
665 | goto wait_init; | ||
666 | |||
667 | if (first_boot != 0x55555555) { | ||
668 | QLCWR32(adapter, CRB_CMDPEG_STATE, 0); | ||
669 | qlcnic_pinit_from_rom(adapter); | ||
670 | msleep(1); | ||
671 | } | ||
672 | |||
673 | QLCWR32(adapter, CRB_DMA_SHIFT, 0x55555555); | ||
674 | QLCWR32(adapter, QLCNIC_PEG_HALT_STATUS1, 0); | ||
675 | QLCWR32(adapter, QLCNIC_PEG_HALT_STATUS2, 0); | ||
676 | |||
677 | qlcnic_set_port_mode(adapter); | ||
678 | |||
679 | err = qlcnic_load_firmware(adapter); | ||
680 | if (err) | ||
681 | goto err_out; | ||
682 | |||
683 | qlcnic_release_firmware(adapter); | ||
684 | |||
685 | val = (_QLCNIC_LINUX_MAJOR << 16) | ||
686 | | ((_QLCNIC_LINUX_MINOR << 8)) | ||
687 | | (_QLCNIC_LINUX_SUBVERSION); | ||
688 | QLCWR32(adapter, CRB_DRIVER_VERSION, val); | ||
689 | |||
690 | wait_init: | ||
691 | /* Handshake with the card before we register the devices. */ | ||
692 | err = qlcnic_phantom_init(adapter); | ||
693 | if (err) | ||
694 | goto err_out; | ||
695 | |||
696 | QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_READY); | ||
697 | |||
698 | qlcnic_update_dma_mask(adapter); | ||
699 | |||
700 | qlcnic_check_options(adapter); | ||
701 | |||
702 | adapter->need_fw_reset = 0; | ||
703 | |||
704 | /* fall through and release firmware */ | ||
705 | |||
706 | err_out: | ||
707 | qlcnic_release_firmware(adapter); | ||
708 | return err; | ||
709 | } | ||
710 | |||
711 | static int | ||
712 | qlcnic_request_irq(struct qlcnic_adapter *adapter) | ||
713 | { | ||
714 | irq_handler_t handler; | ||
715 | struct qlcnic_host_sds_ring *sds_ring; | ||
716 | int err, ring; | ||
717 | |||
718 | unsigned long flags = 0; | ||
719 | struct net_device *netdev = adapter->netdev; | ||
720 | struct qlcnic_recv_context *recv_ctx = &adapter->recv_ctx; | ||
721 | |||
722 | if (adapter->diag_test == QLCNIC_INTERRUPT_TEST) { | ||
723 | handler = qlcnic_tmp_intr; | ||
724 | if (!QLCNIC_IS_MSI_FAMILY(adapter)) | ||
725 | flags |= IRQF_SHARED; | ||
726 | |||
727 | } else { | ||
728 | if (adapter->flags & QLCNIC_MSIX_ENABLED) | ||
729 | handler = qlcnic_msix_intr; | ||
730 | else if (adapter->flags & QLCNIC_MSI_ENABLED) | ||
731 | handler = qlcnic_msi_intr; | ||
732 | else { | ||
733 | flags |= IRQF_SHARED; | ||
734 | handler = qlcnic_intr; | ||
735 | } | ||
736 | } | ||
737 | adapter->irq = netdev->irq; | ||
738 | |||
739 | for (ring = 0; ring < adapter->max_sds_rings; ring++) { | ||
740 | sds_ring = &recv_ctx->sds_rings[ring]; | ||
741 | sprintf(sds_ring->name, "%s[%d]", netdev->name, ring); | ||
742 | err = request_irq(sds_ring->irq, handler, | ||
743 | flags, sds_ring->name, sds_ring); | ||
744 | if (err) | ||
745 | return err; | ||
746 | } | ||
747 | |||
748 | return 0; | ||
749 | } | ||
750 | |||
751 | static void | ||
752 | qlcnic_free_irq(struct qlcnic_adapter *adapter) | ||
753 | { | ||
754 | int ring; | ||
755 | struct qlcnic_host_sds_ring *sds_ring; | ||
756 | |||
757 | struct qlcnic_recv_context *recv_ctx = &adapter->recv_ctx; | ||
758 | |||
759 | for (ring = 0; ring < adapter->max_sds_rings; ring++) { | ||
760 | sds_ring = &recv_ctx->sds_rings[ring]; | ||
761 | free_irq(sds_ring->irq, sds_ring); | ||
762 | } | ||
763 | } | ||
764 | |||
765 | static void | ||
766 | qlcnic_init_coalesce_defaults(struct qlcnic_adapter *adapter) | ||
767 | { | ||
768 | adapter->coal.flags = QLCNIC_INTR_DEFAULT; | ||
769 | adapter->coal.normal.data.rx_time_us = | ||
770 | QLCNIC_DEFAULT_INTR_COALESCE_RX_TIME_US; | ||
771 | adapter->coal.normal.data.rx_packets = | ||
772 | QLCNIC_DEFAULT_INTR_COALESCE_RX_PACKETS; | ||
773 | adapter->coal.normal.data.tx_time_us = | ||
774 | QLCNIC_DEFAULT_INTR_COALESCE_TX_TIME_US; | ||
775 | adapter->coal.normal.data.tx_packets = | ||
776 | QLCNIC_DEFAULT_INTR_COALESCE_TX_PACKETS; | ||
777 | } | ||
778 | |||
779 | static int | ||
780 | __qlcnic_up(struct qlcnic_adapter *adapter, struct net_device *netdev) | ||
781 | { | ||
782 | if (adapter->is_up != QLCNIC_ADAPTER_UP_MAGIC) | ||
783 | return -EIO; | ||
784 | |||
785 | qlcnic_set_multi(netdev); | ||
786 | qlcnic_fw_cmd_set_mtu(adapter, netdev->mtu); | ||
787 | |||
788 | adapter->ahw.linkup = 0; | ||
789 | |||
790 | if (adapter->max_sds_rings > 1) | ||
791 | qlcnic_config_rss(adapter, 1); | ||
792 | |||
793 | qlcnic_config_intr_coalesce(adapter); | ||
794 | |||
795 | if (adapter->capabilities & QLCNIC_FW_CAPABILITY_HW_LRO) | ||
796 | qlcnic_config_hw_lro(adapter, QLCNIC_LRO_ENABLED); | ||
797 | |||
798 | qlcnic_napi_enable(adapter); | ||
799 | |||
800 | qlcnic_linkevent_request(adapter, 1); | ||
801 | |||
802 | set_bit(__QLCNIC_DEV_UP, &adapter->state); | ||
803 | return 0; | ||
804 | } | ||
805 | |||
806 | /* Usage: During resume and firmware recovery module.*/ | ||
807 | |||
808 | static int | ||
809 | qlcnic_up(struct qlcnic_adapter *adapter, struct net_device *netdev) | ||
810 | { | ||
811 | int err = 0; | ||
812 | |||
813 | rtnl_lock(); | ||
814 | if (netif_running(netdev)) | ||
815 | err = __qlcnic_up(adapter, netdev); | ||
816 | rtnl_unlock(); | ||
817 | |||
818 | return err; | ||
819 | } | ||
820 | |||
821 | static void | ||
822 | __qlcnic_down(struct qlcnic_adapter *adapter, struct net_device *netdev) | ||
823 | { | ||
824 | if (adapter->is_up != QLCNIC_ADAPTER_UP_MAGIC) | ||
825 | return; | ||
826 | |||
827 | if (!test_and_clear_bit(__QLCNIC_DEV_UP, &adapter->state)) | ||
828 | return; | ||
829 | |||
830 | smp_mb(); | ||
831 | spin_lock(&adapter->tx_clean_lock); | ||
832 | netif_carrier_off(netdev); | ||
833 | netif_tx_disable(netdev); | ||
834 | |||
835 | qlcnic_free_mac_list(adapter); | ||
836 | |||
837 | qlcnic_nic_set_promisc(adapter, QLCNIC_NIU_NON_PROMISC_MODE); | ||
838 | |||
839 | qlcnic_napi_disable(adapter); | ||
840 | |||
841 | qlcnic_release_tx_buffers(adapter); | ||
842 | spin_unlock(&adapter->tx_clean_lock); | ||
843 | } | ||
844 | |||
845 | /* Usage: During suspend and firmware recovery module */ | ||
846 | |||
847 | static void | ||
848 | qlcnic_down(struct qlcnic_adapter *adapter, struct net_device *netdev) | ||
849 | { | ||
850 | rtnl_lock(); | ||
851 | if (netif_running(netdev)) | ||
852 | __qlcnic_down(adapter, netdev); | ||
853 | rtnl_unlock(); | ||
854 | |||
855 | } | ||
856 | |||
857 | static int | ||
858 | qlcnic_attach(struct qlcnic_adapter *adapter) | ||
859 | { | ||
860 | struct net_device *netdev = adapter->netdev; | ||
861 | struct pci_dev *pdev = adapter->pdev; | ||
862 | int err, ring; | ||
863 | struct qlcnic_host_rds_ring *rds_ring; | ||
864 | |||
865 | if (adapter->is_up == QLCNIC_ADAPTER_UP_MAGIC) | ||
866 | return 0; | ||
867 | |||
868 | err = qlcnic_init_firmware(adapter); | ||
869 | if (err) | ||
870 | return err; | ||
871 | |||
872 | err = qlcnic_napi_add(adapter, netdev); | ||
873 | if (err) | ||
874 | return err; | ||
875 | |||
876 | err = qlcnic_alloc_sw_resources(adapter); | ||
877 | if (err) { | ||
878 | dev_err(&pdev->dev, "Error in setting sw resources\n"); | ||
879 | return err; | ||
880 | } | ||
881 | |||
882 | err = qlcnic_alloc_hw_resources(adapter); | ||
883 | if (err) { | ||
884 | dev_err(&pdev->dev, "Error in setting hw resources\n"); | ||
885 | goto err_out_free_sw; | ||
886 | } | ||
887 | |||
888 | |||
889 | for (ring = 0; ring < adapter->max_rds_rings; ring++) { | ||
890 | rds_ring = &adapter->recv_ctx.rds_rings[ring]; | ||
891 | qlcnic_post_rx_buffers(adapter, ring, rds_ring); | ||
892 | } | ||
893 | |||
894 | err = qlcnic_request_irq(adapter); | ||
895 | if (err) { | ||
896 | dev_err(&pdev->dev, "failed to setup interrupt\n"); | ||
897 | goto err_out_free_rxbuf; | ||
898 | } | ||
899 | |||
900 | qlcnic_init_coalesce_defaults(adapter); | ||
901 | |||
902 | qlcnic_create_sysfs_entries(adapter); | ||
903 | |||
904 | adapter->is_up = QLCNIC_ADAPTER_UP_MAGIC; | ||
905 | return 0; | ||
906 | |||
907 | err_out_free_rxbuf: | ||
908 | qlcnic_release_rx_buffers(adapter); | ||
909 | qlcnic_free_hw_resources(adapter); | ||
910 | err_out_free_sw: | ||
911 | qlcnic_free_sw_resources(adapter); | ||
912 | return err; | ||
913 | } | ||
914 | |||
915 | static void | ||
916 | qlcnic_detach(struct qlcnic_adapter *adapter) | ||
917 | { | ||
918 | if (adapter->is_up != QLCNIC_ADAPTER_UP_MAGIC) | ||
919 | return; | ||
920 | |||
921 | qlcnic_remove_sysfs_entries(adapter); | ||
922 | |||
923 | qlcnic_free_hw_resources(adapter); | ||
924 | qlcnic_release_rx_buffers(adapter); | ||
925 | qlcnic_free_irq(adapter); | ||
926 | qlcnic_napi_del(adapter); | ||
927 | qlcnic_free_sw_resources(adapter); | ||
928 | |||
929 | adapter->is_up = 0; | ||
930 | } | ||
931 | |||
932 | void qlcnic_diag_free_res(struct net_device *netdev, int max_sds_rings) | ||
933 | { | ||
934 | struct qlcnic_adapter *adapter = netdev_priv(netdev); | ||
935 | struct qlcnic_host_sds_ring *sds_ring; | ||
936 | int ring; | ||
937 | |||
938 | if (adapter->diag_test == QLCNIC_INTERRUPT_TEST) { | ||
939 | for (ring = 0; ring < adapter->max_sds_rings; ring++) { | ||
940 | sds_ring = &adapter->recv_ctx.sds_rings[ring]; | ||
941 | qlcnic_disable_int(sds_ring); | ||
942 | } | ||
943 | } | ||
944 | |||
945 | qlcnic_detach(adapter); | ||
946 | |||
947 | adapter->diag_test = 0; | ||
948 | adapter->max_sds_rings = max_sds_rings; | ||
949 | |||
950 | if (qlcnic_attach(adapter)) | ||
951 | return; | ||
952 | |||
953 | if (netif_running(netdev)) | ||
954 | __qlcnic_up(adapter, netdev); | ||
955 | |||
956 | netif_device_attach(netdev); | ||
957 | } | ||
958 | |||
959 | int qlcnic_diag_alloc_res(struct net_device *netdev, int test) | ||
960 | { | ||
961 | struct qlcnic_adapter *adapter = netdev_priv(netdev); | ||
962 | struct qlcnic_host_sds_ring *sds_ring; | ||
963 | int ring; | ||
964 | int ret; | ||
965 | |||
966 | netif_device_detach(netdev); | ||
967 | |||
968 | if (netif_running(netdev)) | ||
969 | __qlcnic_down(adapter, netdev); | ||
970 | |||
971 | qlcnic_detach(adapter); | ||
972 | |||
973 | adapter->max_sds_rings = 1; | ||
974 | adapter->diag_test = test; | ||
975 | |||
976 | ret = qlcnic_attach(adapter); | ||
977 | if (ret) | ||
978 | return ret; | ||
979 | |||
980 | if (adapter->diag_test == QLCNIC_INTERRUPT_TEST) { | ||
981 | for (ring = 0; ring < adapter->max_sds_rings; ring++) { | ||
982 | sds_ring = &adapter->recv_ctx.sds_rings[ring]; | ||
983 | qlcnic_enable_int(sds_ring); | ||
984 | } | ||
985 | } | ||
986 | |||
987 | return 0; | ||
988 | } | ||
989 | |||
990 | int | ||
991 | qlcnic_reset_context(struct qlcnic_adapter *adapter) | ||
992 | { | ||
993 | int err = 0; | ||
994 | struct net_device *netdev = adapter->netdev; | ||
995 | |||
996 | if (test_and_set_bit(__QLCNIC_RESETTING, &adapter->state)) | ||
997 | return -EBUSY; | ||
998 | |||
999 | if (adapter->is_up == QLCNIC_ADAPTER_UP_MAGIC) { | ||
1000 | |||
1001 | netif_device_detach(netdev); | ||
1002 | |||
1003 | if (netif_running(netdev)) | ||
1004 | __qlcnic_down(adapter, netdev); | ||
1005 | |||
1006 | qlcnic_detach(adapter); | ||
1007 | |||
1008 | if (netif_running(netdev)) { | ||
1009 | err = qlcnic_attach(adapter); | ||
1010 | if (!err) | ||
1011 | err = __qlcnic_up(adapter, netdev); | ||
1012 | |||
1013 | if (err) | ||
1014 | goto done; | ||
1015 | } | ||
1016 | |||
1017 | netif_device_attach(netdev); | ||
1018 | } | ||
1019 | |||
1020 | done: | ||
1021 | clear_bit(__QLCNIC_RESETTING, &adapter->state); | ||
1022 | return err; | ||
1023 | } | ||
1024 | |||
1025 | static int | ||
1026 | qlcnic_setup_netdev(struct qlcnic_adapter *adapter, | ||
1027 | struct net_device *netdev) | ||
1028 | { | ||
1029 | int err; | ||
1030 | struct pci_dev *pdev = adapter->pdev; | ||
1031 | |||
1032 | adapter->rx_csum = 1; | ||
1033 | adapter->mc_enabled = 0; | ||
1034 | adapter->max_mc_count = 38; | ||
1035 | |||
1036 | netdev->netdev_ops = &qlcnic_netdev_ops; | ||
1037 | netdev->watchdog_timeo = 2*HZ; | ||
1038 | |||
1039 | qlcnic_change_mtu(netdev, netdev->mtu); | ||
1040 | |||
1041 | SET_ETHTOOL_OPS(netdev, &qlcnic_ethtool_ops); | ||
1042 | |||
1043 | netdev->features |= (NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO); | ||
1044 | netdev->features |= (NETIF_F_GRO); | ||
1045 | netdev->vlan_features |= (NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO); | ||
1046 | |||
1047 | netdev->features |= (NETIF_F_IPV6_CSUM | NETIF_F_TSO6); | ||
1048 | netdev->vlan_features |= (NETIF_F_IPV6_CSUM | NETIF_F_TSO6); | ||
1049 | |||
1050 | if (adapter->pci_using_dac) { | ||
1051 | netdev->features |= NETIF_F_HIGHDMA; | ||
1052 | netdev->vlan_features |= NETIF_F_HIGHDMA; | ||
1053 | } | ||
1054 | |||
1055 | if (adapter->capabilities & QLCNIC_FW_CAPABILITY_FVLANTX) | ||
1056 | netdev->features |= (NETIF_F_HW_VLAN_TX); | ||
1057 | |||
1058 | if (adapter->capabilities & QLCNIC_FW_CAPABILITY_HW_LRO) | ||
1059 | netdev->features |= NETIF_F_LRO; | ||
1060 | |||
1061 | netdev->irq = adapter->msix_entries[0].vector; | ||
1062 | |||
1063 | INIT_WORK(&adapter->tx_timeout_task, qlcnic_tx_timeout_task); | ||
1064 | |||
1065 | if (qlcnic_read_mac_addr(adapter)) | ||
1066 | dev_warn(&pdev->dev, "failed to read mac addr\n"); | ||
1067 | |||
1068 | netif_carrier_off(netdev); | ||
1069 | netif_stop_queue(netdev); | ||
1070 | |||
1071 | err = register_netdev(netdev); | ||
1072 | if (err) { | ||
1073 | dev_err(&pdev->dev, "failed to register net device\n"); | ||
1074 | return err; | ||
1075 | } | ||
1076 | |||
1077 | return 0; | ||
1078 | } | ||
1079 | |||
1080 | static int __devinit | ||
1081 | qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | ||
1082 | { | ||
1083 | struct net_device *netdev = NULL; | ||
1084 | struct qlcnic_adapter *adapter = NULL; | ||
1085 | int err; | ||
1086 | int pci_func_id = PCI_FUNC(pdev->devfn); | ||
1087 | uint8_t revision_id; | ||
1088 | |||
1089 | err = pci_enable_device(pdev); | ||
1090 | if (err) | ||
1091 | return err; | ||
1092 | |||
1093 | if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) { | ||
1094 | err = -ENODEV; | ||
1095 | goto err_out_disable_pdev; | ||
1096 | } | ||
1097 | |||
1098 | err = pci_request_regions(pdev, qlcnic_driver_name); | ||
1099 | if (err) | ||
1100 | goto err_out_disable_pdev; | ||
1101 | |||
1102 | pci_set_master(pdev); | ||
1103 | |||
1104 | netdev = alloc_etherdev(sizeof(struct qlcnic_adapter)); | ||
1105 | if (!netdev) { | ||
1106 | dev_err(&pdev->dev, "failed to allocate net_device\n"); | ||
1107 | err = -ENOMEM; | ||
1108 | goto err_out_free_res; | ||
1109 | } | ||
1110 | |||
1111 | SET_NETDEV_DEV(netdev, &pdev->dev); | ||
1112 | |||
1113 | adapter = netdev_priv(netdev); | ||
1114 | adapter->netdev = netdev; | ||
1115 | adapter->pdev = pdev; | ||
1116 | adapter->ahw.pci_func = pci_func_id; | ||
1117 | |||
1118 | revision_id = pdev->revision; | ||
1119 | adapter->ahw.revision_id = revision_id; | ||
1120 | |||
1121 | rwlock_init(&adapter->ahw.crb_lock); | ||
1122 | mutex_init(&adapter->ahw.mem_lock); | ||
1123 | |||
1124 | spin_lock_init(&adapter->tx_clean_lock); | ||
1125 | INIT_LIST_HEAD(&adapter->mac_list); | ||
1126 | |||
1127 | err = qlcnic_setup_pci_map(adapter); | ||
1128 | if (err) | ||
1129 | goto err_out_free_netdev; | ||
1130 | |||
1131 | /* This will be reset for mezz cards */ | ||
1132 | adapter->portnum = pci_func_id; | ||
1133 | |||
1134 | err = qlcnic_get_board_info(adapter); | ||
1135 | if (err) { | ||
1136 | dev_err(&pdev->dev, "Error getting board config info.\n"); | ||
1137 | goto err_out_iounmap; | ||
1138 | } | ||
1139 | |||
1140 | |||
1141 | err = qlcnic_start_firmware(adapter); | ||
1142 | if (err) | ||
1143 | goto err_out_decr_ref; | ||
1144 | |||
1145 | /* | ||
1146 | * See if the firmware gave us a virtual-physical port mapping. | ||
1147 | */ | ||
1148 | adapter->physical_port = adapter->portnum; | ||
1149 | |||
1150 | qlcnic_clear_stats(adapter); | ||
1151 | |||
1152 | qlcnic_setup_intr(adapter); | ||
1153 | |||
1154 | err = qlcnic_setup_netdev(adapter, netdev); | ||
1155 | if (err) | ||
1156 | goto err_out_disable_msi; | ||
1157 | |||
1158 | pci_set_drvdata(pdev, adapter); | ||
1159 | |||
1160 | qlcnic_schedule_work(adapter, qlcnic_fw_poll_work, FW_POLL_DELAY); | ||
1161 | |||
1162 | switch (adapter->ahw.port_type) { | ||
1163 | case QLCNIC_GBE: | ||
1164 | dev_info(&adapter->pdev->dev, "%s: GbE port initialized\n", | ||
1165 | adapter->netdev->name); | ||
1166 | break; | ||
1167 | case QLCNIC_XGBE: | ||
1168 | dev_info(&adapter->pdev->dev, "%s: XGbE port initialized\n", | ||
1169 | adapter->netdev->name); | ||
1170 | break; | ||
1171 | } | ||
1172 | |||
1173 | qlcnic_create_diag_entries(adapter); | ||
1174 | |||
1175 | return 0; | ||
1176 | |||
1177 | err_out_disable_msi: | ||
1178 | qlcnic_teardown_intr(adapter); | ||
1179 | |||
1180 | err_out_decr_ref: | ||
1181 | qlcnic_clr_all_drv_state(adapter); | ||
1182 | |||
1183 | err_out_iounmap: | ||
1184 | qlcnic_cleanup_pci_map(adapter); | ||
1185 | |||
1186 | err_out_free_netdev: | ||
1187 | free_netdev(netdev); | ||
1188 | |||
1189 | err_out_free_res: | ||
1190 | pci_release_regions(pdev); | ||
1191 | |||
1192 | err_out_disable_pdev: | ||
1193 | pci_set_drvdata(pdev, NULL); | ||
1194 | pci_disable_device(pdev); | ||
1195 | return err; | ||
1196 | } | ||
1197 | |||
1198 | static void __devexit qlcnic_remove(struct pci_dev *pdev) | ||
1199 | { | ||
1200 | struct qlcnic_adapter *adapter; | ||
1201 | struct net_device *netdev; | ||
1202 | |||
1203 | adapter = pci_get_drvdata(pdev); | ||
1204 | if (adapter == NULL) | ||
1205 | return; | ||
1206 | |||
1207 | netdev = adapter->netdev; | ||
1208 | |||
1209 | qlcnic_cancel_fw_work(adapter); | ||
1210 | |||
1211 | unregister_netdev(netdev); | ||
1212 | |||
1213 | cancel_work_sync(&adapter->tx_timeout_task); | ||
1214 | |||
1215 | qlcnic_detach(adapter); | ||
1216 | |||
1217 | qlcnic_clr_all_drv_state(adapter); | ||
1218 | |||
1219 | clear_bit(__QLCNIC_RESETTING, &adapter->state); | ||
1220 | |||
1221 | qlcnic_teardown_intr(adapter); | ||
1222 | |||
1223 | qlcnic_remove_diag_entries(adapter); | ||
1224 | |||
1225 | qlcnic_cleanup_pci_map(adapter); | ||
1226 | |||
1227 | qlcnic_release_firmware(adapter); | ||
1228 | |||
1229 | pci_release_regions(pdev); | ||
1230 | pci_disable_device(pdev); | ||
1231 | pci_set_drvdata(pdev, NULL); | ||
1232 | |||
1233 | free_netdev(netdev); | ||
1234 | } | ||
1235 | static int __qlcnic_shutdown(struct pci_dev *pdev) | ||
1236 | { | ||
1237 | struct qlcnic_adapter *adapter = pci_get_drvdata(pdev); | ||
1238 | struct net_device *netdev = adapter->netdev; | ||
1239 | int retval; | ||
1240 | |||
1241 | netif_device_detach(netdev); | ||
1242 | |||
1243 | qlcnic_cancel_fw_work(adapter); | ||
1244 | |||
1245 | if (netif_running(netdev)) | ||
1246 | qlcnic_down(adapter, netdev); | ||
1247 | |||
1248 | cancel_work_sync(&adapter->tx_timeout_task); | ||
1249 | |||
1250 | qlcnic_detach(adapter); | ||
1251 | |||
1252 | qlcnic_clr_all_drv_state(adapter); | ||
1253 | |||
1254 | clear_bit(__QLCNIC_RESETTING, &adapter->state); | ||
1255 | |||
1256 | retval = pci_save_state(pdev); | ||
1257 | if (retval) | ||
1258 | return retval; | ||
1259 | |||
1260 | if (qlcnic_wol_supported(adapter)) { | ||
1261 | pci_enable_wake(pdev, PCI_D3cold, 1); | ||
1262 | pci_enable_wake(pdev, PCI_D3hot, 1); | ||
1263 | } | ||
1264 | |||
1265 | return 0; | ||
1266 | } | ||
1267 | |||
1268 | static void qlcnic_shutdown(struct pci_dev *pdev) | ||
1269 | { | ||
1270 | if (__qlcnic_shutdown(pdev)) | ||
1271 | return; | ||
1272 | |||
1273 | pci_disable_device(pdev); | ||
1274 | } | ||
1275 | |||
1276 | #ifdef CONFIG_PM | ||
1277 | static int | ||
1278 | qlcnic_suspend(struct pci_dev *pdev, pm_message_t state) | ||
1279 | { | ||
1280 | int retval; | ||
1281 | |||
1282 | retval = __qlcnic_shutdown(pdev); | ||
1283 | if (retval) | ||
1284 | return retval; | ||
1285 | |||
1286 | pci_set_power_state(pdev, pci_choose_state(pdev, state)); | ||
1287 | return 0; | ||
1288 | } | ||
1289 | |||
1290 | static int | ||
1291 | qlcnic_resume(struct pci_dev *pdev) | ||
1292 | { | ||
1293 | struct qlcnic_adapter *adapter = pci_get_drvdata(pdev); | ||
1294 | struct net_device *netdev = adapter->netdev; | ||
1295 | int err; | ||
1296 | |||
1297 | err = pci_enable_device(pdev); | ||
1298 | if (err) | ||
1299 | return err; | ||
1300 | |||
1301 | pci_set_power_state(pdev, PCI_D0); | ||
1302 | pci_set_master(pdev); | ||
1303 | pci_restore_state(pdev); | ||
1304 | |||
1305 | adapter->ahw.crb_win = -1; | ||
1306 | adapter->ahw.ocm_win = -1; | ||
1307 | |||
1308 | err = qlcnic_start_firmware(adapter); | ||
1309 | if (err) { | ||
1310 | dev_err(&pdev->dev, "failed to start firmware\n"); | ||
1311 | return err; | ||
1312 | } | ||
1313 | |||
1314 | if (netif_running(netdev)) { | ||
1315 | err = qlcnic_attach(adapter); | ||
1316 | if (err) | ||
1317 | goto err_out; | ||
1318 | |||
1319 | err = qlcnic_up(adapter, netdev); | ||
1320 | if (err) | ||
1321 | goto err_out_detach; | ||
1322 | |||
1323 | |||
1324 | qlcnic_config_indev_addr(netdev, NETDEV_UP); | ||
1325 | } | ||
1326 | |||
1327 | netif_device_attach(netdev); | ||
1328 | qlcnic_schedule_work(adapter, qlcnic_fw_poll_work, FW_POLL_DELAY); | ||
1329 | return 0; | ||
1330 | |||
1331 | err_out_detach: | ||
1332 | qlcnic_detach(adapter); | ||
1333 | err_out: | ||
1334 | qlcnic_clr_all_drv_state(adapter); | ||
1335 | return err; | ||
1336 | } | ||
1337 | #endif | ||
1338 | |||
1339 | static int qlcnic_open(struct net_device *netdev) | ||
1340 | { | ||
1341 | struct qlcnic_adapter *adapter = netdev_priv(netdev); | ||
1342 | int err; | ||
1343 | |||
1344 | if (adapter->driver_mismatch) | ||
1345 | return -EIO; | ||
1346 | |||
1347 | err = qlcnic_attach(adapter); | ||
1348 | if (err) | ||
1349 | return err; | ||
1350 | |||
1351 | err = __qlcnic_up(adapter, netdev); | ||
1352 | if (err) | ||
1353 | goto err_out; | ||
1354 | |||
1355 | netif_start_queue(netdev); | ||
1356 | |||
1357 | return 0; | ||
1358 | |||
1359 | err_out: | ||
1360 | qlcnic_detach(adapter); | ||
1361 | return err; | ||
1362 | } | ||
1363 | |||
1364 | /* | ||
1365 | * qlcnic_close - Disables a network interface entry point | ||
1366 | */ | ||
1367 | static int qlcnic_close(struct net_device *netdev) | ||
1368 | { | ||
1369 | struct qlcnic_adapter *adapter = netdev_priv(netdev); | ||
1370 | |||
1371 | __qlcnic_down(adapter, netdev); | ||
1372 | return 0; | ||
1373 | } | ||
1374 | |||
1375 | static void | ||
1376 | qlcnic_tso_check(struct net_device *netdev, | ||
1377 | struct qlcnic_host_tx_ring *tx_ring, | ||
1378 | struct cmd_desc_type0 *first_desc, | ||
1379 | struct sk_buff *skb) | ||
1380 | { | ||
1381 | u8 opcode = TX_ETHER_PKT; | ||
1382 | __be16 protocol = skb->protocol; | ||
1383 | u16 flags = 0, vid = 0; | ||
1384 | u32 producer; | ||
1385 | int copied, offset, copy_len, hdr_len = 0, tso = 0, vlan_oob = 0; | ||
1386 | struct cmd_desc_type0 *hwdesc; | ||
1387 | struct vlan_ethhdr *vh; | ||
1388 | |||
1389 | if (protocol == cpu_to_be16(ETH_P_8021Q)) { | ||
1390 | |||
1391 | vh = (struct vlan_ethhdr *)skb->data; | ||
1392 | protocol = vh->h_vlan_encapsulated_proto; | ||
1393 | flags = FLAGS_VLAN_TAGGED; | ||
1394 | |||
1395 | } else if (vlan_tx_tag_present(skb)) { | ||
1396 | |||
1397 | flags = FLAGS_VLAN_OOB; | ||
1398 | vid = vlan_tx_tag_get(skb); | ||
1399 | qlcnic_set_tx_vlan_tci(first_desc, vid); | ||
1400 | vlan_oob = 1; | ||
1401 | } | ||
1402 | |||
1403 | if ((netdev->features & (NETIF_F_TSO | NETIF_F_TSO6)) && | ||
1404 | skb_shinfo(skb)->gso_size > 0) { | ||
1405 | |||
1406 | hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb); | ||
1407 | |||
1408 | first_desc->mss = cpu_to_le16(skb_shinfo(skb)->gso_size); | ||
1409 | first_desc->total_hdr_length = hdr_len; | ||
1410 | if (vlan_oob) { | ||
1411 | first_desc->total_hdr_length += VLAN_HLEN; | ||
1412 | first_desc->tcp_hdr_offset = VLAN_HLEN; | ||
1413 | first_desc->ip_hdr_offset = VLAN_HLEN; | ||
1414 | /* Only in case of TSO on vlan device */ | ||
1415 | flags |= FLAGS_VLAN_TAGGED; | ||
1416 | } | ||
1417 | |||
1418 | opcode = (protocol == cpu_to_be16(ETH_P_IPV6)) ? | ||
1419 | TX_TCP_LSO6 : TX_TCP_LSO; | ||
1420 | tso = 1; | ||
1421 | |||
1422 | } else if (skb->ip_summed == CHECKSUM_PARTIAL) { | ||
1423 | u8 l4proto; | ||
1424 | |||
1425 | if (protocol == cpu_to_be16(ETH_P_IP)) { | ||
1426 | l4proto = ip_hdr(skb)->protocol; | ||
1427 | |||
1428 | if (l4proto == IPPROTO_TCP) | ||
1429 | opcode = TX_TCP_PKT; | ||
1430 | else if (l4proto == IPPROTO_UDP) | ||
1431 | opcode = TX_UDP_PKT; | ||
1432 | } else if (protocol == cpu_to_be16(ETH_P_IPV6)) { | ||
1433 | l4proto = ipv6_hdr(skb)->nexthdr; | ||
1434 | |||
1435 | if (l4proto == IPPROTO_TCP) | ||
1436 | opcode = TX_TCPV6_PKT; | ||
1437 | else if (l4proto == IPPROTO_UDP) | ||
1438 | opcode = TX_UDPV6_PKT; | ||
1439 | } | ||
1440 | } | ||
1441 | |||
1442 | first_desc->tcp_hdr_offset += skb_transport_offset(skb); | ||
1443 | first_desc->ip_hdr_offset += skb_network_offset(skb); | ||
1444 | qlcnic_set_tx_flags_opcode(first_desc, flags, opcode); | ||
1445 | |||
1446 | if (!tso) | ||
1447 | return; | ||
1448 | |||
1449 | /* For LSO, we need to copy the MAC/IP/TCP headers into | ||
1450 | * the descriptor ring | ||
1451 | */ | ||
1452 | producer = tx_ring->producer; | ||
1453 | copied = 0; | ||
1454 | offset = 2; | ||
1455 | |||
1456 | if (vlan_oob) { | ||
1457 | /* Create a TSO vlan header template for firmware */ | ||
1458 | |||
1459 | hwdesc = &tx_ring->desc_head[producer]; | ||
1460 | tx_ring->cmd_buf_arr[producer].skb = NULL; | ||
1461 | |||
1462 | copy_len = min((int)sizeof(struct cmd_desc_type0) - offset, | ||
1463 | hdr_len + VLAN_HLEN); | ||
1464 | |||
1465 | vh = (struct vlan_ethhdr *)((char *)hwdesc + 2); | ||
1466 | skb_copy_from_linear_data(skb, vh, 12); | ||
1467 | vh->h_vlan_proto = htons(ETH_P_8021Q); | ||
1468 | vh->h_vlan_TCI = htons(vid); | ||
1469 | skb_copy_from_linear_data_offset(skb, 12, | ||
1470 | (char *)vh + 16, copy_len - 16); | ||
1471 | |||
1472 | copied = copy_len - VLAN_HLEN; | ||
1473 | offset = 0; | ||
1474 | |||
1475 | producer = get_next_index(producer, tx_ring->num_desc); | ||
1476 | } | ||
1477 | |||
1478 | while (copied < hdr_len) { | ||
1479 | |||
1480 | copy_len = min((int)sizeof(struct cmd_desc_type0) - offset, | ||
1481 | (hdr_len - copied)); | ||
1482 | |||
1483 | hwdesc = &tx_ring->desc_head[producer]; | ||
1484 | tx_ring->cmd_buf_arr[producer].skb = NULL; | ||
1485 | |||
1486 | skb_copy_from_linear_data_offset(skb, copied, | ||
1487 | (char *)hwdesc + offset, copy_len); | ||
1488 | |||
1489 | copied += copy_len; | ||
1490 | offset = 0; | ||
1491 | |||
1492 | producer = get_next_index(producer, tx_ring->num_desc); | ||
1493 | } | ||
1494 | |||
1495 | tx_ring->producer = producer; | ||
1496 | barrier(); | ||
1497 | } | ||
1498 | |||
1499 | static int | ||
1500 | qlcnic_map_tx_skb(struct pci_dev *pdev, | ||
1501 | struct sk_buff *skb, struct qlcnic_cmd_buffer *pbuf) | ||
1502 | { | ||
1503 | struct qlcnic_skb_frag *nf; | ||
1504 | struct skb_frag_struct *frag; | ||
1505 | int i, nr_frags; | ||
1506 | dma_addr_t map; | ||
1507 | |||
1508 | nr_frags = skb_shinfo(skb)->nr_frags; | ||
1509 | nf = &pbuf->frag_array[0]; | ||
1510 | |||
1511 | map = pci_map_single(pdev, skb->data, | ||
1512 | skb_headlen(skb), PCI_DMA_TODEVICE); | ||
1513 | if (pci_dma_mapping_error(pdev, map)) | ||
1514 | goto out_err; | ||
1515 | |||
1516 | nf->dma = map; | ||
1517 | nf->length = skb_headlen(skb); | ||
1518 | |||
1519 | for (i = 0; i < nr_frags; i++) { | ||
1520 | frag = &skb_shinfo(skb)->frags[i]; | ||
1521 | nf = &pbuf->frag_array[i+1]; | ||
1522 | |||
1523 | map = pci_map_page(pdev, frag->page, frag->page_offset, | ||
1524 | frag->size, PCI_DMA_TODEVICE); | ||
1525 | if (pci_dma_mapping_error(pdev, map)) | ||
1526 | goto unwind; | ||
1527 | |||
1528 | nf->dma = map; | ||
1529 | nf->length = frag->size; | ||
1530 | } | ||
1531 | |||
1532 | return 0; | ||
1533 | |||
1534 | unwind: | ||
1535 | while (--i >= 0) { | ||
1536 | nf = &pbuf->frag_array[i+1]; | ||
1537 | pci_unmap_page(pdev, nf->dma, nf->length, PCI_DMA_TODEVICE); | ||
1538 | } | ||
1539 | |||
1540 | nf = &pbuf->frag_array[0]; | ||
1541 | pci_unmap_single(pdev, nf->dma, skb_headlen(skb), PCI_DMA_TODEVICE); | ||
1542 | |||
1543 | out_err: | ||
1544 | return -ENOMEM; | ||
1545 | } | ||
1546 | |||
1547 | static inline void | ||
1548 | qlcnic_clear_cmddesc(u64 *desc) | ||
1549 | { | ||
1550 | desc[0] = 0ULL; | ||
1551 | desc[2] = 0ULL; | ||
1552 | } | ||
1553 | |||
1554 | netdev_tx_t | ||
1555 | qlcnic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) | ||
1556 | { | ||
1557 | struct qlcnic_adapter *adapter = netdev_priv(netdev); | ||
1558 | struct qlcnic_host_tx_ring *tx_ring = adapter->tx_ring; | ||
1559 | struct qlcnic_cmd_buffer *pbuf; | ||
1560 | struct qlcnic_skb_frag *buffrag; | ||
1561 | struct cmd_desc_type0 *hwdesc, *first_desc; | ||
1562 | struct pci_dev *pdev; | ||
1563 | int i, k; | ||
1564 | |||
1565 | u32 producer; | ||
1566 | int frag_count, no_of_desc; | ||
1567 | u32 num_txd = tx_ring->num_desc; | ||
1568 | |||
1569 | frag_count = skb_shinfo(skb)->nr_frags + 1; | ||
1570 | |||
1571 | /* 4 fragments per cmd des */ | ||
1572 | no_of_desc = (frag_count + 3) >> 2; | ||
1573 | |||
1574 | if (unlikely(no_of_desc + 2 > qlcnic_tx_avail(tx_ring))) { | ||
1575 | netif_stop_queue(netdev); | ||
1576 | return NETDEV_TX_BUSY; | ||
1577 | } | ||
1578 | |||
1579 | producer = tx_ring->producer; | ||
1580 | pbuf = &tx_ring->cmd_buf_arr[producer]; | ||
1581 | |||
1582 | pdev = adapter->pdev; | ||
1583 | |||
1584 | if (qlcnic_map_tx_skb(pdev, skb, pbuf)) | ||
1585 | goto drop_packet; | ||
1586 | |||
1587 | pbuf->skb = skb; | ||
1588 | pbuf->frag_count = frag_count; | ||
1589 | |||
1590 | first_desc = hwdesc = &tx_ring->desc_head[producer]; | ||
1591 | qlcnic_clear_cmddesc((u64 *)hwdesc); | ||
1592 | |||
1593 | qlcnic_set_tx_frags_len(first_desc, frag_count, skb->len); | ||
1594 | qlcnic_set_tx_port(first_desc, adapter->portnum); | ||
1595 | |||
1596 | for (i = 0; i < frag_count; i++) { | ||
1597 | |||
1598 | k = i % 4; | ||
1599 | |||
1600 | if ((k == 0) && (i > 0)) { | ||
1601 | /* move to next desc.*/ | ||
1602 | producer = get_next_index(producer, num_txd); | ||
1603 | hwdesc = &tx_ring->desc_head[producer]; | ||
1604 | qlcnic_clear_cmddesc((u64 *)hwdesc); | ||
1605 | tx_ring->cmd_buf_arr[producer].skb = NULL; | ||
1606 | } | ||
1607 | |||
1608 | buffrag = &pbuf->frag_array[i]; | ||
1609 | |||
1610 | hwdesc->buffer_length[k] = cpu_to_le16(buffrag->length); | ||
1611 | switch (k) { | ||
1612 | case 0: | ||
1613 | hwdesc->addr_buffer1 = cpu_to_le64(buffrag->dma); | ||
1614 | break; | ||
1615 | case 1: | ||
1616 | hwdesc->addr_buffer2 = cpu_to_le64(buffrag->dma); | ||
1617 | break; | ||
1618 | case 2: | ||
1619 | hwdesc->addr_buffer3 = cpu_to_le64(buffrag->dma); | ||
1620 | break; | ||
1621 | case 3: | ||
1622 | hwdesc->addr_buffer4 = cpu_to_le64(buffrag->dma); | ||
1623 | break; | ||
1624 | } | ||
1625 | } | ||
1626 | |||
1627 | tx_ring->producer = get_next_index(producer, num_txd); | ||
1628 | |||
1629 | qlcnic_tso_check(netdev, tx_ring, first_desc, skb); | ||
1630 | |||
1631 | qlcnic_update_cmd_producer(adapter, tx_ring); | ||
1632 | |||
1633 | adapter->stats.txbytes += skb->len; | ||
1634 | adapter->stats.xmitcalled++; | ||
1635 | |||
1636 | return NETDEV_TX_OK; | ||
1637 | |||
1638 | drop_packet: | ||
1639 | adapter->stats.txdropped++; | ||
1640 | dev_kfree_skb_any(skb); | ||
1641 | return NETDEV_TX_OK; | ||
1642 | } | ||
1643 | |||
1644 | static int qlcnic_check_temp(struct qlcnic_adapter *adapter) | ||
1645 | { | ||
1646 | struct net_device *netdev = adapter->netdev; | ||
1647 | u32 temp, temp_state, temp_val; | ||
1648 | int rv = 0; | ||
1649 | |||
1650 | temp = QLCRD32(adapter, CRB_TEMP_STATE); | ||
1651 | |||
1652 | temp_state = qlcnic_get_temp_state(temp); | ||
1653 | temp_val = qlcnic_get_temp_val(temp); | ||
1654 | |||
1655 | if (temp_state == QLCNIC_TEMP_PANIC) { | ||
1656 | dev_err(&netdev->dev, | ||
1657 | "Device temperature %d degrees C exceeds" | ||
1658 | " maximum allowed. Hardware has been shut down.\n", | ||
1659 | temp_val); | ||
1660 | rv = 1; | ||
1661 | } else if (temp_state == QLCNIC_TEMP_WARN) { | ||
1662 | if (adapter->temp == QLCNIC_TEMP_NORMAL) { | ||
1663 | dev_err(&netdev->dev, | ||
1664 | "Device temperature %d degrees C " | ||
1665 | "exceeds operating range." | ||
1666 | " Immediate action needed.\n", | ||
1667 | temp_val); | ||
1668 | } | ||
1669 | } else { | ||
1670 | if (adapter->temp == QLCNIC_TEMP_WARN) { | ||
1671 | dev_info(&netdev->dev, | ||
1672 | "Device temperature is now %d degrees C" | ||
1673 | " in normal range.\n", temp_val); | ||
1674 | } | ||
1675 | } | ||
1676 | adapter->temp = temp_state; | ||
1677 | return rv; | ||
1678 | } | ||
1679 | |||
1680 | void qlcnic_advert_link_change(struct qlcnic_adapter *adapter, int linkup) | ||
1681 | { | ||
1682 | struct net_device *netdev = adapter->netdev; | ||
1683 | |||
1684 | if (adapter->ahw.linkup && !linkup) { | ||
1685 | dev_info(&netdev->dev, "NIC Link is down\n"); | ||
1686 | adapter->ahw.linkup = 0; | ||
1687 | if (netif_running(netdev)) { | ||
1688 | netif_carrier_off(netdev); | ||
1689 | netif_stop_queue(netdev); | ||
1690 | } | ||
1691 | } else if (!adapter->ahw.linkup && linkup) { | ||
1692 | dev_info(&netdev->dev, "NIC Link is up\n"); | ||
1693 | adapter->ahw.linkup = 1; | ||
1694 | if (netif_running(netdev)) { | ||
1695 | netif_carrier_on(netdev); | ||
1696 | netif_wake_queue(netdev); | ||
1697 | } | ||
1698 | } | ||
1699 | } | ||
1700 | |||
1701 | static void qlcnic_tx_timeout(struct net_device *netdev) | ||
1702 | { | ||
1703 | struct qlcnic_adapter *adapter = netdev_priv(netdev); | ||
1704 | |||
1705 | if (test_bit(__QLCNIC_RESETTING, &adapter->state)) | ||
1706 | return; | ||
1707 | |||
1708 | dev_err(&netdev->dev, "transmit timeout, resetting.\n"); | ||
1709 | schedule_work(&adapter->tx_timeout_task); | ||
1710 | } | ||
1711 | |||
1712 | static void qlcnic_tx_timeout_task(struct work_struct *work) | ||
1713 | { | ||
1714 | struct qlcnic_adapter *adapter = | ||
1715 | container_of(work, struct qlcnic_adapter, tx_timeout_task); | ||
1716 | |||
1717 | if (!netif_running(adapter->netdev)) | ||
1718 | return; | ||
1719 | |||
1720 | if (test_and_set_bit(__QLCNIC_RESETTING, &adapter->state)) | ||
1721 | return; | ||
1722 | |||
1723 | if (++adapter->tx_timeo_cnt >= QLCNIC_MAX_TX_TIMEOUTS) | ||
1724 | goto request_reset; | ||
1725 | |||
1726 | clear_bit(__QLCNIC_RESETTING, &adapter->state); | ||
1727 | if (!qlcnic_reset_context(adapter)) { | ||
1728 | adapter->netdev->trans_start = jiffies; | ||
1729 | return; | ||
1730 | |||
1731 | /* context reset failed, fall through for fw reset */ | ||
1732 | } | ||
1733 | |||
1734 | request_reset: | ||
1735 | adapter->need_fw_reset = 1; | ||
1736 | clear_bit(__QLCNIC_RESETTING, &adapter->state); | ||
1737 | } | ||
1738 | |||
1739 | static struct net_device_stats *qlcnic_get_stats(struct net_device *netdev) | ||
1740 | { | ||
1741 | struct qlcnic_adapter *adapter = netdev_priv(netdev); | ||
1742 | struct net_device_stats *stats = &netdev->stats; | ||
1743 | |||
1744 | memset(stats, 0, sizeof(*stats)); | ||
1745 | |||
1746 | stats->rx_packets = adapter->stats.rx_pkts + adapter->stats.lro_pkts; | ||
1747 | stats->tx_packets = adapter->stats.xmitfinished; | ||
1748 | stats->rx_bytes = adapter->stats.rxbytes; | ||
1749 | stats->tx_bytes = adapter->stats.txbytes; | ||
1750 | stats->rx_dropped = adapter->stats.rxdropped; | ||
1751 | stats->tx_dropped = adapter->stats.txdropped; | ||
1752 | |||
1753 | return stats; | ||
1754 | } | ||
1755 | |||
1756 | static irqreturn_t qlcnic_clear_legacy_intr(struct qlcnic_adapter *adapter) | ||
1757 | { | ||
1758 | u32 status; | ||
1759 | |||
1760 | status = readl(adapter->isr_int_vec); | ||
1761 | |||
1762 | if (!(status & adapter->int_vec_bit)) | ||
1763 | return IRQ_NONE; | ||
1764 | |||
1765 | /* check interrupt state machine, to be sure */ | ||
1766 | status = readl(adapter->crb_int_state_reg); | ||
1767 | if (!ISR_LEGACY_INT_TRIGGERED(status)) | ||
1768 | return IRQ_NONE; | ||
1769 | |||
1770 | writel(0xffffffff, adapter->tgt_status_reg); | ||
1771 | /* read twice to ensure write is flushed */ | ||
1772 | readl(adapter->isr_int_vec); | ||
1773 | readl(adapter->isr_int_vec); | ||
1774 | |||
1775 | return IRQ_HANDLED; | ||
1776 | } | ||
1777 | |||
1778 | static irqreturn_t qlcnic_tmp_intr(int irq, void *data) | ||
1779 | { | ||
1780 | struct qlcnic_host_sds_ring *sds_ring = data; | ||
1781 | struct qlcnic_adapter *adapter = sds_ring->adapter; | ||
1782 | |||
1783 | if (adapter->flags & QLCNIC_MSIX_ENABLED) | ||
1784 | goto done; | ||
1785 | else if (adapter->flags & QLCNIC_MSI_ENABLED) { | ||
1786 | writel(0xffffffff, adapter->tgt_status_reg); | ||
1787 | goto done; | ||
1788 | } | ||
1789 | |||
1790 | if (qlcnic_clear_legacy_intr(adapter) == IRQ_NONE) | ||
1791 | return IRQ_NONE; | ||
1792 | |||
1793 | done: | ||
1794 | adapter->diag_cnt++; | ||
1795 | qlcnic_enable_int(sds_ring); | ||
1796 | return IRQ_HANDLED; | ||
1797 | } | ||
1798 | |||
1799 | static irqreturn_t qlcnic_intr(int irq, void *data) | ||
1800 | { | ||
1801 | struct qlcnic_host_sds_ring *sds_ring = data; | ||
1802 | struct qlcnic_adapter *adapter = sds_ring->adapter; | ||
1803 | |||
1804 | if (qlcnic_clear_legacy_intr(adapter) == IRQ_NONE) | ||
1805 | return IRQ_NONE; | ||
1806 | |||
1807 | napi_schedule(&sds_ring->napi); | ||
1808 | |||
1809 | return IRQ_HANDLED; | ||
1810 | } | ||
1811 | |||
1812 | static irqreturn_t qlcnic_msi_intr(int irq, void *data) | ||
1813 | { | ||
1814 | struct qlcnic_host_sds_ring *sds_ring = data; | ||
1815 | struct qlcnic_adapter *adapter = sds_ring->adapter; | ||
1816 | |||
1817 | /* clear interrupt */ | ||
1818 | writel(0xffffffff, adapter->tgt_status_reg); | ||
1819 | |||
1820 | napi_schedule(&sds_ring->napi); | ||
1821 | return IRQ_HANDLED; | ||
1822 | } | ||
1823 | |||
1824 | static irqreturn_t qlcnic_msix_intr(int irq, void *data) | ||
1825 | { | ||
1826 | struct qlcnic_host_sds_ring *sds_ring = data; | ||
1827 | |||
1828 | napi_schedule(&sds_ring->napi); | ||
1829 | return IRQ_HANDLED; | ||
1830 | } | ||
1831 | |||
1832 | static int qlcnic_process_cmd_ring(struct qlcnic_adapter *adapter) | ||
1833 | { | ||
1834 | u32 sw_consumer, hw_consumer; | ||
1835 | int count = 0, i; | ||
1836 | struct qlcnic_cmd_buffer *buffer; | ||
1837 | struct pci_dev *pdev = adapter->pdev; | ||
1838 | struct net_device *netdev = adapter->netdev; | ||
1839 | struct qlcnic_skb_frag *frag; | ||
1840 | int done; | ||
1841 | struct qlcnic_host_tx_ring *tx_ring = adapter->tx_ring; | ||
1842 | |||
1843 | if (!spin_trylock(&adapter->tx_clean_lock)) | ||
1844 | return 1; | ||
1845 | |||
1846 | sw_consumer = tx_ring->sw_consumer; | ||
1847 | hw_consumer = le32_to_cpu(*(tx_ring->hw_consumer)); | ||
1848 | |||
1849 | while (sw_consumer != hw_consumer) { | ||
1850 | buffer = &tx_ring->cmd_buf_arr[sw_consumer]; | ||
1851 | if (buffer->skb) { | ||
1852 | frag = &buffer->frag_array[0]; | ||
1853 | pci_unmap_single(pdev, frag->dma, frag->length, | ||
1854 | PCI_DMA_TODEVICE); | ||
1855 | frag->dma = 0ULL; | ||
1856 | for (i = 1; i < buffer->frag_count; i++) { | ||
1857 | frag++; | ||
1858 | pci_unmap_page(pdev, frag->dma, frag->length, | ||
1859 | PCI_DMA_TODEVICE); | ||
1860 | frag->dma = 0ULL; | ||
1861 | } | ||
1862 | |||
1863 | adapter->stats.xmitfinished++; | ||
1864 | dev_kfree_skb_any(buffer->skb); | ||
1865 | buffer->skb = NULL; | ||
1866 | } | ||
1867 | |||
1868 | sw_consumer = get_next_index(sw_consumer, tx_ring->num_desc); | ||
1869 | if (++count >= MAX_STATUS_HANDLE) | ||
1870 | break; | ||
1871 | } | ||
1872 | |||
1873 | if (count && netif_running(netdev)) { | ||
1874 | tx_ring->sw_consumer = sw_consumer; | ||
1875 | |||
1876 | smp_mb(); | ||
1877 | |||
1878 | if (netif_queue_stopped(netdev) && netif_carrier_ok(netdev)) { | ||
1879 | __netif_tx_lock(tx_ring->txq, smp_processor_id()); | ||
1880 | if (qlcnic_tx_avail(tx_ring) > TX_STOP_THRESH) { | ||
1881 | netif_wake_queue(netdev); | ||
1882 | adapter->tx_timeo_cnt = 0; | ||
1883 | } | ||
1884 | __netif_tx_unlock(tx_ring->txq); | ||
1885 | } | ||
1886 | } | ||
1887 | /* | ||
1888 | * If everything is freed up to consumer then check if the ring is full | ||
1889 | * If the ring is full then check if more needs to be freed and | ||
1890 | * schedule the call back again. | ||
1891 | * | ||
1892 | * This happens when there are 2 CPUs. One could be freeing and the | ||
1893 | * other filling it. If the ring is full when we get out of here and | ||
1894 | * the card has already interrupted the host then the host can miss the | ||
1895 | * interrupt. | ||
1896 | * | ||
1897 | * There is still a possible race condition and the host could miss an | ||
1898 | * interrupt. The card has to take care of this. | ||
1899 | */ | ||
1900 | hw_consumer = le32_to_cpu(*(tx_ring->hw_consumer)); | ||
1901 | done = (sw_consumer == hw_consumer); | ||
1902 | spin_unlock(&adapter->tx_clean_lock); | ||
1903 | |||
1904 | return done; | ||
1905 | } | ||
1906 | |||
1907 | static int qlcnic_poll(struct napi_struct *napi, int budget) | ||
1908 | { | ||
1909 | struct qlcnic_host_sds_ring *sds_ring = | ||
1910 | container_of(napi, struct qlcnic_host_sds_ring, napi); | ||
1911 | |||
1912 | struct qlcnic_adapter *adapter = sds_ring->adapter; | ||
1913 | |||
1914 | int tx_complete; | ||
1915 | int work_done; | ||
1916 | |||
1917 | tx_complete = qlcnic_process_cmd_ring(adapter); | ||
1918 | |||
1919 | work_done = qlcnic_process_rcv_ring(sds_ring, budget); | ||
1920 | |||
1921 | if ((work_done < budget) && tx_complete) { | ||
1922 | napi_complete(&sds_ring->napi); | ||
1923 | if (test_bit(__QLCNIC_DEV_UP, &adapter->state)) | ||
1924 | qlcnic_enable_int(sds_ring); | ||
1925 | } | ||
1926 | |||
1927 | return work_done; | ||
1928 | } | ||
1929 | |||
1930 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
1931 | static void qlcnic_poll_controller(struct net_device *netdev) | ||
1932 | { | ||
1933 | struct qlcnic_adapter *adapter = netdev_priv(netdev); | ||
1934 | disable_irq(adapter->irq); | ||
1935 | qlcnic_intr(adapter->irq, adapter); | ||
1936 | enable_irq(adapter->irq); | ||
1937 | } | ||
1938 | #endif | ||
1939 | |||
1940 | static void | ||
1941 | qlcnic_set_drv_state(struct qlcnic_adapter *adapter, int state) | ||
1942 | { | ||
1943 | u32 val; | ||
1944 | |||
1945 | WARN_ON(state != QLCNIC_DEV_NEED_RESET && | ||
1946 | state != QLCNIC_DEV_NEED_QUISCENT); | ||
1947 | |||
1948 | if (qlcnic_api_lock(adapter)) | ||
1949 | return ; | ||
1950 | |||
1951 | val = QLCRD32(adapter, QLCNIC_CRB_DRV_STATE); | ||
1952 | |||
1953 | if (state == QLCNIC_DEV_NEED_RESET) | ||
1954 | val |= ((u32)0x1 << (adapter->portnum * 4)); | ||
1955 | else if (state == QLCNIC_DEV_NEED_QUISCENT) | ||
1956 | val |= ((u32)0x1 << ((adapter->portnum * 4) + 1)); | ||
1957 | |||
1958 | QLCWR32(adapter, QLCNIC_CRB_DRV_STATE, val); | ||
1959 | |||
1960 | qlcnic_api_unlock(adapter); | ||
1961 | } | ||
1962 | |||
1963 | static int | ||
1964 | qlcnic_clr_drv_state(struct qlcnic_adapter *adapter) | ||
1965 | { | ||
1966 | u32 val; | ||
1967 | |||
1968 | if (qlcnic_api_lock(adapter)) | ||
1969 | return -EBUSY; | ||
1970 | |||
1971 | val = QLCRD32(adapter, QLCNIC_CRB_DRV_STATE); | ||
1972 | val &= ~((u32)0x3 << (adapter->portnum * 4)); | ||
1973 | QLCWR32(adapter, QLCNIC_CRB_DRV_STATE, val); | ||
1974 | |||
1975 | qlcnic_api_unlock(adapter); | ||
1976 | |||
1977 | return 0; | ||
1978 | } | ||
1979 | |||
1980 | static void | ||
1981 | qlcnic_clr_all_drv_state(struct qlcnic_adapter *adapter) | ||
1982 | { | ||
1983 | u32 val; | ||
1984 | |||
1985 | if (qlcnic_api_lock(adapter)) | ||
1986 | goto err; | ||
1987 | |||
1988 | val = QLCRD32(adapter, QLCNIC_CRB_DEV_REF_COUNT); | ||
1989 | val &= ~((u32)0x1 << (adapter->portnum * 4)); | ||
1990 | QLCWR32(adapter, QLCNIC_CRB_DEV_REF_COUNT, val); | ||
1991 | |||
1992 | if (!(val & 0x11111111)) | ||
1993 | QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_COLD); | ||
1994 | |||
1995 | val = QLCRD32(adapter, QLCNIC_CRB_DRV_STATE); | ||
1996 | val &= ~((u32)0x3 << (adapter->portnum * 4)); | ||
1997 | QLCWR32(adapter, QLCNIC_CRB_DRV_STATE, val); | ||
1998 | |||
1999 | qlcnic_api_unlock(adapter); | ||
2000 | err: | ||
2001 | adapter->fw_fail_cnt = 0; | ||
2002 | clear_bit(__QLCNIC_START_FW, &adapter->state); | ||
2003 | clear_bit(__QLCNIC_RESETTING, &adapter->state); | ||
2004 | } | ||
2005 | |||
2006 | static int | ||
2007 | qlcnic_check_drv_state(struct qlcnic_adapter *adapter) | ||
2008 | { | ||
2009 | int act, state; | ||
2010 | |||
2011 | state = QLCRD32(adapter, QLCNIC_CRB_DRV_STATE); | ||
2012 | act = QLCRD32(adapter, QLCNIC_CRB_DEV_REF_COUNT); | ||
2013 | |||
2014 | if (((state & 0x11111111) == (act & 0x11111111)) || | ||
2015 | ((act & 0x11111111) == ((state >> 1) & 0x11111111))) | ||
2016 | return 0; | ||
2017 | else | ||
2018 | return 1; | ||
2019 | } | ||
2020 | |||
2021 | static int | ||
2022 | qlcnic_can_start_firmware(struct qlcnic_adapter *adapter) | ||
2023 | { | ||
2024 | u32 val, prev_state; | ||
2025 | int cnt = 0; | ||
2026 | int portnum = adapter->portnum; | ||
2027 | |||
2028 | if (qlcnic_api_lock(adapter)) | ||
2029 | return -1; | ||
2030 | |||
2031 | val = QLCRD32(adapter, QLCNIC_CRB_DEV_REF_COUNT); | ||
2032 | if (!(val & ((int)0x1 << (portnum * 4)))) { | ||
2033 | val |= ((u32)0x1 << (portnum * 4)); | ||
2034 | QLCWR32(adapter, QLCNIC_CRB_DEV_REF_COUNT, val); | ||
2035 | } else if (test_and_clear_bit(__QLCNIC_START_FW, &adapter->state)) { | ||
2036 | goto start_fw; | ||
2037 | } | ||
2038 | |||
2039 | prev_state = QLCRD32(adapter, QLCNIC_CRB_DEV_STATE); | ||
2040 | |||
2041 | switch (prev_state) { | ||
2042 | case QLCNIC_DEV_COLD: | ||
2043 | start_fw: | ||
2044 | QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_INITALIZING); | ||
2045 | qlcnic_api_unlock(adapter); | ||
2046 | return 1; | ||
2047 | |||
2048 | case QLCNIC_DEV_READY: | ||
2049 | qlcnic_api_unlock(adapter); | ||
2050 | return 0; | ||
2051 | |||
2052 | case QLCNIC_DEV_NEED_RESET: | ||
2053 | val = QLCRD32(adapter, QLCNIC_CRB_DRV_STATE); | ||
2054 | val |= ((u32)0x1 << (portnum * 4)); | ||
2055 | QLCWR32(adapter, QLCNIC_CRB_DRV_STATE, val); | ||
2056 | break; | ||
2057 | |||
2058 | case QLCNIC_DEV_NEED_QUISCENT: | ||
2059 | val = QLCRD32(adapter, QLCNIC_CRB_DRV_STATE); | ||
2060 | val |= ((u32)0x1 << ((portnum * 4) + 1)); | ||
2061 | QLCWR32(adapter, QLCNIC_CRB_DRV_STATE, val); | ||
2062 | break; | ||
2063 | |||
2064 | case QLCNIC_DEV_FAILED: | ||
2065 | qlcnic_api_unlock(adapter); | ||
2066 | return -1; | ||
2067 | } | ||
2068 | |||
2069 | qlcnic_api_unlock(adapter); | ||
2070 | msleep(1000); | ||
2071 | while ((QLCRD32(adapter, QLCNIC_CRB_DEV_STATE) != QLCNIC_DEV_READY) && | ||
2072 | ++cnt < 20) | ||
2073 | msleep(1000); | ||
2074 | |||
2075 | if (cnt >= 20) | ||
2076 | return -1; | ||
2077 | |||
2078 | if (qlcnic_api_lock(adapter)) | ||
2079 | return -1; | ||
2080 | |||
2081 | val = QLCRD32(adapter, QLCNIC_CRB_DRV_STATE); | ||
2082 | val &= ~((u32)0x3 << (portnum * 4)); | ||
2083 | QLCWR32(adapter, QLCNIC_CRB_DRV_STATE, val); | ||
2084 | |||
2085 | qlcnic_api_unlock(adapter); | ||
2086 | |||
2087 | return 0; | ||
2088 | } | ||
2089 | |||
2090 | static void | ||
2091 | qlcnic_fwinit_work(struct work_struct *work) | ||
2092 | { | ||
2093 | struct qlcnic_adapter *adapter = container_of(work, | ||
2094 | struct qlcnic_adapter, fw_work.work); | ||
2095 | int dev_state; | ||
2096 | |||
2097 | if (++adapter->fw_wait_cnt > FW_POLL_THRESH) | ||
2098 | goto err_ret; | ||
2099 | |||
2100 | if (test_bit(__QLCNIC_START_FW, &adapter->state)) { | ||
2101 | |||
2102 | if (qlcnic_check_drv_state(adapter)) { | ||
2103 | qlcnic_schedule_work(adapter, | ||
2104 | qlcnic_fwinit_work, FW_POLL_DELAY); | ||
2105 | return; | ||
2106 | } | ||
2107 | |||
2108 | if (!qlcnic_start_firmware(adapter)) { | ||
2109 | qlcnic_schedule_work(adapter, qlcnic_attach_work, 0); | ||
2110 | return; | ||
2111 | } | ||
2112 | |||
2113 | goto err_ret; | ||
2114 | } | ||
2115 | |||
2116 | dev_state = QLCRD32(adapter, QLCNIC_CRB_DEV_STATE); | ||
2117 | switch (dev_state) { | ||
2118 | case QLCNIC_DEV_READY: | ||
2119 | if (!qlcnic_start_firmware(adapter)) { | ||
2120 | qlcnic_schedule_work(adapter, qlcnic_attach_work, 0); | ||
2121 | return; | ||
2122 | } | ||
2123 | case QLCNIC_DEV_FAILED: | ||
2124 | break; | ||
2125 | |||
2126 | default: | ||
2127 | qlcnic_schedule_work(adapter, | ||
2128 | qlcnic_fwinit_work, 2 * FW_POLL_DELAY); | ||
2129 | return; | ||
2130 | } | ||
2131 | |||
2132 | err_ret: | ||
2133 | qlcnic_clr_all_drv_state(adapter); | ||
2134 | } | ||
2135 | |||
2136 | static void | ||
2137 | qlcnic_detach_work(struct work_struct *work) | ||
2138 | { | ||
2139 | struct qlcnic_adapter *adapter = container_of(work, | ||
2140 | struct qlcnic_adapter, fw_work.work); | ||
2141 | struct net_device *netdev = adapter->netdev; | ||
2142 | u32 status; | ||
2143 | |||
2144 | netif_device_detach(netdev); | ||
2145 | |||
2146 | qlcnic_down(adapter, netdev); | ||
2147 | |||
2148 | rtnl_lock(); | ||
2149 | qlcnic_detach(adapter); | ||
2150 | rtnl_unlock(); | ||
2151 | |||
2152 | status = QLCRD32(adapter, QLCNIC_PEG_HALT_STATUS1); | ||
2153 | |||
2154 | if (status & QLCNIC_RCODE_FATAL_ERROR) | ||
2155 | goto err_ret; | ||
2156 | |||
2157 | if (adapter->temp == QLCNIC_TEMP_PANIC) | ||
2158 | goto err_ret; | ||
2159 | |||
2160 | qlcnic_set_drv_state(adapter, adapter->dev_state); | ||
2161 | |||
2162 | adapter->fw_wait_cnt = 0; | ||
2163 | |||
2164 | qlcnic_schedule_work(adapter, qlcnic_fwinit_work, FW_POLL_DELAY); | ||
2165 | |||
2166 | return; | ||
2167 | |||
2168 | err_ret: | ||
2169 | qlcnic_clr_all_drv_state(adapter); | ||
2170 | |||
2171 | } | ||
2172 | |||
2173 | static void | ||
2174 | qlcnic_dev_request_reset(struct qlcnic_adapter *adapter) | ||
2175 | { | ||
2176 | u32 state; | ||
2177 | |||
2178 | if (qlcnic_api_lock(adapter)) | ||
2179 | return; | ||
2180 | |||
2181 | state = QLCRD32(adapter, QLCNIC_CRB_DEV_STATE); | ||
2182 | |||
2183 | if (state != QLCNIC_DEV_INITALIZING && state != QLCNIC_DEV_NEED_RESET) { | ||
2184 | QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_NEED_RESET); | ||
2185 | set_bit(__QLCNIC_START_FW, &adapter->state); | ||
2186 | } | ||
2187 | |||
2188 | qlcnic_api_unlock(adapter); | ||
2189 | } | ||
2190 | |||
2191 | static void | ||
2192 | qlcnic_schedule_work(struct qlcnic_adapter *adapter, | ||
2193 | work_func_t func, int delay) | ||
2194 | { | ||
2195 | INIT_DELAYED_WORK(&adapter->fw_work, func); | ||
2196 | schedule_delayed_work(&adapter->fw_work, round_jiffies_relative(delay)); | ||
2197 | } | ||
2198 | |||
2199 | static void | ||
2200 | qlcnic_cancel_fw_work(struct qlcnic_adapter *adapter) | ||
2201 | { | ||
2202 | while (test_and_set_bit(__QLCNIC_RESETTING, &adapter->state)) | ||
2203 | msleep(10); | ||
2204 | |||
2205 | cancel_delayed_work_sync(&adapter->fw_work); | ||
2206 | } | ||
2207 | |||
2208 | static void | ||
2209 | qlcnic_attach_work(struct work_struct *work) | ||
2210 | { | ||
2211 | struct qlcnic_adapter *adapter = container_of(work, | ||
2212 | struct qlcnic_adapter, fw_work.work); | ||
2213 | struct net_device *netdev = adapter->netdev; | ||
2214 | int err; | ||
2215 | |||
2216 | if (netif_running(netdev)) { | ||
2217 | err = qlcnic_attach(adapter); | ||
2218 | if (err) | ||
2219 | goto done; | ||
2220 | |||
2221 | err = qlcnic_up(adapter, netdev); | ||
2222 | if (err) { | ||
2223 | qlcnic_detach(adapter); | ||
2224 | goto done; | ||
2225 | } | ||
2226 | |||
2227 | qlcnic_config_indev_addr(netdev, NETDEV_UP); | ||
2228 | } | ||
2229 | |||
2230 | netif_device_attach(netdev); | ||
2231 | |||
2232 | done: | ||
2233 | adapter->fw_fail_cnt = 0; | ||
2234 | clear_bit(__QLCNIC_RESETTING, &adapter->state); | ||
2235 | |||
2236 | if (!qlcnic_clr_drv_state(adapter)) | ||
2237 | qlcnic_schedule_work(adapter, qlcnic_fw_poll_work, | ||
2238 | FW_POLL_DELAY); | ||
2239 | } | ||
2240 | |||
2241 | static int | ||
2242 | qlcnic_check_health(struct qlcnic_adapter *adapter) | ||
2243 | { | ||
2244 | u32 state = 0, heartbit; | ||
2245 | struct net_device *netdev = adapter->netdev; | ||
2246 | |||
2247 | if (qlcnic_check_temp(adapter)) | ||
2248 | goto detach; | ||
2249 | |||
2250 | if (adapter->need_fw_reset) { | ||
2251 | qlcnic_dev_request_reset(adapter); | ||
2252 | goto detach; | ||
2253 | } | ||
2254 | |||
2255 | state = QLCRD32(adapter, QLCNIC_CRB_DEV_STATE); | ||
2256 | if (state == QLCNIC_DEV_NEED_RESET || state == QLCNIC_DEV_NEED_QUISCENT) | ||
2257 | adapter->need_fw_reset = 1; | ||
2258 | |||
2259 | heartbit = QLCRD32(adapter, QLCNIC_PEG_ALIVE_COUNTER); | ||
2260 | if (heartbit != adapter->heartbit) { | ||
2261 | adapter->heartbit = heartbit; | ||
2262 | adapter->fw_fail_cnt = 0; | ||
2263 | if (adapter->need_fw_reset) | ||
2264 | goto detach; | ||
2265 | return 0; | ||
2266 | } | ||
2267 | |||
2268 | if (++adapter->fw_fail_cnt < FW_FAIL_THRESH) | ||
2269 | return 0; | ||
2270 | |||
2271 | qlcnic_dev_request_reset(adapter); | ||
2272 | |||
2273 | clear_bit(__QLCNIC_FW_ATTACHED, &adapter->state); | ||
2274 | |||
2275 | dev_info(&netdev->dev, "firmware hang detected\n"); | ||
2276 | |||
2277 | detach: | ||
2278 | adapter->dev_state = (state == QLCNIC_DEV_NEED_QUISCENT) ? state : | ||
2279 | QLCNIC_DEV_NEED_RESET; | ||
2280 | |||
2281 | if ((auto_fw_reset == AUTO_FW_RESET_ENABLED) && | ||
2282 | !test_and_set_bit(__QLCNIC_RESETTING, &adapter->state)) | ||
2283 | qlcnic_schedule_work(adapter, qlcnic_detach_work, 0); | ||
2284 | |||
2285 | return 1; | ||
2286 | } | ||
2287 | |||
2288 | static void | ||
2289 | qlcnic_fw_poll_work(struct work_struct *work) | ||
2290 | { | ||
2291 | struct qlcnic_adapter *adapter = container_of(work, | ||
2292 | struct qlcnic_adapter, fw_work.work); | ||
2293 | |||
2294 | if (test_bit(__QLCNIC_RESETTING, &adapter->state)) | ||
2295 | goto reschedule; | ||
2296 | |||
2297 | |||
2298 | if (qlcnic_check_health(adapter)) | ||
2299 | return; | ||
2300 | |||
2301 | reschedule: | ||
2302 | qlcnic_schedule_work(adapter, qlcnic_fw_poll_work, FW_POLL_DELAY); | ||
2303 | } | ||
2304 | |||
2305 | static ssize_t | ||
2306 | qlcnic_store_bridged_mode(struct device *dev, | ||
2307 | struct device_attribute *attr, const char *buf, size_t len) | ||
2308 | { | ||
2309 | struct qlcnic_adapter *adapter = dev_get_drvdata(dev); | ||
2310 | unsigned long new; | ||
2311 | int ret = -EINVAL; | ||
2312 | |||
2313 | if (!(adapter->capabilities & QLCNIC_FW_CAPABILITY_BDG)) | ||
2314 | goto err_out; | ||
2315 | |||
2316 | if (adapter->is_up != QLCNIC_ADAPTER_UP_MAGIC) | ||
2317 | goto err_out; | ||
2318 | |||
2319 | if (strict_strtoul(buf, 2, &new)) | ||
2320 | goto err_out; | ||
2321 | |||
2322 | if (!qlcnic_config_bridged_mode(adapter, !!new)) | ||
2323 | ret = len; | ||
2324 | |||
2325 | err_out: | ||
2326 | return ret; | ||
2327 | } | ||
2328 | |||
2329 | static ssize_t | ||
2330 | qlcnic_show_bridged_mode(struct device *dev, | ||
2331 | struct device_attribute *attr, char *buf) | ||
2332 | { | ||
2333 | struct qlcnic_adapter *adapter = dev_get_drvdata(dev); | ||
2334 | int bridged_mode = 0; | ||
2335 | |||
2336 | if (adapter->capabilities & QLCNIC_FW_CAPABILITY_BDG) | ||
2337 | bridged_mode = !!(adapter->flags & QLCNIC_BRIDGE_ENABLED); | ||
2338 | |||
2339 | return sprintf(buf, "%d\n", bridged_mode); | ||
2340 | } | ||
2341 | |||
2342 | static struct device_attribute dev_attr_bridged_mode = { | ||
2343 | .attr = {.name = "bridged_mode", .mode = (S_IRUGO | S_IWUSR)}, | ||
2344 | .show = qlcnic_show_bridged_mode, | ||
2345 | .store = qlcnic_store_bridged_mode, | ||
2346 | }; | ||
2347 | |||
2348 | static ssize_t | ||
2349 | qlcnic_store_diag_mode(struct device *dev, | ||
2350 | struct device_attribute *attr, const char *buf, size_t len) | ||
2351 | { | ||
2352 | struct qlcnic_adapter *adapter = dev_get_drvdata(dev); | ||
2353 | unsigned long new; | ||
2354 | |||
2355 | if (strict_strtoul(buf, 2, &new)) | ||
2356 | return -EINVAL; | ||
2357 | |||
2358 | if (!!new != !!(adapter->flags & QLCNIC_DIAG_ENABLED)) | ||
2359 | adapter->flags ^= QLCNIC_DIAG_ENABLED; | ||
2360 | |||
2361 | return len; | ||
2362 | } | ||
2363 | |||
2364 | static ssize_t | ||
2365 | qlcnic_show_diag_mode(struct device *dev, | ||
2366 | struct device_attribute *attr, char *buf) | ||
2367 | { | ||
2368 | struct qlcnic_adapter *adapter = dev_get_drvdata(dev); | ||
2369 | |||
2370 | return sprintf(buf, "%d\n", | ||
2371 | !!(adapter->flags & QLCNIC_DIAG_ENABLED)); | ||
2372 | } | ||
2373 | |||
2374 | static struct device_attribute dev_attr_diag_mode = { | ||
2375 | .attr = {.name = "diag_mode", .mode = (S_IRUGO | S_IWUSR)}, | ||
2376 | .show = qlcnic_show_diag_mode, | ||
2377 | .store = qlcnic_store_diag_mode, | ||
2378 | }; | ||
2379 | |||
2380 | static int | ||
2381 | qlcnic_sysfs_validate_crb(struct qlcnic_adapter *adapter, | ||
2382 | loff_t offset, size_t size) | ||
2383 | { | ||
2384 | if (!(adapter->flags & QLCNIC_DIAG_ENABLED)) | ||
2385 | return -EIO; | ||
2386 | |||
2387 | if ((size != 4) || (offset & 0x3)) | ||
2388 | return -EINVAL; | ||
2389 | |||
2390 | if (offset < QLCNIC_PCI_CRBSPACE) | ||
2391 | return -EINVAL; | ||
2392 | |||
2393 | return 0; | ||
2394 | } | ||
2395 | |||
2396 | static ssize_t | ||
2397 | qlcnic_sysfs_read_crb(struct kobject *kobj, struct bin_attribute *attr, | ||
2398 | char *buf, loff_t offset, size_t size) | ||
2399 | { | ||
2400 | struct device *dev = container_of(kobj, struct device, kobj); | ||
2401 | struct qlcnic_adapter *adapter = dev_get_drvdata(dev); | ||
2402 | u32 data; | ||
2403 | int ret; | ||
2404 | |||
2405 | ret = qlcnic_sysfs_validate_crb(adapter, offset, size); | ||
2406 | if (ret != 0) | ||
2407 | return ret; | ||
2408 | |||
2409 | data = QLCRD32(adapter, offset); | ||
2410 | memcpy(buf, &data, size); | ||
2411 | return size; | ||
2412 | } | ||
2413 | |||
2414 | static ssize_t | ||
2415 | qlcnic_sysfs_write_crb(struct kobject *kobj, struct bin_attribute *attr, | ||
2416 | char *buf, loff_t offset, size_t size) | ||
2417 | { | ||
2418 | struct device *dev = container_of(kobj, struct device, kobj); | ||
2419 | struct qlcnic_adapter *adapter = dev_get_drvdata(dev); | ||
2420 | u32 data; | ||
2421 | int ret; | ||
2422 | |||
2423 | ret = qlcnic_sysfs_validate_crb(adapter, offset, size); | ||
2424 | if (ret != 0) | ||
2425 | return ret; | ||
2426 | |||
2427 | memcpy(&data, buf, size); | ||
2428 | QLCWR32(adapter, offset, data); | ||
2429 | return size; | ||
2430 | } | ||
2431 | |||
2432 | static int | ||
2433 | qlcnic_sysfs_validate_mem(struct qlcnic_adapter *adapter, | ||
2434 | loff_t offset, size_t size) | ||
2435 | { | ||
2436 | if (!(adapter->flags & QLCNIC_DIAG_ENABLED)) | ||
2437 | return -EIO; | ||
2438 | |||
2439 | if ((size != 8) || (offset & 0x7)) | ||
2440 | return -EIO; | ||
2441 | |||
2442 | return 0; | ||
2443 | } | ||
2444 | |||
2445 | static ssize_t | ||
2446 | qlcnic_sysfs_read_mem(struct kobject *kobj, struct bin_attribute *attr, | ||
2447 | char *buf, loff_t offset, size_t size) | ||
2448 | { | ||
2449 | struct device *dev = container_of(kobj, struct device, kobj); | ||
2450 | struct qlcnic_adapter *adapter = dev_get_drvdata(dev); | ||
2451 | u64 data; | ||
2452 | int ret; | ||
2453 | |||
2454 | ret = qlcnic_sysfs_validate_mem(adapter, offset, size); | ||
2455 | if (ret != 0) | ||
2456 | return ret; | ||
2457 | |||
2458 | if (qlcnic_pci_mem_read_2M(adapter, offset, &data)) | ||
2459 | return -EIO; | ||
2460 | |||
2461 | memcpy(buf, &data, size); | ||
2462 | |||
2463 | return size; | ||
2464 | } | ||
2465 | |||
2466 | static ssize_t | ||
2467 | qlcnic_sysfs_write_mem(struct kobject *kobj, struct bin_attribute *attr, | ||
2468 | char *buf, loff_t offset, size_t size) | ||
2469 | { | ||
2470 | struct device *dev = container_of(kobj, struct device, kobj); | ||
2471 | struct qlcnic_adapter *adapter = dev_get_drvdata(dev); | ||
2472 | u64 data; | ||
2473 | int ret; | ||
2474 | |||
2475 | ret = qlcnic_sysfs_validate_mem(adapter, offset, size); | ||
2476 | if (ret != 0) | ||
2477 | return ret; | ||
2478 | |||
2479 | memcpy(&data, buf, size); | ||
2480 | |||
2481 | if (qlcnic_pci_mem_write_2M(adapter, offset, data)) | ||
2482 | return -EIO; | ||
2483 | |||
2484 | return size; | ||
2485 | } | ||
2486 | |||
2487 | |||
2488 | static struct bin_attribute bin_attr_crb = { | ||
2489 | .attr = {.name = "crb", .mode = (S_IRUGO | S_IWUSR)}, | ||
2490 | .size = 0, | ||
2491 | .read = qlcnic_sysfs_read_crb, | ||
2492 | .write = qlcnic_sysfs_write_crb, | ||
2493 | }; | ||
2494 | |||
2495 | static struct bin_attribute bin_attr_mem = { | ||
2496 | .attr = {.name = "mem", .mode = (S_IRUGO | S_IWUSR)}, | ||
2497 | .size = 0, | ||
2498 | .read = qlcnic_sysfs_read_mem, | ||
2499 | .write = qlcnic_sysfs_write_mem, | ||
2500 | }; | ||
2501 | |||
2502 | static void | ||
2503 | qlcnic_create_sysfs_entries(struct qlcnic_adapter *adapter) | ||
2504 | { | ||
2505 | struct device *dev = &adapter->pdev->dev; | ||
2506 | |||
2507 | if (adapter->capabilities & QLCNIC_FW_CAPABILITY_BDG) | ||
2508 | if (device_create_file(dev, &dev_attr_bridged_mode)) | ||
2509 | dev_warn(dev, | ||
2510 | "failed to create bridged_mode sysfs entry\n"); | ||
2511 | } | ||
2512 | |||
2513 | static void | ||
2514 | qlcnic_remove_sysfs_entries(struct qlcnic_adapter *adapter) | ||
2515 | { | ||
2516 | struct device *dev = &adapter->pdev->dev; | ||
2517 | |||
2518 | if (adapter->capabilities & QLCNIC_FW_CAPABILITY_BDG) | ||
2519 | device_remove_file(dev, &dev_attr_bridged_mode); | ||
2520 | } | ||
2521 | |||
2522 | static void | ||
2523 | qlcnic_create_diag_entries(struct qlcnic_adapter *adapter) | ||
2524 | { | ||
2525 | struct device *dev = &adapter->pdev->dev; | ||
2526 | |||
2527 | if (device_create_file(dev, &dev_attr_diag_mode)) | ||
2528 | dev_info(dev, "failed to create diag_mode sysfs entry\n"); | ||
2529 | if (device_create_bin_file(dev, &bin_attr_crb)) | ||
2530 | dev_info(dev, "failed to create crb sysfs entry\n"); | ||
2531 | if (device_create_bin_file(dev, &bin_attr_mem)) | ||
2532 | dev_info(dev, "failed to create mem sysfs entry\n"); | ||
2533 | } | ||
2534 | |||
2535 | |||
2536 | static void | ||
2537 | qlcnic_remove_diag_entries(struct qlcnic_adapter *adapter) | ||
2538 | { | ||
2539 | struct device *dev = &adapter->pdev->dev; | ||
2540 | |||
2541 | device_remove_file(dev, &dev_attr_diag_mode); | ||
2542 | device_remove_bin_file(dev, &bin_attr_crb); | ||
2543 | device_remove_bin_file(dev, &bin_attr_mem); | ||
2544 | } | ||
2545 | |||
2546 | #ifdef CONFIG_INET | ||
2547 | |||
2548 | #define is_qlcnic_netdev(dev) (dev->netdev_ops == &qlcnic_netdev_ops) | ||
2549 | |||
2550 | static int | ||
2551 | qlcnic_destip_supported(struct qlcnic_adapter *adapter) | ||
2552 | { | ||
2553 | if (adapter->ahw.cut_through) | ||
2554 | return 0; | ||
2555 | |||
2556 | return 1; | ||
2557 | } | ||
2558 | |||
2559 | static void | ||
2560 | qlcnic_config_indev_addr(struct net_device *dev, unsigned long event) | ||
2561 | { | ||
2562 | struct in_device *indev; | ||
2563 | struct qlcnic_adapter *adapter = netdev_priv(dev); | ||
2564 | |||
2565 | if (!qlcnic_destip_supported(adapter)) | ||
2566 | return; | ||
2567 | |||
2568 | indev = in_dev_get(dev); | ||
2569 | if (!indev) | ||
2570 | return; | ||
2571 | |||
2572 | for_ifa(indev) { | ||
2573 | switch (event) { | ||
2574 | case NETDEV_UP: | ||
2575 | qlcnic_config_ipaddr(adapter, | ||
2576 | ifa->ifa_address, QLCNIC_IP_UP); | ||
2577 | break; | ||
2578 | case NETDEV_DOWN: | ||
2579 | qlcnic_config_ipaddr(adapter, | ||
2580 | ifa->ifa_address, QLCNIC_IP_DOWN); | ||
2581 | break; | ||
2582 | default: | ||
2583 | break; | ||
2584 | } | ||
2585 | } endfor_ifa(indev); | ||
2586 | |||
2587 | in_dev_put(indev); | ||
2588 | return; | ||
2589 | } | ||
2590 | |||
2591 | static int qlcnic_netdev_event(struct notifier_block *this, | ||
2592 | unsigned long event, void *ptr) | ||
2593 | { | ||
2594 | struct qlcnic_adapter *adapter; | ||
2595 | struct net_device *dev = (struct net_device *)ptr; | ||
2596 | |||
2597 | recheck: | ||
2598 | if (dev == NULL) | ||
2599 | goto done; | ||
2600 | |||
2601 | if (dev->priv_flags & IFF_802_1Q_VLAN) { | ||
2602 | dev = vlan_dev_real_dev(dev); | ||
2603 | goto recheck; | ||
2604 | } | ||
2605 | |||
2606 | if (!is_qlcnic_netdev(dev)) | ||
2607 | goto done; | ||
2608 | |||
2609 | adapter = netdev_priv(dev); | ||
2610 | |||
2611 | if (!adapter) | ||
2612 | goto done; | ||
2613 | |||
2614 | if (adapter->is_up != QLCNIC_ADAPTER_UP_MAGIC) | ||
2615 | goto done; | ||
2616 | |||
2617 | qlcnic_config_indev_addr(dev, event); | ||
2618 | done: | ||
2619 | return NOTIFY_DONE; | ||
2620 | } | ||
2621 | |||
2622 | static int | ||
2623 | qlcnic_inetaddr_event(struct notifier_block *this, | ||
2624 | unsigned long event, void *ptr) | ||
2625 | { | ||
2626 | struct qlcnic_adapter *adapter; | ||
2627 | struct net_device *dev; | ||
2628 | |||
2629 | struct in_ifaddr *ifa = (struct in_ifaddr *)ptr; | ||
2630 | |||
2631 | dev = ifa->ifa_dev ? ifa->ifa_dev->dev : NULL; | ||
2632 | |||
2633 | recheck: | ||
2634 | if (dev == NULL || !netif_running(dev)) | ||
2635 | goto done; | ||
2636 | |||
2637 | if (dev->priv_flags & IFF_802_1Q_VLAN) { | ||
2638 | dev = vlan_dev_real_dev(dev); | ||
2639 | goto recheck; | ||
2640 | } | ||
2641 | |||
2642 | if (!is_qlcnic_netdev(dev)) | ||
2643 | goto done; | ||
2644 | |||
2645 | adapter = netdev_priv(dev); | ||
2646 | |||
2647 | if (!adapter || !qlcnic_destip_supported(adapter)) | ||
2648 | goto done; | ||
2649 | |||
2650 | if (adapter->is_up != QLCNIC_ADAPTER_UP_MAGIC) | ||
2651 | goto done; | ||
2652 | |||
2653 | switch (event) { | ||
2654 | case NETDEV_UP: | ||
2655 | qlcnic_config_ipaddr(adapter, ifa->ifa_address, QLCNIC_IP_UP); | ||
2656 | break; | ||
2657 | case NETDEV_DOWN: | ||
2658 | qlcnic_config_ipaddr(adapter, ifa->ifa_address, QLCNIC_IP_DOWN); | ||
2659 | break; | ||
2660 | default: | ||
2661 | break; | ||
2662 | } | ||
2663 | |||
2664 | done: | ||
2665 | return NOTIFY_DONE; | ||
2666 | } | ||
2667 | |||
2668 | static struct notifier_block qlcnic_netdev_cb = { | ||
2669 | .notifier_call = qlcnic_netdev_event, | ||
2670 | }; | ||
2671 | |||
2672 | static struct notifier_block qlcnic_inetaddr_cb = { | ||
2673 | .notifier_call = qlcnic_inetaddr_event, | ||
2674 | }; | ||
2675 | #else | ||
2676 | static void | ||
2677 | qlcnic_config_indev_addr(struct net_device *dev, unsigned long event) | ||
2678 | { } | ||
2679 | #endif | ||
2680 | |||
2681 | static struct pci_driver qlcnic_driver = { | ||
2682 | .name = qlcnic_driver_name, | ||
2683 | .id_table = qlcnic_pci_tbl, | ||
2684 | .probe = qlcnic_probe, | ||
2685 | .remove = __devexit_p(qlcnic_remove), | ||
2686 | #ifdef CONFIG_PM | ||
2687 | .suspend = qlcnic_suspend, | ||
2688 | .resume = qlcnic_resume, | ||
2689 | #endif | ||
2690 | .shutdown = qlcnic_shutdown | ||
2691 | }; | ||
2692 | |||
2693 | static int __init qlcnic_init_module(void) | ||
2694 | { | ||
2695 | |||
2696 | printk(KERN_INFO "%s\n", qlcnic_driver_string); | ||
2697 | |||
2698 | #ifdef CONFIG_INET | ||
2699 | register_netdevice_notifier(&qlcnic_netdev_cb); | ||
2700 | register_inetaddr_notifier(&qlcnic_inetaddr_cb); | ||
2701 | #endif | ||
2702 | |||
2703 | |||
2704 | return pci_register_driver(&qlcnic_driver); | ||
2705 | } | ||
2706 | |||
2707 | module_init(qlcnic_init_module); | ||
2708 | |||
2709 | static void __exit qlcnic_exit_module(void) | ||
2710 | { | ||
2711 | |||
2712 | pci_unregister_driver(&qlcnic_driver); | ||
2713 | |||
2714 | #ifdef CONFIG_INET | ||
2715 | unregister_inetaddr_notifier(&qlcnic_inetaddr_cb); | ||
2716 | unregister_netdevice_notifier(&qlcnic_netdev_cb); | ||
2717 | #endif | ||
2718 | } | ||
2719 | |||
2720 | module_exit(qlcnic_exit_module); | ||