diff options
author | Dhananjay Phadke <dhananjay@netxen.com> | 2008-07-21 22:44:04 -0400 |
---|---|---|
committer | Jeff Garzik <jgarzik@redhat.com> | 2008-07-22 17:51:53 -0400 |
commit | 2956640d4aaaecd42bd8ba800cc8c33bfe206b7e (patch) | |
tree | 78c0442fd1a382f5f01489d4f268c5876d243b95 /drivers/net | |
parent | 3ce06a320f8d5a3f16960e63021cc372283efffb (diff) |
netxen: pci probe and firmware init changes
Add initialization code in pci probe for new chip and retain
compatibility with old revisions.
Signed-off-by: Dhananjay Phadke <dhananjay@netxen.com>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/netxen/netxen_nic.h | 40 | ||||
-rw-r--r-- | drivers/net/netxen/netxen_nic_hw.c | 71 | ||||
-rw-r--r-- | drivers/net/netxen/netxen_nic_init.c | 404 | ||||
-rw-r--r-- | drivers/net/netxen/netxen_nic_main.c | 795 |
4 files changed, 872 insertions, 438 deletions
diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h index 29ab2ce30d6e..b23a5a447f0c 100644 --- a/drivers/net/netxen/netxen_nic.h +++ b/drivers/net/netxen/netxen_nic.h | |||
@@ -801,6 +801,7 @@ struct netxen_hardware_context { | |||
801 | unsigned long db_len; | 801 | unsigned long db_len; |
802 | unsigned long pci_len0; | 802 | unsigned long pci_len0; |
803 | 803 | ||
804 | u8 cut_through; | ||
804 | int qdr_sn_window; | 805 | int qdr_sn_window; |
805 | int ddr_mn_window; | 806 | int ddr_mn_window; |
806 | unsigned long mn_win_crb; | 807 | unsigned long mn_win_crb; |
@@ -871,9 +872,16 @@ struct netxen_recv_context { | |||
871 | struct status_desc *rcv_status_desc_head; | 872 | struct status_desc *rcv_status_desc_head; |
872 | }; | 873 | }; |
873 | 874 | ||
874 | #define NETXEN_NIC_MSI_ENABLED 0x02 | 875 | #define NETXEN_NIC_MSI_ENABLED 0x02 |
875 | #define NETXEN_DMA_MASK 0xfffffffe | 876 | #define NETXEN_NIC_MSIX_ENABLED 0x04 |
876 | #define NETXEN_DB_MAPSIZE_BYTES 0x1000 | 877 | #define NETXEN_IS_MSI_FAMILY(adapter) \ |
878 | ((adapter)->flags & (NETXEN_NIC_MSI_ENABLED | NETXEN_NIC_MSIX_ENABLED)) | ||
879 | |||
880 | #define MSIX_ENTRIES_PER_ADAPTER 8 | ||
881 | #define NETXEN_MSIX_TBL_SPACE 8192 | ||
882 | #define NETXEN_PCI_REG_MSIX_TBL 0x44 | ||
883 | |||
884 | #define NETXEN_DB_MAPSIZE_BYTES 0x1000 | ||
877 | 885 | ||
878 | struct netxen_dummy_dma { | 886 | struct netxen_dummy_dma { |
879 | void *addr; | 887 | void *addr; |
@@ -885,6 +893,7 @@ struct netxen_adapter { | |||
885 | 893 | ||
886 | struct net_device *netdev; | 894 | struct net_device *netdev; |
887 | struct pci_dev *pdev; | 895 | struct pci_dev *pdev; |
896 | int pci_using_dac; | ||
888 | struct napi_struct napi; | 897 | struct napi_struct napi; |
889 | struct net_device_stats net_stats; | 898 | struct net_device_stats net_stats; |
890 | unsigned char mac_addr[ETH_ALEN]; | 899 | unsigned char mac_addr[ETH_ALEN]; |
@@ -895,6 +904,8 @@ struct netxen_adapter { | |||
895 | uint8_t mc_enabled; | 904 | uint8_t mc_enabled; |
896 | uint8_t max_mc_count; | 905 | uint8_t max_mc_count; |
897 | 906 | ||
907 | struct netxen_legacy_intr_set legacy_intr; | ||
908 | |||
898 | struct work_struct watchdog_task; | 909 | struct work_struct watchdog_task; |
899 | struct timer_list watchdog_timer; | 910 | struct timer_list watchdog_timer; |
900 | struct work_struct tx_timeout_task; | 911 | struct work_struct tx_timeout_task; |
@@ -903,6 +914,8 @@ struct netxen_adapter { | |||
903 | u32 crb_win; | 914 | u32 crb_win; |
904 | rwlock_t adapter_lock; | 915 | rwlock_t adapter_lock; |
905 | 916 | ||
917 | uint64_t dma_mask; | ||
918 | |||
906 | u32 cmd_producer; | 919 | u32 cmd_producer; |
907 | __le32 *cmd_consumer; | 920 | __le32 *cmd_consumer; |
908 | u32 last_cmd_consumer; | 921 | u32 last_cmd_consumer; |
@@ -919,6 +932,12 @@ struct netxen_adapter { | |||
919 | int driver_mismatch; | 932 | int driver_mismatch; |
920 | u32 temp; | 933 | u32 temp; |
921 | 934 | ||
935 | u32 fw_major; | ||
936 | |||
937 | u8 msix_supported; | ||
938 | u8 max_possible_rss_rings; | ||
939 | struct msix_entry msix_entries[MSIX_ENTRIES_PER_ADAPTER]; | ||
940 | |||
922 | struct netxen_adapter_stats stats; | 941 | struct netxen_adapter_stats stats; |
923 | 942 | ||
924 | u16 link_speed; | 943 | u16 link_speed; |
@@ -1092,8 +1111,10 @@ unsigned long netxen_nic_pci_set_window_2M(struct netxen_adapter *adapter, | |||
1092 | void netxen_free_adapter_offload(struct netxen_adapter *adapter); | 1111 | void netxen_free_adapter_offload(struct netxen_adapter *adapter); |
1093 | int netxen_initialize_adapter_offload(struct netxen_adapter *adapter); | 1112 | int netxen_initialize_adapter_offload(struct netxen_adapter *adapter); |
1094 | int netxen_phantom_init(struct netxen_adapter *adapter, int pegtune_val); | 1113 | int netxen_phantom_init(struct netxen_adapter *adapter, int pegtune_val); |
1114 | int netxen_receive_peg_ready(struct netxen_adapter *adapter); | ||
1095 | int netxen_load_firmware(struct netxen_adapter *adapter); | 1115 | int netxen_load_firmware(struct netxen_adapter *adapter); |
1096 | int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose); | 1116 | int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose); |
1117 | |||
1097 | int netxen_rom_fast_read(struct netxen_adapter *adapter, int addr, int *valp); | 1118 | int netxen_rom_fast_read(struct netxen_adapter *adapter, int addr, int *valp); |
1098 | int netxen_rom_fast_read_words(struct netxen_adapter *adapter, int addr, | 1119 | int netxen_rom_fast_read_words(struct netxen_adapter *adapter, int addr, |
1099 | u8 *bytes, size_t size); | 1120 | u8 *bytes, size_t size); |
@@ -1107,14 +1128,19 @@ void netxen_halt_pegs(struct netxen_adapter *adapter); | |||
1107 | 1128 | ||
1108 | int netxen_rom_se(struct netxen_adapter *adapter, int addr); | 1129 | int netxen_rom_se(struct netxen_adapter *adapter, int addr); |
1109 | 1130 | ||
1110 | /* Functions from netxen_nic_isr.c */ | 1131 | int netxen_alloc_sw_resources(struct netxen_adapter *adapter); |
1111 | void netxen_initialize_adapter_sw(struct netxen_adapter *adapter); | 1132 | void netxen_free_sw_resources(struct netxen_adapter *adapter); |
1133 | |||
1134 | int netxen_alloc_hw_resources(struct netxen_adapter *adapter); | ||
1135 | void netxen_free_hw_resources(struct netxen_adapter *adapter); | ||
1136 | |||
1137 | void netxen_release_rx_buffers(struct netxen_adapter *adapter); | ||
1138 | void netxen_release_tx_buffers(struct netxen_adapter *adapter); | ||
1139 | |||
1112 | void netxen_initialize_adapter_ops(struct netxen_adapter *adapter); | 1140 | void netxen_initialize_adapter_ops(struct netxen_adapter *adapter); |
1113 | int netxen_init_firmware(struct netxen_adapter *adapter); | 1141 | int netxen_init_firmware(struct netxen_adapter *adapter); |
1114 | void netxen_free_hw_resources(struct netxen_adapter *adapter); | ||
1115 | void netxen_tso_check(struct netxen_adapter *adapter, | 1142 | void netxen_tso_check(struct netxen_adapter *adapter, |
1116 | struct cmd_desc_type0 *desc, struct sk_buff *skb); | 1143 | struct cmd_desc_type0 *desc, struct sk_buff *skb); |
1117 | int netxen_nic_hw_resources(struct netxen_adapter *adapter); | ||
1118 | void netxen_nic_clear_stats(struct netxen_adapter *adapter); | 1144 | void netxen_nic_clear_stats(struct netxen_adapter *adapter); |
1119 | void netxen_watchdog_task(struct work_struct *work); | 1145 | void netxen_watchdog_task(struct work_struct *work); |
1120 | void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ctx, | 1146 | void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ctx, |
diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c index defbeeac5dbe..fde8c6f1c9f5 100644 --- a/drivers/net/netxen/netxen_nic_hw.c +++ b/drivers/net/netxen/netxen_nic_hw.c | |||
@@ -359,8 +359,6 @@ static u64 ctx_addr_sig_regs[][3] = { | |||
359 | #define ADDR_IN_RANGE(addr, low, high) \ | 359 | #define ADDR_IN_RANGE(addr, low, high) \ |
360 | (((addr) <= (high)) && ((addr) >= (low))) | 360 | (((addr) <= (high)) && ((addr) >= (low))) |
361 | 361 | ||
362 | #define NETXEN_FLASH_BASE (NETXEN_BOOTLD_START) | ||
363 | #define NETXEN_PHANTOM_MEM_BASE (NETXEN_FLASH_BASE) | ||
364 | #define NETXEN_MAX_MTU 8000 + NETXEN_ENET_HEADER_SIZE + NETXEN_ETH_FCS_SIZE | 362 | #define NETXEN_MAX_MTU 8000 + NETXEN_ENET_HEADER_SIZE + NETXEN_ETH_FCS_SIZE |
365 | #define NETXEN_MIN_MTU 64 | 363 | #define NETXEN_MIN_MTU 64 |
366 | #define NETXEN_ETH_FCS_SIZE 4 | 364 | #define NETXEN_ETH_FCS_SIZE 4 |
@@ -381,8 +379,6 @@ static u64 ctx_addr_sig_regs[][3] = { | |||
381 | 379 | ||
382 | #define NETXEN_NIC_WINDOW_MARGIN 0x100000 | 380 | #define NETXEN_NIC_WINDOW_MARGIN 0x100000 |
383 | 381 | ||
384 | void netxen_free_hw_resources(struct netxen_adapter *adapter); | ||
385 | |||
386 | int netxen_nic_set_mac(struct net_device *netdev, void *p) | 382 | int netxen_nic_set_mac(struct net_device *netdev, void *p) |
387 | { | 383 | { |
388 | struct netxen_adapter *adapter = netdev_priv(netdev); | 384 | struct netxen_adapter *adapter = netdev_priv(netdev); |
@@ -564,41 +560,22 @@ int netxen_nic_change_mtu(struct net_device *netdev, int mtu) | |||
564 | * check if the firmware has been downloaded and ready to run and | 560 | * check if the firmware has been downloaded and ready to run and |
565 | * setup the address for the descriptors in the adapter | 561 | * setup the address for the descriptors in the adapter |
566 | */ | 562 | */ |
567 | int netxen_nic_hw_resources(struct netxen_adapter *adapter) | 563 | int netxen_alloc_hw_resources(struct netxen_adapter *adapter) |
568 | { | 564 | { |
569 | struct netxen_hardware_context *hw = &adapter->ahw; | 565 | struct netxen_hardware_context *hw = &adapter->ahw; |
570 | u32 state = 0; | 566 | u32 state = 0; |
571 | void *addr; | 567 | void *addr; |
572 | int loops = 0, err = 0; | 568 | int err = 0; |
573 | int ctx, ring; | 569 | int ctx, ring; |
574 | struct netxen_recv_context *recv_ctx; | 570 | struct netxen_recv_context *recv_ctx; |
575 | struct netxen_rcv_desc_ctx *rcv_desc; | 571 | struct netxen_rcv_desc_ctx *rcv_desc; |
576 | int func_id = adapter->portnum; | 572 | int func_id = adapter->portnum; |
577 | 573 | ||
578 | DPRINTK(INFO, "crb_base: %lx %x", NETXEN_PCI_CRBSPACE, | 574 | err = netxen_receive_peg_ready(adapter); |
579 | PCI_OFFSET_SECOND_RANGE(adapter, NETXEN_PCI_CRBSPACE)); | 575 | if (err) { |
580 | DPRINTK(INFO, "cam base: %lx %x", NETXEN_CRB_CAM, | 576 | printk(KERN_ERR "Rcv Peg initialization not complete:%x.\n", |
581 | pci_base_offset(adapter, NETXEN_CRB_CAM)); | 577 | state); |
582 | DPRINTK(INFO, "cam RAM: %lx %x", NETXEN_CAM_RAM_BASE, | 578 | return err; |
583 | pci_base_offset(adapter, NETXEN_CAM_RAM_BASE)); | ||
584 | |||
585 | |||
586 | for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) { | ||
587 | loops = 0; | ||
588 | state = 0; | ||
589 | do { | ||
590 | /* Window 1 call */ | ||
591 | state = adapter->pci_read_normalize(adapter, | ||
592 | CRB_RCVPEG_STATE); | ||
593 | msleep(1); | ||
594 | loops++; | ||
595 | } while (state != PHAN_PEG_RCV_INITIALIZED && loops < 20); | ||
596 | if (loops >= 20) { | ||
597 | printk(KERN_ERR "Rcv Peg initialization not complete:" | ||
598 | "%x.\n", state); | ||
599 | err = -EIO; | ||
600 | return err; | ||
601 | } | ||
602 | } | 579 | } |
603 | adapter->intr_scheme = adapter->pci_read_normalize(adapter, | 580 | adapter->intr_scheme = adapter->pci_read_normalize(adapter, |
604 | CRB_NIC_CAPABILITIES_FW); | 581 | CRB_NIC_CAPABILITIES_FW); |
@@ -992,10 +969,12 @@ int netxen_load_firmware(struct netxen_adapter *adapter) | |||
992 | { | 969 | { |
993 | int i; | 970 | int i; |
994 | u32 data, size = 0; | 971 | u32 data, size = 0; |
995 | u32 flashaddr = NETXEN_FLASH_BASE, memaddr = NETXEN_PHANTOM_MEM_BASE; | 972 | u32 flashaddr = NETXEN_BOOTLD_START, memaddr = NETXEN_BOOTLD_START; |
973 | |||
974 | size = (NETXEN_IMAGE_START - NETXEN_BOOTLD_START)/4; | ||
996 | 975 | ||
997 | size = NETXEN_FIRMWARE_LEN; | 976 | if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) |
998 | adapter->pci_write_normalize(adapter, | 977 | adapter->pci_write_normalize(adapter, |
999 | NETXEN_ROMUSB_GLB_CAS_RST, 1); | 978 | NETXEN_ROMUSB_GLB_CAS_RST, 1); |
1000 | 979 | ||
1001 | for (i = 0; i < size; i++) { | 980 | for (i = 0; i < size; i++) { |
@@ -1007,12 +986,17 @@ int netxen_load_firmware(struct netxen_adapter *adapter) | |||
1007 | memaddr += 4; | 986 | memaddr += 4; |
1008 | cond_resched(); | 987 | cond_resched(); |
1009 | } | 988 | } |
1010 | udelay(100); | 989 | msleep(1); |
1011 | /* make sure Casper is powered on */ | 990 | |
1012 | adapter->pci_write_normalize(adapter, | 991 | if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) |
992 | adapter->pci_write_normalize(adapter, | ||
993 | NETXEN_ROMUSB_GLB_SW_RESET, 0x80001d); | ||
994 | else { | ||
995 | adapter->pci_write_normalize(adapter, | ||
1013 | NETXEN_ROMUSB_GLB_CHIP_CLK_CTRL, 0x3fff); | 996 | NETXEN_ROMUSB_GLB_CHIP_CLK_CTRL, 0x3fff); |
1014 | adapter->pci_write_normalize(adapter, | 997 | adapter->pci_write_normalize(adapter, |
1015 | NETXEN_ROMUSB_GLB_CAS_RST, 0); | 998 | NETXEN_ROMUSB_GLB_CAS_RST, 0); |
999 | } | ||
1016 | 1000 | ||
1017 | return 0; | 1001 | return 0; |
1018 | } | 1002 | } |
@@ -2241,6 +2225,8 @@ void netxen_nic_flash_print(struct netxen_adapter *adapter) | |||
2241 | adapter->hw_read_wx(adapter, NETXEN_FW_VERSION_MINOR, &fw_minor, 4); | 2225 | adapter->hw_read_wx(adapter, NETXEN_FW_VERSION_MINOR, &fw_minor, 4); |
2242 | adapter->hw_read_wx(adapter, NETXEN_FW_VERSION_SUB, &fw_build, 4); | 2226 | adapter->hw_read_wx(adapter, NETXEN_FW_VERSION_SUB, &fw_build, 4); |
2243 | 2227 | ||
2228 | adapter->fw_major = fw_major; | ||
2229 | |||
2244 | if (adapter->portnum == 0) { | 2230 | if (adapter->portnum == 0) { |
2245 | get_brd_name_by_type(board_info->board_type, brd_name); | 2231 | get_brd_name_by_type(board_info->board_type, brd_name); |
2246 | 2232 | ||
@@ -2262,16 +2248,5 @@ void netxen_nic_flash_print(struct netxen_adapter *adapter) | |||
2262 | adapter->netdev->name); | 2248 | adapter->netdev->name); |
2263 | return; | 2249 | return; |
2264 | } | 2250 | } |
2265 | |||
2266 | switch (adapter->ahw.board_type) { | ||
2267 | case NETXEN_NIC_GBE: | ||
2268 | dev_info(&adapter->pdev->dev, "%s: GbE port initialized\n", | ||
2269 | adapter->netdev->name); | ||
2270 | break; | ||
2271 | case NETXEN_NIC_XGBE: | ||
2272 | dev_info(&adapter->pdev->dev, "%s: XGbE port initialized\n", | ||
2273 | adapter->netdev->name); | ||
2274 | break; | ||
2275 | } | ||
2276 | } | 2251 | } |
2277 | 2252 | ||
diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c index 7323cd7b544a..c6e2bc71d8f3 100644 --- a/drivers/net/netxen/netxen_nic_init.c +++ b/drivers/net/netxen/netxen_nic_init.c | |||
@@ -130,7 +130,7 @@ int netxen_init_firmware(struct netxen_adapter *adapter) | |||
130 | return 0; | 130 | return 0; |
131 | 131 | ||
132 | while (state != PHAN_INITIALIZE_COMPLETE && loops < 2000) { | 132 | while (state != PHAN_INITIALIZE_COMPLETE && loops < 2000) { |
133 | udelay(100); | 133 | msleep(1); |
134 | /* Window 1 call */ | 134 | /* Window 1 call */ |
135 | state = adapter->pci_read_normalize(adapter, CRB_CMDPEG_STATE); | 135 | state = adapter->pci_read_normalize(adapter, CRB_CMDPEG_STATE); |
136 | 136 | ||
@@ -155,34 +155,165 @@ int netxen_init_firmware(struct netxen_adapter *adapter) | |||
155 | return err; | 155 | return err; |
156 | } | 156 | } |
157 | 157 | ||
158 | void netxen_initialize_adapter_sw(struct netxen_adapter *adapter) | 158 | void netxen_release_rx_buffers(struct netxen_adapter *adapter) |
159 | { | 159 | { |
160 | int ctxid, ring; | 160 | struct netxen_recv_context *recv_ctx; |
161 | u32 i; | ||
162 | u32 num_rx_bufs = 0; | ||
163 | struct netxen_rcv_desc_ctx *rcv_desc; | 161 | struct netxen_rcv_desc_ctx *rcv_desc; |
162 | struct netxen_rx_buffer *rx_buf; | ||
163 | int i, ctxid, ring; | ||
164 | 164 | ||
165 | DPRINTK(INFO, "initializing some queues: %p\n", adapter); | ||
166 | for (ctxid = 0; ctxid < MAX_RCV_CTX; ++ctxid) { | 165 | for (ctxid = 0; ctxid < MAX_RCV_CTX; ++ctxid) { |
166 | recv_ctx = &adapter->recv_ctx[ctxid]; | ||
167 | for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) { | 167 | for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) { |
168 | struct netxen_rx_buffer *rx_buf; | 168 | rcv_desc = &recv_ctx->rcv_desc[ring]; |
169 | rcv_desc = &adapter->recv_ctx[ctxid].rcv_desc[ring]; | 169 | for (i = 0; i < rcv_desc->max_rx_desc_count; ++i) { |
170 | rx_buf = &(rcv_desc->rx_buf_arr[i]); | ||
171 | if (rx_buf->state == NETXEN_BUFFER_FREE) | ||
172 | continue; | ||
173 | pci_unmap_single(adapter->pdev, | ||
174 | rx_buf->dma, | ||
175 | rcv_desc->dma_size, | ||
176 | PCI_DMA_FROMDEVICE); | ||
177 | if (rx_buf->skb != NULL) | ||
178 | dev_kfree_skb_any(rx_buf->skb); | ||
179 | } | ||
180 | } | ||
181 | } | ||
182 | } | ||
183 | |||
184 | void netxen_release_tx_buffers(struct netxen_adapter *adapter) | ||
185 | { | ||
186 | struct netxen_cmd_buffer *cmd_buf; | ||
187 | struct netxen_skb_frag *buffrag; | ||
188 | int i, j; | ||
189 | |||
190 | cmd_buf = adapter->cmd_buf_arr; | ||
191 | for (i = 0; i < adapter->max_tx_desc_count; i++) { | ||
192 | buffrag = cmd_buf->frag_array; | ||
193 | if (buffrag->dma) { | ||
194 | pci_unmap_single(adapter->pdev, buffrag->dma, | ||
195 | buffrag->length, PCI_DMA_TODEVICE); | ||
196 | buffrag->dma = 0ULL; | ||
197 | } | ||
198 | for (j = 0; j < cmd_buf->frag_count; j++) { | ||
199 | buffrag++; | ||
200 | if (buffrag->dma) { | ||
201 | pci_unmap_page(adapter->pdev, buffrag->dma, | ||
202 | buffrag->length, | ||
203 | PCI_DMA_TODEVICE); | ||
204 | buffrag->dma = 0ULL; | ||
205 | } | ||
206 | } | ||
207 | /* Free the skb we received in netxen_nic_xmit_frame */ | ||
208 | if (cmd_buf->skb) { | ||
209 | dev_kfree_skb_any(cmd_buf->skb); | ||
210 | cmd_buf->skb = NULL; | ||
211 | } | ||
212 | cmd_buf++; | ||
213 | } | ||
214 | } | ||
215 | |||
216 | void netxen_free_sw_resources(struct netxen_adapter *adapter) | ||
217 | { | ||
218 | struct netxen_recv_context *recv_ctx; | ||
219 | struct netxen_rcv_desc_ctx *rcv_desc; | ||
220 | int ctx, ring; | ||
221 | |||
222 | for (ctx = 0; ctx < MAX_RCV_CTX; ctx++) { | ||
223 | recv_ctx = &adapter->recv_ctx[ctx]; | ||
224 | for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) { | ||
225 | rcv_desc = &recv_ctx->rcv_desc[ring]; | ||
226 | if (rcv_desc->rx_buf_arr) { | ||
227 | vfree(rcv_desc->rx_buf_arr); | ||
228 | rcv_desc->rx_buf_arr = NULL; | ||
229 | } | ||
230 | } | ||
231 | } | ||
232 | if (adapter->cmd_buf_arr) | ||
233 | vfree(adapter->cmd_buf_arr); | ||
234 | return; | ||
235 | } | ||
236 | |||
237 | int netxen_alloc_sw_resources(struct netxen_adapter *adapter) | ||
238 | { | ||
239 | struct netxen_recv_context *recv_ctx; | ||
240 | struct netxen_rcv_desc_ctx *rcv_desc; | ||
241 | struct netxen_rx_buffer *rx_buf; | ||
242 | int ctx, ring, i, num_rx_bufs; | ||
243 | |||
244 | struct netxen_cmd_buffer *cmd_buf_arr; | ||
245 | struct net_device *netdev = adapter->netdev; | ||
246 | |||
247 | cmd_buf_arr = (struct netxen_cmd_buffer *)vmalloc(TX_RINGSIZE); | ||
248 | if (cmd_buf_arr == NULL) { | ||
249 | printk(KERN_ERR "%s: Failed to allocate cmd buffer ring\n", | ||
250 | netdev->name); | ||
251 | return -ENOMEM; | ||
252 | } | ||
253 | memset(cmd_buf_arr, 0, TX_RINGSIZE); | ||
254 | adapter->cmd_buf_arr = cmd_buf_arr; | ||
255 | |||
256 | for (ctx = 0; ctx < MAX_RCV_CTX; ctx++) { | ||
257 | recv_ctx = &adapter->recv_ctx[ctx]; | ||
258 | for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) { | ||
259 | rcv_desc = &recv_ctx->rcv_desc[ring]; | ||
260 | switch (RCV_DESC_TYPE(ring)) { | ||
261 | case RCV_DESC_NORMAL: | ||
262 | rcv_desc->max_rx_desc_count = | ||
263 | adapter->max_rx_desc_count; | ||
264 | rcv_desc->flags = RCV_DESC_NORMAL; | ||
265 | rcv_desc->dma_size = RX_DMA_MAP_LEN; | ||
266 | rcv_desc->skb_size = MAX_RX_BUFFER_LENGTH; | ||
267 | break; | ||
268 | |||
269 | case RCV_DESC_JUMBO: | ||
270 | rcv_desc->max_rx_desc_count = | ||
271 | adapter->max_jumbo_rx_desc_count; | ||
272 | rcv_desc->flags = RCV_DESC_JUMBO; | ||
273 | rcv_desc->dma_size = RX_JUMBO_DMA_MAP_LEN; | ||
274 | rcv_desc->skb_size = | ||
275 | MAX_RX_JUMBO_BUFFER_LENGTH; | ||
276 | break; | ||
277 | |||
278 | case RCV_RING_LRO: | ||
279 | rcv_desc->max_rx_desc_count = | ||
280 | adapter->max_lro_rx_desc_count; | ||
281 | rcv_desc->flags = RCV_DESC_LRO; | ||
282 | rcv_desc->dma_size = RX_LRO_DMA_MAP_LEN; | ||
283 | rcv_desc->skb_size = MAX_RX_LRO_BUFFER_LENGTH; | ||
284 | break; | ||
285 | |||
286 | } | ||
287 | rcv_desc->rx_buf_arr = (struct netxen_rx_buffer *) | ||
288 | vmalloc(RCV_BUFFSIZE); | ||
289 | if (rcv_desc->rx_buf_arr == NULL) { | ||
290 | printk(KERN_ERR "%s: Failed to allocate " | ||
291 | "rx buffer ring %d\n", | ||
292 | netdev->name, ring); | ||
293 | /* free whatever was already allocated */ | ||
294 | goto err_out; | ||
295 | } | ||
296 | memset(rcv_desc->rx_buf_arr, 0, RCV_BUFFSIZE); | ||
170 | rcv_desc->begin_alloc = 0; | 297 | rcv_desc->begin_alloc = 0; |
171 | rx_buf = rcv_desc->rx_buf_arr; | ||
172 | num_rx_bufs = rcv_desc->max_rx_desc_count; | ||
173 | /* | 298 | /* |
174 | * Now go through all of them, set reference handles | 299 | * Now go through all of them, set reference handles |
175 | * and put them in the queues. | 300 | * and put them in the queues. |
176 | */ | 301 | */ |
302 | num_rx_bufs = rcv_desc->max_rx_desc_count; | ||
303 | rx_buf = rcv_desc->rx_buf_arr; | ||
177 | for (i = 0; i < num_rx_bufs; i++) { | 304 | for (i = 0; i < num_rx_bufs; i++) { |
178 | rx_buf->ref_handle = i; | 305 | rx_buf->ref_handle = i; |
179 | rx_buf->state = NETXEN_BUFFER_FREE; | 306 | rx_buf->state = NETXEN_BUFFER_FREE; |
180 | DPRINTK(INFO, "Rx buf:ctx%d i(%d) rx_buf:" | ||
181 | "%p\n", ctxid, i, rx_buf); | ||
182 | rx_buf++; | 307 | rx_buf++; |
183 | } | 308 | } |
184 | } | 309 | } |
185 | } | 310 | } |
311 | |||
312 | return 0; | ||
313 | |||
314 | err_out: | ||
315 | netxen_free_sw_resources(adapter); | ||
316 | return -ENOMEM; | ||
186 | } | 317 | } |
187 | 318 | ||
188 | void netxen_initialize_adapter_ops(struct netxen_adapter *adapter) | 319 | void netxen_initialize_adapter_ops(struct netxen_adapter *adapter) |
@@ -730,19 +861,18 @@ int netxen_flash_unlock(struct netxen_adapter *adapter) | |||
730 | #define NETXEN_BOARDTYPE 0x4008 | 861 | #define NETXEN_BOARDTYPE 0x4008 |
731 | #define NETXEN_BOARDNUM 0x400c | 862 | #define NETXEN_BOARDNUM 0x400c |
732 | #define NETXEN_CHIPNUM 0x4010 | 863 | #define NETXEN_CHIPNUM 0x4010 |
733 | #define NETXEN_ROMBUS_RESET 0xFFFFFFFF | ||
734 | 864 | ||
735 | int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose) | 865 | int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose) |
736 | { | 866 | { |
737 | int addr, val; | 867 | int addr, val; |
738 | int n, i; | 868 | int i, init_delay = 0; |
739 | int init_delay = 0; | ||
740 | struct crb_addr_pair *buf; | 869 | struct crb_addr_pair *buf; |
870 | unsigned offset, n; | ||
741 | u32 off; | 871 | u32 off; |
742 | 872 | ||
743 | /* resetall */ | 873 | /* resetall */ |
744 | netxen_crb_writelit_adapter(adapter, NETXEN_ROMUSB_GLB_SW_RESET, | 874 | netxen_crb_writelit_adapter(adapter, NETXEN_ROMUSB_GLB_SW_RESET, |
745 | NETXEN_ROMBUS_RESET); | 875 | 0xffffffff); |
746 | 876 | ||
747 | if (verbose) { | 877 | if (verbose) { |
748 | if (netxen_rom_fast_read(adapter, NETXEN_BOARDTYPE, &val) == 0) | 878 | if (netxen_rom_fast_read(adapter, NETXEN_BOARDTYPE, &val) == 0) |
@@ -759,108 +889,141 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose) | |||
759 | printk("Could not read chip number\n"); | 889 | printk("Could not read chip number\n"); |
760 | } | 890 | } |
761 | 891 | ||
762 | if (netxen_rom_fast_read(adapter, 0, &n) == 0 && (n & 0x80000000)) { | 892 | if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) { |
763 | n &= ~0x80000000; | 893 | if (netxen_rom_fast_read(adapter, 0, &n) != 0 || |
764 | if (n < 0x400) { | 894 | (n != 0xcafecafeUL) || |
765 | if (verbose) | 895 | netxen_rom_fast_read(adapter, 4, &n) != 0) { |
766 | printk("%s: %d CRB init values found" | 896 | printk(KERN_ERR "%s: ERROR Reading crb_init area: " |
767 | " in ROM.\n", netxen_nic_driver_name, n); | 897 | "n: %08x\n", netxen_nic_driver_name, n); |
768 | } else { | ||
769 | printk("%s:n=0x%x Error! NetXen card flash not" | ||
770 | " initialized.\n", __FUNCTION__, n); | ||
771 | return -EIO; | 898 | return -EIO; |
772 | } | 899 | } |
773 | buf = kcalloc(n, sizeof(struct crb_addr_pair), GFP_KERNEL); | 900 | offset = n & 0xffffU; |
774 | if (buf == NULL) { | 901 | n = (n >> 16) & 0xffffU; |
775 | printk("%s: netxen_pinit_from_rom: Unable to calloc " | 902 | } else { |
776 | "memory.\n", netxen_nic_driver_name); | 903 | if (netxen_rom_fast_read(adapter, 0, &n) != 0 || |
777 | return -ENOMEM; | 904 | !(n & 0x80000000)) { |
778 | } | 905 | printk(KERN_ERR "%s: ERROR Reading crb_init area: " |
779 | for (i = 0; i < n; i++) { | 906 | "n: %08x\n", netxen_nic_driver_name, n); |
780 | if (netxen_rom_fast_read(adapter, 8 * i + 4, &val) != 0 | 907 | return -EIO; |
781 | || netxen_rom_fast_read(adapter, 8 * i + 8, | ||
782 | &addr) != 0) | ||
783 | return -EIO; | ||
784 | |||
785 | buf[i].addr = addr; | ||
786 | buf[i].data = val; | ||
787 | |||
788 | if (verbose) | ||
789 | printk("%s: PCI: 0x%08x == 0x%08x\n", | ||
790 | netxen_nic_driver_name, (unsigned int) | ||
791 | netxen_decode_crb_addr(addr), val); | ||
792 | } | 908 | } |
793 | for (i = 0; i < n; i++) { | 909 | offset = 1; |
910 | n &= ~0x80000000; | ||
911 | } | ||
912 | |||
913 | if (n < 1024) { | ||
914 | if (verbose) | ||
915 | printk(KERN_DEBUG "%s: %d CRB init values found" | ||
916 | " in ROM.\n", netxen_nic_driver_name, n); | ||
917 | } else { | ||
918 | printk(KERN_ERR "%s:n=0x%x Error! NetXen card flash not" | ||
919 | " initialized.\n", __func__, n); | ||
920 | return -EIO; | ||
921 | } | ||
922 | |||
923 | buf = kcalloc(n, sizeof(struct crb_addr_pair), GFP_KERNEL); | ||
924 | if (buf == NULL) { | ||
925 | printk("%s: netxen_pinit_from_rom: Unable to calloc memory.\n", | ||
926 | netxen_nic_driver_name); | ||
927 | return -ENOMEM; | ||
928 | } | ||
929 | for (i = 0; i < n; i++) { | ||
930 | if (netxen_rom_fast_read(adapter, 8*i + 4*offset, &val) != 0 || | ||
931 | netxen_rom_fast_read(adapter, 8*i + 4*offset + 4, &addr) != 0) | ||
932 | return -EIO; | ||
933 | |||
934 | buf[i].addr = addr; | ||
935 | buf[i].data = val; | ||
794 | 936 | ||
795 | off = netxen_decode_crb_addr(buf[i].addr); | 937 | if (verbose) |
796 | if (off == NETXEN_ADDR_ERROR) { | 938 | printk(KERN_DEBUG "%s: PCI: 0x%08x == 0x%08x\n", |
797 | printk(KERN_ERR"CRB init value out of range %x\n", | 939 | netxen_nic_driver_name, |
940 | (u32)netxen_decode_crb_addr(addr), val); | ||
941 | } | ||
942 | for (i = 0; i < n; i++) { | ||
943 | |||
944 | off = netxen_decode_crb_addr(buf[i].addr); | ||
945 | if (off == NETXEN_ADDR_ERROR) { | ||
946 | printk(KERN_ERR"CRB init value out of range %x\n", | ||
798 | buf[i].addr); | 947 | buf[i].addr); |
948 | continue; | ||
949 | } | ||
950 | off += NETXEN_PCI_CRBSPACE; | ||
951 | /* skipping cold reboot MAGIC */ | ||
952 | if (off == NETXEN_CAM_RAM(0x1fc)) | ||
953 | continue; | ||
954 | |||
955 | if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) { | ||
956 | /* do not reset PCI */ | ||
957 | if (off == (ROMUSB_GLB + 0xbc)) | ||
799 | continue; | 958 | continue; |
800 | } | 959 | if (off == (NETXEN_CRB_PEG_NET_1 + 0x18)) |
801 | off += NETXEN_PCI_CRBSPACE; | 960 | buf[i].data = 0x1020; |
802 | /* skipping cold reboot MAGIC */ | 961 | /* skip the function enable register */ |
803 | if (off == NETXEN_CAM_RAM(0x1fc)) | 962 | if (off == NETXEN_PCIE_REG(PCIE_SETUP_FUNCTION)) |
804 | continue; | 963 | continue; |
964 | if (off == NETXEN_PCIE_REG(PCIE_SETUP_FUNCTION2)) | ||
965 | continue; | ||
966 | if ((off & 0x0ff00000) == NETXEN_CRB_SMB) | ||
967 | continue; | ||
968 | } | ||
805 | 969 | ||
806 | /* After writing this register, HW needs time for CRB */ | 970 | if (off == NETXEN_ADDR_ERROR) { |
807 | /* to quiet down (else crb_window returns 0xffffffff) */ | 971 | printk(KERN_ERR "%s: Err: Unknown addr: 0x%08x\n", |
808 | if (off == NETXEN_ROMUSB_GLB_SW_RESET) { | 972 | netxen_nic_driver_name, buf[i].addr); |
809 | init_delay = 1; | 973 | continue; |
974 | } | ||
975 | |||
976 | /* After writing this register, HW needs time for CRB */ | ||
977 | /* to quiet down (else crb_window returns 0xffffffff) */ | ||
978 | if (off == NETXEN_ROMUSB_GLB_SW_RESET) { | ||
979 | init_delay = 1; | ||
980 | if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) { | ||
810 | /* hold xdma in reset also */ | 981 | /* hold xdma in reset also */ |
811 | buf[i].data = NETXEN_NIC_XDMA_RESET; | 982 | buf[i].data = NETXEN_NIC_XDMA_RESET; |
812 | } | 983 | } |
984 | } | ||
813 | 985 | ||
814 | adapter->hw_write_wx(adapter, off, &buf[i].data, 4); | 986 | adapter->hw_write_wx(adapter, off, &buf[i].data, 4); |
815 | 987 | ||
816 | if (init_delay == 1) { | 988 | if (init_delay == 1) { |
817 | msleep(1000); | 989 | msleep(1000); |
818 | init_delay = 0; | 990 | init_delay = 0; |
819 | } | ||
820 | msleep(1); | ||
821 | } | 991 | } |
822 | kfree(buf); | 992 | msleep(1); |
993 | } | ||
994 | kfree(buf); | ||
823 | 995 | ||
824 | /* disable_peg_cache_all */ | 996 | /* disable_peg_cache_all */ |
825 | 997 | ||
826 | /* unreset_net_cache */ | 998 | /* unreset_net_cache */ |
827 | adapter->hw_read_wx(adapter, NETXEN_ROMUSB_GLB_SW_RESET, &val, | 999 | if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) { |
828 | 4); | 1000 | adapter->hw_read_wx(adapter, |
829 | netxen_crb_writelit_adapter(adapter, NETXEN_ROMUSB_GLB_SW_RESET, | 1001 | NETXEN_ROMUSB_GLB_SW_RESET, &val, 4); |
830 | (val & 0xffffff0f)); | ||
831 | /* p2dn replyCount */ | ||
832 | netxen_crb_writelit_adapter(adapter, | 1002 | netxen_crb_writelit_adapter(adapter, |
833 | NETXEN_CRB_PEG_NET_D + 0xec, 0x1e); | 1003 | NETXEN_ROMUSB_GLB_SW_RESET, (val & 0xffffff0f)); |
834 | /* disable_peg_cache 0 */ | ||
835 | netxen_crb_writelit_adapter(adapter, | ||
836 | NETXEN_CRB_PEG_NET_D + 0x4c, 8); | ||
837 | /* disable_peg_cache 1 */ | ||
838 | netxen_crb_writelit_adapter(adapter, | ||
839 | NETXEN_CRB_PEG_NET_I + 0x4c, 8); | ||
840 | |||
841 | /* peg_clr_all */ | ||
842 | |||
843 | /* peg_clr 0 */ | ||
844 | netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_0 + 0x8, | ||
845 | 0); | ||
846 | netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_0 + 0xc, | ||
847 | 0); | ||
848 | /* peg_clr 1 */ | ||
849 | netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_1 + 0x8, | ||
850 | 0); | ||
851 | netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_1 + 0xc, | ||
852 | 0); | ||
853 | /* peg_clr 2 */ | ||
854 | netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_2 + 0x8, | ||
855 | 0); | ||
856 | netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_2 + 0xc, | ||
857 | 0); | ||
858 | /* peg_clr 3 */ | ||
859 | netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_3 + 0x8, | ||
860 | 0); | ||
861 | netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_3 + 0xc, | ||
862 | 0); | ||
863 | } | 1004 | } |
1005 | |||
1006 | /* p2dn replyCount */ | ||
1007 | netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_D + 0xec, 0x1e); | ||
1008 | /* disable_peg_cache 0 */ | ||
1009 | netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_D + 0x4c, 8); | ||
1010 | /* disable_peg_cache 1 */ | ||
1011 | netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_I + 0x4c, 8); | ||
1012 | |||
1013 | /* peg_clr_all */ | ||
1014 | |||
1015 | /* peg_clr 0 */ | ||
1016 | netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_0 + 0x8, 0); | ||
1017 | netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_0 + 0xc, 0); | ||
1018 | /* peg_clr 1 */ | ||
1019 | netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_1 + 0x8, 0); | ||
1020 | netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_1 + 0xc, 0); | ||
1021 | /* peg_clr 2 */ | ||
1022 | netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_2 + 0x8, 0); | ||
1023 | netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_2 + 0xc, 0); | ||
1024 | /* peg_clr 3 */ | ||
1025 | netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_3 + 0x8, 0); | ||
1026 | netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_3 + 0xc, 0); | ||
864 | return 0; | 1027 | return 0; |
865 | } | 1028 | } |
866 | 1029 | ||
@@ -876,7 +1039,7 @@ int netxen_initialize_adapter_offload(struct netxen_adapter *adapter) | |||
876 | &adapter->dummy_dma.phys_addr); | 1039 | &adapter->dummy_dma.phys_addr); |
877 | if (adapter->dummy_dma.addr == NULL) { | 1040 | if (adapter->dummy_dma.addr == NULL) { |
878 | printk("%s: ERROR: Could not allocate dummy DMA memory\n", | 1041 | printk("%s: ERROR: Could not allocate dummy DMA memory\n", |
879 | __FUNCTION__); | 1042 | __func__); |
880 | return -ENOMEM; | 1043 | return -ENOMEM; |
881 | } | 1044 | } |
882 | 1045 | ||
@@ -887,6 +1050,11 @@ int netxen_initialize_adapter_offload(struct netxen_adapter *adapter) | |||
887 | adapter->pci_write_normalize(adapter, CRB_HOST_DUMMY_BUF_ADDR_HI, hi); | 1050 | adapter->pci_write_normalize(adapter, CRB_HOST_DUMMY_BUF_ADDR_HI, hi); |
888 | adapter->pci_write_normalize(adapter, CRB_HOST_DUMMY_BUF_ADDR_LO, lo); | 1051 | adapter->pci_write_normalize(adapter, CRB_HOST_DUMMY_BUF_ADDR_LO, lo); |
889 | 1052 | ||
1053 | if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) { | ||
1054 | uint32_t temp = 0; | ||
1055 | adapter->hw_write_wx(adapter, CRB_HOST_DUMMY_BUF, &temp, 4); | ||
1056 | } | ||
1057 | |||
890 | return 0; | 1058 | return 0; |
891 | } | 1059 | } |
892 | 1060 | ||
@@ -920,22 +1088,24 @@ void netxen_free_adapter_offload(struct netxen_adapter *adapter) | |||
920 | int netxen_phantom_init(struct netxen_adapter *adapter, int pegtune_val) | 1088 | int netxen_phantom_init(struct netxen_adapter *adapter, int pegtune_val) |
921 | { | 1089 | { |
922 | u32 val = 0; | 1090 | u32 val = 0; |
923 | int retries = 30; | 1091 | int retries = 60; |
924 | 1092 | ||
925 | if (!pegtune_val) { | 1093 | if (!pegtune_val) { |
926 | do { | 1094 | do { |
927 | val = adapter->pci_read_normalize(adapter, | 1095 | val = adapter->pci_read_normalize(adapter, |
928 | CRB_CMDPEG_STATE); | 1096 | CRB_CMDPEG_STATE); |
929 | pegtune_val = adapter->pci_read_normalize(adapter, | ||
930 | NETXEN_ROMUSB_GLB_PEGTUNE_DONE); | ||
931 | 1097 | ||
932 | if (val == PHAN_INITIALIZE_COMPLETE || | 1098 | if (val == PHAN_INITIALIZE_COMPLETE || |
933 | val == PHAN_INITIALIZE_ACK) | 1099 | val == PHAN_INITIALIZE_ACK) |
934 | return 0; | 1100 | return 0; |
935 | 1101 | ||
936 | msleep(1000); | 1102 | msleep(500); |
1103 | |||
937 | } while (--retries); | 1104 | } while (--retries); |
1105 | |||
938 | if (!retries) { | 1106 | if (!retries) { |
1107 | pegtune_val = adapter->pci_read_normalize(adapter, | ||
1108 | NETXEN_ROMUSB_GLB_PEGTUNE_DONE); | ||
939 | printk(KERN_WARNING "netxen_phantom_init: init failed, " | 1109 | printk(KERN_WARNING "netxen_phantom_init: init failed, " |
940 | "pegtune_val=%x\n", pegtune_val); | 1110 | "pegtune_val=%x\n", pegtune_val); |
941 | return -1; | 1111 | return -1; |
@@ -945,6 +1115,30 @@ int netxen_phantom_init(struct netxen_adapter *adapter, int pegtune_val) | |||
945 | return 0; | 1115 | return 0; |
946 | } | 1116 | } |
947 | 1117 | ||
1118 | int netxen_receive_peg_ready(struct netxen_adapter *adapter) | ||
1119 | { | ||
1120 | u32 val = 0; | ||
1121 | int retries = 2000; | ||
1122 | |||
1123 | do { | ||
1124 | val = adapter->pci_read_normalize(adapter, CRB_RCVPEG_STATE); | ||
1125 | |||
1126 | if (val == PHAN_PEG_RCV_INITIALIZED) | ||
1127 | return 0; | ||
1128 | |||
1129 | msleep(10); | ||
1130 | |||
1131 | } while (--retries); | ||
1132 | |||
1133 | if (!retries) { | ||
1134 | printk(KERN_ERR "Receive Peg initialization not " | ||
1135 | "complete, state: 0x%x.\n", val); | ||
1136 | return -EIO; | ||
1137 | } | ||
1138 | |||
1139 | return 0; | ||
1140 | } | ||
1141 | |||
948 | static int netxen_nic_check_temp(struct netxen_adapter *adapter) | 1142 | static int netxen_nic_check_temp(struct netxen_adapter *adapter) |
949 | { | 1143 | { |
950 | struct net_device *netdev = adapter->netdev; | 1144 | struct net_device *netdev = adapter->netdev; |
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index 72d9f48b80dc..4d32f3cc2fbd 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c | |||
@@ -49,13 +49,22 @@ 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 | static int port_mode = NETXEN_PORT_MODE_AUTO_NEG; | ||
53 | |||
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; | ||
60 | |||
52 | #define NETXEN_NETDEV_WEIGHT 120 | 61 | #define NETXEN_NETDEV_WEIGHT 120 |
53 | #define NETXEN_ADAPTER_UP_MAGIC 777 | 62 | #define NETXEN_ADAPTER_UP_MAGIC 777 |
54 | #define NETXEN_NIC_PEG_TUNE 0 | 63 | #define NETXEN_NIC_PEG_TUNE 0 |
55 | 64 | ||
56 | /* Local functions to NetXen NIC driver */ | 65 | /* Local functions to NetXen NIC driver */ |
57 | static int __devinit netxen_nic_probe(struct pci_dev *pdev, | 66 | static int __devinit netxen_nic_probe(struct pci_dev *pdev, |
58 | const struct pci_device_id *ent); | 67 | const struct pci_device_id *ent); |
59 | static void __devexit netxen_nic_remove(struct pci_dev *pdev); | 68 | static void __devexit netxen_nic_remove(struct pci_dev *pdev); |
60 | static int netxen_nic_open(struct net_device *netdev); | 69 | static int netxen_nic_open(struct net_device *netdev); |
61 | static int netxen_nic_close(struct net_device *netdev); | 70 | static int netxen_nic_close(struct net_device *netdev); |
@@ -135,9 +144,11 @@ netxen_nic_update_cmd_consumer(struct netxen_adapter *adapter, | |||
135 | adapter->crb_addr_cmd_consumer, crb_consumer); | 144 | adapter->crb_addr_cmd_consumer, crb_consumer); |
136 | } | 145 | } |
137 | 146 | ||
138 | static uint32_t msi_tgt_status[4] = { | 147 | static uint32_t msi_tgt_status[8] = { |
139 | ISR_INT_TARGET_STATUS, ISR_INT_TARGET_STATUS_F1, | 148 | ISR_INT_TARGET_STATUS, ISR_INT_TARGET_STATUS_F1, |
140 | ISR_INT_TARGET_STATUS_F2, ISR_INT_TARGET_STATUS_F3 | 149 | ISR_INT_TARGET_STATUS_F2, ISR_INT_TARGET_STATUS_F3, |
150 | ISR_INT_TARGET_STATUS_F4, ISR_INT_TARGET_STATUS_F5, | ||
151 | ISR_INT_TARGET_STATUS_F6, ISR_INT_TARGET_STATUS_F7 | ||
141 | }; | 152 | }; |
142 | 153 | ||
143 | static uint32_t sw_int_mask[4] = { | 154 | static uint32_t sw_int_mask[4] = { |
@@ -145,6 +156,8 @@ static uint32_t sw_int_mask[4] = { | |||
145 | CRB_SW_INT_MASK_2, CRB_SW_INT_MASK_3 | 156 | CRB_SW_INT_MASK_2, CRB_SW_INT_MASK_3 |
146 | }; | 157 | }; |
147 | 158 | ||
159 | static struct netxen_legacy_intr_set legacy_intr[] = NX_LEGACY_INTR_CONFIG; | ||
160 | |||
148 | static void netxen_nic_disable_int(struct netxen_adapter *adapter) | 161 | static void netxen_nic_disable_int(struct netxen_adapter *adapter) |
149 | { | 162 | { |
150 | u32 mask = 0x7ff; | 163 | u32 mask = 0x7ff; |
@@ -159,7 +172,7 @@ static void netxen_nic_disable_int(struct netxen_adapter *adapter) | |||
159 | adapter->intr_scheme != INTR_SCHEME_PERPORT) | 172 | adapter->intr_scheme != INTR_SCHEME_PERPORT) |
160 | adapter->pci_write_immediate(adapter, ISR_INT_MASK, mask); | 173 | adapter->pci_write_immediate(adapter, ISR_INT_MASK, mask); |
161 | 174 | ||
162 | if (!(adapter->flags & NETXEN_NIC_MSI_ENABLED)) { | 175 | if (!NETXEN_IS_MSI_FAMILY(adapter)) { |
163 | do { | 176 | do { |
164 | adapter->pci_write_immediate(adapter, | 177 | adapter->pci_write_immediate(adapter, |
165 | ISR_INT_TARGET_STATUS, 0xffffffff); | 178 | ISR_INT_TARGET_STATUS, 0xffffffff); |
@@ -208,7 +221,7 @@ static void netxen_nic_enable_int(struct netxen_adapter *adapter) | |||
208 | 221 | ||
209 | adapter->pci_write_normalize(adapter, sw_int_mask[port], 0x1); | 222 | adapter->pci_write_normalize(adapter, sw_int_mask[port], 0x1); |
210 | 223 | ||
211 | if (!(adapter->flags & NETXEN_NIC_MSI_ENABLED)) { | 224 | if (!NETXEN_IS_MSI_FAMILY(adapter)) { |
212 | mask = 0xbff; | 225 | mask = 0xbff; |
213 | if (adapter->intr_scheme != -1 && | 226 | if (adapter->intr_scheme != -1 && |
214 | adapter->intr_scheme != INTR_SCHEME_PERPORT) { | 227 | adapter->intr_scheme != INTR_SCHEME_PERPORT) { |
@@ -222,6 +235,280 @@ static void netxen_nic_enable_int(struct netxen_adapter *adapter) | |||
222 | DPRINTK(1, INFO, "Done with enable Int\n"); | 235 | DPRINTK(1, INFO, "Done with enable Int\n"); |
223 | } | 236 | } |
224 | 237 | ||
238 | static int nx_set_dma_mask(struct netxen_adapter *adapter, uint8_t revision_id) | ||
239 | { | ||
240 | struct pci_dev *pdev = adapter->pdev; | ||
241 | int err; | ||
242 | uint64_t mask; | ||
243 | |||
244 | #ifdef CONFIG_IA64 | ||
245 | adapter->dma_mask = DMA_32BIT_MASK; | ||
246 | #else | ||
247 | if (revision_id >= NX_P3_B0) { | ||
248 | /* should go to DMA_64BIT_MASK */ | ||
249 | adapter->dma_mask = DMA_39BIT_MASK; | ||
250 | mask = DMA_39BIT_MASK; | ||
251 | } else if (revision_id == NX_P3_A2) { | ||
252 | adapter->dma_mask = DMA_39BIT_MASK; | ||
253 | mask = DMA_39BIT_MASK; | ||
254 | } else if (revision_id == NX_P2_C1) { | ||
255 | adapter->dma_mask = DMA_35BIT_MASK; | ||
256 | mask = DMA_35BIT_MASK; | ||
257 | } else { | ||
258 | adapter->dma_mask = DMA_32BIT_MASK; | ||
259 | mask = DMA_32BIT_MASK; | ||
260 | goto set_32_bit_mask; | ||
261 | } | ||
262 | |||
263 | /* | ||
264 | * Consistent DMA mask is set to 32 bit because it cannot be set to | ||
265 | * 35 bits. For P3 also leave it at 32 bits for now. Only the rings | ||
266 | * come off this pool. | ||
267 | */ | ||
268 | if (pci_set_dma_mask(pdev, mask) == 0 && | ||
269 | pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK) == 0) { | ||
270 | adapter->pci_using_dac = 1; | ||
271 | return 0; | ||
272 | } | ||
273 | #endif /* CONFIG_IA64 */ | ||
274 | |||
275 | set_32_bit_mask: | ||
276 | err = pci_set_dma_mask(pdev, DMA_32BIT_MASK); | ||
277 | if (!err) | ||
278 | err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK); | ||
279 | if (err) { | ||
280 | DPRINTK(ERR, "No usable DMA configuration, aborting:%d\n", err); | ||
281 | return err; | ||
282 | } | ||
283 | |||
284 | adapter->pci_using_dac = 0; | ||
285 | return 0; | ||
286 | } | ||
287 | |||
288 | static void netxen_check_options(struct netxen_adapter *adapter) | ||
289 | { | ||
290 | switch (adapter->ahw.boardcfg.board_type) { | ||
291 | case NETXEN_BRDTYPE_P3_HMEZ: | ||
292 | case NETXEN_BRDTYPE_P3_XG_LOM: | ||
293 | case NETXEN_BRDTYPE_P3_10G_CX4: | ||
294 | case NETXEN_BRDTYPE_P3_10G_CX4_LP: | ||
295 | case NETXEN_BRDTYPE_P3_IMEZ: | ||
296 | case NETXEN_BRDTYPE_P3_10G_SFP_PLUS: | ||
297 | case NETXEN_BRDTYPE_P3_10G_XFP: | ||
298 | case NETXEN_BRDTYPE_P3_10000_BASE_T: | ||
299 | adapter->msix_supported = !!use_msi_x; | ||
300 | adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS_10G; | ||
301 | break; | ||
302 | |||
303 | case NETXEN_BRDTYPE_P2_SB31_10G: | ||
304 | case NETXEN_BRDTYPE_P2_SB31_10G_CX4: | ||
305 | case NETXEN_BRDTYPE_P2_SB31_10G_IMEZ: | ||
306 | case NETXEN_BRDTYPE_P2_SB31_10G_HMEZ: | ||
307 | adapter->msix_supported = 0; | ||
308 | adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS_10G; | ||
309 | break; | ||
310 | |||
311 | case NETXEN_BRDTYPE_P3_REF_QG: | ||
312 | case NETXEN_BRDTYPE_P3_4_GB: | ||
313 | case NETXEN_BRDTYPE_P3_4_GB_MM: | ||
314 | case NETXEN_BRDTYPE_P2_SB35_4G: | ||
315 | case NETXEN_BRDTYPE_P2_SB31_2G: | ||
316 | adapter->msix_supported = 0; | ||
317 | adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS_1G; | ||
318 | break; | ||
319 | |||
320 | default: | ||
321 | adapter->msix_supported = 0; | ||
322 | adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS_1G; | ||
323 | |||
324 | printk(KERN_WARNING "Unknown board type(0x%x)\n", | ||
325 | adapter->ahw.boardcfg.board_type); | ||
326 | break; | ||
327 | } | ||
328 | |||
329 | adapter->max_tx_desc_count = MAX_CMD_DESCRIPTORS_HOST; | ||
330 | adapter->max_jumbo_rx_desc_count = MAX_JUMBO_RCV_DESCRIPTORS; | ||
331 | adapter->max_lro_rx_desc_count = MAX_LRO_RCV_DESCRIPTORS; | ||
332 | |||
333 | adapter->max_possible_rss_rings = 1; | ||
334 | return; | ||
335 | } | ||
336 | |||
337 | static int | ||
338 | netxen_check_hw_init(struct netxen_adapter *adapter, int first_boot) | ||
339 | { | ||
340 | int ret = 0; | ||
341 | |||
342 | if (first_boot == 0x55555555) { | ||
343 | /* This is the first boot after power up */ | ||
344 | |||
345 | /* PCI bus master workaround */ | ||
346 | adapter->hw_read_wx(adapter, | ||
347 | NETXEN_PCIE_REG(0x4), &first_boot, 4); | ||
348 | if (!(first_boot & 0x4)) { | ||
349 | first_boot |= 0x4; | ||
350 | adapter->hw_write_wx(adapter, | ||
351 | NETXEN_PCIE_REG(0x4), &first_boot, 4); | ||
352 | adapter->hw_read_wx(adapter, | ||
353 | NETXEN_PCIE_REG(0x4), &first_boot, 4); | ||
354 | } | ||
355 | |||
356 | /* This is the first boot after power up */ | ||
357 | adapter->hw_read_wx(adapter, | ||
358 | NETXEN_ROMUSB_GLB_SW_RESET, &first_boot, 4); | ||
359 | if (first_boot != 0x80000f) { | ||
360 | /* clear the register for future unloads/loads */ | ||
361 | adapter->pci_write_normalize(adapter, | ||
362 | NETXEN_CAM_RAM(0x1fc), 0); | ||
363 | ret = -1; | ||
364 | } | ||
365 | |||
366 | if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) { | ||
367 | /* Start P2 boot loader */ | ||
368 | adapter->pci_write_normalize(adapter, | ||
369 | NETXEN_CAM_RAM(0x1fc), NETXEN_BDINFO_MAGIC); | ||
370 | adapter->pci_write_normalize(adapter, | ||
371 | NETXEN_ROMUSB_GLB_PEGTUNE_DONE, 1); | ||
372 | } | ||
373 | } | ||
374 | return ret; | ||
375 | } | ||
376 | |||
377 | static void netxen_set_port_mode(struct netxen_adapter *adapter) | ||
378 | { | ||
379 | u32 val, data; | ||
380 | |||
381 | val = adapter->ahw.boardcfg.board_type; | ||
382 | if ((val == NETXEN_BRDTYPE_P3_HMEZ) || | ||
383 | (val == NETXEN_BRDTYPE_P3_XG_LOM)) { | ||
384 | if (port_mode == NETXEN_PORT_MODE_802_3_AP) { | ||
385 | data = NETXEN_PORT_MODE_802_3_AP; | ||
386 | adapter->hw_write_wx(adapter, | ||
387 | NETXEN_PORT_MODE_ADDR, &data, 4); | ||
388 | } else if (port_mode == NETXEN_PORT_MODE_XG) { | ||
389 | data = NETXEN_PORT_MODE_XG; | ||
390 | adapter->hw_write_wx(adapter, | ||
391 | NETXEN_PORT_MODE_ADDR, &data, 4); | ||
392 | } else if (port_mode == NETXEN_PORT_MODE_AUTO_NEG_1G) { | ||
393 | data = NETXEN_PORT_MODE_AUTO_NEG_1G; | ||
394 | adapter->hw_write_wx(adapter, | ||
395 | NETXEN_PORT_MODE_ADDR, &data, 4); | ||
396 | } else if (port_mode == NETXEN_PORT_MODE_AUTO_NEG_XG) { | ||
397 | data = NETXEN_PORT_MODE_AUTO_NEG_XG; | ||
398 | adapter->hw_write_wx(adapter, | ||
399 | NETXEN_PORT_MODE_ADDR, &data, 4); | ||
400 | } else { | ||
401 | data = NETXEN_PORT_MODE_AUTO_NEG; | ||
402 | adapter->hw_write_wx(adapter, | ||
403 | NETXEN_PORT_MODE_ADDR, &data, 4); | ||
404 | } | ||
405 | |||
406 | if ((wol_port_mode != NETXEN_PORT_MODE_802_3_AP) && | ||
407 | (wol_port_mode != NETXEN_PORT_MODE_XG) && | ||
408 | (wol_port_mode != NETXEN_PORT_MODE_AUTO_NEG_1G) && | ||
409 | (wol_port_mode != NETXEN_PORT_MODE_AUTO_NEG_XG)) { | ||
410 | wol_port_mode = NETXEN_PORT_MODE_AUTO_NEG; | ||
411 | } | ||
412 | adapter->hw_write_wx(adapter, NETXEN_WOL_PORT_MODE, | ||
413 | &wol_port_mode, 4); | ||
414 | } | ||
415 | } | ||
416 | |||
417 | #define PCI_CAP_ID_GEN 0x10 | ||
418 | |||
419 | static void netxen_pcie_strap_init(struct netxen_adapter *adapter) | ||
420 | { | ||
421 | u32 pdevfuncsave; | ||
422 | u32 c8c9value = 0; | ||
423 | u32 chicken = 0; | ||
424 | u32 control = 0; | ||
425 | int i, pos; | ||
426 | struct pci_dev *pdev; | ||
427 | |||
428 | pdev = pci_get_device(0x1166, 0x0140, NULL); | ||
429 | if (pdev) { | ||
430 | pci_dev_put(pdev); | ||
431 | adapter->hw_read_wx(adapter, | ||
432 | NETXEN_PCIE_REG(PCIE_TGT_SPLIT_CHICKEN), &chicken, 4); | ||
433 | chicken |= 0x4000; | ||
434 | adapter->hw_write_wx(adapter, | ||
435 | NETXEN_PCIE_REG(PCIE_TGT_SPLIT_CHICKEN), &chicken, 4); | ||
436 | } | ||
437 | |||
438 | pdev = adapter->pdev; | ||
439 | |||
440 | adapter->hw_read_wx(adapter, | ||
441 | NETXEN_PCIE_REG(PCIE_CHICKEN3), &chicken, 4); | ||
442 | /* clear chicken3.25:24 */ | ||
443 | chicken &= 0xFCFFFFFF; | ||
444 | /* | ||
445 | * if gen1 and B0, set F1020 - if gen 2, do nothing | ||
446 | * if gen2 set to F1000 | ||
447 | */ | ||
448 | pos = pci_find_capability(pdev, PCI_CAP_ID_GEN); | ||
449 | if (pos == 0xC0) { | ||
450 | pci_read_config_dword(pdev, pos + 0x10, &control); | ||
451 | if ((control & 0x000F0000) != 0x00020000) { | ||
452 | /* set chicken3.24 if gen1 */ | ||
453 | chicken |= 0x01000000; | ||
454 | } | ||
455 | printk(KERN_INFO "%s Gen2 strapping detected\n", | ||
456 | netxen_nic_driver_name); | ||
457 | c8c9value = 0xF1000; | ||
458 | } else { | ||
459 | /* set chicken3.24 if gen1 */ | ||
460 | chicken |= 0x01000000; | ||
461 | printk(KERN_INFO "%s Gen1 strapping detected\n", | ||
462 | netxen_nic_driver_name); | ||
463 | if (adapter->ahw.revision_id == NX_P3_B0) | ||
464 | c8c9value = 0xF1020; | ||
465 | else | ||
466 | c8c9value = 0; | ||
467 | |||
468 | } | ||
469 | adapter->hw_write_wx(adapter, | ||
470 | NETXEN_PCIE_REG(PCIE_CHICKEN3), &chicken, 4); | ||
471 | |||
472 | if (!c8c9value) | ||
473 | return; | ||
474 | |||
475 | pdevfuncsave = pdev->devfn; | ||
476 | if (pdevfuncsave & 0x07) | ||
477 | return; | ||
478 | |||
479 | for (i = 0; i < 8; i++) { | ||
480 | pci_read_config_dword(pdev, pos + 8, &control); | ||
481 | pci_read_config_dword(pdev, pos + 8, &control); | ||
482 | pci_write_config_dword(pdev, pos + 8, c8c9value); | ||
483 | pdev->devfn++; | ||
484 | } | ||
485 | pdev->devfn = pdevfuncsave; | ||
486 | } | ||
487 | |||
488 | static void netxen_set_msix_bit(struct pci_dev *pdev, int enable) | ||
489 | { | ||
490 | u32 control; | ||
491 | int pos; | ||
492 | |||
493 | pos = pci_find_capability(pdev, PCI_CAP_ID_MSIX); | ||
494 | if (pos) { | ||
495 | pci_read_config_dword(pdev, pos, &control); | ||
496 | if (enable) | ||
497 | control |= PCI_MSIX_FLAGS_ENABLE; | ||
498 | else | ||
499 | control = 0; | ||
500 | pci_write_config_dword(pdev, pos, control); | ||
501 | } | ||
502 | } | ||
503 | |||
504 | static void netxen_init_msix_entries(struct netxen_adapter *adapter) | ||
505 | { | ||
506 | int i; | ||
507 | |||
508 | for (i = 0; i < MSIX_ENTRIES_PER_ADAPTER; i++) | ||
509 | adapter->msix_entries[i].entry = i; | ||
510 | } | ||
511 | |||
225 | /* | 512 | /* |
226 | * netxen_nic_probe() | 513 | * netxen_nic_probe() |
227 | * | 514 | * |
@@ -247,28 +534,28 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
247 | 534 | ||
248 | 535 | ||
249 | u8 __iomem *db_ptr = NULL; | 536 | u8 __iomem *db_ptr = NULL; |
250 | unsigned long mem_base, mem_len, db_base, db_len, pci_len0; | 537 | unsigned long mem_base, mem_len, db_base, db_len, pci_len0 = 0; |
251 | int pci_using_dac, i = 0, err; | 538 | int i = 0, err; |
252 | int ring; | 539 | int first_driver, first_boot; |
253 | struct netxen_recv_context *recv_ctx = NULL; | ||
254 | struct netxen_rcv_desc_ctx *rcv_desc = NULL; | ||
255 | struct netxen_cmd_buffer *cmd_buf_arr = NULL; | ||
256 | __le64 mac_addr[FLASH_NUM_PORTS + 1]; | 540 | __le64 mac_addr[FLASH_NUM_PORTS + 1]; |
257 | int valid_mac = 0; | ||
258 | u32 val; | 541 | u32 val; |
259 | int pci_func_id = PCI_FUNC(pdev->devfn); | 542 | int pci_func_id = PCI_FUNC(pdev->devfn); |
260 | DECLARE_MAC_BUF(mac); | 543 | DECLARE_MAC_BUF(mac); |
544 | struct netxen_legacy_intr_set *legacy_intrp; | ||
545 | uint8_t revision_id; | ||
261 | 546 | ||
262 | if (pci_func_id == 0) | 547 | if (pci_func_id == 0) |
263 | printk(KERN_INFO "%s \n", netxen_nic_driver_string); | 548 | printk(KERN_INFO "%s\n", netxen_nic_driver_string); |
264 | 549 | ||
265 | if (pdev->class != 0x020000) { | 550 | if (pdev->class != 0x020000) { |
266 | printk(KERN_DEBUG "NetXen function %d, class %x will not " | 551 | printk(KERN_DEBUG "NetXen function %d, class %x will not " |
267 | "be enabled.\n",pci_func_id, pdev->class); | 552 | "be enabled.\n",pci_func_id, pdev->class); |
268 | return -ENODEV; | 553 | return -ENODEV; |
269 | } | 554 | } |
555 | |||
270 | if ((err = pci_enable_device(pdev))) | 556 | if ((err = pci_enable_device(pdev))) |
271 | return err; | 557 | return err; |
558 | |||
272 | if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) { | 559 | if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) { |
273 | err = -ENODEV; | 560 | err = -ENODEV; |
274 | goto err_out_disable_pdev; | 561 | goto err_out_disable_pdev; |
@@ -278,18 +565,6 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
278 | goto err_out_disable_pdev; | 565 | goto err_out_disable_pdev; |
279 | 566 | ||
280 | pci_set_master(pdev); | 567 | pci_set_master(pdev); |
281 | if (pdev->revision == NX_P2_C1 && | ||
282 | (pci_set_dma_mask(pdev, DMA_35BIT_MASK) == 0) && | ||
283 | (pci_set_consistent_dma_mask(pdev, DMA_35BIT_MASK) == 0)) { | ||
284 | pci_using_dac = 1; | ||
285 | } else { | ||
286 | if ((err = pci_set_dma_mask(pdev, DMA_32BIT_MASK)) || | ||
287 | (err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK))) | ||
288 | goto err_out_free_res; | ||
289 | |||
290 | pci_using_dac = 0; | ||
291 | } | ||
292 | |||
293 | 568 | ||
294 | netdev = alloc_etherdev(sizeof(struct netxen_adapter)); | 569 | netdev = alloc_etherdev(sizeof(struct netxen_adapter)); |
295 | if(!netdev) { | 570 | if(!netdev) { |
@@ -302,8 +577,17 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
302 | SET_NETDEV_DEV(netdev, &pdev->dev); | 577 | SET_NETDEV_DEV(netdev, &pdev->dev); |
303 | 578 | ||
304 | adapter = netdev->priv; | 579 | adapter = netdev->priv; |
305 | 580 | adapter->netdev = netdev; | |
581 | adapter->pdev = pdev; | ||
306 | adapter->ahw.pci_func = pci_func_id; | 582 | adapter->ahw.pci_func = pci_func_id; |
583 | |||
584 | revision_id = pdev->revision; | ||
585 | adapter->ahw.revision_id = revision_id; | ||
586 | |||
587 | err = nx_set_dma_mask(adapter, revision_id); | ||
588 | if (err) | ||
589 | goto err_out_free_netdev; | ||
590 | |||
307 | rwlock_init(&adapter->adapter_lock); | 591 | rwlock_init(&adapter->adapter_lock); |
308 | adapter->ahw.qdr_sn_window = -1; | 592 | adapter->ahw.qdr_sn_window = -1; |
309 | adapter->ahw.ddr_mn_window = -1; | 593 | adapter->ahw.ddr_mn_window = -1; |
@@ -379,7 +663,7 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
379 | 663 | ||
380 | if (db_len == 0) { | 664 | if (db_len == 0) { |
381 | printk(KERN_ERR "%s: doorbell is disabled\n", | 665 | printk(KERN_ERR "%s: doorbell is disabled\n", |
382 | netxen_nic_driver_name); | 666 | netxen_nic_driver_name); |
383 | err = -EIO; | 667 | err = -EIO; |
384 | goto err_out_iounmap; | 668 | goto err_out_iounmap; |
385 | } | 669 | } |
@@ -389,7 +673,7 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
389 | db_ptr = ioremap(db_base, NETXEN_DB_MAPSIZE_BYTES); | 673 | db_ptr = ioremap(db_base, NETXEN_DB_MAPSIZE_BYTES); |
390 | if (!db_ptr) { | 674 | if (!db_ptr) { |
391 | printk(KERN_ERR "%s: Failed to allocate doorbell map.", | 675 | printk(KERN_ERR "%s: Failed to allocate doorbell map.", |
392 | netxen_nic_driver_name); | 676 | netxen_nic_driver_name); |
393 | err = -EIO; | 677 | err = -EIO; |
394 | goto err_out_iounmap; | 678 | goto err_out_iounmap; |
395 | } | 679 | } |
@@ -404,11 +688,18 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
404 | adapter->ahw.db_base = db_ptr; | 688 | adapter->ahw.db_base = db_ptr; |
405 | adapter->ahw.db_len = db_len; | 689 | adapter->ahw.db_len = db_len; |
406 | 690 | ||
407 | adapter->netdev = netdev; | ||
408 | adapter->pdev = pdev; | ||
409 | |||
410 | netif_napi_add(netdev, &adapter->napi, | 691 | netif_napi_add(netdev, &adapter->napi, |
411 | netxen_nic_poll, NETXEN_NETDEV_WEIGHT); | 692 | netxen_nic_poll, NETXEN_NETDEV_WEIGHT); |
693 | |||
694 | if (revision_id >= NX_P3_B0) | ||
695 | legacy_intrp = &legacy_intr[pci_func_id]; | ||
696 | else | ||
697 | legacy_intrp = &legacy_intr[0]; | ||
698 | |||
699 | adapter->legacy_intr.int_vec_bit = legacy_intrp->int_vec_bit; | ||
700 | adapter->legacy_intr.tgt_status_reg = legacy_intrp->tgt_status_reg; | ||
701 | adapter->legacy_intr.tgt_mask_reg = legacy_intrp->tgt_mask_reg; | ||
702 | adapter->legacy_intr.pci_int_reg = legacy_intrp->pci_int_reg; | ||
412 | 703 | ||
413 | /* this will be read from FW later */ | 704 | /* this will be read from FW later */ |
414 | adapter->intr_scheme = -1; | 705 | adapter->intr_scheme = -1; |
@@ -418,8 +709,11 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
418 | adapter->portnum = pci_func_id; | 709 | adapter->portnum = pci_func_id; |
419 | adapter->status &= ~NETXEN_NETDEV_STATUS; | 710 | adapter->status &= ~NETXEN_NETDEV_STATUS; |
420 | adapter->rx_csum = 1; | 711 | adapter->rx_csum = 1; |
421 | adapter->max_mc_count = 16; | ||
422 | adapter->mc_enabled = 0; | 712 | adapter->mc_enabled = 0; |
713 | if (NX_IS_REVISION_P3(revision_id)) | ||
714 | adapter->max_mc_count = 38; | ||
715 | else | ||
716 | adapter->max_mc_count = 16; | ||
423 | 717 | ||
424 | netdev->open = netxen_nic_open; | 718 | netdev->open = netxen_nic_open; |
425 | netdev->stop = netxen_nic_close; | 719 | netdev->stop = netxen_nic_close; |
@@ -441,18 +735,12 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
441 | netdev->features = NETIF_F_SG; | 735 | netdev->features = NETIF_F_SG; |
442 | netdev->features |= NETIF_F_IP_CSUM; | 736 | netdev->features |= NETIF_F_IP_CSUM; |
443 | netdev->features |= NETIF_F_TSO; | 737 | netdev->features |= NETIF_F_TSO; |
738 | if (NX_IS_REVISION_P3(revision_id)) | ||
739 | netdev->features |= NETIF_F_TSO6; | ||
444 | 740 | ||
445 | if (pci_using_dac) | 741 | if (adapter->pci_using_dac) |
446 | netdev->features |= NETIF_F_HIGHDMA; | 742 | netdev->features |= NETIF_F_HIGHDMA; |
447 | 743 | ||
448 | if (pci_enable_msi(pdev)) | ||
449 | adapter->flags &= ~NETXEN_NIC_MSI_ENABLED; | ||
450 | else | ||
451 | adapter->flags |= NETXEN_NIC_MSI_ENABLED; | ||
452 | |||
453 | netdev->irq = pdev->irq; | ||
454 | INIT_WORK(&adapter->tx_timeout_task, netxen_tx_timeout_task); | ||
455 | |||
456 | /* | 744 | /* |
457 | * Set the CRB window to invalid. If any register in window 0 is | 745 | * Set the CRB window to invalid. If any register in window 0 is |
458 | * accessed it should set the window to 0 and then reset it to 1. | 746 | * accessed it should set the window to 0 and then reset it to 1. |
@@ -461,87 +749,13 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
461 | 749 | ||
462 | if (netxen_nic_get_board_info(adapter) != 0) { | 750 | if (netxen_nic_get_board_info(adapter) != 0) { |
463 | printk("%s: Error getting board config info.\n", | 751 | printk("%s: Error getting board config info.\n", |
464 | netxen_nic_driver_name); | 752 | netxen_nic_driver_name); |
465 | err = -EIO; | 753 | err = -EIO; |
466 | goto err_out_iounmap; | 754 | goto err_out_iounmap; |
467 | } | 755 | } |
468 | 756 | ||
469 | /* | ||
470 | * Adapter in our case is quad port so initialize it before | ||
471 | * initializing the ports | ||
472 | */ | ||
473 | |||
474 | netxen_initialize_adapter_ops(adapter); | 757 | netxen_initialize_adapter_ops(adapter); |
475 | 758 | ||
476 | adapter->max_tx_desc_count = MAX_CMD_DESCRIPTORS_HOST; | ||
477 | if ((adapter->ahw.boardcfg.board_type == NETXEN_BRDTYPE_P2_SB35_4G) || | ||
478 | (adapter->ahw.boardcfg.board_type == | ||
479 | NETXEN_BRDTYPE_P2_SB31_2G)) | ||
480 | adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS_1G; | ||
481 | else | ||
482 | adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS; | ||
483 | adapter->max_jumbo_rx_desc_count = MAX_JUMBO_RCV_DESCRIPTORS; | ||
484 | adapter->max_lro_rx_desc_count = MAX_LRO_RCV_DESCRIPTORS; | ||
485 | |||
486 | cmd_buf_arr = (struct netxen_cmd_buffer *)vmalloc(TX_RINGSIZE); | ||
487 | if (cmd_buf_arr == NULL) { | ||
488 | printk(KERN_ERR | ||
489 | "%s: Could not allocate cmd_buf_arr memory:%d\n", | ||
490 | netxen_nic_driver_name, (int)TX_RINGSIZE); | ||
491 | err = -ENOMEM; | ||
492 | goto err_out_free_adapter; | ||
493 | } | ||
494 | memset(cmd_buf_arr, 0, TX_RINGSIZE); | ||
495 | adapter->cmd_buf_arr = cmd_buf_arr; | ||
496 | |||
497 | for (i = 0; i < MAX_RCV_CTX; ++i) { | ||
498 | recv_ctx = &adapter->recv_ctx[i]; | ||
499 | for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) { | ||
500 | rcv_desc = &recv_ctx->rcv_desc[ring]; | ||
501 | switch (RCV_DESC_TYPE(ring)) { | ||
502 | case RCV_DESC_NORMAL: | ||
503 | rcv_desc->max_rx_desc_count = | ||
504 | adapter->max_rx_desc_count; | ||
505 | rcv_desc->flags = RCV_DESC_NORMAL; | ||
506 | rcv_desc->dma_size = RX_DMA_MAP_LEN; | ||
507 | rcv_desc->skb_size = MAX_RX_BUFFER_LENGTH; | ||
508 | break; | ||
509 | |||
510 | case RCV_DESC_JUMBO: | ||
511 | rcv_desc->max_rx_desc_count = | ||
512 | adapter->max_jumbo_rx_desc_count; | ||
513 | rcv_desc->flags = RCV_DESC_JUMBO; | ||
514 | rcv_desc->dma_size = RX_JUMBO_DMA_MAP_LEN; | ||
515 | rcv_desc->skb_size = MAX_RX_JUMBO_BUFFER_LENGTH; | ||
516 | break; | ||
517 | |||
518 | case RCV_RING_LRO: | ||
519 | rcv_desc->max_rx_desc_count = | ||
520 | adapter->max_lro_rx_desc_count; | ||
521 | rcv_desc->flags = RCV_DESC_LRO; | ||
522 | rcv_desc->dma_size = RX_LRO_DMA_MAP_LEN; | ||
523 | rcv_desc->skb_size = MAX_RX_LRO_BUFFER_LENGTH; | ||
524 | break; | ||
525 | |||
526 | } | ||
527 | rcv_desc->rx_buf_arr = (struct netxen_rx_buffer *) | ||
528 | vmalloc(RCV_BUFFSIZE); | ||
529 | |||
530 | if (rcv_desc->rx_buf_arr == NULL) { | ||
531 | printk(KERN_ERR "%s: Could not allocate " | ||
532 | "rcv_desc->rx_buf_arr memory:%d\n", | ||
533 | netxen_nic_driver_name, | ||
534 | (int)RCV_BUFFSIZE); | ||
535 | err = -ENOMEM; | ||
536 | goto err_out_free_rx_buffer; | ||
537 | } | ||
538 | memset(rcv_desc->rx_buf_arr, 0, RCV_BUFFSIZE); | ||
539 | } | ||
540 | |||
541 | } | ||
542 | |||
543 | netxen_initialize_adapter_sw(adapter); /* initialize the buffers in adapter */ | ||
544 | |||
545 | /* Mezz cards have PCI function 0,2,3 enabled */ | 759 | /* Mezz cards have PCI function 0,2,3 enabled */ |
546 | switch (adapter->ahw.boardcfg.board_type) { | 760 | switch (adapter->ahw.boardcfg.board_type) { |
547 | case NETXEN_BRDTYPE_P2_SB31_10G_IMEZ: | 761 | case NETXEN_BRDTYPE_P2_SB31_10G_IMEZ: |
@@ -553,81 +767,51 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
553 | break; | 767 | break; |
554 | } | 768 | } |
555 | 769 | ||
556 | init_timer(&adapter->watchdog_timer); | 770 | /* |
557 | adapter->ahw.xg_linkup = 0; | 771 | * This call will setup various max rx/tx counts. |
558 | adapter->watchdog_timer.function = &netxen_watchdog; | 772 | * It must be done before any buffer/ring allocations. |
559 | adapter->watchdog_timer.data = (unsigned long)adapter; | 773 | */ |
560 | INIT_WORK(&adapter->watchdog_task, netxen_watchdog_task); | 774 | netxen_check_options(adapter); |
561 | adapter->ahw.revision_id = pdev->revision; | ||
562 | 775 | ||
776 | first_driver = 0; | ||
777 | if (NX_IS_REVISION_P3(revision_id)) { | ||
778 | if (adapter->ahw.pci_func == 0) | ||
779 | first_driver = 1; | ||
780 | } else { | ||
781 | if (adapter->portnum == 0) | ||
782 | first_driver = 1; | ||
783 | } | ||
563 | adapter->crb_addr_cmd_producer = crb_cmd_producer[adapter->portnum]; | 784 | adapter->crb_addr_cmd_producer = crb_cmd_producer[adapter->portnum]; |
564 | adapter->crb_addr_cmd_consumer = crb_cmd_consumer[adapter->portnum]; | 785 | adapter->crb_addr_cmd_consumer = crb_cmd_consumer[adapter->portnum]; |
565 | netxen_nic_update_cmd_producer(adapter, 0); | 786 | netxen_nic_update_cmd_producer(adapter, 0); |
566 | netxen_nic_update_cmd_consumer(adapter, 0); | 787 | netxen_nic_update_cmd_consumer(adapter, 0); |
567 | 788 | ||
568 | if (netxen_is_flash_supported(adapter) == 0 && | 789 | if (first_driver) { |
569 | netxen_get_flash_mac_addr(adapter, mac_addr) == 0) | 790 | first_boot = adapter->pci_read_normalize(adapter, |
570 | valid_mac = 1; | 791 | NETXEN_CAM_RAM(0x1fc)); |
571 | else | ||
572 | valid_mac = 0; | ||
573 | |||
574 | if (valid_mac) { | ||
575 | unsigned char *p = (unsigned char *)&mac_addr[adapter->portnum]; | ||
576 | netdev->dev_addr[0] = *(p + 5); | ||
577 | netdev->dev_addr[1] = *(p + 4); | ||
578 | netdev->dev_addr[2] = *(p + 3); | ||
579 | netdev->dev_addr[3] = *(p + 2); | ||
580 | netdev->dev_addr[4] = *(p + 1); | ||
581 | netdev->dev_addr[5] = *(p + 0); | ||
582 | 792 | ||
583 | memcpy(netdev->perm_addr, netdev->dev_addr, | 793 | err = netxen_check_hw_init(adapter, first_boot); |
584 | netdev->addr_len); | 794 | if (err) { |
585 | if (!is_valid_ether_addr(netdev->perm_addr)) { | 795 | printk(KERN_ERR "%s: error in init HW init sequence\n", |
586 | printk(KERN_ERR "%s: Bad MAC address %s.\n", | 796 | netxen_nic_driver_name); |
587 | netxen_nic_driver_name, | 797 | goto err_out_iounmap; |
588 | print_mac(mac, netdev->dev_addr)); | ||
589 | } else { | ||
590 | if (adapter->macaddr_set) | ||
591 | adapter->macaddr_set(adapter, | ||
592 | netdev->dev_addr); | ||
593 | } | 798 | } |
594 | } | ||
595 | 799 | ||
596 | if (adapter->portnum == 0) { | 800 | if (NX_IS_REVISION_P3(revision_id)) |
597 | err = netxen_initialize_adapter_offload(adapter); | 801 | netxen_set_port_mode(adapter); |
598 | if (err) | 802 | |
599 | goto err_out_free_rx_buffer; | 803 | if (first_boot != 0x55555555) { |
600 | val = adapter->pci_read_normalize(adapter, | ||
601 | NETXEN_CAM_RAM(0x1fc)); | ||
602 | if (val == 0x55555555) { | ||
603 | /* This is the first boot after power up */ | ||
604 | netxen_nic_read_w0(adapter, NETXEN_PCIE_REG(0x4), &val); | ||
605 | if (!(val & 0x4)) { | ||
606 | val |= 0x4; | ||
607 | netxen_nic_write_w0(adapter, NETXEN_PCIE_REG(0x4), val); | ||
608 | netxen_nic_read_w0(adapter, NETXEN_PCIE_REG(0x4), &val); | ||
609 | if (!(val & 0x4)) | ||
610 | printk(KERN_ERR "%s: failed to set MSI bit in PCI-e reg\n", | ||
611 | netxen_nic_driver_name); | ||
612 | } | ||
613 | val = adapter->pci_read_normalize(adapter, | ||
614 | NETXEN_ROMUSB_GLB_SW_RESET); | ||
615 | printk(KERN_INFO"NetXen: read 0x%08x for reset reg.\n",val); | ||
616 | if (val != 0x80000f) { | ||
617 | /* clear the register for future unloads/loads */ | ||
618 | adapter->pci_write_normalize(adapter, | ||
619 | NETXEN_CAM_RAM(0x1fc), 0); | ||
620 | printk(KERN_ERR "ERROR in NetXen HW init sequence.\n"); | ||
621 | err = -ENODEV; | ||
622 | goto err_out_free_dev; | ||
623 | } | ||
624 | } else { | ||
625 | adapter->pci_write_normalize(adapter, | 804 | adapter->pci_write_normalize(adapter, |
626 | CRB_CMDPEG_STATE, 0); | 805 | CRB_CMDPEG_STATE, 0); |
627 | netxen_pinit_from_rom(adapter, 0); | 806 | netxen_pinit_from_rom(adapter, 0); |
628 | msleep(1); | 807 | msleep(1); |
629 | netxen_load_firmware(adapter); | 808 | netxen_load_firmware(adapter); |
630 | netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE); | 809 | } |
810 | |||
811 | if (NX_IS_REVISION_P3(revision_id)) | ||
812 | netxen_pcie_strap_init(adapter); | ||
813 | |||
814 | if (NX_IS_REVISION_P2(revision_id)) { | ||
631 | 815 | ||
632 | /* Initialize multicast addr pool owners */ | 816 | /* Initialize multicast addr pool owners */ |
633 | val = 0x7654; | 817 | val = 0x7654; |
@@ -638,10 +822,16 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
638 | 822 | ||
639 | } | 823 | } |
640 | 824 | ||
641 | /* clear the register for future unloads/loads */ | 825 | if ((first_boot == 0x55555555) && |
642 | adapter->pci_write_normalize(adapter, NETXEN_CAM_RAM(0x1fc), 0); | 826 | (NX_IS_REVISION_P2(revision_id))) { |
643 | dev_info(&pdev->dev, "cmdpeg state: 0x%0x\n", | 827 | /* Unlock the HW, prompting the boot sequence */ |
644 | adapter->pci_read_normalize(adapter, CRB_CMDPEG_STATE)); | 828 | adapter->pci_write_normalize(adapter, |
829 | NETXEN_ROMUSB_GLB_PEGTUNE_DONE, 1); | ||
830 | } | ||
831 | |||
832 | err = netxen_initialize_adapter_offload(adapter); | ||
833 | if (err) | ||
834 | goto err_out_iounmap; | ||
645 | 835 | ||
646 | /* | 836 | /* |
647 | * Tell the hardware our version number. | 837 | * Tell the hardware our version number. |
@@ -651,12 +841,19 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
651 | | (_NETXEN_NIC_LINUX_SUBVERSION); | 841 | | (_NETXEN_NIC_LINUX_SUBVERSION); |
652 | adapter->pci_write_normalize(adapter, CRB_DRIVER_VERSION, i); | 842 | adapter->pci_write_normalize(adapter, CRB_DRIVER_VERSION, i); |
653 | 843 | ||
654 | /* Unlock the HW, prompting the boot sequence */ | ||
655 | adapter->pci_write_normalize(adapter, | ||
656 | NETXEN_ROMUSB_GLB_PEGTUNE_DONE, 1); | ||
657 | /* Handshake with the card before we register the devices. */ | 844 | /* Handshake with the card before we register the devices. */ |
658 | netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE); | 845 | netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE); |
659 | } | 846 | |
847 | if (NX_IS_REVISION_P3(revision_id)) { | ||
848 | adapter->hw_read_wx(adapter, | ||
849 | NETXEN_MIU_MN_CONTROL, &val, 4); | ||
850 | adapter->ahw.cut_through = (val & 0x4) ? 1 : 0; | ||
851 | dev_info(&pdev->dev, "firmware running in %s mode\n", | ||
852 | adapter->ahw.cut_through ? "cut through" : "legacy"); | ||
853 | } | ||
854 | } /* first_driver */ | ||
855 | |||
856 | netxen_nic_flash_print(adapter); | ||
660 | 857 | ||
661 | /* | 858 | /* |
662 | * See if the firmware gave us a virtual-physical port mapping. | 859 | * See if the firmware gave us a virtual-physical port mapping. |
@@ -666,6 +863,76 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
666 | if (i != 0x55555555) | 863 | if (i != 0x55555555) |
667 | adapter->physical_port = i; | 864 | adapter->physical_port = i; |
668 | 865 | ||
866 | adapter->flags &= ~(NETXEN_NIC_MSI_ENABLED | NETXEN_NIC_MSIX_ENABLED); | ||
867 | |||
868 | netxen_set_msix_bit(pdev, 0); | ||
869 | |||
870 | if (NX_IS_REVISION_P3(revision_id)) { | ||
871 | if ((mem_len != NETXEN_PCI_128MB_SIZE) && | ||
872 | mem_len != NETXEN_PCI_2MB_SIZE) | ||
873 | adapter->msix_supported = 0; | ||
874 | } | ||
875 | |||
876 | if (adapter->msix_supported) { | ||
877 | |||
878 | netxen_init_msix_entries(adapter); | ||
879 | |||
880 | if (pci_enable_msix(pdev, adapter->msix_entries, | ||
881 | MSIX_ENTRIES_PER_ADAPTER)) | ||
882 | goto request_msi; | ||
883 | |||
884 | adapter->flags |= NETXEN_NIC_MSIX_ENABLED; | ||
885 | netxen_set_msix_bit(pdev, 1); | ||
886 | dev_info(&pdev->dev, "using msi-x interrupts\n"); | ||
887 | |||
888 | } else { | ||
889 | request_msi: | ||
890 | if (use_msi && !pci_enable_msi(pdev)) { | ||
891 | adapter->flags |= NETXEN_NIC_MSI_ENABLED; | ||
892 | dev_info(&pdev->dev, "using msi interrupts\n"); | ||
893 | } else | ||
894 | dev_info(&pdev->dev, "using legacy interrupts\n"); | ||
895 | } | ||
896 | |||
897 | if (adapter->flags & NETXEN_NIC_MSIX_ENABLED) | ||
898 | netdev->irq = adapter->msix_entries[0].vector; | ||
899 | else | ||
900 | netdev->irq = pdev->irq; | ||
901 | |||
902 | err = netxen_receive_peg_ready(adapter); | ||
903 | if (err) | ||
904 | goto err_out_disable_msi; | ||
905 | |||
906 | init_timer(&adapter->watchdog_timer); | ||
907 | adapter->ahw.xg_linkup = 0; | ||
908 | adapter->watchdog_timer.function = &netxen_watchdog; | ||
909 | adapter->watchdog_timer.data = (unsigned long)adapter; | ||
910 | INIT_WORK(&adapter->watchdog_task, netxen_watchdog_task); | ||
911 | INIT_WORK(&adapter->tx_timeout_task, netxen_tx_timeout_task); | ||
912 | |||
913 | if (netxen_is_flash_supported(adapter) == 0 && | ||
914 | netxen_get_flash_mac_addr(adapter, mac_addr) == 0) { | ||
915 | unsigned char *p; | ||
916 | |||
917 | p = (unsigned char *)&mac_addr[adapter->portnum]; | ||
918 | netdev->dev_addr[0] = *(p + 5); | ||
919 | netdev->dev_addr[1] = *(p + 4); | ||
920 | netdev->dev_addr[2] = *(p + 3); | ||
921 | netdev->dev_addr[3] = *(p + 2); | ||
922 | netdev->dev_addr[4] = *(p + 1); | ||
923 | netdev->dev_addr[5] = *(p + 0); | ||
924 | |||
925 | memcpy(netdev->perm_addr, netdev->dev_addr, | ||
926 | netdev->addr_len); | ||
927 | if (!is_valid_ether_addr(netdev->perm_addr)) { | ||
928 | printk(KERN_ERR "%s: Bad MAC address %s.\n", | ||
929 | netxen_nic_driver_name, | ||
930 | print_mac(mac, netdev->dev_addr)); | ||
931 | } else { | ||
932 | adapter->macaddr_set(adapter, netdev->dev_addr); | ||
933 | } | ||
934 | } | ||
935 | |||
669 | netif_carrier_off(netdev); | 936 | netif_carrier_off(netdev); |
670 | netif_stop_queue(netdev); | 937 | netif_stop_queue(netdev); |
671 | 938 | ||
@@ -674,41 +941,37 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
674 | " aborting\n", netxen_nic_driver_name, | 941 | " aborting\n", netxen_nic_driver_name, |
675 | adapter->portnum); | 942 | adapter->portnum); |
676 | err = -EIO; | 943 | err = -EIO; |
677 | goto err_out_free_dev; | 944 | goto err_out_disable_msi; |
678 | } | 945 | } |
679 | 946 | ||
680 | netxen_nic_flash_print(adapter); | ||
681 | pci_set_drvdata(pdev, adapter); | 947 | pci_set_drvdata(pdev, adapter); |
682 | 948 | ||
683 | return 0; | 949 | switch (adapter->ahw.board_type) { |
684 | 950 | case NETXEN_NIC_GBE: | |
685 | err_out_free_dev: | 951 | dev_info(&adapter->pdev->dev, "%s: GbE port initialized\n", |
686 | if (adapter->portnum == 0) | 952 | adapter->netdev->name); |
687 | netxen_free_adapter_offload(adapter); | 953 | break; |
688 | 954 | case NETXEN_NIC_XGBE: | |
689 | err_out_free_rx_buffer: | 955 | dev_info(&adapter->pdev->dev, "%s: XGbE port initialized\n", |
690 | for (i = 0; i < MAX_RCV_CTX; ++i) { | 956 | adapter->netdev->name); |
691 | recv_ctx = &adapter->recv_ctx[i]; | 957 | break; |
692 | for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) { | ||
693 | rcv_desc = &recv_ctx->rcv_desc[ring]; | ||
694 | if (rcv_desc->rx_buf_arr != NULL) { | ||
695 | vfree(rcv_desc->rx_buf_arr); | ||
696 | rcv_desc->rx_buf_arr = NULL; | ||
697 | } | ||
698 | } | ||
699 | } | 958 | } |
700 | vfree(cmd_buf_arr); | ||
701 | 959 | ||
702 | err_out_free_adapter: | 960 | return 0; |
961 | |||
962 | err_out_disable_msi: | ||
963 | if (adapter->flags & NETXEN_NIC_MSIX_ENABLED) | ||
964 | pci_disable_msix(pdev); | ||
703 | if (adapter->flags & NETXEN_NIC_MSI_ENABLED) | 965 | if (adapter->flags & NETXEN_NIC_MSI_ENABLED) |
704 | pci_disable_msi(pdev); | 966 | pci_disable_msi(pdev); |
705 | 967 | ||
706 | pci_set_drvdata(pdev, NULL); | 968 | if (first_driver) |
969 | netxen_free_adapter_offload(adapter); | ||
707 | 970 | ||
971 | err_out_iounmap: | ||
708 | if (db_ptr) | 972 | if (db_ptr) |
709 | iounmap(db_ptr); | 973 | iounmap(db_ptr); |
710 | 974 | ||
711 | err_out_iounmap: | ||
712 | if (mem_ptr0) | 975 | if (mem_ptr0) |
713 | iounmap(mem_ptr0); | 976 | iounmap(mem_ptr0); |
714 | if (mem_ptr1) | 977 | if (mem_ptr1) |
@@ -723,6 +986,7 @@ err_out_free_res: | |||
723 | pci_release_regions(pdev); | 986 | pci_release_regions(pdev); |
724 | 987 | ||
725 | err_out_disable_pdev: | 988 | err_out_disable_pdev: |
989 | pci_set_drvdata(pdev, NULL); | ||
726 | pci_disable_device(pdev); | 990 | pci_disable_device(pdev); |
727 | return err; | 991 | return err; |
728 | } | 992 | } |
@@ -731,11 +995,6 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev) | |||
731 | { | 995 | { |
732 | struct netxen_adapter *adapter; | 996 | struct netxen_adapter *adapter; |
733 | struct net_device *netdev; | 997 | struct net_device *netdev; |
734 | struct netxen_rx_buffer *buffer; | ||
735 | struct netxen_recv_context *recv_ctx; | ||
736 | struct netxen_rcv_desc_ctx *rcv_desc; | ||
737 | int i, ctxid, ring; | ||
738 | static int init_firmware_done = 0; | ||
739 | 998 | ||
740 | adapter = pci_get_drvdata(pdev); | 999 | adapter = pci_get_drvdata(pdev); |
741 | if (adapter == NULL) | 1000 | if (adapter == NULL) |
@@ -746,36 +1005,18 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev) | |||
746 | unregister_netdev(netdev); | 1005 | unregister_netdev(netdev); |
747 | 1006 | ||
748 | if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC) { | 1007 | if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC) { |
749 | init_firmware_done++; | ||
750 | netxen_free_hw_resources(adapter); | 1008 | netxen_free_hw_resources(adapter); |
1009 | netxen_free_sw_resources(adapter); | ||
751 | } | 1010 | } |
752 | 1011 | ||
753 | for (ctxid = 0; ctxid < MAX_RCV_CTX; ++ctxid) { | ||
754 | recv_ctx = &adapter->recv_ctx[ctxid]; | ||
755 | for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) { | ||
756 | rcv_desc = &recv_ctx->rcv_desc[ring]; | ||
757 | for (i = 0; i < rcv_desc->max_rx_desc_count; ++i) { | ||
758 | buffer = &(rcv_desc->rx_buf_arr[i]); | ||
759 | if (buffer->state == NETXEN_BUFFER_FREE) | ||
760 | continue; | ||
761 | pci_unmap_single(pdev, buffer->dma, | ||
762 | rcv_desc->dma_size, | ||
763 | PCI_DMA_FROMDEVICE); | ||
764 | if (buffer->skb != NULL) | ||
765 | dev_kfree_skb_any(buffer->skb); | ||
766 | } | ||
767 | vfree(rcv_desc->rx_buf_arr); | ||
768 | } | ||
769 | } | ||
770 | |||
771 | vfree(adapter->cmd_buf_arr); | ||
772 | |||
773 | if (adapter->portnum == 0) | 1012 | if (adapter->portnum == 0) |
774 | netxen_free_adapter_offload(adapter); | 1013 | netxen_free_adapter_offload(adapter); |
775 | 1014 | ||
776 | if (adapter->irq) | 1015 | if (adapter->irq) |
777 | free_irq(adapter->irq, adapter); | 1016 | free_irq(adapter->irq, adapter); |
778 | 1017 | ||
1018 | if (adapter->flags & NETXEN_NIC_MSIX_ENABLED) | ||
1019 | pci_disable_msix(pdev); | ||
779 | if (adapter->flags & NETXEN_NIC_MSI_ENABLED) | 1020 | if (adapter->flags & NETXEN_NIC_MSI_ENABLED) |
780 | pci_disable_msi(pdev); | 1021 | pci_disable_msi(pdev); |
781 | 1022 | ||
@@ -813,52 +1054,67 @@ static int netxen_nic_open(struct net_device *netdev) | |||
813 | return -EIO; | 1054 | return -EIO; |
814 | } | 1055 | } |
815 | 1056 | ||
816 | /* setup all the resources for the Phantom... */ | 1057 | err = netxen_alloc_sw_resources(adapter); |
817 | /* this include the descriptors for rcv, tx, and status */ | ||
818 | netxen_nic_clear_stats(adapter); | ||
819 | err = netxen_nic_hw_resources(adapter); | ||
820 | if (err) { | 1058 | if (err) { |
821 | printk(KERN_ERR "Error in setting hw resources:%d\n", | 1059 | printk(KERN_ERR "%s: Error in setting sw resources\n", |
822 | err); | 1060 | netdev->name); |
823 | return err; | 1061 | return err; |
824 | } | 1062 | } |
1063 | |||
1064 | netxen_nic_clear_stats(adapter); | ||
1065 | |||
1066 | err = netxen_alloc_hw_resources(adapter); | ||
1067 | if (err) { | ||
1068 | printk(KERN_ERR "%s: Error in setting hw resources\n", | ||
1069 | netdev->name); | ||
1070 | goto err_out_free_sw; | ||
1071 | } | ||
1072 | |||
1073 | if (adapter->fw_major < 4) { | ||
1074 | adapter->crb_addr_cmd_producer = | ||
1075 | crb_cmd_producer[adapter->portnum]; | ||
1076 | adapter->crb_addr_cmd_consumer = | ||
1077 | crb_cmd_consumer[adapter->portnum]; | ||
1078 | } | ||
1079 | |||
1080 | netxen_nic_update_cmd_producer(adapter, 0); | ||
1081 | netxen_nic_update_cmd_consumer(adapter, 0); | ||
1082 | |||
825 | for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) { | 1083 | for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) { |
826 | for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) | 1084 | for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) |
827 | netxen_post_rx_buffers(adapter, ctx, ring); | 1085 | netxen_post_rx_buffers(adapter, ctx, ring); |
828 | } | 1086 | } |
829 | adapter->irq = adapter->pdev->irq; | 1087 | if (NETXEN_IS_MSI_FAMILY(adapter)) |
830 | if (adapter->flags & NETXEN_NIC_MSI_ENABLED) | ||
831 | handler = netxen_msi_intr; | 1088 | handler = netxen_msi_intr; |
832 | else { | 1089 | else { |
833 | flags |= IRQF_SHARED; | 1090 | flags |= IRQF_SHARED; |
834 | handler = netxen_intr; | 1091 | handler = netxen_intr; |
835 | } | 1092 | } |
1093 | adapter->irq = netdev->irq; | ||
836 | err = request_irq(adapter->irq, handler, | 1094 | err = request_irq(adapter->irq, handler, |
837 | flags, netdev->name, adapter); | 1095 | flags, netdev->name, adapter); |
838 | if (err) { | 1096 | if (err) { |
839 | printk(KERN_ERR "request_irq failed with: %d\n", err); | 1097 | printk(KERN_ERR "request_irq failed with: %d\n", err); |
840 | netxen_free_hw_resources(adapter); | 1098 | goto err_out_free_hw; |
841 | return err; | ||
842 | } | 1099 | } |
843 | 1100 | ||
844 | adapter->is_up = NETXEN_ADAPTER_UP_MAGIC; | 1101 | adapter->is_up = NETXEN_ADAPTER_UP_MAGIC; |
845 | } | 1102 | } |
1103 | |||
846 | /* Done here again so that even if phantom sw overwrote it, | 1104 | /* Done here again so that even if phantom sw overwrote it, |
847 | * we set it */ | 1105 | * we set it */ |
848 | if (adapter->init_port | 1106 | err = adapter->init_port(adapter, adapter->portnum); |
849 | && adapter->init_port(adapter, adapter->portnum) != 0) { | 1107 | if (err) { |
850 | printk(KERN_ERR "%s: Failed to initialize port %d\n", | 1108 | printk(KERN_ERR "%s: Failed to initialize port %d\n", |
851 | netxen_nic_driver_name, adapter->portnum); | 1109 | netxen_nic_driver_name, adapter->portnum); |
852 | return -EIO; | 1110 | goto err_out_free_irq; |
853 | } | 1111 | } |
854 | if (adapter->macaddr_set) | 1112 | adapter->macaddr_set(adapter, netdev->dev_addr); |
855 | adapter->macaddr_set(adapter, netdev->dev_addr); | ||
856 | 1113 | ||
857 | netxen_nic_set_link_parameters(adapter); | 1114 | netxen_nic_set_link_parameters(adapter); |
858 | 1115 | ||
859 | netxen_nic_set_multi(netdev); | 1116 | netxen_nic_set_multi(netdev); |
860 | if (adapter->set_mtu) | 1117 | adapter->set_mtu(adapter, netdev->mtu); |
861 | adapter->set_mtu(adapter, netdev->mtu); | ||
862 | 1118 | ||
863 | mod_timer(&adapter->watchdog_timer, jiffies); | 1119 | mod_timer(&adapter->watchdog_timer, jiffies); |
864 | 1120 | ||
@@ -868,6 +1124,14 @@ static int netxen_nic_open(struct net_device *netdev) | |||
868 | netif_start_queue(netdev); | 1124 | netif_start_queue(netdev); |
869 | 1125 | ||
870 | return 0; | 1126 | return 0; |
1127 | |||
1128 | err_out_free_irq: | ||
1129 | free_irq(adapter->irq, adapter); | ||
1130 | err_out_free_hw: | ||
1131 | netxen_free_hw_resources(adapter); | ||
1132 | err_out_free_sw: | ||
1133 | netxen_free_sw_resources(adapter); | ||
1134 | return err; | ||
871 | } | 1135 | } |
872 | 1136 | ||
873 | /* | 1137 | /* |
@@ -876,9 +1140,6 @@ static int netxen_nic_open(struct net_device *netdev) | |||
876 | static int netxen_nic_close(struct net_device *netdev) | 1140 | static int netxen_nic_close(struct net_device *netdev) |
877 | { | 1141 | { |
878 | struct netxen_adapter *adapter = netdev_priv(netdev); | 1142 | struct netxen_adapter *adapter = netdev_priv(netdev); |
879 | int i, j; | ||
880 | struct netxen_cmd_buffer *cmd_buff; | ||
881 | struct netxen_skb_frag *buffrag; | ||
882 | 1143 | ||
883 | netif_carrier_off(netdev); | 1144 | netif_carrier_off(netdev); |
884 | netif_stop_queue(netdev); | 1145 | netif_stop_queue(netdev); |
@@ -889,30 +1150,8 @@ static int netxen_nic_close(struct net_device *netdev) | |||
889 | 1150 | ||
890 | netxen_nic_disable_int(adapter); | 1151 | netxen_nic_disable_int(adapter); |
891 | 1152 | ||
892 | cmd_buff = adapter->cmd_buf_arr; | 1153 | netxen_release_tx_buffers(adapter); |
893 | for (i = 0; i < adapter->max_tx_desc_count; i++) { | 1154 | |
894 | buffrag = cmd_buff->frag_array; | ||
895 | if (buffrag->dma) { | ||
896 | pci_unmap_single(adapter->pdev, buffrag->dma, | ||
897 | buffrag->length, PCI_DMA_TODEVICE); | ||
898 | buffrag->dma = 0ULL; | ||
899 | } | ||
900 | for (j = 0; j < cmd_buff->frag_count; j++) { | ||
901 | buffrag++; | ||
902 | if (buffrag->dma) { | ||
903 | pci_unmap_page(adapter->pdev, buffrag->dma, | ||
904 | buffrag->length, | ||
905 | PCI_DMA_TODEVICE); | ||
906 | buffrag->dma = 0ULL; | ||
907 | } | ||
908 | } | ||
909 | /* Free the skb we received in netxen_nic_xmit_frame */ | ||
910 | if (cmd_buff->skb) { | ||
911 | dev_kfree_skb_any(cmd_buff->skb); | ||
912 | cmd_buff->skb = NULL; | ||
913 | } | ||
914 | cmd_buff++; | ||
915 | } | ||
916 | if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC) { | 1155 | if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC) { |
917 | FLUSH_SCHEDULED_WORK(); | 1156 | FLUSH_SCHEDULED_WORK(); |
918 | del_timer_sync(&adapter->watchdog_timer); | 1157 | del_timer_sync(&adapter->watchdog_timer); |