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