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