1 /*******************************************************************************
3 * Wireless device driver for Linux (wlags49).
5 * Copyright (c) 1998-2003 Agere Systems Inc.
9 * Initially developed by TriplePoint, Inc.
10 * http://www.triplepoint.com
12 *------------------------------------------------------------------------------
14 * This file contains processing and initialization specific to PCI/miniPCI
17 *------------------------------------------------------------------------------
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
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.
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
60 ******************************************************************************/
64 /*******************************************************************************
65 * VERSION CONTROL INFORMATION
66 *******************************************************************************
69 * $Date: 2004/08/06 11:25:37 $
71 * $Source: /usr/local/cvs/wl_lkm/wireless/wl_pci.c,v $
73 ******************************************************************************/
77 /*******************************************************************************
79 ******************************************************************************/
80 #include <wireless/wl_version.h>
82 #include <linux/module.h>
83 #include <linux/kernel.h>
84 #include <linux/errno.h>
85 #include <linux/pci.h>
86 #include <linux/init.h>
87 #include <linux/sched.h>
88 #include <linux/ptrace.h>
89 #include <linux/slab.h>
90 #include <linux/ctype.h>
91 #include <linux/string.h>
92 //#include <linux/timer.h>
93 #include <linux/interrupt.h>
95 #include <linux/delay.h>
96 #include <asm/system.h>
99 #include <asm/system.h>
100 #include <asm/bitops.h>
101 #include <asm/uaccess.h>
103 #include <linux/ethtool.h>
104 #include <linux/netdevice.h>
105 #include <linux/etherdevice.h>
106 #include <linux/skbuff.h>
107 #include <linux/if_arp.h>
108 #include <linux/ioport.h>
110 #include <hcf/debug.h>
116 #include <wireless/wl_if.h>
117 #include <wireless/wl_internal.h>
118 #include <wireless/wl_util.h>
119 #include <wireless/wl_main.h>
120 #include <wireless/wl_netdev.h>
121 #include <wireless/wl_pci.h>
124 /*******************************************************************************
126 ******************************************************************************/
128 extern dbg_info_t *DbgInfo;
131 /* define the PCI device Table Cardname and id tables */
132 enum hermes_pci_versions {
133 CH_Agere_Systems_Mini_PCI_V1 = 0,
136 static struct pci_device_id wl_pci_tbl[] __devinitdata = {
137 { WL_LKM_PCI_VENDOR_ID, WL_LKM_PCI_DEVICE_ID_0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_Agere_Systems_Mini_PCI_V1 },
138 { WL_LKM_PCI_VENDOR_ID, WL_LKM_PCI_DEVICE_ID_1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_Agere_Systems_Mini_PCI_V1 },
139 { WL_LKM_PCI_VENDOR_ID, WL_LKM_PCI_DEVICE_ID_2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_Agere_Systems_Mini_PCI_V1 },
140 { } /* Terminating entry */
143 MODULE_DEVICE_TABLE(pci, wl_pci_tbl);
145 /*******************************************************************************
146 * function prototypes
147 ******************************************************************************/
148 int __devinit wl_pci_probe( struct pci_dev *pdev,
149 const struct pci_device_id *ent );
150 void __devexit wl_pci_remove(struct pci_dev *pdev);
151 int wl_pci_setup( struct pci_dev *pdev );
152 void wl_pci_enable_cardbus_interrupts( struct pci_dev *pdev );
155 int wl_pci_dma_alloc( struct pci_dev *pdev, struct wl_private *lp );
156 int wl_pci_dma_free( struct pci_dev *pdev, struct wl_private *lp );
157 int wl_pci_dma_alloc_tx_packet( struct pci_dev *pdev, struct wl_private *lp,
159 int wl_pci_dma_free_tx_packet( struct pci_dev *pdev, struct wl_private *lp,
161 int wl_pci_dma_alloc_rx_packet( struct pci_dev *pdev, struct wl_private *lp,
163 int wl_pci_dma_free_rx_packet( struct pci_dev *pdev, struct wl_private *lp,
165 int wl_pci_dma_alloc_desc_and_buf( struct pci_dev *pdev, struct wl_private *lp,
166 DESC_STRCT **desc, int size );
167 int wl_pci_dma_free_desc_and_buf( struct pci_dev *pdev, struct wl_private *lp,
169 int wl_pci_dma_alloc_desc( struct pci_dev *pdev, struct wl_private *lp,
171 int wl_pci_dma_free_desc( struct pci_dev *pdev, struct wl_private *lp,
173 int wl_pci_dma_alloc_buf( struct pci_dev *pdev, struct wl_private *lp,
174 DESC_STRCT *desc, int size );
175 int wl_pci_dma_free_buf( struct pci_dev *pdev, struct wl_private *lp,
178 void wl_pci_dma_hcf_reclaim_rx( struct wl_private *lp );
181 /*******************************************************************************
182 * PCI module function registration
183 ******************************************************************************/
184 static struct pci_driver wl_driver =
187 id_table: wl_pci_tbl,
189 remove: __devexit_p(wl_pci_remove),
194 /*******************************************************************************
195 * wl_adapter_init_module()
196 *******************************************************************************
200 * Called by init_module() to perform PCI-specific driver initialization.
210 ******************************************************************************/
211 int wl_adapter_init_module( void )
214 /*------------------------------------------------------------------------*/
216 DBG_FUNC( "wl_adapter_init_module()" );
217 DBG_ENTER( DbgInfo );
218 DBG_TRACE( DbgInfo, "wl_adapter_init_module() -- PCI\n" );
220 result = pci_register_driver( &wl_driver ); //;?replace with pci_module_init, Rubini pg 490
221 //;? why not do something with the result
223 DBG_LEAVE( DbgInfo );
225 } // wl_adapter_init_module
226 /*============================================================================*/
228 /*******************************************************************************
229 * wl_adapter_cleanup_module()
230 *******************************************************************************
234 * Called by cleanup_module() to perform PCI-specific driver cleanup.
244 ******************************************************************************/
245 void wl_adapter_cleanup_module( void )
247 //;?how comes wl_adapter_cleanup_module is located in a seemingly pci specific module
248 DBG_FUNC( "wl_adapter_cleanup_module" );
249 DBG_ENTER( DbgInfo );
251 //;?DBG_TRACE below feels like nearly redundant in the light of DBG_ENTER above
252 DBG_TRACE( DbgInfo, "wl_adapter_cleanup_module() -- PCI\n" );
254 pci_unregister_driver( &wl_driver );
256 DBG_LEAVE( DbgInfo );
258 } // wl_adapter_cleanup_module
259 /*============================================================================*/
261 /*******************************************************************************
262 * wl_adapter_insert()
263 *******************************************************************************
267 * Called by wl_pci_probe() to continue the process of device insertion.
271 * dev - a pointer to the device's net_device structure
277 ******************************************************************************/
278 int wl_adapter_insert( struct net_device *dev )
281 /*------------------------------------------------------------------------*/
283 DBG_FUNC( "wl_adapter_insert" );
284 DBG_ENTER( DbgInfo );
286 DBG_TRACE( DbgInfo, "wl_adapter_insert() -- PCI\n" );
289 DBG_ERROR( DbgInfo, "net_device pointer is NULL!!!\n" );
290 } else if( dev->priv == NULL ) {
291 DBG_ERROR( DbgInfo, "wl_private pointer is NULL!!!\n" );
292 } else if( wl_insert( dev ) ) { /* Perform remaining device initialization */
295 DBG_TRACE( DbgInfo, "wl_insert() FAILED\n" );
297 DBG_LEAVE( DbgInfo );
299 } // wl_adapter_insert
300 /*============================================================================*/
302 /*******************************************************************************
304 *******************************************************************************
312 * dev - a pointer to the device's net_device structure
318 ******************************************************************************/
319 int wl_adapter_open( struct net_device *dev )
322 int hcf_status = HCF_SUCCESS;
323 /*------------------------------------------------------------------------*/
325 DBG_FUNC( "wl_adapter_open" );
326 DBG_ENTER( DbgInfo );
328 DBG_TRACE( DbgInfo, "wl_adapter_open() -- PCI\n" );
330 hcf_status = wl_open( dev );
332 if( hcf_status != HCF_SUCCESS ) {
336 DBG_LEAVE( DbgInfo );
339 /*============================================================================*/
341 /*******************************************************************************
343 *******************************************************************************
351 * dev - a pointer to the device's net_device structure
357 ******************************************************************************/
358 int wl_adapter_close( struct net_device *dev )
360 DBG_FUNC( "wl_adapter_close" );
361 DBG_ENTER( DbgInfo );
363 DBG_TRACE( DbgInfo, "wl_adapter_close() -- PCI\n" );
364 DBG_TRACE( DbgInfo, "%s: Shutting down adapter.\n", dev->name );
368 DBG_LEAVE( DbgInfo );
370 } // wl_adapter_close
371 /*============================================================================*/
373 /*******************************************************************************
374 * wl_adapter_is_open()
375 *******************************************************************************
379 * Check whether this device is open. Returns
383 * dev - a pointer to the device's net_device structure
387 * nonzero if device is open.
389 ******************************************************************************/
390 int wl_adapter_is_open( struct net_device *dev )
392 /* This function is used in PCMCIA to check the status of the 'open' field
393 in the dev_link_t structure associated with a network device. There
394 doesn't seem to be an analog to this for PCI, and checking the status
395 contained in the net_device structure doesn't have the same effect.
396 For now, return TRUE, but find out if this is necessary for PCI. */
399 } // wl_adapter_is_open
400 /*============================================================================*/
402 /*******************************************************************************
404 *******************************************************************************
408 * Registered in the pci_driver structure, this function is called when the
409 * PCI subsystem finds a new PCI device which matches the infomation contained
410 * in the pci_device_id table.
414 * pdev - a pointer to the device's pci_dev structure
415 * ent - this device's entry in the pci_device_id table
420 * errno value otherwise
422 ******************************************************************************/
423 int __devinit wl_pci_probe( struct pci_dev *pdev,
424 const struct pci_device_id *ent )
427 /*------------------------------------------------------------------------*/
429 DBG_FUNC( "wl_pci_probe" );
430 DBG_ENTER( DbgInfo );
431 DBG_PRINT( "%s\n", VERSION_INFO );
433 result = wl_pci_setup( pdev );
435 DBG_LEAVE( DbgInfo );
439 /*============================================================================*/
441 /*******************************************************************************
443 *******************************************************************************
447 * Registered in the pci_driver structure, this function is called when the
448 * PCI subsystem detects that a PCI device which matches the infomation
449 * contained in the pci_device_id table has been removed.
453 * pdev - a pointer to the device's pci_dev structure
459 ******************************************************************************/
460 void __devexit wl_pci_remove(struct pci_dev *pdev)
462 struct net_device *dev = NULL;
463 /*------------------------------------------------------------------------*/
465 DBG_FUNC( "wl_pci_remove" );
466 DBG_ENTER( DbgInfo );
468 /* Make sure the pci_dev pointer passed in is valid */
470 DBG_ERROR( DbgInfo, "PCI subsys passed in an invalid pci_dev pointer\n" );
474 dev = (struct net_device *)pci_get_drvdata( pdev );
476 DBG_ERROR( DbgInfo, "Could not retrieve net_device structure\n" );
480 /* Perform device cleanup */
482 free_irq( dev->irq, dev );
485 wl_pci_dma_free( pdev, (struct wl_private *)dev->priv );
488 wl_device_dealloc( dev );
490 DBG_LEAVE( DbgInfo );
493 /*============================================================================*/
495 /*******************************************************************************
497 *******************************************************************************
501 * Called by wl_pci_probe() to begin a device's initialization process.
505 * pdev - a pointer to the device's pci_dev structure
510 * errno value otherwise
512 ******************************************************************************/
513 int wl_pci_setup( struct pci_dev *pdev )
516 struct net_device *dev = NULL;
517 struct wl_private *lp = NULL;
518 /*------------------------------------------------------------------------*/
520 DBG_FUNC( "wl_pci_setup" );
521 DBG_ENTER( DbgInfo );
523 /* Make sure the pci_dev pointer passed in is valid */
525 DBG_ERROR( DbgInfo, "PCI subsys passed in an invalid pci_dev pointer\n" );
529 result = pci_enable_device( pdev );
531 DBG_ERROR( DbgInfo, "pci_enable_device() failed\n" );
532 DBG_LEAVE( DbgInfo );
536 /* We found our device! Let's register it with the system */
537 DBG_TRACE( DbgInfo, "Found our device, now registering\n" );
538 dev = wl_device_alloc( );
540 DBG_ERROR( DbgInfo, "Could not register device!!!\n" );
541 DBG_LEAVE( DbgInfo );
545 /* Make sure that space was allocated for our private adapter struct */
546 if( dev->priv == NULL ) {
547 DBG_ERROR( DbgInfo, "Private adapter struct was not allocated!!!\n" );
548 DBG_LEAVE( DbgInfo );
553 /* Allocate DMA Descriptors */
554 if( wl_pci_dma_alloc( pdev, (struct wl_private *)dev->priv ) < 0 ) {
555 DBG_ERROR( DbgInfo, "Could not allocate DMA descriptor memory!!!\n" );
556 DBG_LEAVE( DbgInfo );
561 /* Register our private adapter structure with PCI */
562 pci_set_drvdata( pdev, dev );
564 /* Fill out bus specific information in the net_device struct */
565 dev->irq = pdev->irq;
566 SET_MODULE_OWNER( dev );
568 DBG_TRACE( DbgInfo, "Device Base Address: %#03lx\n", pdev->resource[0].start );
569 dev->base_addr = pdev->resource[0].start;
571 /* Initialize our device here */
572 if( !wl_adapter_insert( dev )) {
573 DBG_ERROR( DbgInfo, "wl_adapter_insert() FAILED!!!\n" );
574 wl_device_dealloc( dev );
575 DBG_LEAVE( DbgInfo );
579 /* Register our ISR */
580 DBG_TRACE( DbgInfo, "Registering ISR...\n" );
582 result = request_irq(dev->irq, wl_isr, SA_SHIRQ, dev->name, dev);
584 DBG_WARNING( DbgInfo, "Could not register ISR!!!\n" );
585 DBG_LEAVE( DbgInfo );
589 /* Make sure interrupts are enabled properly for CardBus */
590 lp = (struct wl_private *)dev->priv;
592 if( lp->hcfCtx.IFB_BusType == CFG_NIC_BUS_TYPE_CARDBUS ||
593 lp->hcfCtx.IFB_BusType == CFG_NIC_BUS_TYPE_PCI ) {
594 DBG_TRACE( DbgInfo, "This is a PCI/CardBus card, enable interrupts\n" );
595 wl_pci_enable_cardbus_interrupts( pdev );
598 /* Enable bus mastering */
599 pci_set_master( pdev );
601 DBG_LEAVE( DbgInfo );
604 /*============================================================================*/
606 /*******************************************************************************
607 * wl_pci_enable_cardbus_interrupts()
608 *******************************************************************************
612 * Called by wl_pci_setup() to enable interrupts on a CardBus device. This
613 * is done by writing bit 15 to the function event mask register. This
614 * CardBus-specific register is located in BAR2 (counting from BAR0), in memory
615 * space at byte offset 1f4 (7f4 for WARP).
619 * pdev - a pointer to the device's pci_dev structure
625 ******************************************************************************/
626 void wl_pci_enable_cardbus_interrupts( struct pci_dev *pdev )
630 u32 func_evt_mask_reg;
631 void *mem_addr_kern = NULL;
632 /*------------------------------------------------------------------------*/
634 DBG_FUNC( "wl_pci_enable_cardbus_interrupts" );
635 DBG_ENTER( DbgInfo );
637 /* Initialize to known bad values */
638 bar2_reg = 0xdeadbeef;
639 mem_addr_bus = 0xdeadbeef;
641 /* Read the BAR2 register; this register contains the base address of the
642 memory region where the function event mask register lives */
643 pci_read_config_dword( pdev, PCI_BASE_ADDRESS_2, &bar2_reg );
644 mem_addr_bus = bar2_reg & PCI_BASE_ADDRESS_MEM_MASK;
646 /* Once the base address is obtained, remap the memory region to kernel
647 space so we can retrieve the register */
648 mem_addr_kern = ioremap( mem_addr_bus, 0x200 );
651 #define REG_OFFSET 0x07F4
653 #define REG_OFFSET 0x01F4
658 /* Retrieve the functional event mask register, enable interrupts by
659 setting Bit 15, and write back the value */
660 func_evt_mask_reg = *(u32 *)( mem_addr_kern + REG_OFFSET );
661 func_evt_mask_reg |= BIT15;
662 *(u32 *)( mem_addr_kern + REG_OFFSET ) = func_evt_mask_reg;
664 /* Once complete, unmap the region and exit */
665 iounmap( mem_addr_kern );
667 DBG_LEAVE( DbgInfo );
669 } // wl_pci_enable_cardbus_interrupts
670 /*============================================================================*/
673 /*******************************************************************************
675 *******************************************************************************
679 * Allocates all resources needed for PCI/CardBus DMA operation
683 * pdev - a pointer to the device's pci_dev structure
684 * lp - the device's private adapter structure
689 * errno value otherwise
691 ******************************************************************************/
692 int wl_pci_dma_alloc( struct pci_dev *pdev, struct wl_private *lp )
696 /*------------------------------------------------------------------------*/
698 DBG_FUNC( "wl_pci_dma_alloc" );
699 DBG_ENTER( DbgInfo );
701 // lp->dma.tx_rsc_ind = lp->dma.rx_rsc_ind = 0;
703 // /* Alloc for the Tx chain and its reclaim descriptor */
704 // for( i = 0; i < NUM_TX_DESC; i++ ) {
705 // status = wl_pci_dma_alloc_tx_packet( pdev, lp, &lp->dma.tx_packet[i] );
706 // if( status == 0 ) {
707 // DBG_PRINT( "lp->dma.tx_packet[%d] : 0x%p\n", i, lp->dma.tx_packet[i] );
708 // DBG_PRINT( "lp->dma.tx_packet[%d]->next_desc_addr : 0x%p\n", i, lp->dma.tx_packet[i]->next_desc_addr );
709 // lp->dma.tx_rsc_ind++;
711 // DBG_ERROR( DbgInfo, "Could not alloc DMA Tx Packet\n" );
715 // if( status == 0 ) {
716 // status = wl_pci_dma_alloc_desc( pdev, lp, &lp->dma.tx_reclaim_desc );
717 // DBG_PRINT( "lp->dma.tx_reclaim_desc: 0x%p\n", lp->dma.tx_reclaim_desc );
719 // /* Alloc for the Rx chain and its reclaim descriptor */
720 // if( status == 0 ) {
721 // for( i = 0; i < NUM_RX_DESC; i++ ) {
722 // status = wl_pci_dma_alloc_rx_packet( pdev, lp, &lp->dma.rx_packet[i] );
723 // if( status == 0 ) {
724 // DBG_PRINT( "lp->dma.rx_packet[%d] : 0x%p\n", i, lp->dma.rx_packet[i] );
725 // DBG_PRINT( "lp->dma.rx_packet[%d]->next_desc_addr : 0x%p\n", i, lp->dma.rx_packet[i]->next_desc_addr );
726 // lp->dma.rx_rsc_ind++;
728 // DBG_ERROR( DbgInfo, "Could not alloc DMA Rx Packet\n" );
733 // if( status == 0 ) {
734 // status = wl_pci_dma_alloc_desc( pdev, lp, &lp->dma.rx_reclaim_desc );
735 // DBG_PRINT( "lp->dma.rx_reclaim_desc: 0x%p\n", lp->dma.rx_reclaim_desc );
737 // /* Store status, as host should not call HCF functions if this fails */
738 // lp->dma.status = status; //;?all useages of dma.status have been commented out
739 // DBG_LEAVE( DbgInfo );
741 } // wl_pci_dma_alloc
742 /*============================================================================*/
744 /*******************************************************************************
746 *******************************************************************************
750 * Deallocated all resources needed for PCI/CardBus DMA operation
754 * pdev - a pointer to the device's pci_dev structure
755 * lp - the device's private adapter structure
760 * errno value otherwise
762 ******************************************************************************/
763 int wl_pci_dma_free( struct pci_dev *pdev, struct wl_private *lp )
767 /*------------------------------------------------------------------------*/
769 DBG_FUNC( "wl_pci_dma_free" );
770 DBG_ENTER( DbgInfo );
772 /* Reclaim all Rx packets that were handed over to the HCF */
773 /* Do I need to do this? Before this free is called, I've already disabled
774 the port which will call wl_pci_dma_hcf_reclaim */
775 //if( lp->dma.status == 0 )
777 // wl_pci_dma_hcf_reclaim( lp );
780 /* Free everything needed for DMA Rx */
781 for( i = 0; i < NUM_RX_DESC; i++ ) {
782 if( lp->dma.rx_packet[i] ) {
783 status = wl_pci_dma_free_rx_packet( pdev, lp, &lp->dma.rx_packet[i] );
785 DBG_WARNING( DbgInfo, "Problem freeing Rx packet\n" );
789 lp->dma.rx_rsc_ind = 0;
791 if( lp->dma.rx_reclaim_desc ) {
792 status = wl_pci_dma_free_desc( pdev, lp, &lp->dma.rx_reclaim_desc );
794 DBG_WARNING( DbgInfo, "Problem freeing Rx reclaim descriptor\n" );
798 /* Free everything needed for DMA Tx */
799 for( i = 0; i < NUM_TX_DESC; i++ ) {
800 if( lp->dma.tx_packet[i] ) {
801 status = wl_pci_dma_free_tx_packet( pdev, lp, &lp->dma.tx_packet[i] );
803 DBG_WARNING( DbgInfo, "Problem freeing Tx packet\n" );
807 lp->dma.tx_rsc_ind = 0;
809 if( lp->dma.tx_reclaim_desc ) {
810 status = wl_pci_dma_free_desc( pdev, lp, &lp->dma.tx_reclaim_desc );
812 DBG_WARNING( DbgInfo, "Problem freeing Tx reclaim descriptor\n" );
816 DBG_LEAVE( DbgInfo );
820 /*============================================================================*/
822 /*******************************************************************************
823 * wl_pci_dma_alloc_tx_packet()
824 *******************************************************************************
828 * Allocates a single Tx packet, consisting of several descriptors and
829 * buffers. Data to transmit is first copied into the 'payload' buffer
830 * before being transmitted.
834 * pdev - a pointer to the device's pci_dev structure
835 * lp - the device's private adapter structure
836 * desc - a pointer which will reference the descriptor to be alloc'd.
841 * errno value otherwise
843 ******************************************************************************/
844 int wl_pci_dma_alloc_tx_packet( struct pci_dev *pdev, struct wl_private *lp,
848 // /*------------------------------------------------------------------------*/
850 // if( desc == NULL ) {
853 // if( status == 0 ) {
854 // status = wl_pci_dma_alloc_desc_and_buf( pdev, lp, desc,
855 // HCF_DMA_TX_BUF1_SIZE );
857 // if( status == 0 ) {
858 // status = wl_pci_dma_alloc_desc_and_buf( pdev, lp,
859 // &( (*desc)->next_desc_addr ),
860 // HCF_MAX_PACKET_SIZE );
863 // if( status == 0 ) {
864 // (*desc)->next_desc_phys_addr = (*desc)->next_desc_addr->desc_phys_addr;
867 } // wl_pci_dma_alloc_tx_packet
868 /*============================================================================*/
870 /*******************************************************************************
871 * wl_pci_dma_free_tx_packet()
872 *******************************************************************************
876 * Frees a single Tx packet, described in the corresponding alloc function.
880 * pdev - a pointer to the device's pci_dev structure
881 * lp - the device's private adapter structure
882 * desc - a pointer which will reference the descriptor to be alloc'd.
887 * errno value otherwise
889 ******************************************************************************/
890 int wl_pci_dma_free_tx_packet( struct pci_dev *pdev, struct wl_private *lp,
894 /*------------------------------------------------------------------------*/
896 if( *desc == NULL ) {
897 DBG_PRINT( "Null descriptor\n" );
900 //;?the "limited" NDIS strategy, assuming a frame consists ALWAYS out of 2
901 //descriptors, make this robust
902 if( status == 0 && (*desc)->next_desc_addr ) {
903 status = wl_pci_dma_free_desc_and_buf( pdev, lp, &(*desc)->next_desc_addr );
906 status = wl_pci_dma_free_desc_and_buf( pdev, lp, desc );
909 } // wl_pci_dma_free_tx_packet
910 /*============================================================================*/
912 /*******************************************************************************
913 * wl_pci_dma_alloc_rx_packet()
914 *******************************************************************************
918 * Allocates a single Rx packet, consisting of two descriptors and one
919 * contiguous buffer. THe buffer starts with the hermes-specific header.
920 * One descriptor points at the start, the other at offset 0x3a of the
925 * pdev - a pointer to the device's pci_dev structure
926 * lp - the device's private adapter structure
927 * desc - a pointer which will reference the descriptor to be alloc'd.
932 * errno value otherwise
934 ******************************************************************************/
935 int wl_pci_dma_alloc_rx_packet( struct pci_dev *pdev, struct wl_private *lp,
940 /*------------------------------------------------------------------------*/
942 // if( desc == NULL ) {
945 // //;?the "limited" NDIS strategy, assuming a frame consists ALWAYS out of 2
946 // //descriptors, make this robust
947 // if( status == 0 ) {
948 // status = wl_pci_dma_alloc_desc( pdev, lp, desc );
950 // if( status == 0 ) {
951 // status = wl_pci_dma_alloc_buf( pdev, lp, *desc, HCF_MAX_PACKET_SIZE );
953 // if( status == 0 ) {
954 // status = wl_pci_dma_alloc_desc( pdev, lp, &p );
956 // if( status == 0 ) {
957 // /* Size of 1st descriptor becomes 0x3a bytes */
958 // SET_BUF_SIZE( *desc, HCF_DMA_RX_BUF1_SIZE );
960 // /* Make 2nd descriptor point at offset 0x3a of the buffer */
961 // SET_BUF_SIZE( p, ( HCF_MAX_PACKET_SIZE - HCF_DMA_RX_BUF1_SIZE ));
962 // p->buf_addr = (*desc)->buf_addr + HCF_DMA_RX_BUF1_SIZE;
963 // p->buf_phys_addr = (*desc)->buf_phys_addr + HCF_DMA_RX_BUF1_SIZE;
964 // p->next_desc_addr = NULL;
966 // /* Chain 2nd descriptor to 1st descriptor */
967 // (*desc)->next_desc_addr = p;
968 // (*desc)->next_desc_phys_addr = p->desc_phys_addr;
972 } // wl_pci_dma_alloc_rx_packet
973 /*============================================================================*/
975 /*******************************************************************************
976 * wl_pci_dma_free_rx_packet()
977 *******************************************************************************
981 * Frees a single Rx packet, described in the corresponding alloc function.
985 * pdev - a pointer to the device's pci_dev structure
986 * lp - the device's private adapter structure
987 * desc - a pointer which will reference the descriptor to be alloc'd.
992 * errno value otherwise
994 ******************************************************************************/
995 int wl_pci_dma_free_rx_packet( struct pci_dev *pdev, struct wl_private *lp,
1000 /*------------------------------------------------------------------------*/
1002 if( *desc == NULL ) {
1006 p = (*desc)->next_desc_addr;
1008 /* Free the 2nd descriptor */
1011 p->buf_phys_addr = 0;
1013 status = wl_pci_dma_free_desc( pdev, lp, &p );
1017 /* Free the buffer and 1st descriptor */
1019 SET_BUF_SIZE( *desc, HCF_MAX_PACKET_SIZE );
1020 status = wl_pci_dma_free_desc_and_buf( pdev, lp, desc );
1023 } // wl_pci_dma_free_rx_packet
1024 /*============================================================================*/
1026 /*******************************************************************************
1027 * wl_pci_dma_alloc_desc_and_buf()
1028 *******************************************************************************
1032 * Allocates a DMA descriptor and buffer, and associates them with one
1037 * pdev - a pointer to the device's pci_dev structure
1038 * lp - the device's private adapter structure
1039 * desc - a pointer which will reference the descriptor to be alloc'd
1044 * errno value otherwise
1046 ******************************************************************************/
1047 int wl_pci_dma_alloc_desc_and_buf( struct pci_dev *pdev, struct wl_private *lp,
1048 DESC_STRCT **desc, int size )
1051 /*------------------------------------------------------------------------*/
1053 // if( desc == NULL ) {
1054 // status = -EFAULT;
1056 // if( status == 0 ) {
1057 // status = wl_pci_dma_alloc_desc( pdev, lp, desc );
1059 // if( status == 0 ) {
1060 // status = wl_pci_dma_alloc_buf( pdev, lp, *desc, size );
1064 } // wl_pci_dma_alloc_desc_and_buf
1065 /*============================================================================*/
1067 /*******************************************************************************
1068 * wl_pci_dma_free_desc_and_buf()
1069 *******************************************************************************
1073 * Frees a DMA descriptor and associated buffer.
1077 * pdev - a pointer to the device's pci_dev structure
1078 * lp - the device's private adapter structure
1079 * desc - a pointer which will reference the descriptor to be alloc'd
1084 * errno value otherwise
1086 ******************************************************************************/
1087 int wl_pci_dma_free_desc_and_buf( struct pci_dev *pdev, struct wl_private *lp,
1091 /*------------------------------------------------------------------------*/
1093 if( desc == NULL ) {
1096 if( status == 0 && *desc == NULL ) {
1100 status = wl_pci_dma_free_buf( pdev, lp, *desc );
1103 status = wl_pci_dma_free_desc( pdev, lp, desc );
1107 } // wl_pci_dma_free_desc_and_buf
1108 /*============================================================================*/
1110 /*******************************************************************************
1111 * wl_pci_dma_alloc_desc()
1112 *******************************************************************************
1116 * Allocates one DMA descriptor in cache coherent memory.
1120 * pdev - a pointer to the device's pci_dev structure
1121 * lp - the device's private adapter structure
1126 * errno value otherwise
1128 ******************************************************************************/
1129 int wl_pci_dma_alloc_desc( struct pci_dev *pdev, struct wl_private *lp,
1134 // /*------------------------------------------------------------------------*/
1136 // DBG_FUNC( "wl_pci_dma_alloc_desc" );
1137 // DBG_ENTER( DbgInfo );
1139 // if( desc == NULL ) {
1140 // status = -EFAULT;
1142 // if( status == 0 ) {
1143 // *desc = pci_alloc_consistent( pdev, sizeof( DESC_STRCT ), &pa );
1145 // if( *desc == NULL ) {
1146 // DBG_ERROR( DbgInfo, "pci_alloc_consistent() failed\n" );
1147 // status = -ENOMEM;
1149 // memset( *desc, 0, sizeof( DESC_STRCT ));
1150 // (*desc)->desc_phys_addr = cpu_to_le32( pa );
1152 // DBG_LEAVE( DbgInfo );
1154 } // wl_pci_dma_alloc_desc
1155 /*============================================================================*/
1157 /*******************************************************************************
1158 * wl_pci_dma_free_desc()
1159 *******************************************************************************
1163 * Frees one DMA descriptor in cache coherent memory.
1167 * pdev - a pointer to the device's pci_dev structure
1168 * lp - the device's private adapter structure
1173 * errno value otherwise
1175 ******************************************************************************/
1176 int wl_pci_dma_free_desc( struct pci_dev *pdev, struct wl_private *lp,
1180 /*------------------------------------------------------------------------*/
1182 if( *desc == NULL ) {
1186 pci_free_consistent( pdev, sizeof( DESC_STRCT ), *desc,
1187 (*desc)->desc_phys_addr );
1191 } // wl_pci_dma_free_desc
1192 /*============================================================================*/
1194 /*******************************************************************************
1195 * wl_pci_dma_alloc_buf()
1196 *******************************************************************************
1200 * Allocates one DMA buffer in cache coherent memory, and associates a DMA
1201 * descriptor with this buffer.
1205 * pdev - a pointer to the device's pci_dev structure
1206 * lp - the device's private adapter structure
1211 * errno value otherwise
1213 ******************************************************************************/
1214 int wl_pci_dma_alloc_buf( struct pci_dev *pdev, struct wl_private *lp,
1215 DESC_STRCT *desc, int size )
1219 /*------------------------------------------------------------------------*/
1221 // DBG_FUNC( "wl_pci_dma_alloc_buf" );
1222 // DBG_ENTER( DbgInfo );
1224 // if( desc == NULL ) {
1225 // status = -EFAULT;
1227 // if( status == 0 && desc->buf_addr != NULL ) {
1228 // status = -EFAULT;
1230 // if( status == 0 ) {
1231 // desc->buf_addr = pci_alloc_consistent( pdev, size, &pa );
1233 // if( desc->buf_addr == NULL ) {
1234 // DBG_ERROR( DbgInfo, "pci_alloc_consistent() failed\n" );
1235 // status = -ENOMEM;
1237 // desc->buf_phys_addr = cpu_to_le32( pa );
1238 // SET_BUF_SIZE( desc, size );
1240 // DBG_LEAVE( DbgInfo );
1242 } // wl_pci_dma_alloc_buf
1243 /*============================================================================*/
1245 /*******************************************************************************
1246 * wl_pci_dma_free_buf()
1247 *******************************************************************************
1251 * Allocates one DMA buffer in cache coherent memory, and associates a DMA
1252 * descriptor with this buffer.
1256 * pdev - a pointer to the device's pci_dev structure
1257 * lp - the device's private adapter structure
1262 * errno value otherwise
1264 ******************************************************************************/
1265 int wl_pci_dma_free_buf( struct pci_dev *pdev, struct wl_private *lp,
1269 /*------------------------------------------------------------------------*/
1271 if( desc == NULL ) {
1274 if( status == 0 && desc->buf_addr == NULL ) {
1278 pci_free_consistent( pdev, GET_BUF_SIZE( desc ), desc->buf_addr,
1279 desc->buf_phys_addr );
1282 desc->buf_phys_addr = 0;
1283 SET_BUF_SIZE( desc, 0 );
1286 } // wl_pci_dma_free_buf
1287 /*============================================================================*/
1289 /*******************************************************************************
1290 * wl_pci_dma_hcf_supply()
1291 *******************************************************************************
1295 * Supply HCF with DMA-related resources. These consist of:
1296 * - buffers and descriptors for receive purposes
1297 * - one 'reclaim' descriptor for the transmit path, used to fulfill a
1298 * certain H25 DMA engine requirement
1299 * - one 'reclaim' descriptor for the receive path, used to fulfill a
1300 * certain H25 DMA engine requirement
1302 * This function is called at start-of-day or at re-initialization.
1306 * lp - the device's private adapter structure
1311 * errno value otherwise
1313 ******************************************************************************/
1314 void wl_pci_dma_hcf_supply( struct wl_private *lp )
1317 /*------------------------------------------------------------------------*/
1319 DBG_FUNC( "wl_pci_dma_hcf_supply" );
1320 DBG_ENTER( DbgInfo );
1322 //if( lp->dma.status == 0 );
1324 /* Hand over the Rx/Tx reclaim descriptors to the HCF */
1325 if( lp->dma.tx_reclaim_desc ) {
1326 DBG_PRINT( "lp->dma.tx_reclaim_desc: 0x%p\n", lp->dma.tx_reclaim_desc );
1327 hcf_dma_tx_put( &lp->hcfCtx, lp->dma.tx_reclaim_desc, 0 );
1328 lp->dma.tx_reclaim_desc = NULL;
1329 DBG_PRINT( "lp->dma.tx_reclaim_desc: 0x%p\n", lp->dma.tx_reclaim_desc );
1331 if( lp->dma.rx_reclaim_desc ) {
1332 DBG_PRINT( "lp->dma.rx_reclaim_desc: 0x%p\n", lp->dma.rx_reclaim_desc );
1333 hcf_dma_rx_put( &lp->hcfCtx, lp->dma.rx_reclaim_desc );
1334 lp->dma.rx_reclaim_desc = NULL;
1335 DBG_PRINT( "lp->dma.rx_reclaim_desc: 0x%p\n", lp->dma.rx_reclaim_desc );
1337 /* Hand over the Rx descriptor chain to the HCF */
1338 for( i = 0; i < NUM_RX_DESC; i++ ) {
1339 DBG_PRINT( "lp->dma.rx_packet[%d]: 0x%p\n", i, lp->dma.rx_packet[i] );
1340 hcf_dma_rx_put( &lp->hcfCtx, lp->dma.rx_packet[i] );
1341 lp->dma.rx_packet[i] = NULL;
1342 DBG_PRINT( "lp->dma.rx_packet[%d]: 0x%p\n", i, lp->dma.rx_packet[i] );
1346 DBG_LEAVE( DbgInfo );
1348 } // wl_pci_dma_hcf_supply
1349 /*============================================================================*/
1351 /*******************************************************************************
1352 * wl_pci_dma_hcf_reclaim()
1353 *******************************************************************************
1357 * Return DMA-related resources from the HCF. These consist of:
1358 * - buffers and descriptors for receive purposes
1359 * - buffers and descriptors for transmit purposes
1360 * - one 'reclaim' descriptor for the transmit path, used to fulfill a
1361 * certain H25 DMA engine requirement
1362 * - one 'reclaim' descriptor for the receive path, used to fulfill a
1363 * certain H25 DMA engine requirement
1365 * This function is called at end-of-day or at re-initialization.
1369 * lp - the device's private adapter structure
1374 * errno value otherwise
1376 ******************************************************************************/
1377 void wl_pci_dma_hcf_reclaim( struct wl_private *lp )
1380 /*------------------------------------------------------------------------*/
1382 DBG_FUNC( "wl_pci_dma_hcf_reclaim" );
1383 DBG_ENTER( DbgInfo );
1385 wl_pci_dma_hcf_reclaim_rx( lp );
1386 for( i = 0; i < NUM_RX_DESC; i++ ) {
1387 DBG_PRINT( "rx_packet[%d] 0x%p\n", i, lp->dma.rx_packet[i] );
1388 // if( lp->dma.rx_packet[i] == NULL ) {
1389 // DBG_PRINT( "wl_pci_dma_hcf_reclaim: rx_packet[%d] NULL\n", i );
1393 wl_pci_dma_hcf_reclaim_tx( lp );
1394 for( i = 0; i < NUM_TX_DESC; i++ ) {
1395 DBG_PRINT( "tx_packet[%d] 0x%p\n", i, lp->dma.tx_packet[i] );
1396 // if( lp->dma.tx_packet[i] == NULL ) {
1397 // DBG_PRINT( "wl_pci_dma_hcf_reclaim: tx_packet[%d] NULL\n", i );
1401 DBG_LEAVE( DbgInfo );
1403 } // wl_pci_dma_hcf_reclaim
1404 /*============================================================================*/
1406 /*******************************************************************************
1407 * wl_pci_dma_hcf_reclaim_rx()
1408 *******************************************************************************
1412 * Reclaim Rx packets that have already been processed by the HCF.
1416 * lp - the device's private adapter structure
1421 * errno value otherwise
1423 ******************************************************************************/
1424 void wl_pci_dma_hcf_reclaim_rx( struct wl_private *lp )
1428 /*------------------------------------------------------------------------*/
1430 DBG_FUNC( "wl_pci_dma_hcf_reclaim_rx" );
1431 DBG_ENTER( DbgInfo );
1433 //if( lp->dma.status == 0 )
1435 while ( ( p = hcf_dma_rx_get( &lp->hcfCtx ) ) != NULL ) {
1436 if( p && p->buf_addr == NULL ) {
1437 /* A reclaim descriptor is being given back by the HCF. Reclaim
1438 descriptors have a NULL buf_addr */
1439 lp->dma.rx_reclaim_desc = p;
1440 DBG_PRINT( "reclaim_descriptor: 0x%p\n", p );
1443 for( i = 0; i < NUM_RX_DESC; i++ ) {
1444 if( lp->dma.rx_packet[i] == NULL ) {
1448 /* An Rx buffer descriptor is being given back by the HCF */
1449 lp->dma.rx_packet[i] = p;
1450 lp->dma.rx_rsc_ind++;
1451 DBG_PRINT( "rx_packet[%d] 0x%p\n", i, lp->dma.rx_packet[i] );
1454 DBG_LEAVE( DbgInfo );
1455 } // wl_pci_dma_hcf_reclaim_rx
1456 /*============================================================================*/
1458 /*******************************************************************************
1459 * wl_pci_dma_get_tx_packet()
1460 *******************************************************************************
1464 * Obtains a Tx descriptor from the chain to use for Tx.
1468 * lp - a pointer to the device's wl_private structure.
1472 * A pointer to the retrieved descriptor
1474 ******************************************************************************/
1475 DESC_STRCT * wl_pci_dma_get_tx_packet( struct wl_private *lp )
1478 DESC_STRCT *desc = NULL;
1479 /*------------------------------------------------------------------------*/
1481 for( i = 0; i < NUM_TX_DESC; i++ ) {
1482 if( lp->dma.tx_packet[i] ) {
1487 if( i != NUM_TX_DESC ) {
1488 desc = lp->dma.tx_packet[i];
1490 lp->dma.tx_packet[i] = NULL;
1491 lp->dma.tx_rsc_ind--;
1493 memset( desc->buf_addr, 0, HCF_DMA_TX_BUF1_SIZE );
1497 } // wl_pci_dma_get_tx_packet
1498 /*============================================================================*/
1500 /*******************************************************************************
1501 * wl_pci_dma_put_tx_packet()
1502 *******************************************************************************
1506 * Returns a Tx descriptor to the chain.
1510 * lp - a pointer to the device's wl_private structure.
1511 * desc - a pointer to the descriptor to return.
1517 ******************************************************************************/
1518 void wl_pci_dma_put_tx_packet( struct wl_private *lp, DESC_STRCT *desc )
1521 /*------------------------------------------------------------------------*/
1523 for( i = 0; i < NUM_TX_DESC; i++ ) {
1524 if( lp->dma.tx_packet[i] == NULL ) {
1529 if( i != NUM_TX_DESC ) {
1530 lp->dma.tx_packet[i] = desc;
1531 lp->dma.tx_rsc_ind++;
1533 } // wl_pci_dma_put_tx_packet
1534 /*============================================================================*/
1536 /*******************************************************************************
1537 * wl_pci_dma_hcf_reclaim_tx()
1538 *******************************************************************************
1542 * Reclaim Tx packets that have either been processed by the HCF due to a
1543 * port disable or a Tx completion.
1547 * lp - the device's private adapter structure
1552 * errno value otherwise
1554 ******************************************************************************/
1555 void wl_pci_dma_hcf_reclaim_tx( struct wl_private *lp )
1559 /*------------------------------------------------------------------------*/
1561 DBG_FUNC( "wl_pci_dma_hcf_reclaim_tx" );
1562 DBG_ENTER( DbgInfo );
1564 //if( lp->dma.status == 0 )
1566 while ( ( p = hcf_dma_tx_get( &lp->hcfCtx ) ) != NULL ) {
1568 if( p != NULL && p->buf_addr == NULL ) {
1569 /* A Reclaim descriptor is being given back by the HCF. Reclaim
1570 descriptors have a NULL buf_addr */
1571 lp->dma.tx_reclaim_desc = p;
1572 DBG_PRINT( "reclaim_descriptor: 0x%p\n", p );
1575 for( i = 0; i < NUM_TX_DESC; i++ ) {
1576 if( lp->dma.tx_packet[i] == NULL ) {
1580 /* An Rx buffer descriptor is being given back by the HCF */
1581 lp->dma.tx_packet[i] = p;
1582 lp->dma.tx_rsc_ind++;
1583 DBG_PRINT( "tx_packet[%d] 0x%p\n", i, lp->dma.tx_packet[i] );
1587 if( lp->netif_queue_on == FALSE ) {
1588 netif_wake_queue( lp->dev );
1589 WL_WDS_NETIF_WAKE_QUEUE( lp );
1590 lp->netif_queue_on = TRUE;
1592 DBG_LEAVE( DbgInfo );
1594 } // wl_pci_dma_hcf_reclaim_tx
1595 /*============================================================================*/
1596 #endif // ENABLE_DMA