GUI: Fix Tomato RAF theme for all builds. Compilation typo.
[tomato.git] / release / src-rt-6.x.4708 / linux / linux-2.6.36 / drivers / staging / wlags49_h2 / wl_pci.c
blob020b17adee2d27bcc20fddb21df10d00451570cf
1 /*******************************************************************************
2 * Agere Systems Inc.
3 * Wireless device driver for Linux (wlags49).
5 * Copyright (c) 1998-2003 Agere Systems Inc.
6 * All rights reserved.
7 * http://www.agere.com
9 * Initially developed by TriplePoint, Inc.
10 * http://www.triplepoint.com
12 *------------------------------------------------------------------------------
14 * This file contains processing and initialization specific to PCI/miniPCI
15 * devices.
17 *------------------------------------------------------------------------------
19 * SOFTWARE LICENSE
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.
26 * Copyright © 2003 Agere Systems Inc.
27 * All rights reserved.
29 * Redistribution and use in source or binary forms, with or without
30 * modifications, are permitted provided that the following conditions are met:
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.
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.
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.
45 * Disclaimer
47 * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES,
48 * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
49 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY
50 * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
51 * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY
52 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
53 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
54 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
55 * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT
56 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
57 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
58 * DAMAGE.
60 ******************************************************************************/
62 /*******************************************************************************
63 * include files
64 ******************************************************************************/
65 #include <wireless/wl_version.h>
67 #include <linux/module.h>
68 #include <linux/kernel.h>
69 #include <linux/errno.h>
70 #include <linux/pci.h>
71 #include <linux/init.h>
72 #include <linux/sched.h>
73 #include <linux/ptrace.h>
74 #include <linux/ctype.h>
75 #include <linux/string.h>
76 //#include <linux/timer.h>
77 #include <linux/interrupt.h>
78 #include <linux/in.h>
79 #include <linux/delay.h>
80 #include <asm/system.h>
81 #include <asm/io.h>
82 #include <asm/irq.h>
83 #include <asm/bitops.h>
84 #include <asm/uaccess.h>
86 #include <linux/ethtool.h>
87 #include <linux/netdevice.h>
88 #include <linux/etherdevice.h>
89 #include <linux/skbuff.h>
90 #include <linux/if_arp.h>
91 #include <linux/ioport.h>
93 #include <hcf/debug.h>
95 #include <hcf.h>
96 #include <dhf.h>
97 #include <hcfdef.h>
99 #include <wireless/wl_if.h>
100 #include <wireless/wl_internal.h>
101 #include <wireless/wl_util.h>
102 #include <wireless/wl_main.h>
103 #include <wireless/wl_netdev.h>
104 #include <wireless/wl_pci.h>
107 /*******************************************************************************
108 * global variables
109 ******************************************************************************/
110 #if DBG
111 extern dbg_info_t *DbgInfo;
112 #endif // DBG
114 /* define the PCI device Table Cardname and id tables */
115 enum hermes_pci_versions {
116 CH_Agere_Systems_Mini_PCI_V1 = 0,
119 static struct pci_device_id wl_pci_tbl[] __devinitdata = {
120 { PCI_VENDOR_ID_WL_LKM, PCI_DEVICE_ID_WL_LKM_0,
121 PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_Agere_Systems_Mini_PCI_V1 },
122 { PCI_VENDOR_ID_WL_LKM, PCI_DEVICE_ID_WL_LKM_1,
123 PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_Agere_Systems_Mini_PCI_V1 },
124 { PCI_VENDOR_ID_WL_LKM, PCI_DEVICE_ID_WL_LKM_2,
125 PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_Agere_Systems_Mini_PCI_V1 },
127 { } /* Terminating entry */
130 MODULE_DEVICE_TABLE(pci, wl_pci_tbl);
132 /*******************************************************************************
133 * function prototypes
134 ******************************************************************************/
135 int __devinit wl_pci_probe( struct pci_dev *pdev,
136 const struct pci_device_id *ent );
137 void __devexit wl_pci_remove(struct pci_dev *pdev);
138 int wl_pci_setup( struct pci_dev *pdev );
139 void wl_pci_enable_cardbus_interrupts( struct pci_dev *pdev );
141 #ifdef ENABLE_DMA
142 int wl_pci_dma_alloc( struct pci_dev *pdev, struct wl_private *lp );
143 int wl_pci_dma_free( struct pci_dev *pdev, struct wl_private *lp );
144 int wl_pci_dma_alloc_tx_packet( struct pci_dev *pdev, struct wl_private *lp,
145 DESC_STRCT **desc );
146 int wl_pci_dma_free_tx_packet( struct pci_dev *pdev, struct wl_private *lp,
147 DESC_STRCT **desc );
148 int wl_pci_dma_alloc_rx_packet( struct pci_dev *pdev, struct wl_private *lp,
149 DESC_STRCT **desc );
150 int wl_pci_dma_free_rx_packet( struct pci_dev *pdev, struct wl_private *lp,
151 DESC_STRCT **desc );
152 int wl_pci_dma_alloc_desc_and_buf( struct pci_dev *pdev, struct wl_private *lp,
153 DESC_STRCT **desc, int size );
154 int wl_pci_dma_free_desc_and_buf( struct pci_dev *pdev, struct wl_private *lp,
155 DESC_STRCT **desc );
156 int wl_pci_dma_alloc_desc( struct pci_dev *pdev, struct wl_private *lp,
157 DESC_STRCT **desc );
158 int wl_pci_dma_free_desc( struct pci_dev *pdev, struct wl_private *lp,
159 DESC_STRCT **desc );
160 int wl_pci_dma_alloc_buf( struct pci_dev *pdev, struct wl_private *lp,
161 DESC_STRCT *desc, int size );
162 int wl_pci_dma_free_buf( struct pci_dev *pdev, struct wl_private *lp,
163 DESC_STRCT *desc );
165 void wl_pci_dma_hcf_reclaim_rx( struct wl_private *lp );
166 #endif // ENABLE_DMA
168 /*******************************************************************************
169 * PCI module function registration
170 ******************************************************************************/
171 static struct pci_driver wl_driver =
173 name: MODULE_NAME,
174 id_table: wl_pci_tbl,
175 probe: wl_pci_probe,
176 remove: __devexit_p(wl_pci_remove),
177 suspend: NULL,
178 resume: NULL,
181 /*******************************************************************************
182 * wl_adapter_init_module()
183 *******************************************************************************
185 * DESCRIPTION:
187 * Called by init_module() to perform PCI-specific driver initialization.
189 * PARAMETERS:
191 * N/A
193 * RETURNS:
197 ******************************************************************************/
198 int wl_adapter_init_module( void )
200 int result;
201 /*------------------------------------------------------------------------*/
203 DBG_FUNC( "wl_adapter_init_module()" );
204 DBG_ENTER( DbgInfo );
205 DBG_TRACE( DbgInfo, "wl_adapter_init_module() -- PCI\n" );
207 result = pci_register_driver( &wl_driver ); //;?replace with pci_module_init, Rubini pg 490
208 //;? why not do something with the result
210 DBG_LEAVE( DbgInfo );
211 return 0;
212 } // wl_adapter_init_module
213 /*============================================================================*/
215 /*******************************************************************************
216 * wl_adapter_cleanup_module()
217 *******************************************************************************
219 * DESCRIPTION:
221 * Called by cleanup_module() to perform PCI-specific driver cleanup.
223 * PARAMETERS:
225 * N/A
227 * RETURNS:
229 * N/A
231 ******************************************************************************/
232 void wl_adapter_cleanup_module( void )
234 //;?how comes wl_adapter_cleanup_module is located in a seemingly pci specific module
235 DBG_FUNC( "wl_adapter_cleanup_module" );
236 DBG_ENTER( DbgInfo );
238 //;?DBG_TRACE below feels like nearly redundant in the light of DBG_ENTER above
239 DBG_TRACE( DbgInfo, "wl_adapter_cleanup_module() -- PCI\n" );
241 pci_unregister_driver( &wl_driver );
243 DBG_LEAVE( DbgInfo );
244 return;
245 } // wl_adapter_cleanup_module
246 /*============================================================================*/
248 /*******************************************************************************
249 * wl_adapter_insert()
250 *******************************************************************************
252 * DESCRIPTION:
254 * Called by wl_pci_probe() to continue the process of device insertion.
256 * PARAMETERS:
258 * dev - a pointer to the device's net_device structure
260 * RETURNS:
262 * TRUE or FALSE
264 ******************************************************************************/
265 int wl_adapter_insert( struct net_device *dev )
267 int result = FALSE;
268 /*------------------------------------------------------------------------*/
270 DBG_FUNC( "wl_adapter_insert" );
271 DBG_ENTER( DbgInfo );
273 DBG_TRACE( DbgInfo, "wl_adapter_insert() -- PCI\n" );
275 if( dev == NULL ) {
276 DBG_ERROR( DbgInfo, "net_device pointer is NULL!!!\n" );
277 } else if( dev->priv == NULL ) {
278 DBG_ERROR( DbgInfo, "wl_private pointer is NULL!!!\n" );
279 } else if( wl_insert( dev ) ) { /* Perform remaining device initialization */
280 result = TRUE;
281 } else {
282 DBG_TRACE( DbgInfo, "wl_insert() FAILED\n" );
284 DBG_LEAVE( DbgInfo );
285 return result;
286 } // wl_adapter_insert
287 /*============================================================================*/
289 /*******************************************************************************
290 * wl_adapter_open()
291 *******************************************************************************
293 * DESCRIPTION:
295 * Open the device.
297 * PARAMETERS:
299 * dev - a pointer to the device's net_device structure
301 * RETURNS:
303 * an HCF status code
305 ******************************************************************************/
306 int wl_adapter_open( struct net_device *dev )
308 int result = 0;
309 int hcf_status = HCF_SUCCESS;
310 /*------------------------------------------------------------------------*/
312 DBG_FUNC( "wl_adapter_open" );
313 DBG_ENTER( DbgInfo );
315 DBG_TRACE( DbgInfo, "wl_adapter_open() -- PCI\n" );
317 hcf_status = wl_open( dev );
319 if( hcf_status != HCF_SUCCESS ) {
320 result = -ENODEV;
323 DBG_LEAVE( DbgInfo );
324 return result;
325 } // wl_adapter_open
326 /*============================================================================*/
328 /*******************************************************************************
329 * wl_adapter_close()
330 *******************************************************************************
332 * DESCRIPTION:
334 * Close the device
336 * PARAMETERS:
338 * dev - a pointer to the device's net_device structure
340 * RETURNS:
344 ******************************************************************************/
345 int wl_adapter_close( struct net_device *dev )
347 DBG_FUNC( "wl_adapter_close" );
348 DBG_ENTER( DbgInfo );
350 DBG_TRACE( DbgInfo, "wl_adapter_close() -- PCI\n" );
351 DBG_TRACE( DbgInfo, "%s: Shutting down adapter.\n", dev->name );
353 wl_close( dev );
355 DBG_LEAVE( DbgInfo );
356 return 0;
357 } // wl_adapter_close
358 /*============================================================================*/
360 /*******************************************************************************
361 * wl_adapter_is_open()
362 *******************************************************************************
364 * DESCRIPTION:
366 * Check whether this device is open. Returns
368 * PARAMETERS:
370 * dev - a pointer to the device's net_device structure
372 * RETURNS:
374 * nonzero if device is open.
376 ******************************************************************************/
377 int wl_adapter_is_open( struct net_device *dev )
379 /* This function is used in PCMCIA to check the status of the 'open' field
380 in the dev_link_t structure associated with a network device. There
381 doesn't seem to be an analog to this for PCI, and checking the status
382 contained in the net_device structure doesn't have the same effect.
383 For now, return TRUE, but find out if this is necessary for PCI. */
385 return TRUE;
386 } // wl_adapter_is_open
387 /*============================================================================*/
389 /*******************************************************************************
390 * wl_pci_probe()
391 *******************************************************************************
393 * DESCRIPTION:
395 * Registered in the pci_driver structure, this function is called when the
396 * PCI subsystem finds a new PCI device which matches the infomation contained
397 * in the pci_device_id table.
399 * PARAMETERS:
401 * pdev - a pointer to the device's pci_dev structure
402 * ent - this device's entry in the pci_device_id table
404 * RETURNS:
406 * 0 on success
407 * errno value otherwise
409 ******************************************************************************/
410 int __devinit wl_pci_probe( struct pci_dev *pdev,
411 const struct pci_device_id *ent )
413 int result;
414 /*------------------------------------------------------------------------*/
416 DBG_FUNC( "wl_pci_probe" );
417 DBG_ENTER( DbgInfo );
418 DBG_PRINT( "%s\n", VERSION_INFO );
420 result = wl_pci_setup( pdev );
422 DBG_LEAVE( DbgInfo );
424 return result;
425 } // wl_pci_probe
426 /*============================================================================*/
428 /*******************************************************************************
429 * wl_pci_remove()
430 *******************************************************************************
432 * DESCRIPTION:
434 * Registered in the pci_driver structure, this function is called when the
435 * PCI subsystem detects that a PCI device which matches the infomation
436 * contained in the pci_device_id table has been removed.
438 * PARAMETERS:
440 * pdev - a pointer to the device's pci_dev structure
442 * RETURNS:
444 * N/A
446 ******************************************************************************/
447 void __devexit wl_pci_remove(struct pci_dev *pdev)
449 struct net_device *dev = NULL;
450 /*------------------------------------------------------------------------*/
452 DBG_FUNC( "wl_pci_remove" );
453 DBG_ENTER( DbgInfo );
455 /* Make sure the pci_dev pointer passed in is valid */
456 if( pdev == NULL ) {
457 DBG_ERROR( DbgInfo, "PCI subsys passed in an invalid pci_dev pointer\n" );
458 return;
461 dev = (struct net_device *)pci_get_drvdata( pdev );
462 if( dev == NULL ) {
463 DBG_ERROR( DbgInfo, "Could not retrieve net_device structure\n" );
464 return;
467 /* Perform device cleanup */
468 wl_remove( dev );
469 free_irq( dev->irq, dev );
471 #ifdef ENABLE_DMA
472 wl_pci_dma_free( pdev, dev->priv );
473 #endif
475 wl_device_dealloc( dev );
477 DBG_LEAVE( DbgInfo );
478 return;
479 } // wl_pci_remove
480 /*============================================================================*/
482 /*******************************************************************************
483 * wl_pci_setup()
484 *******************************************************************************
486 * DESCRIPTION:
488 * Called by wl_pci_probe() to begin a device's initialization process.
490 * PARAMETERS:
492 * pdev - a pointer to the device's pci_dev structure
494 * RETURNS:
496 * 0 on success
497 * errno value otherwise
499 ******************************************************************************/
500 int wl_pci_setup( struct pci_dev *pdev )
502 int result = 0;
503 struct net_device *dev = NULL;
504 struct wl_private *lp = NULL;
505 /*------------------------------------------------------------------------*/
507 DBG_FUNC( "wl_pci_setup" );
508 DBG_ENTER( DbgInfo );
510 /* Make sure the pci_dev pointer passed in is valid */
511 if( pdev == NULL ) {
512 DBG_ERROR( DbgInfo, "PCI subsys passed in an invalid pci_dev pointer\n" );
513 return -ENODEV;
516 result = pci_enable_device( pdev );
517 if( result != 0 ) {
518 DBG_ERROR( DbgInfo, "pci_enable_device() failed\n" );
519 DBG_LEAVE( DbgInfo );
520 return result;
523 /* We found our device! Let's register it with the system */
524 DBG_TRACE( DbgInfo, "Found our device, now registering\n" );
525 dev = wl_device_alloc( );
526 if( dev == NULL ) {
527 DBG_ERROR( DbgInfo, "Could not register device!!!\n" );
528 DBG_LEAVE( DbgInfo );
529 return -ENOMEM;
532 /* Make sure that space was allocated for our private adapter struct */
533 if( dev->priv == NULL ) {
534 DBG_ERROR( DbgInfo, "Private adapter struct was not allocated!!!\n" );
535 DBG_LEAVE( DbgInfo );
536 return -ENOMEM;
539 #ifdef ENABLE_DMA
540 /* Allocate DMA Descriptors */
541 if( wl_pci_dma_alloc( pdev, dev->priv ) < 0 ) {
542 DBG_ERROR( DbgInfo, "Could not allocate DMA descriptor memory!!!\n" );
543 DBG_LEAVE( DbgInfo );
544 return -ENOMEM;
546 #endif
548 /* Register our private adapter structure with PCI */
549 pci_set_drvdata( pdev, dev );
551 /* Fill out bus specific information in the net_device struct */
552 dev->irq = pdev->irq;
553 SET_MODULE_OWNER( dev );
555 DBG_TRACE( DbgInfo, "Device Base Address: %#03lx\n", pdev->resource[0].start );
556 dev->base_addr = pdev->resource[0].start;
558 /* Initialize our device here */
559 if( !wl_adapter_insert( dev )) {
560 DBG_ERROR( DbgInfo, "wl_adapter_insert() FAILED!!!\n" );
561 wl_device_dealloc( dev );
562 DBG_LEAVE( DbgInfo );
563 return -EINVAL;
566 /* Register our ISR */
567 DBG_TRACE( DbgInfo, "Registering ISR...\n" );
569 result = request_irq(dev->irq, wl_isr, SA_SHIRQ, dev->name, dev);
570 if( result ) {
571 DBG_WARNING( DbgInfo, "Could not register ISR!!!\n" );
572 DBG_LEAVE( DbgInfo );
573 return result;
576 /* Make sure interrupts are enabled properly for CardBus */
577 lp = dev->priv;
579 if( lp->hcfCtx.IFB_BusType == CFG_NIC_BUS_TYPE_CARDBUS ||
580 lp->hcfCtx.IFB_BusType == CFG_NIC_BUS_TYPE_PCI ) {
581 DBG_TRACE( DbgInfo, "This is a PCI/CardBus card, enable interrupts\n" );
582 wl_pci_enable_cardbus_interrupts( pdev );
585 /* Enable bus mastering */
586 pci_set_master( pdev );
588 DBG_LEAVE( DbgInfo );
589 return 0;
590 } // wl_pci_setup
591 /*============================================================================*/
593 /*******************************************************************************
594 * wl_pci_enable_cardbus_interrupts()
595 *******************************************************************************
597 * DESCRIPTION:
599 * Called by wl_pci_setup() to enable interrupts on a CardBus device. This
600 * is done by writing bit 15 to the function event mask register. This
601 * CardBus-specific register is located in BAR2 (counting from BAR0), in memory
602 * space at byte offset 1f4 (7f4 for WARP).
604 * PARAMETERS:
606 * pdev - a pointer to the device's pci_dev structure
608 * RETURNS:
610 * N/A
612 ******************************************************************************/
613 void wl_pci_enable_cardbus_interrupts( struct pci_dev *pdev )
615 u32 bar2_reg;
616 u32 mem_addr_bus;
617 u32 func_evt_mask_reg;
618 void *mem_addr_kern = NULL;
619 /*------------------------------------------------------------------------*/
621 DBG_FUNC( "wl_pci_enable_cardbus_interrupts" );
622 DBG_ENTER( DbgInfo );
624 /* Initialize to known bad values */
625 bar2_reg = 0xdeadbeef;
626 mem_addr_bus = 0xdeadbeef;
628 /* Read the BAR2 register; this register contains the base address of the
629 memory region where the function event mask register lives */
630 pci_read_config_dword( pdev, PCI_BASE_ADDRESS_2, &bar2_reg );
631 mem_addr_bus = bar2_reg & PCI_BASE_ADDRESS_MEM_MASK;
633 /* Once the base address is obtained, remap the memory region to kernel
634 space so we can retrieve the register */
635 mem_addr_kern = ioremap( mem_addr_bus, 0x200 );
637 #ifdef HERMES25
638 #define REG_OFFSET 0x07F4
639 #else
640 #define REG_OFFSET 0x01F4
641 #endif // HERMES25
643 #define BIT15 0x8000
645 /* Retrieve the functional event mask register, enable interrupts by
646 setting Bit 15, and write back the value */
647 func_evt_mask_reg = *(u32 *)( mem_addr_kern + REG_OFFSET );
648 func_evt_mask_reg |= BIT15;
649 *(u32 *)( mem_addr_kern + REG_OFFSET ) = func_evt_mask_reg;
651 /* Once complete, unmap the region and exit */
652 iounmap( mem_addr_kern );
654 DBG_LEAVE( DbgInfo );
655 return;
656 } // wl_pci_enable_cardbus_interrupts
657 /*============================================================================*/
659 #ifdef ENABLE_DMA
660 /*******************************************************************************
661 * wl_pci_dma_alloc()
662 *******************************************************************************
664 * DESCRIPTION:
666 * Allocates all resources needed for PCI/CardBus DMA operation
668 * PARAMETERS:
670 * pdev - a pointer to the device's pci_dev structure
671 * lp - the device's private adapter structure
673 * RETURNS:
675 * 0 on success
676 * errno value otherwise
678 ******************************************************************************/
679 int wl_pci_dma_alloc( struct pci_dev *pdev, struct wl_private *lp )
681 int i;
682 int status = 0;
683 /*------------------------------------------------------------------------*/
685 DBG_FUNC( "wl_pci_dma_alloc" );
686 DBG_ENTER( DbgInfo );
688 // lp->dma.tx_rsc_ind = lp->dma.rx_rsc_ind = 0;
690 // /* Alloc for the Tx chain and its reclaim descriptor */
691 // for( i = 0; i < NUM_TX_DESC; i++ ) {
692 // status = wl_pci_dma_alloc_tx_packet( pdev, lp, &lp->dma.tx_packet[i] );
693 // if( status == 0 ) {
694 // DBG_PRINT( "lp->dma.tx_packet[%d] : 0x%p\n", i, lp->dma.tx_packet[i] );
695 // DBG_PRINT( "lp->dma.tx_packet[%d]->next_desc_addr : 0x%p\n", i, lp->dma.tx_packet[i]->next_desc_addr );
696 // lp->dma.tx_rsc_ind++;
697 // } else {
698 // DBG_ERROR( DbgInfo, "Could not alloc DMA Tx Packet\n" );
699 // break;
700 // }
701 // }
702 // if( status == 0 ) {
703 // status = wl_pci_dma_alloc_desc( pdev, lp, &lp->dma.tx_reclaim_desc );
704 // DBG_PRINT( "lp->dma.tx_reclaim_desc: 0x%p\n", lp->dma.tx_reclaim_desc );
705 // }
706 // /* Alloc for the Rx chain and its reclaim descriptor */
707 // if( status == 0 ) {
708 // for( i = 0; i < NUM_RX_DESC; i++ ) {
709 // status = wl_pci_dma_alloc_rx_packet( pdev, lp, &lp->dma.rx_packet[i] );
710 // if( status == 0 ) {
711 // DBG_PRINT( "lp->dma.rx_packet[%d] : 0x%p\n", i, lp->dma.rx_packet[i] );
712 // DBG_PRINT( "lp->dma.rx_packet[%d]->next_desc_addr : 0x%p\n", i, lp->dma.rx_packet[i]->next_desc_addr );
713 // lp->dma.rx_rsc_ind++;
714 // } else {
715 // DBG_ERROR( DbgInfo, "Could not alloc DMA Rx Packet\n" );
716 // break;
717 // }
718 // }
719 // }
720 // if( status == 0 ) {
721 // status = wl_pci_dma_alloc_desc( pdev, lp, &lp->dma.rx_reclaim_desc );
722 // DBG_PRINT( "lp->dma.rx_reclaim_desc: 0x%p\n", lp->dma.rx_reclaim_desc );
723 // }
724 // /* Store status, as host should not call HCF functions if this fails */
725 // lp->dma.status = status; //;?all useages of dma.status have been commented out
726 // DBG_LEAVE( DbgInfo );
727 return status;
728 } // wl_pci_dma_alloc
729 /*============================================================================*/
731 /*******************************************************************************
732 * wl_pci_dma_free()
733 *******************************************************************************
735 * DESCRIPTION:
737 * Deallocated all resources needed for PCI/CardBus DMA operation
739 * PARAMETERS:
741 * pdev - a pointer to the device's pci_dev structure
742 * lp - the device's private adapter structure
744 * RETURNS:
746 * 0 on success
747 * errno value otherwise
749 ******************************************************************************/
750 int wl_pci_dma_free( struct pci_dev *pdev, struct wl_private *lp )
752 int i;
753 int status = 0;
754 /*------------------------------------------------------------------------*/
756 DBG_FUNC( "wl_pci_dma_free" );
757 DBG_ENTER( DbgInfo );
759 /* Reclaim all Rx packets that were handed over to the HCF */
760 /* Do I need to do this? Before this free is called, I've already disabled
761 the port which will call wl_pci_dma_hcf_reclaim */
762 //if( lp->dma.status == 0 )
764 // wl_pci_dma_hcf_reclaim( lp );
767 /* Free everything needed for DMA Rx */
768 for( i = 0; i < NUM_RX_DESC; i++ ) {
769 if( lp->dma.rx_packet[i] ) {
770 status = wl_pci_dma_free_rx_packet( pdev, lp, &lp->dma.rx_packet[i] );
771 if( status != 0 ) {
772 DBG_WARNING( DbgInfo, "Problem freeing Rx packet\n" );
776 lp->dma.rx_rsc_ind = 0;
778 if( lp->dma.rx_reclaim_desc ) {
779 status = wl_pci_dma_free_desc( pdev, lp, &lp->dma.rx_reclaim_desc );
780 if( status != 0 ) {
781 DBG_WARNING( DbgInfo, "Problem freeing Rx reclaim descriptor\n" );
785 /* Free everything needed for DMA Tx */
786 for( i = 0; i < NUM_TX_DESC; i++ ) {
787 if( lp->dma.tx_packet[i] ) {
788 status = wl_pci_dma_free_tx_packet( pdev, lp, &lp->dma.tx_packet[i] );
789 if( status != 0 ) {
790 DBG_WARNING( DbgInfo, "Problem freeing Tx packet\n" );
794 lp->dma.tx_rsc_ind = 0;
796 if( lp->dma.tx_reclaim_desc ) {
797 status = wl_pci_dma_free_desc( pdev, lp, &lp->dma.tx_reclaim_desc );
798 if( status != 0 ) {
799 DBG_WARNING( DbgInfo, "Problem freeing Tx reclaim descriptor\n" );
803 DBG_LEAVE( DbgInfo );
804 return status;
805 } // wl_pci_dma_free
807 /*============================================================================*/
809 /*******************************************************************************
810 * wl_pci_dma_alloc_tx_packet()
811 *******************************************************************************
813 * DESCRIPTION:
815 * Allocates a single Tx packet, consisting of several descriptors and
816 * buffers. Data to transmit is first copied into the 'payload' buffer
817 * before being transmitted.
819 * PARAMETERS:
821 * pdev - a pointer to the device's pci_dev structure
822 * lp - the device's private adapter structure
823 * desc - a pointer which will reference the descriptor to be alloc'd.
825 * RETURNS:
827 * 0 on success
828 * errno value otherwise
830 ******************************************************************************/
831 int wl_pci_dma_alloc_tx_packet( struct pci_dev *pdev, struct wl_private *lp,
832 DESC_STRCT **desc )
834 // int status = 0;
835 // /*------------------------------------------------------------------------*/
837 // if( desc == NULL ) {
838 // status = -EFAULT;
839 // }
840 // if( status == 0 ) {
841 // status = wl_pci_dma_alloc_desc_and_buf( pdev, lp, desc,
842 // HCF_DMA_TX_BUF1_SIZE );
844 // if( status == 0 ) {
845 // status = wl_pci_dma_alloc_desc_and_buf( pdev, lp,
846 // &( (*desc)->next_desc_addr ),
847 // HCF_MAX_PACKET_SIZE );
848 // }
849 // }
850 // if( status == 0 ) {
851 // (*desc)->next_desc_phys_addr = (*desc)->next_desc_addr->desc_phys_addr;
852 // }
853 // return status;
854 } // wl_pci_dma_alloc_tx_packet
855 /*============================================================================*/
857 /*******************************************************************************
858 * wl_pci_dma_free_tx_packet()
859 *******************************************************************************
861 * DESCRIPTION:
863 * Frees a single Tx packet, described in the corresponding alloc function.
865 * PARAMETERS:
867 * pdev - a pointer to the device's pci_dev structure
868 * lp - the device's private adapter structure
869 * desc - a pointer which will reference the descriptor to be alloc'd.
871 * RETURNS:
873 * 0 on success
874 * errno value otherwise
876 ******************************************************************************/
877 int wl_pci_dma_free_tx_packet( struct pci_dev *pdev, struct wl_private *lp,
878 DESC_STRCT **desc )
880 int status = 0;
881 /*------------------------------------------------------------------------*/
883 if( *desc == NULL ) {
884 DBG_PRINT( "Null descriptor\n" );
885 status = -EFAULT;
887 //;?the "limited" NDIS strategy, assuming a frame consists ALWAYS out of 2
888 //descriptors, make this robust
889 if( status == 0 && (*desc)->next_desc_addr ) {
890 status = wl_pci_dma_free_desc_and_buf( pdev, lp, &(*desc)->next_desc_addr );
892 if( status == 0 ) {
893 status = wl_pci_dma_free_desc_and_buf( pdev, lp, desc );
895 return status;
896 } // wl_pci_dma_free_tx_packet
897 /*============================================================================*/
899 /*******************************************************************************
900 * wl_pci_dma_alloc_rx_packet()
901 *******************************************************************************
903 * DESCRIPTION:
905 * Allocates a single Rx packet, consisting of two descriptors and one
906 * contiguous buffer. THe buffer starts with the hermes-specific header.
907 * One descriptor points at the start, the other at offset 0x3a of the
908 * buffer.
910 * PARAMETERS:
912 * pdev - a pointer to the device's pci_dev structure
913 * lp - the device's private adapter structure
914 * desc - a pointer which will reference the descriptor to be alloc'd.
916 * RETURNS:
918 * 0 on success
919 * errno value otherwise
921 ******************************************************************************/
922 int wl_pci_dma_alloc_rx_packet( struct pci_dev *pdev, struct wl_private *lp,
923 DESC_STRCT **desc )
925 int status = 0;
926 DESC_STRCT *p;
927 /*------------------------------------------------------------------------*/
929 // if( desc == NULL ) {
930 // status = -EFAULT;
931 // }
932 // //;?the "limited" NDIS strategy, assuming a frame consists ALWAYS out of 2
933 // //descriptors, make this robust
934 // if( status == 0 ) {
935 // status = wl_pci_dma_alloc_desc( pdev, lp, desc );
936 // }
937 // if( status == 0 ) {
938 // status = wl_pci_dma_alloc_buf( pdev, lp, *desc, HCF_MAX_PACKET_SIZE );
939 // }
940 // if( status == 0 ) {
941 // status = wl_pci_dma_alloc_desc( pdev, lp, &p );
942 // }
943 // if( status == 0 ) {
944 // /* Size of 1st descriptor becomes 0x3a bytes */
945 // SET_BUF_SIZE( *desc, HCF_DMA_RX_BUF1_SIZE );
947 // /* Make 2nd descriptor point at offset 0x3a of the buffer */
948 // SET_BUF_SIZE( p, ( HCF_MAX_PACKET_SIZE - HCF_DMA_RX_BUF1_SIZE ));
949 // p->buf_addr = (*desc)->buf_addr + HCF_DMA_RX_BUF1_SIZE;
950 // p->buf_phys_addr = (*desc)->buf_phys_addr + HCF_DMA_RX_BUF1_SIZE;
951 // p->next_desc_addr = NULL;
953 // /* Chain 2nd descriptor to 1st descriptor */
954 // (*desc)->next_desc_addr = p;
955 // (*desc)->next_desc_phys_addr = p->desc_phys_addr;
956 // }
958 return status;
959 } // wl_pci_dma_alloc_rx_packet
960 /*============================================================================*/
962 /*******************************************************************************
963 * wl_pci_dma_free_rx_packet()
964 *******************************************************************************
966 * DESCRIPTION:
968 * Frees a single Rx packet, described in the corresponding alloc function.
970 * PARAMETERS:
972 * pdev - a pointer to the device's pci_dev structure
973 * lp - the device's private adapter structure
974 * desc - a pointer which will reference the descriptor to be alloc'd.
976 * RETURNS:
978 * 0 on success
979 * errno value otherwise
981 ******************************************************************************/
982 int wl_pci_dma_free_rx_packet( struct pci_dev *pdev, struct wl_private *lp,
983 DESC_STRCT **desc )
985 int status = 0;
986 DESC_STRCT *p;
987 /*------------------------------------------------------------------------*/
989 if( *desc == NULL ) {
990 status = -EFAULT;
992 if( status == 0 ) {
993 p = (*desc)->next_desc_addr;
995 /* Free the 2nd descriptor */
996 if( p != NULL ) {
997 p->buf_addr = NULL;
998 p->buf_phys_addr = 0;
1000 status = wl_pci_dma_free_desc( pdev, lp, &p );
1004 /* Free the buffer and 1st descriptor */
1005 if( status == 0 ) {
1006 SET_BUF_SIZE( *desc, HCF_MAX_PACKET_SIZE );
1007 status = wl_pci_dma_free_desc_and_buf( pdev, lp, desc );
1009 return status;
1010 } // wl_pci_dma_free_rx_packet
1011 /*============================================================================*/
1013 /*******************************************************************************
1014 * wl_pci_dma_alloc_desc_and_buf()
1015 *******************************************************************************
1017 * DESCRIPTION:
1019 * Allocates a DMA descriptor and buffer, and associates them with one
1020 * another.
1022 * PARAMETERS:
1024 * pdev - a pointer to the device's pci_dev structure
1025 * lp - the device's private adapter structure
1026 * desc - a pointer which will reference the descriptor to be alloc'd
1028 * RETURNS:
1030 * 0 on success
1031 * errno value otherwise
1033 ******************************************************************************/
1034 int wl_pci_dma_alloc_desc_and_buf( struct pci_dev *pdev, struct wl_private *lp,
1035 DESC_STRCT **desc, int size )
1037 int status = 0;
1038 /*------------------------------------------------------------------------*/
1040 // if( desc == NULL ) {
1041 // status = -EFAULT;
1042 // }
1043 // if( status == 0 ) {
1044 // status = wl_pci_dma_alloc_desc( pdev, lp, desc );
1046 // if( status == 0 ) {
1047 // status = wl_pci_dma_alloc_buf( pdev, lp, *desc, size );
1048 // }
1049 // }
1050 return status;
1051 } // wl_pci_dma_alloc_desc_and_buf
1052 /*============================================================================*/
1054 /*******************************************************************************
1055 * wl_pci_dma_free_desc_and_buf()
1056 *******************************************************************************
1058 * DESCRIPTION:
1060 * Frees a DMA descriptor and associated buffer.
1062 * PARAMETERS:
1064 * pdev - a pointer to the device's pci_dev structure
1065 * lp - the device's private adapter structure
1066 * desc - a pointer which will reference the descriptor to be alloc'd
1068 * RETURNS:
1070 * 0 on success
1071 * errno value otherwise
1073 ******************************************************************************/
1074 int wl_pci_dma_free_desc_and_buf( struct pci_dev *pdev, struct wl_private *lp,
1075 DESC_STRCT **desc )
1077 int status = 0;
1078 /*------------------------------------------------------------------------*/
1080 if( desc == NULL ) {
1081 status = -EFAULT;
1083 if( status == 0 && *desc == NULL ) {
1084 status = -EFAULT;
1086 if( status == 0 ) {
1087 status = wl_pci_dma_free_buf( pdev, lp, *desc );
1089 if( status == 0 ) {
1090 status = wl_pci_dma_free_desc( pdev, lp, desc );
1093 return status;
1094 } // wl_pci_dma_free_desc_and_buf
1095 /*============================================================================*/
1097 /*******************************************************************************
1098 * wl_pci_dma_alloc_desc()
1099 *******************************************************************************
1101 * DESCRIPTION:
1103 * Allocates one DMA descriptor in cache coherent memory.
1105 * PARAMETERS:
1107 * pdev - a pointer to the device's pci_dev structure
1108 * lp - the device's private adapter structure
1110 * RETURNS:
1112 * 0 on success
1113 * errno value otherwise
1115 ******************************************************************************/
1116 int wl_pci_dma_alloc_desc( struct pci_dev *pdev, struct wl_private *lp,
1117 DESC_STRCT **desc )
1119 // int status = 0;
1120 // dma_addr_t pa;
1121 // /*------------------------------------------------------------------------*/
1123 // DBG_FUNC( "wl_pci_dma_alloc_desc" );
1124 // DBG_ENTER( DbgInfo );
1126 // if( desc == NULL ) {
1127 // status = -EFAULT;
1128 // }
1129 // if( status == 0 ) {
1130 // *desc = pci_alloc_consistent( pdev, sizeof( DESC_STRCT ), &pa );
1131 // }
1132 // if( *desc == NULL ) {
1133 // DBG_ERROR( DbgInfo, "pci_alloc_consistent() failed\n" );
1134 // status = -ENOMEM;
1135 // } else {
1136 // memset( *desc, 0, sizeof( DESC_STRCT ));
1137 // (*desc)->desc_phys_addr = cpu_to_le32( pa );
1138 // }
1139 // DBG_LEAVE( DbgInfo );
1140 // return status;
1141 } // wl_pci_dma_alloc_desc
1142 /*============================================================================*/
1144 /*******************************************************************************
1145 * wl_pci_dma_free_desc()
1146 *******************************************************************************
1148 * DESCRIPTION:
1150 * Frees one DMA descriptor in cache coherent memory.
1152 * PARAMETERS:
1154 * pdev - a pointer to the device's pci_dev structure
1155 * lp - the device's private adapter structure
1157 * RETURNS:
1159 * 0 on success
1160 * errno value otherwise
1162 ******************************************************************************/
1163 int wl_pci_dma_free_desc( struct pci_dev *pdev, struct wl_private *lp,
1164 DESC_STRCT **desc )
1166 int status = 0;
1167 /*------------------------------------------------------------------------*/
1169 if( *desc == NULL ) {
1170 status = -EFAULT;
1172 if( status == 0 ) {
1173 pci_free_consistent( pdev, sizeof( DESC_STRCT ), *desc,
1174 (*desc)->desc_phys_addr );
1176 *desc = NULL;
1177 return status;
1178 } // wl_pci_dma_free_desc
1179 /*============================================================================*/
1181 /*******************************************************************************
1182 * wl_pci_dma_alloc_buf()
1183 *******************************************************************************
1185 * DESCRIPTION:
1187 * Allocates one DMA buffer in cache coherent memory, and associates a DMA
1188 * descriptor with this buffer.
1190 * PARAMETERS:
1192 * pdev - a pointer to the device's pci_dev structure
1193 * lp - the device's private adapter structure
1195 * RETURNS:
1197 * 0 on success
1198 * errno value otherwise
1200 ******************************************************************************/
1201 int wl_pci_dma_alloc_buf( struct pci_dev *pdev, struct wl_private *lp,
1202 DESC_STRCT *desc, int size )
1204 int status = 0;
1205 dma_addr_t pa;
1206 /*------------------------------------------------------------------------*/
1208 // DBG_FUNC( "wl_pci_dma_alloc_buf" );
1209 // DBG_ENTER( DbgInfo );
1211 // if( desc == NULL ) {
1212 // status = -EFAULT;
1213 // }
1214 // if( status == 0 && desc->buf_addr != NULL ) {
1215 // status = -EFAULT;
1216 // }
1217 // if( status == 0 ) {
1218 // desc->buf_addr = pci_alloc_consistent( pdev, size, &pa );
1219 // }
1220 // if( desc->buf_addr == NULL ) {
1221 // DBG_ERROR( DbgInfo, "pci_alloc_consistent() failed\n" );
1222 // status = -ENOMEM;
1223 // } else {
1224 // desc->buf_phys_addr = cpu_to_le32( pa );
1225 // SET_BUF_SIZE( desc, size );
1226 // }
1227 // DBG_LEAVE( DbgInfo );
1228 return status;
1229 } // wl_pci_dma_alloc_buf
1230 /*============================================================================*/
1232 /*******************************************************************************
1233 * wl_pci_dma_free_buf()
1234 *******************************************************************************
1236 * DESCRIPTION:
1238 * Allocates one DMA buffer in cache coherent memory, and associates a DMA
1239 * descriptor with this buffer.
1241 * PARAMETERS:
1243 * pdev - a pointer to the device's pci_dev structure
1244 * lp - the device's private adapter structure
1246 * RETURNS:
1248 * 0 on success
1249 * errno value otherwise
1251 ******************************************************************************/
1252 int wl_pci_dma_free_buf( struct pci_dev *pdev, struct wl_private *lp,
1253 DESC_STRCT *desc )
1255 int status = 0;
1256 /*------------------------------------------------------------------------*/
1258 if( desc == NULL ) {
1259 status = -EFAULT;
1261 if( status == 0 && desc->buf_addr == NULL ) {
1262 status = -EFAULT;
1264 if( status == 0 ) {
1265 pci_free_consistent( pdev, GET_BUF_SIZE( desc ), desc->buf_addr,
1266 desc->buf_phys_addr );
1268 desc->buf_addr = 0;
1269 desc->buf_phys_addr = 0;
1270 SET_BUF_SIZE( desc, 0 );
1272 return status;
1273 } // wl_pci_dma_free_buf
1274 /*============================================================================*/
1276 /*******************************************************************************
1277 * wl_pci_dma_hcf_supply()
1278 *******************************************************************************
1280 * DESCRIPTION:
1282 * Supply HCF with DMA-related resources. These consist of:
1283 * - buffers and descriptors for receive purposes
1284 * - one 'reclaim' descriptor for the transmit path, used to fulfill a
1285 * certain H25 DMA engine requirement
1286 * - one 'reclaim' descriptor for the receive path, used to fulfill a
1287 * certain H25 DMA engine requirement
1289 * This function is called at start-of-day or at re-initialization.
1291 * PARAMETERS:
1293 * lp - the device's private adapter structure
1295 * RETURNS:
1297 * 0 on success
1298 * errno value otherwise
1300 ******************************************************************************/
1301 void wl_pci_dma_hcf_supply( struct wl_private *lp )
1303 int i;
1304 /*------------------------------------------------------------------------*/
1306 DBG_FUNC( "wl_pci_dma_hcf_supply" );
1307 DBG_ENTER( DbgInfo );
1309 //if( lp->dma.status == 0 );
1311 /* Hand over the Rx/Tx reclaim descriptors to the HCF */
1312 if( lp->dma.tx_reclaim_desc ) {
1313 DBG_PRINT( "lp->dma.tx_reclaim_desc: 0x%p\n", lp->dma.tx_reclaim_desc );
1314 hcf_dma_tx_put( &lp->hcfCtx, lp->dma.tx_reclaim_desc, 0 );
1315 lp->dma.tx_reclaim_desc = NULL;
1316 DBG_PRINT( "lp->dma.tx_reclaim_desc: 0x%p\n", lp->dma.tx_reclaim_desc );
1318 if( lp->dma.rx_reclaim_desc ) {
1319 DBG_PRINT( "lp->dma.rx_reclaim_desc: 0x%p\n", lp->dma.rx_reclaim_desc );
1320 hcf_dma_rx_put( &lp->hcfCtx, lp->dma.rx_reclaim_desc );
1321 lp->dma.rx_reclaim_desc = NULL;
1322 DBG_PRINT( "lp->dma.rx_reclaim_desc: 0x%p\n", lp->dma.rx_reclaim_desc );
1324 /* Hand over the Rx descriptor chain to the HCF */
1325 for( i = 0; i < NUM_RX_DESC; i++ ) {
1326 DBG_PRINT( "lp->dma.rx_packet[%d]: 0x%p\n", i, lp->dma.rx_packet[i] );
1327 hcf_dma_rx_put( &lp->hcfCtx, lp->dma.rx_packet[i] );
1328 lp->dma.rx_packet[i] = NULL;
1329 DBG_PRINT( "lp->dma.rx_packet[%d]: 0x%p\n", i, lp->dma.rx_packet[i] );
1333 DBG_LEAVE( DbgInfo );
1334 return;
1335 } // wl_pci_dma_hcf_supply
1336 /*============================================================================*/
1338 /*******************************************************************************
1339 * wl_pci_dma_hcf_reclaim()
1340 *******************************************************************************
1342 * DESCRIPTION:
1344 * Return DMA-related resources from the HCF. These consist of:
1345 * - buffers and descriptors for receive purposes
1346 * - buffers and descriptors for transmit purposes
1347 * - one 'reclaim' descriptor for the transmit path, used to fulfill a
1348 * certain H25 DMA engine requirement
1349 * - one 'reclaim' descriptor for the receive path, used to fulfill a
1350 * certain H25 DMA engine requirement
1352 * This function is called at end-of-day or at re-initialization.
1354 * PARAMETERS:
1356 * lp - the device's private adapter structure
1358 * RETURNS:
1360 * 0 on success
1361 * errno value otherwise
1363 ******************************************************************************/
1364 void wl_pci_dma_hcf_reclaim( struct wl_private *lp )
1366 int i;
1367 /*------------------------------------------------------------------------*/
1369 DBG_FUNC( "wl_pci_dma_hcf_reclaim" );
1370 DBG_ENTER( DbgInfo );
1372 wl_pci_dma_hcf_reclaim_rx( lp );
1373 for( i = 0; i < NUM_RX_DESC; i++ ) {
1374 DBG_PRINT( "rx_packet[%d] 0x%p\n", i, lp->dma.rx_packet[i] );
1375 // if( lp->dma.rx_packet[i] == NULL ) {
1376 // DBG_PRINT( "wl_pci_dma_hcf_reclaim: rx_packet[%d] NULL\n", i );
1377 // }
1380 wl_pci_dma_hcf_reclaim_tx( lp );
1381 for( i = 0; i < NUM_TX_DESC; i++ ) {
1382 DBG_PRINT( "tx_packet[%d] 0x%p\n", i, lp->dma.tx_packet[i] );
1383 // if( lp->dma.tx_packet[i] == NULL ) {
1384 // DBG_PRINT( "wl_pci_dma_hcf_reclaim: tx_packet[%d] NULL\n", i );
1385 // }
1388 DBG_LEAVE( DbgInfo );
1389 return;
1390 } // wl_pci_dma_hcf_reclaim
1391 /*============================================================================*/
1393 /*******************************************************************************
1394 * wl_pci_dma_hcf_reclaim_rx()
1395 *******************************************************************************
1397 * DESCRIPTION:
1399 * Reclaim Rx packets that have already been processed by the HCF.
1401 * PARAMETERS:
1403 * lp - the device's private adapter structure
1405 * RETURNS:
1407 * 0 on success
1408 * errno value otherwise
1410 ******************************************************************************/
1411 void wl_pci_dma_hcf_reclaim_rx( struct wl_private *lp )
1413 int i;
1414 DESC_STRCT *p;
1415 /*------------------------------------------------------------------------*/
1417 DBG_FUNC( "wl_pci_dma_hcf_reclaim_rx" );
1418 DBG_ENTER( DbgInfo );
1420 //if( lp->dma.status == 0 )
1422 while ( ( p = hcf_dma_rx_get( &lp->hcfCtx ) ) != NULL ) {
1423 if( p && p->buf_addr == NULL ) {
1424 /* A reclaim descriptor is being given back by the HCF. Reclaim
1425 descriptors have a NULL buf_addr */
1426 lp->dma.rx_reclaim_desc = p;
1427 DBG_PRINT( "reclaim_descriptor: 0x%p\n", p );
1428 continue;
1430 for( i = 0; i < NUM_RX_DESC; i++ ) {
1431 if( lp->dma.rx_packet[i] == NULL ) {
1432 break;
1435 /* An Rx buffer descriptor is being given back by the HCF */
1436 lp->dma.rx_packet[i] = p;
1437 lp->dma.rx_rsc_ind++;
1438 DBG_PRINT( "rx_packet[%d] 0x%p\n", i, lp->dma.rx_packet[i] );
1441 DBG_LEAVE( DbgInfo );
1442 } // wl_pci_dma_hcf_reclaim_rx
1443 /*============================================================================*/
1445 /*******************************************************************************
1446 * wl_pci_dma_get_tx_packet()
1447 *******************************************************************************
1449 * DESCRIPTION:
1451 * Obtains a Tx descriptor from the chain to use for Tx.
1453 * PARAMETERS:
1455 * lp - a pointer to the device's wl_private structure.
1457 * RETURNS:
1459 * A pointer to the retrieved descriptor
1461 ******************************************************************************/
1462 DESC_STRCT * wl_pci_dma_get_tx_packet( struct wl_private *lp )
1464 int i;
1465 DESC_STRCT *desc = NULL;
1466 /*------------------------------------------------------------------------*/
1468 for( i = 0; i < NUM_TX_DESC; i++ ) {
1469 if( lp->dma.tx_packet[i] ) {
1470 break;
1474 if( i != NUM_TX_DESC ) {
1475 desc = lp->dma.tx_packet[i];
1477 lp->dma.tx_packet[i] = NULL;
1478 lp->dma.tx_rsc_ind--;
1480 memset( desc->buf_addr, 0, HCF_DMA_TX_BUF1_SIZE );
1483 return desc;
1484 } // wl_pci_dma_get_tx_packet
1485 /*============================================================================*/
1487 /*******************************************************************************
1488 * wl_pci_dma_put_tx_packet()
1489 *******************************************************************************
1491 * DESCRIPTION:
1493 * Returns a Tx descriptor to the chain.
1495 * PARAMETERS:
1497 * lp - a pointer to the device's wl_private structure.
1498 * desc - a pointer to the descriptor to return.
1500 * RETURNS:
1502 * N/A
1504 ******************************************************************************/
1505 void wl_pci_dma_put_tx_packet( struct wl_private *lp, DESC_STRCT *desc )
1507 int i;
1508 /*------------------------------------------------------------------------*/
1510 for( i = 0; i < NUM_TX_DESC; i++ ) {
1511 if( lp->dma.tx_packet[i] == NULL ) {
1512 break;
1516 if( i != NUM_TX_DESC ) {
1517 lp->dma.tx_packet[i] = desc;
1518 lp->dma.tx_rsc_ind++;
1520 } // wl_pci_dma_put_tx_packet
1521 /*============================================================================*/
1523 /*******************************************************************************
1524 * wl_pci_dma_hcf_reclaim_tx()
1525 *******************************************************************************
1527 * DESCRIPTION:
1529 * Reclaim Tx packets that have either been processed by the HCF due to a
1530 * port disable or a Tx completion.
1532 * PARAMETERS:
1534 * lp - the device's private adapter structure
1536 * RETURNS:
1538 * 0 on success
1539 * errno value otherwise
1541 ******************************************************************************/
1542 void wl_pci_dma_hcf_reclaim_tx( struct wl_private *lp )
1544 int i;
1545 DESC_STRCT *p;
1546 /*------------------------------------------------------------------------*/
1548 DBG_FUNC( "wl_pci_dma_hcf_reclaim_tx" );
1549 DBG_ENTER( DbgInfo );
1551 //if( lp->dma.status == 0 )
1553 while ( ( p = hcf_dma_tx_get( &lp->hcfCtx ) ) != NULL ) {
1555 if( p != NULL && p->buf_addr == NULL ) {
1556 /* A Reclaim descriptor is being given back by the HCF. Reclaim
1557 descriptors have a NULL buf_addr */
1558 lp->dma.tx_reclaim_desc = p;
1559 DBG_PRINT( "reclaim_descriptor: 0x%p\n", p );
1560 continue;
1562 for( i = 0; i < NUM_TX_DESC; i++ ) {
1563 if( lp->dma.tx_packet[i] == NULL ) {
1564 break;
1567 /* An Rx buffer descriptor is being given back by the HCF */
1568 lp->dma.tx_packet[i] = p;
1569 lp->dma.tx_rsc_ind++;
1570 DBG_PRINT( "tx_packet[%d] 0x%p\n", i, lp->dma.tx_packet[i] );
1574 if( lp->netif_queue_on == FALSE ) {
1575 netif_wake_queue( lp->dev );
1576 WL_WDS_NETIF_WAKE_QUEUE( lp );
1577 lp->netif_queue_on = TRUE;
1579 DBG_LEAVE( DbgInfo );
1580 return;
1581 } // wl_pci_dma_hcf_reclaim_tx
1582 /*============================================================================*/
1583 #endif // ENABLE_DMA