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