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 ******************************************************************************/
62 /*******************************************************************************
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/sched.h>
72 #include <linux/ptrace.h>
73 #include <linux/ctype.h>
74 #include <linux/string.h>
75 //#include <linux/timer.h>
76 #include <linux/interrupt.h>
78 #include <linux/delay.h>
81 #include <asm/bitops.h>
82 #include <asm/uaccess.h>
84 #include <linux/ethtool.h>
85 #include <linux/netdevice.h>
86 #include <linux/etherdevice.h>
87 #include <linux/skbuff.h>
88 #include <linux/if_arp.h>
89 #include <linux/ioport.h>
91 #include <hcf/debug.h>
97 #include <wireless/wl_if.h>
98 #include <wireless/wl_internal.h>
99 #include <wireless/wl_util.h>
100 #include <wireless/wl_main.h>
101 #include <wireless/wl_netdev.h>
102 #include <wireless/wl_pci.h>
105 /*******************************************************************************
107 ******************************************************************************/
109 extern dbg_info_t *DbgInfo;
112 /* define the PCI device Table Cardname and id tables */
113 static struct pci_device_id wl_pci_tbl[] = {
114 { PCI_DEVICE(PCI_VENDOR_ID_WL_LKM, PCI_DEVICE_ID_WL_LKM_0), },
115 { PCI_DEVICE(PCI_VENDOR_ID_WL_LKM, PCI_DEVICE_ID_WL_LKM_1), },
116 { PCI_DEVICE(PCI_VENDOR_ID_WL_LKM, PCI_DEVICE_ID_WL_LKM_2), },
118 { } /* Terminating entry */
121 MODULE_DEVICE_TABLE(pci, wl_pci_tbl);
123 /*******************************************************************************
124 * function prototypes
125 ******************************************************************************/
126 int wl_pci_probe( struct pci_dev *pdev,
127 const struct pci_device_id *ent );
128 void wl_pci_remove(struct pci_dev *pdev);
129 int wl_pci_setup( struct pci_dev *pdev );
130 void wl_pci_enable_cardbus_interrupts( struct pci_dev *pdev );
133 int wl_pci_dma_alloc( struct pci_dev *pdev, struct wl_private *lp );
134 int wl_pci_dma_free( struct pci_dev *pdev, struct wl_private *lp );
135 int wl_pci_dma_alloc_tx_packet( struct pci_dev *pdev, struct wl_private *lp,
137 int wl_pci_dma_free_tx_packet( struct pci_dev *pdev, struct wl_private *lp,
139 int wl_pci_dma_alloc_rx_packet( struct pci_dev *pdev, struct wl_private *lp,
141 int wl_pci_dma_free_rx_packet( struct pci_dev *pdev, struct wl_private *lp,
143 int wl_pci_dma_alloc_desc_and_buf( struct pci_dev *pdev, struct wl_private *lp,
144 DESC_STRCT **desc, int size );
145 int wl_pci_dma_free_desc_and_buf( struct pci_dev *pdev, struct wl_private *lp,
147 int wl_pci_dma_alloc_desc( struct pci_dev *pdev, struct wl_private *lp,
149 int wl_pci_dma_free_desc( struct pci_dev *pdev, struct wl_private *lp,
151 int wl_pci_dma_alloc_buf( struct pci_dev *pdev, struct wl_private *lp,
152 DESC_STRCT *desc, int size );
153 int wl_pci_dma_free_buf( struct pci_dev *pdev, struct wl_private *lp,
156 void wl_pci_dma_hcf_reclaim_rx( struct wl_private *lp );
159 /*******************************************************************************
160 * PCI module function registration
161 ******************************************************************************/
162 static struct pci_driver wl_driver = {
164 .id_table = wl_pci_tbl,
165 .probe = wl_pci_probe,
166 .remove = wl_pci_remove,
171 /*******************************************************************************
172 * wl_adapter_init_module()
173 *******************************************************************************
177 * Called by init_module() to perform PCI-specific driver initialization.
187 ******************************************************************************/
188 int wl_adapter_init_module( void )
192 DBG_TRACE( DbgInfo, "wl_adapter_init_module() -- PCI\n" );
194 result = pci_register_driver( &wl_driver ); //;?replace with pci_module_init, Rubini pg 490
195 //;? why not do something with the result
197 DBG_LEAVE( DbgInfo );
199 } // wl_adapter_init_module
200 /*============================================================================*/
202 /*******************************************************************************
203 * wl_adapter_cleanup_module()
204 *******************************************************************************
208 * Called by cleanup_module() to perform PCI-specific driver cleanup.
218 ******************************************************************************/
219 void wl_adapter_cleanup_module( void )
221 //;?how come wl_adapter_cleanup_module is located in a seemingly pci specific module
222 DBG_TRACE( DbgInfo, "wl_adapter_cleanup_module() -- PCI\n" );
224 pci_unregister_driver( &wl_driver );
226 DBG_LEAVE( DbgInfo );
228 } // wl_adapter_cleanup_module
229 /*============================================================================*/
231 /*******************************************************************************
232 * wl_adapter_insert()
233 *******************************************************************************
237 * Called by wl_pci_probe() to continue the process of device insertion.
241 * dev - a pointer to the device's net_device structure
247 ******************************************************************************/
248 int wl_adapter_insert( struct net_device *dev )
252 DBG_TRACE( DbgInfo, "wl_adapter_insert() -- PCI\n" );
255 DBG_ERROR( DbgInfo, "net_device pointer is NULL!!!\n" );
256 } else if( dev->priv == NULL ) {
257 DBG_ERROR( DbgInfo, "wl_private pointer is NULL!!!\n" );
258 } else if( wl_insert( dev ) ) { /* Perform remaining device initialization */
261 DBG_TRACE( DbgInfo, "wl_insert() FAILED\n" );
263 DBG_LEAVE( DbgInfo );
265 } // wl_adapter_insert
266 /*============================================================================*/
268 /*******************************************************************************
270 *******************************************************************************
278 * dev - a pointer to the device's net_device structure
284 ******************************************************************************/
285 int wl_adapter_open( struct net_device *dev )
288 int hcf_status = HCF_SUCCESS;
290 DBG_TRACE( DbgInfo, "wl_adapter_open() -- PCI\n" );
292 hcf_status = wl_open( dev );
294 if( hcf_status != HCF_SUCCESS ) {
298 DBG_LEAVE( DbgInfo );
301 /*============================================================================*/
303 /*******************************************************************************
305 *******************************************************************************
313 * dev - a pointer to the device's net_device structure
319 ******************************************************************************/
320 int wl_adapter_close( struct net_device *dev )
322 DBG_TRACE( DbgInfo, "wl_adapter_close() -- PCI\n" );
323 DBG_TRACE( DbgInfo, "%s: Shutting down adapter.\n", dev->name );
327 DBG_LEAVE( DbgInfo );
329 } // wl_adapter_close
330 /*============================================================================*/
332 /*******************************************************************************
333 * wl_adapter_is_open()
334 *******************************************************************************
338 * Check whether this device is open. Returns
342 * dev - a pointer to the device's net_device structure
346 * nonzero if device is open.
348 ******************************************************************************/
349 int wl_adapter_is_open( struct net_device *dev )
351 /* This function is used in PCMCIA to check the status of the 'open' field
352 in the dev_link_t structure associated with a network device. There
353 doesn't seem to be an analog to this for PCI, and checking the status
354 contained in the net_device structure doesn't have the same effect.
355 For now, return TRUE, but find out if this is necessary for PCI. */
358 } // wl_adapter_is_open
359 /*============================================================================*/
361 /*******************************************************************************
363 *******************************************************************************
367 * Registered in the pci_driver structure, this function is called when the
368 * PCI subsystem finds a new PCI device which matches the information contained
369 * in the pci_device_id table.
373 * pdev - a pointer to the device's pci_dev structure
374 * ent - this device's entry in the pci_device_id table
379 * errno value otherwise
381 ******************************************************************************/
382 int wl_pci_probe( struct pci_dev *pdev,
383 const struct pci_device_id *ent )
387 DBG_PRINT( "%s\n", VERSION_INFO );
389 result = wl_pci_setup( pdev );
391 DBG_LEAVE( DbgInfo );
395 /*============================================================================*/
397 /*******************************************************************************
399 *******************************************************************************
403 * Registered in the pci_driver structure, this function is called when the
404 * PCI subsystem detects that a PCI device which matches the information
405 * contained in the pci_device_id table has been removed.
409 * pdev - a pointer to the device's pci_dev structure
415 ******************************************************************************/
416 void wl_pci_remove(struct pci_dev *pdev)
418 struct net_device *dev = NULL;
420 /* Make sure the pci_dev pointer passed in is valid */
422 DBG_ERROR( DbgInfo, "PCI subsys passed in an invalid pci_dev pointer\n" );
426 dev = pci_get_drvdata( pdev );
428 DBG_ERROR( DbgInfo, "Could not retrieve net_device structure\n" );
432 /* Perform device cleanup */
434 free_irq( dev->irq, dev );
437 wl_pci_dma_free( pdev, dev->priv );
440 wl_device_dealloc( dev );
442 DBG_LEAVE( DbgInfo );
445 /*============================================================================*/
447 /*******************************************************************************
449 *******************************************************************************
453 * Called by wl_pci_probe() to begin a device's initialization process.
457 * pdev - a pointer to the device's pci_dev structure
462 * errno value otherwise
464 ******************************************************************************/
465 int wl_pci_setup( struct pci_dev *pdev )
468 struct net_device *dev = NULL;
469 struct wl_private *lp = NULL;
471 /* Make sure the pci_dev pointer passed in is valid */
473 DBG_ERROR( DbgInfo, "PCI subsys passed in an invalid pci_dev pointer\n" );
477 result = pci_enable_device( pdev );
479 DBG_ERROR( DbgInfo, "pci_enable_device() failed\n" );
480 DBG_LEAVE( DbgInfo );
484 /* We found our device! Let's register it with the system */
485 DBG_TRACE( DbgInfo, "Found our device, now registering\n" );
486 dev = wl_device_alloc( );
488 DBG_ERROR( DbgInfo, "Could not register device!!!\n" );
489 DBG_LEAVE( DbgInfo );
493 /* Make sure that space was allocated for our private adapter struct */
494 if( dev->priv == NULL ) {
495 DBG_ERROR( DbgInfo, "Private adapter struct was not allocated!!!\n" );
496 wl_device_dealloc(dev);
497 DBG_LEAVE( DbgInfo );
502 /* Allocate DMA Descriptors */
503 if( wl_pci_dma_alloc( pdev, dev->priv ) < 0 ) {
504 DBG_ERROR( DbgInfo, "Could not allocate DMA descriptor memory!!!\n" );
505 wl_device_dealloc(dev);
506 DBG_LEAVE( DbgInfo );
511 /* Register our private adapter structure with PCI */
512 pci_set_drvdata( pdev, dev );
514 /* Fill out bus specific information in the net_device struct */
515 dev->irq = pdev->irq;
516 SET_MODULE_OWNER( dev );
518 DBG_TRACE( DbgInfo, "Device Base Address: %#03lx\n", pdev->resource[0].start );
519 dev->base_addr = pdev->resource[0].start;
521 /* Initialize our device here */
522 if( !wl_adapter_insert( dev )) {
523 DBG_ERROR( DbgInfo, "wl_adapter_insert() FAILED!!!\n" );
524 wl_device_dealloc( dev );
525 DBG_LEAVE( DbgInfo );
529 /* Register our ISR */
530 DBG_TRACE( DbgInfo, "Registering ISR...\n" );
532 result = request_irq(dev->irq, wl_isr, SA_SHIRQ, dev->name, dev);
534 DBG_WARNING( DbgInfo, "Could not register ISR!!!\n" );
536 wl_device_dealloc(dev);
537 DBG_LEAVE( DbgInfo );
541 /* Make sure interrupts are enabled properly for CardBus */
544 if( lp->hcfCtx.IFB_BusType == CFG_NIC_BUS_TYPE_CARDBUS ||
545 lp->hcfCtx.IFB_BusType == CFG_NIC_BUS_TYPE_PCI ) {
546 DBG_TRACE( DbgInfo, "This is a PCI/CardBus card, enable interrupts\n" );
547 wl_pci_enable_cardbus_interrupts( pdev );
550 /* Enable bus mastering */
551 pci_set_master( pdev );
553 DBG_LEAVE( DbgInfo );
556 /*============================================================================*/
558 /*******************************************************************************
559 * wl_pci_enable_cardbus_interrupts()
560 *******************************************************************************
564 * Called by wl_pci_setup() to enable interrupts on a CardBus device. This
565 * is done by writing bit 15 to the function event mask register. This
566 * CardBus-specific register is located in BAR2 (counting from BAR0), in memory
567 * space at byte offset 1f4 (7f4 for WARP).
571 * pdev - a pointer to the device's pci_dev structure
577 ******************************************************************************/
578 void wl_pci_enable_cardbus_interrupts( struct pci_dev *pdev )
582 u32 func_evt_mask_reg;
583 void *mem_addr_kern = NULL;
585 /* Initialize to known bad values */
586 bar2_reg = 0xdeadbeef;
587 mem_addr_bus = 0xdeadbeef;
589 /* Read the BAR2 register; this register contains the base address of the
590 memory region where the function event mask register lives */
591 pci_read_config_dword( pdev, PCI_BASE_ADDRESS_2, &bar2_reg );
592 mem_addr_bus = bar2_reg & PCI_BASE_ADDRESS_MEM_MASK;
594 /* Once the base address is obtained, remap the memory region to kernel
595 space so we can retrieve the register */
596 mem_addr_kern = ioremap( mem_addr_bus, 0x200 );
599 #define REG_OFFSET 0x07F4
601 #define REG_OFFSET 0x01F4
606 /* Retrieve the functional event mask register, enable interrupts by
607 setting Bit 15, and write back the value */
608 func_evt_mask_reg = *(u32 *)( mem_addr_kern + REG_OFFSET );
609 func_evt_mask_reg |= BIT15;
610 *(u32 *)( mem_addr_kern + REG_OFFSET ) = func_evt_mask_reg;
612 /* Once complete, unmap the region and exit */
613 iounmap( mem_addr_kern );
615 DBG_LEAVE( DbgInfo );
617 } // wl_pci_enable_cardbus_interrupts
618 /*============================================================================*/
621 /*******************************************************************************
623 *******************************************************************************
627 * Allocates all resources needed for PCI/CardBus DMA operation
631 * pdev - a pointer to the device's pci_dev structure
632 * lp - the device's private adapter structure
637 * errno value otherwise
639 ******************************************************************************/
640 int wl_pci_dma_alloc( struct pci_dev *pdev, struct wl_private *lp )
645 // lp->dma.tx_rsc_ind = lp->dma.rx_rsc_ind = 0;
647 // /* Alloc for the Tx chain and its reclaim descriptor */
648 // for( i = 0; i < NUM_TX_DESC; i++ ) {
649 // status = wl_pci_dma_alloc_tx_packet( pdev, lp, &lp->dma.tx_packet[i] );
650 // if( status == 0 ) {
651 // DBG_PRINT( "lp->dma.tx_packet[%d] : 0x%p\n", i, lp->dma.tx_packet[i] );
652 // DBG_PRINT( "lp->dma.tx_packet[%d]->next_desc_addr : 0x%p\n", i, lp->dma.tx_packet[i]->next_desc_addr );
653 // lp->dma.tx_rsc_ind++;
655 // DBG_ERROR( DbgInfo, "Could not alloc DMA Tx Packet\n" );
659 // if( status == 0 ) {
660 // status = wl_pci_dma_alloc_desc( pdev, lp, &lp->dma.tx_reclaim_desc );
661 // DBG_PRINT( "lp->dma.tx_reclaim_desc: 0x%p\n", lp->dma.tx_reclaim_desc );
663 // /* Alloc for the Rx chain and its reclaim descriptor */
664 // if( status == 0 ) {
665 // for( i = 0; i < NUM_RX_DESC; i++ ) {
666 // status = wl_pci_dma_alloc_rx_packet( pdev, lp, &lp->dma.rx_packet[i] );
667 // if( status == 0 ) {
668 // DBG_PRINT( "lp->dma.rx_packet[%d] : 0x%p\n", i, lp->dma.rx_packet[i] );
669 // DBG_PRINT( "lp->dma.rx_packet[%d]->next_desc_addr : 0x%p\n", i, lp->dma.rx_packet[i]->next_desc_addr );
670 // lp->dma.rx_rsc_ind++;
672 // DBG_ERROR( DbgInfo, "Could not alloc DMA Rx Packet\n" );
677 // if( status == 0 ) {
678 // status = wl_pci_dma_alloc_desc( pdev, lp, &lp->dma.rx_reclaim_desc );
679 // DBG_PRINT( "lp->dma.rx_reclaim_desc: 0x%p\n", lp->dma.rx_reclaim_desc );
681 // /* Store status, as host should not call HCF functions if this fails */
682 // lp->dma.status = status; //;?all useages of dma.status have been commented out
683 // DBG_LEAVE( DbgInfo );
685 } // wl_pci_dma_alloc
686 /*============================================================================*/
688 /*******************************************************************************
690 *******************************************************************************
694 * Deallocated all resources needed for PCI/CardBus DMA operation
698 * pdev - a pointer to the device's pci_dev structure
699 * lp - the device's private adapter structure
704 * errno value otherwise
706 ******************************************************************************/
707 int wl_pci_dma_free( struct pci_dev *pdev, struct wl_private *lp )
712 /* Reclaim all Rx packets that were handed over to the HCF */
713 /* Do I need to do this? Before this free is called, I've already disabled
714 the port which will call wl_pci_dma_hcf_reclaim */
715 //if( lp->dma.status == 0 )
717 // wl_pci_dma_hcf_reclaim( lp );
720 /* Free everything needed for DMA Rx */
721 for( i = 0; i < NUM_RX_DESC; i++ ) {
722 if( lp->dma.rx_packet[i] ) {
723 status = wl_pci_dma_free_rx_packet( pdev, lp, &lp->dma.rx_packet[i] );
725 DBG_WARNING( DbgInfo, "Problem freeing Rx packet\n" );
729 lp->dma.rx_rsc_ind = 0;
731 if( lp->dma.rx_reclaim_desc ) {
732 status = wl_pci_dma_free_desc( pdev, lp, &lp->dma.rx_reclaim_desc );
734 DBG_WARNING( DbgInfo, "Problem freeing Rx reclaim descriptor\n" );
738 /* Free everything needed for DMA Tx */
739 for( i = 0; i < NUM_TX_DESC; i++ ) {
740 if( lp->dma.tx_packet[i] ) {
741 status = wl_pci_dma_free_tx_packet( pdev, lp, &lp->dma.tx_packet[i] );
743 DBG_WARNING( DbgInfo, "Problem freeing Tx packet\n" );
747 lp->dma.tx_rsc_ind = 0;
749 if( lp->dma.tx_reclaim_desc ) {
750 status = wl_pci_dma_free_desc( pdev, lp, &lp->dma.tx_reclaim_desc );
752 DBG_WARNING( DbgInfo, "Problem freeing Tx reclaim descriptor\n" );
756 DBG_LEAVE( DbgInfo );
760 /*============================================================================*/
762 /*******************************************************************************
763 * wl_pci_dma_alloc_tx_packet()
764 *******************************************************************************
768 * Allocates a single Tx packet, consisting of several descriptors and
769 * buffers. Data to transmit is first copied into the 'payload' buffer
770 * before being transmitted.
774 * pdev - a pointer to the device's pci_dev structure
775 * lp - the device's private adapter structure
776 * desc - a pointer which will reference the descriptor to be alloc'd.
781 * errno value otherwise
783 ******************************************************************************/
784 int wl_pci_dma_alloc_tx_packet( struct pci_dev *pdev, struct wl_private *lp,
788 // /*------------------------------------------------------------------------*/
790 // if( desc == NULL ) {
793 // if( status == 0 ) {
794 // status = wl_pci_dma_alloc_desc_and_buf( pdev, lp, desc,
795 // HCF_DMA_TX_BUF1_SIZE );
797 // if( status == 0 ) {
798 // status = wl_pci_dma_alloc_desc_and_buf( pdev, lp,
799 // &( (*desc)->next_desc_addr ),
800 // HCF_MAX_PACKET_SIZE );
803 // if( status == 0 ) {
804 // (*desc)->next_desc_phys_addr = (*desc)->next_desc_addr->desc_phys_addr;
807 } // wl_pci_dma_alloc_tx_packet
808 /*============================================================================*/
810 /*******************************************************************************
811 * wl_pci_dma_free_tx_packet()
812 *******************************************************************************
816 * Frees a single Tx packet, described in the corresponding alloc function.
820 * pdev - a pointer to the device's pci_dev structure
821 * lp - the device's private adapter structure
822 * desc - a pointer which will reference the descriptor to be alloc'd.
827 * errno value otherwise
829 ******************************************************************************/
830 int wl_pci_dma_free_tx_packet( struct pci_dev *pdev, struct wl_private *lp,
834 /*------------------------------------------------------------------------*/
836 if( *desc == NULL ) {
837 DBG_PRINT( "Null descriptor\n" );
840 //;?the "limited" NDIS strategy, assuming a frame consists ALWAYS out of 2
841 //descriptors, make this robust
842 if( status == 0 && (*desc)->next_desc_addr ) {
843 status = wl_pci_dma_free_desc_and_buf( pdev, lp, &(*desc)->next_desc_addr );
846 status = wl_pci_dma_free_desc_and_buf( pdev, lp, desc );
849 } // wl_pci_dma_free_tx_packet
850 /*============================================================================*/
852 /*******************************************************************************
853 * wl_pci_dma_alloc_rx_packet()
854 *******************************************************************************
858 * Allocates a single Rx packet, consisting of two descriptors and one
859 * contiguous buffer. The buffer starts with the hermes-specific header.
860 * One descriptor points at the start, the other at offset 0x3a of the
865 * pdev - a pointer to the device's pci_dev structure
866 * lp - the device's private adapter structure
867 * desc - a pointer which will reference the descriptor to be alloc'd.
872 * errno value otherwise
874 ******************************************************************************/
875 int wl_pci_dma_alloc_rx_packet( struct pci_dev *pdev, struct wl_private *lp,
880 /*------------------------------------------------------------------------*/
882 // if( desc == NULL ) {
885 // //;?the "limited" NDIS strategy, assuming a frame consists ALWAYS out of 2
886 // //descriptors, make this robust
887 // if( status == 0 ) {
888 // status = wl_pci_dma_alloc_desc( pdev, lp, desc );
890 // if( status == 0 ) {
891 // status = wl_pci_dma_alloc_buf( pdev, lp, *desc, HCF_MAX_PACKET_SIZE );
893 // if( status == 0 ) {
894 // status = wl_pci_dma_alloc_desc( pdev, lp, &p );
896 // if( status == 0 ) {
897 // /* Size of 1st descriptor becomes 0x3a bytes */
898 // SET_BUF_SIZE( *desc, HCF_DMA_RX_BUF1_SIZE );
900 // /* Make 2nd descriptor point at offset 0x3a of the buffer */
901 // SET_BUF_SIZE( p, ( HCF_MAX_PACKET_SIZE - HCF_DMA_RX_BUF1_SIZE ));
902 // p->buf_addr = (*desc)->buf_addr + HCF_DMA_RX_BUF1_SIZE;
903 // p->buf_phys_addr = (*desc)->buf_phys_addr + HCF_DMA_RX_BUF1_SIZE;
904 // p->next_desc_addr = NULL;
906 // /* Chain 2nd descriptor to 1st descriptor */
907 // (*desc)->next_desc_addr = p;
908 // (*desc)->next_desc_phys_addr = p->desc_phys_addr;
912 } // wl_pci_dma_alloc_rx_packet
913 /*============================================================================*/
915 /*******************************************************************************
916 * wl_pci_dma_free_rx_packet()
917 *******************************************************************************
921 * Frees a single Rx packet, described in the corresponding alloc function.
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_free_rx_packet( struct pci_dev *pdev, struct wl_private *lp,
940 /*------------------------------------------------------------------------*/
942 if( *desc == NULL ) {
946 p = (*desc)->next_desc_addr;
948 /* Free the 2nd descriptor */
951 p->buf_phys_addr = 0;
953 status = wl_pci_dma_free_desc( pdev, lp, &p );
957 /* Free the buffer and 1st descriptor */
959 SET_BUF_SIZE( *desc, HCF_MAX_PACKET_SIZE );
960 status = wl_pci_dma_free_desc_and_buf( pdev, lp, desc );
963 } // wl_pci_dma_free_rx_packet
964 /*============================================================================*/
966 /*******************************************************************************
967 * wl_pci_dma_alloc_desc_and_buf()
968 *******************************************************************************
972 * Allocates a DMA descriptor and buffer, and associates them with one
977 * pdev - a pointer to the device's pci_dev structure
978 * lp - the device's private adapter structure
979 * desc - a pointer which will reference the descriptor to be alloc'd
984 * errno value otherwise
986 ******************************************************************************/
987 int wl_pci_dma_alloc_desc_and_buf( struct pci_dev *pdev, struct wl_private *lp,
988 DESC_STRCT **desc, int size )
991 /*------------------------------------------------------------------------*/
993 // if( desc == NULL ) {
996 // if( status == 0 ) {
997 // status = wl_pci_dma_alloc_desc( pdev, lp, desc );
999 // if( status == 0 ) {
1000 // status = wl_pci_dma_alloc_buf( pdev, lp, *desc, size );
1004 } // wl_pci_dma_alloc_desc_and_buf
1005 /*============================================================================*/
1007 /*******************************************************************************
1008 * wl_pci_dma_free_desc_and_buf()
1009 *******************************************************************************
1013 * Frees a DMA descriptor and associated buffer.
1017 * pdev - a pointer to the device's pci_dev structure
1018 * lp - the device's private adapter structure
1019 * desc - a pointer which will reference the descriptor to be alloc'd
1024 * errno value otherwise
1026 ******************************************************************************/
1027 int wl_pci_dma_free_desc_and_buf( struct pci_dev *pdev, struct wl_private *lp,
1031 /*------------------------------------------------------------------------*/
1033 if( desc == NULL ) {
1036 if( status == 0 && *desc == NULL ) {
1040 status = wl_pci_dma_free_buf( pdev, lp, *desc );
1043 status = wl_pci_dma_free_desc( pdev, lp, desc );
1047 } // wl_pci_dma_free_desc_and_buf
1048 /*============================================================================*/
1050 /*******************************************************************************
1051 * wl_pci_dma_alloc_desc()
1052 *******************************************************************************
1056 * Allocates one DMA descriptor in cache coherent memory.
1060 * pdev - a pointer to the device's pci_dev structure
1061 * lp - the device's private adapter structure
1066 * errno value otherwise
1068 ******************************************************************************/
1069 int wl_pci_dma_alloc_desc( struct pci_dev *pdev, struct wl_private *lp,
1075 // if( desc == NULL ) {
1076 // status = -EFAULT;
1078 // if( status == 0 ) {
1079 // *desc = pci_alloc_consistent( pdev, sizeof( DESC_STRCT ), &pa );
1081 // if( *desc == NULL ) {
1082 // DBG_ERROR( DbgInfo, "pci_alloc_consistent() failed\n" );
1083 // status = -ENOMEM;
1085 // memset( *desc, 0, sizeof( DESC_STRCT ));
1086 // (*desc)->desc_phys_addr = cpu_to_le32( pa );
1088 // DBG_LEAVE( DbgInfo );
1090 } // wl_pci_dma_alloc_desc
1091 /*============================================================================*/
1093 /*******************************************************************************
1094 * wl_pci_dma_free_desc()
1095 *******************************************************************************
1099 * Frees one DMA descriptor in cache coherent memory.
1103 * pdev - a pointer to the device's pci_dev structure
1104 * lp - the device's private adapter structure
1109 * errno value otherwise
1111 ******************************************************************************/
1112 int wl_pci_dma_free_desc( struct pci_dev *pdev, struct wl_private *lp,
1116 /*------------------------------------------------------------------------*/
1118 if( *desc == NULL ) {
1122 pci_free_consistent( pdev, sizeof( DESC_STRCT ), *desc,
1123 (*desc)->desc_phys_addr );
1127 } // wl_pci_dma_free_desc
1128 /*============================================================================*/
1130 /*******************************************************************************
1131 * wl_pci_dma_alloc_buf()
1132 *******************************************************************************
1136 * Allocates one DMA buffer in cache coherent memory, and associates a DMA
1137 * descriptor with this buffer.
1141 * pdev - a pointer to the device's pci_dev structure
1142 * lp - the device's private adapter structure
1147 * errno value otherwise
1149 ******************************************************************************/
1150 int wl_pci_dma_alloc_buf( struct pci_dev *pdev, struct wl_private *lp,
1151 DESC_STRCT *desc, int size )
1156 // if( desc == NULL ) {
1157 // status = -EFAULT;
1159 // if( status == 0 && desc->buf_addr != NULL ) {
1160 // status = -EFAULT;
1162 // if( status == 0 ) {
1163 // desc->buf_addr = pci_alloc_consistent( pdev, size, &pa );
1165 // if( desc->buf_addr == NULL ) {
1166 // DBG_ERROR( DbgInfo, "pci_alloc_consistent() failed\n" );
1167 // status = -ENOMEM;
1169 // desc->buf_phys_addr = cpu_to_le32( pa );
1170 // SET_BUF_SIZE( desc, size );
1172 // DBG_LEAVE( DbgInfo );
1174 } // wl_pci_dma_alloc_buf
1175 /*============================================================================*/
1177 /*******************************************************************************
1178 * wl_pci_dma_free_buf()
1179 *******************************************************************************
1183 * Allocates one DMA buffer in cache coherent memory, and associates a DMA
1184 * descriptor with this buffer.
1188 * pdev - a pointer to the device's pci_dev structure
1189 * lp - the device's private adapter structure
1194 * errno value otherwise
1196 ******************************************************************************/
1197 int wl_pci_dma_free_buf( struct pci_dev *pdev, struct wl_private *lp,
1201 /*------------------------------------------------------------------------*/
1203 if( desc == NULL ) {
1206 if( status == 0 && desc->buf_addr == NULL ) {
1210 pci_free_consistent( pdev, GET_BUF_SIZE( desc ), desc->buf_addr,
1211 desc->buf_phys_addr );
1214 desc->buf_phys_addr = 0;
1215 SET_BUF_SIZE( desc, 0 );
1218 } // wl_pci_dma_free_buf
1219 /*============================================================================*/
1221 /*******************************************************************************
1222 * wl_pci_dma_hcf_supply()
1223 *******************************************************************************
1227 * Supply HCF with DMA-related resources. These consist of:
1228 * - buffers and descriptors for receive purposes
1229 * - one 'reclaim' descriptor for the transmit path, used to fulfill a
1230 * certain H25 DMA engine requirement
1231 * - one 'reclaim' descriptor for the receive path, used to fulfill a
1232 * certain H25 DMA engine requirement
1234 * This function is called at start-of-day or at re-initialization.
1238 * lp - the device's private adapter structure
1243 * errno value otherwise
1245 ******************************************************************************/
1246 void wl_pci_dma_hcf_supply( struct wl_private *lp )
1250 //if( lp->dma.status == 0 );
1252 /* Hand over the Rx/Tx reclaim descriptors to the HCF */
1253 if( lp->dma.tx_reclaim_desc ) {
1254 DBG_PRINT( "lp->dma.tx_reclaim_desc: 0x%p\n", lp->dma.tx_reclaim_desc );
1255 hcf_dma_tx_put( &lp->hcfCtx, lp->dma.tx_reclaim_desc, 0 );
1256 lp->dma.tx_reclaim_desc = NULL;
1257 DBG_PRINT( "lp->dma.tx_reclaim_desc: 0x%p\n", lp->dma.tx_reclaim_desc );
1259 if( lp->dma.rx_reclaim_desc ) {
1260 DBG_PRINT( "lp->dma.rx_reclaim_desc: 0x%p\n", lp->dma.rx_reclaim_desc );
1261 hcf_dma_rx_put( &lp->hcfCtx, lp->dma.rx_reclaim_desc );
1262 lp->dma.rx_reclaim_desc = NULL;
1263 DBG_PRINT( "lp->dma.rx_reclaim_desc: 0x%p\n", lp->dma.rx_reclaim_desc );
1265 /* Hand over the Rx descriptor chain to the HCF */
1266 for( i = 0; i < NUM_RX_DESC; i++ ) {
1267 DBG_PRINT( "lp->dma.rx_packet[%d]: 0x%p\n", i, lp->dma.rx_packet[i] );
1268 hcf_dma_rx_put( &lp->hcfCtx, lp->dma.rx_packet[i] );
1269 lp->dma.rx_packet[i] = NULL;
1270 DBG_PRINT( "lp->dma.rx_packet[%d]: 0x%p\n", i, lp->dma.rx_packet[i] );
1274 DBG_LEAVE( DbgInfo );
1276 } // wl_pci_dma_hcf_supply
1277 /*============================================================================*/
1279 /*******************************************************************************
1280 * wl_pci_dma_hcf_reclaim()
1281 *******************************************************************************
1285 * Return DMA-related resources from the HCF. These consist of:
1286 * - buffers and descriptors for receive purposes
1287 * - buffers and descriptors for transmit purposes
1288 * - one 'reclaim' descriptor for the transmit path, used to fulfill a
1289 * certain H25 DMA engine requirement
1290 * - one 'reclaim' descriptor for the receive path, used to fulfill a
1291 * certain H25 DMA engine requirement
1293 * This function is called at end-of-day or at re-initialization.
1297 * lp - the device's private adapter structure
1302 * errno value otherwise
1304 ******************************************************************************/
1305 void wl_pci_dma_hcf_reclaim( struct wl_private *lp )
1309 wl_pci_dma_hcf_reclaim_rx( lp );
1310 for( i = 0; i < NUM_RX_DESC; i++ ) {
1311 DBG_PRINT( "rx_packet[%d] 0x%p\n", i, lp->dma.rx_packet[i] );
1312 // if( lp->dma.rx_packet[i] == NULL ) {
1313 // DBG_PRINT( "wl_pci_dma_hcf_reclaim: rx_packet[%d] NULL\n", i );
1317 wl_pci_dma_hcf_reclaim_tx( lp );
1318 for( i = 0; i < NUM_TX_DESC; i++ ) {
1319 DBG_PRINT( "tx_packet[%d] 0x%p\n", i, lp->dma.tx_packet[i] );
1320 // if( lp->dma.tx_packet[i] == NULL ) {
1321 // DBG_PRINT( "wl_pci_dma_hcf_reclaim: tx_packet[%d] NULL\n", i );
1325 DBG_LEAVE( DbgInfo );
1327 } // wl_pci_dma_hcf_reclaim
1328 /*============================================================================*/
1330 /*******************************************************************************
1331 * wl_pci_dma_hcf_reclaim_rx()
1332 *******************************************************************************
1336 * Reclaim Rx packets that have already been processed by the HCF.
1340 * lp - the device's private adapter structure
1345 * errno value otherwise
1347 ******************************************************************************/
1348 void wl_pci_dma_hcf_reclaim_rx( struct wl_private *lp )
1353 //if( lp->dma.status == 0 )
1355 while ( ( p = hcf_dma_rx_get( &lp->hcfCtx ) ) != NULL ) {
1356 if( p && p->buf_addr == NULL ) {
1357 /* A reclaim descriptor is being given back by the HCF. Reclaim
1358 descriptors have a NULL buf_addr */
1359 lp->dma.rx_reclaim_desc = p;
1360 DBG_PRINT( "reclaim_descriptor: 0x%p\n", p );
1363 for( i = 0; i < NUM_RX_DESC; i++ ) {
1364 if( lp->dma.rx_packet[i] == NULL ) {
1368 /* An Rx buffer descriptor is being given back by the HCF */
1369 lp->dma.rx_packet[i] = p;
1370 lp->dma.rx_rsc_ind++;
1371 DBG_PRINT( "rx_packet[%d] 0x%p\n", i, lp->dma.rx_packet[i] );
1374 DBG_LEAVE( DbgInfo );
1375 } // wl_pci_dma_hcf_reclaim_rx
1376 /*============================================================================*/
1378 /*******************************************************************************
1379 * wl_pci_dma_get_tx_packet()
1380 *******************************************************************************
1384 * Obtains a Tx descriptor from the chain to use for Tx.
1388 * lp - a pointer to the device's wl_private structure.
1392 * A pointer to the retrieved descriptor
1394 ******************************************************************************/
1395 DESC_STRCT * wl_pci_dma_get_tx_packet( struct wl_private *lp )
1398 DESC_STRCT *desc = NULL;
1399 /*------------------------------------------------------------------------*/
1401 for( i = 0; i < NUM_TX_DESC; i++ ) {
1402 if( lp->dma.tx_packet[i] ) {
1407 if( i != NUM_TX_DESC ) {
1408 desc = lp->dma.tx_packet[i];
1410 lp->dma.tx_packet[i] = NULL;
1411 lp->dma.tx_rsc_ind--;
1413 memset( desc->buf_addr, 0, HCF_DMA_TX_BUF1_SIZE );
1417 } // wl_pci_dma_get_tx_packet
1418 /*============================================================================*/
1420 /*******************************************************************************
1421 * wl_pci_dma_put_tx_packet()
1422 *******************************************************************************
1426 * Returns a Tx descriptor to the chain.
1430 * lp - a pointer to the device's wl_private structure.
1431 * desc - a pointer to the descriptor to return.
1437 ******************************************************************************/
1438 void wl_pci_dma_put_tx_packet( struct wl_private *lp, DESC_STRCT *desc )
1441 /*------------------------------------------------------------------------*/
1443 for( i = 0; i < NUM_TX_DESC; i++ ) {
1444 if( lp->dma.tx_packet[i] == NULL ) {
1449 if( i != NUM_TX_DESC ) {
1450 lp->dma.tx_packet[i] = desc;
1451 lp->dma.tx_rsc_ind++;
1453 } // wl_pci_dma_put_tx_packet
1454 /*============================================================================*/
1456 /*******************************************************************************
1457 * wl_pci_dma_hcf_reclaim_tx()
1458 *******************************************************************************
1462 * Reclaim Tx packets that have either been processed by the HCF due to a
1463 * port disable or a Tx completion.
1467 * lp - the device's private adapter structure
1472 * errno value otherwise
1474 ******************************************************************************/
1475 void wl_pci_dma_hcf_reclaim_tx( struct wl_private *lp )
1480 //if( lp->dma.status == 0 )
1482 while ( ( p = hcf_dma_tx_get( &lp->hcfCtx ) ) != NULL ) {
1484 if( p != NULL && p->buf_addr == NULL ) {
1485 /* A Reclaim descriptor is being given back by the HCF. Reclaim
1486 descriptors have a NULL buf_addr */
1487 lp->dma.tx_reclaim_desc = p;
1488 DBG_PRINT( "reclaim_descriptor: 0x%p\n", p );
1491 for( i = 0; i < NUM_TX_DESC; i++ ) {
1492 if( lp->dma.tx_packet[i] == NULL ) {
1496 /* An Rx buffer descriptor is being given back by the HCF */
1497 lp->dma.tx_packet[i] = p;
1498 lp->dma.tx_rsc_ind++;
1499 DBG_PRINT( "tx_packet[%d] 0x%p\n", i, lp->dma.tx_packet[i] );
1503 if( lp->netif_queue_on == FALSE ) {
1504 netif_wake_queue( lp->dev );
1505 WL_WDS_NETIF_WAKE_QUEUE( lp );
1506 lp->netif_queue_on = TRUE;
1508 DBG_LEAVE( DbgInfo );
1510 } // wl_pci_dma_hcf_reclaim_tx
1511 /*============================================================================*/
1512 #endif // ENABLE_DMA