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/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>
79 #include <linux/delay.h>
82 #include <asm/bitops.h>
83 #include <asm/uaccess.h>
85 #include <linux/ethtool.h>
86 #include <linux/netdevice.h>
87 #include <linux/etherdevice.h>
88 #include <linux/skbuff.h>
89 #include <linux/if_arp.h>
90 #include <linux/ioport.h>
92 #include <hcf/debug.h>
98 #include <wireless/wl_if.h>
99 #include <wireless/wl_internal.h>
100 #include <wireless/wl_util.h>
101 #include <wireless/wl_main.h>
102 #include <wireless/wl_netdev.h>
103 #include <wireless/wl_pci.h>
106 /*******************************************************************************
108 ******************************************************************************/
110 extern dbg_info_t *DbgInfo;
113 /* define the PCI device Table Cardname and id tables */
114 static struct pci_device_id wl_pci_tbl[] = {
115 { PCI_DEVICE(PCI_VENDOR_ID_WL_LKM, PCI_DEVICE_ID_WL_LKM_0), },
116 { PCI_DEVICE(PCI_VENDOR_ID_WL_LKM, PCI_DEVICE_ID_WL_LKM_1), },
117 { PCI_DEVICE(PCI_VENDOR_ID_WL_LKM, PCI_DEVICE_ID_WL_LKM_2), },
119 { } /* Terminating entry */
122 MODULE_DEVICE_TABLE(pci, wl_pci_tbl);
124 /*******************************************************************************
125 * function prototypes
126 ******************************************************************************/
127 int wl_pci_probe( struct pci_dev *pdev,
128 const struct pci_device_id *ent );
129 void wl_pci_remove(struct pci_dev *pdev);
130 int wl_pci_setup( struct pci_dev *pdev );
131 void wl_pci_enable_cardbus_interrupts( struct pci_dev *pdev );
134 int wl_pci_dma_alloc( struct pci_dev *pdev, struct wl_private *lp );
135 int wl_pci_dma_free( struct pci_dev *pdev, struct wl_private *lp );
136 int wl_pci_dma_alloc_tx_packet( struct pci_dev *pdev, struct wl_private *lp,
138 int wl_pci_dma_free_tx_packet( struct pci_dev *pdev, struct wl_private *lp,
140 int wl_pci_dma_alloc_rx_packet( struct pci_dev *pdev, struct wl_private *lp,
142 int wl_pci_dma_free_rx_packet( struct pci_dev *pdev, struct wl_private *lp,
144 int wl_pci_dma_alloc_desc_and_buf( struct pci_dev *pdev, struct wl_private *lp,
145 DESC_STRCT **desc, int size );
146 int wl_pci_dma_free_desc_and_buf( struct pci_dev *pdev, struct wl_private *lp,
148 int wl_pci_dma_alloc_desc( struct pci_dev *pdev, struct wl_private *lp,
150 int wl_pci_dma_free_desc( struct pci_dev *pdev, struct wl_private *lp,
152 int wl_pci_dma_alloc_buf( struct pci_dev *pdev, struct wl_private *lp,
153 DESC_STRCT *desc, int size );
154 int wl_pci_dma_free_buf( struct pci_dev *pdev, struct wl_private *lp,
157 void wl_pci_dma_hcf_reclaim_rx( struct wl_private *lp );
160 /*******************************************************************************
161 * PCI module function registration
162 ******************************************************************************/
163 static struct pci_driver wl_driver = {
165 .id_table = wl_pci_tbl,
166 .probe = wl_pci_probe,
167 .remove = wl_pci_remove,
172 /*******************************************************************************
173 * wl_adapter_init_module()
174 *******************************************************************************
178 * Called by init_module() to perform PCI-specific driver initialization.
188 ******************************************************************************/
189 int wl_adapter_init_module( void )
192 /*------------------------------------------------------------------------*/
194 DBG_FUNC( "wl_adapter_init_module()" );
195 DBG_ENTER( DbgInfo );
196 DBG_TRACE( DbgInfo, "wl_adapter_init_module() -- PCI\n" );
198 result = pci_register_driver( &wl_driver ); //;?replace with pci_module_init, Rubini pg 490
199 //;? why not do something with the result
201 DBG_LEAVE( DbgInfo );
203 } // wl_adapter_init_module
204 /*============================================================================*/
206 /*******************************************************************************
207 * wl_adapter_cleanup_module()
208 *******************************************************************************
212 * Called by cleanup_module() to perform PCI-specific driver cleanup.
222 ******************************************************************************/
223 void wl_adapter_cleanup_module( void )
225 //;?how come wl_adapter_cleanup_module is located in a seemingly pci specific module
226 DBG_FUNC( "wl_adapter_cleanup_module" );
227 DBG_ENTER( DbgInfo );
229 //;?DBG_TRACE below feels like nearly redundant in the light of DBG_ENTER above
230 DBG_TRACE( DbgInfo, "wl_adapter_cleanup_module() -- PCI\n" );
232 pci_unregister_driver( &wl_driver );
234 DBG_LEAVE( DbgInfo );
236 } // wl_adapter_cleanup_module
237 /*============================================================================*/
239 /*******************************************************************************
240 * wl_adapter_insert()
241 *******************************************************************************
245 * Called by wl_pci_probe() to continue the process of device insertion.
249 * dev - a pointer to the device's net_device structure
255 ******************************************************************************/
256 int wl_adapter_insert( struct net_device *dev )
259 /*------------------------------------------------------------------------*/
261 DBG_FUNC( "wl_adapter_insert" );
262 DBG_ENTER( DbgInfo );
264 DBG_TRACE( DbgInfo, "wl_adapter_insert() -- PCI\n" );
267 DBG_ERROR( DbgInfo, "net_device pointer is NULL!!!\n" );
268 } else if( dev->priv == NULL ) {
269 DBG_ERROR( DbgInfo, "wl_private pointer is NULL!!!\n" );
270 } else if( wl_insert( dev ) ) { /* Perform remaining device initialization */
273 DBG_TRACE( DbgInfo, "wl_insert() FAILED\n" );
275 DBG_LEAVE( DbgInfo );
277 } // wl_adapter_insert
278 /*============================================================================*/
280 /*******************************************************************************
282 *******************************************************************************
290 * dev - a pointer to the device's net_device structure
296 ******************************************************************************/
297 int wl_adapter_open( struct net_device *dev )
300 int hcf_status = HCF_SUCCESS;
301 /*------------------------------------------------------------------------*/
303 DBG_FUNC( "wl_adapter_open" );
304 DBG_ENTER( DbgInfo );
306 DBG_TRACE( DbgInfo, "wl_adapter_open() -- PCI\n" );
308 hcf_status = wl_open( dev );
310 if( hcf_status != HCF_SUCCESS ) {
314 DBG_LEAVE( DbgInfo );
317 /*============================================================================*/
319 /*******************************************************************************
321 *******************************************************************************
329 * dev - a pointer to the device's net_device structure
335 ******************************************************************************/
336 int wl_adapter_close( struct net_device *dev )
338 DBG_FUNC( "wl_adapter_close" );
339 DBG_ENTER( DbgInfo );
341 DBG_TRACE( DbgInfo, "wl_adapter_close() -- PCI\n" );
342 DBG_TRACE( DbgInfo, "%s: Shutting down adapter.\n", dev->name );
346 DBG_LEAVE( DbgInfo );
348 } // wl_adapter_close
349 /*============================================================================*/
351 /*******************************************************************************
352 * wl_adapter_is_open()
353 *******************************************************************************
357 * Check whether this device is open. Returns
361 * dev - a pointer to the device's net_device structure
365 * nonzero if device is open.
367 ******************************************************************************/
368 int wl_adapter_is_open( struct net_device *dev )
370 /* This function is used in PCMCIA to check the status of the 'open' field
371 in the dev_link_t structure associated with a network device. There
372 doesn't seem to be an analog to this for PCI, and checking the status
373 contained in the net_device structure doesn't have the same effect.
374 For now, return TRUE, but find out if this is necessary for PCI. */
377 } // wl_adapter_is_open
378 /*============================================================================*/
380 /*******************************************************************************
382 *******************************************************************************
386 * Registered in the pci_driver structure, this function is called when the
387 * PCI subsystem finds a new PCI device which matches the information contained
388 * in the pci_device_id table.
392 * pdev - a pointer to the device's pci_dev structure
393 * ent - this device's entry in the pci_device_id table
398 * errno value otherwise
400 ******************************************************************************/
401 int wl_pci_probe( struct pci_dev *pdev,
402 const struct pci_device_id *ent )
405 /*------------------------------------------------------------------------*/
407 DBG_FUNC( "wl_pci_probe" );
408 DBG_ENTER( DbgInfo );
409 DBG_PRINT( "%s\n", VERSION_INFO );
411 result = wl_pci_setup( pdev );
413 DBG_LEAVE( DbgInfo );
417 /*============================================================================*/
419 /*******************************************************************************
421 *******************************************************************************
425 * Registered in the pci_driver structure, this function is called when the
426 * PCI subsystem detects that a PCI device which matches the information
427 * contained in the pci_device_id table has been removed.
431 * pdev - a pointer to the device's pci_dev structure
437 ******************************************************************************/
438 void wl_pci_remove(struct pci_dev *pdev)
440 struct net_device *dev = NULL;
441 /*------------------------------------------------------------------------*/
443 DBG_FUNC( "wl_pci_remove" );
444 DBG_ENTER( DbgInfo );
446 /* Make sure the pci_dev pointer passed in is valid */
448 DBG_ERROR( DbgInfo, "PCI subsys passed in an invalid pci_dev pointer\n" );
452 dev = pci_get_drvdata( pdev );
454 DBG_ERROR( DbgInfo, "Could not retrieve net_device structure\n" );
458 /* Perform device cleanup */
460 free_irq( dev->irq, dev );
463 wl_pci_dma_free( pdev, dev->priv );
466 wl_device_dealloc( dev );
468 DBG_LEAVE( DbgInfo );
471 /*============================================================================*/
473 /*******************************************************************************
475 *******************************************************************************
479 * Called by wl_pci_probe() to begin a device's initialization process.
483 * pdev - a pointer to the device's pci_dev structure
488 * errno value otherwise
490 ******************************************************************************/
491 int wl_pci_setup( struct pci_dev *pdev )
494 struct net_device *dev = NULL;
495 struct wl_private *lp = NULL;
496 /*------------------------------------------------------------------------*/
498 DBG_FUNC( "wl_pci_setup" );
499 DBG_ENTER( DbgInfo );
501 /* Make sure the pci_dev pointer passed in is valid */
503 DBG_ERROR( DbgInfo, "PCI subsys passed in an invalid pci_dev pointer\n" );
507 result = pci_enable_device( pdev );
509 DBG_ERROR( DbgInfo, "pci_enable_device() failed\n" );
510 DBG_LEAVE( DbgInfo );
514 /* We found our device! Let's register it with the system */
515 DBG_TRACE( DbgInfo, "Found our device, now registering\n" );
516 dev = wl_device_alloc( );
518 DBG_ERROR( DbgInfo, "Could not register device!!!\n" );
519 DBG_LEAVE( DbgInfo );
523 /* Make sure that space was allocated for our private adapter struct */
524 if( dev->priv == NULL ) {
525 DBG_ERROR( DbgInfo, "Private adapter struct was not allocated!!!\n" );
526 wl_device_dealloc(dev);
527 DBG_LEAVE( DbgInfo );
532 /* Allocate DMA Descriptors */
533 if( wl_pci_dma_alloc( pdev, dev->priv ) < 0 ) {
534 DBG_ERROR( DbgInfo, "Could not allocate DMA descriptor memory!!!\n" );
535 wl_device_dealloc(dev);
536 DBG_LEAVE( DbgInfo );
541 /* Register our private adapter structure with PCI */
542 pci_set_drvdata( pdev, dev );
544 /* Fill out bus specific information in the net_device struct */
545 dev->irq = pdev->irq;
546 SET_MODULE_OWNER( dev );
548 DBG_TRACE( DbgInfo, "Device Base Address: %#03lx\n", pdev->resource[0].start );
549 dev->base_addr = pdev->resource[0].start;
551 /* Initialize our device here */
552 if( !wl_adapter_insert( dev )) {
553 DBG_ERROR( DbgInfo, "wl_adapter_insert() FAILED!!!\n" );
554 wl_device_dealloc( dev );
555 DBG_LEAVE( DbgInfo );
559 /* Register our ISR */
560 DBG_TRACE( DbgInfo, "Registering ISR...\n" );
562 result = request_irq(dev->irq, wl_isr, SA_SHIRQ, dev->name, dev);
564 DBG_WARNING( DbgInfo, "Could not register ISR!!!\n" );
566 wl_device_dealloc(dev);
567 DBG_LEAVE( DbgInfo );
571 /* Make sure interrupts are enabled properly for CardBus */
574 if( lp->hcfCtx.IFB_BusType == CFG_NIC_BUS_TYPE_CARDBUS ||
575 lp->hcfCtx.IFB_BusType == CFG_NIC_BUS_TYPE_PCI ) {
576 DBG_TRACE( DbgInfo, "This is a PCI/CardBus card, enable interrupts\n" );
577 wl_pci_enable_cardbus_interrupts( pdev );
580 /* Enable bus mastering */
581 pci_set_master( pdev );
583 DBG_LEAVE( DbgInfo );
586 /*============================================================================*/
588 /*******************************************************************************
589 * wl_pci_enable_cardbus_interrupts()
590 *******************************************************************************
594 * Called by wl_pci_setup() to enable interrupts on a CardBus device. This
595 * is done by writing bit 15 to the function event mask register. This
596 * CardBus-specific register is located in BAR2 (counting from BAR0), in memory
597 * space at byte offset 1f4 (7f4 for WARP).
601 * pdev - a pointer to the device's pci_dev structure
607 ******************************************************************************/
608 void wl_pci_enable_cardbus_interrupts( struct pci_dev *pdev )
612 u32 func_evt_mask_reg;
613 void *mem_addr_kern = NULL;
614 /*------------------------------------------------------------------------*/
616 DBG_FUNC( "wl_pci_enable_cardbus_interrupts" );
617 DBG_ENTER( DbgInfo );
619 /* Initialize to known bad values */
620 bar2_reg = 0xdeadbeef;
621 mem_addr_bus = 0xdeadbeef;
623 /* Read the BAR2 register; this register contains the base address of the
624 memory region where the function event mask register lives */
625 pci_read_config_dword( pdev, PCI_BASE_ADDRESS_2, &bar2_reg );
626 mem_addr_bus = bar2_reg & PCI_BASE_ADDRESS_MEM_MASK;
628 /* Once the base address is obtained, remap the memory region to kernel
629 space so we can retrieve the register */
630 mem_addr_kern = ioremap( mem_addr_bus, 0x200 );
633 #define REG_OFFSET 0x07F4
635 #define REG_OFFSET 0x01F4
640 /* Retrieve the functional event mask register, enable interrupts by
641 setting Bit 15, and write back the value */
642 func_evt_mask_reg = *(u32 *)( mem_addr_kern + REG_OFFSET );
643 func_evt_mask_reg |= BIT15;
644 *(u32 *)( mem_addr_kern + REG_OFFSET ) = func_evt_mask_reg;
646 /* Once complete, unmap the region and exit */
647 iounmap( mem_addr_kern );
649 DBG_LEAVE( DbgInfo );
651 } // wl_pci_enable_cardbus_interrupts
652 /*============================================================================*/
655 /*******************************************************************************
657 *******************************************************************************
661 * Allocates all resources needed for PCI/CardBus DMA operation
665 * pdev - a pointer to the device's pci_dev structure
666 * lp - the device's private adapter structure
671 * errno value otherwise
673 ******************************************************************************/
674 int wl_pci_dma_alloc( struct pci_dev *pdev, struct wl_private *lp )
678 /*------------------------------------------------------------------------*/
680 DBG_FUNC( "wl_pci_dma_alloc" );
681 DBG_ENTER( DbgInfo );
683 // lp->dma.tx_rsc_ind = lp->dma.rx_rsc_ind = 0;
685 // /* Alloc for the Tx chain and its reclaim descriptor */
686 // for( i = 0; i < NUM_TX_DESC; i++ ) {
687 // status = wl_pci_dma_alloc_tx_packet( pdev, lp, &lp->dma.tx_packet[i] );
688 // if( status == 0 ) {
689 // DBG_PRINT( "lp->dma.tx_packet[%d] : 0x%p\n", i, lp->dma.tx_packet[i] );
690 // DBG_PRINT( "lp->dma.tx_packet[%d]->next_desc_addr : 0x%p\n", i, lp->dma.tx_packet[i]->next_desc_addr );
691 // lp->dma.tx_rsc_ind++;
693 // DBG_ERROR( DbgInfo, "Could not alloc DMA Tx Packet\n" );
697 // if( status == 0 ) {
698 // status = wl_pci_dma_alloc_desc( pdev, lp, &lp->dma.tx_reclaim_desc );
699 // DBG_PRINT( "lp->dma.tx_reclaim_desc: 0x%p\n", lp->dma.tx_reclaim_desc );
701 // /* Alloc for the Rx chain and its reclaim descriptor */
702 // if( status == 0 ) {
703 // for( i = 0; i < NUM_RX_DESC; i++ ) {
704 // status = wl_pci_dma_alloc_rx_packet( pdev, lp, &lp->dma.rx_packet[i] );
705 // if( status == 0 ) {
706 // DBG_PRINT( "lp->dma.rx_packet[%d] : 0x%p\n", i, lp->dma.rx_packet[i] );
707 // DBG_PRINT( "lp->dma.rx_packet[%d]->next_desc_addr : 0x%p\n", i, lp->dma.rx_packet[i]->next_desc_addr );
708 // lp->dma.rx_rsc_ind++;
710 // DBG_ERROR( DbgInfo, "Could not alloc DMA Rx Packet\n" );
715 // if( status == 0 ) {
716 // status = wl_pci_dma_alloc_desc( pdev, lp, &lp->dma.rx_reclaim_desc );
717 // DBG_PRINT( "lp->dma.rx_reclaim_desc: 0x%p\n", lp->dma.rx_reclaim_desc );
719 // /* Store status, as host should not call HCF functions if this fails */
720 // lp->dma.status = status; //;?all useages of dma.status have been commented out
721 // DBG_LEAVE( DbgInfo );
723 } // wl_pci_dma_alloc
724 /*============================================================================*/
726 /*******************************************************************************
728 *******************************************************************************
732 * Deallocated all resources needed for PCI/CardBus DMA operation
736 * pdev - a pointer to the device's pci_dev structure
737 * lp - the device's private adapter structure
742 * errno value otherwise
744 ******************************************************************************/
745 int wl_pci_dma_free( struct pci_dev *pdev, struct wl_private *lp )
749 /*------------------------------------------------------------------------*/
751 DBG_FUNC( "wl_pci_dma_free" );
752 DBG_ENTER( DbgInfo );
754 /* Reclaim all Rx packets that were handed over to the HCF */
755 /* Do I need to do this? Before this free is called, I've already disabled
756 the port which will call wl_pci_dma_hcf_reclaim */
757 //if( lp->dma.status == 0 )
759 // wl_pci_dma_hcf_reclaim( lp );
762 /* Free everything needed for DMA Rx */
763 for( i = 0; i < NUM_RX_DESC; i++ ) {
764 if( lp->dma.rx_packet[i] ) {
765 status = wl_pci_dma_free_rx_packet( pdev, lp, &lp->dma.rx_packet[i] );
767 DBG_WARNING( DbgInfo, "Problem freeing Rx packet\n" );
771 lp->dma.rx_rsc_ind = 0;
773 if( lp->dma.rx_reclaim_desc ) {
774 status = wl_pci_dma_free_desc( pdev, lp, &lp->dma.rx_reclaim_desc );
776 DBG_WARNING( DbgInfo, "Problem freeing Rx reclaim descriptor\n" );
780 /* Free everything needed for DMA Tx */
781 for( i = 0; i < NUM_TX_DESC; i++ ) {
782 if( lp->dma.tx_packet[i] ) {
783 status = wl_pci_dma_free_tx_packet( pdev, lp, &lp->dma.tx_packet[i] );
785 DBG_WARNING( DbgInfo, "Problem freeing Tx packet\n" );
789 lp->dma.tx_rsc_ind = 0;
791 if( lp->dma.tx_reclaim_desc ) {
792 status = wl_pci_dma_free_desc( pdev, lp, &lp->dma.tx_reclaim_desc );
794 DBG_WARNING( DbgInfo, "Problem freeing Tx reclaim descriptor\n" );
798 DBG_LEAVE( DbgInfo );
802 /*============================================================================*/
804 /*******************************************************************************
805 * wl_pci_dma_alloc_tx_packet()
806 *******************************************************************************
810 * Allocates a single Tx packet, consisting of several descriptors and
811 * buffers. Data to transmit is first copied into the 'payload' buffer
812 * before being transmitted.
816 * pdev - a pointer to the device's pci_dev structure
817 * lp - the device's private adapter structure
818 * desc - a pointer which will reference the descriptor to be alloc'd.
823 * errno value otherwise
825 ******************************************************************************/
826 int wl_pci_dma_alloc_tx_packet( struct pci_dev *pdev, struct wl_private *lp,
830 // /*------------------------------------------------------------------------*/
832 // if( desc == NULL ) {
835 // if( status == 0 ) {
836 // status = wl_pci_dma_alloc_desc_and_buf( pdev, lp, desc,
837 // HCF_DMA_TX_BUF1_SIZE );
839 // if( status == 0 ) {
840 // status = wl_pci_dma_alloc_desc_and_buf( pdev, lp,
841 // &( (*desc)->next_desc_addr ),
842 // HCF_MAX_PACKET_SIZE );
845 // if( status == 0 ) {
846 // (*desc)->next_desc_phys_addr = (*desc)->next_desc_addr->desc_phys_addr;
849 } // wl_pci_dma_alloc_tx_packet
850 /*============================================================================*/
852 /*******************************************************************************
853 * wl_pci_dma_free_tx_packet()
854 *******************************************************************************
858 * Frees a single Tx packet, described in the corresponding alloc function.
862 * pdev - a pointer to the device's pci_dev structure
863 * lp - the device's private adapter structure
864 * desc - a pointer which will reference the descriptor to be alloc'd.
869 * errno value otherwise
871 ******************************************************************************/
872 int wl_pci_dma_free_tx_packet( struct pci_dev *pdev, struct wl_private *lp,
876 /*------------------------------------------------------------------------*/
878 if( *desc == NULL ) {
879 DBG_PRINT( "Null descriptor\n" );
882 //;?the "limited" NDIS strategy, assuming a frame consists ALWAYS out of 2
883 //descriptors, make this robust
884 if( status == 0 && (*desc)->next_desc_addr ) {
885 status = wl_pci_dma_free_desc_and_buf( pdev, lp, &(*desc)->next_desc_addr );
888 status = wl_pci_dma_free_desc_and_buf( pdev, lp, desc );
891 } // wl_pci_dma_free_tx_packet
892 /*============================================================================*/
894 /*******************************************************************************
895 * wl_pci_dma_alloc_rx_packet()
896 *******************************************************************************
900 * Allocates a single Rx packet, consisting of two descriptors and one
901 * contiguous buffer. The buffer starts with the hermes-specific header.
902 * One descriptor points at the start, the other at offset 0x3a of the
907 * pdev - a pointer to the device's pci_dev structure
908 * lp - the device's private adapter structure
909 * desc - a pointer which will reference the descriptor to be alloc'd.
914 * errno value otherwise
916 ******************************************************************************/
917 int wl_pci_dma_alloc_rx_packet( struct pci_dev *pdev, struct wl_private *lp,
922 /*------------------------------------------------------------------------*/
924 // if( desc == NULL ) {
927 // //;?the "limited" NDIS strategy, assuming a frame consists ALWAYS out of 2
928 // //descriptors, make this robust
929 // if( status == 0 ) {
930 // status = wl_pci_dma_alloc_desc( pdev, lp, desc );
932 // if( status == 0 ) {
933 // status = wl_pci_dma_alloc_buf( pdev, lp, *desc, HCF_MAX_PACKET_SIZE );
935 // if( status == 0 ) {
936 // status = wl_pci_dma_alloc_desc( pdev, lp, &p );
938 // if( status == 0 ) {
939 // /* Size of 1st descriptor becomes 0x3a bytes */
940 // SET_BUF_SIZE( *desc, HCF_DMA_RX_BUF1_SIZE );
942 // /* Make 2nd descriptor point at offset 0x3a of the buffer */
943 // SET_BUF_SIZE( p, ( HCF_MAX_PACKET_SIZE - HCF_DMA_RX_BUF1_SIZE ));
944 // p->buf_addr = (*desc)->buf_addr + HCF_DMA_RX_BUF1_SIZE;
945 // p->buf_phys_addr = (*desc)->buf_phys_addr + HCF_DMA_RX_BUF1_SIZE;
946 // p->next_desc_addr = NULL;
948 // /* Chain 2nd descriptor to 1st descriptor */
949 // (*desc)->next_desc_addr = p;
950 // (*desc)->next_desc_phys_addr = p->desc_phys_addr;
954 } // wl_pci_dma_alloc_rx_packet
955 /*============================================================================*/
957 /*******************************************************************************
958 * wl_pci_dma_free_rx_packet()
959 *******************************************************************************
963 * Frees a single Rx packet, described in the corresponding alloc function.
967 * pdev - a pointer to the device's pci_dev structure
968 * lp - the device's private adapter structure
969 * desc - a pointer which will reference the descriptor to be alloc'd.
974 * errno value otherwise
976 ******************************************************************************/
977 int wl_pci_dma_free_rx_packet( struct pci_dev *pdev, struct wl_private *lp,
982 /*------------------------------------------------------------------------*/
984 if( *desc == NULL ) {
988 p = (*desc)->next_desc_addr;
990 /* Free the 2nd descriptor */
993 p->buf_phys_addr = 0;
995 status = wl_pci_dma_free_desc( pdev, lp, &p );
999 /* Free the buffer and 1st descriptor */
1001 SET_BUF_SIZE( *desc, HCF_MAX_PACKET_SIZE );
1002 status = wl_pci_dma_free_desc_and_buf( pdev, lp, desc );
1005 } // wl_pci_dma_free_rx_packet
1006 /*============================================================================*/
1008 /*******************************************************************************
1009 * wl_pci_dma_alloc_desc_and_buf()
1010 *******************************************************************************
1014 * Allocates a DMA descriptor and buffer, and associates them with one
1019 * pdev - a pointer to the device's pci_dev structure
1020 * lp - the device's private adapter structure
1021 * desc - a pointer which will reference the descriptor to be alloc'd
1026 * errno value otherwise
1028 ******************************************************************************/
1029 int wl_pci_dma_alloc_desc_and_buf( struct pci_dev *pdev, struct wl_private *lp,
1030 DESC_STRCT **desc, int size )
1033 /*------------------------------------------------------------------------*/
1035 // if( desc == NULL ) {
1036 // status = -EFAULT;
1038 // if( status == 0 ) {
1039 // status = wl_pci_dma_alloc_desc( pdev, lp, desc );
1041 // if( status == 0 ) {
1042 // status = wl_pci_dma_alloc_buf( pdev, lp, *desc, size );
1046 } // wl_pci_dma_alloc_desc_and_buf
1047 /*============================================================================*/
1049 /*******************************************************************************
1050 * wl_pci_dma_free_desc_and_buf()
1051 *******************************************************************************
1055 * Frees a DMA descriptor and associated buffer.
1059 * pdev - a pointer to the device's pci_dev structure
1060 * lp - the device's private adapter structure
1061 * desc - a pointer which will reference the descriptor to be alloc'd
1066 * errno value otherwise
1068 ******************************************************************************/
1069 int wl_pci_dma_free_desc_and_buf( struct pci_dev *pdev, struct wl_private *lp,
1073 /*------------------------------------------------------------------------*/
1075 if( desc == NULL ) {
1078 if( status == 0 && *desc == NULL ) {
1082 status = wl_pci_dma_free_buf( pdev, lp, *desc );
1085 status = wl_pci_dma_free_desc( pdev, lp, desc );
1089 } // wl_pci_dma_free_desc_and_buf
1090 /*============================================================================*/
1092 /*******************************************************************************
1093 * wl_pci_dma_alloc_desc()
1094 *******************************************************************************
1098 * Allocates one DMA descriptor in cache coherent memory.
1102 * pdev - a pointer to the device's pci_dev structure
1103 * lp - the device's private adapter structure
1108 * errno value otherwise
1110 ******************************************************************************/
1111 int wl_pci_dma_alloc_desc( struct pci_dev *pdev, struct wl_private *lp,
1116 // /*------------------------------------------------------------------------*/
1118 // DBG_FUNC( "wl_pci_dma_alloc_desc" );
1119 // DBG_ENTER( DbgInfo );
1121 // if( desc == NULL ) {
1122 // status = -EFAULT;
1124 // if( status == 0 ) {
1125 // *desc = pci_alloc_consistent( pdev, sizeof( DESC_STRCT ), &pa );
1127 // if( *desc == NULL ) {
1128 // DBG_ERROR( DbgInfo, "pci_alloc_consistent() failed\n" );
1129 // status = -ENOMEM;
1131 // memset( *desc, 0, sizeof( DESC_STRCT ));
1132 // (*desc)->desc_phys_addr = cpu_to_le32( pa );
1134 // DBG_LEAVE( DbgInfo );
1136 } // wl_pci_dma_alloc_desc
1137 /*============================================================================*/
1139 /*******************************************************************************
1140 * wl_pci_dma_free_desc()
1141 *******************************************************************************
1145 * Frees one DMA descriptor in cache coherent memory.
1149 * pdev - a pointer to the device's pci_dev structure
1150 * lp - the device's private adapter structure
1155 * errno value otherwise
1157 ******************************************************************************/
1158 int wl_pci_dma_free_desc( struct pci_dev *pdev, struct wl_private *lp,
1162 /*------------------------------------------------------------------------*/
1164 if( *desc == NULL ) {
1168 pci_free_consistent( pdev, sizeof( DESC_STRCT ), *desc,
1169 (*desc)->desc_phys_addr );
1173 } // wl_pci_dma_free_desc
1174 /*============================================================================*/
1176 /*******************************************************************************
1177 * wl_pci_dma_alloc_buf()
1178 *******************************************************************************
1182 * Allocates one DMA buffer in cache coherent memory, and associates a DMA
1183 * descriptor with this buffer.
1187 * pdev - a pointer to the device's pci_dev structure
1188 * lp - the device's private adapter structure
1193 * errno value otherwise
1195 ******************************************************************************/
1196 int wl_pci_dma_alloc_buf( struct pci_dev *pdev, struct wl_private *lp,
1197 DESC_STRCT *desc, int size )
1201 /*------------------------------------------------------------------------*/
1203 // DBG_FUNC( "wl_pci_dma_alloc_buf" );
1204 // DBG_ENTER( DbgInfo );
1206 // if( desc == NULL ) {
1207 // status = -EFAULT;
1209 // if( status == 0 && desc->buf_addr != NULL ) {
1210 // status = -EFAULT;
1212 // if( status == 0 ) {
1213 // desc->buf_addr = pci_alloc_consistent( pdev, size, &pa );
1215 // if( desc->buf_addr == NULL ) {
1216 // DBG_ERROR( DbgInfo, "pci_alloc_consistent() failed\n" );
1217 // status = -ENOMEM;
1219 // desc->buf_phys_addr = cpu_to_le32( pa );
1220 // SET_BUF_SIZE( desc, size );
1222 // DBG_LEAVE( DbgInfo );
1224 } // wl_pci_dma_alloc_buf
1225 /*============================================================================*/
1227 /*******************************************************************************
1228 * wl_pci_dma_free_buf()
1229 *******************************************************************************
1233 * Allocates one DMA buffer in cache coherent memory, and associates a DMA
1234 * descriptor with this buffer.
1238 * pdev - a pointer to the device's pci_dev structure
1239 * lp - the device's private adapter structure
1244 * errno value otherwise
1246 ******************************************************************************/
1247 int wl_pci_dma_free_buf( struct pci_dev *pdev, struct wl_private *lp,
1251 /*------------------------------------------------------------------------*/
1253 if( desc == NULL ) {
1256 if( status == 0 && desc->buf_addr == NULL ) {
1260 pci_free_consistent( pdev, GET_BUF_SIZE( desc ), desc->buf_addr,
1261 desc->buf_phys_addr );
1264 desc->buf_phys_addr = 0;
1265 SET_BUF_SIZE( desc, 0 );
1268 } // wl_pci_dma_free_buf
1269 /*============================================================================*/
1271 /*******************************************************************************
1272 * wl_pci_dma_hcf_supply()
1273 *******************************************************************************
1277 * Supply HCF with DMA-related resources. These consist of:
1278 * - buffers and descriptors for receive purposes
1279 * - one 'reclaim' descriptor for the transmit path, used to fulfill a
1280 * certain H25 DMA engine requirement
1281 * - one 'reclaim' descriptor for the receive path, used to fulfill a
1282 * certain H25 DMA engine requirement
1284 * This function is called at start-of-day or at re-initialization.
1288 * lp - the device's private adapter structure
1293 * errno value otherwise
1295 ******************************************************************************/
1296 void wl_pci_dma_hcf_supply( struct wl_private *lp )
1299 /*------------------------------------------------------------------------*/
1301 DBG_FUNC( "wl_pci_dma_hcf_supply" );
1302 DBG_ENTER( DbgInfo );
1304 //if( lp->dma.status == 0 );
1306 /* Hand over the Rx/Tx reclaim descriptors to the HCF */
1307 if( lp->dma.tx_reclaim_desc ) {
1308 DBG_PRINT( "lp->dma.tx_reclaim_desc: 0x%p\n", lp->dma.tx_reclaim_desc );
1309 hcf_dma_tx_put( &lp->hcfCtx, lp->dma.tx_reclaim_desc, 0 );
1310 lp->dma.tx_reclaim_desc = NULL;
1311 DBG_PRINT( "lp->dma.tx_reclaim_desc: 0x%p\n", lp->dma.tx_reclaim_desc );
1313 if( lp->dma.rx_reclaim_desc ) {
1314 DBG_PRINT( "lp->dma.rx_reclaim_desc: 0x%p\n", lp->dma.rx_reclaim_desc );
1315 hcf_dma_rx_put( &lp->hcfCtx, lp->dma.rx_reclaim_desc );
1316 lp->dma.rx_reclaim_desc = NULL;
1317 DBG_PRINT( "lp->dma.rx_reclaim_desc: 0x%p\n", lp->dma.rx_reclaim_desc );
1319 /* Hand over the Rx descriptor chain to the HCF */
1320 for( i = 0; i < NUM_RX_DESC; i++ ) {
1321 DBG_PRINT( "lp->dma.rx_packet[%d]: 0x%p\n", i, lp->dma.rx_packet[i] );
1322 hcf_dma_rx_put( &lp->hcfCtx, lp->dma.rx_packet[i] );
1323 lp->dma.rx_packet[i] = NULL;
1324 DBG_PRINT( "lp->dma.rx_packet[%d]: 0x%p\n", i, lp->dma.rx_packet[i] );
1328 DBG_LEAVE( DbgInfo );
1330 } // wl_pci_dma_hcf_supply
1331 /*============================================================================*/
1333 /*******************************************************************************
1334 * wl_pci_dma_hcf_reclaim()
1335 *******************************************************************************
1339 * Return DMA-related resources from the HCF. These consist of:
1340 * - buffers and descriptors for receive purposes
1341 * - buffers and descriptors for transmit purposes
1342 * - one 'reclaim' descriptor for the transmit path, used to fulfill a
1343 * certain H25 DMA engine requirement
1344 * - one 'reclaim' descriptor for the receive path, used to fulfill a
1345 * certain H25 DMA engine requirement
1347 * This function is called at end-of-day or at re-initialization.
1351 * lp - the device's private adapter structure
1356 * errno value otherwise
1358 ******************************************************************************/
1359 void wl_pci_dma_hcf_reclaim( struct wl_private *lp )
1362 /*------------------------------------------------------------------------*/
1364 DBG_FUNC( "wl_pci_dma_hcf_reclaim" );
1365 DBG_ENTER( DbgInfo );
1367 wl_pci_dma_hcf_reclaim_rx( lp );
1368 for( i = 0; i < NUM_RX_DESC; i++ ) {
1369 DBG_PRINT( "rx_packet[%d] 0x%p\n", i, lp->dma.rx_packet[i] );
1370 // if( lp->dma.rx_packet[i] == NULL ) {
1371 // DBG_PRINT( "wl_pci_dma_hcf_reclaim: rx_packet[%d] NULL\n", i );
1375 wl_pci_dma_hcf_reclaim_tx( lp );
1376 for( i = 0; i < NUM_TX_DESC; i++ ) {
1377 DBG_PRINT( "tx_packet[%d] 0x%p\n", i, lp->dma.tx_packet[i] );
1378 // if( lp->dma.tx_packet[i] == NULL ) {
1379 // DBG_PRINT( "wl_pci_dma_hcf_reclaim: tx_packet[%d] NULL\n", i );
1383 DBG_LEAVE( DbgInfo );
1385 } // wl_pci_dma_hcf_reclaim
1386 /*============================================================================*/
1388 /*******************************************************************************
1389 * wl_pci_dma_hcf_reclaim_rx()
1390 *******************************************************************************
1394 * Reclaim Rx packets that have already been processed by the HCF.
1398 * lp - the device's private adapter structure
1403 * errno value otherwise
1405 ******************************************************************************/
1406 void wl_pci_dma_hcf_reclaim_rx( struct wl_private *lp )
1410 /*------------------------------------------------------------------------*/
1412 DBG_FUNC( "wl_pci_dma_hcf_reclaim_rx" );
1413 DBG_ENTER( DbgInfo );
1415 //if( lp->dma.status == 0 )
1417 while ( ( p = hcf_dma_rx_get( &lp->hcfCtx ) ) != NULL ) {
1418 if( p && p->buf_addr == NULL ) {
1419 /* A reclaim descriptor is being given back by the HCF. Reclaim
1420 descriptors have a NULL buf_addr */
1421 lp->dma.rx_reclaim_desc = p;
1422 DBG_PRINT( "reclaim_descriptor: 0x%p\n", p );
1425 for( i = 0; i < NUM_RX_DESC; i++ ) {
1426 if( lp->dma.rx_packet[i] == NULL ) {
1430 /* An Rx buffer descriptor is being given back by the HCF */
1431 lp->dma.rx_packet[i] = p;
1432 lp->dma.rx_rsc_ind++;
1433 DBG_PRINT( "rx_packet[%d] 0x%p\n", i, lp->dma.rx_packet[i] );
1436 DBG_LEAVE( DbgInfo );
1437 } // wl_pci_dma_hcf_reclaim_rx
1438 /*============================================================================*/
1440 /*******************************************************************************
1441 * wl_pci_dma_get_tx_packet()
1442 *******************************************************************************
1446 * Obtains a Tx descriptor from the chain to use for Tx.
1450 * lp - a pointer to the device's wl_private structure.
1454 * A pointer to the retrieved descriptor
1456 ******************************************************************************/
1457 DESC_STRCT * wl_pci_dma_get_tx_packet( struct wl_private *lp )
1460 DESC_STRCT *desc = NULL;
1461 /*------------------------------------------------------------------------*/
1463 for( i = 0; i < NUM_TX_DESC; i++ ) {
1464 if( lp->dma.tx_packet[i] ) {
1469 if( i != NUM_TX_DESC ) {
1470 desc = lp->dma.tx_packet[i];
1472 lp->dma.tx_packet[i] = NULL;
1473 lp->dma.tx_rsc_ind--;
1475 memset( desc->buf_addr, 0, HCF_DMA_TX_BUF1_SIZE );
1479 } // wl_pci_dma_get_tx_packet
1480 /*============================================================================*/
1482 /*******************************************************************************
1483 * wl_pci_dma_put_tx_packet()
1484 *******************************************************************************
1488 * Returns a Tx descriptor to the chain.
1492 * lp - a pointer to the device's wl_private structure.
1493 * desc - a pointer to the descriptor to return.
1499 ******************************************************************************/
1500 void wl_pci_dma_put_tx_packet( struct wl_private *lp, DESC_STRCT *desc )
1503 /*------------------------------------------------------------------------*/
1505 for( i = 0; i < NUM_TX_DESC; i++ ) {
1506 if( lp->dma.tx_packet[i] == NULL ) {
1511 if( i != NUM_TX_DESC ) {
1512 lp->dma.tx_packet[i] = desc;
1513 lp->dma.tx_rsc_ind++;
1515 } // wl_pci_dma_put_tx_packet
1516 /*============================================================================*/
1518 /*******************************************************************************
1519 * wl_pci_dma_hcf_reclaim_tx()
1520 *******************************************************************************
1524 * Reclaim Tx packets that have either been processed by the HCF due to a
1525 * port disable or a Tx completion.
1529 * lp - the device's private adapter structure
1534 * errno value otherwise
1536 ******************************************************************************/
1537 void wl_pci_dma_hcf_reclaim_tx( struct wl_private *lp )
1541 /*------------------------------------------------------------------------*/
1543 DBG_FUNC( "wl_pci_dma_hcf_reclaim_tx" );
1544 DBG_ENTER( DbgInfo );
1546 //if( lp->dma.status == 0 )
1548 while ( ( p = hcf_dma_tx_get( &lp->hcfCtx ) ) != NULL ) {
1550 if( p != NULL && p->buf_addr == NULL ) {
1551 /* A Reclaim descriptor is being given back by the HCF. Reclaim
1552 descriptors have a NULL buf_addr */
1553 lp->dma.tx_reclaim_desc = p;
1554 DBG_PRINT( "reclaim_descriptor: 0x%p\n", p );
1557 for( i = 0; i < NUM_TX_DESC; i++ ) {
1558 if( lp->dma.tx_packet[i] == NULL ) {
1562 /* An Rx buffer descriptor is being given back by the HCF */
1563 lp->dma.tx_packet[i] = p;
1564 lp->dma.tx_rsc_ind++;
1565 DBG_PRINT( "tx_packet[%d] 0x%p\n", i, lp->dma.tx_packet[i] );
1569 if( lp->netif_queue_on == FALSE ) {
1570 netif_wake_queue( lp->dev );
1571 WL_WDS_NETIF_WAKE_QUEUE( lp );
1572 lp->netif_queue_on = TRUE;
1574 DBG_LEAVE( DbgInfo );
1576 } // wl_pci_dma_hcf_reclaim_tx
1577 /*============================================================================*/
1578 #endif // ENABLE_DMA