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