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