Merge branch 'staging-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh...
[pandora-kernel.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/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
111 extern dbg_info_t *DbgInfo;
112 #endif  // DBG
113
114 /* define the PCI device Table Cardname and id tables */
115 enum hermes_pci_versions {
116         CH_Agere_Systems_Mini_PCI_V1 = 0,
117 };
118
119 static 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
130 MODULE_DEVICE_TABLE(pci, wl_pci_tbl);
131
132 /*******************************************************************************
133  * function prototypes
134  ******************************************************************************/
135 int __devinit wl_pci_probe( struct pci_dev *pdev,
136                                 const struct pci_device_id *ent );
137 void __devexit wl_pci_remove(struct pci_dev *pdev);
138 int wl_pci_setup( struct pci_dev *pdev );
139 void wl_pci_enable_cardbus_interrupts( struct pci_dev *pdev );
140
141 #ifdef ENABLE_DMA
142 int wl_pci_dma_alloc( struct pci_dev *pdev, struct wl_private *lp );
143 int wl_pci_dma_free( struct pci_dev *pdev, struct wl_private *lp );
144 int wl_pci_dma_alloc_tx_packet( struct pci_dev *pdev, struct wl_private *lp,
145                                 DESC_STRCT **desc );
146 int wl_pci_dma_free_tx_packet( struct pci_dev *pdev, struct wl_private *lp,
147                                 DESC_STRCT **desc );
148 int wl_pci_dma_alloc_rx_packet( struct pci_dev *pdev, struct wl_private *lp,
149                                 DESC_STRCT **desc );
150 int wl_pci_dma_free_rx_packet( struct pci_dev *pdev, struct wl_private *lp,
151                                 DESC_STRCT **desc );
152 int wl_pci_dma_alloc_desc_and_buf( struct pci_dev *pdev, struct wl_private *lp,
153                                    DESC_STRCT **desc, int size );
154 int wl_pci_dma_free_desc_and_buf( struct pci_dev *pdev, struct wl_private *lp,
155                                    DESC_STRCT **desc );
156 int wl_pci_dma_alloc_desc( struct pci_dev *pdev, struct wl_private *lp,
157                            DESC_STRCT **desc );
158 int wl_pci_dma_free_desc( struct pci_dev *pdev, struct wl_private *lp,
159                            DESC_STRCT **desc );
160 int wl_pci_dma_alloc_buf( struct pci_dev *pdev, struct wl_private *lp,
161                           DESC_STRCT *desc, int size );
162 int wl_pci_dma_free_buf( struct pci_dev *pdev, struct wl_private *lp,
163                           DESC_STRCT *desc );
164
165 void wl_pci_dma_hcf_reclaim_rx( struct wl_private *lp );
166 #endif  // ENABLE_DMA
167
168 /*******************************************************************************
169  * PCI module function registration
170  ******************************************************************************/
171 static 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  ******************************************************************************/
198 int 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  ******************************************************************************/
232 void 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  ******************************************************************************/
265 int 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  ******************************************************************************/
306 int 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  ******************************************************************************/
345 int 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  ******************************************************************************/
377 int 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  ******************************************************************************/
410 int __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  ******************************************************************************/
447 void __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 = 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  ******************************************************************************/
500 int 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  ******************************************************************************/
613 void 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  ******************************************************************************/
679 int 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  ******************************************************************************/
750 int 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  ******************************************************************************/
831 int 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  ******************************************************************************/
877 int 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  ******************************************************************************/
922 int 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  ******************************************************************************/
982 int 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  ******************************************************************************/
1034 int 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  ******************************************************************************/
1074 int 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  ******************************************************************************/
1116 int 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  ******************************************************************************/
1163 int 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  ******************************************************************************/
1201 int 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  ******************************************************************************/
1252 int 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  ******************************************************************************/
1301 void 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  ******************************************************************************/
1364 void 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  ******************************************************************************/
1411 void 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  ******************************************************************************/
1462 DESC_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  ******************************************************************************/
1505 void 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  ******************************************************************************/
1542 void 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