These changes are the raw update to linux-4.4.6-rt14. Kernel sources
[kvmfornfv.git] / kernel / drivers / staging / ft1000 / ft1000-pcmcia / ft1000_hw.c
diff --git a/kernel/drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c b/kernel/drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c
deleted file mode 100644 (file)
index eecfa37..0000000
+++ /dev/null
@@ -1,2068 +0,0 @@
-/*---------------------------------------------------------------------------
-  FT1000 driver for Flarion Flash OFDM NIC Device
-
-  Copyright (C) 2002 Flarion Technologies, All rights reserved.
-  Copyright (C) 2006 Patrik Ostrihon, All rights reserved.
-  Copyright (C) 2006 ProWeb Consulting, a.s, All rights reserved.
-
-  This program is free software; you can redistribute it and/or modify it
-  under the terms of the GNU General Public License as published by the Free
-  Software Foundation; either version 2 of the License, or (at your option) any
-  later version. This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-  or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
-  more details. You should have received a copy of the GNU General Public
-  License along with this program; if not, write to the
-  Free Software Foundation, Inc., 59 Temple Place -
-  Suite 330, Boston, MA 02111-1307, USA.
-  -------------------------------------------------------------------------*/
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/sched.h>
-#include <linux/ptrace.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/timer.h>
-#include <linux/interrupt.h>
-#include <linux/in.h>
-#include <linux/io.h>
-#include <linux/bitops.h>
-
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-#include <linux/if_arp.h>
-#include <linux/ioport.h>
-#include <linux/wait.h>
-#include <linux/vmalloc.h>
-
-#include <linux/firmware.h>
-#include <linux/ethtool.h>
-
-#include <pcmcia/cistpl.h>
-#include <pcmcia/cisreg.h>
-#include <pcmcia/ds.h>
-
-#include <linux/delay.h>
-#include "ft1000.h"
-
-static const struct firmware *fw_entry;
-
-static void ft1000_hbchk(u_long data);
-static struct timer_list poll_timer = {
-       .function = ft1000_hbchk
-};
-
-static u16 cmdbuffer[1024];
-static u8 tempbuffer[1600];
-static u8 ft1000_card_present;
-static u8 flarion_ft1000_cnt;
-
-static irqreturn_t ft1000_interrupt(int irq, void *dev_id);
-static void ft1000_enable_interrupts(struct net_device *dev);
-static void ft1000_disable_interrupts(struct net_device *dev);
-
-/* new kernel */
-MODULE_AUTHOR("");
-MODULE_DESCRIPTION("Support for Flarion Flash OFDM NIC Device. Support for PCMCIA when used with ft1000_cs.");
-MODULE_LICENSE("GPL");
-MODULE_SUPPORTED_DEVICE("FT1000");
-
-#define MAX_RCV_LOOP   100
-
-/*---------------------------------------------------------------------------
-
-  Function:   ft1000_read_fifo_len
-  Description: This function will read the ASIC Uplink FIFO status register
-  which will return the number of bytes remaining in the Uplink FIFO.
-  Sixteen bytes are subtracted to make sure that the ASIC does not
-  reach its threshold.
-  Input:
-  dev    - network device structure
-  Output:
-  value  - number of bytes available in the ASIC Uplink FIFO.
-
-  -------------------------------------------------------------------------*/
-static inline u16 ft1000_read_fifo_len(struct net_device *dev)
-{
-       struct ft1000_info *info = netdev_priv(dev);
-
-       if (info->AsicID == ELECTRABUZZ_ID)
-               return (ft1000_read_reg(dev, FT1000_REG_UFIFO_STAT) - 16);
-       else
-               return (ft1000_read_reg(dev, FT1000_REG_MAG_UFSR) - 16);
-}
-
-/*---------------------------------------------------------------------------
-
-  Function:   ft1000_read_dpram
-  Description: This function will read the specific area of dpram
-  (Electrabuzz ASIC only)
-  Input:
-  dev    - device structure
-  offset - index of dpram
-  Output:
-  value  - value of dpram
-
-  -------------------------------------------------------------------------*/
-u16 ft1000_read_dpram(struct net_device *dev, int offset)
-{
-       struct ft1000_info *info = netdev_priv(dev);
-       unsigned long flags;
-       u16 data;
-
-       /* Provide mutual exclusive access while reading ASIC registers. */
-       spin_lock_irqsave(&info->dpram_lock, flags);
-       ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR, offset);
-       data = ft1000_read_reg(dev, FT1000_REG_DPRAM_DATA);
-       spin_unlock_irqrestore(&info->dpram_lock, flags);
-
-       return data;
-}
-
-/*---------------------------------------------------------------------------
-
-  Function:   ft1000_write_dpram
-  Description: This function will write to a specific area of dpram
-  (Electrabuzz ASIC only)
-  Input:
-  dev    - device structure
-  offset - index of dpram
-  value  - value to write
-  Output:
-  none.
-
-  -------------------------------------------------------------------------*/
-static inline void ft1000_write_dpram(struct net_device *dev,
-                                     int offset, u16 value)
-{
-       struct ft1000_info *info = netdev_priv(dev);
-       unsigned long flags;
-
-       /* Provide mutual exclusive access while reading ASIC registers. */
-       spin_lock_irqsave(&info->dpram_lock, flags);
-       ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR, offset);
-       ft1000_write_reg(dev, FT1000_REG_DPRAM_DATA, value);
-       spin_unlock_irqrestore(&info->dpram_lock, flags);
-}
-
-/*---------------------------------------------------------------------------
-
-  Function:   ft1000_read_dpram_mag_16
-  Description: This function will read the specific area of dpram
-  (Magnemite ASIC only)
-  Input:
-  dev    - device structure
-  offset - index of dpram
-  Output:
-  value  - value of dpram
-
-  -------------------------------------------------------------------------*/
-u16 ft1000_read_dpram_mag_16(struct net_device *dev, int offset, int Index)
-{
-       struct ft1000_info *info = netdev_priv(dev);
-       unsigned long flags;
-       u16 data;
-
-       /* Provide mutual exclusive access while reading ASIC registers. */
-       spin_lock_irqsave(&info->dpram_lock, flags);
-       ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR, offset);
-       /* check if we want to read upper or lower 32-bit word */
-       if (Index)
-               data = ft1000_read_reg(dev, FT1000_REG_MAG_DPDATAL);
-       else
-               data = ft1000_read_reg(dev, FT1000_REG_MAG_DPDATAH);
-
-       spin_unlock_irqrestore(&info->dpram_lock, flags);
-
-       return data;
-}
-
-/*---------------------------------------------------------------------------
-
-  Function:   ft1000_write_dpram_mag_16
-  Description: This function will write to a specific area of dpram
-  (Magnemite ASIC only)
-  Input:
-  dev    - device structure
-  offset - index of dpram
-  value  - value to write
-  Output:
-  none.
-
-  -------------------------------------------------------------------------*/
-static inline void ft1000_write_dpram_mag_16(struct net_device *dev,
-                                            int offset, u16 value, int Index)
-{
-       struct ft1000_info *info = netdev_priv(dev);
-       unsigned long flags;
-
-       /* Provide mutual exclusive access while reading ASIC registers. */
-       spin_lock_irqsave(&info->dpram_lock, flags);
-       ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR, offset);
-       if (Index)
-               ft1000_write_reg(dev, FT1000_REG_MAG_DPDATAL, value);
-       else
-               ft1000_write_reg(dev, FT1000_REG_MAG_DPDATAH, value);
-
-       spin_unlock_irqrestore(&info->dpram_lock, flags);
-}
-
-/*---------------------------------------------------------------------------
-
-  Function:   ft1000_read_dpram_mag_32
-  Description: This function will read the specific area of dpram
-  (Magnemite ASIC only)
-  Input:
-  dev    - device structure
-  offset - index of dpram
-  Output:
-  value  - value of dpram
-
-  -------------------------------------------------------------------------*/
-u32 ft1000_read_dpram_mag_32(struct net_device *dev, int offset)
-{
-       struct ft1000_info *info = netdev_priv(dev);
-       unsigned long flags;
-       u32 data;
-
-       /* Provide mutual exclusive access while reading ASIC registers. */
-       spin_lock_irqsave(&info->dpram_lock, flags);
-       ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR, offset);
-       data = inl(dev->base_addr + FT1000_REG_MAG_DPDATAL);
-       spin_unlock_irqrestore(&info->dpram_lock, flags);
-
-       return data;
-}
-
-/*---------------------------------------------------------------------------
-
-  Function:   ft1000_write_dpram_mag_32
-  Description: This function will write to a specific area of dpram
-  (Magnemite ASIC only)
-  Input:
-  dev    - device structure
-  offset - index of dpram
-  value  - value to write
-  Output:
-  none.
-
-  -------------------------------------------------------------------------*/
-void ft1000_write_dpram_mag_32(struct net_device *dev, int offset, u32 value)
-{
-       struct ft1000_info *info = netdev_priv(dev);
-       unsigned long flags;
-
-       /* Provide mutual exclusive access while reading ASIC registers. */
-       spin_lock_irqsave(&info->dpram_lock, flags);
-       ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR, offset);
-       outl(value, dev->base_addr + FT1000_REG_MAG_DPDATAL);
-       spin_unlock_irqrestore(&info->dpram_lock, flags);
-}
-
-/*---------------------------------------------------------------------------
-
-  Function:   ft1000_enable_interrupts
-  Description: This function will enable interrupts base on the current
-              interrupt mask.
-  Input:
-  dev    - device structure
-  Output:
-  None.
-
-  -------------------------------------------------------------------------*/
-static void ft1000_enable_interrupts(struct net_device *dev)
-{
-       u16 tempword;
-
-       ft1000_write_reg(dev, FT1000_REG_SUP_IMASK, ISR_DEFAULT_MASK);
-       tempword = ft1000_read_reg(dev, FT1000_REG_SUP_IMASK);
-       pr_debug("current interrupt enable mask = 0x%x\n", tempword);
-}
-
-/*---------------------------------------------------------------------------
-
-  Function:   ft1000_disable_interrupts
-  Description: This function will disable all interrupts.
-  Input:
-  dev    - device structure
-  Output:
-  None.
-
-  -------------------------------------------------------------------------*/
-static void ft1000_disable_interrupts(struct net_device *dev)
-{
-       u16 tempword;
-
-       ft1000_write_reg(dev, FT1000_REG_SUP_IMASK, ISR_MASK_ALL);
-       tempword = ft1000_read_reg(dev, FT1000_REG_SUP_IMASK);
-       pr_debug("current interrupt enable mask = 0x%x\n", tempword);
-}
-
-/*---------------------------------------------------------------------------
-  Function:    ft1000_read_dsp_timer
-  Description: This function reads the DSP timer and stores its value in the
-               DSP_TIME field of the ft1000_info struct passed as argument
-  Input:
-  dev    - device structure
-  info   - ft1000_info structure
-  Output:
-  None.
-
-  -------------------------------------------------------------------------*/
-static void ft1000_read_dsp_timer(struct net_device *dev,
-                                 struct ft1000_info *info)
-{
-       if (info->AsicID == ELECTRABUZZ_ID) {
-               info->DSP_TIME[0] = ft1000_read_dpram(dev, FT1000_DSP_TIMER0);
-               info->DSP_TIME[1] = ft1000_read_dpram(dev, FT1000_DSP_TIMER1);
-               info->DSP_TIME[2] = ft1000_read_dpram(dev, FT1000_DSP_TIMER2);
-               info->DSP_TIME[3] = ft1000_read_dpram(dev, FT1000_DSP_TIMER3);
-       } else {
-               info->DSP_TIME[0] =
-                       ft1000_read_dpram_mag_16(dev, FT1000_MAG_DSP_TIMER0,
-                                                FT1000_MAG_DSP_TIMER0_INDX);
-               info->DSP_TIME[1] =
-                       ft1000_read_dpram_mag_16(dev, FT1000_MAG_DSP_TIMER1,
-                                                FT1000_MAG_DSP_TIMER1_INDX);
-               info->DSP_TIME[2] =
-                       ft1000_read_dpram_mag_16(dev, FT1000_MAG_DSP_TIMER2,
-                                                FT1000_MAG_DSP_TIMER2_INDX);
-               info->DSP_TIME[3] =
-                       ft1000_read_dpram_mag_16(dev, FT1000_MAG_DSP_TIMER3,
-                                                FT1000_MAG_DSP_TIMER3_INDX);
-       }
-}
-
-/*---------------------------------------------------------------------------
-
-  Function:   ft1000_reset_asic
-  Description: This function will call the Card Service function to reset the
-  ASIC.
-  Input:
-  dev    - device structure
-  Output:
-  none
-
-  -------------------------------------------------------------------------*/
-static void ft1000_reset_asic(struct net_device *dev)
-{
-       struct ft1000_info *info = netdev_priv(dev);
-       struct ft1000_pcmcia *pcmcia = info->priv;
-       u16 tempword;
-
-       (*info->ft1000_reset) (pcmcia->link);
-
-       /*
-        * Let's use the register provided by the Magnemite ASIC to reset the
-        * ASIC and DSP.
-        */
-       if (info->AsicID == MAGNEMITE_ID) {
-               ft1000_write_reg(dev, FT1000_REG_RESET,
-                                DSP_RESET_BIT | ASIC_RESET_BIT);
-       }
-       mdelay(1);
-       if (info->AsicID == ELECTRABUZZ_ID) {
-               /* set watermark to -1 in order to not generate an interrupt */
-               ft1000_write_reg(dev, FT1000_REG_WATERMARK, 0xffff);
-       } else {
-               /* set watermark to -1 in order to not generate an interrupt */
-               ft1000_write_reg(dev, FT1000_REG_MAG_WATERMARK, 0xffff);
-       }
-       /* clear interrupts */
-       tempword = ft1000_read_reg(dev, FT1000_REG_SUP_ISR);
-       pr_debug("interrupt status register = 0x%x\n", tempword);
-       ft1000_write_reg(dev, FT1000_REG_SUP_ISR, tempword);
-       tempword = ft1000_read_reg(dev, FT1000_REG_SUP_ISR);
-       pr_debug("interrupt status register = 0x%x\n", tempword);
-
-}
-
-/*---------------------------------------------------------------------------
-
-  Function:   ft1000_reset_card
-  Description: This function will reset the card
-  Input:
-  dev    - device structure
-  Output:
-  status - false (card reset fail)
-  true  (card reset successful)
-
-  -------------------------------------------------------------------------*/
-static int ft1000_reset_card(struct net_device *dev)
-{
-       struct ft1000_info *info = netdev_priv(dev);
-       u16 tempword;
-       int i;
-       unsigned long flags;
-       struct prov_record *ptr;
-       struct prov_record *tmp;
-
-       info->CardReady = 0;
-       info->ProgConStat = 0;
-       info->squeseqnum = 0;
-       ft1000_disable_interrupts(dev);
-
-       /* del_timer(&poll_timer); */
-
-       /* Make sure we free any memory reserve for provisioning */
-       list_for_each_entry_safe(ptr, tmp, &info->prov_list, list) {
-               pr_debug("deleting provisioning record\n");
-               list_del(&ptr->list);
-               kfree(ptr->pprov_data);
-               kfree(ptr);
-       }
-
-       if (info->AsicID == ELECTRABUZZ_ID) {
-               pr_debug("resetting DSP\n");
-               ft1000_write_reg(dev, FT1000_REG_RESET, DSP_RESET_BIT);
-       } else {
-               pr_debug("resetting ASIC and DSP\n");
-               ft1000_write_reg(dev, FT1000_REG_RESET,
-                                DSP_RESET_BIT | ASIC_RESET_BIT);
-       }
-
-       /* Copy DSP session record into info block if this is not a coldstart */
-       if (ft1000_card_present == 1) {
-               spin_lock_irqsave(&info->dpram_lock, flags);
-               if (info->AsicID == ELECTRABUZZ_ID) {
-                       ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR,
-                                        FT1000_DPRAM_RX_BASE);
-                       for (i = 0; i < MAX_DSP_SESS_REC; i++) {
-                               info->DSPSess.Rec[i] =
-                                       ft1000_read_reg(dev,
-                                                       FT1000_REG_DPRAM_DATA);
-                       }
-               } else {
-                       ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR,
-                                        FT1000_DPRAM_MAG_RX_BASE);
-                       for (i = 0; i < MAX_DSP_SESS_REC / 2; i++) {
-                               info->DSPSess.MagRec[i] =
-                                       inl(dev->base_addr
-                                               + FT1000_REG_MAG_DPDATA);
-                       }
-               }
-               spin_unlock_irqrestore(&info->dpram_lock, flags);
-       }
-
-       pr_debug("resetting ASIC\n");
-       mdelay(10);
-       /* reset ASIC */
-       ft1000_reset_asic(dev);
-
-       pr_debug("downloading dsp image\n");
-
-       if (info->AsicID == MAGNEMITE_ID) {
-               /* Put dsp in reset and take ASIC out of reset */
-               pr_debug("Put DSP in reset and take ASIC out of reset\n");
-               ft1000_write_reg(dev, FT1000_REG_RESET, DSP_RESET_BIT);
-
-               /* Setting MAGNEMITE ASIC to big endian mode */
-               ft1000_write_reg(dev, FT1000_REG_SUP_CTRL, HOST_INTF_BE);
-               /* Download bootloader */
-               card_bootload(dev);
-
-               /* Take DSP out of reset */
-               ft1000_write_reg(dev, FT1000_REG_RESET, 0);
-               /* FLARION_DSP_ACTIVE; */
-               mdelay(10);
-               pr_debug("Take DSP out of reset\n");
-
-               /*
-                * Wait for 0xfefe indicating dsp ready before starting
-                * download
-                */
-               for (i = 0; i < 50; i++) {
-                       tempword = ft1000_read_dpram_mag_16(dev,
-                                               FT1000_MAG_DPRAM_FEFE,
-                                               FT1000_MAG_DPRAM_FEFE_INDX);
-                       if (tempword == 0xfefe)
-                               break;
-                       mdelay(20);
-               }
-
-               if (i == 50) {
-                       pr_debug("No FEFE detected from DSP\n");
-                       return false;
-               }
-
-       } else {
-               /* Take DSP out of reset */
-               ft1000_write_reg(dev, FT1000_REG_RESET, ~DSP_RESET_BIT);
-               mdelay(10);
-       }
-
-       if (card_download(dev, fw_entry->data, fw_entry->size)) {
-               pr_debug("card download unsuccessful\n");
-               return false;
-       }
-       pr_debug("card download successful\n");
-
-       mdelay(10);
-
-       if (info->AsicID == ELECTRABUZZ_ID) {
-               /*
-                * Need to initialize the FIFO length counter to zero in order
-                * to sync up with the DSP
-                */
-               info->fifo_cnt = 0;
-               ft1000_write_dpram(dev, FT1000_FIFO_LEN, info->fifo_cnt);
-               /* Initialize DSP heartbeat area to ho */
-               ft1000_write_dpram(dev, FT1000_HI_HO, ho);
-               tempword = ft1000_read_dpram(dev, FT1000_HI_HO);
-               pr_debug("hi_ho value = 0x%x\n", tempword);
-       } else {
-               /* Initialize DSP heartbeat area to ho */
-               ft1000_write_dpram_mag_16(dev, FT1000_MAG_HI_HO, ho_mag,
-                                         FT1000_MAG_HI_HO_INDX);
-               tempword =
-                       ft1000_read_dpram_mag_16(dev, FT1000_MAG_HI_HO,
-                                                FT1000_MAG_HI_HO_INDX);
-               pr_debug("hi_ho value = 0x%x\n", tempword);
-       }
-
-       info->CardReady = 1;
-       ft1000_enable_interrupts(dev);
-
-       /* Schedule heartbeat process to run every 2 seconds */
-       /* poll_timer.expires = jiffies + (2*HZ); */
-       /* poll_timer.data = (u_long)dev; */
-       /* add_timer(&poll_timer); */
-
-       return true;
-
-}
-
-/*---------------------------------------------------------------------------
-
-  Function:   ft1000_chkcard
-  Description: This function will check if the device is presently available on
-  the system.
-  Input:
-  dev    - device structure
-  Output:
-  status - false (device is not present)
-  true  (device is present)
-
-  -------------------------------------------------------------------------*/
-static int ft1000_chkcard(struct net_device *dev)
-{
-       u16 tempword;
-
-       /*
-        * Mask register is used to check for device presence since it is never
-        * set to zero.
-        */
-       tempword = ft1000_read_reg(dev, FT1000_REG_SUP_IMASK);
-       if (tempword == 0) {
-               pr_debug("IMASK = 0 Card not detected\n");
-               return false;
-       }
-       /*
-        * The system will return the value of 0xffff for the version register
-        * if the device is not present.
-        */
-       tempword = ft1000_read_reg(dev, FT1000_REG_ASIC_ID);
-       if (tempword == 0xffff) {
-               pr_debug("Version = 0xffff Card not detected\n");
-               return false;
-       }
-       return true;
-}
-
-
-/*---------------------------------------------------------------------------
-
-  Function:   ft1000_hbchk
-  Description: This function will perform the heart beat check of the DSP as
-  well as the ASIC.
-  Input:
-  dev    - device structure
-  Output:
-  none
-
-  -------------------------------------------------------------------------*/
-static void ft1000_hbchk(u_long data)
-{
-       struct net_device *dev = (struct net_device *)data;
-
-       struct ft1000_info *info;
-       u16 tempword;
-
-       info = netdev_priv(dev);
-
-       if (info->CardReady == 1) {
-               /* Perform dsp heartbeat check */
-               if (info->AsicID == ELECTRABUZZ_ID) {
-                       tempword = ft1000_read_dpram(dev, FT1000_HI_HO);
-               } else {
-                       tempword =
-                               ntohs(ft1000_read_dpram_mag_16
-                                     (dev, FT1000_MAG_HI_HO,
-                                      FT1000_MAG_HI_HO_INDX));
-               }
-               pr_debug("hi_ho value = 0x%x\n", tempword);
-               /* Let's perform another check if ho is not detected */
-               if (tempword != ho) {
-                       if (info->AsicID == ELECTRABUZZ_ID)
-                               tempword = ft1000_read_dpram(dev, FT1000_HI_HO);
-                       else
-                               tempword = ntohs(ft1000_read_dpram_mag_16(dev,
-                                                       FT1000_MAG_HI_HO,
-                                                       FT1000_MAG_HI_HO_INDX));
-               }
-               if (tempword != ho) {
-                       pr_info("heartbeat failed - no ho detected\n");
-                       ft1000_read_dsp_timer(dev, info);
-                       info->DrvErrNum = DSP_HB_INFO;
-                       if (ft1000_reset_card(dev) == 0) {
-                               pr_info("Hardware Failure Detected - PC Card disabled\n");
-                               info->ProgConStat = 0xff;
-                               return;
-                       }
-                       /* Schedule this module to run every 2 seconds */
-                       poll_timer.expires = jiffies + (2*HZ);
-                       poll_timer.data = (u_long)dev;
-                       add_timer(&poll_timer);
-                       return;
-               }
-
-               tempword = ft1000_read_reg(dev, FT1000_REG_DOORBELL);
-               /* Let's check doorbell again if fail */
-               if (tempword & FT1000_DB_HB)
-                       tempword = ft1000_read_reg(dev, FT1000_REG_DOORBELL);
-
-               if (tempword & FT1000_DB_HB) {
-                       pr_info("heartbeat doorbell not clear by firmware\n");
-                       ft1000_read_dsp_timer(dev, info);
-                       info->DrvErrNum = DSP_HB_INFO;
-                       if (ft1000_reset_card(dev) == 0) {
-                               pr_info("Hardware Failure Detected - PC Card disabled\n");
-                               info->ProgConStat = 0xff;
-                               return;
-                       }
-                       /* Schedule this module to run every 2 seconds */
-                       poll_timer.expires = jiffies + (2*HZ);
-                       poll_timer.data = (u_long)dev;
-                       add_timer(&poll_timer);
-                       return;
-               }
-               /*
-                * Set dedicated area to hi and ring appropriate doorbell
-                * according to hi/ho heartbeat protocol
-                */
-               if (info->AsicID == ELECTRABUZZ_ID) {
-                       ft1000_write_dpram(dev, FT1000_HI_HO, hi);
-               } else {
-                       ft1000_write_dpram_mag_16(dev, FT1000_MAG_HI_HO, hi_mag,
-                                                 FT1000_MAG_HI_HO_INDX);
-               }
-
-               if (info->AsicID == ELECTRABUZZ_ID) {
-                       tempword = ft1000_read_dpram(dev, FT1000_HI_HO);
-               } else {
-                       tempword =
-                               ntohs(ft1000_read_dpram_mag_16
-                                     (dev, FT1000_MAG_HI_HO,
-                                      FT1000_MAG_HI_HO_INDX));
-               }
-               /* Let's write hi again if fail */
-               if (tempword != hi) {
-                       if (info->AsicID == ELECTRABUZZ_ID)
-                               ft1000_write_dpram(dev, FT1000_HI_HO, hi);
-                       else
-                               ft1000_write_dpram_mag_16(dev, FT1000_MAG_HI_HO,
-                                               hi_mag, FT1000_MAG_HI_HO_INDX);
-
-                       if (info->AsicID == ELECTRABUZZ_ID)
-                               tempword = ft1000_read_dpram(dev, FT1000_HI_HO);
-                       else
-                               tempword = ntohs(ft1000_read_dpram_mag_16(dev,
-                                                       FT1000_MAG_HI_HO,
-                                                       FT1000_MAG_HI_HO_INDX));
-               }
-
-               if (tempword != hi) {
-                       pr_info("heartbeat failed - cannot write hi into DPRAM\n");
-                       ft1000_read_dsp_timer(dev, info);
-                       info->DrvErrNum = DSP_HB_INFO;
-                       if (ft1000_reset_card(dev) == 0) {
-                               pr_info("Hardware Failure Detected - PC Card disabled\n");
-                               info->ProgConStat = 0xff;
-                               return;
-                       }
-                       /* Schedule this module to run every 2 seconds */
-                       poll_timer.expires = jiffies + (2*HZ);
-                       poll_timer.data = (u_long)dev;
-                       add_timer(&poll_timer);
-                       return;
-               }
-               ft1000_write_reg(dev, FT1000_REG_DOORBELL, FT1000_DB_HB);
-
-       }
-
-       /* Schedule this module to run every 2 seconds */
-       poll_timer.expires = jiffies + (2 * HZ);
-       poll_timer.data = (u_long)dev;
-       add_timer(&poll_timer);
-}
-
-/*---------------------------------------------------------------------------
-
-  Function:   ft1000_send_cmd
-  Description:
-  Input:
-  Output:
-
-  -------------------------------------------------------------------------*/
-static void ft1000_send_cmd(struct net_device *dev, u16 *ptempbuffer, int size,
-                           u16 qtype)
-{
-       struct ft1000_info *info = netdev_priv(dev);
-       int i;
-       u16 tempword;
-       unsigned long flags;
-
-       size += sizeof(struct pseudo_hdr);
-       /* check for odd byte and increment to 16-bit word align value */
-       if ((size & 0x0001))
-               size++;
-       pr_debug("total length = %d\n", size);
-       pr_debug("length = %d\n", ntohs(*ptempbuffer));
-       /*
-        * put message into slow queue area
-        * All messages are in the form total_len + pseudo header + message body
-        */
-       spin_lock_irqsave(&info->dpram_lock, flags);
-
-       /* Make sure SLOWQ doorbell is clear */
-       tempword = ft1000_read_reg(dev, FT1000_REG_DOORBELL);
-       i = 0;
-       while (tempword & FT1000_DB_DPRAM_TX) {
-               mdelay(10);
-               i++;
-               if (i == 10) {
-                       spin_unlock_irqrestore(&info->dpram_lock, flags);
-                       return;
-               }
-               tempword = ft1000_read_reg(dev, FT1000_REG_DOORBELL);
-       }
-
-       if (info->AsicID == ELECTRABUZZ_ID) {
-               ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR,
-                                FT1000_DPRAM_TX_BASE);
-               /* Write total length to dpram */
-               ft1000_write_reg(dev, FT1000_REG_DPRAM_DATA, size);
-               /* Write pseudo header and messgae body */
-               for (i = 0; i < (size >> 1); i++) {
-                       pr_debug("data %d = 0x%x\n", i, *ptempbuffer);
-                       tempword = htons(*ptempbuffer++);
-                       ft1000_write_reg(dev, FT1000_REG_DPRAM_DATA, tempword);
-               }
-       } else {
-               ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR,
-                                FT1000_DPRAM_MAG_TX_BASE);
-               /* Write total length to dpram */
-               ft1000_write_reg(dev, FT1000_REG_MAG_DPDATAH, htons(size));
-               /* Write pseudo header and messgae body */
-               ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR,
-                                FT1000_DPRAM_MAG_TX_BASE + 1);
-               for (i = 0; i < (size >> 2); i++) {
-                       pr_debug("data = 0x%x\n", *ptempbuffer);
-                       outw(*ptempbuffer++,
-                            dev->base_addr + FT1000_REG_MAG_DPDATAL);
-                       pr_debug("data = 0x%x\n", *ptempbuffer);
-                       outw(*ptempbuffer++,
-                            dev->base_addr + FT1000_REG_MAG_DPDATAH);
-               }
-               pr_debug("data = 0x%x\n", *ptempbuffer);
-               outw(*ptempbuffer++, dev->base_addr + FT1000_REG_MAG_DPDATAL);
-               pr_debug("data = 0x%x\n", *ptempbuffer);
-               outw(*ptempbuffer++, dev->base_addr + FT1000_REG_MAG_DPDATAH);
-       }
-       spin_unlock_irqrestore(&info->dpram_lock, flags);
-
-       /* ring doorbell to notify DSP that we have a message ready */
-       ft1000_write_reg(dev, FT1000_REG_DOORBELL, FT1000_DB_DPRAM_TX);
-}
-
-/*---------------------------------------------------------------------------
-
-  Function:   ft1000_receive_cmd
-  Description: This function will read a message from the dpram area.
-  Input:
-  dev - network device structure
-  pbuffer - caller supply address to buffer
-  pnxtph - pointer to next pseudo header
-  Output:
-  Status = 0 (unsuccessful)
-  = 1 (successful)
-
-  -------------------------------------------------------------------------*/
-static bool ft1000_receive_cmd(struct net_device *dev, u16 *pbuffer,
-                              int maxsz, u16 *pnxtph)
-{
-       struct ft1000_info *info = netdev_priv(dev);
-       u16 size;
-       u16 *ppseudohdr;
-       int i;
-       u16 tempword;
-       unsigned long flags;
-
-       if (info->AsicID == ELECTRABUZZ_ID) {
-               size = ft1000_read_dpram(dev, *pnxtph)
-                       + sizeof(struct pseudo_hdr);
-       } else {
-               size = ntohs(ft1000_read_dpram_mag_16(dev, FT1000_MAG_PH_LEN,
-                                                     FT1000_MAG_PH_LEN_INDX))
-                               + sizeof(struct pseudo_hdr);
-       }
-       if (size > maxsz) {
-               pr_debug("Invalid command length = %d\n", size);
-               return false;
-       }
-       ppseudohdr = (u16 *)pbuffer;
-       spin_lock_irqsave(&info->dpram_lock, flags);
-       if (info->AsicID == ELECTRABUZZ_ID) {
-               ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR,
-                                FT1000_DPRAM_RX_BASE + 2);
-               for (i = 0; i <= (size >> 1); i++) {
-                       tempword =
-                               ft1000_read_reg(dev, FT1000_REG_DPRAM_DATA);
-                       *pbuffer++ = ntohs(tempword);
-               }
-       } else {
-               ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR,
-                                FT1000_DPRAM_MAG_RX_BASE);
-               *pbuffer = inw(dev->base_addr + FT1000_REG_MAG_DPDATAH);
-               pr_debug("received data = 0x%x\n", *pbuffer);
-               pbuffer++;
-               ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR,
-                                FT1000_DPRAM_MAG_RX_BASE + 1);
-               for (i = 0; i <= (size >> 2); i++) {
-                       *pbuffer =
-                               inw(dev->base_addr +
-                                   FT1000_REG_MAG_DPDATAL);
-                       pbuffer++;
-                       *pbuffer =
-                               inw(dev->base_addr +
-                                   FT1000_REG_MAG_DPDATAH);
-                       pbuffer++;
-               }
-               /* copy odd aligned word */
-               *pbuffer = inw(dev->base_addr + FT1000_REG_MAG_DPDATAL);
-               pr_debug("received data = 0x%x\n", *pbuffer);
-               pbuffer++;
-               *pbuffer = inw(dev->base_addr + FT1000_REG_MAG_DPDATAH);
-               pr_debug("received data = 0x%x\n", *pbuffer);
-               pbuffer++;
-       }
-       if (size & 0x0001) {
-               /* copy odd byte from fifo */
-               tempword = ft1000_read_reg(dev, FT1000_REG_DPRAM_DATA);
-               *pbuffer = ntohs(tempword);
-       }
-       spin_unlock_irqrestore(&info->dpram_lock, flags);
-
-       /*
-        * Check if pseudo header checksum is good
-        * Calculate pseudo header checksum
-        */
-       tempword = *ppseudohdr++;
-       for (i = 1; i < 7; i++)
-               tempword ^= *ppseudohdr++;
-       if (tempword != *ppseudohdr) {
-               pr_debug("Pseudo header checksum mismatch\n");
-               /* Drop this message */
-               return false;
-       }
-       return true;
-}
-
-/*---------------------------------------------------------------------------
-
-  Function:   ft1000_proc_drvmsg
-  Description: This function will process the various driver messages.
-  Input:
-  dev    - device structure
-  pnxtph - pointer to next pseudo header
-  Output:
-  none
-
-  -------------------------------------------------------------------------*/
-static void ft1000_proc_drvmsg(struct net_device *dev)
-{
-       struct ft1000_info *info = netdev_priv(dev);
-       u16 msgtype;
-       u16 tempword;
-       struct media_msg *pmediamsg;
-       struct dsp_init_msg *pdspinitmsg;
-       struct drv_msg *pdrvmsg;
-       u16 len;
-       u16 i;
-       struct prov_record *ptr;
-       struct pseudo_hdr *ppseudo_hdr;
-       u16 *pmsg;
-       struct timeval tv;
-       union {
-               u8 byte[2];
-               u16 wrd;
-       } convert;
-
-       if (info->AsicID == ELECTRABUZZ_ID)
-               tempword = FT1000_DPRAM_RX_BASE+2;
-       else
-               tempword = FT1000_DPRAM_MAG_RX_BASE;
-
-       if (ft1000_receive_cmd(dev, &cmdbuffer[0], MAX_CMD_SQSIZE, &tempword)) {
-
-               /*
-                * Get the message type which is total_len + PSEUDO header
-                * + msgtype + message body
-                */
-               pdrvmsg = (struct drv_msg *)&cmdbuffer[0];
-               msgtype = ntohs(pdrvmsg->type);
-               pr_debug("Command message type = 0x%x\n", msgtype);
-               switch (msgtype) {
-               case DSP_PROVISION:
-                       pr_debug("Got a provisioning request message from DSP\n");
-                       mdelay(25);
-                       while (list_empty(&info->prov_list) == 0) {
-                               pr_debug("Sending a provisioning message\n");
-                               /* Make sure SLOWQ doorbell is clear */
-                               tempword = ft1000_read_reg(dev,
-                                                          FT1000_REG_DOORBELL);
-                               i = 0;
-                               while (tempword & FT1000_DB_DPRAM_TX) {
-                                       mdelay(5);
-                                       i++;
-                                       if (i == 10)
-                                               break;
-                               }
-                               ptr = list_entry(info->prov_list.next,
-                                                struct prov_record, list);
-                               len = *(u16 *)ptr->pprov_data;
-                               len = htons(len);
-
-                               pmsg = (u16 *)ptr->pprov_data;
-                               ppseudo_hdr = (struct pseudo_hdr *)pmsg;
-                               /* Insert slow queue sequence number */
-                               ppseudo_hdr->seq_num = info->squeseqnum++;
-                               ppseudo_hdr->portsrc = 0;
-                               /* Calculate new checksum */
-                               ppseudo_hdr->checksum = *pmsg++;
-                               pr_debug("checksum = 0x%x\n",
-                                        ppseudo_hdr->checksum);
-                               for (i = 1; i < 7; i++) {
-                                       ppseudo_hdr->checksum ^= *pmsg++;
-                                       pr_debug("checksum = 0x%x\n",
-                                                ppseudo_hdr->checksum);
-                               }
-
-                               ft1000_send_cmd(dev, (u16 *)ptr->pprov_data,
-                                               len, SLOWQ_TYPE);
-                               list_del(&ptr->list);
-                               kfree(ptr->pprov_data);
-                               kfree(ptr);
-                       }
-                       /*
-                        * Indicate adapter is ready to take application
-                        * messages after all provisioning messages are sent
-                        */
-                       info->CardReady = 1;
-                       break;
-               case MEDIA_STATE:
-                       pmediamsg = (struct media_msg *)&cmdbuffer[0];
-                       if (info->ProgConStat != 0xFF) {
-                               if (pmediamsg->state) {
-                                       pr_debug("Media is up\n");
-                                       if (info->mediastate == 0) {
-                                               netif_carrier_on(dev);
-                                               netif_wake_queue(dev);
-                                               info->mediastate = 1;
-                                               do_gettimeofday(&tv);
-                                               info->ConTm = tv.tv_sec;
-                                       }
-                               } else {
-                                       pr_debug("Media is down\n");
-                                       if (info->mediastate == 1) {
-                                               info->mediastate = 0;
-                                               netif_carrier_off(dev);
-                                               netif_stop_queue(dev);
-                                               info->ConTm = 0;
-                                       }
-                               }
-                       } else {
-                               pr_debug("Media is down\n");
-                               if (info->mediastate == 1) {
-                                       info->mediastate = 0;
-                                       netif_carrier_off(dev);
-                                       netif_stop_queue(dev);
-                                       info->ConTm = 0;
-                               }
-                       }
-                       break;
-               case DSP_INIT_MSG:
-                       pdspinitmsg = (struct dsp_init_msg *)&cmdbuffer[0];
-                       memcpy(info->DspVer, pdspinitmsg->DspVer, DSPVERSZ);
-                       pr_debug("DSPVER = 0x%2x 0x%2x 0x%2x 0x%2x\n",
-                                info->DspVer[0], info->DspVer[1],
-                                info->DspVer[2], info->DspVer[3]);
-                       memcpy(info->HwSerNum, pdspinitmsg->HwSerNum,
-                              HWSERNUMSZ);
-                       memcpy(info->Sku, pdspinitmsg->Sku, SKUSZ);
-                       memcpy(info->eui64, pdspinitmsg->eui64, EUISZ);
-                       dev->dev_addr[0] = info->eui64[0];
-                       dev->dev_addr[1] = info->eui64[1];
-                       dev->dev_addr[2] = info->eui64[2];
-                       dev->dev_addr[3] = info->eui64[5];
-                       dev->dev_addr[4] = info->eui64[6];
-                       dev->dev_addr[5] = info->eui64[7];
-
-                       if (ntohs(pdspinitmsg->length) ==
-                           (sizeof(struct dsp_init_msg) - 20)) {
-                               memcpy(info->ProductMode,
-                                      pdspinitmsg->ProductMode, MODESZ);
-                               memcpy(info->RfCalVer, pdspinitmsg->RfCalVer,
-                                      CALVERSZ);
-                               memcpy(info->RfCalDate, pdspinitmsg->RfCalDate,
-                                      CALDATESZ);
-                               pr_debug("RFCalVer = 0x%2x 0x%2x\n",
-                                        info->RfCalVer[0], info->RfCalVer[1]);
-                       }
-
-                       break;
-               case DSP_STORE_INFO:
-                       pr_debug("Got DSP_STORE_INFO\n");
-                       tempword = ntohs(pdrvmsg->length);
-                       info->DSPInfoBlklen = tempword;
-                       if (tempword < (MAX_DSP_SESS_REC - 4)) {
-                               pmsg = (u16 *)&pdrvmsg->data[0];
-                               for (i = 0; i < ((tempword + 1) / 2); i++) {
-                                       pr_debug("dsp info data = 0x%x\n",
-                                                *pmsg);
-                                       info->DSPInfoBlk[i + 10] = *pmsg++;
-                               }
-                       }
-                       break;
-               case DSP_GET_INFO:
-                       pr_debug("Got DSP_GET_INFO\n");
-                       /*
-                        * copy dsp info block to dsp
-                        * allow any outstanding ioctl to finish
-                        */
-                       mdelay(10);
-                       tempword = ft1000_read_reg(dev, FT1000_REG_DOORBELL);
-                       if (tempword & FT1000_DB_DPRAM_TX) {
-                               mdelay(10);
-                               tempword = ft1000_read_reg(dev,
-                                                          FT1000_REG_DOORBELL);
-                               if (tempword & FT1000_DB_DPRAM_TX)
-                                       mdelay(10);
-                       }
-
-                       if ((tempword & FT1000_DB_DPRAM_TX) == 0) {
-                               /*
-                                * Put message into Slow Queue
-                                * Form Pseudo header
-                                */
-                               pmsg = (u16 *)info->DSPInfoBlk;
-                               ppseudo_hdr = (struct pseudo_hdr *)pmsg;
-                               ppseudo_hdr->length =
-                                       htons(info->DSPInfoBlklen + 4);
-                               ppseudo_hdr->source = 0x10;
-                               ppseudo_hdr->destination = 0x20;
-                               ppseudo_hdr->portdest = 0;
-                               ppseudo_hdr->portsrc = 0;
-                               ppseudo_hdr->sh_str_id = 0;
-                               ppseudo_hdr->control = 0;
-                               ppseudo_hdr->rsvd1 = 0;
-                               ppseudo_hdr->rsvd2 = 0;
-                               ppseudo_hdr->qos_class = 0;
-                               /* Insert slow queue sequence number */
-                               ppseudo_hdr->seq_num = info->squeseqnum++;
-                               /* Insert application id */
-                               ppseudo_hdr->portsrc = 0;
-                               /* Calculate new checksum */
-                               ppseudo_hdr->checksum = *pmsg++;
-                               for (i = 1; i < 7; i++)
-                                       ppseudo_hdr->checksum ^= *pmsg++;
-
-                               info->DSPInfoBlk[8] = 0x7200;
-                               info->DSPInfoBlk[9] =
-                                       htons(info->DSPInfoBlklen);
-                               ft1000_send_cmd(dev, info->DSPInfoBlk,
-                                               (u16)(info->DSPInfoBlklen+4),
-                                               0);
-                       }
-
-                       break;
-               case GET_DRV_ERR_RPT_MSG:
-                       pr_debug("Got GET_DRV_ERR_RPT_MSG\n");
-                       /*
-                        * copy driver error message to dsp
-                        * allow any outstanding ioctl to finish
-                        */
-                       mdelay(10);
-                       tempword = ft1000_read_reg(dev, FT1000_REG_DOORBELL);
-                       if (tempword & FT1000_DB_DPRAM_TX) {
-                               mdelay(10);
-                               tempword = ft1000_read_reg(dev,
-                                                          FT1000_REG_DOORBELL);
-                               if (tempword & FT1000_DB_DPRAM_TX)
-                                       mdelay(10);
-                       }
-
-                       if ((tempword & FT1000_DB_DPRAM_TX) == 0) {
-                               /*
-                                * Put message into Slow Queue
-                                * Form Pseudo header
-                                */
-                               pmsg = (u16 *)&tempbuffer[0];
-                               ppseudo_hdr = (struct pseudo_hdr *)pmsg;
-                               ppseudo_hdr->length = htons(0x0012);
-                               ppseudo_hdr->source = 0x10;
-                               ppseudo_hdr->destination = 0x20;
-                               ppseudo_hdr->portdest = 0;
-                               ppseudo_hdr->portsrc = 0;
-                               ppseudo_hdr->sh_str_id = 0;
-                               ppseudo_hdr->control = 0;
-                               ppseudo_hdr->rsvd1 = 0;
-                               ppseudo_hdr->rsvd2 = 0;
-                               ppseudo_hdr->qos_class = 0;
-                               /* Insert slow queue sequence number */
-                               ppseudo_hdr->seq_num = info->squeseqnum++;
-                               /* Insert application id */
-                               ppseudo_hdr->portsrc = 0;
-                               /* Calculate new checksum */
-                               ppseudo_hdr->checksum = *pmsg++;
-                               for (i = 1; i < 7; i++)
-                                       ppseudo_hdr->checksum ^= *pmsg++;
-
-                               pmsg = (u16 *)&tempbuffer[16];
-                               *pmsg++ = htons(RSP_DRV_ERR_RPT_MSG);
-                               *pmsg++ = htons(0x000e);
-                               *pmsg++ = htons(info->DSP_TIME[0]);
-                               *pmsg++ = htons(info->DSP_TIME[1]);
-                               *pmsg++ = htons(info->DSP_TIME[2]);
-                               *pmsg++ = htons(info->DSP_TIME[3]);
-                               convert.byte[0] = info->DspVer[0];
-                               convert.byte[1] = info->DspVer[1];
-                               *pmsg++ = convert.wrd;
-                               convert.byte[0] = info->DspVer[2];
-                               convert.byte[1] = info->DspVer[3];
-                               *pmsg++ = convert.wrd;
-                               *pmsg++ = htons(info->DrvErrNum);
-
-                               ft1000_send_cmd(dev, (u16 *)&tempbuffer[0],
-                                               (u16)(0x0012), 0);
-                               info->DrvErrNum = 0;
-                       }
-
-                       break;
-               default:
-                       break;
-               }
-       }
-}
-
-/*---------------------------------------------------------------------------
-
-  Function:   ft1000_parse_dpram_msg
-  Description: This function will parse the message received from the DSP
-  via the DPRAM interface.
-  Input:
-  dev    - device structure
-  Output:
-  status - FAILURE
-  SUCCESS
-
-  -------------------------------------------------------------------------*/
-static int ft1000_parse_dpram_msg(struct net_device *dev)
-{
-       struct ft1000_info *info = netdev_priv(dev);
-       u16 doorbell;
-       u16 portid;
-       u16 nxtph;
-       u16 total_len;
-       int i = 0;
-       unsigned long flags;
-
-       doorbell = ft1000_read_reg(dev, FT1000_REG_DOORBELL);
-       pr_debug("Doorbell = 0x%x\n", doorbell);
-
-       if (doorbell & FT1000_ASIC_RESET_REQ) {
-               /* Copy DSP session record from info block */
-               spin_lock_irqsave(&info->dpram_lock, flags);
-               if (info->AsicID == ELECTRABUZZ_ID) {
-                       ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR,
-                                        FT1000_DPRAM_RX_BASE);
-                       for (i = 0; i < MAX_DSP_SESS_REC; i++) {
-                               ft1000_write_reg(dev, FT1000_REG_DPRAM_DATA,
-                                                info->DSPSess.Rec[i]);
-                       }
-               } else {
-                       ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR,
-                                        FT1000_DPRAM_MAG_RX_BASE);
-                       for (i = 0; i < MAX_DSP_SESS_REC / 2; i++) {
-                               outl(info->DSPSess.MagRec[i],
-                                    dev->base_addr + FT1000_REG_MAG_DPDATA);
-                       }
-               }
-               spin_unlock_irqrestore(&info->dpram_lock, flags);
-
-               /* clear ASIC RESET request */
-               ft1000_write_reg(dev, FT1000_REG_DOORBELL,
-                                FT1000_ASIC_RESET_REQ);
-               pr_debug("Got an ASIC RESET Request\n");
-               ft1000_write_reg(dev, FT1000_REG_DOORBELL,
-                                FT1000_ASIC_RESET_DSP);
-
-               if (info->AsicID == MAGNEMITE_ID) {
-                       /* Setting MAGNEMITE ASIC to big endian mode */
-                       ft1000_write_reg(dev, FT1000_REG_SUP_CTRL,
-                                        HOST_INTF_BE);
-               }
-       }
-
-       if (doorbell & FT1000_DSP_ASIC_RESET) {
-               pr_debug("Got a dsp ASIC reset message\n");
-               ft1000_write_reg(dev, FT1000_REG_DOORBELL,
-                                FT1000_DSP_ASIC_RESET);
-               udelay(200);
-               return SUCCESS;
-       }
-
-       if (doorbell & FT1000_DB_DPRAM_RX) {
-               pr_debug("Got a slow queue message\n");
-               nxtph = FT1000_DPRAM_RX_BASE + 2;
-               if (info->AsicID == ELECTRABUZZ_ID) {
-                       total_len =
-                               ft1000_read_dpram(dev, FT1000_DPRAM_RX_BASE);
-               } else {
-                       total_len =
-                               ntohs(ft1000_read_dpram_mag_16
-                                     (dev, FT1000_MAG_TOTAL_LEN,
-                                      FT1000_MAG_TOTAL_LEN_INDX));
-               }
-               pr_debug("total length = %d\n", total_len);
-               if ((total_len < MAX_CMD_SQSIZE)
-                               && (total_len > sizeof(struct pseudo_hdr))) {
-                       total_len += nxtph;
-                       /*
-                        * ft1000_read_reg will return a value that needs to be
-                        * byteswap in order to get DSP_QID_OFFSET.
-                        */
-                       if (info->AsicID == ELECTRABUZZ_ID) {
-                               portid = (ft1000_read_dpram(dev, DSP_QID_OFFSET
-                                               + FT1000_DPRAM_RX_BASE + 2)
-                                               >> 8) & 0xff;
-                       } else {
-                               portid =
-                                       ft1000_read_dpram_mag_16
-                                        (dev, FT1000_MAG_PORT_ID,
-                                         FT1000_MAG_PORT_ID_INDX) & 0xff;
-                       }
-                       pr_debug("DSP_QID = 0x%x\n", portid);
-
-                       if (portid == DRIVERID) {
-                               /*
-                                * We are assumming one driver message from the
-                                * DSP at a time.
-                                */
-                               ft1000_proc_drvmsg(dev);
-                       }
-               }
-               ft1000_write_reg(dev, FT1000_REG_DOORBELL, FT1000_DB_DPRAM_RX);
-       }
-
-       if (doorbell & FT1000_DB_COND_RESET) {
-               /* Reset ASIC and DSP */
-               ft1000_read_dsp_timer(dev, info);
-               info->DrvErrNum = DSP_CONDRESET_INFO;
-               pr_debug("DSP conditional reset requested\n");
-               ft1000_reset_card(dev);
-               ft1000_write_reg(dev, FT1000_REG_DOORBELL,
-                                FT1000_DB_COND_RESET);
-       }
-       /* let's clear any unexpected doorbells from DSP */
-       doorbell =
-               doorbell & ~(FT1000_DB_DPRAM_RX | FT1000_ASIC_RESET_REQ |
-                            FT1000_DB_COND_RESET | 0xff00);
-       if (doorbell) {
-               pr_debug("Clearing unexpected doorbell = 0x%x\n", doorbell);
-               ft1000_write_reg(dev, FT1000_REG_DOORBELL, doorbell);
-       }
-
-       return SUCCESS;
-
-}
-
-/*---------------------------------------------------------------------------
-
-  Function:   ft1000_flush_fifo
-  Description: This function will flush one packet from the downlink
-  FIFO.
-  Input:
-  dev      - device structure
-  drv_err  - driver error causing the flush fifo
-  Output:
-  None.
-
-  -------------------------------------------------------------------------*/
-static void ft1000_flush_fifo(struct net_device *dev, u16 DrvErrNum)
-{
-       struct ft1000_info *info = netdev_priv(dev);
-       struct ft1000_pcmcia *pcmcia = info->priv;
-       u16 i;
-       u32 templong;
-       u16 tempword;
-
-       if (pcmcia->PktIntfErr > MAX_PH_ERR) {
-               ft1000_read_dsp_timer(dev, info);
-               info->DrvErrNum = DrvErrNum;
-               ft1000_reset_card(dev);
-               return;
-       }
-       /* Flush corrupted pkt from FIFO */
-       i = 0;
-       do {
-               if (info->AsicID == ELECTRABUZZ_ID) {
-                       tempword =
-                               ft1000_read_reg(dev, FT1000_REG_DFIFO);
-                       tempword =
-                               ft1000_read_reg(dev, FT1000_REG_DFIFO_STAT);
-               } else {
-                       templong =
-                               inl(dev->base_addr + FT1000_REG_MAG_DFR);
-                       tempword =
-                               inw(dev->base_addr + FT1000_REG_MAG_DFSR);
-               }
-               i++;
-               /*
-                * This should never happen unless the ASIC is broken.
-                * We must reset to recover.
-                */
-               if ((i > 2048) || (tempword == 0)) {
-                       ft1000_read_dsp_timer(dev, info);
-                       if (tempword == 0) {
-                               /*
-                                * Let's check if ASIC reads are still ok by
-                                * reading the Mask register which is never zero
-                                * at this point of the code.
-                                */
-                               tempword =
-                                       inw(dev->base_addr +
-                                           FT1000_REG_SUP_IMASK);
-                               if (tempword == 0) {
-                                       /*
-                                        * This indicates that we can not
-                                        * communicate with the ASIC
-                                        */
-                                       info->DrvErrNum = FIFO_FLUSH_BADCNT;
-                               } else {
-                                       /*
-                                        * Let's assume that we really flush
-                                        * the FIFO
-                                        */
-                                       pcmcia->PktIntfErr++;
-                                       return;
-                               }
-                       } else {
-                               info->DrvErrNum = FIFO_FLUSH_MAXLIMIT;
-                       }
-                       return;
-               }
-               tempword = inw(dev->base_addr + FT1000_REG_SUP_STAT);
-       } while ((tempword & 0x03) != 0x03);
-       if (info->AsicID == ELECTRABUZZ_ID) {
-               i++;
-               pr_debug("Flushing FIFO complete = %x\n", tempword);
-               /* Flush last word in FIFO. */
-               tempword = ft1000_read_reg(dev, FT1000_REG_DFIFO);
-               /* Update FIFO counter for DSP */
-               i = i * 2;
-               pr_debug("Flush Data byte count to dsp = %d\n", i);
-               info->fifo_cnt += i;
-               ft1000_write_dpram(dev, FT1000_FIFO_LEN,
-                                  info->fifo_cnt);
-       } else {
-               pr_debug("Flushing FIFO complete = %x\n", tempword);
-               /* Flush last word in FIFO */
-               templong = inl(dev->base_addr + FT1000_REG_MAG_DFR);
-               tempword = inw(dev->base_addr + FT1000_REG_SUP_STAT);
-               pr_debug("FT1000_REG_SUP_STAT = 0x%x\n", tempword);
-               tempword = inw(dev->base_addr + FT1000_REG_MAG_DFSR);
-               pr_debug("FT1000_REG_MAG_DFSR = 0x%x\n", tempword);
-       }
-       if (DrvErrNum)
-               pcmcia->PktIntfErr++;
-}
-
-/*---------------------------------------------------------------------------
-
-  Function:   ft1000_copy_up_pkt
-  Description: This function will pull Flarion packets out of the Downlink
-  FIFO and convert it to an ethernet packet.  The ethernet packet will
-  then be deliver to the TCP/IP stack.
-  Input:
-  dev    - device structure
-  Output:
-  status - FAILURE
-  SUCCESS
-
-  -------------------------------------------------------------------------*/
-static int ft1000_copy_up_pkt(struct net_device *dev)
-{
-       u16 tempword;
-       struct ft1000_info *info = netdev_priv(dev);
-       u16 len;
-       struct sk_buff *skb;
-       u16 i;
-       u8 *pbuffer = NULL;
-       u8 *ptemp = NULL;
-       u16 chksum;
-       u32 *ptemplong;
-       u32 templong;
-
-       /* Read length */
-       if (info->AsicID == ELECTRABUZZ_ID) {
-               tempword = ft1000_read_reg(dev, FT1000_REG_DFIFO);
-               len = tempword;
-       } else {
-               tempword = ft1000_read_reg(dev, FT1000_REG_MAG_DFRL);
-               len = ntohs(tempword);
-       }
-       chksum = tempword;
-       pr_debug("Number of Bytes in FIFO = %d\n", len);
-
-       if (len > ENET_MAX_SIZE) {
-               pr_debug("size of ethernet packet invalid\n");
-               if (info->AsicID == MAGNEMITE_ID) {
-                       /* Read High word to complete 32 bit access */
-                       tempword = ft1000_read_reg(dev, FT1000_REG_MAG_DFRH);
-               }
-               ft1000_flush_fifo(dev, DSP_PKTLEN_INFO);
-               info->stats.rx_errors++;
-               return FAILURE;
-       }
-
-       skb = dev_alloc_skb(len + 12 + 2);
-
-       if (skb == NULL) {
-               /* Read High word to complete 32 bit access */
-               if (info->AsicID == MAGNEMITE_ID)
-                       tempword = ft1000_read_reg(dev, FT1000_REG_MAG_DFRH);
-
-               ft1000_flush_fifo(dev, 0);
-               info->stats.rx_errors++;
-               return FAILURE;
-       }
-       pbuffer = (u8 *)skb_put(skb, len + 12);
-
-       /* Pseudo header */
-       if (info->AsicID == ELECTRABUZZ_ID) {
-               for (i = 1; i < 7; i++) {
-                       tempword = ft1000_read_reg(dev, FT1000_REG_DFIFO);
-                       chksum ^= tempword;
-               }
-               /* read checksum value */
-               tempword = ft1000_read_reg(dev, FT1000_REG_DFIFO);
-       } else {
-               tempword = ft1000_read_reg(dev, FT1000_REG_MAG_DFRH);
-               pr_debug("Pseudo = 0x%x\n", tempword);
-               chksum ^= tempword;
-
-               tempword = ft1000_read_reg(dev, FT1000_REG_MAG_DFRL);
-               pr_debug("Pseudo = 0x%x\n", tempword);
-               chksum ^= tempword;
-
-               tempword = ft1000_read_reg(dev, FT1000_REG_MAG_DFRH);
-               pr_debug("Pseudo = 0x%x\n", tempword);
-               chksum ^= tempword;
-
-               tempword = ft1000_read_reg(dev, FT1000_REG_MAG_DFRL);
-               pr_debug("Pseudo = 0x%x\n", tempword);
-               chksum ^= tempword;
-
-               tempword = ft1000_read_reg(dev, FT1000_REG_MAG_DFRH);
-               pr_debug("Pseudo = 0x%x\n", tempword);
-               chksum ^= tempword;
-
-               tempword = ft1000_read_reg(dev, FT1000_REG_MAG_DFRL);
-               pr_debug("Pseudo = 0x%x\n", tempword);
-               chksum ^= tempword;
-
-               /* read checksum value */
-               tempword = ft1000_read_reg(dev, FT1000_REG_MAG_DFRH);
-               pr_debug("Pseudo = 0x%x\n", tempword);
-       }
-
-       if (chksum != tempword) {
-               pr_debug("Packet checksum mismatch 0x%x 0x%x\n",
-                        chksum, tempword);
-               ft1000_flush_fifo(dev, DSP_PKTPHCKSUM_INFO);
-               info->stats.rx_errors++;
-               kfree_skb(skb);
-               return FAILURE;
-       }
-       /* subtract the number of bytes read already */
-       ptemp = pbuffer;
-
-       /* fake MAC address */
-       *pbuffer++ = dev->dev_addr[0];
-       *pbuffer++ = dev->dev_addr[1];
-       *pbuffer++ = dev->dev_addr[2];
-       *pbuffer++ = dev->dev_addr[3];
-       *pbuffer++ = dev->dev_addr[4];
-       *pbuffer++ = dev->dev_addr[5];
-       *pbuffer++ = 0x00;
-       *pbuffer++ = 0x07;
-       *pbuffer++ = 0x35;
-       *pbuffer++ = 0xff;
-       *pbuffer++ = 0xff;
-       *pbuffer++ = 0xfe;
-
-       if (info->AsicID == ELECTRABUZZ_ID) {
-               for (i = 0; i < len / 2; i++) {
-                       tempword = ft1000_read_reg(dev, FT1000_REG_DFIFO);
-                       *pbuffer++ = (u8) (tempword >> 8);
-                       *pbuffer++ = (u8)tempword;
-                       if (ft1000_chkcard(dev) == false) {
-                               kfree_skb(skb);
-                               return FAILURE;
-                       }
-               }
-
-               /* Need to read one more word if odd byte */
-               if (len & 0x0001) {
-                       tempword = ft1000_read_reg(dev, FT1000_REG_DFIFO);
-                       *pbuffer++ = (u8) (tempword >> 8);
-               }
-       } else {
-               ptemplong = (u32 *)pbuffer;
-               for (i = 0; i < len / 4; i++) {
-                       templong = inl(dev->base_addr + FT1000_REG_MAG_DFR);
-                       pr_debug("Data = 0x%8x\n", templong);
-                       *ptemplong++ = templong;
-               }
-
-               /* Need to read one more word if odd align. */
-               if (len & 0x0003) {
-                       templong = inl(dev->base_addr + FT1000_REG_MAG_DFR);
-                       pr_debug("Data = 0x%8x\n", templong);
-                       *ptemplong++ = templong;
-               }
-
-       }
-
-       pr_debug("Data passed to Protocol layer:\n");
-       for (i = 0; i < len + 12; i++)
-               pr_debug("Protocol Data: 0x%x\n", *ptemp++);
-
-       skb->dev = dev;
-       skb->protocol = eth_type_trans(skb, dev);
-       skb->ip_summed = CHECKSUM_UNNECESSARY;
-       netif_rx(skb);
-
-       info->stats.rx_packets++;
-       /* Add on 12 bytes for MAC address which was removed */
-       info->stats.rx_bytes += (len + 12);
-
-       if (info->AsicID == ELECTRABUZZ_ID) {
-               /* track how many bytes have been read from FIFO - round up to
-                * 16 bit word */
-               tempword = len + 16;
-               if (tempword & 0x01)
-                       tempword++;
-               info->fifo_cnt += tempword;
-               ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR, FT1000_FIFO_LEN);
-               ft1000_write_reg(dev, FT1000_REG_DPRAM_DATA, info->fifo_cnt);
-       }
-
-       return SUCCESS;
-}
-
-/*---------------------------------------------------------------------------
-
-  Function:   ft1000_copy_down_pkt
-  Description: This function will take an ethernet packet and convert it to
-  a Flarion packet prior to sending it to the ASIC Downlink
-  FIFO.
-  Input:
-  dev    - device structure
-  packet - address of ethernet packet
-  len    - length of IP packet
-  Output:
-  status - FAILURE
-  SUCCESS
-
-  -------------------------------------------------------------------------*/
-static int ft1000_copy_down_pkt(struct net_device *dev, u16 *packet, u16 len)
-{
-       struct ft1000_info *info = netdev_priv(dev);
-       struct ft1000_pcmcia *pcmcia = info->priv;
-       union {
-               struct pseudo_hdr blk;
-               u16 buff[sizeof(struct pseudo_hdr) >> 1];
-               u8 buffc[sizeof(struct pseudo_hdr)];
-       } pseudo;
-       int i;
-       u32 *plong;
-
-       /* Check if there is room on the FIFO */
-       if (len > ft1000_read_fifo_len(dev)) {
-               udelay(10);
-               if (len > ft1000_read_fifo_len(dev))
-                       udelay(20);
-               if (len > ft1000_read_fifo_len(dev))
-                       udelay(20);
-               if (len > ft1000_read_fifo_len(dev))
-                       udelay(20);
-               if (len > ft1000_read_fifo_len(dev))
-                       udelay(20);
-               if (len > ft1000_read_fifo_len(dev))
-                       udelay(20);
-               if (len > ft1000_read_fifo_len(dev)) {
-                       pr_debug("Transmit FIFO is full - pkt drop\n");
-                       info->stats.tx_errors++;
-                       return SUCCESS;
-               }
-       }
-       /* Create pseudo header and send pseudo/ip to hardware */
-       if (info->AsicID == ELECTRABUZZ_ID)
-               pseudo.blk.length = len;
-       else
-               pseudo.blk.length = ntohs(len);
-
-       pseudo.blk.source = DSPID;      /* Need to swap to get in correct
-                                          order */
-       pseudo.blk.destination = HOSTID;
-       pseudo.blk.portdest = NETWORKID;        /* Need to swap to get in
-                                                  correct order */
-       pseudo.blk.portsrc = DSPAIRID;
-       pseudo.blk.sh_str_id = 0;
-       pseudo.blk.control = 0;
-       pseudo.blk.rsvd1 = 0;
-       pseudo.blk.seq_num = 0;
-       pseudo.blk.rsvd2 = pcmcia->packetseqnum++;
-       pseudo.blk.qos_class = 0;
-       /* Calculate pseudo header checksum */
-       pseudo.blk.checksum = pseudo.buff[0];
-       for (i = 1; i < 7; i++)
-               pseudo.blk.checksum ^= pseudo.buff[i];
-
-       /* Production Mode */
-       if (info->AsicID == ELECTRABUZZ_ID) {
-               /* copy first word to UFIFO_BEG reg */
-               ft1000_write_reg(dev, FT1000_REG_UFIFO_BEG, pseudo.buff[0]);
-               pr_debug("data 0 BEG = 0x%04x\n", pseudo.buff[0]);
-
-               /* copy subsequent words to UFIFO_MID reg */
-               ft1000_write_reg(dev, FT1000_REG_UFIFO_MID, pseudo.buff[1]);
-               pr_debug("data 1 MID = 0x%04x\n", pseudo.buff[1]);
-               ft1000_write_reg(dev, FT1000_REG_UFIFO_MID, pseudo.buff[2]);
-               pr_debug("data 2 MID = 0x%04x\n", pseudo.buff[2]);
-               ft1000_write_reg(dev, FT1000_REG_UFIFO_MID, pseudo.buff[3]);
-               pr_debug("data 3 MID = 0x%04x\n", pseudo.buff[3]);
-               ft1000_write_reg(dev, FT1000_REG_UFIFO_MID, pseudo.buff[4]);
-               pr_debug("data 4 MID = 0x%04x\n", pseudo.buff[4]);
-               ft1000_write_reg(dev, FT1000_REG_UFIFO_MID, pseudo.buff[5]);
-               pr_debug("data 5 MID = 0x%04x\n", pseudo.buff[5]);
-               ft1000_write_reg(dev, FT1000_REG_UFIFO_MID, pseudo.buff[6]);
-               pr_debug("data 6 MID = 0x%04x\n", pseudo.buff[6]);
-               ft1000_write_reg(dev, FT1000_REG_UFIFO_MID, pseudo.buff[7]);
-               pr_debug("data 7 MID = 0x%04x\n", pseudo.buff[7]);
-
-               /* Write PPP type + IP Packet into Downlink FIFO */
-               for (i = 0; i < (len >> 1) - 1; i++) {
-                       ft1000_write_reg(dev, FT1000_REG_UFIFO_MID,
-                                        htons(*packet));
-                       pr_debug("data %d MID = 0x%04x\n",
-                                i + 8, htons(*packet));
-                       packet++;
-               }
-
-               /* Check for odd byte */
-               if (len & 0x0001) {
-                       ft1000_write_reg(dev, FT1000_REG_UFIFO_MID,
-                                        htons(*packet));
-                       pr_debug("data MID = 0x%04x\n", htons(*packet));
-                       packet++;
-                       ft1000_write_reg(dev, FT1000_REG_UFIFO_END,
-                                        htons(*packet));
-                       pr_debug("data %d MID = 0x%04x\n",
-                                i + 8, htons(*packet));
-               } else {
-                       ft1000_write_reg(dev, FT1000_REG_UFIFO_END,
-                                        htons(*packet));
-                       pr_debug("data %d MID = 0x%04x\n",
-                                i + 8, htons(*packet));
-               }
-       } else {
-               outl(*(u32 *)&pseudo.buff[0],
-                    dev->base_addr + FT1000_REG_MAG_UFDR);
-               pr_debug("Pseudo = 0x%8x\n", *(u32 *)&pseudo.buff[0]);
-               outl(*(u32 *)&pseudo.buff[2],
-                    dev->base_addr + FT1000_REG_MAG_UFDR);
-               pr_debug("Pseudo = 0x%8x\n", *(u32 *)&pseudo.buff[2]);
-               outl(*(u32 *)&pseudo.buff[4],
-                    dev->base_addr + FT1000_REG_MAG_UFDR);
-               pr_debug("Pseudo = 0x%8x\n", *(u32 *)&pseudo.buff[4]);
-               outl(*(u32 *)&pseudo.buff[6],
-                    dev->base_addr + FT1000_REG_MAG_UFDR);
-               pr_debug("Pseudo = 0x%8x\n", *(u32 *)&pseudo.buff[6]);
-
-               plong = (u32 *)packet;
-               /* Write PPP type + IP Packet into Downlink FIFO */
-               for (i = 0; i < (len >> 2); i++)
-                       outl(*plong++, dev->base_addr + FT1000_REG_MAG_UFDR);
-
-               /* Check for odd alignment */
-               if (len & 0x0003) {
-                       pr_debug("data = 0x%8x\n", *plong);
-                       outl(*plong++, dev->base_addr + FT1000_REG_MAG_UFDR);
-               }
-               outl(1, dev->base_addr + FT1000_REG_MAG_UFER);
-       }
-
-       info->stats.tx_packets++;
-       /* Add 14 bytes for MAC address plus ethernet type */
-       info->stats.tx_bytes += (len + 14);
-       return SUCCESS;
-}
-
-static struct net_device_stats *ft1000_stats(struct net_device *dev)
-{
-       struct ft1000_info *info = netdev_priv(dev);
-
-       return &info->stats;
-}
-
-static int ft1000_open(struct net_device *dev)
-{
-       ft1000_reset_card(dev);
-
-       /* schedule ft1000_hbchk to perform periodic heartbeat checks on DSP
-        * and ASIC */
-       init_timer(&poll_timer);
-       poll_timer.expires = jiffies + (2 * HZ);
-       poll_timer.data = (u_long)dev;
-       add_timer(&poll_timer);
-
-       return 0;
-}
-
-static int ft1000_close(struct net_device *dev)
-{
-       struct ft1000_info *info = netdev_priv(dev);
-
-       info->CardReady = 0;
-       del_timer(&poll_timer);
-
-       if (ft1000_card_present == 1) {
-               pr_debug("Media is down\n");
-               netif_stop_queue(dev);
-
-               ft1000_disable_interrupts(dev);
-               ft1000_write_reg(dev, FT1000_REG_RESET, DSP_RESET_BIT);
-
-               /* reset ASIC */
-               ft1000_reset_asic(dev);
-       }
-       return 0;
-}
-
-static int ft1000_start_xmit(struct sk_buff *skb, struct net_device *dev)
-{
-       struct ft1000_info *info = netdev_priv(dev);
-       u8 *pdata;
-
-       if (skb == NULL) {
-               pr_debug("skb == NULL!!!\n");
-               return 0;
-       }
-
-       pr_debug("length of packet = %d\n", skb->len);
-
-       pdata = (u8 *)skb->data;
-
-       if (info->mediastate == 0) {
-               /* Drop packet is mediastate is down */
-               pr_debug("mediastate is down\n");
-               return SUCCESS;
-       }
-
-       if ((skb->len < ENET_HEADER_SIZE) || (skb->len > ENET_MAX_SIZE)) {
-               /* Drop packet which has invalid size */
-               pr_debug("invalid ethernet length\n");
-               return SUCCESS;
-       }
-       ft1000_copy_down_pkt(dev, (u16 *) (pdata + ENET_HEADER_SIZE - 2),
-                            skb->len - ENET_HEADER_SIZE + 2);
-
-       dev_kfree_skb(skb);
-
-       return 0;
-}
-
-static irqreturn_t ft1000_interrupt(int irq, void *dev_id)
-{
-       struct net_device *dev = dev_id;
-       struct ft1000_info *info = netdev_priv(dev);
-       u16 tempword;
-       u16 inttype;
-       int cnt;
-
-       if (info->CardReady == 0) {
-               ft1000_disable_interrupts(dev);
-               return IRQ_HANDLED;
-       }
-
-       if (ft1000_chkcard(dev) == false) {
-               ft1000_disable_interrupts(dev);
-               return IRQ_HANDLED;
-       }
-
-       ft1000_disable_interrupts(dev);
-
-       /* Read interrupt type */
-       inttype = ft1000_read_reg(dev, FT1000_REG_SUP_ISR);
-
-       /* Make sure we process all interrupt before leaving the ISR due to the
-        * edge trigger interrupt type */
-       while (inttype) {
-               if (inttype & ISR_DOORBELL_PEND)
-                       ft1000_parse_dpram_msg(dev);
-
-               if (inttype & ISR_RCV) {
-                       pr_debug("Data in FIFO\n");
-
-                       cnt = 0;
-                       do {
-                               /* Check if we have packets in the Downlink
-                                * FIFO */
-                               if (info->AsicID == ELECTRABUZZ_ID) {
-                                       tempword = ft1000_read_reg(dev,
-                                                       FT1000_REG_DFIFO_STAT);
-                               } else {
-                                       tempword = ft1000_read_reg(dev,
-                                                       FT1000_REG_MAG_DFSR);
-                               }
-                               if (!(tempword & 0x1f))
-                                       break;
-                               ft1000_copy_up_pkt(dev);
-                               cnt++;
-                       } while (cnt < MAX_RCV_LOOP);
-
-               }
-               /* clear interrupts */
-               tempword = ft1000_read_reg(dev, FT1000_REG_SUP_ISR);
-               pr_debug("interrupt status register = 0x%x\n", tempword);
-               ft1000_write_reg(dev, FT1000_REG_SUP_ISR, tempword);
-
-               /* Read interrupt type */
-               inttype = ft1000_read_reg(dev, FT1000_REG_SUP_ISR);
-               pr_debug("interrupt status register after clear = 0x%x\n",
-                        inttype);
-       }
-       ft1000_enable_interrupts(dev);
-       return IRQ_HANDLED;
-}
-
-void stop_ft1000_card(struct net_device *dev)
-{
-       struct ft1000_info *info = netdev_priv(dev);
-       struct prov_record *ptr;
-       struct prov_record *tmp;
-       /* int cnt; */
-
-       info->CardReady = 0;
-       ft1000_card_present = 0;
-       netif_stop_queue(dev);
-       ft1000_disable_interrupts(dev);
-
-       /* Make sure we free any memory reserve for provisioning */
-       list_for_each_entry_safe(ptr, tmp, &info->prov_list, list) {
-               list_del(&ptr->list);
-               kfree(ptr->pprov_data);
-               kfree(ptr);
-       }
-
-       kfree(info->priv);
-
-       if (info->registered) {
-               unregister_netdev(dev);
-               info->registered = 0;
-       }
-
-       free_irq(dev->irq, dev);
-       release_region(dev->base_addr, 256);
-       release_firmware(fw_entry);
-       flarion_ft1000_cnt--;
-
-}
-
-static void ft1000_get_drvinfo(struct net_device *dev,
-                              struct ethtool_drvinfo *info)
-{
-       struct ft1000_info *ft_info;
-
-       ft_info = netdev_priv(dev);
-
-       strlcpy(info->driver, "ft1000", sizeof(info->driver));
-       snprintf(info->bus_info, sizeof(info->bus_info), "PCMCIA 0x%lx",
-                dev->base_addr);
-       snprintf(info->fw_version, sizeof(info->fw_version), "%d.%d.%d.%d",
-                ft_info->DspVer[0], ft_info->DspVer[1], ft_info->DspVer[2],
-                ft_info->DspVer[3]);
-}
-
-static u32 ft1000_get_link(struct net_device *dev)
-{
-       struct ft1000_info *info;
-
-       info = netdev_priv(dev);
-       return info->mediastate;
-}
-
-static const struct ethtool_ops ops = {
-       .get_drvinfo = ft1000_get_drvinfo,
-       .get_link = ft1000_get_link
-};
-
-struct net_device *init_ft1000_card(struct pcmcia_device *link,
-                                   void *ft1000_reset)
-{
-       struct ft1000_info *info;
-       struct ft1000_pcmcia *pcmcia;
-       struct net_device *dev;
-
-       static const struct net_device_ops ft1000ops = {
-                       .ndo_open = &ft1000_open,
-                       .ndo_stop = &ft1000_close,
-                       .ndo_start_xmit = &ft1000_start_xmit,
-                       .ndo_get_stats = &ft1000_stats,
-               };
-
-       pr_debug("irq = %d, port = 0x%04llx\n",
-                link->irq, (unsigned long long)link->resource[0]->start);
-
-       flarion_ft1000_cnt++;
-
-       if (flarion_ft1000_cnt > 1) {
-               flarion_ft1000_cnt--;
-
-               dev_info(&link->dev,
-                        "This driver can not support more than one instance\n");
-               return NULL;
-       }
-
-       dev = alloc_etherdev(sizeof(struct ft1000_info));
-       if (!dev) {
-               dev_err(&link->dev, "Failed to allocate etherdev\n");
-               return NULL;
-       }
-
-       SET_NETDEV_DEV(dev, &link->dev);
-       info = netdev_priv(dev);
-
-       memset(info, 0, sizeof(struct ft1000_info));
-
-       pr_debug("address of dev = 0x%p\n", dev);
-       pr_debug("address of dev info = 0x%p\n", info);
-       pr_debug("device name = %s\n", dev->name);
-
-       memset(&info->stats, 0, sizeof(struct net_device_stats));
-
-       info->priv = kzalloc(sizeof(struct ft1000_pcmcia), GFP_KERNEL);
-       pcmcia = info->priv;
-       pcmcia->link = link;
-
-       spin_lock_init(&info->dpram_lock);
-       info->DrvErrNum = 0;
-       info->registered = 1;
-       info->ft1000_reset = ft1000_reset;
-       info->mediastate = 0;
-       info->fifo_cnt = 0;
-       info->CardReady = 0;
-       info->DSP_TIME[0] = 0;
-       info->DSP_TIME[1] = 0;
-       info->DSP_TIME[2] = 0;
-       info->DSP_TIME[3] = 0;
-       flarion_ft1000_cnt = 0;
-
-       INIT_LIST_HEAD(&info->prov_list);
-
-       info->squeseqnum = 0;
-
-       /* dev->hard_start_xmit = &ft1000_start_xmit; */
-       /* dev->get_stats = &ft1000_stats; */
-       /* dev->open = &ft1000_open; */
-       /* dev->stop = &ft1000_close; */
-
-       dev->netdev_ops = &ft1000ops;
-
-       pr_debug("device name = %s\n", dev->name);
-
-       dev->irq = link->irq;
-       dev->base_addr = link->resource[0]->start;
-       if (pcmcia_get_mac_from_cis(link, dev)) {
-               netdev_err(dev, "Could not read mac address\n");
-               goto err_dev;
-       }
-
-       if (request_irq(dev->irq, ft1000_interrupt, IRQF_SHARED, dev->name,
-                       dev)) {
-               netdev_err(dev, "Could not request_irq\n");
-               goto err_dev;
-       }
-
-       if (request_region(dev->base_addr, 256, dev->name) == NULL) {
-               netdev_err(dev, "Could not request_region\n");
-               goto err_irq;
-       }
-
-       if (register_netdev(dev)) {
-               pr_debug("Could not register netdev\n");
-               goto err_reg;
-       }
-
-       info->AsicID = ft1000_read_reg(dev, FT1000_REG_ASIC_ID);
-       if (info->AsicID == ELECTRABUZZ_ID) {
-               pr_debug("ELECTRABUZZ ASIC\n");
-               if (request_firmware(&fw_entry, "ft1000.img",
-                                    &link->dev) != 0) {
-                       pr_info("Could not open ft1000.img\n");
-                       goto err_unreg;
-               }
-       } else {
-               pr_debug("MAGNEMITE ASIC\n");
-               if (request_firmware(&fw_entry, "ft2000.img",
-                                    &link->dev) != 0) {
-                       pr_info("Could not open ft2000.img\n");
-                       goto err_unreg;
-               }
-       }
-
-       ft1000_enable_interrupts(dev);
-
-       ft1000_card_present = 1;
-       dev->ethtool_ops = &ops;
-       pr_info("%s: addr 0x%04lx irq %d, MAC addr %pM\n",
-               dev->name, dev->base_addr, dev->irq, dev->dev_addr);
-       return dev;
-
-err_unreg:
-       unregister_netdev(dev);
-err_reg:
-       release_region(dev->base_addr, 256);
-err_irq:
-       free_irq(dev->irq, dev);
-err_dev:
-       free_netdev(dev);
-       return NULL;
-}