diff options
author | Thomas White <taw@bitwiz.org.uk> | 2009-04-25 19:23:57 +0100 |
---|---|---|
committer | Thomas White <taw@bitwiz.org.uk> | 2009-04-25 19:23:57 +0100 |
commit | ca8cdf043c7c6d8e1b4b3d86f3cae12fc37756a2 (patch) | |
tree | dad605a1b3142e85d9ddc08a77d62f6bf09f22cc /drivers/ar6000/ar6000/ar6000_drv.c | |
parent | 16696dd08020690cff796fc4705b4d6bd14e91b0 (diff) | |
parent | b4136a36f31a65d0998a328465df9e8e2ba93166 (diff) |
Merge branch 'andy-tracking' into drm-tracking
Conflicts:
drivers/mfd/glamo/Kconfig
Diffstat (limited to 'drivers/ar6000/ar6000/ar6000_drv.c')
-rw-r--r-- | drivers/ar6000/ar6000/ar6000_drv.c | 195 |
1 files changed, 97 insertions, 98 deletions
diff --git a/drivers/ar6000/ar6000/ar6000_drv.c b/drivers/ar6000/ar6000/ar6000_drv.c index 816557641de..b790670ece8 100644 --- a/drivers/ar6000/ar6000/ar6000_drv.c +++ b/drivers/ar6000/ar6000/ar6000_drv.c @@ -238,6 +238,8 @@ static void ar6000_tx_complete(void *Context, HTC_PACKET *pPacket); static void ar6000_tx_queue_full(void *Context, HTC_ENDPOINT_ID Endpoint); +static void ar6000_tx_queue_avail(void *Context, HTC_ENDPOINT_ID Endpoint); + /* * Static variables */ @@ -972,86 +974,17 @@ ar6000_destroy(struct net_device *dev, unsigned int unregister) return; } - /* Stop the transmit queues */ - netif_stop_queue(dev); - - /* Disable the target and the interrupts associated with it */ - if (ar->arWmiReady == TRUE) - { - if (!bypasswmi) - { - if (ar->arConnected == TRUE || ar->arConnectPending == TRUE) - { - AR_DEBUG_PRINTF("%s(): Disconnect\n", __func__); - AR6000_SPIN_LOCK(&ar->arLock, 0); - ar6000_init_profile_info(ar); - AR6000_SPIN_UNLOCK(&ar->arLock, 0); - wmi_disconnect_cmd(ar->arWmi); - } - - ar6000_dbglog_get_debug_logs(ar); - ar->arWmiReady = FALSE; - ar->arConnected = FALSE; - ar->arConnectPending = FALSE; - wmi_shutdown(ar->arWmi); - ar->arWmiEnabled = FALSE; - ar->arWmi = NULL; - ar->arWlanState = WLAN_ENABLED; -#ifdef USER_KEYS - ar->user_savedkeys_stat = USER_SAVEDKEYS_STAT_INIT; - ar->user_key_ctrl = 0; -#endif - } - - AR_DEBUG_PRINTF("%s(): WMI stopped\n", __func__); - } - else - { - AR_DEBUG_PRINTF("%s(): WMI not ready 0x%08x 0x%08x\n", - __func__, (unsigned int) ar, (unsigned int) ar->arWmi); - - /* Shut down WMI if we have started it */ - if(ar->arWmiEnabled == TRUE) - { - AR_DEBUG_PRINTF("%s(): Shut down WMI\n", __func__); - wmi_shutdown(ar->arWmi); - ar->arWmiEnabled = FALSE; - ar->arWmi = NULL; - } - } - - /* stop HTC */ - HTCStop(ar->arHtcTarget); - - /* set the instance to NULL so we do not get called back on remove incase we - * we're explicity destroyed by module unload */ - HTCSetInstance(ar->arHtcTarget, NULL); - - if (resetok) { - /* try to reset the device if we can - * The driver may have been configure NOT to reset the target during - * a debug session */ - AR_DEBUG_PRINTF(" Attempting to reset target on instance destroy.... \n"); - ar6000_reset_device(ar->arHifDevice, ar->arTargetType); - } else { - AR_DEBUG_PRINTF(" Host does not want target reset. \n"); - } - - /* Done with cookies */ - ar6000_cookie_cleanup(ar); - - /* Cleanup BMI */ - BMIInit(); - /* Clear the tx counters */ memset(tx_attempt, 0, sizeof(tx_attempt)); memset(tx_post, 0, sizeof(tx_post)); memset(tx_complete, 0, sizeof(tx_complete)); - /* Free up the device data structure */ - if (unregister) - unregister_netdev(dev); + if (unregister) { + unregister_netdev(dev); + } else { + ar6000_close(dev); + } free_raw_buffers(ar); @@ -1149,7 +1082,7 @@ static int ar6000_open(struct net_device *dev) { /* Wake up the queues */ - netif_wake_queue(dev); + netif_start_queue(dev); return 0; } @@ -1157,8 +1090,79 @@ ar6000_open(struct net_device *dev) static int ar6000_close(struct net_device *dev) { + AR_SOFTC_T *ar = netdev_priv(dev); + + /* Stop the transmit queues */ netif_stop_queue(dev); + /* Disable the target and the interrupts associated with it */ + if (ar->arWmiReady == TRUE) + { + if (!bypasswmi) + { + if (ar->arConnected == TRUE || ar->arConnectPending == TRUE) + { + AR_DEBUG_PRINTF("%s(): Disconnect\n", __func__); + AR6000_SPIN_LOCK(&ar->arLock, 0); + ar6000_init_profile_info(ar); + AR6000_SPIN_UNLOCK(&ar->arLock, 0); + wmi_disconnect_cmd(ar->arWmi); + } + + ar6000_dbglog_get_debug_logs(ar); + ar->arWmiReady = FALSE; + ar->arConnected = FALSE; + ar->arConnectPending = FALSE; + wmi_shutdown(ar->arWmi); + ar->arWmiEnabled = FALSE; + ar->arWmi = NULL; + ar->arWlanState = WLAN_ENABLED; +#ifdef USER_KEYS + ar->user_savedkeys_stat = USER_SAVEDKEYS_STAT_INIT; + ar->user_key_ctrl = 0; +#endif + } + + AR_DEBUG_PRINTF("%s(): WMI stopped\n", __func__); + } + else + { + AR_DEBUG_PRINTF("%s(): WMI not ready 0x%08x 0x%08x\n", + __func__, (unsigned int) ar, (unsigned int) ar->arWmi); + + /* Shut down WMI if we have started it */ + if(ar->arWmiEnabled == TRUE) + { + AR_DEBUG_PRINTF("%s(): Shut down WMI\n", __func__); + wmi_shutdown(ar->arWmi); + ar->arWmiEnabled = FALSE; + ar->arWmi = NULL; + } + } + + /* stop HTC */ + HTCStop(ar->arHtcTarget); + + /* set the instance to NULL so we do not get called back on remove incase we + * we're explicity destroyed by module unload */ + HTCSetInstance(ar->arHtcTarget, NULL); + + if (resetok) { + /* try to reset the device if we can + * The driver may have been configure NOT to reset the target during + * a debug session */ + AR_DEBUG_PRINTF(" Attempting to reset target on instance destroy.... \n"); + ar6000_reset_device(ar->arHifDevice, ar->arTargetType); + } else { + AR_DEBUG_PRINTF(" Host does not want target reset. \n"); + } + + /* Done with cookies */ + ar6000_cookie_cleanup(ar); + + /* Cleanup BMI */ + BMIInit(); + return 0; } @@ -1278,6 +1282,7 @@ int ar6000_init(struct net_device *dev) connect.EpCallbacks.EpRecv = ar6000_rx; connect.EpCallbacks.EpRecvRefill = ar6000_rx_refill; connect.EpCallbacks.EpSendFull = ar6000_tx_queue_full; + connect.EpCallbacks.EpSendAvail = ar6000_tx_queue_avail; /* set the max queue depth so that our ar6000_tx_queue_full handler gets called. * Linux has the peculiarity of not providing flow control between the * NIC and the network stack. There is no API to indicate that a TX packet @@ -1753,10 +1758,10 @@ applyAPTCHeuristics(AR_SOFTC_T *ar) } #endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */ -static void ar6000_tx_queue_full(void *Context, HTC_ENDPOINT_ID Endpoint) +static void +ar6000_tx_queue_full(void *Context, HTC_ENDPOINT_ID Endpoint) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)Context; - + AR_SOFTC_T *ar = (AR_SOFTC_T *) Context; if (Endpoint == arWMIStream2EndpointID(ar,WMI_CONTROL_PRI)) { if (!bypasswmi) { @@ -1771,19 +1776,26 @@ static void ar6000_tx_queue_full(void *Context, HTC_ENDPOINT_ID Endpoint) AR_DEBUG_PRINTF("WMI Control Endpoint is FULL!!! \n"); } } else { - - AR6000_SPIN_LOCK(&ar->arLock, 0); - ar->arNetQueueStopped = TRUE; - AR6000_SPIN_UNLOCK(&ar->arLock, 0); /* one of the data endpoints queues is getting full..need to stop network stack - * the queue will resume in ar6000_tx_complete() */ + * the queue will resume after credits received */ netif_stop_queue(ar->arNetDev); } +} +static void +ar6000_tx_queue_avail(void *Context, HTC_ENDPOINT_ID Endpoint) +{ + AR_SOFTC_T *ar = (AR_SOFTC_T *)Context; + if (Endpoint == arWMIStream2EndpointID(ar,WMI_CONTROL_PRI)) { + /* FIXME: what do for it? */ + } else { + /* Wake up interface, rescheduling prevented. */ + if (ar->arConnected == TRUE || bypasswmi) + netif_wake_queue(ar->arNetDev); + } } - static void ar6000_tx_complete(void *Context, HTC_PACKET *pPacket) { @@ -1877,10 +1889,6 @@ ar6000_tx_complete(void *Context, HTC_PACKET *pPacket) ar6000_free_cookie(ar, cookie); } - if (ar->arNetQueueStopped) { - ar->arNetQueueStopped = FALSE; - } - AR6000_SPIN_UNLOCK(&ar->arLock, 0); /* lock is released, we can freely call other kernel APIs */ @@ -1888,18 +1896,9 @@ ar6000_tx_complete(void *Context, HTC_PACKET *pPacket) /* this indirectly frees the HTC_PACKET */ A_NETBUF_FREE(skb); - if ((ar->arConnected == TRUE) || (bypasswmi)) { - if (status != A_ECANCELED) { - /* don't wake the queue if we are flushing, other wise it will just - * keep queueing packets, which will keep failing */ - netif_wake_queue(ar->arNetDev); - } - } - if (wakeEvent) { wake_up(&arEvent); } - } /* @@ -2317,7 +2316,7 @@ ar6000_connect_event(AR_SOFTC_T *ar, A_UINT16 channel, A_UINT8 *bssid, /* flush data queues */ ar6000_TxDataCleanup(ar); - netif_wake_queue(ar->arNetDev); + netif_start_queue(ar->arNetDev); if ((OPEN_AUTH == ar->arDot11AuthMode) && (NONE_AUTH == ar->arAuthMode) && |