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