diff options
Diffstat (limited to 'drivers/net/netxen/netxen_nic_init.c')
-rw-r--r-- | drivers/net/netxen/netxen_nic_init.c | 239 |
1 files changed, 200 insertions, 39 deletions
diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c index d122e51e43ab..0dca029bc3e5 100644 --- a/drivers/net/netxen/netxen_nic_init.c +++ b/drivers/net/netxen/netxen_nic_init.c | |||
@@ -51,11 +51,13 @@ static unsigned int crb_addr_xform[NETXEN_MAX_CRB_XFORM]; | |||
51 | crb_addr_xform[NETXEN_HW_PX_MAP_CRB_##name] = \ | 51 | crb_addr_xform[NETXEN_HW_PX_MAP_CRB_##name] = \ |
52 | NETXEN_HW_CRB_HUB_AGT_ADR_##name << 20 | 52 | NETXEN_HW_CRB_HUB_AGT_ADR_##name << 20 |
53 | 53 | ||
54 | #define NETXEN_NIC_XDMA_RESET 0x8000ff | ||
55 | |||
54 | static inline void | 56 | static inline void |
55 | netxen_nic_locked_write_reg(struct netxen_adapter *adapter, | 57 | netxen_nic_locked_write_reg(struct netxen_adapter *adapter, |
56 | unsigned long off, int *data) | 58 | unsigned long off, int *data) |
57 | { | 59 | { |
58 | void __iomem *addr = (adapter->ahw.pci_base + off); | 60 | void __iomem *addr = pci_base_offset(adapter, off); |
59 | writel(*data, addr); | 61 | writel(*data, addr); |
60 | } | 62 | } |
61 | 63 | ||
@@ -141,6 +143,24 @@ int netxen_init_firmware(struct netxen_adapter *adapter) | |||
141 | return err; | 143 | return err; |
142 | } | 144 | } |
143 | 145 | ||
146 | #define NETXEN_ADDR_LIMIT 0xffffffffULL | ||
147 | |||
148 | void *netxen_alloc(struct pci_dev *pdev, size_t sz, dma_addr_t * ptr, | ||
149 | struct pci_dev **used_dev) | ||
150 | { | ||
151 | void *addr; | ||
152 | |||
153 | addr = pci_alloc_consistent(pdev, sz, ptr); | ||
154 | if ((unsigned long long)(*ptr) < NETXEN_ADDR_LIMIT) { | ||
155 | *used_dev = pdev; | ||
156 | return addr; | ||
157 | } | ||
158 | pci_free_consistent(pdev, sz, addr, *ptr); | ||
159 | addr = pci_alloc_consistent(NULL, sz, ptr); | ||
160 | *used_dev = NULL; | ||
161 | return addr; | ||
162 | } | ||
163 | |||
144 | void netxen_initialize_adapter_sw(struct netxen_adapter *adapter) | 164 | void netxen_initialize_adapter_sw(struct netxen_adapter *adapter) |
145 | { | 165 | { |
146 | int ctxid, ring; | 166 | int ctxid, ring; |
@@ -177,23 +197,17 @@ void netxen_initialize_adapter_sw(struct netxen_adapter *adapter) | |||
177 | 197 | ||
178 | void netxen_initialize_adapter_hw(struct netxen_adapter *adapter) | 198 | void netxen_initialize_adapter_hw(struct netxen_adapter *adapter) |
179 | { | 199 | { |
200 | int ports = 0; | ||
201 | struct netxen_board_info *board_info = &(adapter->ahw.boardcfg); | ||
202 | |||
180 | if (netxen_nic_get_board_info(adapter) != 0) | 203 | if (netxen_nic_get_board_info(adapter) != 0) |
181 | printk("%s: Error getting board config info.\n", | 204 | printk("%s: Error getting board config info.\n", |
182 | netxen_nic_driver_name); | 205 | netxen_nic_driver_name); |
183 | 206 | get_brd_port_by_type(board_info->board_type, &ports); | |
184 | switch (adapter->ahw.board_type) { | 207 | if (ports == 0) |
185 | case NETXEN_NIC_GBE: | ||
186 | adapter->ahw.max_ports = 4; | ||
187 | break; | ||
188 | |||
189 | case NETXEN_NIC_XGBE: | ||
190 | adapter->ahw.max_ports = 1; | ||
191 | break; | ||
192 | |||
193 | default: | ||
194 | printk(KERN_ERR "%s: Unknown board type\n", | 208 | printk(KERN_ERR "%s: Unknown board type\n", |
195 | netxen_nic_driver_name); | 209 | netxen_nic_driver_name); |
196 | } | 210 | adapter->ahw.max_ports = ports; |
197 | } | 211 | } |
198 | 212 | ||
199 | void netxen_initialize_adapter_ops(struct netxen_adapter *adapter) | 213 | void netxen_initialize_adapter_ops(struct netxen_adapter *adapter) |
@@ -225,6 +239,7 @@ void netxen_initialize_adapter_ops(struct netxen_adapter *adapter) | |||
225 | ops->handle_phy_intr = netxen_nic_xgbe_handle_phy_intr; | 239 | ops->handle_phy_intr = netxen_nic_xgbe_handle_phy_intr; |
226 | ops->macaddr_set = netxen_niu_xg_macaddr_set; | 240 | ops->macaddr_set = netxen_niu_xg_macaddr_set; |
227 | ops->set_mtu = netxen_nic_set_mtu_xgb; | 241 | ops->set_mtu = netxen_nic_set_mtu_xgb; |
242 | ops->init_port = netxen_niu_xg_init_port; | ||
228 | ops->set_promisc = netxen_niu_xg_set_promiscuous_mode; | 243 | ops->set_promisc = netxen_niu_xg_set_promiscuous_mode; |
229 | ops->unset_promisc = netxen_niu_xg_set_promiscuous_mode; | 244 | ops->unset_promisc = netxen_niu_xg_set_promiscuous_mode; |
230 | ops->stop_port = netxen_niu_disable_xg_port; | 245 | ops->stop_port = netxen_niu_disable_xg_port; |
@@ -295,15 +310,6 @@ static inline int rom_lock(struct netxen_adapter *adapter) | |||
295 | return 0; | 310 | return 0; |
296 | } | 311 | } |
297 | 312 | ||
298 | static inline void rom_unlock(struct netxen_adapter *adapter) | ||
299 | { | ||
300 | u32 val; | ||
301 | |||
302 | /* release semaphore2 */ | ||
303 | netxen_nic_read_w0(adapter, NETXEN_PCIE_REG(PCIE_SEM2_UNLOCK), &val); | ||
304 | |||
305 | } | ||
306 | |||
307 | int netxen_wait_rom_done(struct netxen_adapter *adapter) | 313 | int netxen_wait_rom_done(struct netxen_adapter *adapter) |
308 | { | 314 | { |
309 | long timeout = 0; | 315 | long timeout = 0; |
@@ -321,6 +327,81 @@ int netxen_wait_rom_done(struct netxen_adapter *adapter) | |||
321 | return 0; | 327 | return 0; |
322 | } | 328 | } |
323 | 329 | ||
330 | static inline int netxen_rom_wren(struct netxen_adapter *adapter) | ||
331 | { | ||
332 | /* Set write enable latch in ROM status register */ | ||
333 | netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ABYTE_CNT, 0); | ||
334 | netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_INSTR_OPCODE, | ||
335 | M25P_INSTR_WREN); | ||
336 | if (netxen_wait_rom_done(adapter)) { | ||
337 | return -1; | ||
338 | } | ||
339 | return 0; | ||
340 | } | ||
341 | |||
342 | static inline unsigned int netxen_rdcrbreg(struct netxen_adapter *adapter, | ||
343 | unsigned int addr) | ||
344 | { | ||
345 | unsigned int data = 0xdeaddead; | ||
346 | data = netxen_nic_reg_read(adapter, addr); | ||
347 | return data; | ||
348 | } | ||
349 | |||
350 | static inline int netxen_do_rom_rdsr(struct netxen_adapter *adapter) | ||
351 | { | ||
352 | netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_INSTR_OPCODE, | ||
353 | M25P_INSTR_RDSR); | ||
354 | if (netxen_wait_rom_done(adapter)) { | ||
355 | return -1; | ||
356 | } | ||
357 | return netxen_rdcrbreg(adapter, NETXEN_ROMUSB_ROM_RDATA); | ||
358 | } | ||
359 | |||
360 | static inline void netxen_rom_unlock(struct netxen_adapter *adapter) | ||
361 | { | ||
362 | u32 val; | ||
363 | |||
364 | /* release semaphore2 */ | ||
365 | netxen_nic_read_w0(adapter, NETXEN_PCIE_REG(PCIE_SEM2_UNLOCK), &val); | ||
366 | |||
367 | } | ||
368 | |||
369 | int netxen_rom_wip_poll(struct netxen_adapter *adapter) | ||
370 | { | ||
371 | long timeout = 0; | ||
372 | long wip = 1; | ||
373 | int val; | ||
374 | netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ABYTE_CNT, 0); | ||
375 | while (wip != 0) { | ||
376 | val = netxen_do_rom_rdsr(adapter); | ||
377 | wip = val & 1; | ||
378 | timeout++; | ||
379 | if (timeout > rom_max_timeout) { | ||
380 | return -1; | ||
381 | } | ||
382 | } | ||
383 | return 0; | ||
384 | } | ||
385 | |||
386 | static inline int do_rom_fast_write(struct netxen_adapter *adapter, | ||
387 | int addr, int data) | ||
388 | { | ||
389 | if (netxen_rom_wren(adapter)) { | ||
390 | return -1; | ||
391 | } | ||
392 | netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_WDATA, data); | ||
393 | netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ADDRESS, addr); | ||
394 | netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ABYTE_CNT, 3); | ||
395 | netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_INSTR_OPCODE, | ||
396 | M25P_INSTR_PP); | ||
397 | if (netxen_wait_rom_done(adapter)) { | ||
398 | netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ABYTE_CNT, 0); | ||
399 | return -1; | ||
400 | } | ||
401 | |||
402 | return netxen_rom_wip_poll(adapter); | ||
403 | } | ||
404 | |||
324 | static inline int | 405 | static inline int |
325 | do_rom_fast_read(struct netxen_adapter *adapter, int addr, int *valp) | 406 | do_rom_fast_read(struct netxen_adapter *adapter, int addr, int *valp) |
326 | { | 407 | { |
@@ -350,7 +431,43 @@ int netxen_rom_fast_read(struct netxen_adapter *adapter, int addr, int *valp) | |||
350 | return -EIO; | 431 | return -EIO; |
351 | 432 | ||
352 | ret = do_rom_fast_read(adapter, addr, valp); | 433 | ret = do_rom_fast_read(adapter, addr, valp); |
353 | rom_unlock(adapter); | 434 | netxen_rom_unlock(adapter); |
435 | return ret; | ||
436 | } | ||
437 | |||
438 | int netxen_rom_fast_write(struct netxen_adapter *adapter, int addr, int data) | ||
439 | { | ||
440 | int ret = 0; | ||
441 | |||
442 | if (rom_lock(adapter) != 0) { | ||
443 | return -1; | ||
444 | } | ||
445 | ret = do_rom_fast_write(adapter, addr, data); | ||
446 | netxen_rom_unlock(adapter); | ||
447 | return ret; | ||
448 | } | ||
449 | int netxen_do_rom_se(struct netxen_adapter *adapter, int addr) | ||
450 | { | ||
451 | netxen_rom_wren(adapter); | ||
452 | netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ADDRESS, addr); | ||
453 | netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ABYTE_CNT, 3); | ||
454 | netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_INSTR_OPCODE, | ||
455 | M25P_INSTR_SE); | ||
456 | if (netxen_wait_rom_done(adapter)) { | ||
457 | netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ABYTE_CNT, 0); | ||
458 | return -1; | ||
459 | } | ||
460 | return netxen_rom_wip_poll(adapter); | ||
461 | } | ||
462 | |||
463 | int netxen_rom_se(struct netxen_adapter *adapter, int addr) | ||
464 | { | ||
465 | int ret = 0; | ||
466 | if (rom_lock(adapter) != 0) { | ||
467 | return -1; | ||
468 | } | ||
469 | ret = netxen_do_rom_se(adapter, addr); | ||
470 | netxen_rom_unlock(adapter); | ||
354 | return ret; | 471 | return ret; |
355 | } | 472 | } |
356 | 473 | ||
@@ -372,7 +489,7 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose) | |||
372 | /* resetall */ | 489 | /* resetall */ |
373 | status = netxen_nic_get_board_info(adapter); | 490 | status = netxen_nic_get_board_info(adapter); |
374 | if (status) | 491 | if (status) |
375 | printk("%s: pinit_from_rom: Error getting board info\n", | 492 | printk("%s: netxen_pinit_from_rom: Error getting board info\n", |
376 | netxen_nic_driver_name); | 493 | netxen_nic_driver_name); |
377 | 494 | ||
378 | netxen_crb_writelit_adapter(adapter, NETXEN_ROMUSB_GLB_SW_RESET, | 495 | netxen_crb_writelit_adapter(adapter, NETXEN_ROMUSB_GLB_SW_RESET, |
@@ -408,8 +525,8 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose) | |||
408 | } | 525 | } |
409 | buf = kcalloc(n, sizeof(struct crb_addr_pair), GFP_KERNEL); | 526 | buf = kcalloc(n, sizeof(struct crb_addr_pair), GFP_KERNEL); |
410 | if (buf == NULL) { | 527 | if (buf == NULL) { |
411 | printk("%s: pinit_from_rom: Unable to calloc memory.\n", | 528 | printk("%s: netxen_pinit_from_rom: Unable to calloc " |
412 | netxen_nic_driver_name); | 529 | "memory.\n", netxen_nic_driver_name); |
413 | return -ENOMEM; | 530 | return -ENOMEM; |
414 | } | 531 | } |
415 | for (i = 0; i < n; i++) { | 532 | for (i = 0; i < n; i++) { |
@@ -441,7 +558,7 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose) | |||
441 | if (off == NETXEN_ROMUSB_GLB_SW_RESET) { | 558 | if (off == NETXEN_ROMUSB_GLB_SW_RESET) { |
442 | init_delay = 1; | 559 | init_delay = 1; |
443 | /* hold xdma in reset also */ | 560 | /* hold xdma in reset also */ |
444 | buf[i].data = 0x8000ff; | 561 | buf[i].data = NETXEN_NIC_XDMA_RESET; |
445 | } | 562 | } |
446 | 563 | ||
447 | if (ADDR_IN_WINDOW1(off)) { | 564 | if (ADDR_IN_WINDOW1(off)) { |
@@ -450,7 +567,7 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose) | |||
450 | } else { | 567 | } else { |
451 | netxen_nic_pci_change_crbwindow(adapter, 0); | 568 | netxen_nic_pci_change_crbwindow(adapter, 0); |
452 | writel(buf[i].data, | 569 | writel(buf[i].data, |
453 | adapter->ahw.pci_base + off); | 570 | pci_base_offset(adapter, off)); |
454 | 571 | ||
455 | netxen_nic_pci_change_crbwindow(adapter, 1); | 572 | netxen_nic_pci_change_crbwindow(adapter, 1); |
456 | } | 573 | } |
@@ -505,18 +622,15 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose) | |||
505 | return 0; | 622 | return 0; |
506 | } | 623 | } |
507 | 624 | ||
508 | void netxen_phantom_init(struct netxen_adapter *adapter) | 625 | void netxen_phantom_init(struct netxen_adapter *adapter, int pegtune_val) |
509 | { | 626 | { |
510 | u32 val = 0; | 627 | u32 val = 0; |
511 | int loops = 0; | 628 | int loops = 0; |
512 | 629 | ||
513 | netxen_nic_hw_read_wx(adapter, NETXEN_ROMUSB_GLB_PEGTUNE_DONE, &val, 4); | 630 | if (!pegtune_val) { |
514 | writel(1, | ||
515 | NETXEN_CRB_NORMALIZE(adapter, NETXEN_ROMUSB_GLB_PEGTUNE_DONE)); | ||
516 | |||
517 | if (0 == val) { | ||
518 | while (val != PHAN_INITIALIZE_COMPLETE && loops < 200000) { | 631 | while (val != PHAN_INITIALIZE_COMPLETE && loops < 200000) { |
519 | udelay(100); | 632 | udelay(100); |
633 | schedule(); | ||
520 | val = | 634 | val = |
521 | readl(NETXEN_CRB_NORMALIZE | 635 | readl(NETXEN_CRB_NORMALIZE |
522 | (adapter, CRB_CMDPEG_STATE)); | 636 | (adapter, CRB_CMDPEG_STATE)); |
@@ -536,7 +650,7 @@ int netxen_nic_rx_has_work(struct netxen_adapter *adapter) | |||
536 | &(adapter->recv_ctx[ctx]); | 650 | &(adapter->recv_ctx[ctx]); |
537 | u32 consumer; | 651 | u32 consumer; |
538 | struct status_desc *desc_head; | 652 | struct status_desc *desc_head; |
539 | struct status_desc *desc; /* used to read status desc here */ | 653 | struct status_desc *desc; |
540 | 654 | ||
541 | consumer = recv_ctx->status_rx_consumer; | 655 | consumer = recv_ctx->status_rx_consumer; |
542 | desc_head = recv_ctx->rcv_status_desc_head; | 656 | desc_head = recv_ctx->rcv_status_desc_head; |
@@ -549,6 +663,53 @@ int netxen_nic_rx_has_work(struct netxen_adapter *adapter) | |||
549 | return 0; | 663 | return 0; |
550 | } | 664 | } |
551 | 665 | ||
666 | static inline int netxen_nic_check_temp(struct netxen_adapter *adapter) | ||
667 | { | ||
668 | int port_num; | ||
669 | struct netxen_port *port; | ||
670 | struct net_device *netdev; | ||
671 | uint32_t temp, temp_state, temp_val; | ||
672 | int rv = 0; | ||
673 | |||
674 | temp = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_TEMP_STATE)); | ||
675 | |||
676 | temp_state = nx_get_temp_state(temp); | ||
677 | temp_val = nx_get_temp_val(temp); | ||
678 | |||
679 | if (temp_state == NX_TEMP_PANIC) { | ||
680 | printk(KERN_ALERT | ||
681 | "%s: Device temperature %d degrees C exceeds" | ||
682 | " maximum allowed. Hardware has been shut down.\n", | ||
683 | netxen_nic_driver_name, temp_val); | ||
684 | for (port_num = 0; port_num < adapter->ahw.max_ports; | ||
685 | port_num++) { | ||
686 | port = adapter->port[port_num]; | ||
687 | netdev = port->netdev; | ||
688 | |||
689 | netif_carrier_off(netdev); | ||
690 | netif_stop_queue(netdev); | ||
691 | } | ||
692 | rv = 1; | ||
693 | } else if (temp_state == NX_TEMP_WARN) { | ||
694 | if (adapter->temp == NX_TEMP_NORMAL) { | ||
695 | printk(KERN_ALERT | ||
696 | "%s: Device temperature %d degrees C " | ||
697 | "exceeds operating range." | ||
698 | " Immediate action needed.\n", | ||
699 | netxen_nic_driver_name, temp_val); | ||
700 | } | ||
701 | } else { | ||
702 | if (adapter->temp == NX_TEMP_WARN) { | ||
703 | printk(KERN_INFO | ||
704 | "%s: Device temperature is now %d degrees C" | ||
705 | " in normal range.\n", netxen_nic_driver_name, | ||
706 | temp_val); | ||
707 | } | ||
708 | } | ||
709 | adapter->temp = temp_state; | ||
710 | return rv; | ||
711 | } | ||
712 | |||
552 | void netxen_watchdog_task(unsigned long v) | 713 | void netxen_watchdog_task(unsigned long v) |
553 | { | 714 | { |
554 | int port_num; | 715 | int port_num; |
@@ -556,6 +717,9 @@ void netxen_watchdog_task(unsigned long v) | |||
556 | struct net_device *netdev; | 717 | struct net_device *netdev; |
557 | struct netxen_adapter *adapter = (struct netxen_adapter *)v; | 718 | struct netxen_adapter *adapter = (struct netxen_adapter *)v; |
558 | 719 | ||
720 | if (netxen_nic_check_temp(adapter)) | ||
721 | return; | ||
722 | |||
559 | for (port_num = 0; port_num < adapter->ahw.max_ports; port_num++) { | 723 | for (port_num = 0; port_num < adapter->ahw.max_ports; port_num++) { |
560 | port = adapter->port[port_num]; | 724 | port = adapter->port[port_num]; |
561 | netdev = port->netdev; | 725 | netdev = port->netdev; |
@@ -570,8 +734,6 @@ void netxen_watchdog_task(unsigned long v) | |||
570 | netif_wake_queue(netdev); | 734 | netif_wake_queue(netdev); |
571 | } | 735 | } |
572 | 736 | ||
573 | netxen_nic_pci_change_crbwindow(adapter, 1); | ||
574 | |||
575 | if (adapter->ops->handle_phy_intr) | 737 | if (adapter->ops->handle_phy_intr) |
576 | adapter->ops->handle_phy_intr(adapter); | 738 | adapter->ops->handle_phy_intr(adapter); |
577 | mod_timer(&adapter->watchdog_timer, jiffies + 2 * HZ); | 739 | mod_timer(&adapter->watchdog_timer, jiffies + 2 * HZ); |
@@ -742,7 +904,6 @@ void netxen_process_cmd_ring(unsigned long data) | |||
742 | * number as part of the descriptor. This way we will be able to get | 904 | * number as part of the descriptor. This way we will be able to get |
743 | * the netdev which is associated with that device. | 905 | * the netdev which is associated with that device. |
744 | */ | 906 | */ |
745 | /* Window = 1 */ | ||
746 | consumer = | 907 | consumer = |
747 | readl(NETXEN_CRB_NORMALIZE(adapter, CRB_CMD_CONSUMER_OFFSET)); | 908 | readl(NETXEN_CRB_NORMALIZE(adapter, CRB_CMD_CONSUMER_OFFSET)); |
748 | 909 | ||
@@ -861,7 +1022,7 @@ void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ctx, u32 ringid) | |||
861 | * We need to schedule the posting of buffers to the pegs. | 1022 | * We need to schedule the posting of buffers to the pegs. |
862 | */ | 1023 | */ |
863 | rcv_desc->begin_alloc = index; | 1024 | rcv_desc->begin_alloc = index; |
864 | DPRINTK(ERR, "unm_post_rx_buffers: " | 1025 | DPRINTK(ERR, "netxen_post_rx_buffers: " |
865 | " allocated only %d buffers\n", count); | 1026 | " allocated only %d buffers\n", count); |
866 | break; | 1027 | break; |
867 | } | 1028 | } |