Merge git://git.infradead.org/users/dhowells/workq-2.6
[pandora-kernel.git] / drivers / net / netxen / netxen_nic_init.c
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 initialize the Phantom Hardware
31  *
32  */
33
34 #include <linux/netdevice.h>
35 #include <linux/delay.h>
36 #include "netxen_nic.h"
37 #include "netxen_nic_hw.h"
38 #include "netxen_nic_ioctl.h"
39 #include "netxen_nic_phan_reg.h"
40
41 struct crb_addr_pair {
42         long addr;
43         long data;
44 };
45
46 #define NETXEN_MAX_CRB_XFORM 60
47 static unsigned int crb_addr_xform[NETXEN_MAX_CRB_XFORM];
48 #define NETXEN_ADDR_ERROR ((unsigned long ) 0xffffffff )
49
50 #define crb_addr_transform(name) \
51         crb_addr_xform[NETXEN_HW_PX_MAP_CRB_##name] = \
52         NETXEN_HW_CRB_HUB_AGT_ADR_##name << 20
53
54 #define NETXEN_NIC_XDMA_RESET 0x8000ff
55
56 static inline void
57 netxen_nic_locked_write_reg(struct netxen_adapter *adapter,
58                             unsigned long off, int *data)
59 {
60         void __iomem *addr = pci_base_offset(adapter, off);
61         writel(*data, addr);
62 }
63
64 static void crb_addr_transform_setup(void)
65 {
66         crb_addr_transform(XDMA);
67         crb_addr_transform(TIMR);
68         crb_addr_transform(SRE);
69         crb_addr_transform(SQN3);
70         crb_addr_transform(SQN2);
71         crb_addr_transform(SQN1);
72         crb_addr_transform(SQN0);
73         crb_addr_transform(SQS3);
74         crb_addr_transform(SQS2);
75         crb_addr_transform(SQS1);
76         crb_addr_transform(SQS0);
77         crb_addr_transform(RPMX7);
78         crb_addr_transform(RPMX6);
79         crb_addr_transform(RPMX5);
80         crb_addr_transform(RPMX4);
81         crb_addr_transform(RPMX3);
82         crb_addr_transform(RPMX2);
83         crb_addr_transform(RPMX1);
84         crb_addr_transform(RPMX0);
85         crb_addr_transform(ROMUSB);
86         crb_addr_transform(SN);
87         crb_addr_transform(QMN);
88         crb_addr_transform(QMS);
89         crb_addr_transform(PGNI);
90         crb_addr_transform(PGND);
91         crb_addr_transform(PGN3);
92         crb_addr_transform(PGN2);
93         crb_addr_transform(PGN1);
94         crb_addr_transform(PGN0);
95         crb_addr_transform(PGSI);
96         crb_addr_transform(PGSD);
97         crb_addr_transform(PGS3);
98         crb_addr_transform(PGS2);
99         crb_addr_transform(PGS1);
100         crb_addr_transform(PGS0);
101         crb_addr_transform(PS);
102         crb_addr_transform(PH);
103         crb_addr_transform(NIU);
104         crb_addr_transform(I2Q);
105         crb_addr_transform(EG);
106         crb_addr_transform(MN);
107         crb_addr_transform(MS);
108         crb_addr_transform(CAS2);
109         crb_addr_transform(CAS1);
110         crb_addr_transform(CAS0);
111         crb_addr_transform(CAM);
112         crb_addr_transform(C2C1);
113         crb_addr_transform(C2C0);
114 }
115
116 int netxen_init_firmware(struct netxen_adapter *adapter)
117 {
118         u32 state = 0, loops = 0, err = 0;
119
120         /* Window 1 call */
121         state = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_STATE));
122
123         if (state == PHAN_INITIALIZE_ACK)
124                 return 0;
125
126         while (state != PHAN_INITIALIZE_COMPLETE && loops < 2000) {
127                 udelay(100);
128                 /* Window 1 call */
129                 state = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_STATE));
130
131                 loops++;
132         }
133         if (loops >= 2000) {
134                 printk(KERN_ERR "Cmd Peg initialization not complete:%x.\n",
135                        state);
136                 err = -EIO;
137                 return err;
138         }
139         /* Window 1 call */
140         writel(PHAN_INITIALIZE_ACK,
141                NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_STATE));
142
143         return err;
144 }
145
146 #define NETXEN_ADDR_LIMIT 0xffffffffULL
147
148 void *netxen_alloc(struct pci_dev *pdev, size_t sz, dma_addr_t * ptr,
149                    struct pci_dev **used_dev)
150 {
151         void *addr;
152
153         addr = pci_alloc_consistent(pdev, sz, ptr);
154         if ((unsigned long long)(*ptr) < NETXEN_ADDR_LIMIT) {
155                 *used_dev = pdev;
156                 return addr;
157         }
158         pci_free_consistent(pdev, sz, addr, *ptr);
159         addr = pci_alloc_consistent(NULL, sz, ptr);
160         *used_dev = NULL;
161         return addr;
162 }
163
164 void netxen_initialize_adapter_sw(struct netxen_adapter *adapter)
165 {
166         int ctxid, ring;
167         u32 i;
168         u32 num_rx_bufs = 0;
169         struct netxen_rcv_desc_ctx *rcv_desc;
170
171         DPRINTK(INFO, "initializing some queues: %p\n", adapter);
172         for (ctxid = 0; ctxid < MAX_RCV_CTX; ++ctxid) {
173                 for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) {
174                         struct netxen_rx_buffer *rx_buf;
175                         rcv_desc = &adapter->recv_ctx[ctxid].rcv_desc[ring];
176                         rcv_desc->rcv_free = rcv_desc->max_rx_desc_count;
177                         rcv_desc->begin_alloc = 0;
178                         rx_buf = rcv_desc->rx_buf_arr;
179                         num_rx_bufs = rcv_desc->max_rx_desc_count;
180                         /*
181                          * Now go through all of them, set reference handles
182                          * and put them in the queues.
183                          */
184                         for (i = 0; i < num_rx_bufs; i++) {
185                                 rx_buf->ref_handle = i;
186                                 rx_buf->state = NETXEN_BUFFER_FREE;
187
188                                 DPRINTK(INFO, "Rx buf:ctx%d i(%d) rx_buf:"
189                                         "%p\n", ctxid, i, rx_buf);
190                                 rx_buf++;
191                         }
192                 }
193         }
194         DPRINTK(INFO, "initialized buffers for %s and %s\n",
195                 "adapter->free_cmd_buf_list", "adapter->free_rxbuf");
196 }
197
198 void netxen_initialize_adapter_hw(struct netxen_adapter *adapter)
199 {
200         int ports = 0;
201         struct netxen_board_info *board_info = &(adapter->ahw.boardcfg);
202
203         if (netxen_nic_get_board_info(adapter) != 0)
204                 printk("%s: Error getting board config info.\n",
205                        netxen_nic_driver_name);
206         get_brd_port_by_type(board_info->board_type, &ports);
207         if (ports == 0)
208                 printk(KERN_ERR "%s: Unknown board type\n",
209                        netxen_nic_driver_name);
210         adapter->ahw.max_ports = ports;
211 }
212
213 void netxen_initialize_adapter_ops(struct netxen_adapter *adapter)
214 {
215         struct netxen_drvops *ops = adapter->ops;
216         switch (adapter->ahw.board_type) {
217         case NETXEN_NIC_GBE:
218                 ops->enable_phy_interrupts =
219                     netxen_niu_gbe_enable_phy_interrupts;
220                 ops->disable_phy_interrupts =
221                     netxen_niu_gbe_disable_phy_interrupts;
222                 ops->handle_phy_intr = netxen_nic_gbe_handle_phy_intr;
223                 ops->macaddr_set = netxen_niu_macaddr_set;
224                 ops->set_mtu = netxen_nic_set_mtu_gb;
225                 ops->set_promisc = netxen_niu_set_promiscuous_mode;
226                 ops->unset_promisc = netxen_niu_set_promiscuous_mode;
227                 ops->phy_read = netxen_niu_gbe_phy_read;
228                 ops->phy_write = netxen_niu_gbe_phy_write;
229                 ops->init_port = netxen_niu_gbe_init_port;
230                 ops->init_niu = netxen_nic_init_niu_gb;
231                 ops->stop_port = netxen_niu_disable_gbe_port;
232                 break;
233
234         case NETXEN_NIC_XGBE:
235                 ops->enable_phy_interrupts =
236                     netxen_niu_xgbe_enable_phy_interrupts;
237                 ops->disable_phy_interrupts =
238                     netxen_niu_xgbe_disable_phy_interrupts;
239                 ops->handle_phy_intr = netxen_nic_xgbe_handle_phy_intr;
240                 ops->macaddr_set = netxen_niu_xg_macaddr_set;
241                 ops->set_mtu = netxen_nic_set_mtu_xgb;
242                 ops->init_port = netxen_niu_xg_init_port;
243                 ops->set_promisc = netxen_niu_xg_set_promiscuous_mode;
244                 ops->unset_promisc = netxen_niu_xg_set_promiscuous_mode;
245                 ops->stop_port = netxen_niu_disable_xg_port;
246                 break;
247
248         default:
249                 break;
250         }
251 }
252
253 /*
254  * netxen_decode_crb_addr(0 - utility to translate from internal Phantom CRB
255  * address to external PCI CRB address.
256  */
257 unsigned long netxen_decode_crb_addr(unsigned long addr)
258 {
259         int i;
260         unsigned long base_addr, offset, pci_base;
261
262         crb_addr_transform_setup();
263
264         pci_base = NETXEN_ADDR_ERROR;
265         base_addr = addr & 0xfff00000;
266         offset = addr & 0x000fffff;
267
268         for (i = 0; i < NETXEN_MAX_CRB_XFORM; i++) {
269                 if (crb_addr_xform[i] == base_addr) {
270                         pci_base = i << 20;
271                         break;
272                 }
273         }
274         if (pci_base == NETXEN_ADDR_ERROR)
275                 return pci_base;
276         else
277                 return (pci_base + offset);
278 }
279
280 static long rom_max_timeout = 10000;
281 static long rom_lock_timeout = 1000000;
282
283 static inline int rom_lock(struct netxen_adapter *adapter)
284 {
285         int iter;
286         u32 done = 0;
287         int timeout = 0;
288
289         while (!done) {
290                 /* acquire semaphore2 from PCI HW block */
291                 netxen_nic_read_w0(adapter, NETXEN_PCIE_REG(PCIE_SEM2_LOCK),
292                                    &done);
293                 if (done == 1)
294                         break;
295                 if (timeout >= rom_lock_timeout)
296                         return -EIO;
297
298                 timeout++;
299                 /*
300                  * Yield CPU
301                  */
302                 if (!in_atomic())
303                         schedule();
304                 else {
305                         for (iter = 0; iter < 20; iter++)
306                                 cpu_relax();    /*This a nop instr on i386 */
307                 }
308         }
309         netxen_nic_reg_write(adapter, NETXEN_ROM_LOCK_ID, ROM_LOCK_DRIVER);
310         return 0;
311 }
312
313 int netxen_wait_rom_done(struct netxen_adapter *adapter)
314 {
315         long timeout = 0;
316         long done = 0;
317
318         while (done == 0) {
319                 done = netxen_nic_reg_read(adapter, NETXEN_ROMUSB_GLB_STATUS);
320                 done &= 2;
321                 timeout++;
322                 if (timeout >= rom_max_timeout) {
323                         printk("Timeout reached  waiting for rom done");
324                         return -EIO;
325                 }
326         }
327         return 0;
328 }
329
330 static inline int netxen_rom_wren(struct netxen_adapter *adapter)
331 {
332         /* Set write enable latch in ROM status register */
333         netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ABYTE_CNT, 0);
334         netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_INSTR_OPCODE,
335                              M25P_INSTR_WREN);
336         if (netxen_wait_rom_done(adapter)) {
337                 return -1;
338         }
339         return 0;
340 }
341
342 static inline unsigned int netxen_rdcrbreg(struct netxen_adapter *adapter,
343                                            unsigned int addr)
344 {
345         unsigned int data = 0xdeaddead;
346         data = netxen_nic_reg_read(adapter, addr);
347         return data;
348 }
349
350 static inline int netxen_do_rom_rdsr(struct netxen_adapter *adapter)
351 {
352         netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_INSTR_OPCODE,
353                              M25P_INSTR_RDSR);
354         if (netxen_wait_rom_done(adapter)) {
355                 return -1;
356         }
357         return netxen_rdcrbreg(adapter, NETXEN_ROMUSB_ROM_RDATA);
358 }
359
360 static inline void netxen_rom_unlock(struct netxen_adapter *adapter)
361 {
362         u32 val;
363
364         /* release semaphore2 */
365         netxen_nic_read_w0(adapter, NETXEN_PCIE_REG(PCIE_SEM2_UNLOCK), &val);
366
367 }
368
369 int netxen_rom_wip_poll(struct netxen_adapter *adapter)
370 {
371         long timeout = 0;
372         long wip = 1;
373         int val;
374         netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ABYTE_CNT, 0);
375         while (wip != 0) {
376                 val = netxen_do_rom_rdsr(adapter);
377                 wip = val & 1;
378                 timeout++;
379                 if (timeout > rom_max_timeout) {
380                         return -1;
381                 }
382         }
383         return 0;
384 }
385
386 static inline int do_rom_fast_write(struct netxen_adapter *adapter,
387                                     int addr, int data)
388 {
389         if (netxen_rom_wren(adapter)) {
390                 return -1;
391         }
392         netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_WDATA, data);
393         netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ADDRESS, addr);
394         netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ABYTE_CNT, 3);
395         netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_INSTR_OPCODE,
396                              M25P_INSTR_PP);
397         if (netxen_wait_rom_done(adapter)) {
398                 netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ABYTE_CNT, 0);
399                 return -1;
400         }
401
402         return netxen_rom_wip_poll(adapter);
403 }
404
405 static inline int
406 do_rom_fast_read(struct netxen_adapter *adapter, int addr, int *valp)
407 {
408         netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ADDRESS, addr);
409         netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ABYTE_CNT, 3);
410         udelay(100);            /* prevent bursting on CRB */
411         netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_DUMMY_BYTE_CNT, 0);
412         netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_INSTR_OPCODE, 0xb);
413         if (netxen_wait_rom_done(adapter)) {
414                 printk("Error waiting for rom done\n");
415                 return -EIO;
416         }
417         /* reset abyte_cnt and dummy_byte_cnt */
418         netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ABYTE_CNT, 0);
419         udelay(100);            /* prevent bursting on CRB */
420         netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_DUMMY_BYTE_CNT, 0);
421
422         *valp = netxen_nic_reg_read(adapter, NETXEN_ROMUSB_ROM_RDATA);
423         return 0;
424 }
425
426 int netxen_rom_fast_read(struct netxen_adapter *adapter, int addr, int *valp)
427 {
428         int ret;
429
430         if (rom_lock(adapter) != 0)
431                 return -EIO;
432
433         ret = do_rom_fast_read(adapter, addr, valp);
434         netxen_rom_unlock(adapter);
435         return ret;
436 }
437
438 int netxen_rom_fast_write(struct netxen_adapter *adapter, int addr, int data)
439 {
440         int ret = 0;
441
442         if (rom_lock(adapter) != 0) {
443                 return -1;
444         }
445         ret = do_rom_fast_write(adapter, addr, data);
446         netxen_rom_unlock(adapter);
447         return ret;
448 }
449 int netxen_do_rom_se(struct netxen_adapter *adapter, int addr)
450 {
451         netxen_rom_wren(adapter);
452         netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ADDRESS, addr);
453         netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ABYTE_CNT, 3);
454         netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_INSTR_OPCODE,
455                              M25P_INSTR_SE);
456         if (netxen_wait_rom_done(adapter)) {
457                 netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ABYTE_CNT, 0);
458                 return -1;
459         }
460         return netxen_rom_wip_poll(adapter);
461 }
462
463 int netxen_rom_se(struct netxen_adapter *adapter, int addr)
464 {
465         int ret = 0;
466         if (rom_lock(adapter) != 0) {
467                 return -1;
468         }
469         ret = netxen_do_rom_se(adapter, addr);
470         netxen_rom_unlock(adapter);
471         return ret;
472 }
473
474 #define NETXEN_BOARDTYPE                0x4008
475 #define NETXEN_BOARDNUM                 0x400c
476 #define NETXEN_CHIPNUM                  0x4010
477 #define NETXEN_ROMBUS_RESET             0xFFFFFFFF
478 #define NETXEN_ROM_FIRST_BARRIER        0x800000000ULL
479 #define NETXEN_ROM_FOUND_INIT           0x400
480
481 int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose)
482 {
483         int addr, val, status;
484         int n, i;
485         int init_delay = 0;
486         struct crb_addr_pair *buf;
487         unsigned long off;
488
489         /* resetall */
490         status = netxen_nic_get_board_info(adapter);
491         if (status)
492                 printk("%s: netxen_pinit_from_rom: Error getting board info\n",
493                        netxen_nic_driver_name);
494
495         netxen_crb_writelit_adapter(adapter, NETXEN_ROMUSB_GLB_SW_RESET,
496                                     NETXEN_ROMBUS_RESET);
497
498         if (verbose) {
499                 int val;
500                 if (netxen_rom_fast_read(adapter, NETXEN_BOARDTYPE, &val) == 0)
501                         printk("P2 ROM board type: 0x%08x\n", val);
502                 else
503                         printk("Could not read board type\n");
504                 if (netxen_rom_fast_read(adapter, NETXEN_BOARDNUM, &val) == 0)
505                         printk("P2 ROM board  num: 0x%08x\n", val);
506                 else
507                         printk("Could not read board number\n");
508                 if (netxen_rom_fast_read(adapter, NETXEN_CHIPNUM, &val) == 0)
509                         printk("P2 ROM chip   num: 0x%08x\n", val);
510                 else
511                         printk("Could not read chip number\n");
512         }
513
514         if (netxen_rom_fast_read(adapter, 0, &n) == 0
515             && (n & NETXEN_ROM_FIRST_BARRIER)) {
516                 n &= ~NETXEN_ROM_ROUNDUP;
517                 if (n < NETXEN_ROM_FOUND_INIT) {
518                         if (verbose)
519                                 printk("%s: %d CRB init values found"
520                                        " in ROM.\n", netxen_nic_driver_name, n);
521                 } else {
522                         printk("%s:n=0x%x Error! NetXen card flash not"
523                                " initialized.\n", __FUNCTION__, n);
524                         return -EIO;
525                 }
526                 buf = kcalloc(n, sizeof(struct crb_addr_pair), GFP_KERNEL);
527                 if (buf == NULL) {
528                         printk("%s: netxen_pinit_from_rom: Unable to calloc "
529                                "memory.\n", netxen_nic_driver_name);
530                         return -ENOMEM;
531                 }
532                 for (i = 0; i < n; i++) {
533                         if (netxen_rom_fast_read(adapter, 8 * i + 4, &val) != 0
534                             || netxen_rom_fast_read(adapter, 8 * i + 8,
535                                                     &addr) != 0)
536                                 return -EIO;
537
538                         buf[i].addr = addr;
539                         buf[i].data = val;
540
541                         if (verbose)
542                                 printk("%s: PCI:     0x%08x == 0x%08x\n",
543                                        netxen_nic_driver_name, (unsigned int)
544                                        netxen_decode_crb_addr((unsigned long)
545                                                               addr), val);
546                 }
547                 for (i = 0; i < n; i++) {
548
549                         off =
550                             netxen_decode_crb_addr((unsigned long)buf[i].addr) +
551                             NETXEN_PCI_CRBSPACE;
552                         /* skipping cold reboot MAGIC */
553                         if (off == NETXEN_CAM_RAM(0x1fc))
554                                 continue;
555
556                         /* After writing this register, HW needs time for CRB */
557                         /* to quiet down (else crb_window returns 0xffffffff) */
558                         if (off == NETXEN_ROMUSB_GLB_SW_RESET) {
559                                 init_delay = 1;
560                                 /* hold xdma in reset also */
561                                 buf[i].data = NETXEN_NIC_XDMA_RESET;
562                         }
563
564                         if (ADDR_IN_WINDOW1(off)) {
565                                 writel(buf[i].data,
566                                        NETXEN_CRB_NORMALIZE(adapter, off));
567                         } else {
568                                 netxen_nic_pci_change_crbwindow(adapter, 0);
569                                 writel(buf[i].data,
570                                        pci_base_offset(adapter, off));
571
572                                 netxen_nic_pci_change_crbwindow(adapter, 1);
573                         }
574                         if (init_delay == 1) {
575                                 ssleep(1);
576                                 init_delay = 0;
577                         }
578                         msleep(1);
579                 }
580                 kfree(buf);
581
582                 /* disable_peg_cache_all */
583
584                 /* unreset_net_cache */
585                 netxen_nic_hw_read_wx(adapter, NETXEN_ROMUSB_GLB_SW_RESET, &val,
586                                       4);
587                 netxen_crb_writelit_adapter(adapter, NETXEN_ROMUSB_GLB_SW_RESET,
588                                             (val & 0xffffff0f));
589                 /* p2dn replyCount */
590                 netxen_crb_writelit_adapter(adapter,
591                                             NETXEN_CRB_PEG_NET_D + 0xec, 0x1e);
592                 /* disable_peg_cache 0 */
593                 netxen_crb_writelit_adapter(adapter,
594                                             NETXEN_CRB_PEG_NET_D + 0x4c, 8);
595                 /* disable_peg_cache 1 */
596                 netxen_crb_writelit_adapter(adapter,
597                                             NETXEN_CRB_PEG_NET_I + 0x4c, 8);
598
599                 /* peg_clr_all */
600
601                 /* peg_clr 0 */
602                 netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_0 + 0x8,
603                                             0);
604                 netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_0 + 0xc,
605                                             0);
606                 /* peg_clr 1 */
607                 netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_1 + 0x8,
608                                             0);
609                 netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_1 + 0xc,
610                                             0);
611                 /* peg_clr 2 */
612                 netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_2 + 0x8,
613                                             0);
614                 netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_2 + 0xc,
615                                             0);
616                 /* peg_clr 3 */
617                 netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_3 + 0x8,
618                                             0);
619                 netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_3 + 0xc,
620                                             0);
621         }
622         return 0;
623 }
624
625 void netxen_phantom_init(struct netxen_adapter *adapter, int pegtune_val)
626 {
627         u32 val = 0;
628         int loops = 0;
629
630         if (!pegtune_val) {
631                 while (val != PHAN_INITIALIZE_COMPLETE && loops < 200000) {
632                         udelay(100);
633                         schedule();
634                         val =
635                             readl(NETXEN_CRB_NORMALIZE
636                                   (adapter, CRB_CMDPEG_STATE));
637                         loops++;
638                 }
639                 if (val != PHAN_INITIALIZE_COMPLETE)
640                         printk("WARNING: Initial boot wait loop failed...\n");
641         }
642 }
643
644 int netxen_nic_rx_has_work(struct netxen_adapter *adapter)
645 {
646         int ctx;
647
648         for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) {
649                 struct netxen_recv_context *recv_ctx =
650                     &(adapter->recv_ctx[ctx]);
651                 u32 consumer;
652                 struct status_desc *desc_head;
653                 struct status_desc *desc;
654
655                 consumer = recv_ctx->status_rx_consumer;
656                 desc_head = recv_ctx->rcv_status_desc_head;
657                 desc = &desc_head[consumer];
658
659                 if (((le16_to_cpu(desc->owner)) & STATUS_OWNER_HOST))
660                         return 1;
661         }
662
663         return 0;
664 }
665
666 static inline int netxen_nic_check_temp(struct netxen_adapter *adapter)
667 {
668         int port_num;
669         struct netxen_port *port;
670         struct net_device *netdev;
671         uint32_t temp, temp_state, temp_val;
672         int rv = 0;
673
674         temp = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_TEMP_STATE));
675
676         temp_state = nx_get_temp_state(temp);
677         temp_val = nx_get_temp_val(temp);
678
679         if (temp_state == NX_TEMP_PANIC) {
680                 printk(KERN_ALERT
681                        "%s: Device temperature %d degrees C exceeds"
682                        " maximum allowed. Hardware has been shut down.\n",
683                        netxen_nic_driver_name, temp_val);
684                 for (port_num = 0; port_num < adapter->ahw.max_ports;
685                      port_num++) {
686                         port = adapter->port[port_num];
687                         netdev = port->netdev;
688
689                         netif_carrier_off(netdev);
690                         netif_stop_queue(netdev);
691                 }
692                 rv = 1;
693         } else if (temp_state == NX_TEMP_WARN) {
694                 if (adapter->temp == NX_TEMP_NORMAL) {
695                         printk(KERN_ALERT
696                                "%s: Device temperature %d degrees C "
697                                "exceeds operating range."
698                                " Immediate action needed.\n",
699                                netxen_nic_driver_name, temp_val);
700                 }
701         } else {
702                 if (adapter->temp == NX_TEMP_WARN) {
703                         printk(KERN_INFO
704                                "%s: Device temperature is now %d degrees C"
705                                " in normal range.\n", netxen_nic_driver_name,
706                                temp_val);
707                 }
708         }
709         adapter->temp = temp_state;
710         return rv;
711 }
712
713 void netxen_watchdog_task(struct work_struct *work)
714 {
715         int port_num;
716         struct netxen_port *port;
717         struct net_device *netdev;
718         struct netxen_adapter *adapter =
719                 container_of(work, struct netxen_adapter, watchdog_task);
720
721         if (netxen_nic_check_temp(adapter))
722                 return;
723
724         for (port_num = 0; port_num < adapter->ahw.max_ports; port_num++) {
725                 port = adapter->port[port_num];
726                 netdev = port->netdev;
727
728                 if ((netif_running(netdev)) && !netif_carrier_ok(netdev)) {
729                         printk(KERN_INFO "%s port %d, %s carrier is now ok\n",
730                                netxen_nic_driver_name, port_num, netdev->name);
731                         netif_carrier_on(netdev);
732                 }
733
734                 if (netif_queue_stopped(netdev))
735                         netif_wake_queue(netdev);
736         }
737
738         if (adapter->ops->handle_phy_intr)
739                 adapter->ops->handle_phy_intr(adapter);
740         mod_timer(&adapter->watchdog_timer, jiffies + 2 * HZ);
741 }
742
743 /*
744  * netxen_process_rcv() send the received packet to the protocol stack.
745  * and if the number of receives exceeds RX_BUFFERS_REFILL, then we
746  * invoke the routine to send more rx buffers to the Phantom...
747  */
748 void
749 netxen_process_rcv(struct netxen_adapter *adapter, int ctxid,
750                    struct status_desc *desc)
751 {
752         struct netxen_port *port = adapter->port[STATUS_DESC_PORT(desc)];
753         struct pci_dev *pdev = port->pdev;
754         struct net_device *netdev = port->netdev;
755         int index = le16_to_cpu(desc->reference_handle);
756         struct netxen_recv_context *recv_ctx = &(adapter->recv_ctx[ctxid]);
757         struct netxen_rx_buffer *buffer;
758         struct sk_buff *skb;
759         u32 length = le16_to_cpu(desc->total_length);
760         u32 desc_ctx;
761         struct netxen_rcv_desc_ctx *rcv_desc;
762         int ret;
763
764         desc_ctx = STATUS_DESC_TYPE(desc);
765         if (unlikely(desc_ctx >= NUM_RCV_DESC_RINGS)) {
766                 printk("%s: %s Bad Rcv descriptor ring\n",
767                        netxen_nic_driver_name, netdev->name);
768                 return;
769         }
770
771         rcv_desc = &recv_ctx->rcv_desc[desc_ctx];
772         buffer = &rcv_desc->rx_buf_arr[index];
773
774         pci_unmap_single(pdev, buffer->dma, rcv_desc->dma_size,
775                          PCI_DMA_FROMDEVICE);
776
777         skb = (struct sk_buff *)buffer->skb;
778
779         if (likely(STATUS_DESC_STATUS(desc) == STATUS_CKSUM_OK)) {
780                 port->stats.csummed++;
781                 skb->ip_summed = CHECKSUM_UNNECESSARY;
782         } else
783                 skb->ip_summed = CHECKSUM_NONE;
784         skb->dev = netdev;
785         skb_put(skb, length);
786         skb->protocol = eth_type_trans(skb, netdev);
787
788         ret = netif_receive_skb(skb);
789
790         /*
791          * RH: Do we need these stats on a regular basis. Can we get it from
792          * Linux stats.
793          */
794         switch (ret) {
795         case NET_RX_SUCCESS:
796                 port->stats.uphappy++;
797                 break;
798
799         case NET_RX_CN_LOW:
800                 port->stats.uplcong++;
801                 break;
802
803         case NET_RX_CN_MOD:
804                 port->stats.upmcong++;
805                 break;
806
807         case NET_RX_CN_HIGH:
808                 port->stats.uphcong++;
809                 break;
810
811         case NET_RX_DROP:
812                 port->stats.updropped++;
813                 break;
814
815         default:
816                 port->stats.updunno++;
817                 break;
818         }
819
820         netdev->last_rx = jiffies;
821
822         rcv_desc->rcv_free++;
823         rcv_desc->rcv_pending--;
824
825         /*
826          * We just consumed one buffer so post a buffer.
827          */
828         adapter->stats.post_called++;
829         buffer->skb = NULL;
830         buffer->state = NETXEN_BUFFER_FREE;
831
832         port->stats.no_rcv++;
833         port->stats.rxbytes += length;
834 }
835
836 /* Process Receive status ring */
837 u32 netxen_process_rcv_ring(struct netxen_adapter *adapter, int ctxid, int max)
838 {
839         struct netxen_recv_context *recv_ctx = &(adapter->recv_ctx[ctxid]);
840         struct status_desc *desc_head = recv_ctx->rcv_status_desc_head;
841         struct status_desc *desc;       /* used to read status desc here */
842         u32 consumer = recv_ctx->status_rx_consumer;
843         int count = 0, ring;
844
845         DPRINTK(INFO, "procesing receive\n");
846         /*
847          * we assume in this case that there is only one port and that is
848          * port #1...changes need to be done in firmware to indicate port
849          * number as part of the descriptor. This way we will be able to get
850          * the netdev which is associated with that device.
851          */
852         while (count < max) {
853                 desc = &desc_head[consumer];
854                 if (!((le16_to_cpu(desc->owner)) & STATUS_OWNER_HOST)) {
855                         DPRINTK(ERR, "desc %p ownedby %x\n", desc, desc->owner);
856                         break;
857                 }
858                 netxen_process_rcv(adapter, ctxid, desc);
859                 desc->owner = STATUS_OWNER_PHANTOM;
860                 consumer = (consumer + 1) & (adapter->max_rx_desc_count - 1);
861                 count++;
862         }
863         if (count) {
864                 for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) {
865                         netxen_post_rx_buffers(adapter, ctxid, ring);
866                 }
867         }
868
869         /* update the consumer index in phantom */
870         if (count) {
871                 adapter->stats.process_rcv++;
872                 recv_ctx->status_rx_consumer = consumer;
873
874                 /* Window = 1 */
875                 writel(consumer,
876                        NETXEN_CRB_NORMALIZE(adapter,
877                                             recv_crb_registers[ctxid].
878                                             crb_rcv_status_consumer));
879         }
880
881         return count;
882 }
883
884 /* Process Command status ring */
885 void netxen_process_cmd_ring(unsigned long data)
886 {
887         u32 last_consumer;
888         u32 consumer;
889         struct netxen_adapter *adapter = (struct netxen_adapter *)data;
890         int count = 0;
891         struct netxen_cmd_buffer *buffer;
892         struct netxen_port *port;       /* port #1 */
893         struct netxen_port *nport;
894         struct pci_dev *pdev;
895         struct netxen_skb_frag *frag;
896         u32 i;
897         struct sk_buff *skb = NULL;
898         int p;
899
900         spin_lock(&adapter->tx_lock);
901         last_consumer = adapter->last_cmd_consumer;
902         DPRINTK(INFO, "procesing xmit complete\n");
903         /* we assume in this case that there is only one port and that is
904          * port #1...changes need to be done in firmware to indicate port
905          * number as part of the descriptor. This way we will be able to get
906          * the netdev which is associated with that device.
907          */
908         consumer =
909             readl(NETXEN_CRB_NORMALIZE(adapter, CRB_CMD_CONSUMER_OFFSET));
910
911         if (last_consumer == consumer) {        /* Ring is empty    */
912                 DPRINTK(INFO, "last_consumer %d == consumer %d\n",
913                         last_consumer, consumer);
914                 spin_unlock(&adapter->tx_lock);
915                 return;
916         }
917
918         adapter->proc_cmd_buf_counter++;
919         adapter->stats.process_xmit++;
920         /*
921          * Not needed - does not seem to be used anywhere.
922          * adapter->cmd_consumer = consumer;
923          */
924         spin_unlock(&adapter->tx_lock);
925
926         while ((last_consumer != consumer) && (count < MAX_STATUS_HANDLE)) {
927                 buffer = &adapter->cmd_buf_arr[last_consumer];
928                 port = adapter->port[buffer->port];
929                 pdev = port->pdev;
930                 frag = &buffer->frag_array[0];
931                 skb = buffer->skb;
932                 if (skb && (cmpxchg(&buffer->skb, skb, 0) == skb)) {
933                         pci_unmap_single(pdev, frag->dma, frag->length,
934                                          PCI_DMA_TODEVICE);
935                         for (i = 1; i < buffer->frag_count; i++) {
936                                 DPRINTK(INFO, "getting fragment no %d\n", i);
937                                 frag++; /* Get the next frag */
938                                 pci_unmap_page(pdev, frag->dma, frag->length,
939                                                PCI_DMA_TODEVICE);
940                         }
941
942                         port->stats.skbfreed++;
943                         dev_kfree_skb_any(skb);
944                         skb = NULL;
945                 } else if (adapter->proc_cmd_buf_counter == 1) {
946                         port->stats.txnullskb++;
947                 }
948                 if (unlikely(netif_queue_stopped(port->netdev)
949                              && netif_carrier_ok(port->netdev))
950                     && ((jiffies - port->netdev->trans_start) >
951                         port->netdev->watchdog_timeo)) {
952                         schedule_work(&port->adapter->tx_timeout_task);
953                 }
954
955                 last_consumer = get_next_index(last_consumer,
956                                                adapter->max_tx_desc_count);
957                 count++;
958         }
959         adapter->stats.noxmitdone += count;
960
961         count = 0;
962         spin_lock(&adapter->tx_lock);
963         if ((--adapter->proc_cmd_buf_counter) == 0) {
964                 adapter->last_cmd_consumer = last_consumer;
965                 while ((adapter->last_cmd_consumer != consumer)
966                        && (count < MAX_STATUS_HANDLE)) {
967                         buffer =
968                             &adapter->cmd_buf_arr[adapter->last_cmd_consumer];
969                         count++;
970                         if (buffer->skb)
971                                 break;
972                         else
973                                 adapter->last_cmd_consumer =
974                                     get_next_index(adapter->last_cmd_consumer,
975                                                    adapter->max_tx_desc_count);
976                 }
977         }
978         if (count) {
979                 for (p = 0; p < adapter->ahw.max_ports; p++) {
980                         nport = adapter->port[p];
981                         if (netif_queue_stopped(nport->netdev)
982                             && (nport->flags & NETXEN_NETDEV_STATUS)) {
983                                 netif_wake_queue(nport->netdev);
984                                 nport->flags &= ~NETXEN_NETDEV_STATUS;
985                         }
986                 }
987         }
988
989         spin_unlock(&adapter->tx_lock);
990         DPRINTK(INFO, "last consumer is %d in %s\n", last_consumer,
991                 __FUNCTION__);
992 }
993
994 /*
995  * netxen_post_rx_buffers puts buffer in the Phantom memory
996  */
997 void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ctx, u32 ringid)
998 {
999         struct pci_dev *pdev = adapter->ahw.pdev;
1000         struct sk_buff *skb;
1001         struct netxen_recv_context *recv_ctx = &(adapter->recv_ctx[ctx]);
1002         struct netxen_rcv_desc_ctx *rcv_desc = NULL;
1003         struct netxen_recv_crb *crbarea = &recv_crb_registers[ctx];
1004         struct netxen_rcv_desc_crb *rcv_desc_crb = NULL;
1005         u32 producer;
1006         struct rcv_desc *pdesc;
1007         struct netxen_rx_buffer *buffer;
1008         int count = 0;
1009         int index = 0;
1010
1011         adapter->stats.post_called++;
1012         rcv_desc = &recv_ctx->rcv_desc[ringid];
1013         rcv_desc_crb = &crbarea->rcv_desc_crb[ringid];
1014
1015         producer = rcv_desc->producer;
1016         index = rcv_desc->begin_alloc;
1017         buffer = &rcv_desc->rx_buf_arr[index];
1018         /* We can start writing rx descriptors into the phantom memory. */
1019         while (buffer->state == NETXEN_BUFFER_FREE) {
1020                 skb = dev_alloc_skb(rcv_desc->skb_size);
1021                 if (unlikely(!skb)) {
1022                         /*
1023                          * We need to schedule the posting of buffers to the pegs.
1024                          */
1025                         rcv_desc->begin_alloc = index;
1026                         DPRINTK(ERR, "netxen_post_rx_buffers: "
1027                                 " allocated only %d buffers\n", count);
1028                         break;
1029                 }
1030                 count++;        /* now there should be no failure */
1031                 pdesc = &rcv_desc->desc_head[producer];
1032                 skb_reserve(skb, NET_IP_ALIGN);
1033                 /* 
1034                  * This will be setup when we receive the
1035                  * buffer after it has been filled
1036                  * skb->dev = netdev;
1037                  */
1038                 buffer->skb = skb;
1039                 buffer->state = NETXEN_BUFFER_BUSY;
1040                 buffer->dma = pci_map_single(pdev, skb->data,
1041                                              rcv_desc->dma_size,
1042                                              PCI_DMA_FROMDEVICE);
1043                 /* make a rcv descriptor  */
1044                 pdesc->reference_handle = le16_to_cpu(buffer->ref_handle);
1045                 pdesc->buffer_length = le16_to_cpu(rcv_desc->dma_size);
1046                 pdesc->addr_buffer = cpu_to_le64(buffer->dma);
1047                 DPRINTK(INFO, "done writing descripter\n");
1048                 producer =
1049                     get_next_index(producer, rcv_desc->max_rx_desc_count);
1050                 index = get_next_index(index, rcv_desc->max_rx_desc_count);
1051                 buffer = &rcv_desc->rx_buf_arr[index];
1052         }
1053
1054         /* if we did allocate buffers, then write the count to Phantom */
1055         if (count) {
1056                 rcv_desc->begin_alloc = index;
1057                 rcv_desc->rcv_pending += count;
1058                 adapter->stats.lastposted = count;
1059                 adapter->stats.posted += count;
1060                 rcv_desc->producer = producer;
1061                 if (rcv_desc->rcv_free >= 32) {
1062                         rcv_desc->rcv_free = 0;
1063                         /* Window = 1 */
1064                         writel((producer - 1) &
1065                                (rcv_desc->max_rx_desc_count - 1),
1066                                NETXEN_CRB_NORMALIZE(adapter,
1067                                                     rcv_desc_crb->
1068                                                     crb_rcv_producer_offset));
1069                         wmb();
1070                 }
1071         }
1072 }
1073
1074 int netxen_nic_tx_has_work(struct netxen_adapter *adapter)
1075 {
1076         if (find_diff_among(adapter->last_cmd_consumer,
1077                             adapter->cmd_producer,
1078                             adapter->max_tx_desc_count) > 0)
1079                 return 1;
1080
1081         return 0;
1082 }
1083
1084 int
1085 netxen_nic_fill_statistics(struct netxen_adapter *adapter,
1086                            struct netxen_port *port,
1087                            struct netxen_statistics *netxen_stats)
1088 {
1089         void __iomem *addr;
1090
1091         if (adapter->ahw.board_type == NETXEN_NIC_XGBE) {
1092                 netxen_nic_pci_change_crbwindow(adapter, 0);
1093                 NETXEN_NIC_LOCKED_READ_REG(NETXEN_NIU_XGE_TX_BYTE_CNT,
1094                                            &(netxen_stats->tx_bytes));
1095                 NETXEN_NIC_LOCKED_READ_REG(NETXEN_NIU_XGE_TX_FRAME_CNT,
1096                                            &(netxen_stats->tx_packets));
1097                 NETXEN_NIC_LOCKED_READ_REG(NETXEN_NIU_XGE_RX_BYTE_CNT,
1098                                            &(netxen_stats->rx_bytes));
1099                 NETXEN_NIC_LOCKED_READ_REG(NETXEN_NIU_XGE_RX_FRAME_CNT,
1100                                            &(netxen_stats->rx_packets));
1101                 NETXEN_NIC_LOCKED_READ_REG(NETXEN_NIU_XGE_AGGR_ERROR_CNT,
1102                                            &(netxen_stats->rx_errors));
1103                 NETXEN_NIC_LOCKED_READ_REG(NETXEN_NIU_XGE_CRC_ERROR_CNT,
1104                                            &(netxen_stats->rx_crc_errors));
1105                 NETXEN_NIC_LOCKED_READ_REG(NETXEN_NIU_XGE_OVERSIZE_FRAME_ERR,
1106                                            &(netxen_stats->
1107                                              rx_long_length_error));
1108                 NETXEN_NIC_LOCKED_READ_REG(NETXEN_NIU_XGE_UNDERSIZE_FRAME_ERR,
1109                                            &(netxen_stats->
1110                                              rx_short_length_error));
1111
1112                 netxen_nic_pci_change_crbwindow(adapter, 1);
1113         } else {
1114                 spin_lock_bh(&adapter->tx_lock);
1115                 netxen_stats->tx_bytes = port->stats.txbytes;
1116                 netxen_stats->tx_packets = port->stats.xmitedframes +
1117                     port->stats.xmitfinished;
1118                 netxen_stats->rx_bytes = port->stats.rxbytes;
1119                 netxen_stats->rx_packets = port->stats.no_rcv;
1120                 netxen_stats->rx_errors = port->stats.rcvdbadskb;
1121                 netxen_stats->tx_errors = port->stats.nocmddescriptor;
1122                 netxen_stats->rx_short_length_error = port->stats.uplcong;
1123                 netxen_stats->rx_long_length_error = port->stats.uphcong;
1124                 netxen_stats->rx_crc_errors = 0;
1125                 netxen_stats->rx_mac_errors = 0;
1126                 spin_unlock_bh(&adapter->tx_lock);
1127         }
1128         return 0;
1129 }
1130
1131 void netxen_nic_clear_stats(struct netxen_adapter *adapter)
1132 {
1133         struct netxen_port *port;
1134         int port_num;
1135
1136         memset(&adapter->stats, 0, sizeof(adapter->stats));
1137         for (port_num = 0; port_num < adapter->ahw.max_ports; port_num++) {
1138                 port = adapter->port[port_num];
1139                 memset(&port->stats, 0, sizeof(port->stats));
1140         }
1141 }
1142
1143 int
1144 netxen_nic_clear_statistics(struct netxen_adapter *adapter,
1145                             struct netxen_port *port)
1146 {
1147         int data = 0;
1148
1149         netxen_nic_pci_change_crbwindow(adapter, 0);
1150
1151         netxen_nic_locked_write_reg(adapter, NETXEN_NIU_XGE_TX_BYTE_CNT, &data);
1152         netxen_nic_locked_write_reg(adapter, NETXEN_NIU_XGE_TX_FRAME_CNT,
1153                                     &data);
1154         netxen_nic_locked_write_reg(adapter, NETXEN_NIU_XGE_RX_BYTE_CNT, &data);
1155         netxen_nic_locked_write_reg(adapter, NETXEN_NIU_XGE_RX_FRAME_CNT,
1156                                     &data);
1157         netxen_nic_locked_write_reg(adapter, NETXEN_NIU_XGE_AGGR_ERROR_CNT,
1158                                     &data);
1159         netxen_nic_locked_write_reg(adapter, NETXEN_NIU_XGE_CRC_ERROR_CNT,
1160                                     &data);
1161         netxen_nic_locked_write_reg(adapter, NETXEN_NIU_XGE_OVERSIZE_FRAME_ERR,
1162                                     &data);
1163         netxen_nic_locked_write_reg(adapter, NETXEN_NIU_XGE_UNDERSIZE_FRAME_ERR,
1164                                     &data);
1165
1166         netxen_nic_pci_change_crbwindow(adapter, 1);
1167         netxen_nic_clear_stats(adapter);
1168         return 0;
1169 }
1170
1171 int
1172 netxen_nic_do_ioctl(struct netxen_adapter *adapter, void *u_data,
1173                     struct netxen_port *port)
1174 {
1175         struct netxen_nic_ioctl_data data;
1176         struct netxen_nic_ioctl_data *up_data;
1177         int retval = 0;
1178         struct netxen_statistics netxen_stats;
1179
1180         up_data = (void *)u_data;
1181
1182         DPRINTK(INFO, "doing ioctl for %p\n", adapter);
1183         if (copy_from_user(&data, (void __user *)up_data, sizeof(data))) {
1184                 /* evil user tried to crash the kernel */
1185                 DPRINTK(ERR, "bad copy from userland: %d\n", (int)sizeof(data));
1186                 retval = -EFAULT;
1187                 goto error_out;
1188         }
1189
1190         /* Shouldn't access beyond legal limits of  "char u[64];" member */
1191         if (!data.ptr && (data.size > sizeof(data.u))) {
1192                 /* evil user tried to crash the kernel */
1193                 DPRINTK(ERR, "bad size: %d\n", data.size);
1194                 retval = -EFAULT;
1195                 goto error_out;
1196         }
1197
1198         switch (data.cmd) {
1199         case netxen_nic_cmd_pci_read:
1200                 if ((retval = netxen_nic_hw_read_wx(adapter, data.off,
1201                                                     &(data.u), data.size)))
1202                         goto error_out;
1203                 if (copy_to_user
1204                     ((void __user *)&(up_data->u), &(data.u), data.size)) {
1205                         DPRINTK(ERR, "bad copy to userland: %d\n",
1206                                 (int)sizeof(data));
1207                         retval = -EFAULT;
1208                         goto error_out;
1209                 }
1210                 data.rv = 0;
1211                 break;
1212
1213         case netxen_nic_cmd_pci_write:
1214                 data.rv = netxen_nic_hw_write_wx(adapter, data.off, &(data.u),
1215                                                  data.size);
1216                 break;
1217
1218         case netxen_nic_cmd_pci_config_read:
1219                 switch (data.size) {
1220                 case 1:
1221                         data.rv = pci_read_config_byte(adapter->ahw.pdev,
1222                                                        data.off,
1223                                                        (char *)&(data.u));
1224                         break;
1225                 case 2:
1226                         data.rv = pci_read_config_word(adapter->ahw.pdev,
1227                                                        data.off,
1228                                                        (short *)&(data.u));
1229                         break;
1230                 case 4:
1231                         data.rv = pci_read_config_dword(adapter->ahw.pdev,
1232                                                         data.off,
1233                                                         (u32 *) & (data.u));
1234                         break;
1235                 }
1236                 if (copy_to_user
1237                     ((void __user *)&(up_data->u), &(data.u), data.size)) {
1238                         DPRINTK(ERR, "bad copy to userland: %d\n",
1239                                 (int)sizeof(data));
1240                         retval = -EFAULT;
1241                         goto error_out;
1242                 }
1243                 break;
1244
1245         case netxen_nic_cmd_pci_config_write:
1246                 switch (data.size) {
1247                 case 1:
1248                         data.rv = pci_write_config_byte(adapter->ahw.pdev,
1249                                                         data.off,
1250                                                         *(char *)&(data.u));
1251                         break;
1252                 case 2:
1253                         data.rv = pci_write_config_word(adapter->ahw.pdev,
1254                                                         data.off,
1255                                                         *(short *)&(data.u));
1256                         break;
1257                 case 4:
1258                         data.rv = pci_write_config_dword(adapter->ahw.pdev,
1259                                                          data.off,
1260                                                          *(u32 *) & (data.u));
1261                         break;
1262                 }
1263                 break;
1264
1265         case netxen_nic_cmd_get_stats:
1266                 data.rv =
1267                     netxen_nic_fill_statistics(adapter, port, &netxen_stats);
1268                 if (copy_to_user
1269                     ((void __user *)(up_data->ptr), (void *)&netxen_stats,
1270                      sizeof(struct netxen_statistics))) {
1271                         DPRINTK(ERR, "bad copy to userland: %d\n",
1272                                 (int)sizeof(netxen_stats));
1273                         retval = -EFAULT;
1274                         goto error_out;
1275                 }
1276                 up_data->rv = data.rv;
1277                 break;
1278
1279         case netxen_nic_cmd_clear_stats:
1280                 data.rv = netxen_nic_clear_statistics(adapter, port);
1281                 up_data->rv = data.rv;
1282                 break;
1283
1284         case netxen_nic_cmd_get_version:
1285                 if (copy_to_user
1286                     ((void __user *)&(up_data->u), NETXEN_NIC_LINUX_VERSIONID,
1287                      sizeof(NETXEN_NIC_LINUX_VERSIONID))) {
1288                         DPRINTK(ERR, "bad copy to userland: %d\n",
1289                                 (int)sizeof(data));
1290                         retval = -EFAULT;
1291                         goto error_out;
1292                 }
1293                 break;
1294
1295         default:
1296                 DPRINTK(INFO, "bad command %d for %p\n", data.cmd, adapter);
1297                 retval = -EOPNOTSUPP;
1298                 goto error_out;
1299         }
1300         put_user(data.rv, (u16 __user *) (&(up_data->rv)));
1301         DPRINTK(INFO, "done ioctl for %p well.\n", adapter);
1302
1303       error_out:
1304         return retval;
1305 }