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