diff options
Diffstat (limited to 'drivers/net/netxen/netxen_nic_hw.c')
-rw-r--r-- | drivers/net/netxen/netxen_nic_hw.c | 1010 |
1 files changed, 1010 insertions, 0 deletions
diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c new file mode 100644 index 000000000000..105c24f0ad4c --- /dev/null +++ b/drivers/net/netxen/netxen_nic_hw.c | |||
@@ -0,0 +1,1010 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2003 - 2006 NetXen, Inc. | ||
3 | * All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU General Public License | ||
7 | * as published by the Free Software Foundation; either version 2 | ||
8 | * of the License, or (at your option) any later version. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, but | ||
11 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program; if not, write to the Free Software | ||
17 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, | ||
18 | * MA 02111-1307, USA. | ||
19 | * | ||
20 | * The full GNU General Public License is included in this distribution | ||
21 | * in the file called LICENSE. | ||
22 | * | ||
23 | * Contact Information: | ||
24 | * info@netxen.com | ||
25 | * NetXen, | ||
26 | * 3965 Freedom Circle, Fourth floor, | ||
27 | * Santa Clara, CA 95054 | ||
28 | * | ||
29 | * | ||
30 | * Source file for NIC routines to access the Phantom hardware | ||
31 | * | ||
32 | */ | ||
33 | |||
34 | #include "netxen_nic.h" | ||
35 | #include "netxen_nic_hw.h" | ||
36 | #include "netxen_nic_phan_reg.h" | ||
37 | |||
38 | /* PCI Windowing for DDR regions. */ | ||
39 | |||
40 | #define ADDR_IN_RANGE(addr, low, high) \ | ||
41 | (((addr) <= (high)) && ((addr) >= (low))) | ||
42 | |||
43 | #define NETXEN_FLASH_BASE (BOOTLD_START) | ||
44 | #define NETXEN_PHANTOM_MEM_BASE (NETXEN_FLASH_BASE) | ||
45 | #define NETXEN_MAX_MTU 8000 | ||
46 | #define NETXEN_MIN_MTU 64 | ||
47 | #define NETXEN_ETH_FCS_SIZE 4 | ||
48 | #define NETXEN_ENET_HEADER_SIZE 14 | ||
49 | #define NETXEN_WINDOW_ONE 0x2000000 /*CRB Window: bit 25 of CRB address */ | ||
50 | #define NETXEN_FIRMWARE_LEN ((16 * 1024) / 4) | ||
51 | #define NETXEN_NIU_HDRSIZE (0x1 << 6) | ||
52 | #define NETXEN_NIU_TLRSIZE (0x1 << 5) | ||
53 | |||
54 | #define lower32(x) ((u32)((x) & 0xffffffff)) | ||
55 | #define upper32(x) \ | ||
56 | ((u32)(((unsigned long long)(x) >> 32) & 0xffffffff)) | ||
57 | |||
58 | #define NETXEN_NIC_ZERO_PAUSE_ADDR 0ULL | ||
59 | #define NETXEN_NIC_UNIT_PAUSE_ADDR 0x200ULL | ||
60 | #define NETXEN_NIC_EPG_PAUSE_ADDR1 0x2200010000c28001ULL | ||
61 | #define NETXEN_NIC_EPG_PAUSE_ADDR2 0x0100088866554433ULL | ||
62 | |||
63 | #define NETXEN_NIC_WINDOW_MARGIN 0x100000 | ||
64 | |||
65 | unsigned long netxen_nic_pci_set_window(struct netxen_adapter *adapter, | ||
66 | unsigned long long addr); | ||
67 | void netxen_free_hw_resources(struct netxen_adapter *adapter); | ||
68 | |||
69 | int netxen_nic_set_mac(struct net_device *netdev, void *p) | ||
70 | { | ||
71 | struct netxen_port *port = netdev_priv(netdev); | ||
72 | struct netxen_adapter *adapter = port->adapter; | ||
73 | struct sockaddr *addr = p; | ||
74 | |||
75 | if (netif_running(netdev)) | ||
76 | return -EBUSY; | ||
77 | |||
78 | if (!is_valid_ether_addr(addr->sa_data)) | ||
79 | return -EADDRNOTAVAIL; | ||
80 | |||
81 | DPRINTK(INFO, "valid ether addr\n"); | ||
82 | memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len); | ||
83 | |||
84 | if (adapter->ops->macaddr_set) | ||
85 | adapter->ops->macaddr_set(port, addr->sa_data); | ||
86 | |||
87 | return 0; | ||
88 | } | ||
89 | |||
90 | /* | ||
91 | * netxen_nic_set_multi - Multicast | ||
92 | */ | ||
93 | void netxen_nic_set_multi(struct net_device *netdev) | ||
94 | { | ||
95 | struct netxen_port *port = netdev_priv(netdev); | ||
96 | struct netxen_adapter *adapter = port->adapter; | ||
97 | struct dev_mc_list *mc_ptr; | ||
98 | __le32 netxen_mac_addr_cntl_data = 0; | ||
99 | |||
100 | mc_ptr = netdev->mc_list; | ||
101 | if (netdev->flags & IFF_PROMISC) { | ||
102 | if (adapter->ops->set_promisc) | ||
103 | adapter->ops->set_promisc(adapter, | ||
104 | port->portnum, | ||
105 | NETXEN_NIU_PROMISC_MODE); | ||
106 | } else { | ||
107 | if (adapter->ops->unset_promisc && | ||
108 | adapter->ahw.boardcfg.board_type | ||
109 | != NETXEN_BRDTYPE_P2_SB31_10G_IMEZ) | ||
110 | adapter->ops->unset_promisc(adapter, | ||
111 | port->portnum, | ||
112 | NETXEN_NIU_NON_PROMISC_MODE); | ||
113 | } | ||
114 | if (adapter->ahw.board_type == NETXEN_NIC_XGBE) { | ||
115 | netxen_nic_mcr_set_mode_select(netxen_mac_addr_cntl_data, 0x03); | ||
116 | netxen_nic_mcr_set_id_pool0(netxen_mac_addr_cntl_data, 0x00); | ||
117 | netxen_nic_mcr_set_id_pool1(netxen_mac_addr_cntl_data, 0x00); | ||
118 | netxen_nic_mcr_set_id_pool2(netxen_mac_addr_cntl_data, 0x00); | ||
119 | netxen_nic_mcr_set_id_pool3(netxen_mac_addr_cntl_data, 0x00); | ||
120 | netxen_nic_mcr_set_enable_xtnd0(netxen_mac_addr_cntl_data); | ||
121 | netxen_nic_mcr_set_enable_xtnd1(netxen_mac_addr_cntl_data); | ||
122 | netxen_nic_mcr_set_enable_xtnd2(netxen_mac_addr_cntl_data); | ||
123 | netxen_nic_mcr_set_enable_xtnd3(netxen_mac_addr_cntl_data); | ||
124 | } else { | ||
125 | netxen_nic_mcr_set_mode_select(netxen_mac_addr_cntl_data, 0x00); | ||
126 | netxen_nic_mcr_set_id_pool0(netxen_mac_addr_cntl_data, 0x00); | ||
127 | netxen_nic_mcr_set_id_pool1(netxen_mac_addr_cntl_data, 0x01); | ||
128 | netxen_nic_mcr_set_id_pool2(netxen_mac_addr_cntl_data, 0x02); | ||
129 | netxen_nic_mcr_set_id_pool3(netxen_mac_addr_cntl_data, 0x03); | ||
130 | } | ||
131 | writel(netxen_mac_addr_cntl_data, | ||
132 | NETXEN_CRB_NORMALIZE(adapter, NETXEN_MAC_ADDR_CNTL_REG)); | ||
133 | if (adapter->ahw.board_type == NETXEN_NIC_XGBE) { | ||
134 | writel(netxen_mac_addr_cntl_data, | ||
135 | NETXEN_CRB_NORMALIZE(adapter, | ||
136 | NETXEN_MULTICAST_ADDR_HI_0)); | ||
137 | } else { | ||
138 | writel(netxen_mac_addr_cntl_data, | ||
139 | NETXEN_CRB_NORMALIZE(adapter, | ||
140 | NETXEN_MULTICAST_ADDR_HI_1)); | ||
141 | } | ||
142 | netxen_mac_addr_cntl_data = 0; | ||
143 | writel(netxen_mac_addr_cntl_data, | ||
144 | NETXEN_CRB_NORMALIZE(adapter, NETXEN_NIU_GB_DROP_WRONGADDR)); | ||
145 | } | ||
146 | |||
147 | /* | ||
148 | * netxen_nic_change_mtu - Change the Maximum Transfer Unit | ||
149 | * @returns 0 on success, negative on failure | ||
150 | */ | ||
151 | int netxen_nic_change_mtu(struct net_device *netdev, int mtu) | ||
152 | { | ||
153 | struct netxen_port *port = netdev_priv(netdev); | ||
154 | struct netxen_adapter *adapter = port->adapter; | ||
155 | int eff_mtu = mtu + NETXEN_ENET_HEADER_SIZE + NETXEN_ETH_FCS_SIZE; | ||
156 | |||
157 | if ((eff_mtu > NETXEN_MAX_MTU) || (eff_mtu < NETXEN_MIN_MTU)) { | ||
158 | printk(KERN_ERR "%s: %s %d is not supported.\n", | ||
159 | netxen_nic_driver_name, netdev->name, mtu); | ||
160 | return -EINVAL; | ||
161 | } | ||
162 | |||
163 | if (adapter->ops->set_mtu) | ||
164 | adapter->ops->set_mtu(port, mtu); | ||
165 | netdev->mtu = mtu; | ||
166 | |||
167 | return 0; | ||
168 | } | ||
169 | |||
170 | /* | ||
171 | * check if the firmware has been downloaded and ready to run and | ||
172 | * setup the address for the descriptors in the adapter | ||
173 | */ | ||
174 | int netxen_nic_hw_resources(struct netxen_adapter *adapter) | ||
175 | { | ||
176 | struct netxen_hardware_context *hw = &adapter->ahw; | ||
177 | u32 state = 0; | ||
178 | void *addr; | ||
179 | void *pause_addr; | ||
180 | int loops = 0, err = 0; | ||
181 | int ctx, ring; | ||
182 | u32 card_cmdring = 0; | ||
183 | struct netxen_rcv_desc_crb *rcv_desc_crb = NULL; | ||
184 | struct netxen_recv_context *recv_ctx; | ||
185 | struct netxen_rcv_desc_ctx *rcv_desc; | ||
186 | |||
187 | DPRINTK(INFO, "crb_base: %lx %lx", NETXEN_PCI_CRBSPACE, | ||
188 | PCI_OFFSET_SECOND_RANGE(adapter, NETXEN_PCI_CRBSPACE)); | ||
189 | DPRINTK(INFO, "cam base: %lx %lx", NETXEN_CRB_CAM, | ||
190 | pci_base_offset(adapter, NETXEN_CRB_CAM)); | ||
191 | DPRINTK(INFO, "cam RAM: %lx %lx", NETXEN_CAM_RAM_BASE, | ||
192 | pci_base_offset(adapter, NETXEN_CAM_RAM_BASE)); | ||
193 | DPRINTK(INFO, "NIC base:%lx %lx\n", NIC_CRB_BASE_PORT1, | ||
194 | pci_base_offset(adapter, NIC_CRB_BASE_PORT1)); | ||
195 | |||
196 | /* Window 1 call */ | ||
197 | card_cmdring = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_CMDRING)); | ||
198 | |||
199 | DPRINTK(INFO, "Command Peg sends 0x%x for cmdring base\n", | ||
200 | card_cmdring); | ||
201 | |||
202 | for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) { | ||
203 | DPRINTK(INFO, "Command Peg ready..waiting for rcv peg\n"); | ||
204 | loops = 0; | ||
205 | state = 0; | ||
206 | /* Window 1 call */ | ||
207 | state = readl(NETXEN_CRB_NORMALIZE(adapter, | ||
208 | recv_crb_registers[ctx]. | ||
209 | crb_rcvpeg_state)); | ||
210 | while (state != PHAN_PEG_RCV_INITIALIZED && loops < 20) { | ||
211 | udelay(100); | ||
212 | /* Window 1 call */ | ||
213 | state = readl(NETXEN_CRB_NORMALIZE(adapter, | ||
214 | recv_crb_registers | ||
215 | [ctx]. | ||
216 | crb_rcvpeg_state)); | ||
217 | loops++; | ||
218 | } | ||
219 | if (loops >= 20) { | ||
220 | printk(KERN_ERR "Rcv Peg initialization not complete:" | ||
221 | "%x.\n", state); | ||
222 | err = -EIO; | ||
223 | return err; | ||
224 | } | ||
225 | } | ||
226 | DPRINTK(INFO, "Recieve Peg ready too. starting stuff\n"); | ||
227 | |||
228 | addr = netxen_alloc(adapter->ahw.pdev, | ||
229 | sizeof(struct cmd_desc_type0) * | ||
230 | adapter->max_tx_desc_count, | ||
231 | &hw->cmd_desc_phys_addr, &hw->cmd_desc_pdev); | ||
232 | |||
233 | if (addr == NULL) { | ||
234 | DPRINTK(ERR, "bad return from pci_alloc_consistent\n"); | ||
235 | return -ENOMEM; | ||
236 | } | ||
237 | |||
238 | pause_addr = netxen_alloc(adapter->ahw.pdev, 512, | ||
239 | (dma_addr_t *) & hw->pause_physaddr, | ||
240 | &hw->pause_pdev); | ||
241 | if (pause_addr == NULL) { | ||
242 | DPRINTK(1, ERR, "bad return from pci_alloc_consistent\n"); | ||
243 | return -ENOMEM; | ||
244 | } | ||
245 | |||
246 | hw->pauseaddr = (char *)pause_addr; | ||
247 | { | ||
248 | u64 *ptr = (u64 *) pause_addr; | ||
249 | *ptr++ = NETXEN_NIC_ZERO_PAUSE_ADDR; | ||
250 | *ptr++ = NETXEN_NIC_ZERO_PAUSE_ADDR; | ||
251 | *ptr++ = NETXEN_NIC_UNIT_PAUSE_ADDR; | ||
252 | *ptr++ = NETXEN_NIC_ZERO_PAUSE_ADDR; | ||
253 | *ptr++ = NETXEN_NIC_EPG_PAUSE_ADDR1; | ||
254 | *ptr++ = NETXEN_NIC_EPG_PAUSE_ADDR2; | ||
255 | } | ||
256 | |||
257 | hw->cmd_desc_head = (struct cmd_desc_type0 *)addr; | ||
258 | |||
259 | for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) { | ||
260 | recv_ctx = &adapter->recv_ctx[ctx]; | ||
261 | |||
262 | for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) { | ||
263 | rcv_desc = &recv_ctx->rcv_desc[ring]; | ||
264 | addr = netxen_alloc(adapter->ahw.pdev, | ||
265 | RCV_DESC_RINGSIZE, | ||
266 | &rcv_desc->phys_addr, | ||
267 | &rcv_desc->phys_pdev); | ||
268 | if (addr == NULL) { | ||
269 | DPRINTK(ERR, "bad return from " | ||
270 | "pci_alloc_consistent\n"); | ||
271 | netxen_free_hw_resources(adapter); | ||
272 | err = -ENOMEM; | ||
273 | return err; | ||
274 | } | ||
275 | rcv_desc->desc_head = (struct rcv_desc *)addr; | ||
276 | } | ||
277 | |||
278 | addr = netxen_alloc(adapter->ahw.pdev, STATUS_DESC_RINGSIZE, | ||
279 | &recv_ctx->rcv_status_desc_phys_addr, | ||
280 | &recv_ctx->rcv_status_desc_pdev); | ||
281 | if (addr == NULL) { | ||
282 | DPRINTK(ERR, "bad return from" | ||
283 | " pci_alloc_consistent\n"); | ||
284 | netxen_free_hw_resources(adapter); | ||
285 | err = -ENOMEM; | ||
286 | return err; | ||
287 | } | ||
288 | recv_ctx->rcv_status_desc_head = (struct status_desc *)addr; | ||
289 | for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) { | ||
290 | rcv_desc = &recv_ctx->rcv_desc[ring]; | ||
291 | rcv_desc_crb = | ||
292 | &recv_crb_registers[ctx].rcv_desc_crb[ring]; | ||
293 | DPRINTK(INFO, "ring #%d crb global ring reg 0x%x\n", | ||
294 | ring, rcv_desc_crb->crb_globalrcv_ring); | ||
295 | /* Window = 1 */ | ||
296 | writel(lower32(rcv_desc->phys_addr), | ||
297 | NETXEN_CRB_NORMALIZE(adapter, | ||
298 | rcv_desc_crb-> | ||
299 | crb_globalrcv_ring)); | ||
300 | DPRINTK(INFO, "GLOBAL_RCV_RING ctx %d, addr 0x%x" | ||
301 | " val 0x%llx," | ||
302 | " virt %p\n", ctx, | ||
303 | rcv_desc_crb->crb_globalrcv_ring, | ||
304 | (unsigned long long)rcv_desc->phys_addr, | ||
305 | +rcv_desc->desc_head); | ||
306 | } | ||
307 | |||
308 | /* Window = 1 */ | ||
309 | writel(lower32(recv_ctx->rcv_status_desc_phys_addr), | ||
310 | NETXEN_CRB_NORMALIZE(adapter, | ||
311 | recv_crb_registers[ctx]. | ||
312 | crb_rcvstatus_ring)); | ||
313 | DPRINTK(INFO, "RCVSTATUS_RING, ctx %d, addr 0x%x," | ||
314 | " val 0x%x,virt%p\n", | ||
315 | ctx, | ||
316 | recv_crb_registers[ctx].crb_rcvstatus_ring, | ||
317 | (unsigned long long)recv_ctx->rcv_status_desc_phys_addr, | ||
318 | recv_ctx->rcv_status_desc_head); | ||
319 | } | ||
320 | /* Window = 1 */ | ||
321 | writel(lower32(hw->pause_physaddr), | ||
322 | NETXEN_CRB_NORMALIZE(adapter, CRB_PAUSE_ADDR_LO)); | ||
323 | writel(upper32(hw->pause_physaddr), | ||
324 | NETXEN_CRB_NORMALIZE(adapter, CRB_PAUSE_ADDR_HI)); | ||
325 | |||
326 | writel(lower32(hw->cmd_desc_phys_addr), | ||
327 | NETXEN_CRB_NORMALIZE(adapter, CRB_HOST_CMD_ADDR_LO)); | ||
328 | writel(upper32(hw->cmd_desc_phys_addr), | ||
329 | NETXEN_CRB_NORMALIZE(adapter, CRB_HOST_CMD_ADDR_HI)); | ||
330 | return err; | ||
331 | } | ||
332 | |||
333 | void netxen_free_hw_resources(struct netxen_adapter *adapter) | ||
334 | { | ||
335 | struct netxen_recv_context *recv_ctx; | ||
336 | struct netxen_rcv_desc_ctx *rcv_desc; | ||
337 | int ctx, ring; | ||
338 | |||
339 | if (adapter->ahw.cmd_desc_head != NULL) { | ||
340 | pci_free_consistent(adapter->ahw.cmd_desc_pdev, | ||
341 | sizeof(struct cmd_desc_type0) * | ||
342 | adapter->max_tx_desc_count, | ||
343 | adapter->ahw.cmd_desc_head, | ||
344 | adapter->ahw.cmd_desc_phys_addr); | ||
345 | adapter->ahw.cmd_desc_head = NULL; | ||
346 | } | ||
347 | if (adapter->ahw.pauseaddr != NULL) { | ||
348 | pci_free_consistent(adapter->ahw.pause_pdev, 512, | ||
349 | adapter->ahw.pauseaddr, | ||
350 | adapter->ahw.pause_physaddr); | ||
351 | adapter->ahw.pauseaddr = NULL; | ||
352 | } | ||
353 | |||
354 | for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) { | ||
355 | recv_ctx = &adapter->recv_ctx[ctx]; | ||
356 | for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) { | ||
357 | rcv_desc = &recv_ctx->rcv_desc[ring]; | ||
358 | |||
359 | if (rcv_desc->desc_head != NULL) { | ||
360 | pci_free_consistent(rcv_desc->phys_pdev, | ||
361 | RCV_DESC_RINGSIZE, | ||
362 | rcv_desc->desc_head, | ||
363 | rcv_desc->phys_addr); | ||
364 | rcv_desc->desc_head = NULL; | ||
365 | } | ||
366 | } | ||
367 | |||
368 | if (recv_ctx->rcv_status_desc_head != NULL) { | ||
369 | pci_free_consistent(recv_ctx->rcv_status_desc_pdev, | ||
370 | STATUS_DESC_RINGSIZE, | ||
371 | recv_ctx->rcv_status_desc_head, | ||
372 | recv_ctx-> | ||
373 | rcv_status_desc_phys_addr); | ||
374 | recv_ctx->rcv_status_desc_head = NULL; | ||
375 | } | ||
376 | } | ||
377 | } | ||
378 | |||
379 | void netxen_tso_check(struct netxen_adapter *adapter, | ||
380 | struct cmd_desc_type0 *desc, struct sk_buff *skb) | ||
381 | { | ||
382 | if (desc->mss) { | ||
383 | desc->total_hdr_length = sizeof(struct ethhdr) + | ||
384 | ((skb->nh.iph)->ihl * sizeof(u32)) + | ||
385 | ((skb->h.th)->doff * sizeof(u32)); | ||
386 | desc->opcode = TX_TCP_LSO; | ||
387 | } else if (skb->ip_summed == CHECKSUM_COMPLETE) { | ||
388 | if (skb->nh.iph->protocol == IPPROTO_TCP) { | ||
389 | desc->opcode = TX_TCP_PKT; | ||
390 | } else if (skb->nh.iph->protocol == IPPROTO_UDP) { | ||
391 | desc->opcode = TX_UDP_PKT; | ||
392 | } else { | ||
393 | return; | ||
394 | } | ||
395 | } | ||
396 | adapter->stats.xmitcsummed++; | ||
397 | CMD_DESC_TCP_HDR_OFFSET_WRT(desc, skb->h.raw - skb->data); | ||
398 | desc->length_tcp_hdr = cpu_to_le32(desc->length_tcp_hdr); | ||
399 | desc->ip_hdr_offset = skb->nh.raw - skb->data; | ||
400 | } | ||
401 | |||
402 | int netxen_is_flash_supported(struct netxen_adapter *adapter) | ||
403 | { | ||
404 | const int locs[] = { 0, 0x4, 0x100, 0x4000, 0x4128 }; | ||
405 | int addr, val01, val02, i, j; | ||
406 | |||
407 | /* if the flash size less than 4Mb, make huge war cry and die */ | ||
408 | for (j = 1; j < 4; j++) { | ||
409 | addr = j * NETXEN_NIC_WINDOW_MARGIN; | ||
410 | for (i = 0; i < (sizeof(locs) / sizeof(locs[0])); i++) { | ||
411 | if (netxen_rom_fast_read(adapter, locs[i], &val01) == 0 | ||
412 | && netxen_rom_fast_read(adapter, (addr + locs[i]), | ||
413 | &val02) == 0) { | ||
414 | if (val01 == val02) | ||
415 | return -1; | ||
416 | } else | ||
417 | return -1; | ||
418 | } | ||
419 | } | ||
420 | |||
421 | return 0; | ||
422 | } | ||
423 | |||
424 | static int netxen_get_flash_block(struct netxen_adapter *adapter, int base, | ||
425 | int size, u32 * buf) | ||
426 | { | ||
427 | int i, addr; | ||
428 | u32 *ptr32; | ||
429 | |||
430 | addr = base; | ||
431 | ptr32 = buf; | ||
432 | for (i = 0; i < size / sizeof(u32); i++) { | ||
433 | if (netxen_rom_fast_read(adapter, addr, ptr32) == -1) | ||
434 | return -1; | ||
435 | ptr32++; | ||
436 | addr += sizeof(u32); | ||
437 | } | ||
438 | if ((char *)buf + size > (char *)ptr32) { | ||
439 | u32 local; | ||
440 | |||
441 | if (netxen_rom_fast_read(adapter, addr, &local) == -1) | ||
442 | return -1; | ||
443 | memcpy(ptr32, &local, (char *)buf + size - (char *)ptr32); | ||
444 | } | ||
445 | |||
446 | return 0; | ||
447 | } | ||
448 | |||
449 | int netxen_get_flash_mac_addr(struct netxen_adapter *adapter, u64 mac[]) | ||
450 | { | ||
451 | u32 *pmac = (u32 *) & mac[0]; | ||
452 | |||
453 | if (netxen_get_flash_block(adapter, | ||
454 | USER_START + | ||
455 | offsetof(struct netxen_new_user_info, | ||
456 | mac_addr), | ||
457 | FLASH_NUM_PORTS * sizeof(u64), pmac) == -1) { | ||
458 | return -1; | ||
459 | } | ||
460 | if (*mac == ~0ULL) { | ||
461 | if (netxen_get_flash_block(adapter, | ||
462 | USER_START_OLD + | ||
463 | offsetof(struct netxen_user_old_info, | ||
464 | mac_addr), | ||
465 | FLASH_NUM_PORTS * sizeof(u64), | ||
466 | pmac) == -1) | ||
467 | return -1; | ||
468 | if (*mac == ~0ULL) | ||
469 | return -1; | ||
470 | } | ||
471 | return 0; | ||
472 | } | ||
473 | |||
474 | /* | ||
475 | * Changes the CRB window to the specified window. | ||
476 | */ | ||
477 | void netxen_nic_pci_change_crbwindow(struct netxen_adapter *adapter, u32 wndw) | ||
478 | { | ||
479 | void __iomem *offset; | ||
480 | u32 tmp; | ||
481 | int count = 0; | ||
482 | |||
483 | if (adapter->curr_window == wndw) | ||
484 | return; | ||
485 | |||
486 | /* | ||
487 | * Move the CRB window. | ||
488 | * We need to write to the "direct access" region of PCI | ||
489 | * to avoid a race condition where the window register has | ||
490 | * not been successfully written across CRB before the target | ||
491 | * register address is received by PCI. The direct region bypasses | ||
492 | * the CRB bus. | ||
493 | */ | ||
494 | offset = | ||
495 | PCI_OFFSET_SECOND_RANGE(adapter, | ||
496 | NETXEN_PCIX_PH_REG(PCIX_CRB_WINDOW)); | ||
497 | |||
498 | if (wndw & 0x1) | ||
499 | wndw = NETXEN_WINDOW_ONE; | ||
500 | |||
501 | writel(wndw, offset); | ||
502 | |||
503 | /* MUST make sure window is set before we forge on... */ | ||
504 | while ((tmp = readl(offset)) != wndw) { | ||
505 | printk(KERN_WARNING "%s: %s WARNING: CRB window value not " | ||
506 | "registered properly: 0x%08x.\n", | ||
507 | netxen_nic_driver_name, __FUNCTION__, tmp); | ||
508 | mdelay(1); | ||
509 | if (count >= 10) | ||
510 | break; | ||
511 | count++; | ||
512 | } | ||
513 | |||
514 | adapter->curr_window = wndw; | ||
515 | } | ||
516 | |||
517 | void netxen_load_firmware(struct netxen_adapter *adapter) | ||
518 | { | ||
519 | int i; | ||
520 | long data, size = 0; | ||
521 | long flashaddr = NETXEN_FLASH_BASE, memaddr = NETXEN_PHANTOM_MEM_BASE; | ||
522 | u64 off; | ||
523 | void __iomem *addr; | ||
524 | |||
525 | size = NETXEN_FIRMWARE_LEN; | ||
526 | writel(1, NETXEN_CRB_NORMALIZE(adapter, NETXEN_ROMUSB_GLB_CAS_RST)); | ||
527 | |||
528 | for (i = 0; i < size; i++) { | ||
529 | if (netxen_rom_fast_read(adapter, flashaddr, (int *)&data) != 0) { | ||
530 | DPRINTK(ERR, | ||
531 | "Error in netxen_rom_fast_read(). Will skip" | ||
532 | "loading flash image\n"); | ||
533 | return; | ||
534 | } | ||
535 | off = netxen_nic_pci_set_window(adapter, memaddr); | ||
536 | addr = pci_base_offset(adapter, off); | ||
537 | writel(data, addr); | ||
538 | flashaddr += 4; | ||
539 | memaddr += 4; | ||
540 | } | ||
541 | udelay(100); | ||
542 | /* make sure Casper is powered on */ | ||
543 | writel(0x3fff, | ||
544 | NETXEN_CRB_NORMALIZE(adapter, NETXEN_ROMUSB_GLB_CHIP_CLK_CTRL)); | ||
545 | writel(0, NETXEN_CRB_NORMALIZE(adapter, NETXEN_ROMUSB_GLB_CAS_RST)); | ||
546 | |||
547 | udelay(100); | ||
548 | } | ||
549 | |||
550 | int | ||
551 | netxen_nic_hw_write_wx(struct netxen_adapter *adapter, u64 off, void *data, | ||
552 | int len) | ||
553 | { | ||
554 | void __iomem *addr; | ||
555 | |||
556 | if (ADDR_IN_WINDOW1(off)) { | ||
557 | addr = NETXEN_CRB_NORMALIZE(adapter, off); | ||
558 | } else { /* Window 0 */ | ||
559 | addr = pci_base_offset(adapter, off); | ||
560 | netxen_nic_pci_change_crbwindow(adapter, 0); | ||
561 | } | ||
562 | |||
563 | DPRINTK(INFO, "writing to base %lx offset %llx addr %p" | ||
564 | " data %llx len %d\n", | ||
565 | pci_base(adapter, off), off, addr, | ||
566 | *(unsigned long long *)data, len); | ||
567 | if (!addr) { | ||
568 | netxen_nic_pci_change_crbwindow(adapter, 1); | ||
569 | return 1; | ||
570 | } | ||
571 | |||
572 | switch (len) { | ||
573 | case 1: | ||
574 | writeb(*(u8 *) data, addr); | ||
575 | break; | ||
576 | case 2: | ||
577 | writew(*(u16 *) data, addr); | ||
578 | break; | ||
579 | case 4: | ||
580 | writel(*(u32 *) data, addr); | ||
581 | break; | ||
582 | case 8: | ||
583 | writeq(*(u64 *) data, addr); | ||
584 | break; | ||
585 | default: | ||
586 | DPRINTK(INFO, | ||
587 | "writing data %lx to offset %llx, num words=%d\n", | ||
588 | *(unsigned long *)data, off, (len >> 3)); | ||
589 | |||
590 | netxen_nic_hw_block_write64((u64 __iomem *) data, addr, | ||
591 | (len >> 3)); | ||
592 | break; | ||
593 | } | ||
594 | if (!ADDR_IN_WINDOW1(off)) | ||
595 | netxen_nic_pci_change_crbwindow(adapter, 1); | ||
596 | |||
597 | return 0; | ||
598 | } | ||
599 | |||
600 | int | ||
601 | netxen_nic_hw_read_wx(struct netxen_adapter *adapter, u64 off, void *data, | ||
602 | int len) | ||
603 | { | ||
604 | void __iomem *addr; | ||
605 | |||
606 | if (ADDR_IN_WINDOW1(off)) { /* Window 1 */ | ||
607 | addr = NETXEN_CRB_NORMALIZE(adapter, off); | ||
608 | } else { /* Window 0 */ | ||
609 | addr = pci_base_offset(adapter, off); | ||
610 | netxen_nic_pci_change_crbwindow(adapter, 0); | ||
611 | } | ||
612 | |||
613 | DPRINTK(INFO, "reading from base %lx offset %llx addr %p\n", | ||
614 | pci_base(adapter, off), off, addr); | ||
615 | if (!addr) { | ||
616 | netxen_nic_pci_change_crbwindow(adapter, 1); | ||
617 | return 1; | ||
618 | } | ||
619 | switch (len) { | ||
620 | case 1: | ||
621 | *(u8 *) data = readb(addr); | ||
622 | break; | ||
623 | case 2: | ||
624 | *(u16 *) data = readw(addr); | ||
625 | break; | ||
626 | case 4: | ||
627 | *(u32 *) data = readl(addr); | ||
628 | break; | ||
629 | case 8: | ||
630 | *(u64 *) data = readq(addr); | ||
631 | break; | ||
632 | default: | ||
633 | netxen_nic_hw_block_read64((u64 __iomem *) data, addr, | ||
634 | (len >> 3)); | ||
635 | break; | ||
636 | } | ||
637 | DPRINTK(INFO, "read %lx\n", *(unsigned long *)data); | ||
638 | |||
639 | if (!ADDR_IN_WINDOW1(off)) | ||
640 | netxen_nic_pci_change_crbwindow(adapter, 1); | ||
641 | |||
642 | return 0; | ||
643 | } | ||
644 | |||
645 | void netxen_nic_reg_write(struct netxen_adapter *adapter, u64 off, u32 val) | ||
646 | { /* Only for window 1 */ | ||
647 | void __iomem *addr; | ||
648 | |||
649 | addr = NETXEN_CRB_NORMALIZE(adapter, off); | ||
650 | DPRINTK(INFO, "writing to base %lx offset %llx addr %p data %x\n", | ||
651 | pci_base(adapter, off), off, addr); | ||
652 | writel(val, addr); | ||
653 | |||
654 | } | ||
655 | |||
656 | int netxen_nic_reg_read(struct netxen_adapter *adapter, u64 off) | ||
657 | { /* Only for window 1 */ | ||
658 | void __iomem *addr; | ||
659 | int val; | ||
660 | |||
661 | addr = NETXEN_CRB_NORMALIZE(adapter, off); | ||
662 | DPRINTK(INFO, "reading from base %lx offset %llx addr %p\n", | ||
663 | adapter->ahw.pci_base, off, addr); | ||
664 | val = readl(addr); | ||
665 | writel(val, addr); | ||
666 | |||
667 | return val; | ||
668 | } | ||
669 | |||
670 | /* Change the window to 0, write and change back to window 1. */ | ||
671 | void netxen_nic_write_w0(struct netxen_adapter *adapter, u32 index, u32 value) | ||
672 | { | ||
673 | void __iomem *addr; | ||
674 | |||
675 | netxen_nic_pci_change_crbwindow(adapter, 0); | ||
676 | addr = pci_base_offset(adapter, index); | ||
677 | writel(value, addr); | ||
678 | netxen_nic_pci_change_crbwindow(adapter, 1); | ||
679 | } | ||
680 | |||
681 | /* Change the window to 0, read and change back to window 1. */ | ||
682 | void netxen_nic_read_w0(struct netxen_adapter *adapter, u32 index, u32 * value) | ||
683 | { | ||
684 | void __iomem *addr; | ||
685 | |||
686 | addr = pci_base_offset(adapter, index); | ||
687 | |||
688 | netxen_nic_pci_change_crbwindow(adapter, 0); | ||
689 | *value = readl(addr); | ||
690 | netxen_nic_pci_change_crbwindow(adapter, 1); | ||
691 | } | ||
692 | |||
693 | int netxen_pci_set_window_warning_count = 0; | ||
694 | |||
695 | unsigned long | ||
696 | netxen_nic_pci_set_window(struct netxen_adapter *adapter, | ||
697 | unsigned long long addr) | ||
698 | { | ||
699 | static int ddr_mn_window = -1; | ||
700 | static int qdr_sn_window = -1; | ||
701 | int window; | ||
702 | |||
703 | if (ADDR_IN_RANGE(addr, NETXEN_ADDR_DDR_NET, NETXEN_ADDR_DDR_NET_MAX)) { | ||
704 | /* DDR network side */ | ||
705 | addr -= NETXEN_ADDR_DDR_NET; | ||
706 | window = (addr >> 25) & 0x3ff; | ||
707 | if (ddr_mn_window != window) { | ||
708 | ddr_mn_window = window; | ||
709 | writel(window, PCI_OFFSET_SECOND_RANGE(adapter, | ||
710 | NETXEN_PCIX_PH_REG | ||
711 | (PCIX_MN_WINDOW))); | ||
712 | /* MUST make sure window is set before we forge on... */ | ||
713 | readl(PCI_OFFSET_SECOND_RANGE(adapter, | ||
714 | NETXEN_PCIX_PH_REG | ||
715 | (PCIX_MN_WINDOW))); | ||
716 | } | ||
717 | addr -= (window * NETXEN_WINDOW_ONE); | ||
718 | addr += NETXEN_PCI_DDR_NET; | ||
719 | } else if (ADDR_IN_RANGE(addr, NETXEN_ADDR_OCM0, NETXEN_ADDR_OCM0_MAX)) { | ||
720 | addr -= NETXEN_ADDR_OCM0; | ||
721 | addr += NETXEN_PCI_OCM0; | ||
722 | } else if (ADDR_IN_RANGE(addr, NETXEN_ADDR_OCM1, NETXEN_ADDR_OCM1_MAX)) { | ||
723 | addr -= NETXEN_ADDR_OCM1; | ||
724 | addr += NETXEN_PCI_OCM1; | ||
725 | } else | ||
726 | if (ADDR_IN_RANGE | ||
727 | (addr, NETXEN_ADDR_QDR_NET, NETXEN_ADDR_QDR_NET_MAX)) { | ||
728 | /* QDR network side */ | ||
729 | addr -= NETXEN_ADDR_QDR_NET; | ||
730 | window = (addr >> 22) & 0x3f; | ||
731 | if (qdr_sn_window != window) { | ||
732 | qdr_sn_window = window; | ||
733 | writel((window << 22), | ||
734 | PCI_OFFSET_SECOND_RANGE(adapter, | ||
735 | NETXEN_PCIX_PH_REG | ||
736 | (PCIX_SN_WINDOW))); | ||
737 | /* MUST make sure window is set before we forge on... */ | ||
738 | readl(PCI_OFFSET_SECOND_RANGE(adapter, | ||
739 | NETXEN_PCIX_PH_REG | ||
740 | (PCIX_SN_WINDOW))); | ||
741 | } | ||
742 | addr -= (window * 0x400000); | ||
743 | addr += NETXEN_PCI_QDR_NET; | ||
744 | } else { | ||
745 | /* | ||
746 | * peg gdb frequently accesses memory that doesn't exist, | ||
747 | * this limits the chit chat so debugging isn't slowed down. | ||
748 | */ | ||
749 | if ((netxen_pci_set_window_warning_count++ < 8) | ||
750 | || (netxen_pci_set_window_warning_count % 64 == 0)) | ||
751 | printk("%s: Warning:netxen_nic_pci_set_window()" | ||
752 | " Unknown address range!\n", | ||
753 | netxen_nic_driver_name); | ||
754 | |||
755 | } | ||
756 | return addr; | ||
757 | } | ||
758 | |||
759 | int netxen_nic_get_board_info(struct netxen_adapter *adapter) | ||
760 | { | ||
761 | int rv = 0; | ||
762 | int addr = BRDCFG_START; | ||
763 | struct netxen_board_info *boardinfo; | ||
764 | int index; | ||
765 | u32 *ptr32; | ||
766 | |||
767 | boardinfo = &adapter->ahw.boardcfg; | ||
768 | ptr32 = (u32 *) boardinfo; | ||
769 | |||
770 | for (index = 0; index < sizeof(struct netxen_board_info) / sizeof(u32); | ||
771 | index++) { | ||
772 | if (netxen_rom_fast_read(adapter, addr, ptr32) == -1) { | ||
773 | return -EIO; | ||
774 | } | ||
775 | ptr32++; | ||
776 | addr += sizeof(u32); | ||
777 | } | ||
778 | if (boardinfo->magic != NETXEN_BDINFO_MAGIC) { | ||
779 | printk("%s: ERROR reading %s board config." | ||
780 | " Read %x, expected %x\n", netxen_nic_driver_name, | ||
781 | netxen_nic_driver_name, | ||
782 | boardinfo->magic, NETXEN_BDINFO_MAGIC); | ||
783 | rv = -1; | ||
784 | } | ||
785 | if (boardinfo->header_version != NETXEN_BDINFO_VERSION) { | ||
786 | printk("%s: Unknown board config version." | ||
787 | " Read %x, expected %x\n", netxen_nic_driver_name, | ||
788 | boardinfo->header_version, NETXEN_BDINFO_VERSION); | ||
789 | rv = -1; | ||
790 | } | ||
791 | |||
792 | DPRINTK(INFO, "Discovered board type:0x%x ", boardinfo->board_type); | ||
793 | switch ((netxen_brdtype_t) boardinfo->board_type) { | ||
794 | case NETXEN_BRDTYPE_P2_SB35_4G: | ||
795 | adapter->ahw.board_type = NETXEN_NIC_GBE; | ||
796 | break; | ||
797 | case NETXEN_BRDTYPE_P2_SB31_10G: | ||
798 | case NETXEN_BRDTYPE_P2_SB31_10G_IMEZ: | ||
799 | case NETXEN_BRDTYPE_P2_SB31_10G_HMEZ: | ||
800 | case NETXEN_BRDTYPE_P2_SB31_10G_CX4: | ||
801 | adapter->ahw.board_type = NETXEN_NIC_XGBE; | ||
802 | break; | ||
803 | case NETXEN_BRDTYPE_P1_BD: | ||
804 | case NETXEN_BRDTYPE_P1_SB: | ||
805 | case NETXEN_BRDTYPE_P1_SMAX: | ||
806 | case NETXEN_BRDTYPE_P1_SOCK: | ||
807 | adapter->ahw.board_type = NETXEN_NIC_GBE; | ||
808 | break; | ||
809 | default: | ||
810 | printk("%s: Unknown(%x)\n", netxen_nic_driver_name, | ||
811 | boardinfo->board_type); | ||
812 | break; | ||
813 | } | ||
814 | |||
815 | return rv; | ||
816 | } | ||
817 | |||
818 | /* NIU access sections */ | ||
819 | |||
820 | int netxen_nic_set_mtu_gb(struct netxen_port *port, int new_mtu) | ||
821 | { | ||
822 | struct netxen_adapter *adapter = port->adapter; | ||
823 | netxen_nic_write_w0(adapter, | ||
824 | NETXEN_NIU_GB_MAX_FRAME_SIZE(port->portnum), | ||
825 | new_mtu); | ||
826 | return 0; | ||
827 | } | ||
828 | |||
829 | int netxen_nic_set_mtu_xgb(struct netxen_port *port, int new_mtu) | ||
830 | { | ||
831 | struct netxen_adapter *adapter = port->adapter; | ||
832 | new_mtu += NETXEN_NIU_HDRSIZE + NETXEN_NIU_TLRSIZE; | ||
833 | netxen_nic_write_w0(adapter, NETXEN_NIU_XGE_MAX_FRAME_SIZE, new_mtu); | ||
834 | return 0; | ||
835 | } | ||
836 | |||
837 | void netxen_nic_init_niu_gb(struct netxen_adapter *adapter) | ||
838 | { | ||
839 | int portno; | ||
840 | for (portno = 0; portno < NETXEN_NIU_MAX_GBE_PORTS; portno++) | ||
841 | netxen_niu_gbe_init_port(adapter, portno); | ||
842 | } | ||
843 | |||
844 | void netxen_nic_stop_all_ports(struct netxen_adapter *adapter) | ||
845 | { | ||
846 | int port_nr; | ||
847 | struct netxen_port *port; | ||
848 | |||
849 | for (port_nr = 0; port_nr < adapter->ahw.max_ports; port_nr++) { | ||
850 | port = adapter->port[port_nr]; | ||
851 | if (adapter->ops->stop_port) | ||
852 | adapter->ops->stop_port(adapter, port->portnum); | ||
853 | } | ||
854 | } | ||
855 | |||
856 | void | ||
857 | netxen_crb_writelit_adapter(struct netxen_adapter *adapter, unsigned long off, | ||
858 | int data) | ||
859 | { | ||
860 | void __iomem *addr; | ||
861 | |||
862 | if (ADDR_IN_WINDOW1(off)) { | ||
863 | writel(data, NETXEN_CRB_NORMALIZE(adapter, off)); | ||
864 | } else { | ||
865 | netxen_nic_pci_change_crbwindow(adapter, 0); | ||
866 | addr = pci_base_offset(adapter, off); | ||
867 | writel(data, addr); | ||
868 | netxen_nic_pci_change_crbwindow(adapter, 1); | ||
869 | } | ||
870 | } | ||
871 | |||
872 | void netxen_nic_set_link_parameters(struct netxen_port *port) | ||
873 | { | ||
874 | struct netxen_adapter *adapter = port->adapter; | ||
875 | __le32 status; | ||
876 | u16 autoneg; | ||
877 | __le32 mode; | ||
878 | |||
879 | netxen_nic_read_w0(adapter, NETXEN_NIU_MODE, &mode); | ||
880 | if (netxen_get_niu_enable_ge(mode)) { /* Gb 10/100/1000 Mbps mode */ | ||
881 | if (adapter->ops->phy_read | ||
882 | && adapter->ops-> | ||
883 | phy_read(adapter, port->portnum, | ||
884 | NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS, | ||
885 | &status) == 0) { | ||
886 | if (netxen_get_phy_link(status)) { | ||
887 | switch (netxen_get_phy_speed(status)) { | ||
888 | case 0: | ||
889 | port->link_speed = SPEED_10; | ||
890 | break; | ||
891 | case 1: | ||
892 | port->link_speed = SPEED_100; | ||
893 | break; | ||
894 | case 2: | ||
895 | port->link_speed = SPEED_1000; | ||
896 | break; | ||
897 | default: | ||
898 | port->link_speed = -1; | ||
899 | break; | ||
900 | } | ||
901 | switch (netxen_get_phy_duplex(status)) { | ||
902 | case 0: | ||
903 | port->link_duplex = DUPLEX_HALF; | ||
904 | break; | ||
905 | case 1: | ||
906 | port->link_duplex = DUPLEX_FULL; | ||
907 | break; | ||
908 | default: | ||
909 | port->link_duplex = -1; | ||
910 | break; | ||
911 | } | ||
912 | if (adapter->ops->phy_read | ||
913 | && adapter->ops-> | ||
914 | phy_read(adapter, port->portnum, | ||
915 | NETXEN_NIU_GB_MII_MGMT_ADDR_AUTONEG, | ||
916 | (__le32 *) & autoneg) != 0) | ||
917 | port->link_autoneg = autoneg; | ||
918 | } else | ||
919 | goto link_down; | ||
920 | } else { | ||
921 | link_down: | ||
922 | port->link_speed = -1; | ||
923 | port->link_duplex = -1; | ||
924 | } | ||
925 | } | ||
926 | } | ||
927 | |||
928 | void netxen_nic_flash_print(struct netxen_adapter *adapter) | ||
929 | { | ||
930 | int valid = 1; | ||
931 | u32 fw_major = 0; | ||
932 | u32 fw_minor = 0; | ||
933 | u32 fw_build = 0; | ||
934 | char brd_name[NETXEN_MAX_SHORT_NAME]; | ||
935 | struct netxen_new_user_info user_info; | ||
936 | int i, addr = USER_START; | ||
937 | u32 *ptr32; | ||
938 | |||
939 | struct netxen_board_info *board_info = &(adapter->ahw.boardcfg); | ||
940 | if (board_info->magic != NETXEN_BDINFO_MAGIC) { | ||
941 | printk | ||
942 | ("NetXen Unknown board config, Read 0x%x expected as 0x%x\n", | ||
943 | board_info->magic, NETXEN_BDINFO_MAGIC); | ||
944 | valid = 0; | ||
945 | } | ||
946 | if (board_info->header_version != NETXEN_BDINFO_VERSION) { | ||
947 | printk("NetXen Unknown board config version." | ||
948 | " Read %x, expected %x\n", | ||
949 | board_info->header_version, NETXEN_BDINFO_VERSION); | ||
950 | valid = 0; | ||
951 | } | ||
952 | if (valid) { | ||
953 | ptr32 = (u32 *) & user_info; | ||
954 | for (i = 0; | ||
955 | i < sizeof(struct netxen_new_user_info) / sizeof(u32); | ||
956 | i++) { | ||
957 | if (netxen_rom_fast_read(adapter, addr, ptr32) == -1) { | ||
958 | printk("%s: ERROR reading %s board userarea.\n", | ||
959 | netxen_nic_driver_name, | ||
960 | netxen_nic_driver_name); | ||
961 | return; | ||
962 | } | ||
963 | ptr32++; | ||
964 | addr += sizeof(u32); | ||
965 | } | ||
966 | get_brd_name_by_type(board_info->board_type, brd_name); | ||
967 | |||
968 | printk("NetXen %s Board S/N %s Chip id 0x%x\n", | ||
969 | brd_name, user_info.serial_num, board_info->chip_id); | ||
970 | |||
971 | printk("NetXen %s Board #%d, Chip id 0x%x\n", | ||
972 | board_info->board_type == 0x0b ? "XGB" : "GBE", | ||
973 | board_info->board_num, board_info->chip_id); | ||
974 | fw_major = readl(NETXEN_CRB_NORMALIZE(adapter, | ||
975 | NETXEN_FW_VERSION_MAJOR)); | ||
976 | fw_minor = readl(NETXEN_CRB_NORMALIZE(adapter, | ||
977 | NETXEN_FW_VERSION_MINOR)); | ||
978 | fw_build = | ||
979 | readl(NETXEN_CRB_NORMALIZE(adapter, NETXEN_FW_VERSION_SUB)); | ||
980 | |||
981 | printk("NetXen Firmware version %d.%d.%d\n", fw_major, fw_minor, | ||
982 | fw_build); | ||
983 | } | ||
984 | if (fw_major != _NETXEN_NIC_LINUX_MAJOR) { | ||
985 | printk(KERN_ERR "The mismatch in driver version and firmware " | ||
986 | "version major number\n" | ||
987 | "Driver version major number = %d \t" | ||
988 | "Firmware version major number = %d \n", | ||
989 | _NETXEN_NIC_LINUX_MAJOR, fw_major); | ||
990 | adapter->driver_mismatch = 1; | ||
991 | } | ||
992 | if (fw_minor != _NETXEN_NIC_LINUX_MINOR) { | ||
993 | printk(KERN_ERR "The mismatch in driver version and firmware " | ||
994 | "version minor number\n" | ||
995 | "Driver version minor number = %d \t" | ||
996 | "Firmware version minor number = %d \n", | ||
997 | _NETXEN_NIC_LINUX_MINOR, fw_minor); | ||
998 | adapter->driver_mismatch = 1; | ||
999 | } | ||
1000 | if (adapter->driver_mismatch) | ||
1001 | printk(KERN_INFO "Use the driver with version no %d.%d.xxx\n", | ||
1002 | fw_major, fw_minor); | ||
1003 | } | ||
1004 | |||
1005 | int netxen_crb_read_val(struct netxen_adapter *adapter, unsigned long off) | ||
1006 | { | ||
1007 | int data; | ||
1008 | netxen_nic_hw_read_wx(adapter, off, &data, 4); | ||
1009 | return data; | ||
1010 | } | ||