linux/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c
<<
>>
Prefs
   1/* CopyRight (C) 2007 Qualcomm Inc. All Rights Reserved.
   2*
   3*
   4* This file is part of Express Card USB Driver
   5*/
   6
   7#include <linux/kernel.h>
   8#include <linux/module.h>
   9#include <linux/netdevice.h>
  10#include <linux/etherdevice.h>
  11#include <linux/usb.h>
  12#include "ft1000_usb.h"
  13#include <linux/types.h>
  14
  15#define HARLEY_READ_REGISTER     0x0
  16#define HARLEY_WRITE_REGISTER    0x01
  17#define HARLEY_READ_DPRAM_32     0x02
  18#define HARLEY_READ_DPRAM_LOW    0x03
  19#define HARLEY_READ_DPRAM_HIGH   0x04
  20#define HARLEY_WRITE_DPRAM_32    0x05
  21#define HARLEY_WRITE_DPRAM_LOW   0x06
  22#define HARLEY_WRITE_DPRAM_HIGH  0x07
  23
  24#define HARLEY_READ_OPERATION    0xc1
  25#define HARLEY_WRITE_OPERATION   0x41
  26
  27#if 0
  28#define JDEBUG
  29#endif
  30
  31static int ft1000_submit_rx_urb(struct ft1000_info *info);
  32
  33static u8 tempbuffer[1600];
  34
  35#define MAX_RCV_LOOP   100
  36
  37/* send a control message via USB interface synchronously
  38*  Parameters:  ft1000_usb  - device structure
  39*               pipe - usb control message pipe
  40*               request - control request
  41*               requesttype - control message request type
  42*               value - value to be written or 0
  43*               index - register index
  44*               data - data buffer to hold the read/write values
  45*               size - data size
  46*               timeout - control message time out value
  47*/
  48static int ft1000_control(struct ft1000_usb *ft1000dev, unsigned int pipe,
  49                          u8 request, u8 requesttype, u16 value, u16 index,
  50                          void *data, u16 size, int timeout)
  51{
  52        int ret;
  53
  54        if ((ft1000dev == NULL) || (ft1000dev->dev == NULL)) {
  55                DEBUG("ft1000dev or ft1000dev->dev == NULL, failure\n");
  56                return -ENODEV;
  57        }
  58
  59        ret = usb_control_msg(ft1000dev->dev, pipe, request, requesttype,
  60                              value, index, data, size, timeout);
  61
  62        if (ret > 0)
  63                ret = 0;
  64
  65        return ret;
  66}
  67
  68/* returns the value in a register */
  69int ft1000_read_register(struct ft1000_usb *ft1000dev, u16 *Data,
  70                         u16 nRegIndx)
  71{
  72        int ret = 0;
  73
  74        ret = ft1000_control(ft1000dev,
  75                             usb_rcvctrlpipe(ft1000dev->dev, 0),
  76                             HARLEY_READ_REGISTER,
  77                             HARLEY_READ_OPERATION,
  78                             0,
  79                             nRegIndx,
  80                             Data,
  81                             2,
  82                             USB_CTRL_GET_TIMEOUT);
  83
  84        return ret;
  85}
  86
  87/* writes the value in a register */
  88int ft1000_write_register(struct ft1000_usb *ft1000dev, u16 value,
  89                          u16 nRegIndx)
  90{
  91        int ret = 0;
  92
  93        ret = ft1000_control(ft1000dev,
  94                             usb_sndctrlpipe(ft1000dev->dev, 0),
  95                             HARLEY_WRITE_REGISTER,
  96                             HARLEY_WRITE_OPERATION,
  97                             value,
  98                             nRegIndx,
  99                             NULL,
 100                             0,
 101                             USB_CTRL_SET_TIMEOUT);
 102
 103        return ret;
 104}
 105
 106/* read a number of bytes from DPRAM */
 107int ft1000_read_dpram32(struct ft1000_usb *ft1000dev, u16 indx, u8 *buffer,
 108                        u16 cnt)
 109{
 110        int ret = 0;
 111
 112        ret = ft1000_control(ft1000dev,
 113                             usb_rcvctrlpipe(ft1000dev->dev, 0),
 114                             HARLEY_READ_DPRAM_32,
 115                             HARLEY_READ_OPERATION,
 116                             0,
 117                             indx,
 118                             buffer,
 119                             cnt,
 120                             USB_CTRL_GET_TIMEOUT);
 121
 122        return ret;
 123}
 124
 125/* writes into DPRAM a number of bytes */
 126int ft1000_write_dpram32(struct ft1000_usb *ft1000dev, u16 indx, u8 *buffer,
 127                         u16 cnt)
 128{
 129        int ret = 0;
 130
 131        if (cnt % 4)
 132                cnt += cnt - (cnt % 4);
 133
 134        ret = ft1000_control(ft1000dev,
 135                             usb_sndctrlpipe(ft1000dev->dev, 0),
 136                             HARLEY_WRITE_DPRAM_32,
 137                             HARLEY_WRITE_OPERATION,
 138                             0,
 139                             indx,
 140                             buffer,
 141                             cnt,
 142                             USB_CTRL_SET_TIMEOUT);
 143
 144        return ret;
 145}
 146
 147/* read 16 bits from DPRAM */
 148int ft1000_read_dpram16(struct ft1000_usb *ft1000dev, u16 indx, u8 *buffer,
 149                        u8 highlow)
 150{
 151        int ret = 0;
 152        u8 request;
 153
 154        if (highlow == 0)
 155                request = HARLEY_READ_DPRAM_LOW;
 156        else
 157                request = HARLEY_READ_DPRAM_HIGH;
 158
 159        ret = ft1000_control(ft1000dev,
 160                             usb_rcvctrlpipe(ft1000dev->dev, 0),
 161                             request,
 162                             HARLEY_READ_OPERATION,
 163                             0,
 164                             indx,
 165                             buffer,
 166                             2,
 167                             USB_CTRL_GET_TIMEOUT);
 168
 169        return ret;
 170}
 171
 172/* write into DPRAM a number of bytes */
 173int ft1000_write_dpram16(struct ft1000_usb *ft1000dev, u16 indx, u16 value,
 174                u8 highlow)
 175{
 176        int ret = 0;
 177        u8 request;
 178
 179        if (highlow == 0)
 180                request = HARLEY_WRITE_DPRAM_LOW;
 181        else
 182                request = HARLEY_WRITE_DPRAM_HIGH;
 183
 184        ret = ft1000_control(ft1000dev,
 185                             usb_sndctrlpipe(ft1000dev->dev, 0),
 186                             request,
 187                             HARLEY_WRITE_OPERATION,
 188                             value,
 189                             indx,
 190                             NULL,
 191                             0,
 192                             USB_CTRL_SET_TIMEOUT);
 193
 194        return ret;
 195}
 196
 197/* read DPRAM 4 words at a time */
 198int fix_ft1000_read_dpram32(struct ft1000_usb *ft1000dev, u16 indx,
 199                            u8 *buffer)
 200{
 201        u8 buf[16];
 202        u16 pos;
 203        int ret = 0;
 204
 205        pos = (indx / 4) * 4;
 206        ret = ft1000_read_dpram32(ft1000dev, pos, buf, 16);
 207
 208        if (ret == 0) {
 209                pos = (indx % 4) * 4;
 210                *buffer++ = buf[pos++];
 211                *buffer++ = buf[pos++];
 212                *buffer++ = buf[pos++];
 213                *buffer++ = buf[pos++];
 214        } else {
 215                DEBUG("fix_ft1000_read_dpram32: DPRAM32 Read failed\n");
 216                *buffer++ = 0;
 217                *buffer++ = 0;
 218                *buffer++ = 0;
 219                *buffer++ = 0;
 220        }
 221
 222        return ret;
 223}
 224
 225
 226/* Description: This function write to DPRAM 4 words at a time */
 227int fix_ft1000_write_dpram32(struct ft1000_usb *ft1000dev, u16 indx, u8 *buffer)
 228{
 229        u16 pos1;
 230        u16 pos2;
 231        u16 i;
 232        u8 buf[32];
 233        u8 resultbuffer[32];
 234        u8 *pdata;
 235        int ret  = 0;
 236
 237        pos1 = (indx / 4) * 4;
 238        pdata = buffer;
 239        ret = ft1000_read_dpram32(ft1000dev, pos1, buf, 16);
 240
 241        if (ret == 0) {
 242                pos2 = (indx % 4)*4;
 243                buf[pos2++] = *buffer++;
 244                buf[pos2++] = *buffer++;
 245                buf[pos2++] = *buffer++;
 246                buf[pos2++] = *buffer++;
 247                ret = ft1000_write_dpram32(ft1000dev, pos1, buf, 16);
 248        } else {
 249                DEBUG("fix_ft1000_write_dpram32: DPRAM32 Read failed\n");
 250                return ret;
 251        }
 252
 253        ret = ft1000_read_dpram32(ft1000dev, pos1, (u8 *)&resultbuffer[0], 16);
 254
 255        if (ret == 0) {
 256                buffer = pdata;
 257                for (i = 0; i < 16; i++) {
 258                        if (buf[i] != resultbuffer[i])
 259                                ret = -1;
 260                }
 261        }
 262
 263        if (ret == -1) {
 264                ret = ft1000_write_dpram32(ft1000dev, pos1,
 265                                           (u8 *)&tempbuffer[0], 16);
 266                ret = ft1000_read_dpram32(ft1000dev, pos1,
 267                                          (u8 *)&resultbuffer[0], 16);
 268                if (ret == 0) {
 269                        buffer = pdata;
 270                        for (i = 0; i < 16; i++) {
 271                                if (tempbuffer[i] != resultbuffer[i]) {
 272                                        ret = -1;
 273                                        DEBUG("%s Failed to write\n",
 274                                              __func__);
 275                                }
 276                        }
 277                }
 278        }
 279
 280        return ret;
 281}
 282
 283/* reset or activate the DSP */
 284static void card_reset_dsp(struct ft1000_usb *ft1000dev, bool value)
 285{
 286        int status = 0;
 287        u16 tempword;
 288
 289        status = ft1000_write_register(ft1000dev, HOST_INTF_BE,
 290                                        FT1000_REG_SUP_CTRL);
 291        status = ft1000_read_register(ft1000dev, &tempword,
 292                                      FT1000_REG_SUP_CTRL);
 293
 294        if (value) {
 295                DEBUG("Reset DSP\n");
 296                status = ft1000_read_register(ft1000dev, &tempword,
 297                                              FT1000_REG_RESET);
 298                tempword |= DSP_RESET_BIT;
 299                status = ft1000_write_register(ft1000dev, tempword,
 300                                               FT1000_REG_RESET);
 301        } else {
 302                DEBUG("Activate DSP\n");
 303                status = ft1000_read_register(ft1000dev, &tempword,
 304                                              FT1000_REG_RESET);
 305                tempword |= DSP_ENCRYPTED;
 306                tempword &= ~DSP_UNENCRYPTED;
 307                status = ft1000_write_register(ft1000dev, tempword,
 308                                               FT1000_REG_RESET);
 309                status = ft1000_read_register(ft1000dev, &tempword,
 310                                              FT1000_REG_RESET);
 311                tempword &= ~EFUSE_MEM_DISABLE;
 312                tempword &= ~DSP_RESET_BIT;
 313                status = ft1000_write_register(ft1000dev, tempword,
 314                                               FT1000_REG_RESET);
 315                status = ft1000_read_register(ft1000dev, &tempword,
 316                                              FT1000_REG_RESET);
 317        }
 318}
 319
 320/* send a command to ASIC
 321*  Parameters:  ft1000_usb  - device structure
 322*               ptempbuffer - command buffer
 323*               size - command buffer size
 324*/
 325void card_send_command(struct ft1000_usb *ft1000dev, void *ptempbuffer,
 326                       int size)
 327{
 328        unsigned short temp;
 329        unsigned char *commandbuf;
 330
 331        DEBUG("card_send_command: enter card_send_command... size=%d\n", size);
 332
 333        commandbuf = kmalloc(size + 2, GFP_KERNEL);
 334        memcpy((void *)commandbuf + 2, (void *)ptempbuffer, size);
 335
 336        ft1000_read_register(ft1000dev, &temp, FT1000_REG_DOORBELL);
 337
 338        if (temp & 0x0100)
 339                usleep_range(900, 1100);
 340
 341        /* check for odd word */
 342        size = size + 2;
 343
 344        /* Must force to be 32 bit aligned */
 345        if (size % 4)
 346                size += 4 - (size % 4);
 347
 348        ft1000_write_dpram32(ft1000dev, 0, commandbuf, size);
 349        usleep_range(900, 1100);
 350        ft1000_write_register(ft1000dev, FT1000_DB_DPRAM_TX,
 351                              FT1000_REG_DOORBELL);
 352        usleep_range(900, 1100);
 353
 354        ft1000_read_register(ft1000dev, &temp, FT1000_REG_DOORBELL);
 355
 356#if 0
 357        if ((temp & 0x0100) == 0)
 358                DEBUG("card_send_command: Message sent\n");
 359#endif
 360
 361}
 362
 363/* load or reload the DSP */
 364int dsp_reload(struct ft1000_usb *ft1000dev)
 365{
 366        int status;
 367        u16 tempword;
 368        u32 templong;
 369
 370        struct ft1000_info *pft1000info;
 371
 372        pft1000info = netdev_priv(ft1000dev->net);
 373
 374        pft1000info->CardReady = 0;
 375
 376        /* Program Interrupt Mask register */
 377        status = ft1000_write_register(ft1000dev, 0xffff, FT1000_REG_SUP_IMASK);
 378
 379        status = ft1000_read_register(ft1000dev, &tempword, FT1000_REG_RESET);
 380        tempword |= ASIC_RESET_BIT;
 381        status = ft1000_write_register(ft1000dev, tempword, FT1000_REG_RESET);
 382        msleep(1000);
 383        status = ft1000_read_register(ft1000dev, &tempword, FT1000_REG_RESET);
 384        DEBUG("Reset Register = 0x%x\n", tempword);
 385
 386        /* Toggle DSP reset */
 387        card_reset_dsp(ft1000dev, 1);
 388        msleep(1000);
 389        card_reset_dsp(ft1000dev, 0);
 390        msleep(1000);
 391
 392        status =
 393            ft1000_write_register(ft1000dev, HOST_INTF_BE, FT1000_REG_SUP_CTRL);
 394
 395        /* Let's check for FEFE */
 396        status =
 397            ft1000_read_dpram32(ft1000dev, FT1000_MAG_DPRAM_FEFE_INDX,
 398                                (u8 *) &templong, 4);
 399        DEBUG("templong (fefe) = 0x%8x\n", templong);
 400
 401        /* call codeloader */
 402        status = scram_dnldr(ft1000dev, pFileStart, FileLength);
 403
 404        if (status != 0)
 405                return -EIO;
 406
 407        msleep(1000);
 408
 409        DEBUG("dsp_reload returned\n");
 410
 411        return 0;
 412}
 413
 414/* call the Card Service function to reset the ASIC. */
 415static void ft1000_reset_asic(struct net_device *dev)
 416{
 417        struct ft1000_info *info = netdev_priv(dev);
 418        struct ft1000_usb *ft1000dev = info->priv;
 419        u16 tempword;
 420
 421        DEBUG("ft1000_hw:ft1000_reset_asic called\n");
 422
 423        /* Let's use the register provided by the Magnemite ASIC to reset the
 424         * ASIC and DSP.
 425         */
 426        ft1000_write_register(ft1000dev, (DSP_RESET_BIT | ASIC_RESET_BIT),
 427                              FT1000_REG_RESET);
 428
 429        mdelay(1);
 430
 431        /* set watermark to -1 in order to not generate an interrupt */
 432        ft1000_write_register(ft1000dev, 0xffff, FT1000_REG_MAG_WATERMARK);
 433
 434        /* clear interrupts */
 435        ft1000_read_register(ft1000dev, &tempword, FT1000_REG_SUP_ISR);
 436        DEBUG("ft1000_hw: interrupt status register = 0x%x\n", tempword);
 437        ft1000_write_register(ft1000dev, tempword, FT1000_REG_SUP_ISR);
 438        ft1000_read_register(ft1000dev, &tempword, FT1000_REG_SUP_ISR);
 439        DEBUG("ft1000_hw: interrupt status register = 0x%x\n", tempword);
 440}
 441
 442static int ft1000_reset_card(struct net_device *dev)
 443{
 444        struct ft1000_info *info = netdev_priv(dev);
 445        struct ft1000_usb *ft1000dev = info->priv;
 446        u16 tempword;
 447        struct prov_record *ptr;
 448
 449        DEBUG("ft1000_hw:ft1000_reset_card called.....\n");
 450
 451        ft1000dev->fCondResetPend = true;
 452        info->CardReady = 0;
 453        ft1000dev->fProvComplete = false;
 454
 455        /* Make sure we free any memory reserve for provisioning */
 456        while (list_empty(&info->prov_list) == 0) {
 457                DEBUG("ft1000_reset_card:deleting provisioning record\n");
 458                ptr =
 459                    list_entry(info->prov_list.next, struct prov_record, list);
 460                list_del(&ptr->list);
 461                kfree(ptr->pprov_data);
 462                kfree(ptr);
 463        }
 464
 465        DEBUG("ft1000_hw:ft1000_reset_card: reset asic\n");
 466        ft1000_reset_asic(dev);
 467
 468        DEBUG("ft1000_hw:ft1000_reset_card: call dsp_reload\n");
 469        dsp_reload(ft1000dev);
 470
 471        DEBUG("dsp reload successful\n");
 472
 473        mdelay(10);
 474
 475        /* Initialize DSP heartbeat area */
 476        ft1000_write_dpram16(ft1000dev, FT1000_MAG_HI_HO, ho_mag,
 477                             FT1000_MAG_HI_HO_INDX);
 478        ft1000_read_dpram16(ft1000dev, FT1000_MAG_HI_HO, (u8 *) &tempword,
 479                            FT1000_MAG_HI_HO_INDX);
 480        DEBUG("ft1000_hw:ft1000_reset_card:hi_ho value = 0x%x\n", tempword);
 481
 482        info->CardReady = 1;
 483
 484        ft1000dev->fCondResetPend = false;
 485
 486        return TRUE;
 487}
 488
 489/* callback function when a urb is transmitted */
 490static void ft1000_usb_transmit_complete(struct urb *urb)
 491{
 492
 493        struct ft1000_usb *ft1000dev = urb->context;
 494
 495        if (urb->status)
 496                pr_err("%s: TX status %d\n", ft1000dev->net->name, urb->status);
 497
 498        netif_wake_queue(ft1000dev->net);
 499}
 500
 501/* take an ethernet packet and convert it to a Flarion
 502*  packet prior to sending it to the ASIC Downlink FIFO.
 503*/
 504static int ft1000_copy_down_pkt(struct net_device *netdev, u8 *packet, u16 len)
 505{
 506        struct ft1000_info *pInfo = netdev_priv(netdev);
 507        struct ft1000_usb *pFt1000Dev = pInfo->priv;
 508
 509        int count, ret;
 510        u8 *t;
 511        struct pseudo_hdr hdr;
 512
 513        if (!pInfo->CardReady) {
 514                DEBUG("ft1000_copy_down_pkt::Card Not Ready\n");
 515                return -ENODEV;
 516        }
 517
 518        count = sizeof(struct pseudo_hdr) + len;
 519        if (count > MAX_BUF_SIZE) {
 520                DEBUG("Error:ft1000_copy_down_pkt:Message Size Overflow!\n");
 521                DEBUG("size = %d\n", count);
 522                return -EINVAL;
 523        }
 524
 525        if (count % 4)
 526                count = count + (4 - (count % 4));
 527
 528        memset(&hdr, 0, sizeof(struct pseudo_hdr));
 529
 530        hdr.length = ntohs(count);
 531        hdr.source = 0x10;
 532        hdr.destination = 0x20;
 533        hdr.portdest = 0x20;
 534        hdr.portsrc = 0x10;
 535        hdr.sh_str_id = 0x91;
 536        hdr.control = 0x00;
 537
 538        hdr.checksum = hdr.length ^ hdr.source ^ hdr.destination ^
 539            hdr.portdest ^ hdr.portsrc ^ hdr.sh_str_id ^ hdr.control;
 540
 541        memcpy(&pFt1000Dev->tx_buf[0], &hdr, sizeof(hdr));
 542        memcpy(&(pFt1000Dev->tx_buf[sizeof(struct pseudo_hdr)]), packet, len);
 543
 544        netif_stop_queue(netdev);
 545
 546        usb_fill_bulk_urb(pFt1000Dev->tx_urb,
 547                          pFt1000Dev->dev,
 548                          usb_sndbulkpipe(pFt1000Dev->dev,
 549                                          pFt1000Dev->bulk_out_endpointAddr),
 550                          pFt1000Dev->tx_buf, count,
 551                          ft1000_usb_transmit_complete, (void *)pFt1000Dev);
 552
 553        t = (u8 *) pFt1000Dev->tx_urb->transfer_buffer;
 554
 555        ret = usb_submit_urb(pFt1000Dev->tx_urb, GFP_ATOMIC);
 556
 557        if (ret) {
 558                DEBUG("ft1000 failed tx_urb %d\n", ret);
 559                return ret;
 560        } else {
 561                pInfo->stats.tx_packets++;
 562                pInfo->stats.tx_bytes += (len + 14);
 563        }
 564
 565        return 0;
 566}
 567
 568/* transmit an ethernet packet
 569*  Parameters:  skb - socket buffer to be sent
 570*               dev - network device
 571*/
 572static int ft1000_start_xmit(struct sk_buff *skb, struct net_device *dev)
 573{
 574        struct ft1000_info *pInfo = netdev_priv(dev);
 575        struct ft1000_usb *pFt1000Dev = pInfo->priv;
 576        u8 *pdata;
 577        int maxlen, pipe;
 578
 579        if (skb == NULL) {
 580                DEBUG("ft1000_hw: ft1000_start_xmit:skb == NULL!!!\n");
 581                return NETDEV_TX_OK;
 582        }
 583
 584        if (pFt1000Dev->status & FT1000_STATUS_CLOSING) {
 585                DEBUG("network driver is closed, return\n");
 586                goto err;
 587        }
 588
 589        pipe =
 590            usb_sndbulkpipe(pFt1000Dev->dev, pFt1000Dev->bulk_out_endpointAddr);
 591        maxlen = usb_maxpacket(pFt1000Dev->dev, pipe, usb_pipeout(pipe));
 592
 593        pdata = (u8 *) skb->data;
 594
 595        if (pInfo->mediastate == 0) {
 596                /* Drop packet is mediastate is down */
 597                DEBUG("ft1000_hw:ft1000_start_xmit:mediastate is down\n");
 598                goto err;
 599        }
 600
 601        if ((skb->len < ENET_HEADER_SIZE) || (skb->len > ENET_MAX_SIZE)) {
 602                /* Drop packet which has invalid size */
 603                DEBUG("ft1000_hw:ft1000_start_xmit:invalid ethernet length\n");
 604                goto err;
 605        }
 606
 607        ft1000_copy_down_pkt(dev, (pdata + ENET_HEADER_SIZE - 2),
 608                             skb->len - ENET_HEADER_SIZE + 2);
 609
 610err:
 611        dev_kfree_skb(skb);
 612
 613        return NETDEV_TX_OK;
 614}
 615
 616/* open the network driver */
 617static int ft1000_open(struct net_device *dev)
 618{
 619        struct ft1000_info *pInfo = netdev_priv(dev);
 620        struct ft1000_usb *pFt1000Dev = pInfo->priv;
 621        struct timeval tv;
 622
 623        DEBUG("ft1000_open is called for card %d\n", pFt1000Dev->CardNumber);
 624
 625        pInfo->stats.rx_bytes = 0;
 626        pInfo->stats.tx_bytes = 0;
 627        pInfo->stats.rx_packets = 0;
 628        pInfo->stats.tx_packets = 0;
 629        do_gettimeofday(&tv);
 630        pInfo->ConTm = tv.tv_sec;
 631        pInfo->ProgConStat = 0;
 632
 633        netif_start_queue(dev);
 634
 635        netif_carrier_on(dev);
 636
 637        return ft1000_submit_rx_urb(pInfo);
 638}
 639
 640static struct net_device_stats *ft1000_netdev_stats(struct net_device *dev)
 641{
 642        struct ft1000_info *info = netdev_priv(dev);
 643
 644        return &(info->stats);
 645}
 646
 647static const struct net_device_ops ftnet_ops = {
 648        .ndo_open = &ft1000_open,
 649        .ndo_stop = &ft1000_close,
 650        .ndo_start_xmit = &ft1000_start_xmit,
 651        .ndo_get_stats = &ft1000_netdev_stats,
 652};
 653
 654/* initialize the network device */
 655static int ft1000_reset(void *dev)
 656{
 657        ft1000_reset_card(dev);
 658        return 0;
 659}
 660
 661int init_ft1000_netdev(struct ft1000_usb *ft1000dev)
 662{
 663        struct net_device *netdev;
 664        struct ft1000_info *pInfo = NULL;
 665        struct dpram_blk *pdpram_blk;
 666        int i, ret_val;
 667        struct list_head *cur, *tmp;
 668        char card_nr[2];
 669        u8 gCardIndex = 0;
 670
 671        DEBUG("Enter init_ft1000_netdev...\n");
 672
 673        netdev = alloc_etherdev(sizeof(struct ft1000_info));
 674        if (!netdev) {
 675                DEBUG("init_ft1000_netdev: can not allocate network device\n");
 676                return -ENOMEM;
 677        }
 678
 679        pInfo = netdev_priv(netdev);
 680
 681        memset(pInfo, 0, sizeof(struct ft1000_info));
 682
 683        dev_alloc_name(netdev, netdev->name);
 684
 685        DEBUG("init_ft1000_netdev: network device name is %s\n", netdev->name);
 686
 687        if (strncmp(netdev->name, "eth", 3) == 0) {
 688                card_nr[0] = netdev->name[3];
 689                card_nr[1] = '\0';
 690                ret_val = kstrtou8(card_nr, 10, &gCardIndex);
 691                if (ret_val) {
 692                        netdev_err(ft1000dev->net, "Can't parse netdev\n");
 693                        goto err_net;
 694                }
 695
 696                ft1000dev->CardNumber = gCardIndex;
 697                DEBUG("card number = %d\n", ft1000dev->CardNumber);
 698        } else {
 699                netdev_err(ft1000dev->net, "ft1000: Invalid device name\n");
 700                ret_val = -ENXIO;
 701                goto err_net;
 702        }
 703
 704        memset(&pInfo->stats, 0, sizeof(struct net_device_stats));
 705
 706        spin_lock_init(&pInfo->dpram_lock);
 707        pInfo->priv = ft1000dev;
 708        pInfo->DrvErrNum = 0;
 709        pInfo->registered = 1;
 710        pInfo->ft1000_reset = ft1000_reset;
 711        pInfo->mediastate = 0;
 712        pInfo->fifo_cnt = 0;
 713        ft1000dev->DeviceCreated = FALSE;
 714        pInfo->CardReady = 0;
 715        pInfo->DSP_TIME[0] = 0;
 716        pInfo->DSP_TIME[1] = 0;
 717        pInfo->DSP_TIME[2] = 0;
 718        pInfo->DSP_TIME[3] = 0;
 719        ft1000dev->fAppMsgPend = false;
 720        ft1000dev->fCondResetPend = false;
 721        ft1000dev->usbboot = 0;
 722        ft1000dev->dspalive = 0;
 723        memset(&ft1000dev->tempbuf[0], 0, sizeof(ft1000dev->tempbuf));
 724
 725        INIT_LIST_HEAD(&pInfo->prov_list);
 726
 727        INIT_LIST_HEAD(&ft1000dev->nodes.list);
 728
 729        netdev->netdev_ops = &ftnet_ops;
 730
 731        ft1000dev->net = netdev;
 732
 733        DEBUG("Initialize free_buff_lock and freercvpool\n");
 734        spin_lock_init(&free_buff_lock);
 735
 736        /* initialize a list of buffers to be use for queuing
 737         * up receive command data
 738         */
 739        INIT_LIST_HEAD(&freercvpool);
 740
 741        /* create list of free buffers */
 742        for (i = 0; i < NUM_OF_FREE_BUFFERS; i++) {
 743                /* Get memory for DPRAM_DATA link list */
 744                pdpram_blk = kmalloc(sizeof(struct dpram_blk), GFP_KERNEL);
 745                if (pdpram_blk == NULL) {
 746                        ret_val = -ENOMEM;
 747                        goto err_free;
 748                }
 749                /* Get a block of memory to store command data */
 750                pdpram_blk->pbuffer = kmalloc(MAX_CMD_SQSIZE, GFP_KERNEL);
 751                if (pdpram_blk->pbuffer == NULL) {
 752                        ret_val = -ENOMEM;
 753                        kfree(pdpram_blk);
 754                        goto err_free;
 755                }
 756                /* link provisioning data */
 757                list_add_tail(&pdpram_blk->list, &freercvpool);
 758        }
 759        numofmsgbuf = NUM_OF_FREE_BUFFERS;
 760
 761        return 0;
 762
 763err_free:
 764        list_for_each_safe(cur, tmp, &freercvpool) {
 765                pdpram_blk = list_entry(cur, struct dpram_blk, list);
 766                list_del(&pdpram_blk->list);
 767                kfree(pdpram_blk->pbuffer);
 768                kfree(pdpram_blk);
 769        }
 770err_net:
 771        free_netdev(netdev);
 772        return ret_val;
 773}
 774
 775/* register the network driver */
 776int reg_ft1000_netdev(struct ft1000_usb *ft1000dev,
 777                      struct usb_interface *intf)
 778{
 779        struct net_device *netdev;
 780        struct ft1000_info *pInfo;
 781        int rc;
 782
 783        netdev = ft1000dev->net;
 784        pInfo = netdev_priv(ft1000dev->net);
 785        DEBUG("Enter reg_ft1000_netdev...\n");
 786
 787        ft1000_read_register(ft1000dev, &pInfo->AsicID, FT1000_REG_ASIC_ID);
 788
 789        usb_set_intfdata(intf, pInfo);
 790        SET_NETDEV_DEV(netdev, &intf->dev);
 791
 792        rc = register_netdev(netdev);
 793        if (rc) {
 794                DEBUG("reg_ft1000_netdev: could not register network device\n");
 795                free_netdev(netdev);
 796                return rc;
 797        }
 798
 799        ft1000_create_dev(ft1000dev);
 800
 801        DEBUG("reg_ft1000_netdev returned\n");
 802
 803        pInfo->CardReady = 1;
 804
 805        return 0;
 806}
 807
 808/* take a packet from the FIFO up link and
 809*  convert it into an ethernet packet and deliver it to the IP stack
 810*/
 811static int ft1000_copy_up_pkt(struct urb *urb)
 812{
 813        struct ft1000_info *info = urb->context;
 814        struct ft1000_usb *ft1000dev = info->priv;
 815        struct net_device *net = ft1000dev->net;
 816
 817        u16 tempword;
 818        u16 len;
 819        u16 lena;
 820        struct sk_buff *skb;
 821        u16 i;
 822        u8 *pbuffer = NULL;
 823        u8 *ptemp = NULL;
 824        u16 *chksum;
 825
 826        if (ft1000dev->status & FT1000_STATUS_CLOSING) {
 827                DEBUG("network driver is closed, return\n");
 828                return 0;
 829        }
 830        /* Read length */
 831        len = urb->transfer_buffer_length;
 832        lena = urb->actual_length;
 833
 834        chksum = (u16 *) ft1000dev->rx_buf;
 835
 836        tempword = *chksum++;
 837        for (i = 1; i < 7; i++)
 838                tempword ^= *chksum++;
 839
 840        if (tempword != *chksum) {
 841                info->stats.rx_errors++;
 842                ft1000_submit_rx_urb(info);
 843                return -1;
 844        }
 845
 846        skb = dev_alloc_skb(len + 12 + 2);
 847
 848        if (skb == NULL) {
 849                DEBUG("ft1000_copy_up_pkt: No Network buffers available\n");
 850                info->stats.rx_errors++;
 851                ft1000_submit_rx_urb(info);
 852                return -1;
 853        }
 854
 855        pbuffer = (u8 *) skb_put(skb, len + 12);
 856
 857        /* subtract the number of bytes read already */
 858        ptemp = pbuffer;
 859
 860        /* fake MAC address */
 861        *pbuffer++ = net->dev_addr[0];
 862        *pbuffer++ = net->dev_addr[1];
 863        *pbuffer++ = net->dev_addr[2];
 864        *pbuffer++ = net->dev_addr[3];
 865        *pbuffer++ = net->dev_addr[4];
 866        *pbuffer++ = net->dev_addr[5];
 867        *pbuffer++ = 0x00;
 868        *pbuffer++ = 0x07;
 869        *pbuffer++ = 0x35;
 870        *pbuffer++ = 0xff;
 871        *pbuffer++ = 0xff;
 872        *pbuffer++ = 0xfe;
 873
 874        memcpy(pbuffer, ft1000dev->rx_buf + sizeof(struct pseudo_hdr),
 875               len - sizeof(struct pseudo_hdr));
 876
 877        skb->dev = net;
 878
 879        skb->protocol = eth_type_trans(skb, net);
 880        skb->ip_summed = CHECKSUM_UNNECESSARY;
 881        netif_rx(skb);
 882
 883        info->stats.rx_packets++;
 884        /* Add on 12 bytes for MAC address which was removed */
 885        info->stats.rx_bytes += (lena + 12);
 886
 887        ft1000_submit_rx_urb(info);
 888
 889        return 0;
 890}
 891
 892
 893/* the receiving function of the network driver */
 894static int ft1000_submit_rx_urb(struct ft1000_info *info)
 895{
 896        int result;
 897        struct ft1000_usb *pFt1000Dev = info->priv;
 898
 899        if (pFt1000Dev->status & FT1000_STATUS_CLOSING) {
 900                DEBUG("network driver is closed, return\n");
 901                return -ENODEV;
 902        }
 903
 904        usb_fill_bulk_urb(pFt1000Dev->rx_urb,
 905                          pFt1000Dev->dev,
 906                          usb_rcvbulkpipe(pFt1000Dev->dev,
 907                                          pFt1000Dev->bulk_in_endpointAddr),
 908                          pFt1000Dev->rx_buf, MAX_BUF_SIZE,
 909                          (usb_complete_t) ft1000_copy_up_pkt, info);
 910
 911        result = usb_submit_urb(pFt1000Dev->rx_urb, GFP_ATOMIC);
 912
 913        if (result) {
 914                pr_err("ft1000_submit_rx_urb: submitting rx_urb %d failed\n",
 915                       result);
 916                return result;
 917        }
 918
 919        return 0;
 920}
 921
 922/* close the network driver */
 923int ft1000_close(struct net_device *net)
 924{
 925        struct ft1000_info *pInfo = netdev_priv(net);
 926        struct ft1000_usb *ft1000dev = pInfo->priv;
 927
 928        ft1000dev->status |= FT1000_STATUS_CLOSING;
 929
 930        DEBUG("ft1000_close: pInfo=%p, ft1000dev=%p\n", pInfo, ft1000dev);
 931        netif_carrier_off(net);
 932        netif_stop_queue(net);
 933        ft1000dev->status &= ~FT1000_STATUS_CLOSING;
 934
 935        pInfo->ProgConStat = 0xff;
 936
 937        return 0;
 938}
 939
 940/* check if the device is presently available on the system. */
 941static int ft1000_chkcard(struct ft1000_usb *dev)
 942{
 943        u16 tempword;
 944        int status;
 945
 946        if (dev->fCondResetPend) {
 947                DEBUG("ft1000_hw:ft1000_chkcard:Card is being reset, return FALSE\n");
 948                return TRUE;
 949        }
 950        /* Mask register is used to check for device presence since it is never
 951         * set to zero.
 952         */
 953        status = ft1000_read_register(dev, &tempword, FT1000_REG_SUP_IMASK);
 954        if (tempword == 0) {
 955                DEBUG("ft1000_hw:ft1000_chkcard: IMASK = 0 Card not detected\n");
 956                return FALSE;
 957        }
 958        /* The system will return the value of 0xffff for the version register
 959         * if the device is not present.
 960         */
 961        status = ft1000_read_register(dev, &tempword, FT1000_REG_ASIC_ID);
 962        if (tempword != 0x1b01) {
 963                dev->status |= FT1000_STATUS_CLOSING;
 964                DEBUG("ft1000_hw:ft1000_chkcard: Version = 0xffff Card not detected\n");
 965                return FALSE;
 966        }
 967        return TRUE;
 968}
 969
 970/* read a message from the dpram area.
 971*  Input:
 972*    dev - network device structure
 973*    pbuffer - caller supply address to buffer
 974*/
 975static bool ft1000_receive_cmd(struct ft1000_usb *dev, u16 *pbuffer,
 976                               int maxsz)
 977{
 978        u16 size;
 979        int ret;
 980        u16 *ppseudohdr;
 981        int i;
 982        u16 tempword;
 983
 984        ret =
 985            ft1000_read_dpram16(dev, FT1000_MAG_PH_LEN, (u8 *) &size,
 986                                FT1000_MAG_PH_LEN_INDX);
 987        size = ntohs(size) + PSEUDOSZ;
 988        if (size > maxsz) {
 989                DEBUG("FT1000:ft1000_receive_cmd:Invalid command length = %d\n",
 990                      size);
 991                return FALSE;
 992        } else {
 993                ppseudohdr = (u16 *) pbuffer;
 994                ft1000_write_register(dev, FT1000_DPRAM_MAG_RX_BASE,
 995                                      FT1000_REG_DPRAM_ADDR);
 996                ret =
 997                    ft1000_read_register(dev, pbuffer, FT1000_REG_MAG_DPDATAH);
 998                pbuffer++;
 999                ft1000_write_register(dev, FT1000_DPRAM_MAG_RX_BASE + 1,
1000                                      FT1000_REG_DPRAM_ADDR);
1001                for (i = 0; i <= (size >> 2); i++) {
1002                        ret =
1003                            ft1000_read_register(dev, pbuffer,
1004                                                 FT1000_REG_MAG_DPDATAL);
1005                        pbuffer++;
1006                        ret =
1007                            ft1000_read_register(dev, pbuffer,
1008                                                 FT1000_REG_MAG_DPDATAH);
1009                        pbuffer++;
1010                }
1011                /* copy odd aligned word */
1012                ret =
1013                    ft1000_read_register(dev, pbuffer, FT1000_REG_MAG_DPDATAL);
1014
1015                pbuffer++;
1016                ret =
1017                    ft1000_read_register(dev, pbuffer, FT1000_REG_MAG_DPDATAH);
1018
1019                pbuffer++;
1020                if (size & 0x0001) {
1021                        /* copy odd byte from fifo */
1022                        ret =
1023                            ft1000_read_register(dev, &tempword,
1024                                                 FT1000_REG_DPRAM_DATA);
1025                        *pbuffer = ntohs(tempword);
1026                }
1027                /* Check if pseudo header checksum is good
1028                 * Calculate pseudo header checksum
1029                 */
1030                tempword = *ppseudohdr++;
1031                for (i = 1; i < 7; i++)
1032                        tempword ^= *ppseudohdr++;
1033
1034                if ((tempword != *ppseudohdr))
1035                        return FALSE;
1036
1037                return TRUE;
1038        }
1039}
1040
1041static int ft1000_dsp_prov(void *arg)
1042{
1043        struct ft1000_usb *dev = (struct ft1000_usb *)arg;
1044        struct ft1000_info *info = netdev_priv(dev->net);
1045        u16 tempword;
1046        u16 len;
1047        u16 i = 0;
1048        struct prov_record *ptr;
1049        struct pseudo_hdr *ppseudo_hdr;
1050        u16 *pmsg;
1051        int status;
1052        u16 TempShortBuf[256];
1053
1054        DEBUG("*** DspProv Entered\n");
1055
1056        while (list_empty(&info->prov_list) == 0) {
1057                DEBUG("DSP Provisioning List Entry\n");
1058
1059                /* Check if doorbell is available */
1060                DEBUG("check if doorbell is cleared\n");
1061                status =
1062                    ft1000_read_register(dev, &tempword, FT1000_REG_DOORBELL);
1063                if (status) {
1064                        DEBUG("ft1000_dsp_prov::ft1000_read_register error\n");
1065                        break;
1066                }
1067
1068                while (tempword & FT1000_DB_DPRAM_TX) {
1069                        mdelay(10);
1070                        i++;
1071                        if (i == 10) {
1072                                DEBUG("FT1000:ft1000_dsp_prov:message drop\n");
1073                                return -1;
1074                        }
1075                        ft1000_read_register(dev, &tempword,
1076                                             FT1000_REG_DOORBELL);
1077                }
1078
1079                if (!(tempword & FT1000_DB_DPRAM_TX)) {
1080                        DEBUG("*** Provision Data Sent to DSP\n");
1081
1082                        /* Send provisioning data */
1083                        ptr =
1084                            list_entry(info->prov_list.next, struct prov_record,
1085                                       list);
1086                        len = *(u16 *) ptr->pprov_data;
1087                        len = htons(len);
1088                        len += PSEUDOSZ;
1089
1090                        pmsg = (u16 *) ptr->pprov_data;
1091                        ppseudo_hdr = (struct pseudo_hdr *)pmsg;
1092                        /* Insert slow queue sequence number */
1093                        ppseudo_hdr->seq_num = info->squeseqnum++;
1094                        ppseudo_hdr->portsrc = 0;
1095                        /* Calculate new checksum */
1096                        ppseudo_hdr->checksum = *pmsg++;
1097                        for (i = 1; i < 7; i++)
1098                                ppseudo_hdr->checksum ^= *pmsg++;
1099
1100                        TempShortBuf[0] = 0;
1101                        TempShortBuf[1] = htons(len);
1102                        memcpy(&TempShortBuf[2], ppseudo_hdr, len);
1103
1104                        status =
1105                            ft1000_write_dpram32(dev, 0,
1106                                                 (u8 *) &TempShortBuf[0],
1107                                                 (unsigned short)(len + 2));
1108                        status =
1109                            ft1000_write_register(dev, FT1000_DB_DPRAM_TX,
1110                                                  FT1000_REG_DOORBELL);
1111
1112                        list_del(&ptr->list);
1113                        kfree(ptr->pprov_data);
1114                        kfree(ptr);
1115                }
1116                usleep_range(9000, 11000);
1117        }
1118
1119        DEBUG("DSP Provisioning List Entry finished\n");
1120
1121        msleep(100);
1122
1123        dev->fProvComplete = true;
1124        info->CardReady = 1;
1125
1126        return 0;
1127}
1128
1129static int ft1000_proc_drvmsg(struct ft1000_usb *dev, u16 size)
1130{
1131        struct ft1000_info *info = netdev_priv(dev->net);
1132        u16 msgtype;
1133        u16 tempword;
1134        struct media_msg *pmediamsg;
1135        struct dsp_init_msg *pdspinitmsg;
1136        struct drv_msg *pdrvmsg;
1137        u16 i;
1138        struct pseudo_hdr *ppseudo_hdr;
1139        u16 *pmsg;
1140        int status;
1141        union {
1142                u8 byte[2];
1143                u16 wrd;
1144        } convert;
1145
1146        char *cmdbuffer = kmalloc(1600, GFP_KERNEL);
1147        if (!cmdbuffer)
1148                return -1;
1149
1150        status = ft1000_read_dpram32(dev, 0x200, cmdbuffer, size);
1151
1152#ifdef JDEBUG
1153        DEBUG("ft1000_proc_drvmsg:cmdbuffer\n");
1154        for (i = 0; i < size; i += 5) {
1155                if ((i + 5) < size)
1156                        DEBUG("0x%x, 0x%x, 0x%x, 0x%x, 0x%x\n", cmdbuffer[i],
1157                              cmdbuffer[i + 1], cmdbuffer[i + 2],
1158                              cmdbuffer[i + 3], cmdbuffer[i + 4]);
1159                else {
1160                        for (j = i; j < size; j++)
1161                                DEBUG("0x%x ", cmdbuffer[j]);
1162                        DEBUG("\n");
1163                        break;
1164                }
1165        }
1166#endif
1167        pdrvmsg = (struct drv_msg *)&cmdbuffer[2];
1168        msgtype = ntohs(pdrvmsg->type);
1169        DEBUG("ft1000_proc_drvmsg:Command message type = 0x%x\n", msgtype);
1170        switch (msgtype) {
1171        case MEDIA_STATE:{
1172                DEBUG("ft1000_proc_drvmsg:Command message type = MEDIA_STATE");
1173                pmediamsg = (struct media_msg *)&cmdbuffer[0];
1174                if (info->ProgConStat != 0xFF) {
1175                        if (pmediamsg->state) {
1176                                DEBUG("Media is up\n");
1177                                if (info->mediastate == 0) {
1178                                        if (dev->NetDevRegDone)
1179                                                netif_wake_queue(dev->net);
1180                                        info->mediastate = 1;
1181                                }
1182                        } else {
1183                                DEBUG("Media is down\n");
1184                                if (info->mediastate == 1) {
1185                                        info->mediastate = 0;
1186                                        if (dev->NetDevRegDone)
1187                                                info->ConTm = 0;
1188                                }
1189                        }
1190                } else {
1191                        DEBUG("Media is down\n");
1192                        if (info->mediastate == 1) {
1193                                info->mediastate = 0;
1194                                info->ConTm = 0;
1195                        }
1196                }
1197                break;
1198        }
1199        case DSP_INIT_MSG:{
1200                DEBUG("ft1000_proc_drvmsg:Command message type = DSP_INIT_MSG");
1201                pdspinitmsg = (struct dsp_init_msg *)&cmdbuffer[2];
1202                memcpy(info->DspVer, pdspinitmsg->DspVer, DSPVERSZ);
1203                DEBUG("DSPVER = 0x%2x 0x%2x 0x%2x 0x%2x\n",
1204                      info->DspVer[0], info->DspVer[1], info->DspVer[2],
1205                      info->DspVer[3]);
1206                memcpy(info->HwSerNum, pdspinitmsg->HwSerNum,
1207                       HWSERNUMSZ);
1208                memcpy(info->Sku, pdspinitmsg->Sku, SKUSZ);
1209                memcpy(info->eui64, pdspinitmsg->eui64, EUISZ);
1210                DEBUG("EUI64=%2x.%2x.%2x.%2x.%2x.%2x.%2x.%2x\n",
1211                      info->eui64[0], info->eui64[1], info->eui64[2],
1212                      info->eui64[3], info->eui64[4], info->eui64[5],
1213                      info->eui64[6], info->eui64[7]);
1214                dev->net->dev_addr[0] = info->eui64[0];
1215                dev->net->dev_addr[1] = info->eui64[1];
1216                dev->net->dev_addr[2] = info->eui64[2];
1217                dev->net->dev_addr[3] = info->eui64[5];
1218                dev->net->dev_addr[4] = info->eui64[6];
1219                dev->net->dev_addr[5] = info->eui64[7];
1220
1221                if (ntohs(pdspinitmsg->length) ==
1222                    (sizeof(struct dsp_init_msg) - 20)) {
1223                        memcpy(info->ProductMode, pdspinitmsg->ProductMode,
1224                                        MODESZ);
1225                        memcpy(info->RfCalVer, pdspinitmsg->RfCalVer, CALVERSZ);
1226                        memcpy(info->RfCalDate, pdspinitmsg->RfCalDate,
1227                               CALDATESZ);
1228                        DEBUG("RFCalVer = 0x%2x 0x%2x\n", info->RfCalVer[0],
1229                                        info->RfCalVer[1]);
1230                }
1231                break;
1232        }
1233        case DSP_PROVISION:{
1234                DEBUG("ft1000_proc_drvmsg:Command message type = DSP_PROVISION\n");
1235
1236                /* kick off dspprov routine to start provisioning
1237                 * Send provisioning data to DSP
1238                 */
1239                if (list_empty(&info->prov_list) == 0) {
1240                        dev->fProvComplete = false;
1241                        status = ft1000_dsp_prov(dev);
1242                        if (status != 0)
1243                                goto out;
1244                } else {
1245                        dev->fProvComplete = true;
1246                        status = ft1000_write_register(dev, FT1000_DB_HB,
1247                                        FT1000_REG_DOORBELL);
1248                        DEBUG("FT1000:drivermsg:No more DSP provisioning data in dsp image\n");
1249                }
1250                DEBUG("ft1000_proc_drvmsg:DSP PROVISION is done\n");
1251                break;
1252        }
1253        case DSP_STORE_INFO:{
1254                DEBUG("ft1000_proc_drvmsg:Command message type = DSP_STORE_INFO");
1255                DEBUG("FT1000:drivermsg:Got DSP_STORE_INFO\n");
1256                tempword = ntohs(pdrvmsg->length);
1257                info->DSPInfoBlklen = tempword;
1258                if (tempword < (MAX_DSP_SESS_REC - 4)) {
1259                        pmsg = (u16 *) &pdrvmsg->data[0];
1260                        for (i = 0; i < ((tempword + 1) / 2); i++) {
1261                                DEBUG("FT1000:drivermsg:dsp info data = 0x%x\n", *pmsg);
1262                                info->DSPInfoBlk[i + 10] = *pmsg++;
1263                        }
1264                } else {
1265                        info->DSPInfoBlklen = 0;
1266                }
1267                break;
1268        }
1269        case DSP_GET_INFO:{
1270                DEBUG("FT1000:drivermsg:Got DSP_GET_INFO\n");
1271                /* copy dsp info block to dsp */
1272                dev->DrvMsgPend = 1;
1273                /* allow any outstanding ioctl to finish */
1274                mdelay(10);
1275                status = ft1000_read_register(dev, &tempword,
1276                                FT1000_REG_DOORBELL);
1277                if (tempword & FT1000_DB_DPRAM_TX) {
1278                        mdelay(10);
1279                        status = ft1000_read_register(dev, &tempword,
1280                                        FT1000_REG_DOORBELL);
1281                        if (tempword & FT1000_DB_DPRAM_TX) {
1282                                mdelay(10);
1283                                status = ft1000_read_register(dev, &tempword,
1284                                                FT1000_REG_DOORBELL);
1285                                if (tempword & FT1000_DB_DPRAM_TX)
1286                                        break;
1287                        }
1288                }
1289                /* Put message into Slow Queue Form Pseudo header */
1290                pmsg = (u16 *) info->DSPInfoBlk;
1291                *pmsg++ = 0;
1292                *pmsg++ = htons(info->DSPInfoBlklen + 20 + info->DSPInfoBlklen);
1293                ppseudo_hdr =
1294                    (struct pseudo_hdr *)(u16 *) &info->DSPInfoBlk[2];
1295                ppseudo_hdr->length = htons(info->DSPInfoBlklen + 4
1296                                + info->DSPInfoBlklen);
1297                ppseudo_hdr->source = 0x10;
1298                ppseudo_hdr->destination = 0x20;
1299                ppseudo_hdr->portdest = 0;
1300                ppseudo_hdr->portsrc = 0;
1301                ppseudo_hdr->sh_str_id = 0;
1302                ppseudo_hdr->control = 0;
1303                ppseudo_hdr->rsvd1 = 0;
1304                ppseudo_hdr->rsvd2 = 0;
1305                ppseudo_hdr->qos_class = 0;
1306                /* Insert slow queue sequence number */
1307                ppseudo_hdr->seq_num = info->squeseqnum++;
1308                /* Insert application id */
1309                ppseudo_hdr->portsrc = 0;
1310                /* Calculate new checksum */
1311                ppseudo_hdr->checksum = *pmsg++;
1312                for (i = 1; i < 7; i++)
1313                        ppseudo_hdr->checksum ^= *pmsg++;
1314
1315                info->DSPInfoBlk[10] = 0x7200;
1316                info->DSPInfoBlk[11] = htons(info->DSPInfoBlklen);
1317                status = ft1000_write_dpram32(dev, 0,
1318                                (u8 *)&info->DSPInfoBlk[0],
1319                                (unsigned short)(info->DSPInfoBlklen + 22));
1320                status = ft1000_write_register(dev, FT1000_DB_DPRAM_TX,
1321                                FT1000_REG_DOORBELL);
1322                dev->DrvMsgPend = 0;
1323                break;
1324        }
1325        case GET_DRV_ERR_RPT_MSG:{
1326                DEBUG("FT1000:drivermsg:Got GET_DRV_ERR_RPT_MSG\n");
1327                /* copy driver error message to dsp */
1328                dev->DrvMsgPend = 1;
1329                /* allow any outstanding ioctl to finish */
1330                mdelay(10);
1331                status = ft1000_read_register(dev, &tempword,
1332                                FT1000_REG_DOORBELL);
1333                if (tempword & FT1000_DB_DPRAM_TX) {
1334                        mdelay(10);
1335                        status = ft1000_read_register(dev, &tempword,
1336                                        FT1000_REG_DOORBELL);
1337                        if (tempword & FT1000_DB_DPRAM_TX)
1338                                mdelay(10);
1339                }
1340                if ((tempword & FT1000_DB_DPRAM_TX) == 0) {
1341                        /* Put message into Slow Queue Form Pseudo header */
1342                        pmsg = (u16 *) &tempbuffer[0];
1343                        ppseudo_hdr = (struct pseudo_hdr *)pmsg;
1344                        ppseudo_hdr->length = htons(0x0012);
1345                        ppseudo_hdr->source = 0x10;
1346                        ppseudo_hdr->destination = 0x20;
1347                        ppseudo_hdr->portdest = 0;
1348                        ppseudo_hdr->portsrc = 0;
1349                        ppseudo_hdr->sh_str_id = 0;
1350                        ppseudo_hdr->control = 0;
1351                        ppseudo_hdr->rsvd1 = 0;
1352                        ppseudo_hdr->rsvd2 = 0;
1353                        ppseudo_hdr->qos_class = 0;
1354                        /* Insert slow queue sequence number */
1355                        ppseudo_hdr->seq_num = info->squeseqnum++;
1356                        /* Insert application id */
1357                        ppseudo_hdr->portsrc = 0;
1358                        /* Calculate new checksum */
1359                        ppseudo_hdr->checksum = *pmsg++;
1360                        for (i = 1; i < 7; i++)
1361                                ppseudo_hdr->checksum ^= *pmsg++;
1362
1363                        pmsg = (u16 *) &tempbuffer[16];
1364                        *pmsg++ = htons(RSP_DRV_ERR_RPT_MSG);
1365                        *pmsg++ = htons(0x000e);
1366                        *pmsg++ = htons(info->DSP_TIME[0]);
1367                        *pmsg++ = htons(info->DSP_TIME[1]);
1368                        *pmsg++ = htons(info->DSP_TIME[2]);
1369                        *pmsg++ = htons(info->DSP_TIME[3]);
1370                        convert.byte[0] = info->DspVer[0];
1371                        convert.byte[1] = info->DspVer[1];
1372                        *pmsg++ = convert.wrd;
1373                        convert.byte[0] = info->DspVer[2];
1374                        convert.byte[1] = info->DspVer[3];
1375                        *pmsg++ = convert.wrd;
1376                        *pmsg++ = htons(info->DrvErrNum);
1377
1378                        card_send_command(dev, (unsigned char *)&tempbuffer[0],
1379                                        (u16)(0x0012 + PSEUDOSZ));
1380                        info->DrvErrNum = 0;
1381                }
1382                dev->DrvMsgPend = 0;
1383                break;
1384        }
1385        default:
1386                break;
1387        }
1388
1389        status = 0;
1390out:
1391        kfree(cmdbuffer);
1392        DEBUG("return from ft1000_proc_drvmsg\n");
1393        return status;
1394}
1395
1396/* Check which application has registered for dsp broadcast messages */
1397static int dsp_broadcast_msg_id(struct ft1000_usb *dev)
1398{
1399        struct dpram_blk *pdpram_blk;
1400        unsigned long flags;
1401        int i;
1402
1403        for (i = 0; i < MAX_NUM_APP; i++) {
1404                if ((dev->app_info[i].DspBCMsgFlag)
1405                                && (dev->app_info[i].fileobject)
1406                                && (dev->app_info[i].NumOfMsg
1407                                        < MAX_MSG_LIMIT)) {
1408                        pdpram_blk = ft1000_get_buffer(&freercvpool);
1409                        if (pdpram_blk == NULL) {
1410                                DEBUG("Out of memory in free receive command pool\n");
1411                                dev->app_info[i].nRxMsgMiss++;
1412                                return -1;
1413                        }
1414                        if (ft1000_receive_cmd(dev, pdpram_blk->pbuffer,
1415                                                MAX_CMD_SQSIZE)) {
1416                                /* Put message into the
1417                                 * appropriate application block
1418                                 */
1419                                dev->app_info[i].nRxMsg++;
1420                                spin_lock_irqsave(&free_buff_lock, flags);
1421                                list_add_tail(&pdpram_blk->list,
1422                                                &dev->app_info[i] .app_sqlist);
1423                                dev->app_info[i].NumOfMsg++;
1424                                spin_unlock_irqrestore(&free_buff_lock, flags);
1425                                wake_up_interruptible(&dev->app_info[i]
1426                                                .wait_dpram_msg);
1427                        } else {
1428                                dev->app_info[i].nRxMsgMiss++;
1429                                ft1000_free_buffer(pdpram_blk, &freercvpool);
1430                                DEBUG("pdpram_blk::ft1000_get_buffer NULL\n");
1431                                return -1;
1432                        }
1433                }
1434        }
1435        return 0;
1436}
1437
1438static int handle_misc_portid(struct ft1000_usb *dev)
1439{
1440        struct dpram_blk *pdpram_blk;
1441        int i;
1442
1443        pdpram_blk = ft1000_get_buffer(&freercvpool);
1444        if (pdpram_blk == NULL) {
1445                DEBUG("Out of memory in free receive command pool\n");
1446                return -1;
1447        }
1448        if (!ft1000_receive_cmd(dev, pdpram_blk->pbuffer, MAX_CMD_SQSIZE))
1449                goto exit_failure;
1450
1451        /* Search for correct application block */
1452        for (i = 0; i < MAX_NUM_APP; i++) {
1453                if (dev->app_info[i].app_id == ((struct pseudo_hdr *)
1454                                        pdpram_blk->pbuffer)->portdest)
1455                        break;
1456        }
1457        if (i == MAX_NUM_APP) {
1458                DEBUG("FT1000:ft1000_parse_dpram_msg: No application matching id = %d\n", ((struct pseudo_hdr *)pdpram_blk->pbuffer)->portdest);
1459                goto exit_failure;
1460        } else if (dev->app_info[i].NumOfMsg > MAX_MSG_LIMIT) {
1461                goto exit_failure;
1462        } else {
1463                dev->app_info[i].nRxMsg++;
1464                /* Put message into the appropriate application block */
1465                list_add_tail(&pdpram_blk->list, &dev->app_info[i].app_sqlist);
1466                dev->app_info[i].NumOfMsg++;
1467        }
1468        return 0;
1469
1470exit_failure:
1471        ft1000_free_buffer(pdpram_blk, &freercvpool);
1472        return -1;
1473}
1474
1475int ft1000_poll(void *dev_id)
1476{
1477        struct ft1000_usb *dev = (struct ft1000_usb *)dev_id;
1478        struct ft1000_info *info = netdev_priv(dev->net);
1479        u16 tempword;
1480        int status;
1481        u16 size;
1482        int i;
1483        u16 data;
1484        u16 modulo;
1485        u16 portid;
1486
1487        if (ft1000_chkcard(dev) == FALSE) {
1488                DEBUG("ft1000_poll::ft1000_chkcard: failed\n");
1489                return -1;
1490        }
1491        status = ft1000_read_register(dev, &tempword, FT1000_REG_DOORBELL);
1492        if (!status) {
1493                if (tempword & FT1000_DB_DPRAM_RX) {
1494                        status = ft1000_read_dpram16(dev,
1495                                        0x200, (u8 *)&data, 0);
1496                        size = ntohs(data) + 16 + 2;
1497                        if (size % 4) {
1498                                modulo = 4 - (size % 4);
1499                                size = size + modulo;
1500                        }
1501                        status = ft1000_read_dpram16(dev, 0x201,
1502                                        (u8 *)&portid, 1);
1503                        portid &= 0xff;
1504                        if (size < MAX_CMD_SQSIZE) {
1505                                switch (portid) {
1506                                case DRIVERID:
1507                                        DEBUG("ft1000_poll: FT1000_REG_DOORBELL message type: FT1000_DB_DPRAM_RX : portid DRIVERID\n");
1508                                        status = ft1000_proc_drvmsg(dev, size);
1509                                        if (status != 0)
1510                                                return status;
1511                                        break;
1512                                case DSPBCMSGID:
1513                                        status = dsp_broadcast_msg_id(dev);
1514                                        break;
1515                                default:
1516                                        status = handle_misc_portid(dev);
1517                                        break;
1518                                }
1519                        } else
1520                                DEBUG("FT1000:dpc:Invalid total length for SlowQ = %d\n", size);
1521                        status = ft1000_write_register(dev,
1522                                        FT1000_DB_DPRAM_RX,
1523                                        FT1000_REG_DOORBELL);
1524                } else if (tempword & FT1000_DSP_ASIC_RESET) {
1525                        /* Let's reset the ASIC from the Host side as well */
1526                        status = ft1000_write_register(dev, ASIC_RESET_BIT,
1527                                        FT1000_REG_RESET);
1528                        status = ft1000_read_register(dev, &tempword,
1529                                        FT1000_REG_RESET);
1530                        i = 0;
1531                        while (tempword & ASIC_RESET_BIT) {
1532                                status = ft1000_read_register(dev, &tempword,
1533                                                FT1000_REG_RESET);
1534                                usleep_range(9000, 11000);
1535                                i++;
1536                                if (i == 100)
1537                                        break;
1538                        }
1539                        if (i == 100) {
1540                                DEBUG("Unable to reset ASIC\n");
1541                                return 0;
1542                        }
1543                        usleep_range(9000, 11000);
1544                        /* Program WMARK register */
1545                        status = ft1000_write_register(dev, 0x600,
1546                                        FT1000_REG_MAG_WATERMARK);
1547                        /* clear ASIC reset doorbell */
1548                        status = ft1000_write_register(dev,
1549                                        FT1000_DSP_ASIC_RESET,
1550                                        FT1000_REG_DOORBELL);
1551                        usleep_range(9000, 11000);
1552                } else if (tempword & FT1000_ASIC_RESET_REQ) {
1553                        DEBUG("ft1000_poll: FT1000_REG_DOORBELL message type:  FT1000_ASIC_RESET_REQ\n");
1554                        /* clear ASIC reset request from DSP */
1555                        status = ft1000_write_register(dev,
1556                                        FT1000_ASIC_RESET_REQ,
1557                                        FT1000_REG_DOORBELL);
1558                        status = ft1000_write_register(dev, HOST_INTF_BE,
1559                                        FT1000_REG_SUP_CTRL);
1560                        /* copy dsp session record from Adapter block */
1561                        status = ft1000_write_dpram32(dev, 0,
1562                                        (u8 *)&info->DSPSess.Rec[0], 1024);
1563                        status = ft1000_write_register(dev, 0x600,
1564                                        FT1000_REG_MAG_WATERMARK);
1565                        /* ring doorbell to tell DSP that
1566                         * ASIC is out of reset
1567                         * */
1568                        status = ft1000_write_register(dev,
1569                                        FT1000_ASIC_RESET_DSP,
1570                                        FT1000_REG_DOORBELL);
1571                } else if (tempword & FT1000_DB_COND_RESET) {
1572                        DEBUG("ft1000_poll: FT1000_REG_DOORBELL message type:  FT1000_DB_COND_RESET\n");
1573                        if (!dev->fAppMsgPend) {
1574                                /* Reset ASIC and DSP */
1575                                status = ft1000_read_dpram16(dev,
1576                                                FT1000_MAG_DSP_TIMER0,
1577                                                (u8 *)&(info->DSP_TIME[0]),
1578                                                FT1000_MAG_DSP_TIMER0_INDX);
1579                                status = ft1000_read_dpram16(dev,
1580                                                FT1000_MAG_DSP_TIMER1,
1581                                                (u8 *)&(info->DSP_TIME[1]),
1582                                                FT1000_MAG_DSP_TIMER1_INDX);
1583                                status = ft1000_read_dpram16(dev,
1584                                                FT1000_MAG_DSP_TIMER2,
1585                                                (u8 *)&(info->DSP_TIME[2]),
1586                                                FT1000_MAG_DSP_TIMER2_INDX);
1587                                status = ft1000_read_dpram16(dev,
1588                                                FT1000_MAG_DSP_TIMER3,
1589                                                (u8 *)&(info->DSP_TIME[3]),
1590                                                FT1000_MAG_DSP_TIMER3_INDX);
1591                                info->CardReady = 0;
1592                                info->DrvErrNum = DSP_CONDRESET_INFO;
1593                                DEBUG("ft1000_hw:DSP conditional reset requested\n");
1594                                info->ft1000_reset(dev->net);
1595                        } else {
1596                                dev->fProvComplete = false;
1597                                dev->fCondResetPend = true;
1598                        }
1599                        ft1000_write_register(dev, FT1000_DB_COND_RESET,
1600                                        FT1000_REG_DOORBELL);
1601                }
1602        }
1603        return 0;
1604}
1605