diff options
Diffstat (limited to 'drivers/net/netxen/netxen_nic_main.c')
-rw-r--r-- | drivers/net/netxen/netxen_nic_main.c | 1169 |
1 files changed, 785 insertions, 384 deletions
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index 63cd67b931e7..91d209a8f6cb 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c | |||
@@ -49,13 +49,18 @@ char netxen_nic_driver_name[] = "netxen_nic"; | |||
49 | static char netxen_nic_driver_string[] = "NetXen Network Driver version " | 49 | static char netxen_nic_driver_string[] = "NetXen Network Driver version " |
50 | NETXEN_NIC_LINUX_VERSIONID; | 50 | NETXEN_NIC_LINUX_VERSIONID; |
51 | 51 | ||
52 | #define NETXEN_NETDEV_WEIGHT 120 | 52 | static int port_mode = NETXEN_PORT_MODE_AUTO_NEG; |
53 | #define NETXEN_ADAPTER_UP_MAGIC 777 | 53 | |
54 | #define NETXEN_NIC_PEG_TUNE 0 | 54 | /* Default to restricted 1G auto-neg mode */ |
55 | static int wol_port_mode = 5; | ||
56 | |||
57 | static int use_msi = 1; | ||
58 | |||
59 | static int use_msi_x = 1; | ||
55 | 60 | ||
56 | /* Local functions to NetXen NIC driver */ | 61 | /* Local functions to NetXen NIC driver */ |
57 | static int __devinit netxen_nic_probe(struct pci_dev *pdev, | 62 | static int __devinit netxen_nic_probe(struct pci_dev *pdev, |
58 | const struct pci_device_id *ent); | 63 | const struct pci_device_id *ent); |
59 | static void __devexit netxen_nic_remove(struct pci_dev *pdev); | 64 | static void __devexit netxen_nic_remove(struct pci_dev *pdev); |
60 | static int netxen_nic_open(struct net_device *netdev); | 65 | static int netxen_nic_open(struct net_device *netdev); |
61 | static int netxen_nic_close(struct net_device *netdev); | 66 | static int netxen_nic_close(struct net_device *netdev); |
@@ -83,6 +88,7 @@ static struct pci_device_id netxen_pci_tbl[] __devinitdata = { | |||
83 | ENTRY(0x0005), | 88 | ENTRY(0x0005), |
84 | ENTRY(0x0024), | 89 | ENTRY(0x0024), |
85 | ENTRY(0x0025), | 90 | ENTRY(0x0025), |
91 | ENTRY(0x0100), | ||
86 | {0,} | 92 | {0,} |
87 | }; | 93 | }; |
88 | 94 | ||
@@ -108,95 +114,61 @@ static struct workqueue_struct *netxen_workq; | |||
108 | 114 | ||
109 | static void netxen_watchdog(unsigned long); | 115 | static void netxen_watchdog(unsigned long); |
110 | 116 | ||
111 | static void netxen_nic_update_cmd_producer(struct netxen_adapter *adapter, | 117 | static uint32_t crb_cmd_producer[4] = { |
112 | uint32_t crb_producer) | 118 | CRB_CMD_PRODUCER_OFFSET, CRB_CMD_PRODUCER_OFFSET_1, |
119 | CRB_CMD_PRODUCER_OFFSET_2, CRB_CMD_PRODUCER_OFFSET_3 | ||
120 | }; | ||
121 | |||
122 | void | ||
123 | netxen_nic_update_cmd_producer(struct netxen_adapter *adapter, | ||
124 | uint32_t crb_producer) | ||
113 | { | 125 | { |
114 | switch (adapter->portnum) { | 126 | adapter->pci_write_normalize(adapter, |
115 | case 0: | 127 | adapter->crb_addr_cmd_producer, crb_producer); |
116 | writel(crb_producer, NETXEN_CRB_NORMALIZE | ||
117 | (adapter, CRB_CMD_PRODUCER_OFFSET)); | ||
118 | return; | ||
119 | case 1: | ||
120 | writel(crb_producer, NETXEN_CRB_NORMALIZE | ||
121 | (adapter, CRB_CMD_PRODUCER_OFFSET_1)); | ||
122 | return; | ||
123 | case 2: | ||
124 | writel(crb_producer, NETXEN_CRB_NORMALIZE | ||
125 | (adapter, CRB_CMD_PRODUCER_OFFSET_2)); | ||
126 | return; | ||
127 | case 3: | ||
128 | writel(crb_producer, NETXEN_CRB_NORMALIZE | ||
129 | (adapter, CRB_CMD_PRODUCER_OFFSET_3)); | ||
130 | return; | ||
131 | default: | ||
132 | printk(KERN_WARNING "We tried to update " | ||
133 | "CRB_CMD_PRODUCER_OFFSET for invalid " | ||
134 | "PCI function id %d\n", | ||
135 | adapter->portnum); | ||
136 | return; | ||
137 | } | ||
138 | } | 128 | } |
139 | 129 | ||
140 | static void netxen_nic_update_cmd_consumer(struct netxen_adapter *adapter, | 130 | static uint32_t crb_cmd_consumer[4] = { |
141 | u32 crb_consumer) | 131 | CRB_CMD_CONSUMER_OFFSET, CRB_CMD_CONSUMER_OFFSET_1, |
132 | CRB_CMD_CONSUMER_OFFSET_2, CRB_CMD_CONSUMER_OFFSET_3 | ||
133 | }; | ||
134 | |||
135 | static inline void | ||
136 | netxen_nic_update_cmd_consumer(struct netxen_adapter *adapter, | ||
137 | u32 crb_consumer) | ||
142 | { | 138 | { |
143 | switch (adapter->portnum) { | 139 | adapter->pci_write_normalize(adapter, |
144 | case 0: | 140 | adapter->crb_addr_cmd_consumer, crb_consumer); |
145 | writel(crb_consumer, NETXEN_CRB_NORMALIZE | ||
146 | (adapter, CRB_CMD_CONSUMER_OFFSET)); | ||
147 | return; | ||
148 | case 1: | ||
149 | writel(crb_consumer, NETXEN_CRB_NORMALIZE | ||
150 | (adapter, CRB_CMD_CONSUMER_OFFSET_1)); | ||
151 | return; | ||
152 | case 2: | ||
153 | writel(crb_consumer, NETXEN_CRB_NORMALIZE | ||
154 | (adapter, CRB_CMD_CONSUMER_OFFSET_2)); | ||
155 | return; | ||
156 | case 3: | ||
157 | writel(crb_consumer, NETXEN_CRB_NORMALIZE | ||
158 | (adapter, CRB_CMD_CONSUMER_OFFSET_3)); | ||
159 | return; | ||
160 | default: | ||
161 | printk(KERN_WARNING "We tried to update " | ||
162 | "CRB_CMD_PRODUCER_OFFSET for invalid " | ||
163 | "PCI function id %d\n", | ||
164 | adapter->portnum); | ||
165 | return; | ||
166 | } | ||
167 | } | 141 | } |
168 | 142 | ||
169 | #define ADAPTER_LIST_SIZE 12 | 143 | static uint32_t msi_tgt_status[8] = { |
170 | |||
171 | static uint32_t msi_tgt_status[4] = { | ||
172 | ISR_INT_TARGET_STATUS, ISR_INT_TARGET_STATUS_F1, | 144 | ISR_INT_TARGET_STATUS, ISR_INT_TARGET_STATUS_F1, |
173 | ISR_INT_TARGET_STATUS_F2, ISR_INT_TARGET_STATUS_F3 | 145 | ISR_INT_TARGET_STATUS_F2, ISR_INT_TARGET_STATUS_F3, |
146 | ISR_INT_TARGET_STATUS_F4, ISR_INT_TARGET_STATUS_F5, | ||
147 | ISR_INT_TARGET_STATUS_F6, ISR_INT_TARGET_STATUS_F7 | ||
174 | }; | 148 | }; |
175 | 149 | ||
176 | static uint32_t sw_int_mask[4] = { | 150 | static struct netxen_legacy_intr_set legacy_intr[] = NX_LEGACY_INTR_CONFIG; |
177 | CRB_SW_INT_MASK_0, CRB_SW_INT_MASK_1, | ||
178 | CRB_SW_INT_MASK_2, CRB_SW_INT_MASK_3 | ||
179 | }; | ||
180 | 151 | ||
181 | static void netxen_nic_disable_int(struct netxen_adapter *adapter) | 152 | static void netxen_nic_disable_int(struct netxen_adapter *adapter) |
182 | { | 153 | { |
183 | u32 mask = 0x7ff; | 154 | u32 mask = 0x7ff; |
184 | int retries = 32; | 155 | int retries = 32; |
185 | int port = adapter->portnum; | ||
186 | int pci_fn = adapter->ahw.pci_func; | 156 | int pci_fn = adapter->ahw.pci_func; |
187 | 157 | ||
188 | if (adapter->msi_mode != MSI_MODE_MULTIFUNC) | 158 | if (adapter->msi_mode != MSI_MODE_MULTIFUNC) |
189 | writel(0x0, NETXEN_CRB_NORMALIZE(adapter, sw_int_mask[port])); | 159 | adapter->pci_write_normalize(adapter, |
160 | adapter->crb_intr_mask, 0); | ||
190 | 161 | ||
191 | if (adapter->intr_scheme != -1 && | 162 | if (adapter->intr_scheme != -1 && |
192 | adapter->intr_scheme != INTR_SCHEME_PERPORT) | 163 | adapter->intr_scheme != INTR_SCHEME_PERPORT) |
193 | writel(mask,PCI_OFFSET_SECOND_RANGE(adapter, ISR_INT_MASK)); | 164 | adapter->pci_write_immediate(adapter, ISR_INT_MASK, mask); |
194 | 165 | ||
195 | if (!(adapter->flags & NETXEN_NIC_MSI_ENABLED)) { | 166 | if (!NETXEN_IS_MSI_FAMILY(adapter)) { |
196 | do { | 167 | do { |
197 | writel(0xffffffff, | 168 | adapter->pci_write_immediate(adapter, |
198 | PCI_OFFSET_SECOND_RANGE(adapter, ISR_INT_TARGET_STATUS)); | 169 | ISR_INT_TARGET_STATUS, 0xffffffff); |
199 | mask = readl(pci_base_offset(adapter, ISR_INT_VECTOR)); | 170 | mask = adapter->pci_read_immediate(adapter, |
171 | ISR_INT_VECTOR); | ||
200 | if (!(mask & 0x80)) | 172 | if (!(mask & 0x80)) |
201 | break; | 173 | break; |
202 | udelay(10); | 174 | udelay(10); |
@@ -208,8 +180,8 @@ static void netxen_nic_disable_int(struct netxen_adapter *adapter) | |||
208 | } | 180 | } |
209 | } else { | 181 | } else { |
210 | if (adapter->msi_mode == MSI_MODE_MULTIFUNC) { | 182 | if (adapter->msi_mode == MSI_MODE_MULTIFUNC) { |
211 | writel(0xffffffff, PCI_OFFSET_SECOND_RANGE(adapter, | 183 | adapter->pci_write_immediate(adapter, |
212 | msi_tgt_status[pci_fn])); | 184 | msi_tgt_status[pci_fn], 0xffffffff); |
213 | } | 185 | } |
214 | } | 186 | } |
215 | } | 187 | } |
@@ -217,7 +189,6 @@ static void netxen_nic_disable_int(struct netxen_adapter *adapter) | |||
217 | static void netxen_nic_enable_int(struct netxen_adapter *adapter) | 189 | static void netxen_nic_enable_int(struct netxen_adapter *adapter) |
218 | { | 190 | { |
219 | u32 mask; | 191 | u32 mask; |
220 | int port = adapter->portnum; | ||
221 | 192 | ||
222 | DPRINTK(1, INFO, "Entered ISR Enable \n"); | 193 | DPRINTK(1, INFO, "Entered ISR Enable \n"); |
223 | 194 | ||
@@ -235,24 +206,299 @@ static void netxen_nic_enable_int(struct netxen_adapter *adapter) | |||
235 | break; | 206 | break; |
236 | } | 207 | } |
237 | 208 | ||
238 | writel(mask, PCI_OFFSET_SECOND_RANGE(adapter, ISR_INT_MASK)); | 209 | adapter->pci_write_immediate(adapter, ISR_INT_MASK, mask); |
239 | } | 210 | } |
240 | 211 | ||
241 | writel(0x1, NETXEN_CRB_NORMALIZE(adapter, sw_int_mask[port])); | 212 | adapter->pci_write_normalize(adapter, adapter->crb_intr_mask, 0x1); |
242 | 213 | ||
243 | if (!(adapter->flags & NETXEN_NIC_MSI_ENABLED)) { | 214 | if (!NETXEN_IS_MSI_FAMILY(adapter)) { |
244 | mask = 0xbff; | 215 | mask = 0xbff; |
245 | if (adapter->intr_scheme != -1 && | 216 | if (adapter->intr_scheme != -1 && |
246 | adapter->intr_scheme != INTR_SCHEME_PERPORT) { | 217 | adapter->intr_scheme != INTR_SCHEME_PERPORT) { |
247 | writel(0X0, NETXEN_CRB_NORMALIZE(adapter, CRB_INT_VECTOR)); | 218 | adapter->pci_write_normalize(adapter, |
219 | CRB_INT_VECTOR, 0); | ||
248 | } | 220 | } |
249 | writel(mask, | 221 | adapter->pci_write_immediate(adapter, |
250 | PCI_OFFSET_SECOND_RANGE(adapter, ISR_INT_TARGET_MASK)); | 222 | ISR_INT_TARGET_MASK, mask); |
251 | } | 223 | } |
252 | 224 | ||
253 | DPRINTK(1, INFO, "Done with enable Int\n"); | 225 | DPRINTK(1, INFO, "Done with enable Int\n"); |
254 | } | 226 | } |
255 | 227 | ||
228 | static int nx_set_dma_mask(struct netxen_adapter *adapter, uint8_t revision_id) | ||
229 | { | ||
230 | struct pci_dev *pdev = adapter->pdev; | ||
231 | int err; | ||
232 | uint64_t mask; | ||
233 | |||
234 | #ifdef CONFIG_IA64 | ||
235 | adapter->dma_mask = DMA_32BIT_MASK; | ||
236 | #else | ||
237 | if (revision_id >= NX_P3_B0) { | ||
238 | /* should go to DMA_64BIT_MASK */ | ||
239 | adapter->dma_mask = DMA_39BIT_MASK; | ||
240 | mask = DMA_39BIT_MASK; | ||
241 | } else if (revision_id == NX_P3_A2) { | ||
242 | adapter->dma_mask = DMA_39BIT_MASK; | ||
243 | mask = DMA_39BIT_MASK; | ||
244 | } else if (revision_id == NX_P2_C1) { | ||
245 | adapter->dma_mask = DMA_35BIT_MASK; | ||
246 | mask = DMA_35BIT_MASK; | ||
247 | } else { | ||
248 | adapter->dma_mask = DMA_32BIT_MASK; | ||
249 | mask = DMA_32BIT_MASK; | ||
250 | goto set_32_bit_mask; | ||
251 | } | ||
252 | |||
253 | /* | ||
254 | * Consistent DMA mask is set to 32 bit because it cannot be set to | ||
255 | * 35 bits. For P3 also leave it at 32 bits for now. Only the rings | ||
256 | * come off this pool. | ||
257 | */ | ||
258 | if (pci_set_dma_mask(pdev, mask) == 0 && | ||
259 | pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK) == 0) { | ||
260 | adapter->pci_using_dac = 1; | ||
261 | return 0; | ||
262 | } | ||
263 | #endif /* CONFIG_IA64 */ | ||
264 | |||
265 | set_32_bit_mask: | ||
266 | err = pci_set_dma_mask(pdev, DMA_32BIT_MASK); | ||
267 | if (!err) | ||
268 | err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK); | ||
269 | if (err) { | ||
270 | DPRINTK(ERR, "No usable DMA configuration, aborting:%d\n", err); | ||
271 | return err; | ||
272 | } | ||
273 | |||
274 | adapter->pci_using_dac = 0; | ||
275 | return 0; | ||
276 | } | ||
277 | |||
278 | static void netxen_check_options(struct netxen_adapter *adapter) | ||
279 | { | ||
280 | switch (adapter->ahw.boardcfg.board_type) { | ||
281 | case NETXEN_BRDTYPE_P3_HMEZ: | ||
282 | case NETXEN_BRDTYPE_P3_XG_LOM: | ||
283 | case NETXEN_BRDTYPE_P3_10G_CX4: | ||
284 | case NETXEN_BRDTYPE_P3_10G_CX4_LP: | ||
285 | case NETXEN_BRDTYPE_P3_IMEZ: | ||
286 | case NETXEN_BRDTYPE_P3_10G_SFP_PLUS: | ||
287 | case NETXEN_BRDTYPE_P3_10G_XFP: | ||
288 | case NETXEN_BRDTYPE_P3_10000_BASE_T: | ||
289 | adapter->msix_supported = !!use_msi_x; | ||
290 | adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS_10G; | ||
291 | break; | ||
292 | |||
293 | case NETXEN_BRDTYPE_P2_SB31_10G: | ||
294 | case NETXEN_BRDTYPE_P2_SB31_10G_CX4: | ||
295 | case NETXEN_BRDTYPE_P2_SB31_10G_IMEZ: | ||
296 | case NETXEN_BRDTYPE_P2_SB31_10G_HMEZ: | ||
297 | adapter->msix_supported = 0; | ||
298 | adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS_10G; | ||
299 | break; | ||
300 | |||
301 | case NETXEN_BRDTYPE_P3_REF_QG: | ||
302 | case NETXEN_BRDTYPE_P3_4_GB: | ||
303 | case NETXEN_BRDTYPE_P3_4_GB_MM: | ||
304 | case NETXEN_BRDTYPE_P2_SB35_4G: | ||
305 | case NETXEN_BRDTYPE_P2_SB31_2G: | ||
306 | adapter->msix_supported = 0; | ||
307 | adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS_1G; | ||
308 | break; | ||
309 | |||
310 | default: | ||
311 | adapter->msix_supported = 0; | ||
312 | adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS_1G; | ||
313 | |||
314 | printk(KERN_WARNING "Unknown board type(0x%x)\n", | ||
315 | adapter->ahw.boardcfg.board_type); | ||
316 | break; | ||
317 | } | ||
318 | |||
319 | adapter->max_tx_desc_count = MAX_CMD_DESCRIPTORS_HOST; | ||
320 | adapter->max_jumbo_rx_desc_count = MAX_JUMBO_RCV_DESCRIPTORS; | ||
321 | adapter->max_lro_rx_desc_count = MAX_LRO_RCV_DESCRIPTORS; | ||
322 | |||
323 | adapter->max_possible_rss_rings = 1; | ||
324 | return; | ||
325 | } | ||
326 | |||
327 | static int | ||
328 | netxen_check_hw_init(struct netxen_adapter *adapter, int first_boot) | ||
329 | { | ||
330 | int ret = 0; | ||
331 | |||
332 | if (first_boot == 0x55555555) { | ||
333 | /* This is the first boot after power up */ | ||
334 | |||
335 | /* PCI bus master workaround */ | ||
336 | adapter->hw_read_wx(adapter, | ||
337 | NETXEN_PCIE_REG(0x4), &first_boot, 4); | ||
338 | if (!(first_boot & 0x4)) { | ||
339 | first_boot |= 0x4; | ||
340 | adapter->hw_write_wx(adapter, | ||
341 | NETXEN_PCIE_REG(0x4), &first_boot, 4); | ||
342 | adapter->hw_read_wx(adapter, | ||
343 | NETXEN_PCIE_REG(0x4), &first_boot, 4); | ||
344 | } | ||
345 | |||
346 | /* This is the first boot after power up */ | ||
347 | adapter->hw_read_wx(adapter, | ||
348 | NETXEN_ROMUSB_GLB_SW_RESET, &first_boot, 4); | ||
349 | if (first_boot != 0x80000f) { | ||
350 | /* clear the register for future unloads/loads */ | ||
351 | adapter->pci_write_normalize(adapter, | ||
352 | NETXEN_CAM_RAM(0x1fc), 0); | ||
353 | ret = -1; | ||
354 | } | ||
355 | |||
356 | if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) { | ||
357 | /* Start P2 boot loader */ | ||
358 | adapter->pci_write_normalize(adapter, | ||
359 | NETXEN_CAM_RAM(0x1fc), NETXEN_BDINFO_MAGIC); | ||
360 | adapter->pci_write_normalize(adapter, | ||
361 | NETXEN_ROMUSB_GLB_PEGTUNE_DONE, 1); | ||
362 | } | ||
363 | } | ||
364 | return ret; | ||
365 | } | ||
366 | |||
367 | static void netxen_set_port_mode(struct netxen_adapter *adapter) | ||
368 | { | ||
369 | u32 val, data; | ||
370 | |||
371 | val = adapter->ahw.boardcfg.board_type; | ||
372 | if ((val == NETXEN_BRDTYPE_P3_HMEZ) || | ||
373 | (val == NETXEN_BRDTYPE_P3_XG_LOM)) { | ||
374 | if (port_mode == NETXEN_PORT_MODE_802_3_AP) { | ||
375 | data = NETXEN_PORT_MODE_802_3_AP; | ||
376 | adapter->hw_write_wx(adapter, | ||
377 | NETXEN_PORT_MODE_ADDR, &data, 4); | ||
378 | } else if (port_mode == NETXEN_PORT_MODE_XG) { | ||
379 | data = NETXEN_PORT_MODE_XG; | ||
380 | adapter->hw_write_wx(adapter, | ||
381 | NETXEN_PORT_MODE_ADDR, &data, 4); | ||
382 | } else if (port_mode == NETXEN_PORT_MODE_AUTO_NEG_1G) { | ||
383 | data = NETXEN_PORT_MODE_AUTO_NEG_1G; | ||
384 | adapter->hw_write_wx(adapter, | ||
385 | NETXEN_PORT_MODE_ADDR, &data, 4); | ||
386 | } else if (port_mode == NETXEN_PORT_MODE_AUTO_NEG_XG) { | ||
387 | data = NETXEN_PORT_MODE_AUTO_NEG_XG; | ||
388 | adapter->hw_write_wx(adapter, | ||
389 | NETXEN_PORT_MODE_ADDR, &data, 4); | ||
390 | } else { | ||
391 | data = NETXEN_PORT_MODE_AUTO_NEG; | ||
392 | adapter->hw_write_wx(adapter, | ||
393 | NETXEN_PORT_MODE_ADDR, &data, 4); | ||
394 | } | ||
395 | |||
396 | if ((wol_port_mode != NETXEN_PORT_MODE_802_3_AP) && | ||
397 | (wol_port_mode != NETXEN_PORT_MODE_XG) && | ||
398 | (wol_port_mode != NETXEN_PORT_MODE_AUTO_NEG_1G) && | ||
399 | (wol_port_mode != NETXEN_PORT_MODE_AUTO_NEG_XG)) { | ||
400 | wol_port_mode = NETXEN_PORT_MODE_AUTO_NEG; | ||
401 | } | ||
402 | adapter->hw_write_wx(adapter, NETXEN_WOL_PORT_MODE, | ||
403 | &wol_port_mode, 4); | ||
404 | } | ||
405 | } | ||
406 | |||
407 | #define PCI_CAP_ID_GEN 0x10 | ||
408 | |||
409 | static void netxen_pcie_strap_init(struct netxen_adapter *adapter) | ||
410 | { | ||
411 | u32 pdevfuncsave; | ||
412 | u32 c8c9value = 0; | ||
413 | u32 chicken = 0; | ||
414 | u32 control = 0; | ||
415 | int i, pos; | ||
416 | struct pci_dev *pdev; | ||
417 | |||
418 | pdev = pci_get_device(0x1166, 0x0140, NULL); | ||
419 | if (pdev) { | ||
420 | pci_dev_put(pdev); | ||
421 | adapter->hw_read_wx(adapter, | ||
422 | NETXEN_PCIE_REG(PCIE_TGT_SPLIT_CHICKEN), &chicken, 4); | ||
423 | chicken |= 0x4000; | ||
424 | adapter->hw_write_wx(adapter, | ||
425 | NETXEN_PCIE_REG(PCIE_TGT_SPLIT_CHICKEN), &chicken, 4); | ||
426 | } | ||
427 | |||
428 | pdev = adapter->pdev; | ||
429 | |||
430 | adapter->hw_read_wx(adapter, | ||
431 | NETXEN_PCIE_REG(PCIE_CHICKEN3), &chicken, 4); | ||
432 | /* clear chicken3.25:24 */ | ||
433 | chicken &= 0xFCFFFFFF; | ||
434 | /* | ||
435 | * if gen1 and B0, set F1020 - if gen 2, do nothing | ||
436 | * if gen2 set to F1000 | ||
437 | */ | ||
438 | pos = pci_find_capability(pdev, PCI_CAP_ID_GEN); | ||
439 | if (pos == 0xC0) { | ||
440 | pci_read_config_dword(pdev, pos + 0x10, &control); | ||
441 | if ((control & 0x000F0000) != 0x00020000) { | ||
442 | /* set chicken3.24 if gen1 */ | ||
443 | chicken |= 0x01000000; | ||
444 | } | ||
445 | printk(KERN_INFO "%s Gen2 strapping detected\n", | ||
446 | netxen_nic_driver_name); | ||
447 | c8c9value = 0xF1000; | ||
448 | } else { | ||
449 | /* set chicken3.24 if gen1 */ | ||
450 | chicken |= 0x01000000; | ||
451 | printk(KERN_INFO "%s Gen1 strapping detected\n", | ||
452 | netxen_nic_driver_name); | ||
453 | if (adapter->ahw.revision_id == NX_P3_B0) | ||
454 | c8c9value = 0xF1020; | ||
455 | else | ||
456 | c8c9value = 0; | ||
457 | |||
458 | } | ||
459 | adapter->hw_write_wx(adapter, | ||
460 | NETXEN_PCIE_REG(PCIE_CHICKEN3), &chicken, 4); | ||
461 | |||
462 | if (!c8c9value) | ||
463 | return; | ||
464 | |||
465 | pdevfuncsave = pdev->devfn; | ||
466 | if (pdevfuncsave & 0x07) | ||
467 | return; | ||
468 | |||
469 | for (i = 0; i < 8; i++) { | ||
470 | pci_read_config_dword(pdev, pos + 8, &control); | ||
471 | pci_read_config_dword(pdev, pos + 8, &control); | ||
472 | pci_write_config_dword(pdev, pos + 8, c8c9value); | ||
473 | pdev->devfn++; | ||
474 | } | ||
475 | pdev->devfn = pdevfuncsave; | ||
476 | } | ||
477 | |||
478 | static void netxen_set_msix_bit(struct pci_dev *pdev, int enable) | ||
479 | { | ||
480 | u32 control; | ||
481 | int pos; | ||
482 | |||
483 | pos = pci_find_capability(pdev, PCI_CAP_ID_MSIX); | ||
484 | if (pos) { | ||
485 | pci_read_config_dword(pdev, pos, &control); | ||
486 | if (enable) | ||
487 | control |= PCI_MSIX_FLAGS_ENABLE; | ||
488 | else | ||
489 | control = 0; | ||
490 | pci_write_config_dword(pdev, pos, control); | ||
491 | } | ||
492 | } | ||
493 | |||
494 | static void netxen_init_msix_entries(struct netxen_adapter *adapter) | ||
495 | { | ||
496 | int i; | ||
497 | |||
498 | for (i = 0; i < MSIX_ENTRIES_PER_ADAPTER; i++) | ||
499 | adapter->msix_entries[i].entry = i; | ||
500 | } | ||
501 | |||
256 | /* | 502 | /* |
257 | * netxen_nic_probe() | 503 | * netxen_nic_probe() |
258 | * | 504 | * |
@@ -278,28 +524,28 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
278 | 524 | ||
279 | 525 | ||
280 | u8 __iomem *db_ptr = NULL; | 526 | u8 __iomem *db_ptr = NULL; |
281 | unsigned long mem_base, mem_len, db_base, db_len; | 527 | unsigned long mem_base, mem_len, db_base, db_len, pci_len0 = 0; |
282 | int pci_using_dac, i = 0, err; | 528 | int i = 0, err; |
283 | int ring; | 529 | int first_driver, first_boot; |
284 | struct netxen_recv_context *recv_ctx = NULL; | ||
285 | struct netxen_rcv_desc_ctx *rcv_desc = NULL; | ||
286 | struct netxen_cmd_buffer *cmd_buf_arr = NULL; | ||
287 | __le64 mac_addr[FLASH_NUM_PORTS + 1]; | 530 | __le64 mac_addr[FLASH_NUM_PORTS + 1]; |
288 | int valid_mac = 0; | ||
289 | u32 val; | 531 | u32 val; |
290 | int pci_func_id = PCI_FUNC(pdev->devfn); | 532 | int pci_func_id = PCI_FUNC(pdev->devfn); |
291 | DECLARE_MAC_BUF(mac); | 533 | DECLARE_MAC_BUF(mac); |
534 | struct netxen_legacy_intr_set *legacy_intrp; | ||
535 | uint8_t revision_id; | ||
292 | 536 | ||
293 | if (pci_func_id == 0) | 537 | if (pci_func_id == 0) |
294 | printk(KERN_INFO "%s \n", netxen_nic_driver_string); | 538 | printk(KERN_INFO "%s\n", netxen_nic_driver_string); |
295 | 539 | ||
296 | if (pdev->class != 0x020000) { | 540 | if (pdev->class != 0x020000) { |
297 | printk(KERN_DEBUG "NetXen function %d, class %x will not " | 541 | printk(KERN_DEBUG "NetXen function %d, class %x will not " |
298 | "be enabled.\n",pci_func_id, pdev->class); | 542 | "be enabled.\n",pci_func_id, pdev->class); |
299 | return -ENODEV; | 543 | return -ENODEV; |
300 | } | 544 | } |
545 | |||
301 | if ((err = pci_enable_device(pdev))) | 546 | if ((err = pci_enable_device(pdev))) |
302 | return err; | 547 | return err; |
548 | |||
303 | if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) { | 549 | if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) { |
304 | err = -ENODEV; | 550 | err = -ENODEV; |
305 | goto err_out_disable_pdev; | 551 | goto err_out_disable_pdev; |
@@ -309,18 +555,6 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
309 | goto err_out_disable_pdev; | 555 | goto err_out_disable_pdev; |
310 | 556 | ||
311 | pci_set_master(pdev); | 557 | pci_set_master(pdev); |
312 | if (pdev->revision == NX_P2_C1 && | ||
313 | (pci_set_dma_mask(pdev, DMA_35BIT_MASK) == 0) && | ||
314 | (pci_set_consistent_dma_mask(pdev, DMA_35BIT_MASK) == 0)) { | ||
315 | pci_using_dac = 1; | ||
316 | } else { | ||
317 | if ((err = pci_set_dma_mask(pdev, DMA_32BIT_MASK)) || | ||
318 | (err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK))) | ||
319 | goto err_out_free_res; | ||
320 | |||
321 | pci_using_dac = 0; | ||
322 | } | ||
323 | |||
324 | 558 | ||
325 | netdev = alloc_etherdev(sizeof(struct netxen_adapter)); | 559 | netdev = alloc_etherdev(sizeof(struct netxen_adapter)); |
326 | if(!netdev) { | 560 | if(!netdev) { |
@@ -333,13 +567,35 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
333 | SET_NETDEV_DEV(netdev, &pdev->dev); | 567 | SET_NETDEV_DEV(netdev, &pdev->dev); |
334 | 568 | ||
335 | adapter = netdev->priv; | 569 | adapter = netdev->priv; |
336 | 570 | adapter->netdev = netdev; | |
337 | adapter->ahw.pdev = pdev; | 571 | adapter->pdev = pdev; |
338 | adapter->ahw.pci_func = pci_func_id; | 572 | adapter->ahw.pci_func = pci_func_id; |
339 | 573 | ||
574 | revision_id = pdev->revision; | ||
575 | adapter->ahw.revision_id = revision_id; | ||
576 | |||
577 | err = nx_set_dma_mask(adapter, revision_id); | ||
578 | if (err) | ||
579 | goto err_out_free_netdev; | ||
580 | |||
581 | rwlock_init(&adapter->adapter_lock); | ||
582 | adapter->ahw.qdr_sn_window = -1; | ||
583 | adapter->ahw.ddr_mn_window = -1; | ||
584 | |||
340 | /* remap phys address */ | 585 | /* remap phys address */ |
341 | mem_base = pci_resource_start(pdev, 0); /* 0 is for BAR 0 */ | 586 | mem_base = pci_resource_start(pdev, 0); /* 0 is for BAR 0 */ |
342 | mem_len = pci_resource_len(pdev, 0); | 587 | mem_len = pci_resource_len(pdev, 0); |
588 | pci_len0 = 0; | ||
589 | |||
590 | adapter->hw_write_wx = netxen_nic_hw_write_wx_128M; | ||
591 | adapter->hw_read_wx = netxen_nic_hw_read_wx_128M; | ||
592 | adapter->pci_read_immediate = netxen_nic_pci_read_immediate_128M; | ||
593 | adapter->pci_write_immediate = netxen_nic_pci_write_immediate_128M; | ||
594 | adapter->pci_read_normalize = netxen_nic_pci_read_normalize_128M; | ||
595 | adapter->pci_write_normalize = netxen_nic_pci_write_normalize_128M; | ||
596 | adapter->pci_set_window = netxen_nic_pci_set_window_128M; | ||
597 | adapter->pci_mem_read = netxen_nic_pci_mem_read_128M; | ||
598 | adapter->pci_mem_write = netxen_nic_pci_mem_write_128M; | ||
343 | 599 | ||
344 | /* 128 Meg of memory */ | 600 | /* 128 Meg of memory */ |
345 | if (mem_len == NETXEN_PCI_128MB_SIZE) { | 601 | if (mem_len == NETXEN_PCI_128MB_SIZE) { |
@@ -356,27 +612,48 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
356 | SECOND_PAGE_GROUP_START, THIRD_PAGE_GROUP_SIZE); | 612 | SECOND_PAGE_GROUP_START, THIRD_PAGE_GROUP_SIZE); |
357 | first_page_group_start = 0; | 613 | first_page_group_start = 0; |
358 | first_page_group_end = 0; | 614 | first_page_group_end = 0; |
615 | } else if (mem_len == NETXEN_PCI_2MB_SIZE) { | ||
616 | adapter->hw_write_wx = netxen_nic_hw_write_wx_2M; | ||
617 | adapter->hw_read_wx = netxen_nic_hw_read_wx_2M; | ||
618 | adapter->pci_read_immediate = netxen_nic_pci_read_immediate_2M; | ||
619 | adapter->pci_write_immediate = | ||
620 | netxen_nic_pci_write_immediate_2M; | ||
621 | adapter->pci_read_normalize = netxen_nic_pci_read_normalize_2M; | ||
622 | adapter->pci_write_normalize = | ||
623 | netxen_nic_pci_write_normalize_2M; | ||
624 | adapter->pci_set_window = netxen_nic_pci_set_window_2M; | ||
625 | adapter->pci_mem_read = netxen_nic_pci_mem_read_2M; | ||
626 | adapter->pci_mem_write = netxen_nic_pci_mem_write_2M; | ||
627 | |||
628 | mem_ptr0 = ioremap(mem_base, mem_len); | ||
629 | pci_len0 = mem_len; | ||
630 | first_page_group_start = 0; | ||
631 | first_page_group_end = 0; | ||
632 | |||
633 | adapter->ahw.ddr_mn_window = 0; | ||
634 | adapter->ahw.qdr_sn_window = 0; | ||
635 | |||
636 | adapter->ahw.mn_win_crb = 0x100000 + PCIX_MN_WINDOW + | ||
637 | (pci_func_id * 0x20); | ||
638 | adapter->ahw.ms_win_crb = 0x100000 + PCIX_SN_WINDOW; | ||
639 | if (pci_func_id < 4) | ||
640 | adapter->ahw.ms_win_crb += (pci_func_id * 0x20); | ||
641 | else | ||
642 | adapter->ahw.ms_win_crb += | ||
643 | 0xA0 + ((pci_func_id - 4) * 0x10); | ||
359 | } else { | 644 | } else { |
360 | err = -EIO; | 645 | err = -EIO; |
361 | goto err_out_free_netdev; | 646 | goto err_out_free_netdev; |
362 | } | 647 | } |
363 | 648 | ||
364 | if ((!mem_ptr0 && mem_len == NETXEN_PCI_128MB_SIZE) || | 649 | dev_info(&pdev->dev, "%dMB memory map\n", (int)(mem_len>>20)); |
365 | !mem_ptr1 || !mem_ptr2) { | ||
366 | DPRINTK(ERR, | ||
367 | "Cannot remap adapter memory aborting.:" | ||
368 | "0 -> %p, 1 -> %p, 2 -> %p\n", | ||
369 | mem_ptr0, mem_ptr1, mem_ptr2); | ||
370 | 650 | ||
371 | err = -EIO; | ||
372 | goto err_out_iounmap; | ||
373 | } | ||
374 | db_base = pci_resource_start(pdev, 4); /* doorbell is on bar 4 */ | 651 | db_base = pci_resource_start(pdev, 4); /* doorbell is on bar 4 */ |
375 | db_len = pci_resource_len(pdev, 4); | 652 | db_len = pci_resource_len(pdev, 4); |
376 | 653 | ||
377 | if (db_len == 0) { | 654 | if (db_len == 0) { |
378 | printk(KERN_ERR "%s: doorbell is disabled\n", | 655 | printk(KERN_ERR "%s: doorbell is disabled\n", |
379 | netxen_nic_driver_name); | 656 | netxen_nic_driver_name); |
380 | err = -EIO; | 657 | err = -EIO; |
381 | goto err_out_iounmap; | 658 | goto err_out_iounmap; |
382 | } | 659 | } |
@@ -386,13 +663,14 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
386 | db_ptr = ioremap(db_base, NETXEN_DB_MAPSIZE_BYTES); | 663 | db_ptr = ioremap(db_base, NETXEN_DB_MAPSIZE_BYTES); |
387 | if (!db_ptr) { | 664 | if (!db_ptr) { |
388 | printk(KERN_ERR "%s: Failed to allocate doorbell map.", | 665 | printk(KERN_ERR "%s: Failed to allocate doorbell map.", |
389 | netxen_nic_driver_name); | 666 | netxen_nic_driver_name); |
390 | err = -EIO; | 667 | err = -EIO; |
391 | goto err_out_iounmap; | 668 | goto err_out_iounmap; |
392 | } | 669 | } |
393 | DPRINTK(INFO, "doorbell ioremaped at %p\n", db_ptr); | 670 | DPRINTK(INFO, "doorbell ioremaped at %p\n", db_ptr); |
394 | 671 | ||
395 | adapter->ahw.pci_base0 = mem_ptr0; | 672 | adapter->ahw.pci_base0 = mem_ptr0; |
673 | adapter->ahw.pci_len0 = pci_len0; | ||
396 | adapter->ahw.first_page_group_start = first_page_group_start; | 674 | adapter->ahw.first_page_group_start = first_page_group_start; |
397 | adapter->ahw.first_page_group_end = first_page_group_end; | 675 | adapter->ahw.first_page_group_end = first_page_group_end; |
398 | adapter->ahw.pci_base1 = mem_ptr1; | 676 | adapter->ahw.pci_base1 = mem_ptr1; |
@@ -400,11 +678,18 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
400 | adapter->ahw.db_base = db_ptr; | 678 | adapter->ahw.db_base = db_ptr; |
401 | adapter->ahw.db_len = db_len; | 679 | adapter->ahw.db_len = db_len; |
402 | 680 | ||
403 | adapter->netdev = netdev; | ||
404 | adapter->pdev = pdev; | ||
405 | |||
406 | netif_napi_add(netdev, &adapter->napi, | 681 | netif_napi_add(netdev, &adapter->napi, |
407 | netxen_nic_poll, NETXEN_NETDEV_WEIGHT); | 682 | netxen_nic_poll, NETXEN_NETDEV_WEIGHT); |
683 | |||
684 | if (revision_id >= NX_P3_B0) | ||
685 | legacy_intrp = &legacy_intr[pci_func_id]; | ||
686 | else | ||
687 | legacy_intrp = &legacy_intr[0]; | ||
688 | |||
689 | adapter->legacy_intr.int_vec_bit = legacy_intrp->int_vec_bit; | ||
690 | adapter->legacy_intr.tgt_status_reg = legacy_intrp->tgt_status_reg; | ||
691 | adapter->legacy_intr.tgt_mask_reg = legacy_intrp->tgt_mask_reg; | ||
692 | adapter->legacy_intr.pci_int_reg = legacy_intrp->pci_int_reg; | ||
408 | 693 | ||
409 | /* this will be read from FW later */ | 694 | /* this will be read from FW later */ |
410 | adapter->intr_scheme = -1; | 695 | adapter->intr_scheme = -1; |
@@ -414,12 +699,23 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
414 | adapter->portnum = pci_func_id; | 699 | adapter->portnum = pci_func_id; |
415 | adapter->status &= ~NETXEN_NETDEV_STATUS; | 700 | adapter->status &= ~NETXEN_NETDEV_STATUS; |
416 | adapter->rx_csum = 1; | 701 | adapter->rx_csum = 1; |
702 | adapter->mc_enabled = 0; | ||
703 | if (NX_IS_REVISION_P3(revision_id)) { | ||
704 | adapter->max_mc_count = 38; | ||
705 | adapter->max_rds_rings = 2; | ||
706 | } else { | ||
707 | adapter->max_mc_count = 16; | ||
708 | adapter->max_rds_rings = 3; | ||
709 | } | ||
417 | 710 | ||
418 | netdev->open = netxen_nic_open; | 711 | netdev->open = netxen_nic_open; |
419 | netdev->stop = netxen_nic_close; | 712 | netdev->stop = netxen_nic_close; |
420 | netdev->hard_start_xmit = netxen_nic_xmit_frame; | 713 | netdev->hard_start_xmit = netxen_nic_xmit_frame; |
421 | netdev->get_stats = netxen_nic_get_stats; | 714 | netdev->get_stats = netxen_nic_get_stats; |
422 | netdev->set_multicast_list = netxen_nic_set_multi; | 715 | if (NX_IS_REVISION_P3(revision_id)) |
716 | netdev->set_multicast_list = netxen_p3_nic_set_multi; | ||
717 | else | ||
718 | netdev->set_multicast_list = netxen_p2_nic_set_multi; | ||
423 | netdev->set_mac_address = netxen_nic_set_mac; | 719 | netdev->set_mac_address = netxen_nic_set_mac; |
424 | netdev->change_mtu = netxen_nic_change_mtu; | 720 | netdev->change_mtu = netxen_nic_change_mtu; |
425 | netdev->tx_timeout = netxen_tx_timeout; | 721 | netdev->tx_timeout = netxen_tx_timeout; |
@@ -435,18 +731,14 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
435 | netdev->features = NETIF_F_SG; | 731 | netdev->features = NETIF_F_SG; |
436 | netdev->features |= NETIF_F_IP_CSUM; | 732 | netdev->features |= NETIF_F_IP_CSUM; |
437 | netdev->features |= NETIF_F_TSO; | 733 | netdev->features |= NETIF_F_TSO; |
734 | if (NX_IS_REVISION_P3(revision_id)) { | ||
735 | netdev->features |= NETIF_F_IPV6_CSUM; | ||
736 | netdev->features |= NETIF_F_TSO6; | ||
737 | } | ||
438 | 738 | ||
439 | if (pci_using_dac) | 739 | if (adapter->pci_using_dac) |
440 | netdev->features |= NETIF_F_HIGHDMA; | 740 | netdev->features |= NETIF_F_HIGHDMA; |
441 | 741 | ||
442 | if (pci_enable_msi(pdev)) | ||
443 | adapter->flags &= ~NETXEN_NIC_MSI_ENABLED; | ||
444 | else | ||
445 | adapter->flags |= NETXEN_NIC_MSI_ENABLED; | ||
446 | |||
447 | netdev->irq = pdev->irq; | ||
448 | INIT_WORK(&adapter->tx_timeout_task, netxen_tx_timeout_task); | ||
449 | |||
450 | /* | 742 | /* |
451 | * Set the CRB window to invalid. If any register in window 0 is | 743 | * Set the CRB window to invalid. If any register in window 0 is |
452 | * accessed it should set the window to 0 and then reset it to 1. | 744 | * accessed it should set the window to 0 and then reset it to 1. |
@@ -455,87 +747,13 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
455 | 747 | ||
456 | if (netxen_nic_get_board_info(adapter) != 0) { | 748 | if (netxen_nic_get_board_info(adapter) != 0) { |
457 | printk("%s: Error getting board config info.\n", | 749 | printk("%s: Error getting board config info.\n", |
458 | netxen_nic_driver_name); | 750 | netxen_nic_driver_name); |
459 | err = -EIO; | 751 | err = -EIO; |
460 | goto err_out_iounmap; | 752 | goto err_out_iounmap; |
461 | } | 753 | } |
462 | 754 | ||
463 | /* | ||
464 | * Adapter in our case is quad port so initialize it before | ||
465 | * initializing the ports | ||
466 | */ | ||
467 | |||
468 | netxen_initialize_adapter_ops(adapter); | 755 | netxen_initialize_adapter_ops(adapter); |
469 | 756 | ||
470 | adapter->max_tx_desc_count = MAX_CMD_DESCRIPTORS_HOST; | ||
471 | if ((adapter->ahw.boardcfg.board_type == NETXEN_BRDTYPE_P2_SB35_4G) || | ||
472 | (adapter->ahw.boardcfg.board_type == | ||
473 | NETXEN_BRDTYPE_P2_SB31_2G)) | ||
474 | adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS_1G; | ||
475 | else | ||
476 | adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS; | ||
477 | adapter->max_jumbo_rx_desc_count = MAX_JUMBO_RCV_DESCRIPTORS; | ||
478 | adapter->max_lro_rx_desc_count = MAX_LRO_RCV_DESCRIPTORS; | ||
479 | |||
480 | cmd_buf_arr = (struct netxen_cmd_buffer *)vmalloc(TX_RINGSIZE); | ||
481 | if (cmd_buf_arr == NULL) { | ||
482 | printk(KERN_ERR | ||
483 | "%s: Could not allocate cmd_buf_arr memory:%d\n", | ||
484 | netxen_nic_driver_name, (int)TX_RINGSIZE); | ||
485 | err = -ENOMEM; | ||
486 | goto err_out_free_adapter; | ||
487 | } | ||
488 | memset(cmd_buf_arr, 0, TX_RINGSIZE); | ||
489 | adapter->cmd_buf_arr = cmd_buf_arr; | ||
490 | |||
491 | for (i = 0; i < MAX_RCV_CTX; ++i) { | ||
492 | recv_ctx = &adapter->recv_ctx[i]; | ||
493 | for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) { | ||
494 | rcv_desc = &recv_ctx->rcv_desc[ring]; | ||
495 | switch (RCV_DESC_TYPE(ring)) { | ||
496 | case RCV_DESC_NORMAL: | ||
497 | rcv_desc->max_rx_desc_count = | ||
498 | adapter->max_rx_desc_count; | ||
499 | rcv_desc->flags = RCV_DESC_NORMAL; | ||
500 | rcv_desc->dma_size = RX_DMA_MAP_LEN; | ||
501 | rcv_desc->skb_size = MAX_RX_BUFFER_LENGTH; | ||
502 | break; | ||
503 | |||
504 | case RCV_DESC_JUMBO: | ||
505 | rcv_desc->max_rx_desc_count = | ||
506 | adapter->max_jumbo_rx_desc_count; | ||
507 | rcv_desc->flags = RCV_DESC_JUMBO; | ||
508 | rcv_desc->dma_size = RX_JUMBO_DMA_MAP_LEN; | ||
509 | rcv_desc->skb_size = MAX_RX_JUMBO_BUFFER_LENGTH; | ||
510 | break; | ||
511 | |||
512 | case RCV_RING_LRO: | ||
513 | rcv_desc->max_rx_desc_count = | ||
514 | adapter->max_lro_rx_desc_count; | ||
515 | rcv_desc->flags = RCV_DESC_LRO; | ||
516 | rcv_desc->dma_size = RX_LRO_DMA_MAP_LEN; | ||
517 | rcv_desc->skb_size = MAX_RX_LRO_BUFFER_LENGTH; | ||
518 | break; | ||
519 | |||
520 | } | ||
521 | rcv_desc->rx_buf_arr = (struct netxen_rx_buffer *) | ||
522 | vmalloc(RCV_BUFFSIZE); | ||
523 | |||
524 | if (rcv_desc->rx_buf_arr == NULL) { | ||
525 | printk(KERN_ERR "%s: Could not allocate " | ||
526 | "rcv_desc->rx_buf_arr memory:%d\n", | ||
527 | netxen_nic_driver_name, | ||
528 | (int)RCV_BUFFSIZE); | ||
529 | err = -ENOMEM; | ||
530 | goto err_out_free_rx_buffer; | ||
531 | } | ||
532 | memset(rcv_desc->rx_buf_arr, 0, RCV_BUFFSIZE); | ||
533 | } | ||
534 | |||
535 | } | ||
536 | |||
537 | netxen_initialize_adapter_sw(adapter); /* initialize the buffers in adapter */ | ||
538 | |||
539 | /* Mezz cards have PCI function 0,2,3 enabled */ | 757 | /* Mezz cards have PCI function 0,2,3 enabled */ |
540 | switch (adapter->ahw.boardcfg.board_type) { | 758 | switch (adapter->ahw.boardcfg.board_type) { |
541 | case NETXEN_BRDTYPE_P2_SB31_10G_IMEZ: | 759 | case NETXEN_BRDTYPE_P2_SB31_10G_IMEZ: |
@@ -547,90 +765,71 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
547 | break; | 765 | break; |
548 | } | 766 | } |
549 | 767 | ||
550 | init_timer(&adapter->watchdog_timer); | 768 | /* |
551 | adapter->ahw.xg_linkup = 0; | 769 | * This call will setup various max rx/tx counts. |
552 | adapter->watchdog_timer.function = &netxen_watchdog; | 770 | * It must be done before any buffer/ring allocations. |
553 | adapter->watchdog_timer.data = (unsigned long)adapter; | 771 | */ |
554 | INIT_WORK(&adapter->watchdog_task, netxen_watchdog_task); | 772 | netxen_check_options(adapter); |
555 | adapter->ahw.pdev = pdev; | ||
556 | adapter->ahw.revision_id = pdev->revision; | ||
557 | |||
558 | /* make sure Window == 1 */ | ||
559 | netxen_nic_pci_change_crbwindow(adapter, 1); | ||
560 | 773 | ||
774 | first_driver = 0; | ||
775 | if (NX_IS_REVISION_P3(revision_id)) { | ||
776 | if (adapter->ahw.pci_func == 0) | ||
777 | first_driver = 1; | ||
778 | } else { | ||
779 | if (adapter->portnum == 0) | ||
780 | first_driver = 1; | ||
781 | } | ||
782 | adapter->crb_addr_cmd_producer = crb_cmd_producer[adapter->portnum]; | ||
783 | adapter->crb_addr_cmd_consumer = crb_cmd_consumer[adapter->portnum]; | ||
561 | netxen_nic_update_cmd_producer(adapter, 0); | 784 | netxen_nic_update_cmd_producer(adapter, 0); |
562 | netxen_nic_update_cmd_consumer(adapter, 0); | 785 | netxen_nic_update_cmd_consumer(adapter, 0); |
563 | writel(0, NETXEN_CRB_NORMALIZE(adapter, CRB_HOST_CMD_ADDR_LO)); | ||
564 | 786 | ||
565 | if (netxen_is_flash_supported(adapter) == 0 && | 787 | if (first_driver) { |
566 | netxen_get_flash_mac_addr(adapter, mac_addr) == 0) | 788 | first_boot = adapter->pci_read_normalize(adapter, |
567 | valid_mac = 1; | 789 | NETXEN_CAM_RAM(0x1fc)); |
568 | else | ||
569 | valid_mac = 0; | ||
570 | |||
571 | if (valid_mac) { | ||
572 | unsigned char *p = (unsigned char *)&mac_addr[adapter->portnum]; | ||
573 | netdev->dev_addr[0] = *(p + 5); | ||
574 | netdev->dev_addr[1] = *(p + 4); | ||
575 | netdev->dev_addr[2] = *(p + 3); | ||
576 | netdev->dev_addr[3] = *(p + 2); | ||
577 | netdev->dev_addr[4] = *(p + 1); | ||
578 | netdev->dev_addr[5] = *(p + 0); | ||
579 | 790 | ||
580 | memcpy(netdev->perm_addr, netdev->dev_addr, | 791 | err = netxen_check_hw_init(adapter, first_boot); |
581 | netdev->addr_len); | 792 | if (err) { |
582 | if (!is_valid_ether_addr(netdev->perm_addr)) { | 793 | printk(KERN_ERR "%s: error in init HW init sequence\n", |
583 | printk(KERN_ERR "%s: Bad MAC address %s.\n", | 794 | netxen_nic_driver_name); |
584 | netxen_nic_driver_name, | 795 | goto err_out_iounmap; |
585 | print_mac(mac, netdev->dev_addr)); | ||
586 | } else { | ||
587 | if (adapter->macaddr_set) | ||
588 | adapter->macaddr_set(adapter, | ||
589 | netdev->dev_addr); | ||
590 | } | 796 | } |
591 | } | ||
592 | 797 | ||
593 | if (adapter->portnum == 0) { | 798 | if (NX_IS_REVISION_P3(revision_id)) |
594 | err = netxen_initialize_adapter_offload(adapter); | 799 | netxen_set_port_mode(adapter); |
595 | if (err) | 800 | |
596 | goto err_out_free_rx_buffer; | 801 | if (first_boot != 0x55555555) { |
597 | val = readl(NETXEN_CRB_NORMALIZE(adapter, | 802 | adapter->pci_write_normalize(adapter, |
598 | NETXEN_CAM_RAM(0x1fc))); | 803 | CRB_CMDPEG_STATE, 0); |
599 | if (val == 0x55555555) { | ||
600 | /* This is the first boot after power up */ | ||
601 | netxen_nic_read_w0(adapter, NETXEN_PCIE_REG(0x4), &val); | ||
602 | if (!(val & 0x4)) { | ||
603 | val |= 0x4; | ||
604 | netxen_nic_write_w0(adapter, NETXEN_PCIE_REG(0x4), val); | ||
605 | netxen_nic_read_w0(adapter, NETXEN_PCIE_REG(0x4), &val); | ||
606 | if (!(val & 0x4)) | ||
607 | printk(KERN_ERR "%s: failed to set MSI bit in PCI-e reg\n", | ||
608 | netxen_nic_driver_name); | ||
609 | } | ||
610 | val = readl(NETXEN_CRB_NORMALIZE(adapter, | ||
611 | NETXEN_ROMUSB_GLB_SW_RESET)); | ||
612 | printk(KERN_INFO"NetXen: read 0x%08x for reset reg.\n",val); | ||
613 | if (val != 0x80000f) { | ||
614 | /* clear the register for future unloads/loads */ | ||
615 | writel(0, NETXEN_CRB_NORMALIZE(adapter, | ||
616 | NETXEN_CAM_RAM(0x1fc))); | ||
617 | printk(KERN_ERR "ERROR in NetXen HW init sequence.\n"); | ||
618 | err = -ENODEV; | ||
619 | goto err_out_free_dev; | ||
620 | } | ||
621 | } else { | ||
622 | writel(0, NETXEN_CRB_NORMALIZE(adapter, | ||
623 | CRB_CMDPEG_STATE)); | ||
624 | netxen_pinit_from_rom(adapter, 0); | 804 | netxen_pinit_from_rom(adapter, 0); |
625 | msleep(1); | 805 | msleep(1); |
626 | netxen_load_firmware(adapter); | 806 | netxen_load_firmware(adapter); |
627 | netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE); | ||
628 | } | 807 | } |
629 | 808 | ||
630 | /* clear the register for future unloads/loads */ | 809 | if (NX_IS_REVISION_P3(revision_id)) |
631 | writel(0, NETXEN_CRB_NORMALIZE(adapter, NETXEN_CAM_RAM(0x1fc))); | 810 | netxen_pcie_strap_init(adapter); |
632 | dev_info(&pdev->dev, "cmdpeg state: 0x%0x\n", | 811 | |
633 | readl(NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_STATE))); | 812 | if (NX_IS_REVISION_P2(revision_id)) { |
813 | |||
814 | /* Initialize multicast addr pool owners */ | ||
815 | val = 0x7654; | ||
816 | if (adapter->ahw.board_type == NETXEN_NIC_XGBE) | ||
817 | val |= 0x0f000000; | ||
818 | netxen_crb_writelit_adapter(adapter, | ||
819 | NETXEN_MAC_ADDR_CNTL_REG, val); | ||
820 | |||
821 | } | ||
822 | |||
823 | if ((first_boot == 0x55555555) && | ||
824 | (NX_IS_REVISION_P2(revision_id))) { | ||
825 | /* Unlock the HW, prompting the boot sequence */ | ||
826 | adapter->pci_write_normalize(adapter, | ||
827 | NETXEN_ROMUSB_GLB_PEGTUNE_DONE, 1); | ||
828 | } | ||
829 | |||
830 | err = netxen_initialize_adapter_offload(adapter); | ||
831 | if (err) | ||
832 | goto err_out_iounmap; | ||
634 | 833 | ||
635 | /* | 834 | /* |
636 | * Tell the hardware our version number. | 835 | * Tell the hardware our version number. |
@@ -638,24 +837,101 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
638 | i = (_NETXEN_NIC_LINUX_MAJOR << 16) | 837 | i = (_NETXEN_NIC_LINUX_MAJOR << 16) |
639 | | ((_NETXEN_NIC_LINUX_MINOR << 8)) | 838 | | ((_NETXEN_NIC_LINUX_MINOR << 8)) |
640 | | (_NETXEN_NIC_LINUX_SUBVERSION); | 839 | | (_NETXEN_NIC_LINUX_SUBVERSION); |
641 | writel(i, NETXEN_CRB_NORMALIZE(adapter, CRB_DRIVER_VERSION)); | 840 | adapter->pci_write_normalize(adapter, CRB_DRIVER_VERSION, i); |
642 | 841 | ||
643 | /* Unlock the HW, prompting the boot sequence */ | ||
644 | writel(1, | ||
645 | NETXEN_CRB_NORMALIZE(adapter, | ||
646 | NETXEN_ROMUSB_GLB_PEGTUNE_DONE)); | ||
647 | /* Handshake with the card before we register the devices. */ | 842 | /* Handshake with the card before we register the devices. */ |
648 | netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE); | 843 | netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE); |
844 | |||
845 | } /* first_driver */ | ||
846 | |||
847 | netxen_nic_flash_print(adapter); | ||
848 | |||
849 | if (NX_IS_REVISION_P3(revision_id)) { | ||
850 | adapter->hw_read_wx(adapter, | ||
851 | NETXEN_MIU_MN_CONTROL, &val, 4); | ||
852 | adapter->ahw.cut_through = (val & 0x4) ? 1 : 0; | ||
853 | dev_info(&pdev->dev, "firmware running in %s mode\n", | ||
854 | adapter->ahw.cut_through ? "cut through" : "legacy"); | ||
649 | } | 855 | } |
650 | 856 | ||
651 | /* | 857 | /* |
652 | * See if the firmware gave us a virtual-physical port mapping. | 858 | * See if the firmware gave us a virtual-physical port mapping. |
653 | */ | 859 | */ |
654 | adapter->physical_port = adapter->portnum; | 860 | adapter->physical_port = adapter->portnum; |
655 | i = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_V2P(adapter->portnum))); | 861 | i = adapter->pci_read_normalize(adapter, CRB_V2P(adapter->portnum)); |
656 | if (i != 0x55555555) | 862 | if (i != 0x55555555) |
657 | adapter->physical_port = i; | 863 | adapter->physical_port = i; |
658 | 864 | ||
865 | adapter->flags &= ~(NETXEN_NIC_MSI_ENABLED | NETXEN_NIC_MSIX_ENABLED); | ||
866 | |||
867 | netxen_set_msix_bit(pdev, 0); | ||
868 | |||
869 | if (NX_IS_REVISION_P3(revision_id)) { | ||
870 | if ((mem_len != NETXEN_PCI_128MB_SIZE) && | ||
871 | mem_len != NETXEN_PCI_2MB_SIZE) | ||
872 | adapter->msix_supported = 0; | ||
873 | } | ||
874 | |||
875 | if (adapter->msix_supported) { | ||
876 | |||
877 | netxen_init_msix_entries(adapter); | ||
878 | |||
879 | if (pci_enable_msix(pdev, adapter->msix_entries, | ||
880 | MSIX_ENTRIES_PER_ADAPTER)) | ||
881 | goto request_msi; | ||
882 | |||
883 | adapter->flags |= NETXEN_NIC_MSIX_ENABLED; | ||
884 | netxen_set_msix_bit(pdev, 1); | ||
885 | dev_info(&pdev->dev, "using msi-x interrupts\n"); | ||
886 | |||
887 | } else { | ||
888 | request_msi: | ||
889 | if (use_msi && !pci_enable_msi(pdev)) { | ||
890 | adapter->flags |= NETXEN_NIC_MSI_ENABLED; | ||
891 | dev_info(&pdev->dev, "using msi interrupts\n"); | ||
892 | } else | ||
893 | dev_info(&pdev->dev, "using legacy interrupts\n"); | ||
894 | } | ||
895 | |||
896 | if (adapter->flags & NETXEN_NIC_MSIX_ENABLED) | ||
897 | netdev->irq = adapter->msix_entries[0].vector; | ||
898 | else | ||
899 | netdev->irq = pdev->irq; | ||
900 | |||
901 | err = netxen_receive_peg_ready(adapter); | ||
902 | if (err) | ||
903 | goto err_out_disable_msi; | ||
904 | |||
905 | init_timer(&adapter->watchdog_timer); | ||
906 | adapter->ahw.linkup = 0; | ||
907 | adapter->watchdog_timer.function = &netxen_watchdog; | ||
908 | adapter->watchdog_timer.data = (unsigned long)adapter; | ||
909 | INIT_WORK(&adapter->watchdog_task, netxen_watchdog_task); | ||
910 | INIT_WORK(&adapter->tx_timeout_task, netxen_tx_timeout_task); | ||
911 | |||
912 | if (netxen_is_flash_supported(adapter) == 0 && | ||
913 | netxen_get_flash_mac_addr(adapter, mac_addr) == 0) { | ||
914 | unsigned char *p; | ||
915 | |||
916 | p = (unsigned char *)&mac_addr[adapter->portnum]; | ||
917 | netdev->dev_addr[0] = *(p + 5); | ||
918 | netdev->dev_addr[1] = *(p + 4); | ||
919 | netdev->dev_addr[2] = *(p + 3); | ||
920 | netdev->dev_addr[3] = *(p + 2); | ||
921 | netdev->dev_addr[4] = *(p + 1); | ||
922 | netdev->dev_addr[5] = *(p + 0); | ||
923 | |||
924 | memcpy(netdev->perm_addr, netdev->dev_addr, | ||
925 | netdev->addr_len); | ||
926 | if (!is_valid_ether_addr(netdev->perm_addr)) { | ||
927 | printk(KERN_ERR "%s: Bad MAC address %s.\n", | ||
928 | netxen_nic_driver_name, | ||
929 | print_mac(mac, netdev->dev_addr)); | ||
930 | } else { | ||
931 | adapter->macaddr_set(adapter, netdev->dev_addr); | ||
932 | } | ||
933 | } | ||
934 | |||
659 | netif_carrier_off(netdev); | 935 | netif_carrier_off(netdev); |
660 | netif_stop_queue(netdev); | 936 | netif_stop_queue(netdev); |
661 | 937 | ||
@@ -664,41 +940,37 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
664 | " aborting\n", netxen_nic_driver_name, | 940 | " aborting\n", netxen_nic_driver_name, |
665 | adapter->portnum); | 941 | adapter->portnum); |
666 | err = -EIO; | 942 | err = -EIO; |
667 | goto err_out_free_dev; | 943 | goto err_out_disable_msi; |
668 | } | 944 | } |
669 | 945 | ||
670 | netxen_nic_flash_print(adapter); | ||
671 | pci_set_drvdata(pdev, adapter); | 946 | pci_set_drvdata(pdev, adapter); |
672 | 947 | ||
673 | return 0; | 948 | switch (adapter->ahw.board_type) { |
674 | 949 | case NETXEN_NIC_GBE: | |
675 | err_out_free_dev: | 950 | dev_info(&adapter->pdev->dev, "%s: GbE port initialized\n", |
676 | if (adapter->portnum == 0) | 951 | adapter->netdev->name); |
677 | netxen_free_adapter_offload(adapter); | 952 | break; |
678 | 953 | case NETXEN_NIC_XGBE: | |
679 | err_out_free_rx_buffer: | 954 | dev_info(&adapter->pdev->dev, "%s: XGbE port initialized\n", |
680 | for (i = 0; i < MAX_RCV_CTX; ++i) { | 955 | adapter->netdev->name); |
681 | recv_ctx = &adapter->recv_ctx[i]; | 956 | break; |
682 | for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) { | ||
683 | rcv_desc = &recv_ctx->rcv_desc[ring]; | ||
684 | if (rcv_desc->rx_buf_arr != NULL) { | ||
685 | vfree(rcv_desc->rx_buf_arr); | ||
686 | rcv_desc->rx_buf_arr = NULL; | ||
687 | } | ||
688 | } | ||
689 | } | 957 | } |
690 | vfree(cmd_buf_arr); | ||
691 | 958 | ||
692 | err_out_free_adapter: | 959 | return 0; |
960 | |||
961 | err_out_disable_msi: | ||
962 | if (adapter->flags & NETXEN_NIC_MSIX_ENABLED) | ||
963 | pci_disable_msix(pdev); | ||
693 | if (adapter->flags & NETXEN_NIC_MSI_ENABLED) | 964 | if (adapter->flags & NETXEN_NIC_MSI_ENABLED) |
694 | pci_disable_msi(pdev); | 965 | pci_disable_msi(pdev); |
695 | 966 | ||
696 | pci_set_drvdata(pdev, NULL); | 967 | if (first_driver) |
968 | netxen_free_adapter_offload(adapter); | ||
697 | 969 | ||
970 | err_out_iounmap: | ||
698 | if (db_ptr) | 971 | if (db_ptr) |
699 | iounmap(db_ptr); | 972 | iounmap(db_ptr); |
700 | 973 | ||
701 | err_out_iounmap: | ||
702 | if (mem_ptr0) | 974 | if (mem_ptr0) |
703 | iounmap(mem_ptr0); | 975 | iounmap(mem_ptr0); |
704 | if (mem_ptr1) | 976 | if (mem_ptr1) |
@@ -713,6 +985,7 @@ err_out_free_res: | |||
713 | pci_release_regions(pdev); | 985 | pci_release_regions(pdev); |
714 | 986 | ||
715 | err_out_disable_pdev: | 987 | err_out_disable_pdev: |
988 | pci_set_drvdata(pdev, NULL); | ||
716 | pci_disable_device(pdev); | 989 | pci_disable_device(pdev); |
717 | return err; | 990 | return err; |
718 | } | 991 | } |
@@ -721,11 +994,6 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev) | |||
721 | { | 994 | { |
722 | struct netxen_adapter *adapter; | 995 | struct netxen_adapter *adapter; |
723 | struct net_device *netdev; | 996 | struct net_device *netdev; |
724 | struct netxen_rx_buffer *buffer; | ||
725 | struct netxen_recv_context *recv_ctx; | ||
726 | struct netxen_rcv_desc_ctx *rcv_desc; | ||
727 | int i, ctxid, ring; | ||
728 | static int init_firmware_done = 0; | ||
729 | 997 | ||
730 | adapter = pci_get_drvdata(pdev); | 998 | adapter = pci_get_drvdata(pdev); |
731 | if (adapter == NULL) | 999 | if (adapter == NULL) |
@@ -736,36 +1004,18 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev) | |||
736 | unregister_netdev(netdev); | 1004 | unregister_netdev(netdev); |
737 | 1005 | ||
738 | if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC) { | 1006 | if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC) { |
739 | init_firmware_done++; | ||
740 | netxen_free_hw_resources(adapter); | 1007 | netxen_free_hw_resources(adapter); |
1008 | netxen_free_sw_resources(adapter); | ||
741 | } | 1009 | } |
742 | 1010 | ||
743 | for (ctxid = 0; ctxid < MAX_RCV_CTX; ++ctxid) { | ||
744 | recv_ctx = &adapter->recv_ctx[ctxid]; | ||
745 | for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) { | ||
746 | rcv_desc = &recv_ctx->rcv_desc[ring]; | ||
747 | for (i = 0; i < rcv_desc->max_rx_desc_count; ++i) { | ||
748 | buffer = &(rcv_desc->rx_buf_arr[i]); | ||
749 | if (buffer->state == NETXEN_BUFFER_FREE) | ||
750 | continue; | ||
751 | pci_unmap_single(pdev, buffer->dma, | ||
752 | rcv_desc->dma_size, | ||
753 | PCI_DMA_FROMDEVICE); | ||
754 | if (buffer->skb != NULL) | ||
755 | dev_kfree_skb_any(buffer->skb); | ||
756 | } | ||
757 | vfree(rcv_desc->rx_buf_arr); | ||
758 | } | ||
759 | } | ||
760 | |||
761 | vfree(adapter->cmd_buf_arr); | ||
762 | |||
763 | if (adapter->portnum == 0) | 1011 | if (adapter->portnum == 0) |
764 | netxen_free_adapter_offload(adapter); | 1012 | netxen_free_adapter_offload(adapter); |
765 | 1013 | ||
766 | if (adapter->irq) | 1014 | if (adapter->irq) |
767 | free_irq(adapter->irq, adapter); | 1015 | free_irq(adapter->irq, adapter); |
768 | 1016 | ||
1017 | if (adapter->flags & NETXEN_NIC_MSIX_ENABLED) | ||
1018 | pci_disable_msix(pdev); | ||
769 | if (adapter->flags & NETXEN_NIC_MSI_ENABLED) | 1019 | if (adapter->flags & NETXEN_NIC_MSI_ENABLED) |
770 | pci_disable_msi(pdev); | 1020 | pci_disable_msi(pdev); |
771 | 1021 | ||
@@ -803,51 +1053,69 @@ static int netxen_nic_open(struct net_device *netdev) | |||
803 | return -EIO; | 1053 | return -EIO; |
804 | } | 1054 | } |
805 | 1055 | ||
806 | /* setup all the resources for the Phantom... */ | 1056 | err = netxen_alloc_sw_resources(adapter); |
807 | /* this include the descriptors for rcv, tx, and status */ | ||
808 | netxen_nic_clear_stats(adapter); | ||
809 | err = netxen_nic_hw_resources(adapter); | ||
810 | if (err) { | 1057 | if (err) { |
811 | printk(KERN_ERR "Error in setting hw resources:%d\n", | 1058 | printk(KERN_ERR "%s: Error in setting sw resources\n", |
812 | err); | 1059 | netdev->name); |
813 | return err; | 1060 | return err; |
814 | } | 1061 | } |
1062 | |||
1063 | netxen_nic_clear_stats(adapter); | ||
1064 | |||
1065 | err = netxen_alloc_hw_resources(adapter); | ||
1066 | if (err) { | ||
1067 | printk(KERN_ERR "%s: Error in setting hw resources\n", | ||
1068 | netdev->name); | ||
1069 | goto err_out_free_sw; | ||
1070 | } | ||
1071 | |||
1072 | if (adapter->fw_major < 4) { | ||
1073 | adapter->crb_addr_cmd_producer = | ||
1074 | crb_cmd_producer[adapter->portnum]; | ||
1075 | adapter->crb_addr_cmd_consumer = | ||
1076 | crb_cmd_consumer[adapter->portnum]; | ||
1077 | } | ||
1078 | |||
1079 | netxen_nic_update_cmd_producer(adapter, 0); | ||
1080 | netxen_nic_update_cmd_consumer(adapter, 0); | ||
1081 | |||
815 | for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) { | 1082 | for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) { |
816 | for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) | 1083 | for (ring = 0; ring < adapter->max_rds_rings; ring++) |
817 | netxen_post_rx_buffers(adapter, ctx, ring); | 1084 | netxen_post_rx_buffers(adapter, ctx, ring); |
818 | } | 1085 | } |
819 | adapter->irq = adapter->ahw.pdev->irq; | 1086 | if (NETXEN_IS_MSI_FAMILY(adapter)) |
820 | if (adapter->flags & NETXEN_NIC_MSI_ENABLED) | ||
821 | handler = netxen_msi_intr; | 1087 | handler = netxen_msi_intr; |
822 | else { | 1088 | else { |
823 | flags |= IRQF_SHARED; | 1089 | flags |= IRQF_SHARED; |
824 | handler = netxen_intr; | 1090 | handler = netxen_intr; |
825 | } | 1091 | } |
1092 | adapter->irq = netdev->irq; | ||
826 | err = request_irq(adapter->irq, handler, | 1093 | err = request_irq(adapter->irq, handler, |
827 | flags, netdev->name, adapter); | 1094 | flags, netdev->name, adapter); |
828 | if (err) { | 1095 | if (err) { |
829 | printk(KERN_ERR "request_irq failed with: %d\n", err); | 1096 | printk(KERN_ERR "request_irq failed with: %d\n", err); |
830 | netxen_free_hw_resources(adapter); | 1097 | goto err_out_free_hw; |
831 | return err; | ||
832 | } | 1098 | } |
833 | 1099 | ||
834 | adapter->is_up = NETXEN_ADAPTER_UP_MAGIC; | 1100 | adapter->is_up = NETXEN_ADAPTER_UP_MAGIC; |
835 | } | 1101 | } |
1102 | |||
836 | /* Done here again so that even if phantom sw overwrote it, | 1103 | /* Done here again so that even if phantom sw overwrote it, |
837 | * we set it */ | 1104 | * we set it */ |
838 | if (adapter->init_port | 1105 | err = adapter->init_port(adapter, adapter->physical_port); |
839 | && adapter->init_port(adapter, adapter->portnum) != 0) { | 1106 | if (err) { |
840 | printk(KERN_ERR "%s: Failed to initialize port %d\n", | 1107 | printk(KERN_ERR "%s: Failed to initialize port %d\n", |
841 | netxen_nic_driver_name, adapter->portnum); | 1108 | netxen_nic_driver_name, adapter->portnum); |
842 | return -EIO; | 1109 | goto err_out_free_irq; |
843 | } | 1110 | } |
844 | if (adapter->macaddr_set) | 1111 | adapter->macaddr_set(adapter, netdev->dev_addr); |
845 | adapter->macaddr_set(adapter, netdev->dev_addr); | ||
846 | 1112 | ||
847 | netxen_nic_set_link_parameters(adapter); | 1113 | netxen_nic_set_link_parameters(adapter); |
848 | 1114 | ||
849 | netxen_nic_set_multi(netdev); | 1115 | netdev->set_multicast_list(netdev); |
850 | if (adapter->set_mtu) | 1116 | if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) |
1117 | nx_fw_cmd_set_mtu(adapter, netdev->mtu); | ||
1118 | else | ||
851 | adapter->set_mtu(adapter, netdev->mtu); | 1119 | adapter->set_mtu(adapter, netdev->mtu); |
852 | 1120 | ||
853 | mod_timer(&adapter->watchdog_timer, jiffies); | 1121 | mod_timer(&adapter->watchdog_timer, jiffies); |
@@ -858,6 +1126,14 @@ static int netxen_nic_open(struct net_device *netdev) | |||
858 | netif_start_queue(netdev); | 1126 | netif_start_queue(netdev); |
859 | 1127 | ||
860 | return 0; | 1128 | return 0; |
1129 | |||
1130 | err_out_free_irq: | ||
1131 | free_irq(adapter->irq, adapter); | ||
1132 | err_out_free_hw: | ||
1133 | netxen_free_hw_resources(adapter); | ||
1134 | err_out_free_sw: | ||
1135 | netxen_free_sw_resources(adapter); | ||
1136 | return err; | ||
861 | } | 1137 | } |
862 | 1138 | ||
863 | /* | 1139 | /* |
@@ -866,9 +1142,6 @@ static int netxen_nic_open(struct net_device *netdev) | |||
866 | static int netxen_nic_close(struct net_device *netdev) | 1142 | static int netxen_nic_close(struct net_device *netdev) |
867 | { | 1143 | { |
868 | struct netxen_adapter *adapter = netdev_priv(netdev); | 1144 | struct netxen_adapter *adapter = netdev_priv(netdev); |
869 | int i, j; | ||
870 | struct netxen_cmd_buffer *cmd_buff; | ||
871 | struct netxen_skb_frag *buffrag; | ||
872 | 1145 | ||
873 | netif_carrier_off(netdev); | 1146 | netif_carrier_off(netdev); |
874 | netif_stop_queue(netdev); | 1147 | netif_stop_queue(netdev); |
@@ -879,30 +1152,8 @@ static int netxen_nic_close(struct net_device *netdev) | |||
879 | 1152 | ||
880 | netxen_nic_disable_int(adapter); | 1153 | netxen_nic_disable_int(adapter); |
881 | 1154 | ||
882 | cmd_buff = adapter->cmd_buf_arr; | 1155 | netxen_release_tx_buffers(adapter); |
883 | for (i = 0; i < adapter->max_tx_desc_count; i++) { | 1156 | |
884 | buffrag = cmd_buff->frag_array; | ||
885 | if (buffrag->dma) { | ||
886 | pci_unmap_single(adapter->pdev, buffrag->dma, | ||
887 | buffrag->length, PCI_DMA_TODEVICE); | ||
888 | buffrag->dma = 0ULL; | ||
889 | } | ||
890 | for (j = 0; j < cmd_buff->frag_count; j++) { | ||
891 | buffrag++; | ||
892 | if (buffrag->dma) { | ||
893 | pci_unmap_page(adapter->pdev, buffrag->dma, | ||
894 | buffrag->length, | ||
895 | PCI_DMA_TODEVICE); | ||
896 | buffrag->dma = 0ULL; | ||
897 | } | ||
898 | } | ||
899 | /* Free the skb we received in netxen_nic_xmit_frame */ | ||
900 | if (cmd_buff->skb) { | ||
901 | dev_kfree_skb_any(cmd_buff->skb); | ||
902 | cmd_buff->skb = NULL; | ||
903 | } | ||
904 | cmd_buff++; | ||
905 | } | ||
906 | if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC) { | 1157 | if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC) { |
907 | FLUSH_SCHEDULED_WORK(); | 1158 | FLUSH_SCHEDULED_WORK(); |
908 | del_timer_sync(&adapter->watchdog_timer); | 1159 | del_timer_sync(&adapter->watchdog_timer); |
@@ -911,6 +1162,31 @@ static int netxen_nic_close(struct net_device *netdev) | |||
911 | return 0; | 1162 | return 0; |
912 | } | 1163 | } |
913 | 1164 | ||
1165 | void netxen_tso_check(struct netxen_adapter *adapter, | ||
1166 | struct cmd_desc_type0 *desc, struct sk_buff *skb) | ||
1167 | { | ||
1168 | if (desc->mss) { | ||
1169 | desc->total_hdr_length = (sizeof(struct ethhdr) + | ||
1170 | ip_hdrlen(skb) + tcp_hdrlen(skb)); | ||
1171 | |||
1172 | if ((NX_IS_REVISION_P3(adapter->ahw.revision_id)) && | ||
1173 | (skb->protocol == htons(ETH_P_IPV6))) | ||
1174 | netxen_set_cmd_desc_opcode(desc, TX_TCP_LSO6); | ||
1175 | else | ||
1176 | netxen_set_cmd_desc_opcode(desc, TX_TCP_LSO); | ||
1177 | |||
1178 | } else if (skb->ip_summed == CHECKSUM_PARTIAL) { | ||
1179 | if (ip_hdr(skb)->protocol == IPPROTO_TCP) | ||
1180 | netxen_set_cmd_desc_opcode(desc, TX_TCP_PKT); | ||
1181 | else if (ip_hdr(skb)->protocol == IPPROTO_UDP) | ||
1182 | netxen_set_cmd_desc_opcode(desc, TX_UDP_PKT); | ||
1183 | else | ||
1184 | return; | ||
1185 | } | ||
1186 | desc->tcp_hdr_offset = skb_transport_offset(skb); | ||
1187 | desc->ip_hdr_offset = skb_network_offset(skb); | ||
1188 | } | ||
1189 | |||
914 | static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) | 1190 | static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) |
915 | { | 1191 | { |
916 | struct netxen_adapter *adapter = netdev_priv(netdev); | 1192 | struct netxen_adapter *adapter = netdev_priv(netdev); |
@@ -932,7 +1208,7 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) | |||
932 | 1208 | ||
933 | /* There 4 fragments per descriptor */ | 1209 | /* There 4 fragments per descriptor */ |
934 | no_of_desc = (frag_count + 3) >> 2; | 1210 | no_of_desc = (frag_count + 3) >> 2; |
935 | if (netdev->features & NETIF_F_TSO) { | 1211 | if (netdev->features & (NETIF_F_TSO | NETIF_F_TSO6)) { |
936 | if (skb_shinfo(skb)->gso_size > 0) { | 1212 | if (skb_shinfo(skb)->gso_size > 0) { |
937 | 1213 | ||
938 | no_of_desc++; | 1214 | no_of_desc++; |
@@ -959,7 +1235,8 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) | |||
959 | memset(hwdesc, 0, sizeof(struct cmd_desc_type0)); | 1235 | memset(hwdesc, 0, sizeof(struct cmd_desc_type0)); |
960 | /* Take skb->data itself */ | 1236 | /* Take skb->data itself */ |
961 | pbuf = &adapter->cmd_buf_arr[producer]; | 1237 | pbuf = &adapter->cmd_buf_arr[producer]; |
962 | if ((netdev->features & NETIF_F_TSO) && skb_shinfo(skb)->gso_size > 0) { | 1238 | if ((netdev->features & (NETIF_F_TSO | NETIF_F_TSO6)) && |
1239 | skb_shinfo(skb)->gso_size > 0) { | ||
963 | pbuf->mss = skb_shinfo(skb)->gso_size; | 1240 | pbuf->mss = skb_shinfo(skb)->gso_size; |
964 | hwdesc->mss = cpu_to_le16(skb_shinfo(skb)->gso_size); | 1241 | hwdesc->mss = cpu_to_le16(skb_shinfo(skb)->gso_size); |
965 | } else { | 1242 | } else { |
@@ -1086,6 +1363,89 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) | |||
1086 | return NETDEV_TX_OK; | 1363 | return NETDEV_TX_OK; |
1087 | } | 1364 | } |
1088 | 1365 | ||
1366 | static int netxen_nic_check_temp(struct netxen_adapter *adapter) | ||
1367 | { | ||
1368 | struct net_device *netdev = adapter->netdev; | ||
1369 | uint32_t temp, temp_state, temp_val; | ||
1370 | int rv = 0; | ||
1371 | |||
1372 | temp = adapter->pci_read_normalize(adapter, CRB_TEMP_STATE); | ||
1373 | |||
1374 | temp_state = nx_get_temp_state(temp); | ||
1375 | temp_val = nx_get_temp_val(temp); | ||
1376 | |||
1377 | if (temp_state == NX_TEMP_PANIC) { | ||
1378 | printk(KERN_ALERT | ||
1379 | "%s: Device temperature %d degrees C exceeds" | ||
1380 | " maximum allowed. Hardware has been shut down.\n", | ||
1381 | netxen_nic_driver_name, temp_val); | ||
1382 | |||
1383 | netif_carrier_off(netdev); | ||
1384 | netif_stop_queue(netdev); | ||
1385 | rv = 1; | ||
1386 | } else if (temp_state == NX_TEMP_WARN) { | ||
1387 | if (adapter->temp == NX_TEMP_NORMAL) { | ||
1388 | printk(KERN_ALERT | ||
1389 | "%s: Device temperature %d degrees C " | ||
1390 | "exceeds operating range." | ||
1391 | " Immediate action needed.\n", | ||
1392 | netxen_nic_driver_name, temp_val); | ||
1393 | } | ||
1394 | } else { | ||
1395 | if (adapter->temp == NX_TEMP_WARN) { | ||
1396 | printk(KERN_INFO | ||
1397 | "%s: Device temperature is now %d degrees C" | ||
1398 | " in normal range.\n", netxen_nic_driver_name, | ||
1399 | temp_val); | ||
1400 | } | ||
1401 | } | ||
1402 | adapter->temp = temp_state; | ||
1403 | return rv; | ||
1404 | } | ||
1405 | |||
1406 | static void netxen_nic_handle_phy_intr(struct netxen_adapter *adapter) | ||
1407 | { | ||
1408 | struct net_device *netdev = adapter->netdev; | ||
1409 | u32 val, port, linkup; | ||
1410 | |||
1411 | port = adapter->physical_port; | ||
1412 | |||
1413 | if (adapter->ahw.board_type == NETXEN_NIC_GBE) { | ||
1414 | val = adapter->pci_read_normalize(adapter, CRB_XG_STATE); | ||
1415 | linkup = (val >> port) & 1; | ||
1416 | } else { | ||
1417 | if (adapter->fw_major < 4) { | ||
1418 | val = adapter->pci_read_normalize(adapter, | ||
1419 | CRB_XG_STATE); | ||
1420 | val = (val >> port*8) & 0xff; | ||
1421 | linkup = (val == XG_LINK_UP); | ||
1422 | } else { | ||
1423 | val = adapter->pci_read_normalize(adapter, | ||
1424 | CRB_XG_STATE_P3); | ||
1425 | val = XG_LINK_STATE_P3(adapter->ahw.pci_func, val); | ||
1426 | linkup = (val == XG_LINK_UP_P3); | ||
1427 | } | ||
1428 | } | ||
1429 | |||
1430 | if (adapter->ahw.linkup && !linkup) { | ||
1431 | printk(KERN_INFO "%s: %s NIC Link is down\n", | ||
1432 | netxen_nic_driver_name, netdev->name); | ||
1433 | adapter->ahw.linkup = 0; | ||
1434 | if (netif_running(netdev)) { | ||
1435 | netif_carrier_off(netdev); | ||
1436 | netif_stop_queue(netdev); | ||
1437 | } | ||
1438 | } else if (!adapter->ahw.linkup && linkup) { | ||
1439 | printk(KERN_INFO "%s: %s NIC Link is up\n", | ||
1440 | netxen_nic_driver_name, netdev->name); | ||
1441 | adapter->ahw.linkup = 1; | ||
1442 | if (netif_running(netdev)) { | ||
1443 | netif_carrier_on(netdev); | ||
1444 | netif_wake_queue(netdev); | ||
1445 | } | ||
1446 | } | ||
1447 | } | ||
1448 | |||
1089 | static void netxen_watchdog(unsigned long v) | 1449 | static void netxen_watchdog(unsigned long v) |
1090 | { | 1450 | { |
1091 | struct netxen_adapter *adapter = (struct netxen_adapter *)v; | 1451 | struct netxen_adapter *adapter = (struct netxen_adapter *)v; |
@@ -1093,6 +1453,19 @@ static void netxen_watchdog(unsigned long v) | |||
1093 | SCHEDULE_WORK(&adapter->watchdog_task); | 1453 | SCHEDULE_WORK(&adapter->watchdog_task); |
1094 | } | 1454 | } |
1095 | 1455 | ||
1456 | void netxen_watchdog_task(struct work_struct *work) | ||
1457 | { | ||
1458 | struct netxen_adapter *adapter = | ||
1459 | container_of(work, struct netxen_adapter, watchdog_task); | ||
1460 | |||
1461 | if ((adapter->portnum == 0) && netxen_nic_check_temp(adapter)) | ||
1462 | return; | ||
1463 | |||
1464 | netxen_nic_handle_phy_intr(adapter); | ||
1465 | |||
1466 | mod_timer(&adapter->watchdog_timer, jiffies + 2 * HZ); | ||
1467 | } | ||
1468 | |||
1096 | static void netxen_tx_timeout(struct net_device *netdev) | 1469 | static void netxen_tx_timeout(struct net_device *netdev) |
1097 | { | 1470 | { |
1098 | struct netxen_adapter *adapter = (struct netxen_adapter *) | 1471 | struct netxen_adapter *adapter = (struct netxen_adapter *) |
@@ -1118,6 +1491,38 @@ static void netxen_tx_timeout_task(struct work_struct *work) | |||
1118 | netif_wake_queue(adapter->netdev); | 1491 | netif_wake_queue(adapter->netdev); |
1119 | } | 1492 | } |
1120 | 1493 | ||
1494 | /* | ||
1495 | * netxen_nic_get_stats - Get System Network Statistics | ||
1496 | * @netdev: network interface device structure | ||
1497 | */ | ||
1498 | struct net_device_stats *netxen_nic_get_stats(struct net_device *netdev) | ||
1499 | { | ||
1500 | struct netxen_adapter *adapter = netdev_priv(netdev); | ||
1501 | struct net_device_stats *stats = &adapter->net_stats; | ||
1502 | |||
1503 | memset(stats, 0, sizeof(*stats)); | ||
1504 | |||
1505 | /* total packets received */ | ||
1506 | stats->rx_packets = adapter->stats.no_rcv; | ||
1507 | /* total packets transmitted */ | ||
1508 | stats->tx_packets = adapter->stats.xmitedframes + | ||
1509 | adapter->stats.xmitfinished; | ||
1510 | /* total bytes received */ | ||
1511 | stats->rx_bytes = adapter->stats.rxbytes; | ||
1512 | /* total bytes transmitted */ | ||
1513 | stats->tx_bytes = adapter->stats.txbytes; | ||
1514 | /* bad packets received */ | ||
1515 | stats->rx_errors = adapter->stats.rcvdbadskb; | ||
1516 | /* packet transmit problems */ | ||
1517 | stats->tx_errors = adapter->stats.nocmddescriptor; | ||
1518 | /* no space in linux buffers */ | ||
1519 | stats->rx_dropped = adapter->stats.rxdropped; | ||
1520 | /* no space available in linux */ | ||
1521 | stats->tx_dropped = adapter->stats.txdropped; | ||
1522 | |||
1523 | return stats; | ||
1524 | } | ||
1525 | |||
1121 | static inline void | 1526 | static inline void |
1122 | netxen_handle_int(struct netxen_adapter *adapter) | 1527 | netxen_handle_int(struct netxen_adapter *adapter) |
1123 | { | 1528 | { |
@@ -1125,20 +1530,20 @@ netxen_handle_int(struct netxen_adapter *adapter) | |||
1125 | napi_schedule(&adapter->napi); | 1530 | napi_schedule(&adapter->napi); |
1126 | } | 1531 | } |
1127 | 1532 | ||
1128 | irqreturn_t netxen_intr(int irq, void *data) | 1533 | static irqreturn_t netxen_intr(int irq, void *data) |
1129 | { | 1534 | { |
1130 | struct netxen_adapter *adapter = data; | 1535 | struct netxen_adapter *adapter = data; |
1131 | u32 our_int = 0; | 1536 | u32 our_int = 0; |
1132 | 1537 | ||
1133 | our_int = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_INT_VECTOR)); | 1538 | our_int = adapter->pci_read_normalize(adapter, CRB_INT_VECTOR); |
1134 | /* not our interrupt */ | 1539 | /* not our interrupt */ |
1135 | if ((our_int & (0x80 << adapter->portnum)) == 0) | 1540 | if ((our_int & (0x80 << adapter->portnum)) == 0) |
1136 | return IRQ_NONE; | 1541 | return IRQ_NONE; |
1137 | 1542 | ||
1138 | if (adapter->intr_scheme == INTR_SCHEME_PERPORT) { | 1543 | if (adapter->intr_scheme == INTR_SCHEME_PERPORT) { |
1139 | /* claim interrupt */ | 1544 | /* claim interrupt */ |
1140 | writel(our_int & ~((u32)(0x80 << adapter->portnum)), | 1545 | adapter->pci_write_normalize(adapter, CRB_INT_VECTOR, |
1141 | NETXEN_CRB_NORMALIZE(adapter, CRB_INT_VECTOR)); | 1546 | our_int & ~((u32)(0x80 << adapter->portnum))); |
1142 | } | 1547 | } |
1143 | 1548 | ||
1144 | netxen_handle_int(adapter); | 1549 | netxen_handle_int(adapter); |
@@ -1146,7 +1551,7 @@ irqreturn_t netxen_intr(int irq, void *data) | |||
1146 | return IRQ_HANDLED; | 1551 | return IRQ_HANDLED; |
1147 | } | 1552 | } |
1148 | 1553 | ||
1149 | irqreturn_t netxen_msi_intr(int irq, void *data) | 1554 | static irqreturn_t netxen_msi_intr(int irq, void *data) |
1150 | { | 1555 | { |
1151 | struct netxen_adapter *adapter = data; | 1556 | struct netxen_adapter *adapter = data; |
1152 | 1557 | ||
@@ -1220,10 +1625,6 @@ module_init(netxen_init_module); | |||
1220 | 1625 | ||
1221 | static void __exit netxen_exit_module(void) | 1626 | static void __exit netxen_exit_module(void) |
1222 | { | 1627 | { |
1223 | /* | ||
1224 | * Wait for some time to allow the dma to drain, if any. | ||
1225 | */ | ||
1226 | msleep(100); | ||
1227 | pci_unregister_driver(&netxen_driver); | 1628 | pci_unregister_driver(&netxen_driver); |
1228 | destroy_workqueue(netxen_workq); | 1629 | destroy_workqueue(netxen_workq); |
1229 | } | 1630 | } |