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
198 } // wl_adapter_init_module
199 /*============================================================================*/
201 /*******************************************************************************
202 * wl_adapter_cleanup_module()
203 *******************************************************************************
207 * Called by cleanup_module() to perform PCI-specific driver cleanup.
217 ******************************************************************************/
218 void wl_adapter_cleanup_module( void )
220 //;?how come wl_adapter_cleanup_module is located in a seemingly pci specific module
221 DBG_TRACE( DbgInfo, "wl_adapter_cleanup_module() -- PCI\n" );
223 pci_unregister_driver( &wl_driver );
226 } // wl_adapter_cleanup_module
227 /*============================================================================*/
229 /*******************************************************************************
230 * wl_adapter_insert()
231 *******************************************************************************
235 * Called by wl_pci_probe() to continue the process of device insertion.
239 * dev - a pointer to the device's net_device structure
245 ******************************************************************************/
246 int wl_adapter_insert( struct net_device *dev )
250 DBG_TRACE( DbgInfo, "wl_adapter_insert() -- PCI\n" );
253 DBG_ERROR( DbgInfo, "net_device pointer is NULL!!!\n" );
254 } else if( dev->priv == NULL ) {
255 DBG_ERROR( DbgInfo, "wl_private pointer is NULL!!!\n" );
256 } else if( wl_insert( dev ) ) { /* Perform remaining device initialization */
259 DBG_TRACE( DbgInfo, "wl_insert() FAILED\n" );
262 } // wl_adapter_insert
263 /*============================================================================*/
265 /*******************************************************************************
267 *******************************************************************************
275 * dev - a pointer to the device's net_device structure
281 ******************************************************************************/
282 int wl_adapter_open( struct net_device *dev )
285 int hcf_status = HCF_SUCCESS;
287 DBG_TRACE( DbgInfo, "wl_adapter_open() -- PCI\n" );
289 hcf_status = wl_open( dev );
291 if( hcf_status != HCF_SUCCESS ) {
297 /*============================================================================*/
299 /*******************************************************************************
301 *******************************************************************************
309 * dev - a pointer to the device's net_device structure
315 ******************************************************************************/
316 int wl_adapter_close( struct net_device *dev )
318 DBG_TRACE( DbgInfo, "wl_adapter_close() -- PCI\n" );
319 DBG_TRACE( DbgInfo, "%s: Shutting down adapter.\n", dev->name );
324 } // wl_adapter_close
325 /*============================================================================*/
327 /*******************************************************************************
328 * wl_adapter_is_open()
329 *******************************************************************************
333 * Check whether this device is open. Returns
337 * dev - a pointer to the device's net_device structure
341 * nonzero if device is open.
343 ******************************************************************************/
344 int wl_adapter_is_open( struct net_device *dev )
346 /* This function is used in PCMCIA to check the status of the 'open' field
347 in the dev_link_t structure associated with a network device. There
348 doesn't seem to be an analog to this for PCI, and checking the status
349 contained in the net_device structure doesn't have the same effect.
350 For now, return TRUE, but find out if this is necessary for PCI. */
353 } // wl_adapter_is_open
354 /*============================================================================*/
356 /*******************************************************************************
358 *******************************************************************************
362 * Registered in the pci_driver structure, this function is called when the
363 * PCI subsystem finds a new PCI device which matches the information contained
364 * in the pci_device_id table.
368 * pdev - a pointer to the device's pci_dev structure
369 * ent - this device's entry in the pci_device_id table
374 * errno value otherwise
376 ******************************************************************************/
377 int wl_pci_probe( struct pci_dev *pdev,
378 const struct pci_device_id *ent )
382 DBG_PRINT( "%s\n", VERSION_INFO );
384 result = wl_pci_setup( pdev );
388 /*============================================================================*/
390 /*******************************************************************************
392 *******************************************************************************
396 * Registered in the pci_driver structure, this function is called when the
397 * PCI subsystem detects that a PCI device which matches the information
398 * contained in the pci_device_id table has been removed.
402 * pdev - a pointer to the device's pci_dev structure
408 ******************************************************************************/
409 void wl_pci_remove(struct pci_dev *pdev)
411 struct net_device *dev = NULL;
413 /* Make sure the pci_dev pointer passed in is valid */
415 DBG_ERROR( DbgInfo, "PCI subsys passed in an invalid pci_dev pointer\n" );
419 dev = pci_get_drvdata( pdev );
421 DBG_ERROR( DbgInfo, "Could not retrieve net_device structure\n" );
425 /* Perform device cleanup */
427 free_irq( dev->irq, dev );
430 wl_pci_dma_free( pdev, dev->priv );
433 wl_device_dealloc( dev );
437 /*============================================================================*/
439 /*******************************************************************************
441 *******************************************************************************
445 * Called by wl_pci_probe() to begin a device's initialization process.
449 * pdev - a pointer to the device's pci_dev structure
454 * errno value otherwise
456 ******************************************************************************/
457 int wl_pci_setup( struct pci_dev *pdev )
460 struct net_device *dev = NULL;
461 struct wl_private *lp = NULL;
463 /* Make sure the pci_dev pointer passed in is valid */
465 DBG_ERROR( DbgInfo, "PCI subsys passed in an invalid pci_dev pointer\n" );
469 result = pci_enable_device( pdev );
471 DBG_ERROR( DbgInfo, "pci_enable_device() failed\n" );
475 /* We found our device! Let's register it with the system */
476 DBG_TRACE( DbgInfo, "Found our device, now registering\n" );
477 dev = wl_device_alloc( );
479 DBG_ERROR( DbgInfo, "Could not register device!!!\n" );
483 /* Make sure that space was allocated for our private adapter struct */
484 if( dev->priv == NULL ) {
485 DBG_ERROR( DbgInfo, "Private adapter struct was not allocated!!!\n" );
486 wl_device_dealloc(dev);
491 /* Allocate DMA Descriptors */
492 if( wl_pci_dma_alloc( pdev, dev->priv ) < 0 ) {
493 DBG_ERROR( DbgInfo, "Could not allocate DMA descriptor memory!!!\n" );
494 wl_device_dealloc(dev);
499 /* Register our private adapter structure with PCI */
500 pci_set_drvdata( pdev, dev );
502 /* Fill out bus specific information in the net_device struct */
503 dev->irq = pdev->irq;
504 SET_MODULE_OWNER( dev );
506 DBG_TRACE( DbgInfo, "Device Base Address: %#03lx\n", pdev->resource[0].start );
507 dev->base_addr = pdev->resource[0].start;
509 /* Initialize our device here */
510 if( !wl_adapter_insert( dev )) {
511 DBG_ERROR( DbgInfo, "wl_adapter_insert() FAILED!!!\n" );
512 wl_device_dealloc( dev );
516 /* Register our ISR */
517 DBG_TRACE( DbgInfo, "Registering ISR...\n" );
519 result = request_irq(dev->irq, wl_isr, SA_SHIRQ, dev->name, dev);
521 DBG_WARNING( DbgInfo, "Could not register ISR!!!\n" );
523 wl_device_dealloc(dev);
527 /* Make sure interrupts are enabled properly for CardBus */
530 if( lp->hcfCtx.IFB_BusType == CFG_NIC_BUS_TYPE_CARDBUS ||
531 lp->hcfCtx.IFB_BusType == CFG_NIC_BUS_TYPE_PCI ) {
532 DBG_TRACE( DbgInfo, "This is a PCI/CardBus card, enable interrupts\n" );
533 wl_pci_enable_cardbus_interrupts( pdev );
536 /* Enable bus mastering */
537 pci_set_master( pdev );
541 /*============================================================================*/
543 /*******************************************************************************
544 * wl_pci_enable_cardbus_interrupts()
545 *******************************************************************************
549 * Called by wl_pci_setup() to enable interrupts on a CardBus device. This
550 * is done by writing bit 15 to the function event mask register. This
551 * CardBus-specific register is located in BAR2 (counting from BAR0), in memory
552 * space at byte offset 1f4 (7f4 for WARP).
556 * pdev - a pointer to the device's pci_dev structure
562 ******************************************************************************/
563 void wl_pci_enable_cardbus_interrupts( struct pci_dev *pdev )
567 u32 func_evt_mask_reg;
568 void *mem_addr_kern = NULL;
570 /* Initialize to known bad values */
571 bar2_reg = 0xdeadbeef;
572 mem_addr_bus = 0xdeadbeef;
574 /* Read the BAR2 register; this register contains the base address of the
575 memory region where the function event mask register lives */
576 pci_read_config_dword( pdev, PCI_BASE_ADDRESS_2, &bar2_reg );
577 mem_addr_bus = bar2_reg & PCI_BASE_ADDRESS_MEM_MASK;
579 /* Once the base address is obtained, remap the memory region to kernel
580 space so we can retrieve the register */
581 mem_addr_kern = ioremap( mem_addr_bus, 0x200 );
584 #define REG_OFFSET 0x07F4
586 #define REG_OFFSET 0x01F4
591 /* Retrieve the functional event mask register, enable interrupts by
592 setting Bit 15, and write back the value */
593 func_evt_mask_reg = *(u32 *)( mem_addr_kern + REG_OFFSET );
594 func_evt_mask_reg |= BIT15;
595 *(u32 *)( mem_addr_kern + REG_OFFSET ) = func_evt_mask_reg;
597 /* Once complete, unmap the region and exit */
598 iounmap( mem_addr_kern );
599 } // wl_pci_enable_cardbus_interrupts
600 /*============================================================================*/
603 /*******************************************************************************
605 *******************************************************************************
609 * Allocates all resources needed for PCI/CardBus DMA operation
613 * pdev - a pointer to the device's pci_dev structure
614 * lp - the device's private adapter structure
619 * errno value otherwise
621 ******************************************************************************/
622 int wl_pci_dma_alloc( struct pci_dev *pdev, struct wl_private *lp )
627 // lp->dma.tx_rsc_ind = lp->dma.rx_rsc_ind = 0;
629 // /* Alloc for the Tx chain and its reclaim descriptor */
630 // for( i = 0; i < NUM_TX_DESC; i++ ) {
631 // status = wl_pci_dma_alloc_tx_packet( pdev, lp, &lp->dma.tx_packet[i] );
632 // if( status == 0 ) {
633 // DBG_PRINT( "lp->dma.tx_packet[%d] : 0x%p\n", i, lp->dma.tx_packet[i] );
634 // DBG_PRINT( "lp->dma.tx_packet[%d]->next_desc_addr : 0x%p\n", i, lp->dma.tx_packet[i]->next_desc_addr );
635 // lp->dma.tx_rsc_ind++;
637 // DBG_ERROR( DbgInfo, "Could not alloc DMA Tx Packet\n" );
641 // if( status == 0 ) {
642 // status = wl_pci_dma_alloc_desc( pdev, lp, &lp->dma.tx_reclaim_desc );
643 // DBG_PRINT( "lp->dma.tx_reclaim_desc: 0x%p\n", lp->dma.tx_reclaim_desc );
645 // /* Alloc for the Rx chain and its reclaim descriptor */
646 // if( status == 0 ) {
647 // for( i = 0; i < NUM_RX_DESC; i++ ) {
648 // status = wl_pci_dma_alloc_rx_packet( pdev, lp, &lp->dma.rx_packet[i] );
649 // if( status == 0 ) {
650 // DBG_PRINT( "lp->dma.rx_packet[%d] : 0x%p\n", i, lp->dma.rx_packet[i] );
651 // DBG_PRINT( "lp->dma.rx_packet[%d]->next_desc_addr : 0x%p\n", i, lp->dma.rx_packet[i]->next_desc_addr );
652 // lp->dma.rx_rsc_ind++;
654 // DBG_ERROR( DbgInfo, "Could not alloc DMA Rx Packet\n" );
659 // if( status == 0 ) {
660 // status = wl_pci_dma_alloc_desc( pdev, lp, &lp->dma.rx_reclaim_desc );
661 // DBG_PRINT( "lp->dma.rx_reclaim_desc: 0x%p\n", lp->dma.rx_reclaim_desc );
663 // /* Store status, as host should not call HCF functions if this fails */
664 // lp->dma.status = status; //;?all useages of dma.status have been commented out
666 } // wl_pci_dma_alloc
667 /*============================================================================*/
669 /*******************************************************************************
671 *******************************************************************************
675 * Deallocated all resources needed for PCI/CardBus DMA operation
679 * pdev - a pointer to the device's pci_dev structure
680 * lp - the device's private adapter structure
685 * errno value otherwise
687 ******************************************************************************/
688 int wl_pci_dma_free( struct pci_dev *pdev, struct wl_private *lp )
693 /* Reclaim all Rx packets that were handed over to the HCF */
694 /* Do I need to do this? Before this free is called, I've already disabled
695 the port which will call wl_pci_dma_hcf_reclaim */
696 //if( lp->dma.status == 0 )
698 // wl_pci_dma_hcf_reclaim( lp );
701 /* Free everything needed for DMA Rx */
702 for( i = 0; i < NUM_RX_DESC; i++ ) {
703 if( lp->dma.rx_packet[i] ) {
704 status = wl_pci_dma_free_rx_packet( pdev, lp, &lp->dma.rx_packet[i] );
706 DBG_WARNING( DbgInfo, "Problem freeing Rx packet\n" );
710 lp->dma.rx_rsc_ind = 0;
712 if( lp->dma.rx_reclaim_desc ) {
713 status = wl_pci_dma_free_desc( pdev, lp, &lp->dma.rx_reclaim_desc );
715 DBG_WARNING( DbgInfo, "Problem freeing Rx reclaim descriptor\n" );
719 /* Free everything needed for DMA Tx */
720 for( i = 0; i < NUM_TX_DESC; i++ ) {
721 if( lp->dma.tx_packet[i] ) {
722 status = wl_pci_dma_free_tx_packet( pdev, lp, &lp->dma.tx_packet[i] );
724 DBG_WARNING( DbgInfo, "Problem freeing Tx packet\n" );
728 lp->dma.tx_rsc_ind = 0;
730 if( lp->dma.tx_reclaim_desc ) {
731 status = wl_pci_dma_free_desc( pdev, lp, &lp->dma.tx_reclaim_desc );
733 DBG_WARNING( DbgInfo, "Problem freeing Tx reclaim descriptor\n" );
740 /*============================================================================*/
742 /*******************************************************************************
743 * wl_pci_dma_alloc_tx_packet()
744 *******************************************************************************
748 * Allocates a single Tx packet, consisting of several descriptors and
749 * buffers. Data to transmit is first copied into the 'payload' buffer
750 * before being transmitted.
754 * pdev - a pointer to the device's pci_dev structure
755 * lp - the device's private adapter structure
756 * desc - a pointer which will reference the descriptor to be alloc'd.
761 * errno value otherwise
763 ******************************************************************************/
764 int wl_pci_dma_alloc_tx_packet( struct pci_dev *pdev, struct wl_private *lp,
768 // /*------------------------------------------------------------------------*/
770 // if( desc == NULL ) {
773 // if( status == 0 ) {
774 // status = wl_pci_dma_alloc_desc_and_buf( pdev, lp, desc,
775 // HCF_DMA_TX_BUF1_SIZE );
777 // if( status == 0 ) {
778 // status = wl_pci_dma_alloc_desc_and_buf( pdev, lp,
779 // &( (*desc)->next_desc_addr ),
780 // HCF_MAX_PACKET_SIZE );
783 // if( status == 0 ) {
784 // (*desc)->next_desc_phys_addr = (*desc)->next_desc_addr->desc_phys_addr;
787 } // wl_pci_dma_alloc_tx_packet
788 /*============================================================================*/
790 /*******************************************************************************
791 * wl_pci_dma_free_tx_packet()
792 *******************************************************************************
796 * Frees a single Tx packet, described in the corresponding alloc function.
800 * pdev - a pointer to the device's pci_dev structure
801 * lp - the device's private adapter structure
802 * desc - a pointer which will reference the descriptor to be alloc'd.
807 * errno value otherwise
809 ******************************************************************************/
810 int wl_pci_dma_free_tx_packet( struct pci_dev *pdev, struct wl_private *lp,
814 /*------------------------------------------------------------------------*/
816 if( *desc == NULL ) {
817 DBG_PRINT( "Null descriptor\n" );
820 //;?the "limited" NDIS strategy, assuming a frame consists ALWAYS out of 2
821 //descriptors, make this robust
822 if( status == 0 && (*desc)->next_desc_addr ) {
823 status = wl_pci_dma_free_desc_and_buf( pdev, lp, &(*desc)->next_desc_addr );
826 status = wl_pci_dma_free_desc_and_buf( pdev, lp, desc );
829 } // wl_pci_dma_free_tx_packet
830 /*============================================================================*/
832 /*******************************************************************************
833 * wl_pci_dma_alloc_rx_packet()
834 *******************************************************************************
838 * Allocates a single Rx packet, consisting of two descriptors and one
839 * contiguous buffer. The buffer starts with the hermes-specific header.
840 * One descriptor points at the start, the other at offset 0x3a of the
845 * pdev - a pointer to the device's pci_dev structure
846 * lp - the device's private adapter structure
847 * desc - a pointer which will reference the descriptor to be alloc'd.
852 * errno value otherwise
854 ******************************************************************************/
855 int wl_pci_dma_alloc_rx_packet( struct pci_dev *pdev, struct wl_private *lp,
860 /*------------------------------------------------------------------------*/
862 // if( desc == NULL ) {
865 // //;?the "limited" NDIS strategy, assuming a frame consists ALWAYS out of 2
866 // //descriptors, make this robust
867 // if( status == 0 ) {
868 // status = wl_pci_dma_alloc_desc( pdev, lp, desc );
870 // if( status == 0 ) {
871 // status = wl_pci_dma_alloc_buf( pdev, lp, *desc, HCF_MAX_PACKET_SIZE );
873 // if( status == 0 ) {
874 // status = wl_pci_dma_alloc_desc( pdev, lp, &p );
876 // if( status == 0 ) {
877 // /* Size of 1st descriptor becomes 0x3a bytes */
878 // SET_BUF_SIZE( *desc, HCF_DMA_RX_BUF1_SIZE );
880 // /* Make 2nd descriptor point at offset 0x3a of the buffer */
881 // SET_BUF_SIZE( p, ( HCF_MAX_PACKET_SIZE - HCF_DMA_RX_BUF1_SIZE ));
882 // p->buf_addr = (*desc)->buf_addr + HCF_DMA_RX_BUF1_SIZE;
883 // p->buf_phys_addr = (*desc)->buf_phys_addr + HCF_DMA_RX_BUF1_SIZE;
884 // p->next_desc_addr = NULL;
886 // /* Chain 2nd descriptor to 1st descriptor */
887 // (*desc)->next_desc_addr = p;
888 // (*desc)->next_desc_phys_addr = p->desc_phys_addr;
892 } // wl_pci_dma_alloc_rx_packet
893 /*============================================================================*/
895 /*******************************************************************************
896 * wl_pci_dma_free_rx_packet()
897 *******************************************************************************
901 * Frees a single Rx packet, described in the corresponding alloc function.
905 * pdev - a pointer to the device's pci_dev structure
906 * lp - the device's private adapter structure
907 * desc - a pointer which will reference the descriptor to be alloc'd.
912 * errno value otherwise
914 ******************************************************************************/
915 int wl_pci_dma_free_rx_packet( struct pci_dev *pdev, struct wl_private *lp,
920 /*------------------------------------------------------------------------*/
922 if( *desc == NULL ) {
926 p = (*desc)->next_desc_addr;
928 /* Free the 2nd descriptor */
931 p->buf_phys_addr = 0;
933 status = wl_pci_dma_free_desc( pdev, lp, &p );
937 /* Free the buffer and 1st descriptor */
939 SET_BUF_SIZE( *desc, HCF_MAX_PACKET_SIZE );
940 status = wl_pci_dma_free_desc_and_buf( pdev, lp, desc );
943 } // wl_pci_dma_free_rx_packet
944 /*============================================================================*/
946 /*******************************************************************************
947 * wl_pci_dma_alloc_desc_and_buf()
948 *******************************************************************************
952 * Allocates a DMA descriptor and buffer, and associates them with one
957 * pdev - a pointer to the device's pci_dev structure
958 * lp - the device's private adapter structure
959 * desc - a pointer which will reference the descriptor to be alloc'd
964 * errno value otherwise
966 ******************************************************************************/
967 int wl_pci_dma_alloc_desc_and_buf( struct pci_dev *pdev, struct wl_private *lp,
968 DESC_STRCT **desc, int size )
971 /*------------------------------------------------------------------------*/
973 // if( desc == NULL ) {
976 // if( status == 0 ) {
977 // status = wl_pci_dma_alloc_desc( pdev, lp, desc );
979 // if( status == 0 ) {
980 // status = wl_pci_dma_alloc_buf( pdev, lp, *desc, size );
984 } // wl_pci_dma_alloc_desc_and_buf
985 /*============================================================================*/
987 /*******************************************************************************
988 * wl_pci_dma_free_desc_and_buf()
989 *******************************************************************************
993 * Frees a DMA descriptor and associated buffer.
997 * pdev - a pointer to the device's pci_dev structure
998 * lp - the device's private adapter structure
999 * desc - a pointer which will reference the descriptor to be alloc'd
1004 * errno value otherwise
1006 ******************************************************************************/
1007 int wl_pci_dma_free_desc_and_buf( struct pci_dev *pdev, struct wl_private *lp,
1011 /*------------------------------------------------------------------------*/
1013 if( desc == NULL ) {
1016 if( status == 0 && *desc == NULL ) {
1020 status = wl_pci_dma_free_buf( pdev, lp, *desc );
1023 status = wl_pci_dma_free_desc( pdev, lp, desc );
1027 } // wl_pci_dma_free_desc_and_buf
1028 /*============================================================================*/
1030 /*******************************************************************************
1031 * wl_pci_dma_alloc_desc()
1032 *******************************************************************************
1036 * Allocates one DMA descriptor in cache coherent memory.
1040 * pdev - a pointer to the device's pci_dev structure
1041 * lp - the device's private adapter structure
1046 * errno value otherwise
1048 ******************************************************************************/
1049 int wl_pci_dma_alloc_desc( struct pci_dev *pdev, struct wl_private *lp,
1055 // if( desc == NULL ) {
1056 // status = -EFAULT;
1058 // if( status == 0 ) {
1059 // *desc = pci_alloc_consistent( pdev, sizeof( DESC_STRCT ), &pa );
1061 // if( *desc == NULL ) {
1062 // DBG_ERROR( DbgInfo, "pci_alloc_consistent() failed\n" );
1063 // status = -ENOMEM;
1065 // memset( *desc, 0, sizeof( DESC_STRCT ));
1066 // (*desc)->desc_phys_addr = cpu_to_le32( pa );
1069 } // wl_pci_dma_alloc_desc
1070 /*============================================================================*/
1072 /*******************************************************************************
1073 * wl_pci_dma_free_desc()
1074 *******************************************************************************
1078 * Frees one DMA descriptor in cache coherent memory.
1082 * pdev - a pointer to the device's pci_dev structure
1083 * lp - the device's private adapter structure
1088 * errno value otherwise
1090 ******************************************************************************/
1091 int wl_pci_dma_free_desc( struct pci_dev *pdev, struct wl_private *lp,
1095 /*------------------------------------------------------------------------*/
1097 if( *desc == NULL ) {
1101 pci_free_consistent( pdev, sizeof( DESC_STRCT ), *desc,
1102 (*desc)->desc_phys_addr );
1106 } // wl_pci_dma_free_desc
1107 /*============================================================================*/
1109 /*******************************************************************************
1110 * wl_pci_dma_alloc_buf()
1111 *******************************************************************************
1115 * Allocates one DMA buffer in cache coherent memory, and associates a DMA
1116 * descriptor with this buffer.
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_buf( struct pci_dev *pdev, struct wl_private *lp,
1130 DESC_STRCT *desc, int size )
1135 // if( desc == NULL ) {
1136 // status = -EFAULT;
1138 // if( status == 0 && desc->buf_addr != NULL ) {
1139 // status = -EFAULT;
1141 // if( status == 0 ) {
1142 // desc->buf_addr = pci_alloc_consistent( pdev, size, &pa );
1144 // if( desc->buf_addr == NULL ) {
1145 // DBG_ERROR( DbgInfo, "pci_alloc_consistent() failed\n" );
1146 // status = -ENOMEM;
1148 // desc->buf_phys_addr = cpu_to_le32( pa );
1149 // SET_BUF_SIZE( desc, size );
1152 } // wl_pci_dma_alloc_buf
1153 /*============================================================================*/
1155 /*******************************************************************************
1156 * wl_pci_dma_free_buf()
1157 *******************************************************************************
1161 * Allocates one DMA buffer in cache coherent memory, and associates a DMA
1162 * descriptor with this buffer.
1166 * pdev - a pointer to the device's pci_dev structure
1167 * lp - the device's private adapter structure
1172 * errno value otherwise
1174 ******************************************************************************/
1175 int wl_pci_dma_free_buf( struct pci_dev *pdev, struct wl_private *lp,
1179 /*------------------------------------------------------------------------*/
1181 if( desc == NULL ) {
1184 if( status == 0 && desc->buf_addr == NULL ) {
1188 pci_free_consistent( pdev, GET_BUF_SIZE( desc ), desc->buf_addr,
1189 desc->buf_phys_addr );
1192 desc->buf_phys_addr = 0;
1193 SET_BUF_SIZE( desc, 0 );
1196 } // wl_pci_dma_free_buf
1197 /*============================================================================*/
1199 /*******************************************************************************
1200 * wl_pci_dma_hcf_supply()
1201 *******************************************************************************
1205 * Supply HCF with DMA-related resources. These consist of:
1206 * - buffers and descriptors for receive purposes
1207 * - one 'reclaim' descriptor for the transmit path, used to fulfill a
1208 * certain H25 DMA engine requirement
1209 * - one 'reclaim' descriptor for the receive path, used to fulfill a
1210 * certain H25 DMA engine requirement
1212 * This function is called at start-of-day or at re-initialization.
1216 * lp - the device's private adapter structure
1221 * errno value otherwise
1223 ******************************************************************************/
1224 void wl_pci_dma_hcf_supply( struct wl_private *lp )
1228 //if( lp->dma.status == 0 );
1230 /* Hand over the Rx/Tx reclaim descriptors to the HCF */
1231 if( lp->dma.tx_reclaim_desc ) {
1232 DBG_PRINT( "lp->dma.tx_reclaim_desc: 0x%p\n", lp->dma.tx_reclaim_desc );
1233 hcf_dma_tx_put( &lp->hcfCtx, lp->dma.tx_reclaim_desc, 0 );
1234 lp->dma.tx_reclaim_desc = NULL;
1235 DBG_PRINT( "lp->dma.tx_reclaim_desc: 0x%p\n", lp->dma.tx_reclaim_desc );
1237 if( lp->dma.rx_reclaim_desc ) {
1238 DBG_PRINT( "lp->dma.rx_reclaim_desc: 0x%p\n", lp->dma.rx_reclaim_desc );
1239 hcf_dma_rx_put( &lp->hcfCtx, lp->dma.rx_reclaim_desc );
1240 lp->dma.rx_reclaim_desc = NULL;
1241 DBG_PRINT( "lp->dma.rx_reclaim_desc: 0x%p\n", lp->dma.rx_reclaim_desc );
1243 /* Hand over the Rx descriptor chain to the HCF */
1244 for( i = 0; i < NUM_RX_DESC; i++ ) {
1245 DBG_PRINT( "lp->dma.rx_packet[%d]: 0x%p\n", i, lp->dma.rx_packet[i] );
1246 hcf_dma_rx_put( &lp->hcfCtx, lp->dma.rx_packet[i] );
1247 lp->dma.rx_packet[i] = NULL;
1248 DBG_PRINT( "lp->dma.rx_packet[%d]: 0x%p\n", i, lp->dma.rx_packet[i] );
1253 } // wl_pci_dma_hcf_supply
1254 /*============================================================================*/
1256 /*******************************************************************************
1257 * wl_pci_dma_hcf_reclaim()
1258 *******************************************************************************
1262 * Return DMA-related resources from the HCF. These consist of:
1263 * - buffers and descriptors for receive purposes
1264 * - buffers and descriptors for transmit purposes
1265 * - one 'reclaim' descriptor for the transmit path, used to fulfill a
1266 * certain H25 DMA engine requirement
1267 * - one 'reclaim' descriptor for the receive path, used to fulfill a
1268 * certain H25 DMA engine requirement
1270 * This function is called at end-of-day or at re-initialization.
1274 * lp - the device's private adapter structure
1279 * errno value otherwise
1281 ******************************************************************************/
1282 void wl_pci_dma_hcf_reclaim( struct wl_private *lp )
1286 wl_pci_dma_hcf_reclaim_rx( lp );
1287 for( i = 0; i < NUM_RX_DESC; i++ ) {
1288 DBG_PRINT( "rx_packet[%d] 0x%p\n", i, lp->dma.rx_packet[i] );
1289 // if( lp->dma.rx_packet[i] == NULL ) {
1290 // DBG_PRINT( "wl_pci_dma_hcf_reclaim: rx_packet[%d] NULL\n", i );
1294 wl_pci_dma_hcf_reclaim_tx( lp );
1295 for( i = 0; i < NUM_TX_DESC; i++ ) {
1296 DBG_PRINT( "tx_packet[%d] 0x%p\n", i, lp->dma.tx_packet[i] );
1297 // if( lp->dma.tx_packet[i] == NULL ) {
1298 // DBG_PRINT( "wl_pci_dma_hcf_reclaim: tx_packet[%d] NULL\n", i );
1303 } // wl_pci_dma_hcf_reclaim
1304 /*============================================================================*/
1306 /*******************************************************************************
1307 * wl_pci_dma_hcf_reclaim_rx()
1308 *******************************************************************************
1312 * Reclaim Rx packets that have already been processed by the HCF.
1316 * lp - the device's private adapter structure
1321 * errno value otherwise
1323 ******************************************************************************/
1324 void wl_pci_dma_hcf_reclaim_rx( struct wl_private *lp )
1329 //if( lp->dma.status == 0 )
1331 while ( ( p = hcf_dma_rx_get( &lp->hcfCtx ) ) != NULL ) {
1332 if( p && p->buf_addr == NULL ) {
1333 /* A reclaim descriptor is being given back by the HCF. Reclaim
1334 descriptors have a NULL buf_addr */
1335 lp->dma.rx_reclaim_desc = p;
1336 DBG_PRINT( "reclaim_descriptor: 0x%p\n", p );
1339 for( i = 0; i < NUM_RX_DESC; i++ ) {
1340 if( lp->dma.rx_packet[i] == NULL ) {
1344 /* An Rx buffer descriptor is being given back by the HCF */
1345 lp->dma.rx_packet[i] = p;
1346 lp->dma.rx_rsc_ind++;
1347 DBG_PRINT( "rx_packet[%d] 0x%p\n", i, lp->dma.rx_packet[i] );
1350 } // wl_pci_dma_hcf_reclaim_rx
1351 /*============================================================================*/
1353 /*******************************************************************************
1354 * wl_pci_dma_get_tx_packet()
1355 *******************************************************************************
1359 * Obtains a Tx descriptor from the chain to use for Tx.
1363 * lp - a pointer to the device's wl_private structure.
1367 * A pointer to the retrieved descriptor
1369 ******************************************************************************/
1370 DESC_STRCT * wl_pci_dma_get_tx_packet( struct wl_private *lp )
1373 DESC_STRCT *desc = NULL;
1374 /*------------------------------------------------------------------------*/
1376 for( i = 0; i < NUM_TX_DESC; i++ ) {
1377 if( lp->dma.tx_packet[i] ) {
1382 if( i != NUM_TX_DESC ) {
1383 desc = lp->dma.tx_packet[i];
1385 lp->dma.tx_packet[i] = NULL;
1386 lp->dma.tx_rsc_ind--;
1388 memset( desc->buf_addr, 0, HCF_DMA_TX_BUF1_SIZE );
1392 } // wl_pci_dma_get_tx_packet
1393 /*============================================================================*/
1395 /*******************************************************************************
1396 * wl_pci_dma_put_tx_packet()
1397 *******************************************************************************
1401 * Returns a Tx descriptor to the chain.
1405 * lp - a pointer to the device's wl_private structure.
1406 * desc - a pointer to the descriptor to return.
1412 ******************************************************************************/
1413 void wl_pci_dma_put_tx_packet( struct wl_private *lp, DESC_STRCT *desc )
1416 /*------------------------------------------------------------------------*/
1418 for( i = 0; i < NUM_TX_DESC; i++ ) {
1419 if( lp->dma.tx_packet[i] == NULL ) {
1424 if( i != NUM_TX_DESC ) {
1425 lp->dma.tx_packet[i] = desc;
1426 lp->dma.tx_rsc_ind++;
1428 } // wl_pci_dma_put_tx_packet
1429 /*============================================================================*/
1431 /*******************************************************************************
1432 * wl_pci_dma_hcf_reclaim_tx()
1433 *******************************************************************************
1437 * Reclaim Tx packets that have either been processed by the HCF due to a
1438 * port disable or a Tx completion.
1442 * lp - the device's private adapter structure
1447 * errno value otherwise
1449 ******************************************************************************/
1450 void wl_pci_dma_hcf_reclaim_tx( struct wl_private *lp )
1455 //if( lp->dma.status == 0 )
1457 while ( ( p = hcf_dma_tx_get( &lp->hcfCtx ) ) != NULL ) {
1459 if( p != NULL && p->buf_addr == NULL ) {
1460 /* A Reclaim descriptor is being given back by the HCF. Reclaim
1461 descriptors have a NULL buf_addr */
1462 lp->dma.tx_reclaim_desc = p;
1463 DBG_PRINT( "reclaim_descriptor: 0x%p\n", p );
1466 for( i = 0; i < NUM_TX_DESC; i++ ) {
1467 if( lp->dma.tx_packet[i] == NULL ) {
1471 /* An Rx buffer descriptor is being given back by the HCF */
1472 lp->dma.tx_packet[i] = p;
1473 lp->dma.tx_rsc_ind++;
1474 DBG_PRINT( "tx_packet[%d] 0x%p\n", i, lp->dma.tx_packet[i] );
1478 if( lp->netif_queue_on == FALSE ) {
1479 netif_wake_queue( lp->dev );
1480 WL_WDS_NETIF_WAKE_QUEUE( lp );
1481 lp->netif_queue_on = TRUE;
1484 } // wl_pci_dma_hcf_reclaim_tx
1485 /*============================================================================*/
1486 #endif // ENABLE_DMA