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