summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/staging/wlags49_h2/wl_netdev.c1949
1 files changed, 999 insertions, 950 deletions
diff --git a/drivers/staging/wlags49_h2/wl_netdev.c b/drivers/staging/wlags49_h2/wl_netdev.c
index 85fdeda..ae42c8e 100644
--- a/drivers/staging/wlags49_h2/wl_netdev.c
+++ b/drivers/staging/wlags49_h2/wl_netdev.c
@@ -104,16 +104,15 @@
#ifdef USE_PROFILE
#include <wl_profile.h>
-#endif /* USE_PROFILE */
+#endif /* USE_PROFILE */
#ifdef BUS_PCMCIA
#include <wl_cs.h>
-#endif /* BUS_PCMCIA */
+#endif /* BUS_PCMCIA */
#ifdef BUS_PCI
#include <wl_pci.h>
-#endif /* BUS_PCI */
-
+#endif /* BUS_PCI */
#if HCF_ENCAP
#define MTU_MAX (HCF_MAX_MSG - ETH_HLEN - 8)
@@ -158,20 +157,21 @@
* errno value otherwise
*
******************************************************************************/
-int wl_init( struct net_device *dev )
+int wl_init(struct net_device *dev)
{
// unsigned long flags;
// struct wl_private *lp = wl_priv(dev);
- DBG_PARAM( DbgInfo, "dev", "%s (0x%p)", dev->name, dev );
+ DBG_PARAM(DbgInfo, "dev", "%s (0x%p)", dev->name, dev);
- /* Nothing to do, but grab the spinlock anyway just in case we ever need
- this routine */
+ /* Nothing to do, but grab the spinlock anyway just in case we ever need
+ this routine */
// wl_lock( lp, &flags );
// wl_unlock( lp, &flags );
- return 0;
-} // wl_init
+ return 0;
+} // wl_init
+
/*============================================================================*/
/*******************************************************************************
@@ -193,17 +193,18 @@ int wl_init( struct net_device *dev )
* errno otherwise
*
******************************************************************************/
-int wl_config( struct net_device *dev, struct ifmap *map )
+int wl_config(struct net_device *dev, struct ifmap *map)
{
- DBG_PARAM( DbgInfo, "dev", "%s (0x%p)", dev->name, dev );
- DBG_PARAM( DbgInfo, "map", "0x%p", map );
+ DBG_PARAM(DbgInfo, "dev", "%s (0x%p)", dev->name, dev);
+ DBG_PARAM(DbgInfo, "map", "0x%p", map);
+
+ /* The only thing we care about here is a port change. Since this not needed,
+ ignore the request. */
+ DBG_TRACE(DbgInfo, "%s: %s called.\n", dev->name, __func__);
- /* The only thing we care about here is a port change. Since this not needed,
- ignore the request. */
- DBG_TRACE(DbgInfo, "%s: %s called.\n", dev->name, __func__);
+ return 0;
+} // wl_config
- return 0;
-} // wl_config
/*============================================================================*/
/*******************************************************************************
@@ -224,48 +225,49 @@ int wl_config( struct net_device *dev, struct ifmap *map )
* statistics.
*
******************************************************************************/
-struct net_device_stats *wl_stats( struct net_device *dev )
+struct net_device_stats *wl_stats(struct net_device *dev)
{
#ifdef USE_WDS
- int count;
-#endif /* USE_WDS */
- unsigned long flags;
- struct net_device_stats *pStats;
- struct wl_private *lp = wl_priv(dev);
+ int count;
+#endif /* USE_WDS */
+ unsigned long flags;
+ struct net_device_stats *pStats;
+ struct wl_private *lp = wl_priv(dev);
- //DBG_PARAM( DbgInfo, "dev", "%s (0x%p)", dev->name, dev );
+ //DBG_PARAM( DbgInfo, "dev", "%s (0x%p)", dev->name, dev );
- pStats = NULL;
+ pStats = NULL;
- wl_lock( lp, &flags );
+ wl_lock(lp, &flags);
#ifdef USE_RTS
- if( lp->useRTS == 1 ) {
- wl_unlock( lp, &flags );
- return NULL;
- }
-#endif /* USE_RTS */
+ if (lp->useRTS == 1) {
+ wl_unlock(lp, &flags);
+ return NULL;
+ }
+#endif /* USE_RTS */
- /* Return the statistics for the appropriate device */
+ /* Return the statistics for the appropriate device */
#ifdef USE_WDS
- for( count = 0; count < NUM_WDS_PORTS; count++ ) {
- if( dev == lp->wds_port[count].dev ) {
- pStats = &( lp->wds_port[count].stats );
+ for (count = 0; count < NUM_WDS_PORTS; count++) {
+ if (dev == lp->wds_port[count].dev) {
+ pStats = &(lp->wds_port[count].stats);
+ }
}
- }
-#endif /* USE_WDS */
+#endif /* USE_WDS */
+
+ /* If pStats is still NULL, then the device is not a WDS port */
+ if (pStats == NULL) {
+ pStats = &(lp->stats);
+ }
- /* If pStats is still NULL, then the device is not a WDS port */
- if( pStats == NULL ) {
- pStats = &( lp->stats );
- }
+ wl_unlock(lp, &flags);
- wl_unlock( lp, &flags );
+ return pStats;
+} // wl_stats
- return pStats;
-} // wl_stats
/*============================================================================*/
/*******************************************************************************
@@ -288,75 +290,75 @@ struct net_device_stats *wl_stats( struct net_device *dev )
******************************************************************************/
int wl_open(struct net_device *dev)
{
- int status = HCF_SUCCESS;
- struct wl_private *lp = wl_priv(dev);
- unsigned long flags;
+ int status = HCF_SUCCESS;
+ struct wl_private *lp = wl_priv(dev);
+ unsigned long flags;
- wl_lock( lp, &flags );
+ wl_lock(lp, &flags);
#ifdef USE_RTS
- if( lp->useRTS == 1 ) {
- DBG_TRACE( DbgInfo, "Skipping device open, in RTS mode\n" );
- wl_unlock( lp, &flags );
- return -EIO;
- }
-#endif /* USE_RTS */
+ if (lp->useRTS == 1) {
+ DBG_TRACE(DbgInfo, "Skipping device open, in RTS mode\n");
+ wl_unlock(lp, &flags);
+ return -EIO;
+ }
+#endif /* USE_RTS */
#ifdef USE_PROFILE
- parse_config( dev );
+ parse_config(dev);
#endif
- if( lp->portState == WVLAN_PORT_STATE_DISABLED ) {
- DBG_TRACE( DbgInfo, "Enabling Port 0\n" );
- status = wl_enable( lp );
-
- if( status != HCF_SUCCESS ) {
- DBG_TRACE( DbgInfo, "Enable port 0 failed: 0x%x\n", status );
- }
- }
-
- // Holding the lock too long, make a gap to allow other processes
- wl_unlock(lp, &flags);
- wl_lock( lp, &flags );
-
- if ( strlen( lp->fw_image_filename ) ) {
- DBG_TRACE( DbgInfo, ";???? Kludgy way to force a download\n" );
- status = wl_go( lp );
- } else {
- status = wl_apply( lp );
- }
-
- // Holding the lock too long, make a gap to allow other processes
- wl_unlock(lp, &flags);
- wl_lock( lp, &flags );
-
- if( status != HCF_SUCCESS ) {
- // Unsuccessful, try reset of the card to recover
- status = wl_reset( dev );
- }
-
- // Holding the lock too long, make a gap to allow other processes
- wl_unlock(lp, &flags);
- wl_lock( lp, &flags );
-
- if( status == HCF_SUCCESS ) {
- netif_carrier_on( dev );
- WL_WDS_NETIF_CARRIER_ON( lp );
-
- lp->is_handling_int = WL_HANDLING_INT; // Start handling interrupts
- wl_act_int_on( lp );
-
- netif_start_queue( dev );
- WL_WDS_NETIF_START_QUEUE( lp );
- } else {
- wl_hcf_error( dev, status ); /* Report the error */
- netif_device_detach( dev ); /* Stop the device and queue */
- }
-
- wl_unlock( lp, &flags );
-
- return status;
-} // wl_open
+ if (lp->portState == WVLAN_PORT_STATE_DISABLED) {
+ DBG_TRACE(DbgInfo, "Enabling Port 0\n");
+ status = wl_enable(lp);
+
+ if (status != HCF_SUCCESS) {
+ DBG_TRACE(DbgInfo, "Enable port 0 failed: 0x%x\n",
+ status);
+ }
+ }
+ // Holding the lock too long, make a gap to allow other processes
+ wl_unlock(lp, &flags);
+ wl_lock(lp, &flags);
+
+ if (strlen(lp->fw_image_filename)) {
+ DBG_TRACE(DbgInfo, ";???? Kludgy way to force a download\n");
+ status = wl_go(lp);
+ } else {
+ status = wl_apply(lp);
+ }
+
+ // Holding the lock too long, make a gap to allow other processes
+ wl_unlock(lp, &flags);
+ wl_lock(lp, &flags);
+
+ if (status != HCF_SUCCESS) {
+ // Unsuccessful, try reset of the card to recover
+ status = wl_reset(dev);
+ }
+ // Holding the lock too long, make a gap to allow other processes
+ wl_unlock(lp, &flags);
+ wl_lock(lp, &flags);
+
+ if (status == HCF_SUCCESS) {
+ netif_carrier_on(dev);
+ WL_WDS_NETIF_CARRIER_ON(lp);
+
+ lp->is_handling_int = WL_HANDLING_INT; // Start handling interrupts
+ wl_act_int_on(lp);
+
+ netif_start_queue(dev);
+ WL_WDS_NETIF_START_QUEUE(lp);
+ } else {
+ wl_hcf_error(dev, status); /* Report the error */
+ netif_device_detach(dev); /* Stop the device and queue */
+ }
+
+ wl_unlock(lp, &flags);
+
+ return status;
+} // wl_open
+
/*============================================================================*/
/*******************************************************************************
@@ -377,73 +379,73 @@ int wl_open(struct net_device *dev)
* errno otherwise
*
******************************************************************************/
-int wl_close( struct net_device *dev )
+int wl_close(struct net_device *dev)
{
- struct wl_private *lp = wl_priv(dev);
- unsigned long flags;
+ struct wl_private *lp = wl_priv(dev);
+ unsigned long flags;
- DBG_PARAM(DbgInfo, "dev", "%s (0x%p)", dev->name, dev);
+ DBG_PARAM(DbgInfo, "dev", "%s (0x%p)", dev->name, dev);
- /* Mark the adapter as busy */
- netif_stop_queue( dev );
- WL_WDS_NETIF_STOP_QUEUE( lp );
+ /* Mark the adapter as busy */
+ netif_stop_queue(dev);
+ WL_WDS_NETIF_STOP_QUEUE(lp);
- netif_carrier_off( dev );
- WL_WDS_NETIF_CARRIER_OFF( lp );
+ netif_carrier_off(dev);
+ WL_WDS_NETIF_CARRIER_OFF(lp);
- /* Shutdown the adapter:
- Disable adapter interrupts
- Stop Tx/Rx
- Update statistics
- Set low power mode
- */
+ /* Shutdown the adapter:
+ Disable adapter interrupts
+ Stop Tx/Rx
+ Update statistics
+ Set low power mode
+ */
- wl_lock( lp, &flags );
+ wl_lock(lp, &flags);
- wl_act_int_off( lp );
- lp->is_handling_int = WL_NOT_HANDLING_INT; // Stop handling interrupts
+ wl_act_int_off(lp);
+ lp->is_handling_int = WL_NOT_HANDLING_INT; // Stop handling interrupts
#ifdef USE_RTS
- if( lp->useRTS == 1 ) {
- DBG_TRACE( DbgInfo, "Skipping device close, in RTS mode\n" );
- wl_unlock( lp, &flags );
- return -EIO;
- }
-#endif /* USE_RTS */
+ if (lp->useRTS == 1) {
+ DBG_TRACE(DbgInfo, "Skipping device close, in RTS mode\n");
+ wl_unlock(lp, &flags);
+ return -EIO;
+ }
+#endif /* USE_RTS */
+
+ /* Disable the ports */
+ wl_disable(lp);
- /* Disable the ports */
- wl_disable( lp );
+ wl_unlock(lp, &flags);
- wl_unlock( lp, &flags );
+ return 0;
+} // wl_close
- return 0;
-} // wl_close
/*============================================================================*/
static void wl_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
{
- strlcpy(info->driver, DRIVER_NAME, sizeof(info->driver));
- strlcpy(info->version, DRV_VERSION_STR, sizeof(info->version));
-// strlcpy(info.fw_version, priv->fw_name,
-// sizeof(info.fw_version));
-
- if (dev->dev.parent) {
- dev_set_name(dev->dev.parent, "%s", info->bus_info);
- //strlcpy(info->bus_info, dev->dev.parent->bus_id,
- // sizeof(info->bus_info));
- } else {
- snprintf(info->bus_info, sizeof(info->bus_info),
- "PCMCIA FIXME");
-// "PCMCIA 0x%lx", priv->hw.iobase);
- }
-} // wl_get_drvinfo
+ strlcpy(info->driver, DRIVER_NAME, sizeof(info->driver));
+ strlcpy(info->version, DRV_VERSION_STR, sizeof(info->version));
+// strlcpy(info.fw_version, priv->fw_name,
+// sizeof(info.fw_version));
+
+ if (dev->dev.parent) {
+ dev_set_name(dev->dev.parent, "%s", info->bus_info);
+ //strlcpy(info->bus_info, dev->dev.parent->bus_id,
+ // sizeof(info->bus_info));
+ } else {
+ snprintf(info->bus_info, sizeof(info->bus_info),
+ "PCMCIA FIXME");
+// "PCMCIA 0x%lx", priv->hw.iobase);
+ }
+} // wl_get_drvinfo
static struct ethtool_ops wl_ethtool_ops = {
- .get_drvinfo = wl_get_drvinfo,
- .get_link = ethtool_op_get_link,
+ .get_drvinfo = wl_get_drvinfo,
+ .get_link = ethtool_op_get_link,
};
-
/*******************************************************************************
* wl_ioctl()
*******************************************************************************
@@ -464,81 +466,86 @@ static struct ethtool_ops wl_ethtool_ops = {
* errno value otherwise
*
******************************************************************************/
-int wl_ioctl( struct net_device *dev, struct ifreq *rq, int cmd )
+int wl_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
{
- struct wl_private *lp = wl_priv(dev);
- unsigned long flags;
- int ret = 0;
+ struct wl_private *lp = wl_priv(dev);
+ unsigned long flags;
+ int ret = 0;
- DBG_PARAM(DbgInfo, "dev", "%s (0x%p)", dev->name, dev);
- DBG_PARAM(DbgInfo, "rq", "0x%p", rq);
- DBG_PARAM(DbgInfo, "cmd", "0x%04x", cmd);
+ DBG_PARAM(DbgInfo, "dev", "%s (0x%p)", dev->name, dev);
+ DBG_PARAM(DbgInfo, "rq", "0x%p", rq);
+ DBG_PARAM(DbgInfo, "cmd", "0x%04x", cmd);
- wl_lock( lp, &flags );
+ wl_lock(lp, &flags);
- wl_act_int_off( lp );
+ wl_act_int_off(lp);
#ifdef USE_RTS
- if( lp->useRTS == 1 ) {
- /* Handle any RTS IOCTL here */
- if( cmd == WL_IOCTL_RTS ) {
- DBG_TRACE( DbgInfo, "IOCTL: WL_IOCTL_RTS\n" );
- ret = wvlan_rts( (struct rtsreq *)rq, dev->base_addr );
- } else {
- DBG_TRACE( DbgInfo, "IOCTL not supported in RTS mode: 0x%X\n", cmd );
- ret = -EOPNOTSUPP;
- }
+ if (lp->useRTS == 1) {
+ /* Handle any RTS IOCTL here */
+ if (cmd == WL_IOCTL_RTS) {
+ DBG_TRACE(DbgInfo, "IOCTL: WL_IOCTL_RTS\n");
+ ret = wvlan_rts((struct rtsreq *)rq, dev->base_addr);
+ } else {
+ DBG_TRACE(DbgInfo,
+ "IOCTL not supported in RTS mode: 0x%X\n",
+ cmd);
+ ret = -EOPNOTSUPP;
+ }
- goto out_act_int_on_unlock;
- }
-#endif /* USE_RTS */
+ goto out_act_int_on_unlock;
+ }
+#endif /* USE_RTS */
- /* Only handle UIL IOCTL requests when the UIL has the system blocked. */
- if( !(( lp->flags & WVLAN2_UIL_BUSY ) && ( cmd != WVLAN2_IOCTL_UIL ))) {
+ /* Only handle UIL IOCTL requests when the UIL has the system blocked. */
+ if (!((lp->flags & WVLAN2_UIL_BUSY) && (cmd != WVLAN2_IOCTL_UIL))) {
#ifdef USE_UIL
- struct uilreq *urq = (struct uilreq *)rq;
+ struct uilreq *urq = (struct uilreq *)rq;
#endif /* USE_UIL */
- switch( cmd ) {
- // ================== Private IOCTLs (up to 16) ==================
+ switch (cmd) {
+ // ================== Private IOCTLs (up to 16) ==================
#ifdef USE_UIL
- case WVLAN2_IOCTL_UIL:
- DBG_TRACE( DbgInfo, "IOCTL: WVLAN2_IOCTL_UIL\n" );
- ret = wvlan_uil( urq, lp );
- break;
-#endif /* USE_UIL */
-
- default:
- DBG_TRACE(DbgInfo, "IOCTL CODE NOT SUPPORTED: 0x%X\n", cmd );
- ret = -EOPNOTSUPP;
- break;
+ case WVLAN2_IOCTL_UIL:
+ DBG_TRACE(DbgInfo, "IOCTL: WVLAN2_IOCTL_UIL\n");
+ ret = wvlan_uil(urq, lp);
+ break;
+#endif /* USE_UIL */
+
+ default:
+ DBG_TRACE(DbgInfo, "IOCTL CODE NOT SUPPORTED: 0x%X\n",
+ cmd);
+ ret = -EOPNOTSUPP;
+ break;
+ }
+ } else {
+ DBG_WARNING(DbgInfo,
+ "DEVICE IS BUSY, CANNOT PROCESS REQUEST\n");
+ ret = -EBUSY;
}
- } else {
- DBG_WARNING( DbgInfo, "DEVICE IS BUSY, CANNOT PROCESS REQUEST\n" );
- ret = -EBUSY;
- }
#ifdef USE_RTS
out_act_int_on_unlock:
-#endif /* USE_RTS */
- wl_act_int_on( lp );
+#endif /* USE_RTS */
+ wl_act_int_on(lp);
+
+ wl_unlock(lp, &flags);
- wl_unlock( lp, &flags );
+ return ret;
+} // wl_ioctl
- return ret;
-} // wl_ioctl
/*============================================================================*/
#ifdef CONFIG_NET_POLL_CONTROLLER
static void wl_poll(struct net_device *dev)
{
- struct wl_private *lp = wl_priv(dev);
- unsigned long flags;
- struct pt_regs regs;
+ struct wl_private *lp = wl_priv(dev);
+ unsigned long flags;
+ struct pt_regs regs;
- wl_lock( lp, &flags );
- wl_isr(dev->irq, dev, &regs);
- wl_unlock( lp, &flags );
+ wl_lock(lp, &flags);
+ wl_isr(dev->irq, dev, &regs);
+ wl_unlock(lp, &flags);
}
#endif
@@ -559,53 +566,55 @@ static void wl_poll(struct net_device *dev)
* N/A
*
******************************************************************************/
-void wl_tx_timeout( struct net_device *dev )
+void wl_tx_timeout(struct net_device *dev)
{
#ifdef USE_WDS
- int count;
-#endif /* USE_WDS */
- unsigned long flags;
- struct wl_private *lp = wl_priv(dev);
- struct net_device_stats *pStats = NULL;
+ int count;
+#endif /* USE_WDS */
+ unsigned long flags;
+ struct wl_private *lp = wl_priv(dev);
+ struct net_device_stats *pStats = NULL;
- DBG_WARNING( DbgInfo, "%s: Transmit timeout.\n", dev->name );
+ DBG_WARNING(DbgInfo, "%s: Transmit timeout.\n", dev->name);
- wl_lock( lp, &flags );
+ wl_lock(lp, &flags);
#ifdef USE_RTS
- if( lp->useRTS == 1 ) {
- DBG_TRACE( DbgInfo, "Skipping tx_timeout handler, in RTS mode\n" );
- wl_unlock( lp, &flags );
- return;
- }
-#endif /* USE_RTS */
-
- /* Figure out which device (the "root" device or WDS port) this timeout
- is for */
+ if (lp->useRTS == 1) {
+ DBG_TRACE(DbgInfo,
+ "Skipping tx_timeout handler, in RTS mode\n");
+ wl_unlock(lp, &flags);
+ return;
+ }
+#endif /* USE_RTS */
+
+ /* Figure out which device (the "root" device or WDS port) this timeout
+ is for */
#ifdef USE_WDS
- for( count = 0; count < NUM_WDS_PORTS; count++ ) {
- if( dev == lp->wds_port[count].dev ) {
- pStats = &( lp->wds_port[count].stats );
+ for (count = 0; count < NUM_WDS_PORTS; count++) {
+ if (dev == lp->wds_port[count].dev) {
+ pStats = &(lp->wds_port[count].stats);
- /* Break the loop so that we can use the counter to access WDS
- information in the private structure */
- break;
+ /* Break the loop so that we can use the counter to access WDS
+ information in the private structure */
+ break;
+ }
}
- }
-#endif /* USE_WDS */
+#endif /* USE_WDS */
+
+ /* If pStats is still NULL, then the device is not a WDS port */
+ if (pStats == NULL) {
+ pStats = &(lp->stats);
+ }
- /* If pStats is still NULL, then the device is not a WDS port */
- if( pStats == NULL ) {
- pStats = &( lp->stats );
- }
+ /* Accumulate the timeout error */
+ pStats->tx_errors++;
- /* Accumulate the timeout error */
- pStats->tx_errors++;
+ wl_unlock(lp, &flags);
+} // wl_tx_timeout
- wl_unlock( lp, &flags );
-} // wl_tx_timeout
/*============================================================================*/
/*******************************************************************************
@@ -626,103 +635,105 @@ void wl_tx_timeout( struct net_device *dev )
* 1 on error
*
******************************************************************************/
-int wl_send( struct wl_private *lp )
+int wl_send(struct wl_private *lp)
{
- int status;
- DESC_STRCT *desc;
- WVLAN_LFRAME *txF = NULL;
- struct list_head *element;
- int len;
+ int status;
+ DESC_STRCT *desc;
+ WVLAN_LFRAME *txF = NULL;
+ struct list_head *element;
+ int len;
/*------------------------------------------------------------------------*/
- if( lp == NULL ) {
- DBG_ERROR( DbgInfo, "Private adapter struct is NULL\n" );
- return FALSE;
- }
- if( lp->dev == NULL ) {
- DBG_ERROR( DbgInfo, "net_device struct in wl_private is NULL\n" );
- return FALSE;
- }
-
- /* Check for the availability of FIDs; if none are available, don't take any
- frames off the txQ */
- if( lp->hcfCtx.IFB_RscInd == 0 ) {
- return FALSE;
- }
-
- /* Reclaim the TxQ Elements and place them back on the free queue */
- if( !list_empty( &( lp->txQ[0] ))) {
- element = lp->txQ[0].next;
-
- txF = (WVLAN_LFRAME * )list_entry( element, WVLAN_LFRAME, node );
- if( txF != NULL ) {
- lp->txF.skb = txF->frame.skb;
- lp->txF.port = txF->frame.port;
-
- txF->frame.skb = NULL;
- txF->frame.port = 0;
-
- list_del( &( txF->node ));
- list_add( element, &( lp->txFree ));
-
- lp->txQ_count--;
-
- if( lp->txQ_count < TX_Q_LOW_WATER_MARK ) {
- if( lp->netif_queue_on == FALSE ) {
- DBG_TX( DbgInfo, "Kickstarting Q: %d\n", lp->txQ_count );
- netif_wake_queue( lp->dev );
- WL_WDS_NETIF_WAKE_QUEUE( lp );
- lp->netif_queue_on = TRUE;
- }
- }
- }
- }
-
- if( lp->txF.skb == NULL ) {
- return FALSE;
- }
-
- /* If the device has resources (FIDs) available, then Tx the packet */
- /* Format the TxRequest and send it to the adapter */
- len = lp->txF.skb->len < ETH_ZLEN ? ETH_ZLEN : lp->txF.skb->len;
-
- desc = &( lp->desc_tx );
- desc->buf_addr = lp->txF.skb->data;
- desc->BUF_CNT = len;
- desc->next_desc_addr = NULL;
-
- status = hcf_send_msg( &( lp->hcfCtx ), desc, lp->txF.port );
-
- if( status == HCF_SUCCESS ) {
- lp->dev->trans_start = jiffies;
-
- DBG_TX( DbgInfo, "Transmit...\n" );
-
- if( lp->txF.port == HCF_PORT_0 ) {
- lp->stats.tx_packets++;
- lp->stats.tx_bytes += lp->txF.skb->len;
- }
+ if (lp == NULL) {
+ DBG_ERROR(DbgInfo, "Private adapter struct is NULL\n");
+ return FALSE;
+ }
+ if (lp->dev == NULL) {
+ DBG_ERROR(DbgInfo, "net_device struct in wl_private is NULL\n");
+ return FALSE;
+ }
+
+ /* Check for the availability of FIDs; if none are available, don't take any
+ frames off the txQ */
+ if (lp->hcfCtx.IFB_RscInd == 0) {
+ return FALSE;
+ }
+
+ /* Reclaim the TxQ Elements and place them back on the free queue */
+ if (!list_empty(&(lp->txQ[0]))) {
+ element = lp->txQ[0].next;
+
+ txF = (WVLAN_LFRAME *) list_entry(element, WVLAN_LFRAME, node);
+ if (txF != NULL) {
+ lp->txF.skb = txF->frame.skb;
+ lp->txF.port = txF->frame.port;
+
+ txF->frame.skb = NULL;
+ txF->frame.port = 0;
+
+ list_del(&(txF->node));
+ list_add(element, &(lp->txFree));
+
+ lp->txQ_count--;
+ if (lp->txQ_count < TX_Q_LOW_WATER_MARK) {
+ if (lp->netif_queue_on == FALSE) {
+ DBG_TX(DbgInfo, "Kickstarting Q: %d\n",
+ lp->txQ_count);
+ netif_wake_queue(lp->dev);
+ WL_WDS_NETIF_WAKE_QUEUE(lp);
+ lp->netif_queue_on = TRUE;
+ }
+ }
+ }
+ }
+
+ if (lp->txF.skb == NULL) {
+ return FALSE;
+ }
+
+ /* If the device has resources (FIDs) available, then Tx the packet */
+ /* Format the TxRequest and send it to the adapter */
+ len = lp->txF.skb->len < ETH_ZLEN ? ETH_ZLEN : lp->txF.skb->len;
+
+ desc = &(lp->desc_tx);
+ desc->buf_addr = lp->txF.skb->data;
+ desc->BUF_CNT = len;
+ desc->next_desc_addr = NULL;
+
+ status = hcf_send_msg(&(lp->hcfCtx), desc, lp->txF.port);
+
+ if (status == HCF_SUCCESS) {
+ lp->dev->trans_start = jiffies;
+
+ DBG_TX(DbgInfo, "Transmit...\n");
+
+ if (lp->txF.port == HCF_PORT_0) {
+ lp->stats.tx_packets++;
+ lp->stats.tx_bytes += lp->txF.skb->len;
+ }
#ifdef USE_WDS
- else
- {
- lp->wds_port[(( lp->txF.port >> 8 ) - 1)].stats.tx_packets++;
- lp->wds_port[(( lp->txF.port >> 8 ) - 1)].stats.tx_bytes += lp->txF.skb->len;
- }
+ else {
+ lp->wds_port[((lp->txF.port >> 8) -
+ 1)].stats.tx_packets++;
+ lp->wds_port[((lp->txF.port >> 8) -
+ 1)].stats.tx_bytes += lp->txF.skb->len;
+ }
-#endif /* USE_WDS */
+#endif /* USE_WDS */
- /* Free the skb and perform queue cleanup, as the buffer was
- transmitted successfully */
- dev_kfree_skb( lp->txF.skb );
+ /* Free the skb and perform queue cleanup, as the buffer was
+ transmitted successfully */
+ dev_kfree_skb(lp->txF.skb);
+
+ lp->txF.skb = NULL;
+ lp->txF.port = 0;
+ }
- lp->txF.skb = NULL;
- lp->txF.port = 0;
- }
+ return TRUE;
+} // wl_send
- return TRUE;
-} // wl_send
/*============================================================================*/
/*******************************************************************************
@@ -744,75 +755,74 @@ int wl_send( struct wl_private *lp )
* 1 on error
*
******************************************************************************/
-int wl_tx( struct sk_buff *skb, struct net_device *dev, int port )
+int wl_tx(struct sk_buff *skb, struct net_device *dev, int port)
{
- unsigned long flags;
- struct wl_private *lp = wl_priv(dev);
- WVLAN_LFRAME *txF = NULL;
- struct list_head *element;
+ unsigned long flags;
+ struct wl_private *lp = wl_priv(dev);
+ WVLAN_LFRAME *txF = NULL;
+ struct list_head *element;
/*------------------------------------------------------------------------*/
- /* Grab the spinlock */
- wl_lock( lp, &flags );
-
- if( lp->flags & WVLAN2_UIL_BUSY ) {
- DBG_WARNING( DbgInfo, "UIL has device blocked\n" );
- /* Start dropping packets here??? */
- wl_unlock( lp, &flags );
- return 1;
- }
+ /* Grab the spinlock */
+ wl_lock(lp, &flags);
+ if (lp->flags & WVLAN2_UIL_BUSY) {
+ DBG_WARNING(DbgInfo, "UIL has device blocked\n");
+ /* Start dropping packets here??? */
+ wl_unlock(lp, &flags);
+ return 1;
+ }
#ifdef USE_RTS
- if( lp->useRTS == 1 ) {
- DBG_PRINT( "RTS: we're getting a Tx...\n" );
- wl_unlock( lp, &flags );
- return 1;
- }
-#endif /* USE_RTS */
-
- if( !lp->use_dma ) {
- /* Get an element from the queue */
- element = lp->txFree.next;
- txF = (WVLAN_LFRAME *)list_entry( element, WVLAN_LFRAME, node );
- if( txF == NULL ) {
- DBG_ERROR( DbgInfo, "Problem with list_entry\n" );
- wl_unlock( lp, &flags );
- return 1;
- }
- /* Fill out the frame */
- txF->frame.skb = skb;
- txF->frame.port = port;
- /* Move the frame to the txQ */
- /* NOTE: Here's where we would do priority queueing */
- list_move(&(txF->node), &(lp->txQ[0]));
-
- lp->txQ_count++;
- if( lp->txQ_count >= DEFAULT_NUM_TX_FRAMES ) {
- DBG_TX( DbgInfo, "Q Full: %d\n", lp->txQ_count );
- if( lp->netif_queue_on == TRUE ) {
- netif_stop_queue( lp->dev );
- WL_WDS_NETIF_STOP_QUEUE( lp );
- lp->netif_queue_on = FALSE;
- }
- }
- }
- wl_act_int_off( lp ); /* Disable Interrupts */
-
- /* Send the data to the hardware using the appropriate method */
+ if (lp->useRTS == 1) {
+ DBG_PRINT("RTS: we're getting a Tx...\n");
+ wl_unlock(lp, &flags);
+ return 1;
+ }
+#endif /* USE_RTS */
+
+ if (!lp->use_dma) {
+ /* Get an element from the queue */
+ element = lp->txFree.next;
+ txF = (WVLAN_LFRAME *) list_entry(element, WVLAN_LFRAME, node);
+ if (txF == NULL) {
+ DBG_ERROR(DbgInfo, "Problem with list_entry\n");
+ wl_unlock(lp, &flags);
+ return 1;
+ }
+ /* Fill out the frame */
+ txF->frame.skb = skb;
+ txF->frame.port = port;
+ /* Move the frame to the txQ */
+ /* NOTE: Here's where we would do priority queueing */
+ list_move(&(txF->node), &(lp->txQ[0]));
+
+ lp->txQ_count++;
+ if (lp->txQ_count >= DEFAULT_NUM_TX_FRAMES) {
+ DBG_TX(DbgInfo, "Q Full: %d\n", lp->txQ_count);
+ if (lp->netif_queue_on == TRUE) {
+ netif_stop_queue(lp->dev);
+ WL_WDS_NETIF_STOP_QUEUE(lp);
+ lp->netif_queue_on = FALSE;
+ }
+ }
+ }
+ wl_act_int_off(lp); /* Disable Interrupts */
+
+ /* Send the data to the hardware using the appropriate method */
#ifdef ENABLE_DMA
- if( lp->use_dma ) {
- wl_send_dma( lp, skb, port );
- }
- else
+ if (lp->use_dma) {
+ wl_send_dma(lp, skb, port);
+ } else
#endif
- {
- wl_send( lp );
- }
- /* Re-enable Interrupts, release the spinlock and return */
- wl_act_int_on( lp );
- wl_unlock( lp, &flags );
- return 0;
-} // wl_tx
+ {
+ wl_send(lp);
+ }
+ /* Re-enable Interrupts, release the spinlock and return */
+ wl_act_int_on(lp);
+ wl_unlock(lp, &flags);
+ return 0;
+} // wl_tx
+
/*============================================================================*/
/*******************************************************************************
@@ -835,67 +845,68 @@ int wl_tx( struct sk_buff *skb, struct net_device *dev, int port )
******************************************************************************/
int wl_rx(struct net_device *dev)
{
- int port;
- struct sk_buff *skb;
- struct wl_private *lp = wl_priv(dev);
- int status;
- hcf_16 pktlen;
- hcf_16 hfs_stat;
- DESC_STRCT *desc;
+ int port;
+ struct sk_buff *skb;
+ struct wl_private *lp = wl_priv(dev);
+ int status;
+ hcf_16 pktlen;
+ hcf_16 hfs_stat;
+ DESC_STRCT *desc;
/*------------------------------------------------------------------------*/
- DBG_PARAM(DbgInfo, "dev", "%s (0x%p)", dev->name, dev);
+ DBG_PARAM(DbgInfo, "dev", "%s (0x%p)", dev->name, dev);
- if(!( lp->flags & WVLAN2_UIL_BUSY )) {
+ if (!(lp->flags & WVLAN2_UIL_BUSY)) {
#ifdef USE_RTS
- if( lp->useRTS == 1 ) {
- DBG_PRINT( "RTS: We're getting an Rx...\n" );
- return -EIO;
- }
-#endif /* USE_RTS */
-
- /* Read the HFS_STAT register from the lookahead buffer */
- hfs_stat = (hcf_16)(( lp->lookAheadBuf[HFS_STAT] ) |
- ( lp->lookAheadBuf[HFS_STAT + 1] << 8 ));
-
- /* Make sure the frame isn't bad */
- if(( hfs_stat & HFS_STAT_ERR ) != HCF_SUCCESS ) {
- DBG_WARNING( DbgInfo, "HFS_STAT_ERROR (0x%x) in Rx Packet\n",
- lp->lookAheadBuf[HFS_STAT] );
- return -EIO;
- }
-
- /* Determine what port this packet is for */
- port = ( hfs_stat >> 8 ) & 0x0007;
- DBG_RX( DbgInfo, "Rx frame for port %d\n", port );
-
- pktlen = lp->hcfCtx.IFB_RxLen;
- if (pktlen != 0) {
- skb = ALLOC_SKB(pktlen);
- if (skb != NULL) {
- /* Set the netdev based on the port */
- switch( port ) {
+ if (lp->useRTS == 1) {
+ DBG_PRINT("RTS: We're getting an Rx...\n");
+ return -EIO;
+ }
+#endif /* USE_RTS */
+
+ /* Read the HFS_STAT register from the lookahead buffer */
+ hfs_stat = (hcf_16) ((lp->lookAheadBuf[HFS_STAT]) |
+ (lp->lookAheadBuf[HFS_STAT + 1] << 8));
+
+ /* Make sure the frame isn't bad */
+ if ((hfs_stat & HFS_STAT_ERR) != HCF_SUCCESS) {
+ DBG_WARNING(DbgInfo,
+ "HFS_STAT_ERROR (0x%x) in Rx Packet\n",
+ lp->lookAheadBuf[HFS_STAT]);
+ return -EIO;
+ }
+
+ /* Determine what port this packet is for */
+ port = (hfs_stat >> 8) & 0x0007;
+ DBG_RX(DbgInfo, "Rx frame for port %d\n", port);
+
+ pktlen = lp->hcfCtx.IFB_RxLen;
+ if (pktlen != 0) {
+ skb = ALLOC_SKB(pktlen);
+ if (skb != NULL) {
+ /* Set the netdev based on the port */
+ switch (port) {
#ifdef USE_WDS
- case 1:
- case 2:
- case 3:
- case 4:
- case 5:
- case 6:
- skb->dev = lp->wds_port[port-1].dev;
- break;
-#endif /* USE_WDS */
-
- case 0:
- default:
- skb->dev = dev;
- break;
- }
-
- desc = &( lp->desc_rx );
-
- desc->next_desc_addr = NULL;
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ case 6:
+ skb->dev = lp->wds_port[port - 1].dev;
+ break;
+#endif /* USE_WDS */
+
+ case 0:
+ default:
+ skb->dev = dev;
+ break;
+ }
+
+ desc = &(lp->desc_rx);
+
+ desc->next_desc_addr = NULL;
/*
#define BLOCK_INPUT(buf, len) \
@@ -904,67 +915,75 @@ int wl_rx(struct net_device *dev)
status = hcf_rcv_msg(&(lp->hcfCtx), desc, 0)
*/
- GET_PACKET( skb->dev, skb, pktlen );
+ GET_PACKET(skb->dev, skb, pktlen);
- if( status == HCF_SUCCESS ) {
- netif_rx( skb );
+ if (status == HCF_SUCCESS) {
+ netif_rx(skb);
- if( port == 0 ) {
- lp->stats.rx_packets++;
- lp->stats.rx_bytes += pktlen;
- }
+ if (port == 0) {
+ lp->stats.rx_packets++;
+ lp->stats.rx_bytes += pktlen;
+ }
#ifdef USE_WDS
- else
- {
- lp->wds_port[port-1].stats.rx_packets++;
- lp->wds_port[port-1].stats.rx_bytes += pktlen;
- }
-#endif /* USE_WDS */
-
- dev->last_rx = jiffies;
+ else {
+ lp->wds_port[port -
+ 1].stats.
+ rx_packets++;
+ lp->wds_port[port -
+ 1].stats.
+ rx_bytes += pktlen;
+ }
+#endif /* USE_WDS */
+
+ dev->last_rx = jiffies;
#ifdef WIRELESS_EXT
#ifdef WIRELESS_SPY
- if( lp->spydata.spy_number > 0 ) {
- char *srcaddr = skb->mac.raw + MAC_ADDR_SIZE;
+ if (lp->spydata.spy_number > 0) {
+ char *srcaddr =
+ skb->mac.raw +
+ MAC_ADDR_SIZE;
- wl_spy_gather( dev, srcaddr );
- }
+ wl_spy_gather(dev, srcaddr);
+ }
#endif /* WIRELESS_SPY */
#endif /* WIRELESS_EXT */
- } else {
- DBG_ERROR( DbgInfo, "Rx request to card FAILED\n" );
+ } else {
+ DBG_ERROR(DbgInfo,
+ "Rx request to card FAILED\n");
- if( port == 0 ) {
- lp->stats.rx_dropped++;
- }
+ if (port == 0) {
+ lp->stats.rx_dropped++;
+ }
#ifdef USE_WDS
- else
- {
- lp->wds_port[port-1].stats.rx_dropped++;
- }
-#endif /* USE_WDS */
-
- dev_kfree_skb( skb );
- }
- } else {
- DBG_ERROR( DbgInfo, "Could not alloc skb\n" );
-
- if( port == 0 ) {
- lp->stats.rx_dropped++;
- }
+ else {
+ lp->wds_port[port -
+ 1].stats.
+ rx_dropped++;
+ }
+#endif /* USE_WDS */
+
+ dev_kfree_skb(skb);
+ }
+ } else {
+ DBG_ERROR(DbgInfo, "Could not alloc skb\n");
+
+ if (port == 0) {
+ lp->stats.rx_dropped++;
+ }
#ifdef USE_WDS
- else
- {
- lp->wds_port[port-1].stats.rx_dropped++;
- }
-#endif /* USE_WDS */
- }
- }
- }
-
- return 0;
-} // wl_rx
+ else {
+ lp->wds_port[port -
+ 1].stats.rx_dropped++;
+ }
+#endif /* USE_WDS */
+ }
+ }
+ }
+
+ return 0;
+} // wl_rx
+
/*============================================================================*/
/*******************************************************************************
@@ -986,142 +1005,153 @@ int wl_rx(struct net_device *dev)
******************************************************************************/
#ifdef NEW_MULTICAST
-void wl_multicast( struct net_device *dev )
+void wl_multicast(struct net_device *dev)
{
-#if 1 //;? (HCF_TYPE) & HCF_TYPE_STA //;?should we return an error status in AP mode
+#if 1 //;? (HCF_TYPE) & HCF_TYPE_STA //;?should we return an error status in AP mode
//;?seems reasonable that even an AP-only driver could afford this small additional footprint
- int x;
- struct netdev_hw_addr *ha;
- struct wl_private *lp = wl_priv(dev);
- unsigned long flags;
+ int x;
+ struct netdev_hw_addr *ha;
+ struct wl_private *lp = wl_priv(dev);
+ unsigned long flags;
- DBG_PARAM( DbgInfo, "dev", "%s (0x%p)", dev->name, dev );
+ DBG_PARAM(DbgInfo, "dev", "%s (0x%p)", dev->name, dev);
- if( !wl_adapter_is_open( dev ))
- return;
+ if (!wl_adapter_is_open(dev))
+ return;
#if DBG
- if( DBG_FLAGS( DbgInfo ) & DBG_PARAM_ON ) {
- DBG_PRINT(" flags: %s%s%s\n",
- ( dev->flags & IFF_PROMISC ) ? "Promiscuous " : "",
- ( dev->flags & IFF_MULTICAST ) ? "Multicast " : "",
- ( dev->flags & IFF_ALLMULTI ) ? "All-Multicast" : "" );
+ if (DBG_FLAGS(DbgInfo) & DBG_PARAM_ON) {
+ DBG_PRINT(" flags: %s%s%s\n",
+ (dev->flags & IFF_PROMISC) ? "Promiscuous " : "",
+ (dev->flags & IFF_MULTICAST) ? "Multicast " : "",
+ (dev->flags & IFF_ALLMULTI) ? "All-Multicast" : "");
- DBG_PRINT( " mc_count: %d\n", netdev_mc_count(dev));
+ DBG_PRINT(" mc_count: %d\n", netdev_mc_count(dev));
- netdev_for_each_mc_addr(ha, dev)
- DBG_PRINT(" %pM (%d)\n", ha->addr, dev->addr_len);
- }
+ netdev_for_each_mc_addr(ha, dev)
+ DBG_PRINT(" %pM (%d)\n", ha->addr, dev->addr_len);
+ }
#endif /* DBG */
- if(!( lp->flags & WVLAN2_UIL_BUSY )) {
+ if (!(lp->flags & WVLAN2_UIL_BUSY)) {
#ifdef USE_RTS
- if( lp->useRTS == 1 ) {
- DBG_TRACE( DbgInfo, "Skipping multicast, in RTS mode\n" );
- return;
- }
-#endif /* USE_RTS */
-
- wl_lock( lp, &flags );
- wl_act_int_off( lp );
-
- if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_STA ) {
- if( dev->flags & IFF_PROMISC ) {
- /* Enable promiscuous mode */
- lp->ltvRecord.len = 2;
- lp->ltvRecord.typ = CFG_PROMISCUOUS_MODE;
- lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( 1 );
- DBG_PRINT( "Enabling Promiscuous mode (IFF_PROMISC)\n" );
- hcf_put_info( &( lp->hcfCtx ), (LTVP)&( lp->ltvRecord ));
- }
- else if ((netdev_mc_count(dev) > HCF_MAX_MULTICAST) ||
- ( dev->flags & IFF_ALLMULTI )) {
- /* Shutting off this filter will enable all multicast frames to
- be sent up from the device; however, this is a static RID, so
- a call to wl_apply() is needed */
- lp->ltvRecord.len = 2;
- lp->ltvRecord.typ = CFG_CNF_RX_ALL_GROUP_ADDR;
- lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( 0 );
- DBG_PRINT( "Enabling all multicast mode (IFF_ALLMULTI)\n" );
- hcf_put_info( &( lp->hcfCtx ), (LTVP)&( lp->ltvRecord ));
- wl_apply( lp );
- }
- else if (!netdev_mc_empty(dev)) {
- /* Set the multicast addresses */
- lp->ltvRecord.len = ( netdev_mc_count(dev) * 3 ) + 1;
- lp->ltvRecord.typ = CFG_GROUP_ADDR;
-
- x = 0;
- netdev_for_each_mc_addr(ha, dev)
- memcpy(&(lp->ltvRecord.u.u8[x++ * ETH_ALEN]),
- ha->addr, ETH_ALEN);
- DBG_PRINT( "Setting multicast list\n" );
- hcf_put_info( &( lp->hcfCtx ), (LTVP)&( lp->ltvRecord ));
- } else {
- /* Disable promiscuous mode */
- lp->ltvRecord.len = 2;
- lp->ltvRecord.typ = CFG_PROMISCUOUS_MODE;
- lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( 0 );
- DBG_PRINT( "Disabling Promiscuous mode\n" );
- hcf_put_info( &( lp->hcfCtx ), (LTVP)&( lp->ltvRecord ));
-
- /* Disable multicast mode */
- lp->ltvRecord.len = 2;
- lp->ltvRecord.typ = CFG_GROUP_ADDR;
- DBG_PRINT( "Disabling Multicast mode\n" );
- hcf_put_info( &( lp->hcfCtx ), (LTVP)&( lp->ltvRecord ));
-
- /* Turning on this filter will prevent all multicast frames from
- being sent up from the device; however, this is a static RID,
- so a call to wl_apply() is needed */
- lp->ltvRecord.len = 2;
- lp->ltvRecord.typ = CFG_CNF_RX_ALL_GROUP_ADDR;
- lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( 1 );
- DBG_PRINT( "Disabling all multicast mode (IFF_ALLMULTI)\n" );
- hcf_put_info( &( lp->hcfCtx ), (LTVP)&( lp->ltvRecord ));
- wl_apply( lp );
- }
- }
- wl_act_int_on( lp );
- wl_unlock( lp, &flags );
- }
+ if (lp->useRTS == 1) {
+ DBG_TRACE(DbgInfo, "Skipping multicast, in RTS mode\n");
+ return;
+ }
+#endif /* USE_RTS */
+
+ wl_lock(lp, &flags);
+ wl_act_int_off(lp);
+
+ if (CNV_INT_TO_LITTLE(lp->hcfCtx.IFB_FWIdentity.comp_id) ==
+ COMP_ID_FW_STA) {
+ if (dev->flags & IFF_PROMISC) {
+ /* Enable promiscuous mode */
+ lp->ltvRecord.len = 2;
+ lp->ltvRecord.typ = CFG_PROMISCUOUS_MODE;
+ lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE(1);
+ DBG_PRINT
+ ("Enabling Promiscuous mode (IFF_PROMISC)\n");
+ hcf_put_info(&(lp->hcfCtx),
+ (LTVP) & (lp->ltvRecord));
+ } else if ((netdev_mc_count(dev) > HCF_MAX_MULTICAST)
+ || (dev->flags & IFF_ALLMULTI)) {
+ /* Shutting off this filter will enable all multicast frames to
+ be sent up from the device; however, this is a static RID, so
+ a call to wl_apply() is needed */
+ lp->ltvRecord.len = 2;
+ lp->ltvRecord.typ = CFG_CNF_RX_ALL_GROUP_ADDR;
+ lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE(0);
+ DBG_PRINT
+ ("Enabling all multicast mode (IFF_ALLMULTI)\n");
+ hcf_put_info(&(lp->hcfCtx),
+ (LTVP) & (lp->ltvRecord));
+ wl_apply(lp);
+ } else if (!netdev_mc_empty(dev)) {
+ /* Set the multicast addresses */
+ lp->ltvRecord.len =
+ (netdev_mc_count(dev) * 3) + 1;
+ lp->ltvRecord.typ = CFG_GROUP_ADDR;
+
+ x = 0;
+ netdev_for_each_mc_addr(ha, dev)
+ memcpy(&
+ (lp->ltvRecord.u.u8[x++ * ETH_ALEN]),
+ ha->addr, ETH_ALEN);
+ DBG_PRINT("Setting multicast list\n");
+ hcf_put_info(&(lp->hcfCtx),
+ (LTVP) & (lp->ltvRecord));
+ } else {
+ /* Disable promiscuous mode */
+ lp->ltvRecord.len = 2;
+ lp->ltvRecord.typ = CFG_PROMISCUOUS_MODE;
+ lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE(0);
+ DBG_PRINT("Disabling Promiscuous mode\n");
+ hcf_put_info(&(lp->hcfCtx),
+ (LTVP) & (lp->ltvRecord));
+
+ /* Disable multicast mode */
+ lp->ltvRecord.len = 2;
+ lp->ltvRecord.typ = CFG_GROUP_ADDR;
+ DBG_PRINT("Disabling Multicast mode\n");
+ hcf_put_info(&(lp->hcfCtx),
+ (LTVP) & (lp->ltvRecord));
+
+ /* Turning on this filter will prevent all multicast frames from
+ being sent up from the device; however, this is a static RID,
+ so a call to wl_apply() is needed */
+ lp->ltvRecord.len = 2;
+ lp->ltvRecord.typ = CFG_CNF_RX_ALL_GROUP_ADDR;
+ lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE(1);
+ DBG_PRINT
+ ("Disabling all multicast mode (IFF_ALLMULTI)\n");
+ hcf_put_info(&(lp->hcfCtx),
+ (LTVP) & (lp->ltvRecord));
+ wl_apply(lp);
+ }
+ }
+ wl_act_int_on(lp);
+ wl_unlock(lp, &flags);
+ }
#endif /* HCF_STA */
-} // wl_multicast
+} // wl_multicast
+
/*============================================================================*/
#else /* NEW_MULTICAST */
-void wl_multicast( struct net_device *dev, int num_addrs, void *addrs )
+void wl_multicast(struct net_device *dev, int num_addrs, void *addrs)
{
- DBG_PARAM( DbgInfo, "dev", "%s (0x%p)", dev->name, dev );
- DBG_PARAM( DbgInfo, "num_addrs", "%d", num_addrs );
- DBG_PARAM( DbgInfo, "addrs", "0x%p", addrs );
+ DBG_PARAM(DbgInfo, "dev", "%s (0x%p)", dev->name, dev);
+ DBG_PARAM(DbgInfo, "num_addrs", "%d", num_addrs);
+ DBG_PARAM(DbgInfo, "addrs", "0x%p", addrs);
#error Obsolete set multicast interface!
-} // wl_multicast
+} // wl_multicast
+
/*============================================================================*/
#endif /* NEW_MULTICAST */
-static const struct net_device_ops wl_netdev_ops =
-{
- .ndo_start_xmit = &wl_tx_port0,
+static const struct net_device_ops wl_netdev_ops = {
+ .ndo_start_xmit = &wl_tx_port0,
- .ndo_set_config = &wl_config,
- .ndo_get_stats = &wl_stats,
- .ndo_set_rx_mode = &wl_multicast,
+ .ndo_set_config = &wl_config,
+ .ndo_get_stats = &wl_stats,
+ .ndo_set_rx_mode = &wl_multicast,
- .ndo_init = &wl_insert,
- .ndo_open = &wl_adapter_open,
- .ndo_stop = &wl_adapter_close,
- .ndo_do_ioctl = &wl_ioctl,
+ .ndo_init = &wl_insert,
+ .ndo_open = &wl_adapter_open,
+ .ndo_stop = &wl_adapter_close,
+ .ndo_do_ioctl = &wl_ioctl,
- .ndo_tx_timeout = &wl_tx_timeout,
+ .ndo_tx_timeout = &wl_tx_timeout,
#ifdef CONFIG_NET_POLL_CONTROLLER
- .ndo_poll_controller = wl_poll,
+ .ndo_poll_controller = wl_poll,
#endif
};
@@ -1144,48 +1174,47 @@ static const struct net_device_ops wl_netdev_ops =
* device.
*
******************************************************************************/
-struct net_device * wl_device_alloc( void )
+struct net_device *wl_device_alloc(void)
{
- struct net_device *dev = NULL;
- struct wl_private *lp = NULL;
-
- /* Alloc a net_device struct */
- dev = alloc_etherdev(sizeof(struct wl_private));
- if (!dev)
- return NULL;
-
- /* Initialize the 'next' pointer in the struct. Currently only used for PCI,
- but do it here just in case it's used for other buses in the future */
- lp = wl_priv(dev);
-
+ struct net_device *dev = NULL;
+ struct wl_private *lp = NULL;
+
+ /* Alloc a net_device struct */
+ dev = alloc_etherdev(sizeof(struct wl_private));
+ if (!dev)
+ return NULL;
+
+ /* Initialize the 'next' pointer in the struct. Currently only used for PCI,
+ but do it here just in case it's used for other buses in the future */
+ lp = wl_priv(dev);
+
+ /* Check MTU */
+ if (dev->mtu > MTU_MAX) {
+ DBG_WARNING(DbgInfo, "%s: MTU set too high, limiting to %d.\n",
+ dev->name, MTU_MAX);
+ dev->mtu = MTU_MAX;
+ }
- /* Check MTU */
- if( dev->mtu > MTU_MAX )
- {
- DBG_WARNING( DbgInfo, "%s: MTU set too high, limiting to %d.\n",
- dev->name, MTU_MAX );
- dev->mtu = MTU_MAX;
- }
+ /* Setup the function table in the device structure. */
- /* Setup the function table in the device structure. */
+ dev->wireless_handlers = (struct iw_handler_def *)&wl_iw_handler_def;
+ lp->wireless_data.spy_data = &lp->spy_data;
+ dev->wireless_data = &lp->wireless_data;
- dev->wireless_handlers = (struct iw_handler_def *)&wl_iw_handler_def;
- lp->wireless_data.spy_data = &lp->spy_data;
- dev->wireless_data = &lp->wireless_data;
+ dev->netdev_ops = &wl_netdev_ops;
- dev->netdev_ops = &wl_netdev_ops;
+ dev->watchdog_timeo = TX_TIMEOUT;
- dev->watchdog_timeo = TX_TIMEOUT;
+ dev->ethtool_ops = &wl_ethtool_ops;
- dev->ethtool_ops = &wl_ethtool_ops;
+ netif_stop_queue(dev);
- netif_stop_queue( dev );
+ /* Allocate virtual devices for WDS support if needed */
+ WL_WDS_DEVICE_ALLOC(lp);
- /* Allocate virtual devices for WDS support if needed */
- WL_WDS_DEVICE_ALLOC( lp );
+ return dev;
+} // wl_device_alloc
- return dev;
-} // wl_device_alloc
/*============================================================================*/
/*******************************************************************************
@@ -1206,15 +1235,16 @@ struct net_device * wl_device_alloc( void )
* N/A
*
******************************************************************************/
-void wl_device_dealloc( struct net_device *dev )
+void wl_device_dealloc(struct net_device *dev)
{
// struct wl_private *lp = wl_priv(dev);
- /* Dealloc the WDS ports */
- WL_WDS_DEVICE_DEALLOC( lp );
+ /* Dealloc the WDS ports */
+ WL_WDS_DEVICE_DEALLOC(lp);
+
+ free_netdev(dev);
+} // wl_device_dealloc
- free_netdev( dev );
-} // wl_device_dealloc
/*============================================================================*/
/*******************************************************************************
@@ -1235,15 +1265,16 @@ void wl_device_dealloc( struct net_device *dev )
* N/A
*
******************************************************************************/
-int wl_tx_port0( struct sk_buff *skb, struct net_device *dev )
+int wl_tx_port0(struct sk_buff *skb, struct net_device *dev)
{
- DBG_TX( DbgInfo, "Tx on Port 0\n" );
+ DBG_TX(DbgInfo, "Tx on Port 0\n");
- return wl_tx( skb, dev, HCF_PORT_0 );
+ return wl_tx(skb, dev, HCF_PORT_0);
#ifdef ENABLE_DMA
- return wl_tx_dma( skb, dev, HCF_PORT_0 );
+ return wl_tx_dma(skb, dev, HCF_PORT_0);
#endif
-} // wl_tx_port0
+} // wl_tx_port0
+
/*============================================================================*/
#ifdef USE_WDS
@@ -1266,11 +1297,12 @@ int wl_tx_port0( struct sk_buff *skb, struct net_device *dev )
* N/A
*
******************************************************************************/
-int wl_tx_port1( struct sk_buff *skb, struct net_device *dev )
+int wl_tx_port1(struct sk_buff *skb, struct net_device *dev)
{
- DBG_TX( DbgInfo, "Tx on Port 1\n" );
- return wl_tx( skb, dev, HCF_PORT_1 );
-} // wl_tx_port1
+ DBG_TX(DbgInfo, "Tx on Port 1\n");
+ return wl_tx(skb, dev, HCF_PORT_1);
+} // wl_tx_port1
+
/*============================================================================*/
/*******************************************************************************
@@ -1291,11 +1323,12 @@ int wl_tx_port1( struct sk_buff *skb, struct net_device *dev )
* N/A
*
******************************************************************************/
-int wl_tx_port2( struct sk_buff *skb, struct net_device *dev )
+int wl_tx_port2(struct sk_buff *skb, struct net_device *dev)
{
- DBG_TX( DbgInfo, "Tx on Port 2\n" );
- return wl_tx( skb, dev, HCF_PORT_2 );
-} // wl_tx_port2
+ DBG_TX(DbgInfo, "Tx on Port 2\n");
+ return wl_tx(skb, dev, HCF_PORT_2);
+} // wl_tx_port2
+
/*============================================================================*/
/*******************************************************************************
@@ -1316,11 +1349,12 @@ int wl_tx_port2( struct sk_buff *skb, struct net_device *dev )
* N/A
*
******************************************************************************/
-int wl_tx_port3( struct sk_buff *skb, struct net_device *dev )
+int wl_tx_port3(struct sk_buff *skb, struct net_device *dev)
{
- DBG_TX( DbgInfo, "Tx on Port 3\n" );
- return wl_tx( skb, dev, HCF_PORT_3 );
-} // wl_tx_port3
+ DBG_TX(DbgInfo, "Tx on Port 3\n");
+ return wl_tx(skb, dev, HCF_PORT_3);
+} // wl_tx_port3
+
/*============================================================================*/
/*******************************************************************************
@@ -1341,11 +1375,12 @@ int wl_tx_port3( struct sk_buff *skb, struct net_device *dev )
* N/A
*
******************************************************************************/
-int wl_tx_port4( struct sk_buff *skb, struct net_device *dev )
+int wl_tx_port4(struct sk_buff *skb, struct net_device *dev)
{
- DBG_TX( DbgInfo, "Tx on Port 4\n" );
- return wl_tx( skb, dev, HCF_PORT_4 );
-} // wl_tx_port4
+ DBG_TX(DbgInfo, "Tx on Port 4\n");
+ return wl_tx(skb, dev, HCF_PORT_4);
+} // wl_tx_port4
+
/*============================================================================*/
/*******************************************************************************
@@ -1366,11 +1401,12 @@ int wl_tx_port4( struct sk_buff *skb, struct net_device *dev )
* N/A
*
******************************************************************************/
-int wl_tx_port5( struct sk_buff *skb, struct net_device *dev )
+int wl_tx_port5(struct sk_buff *skb, struct net_device *dev)
{
- DBG_TX( DbgInfo, "Tx on Port 5\n" );
- return wl_tx( skb, dev, HCF_PORT_5 );
-} // wl_tx_port5
+ DBG_TX(DbgInfo, "Tx on Port 5\n");
+ return wl_tx(skb, dev, HCF_PORT_5);
+} // wl_tx_port5
+
/*============================================================================*/
/*******************************************************************************
@@ -1391,11 +1427,12 @@ int wl_tx_port5( struct sk_buff *skb, struct net_device *dev )
* N/A
*
******************************************************************************/
-int wl_tx_port6( struct sk_buff *skb, struct net_device *dev )
+int wl_tx_port6(struct sk_buff *skb, struct net_device *dev)
{
- DBG_TX( DbgInfo, "Tx on Port 6\n" );
- return wl_tx( skb, dev, HCF_PORT_6 );
-} // wl_tx_port6
+ DBG_TX(DbgInfo, "Tx on Port 6\n");
+ return wl_tx(skb, dev, HCF_PORT_6);
+} // wl_tx_port6
+
/*============================================================================*/
/*******************************************************************************
@@ -1417,50 +1454,51 @@ int wl_tx_port6( struct sk_buff *skb, struct net_device *dev )
* structs in the private adapter structure.
*
******************************************************************************/
-void wl_wds_device_alloc( struct wl_private *lp )
+void wl_wds_device_alloc(struct wl_private *lp)
{
- int count;
+ int count;
- /* WDS support requires additional net_device structs to be allocated,
- so that user space apps can use these virtual devices to specify the
- port on which to Tx/Rx */
- for( count = 0; count < NUM_WDS_PORTS; count++ ) {
- struct net_device *dev_wds = NULL;
+ /* WDS support requires additional net_device structs to be allocated,
+ so that user space apps can use these virtual devices to specify the
+ port on which to Tx/Rx */
+ for (count = 0; count < NUM_WDS_PORTS; count++) {
+ struct net_device *dev_wds = NULL;
+
+ dev_wds = kzalloc(sizeof(struct net_device), GFP_KERNEL);
+ if (!dev_wds)
+ return;
+
+ ether_setup(dev_wds);
+
+ lp->wds_port[count].dev = dev_wds;
+
+ /* Re-use wl_init for all the devices, as it currently does nothing, but
+ is required. Re-use the stats/tx_timeout handler for all as well; the
+ WDS port which is requesting these operations can be determined by
+ the net_device pointer. Set the private member of all devices to point
+ to the same net_device struct; that way, all information gets
+ funnelled through the one "real" net_device. Name the WDS ports
+ "wds<n>" */
+ lp->wds_port[count].dev->init = &wl_init;
+ lp->wds_port[count].dev->get_stats = &wl_stats;
+ lp->wds_port[count].dev->tx_timeout = &wl_tx_timeout;
+ lp->wds_port[count].dev->watchdog_timeo = TX_TIMEOUT;
+ lp->wds_port[count].dev->priv = lp;
+
+ sprintf(lp->wds_port[count].dev->name, "wds%d", count);
+ }
- dev_wds = kzalloc(sizeof(struct net_device), GFP_KERNEL);
- if (!dev_wds)
- return;
+ /* Register the Tx handlers */
+ lp->wds_port[0].dev->hard_start_xmit = &wl_tx_port1;
+ lp->wds_port[1].dev->hard_start_xmit = &wl_tx_port2;
+ lp->wds_port[2].dev->hard_start_xmit = &wl_tx_port3;
+ lp->wds_port[3].dev->hard_start_xmit = &wl_tx_port4;
+ lp->wds_port[4].dev->hard_start_xmit = &wl_tx_port5;
+ lp->wds_port[5].dev->hard_start_xmit = &wl_tx_port6;
+
+ WL_WDS_NETIF_STOP_QUEUE(lp);
+} // wl_wds_device_alloc
- ether_setup( dev_wds );
-
- lp->wds_port[count].dev = dev_wds;
-
- /* Re-use wl_init for all the devices, as it currently does nothing, but
- is required. Re-use the stats/tx_timeout handler for all as well; the
- WDS port which is requesting these operations can be determined by
- the net_device pointer. Set the private member of all devices to point
- to the same net_device struct; that way, all information gets
- funnelled through the one "real" net_device. Name the WDS ports
- "wds<n>" */
- lp->wds_port[count].dev->init = &wl_init;
- lp->wds_port[count].dev->get_stats = &wl_stats;
- lp->wds_port[count].dev->tx_timeout = &wl_tx_timeout;
- lp->wds_port[count].dev->watchdog_timeo = TX_TIMEOUT;
- lp->wds_port[count].dev->priv = lp;
-
- sprintf( lp->wds_port[count].dev->name, "wds%d", count );
- }
-
- /* Register the Tx handlers */
- lp->wds_port[0].dev->hard_start_xmit = &wl_tx_port1;
- lp->wds_port[1].dev->hard_start_xmit = &wl_tx_port2;
- lp->wds_port[2].dev->hard_start_xmit = &wl_tx_port3;
- lp->wds_port[3].dev->hard_start_xmit = &wl_tx_port4;
- lp->wds_port[4].dev->hard_start_xmit = &wl_tx_port5;
- lp->wds_port[5].dev->hard_start_xmit = &wl_tx_port6;
-
- WL_WDS_NETIF_STOP_QUEUE( lp );
-} // wl_wds_device_alloc
/*============================================================================*/
/*******************************************************************************
@@ -1480,26 +1518,27 @@ void wl_wds_device_alloc( struct wl_private *lp )
* N/A
*
******************************************************************************/
-void wl_wds_device_dealloc( struct wl_private *lp )
+void wl_wds_device_dealloc(struct wl_private *lp)
{
- int count;
+ int count;
- for( count = 0; count < NUM_WDS_PORTS; count++ ) {
- struct net_device *dev_wds = NULL;
+ for (count = 0; count < NUM_WDS_PORTS; count++) {
+ struct net_device *dev_wds = NULL;
- dev_wds = lp->wds_port[count].dev;
+ dev_wds = lp->wds_port[count].dev;
- if( dev_wds != NULL ) {
- if( dev_wds->flags & IFF_UP ) {
- dev_close( dev_wds );
- dev_wds->flags &= ~( IFF_UP | IFF_RUNNING );
- }
+ if (dev_wds != NULL) {
+ if (dev_wds->flags & IFF_UP) {
+ dev_close(dev_wds);
+ dev_wds->flags &= ~(IFF_UP | IFF_RUNNING);
+ }
+
+ free_netdev(dev_wds);
+ lp->wds_port[count].dev = NULL;
+ }
+ }
+} // wl_wds_device_dealloc
- free_netdev(dev_wds);
- lp->wds_port[count].dev = NULL;
- }
- }
-} // wl_wds_device_dealloc
/*============================================================================*/
/*******************************************************************************
@@ -1520,21 +1559,22 @@ void wl_wds_device_dealloc( struct wl_private *lp )
* N/A
*
******************************************************************************/
-void wl_wds_netif_start_queue( struct wl_private *lp )
+void wl_wds_netif_start_queue(struct wl_private *lp)
{
- int count;
+ int count;
/*------------------------------------------------------------------------*/
- if( lp != NULL ) {
- for( count = 0; count < NUM_WDS_PORTS; count++ ) {
- if( lp->wds_port[count].is_registered &&
- lp->wds_port[count].netif_queue_on == FALSE ) {
- netif_start_queue( lp->wds_port[count].dev );
- lp->wds_port[count].netif_queue_on = TRUE;
- }
- }
- }
-} // wl_wds_netif_start_queue
+ if (lp != NULL) {
+ for (count = 0; count < NUM_WDS_PORTS; count++) {
+ if (lp->wds_port[count].is_registered &&
+ lp->wds_port[count].netif_queue_on == FALSE) {
+ netif_start_queue(lp->wds_port[count].dev);
+ lp->wds_port[count].netif_queue_on = TRUE;
+ }
+ }
+ }
+} // wl_wds_netif_start_queue
+
/*============================================================================*/
/*******************************************************************************
@@ -1555,21 +1595,22 @@ void wl_wds_netif_start_queue( struct wl_private *lp )
* N/A
*
******************************************************************************/
-void wl_wds_netif_stop_queue( struct wl_private *lp )
+void wl_wds_netif_stop_queue(struct wl_private *lp)
{
- int count;
+ int count;
/*------------------------------------------------------------------------*/
- if( lp != NULL ) {
- for( count = 0; count < NUM_WDS_PORTS; count++ ) {
- if( lp->wds_port[count].is_registered &&
- lp->wds_port[count].netif_queue_on == TRUE ) {
- netif_stop_queue( lp->wds_port[count].dev );
- lp->wds_port[count].netif_queue_on = FALSE;
- }
- }
- }
-} // wl_wds_netif_stop_queue
+ if (lp != NULL) {
+ for (count = 0; count < NUM_WDS_PORTS; count++) {
+ if (lp->wds_port[count].is_registered &&
+ lp->wds_port[count].netif_queue_on == TRUE) {
+ netif_stop_queue(lp->wds_port[count].dev);
+ lp->wds_port[count].netif_queue_on = FALSE;
+ }
+ }
+ }
+} // wl_wds_netif_stop_queue
+
/*============================================================================*/
/*******************************************************************************
@@ -1590,21 +1631,22 @@ void wl_wds_netif_stop_queue( struct wl_private *lp )
* N/A
*
******************************************************************************/
-void wl_wds_netif_wake_queue( struct wl_private *lp )
+void wl_wds_netif_wake_queue(struct wl_private *lp)
{
- int count;
+ int count;
/*------------------------------------------------------------------------*/
- if( lp != NULL ) {
- for( count = 0; count < NUM_WDS_PORTS; count++ ) {
- if( lp->wds_port[count].is_registered &&
- lp->wds_port[count].netif_queue_on == FALSE ) {
- netif_wake_queue( lp->wds_port[count].dev );
- lp->wds_port[count].netif_queue_on = TRUE;
- }
- }
- }
-} // wl_wds_netif_wake_queue
+ if (lp != NULL) {
+ for (count = 0; count < NUM_WDS_PORTS; count++) {
+ if (lp->wds_port[count].is_registered &&
+ lp->wds_port[count].netif_queue_on == FALSE) {
+ netif_wake_queue(lp->wds_port[count].dev);
+ lp->wds_port[count].netif_queue_on = TRUE;
+ }
+ }
+ }
+} // wl_wds_netif_wake_queue
+
/*============================================================================*/
/*******************************************************************************
@@ -1625,19 +1667,20 @@ void wl_wds_netif_wake_queue( struct wl_private *lp )
* N/A
*
******************************************************************************/
-void wl_wds_netif_carrier_on( struct wl_private *lp )
+void wl_wds_netif_carrier_on(struct wl_private *lp)
{
- int count;
+ int count;
/*------------------------------------------------------------------------*/
- if( lp != NULL ) {
- for( count = 0; count < NUM_WDS_PORTS; count++ ) {
- if( lp->wds_port[count].is_registered ) {
- netif_carrier_on( lp->wds_port[count].dev );
- }
- }
- }
-} // wl_wds_netif_carrier_on
+ if (lp != NULL) {
+ for (count = 0; count < NUM_WDS_PORTS; count++) {
+ if (lp->wds_port[count].is_registered) {
+ netif_carrier_on(lp->wds_port[count].dev);
+ }
+ }
+ }
+} // wl_wds_netif_carrier_on
+
/*============================================================================*/
/*******************************************************************************
@@ -1658,21 +1701,22 @@ void wl_wds_netif_carrier_on( struct wl_private *lp )
* N/A
*
******************************************************************************/
-void wl_wds_netif_carrier_off( struct wl_private *lp )
+void wl_wds_netif_carrier_off(struct wl_private *lp)
{
int count;
- if(lp != NULL) {
- for(count = 0; count < NUM_WDS_PORTS; count++) {
- if(lp->wds_port[count].is_registered)
+ if (lp != NULL) {
+ for (count = 0; count < NUM_WDS_PORTS; count++) {
+ if (lp->wds_port[count].is_registered)
netif_carrier_off(lp->wds_port[count].dev);
}
}
-} // wl_wds_netif_carrier_off
+} // wl_wds_netif_carrier_off
+
/*============================================================================*/
-#endif /* USE_WDS */
+#endif /* USE_WDS */
#ifdef ENABLE_DMA
/*******************************************************************************
@@ -1695,70 +1739,71 @@ void wl_wds_netif_carrier_off( struct wl_private *lp )
* 1 on error
*
******************************************************************************/
-int wl_send_dma( struct wl_private *lp, struct sk_buff *skb, int port )
+int wl_send_dma(struct wl_private *lp, struct sk_buff *skb, int port)
{
- int len;
- DESC_STRCT *desc = NULL;
- DESC_STRCT *desc_next = NULL;
+ int len;
+ DESC_STRCT *desc = NULL;
+ DESC_STRCT *desc_next = NULL;
/*------------------------------------------------------------------------*/
- if( lp == NULL ) {
- DBG_ERROR( DbgInfo, "Private adapter struct is NULL\n" );
- return FALSE;
- }
+ if (lp == NULL) {
+ DBG_ERROR(DbgInfo, "Private adapter struct is NULL\n");
+ return FALSE;
+ }
+
+ if (lp->dev == NULL) {
+ DBG_ERROR(DbgInfo, "net_device struct in wl_private is NULL\n");
+ return FALSE;
+ }
- if( lp->dev == NULL ) {
- DBG_ERROR( DbgInfo, "net_device struct in wl_private is NULL\n" );
- return FALSE;
- }
+ /* AGAIN, ALL THE QUEUEING DONE HERE IN I/O MODE IS NOT PERFORMED */
- /* AGAIN, ALL THE QUEUEING DONE HERE IN I/O MODE IS NOT PERFORMED */
+ if (skb == NULL) {
+ DBG_WARNING(DbgInfo, "Nothing to send.\n");
+ return FALSE;
+ }
- if( skb == NULL ) {
- DBG_WARNING (DbgInfo, "Nothing to send.\n");
- return FALSE;
- }
+ len = skb->len;
- len = skb->len;
+ /* Get a free descriptor */
+ desc = wl_pci_dma_get_tx_packet(lp);
- /* Get a free descriptor */
- desc = wl_pci_dma_get_tx_packet( lp );
+ if (desc == NULL) {
+ if (lp->netif_queue_on == TRUE) {
+ netif_stop_queue(lp->dev);
+ WL_WDS_NETIF_STOP_QUEUE(lp);
+ lp->netif_queue_on = FALSE;
- if( desc == NULL ) {
- if( lp->netif_queue_on == TRUE ) {
- netif_stop_queue( lp->dev );
- WL_WDS_NETIF_STOP_QUEUE( lp );
- lp->netif_queue_on = FALSE;
+ dev_kfree_skb(skb);
+ return 0;
+ }
+ }
- dev_kfree_skb( skb );
- return 0;
- }
- }
+ SET_BUF_CNT(desc, /*HCF_DMA_FD_CNT */ HFS_ADDR_DEST);
+ SET_BUF_SIZE(desc, HCF_DMA_TX_BUF1_SIZE);
- SET_BUF_CNT( desc, /*HCF_DMA_FD_CNT*/HFS_ADDR_DEST );
- SET_BUF_SIZE( desc, HCF_DMA_TX_BUF1_SIZE );
+ desc_next = desc->next_desc_addr;
- desc_next = desc->next_desc_addr;
+ if (desc_next->buf_addr == NULL) {
+ DBG_ERROR(DbgInfo, "DMA descriptor buf_addr is NULL\n");
+ return FALSE;
+ }
- if( desc_next->buf_addr == NULL ) {
- DBG_ERROR( DbgInfo, "DMA descriptor buf_addr is NULL\n" );
- return FALSE;
- }
+ /* Copy the payload into the DMA packet */
+ memcpy(desc_next->buf_addr, skb->data, len);
- /* Copy the payload into the DMA packet */
- memcpy( desc_next->buf_addr, skb->data, len );
+ SET_BUF_CNT(desc_next, len);
+ SET_BUF_SIZE(desc_next, HCF_MAX_PACKET_SIZE);
- SET_BUF_CNT( desc_next, len );
- SET_BUF_SIZE( desc_next, HCF_MAX_PACKET_SIZE );
+ hcf_dma_tx_put(&(lp->hcfCtx), desc, 0);
- hcf_dma_tx_put( &( lp->hcfCtx ), desc, 0 );
+ /* Free the skb and perform queue cleanup, as the buffer was
+ transmitted successfully */
+ dev_kfree_skb(skb);
- /* Free the skb and perform queue cleanup, as the buffer was
- transmitted successfully */
- dev_kfree_skb( skb );
+ return TRUE;
+} // wl_send_dma
- return TRUE;
-} // wl_send_dma
/*============================================================================*/
/*******************************************************************************
@@ -1779,147 +1824,151 @@ int wl_send_dma( struct wl_private *lp, struct sk_buff *skb, int port )
* 1 on error
*
******************************************************************************/
-int wl_rx_dma( struct net_device *dev )
+int wl_rx_dma(struct net_device *dev)
{
- int port;
- hcf_16 pktlen;
- hcf_16 hfs_stat;
- struct sk_buff *skb;
- struct wl_private *lp = NULL;
- DESC_STRCT *desc, *desc_next;
- //CFG_MB_INFO_RANGE2_STRCT x;
+ int port;
+ hcf_16 pktlen;
+ hcf_16 hfs_stat;
+ struct sk_buff *skb;
+ struct wl_private *lp = NULL;
+ DESC_STRCT *desc, *desc_next;
+ //CFG_MB_INFO_RANGE2_STRCT x;
/*------------------------------------------------------------------------*/
- DBG_PARAM(DbgInfo, "dev", "%s (0x%p)", dev->name, dev);
+ DBG_PARAM(DbgInfo, "dev", "%s (0x%p)", dev->name, dev);
- if((( lp = dev->priv ) != NULL ) &&
- !( lp->flags & WVLAN2_UIL_BUSY )) {
+ if (((lp = dev->priv) != NULL) && !(lp->flags & WVLAN2_UIL_BUSY)) {
#ifdef USE_RTS
- if( lp->useRTS == 1 ) {
- DBG_PRINT( "RTS: We're getting an Rx...\n" );
- return -EIO;
- }
-#endif /* USE_RTS */
-
- //if( lp->dma.status == 0 )
- //{
- desc = hcf_dma_rx_get( &( lp->hcfCtx ));
-
- if( desc != NULL )
- {
- /* Check and see if we rcvd. a WMP frame */
- /*
- if((( *(hcf_8 *)&desc->buf_addr[HFS_STAT] ) &
- ( HFS_STAT_MSG_TYPE | HFS_STAT_ERR )) == HFS_STAT_WMP_MSG )
- {
- DBG_TRACE( DbgInfo, "Got a WMP frame\n" );
-
- x.len = sizeof( CFG_MB_INFO_RANGE2_STRCT ) / sizeof( hcf_16 );
- x.typ = CFG_MB_INFO;
- x.base_typ = CFG_WMP;
- x.frag_cnt = 2;
- x.frag_buf[0].frag_len = GET_BUF_CNT( descp ) / sizeof( hcf_16 );
- x.frag_buf[0].frag_addr = (hcf_8 *) descp->buf_addr ;
- x.frag_buf[1].frag_len = ( GET_BUF_CNT( descp->next_desc_addr ) + 1 ) / sizeof( hcf_16 );
- x.frag_buf[1].frag_addr = (hcf_8 *) descp->next_desc_addr->buf_addr ;
-
- hcf_put_info( &( lp->hcfCtx ), (LTVP)&x );
- }
- */
-
- desc_next = desc->next_desc_addr;
-
- /* Make sure the buffer isn't empty */
- if( GET_BUF_CNT( desc ) == 0 ) {
- DBG_WARNING( DbgInfo, "Buffer is empty!\n" );
-
- /* Give the descriptor back to the HCF */
- hcf_dma_rx_put( &( lp->hcfCtx ), desc );
- return -EIO;
- }
-
- /* Read the HFS_STAT register from the lookahead buffer */
- hfs_stat = (hcf_16)( desc->buf_addr[HFS_STAT/2] );
-
- /* Make sure the frame isn't bad */
- if(( hfs_stat & HFS_STAT_ERR ) != HCF_SUCCESS )
- {
- DBG_WARNING( DbgInfo, "HFS_STAT_ERROR (0x%x) in Rx Packet\n",
- desc->buf_addr[HFS_STAT/2] );
-
- /* Give the descriptor back to the HCF */
- hcf_dma_rx_put( &( lp->hcfCtx ), desc );
- return -EIO;
- }
-
- /* Determine what port this packet is for */
- port = ( hfs_stat >> 8 ) & 0x0007;
- DBG_RX( DbgInfo, "Rx frame for port %d\n", port );
-
- pktlen = GET_BUF_CNT(desc_next);
- if (pktlen != 0) {
- skb = ALLOC_SKB(pktlen);
- if (skb != NULL) {
- switch( port ) {
+ if (lp->useRTS == 1) {
+ DBG_PRINT("RTS: We're getting an Rx...\n");
+ return -EIO;
+ }
+#endif /* USE_RTS */
+
+ //if( lp->dma.status == 0 )
+ //{
+ desc = hcf_dma_rx_get(&(lp->hcfCtx));
+
+ if (desc != NULL) {
+ /* Check and see if we rcvd. a WMP frame */
+ /*
+ if((( *(hcf_8 *)&desc->buf_addr[HFS_STAT] ) &
+ ( HFS_STAT_MSG_TYPE | HFS_STAT_ERR )) == HFS_STAT_WMP_MSG )
+ {
+ DBG_TRACE( DbgInfo, "Got a WMP frame\n" );
+
+ x.len = sizeof( CFG_MB_INFO_RANGE2_STRCT ) / sizeof( hcf_16 );
+ x.typ = CFG_MB_INFO;
+ x.base_typ = CFG_WMP;
+ x.frag_cnt = 2;
+ x.frag_buf[0].frag_len = GET_BUF_CNT( descp ) / sizeof( hcf_16 );
+ x.frag_buf[0].frag_addr = (hcf_8 *) descp->buf_addr ;
+ x.frag_buf[1].frag_len = ( GET_BUF_CNT( descp->next_desc_addr ) + 1 ) / sizeof( hcf_16 );
+ x.frag_buf[1].frag_addr = (hcf_8 *) descp->next_desc_addr->buf_addr ;
+
+ hcf_put_info( &( lp->hcfCtx ), (LTVP)&x );
+ }
+ */
+
+ desc_next = desc->next_desc_addr;
+
+ /* Make sure the buffer isn't empty */
+ if (GET_BUF_CNT(desc) == 0) {
+ DBG_WARNING(DbgInfo, "Buffer is empty!\n");
+
+ /* Give the descriptor back to the HCF */
+ hcf_dma_rx_put(&(lp->hcfCtx), desc);
+ return -EIO;
+ }
+
+ /* Read the HFS_STAT register from the lookahead buffer */
+ hfs_stat = (hcf_16) (desc->buf_addr[HFS_STAT / 2]);
+
+ /* Make sure the frame isn't bad */
+ if ((hfs_stat & HFS_STAT_ERR) != HCF_SUCCESS) {
+ DBG_WARNING(DbgInfo,
+ "HFS_STAT_ERROR (0x%x) in Rx Packet\n",
+ desc->buf_addr[HFS_STAT / 2]);
+
+ /* Give the descriptor back to the HCF */
+ hcf_dma_rx_put(&(lp->hcfCtx), desc);
+ return -EIO;
+ }
+
+ /* Determine what port this packet is for */
+ port = (hfs_stat >> 8) & 0x0007;
+ DBG_RX(DbgInfo, "Rx frame for port %d\n", port);
+
+ pktlen = GET_BUF_CNT(desc_next);
+ if (pktlen != 0) {
+ skb = ALLOC_SKB(pktlen);
+ if (skb != NULL) {
+ switch (port) {
#ifdef USE_WDS
- case 1:
- case 2:
- case 3:
- case 4:
- case 5:
- case 6:
- skb->dev = lp->wds_port[port-1].dev;
- break;
-#endif /* USE_WDS */
-
- case 0:
- default:
- skb->dev = dev;
- break;
- }
-
- GET_PACKET_DMA( skb->dev, skb, pktlen );
-
- /* Give the descriptor back to the HCF */
- hcf_dma_rx_put( &( lp->hcfCtx ), desc );
-
- netif_rx( skb );
-
- if( port == 0 ) {
- lp->stats.rx_packets++;
- lp->stats.rx_bytes += pktlen;
- }
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ case 6:
+ skb->dev =
+ lp->wds_port[port - 1].dev;
+ break;
+#endif /* USE_WDS */
+
+ case 0:
+ default:
+ skb->dev = dev;
+ break;
+ }
+
+ GET_PACKET_DMA(skb->dev, skb, pktlen);
+
+ /* Give the descriptor back to the HCF */
+ hcf_dma_rx_put(&(lp->hcfCtx), desc);
+
+ netif_rx(skb);
+
+ if (port == 0) {
+ lp->stats.rx_packets++;
+ lp->stats.rx_bytes += pktlen;
+ }
#ifdef USE_WDS
- else
- {
- lp->wds_port[port-1].stats.rx_packets++;
- lp->wds_port[port-1].stats.rx_bytes += pktlen;
- }
-#endif /* USE_WDS */
-
- dev->last_rx = jiffies;
-
- } else {
- DBG_ERROR( DbgInfo, "Could not alloc skb\n" );
-
- if( port == 0 )
- {
- lp->stats.rx_dropped++;
- }
+ else {
+ lp->wds_port[port -
+ 1].stats.
+ rx_packets++;
+ lp->wds_port[port -
+ 1].stats.
+ rx_bytes += pktlen;
+ }
+#endif /* USE_WDS */
+
+ dev->last_rx = jiffies;
+
+ } else {
+ DBG_ERROR(DbgInfo,
+ "Could not alloc skb\n");
+
+ if (port == 0) {
+ lp->stats.rx_dropped++;
+ }
#ifdef USE_WDS
- else
- {
- lp->wds_port[port-1].stats.rx_dropped++;
- }
-#endif /* USE_WDS */
- }
- }
- }
- //}
- }
-
- return 0;
-} // wl_rx_dma
+ else {
+ lp->wds_port[port -
+ 1].stats.
+ rx_dropped++;
+ }
+#endif /* USE_WDS */
+ }
+ }
+ }
+ //}
+ }
+
+ return 0;
+} // wl_rx_dma
+
/*============================================================================*/
-#endif // ENABLE_DMA
+#endif // ENABLE_DMA
OpenPOWER on IntegriCloud