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