linux/drivers/staging/wlags49_h2/wl_pci.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 processing and initialization specific to PCI/miniPCI
  15 *   devices.
  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 <wireless/wl_version.h>
  66
  67#include <linux/module.h>
  68#include <linux/kernel.h>
  69#include <linux/errno.h>
  70#include <linux/pci.h>
  71#include <linux/init.h>
  72#include <linux/sched.h>
  73#include <linux/ptrace.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 <asm/io.h>
  81#include <asm/irq.h>
  82#include <asm/bitops.h>
  83#include <asm/uaccess.h>
  84
  85#include <linux/ethtool.h>
  86#include <linux/netdevice.h>
  87#include <linux/etherdevice.h>
  88#include <linux/skbuff.h>
  89#include <linux/if_arp.h>
  90#include <linux/ioport.h>
  91
  92#include <hcf/debug.h>
  93
  94#include <hcf.h>
  95#include <dhf.h>
  96#include <hcfdef.h>
  97
  98#include <wireless/wl_if.h>
  99#include <wireless/wl_internal.h>
 100#include <wireless/wl_util.h>
 101#include <wireless/wl_main.h>
 102#include <wireless/wl_netdev.h>
 103#include <wireless/wl_pci.h>
 104
 105
 106/*******************************************************************************
 107 * global variables
 108 ******************************************************************************/
 109#if DBG
 110extern dbg_info_t *DbgInfo;
 111#endif  // DBG
 112
 113/* define the PCI device Table Cardname and id tables */
 114static struct pci_device_id wl_pci_tbl[] = {
 115        { PCI_DEVICE(PCI_VENDOR_ID_WL_LKM, PCI_DEVICE_ID_WL_LKM_0), },
 116        { PCI_DEVICE(PCI_VENDOR_ID_WL_LKM, PCI_DEVICE_ID_WL_LKM_1), },
 117        { PCI_DEVICE(PCI_VENDOR_ID_WL_LKM, PCI_DEVICE_ID_WL_LKM_2), },
 118
 119        { }                     /* Terminating entry */
 120};
 121
 122MODULE_DEVICE_TABLE(pci, wl_pci_tbl);
 123
 124/*******************************************************************************
 125 * function prototypes
 126 ******************************************************************************/
 127int wl_pci_probe( struct pci_dev *pdev,
 128                                const struct pci_device_id *ent );
 129void wl_pci_remove(struct pci_dev *pdev);
 130int wl_pci_setup( struct pci_dev *pdev );
 131void wl_pci_enable_cardbus_interrupts( struct pci_dev *pdev );
 132
 133#ifdef ENABLE_DMA
 134int wl_pci_dma_alloc( struct pci_dev *pdev, struct wl_private *lp );
 135int wl_pci_dma_free( struct pci_dev *pdev, struct wl_private *lp );
 136int wl_pci_dma_alloc_tx_packet( struct pci_dev *pdev, struct wl_private *lp,
 137                                DESC_STRCT **desc );
 138int wl_pci_dma_free_tx_packet( struct pci_dev *pdev, struct wl_private *lp,
 139                                DESC_STRCT **desc );
 140int wl_pci_dma_alloc_rx_packet( struct pci_dev *pdev, struct wl_private *lp,
 141                                DESC_STRCT **desc );
 142int wl_pci_dma_free_rx_packet( struct pci_dev *pdev, struct wl_private *lp,
 143                                DESC_STRCT **desc );
 144int wl_pci_dma_alloc_desc_and_buf( struct pci_dev *pdev, struct wl_private *lp,
 145                                   DESC_STRCT **desc, int size );
 146int wl_pci_dma_free_desc_and_buf( struct pci_dev *pdev, struct wl_private *lp,
 147                                   DESC_STRCT **desc );
 148int wl_pci_dma_alloc_desc( struct pci_dev *pdev, struct wl_private *lp,
 149                           DESC_STRCT **desc );
 150int wl_pci_dma_free_desc( struct pci_dev *pdev, struct wl_private *lp,
 151                           DESC_STRCT **desc );
 152int wl_pci_dma_alloc_buf( struct pci_dev *pdev, struct wl_private *lp,
 153                          DESC_STRCT *desc, int size );
 154int wl_pci_dma_free_buf( struct pci_dev *pdev, struct wl_private *lp,
 155                          DESC_STRCT *desc );
 156
 157void wl_pci_dma_hcf_reclaim_rx( struct wl_private *lp );
 158#endif  // ENABLE_DMA
 159
 160/*******************************************************************************
 161 * PCI module function registration
 162 ******************************************************************************/
 163static struct pci_driver wl_driver = {
 164        .name     = MODULE_NAME,
 165        .id_table = wl_pci_tbl,
 166        .probe    = wl_pci_probe,
 167        .remove   = wl_pci_remove,
 168        .suspend  = NULL,
 169        .resume   = NULL
 170};
 171
 172/*******************************************************************************
 173 *      wl_adapter_init_module()
 174 *******************************************************************************
 175 *
 176 *  DESCRIPTION:
 177 *
 178 *      Called by init_module() to perform PCI-specific driver initialization.
 179 *
 180 *  PARAMETERS:
 181 *
 182 *      N/A
 183 *
 184 *  RETURNS:
 185 *
 186 *      0
 187 *
 188 ******************************************************************************/
 189int wl_adapter_init_module( void )
 190{
 191    int result;
 192    /*------------------------------------------------------------------------*/
 193
 194    DBG_FUNC( "wl_adapter_init_module()" );
 195    DBG_ENTER( DbgInfo );
 196    DBG_TRACE( DbgInfo, "wl_adapter_init_module() -- PCI\n" );
 197
 198    result = pci_register_driver( &wl_driver ); //;?replace with pci_module_init, Rubini pg 490
 199        //;? why not do something with the result
 200
 201    DBG_LEAVE( DbgInfo );
 202    return 0;
 203} // wl_adapter_init_module
 204/*============================================================================*/
 205
 206/*******************************************************************************
 207 *      wl_adapter_cleanup_module()
 208 *******************************************************************************
 209 *
 210 *  DESCRIPTION:
 211 *
 212 *      Called by cleanup_module() to perform PCI-specific driver cleanup.
 213 *
 214 *  PARAMETERS:
 215 *
 216 *      N/A
 217 *
 218 *  RETURNS:
 219 *
 220 *      N/A
 221 *
 222 ******************************************************************************/
 223void wl_adapter_cleanup_module( void )
 224{
 225        //;?how come wl_adapter_cleanup_module is located in a seemingly pci specific module
 226    DBG_FUNC( "wl_adapter_cleanup_module" );
 227    DBG_ENTER( DbgInfo );
 228
 229        //;?DBG_TRACE below feels like nearly redundant in the light of DBG_ENTER above
 230    DBG_TRACE( DbgInfo, "wl_adapter_cleanup_module() -- PCI\n" );
 231
 232    pci_unregister_driver( &wl_driver );
 233
 234    DBG_LEAVE( DbgInfo );
 235    return;
 236} // wl_adapter_cleanup_module
 237/*============================================================================*/
 238
 239/*******************************************************************************
 240 *      wl_adapter_insert()
 241 *******************************************************************************
 242 *
 243 *  DESCRIPTION:
 244 *
 245 *      Called by wl_pci_probe() to continue the process of device insertion.
 246 *
 247 *  PARAMETERS:
 248 *
 249 *      dev - a pointer to the device's net_device structure
 250 *
 251 *  RETURNS:
 252 *
 253 *      TRUE or FALSE
 254 *
 255 ******************************************************************************/
 256int wl_adapter_insert( struct net_device *dev )
 257{
 258    int result = FALSE;
 259    /*------------------------------------------------------------------------*/
 260
 261    DBG_FUNC( "wl_adapter_insert" );
 262    DBG_ENTER( DbgInfo );
 263
 264    DBG_TRACE( DbgInfo, "wl_adapter_insert() -- PCI\n" );
 265
 266    if( dev == NULL ) {
 267        DBG_ERROR( DbgInfo, "net_device pointer is NULL!!!\n" );
 268    } else if( dev->priv == NULL ) {
 269        DBG_ERROR( DbgInfo, "wl_private pointer is NULL!!!\n" );
 270    } else if( wl_insert( dev ) ) { /* Perform remaining device initialization */
 271                result = TRUE;
 272        } else {
 273        DBG_TRACE( DbgInfo, "wl_insert() FAILED\n" );
 274    }
 275    DBG_LEAVE( DbgInfo );
 276    return result;
 277} // wl_adapter_insert
 278/*============================================================================*/
 279
 280/*******************************************************************************
 281 *      wl_adapter_open()
 282 *******************************************************************************
 283 *
 284 *  DESCRIPTION:
 285 *
 286 *      Open the device.
 287 *
 288 *  PARAMETERS:
 289 *
 290 *      dev - a pointer to the device's net_device structure
 291 *
 292 *  RETURNS:
 293 *
 294 *      an HCF status code
 295 *
 296 ******************************************************************************/
 297int wl_adapter_open( struct net_device *dev )
 298{
 299    int         result = 0;
 300    int         hcf_status = HCF_SUCCESS;
 301    /*------------------------------------------------------------------------*/
 302
 303    DBG_FUNC( "wl_adapter_open" );
 304    DBG_ENTER( DbgInfo );
 305
 306    DBG_TRACE( DbgInfo, "wl_adapter_open() -- PCI\n" );
 307
 308    hcf_status = wl_open( dev );
 309
 310    if( hcf_status != HCF_SUCCESS ) {
 311        result = -ENODEV;
 312    }
 313
 314    DBG_LEAVE( DbgInfo );
 315    return result;
 316} // wl_adapter_open
 317/*============================================================================*/
 318
 319/*******************************************************************************
 320 *      wl_adapter_close()
 321 *******************************************************************************
 322 *
 323 *  DESCRIPTION:
 324 *
 325 *      Close the device
 326 *
 327 *  PARAMETERS:
 328 *
 329 *      dev - a pointer to the device's net_device structure
 330 *
 331 *  RETURNS:
 332 *
 333 *      0
 334 *
 335 ******************************************************************************/
 336int wl_adapter_close( struct net_device *dev )
 337{
 338    DBG_FUNC( "wl_adapter_close" );
 339    DBG_ENTER( DbgInfo );
 340
 341    DBG_TRACE( DbgInfo, "wl_adapter_close() -- PCI\n" );
 342    DBG_TRACE( DbgInfo, "%s: Shutting down adapter.\n", dev->name );
 343
 344    wl_close( dev );
 345
 346    DBG_LEAVE( DbgInfo );
 347    return 0;
 348} // wl_adapter_close
 349/*============================================================================*/
 350
 351/*******************************************************************************
 352 *      wl_adapter_is_open()
 353 *******************************************************************************
 354 *
 355 *  DESCRIPTION:
 356 *
 357 *      Check whether this device is open. Returns
 358 *
 359 *  PARAMETERS:
 360 *
 361 *      dev - a pointer to the device's net_device structure
 362 *
 363 *  RETURNS:
 364 *
 365 *      nonzero if device is open.
 366 *
 367 ******************************************************************************/
 368int wl_adapter_is_open( struct net_device *dev )
 369{
 370    /* This function is used in PCMCIA to check the status of the 'open' field
 371       in the dev_link_t structure associated with a network device. There
 372       doesn't seem to be an analog to this for PCI, and checking the status
 373       contained in the net_device structure doesn't have the same effect.
 374       For now, return TRUE, but find out if this is necessary for PCI. */
 375
 376    return TRUE;
 377} // wl_adapter_is_open
 378/*============================================================================*/
 379
 380/*******************************************************************************
 381 *      wl_pci_probe()
 382 *******************************************************************************
 383 *
 384 *  DESCRIPTION:
 385 *
 386 *      Registered in the pci_driver structure, this function is called when the
 387 *  PCI subsystem finds a new PCI device which matches the information contained
 388 *  in the pci_device_id table.
 389 *
 390 *  PARAMETERS:
 391 *
 392 *      pdev    - a pointer to the device's pci_dev structure
 393 *      ent     - this device's entry in the pci_device_id table
 394 *
 395 *  RETURNS:
 396 *
 397 *      0 on success
 398 *      errno value otherwise
 399 *
 400 ******************************************************************************/
 401int wl_pci_probe( struct pci_dev *pdev,
 402                                const struct pci_device_id *ent )
 403{
 404    int result;
 405    /*------------------------------------------------------------------------*/
 406
 407    DBG_FUNC( "wl_pci_probe" );
 408    DBG_ENTER( DbgInfo );
 409        DBG_PRINT( "%s\n", VERSION_INFO );
 410
 411    result = wl_pci_setup( pdev );
 412
 413    DBG_LEAVE( DbgInfo );
 414
 415    return result;
 416} // wl_pci_probe
 417/*============================================================================*/
 418
 419/*******************************************************************************
 420 *      wl_pci_remove()
 421 *******************************************************************************
 422 *
 423 *  DESCRIPTION:
 424 *
 425 *      Registered in the pci_driver structure, this function is called when the
 426 *  PCI subsystem detects that a PCI device which matches the information
 427 *  contained in the pci_device_id table has been removed.
 428 *
 429 *  PARAMETERS:
 430 *
 431 *      pdev - a pointer to the device's pci_dev structure
 432 *
 433 *  RETURNS:
 434 *
 435 *      N/A
 436 *
 437 ******************************************************************************/
 438void wl_pci_remove(struct pci_dev *pdev)
 439{
 440    struct net_device       *dev = NULL;
 441    /*------------------------------------------------------------------------*/
 442
 443    DBG_FUNC( "wl_pci_remove" );
 444    DBG_ENTER( DbgInfo );
 445
 446    /* Make sure the pci_dev pointer passed in is valid */
 447    if( pdev == NULL ) {
 448        DBG_ERROR( DbgInfo, "PCI subsys passed in an invalid pci_dev pointer\n" );
 449        return;
 450    }
 451
 452    dev = pci_get_drvdata( pdev );
 453    if( dev == NULL ) {
 454        DBG_ERROR( DbgInfo, "Could not retrieve net_device structure\n" );
 455        return;
 456    }
 457
 458    /* Perform device cleanup */
 459    wl_remove( dev );
 460    free_irq( dev->irq, dev );
 461
 462#ifdef ENABLE_DMA
 463    wl_pci_dma_free( pdev, dev->priv );
 464#endif
 465
 466    wl_device_dealloc( dev );
 467
 468    DBG_LEAVE( DbgInfo );
 469    return;
 470} // wl_pci_remove
 471/*============================================================================*/
 472
 473/*******************************************************************************
 474 *      wl_pci_setup()
 475 *******************************************************************************
 476 *
 477 *  DESCRIPTION:
 478 *
 479 *      Called by wl_pci_probe() to begin a device's initialization process.
 480 *
 481 *  PARAMETERS:
 482 *
 483 *      pdev - a pointer to the device's pci_dev structure
 484 *
 485 *  RETURNS:
 486 *
 487 *      0 on success
 488 *      errno value otherwise
 489 *
 490 ******************************************************************************/
 491int wl_pci_setup( struct pci_dev *pdev )
 492{
 493    int                 result = 0;
 494    struct net_device   *dev = NULL;
 495    struct wl_private   *lp = NULL;
 496    /*------------------------------------------------------------------------*/
 497
 498    DBG_FUNC( "wl_pci_setup" );
 499    DBG_ENTER( DbgInfo );
 500
 501    /* Make sure the pci_dev pointer passed in is valid */
 502    if( pdev == NULL ) {
 503        DBG_ERROR( DbgInfo, "PCI subsys passed in an invalid pci_dev pointer\n" );
 504        return -ENODEV;
 505    }
 506
 507    result = pci_enable_device( pdev );
 508    if( result != 0 ) {
 509        DBG_ERROR( DbgInfo, "pci_enable_device() failed\n" );
 510        DBG_LEAVE( DbgInfo );
 511        return result;
 512    }
 513
 514    /* We found our device! Let's register it with the system */
 515    DBG_TRACE( DbgInfo, "Found our device, now registering\n" );
 516    dev = wl_device_alloc( );
 517    if( dev == NULL ) {
 518        DBG_ERROR( DbgInfo, "Could not register device!!!\n" );
 519        DBG_LEAVE( DbgInfo );
 520        return -ENOMEM;
 521    }
 522
 523    /* Make sure that space was allocated for our private adapter struct */
 524    if( dev->priv == NULL ) {
 525        DBG_ERROR( DbgInfo, "Private adapter struct was not allocated!!!\n" );
 526        wl_device_dealloc(dev);
 527        DBG_LEAVE( DbgInfo );
 528        return -ENOMEM;
 529    }
 530
 531#ifdef ENABLE_DMA
 532    /* Allocate DMA Descriptors */
 533    if( wl_pci_dma_alloc( pdev, dev->priv ) < 0 ) {
 534        DBG_ERROR( DbgInfo, "Could not allocate DMA descriptor memory!!!\n" );
 535        wl_device_dealloc(dev);
 536        DBG_LEAVE( DbgInfo );
 537        return -ENOMEM;
 538    }
 539#endif
 540
 541    /* Register our private adapter structure with PCI */
 542    pci_set_drvdata( pdev, dev );
 543
 544    /* Fill out bus specific information in the net_device struct */
 545    dev->irq = pdev->irq;
 546    SET_MODULE_OWNER( dev );
 547
 548    DBG_TRACE( DbgInfo, "Device Base Address: %#03lx\n", pdev->resource[0].start );
 549        dev->base_addr = pdev->resource[0].start;
 550
 551    /* Initialize our device here */
 552    if( !wl_adapter_insert( dev )) {
 553        DBG_ERROR( DbgInfo, "wl_adapter_insert() FAILED!!!\n" );
 554        wl_device_dealloc( dev );
 555        DBG_LEAVE( DbgInfo );
 556        return -EINVAL;
 557    }
 558
 559    /* Register our ISR */
 560    DBG_TRACE( DbgInfo, "Registering ISR...\n" );
 561
 562    result = request_irq(dev->irq, wl_isr, SA_SHIRQ, dev->name, dev);
 563    if( result ) {
 564        DBG_WARNING( DbgInfo, "Could not register ISR!!!\n" );
 565        wl_remove(dev);
 566        wl_device_dealloc(dev);
 567        DBG_LEAVE( DbgInfo );
 568        return result;
 569        }
 570
 571    /* Make sure interrupts are enabled properly for CardBus */
 572    lp = dev->priv;
 573
 574    if( lp->hcfCtx.IFB_BusType == CFG_NIC_BUS_TYPE_CARDBUS ||
 575            lp->hcfCtx.IFB_BusType == CFG_NIC_BUS_TYPE_PCI              ) {
 576        DBG_TRACE( DbgInfo, "This is a PCI/CardBus card, enable interrupts\n" );
 577        wl_pci_enable_cardbus_interrupts( pdev );
 578    }
 579
 580    /* Enable bus mastering */
 581    pci_set_master( pdev );
 582
 583    DBG_LEAVE( DbgInfo );
 584    return 0;
 585} // wl_pci_setup
 586/*============================================================================*/
 587
 588/*******************************************************************************
 589 *      wl_pci_enable_cardbus_interrupts()
 590 *******************************************************************************
 591 *
 592 *  DESCRIPTION:
 593 *
 594 *      Called by wl_pci_setup() to enable interrupts on a CardBus device. This
 595 *  is done by writing bit 15 to the function event mask register. This
 596 *  CardBus-specific register is located in BAR2 (counting from BAR0), in memory
 597 *  space at byte offset 1f4 (7f4 for WARP).
 598 *
 599 *  PARAMETERS:
 600 *
 601 *      pdev - a pointer to the device's pci_dev structure
 602 *
 603 *  RETURNS:
 604 *
 605 *      N/A
 606 *
 607 ******************************************************************************/
 608void wl_pci_enable_cardbus_interrupts( struct pci_dev *pdev )
 609{
 610    u32                 bar2_reg;
 611    u32                 mem_addr_bus;
 612    u32                 func_evt_mask_reg;
 613    void                *mem_addr_kern = NULL;
 614    /*------------------------------------------------------------------------*/
 615
 616    DBG_FUNC( "wl_pci_enable_cardbus_interrupts" );
 617    DBG_ENTER( DbgInfo );
 618
 619    /* Initialize to known bad values */
 620    bar2_reg = 0xdeadbeef;
 621    mem_addr_bus = 0xdeadbeef;
 622
 623    /* Read the BAR2 register; this register contains the base address of the
 624       memory region where the function event mask register lives */
 625    pci_read_config_dword( pdev, PCI_BASE_ADDRESS_2, &bar2_reg );
 626    mem_addr_bus = bar2_reg & PCI_BASE_ADDRESS_MEM_MASK;
 627
 628    /* Once the base address is obtained, remap the memory region to kernel
 629       space so we can retrieve the register */
 630    mem_addr_kern = ioremap( mem_addr_bus, 0x200 );
 631
 632#ifdef HERMES25
 633#define REG_OFFSET  0x07F4
 634#else
 635#define REG_OFFSET  0x01F4
 636#endif // HERMES25
 637
 638#define BIT15       0x8000
 639
 640    /* Retrieve the functional event mask register, enable interrupts by
 641       setting Bit 15, and write back the value */
 642    func_evt_mask_reg = *(u32 *)( mem_addr_kern + REG_OFFSET );
 643    func_evt_mask_reg |= BIT15;
 644    *(u32 *)( mem_addr_kern + REG_OFFSET ) = func_evt_mask_reg;
 645
 646    /* Once complete, unmap the region and exit */
 647    iounmap( mem_addr_kern );
 648
 649    DBG_LEAVE( DbgInfo );
 650    return;
 651} // wl_pci_enable_cardbus_interrupts
 652/*============================================================================*/
 653
 654#ifdef ENABLE_DMA
 655/*******************************************************************************
 656 *      wl_pci_dma_alloc()
 657 *******************************************************************************
 658 *
 659 *  DESCRIPTION:
 660 *
 661 *      Allocates all resources needed for PCI/CardBus DMA operation
 662 *
 663 *  PARAMETERS:
 664 *
 665 *      pdev - a pointer to the device's pci_dev structure
 666 *      lp  - the device's private adapter structure
 667 *
 668 *  RETURNS:
 669 *
 670 *      0 on success
 671 *      errno value otherwise
 672 *
 673 ******************************************************************************/
 674int wl_pci_dma_alloc( struct pci_dev *pdev, struct wl_private *lp )
 675{
 676    int i;
 677    int status = 0;
 678    /*------------------------------------------------------------------------*/
 679
 680    DBG_FUNC( "wl_pci_dma_alloc" );
 681    DBG_ENTER( DbgInfo );
 682
 683//     lp->dma.tx_rsc_ind = lp->dma.rx_rsc_ind = 0;
 684//
 685//     /* Alloc for the Tx chain and its reclaim descriptor */
 686//     for( i = 0; i < NUM_TX_DESC; i++ ) {
 687//         status = wl_pci_dma_alloc_tx_packet( pdev, lp, &lp->dma.tx_packet[i] );
 688//         if( status == 0 ) {
 689//             DBG_PRINT( "lp->dma.tx_packet[%d] :                 0x%p\n", i, lp->dma.tx_packet[i] );
 690//             DBG_PRINT( "lp->dma.tx_packet[%d]->next_desc_addr : 0x%p\n", i, lp->dma.tx_packet[i]->next_desc_addr );
 691//             lp->dma.tx_rsc_ind++;
 692//         } else {
 693//             DBG_ERROR( DbgInfo, "Could not alloc DMA Tx Packet\n" );
 694//             break;
 695//         }
 696//     }
 697//     if( status == 0 ) {
 698//         status = wl_pci_dma_alloc_desc( pdev, lp, &lp->dma.tx_reclaim_desc );
 699//         DBG_PRINT( "lp->dma.tx_reclaim_desc: 0x%p\n", lp->dma.tx_reclaim_desc );
 700//     }
 701//     /* Alloc for the Rx chain and its reclaim descriptor */
 702//     if( status == 0 ) {
 703//         for( i = 0; i < NUM_RX_DESC; i++ ) {
 704//             status = wl_pci_dma_alloc_rx_packet( pdev, lp, &lp->dma.rx_packet[i] );
 705//             if( status == 0 ) {
 706//                 DBG_PRINT( "lp->dma.rx_packet[%d]                 : 0x%p\n", i, lp->dma.rx_packet[i] );
 707//                 DBG_PRINT( "lp->dma.rx_packet[%d]->next_desc_addr : 0x%p\n", i, lp->dma.rx_packet[i]->next_desc_addr );
 708//                 lp->dma.rx_rsc_ind++;
 709//             } else {
 710//                 DBG_ERROR( DbgInfo, "Could not alloc DMA Rx Packet\n" );
 711//                 break;
 712//             }
 713//         }
 714//     }
 715//     if( status == 0 ) {
 716//         status = wl_pci_dma_alloc_desc( pdev, lp, &lp->dma.rx_reclaim_desc );
 717//         DBG_PRINT( "lp->dma.rx_reclaim_desc: 0x%p\n", lp->dma.rx_reclaim_desc );
 718//     }
 719//     /* Store status, as host should not call HCF functions if this fails */
 720//     lp->dma.status = status;  //;?all useages of dma.status have been commented out
 721//     DBG_LEAVE( DbgInfo );
 722    return status;
 723} // wl_pci_dma_alloc
 724/*============================================================================*/
 725
 726/*******************************************************************************
 727 *      wl_pci_dma_free()
 728 *******************************************************************************
 729 *
 730 *  DESCRIPTION:
 731 *
 732 *      Deallocated all resources needed for PCI/CardBus DMA operation
 733 *
 734 *  PARAMETERS:
 735 *
 736 *      pdev - a pointer to the device's pci_dev structure
 737 *      lp  - the device's private adapter structure
 738 *
 739 *  RETURNS:
 740 *
 741 *      0 on success
 742 *      errno value otherwise
 743 *
 744 ******************************************************************************/
 745int wl_pci_dma_free( struct pci_dev *pdev, struct wl_private *lp )
 746{
 747    int i;
 748    int status = 0;
 749    /*------------------------------------------------------------------------*/
 750
 751    DBG_FUNC( "wl_pci_dma_free" );
 752    DBG_ENTER( DbgInfo );
 753
 754    /* Reclaim all Rx packets that were handed over to the HCF */
 755    /* Do I need to do this? Before this free is called, I've already disabled
 756       the port which will call wl_pci_dma_hcf_reclaim */
 757    //if( lp->dma.status == 0 )
 758    //{
 759    //    wl_pci_dma_hcf_reclaim( lp );
 760    //}
 761
 762    /* Free everything needed for DMA Rx */
 763    for( i = 0; i < NUM_RX_DESC; i++ ) {
 764        if( lp->dma.rx_packet[i] ) {
 765            status = wl_pci_dma_free_rx_packet( pdev, lp, &lp->dma.rx_packet[i] );
 766            if( status != 0 ) {
 767                DBG_WARNING( DbgInfo, "Problem freeing Rx packet\n" );
 768            }
 769        }
 770    }
 771    lp->dma.rx_rsc_ind = 0;
 772
 773    if( lp->dma.rx_reclaim_desc ) {
 774        status = wl_pci_dma_free_desc( pdev, lp, &lp->dma.rx_reclaim_desc );
 775        if( status != 0 ) {
 776            DBG_WARNING( DbgInfo, "Problem freeing Rx reclaim descriptor\n" );
 777        }
 778    }
 779
 780    /* Free everything needed for DMA Tx */
 781    for( i = 0; i < NUM_TX_DESC; i++ ) {
 782        if( lp->dma.tx_packet[i] ) {
 783            status = wl_pci_dma_free_tx_packet( pdev, lp, &lp->dma.tx_packet[i] );
 784            if( status != 0 ) {
 785                DBG_WARNING( DbgInfo, "Problem freeing Tx packet\n" );
 786            }
 787        }
 788    }
 789    lp->dma.tx_rsc_ind = 0;
 790
 791    if( lp->dma.tx_reclaim_desc ) {
 792        status = wl_pci_dma_free_desc( pdev, lp, &lp->dma.tx_reclaim_desc );
 793        if( status != 0 ) {
 794            DBG_WARNING( DbgInfo, "Problem freeing Tx reclaim descriptor\n" );
 795        }
 796    }
 797
 798    DBG_LEAVE( DbgInfo );
 799    return status;
 800} // wl_pci_dma_free
 801
 802/*============================================================================*/
 803
 804/*******************************************************************************
 805 *      wl_pci_dma_alloc_tx_packet()
 806 *******************************************************************************
 807 *
 808 *  DESCRIPTION:
 809 *
 810 *      Allocates a single Tx packet, consisting of several descriptors and
 811 *      buffers. Data to transmit is first copied into the 'payload' buffer
 812 *      before being transmitted.
 813 *
 814 *  PARAMETERS:
 815 *
 816 *      pdev    - a pointer to the device's pci_dev structure
 817 *      lp      - the device's private adapter structure
 818 *      desc    - a pointer which will reference the descriptor to be alloc'd.
 819 *
 820 *  RETURNS:
 821 *
 822 *      0 on success
 823 *      errno value otherwise
 824 *
 825 ******************************************************************************/
 826int wl_pci_dma_alloc_tx_packet( struct pci_dev *pdev, struct wl_private *lp,
 827                                DESC_STRCT **desc )
 828{
 829//     int status = 0;
 830//     /*------------------------------------------------------------------------*/
 831//
 832//     if( desc == NULL ) {
 833//         status = -EFAULT;
 834//     }
 835//     if( status == 0 ) {
 836//         status = wl_pci_dma_alloc_desc_and_buf( pdev, lp, desc,
 837//                                                 HCF_DMA_TX_BUF1_SIZE );
 838//
 839//         if( status == 0 ) {
 840//             status = wl_pci_dma_alloc_desc_and_buf( pdev, lp,
 841//                                                     &( (*desc)->next_desc_addr ),
 842//                                                     HCF_MAX_PACKET_SIZE );
 843//         }
 844//     }
 845//     if( status == 0 ) {
 846//         (*desc)->next_desc_phys_addr = (*desc)->next_desc_addr->desc_phys_addr;
 847//     }
 848//     return status;
 849} // wl_pci_dma_alloc_tx_packet
 850/*============================================================================*/
 851
 852/*******************************************************************************
 853 *      wl_pci_dma_free_tx_packet()
 854 *******************************************************************************
 855 *
 856 *  DESCRIPTION:
 857 *
 858 *      Frees a single Tx packet, described in the corresponding alloc function.
 859 *
 860 *  PARAMETERS:
 861 *
 862 *      pdev    - a pointer to the device's pci_dev structure
 863 *      lp      - the device's private adapter structure
 864 *      desc    - a pointer which will reference the descriptor to be alloc'd.
 865 *
 866 *  RETURNS:
 867 *
 868 *      0 on success
 869 *      errno value otherwise
 870 *
 871 ******************************************************************************/
 872int wl_pci_dma_free_tx_packet( struct pci_dev *pdev, struct wl_private *lp,
 873                                DESC_STRCT **desc )
 874{
 875    int status = 0;
 876    /*------------------------------------------------------------------------*/
 877
 878    if( *desc == NULL ) {
 879        DBG_PRINT( "Null descriptor\n" );
 880        status = -EFAULT;
 881    }
 882        //;?the "limited" NDIS strategy, assuming a frame consists ALWAYS out of 2
 883        //descriptors, make this robust
 884    if( status == 0 && (*desc)->next_desc_addr ) {
 885        status = wl_pci_dma_free_desc_and_buf( pdev, lp, &(*desc)->next_desc_addr );
 886    }
 887    if( status == 0 ) {
 888        status = wl_pci_dma_free_desc_and_buf( pdev, lp, desc );
 889    }
 890    return status;
 891} // wl_pci_dma_free_tx_packet
 892/*============================================================================*/
 893
 894/*******************************************************************************
 895 *      wl_pci_dma_alloc_rx_packet()
 896 *******************************************************************************
 897 *
 898 *  DESCRIPTION:
 899 *
 900 *      Allocates a single Rx packet, consisting of two descriptors and one
 901 *      contiguous buffer. The buffer starts with the hermes-specific header.
 902 *      One descriptor points at the start, the other at offset 0x3a of the
 903 *      buffer.
 904 *
 905 *  PARAMETERS:
 906 *
 907 *      pdev    - a pointer to the device's pci_dev structure
 908 *      lp      - the device's private adapter structure
 909 *      desc    - a pointer which will reference the descriptor to be alloc'd.
 910 *
 911 *  RETURNS:
 912 *
 913 *      0 on success
 914 *      errno value otherwise
 915 *
 916 ******************************************************************************/
 917int wl_pci_dma_alloc_rx_packet( struct pci_dev *pdev, struct wl_private *lp,
 918                                DESC_STRCT **desc )
 919{
 920    int         status = 0;
 921    DESC_STRCT  *p;
 922    /*------------------------------------------------------------------------*/
 923
 924//     if( desc == NULL ) {
 925//         status = -EFAULT;
 926//     }
 927//      //;?the "limited" NDIS strategy, assuming a frame consists ALWAYS out of 2
 928//      //descriptors, make this robust
 929//     if( status == 0 ) {
 930//         status = wl_pci_dma_alloc_desc( pdev, lp, desc );
 931//      }
 932//     if( status == 0 ) {
 933//         status = wl_pci_dma_alloc_buf( pdev, lp, *desc, HCF_MAX_PACKET_SIZE );
 934//     }
 935//     if( status == 0 ) {
 936//         status = wl_pci_dma_alloc_desc( pdev, lp, &p );
 937//     }
 938//     if( status == 0 ) {
 939//         /* Size of 1st descriptor becomes 0x3a bytes */
 940//         SET_BUF_SIZE( *desc, HCF_DMA_RX_BUF1_SIZE );
 941//
 942//         /* Make 2nd descriptor point at offset 0x3a of the buffer */
 943//         SET_BUF_SIZE( p, ( HCF_MAX_PACKET_SIZE - HCF_DMA_RX_BUF1_SIZE ));
 944//         p->buf_addr       = (*desc)->buf_addr + HCF_DMA_RX_BUF1_SIZE;
 945//         p->buf_phys_addr  = (*desc)->buf_phys_addr + HCF_DMA_RX_BUF1_SIZE;
 946//         p->next_desc_addr = NULL;
 947//
 948//         /* Chain 2nd descriptor to 1st descriptor */
 949//         (*desc)->next_desc_addr      = p;
 950//         (*desc)->next_desc_phys_addr = p->desc_phys_addr;
 951//     }
 952
 953    return status;
 954} // wl_pci_dma_alloc_rx_packet
 955/*============================================================================*/
 956
 957/*******************************************************************************
 958 *      wl_pci_dma_free_rx_packet()
 959 *******************************************************************************
 960 *
 961 *  DESCRIPTION:
 962 *
 963 *      Frees a single Rx packet, described in the corresponding alloc function.
 964 *
 965 *  PARAMETERS:
 966 *
 967 *      pdev    - a pointer to the device's pci_dev structure
 968 *      lp      - the device's private adapter structure
 969 *      desc    - a pointer which will reference the descriptor to be alloc'd.
 970 *
 971 *  RETURNS:
 972 *
 973 *      0 on success
 974 *      errno value otherwise
 975 *
 976 ******************************************************************************/
 977int wl_pci_dma_free_rx_packet( struct pci_dev *pdev, struct wl_private *lp,
 978                                DESC_STRCT **desc )
 979{
 980    int status = 0;
 981    DESC_STRCT *p;
 982    /*------------------------------------------------------------------------*/
 983
 984    if( *desc == NULL ) {
 985        status = -EFAULT;
 986    }
 987    if( status == 0 ) {
 988        p = (*desc)->next_desc_addr;
 989
 990        /* Free the 2nd descriptor */
 991        if( p != NULL ) {
 992            p->buf_addr      = NULL;
 993            p->buf_phys_addr = 0;
 994
 995            status = wl_pci_dma_free_desc( pdev, lp, &p );
 996        }
 997    }
 998
 999    /* Free the buffer and 1st descriptor */
1000    if( status == 0 ) {
1001        SET_BUF_SIZE( *desc, HCF_MAX_PACKET_SIZE );
1002        status = wl_pci_dma_free_desc_and_buf( pdev, lp, desc );
1003    }
1004    return status;
1005} // wl_pci_dma_free_rx_packet
1006/*============================================================================*/
1007
1008/*******************************************************************************
1009 *      wl_pci_dma_alloc_desc_and_buf()
1010 *******************************************************************************
1011 *
1012 *  DESCRIPTION:
1013 *
1014 *      Allocates a DMA descriptor and buffer, and associates them with one
1015 *      another.
1016 *
1017 *  PARAMETERS:
1018 *
1019 *      pdev  - a pointer to the device's pci_dev structure
1020 *      lp    - the device's private adapter structure
1021 *      desc  - a pointer which will reference the descriptor to be alloc'd
1022 *
1023 *  RETURNS:
1024 *
1025 *      0 on success
1026 *      errno value otherwise
1027 *
1028 ******************************************************************************/
1029int wl_pci_dma_alloc_desc_and_buf( struct pci_dev *pdev, struct wl_private *lp,
1030                                   DESC_STRCT **desc, int size )
1031{
1032    int status = 0;
1033    /*------------------------------------------------------------------------*/
1034
1035//     if( desc == NULL ) {
1036//         status = -EFAULT;
1037//     }
1038//     if( status == 0 ) {
1039//         status = wl_pci_dma_alloc_desc( pdev, lp, desc );
1040//
1041//         if( status == 0 ) {
1042//             status = wl_pci_dma_alloc_buf( pdev, lp, *desc, size );
1043//         }
1044//     }
1045    return status;
1046} // wl_pci_dma_alloc_desc_and_buf
1047/*============================================================================*/
1048
1049/*******************************************************************************
1050 *      wl_pci_dma_free_desc_and_buf()
1051 *******************************************************************************
1052 *
1053 *  DESCRIPTION:
1054 *
1055 *      Frees a DMA descriptor and associated buffer.
1056 *
1057 *  PARAMETERS:
1058 *
1059 *      pdev  - a pointer to the device's pci_dev structure
1060 *      lp    - the device's private adapter structure
1061 *      desc  - a pointer which will reference the descriptor to be alloc'd
1062 *
1063 *  RETURNS:
1064 *
1065 *      0 on success
1066 *      errno value otherwise
1067 *
1068 ******************************************************************************/
1069int wl_pci_dma_free_desc_and_buf( struct pci_dev *pdev, struct wl_private *lp,
1070                                   DESC_STRCT **desc )
1071{
1072    int status = 0;
1073    /*------------------------------------------------------------------------*/
1074
1075    if( desc == NULL ) {
1076        status = -EFAULT;
1077    }
1078    if( status == 0 && *desc == NULL ) {
1079        status = -EFAULT;
1080    }
1081    if( status == 0 ) {
1082        status = wl_pci_dma_free_buf( pdev, lp, *desc );
1083
1084        if( status == 0 ) {
1085            status = wl_pci_dma_free_desc( pdev, lp, desc );
1086        }
1087    }
1088    return status;
1089} // wl_pci_dma_free_desc_and_buf
1090/*============================================================================*/
1091
1092/*******************************************************************************
1093 *      wl_pci_dma_alloc_desc()
1094 *******************************************************************************
1095 *
1096 *  DESCRIPTION:
1097 *
1098 *      Allocates one DMA descriptor in cache coherent memory.
1099 *
1100 *  PARAMETERS:
1101 *
1102 *      pdev - a pointer to the device's pci_dev structure
1103 *      lp  - the device's private adapter structure
1104 *
1105 *  RETURNS:
1106 *
1107 *      0 on success
1108 *      errno value otherwise
1109 *
1110 ******************************************************************************/
1111int wl_pci_dma_alloc_desc( struct pci_dev *pdev, struct wl_private *lp,
1112                           DESC_STRCT **desc )
1113{
1114//     int         status = 0;
1115//     dma_addr_t  pa;
1116//     /*------------------------------------------------------------------------*/
1117//
1118//     DBG_FUNC( "wl_pci_dma_alloc_desc" );
1119//     DBG_ENTER( DbgInfo );
1120//
1121//     if( desc == NULL ) {
1122//         status = -EFAULT;
1123//     }
1124//     if( status == 0 ) {
1125//         *desc = pci_alloc_consistent( pdev, sizeof( DESC_STRCT ), &pa );
1126//     }
1127//     if( *desc == NULL ) {
1128//         DBG_ERROR( DbgInfo, "pci_alloc_consistent() failed\n" );
1129//         status = -ENOMEM;
1130//     } else {
1131//         memset( *desc, 0, sizeof( DESC_STRCT ));
1132//         (*desc)->desc_phys_addr = cpu_to_le32( pa );
1133//     }
1134//     DBG_LEAVE( DbgInfo );
1135//     return status;
1136} // wl_pci_dma_alloc_desc
1137/*============================================================================*/
1138
1139/*******************************************************************************
1140 *      wl_pci_dma_free_desc()
1141 *******************************************************************************
1142 *
1143 *  DESCRIPTION:
1144 *
1145 *      Frees one DMA descriptor in cache coherent memory.
1146 *
1147 *  PARAMETERS:
1148 *
1149 *      pdev - a pointer to the device's pci_dev structure
1150 *      lp  - the device's private adapter structure
1151 *
1152 *  RETURNS:
1153 *
1154 *      0 on success
1155 *      errno value otherwise
1156 *
1157 ******************************************************************************/
1158int wl_pci_dma_free_desc( struct pci_dev *pdev, struct wl_private *lp,
1159                           DESC_STRCT **desc )
1160{
1161    int         status = 0;
1162    /*------------------------------------------------------------------------*/
1163
1164    if( *desc == NULL ) {
1165        status = -EFAULT;
1166    }
1167    if( status == 0 ) {
1168        pci_free_consistent( pdev, sizeof( DESC_STRCT ), *desc,
1169                             (*desc)->desc_phys_addr );
1170    }
1171    *desc = NULL;
1172    return status;
1173} // wl_pci_dma_free_desc
1174/*============================================================================*/
1175
1176/*******************************************************************************
1177 *      wl_pci_dma_alloc_buf()
1178 *******************************************************************************
1179 *
1180 *  DESCRIPTION:
1181 *
1182 *      Allocates one DMA buffer in cache coherent memory, and associates a DMA
1183 *      descriptor with this buffer.
1184 *
1185 *  PARAMETERS:
1186 *
1187 *      pdev - a pointer to the device's pci_dev structure
1188 *      lp  - the device's private adapter structure
1189 *
1190 *  RETURNS:
1191 *
1192 *      0 on success
1193 *      errno value otherwise
1194 *
1195 ******************************************************************************/
1196int wl_pci_dma_alloc_buf( struct pci_dev *pdev, struct wl_private *lp,
1197                          DESC_STRCT *desc, int size )
1198{
1199    int         status = 0;
1200    dma_addr_t  pa;
1201    /*------------------------------------------------------------------------*/
1202
1203//     DBG_FUNC( "wl_pci_dma_alloc_buf" );
1204//     DBG_ENTER( DbgInfo );
1205//
1206//     if( desc == NULL ) {
1207//         status = -EFAULT;
1208//     }
1209//     if( status == 0 && desc->buf_addr != NULL ) {
1210//         status = -EFAULT;
1211//     }
1212//     if( status == 0 ) {
1213//         desc->buf_addr = pci_alloc_consistent( pdev, size, &pa );
1214//     }
1215//     if( desc->buf_addr == NULL ) {
1216//         DBG_ERROR( DbgInfo, "pci_alloc_consistent() failed\n" );
1217//         status = -ENOMEM;
1218//     } else {
1219//         desc->buf_phys_addr = cpu_to_le32( pa );
1220//         SET_BUF_SIZE( desc, size );
1221//     }
1222//     DBG_LEAVE( DbgInfo );
1223    return status;
1224} // wl_pci_dma_alloc_buf
1225/*============================================================================*/
1226
1227/*******************************************************************************
1228 *      wl_pci_dma_free_buf()
1229 *******************************************************************************
1230 *
1231 *  DESCRIPTION:
1232 *
1233 *      Allocates one DMA buffer in cache coherent memory, and associates a DMA
1234 *      descriptor with this buffer.
1235 *
1236 *  PARAMETERS:
1237 *
1238 *      pdev - a pointer to the device's pci_dev structure
1239 *      lp  - the device's private adapter structure
1240 *
1241 *  RETURNS:
1242 *
1243 *      0 on success
1244 *      errno value otherwise
1245 *
1246 ******************************************************************************/
1247int wl_pci_dma_free_buf( struct pci_dev *pdev, struct wl_private *lp,
1248                         DESC_STRCT *desc )
1249{
1250    int         status = 0;
1251    /*------------------------------------------------------------------------*/
1252
1253    if( desc == NULL ) {
1254        status = -EFAULT;
1255    }
1256    if( status == 0 && desc->buf_addr == NULL ) {
1257        status = -EFAULT;
1258    }
1259    if( status == 0 ) {
1260        pci_free_consistent( pdev, GET_BUF_SIZE( desc ), desc->buf_addr,
1261                             desc->buf_phys_addr );
1262
1263        desc->buf_addr = 0;
1264        desc->buf_phys_addr = 0;
1265        SET_BUF_SIZE( desc, 0 );
1266    }
1267    return status;
1268} // wl_pci_dma_free_buf
1269/*============================================================================*/
1270
1271/*******************************************************************************
1272 *      wl_pci_dma_hcf_supply()
1273 *******************************************************************************
1274 *
1275 *  DESCRIPTION:
1276 *
1277 *      Supply HCF with DMA-related resources. These consist of:
1278 *          - buffers and descriptors for receive purposes
1279 *          - one 'reclaim' descriptor for the transmit path, used to fulfill a
1280 *            certain H25 DMA engine requirement
1281 *          - one 'reclaim' descriptor for the receive path, used to fulfill a
1282 *            certain H25 DMA engine requirement
1283 *
1284 *      This function is called at start-of-day or at re-initialization.
1285 *
1286 *  PARAMETERS:
1287 *
1288 *      lp  - the device's private adapter structure
1289 *
1290 *  RETURNS:
1291 *
1292 *      0 on success
1293 *      errno value otherwise
1294 *
1295 ******************************************************************************/
1296void wl_pci_dma_hcf_supply( struct wl_private *lp )
1297{
1298    int i;
1299    /*------------------------------------------------------------------------*/
1300
1301    DBG_FUNC( "wl_pci_dma_hcf_supply" );
1302    DBG_ENTER( DbgInfo );
1303
1304    //if( lp->dma.status == 0 );
1305    //{
1306        /* Hand over the Rx/Tx reclaim descriptors to the HCF */
1307        if( lp->dma.tx_reclaim_desc ) {
1308            DBG_PRINT( "lp->dma.tx_reclaim_desc: 0x%p\n", lp->dma.tx_reclaim_desc );
1309            hcf_dma_tx_put( &lp->hcfCtx, lp->dma.tx_reclaim_desc, 0 );
1310            lp->dma.tx_reclaim_desc = NULL;
1311            DBG_PRINT( "lp->dma.tx_reclaim_desc: 0x%p\n", lp->dma.tx_reclaim_desc );
1312        }
1313        if( lp->dma.rx_reclaim_desc ) {
1314            DBG_PRINT( "lp->dma.rx_reclaim_desc: 0x%p\n", lp->dma.rx_reclaim_desc );
1315            hcf_dma_rx_put( &lp->hcfCtx, lp->dma.rx_reclaim_desc );
1316            lp->dma.rx_reclaim_desc = NULL;
1317            DBG_PRINT( "lp->dma.rx_reclaim_desc: 0x%p\n", lp->dma.rx_reclaim_desc );
1318        }
1319        /* Hand over the Rx descriptor chain to the HCF */
1320        for( i = 0; i < NUM_RX_DESC; i++ ) {
1321            DBG_PRINT( "lp->dma.rx_packet[%d]:    0x%p\n", i, lp->dma.rx_packet[i] );
1322            hcf_dma_rx_put( &lp->hcfCtx, lp->dma.rx_packet[i] );
1323            lp->dma.rx_packet[i] = NULL;
1324            DBG_PRINT( "lp->dma.rx_packet[%d]:    0x%p\n", i, lp->dma.rx_packet[i] );
1325        }
1326    //}
1327
1328    DBG_LEAVE( DbgInfo );
1329    return;
1330} // wl_pci_dma_hcf_supply
1331/*============================================================================*/
1332
1333/*******************************************************************************
1334 *      wl_pci_dma_hcf_reclaim()
1335 *******************************************************************************
1336 *
1337 *  DESCRIPTION:
1338 *
1339 *      Return DMA-related resources from the HCF. These consist of:
1340 *          - buffers and descriptors for receive purposes
1341 *          - buffers and descriptors for transmit purposes
1342 *          - one 'reclaim' descriptor for the transmit path, used to fulfill a
1343 *            certain H25 DMA engine requirement
1344 *          - one 'reclaim' descriptor for the receive path, used to fulfill a
1345 *            certain H25 DMA engine requirement
1346 *
1347 *      This function is called at end-of-day or at re-initialization.
1348 *
1349 *  PARAMETERS:
1350 *
1351 *      lp  - the device's private adapter structure
1352 *
1353 *  RETURNS:
1354 *
1355 *      0 on success
1356 *      errno value otherwise
1357 *
1358 ******************************************************************************/
1359void wl_pci_dma_hcf_reclaim( struct wl_private *lp )
1360{
1361    int i;
1362    /*------------------------------------------------------------------------*/
1363
1364    DBG_FUNC( "wl_pci_dma_hcf_reclaim" );
1365    DBG_ENTER( DbgInfo );
1366
1367    wl_pci_dma_hcf_reclaim_rx( lp );
1368    for( i = 0; i < NUM_RX_DESC; i++ ) {
1369        DBG_PRINT( "rx_packet[%d] 0x%p\n", i, lp->dma.rx_packet[i] );
1370//         if( lp->dma.rx_packet[i] == NULL ) {
1371//             DBG_PRINT( "wl_pci_dma_hcf_reclaim: rx_packet[%d] NULL\n", i );
1372//         }
1373    }
1374
1375    wl_pci_dma_hcf_reclaim_tx( lp );
1376    for( i = 0; i < NUM_TX_DESC; i++ ) {
1377        DBG_PRINT( "tx_packet[%d] 0x%p\n", i, lp->dma.tx_packet[i] );
1378//         if( lp->dma.tx_packet[i] == NULL ) {
1379//             DBG_PRINT( "wl_pci_dma_hcf_reclaim: tx_packet[%d] NULL\n", i );
1380//         }
1381     }
1382
1383    DBG_LEAVE( DbgInfo );
1384    return;
1385} // wl_pci_dma_hcf_reclaim
1386/*============================================================================*/
1387
1388/*******************************************************************************
1389 *      wl_pci_dma_hcf_reclaim_rx()
1390 *******************************************************************************
1391 *
1392 *  DESCRIPTION:
1393 *
1394 *      Reclaim Rx packets that have already been processed by the HCF.
1395 *
1396 *  PARAMETERS:
1397 *
1398 *      lp  - the device's private adapter structure
1399 *
1400 *  RETURNS:
1401 *
1402 *      0 on success
1403 *      errno value otherwise
1404 *
1405 ******************************************************************************/
1406void wl_pci_dma_hcf_reclaim_rx( struct wl_private *lp )
1407{
1408    int         i;
1409    DESC_STRCT *p;
1410    /*------------------------------------------------------------------------*/
1411
1412    DBG_FUNC( "wl_pci_dma_hcf_reclaim_rx" );
1413    DBG_ENTER( DbgInfo );
1414
1415    //if( lp->dma.status == 0 )
1416    //{
1417        while ( ( p = hcf_dma_rx_get( &lp->hcfCtx ) ) != NULL ) {
1418            if( p && p->buf_addr == NULL ) {
1419                /* A reclaim descriptor is being given back by the HCF. Reclaim
1420                   descriptors have a NULL buf_addr */
1421                lp->dma.rx_reclaim_desc = p;
1422                DBG_PRINT( "reclaim_descriptor: 0x%p\n", p );
1423                continue;
1424            }
1425            for( i = 0; i < NUM_RX_DESC; i++ ) {
1426                if( lp->dma.rx_packet[i] == NULL ) {
1427                    break;
1428                }
1429            }
1430            /* An Rx buffer descriptor is being given back by the HCF */
1431            lp->dma.rx_packet[i] = p;
1432            lp->dma.rx_rsc_ind++;
1433                DBG_PRINT( "rx_packet[%d] 0x%p\n", i, lp->dma.rx_packet[i] );
1434        }
1435    //}
1436    DBG_LEAVE( DbgInfo );
1437} // wl_pci_dma_hcf_reclaim_rx
1438/*============================================================================*/
1439
1440/*******************************************************************************
1441 *      wl_pci_dma_get_tx_packet()
1442 *******************************************************************************
1443 *
1444 *  DESCRIPTION:
1445 *
1446 *      Obtains a Tx descriptor from the chain to use for Tx.
1447 *
1448 *  PARAMETERS:
1449 *
1450 *      lp - a pointer to the device's wl_private structure.
1451 *
1452 *  RETURNS:
1453 *
1454 *      A pointer to the retrieved descriptor
1455 *
1456 ******************************************************************************/
1457DESC_STRCT * wl_pci_dma_get_tx_packet( struct wl_private *lp )
1458{
1459    int i;
1460    DESC_STRCT *desc = NULL;
1461    /*------------------------------------------------------------------------*/
1462
1463    for( i = 0; i < NUM_TX_DESC; i++ ) {
1464        if( lp->dma.tx_packet[i] ) {
1465            break;
1466        }
1467    }
1468
1469    if( i != NUM_TX_DESC ) {
1470        desc = lp->dma.tx_packet[i];
1471
1472        lp->dma.tx_packet[i] = NULL;
1473        lp->dma.tx_rsc_ind--;
1474
1475        memset( desc->buf_addr, 0, HCF_DMA_TX_BUF1_SIZE );
1476    }
1477
1478    return desc;
1479} // wl_pci_dma_get_tx_packet
1480/*============================================================================*/
1481
1482/*******************************************************************************
1483 *      wl_pci_dma_put_tx_packet()
1484 *******************************************************************************
1485 *
1486 *  DESCRIPTION:
1487 *
1488 *      Returns a Tx descriptor to the chain.
1489 *
1490 *  PARAMETERS:
1491 *
1492 *      lp   - a pointer to the device's wl_private structure.
1493 *      desc - a pointer to the descriptor to return.
1494 *
1495 *  RETURNS:
1496 *
1497 *      N/A
1498 *
1499 ******************************************************************************/
1500void wl_pci_dma_put_tx_packet( struct wl_private *lp, DESC_STRCT *desc )
1501{
1502    int i;
1503    /*------------------------------------------------------------------------*/
1504
1505    for( i = 0; i < NUM_TX_DESC; i++ ) {
1506        if( lp->dma.tx_packet[i] == NULL ) {
1507            break;
1508        }
1509    }
1510
1511    if( i != NUM_TX_DESC ) {
1512        lp->dma.tx_packet[i] = desc;
1513        lp->dma.tx_rsc_ind++;
1514    }
1515} // wl_pci_dma_put_tx_packet
1516/*============================================================================*/
1517
1518/*******************************************************************************
1519 *      wl_pci_dma_hcf_reclaim_tx()
1520 *******************************************************************************
1521 *
1522 *  DESCRIPTION:
1523 *
1524 *      Reclaim Tx packets that have either been processed by the HCF due to a
1525 *      port disable or a Tx completion.
1526 *
1527 *  PARAMETERS:
1528 *
1529 *      lp  - the device's private adapter structure
1530 *
1531 *  RETURNS:
1532 *
1533 *      0 on success
1534 *      errno value otherwise
1535 *
1536 ******************************************************************************/
1537void wl_pci_dma_hcf_reclaim_tx( struct wl_private *lp )
1538{
1539    int         i;
1540    DESC_STRCT *p;
1541    /*------------------------------------------------------------------------*/
1542
1543    DBG_FUNC( "wl_pci_dma_hcf_reclaim_tx" );
1544    DBG_ENTER( DbgInfo );
1545
1546    //if( lp->dma.status == 0 )
1547    //{
1548        while ( ( p = hcf_dma_tx_get( &lp->hcfCtx ) ) != NULL ) {
1549
1550            if( p != NULL && p->buf_addr == NULL ) {
1551                /* A Reclaim descriptor is being given back by the HCF. Reclaim
1552                   descriptors have a NULL buf_addr */
1553                lp->dma.tx_reclaim_desc = p;
1554                DBG_PRINT( "reclaim_descriptor: 0x%p\n", p );
1555                continue;
1556            }
1557            for( i = 0; i < NUM_TX_DESC; i++ ) {
1558                if( lp->dma.tx_packet[i] == NULL ) {
1559                    break;
1560                }
1561            }
1562            /* An Rx buffer descriptor is being given back by the HCF */
1563            lp->dma.tx_packet[i] = p;
1564            lp->dma.tx_rsc_ind++;
1565                DBG_PRINT( "tx_packet[%d] 0x%p\n", i, lp->dma.tx_packet[i] );
1566        }
1567    //}
1568
1569    if( lp->netif_queue_on == FALSE ) {
1570        netif_wake_queue( lp->dev );
1571        WL_WDS_NETIF_WAKE_QUEUE( lp );
1572        lp->netif_queue_on = TRUE;
1573    }
1574    DBG_LEAVE( DbgInfo );
1575    return;
1576} // wl_pci_dma_hcf_reclaim_tx
1577/*============================================================================*/
1578#endif  // ENABLE_DMA
1579