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 )
191 /*------------------------------------------------------------------------*/
193 DBG_FUNC( "wl_adapter_init_module()" );
194 DBG_ENTER( DbgInfo
);
195 DBG_TRACE( DbgInfo
, "wl_adapter_init_module() -- PCI\n" );
197 result
= pci_register_driver( &wl_driver
); //;?replace with pci_module_init, Rubini pg 490
198 //;? why not do something with the result
200 DBG_LEAVE( DbgInfo
);
202 } // wl_adapter_init_module
203 /*============================================================================*/
205 /*******************************************************************************
206 * wl_adapter_cleanup_module()
207 *******************************************************************************
211 * Called by cleanup_module() to perform PCI-specific driver cleanup.
221 ******************************************************************************/
222 void wl_adapter_cleanup_module( void )
224 //;?how come wl_adapter_cleanup_module is located in a seemingly pci specific module
225 DBG_FUNC( "wl_adapter_cleanup_module" );
226 DBG_ENTER( DbgInfo
);
228 //;?DBG_TRACE below feels like nearly redundant in the light of DBG_ENTER above
229 DBG_TRACE( DbgInfo
, "wl_adapter_cleanup_module() -- PCI\n" );
231 pci_unregister_driver( &wl_driver
);
233 DBG_LEAVE( DbgInfo
);
235 } // wl_adapter_cleanup_module
236 /*============================================================================*/
238 /*******************************************************************************
239 * wl_adapter_insert()
240 *******************************************************************************
244 * Called by wl_pci_probe() to continue the process of device insertion.
248 * dev - a pointer to the device's net_device structure
254 ******************************************************************************/
255 int wl_adapter_insert( struct net_device
*dev
)
258 /*------------------------------------------------------------------------*/
260 DBG_FUNC( "wl_adapter_insert" );
261 DBG_ENTER( DbgInfo
);
263 DBG_TRACE( DbgInfo
, "wl_adapter_insert() -- PCI\n" );
266 DBG_ERROR( DbgInfo
, "net_device pointer is NULL!!!\n" );
267 } else if( dev
->priv
== NULL
) {
268 DBG_ERROR( DbgInfo
, "wl_private pointer is NULL!!!\n" );
269 } else if( wl_insert( dev
) ) { /* Perform remaining device initialization */
272 DBG_TRACE( DbgInfo
, "wl_insert() FAILED\n" );
274 DBG_LEAVE( DbgInfo
);
276 } // wl_adapter_insert
277 /*============================================================================*/
279 /*******************************************************************************
281 *******************************************************************************
289 * dev - a pointer to the device's net_device structure
295 ******************************************************************************/
296 int wl_adapter_open( struct net_device
*dev
)
299 int hcf_status
= HCF_SUCCESS
;
300 /*------------------------------------------------------------------------*/
302 DBG_FUNC( "wl_adapter_open" );
303 DBG_ENTER( DbgInfo
);
305 DBG_TRACE( DbgInfo
, "wl_adapter_open() -- PCI\n" );
307 hcf_status
= wl_open( dev
);
309 if( hcf_status
!= HCF_SUCCESS
) {
313 DBG_LEAVE( DbgInfo
);
316 /*============================================================================*/
318 /*******************************************************************************
320 *******************************************************************************
328 * dev - a pointer to the device's net_device structure
334 ******************************************************************************/
335 int wl_adapter_close( struct net_device
*dev
)
337 DBG_FUNC( "wl_adapter_close" );
338 DBG_ENTER( DbgInfo
);
340 DBG_TRACE( DbgInfo
, "wl_adapter_close() -- PCI\n" );
341 DBG_TRACE( DbgInfo
, "%s: Shutting down adapter.\n", dev
->name
);
345 DBG_LEAVE( DbgInfo
);
347 } // wl_adapter_close
348 /*============================================================================*/
350 /*******************************************************************************
351 * wl_adapter_is_open()
352 *******************************************************************************
356 * Check whether this device is open. Returns
360 * dev - a pointer to the device's net_device structure
364 * nonzero if device is open.
366 ******************************************************************************/
367 int wl_adapter_is_open( struct net_device
*dev
)
369 /* This function is used in PCMCIA to check the status of the 'open' field
370 in the dev_link_t structure associated with a network device. There
371 doesn't seem to be an analog to this for PCI, and checking the status
372 contained in the net_device structure doesn't have the same effect.
373 For now, return TRUE, but find out if this is necessary for PCI. */
376 } // wl_adapter_is_open
377 /*============================================================================*/
379 /*******************************************************************************
381 *******************************************************************************
385 * Registered in the pci_driver structure, this function is called when the
386 * PCI subsystem finds a new PCI device which matches the information contained
387 * in the pci_device_id table.
391 * pdev - a pointer to the device's pci_dev structure
392 * ent - this device's entry in the pci_device_id table
397 * errno value otherwise
399 ******************************************************************************/
400 int wl_pci_probe( struct pci_dev
*pdev
,
401 const struct pci_device_id
*ent
)
404 /*------------------------------------------------------------------------*/
406 DBG_FUNC( "wl_pci_probe" );
407 DBG_ENTER( DbgInfo
);
408 DBG_PRINT( "%s\n", VERSION_INFO
);
410 result
= wl_pci_setup( pdev
);
412 DBG_LEAVE( DbgInfo
);
416 /*============================================================================*/
418 /*******************************************************************************
420 *******************************************************************************
424 * Registered in the pci_driver structure, this function is called when the
425 * PCI subsystem detects that a PCI device which matches the information
426 * contained in the pci_device_id table has been removed.
430 * pdev - a pointer to the device's pci_dev structure
436 ******************************************************************************/
437 void wl_pci_remove(struct pci_dev
*pdev
)
439 struct net_device
*dev
= NULL
;
440 /*------------------------------------------------------------------------*/
442 DBG_FUNC( "wl_pci_remove" );
443 DBG_ENTER( DbgInfo
);
445 /* Make sure the pci_dev pointer passed in is valid */
447 DBG_ERROR( DbgInfo
, "PCI subsys passed in an invalid pci_dev pointer\n" );
451 dev
= pci_get_drvdata( pdev
);
453 DBG_ERROR( DbgInfo
, "Could not retrieve net_device structure\n" );
457 /* Perform device cleanup */
459 free_irq( dev
->irq
, dev
);
462 wl_pci_dma_free( pdev
, dev
->priv
);
465 wl_device_dealloc( dev
);
467 DBG_LEAVE( DbgInfo
);
470 /*============================================================================*/
472 /*******************************************************************************
474 *******************************************************************************
478 * Called by wl_pci_probe() to begin a device's initialization process.
482 * pdev - a pointer to the device's pci_dev structure
487 * errno value otherwise
489 ******************************************************************************/
490 int wl_pci_setup( struct pci_dev
*pdev
)
493 struct net_device
*dev
= NULL
;
494 struct wl_private
*lp
= NULL
;
495 /*------------------------------------------------------------------------*/
497 DBG_FUNC( "wl_pci_setup" );
498 DBG_ENTER( DbgInfo
);
500 /* Make sure the pci_dev pointer passed in is valid */
502 DBG_ERROR( DbgInfo
, "PCI subsys passed in an invalid pci_dev pointer\n" );
506 result
= pci_enable_device( pdev
);
508 DBG_ERROR( DbgInfo
, "pci_enable_device() failed\n" );
509 DBG_LEAVE( DbgInfo
);
513 /* We found our device! Let's register it with the system */
514 DBG_TRACE( DbgInfo
, "Found our device, now registering\n" );
515 dev
= wl_device_alloc( );
517 DBG_ERROR( DbgInfo
, "Could not register device!!!\n" );
518 DBG_LEAVE( DbgInfo
);
522 /* Make sure that space was allocated for our private adapter struct */
523 if( dev
->priv
== NULL
) {
524 DBG_ERROR( DbgInfo
, "Private adapter struct was not allocated!!!\n" );
525 wl_device_dealloc(dev
);
526 DBG_LEAVE( DbgInfo
);
531 /* Allocate DMA Descriptors */
532 if( wl_pci_dma_alloc( pdev
, dev
->priv
) < 0 ) {
533 DBG_ERROR( DbgInfo
, "Could not allocate DMA descriptor memory!!!\n" );
534 wl_device_dealloc(dev
);
535 DBG_LEAVE( DbgInfo
);
540 /* Register our private adapter structure with PCI */
541 pci_set_drvdata( pdev
, dev
);
543 /* Fill out bus specific information in the net_device struct */
544 dev
->irq
= pdev
->irq
;
545 SET_MODULE_OWNER( dev
);
547 DBG_TRACE( DbgInfo
, "Device Base Address: %#03lx\n", pdev
->resource
[0].start
);
548 dev
->base_addr
= pdev
->resource
[0].start
;
550 /* Initialize our device here */
551 if( !wl_adapter_insert( dev
)) {
552 DBG_ERROR( DbgInfo
, "wl_adapter_insert() FAILED!!!\n" );
553 wl_device_dealloc( dev
);
554 DBG_LEAVE( DbgInfo
);
558 /* Register our ISR */
559 DBG_TRACE( DbgInfo
, "Registering ISR...\n" );
561 result
= request_irq(dev
->irq
, wl_isr
, SA_SHIRQ
, dev
->name
, dev
);
563 DBG_WARNING( DbgInfo
, "Could not register ISR!!!\n" );
565 wl_device_dealloc(dev
);
566 DBG_LEAVE( DbgInfo
);
570 /* Make sure interrupts are enabled properly for CardBus */
573 if( lp
->hcfCtx
.IFB_BusType
== CFG_NIC_BUS_TYPE_CARDBUS
||
574 lp
->hcfCtx
.IFB_BusType
== CFG_NIC_BUS_TYPE_PCI
) {
575 DBG_TRACE( DbgInfo
, "This is a PCI/CardBus card, enable interrupts\n" );
576 wl_pci_enable_cardbus_interrupts( pdev
);
579 /* Enable bus mastering */
580 pci_set_master( pdev
);
582 DBG_LEAVE( DbgInfo
);
585 /*============================================================================*/
587 /*******************************************************************************
588 * wl_pci_enable_cardbus_interrupts()
589 *******************************************************************************
593 * Called by wl_pci_setup() to enable interrupts on a CardBus device. This
594 * is done by writing bit 15 to the function event mask register. This
595 * CardBus-specific register is located in BAR2 (counting from BAR0), in memory
596 * space at byte offset 1f4 (7f4 for WARP).
600 * pdev - a pointer to the device's pci_dev structure
606 ******************************************************************************/
607 void wl_pci_enable_cardbus_interrupts( struct pci_dev
*pdev
)
611 u32 func_evt_mask_reg
;
612 void *mem_addr_kern
= NULL
;
613 /*------------------------------------------------------------------------*/
615 DBG_FUNC( "wl_pci_enable_cardbus_interrupts" );
616 DBG_ENTER( DbgInfo
);
618 /* Initialize to known bad values */
619 bar2_reg
= 0xdeadbeef;
620 mem_addr_bus
= 0xdeadbeef;
622 /* Read the BAR2 register; this register contains the base address of the
623 memory region where the function event mask register lives */
624 pci_read_config_dword( pdev
, PCI_BASE_ADDRESS_2
, &bar2_reg
);
625 mem_addr_bus
= bar2_reg
& PCI_BASE_ADDRESS_MEM_MASK
;
627 /* Once the base address is obtained, remap the memory region to kernel
628 space so we can retrieve the register */
629 mem_addr_kern
= ioremap( mem_addr_bus
, 0x200 );
632 #define REG_OFFSET 0x07F4
634 #define REG_OFFSET 0x01F4
639 /* Retrieve the functional event mask register, enable interrupts by
640 setting Bit 15, and write back the value */
641 func_evt_mask_reg
= *(u32
*)( mem_addr_kern
+ REG_OFFSET
);
642 func_evt_mask_reg
|= BIT15
;
643 *(u32
*)( mem_addr_kern
+ REG_OFFSET
) = func_evt_mask_reg
;
645 /* Once complete, unmap the region and exit */
646 iounmap( mem_addr_kern
);
648 DBG_LEAVE( DbgInfo
);
650 } // wl_pci_enable_cardbus_interrupts
651 /*============================================================================*/
654 /*******************************************************************************
656 *******************************************************************************
660 * Allocates all resources needed for PCI/CardBus DMA operation
664 * pdev - a pointer to the device's pci_dev structure
665 * lp - the device's private adapter structure
670 * errno value otherwise
672 ******************************************************************************/
673 int wl_pci_dma_alloc( struct pci_dev
*pdev
, struct wl_private
*lp
)
677 /*------------------------------------------------------------------------*/
679 DBG_FUNC( "wl_pci_dma_alloc" );
680 DBG_ENTER( DbgInfo
);
682 // lp->dma.tx_rsc_ind = lp->dma.rx_rsc_ind = 0;
684 // /* Alloc for the Tx chain and its reclaim descriptor */
685 // for( i = 0; i < NUM_TX_DESC; i++ ) {
686 // status = wl_pci_dma_alloc_tx_packet( pdev, lp, &lp->dma.tx_packet[i] );
687 // if( status == 0 ) {
688 // DBG_PRINT( "lp->dma.tx_packet[%d] : 0x%p\n", i, lp->dma.tx_packet[i] );
689 // DBG_PRINT( "lp->dma.tx_packet[%d]->next_desc_addr : 0x%p\n", i, lp->dma.tx_packet[i]->next_desc_addr );
690 // lp->dma.tx_rsc_ind++;
692 // DBG_ERROR( DbgInfo, "Could not alloc DMA Tx Packet\n" );
696 // if( status == 0 ) {
697 // status = wl_pci_dma_alloc_desc( pdev, lp, &lp->dma.tx_reclaim_desc );
698 // DBG_PRINT( "lp->dma.tx_reclaim_desc: 0x%p\n", lp->dma.tx_reclaim_desc );
700 // /* Alloc for the Rx chain and its reclaim descriptor */
701 // if( status == 0 ) {
702 // for( i = 0; i < NUM_RX_DESC; i++ ) {
703 // status = wl_pci_dma_alloc_rx_packet( pdev, lp, &lp->dma.rx_packet[i] );
704 // if( status == 0 ) {
705 // DBG_PRINT( "lp->dma.rx_packet[%d] : 0x%p\n", i, lp->dma.rx_packet[i] );
706 // DBG_PRINT( "lp->dma.rx_packet[%d]->next_desc_addr : 0x%p\n", i, lp->dma.rx_packet[i]->next_desc_addr );
707 // lp->dma.rx_rsc_ind++;
709 // DBG_ERROR( DbgInfo, "Could not alloc DMA Rx Packet\n" );
714 // if( status == 0 ) {
715 // status = wl_pci_dma_alloc_desc( pdev, lp, &lp->dma.rx_reclaim_desc );
716 // DBG_PRINT( "lp->dma.rx_reclaim_desc: 0x%p\n", lp->dma.rx_reclaim_desc );
718 // /* Store status, as host should not call HCF functions if this fails */
719 // lp->dma.status = status; //;?all useages of dma.status have been commented out
720 // DBG_LEAVE( DbgInfo );
722 } // wl_pci_dma_alloc
723 /*============================================================================*/
725 /*******************************************************************************
727 *******************************************************************************
731 * Deallocated all resources needed for PCI/CardBus DMA operation
735 * pdev - a pointer to the device's pci_dev structure
736 * lp - the device's private adapter structure
741 * errno value otherwise
743 ******************************************************************************/
744 int wl_pci_dma_free( struct pci_dev
*pdev
, struct wl_private
*lp
)
748 /*------------------------------------------------------------------------*/
750 DBG_FUNC( "wl_pci_dma_free" );
751 DBG_ENTER( DbgInfo
);
753 /* Reclaim all Rx packets that were handed over to the HCF */
754 /* Do I need to do this? Before this free is called, I've already disabled
755 the port which will call wl_pci_dma_hcf_reclaim */
756 //if( lp->dma.status == 0 )
758 // wl_pci_dma_hcf_reclaim( lp );
761 /* Free everything needed for DMA Rx */
762 for( i
= 0; i
< NUM_RX_DESC
; i
++ ) {
763 if( lp
->dma
.rx_packet
[i
] ) {
764 status
= wl_pci_dma_free_rx_packet( pdev
, lp
, &lp
->dma
.rx_packet
[i
] );
766 DBG_WARNING( DbgInfo
, "Problem freeing Rx packet\n" );
770 lp
->dma
.rx_rsc_ind
= 0;
772 if( lp
->dma
.rx_reclaim_desc
) {
773 status
= wl_pci_dma_free_desc( pdev
, lp
, &lp
->dma
.rx_reclaim_desc
);
775 DBG_WARNING( DbgInfo
, "Problem freeing Rx reclaim descriptor\n" );
779 /* Free everything needed for DMA Tx */
780 for( i
= 0; i
< NUM_TX_DESC
; i
++ ) {
781 if( lp
->dma
.tx_packet
[i
] ) {
782 status
= wl_pci_dma_free_tx_packet( pdev
, lp
, &lp
->dma
.tx_packet
[i
] );
784 DBG_WARNING( DbgInfo
, "Problem freeing Tx packet\n" );
788 lp
->dma
.tx_rsc_ind
= 0;
790 if( lp
->dma
.tx_reclaim_desc
) {
791 status
= wl_pci_dma_free_desc( pdev
, lp
, &lp
->dma
.tx_reclaim_desc
);
793 DBG_WARNING( DbgInfo
, "Problem freeing Tx reclaim descriptor\n" );
797 DBG_LEAVE( DbgInfo
);
801 /*============================================================================*/
803 /*******************************************************************************
804 * wl_pci_dma_alloc_tx_packet()
805 *******************************************************************************
809 * Allocates a single Tx packet, consisting of several descriptors and
810 * buffers. Data to transmit is first copied into the 'payload' buffer
811 * before being transmitted.
815 * pdev - a pointer to the device's pci_dev structure
816 * lp - the device's private adapter structure
817 * desc - a pointer which will reference the descriptor to be alloc'd.
822 * errno value otherwise
824 ******************************************************************************/
825 int wl_pci_dma_alloc_tx_packet( struct pci_dev
*pdev
, struct wl_private
*lp
,
829 // /*------------------------------------------------------------------------*/
831 // if( desc == NULL ) {
834 // if( status == 0 ) {
835 // status = wl_pci_dma_alloc_desc_and_buf( pdev, lp, desc,
836 // HCF_DMA_TX_BUF1_SIZE );
838 // if( status == 0 ) {
839 // status = wl_pci_dma_alloc_desc_and_buf( pdev, lp,
840 // &( (*desc)->next_desc_addr ),
841 // HCF_MAX_PACKET_SIZE );
844 // if( status == 0 ) {
845 // (*desc)->next_desc_phys_addr = (*desc)->next_desc_addr->desc_phys_addr;
848 } // wl_pci_dma_alloc_tx_packet
849 /*============================================================================*/
851 /*******************************************************************************
852 * wl_pci_dma_free_tx_packet()
853 *******************************************************************************
857 * Frees a single Tx packet, described in the corresponding alloc function.
861 * pdev - a pointer to the device's pci_dev structure
862 * lp - the device's private adapter structure
863 * desc - a pointer which will reference the descriptor to be alloc'd.
868 * errno value otherwise
870 ******************************************************************************/
871 int wl_pci_dma_free_tx_packet( struct pci_dev
*pdev
, struct wl_private
*lp
,
875 /*------------------------------------------------------------------------*/
877 if( *desc
== NULL
) {
878 DBG_PRINT( "Null descriptor\n" );
881 //;?the "limited" NDIS strategy, assuming a frame consists ALWAYS out of 2
882 //descriptors, make this robust
883 if( status
== 0 && (*desc
)->next_desc_addr
) {
884 status
= wl_pci_dma_free_desc_and_buf( pdev
, lp
, &(*desc
)->next_desc_addr
);
887 status
= wl_pci_dma_free_desc_and_buf( pdev
, lp
, desc
);
890 } // wl_pci_dma_free_tx_packet
891 /*============================================================================*/
893 /*******************************************************************************
894 * wl_pci_dma_alloc_rx_packet()
895 *******************************************************************************
899 * Allocates a single Rx packet, consisting of two descriptors and one
900 * contiguous buffer. The buffer starts with the hermes-specific header.
901 * One descriptor points at the start, the other at offset 0x3a of the
906 * pdev - a pointer to the device's pci_dev structure
907 * lp - the device's private adapter structure
908 * desc - a pointer which will reference the descriptor to be alloc'd.
913 * errno value otherwise
915 ******************************************************************************/
916 int wl_pci_dma_alloc_rx_packet( struct pci_dev
*pdev
, struct wl_private
*lp
,
921 /*------------------------------------------------------------------------*/
923 // if( desc == NULL ) {
926 // //;?the "limited" NDIS strategy, assuming a frame consists ALWAYS out of 2
927 // //descriptors, make this robust
928 // if( status == 0 ) {
929 // status = wl_pci_dma_alloc_desc( pdev, lp, desc );
931 // if( status == 0 ) {
932 // status = wl_pci_dma_alloc_buf( pdev, lp, *desc, HCF_MAX_PACKET_SIZE );
934 // if( status == 0 ) {
935 // status = wl_pci_dma_alloc_desc( pdev, lp, &p );
937 // if( status == 0 ) {
938 // /* Size of 1st descriptor becomes 0x3a bytes */
939 // SET_BUF_SIZE( *desc, HCF_DMA_RX_BUF1_SIZE );
941 // /* Make 2nd descriptor point at offset 0x3a of the buffer */
942 // SET_BUF_SIZE( p, ( HCF_MAX_PACKET_SIZE - HCF_DMA_RX_BUF1_SIZE ));
943 // p->buf_addr = (*desc)->buf_addr + HCF_DMA_RX_BUF1_SIZE;
944 // p->buf_phys_addr = (*desc)->buf_phys_addr + HCF_DMA_RX_BUF1_SIZE;
945 // p->next_desc_addr = NULL;
947 // /* Chain 2nd descriptor to 1st descriptor */
948 // (*desc)->next_desc_addr = p;
949 // (*desc)->next_desc_phys_addr = p->desc_phys_addr;
953 } // wl_pci_dma_alloc_rx_packet
954 /*============================================================================*/
956 /*******************************************************************************
957 * wl_pci_dma_free_rx_packet()
958 *******************************************************************************
962 * Frees a single Rx packet, described in the corresponding alloc function.
966 * pdev - a pointer to the device's pci_dev structure
967 * lp - the device's private adapter structure
968 * desc - a pointer which will reference the descriptor to be alloc'd.
973 * errno value otherwise
975 ******************************************************************************/
976 int wl_pci_dma_free_rx_packet( struct pci_dev
*pdev
, struct wl_private
*lp
,
981 /*------------------------------------------------------------------------*/
983 if( *desc
== NULL
) {
987 p
= (*desc
)->next_desc_addr
;
989 /* Free the 2nd descriptor */
992 p
->buf_phys_addr
= 0;
994 status
= wl_pci_dma_free_desc( pdev
, lp
, &p
);
998 /* Free the buffer and 1st descriptor */
1000 SET_BUF_SIZE( *desc
, HCF_MAX_PACKET_SIZE
);
1001 status
= wl_pci_dma_free_desc_and_buf( pdev
, lp
, desc
);
1004 } // wl_pci_dma_free_rx_packet
1005 /*============================================================================*/
1007 /*******************************************************************************
1008 * wl_pci_dma_alloc_desc_and_buf()
1009 *******************************************************************************
1013 * Allocates a DMA descriptor and buffer, and associates them with one
1018 * pdev - a pointer to the device's pci_dev structure
1019 * lp - the device's private adapter structure
1020 * desc - a pointer which will reference the descriptor to be alloc'd
1025 * errno value otherwise
1027 ******************************************************************************/
1028 int wl_pci_dma_alloc_desc_and_buf( struct pci_dev
*pdev
, struct wl_private
*lp
,
1029 DESC_STRCT
**desc
, int size
)
1032 /*------------------------------------------------------------------------*/
1034 // if( desc == NULL ) {
1035 // status = -EFAULT;
1037 // if( status == 0 ) {
1038 // status = wl_pci_dma_alloc_desc( pdev, lp, desc );
1040 // if( status == 0 ) {
1041 // status = wl_pci_dma_alloc_buf( pdev, lp, *desc, size );
1045 } // wl_pci_dma_alloc_desc_and_buf
1046 /*============================================================================*/
1048 /*******************************************************************************
1049 * wl_pci_dma_free_desc_and_buf()
1050 *******************************************************************************
1054 * Frees a DMA descriptor and associated buffer.
1058 * pdev - a pointer to the device's pci_dev structure
1059 * lp - the device's private adapter structure
1060 * desc - a pointer which will reference the descriptor to be alloc'd
1065 * errno value otherwise
1067 ******************************************************************************/
1068 int wl_pci_dma_free_desc_and_buf( struct pci_dev
*pdev
, struct wl_private
*lp
,
1072 /*------------------------------------------------------------------------*/
1074 if( desc
== NULL
) {
1077 if( status
== 0 && *desc
== NULL
) {
1081 status
= wl_pci_dma_free_buf( pdev
, lp
, *desc
);
1084 status
= wl_pci_dma_free_desc( pdev
, lp
, desc
);
1088 } // wl_pci_dma_free_desc_and_buf
1089 /*============================================================================*/
1091 /*******************************************************************************
1092 * wl_pci_dma_alloc_desc()
1093 *******************************************************************************
1097 * Allocates one DMA descriptor in cache coherent memory.
1101 * pdev - a pointer to the device's pci_dev structure
1102 * lp - the device's private adapter structure
1107 * errno value otherwise
1109 ******************************************************************************/
1110 int wl_pci_dma_alloc_desc( struct pci_dev
*pdev
, struct wl_private
*lp
,
1115 // /*------------------------------------------------------------------------*/
1117 // DBG_FUNC( "wl_pci_dma_alloc_desc" );
1118 // DBG_ENTER( DbgInfo );
1120 // if( desc == NULL ) {
1121 // status = -EFAULT;
1123 // if( status == 0 ) {
1124 // *desc = pci_alloc_consistent( pdev, sizeof( DESC_STRCT ), &pa );
1126 // if( *desc == NULL ) {
1127 // DBG_ERROR( DbgInfo, "pci_alloc_consistent() failed\n" );
1128 // status = -ENOMEM;
1130 // memset( *desc, 0, sizeof( DESC_STRCT ));
1131 // (*desc)->desc_phys_addr = cpu_to_le32( pa );
1133 // DBG_LEAVE( DbgInfo );
1135 } // wl_pci_dma_alloc_desc
1136 /*============================================================================*/
1138 /*******************************************************************************
1139 * wl_pci_dma_free_desc()
1140 *******************************************************************************
1144 * Frees one DMA descriptor in cache coherent memory.
1148 * pdev - a pointer to the device's pci_dev structure
1149 * lp - the device's private adapter structure
1154 * errno value otherwise
1156 ******************************************************************************/
1157 int wl_pci_dma_free_desc( struct pci_dev
*pdev
, struct wl_private
*lp
,
1161 /*------------------------------------------------------------------------*/
1163 if( *desc
== NULL
) {
1167 pci_free_consistent( pdev
, sizeof( DESC_STRCT
), *desc
,
1168 (*desc
)->desc_phys_addr
);
1172 } // wl_pci_dma_free_desc
1173 /*============================================================================*/
1175 /*******************************************************************************
1176 * wl_pci_dma_alloc_buf()
1177 *******************************************************************************
1181 * Allocates one DMA buffer in cache coherent memory, and associates a DMA
1182 * descriptor with this buffer.
1186 * pdev - a pointer to the device's pci_dev structure
1187 * lp - the device's private adapter structure
1192 * errno value otherwise
1194 ******************************************************************************/
1195 int wl_pci_dma_alloc_buf( struct pci_dev
*pdev
, struct wl_private
*lp
,
1196 DESC_STRCT
*desc
, int size
)
1200 /*------------------------------------------------------------------------*/
1202 // DBG_FUNC( "wl_pci_dma_alloc_buf" );
1203 // DBG_ENTER( DbgInfo );
1205 // if( desc == NULL ) {
1206 // status = -EFAULT;
1208 // if( status == 0 && desc->buf_addr != NULL ) {
1209 // status = -EFAULT;
1211 // if( status == 0 ) {
1212 // desc->buf_addr = pci_alloc_consistent( pdev, size, &pa );
1214 // if( desc->buf_addr == NULL ) {
1215 // DBG_ERROR( DbgInfo, "pci_alloc_consistent() failed\n" );
1216 // status = -ENOMEM;
1218 // desc->buf_phys_addr = cpu_to_le32( pa );
1219 // SET_BUF_SIZE( desc, size );
1221 // DBG_LEAVE( DbgInfo );
1223 } // wl_pci_dma_alloc_buf
1224 /*============================================================================*/
1226 /*******************************************************************************
1227 * wl_pci_dma_free_buf()
1228 *******************************************************************************
1232 * Allocates one DMA buffer in cache coherent memory, and associates a DMA
1233 * descriptor with this buffer.
1237 * pdev - a pointer to the device's pci_dev structure
1238 * lp - the device's private adapter structure
1243 * errno value otherwise
1245 ******************************************************************************/
1246 int wl_pci_dma_free_buf( struct pci_dev
*pdev
, struct wl_private
*lp
,
1250 /*------------------------------------------------------------------------*/
1252 if( desc
== NULL
) {
1255 if( status
== 0 && desc
->buf_addr
== NULL
) {
1259 pci_free_consistent( pdev
, GET_BUF_SIZE( desc
), desc
->buf_addr
,
1260 desc
->buf_phys_addr
);
1263 desc
->buf_phys_addr
= 0;
1264 SET_BUF_SIZE( desc
, 0 );
1267 } // wl_pci_dma_free_buf
1268 /*============================================================================*/
1270 /*******************************************************************************
1271 * wl_pci_dma_hcf_supply()
1272 *******************************************************************************
1276 * Supply HCF with DMA-related resources. These consist of:
1277 * - buffers and descriptors for receive purposes
1278 * - one 'reclaim' descriptor for the transmit path, used to fulfill a
1279 * certain H25 DMA engine requirement
1280 * - one 'reclaim' descriptor for the receive path, used to fulfill a
1281 * certain H25 DMA engine requirement
1283 * This function is called at start-of-day or at re-initialization.
1287 * lp - the device's private adapter structure
1292 * errno value otherwise
1294 ******************************************************************************/
1295 void wl_pci_dma_hcf_supply( struct wl_private
*lp
)
1298 /*------------------------------------------------------------------------*/
1300 DBG_FUNC( "wl_pci_dma_hcf_supply" );
1301 DBG_ENTER( DbgInfo
);
1303 //if( lp->dma.status == 0 );
1305 /* Hand over the Rx/Tx reclaim descriptors to the HCF */
1306 if( lp
->dma
.tx_reclaim_desc
) {
1307 DBG_PRINT( "lp->dma.tx_reclaim_desc: 0x%p\n", lp
->dma
.tx_reclaim_desc
);
1308 hcf_dma_tx_put( &lp
->hcfCtx
, lp
->dma
.tx_reclaim_desc
, 0 );
1309 lp
->dma
.tx_reclaim_desc
= NULL
;
1310 DBG_PRINT( "lp->dma.tx_reclaim_desc: 0x%p\n", lp
->dma
.tx_reclaim_desc
);
1312 if( lp
->dma
.rx_reclaim_desc
) {
1313 DBG_PRINT( "lp->dma.rx_reclaim_desc: 0x%p\n", lp
->dma
.rx_reclaim_desc
);
1314 hcf_dma_rx_put( &lp
->hcfCtx
, lp
->dma
.rx_reclaim_desc
);
1315 lp
->dma
.rx_reclaim_desc
= NULL
;
1316 DBG_PRINT( "lp->dma.rx_reclaim_desc: 0x%p\n", lp
->dma
.rx_reclaim_desc
);
1318 /* Hand over the Rx descriptor chain to the HCF */
1319 for( i
= 0; i
< NUM_RX_DESC
; i
++ ) {
1320 DBG_PRINT( "lp->dma.rx_packet[%d]: 0x%p\n", i
, lp
->dma
.rx_packet
[i
] );
1321 hcf_dma_rx_put( &lp
->hcfCtx
, lp
->dma
.rx_packet
[i
] );
1322 lp
->dma
.rx_packet
[i
] = NULL
;
1323 DBG_PRINT( "lp->dma.rx_packet[%d]: 0x%p\n", i
, lp
->dma
.rx_packet
[i
] );
1327 DBG_LEAVE( DbgInfo
);
1329 } // wl_pci_dma_hcf_supply
1330 /*============================================================================*/
1332 /*******************************************************************************
1333 * wl_pci_dma_hcf_reclaim()
1334 *******************************************************************************
1338 * Return DMA-related resources from the HCF. These consist of:
1339 * - buffers and descriptors for receive purposes
1340 * - buffers and descriptors for transmit purposes
1341 * - one 'reclaim' descriptor for the transmit path, used to fulfill a
1342 * certain H25 DMA engine requirement
1343 * - one 'reclaim' descriptor for the receive path, used to fulfill a
1344 * certain H25 DMA engine requirement
1346 * This function is called at end-of-day or at re-initialization.
1350 * lp - the device's private adapter structure
1355 * errno value otherwise
1357 ******************************************************************************/
1358 void wl_pci_dma_hcf_reclaim( struct wl_private
*lp
)
1361 /*------------------------------------------------------------------------*/
1363 DBG_FUNC( "wl_pci_dma_hcf_reclaim" );
1364 DBG_ENTER( DbgInfo
);
1366 wl_pci_dma_hcf_reclaim_rx( lp
);
1367 for( i
= 0; i
< NUM_RX_DESC
; i
++ ) {
1368 DBG_PRINT( "rx_packet[%d] 0x%p\n", i
, lp
->dma
.rx_packet
[i
] );
1369 // if( lp->dma.rx_packet[i] == NULL ) {
1370 // DBG_PRINT( "wl_pci_dma_hcf_reclaim: rx_packet[%d] NULL\n", i );
1374 wl_pci_dma_hcf_reclaim_tx( lp
);
1375 for( i
= 0; i
< NUM_TX_DESC
; i
++ ) {
1376 DBG_PRINT( "tx_packet[%d] 0x%p\n", i
, lp
->dma
.tx_packet
[i
] );
1377 // if( lp->dma.tx_packet[i] == NULL ) {
1378 // DBG_PRINT( "wl_pci_dma_hcf_reclaim: tx_packet[%d] NULL\n", i );
1382 DBG_LEAVE( DbgInfo
);
1384 } // wl_pci_dma_hcf_reclaim
1385 /*============================================================================*/
1387 /*******************************************************************************
1388 * wl_pci_dma_hcf_reclaim_rx()
1389 *******************************************************************************
1393 * Reclaim Rx packets that have already been processed by the HCF.
1397 * lp - the device's private adapter structure
1402 * errno value otherwise
1404 ******************************************************************************/
1405 void wl_pci_dma_hcf_reclaim_rx( struct wl_private
*lp
)
1409 /*------------------------------------------------------------------------*/
1411 DBG_FUNC( "wl_pci_dma_hcf_reclaim_rx" );
1412 DBG_ENTER( DbgInfo
);
1414 //if( lp->dma.status == 0 )
1416 while ( ( p
= hcf_dma_rx_get( &lp
->hcfCtx
) ) != NULL
) {
1417 if( p
&& p
->buf_addr
== NULL
) {
1418 /* A reclaim descriptor is being given back by the HCF. Reclaim
1419 descriptors have a NULL buf_addr */
1420 lp
->dma
.rx_reclaim_desc
= p
;
1421 DBG_PRINT( "reclaim_descriptor: 0x%p\n", p
);
1424 for( i
= 0; i
< NUM_RX_DESC
; i
++ ) {
1425 if( lp
->dma
.rx_packet
[i
] == NULL
) {
1429 /* An Rx buffer descriptor is being given back by the HCF */
1430 lp
->dma
.rx_packet
[i
] = p
;
1431 lp
->dma
.rx_rsc_ind
++;
1432 DBG_PRINT( "rx_packet[%d] 0x%p\n", i
, lp
->dma
.rx_packet
[i
] );
1435 DBG_LEAVE( DbgInfo
);
1436 } // wl_pci_dma_hcf_reclaim_rx
1437 /*============================================================================*/
1439 /*******************************************************************************
1440 * wl_pci_dma_get_tx_packet()
1441 *******************************************************************************
1445 * Obtains a Tx descriptor from the chain to use for Tx.
1449 * lp - a pointer to the device's wl_private structure.
1453 * A pointer to the retrieved descriptor
1455 ******************************************************************************/
1456 DESC_STRCT
* wl_pci_dma_get_tx_packet( struct wl_private
*lp
)
1459 DESC_STRCT
*desc
= NULL
;
1460 /*------------------------------------------------------------------------*/
1462 for( i
= 0; i
< NUM_TX_DESC
; i
++ ) {
1463 if( lp
->dma
.tx_packet
[i
] ) {
1468 if( i
!= NUM_TX_DESC
) {
1469 desc
= lp
->dma
.tx_packet
[i
];
1471 lp
->dma
.tx_packet
[i
] = NULL
;
1472 lp
->dma
.tx_rsc_ind
--;
1474 memset( desc
->buf_addr
, 0, HCF_DMA_TX_BUF1_SIZE
);
1478 } // wl_pci_dma_get_tx_packet
1479 /*============================================================================*/
1481 /*******************************************************************************
1482 * wl_pci_dma_put_tx_packet()
1483 *******************************************************************************
1487 * Returns a Tx descriptor to the chain.
1491 * lp - a pointer to the device's wl_private structure.
1492 * desc - a pointer to the descriptor to return.
1498 ******************************************************************************/
1499 void wl_pci_dma_put_tx_packet( struct wl_private
*lp
, DESC_STRCT
*desc
)
1502 /*------------------------------------------------------------------------*/
1504 for( i
= 0; i
< NUM_TX_DESC
; i
++ ) {
1505 if( lp
->dma
.tx_packet
[i
] == NULL
) {
1510 if( i
!= NUM_TX_DESC
) {
1511 lp
->dma
.tx_packet
[i
] = desc
;
1512 lp
->dma
.tx_rsc_ind
++;
1514 } // wl_pci_dma_put_tx_packet
1515 /*============================================================================*/
1517 /*******************************************************************************
1518 * wl_pci_dma_hcf_reclaim_tx()
1519 *******************************************************************************
1523 * Reclaim Tx packets that have either been processed by the HCF due to a
1524 * port disable or a Tx completion.
1528 * lp - the device's private adapter structure
1533 * errno value otherwise
1535 ******************************************************************************/
1536 void wl_pci_dma_hcf_reclaim_tx( struct wl_private
*lp
)
1540 /*------------------------------------------------------------------------*/
1542 DBG_FUNC( "wl_pci_dma_hcf_reclaim_tx" );
1543 DBG_ENTER( DbgInfo
);
1545 //if( lp->dma.status == 0 )
1547 while ( ( p
= hcf_dma_tx_get( &lp
->hcfCtx
) ) != NULL
) {
1549 if( p
!= NULL
&& p
->buf_addr
== NULL
) {
1550 /* A Reclaim descriptor is being given back by the HCF. Reclaim
1551 descriptors have a NULL buf_addr */
1552 lp
->dma
.tx_reclaim_desc
= p
;
1553 DBG_PRINT( "reclaim_descriptor: 0x%p\n", p
);
1556 for( i
= 0; i
< NUM_TX_DESC
; i
++ ) {
1557 if( lp
->dma
.tx_packet
[i
] == NULL
) {
1561 /* An Rx buffer descriptor is being given back by the HCF */
1562 lp
->dma
.tx_packet
[i
] = p
;
1563 lp
->dma
.tx_rsc_ind
++;
1564 DBG_PRINT( "tx_packet[%d] 0x%p\n", i
, lp
->dma
.tx_packet
[i
] );
1568 if( lp
->netif_queue_on
== FALSE
) {
1569 netif_wake_queue( lp
->dev
);
1570 WL_WDS_NETIF_WAKE_QUEUE( lp
);
1571 lp
->netif_queue_on
= TRUE
;
1573 DBG_LEAVE( DbgInfo
);
1575 } // wl_pci_dma_hcf_reclaim_tx
1576 /*============================================================================*/
1577 #endif // ENABLE_DMA