|
@@ -1,1478 +0,0 @@
|
|
|
-/*******************************************************************************
|
|
|
- * Agere Systems Inc.
|
|
|
- * Wireless device driver for Linux (wlags49).
|
|
|
- *
|
|
|
- * Copyright (c) 1998-2003 Agere Systems Inc.
|
|
|
- * All rights reserved.
|
|
|
- * http://www.agere.com
|
|
|
- *
|
|
|
- * Initially developed by TriplePoint, Inc.
|
|
|
- * http://www.triplepoint.com
|
|
|
- *
|
|
|
- *------------------------------------------------------------------------------
|
|
|
- *
|
|
|
- * This file contains processing and initialization specific to PCI/miniPCI
|
|
|
- * devices.
|
|
|
- *
|
|
|
- *------------------------------------------------------------------------------
|
|
|
- *
|
|
|
- * SOFTWARE LICENSE
|
|
|
- *
|
|
|
- * This software is provided subject to the following terms and conditions,
|
|
|
- * which you should read carefully before using the software. Using this
|
|
|
- * software indicates your acceptance of these terms and conditions. If you do
|
|
|
- * not agree with these terms and conditions, do not use the software.
|
|
|
- *
|
|
|
- * Copyright © 2003 Agere Systems Inc.
|
|
|
- * All rights reserved.
|
|
|
- *
|
|
|
- * Redistribution and use in source or binary forms, with or without
|
|
|
- * modifications, are permitted provided that the following conditions are met:
|
|
|
- *
|
|
|
- * . Redistributions of source code must retain the above copyright notice, this
|
|
|
- * list of conditions and the following Disclaimer as comments in the code as
|
|
|
- * well as in the documentation and/or other materials provided with the
|
|
|
- * distribution.
|
|
|
- *
|
|
|
- * . Redistributions in binary form must reproduce the above copyright notice,
|
|
|
- * this list of conditions and the following Disclaimer in the documentation
|
|
|
- * and/or other materials provided with the distribution.
|
|
|
- *
|
|
|
- * . Neither the name of Agere Systems Inc. nor the names of the contributors
|
|
|
- * may be used to endorse or promote products derived from this software
|
|
|
- * without specific prior written permission.
|
|
|
- *
|
|
|
- * Disclaimer
|
|
|
- *
|
|
|
- * THIS SOFTWARE IS PROVIDED AS IS AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
|
|
- * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
|
|
|
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY
|
|
|
- * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
|
|
|
- * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY
|
|
|
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
|
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
|
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
|
- * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT
|
|
|
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
|
|
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
|
|
- * DAMAGE.
|
|
|
- *
|
|
|
- ******************************************************************************/
|
|
|
-
|
|
|
-/*******************************************************************************
|
|
|
- * include files
|
|
|
- ******************************************************************************/
|
|
|
-#include <wireless/wl_version.h>
|
|
|
-
|
|
|
-#include <linux/module.h>
|
|
|
-#include <linux/kernel.h>
|
|
|
-#include <linux/errno.h>
|
|
|
-#include <linux/pci.h>
|
|
|
-#include <linux/sched.h>
|
|
|
-#include <linux/ptrace.h>
|
|
|
-#include <linux/ctype.h>
|
|
|
-#include <linux/string.h>
|
|
|
-//#include <linux/timer.h>
|
|
|
-#include <linux/interrupt.h>
|
|
|
-#include <linux/in.h>
|
|
|
-#include <linux/delay.h>
|
|
|
-#include <asm/io.h>
|
|
|
-#include <asm/irq.h>
|
|
|
-#include <asm/bitops.h>
|
|
|
-#include <asm/uaccess.h>
|
|
|
-
|
|
|
-#include <linux/ethtool.h>
|
|
|
-#include <linux/netdevice.h>
|
|
|
-#include <linux/etherdevice.h>
|
|
|
-#include <linux/skbuff.h>
|
|
|
-#include <linux/if_arp.h>
|
|
|
-#include <linux/ioport.h>
|
|
|
-
|
|
|
-#include <hcf/debug.h>
|
|
|
-
|
|
|
-#include <hcf.h>
|
|
|
-#include <dhf.h>
|
|
|
-#include <hcfdef.h>
|
|
|
-
|
|
|
-#include <wireless/wl_if.h>
|
|
|
-#include <wireless/wl_internal.h>
|
|
|
-#include <wireless/wl_util.h>
|
|
|
-#include <wireless/wl_main.h>
|
|
|
-#include <wireless/wl_netdev.h>
|
|
|
-#include <wireless/wl_pci.h>
|
|
|
-
|
|
|
-/* define the PCI device Table Cardname and id tables */
|
|
|
-static struct pci_device_id wl_pci_tbl[] = {
|
|
|
- { PCI_DEVICE(PCI_VENDOR_ID_WL_LKM, PCI_DEVICE_ID_WL_LKM_0), },
|
|
|
- { PCI_DEVICE(PCI_VENDOR_ID_WL_LKM, PCI_DEVICE_ID_WL_LKM_1), },
|
|
|
- { PCI_DEVICE(PCI_VENDOR_ID_WL_LKM, PCI_DEVICE_ID_WL_LKM_2), },
|
|
|
-
|
|
|
- { } /* Terminating entry */
|
|
|
-};
|
|
|
-
|
|
|
-MODULE_DEVICE_TABLE(pci, wl_pci_tbl);
|
|
|
-
|
|
|
-/*******************************************************************************
|
|
|
- * function prototypes
|
|
|
- ******************************************************************************/
|
|
|
-int wl_pci_probe( struct pci_dev *pdev,
|
|
|
- const struct pci_device_id *ent );
|
|
|
-void wl_pci_remove(struct pci_dev *pdev);
|
|
|
-int wl_pci_setup( struct pci_dev *pdev );
|
|
|
-void wl_pci_enable_cardbus_interrupts( struct pci_dev *pdev );
|
|
|
-
|
|
|
-#ifdef ENABLE_DMA
|
|
|
-int wl_pci_dma_alloc( struct pci_dev *pdev, struct wl_private *lp );
|
|
|
-int wl_pci_dma_free( struct pci_dev *pdev, struct wl_private *lp );
|
|
|
-int wl_pci_dma_alloc_tx_packet( struct pci_dev *pdev, struct wl_private *lp,
|
|
|
- DESC_STRCT **desc );
|
|
|
-int wl_pci_dma_free_tx_packet( struct pci_dev *pdev, struct wl_private *lp,
|
|
|
- DESC_STRCT **desc );
|
|
|
-int wl_pci_dma_alloc_rx_packet( struct pci_dev *pdev, struct wl_private *lp,
|
|
|
- DESC_STRCT **desc );
|
|
|
-int wl_pci_dma_free_rx_packet( struct pci_dev *pdev, struct wl_private *lp,
|
|
|
- DESC_STRCT **desc );
|
|
|
-int wl_pci_dma_alloc_desc_and_buf( struct pci_dev *pdev, struct wl_private *lp,
|
|
|
- DESC_STRCT **desc, int size );
|
|
|
-int wl_pci_dma_free_desc_and_buf( struct pci_dev *pdev, struct wl_private *lp,
|
|
|
- DESC_STRCT **desc );
|
|
|
-int wl_pci_dma_alloc_desc( struct pci_dev *pdev, struct wl_private *lp,
|
|
|
- DESC_STRCT **desc );
|
|
|
-int wl_pci_dma_free_desc( struct pci_dev *pdev, struct wl_private *lp,
|
|
|
- DESC_STRCT **desc );
|
|
|
-int wl_pci_dma_alloc_buf( struct pci_dev *pdev, struct wl_private *lp,
|
|
|
- DESC_STRCT *desc, int size );
|
|
|
-int wl_pci_dma_free_buf( struct pci_dev *pdev, struct wl_private *lp,
|
|
|
- DESC_STRCT *desc );
|
|
|
-
|
|
|
-void wl_pci_dma_hcf_reclaim_rx( struct wl_private *lp );
|
|
|
-#endif // ENABLE_DMA
|
|
|
-
|
|
|
-/*******************************************************************************
|
|
|
- * PCI module function registration
|
|
|
- ******************************************************************************/
|
|
|
-static struct pci_driver wl_driver = {
|
|
|
- .name = KBUILD_MODNAME,
|
|
|
- .id_table = wl_pci_tbl,
|
|
|
- .probe = wl_pci_probe,
|
|
|
- .remove = wl_pci_remove,
|
|
|
- .suspend = NULL,
|
|
|
- .resume = NULL
|
|
|
-};
|
|
|
-
|
|
|
-/*******************************************************************************
|
|
|
- * wl_adapter_init_module()
|
|
|
- *******************************************************************************
|
|
|
- *
|
|
|
- * DESCRIPTION:
|
|
|
- *
|
|
|
- * Called by init_module() to perform PCI-specific driver initialization.
|
|
|
- *
|
|
|
- * PARAMETERS:
|
|
|
- *
|
|
|
- * N/A
|
|
|
- *
|
|
|
- * RETURNS:
|
|
|
- *
|
|
|
- * 0
|
|
|
- *
|
|
|
- ******************************************************************************/
|
|
|
-int wl_adapter_init_module( void )
|
|
|
-{
|
|
|
- int result;
|
|
|
-
|
|
|
- DBG_TRACE( DbgInfo, "wl_adapter_init_module() -- PCI\n" );
|
|
|
-
|
|
|
- result = pci_register_driver( &wl_driver ); //;?replace with pci_module_init, Rubini pg 490
|
|
|
- //;? why not do something with the result
|
|
|
-
|
|
|
- return 0;
|
|
|
-} // wl_adapter_init_module
|
|
|
-/*============================================================================*/
|
|
|
-
|
|
|
-/*******************************************************************************
|
|
|
- * wl_adapter_cleanup_module()
|
|
|
- *******************************************************************************
|
|
|
- *
|
|
|
- * DESCRIPTION:
|
|
|
- *
|
|
|
- * Called by cleanup_module() to perform PCI-specific driver cleanup.
|
|
|
- *
|
|
|
- * PARAMETERS:
|
|
|
- *
|
|
|
- * N/A
|
|
|
- *
|
|
|
- * RETURNS:
|
|
|
- *
|
|
|
- * N/A
|
|
|
- *
|
|
|
- ******************************************************************************/
|
|
|
-void wl_adapter_cleanup_module( void )
|
|
|
-{
|
|
|
- //;?how come wl_adapter_cleanup_module is located in a seemingly pci specific module
|
|
|
- DBG_TRACE( DbgInfo, "wl_adapter_cleanup_module() -- PCI\n" );
|
|
|
-
|
|
|
- pci_unregister_driver( &wl_driver );
|
|
|
-
|
|
|
- return;
|
|
|
-} // wl_adapter_cleanup_module
|
|
|
-/*============================================================================*/
|
|
|
-
|
|
|
-/*******************************************************************************
|
|
|
- * wl_adapter_insert()
|
|
|
- *******************************************************************************
|
|
|
- *
|
|
|
- * DESCRIPTION:
|
|
|
- *
|
|
|
- * Called by wl_pci_probe() to continue the process of device insertion.
|
|
|
- *
|
|
|
- * PARAMETERS:
|
|
|
- *
|
|
|
- * dev - a pointer to the device's net_device structure
|
|
|
- *
|
|
|
- * RETURNS:
|
|
|
- *
|
|
|
- * TRUE or FALSE
|
|
|
- *
|
|
|
- ******************************************************************************/
|
|
|
-int wl_adapter_insert( struct net_device *dev )
|
|
|
-{
|
|
|
- int result = FALSE;
|
|
|
-
|
|
|
- DBG_TRACE( DbgInfo, "wl_adapter_insert() -- PCI\n" );
|
|
|
-
|
|
|
- if( dev == NULL ) {
|
|
|
- DBG_ERROR( DbgInfo, "net_device pointer is NULL!!!\n" );
|
|
|
- } else if( dev->priv == NULL ) {
|
|
|
- DBG_ERROR( DbgInfo, "wl_private pointer is NULL!!!\n" );
|
|
|
- } else if( wl_insert( dev ) ) { /* Perform remaining device initialization */
|
|
|
- result = TRUE;
|
|
|
- } else {
|
|
|
- DBG_TRACE( DbgInfo, "wl_insert() FAILED\n" );
|
|
|
- }
|
|
|
- return result;
|
|
|
-} // wl_adapter_insert
|
|
|
-/*============================================================================*/
|
|
|
-
|
|
|
-/*******************************************************************************
|
|
|
- * wl_adapter_open()
|
|
|
- *******************************************************************************
|
|
|
- *
|
|
|
- * DESCRIPTION:
|
|
|
- *
|
|
|
- * Open the device.
|
|
|
- *
|
|
|
- * PARAMETERS:
|
|
|
- *
|
|
|
- * dev - a pointer to the device's net_device structure
|
|
|
- *
|
|
|
- * RETURNS:
|
|
|
- *
|
|
|
- * an HCF status code
|
|
|
- *
|
|
|
- ******************************************************************************/
|
|
|
-int wl_adapter_open( struct net_device *dev )
|
|
|
-{
|
|
|
- int result = 0;
|
|
|
- int hcf_status = HCF_SUCCESS;
|
|
|
-
|
|
|
- DBG_TRACE( DbgInfo, "wl_adapter_open() -- PCI\n" );
|
|
|
-
|
|
|
- hcf_status = wl_open( dev );
|
|
|
-
|
|
|
- if( hcf_status != HCF_SUCCESS ) {
|
|
|
- result = -ENODEV;
|
|
|
- }
|
|
|
-
|
|
|
- return result;
|
|
|
-} // wl_adapter_open
|
|
|
-/*============================================================================*/
|
|
|
-
|
|
|
-/*******************************************************************************
|
|
|
- * wl_adapter_close()
|
|
|
- *******************************************************************************
|
|
|
- *
|
|
|
- * DESCRIPTION:
|
|
|
- *
|
|
|
- * Close the device
|
|
|
- *
|
|
|
- * PARAMETERS:
|
|
|
- *
|
|
|
- * dev - a pointer to the device's net_device structure
|
|
|
- *
|
|
|
- * RETURNS:
|
|
|
- *
|
|
|
- * 0
|
|
|
- *
|
|
|
- ******************************************************************************/
|
|
|
-int wl_adapter_close( struct net_device *dev )
|
|
|
-{
|
|
|
- DBG_TRACE( DbgInfo, "wl_adapter_close() -- PCI\n" );
|
|
|
- DBG_TRACE( DbgInfo, "%s: Shutting down adapter.\n", dev->name );
|
|
|
-
|
|
|
- wl_close( dev );
|
|
|
-
|
|
|
- return 0;
|
|
|
-} // wl_adapter_close
|
|
|
-/*============================================================================*/
|
|
|
-
|
|
|
-/*******************************************************************************
|
|
|
- * wl_adapter_is_open()
|
|
|
- *******************************************************************************
|
|
|
- *
|
|
|
- * DESCRIPTION:
|
|
|
- *
|
|
|
- * Check whether this device is open. Returns
|
|
|
- *
|
|
|
- * PARAMETERS:
|
|
|
- *
|
|
|
- * dev - a pointer to the device's net_device structure
|
|
|
- *
|
|
|
- * RETURNS:
|
|
|
- *
|
|
|
- * nonzero if device is open.
|
|
|
- *
|
|
|
- ******************************************************************************/
|
|
|
-int wl_adapter_is_open( struct net_device *dev )
|
|
|
-{
|
|
|
- /* This function is used in PCMCIA to check the status of the 'open' field
|
|
|
- in the dev_link_t structure associated with a network device. There
|
|
|
- doesn't seem to be an analog to this for PCI, and checking the status
|
|
|
- contained in the net_device structure doesn't have the same effect.
|
|
|
- For now, return TRUE, but find out if this is necessary for PCI. */
|
|
|
-
|
|
|
- return TRUE;
|
|
|
-} // wl_adapter_is_open
|
|
|
-/*============================================================================*/
|
|
|
-
|
|
|
-/*******************************************************************************
|
|
|
- * wl_pci_probe()
|
|
|
- *******************************************************************************
|
|
|
- *
|
|
|
- * DESCRIPTION:
|
|
|
- *
|
|
|
- * Registered in the pci_driver structure, this function is called when the
|
|
|
- * PCI subsystem finds a new PCI device which matches the information contained
|
|
|
- * in the pci_device_id table.
|
|
|
- *
|
|
|
- * PARAMETERS:
|
|
|
- *
|
|
|
- * pdev - a pointer to the device's pci_dev structure
|
|
|
- * ent - this device's entry in the pci_device_id table
|
|
|
- *
|
|
|
- * RETURNS:
|
|
|
- *
|
|
|
- * 0 on success
|
|
|
- * errno value otherwise
|
|
|
- *
|
|
|
- ******************************************************************************/
|
|
|
-int wl_pci_probe( struct pci_dev *pdev,
|
|
|
- const struct pci_device_id *ent )
|
|
|
-{
|
|
|
- int result;
|
|
|
-
|
|
|
- DBG_PRINT( "%s\n", VERSION_INFO );
|
|
|
-
|
|
|
- result = wl_pci_setup( pdev );
|
|
|
-
|
|
|
- return result;
|
|
|
-} // wl_pci_probe
|
|
|
-/*============================================================================*/
|
|
|
-
|
|
|
-/*******************************************************************************
|
|
|
- * wl_pci_remove()
|
|
|
- *******************************************************************************
|
|
|
- *
|
|
|
- * DESCRIPTION:
|
|
|
- *
|
|
|
- * Registered in the pci_driver structure, this function is called when the
|
|
|
- * PCI subsystem detects that a PCI device which matches the information
|
|
|
- * contained in the pci_device_id table has been removed.
|
|
|
- *
|
|
|
- * PARAMETERS:
|
|
|
- *
|
|
|
- * pdev - a pointer to the device's pci_dev structure
|
|
|
- *
|
|
|
- * RETURNS:
|
|
|
- *
|
|
|
- * N/A
|
|
|
- *
|
|
|
- ******************************************************************************/
|
|
|
-void wl_pci_remove(struct pci_dev *pdev)
|
|
|
-{
|
|
|
- struct net_device *dev = NULL;
|
|
|
-
|
|
|
- /* Make sure the pci_dev pointer passed in is valid */
|
|
|
- if( pdev == NULL ) {
|
|
|
- DBG_ERROR( DbgInfo, "PCI subsys passed in an invalid pci_dev pointer\n" );
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- dev = pci_get_drvdata( pdev );
|
|
|
- if( dev == NULL ) {
|
|
|
- DBG_ERROR( DbgInfo, "Could not retrieve net_device structure\n" );
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- /* Perform device cleanup */
|
|
|
- wl_remove( dev );
|
|
|
- free_irq( dev->irq, dev );
|
|
|
-
|
|
|
-#ifdef ENABLE_DMA
|
|
|
- wl_pci_dma_free( pdev, dev->priv );
|
|
|
-#endif
|
|
|
-
|
|
|
- wl_device_dealloc( dev );
|
|
|
-
|
|
|
- return;
|
|
|
-} // wl_pci_remove
|
|
|
-/*============================================================================*/
|
|
|
-
|
|
|
-/*******************************************************************************
|
|
|
- * wl_pci_setup()
|
|
|
- *******************************************************************************
|
|
|
- *
|
|
|
- * DESCRIPTION:
|
|
|
- *
|
|
|
- * Called by wl_pci_probe() to begin a device's initialization process.
|
|
|
- *
|
|
|
- * PARAMETERS:
|
|
|
- *
|
|
|
- * pdev - a pointer to the device's pci_dev structure
|
|
|
- *
|
|
|
- * RETURNS:
|
|
|
- *
|
|
|
- * 0 on success
|
|
|
- * errno value otherwise
|
|
|
- *
|
|
|
- ******************************************************************************/
|
|
|
-int wl_pci_setup( struct pci_dev *pdev )
|
|
|
-{
|
|
|
- int result = 0;
|
|
|
- struct net_device *dev = NULL;
|
|
|
- struct wl_private *lp = NULL;
|
|
|
-
|
|
|
- /* Make sure the pci_dev pointer passed in is valid */
|
|
|
- if( pdev == NULL ) {
|
|
|
- DBG_ERROR( DbgInfo, "PCI subsys passed in an invalid pci_dev pointer\n" );
|
|
|
- return -ENODEV;
|
|
|
- }
|
|
|
-
|
|
|
- result = pci_enable_device( pdev );
|
|
|
- if( result != 0 ) {
|
|
|
- DBG_ERROR( DbgInfo, "pci_enable_device() failed\n" );
|
|
|
- return result;
|
|
|
- }
|
|
|
-
|
|
|
- /* We found our device! Let's register it with the system */
|
|
|
- DBG_TRACE( DbgInfo, "Found our device, now registering\n" );
|
|
|
- dev = wl_device_alloc( );
|
|
|
- if( dev == NULL ) {
|
|
|
- DBG_ERROR( DbgInfo, "Could not register device!!!\n" );
|
|
|
- return -ENOMEM;
|
|
|
- }
|
|
|
-
|
|
|
- /* Make sure that space was allocated for our private adapter struct */
|
|
|
- if( dev->priv == NULL ) {
|
|
|
- DBG_ERROR( DbgInfo, "Private adapter struct was not allocated!!!\n" );
|
|
|
- wl_device_dealloc(dev);
|
|
|
- return -ENOMEM;
|
|
|
- }
|
|
|
-
|
|
|
-#ifdef ENABLE_DMA
|
|
|
- /* Allocate DMA Descriptors */
|
|
|
- if( wl_pci_dma_alloc( pdev, dev->priv ) < 0 ) {
|
|
|
- DBG_ERROR( DbgInfo, "Could not allocate DMA descriptor memory!!!\n" );
|
|
|
- wl_device_dealloc(dev);
|
|
|
- return -ENOMEM;
|
|
|
- }
|
|
|
-#endif
|
|
|
-
|
|
|
- /* Register our private adapter structure with PCI */
|
|
|
- pci_set_drvdata( pdev, dev );
|
|
|
-
|
|
|
- /* Fill out bus specific information in the net_device struct */
|
|
|
- dev->irq = pdev->irq;
|
|
|
- SET_MODULE_OWNER( dev );
|
|
|
-
|
|
|
- DBG_TRACE( DbgInfo, "Device Base Address: %#03lx\n", pdev->resource[0].start );
|
|
|
- dev->base_addr = pdev->resource[0].start;
|
|
|
-
|
|
|
- /* Initialize our device here */
|
|
|
- if( !wl_adapter_insert( dev )) {
|
|
|
- DBG_ERROR( DbgInfo, "wl_adapter_insert() FAILED!!!\n" );
|
|
|
- wl_device_dealloc( dev );
|
|
|
- return -EINVAL;
|
|
|
- }
|
|
|
-
|
|
|
- /* Register our ISR */
|
|
|
- DBG_TRACE( DbgInfo, "Registering ISR...\n" );
|
|
|
-
|
|
|
- result = request_irq(dev->irq, wl_isr, SA_SHIRQ, dev->name, dev);
|
|
|
- if( result ) {
|
|
|
- DBG_WARNING( DbgInfo, "Could not register ISR!!!\n" );
|
|
|
- wl_remove(dev);
|
|
|
- wl_device_dealloc(dev);
|
|
|
- return result;
|
|
|
- }
|
|
|
-
|
|
|
- /* Make sure interrupts are enabled properly for CardBus */
|
|
|
- lp = dev->priv;
|
|
|
-
|
|
|
- if( lp->hcfCtx.IFB_BusType == CFG_NIC_BUS_TYPE_CARDBUS ||
|
|
|
- lp->hcfCtx.IFB_BusType == CFG_NIC_BUS_TYPE_PCI ) {
|
|
|
- DBG_TRACE( DbgInfo, "This is a PCI/CardBus card, enable interrupts\n" );
|
|
|
- wl_pci_enable_cardbus_interrupts( pdev );
|
|
|
- }
|
|
|
-
|
|
|
- /* Enable bus mastering */
|
|
|
- pci_set_master( pdev );
|
|
|
-
|
|
|
- return 0;
|
|
|
-} // wl_pci_setup
|
|
|
-/*============================================================================*/
|
|
|
-
|
|
|
-/*******************************************************************************
|
|
|
- * wl_pci_enable_cardbus_interrupts()
|
|
|
- *******************************************************************************
|
|
|
- *
|
|
|
- * DESCRIPTION:
|
|
|
- *
|
|
|
- * Called by wl_pci_setup() to enable interrupts on a CardBus device. This
|
|
|
- * is done by writing bit 15 to the function event mask register. This
|
|
|
- * CardBus-specific register is located in BAR2 (counting from BAR0), in memory
|
|
|
- * space at byte offset 1f4 (7f4 for WARP).
|
|
|
- *
|
|
|
- * PARAMETERS:
|
|
|
- *
|
|
|
- * pdev - a pointer to the device's pci_dev structure
|
|
|
- *
|
|
|
- * RETURNS:
|
|
|
- *
|
|
|
- * N/A
|
|
|
- *
|
|
|
- ******************************************************************************/
|
|
|
-void wl_pci_enable_cardbus_interrupts( struct pci_dev *pdev )
|
|
|
-{
|
|
|
- u32 bar2_reg;
|
|
|
- u32 mem_addr_bus;
|
|
|
- u32 func_evt_mask_reg;
|
|
|
- void *mem_addr_kern = NULL;
|
|
|
-
|
|
|
- /* Initialize to known bad values */
|
|
|
- bar2_reg = 0xdeadbeef;
|
|
|
- mem_addr_bus = 0xdeadbeef;
|
|
|
-
|
|
|
- /* Read the BAR2 register; this register contains the base address of the
|
|
|
- memory region where the function event mask register lives */
|
|
|
- pci_read_config_dword( pdev, PCI_BASE_ADDRESS_2, &bar2_reg );
|
|
|
- mem_addr_bus = bar2_reg & PCI_BASE_ADDRESS_MEM_MASK;
|
|
|
-
|
|
|
- /* Once the base address is obtained, remap the memory region to kernel
|
|
|
- space so we can retrieve the register */
|
|
|
- mem_addr_kern = ioremap( mem_addr_bus, 0x200 );
|
|
|
-
|
|
|
-#ifdef HERMES25
|
|
|
-#define REG_OFFSET 0x07F4
|
|
|
-#else
|
|
|
-#define REG_OFFSET 0x01F4
|
|
|
-#endif // HERMES25
|
|
|
-
|
|
|
-#define BIT15 0x8000
|
|
|
-
|
|
|
- /* Retrieve the functional event mask register, enable interrupts by
|
|
|
- setting Bit 15, and write back the value */
|
|
|
- func_evt_mask_reg = *(u32 *)( mem_addr_kern + REG_OFFSET );
|
|
|
- func_evt_mask_reg |= BIT15;
|
|
|
- *(u32 *)( mem_addr_kern + REG_OFFSET ) = func_evt_mask_reg;
|
|
|
-
|
|
|
- /* Once complete, unmap the region and exit */
|
|
|
- iounmap( mem_addr_kern );
|
|
|
-} // wl_pci_enable_cardbus_interrupts
|
|
|
-/*============================================================================*/
|
|
|
-
|
|
|
-#ifdef ENABLE_DMA
|
|
|
-/*******************************************************************************
|
|
|
- * wl_pci_dma_alloc()
|
|
|
- *******************************************************************************
|
|
|
- *
|
|
|
- * DESCRIPTION:
|
|
|
- *
|
|
|
- * Allocates all resources needed for PCI/CardBus DMA operation
|
|
|
- *
|
|
|
- * PARAMETERS:
|
|
|
- *
|
|
|
- * pdev - a pointer to the device's pci_dev structure
|
|
|
- * lp - the device's private adapter structure
|
|
|
- *
|
|
|
- * RETURNS:
|
|
|
- *
|
|
|
- * 0 on success
|
|
|
- * errno value otherwise
|
|
|
- *
|
|
|
- ******************************************************************************/
|
|
|
-int wl_pci_dma_alloc( struct pci_dev *pdev, struct wl_private *lp )
|
|
|
-{
|
|
|
- int i;
|
|
|
- int status = 0;
|
|
|
-
|
|
|
-// lp->dma.tx_rsc_ind = lp->dma.rx_rsc_ind = 0;
|
|
|
-//
|
|
|
-// /* Alloc for the Tx chain and its reclaim descriptor */
|
|
|
-// for( i = 0; i < NUM_TX_DESC; i++ ) {
|
|
|
-// status = wl_pci_dma_alloc_tx_packet( pdev, lp, &lp->dma.tx_packet[i] );
|
|
|
-// if( status == 0 ) {
|
|
|
-// DBG_PRINT( "lp->dma.tx_packet[%d] : 0x%p\n", i, lp->dma.tx_packet[i] );
|
|
|
-// DBG_PRINT( "lp->dma.tx_packet[%d]->next_desc_addr : 0x%p\n", i, lp->dma.tx_packet[i]->next_desc_addr );
|
|
|
-// lp->dma.tx_rsc_ind++;
|
|
|
-// } else {
|
|
|
-// DBG_ERROR( DbgInfo, "Could not alloc DMA Tx Packet\n" );
|
|
|
-// break;
|
|
|
-// }
|
|
|
-// }
|
|
|
-// if( status == 0 ) {
|
|
|
-// status = wl_pci_dma_alloc_desc( pdev, lp, &lp->dma.tx_reclaim_desc );
|
|
|
-// DBG_PRINT( "lp->dma.tx_reclaim_desc: 0x%p\n", lp->dma.tx_reclaim_desc );
|
|
|
-// }
|
|
|
-// /* Alloc for the Rx chain and its reclaim descriptor */
|
|
|
-// if( status == 0 ) {
|
|
|
-// for( i = 0; i < NUM_RX_DESC; i++ ) {
|
|
|
-// status = wl_pci_dma_alloc_rx_packet( pdev, lp, &lp->dma.rx_packet[i] );
|
|
|
-// if( status == 0 ) {
|
|
|
-// DBG_PRINT( "lp->dma.rx_packet[%d] : 0x%p\n", i, lp->dma.rx_packet[i] );
|
|
|
-// DBG_PRINT( "lp->dma.rx_packet[%d]->next_desc_addr : 0x%p\n", i, lp->dma.rx_packet[i]->next_desc_addr );
|
|
|
-// lp->dma.rx_rsc_ind++;
|
|
|
-// } else {
|
|
|
-// DBG_ERROR( DbgInfo, "Could not alloc DMA Rx Packet\n" );
|
|
|
-// break;
|
|
|
-// }
|
|
|
-// }
|
|
|
-// }
|
|
|
-// if( status == 0 ) {
|
|
|
-// status = wl_pci_dma_alloc_desc( pdev, lp, &lp->dma.rx_reclaim_desc );
|
|
|
-// DBG_PRINT( "lp->dma.rx_reclaim_desc: 0x%p\n", lp->dma.rx_reclaim_desc );
|
|
|
-// }
|
|
|
-// /* Store status, as host should not call HCF functions if this fails */
|
|
|
-// lp->dma.status = status; //;?all useages of dma.status have been commented out
|
|
|
- return status;
|
|
|
-} // wl_pci_dma_alloc
|
|
|
-/*============================================================================*/
|
|
|
-
|
|
|
-/*******************************************************************************
|
|
|
- * wl_pci_dma_free()
|
|
|
- *******************************************************************************
|
|
|
- *
|
|
|
- * DESCRIPTION:
|
|
|
- *
|
|
|
- * Deallocated all resources needed for PCI/CardBus DMA operation
|
|
|
- *
|
|
|
- * PARAMETERS:
|
|
|
- *
|
|
|
- * pdev - a pointer to the device's pci_dev structure
|
|
|
- * lp - the device's private adapter structure
|
|
|
- *
|
|
|
- * RETURNS:
|
|
|
- *
|
|
|
- * 0 on success
|
|
|
- * errno value otherwise
|
|
|
- *
|
|
|
- ******************************************************************************/
|
|
|
-int wl_pci_dma_free( struct pci_dev *pdev, struct wl_private *lp )
|
|
|
-{
|
|
|
- int i;
|
|
|
- int status = 0;
|
|
|
-
|
|
|
- /* Reclaim all Rx packets that were handed over to the HCF */
|
|
|
- /* Do I need to do this? Before this free is called, I've already disabled
|
|
|
- the port which will call wl_pci_dma_hcf_reclaim */
|
|
|
- //if( lp->dma.status == 0 )
|
|
|
- //{
|
|
|
- // wl_pci_dma_hcf_reclaim( lp );
|
|
|
- //}
|
|
|
-
|
|
|
- /* Free everything needed for DMA Rx */
|
|
|
- for( i = 0; i < NUM_RX_DESC; i++ ) {
|
|
|
- if( lp->dma.rx_packet[i] ) {
|
|
|
- status = wl_pci_dma_free_rx_packet( pdev, lp, &lp->dma.rx_packet[i] );
|
|
|
- if( status != 0 ) {
|
|
|
- DBG_WARNING( DbgInfo, "Problem freeing Rx packet\n" );
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- lp->dma.rx_rsc_ind = 0;
|
|
|
-
|
|
|
- if( lp->dma.rx_reclaim_desc ) {
|
|
|
- status = wl_pci_dma_free_desc( pdev, lp, &lp->dma.rx_reclaim_desc );
|
|
|
- if( status != 0 ) {
|
|
|
- DBG_WARNING( DbgInfo, "Problem freeing Rx reclaim descriptor\n" );
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /* Free everything needed for DMA Tx */
|
|
|
- for( i = 0; i < NUM_TX_DESC; i++ ) {
|
|
|
- if( lp->dma.tx_packet[i] ) {
|
|
|
- status = wl_pci_dma_free_tx_packet( pdev, lp, &lp->dma.tx_packet[i] );
|
|
|
- if( status != 0 ) {
|
|
|
- DBG_WARNING( DbgInfo, "Problem freeing Tx packet\n" );
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- lp->dma.tx_rsc_ind = 0;
|
|
|
-
|
|
|
- if( lp->dma.tx_reclaim_desc ) {
|
|
|
- status = wl_pci_dma_free_desc( pdev, lp, &lp->dma.tx_reclaim_desc );
|
|
|
- if( status != 0 ) {
|
|
|
- DBG_WARNING( DbgInfo, "Problem freeing Tx reclaim descriptor\n" );
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- return status;
|
|
|
-} // wl_pci_dma_free
|
|
|
-
|
|
|
-/*============================================================================*/
|
|
|
-
|
|
|
-/*******************************************************************************
|
|
|
- * wl_pci_dma_alloc_tx_packet()
|
|
|
- *******************************************************************************
|
|
|
- *
|
|
|
- * DESCRIPTION:
|
|
|
- *
|
|
|
- * Allocates a single Tx packet, consisting of several descriptors and
|
|
|
- * buffers. Data to transmit is first copied into the 'payload' buffer
|
|
|
- * before being transmitted.
|
|
|
- *
|
|
|
- * PARAMETERS:
|
|
|
- *
|
|
|
- * pdev - a pointer to the device's pci_dev structure
|
|
|
- * lp - the device's private adapter structure
|
|
|
- * desc - a pointer which will reference the descriptor to be alloc'd.
|
|
|
- *
|
|
|
- * RETURNS:
|
|
|
- *
|
|
|
- * 0 on success
|
|
|
- * errno value otherwise
|
|
|
- *
|
|
|
- ******************************************************************************/
|
|
|
-int wl_pci_dma_alloc_tx_packet( struct pci_dev *pdev, struct wl_private *lp,
|
|
|
- DESC_STRCT **desc )
|
|
|
-{
|
|
|
-// int status = 0;
|
|
|
-// /*------------------------------------------------------------------------*/
|
|
|
-//
|
|
|
-// if( desc == NULL ) {
|
|
|
-// status = -EFAULT;
|
|
|
-// }
|
|
|
-// if( status == 0 ) {
|
|
|
-// status = wl_pci_dma_alloc_desc_and_buf( pdev, lp, desc,
|
|
|
-// HCF_DMA_TX_BUF1_SIZE );
|
|
|
-//
|
|
|
-// if( status == 0 ) {
|
|
|
-// status = wl_pci_dma_alloc_desc_and_buf( pdev, lp,
|
|
|
-// &( (*desc)->next_desc_addr ),
|
|
|
-// HCF_MAX_PACKET_SIZE );
|
|
|
-// }
|
|
|
-// }
|
|
|
-// if( status == 0 ) {
|
|
|
-// (*desc)->next_desc_phys_addr = (*desc)->next_desc_addr->desc_phys_addr;
|
|
|
-// }
|
|
|
-// return status;
|
|
|
-} // wl_pci_dma_alloc_tx_packet
|
|
|
-/*============================================================================*/
|
|
|
-
|
|
|
-/*******************************************************************************
|
|
|
- * wl_pci_dma_free_tx_packet()
|
|
|
- *******************************************************************************
|
|
|
- *
|
|
|
- * DESCRIPTION:
|
|
|
- *
|
|
|
- * Frees a single Tx packet, described in the corresponding alloc function.
|
|
|
- *
|
|
|
- * PARAMETERS:
|
|
|
- *
|
|
|
- * pdev - a pointer to the device's pci_dev structure
|
|
|
- * lp - the device's private adapter structure
|
|
|
- * desc - a pointer which will reference the descriptor to be alloc'd.
|
|
|
- *
|
|
|
- * RETURNS:
|
|
|
- *
|
|
|
- * 0 on success
|
|
|
- * errno value otherwise
|
|
|
- *
|
|
|
- ******************************************************************************/
|
|
|
-int wl_pci_dma_free_tx_packet( struct pci_dev *pdev, struct wl_private *lp,
|
|
|
- DESC_STRCT **desc )
|
|
|
-{
|
|
|
- int status = 0;
|
|
|
- /*------------------------------------------------------------------------*/
|
|
|
-
|
|
|
- if( *desc == NULL ) {
|
|
|
- DBG_PRINT( "Null descriptor\n" );
|
|
|
- status = -EFAULT;
|
|
|
- }
|
|
|
- //;?the "limited" NDIS strategy, assuming a frame consists ALWAYS out of 2
|
|
|
- //descriptors, make this robust
|
|
|
- if( status == 0 && (*desc)->next_desc_addr ) {
|
|
|
- status = wl_pci_dma_free_desc_and_buf( pdev, lp, &(*desc)->next_desc_addr );
|
|
|
- }
|
|
|
- if( status == 0 ) {
|
|
|
- status = wl_pci_dma_free_desc_and_buf( pdev, lp, desc );
|
|
|
- }
|
|
|
- return status;
|
|
|
-} // wl_pci_dma_free_tx_packet
|
|
|
-/*============================================================================*/
|
|
|
-
|
|
|
-/*******************************************************************************
|
|
|
- * wl_pci_dma_alloc_rx_packet()
|
|
|
- *******************************************************************************
|
|
|
- *
|
|
|
- * DESCRIPTION:
|
|
|
- *
|
|
|
- * Allocates a single Rx packet, consisting of two descriptors and one
|
|
|
- * contiguous buffer. The buffer starts with the hermes-specific header.
|
|
|
- * One descriptor points at the start, the other at offset 0x3a of the
|
|
|
- * buffer.
|
|
|
- *
|
|
|
- * PARAMETERS:
|
|
|
- *
|
|
|
- * pdev - a pointer to the device's pci_dev structure
|
|
|
- * lp - the device's private adapter structure
|
|
|
- * desc - a pointer which will reference the descriptor to be alloc'd.
|
|
|
- *
|
|
|
- * RETURNS:
|
|
|
- *
|
|
|
- * 0 on success
|
|
|
- * errno value otherwise
|
|
|
- *
|
|
|
- ******************************************************************************/
|
|
|
-int wl_pci_dma_alloc_rx_packet( struct pci_dev *pdev, struct wl_private *lp,
|
|
|
- DESC_STRCT **desc )
|
|
|
-{
|
|
|
- int status = 0;
|
|
|
- DESC_STRCT *p;
|
|
|
- /*------------------------------------------------------------------------*/
|
|
|
-
|
|
|
-// if( desc == NULL ) {
|
|
|
-// status = -EFAULT;
|
|
|
-// }
|
|
|
-// //;?the "limited" NDIS strategy, assuming a frame consists ALWAYS out of 2
|
|
|
-// //descriptors, make this robust
|
|
|
-// if( status == 0 ) {
|
|
|
-// status = wl_pci_dma_alloc_desc( pdev, lp, desc );
|
|
|
-// }
|
|
|
-// if( status == 0 ) {
|
|
|
-// status = wl_pci_dma_alloc_buf( pdev, lp, *desc, HCF_MAX_PACKET_SIZE );
|
|
|
-// }
|
|
|
-// if( status == 0 ) {
|
|
|
-// status = wl_pci_dma_alloc_desc( pdev, lp, &p );
|
|
|
-// }
|
|
|
-// if( status == 0 ) {
|
|
|
-// /* Size of 1st descriptor becomes 0x3a bytes */
|
|
|
-// SET_BUF_SIZE( *desc, HCF_DMA_RX_BUF1_SIZE );
|
|
|
-//
|
|
|
-// /* Make 2nd descriptor point at offset 0x3a of the buffer */
|
|
|
-// SET_BUF_SIZE( p, ( HCF_MAX_PACKET_SIZE - HCF_DMA_RX_BUF1_SIZE ));
|
|
|
-// p->buf_addr = (*desc)->buf_addr + HCF_DMA_RX_BUF1_SIZE;
|
|
|
-// p->buf_phys_addr = (*desc)->buf_phys_addr + HCF_DMA_RX_BUF1_SIZE;
|
|
|
-// p->next_desc_addr = NULL;
|
|
|
-//
|
|
|
-// /* Chain 2nd descriptor to 1st descriptor */
|
|
|
-// (*desc)->next_desc_addr = p;
|
|
|
-// (*desc)->next_desc_phys_addr = p->desc_phys_addr;
|
|
|
-// }
|
|
|
-
|
|
|
- return status;
|
|
|
-} // wl_pci_dma_alloc_rx_packet
|
|
|
-/*============================================================================*/
|
|
|
-
|
|
|
-/*******************************************************************************
|
|
|
- * wl_pci_dma_free_rx_packet()
|
|
|
- *******************************************************************************
|
|
|
- *
|
|
|
- * DESCRIPTION:
|
|
|
- *
|
|
|
- * Frees a single Rx packet, described in the corresponding alloc function.
|
|
|
- *
|
|
|
- * PARAMETERS:
|
|
|
- *
|
|
|
- * pdev - a pointer to the device's pci_dev structure
|
|
|
- * lp - the device's private adapter structure
|
|
|
- * desc - a pointer which will reference the descriptor to be alloc'd.
|
|
|
- *
|
|
|
- * RETURNS:
|
|
|
- *
|
|
|
- * 0 on success
|
|
|
- * errno value otherwise
|
|
|
- *
|
|
|
- ******************************************************************************/
|
|
|
-int wl_pci_dma_free_rx_packet( struct pci_dev *pdev, struct wl_private *lp,
|
|
|
- DESC_STRCT **desc )
|
|
|
-{
|
|
|
- int status = 0;
|
|
|
- DESC_STRCT *p;
|
|
|
- /*------------------------------------------------------------------------*/
|
|
|
-
|
|
|
- if( *desc == NULL ) {
|
|
|
- status = -EFAULT;
|
|
|
- }
|
|
|
- if( status == 0 ) {
|
|
|
- p = (*desc)->next_desc_addr;
|
|
|
-
|
|
|
- /* Free the 2nd descriptor */
|
|
|
- if( p != NULL ) {
|
|
|
- p->buf_addr = NULL;
|
|
|
- p->buf_phys_addr = 0;
|
|
|
-
|
|
|
- status = wl_pci_dma_free_desc( pdev, lp, &p );
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /* Free the buffer and 1st descriptor */
|
|
|
- if( status == 0 ) {
|
|
|
- SET_BUF_SIZE( *desc, HCF_MAX_PACKET_SIZE );
|
|
|
- status = wl_pci_dma_free_desc_and_buf( pdev, lp, desc );
|
|
|
- }
|
|
|
- return status;
|
|
|
-} // wl_pci_dma_free_rx_packet
|
|
|
-/*============================================================================*/
|
|
|
-
|
|
|
-/*******************************************************************************
|
|
|
- * wl_pci_dma_alloc_desc_and_buf()
|
|
|
- *******************************************************************************
|
|
|
- *
|
|
|
- * DESCRIPTION:
|
|
|
- *
|
|
|
- * Allocates a DMA descriptor and buffer, and associates them with one
|
|
|
- * another.
|
|
|
- *
|
|
|
- * PARAMETERS:
|
|
|
- *
|
|
|
- * pdev - a pointer to the device's pci_dev structure
|
|
|
- * lp - the device's private adapter structure
|
|
|
- * desc - a pointer which will reference the descriptor to be alloc'd
|
|
|
- *
|
|
|
- * RETURNS:
|
|
|
- *
|
|
|
- * 0 on success
|
|
|
- * errno value otherwise
|
|
|
- *
|
|
|
- ******************************************************************************/
|
|
|
-int wl_pci_dma_alloc_desc_and_buf( struct pci_dev *pdev, struct wl_private *lp,
|
|
|
- DESC_STRCT **desc, int size )
|
|
|
-{
|
|
|
- int status = 0;
|
|
|
- /*------------------------------------------------------------------------*/
|
|
|
-
|
|
|
-// if( desc == NULL ) {
|
|
|
-// status = -EFAULT;
|
|
|
-// }
|
|
|
-// if( status == 0 ) {
|
|
|
-// status = wl_pci_dma_alloc_desc( pdev, lp, desc );
|
|
|
-//
|
|
|
-// if( status == 0 ) {
|
|
|
-// status = wl_pci_dma_alloc_buf( pdev, lp, *desc, size );
|
|
|
-// }
|
|
|
-// }
|
|
|
- return status;
|
|
|
-} // wl_pci_dma_alloc_desc_and_buf
|
|
|
-/*============================================================================*/
|
|
|
-
|
|
|
-/*******************************************************************************
|
|
|
- * wl_pci_dma_free_desc_and_buf()
|
|
|
- *******************************************************************************
|
|
|
- *
|
|
|
- * DESCRIPTION:
|
|
|
- *
|
|
|
- * Frees a DMA descriptor and associated buffer.
|
|
|
- *
|
|
|
- * PARAMETERS:
|
|
|
- *
|
|
|
- * pdev - a pointer to the device's pci_dev structure
|
|
|
- * lp - the device's private adapter structure
|
|
|
- * desc - a pointer which will reference the descriptor to be alloc'd
|
|
|
- *
|
|
|
- * RETURNS:
|
|
|
- *
|
|
|
- * 0 on success
|
|
|
- * errno value otherwise
|
|
|
- *
|
|
|
- ******************************************************************************/
|
|
|
-int wl_pci_dma_free_desc_and_buf( struct pci_dev *pdev, struct wl_private *lp,
|
|
|
- DESC_STRCT **desc )
|
|
|
-{
|
|
|
- int status = 0;
|
|
|
- /*------------------------------------------------------------------------*/
|
|
|
-
|
|
|
- if( desc == NULL ) {
|
|
|
- status = -EFAULT;
|
|
|
- }
|
|
|
- if( status == 0 && *desc == NULL ) {
|
|
|
- status = -EFAULT;
|
|
|
- }
|
|
|
- if( status == 0 ) {
|
|
|
- status = wl_pci_dma_free_buf( pdev, lp, *desc );
|
|
|
-
|
|
|
- if( status == 0 ) {
|
|
|
- status = wl_pci_dma_free_desc( pdev, lp, desc );
|
|
|
- }
|
|
|
- }
|
|
|
- return status;
|
|
|
-} // wl_pci_dma_free_desc_and_buf
|
|
|
-/*============================================================================*/
|
|
|
-
|
|
|
-/*******************************************************************************
|
|
|
- * wl_pci_dma_alloc_desc()
|
|
|
- *******************************************************************************
|
|
|
- *
|
|
|
- * DESCRIPTION:
|
|
|
- *
|
|
|
- * Allocates one DMA descriptor in cache coherent memory.
|
|
|
- *
|
|
|
- * PARAMETERS:
|
|
|
- *
|
|
|
- * pdev - a pointer to the device's pci_dev structure
|
|
|
- * lp - the device's private adapter structure
|
|
|
- *
|
|
|
- * RETURNS:
|
|
|
- *
|
|
|
- * 0 on success
|
|
|
- * errno value otherwise
|
|
|
- *
|
|
|
- ******************************************************************************/
|
|
|
-int wl_pci_dma_alloc_desc( struct pci_dev *pdev, struct wl_private *lp,
|
|
|
- DESC_STRCT **desc )
|
|
|
-{
|
|
|
-// int status = 0;
|
|
|
-// dma_addr_t pa;
|
|
|
-//
|
|
|
-// if( desc == NULL ) {
|
|
|
-// status = -EFAULT;
|
|
|
-// }
|
|
|
-// if( status == 0 ) {
|
|
|
-// *desc = pci_alloc_consistent( pdev, sizeof( DESC_STRCT ), &pa );
|
|
|
-// }
|
|
|
-// if( *desc == NULL ) {
|
|
|
-// DBG_ERROR( DbgInfo, "pci_alloc_consistent() failed\n" );
|
|
|
-// status = -ENOMEM;
|
|
|
-// } else {
|
|
|
-// memset( *desc, 0, sizeof( DESC_STRCT ));
|
|
|
-// (*desc)->desc_phys_addr = cpu_to_le32( pa );
|
|
|
-// }
|
|
|
-// return status;
|
|
|
-} // wl_pci_dma_alloc_desc
|
|
|
-/*============================================================================*/
|
|
|
-
|
|
|
-/*******************************************************************************
|
|
|
- * wl_pci_dma_free_desc()
|
|
|
- *******************************************************************************
|
|
|
- *
|
|
|
- * DESCRIPTION:
|
|
|
- *
|
|
|
- * Frees one DMA descriptor in cache coherent memory.
|
|
|
- *
|
|
|
- * PARAMETERS:
|
|
|
- *
|
|
|
- * pdev - a pointer to the device's pci_dev structure
|
|
|
- * lp - the device's private adapter structure
|
|
|
- *
|
|
|
- * RETURNS:
|
|
|
- *
|
|
|
- * 0 on success
|
|
|
- * errno value otherwise
|
|
|
- *
|
|
|
- ******************************************************************************/
|
|
|
-int wl_pci_dma_free_desc( struct pci_dev *pdev, struct wl_private *lp,
|
|
|
- DESC_STRCT **desc )
|
|
|
-{
|
|
|
- int status = 0;
|
|
|
- /*------------------------------------------------------------------------*/
|
|
|
-
|
|
|
- if( *desc == NULL ) {
|
|
|
- status = -EFAULT;
|
|
|
- }
|
|
|
- if( status == 0 ) {
|
|
|
- pci_free_consistent( pdev, sizeof( DESC_STRCT ), *desc,
|
|
|
- (*desc)->desc_phys_addr );
|
|
|
- }
|
|
|
- *desc = NULL;
|
|
|
- return status;
|
|
|
-} // wl_pci_dma_free_desc
|
|
|
-/*============================================================================*/
|
|
|
-
|
|
|
-/*******************************************************************************
|
|
|
- * wl_pci_dma_alloc_buf()
|
|
|
- *******************************************************************************
|
|
|
- *
|
|
|
- * DESCRIPTION:
|
|
|
- *
|
|
|
- * Allocates one DMA buffer in cache coherent memory, and associates a DMA
|
|
|
- * descriptor with this buffer.
|
|
|
- *
|
|
|
- * PARAMETERS:
|
|
|
- *
|
|
|
- * pdev - a pointer to the device's pci_dev structure
|
|
|
- * lp - the device's private adapter structure
|
|
|
- *
|
|
|
- * RETURNS:
|
|
|
- *
|
|
|
- * 0 on success
|
|
|
- * errno value otherwise
|
|
|
- *
|
|
|
- ******************************************************************************/
|
|
|
-int wl_pci_dma_alloc_buf( struct pci_dev *pdev, struct wl_private *lp,
|
|
|
- DESC_STRCT *desc, int size )
|
|
|
-{
|
|
|
- int status = 0;
|
|
|
- dma_addr_t pa;
|
|
|
-//
|
|
|
-// if( desc == NULL ) {
|
|
|
-// status = -EFAULT;
|
|
|
-// }
|
|
|
-// if( status == 0 && desc->buf_addr != NULL ) {
|
|
|
-// status = -EFAULT;
|
|
|
-// }
|
|
|
-// if( status == 0 ) {
|
|
|
-// desc->buf_addr = pci_alloc_consistent( pdev, size, &pa );
|
|
|
-// }
|
|
|
-// if( desc->buf_addr == NULL ) {
|
|
|
-// DBG_ERROR( DbgInfo, "pci_alloc_consistent() failed\n" );
|
|
|
-// status = -ENOMEM;
|
|
|
-// } else {
|
|
|
-// desc->buf_phys_addr = cpu_to_le32( pa );
|
|
|
-// SET_BUF_SIZE( desc, size );
|
|
|
-// }
|
|
|
- return status;
|
|
|
-} // wl_pci_dma_alloc_buf
|
|
|
-/*============================================================================*/
|
|
|
-
|
|
|
-/*******************************************************************************
|
|
|
- * wl_pci_dma_free_buf()
|
|
|
- *******************************************************************************
|
|
|
- *
|
|
|
- * DESCRIPTION:
|
|
|
- *
|
|
|
- * Allocates one DMA buffer in cache coherent memory, and associates a DMA
|
|
|
- * descriptor with this buffer.
|
|
|
- *
|
|
|
- * PARAMETERS:
|
|
|
- *
|
|
|
- * pdev - a pointer to the device's pci_dev structure
|
|
|
- * lp - the device's private adapter structure
|
|
|
- *
|
|
|
- * RETURNS:
|
|
|
- *
|
|
|
- * 0 on success
|
|
|
- * errno value otherwise
|
|
|
- *
|
|
|
- ******************************************************************************/
|
|
|
-int wl_pci_dma_free_buf( struct pci_dev *pdev, struct wl_private *lp,
|
|
|
- DESC_STRCT *desc )
|
|
|
-{
|
|
|
- int status = 0;
|
|
|
- /*------------------------------------------------------------------------*/
|
|
|
-
|
|
|
- if( desc == NULL ) {
|
|
|
- status = -EFAULT;
|
|
|
- }
|
|
|
- if( status == 0 && desc->buf_addr == NULL ) {
|
|
|
- status = -EFAULT;
|
|
|
- }
|
|
|
- if( status == 0 ) {
|
|
|
- pci_free_consistent( pdev, GET_BUF_SIZE( desc ), desc->buf_addr,
|
|
|
- desc->buf_phys_addr );
|
|
|
-
|
|
|
- desc->buf_addr = 0;
|
|
|
- desc->buf_phys_addr = 0;
|
|
|
- SET_BUF_SIZE( desc, 0 );
|
|
|
- }
|
|
|
- return status;
|
|
|
-} // wl_pci_dma_free_buf
|
|
|
-/*============================================================================*/
|
|
|
-
|
|
|
-/*******************************************************************************
|
|
|
- * wl_pci_dma_hcf_supply()
|
|
|
- *******************************************************************************
|
|
|
- *
|
|
|
- * DESCRIPTION:
|
|
|
- *
|
|
|
- * Supply HCF with DMA-related resources. These consist of:
|
|
|
- * - buffers and descriptors for receive purposes
|
|
|
- * - one 'reclaim' descriptor for the transmit path, used to fulfill a
|
|
|
- * certain H25 DMA engine requirement
|
|
|
- * - one 'reclaim' descriptor for the receive path, used to fulfill a
|
|
|
- * certain H25 DMA engine requirement
|
|
|
- *
|
|
|
- * This function is called at start-of-day or at re-initialization.
|
|
|
- *
|
|
|
- * PARAMETERS:
|
|
|
- *
|
|
|
- * lp - the device's private adapter structure
|
|
|
- *
|
|
|
- * RETURNS:
|
|
|
- *
|
|
|
- * 0 on success
|
|
|
- * errno value otherwise
|
|
|
- *
|
|
|
- ******************************************************************************/
|
|
|
-void wl_pci_dma_hcf_supply( struct wl_private *lp )
|
|
|
-{
|
|
|
- int i;
|
|
|
-
|
|
|
- //if( lp->dma.status == 0 );
|
|
|
- //{
|
|
|
- /* Hand over the Rx/Tx reclaim descriptors to the HCF */
|
|
|
- if( lp->dma.tx_reclaim_desc ) {
|
|
|
- DBG_PRINT( "lp->dma.tx_reclaim_desc: 0x%p\n", lp->dma.tx_reclaim_desc );
|
|
|
- hcf_dma_tx_put( &lp->hcfCtx, lp->dma.tx_reclaim_desc, 0 );
|
|
|
- lp->dma.tx_reclaim_desc = NULL;
|
|
|
- DBG_PRINT( "lp->dma.tx_reclaim_desc: 0x%p\n", lp->dma.tx_reclaim_desc );
|
|
|
- }
|
|
|
- if( lp->dma.rx_reclaim_desc ) {
|
|
|
- DBG_PRINT( "lp->dma.rx_reclaim_desc: 0x%p\n", lp->dma.rx_reclaim_desc );
|
|
|
- hcf_dma_rx_put( &lp->hcfCtx, lp->dma.rx_reclaim_desc );
|
|
|
- lp->dma.rx_reclaim_desc = NULL;
|
|
|
- DBG_PRINT( "lp->dma.rx_reclaim_desc: 0x%p\n", lp->dma.rx_reclaim_desc );
|
|
|
- }
|
|
|
- /* Hand over the Rx descriptor chain to the HCF */
|
|
|
- for( i = 0; i < NUM_RX_DESC; i++ ) {
|
|
|
- DBG_PRINT( "lp->dma.rx_packet[%d]: 0x%p\n", i, lp->dma.rx_packet[i] );
|
|
|
- hcf_dma_rx_put( &lp->hcfCtx, lp->dma.rx_packet[i] );
|
|
|
- lp->dma.rx_packet[i] = NULL;
|
|
|
- DBG_PRINT( "lp->dma.rx_packet[%d]: 0x%p\n", i, lp->dma.rx_packet[i] );
|
|
|
- }
|
|
|
- //}
|
|
|
-
|
|
|
- return;
|
|
|
-} // wl_pci_dma_hcf_supply
|
|
|
-/*============================================================================*/
|
|
|
-
|
|
|
-/*******************************************************************************
|
|
|
- * wl_pci_dma_hcf_reclaim()
|
|
|
- *******************************************************************************
|
|
|
- *
|
|
|
- * DESCRIPTION:
|
|
|
- *
|
|
|
- * Return DMA-related resources from the HCF. These consist of:
|
|
|
- * - buffers and descriptors for receive purposes
|
|
|
- * - buffers and descriptors for transmit purposes
|
|
|
- * - one 'reclaim' descriptor for the transmit path, used to fulfill a
|
|
|
- * certain H25 DMA engine requirement
|
|
|
- * - one 'reclaim' descriptor for the receive path, used to fulfill a
|
|
|
- * certain H25 DMA engine requirement
|
|
|
- *
|
|
|
- * This function is called at end-of-day or at re-initialization.
|
|
|
- *
|
|
|
- * PARAMETERS:
|
|
|
- *
|
|
|
- * lp - the device's private adapter structure
|
|
|
- *
|
|
|
- * RETURNS:
|
|
|
- *
|
|
|
- * 0 on success
|
|
|
- * errno value otherwise
|
|
|
- *
|
|
|
- ******************************************************************************/
|
|
|
-void wl_pci_dma_hcf_reclaim( struct wl_private *lp )
|
|
|
-{
|
|
|
- int i;
|
|
|
-
|
|
|
- wl_pci_dma_hcf_reclaim_rx( lp );
|
|
|
- for( i = 0; i < NUM_RX_DESC; i++ ) {
|
|
|
- DBG_PRINT( "rx_packet[%d] 0x%p\n", i, lp->dma.rx_packet[i] );
|
|
|
-// if( lp->dma.rx_packet[i] == NULL ) {
|
|
|
-// DBG_PRINT( "wl_pci_dma_hcf_reclaim: rx_packet[%d] NULL\n", i );
|
|
|
-// }
|
|
|
- }
|
|
|
-
|
|
|
- wl_pci_dma_hcf_reclaim_tx( lp );
|
|
|
- for( i = 0; i < NUM_TX_DESC; i++ ) {
|
|
|
- DBG_PRINT( "tx_packet[%d] 0x%p\n", i, lp->dma.tx_packet[i] );
|
|
|
-// if( lp->dma.tx_packet[i] == NULL ) {
|
|
|
-// DBG_PRINT( "wl_pci_dma_hcf_reclaim: tx_packet[%d] NULL\n", i );
|
|
|
-// }
|
|
|
- }
|
|
|
-
|
|
|
- return;
|
|
|
-} // wl_pci_dma_hcf_reclaim
|
|
|
-/*============================================================================*/
|
|
|
-
|
|
|
-/*******************************************************************************
|
|
|
- * wl_pci_dma_hcf_reclaim_rx()
|
|
|
- *******************************************************************************
|
|
|
- *
|
|
|
- * DESCRIPTION:
|
|
|
- *
|
|
|
- * Reclaim Rx packets that have already been processed by the HCF.
|
|
|
- *
|
|
|
- * PARAMETERS:
|
|
|
- *
|
|
|
- * lp - the device's private adapter structure
|
|
|
- *
|
|
|
- * RETURNS:
|
|
|
- *
|
|
|
- * 0 on success
|
|
|
- * errno value otherwise
|
|
|
- *
|
|
|
- ******************************************************************************/
|
|
|
-void wl_pci_dma_hcf_reclaim_rx( struct wl_private *lp )
|
|
|
-{
|
|
|
- int i;
|
|
|
- DESC_STRCT *p;
|
|
|
-
|
|
|
- //if( lp->dma.status == 0 )
|
|
|
- //{
|
|
|
- while ( ( p = hcf_dma_rx_get( &lp->hcfCtx ) ) != NULL ) {
|
|
|
- if( p && p->buf_addr == NULL ) {
|
|
|
- /* A reclaim descriptor is being given back by the HCF. Reclaim
|
|
|
- descriptors have a NULL buf_addr */
|
|
|
- lp->dma.rx_reclaim_desc = p;
|
|
|
- DBG_PRINT( "reclaim_descriptor: 0x%p\n", p );
|
|
|
- continue;
|
|
|
- }
|
|
|
- for( i = 0; i < NUM_RX_DESC; i++ ) {
|
|
|
- if( lp->dma.rx_packet[i] == NULL ) {
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
- /* An Rx buffer descriptor is being given back by the HCF */
|
|
|
- lp->dma.rx_packet[i] = p;
|
|
|
- lp->dma.rx_rsc_ind++;
|
|
|
- DBG_PRINT( "rx_packet[%d] 0x%p\n", i, lp->dma.rx_packet[i] );
|
|
|
- }
|
|
|
- //}
|
|
|
-} // wl_pci_dma_hcf_reclaim_rx
|
|
|
-/*============================================================================*/
|
|
|
-
|
|
|
-/*******************************************************************************
|
|
|
- * wl_pci_dma_get_tx_packet()
|
|
|
- *******************************************************************************
|
|
|
- *
|
|
|
- * DESCRIPTION:
|
|
|
- *
|
|
|
- * Obtains a Tx descriptor from the chain to use for Tx.
|
|
|
- *
|
|
|
- * PARAMETERS:
|
|
|
- *
|
|
|
- * lp - a pointer to the device's wl_private structure.
|
|
|
- *
|
|
|
- * RETURNS:
|
|
|
- *
|
|
|
- * A pointer to the retrieved descriptor
|
|
|
- *
|
|
|
- ******************************************************************************/
|
|
|
-DESC_STRCT * wl_pci_dma_get_tx_packet( struct wl_private *lp )
|
|
|
-{
|
|
|
- int i;
|
|
|
- DESC_STRCT *desc = NULL;
|
|
|
- /*------------------------------------------------------------------------*/
|
|
|
-
|
|
|
- for( i = 0; i < NUM_TX_DESC; i++ ) {
|
|
|
- if( lp->dma.tx_packet[i] ) {
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if( i != NUM_TX_DESC ) {
|
|
|
- desc = lp->dma.tx_packet[i];
|
|
|
-
|
|
|
- lp->dma.tx_packet[i] = NULL;
|
|
|
- lp->dma.tx_rsc_ind--;
|
|
|
-
|
|
|
- memset( desc->buf_addr, 0, HCF_DMA_TX_BUF1_SIZE );
|
|
|
- }
|
|
|
-
|
|
|
- return desc;
|
|
|
-} // wl_pci_dma_get_tx_packet
|
|
|
-/*============================================================================*/
|
|
|
-
|
|
|
-/*******************************************************************************
|
|
|
- * wl_pci_dma_put_tx_packet()
|
|
|
- *******************************************************************************
|
|
|
- *
|
|
|
- * DESCRIPTION:
|
|
|
- *
|
|
|
- * Returns a Tx descriptor to the chain.
|
|
|
- *
|
|
|
- * PARAMETERS:
|
|
|
- *
|
|
|
- * lp - a pointer to the device's wl_private structure.
|
|
|
- * desc - a pointer to the descriptor to return.
|
|
|
- *
|
|
|
- * RETURNS:
|
|
|
- *
|
|
|
- * N/A
|
|
|
- *
|
|
|
- ******************************************************************************/
|
|
|
-void wl_pci_dma_put_tx_packet( struct wl_private *lp, DESC_STRCT *desc )
|
|
|
-{
|
|
|
- int i;
|
|
|
- /*------------------------------------------------------------------------*/
|
|
|
-
|
|
|
- for( i = 0; i < NUM_TX_DESC; i++ ) {
|
|
|
- if( lp->dma.tx_packet[i] == NULL ) {
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if( i != NUM_TX_DESC ) {
|
|
|
- lp->dma.tx_packet[i] = desc;
|
|
|
- lp->dma.tx_rsc_ind++;
|
|
|
- }
|
|
|
-} // wl_pci_dma_put_tx_packet
|
|
|
-/*============================================================================*/
|
|
|
-
|
|
|
-/*******************************************************************************
|
|
|
- * wl_pci_dma_hcf_reclaim_tx()
|
|
|
- *******************************************************************************
|
|
|
- *
|
|
|
- * DESCRIPTION:
|
|
|
- *
|
|
|
- * Reclaim Tx packets that have either been processed by the HCF due to a
|
|
|
- * port disable or a Tx completion.
|
|
|
- *
|
|
|
- * PARAMETERS:
|
|
|
- *
|
|
|
- * lp - the device's private adapter structure
|
|
|
- *
|
|
|
- * RETURNS:
|
|
|
- *
|
|
|
- * 0 on success
|
|
|
- * errno value otherwise
|
|
|
- *
|
|
|
- ******************************************************************************/
|
|
|
-void wl_pci_dma_hcf_reclaim_tx( struct wl_private *lp )
|
|
|
-{
|
|
|
- int i;
|
|
|
- DESC_STRCT *p;
|
|
|
-
|
|
|
- //if( lp->dma.status == 0 )
|
|
|
- //{
|
|
|
- while ( ( p = hcf_dma_tx_get( &lp->hcfCtx ) ) != NULL ) {
|
|
|
-
|
|
|
- if( p != NULL && p->buf_addr == NULL ) {
|
|
|
- /* A Reclaim descriptor is being given back by the HCF. Reclaim
|
|
|
- descriptors have a NULL buf_addr */
|
|
|
- lp->dma.tx_reclaim_desc = p;
|
|
|
- DBG_PRINT( "reclaim_descriptor: 0x%p\n", p );
|
|
|
- continue;
|
|
|
- }
|
|
|
- for( i = 0; i < NUM_TX_DESC; i++ ) {
|
|
|
- if( lp->dma.tx_packet[i] == NULL ) {
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
- /* An Rx buffer descriptor is being given back by the HCF */
|
|
|
- lp->dma.tx_packet[i] = p;
|
|
|
- lp->dma.tx_rsc_ind++;
|
|
|
- DBG_PRINT( "tx_packet[%d] 0x%p\n", i, lp->dma.tx_packet[i] );
|
|
|
- }
|
|
|
- //}
|
|
|
-
|
|
|
- if( lp->netif_queue_on == FALSE ) {
|
|
|
- netif_wake_queue( lp->dev );
|
|
|
- WL_WDS_NETIF_WAKE_QUEUE( lp );
|
|
|
- lp->netif_queue_on = TRUE;
|
|
|
- }
|
|
|
- return;
|
|
|
-} // wl_pci_dma_hcf_reclaim_tx
|
|
|
-/*============================================================================*/
|
|
|
-#endif // ENABLE_DMA
|