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