OSDN Git Service

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