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