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