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