diff options
Diffstat (limited to 'drivers/net/wireless/ipw2x00/ipw2100.c')
-rw-r--r-- | drivers/net/wireless/ipw2x00/ipw2100.c | 84 |
1 files changed, 37 insertions, 47 deletions
diff --git a/drivers/net/wireless/ipw2x00/ipw2100.c b/drivers/net/wireless/ipw2x00/ipw2100.c index 996e9d7d7586..44307753587d 100644 --- a/drivers/net/wireless/ipw2x00/ipw2100.c +++ b/drivers/net/wireless/ipw2x00/ipw2100.c | |||
@@ -63,7 +63,7 @@ When data is sent to the firmware, the first TBD is used to indicate to the | |||
63 | firmware if a Command or Data is being sent. If it is Command, all of the | 63 | firmware if a Command or Data is being sent. If it is Command, all of the |
64 | command information is contained within the physical address referred to by the | 64 | command information is contained within the physical address referred to by the |
65 | TBD. If it is Data, the first TBD indicates the type of data packet, number | 65 | TBD. If it is Data, the first TBD indicates the type of data packet, number |
66 | of fragments, etc. The next TBD then referrs to the actual packet location. | 66 | of fragments, etc. The next TBD then refers to the actual packet location. |
67 | 67 | ||
68 | The Tx flow cycle is as follows: | 68 | The Tx flow cycle is as follows: |
69 | 69 | ||
@@ -706,11 +706,10 @@ static void schedule_reset(struct ipw2100_priv *priv) | |||
706 | netif_stop_queue(priv->net_dev); | 706 | netif_stop_queue(priv->net_dev); |
707 | priv->status |= STATUS_RESET_PENDING; | 707 | priv->status |= STATUS_RESET_PENDING; |
708 | if (priv->reset_backoff) | 708 | if (priv->reset_backoff) |
709 | queue_delayed_work(priv->workqueue, &priv->reset_work, | 709 | schedule_delayed_work(&priv->reset_work, |
710 | priv->reset_backoff * HZ); | 710 | priv->reset_backoff * HZ); |
711 | else | 711 | else |
712 | queue_delayed_work(priv->workqueue, &priv->reset_work, | 712 | schedule_delayed_work(&priv->reset_work, 0); |
713 | 0); | ||
714 | 713 | ||
715 | if (priv->reset_backoff < MAX_RESET_BACKOFF) | 714 | if (priv->reset_backoff < MAX_RESET_BACKOFF) |
716 | priv->reset_backoff++; | 715 | priv->reset_backoff++; |
@@ -1397,7 +1396,7 @@ static int ipw2100_power_cycle_adapter(struct ipw2100_priv *priv) | |||
1397 | } | 1396 | } |
1398 | 1397 | ||
1399 | /* | 1398 | /* |
1400 | * Send the CARD_DISABLE_PHY_OFF comamnd to the card to disable it | 1399 | * Send the CARD_DISABLE_PHY_OFF command to the card to disable it |
1401 | * | 1400 | * |
1402 | * After disabling, if the card was associated, a STATUS_ASSN_LOST will be sent. | 1401 | * After disabling, if the card was associated, a STATUS_ASSN_LOST will be sent. |
1403 | * | 1402 | * |
@@ -1474,7 +1473,7 @@ static int ipw2100_enable_adapter(struct ipw2100_priv *priv) | |||
1474 | 1473 | ||
1475 | if (priv->stop_hang_check) { | 1474 | if (priv->stop_hang_check) { |
1476 | priv->stop_hang_check = 0; | 1475 | priv->stop_hang_check = 0; |
1477 | queue_delayed_work(priv->workqueue, &priv->hang_check, HZ / 2); | 1476 | schedule_delayed_work(&priv->hang_check, HZ / 2); |
1478 | } | 1477 | } |
1479 | 1478 | ||
1480 | fail_up: | 1479 | fail_up: |
@@ -1808,8 +1807,8 @@ static int ipw2100_up(struct ipw2100_priv *priv, int deferred) | |||
1808 | 1807 | ||
1809 | if (priv->stop_rf_kill) { | 1808 | if (priv->stop_rf_kill) { |
1810 | priv->stop_rf_kill = 0; | 1809 | priv->stop_rf_kill = 0; |
1811 | queue_delayed_work(priv->workqueue, &priv->rf_kill, | 1810 | schedule_delayed_work(&priv->rf_kill, |
1812 | round_jiffies_relative(HZ)); | 1811 | round_jiffies_relative(HZ)); |
1813 | } | 1812 | } |
1814 | 1813 | ||
1815 | deferred = 1; | 1814 | deferred = 1; |
@@ -1921,9 +1920,9 @@ static int ipw2100_net_init(struct net_device *dev) | |||
1921 | 1920 | ||
1922 | bg_band->band = IEEE80211_BAND_2GHZ; | 1921 | bg_band->band = IEEE80211_BAND_2GHZ; |
1923 | bg_band->n_channels = geo->bg_channels; | 1922 | bg_band->n_channels = geo->bg_channels; |
1924 | bg_band->channels = | 1923 | bg_band->channels = kcalloc(geo->bg_channels, |
1925 | kzalloc(geo->bg_channels * | 1924 | sizeof(struct ieee80211_channel), |
1926 | sizeof(struct ieee80211_channel), GFP_KERNEL); | 1925 | GFP_KERNEL); |
1927 | if (!bg_band->channels) { | 1926 | if (!bg_band->channels) { |
1928 | ipw2100_down(priv); | 1927 | ipw2100_down(priv); |
1929 | return -ENOMEM; | 1928 | return -ENOMEM; |
@@ -2086,7 +2085,7 @@ static void isr_indicate_associated(struct ipw2100_priv *priv, u32 status) | |||
2086 | priv->status |= STATUS_ASSOCIATING; | 2085 | priv->status |= STATUS_ASSOCIATING; |
2087 | priv->connect_start = get_seconds(); | 2086 | priv->connect_start = get_seconds(); |
2088 | 2087 | ||
2089 | queue_delayed_work(priv->workqueue, &priv->wx_event_work, HZ / 10); | 2088 | schedule_delayed_work(&priv->wx_event_work, HZ / 10); |
2090 | } | 2089 | } |
2091 | 2090 | ||
2092 | static int ipw2100_set_essid(struct ipw2100_priv *priv, char *essid, | 2091 | static int ipw2100_set_essid(struct ipw2100_priv *priv, char *essid, |
@@ -2166,9 +2165,9 @@ static void isr_indicate_association_lost(struct ipw2100_priv *priv, u32 status) | |||
2166 | return; | 2165 | return; |
2167 | 2166 | ||
2168 | if (priv->status & STATUS_SECURITY_UPDATED) | 2167 | if (priv->status & STATUS_SECURITY_UPDATED) |
2169 | queue_delayed_work(priv->workqueue, &priv->security_work, 0); | 2168 | schedule_delayed_work(&priv->security_work, 0); |
2170 | 2169 | ||
2171 | queue_delayed_work(priv->workqueue, &priv->wx_event_work, 0); | 2170 | schedule_delayed_work(&priv->wx_event_work, 0); |
2172 | } | 2171 | } |
2173 | 2172 | ||
2174 | static void isr_indicate_rf_kill(struct ipw2100_priv *priv, u32 status) | 2173 | static void isr_indicate_rf_kill(struct ipw2100_priv *priv, u32 status) |
@@ -2183,8 +2182,7 @@ static void isr_indicate_rf_kill(struct ipw2100_priv *priv, u32 status) | |||
2183 | /* Make sure the RF Kill check timer is running */ | 2182 | /* Make sure the RF Kill check timer is running */ |
2184 | priv->stop_rf_kill = 0; | 2183 | priv->stop_rf_kill = 0; |
2185 | cancel_delayed_work(&priv->rf_kill); | 2184 | cancel_delayed_work(&priv->rf_kill); |
2186 | queue_delayed_work(priv->workqueue, &priv->rf_kill, | 2185 | schedule_delayed_work(&priv->rf_kill, round_jiffies_relative(HZ)); |
2187 | round_jiffies_relative(HZ)); | ||
2188 | } | 2186 | } |
2189 | 2187 | ||
2190 | static void send_scan_event(void *data) | 2188 | static void send_scan_event(void *data) |
@@ -2219,13 +2217,12 @@ static void isr_scan_complete(struct ipw2100_priv *priv, u32 status) | |||
2219 | /* Only userspace-requested scan completion events go out immediately */ | 2217 | /* Only userspace-requested scan completion events go out immediately */ |
2220 | if (!priv->user_requested_scan) { | 2218 | if (!priv->user_requested_scan) { |
2221 | if (!delayed_work_pending(&priv->scan_event_later)) | 2219 | if (!delayed_work_pending(&priv->scan_event_later)) |
2222 | queue_delayed_work(priv->workqueue, | 2220 | schedule_delayed_work(&priv->scan_event_later, |
2223 | &priv->scan_event_later, | 2221 | round_jiffies_relative(msecs_to_jiffies(4000))); |
2224 | round_jiffies_relative(msecs_to_jiffies(4000))); | ||
2225 | } else { | 2222 | } else { |
2226 | priv->user_requested_scan = 0; | 2223 | priv->user_requested_scan = 0; |
2227 | cancel_delayed_work(&priv->scan_event_later); | 2224 | cancel_delayed_work(&priv->scan_event_later); |
2228 | queue_work(priv->workqueue, &priv->scan_event_now); | 2225 | schedule_work(&priv->scan_event_now); |
2229 | } | 2226 | } |
2230 | } | 2227 | } |
2231 | 2228 | ||
@@ -3056,9 +3053,9 @@ static void ipw2100_tx_send_commands(struct ipw2100_priv *priv) | |||
3056 | 3053 | ||
3057 | packet = list_entry(element, struct ipw2100_tx_packet, list); | 3054 | packet = list_entry(element, struct ipw2100_tx_packet, list); |
3058 | 3055 | ||
3059 | IPW_DEBUG_TX("using TBD at virt=%p, phys=%p\n", | 3056 | IPW_DEBUG_TX("using TBD at virt=%p, phys=%04X\n", |
3060 | &txq->drv[txq->next], | 3057 | &txq->drv[txq->next], |
3061 | (void *)(txq->nic + txq->next * | 3058 | (u32) (txq->nic + txq->next * |
3062 | sizeof(struct ipw2100_bd))); | 3059 | sizeof(struct ipw2100_bd))); |
3063 | 3060 | ||
3064 | packet->index = txq->next; | 3061 | packet->index = txq->next; |
@@ -4329,8 +4326,8 @@ static int ipw_radio_kill_sw(struct ipw2100_priv *priv, int disable_radio) | |||
4329 | /* Make sure the RF_KILL check timer is running */ | 4326 | /* Make sure the RF_KILL check timer is running */ |
4330 | priv->stop_rf_kill = 0; | 4327 | priv->stop_rf_kill = 0; |
4331 | cancel_delayed_work(&priv->rf_kill); | 4328 | cancel_delayed_work(&priv->rf_kill); |
4332 | queue_delayed_work(priv->workqueue, &priv->rf_kill, | 4329 | schedule_delayed_work(&priv->rf_kill, |
4333 | round_jiffies_relative(HZ)); | 4330 | round_jiffies_relative(HZ)); |
4334 | } else | 4331 | } else |
4335 | schedule_reset(priv); | 4332 | schedule_reset(priv); |
4336 | } | 4333 | } |
@@ -4461,20 +4458,17 @@ static void bd_queue_initialize(struct ipw2100_priv *priv, | |||
4461 | IPW_DEBUG_INFO("exit\n"); | 4458 | IPW_DEBUG_INFO("exit\n"); |
4462 | } | 4459 | } |
4463 | 4460 | ||
4464 | static void ipw2100_kill_workqueue(struct ipw2100_priv *priv) | 4461 | static void ipw2100_kill_works(struct ipw2100_priv *priv) |
4465 | { | 4462 | { |
4466 | if (priv->workqueue) { | 4463 | priv->stop_rf_kill = 1; |
4467 | priv->stop_rf_kill = 1; | 4464 | priv->stop_hang_check = 1; |
4468 | priv->stop_hang_check = 1; | 4465 | cancel_delayed_work_sync(&priv->reset_work); |
4469 | cancel_delayed_work(&priv->reset_work); | 4466 | cancel_delayed_work_sync(&priv->security_work); |
4470 | cancel_delayed_work(&priv->security_work); | 4467 | cancel_delayed_work_sync(&priv->wx_event_work); |
4471 | cancel_delayed_work(&priv->wx_event_work); | 4468 | cancel_delayed_work_sync(&priv->hang_check); |
4472 | cancel_delayed_work(&priv->hang_check); | 4469 | cancel_delayed_work_sync(&priv->rf_kill); |
4473 | cancel_delayed_work(&priv->rf_kill); | 4470 | cancel_work_sync(&priv->scan_event_now); |
4474 | cancel_delayed_work(&priv->scan_event_later); | 4471 | cancel_delayed_work_sync(&priv->scan_event_later); |
4475 | destroy_workqueue(priv->workqueue); | ||
4476 | priv->workqueue = NULL; | ||
4477 | } | ||
4478 | } | 4472 | } |
4479 | 4473 | ||
4480 | static int ipw2100_tx_allocate(struct ipw2100_priv *priv) | 4474 | static int ipw2100_tx_allocate(struct ipw2100_priv *priv) |
@@ -6046,7 +6040,7 @@ static void ipw2100_hang_check(struct work_struct *work) | |||
6046 | priv->last_rtc = rtc; | 6040 | priv->last_rtc = rtc; |
6047 | 6041 | ||
6048 | if (!priv->stop_hang_check) | 6042 | if (!priv->stop_hang_check) |
6049 | queue_delayed_work(priv->workqueue, &priv->hang_check, HZ / 2); | 6043 | schedule_delayed_work(&priv->hang_check, HZ / 2); |
6050 | 6044 | ||
6051 | spin_unlock_irqrestore(&priv->low_lock, flags); | 6045 | spin_unlock_irqrestore(&priv->low_lock, flags); |
6052 | } | 6046 | } |
@@ -6062,8 +6056,8 @@ static void ipw2100_rf_kill(struct work_struct *work) | |||
6062 | if (rf_kill_active(priv)) { | 6056 | if (rf_kill_active(priv)) { |
6063 | IPW_DEBUG_RF_KILL("RF Kill active, rescheduling GPIO check\n"); | 6057 | IPW_DEBUG_RF_KILL("RF Kill active, rescheduling GPIO check\n"); |
6064 | if (!priv->stop_rf_kill) | 6058 | if (!priv->stop_rf_kill) |
6065 | queue_delayed_work(priv->workqueue, &priv->rf_kill, | 6059 | schedule_delayed_work(&priv->rf_kill, |
6066 | round_jiffies_relative(HZ)); | 6060 | round_jiffies_relative(HZ)); |
6067 | goto exit_unlock; | 6061 | goto exit_unlock; |
6068 | } | 6062 | } |
6069 | 6063 | ||
@@ -6209,8 +6203,6 @@ static struct net_device *ipw2100_alloc_device(struct pci_dev *pci_dev, | |||
6209 | INIT_LIST_HEAD(&priv->fw_pend_list); | 6203 | INIT_LIST_HEAD(&priv->fw_pend_list); |
6210 | INIT_STAT(&priv->fw_pend_stat); | 6204 | INIT_STAT(&priv->fw_pend_stat); |
6211 | 6205 | ||
6212 | priv->workqueue = create_workqueue(DRV_NAME); | ||
6213 | |||
6214 | INIT_DELAYED_WORK(&priv->reset_work, ipw2100_reset_adapter); | 6206 | INIT_DELAYED_WORK(&priv->reset_work, ipw2100_reset_adapter); |
6215 | INIT_DELAYED_WORK(&priv->security_work, ipw2100_security_work); | 6207 | INIT_DELAYED_WORK(&priv->security_work, ipw2100_security_work); |
6216 | INIT_DELAYED_WORK(&priv->wx_event_work, ipw2100_wx_event_work); | 6208 | INIT_DELAYED_WORK(&priv->wx_event_work, ipw2100_wx_event_work); |
@@ -6410,7 +6402,7 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev, | |||
6410 | if (dev->irq) | 6402 | if (dev->irq) |
6411 | free_irq(dev->irq, priv); | 6403 | free_irq(dev->irq, priv); |
6412 | 6404 | ||
6413 | ipw2100_kill_workqueue(priv); | 6405 | ipw2100_kill_works(priv); |
6414 | 6406 | ||
6415 | /* These are safe to call even if they weren't allocated */ | 6407 | /* These are safe to call even if they weren't allocated */ |
6416 | ipw2100_queues_free(priv); | 6408 | ipw2100_queues_free(priv); |
@@ -6460,9 +6452,7 @@ static void __devexit ipw2100_pci_remove_one(struct pci_dev *pci_dev) | |||
6460 | * first, then close() will crash. */ | 6452 | * first, then close() will crash. */ |
6461 | unregister_netdev(dev); | 6453 | unregister_netdev(dev); |
6462 | 6454 | ||
6463 | /* ipw2100_down will ensure that there is no more pending work | 6455 | ipw2100_kill_works(priv); |
6464 | * in the workqueue's, so we can safely remove them now. */ | ||
6465 | ipw2100_kill_workqueue(priv); | ||
6466 | 6456 | ||
6467 | ipw2100_queues_free(priv); | 6457 | ipw2100_queues_free(priv); |
6468 | 6458 | ||