linux/drivers/staging/wlags49_h2/wl_netdev.c
<<
>>
Prefs
   1/*******************************************************************************
   2 * Agere Systems Inc.
   3 * Wireless device driver for Linux (wlags49).
   4 *
   5 * Copyright (c) 1998-2003 Agere Systems Inc.
   6 * All rights reserved.
   7 *   http://www.agere.com
   8 *
   9 * Initially developed by TriplePoint, Inc.
  10 *   http://www.triplepoint.com
  11 *
  12 *------------------------------------------------------------------------------
  13 *
  14 *   This file contains handler functions registered with the net_device
  15 *   structure.
  16 *
  17 *------------------------------------------------------------------------------
  18 *
  19 * SOFTWARE LICENSE
  20 *
  21 * This software is provided subject to the following terms and conditions,
  22 * which you should read carefully before using the software.  Using this
  23 * software indicates your acceptance of these terms and conditions.  If you do
  24 * not agree with these terms and conditions, do not use the software.
  25 *
  26 * Copyright © 2003 Agere Systems Inc.
  27 * All rights reserved.
  28 *
  29 * Redistribution and use in source or binary forms, with or without
  30 * modifications, are permitted provided that the following conditions are met:
  31 *
  32 * . Redistributions of source code must retain the above copyright notice, this
  33 *    list of conditions and the following Disclaimer as comments in the code as
  34 *    well as in the documentation and/or other materials provided with the
  35 *    distribution.
  36 *
  37 * . Redistributions in binary form must reproduce the above copyright notice,
  38 *    this list of conditions and the following Disclaimer in the documentation
  39 *    and/or other materials provided with the distribution.
  40 *
  41 * . Neither the name of Agere Systems Inc. nor the names of the contributors
  42 *    may be used to endorse or promote products derived from this software
  43 *    without specific prior written permission.
  44 *
  45 * Disclaimer
  46 *
  47 * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES,
  48 * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
  49 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  ANY
  50 * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
  51 * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY
  52 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  53 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  54 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  55 * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT
  56 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  57 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
  58 * DAMAGE.
  59 *
  60 ******************************************************************************/
  61
  62/*******************************************************************************
  63 * include files
  64 ******************************************************************************/
  65#include <wl_version.h>
  66
  67#include <linux/module.h>
  68#include <linux/slab.h>
  69#include <linux/types.h>
  70#include <linux/kernel.h>
  71// #include <linux/sched.h>
  72// #include <linux/ptrace.h>
  73// #include <linux/slab.h>
  74// #include <linux/ctype.h>
  75// #include <linux/string.h>
  76//#include <linux/timer.h>
  77// #include <linux/interrupt.h>
  78// #include <linux/in.h>
  79// #include <linux/delay.h>
  80// #include <linux/skbuff.h>
  81// #include <asm/io.h>
  82// // #include <asm/bitops.h>
  83
  84#include <linux/netdevice.h>
  85#include <linux/ethtool.h>
  86#include <linux/etherdevice.h>
  87// #include <linux/skbuff.h>
  88// #include <linux/if_arp.h>
  89// #include <linux/ioport.h>
  90
  91#include <debug.h>
  92
  93#include <hcf.h>
  94#include <dhf.h>
  95// #include <hcfdef.h>
  96
  97#include <wl_if.h>
  98#include <wl_internal.h>
  99#include <wl_util.h>
 100#include <wl_priv.h>
 101#include <wl_main.h>
 102#include <wl_netdev.h>
 103#include <wl_wext.h>
 104
 105#ifdef USE_PROFILE
 106#include <wl_profile.h>
 107#endif  /* USE_PROFILE */
 108
 109#ifdef BUS_PCMCIA
 110#include <wl_cs.h>
 111#endif  /* BUS_PCMCIA */
 112
 113#ifdef BUS_PCI
 114#include <wl_pci.h>
 115#endif  /* BUS_PCI */
 116
 117
 118/*******************************************************************************
 119 * global variables
 120 ******************************************************************************/
 121#if DBG
 122extern dbg_info_t *DbgInfo;
 123#endif  /* DBG */
 124
 125
 126#if HCF_ENCAP
 127#define MTU_MAX (HCF_MAX_MSG - ETH_HLEN - 8)
 128#else
 129#define MTU_MAX (HCF_MAX_MSG - ETH_HLEN)
 130#endif
 131
 132//static int mtu = MTU_MAX;
 133//MODULE_PARM(mtu, "i");
 134//MODULE_PARM_DESC(mtu, "MTU");
 135
 136/*******************************************************************************
 137 * macros
 138 ******************************************************************************/
 139#define BLOCK_INPUT(buf, len) \
 140    desc->buf_addr = buf; \
 141    desc->BUF_SIZE = len; \
 142    status = hcf_rcv_msg(&(lp->hcfCtx), desc, 0)
 143
 144#define BLOCK_INPUT_DMA(buf, len) memcpy( buf, desc_next->buf_addr, pktlen )
 145
 146/*******************************************************************************
 147 * function prototypes
 148 ******************************************************************************/
 149
 150/*******************************************************************************
 151 *      wl_init()
 152 *******************************************************************************
 153 *
 154 *  DESCRIPTION:
 155 *
 156 *      We never need to do anything when a "Wireless" device is "initialized"
 157 *  by the net software, because we only register already-found cards.
 158 *
 159 *  PARAMETERS:
 160 *
 161 *      dev - a pointer to the device's net_device structure
 162 *
 163 *  RETURNS:
 164 *
 165 *      0 on success
 166 *      errno value otherwise
 167 *
 168 ******************************************************************************/
 169int wl_init( struct net_device *dev )
 170{
 171//    unsigned long       flags;
 172//    struct wl_private   *lp = wl_priv(dev);
 173    /*------------------------------------------------------------------------*/
 174
 175    DBG_FUNC( "wl_init" );
 176    DBG_ENTER( DbgInfo );
 177
 178    DBG_PARAM( DbgInfo, "dev", "%s (0x%p)", dev->name, dev );
 179
 180    /* Nothing to do, but grab the spinlock anyway just in case we ever need
 181       this routine */
 182//  wl_lock( lp, &flags );
 183//  wl_unlock( lp, &flags );
 184
 185    DBG_LEAVE( DbgInfo );
 186    return 0;
 187} // wl_init
 188/*============================================================================*/
 189
 190/*******************************************************************************
 191 *      wl_config()
 192 *******************************************************************************
 193 *
 194 *  DESCRIPTION:
 195 *
 196 *      Implement the SIOCSIFMAP interface.
 197 *
 198 *  PARAMETERS:
 199 *
 200 *      dev - a pointer to the device's net_device structure
 201 *      map - a pointer to the device's ifmap structure
 202 *
 203 *  RETURNS:
 204 *
 205 *      0 on success
 206 *      errno otherwise
 207 *
 208 ******************************************************************************/
 209int wl_config( struct net_device *dev, struct ifmap *map )
 210{
 211    DBG_FUNC( "wl_config" );
 212    DBG_ENTER( DbgInfo );
 213
 214    DBG_PARAM( DbgInfo, "dev", "%s (0x%p)", dev->name, dev );
 215    DBG_PARAM( DbgInfo, "map", "0x%p", map );
 216
 217    /* The only thing we care about here is a port change. Since this not needed,
 218       ignore the request. */
 219    DBG_TRACE(DbgInfo, "%s: %s called.\n", dev->name, __func__);
 220
 221    DBG_LEAVE( DbgInfo );
 222    return 0;
 223} // wl_config
 224/*============================================================================*/
 225
 226/*******************************************************************************
 227 *      wl_stats()
 228 *******************************************************************************
 229 *
 230 *  DESCRIPTION:
 231 *
 232 *      Return the current device statistics.
 233 *
 234 *  PARAMETERS:
 235 *
 236 *      dev - a pointer to the device's net_device structure
 237 *
 238 *  RETURNS:
 239 *
 240 *      a pointer to a net_device_stats structure containing the network
 241 *      statistics.
 242 *
 243 ******************************************************************************/
 244struct net_device_stats *wl_stats( struct net_device *dev )
 245{
 246#ifdef USE_WDS
 247    int                         count;
 248#endif  /* USE_WDS */
 249    unsigned long               flags;
 250    struct net_device_stats     *pStats;
 251    struct wl_private           *lp = wl_priv(dev);
 252    /*------------------------------------------------------------------------*/
 253
 254    //DBG_FUNC( "wl_stats" );
 255    //DBG_ENTER( DbgInfo );
 256    //DBG_PARAM( DbgInfo, "dev", "%s (0x%p)", dev->name, dev );
 257
 258    pStats = NULL;
 259
 260    wl_lock( lp, &flags );
 261
 262#ifdef USE_RTS
 263    if( lp->useRTS == 1 ) {
 264        wl_unlock( lp, &flags );
 265
 266        //DBG_LEAVE( DbgInfo );
 267        return NULL;
 268    }
 269#endif  /* USE_RTS */
 270
 271    /* Return the statistics for the appropriate device */
 272#ifdef USE_WDS
 273
 274    for( count = 0; count < NUM_WDS_PORTS; count++ ) {
 275        if( dev == lp->wds_port[count].dev ) {
 276            pStats = &( lp->wds_port[count].stats );
 277        }
 278    }
 279
 280#endif  /* USE_WDS */
 281
 282    /* If pStats is still NULL, then the device is not a WDS port */
 283    if( pStats == NULL ) {
 284        pStats = &( lp->stats );
 285    }
 286
 287    wl_unlock( lp, &flags );
 288
 289    //DBG_LEAVE( DbgInfo );
 290
 291    return pStats;
 292} // wl_stats
 293/*============================================================================*/
 294
 295/*******************************************************************************
 296 *      wl_open()
 297 *******************************************************************************
 298 *
 299 *  DESCRIPTION:
 300 *
 301 *      Open the device.
 302 *
 303 *  PARAMETERS:
 304 *
 305 *      dev - a pointer to the device's net_device structure
 306 *
 307 *  RETURNS:
 308 *
 309 *      0 on success
 310 *      errno otherwise
 311 *
 312 ******************************************************************************/
 313int wl_open(struct net_device *dev)
 314{
 315    int                 status = HCF_SUCCESS;
 316    struct wl_private   *lp = wl_priv(dev);
 317    unsigned long       flags;
 318    /*------------------------------------------------------------------------*/
 319
 320    DBG_FUNC( "wl_open" );
 321    DBG_ENTER( DbgInfo );
 322
 323    wl_lock( lp, &flags );
 324
 325#ifdef USE_RTS
 326    if( lp->useRTS == 1 ) {
 327        DBG_TRACE( DbgInfo, "Skipping device open, in RTS mode\n" );
 328        wl_unlock( lp, &flags );
 329        DBG_LEAVE( DbgInfo );
 330        return -EIO;
 331    }
 332#endif  /* USE_RTS */
 333
 334#ifdef USE_PROFILE
 335    parse_config( dev );
 336#endif
 337
 338    if( lp->portState == WVLAN_PORT_STATE_DISABLED ) {
 339        DBG_TRACE( DbgInfo, "Enabling Port 0\n" );
 340        status = wl_enable( lp );
 341
 342        if( status != HCF_SUCCESS ) {
 343            DBG_TRACE( DbgInfo, "Enable port 0 failed: 0x%x\n", status );
 344        }
 345    }
 346
 347    // Holding the lock too long, make a gap to allow other processes
 348    wl_unlock(lp, &flags);
 349    wl_lock( lp, &flags );
 350
 351    if ( strlen( lp->fw_image_filename ) ) {
 352        DBG_TRACE( DbgInfo, ";???? Kludgy way to force a download\n" );
 353        status = wl_go( lp );
 354    } else {
 355        status = wl_apply( lp );
 356    }
 357
 358    // Holding the lock too long, make a gap to allow other processes
 359    wl_unlock(lp, &flags);
 360    wl_lock( lp, &flags );
 361
 362    if( status != HCF_SUCCESS ) {
 363        // Unsuccessful, try reset of the card to recover
 364        status = wl_reset( dev );
 365    }
 366
 367    // Holding the lock too long, make a gap to allow other processes
 368    wl_unlock(lp, &flags);
 369    wl_lock( lp, &flags );
 370
 371    if( status == HCF_SUCCESS ) {
 372        netif_carrier_on( dev );
 373        WL_WDS_NETIF_CARRIER_ON( lp );
 374
 375        lp->is_handling_int = WL_HANDLING_INT; // Start handling interrupts
 376        wl_act_int_on( lp );
 377
 378        netif_start_queue( dev );
 379        WL_WDS_NETIF_START_QUEUE( lp );
 380    } else {
 381        wl_hcf_error( dev, status );            /* Report the error */
 382        netif_device_detach( dev );             /* Stop the device and queue */
 383    }
 384
 385    wl_unlock( lp, &flags );
 386
 387    DBG_LEAVE( DbgInfo );
 388    return status;
 389} // wl_open
 390/*============================================================================*/
 391
 392/*******************************************************************************
 393 *      wl_close()
 394 *******************************************************************************
 395 *
 396 *  DESCRIPTION:
 397 *
 398 *      Close the device.
 399 *
 400 *  PARAMETERS:
 401 *
 402 *      dev - a pointer to the device's net_device structure
 403 *
 404 *  RETURNS:
 405 *
 406 *      0 on success
 407 *      errno otherwise
 408 *
 409 ******************************************************************************/
 410int wl_close( struct net_device *dev )
 411{
 412    struct wl_private   *lp = wl_priv(dev);
 413    unsigned long   flags;
 414    /*------------------------------------------------------------------------*/
 415
 416    DBG_FUNC("wl_close");
 417    DBG_ENTER(DbgInfo);
 418    DBG_PARAM(DbgInfo, "dev", "%s (0x%p)", dev->name, dev);
 419
 420    /* Mark the adapter as busy */
 421    netif_stop_queue( dev );
 422    WL_WDS_NETIF_STOP_QUEUE( lp );
 423
 424    netif_carrier_off( dev );
 425    WL_WDS_NETIF_CARRIER_OFF( lp );
 426
 427    /* Shutdown the adapter:
 428            Disable adapter interrupts
 429            Stop Tx/Rx
 430            Update statistics
 431            Set low power mode
 432    */
 433
 434    wl_lock( lp, &flags );
 435
 436    wl_act_int_off( lp );
 437    lp->is_handling_int = WL_NOT_HANDLING_INT; // Stop handling interrupts
 438
 439#ifdef USE_RTS
 440    if( lp->useRTS == 1 ) {
 441        DBG_TRACE( DbgInfo, "Skipping device close, in RTS mode\n" );
 442        wl_unlock( lp, &flags );
 443        DBG_LEAVE( DbgInfo );
 444        return -EIO;
 445    }
 446#endif  /* USE_RTS */
 447
 448    /* Disable the ports */
 449    wl_disable( lp );
 450
 451    wl_unlock( lp, &flags );
 452
 453    DBG_LEAVE( DbgInfo );
 454    return 0;
 455} // wl_close
 456/*============================================================================*/
 457
 458static void wl_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
 459{
 460    strlcpy(info->driver, DRIVER_NAME, sizeof(info->driver));
 461    strlcpy(info->version, DRV_VERSION_STR, sizeof(info->version));
 462//      strlcpy(info.fw_version, priv->fw_name,
 463//      sizeof(info.fw_version));
 464
 465    if (dev->dev.parent) {
 466        dev_set_name(dev->dev.parent, "%s", info->bus_info);
 467        //strlcpy(info->bus_info, dev->dev.parent->bus_id,
 468        //      sizeof(info->bus_info));
 469    } else {
 470        snprintf(info->bus_info, sizeof(info->bus_info),
 471                "PCMCIA FIXME");
 472//                  "PCMCIA 0x%lx", priv->hw.iobase);
 473    }
 474} // wl_get_drvinfo
 475
 476static struct ethtool_ops wl_ethtool_ops = {
 477    .get_drvinfo = wl_get_drvinfo,
 478    .get_link = ethtool_op_get_link,
 479};
 480
 481
 482/*******************************************************************************
 483 *      wl_ioctl()
 484 *******************************************************************************
 485 *
 486 *  DESCRIPTION:
 487 *
 488 *      The IOCTL handler for the device.
 489 *
 490 *  PARAMETERS:
 491 *
 492 *      dev - a pointer to the device's net_device struct.
 493 *      rq  - a pointer to the IOCTL request buffer.
 494 *      cmd - the IOCTL command code.
 495 *
 496 *  RETURNS:
 497 *
 498 *      0 on success
 499 *      errno value otherwise
 500 *
 501 ******************************************************************************/
 502int wl_ioctl( struct net_device *dev, struct ifreq *rq, int cmd )
 503{
 504    struct wl_private  *lp = wl_priv(dev);
 505    unsigned long           flags;
 506    int                     ret = 0;
 507    /*------------------------------------------------------------------------*/
 508
 509    DBG_FUNC( "wl_ioctl" );
 510    DBG_ENTER(DbgInfo);
 511    DBG_PARAM(DbgInfo, "dev", "%s (0x%p)", dev->name, dev);
 512    DBG_PARAM(DbgInfo, "rq", "0x%p", rq);
 513    DBG_PARAM(DbgInfo, "cmd", "0x%04x", cmd);
 514
 515    wl_lock( lp, &flags );
 516
 517    wl_act_int_off( lp );
 518
 519#ifdef USE_RTS
 520    if( lp->useRTS == 1 ) {
 521        /* Handle any RTS IOCTL here */
 522        if( cmd == WL_IOCTL_RTS ) {
 523            DBG_TRACE( DbgInfo, "IOCTL: WL_IOCTL_RTS\n" );
 524            ret = wvlan_rts( (struct rtsreq *)rq, dev->base_addr );
 525        } else {
 526            DBG_TRACE( DbgInfo, "IOCTL not supported in RTS mode: 0x%X\n", cmd );
 527            ret = -EOPNOTSUPP;
 528        }
 529
 530        goto out_act_int_on_unlock;
 531    }
 532#endif  /* USE_RTS */
 533
 534    /* Only handle UIL IOCTL requests when the UIL has the system blocked. */
 535    if( !(( lp->flags & WVLAN2_UIL_BUSY ) && ( cmd != WVLAN2_IOCTL_UIL ))) {
 536#ifdef USE_UIL
 537        struct uilreq  *urq = (struct uilreq *)rq;
 538#endif /* USE_UIL */
 539
 540        switch( cmd ) {
 541                // ================== Private IOCTLs (up to 16) ==================
 542#ifdef USE_UIL
 543        case WVLAN2_IOCTL_UIL:
 544             DBG_TRACE( DbgInfo, "IOCTL: WVLAN2_IOCTL_UIL\n" );
 545             ret = wvlan_uil( urq, lp );
 546             break;
 547#endif  /* USE_UIL */
 548
 549        default:
 550             DBG_TRACE(DbgInfo, "IOCTL CODE NOT SUPPORTED: 0x%X\n", cmd );
 551             ret = -EOPNOTSUPP;
 552             break;
 553        }
 554    } else {
 555        DBG_WARNING( DbgInfo, "DEVICE IS BUSY, CANNOT PROCESS REQUEST\n" );
 556        ret = -EBUSY;
 557    }
 558
 559#ifdef USE_RTS
 560out_act_int_on_unlock:
 561#endif  /* USE_RTS */
 562    wl_act_int_on( lp );
 563
 564    wl_unlock( lp, &flags );
 565
 566    DBG_LEAVE( DbgInfo );
 567    return ret;
 568} // wl_ioctl
 569/*============================================================================*/
 570
 571#ifdef CONFIG_NET_POLL_CONTROLLER
 572void wl_poll(struct net_device *dev)
 573{
 574    struct wl_private *lp = wl_priv(dev);
 575    unsigned long flags;
 576    struct pt_regs regs;
 577
 578    wl_lock( lp, &flags );
 579    wl_isr(dev->irq, dev, &regs);
 580    wl_unlock( lp, &flags );
 581}
 582#endif
 583
 584/*******************************************************************************
 585 *      wl_tx_timeout()
 586 *******************************************************************************
 587 *
 588 *  DESCRIPTION:
 589 *
 590 *      The handler called when, for some reason, a Tx request is not completed.
 591 *
 592 *  PARAMETERS:
 593 *
 594 *      dev - a pointer to the device's net_device struct.
 595 *
 596 *  RETURNS:
 597 *
 598 *      N/A
 599 *
 600 ******************************************************************************/
 601void wl_tx_timeout( struct net_device *dev )
 602{
 603#ifdef USE_WDS
 604    int                     count;
 605#endif  /* USE_WDS */
 606    unsigned long           flags;
 607    struct wl_private       *lp = wl_priv(dev);
 608    struct net_device_stats *pStats = NULL;
 609    /*------------------------------------------------------------------------*/
 610
 611    DBG_FUNC( "wl_tx_timeout" );
 612    DBG_ENTER( DbgInfo );
 613
 614    DBG_WARNING( DbgInfo, "%s: Transmit timeout.\n", dev->name );
 615
 616    wl_lock( lp, &flags );
 617
 618#ifdef USE_RTS
 619    if( lp->useRTS == 1 ) {
 620        DBG_TRACE( DbgInfo, "Skipping tx_timeout handler, in RTS mode\n" );
 621        wl_unlock( lp, &flags );
 622
 623        DBG_LEAVE( DbgInfo );
 624        return;
 625    }
 626#endif  /* USE_RTS */
 627
 628    /* Figure out which device (the "root" device or WDS port) this timeout
 629       is for */
 630#ifdef USE_WDS
 631
 632    for( count = 0; count < NUM_WDS_PORTS; count++ ) {
 633        if( dev == lp->wds_port[count].dev ) {
 634            pStats = &( lp->wds_port[count].stats );
 635
 636            /* Break the loop so that we can use the counter to access WDS
 637               information in the private structure */
 638            break;
 639        }
 640    }
 641
 642#endif  /* USE_WDS */
 643
 644    /* If pStats is still NULL, then the device is not a WDS port */
 645    if( pStats == NULL ) {
 646        pStats = &( lp->stats );
 647    }
 648
 649    /* Accumulate the timeout error */
 650    pStats->tx_errors++;
 651
 652    wl_unlock( lp, &flags );
 653
 654    DBG_LEAVE( DbgInfo );
 655} // wl_tx_timeout
 656/*============================================================================*/
 657
 658/*******************************************************************************
 659 *      wl_send()
 660 *******************************************************************************
 661 *
 662 *  DESCRIPTION:
 663 *
 664 *      The routine which performs data transmits.
 665 *
 666 *  PARAMETERS:
 667 *
 668 *      lp  - a pointer to the device's wl_private struct.
 669 *
 670 *  RETURNS:
 671 *
 672 *      0 on success
 673 *      1 on error
 674 *
 675 ******************************************************************************/
 676int wl_send( struct wl_private *lp )
 677{
 678
 679    int                 status;
 680    DESC_STRCT          *desc;
 681    WVLAN_LFRAME        *txF = NULL;
 682    struct list_head    *element;
 683    int                 len;
 684    /*------------------------------------------------------------------------*/
 685
 686    DBG_FUNC( "wl_send" );
 687
 688    if( lp == NULL ) {
 689        DBG_ERROR( DbgInfo, "Private adapter struct is NULL\n" );
 690        return FALSE;
 691    }
 692    if( lp->dev == NULL ) {
 693        DBG_ERROR( DbgInfo, "net_device struct in wl_private is NULL\n" );
 694        return FALSE;
 695    }
 696
 697    /* Check for the availability of FIDs; if none are available, don't take any
 698       frames off the txQ */
 699    if( lp->hcfCtx.IFB_RscInd == 0 ) {
 700        return FALSE;
 701    }
 702
 703    /* Reclaim the TxQ Elements and place them back on the free queue */
 704    if( !list_empty( &( lp->txQ[0] ))) {
 705        element = lp->txQ[0].next;
 706
 707        txF = (WVLAN_LFRAME * )list_entry( element, WVLAN_LFRAME, node );
 708        if( txF != NULL ) {
 709            lp->txF.skb  = txF->frame.skb;
 710            lp->txF.port = txF->frame.port;
 711
 712            txF->frame.skb  = NULL;
 713            txF->frame.port = 0;
 714
 715            list_del( &( txF->node ));
 716            list_add( element, &( lp->txFree ));
 717
 718            lp->txQ_count--;
 719
 720            if( lp->txQ_count < TX_Q_LOW_WATER_MARK ) {
 721                if( lp->netif_queue_on == FALSE ) {
 722                    DBG_TX( DbgInfo, "Kickstarting Q: %d\n", lp->txQ_count );
 723                    netif_wake_queue( lp->dev );
 724                    WL_WDS_NETIF_WAKE_QUEUE( lp );
 725                    lp->netif_queue_on = TRUE;
 726                }
 727            }
 728        }
 729    }
 730
 731    if( lp->txF.skb == NULL ) {
 732        return FALSE;
 733    }
 734
 735    /* If the device has resources (FIDs) available, then Tx the packet */
 736    /* Format the TxRequest and send it to the adapter */
 737    len = lp->txF.skb->len < ETH_ZLEN ? ETH_ZLEN : lp->txF.skb->len;
 738
 739    desc                    = &( lp->desc_tx );
 740    desc->buf_addr          = lp->txF.skb->data;
 741    desc->BUF_CNT           = len;
 742    desc->next_desc_addr    = NULL;
 743
 744    status = hcf_send_msg( &( lp->hcfCtx ), desc, lp->txF.port );
 745
 746    if( status == HCF_SUCCESS ) {
 747        lp->dev->trans_start = jiffies;
 748
 749        DBG_TX( DbgInfo, "Transmit...\n" );
 750
 751        if( lp->txF.port == HCF_PORT_0 ) {
 752            lp->stats.tx_packets++;
 753            lp->stats.tx_bytes += lp->txF.skb->len;
 754        }
 755
 756#ifdef USE_WDS
 757        else
 758        {
 759            lp->wds_port[(( lp->txF.port >> 8 ) - 1)].stats.tx_packets++;
 760            lp->wds_port[(( lp->txF.port >> 8 ) - 1)].stats.tx_bytes += lp->txF.skb->len;
 761        }
 762
 763#endif  /* USE_WDS */
 764
 765        /* Free the skb and perform queue cleanup, as the buffer was
 766            transmitted successfully */
 767        dev_kfree_skb( lp->txF.skb );
 768
 769        lp->txF.skb = NULL;
 770        lp->txF.port = 0;
 771    }
 772
 773    return TRUE;
 774} // wl_send
 775/*============================================================================*/
 776
 777/*******************************************************************************
 778 *      wl_tx()
 779 *******************************************************************************
 780 *
 781 *  DESCRIPTION:
 782 *
 783 *      The Tx handler function for the network layer.
 784 *
 785 *  PARAMETERS:
 786 *
 787 *      skb - a pointer to the sk_buff structure containing the data to transfer.
 788 *      dev - a pointer to the device's net_device structure.
 789 *
 790 *  RETURNS:
 791 *
 792 *      0 on success
 793 *      1 on error
 794 *
 795 ******************************************************************************/
 796int wl_tx( struct sk_buff *skb, struct net_device *dev, int port )
 797{
 798    unsigned long           flags;
 799    struct wl_private       *lp = wl_priv(dev);
 800    WVLAN_LFRAME            *txF = NULL;
 801    struct list_head        *element;
 802    /*------------------------------------------------------------------------*/
 803
 804    DBG_FUNC( "wl_tx" );
 805
 806    /* Grab the spinlock */
 807    wl_lock( lp, &flags );
 808
 809    if( lp->flags & WVLAN2_UIL_BUSY ) {
 810        DBG_WARNING( DbgInfo, "UIL has device blocked\n" );
 811        /* Start dropping packets here??? */
 812        wl_unlock( lp, &flags );
 813        return 1;
 814    }
 815
 816#ifdef USE_RTS
 817    if( lp->useRTS == 1 ) {
 818        DBG_PRINT( "RTS: we're getting a Tx...\n" );
 819        wl_unlock( lp, &flags );
 820        return 1;
 821    }
 822#endif  /* USE_RTS */
 823
 824    if( !lp->use_dma ) {
 825        /* Get an element from the queue */
 826        element = lp->txFree.next;
 827        txF = (WVLAN_LFRAME *)list_entry( element, WVLAN_LFRAME, node );
 828        if( txF == NULL ) {
 829            DBG_ERROR( DbgInfo, "Problem with list_entry\n" );
 830            wl_unlock( lp, &flags );
 831            return 1;
 832        }
 833        /* Fill out the frame */
 834        txF->frame.skb = skb;
 835        txF->frame.port = port;
 836        /* Move the frame to the txQ */
 837        /* NOTE: Here's where we would do priority queueing */
 838        list_move(&(txF->node), &(lp->txQ[0]));
 839
 840        lp->txQ_count++;
 841        if( lp->txQ_count >= DEFAULT_NUM_TX_FRAMES ) {
 842            DBG_TX( DbgInfo, "Q Full: %d\n", lp->txQ_count );
 843            if( lp->netif_queue_on == TRUE ) {
 844                netif_stop_queue( lp->dev );
 845                WL_WDS_NETIF_STOP_QUEUE( lp );
 846                lp->netif_queue_on = FALSE;
 847            }
 848        }
 849    }
 850    wl_act_int_off( lp ); /* Disable Interrupts */
 851
 852    /* Send the data to the hardware using the appropriate method */
 853#ifdef ENABLE_DMA
 854    if( lp->use_dma ) {
 855        wl_send_dma( lp, skb, port );
 856    }
 857    else
 858#endif
 859    {
 860        wl_send( lp );
 861    }
 862    /* Re-enable Interrupts, release the spinlock and return */
 863    wl_act_int_on( lp );
 864    wl_unlock( lp, &flags );
 865    return 0;
 866} // wl_tx
 867/*============================================================================*/
 868
 869/*******************************************************************************
 870 *      wl_rx()
 871 *******************************************************************************
 872 *
 873 *  DESCRIPTION:
 874 *
 875 *      The routine which performs data reception.
 876 *
 877 *  PARAMETERS:
 878 *
 879 *      dev - a pointer to the device's net_device structure.
 880 *
 881 *  RETURNS:
 882 *
 883 *      0 on success
 884 *      1 on error
 885 *
 886 ******************************************************************************/
 887int wl_rx(struct net_device *dev)
 888{
 889    int                     port;
 890    struct sk_buff          *skb;
 891    struct wl_private       *lp = wl_priv(dev);
 892    int                     status;
 893    hcf_16                  pktlen;
 894    hcf_16                  hfs_stat;
 895    DESC_STRCT              *desc;
 896    /*------------------------------------------------------------------------*/
 897
 898    DBG_FUNC("wl_rx")
 899    DBG_PARAM(DbgInfo, "dev", "%s (0x%p)", dev->name, dev);
 900
 901    if(!( lp->flags & WVLAN2_UIL_BUSY )) {
 902
 903#ifdef USE_RTS
 904        if( lp->useRTS == 1 ) {
 905            DBG_PRINT( "RTS: We're getting an Rx...\n" );
 906            return -EIO;
 907        }
 908#endif  /* USE_RTS */
 909
 910        /* Read the HFS_STAT register from the lookahead buffer */
 911        hfs_stat = (hcf_16)(( lp->lookAheadBuf[HFS_STAT] ) |
 912                            ( lp->lookAheadBuf[HFS_STAT + 1] << 8 ));
 913
 914        /* Make sure the frame isn't bad */
 915        if(( hfs_stat & HFS_STAT_ERR ) != HCF_SUCCESS ) {
 916            DBG_WARNING( DbgInfo, "HFS_STAT_ERROR (0x%x) in Rx Packet\n",
 917                         lp->lookAheadBuf[HFS_STAT] );
 918            return -EIO;
 919        }
 920
 921        /* Determine what port this packet is for */
 922        port = ( hfs_stat >> 8 ) & 0x0007;
 923        DBG_RX( DbgInfo, "Rx frame for port %d\n", port );
 924
 925        pktlen = lp->hcfCtx.IFB_RxLen;
 926        if (pktlen != 0) {
 927            skb = ALLOC_SKB(pktlen);
 928            if (skb != NULL) {
 929                /* Set the netdev based on the port */
 930                switch( port ) {
 931#ifdef USE_WDS
 932                case 1:
 933                case 2:
 934                case 3:
 935                case 4:
 936                case 5:
 937                case 6:
 938                    skb->dev = lp->wds_port[port-1].dev;
 939                    break;
 940#endif  /* USE_WDS */
 941
 942                case 0:
 943                default:
 944                    skb->dev = dev;
 945                    break;
 946                }
 947
 948                desc = &( lp->desc_rx );
 949
 950                desc->next_desc_addr = NULL;
 951
 952/*
 953#define BLOCK_INPUT(buf, len) \
 954    desc->buf_addr = buf; \
 955    desc->BUF_SIZE = len; \
 956    status = hcf_rcv_msg(&(lp->hcfCtx), desc, 0)
 957*/
 958
 959                GET_PACKET( skb->dev, skb, pktlen );
 960
 961                if( status == HCF_SUCCESS ) {
 962                    netif_rx( skb );
 963
 964                    if( port == 0 ) {
 965                        lp->stats.rx_packets++;
 966                        lp->stats.rx_bytes += pktlen;
 967                    }
 968#ifdef USE_WDS
 969                    else
 970                    {
 971                        lp->wds_port[port-1].stats.rx_packets++;
 972                        lp->wds_port[port-1].stats.rx_bytes += pktlen;
 973                    }
 974#endif  /* USE_WDS */
 975
 976                    dev->last_rx = jiffies;
 977
 978#ifdef WIRELESS_EXT
 979#ifdef WIRELESS_SPY
 980                    if( lp->spydata.spy_number > 0 ) {
 981                        char *srcaddr = skb->mac.raw + MAC_ADDR_SIZE;
 982
 983                        wl_spy_gather( dev, srcaddr );
 984                    }
 985#endif /* WIRELESS_SPY */
 986#endif /* WIRELESS_EXT */
 987                } else {
 988                    DBG_ERROR( DbgInfo, "Rx request to card FAILED\n" );
 989
 990                    if( port == 0 ) {
 991                        lp->stats.rx_dropped++;
 992                    }
 993#ifdef USE_WDS
 994                    else
 995                    {
 996                        lp->wds_port[port-1].stats.rx_dropped++;
 997                    }
 998#endif  /* USE_WDS */
 999
1000                    dev_kfree_skb( skb );
1001                }
1002            } else {
1003                DBG_ERROR( DbgInfo, "Could not alloc skb\n" );
1004
1005                if( port == 0 ) {
1006                    lp->stats.rx_dropped++;
1007                }
1008#ifdef USE_WDS
1009                else
1010                {
1011                    lp->wds_port[port-1].stats.rx_dropped++;
1012                }
1013#endif  /* USE_WDS */
1014            }
1015        }
1016    }
1017
1018    return 0;
1019} // wl_rx
1020/*============================================================================*/
1021
1022/*******************************************************************************
1023 *      wl_multicast()
1024 *******************************************************************************
1025 *
1026 *  DESCRIPTION:
1027 *
1028 *      Function to handle multicast packets
1029 *
1030 *  PARAMETERS:
1031 *
1032 *      dev - a pointer to the device's net_device structure.
1033 *
1034 *  RETURNS:
1035 *
1036 *      N/A
1037 *
1038 ******************************************************************************/
1039#ifdef NEW_MULTICAST
1040
1041void wl_multicast( struct net_device *dev )
1042{
1043#if 1 //;? (HCF_TYPE) & HCF_TYPE_STA //;?should we return an error status in AP mode
1044//;?seems reasonable that even an AP-only driver could afford this small additional footprint
1045
1046    int                 x;
1047    struct netdev_hw_addr *ha;
1048    struct wl_private   *lp = wl_priv(dev);
1049    unsigned long       flags;
1050    /*------------------------------------------------------------------------*/
1051
1052    DBG_FUNC( "wl_multicast" );
1053    DBG_ENTER( DbgInfo );
1054    DBG_PARAM( DbgInfo, "dev", "%s (0x%p)", dev->name, dev );
1055
1056    if( !wl_adapter_is_open( dev )) {
1057        DBG_LEAVE( DbgInfo );
1058        return;
1059    }
1060
1061#if DBG
1062    if( DBG_FLAGS( DbgInfo ) & DBG_PARAM_ON ) {
1063        DBG_PRINT("  flags: %s%s%s\n",
1064            ( dev->flags & IFF_PROMISC ) ? "Promiscuous " : "",
1065            ( dev->flags & IFF_MULTICAST ) ? "Multicast " : "",
1066            ( dev->flags & IFF_ALLMULTI ) ? "All-Multicast" : "" );
1067
1068        DBG_PRINT( "  mc_count: %d\n", netdev_mc_count(dev));
1069
1070        netdev_for_each_mc_addr(ha, dev)
1071        DBG_PRINT("    %pM (%d)\n", ha->addr, dev->addr_len);
1072    }
1073#endif /* DBG */
1074
1075    if(!( lp->flags & WVLAN2_UIL_BUSY )) {
1076
1077#ifdef USE_RTS
1078        if( lp->useRTS == 1 ) {
1079            DBG_TRACE( DbgInfo, "Skipping multicast, in RTS mode\n" );
1080
1081            DBG_LEAVE( DbgInfo );
1082            return;
1083        }
1084#endif  /* USE_RTS */
1085
1086        wl_lock( lp, &flags );
1087        wl_act_int_off( lp );
1088
1089                if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_STA  ) {
1090            if( dev->flags & IFF_PROMISC ) {
1091                /* Enable promiscuous mode */
1092                lp->ltvRecord.len       = 2;
1093                lp->ltvRecord.typ       = CFG_PROMISCUOUS_MODE;
1094                lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( 1 );
1095                DBG_PRINT( "Enabling Promiscuous mode (IFF_PROMISC)\n" );
1096                hcf_put_info( &( lp->hcfCtx ), (LTVP)&( lp->ltvRecord ));
1097            }
1098            else if ((netdev_mc_count(dev) > HCF_MAX_MULTICAST) ||
1099                    ( dev->flags & IFF_ALLMULTI )) {
1100                /* Shutting off this filter will enable all multicast frames to
1101                   be sent up from the device; however, this is a static RID, so
1102                   a call to wl_apply() is needed */
1103                lp->ltvRecord.len       = 2;
1104                lp->ltvRecord.typ       = CFG_CNF_RX_ALL_GROUP_ADDR;
1105                lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( 0 );
1106                DBG_PRINT( "Enabling all multicast mode (IFF_ALLMULTI)\n" );
1107                hcf_put_info( &( lp->hcfCtx ), (LTVP)&( lp->ltvRecord ));
1108                wl_apply( lp );
1109            }
1110            else if (!netdev_mc_empty(dev)) {
1111                /* Set the multicast addresses */
1112                lp->ltvRecord.len = ( netdev_mc_count(dev) * 3 ) + 1;
1113                lp->ltvRecord.typ = CFG_GROUP_ADDR;
1114
1115                x = 0;
1116                netdev_for_each_mc_addr(ha, dev)
1117                    memcpy(&(lp->ltvRecord.u.u8[x++ * ETH_ALEN]),
1118                           ha->addr, ETH_ALEN);
1119                DBG_PRINT( "Setting multicast list\n" );
1120                hcf_put_info( &( lp->hcfCtx ), (LTVP)&( lp->ltvRecord ));
1121            } else {
1122                /* Disable promiscuous mode */
1123                lp->ltvRecord.len       = 2;
1124                lp->ltvRecord.typ       = CFG_PROMISCUOUS_MODE;
1125                lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( 0 );
1126                DBG_PRINT( "Disabling Promiscuous mode\n" );
1127                hcf_put_info( &( lp->hcfCtx ), (LTVP)&( lp->ltvRecord ));
1128
1129                /* Disable multicast mode */
1130                lp->ltvRecord.len = 2;
1131                lp->ltvRecord.typ = CFG_GROUP_ADDR;
1132                DBG_PRINT( "Disabling Multicast mode\n" );
1133                hcf_put_info( &( lp->hcfCtx ), (LTVP)&( lp->ltvRecord ));
1134
1135                /* Turning on this filter will prevent all multicast frames from
1136                   being sent up from the device; however, this is a static RID,
1137                   so a call to wl_apply() is needed */
1138                lp->ltvRecord.len       = 2;
1139                lp->ltvRecord.typ       = CFG_CNF_RX_ALL_GROUP_ADDR;
1140                lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( 1 );
1141                DBG_PRINT( "Disabling all multicast mode (IFF_ALLMULTI)\n" );
1142                hcf_put_info( &( lp->hcfCtx ), (LTVP)&( lp->ltvRecord ));
1143                wl_apply( lp );
1144            }
1145        }
1146        wl_act_int_on( lp );
1147        wl_unlock( lp, &flags );
1148    }
1149    DBG_LEAVE( DbgInfo );
1150#endif /* HCF_STA */
1151} // wl_multicast
1152/*============================================================================*/
1153
1154#else /* NEW_MULTICAST */
1155
1156void wl_multicast( struct net_device *dev, int num_addrs, void *addrs )
1157{
1158    DBG_FUNC( "wl_multicast");
1159    DBG_ENTER(DbgInfo);
1160
1161    DBG_PARAM( DbgInfo, "dev", "%s (0x%p)", dev->name, dev );
1162    DBG_PARAM( DbgInfo, "num_addrs", "%d", num_addrs );
1163    DBG_PARAM( DbgInfo, "addrs", "0x%p", addrs );
1164
1165#error Obsolete set multicast interface!
1166
1167    DBG_LEAVE( DbgInfo );
1168} // wl_multicast
1169/*============================================================================*/
1170
1171#endif /* NEW_MULTICAST */
1172
1173static const struct net_device_ops wl_netdev_ops =
1174{
1175    .ndo_start_xmit         = &wl_tx_port0,
1176
1177    .ndo_set_config         = &wl_config,
1178    .ndo_get_stats          = &wl_stats,
1179    .ndo_set_rx_mode        = &wl_multicast,
1180
1181    .ndo_init               = &wl_insert,
1182    .ndo_open               = &wl_adapter_open,
1183    .ndo_stop               = &wl_adapter_close,
1184    .ndo_do_ioctl           = &wl_ioctl,
1185
1186    .ndo_tx_timeout         = &wl_tx_timeout,
1187
1188#ifdef CONFIG_NET_POLL_CONTROLLER
1189    .ndo_poll_controller    = wl_poll,
1190#endif
1191};
1192
1193/*******************************************************************************
1194 *      wl_device_alloc()
1195 *******************************************************************************
1196 *
1197 *  DESCRIPTION:
1198 *
1199 *      Create instances of net_device and wl_private for the new adapter
1200 *  and register the device's entry points in the net_device structure.
1201 *
1202 *  PARAMETERS:
1203 *
1204 *      N/A
1205 *
1206 *  RETURNS:
1207 *
1208 *      a pointer to an allocated and initialized net_device struct for this
1209 *      device.
1210 *
1211 ******************************************************************************/
1212struct net_device * wl_device_alloc( void )
1213{
1214    struct net_device   *dev = NULL;
1215    struct wl_private   *lp = NULL;
1216    /*------------------------------------------------------------------------*/
1217
1218    DBG_FUNC( "wl_device_alloc" );
1219    DBG_ENTER( DbgInfo );
1220
1221    /* Alloc a net_device struct */
1222    dev = alloc_etherdev(sizeof(struct wl_private));
1223    if (!dev)
1224        return NULL;
1225
1226    /* Initialize the 'next' pointer in the struct. Currently only used for PCI,
1227       but do it here just in case it's used for other buses in the future */
1228    lp = wl_priv(dev);
1229
1230
1231    /* Check MTU */
1232    if( dev->mtu > MTU_MAX )
1233    {
1234            DBG_WARNING( DbgInfo, "%s: MTU set too high, limiting to %d.\n",
1235                        dev->name, MTU_MAX );
1236        dev->mtu = MTU_MAX;
1237    }
1238
1239    /* Setup the function table in the device structure. */
1240
1241    dev->wireless_handlers = (struct iw_handler_def *)&wl_iw_handler_def;
1242    lp->wireless_data.spy_data = &lp->spy_data;
1243    dev->wireless_data = &lp->wireless_data;
1244
1245    dev->netdev_ops = &wl_netdev_ops;
1246
1247    dev->watchdog_timeo     = TX_TIMEOUT;
1248
1249    dev->ethtool_ops        = &wl_ethtool_ops;
1250
1251    netif_stop_queue( dev );
1252
1253    /* Allocate virtual devices for WDS support if needed */
1254    WL_WDS_DEVICE_ALLOC( lp );
1255
1256    DBG_LEAVE( DbgInfo );
1257    return dev;
1258} // wl_device_alloc
1259/*============================================================================*/
1260
1261/*******************************************************************************
1262 *      wl_device_dealloc()
1263 *******************************************************************************
1264 *
1265 *  DESCRIPTION:
1266 *
1267 *      Free instances of net_device and wl_private strcutres for an adapter
1268 *  and perform basic cleanup.
1269 *
1270 *  PARAMETERS:
1271 *
1272 *      dev - a pointer to the device's net_device structure.
1273 *
1274 *  RETURNS:
1275 *
1276 *      N/A
1277 *
1278 ******************************************************************************/
1279void wl_device_dealloc( struct net_device *dev )
1280{
1281//    struct wl_private   *lp = wl_priv(dev);
1282    /*------------------------------------------------------------------------*/
1283
1284    DBG_FUNC( "wl_device_dealloc" );
1285    DBG_ENTER( DbgInfo );
1286
1287    /* Dealloc the WDS ports */
1288    WL_WDS_DEVICE_DEALLOC( lp );
1289
1290    free_netdev( dev );
1291
1292    DBG_LEAVE( DbgInfo );
1293} // wl_device_dealloc
1294/*============================================================================*/
1295
1296/*******************************************************************************
1297 *      wl_tx_port0()
1298 *******************************************************************************
1299 *
1300 *  DESCRIPTION:
1301 *
1302 *      The handler routine for Tx over HCF_PORT_0.
1303 *
1304 *  PARAMETERS:
1305 *
1306 *      skb - a pointer to the sk_buff to transmit.
1307 *      dev - a pointer to a net_device structure representing HCF_PORT_0.
1308 *
1309 *  RETURNS:
1310 *
1311 *      N/A
1312 *
1313 ******************************************************************************/
1314int wl_tx_port0( struct sk_buff *skb, struct net_device *dev )
1315{
1316    DBG_TX( DbgInfo, "Tx on Port 0\n" );
1317
1318    return wl_tx( skb, dev, HCF_PORT_0 );
1319#ifdef ENABLE_DMA
1320    return wl_tx_dma( skb, dev, HCF_PORT_0 );
1321#endif
1322} // wl_tx_port0
1323/*============================================================================*/
1324
1325#ifdef USE_WDS
1326
1327/*******************************************************************************
1328 *      wl_tx_port1()
1329 *******************************************************************************
1330 *
1331 *  DESCRIPTION:
1332 *
1333 *      The handler routine for Tx over HCF_PORT_1.
1334 *
1335 *  PARAMETERS:
1336 *
1337 *      skb - a pointer to the sk_buff to transmit.
1338 *      dev - a pointer to a net_device structure representing HCF_PORT_1.
1339 *
1340 *  RETURNS:
1341 *
1342 *      N/A
1343 *
1344 ******************************************************************************/
1345int wl_tx_port1( struct sk_buff *skb, struct net_device *dev )
1346{
1347    DBG_TX( DbgInfo, "Tx on Port 1\n" );
1348    return wl_tx( skb, dev, HCF_PORT_1 );
1349} // wl_tx_port1
1350/*============================================================================*/
1351
1352/*******************************************************************************
1353 *      wl_tx_port2()
1354 *******************************************************************************
1355 *
1356 *  DESCRIPTION:
1357 *
1358 *      The handler routine for Tx over HCF_PORT_2.
1359 *
1360 *  PARAMETERS:
1361 *
1362 *      skb - a pointer to the sk_buff to transmit.
1363 *      dev - a pointer to a net_device structure representing HCF_PORT_2.
1364 *
1365 *  RETURNS:
1366 *
1367 *      N/A
1368 *
1369 ******************************************************************************/
1370int wl_tx_port2( struct sk_buff *skb, struct net_device *dev )
1371{
1372    DBG_TX( DbgInfo, "Tx on Port 2\n" );
1373    return wl_tx( skb, dev, HCF_PORT_2 );
1374} // wl_tx_port2
1375/*============================================================================*/
1376
1377/*******************************************************************************
1378 *      wl_tx_port3()
1379 *******************************************************************************
1380 *
1381 *  DESCRIPTION:
1382 *
1383 *      The handler routine for Tx over HCF_PORT_3.
1384 *
1385 *  PARAMETERS:
1386 *
1387 *      skb - a pointer to the sk_buff to transmit.
1388 *      dev - a pointer to a net_device structure representing HCF_PORT_3.
1389 *
1390 *  RETURNS:
1391 *
1392 *      N/A
1393 *
1394 ******************************************************************************/
1395int wl_tx_port3( struct sk_buff *skb, struct net_device *dev )
1396{
1397    DBG_TX( DbgInfo, "Tx on Port 3\n" );
1398    return wl_tx( skb, dev, HCF_PORT_3 );
1399} // wl_tx_port3
1400/*============================================================================*/
1401
1402/*******************************************************************************
1403 *      wl_tx_port4()
1404 *******************************************************************************
1405 *
1406 *  DESCRIPTION:
1407 *
1408 *      The handler routine for Tx over HCF_PORT_4.
1409 *
1410 *  PARAMETERS:
1411 *
1412 *      skb - a pointer to the sk_buff to transmit.
1413 *      dev - a pointer to a net_device structure representing HCF_PORT_4.
1414 *
1415 *  RETURNS:
1416 *
1417 *      N/A
1418 *
1419 ******************************************************************************/
1420int wl_tx_port4( struct sk_buff *skb, struct net_device *dev )
1421{
1422    DBG_TX( DbgInfo, "Tx on Port 4\n" );
1423    return wl_tx( skb, dev, HCF_PORT_4 );
1424} // wl_tx_port4
1425/*============================================================================*/
1426
1427/*******************************************************************************
1428 *      wl_tx_port5()
1429 *******************************************************************************
1430 *
1431 *  DESCRIPTION:
1432 *
1433 *      The handler routine for Tx over HCF_PORT_5.
1434 *
1435 *  PARAMETERS:
1436 *
1437 *      skb - a pointer to the sk_buff to transmit.
1438 *      dev - a pointer to a net_device structure representing HCF_PORT_5.
1439 *
1440 *  RETURNS:
1441 *
1442 *      N/A
1443 *
1444 ******************************************************************************/
1445int wl_tx_port5( struct sk_buff *skb, struct net_device *dev )
1446{
1447    DBG_TX( DbgInfo, "Tx on Port 5\n" );
1448    return wl_tx( skb, dev, HCF_PORT_5 );
1449} // wl_tx_port5
1450/*============================================================================*/
1451
1452/*******************************************************************************
1453 *      wl_tx_port6()
1454 *******************************************************************************
1455 *
1456 *  DESCRIPTION:
1457 *
1458 *      The handler routine for Tx over HCF_PORT_6.
1459 *
1460 *  PARAMETERS:
1461 *
1462 *      skb - a pointer to the sk_buff to transmit.
1463 *      dev - a pointer to a net_device structure representing HCF_PORT_6.
1464 *
1465 *  RETURNS:
1466 *
1467 *      N/A
1468 *
1469 ******************************************************************************/
1470int wl_tx_port6( struct sk_buff *skb, struct net_device *dev )
1471{
1472    DBG_TX( DbgInfo, "Tx on Port 6\n" );
1473    return wl_tx( skb, dev, HCF_PORT_6 );
1474} // wl_tx_port6
1475/*============================================================================*/
1476
1477/*******************************************************************************
1478 *      wl_wds_device_alloc()
1479 *******************************************************************************
1480 *
1481 *  DESCRIPTION:
1482 *
1483 *      Create instances of net_device to represent the WDS ports, and register
1484 *  the device's entry points in the net_device structure.
1485 *
1486 *  PARAMETERS:
1487 *
1488 *      lp  - a pointer to the device's private adapter structure
1489 *
1490 *  RETURNS:
1491 *
1492 *      N/A, but will place pointers to the allocated and initialized net_device
1493 *      structs in the private adapter structure.
1494 *
1495 ******************************************************************************/
1496void wl_wds_device_alloc( struct wl_private *lp )
1497{
1498    int count;
1499    /*------------------------------------------------------------------------*/
1500
1501    DBG_FUNC( "wl_wds_device_alloc" );
1502    DBG_ENTER( DbgInfo );
1503
1504    /* WDS support requires additional net_device structs to be allocated,
1505       so that user space apps can use these virtual devices to specify the
1506       port on which to Tx/Rx */
1507    for( count = 0; count < NUM_WDS_PORTS; count++ ) {
1508        struct net_device *dev_wds = NULL;
1509
1510        dev_wds = kzalloc(sizeof(struct net_device), GFP_KERNEL);
1511        if (!dev_wds) {
1512                DBG_LEAVE(DbgInfo);
1513                return;
1514        }
1515
1516        ether_setup( dev_wds );
1517
1518        lp->wds_port[count].dev = dev_wds;
1519
1520        /* Re-use wl_init for all the devices, as it currently does nothing, but
1521           is required. Re-use the stats/tx_timeout handler for all as well; the
1522           WDS port which is requesting these operations can be determined by
1523           the net_device pointer. Set the private member of all devices to point
1524           to the same net_device struct; that way, all information gets
1525           funnelled through the one "real" net_device. Name the WDS ports
1526           "wds<n>" */
1527        lp->wds_port[count].dev->init           = &wl_init;
1528        lp->wds_port[count].dev->get_stats      = &wl_stats;
1529        lp->wds_port[count].dev->tx_timeout     = &wl_tx_timeout;
1530        lp->wds_port[count].dev->watchdog_timeo = TX_TIMEOUT;
1531        lp->wds_port[count].dev->priv           = lp;
1532
1533        sprintf( lp->wds_port[count].dev->name, "wds%d", count );
1534    }
1535
1536    /* Register the Tx handlers */
1537    lp->wds_port[0].dev->hard_start_xmit = &wl_tx_port1;
1538    lp->wds_port[1].dev->hard_start_xmit = &wl_tx_port2;
1539    lp->wds_port[2].dev->hard_start_xmit = &wl_tx_port3;
1540    lp->wds_port[3].dev->hard_start_xmit = &wl_tx_port4;
1541    lp->wds_port[4].dev->hard_start_xmit = &wl_tx_port5;
1542    lp->wds_port[5].dev->hard_start_xmit = &wl_tx_port6;
1543
1544    WL_WDS_NETIF_STOP_QUEUE( lp );
1545
1546    DBG_LEAVE( DbgInfo );
1547} // wl_wds_device_alloc
1548/*============================================================================*/
1549
1550/*******************************************************************************
1551 *      wl_wds_device_dealloc()
1552 *******************************************************************************
1553 *
1554 *  DESCRIPTION:
1555 *
1556 *      Free instances of net_device structures used to support WDS.
1557 *
1558 *  PARAMETERS:
1559 *
1560 *      lp  - a pointer to the device's private adapter structure
1561 *
1562 *  RETURNS:
1563 *
1564 *      N/A
1565 *
1566 ******************************************************************************/
1567void wl_wds_device_dealloc( struct wl_private *lp )
1568{
1569    int count;
1570    /*------------------------------------------------------------------------*/
1571
1572    DBG_FUNC( "wl_wds_device_dealloc" );
1573    DBG_ENTER( DbgInfo );
1574
1575    for( count = 0; count < NUM_WDS_PORTS; count++ ) {
1576        struct net_device *dev_wds = NULL;
1577
1578        dev_wds = lp->wds_port[count].dev;
1579
1580        if( dev_wds != NULL ) {
1581            if( dev_wds->flags & IFF_UP ) {
1582                dev_close( dev_wds );
1583                dev_wds->flags &= ~( IFF_UP | IFF_RUNNING );
1584            }
1585
1586            free_netdev(dev_wds);
1587            lp->wds_port[count].dev = NULL;
1588        }
1589    }
1590
1591    DBG_LEAVE( DbgInfo );
1592} // wl_wds_device_dealloc
1593/*============================================================================*/
1594
1595/*******************************************************************************
1596 *      wl_wds_netif_start_queue()
1597 *******************************************************************************
1598 *
1599 *  DESCRIPTION:
1600 *
1601 *      Used to start the netif queues of all the "virtual" network devices
1602 *      which represent the WDS ports.
1603 *
1604 *  PARAMETERS:
1605 *
1606 *      lp  - a pointer to the device's private adapter structure
1607 *
1608 *  RETURNS:
1609 *
1610 *      N/A
1611 *
1612 ******************************************************************************/
1613void wl_wds_netif_start_queue( struct wl_private *lp )
1614{
1615    int count;
1616    /*------------------------------------------------------------------------*/
1617
1618    if( lp != NULL ) {
1619        for( count = 0; count < NUM_WDS_PORTS; count++ ) {
1620            if( lp->wds_port[count].is_registered &&
1621                lp->wds_port[count].netif_queue_on == FALSE ) {
1622                netif_start_queue( lp->wds_port[count].dev );
1623                lp->wds_port[count].netif_queue_on = TRUE;
1624            }
1625        }
1626    }
1627} // wl_wds_netif_start_queue
1628/*============================================================================*/
1629
1630/*******************************************************************************
1631 *      wl_wds_netif_stop_queue()
1632 *******************************************************************************
1633 *
1634 *  DESCRIPTION:
1635 *
1636 *      Used to stop the netif queues of all the "virtual" network devices
1637 *      which represent the WDS ports.
1638 *
1639 *  PARAMETERS:
1640 *
1641 *      lp  - a pointer to the device's private adapter structure
1642 *
1643 *  RETURNS:
1644 *
1645 *      N/A
1646 *
1647 ******************************************************************************/
1648void wl_wds_netif_stop_queue( struct wl_private *lp )
1649{
1650    int count;
1651    /*------------------------------------------------------------------------*/
1652
1653    if( lp != NULL ) {
1654        for( count = 0; count < NUM_WDS_PORTS; count++ ) {
1655            if( lp->wds_port[count].is_registered &&
1656                lp->wds_port[count].netif_queue_on == TRUE ) {
1657                netif_stop_queue( lp->wds_port[count].dev );
1658                lp->wds_port[count].netif_queue_on = FALSE;
1659            }
1660        }
1661    }
1662} // wl_wds_netif_stop_queue
1663/*============================================================================*/
1664
1665/*******************************************************************************
1666 *      wl_wds_netif_wake_queue()
1667 *******************************************************************************
1668 *
1669 *  DESCRIPTION:
1670 *
1671 *      Used to wake the netif queues of all the "virtual" network devices
1672 *      which represent the WDS ports.
1673 *
1674 *  PARAMETERS:
1675 *
1676 *      lp  - a pointer to the device's private adapter structure
1677 *
1678 *  RETURNS:
1679 *
1680 *      N/A
1681 *
1682 ******************************************************************************/
1683void wl_wds_netif_wake_queue( struct wl_private *lp )
1684{
1685    int count;
1686    /*------------------------------------------------------------------------*/
1687
1688    if( lp != NULL ) {
1689        for( count = 0; count < NUM_WDS_PORTS; count++ ) {
1690            if( lp->wds_port[count].is_registered &&
1691                lp->wds_port[count].netif_queue_on == FALSE ) {
1692                netif_wake_queue( lp->wds_port[count].dev );
1693                lp->wds_port[count].netif_queue_on = TRUE;
1694            }
1695        }
1696    }
1697} // wl_wds_netif_wake_queue
1698/*============================================================================*/
1699
1700/*******************************************************************************
1701 *      wl_wds_netif_carrier_on()
1702 *******************************************************************************
1703 *
1704 *  DESCRIPTION:
1705 *
1706 *      Used to signal the network layer that carrier is present on all of the
1707 *      "virtual" network devices which represent the WDS ports.
1708 *
1709 *  PARAMETERS:
1710 *
1711 *      lp  - a pointer to the device's private adapter structure
1712 *
1713 *  RETURNS:
1714 *
1715 *      N/A
1716 *
1717 ******************************************************************************/
1718void wl_wds_netif_carrier_on( struct wl_private *lp )
1719{
1720    int count;
1721    /*------------------------------------------------------------------------*/
1722
1723    if( lp != NULL ) {
1724        for( count = 0; count < NUM_WDS_PORTS; count++ ) {
1725            if( lp->wds_port[count].is_registered ) {
1726                netif_carrier_on( lp->wds_port[count].dev );
1727            }
1728        }
1729    }
1730} // wl_wds_netif_carrier_on
1731/*============================================================================*/
1732
1733/*******************************************************************************
1734 *      wl_wds_netif_carrier_off()
1735 *******************************************************************************
1736 *
1737 *  DESCRIPTION:
1738 *
1739 *      Used to signal the network layer that carrier is NOT present on all of
1740 *      the "virtual" network devices which represent the WDS ports.
1741 *
1742 *  PARAMETERS:
1743 *
1744 *      lp  - a pointer to the device's private adapter structure
1745 *
1746 *  RETURNS:
1747 *
1748 *      N/A
1749 *
1750 ******************************************************************************/
1751void wl_wds_netif_carrier_off( struct wl_private *lp )
1752{
1753        int count;
1754
1755        if(lp != NULL) {
1756                for(count = 0; count < NUM_WDS_PORTS; count++) {
1757                        if(lp->wds_port[count].is_registered)
1758                                netif_carrier_off(lp->wds_port[count].dev);
1759                }
1760        }
1761
1762} // wl_wds_netif_carrier_off
1763/*============================================================================*/
1764
1765#endif  /* USE_WDS */
1766
1767#ifdef ENABLE_DMA
1768/*******************************************************************************
1769 *      wl_send_dma()
1770 *******************************************************************************
1771 *
1772 *  DESCRIPTION:
1773 *
1774 *      The routine which performs data transmits when using busmaster DMA.
1775 *
1776 *  PARAMETERS:
1777 *
1778 *      lp   - a pointer to the device's wl_private struct.
1779 *      skb  - a pointer to the network layer's data buffer.
1780 *      port - the Hermes port on which to transmit.
1781 *
1782 *  RETURNS:
1783 *
1784 *      0 on success
1785 *      1 on error
1786 *
1787 ******************************************************************************/
1788int wl_send_dma( struct wl_private *lp, struct sk_buff *skb, int port )
1789{
1790    int         len;
1791    DESC_STRCT *desc = NULL;
1792    DESC_STRCT *desc_next = NULL;
1793    /*------------------------------------------------------------------------*/
1794
1795    DBG_FUNC( "wl_send_dma" );
1796
1797    if( lp == NULL ) {
1798        DBG_ERROR( DbgInfo, "Private adapter struct is NULL\n" );
1799        return FALSE;
1800    }
1801
1802    if( lp->dev == NULL ) {
1803        DBG_ERROR( DbgInfo, "net_device struct in wl_private is NULL\n" );
1804        return FALSE;
1805    }
1806
1807    /* AGAIN, ALL THE QUEUEING DONE HERE IN I/O MODE IS NOT PERFORMED */
1808
1809    if( skb == NULL ) {
1810        DBG_WARNING (DbgInfo, "Nothing to send.\n");
1811        return FALSE;
1812    }
1813
1814    len = skb->len;
1815
1816    /* Get a free descriptor */
1817    desc = wl_pci_dma_get_tx_packet( lp );
1818
1819    if( desc == NULL ) {
1820        if( lp->netif_queue_on == TRUE ) {
1821            netif_stop_queue( lp->dev );
1822            WL_WDS_NETIF_STOP_QUEUE( lp );
1823            lp->netif_queue_on = FALSE;
1824
1825            dev_kfree_skb( skb );
1826            return 0;
1827        }
1828    }
1829
1830    SET_BUF_CNT( desc, /*HCF_DMA_FD_CNT*/HFS_ADDR_DEST );
1831    SET_BUF_SIZE( desc, HCF_DMA_TX_BUF1_SIZE );
1832
1833    desc_next = desc->next_desc_addr;
1834
1835    if( desc_next->buf_addr == NULL ) {
1836        DBG_ERROR( DbgInfo, "DMA descriptor buf_addr is NULL\n" );
1837        return FALSE;
1838    }
1839
1840    /* Copy the payload into the DMA packet */
1841    memcpy( desc_next->buf_addr, skb->data, len );
1842
1843    SET_BUF_CNT( desc_next, len );
1844    SET_BUF_SIZE( desc_next, HCF_MAX_PACKET_SIZE );
1845
1846    hcf_dma_tx_put( &( lp->hcfCtx ), desc, 0 );
1847
1848    /* Free the skb and perform queue cleanup, as the buffer was
1849            transmitted successfully */
1850    dev_kfree_skb( skb );
1851
1852    return TRUE;
1853} // wl_send_dma
1854/*============================================================================*/
1855
1856/*******************************************************************************
1857 *      wl_rx_dma()
1858 *******************************************************************************
1859 *
1860 *  DESCRIPTION:
1861 *
1862 *      The routine which performs data reception when using busmaster DMA.
1863 *
1864 *  PARAMETERS:
1865 *
1866 *      dev - a pointer to the device's net_device structure.
1867 *
1868 *  RETURNS:
1869 *
1870 *      0 on success
1871 *      1 on error
1872 *
1873 ******************************************************************************/
1874int wl_rx_dma( struct net_device *dev )
1875{
1876    int                      port;
1877    hcf_16                   pktlen;
1878    hcf_16                   hfs_stat;
1879    struct sk_buff          *skb;
1880    struct wl_private       *lp = NULL;
1881    DESC_STRCT              *desc, *desc_next;
1882    //CFG_MB_INFO_RANGE2_STRCT x;
1883    /*------------------------------------------------------------------------*/
1884
1885    DBG_FUNC("wl_rx")
1886    DBG_PARAM(DbgInfo, "dev", "%s (0x%p)", dev->name, dev);
1887
1888    if((( lp = dev->priv ) != NULL ) &&
1889        !( lp->flags & WVLAN2_UIL_BUSY )) {
1890
1891#ifdef USE_RTS
1892        if( lp->useRTS == 1 ) {
1893            DBG_PRINT( "RTS: We're getting an Rx...\n" );
1894            return -EIO;
1895        }
1896#endif  /* USE_RTS */
1897
1898        //if( lp->dma.status == 0 )
1899        //{
1900            desc = hcf_dma_rx_get( &( lp->hcfCtx ));
1901
1902            if( desc != NULL )
1903            {
1904                /* Check and see if we rcvd. a WMP frame */
1905                /*
1906                if((( *(hcf_8 *)&desc->buf_addr[HFS_STAT] ) &
1907                    ( HFS_STAT_MSG_TYPE | HFS_STAT_ERR )) == HFS_STAT_WMP_MSG )
1908                {
1909                    DBG_TRACE( DbgInfo, "Got a WMP frame\n" );
1910
1911                    x.len = sizeof( CFG_MB_INFO_RANGE2_STRCT ) / sizeof( hcf_16 );
1912                                    x.typ = CFG_MB_INFO;
1913                                    x.base_typ = CFG_WMP;
1914                                    x.frag_cnt = 2;
1915                                    x.frag_buf[0].frag_len  = GET_BUF_CNT( descp ) / sizeof( hcf_16 );
1916                                    x.frag_buf[0].frag_addr = (hcf_8 *) descp->buf_addr ;
1917                                    x.frag_buf[1].frag_len  = ( GET_BUF_CNT( descp->next_desc_addr ) + 1 ) / sizeof( hcf_16 );
1918                                    x.frag_buf[1].frag_addr = (hcf_8 *) descp->next_desc_addr->buf_addr ;
1919
1920                    hcf_put_info( &( lp->hcfCtx ), (LTVP)&x );
1921                }
1922                */
1923
1924                desc_next = desc->next_desc_addr;
1925
1926                /* Make sure the buffer isn't empty */
1927                if( GET_BUF_CNT( desc ) == 0 ) {
1928                    DBG_WARNING( DbgInfo, "Buffer is empty!\n" );
1929
1930                    /* Give the descriptor back to the HCF */
1931                    hcf_dma_rx_put( &( lp->hcfCtx ), desc );
1932                    return -EIO;
1933                }
1934
1935                /* Read the HFS_STAT register from the lookahead buffer */
1936                hfs_stat = (hcf_16)( desc->buf_addr[HFS_STAT/2] );
1937
1938                /* Make sure the frame isn't bad */
1939                if(( hfs_stat & HFS_STAT_ERR ) != HCF_SUCCESS )
1940                {
1941                    DBG_WARNING( DbgInfo, "HFS_STAT_ERROR (0x%x) in Rx Packet\n",
1942                                desc->buf_addr[HFS_STAT/2] );
1943
1944                    /* Give the descriptor back to the HCF */
1945                    hcf_dma_rx_put( &( lp->hcfCtx ), desc );
1946                    return -EIO;
1947                }
1948
1949                /* Determine what port this packet is for */
1950                port = ( hfs_stat >> 8 ) & 0x0007;
1951                DBG_RX( DbgInfo, "Rx frame for port %d\n", port );
1952
1953                pktlen = GET_BUF_CNT(desc_next);
1954                if (pktlen != 0) {
1955                    skb = ALLOC_SKB(pktlen);
1956                    if (skb != NULL) {
1957                        switch( port ) {
1958#ifdef USE_WDS
1959                        case 1:
1960                        case 2:
1961                        case 3:
1962                        case 4:
1963                        case 5:
1964                        case 6:
1965                            skb->dev = lp->wds_port[port-1].dev;
1966                            break;
1967#endif  /* USE_WDS */
1968
1969                        case 0:
1970                        default:
1971                            skb->dev = dev;
1972                            break;
1973                        }
1974
1975                        GET_PACKET_DMA( skb->dev, skb, pktlen );
1976
1977                        /* Give the descriptor back to the HCF */
1978                        hcf_dma_rx_put( &( lp->hcfCtx ), desc );
1979
1980                        netif_rx( skb );
1981
1982                        if( port == 0 ) {
1983                            lp->stats.rx_packets++;
1984                            lp->stats.rx_bytes += pktlen;
1985                        }
1986#ifdef USE_WDS
1987                        else
1988                        {
1989                            lp->wds_port[port-1].stats.rx_packets++;
1990                            lp->wds_port[port-1].stats.rx_bytes += pktlen;
1991                        }
1992#endif  /* USE_WDS */
1993
1994                        dev->last_rx = jiffies;
1995
1996                    } else {
1997                        DBG_ERROR( DbgInfo, "Could not alloc skb\n" );
1998
1999                        if( port == 0 )
2000                            {
2001                                lp->stats.rx_dropped++;
2002                            }
2003#ifdef USE_WDS
2004                        else
2005                        {
2006                            lp->wds_port[port-1].stats.rx_dropped++;
2007                        }
2008#endif  /* USE_WDS */
2009                    }
2010                }
2011            }
2012        //}
2013    }
2014
2015    return 0;
2016} // wl_rx_dma
2017/*============================================================================*/
2018#endif  // ENABLE_DMA
2019