ethtool: fix drvinfo strings set in drivers
[pandora-kernel.git] / drivers / staging / ft1000 / ft1000-pcmcia / ft1000_hw.c
1 /*---------------------------------------------------------------------------
2    FT1000 driver for Flarion Flash OFDM NIC Device
3
4    Copyright (C) 2002 Flarion Technologies, All rights reserved.
5    Copyright (C) 2006 Patrik Ostrihon, All rights reserved.
6    Copyright (C) 2006 ProWeb Consulting, a.s, All rights reserved.
7
8    This program is free software; you can redistribute it and/or modify it
9    under the terms of the GNU General Public License as published by the Free
10    Software Foundation; either version 2 of the License, or (at your option) any
11    later version. This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
14    more details. You should have received a copy of the GNU General Public
15    License along with this program; if not, write to the
16    Free Software Foundation, Inc., 59 Temple Place -
17    Suite 330, Boston, MA 02111-1307, USA.
18 -----------------------------------------------------------------------------*/
19
20 #include <linux/kernel.h>
21 #include <linux/module.h>
22 #include <linux/proc_fs.h>
23
24 #include <linux/sched.h>
25 #include <linux/ptrace.h>
26 #include <linux/slab.h>
27 #include <linux/string.h>
28 #include <linux/timer.h>
29 #include <linux/interrupt.h>
30 #include <linux/in.h>
31 #include <asm/io.h>
32 #include <asm/bitops.h>
33
34 #include <linux/netdevice.h>
35 #include <linux/etherdevice.h>
36 #include <linux/skbuff.h>
37 #include <linux/if_arp.h>
38 #include <linux/ioport.h>
39 #include <linux/wait.h>
40 #include <linux/vmalloc.h>
41
42 #include <linux/firmware.h>
43 #include <linux/ethtool.h>
44
45 #include <pcmcia/cistpl.h>
46 #include <pcmcia/cisreg.h>
47 #include <pcmcia/ds.h>
48
49 #ifdef FT_DEBUG
50 #define DEBUG(n, args...) printk(KERN_DEBUG args);
51 #else
52 #define DEBUG(n, args...)
53 #endif
54
55 #include <linux/delay.h>
56 #include "ft1000.h"
57
58 static const struct firmware *fw_entry;
59
60 static void ft1000_hbchk(u_long data);
61 static struct timer_list poll_timer = {
62       .function = ft1000_hbchk
63 };
64
65 static u16 cmdbuffer[1024];
66 static u8 tempbuffer[1600];
67 static u8 ft1000_card_present = 0;
68 static u8 flarion_ft1000_cnt = 0;
69
70 static irqreturn_t ft1000_interrupt(int irq, void *dev_id);
71 static void ft1000_enable_interrupts(struct net_device *dev);
72 static void ft1000_disable_interrupts(struct net_device *dev);
73
74 /* new kernel */
75 MODULE_AUTHOR("");
76 MODULE_DESCRIPTION
77     ("Support for Flarion Flash OFDM NIC Device. Support for PCMCIA when used with ft1000_cs.");
78 MODULE_LICENSE("GPL");
79 MODULE_SUPPORTED_DEVICE("FT1000");
80
81 #define MAX_RCV_LOOP   100
82
83 //---------------------------------------------------------------------------
84 //
85 // Function:   ft1000_read_fifo_len
86 // Description: This function will read the ASIC Uplink FIFO status register
87 //             which will return the number of bytes remaining in the Uplink FIFO.
88 //             Sixteen bytes are subtracted to make sure that the ASIC does not
89 //             reach its threshold.
90 // Input:
91 //     dev    - network device structure
92 // Output:
93 //     value  - number of bytes available in the ASIC Uplink FIFO.
94 //
95 //---------------------------------------------------------------------------
96 static inline u16 ft1000_read_fifo_len(struct net_device *dev)
97 {
98         struct ft1000_info *info = netdev_priv(dev);
99
100         if (info->AsicID == ELECTRABUZZ_ID)
101                 return (ft1000_read_reg(dev, FT1000_REG_UFIFO_STAT) - 16);
102         else
103                 return (ft1000_read_reg(dev, FT1000_REG_MAG_UFSR) - 16);
104 }
105
106 //---------------------------------------------------------------------------
107 //
108 // Function:   ft1000_read_dpram
109 // Description: This function will read the specific area of dpram
110 //             (Electrabuzz ASIC only)
111 // Input:
112 //     dev    - device structure
113 //     offset - index of dpram
114 // Output:
115 //     value  - value of dpram
116 //
117 //---------------------------------------------------------------------------
118 u16 ft1000_read_dpram(struct net_device *dev, int offset)
119 {
120         struct ft1000_info *info = netdev_priv(dev);
121         unsigned long flags;
122         u16 data;
123
124         // Provide mutual exclusive access while reading ASIC registers.
125         spin_lock_irqsave(&info->dpram_lock, flags);
126         ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR, offset);
127         data = ft1000_read_reg(dev, FT1000_REG_DPRAM_DATA);
128         spin_unlock_irqrestore(&info->dpram_lock, flags);
129
130         return (data);
131 }
132
133 //---------------------------------------------------------------------------
134 //
135 // Function:   ft1000_write_dpram
136 // Description: This function will write to a specific area of dpram
137 //             (Electrabuzz ASIC only)
138 // Input:
139 //     dev    - device structure
140 //     offset - index of dpram
141 //     value  - value to write
142 // Output:
143 //     none.
144 //
145 //---------------------------------------------------------------------------
146 static inline void ft1000_write_dpram(struct net_device *dev,
147                                           int offset, u16 value)
148 {
149         struct ft1000_info *info = netdev_priv(dev);
150         unsigned long flags;
151
152         // Provide mutual exclusive access while reading ASIC registers.
153         spin_lock_irqsave(&info->dpram_lock, flags);
154         ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR, offset);
155         ft1000_write_reg(dev, FT1000_REG_DPRAM_DATA, value);
156         spin_unlock_irqrestore(&info->dpram_lock, flags);
157 }
158
159 //---------------------------------------------------------------------------
160 //
161 // Function:   ft1000_read_dpram_mag_16
162 // Description: This function will read the specific area of dpram
163 //             (Magnemite ASIC only)
164 // Input:
165 //     dev    - device structure
166 //     offset - index of dpram
167 // Output:
168 //     value  - value of dpram
169 //
170 //---------------------------------------------------------------------------
171 u16 ft1000_read_dpram_mag_16(struct net_device *dev, int offset, int Index)
172 {
173         struct ft1000_info *info = netdev_priv(dev);
174         unsigned long flags;
175         u16 data;
176
177         // Provide mutual exclusive access while reading ASIC registers.
178         spin_lock_irqsave(&info->dpram_lock, flags);
179         ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR, offset);
180         // check if we want to read upper or lower 32-bit word
181         if (Index) {
182                 data = ft1000_read_reg(dev, FT1000_REG_MAG_DPDATAL);
183         } else {
184                 data = ft1000_read_reg(dev, FT1000_REG_MAG_DPDATAH);
185         }
186         spin_unlock_irqrestore(&info->dpram_lock, flags);
187
188         return (data);
189 }
190
191 //---------------------------------------------------------------------------
192 //
193 // Function:   ft1000_write_dpram_mag_16
194 // Description: This function will write to a specific area of dpram
195 //             (Magnemite ASIC only)
196 // Input:
197 //     dev    - device structure
198 //     offset - index of dpram
199 //     value  - value to write
200 // Output:
201 //     none.
202 //
203 //---------------------------------------------------------------------------
204 static inline void ft1000_write_dpram_mag_16(struct net_device *dev,
205                                                  int offset, u16 value, int Index)
206 {
207         struct ft1000_info *info = netdev_priv(dev);
208         unsigned long flags;
209
210         // Provide mutual exclusive access while reading ASIC registers.
211         spin_lock_irqsave(&info->dpram_lock, flags);
212         ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR, offset);
213         if (Index) {
214                 ft1000_write_reg(dev, FT1000_REG_MAG_DPDATAL, value);
215         } else {
216                 ft1000_write_reg(dev, FT1000_REG_MAG_DPDATAH, value);
217         }
218         spin_unlock_irqrestore(&info->dpram_lock, flags);
219 }
220
221 //---------------------------------------------------------------------------
222 //
223 // Function:   ft1000_read_dpram_mag_32
224 // Description: This function will read the specific area of dpram
225 //             (Magnemite ASIC only)
226 // Input:
227 //     dev    - device structure
228 //     offset - index of dpram
229 // Output:
230 //     value  - value of dpram
231 //
232 //---------------------------------------------------------------------------
233 u32 ft1000_read_dpram_mag_32(struct net_device *dev, int offset)
234 {
235         struct ft1000_info *info = netdev_priv(dev);
236         unsigned long flags;
237         u32 data;
238
239         // Provide mutual exclusive access while reading ASIC registers.
240         spin_lock_irqsave(&info->dpram_lock, flags);
241         ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR, offset);
242         data = inl(dev->base_addr + FT1000_REG_MAG_DPDATAL);
243         spin_unlock_irqrestore(&info->dpram_lock, flags);
244
245         return (data);
246 }
247
248 //---------------------------------------------------------------------------
249 //
250 // Function:   ft1000_write_dpram_mag_32
251 // Description: This function will write to a specific area of dpram
252 //             (Magnemite ASIC only)
253 // Input:
254 //     dev    - device structure
255 //     offset - index of dpram
256 //     value  - value to write
257 // Output:
258 //     none.
259 //
260 //---------------------------------------------------------------------------
261 void ft1000_write_dpram_mag_32(struct net_device *dev, int offset, u32 value)
262 {
263         struct ft1000_info *info = netdev_priv(dev);
264         unsigned long flags;
265
266         // Provide mutual exclusive access while reading ASIC registers.
267         spin_lock_irqsave(&info->dpram_lock, flags);
268         ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR, offset);
269         outl(value, dev->base_addr + FT1000_REG_MAG_DPDATAL);
270         spin_unlock_irqrestore(&info->dpram_lock, flags);
271 }
272
273 //---------------------------------------------------------------------------
274 //
275 // Function:   ft1000_enable_interrupts
276 // Description: This function will enable interrupts base on the current interrupt mask.
277 // Input:
278 //     dev    - device structure
279 // Output:
280 //     None.
281 //
282 //---------------------------------------------------------------------------
283 static void ft1000_enable_interrupts(struct net_device *dev)
284 {
285         u16 tempword;
286
287         DEBUG(1, "ft1000_hw:ft1000_enable_interrupts()\n");
288         ft1000_write_reg(dev, FT1000_REG_SUP_IMASK, ISR_DEFAULT_MASK);
289         tempword = ft1000_read_reg(dev, FT1000_REG_SUP_IMASK);
290         DEBUG(1,
291                   "ft1000_hw:ft1000_enable_interrupts:current interrupt enable mask = 0x%x\n",
292                   tempword);
293 }
294
295 //---------------------------------------------------------------------------
296 //
297 // Function:   ft1000_disable_interrupts
298 // Description: This function will disable all interrupts.
299 // Input:
300 //     dev    - device structure
301 // Output:
302 //     None.
303 //
304 //---------------------------------------------------------------------------
305 static void ft1000_disable_interrupts(struct net_device *dev)
306 {
307         u16 tempword;
308
309         DEBUG(1, "ft1000_hw: ft1000_disable_interrupts()\n");
310         ft1000_write_reg(dev, FT1000_REG_SUP_IMASK, ISR_MASK_ALL);
311         tempword = ft1000_read_reg(dev, FT1000_REG_SUP_IMASK);
312         DEBUG(1,
313                   "ft1000_hw:ft1000_disable_interrupts:current interrupt enable mask = 0x%x\n",
314                   tempword);
315 }
316
317 //---------------------------------------------------------------------------
318 //
319 // Function:   ft1000_reset_asic
320 // Description: This function will call the Card Service function to reset the
321 //             ASIC.
322 // Input:
323 //     dev    - device structure
324 // Output:
325 //     none
326 //
327 //---------------------------------------------------------------------------
328 static void ft1000_reset_asic(struct net_device *dev)
329 {
330         struct ft1000_info *info = netdev_priv(dev);
331         u16 tempword;
332
333         DEBUG(1, "ft1000_hw:ft1000_reset_asic called\n");
334
335         (*info->ft1000_reset) (info->link);
336
337         // Let's use the register provided by the Magnemite ASIC to reset the
338         // ASIC and DSP.
339         if (info->AsicID == MAGNEMITE_ID) {
340                 ft1000_write_reg(dev, FT1000_REG_RESET,
341                                  (DSP_RESET_BIT | ASIC_RESET_BIT));
342         }
343         mdelay(1);
344         if (info->AsicID == ELECTRABUZZ_ID) {
345                 // set watermark to -1 in order to not generate an interrupt
346                 ft1000_write_reg(dev, FT1000_REG_WATERMARK, 0xffff);
347         } else {
348                 // set watermark to -1 in order to not generate an interrupt
349                 ft1000_write_reg(dev, FT1000_REG_MAG_WATERMARK, 0xffff);
350         }
351         // clear interrupts
352         tempword = ft1000_read_reg(dev, FT1000_REG_SUP_ISR);
353         DEBUG(1, "ft1000_hw: interrupt status register = 0x%x\n", tempword);
354         ft1000_write_reg(dev, FT1000_REG_SUP_ISR, tempword);
355         tempword = ft1000_read_reg(dev, FT1000_REG_SUP_ISR);
356         DEBUG(1, "ft1000_hw: interrupt status register = 0x%x\n", tempword);
357
358 }
359
360 //---------------------------------------------------------------------------
361 //
362 // Function:   ft1000_reset_card
363 // Description: This function will reset the card
364 // Input:
365 //     dev    - device structure
366 // Output:
367 //     status - false (card reset fail)
368 //              true  (card reset successful)
369 //
370 //---------------------------------------------------------------------------
371 static int ft1000_reset_card(struct net_device *dev)
372 {
373         struct ft1000_info *info = netdev_priv(dev);
374         u16 tempword;
375         int i;
376         unsigned long flags;
377         struct prov_record *ptr;
378
379         DEBUG(1, "ft1000_hw:ft1000_reset_card called.....\n");
380
381         info->CardReady = 0;
382         info->ProgConStat = 0;
383         info->squeseqnum = 0;
384         ft1000_disable_interrupts(dev);
385
386 //      del_timer(&poll_timer);
387
388         // Make sure we free any memory reserve for provisioning
389         while (list_empty(&info->prov_list) == 0) {
390                 DEBUG(0,
391                           "ft1000_hw:ft1000_reset_card:deleting provisioning record\n");
392                 ptr = list_entry(info->prov_list.next, struct prov_record, list);
393                 list_del(&ptr->list);
394                 kfree(ptr->pprov_data);
395                 kfree(ptr);
396         }
397
398         if (info->AsicID == ELECTRABUZZ_ID) {
399                 DEBUG(1, "ft1000_hw:ft1000_reset_card:resetting DSP\n");
400                 ft1000_write_reg(dev, FT1000_REG_RESET, DSP_RESET_BIT);
401         } else {
402                 DEBUG(1,
403                           "ft1000_hw:ft1000_reset_card:resetting ASIC and DSP\n");
404                 ft1000_write_reg(dev, FT1000_REG_RESET,
405                                  (DSP_RESET_BIT | ASIC_RESET_BIT));
406         }
407
408         // Copy DSP session record into info block if this is not a coldstart
409         if (ft1000_card_present == 1) {
410                 spin_lock_irqsave(&info->dpram_lock, flags);
411                 if (info->AsicID == ELECTRABUZZ_ID) {
412                         ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR,
413                                          FT1000_DPRAM_RX_BASE);
414                         for (i = 0; i < MAX_DSP_SESS_REC; i++) {
415                                 info->DSPSess.Rec[i] =
416                                         ft1000_read_reg(dev,
417                                                         FT1000_REG_DPRAM_DATA);
418                         }
419                 } else {
420                         ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR,
421                                          FT1000_DPRAM_MAG_RX_BASE);
422                         for (i = 0; i < MAX_DSP_SESS_REC / 2; i++) {
423                                 info->DSPSess.MagRec[i] =
424                                         inl(dev->base_addr + FT1000_REG_MAG_DPDATA);
425                         }
426                 }
427                 spin_unlock_irqrestore(&info->dpram_lock, flags);
428         }
429
430         DEBUG(1, "ft1000_hw:ft1000_reset_card:resetting ASIC\n");
431         mdelay(10);
432         //reset ASIC
433         ft1000_reset_asic(dev);
434
435         DEBUG(1, "ft1000_hw:ft1000_reset_card:downloading dsp image\n");
436
437         if (info->AsicID == MAGNEMITE_ID) {
438                 // Put dsp in reset and take ASIC out of reset
439                 DEBUG(0,
440                           "ft1000_hw:ft1000_reset_card:Put DSP in reset and take ASIC out of reset\n");
441                 ft1000_write_reg(dev, FT1000_REG_RESET, DSP_RESET_BIT);
442
443                 // Setting MAGNEMITE ASIC to big endian mode
444                 ft1000_write_reg(dev, FT1000_REG_SUP_CTRL, HOST_INTF_BE);
445                 // Download bootloader
446                 card_bootload(dev);
447
448                 // Take DSP out of reset
449                 ft1000_write_reg(dev, FT1000_REG_RESET, 0);
450                 // FLARION_DSP_ACTIVE;
451                 mdelay(10);
452                 DEBUG(0, "ft1000_hw:ft1000_reset_card:Take DSP out of reset\n");
453
454                 // Wait for 0xfefe indicating dsp ready before starting download
455                 for (i = 0; i < 50; i++) {
456                         tempword =
457                                 ft1000_read_dpram_mag_16(dev, FT1000_MAG_DPRAM_FEFE,
458                                                          FT1000_MAG_DPRAM_FEFE_INDX);
459                         if (tempword == 0xfefe) {
460                                 break;
461                         }
462                         mdelay(20);
463                 }
464
465                 if (i == 50) {
466                         DEBUG(0,
467                                   "ft1000_hw:ft1000_reset_card:No FEFE detected from DSP\n");
468                         return false;
469                 }
470
471         } else {
472                 // Take DSP out of reset
473                 ft1000_write_reg(dev, FT1000_REG_RESET, ~DSP_RESET_BIT);
474                 mdelay(10);
475         }
476
477         if (card_download(dev, fw_entry->data, fw_entry->size)) {
478                 DEBUG(1, "card download unsuccessful\n");
479                 return false;
480         } else {
481                 DEBUG(1, "card download successful\n");
482         }
483
484         mdelay(10);
485
486         if (info->AsicID == ELECTRABUZZ_ID) {
487                 // Need to initialize the FIFO length counter to zero in order to sync up
488                 // with the DSP
489                 info->fifo_cnt = 0;
490                 ft1000_write_dpram(dev, FT1000_FIFO_LEN, info->fifo_cnt);
491                 // Initialize DSP heartbeat area to ho
492                 ft1000_write_dpram(dev, FT1000_HI_HO, ho);
493                 tempword = ft1000_read_dpram(dev, FT1000_HI_HO);
494                 DEBUG(1, "ft1000_hw:ft1000_reset_asic:hi_ho value = 0x%x\n",
495                           tempword);
496         } else {
497                 // Initialize DSP heartbeat area to ho
498                 ft1000_write_dpram_mag_16(dev, FT1000_MAG_HI_HO, ho_mag,
499                                           FT1000_MAG_HI_HO_INDX);
500                 tempword =
501                         ft1000_read_dpram_mag_16(dev, FT1000_MAG_HI_HO,
502                                                  FT1000_MAG_HI_HO_INDX);
503                 DEBUG(1, "ft1000_hw:ft1000_reset_card:hi_ho value = 0x%x\n",
504                           tempword);
505         }
506
507         info->CardReady = 1;
508         ft1000_enable_interrupts(dev);
509
510         /* Schedule heartbeat process to run every 2 seconds */
511 //      poll_timer.expires = jiffies + (2*HZ);
512 //      poll_timer.data = (u_long)dev;
513 //      add_timer(&poll_timer);
514
515         return true;
516
517 }
518
519 //---------------------------------------------------------------------------
520 //
521 // Function:   ft1000_chkcard
522 // Description: This function will check if the device is presently available on
523 //             the system.
524 // Input:
525 //     dev    - device structure
526 // Output:
527 //     status - false (device is not present)
528 //              true  (device is present)
529 //
530 //---------------------------------------------------------------------------
531 static int ft1000_chkcard(struct net_device *dev)
532 {
533         u16 tempword;
534
535         // Mask register is used to check for device presence since it is never
536         // set to zero.
537         tempword = ft1000_read_reg(dev, FT1000_REG_SUP_IMASK);
538         if (tempword == 0) {
539                 DEBUG(1,
540                           "ft1000_hw:ft1000_chkcard: IMASK = 0 Card not detected\n");
541                 return false;
542         }
543         // The system will return the value of 0xffff for the version register
544         // if the device is not present.
545         tempword = ft1000_read_reg(dev, FT1000_REG_ASIC_ID);
546         if (tempword == 0xffff) {
547                 DEBUG(1,
548                           "ft1000_hw:ft1000_chkcard: Version = 0xffff Card not detected\n");
549                 return false;
550         }
551         return true;
552 }
553
554
555 //---------------------------------------------------------------------------
556 //
557 // Function:   ft1000_hbchk
558 // Description: This function will perform the heart beat check of the DSP as
559 //             well as the ASIC.
560 // Input:
561 //     dev    - device structure
562 // Output:
563 //     none
564 //
565 //---------------------------------------------------------------------------
566 static void ft1000_hbchk(u_long data)
567 {
568         struct net_device *dev = (struct net_device *)data;
569
570         struct ft1000_info *info;
571         u16 tempword;
572
573         info = netdev_priv(dev);
574
575         if (info->CardReady == 1) {
576                 // Perform dsp heartbeat check
577                 if (info->AsicID == ELECTRABUZZ_ID) {
578                         tempword = ft1000_read_dpram(dev, FT1000_HI_HO);
579                 } else {
580                         tempword =
581                                 ntohs(ft1000_read_dpram_mag_16
582                                   (dev, FT1000_MAG_HI_HO,
583                                    FT1000_MAG_HI_HO_INDX));
584                 }
585                 DEBUG(1, "ft1000_hw:ft1000_hbchk:hi_ho value = 0x%x\n",
586                           tempword);
587                 // Let's perform another check if ho is not detected
588                 if (tempword != ho) {
589                         if (info->AsicID == ELECTRABUZZ_ID) {
590                                 tempword = ft1000_read_dpram(dev, FT1000_HI_HO);
591                         }
592                         else {
593                                 tempword = ntohs(ft1000_read_dpram_mag_16(dev, FT1000_MAG_HI_HO, FT1000_MAG_HI_HO_INDX));
594                         }
595                 }
596                 if (tempword != ho) {
597                         printk(KERN_INFO
598                                    "ft1000: heartbeat failed - no ho detected\n");
599                         if (info->AsicID == ELECTRABUZZ_ID) {
600                                 info->DSP_TIME[0] =
601                                         ft1000_read_dpram(dev, FT1000_DSP_TIMER0);
602                                 info->DSP_TIME[1] =
603                                         ft1000_read_dpram(dev, FT1000_DSP_TIMER1);
604                                 info->DSP_TIME[2] =
605                                         ft1000_read_dpram(dev, FT1000_DSP_TIMER2);
606                                 info->DSP_TIME[3] =
607                                         ft1000_read_dpram(dev, FT1000_DSP_TIMER3);
608                         } else {
609                                 info->DSP_TIME[0] =
610                                         ft1000_read_dpram_mag_16(dev,
611                                                                  FT1000_MAG_DSP_TIMER0,
612                                                                  FT1000_MAG_DSP_TIMER0_INDX);
613                                 info->DSP_TIME[1] =
614                                         ft1000_read_dpram_mag_16(dev,
615                                                                  FT1000_MAG_DSP_TIMER1,
616                                                                  FT1000_MAG_DSP_TIMER1_INDX);
617                                 info->DSP_TIME[2] =
618                                         ft1000_read_dpram_mag_16(dev,
619                                                                  FT1000_MAG_DSP_TIMER2,
620                                                                  FT1000_MAG_DSP_TIMER2_INDX);
621                                 info->DSP_TIME[3] =
622                                         ft1000_read_dpram_mag_16(dev,
623                                                                  FT1000_MAG_DSP_TIMER3,
624                                                                  FT1000_MAG_DSP_TIMER3_INDX);
625                         }
626                         info->DrvErrNum = DSP_HB_INFO;
627                         if (ft1000_reset_card(dev) == 0) {
628                                 printk(KERN_INFO
629                                            "ft1000: Hardware Failure Detected - PC Card disabled\n");
630                                 info->ProgConStat = 0xff;
631                                 return;
632                         }
633                         /* Schedule this module to run every 2 seconds */
634                         poll_timer.expires = jiffies + (2*HZ);
635                         poll_timer.data = (u_long)dev;
636                         add_timer(&poll_timer);
637                         return;
638                 }
639
640                 tempword = ft1000_read_reg(dev, FT1000_REG_DOORBELL);
641                 // Let's check doorbell again if fail
642                 if (tempword & FT1000_DB_HB) {
643                         tempword = ft1000_read_reg(dev, FT1000_REG_DOORBELL);
644                 }
645                 if (tempword & FT1000_DB_HB) {
646                         printk(KERN_INFO
647                                    "ft1000: heartbeat doorbell not clear by firmware\n");
648                         if (info->AsicID == ELECTRABUZZ_ID) {
649                                 info->DSP_TIME[0] =
650                                         ft1000_read_dpram(dev, FT1000_DSP_TIMER0);
651                                 info->DSP_TIME[1] =
652                                         ft1000_read_dpram(dev, FT1000_DSP_TIMER1);
653                                 info->DSP_TIME[2] =
654                                         ft1000_read_dpram(dev, FT1000_DSP_TIMER2);
655                                 info->DSP_TIME[3] =
656                                         ft1000_read_dpram(dev, FT1000_DSP_TIMER3);
657                         } else {
658                                 info->DSP_TIME[0] =
659                                         ft1000_read_dpram_mag_16(dev,
660                                                                  FT1000_MAG_DSP_TIMER0,
661                                                                  FT1000_MAG_DSP_TIMER0_INDX);
662                                 info->DSP_TIME[1] =
663                                         ft1000_read_dpram_mag_16(dev,
664                                                                  FT1000_MAG_DSP_TIMER1,
665                                                                  FT1000_MAG_DSP_TIMER1_INDX);
666                                 info->DSP_TIME[2] =
667                                         ft1000_read_dpram_mag_16(dev,
668                                                                  FT1000_MAG_DSP_TIMER2,
669                                                                  FT1000_MAG_DSP_TIMER2_INDX);
670                                 info->DSP_TIME[3] =
671                                         ft1000_read_dpram_mag_16(dev,
672                                                                  FT1000_MAG_DSP_TIMER3,
673                                                                  FT1000_MAG_DSP_TIMER3_INDX);
674                         }
675                         info->DrvErrNum = DSP_HB_INFO;
676                         if (ft1000_reset_card(dev) == 0) {
677                                 printk(KERN_INFO
678                                            "ft1000: Hardware Failure Detected - PC Card disabled\n");
679                                 info->ProgConStat = 0xff;
680                                 return;
681                         }
682                         /* Schedule this module to run every 2 seconds */
683                         poll_timer.expires = jiffies + (2*HZ);
684                         poll_timer.data = (u_long)dev;
685                         add_timer(&poll_timer);
686                         return;
687                 }
688                 // Set dedicated area to hi and ring appropriate doorbell according
689                 // to hi/ho heartbeat protocol
690                 if (info->AsicID == ELECTRABUZZ_ID) {
691                         ft1000_write_dpram(dev, FT1000_HI_HO, hi);
692                 } else {
693                         ft1000_write_dpram_mag_16(dev, FT1000_MAG_HI_HO, hi_mag,
694                                                   FT1000_MAG_HI_HO_INDX);
695                 }
696
697                 if (info->AsicID == ELECTRABUZZ_ID) {
698                         tempword = ft1000_read_dpram(dev, FT1000_HI_HO);
699                 } else {
700                         tempword =
701                                 ntohs(ft1000_read_dpram_mag_16
702                                   (dev, FT1000_MAG_HI_HO,
703                                    FT1000_MAG_HI_HO_INDX));
704                 }
705         // Let's write hi again if fail
706                 if (tempword != hi) {
707                         if (info->AsicID == ELECTRABUZZ_ID) {
708                                 ft1000_write_dpram(dev, FT1000_HI_HO, hi);
709                         }
710                         else {
711                                 ft1000_write_dpram_mag_16(dev, FT1000_MAG_HI_HO, hi_mag, FT1000_MAG_HI_HO_INDX);
712                         }
713
714                         if (info->AsicID == ELECTRABUZZ_ID) {
715                                 tempword = ft1000_read_dpram(dev, FT1000_HI_HO);
716                         }
717                         else {
718                                 tempword = ntohs(ft1000_read_dpram_mag_16(dev, FT1000_MAG_HI_HO, FT1000_MAG_HI_HO_INDX));
719                         }
720
721                 }
722
723                 if (tempword != hi) {
724                         printk(KERN_INFO
725                                    "ft1000: heartbeat failed - cannot write hi into DPRAM\n");
726                         if (info->AsicID == ELECTRABUZZ_ID) {
727                                 info->DSP_TIME[0] =
728                                         ft1000_read_dpram(dev, FT1000_DSP_TIMER0);
729                                 info->DSP_TIME[1] =
730                                         ft1000_read_dpram(dev, FT1000_DSP_TIMER1);
731                                 info->DSP_TIME[2] =
732                                         ft1000_read_dpram(dev, FT1000_DSP_TIMER2);
733                                 info->DSP_TIME[3] =
734                                         ft1000_read_dpram(dev, FT1000_DSP_TIMER3);
735                         } else {
736                                 info->DSP_TIME[0] =
737                                         ft1000_read_dpram_mag_16(dev,
738                                                                  FT1000_MAG_DSP_TIMER0,
739                                                                  FT1000_MAG_DSP_TIMER0_INDX);
740                                 info->DSP_TIME[1] =
741                                         ft1000_read_dpram_mag_16(dev,
742                                                                  FT1000_MAG_DSP_TIMER1,
743                                                                  FT1000_MAG_DSP_TIMER1_INDX);
744                                 info->DSP_TIME[2] =
745                                         ft1000_read_dpram_mag_16(dev,
746                                                                  FT1000_MAG_DSP_TIMER2,
747                                                                  FT1000_MAG_DSP_TIMER2_INDX);
748                                 info->DSP_TIME[3] =
749                                         ft1000_read_dpram_mag_16(dev,
750                                                                  FT1000_MAG_DSP_TIMER3,
751                                                                  FT1000_MAG_DSP_TIMER3_INDX);
752                         }
753                         info->DrvErrNum = DSP_HB_INFO;
754                         if (ft1000_reset_card(dev) == 0) {
755                                 printk(KERN_INFO
756                                            "ft1000: Hardware Failure Detected - PC Card disabled\n");
757                                 info->ProgConStat = 0xff;
758                                 return;
759                         }
760                         /* Schedule this module to run every 2 seconds */
761                         poll_timer.expires = jiffies + (2*HZ);
762                         poll_timer.data = (u_long)dev;
763                         add_timer(&poll_timer);
764                         return;
765                 }
766                 ft1000_write_reg(dev, FT1000_REG_DOORBELL, FT1000_DB_HB);
767
768         }
769
770         /* Schedule this module to run every 2 seconds */
771         poll_timer.expires = jiffies + (2 * HZ);
772         poll_timer.data = (u_long) dev;
773         add_timer(&poll_timer);
774 }
775
776 //---------------------------------------------------------------------------
777 //
778 // Function:   ft1000_send_cmd
779 // Description:
780 // Input:
781 // Output:
782 //
783 //---------------------------------------------------------------------------
784 static void ft1000_send_cmd (struct net_device *dev, u16 *ptempbuffer, int size, u16 qtype)
785 {
786         struct ft1000_info *info = netdev_priv(dev);
787         int i;
788         u16 tempword;
789         unsigned long flags;
790
791         size += sizeof(struct pseudo_hdr);
792         // check for odd byte and increment to 16-bit word align value
793         if ((size & 0x0001)) {
794                 size++;
795         }
796         DEBUG(1, "FT1000:ft1000_send_cmd:total length = %d\n", size);
797         DEBUG(1, "FT1000:ft1000_send_cmd:length = %d\n", ntohs(*ptempbuffer));
798         // put message into slow queue area
799         // All messages are in the form total_len + pseudo header + message body
800         spin_lock_irqsave(&info->dpram_lock, flags);
801
802     // Make sure SLOWQ doorbell is clear
803     tempword = ft1000_read_reg(dev, FT1000_REG_DOORBELL);
804     i=0;
805     while (tempword & FT1000_DB_DPRAM_TX) {
806         mdelay(10);
807         i++;
808         if (i==10) {
809             spin_unlock_irqrestore(&info->dpram_lock, flags);
810             return;
811         }
812         tempword = ft1000_read_reg(dev, FT1000_REG_DOORBELL);
813     }
814
815         if (info->AsicID == ELECTRABUZZ_ID) {
816                 ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR,
817                                  FT1000_DPRAM_TX_BASE);
818                 // Write total length to dpram
819                 ft1000_write_reg(dev, FT1000_REG_DPRAM_DATA, size);
820                 // Write pseudo header and messgae body
821                 for (i = 0; i < (size >> 1); i++) {
822                         DEBUG(1, "FT1000:ft1000_send_cmd:data %d = 0x%x\n", i,
823                                   *ptempbuffer);
824                         tempword = htons(*ptempbuffer++);
825                         ft1000_write_reg(dev, FT1000_REG_DPRAM_DATA, tempword);
826                 }
827         } else {
828                 ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR,
829                                  FT1000_DPRAM_MAG_TX_BASE);
830                 // Write total length to dpram
831                 ft1000_write_reg(dev, FT1000_REG_MAG_DPDATAH, htons(size));
832                 // Write pseudo header and messgae body
833                 ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR,
834                                  FT1000_DPRAM_MAG_TX_BASE + 1);
835                 for (i = 0; i < (size >> 2); i++) {
836                         DEBUG(1, "FT1000:ft1000_send_cmd:data = 0x%x\n",
837                                   *ptempbuffer);
838                         outw(*ptempbuffer++,
839                                  dev->base_addr + FT1000_REG_MAG_DPDATAL);
840                         DEBUG(1, "FT1000:ft1000_send_cmd:data = 0x%x\n",
841                                   *ptempbuffer);
842                         outw(*ptempbuffer++,
843                                  dev->base_addr + FT1000_REG_MAG_DPDATAH);
844                 }
845                 DEBUG(1, "FT1000:ft1000_send_cmd:data = 0x%x\n", *ptempbuffer);
846                 outw(*ptempbuffer++, dev->base_addr + FT1000_REG_MAG_DPDATAL);
847                 DEBUG(1, "FT1000:ft1000_send_cmd:data = 0x%x\n", *ptempbuffer);
848                 outw(*ptempbuffer++, dev->base_addr + FT1000_REG_MAG_DPDATAH);
849         }
850         spin_unlock_irqrestore(&info->dpram_lock, flags);
851
852         // ring doorbell to notify DSP that we have a message ready
853         ft1000_write_reg(dev, FT1000_REG_DOORBELL, FT1000_DB_DPRAM_TX);
854 }
855
856 //---------------------------------------------------------------------------
857 //
858 // Function:   ft1000_receive_cmd
859 // Description: This function will read a message from the dpram area.
860 // Input:
861 //    dev - network device structure
862 //    pbuffer - caller supply address to buffer
863 //    pnxtph - pointer to next pseudo header
864 // Output:
865 //   Status = 0 (unsuccessful)
866 //          = 1 (successful)
867 //
868 //---------------------------------------------------------------------------
869 static bool ft1000_receive_cmd(struct net_device *dev, u16 *pbuffer,
870                                 int maxsz, u16 *pnxtph)
871 {
872         struct ft1000_info *info = netdev_priv(dev);
873         u16 size;
874         u16 *ppseudohdr;
875         int i;
876         u16 tempword;
877         unsigned long flags;
878
879         if (info->AsicID == ELECTRABUZZ_ID) {
880                 size = ( ft1000_read_dpram(dev, *pnxtph) ) + sizeof(struct pseudo_hdr);
881         } else {
882                 size =
883                         ntohs(ft1000_read_dpram_mag_16
884                           (dev, FT1000_MAG_PH_LEN,
885                            FT1000_MAG_PH_LEN_INDX)) + sizeof(struct pseudo_hdr);
886         }
887         if (size > maxsz) {
888                 DEBUG(1,
889                           "FT1000:ft1000_receive_cmd:Invalid command length = %d\n",
890                           size);
891                 return false;
892         } else {
893                 ppseudohdr = (u16 *) pbuffer;
894                 spin_lock_irqsave(&info->dpram_lock, flags);
895                 if (info->AsicID == ELECTRABUZZ_ID) {
896                         ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR,
897                                          FT1000_DPRAM_RX_BASE + 2);
898                         for (i = 0; i <= (size >> 1); i++) {
899                                 tempword =
900                                         ft1000_read_reg(dev, FT1000_REG_DPRAM_DATA);
901                                 *pbuffer++ = ntohs(tempword);
902                         }
903                 } else {
904                         ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR,
905                                          FT1000_DPRAM_MAG_RX_BASE);
906                         *pbuffer = inw(dev->base_addr + FT1000_REG_MAG_DPDATAH);
907                         DEBUG(1, "ft1000_hw:received data = 0x%x\n", *pbuffer);
908                         pbuffer++;
909                         ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR,
910                                          FT1000_DPRAM_MAG_RX_BASE + 1);
911                         for (i = 0; i <= (size >> 2); i++) {
912                                 *pbuffer =
913                                         inw(dev->base_addr +
914                                         FT1000_REG_MAG_DPDATAL);
915                                 pbuffer++;
916                                 *pbuffer =
917                                         inw(dev->base_addr +
918                                         FT1000_REG_MAG_DPDATAH);
919                                 pbuffer++;
920                         }
921                         //copy odd aligned word
922                         *pbuffer = inw(dev->base_addr + FT1000_REG_MAG_DPDATAL);
923                         DEBUG(1, "ft1000_hw:received data = 0x%x\n", *pbuffer);
924                         pbuffer++;
925                         *pbuffer = inw(dev->base_addr + FT1000_REG_MAG_DPDATAH);
926                         DEBUG(1, "ft1000_hw:received data = 0x%x\n", *pbuffer);
927                         pbuffer++;
928                 }
929                 if (size & 0x0001) {
930                         //copy odd byte from fifo
931                         tempword = ft1000_read_reg(dev, FT1000_REG_DPRAM_DATA);
932                         *pbuffer = ntohs(tempword);
933                 }
934                 spin_unlock_irqrestore(&info->dpram_lock, flags);
935
936                 // Check if pseudo header checksum is good
937                 // Calculate pseudo header checksum
938                 tempword = *ppseudohdr++;
939                 for (i = 1; i < 7; i++) {
940                         tempword ^= *ppseudohdr++;
941                 }
942                 if ((tempword != *ppseudohdr)) {
943                         DEBUG(1,
944                                   "FT1000:ft1000_receive_cmd:Pseudo header checksum mismatch\n");
945                         // Drop this message
946                         return false;
947                 }
948                 return true;
949         }
950 }
951
952 //---------------------------------------------------------------------------
953 //
954 // Function:   ft1000_proc_drvmsg
955 // Description: This function will process the various driver messages.
956 // Input:
957 //     dev    - device structure
958 //     pnxtph - pointer to next pseudo header
959 // Output:
960 //     none
961 //
962 //---------------------------------------------------------------------------
963 static void ft1000_proc_drvmsg(struct net_device *dev)
964 {
965         struct ft1000_info *info = netdev_priv(dev);
966         u16 msgtype;
967         u16 tempword;
968         struct media_msg *pmediamsg;
969         struct dsp_init_msg *pdspinitmsg;
970         struct drv_msg *pdrvmsg;
971         u16 len;
972         u16 i;
973         struct prov_record *ptr;
974         struct pseudo_hdr *ppseudo_hdr;
975         u16 *pmsg;
976         struct timeval tv;
977         union {
978                 u8 byte[2];
979                 u16 wrd;
980         } convert;
981
982     if (info->AsicID == ELECTRABUZZ_ID) {
983         tempword = FT1000_DPRAM_RX_BASE+2;
984     }
985     else {
986         tempword = FT1000_DPRAM_MAG_RX_BASE;
987     }
988     if ( ft1000_receive_cmd(dev, &cmdbuffer[0], MAX_CMD_SQSIZE, &tempword) ) {
989
990                 // Get the message type which is total_len + PSEUDO header + msgtype + message body
991                 pdrvmsg = (struct drv_msg *) & cmdbuffer[0];
992                 msgtype = ntohs(pdrvmsg->type);
993                 DEBUG(1, "Command message type = 0x%x\n", msgtype);
994                 switch (msgtype) {
995                 case DSP_PROVISION:
996                         DEBUG(0,
997                                   "Got a provisioning request message from DSP\n");
998                         mdelay(25);
999                         while (list_empty(&info->prov_list) == 0) {
1000                                 DEBUG(0, "Sending a provisioning message\n");
1001                                 // Make sure SLOWQ doorbell is clear
1002                                 tempword =
1003                                         ft1000_read_reg(dev, FT1000_REG_DOORBELL);
1004                                 i = 0;
1005                                 while (tempword & FT1000_DB_DPRAM_TX) {
1006                                         mdelay(5);
1007                                         i++;
1008                                         if (i == 10) {
1009                                                 break;
1010                                         }
1011                                 }
1012                                 ptr =
1013                                         list_entry(info->prov_list.next,
1014                                                    struct prov_record, list);
1015                                 len = *(u16 *) ptr->pprov_data;
1016                                 len = htons(len);
1017
1018                                 pmsg = (u16 *) ptr->pprov_data;
1019                                 ppseudo_hdr = (struct pseudo_hdr *) pmsg;
1020                                 // Insert slow queue sequence number
1021                                 ppseudo_hdr->seq_num = info->squeseqnum++;
1022                                 ppseudo_hdr->portsrc = 0;
1023                                 // Calculate new checksum
1024                                 ppseudo_hdr->checksum = *pmsg++;
1025                                 DEBUG(1, "checksum = 0x%x\n",
1026                                           ppseudo_hdr->checksum);
1027                                 for (i = 1; i < 7; i++) {
1028                                         ppseudo_hdr->checksum ^= *pmsg++;
1029                                         DEBUG(1, "checksum = 0x%x\n",
1030                                                   ppseudo_hdr->checksum);
1031                                 }
1032
1033                                 ft1000_send_cmd (dev, (u16 *)ptr->pprov_data, len, SLOWQ_TYPE);
1034                                 list_del(&ptr->list);
1035                                 kfree(ptr->pprov_data);
1036                                 kfree(ptr);
1037                         }
1038                         // Indicate adapter is ready to take application messages after all
1039                         // provisioning messages are sent
1040                         info->CardReady = 1;
1041                         break;
1042                 case MEDIA_STATE:
1043                         pmediamsg = (struct media_msg *) & cmdbuffer[0];
1044                         if (info->ProgConStat != 0xFF) {
1045                         if (pmediamsg->state) {
1046                                 DEBUG(1, "Media is up\n");
1047                                 if (info->mediastate == 0) {
1048                                         netif_carrier_on(dev);
1049                                         netif_wake_queue(dev);
1050                                         info->mediastate = 1;
1051                                         do_gettimeofday(&tv);
1052                                         info->ConTm = tv.tv_sec;
1053                                 }
1054                         } else {
1055                                 DEBUG(1, "Media is down\n");
1056                                 if (info->mediastate == 1) {
1057                                         info->mediastate = 0;
1058                                         netif_carrier_off(dev);
1059                                         netif_stop_queue(dev);
1060                                         info->ConTm = 0;
1061                                 }
1062                         }
1063             }
1064             else {
1065                 DEBUG(1,"Media is down\n");
1066                 if (info->mediastate == 1) {
1067                     info->mediastate = 0;
1068                     netif_carrier_off(dev);
1069                     netif_stop_queue(dev);
1070                     info->ConTm = 0;
1071                 }
1072             }
1073                         break;
1074                 case DSP_INIT_MSG:
1075                         pdspinitmsg = (struct dsp_init_msg *) & cmdbuffer[0];
1076                         memcpy(info->DspVer, pdspinitmsg->DspVer, DSPVERSZ);
1077                         DEBUG(1, "DSPVER = 0x%2x 0x%2x 0x%2x 0x%2x\n",
1078                                   info->DspVer[0], info->DspVer[1], info->DspVer[2],
1079                                    info->DspVer[3]);
1080                         memcpy(info->HwSerNum, pdspinitmsg->HwSerNum,
1081                                    HWSERNUMSZ);
1082                         memcpy(info->Sku, pdspinitmsg->Sku, SKUSZ);
1083                         memcpy(info->eui64, pdspinitmsg->eui64, EUISZ);
1084                         dev->dev_addr[0] = info->eui64[0];
1085                         dev->dev_addr[1] = info->eui64[1];
1086                         dev->dev_addr[2] = info->eui64[2];
1087                         dev->dev_addr[3] = info->eui64[5];
1088                         dev->dev_addr[4] = info->eui64[6];
1089                         dev->dev_addr[5] = info->eui64[7];
1090
1091                         if (ntohs(pdspinitmsg->length) ==
1092                                 (sizeof(struct dsp_init_msg) - 20)) {
1093                                 memcpy(info->ProductMode,
1094                                            pdspinitmsg->ProductMode, MODESZ);
1095                                 memcpy(info->RfCalVer, pdspinitmsg->RfCalVer,
1096                                            CALVERSZ);
1097                                 memcpy(info->RfCalDate, pdspinitmsg->RfCalDate,
1098                                            CALDATESZ);
1099                                 DEBUG(1, "RFCalVer = 0x%2x 0x%2x\n",
1100                                           info->RfCalVer[0], info->RfCalVer[1]);
1101                         }
1102
1103                         break ;
1104                 case DSP_STORE_INFO:
1105                         DEBUG(1, "FT1000:drivermsg:Got DSP_STORE_INFO\n");
1106                         tempword = ntohs(pdrvmsg->length);
1107                         info->DSPInfoBlklen = tempword;
1108                         if (tempword < (MAX_DSP_SESS_REC - 4)) {
1109                                 pmsg = (u16 *) & pdrvmsg->data[0];
1110                                 for (i = 0; i < ((tempword + 1) / 2); i++) {
1111                                         DEBUG(1,
1112                                                   "FT1000:drivermsg:dsp info data = 0x%x\n",
1113                                                   *pmsg);
1114                                         info->DSPInfoBlk[i + 10] = *pmsg++;
1115                                 }
1116                         }
1117                         break;
1118                 case DSP_GET_INFO:
1119                         DEBUG(1, "FT1000:drivermsg:Got DSP_GET_INFO\n");
1120                         // copy dsp info block to dsp
1121                         // allow any outstanding ioctl to finish
1122                         mdelay(10);
1123                         tempword = ft1000_read_reg(dev, FT1000_REG_DOORBELL);
1124                         if (tempword & FT1000_DB_DPRAM_TX) {
1125                                 mdelay(10);
1126                                 tempword =
1127                                         ft1000_read_reg(dev, FT1000_REG_DOORBELL);
1128                                 if (tempword & FT1000_DB_DPRAM_TX) {
1129                                         mdelay(10);
1130                                 }
1131                         }
1132
1133                         if ((tempword & FT1000_DB_DPRAM_TX) == 0) {
1134                                 // Put message into Slow Queue
1135                                 // Form Pseudo header
1136                                 pmsg = (u16 *) info->DSPInfoBlk;
1137                                 ppseudo_hdr = (struct pseudo_hdr *) pmsg;
1138                                 ppseudo_hdr->length =
1139                                         htons(info->DSPInfoBlklen + 4);
1140                                 ppseudo_hdr->source = 0x10;
1141                                 ppseudo_hdr->destination = 0x20;
1142                                 ppseudo_hdr->portdest = 0;
1143                                 ppseudo_hdr->portsrc = 0;
1144                                 ppseudo_hdr->sh_str_id = 0;
1145                                 ppseudo_hdr->control = 0;
1146                                 ppseudo_hdr->rsvd1 = 0;
1147                                 ppseudo_hdr->rsvd2 = 0;
1148                                 ppseudo_hdr->qos_class = 0;
1149                                 // Insert slow queue sequence number
1150                                 ppseudo_hdr->seq_num = info->squeseqnum++;
1151                                 // Insert application id
1152                                 ppseudo_hdr->portsrc = 0;
1153                                 // Calculate new checksum
1154                                 ppseudo_hdr->checksum = *pmsg++;
1155                                 for (i = 1; i < 7; i++) {
1156                                         ppseudo_hdr->checksum ^= *pmsg++;
1157                                 }
1158                                 info->DSPInfoBlk[8] = 0x7200;
1159                                 info->DSPInfoBlk[9] =
1160                                         htons(info->DSPInfoBlklen);
1161                                 ft1000_send_cmd (dev, (u16 *)info->DSPInfoBlk, (u16)(info->DSPInfoBlklen+4), 0);
1162                         }
1163
1164                         break;
1165                 case GET_DRV_ERR_RPT_MSG:
1166                         DEBUG(1, "FT1000:drivermsg:Got GET_DRV_ERR_RPT_MSG\n");
1167                         // copy driver error message to dsp
1168                         // allow any outstanding ioctl to finish
1169                         mdelay(10);
1170                         tempword = ft1000_read_reg(dev, FT1000_REG_DOORBELL);
1171                         if (tempword & FT1000_DB_DPRAM_TX) {
1172                                 mdelay(10);
1173                                 tempword =
1174                                         ft1000_read_reg(dev, FT1000_REG_DOORBELL);
1175                                 if (tempword & FT1000_DB_DPRAM_TX) {
1176                                         mdelay(10);
1177                                 }
1178                         }
1179
1180                         if ((tempword & FT1000_DB_DPRAM_TX) == 0) {
1181                                 // Put message into Slow Queue
1182                                 // Form Pseudo header
1183                                 pmsg = (u16 *) & tempbuffer[0];
1184                                 ppseudo_hdr = (struct pseudo_hdr *) pmsg;
1185                                 ppseudo_hdr->length = htons(0x0012);
1186                                 ppseudo_hdr->source = 0x10;
1187                                 ppseudo_hdr->destination = 0x20;
1188                                 ppseudo_hdr->portdest = 0;
1189                                 ppseudo_hdr->portsrc = 0;
1190                                 ppseudo_hdr->sh_str_id = 0;
1191                                 ppseudo_hdr->control = 0;
1192                                 ppseudo_hdr->rsvd1 = 0;
1193                                 ppseudo_hdr->rsvd2 = 0;
1194                                 ppseudo_hdr->qos_class = 0;
1195                                 // Insert slow queue sequence number
1196                                 ppseudo_hdr->seq_num = info->squeseqnum++;
1197                                 // Insert application id
1198                                 ppseudo_hdr->portsrc = 0;
1199                                 // Calculate new checksum
1200                 ppseudo_hdr->checksum = *pmsg++;
1201                 for (i=1; i<7; i++) {
1202                     ppseudo_hdr->checksum ^= *pmsg++;
1203                 }
1204                                 pmsg = (u16 *) & tempbuffer[16];
1205                                 *pmsg++ = htons(RSP_DRV_ERR_RPT_MSG);
1206                                 *pmsg++ = htons(0x000e);
1207                                 *pmsg++ = htons(info->DSP_TIME[0]);
1208                                 *pmsg++ = htons(info->DSP_TIME[1]);
1209                                 *pmsg++ = htons(info->DSP_TIME[2]);
1210                                 *pmsg++ = htons(info->DSP_TIME[3]);
1211                                 convert.byte[0] = info->DspVer[0];
1212                                 convert.byte[1] = info->DspVer[1];
1213                                 *pmsg++ = convert.wrd;
1214                                 convert.byte[0] = info->DspVer[2];
1215                                 convert.byte[1] = info->DspVer[3];
1216                                 *pmsg++ = convert.wrd;
1217                                 *pmsg++ = htons(info->DrvErrNum);
1218
1219                                 ft1000_send_cmd (dev, (u16 *)&tempbuffer[0], (u16)(0x0012), 0);
1220                                 info->DrvErrNum = 0;
1221                         }
1222
1223                         break;
1224                 default:
1225                         break;
1226                 }
1227         }
1228 }
1229
1230 //---------------------------------------------------------------------------
1231 //
1232 // Function:   ft1000_parse_dpram_msg
1233 // Description: This function will parse the message received from the DSP
1234 //             via the DPRAM interface.
1235 // Input:
1236 //     dev    - device structure
1237 // Output:
1238 //     status - FAILURE
1239 //              SUCCESS
1240 //
1241 //---------------------------------------------------------------------------
1242 static int ft1000_parse_dpram_msg(struct net_device *dev)
1243 {
1244         struct ft1000_info *info = netdev_priv(dev);
1245         u16 doorbell;
1246         u16 portid;
1247         u16 nxtph;
1248         u16 total_len;
1249         int i = 0;
1250         int cnt;
1251         unsigned long flags;
1252
1253         doorbell = ft1000_read_reg(dev, FT1000_REG_DOORBELL);
1254         DEBUG(1, "Doorbell = 0x%x\n", doorbell);
1255
1256         if (doorbell & FT1000_ASIC_RESET_REQ) {
1257                 // Copy DSP session record from info block
1258                 spin_lock_irqsave(&info->dpram_lock, flags);
1259                 if (info->AsicID == ELECTRABUZZ_ID) {
1260                         ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR,
1261                                          FT1000_DPRAM_RX_BASE);
1262                         for (i = 0; i < MAX_DSP_SESS_REC; i++) {
1263                                 ft1000_write_reg(dev, FT1000_REG_DPRAM_DATA,
1264                                                  info->DSPSess.Rec[i]);
1265                         }
1266                 } else {
1267                         ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR,
1268                                          FT1000_DPRAM_MAG_RX_BASE);
1269                         for (i = 0; i < MAX_DSP_SESS_REC / 2; i++) {
1270                                 outl(info->DSPSess.MagRec[i],
1271                                          dev->base_addr + FT1000_REG_MAG_DPDATA);
1272                         }
1273                 }
1274                 spin_unlock_irqrestore(&info->dpram_lock, flags);
1275
1276                 // clear ASIC RESET request
1277                 ft1000_write_reg(dev, FT1000_REG_DOORBELL,
1278                                  FT1000_ASIC_RESET_REQ);
1279                 DEBUG(1, "Got an ASIC RESET Request\n");
1280                 ft1000_write_reg(dev, FT1000_REG_DOORBELL,
1281                                  FT1000_ASIC_RESET_DSP);
1282
1283                 if (info->AsicID == MAGNEMITE_ID) {
1284                         // Setting MAGNEMITE ASIC to big endian mode
1285                         ft1000_write_reg(dev, FT1000_REG_SUP_CTRL,
1286                                          HOST_INTF_BE);
1287                 }
1288         }
1289
1290         if (doorbell & FT1000_DSP_ASIC_RESET) {
1291                 DEBUG(0,
1292                           "FT1000:ft1000_parse_dpram_msg: Got a dsp ASIC reset message\n");
1293                 ft1000_write_reg(dev, FT1000_REG_DOORBELL,
1294                                  FT1000_DSP_ASIC_RESET);
1295                 udelay(200);
1296                 return SUCCESS;
1297         }
1298
1299         if (doorbell & FT1000_DB_DPRAM_RX) {
1300                 DEBUG(1,
1301                           "FT1000:ft1000_parse_dpram_msg: Got a slow queue message\n");
1302                 nxtph = FT1000_DPRAM_RX_BASE + 2;
1303                 if (info->AsicID == ELECTRABUZZ_ID) {
1304                         total_len =
1305                                 ft1000_read_dpram(dev, FT1000_DPRAM_RX_BASE);
1306                 } else {
1307                         total_len =
1308                                 ntohs(ft1000_read_dpram_mag_16
1309                                   (dev, FT1000_MAG_TOTAL_LEN,
1310                                    FT1000_MAG_TOTAL_LEN_INDX));
1311                 }
1312                 DEBUG(1, "FT1000:ft1000_parse_dpram_msg:total length = %d\n",
1313                           total_len);
1314                 if ((total_len < MAX_CMD_SQSIZE) && (total_len > sizeof(struct pseudo_hdr))) {
1315             total_len += nxtph;
1316             cnt = 0;
1317             // ft1000_read_reg will return a value that needs to be byteswap
1318             // in order to get DSP_QID_OFFSET.
1319                         if (info->AsicID == ELECTRABUZZ_ID) {
1320                                 portid =
1321                                         (ft1000_read_dpram
1322                                          (dev,
1323                                           DSP_QID_OFFSET + FT1000_DPRAM_RX_BASE +
1324                                           2) >> 8) & 0xff;
1325                         } else {
1326                                 portid =
1327                                         (ft1000_read_dpram_mag_16
1328                                          (dev, FT1000_MAG_PORT_ID,
1329                                           FT1000_MAG_PORT_ID_INDX) & 0xff);
1330                         }
1331                         DEBUG(1, "DSP_QID = 0x%x\n", portid);
1332
1333                         if (portid == DRIVERID) {
1334                                 // We are assumming one driver message from the DSP at a time.
1335                                 ft1000_proc_drvmsg(dev);
1336                         }
1337                 }
1338                 ft1000_write_reg(dev, FT1000_REG_DOORBELL, FT1000_DB_DPRAM_RX);
1339         }
1340
1341         if (doorbell & FT1000_DB_COND_RESET) {
1342                 // Reset ASIC and DSP
1343                 if (info->AsicID == ELECTRABUZZ_ID) {
1344                         info->DSP_TIME[0] =
1345                                 ft1000_read_dpram(dev, FT1000_DSP_TIMER0);
1346                         info->DSP_TIME[1] =
1347                                 ft1000_read_dpram(dev, FT1000_DSP_TIMER1);
1348                         info->DSP_TIME[2] =
1349                                 ft1000_read_dpram(dev, FT1000_DSP_TIMER2);
1350                         info->DSP_TIME[3] =
1351                                 ft1000_read_dpram(dev, FT1000_DSP_TIMER3);
1352                 } else {
1353                         info->DSP_TIME[0] =
1354                                 ft1000_read_dpram_mag_16(dev, FT1000_MAG_DSP_TIMER0,
1355                                                          FT1000_MAG_DSP_TIMER0_INDX);
1356                         info->DSP_TIME[1] =
1357                                 ft1000_read_dpram_mag_16(dev, FT1000_MAG_DSP_TIMER1,
1358                                                          FT1000_MAG_DSP_TIMER1_INDX);
1359                         info->DSP_TIME[2] =
1360                                 ft1000_read_dpram_mag_16(dev, FT1000_MAG_DSP_TIMER2,
1361                                                          FT1000_MAG_DSP_TIMER2_INDX);
1362                         info->DSP_TIME[3] =
1363                                 ft1000_read_dpram_mag_16(dev, FT1000_MAG_DSP_TIMER3,
1364                                                          FT1000_MAG_DSP_TIMER3_INDX);
1365                 }
1366                 info->DrvErrNum = DSP_CONDRESET_INFO;
1367                 DEBUG(1, "ft1000_hw:DSP conditional reset requested\n");
1368                 ft1000_reset_card(dev);
1369                 ft1000_write_reg(dev, FT1000_REG_DOORBELL,
1370                                  FT1000_DB_COND_RESET);
1371         }
1372         // let's clear any unexpected doorbells from DSP
1373         doorbell =
1374                 doorbell & ~(FT1000_DB_DPRAM_RX | FT1000_ASIC_RESET_REQ |
1375                          FT1000_DB_COND_RESET | 0xff00);
1376         if (doorbell) {
1377                 DEBUG(1, "Clearing unexpected doorbell = 0x%x\n", doorbell);
1378                 ft1000_write_reg(dev, FT1000_REG_DOORBELL, doorbell);
1379         }
1380
1381         return SUCCESS;
1382
1383 }
1384
1385 //---------------------------------------------------------------------------
1386 //
1387 // Function:   ft1000_flush_fifo
1388 // Description: This function will flush one packet from the downlink
1389 //             FIFO.
1390 // Input:
1391 //     dev      - device structure
1392 //     drv_err  - driver error causing the flush fifo
1393 // Output:
1394 //     None.
1395 //
1396 //---------------------------------------------------------------------------
1397 static void ft1000_flush_fifo(struct net_device *dev, u16 DrvErrNum)
1398 {
1399         struct ft1000_info *info = netdev_priv(dev);
1400         u16 i;
1401         u32 templong;
1402         u16 tempword;
1403
1404         DEBUG(1, "ft1000:ft1000_hw:ft1000_flush_fifo called\n");
1405         if (info->PktIntfErr > MAX_PH_ERR) {
1406                 if (info->AsicID == ELECTRABUZZ_ID) {
1407                         info->DSP_TIME[0] =
1408                                 ft1000_read_dpram(dev, FT1000_DSP_TIMER0);
1409                         info->DSP_TIME[1] =
1410                                 ft1000_read_dpram(dev, FT1000_DSP_TIMER1);
1411                         info->DSP_TIME[2] =
1412                                 ft1000_read_dpram(dev, FT1000_DSP_TIMER2);
1413                         info->DSP_TIME[3] =
1414                                 ft1000_read_dpram(dev, FT1000_DSP_TIMER3);
1415                 } else {
1416                         info->DSP_TIME[0] =
1417                                 ft1000_read_dpram_mag_16(dev, FT1000_MAG_DSP_TIMER0,
1418                                                          FT1000_MAG_DSP_TIMER0_INDX);
1419                         info->DSP_TIME[1] =
1420                                 ft1000_read_dpram_mag_16(dev, FT1000_MAG_DSP_TIMER1,
1421                                                          FT1000_MAG_DSP_TIMER1_INDX);
1422                         info->DSP_TIME[2] =
1423                                 ft1000_read_dpram_mag_16(dev, FT1000_MAG_DSP_TIMER2,
1424                                                          FT1000_MAG_DSP_TIMER2_INDX);
1425                         info->DSP_TIME[3] =
1426                                 ft1000_read_dpram_mag_16(dev, FT1000_MAG_DSP_TIMER3,
1427                                                          FT1000_MAG_DSP_TIMER3_INDX);
1428                 }
1429                 info->DrvErrNum = DrvErrNum;
1430                 ft1000_reset_card(dev);
1431                 return;
1432         } else {
1433                 // Flush corrupted pkt from FIFO
1434                 i = 0;
1435                 do {
1436                         if (info->AsicID == ELECTRABUZZ_ID) {
1437                                 tempword =
1438                                         ft1000_read_reg(dev, FT1000_REG_DFIFO);
1439                                 tempword =
1440                                         ft1000_read_reg(dev, FT1000_REG_DFIFO_STAT);
1441                         } else {
1442                                 templong =
1443                                         inl(dev->base_addr + FT1000_REG_MAG_DFR);
1444                                 tempword =
1445                                         inw(dev->base_addr + FT1000_REG_MAG_DFSR);
1446                         }
1447                         i++;
1448                         // This should never happen unless the ASIC is broken.
1449                         // We must reset to recover.
1450                         if ((i > 2048) || (tempword == 0)) {
1451                                 if (info->AsicID == ELECTRABUZZ_ID) {
1452                                         info->DSP_TIME[0] =
1453                                                 ft1000_read_dpram(dev,
1454                                                                   FT1000_DSP_TIMER0);
1455                                         info->DSP_TIME[1] =
1456                                                 ft1000_read_dpram(dev,
1457                                                                   FT1000_DSP_TIMER1);
1458                                         info->DSP_TIME[2] =
1459                                                 ft1000_read_dpram(dev,
1460                                                                   FT1000_DSP_TIMER2);
1461                                         info->DSP_TIME[3] =
1462                                                 ft1000_read_dpram(dev,
1463                                                                   FT1000_DSP_TIMER3);
1464                                 } else {
1465                                         info->DSP_TIME[0] =
1466                                                 ft1000_read_dpram_mag_16(dev,
1467                                                                          FT1000_MAG_DSP_TIMER0,
1468                                                                          FT1000_MAG_DSP_TIMER0_INDX);
1469                                         info->DSP_TIME[1] =
1470                                                 ft1000_read_dpram_mag_16(dev,
1471                                                                          FT1000_MAG_DSP_TIMER1,
1472                                                                          FT1000_MAG_DSP_TIMER1_INDX);
1473                                         info->DSP_TIME[2] =
1474                                                 ft1000_read_dpram_mag_16(dev,
1475                                                                          FT1000_MAG_DSP_TIMER2,
1476                                                                          FT1000_MAG_DSP_TIMER2_INDX);
1477                                         info->DSP_TIME[3] =
1478                                                 ft1000_read_dpram_mag_16(dev,
1479                                                                          FT1000_MAG_DSP_TIMER3,
1480                                                                          FT1000_MAG_DSP_TIMER3_INDX);
1481                                 }
1482                                 if (tempword == 0) {
1483                                         // Let's check if ASIC reads are still ok by reading the Mask register
1484                                         // which is never zero at this point of the code.
1485                                         tempword =
1486                                                 inw(dev->base_addr +
1487                                                 FT1000_REG_SUP_IMASK);
1488                                         if (tempword == 0) {
1489                                                 // This indicates that we can not communicate with the ASIC
1490                                                 info->DrvErrNum =
1491                                                         FIFO_FLUSH_BADCNT;
1492                                         } else {
1493                                                 // Let's assume that we really flush the FIFO
1494                                                 info->PktIntfErr++;
1495                                                 return;
1496                                         }
1497                                 } else {
1498                                         info->DrvErrNum = FIFO_FLUSH_MAXLIMIT;
1499                                 }
1500                                 return;
1501                         }
1502                         tempword = inw(dev->base_addr + FT1000_REG_SUP_STAT);
1503                 } while ((tempword & 0x03) != 0x03);
1504                 if (info->AsicID == ELECTRABUZZ_ID) {
1505                         i++;
1506                         DEBUG(0, "Flushing FIFO complete = %x\n", tempword);
1507                         // Flush last word in FIFO.
1508                         tempword = ft1000_read_reg(dev, FT1000_REG_DFIFO);
1509                         // Update FIFO counter for DSP
1510                         i = i * 2;
1511                         DEBUG(0, "Flush Data byte count to dsp = %d\n", i);
1512                         info->fifo_cnt += i;
1513                         ft1000_write_dpram(dev, FT1000_FIFO_LEN,
1514                                            info->fifo_cnt);
1515                 } else {
1516                         DEBUG(0, "Flushing FIFO complete = %x\n", tempword);
1517                         // Flush last word in FIFO
1518                         templong = inl(dev->base_addr + FT1000_REG_MAG_DFR);
1519                         tempword = inw(dev->base_addr + FT1000_REG_SUP_STAT);
1520                         DEBUG(0, "FT1000_REG_SUP_STAT = 0x%x\n", tempword);
1521                         tempword = inw(dev->base_addr + FT1000_REG_MAG_DFSR);
1522                         DEBUG(0, "FT1000_REG_MAG_DFSR = 0x%x\n", tempword);
1523                 }
1524                 if (DrvErrNum) {
1525                         info->PktIntfErr++;
1526                 }
1527         }
1528 }
1529
1530 //---------------------------------------------------------------------------
1531 //
1532 // Function:   ft1000_copy_up_pkt
1533 // Description: This function will pull Flarion packets out of the Downlink
1534 //             FIFO and convert it to an ethernet packet.  The ethernet packet will
1535 //             then be deliver to the TCP/IP stack.
1536 // Input:
1537 //     dev    - device structure
1538 // Output:
1539 //     status - FAILURE
1540 //              SUCCESS
1541 //
1542 //---------------------------------------------------------------------------
1543 static int ft1000_copy_up_pkt(struct net_device *dev)
1544 {
1545         u16 tempword;
1546         struct ft1000_info *info = netdev_priv(dev);
1547         u16 len;
1548         struct sk_buff *skb;
1549         u16 i;
1550         u8 *pbuffer = NULL;
1551         u8 *ptemp = NULL;
1552         u16 chksum;
1553         u32 *ptemplong;
1554         u32 templong;
1555
1556         DEBUG(1, "ft1000_copy_up_pkt\n");
1557         // Read length
1558         if (info->AsicID == ELECTRABUZZ_ID) {
1559                 tempword = ft1000_read_reg(dev, FT1000_REG_DFIFO);
1560                 len = tempword;
1561         } else {
1562                 tempword = ft1000_read_reg(dev, FT1000_REG_MAG_DFRL);
1563                 len = ntohs(tempword);
1564         }
1565         chksum = tempword;
1566         DEBUG(1, "Number of Bytes in FIFO = %d\n", len);
1567
1568         if (len > ENET_MAX_SIZE) {
1569                 DEBUG(0, "size of ethernet packet invalid\n");
1570                 if (info->AsicID == MAGNEMITE_ID) {
1571                         // Read High word to complete 32 bit access
1572                         tempword = ft1000_read_reg(dev, FT1000_REG_MAG_DFRH);
1573                 }
1574                 ft1000_flush_fifo(dev, DSP_PKTLEN_INFO);
1575                 info->stats.rx_errors++;
1576                 return FAILURE;
1577         }
1578
1579         skb = dev_alloc_skb(len + 12 + 2);
1580
1581         if (skb == NULL) {
1582                 DEBUG(0, "No Network buffers available\n");
1583                 // Read High word to complete 32 bit access
1584                 if (info->AsicID == MAGNEMITE_ID) {
1585                         tempword = ft1000_read_reg(dev, FT1000_REG_MAG_DFRH);
1586                 }
1587                 ft1000_flush_fifo(dev, 0);
1588                 info->stats.rx_errors++;
1589                 return FAILURE;
1590         }
1591         pbuffer = (u8 *) skb_put(skb, len + 12);
1592
1593         // Pseudo header
1594         if (info->AsicID == ELECTRABUZZ_ID) {
1595                 for (i = 1; i < 7; i++) {
1596                         tempword = ft1000_read_reg(dev, FT1000_REG_DFIFO);
1597                         chksum ^= tempword;
1598                 }
1599                 // read checksum value
1600                 tempword = ft1000_read_reg(dev, FT1000_REG_DFIFO);
1601         } else {
1602                 tempword = ft1000_read_reg(dev, FT1000_REG_MAG_DFRH);
1603                 DEBUG(1, "Pseudo = 0x%x\n", tempword);
1604                 chksum ^= tempword;
1605
1606                 tempword = ft1000_read_reg(dev, FT1000_REG_MAG_DFRL);
1607                 DEBUG(1, "Pseudo = 0x%x\n", tempword);
1608                 chksum ^= tempword;
1609
1610                 tempword = ft1000_read_reg(dev, FT1000_REG_MAG_DFRH);
1611                 DEBUG(1, "Pseudo = 0x%x\n", tempword);
1612                 chksum ^= tempword;
1613
1614                 tempword = ft1000_read_reg(dev, FT1000_REG_MAG_DFRL);
1615                 DEBUG(1, "Pseudo = 0x%x\n", tempword);
1616                 chksum ^= tempword;
1617
1618                 tempword = ft1000_read_reg(dev, FT1000_REG_MAG_DFRH);
1619                 DEBUG(1, "Pseudo = 0x%x\n", tempword);
1620                 chksum ^= tempword;
1621
1622                 tempword = ft1000_read_reg(dev, FT1000_REG_MAG_DFRL);
1623                 DEBUG(1, "Pseudo = 0x%x\n", tempword);
1624                 chksum ^= tempword;
1625
1626                 // read checksum value
1627                 tempword = ft1000_read_reg(dev, FT1000_REG_MAG_DFRH);
1628                 DEBUG(1, "Pseudo = 0x%x\n", tempword);
1629         }
1630
1631         if (chksum != tempword) {
1632                 DEBUG(0, "Packet checksum mismatch 0x%x 0x%x\n", chksum,
1633                           tempword);
1634                 ft1000_flush_fifo(dev, DSP_PKTPHCKSUM_INFO);
1635                 info->stats.rx_errors++;
1636                 kfree_skb(skb);
1637                 return FAILURE;
1638         }
1639         //subtract the number of bytes read already
1640         ptemp = pbuffer;
1641
1642         // fake MAC address
1643         *pbuffer++ = dev->dev_addr[0];
1644         *pbuffer++ = dev->dev_addr[1];
1645         *pbuffer++ = dev->dev_addr[2];
1646         *pbuffer++ = dev->dev_addr[3];
1647         *pbuffer++ = dev->dev_addr[4];
1648         *pbuffer++ = dev->dev_addr[5];
1649         *pbuffer++ = 0x00;
1650         *pbuffer++ = 0x07;
1651         *pbuffer++ = 0x35;
1652         *pbuffer++ = 0xff;
1653         *pbuffer++ = 0xff;
1654         *pbuffer++ = 0xfe;
1655
1656         if (info->AsicID == ELECTRABUZZ_ID) {
1657                 for (i = 0; i < len / 2; i++) {
1658                         tempword = ft1000_read_reg(dev, FT1000_REG_DFIFO);
1659                         *pbuffer++ = (u8) (tempword >> 8);
1660                         *pbuffer++ = (u8) tempword;
1661                         if (ft1000_chkcard(dev) == false) {
1662                                 kfree_skb(skb);
1663                                 return FAILURE;
1664                         }
1665                 }
1666
1667                 // Need to read one more word if odd byte
1668                 if (len & 0x0001) {
1669                         tempword = ft1000_read_reg(dev, FT1000_REG_DFIFO);
1670                         *pbuffer++ = (u8) (tempword >> 8);
1671                 }
1672         } else {
1673                 ptemplong = (u32 *) pbuffer;
1674                 for (i = 0; i < len / 4; i++) {
1675                         templong = inl(dev->base_addr + FT1000_REG_MAG_DFR);
1676                         DEBUG(1, "Data = 0x%8x\n", templong);
1677                         *ptemplong++ = templong;
1678                 }
1679
1680                 // Need to read one more word if odd align.
1681                 if (len & 0x0003) {
1682                         templong = inl(dev->base_addr + FT1000_REG_MAG_DFR);
1683                         DEBUG(1, "Data = 0x%8x\n", templong);
1684                         *ptemplong++ = templong;
1685                 }
1686
1687         }
1688
1689         DEBUG(1, "Data passed to Protocol layer:\n");
1690         for (i = 0; i < len + 12; i++) {
1691                 DEBUG(1, "Protocol Data: 0x%x\n ", *ptemp++);
1692         }
1693
1694         skb->dev = dev;
1695         skb->protocol = eth_type_trans(skb, dev);
1696         skb->ip_summed = CHECKSUM_UNNECESSARY;
1697         netif_rx(skb);
1698
1699         info->stats.rx_packets++;
1700         // Add on 12 bytes for MAC address which was removed
1701         info->stats.rx_bytes += (len + 12);
1702
1703         if (info->AsicID == ELECTRABUZZ_ID) {
1704                 // track how many bytes have been read from FIFO - round up to 16 bit word
1705                 tempword = len + 16;
1706                 if (tempword & 0x01)
1707                         tempword++;
1708                 info->fifo_cnt += tempword;
1709                 ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR, FT1000_FIFO_LEN);
1710                 ft1000_write_reg(dev, FT1000_REG_DPRAM_DATA, info->fifo_cnt);
1711         }
1712
1713         return SUCCESS;
1714 }
1715
1716 //---------------------------------------------------------------------------
1717 //
1718 // Function:   ft1000_copy_down_pkt
1719 // Description: This function will take an ethernet packet and convert it to
1720 //             a Flarion packet prior to sending it to the ASIC Downlink
1721 //             FIFO.
1722 // Input:
1723 //     dev    - device structure
1724 //     packet - address of ethernet packet
1725 //     len    - length of IP packet
1726 // Output:
1727 //     status - FAILURE
1728 //              SUCCESS
1729 //
1730 //---------------------------------------------------------------------------
1731 static int ft1000_copy_down_pkt(struct net_device *dev, u16 * packet, u16 len)
1732 {
1733         struct ft1000_info *info = netdev_priv(dev);
1734         union {
1735                 struct pseudo_hdr blk;
1736                 u16 buff[sizeof(struct pseudo_hdr) >> 1];
1737                 u8 buffc[sizeof(struct pseudo_hdr)];
1738         } pseudo;
1739         int i;
1740         u32 *plong;
1741
1742         DEBUG(1, "ft1000_hw: copy_down_pkt()\n");
1743
1744         // Check if there is room on the FIFO
1745         if (len > ft1000_read_fifo_len(dev)) {
1746                 udelay(10);
1747                 if (len > ft1000_read_fifo_len(dev)) {
1748                         udelay(20);
1749                 }
1750                 if (len > ft1000_read_fifo_len(dev)) {
1751                         udelay(20);
1752                 }
1753                 if (len > ft1000_read_fifo_len(dev)) {
1754                         udelay(20);
1755                 }
1756                 if (len > ft1000_read_fifo_len(dev)) {
1757                         udelay(20);
1758                 }
1759                 if (len > ft1000_read_fifo_len(dev)) {
1760                         udelay(20);
1761                 }
1762                 if (len > ft1000_read_fifo_len(dev)) {
1763                         DEBUG(1,
1764                                   "ft1000_hw:ft1000_copy_down_pkt:Transmit FIFO is fulli - pkt drop\n");
1765                         info->stats.tx_errors++;
1766                         return SUCCESS;
1767                 }
1768         }
1769         // Create pseudo header and send pseudo/ip to hardware
1770         if (info->AsicID == ELECTRABUZZ_ID) {
1771                 pseudo.blk.length = len;
1772         } else {
1773                 pseudo.blk.length = ntohs(len);
1774         }
1775         pseudo.blk.source = DSPID;      // Need to swap to get in correct order
1776         pseudo.blk.destination = HOSTID;
1777         pseudo.blk.portdest = NETWORKID;        // Need to swap to get in correct order
1778         pseudo.blk.portsrc = DSPAIRID;
1779         pseudo.blk.sh_str_id = 0;
1780         pseudo.blk.control = 0;
1781         pseudo.blk.rsvd1 = 0;
1782         pseudo.blk.seq_num = 0;
1783         pseudo.blk.rsvd2 = info->packetseqnum++;
1784         pseudo.blk.qos_class = 0;
1785         /* Calculate pseudo header checksum */
1786         pseudo.blk.checksum = pseudo.buff[0];
1787         for (i = 1; i < 7; i++) {
1788                 pseudo.blk.checksum ^= pseudo.buff[i];
1789         }
1790
1791         // Production Mode
1792         if (info->AsicID == ELECTRABUZZ_ID) {
1793                 // copy first word to UFIFO_BEG reg
1794                 ft1000_write_reg(dev, FT1000_REG_UFIFO_BEG, pseudo.buff[0]);
1795                 DEBUG(1, "ft1000_hw:ft1000_copy_down_pkt:data 0 BEG = 0x%04x\n",
1796                           pseudo.buff[0]);
1797
1798                 // copy subsequent words to UFIFO_MID reg
1799                 ft1000_write_reg(dev, FT1000_REG_UFIFO_MID, pseudo.buff[1]);
1800                 DEBUG(1, "ft1000_hw:ft1000_copy_down_pkt:data 1 MID = 0x%04x\n",
1801                           pseudo.buff[1]);
1802                 ft1000_write_reg(dev, FT1000_REG_UFIFO_MID, pseudo.buff[2]);
1803                 DEBUG(1, "ft1000_hw:ft1000_copy_down_pkt:data 2 MID = 0x%04x\n",
1804                           pseudo.buff[2]);
1805                 ft1000_write_reg(dev, FT1000_REG_UFIFO_MID, pseudo.buff[3]);
1806                 DEBUG(1, "ft1000_hw:ft1000_copy_down_pkt:data 3 MID = 0x%04x\n",
1807                           pseudo.buff[3]);
1808                 ft1000_write_reg(dev, FT1000_REG_UFIFO_MID, pseudo.buff[4]);
1809                 DEBUG(1, "ft1000_hw:ft1000_copy_down_pkt:data 4 MID = 0x%04x\n",
1810                           pseudo.buff[4]);
1811                 ft1000_write_reg(dev, FT1000_REG_UFIFO_MID, pseudo.buff[5]);
1812                 DEBUG(1, "ft1000_hw:ft1000_copy_down_pkt:data 5 MID = 0x%04x\n",
1813                           pseudo.buff[5]);
1814                 ft1000_write_reg(dev, FT1000_REG_UFIFO_MID, pseudo.buff[6]);
1815                 DEBUG(1, "ft1000_hw:ft1000_copy_down_pkt:data 6 MID = 0x%04x\n",
1816                           pseudo.buff[6]);
1817                 ft1000_write_reg(dev, FT1000_REG_UFIFO_MID, pseudo.buff[7]);
1818                 DEBUG(1, "ft1000_hw:ft1000_copy_down_pkt:data 7 MID = 0x%04x\n",
1819                           pseudo.buff[7]);
1820
1821                 // Write PPP type + IP Packet into Downlink FIFO
1822                 for (i = 0; i < (len >> 1) - 1; i++) {
1823                         ft1000_write_reg(dev, FT1000_REG_UFIFO_MID,
1824                                          htons(*packet));
1825                         DEBUG(1,
1826                                   "ft1000_hw:ft1000_copy_down_pkt:data %d MID = 0x%04x\n",
1827                                   i + 8, htons(*packet));
1828                         packet++;
1829                 }
1830
1831                 // Check for odd byte
1832                 if (len & 0x0001) {
1833                         ft1000_write_reg(dev, FT1000_REG_UFIFO_MID,
1834                                          htons(*packet));
1835                         DEBUG(1,
1836                                   "ft1000_hw:ft1000_copy_down_pkt:data MID = 0x%04x\n",
1837                                   htons(*packet));
1838                         packet++;
1839                         ft1000_write_reg(dev, FT1000_REG_UFIFO_END,
1840                                          htons(*packet));
1841                         DEBUG(1,
1842                                   "ft1000_hw:ft1000_copy_down_pkt:data %d MID = 0x%04x\n",
1843                                   i + 8, htons(*packet));
1844                 } else {
1845                         ft1000_write_reg(dev, FT1000_REG_UFIFO_END,
1846                                          htons(*packet));
1847                         DEBUG(1,
1848                                   "ft1000_hw:ft1000_copy_down_pkt:data %d MID = 0x%04x\n",
1849                                   i + 8, htons(*packet));
1850                 }
1851         } else {
1852                 outl(*(u32 *) & pseudo.buff[0],
1853                          dev->base_addr + FT1000_REG_MAG_UFDR);
1854                 DEBUG(1, "ft1000_copy_down_pkt: Pseudo = 0x%8x\n",
1855                           *(u32 *) & pseudo.buff[0]);
1856                 outl(*(u32 *) & pseudo.buff[2],
1857                          dev->base_addr + FT1000_REG_MAG_UFDR);
1858                 DEBUG(1, "ft1000_copy_down_pkt: Pseudo = 0x%8x\n",
1859                           *(u32 *) & pseudo.buff[2]);
1860                 outl(*(u32 *) & pseudo.buff[4],
1861                          dev->base_addr + FT1000_REG_MAG_UFDR);
1862                 DEBUG(1, "ft1000_copy_down_pkt: Pseudo = 0x%8x\n",
1863                           *(u32 *) & pseudo.buff[4]);
1864                 outl(*(u32 *) & pseudo.buff[6],
1865                          dev->base_addr + FT1000_REG_MAG_UFDR);
1866                 DEBUG(1, "ft1000_copy_down_pkt: Pseudo = 0x%8x\n",
1867                           *(u32 *) & pseudo.buff[6]);
1868
1869                 plong = (u32 *) packet;
1870                 // Write PPP type + IP Packet into Downlink FIFO
1871                 for (i = 0; i < (len >> 2); i++) {
1872                         outl(*plong++, dev->base_addr + FT1000_REG_MAG_UFDR);
1873                 }
1874
1875                 // Check for odd alignment
1876                 if (len & 0x0003) {
1877                         DEBUG(1,
1878                                   "ft1000_hw:ft1000_copy_down_pkt:data = 0x%8x\n",
1879                                   *plong);
1880                         outl(*plong++, dev->base_addr + FT1000_REG_MAG_UFDR);
1881                 }
1882                 outl(1, dev->base_addr + FT1000_REG_MAG_UFER);
1883         }
1884
1885         info->stats.tx_packets++;
1886         // Add 14 bytes for MAC address plus ethernet type
1887         info->stats.tx_bytes += (len + 14);
1888         return SUCCESS;
1889 }
1890
1891 static struct net_device_stats *ft1000_stats(struct net_device *dev)
1892 {
1893         struct ft1000_info *info = netdev_priv(dev);
1894         return (&info->stats);
1895 }
1896
1897 static int ft1000_open(struct net_device *dev)
1898 {
1899
1900         DEBUG(0, "ft1000_hw: ft1000_open is called\n");
1901
1902         ft1000_reset_card(dev);
1903         DEBUG(0, "ft1000_hw: ft1000_open is ended\n");
1904
1905         /* schedule ft1000_hbchk to perform periodic heartbeat checks on DSP and ASIC */
1906         init_timer(&poll_timer);
1907         poll_timer.expires = jiffies + (2 * HZ);
1908         poll_timer.data = (u_long) dev;
1909         add_timer(&poll_timer);
1910
1911         DEBUG(0, "ft1000_hw: ft1000_open is ended2\n");
1912         return 0;
1913 }
1914
1915 static int ft1000_close(struct net_device *dev)
1916 {
1917         struct ft1000_info *info = netdev_priv(dev);
1918
1919         DEBUG(0, "ft1000_hw: ft1000_close()\n");
1920
1921         info->CardReady = 0;
1922         del_timer(&poll_timer);
1923
1924         if (ft1000_card_present == 1) {
1925                 DEBUG(0, "Media is down\n");
1926                 netif_stop_queue(dev);
1927
1928                 ft1000_disable_interrupts(dev);
1929                 ft1000_write_reg(dev, FT1000_REG_RESET, DSP_RESET_BIT);
1930
1931                 //reset ASIC
1932                 ft1000_reset_asic(dev);
1933         }
1934         return 0;
1935 }
1936
1937 static int ft1000_start_xmit(struct sk_buff *skb, struct net_device *dev)
1938 {
1939         struct ft1000_info *info = netdev_priv(dev);
1940         u8 *pdata;
1941
1942         DEBUG(1, "ft1000_hw: ft1000_start_xmit()\n");
1943         if (skb == NULL) {
1944                 DEBUG(1, "ft1000_hw: ft1000_start_xmit:skb == NULL!!!\n");
1945                 return 0;
1946         }
1947
1948         DEBUG(1, "ft1000_hw: ft1000_start_xmit:length of packet = %d\n",
1949                   skb->len);
1950
1951         pdata = (u8 *) skb->data;
1952
1953         if (info->mediastate == 0) {
1954                 /* Drop packet is mediastate is down */
1955                 DEBUG(1, "ft1000_hw:ft1000_copy_down_pkt:mediastate is down\n");
1956                 return SUCCESS;
1957         }
1958
1959         if ((skb->len < ENET_HEADER_SIZE) || (skb->len > ENET_MAX_SIZE)) {
1960                 /* Drop packet which has invalid size */
1961                 DEBUG(1,
1962                           "ft1000_hw:ft1000_copy_down_pkt:invalid ethernet length\n");
1963                 return SUCCESS;
1964         }
1965         ft1000_copy_down_pkt(dev, (u16 *) (pdata + ENET_HEADER_SIZE - 2),
1966                                  skb->len - ENET_HEADER_SIZE + 2);
1967
1968         dev_kfree_skb(skb);
1969
1970         return 0;
1971 }
1972
1973 static irqreturn_t ft1000_interrupt(int irq, void *dev_id)
1974 {
1975         struct net_device *dev = (struct net_device *)dev_id;
1976         struct ft1000_info *info = netdev_priv(dev);
1977         u16 tempword;
1978         u16 inttype;
1979         int cnt;
1980
1981         DEBUG(1, "ft1000_hw: ft1000_interrupt()\n");
1982
1983         if (info->CardReady == 0) {
1984                 ft1000_disable_interrupts(dev);
1985                 return IRQ_HANDLED;
1986         }
1987
1988         if (ft1000_chkcard(dev) == false) {
1989                 ft1000_disable_interrupts(dev);
1990                 return IRQ_HANDLED;
1991         }
1992
1993         ft1000_disable_interrupts(dev);
1994
1995         // Read interrupt type
1996         inttype = ft1000_read_reg(dev, FT1000_REG_SUP_ISR);
1997
1998     // Make sure we process all interrupt before leaving the ISR due to the edge trigger interrupt type
1999         while (inttype) {
2000                 if (inttype & ISR_DOORBELL_PEND)
2001                         ft1000_parse_dpram_msg(dev);
2002
2003                 if (inttype & ISR_RCV) {
2004                         DEBUG(1, "Data in FIFO\n");
2005
2006                         cnt = 0;
2007                         do {
2008                                 // Check if we have packets in the Downlink FIFO
2009                                 if (info->AsicID == ELECTRABUZZ_ID) {
2010                                         tempword =
2011                                         ft1000_read_reg(dev,
2012                                                         FT1000_REG_DFIFO_STAT);
2013                                 } else {
2014                                         tempword =
2015                                         ft1000_read_reg(dev,
2016                                                         FT1000_REG_MAG_DFSR);
2017                                 }
2018                                 if (tempword & 0x1f) {
2019                                         ft1000_copy_up_pkt(dev);
2020                                 } else {
2021                                         break;
2022                                 }
2023                                 cnt++;
2024                         } while (cnt < MAX_RCV_LOOP);
2025
2026                 }
2027                 // clear interrupts
2028                 tempword = ft1000_read_reg(dev, FT1000_REG_SUP_ISR);
2029                 DEBUG(1, "ft1000_hw: interrupt status register = 0x%x\n", tempword);
2030                 ft1000_write_reg(dev, FT1000_REG_SUP_ISR, tempword);
2031
2032                 // Read interrupt type
2033                 inttype = ft1000_read_reg (dev, FT1000_REG_SUP_ISR);
2034                 DEBUG(1,"ft1000_hw: interrupt status register after clear = 0x%x\n",inttype);
2035         }
2036         ft1000_enable_interrupts(dev);
2037         return IRQ_HANDLED;
2038 }
2039
2040 void stop_ft1000_card(struct net_device *dev)
2041 {
2042         struct ft1000_info *info = netdev_priv(dev);
2043         struct prov_record *ptr;
2044 //      int cnt;
2045
2046         DEBUG(0, "ft1000_hw: stop_ft1000_card()\n");
2047
2048         info->CardReady = 0;
2049         ft1000_card_present = 0;
2050         netif_stop_queue(dev);
2051         ft1000_disable_interrupts(dev);
2052
2053         // Make sure we free any memory reserve for provisioning
2054         while (list_empty(&info->prov_list) == 0) {
2055                 ptr = list_entry(info->prov_list.next, struct prov_record, list);
2056                 list_del(&ptr->list);
2057                 kfree(ptr->pprov_data);
2058                 kfree(ptr);
2059         }
2060
2061         if (info->registered) {
2062                 unregister_netdev(dev);
2063                 info->registered = 0;
2064         }
2065
2066         free_irq(dev->irq, dev);
2067         release_region(dev->base_addr,256);
2068         release_firmware(fw_entry);
2069         flarion_ft1000_cnt--;
2070         ft1000CleanupProc(dev);
2071
2072 }
2073
2074 static void ft1000_get_drvinfo(struct net_device *dev,
2075                                    struct ethtool_drvinfo *info)
2076 {
2077         struct ft1000_info *ft_info;
2078         ft_info = netdev_priv(dev);
2079
2080         strlcpy(info->driver, "ft1000", sizeof(info->driver));
2081         snprintf(info->bus_info, sizeof(info->bus_info), "PCMCIA 0x%lx",
2082                  dev->base_addr);
2083         snprintf(info->fw_version, sizeof(info->fw_version), "%d.%d.%d.%d",
2084                  ft_info->DspVer[0], ft_info->DspVer[1], ft_info->DspVer[2],
2085                  ft_info->DspVer[3]);
2086 }
2087
2088 static u32 ft1000_get_link(struct net_device *dev)
2089 {
2090         struct ft1000_info *info;
2091         info = netdev_priv(dev);
2092         return info->mediastate;
2093 }
2094
2095 static const struct ethtool_ops ops = {
2096         .get_drvinfo = ft1000_get_drvinfo,
2097         .get_link = ft1000_get_link
2098 };
2099
2100 struct net_device *init_ft1000_card(struct pcmcia_device *link,
2101                                                 void *ft1000_reset)
2102 {
2103         struct ft1000_info *info;
2104         struct net_device *dev;
2105
2106         static const struct net_device_ops ft1000ops =          // Slavius 21.10.2009 due to kernel changes
2107         {
2108                 .ndo_open = &ft1000_open,
2109                 .ndo_stop = &ft1000_close,
2110                 .ndo_start_xmit = &ft1000_start_xmit,
2111                 .ndo_get_stats = &ft1000_stats,
2112         };
2113
2114         DEBUG(1, "ft1000_hw: init_ft1000_card()\n");
2115         DEBUG(1, "ft1000_hw: irq = %d\n", link->irq);
2116         DEBUG(1, "ft1000_hw: port = 0x%04x\n", link->resource[0]->start);
2117
2118         flarion_ft1000_cnt++;
2119
2120         if (flarion_ft1000_cnt > 1) {
2121                 flarion_ft1000_cnt--;
2122
2123                 printk(KERN_INFO
2124                            "ft1000: This driver can not support more than one instance\n");
2125                 return NULL;
2126         }
2127
2128         dev = alloc_etherdev(sizeof(struct ft1000_info));
2129         if (!dev) {
2130                 printk(KERN_ERR "ft1000: failed to allocate etherdev\n");
2131                 return NULL;
2132         }
2133
2134         SET_NETDEV_DEV(dev, &link->dev);
2135         info = netdev_priv(dev);
2136
2137         memset(info, 0, sizeof(struct ft1000_info));
2138
2139         DEBUG(1, "address of dev = 0x%8x\n", (u32) dev);
2140         DEBUG(1, "address of dev info = 0x%8x\n", (u32) info);
2141         DEBUG(0, "device name = %s\n", dev->name);
2142
2143         memset(&info->stats, 0, sizeof(struct net_device_stats));
2144
2145         spin_lock_init(&info->dpram_lock);
2146         info->DrvErrNum = 0;
2147         info->registered = 1;
2148         info->link = link;
2149         info->ft1000_reset = ft1000_reset;
2150         info->mediastate = 0;
2151         info->fifo_cnt = 0;
2152         info->CardReady = 0;
2153         info->DSP_TIME[0] = 0;
2154         info->DSP_TIME[1] = 0;
2155         info->DSP_TIME[2] = 0;
2156         info->DSP_TIME[3] = 0;
2157         flarion_ft1000_cnt = 0;
2158
2159         INIT_LIST_HEAD(&info->prov_list);
2160
2161         info->squeseqnum = 0;
2162
2163 //      dev->hard_start_xmit = &ft1000_start_xmit;
2164 //      dev->get_stats = &ft1000_stats;
2165 //      dev->open = &ft1000_open;
2166 //      dev->stop = &ft1000_close;
2167
2168         dev->netdev_ops = &ft1000ops;           // Slavius 21.10.2009 due to kernel changes
2169
2170         DEBUG(0, "device name = %s\n", dev->name);
2171
2172         dev->irq = link->irq;
2173         dev->base_addr = link->resource[0]->start;
2174         if (pcmcia_get_mac_from_cis(link, dev)) {
2175                 printk(KERN_ERR "ft1000: Could not read mac address\n");
2176                 goto err_dev;
2177         }
2178
2179         if (request_irq(dev->irq, ft1000_interrupt, IRQF_SHARED, dev->name, dev)) {
2180                 printk(KERN_ERR "ft1000: Could not request_irq\n");
2181                 goto err_dev;
2182         }
2183
2184         if (request_region(dev->base_addr, 256, dev->name) == NULL) {
2185                 printk(KERN_ERR "ft1000: Could not request_region\n");
2186                 goto err_irq;
2187         }
2188
2189         if (register_netdev(dev) != 0) {
2190                 DEBUG(0, "ft1000: Could not register netdev");
2191                 goto err_reg;
2192         }
2193
2194         info->AsicID = ft1000_read_reg(dev, FT1000_REG_ASIC_ID);
2195         if (info->AsicID == ELECTRABUZZ_ID) {
2196                 DEBUG(0, "ft1000_hw: ELECTRABUZZ ASIC\n");
2197                 if (request_firmware(&fw_entry, "ft1000.img", &link->dev) != 0) {
2198                         printk(KERN_INFO "ft1000: Could not open ft1000.img\n");
2199                         goto err_unreg;
2200                 }
2201         } else {
2202                 DEBUG(0, "ft1000_hw: MAGNEMITE ASIC\n");
2203                 if (request_firmware(&fw_entry, "ft2000.img", &link->dev) != 0) {
2204                         printk(KERN_INFO "ft1000: Could not open ft2000.img\n");
2205                         goto err_unreg;
2206                 }
2207         }
2208
2209         ft1000_enable_interrupts(dev);
2210
2211         ft1000InitProc(dev);
2212         ft1000_card_present = 1;
2213         SET_ETHTOOL_OPS(dev, &ops);
2214         printk(KERN_INFO "ft1000: %s: addr 0x%04lx irq %d, MAC addr %pM\n",
2215                         dev->name, dev->base_addr, dev->irq, dev->dev_addr);
2216         return dev;
2217
2218 err_unreg:
2219         unregister_netdev(dev);
2220 err_reg:
2221         release_region(dev->base_addr, 256);
2222 err_irq:
2223         free_irq(dev->irq, dev);
2224 err_dev:
2225         free_netdev(dev);
2226         return NULL;
2227 }