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