From 5af70c864a1539bd1d3f3fcb04ab9558491c9103 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Tue, 28 Feb 2012 00:41:28 +0200 Subject: wl12xx: set the ELP entry delay to the FW dyn-ps timeout With PSM handled in FW, the checks in wl1271_elp_work() are always true. Thus during active traffic we constantly enter and exit ELP (many times per second). As each ELP exit takes ~10ms, this can have an adverse effect on throughput and interactivity. Set the ELP timeout to the dyn-ps timeout. This period is longer and avoids the above problem. It also makes sense to stay out of ELP while we are awake on the network, to minimize delays in Tx/Rx. The same thing was done by the mac80211 dynamic-ps mechanism before the FW DPS changes. Signed-off-by: Arik Nemtsov Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/ps.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/net/wireless/wl12xx/ps.c b/drivers/net/wireless/wl12xx/ps.c index 23d67501c50a..78f598b4f97b 100644 --- a/drivers/net/wireless/wl12xx/ps.c +++ b/drivers/net/wireless/wl12xx/ps.c @@ -69,8 +69,6 @@ out: mutex_unlock(&wl->mutex); } -#define ELP_ENTRY_DELAY 5 - /* Routines to toggle sleep mode while in ELP */ void wl1271_ps_elp_sleep(struct wl1271 *wl) { @@ -90,7 +88,7 @@ void wl1271_ps_elp_sleep(struct wl1271 *wl) } ieee80211_queue_delayed_work(wl->hw, &wl->elp_work, - msecs_to_jiffies(ELP_ENTRY_DELAY)); + msecs_to_jiffies(wl->conf.conn.dynamic_ps_timeout)); } int wl1271_ps_elp_wakeup(struct wl1271 *wl) -- cgit From 0b0e32b792b4077c113ae70d6de12b5f301e0882 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Tue, 28 Feb 2012 00:41:29 +0200 Subject: wl12xx: change bits in the link_map under spin lock These bits are used in op_tx to determine if a packet should be dropped. As such we should use the spin lock to sync the state. Signed-off-by: Arik Nemtsov Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/cmd.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/net/wireless/wl12xx/cmd.c b/drivers/net/wireless/wl12xx/cmd.c index b776d9d5efe8..ef994dacf8d2 100644 --- a/drivers/net/wireless/wl12xx/cmd.c +++ b/drivers/net/wireless/wl12xx/cmd.c @@ -459,23 +459,32 @@ out: int wl12xx_allocate_link(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 *hlid) { + unsigned long flags; u8 link = find_first_zero_bit(wl->links_map, WL12XX_MAX_LINKS); if (link >= WL12XX_MAX_LINKS) return -EBUSY; + /* these bits are used by op_tx */ + spin_lock_irqsave(&wl->wl_lock, flags); __set_bit(link, wl->links_map); __set_bit(link, wlvif->links_map); + spin_unlock_irqrestore(&wl->wl_lock, flags); *hlid = link; return 0; } void wl12xx_free_link(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 *hlid) { + unsigned long flags; + if (*hlid == WL12XX_INVALID_LINK_ID) return; + /* these bits are used by op_tx */ + spin_lock_irqsave(&wl->wl_lock, flags); __clear_bit(*hlid, wl->links_map); __clear_bit(*hlid, wlvif->links_map); + spin_unlock_irqrestore(&wl->wl_lock, flags); *hlid = WL12XX_INVALID_LINK_ID; } -- cgit From 6246ca003f2560e30b9696757efc271284b809f6 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Tue, 28 Feb 2012 00:41:30 +0200 Subject: wl12xx: reset link Tx queues when freeing it Before, the link was first freed (invalidating it in the map), and later on vif removal, all valid wlvif-related links were reset. Since these links were already invalid, we failed to reset them. The bug was made worse by op_stop, which set the tx_queue_count to 0 arbitrarily. This resulted in a negative tx_queue_count in some scenarios. Fix this by resetting the Tx-queues of a link when freeing it. Add a WARN_ON and reset all link Tx-queues in op_stop, to avoid a negative tx_queue_count. [changed WARN_ON to WARN_ON_ONCE -- Luca] Signed-off-by: Arik Nemtsov Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/cmd.c | 7 +++++++ drivers/net/wireless/wl12xx/main.c | 1 - drivers/net/wireless/wl12xx/tx.c | 13 ++++++++++--- 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/wl12xx/cmd.c b/drivers/net/wireless/wl12xx/cmd.c index ef994dacf8d2..ae1f3d7f34d2 100644 --- a/drivers/net/wireless/wl12xx/cmd.c +++ b/drivers/net/wireless/wl12xx/cmd.c @@ -485,6 +485,13 @@ void wl12xx_free_link(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 *hlid) __clear_bit(*hlid, wl->links_map); __clear_bit(*hlid, wlvif->links_map); spin_unlock_irqrestore(&wl->wl_lock, flags); + + /* + * At this point op_tx() will not add more packets to the queues. We + * can purge them. + */ + wl1271_tx_reset_link_queues(wl, *hlid); + *hlid = WL12XX_INVALID_LINK_ID; } diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index adf9bbcf88fd..712e38530153 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -4228,7 +4228,6 @@ void wl1271_free_sta(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 hlid) clear_bit(hlid, wlvif->ap.sta_hlid_map); memset(wl->links[hlid].addr, 0, ETH_ALEN); wl->links[hlid].ba_bitmap = 0; - wl1271_tx_reset_link_queues(wl, hlid); __clear_bit(hlid, &wl->ap_ps_map); __clear_bit(hlid, (unsigned long *)&wl->ap_fw_ps_map); wl12xx_free_link(wl, wlvif, &hlid); diff --git a/drivers/net/wireless/wl12xx/tx.c b/drivers/net/wireless/wl12xx/tx.c index 6446e4d3e8f9..8f5ab047aec8 100644 --- a/drivers/net/wireless/wl12xx/tx.c +++ b/drivers/net/wireless/wl12xx/tx.c @@ -527,6 +527,7 @@ static struct sk_buff *wl12xx_lnk_skb_dequeue(struct wl1271 *wl, if (skb) { int q = wl1271_tx_get_queue(skb_get_queue_mapping(skb)); spin_lock_irqsave(&wl->wl_lock, flags); + WARN_ON_ONCE(wl->tx_queue_count[q] <= 0); wl->tx_queue_count[q]--; spin_unlock_irqrestore(&wl->wl_lock, flags); } @@ -602,6 +603,7 @@ static struct sk_buff *wl1271_skb_dequeue(struct wl1271 *wl) skb = wl->dummy_packet; q = wl1271_tx_get_queue(skb_get_queue_mapping(skb)); spin_lock_irqsave(&wl->wl_lock, flags); + WARN_ON_ONCE(wl->tx_queue_count[q] <= 0); wl->tx_queue_count[q]--; spin_unlock_irqrestore(&wl->wl_lock, flags); } @@ -959,7 +961,6 @@ void wl12xx_tx_reset_wlvif(struct wl1271 *wl, struct wl12xx_vif *wlvif) else wlvif->sta.ba_rx_bitmap = 0; - wl1271_tx_reset_link_queues(wl, i); wl->links[i].allocated_pkts = 0; wl->links[i].prev_freed_pkts = 0; } @@ -973,8 +974,14 @@ void wl12xx_tx_reset(struct wl1271 *wl, bool reset_tx_queues) struct sk_buff *skb; struct ieee80211_tx_info *info; - for (i = 0; i < NUM_TX_QUEUES; i++) - wl->tx_queue_count[i] = 0; + /* only reset the queues if something bad happened */ + if (WARN_ON_ONCE(wl1271_tx_total_queue_count(wl) != 0)) { + for (i = 0; i < WL12XX_MAX_LINKS; i++) + wl1271_tx_reset_link_queues(wl, i); + + for (i = 0; i < NUM_TX_QUEUES; i++) + wl->tx_queue_count[i] = 0; + } wl->stopped_queues_map = 0; -- cgit From 49c9cd26445aa8bc8348c384c943b758c57c47a9 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Tue, 28 Feb 2012 00:41:31 +0200 Subject: wl12xx: avoid starving the system hlid Re-factor the Tx scheduler so that the system_hlid is taken into account before restarting an iteration over the wlvifs. Previously this hlid had a lower priority and would starve if some wlvif had many packets. In addition avoid iterating over wlvifs past last_wlvif when performing the a second pass. If we had packets in those wlvifs they would have been found earlier. Signed-off-by: Arik Nemtsov Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/tx.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/wl12xx/tx.c b/drivers/net/wireless/wl12xx/tx.c index 8f5ab047aec8..6640c3975cfb 100644 --- a/drivers/net/wireless/wl12xx/tx.c +++ b/drivers/net/wireless/wl12xx/tx.c @@ -572,6 +572,7 @@ static struct sk_buff *wl1271_skb_dequeue(struct wl1271 *wl) struct wl12xx_vif *wlvif = wl->last_wlvif; struct sk_buff *skb = NULL; + /* continue from last wlvif (round robin) */ if (wlvif) { wl12xx_for_each_wlvif_continue(wl, wlvif) { skb = wl12xx_vif_skb_dequeue(wl, wlvif); @@ -582,7 +583,11 @@ static struct sk_buff *wl1271_skb_dequeue(struct wl1271 *wl) } } - /* do another pass */ + /* dequeue from the system HLID before the restarting wlvif list */ + if (!skb) + skb = wl12xx_lnk_skb_dequeue(wl, &wl->links[wl->system_hlid]); + + /* do a new pass over the wlvif list */ if (!skb) { wl12xx_for_each_wlvif(wl, wlvif) { skb = wl12xx_vif_skb_dequeue(wl, wlvif); @@ -590,12 +595,16 @@ static struct sk_buff *wl1271_skb_dequeue(struct wl1271 *wl) wl->last_wlvif = wlvif; break; } + + /* + * No need to continue after last_wlvif. The previous + * pass should have found it. + */ + if (wlvif == wl->last_wlvif) + break; } } - if (!skb) - skb = wl12xx_lnk_skb_dequeue(wl, &wl->links[wl->system_hlid]); - if (!skb && test_and_clear_bit(WL1271_FLAG_DUMMY_PACKET_PENDING, &wl->flags)) { int q; -- cgit From 18aa755b84715f36e2811734f95cb822bcacfd89 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Tue, 28 Feb 2012 00:41:32 +0200 Subject: wl12xx: flush all Tx queues on tx_flush timeout Ensure our queues are empty at the end of a tx_flush(), in case we timeout on passively waiting for them. This makes sure no left-overs are transmitted when we are on the wrong channel. Signed-off-by: Arik Nemtsov Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/tx.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/net/wireless/wl12xx/tx.c b/drivers/net/wireless/wl12xx/tx.c index 6640c3975cfb..8f78fddcb723 100644 --- a/drivers/net/wireless/wl12xx/tx.c +++ b/drivers/net/wireless/wl12xx/tx.c @@ -1040,6 +1040,7 @@ void wl12xx_tx_reset(struct wl1271 *wl, bool reset_tx_queues) void wl1271_tx_flush(struct wl1271 *wl) { unsigned long timeout; + int i; timeout = jiffies + usecs_to_jiffies(WL1271_TX_FLUSH_TIMEOUT); while (!time_after(jiffies, timeout)) { @@ -1057,6 +1058,12 @@ void wl1271_tx_flush(struct wl1271 *wl) } wl1271_warning("Unable to flush all TX buffers, timed out."); + + /* forcibly flush all Tx buffers on our queues */ + mutex_lock(&wl->mutex); + for (i = 0; i < WL12XX_MAX_LINKS; i++) + wl1271_tx_reset_link_queues(wl, i); + mutex_unlock(&wl->mutex); } u32 wl1271_tx_min_rate_get(struct wl1271 *wl, u32 rate_set) -- cgit From b9239b665889582835fbd54730902eee08aa42d7 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Tue, 28 Feb 2012 00:41:33 +0200 Subject: wl12xx: flush Tx during suspend and 802.11h chan switch Flush our Tx queues before suspending or changing the channel due to a channel_switch element in the AP beacon. Signed-off-by: Arik Nemtsov Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/main.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index 712e38530153..ad1a4addaab5 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -1737,6 +1737,8 @@ static int wl1271_op_suspend(struct ieee80211_hw *hw, wl1271_debug(DEBUG_MAC80211, "mac80211 suspend wow=%d", !!wow); WARN_ON(!wow || !wow->any); + wl1271_tx_flush(wl); + wl->wow_enabled = true; wl12xx_for_each_wlvif(wl, wlvif) { ret = wl1271_configure_suspend(wl, wlvif); @@ -4496,6 +4498,8 @@ static void wl12xx_op_channel_switch(struct ieee80211_hw *hw, wl1271_debug(DEBUG_MAC80211, "mac80211 channel switch"); + wl1271_tx_flush(wl); + mutex_lock(&wl->mutex); if (unlikely(wl->state == WL1271_STATE_OFF)) { -- cgit From d7b63b9fc7ee73e75a4c7fdb899a7c43ded7d25f Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Tue, 28 Feb 2012 00:41:34 +0200 Subject: wl12xx: increase dynamic PS timeout to 200ms This ensures the user won't encounter lag associated with getting in and out of PSM when the card is in use. Signed-off-by: Arik Nemtsov Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index ad1a4addaab5..418b2b82c185 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -246,7 +246,7 @@ static struct conf_drv_settings default_conf = { .psm_entry_retries = 8, .psm_exit_retries = 16, .psm_entry_nullfunc_retries = 3, - .dynamic_ps_timeout = 100, + .dynamic_ps_timeout = 200, .forced_ps = false, .keep_alive_interval = 55000, .max_listen_interval = 20, -- cgit From 349345a4ec631cd98767b58b065535dd2278697c Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Sun, 4 Mar 2012 10:55:45 +0200 Subject: wl12xx: don't start dev role on ibss vifs device role is used for scanning and sending packets before connection. however, since we don't need to send packets before ibss creation, there is no need to start the device on idle-off. Signed-off-by: Eliad Peller Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/main.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index 418b2b82c185..93636ea84dae 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -3746,10 +3746,8 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl, ibss_joined = true; } else { if (test_and_clear_bit(WLVIF_FLAG_IBSS_JOINED, - &wlvif->flags)) { + &wlvif->flags)) wl1271_unjoin(wl, wlvif); - wl12xx_start_dev(wl, wlvif); - } } } @@ -3767,7 +3765,7 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl, do_join = true; } - if (changed & BSS_CHANGED_IDLE) { + if (changed & BSS_CHANGED_IDLE && !is_ibss) { ret = wl1271_sta_handle_idle(wl, wlvif, bss_conf->idle); if (ret < 0) wl1271_warning("idle mode change failed %d", ret); -- cgit From 8a6a84a471f7de1845174d1dd66b35074d9d9398 Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Sun, 4 Mar 2012 10:55:46 +0200 Subject: wl12xx: consider bss_conf->idle instead of hw->conf.flags On disassociation, check only whether the current vif is idle, instead of checking whether the device is idle. Signed-off-by: Eliad Peller Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/main.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index 93636ea84dae..b771106c0a1e 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -3901,7 +3901,6 @@ sta_not_found: /* restore the bssid filter and go to dummy bssid */ if (was_assoc) { - u32 conf_flags = wl->hw->conf.flags; /* * we might have to disable roc, if there was * no IF_OPER_UP notification. @@ -3924,7 +3923,7 @@ sta_not_found: } wl1271_unjoin(wl, wlvif); - if (!(conf_flags & IEEE80211_CONF_IDLE)) + if (!bss_conf->idle) wl12xx_start_dev(wl, wlvif); } } -- cgit From 2d6cf2b51fa3492c479c6d1f86496e120b51e1d8 Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Sun, 4 Mar 2012 10:55:47 +0200 Subject: wl12xx: implement sta_state callback Implement sta_state callback instead of the sta_add/remove callbacks. Update the fw regarding peer state and ht caps only after the station was authorized. Otherwise, the fw might try establishing BA session before the sta is authorized. Signed-off-by: Eliad Peller Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/main.c | 137 ++++++++++++++++++++++--------------- 1 file changed, 82 insertions(+), 55 deletions(-) diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index b771106c0a1e..8569ac3760df 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -4233,100 +4233,128 @@ void wl1271_free_sta(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 hlid) wl->active_sta_count--; } -static int wl1271_op_sta_add(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct ieee80211_sta *sta) +static int wl12xx_sta_add(struct wl1271 *wl, + struct wl12xx_vif *wlvif, + struct ieee80211_sta *sta) { - struct wl1271 *wl = hw->priv; - struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif); struct wl1271_station *wl_sta; int ret = 0; u8 hlid; - mutex_lock(&wl->mutex); - - if (unlikely(wl->state == WL1271_STATE_OFF)) - goto out; - - if (wlvif->bss_type != BSS_TYPE_AP_BSS) - goto out; - wl1271_debug(DEBUG_MAC80211, "mac80211 add sta %d", (int)sta->aid); ret = wl1271_allocate_sta(wl, wlvif, sta); if (ret < 0) - goto out; + return ret; wl_sta = (struct wl1271_station *)sta->drv_priv; hlid = wl_sta->hlid; - ret = wl1271_ps_elp_wakeup(wl); - if (ret < 0) - goto out_free_sta; - ret = wl12xx_cmd_add_peer(wl, wlvif, sta, hlid); if (ret < 0) - goto out_sleep; + wl1271_free_sta(wl, wlvif, hlid); - ret = wl12xx_cmd_set_peer_state(wl, hlid); - if (ret < 0) - goto out_sleep; + return ret; +} - ret = wl1271_acx_set_ht_capabilities(wl, &sta->ht_cap, true, hlid); - if (ret < 0) - goto out_sleep; +static int wl12xx_sta_remove(struct wl1271 *wl, + struct wl12xx_vif *wlvif, + struct ieee80211_sta *sta) +{ + struct wl1271_station *wl_sta; + int ret = 0, id; -out_sleep: - wl1271_ps_elp_sleep(wl); + wl1271_debug(DEBUG_MAC80211, "mac80211 remove sta %d", (int)sta->aid); + + wl_sta = (struct wl1271_station *)sta->drv_priv; + id = wl_sta->hlid; + if (WARN_ON(!test_bit(id, wlvif->ap.sta_hlid_map))) + return -EINVAL; -out_free_sta: + ret = wl12xx_cmd_remove_peer(wl, wl_sta->hlid); if (ret < 0) - wl1271_free_sta(wl, wlvif, hlid); + return ret; -out: - mutex_unlock(&wl->mutex); + wl1271_free_sta(wl, wlvif, wl_sta->hlid); return ret; } -static int wl1271_op_sta_remove(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct ieee80211_sta *sta) +static int wl12xx_update_sta_state(struct wl1271 *wl, + struct wl12xx_vif *wlvif, + struct ieee80211_sta *sta, + enum ieee80211_sta_state old_state, + enum ieee80211_sta_state new_state) { - struct wl1271 *wl = hw->priv; - struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif); struct wl1271_station *wl_sta; - int ret = 0, id; + u8 hlid; + bool is_ap = wlvif->bss_type == BSS_TYPE_AP_BSS; + bool is_sta = wlvif->bss_type == BSS_TYPE_STA_BSS; + int ret; - mutex_lock(&wl->mutex); + wl_sta = (struct wl1271_station *)sta->drv_priv; + hlid = wl_sta->hlid; - if (unlikely(wl->state == WL1271_STATE_OFF)) - goto out; + /* Add station (AP mode) */ + if (is_ap && + old_state == IEEE80211_STA_NOTEXIST && + new_state == IEEE80211_STA_NONE) + return wl12xx_sta_add(wl, wlvif, sta); + + /* Remove station (AP mode) */ + if (is_ap && + old_state == IEEE80211_STA_NONE && + new_state == IEEE80211_STA_NOTEXIST) { + /* must not fail */ + wl12xx_sta_remove(wl, wlvif, sta); + return 0; + } - if (wlvif->bss_type != BSS_TYPE_AP_BSS) - goto out; + /* Authorize station (AP mode) */ + if (is_ap && + new_state == IEEE80211_STA_AUTHORIZED) { + ret = wl12xx_cmd_set_peer_state(wl, hlid); + if (ret < 0) + return ret; - wl1271_debug(DEBUG_MAC80211, "mac80211 remove sta %d", (int)sta->aid); + ret = wl1271_acx_set_ht_capabilities(wl, &sta->ht_cap, true, + hlid); + return ret; + } - wl_sta = (struct wl1271_station *)sta->drv_priv; - id = wl_sta->hlid; - if (WARN_ON(!test_bit(id, wlvif->ap.sta_hlid_map))) + return 0; +} + +static int wl12xx_op_sta_state(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, + enum ieee80211_sta_state old_state, + enum ieee80211_sta_state new_state) +{ + struct wl1271 *wl = hw->priv; + struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif); + int ret; + + wl1271_debug(DEBUG_MAC80211, "mac80211 sta %d state=%d->%d", + sta->aid, old_state, new_state); + + mutex_lock(&wl->mutex); + + if (unlikely(wl->state == WL1271_STATE_OFF)) { + ret = -EBUSY; goto out; + } ret = wl1271_ps_elp_wakeup(wl); if (ret < 0) goto out; - ret = wl12xx_cmd_remove_peer(wl, wl_sta->hlid); - if (ret < 0) - goto out_sleep; + ret = wl12xx_update_sta_state(wl, wlvif, sta, old_state, new_state); - wl1271_free_sta(wl, wlvif, wl_sta->hlid); - -out_sleep: wl1271_ps_elp_sleep(wl); - out: mutex_unlock(&wl->mutex); + if (new_state < old_state) + return 0; return ret; } @@ -4795,8 +4823,7 @@ static const struct ieee80211_ops wl1271_ops = { .conf_tx = wl1271_op_conf_tx, .get_tsf = wl1271_op_get_tsf, .get_survey = wl1271_op_get_survey, - .sta_add = wl1271_op_sta_add, - .sta_remove = wl1271_op_sta_remove, + .sta_state = wl12xx_op_sta_state, .ampdu_action = wl1271_op_ampdu_action, .tx_frames_pending = wl1271_tx_frames_pending, .set_bitrate_mask = wl12xx_set_bitrate_mask, -- cgit From 9fd6f21ba295810e36299981411f62719364d9e9 Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Sun, 4 Mar 2012 10:55:48 +0200 Subject: wl12xx: set authorized AP on sta_state notification wl12xx currently looks for AP authorization by registering a netdev notifier and waiting for the IF_OPER_UP notification, which is quite cumbersome. Use the newly introduced sta_state callback (waiting for assoc -> auth notification) instead, in order to simplify it. Signed-off-by: Eliad Peller Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/main.c | 117 +++++++---------------------------- drivers/net/wireless/wl12xx/wl12xx.h | 3 +- 2 files changed, 23 insertions(+), 97 deletions(-) diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index 8569ac3760df..a330b0c0ae61 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -392,15 +392,15 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl, static void wl1271_op_stop(struct ieee80211_hw *hw); static void wl1271_free_ap_keys(struct wl1271 *wl, struct wl12xx_vif *wlvif); -static DEFINE_MUTEX(wl_list_mutex); -static LIST_HEAD(wl_list); - -static int wl1271_check_operstate(struct wl1271 *wl, struct wl12xx_vif *wlvif, - unsigned char operstate) +static int wl12xx_set_authorized(struct wl1271 *wl, + struct wl12xx_vif *wlvif) { int ret; - if (operstate != IF_OPER_UP) + if (WARN_ON(wlvif->bss_type != BSS_TYPE_STA_BSS)) + return -EINVAL; + + if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags)) return 0; if (test_and_set_bit(WLVIF_FLAG_STA_STATE_SENT, &wlvif->flags)) @@ -415,76 +415,6 @@ static int wl1271_check_operstate(struct wl1271 *wl, struct wl12xx_vif *wlvif, wl1271_info("Association completed."); return 0; } -static int wl1271_dev_notify(struct notifier_block *me, unsigned long what, - void *arg) -{ - struct net_device *dev = arg; - struct wireless_dev *wdev; - struct wiphy *wiphy; - struct ieee80211_hw *hw; - struct wl1271 *wl; - struct wl1271 *wl_temp; - struct wl12xx_vif *wlvif; - int ret = 0; - - /* Check that this notification is for us. */ - if (what != NETDEV_CHANGE) - return NOTIFY_DONE; - - wdev = dev->ieee80211_ptr; - if (wdev == NULL) - return NOTIFY_DONE; - - wiphy = wdev->wiphy; - if (wiphy == NULL) - return NOTIFY_DONE; - - hw = wiphy_priv(wiphy); - if (hw == NULL) - return NOTIFY_DONE; - - wl_temp = hw->priv; - mutex_lock(&wl_list_mutex); - list_for_each_entry(wl, &wl_list, list) { - if (wl == wl_temp) - break; - } - mutex_unlock(&wl_list_mutex); - if (wl != wl_temp) - return NOTIFY_DONE; - - mutex_lock(&wl->mutex); - - if (wl->state == WL1271_STATE_OFF) - goto out; - - if (dev->operstate != IF_OPER_UP) - goto out; - /* - * The correct behavior should be just getting the appropriate wlvif - * from the given dev, but currently we don't have a mac80211 - * interface for it. - */ - wl12xx_for_each_wlvif_sta(wl, wlvif) { - struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif); - - if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags)) - continue; - - ret = wl1271_ps_elp_wakeup(wl); - if (ret < 0) - goto out; - - wl1271_check_operstate(wl, wlvif, - ieee80211_get_operstate(vif)); - - wl1271_ps_elp_sleep(wl); - } -out: - mutex_unlock(&wl->mutex); - - return NOTIFY_OK; -} static int wl1271_reg_notify(struct wiphy *wiphy, struct regulatory_request *request) @@ -1626,10 +1556,6 @@ static struct sk_buff *wl12xx_alloc_dummy_packet(struct wl1271 *wl) } -static struct notifier_block wl1271_dev_notifier = { - .notifier_call = wl1271_dev_notify, -}; - #ifdef CONFIG_PM static int wl1271_configure_suspend_sta(struct wl1271 *wl, struct wl12xx_vif *wlvif) @@ -1856,10 +1782,6 @@ static void wl1271_op_stop(struct ieee80211_hw *hw) wl->state = WL1271_STATE_OFF; mutex_unlock(&wl->mutex); - mutex_lock(&wl_list_mutex); - list_del(&wl->list); - mutex_unlock(&wl_list_mutex); - wl1271_flush_deferred_work(wl); cancel_delayed_work_sync(&wl->scan_complete_work); cancel_work_sync(&wl->netstack_work); @@ -2270,11 +2192,6 @@ out: out_unlock: mutex_unlock(&wl->mutex); - mutex_lock(&wl_list_mutex); - if (!ret) - list_add(&wl->list, &wl_list); - mutex_unlock(&wl_list_mutex); - return ret; } @@ -3967,8 +3884,8 @@ sta_not_found: if (ret < 0) goto out; - wl1271_check_operstate(wl, wlvif, - ieee80211_get_operstate(vif)); + if (test_bit(WLVIF_FLAG_STA_AUTHORIZED, &wlvif->flags)) + wl12xx_set_authorized(wl, wlvif); } /* * stop device role if started (we might already be in @@ -4321,6 +4238,20 @@ static int wl12xx_update_sta_state(struct wl1271 *wl, return ret; } + /* Authorize station */ + if (is_sta && + new_state == IEEE80211_STA_AUTHORIZED) { + set_bit(WLVIF_FLAG_STA_AUTHORIZED, &wlvif->flags); + return wl12xx_set_authorized(wl, wlvif); + } + + if (is_sta && + old_state == IEEE80211_STA_AUTHORIZED && + new_state == IEEE80211_STA_ASSOC) { + clear_bit(WLVIF_FLAG_STA_AUTHORIZED, &wlvif->flags); + return 0; + } + return 0; } @@ -5144,8 +5075,6 @@ static int wl1271_register_hw(struct wl1271 *wl) wl1271_debugfs_init(wl); - register_netdevice_notifier(&wl1271_dev_notifier); - wl1271_notice("loaded"); out: @@ -5157,7 +5086,6 @@ static void wl1271_unregister_hw(struct wl1271 *wl) if (wl->plt) wl1271_plt_stop(wl); - unregister_netdevice_notifier(&wl1271_dev_notifier); ieee80211_unregister_hw(wl->hw); wl->mac80211_registered = false; @@ -5278,7 +5206,6 @@ static struct ieee80211_hw *wl1271_alloc_hw(void) wl = hw->priv; memset(wl, 0, sizeof(*wl)); - INIT_LIST_HEAD(&wl->list); INIT_LIST_HEAD(&wl->wlvif_list); wl->hw = hw; diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/wl12xx/wl12xx.h index 90352415e2aa..b26b1be9a98b 100644 --- a/drivers/net/wireless/wl12xx/wl12xx.h +++ b/drivers/net/wireless/wl12xx/wl12xx.h @@ -265,6 +265,7 @@ enum wl12xx_flags { enum wl12xx_vif_flags { WLVIF_FLAG_INITIALIZED, WLVIF_FLAG_STA_ASSOCIATED, + WLVIF_FLAG_STA_AUTHORIZED, WLVIF_FLAG_IBSS_JOINED, WLVIF_FLAG_AP_STARTED, WLVIF_FLAG_IN_PS, @@ -452,8 +453,6 @@ struct wl1271 { bool enable_11a; - struct list_head list; - /* Most recently reported noise in dBm */ s8 noise; -- cgit From b32b2b0f8ea82cb51d70b88815c25e0f1c0cf7a5 Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Sun, 4 Mar 2012 10:55:49 +0200 Subject: wl12xx: increment session_counter for device role as well The sesssion_counter has to be incremented each time the dev is started (similar to sta role). Signed-off-by: Eliad Peller Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/cmd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/wl12xx/cmd.c b/drivers/net/wireless/wl12xx/cmd.c index ae1f3d7f34d2..1ef212f6440f 100644 --- a/drivers/net/wireless/wl12xx/cmd.c +++ b/drivers/net/wireless/wl12xx/cmd.c @@ -531,7 +531,7 @@ static int wl12xx_cmd_role_start_dev(struct wl1271 *wl, goto out_free; } cmd->device.hlid = wlvif->dev_hlid; - cmd->device.session = wlvif->session_counter; + cmd->device.session = wl12xx_get_new_session_id(wl, wlvif); wl1271_debug(DEBUG_CMD, "role start: roleid=%d, hlid=%d, session=%d", cmd->role_id, cmd->device.hlid, cmd->device.session); -- cgit From 249e9698899643a799951a6e772facae346f0941 Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Sun, 4 Mar 2012 10:55:50 +0200 Subject: wl12xx: set correct vif type in change_interface callback In some cases, the wrong vif type was set in the change_interface callback (P2P_CLIENT/P2P_GO instead of STA/AP) Signed-off-by: Eliad Peller Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index a330b0c0ae61..65f91d7bad31 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -2336,7 +2336,7 @@ static int wl12xx_op_change_interface(struct ieee80211_hw *hw, set_bit(WL1271_FLAG_VIF_CHANGE_IN_PROGRESS, &wl->flags); wl1271_op_remove_interface(hw, vif); - vif->type = ieee80211_iftype_p2p(new_type, p2p); + vif->type = new_type; vif->p2p = p2p; ret = wl1271_op_add_interface(hw, vif); -- cgit From 121af04995d29e3287b849a768789c668d39dce3 Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Sun, 4 Mar 2012 10:55:51 +0200 Subject: wl12xx: don't handle change_channel while associated Currently, CHANGE_CHANNEL indication while associated is considered as roaming attempt. However, with the new auth/assoc redesign, we no longer have to handle this case, so remove it. Signed-off-by: Eliad Peller Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/main.c | 41 +++++++++++++------------------------- 1 file changed, 14 insertions(+), 27 deletions(-) diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index 65f91d7bad31..85bbe7f4f517 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -2515,35 +2515,22 @@ static int wl12xx_config_vif(struct wl1271 *wl, struct wl12xx_vif *wlvif, wl1271_warning("rate policy for channel " "failed %d", ret); - if (test_bit(WLVIF_FLAG_STA_ASSOCIATED, - &wlvif->flags)) { - if (wl12xx_dev_role_started(wlvif)) { - /* roaming */ - ret = wl12xx_croc(wl, - wlvif->dev_role_id); - if (ret < 0) - return ret; - } - ret = wl1271_join(wl, wlvif, false); + /* + * change the ROC channel. do it only if we are + * not idle. otherwise, CROC will be called + * anyway. + */ + if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED, + &wlvif->flags) && + wl12xx_dev_role_started(wlvif) && + !(conf->flags & IEEE80211_CONF_IDLE)) { + ret = wl12xx_stop_dev(wl, wlvif); if (ret < 0) - wl1271_warning("cmd join on channel " - "failed %d", ret); - } else { - /* - * change the ROC channel. do it only if we are - * not idle. otherwise, CROC will be called - * anyway. - */ - if (wl12xx_dev_role_started(wlvif) && - !(conf->flags & IEEE80211_CONF_IDLE)) { - ret = wl12xx_stop_dev(wl, wlvif); - if (ret < 0) - return ret; + return ret; - ret = wl12xx_start_dev(wl, wlvif); - if (ret < 0) - return ret; - } + ret = wl12xx_start_dev(wl, wlvif); + if (ret < 0) + return ret; } } } -- cgit From 97fd311a2615d8f35e796b11a14b6cf3d335d423 Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Sun, 4 Mar 2012 10:55:52 +0200 Subject: wl12xx: don't allow scanning while device is in ROC return EBUSY on scan when there is any role in ROC (not necessarily the one we are going to use) Signed-off-by: Eliad Peller Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/main.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index 85bbe7f4f517..1d5f2d5614fb 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -3057,8 +3057,6 @@ static int wl1271_op_hw_scan(struct ieee80211_hw *hw, struct cfg80211_scan_request *req) { struct wl1271 *wl = hw->priv; - struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif); - int ret; u8 *ssid = NULL; size_t len = 0; @@ -3086,8 +3084,8 @@ static int wl1271_op_hw_scan(struct ieee80211_hw *hw, if (ret < 0) goto out; - if (test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags) && - test_bit(wlvif->role_id, wl->roc_map)) { + /* fail if there is any role in ROC */ + if (find_first_bit(wl->roc_map, WL12XX_MAX_ROLES) < WL12XX_MAX_ROLES) { /* don't allow scanning right now */ ret = -EBUSY; goto out_sleep; -- cgit From 6667776d3cf32dd3809a18917c2b7adb8ef12aa2 Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Sun, 4 Mar 2012 10:55:53 +0200 Subject: wl12xx: configure the correct beacon_interval We didn't update the beacon interval on association (or on a change notification when working as sta), so the default interval (100ms) was always used. Update the beacon interval according to the bss_conf before starting the sta role (on association). Signed-off-by: Eliad Peller Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index 1d5f2d5614fb..89bf9eadc840 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -3723,6 +3723,7 @@ sta_not_found: u32 rates; int ieoffset; wlvif->aid = bss_conf->aid; + wlvif->beacon_int = bss_conf->beacon_int; set_assoc = true; /* -- cgit From e9ba7152c1f5babd6ad9ad45619e0a10b4c08554 Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Sun, 4 Mar 2012 10:55:54 +0200 Subject: wl12xx: avoid bug_on_recovery during fw switch Add a flag to indicate we initiated a recovery work on purpose, in order to avoid triggering BUG() (when the bug_on_recovery module param was set). Signed-off-by: Eliad Peller Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/main.c | 5 ++++- drivers/net/wireless/wl12xx/wl12xx.h | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index 89bf9eadc840..3c966f2e00d0 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -1154,7 +1154,8 @@ static void wl1271_recovery_work(struct work_struct *work) wl1271_info("Hardware recovery in progress. FW ver: %s pc: 0x%x", wl->chip.fw_ver_str, wl1271_read32(wl, SCR_PAD4)); - BUG_ON(bug_on_recovery); + BUG_ON(bug_on_recovery && + !test_bit(WL1271_FLAG_INTENDED_FW_RECOVERY, &wl->flags)); /* * Advance security sequence number to overcome potential progress @@ -2133,6 +2134,7 @@ static int wl1271_op_add_interface(struct ieee80211_hw *hw, if (wl12xx_need_fw_change(wl, vif_count, true)) { wl12xx_force_active_psm(wl); + set_bit(WL1271_FLAG_INTENDED_FW_RECOVERY, &wl->flags); mutex_unlock(&wl->mutex); wl1271_recovery_work(&wl->recovery_work); return 0; @@ -2317,6 +2319,7 @@ static void wl1271_op_remove_interface(struct ieee80211_hw *hw, WARN_ON(iter != wlvif); if (wl12xx_need_fw_change(wl, vif_count, false)) { wl12xx_force_active_psm(wl); + set_bit(WL1271_FLAG_INTENDED_FW_RECOVERY, &wl->flags); wl12xx_queue_recovery_work(wl); cancel_recovery = false; } diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/wl12xx/wl12xx.h index b26b1be9a98b..6e13a3073e9f 100644 --- a/drivers/net/wireless/wl12xx/wl12xx.h +++ b/drivers/net/wireless/wl12xx/wl12xx.h @@ -260,6 +260,7 @@ enum wl12xx_flags { WL1271_FLAG_SOFT_GEMINI, WL1271_FLAG_RECOVERY_IN_PROGRESS, WL1271_FLAG_VIF_CHANGE_IN_PROGRESS, + WL1271_FLAG_INTENDED_FW_RECOVERY, }; enum wl12xx_vif_flags { -- cgit From 8ccd16e6cb17a1e961617cc67798bbb222e4cd13 Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Sun, 4 Mar 2012 10:55:55 +0200 Subject: wl12xx: print the tx packet len Add the packet length to the tx debug print. Signed-off-by: Eliad Peller Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index 3c966f2e00d0..95a76a5f9eeb 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -1459,7 +1459,8 @@ static void wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) goto out; } - wl1271_debug(DEBUG_TX, "queue skb hlid %d q %d", hlid, q); + wl1271_debug(DEBUG_TX, "queue skb hlid %d q %d len %d", + hlid, q, skb->len); skb_queue_tail(&wl->links[hlid].tx_queue[q], skb); wl->tx_queue_count[q]++; -- cgit From a0f6d6caef4033aa9c3e2ea2ceae256c4347a419 Mon Sep 17 00:00:00 2001 From: Amitkumar Karwar Date: Fri, 24 Feb 2012 21:36:05 -0800 Subject: mwifiex: handle auto authentication mode correctly When authentication type is configured to NL80211_AUTHTYPE_AUTOMATIC, driver tries to connect using open mode. The association is failed if AP is configured in shared mode. This patch adds code to try association using shared mode as well if open mode association fails. Now since we returned exact error code in association response handler (instead of -1), corresponding changes are done in mwifiex_process_cmdresp(). Signed-off-by: Amitkumar Karwar Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/cfg80211.c | 10 ++++++---- drivers/net/wireless/mwifiex/cmdevt.c | 8 +++----- drivers/net/wireless/mwifiex/join.c | 2 +- drivers/net/wireless/mwifiex/main.h | 1 + drivers/net/wireless/mwifiex/sta_ioctl.c | 11 +++++++++++ 5 files changed, 22 insertions(+), 10 deletions(-) diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index a460fb0cc503..6a81101bab44 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c @@ -873,6 +873,7 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid, priv->sec_info.wpa2_enabled = false; priv->wep_key_curr_index = 0; priv->sec_info.encryption_mode = 0; + priv->sec_info.is_authtype_auto = 0; ret = mwifiex_set_encode(priv, NULL, 0, 0, 1); if (mode == NL80211_IFTYPE_ADHOC) { @@ -894,11 +895,12 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid, } /* Now handle infra mode. "sme" is valid for infra mode only */ - if (sme->auth_type == NL80211_AUTHTYPE_AUTOMATIC - || sme->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM) + if (sme->auth_type == NL80211_AUTHTYPE_AUTOMATIC) { auth_type = NL80211_AUTHTYPE_OPEN_SYSTEM; - else if (sme->auth_type == NL80211_AUTHTYPE_SHARED_KEY) - auth_type = NL80211_AUTHTYPE_SHARED_KEY; + priv->sec_info.is_authtype_auto = 1; + } else { + auth_type = sme->auth_type; + } if (sme->crypto.n_ciphers_pairwise) { priv->sec_info.encryption_mode = diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c index 6623db69e157..c82eb7ff2fa2 100644 --- a/drivers/net/wireless/mwifiex/cmdevt.c +++ b/drivers/net/wireless/mwifiex/cmdevt.c @@ -771,7 +771,7 @@ int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter) /* Check init command response */ if (adapter->hw_status == MWIFIEX_HW_STATUS_INITIALIZING) { - if (ret == -1) { + if (ret) { dev_err(adapter->dev, "%s: cmd %#x failed during " "initialization\n", __func__, cmdresp_no); mwifiex_init_fw_complete(adapter); @@ -781,10 +781,8 @@ int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter) } if (adapter->curr_cmd) { - if (adapter->curr_cmd->wait_q_enabled && (!ret)) - adapter->cmd_wait_q.status = 0; - else if (adapter->curr_cmd->wait_q_enabled && (ret == -1)) - adapter->cmd_wait_q.status = -1; + if (adapter->curr_cmd->wait_q_enabled) + adapter->cmd_wait_q.status = ret; /* Clean up and put current command back to cmd_free_q */ mwifiex_insert_cmd_to_free_q(adapter, adapter->curr_cmd); diff --git a/drivers/net/wireless/mwifiex/join.c b/drivers/net/wireless/mwifiex/join.c index ee439fc2f4f3..5c95e4839004 100644 --- a/drivers/net/wireless/mwifiex/join.c +++ b/drivers/net/wireless/mwifiex/join.c @@ -585,7 +585,7 @@ int mwifiex_ret_802_11_associate(struct mwifiex_private *priv, le16_to_cpu(assoc_rsp->cap_info_bitmap), le16_to_cpu(assoc_rsp->a_id)); - ret = -1; + ret = le16_to_cpu(assoc_rsp->status_code); goto done; } diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h index 4c8621706278..dddb5563398a 100644 --- a/drivers/net/wireless/mwifiex/main.h +++ b/drivers/net/wireless/mwifiex/main.h @@ -219,6 +219,7 @@ struct mwifiex_802_11_security { u8 wapi_key_on; u8 wep_enabled; u32 authentication_mode; + u8 is_authtype_auto; u32 encryption_mode; }; diff --git a/drivers/net/wireless/mwifiex/sta_ioctl.c b/drivers/net/wireless/mwifiex/sta_ioctl.c index 866026ecca44..e10161f5894c 100644 --- a/drivers/net/wireless/mwifiex/sta_ioctl.c +++ b/drivers/net/wireless/mwifiex/sta_ioctl.c @@ -249,6 +249,17 @@ int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss, * application retrieval */ priv->assoc_rsp_size = 0; ret = mwifiex_associate(priv, bss_desc); + + /* If auth type is auto and association fails using open mode, + * try to connect using shared mode */ + if (ret == WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG && + priv->sec_info.is_authtype_auto && + priv->sec_info.wep_enabled) { + priv->sec_info.authentication_mode = + NL80211_AUTHTYPE_SHARED_KEY; + ret = mwifiex_associate(priv, bss_desc); + } + if (bss) cfg80211_put_bss(bss); } else { -- cgit From d6157bf78015e53371e806e0f8fd44ef6a1bfc5d Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Mon, 27 Feb 2012 19:58:39 +0100 Subject: Revert "ath9k_hw: Fix false tx hung detection in AR9003 chips" The approach of this change is flawed, as it triggers tx status processing from more callsites, yet the chips only have one global tx status queue. Subsequent patches will properly fix the issue that this one tried to address. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_mac.c | 8 ++------ drivers/net/wireless/ath/ath9k/beacon.c | 6 ------ 2 files changed, 2 insertions(+), 12 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.c b/drivers/net/wireless/ath/ath9k/ar9003_mac.c index 8d1bca03bc0e..01d5c1a4d746 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c @@ -326,7 +326,6 @@ static bool ar9003_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked) static int ar9003_hw_proc_txdesc(struct ath_hw *ah, void *ds, struct ath_tx_status *ts) { - struct ar9003_txc *txc = (struct ar9003_txc *) ds; struct ar9003_txs *ads; u32 status; @@ -336,11 +335,7 @@ static int ar9003_hw_proc_txdesc(struct ath_hw *ah, void *ds, if ((status & AR_TxDone) == 0) return -EINPROGRESS; - ts->qid = MS(ads->ds_info, AR_TxQcuNum); - if (!txc || (MS(txc->info, AR_TxQcuNum) == ts->qid)) - ah->ts_tail = (ah->ts_tail + 1) % ah->ts_size; - else - return -ENOENT; + ah->ts_tail = (ah->ts_tail + 1) % ah->ts_size; if ((MS(ads->ds_info, AR_DescId) != ATHEROS_VENDOR_ID) || (MS(ads->ds_info, AR_TxRxDesc) != 1)) { @@ -354,6 +349,7 @@ static int ar9003_hw_proc_txdesc(struct ath_hw *ah, void *ds, ts->ts_seqnum = MS(status, AR_SeqNum); ts->tid = MS(status, AR_TxTid); + ts->qid = MS(ads->ds_info, AR_TxQcuNum); ts->desc_id = MS(ads->status1, AR_TxDescId); ts->ts_tstamp = ads->status4; ts->ts_status = 0; diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c index b8967e482e6e..6d1e46577db0 100644 --- a/drivers/net/wireless/ath/ath9k/beacon.c +++ b/drivers/net/wireless/ath/ath9k/beacon.c @@ -355,7 +355,6 @@ void ath_beacon_tasklet(unsigned long data) struct ath_common *common = ath9k_hw_common(ah); struct ath_buf *bf = NULL; struct ieee80211_vif *vif; - struct ath_tx_status ts; bool edma = !!(ah->caps.hw_caps & ATH9K_HW_CAP_EDMA); int slot; u32 bfaddr, bc = 0; @@ -462,11 +461,6 @@ void ath_beacon_tasklet(unsigned long data) ath9k_hw_txstart(ah, sc->beacon.beaconq); sc->beacon.ast_be_xmit += bc; /* XXX per-vif? */ - if (edma) { - spin_lock_bh(&sc->sc_pcu_lock); - ath9k_hw_txprocdesc(ah, bf->bf_desc, (void *)&ts); - spin_unlock_bh(&sc->sc_pcu_lock); - } } } -- cgit From 4286df60edfe19d3407fa112bf4bdfeeadda897c Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Mon, 27 Feb 2012 19:58:40 +0100 Subject: ath9k: do not call ath9k_hw_txprocdesc on AR9003 outside of the tx tasklet Since AR9003 uses a global tx status queue, processing tx status outside of the regular tx tasklet is dangerous and messes up hardware/software synchronization of tx status events. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 02e95c8e7465..cc2535c38bed 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -2300,6 +2300,7 @@ static int ath9k_tx_last_beacon(struct ieee80211_hw *hw) struct ath_vif *avp; struct ath_buf *bf; struct ath_tx_status ts; + bool edma = !!(ah->caps.hw_caps & ATH9K_HW_CAP_EDMA); int status; vif = sc->beacon.bslot[0]; @@ -2310,7 +2311,7 @@ static int ath9k_tx_last_beacon(struct ieee80211_hw *hw) if (!avp->is_bslot_active) return 0; - if (!sc->beacon.tx_processed) { + if (!sc->beacon.tx_processed && !edma) { tasklet_disable(&sc->bcon_tasklet); bf = avp->av_bcbuf; -- cgit From 627e67a656bbb1d616c1ca2d056138a164111a52 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Mon, 27 Feb 2012 19:58:41 +0100 Subject: ath9k_hw: enable interrupts for beacon tx completion events Not doing so could cause the tx status queue to overflow during longer periods of time without non-beacon tx. These events are also required for proper drv_tx_last_beacon handling. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/mac.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c index e196aba77acf..5f4ae6c9a93c 100644 --- a/drivers/net/wireless/ath/ath9k/mac.c +++ b/drivers/net/wireless/ath/ath9k/mac.c @@ -745,7 +745,11 @@ int ath9k_hw_beaconq_setup(struct ath_hw *ah) qi.tqi_aifs = 1; qi.tqi_cwmin = 0; qi.tqi_cwmax = 0; - /* NB: don't enable any interrupts */ + + if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) + qi.tqi_qflags = TXQ_FLAG_TXOKINT_ENABLE | + TXQ_FLAG_TXERRINT_ENABLE; + return ath9k_hw_setuptxqueue(ah, ATH9K_TX_QUEUE_BEACON, &qi); } EXPORT_SYMBOL(ath9k_hw_beaconq_setup); -- cgit From 4e0ad2591adde7bec878a4b37a073427aec3e19c Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Mon, 27 Feb 2012 19:58:42 +0100 Subject: ath9k: fix drv_tx_last_beacon on AR9003 by processing beacon tx status Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/beacon.c | 2 +- drivers/net/wireless/ath/ath9k/xmit.c | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c index 6d1e46577db0..43882f9e25c4 100644 --- a/drivers/net/wireless/ath/ath9k/beacon.c +++ b/drivers/net/wireless/ath/ath9k/beacon.c @@ -91,7 +91,7 @@ static void ath_beacon_setup(struct ath_softc *sc, struct ath_vif *avp, info.txpower = MAX_RATE_POWER; info.keyix = ATH9K_TXKEYIX_INVALID; info.keytype = ATH9K_KEY_TYPE_CLEAR; - info.flags = ATH9K_TXDESC_NOACK; + info.flags = ATH9K_TXDESC_NOACK | ATH9K_TXDESC_INTREQ; info.buf_addr[0] = bf->bf_buf_addr; info.buf_len[0] = roundup(skb->len, 4); diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 5dd27d2712fc..9f785015a7dc 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -2296,9 +2296,12 @@ void ath_tx_edma_tasklet(struct ath_softc *sc) break; } - /* Skip beacon completions */ - if (ts.qid == sc->beacon.beaconq) + /* Process beacon completions separately */ + if (ts.qid == sc->beacon.beaconq) { + sc->beacon.tx_processed = true; + sc->beacon.tx_last = !(ts.ts_status & ATH9K_TXERR_MASK); continue; + } txq = &sc->tx.txq[ts.qid]; -- cgit From edd8d90b624e97105d26615d1655da22a3605fff Mon Sep 17 00:00:00 2001 From: Hauke Mehrtens Date: Tue, 28 Feb 2012 00:56:04 +0100 Subject: ssb: sprom fix some sizes / signedness Some parts of the sprom struct are bigger than needed. The leddc and maxpwr values are just 8 bit long and not 16. rxpo2g and rxpo5g are signed I got these information for the open source part of the Broadcom SDK covering sprom version 1 to 9. rxpo2g contained a negative number on my bcm5354 based device, this cased an error and Broadcom SDK says this is signed. Signed-off-by: Hauke Mehrtens Signed-off-by: John W. Linville --- include/linux/ssb/ssb.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/include/linux/ssb/ssb.h b/include/linux/ssb/ssb.h index bbc2612cb64a..f1696213e3b5 100644 --- a/include/linux/ssb/ssb.h +++ b/include/linux/ssb/ssb.h @@ -33,8 +33,8 @@ struct ssb_sprom { u8 et1mdcport; /* MDIO for enet1 */ u16 board_rev; /* Board revision number from SPROM. */ u8 country_code; /* Country Code */ - u16 leddc_on_time; /* LED Powersave Duty Cycle On Count */ - u16 leddc_off_time; /* LED Powersave Duty Cycle Off Count */ + u8 leddc_on_time; /* LED Powersave Duty Cycle On Count */ + u8 leddc_off_time; /* LED Powersave Duty Cycle Off Count */ u8 ant_available_a; /* 2GHz antenna available bits (up to 4) */ u8 ant_available_bg; /* 5GHz antenna available bits (up to 4) */ u16 pa0b0; @@ -53,10 +53,10 @@ struct ssb_sprom { u8 gpio1; /* GPIO pin 1 */ u8 gpio2; /* GPIO pin 2 */ u8 gpio3; /* GPIO pin 3 */ - u16 maxpwr_bg; /* 2.4GHz Amplifier Max Power (in dBm Q5.2) */ - u16 maxpwr_al; /* 5.2GHz Amplifier Max Power (in dBm Q5.2) */ - u16 maxpwr_a; /* 5.3GHz Amplifier Max Power (in dBm Q5.2) */ - u16 maxpwr_ah; /* 5.8GHz Amplifier Max Power (in dBm Q5.2) */ + u8 maxpwr_bg; /* 2.4GHz Amplifier Max Power (in dBm Q5.2) */ + u8 maxpwr_al; /* 5.2GHz Amplifier Max Power (in dBm Q5.2) */ + u8 maxpwr_a; /* 5.3GHz Amplifier Max Power (in dBm Q5.2) */ + u8 maxpwr_ah; /* 5.8GHz Amplifier Max Power (in dBm Q5.2) */ u8 itssi_a; /* Idle TSSI Target for A-PHY */ u8 itssi_bg; /* Idle TSSI Target for B/G-PHY */ u8 tri2g; /* 2.4GHz TX isolation */ @@ -67,8 +67,8 @@ struct ssb_sprom { u8 txpid5gl[4]; /* 4.9 - 5.1GHz TX power index */ u8 txpid5g[4]; /* 5.1 - 5.5GHz TX power index */ u8 txpid5gh[4]; /* 5.5 - ...GHz TX power index */ - u8 rxpo2g; /* 2GHz RX power offset */ - u8 rxpo5g; /* 5GHz RX power offset */ + s8 rxpo2g; /* 2GHz RX power offset */ + s8 rxpo5g; /* 5GHz RX power offset */ u8 rssisav2g; /* 2GHz RSSI params */ u8 rssismc2g; u8 rssismf2g; -- cgit From f8f8a660ba501ad14617ccd0d91a1ed8ce54d6d0 Mon Sep 17 00:00:00 2001 From: Hauke Mehrtens Date: Tue, 28 Feb 2012 00:56:05 +0100 Subject: ssb: remove 5GHz antenna gain from sprom There is no 2.4 GHz or 5GHz antenna gain stored in sprom. The sprom just stores the gain values for antenna 1 and 2 or 1 to 4 for more recent sprom versions. On old devices antenna 2 was used for 5 GHz wifi. Signed-off-by: Hauke Mehrtens Signed-off-by: John W. Linville --- drivers/net/wireless/b43legacy/phy.c | 2 +- drivers/ssb/pci.c | 41 ++++++++++++------------------------ drivers/ssb/pcmcia.c | 12 ++++------- drivers/ssb/sdio.c | 12 ++++------- include/linux/ssb/ssb.h | 7 +----- 5 files changed, 24 insertions(+), 50 deletions(-) diff --git a/drivers/net/wireless/b43legacy/phy.c b/drivers/net/wireless/b43legacy/phy.c index 96faaef3661b..950334197f40 100644 --- a/drivers/net/wireless/b43legacy/phy.c +++ b/drivers/net/wireless/b43legacy/phy.c @@ -1860,7 +1860,7 @@ void b43legacy_phy_xmitpower(struct b43legacy_wldev *dev) * which accounts for the factor of 4 */ #define REG_MAX_PWR 20 max_pwr = min(REG_MAX_PWR * 4 - - dev->dev->bus->sprom.antenna_gain.ghz24.a0 + - dev->dev->bus->sprom.antenna_gain.a0 - 0x6, max_pwr); /* find the desired power in Q5.2 - power_level is in dBm diff --git a/drivers/ssb/pci.c b/drivers/ssb/pci.c index befa89eac6f3..ed4124469a3a 100644 --- a/drivers/ssb/pci.c +++ b/drivers/ssb/pci.c @@ -331,7 +331,6 @@ static void sprom_extract_r123(struct ssb_sprom *out, const u16 *in) { int i; u16 v; - s8 gain; u16 loc[3]; if (out->revision == 3) /* rev 3 moved MAC */ @@ -390,20 +389,12 @@ static void sprom_extract_r123(struct ssb_sprom *out, const u16 *in) SPEX(boardflags_hi, SSB_SPROM2_BFLHI, 0xFFFF, 0); /* Extract the antenna gain values. */ - gain = r123_extract_antgain(out->revision, in, - SSB_SPROM1_AGAIN_BG, - SSB_SPROM1_AGAIN_BG_SHIFT); - out->antenna_gain.ghz24.a0 = gain; - out->antenna_gain.ghz24.a1 = gain; - out->antenna_gain.ghz24.a2 = gain; - out->antenna_gain.ghz24.a3 = gain; - gain = r123_extract_antgain(out->revision, in, - SSB_SPROM1_AGAIN_A, - SSB_SPROM1_AGAIN_A_SHIFT); - out->antenna_gain.ghz5.a0 = gain; - out->antenna_gain.ghz5.a1 = gain; - out->antenna_gain.ghz5.a2 = gain; - out->antenna_gain.ghz5.a3 = gain; + out->antenna_gain.a0 = r123_extract_antgain(out->revision, in, + SSB_SPROM1_AGAIN_BG, + SSB_SPROM1_AGAIN_BG_SHIFT); + out->antenna_gain.a1 = r123_extract_antgain(out->revision, in, + SSB_SPROM1_AGAIN_A, + SSB_SPROM1_AGAIN_A_SHIFT); } /* Revs 4 5 and 8 have partially shared layout */ @@ -504,16 +495,14 @@ static void sprom_extract_r45(struct ssb_sprom *out, const u16 *in) } /* Extract the antenna gain values. */ - SPEX(antenna_gain.ghz24.a0, SSB_SPROM4_AGAIN01, + SPEX(antenna_gain.a0, SSB_SPROM4_AGAIN01, SSB_SPROM4_AGAIN0, SSB_SPROM4_AGAIN0_SHIFT); - SPEX(antenna_gain.ghz24.a1, SSB_SPROM4_AGAIN01, + SPEX(antenna_gain.a1, SSB_SPROM4_AGAIN01, SSB_SPROM4_AGAIN1, SSB_SPROM4_AGAIN1_SHIFT); - SPEX(antenna_gain.ghz24.a2, SSB_SPROM4_AGAIN23, + SPEX(antenna_gain.a2, SSB_SPROM4_AGAIN23, SSB_SPROM4_AGAIN2, SSB_SPROM4_AGAIN2_SHIFT); - SPEX(antenna_gain.ghz24.a3, SSB_SPROM4_AGAIN23, + SPEX(antenna_gain.a3, SSB_SPROM4_AGAIN23, SSB_SPROM4_AGAIN3, SSB_SPROM4_AGAIN3_SHIFT); - memcpy(&out->antenna_gain.ghz5, &out->antenna_gain.ghz24, - sizeof(out->antenna_gain.ghz5)); sprom_extract_r458(out, in); @@ -602,16 +591,14 @@ static void sprom_extract_r8(struct ssb_sprom *out, const u16 *in) SPEX32(ofdm5ghpo, SSB_SPROM8_OFDM5GHPO, 0xFFFFFFFF, 0); /* Extract the antenna gain values. */ - SPEX(antenna_gain.ghz24.a0, SSB_SPROM8_AGAIN01, + SPEX(antenna_gain.a0, SSB_SPROM8_AGAIN01, SSB_SPROM8_AGAIN0, SSB_SPROM8_AGAIN0_SHIFT); - SPEX(antenna_gain.ghz24.a1, SSB_SPROM8_AGAIN01, + SPEX(antenna_gain.a1, SSB_SPROM8_AGAIN01, SSB_SPROM8_AGAIN1, SSB_SPROM8_AGAIN1_SHIFT); - SPEX(antenna_gain.ghz24.a2, SSB_SPROM8_AGAIN23, + SPEX(antenna_gain.a2, SSB_SPROM8_AGAIN23, SSB_SPROM8_AGAIN2, SSB_SPROM8_AGAIN2_SHIFT); - SPEX(antenna_gain.ghz24.a3, SSB_SPROM8_AGAIN23, + SPEX(antenna_gain.a3, SSB_SPROM8_AGAIN23, SSB_SPROM8_AGAIN3, SSB_SPROM8_AGAIN3_SHIFT); - memcpy(&out->antenna_gain.ghz5, &out->antenna_gain.ghz24, - sizeof(out->antenna_gain.ghz5)); /* Extract cores power info info */ for (i = 0; i < ARRAY_SIZE(pwr_info_offset); i++) { diff --git a/drivers/ssb/pcmcia.c b/drivers/ssb/pcmcia.c index c821c6b2a6a0..fbafed5b729b 100644 --- a/drivers/ssb/pcmcia.c +++ b/drivers/ssb/pcmcia.c @@ -676,14 +676,10 @@ static int ssb_pcmcia_do_get_invariants(struct pcmcia_device *p_dev, case SSB_PCMCIA_CIS_ANTGAIN: GOTO_ERROR_ON(tuple->TupleDataLen != 2, "antg tpl size"); - sprom->antenna_gain.ghz24.a0 = tuple->TupleData[1]; - sprom->antenna_gain.ghz24.a1 = tuple->TupleData[1]; - sprom->antenna_gain.ghz24.a2 = tuple->TupleData[1]; - sprom->antenna_gain.ghz24.a3 = tuple->TupleData[1]; - sprom->antenna_gain.ghz5.a0 = tuple->TupleData[1]; - sprom->antenna_gain.ghz5.a1 = tuple->TupleData[1]; - sprom->antenna_gain.ghz5.a2 = tuple->TupleData[1]; - sprom->antenna_gain.ghz5.a3 = tuple->TupleData[1]; + sprom->antenna_gain.a0 = tuple->TupleData[1]; + sprom->antenna_gain.a1 = tuple->TupleData[1]; + sprom->antenna_gain.a2 = tuple->TupleData[1]; + sprom->antenna_gain.a3 = tuple->TupleData[1]; break; case SSB_PCMCIA_CIS_BFLAGS: GOTO_ERROR_ON((tuple->TupleDataLen != 3) && diff --git a/drivers/ssb/sdio.c b/drivers/ssb/sdio.c index 63fd709038ca..b2d36f7736c5 100644 --- a/drivers/ssb/sdio.c +++ b/drivers/ssb/sdio.c @@ -551,14 +551,10 @@ int ssb_sdio_get_invariants(struct ssb_bus *bus, case SSB_SDIO_CIS_ANTGAIN: GOTO_ERROR_ON(tuple->size != 2, "antg tpl size"); - sprom->antenna_gain.ghz24.a0 = tuple->data[1]; - sprom->antenna_gain.ghz24.a1 = tuple->data[1]; - sprom->antenna_gain.ghz24.a2 = tuple->data[1]; - sprom->antenna_gain.ghz24.a3 = tuple->data[1]; - sprom->antenna_gain.ghz5.a0 = tuple->data[1]; - sprom->antenna_gain.ghz5.a1 = tuple->data[1]; - sprom->antenna_gain.ghz5.a2 = tuple->data[1]; - sprom->antenna_gain.ghz5.a3 = tuple->data[1]; + sprom->antenna_gain.a0 = tuple->data[1]; + sprom->antenna_gain.a1 = tuple->data[1]; + sprom->antenna_gain.a2 = tuple->data[1]; + sprom->antenna_gain.a3 = tuple->data[1]; break; case SSB_SDIO_CIS_BFLAGS: GOTO_ERROR_ON((tuple->size != 3) && diff --git a/include/linux/ssb/ssb.h b/include/linux/ssb/ssb.h index f1696213e3b5..1de56757e949 100644 --- a/include/linux/ssb/ssb.h +++ b/include/linux/ssb/ssb.h @@ -94,12 +94,7 @@ struct ssb_sprom { * on each band. Values in dBm/4 (Q5.2). Negative gain means the * loss in the connectors is bigger than the gain. */ struct { - struct { - s8 a0, a1, a2, a3; - } ghz24; /* 2.4GHz band */ - struct { - s8 a0, a1, a2, a3; - } ghz5; /* 5GHz band */ + s8 a0, a1, a2, a3; } antenna_gain; struct { -- cgit From 3b64e6f9050ff87a746c8e07dc04d97c7f26c5e2 Mon Sep 17 00:00:00 2001 From: Hauke Mehrtens Date: Tue, 28 Feb 2012 00:56:06 +0100 Subject: ssb: fix per path sprom vars On sprom version 4 and 5 there are 4 values for pa_2g, pa_5gl, pa_5g and pa_5gh, for sprom version 8 and 9 there are only 3. Make the per path sprom store also work for older sprom versions. Signed-off-by: Hauke Mehrtens Signed-off-by: John W. Linville --- include/linux/ssb/ssb.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/ssb/ssb.h b/include/linux/ssb/ssb.h index 1de56757e949..49284192521b 100644 --- a/include/linux/ssb/ssb.h +++ b/include/linux/ssb/ssb.h @@ -19,7 +19,7 @@ struct ssb_driver; struct ssb_sprom_core_pwr_info { u8 itssi_2g, itssi_5g; u8 maxpwr_2g, maxpwr_5gl, maxpwr_5g, maxpwr_5gh; - u16 pa_2g[3], pa_5gl[3], pa_5g[3], pa_5gh[3]; + u16 pa_2g[4], pa_5gl[4], pa_5g[4], pa_5gh[4]; }; struct ssb_sprom { -- cgit From 03a5642b6a578d8de355b77efff49bbc45b8be6d Mon Sep 17 00:00:00 2001 From: Hauke Mehrtens Date: Tue, 28 Feb 2012 00:56:07 +0100 Subject: ssb: add alpha2 This member contains the country code encoded with two chars Signed-off-by: Hauke Mehrtens Signed-off-by: John W. Linville --- include/linux/ssb/ssb.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/linux/ssb/ssb.h b/include/linux/ssb/ssb.h index 49284192521b..d658de45ffb9 100644 --- a/include/linux/ssb/ssb.h +++ b/include/linux/ssb/ssb.h @@ -33,6 +33,7 @@ struct ssb_sprom { u8 et1mdcport; /* MDIO for enet1 */ u16 board_rev; /* Board revision number from SPROM. */ u8 country_code; /* Country Code */ + char alpha2[2]; /* Country Code as two chars like EU or US */ u8 leddc_on_time; /* LED Powersave Duty Cycle On Count */ u8 leddc_off_time; /* LED Powersave Duty Cycle Off Count */ u8 ant_available_a; /* 2GHz antenna available bits (up to 4) */ -- cgit From 52aa63f5322aab23e07a52ff8ddd246d34799eb5 Mon Sep 17 00:00:00 2001 From: Hauke Mehrtens Date: Tue, 28 Feb 2012 00:56:08 +0100 Subject: ssb: add some missing sprom attributes This patch extends the sprom struct to contain all sprom attributes found in sprom version 1 to 9. This was done accordingly to the open source part of the Broadcom SDK. Signed-off-by: Hauke Mehrtens Signed-off-by: John W. Linville --- include/linux/ssb/ssb.h | 76 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 75 insertions(+), 1 deletion(-) diff --git a/include/linux/ssb/ssb.h b/include/linux/ssb/ssb.h index d658de45ffb9..d27683180025 100644 --- a/include/linux/ssb/ssb.h +++ b/include/linux/ssb/ssb.h @@ -32,6 +32,8 @@ struct ssb_sprom { u8 et0mdcport; /* MDIO for enet0 */ u8 et1mdcport; /* MDIO for enet1 */ u16 board_rev; /* Board revision number from SPROM. */ + u16 board_num; /* Board number from SPROM. */ + u16 board_type; /* Board type from SPROM. */ u8 country_code; /* Country Code */ char alpha2[2]; /* Country Code as two chars like EU or US */ u8 leddc_on_time; /* LED Powersave Duty Cycle On Count */ @@ -107,7 +109,79 @@ struct ssb_sprom { } ghz5; } fem; - /* TODO - add any parameters needed from rev 2, 3, 4, 5 or 8 SPROMs */ + u16 mcs2gpo[8]; + u16 mcs5gpo[8]; + u16 mcs5glpo[8]; + u16 mcs5ghpo[8]; + u8 opo; + + u8 rxgainerr2ga[3]; + u8 rxgainerr5gla[3]; + u8 rxgainerr5gma[3]; + u8 rxgainerr5gha[3]; + u8 rxgainerr5gua[3]; + + u8 noiselvl2ga[3]; + u8 noiselvl5gla[3]; + u8 noiselvl5gma[3]; + u8 noiselvl5gha[3]; + u8 noiselvl5gua[3]; + + u8 regrev; + u8 txchain; + u8 rxchain; + u8 antswitch; + u16 cddpo; + u16 stbcpo; + u16 bw40po; + u16 bwduppo; + + u8 tempthresh; + u8 tempoffset; + u16 rawtempsense; + u8 measpower; + u8 tempsense_slope; + u8 tempcorrx; + u8 tempsense_option; + u8 freqoffset_corr; + u8 iqcal_swp_dis; + u8 hw_iqcal_en; + u8 elna2g; + u8 elna5g; + u8 phycal_tempdelta; + u8 temps_period; + u8 temps_hysteresis; + u8 measpower1; + u8 measpower2; + u8 pcieingress_war; + + /* power per rate from sromrev 9 */ + u16 cckbw202gpo; + u16 cckbw20ul2gpo; + u32 legofdmbw202gpo; + u32 legofdmbw20ul2gpo; + u32 legofdmbw205glpo; + u32 legofdmbw20ul5glpo; + u32 legofdmbw205gmpo; + u32 legofdmbw20ul5gmpo; + u32 legofdmbw205ghpo; + u32 legofdmbw20ul5ghpo; + u32 mcsbw202gpo; + u32 mcsbw20ul2gpo; + u32 mcsbw402gpo; + u32 mcsbw205glpo; + u32 mcsbw20ul5glpo; + u32 mcsbw405glpo; + u32 mcsbw205gmpo; + u32 mcsbw20ul5gmpo; + u32 mcsbw405gmpo; + u32 mcsbw205ghpo; + u32 mcsbw20ul5ghpo; + u32 mcsbw405ghpo; + u16 mcs32po; + u16 legofdm40duppo; + u8 sar2g; + u8 sar5g; }; /* Information about the PCB the circuitry is soldered on. */ -- cgit From 1c9351cf2180924c91bb85e5ba607f24a3d875b1 Mon Sep 17 00:00:00 2001 From: Hauke Mehrtens Date: Tue, 28 Feb 2012 00:56:09 +0100 Subject: bcma: export bcma_find_core This function is needed by the bcm47xx arch code to get the number of the ieee80211 core. Signed-off-by: Hauke Mehrtens Signed-off-by: John W. Linville --- drivers/bcma/main.c | 3 ++- include/linux/bcma/bcma.h | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/bcma/main.c b/drivers/bcma/main.c index b8379b90d045..7e138ec21357 100644 --- a/drivers/bcma/main.c +++ b/drivers/bcma/main.c @@ -61,7 +61,7 @@ static struct bus_type bcma_bus_type = { .dev_attrs = bcma_device_attrs, }; -static struct bcma_device *bcma_find_core(struct bcma_bus *bus, u16 coreid) +struct bcma_device *bcma_find_core(struct bcma_bus *bus, u16 coreid) { struct bcma_device *core; @@ -71,6 +71,7 @@ static struct bcma_device *bcma_find_core(struct bcma_bus *bus, u16 coreid) } return NULL; } +EXPORT_SYMBOL_GPL(bcma_find_core); static void bcma_release_core_dev(struct device *dev) { diff --git a/include/linux/bcma/bcma.h b/include/linux/bcma/bcma.h index b9f65fbee42f..46bbd088c4ad 100644 --- a/include/linux/bcma/bcma.h +++ b/include/linux/bcma/bcma.h @@ -284,6 +284,7 @@ static inline void bcma_maskset16(struct bcma_device *cc, bcma_write16(cc, offset, (bcma_read16(cc, offset) & mask) | set); } +extern struct bcma_device *bcma_find_core(struct bcma_bus *bus, u16 coreid); extern bool bcma_core_is_enabled(struct bcma_device *core); extern void bcma_core_disable(struct bcma_device *core, u32 flags); extern int bcma_core_enable(struct bcma_device *core, u32 flags); -- cgit From a027237a56f7d519eee5749cfb720e568d0bb0b6 Mon Sep 17 00:00:00 2001 From: Hauke Mehrtens Date: Tue, 28 Feb 2012 00:56:10 +0100 Subject: bcma: add support for sprom not found on the device On SoCs the sprom is stored in the nvram in a special partition on the flash chip. The nvram contains the sprom for the main bus, but sometimes also for a pci devices using bcma. This patch makes it possible for the arch code to register a function to fetch the needed sprom from the nvram and provide it to the bcma code. Signed-off-by: Hauke Mehrtens Signed-off-by: John W. Linville --- drivers/bcma/sprom.c | 77 ++++++++++++++++++++++++++++++++++++++++++----- include/linux/bcma/bcma.h | 6 ++++ 2 files changed, 75 insertions(+), 8 deletions(-) diff --git a/drivers/bcma/sprom.c b/drivers/bcma/sprom.c index ca7752510d5b..916ae255ff64 100644 --- a/drivers/bcma/sprom.c +++ b/drivers/bcma/sprom.c @@ -2,6 +2,8 @@ * Broadcom specific AMBA * SPROM reading * + * Copyright 2011, 2012, Hauke Mehrtens + * * Licensed under the GNU/GPL. See COPYING for details. */ @@ -14,6 +16,45 @@ #include #include +static int(*get_fallback_sprom)(struct bcma_bus *dev, struct ssb_sprom *out); + +/** + * bcma_arch_register_fallback_sprom - Registers a method providing a + * fallback SPROM if no SPROM is found. + * + * @sprom_callback: The callback function. + * + * With this function the architecture implementation may register a + * callback handler which fills the SPROM data structure. The fallback is + * used for PCI based BCMA devices, where no valid SPROM can be found + * in the shadow registers and to provide the SPROM for SoCs where BCMA is + * to controll the system bus. + * + * This function is useful for weird architectures that have a half-assed + * BCMA device hardwired to their PCI bus. + * + * This function is available for architecture code, only. So it is not + * exported. + */ +int bcma_arch_register_fallback_sprom(int (*sprom_callback)(struct bcma_bus *bus, + struct ssb_sprom *out)) +{ + if (get_fallback_sprom) + return -EEXIST; + get_fallback_sprom = sprom_callback; + + return 0; +} + +static int bcma_fill_sprom_with_fallback(struct bcma_bus *bus, + struct ssb_sprom *out) +{ + if (!get_fallback_sprom) + return -ENOENT; + + return get_fallback_sprom(bus, out); +} + /************************************************** * R/W ops. **************************************************/ @@ -246,23 +287,43 @@ static void bcma_sprom_extract_r8(struct bcma_bus *bus, const u16 *sprom) SSB_SROM8_FEM_ANTSWLUT_SHIFT); } +static bool bcma_is_sprom_available(struct bcma_bus *bus) +{ + u32 sromctrl; + + if (!(bus->drv_cc.capabilities & BCMA_CC_CAP_SPROM)) + return false; + + if (bus->drv_cc.core->id.rev >= 32) { + sromctrl = bcma_read32(bus->drv_cc.core, BCMA_CC_SROM_CONTROL); + return sromctrl & BCMA_CC_SROM_CONTROL_PRESENT; + } + return true; +} + int bcma_sprom_get(struct bcma_bus *bus) { u16 offset; u16 *sprom; - u32 sromctrl; int err = 0; if (!bus->drv_cc.core) return -EOPNOTSUPP; - if (!(bus->drv_cc.capabilities & BCMA_CC_CAP_SPROM)) - return -ENOENT; - - if (bus->drv_cc.core->id.rev >= 32) { - sromctrl = bcma_read32(bus->drv_cc.core, BCMA_CC_SROM_CONTROL); - if (!(sromctrl & BCMA_CC_SROM_CONTROL_PRESENT)) - return -ENOENT; + if (!bcma_is_sprom_available(bus)) { + /* + * Maybe there is no SPROM on the device? + * Now we ask the arch code if there is some sprom + * available for this device in some other storage. + */ + err = bcma_fill_sprom_with_fallback(bus, &bus->sprom); + if (err) { + pr_warn("Using fallback SPROM failed (err %d)\n", err); + } else { + pr_debug("Using SPROM revision %d provided by" + " platform.\n", bus->sprom.revision); + return 0; + } } sprom = kcalloc(SSB_SPROMSIZE_WORDS_R4, sizeof(u16), diff --git a/include/linux/bcma/bcma.h b/include/linux/bcma/bcma.h index 46bbd088c4ad..5af9a075498f 100644 --- a/include/linux/bcma/bcma.h +++ b/include/linux/bcma/bcma.h @@ -176,6 +176,12 @@ int __bcma_driver_register(struct bcma_driver *drv, struct module *owner); extern void bcma_driver_unregister(struct bcma_driver *drv); +/* Set a fallback SPROM. + * See kdoc at the function definition for complete documentation. */ +extern int bcma_arch_register_fallback_sprom( + int (*sprom_callback)(struct bcma_bus *bus, + struct ssb_sprom *out)); + struct bcma_bus { /* The MMIO area. */ void __iomem *mmio; -- cgit From 44d4b2ae94b19080d6d033a1f5cf2cc47443be3b Mon Sep 17 00:00:00 2001 From: Hauke Mehrtens Date: Tue, 28 Feb 2012 00:56:11 +0100 Subject: MIPS: BCM47XX: return number of written bytes in nvram_getenv Signed-off-by: Hauke Mehrtens Signed-off-by: John W. Linville --- arch/mips/bcm47xx/nvram.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/arch/mips/bcm47xx/nvram.c b/arch/mips/bcm47xx/nvram.c index a84e3bb7387f..d43ceff5be47 100644 --- a/arch/mips/bcm47xx/nvram.c +++ b/arch/mips/bcm47xx/nvram.c @@ -107,8 +107,7 @@ int nvram_getenv(char *name, char *val, size_t val_len) value = eq + 1; if ((eq - var) == strlen(name) && strncmp(var, name, (eq - var)) == 0) { - snprintf(val, val_len, "%s", value); - return 0; + return snprintf(val, val_len, "%s", value); } } return NVRAM_ERR_ENVNOTFOUND; -- cgit From ac78838b65f6e843bc04cd7772ce7c85b607a404 Mon Sep 17 00:00:00 2001 From: Hauke Mehrtens Date: Tue, 28 Feb 2012 00:56:12 +0100 Subject: MIPS: BCM47XX: fix signature of nvram_parse_macaddr Explicitly enforce an char array of 6 bytes for the mac address. Signed-off-by: Hauke Mehrtens Signed-off-by: John W. Linville --- arch/mips/include/asm/mach-bcm47xx/nvram.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/mips/include/asm/mach-bcm47xx/nvram.h b/arch/mips/include/asm/mach-bcm47xx/nvram.h index 184d5ecb5f51..69ef3efe06e7 100644 --- a/arch/mips/include/asm/mach-bcm47xx/nvram.h +++ b/arch/mips/include/asm/mach-bcm47xx/nvram.h @@ -37,7 +37,7 @@ struct nvram_header { extern int nvram_getenv(char *name, char *val, size_t val_len); -static inline void nvram_parse_macaddr(char *buf, u8 *macaddr) +static inline void nvram_parse_macaddr(char *buf, u8 macaddr[6]) { if (strchr(buf, ':')) sscanf(buf, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", &macaddr[0], -- cgit From 019eee2e34e2d1db715dc4fe5be2079800636fa8 Mon Sep 17 00:00:00 2001 From: Hauke Mehrtens Date: Tue, 28 Feb 2012 00:56:13 +0100 Subject: MIPS: BCM47XX: move and extend sprom parsing Move the sprom parsing from nvram into sprom.c. There are all values needed for sprom version 1 to 9 read from nvram and there are more sanity checks added. This is based on the sprom parsing in the open source part of the Broadcom SDK. Signed-off-by: Hauke Mehrtens Signed-off-by: John W. Linville --- arch/mips/bcm47xx/Makefile | 2 +- arch/mips/bcm47xx/setup.c | 151 +------ arch/mips/bcm47xx/sprom.c | 620 +++++++++++++++++++++++++++ arch/mips/include/asm/mach-bcm47xx/bcm47xx.h | 3 + 4 files changed, 625 insertions(+), 151 deletions(-) create mode 100644 arch/mips/bcm47xx/sprom.c diff --git a/arch/mips/bcm47xx/Makefile b/arch/mips/bcm47xx/Makefile index 4add17349ff9..4389de182eb4 100644 --- a/arch/mips/bcm47xx/Makefile +++ b/arch/mips/bcm47xx/Makefile @@ -3,5 +3,5 @@ # under Linux. # -obj-y += gpio.o irq.o nvram.o prom.o serial.o setup.o time.o +obj-y += gpio.o irq.o nvram.o prom.o serial.o setup.o time.o sprom.o obj-$(CONFIG_BCM47XX_SSB) += wgt634u.o diff --git a/arch/mips/bcm47xx/setup.c b/arch/mips/bcm47xx/setup.c index aab6b0c40a75..6b0dacde98d4 100644 --- a/arch/mips/bcm47xx/setup.c +++ b/arch/mips/bcm47xx/setup.c @@ -85,156 +85,7 @@ static void bcm47xx_machine_halt(void) } #ifdef CONFIG_BCM47XX_SSB -#define READ_FROM_NVRAM(_outvar, name, buf) \ - if (nvram_getprefix(prefix, name, buf, sizeof(buf)) >= 0)\ - sprom->_outvar = simple_strtoul(buf, NULL, 0); - -#define READ_FROM_NVRAM2(_outvar, name1, name2, buf) \ - if (nvram_getprefix(prefix, name1, buf, sizeof(buf)) >= 0 || \ - nvram_getprefix(prefix, name2, buf, sizeof(buf)) >= 0)\ - sprom->_outvar = simple_strtoul(buf, NULL, 0); - -static inline int nvram_getprefix(const char *prefix, char *name, - char *buf, int len) -{ - if (prefix) { - char key[100]; - - snprintf(key, sizeof(key), "%s%s", prefix, name); - return nvram_getenv(key, buf, len); - } - - return nvram_getenv(name, buf, len); -} - -static u32 nvram_getu32(const char *name, char *buf, int len) -{ - int rv; - char key[100]; - u16 var0, var1; - - snprintf(key, sizeof(key), "%s0", name); - rv = nvram_getenv(key, buf, len); - /* return 0 here so this looks like unset */ - if (rv < 0) - return 0; - var0 = simple_strtoul(buf, NULL, 0); - - snprintf(key, sizeof(key), "%s1", name); - rv = nvram_getenv(key, buf, len); - if (rv < 0) - return 0; - var1 = simple_strtoul(buf, NULL, 0); - return var1 << 16 | var0; -} - -static void bcm47xx_fill_sprom(struct ssb_sprom *sprom, const char *prefix) -{ - char buf[100]; - u32 boardflags; - - memset(sprom, 0, sizeof(struct ssb_sprom)); - - sprom->revision = 1; /* Fallback: Old hardware does not define this. */ - READ_FROM_NVRAM(revision, "sromrev", buf); - if (nvram_getprefix(prefix, "il0macaddr", buf, sizeof(buf)) >= 0 || - nvram_getprefix(prefix, "macaddr", buf, sizeof(buf)) >= 0) - nvram_parse_macaddr(buf, sprom->il0mac); - if (nvram_getprefix(prefix, "et0macaddr", buf, sizeof(buf)) >= 0) - nvram_parse_macaddr(buf, sprom->et0mac); - if (nvram_getprefix(prefix, "et1macaddr", buf, sizeof(buf)) >= 0) - nvram_parse_macaddr(buf, sprom->et1mac); - READ_FROM_NVRAM(et0phyaddr, "et0phyaddr", buf); - READ_FROM_NVRAM(et1phyaddr, "et1phyaddr", buf); - READ_FROM_NVRAM(et0mdcport, "et0mdcport", buf); - READ_FROM_NVRAM(et1mdcport, "et1mdcport", buf); - READ_FROM_NVRAM(board_rev, "boardrev", buf); - READ_FROM_NVRAM(country_code, "ccode", buf); - READ_FROM_NVRAM(ant_available_a, "aa5g", buf); - READ_FROM_NVRAM(ant_available_bg, "aa2g", buf); - READ_FROM_NVRAM(pa0b0, "pa0b0", buf); - READ_FROM_NVRAM(pa0b1, "pa0b1", buf); - READ_FROM_NVRAM(pa0b2, "pa0b2", buf); - READ_FROM_NVRAM(pa1b0, "pa1b0", buf); - READ_FROM_NVRAM(pa1b1, "pa1b1", buf); - READ_FROM_NVRAM(pa1b2, "pa1b2", buf); - READ_FROM_NVRAM(pa1lob0, "pa1lob0", buf); - READ_FROM_NVRAM(pa1lob2, "pa1lob1", buf); - READ_FROM_NVRAM(pa1lob1, "pa1lob2", buf); - READ_FROM_NVRAM(pa1hib0, "pa1hib0", buf); - READ_FROM_NVRAM(pa1hib2, "pa1hib1", buf); - READ_FROM_NVRAM(pa1hib1, "pa1hib2", buf); - READ_FROM_NVRAM2(gpio0, "ledbh0", "wl0gpio0", buf); - READ_FROM_NVRAM2(gpio1, "ledbh1", "wl0gpio1", buf); - READ_FROM_NVRAM2(gpio2, "ledbh2", "wl0gpio2", buf); - READ_FROM_NVRAM2(gpio3, "ledbh3", "wl0gpio3", buf); - READ_FROM_NVRAM2(maxpwr_bg, "maxp2ga0", "pa0maxpwr", buf); - READ_FROM_NVRAM2(maxpwr_al, "maxp5gla0", "pa1lomaxpwr", buf); - READ_FROM_NVRAM2(maxpwr_a, "maxp5ga0", "pa1maxpwr", buf); - READ_FROM_NVRAM2(maxpwr_ah, "maxp5gha0", "pa1himaxpwr", buf); - READ_FROM_NVRAM2(itssi_bg, "itt5ga0", "pa0itssit", buf); - READ_FROM_NVRAM2(itssi_a, "itt2ga0", "pa1itssit", buf); - READ_FROM_NVRAM(tri2g, "tri2g", buf); - READ_FROM_NVRAM(tri5gl, "tri5gl", buf); - READ_FROM_NVRAM(tri5g, "tri5g", buf); - READ_FROM_NVRAM(tri5gh, "tri5gh", buf); - READ_FROM_NVRAM(txpid2g[0], "txpid2ga0", buf); - READ_FROM_NVRAM(txpid2g[1], "txpid2ga1", buf); - READ_FROM_NVRAM(txpid2g[2], "txpid2ga2", buf); - READ_FROM_NVRAM(txpid2g[3], "txpid2ga3", buf); - READ_FROM_NVRAM(txpid5g[0], "txpid5ga0", buf); - READ_FROM_NVRAM(txpid5g[1], "txpid5ga1", buf); - READ_FROM_NVRAM(txpid5g[2], "txpid5ga2", buf); - READ_FROM_NVRAM(txpid5g[3], "txpid5ga3", buf); - READ_FROM_NVRAM(txpid5gl[0], "txpid5gla0", buf); - READ_FROM_NVRAM(txpid5gl[1], "txpid5gla1", buf); - READ_FROM_NVRAM(txpid5gl[2], "txpid5gla2", buf); - READ_FROM_NVRAM(txpid5gl[3], "txpid5gla3", buf); - READ_FROM_NVRAM(txpid5gh[0], "txpid5gha0", buf); - READ_FROM_NVRAM(txpid5gh[1], "txpid5gha1", buf); - READ_FROM_NVRAM(txpid5gh[2], "txpid5gha2", buf); - READ_FROM_NVRAM(txpid5gh[3], "txpid5gha3", buf); - READ_FROM_NVRAM(rxpo2g, "rxpo2g", buf); - READ_FROM_NVRAM(rxpo5g, "rxpo5g", buf); - READ_FROM_NVRAM(rssisav2g, "rssisav2g", buf); - READ_FROM_NVRAM(rssismc2g, "rssismc2g", buf); - READ_FROM_NVRAM(rssismf2g, "rssismf2g", buf); - READ_FROM_NVRAM(bxa2g, "bxa2g", buf); - READ_FROM_NVRAM(rssisav5g, "rssisav5g", buf); - READ_FROM_NVRAM(rssismc5g, "rssismc5g", buf); - READ_FROM_NVRAM(rssismf5g, "rssismf5g", buf); - READ_FROM_NVRAM(bxa5g, "bxa5g", buf); - READ_FROM_NVRAM(cck2gpo, "cck2gpo", buf); - - sprom->ofdm2gpo = nvram_getu32("ofdm2gpo", buf, sizeof(buf)); - sprom->ofdm5glpo = nvram_getu32("ofdm5glpo", buf, sizeof(buf)); - sprom->ofdm5gpo = nvram_getu32("ofdm5gpo", buf, sizeof(buf)); - sprom->ofdm5ghpo = nvram_getu32("ofdm5ghpo", buf, sizeof(buf)); - - READ_FROM_NVRAM(antenna_gain.ghz24.a0, "ag0", buf); - READ_FROM_NVRAM(antenna_gain.ghz24.a1, "ag1", buf); - READ_FROM_NVRAM(antenna_gain.ghz24.a2, "ag2", buf); - READ_FROM_NVRAM(antenna_gain.ghz24.a3, "ag3", buf); - memcpy(&sprom->antenna_gain.ghz5, &sprom->antenna_gain.ghz24, - sizeof(sprom->antenna_gain.ghz5)); - - if (nvram_getprefix(prefix, "boardflags", buf, sizeof(buf)) >= 0) { - boardflags = simple_strtoul(buf, NULL, 0); - if (boardflags) { - sprom->boardflags_lo = (boardflags & 0x0000FFFFU); - sprom->boardflags_hi = (boardflags & 0xFFFF0000U) >> 16; - } - } - if (nvram_getprefix(prefix, "boardflags2", buf, sizeof(buf)) >= 0) { - boardflags = simple_strtoul(buf, NULL, 0); - if (boardflags) { - sprom->boardflags2_lo = (boardflags & 0x0000FFFFU); - sprom->boardflags2_hi = (boardflags & 0xFFFF0000U) >> 16; - } - } -} - -int bcm47xx_get_sprom(struct ssb_bus *bus, struct ssb_sprom *out) +static int bcm47xx_get_sprom(struct ssb_bus *bus, struct ssb_sprom *out) { char prefix[10]; diff --git a/arch/mips/bcm47xx/sprom.c b/arch/mips/bcm47xx/sprom.c new file mode 100644 index 000000000000..5c8dcd2a8a93 --- /dev/null +++ b/arch/mips/bcm47xx/sprom.c @@ -0,0 +1,620 @@ +/* + * Copyright (C) 2004 Florian Schirmer + * Copyright (C) 2006 Felix Fietkau + * Copyright (C) 2006 Michael Buesch + * Copyright (C) 2010 Waldemar Brodkorb + * Copyright (C) 2010-2012 Hauke Mehrtens + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR 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, WHETHER IN 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. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include + +static void create_key(const char *prefix, const char *postfix, + const char *name, char *buf, int len) +{ + if (prefix && postfix) + snprintf(buf, len, "%s%s%s", prefix, name, postfix); + else if (prefix) + snprintf(buf, len, "%s%s", prefix, name); + else if (postfix) + snprintf(buf, len, "%s%s", name, postfix); + else + snprintf(buf, len, "%s", name); +} + +#define NVRAM_READ_VAL(type) \ +static void nvram_read_ ## type (const char *prefix, \ + const char *postfix, const char *name, \ + type *val, type allset) \ +{ \ + char buf[100]; \ + char key[40]; \ + int err; \ + type var; \ + \ + create_key(prefix, postfix, name, key, sizeof(key)); \ + \ + err = nvram_getenv(key, buf, sizeof(buf)); \ + if (err < 0) \ + return; \ + err = kstrto ## type (buf, 0, &var); \ + if (err) { \ + pr_warn("can not parse nvram name %s with value %s" \ + " got %i", key, buf, err); \ + return; \ + } \ + if (allset && var == allset) \ + return; \ + *val = var; \ +} + +NVRAM_READ_VAL(u8) +NVRAM_READ_VAL(s8) +NVRAM_READ_VAL(u16) +NVRAM_READ_VAL(u32) + +#undef NVRAM_READ_VAL + +static void nvram_read_u32_2(const char *prefix, const char *name, + u16 *val_lo, u16 *val_hi) +{ + char buf[100]; + char key[40]; + int err; + u32 val; + + create_key(prefix, NULL, name, key, sizeof(key)); + + err = nvram_getenv(key, buf, sizeof(buf)); + if (err < 0) + return; + err = kstrtou32(buf, 0, &val); + if (err) { + pr_warn("can not parse nvram name %s with value %s got %i", + key, buf, err); + return; + } + *val_lo = (val & 0x0000FFFFU); + *val_hi = (val & 0xFFFF0000U) >> 16; +} + +static void nvram_read_leddc(const char *prefix, const char *name, + u8 *leddc_on_time, u8 *leddc_off_time) +{ + char buf[100]; + char key[40]; + int err; + u32 val; + + create_key(prefix, NULL, name, key, sizeof(key)); + + err = nvram_getenv(key, buf, sizeof(buf)); + if (err < 0) + return; + err = kstrtou32(buf, 0, &val); + if (err) { + pr_warn("can not parse nvram name %s with value %s got %i", + key, buf, err); + return; + } + + if (val == 0xffff || val == 0xffffffff) + return; + + *leddc_on_time = val & 0xff; + *leddc_off_time = (val >> 16) & 0xff; +} + +static void nvram_read_macaddr(const char *prefix, const char *name, + u8 (*val)[6]) +{ + char buf[100]; + char key[40]; + int err; + + create_key(prefix, NULL, name, key, sizeof(key)); + + err = nvram_getenv(key, buf, sizeof(buf)); + if (err < 0) + return; + nvram_parse_macaddr(buf, *val); +} + +static void nvram_read_alpha2(const char *prefix, const char *name, + char (*val)[2]) +{ + char buf[10]; + char key[40]; + int err; + + create_key(prefix, NULL, name, key, sizeof(key)); + + err = nvram_getenv(key, buf, sizeof(buf)); + if (err < 0) + return; + if (buf[0] == '0') + return; + if (strlen(buf) > 2) { + pr_warn("alpha2 is too long %s", buf); + return; + } + memcpy(val, buf, sizeof(val)); +} + +static void bcm47xx_fill_sprom_r1234589(struct ssb_sprom *sprom, + const char *prefix) +{ + nvram_read_u16(prefix, NULL, "boardrev", &sprom->board_rev, 0); + nvram_read_u16(prefix, NULL, "boardnum", &sprom->board_num, 0); + nvram_read_u8(prefix, NULL, "ledbh0", &sprom->gpio0, 0xff); + nvram_read_u8(prefix, NULL, "ledbh1", &sprom->gpio1, 0xff); + nvram_read_u8(prefix, NULL, "ledbh2", &sprom->gpio2, 0xff); + nvram_read_u8(prefix, NULL, "ledbh3", &sprom->gpio3, 0xff); + nvram_read_u8(prefix, NULL, "aa2g", &sprom->ant_available_bg, 0); + nvram_read_u8(prefix, NULL, "aa5g", &sprom->ant_available_a, 0); + nvram_read_s8(prefix, NULL, "ag0", &sprom->antenna_gain.a0, 0); + nvram_read_s8(prefix, NULL, "ag1", &sprom->antenna_gain.a1, 0); + nvram_read_alpha2(prefix, "ccode", &sprom->alpha2); +} + +static void bcm47xx_fill_sprom_r12389(struct ssb_sprom *sprom, + const char *prefix) +{ + nvram_read_u16(prefix, NULL, "pa0b0", &sprom->pa0b0, 0); + nvram_read_u16(prefix, NULL, "pa0b1", &sprom->pa0b1, 0); + nvram_read_u16(prefix, NULL, "pa0b2", &sprom->pa0b2, 0); + nvram_read_u8(prefix, NULL, "pa0itssit", &sprom->itssi_bg, 0); + nvram_read_u8(prefix, NULL, "pa0maxpwr", &sprom->maxpwr_bg, 0); + nvram_read_u16(prefix, NULL, "pa1b0", &sprom->pa1b0, 0); + nvram_read_u16(prefix, NULL, "pa1b1", &sprom->pa1b1, 0); + nvram_read_u16(prefix, NULL, "pa1b2", &sprom->pa1b2, 0); + nvram_read_u8(prefix, NULL, "pa1itssit", &sprom->itssi_a, 0); + nvram_read_u8(prefix, NULL, "pa1maxpwr", &sprom->maxpwr_a, 0); +} + +static void bcm47xx_fill_sprom_r1(struct ssb_sprom *sprom, const char *prefix) +{ + nvram_read_u16(prefix, NULL, "boardflags", &sprom->boardflags_lo, 0); + nvram_read_u8(prefix, NULL, "cc", &sprom->country_code, 0); +} + +static void bcm47xx_fill_sprom_r2389(struct ssb_sprom *sprom, + const char *prefix) +{ + nvram_read_u8(prefix, NULL, "opo", &sprom->opo, 0); + nvram_read_u16(prefix, NULL, "pa1lob0", &sprom->pa1lob0, 0); + nvram_read_u16(prefix, NULL, "pa1lob1", &sprom->pa1lob1, 0); + nvram_read_u16(prefix, NULL, "pa1lob2", &sprom->pa1lob2, 0); + nvram_read_u16(prefix, NULL, "pa1hib0", &sprom->pa1hib0, 0); + nvram_read_u16(prefix, NULL, "pa1hib1", &sprom->pa1hib1, 0); + nvram_read_u16(prefix, NULL, "pa1hib2", &sprom->pa1hib2, 0); + nvram_read_u8(prefix, NULL, "pa1lomaxpwr", &sprom->maxpwr_al, 0); + nvram_read_u8(prefix, NULL, "pa1himaxpwr", &sprom->maxpwr_ah, 0); +} + +static void bcm47xx_fill_sprom_r2(struct ssb_sprom *sprom, const char *prefix) +{ + nvram_read_u32_2(prefix, "boardflags", &sprom->boardflags_lo, + &sprom->boardflags_hi); + nvram_read_u16(prefix, NULL, "boardtype", &sprom->board_type, 0); +} + +static void bcm47xx_fill_sprom_r389(struct ssb_sprom *sprom, const char *prefix) +{ + nvram_read_u8(prefix, NULL, "bxa2g", &sprom->bxa2g, 0); + nvram_read_u8(prefix, NULL, "rssisav2g", &sprom->rssisav2g, 0); + nvram_read_u8(prefix, NULL, "rssismc2g", &sprom->rssismc2g, 0); + nvram_read_u8(prefix, NULL, "rssismf2g", &sprom->rssismf2g, 0); + nvram_read_u8(prefix, NULL, "bxa5g", &sprom->bxa5g, 0); + nvram_read_u8(prefix, NULL, "rssisav5g", &sprom->rssisav5g, 0); + nvram_read_u8(prefix, NULL, "rssismc5g", &sprom->rssismc5g, 0); + nvram_read_u8(prefix, NULL, "rssismf5g", &sprom->rssismf5g, 0); + nvram_read_u8(prefix, NULL, "tri2g", &sprom->tri2g, 0); + nvram_read_u8(prefix, NULL, "tri5g", &sprom->tri5g, 0); + nvram_read_u8(prefix, NULL, "tri5gl", &sprom->tri5gl, 0); + nvram_read_u8(prefix, NULL, "tri5gh", &sprom->tri5gh, 0); + nvram_read_s8(prefix, NULL, "rxpo2g", &sprom->rxpo2g, 0); + nvram_read_s8(prefix, NULL, "rxpo5g", &sprom->rxpo5g, 0); +} + +static void bcm47xx_fill_sprom_r3(struct ssb_sprom *sprom, const char *prefix) +{ + nvram_read_u32_2(prefix, "boardflags", &sprom->boardflags_lo, + &sprom->boardflags_hi); + nvram_read_u16(prefix, NULL, "boardtype", &sprom->board_type, 0); + nvram_read_u8(prefix, NULL, "regrev", &sprom->regrev, 0); + nvram_read_leddc(prefix, "leddc", &sprom->leddc_on_time, + &sprom->leddc_off_time); +} + +static void bcm47xx_fill_sprom_r4589(struct ssb_sprom *sprom, + const char *prefix) +{ + nvram_read_u32_2(prefix, "boardflags", &sprom->boardflags_lo, + &sprom->boardflags_hi); + nvram_read_u32_2(prefix, "boardflags2", &sprom->boardflags2_lo, + &sprom->boardflags2_hi); + nvram_read_u16(prefix, NULL, "boardtype", &sprom->board_type, 0); + nvram_read_u8(prefix, NULL, "regrev", &sprom->regrev, 0); + nvram_read_s8(prefix, NULL, "ag2", &sprom->antenna_gain.a2, 0); + nvram_read_s8(prefix, NULL, "ag3", &sprom->antenna_gain.a3, 0); + nvram_read_u8(prefix, NULL, "txchain", &sprom->txchain, 0xf); + nvram_read_u8(prefix, NULL, "rxchain", &sprom->rxchain, 0xf); + nvram_read_u8(prefix, NULL, "antswitch", &sprom->antswitch, 0xff); + nvram_read_leddc(prefix, "leddc", &sprom->leddc_on_time, + &sprom->leddc_off_time); +} + +static void bcm47xx_fill_sprom_r458(struct ssb_sprom *sprom, const char *prefix) +{ + nvram_read_u16(prefix, NULL, "cck2gpo", &sprom->cck2gpo, 0); + nvram_read_u32(prefix, NULL, "ofdm2gpo", &sprom->ofdm2gpo, 0); + nvram_read_u32(prefix, NULL, "ofdm5gpo", &sprom->ofdm5gpo, 0); + nvram_read_u32(prefix, NULL, "ofdm5glpo", &sprom->ofdm5glpo, 0); + nvram_read_u32(prefix, NULL, "ofdm5ghpo", &sprom->ofdm5ghpo, 0); + nvram_read_u16(prefix, NULL, "cddpo", &sprom->cddpo, 0); + nvram_read_u16(prefix, NULL, "stbcpo", &sprom->stbcpo, 0); + nvram_read_u16(prefix, NULL, "bw40po", &sprom->bw40po, 0); + nvram_read_u16(prefix, NULL, "bwduppo", &sprom->bwduppo, 0); + nvram_read_u16(prefix, NULL, "mcs2gpo0", &sprom->mcs2gpo[0], 0); + nvram_read_u16(prefix, NULL, "mcs2gpo1", &sprom->mcs2gpo[1], 0); + nvram_read_u16(prefix, NULL, "mcs2gpo2", &sprom->mcs2gpo[2], 0); + nvram_read_u16(prefix, NULL, "mcs2gpo3", &sprom->mcs2gpo[3], 0); + nvram_read_u16(prefix, NULL, "mcs2gpo4", &sprom->mcs2gpo[4], 0); + nvram_read_u16(prefix, NULL, "mcs2gpo5", &sprom->mcs2gpo[5], 0); + nvram_read_u16(prefix, NULL, "mcs2gpo6", &sprom->mcs2gpo[6], 0); + nvram_read_u16(prefix, NULL, "mcs2gpo7", &sprom->mcs2gpo[7], 0); + nvram_read_u16(prefix, NULL, "mcs5gpo0", &sprom->mcs5gpo[0], 0); + nvram_read_u16(prefix, NULL, "mcs5gpo1", &sprom->mcs5gpo[1], 0); + nvram_read_u16(prefix, NULL, "mcs5gpo2", &sprom->mcs5gpo[2], 0); + nvram_read_u16(prefix, NULL, "mcs5gpo3", &sprom->mcs5gpo[3], 0); + nvram_read_u16(prefix, NULL, "mcs5gpo4", &sprom->mcs5gpo[4], 0); + nvram_read_u16(prefix, NULL, "mcs5gpo5", &sprom->mcs5gpo[5], 0); + nvram_read_u16(prefix, NULL, "mcs5gpo6", &sprom->mcs5gpo[6], 0); + nvram_read_u16(prefix, NULL, "mcs5gpo7", &sprom->mcs5gpo[7], 0); + nvram_read_u16(prefix, NULL, "mcs5glpo0", &sprom->mcs5glpo[0], 0); + nvram_read_u16(prefix, NULL, "mcs5glpo1", &sprom->mcs5glpo[1], 0); + nvram_read_u16(prefix, NULL, "mcs5glpo2", &sprom->mcs5glpo[2], 0); + nvram_read_u16(prefix, NULL, "mcs5glpo3", &sprom->mcs5glpo[3], 0); + nvram_read_u16(prefix, NULL, "mcs5glpo4", &sprom->mcs5glpo[4], 0); + nvram_read_u16(prefix, NULL, "mcs5glpo5", &sprom->mcs5glpo[5], 0); + nvram_read_u16(prefix, NULL, "mcs5glpo6", &sprom->mcs5glpo[6], 0); + nvram_read_u16(prefix, NULL, "mcs5glpo7", &sprom->mcs5glpo[7], 0); + nvram_read_u16(prefix, NULL, "mcs5ghpo0", &sprom->mcs5ghpo[0], 0); + nvram_read_u16(prefix, NULL, "mcs5ghpo1", &sprom->mcs5ghpo[1], 0); + nvram_read_u16(prefix, NULL, "mcs5ghpo2", &sprom->mcs5ghpo[2], 0); + nvram_read_u16(prefix, NULL, "mcs5ghpo3", &sprom->mcs5ghpo[3], 0); + nvram_read_u16(prefix, NULL, "mcs5ghpo4", &sprom->mcs5ghpo[4], 0); + nvram_read_u16(prefix, NULL, "mcs5ghpo5", &sprom->mcs5ghpo[5], 0); + nvram_read_u16(prefix, NULL, "mcs5ghpo6", &sprom->mcs5ghpo[6], 0); + nvram_read_u16(prefix, NULL, "mcs5ghpo7", &sprom->mcs5ghpo[7], 0); +} + +static void bcm47xx_fill_sprom_r45(struct ssb_sprom *sprom, const char *prefix) +{ + nvram_read_u8(prefix, NULL, "txpid2ga0", &sprom->txpid2g[0], 0); + nvram_read_u8(prefix, NULL, "txpid2ga1", &sprom->txpid2g[1], 0); + nvram_read_u8(prefix, NULL, "txpid2ga2", &sprom->txpid2g[2], 0); + nvram_read_u8(prefix, NULL, "txpid2ga3", &sprom->txpid2g[3], 0); + nvram_read_u8(prefix, NULL, "txpid5ga0", &sprom->txpid5g[0], 0); + nvram_read_u8(prefix, NULL, "txpid5ga1", &sprom->txpid5g[1], 0); + nvram_read_u8(prefix, NULL, "txpid5ga2", &sprom->txpid5g[2], 0); + nvram_read_u8(prefix, NULL, "txpid5ga3", &sprom->txpid5g[3], 0); + nvram_read_u8(prefix, NULL, "txpid5gla0", &sprom->txpid5gl[0], 0); + nvram_read_u8(prefix, NULL, "txpid5gla1", &sprom->txpid5gl[1], 0); + nvram_read_u8(prefix, NULL, "txpid5gla2", &sprom->txpid5gl[2], 0); + nvram_read_u8(prefix, NULL, "txpid5gla3", &sprom->txpid5gl[3], 0); + nvram_read_u8(prefix, NULL, "txpid5gha0", &sprom->txpid5gh[0], 0); + nvram_read_u8(prefix, NULL, "txpid5gha1", &sprom->txpid5gh[1], 0); + nvram_read_u8(prefix, NULL, "txpid5gha2", &sprom->txpid5gh[2], 0); + nvram_read_u8(prefix, NULL, "txpid5gha3", &sprom->txpid5gh[3], 0); +} + +static void bcm47xx_fill_sprom_r89(struct ssb_sprom *sprom, const char *prefix) +{ + nvram_read_u8(prefix, NULL, "tssipos2g", &sprom->fem.ghz2.tssipos, 0); + nvram_read_u8(prefix, NULL, "extpagain2g", + &sprom->fem.ghz2.extpa_gain, 0); + nvram_read_u8(prefix, NULL, "pdetrange2g", + &sprom->fem.ghz2.pdet_range, 0); + nvram_read_u8(prefix, NULL, "triso2g", &sprom->fem.ghz2.tr_iso, 0); + nvram_read_u8(prefix, NULL, "antswctl2g", &sprom->fem.ghz2.antswlut, 0); + nvram_read_u8(prefix, NULL, "tssipos5g", &sprom->fem.ghz5.tssipos, 0); + nvram_read_u8(prefix, NULL, "extpagain5g", + &sprom->fem.ghz5.extpa_gain, 0); + nvram_read_u8(prefix, NULL, "pdetrange5g", + &sprom->fem.ghz5.pdet_range, 0); + nvram_read_u8(prefix, NULL, "triso5g", &sprom->fem.ghz5.tr_iso, 0); + nvram_read_u8(prefix, NULL, "antswctl5g", &sprom->fem.ghz5.antswlut, 0); + nvram_read_u8(prefix, NULL, "tempthresh", &sprom->tempthresh, 0); + nvram_read_u8(prefix, NULL, "tempoffset", &sprom->tempoffset, 0); + nvram_read_u16(prefix, NULL, "rawtempsense", &sprom->rawtempsense, 0); + nvram_read_u8(prefix, NULL, "measpower", &sprom->measpower, 0); + nvram_read_u8(prefix, NULL, "tempsense_slope", + &sprom->tempsense_slope, 0); + nvram_read_u8(prefix, NULL, "tempcorrx", &sprom->tempcorrx, 0); + nvram_read_u8(prefix, NULL, "tempsense_option", + &sprom->tempsense_option, 0); + nvram_read_u8(prefix, NULL, "freqoffset_corr", + &sprom->freqoffset_corr, 0); + nvram_read_u8(prefix, NULL, "iqcal_swp_dis", &sprom->iqcal_swp_dis, 0); + nvram_read_u8(prefix, NULL, "hw_iqcal_en", &sprom->hw_iqcal_en, 0); + nvram_read_u8(prefix, NULL, "elna2g", &sprom->elna2g, 0); + nvram_read_u8(prefix, NULL, "elna5g", &sprom->elna5g, 0); + nvram_read_u8(prefix, NULL, "phycal_tempdelta", + &sprom->phycal_tempdelta, 0); + nvram_read_u8(prefix, NULL, "temps_period", &sprom->temps_period, 0); + nvram_read_u8(prefix, NULL, "temps_hysteresis", + &sprom->temps_hysteresis, 0); + nvram_read_u8(prefix, NULL, "measpower1", &sprom->measpower1, 0); + nvram_read_u8(prefix, NULL, "measpower2", &sprom->measpower2, 0); + nvram_read_u8(prefix, NULL, "rxgainerr2ga0", + &sprom->rxgainerr2ga[0], 0); + nvram_read_u8(prefix, NULL, "rxgainerr2ga1", + &sprom->rxgainerr2ga[1], 0); + nvram_read_u8(prefix, NULL, "rxgainerr2ga2", + &sprom->rxgainerr2ga[2], 0); + nvram_read_u8(prefix, NULL, "rxgainerr5gla0", + &sprom->rxgainerr5gla[0], 0); + nvram_read_u8(prefix, NULL, "rxgainerr5gla1", + &sprom->rxgainerr5gla[1], 0); + nvram_read_u8(prefix, NULL, "rxgainerr5gla2", + &sprom->rxgainerr5gla[2], 0); + nvram_read_u8(prefix, NULL, "rxgainerr5gma0", + &sprom->rxgainerr5gma[0], 0); + nvram_read_u8(prefix, NULL, "rxgainerr5gma1", + &sprom->rxgainerr5gma[1], 0); + nvram_read_u8(prefix, NULL, "rxgainerr5gma2", + &sprom->rxgainerr5gma[2], 0); + nvram_read_u8(prefix, NULL, "rxgainerr5gha0", + &sprom->rxgainerr5gha[0], 0); + nvram_read_u8(prefix, NULL, "rxgainerr5gha1", + &sprom->rxgainerr5gha[1], 0); + nvram_read_u8(prefix, NULL, "rxgainerr5gha2", + &sprom->rxgainerr5gha[2], 0); + nvram_read_u8(prefix, NULL, "rxgainerr5gua0", + &sprom->rxgainerr5gua[0], 0); + nvram_read_u8(prefix, NULL, "rxgainerr5gua1", + &sprom->rxgainerr5gua[1], 0); + nvram_read_u8(prefix, NULL, "rxgainerr5gua2", + &sprom->rxgainerr5gua[2], 0); + nvram_read_u8(prefix, NULL, "noiselvl2ga0", &sprom->noiselvl2ga[0], 0); + nvram_read_u8(prefix, NULL, "noiselvl2ga1", &sprom->noiselvl2ga[1], 0); + nvram_read_u8(prefix, NULL, "noiselvl2ga2", &sprom->noiselvl2ga[2], 0); + nvram_read_u8(prefix, NULL, "noiselvl5gla0", + &sprom->noiselvl5gla[0], 0); + nvram_read_u8(prefix, NULL, "noiselvl5gla1", + &sprom->noiselvl5gla[1], 0); + nvram_read_u8(prefix, NULL, "noiselvl5gla2", + &sprom->noiselvl5gla[2], 0); + nvram_read_u8(prefix, NULL, "noiselvl5gma0", + &sprom->noiselvl5gma[0], 0); + nvram_read_u8(prefix, NULL, "noiselvl5gma1", + &sprom->noiselvl5gma[1], 0); + nvram_read_u8(prefix, NULL, "noiselvl5gma2", + &sprom->noiselvl5gma[2], 0); + nvram_read_u8(prefix, NULL, "noiselvl5gha0", + &sprom->noiselvl5gha[0], 0); + nvram_read_u8(prefix, NULL, "noiselvl5gha1", + &sprom->noiselvl5gha[1], 0); + nvram_read_u8(prefix, NULL, "noiselvl5gha2", + &sprom->noiselvl5gha[2], 0); + nvram_read_u8(prefix, NULL, "noiselvl5gua0", + &sprom->noiselvl5gua[0], 0); + nvram_read_u8(prefix, NULL, "noiselvl5gua1", + &sprom->noiselvl5gua[1], 0); + nvram_read_u8(prefix, NULL, "noiselvl5gua2", + &sprom->noiselvl5gua[2], 0); + nvram_read_u8(prefix, NULL, "pcieingress_war", + &sprom->pcieingress_war, 0); +} + +static void bcm47xx_fill_sprom_r9(struct ssb_sprom *sprom, const char *prefix) +{ + nvram_read_u16(prefix, NULL, "cckbw202gpo", &sprom->cckbw202gpo, 0); + nvram_read_u16(prefix, NULL, "cckbw20ul2gpo", &sprom->cckbw20ul2gpo, 0); + nvram_read_u32(prefix, NULL, "legofdmbw202gpo", + &sprom->legofdmbw202gpo, 0); + nvram_read_u32(prefix, NULL, "legofdmbw20ul2gpo", + &sprom->legofdmbw20ul2gpo, 0); + nvram_read_u32(prefix, NULL, "legofdmbw205glpo", + &sprom->legofdmbw205glpo, 0); + nvram_read_u32(prefix, NULL, "legofdmbw20ul5glpo", + &sprom->legofdmbw20ul5glpo, 0); + nvram_read_u32(prefix, NULL, "legofdmbw205gmpo", + &sprom->legofdmbw205gmpo, 0); + nvram_read_u32(prefix, NULL, "legofdmbw20ul5gmpo", + &sprom->legofdmbw20ul5gmpo, 0); + nvram_read_u32(prefix, NULL, "legofdmbw205ghpo", + &sprom->legofdmbw205ghpo, 0); + nvram_read_u32(prefix, NULL, "legofdmbw20ul5ghpo", + &sprom->legofdmbw20ul5ghpo, 0); + nvram_read_u32(prefix, NULL, "mcsbw202gpo", &sprom->mcsbw202gpo, 0); + nvram_read_u32(prefix, NULL, "mcsbw20ul2gpo", &sprom->mcsbw20ul2gpo, 0); + nvram_read_u32(prefix, NULL, "mcsbw402gpo", &sprom->mcsbw402gpo, 0); + nvram_read_u32(prefix, NULL, "mcsbw205glpo", &sprom->mcsbw205glpo, 0); + nvram_read_u32(prefix, NULL, "mcsbw20ul5glpo", + &sprom->mcsbw20ul5glpo, 0); + nvram_read_u32(prefix, NULL, "mcsbw405glpo", &sprom->mcsbw405glpo, 0); + nvram_read_u32(prefix, NULL, "mcsbw205gmpo", &sprom->mcsbw205gmpo, 0); + nvram_read_u32(prefix, NULL, "mcsbw20ul5gmpo", + &sprom->mcsbw20ul5gmpo, 0); + nvram_read_u32(prefix, NULL, "mcsbw405gmpo", &sprom->mcsbw405gmpo, 0); + nvram_read_u32(prefix, NULL, "mcsbw205ghpo", &sprom->mcsbw205ghpo, 0); + nvram_read_u32(prefix, NULL, "mcsbw20ul5ghpo", + &sprom->mcsbw20ul5ghpo, 0); + nvram_read_u32(prefix, NULL, "mcsbw405ghpo", &sprom->mcsbw405ghpo, 0); + nvram_read_u16(prefix, NULL, "mcs32po", &sprom->mcs32po, 0); + nvram_read_u16(prefix, NULL, "legofdm40duppo", + &sprom->legofdm40duppo, 0); + nvram_read_u8(prefix, NULL, "sar2g", &sprom->sar2g, 0); + nvram_read_u8(prefix, NULL, "sar5g", &sprom->sar5g, 0); +} + +static void bcm47xx_fill_sprom_path_r4589(struct ssb_sprom *sprom, + const char *prefix) +{ + char postfix[2]; + int i; + + for (i = 0; i < ARRAY_SIZE(sprom->core_pwr_info); i++) { + struct ssb_sprom_core_pwr_info *pwr_info = &sprom->core_pwr_info[i]; + snprintf(postfix, sizeof(postfix), "%i", i); + nvram_read_u8(prefix, postfix, "maxp2ga", + &pwr_info->maxpwr_2g, 0); + nvram_read_u8(prefix, postfix, "itt2ga", + &pwr_info->itssi_2g, 0); + nvram_read_u8(prefix, postfix, "itt5ga", + &pwr_info->itssi_5g, 0); + nvram_read_u16(prefix, postfix, "pa2gw0a", + &pwr_info->pa_2g[0], 0); + nvram_read_u16(prefix, postfix, "pa2gw1a", + &pwr_info->pa_2g[1], 0); + nvram_read_u16(prefix, postfix, "pa2gw2a", + &pwr_info->pa_2g[2], 0); + nvram_read_u8(prefix, postfix, "maxp5ga", + &pwr_info->maxpwr_5g, 0); + nvram_read_u8(prefix, postfix, "maxp5gha", + &pwr_info->maxpwr_5gh, 0); + nvram_read_u8(prefix, postfix, "maxp5gla", + &pwr_info->maxpwr_5gl, 0); + nvram_read_u16(prefix, postfix, "pa5gw0a", + &pwr_info->pa_5g[0], 0); + nvram_read_u16(prefix, postfix, "pa5gw1a", + &pwr_info->pa_5g[1], 0); + nvram_read_u16(prefix, postfix, "pa5gw2a", + &pwr_info->pa_5g[2], 0); + nvram_read_u16(prefix, postfix, "pa5glw0a", + &pwr_info->pa_5gl[0], 0); + nvram_read_u16(prefix, postfix, "pa5glw1a", + &pwr_info->pa_5gl[1], 0); + nvram_read_u16(prefix, postfix, "pa5glw2a", + &pwr_info->pa_5gl[2], 0); + nvram_read_u16(prefix, postfix, "pa5ghw0a", + &pwr_info->pa_5gh[0], 0); + nvram_read_u16(prefix, postfix, "pa5ghw1a", + &pwr_info->pa_5gh[1], 0); + nvram_read_u16(prefix, postfix, "pa5ghw2a", + &pwr_info->pa_5gh[2], 0); + } +} + +static void bcm47xx_fill_sprom_path_r45(struct ssb_sprom *sprom, + const char *prefix) +{ + char postfix[2]; + int i; + + for (i = 0; i < ARRAY_SIZE(sprom->core_pwr_info); i++) { + struct ssb_sprom_core_pwr_info *pwr_info = &sprom->core_pwr_info[i]; + snprintf(postfix, sizeof(postfix), "%i", i); + nvram_read_u16(prefix, postfix, "pa2gw3a", + &pwr_info->pa_2g[3], 0); + nvram_read_u16(prefix, postfix, "pa5gw3a", + &pwr_info->pa_5g[3], 0); + nvram_read_u16(prefix, postfix, "pa5glw3a", + &pwr_info->pa_5gl[3], 0); + nvram_read_u16(prefix, postfix, "pa5ghw3a", + &pwr_info->pa_5gh[3], 0); + } +} + +void bcm47xx_fill_sprom_ethernet(struct ssb_sprom *sprom, const char *prefix) +{ + nvram_read_macaddr(prefix, "et0macaddr", &sprom->et0mac); + nvram_read_u8(prefix, NULL, "et0mdcport", &sprom->et0mdcport, 0); + nvram_read_u8(prefix, NULL, "et0phyaddr", &sprom->et0phyaddr, 0); + + nvram_read_macaddr(prefix, "et1macaddr", &sprom->et1mac); + nvram_read_u8(prefix, NULL, "et1mdcport", &sprom->et1mdcport, 0); + nvram_read_u8(prefix, NULL, "et1phyaddr", &sprom->et1phyaddr, 0); + + nvram_read_macaddr(prefix, "macaddr", &sprom->il0mac); + nvram_read_macaddr(prefix, "il0macaddr", &sprom->il0mac); +} + +void bcm47xx_fill_sprom(struct ssb_sprom *sprom, const char *prefix) +{ + memset(sprom, 0, sizeof(struct ssb_sprom)); + + bcm47xx_fill_sprom_ethernet(sprom, prefix); + + nvram_read_u8(prefix, NULL, "sromrev", &sprom->revision, 0); + + switch (sprom->revision) { + case 1: + bcm47xx_fill_sprom_r1234589(sprom, prefix); + bcm47xx_fill_sprom_r12389(sprom, prefix); + bcm47xx_fill_sprom_r1(sprom, prefix); + break; + case 2: + bcm47xx_fill_sprom_r1234589(sprom, prefix); + bcm47xx_fill_sprom_r12389(sprom, prefix); + bcm47xx_fill_sprom_r2389(sprom, prefix); + bcm47xx_fill_sprom_r2(sprom, prefix); + break; + case 3: + bcm47xx_fill_sprom_r1234589(sprom, prefix); + bcm47xx_fill_sprom_r12389(sprom, prefix); + bcm47xx_fill_sprom_r2389(sprom, prefix); + bcm47xx_fill_sprom_r389(sprom, prefix); + bcm47xx_fill_sprom_r3(sprom, prefix); + break; + case 4: + case 5: + bcm47xx_fill_sprom_r1234589(sprom, prefix); + bcm47xx_fill_sprom_r4589(sprom, prefix); + bcm47xx_fill_sprom_r458(sprom, prefix); + bcm47xx_fill_sprom_r45(sprom, prefix); + bcm47xx_fill_sprom_path_r4589(sprom, prefix); + bcm47xx_fill_sprom_path_r45(sprom, prefix); + break; + case 8: + bcm47xx_fill_sprom_r1234589(sprom, prefix); + bcm47xx_fill_sprom_r12389(sprom, prefix); + bcm47xx_fill_sprom_r2389(sprom, prefix); + bcm47xx_fill_sprom_r389(sprom, prefix); + bcm47xx_fill_sprom_r4589(sprom, prefix); + bcm47xx_fill_sprom_r458(sprom, prefix); + bcm47xx_fill_sprom_r89(sprom, prefix); + bcm47xx_fill_sprom_path_r4589(sprom, prefix); + break; + case 9: + bcm47xx_fill_sprom_r1234589(sprom, prefix); + bcm47xx_fill_sprom_r12389(sprom, prefix); + bcm47xx_fill_sprom_r2389(sprom, prefix); + bcm47xx_fill_sprom_r389(sprom, prefix); + bcm47xx_fill_sprom_r4589(sprom, prefix); + bcm47xx_fill_sprom_r89(sprom, prefix); + bcm47xx_fill_sprom_r9(sprom, prefix); + bcm47xx_fill_sprom_path_r4589(sprom, prefix); + break; + default: + pr_warn("Unsupported SPROM revision %d detected. Will extract" + " v1\n", sprom->revision); + sprom->revision = 1; + bcm47xx_fill_sprom_r1234589(sprom, prefix); + bcm47xx_fill_sprom_r12389(sprom, prefix); + bcm47xx_fill_sprom_r1(sprom, prefix); + } +} diff --git a/arch/mips/include/asm/mach-bcm47xx/bcm47xx.h b/arch/mips/include/asm/mach-bcm47xx/bcm47xx.h index de95e0723e2b..5ecaf47b34d2 100644 --- a/arch/mips/include/asm/mach-bcm47xx/bcm47xx.h +++ b/arch/mips/include/asm/mach-bcm47xx/bcm47xx.h @@ -44,4 +44,7 @@ union bcm47xx_bus { extern union bcm47xx_bus bcm47xx_bus; extern enum bcm47xx_bus_type bcm47xx_bus_type; +void bcm47xx_fill_sprom(struct ssb_sprom *sprom, const char *prefix); +void bcm47xx_fill_sprom_ethernet(struct ssb_sprom *sprom, const char *prefix); + #endif /* __ASM_BCM47XX_H */ -- cgit From f384b3dddc727b1cbd77e493c24d7fefa883396a Mon Sep 17 00:00:00 2001 From: Hauke Mehrtens Date: Tue, 28 Feb 2012 00:56:14 +0100 Subject: MIPS: BCM47XX: provide sprom to bcma bus On SoCs the sprom is often stored in nvram in the flashchip. This patch registers a sprom fallback callback handler in bcma and provides the sprom needed for this device. Signed-off-by: Hauke Mehrtens Signed-off-by: John W. Linville --- arch/mips/bcm47xx/setup.c | 39 +++++++++++++++++++++++++++++++++++---- 1 file changed, 35 insertions(+), 4 deletions(-) diff --git a/arch/mips/bcm47xx/setup.c b/arch/mips/bcm47xx/setup.c index 6b0dacde98d4..19780aa91708 100644 --- a/arch/mips/bcm47xx/setup.c +++ b/arch/mips/bcm47xx/setup.c @@ -3,7 +3,7 @@ * Copyright (C) 2006 Felix Fietkau * Copyright (C) 2006 Michael Buesch * Copyright (C) 2010 Waldemar Brodkorb - * Copyright (C) 2010-2011 Hauke Mehrtens + * Copyright (C) 2010-2012 Hauke Mehrtens * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -85,7 +85,7 @@ static void bcm47xx_machine_halt(void) } #ifdef CONFIG_BCM47XX_SSB -static int bcm47xx_get_sprom(struct ssb_bus *bus, struct ssb_sprom *out) +static int bcm47xx_get_sprom_ssb(struct ssb_bus *bus, struct ssb_sprom *out) { char prefix[10]; @@ -102,7 +102,7 @@ static int bcm47xx_get_sprom(struct ssb_bus *bus, struct ssb_sprom *out) } static int bcm47xx_get_invariants(struct ssb_bus *bus, - struct ssb_init_invariants *iv) + struct ssb_init_invariants *iv) { char buf[20]; @@ -132,7 +132,7 @@ static void __init bcm47xx_register_ssb(void) char buf[100]; struct ssb_mipscore *mcore; - err = ssb_arch_register_fallback_sprom(&bcm47xx_get_sprom); + err = ssb_arch_register_fallback_sprom(&bcm47xx_get_sprom_ssb); if (err) printk(KERN_WARNING "bcm47xx: someone else already registered" " a ssb SPROM callback handler (err %d)\n", err); @@ -159,10 +159,41 @@ static void __init bcm47xx_register_ssb(void) #endif #ifdef CONFIG_BCM47XX_BCMA +static int bcm47xx_get_sprom_bcma(struct bcma_bus *bus, struct ssb_sprom *out) +{ + char prefix[10]; + struct bcma_device *core; + + switch (bus->hosttype) { + case BCMA_HOSTTYPE_PCI: + snprintf(prefix, sizeof(prefix), "pci/%u/%u/", + bus->host_pci->bus->number + 1, + PCI_SLOT(bus->host_pci->devfn)); + bcm47xx_fill_sprom(out, prefix); + return 0; + case BCMA_HOSTTYPE_SOC: + bcm47xx_fill_sprom_ethernet(out, NULL); + core = bcma_find_core(bus, BCMA_CORE_80211); + if (core) { + snprintf(prefix, sizeof(prefix), "sb/%u/", + core->core_index); + bcm47xx_fill_sprom(out, prefix); + } + return 0; + default: + pr_warn("bcm47xx: unable to fill SPROM for given bustype.\n"); + return -EINVAL; + } +} + static void __init bcm47xx_register_bcma(void) { int err; + err = bcma_arch_register_fallback_sprom(&bcm47xx_get_sprom_bcma); + if (err) + pr_warn("bcm47xx: someone else already registered a bcma SPROM callback handler (err %d)\n", err); + err = bcma_host_soc_register(&bcm47xx_bus.bcma); if (err) panic("Failed to initialize BCMA bus (err %d)", err); -- cgit From eb416ad37db897efe9b2a5b79bd671f5966fa443 Mon Sep 17 00:00:00 2001 From: Avinash Patil Date: Mon, 27 Feb 2012 22:04:11 -0800 Subject: mwifiex: correct bitrates advertised to cfg80211 1. Driver and firmware do not support 22Mbps and 72Mbps bitrates. Remove them from the rate table advertised to cfg80211. 2. First 4 rates from mwifiex_rates table are not valid for 5GHz/A band. Set correct bitrate array's index and no of rates for ieee80211_supported_band for 5GHz band. Signed-off-by: Avinash Patil Signed-off-by: Nishant Sarmukadam Signed-off-by: Amitkumar Karwar Signed-off-by: Yogesh Ashok Powar Signed-off-by: Kiran Divekar Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/cfg80211.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index 6a81101bab44..55293a3ac317 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c @@ -613,7 +613,6 @@ static struct ieee80211_rate mwifiex_rates[] = { {.bitrate = 20, .hw_value = 4, }, {.bitrate = 55, .hw_value = 11, }, {.bitrate = 110, .hw_value = 22, }, - {.bitrate = 220, .hw_value = 44, }, {.bitrate = 60, .hw_value = 12, }, {.bitrate = 90, .hw_value = 18, }, {.bitrate = 120, .hw_value = 24, }, @@ -622,7 +621,6 @@ static struct ieee80211_rate mwifiex_rates[] = { {.bitrate = 360, .hw_value = 72, }, {.bitrate = 480, .hw_value = 96, }, {.bitrate = 540, .hw_value = 108, }, - {.bitrate = 720, .hw_value = 144, }, }; /* Channel definitions to be advertised to cfg80211 */ @@ -688,8 +686,8 @@ static struct ieee80211_channel mwifiex_channels_5ghz[] = { static struct ieee80211_supported_band mwifiex_band_5ghz = { .channels = mwifiex_channels_5ghz, .n_channels = ARRAY_SIZE(mwifiex_channels_5ghz), - .bitrates = mwifiex_rates - 4, - .n_bitrates = ARRAY_SIZE(mwifiex_rates) + 4, + .bitrates = mwifiex_rates + 4, + .n_bitrates = ARRAY_SIZE(mwifiex_rates) - 4, }; -- cgit From b9be5f39bdabb25708a9de294c2cae7bdd8dfb17 Mon Sep 17 00:00:00 2001 From: Amitkumar Karwar Date: Mon, 27 Feb 2012 22:04:14 -0800 Subject: mwifiex: remove unnecessary struct mwifiex_802_11_ssid Use struct cfg80211_ssid available in include/net/cfg80211.h instead of having similar definition in driver. Signed-off-by: Amitkumar Karwar Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/cfg80211.c | 4 ++-- drivers/net/wireless/mwifiex/decl.h | 5 ----- drivers/net/wireless/mwifiex/ioctl.h | 4 ++-- drivers/net/wireless/mwifiex/join.c | 4 ++-- drivers/net/wireless/mwifiex/main.h | 15 +++++++-------- drivers/net/wireless/mwifiex/scan.c | 7 +++---- drivers/net/wireless/mwifiex/sta_event.c | 2 +- drivers/net/wireless/mwifiex/sta_ioctl.c | 5 ++--- 8 files changed, 19 insertions(+), 27 deletions(-) diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index 55293a3ac317..6a91c2fa89fe 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c @@ -839,12 +839,12 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid, u8 *bssid, int mode, struct ieee80211_channel *channel, struct cfg80211_connect_params *sme, bool privacy) { - struct mwifiex_802_11_ssid req_ssid; + struct cfg80211_ssid req_ssid; int ret, auth_type = 0; struct cfg80211_bss *bss = NULL; u8 is_scanning_required = 0; - memset(&req_ssid, 0, sizeof(struct mwifiex_802_11_ssid)); + memset(&req_ssid, 0, sizeof(struct cfg80211_ssid)); req_ssid.ssid_len = ssid_len; if (ssid_len > IEEE80211_MAX_SSID_LEN) { diff --git a/drivers/net/wireless/mwifiex/decl.h b/drivers/net/wireless/mwifiex/decl.h index 3735c775495c..be5fd1652e53 100644 --- a/drivers/net/wireless/mwifiex/decl.h +++ b/drivers/net/wireless/mwifiex/decl.h @@ -91,11 +91,6 @@ struct mwifiex_fw_image { u32 fw_len; }; -struct mwifiex_802_11_ssid { - u32 ssid_len; - u8 ssid[IEEE80211_MAX_SSID_LEN]; -}; - struct mwifiex_wait_queue { wait_queue_head_t wait; int status; diff --git a/drivers/net/wireless/mwifiex/ioctl.h b/drivers/net/wireless/mwifiex/ioctl.h index d5d81f1fe41c..7ca4e8234f3e 100644 --- a/drivers/net/wireless/mwifiex/ioctl.h +++ b/drivers/net/wireless/mwifiex/ioctl.h @@ -50,7 +50,7 @@ struct mwifiex_chan_freq { }; struct mwifiex_ssid_bssid { - struct mwifiex_802_11_ssid ssid; + struct cfg80211_ssid ssid; u8 bssid[ETH_ALEN]; }; @@ -122,7 +122,7 @@ struct mwifiex_ver_ext { struct mwifiex_bss_info { u32 bss_mode; - struct mwifiex_802_11_ssid ssid; + struct cfg80211_ssid ssid; u32 bss_chan; u32 region_code; u32 media_connected; diff --git a/drivers/net/wireless/mwifiex/join.c b/drivers/net/wireless/mwifiex/join.c index 5c95e4839004..bce9991612c8 100644 --- a/drivers/net/wireless/mwifiex/join.c +++ b/drivers/net/wireless/mwifiex/join.c @@ -714,7 +714,7 @@ done: int mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv, struct host_cmd_ds_command *cmd, - struct mwifiex_802_11_ssid *req_ssid) + struct cfg80211_ssid *req_ssid) { int rsn_ie_len = 0; struct mwifiex_adapter *adapter = priv->adapter; @@ -1245,7 +1245,7 @@ int mwifiex_associate(struct mwifiex_private *priv, */ int mwifiex_adhoc_start(struct mwifiex_private *priv, - struct mwifiex_802_11_ssid *adhoc_ssid) + struct cfg80211_ssid *adhoc_ssid) { dev_dbg(priv->adapter->dev, "info: Adhoc Channel = %d\n", priv->adhoc_channel); diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h index dddb5563398a..a0bd4ebd262a 100644 --- a/drivers/net/wireless/mwifiex/main.h +++ b/drivers/net/wireless/mwifiex/main.h @@ -244,7 +244,7 @@ struct ieee_types_generic { struct mwifiex_bssdescriptor { u8 mac_address[ETH_ALEN]; - struct mwifiex_802_11_ssid ssid; + struct cfg80211_ssid ssid; u32 privacy; s32 rssi; u32 channel; @@ -388,7 +388,7 @@ struct mwifiex_private { s16 bcn_rssi_avg; s16 bcn_nf_avg; struct mwifiex_bssdescriptor *attempted_bss_desc; - struct mwifiex_802_11_ssid prev_ssid; + struct cfg80211_ssid prev_ssid; u8 prev_bssid[ETH_ALEN]; struct mwifiex_current_bss_params curr_bss_params; u16 beacon_period; @@ -747,8 +747,7 @@ void mwifiex_queue_scan_cmd(struct mwifiex_private *priv, struct cmd_ctrl_node *cmd_node); int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, struct host_cmd_ds_command *resp); -s32 mwifiex_ssid_cmp(struct mwifiex_802_11_ssid *ssid1, - struct mwifiex_802_11_ssid *ssid2); +s32 mwifiex_ssid_cmp(struct cfg80211_ssid *ssid1, struct cfg80211_ssid *ssid2); int mwifiex_associate(struct mwifiex_private *priv, struct mwifiex_bssdescriptor *bss_desc); int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv, @@ -760,12 +759,12 @@ void mwifiex_reset_connect_state(struct mwifiex_private *priv); u8 mwifiex_band_to_radio_type(u8 band); int mwifiex_deauthenticate(struct mwifiex_private *priv, u8 *mac); int mwifiex_adhoc_start(struct mwifiex_private *priv, - struct mwifiex_802_11_ssid *adhoc_ssid); + struct cfg80211_ssid *adhoc_ssid); int mwifiex_adhoc_join(struct mwifiex_private *priv, struct mwifiex_bssdescriptor *bss_desc); int mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv, struct host_cmd_ds_command *cmd, - struct mwifiex_802_11_ssid *req_ssid); + struct cfg80211_ssid *req_ssid); int mwifiex_cmd_802_11_ad_hoc_join(struct mwifiex_private *priv, struct host_cmd_ds_command *cmd, struct mwifiex_bssdescriptor *bss_desc); @@ -898,7 +897,7 @@ int mwifiex_copy_mcast_addr(struct mwifiex_multicast_list *mlist, struct net_device *dev); int mwifiex_wait_queue_complete(struct mwifiex_adapter *adapter); int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss, - struct mwifiex_802_11_ssid *req_ssid); + struct cfg80211_ssid *req_ssid); int mwifiex_cancel_hs(struct mwifiex_private *priv, int cmd_type); int mwifiex_enable_hs(struct mwifiex_adapter *adapter); int mwifiex_disable_auto_ds(struct mwifiex_private *priv); @@ -907,7 +906,7 @@ int mwifiex_get_signal_info(struct mwifiex_private *priv, int mwifiex_drv_get_data_rate(struct mwifiex_private *priv, struct mwifiex_rate_cfg *rate); int mwifiex_request_scan(struct mwifiex_private *priv, - struct mwifiex_802_11_ssid *req_ssid); + struct cfg80211_ssid *req_ssid); int mwifiex_set_user_scan_ioctl(struct mwifiex_private *priv, struct mwifiex_user_scan_cfg *scan_req); int mwifiex_change_adhoc_chan(struct mwifiex_private *priv, int channel); diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c index 8f10038d1b45..67422f64f9fe 100644 --- a/drivers/net/wireless/mwifiex/scan.c +++ b/drivers/net/wireless/mwifiex/scan.c @@ -163,8 +163,7 @@ mwifiex_is_wpa_oui_present(struct mwifiex_bssdescriptor *bss_desc, u32 cipher) * This function compares two SSIDs and checks if they match. */ s32 -mwifiex_ssid_cmp(struct mwifiex_802_11_ssid *ssid1, - struct mwifiex_802_11_ssid *ssid2) +mwifiex_ssid_cmp(struct cfg80211_ssid *ssid1, struct cfg80211_ssid *ssid2) { if (!ssid1 || !ssid2 || (ssid1->ssid_len != ssid2->ssid_len)) return -1; @@ -1851,7 +1850,7 @@ mwifiex_queue_scan_cmd(struct mwifiex_private *priv, * firmware, filtered on a specific SSID. */ static int mwifiex_scan_specific_ssid(struct mwifiex_private *priv, - struct mwifiex_802_11_ssid *req_ssid) + struct cfg80211_ssid *req_ssid) { struct mwifiex_adapter *adapter = priv->adapter; int ret = 0; @@ -1896,7 +1895,7 @@ static int mwifiex_scan_specific_ssid(struct mwifiex_private *priv, * scan, depending upon whether an SSID is provided or not. */ int mwifiex_request_scan(struct mwifiex_private *priv, - struct mwifiex_802_11_ssid *req_ssid) + struct cfg80211_ssid *req_ssid) { int ret; diff --git a/drivers/net/wireless/mwifiex/sta_event.c b/drivers/net/wireless/mwifiex/sta_event.c index d7aa21da84d0..b9b59db60454 100644 --- a/drivers/net/wireless/mwifiex/sta_event.c +++ b/drivers/net/wireless/mwifiex/sta_event.c @@ -101,7 +101,7 @@ mwifiex_reset_connect_state(struct mwifiex_private *priv) memcpy(&priv->prev_ssid, &priv->curr_bss_params.bss_descriptor.ssid, - sizeof(struct mwifiex_802_11_ssid)); + sizeof(struct cfg80211_ssid)); memcpy(priv->prev_bssid, priv->curr_bss_params.bss_descriptor.mac_address, ETH_ALEN); diff --git a/drivers/net/wireless/mwifiex/sta_ioctl.c b/drivers/net/wireless/mwifiex/sta_ioctl.c index e10161f5894c..593d285111d2 100644 --- a/drivers/net/wireless/mwifiex/sta_ioctl.c +++ b/drivers/net/wireless/mwifiex/sta_ioctl.c @@ -192,7 +192,7 @@ int mwifiex_fill_new_bss_desc(struct mwifiex_private *priv, * first. */ int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss, - struct mwifiex_802_11_ssid *req_ssid) + struct cfg80211_ssid *req_ssid) { int ret; struct mwifiex_adapter *adapter = priv->adapter; @@ -464,8 +464,7 @@ int mwifiex_get_bss_info(struct mwifiex_private *priv, info->bss_mode = priv->bss_mode; - memcpy(&info->ssid, &bss_desc->ssid, - sizeof(struct mwifiex_802_11_ssid)); + memcpy(&info->ssid, &bss_desc->ssid, sizeof(struct cfg80211_ssid)); memcpy(&info->bssid, &bss_desc->mac_address, ETH_ALEN); -- cgit From be0b281e8f7afd56d2250a568b85dafc850bc9ae Mon Sep 17 00:00:00 2001 From: Amitkumar Karwar Date: Mon, 27 Feb 2012 22:04:15 -0800 Subject: mwifiex: fix bug in wildcard scan handling Currently if valid SSID list is provided in scan request, driver performs specific SSID scan otherwise wildcard scan is chosen. When wpa_supplicant provides valid SSID list followed by zero-length SSID for wildcard scan, only specific SSID scan is performed by driver. Actually driver is expected to do both type of scanning in this case. The patch fixes this issue. Also, use SSID list pointer provided by stack directly, instead of copying SSID's to local structure. Signed-off-by: Amitkumar Karwar Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/cfg80211.c | 10 ++++----- drivers/net/wireless/mwifiex/fw.h | 10 +++------ drivers/net/wireless/mwifiex/scan.c | 40 ++++++++++++++++----------------- 3 files changed, 27 insertions(+), 33 deletions(-) diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index 6a91c2fa89fe..b4890a01ba92 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c @@ -1106,12 +1106,10 @@ mwifiex_cfg80211_scan(struct wiphy *wiphy, struct net_device *dev, dev_err(priv->adapter->dev, "failed to alloc scan_req\n"); return -ENOMEM; } - for (i = 0; i < request->n_ssids; i++) { - memcpy(priv->user_scan_cfg->ssid_list[i].ssid, - request->ssids[i].ssid, request->ssids[i].ssid_len); - priv->user_scan_cfg->ssid_list[i].max_len = - request->ssids[i].ssid_len; - } + + priv->user_scan_cfg->num_ssids = request->n_ssids; + priv->user_scan_cfg->ssid_list = request->ssids; + for (i = 0; i < request->n_channels; i++) { chan = request->channels[i]; priv->user_scan_cfg->chan_list[i].chan_number = chan->hw_value; diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h index c82620094a53..fc4ffee6c6b9 100644 --- a/drivers/net/wireless/mwifiex/fw.h +++ b/drivers/net/wireless/mwifiex/fw.h @@ -852,11 +852,6 @@ struct mwifiex_user_scan_chan { u32 scan_time; } __packed; -struct mwifiex_user_scan_ssid { - u8 ssid[IEEE80211_MAX_SSID_LEN + 1]; - u8 max_len; -} __packed; - struct mwifiex_user_scan_cfg { /* * BSS mode to be sent in the firmware command @@ -867,8 +862,9 @@ struct mwifiex_user_scan_cfg { u8 reserved; /* BSSID filter sent in the firmware command to limit the results */ u8 specific_bssid[ETH_ALEN]; - /* SSID filter list used in the to limit the scan results */ - struct mwifiex_user_scan_ssid ssid_list[MWIFIEX_MAX_SSID_LIST_LENGTH]; + /* SSID filter list used in the firmware to limit the scan results */ + struct cfg80211_ssid *ssid_list; + u8 num_ssids; /* Variable number (fixed maximum) of channels to scan up */ struct mwifiex_user_scan_chan chan_list[MWIFIEX_USER_SCAN_CHAN_MAX]; } __packed; diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c index 67422f64f9fe..fd0302fe5bd8 100644 --- a/drivers/net/wireless/mwifiex/scan.c +++ b/drivers/net/wireless/mwifiex/scan.c @@ -737,7 +737,7 @@ mwifiex_scan_setup_scan_config(struct mwifiex_private *priv, u16 scan_dur; u8 channel; u8 radio_type; - u32 ssid_idx; + int i; u8 ssid_filter; u8 rates[MWIFIEX_SUPPORTED_RATES]; u32 rates_size; @@ -792,14 +792,8 @@ mwifiex_scan_setup_scan_config(struct mwifiex_private *priv, user_scan_in->specific_bssid, sizeof(scan_cfg_out->specific_bssid)); - for (ssid_idx = 0; - ((ssid_idx < ARRAY_SIZE(user_scan_in->ssid_list)) - && (*user_scan_in->ssid_list[ssid_idx].ssid - || user_scan_in->ssid_list[ssid_idx].max_len)); - ssid_idx++) { - - ssid_len = strlen(user_scan_in->ssid_list[ssid_idx]. - ssid) + 1; + for (i = 0; i < user_scan_in->num_ssids; i++) { + ssid_len = user_scan_in->ssid_list[i].ssid_len; wildcard_ssid_tlv = (struct mwifiex_ie_types_wildcard_ssid_params *) @@ -810,19 +804,26 @@ mwifiex_scan_setup_scan_config(struct mwifiex_private *priv, (u16) (ssid_len + sizeof(wildcard_ssid_tlv-> max_ssid_length))); - /* max_ssid_length = 0 tells firmware to perform - specific scan for the SSID filled */ - wildcard_ssid_tlv->max_ssid_length = 0; + /* + * max_ssid_length = 0 tells firmware to perform + * specific scan for the SSID filled, whereas + * max_ssid_length = IEEE80211_MAX_SSID_LEN is for + * wildcard scan. + */ + if (ssid_len) + wildcard_ssid_tlv->max_ssid_length = 0; + else + wildcard_ssid_tlv->max_ssid_length = + IEEE80211_MAX_SSID_LEN; memcpy(wildcard_ssid_tlv->ssid, - user_scan_in->ssid_list[ssid_idx].ssid, - ssid_len); + user_scan_in->ssid_list[i].ssid, ssid_len); tlv_pos += (sizeof(wildcard_ssid_tlv->header) + le16_to_cpu(wildcard_ssid_tlv->header.len)); - dev_dbg(adapter->dev, "info: scan: ssid_list[%d]: %s, %d\n", - ssid_idx, wildcard_ssid_tlv->ssid, + dev_dbg(adapter->dev, "info: scan: ssid[%d]: %s, %d\n", + i, wildcard_ssid_tlv->ssid, wildcard_ssid_tlv->max_ssid_length); /* Empty wildcard ssid with a maxlen will match many or @@ -831,7 +832,6 @@ mwifiex_scan_setup_scan_config(struct mwifiex_private *priv, filtered. */ if (!ssid_len && wildcard_ssid_tlv->max_ssid_length) ssid_filter = false; - } /* @@ -840,7 +840,7 @@ mwifiex_scan_setup_scan_config(struct mwifiex_private *priv, * truncate scan results. That is not an issue with an SSID * or BSSID filter applied to the scan results in the firmware. */ - if ((ssid_idx && ssid_filter) + if ((i && ssid_filter) || memcmp(scan_cfg_out->specific_bssid, &zero_mac, sizeof(zero_mac))) *filtered_scan = true; @@ -1876,8 +1876,8 @@ static int mwifiex_scan_specific_ssid(struct mwifiex_private *priv, return -ENOMEM; } - memcpy(scan_cfg->ssid_list[0].ssid, req_ssid->ssid, - req_ssid->ssid_len); + scan_cfg->ssid_list = req_ssid; + scan_cfg->num_ssids = 1; ret = mwifiex_scan_networks(priv, scan_cfg); -- cgit From 3d045a54488b69b0024309b18da5024c036c3152 Mon Sep 17 00:00:00 2001 From: Chun-Yeow Yeoh Date: Tue, 28 Feb 2012 22:00:06 +0800 Subject: mac80211: Fix the generation of PREQs in proactive RANN mechanism of HWMP According to Section Y.7.4 Actions on receipt of proactive RANN, an individually addressed PREQ should be generated towards the neighbor peer mesh STA indicated in the RANN Sender Address field in the forwarding information. Signed-off-by: Chun-Yeow Yeoh Signed-off-by: Javier Cardona Signed-off-by: Thomas Pedersen Signed-off-by: John W. Linville --- net/mac80211/mesh.h | 4 ++++ net/mac80211/mesh_hwmp.c | 20 +++++++++++++++----- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h index c7e5c49471e5..8d53b71378e3 100644 --- a/net/mac80211/mesh.h +++ b/net/mac80211/mesh.h @@ -85,6 +85,8 @@ enum mesh_deferred_task_flags { * @state_lock: mesh path state lock used to protect changes to the * mpath itself. No need to take this lock when adding or removing * an mpath to a hash bucket on a path table. + * @rann_snd_addr: the RANN sender address + * @is_root: the destination station of this path is a root node * @is_gate: the destination station of this path is a mesh gate * * @@ -109,6 +111,8 @@ struct mesh_path { u8 discovery_retries; enum mesh_path_flags flags; spinlock_t state_lock; + u8 rann_snd_addr[ETH_ALEN]; + bool is_root; bool is_gate; }; diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c index 31bc762f209d..639db14f43d2 100644 --- a/net/mac80211/mesh_hwmp.c +++ b/net/mac80211/mesh_hwmp.c @@ -513,8 +513,9 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata, u8 *preq_elem, u32 metric) { struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; - struct mesh_path *mpath; + struct mesh_path *mpath = NULL; u8 *target_addr, *orig_addr; + const u8 *da; u8 target_flags, ttl; u32 orig_sn, target_sn, lifetime; bool reply = false; @@ -591,9 +592,11 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata, flags = PREQ_IE_FLAGS(preq_elem); preq_id = PREQ_IE_PREQ_ID(preq_elem); hopcount = PREQ_IE_HOPCOUNT(preq_elem) + 1; + da = (mpath && mpath->is_root) ? + mpath->rann_snd_addr : broadcast_addr; mesh_path_sel_frame_tx(MPATH_PREQ, flags, orig_addr, cpu_to_le32(orig_sn), target_flags, target_addr, - cpu_to_le32(target_sn), broadcast_addr, + cpu_to_le32(target_sn), da, hopcount, ttl, cpu_to_le32(lifetime), cpu_to_le32(metric), cpu_to_le32(preq_id), sdata); @@ -742,8 +745,8 @@ static void hwmp_rann_frame_process(struct ieee80211_sub_if_data *sdata, if (memcmp(orig_addr, sdata->vif.addr, ETH_ALEN) == 0) return; - mhwmp_dbg("received RANN from %pM (is_gate=%d)", orig_addr, - root_is_gate); + mhwmp_dbg("received RANN from %pM via neighbour %pM (is_gate=%d)", + orig_addr, mgmt->sa, root_is_gate); rcu_read_lock(); mpath = mesh_path_lookup(orig_addr, sdata); @@ -774,6 +777,11 @@ static void hwmp_rann_frame_process(struct ieee80211_sub_if_data *sdata, 0, sdata); mpath->sn = orig_sn; } + + /* Using individually addressed PREQ for root node */ + memcpy(mpath->rann_snd_addr, mgmt->sa, ETH_ALEN); + mpath->is_root = true; + if (root_is_gate) mesh_path_add_gate(mpath); @@ -909,6 +917,7 @@ void mesh_path_start_discovery(struct ieee80211_sub_if_data *sdata) struct mesh_preq_queue *preq_node; struct mesh_path *mpath; u8 ttl, target_flags; + const u8 *da; u32 lifetime; spin_lock_bh(&ifmsh->mesh_preq_queue_lock); @@ -971,9 +980,10 @@ void mesh_path_start_discovery(struct ieee80211_sub_if_data *sdata) target_flags = MP_F_RF; spin_unlock_bh(&mpath->state_lock); + da = (mpath->is_root) ? mpath->rann_snd_addr : broadcast_addr; mesh_path_sel_frame_tx(MPATH_PREQ, 0, sdata->vif.addr, cpu_to_le32(ifmsh->sn), target_flags, mpath->dst, - cpu_to_le32(mpath->sn), broadcast_addr, 0, + cpu_to_le32(mpath->sn), da, 0, ttl, cpu_to_le32(lifetime), 0, cpu_to_le32(ifmsh->preq_id++), sdata); mod_timer(&mpath->timer, jiffies + mpath->discovery_timeout); -- cgit From d53c74e5a124b0aaed7e9b5c462d1806aad54757 Mon Sep 17 00:00:00 2001 From: Mohammed Shafi Shajakhan Date: Tue, 28 Feb 2012 20:54:43 +0530 Subject: ath9k: completely zero intialize valid_phy_rate_idx its better to zero initialize the 'valid_phy_rate_idx' array completely Signed-off-by: Mohammed Shafi Shajakhan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/rc.c | 2 +- drivers/net/wireless/ath/ath9k/rc.h | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c index b8c6c38cbb98..6407af22f7b9 100644 --- a/drivers/net/wireless/ath/ath9k/rc.c +++ b/drivers/net/wireless/ath/ath9k/rc.c @@ -1226,7 +1226,7 @@ static void ath_rc_init(struct ath_softc *sc, ath_rc_init_valid_rate_idx(ath_rc_priv); for (i = 0; i < WLAN_RC_PHY_MAX; i++) { - for (j = 0; j < MAX_TX_RATE_PHY; j++) + for (j = 0; j < RATE_TABLE_SIZE; j++) ath_rc_priv->valid_phy_rateidx[i][j] = 0; ath_rc_priv->valid_phy_ratecnt[i] = 0; } diff --git a/drivers/net/wireless/ath/ath9k/rc.h b/drivers/net/wireless/ath/ath9k/rc.h index b7a4bcd3eec7..75f8e9b06b28 100644 --- a/drivers/net/wireless/ath/ath9k/rc.h +++ b/drivers/net/wireless/ath/ath9k/rc.h @@ -25,8 +25,6 @@ struct ath_softc; #define ATH_RATE_MAX 30 #define RATE_TABLE_SIZE 72 -#define MAX_TX_RATE_PHY 48 - #define RC_INVALID 0x0000 #define RC_LEGACY 0x0001 -- cgit From 6a01f0c08d20a2b1356c1cb90ef97a0dc412b64c Mon Sep 17 00:00:00 2001 From: Mohammed Shafi Shajakhan Date: Tue, 28 Feb 2012 20:54:44 +0530 Subject: ath9k: make use of list_for_each_entry_safe this does the same thing as the previous code Signed-off-by: Mohammed Shafi Shajakhan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/recv.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index 7e1a91af1497..4633f513a80b 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c @@ -169,22 +169,17 @@ static void ath_rx_addbuffer_edma(struct ath_softc *sc, enum ath9k_rx_qtype qtype, int size) { struct ath_common *common = ath9k_hw_common(sc->sc_ah); - u32 nbuf = 0; + struct ath_buf *bf, *tbf; if (list_empty(&sc->rx.rxbuf)) { ath_dbg(common, QUEUE, "No free rx buf available\n"); return; } - while (!list_empty(&sc->rx.rxbuf)) { - nbuf++; - + list_for_each_entry_safe(bf, tbf, &sc->rx.rxbuf, list) if (!ath_rx_edma_buf_link(sc, qtype)) break; - if (nbuf >= size) - break; - } } static void ath_rx_remove_buffer(struct ath_softc *sc, -- cgit From 5809802180b2b638762465cbad3f51a9ac8ff0b3 Mon Sep 17 00:00:00 2001 From: Hauke Mehrtens Date: Tue, 28 Feb 2012 20:45:06 +0100 Subject: b43: prevent firmware on bcm5354 from taking over wrong GPIO pins When using the bcm5354 (Soc with integrated LP-PHY Wifi) with a recent firmware >= 478.104 it runs out of memory after a very short time in OpenWrt after doing an active scan or any thing else where packages are send. This was cased by a gpio misconfiguration, the firmware triggered the GPIO pins used for buttons on some devices and that caused an other driver (OpenWrt diag) listening for these buttons irqs to send many messages to the user space. This patch fixes the bug for my devices (Asus WL-520GU) and makes it work with firmware 666.2. Now the firmware just uses LED GPIO pin number 1 and not the button pins any more. This is the GPIO Pin layout used on my device, see [0]. GPIO pin layout: pin# name type 0 power led 1 wlan led 2 reset button 3 ses buttom This is the nvram configuration output of "nvram show |grep gpio" related nvram configuration: wl0gpio2=11 wl0gpio3=11 wl0gpio0=11 wl0gpio1=0x02 reset_gpio=2 [0]: https://dev.openwrt.org/browser/trunk/package/broadcom-diag/src/diag.c Signed-off-by: Hauke Mehrtens Signed-off-by: John W. Linville --- drivers/net/wireless/b43/main.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index 5189cf38123a..1d633f3b3274 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -2706,6 +2706,8 @@ static int b43_gpio_init(struct b43_wldev *dev) mask |= 0x0060; set |= 0x0060; } + if (dev->dev->chip_id == 0x5354) + set &= 0xff02; if (0 /* FIXME: conditional unknown */ ) { b43_write16(dev, B43_MMIO_GPIO_MASK, b43_read16(dev, B43_MMIO_GPIO_MASK) -- cgit From 5533513784a88049e19dd2ab380a452b61e5171e Mon Sep 17 00:00:00 2001 From: Ashok Nagarajan Date: Tue, 28 Feb 2012 17:04:08 -0800 Subject: {nl,cfg,mac}80211: Implement RSSI threshold for mesh peering Mesh peer links are established only if average rssi of the peer candidate satisfies the threshold. This is not in 802.11s specification but was requested by David Fulgham, an open80211s user. This is a way to avoid marginal peer links with stations that are barely within range. This patch adds a new mesh configuration parameter, mesh_rssi_threshold. This feature is supported only for hardwares that report signal in dBm. Signed-off-by: Ashok Nagarajan Signed-off-by: Javier Cardona Signed-off-by: John W. Linville --- include/linux/nl80211.h | 5 +++++ include/net/cfg80211.h | 1 + net/mac80211/cfg.c | 8 ++++++++ net/mac80211/debugfs_netdev.c | 2 ++ net/mac80211/mesh_plink.c | 16 +++++++++++++++- net/wireless/mesh.c | 3 +++ net/wireless/nl80211.c | 5 +++++ 7 files changed, 39 insertions(+), 1 deletion(-) diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h index be35a68746a7..38fda5ee57f5 100644 --- a/include/linux/nl80211.h +++ b/include/linux/nl80211.h @@ -2112,6 +2112,10 @@ enum nl80211_mntr_flags { * @NL80211_MESHCONF_FORWARDING: set Mesh STA as forwarding or non-forwarding * or forwarding entity (default is TRUE - forwarding entity) * + * @NL80211_MESHCONF_RSSI_THRESHOLD: RSSI threshold in dBm. This specifies the + * threshold for average signal strength of candidate station to establish + * a peer link. + * * @NL80211_MESHCONF_ATTR_MAX: highest possible mesh configuration attribute * * @__NL80211_MESHCONF_ATTR_AFTER_LAST: internal use @@ -2137,6 +2141,7 @@ enum nl80211_meshconf_params { NL80211_MESHCONF_GATE_ANNOUNCEMENTS, NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL, NL80211_MESHCONF_FORWARDING, + NL80211_MESHCONF_RSSI_THRESHOLD, /* keep last */ __NL80211_MESHCONF_ATTR_AFTER_LAST, diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 0178c7489373..b4e015c90885 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -809,6 +809,7 @@ struct mesh_config { * Still keeping the same nomenclature to be in sync with the spec. */ bool dot11MeshGateAnnouncementProtocol; bool dot11MeshForwarding; + s32 rssi_threshold; }; /** diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 6a77d4c910f9..ab31cc56a2fb 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -1314,6 +1314,14 @@ static int ieee80211_update_mesh_config(struct wiphy *wiphy, } if (_chg_mesh_attr(NL80211_MESHCONF_FORWARDING, mask)) conf->dot11MeshForwarding = nconf->dot11MeshForwarding; + if (_chg_mesh_attr(NL80211_MESHCONF_RSSI_THRESHOLD, mask)) { + /* our RSSI threshold implementation is supported only for + * devices that report signal in dBm. + */ + if (!(sdata->local->hw.flags & IEEE80211_HW_SIGNAL_DBM)) + return -ENOTSUPP; + conf->rssi_threshold = nconf->rssi_threshold; + } return 0; } diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c index 510ed1dab3c7..9f484d8905fd 100644 --- a/net/mac80211/debugfs_netdev.c +++ b/net/mac80211/debugfs_netdev.c @@ -443,6 +443,7 @@ IEEE80211_IF_FILE(dot11MeshGateAnnouncementProtocol, IEEE80211_IF_FILE(dot11MeshHWMPRannInterval, u.mesh.mshcfg.dot11MeshHWMPRannInterval, DEC); IEEE80211_IF_FILE(dot11MeshForwarding, u.mesh.mshcfg.dot11MeshForwarding, DEC); +IEEE80211_IF_FILE(rssi_threshold, u.mesh.mshcfg.rssi_threshold, DEC); #endif @@ -581,6 +582,7 @@ static void add_mesh_config(struct ieee80211_sub_if_data *sdata) MESHPARAMS_ADD(dot11MeshHWMPRootMode); MESHPARAMS_ADD(dot11MeshHWMPRannInterval); MESHPARAMS_ADD(dot11MeshGateAnnouncementProtocol); + MESHPARAMS_ADD(rssi_threshold); #undef MESHPARAMS_ADD } #endif diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c index 8806e5ef8ffe..80ce52772538 100644 --- a/net/mac80211/mesh_plink.c +++ b/net/mac80211/mesh_plink.c @@ -31,6 +31,11 @@ #define dot11MeshHoldingTimeout(s) (s->u.mesh.mshcfg.dot11MeshHoldingTimeout) #define dot11MeshMaxPeerLinks(s) (s->u.mesh.mshcfg.dot11MeshMaxPeerLinks) +#define sta_meets_rssi_threshold(sta, sdata) \ + (sdata->u.mesh.mshcfg.rssi_threshold == 0 ||\ + (s8) -ewma_read(&sta->avg_signal) > \ + sdata->u.mesh.mshcfg.rssi_threshold) + enum plink_event { PLINK_UNDEFINED, OPN_ACPT, @@ -301,7 +306,8 @@ void mesh_neighbour_update(u8 *hw_addr, u32 rates, if (mesh_peer_accepts_plinks(elems) && sta->plink_state == NL80211_PLINK_LISTEN && sdata->u.mesh.accepting_plinks && - sdata->u.mesh.mshcfg.auto_open_plinks) + sdata->u.mesh.mshcfg.auto_open_plinks && + sta_meets_rssi_threshold(sta, sdata)) mesh_plink_open(sta); rcu_read_unlock(); @@ -531,6 +537,14 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m return; } + if (ftype == WLAN_SP_MESH_PEERING_OPEN && + !sta_meets_rssi_threshold(sta, sdata)) { + mpl_dbg("Mesh plink: %pM does not meet rssi threshold\n", + sta->sta.addr); + rcu_read_unlock(); + return; + } + if (sta && !test_sta_flag(sta, WLAN_STA_AUTH)) { mpl_dbg("Mesh plink: Action frame from non-authed peer\n"); rcu_read_unlock(); diff --git a/net/wireless/mesh.c b/net/wireless/mesh.c index 9d3e3b6bfcf4..ba21ab22187b 100644 --- a/net/wireless/mesh.c +++ b/net/wireless/mesh.c @@ -23,6 +23,8 @@ #define MESH_PERR_MIN_INT 100 #define MESH_DIAM_TRAVERSAL_TIME 50 +#define MESH_RSSI_THRESHOLD 0 + /* * A path will be refreshed if it is used PATH_REFRESH_TIME milliseconds * before timing out. This way it will remain ACTIVE and no data frames @@ -56,6 +58,7 @@ const struct mesh_config default_mesh_config = { .dot11MeshHWMPRannInterval = MESH_RANN_INTERVAL, .dot11MeshGateAnnouncementProtocol = false, .dot11MeshForwarding = true, + .rssi_threshold = MESH_RSSI_THRESHOLD, }; const struct mesh_setup default_mesh_setup = { diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 1998c3682774..25a470abd21d 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -3290,6 +3290,8 @@ static int nl80211_get_mesh_config(struct sk_buff *skb, cur_params.dot11MeshGateAnnouncementProtocol); NLA_PUT_U8(msg, NL80211_MESHCONF_FORWARDING, cur_params.dot11MeshForwarding); + NLA_PUT_U32(msg, NL80211_MESHCONF_RSSI_THRESHOLD, + cur_params.rssi_threshold); nla_nest_end(msg, pinfoattr); genlmsg_end(msg, hdr); return genlmsg_reply(msg, info); @@ -3322,6 +3324,7 @@ static const struct nla_policy nl80211_meshconf_params_policy[NL80211_MESHCONF_A [NL80211_MESHCONF_HWMP_RANN_INTERVAL] = { .type = NLA_U16 }, [NL80211_MESHCONF_GATE_ANNOUNCEMENTS] = { .type = NLA_U8 }, [NL80211_MESHCONF_FORWARDING] = { .type = NLA_U8 }, + [NL80211_MESHCONF_RSSI_THRESHOLD] = { .type = NLA_U32}, }; static const struct nla_policy @@ -3413,6 +3416,8 @@ do {\ nla_get_u8); FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshForwarding, mask, NL80211_MESHCONF_FORWARDING, nla_get_u8); + FILL_IN_MESH_PARAM_IF_SET(tb, cfg, rssi_threshold, + mask, NL80211_MESHCONF_RSSI_THRESHOLD, nla_get_u32); if (mask_out) *mask_out = mask; -- cgit From 41eedf39dfb145fb8fa04cd5b799f7bdc7679696 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 1 Mar 2012 10:02:08 +0300 Subject: rndis_wlan: integer overflows in rndis_wlan_do_link_up_work() If "offset" is negative then we can get past this check: if (offset > CONTROL_BUFFER_SIZE) Or if we pick a very high "req_ie_len" then we can get around the check: if (offset + req_ie_len > CONTROL_BUFFER_SIZE) I made "resp_ie_len" and "req_ie_len" unsigned. I don't know if it was intentional that they were signed in the original. Signed-off-by: Dan Carpenter Acked-by: Jussi Kivilinna Signed-off-by: John W. Linville --- drivers/net/wireless/rndis_wlan.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c index a330c69583d6..dde45effef14 100644 --- a/drivers/net/wireless/rndis_wlan.c +++ b/drivers/net/wireless/rndis_wlan.c @@ -2755,9 +2755,10 @@ static void rndis_wlan_do_link_up_work(struct usbnet *usbdev) struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); struct ndis_80211_assoc_info *info = NULL; u8 bssid[ETH_ALEN]; - int resp_ie_len, req_ie_len; + unsigned int resp_ie_len, req_ie_len; + unsigned int offset; u8 *req_ie, *resp_ie; - int ret, offset; + int ret; bool roamed = false; bool match_bss; @@ -2785,7 +2786,9 @@ static void rndis_wlan_do_link_up_work(struct usbnet *usbdev) ret = get_association_info(usbdev, info, CONTROL_BUFFER_SIZE); if (!ret) { req_ie_len = le32_to_cpu(info->req_ie_length); - if (req_ie_len > 0) { + if (req_ie_len > CONTROL_BUFFER_SIZE) + req_ie_len = CONTROL_BUFFER_SIZE; + if (req_ie_len != 0) { offset = le32_to_cpu(info->offset_req_ies); if (offset > CONTROL_BUFFER_SIZE) @@ -2799,7 +2802,9 @@ static void rndis_wlan_do_link_up_work(struct usbnet *usbdev) } resp_ie_len = le32_to_cpu(info->resp_ie_length); - if (resp_ie_len > 0) { + if (resp_ie_len > CONTROL_BUFFER_SIZE) + resp_ie_len = CONTROL_BUFFER_SIZE; + if (resp_ie_len != 0) { offset = le32_to_cpu(info->offset_resp_ies); if (offset > CONTROL_BUFFER_SIZE) -- cgit From b26e395038a219685c7f78f3be8aeb578c4a5b60 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 29 Feb 2012 09:36:28 +0300 Subject: rndis_wlan: remove unneeded variables We never use the "len" variable. Signed-off-by: Dan Carpenter Acked-by: Jussi Kivilinna Signed-off-by: John W. Linville --- drivers/net/wireless/rndis_wlan.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c index dde45effef14..1bde2eb54255 100644 --- a/drivers/net/wireless/rndis_wlan.c +++ b/drivers/net/wireless/rndis_wlan.c @@ -1790,9 +1790,8 @@ static struct ndis_80211_pmkid *remove_pmkid(struct usbnet *usbdev, struct cfg80211_pmksa *pmksa, int max_pmkids) { - int i, len, count, newlen, err; + int i, count, newlen, err; - len = le32_to_cpu(pmkids->length); count = le32_to_cpu(pmkids->bssid_info_count); if (count > max_pmkids) @@ -1831,9 +1830,8 @@ static struct ndis_80211_pmkid *update_pmkid(struct usbnet *usbdev, struct cfg80211_pmksa *pmksa, int max_pmkids) { - int i, err, len, count, newlen; + int i, err, count, newlen; - len = le32_to_cpu(pmkids->length); count = le32_to_cpu(pmkids->bssid_info_count); if (count > max_pmkids) -- cgit From 551d6fe6cb67ea6f7ca4425a5085b05d34f39730 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 29 Feb 2012 09:36:57 +0300 Subject: rndis_wlan: make some variables unsigned These variables can never be less than zero because we cap them in get_device_pmkids(). Let's make them unsigned here because it's simpler to not have to worry about negative numbers when we read the code. Signed-off-by: Dan Carpenter Acked-by: Jussi Kivilinna Signed-off-by: John W. Linville --- drivers/net/wireless/rndis_wlan.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c index 1bde2eb54255..454f2f182342 100644 --- a/drivers/net/wireless/rndis_wlan.c +++ b/drivers/net/wireless/rndis_wlan.c @@ -1790,7 +1790,8 @@ static struct ndis_80211_pmkid *remove_pmkid(struct usbnet *usbdev, struct cfg80211_pmksa *pmksa, int max_pmkids) { - int i, count, newlen, err; + int i, newlen, err; + unsigned int count; count = le32_to_cpu(pmkids->bssid_info_count); @@ -1830,7 +1831,8 @@ static struct ndis_80211_pmkid *update_pmkid(struct usbnet *usbdev, struct cfg80211_pmksa *pmksa, int max_pmkids) { - int i, err, count, newlen; + int i, err, newlen; + unsigned int count; count = le32_to_cpu(pmkids->bssid_info_count); -- cgit From e4e02da2ef01deb36aa80fce6ee0bc3e9725ffe8 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 29 Feb 2012 09:37:53 +0300 Subject: rndis_wlan: prevent integer overflow in indication() If we pick a high value for "offset" then it could lead to an integer overflow and we would get past the check for: if (offset + len > buflen) { ... Signed-off-by: Dan Carpenter Acked-by: Jussi Kivilinna Signed-off-by: John W. Linville --- drivers/net/wireless/rndis_wlan.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c index 454f2f182342..ce138d846193 100644 --- a/drivers/net/wireless/rndis_wlan.c +++ b/drivers/net/wireless/rndis_wlan.c @@ -3043,7 +3043,7 @@ static void rndis_wlan_media_specific_indication(struct usbnet *usbdev, struct rndis_indicate *msg, int buflen) { struct ndis_80211_status_indication *indication; - int len, offset; + unsigned int len, offset; offset = offsetof(struct rndis_indicate, status) + le32_to_cpu(msg->offset); @@ -3055,7 +3055,7 @@ static void rndis_wlan_media_specific_indication(struct usbnet *usbdev, return; } - if (offset + len > buflen) { + if (len > buflen || offset > buflen || offset + len > buflen) { netdev_info(usbdev->net, "media specific indication, too large to fit to buffer (%i > %i)\n", offset + len, buflen); return; -- cgit From f808e4ad05704d4ba0082fbb27640294c6fa4eae Mon Sep 17 00:00:00 2001 From: Jussi Kivilinna Date: Wed, 29 Feb 2012 16:24:54 +0200 Subject: rndis_wlan: fix le16/le32_to_cpu mix up with config.beacon_period 'beacon_period' in 'struct ndis_80211_conf' is __le32 instead of __le16 so le32_to_cpu must be used instead of le16_to_cpu. Also correct 'beacon_interval' variables used for passing this value forward from u16 to u32 and rename those variables 'beacon_period' This is to avoid confusion because 'beacon_interval' is defined as __le16 at other structure, 'struct ndis_80211_fixed_ies'. Reported-by: Dan Carpenter Signed-off-by: Jussi Kivilinna Signed-off-by: John W. Linville --- drivers/net/wireless/rndis_wlan.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c index ce138d846193..c831c1f2bd07 100644 --- a/drivers/net/wireless/rndis_wlan.c +++ b/drivers/net/wireless/rndis_wlan.c @@ -1350,7 +1350,7 @@ static int set_channel(struct usbnet *usbdev, int channel) } static struct ieee80211_channel *get_current_channel(struct usbnet *usbdev, - u16 *beacon_interval) + u32 *beacon_period) { struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); struct ieee80211_channel *channel; @@ -1370,8 +1370,8 @@ static struct ieee80211_channel *get_current_channel(struct usbnet *usbdev, if (!channel) return NULL; - if (beacon_interval) - *beacon_interval = le16_to_cpu(config.beacon_period); + if (beacon_period) + *beacon_period = le32_to_cpu(config.beacon_period); return channel; } @@ -2683,7 +2683,7 @@ static void rndis_wlan_craft_connected_bss(struct usbnet *usbdev, u8 *bssid, s32 signal; u64 timestamp; u16 capability; - u16 beacon_interval = 0; + u32 beacon_period = 0; __le32 rssi; u8 ie_buf[34]; int len, ret, ie_len; @@ -2708,7 +2708,7 @@ static void rndis_wlan_craft_connected_bss(struct usbnet *usbdev, u8 *bssid, } /* Get channel and beacon interval */ - channel = get_current_channel(usbdev, &beacon_interval); + channel = get_current_channel(usbdev, &beacon_period); if (!channel) { netdev_warn(usbdev->net, "%s(): could not get channel.\n", __func__); @@ -2738,11 +2738,11 @@ static void rndis_wlan_craft_connected_bss(struct usbnet *usbdev, u8 *bssid, netdev_dbg(usbdev->net, "%s(): channel:%d(freq), bssid:[%pM], tsf:%d, " "capa:%x, beacon int:%d, resp_ie(len:%d, essid:'%.32s'), " "signal:%d\n", __func__, (channel ? channel->center_freq : -1), - bssid, (u32)timestamp, capability, beacon_interval, ie_len, + bssid, (u32)timestamp, capability, beacon_period, ie_len, ssid.essid, signal); bss = cfg80211_inform_bss(priv->wdev.wiphy, channel, bssid, - timestamp, capability, beacon_interval, ie_buf, ie_len, + timestamp, capability, beacon_period, ie_buf, ie_len, signal, GFP_KERNEL); cfg80211_put_bss(bss); } -- cgit From f096ce6d244a380a78e19a7d7a25d9a4a6a6c9b7 Mon Sep 17 00:00:00 2001 From: Jussi Kivilinna Date: Wed, 29 Feb 2012 16:25:00 +0200 Subject: rndis_wlan: use RNDIS_WLAN_NUM_KEYS for all key index checks Use new RNDIS_WLAN_NUM_KEYS for checks in add_wep_key() and add_wpa_key(). Signed-off-by: Jussi Kivilinna Signed-off-by: John W. Linville --- drivers/net/wireless/rndis_wlan.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c index c831c1f2bd07..0e238400b046 100644 --- a/drivers/net/wireless/rndis_wlan.c +++ b/drivers/net/wireless/rndis_wlan.c @@ -1387,13 +1387,15 @@ static int add_wep_key(struct usbnet *usbdev, const u8 *key, int key_len, netdev_dbg(usbdev->net, "%s(idx: %d, len: %d)\n", __func__, index, key_len); - if ((key_len != 5 && key_len != 13) || index < 0 || index > 3) + if (index < 0 || index >= RNDIS_WLAN_NUM_KEYS) return -EINVAL; if (key_len == 5) cipher = WLAN_CIPHER_SUITE_WEP40; - else + else if (key_len == 13) cipher = WLAN_CIPHER_SUITE_WEP104; + else + return -EINVAL; memset(&ndis_key, 0, sizeof(ndis_key)); @@ -1436,7 +1438,7 @@ static int add_wpa_key(struct usbnet *usbdev, const u8 *key, int key_len, bool is_addr_ok; int ret; - if (index < 0 || index >= 4) { + if (index < 0 || index >= RNDIS_WLAN_NUM_KEYS) { netdev_dbg(usbdev->net, "%s(): index out of range (%i)\n", __func__, index); return -EINVAL; -- cgit From 461bc26c93f27d306a0e74cf642b33eb9d2d4112 Mon Sep 17 00:00:00 2001 From: Jussi Kivilinna Date: Wed, 29 Feb 2012 16:25:05 +0200 Subject: rndis_wlan: use u8 for key indexes cfg80211 uses u8 for key indexes and so should rndis_wlan. Signed-off-by: Jussi Kivilinna Signed-off-by: John W. Linville --- drivers/net/wireless/rndis_wlan.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c index 0e238400b046..d66e2980bc27 100644 --- a/drivers/net/wireless/rndis_wlan.c +++ b/drivers/net/wireless/rndis_wlan.c @@ -518,7 +518,7 @@ struct rndis_wlan_private { __le32 current_command_oid; /* encryption stuff */ - int encr_tx_key_index; + u8 encr_tx_key_index; struct rndis_wlan_encr_key encr_keys[RNDIS_WLAN_NUM_KEYS]; int wpa_version; @@ -634,7 +634,7 @@ static u32 get_bcm4320_power_dbm(struct rndis_wlan_private *priv) } } -static bool is_wpa_key(struct rndis_wlan_private *priv, int idx) +static bool is_wpa_key(struct rndis_wlan_private *priv, u8 idx) { int cipher = priv->encr_keys[idx].cipher; @@ -1377,7 +1377,7 @@ static struct ieee80211_channel *get_current_channel(struct usbnet *usbdev, /* index must be 0 - N, as per NDIS */ static int add_wep_key(struct usbnet *usbdev, const u8 *key, int key_len, - int index) + u8 index) { struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); struct ndis_80211_wep_key ndis_key; @@ -1387,7 +1387,7 @@ static int add_wep_key(struct usbnet *usbdev, const u8 *key, int key_len, netdev_dbg(usbdev->net, "%s(idx: %d, len: %d)\n", __func__, index, key_len); - if (index < 0 || index >= RNDIS_WLAN_NUM_KEYS) + if (index >= RNDIS_WLAN_NUM_KEYS) return -EINVAL; if (key_len == 5) @@ -1430,7 +1430,7 @@ static int add_wep_key(struct usbnet *usbdev, const u8 *key, int key_len, } static int add_wpa_key(struct usbnet *usbdev, const u8 *key, int key_len, - int index, const u8 *addr, const u8 *rx_seq, + u8 index, const u8 *addr, const u8 *rx_seq, int seq_len, u32 cipher, __le32 flags) { struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); @@ -1438,7 +1438,7 @@ static int add_wpa_key(struct usbnet *usbdev, const u8 *key, int key_len, bool is_addr_ok; int ret; - if (index < 0 || index >= RNDIS_WLAN_NUM_KEYS) { + if (index >= RNDIS_WLAN_NUM_KEYS) { netdev_dbg(usbdev->net, "%s(): index out of range (%i)\n", __func__, index); return -EINVAL; @@ -1526,7 +1526,7 @@ static int add_wpa_key(struct usbnet *usbdev, const u8 *key, int key_len, return 0; } -static int restore_key(struct usbnet *usbdev, int key_idx) +static int restore_key(struct usbnet *usbdev, u8 key_idx) { struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); struct rndis_wlan_encr_key key; @@ -1552,13 +1552,13 @@ static void restore_keys(struct usbnet *usbdev) restore_key(usbdev, i); } -static void clear_key(struct rndis_wlan_private *priv, int idx) +static void clear_key(struct rndis_wlan_private *priv, u8 idx) { memset(&priv->encr_keys[idx], 0, sizeof(priv->encr_keys[idx])); } /* remove_key is for both wep and wpa */ -static int remove_key(struct usbnet *usbdev, int index, const u8 *bssid) +static int remove_key(struct usbnet *usbdev, u8 index, const u8 *bssid) { struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); struct ndis_80211_remove_key remove_key; -- cgit From 62ebeed8d00aef75eac4fd6c161cae75a41965ca Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Thu, 1 Mar 2012 00:40:08 +0400 Subject: p54spi: Release GPIO lines and IRQ on error in p54spi_probe This makes it possible to reload driver if insmod has failed due to missing firmware. Signed-off-by: Max Filippov Cc: stable Acked-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/p54/p54spi.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/p54/p54spi.c b/drivers/net/wireless/p54/p54spi.c index 7faed62c6378..f7929906d437 100644 --- a/drivers/net/wireless/p54/p54spi.c +++ b/drivers/net/wireless/p54/p54spi.c @@ -618,19 +618,19 @@ static int __devinit p54spi_probe(struct spi_device *spi) ret = spi_setup(spi); if (ret < 0) { dev_err(&priv->spi->dev, "spi_setup failed"); - goto err_free_common; + goto err_free; } ret = gpio_request(p54spi_gpio_power, "p54spi power"); if (ret < 0) { dev_err(&priv->spi->dev, "power GPIO request failed: %d", ret); - goto err_free_common; + goto err_free; } ret = gpio_request(p54spi_gpio_irq, "p54spi irq"); if (ret < 0) { dev_err(&priv->spi->dev, "irq GPIO request failed: %d", ret); - goto err_free_common; + goto err_free_gpio_power; } gpio_direction_output(p54spi_gpio_power, 0); @@ -641,7 +641,7 @@ static int __devinit p54spi_probe(struct spi_device *spi) priv->spi); if (ret < 0) { dev_err(&priv->spi->dev, "request_irq() failed"); - goto err_free_common; + goto err_free_gpio_irq; } irq_set_irq_type(gpio_to_irq(p54spi_gpio_irq), IRQ_TYPE_EDGE_RISING); @@ -673,6 +673,12 @@ static int __devinit p54spi_probe(struct spi_device *spi) return 0; err_free_common: + free_irq(gpio_to_irq(p54spi_gpio_irq), spi); +err_free_gpio_irq: + gpio_free(p54spi_gpio_irq); +err_free_gpio_power: + gpio_free(p54spi_gpio_power); +err_free: p54_free_common(priv->hw); return ret; } -- cgit From 380aeef8941c6b8a3e8de86b5ca000ca986e3b17 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 1 Mar 2012 10:22:30 +0300 Subject: mwifiex: endian bug in mwifiex_drv_change_adhoc_chan() In mwifiex_drv_change_adhoc_chan() we pass channel to mwifiex_bss_ioctl_ibss_channel() which sets the high 16 bits. This works on little endian systems but not on big endian ones. I've changed mwifiex_drv_change_adhoc_chan() to use a 16 bit variable. This matches the other functions in the file. I considered changing mwifiex_change_adhoc_chan() as well but it turns out that the function isn't implemented so I just removed the definition. Signed-off-by: Dan Carpenter Acked-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/main.h | 3 +-- drivers/net/wireless/mwifiex/sta_ioctl.c | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h index a0bd4ebd262a..6dc116647411 100644 --- a/drivers/net/wireless/mwifiex/main.h +++ b/drivers/net/wireless/mwifiex/main.h @@ -909,10 +909,9 @@ int mwifiex_request_scan(struct mwifiex_private *priv, struct cfg80211_ssid *req_ssid); int mwifiex_set_user_scan_ioctl(struct mwifiex_private *priv, struct mwifiex_user_scan_cfg *scan_req); -int mwifiex_change_adhoc_chan(struct mwifiex_private *priv, int channel); int mwifiex_set_radio(struct mwifiex_private *priv, u8 option); -int mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, int channel); +int mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, u16 channel); int mwifiex_set_encode(struct mwifiex_private *priv, const u8 *key, int key_len, u8 key_index, int disable); diff --git a/drivers/net/wireless/mwifiex/sta_ioctl.c b/drivers/net/wireless/mwifiex/sta_ioctl.c index 593d285111d2..0ae1209646c1 100644 --- a/drivers/net/wireless/mwifiex/sta_ioctl.c +++ b/drivers/net/wireless/mwifiex/sta_ioctl.c @@ -609,7 +609,7 @@ static int mwifiex_bss_ioctl_ibss_channel(struct mwifiex_private *priv, * - Start/Join the IBSS */ int -mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, int channel) +mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, u16 channel) { int ret; struct mwifiex_bss_info bss_info; @@ -646,7 +646,7 @@ mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, int channel) ret = mwifiex_deauthenticate(priv, ssid_bssid.bssid); ret = mwifiex_bss_ioctl_ibss_channel(priv, HostCmd_ACT_GEN_SET, - (u16 *) &channel); + &channel); /* Do specific SSID scanning */ if (mwifiex_request_scan(priv, &bss_info.ssid)) { -- cgit From 4d196e4b2ffd734393b54f351507462f19d737b5 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Thu, 1 Mar 2012 11:23:37 +0100 Subject: mac80211: use 16 bit alignment for the if_ibss bssid field Several MAC address comparison functions assume 16 bit alignment for pointers passed to them. Since the addition of the control_port field, alignment for the IBSS bssid was off by one, causing a severe performance hit on architectures without efficient unaligned access (e.g. MIPS). Signed-off-by: Felix Fietkau Acked-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/ieee80211_i.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index cee0c7493fd0..c4130588b035 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -480,7 +480,7 @@ struct ieee80211_if_ibss { bool control_port; - u8 bssid[ETH_ALEN]; + u8 bssid[ETH_ALEN] __aligned(2); u8 ssid[IEEE80211_MAX_SSID_LEN]; u8 ssid_len, ie_len; u8 *ie; -- cgit From 888d04dfbe7e09f930fdaafb257cce2c54c9c3f3 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Thu, 1 Mar 2012 15:22:09 +0100 Subject: mac80211: use compare_ether_addr on MAC addresses instead of memcmp Because of the constant size and guaranteed 16 bit alignment, the inline compare_ether_addr function is much cheaper than calling memcmp. Signed-off-by: Felix Fietkau Acked-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/ibss.c | 10 +++++----- net/mac80211/mesh.c | 2 +- net/mac80211/mesh_hwmp.c | 19 +++++++++++-------- net/mac80211/mesh_pathtbl.c | 14 ++++++++------ net/mac80211/mlme.c | 30 ++++++++++++++++-------------- net/mac80211/rx.c | 6 +++--- net/mac80211/scan.c | 3 ++- net/mac80211/sta_info.c | 5 +++-- net/mac80211/sta_info.h | 3 ++- net/mac80211/status.c | 3 ++- 10 files changed, 53 insertions(+), 42 deletions(-) diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index 7f9ac577600a..33fd8d9f714e 100644 --- a/net/mac80211/ibss.c +++ b/net/mac80211/ibss.c @@ -66,7 +66,7 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, skb_reset_tail_pointer(skb); skb_reserve(skb, sdata->local->hw.extra_tx_headroom); - if (memcmp(ifibss->bssid, bssid, ETH_ALEN)) + if (compare_ether_addr(ifibss->bssid, bssid)) sta_info_flush(sdata->local, sdata); /* if merging, indicate to driver that we leave the old IBSS */ @@ -403,7 +403,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, return; if (sdata->vif.type == NL80211_IFTYPE_ADHOC && - memcmp(mgmt->bssid, sdata->u.ibss.bssid, ETH_ALEN) == 0) { + compare_ether_addr(mgmt->bssid, sdata->u.ibss.bssid) == 0) { rcu_read_lock(); sta = sta_info_get(sdata, mgmt->sa); @@ -508,7 +508,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, goto put_bss; /* same BSSID */ - if (memcmp(cbss->bssid, sdata->u.ibss.bssid, ETH_ALEN) == 0) + if (compare_ether_addr(cbss->bssid, sdata->u.ibss.bssid) == 0) goto put_bss; if (rx_status->flag & RX_FLAG_MACTIME_MPDU) { @@ -831,8 +831,8 @@ static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata, if (!tx_last_beacon && is_multicast_ether_addr(mgmt->da)) return; - if (memcmp(mgmt->bssid, ifibss->bssid, ETH_ALEN) != 0 && - memcmp(mgmt->bssid, "\xff\xff\xff\xff\xff\xff", ETH_ALEN) != 0) + if (compare_ether_addr(mgmt->bssid, ifibss->bssid) != 0 && + !is_broadcast_ether_addr(mgmt->bssid)) return; end = ((u8 *) mgmt) + len; diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c index c707c8bf6d2c..e5fbb7cf3562 100644 --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c @@ -204,7 +204,7 @@ int mesh_rmc_check(u8 *sa, struct ieee80211s_hdr *mesh_hdr, kmem_cache_free(rm_cache, p); --entries; } else if ((seqnum == p->seqnum) && - (memcmp(sa, p->sa, ETH_ALEN) == 0)) + (compare_ether_addr(sa, p->sa) == 0)) return -1; } diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c index 639db14f43d2..ae82ea75bc74 100644 --- a/net/mac80211/mesh_hwmp.c +++ b/net/mac80211/mesh_hwmp.c @@ -8,6 +8,7 @@ */ #include +#include #include #include "wme.h" #include "mesh.h" @@ -419,7 +420,7 @@ static u32 hwmp_route_info_get(struct ieee80211_sub_if_data *sdata, new_metric = MAX_METRIC; exp_time = TU_TO_EXP_TIME(orig_lifetime); - if (memcmp(orig_addr, sdata->vif.addr, ETH_ALEN) == 0) { + if (compare_ether_addr(orig_addr, sdata->vif.addr) == 0) { /* This MP is the originator, we are not interested in this * frame, except for updating transmitter's path info. */ @@ -469,7 +470,7 @@ static u32 hwmp_route_info_get(struct ieee80211_sub_if_data *sdata, /* Update and check transmitter routing info */ ta = mgmt->sa; - if (memcmp(orig_addr, ta, ETH_ALEN) == 0) + if (compare_ether_addr(orig_addr, ta) == 0) fresh_info = false; else { fresh_info = true; @@ -530,7 +531,7 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata, mhwmp_dbg("received PREQ from %pM", orig_addr); - if (memcmp(target_addr, sdata->vif.addr, ETH_ALEN) == 0) { + if (compare_ether_addr(target_addr, sdata->vif.addr) == 0) { mhwmp_dbg("PREQ is for us"); forward = false; reply = true; @@ -627,7 +628,7 @@ static void hwmp_prep_frame_process(struct ieee80211_sub_if_data *sdata, mhwmp_dbg("received PREP from %pM", PREP_IE_ORIG_ADDR(prep_elem)); orig_addr = PREP_IE_ORIG_ADDR(prep_elem); - if (memcmp(orig_addr, sdata->vif.addr, ETH_ALEN) == 0) + if (compare_ether_addr(orig_addr, sdata->vif.addr) == 0) /* destination, no forwarding required */ return; @@ -697,10 +698,12 @@ static void hwmp_perr_frame_process(struct ieee80211_sub_if_data *sdata, rcu_read_lock(); mpath = mesh_path_lookup(target_addr, sdata); if (mpath) { + struct sta_info *sta; + spin_lock_bh(&mpath->state_lock); + sta = next_hop_deref_protected(mpath); if (mpath->flags & MESH_PATH_ACTIVE && - memcmp(ta, next_hop_deref_protected(mpath)->sta.addr, - ETH_ALEN) == 0 && + compare_ether_addr(ta, sta->sta.addr) == 0 && (!(mpath->flags & MESH_PATH_SN_VALID) || SN_GT(target_sn, mpath->sn))) { mpath->flags &= ~MESH_PATH_ACTIVE; @@ -742,7 +745,7 @@ static void hwmp_rann_frame_process(struct ieee80211_sub_if_data *sdata, metric = rann->rann_metric; /* Ignore our own RANNs */ - if (memcmp(orig_addr, sdata->vif.addr, ETH_ALEN) == 0) + if (compare_ether_addr(orig_addr, sdata->vif.addr) == 0) return; mhwmp_dbg("received RANN from %pM via neighbour %pM (is_gate=%d)", @@ -1074,7 +1077,7 @@ int mesh_nexthop_lookup(struct sk_buff *skb, if (time_after(jiffies, mpath->exp_time - msecs_to_jiffies(sdata->u.mesh.mshcfg.path_refresh_time)) && - !memcmp(sdata->vif.addr, hdr->addr4, ETH_ALEN) && + !compare_ether_addr(sdata->vif.addr, hdr->addr4) && !(mpath->flags & MESH_PATH_RESOLVING) && !(mpath->flags & MESH_PATH_FIXED)) mesh_queue_preq(mpath, PREQ_Q_F_START | PREQ_Q_F_REFRESH); diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c index dc51669e67d8..157642f780b9 100644 --- a/net/mac80211/mesh_pathtbl.c +++ b/net/mac80211/mesh_pathtbl.c @@ -348,7 +348,7 @@ static struct mesh_path *mpath_lookup(struct mesh_table *tbl, u8 *dst, hlist_for_each_entry_rcu(node, n, bucket, list) { mpath = node->mpath; if (mpath->sdata == sdata && - memcmp(dst, mpath->dst, ETH_ALEN) == 0) { + compare_ether_addr(dst, mpath->dst) == 0) { if (MPATH_EXPIRED(mpath)) { spin_lock_bh(&mpath->state_lock); mpath->flags &= ~MESH_PATH_ACTIVE; @@ -523,7 +523,7 @@ int mesh_path_add(u8 *dst, struct ieee80211_sub_if_data *sdata) int err = 0; u32 hash_idx; - if (memcmp(dst, sdata->vif.addr, ETH_ALEN) == 0) + if (compare_ether_addr(dst, sdata->vif.addr) == 0) /* never add ourselves as neighbours */ return -ENOTSUPP; @@ -564,7 +564,8 @@ int mesh_path_add(u8 *dst, struct ieee80211_sub_if_data *sdata) err = -EEXIST; hlist_for_each_entry(node, n, bucket, list) { mpath = node->mpath; - if (mpath->sdata == sdata && memcmp(dst, mpath->dst, ETH_ALEN) == 0) + if (mpath->sdata == sdata && + compare_ether_addr(dst, mpath->dst) == 0) goto err_exists; } @@ -655,7 +656,7 @@ int mpp_path_add(u8 *dst, u8 *mpp, struct ieee80211_sub_if_data *sdata) int err = 0; u32 hash_idx; - if (memcmp(dst, sdata->vif.addr, ETH_ALEN) == 0) + if (compare_ether_addr(dst, sdata->vif.addr) == 0) /* never add ourselves as neighbours */ return -ENOTSUPP; @@ -692,7 +693,8 @@ int mpp_path_add(u8 *dst, u8 *mpp, struct ieee80211_sub_if_data *sdata) err = -EEXIST; hlist_for_each_entry(node, n, bucket, list) { mpath = node->mpath; - if (mpath->sdata == sdata && memcmp(dst, mpath->dst, ETH_ALEN) == 0) + if (mpath->sdata == sdata && + compare_ether_addr(dst, mpath->dst) == 0) goto err_exists; } @@ -886,7 +888,7 @@ int mesh_path_del(u8 *addr, struct ieee80211_sub_if_data *sdata) hlist_for_each_entry(node, n, bucket, list) { mpath = node->mpath; if (mpath->sdata == sdata && - memcmp(addr, mpath->dst, ETH_ALEN) == 0) { + compare_ether_addr(addr, mpath->dst) == 0) { __mesh_path_del(tbl, node); goto enddel; } diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index caf97f5a2937..7190da4f2138 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -1822,7 +1822,7 @@ ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata, memcpy(bssid, ifmgd->auth_data->bss->bssid, ETH_ALEN); - if (memcmp(bssid, mgmt->bssid, ETH_ALEN)) + if (compare_ether_addr(bssid, mgmt->bssid)) return RX_MGMT_NONE; auth_alg = le16_to_cpu(mgmt->u.auth.auth_alg); @@ -1903,7 +1903,7 @@ ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata, return RX_MGMT_NONE; if (!ifmgd->associated || - memcmp(mgmt->bssid, ifmgd->associated->bssid, ETH_ALEN)) + compare_ether_addr(mgmt->bssid, ifmgd->associated->bssid)) return RX_MGMT_NONE; bssid = ifmgd->associated->bssid; @@ -1936,7 +1936,7 @@ ieee80211_rx_mgmt_disassoc(struct ieee80211_sub_if_data *sdata, return RX_MGMT_NONE; if (!ifmgd->associated || - memcmp(mgmt->bssid, ifmgd->associated->bssid, ETH_ALEN)) + compare_ether_addr(mgmt->bssid, ifmgd->associated->bssid)) return RX_MGMT_NONE; reason_code = le16_to_cpu(mgmt->u.disassoc.reason_code); @@ -2203,7 +2203,7 @@ ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, if (!assoc_data) return RX_MGMT_NONE; - if (memcmp(assoc_data->bss->bssid, mgmt->bssid, ETH_ALEN)) + if (compare_ether_addr(assoc_data->bss->bssid, mgmt->bssid)) return RX_MGMT_NONE; /* @@ -2291,8 +2291,8 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, bool need_ps = false; if (sdata->u.mgd.associated && - memcmp(mgmt->bssid, sdata->u.mgd.associated->bssid, - ETH_ALEN) == 0) { + compare_ether_addr(mgmt->bssid, sdata->u.mgd.associated->bssid) + == 0) { bss = (void *)sdata->u.mgd.associated->priv; /* not previously set so we may need to recalc */ need_ps = !bss->dtim_period; @@ -2347,7 +2347,7 @@ static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata, ASSERT_MGD_MTX(ifmgd); - if (memcmp(mgmt->da, sdata->vif.addr, ETH_ALEN)) + if (compare_ether_addr(mgmt->da, sdata->vif.addr)) return; /* ignore ProbeResp to foreign address */ baselen = (u8 *) mgmt->u.probe_resp.variable - (u8 *) mgmt; @@ -2360,11 +2360,12 @@ static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata, ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems, false); if (ifmgd->associated && - memcmp(mgmt->bssid, ifmgd->associated->bssid, ETH_ALEN) == 0) + compare_ether_addr(mgmt->bssid, ifmgd->associated->bssid) == 0) ieee80211_reset_ap_probe(sdata); if (ifmgd->auth_data && !ifmgd->auth_data->bss->proberesp_ies && - memcmp(mgmt->bssid, ifmgd->auth_data->bss->bssid, ETH_ALEN) == 0) { + compare_ether_addr(mgmt->bssid, ifmgd->auth_data->bss->bssid) + == 0) { /* got probe response, continue with auth */ printk(KERN_DEBUG "%s: direct probe responded\n", sdata->name); ifmgd->auth_data->tries = 0; @@ -2421,7 +2422,8 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, return; if (ifmgd->assoc_data && !ifmgd->assoc_data->have_beacon && - memcmp(mgmt->bssid, ifmgd->assoc_data->bss->bssid, ETH_ALEN) == 0) { + compare_ether_addr(mgmt->bssid, ifmgd->assoc_data->bss->bssid) + == 0) { ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen, &elems); @@ -2436,7 +2438,7 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, } if (!ifmgd->associated || - memcmp(mgmt->bssid, ifmgd->associated->bssid, ETH_ALEN)) + compare_ether_addr(mgmt->bssid, ifmgd->associated->bssid)) return; bssid = ifmgd->associated->bssid; @@ -3299,7 +3301,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, bool match; /* keep sta info, bssid if matching */ - match = memcmp(ifmgd->bssid, req->bss->bssid, ETH_ALEN) == 0; + match = compare_ether_addr(ifmgd->bssid, req->bss->bssid) == 0; ieee80211_destroy_auth_data(sdata, match); } @@ -3421,7 +3423,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, goto err_clear; } } else - WARN_ON_ONCE(memcmp(ifmgd->bssid, req->bss->bssid, ETH_ALEN)); + WARN_ON_ONCE(compare_ether_addr(ifmgd->bssid, req->bss->bssid)); if (!bss->dtim_period && sdata->local->hw.flags & IEEE80211_HW_NEED_DTIM_PERIOD) { @@ -3471,7 +3473,7 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata, sdata->name, req->bssid, req->reason_code); if (ifmgd->associated && - memcmp(ifmgd->associated->bssid, req->bssid, ETH_ALEN) == 0) + compare_ether_addr(ifmgd->associated->bssid, req->bssid) == 0) ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH, req->reason_code, true, frame_buf); else diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 7a4ff02af261..3cf011fc97f4 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -489,12 +489,12 @@ ieee80211_rx_mesh_check(struct ieee80211_rx_data *rx) if (ieee80211_has_tods(hdr->frame_control) || !ieee80211_has_fromds(hdr->frame_control)) return RX_DROP_MONITOR; - if (memcmp(hdr->addr3, dev_addr, ETH_ALEN) == 0) + if (compare_ether_addr(hdr->addr3, dev_addr) == 0) return RX_DROP_MONITOR; } else { if (!ieee80211_has_a4(hdr->frame_control)) return RX_DROP_MONITOR; - if (memcmp(hdr->addr4, dev_addr, ETH_ALEN) == 0) + if (compare_ether_addr(hdr->addr4, dev_addr) == 0) return RX_DROP_MONITOR; } } @@ -2336,7 +2336,7 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) if (sdata->vif.type != NL80211_IFTYPE_STATION) break; - if (memcmp(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN)) + if (compare_ether_addr(mgmt->bssid, sdata->u.mgd.bssid)) break; goto queue; diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index 9270771702fe..a9d7235df7c3 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c @@ -13,6 +13,7 @@ */ #include +#include #include #include #include @@ -176,7 +177,7 @@ ieee80211_scan_rx(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb) presp = ieee80211_is_probe_resp(fc); if (presp) { /* ignore ProbeResp to foreign address */ - if (memcmp(mgmt->da, sdata->vif.addr, ETH_ALEN)) + if (compare_ether_addr(mgmt->da, sdata->vif.addr)) return RX_DROP_MONITOR; presp = true; diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index cd0f265f42e5..38137cb5f6f0 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -101,7 +102,7 @@ struct sta_info *sta_info_get(struct ieee80211_sub_if_data *sdata, lockdep_is_held(&local->sta_mtx)); while (sta) { if (sta->sdata == sdata && - memcmp(sta->sta.addr, addr, ETH_ALEN) == 0) + compare_ether_addr(sta->sta.addr, addr) == 0) break; sta = rcu_dereference_check(sta->hnext, lockdep_is_held(&local->sta_mtx)); @@ -124,7 +125,7 @@ struct sta_info *sta_info_get_bss(struct ieee80211_sub_if_data *sdata, while (sta) { if ((sta->sdata == sdata || (sta->sdata->bss && sta->sdata->bss == sdata->bss)) && - memcmp(sta->sta.addr, addr, ETH_ALEN) == 0) + compare_ether_addr(sta->sta.addr, addr) == 0) break; sta = rcu_dereference_check(sta->hnext, lockdep_is_held(&local->sta_mtx)); diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h index 23a97c9dc042..3336d54e5558 100644 --- a/net/mac80211/sta_info.h +++ b/net/mac80211/sta_info.h @@ -14,6 +14,7 @@ #include #include #include +#include #include "key.h" /** @@ -489,7 +490,7 @@ void for_each_sta_info_type_check(struct ieee80211_local *local, nxt = _sta ? rcu_dereference(_sta->hnext) : NULL \ ) \ /* compare address and run code only if it matches */ \ - if (memcmp(_sta->sta.addr, (_addr), ETH_ALEN) == 0) + if (compare_ether_addr(_sta->sta.addr, (_addr)) == 0) /* * Get STA info by index, BROKEN! diff --git a/net/mac80211/status.c b/net/mac80211/status.c index c928e4a4effd..5f8f89e89d6b 100644 --- a/net/mac80211/status.c +++ b/net/mac80211/status.c @@ -10,6 +10,7 @@ */ #include +#include #include #include #include "ieee80211_i.h" @@ -377,7 +378,7 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) for_each_sta_info(local, hdr->addr1, sta, tmp) { /* skip wrong virtual interface */ - if (memcmp(hdr->addr2, sta->sdata->vif.addr, ETH_ALEN)) + if (compare_ether_addr(hdr->addr2, sta->sdata->vif.addr)) continue; if (info->flags & IEEE80211_TX_STATUS_EOSP) -- cgit From c04a4ff71b6a59cb5c8deec961b9196226e89573 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 1 Mar 2012 15:28:19 +0100 Subject: cfg80211: fix kernel-doc I forgot to update the kernel-doc in my patch to redesign AP mode APIs, fix that now. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- include/net/cfg80211.h | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index b4e015c90885..d640a39d9513 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -1357,12 +1357,10 @@ struct cfg80211_gtk_rekey_data { * * @set_rekey_data: give the data necessary for GTK rekeying to the driver * - * @add_beacon: Add a beacon with given parameters, @head, @interval - * and @dtim_period will be valid, @tail is optional. - * @set_beacon: Change the beacon parameters for an access point mode - * interface. This should reject the call when no beacon has been - * configured. - * @del_beacon: Remove beacon configuration and stop sending the beacon. + * @start_ap: Start acting in AP mode defined by the parameters. + * @change_beacon: Change the beacon parameters for an access point mode + * interface. This should reject the call when AP mode wasn't started. + * @stop_ap: Stop being an AP, including stopping beaconing. * * @add_station: Add a new station. * @del_station: Remove a station; @mac may be NULL to remove all stations. -- cgit From fe8431f89e25de722610ee5beb2892bd019d1fed Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Thu, 1 Mar 2012 18:00:07 +0100 Subject: mac80211: add an rx flag for ignoring a packet's signal strength For A-MPDU rx it makes sense to only process the signal strength once per aggregate instead of once per subframe. Additonally, some hardware (e.g. Atheros) only provides valid signal strength information for the last subframe. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- include/net/mac80211.h | 3 +++ net/mac80211/rx.c | 9 ++++++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 7477f020ee7a..c06974accfa6 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -659,6 +659,8 @@ ieee80211_tx_info_clear_status(struct ieee80211_tx_info *info) * @RX_FLAG_HT: HT MCS was used and rate_idx is MCS index * @RX_FLAG_40MHZ: HT40 (40 MHz) was used * @RX_FLAG_SHORT_GI: Short guard interval was used + * @RX_FLAG_NO_SIGNAL_VAL: The signal strength value is not present. + * Valid only for data frames (mainly A-MPDU) */ enum mac80211_rx_flags { RX_FLAG_MMIC_ERROR = 1<<0, @@ -672,6 +674,7 @@ enum mac80211_rx_flags { RX_FLAG_HT = 1<<9, RX_FLAG_40MHZ = 1<<10, RX_FLAG_SHORT_GI = 1<<11, + RX_FLAG_NO_SIGNAL_VAL = 1<<12, }; /** diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 3cf011fc97f4..f3b515d16f24 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -177,7 +177,8 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local, pos += 2; /* IEEE80211_RADIOTAP_DBM_ANTSIGNAL */ - if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM) { + if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM && + !(status->flag & RX_FLAG_NO_SIGNAL_VAL)) { *pos = status->signal; rthdr->it_present |= cpu_to_le32(1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL); @@ -1309,8 +1310,10 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx) sta->rx_fragments++; sta->rx_bytes += rx->skb->len; - sta->last_signal = status->signal; - ewma_add(&sta->avg_signal, -status->signal); + if (!(status->flag & RX_FLAG_NO_SIGNAL_VAL)) { + sta->last_signal = status->signal; + ewma_add(&sta->avg_signal, -status->signal); + } /* * Change STA power saving mode only at the end of a frame -- cgit From d665508b98d3cdbeb476e7d6848a513184a81ed0 Mon Sep 17 00:00:00 2001 From: Chun-Yeow Yeoh Date: Fri, 2 Mar 2012 02:03:19 +0800 Subject: mac80211: fix the support of setting non-forwarding entity in Mesh RANN, PREP and PERR propagation should happen only if the dot11MeshForwarding is true. Besides, data frame should not be forwarded if dot11MeshForwarding is false. This redundant checking is necessary to avoid the broadcasted ARP breaking the non-forwarding rule. Signed-off-by: Chun-Yeow Yeoh Signed-off-by: John W. Linville --- net/mac80211/mesh_hwmp.c | 9 ++++++++- net/mac80211/rx.c | 3 +++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c index ae82ea75bc74..4a993f2d1ae1 100644 --- a/net/mac80211/mesh_hwmp.c +++ b/net/mac80211/mesh_hwmp.c @@ -619,6 +619,7 @@ static void hwmp_prep_frame_process(struct ieee80211_sub_if_data *sdata, struct ieee80211_mgmt *mgmt, u8 *prep_elem, u32 metric) { + struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; struct mesh_path *mpath; u8 *target_addr, *orig_addr; u8 ttl, hopcount, flags; @@ -632,6 +633,9 @@ static void hwmp_prep_frame_process(struct ieee80211_sub_if_data *sdata, /* destination, no forwarding required */ return; + if (!ifmsh->mshcfg.dot11MeshForwarding) + return; + ttl = PREP_IE_TTL(prep_elem); if (ttl <= 1) { sdata->u.mesh.mshstats.dropped_frames_ttl++; @@ -709,12 +713,15 @@ static void hwmp_perr_frame_process(struct ieee80211_sub_if_data *sdata, mpath->flags &= ~MESH_PATH_ACTIVE; mpath->sn = target_sn; spin_unlock_bh(&mpath->state_lock); + if (!ifmsh->mshcfg.dot11MeshForwarding) + goto endperr; mesh_path_error_tx(ttl, target_addr, cpu_to_le32(target_sn), cpu_to_le16(target_rcode), broadcast_addr, sdata); } else spin_unlock_bh(&mpath->state_lock); } +endperr: rcu_read_unlock(); } @@ -771,7 +778,7 @@ static void hwmp_rann_frame_process(struct ieee80211_sub_if_data *sdata, mesh_queue_preq(mpath, PREQ_Q_F_START | PREQ_Q_F_REFRESH); } - if (mpath->sn < orig_sn) { + if (mpath->sn < orig_sn && ifmsh->mshcfg.dot11MeshForwarding) { mesh_path_sel_frame_tx(MPATH_RANN, flags, orig_addr, cpu_to_le32(orig_sn), 0, NULL, 0, broadcast_addr, diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index f3b515d16f24..c8166adcd600 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -1960,6 +1960,9 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) return RX_DROP_MONITOR; } + if (!ifmsh->mshcfg.dot11MeshForwarding) + goto out; + fwd_skb = skb_copy(skb, GFP_ATOMIC); if (!fwd_skb) { if (net_ratelimit()) -- cgit From 1b658f118b11de3c4052ed8cbdd5803cd1fa5670 Mon Sep 17 00:00:00 2001 From: Vasanthakumar Thiagarajan Date: Fri, 2 Mar 2012 15:50:02 +0530 Subject: cfg80211: Add an attribute to set inactivity timeout in AP mode This patch adds an attribute, NL80211_ATTR_INACTIVITY_TIMEOUT, to set the inactivity timeout which can be used to remove the station in AP mode. This can be passed in NL80211_CMD_START_AP and used by the drivers which have AP MLME in firmware but don't support get_station() properly. To disable inactivity timer in userspace, wpa_s for example, there is a new flag, NL80211_FEATURE_INACTIVITY_TIMER, in nl80211_feature_flags through which drivers can register their capability to use the inactivity timeout to free the stations. Signed-off-by: Vasanthakumar Thiagarajan Acked-by: Johannes Berg Signed-off-by: John W. Linville --- include/linux/nl80211.h | 15 +++++++++++++-- include/net/cfg80211.h | 2 ++ net/wireless/nl80211.c | 8 ++++++++ 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h index 38fda5ee57f5..9f46c62b1eee 100644 --- a/include/linux/nl80211.h +++ b/include/linux/nl80211.h @@ -168,8 +168,8 @@ * %NL80211_ATTR_DTIM_PERIOD, %NL80211_ATTR_SSID, * %NL80211_ATTR_HIDDEN_SSID, %NL80211_ATTR_CIPHERS_PAIRWISE, * %NL80211_ATTR_CIPHER_GROUP, %NL80211_ATTR_WPA_VERSIONS, - * %NL80211_ATTR_AKM_SUITES, %NL80211_ATTR_PRIVACY and - * %NL80211_ATTR_AUTH_TYPE. + * %NL80211_ATTR_AKM_SUITES, %NL80211_ATTR_PRIVACY, + * %NL80211_ATTR_AUTH_TYPE and %NL80211_ATTR_INACTIVITY_TIMEOUT. * @NL80211_CMD_NEW_BEACON: old alias for %NL80211_CMD_START_AP * @NL80211_CMD_STOP_AP: Stop AP operation on the given interface * @NL80211_CMD_DEL_BEACON: old alias for %NL80211_CMD_STOP_AP @@ -1197,6 +1197,12 @@ enum nl80211_commands { * @NL80211_ATTR_NOACK_MAP: This u16 bitmap contains the No Ack Policy of * up to 16 TIDs. * + * @NL80211_ATTR_INACTIVITY_TIMEOUT: timeout value in seconds, this can be + * used by the drivers which has MLME in firmware and does not have support + * to report per station tx/rx activity to free up the staion entry from + * the list. This needs to be used when the driver advertises the + * capability to timeout the stations. + * * @NL80211_ATTR_MAX: highest attribute number currently defined * @__NL80211_ATTR_AFTER_LAST: internal use */ @@ -1442,6 +1448,8 @@ enum nl80211_attrs { NL80211_ATTR_NOACK_MAP, + NL80211_ATTR_INACTIVITY_TIMEOUT, + /* add attributes here, update the policy in nl80211.c */ __NL80211_ATTR_AFTER_LAST, @@ -2809,10 +2817,13 @@ enum nl80211_ap_sme_features { * TX status to the socket error queue when requested with the * socket option. * @NL80211_FEATURE_HT_IBSS: This driver supports IBSS with HT datarates. + * @NL80211_FEATURE_INACTIVITY_TIMER: This driver takes care of freeing up + * the connected inactive stations in AP mode. */ enum nl80211_feature_flags { NL80211_FEATURE_SK_TX_STATUS = 1 << 0, NL80211_FEATURE_HT_IBSS = 1 << 1, + NL80211_FEATURE_INACTIVITY_TIMER = 1 << 2, }; /** diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index d640a39d9513..804805827736 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -413,6 +413,7 @@ struct cfg80211_beacon_data { * @crypto: crypto settings * @privacy: the BSS uses privacy * @auth_type: Authentication type (algorithm) + * @inactivity_timeout: time in seconds to determine station's inactivity. */ struct cfg80211_ap_settings { struct cfg80211_beacon_data beacon; @@ -424,6 +425,7 @@ struct cfg80211_ap_settings { struct cfg80211_crypto_settings crypto; bool privacy; enum nl80211_auth_type auth_type; + int inactivity_timeout; }; /** diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 25a470abd21d..4b6afc338aac 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -204,6 +204,7 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = { .len = NL80211_HT_CAPABILITY_LEN }, [NL80211_ATTR_NOACK_MAP] = { .type = NLA_U16 }, + [NL80211_ATTR_INACTIVITY_TIMEOUT] = { .type = NLA_U16 }, }; /* policy for the key attributes */ @@ -2214,6 +2215,13 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info) if (err) return err; + if (info->attrs[NL80211_ATTR_INACTIVITY_TIMEOUT]) { + if (!(rdev->wiphy.features & NL80211_FEATURE_INACTIVITY_TIMER)) + return -EOPNOTSUPP; + params.inactivity_timeout = nla_get_u16( + info->attrs[NL80211_ATTR_INACTIVITY_TIMEOUT]); + } + err = rdev->ops->start_ap(&rdev->wiphy, dev, ¶ms); if (!err) wdev->beacon_interval = params.beacon_interval; -- cgit From 293702a3fb75832613e2af097bdc3ac8ef775b33 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 2 Mar 2012 13:18:19 +0100 Subject: mac80211: use common radiotap code for cooked monitors There's no need to hardcode a subset of the radiotap header for cooked monitor receive, we can just reuse the normal monitor mode radiotap code. This simplifies the code and extends the information available on cooked monitor interfaces. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/rx.c | 39 +++++++++------------------------------ 1 file changed, 9 insertions(+), 30 deletions(-) diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index c8166adcd600..10bbbd33b314 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -228,7 +228,7 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb, { struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(origskb); struct ieee80211_sub_if_data *sdata; - int needed_headroom = 0; + int needed_headroom; struct sk_buff *skb, *skb2; struct net_device *prev_dev = NULL; int present_fcs_len = 0; @@ -2544,16 +2544,10 @@ static void ieee80211_rx_cooked_monitor(struct ieee80211_rx_data *rx, { struct ieee80211_sub_if_data *sdata; struct ieee80211_local *local = rx->local; - struct ieee80211_rtap_hdr { - struct ieee80211_radiotap_header hdr; - u8 flags; - u8 rate_or_pad; - __le16 chan_freq; - __le16 chan_flags; - } __packed *rthdr; struct sk_buff *skb = rx->skb, *skb2; struct net_device *prev_dev = NULL; struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); + int needed_headroom; /* * If cooked monitor has been processed already, then @@ -2567,30 +2561,15 @@ static void ieee80211_rx_cooked_monitor(struct ieee80211_rx_data *rx, if (!local->cooked_mntrs) goto out_free_skb; - if (skb_headroom(skb) < sizeof(*rthdr) && - pskb_expand_head(skb, sizeof(*rthdr), 0, GFP_ATOMIC)) - goto out_free_skb; - - rthdr = (void *)skb_push(skb, sizeof(*rthdr)); - memset(rthdr, 0, sizeof(*rthdr)); - rthdr->hdr.it_len = cpu_to_le16(sizeof(*rthdr)); - rthdr->hdr.it_present = - cpu_to_le32((1 << IEEE80211_RADIOTAP_FLAGS) | - (1 << IEEE80211_RADIOTAP_CHANNEL)); + /* room for the radiotap header based on driver features */ + needed_headroom = ieee80211_rx_radiotap_len(local, status); - if (rate) { - rthdr->rate_or_pad = rate->bitrate / 5; - rthdr->hdr.it_present |= - cpu_to_le32(1 << IEEE80211_RADIOTAP_RATE); - } - rthdr->chan_freq = cpu_to_le16(status->freq); + if (skb_headroom(skb) < needed_headroom && + pskb_expand_head(skb, needed_headroom, 0, GFP_ATOMIC)) + goto out_free_skb; - if (status->band == IEEE80211_BAND_5GHZ) - rthdr->chan_flags = cpu_to_le16(IEEE80211_CHAN_OFDM | - IEEE80211_CHAN_5GHZ); - else - rthdr->chan_flags = cpu_to_le16(IEEE80211_CHAN_DYN | - IEEE80211_CHAN_2GHZ); + /* prepend radiotap information */ + ieee80211_add_rx_radiotap_header(local, skb, rate, needed_headroom); skb_set_mac_header(skb, 0); skb->ip_summed = CHECKSUM_UNNECESSARY; -- cgit From 3abead59fcdeb56df8b83288a2f5edbe6423b0bb Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 2 Mar 2012 15:56:59 +0100 Subject: mac80211: combine QoS with other BSS changes When associating and particularly when disassociating there's no need to notify the driver about changes with multiple calls to bss_info_changed, we should combine the QoS enabling/disabling into the same call as otherwise the driver could get confused about QoS suddenly getting disabled while connected. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/ieee80211_i.h | 3 ++- net/mac80211/iface.c | 2 +- net/mac80211/mlme.c | 12 ++++++++---- net/mac80211/util.c | 9 ++++++--- 4 files changed, 17 insertions(+), 9 deletions(-) diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index c4130588b035..24cb1080e238 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -1348,7 +1348,8 @@ int ieee80211_frame_duration(struct ieee80211_local *local, size_t len, void mac80211_ev_michael_mic_failure(struct ieee80211_sub_if_data *sdata, int keyidx, struct ieee80211_hdr *hdr, const u8 *tsc, gfp_t gfp); -void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata); +void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata, + bool bss_notify); void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb); void ieee80211_tx_skb_tid(struct ieee80211_sub_if_data *sdata, diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 620ca8d2ad42..401c01f0731e 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -304,7 +304,7 @@ static int ieee80211_do_open(struct net_device *dev, bool coming_up) * need to initialise the hardware if the hardware * doesn't start up with sane defaults */ - ieee80211_set_wmm_default(sdata); + ieee80211_set_wmm_default(sdata, true); } set_bit(SDATA_STATE_RUNNING, &sdata->state); diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 7190da4f2138..92c5eb124d6f 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -1277,7 +1277,6 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local, /* enable WMM or activate new settings */ sdata->vif.bss_conf.qos = true; - ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_QOS); } static u32 ieee80211_handle_bss_capability(struct ieee80211_sub_if_data *sdata, @@ -1455,8 +1454,6 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, changed |= BSS_CHANGED_ASSOC; sdata->vif.bss_conf.assoc = false; - ieee80211_set_wmm_default(sdata); - /* channel(_type) changes are handled by ieee80211_hw_config */ WARN_ON(!ieee80211_set_channel_type(local, sdata, NL80211_CHAN_NO_HT)); @@ -1484,10 +1481,16 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, changed |= BSS_CHANGED_ARP_FILTER; } + sdata->vif.bss_conf.qos = false; + changed |= BSS_CHANGED_QOS; + /* The BSSID (not really interesting) and HT changed */ changed |= BSS_CHANGED_BSSID | BSS_CHANGED_HT; ieee80211_bss_info_change_notify(sdata, changed); + /* disassociated - set to defaults now */ + ieee80211_set_wmm_default(sdata, false); + del_timer_sync(&sdata->u.mgd.conn_mon_timer); del_timer_sync(&sdata->u.mgd.bcn_mon_timer); del_timer_sync(&sdata->u.mgd.timer); @@ -2155,7 +2158,8 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata, ieee80211_sta_wmm_params(local, sdata, elems.wmm_param, elems.wmm_param_len); else - ieee80211_set_wmm_default(sdata); + ieee80211_set_wmm_default(sdata, false); + changed |= BSS_CHANGED_QOS; if (elems.ht_info_elem && elems.wmm_param && (sdata->local->hw.queues >= 4) && diff --git a/net/mac80211/util.c b/net/mac80211/util.c index f6e4cef92021..0a5ad95ac8b0 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -737,7 +737,8 @@ void ieee802_11_parse_elems(u8 *start, size_t len, ieee802_11_parse_elems_crc(start, len, elems, 0, 0); } -void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata) +void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata, + bool bss_notify) { struct ieee80211_local *local = sdata->local; struct ieee80211_tx_queue_params qparam; @@ -807,7 +808,9 @@ void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata) if (sdata->vif.type != NL80211_IFTYPE_MONITOR) { sdata->vif.bss_conf.qos = sdata->vif.type != NL80211_IFTYPE_STATION; - ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_QOS); + if (bss_notify) + ieee80211_bss_info_change_notify(sdata, + BSS_CHANGED_QOS); } } @@ -829,7 +832,7 @@ void ieee80211_sta_def_wmm_params(struct ieee80211_sub_if_data *sdata, else sdata->flags &= ~IEEE80211_SDATA_OPERATING_GMODE; - ieee80211_set_wmm_default(sdata); + ieee80211_set_wmm_default(sdata, true); } u32 ieee80211_mandatory_rates(struct ieee80211_local *local, -- cgit From 48de1a17fc41613b7e9d61037fa989256d04234f Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Fri, 2 Mar 2012 13:21:22 -0600 Subject: rtlwifi: Detect misread of end-point count In the unlikely event of a misread of the USB end point count, the driver generates a divide fault. To prevent this, add a check of the value returned by _rtl_usb_init(). In addition, add some logging to indicate why the condition occurred. Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/usb.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/rtlwifi/usb.c b/drivers/net/wireless/rtlwifi/usb.c index ffcf89fe45e4..b0eee0eb5679 100644 --- a/drivers/net/wireless/rtlwifi/usb.c +++ b/drivers/net/wireless/rtlwifi/usb.c @@ -346,9 +346,14 @@ static int _rtl_usb_init(struct ieee80211_hw *hw) pep_desc->bEndpointAddress, pep_desc->wMaxPacketSize, pep_desc->bInterval); } - if (rtlusb->in_ep_nums < rtlpriv->cfg->usb_interface_cfg->in_ep_num) - return -EINVAL ; - + if (rtlusb->in_ep_nums < rtlpriv->cfg->usb_interface_cfg->in_ep_num) { + pr_err("Too few input end points found\n"); + return -EINVAL; + } + if (rtlusb->out_ep_nums == 0) { + pr_err("No output end points found\n"); + return -EINVAL; + } /* usb endpoint mapping */ err = rtlpriv->cfg->usb_interface_cfg->usb_endpoint_mapping(hw); rtlusb->usb_mq_to_hwq = rtlpriv->cfg->usb_interface_cfg->usb_mq_to_hwq; @@ -976,6 +981,8 @@ int __devinit rtl_usb_probe(struct usb_interface *intf, } rtlpriv->cfg->ops->init_sw_leds(hw); err = _rtl_usb_init(hw); + if (err) + goto error_out; err = _rtl_usb_init_sw(hw); /* Init mac80211 sw */ err = rtl_init_core(hw); -- cgit From 8f526ab4aa1b145bda2baf56e223050c7ef3e1b0 Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Fri, 2 Mar 2012 13:22:46 -0600 Subject: rtlwifi: Remove extraneous value return In usb.c, routine _rtl_usb_init_sw() always returns 0, and rtl_usb_probe() never checks the returned value. Thus we can change _rtl_usb_init_sw() to a void routine. In addition, remove the underscore at the beginning of the name of the routine. Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/usb.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/rtlwifi/usb.c b/drivers/net/wireless/rtlwifi/usb.c index b0eee0eb5679..2e1e352864bb 100644 --- a/drivers/net/wireless/rtlwifi/usb.c +++ b/drivers/net/wireless/rtlwifi/usb.c @@ -362,7 +362,7 @@ static int _rtl_usb_init(struct ieee80211_hw *hw) return err; } -static int _rtl_usb_init_sw(struct ieee80211_hw *hw) +static void rtl_usb_init_sw(struct ieee80211_hw *hw) { struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); @@ -397,7 +397,6 @@ static int _rtl_usb_init_sw(struct ieee80211_hw *hw) /* HIMR_EX - turn all on */ rtlusb->irq_mask[1] = 0xFFFFFFFF; rtlusb->disableHWSM = true; - return 0; } #define __RADIO_TAP_SIZE_RSV 32 @@ -983,7 +982,7 @@ int __devinit rtl_usb_probe(struct usb_interface *intf, err = _rtl_usb_init(hw); if (err) goto error_out; - err = _rtl_usb_init_sw(hw); + rtl_usb_init_sw(hw); /* Init mac80211 sw */ err = rtl_init_core(hw); if (err) { -- cgit From ebecdcc12fed5d3c81853dea61a0a78a5aefab52 Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Fri, 2 Mar 2012 15:23:36 -0600 Subject: rtlwifi: rtl8192c: Prevent sleeping from invalid context in rtl8192cu When driver rtl8192cu is used with the debug level set to 3 or greater, the result is "sleeping function called from invalid context" due to an rcu_read_lock() call in the DM refresh routine in driver rtl8192c. This lock is not necessary as the USB driver does not use the struct being protected, thus the lock is set only when a PCI interface is active. This bug is reported in https://bugzilla.kernel.org/show_bug.cgi?id=42775. Reported-by: Ronald Wahl Tested-by: Ronald Wahl Signed-off-by: Larry Finger Cc: Stable Cc: Ronald Wahl Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c index cb5535cf3ae2..8646ff2a55ce 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c +++ b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c @@ -1201,13 +1201,18 @@ static void rtl92c_dm_refresh_rate_adaptive_mask(struct ieee80211_hw *hw) "PreState = %d, CurState = %d\n", p_ra->pre_ratr_state, p_ra->ratr_state); - rcu_read_lock(); - sta = ieee80211_find_sta(mac->vif, mac->bssid); + /* Only the PCI card uses sta in the update rate table + * callback routine */ + if (rtlhal->interface == INTF_PCI) { + rcu_read_lock(); + sta = ieee80211_find_sta(mac->vif, mac->bssid); + } rtlpriv->cfg->ops->update_rate_tbl(hw, sta, p_ra->ratr_state); p_ra->pre_ratr_state = p_ra->ratr_state; - rcu_read_unlock(); + if (rtlhal->interface == INTF_PCI) + rcu_read_unlock(); } } } -- cgit From 3bc7e29c984ffda0b6133c2b34233023ff36f370 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Fri, 2 Mar 2012 22:55:45 +0100 Subject: brcm80211: fmac: remove unnecessary NULL pointer check In brcmf_usb_up() the variable devinfo was checked for being a NULL pointer, but this can not happen. Also the check was done after dereferencing the pointer. This patch removes the check. Reviewed-by: Pieter-Paul Giesberts Reviewed-by: Franky (Zhenhui) Lin Reviewed-by: Kan Yan Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/usb.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/net/wireless/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/brcm80211/brcmfmac/usb.c index d4a9e8e7deb3..8616961a066e 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/usb.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/usb.c @@ -712,9 +712,6 @@ static int brcmf_usb_up(struct device *dev) struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev); u16 ifnum; - if (devinfo == NULL) - return -EINVAL; - if (devinfo->bus_pub.state == BCMFMAC_USB_STATE_UP) return 0; -- cgit From ac94f196a5fed4915b82d71b9b111867d78df992 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Fri, 2 Mar 2012 22:55:46 +0100 Subject: brcm80211: fmac: remove brcmf_usb_attrib structure Several fields in this structure are only written once or not used at all. Remaining two fields have been moved and brcmf_usb_attrib definition has been removed. Reviewed-by: Pieter-Paul Giesberts Reviewed-by: Franky (Zhenhui) Lin Reviewed-by: Kan Yan Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/usb.c | 17 +++++++++-------- drivers/net/wireless/brcm80211/brcmfmac/usb.h | 16 ++-------------- 2 files changed, 11 insertions(+), 22 deletions(-) diff --git a/drivers/net/wireless/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/brcm80211/brcmfmac/usb.c index 8616961a066e..0418a40fce8d 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/usb.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/usb.c @@ -897,8 +897,8 @@ brcmf_usb_dlneeded(struct brcmf_usbdev_info *devinfo) sizeof(struct bootrom_id_le)); return false; } else { - devinfo->bus_pub.attrib.devid = chipid; - devinfo->bus_pub.attrib.chiprev = chiprev; + devinfo->bus_pub.devid = chipid; + devinfo->bus_pub.chiprev = chiprev; } return true; } @@ -1064,7 +1064,7 @@ static int brcmf_usb_dlstart(struct brcmf_usbdev_info *devinfo, u8 *fw, int len) if (devinfo == NULL) return -EINVAL; - if (devinfo->bus_pub.attrib.devid == 0xDEAD) + if (devinfo->bus_pub.devid == 0xDEAD) return -EINVAL; err = brcmf_usb_dl_writeimage(devinfo, fw, len); @@ -1085,7 +1085,7 @@ static int brcmf_usb_dlrun(struct brcmf_usbdev_info *devinfo) if (!devinfo) return -EINVAL; - if (devinfo->bus_pub.attrib.devid == 0xDEAD) + if (devinfo->bus_pub.devid == 0xDEAD) return -EINVAL; /* Check we are runnable */ @@ -1124,18 +1124,19 @@ static bool brcmf_usb_chip_support(int chipid, int chiprev) static int brcmf_usb_fw_download(struct brcmf_usbdev_info *devinfo) { - struct brcmf_usb_attrib *attr; + int devid, chiprev; int err; brcmf_dbg(TRACE, "enter\n"); if (devinfo == NULL) return -ENODEV; - attr = &devinfo->bus_pub.attrib; + devid = devinfo->bus_pub.devid; + chiprev = devinfo->bus_pub.chiprev; - if (!brcmf_usb_chip_support(attr->devid, attr->chiprev)) { + if (!brcmf_usb_chip_support(devid, chiprev)) { brcmf_dbg(ERROR, "unsupported chip %d rev %d\n", - attr->devid, attr->chiprev); + devid, chiprev); return -EINVAL; } diff --git a/drivers/net/wireless/brcm80211/brcmfmac/usb.h b/drivers/net/wireless/brcm80211/brcmfmac/usb.h index b31da7b83ff7..3377d63e6c8b 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/usb.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/usb.h @@ -50,19 +50,6 @@ struct brcmf_stats { }; -struct brcmf_usb_attrib { - int bustype; - int vid; - int pid; - int devid; - int chiprev; /* chip revsion number */ - int mtu; - int nchan; /* Data Channels */ - int has_2nd_bulk_in_ep; -}; - -struct brcmf_usbdev_info; - struct brcmf_usbdev { struct brcmf_bus *bus; struct brcmf_usbdev_info *devinfo; @@ -70,7 +57,8 @@ struct brcmf_usbdev { struct brcmf_stats stats; int ntxq, nrxq, rxsize; u32 bus_mtu; - struct brcmf_usb_attrib attrib; + int devid; + int chiprev; /* chip revsion number */ }; /* IO Request Block (IRB) */ -- cgit From 1d9c1796bc448d76429e0937ef69e4f29cd1adad Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Fri, 2 Mar 2012 22:55:47 +0100 Subject: brcm80211: fmac: use counters in brcmf_bus structure The usb code defines a structure for counting statistics. However, it should use the statistics entry provided in brcmf_bus as that is exposed to the net_device. The usb private statistics counter only remains with counters for control packets between driver and usb device. Reviewed-by: Pieter-Paul Giesberts Reviewed-by: Franky (Zhenhui) Lin Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/usb.c | 8 ++++---- drivers/net/wireless/brcm80211/brcmfmac/usb.h | 11 ----------- 2 files changed, 4 insertions(+), 15 deletions(-) diff --git a/drivers/net/wireless/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/brcm80211/brcmfmac/usb.c index 0418a40fce8d..a2a0c45201ac 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/usb.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/usb.c @@ -514,9 +514,9 @@ static void brcmf_usb_tx_complete(struct urb *urb) brcmf_usb_del_fromq(devinfo, req); if (urb->status == 0) - devinfo->bus_pub.stats.tx_packets++; + devinfo->bus_pub.bus->dstats.tx_packets++; else - devinfo->bus_pub.stats.tx_errors++; + devinfo->bus_pub.bus->dstats.tx_errors++; dev_kfree_skb(req->skb); req->skb = NULL; @@ -536,9 +536,9 @@ static void brcmf_usb_rx_complete(struct urb *urb) req->skb = NULL; if (urb->status == 0) { - devinfo->bus_pub.stats.rx_packets++; + devinfo->bus_pub.bus->dstats.rx_packets++; } else { - devinfo->bus_pub.stats.rx_errors++; + devinfo->bus_pub.bus->dstats.rx_errors++; dev_kfree_skb(skb); brcmf_usb_enq(devinfo, &devinfo->rx_freeq, req); return; diff --git a/drivers/net/wireless/brcm80211/brcmfmac/usb.h b/drivers/net/wireless/brcm80211/brcmfmac/usb.h index 3377d63e6c8b..acfa5e89872f 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/usb.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/usb.h @@ -33,21 +33,10 @@ enum brcmf_usb_pnp_state { }; struct brcmf_stats { - u32 tx_errors; - u32 tx_packets; - u32 tx_multicast; u32 tx_ctlpkts; u32 tx_ctlerrs; - u32 tx_dropped; - u32 tx_flushed; - u32 rx_errors; - u32 rx_packets; - u32 rx_multicast; u32 rx_ctlpkts; u32 rx_ctlerrs; - u32 rx_dropped; - u32 rx_flushed; - }; struct brcmf_usbdev { -- cgit From 549040abbc03e87bdee2964fea5e4c827471d4df Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Fri, 2 Mar 2012 22:55:48 +0100 Subject: brcm80211: fmac: initialize host interface drivers regardless result The module init function of brcmfmac calls init functions for SDIO and USB doing driver registration. This patch removes terminating the module init when a driver registration for one host interface fails. Reviewed-by: Pieter-Paul Giesberts Reviewed-by: Franky (Zhenhui) Lin Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c | 4 +--- drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h | 4 ++-- drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c | 14 +++----------- drivers/net/wireless/brcm80211/brcmfmac/usb.c | 4 ++-- 4 files changed, 8 insertions(+), 18 deletions(-) diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c index 83ca3cc2cccb..4688904908ec 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c @@ -604,7 +604,7 @@ void brcmf_sdio_exit(void) sdio_unregister_driver(&brcmf_sdmmc_driver); } -int brcmf_sdio_init(void) +void brcmf_sdio_init(void) { int ret; @@ -614,6 +614,4 @@ int brcmf_sdio_init(void) if (ret) brcmf_dbg(ERROR, "sdio_register_driver failed: %d\n", ret); - - return ret; } diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h index b7671b30692f..366916494be4 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h @@ -108,11 +108,11 @@ extern int brcmf_add_if(struct device *dev, int ifidx, #ifdef CONFIG_BRCMFMAC_SDIO extern void brcmf_sdio_exit(void); -extern int brcmf_sdio_init(void); +extern void brcmf_sdio_init(void); #endif #ifdef CONFIG_BRCMFMAC_USB extern void brcmf_usb_exit(void); -extern int brcmf_usb_init(void); +extern void brcmf_usb_init(void); #endif #endif /* _BRCMF_BUS_H_ */ diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c index c4da05817443..e7345569e9de 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c @@ -1183,21 +1183,13 @@ exit: static int __init brcmfmac_init(void) { - int ret = 0; - #ifdef CONFIG_BRCMFMAC_SDIO - ret = brcmf_sdio_init(); - if (ret) - goto fail; + brcmf_sdio_init(); #endif #ifdef CONFIG_BRCMFMAC_USB - ret = brcmf_usb_init(); - if (ret) - goto fail; + brcmf_usb_init(); #endif - -fail: - return ret; + return 0; } static void __exit brcmfmac_exit(void) diff --git a/drivers/net/wireless/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/brcm80211/brcmfmac/usb.c index a2a0c45201ac..82364223e817 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/usb.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/usb.c @@ -1615,7 +1615,7 @@ void brcmf_usb_exit(void) g_image.len = 0; } -int brcmf_usb_init(void) +void brcmf_usb_init(void) { - return usb_register(&brcmf_usbdrvr); + usb_register(&brcmf_usbdrvr); } -- cgit From e64a4b708fd5b719b54f7f969895b66bcba71486 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Fri, 2 Mar 2012 22:55:49 +0100 Subject: brcm80211: fmac: remove firmware requests from init_module syscall As indicated in [1] on netdev mailing list drivers should not block on the init_module() syscall. This patch defers the actual driver registration to a workqueue so the init_module() syscall can complete without delay. [1] http://article.gmane.org/gmane.linux.network/217729/ Reviewed-by: Pieter-Paul Giesberts Reviewed-by: Franky (Zhenhui) Lin Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c index e7345569e9de..2a1e5ae0c402 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c @@ -1181,7 +1181,7 @@ exit: } #endif /* DEBUG */ -static int __init brcmfmac_init(void) +static void brcmf_driver_init(struct work_struct *work) { #ifdef CONFIG_BRCMFMAC_SDIO brcmf_sdio_init(); @@ -1189,11 +1189,21 @@ static int __init brcmfmac_init(void) #ifdef CONFIG_BRCMFMAC_USB brcmf_usb_init(); #endif +} +static DECLARE_WORK(brcmf_driver_work, brcmf_driver_init); + +static int __init brcmfmac_module_init(void) +{ + if (!schedule_work(&brcmf_driver_work)) + return -EBUSY; + return 0; } -static void __exit brcmfmac_exit(void) +static void __exit brcmfmac_module_exit(void) { + cancel_work_sync(&brcmf_driver_work); + #ifdef CONFIG_BRCMFMAC_SDIO brcmf_sdio_exit(); #endif @@ -1202,5 +1212,5 @@ static void __exit brcmfmac_exit(void) #endif } -module_init(brcmfmac_init); -module_exit(brcmfmac_exit); +module_init(brcmfmac_module_init); +module_exit(brcmfmac_module_exit); -- cgit From b0c359b2f68e982ac9334a5f2c04c3a67dee4d50 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Fri, 2 Mar 2012 22:55:50 +0100 Subject: brcm80211: smac: remove firmware requests from init_module syscall As indicated in [1] on netdev mailing list drivers should not block on the init_module() syscall. This patch defers the actual driver registration to a workqueue so the init_module() syscall can complete without delay. [1] http://article.gmane.org/gmane.linux.network/217729/ Reviewed-by: Pieter-Paul Giesberts Reviewed-by: Alwin Beukers Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- .../net/wireless/brcm80211/brcmsmac/mac80211_if.c | 31 +++++++++++++--------- 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c index fec0f10773e5..569ab8abd2a1 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c @@ -1169,25 +1169,31 @@ static struct bcma_driver brcms_bcma_driver = { /** * This is the main entry point for the brcmsmac driver. * - * This function determines if a device pointed to by pdev is a WL device, - * and if so, performs a brcms_attach() on it. - * + * This function is scheduled upon module initialization and + * does the driver registration, which result in brcms_bcma_probe() + * call resulting in the driver bringup. */ -static int __init brcms_module_init(void) +static void brcms_driver_init(struct work_struct *work) { - int error = -ENODEV; + int error; + error = bcma_driver_register(&brcms_bcma_driver); + if (error) + pr_err("%s: register returned %d\n", __func__, error); +} + +static DECLARE_WORK(brcms_driver_work, brcms_driver_init); + +static int __init brcms_module_init(void) +{ #ifdef DEBUG if (msglevel != 0xdeadbeef) brcm_msg_level = msglevel; -#endif /* DEBUG */ - - error = bcma_driver_register(&brcms_bcma_driver); - pr_err("%s: register returned %d\n", __func__, error); - if (!error) - return 0; +#endif + if (!schedule_work(&brcms_driver_work)) + return -EBUSY; - return error; + return 0; } /** @@ -1199,6 +1205,7 @@ static int __init brcms_module_init(void) */ static void __exit brcms_module_exit(void) { + cancel_work_sync(&brcms_driver_work); bcma_driver_unregister(&brcms_bcma_driver); } -- cgit From 769009b89d8c29c410a99eee3cd63764b1fff869 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Fri, 2 Mar 2012 22:55:51 +0100 Subject: brcm80211: smac: cleanup couple of debug output statements Tidying up some debug statements in brcms_c_ampdu_dotxstatus_complete() that got broken strings to satisfy checkpatch, but the rules changed. Reviewed-by: Pieter-Paul Giesberts Reviewed-by: Alwin Beukers Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmsmac/ampdu.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c b/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c index dbee69620a90..95b5902bc4b3 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c @@ -959,14 +959,13 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, if (supr_status) { update_rate = false; if (supr_status == TX_STATUS_SUPR_BADCH) { - wiphy_err(wiphy, "%s: Pkt tx suppressed, " - "illegal channel possibly %d\n", + wiphy_err(wiphy, + "%s: Pkt tx suppressed, illegal channel possibly %d\n", __func__, CHSPEC_CHANNEL( wlc->default_bss->chanspec)); } else { if (supr_status != TX_STATUS_SUPR_FRAG) - wiphy_err(wiphy, "%s:" - "supr_status 0x%x\n", + wiphy_err(wiphy, "%s: supr_status 0x%x\n", __func__, supr_status); } /* no need to retry for badch; will fail again */ @@ -988,9 +987,8 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, } } else if (txs->phyerr) { update_rate = false; - wiphy_err(wiphy, "wl%d: ampdu tx phy " - "error (0x%x)\n", wlc->pub->unit, - txs->phyerr); + wiphy_err(wiphy, "%s: ampdu tx phy error (0x%x)\n", + __func__, txs->phyerr); if (brcm_msg_level & LOG_ERROR_VAL) { brcmu_prpkt("txpkt (AMPDU)", p); @@ -1018,10 +1016,10 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, ack_recd = false; if (ba_recd) { bindex = MODSUB_POW2(seq, start_seq, SEQNUM_MAX); - BCMMSG(wlc->wiphy, "tid %d seq %d," - " start_seq %d, bindex %d set %d, index %d\n", - tid, seq, start_seq, bindex, - isset(bitmap, bindex), index); + BCMMSG(wiphy, + "tid %d seq %d, start_seq %d, bindex %d set %d, index %d\n", + tid, seq, start_seq, bindex, + isset(bitmap, bindex), index); /* if acked then clear bit and free packet */ if ((bindex < AMPDU_TX_BA_MAX_WSIZE) && isset(bitmap, bindex)) { -- cgit From 804483e90794256f9ed53e795ffbf1e94de237c8 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 5 Mar 2012 22:18:41 +0100 Subject: cfg80211/mac80211: report signal strength for mgmt frames Add the signal strength (in dBm only for now) to frames that are received via nl80211's various frame APIs. Signed-off-by: Johannes Berg Acked-by: Kalle Valo Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath6kl/wmi.c | 6 ++++-- include/linux/nl80211.h | 6 ++++++ include/net/cfg80211.h | 8 +++++--- net/mac80211/rx.c | 13 +++++++++++-- net/wireless/mlme.c | 7 ++++--- net/wireless/nl80211.c | 9 +++++++-- net/wireless/nl80211.h | 3 ++- 7 files changed, 39 insertions(+), 13 deletions(-) diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c b/drivers/net/wireless/ath/ath6kl/wmi.c index 18fa9aa8af92..97abf4699b41 100644 --- a/drivers/net/wireless/ath/ath6kl/wmi.c +++ b/drivers/net/wireless/ath/ath6kl/wmi.c @@ -556,7 +556,8 @@ static int ath6kl_wmi_rx_probe_req_event_rx(struct wmi *wmi, u8 *datap, int len, dlen, freq, vif->probe_req_report); if (vif->probe_req_report || vif->nw_type == AP_NETWORK) - cfg80211_rx_mgmt(vif->ndev, freq, ev->data, dlen, GFP_ATOMIC); + cfg80211_rx_mgmt(vif->ndev, freq, 0, + ev->data, dlen, GFP_ATOMIC); return 0; } @@ -595,7 +596,8 @@ static int ath6kl_wmi_rx_action_event_rx(struct wmi *wmi, u8 *datap, int len, return -EINVAL; } ath6kl_dbg(ATH6KL_DBG_WMI, "rx_action: len=%u freq=%u\n", dlen, freq); - cfg80211_rx_mgmt(vif->ndev, freq, ev->data, dlen, GFP_ATOMIC); + cfg80211_rx_mgmt(vif->ndev, freq, 0, + ev->data, dlen, GFP_ATOMIC); return 0; } diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h index 9f46c62b1eee..c37d67add090 100644 --- a/include/linux/nl80211.h +++ b/include/linux/nl80211.h @@ -1203,6 +1203,10 @@ enum nl80211_commands { * the list. This needs to be used when the driver advertises the * capability to timeout the stations. * + * @NL80211_ATTR_RX_SIGNAL_DBM: signal strength in dBm (as a 32-bit int); + * this attribute is (depending on the driver capabilities) added to + * received frames indicated with %NL80211_CMD_FRAME. + * * @NL80211_ATTR_MAX: highest attribute number currently defined * @__NL80211_ATTR_AFTER_LAST: internal use */ @@ -1450,6 +1454,8 @@ enum nl80211_attrs { NL80211_ATTR_INACTIVITY_TIMEOUT, + NL80211_ATTR_RX_SIGNAL_DBM, + /* add attributes here, update the policy in nl80211.c */ __NL80211_ATTR_AFTER_LAST, diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 804805827736..4682c35a92c4 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -3189,6 +3189,7 @@ void cfg80211_del_sta(struct net_device *dev, const u8 *mac_addr, gfp_t gfp); * cfg80211_rx_mgmt - notification of received, unprocessed management frame * @dev: network device * @freq: Frequency on which the frame was received in MHz + * @sig_dbm: signal strength in mBm, or 0 if unknown * @buf: Management frame (header + body) * @len: length of the frame data * @gfp: context flags @@ -3201,8 +3202,8 @@ void cfg80211_del_sta(struct net_device *dev, const u8 *mac_addr, gfp_t gfp); * This function is called whenever an Action frame is received for a station * mode interface, but is not processed in kernel. */ -bool cfg80211_rx_mgmt(struct net_device *dev, int freq, const u8 *buf, - size_t len, gfp_t gfp); +bool cfg80211_rx_mgmt(struct net_device *dev, int freq, int sig_dbm, + const u8 *buf, size_t len, gfp_t gfp); /** * cfg80211_mgmt_tx_status - notification of TX status for management frame @@ -3315,6 +3316,7 @@ void cfg80211_probe_status(struct net_device *dev, const u8 *addr, * @frame: the frame * @len: length of the frame * @freq: frequency the frame was received on + * @sig_dbm: signal strength in mBm, or 0 if unknown * @gfp: allocation flags * * Use this function to report to userspace when a beacon was @@ -3323,7 +3325,7 @@ void cfg80211_probe_status(struct net_device *dev, const u8 *addr, */ void cfg80211_report_obss_beacon(struct wiphy *wiphy, const u8 *frame, size_t len, - int freq, gfp_t gfp); + int freq, int sig_dbm, gfp_t gfp); /* * cfg80211_can_beacon_sec_chan - test if ht40 on extension channel can be used diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 10bbbd33b314..5f6e32ca0858 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -2188,9 +2188,14 @@ ieee80211_rx_h_mgmt_check(struct ieee80211_rx_data *rx) if (rx->sdata->vif.type == NL80211_IFTYPE_AP && ieee80211_is_beacon(mgmt->frame_control) && !(rx->flags & IEEE80211_RX_BEACON_REPORTED)) { + int sig = 0; + + if (rx->local->hw.flags & IEEE80211_HW_SIGNAL_DBM) + sig = status->signal; + cfg80211_report_obss_beacon(rx->local->hw.wiphy, rx->skb->data, rx->skb->len, - status->freq, GFP_ATOMIC); + status->freq, sig, GFP_ATOMIC); rx->flags |= IEEE80211_RX_BEACON_REPORTED; } @@ -2414,6 +2419,7 @@ static ieee80211_rx_result debug_noinline ieee80211_rx_h_userspace_mgmt(struct ieee80211_rx_data *rx) { struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb); + int sig = 0; /* skip known-bad action frames and return them in the next handler */ if (status->rx_flags & IEEE80211_RX_MALFORMED_ACTION_FRM) @@ -2426,7 +2432,10 @@ ieee80211_rx_h_userspace_mgmt(struct ieee80211_rx_data *rx) * it transmitted were processed or returned. */ - if (cfg80211_rx_mgmt(rx->sdata->dev, status->freq, + if (rx->local->hw.flags & IEEE80211_HW_SIGNAL_DBM) + sig = status->signal; + + if (cfg80211_rx_mgmt(rx->sdata->dev, status->freq, sig, rx->skb->data, rx->skb->len, GFP_ATOMIC)) { if (rx->sta) diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c index fb1e72179117..f5a7ac3a0939 100644 --- a/net/wireless/mlme.c +++ b/net/wireless/mlme.c @@ -814,8 +814,8 @@ int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev, cookie); } -bool cfg80211_rx_mgmt(struct net_device *dev, int freq, const u8 *buf, - size_t len, gfp_t gfp) +bool cfg80211_rx_mgmt(struct net_device *dev, int freq, int sig_mbm, + const u8 *buf, size_t len, gfp_t gfp) { struct wireless_dev *wdev = dev->ieee80211_ptr; struct wiphy *wiphy = wdev->wiphy; @@ -854,7 +854,8 @@ bool cfg80211_rx_mgmt(struct net_device *dev, int freq, const u8 *buf, /* found match! */ /* Indicate the received Action frame to user space */ - if (nl80211_send_mgmt(rdev, dev, reg->nlpid, freq, + if (nl80211_send_mgmt(rdev, dev, reg->nlpid, + freq, sig_mbm, buf, len, gfp)) continue; diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 4b6afc338aac..39dbdf2adb12 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -7686,7 +7686,8 @@ bool nl80211_unexpected_4addr_frame(struct net_device *dev, int nl80211_send_mgmt(struct cfg80211_registered_device *rdev, struct net_device *netdev, u32 nlpid, - int freq, const u8 *buf, size_t len, gfp_t gfp) + int freq, int sig_dbm, + const u8 *buf, size_t len, gfp_t gfp) { struct sk_buff *msg; void *hdr; @@ -7704,6 +7705,8 @@ int nl80211_send_mgmt(struct cfg80211_registered_device *rdev, NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx); NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex); NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, freq); + if (sig_dbm) + NLA_PUT_U32(msg, NL80211_ATTR_RX_SIGNAL_DBM, sig_dbm); NLA_PUT(msg, NL80211_ATTR_FRAME, len, buf); genlmsg_end(msg, hdr); @@ -7965,7 +7968,7 @@ EXPORT_SYMBOL(cfg80211_probe_status); void cfg80211_report_obss_beacon(struct wiphy *wiphy, const u8 *frame, size_t len, - int freq, gfp_t gfp) + int freq, int sig_dbm, gfp_t gfp) { struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); struct sk_buff *msg; @@ -7988,6 +7991,8 @@ void cfg80211_report_obss_beacon(struct wiphy *wiphy, NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx); if (freq) NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, freq); + if (sig_dbm) + NLA_PUT_U32(msg, NL80211_ATTR_RX_SIGNAL_DBM, sig_dbm); NLA_PUT(msg, NL80211_ATTR_FRAME, len, frame); genlmsg_end(msg, hdr); diff --git a/net/wireless/nl80211.h b/net/wireless/nl80211.h index 12bf4d185abe..4ffe50df9f31 100644 --- a/net/wireless/nl80211.h +++ b/net/wireless/nl80211.h @@ -92,7 +92,8 @@ void nl80211_send_sta_del_event(struct cfg80211_registered_device *rdev, gfp_t gfp); int nl80211_send_mgmt(struct cfg80211_registered_device *rdev, - struct net_device *netdev, u32 nlpid, int freq, + struct net_device *netdev, u32 nlpid, + int freq, int sig_dbm, const u8 *buf, size_t len, gfp_t gfp); void nl80211_send_mgmt_tx_status(struct cfg80211_registered_device *rdev, struct net_device *netdev, u64 cookie, -- cgit From da473b61ad9e25e2ac3efb58d95c5b573260c6a8 Mon Sep 17 00:00:00 2001 From: Chun-Yeow Yeoh Date: Sat, 3 Mar 2012 09:48:56 +0800 Subject: ath5k: allow AP and mesh mode to operate simultaneously This patch allows the possibility of having the mesh point and AP to be operated simultaneously in one single radio. Previously, mesh point fails to generate the mesh beacon if virtual AP is created for the same radio. Signed-off-by: Chun-Yeow Yeoh Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/ath5k.h | 1 + drivers/net/wireless/ath/ath5k/base.c | 6 ++++-- drivers/net/wireless/ath/ath5k/mac80211-ops.c | 4 ++++ 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h index 6640326f7005..8d434b8f5855 100644 --- a/drivers/net/wireless/ath/ath5k/ath5k.h +++ b/drivers/net/wireless/ath/ath5k/ath5k.h @@ -1320,6 +1320,7 @@ struct ath5k_hw { struct ieee80211_vif *bslot[ATH_BCBUF]; u16 num_ap_vifs; u16 num_adhoc_vifs; + u16 num_mesh_vifs; unsigned int bhalq, /* SW q for outgoing beacons */ bmisscount, /* missed beacon transmits */ bintval, /* beacon interval in TU */ diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index a339693fbe26..b51d58c414d2 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -1867,7 +1867,8 @@ ath5k_beacon_send(struct ath5k_hw *ah) ah->bmisscount = 0; } - if ((ah->opmode == NL80211_IFTYPE_AP && ah->num_ap_vifs > 1) || + if ((ah->opmode == NL80211_IFTYPE_AP && ah->num_ap_vifs + + ah->num_mesh_vifs > 1) || ah->opmode == NL80211_IFTYPE_MESH_POINT) { u64 tsf = ath5k_hw_get_tsf64(ah); u32 tsftu = TSF_TO_TU(tsf); @@ -1952,7 +1953,8 @@ ath5k_beacon_update_timers(struct ath5k_hw *ah, u64 bc_tsf) u64 hw_tsf; intval = ah->bintval & AR5K_BEACON_PERIOD; - if (ah->opmode == NL80211_IFTYPE_AP && ah->num_ap_vifs > 1) { + if (ah->opmode == NL80211_IFTYPE_AP && ah->num_ap_vifs + + ah->num_mesh_vifs > 1) { intval /= ATH_BCBUF; /* staggered multi-bss beacons */ if (intval < 15) ATH5K_WARN(ah, "intval %u is too low, min 15\n", diff --git a/drivers/net/wireless/ath/ath5k/mac80211-ops.c b/drivers/net/wireless/ath/ath5k/mac80211-ops.c index af4c7ecb4b30..5c5329955414 100644 --- a/drivers/net/wireless/ath/ath5k/mac80211-ops.c +++ b/drivers/net/wireless/ath/ath5k/mac80211-ops.c @@ -134,6 +134,8 @@ ath5k_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) ah->num_ap_vifs++; else if (avf->opmode == NL80211_IFTYPE_ADHOC) ah->num_adhoc_vifs++; + else if (avf->opmode == NL80211_IFTYPE_MESH_POINT) + ah->num_mesh_vifs++; } /* Any MAC address is fine, all others are included through the @@ -175,6 +177,8 @@ ath5k_remove_interface(struct ieee80211_hw *hw, ah->num_ap_vifs--; else if (avf->opmode == NL80211_IFTYPE_ADHOC) ah->num_adhoc_vifs--; + else if (avf->opmode == NL80211_IFTYPE_MESH_POINT) + ah->num_mesh_vifs--; ath5k_update_bssid_mask_and_opmode(ah, NULL); mutex_unlock(&ah->lock); -- cgit From a9b89e2567c743483e6354f64d7a7e3a8c101e9e Mon Sep 17 00:00:00 2001 From: Jingjun Wu Date: Fri, 2 Mar 2012 20:52:14 -0600 Subject: rtlwifi: rtl8192ce: Fix loss of receive performance Driver rtl8192ce when used with the RTL8188CE device would start at about 20 Mbps on a 54 Mbps connection, but quickly drop to 1 Mbps. One of the symptoms is that the AP would need to retransmit each packet 4 of 5 times before the driver would acknowledge it. Recovery is possible only by unloading and reloading the driver. This problem was reported at https://bugzilla.redhat.com/show_bug.cgi?id=770207. The problem is due to a missing update of the gain setting. Signed-off-by: Jingjun Wu Signed-off-by: Larry Finger Cc: Stable Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c index 8646ff2a55ce..d8d73dbb5780 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c +++ b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c @@ -520,6 +520,10 @@ void rtl92c_dm_write_dig(struct ieee80211_hw *hw) dm_digtable.cur_igvalue, dm_digtable.pre_igvalue, dm_digtable.backoff_val); + dm_digtable.cur_igvalue += 2; + if (dm_digtable.cur_igvalue > 0x3f) + dm_digtable.cur_igvalue = 0x3f; + if (dm_digtable.pre_igvalue != dm_digtable.cur_igvalue) { rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, 0x7f, dm_digtable.cur_igvalue); -- cgit From 972a31367f94967716b000fd8fac33d259ebcfed Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Sat, 3 Mar 2012 21:24:43 +0100 Subject: p54: pass interface setup errors back to mac80211 Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/p54/main.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/p54/main.c b/drivers/net/wireless/p54/main.c index 40f4eb7da7b2..ee8af1f047c8 100644 --- a/drivers/net/wireless/p54/main.c +++ b/drivers/net/wireless/p54/main.c @@ -227,6 +227,7 @@ static int p54_add_interface(struct ieee80211_hw *dev, struct ieee80211_vif *vif) { struct p54_common *priv = dev->priv; + int err; vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER; @@ -251,9 +252,9 @@ static int p54_add_interface(struct ieee80211_hw *dev, } memcpy(priv->mac_addr, vif->addr, ETH_ALEN); - p54_setup_mac(priv); + err = p54_setup_mac(priv); mutex_unlock(&priv->conf_mutex); - return 0; + return err; } static void p54_remove_interface(struct ieee80211_hw *dev, -- cgit From 26627687e881e79c8c8f9076f79181c2beefcae7 Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Sat, 3 Mar 2012 21:25:19 +0100 Subject: p54pci: use new driver.pm interface for suspend/resume Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/p54/p54pci.c | 48 +++++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/drivers/net/wireless/p54/p54pci.c b/drivers/net/wireless/p54/p54pci.c index b1f51a215792..45df728183fd 100644 --- a/drivers/net/wireless/p54/p54pci.c +++ b/drivers/net/wireless/p54/p54pci.c @@ -624,36 +624,39 @@ static void __devexit p54p_remove(struct pci_dev *pdev) } #ifdef CONFIG_PM -static int p54p_suspend(struct pci_dev *pdev, pm_message_t state) +static int p54p_suspend(struct device *device) { - struct ieee80211_hw *dev = pci_get_drvdata(pdev); - struct p54p_priv *priv = dev->priv; - - if (priv->common.mode != NL80211_IFTYPE_UNSPECIFIED) { - ieee80211_stop_queues(dev); - p54p_stop(dev); - } + struct pci_dev *pdev = to_pci_dev(device); pci_save_state(pdev); - pci_set_power_state(pdev, pci_choose_state(pdev, state)); + pci_set_power_state(pdev, PCI_D3hot); + pci_disable_device(pdev); return 0; } -static int p54p_resume(struct pci_dev *pdev) +static int p54p_resume(struct device *device) { - struct ieee80211_hw *dev = pci_get_drvdata(pdev); - struct p54p_priv *priv = dev->priv; + struct pci_dev *pdev = to_pci_dev(device); + int err; - pci_set_power_state(pdev, PCI_D0); - pci_restore_state(pdev); + err = pci_reenable_device(pdev); + if (err) + return err; + return pci_set_power_state(pdev, PCI_D0); +} - if (priv->common.mode != NL80211_IFTYPE_UNSPECIFIED) { - p54p_open(dev); - ieee80211_wake_queues(dev); - } +static const struct dev_pm_ops p54pci_pm_ops = { + .suspend = p54p_suspend, + .resume = p54p_resume, + .freeze = p54p_suspend, + .thaw = p54p_resume, + .poweroff = p54p_suspend, + .restore = p54p_resume, +}; - return 0; -} +#define P54P_PM_OPS (&p54pci_pm_ops) +#else +#define P54P_PM_OPS (NULL) #endif /* CONFIG_PM */ static struct pci_driver p54p_driver = { @@ -661,10 +664,7 @@ static struct pci_driver p54p_driver = { .id_table = p54p_table, .probe = p54p_probe, .remove = __devexit_p(p54p_remove), -#ifdef CONFIG_PM - .suspend = p54p_suspend, - .resume = p54p_resume, -#endif /* CONFIG_PM */ + .driver.pm = P54P_PM_OPS, }; static int __init p54p_init(void) -- cgit From 342bbf3fee2fa9a18147e74b2e3c4229a4564912 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Sun, 4 Mar 2012 08:50:46 -0800 Subject: iwlwifi: always monitor for stuck queues If we only monitor while associated, the following can happen: - we're associated, and the queue stuck check runs, setting the queue "touch" time to X - we disassociate, stopping the monitoring, which leaves the time set to X - almost 2s later, we associate, and enqueue a frame - before the frame is transmitted, we monitor for stuck queues, and find the time set to X, although it is now later than X + 2000ms, so we decide that the queue is stuck and erroneously restart the device It happens more with P2P because there we can go between associated/unassociated frequently. Cc: stable@vger.kernel.org Reported-by: Ben Cahill Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-core.c | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 275e08966059..8551c95e7437 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -1345,20 +1345,10 @@ void iwl_bg_watchdog(unsigned long data) if (timeout == 0) return; - /* monitor and check for stuck cmd queue */ - if (iwl_check_stuck_queue(priv, priv->shrd->cmd_queue)) - return; - - /* monitor and check for other stuck queues */ - if (iwl_is_any_associated(priv)) { - for (cnt = 0; cnt < hw_params(priv).max_txq_num; cnt++) { - /* skip as we already checked the command queue */ - if (cnt == priv->shrd->cmd_queue) - continue; - if (iwl_check_stuck_queue(priv, cnt)) - return; - } - } + /* monitor and check for stuck queues */ + for (cnt = 0; cnt < hw_params(priv).max_txq_num; cnt++) + if (iwl_check_stuck_queue(priv, cnt)) + return; mod_timer(&priv->watchdog, jiffies + msecs_to_jiffies(IWL_WD_TICK(timeout))); -- cgit From e9a8e8ec1e487536568adc4b3efa8f56e4391a7b Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Mon, 5 Mar 2012 21:10:07 +0300 Subject: airo: fix test for FLAG_RADIO_DOWN We should be doing a shift (1 << FLAG_RADIO_DOWN) here before testing the flag. As luck would have it, this test works almost correctly. The current code tests for FLAG_RADIO_OFF instead of FLAG_RADIO_DOWN. #define FLAG_RADIO_OFF 0 /* User disabling of MAC */ #define FLAG_RADIO_DOWN 1 /* ifup/ifdown disabling of MAC */ Signed-off-by: Dan Carpenter Signed-off-by: John W. Linville --- drivers/net/wireless/airo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c index 1c008c61b95c..ddc061dd150c 100644 --- a/drivers/net/wireless/airo.c +++ b/drivers/net/wireless/airo.c @@ -1869,7 +1869,7 @@ static int readStatsRid(struct airo_info*ai, StatsRid *sr, int rid, int lock) static void try_auto_wep(struct airo_info *ai) { - if (auto_wep && !(ai->flags & FLAG_RADIO_DOWN)) { + if (auto_wep && !test_bit(FLAG_RADIO_DOWN, &ai->flags)) { ai->expires = RUN_AT(3*HZ); wake_up_interruptible(&ai->thr_wait); } -- cgit From d316383dfdb51d46fb9681a68b395a5735f3f4b3 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 5 Mar 2012 11:24:19 -0800 Subject: iwlwifi: move iwl_clear_driver_stations to user There's only one place using this function, so move it where it's needed. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn.c | 35 ++++++++++++++++++++++++++++++++++ drivers/net/wireless/iwlwifi/iwl-agn.h | 35 ---------------------------------- 2 files changed, 35 insertions(+), 35 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index e0fef9f257c2..a7f3a7023d88 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -738,6 +738,41 @@ int iwl_alive_start(struct iwl_priv *priv) return iwl_power_update_mode(priv, true); } +/** + * iwl_clear_driver_stations - clear knowledge of all stations from driver + * @priv: iwl priv struct + * + * This is called during iwl_down() to make sure that in the case + * we're coming there from a hardware restart mac80211 will be + * able to reconfigure stations -- if we're getting there in the + * normal down flow then the stations will already be cleared. + */ +static void iwl_clear_driver_stations(struct iwl_priv *priv) +{ + unsigned long flags; + struct iwl_rxon_context *ctx; + + spin_lock_irqsave(&priv->shrd->sta_lock, flags); + memset(priv->stations, 0, sizeof(priv->stations)); + priv->num_stations = 0; + + priv->ucode_key_table = 0; + + for_each_context(priv, ctx) { + /* + * Remove all key information that is not stored as part + * of station information since mac80211 may not have had + * a chance to remove all the keys. When device is + * reconfigured by mac80211 after an error all keys will + * be reconfigured. + */ + memset(ctx->wep_keys, 0, sizeof(ctx->wep_keys)); + ctx->key_mapping_keys = 0; + } + + spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); +} + void iwl_down(struct iwl_priv *priv) { int exit_pending; diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index cb484e273b93..ef0cdf5b32fa 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h @@ -232,41 +232,6 @@ int iwl_add_sta_callback(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb, struct iwl_device_cmd *cmd); -/** - * iwl_clear_driver_stations - clear knowledge of all stations from driver - * @priv: iwl priv struct - * - * This is called during iwl_down() to make sure that in the case - * we're coming there from a hardware restart mac80211 will be - * able to reconfigure stations -- if we're getting there in the - * normal down flow then the stations will already be cleared. - */ -static inline void iwl_clear_driver_stations(struct iwl_priv *priv) -{ - unsigned long flags; - struct iwl_rxon_context *ctx; - - spin_lock_irqsave(&priv->shrd->sta_lock, flags); - memset(priv->stations, 0, sizeof(priv->stations)); - priv->num_stations = 0; - - priv->ucode_key_table = 0; - - for_each_context(priv, ctx) { - /* - * Remove all key information that is not stored as part - * of station information since mac80211 may not have had - * a chance to remove all the keys. When device is - * reconfigured by mac80211 after an error all keys will - * be reconfigured. - */ - memset(ctx->wep_keys, 0, sizeof(ctx->wep_keys)); - ctx->key_mapping_keys = 0; - } - - spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); -} - static inline int iwl_sta_id(struct ieee80211_sta *sta) { if (WARN_ON(!sta)) -- cgit From f2b69ef022aba3fe436bb03664cf12b261cb64d1 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 5 Mar 2012 11:24:20 -0800 Subject: iwlwifi: remove an unused argument The station ID argument to the function iwlagn_tx_cmd_build_hwcrypto isn't used so remove it. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-tx.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c index 5f78567f4180..81a3b0e3a8e0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c @@ -208,10 +208,9 @@ static void iwlagn_tx_cmd_build_rate(struct iwl_priv *priv, } static void iwlagn_tx_cmd_build_hwcrypto(struct iwl_priv *priv, - struct ieee80211_tx_info *info, - struct iwl_tx_cmd *tx_cmd, - struct sk_buff *skb_frag, - int sta_id) + struct ieee80211_tx_info *info, + struct iwl_tx_cmd *tx_cmd, + struct sk_buff *skb_frag) { struct ieee80211_key_conf *keyconf = info->control.hw_key; @@ -358,7 +357,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) tx_cmd->len = cpu_to_le16(len); if (info->control.hw_key) - iwlagn_tx_cmd_build_hwcrypto(priv, info, tx_cmd, skb, sta_id); + iwlagn_tx_cmd_build_hwcrypto(priv, info, tx_cmd, skb); /* TODO need this for burst mode later on */ iwlagn_tx_cmd_build_basic(priv, skb, tx_cmd, info, hdr, sta_id); -- cgit From 71cb99241d63b26a41c9cce6ed441bc30f90224a Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 5 Mar 2012 11:24:21 -0800 Subject: iwlwifi: reduce sta_lock hold time in TX When we TX, we hold the sta_lock for a long time, a lot of which isn't needed. Reduce the time we hold the lock. Note that this doesn't really change anything as the code is already under the other spinlock, but it makes the code easier to read. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-tx.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c index 81a3b0e3a8e0..59509d80f73f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c @@ -341,13 +341,10 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) if (info->flags & IEEE80211_TX_CTL_AMPDU) is_agg = true; - /* irqs already disabled/saved above when locking priv->shrd->lock */ - spin_lock(&priv->shrd->sta_lock); - dev_cmd = kmem_cache_alloc(priv->tx_cmd_pool, GFP_ATOMIC); if (unlikely(!dev_cmd)) - goto drop_unlock_sta; + goto drop_unlock_priv; memset(dev_cmd, 0, sizeof(*dev_cmd)); tx_cmd = (struct iwl_tx_cmd *) dev_cmd->payload; @@ -372,6 +369,9 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) info->driver_data[0] = ctx; info->driver_data[1] = dev_cmd; + /* irqs already disabled/saved above when locking priv->shrd->lock */ + spin_lock(&priv->shrd->sta_lock); + if (ieee80211_is_data_qos(fc) && !ieee80211_is_qos_nullfunc(fc)) { u8 *qc = NULL; struct iwl_tid_data *tid_data; -- cgit From 40e4e6868c532b439754154d69a2837dbf9bd91e Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 5 Mar 2012 11:24:22 -0800 Subject: iwlwifi: simplify code in iwlagn_key_sta_id Simplify the code by returning directly in the error case and replacing the switch/if with a single if statement. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-sta.c | 21 ++++----------------- 1 file changed, 4 insertions(+), 17 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c index f1298cd6a19a..3eb8fd4771b6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c @@ -1080,32 +1080,19 @@ static u8 iwlagn_key_sta_id(struct iwl_priv *priv, struct ieee80211_sta *sta) { struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; - u8 sta_id = IWL_INVALID_STATION; if (sta) - sta_id = iwl_sta_id(sta); + return iwl_sta_id(sta); /* * The device expects GTKs for station interfaces to be * installed as GTKs for the AP station. If we have no * station ID, then use the ap_sta_id in that case. */ - if (!sta && vif && vif_priv->ctx) { - switch (vif->type) { - case NL80211_IFTYPE_STATION: - sta_id = vif_priv->ctx->ap_sta_id; - break; - default: - /* - * In all other cases, the key will be - * used either for TX only or is bound - * to a station already. - */ - break; - } - } + if (vif->type == NL80211_IFTYPE_STATION && vif_priv->ctx) + return vif_priv->ctx->ap_sta_id; - return sta_id; + return IWL_INVALID_STATION; } static int iwlagn_send_sta_key(struct iwl_priv *priv, -- cgit From 9451ca1a31be44f8235c3f8f998ff27fc7a8395e Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 5 Mar 2012 11:24:23 -0800 Subject: iwlwifi: build some station commands directly In the powersave related functions we only need to set a few parameters for the station command and can otherwise leave it blank -- there's no need to copy it from the database. This allows us to not use the sta lock here. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-sta.c | 20 +++++++++----------- drivers/net/wireless/iwlwifi/iwl-mac80211.c | 16 ++++++---------- 2 files changed, 15 insertions(+), 21 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c index 3eb8fd4771b6..6b9af994cfa4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c @@ -1437,16 +1437,14 @@ int iwl_sta_rx_agg_stop(struct iwl_priv *priv, struct ieee80211_sta *sta, void iwl_sta_modify_sleep_tx_count(struct iwl_priv *priv, int sta_id, int cnt) { - unsigned long flags; - - spin_lock_irqsave(&priv->shrd->sta_lock, flags); - priv->stations[sta_id].sta.station_flags |= STA_FLG_PWR_SAVE_MSK; - priv->stations[sta_id].sta.station_flags_msk = STA_FLG_PWR_SAVE_MSK; - priv->stations[sta_id].sta.sta.modify_mask = - STA_MODIFY_SLEEP_TX_COUNT_MSK; - priv->stations[sta_id].sta.sleep_tx_count = cpu_to_le16(cnt); - priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; - iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC); - spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); + struct iwl_addsta_cmd cmd = { + .mode = STA_CONTROL_MODIFY_MSK, + .station_flags = STA_FLG_PWR_SAVE_MSK, + .station_flags_msk = STA_FLG_PWR_SAVE_MSK, + .sta.sta_id = sta_id, + .sta.modify_mask = STA_MODIFY_SLEEP_TX_COUNT_MSK, + .sleep_tx_count = cpu_to_le16(cnt), + }; + iwl_send_add_sta(priv, &cmd, CMD_ASYNC); } diff --git a/drivers/net/wireless/iwlwifi/iwl-mac80211.c b/drivers/net/wireless/iwlwifi/iwl-mac80211.c index 03f770543d8e..9fba532d35cd 100644 --- a/drivers/net/wireless/iwlwifi/iwl-mac80211.c +++ b/drivers/net/wireless/iwlwifi/iwl-mac80211.c @@ -1505,17 +1505,13 @@ static int iwlagn_mac_sta_remove(struct ieee80211_hw *hw, static void iwl_sta_modify_ps_wake(struct iwl_priv *priv, int sta_id) { - unsigned long flags; - - spin_lock_irqsave(&priv->shrd->sta_lock, flags); - priv->stations[sta_id].sta.station_flags &= ~STA_FLG_PWR_SAVE_MSK; - priv->stations[sta_id].sta.station_flags_msk = STA_FLG_PWR_SAVE_MSK; - priv->stations[sta_id].sta.sta.modify_mask = 0; - priv->stations[sta_id].sta.sleep_tx_count = 0; - priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; - iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC); - spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); + struct iwl_addsta_cmd cmd = { + .mode = STA_CONTROL_MODIFY_MSK, + .station_flags_msk = STA_FLG_PWR_SAVE_MSK, + .sta.sta_id = sta_id, + }; + iwl_send_add_sta(priv, &cmd, CMD_ASYNC); } static void iwlagn_mac_sta_notify(struct ieee80211_hw *hw, -- cgit From 015c15e1067c988fc87fb550b222f075c8d3f47c Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 5 Mar 2012 11:24:24 -0800 Subject: iwlwifi: introduce per-queue locks Instead of (ab)using the sta_lock, make the transport layer lock its own TX queue data structures with a lock per queue. This also unifies with the cmd queue lock. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h | 2 ++ drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c | 20 +++++++++------ drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | 31 ++++++++++++++--------- drivers/net/wireless/iwlwifi/iwl-trans.h | 2 -- 4 files changed, 33 insertions(+), 22 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h index 5b26b71ae3d5..b1029468ccbd 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h @@ -169,6 +169,7 @@ struct iwl_queue { * @meta: array of meta data for each command/tx buffer * @dma_addr_cmd: physical address of cmd/tx buffer array * @txb: array of per-TFD driver data + * lock: queue lock * @time_stamp: time (in jiffies) of last read_ptr change * @need_update: indicates need to update read/write index * @sched_retry: indicates queue is high-throughput aggregation (HT AGG) enabled @@ -187,6 +188,7 @@ struct iwl_tx_queue { struct iwl_device_cmd **cmd; struct iwl_cmd_meta *meta; struct sk_buff **skbs; + spinlock_t lock; unsigned long time_stamp; u8 need_update; u8 sched_retry; diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c index 82e34484fa5e..1cb1dd29b3fe 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c @@ -217,6 +217,8 @@ void iwlagn_txq_free_tfd(struct iwl_trans *trans, struct iwl_tx_queue *txq, { struct iwl_tfd *tfd_tmp = txq->tfds; + lockdep_assert_held(&txq->lock); + iwlagn_unmap_tfd(trans, &txq->meta[index], &tfd_tmp[index], dma_dir); /* free SKB */ @@ -621,7 +623,6 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd) struct iwl_device_cmd *out_cmd; struct iwl_cmd_meta *out_meta; dma_addr_t phys_addr; - unsigned long flags; u32 idx; u16 copy_size, cmd_size; bool is_ct_kill = false; @@ -680,10 +681,10 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd) return -EIO; } - spin_lock_irqsave(&trans->hcmd_lock, flags); + spin_lock_bh(&txq->lock); if (iwl_queue_space(q) < ((cmd->flags & CMD_ASYNC) ? 2 : 1)) { - spin_unlock_irqrestore(&trans->hcmd_lock, flags); + spin_unlock_bh(&txq->lock); IWL_ERR(trans, "No space in command queue\n"); is_ct_kill = iwl_check_for_ct_kill(priv(trans)); @@ -790,7 +791,7 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd) iwl_txq_update_write_ptr(trans, txq); out: - spin_unlock_irqrestore(&trans->hcmd_lock, flags); + spin_unlock_bh(&txq->lock); return idx; } @@ -809,6 +810,8 @@ static void iwl_hcmd_queue_reclaim(struct iwl_trans *trans, int txq_id, struct iwl_queue *q = &txq->q; int nfreed = 0; + lockdep_assert_held(&txq->lock); + if ((idx >= q->n_bd) || (iwl_queue_used(q, idx) == 0)) { IWL_ERR(trans, "%s: Read index for DMA queue txq id (%d), " "index %d is out of range [0-%d] %d %d.\n", __func__, @@ -850,7 +853,6 @@ void iwl_tx_cmd_complete(struct iwl_trans *trans, struct iwl_rx_mem_buffer *rxb, struct iwl_cmd_meta *meta; struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); struct iwl_tx_queue *txq = &trans_pcie->txq[trans->shrd->cmd_queue]; - unsigned long flags; /* If a Tx command is being handled and it isn't in the actual * command queue then there a command routing bug has been introduced @@ -864,6 +866,8 @@ void iwl_tx_cmd_complete(struct iwl_trans *trans, struct iwl_rx_mem_buffer *rxb, return; } + spin_lock(&txq->lock); + cmd_index = get_cmd_index(&txq->q, index); cmd = txq->cmd[cmd_index]; meta = &txq->meta[cmd_index]; @@ -880,8 +884,6 @@ void iwl_tx_cmd_complete(struct iwl_trans *trans, struct iwl_rx_mem_buffer *rxb, rxb->page = NULL; } - spin_lock_irqsave(&trans->hcmd_lock, flags); - iwl_hcmd_queue_reclaim(trans, txq_id, index); if (!(meta->flags & CMD_ASYNC)) { @@ -898,7 +900,7 @@ void iwl_tx_cmd_complete(struct iwl_trans *trans, struct iwl_rx_mem_buffer *rxb, meta->flags = 0; - spin_unlock_irqrestore(&trans->hcmd_lock, flags); + spin_unlock(&txq->lock); } #define HOST_COMPLETE_TIMEOUT (2 * HZ) @@ -1041,6 +1043,8 @@ int iwl_tx_queue_reclaim(struct iwl_trans *trans, int txq_id, int index, if (WARN_ON(txq_id == trans->shrd->cmd_queue)) return 0; + lockdep_assert_held(&txq->lock); + /*Since we free until index _not_ inclusive, the one before index is * the last we will free. This one must be used */ last_to_free = iwl_queue_dec_wrap(index, q->n_bd); diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c index 9f8b23909404..f47426a5ef4d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c @@ -390,6 +390,8 @@ static int iwl_trans_txq_init(struct iwl_trans *trans, struct iwl_tx_queue *txq, if (ret) return ret; + spin_lock_init(&txq->lock); + /* * Tell nic where to find circular buffer of Tx Frame Descriptors for * given Tx queue, and enable the DMA channel used for that queue. @@ -409,8 +411,6 @@ static void iwl_tx_queue_unmap(struct iwl_trans *trans, int txq_id) struct iwl_tx_queue *txq = &trans_pcie->txq[txq_id]; struct iwl_queue *q = &txq->q; enum dma_data_direction dma_dir; - unsigned long flags; - spinlock_t *lock; if (!q->n_bd) return; @@ -418,22 +418,19 @@ static void iwl_tx_queue_unmap(struct iwl_trans *trans, int txq_id) /* In the command queue, all the TBs are mapped as BIDI * so unmap them as such. */ - if (txq_id == trans->shrd->cmd_queue) { + if (txq_id == trans->shrd->cmd_queue) dma_dir = DMA_BIDIRECTIONAL; - lock = &trans->hcmd_lock; - } else { + else dma_dir = DMA_TO_DEVICE; - lock = &trans->shrd->sta_lock; - } - spin_lock_irqsave(lock, flags); + spin_lock_bh(&txq->lock); while (q->write_ptr != q->read_ptr) { /* The read_ptr needs to bound by q->n_window */ iwlagn_txq_free_tfd(trans, txq, get_cmd_index(q, q->read_ptr), dma_dir); q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd); } - spin_unlock_irqrestore(lock, flags); + spin_unlock_bh(&txq->lock); } /** @@ -1358,6 +1355,8 @@ static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, txq = &trans_pcie->txq[txq_id]; q = &txq->q; + spin_lock(&txq->lock); + /* In AGG mode, the index in the ring must correspond to the WiFi * sequence number. This is a HW requirements to help the SCD to parse * the BA. @@ -1404,7 +1403,7 @@ static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, &dev_cmd->hdr, firstlen, DMA_BIDIRECTIONAL); if (unlikely(dma_mapping_error(trans->dev, txcmd_phys))) - return -1; + goto out_err; dma_unmap_addr_set(out_meta, mapping, txcmd_phys); dma_unmap_len_set(out_meta, len, firstlen); @@ -1426,7 +1425,7 @@ static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, dma_unmap_addr(out_meta, mapping), dma_unmap_len(out_meta, len), DMA_BIDIRECTIONAL); - return -1; + goto out_err; } } @@ -1481,7 +1480,11 @@ static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, iwl_stop_queue(trans, txq, "Queue is full"); } } + spin_unlock(&txq->lock); return 0; + out_err: + spin_unlock(&txq->lock); + return -1; } static int iwl_trans_pcie_start_hw(struct iwl_trans *trans) @@ -1560,6 +1563,8 @@ static int iwl_trans_pcie_reclaim(struct iwl_trans *trans, int sta_id, int tid, int tfd_num = ssn & (txq->q.n_bd - 1); int freed = 0; + spin_lock(&txq->lock); + txq->time_stamp = jiffies; if (unlikely(txq_id >= IWLAGN_FIRST_AMPDU_QUEUE && @@ -1574,6 +1579,7 @@ static int iwl_trans_pcie_reclaim(struct iwl_trans *trans, int sta_id, int tid, IWL_DEBUG_TX_QUEUES(trans, "Bad queue mapping txq_id %d, " "agg_txq[sta_id[tid] %d", txq_id, trans_pcie->agg_txq[sta_id][tid]); + spin_unlock(&txq->lock); return 1; } @@ -1587,6 +1593,8 @@ static int iwl_trans_pcie_reclaim(struct iwl_trans *trans, int sta_id, int tid, status != TX_STATUS_FAIL_PASSIVE_NO_RX)) iwl_wake_queue(trans, txq, "Packets reclaimed"); } + + spin_unlock(&txq->lock); return 0; } @@ -2267,7 +2275,6 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct iwl_shared *shrd, trans->ops = &trans_ops_pcie; trans->shrd = shrd; trans_pcie->trans = trans; - spin_lock_init(&trans->hcmd_lock); spin_lock_init(&trans_pcie->irq_lock); /* W/A - seems to solve weird behavior. We need to remove this if we diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index 4e7e6c0eede9..e2f21cfc2cd4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h @@ -309,7 +309,6 @@ enum iwl_trans_state { * @ops - pointer to iwl_trans_ops * @op_mode - pointer to the op_mode * @shrd - pointer to iwl_shared which holds shared data from the upper layer - * @hcmd_lock: protects HCMD * @reg_lock - protect hw register access * @dev - pointer to struct device * that represents the device * @irq - the irq number for the device @@ -326,7 +325,6 @@ struct iwl_trans { struct iwl_op_mode *op_mode; struct iwl_shared *shrd; enum iwl_trans_state state; - spinlock_t hcmd_lock; spinlock_t reg_lock; struct device *dev; -- cgit From fa23cb04b38a9950b21ee756e4419a737d496371 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 5 Mar 2012 11:24:25 -0800 Subject: iwlwifi: make sta lock private & BH lock Now that the transport has its own locking, there's no need to have the sta_lock in the shared data. Also, it can be a BH lock as it's not used from IRQ handlers. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-sta.c | 141 ++++++++++++----------------- drivers/net/wireless/iwlwifi/iwl-agn-tx.c | 46 ++++------ drivers/net/wireless/iwlwifi/iwl-agn.c | 7 +- drivers/net/wireless/iwlwifi/iwl-dev.h | 6 ++ drivers/net/wireless/iwlwifi/iwl-shared.h | 3 - 5 files changed, 88 insertions(+), 115 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c index 6b9af994cfa4..4bd50daeac1a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c @@ -34,9 +34,10 @@ #include "iwl-agn.h" #include "iwl-trans.h" -/* priv->shrd->sta_lock must be held */ static int iwl_sta_ucode_activate(struct iwl_priv *priv, u8 sta_id) { + lockdep_assert_held(&priv->sta_lock); + if (sta_id >= IWLAGN_STATION_COUNT) { IWL_ERR(priv, "invalid sta_id %u", sta_id); return -EINVAL; @@ -64,7 +65,6 @@ static int iwl_process_add_sta_resp(struct iwl_priv *priv, struct iwl_rx_packet *pkt) { u8 sta_id = addsta->sta.sta_id; - unsigned long flags; int ret = -EIO; if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) { @@ -76,7 +76,7 @@ static int iwl_process_add_sta_resp(struct iwl_priv *priv, IWL_DEBUG_INFO(priv, "Processing response for adding station %u\n", sta_id); - spin_lock_irqsave(&priv->shrd->sta_lock, flags); + spin_lock(&priv->sta_lock); switch (pkt->u.add_sta.status) { case ADD_STA_SUCCESS_MSK: @@ -118,7 +118,7 @@ static int iwl_process_add_sta_resp(struct iwl_priv *priv, priv->stations[sta_id].sta.mode == STA_CONTROL_MODIFY_MSK ? "Modified" : "Added", addsta->sta.addr); - spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); + spin_unlock(&priv->sta_lock); return ret; } @@ -317,18 +317,17 @@ int iwl_add_station_common(struct iwl_priv *priv, struct iwl_rxon_context *ctx, const u8 *addr, bool is_ap, struct ieee80211_sta *sta, u8 *sta_id_r) { - unsigned long flags_spin; int ret = 0; u8 sta_id; struct iwl_addsta_cmd sta_cmd; *sta_id_r = 0; - spin_lock_irqsave(&priv->shrd->sta_lock, flags_spin); + spin_lock_bh(&priv->sta_lock); sta_id = iwl_prep_station(priv, ctx, addr, is_ap, sta); if (sta_id == IWL_INVALID_STATION) { IWL_ERR(priv, "Unable to prepare station %pM for addition\n", addr); - spin_unlock_irqrestore(&priv->shrd->sta_lock, flags_spin); + spin_unlock_bh(&priv->sta_lock); return -EINVAL; } @@ -340,7 +339,7 @@ int iwl_add_station_common(struct iwl_priv *priv, struct iwl_rxon_context *ctx, if (priv->stations[sta_id].used & IWL_STA_UCODE_INPROGRESS) { IWL_DEBUG_INFO(priv, "STA %d already in process of being " "added.\n", sta_id); - spin_unlock_irqrestore(&priv->shrd->sta_lock, flags_spin); + spin_unlock_bh(&priv->sta_lock); return -EEXIST; } @@ -348,24 +347,24 @@ int iwl_add_station_common(struct iwl_priv *priv, struct iwl_rxon_context *ctx, (priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE)) { IWL_DEBUG_ASSOC(priv, "STA %d (%pM) already added, not " "adding again.\n", sta_id, addr); - spin_unlock_irqrestore(&priv->shrd->sta_lock, flags_spin); + spin_unlock_bh(&priv->sta_lock); return -EEXIST; } priv->stations[sta_id].used |= IWL_STA_UCODE_INPROGRESS; memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd)); - spin_unlock_irqrestore(&priv->shrd->sta_lock, flags_spin); + spin_unlock_bh(&priv->sta_lock); /* Add station to device's station table */ ret = iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC); if (ret) { - spin_lock_irqsave(&priv->shrd->sta_lock, flags_spin); + spin_lock_bh(&priv->sta_lock); IWL_ERR(priv, "Adding station %pM failed.\n", priv->stations[sta_id].sta.sta.addr); priv->stations[sta_id].used &= ~IWL_STA_DRIVER_ACTIVE; priv->stations[sta_id].used &= ~IWL_STA_UCODE_INPROGRESS; - spin_unlock_irqrestore(&priv->shrd->sta_lock, flags_spin); + spin_unlock_bh(&priv->sta_lock); } *sta_id_r = sta_id; return ret; @@ -373,11 +372,11 @@ int iwl_add_station_common(struct iwl_priv *priv, struct iwl_rxon_context *ctx, /** * iwl_sta_ucode_deactivate - deactivate ucode status for a station - * - * priv->shrd->sta_lock must be held */ static void iwl_sta_ucode_deactivate(struct iwl_priv *priv, u8 sta_id) { + lockdep_assert_held(&priv->sta_lock); + /* Ucode must be active and driver must be non active */ if ((priv->stations[sta_id].used & (IWL_STA_UCODE_ACTIVE | IWL_STA_DRIVER_ACTIVE)) != @@ -396,8 +395,6 @@ static int iwl_send_remove_station(struct iwl_priv *priv, { struct iwl_rx_packet *pkt; int ret; - - unsigned long flags_spin; struct iwl_rem_sta_cmd rm_sta_cmd; struct iwl_host_cmd cmd = { @@ -429,11 +426,9 @@ static int iwl_send_remove_station(struct iwl_priv *priv, switch (pkt->u.rem_sta.status) { case REM_STA_SUCCESS_MSK: if (!temporary) { - spin_lock_irqsave(&priv->shrd->sta_lock, - flags_spin); + spin_lock_bh(&priv->sta_lock); iwl_sta_ucode_deactivate(priv, sta_id); - spin_unlock_irqrestore(&priv->shrd->sta_lock, - flags_spin); + spin_unlock_bh(&priv->sta_lock); } IWL_DEBUG_ASSOC(priv, "REPLY_REMOVE_STA PASSED\n"); break; @@ -454,7 +449,6 @@ static int iwl_send_remove_station(struct iwl_priv *priv, int iwl_remove_station(struct iwl_priv *priv, const u8 sta_id, const u8 *addr) { - unsigned long flags; u8 tid; if (!iwl_is_ready(priv->shrd)) { @@ -475,7 +469,7 @@ int iwl_remove_station(struct iwl_priv *priv, const u8 sta_id, if (WARN_ON(sta_id == IWL_INVALID_STATION)) return -EINVAL; - spin_lock_irqsave(&priv->shrd->sta_lock, flags); + spin_lock_bh(&priv->sta_lock); if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE)) { IWL_DEBUG_INFO(priv, "Removing %pM but non DRIVER active\n", @@ -505,11 +499,11 @@ int iwl_remove_station(struct iwl_priv *priv, const u8 sta_id, if (WARN_ON(priv->num_stations < 0)) priv->num_stations = 0; - spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); + spin_unlock_bh(&priv->sta_lock); return iwl_send_remove_station(priv, addr, sta_id, false); out_err: - spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); + spin_unlock_bh(&priv->sta_lock); return -EINVAL; } @@ -525,12 +519,11 @@ void iwl_clear_ucode_stations(struct iwl_priv *priv, struct iwl_rxon_context *ctx) { int i; - unsigned long flags_spin; bool cleared = false; IWL_DEBUG_INFO(priv, "Clearing ucode stations in driver\n"); - spin_lock_irqsave(&priv->shrd->sta_lock, flags_spin); + spin_lock_bh(&priv->sta_lock); for (i = 0; i < IWLAGN_STATION_COUNT; i++) { if (ctx && ctx->ctxid != priv->stations[i].ctxid) continue; @@ -542,7 +535,7 @@ void iwl_clear_ucode_stations(struct iwl_priv *priv, cleared = true; } } - spin_unlock_irqrestore(&priv->shrd->sta_lock, flags_spin); + spin_unlock_bh(&priv->sta_lock); if (!cleared) IWL_DEBUG_INFO(priv, @@ -561,7 +554,6 @@ void iwl_restore_stations(struct iwl_priv *priv, struct iwl_rxon_context *ctx) { struct iwl_addsta_cmd sta_cmd; struct iwl_link_quality_cmd lq; - unsigned long flags_spin; int i; bool found = false; int ret; @@ -574,7 +566,7 @@ void iwl_restore_stations(struct iwl_priv *priv, struct iwl_rxon_context *ctx) } IWL_DEBUG_ASSOC(priv, "Restoring all known stations ... start.\n"); - spin_lock_irqsave(&priv->shrd->sta_lock, flags_spin); + spin_lock_bh(&priv->sta_lock); for (i = 0; i < IWLAGN_STATION_COUNT; i++) { if (ctx->ctxid != priv->stations[i].ctxid) continue; @@ -601,20 +593,17 @@ void iwl_restore_stations(struct iwl_priv *priv, struct iwl_rxon_context *ctx) sizeof(struct iwl_link_quality_cmd)); send_lq = true; } - spin_unlock_irqrestore(&priv->shrd->sta_lock, - flags_spin); + spin_unlock_bh(&priv->sta_lock); ret = iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC); if (ret) { - spin_lock_irqsave(&priv->shrd->sta_lock, - flags_spin); + spin_lock_bh(&priv->sta_lock); IWL_ERR(priv, "Adding station %pM failed.\n", priv->stations[i].sta.sta.addr); priv->stations[i].used &= ~IWL_STA_DRIVER_ACTIVE; priv->stations[i].used &= ~IWL_STA_UCODE_INPROGRESS; - spin_unlock_irqrestore(&priv->shrd->sta_lock, - flags_spin); + spin_unlock_bh(&priv->sta_lock); } /* * Rate scaling has already been initialized, send @@ -623,12 +612,12 @@ void iwl_restore_stations(struct iwl_priv *priv, struct iwl_rxon_context *ctx) if (send_lq) iwl_send_lq_cmd(priv, ctx, &lq, CMD_SYNC, true); - spin_lock_irqsave(&priv->shrd->sta_lock, flags_spin); + spin_lock_bh(&priv->sta_lock); priv->stations[i].used &= ~IWL_STA_UCODE_INPROGRESS; } } - spin_unlock_irqrestore(&priv->shrd->sta_lock, flags_spin); + spin_unlock_bh(&priv->sta_lock); if (!found) IWL_DEBUG_INFO(priv, "Restoring all known stations .... " "no stations to be restored.\n"); @@ -639,16 +628,15 @@ void iwl_restore_stations(struct iwl_priv *priv, struct iwl_rxon_context *ctx) void iwl_reprogram_ap_sta(struct iwl_priv *priv, struct iwl_rxon_context *ctx) { - unsigned long flags; int sta_id = ctx->ap_sta_id; int ret; struct iwl_addsta_cmd sta_cmd; struct iwl_link_quality_cmd lq; bool active, have_lq = false; - spin_lock_irqsave(&priv->shrd->sta_lock, flags); + spin_lock_bh(&priv->sta_lock); if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE)) { - spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); + spin_unlock_bh(&priv->sta_lock); return; } @@ -661,7 +649,7 @@ void iwl_reprogram_ap_sta(struct iwl_priv *priv, struct iwl_rxon_context *ctx) active = priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE; priv->stations[sta_id].used &= ~IWL_STA_DRIVER_ACTIVE; - spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); + spin_unlock_bh(&priv->sta_lock); if (active) { ret = iwl_send_remove_station( @@ -671,9 +659,9 @@ void iwl_reprogram_ap_sta(struct iwl_priv *priv, struct iwl_rxon_context *ctx) IWL_ERR(priv, "failed to remove STA %pM (%d)\n", priv->stations[sta_id].sta.sta.addr, ret); } - spin_lock_irqsave(&priv->shrd->sta_lock, flags); + spin_lock_bh(&priv->sta_lock); priv->stations[sta_id].used |= IWL_STA_DRIVER_ACTIVE; - spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); + spin_unlock_bh(&priv->sta_lock); ret = iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC); if (ret) @@ -696,10 +684,9 @@ int iwl_get_free_ucode_key_offset(struct iwl_priv *priv) void iwl_dealloc_bcast_stations(struct iwl_priv *priv) { - unsigned long flags; int i; - spin_lock_irqsave(&priv->shrd->sta_lock, flags); + spin_lock_bh(&priv->sta_lock); for (i = 0; i < IWLAGN_STATION_COUNT; i++) { if (!(priv->stations[i].used & IWL_STA_BCAST)) continue; @@ -711,7 +698,7 @@ void iwl_dealloc_bcast_stations(struct iwl_priv *priv) kfree(priv->stations[i].lq); priv->stations[i].lq = NULL; } - spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); + spin_unlock_bh(&priv->sta_lock); } #ifdef CONFIG_IWLWIFI_DEBUG @@ -783,8 +770,6 @@ int iwl_send_lq_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx, struct iwl_link_quality_cmd *lq, u8 flags, bool init) { int ret = 0; - unsigned long flags_spin; - struct iwl_host_cmd cmd = { .id = REPLY_TX_LINK_QUALITY_CMD, .len = { sizeof(struct iwl_link_quality_cmd), }, @@ -796,12 +781,12 @@ int iwl_send_lq_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx, return -EINVAL; - spin_lock_irqsave(&priv->shrd->sta_lock, flags_spin); + spin_lock_bh(&priv->sta_lock); if (!(priv->stations[lq->sta_id].used & IWL_STA_DRIVER_ACTIVE)) { - spin_unlock_irqrestore(&priv->shrd->sta_lock, flags_spin); + spin_unlock_bh(&priv->sta_lock); return -EINVAL; } - spin_unlock_irqrestore(&priv->shrd->sta_lock, flags_spin); + spin_unlock_bh(&priv->sta_lock); iwl_dump_lq_cmd(priv, lq); if (WARN_ON(init && (cmd.flags & CMD_ASYNC))) @@ -819,9 +804,9 @@ int iwl_send_lq_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx, IWL_DEBUG_INFO(priv, "init LQ command complete, " "clearing sta addition status for sta %d\n", lq->sta_id); - spin_lock_irqsave(&priv->shrd->sta_lock, flags_spin); + spin_lock_bh(&priv->sta_lock); priv->stations[lq->sta_id].used &= ~IWL_STA_UCODE_INPROGRESS; - spin_unlock_irqrestore(&priv->shrd->sta_lock, flags_spin); + spin_unlock_bh(&priv->sta_lock); } return ret; } @@ -906,7 +891,6 @@ int iwlagn_add_bssid_station(struct iwl_priv *priv, int ret; u8 sta_id; struct iwl_link_quality_cmd *link_cmd; - unsigned long flags; if (sta_id_r) *sta_id_r = IWL_INVALID_STATION; @@ -920,9 +904,9 @@ int iwlagn_add_bssid_station(struct iwl_priv *priv, if (sta_id_r) *sta_id_r = sta_id; - spin_lock_irqsave(&priv->shrd->sta_lock, flags); + spin_lock_bh(&priv->sta_lock); priv->stations[sta_id].used |= IWL_STA_LOCAL; - spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); + spin_unlock_bh(&priv->sta_lock); /* Set up default rate scaling table in device's station table */ link_cmd = iwl_sta_alloc_lq(priv, ctx, sta_id); @@ -937,9 +921,9 @@ int iwlagn_add_bssid_station(struct iwl_priv *priv, if (ret) IWL_ERR(priv, "Link quality command failed (%d)\n", ret); - spin_lock_irqsave(&priv->shrd->sta_lock, flags); + spin_lock_bh(&priv->sta_lock); priv->stations[sta_id].lq = link_cmd; - spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); + spin_unlock_bh(&priv->sta_lock); return 0; } @@ -1100,14 +1084,13 @@ static int iwlagn_send_sta_key(struct iwl_priv *priv, u8 sta_id, u32 tkip_iv32, u16 *tkip_p1k, u32 cmd_flags) { - unsigned long flags; __le16 key_flags; struct iwl_addsta_cmd sta_cmd; int i; - spin_lock_irqsave(&priv->shrd->sta_lock, flags); + spin_lock_bh(&priv->sta_lock); memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(sta_cmd)); - spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); + spin_unlock_bh(&priv->sta_lock); key_flags = cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS); key_flags |= STA_KEY_FLG_MAP_KEY_MSK; @@ -1174,7 +1157,6 @@ int iwl_remove_dynamic_key(struct iwl_priv *priv, struct ieee80211_key_conf *keyconf, struct ieee80211_sta *sta) { - unsigned long flags; struct iwl_addsta_cmd sta_cmd; u8 sta_id = iwlagn_key_sta_id(priv, ctx->vif, sta); __le16 key_flags; @@ -1183,11 +1165,11 @@ int iwl_remove_dynamic_key(struct iwl_priv *priv, if (sta_id == IWL_INVALID_STATION) return -ENOENT; - spin_lock_irqsave(&priv->shrd->sta_lock, flags); + spin_lock_bh(&priv->sta_lock); memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(sta_cmd)); if (!(priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE)) sta_id = IWL_INVALID_STATION; - spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); + spin_unlock_bh(&priv->sta_lock); if (sta_id == IWL_INVALID_STATION) return 0; @@ -1287,21 +1269,20 @@ int iwlagn_alloc_bcast_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx) { struct iwl_link_quality_cmd *link_cmd; - unsigned long flags; u8 sta_id; - spin_lock_irqsave(&priv->shrd->sta_lock, flags); + spin_lock_bh(&priv->sta_lock); sta_id = iwl_prep_station(priv, ctx, iwl_bcast_addr, false, NULL); if (sta_id == IWL_INVALID_STATION) { IWL_ERR(priv, "Unable to prepare broadcast station\n"); - spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); + spin_unlock_bh(&priv->sta_lock); return -EINVAL; } priv->stations[sta_id].used |= IWL_STA_DRIVER_ACTIVE; priv->stations[sta_id].used |= IWL_STA_BCAST; - spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); + spin_unlock_bh(&priv->sta_lock); link_cmd = iwl_sta_alloc_lq(priv, ctx, sta_id); if (!link_cmd) { @@ -1310,9 +1291,9 @@ int iwlagn_alloc_bcast_station(struct iwl_priv *priv, return -ENOMEM; } - spin_lock_irqsave(&priv->shrd->sta_lock, flags); + spin_lock_bh(&priv->sta_lock); priv->stations[sta_id].lq = link_cmd; - spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); + spin_unlock_bh(&priv->sta_lock); return 0; } @@ -1326,7 +1307,6 @@ int iwlagn_alloc_bcast_station(struct iwl_priv *priv, int iwl_update_bcast_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx) { - unsigned long flags; struct iwl_link_quality_cmd *link_cmd; u8 sta_id = ctx->bcast_sta_id; @@ -1336,13 +1316,13 @@ int iwl_update_bcast_station(struct iwl_priv *priv, return -ENOMEM; } - spin_lock_irqsave(&priv->shrd->sta_lock, flags); + spin_lock_bh(&priv->sta_lock); if (priv->stations[sta_id].lq) kfree(priv->stations[sta_id].lq); else IWL_DEBUG_INFO(priv, "Bcast station rate scaling has not been initialized yet.\n"); priv->stations[sta_id].lq = link_cmd; - spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); + spin_unlock_bh(&priv->sta_lock); return 0; } @@ -1366,18 +1346,17 @@ int iwl_update_bcast_stations(struct iwl_priv *priv) */ int iwl_sta_tx_modify_enable_tid(struct iwl_priv *priv, int sta_id, int tid) { - unsigned long flags; struct iwl_addsta_cmd sta_cmd; lockdep_assert_held(&priv->shrd->mutex); /* Remove "disable" flag, to enable Tx for this TID */ - spin_lock_irqsave(&priv->shrd->sta_lock, flags); + spin_lock_bh(&priv->sta_lock); priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_TID_DISABLE_TX; priv->stations[sta_id].sta.tid_disable_tx &= cpu_to_le16(~(1 << tid)); priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd)); - spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); + spin_unlock_bh(&priv->sta_lock); return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC); } @@ -1385,7 +1364,6 @@ int iwl_sta_tx_modify_enable_tid(struct iwl_priv *priv, int sta_id, int tid) int iwl_sta_rx_agg_start(struct iwl_priv *priv, struct ieee80211_sta *sta, int tid, u16 ssn) { - unsigned long flags; int sta_id; struct iwl_addsta_cmd sta_cmd; @@ -1395,14 +1373,14 @@ int iwl_sta_rx_agg_start(struct iwl_priv *priv, struct ieee80211_sta *sta, if (sta_id == IWL_INVALID_STATION) return -ENXIO; - spin_lock_irqsave(&priv->shrd->sta_lock, flags); + spin_lock_bh(&priv->sta_lock); priv->stations[sta_id].sta.station_flags_msk = 0; priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_ADDBA_TID_MSK; priv->stations[sta_id].sta.add_immediate_ba_tid = (u8)tid; priv->stations[sta_id].sta.add_immediate_ba_ssn = cpu_to_le16(ssn); priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd)); - spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); + spin_unlock_bh(&priv->sta_lock); return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC); } @@ -1410,7 +1388,6 @@ int iwl_sta_rx_agg_start(struct iwl_priv *priv, struct ieee80211_sta *sta, int iwl_sta_rx_agg_stop(struct iwl_priv *priv, struct ieee80211_sta *sta, int tid) { - unsigned long flags; int sta_id; struct iwl_addsta_cmd sta_cmd; @@ -1422,13 +1399,13 @@ int iwl_sta_rx_agg_stop(struct iwl_priv *priv, struct ieee80211_sta *sta, return -ENXIO; } - spin_lock_irqsave(&priv->shrd->sta_lock, flags); + spin_lock_bh(&priv->sta_lock); priv->stations[sta_id].sta.station_flags_msk = 0; priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_DELBA_TID_MSK; priv->stations[sta_id].sta.remove_immediate_ba_tid = (u8)tid; priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd)); - spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); + spin_unlock_bh(&priv->sta_lock); return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC); } diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c index 59509d80f73f..4e69189a631d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c @@ -370,7 +370,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) info->driver_data[1] = dev_cmd; /* irqs already disabled/saved above when locking priv->shrd->lock */ - spin_lock(&priv->shrd->sta_lock); + spin_lock(&priv->sta_lock); if (ieee80211_is_data_qos(fc) && !ieee80211_is_qos_nullfunc(fc)) { u8 *qc = NULL; @@ -417,7 +417,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) !ieee80211_has_morefrags(fc)) priv->tid_data[sta_id][tid].seq_number = seq_number; - spin_unlock(&priv->shrd->sta_lock); + spin_unlock(&priv->sta_lock); spin_unlock_irqrestore(&priv->shrd->lock, flags); /* @@ -435,7 +435,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) drop_unlock_sta: if (dev_cmd) kmem_cache_free(priv->tx_cmd_pool, dev_cmd); - spin_unlock(&priv->shrd->sta_lock); + spin_unlock(&priv->sta_lock); drop_unlock_priv: spin_unlock_irqrestore(&priv->shrd->lock, flags); return -1; @@ -455,7 +455,7 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif, return -ENXIO; } - spin_lock_irqsave(&priv->shrd->sta_lock, flags); + spin_lock_bh(&priv->sta_lock); tid_data = &priv->tid_data[sta_id][tid]; @@ -475,7 +475,7 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif, IWL_WARN(priv, "Stopping AGG while state not ON " "or starting for %d on %d (%d)\n", sta_id, tid, priv->tid_data[sta_id][tid].agg.state); - spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); + spin_unlock_bh(&priv->sta_lock); return 0; } @@ -489,7 +489,7 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif, tid_data->next_reclaimed); priv->tid_data[sta_id][tid].agg.state = IWL_EMPTYING_HW_QUEUE_DELBA; - spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); + spin_unlock_bh(&priv->sta_lock); return 0; } @@ -498,12 +498,10 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif, turn_off: priv->tid_data[sta_id][tid].agg.state = IWL_AGG_OFF; - /* do not restore/save irqs */ - spin_unlock(&priv->shrd->sta_lock); - spin_lock(&priv->shrd->lock); + spin_unlock_bh(&priv->sta_lock); + spin_lock_irqsave(&priv->shrd->lock, flags); iwl_trans_tx_agg_disable(trans(priv), sta_id, tid); - spin_unlock_irqrestore(&priv->shrd->lock, flags); ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); @@ -515,7 +513,6 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif, struct ieee80211_sta *sta, u16 tid, u16 *ssn) { struct iwl_tid_data *tid_data; - unsigned long flags; int sta_id; int ret; @@ -539,7 +536,7 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif, if (ret) return ret; - spin_lock_irqsave(&priv->shrd->sta_lock, flags); + spin_lock_bh(&priv->sta_lock); tid_data = &priv->tid_data[sta_id][tid]; tid_data->agg.ssn = SEQ_TO_SN(tid_data->seq_number); @@ -548,7 +545,7 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif, ret = iwl_trans_tx_agg_alloc(trans(priv), sta_id, tid); if (ret) { - spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); + spin_unlock_bh(&priv->sta_lock); return ret; } @@ -565,7 +562,7 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif, tid_data->agg.state = IWL_EMPTYING_HW_QUEUE_ADDBA; } - spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); + spin_unlock_bh(&priv->sta_lock); return ret; } @@ -575,14 +572,13 @@ int iwlagn_tx_agg_oper(struct iwl_priv *priv, struct ieee80211_vif *vif, { struct iwl_station_priv *sta_priv = (void *) sta->drv_priv; struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif); - unsigned long flags; u16 ssn; buf_size = min_t(int, buf_size, LINK_QUAL_AGG_FRAME_LIMIT_DEF); - spin_lock_irqsave(&priv->shrd->sta_lock, flags); + spin_lock_bh(&priv->sta_lock); ssn = priv->tid_data[sta_priv->sta_id][tid].agg.ssn; - spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); + spin_unlock_bh(&priv->sta_lock); iwl_trans_tx_agg_setup(trans(priv), ctx->ctxid, sta_priv->sta_id, tid, buf_size, ssn); @@ -638,7 +634,7 @@ static void iwlagn_check_ratid_empty(struct iwl_priv *priv, int sta_id, u8 tid) struct ieee80211_vif *vif; u8 *addr; - lockdep_assert_held(&priv->shrd->sta_lock); + lockdep_assert_held(&priv->sta_lock); addr = priv->stations[sta_id].sta.sta.addr; ctx = priv->stations[sta_id].ctxid; @@ -1005,7 +1001,6 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb, int sta_id; int freed; struct ieee80211_tx_info *info; - unsigned long flags; struct sk_buff_head skbs; struct sk_buff *skb; struct iwl_rxon_context *ctx; @@ -1016,7 +1011,7 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb, sta_id = (tx_resp->ra_tid & IWLAGN_TX_RES_RA_MSK) >> IWLAGN_TX_RES_RA_POS; - spin_lock_irqsave(&priv->shrd->sta_lock, flags); + spin_lock(&priv->sta_lock); if (is_agg) iwl_rx_reply_tx_agg(priv, tx_resp); @@ -1106,7 +1101,7 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb, } iwl_check_abort_status(priv, tx_resp->frame_count, status); - spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); + spin_unlock(&priv->sta_lock); return 0; } @@ -1127,7 +1122,6 @@ int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv, struct ieee80211_tx_info *info; struct ieee80211_hdr *hdr; struct sk_buff *skb; - unsigned long flags; int sta_id; int tid; int freed; @@ -1149,12 +1143,12 @@ int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv, tid = ba_resp->tid; agg = &priv->tid_data[sta_id][tid].agg; - spin_lock_irqsave(&priv->shrd->sta_lock, flags); + spin_lock(&priv->sta_lock); if (unlikely(!agg->wait_for_ba)) { if (unlikely(ba_resp->bitmap)) IWL_ERR(priv, "Received BA when not expected\n"); - spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); + spin_unlock(&priv->sta_lock); return 0; } @@ -1165,7 +1159,7 @@ int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv, * transmitted ... if not, it's too late anyway). */ if (iwl_trans_reclaim(trans(priv), sta_id, tid, scd_flow, ba_resp_scd_ssn, 0, &reclaimed_skbs)) { - spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); + spin_unlock(&priv->sta_lock); return 0; } @@ -1230,6 +1224,6 @@ int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv, ieee80211_tx_status_irqsafe(priv->hw, skb); } - spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); + spin_unlock(&priv->sta_lock); return 0; } diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index a7f3a7023d88..0090fab3aacb 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -749,10 +749,9 @@ int iwl_alive_start(struct iwl_priv *priv) */ static void iwl_clear_driver_stations(struct iwl_priv *priv) { - unsigned long flags; struct iwl_rxon_context *ctx; - spin_lock_irqsave(&priv->shrd->sta_lock, flags); + spin_lock_bh(&priv->sta_lock); memset(priv->stations, 0, sizeof(priv->stations)); priv->num_stations = 0; @@ -770,7 +769,7 @@ static void iwl_clear_driver_stations(struct iwl_priv *priv) ctx->key_mapping_keys = 0; } - spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); + spin_unlock_bh(&priv->sta_lock); } void iwl_down(struct iwl_priv *priv) @@ -1039,7 +1038,7 @@ static int iwl_init_drv(struct iwl_priv *priv) { int ret; - spin_lock_init(&priv->shrd->sta_lock); + spin_lock_init(&priv->sta_lock); mutex_init(&priv->shrd->mutex); diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 6e5bf0a14609..dc57522594a6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -719,6 +719,12 @@ struct iwl_priv { /*data shared among all the driver's layers */ struct iwl_shared *shrd; + /* + * protects the station table, if shrd->lock and sta_lock are + * needed, shrd->lock must be acquired first + */ + spinlock_t sta_lock; + /* ieee device used by generic ieee processing code */ struct ieee80211_hw *hw; struct ieee80211_channel *ieee_channels; diff --git a/drivers/net/wireless/iwlwifi/iwl-shared.h b/drivers/net/wireless/iwlwifi/iwl-shared.h index a6441623e6b1..3a0f0a4c58d3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-shared.h +++ b/drivers/net/wireless/iwlwifi/iwl-shared.h @@ -360,8 +360,6 @@ struct iwl_cfg { * @nic: pointer to the nic data * @hw_params: see struct iwl_hw_params * @lock: protect general shared data - * @sta_lock: protects the station table. - * If lock and sta_lock are needed, lock must be acquired first. * @mutex: * @wait_command_queue: the wait_queue for SYNC host command nad uCode load * @eeprom: pointer to the eeprom/OTP image @@ -391,7 +389,6 @@ struct iwl_shared { struct iwl_hw_params hw_params; spinlock_t lock; - spinlock_t sta_lock; struct mutex mutex; wait_queue_head_t wait_command_queue; -- cgit From 4ff70fcdf3c424c3fdca253e7b7556f77eaf39be Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 5 Mar 2012 11:24:26 -0800 Subject: iwlwifi: introduce statistics lock The statistics are currently only half-heartedly locked against concurrent reading & modification so introduce a lock to really protect them. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-calib.c | 16 +++++++--------- drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 2 ++ drivers/net/wireless/iwlwifi/iwl-agn-rx.c | 8 ++++++++ drivers/net/wireless/iwlwifi/iwl-agn.c | 1 + drivers/net/wireless/iwlwifi/iwl-debugfs.c | 21 +++++++++++++++++++++ drivers/net/wireless/iwlwifi/iwl-dev.h | 1 + 6 files changed, 40 insertions(+), 9 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c index 988ee454a944..12acc81ed419 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c @@ -655,7 +655,6 @@ void iwl_sensitivity_calibration(struct iwl_priv *priv) struct iwl_sensitivity_data *data = NULL; struct statistics_rx_non_phy *rx_info; struct statistics_rx_phy *ofdm, *cck; - unsigned long flags; struct statistics_general_data statis; if (priv->disable_sens_cal) @@ -668,13 +667,13 @@ void iwl_sensitivity_calibration(struct iwl_priv *priv) return; } - spin_lock_irqsave(&priv->shrd->lock, flags); + spin_lock_bh(&priv->statistics.lock); rx_info = &priv->statistics.rx_non_phy; ofdm = &priv->statistics.rx_ofdm; cck = &priv->statistics.rx_cck; if (rx_info->interference_data_flag != INTERFERENCE_DATA_AVAILABLE) { IWL_DEBUG_CALIB(priv, "<< invalid data.\n"); - spin_unlock_irqrestore(&priv->shrd->lock, flags); + spin_unlock_bh(&priv->statistics.lock); return; } @@ -698,7 +697,7 @@ void iwl_sensitivity_calibration(struct iwl_priv *priv) statis.beacon_energy_c = le32_to_cpu(rx_info->beacon_energy_c); - spin_unlock_irqrestore(&priv->shrd->lock, flags); + spin_unlock_bh(&priv->statistics.lock); IWL_DEBUG_CALIB(priv, "rx_enable_time = %u usecs\n", rx_enable_time); @@ -958,7 +957,6 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv) u16 stat_chnum = INITIALIZATION_VALUE; u8 rxon_band24; u8 stat_band24; - unsigned long flags; struct statistics_rx_non_phy *rx_info; /* @@ -983,13 +981,13 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv) return; } - spin_lock_irqsave(&priv->shrd->lock, flags); + spin_lock_bh(&priv->statistics.lock); rx_info = &priv->statistics.rx_non_phy; if (rx_info->interference_data_flag != INTERFERENCE_DATA_AVAILABLE) { IWL_DEBUG_CALIB(priv, " << Interference data unavailable\n"); - spin_unlock_irqrestore(&priv->shrd->lock, flags); + spin_unlock_bh(&priv->statistics.lock); return; } @@ -1004,7 +1002,7 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv) if ((rxon_chnum != stat_chnum) || (rxon_band24 != stat_band24)) { IWL_DEBUG_CALIB(priv, "Stats not from chan=%d, band24=%d\n", rxon_chnum, rxon_band24); - spin_unlock_irqrestore(&priv->shrd->lock, flags); + spin_unlock_bh(&priv->statistics.lock); return; } @@ -1023,7 +1021,7 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv) chain_sig_b = le32_to_cpu(rx_info->beacon_rssi_b) & IN_BAND_FILTER; chain_sig_c = le32_to_cpu(rx_info->beacon_rssi_c) & IN_BAND_FILTER; - spin_unlock_irqrestore(&priv->shrd->lock, flags); + spin_unlock_bh(&priv->statistics.lock); data->beacon_count++; diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index 5be0d3695d03..0f8dd0f96fa6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -88,6 +88,8 @@ int iwlagn_send_tx_power(struct iwl_priv *priv) void iwlagn_temperature(struct iwl_priv *priv) { + lockdep_assert_held(&priv->statistics.lock); + /* store temperature from correct statistics (in Celsius) */ priv->temperature = le32_to_cpu(priv->statistics.common.temperature); iwl_tt_handler(priv); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c index 30bb5bbb0cd7..bc21586aed63 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c @@ -266,6 +266,8 @@ static bool iwlagn_good_ack_health(struct iwl_priv *priv, if (priv->agg_tids_count) return true; + lockdep_assert_held(&priv->statistics.lock); + old = &priv->statistics.tx; actual_delta = le32_to_cpu(cur->actual_ack_cnt) - @@ -509,6 +511,8 @@ static int iwlagn_rx_statistics(struct iwl_priv *priv, IWL_DEBUG_RX(priv, "Statistics notification received (%d bytes).\n", len); + spin_lock(&priv->statistics.lock); + if (len == sizeof(struct iwl_bt_notif_statistics)) { struct iwl_bt_notif_statistics *stats; stats = &pkt->u.stats_bt; @@ -542,6 +546,7 @@ static int iwlagn_rx_statistics(struct iwl_priv *priv, WARN_ONCE(1, "len %d doesn't match BT (%zu) or normal (%zu)\n", len, sizeof(struct iwl_bt_notif_statistics), sizeof(struct iwl_notif_statistics)); + spin_unlock(&priv->statistics.lock); return 0; } @@ -585,6 +590,9 @@ static int iwlagn_rx_statistics(struct iwl_priv *priv, } if (cfg(priv)->lib->temperature && change) cfg(priv)->lib->temperature(priv); + + spin_unlock(&priv->statistics.lock); + return 0; } diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 0090fab3aacb..47c788607024 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -1233,6 +1233,7 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans) */ spin_lock_init(&trans(priv)->reg_lock); spin_lock_init(&priv->shrd->lock); + spin_lock_init(&priv->statistics.lock); /*********************** * 3. Read REV register diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index ad74138e1c70..628af563e4e1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c @@ -920,6 +920,8 @@ static int iwl_statistics_flag(struct iwl_priv *priv, char *buf, int bufsz) int p = 0; u32 flag; + lockdep_assert_held(&priv->statistics.lock); + flag = le32_to_cpu(priv->statistics.flag); p += scnprintf(buf + p, bufsz - p, "Statistics Flag(0x%X):\n", flag); @@ -967,6 +969,7 @@ static ssize_t iwl_dbgfs_ucode_rx_stats_read(struct file *file, * the last statistics notification from uCode * might not reflect the current uCode activity */ + spin_lock_bh(&priv->statistics.lock); ofdm = &priv->statistics.rx_ofdm; cck = &priv->statistics.rx_cck; general = &priv->statistics.rx_non_phy; @@ -1363,6 +1366,8 @@ static ssize_t iwl_dbgfs_ucode_rx_stats_read(struct file *file, accum_ht->unsupport_mcs, delta_ht->unsupport_mcs, max_ht->unsupport_mcs); + spin_unlock_bh(&priv->statistics.lock); + ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); kfree(buf); return ret; @@ -1392,6 +1397,8 @@ static ssize_t iwl_dbgfs_ucode_tx_stats_read(struct file *file, * the last statistics notification from uCode * might not reflect the current uCode activity */ + spin_lock_bh(&priv->statistics.lock); + tx = &priv->statistics.tx; accum_tx = &priv->accum_stats.tx; delta_tx = &priv->delta_stats.tx; @@ -1554,6 +1561,9 @@ static ssize_t iwl_dbgfs_ucode_tx_stats_read(struct file *file, fmt_hex, "antenna C:", tx->tx_power.ant_c); } + + spin_unlock_bh(&priv->statistics.lock); + ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); kfree(buf); return ret; @@ -1586,6 +1596,9 @@ static ssize_t iwl_dbgfs_ucode_general_stats_read(struct file *file, * the last statistics notification from uCode * might not reflect the current uCode activity */ + + spin_lock_bh(&priv->statistics.lock); + general = &priv->statistics.common; dbg = &priv->statistics.common.dbg; div = &priv->statistics.common.div; @@ -1670,6 +1683,9 @@ static ssize_t iwl_dbgfs_ucode_general_stats_read(struct file *file, accum_general->num_of_sos_states, delta_general->num_of_sos_states, max_general->num_of_sos_states); + + spin_unlock_bh(&priv->statistics.lock); + ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); kfree(buf); return ret; @@ -1713,6 +1729,9 @@ static ssize_t iwl_dbgfs_ucode_bt_stats_read(struct file *file, * the last statistics notification from uCode * might not reflect the current uCode activity */ + + spin_lock_bh(&priv->statistics.lock); + bt = &priv->statistics.bt_activity; accum_bt = &priv->accum_stats.bt_activity; @@ -1758,6 +1777,8 @@ static ssize_t iwl_dbgfs_ucode_bt_stats_read(struct file *file, le32_to_cpu(priv->statistics.num_bt_kills), priv->statistics.accum_num_bt_kills); + spin_unlock_bh(&priv->statistics.lock); + ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); kfree(buf); return ret; diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index dc57522594a6..daf233026b5e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -851,6 +851,7 @@ struct iwl_priv { struct statistics_bt_activity bt_activity; __le32 num_bt_kills, accum_num_bt_kills; #endif + spinlock_t lock; } statistics; #ifdef CONFIG_IWLWIFI_DEBUGFS struct { -- cgit From 08ae86ac3f9d9c9a60d2883c82cd72a5c66b94db Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 5 Mar 2012 11:24:27 -0800 Subject: iwlwifi: remove shared lock Some data doesn't need protection, some of the lock places are simply useless, and some data can be protected with the mutex instead. Thus the shared lock can be removed by making those changes. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-5000.c | 7 ------- drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 3 --- drivers/net/wireless/iwlwifi/iwl-agn-rs.c | 3 --- drivers/net/wireless/iwlwifi/iwl-agn-rxon.c | 6 ------ drivers/net/wireless/iwlwifi/iwl-agn-tx.c | 9 --------- drivers/net/wireless/iwlwifi/iwl-agn.c | 5 +---- drivers/net/wireless/iwlwifi/iwl-dev.h | 4 ---- drivers/net/wireless/iwlwifi/iwl-mac80211.c | 9 ++------- drivers/net/wireless/iwlwifi/iwl-shared.h | 1 - 9 files changed, 3 insertions(+), 44 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index 1527dec7a267..ccaeead29c2f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -63,12 +63,8 @@ /* NIC configuration for 5000 series */ static void iwl5000_nic_config(struct iwl_priv *priv) { - unsigned long flags; - iwl_rf_config(priv); - spin_lock_irqsave(&priv->shrd->lock, flags); - /* W/A : NIC is stuck in a reset state after Early PCIe power off * (PCIe power is lost before PERST# is asserted), * causing ME FW to lose ownership and not being able to obtain it back. @@ -76,9 +72,6 @@ static void iwl5000_nic_config(struct iwl_priv *priv) iwl_set_bits_mask_prph(trans(priv), APMG_PS_CTRL_REG, APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS, ~APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS); - - - spin_unlock_irqrestore(&priv->shrd->lock, flags); } static struct iwl_sensitivity_ranges iwl5000_sensitivity = { diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index 0f8dd0f96fa6..2470ca767589 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -710,7 +710,6 @@ int iwlagn_bt_coex_profile_notif(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb, struct iwl_device_cmd *cmd) { - unsigned long flags; struct iwl_rx_packet *pkt = rxb_addr(rxb); struct iwl_bt_coex_profile_notif *coex = &pkt->u.bt_coex_profile_notif; struct iwl_bt_uart_msg *uart_msg = &coex->last_bt_uart_msg; @@ -756,9 +755,7 @@ int iwlagn_bt_coex_profile_notif(struct iwl_priv *priv, /* FIXME: based on notification, adjust the prio_boost */ - spin_lock_irqsave(&priv->shrd->lock, flags); priv->bt_ci_compliance = coex->bt_ci_compliance; - spin_unlock_irqrestore(&priv->shrd->lock, flags); return 0; } diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c index a7d67135e3dc..9895b807246b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c @@ -870,19 +870,16 @@ static void rs_bt_update_lq(struct iwl_priv *priv, struct iwl_rxon_context *ctx, { struct iwl_scale_tbl_info *tbl; bool full_concurrent = priv->bt_full_concurrent; - unsigned long flags; if (priv->bt_ant_couple_ok) { /* * Is there a need to switch between * full concurrency and 3-wire? */ - spin_lock_irqsave(&priv->shrd->lock, flags); if (priv->bt_ci_compliance && priv->bt_ant_couple_ok) full_concurrent = true; else full_concurrent = false; - spin_unlock_irqrestore(&priv->shrd->lock, flags); } if ((priv->bt_traffic_load != priv->last_bt_traffic_load) || (priv->bt_full_concurrent != full_concurrent)) { diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c index 73653a6cf32d..a8c790028d53 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c @@ -590,8 +590,6 @@ int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed) } if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { - unsigned long flags; - ch_info = iwl_get_channel_info(priv, channel->band, channel->hw_value); if (!is_channel_valid(ch_info)) { @@ -600,8 +598,6 @@ int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed) goto out; } - spin_lock_irqsave(&priv->shrd->lock, flags); - for_each_context(priv, ctx) { /* Configure HT40 channels */ if (ctx->ht.enabled != conf_is_ht(conf)) @@ -636,8 +632,6 @@ int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed) ctx->vif); } - spin_unlock_irqrestore(&priv->shrd->lock, flags); - iwl_update_bcast_stations(priv); /* diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c index 4e69189a631d..2b722ccb730a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c @@ -259,18 +259,15 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; struct iwl_device_cmd *dev_cmd = NULL; struct iwl_tx_cmd *tx_cmd; - __le16 fc; u8 hdr_len; u16 len, seq_number = 0; u8 sta_id, tid = IWL_MAX_TID_COUNT; - unsigned long flags; bool is_agg = false; if (info->control.vif) ctx = iwl_rxon_ctx_from_vif(info->control.vif); - spin_lock_irqsave(&priv->shrd->lock, flags); if (iwl_is_rfkill(priv->shrd)) { IWL_DEBUG_DROP(priv, "Dropping - RF KILL\n"); goto drop_unlock_priv; @@ -369,7 +366,6 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) info->driver_data[0] = ctx; info->driver_data[1] = dev_cmd; - /* irqs already disabled/saved above when locking priv->shrd->lock */ spin_lock(&priv->sta_lock); if (ieee80211_is_data_qos(fc) && !ieee80211_is_qos_nullfunc(fc)) { @@ -418,7 +414,6 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) priv->tid_data[sta_id][tid].seq_number = seq_number; spin_unlock(&priv->sta_lock); - spin_unlock_irqrestore(&priv->shrd->lock, flags); /* * Avoid atomic ops if it isn't an associated client. @@ -437,7 +432,6 @@ drop_unlock_sta: kmem_cache_free(priv->tx_cmd_pool, dev_cmd); spin_unlock(&priv->sta_lock); drop_unlock_priv: - spin_unlock_irqrestore(&priv->shrd->lock, flags); return -1; } @@ -445,7 +439,6 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif, struct ieee80211_sta *sta, u16 tid) { struct iwl_tid_data *tid_data; - unsigned long flags; int sta_id; sta_id = iwl_sta_id(sta); @@ -500,9 +493,7 @@ turn_off: spin_unlock_bh(&priv->sta_lock); - spin_lock_irqsave(&priv->shrd->lock, flags); iwl_trans_tx_agg_disable(trans(priv), sta_id, tid); - spin_unlock_irqrestore(&priv->shrd->lock, flags); ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 47c788607024..ada9d9e4402b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -552,13 +552,11 @@ static void iwl_rf_kill_ct_config(struct iwl_priv *priv) { struct iwl_ct_kill_config cmd; struct iwl_ct_kill_throttling_config adv_cmd; - unsigned long flags; int ret = 0; - spin_lock_irqsave(&priv->shrd->lock, flags); iwl_write32(trans(priv), CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT); - spin_unlock_irqrestore(&priv->shrd->lock, flags); + priv->thermal_throttle.ct_kill_toggle = false; if (cfg(priv)->base_params->support_ct_kill_exit) { @@ -1232,7 +1230,6 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans) * we should init now */ spin_lock_init(&trans(priv)->reg_lock); - spin_lock_init(&priv->shrd->lock); spin_lock_init(&priv->statistics.lock); /*********************** diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index daf233026b5e..5b537dbe0af4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -719,10 +719,6 @@ struct iwl_priv { /*data shared among all the driver's layers */ struct iwl_shared *shrd; - /* - * protects the station table, if shrd->lock and sta_lock are - * needed, shrd->lock must be acquired first - */ spinlock_t sta_lock; /* ieee device used by generic ieee processing code */ diff --git a/drivers/net/wireless/iwlwifi/iwl-mac80211.c b/drivers/net/wireless/iwlwifi/iwl-mac80211.c index 9fba532d35cd..dcee30f0d629 100644 --- a/drivers/net/wireless/iwlwifi/iwl-mac80211.c +++ b/drivers/net/wireless/iwlwifi/iwl-mac80211.c @@ -779,8 +779,6 @@ static void iwlagn_mac_channel_switch(struct ieee80211_hw *hw, goto out; } - spin_lock_irq(&priv->shrd->lock); - priv->current_ht_config.smps = conf->smps_mode; /* Configure HT40 channels */ @@ -797,8 +795,6 @@ static void iwlagn_mac_channel_switch(struct ieee80211_hw *hw, iwl_set_rxon_ht(priv, ht_conf); iwl_set_flags_for_band(priv, ctx, channel->band, ctx->vif); - spin_unlock_irq(&priv->shrd->lock); - iwl_set_rate(priv); /* * at this point, staging_rxon has the @@ -1133,7 +1129,6 @@ static int iwlagn_mac_conf_tx(struct ieee80211_hw *hw, struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; struct iwl_rxon_context *ctx = vif_priv->ctx; - unsigned long flags; int q; if (WARN_ON(!ctx)) @@ -1153,7 +1148,7 @@ static int iwlagn_mac_conf_tx(struct ieee80211_hw *hw, q = AC_NUM - 1 - queue; - spin_lock_irqsave(&priv->shrd->lock, flags); + mutex_lock(&priv->shrd->mutex); ctx->qos_data.def_qos_parm.ac[q].cw_min = cpu_to_le16(params->cw_min); @@ -1165,7 +1160,7 @@ static int iwlagn_mac_conf_tx(struct ieee80211_hw *hw, ctx->qos_data.def_qos_parm.ac[q].reserved1 = 0; - spin_unlock_irqrestore(&priv->shrd->lock, flags); + mutex_unlock(&priv->shrd->mutex); IWL_DEBUG_MAC80211(priv, "leave\n"); return 0; diff --git a/drivers/net/wireless/iwlwifi/iwl-shared.h b/drivers/net/wireless/iwlwifi/iwl-shared.h index 3a0f0a4c58d3..7720fc34c278 100644 --- a/drivers/net/wireless/iwlwifi/iwl-shared.h +++ b/drivers/net/wireless/iwlwifi/iwl-shared.h @@ -388,7 +388,6 @@ struct iwl_shared { struct iwl_nic *nic; struct iwl_hw_params hw_params; - spinlock_t lock; struct mutex mutex; wait_queue_head_t wait_command_queue; -- cgit From 5c40d8603d8ed03aa851d20ad8a9155fc79a1b07 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 5 Mar 2012 11:24:28 -0800 Subject: iwlwifi: make EXIT_PENDING depend on mac80211 There's no reason to set EXIT_PENDING when we start removing the module, as mac80211 will cleanly shut down the device in this case. Additionally, there's no point in rejecting commands to the device when we're cleaning up as that only leads to unwanted errors from mac80211 being printed, such as failed to remove key (...) from hardware (-16) Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-rxon.c | 6 ------ drivers/net/wireless/iwlwifi/iwl-agn.c | 6 ------ drivers/net/wireless/iwlwifi/iwl-mac80211.c | 4 ---- drivers/net/wireless/iwlwifi/iwl-scan.c | 3 +-- drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c | 7 ------- 5 files changed, 1 insertion(+), 25 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c index a8c790028d53..7a86a359e573 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c @@ -422,9 +422,6 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) lockdep_assert_held(&priv->shrd->mutex); - if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) - return -EINVAL; - if (!iwl_is_alive(priv->shrd)) return -EBUSY; @@ -560,9 +557,6 @@ int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed) mutex_lock(&priv->shrd->mutex); - if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) - goto out; - if (unlikely(test_bit(STATUS_SCANNING, &priv->shrd->status))) { IWL_DEBUG_MAC80211(priv, "leave - scanning\n"); goto out; diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index ada9d9e4402b..c14eda048948 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -1378,12 +1378,6 @@ static void iwl_op_mode_dvm_stop(struct iwl_op_mode *op_mode) iwl_dbgfs_unregister(priv); - /* ieee80211_unregister_hw call wil cause iwlagn_mac_stop to - * to be called and iwl_down since we are removing the device - * we need to set STATUS_EXIT_PENDING bit. - */ - set_bit(STATUS_EXIT_PENDING, &priv->shrd->status); - iwl_testmode_cleanup(priv); iwlagn_mac_unregister(priv); diff --git a/drivers/net/wireless/iwlwifi/iwl-mac80211.c b/drivers/net/wireless/iwlwifi/iwl-mac80211.c index dcee30f0d629..7f63ba93ba5d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-mac80211.c +++ b/drivers/net/wireless/iwlwifi/iwl-mac80211.c @@ -649,8 +649,6 @@ static int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw, case IEEE80211_AMPDU_RX_STOP: IWL_DEBUG_HT(priv, "stop Rx\n"); ret = iwl_sta_rx_agg_stop(priv, sta, tid); - if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) - ret = 0; break; case IEEE80211_AMPDU_TX_START: if (iwlagn_mod_params.disable_11n & IWL_DISABLE_HT_TXAGG) @@ -666,8 +664,6 @@ static int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw, IWL_DEBUG_HT(priv, "priv->agg_tids_count = %u\n", priv->agg_tids_count); } - if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) - ret = 0; if (!priv->agg_tids_count && cfg(priv)->ht_params && cfg(priv)->ht_params->use_rts_for_aggregation) { /* diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index 42ee1c410efd..766572b9ac89 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c @@ -69,8 +69,7 @@ static int iwl_send_scan_abort(struct iwl_priv *priv) if (!test_bit(STATUS_READY, &priv->shrd->status) || !test_bit(STATUS_GEO_CONFIGURED, &priv->shrd->status) || !test_bit(STATUS_SCAN_HW, &priv->shrd->status) || - test_bit(STATUS_FW_ERROR, &priv->shrd->status) || - test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) + test_bit(STATUS_FW_ERROR, &priv->shrd->status)) return -EIO; ret = iwl_trans_send_cmd(trans(priv), &cmd); diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c index 1cb1dd29b3fe..de2a0d91d658 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c @@ -914,9 +914,6 @@ static int iwl_send_cmd_async(struct iwl_trans *trans, struct iwl_host_cmd *cmd) return -EINVAL; - if (test_bit(STATUS_EXIT_PENDING, &trans->shrd->status)) - return -EBUSY; - ret = iwl_enqueue_hcmd(trans, cmd); if (ret < 0) { IWL_DEBUG_QUIET_RFKILL(trans, @@ -938,10 +935,6 @@ static int iwl_send_cmd_sync(struct iwl_trans *trans, struct iwl_host_cmd *cmd) IWL_DEBUG_INFO(trans, "Attempting to send sync command %s\n", get_cmd_string(cmd->id)); - if (test_bit(STATUS_EXIT_PENDING, &trans->shrd->status)) - return -EBUSY; - - if (test_bit(STATUS_RF_KILL_HW, &trans->shrd->status)) { IWL_ERR(trans, "Command %s aborted: RF KILL Switch\n", get_cmd_string(cmd->id)); -- cgit From fb5fe5b9da167f25fd44818327338eeec20c2a5a Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 5 Mar 2012 11:24:29 -0800 Subject: iwlwifi: simplify auth/assoc flow With mac80211 now giving us station information (via the sta_state callback) before auth/assoc we can get rid of tx_sync by adding the station early for the case of managed interfaces. Keep AP mode actions the same for now. As we now get the BSSID early, we can also get rid of iwl_reprogram_ap_sta(). We can still optimise the number of RXONs we send to the device, but that can be done later. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-rxon.c | 7 - drivers/net/wireless/iwlwifi/iwl-agn-sta.c | 45 ------ drivers/net/wireless/iwlwifi/iwl-agn.h | 1 - drivers/net/wireless/iwlwifi/iwl-dev.h | 3 - drivers/net/wireless/iwlwifi/iwl-mac80211.c | 207 ++++++++++++---------------- 5 files changed, 90 insertions(+), 173 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c index 7a86a359e573..e806ad82e7e3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c @@ -274,8 +274,6 @@ static int iwlagn_rxon_connect(struct iwl_priv *priv, } memcpy(active, &ctx->staging, sizeof(*active)); - iwl_reprogram_ap_sta(priv, ctx); - /* IBSS beacon needs to be sent after setting assoc */ if (ctx->vif && (ctx->vif->type == NL80211_IFTYPE_ADHOC)) if (iwlagn_update_beacon(priv, ctx->vif)) @@ -431,10 +429,6 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) if (!ctx->is_active) return 0; - /* override BSSID if necessary due to preauth */ - if (ctx->preauth_bssid) - memcpy(ctx->staging.bssid_addr, ctx->bssid, ETH_ALEN); - /* always get timestamp with Rx frame */ ctx->staging.flags |= RXON_FLG_TSF2HOST_MSK; @@ -920,7 +914,6 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw, if (!priv->disable_chain_noise_cal) iwlagn_chain_noise_reset(priv); priv->start_calib = 1; - WARN_ON(ctx->preauth_bssid); } if (changes & BSS_CHANGED_IBSS) { diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c index 4bd50daeac1a..222a8f46365f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c @@ -626,51 +626,6 @@ void iwl_restore_stations(struct iwl_priv *priv, struct iwl_rxon_context *ctx) "complete.\n"); } -void iwl_reprogram_ap_sta(struct iwl_priv *priv, struct iwl_rxon_context *ctx) -{ - int sta_id = ctx->ap_sta_id; - int ret; - struct iwl_addsta_cmd sta_cmd; - struct iwl_link_quality_cmd lq; - bool active, have_lq = false; - - spin_lock_bh(&priv->sta_lock); - if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE)) { - spin_unlock_bh(&priv->sta_lock); - return; - } - - memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(sta_cmd)); - sta_cmd.mode = 0; - if (priv->stations[sta_id].lq) { - memcpy(&lq, priv->stations[sta_id].lq, sizeof(lq)); - have_lq = true; - } - - active = priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE; - priv->stations[sta_id].used &= ~IWL_STA_DRIVER_ACTIVE; - spin_unlock_bh(&priv->sta_lock); - - if (active) { - ret = iwl_send_remove_station( - priv, priv->stations[sta_id].sta.sta.addr, - sta_id, true); - if (ret) - IWL_ERR(priv, "failed to remove STA %pM (%d)\n", - priv->stations[sta_id].sta.sta.addr, ret); - } - spin_lock_bh(&priv->sta_lock); - priv->stations[sta_id].used |= IWL_STA_DRIVER_ACTIVE; - spin_unlock_bh(&priv->sta_lock); - - ret = iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC); - if (ret) - IWL_ERR(priv, "failed to re-add STA %pM (%d)\n", - priv->stations[sta_id].sta.sta.addr, ret); - if (have_lq) - iwl_send_lq_cmd(priv, ctx, &lq, CMD_SYNC, true); -} - int iwl_get_free_ucode_key_offset(struct iwl_priv *priv) { int i; diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index ef0cdf5b32fa..a142a197b2e4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h @@ -227,7 +227,6 @@ void iwl_sta_fill_lq(struct iwl_priv *priv, struct iwl_rxon_context *ctx, u8 sta_id, struct iwl_link_quality_cmd *link_cmd); int iwl_send_lq_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx, struct iwl_link_quality_cmd *lq, u8 flags, bool init); -void iwl_reprogram_ap_sta(struct iwl_priv *priv, struct iwl_rxon_context *ctx); int iwl_add_sta_callback(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb, struct iwl_device_cmd *cmd); diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 5b537dbe0af4..9ea9002cc839 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -671,9 +671,6 @@ struct iwl_rxon_context { u8 extension_chan_offset; } ht; - u8 bssid[ETH_ALEN]; - bool preauth_bssid; - bool last_tx_rejected; }; diff --git a/drivers/net/wireless/iwlwifi/iwl-mac80211.c b/drivers/net/wireless/iwlwifi/iwl-mac80211.c index 7f63ba93ba5d..005763fa38ab 100644 --- a/drivers/net/wireless/iwlwifi/iwl-mac80211.c +++ b/drivers/net/wireless/iwlwifi/iwl-mac80211.c @@ -692,12 +692,9 @@ static int iwlagn_mac_sta_add(struct ieee80211_hw *hw, struct iwl_station_priv *sta_priv = (void *)sta->drv_priv; struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; bool is_ap = vif->type == NL80211_IFTYPE_STATION; - int ret = 0; + int ret; u8 sta_id; - IWL_DEBUG_MAC80211(priv, "received request to add station %pM\n", - sta->addr); - mutex_lock(&priv->shrd->mutex); IWL_DEBUG_INFO(priv, "proceeding to add station %pM\n", sta->addr); sta_priv->sta_id = IWL_INVALID_STATION; @@ -712,16 +709,98 @@ static int iwlagn_mac_sta_add(struct ieee80211_hw *hw, IWL_ERR(priv, "Unable to add station %pM (%d)\n", sta->addr, ret); /* Should we return success if return code is EEXIST ? */ - goto out; + return ret; } sta_priv->sta_id = sta_id; - /* Initialize rate scaling */ - IWL_DEBUG_INFO(priv, "Initializing rate scaling for station %pM\n", - sta->addr); - iwl_rs_rate_init(priv, sta, sta_id); - out: + return 0; +} + +static int iwlagn_mac_sta_remove(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta) +{ + struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); + struct iwl_station_priv *sta_priv = (void *)sta->drv_priv; + int ret; + + IWL_DEBUG_INFO(priv, "proceeding to remove station %pM\n", + sta->addr); + ret = iwl_remove_station(priv, sta_priv->sta_id, sta->addr); + if (ret) + IWL_DEBUG_QUIET_RFKILL(priv, "Error removing station %pM\n", + sta->addr); + return ret; +} + +static int iwlagn_mac_sta_state(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, + enum ieee80211_sta_state old_state, + enum ieee80211_sta_state new_state) +{ + struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); + enum { + NONE, ADD, REMOVE, RATE_INIT, ADD_RATE_INIT, + } op = NONE; + int ret; + + IWL_DEBUG_MAC80211(priv, "station %pM state change %d->%d\n", + sta->addr, old_state, new_state); + + mutex_lock(&priv->shrd->mutex); + if (vif->type == NL80211_IFTYPE_STATION) { + if (old_state == IEEE80211_STA_NOTEXIST && + new_state == IEEE80211_STA_NONE) + op = ADD; + else if (old_state == IEEE80211_STA_NONE && + new_state == IEEE80211_STA_NOTEXIST) + op = REMOVE; + else if (old_state == IEEE80211_STA_AUTH && + new_state == IEEE80211_STA_ASSOC) + op = RATE_INIT; + } else { + if (old_state == IEEE80211_STA_AUTH && + new_state == IEEE80211_STA_ASSOC) + op = ADD_RATE_INIT; + else if (old_state == IEEE80211_STA_ASSOC && + new_state == IEEE80211_STA_AUTH) + op = REMOVE; + } + + switch (op) { + case ADD: + ret = iwlagn_mac_sta_add(hw, vif, sta); + break; + case REMOVE: + ret = iwlagn_mac_sta_remove(hw, vif, sta); + break; + case ADD_RATE_INIT: + ret = iwlagn_mac_sta_add(hw, vif, sta); + if (ret) + break; + /* fall through */ + case RATE_INIT: + /* Initialize rate scaling */ + IWL_DEBUG_INFO(priv, + "Initializing rate scaling for station %pM\n", + sta->addr); + iwl_rs_rate_init(priv, sta, iwl_sta_id(sta)); + ret = 0; + break; + default: + ret = 0; + break; + } + + /* + * mac80211 might WARN if we fail, but due the way we + * (badly) handle hard rfkill, we might fail here + */ + if (iwl_is_rfkill(priv->shrd)) + ret = 0; + mutex_unlock(&priv->shrd->mutex); IWL_DEBUG_MAC80211(priv, "leave\n"); @@ -1003,86 +1082,6 @@ static int iwlagn_mac_cancel_remain_on_channel(struct ieee80211_hw *hw) return 0; } -static int iwlagn_mac_tx_sync(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - const u8 *bssid, - enum ieee80211_tx_sync_type type) -{ - struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); - struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; - struct iwl_rxon_context *ctx = vif_priv->ctx; - int ret; - u8 sta_id; - - if (ctx->ctxid != IWL_RXON_CTX_PAN) - return 0; - - IWL_DEBUG_MAC80211(priv, "enter\n"); - mutex_lock(&priv->shrd->mutex); - - if (iwl_is_associated_ctx(ctx)) { - ret = 0; - goto out; - } - - if (ctx->preauth_bssid || test_bit(STATUS_SCAN_HW, - &priv->shrd->status)) { - ret = -EBUSY; - goto out; - } - - ret = iwl_add_station_common(priv, ctx, bssid, true, NULL, &sta_id); - if (ret) - goto out; - - if (WARN_ON(sta_id != ctx->ap_sta_id)) { - ret = -EIO; - goto out_remove_sta; - } - - memcpy(ctx->bssid, bssid, ETH_ALEN); - ctx->preauth_bssid = true; - - ret = iwlagn_commit_rxon(priv, ctx); - - if (ret == 0) - goto out; - - out_remove_sta: - iwl_remove_station(priv, sta_id, bssid); - out: - mutex_unlock(&priv->shrd->mutex); - IWL_DEBUG_MAC80211(priv, "leave\n"); - - return ret; -} - -static void iwlagn_mac_finish_tx_sync(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - const u8 *bssid, - enum ieee80211_tx_sync_type type) -{ - struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); - struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; - struct iwl_rxon_context *ctx = vif_priv->ctx; - - if (ctx->ctxid != IWL_RXON_CTX_PAN) - return; - - IWL_DEBUG_MAC80211(priv, "enter\n"); - mutex_lock(&priv->shrd->mutex); - - if (iwl_is_associated_ctx(ctx)) - goto out; - - iwl_remove_station(priv, ctx->ap_sta_id, bssid); - ctx->preauth_bssid = false; - /* no need to commit */ - out: - mutex_unlock(&priv->shrd->mutex); - IWL_DEBUG_MAC80211(priv, "leave\n"); -} - static void iwlagn_mac_rssi_callback(struct ieee80211_hw *hw, enum ieee80211_rssi_event rssi_event) { @@ -1471,29 +1470,6 @@ static int iwlagn_mac_hw_scan(struct ieee80211_hw *hw, return ret; } -static int iwlagn_mac_sta_remove(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct ieee80211_sta *sta) -{ - struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); - struct iwl_station_priv *sta_priv = (void *)sta->drv_priv; - int ret; - - IWL_DEBUG_MAC80211(priv, "enter: received request to remove " - "station %pM\n", sta->addr); - mutex_lock(&priv->shrd->mutex); - IWL_DEBUG_INFO(priv, "proceeding to remove station %pM\n", - sta->addr); - ret = iwl_remove_station(priv, sta_priv->sta_id, sta->addr); - if (ret) - IWL_DEBUG_QUIET_RFKILL(priv, "Error removing station %pM\n", - sta->addr); - mutex_unlock(&priv->shrd->mutex); - IWL_DEBUG_MAC80211(priv, "leave\n"); - - return ret; -} - static void iwl_sta_modify_ps_wake(struct iwl_priv *priv, int sta_id) { struct iwl_addsta_cmd cmd = { @@ -1559,8 +1535,7 @@ struct ieee80211_ops iwlagn_hw_ops = { .ampdu_action = iwlagn_mac_ampdu_action, .hw_scan = iwlagn_mac_hw_scan, .sta_notify = iwlagn_mac_sta_notify, - .sta_add = iwlagn_mac_sta_add, - .sta_remove = iwlagn_mac_sta_remove, + .sta_state = iwlagn_mac_sta_state, .channel_switch = iwlagn_mac_channel_switch, .flush = iwlagn_mac_flush, .tx_last_beacon = iwlagn_mac_tx_last_beacon, @@ -1569,8 +1544,6 @@ struct ieee80211_ops iwlagn_hw_ops = { .rssi_callback = iwlagn_mac_rssi_callback, CFG80211_TESTMODE_CMD(iwlagn_mac_testmode_cmd) CFG80211_TESTMODE_DUMP(iwlagn_mac_testmode_dump) - .tx_sync = iwlagn_mac_tx_sync, - .finish_tx_sync = iwlagn_mac_finish_tx_sync, .set_tim = iwlagn_mac_set_tim, }; -- cgit From a8bceb392a739321ec20d03a91a86ebdde9c07bb Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 5 Mar 2012 11:24:30 -0800 Subject: iwlwifi: remove per-device debug level There's no need for the per-device debug level that we expose in debugfs since the module parameter is writable in sysfs. At the same time, simplify code by changing iwl_get_debug_level(shrd) & IWL_DL_ISR) to iwl_have_debug_level(IWL_DL_ISR) Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-core.c | 10 ++--- drivers/net/wireless/iwlwifi/iwl-debug.c | 4 +- drivers/net/wireless/iwlwifi/iwl-debug.h | 12 +++--- drivers/net/wireless/iwlwifi/iwl-debugfs.c | 55 +----------------------- drivers/net/wireless/iwlwifi/iwl-shared.h | 27 +----------- drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c | 10 ++--- 6 files changed, 22 insertions(+), 96 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 8551c95e7437..8d25fd6be645 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -836,7 +836,7 @@ static void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand) unsigned long reload_jiffies; #ifdef CONFIG_IWLWIFI_DEBUG - if (iwl_get_debug_level(priv->shrd) & IWL_DL_FW_ERRORS) + if (iwl_have_debug_level(IWL_DL_FW_ERRORS)) iwl_print_rx_config_cmd(priv, IWL_RXON_CTX_BSS); #endif @@ -1004,7 +1004,7 @@ int iwl_alloc_traffic_mem(struct iwl_priv *priv) { u32 traffic_size = IWL_TRAFFIC_DUMP_SIZE; - if (iwl_get_debug_level(priv->shrd) & IWL_DL_TX) { + if (iwl_have_debug_level(IWL_DL_TX)) { if (!priv->tx_traffic) { priv->tx_traffic = kzalloc(traffic_size, GFP_KERNEL); @@ -1012,7 +1012,7 @@ int iwl_alloc_traffic_mem(struct iwl_priv *priv) return -ENOMEM; } } - if (iwl_get_debug_level(priv->shrd) & IWL_DL_RX) { + if (iwl_have_debug_level(IWL_DL_RX)) { if (!priv->rx_traffic) { priv->rx_traffic = kzalloc(traffic_size, GFP_KERNEL); @@ -1039,7 +1039,7 @@ void iwl_dbg_log_tx_data_frame(struct iwl_priv *priv, __le16 fc; u16 len; - if (likely(!(iwl_get_debug_level(priv->shrd) & IWL_DL_TX))) + if (likely(!iwl_have_debug_level(IWL_DL_TX))) return; if (!priv->tx_traffic) @@ -1063,7 +1063,7 @@ void iwl_dbg_log_rx_data_frame(struct iwl_priv *priv, __le16 fc; u16 len; - if (likely(!(iwl_get_debug_level(priv->shrd) & IWL_DL_RX))) + if (likely(!iwl_have_debug_level(IWL_DL_RX))) return; if (!priv->rx_traffic) diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.c b/drivers/net/wireless/iwlwifi/iwl-debug.c index 4bc2e70051d6..059efabda184 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debug.c +++ b/drivers/net/wireless/iwlwifi/iwl-debug.c @@ -104,7 +104,7 @@ void __iwl_err(struct device *dev, bool rfkill_prefix, bool trace_only, } #if defined(CONFIG_IWLWIFI_DEBUG) || defined(CONFIG_IWLWIFI_DEVICE_TRACING) -void __iwl_dbg(struct iwl_shared *shared, struct device *dev, +void __iwl_dbg(struct device *dev, u32 level, bool limit, const char *function, const char *fmt, ...) { @@ -116,7 +116,7 @@ void __iwl_dbg(struct iwl_shared *shared, struct device *dev, va_start(args, fmt); vaf.va = &args; #ifdef CONFIG_IWLWIFI_DEBUG - if (iwl_get_debug_level(shared) & level && + if (iwl_have_debug_level(level) && (!limit || net_ratelimit())) dev_err(dev, "%c %s %pV", in_interrupt() ? 'I' : 'U', function, &vaf); diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.h b/drivers/net/wireless/iwlwifi/iwl-debug.h index 01b23303d736..163d259198be 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debug.h +++ b/drivers/net/wireless/iwlwifi/iwl-debug.h @@ -47,12 +47,12 @@ void __iwl_crit(struct device *dev, const char *fmt, ...); #define IWL_CRIT(m, f, a...) __iwl_crit(trans(m)->dev, f, ## a) #if defined(CONFIG_IWLWIFI_DEBUG) || defined(CONFIG_IWLWIFI_DEVICE_TRACING) -void __iwl_dbg(struct iwl_shared *shared, struct device *dev, +void __iwl_dbg(struct device *dev, u32 level, bool limit, const char *function, const char *fmt, ...); #else static inline void -__iwl_dbg(struct iwl_shared *shared, struct device *dev, +__iwl_dbg(struct device *dev, u32 level, bool limit, const char *function, const char *fmt, ...) {} @@ -65,14 +65,14 @@ do { \ } while (0) #define IWL_DEBUG(m, level, fmt, args...) \ - __iwl_dbg((m)->shrd, trans(m)->dev, level, false, __func__, fmt, ##args) + __iwl_dbg(trans(m)->dev, level, false, __func__, fmt, ##args) #define IWL_DEBUG_LIMIT(m, level, fmt, args...) \ - __iwl_dbg((m)->shrd, trans(m)->dev, level, true, __func__, fmt, ##args) + __iwl_dbg(trans(m)->dev, level, true, __func__, fmt, ##args) #ifdef CONFIG_IWLWIFI_DEBUG #define iwl_print_hex_dump(m, level, p, len) \ do { \ - if (iwl_get_debug_level((m)->shrd) & level) \ + if (iwl_have_debug_level(level)) \ print_hex_dump(KERN_DEBUG, "iwl data: ", \ DUMP_PREFIX_OFFSET, 16, 1, p, len, 1); \ } while (0) @@ -82,7 +82,7 @@ do { \ IWL_ERR(m, fmt, ##args); \ else \ __iwl_err(trans(m)->dev, true, \ - !(iwl_get_debug_level((m)->shrd) & IWL_DL_RADIO),\ + !iwl_have_debug_level(IWL_DL_RADIO), \ fmt, ##args); \ } while (0) #else diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index 628af563e4e1..dd502e82e410 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c @@ -845,8 +845,7 @@ static ssize_t iwl_dbgfs_traffic_log_read(struct file *file, IWL_ERR(priv, "Can not allocate buffer\n"); return -ENOMEM; } - if (priv->tx_traffic && - (iwl_get_debug_level(priv->shrd) & IWL_DL_TX)) { + if (priv->tx_traffic && iwl_have_debug_level(IWL_DL_TX)) { ptr = priv->tx_traffic; pos += scnprintf(buf + pos, bufsz - pos, "Tx Traffic idx: %u\n", priv->tx_traffic_idx); @@ -864,8 +863,7 @@ static ssize_t iwl_dbgfs_traffic_log_read(struct file *file, } } - if (priv->rx_traffic && - (iwl_get_debug_level(priv->shrd) & IWL_DL_RX)) { + if (priv->rx_traffic && iwl_have_debug_level(IWL_DL_RX)) { ptr = priv->rx_traffic; pos += scnprintf(buf + pos, bufsz - pos, "Rx Traffic idx: %u\n", priv->rx_traffic_idx); @@ -2507,52 +2505,6 @@ DEBUGFS_READ_WRITE_FILE_OPS(protection_mode); DEBUGFS_READ_FILE_OPS(reply_tx_error); DEBUGFS_WRITE_FILE_OPS(echo_test); -#ifdef CONFIG_IWLWIFI_DEBUG -static ssize_t iwl_dbgfs_debug_level_read(struct file *file, - char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct iwl_priv *priv = file->private_data; - struct iwl_shared *shrd = priv->shrd; - char buf[11]; - int len; - - len = scnprintf(buf, sizeof(buf), "0x%.8x", - iwl_get_debug_level(shrd)); - - return simple_read_from_buffer(user_buf, count, ppos, buf, len); -} - -static ssize_t iwl_dbgfs_debug_level_write(struct file *file, - const char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct iwl_priv *priv = file->private_data; - struct iwl_shared *shrd = priv->shrd; - char buf[11]; - unsigned long val; - int ret; - - if (count > sizeof(buf)) - return -EINVAL; - - memset(buf, 0, sizeof(buf)); - if (copy_from_user(buf, user_buf, count)) - return -EFAULT; - - ret = strict_strtoul(buf, 0, &val); - if (ret) - return ret; - - shrd->dbg_level_dev = val; - if (iwl_alloc_traffic_mem(priv)) - IWL_ERR(priv, "Not enough memory to generate traffic log\n"); - - return count; -} -DEBUGFS_READ_WRITE_FILE_OPS(debug_level); -#endif /* CONFIG_IWLWIFI_DEBUG */ - /* * Create the debugfs files and directories * @@ -2617,9 +2569,6 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name) DEBUGFS_ADD_FILE(echo_test, dir_debug, S_IWUSR); if (iwl_advanced_bt_coexist(priv)) DEBUGFS_ADD_FILE(bt_traffic, dir_debug, S_IRUSR); -#ifdef CONFIG_IWLWIFI_DEBUG - DEBUGFS_ADD_FILE(debug_level, dir_debug, S_IRUSR | S_IWUSR); -#endif DEBUGFS_ADD_BOOL(disable_sensitivity, dir_rf, &priv->disable_sens_cal); diff --git a/drivers/net/wireless/iwlwifi/iwl-shared.h b/drivers/net/wireless/iwlwifi/iwl-shared.h index 7720fc34c278..239dfbc57bee 100644 --- a/drivers/net/wireless/iwlwifi/iwl-shared.h +++ b/drivers/net/wireless/iwlwifi/iwl-shared.h @@ -346,8 +346,6 @@ struct iwl_cfg { /** * struct iwl_shared - shared fields for all the layers of the driver * - * @dbg_level_dev: dbg level set per device. Prevails on - * iwlagn_mod_params.debug_level if set (!= 0) * @ucode_owner: IWL_OWNERSHIP_* * @cmd_queue: command queue number * @status: STATUS_* @@ -370,10 +368,6 @@ struct iwl_cfg { * @device_pointers: pointers to ucode event tables */ struct iwl_shared { -#ifdef CONFIG_IWLWIFI_DEBUG - u32 dbg_level_dev; -#endif /* CONFIG_IWLWIFI_DEBUG */ - #define IWL_OWNERSHIP_DRIVER 0 #define IWL_OWNERSHIP_TM 1 u8 ucode_owner; @@ -417,27 +411,10 @@ struct iwl_shared { #define trans(_m) ((_m)->shrd->trans) #define hw_params(_m) ((_m)->shrd->hw_params) -#ifdef CONFIG_IWLWIFI_DEBUG -/* - * iwl_get_debug_level: Return active debug level for device - * - * Using sysfs it is possible to set per device debug level. This debug - * level will be used if set, otherwise the global debug level which can be - * set via module parameter is used. - */ -static inline u32 iwl_get_debug_level(struct iwl_shared *shrd) -{ - if (shrd->dbg_level_dev) - return shrd->dbg_level_dev; - else - return iwlagn_mod_params.debug_level; -} -#else -static inline u32 iwl_get_debug_level(struct iwl_shared *shrd) +static inline bool iwl_have_debug_level(u32 level) { - return iwlagn_mod_params.debug_level; + return iwlagn_mod_params.debug_level & level; } -#endif static inline void iwl_free_pages(struct iwl_shared *shrd, unsigned long page) { diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c index 2c910fddaaf6..6495945637b9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c @@ -881,7 +881,7 @@ int iwl_dump_nic_event_log(struct iwl_trans *trans, bool full_log, } #ifdef CONFIG_IWLWIFI_DEBUG - if (!(iwl_get_debug_level(trans->shrd) & IWL_DL_FW_ERRORS) && !full_log) + if (!(iwl_have_debug_level(IWL_DL_FW_ERRORS)) && !full_log) size = (size > DEFAULT_DUMP_EVENT_LOG_ENTRIES) ? DEFAULT_DUMP_EVENT_LOG_ENTRIES : size; #else @@ -901,7 +901,7 @@ int iwl_dump_nic_event_log(struct iwl_trans *trans, bool full_log, if (!*buf) return -ENOMEM; } - if ((iwl_get_debug_level(trans->shrd) & IWL_DL_FW_ERRORS) || full_log) { + if (iwl_have_debug_level(IWL_DL_FW_ERRORS) || full_log) { /* * if uCode has wrapped back to top of log, * start at the oldest entry, @@ -960,7 +960,7 @@ void iwl_irq_tasklet(struct iwl_trans *trans) inta = trans_pcie->inta; #ifdef CONFIG_IWLWIFI_DEBUG - if (iwl_get_debug_level(trans->shrd) & IWL_DL_ISR) { + if (iwl_have_debug_level(IWL_DL_ISR)) { /* just for debug */ inta_mask = iwl_read32(trans, CSR_INT_MASK); IWL_DEBUG_ISR(trans, "inta 0x%08x, enabled 0x%08x\n ", @@ -989,7 +989,7 @@ void iwl_irq_tasklet(struct iwl_trans *trans) } #ifdef CONFIG_IWLWIFI_DEBUG - if (iwl_get_debug_level(trans->shrd) & (IWL_DL_ISR)) { + if (iwl_have_debug_level(IWL_DL_ISR)) { /* NIC fires this, but we don't use it, redundant with WAKEUP */ if (inta & CSR_INT_BIT_SCD) { IWL_DEBUG_ISR(trans, "Scheduler finished to transmit " @@ -1301,7 +1301,7 @@ static irqreturn_t iwl_isr(int irq, void *data) } #ifdef CONFIG_IWLWIFI_DEBUG - if (iwl_get_debug_level(trans->shrd) & (IWL_DL_ISR)) { + if (iwl_have_debug_level(IWL_DL_ISR)) { inta_fh = iwl_read32(trans, CSR_FH_INT_STATUS); IWL_DEBUG_ISR(trans, "ISR inta 0x%08x, enabled 0x%08x, " "fh 0x%08x\n", inta, inta_mask, inta_fh); -- cgit From 54708d8df355b7ecf1d25d4049336840e6107d96 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 5 Mar 2012 11:24:31 -0800 Subject: iwlwifi: remove SKU from config There's no SKU override, we always just use it from EEPROM. As such, we can remove it from the config and use it in hw_param only. Since iwl_eeprom_check_sku() really needs to fill it in also rename that to iwl_eeprom_init_hw_params(). Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 2 +- drivers/net/wireless/iwlwifi/iwl-agn.c | 5 ++--- drivers/net/wireless/iwlwifi/iwl-core.c | 8 ++++---- drivers/net/wireless/iwlwifi/iwl-eeprom.c | 20 +++++++++----------- drivers/net/wireless/iwlwifi/iwl-eeprom.h | 2 +- drivers/net/wireless/iwlwifi/iwl-mac80211.c | 4 ++-- drivers/net/wireless/iwlwifi/iwl-shared.h | 2 -- 7 files changed, 19 insertions(+), 24 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index 2470ca767589..79ac7cb1701b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -235,7 +235,7 @@ int iwlagn_txfifo_flush(struct iwl_priv *priv, u16 flush_control) IWL_PAN_SCD_BK_MSK | IWL_PAN_SCD_MGMT_MSK | IWL_PAN_SCD_MULTICAST_MSK; - if (cfg(priv)->sku & EEPROM_SKU_CAP_11N_ENABLE) + if (hw_params(priv).sku & EEPROM_SKU_CAP_11N_ENABLE) flush_cmd.fifo_control |= IWL_AGG_TX_QUEUE_MSK; IWL_DEBUG_INFO(priv, "fifo queue control: 0X%x\n", diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index c14eda048948..e1bf12578f87 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -1124,13 +1124,12 @@ static void iwl_set_hw_params(struct iwl_priv *priv) get_order(IWL_RX_BUF_SIZE_4K); if (iwlagn_mod_params.disable_11n & IWL_DISABLE_HT_ALL) - cfg(priv)->sku &= ~EEPROM_SKU_CAP_11N_ENABLE; + hw_params(priv).sku &= ~EEPROM_SKU_CAP_11N_ENABLE; hw_params(priv).num_ampdu_queues = cfg(priv)->base_params->num_of_ampdu_queues; hw_params(priv).shadow_reg_enable = cfg(priv)->base_params->shadow_reg_enable; - hw_params(priv).sku = cfg(priv)->sku; hw_params(priv).wd_timeout = cfg(priv)->base_params->wd_timeout; /* Device-specific setup */ @@ -1257,7 +1256,7 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans) if (err) goto out_free_eeprom; - err = iwl_eeprom_check_sku(priv); + err = iwl_eeprom_init_hw_params(priv); if (err) goto out_free_eeprom; diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 8d25fd6be645..c5df3e3d975b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -137,7 +137,7 @@ int iwl_init_geos(struct iwl_priv *priv) sband->bitrates = &rates[IWL_FIRST_OFDM_RATE]; sband->n_bitrates = IWL_RATE_COUNT_LEGACY - IWL_FIRST_OFDM_RATE; - if (cfg(priv)->sku & EEPROM_SKU_CAP_11N_ENABLE) + if (hw_params(priv).sku & EEPROM_SKU_CAP_11N_ENABLE) iwl_init_ht_hw_capab(priv, &sband->ht_cap, IEEE80211_BAND_5GHZ); @@ -147,7 +147,7 @@ int iwl_init_geos(struct iwl_priv *priv) sband->bitrates = rates; sband->n_bitrates = IWL_RATE_COUNT_LEGACY; - if (cfg(priv)->sku & EEPROM_SKU_CAP_11N_ENABLE) + if (hw_params(priv).sku & EEPROM_SKU_CAP_11N_ENABLE) iwl_init_ht_hw_capab(priv, &sband->ht_cap, IEEE80211_BAND_2GHZ); @@ -202,11 +202,11 @@ int iwl_init_geos(struct iwl_priv *priv) priv->tx_power_next = max_tx_power; if ((priv->bands[IEEE80211_BAND_5GHZ].n_channels == 0) && - cfg(priv)->sku & EEPROM_SKU_CAP_BAND_52GHZ) { + hw_params(priv).sku & EEPROM_SKU_CAP_BAND_52GHZ) { IWL_INFO(priv, "Incorrectly detected BG card as ABG. " "Please send your %s to maintainer.\n", trans(priv)->hw_id_str); - cfg(priv)->sku &= ~EEPROM_SKU_CAP_BAND_52GHZ; + hw_params(priv).sku &= ~EEPROM_SKU_CAP_BAND_52GHZ; } IWL_INFO(priv, "Tunable channels: %d 802.11bg, %d 802.11a channels\n", diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c index 07e93787bce8..d8668bccc083 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c @@ -252,26 +252,24 @@ err: } -int iwl_eeprom_check_sku(struct iwl_priv *priv) +int iwl_eeprom_init_hw_params(struct iwl_priv *priv) { struct iwl_shared *shrd = priv->shrd; u16 radio_cfg; - if (!cfg(priv)->sku) { - /* not using sku overwrite */ - cfg(priv)->sku = iwl_eeprom_query16(shrd, EEPROM_SKU_CAP); - if (cfg(priv)->sku & EEPROM_SKU_CAP_11N_ENABLE && - !cfg(priv)->ht_params) { - IWL_ERR(priv, "Invalid 11n configuration\n"); - return -EINVAL; - } + hw_params(priv).sku = iwl_eeprom_query16(shrd, EEPROM_SKU_CAP); + if (hw_params(priv).sku & EEPROM_SKU_CAP_11N_ENABLE && + !cfg(priv)->ht_params) { + IWL_ERR(priv, "Invalid 11n configuration\n"); + return -EINVAL; } - if (!cfg(priv)->sku) { + + if (!hw_params(priv).sku) { IWL_ERR(priv, "Invalid device sku\n"); return -EINVAL; } - IWL_INFO(priv, "Device SKU: 0x%X\n", cfg(priv)->sku); + IWL_INFO(priv, "Device SKU: 0x%X\n", hw_params(priv).sku); if (!cfg(priv)->valid_tx_ant && !cfg(priv)->valid_rx_ant) { /* not using .cfg overwrite */ diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.h b/drivers/net/wireless/iwlwifi/iwl-eeprom.h index cbb86116917b..3b17056d5675 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.h +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.h @@ -309,7 +309,7 @@ struct iwl_eeprom_ops { int iwl_eeprom_init(struct iwl_trans *trans, u32 hw_rev); void iwl_eeprom_free(struct iwl_shared *shrd); int iwl_eeprom_check_version(struct iwl_priv *priv); -int iwl_eeprom_check_sku(struct iwl_priv *priv); +int iwl_eeprom_init_hw_params(struct iwl_priv *priv); const u8 *iwl_eeprom_query_addr(const struct iwl_shared *shrd, size_t offset); u16 iwl_eeprom_query16(const struct iwl_shared *shrd, size_t offset); int iwl_init_channel_map(struct iwl_priv *priv); diff --git a/drivers/net/wireless/iwlwifi/iwl-mac80211.c b/drivers/net/wireless/iwlwifi/iwl-mac80211.c index 005763fa38ab..8b26f3217823 100644 --- a/drivers/net/wireless/iwlwifi/iwl-mac80211.c +++ b/drivers/net/wireless/iwlwifi/iwl-mac80211.c @@ -161,7 +161,7 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv, hw->flags |= IEEE80211_HW_SUPPORTS_PS | IEEE80211_HW_SUPPORTS_DYNAMIC_PS; - if (cfg(priv)->sku & EEPROM_SKU_CAP_11N_ENABLE) + if (hw_params(priv).sku & EEPROM_SKU_CAP_11N_ENABLE) hw->flags |= IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS | IEEE80211_HW_SUPPORTS_STATIC_SMPS; @@ -633,7 +633,7 @@ static int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw, IWL_DEBUG_HT(priv, "A-MPDU action on addr %pM tid %d\n", sta->addr, tid); - if (!(cfg(priv)->sku & EEPROM_SKU_CAP_11N_ENABLE)) + if (!(hw_params(priv).sku & EEPROM_SKU_CAP_11N_ENABLE)) return -EACCES; IWL_DEBUG_MAC80211(priv, "enter\n"); diff --git a/drivers/net/wireless/iwlwifi/iwl-shared.h b/drivers/net/wireless/iwlwifi/iwl-shared.h index 239dfbc57bee..11184f1c4365 100644 --- a/drivers/net/wireless/iwlwifi/iwl-shared.h +++ b/drivers/net/wireless/iwlwifi/iwl-shared.h @@ -282,7 +282,6 @@ enum iwl_led_mode { * @max_data_size: The maximal length of the fw data section * @valid_tx_ant: valid transmit antenna * @valid_rx_ant: valid receive antenna - * @sku: sku information from EEPROM * @eeprom_ver: EEPROM version * @eeprom_calib_ver: EEPROM calibration version * @lib: pointer to the lib ops @@ -321,7 +320,6 @@ struct iwl_cfg { const u32 max_inst_size; u8 valid_tx_ant; u8 valid_rx_ant; - u16 sku; u16 eeprom_ver; u16 eeprom_calib_ver; const struct iwl_lib_ops *lib; -- cgit From 7e79a3937a44b1dc5f457e6dbb8c50e93719286a Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 5 Mar 2012 11:24:32 -0800 Subject: iwlwifi: use valid TX/RX antenna from hw_params It's not really a good idea to write to the global static configuration. Use the valid TX/RX antenna information only from the HW params struct except in the case where the values from the config are used to override the values from the EEPROM. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-1000.c | 7 +++-- drivers/net/wireless/iwlwifi/iwl-2000.c | 7 +++-- drivers/net/wireless/iwlwifi/iwl-5000.c | 16 ++++++------ drivers/net/wireless/iwlwifi/iwl-6000.c | 7 +++-- drivers/net/wireless/iwlwifi/iwl-agn-calib.c | 4 +-- drivers/net/wireless/iwlwifi/iwl-agn.c | 2 +- drivers/net/wireless/iwlwifi/iwl-debugfs.c | 9 ++++--- drivers/net/wireless/iwlwifi/iwl-eeprom.c | 38 +++++++++++++++------------- 8 files changed, 46 insertions(+), 44 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index 605ee3df1d82..22eb0622ac21 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c @@ -131,14 +131,13 @@ static void iwl1000_hw_set_hw_params(struct iwl_priv *priv) hw_params(priv).ht40_channel = BIT(IEEE80211_BAND_2GHZ); - hw_params(priv).tx_chains_num = num_of_ant(cfg(priv)->valid_tx_ant); + hw_params(priv).tx_chains_num = + num_of_ant(hw_params(priv).valid_tx_ant); if (cfg(priv)->rx_with_siso_diversity) hw_params(priv).rx_chains_num = 1; else hw_params(priv).rx_chains_num = - num_of_ant(cfg(priv)->valid_rx_ant); - hw_params(priv).valid_tx_ant = cfg(priv)->valid_tx_ant; - hw_params(priv).valid_rx_ant = cfg(priv)->valid_rx_ant; + num_of_ant(hw_params(priv).valid_rx_ant); iwl1000_set_ct_threshold(priv); diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c index e6e8c79a80d8..43d17a4564e3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-2000.c +++ b/drivers/net/wireless/iwlwifi/iwl-2000.c @@ -127,14 +127,13 @@ static void iwl2000_hw_set_hw_params(struct iwl_priv *priv) hw_params(priv).ht40_channel = BIT(IEEE80211_BAND_2GHZ); - hw_params(priv).tx_chains_num = num_of_ant(cfg(priv)->valid_tx_ant); + hw_params(priv).tx_chains_num = + num_of_ant(hw_params(priv).valid_tx_ant); if (cfg(priv)->rx_with_siso_diversity) hw_params(priv).rx_chains_num = 1; else hw_params(priv).rx_chains_num = - num_of_ant(cfg(priv)->valid_rx_ant); - hw_params(priv).valid_tx_ant = cfg(priv)->valid_tx_ant; - hw_params(priv).valid_rx_ant = cfg(priv)->valid_rx_ant; + num_of_ant(hw_params(priv).valid_rx_ant); iwl2000_set_ct_threshold(priv); diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index ccaeead29c2f..8cdc4a35a973 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -167,10 +167,10 @@ static void iwl5000_hw_set_hw_params(struct iwl_priv *priv) hw_params(priv).ht40_channel = BIT(IEEE80211_BAND_2GHZ) | BIT(IEEE80211_BAND_5GHZ); - hw_params(priv).tx_chains_num = num_of_ant(cfg(priv)->valid_tx_ant); - hw_params(priv).rx_chains_num = num_of_ant(cfg(priv)->valid_rx_ant); - hw_params(priv).valid_tx_ant = cfg(priv)->valid_tx_ant; - hw_params(priv).valid_rx_ant = cfg(priv)->valid_rx_ant; + hw_params(priv).tx_chains_num = + num_of_ant(hw_params(priv).valid_tx_ant); + hw_params(priv).rx_chains_num = + num_of_ant(hw_params(priv).valid_rx_ant); iwl5000_set_ct_threshold(priv); @@ -190,10 +190,10 @@ static void iwl5150_hw_set_hw_params(struct iwl_priv *priv) hw_params(priv).ht40_channel = BIT(IEEE80211_BAND_2GHZ) | BIT(IEEE80211_BAND_5GHZ); - hw_params(priv).tx_chains_num = num_of_ant(cfg(priv)->valid_tx_ant); - hw_params(priv).rx_chains_num = num_of_ant(cfg(priv)->valid_rx_ant); - hw_params(priv).valid_tx_ant = cfg(priv)->valid_tx_ant; - hw_params(priv).valid_rx_ant = cfg(priv)->valid_rx_ant; + hw_params(priv).tx_chains_num = + num_of_ant(hw_params(priv).valid_tx_ant); + hw_params(priv).rx_chains_num = + num_of_ant(hw_params(priv).valid_rx_ant); iwl5150_set_ct_threshold(priv); diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index 223e60a1b79d..720e8e6e62ae 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -149,14 +149,13 @@ static void iwl6000_hw_set_hw_params(struct iwl_priv *priv) hw_params(priv).ht40_channel = BIT(IEEE80211_BAND_2GHZ) | BIT(IEEE80211_BAND_5GHZ); - hw_params(priv).tx_chains_num = num_of_ant(cfg(priv)->valid_tx_ant); + hw_params(priv).tx_chains_num = + num_of_ant(hw_params(priv).valid_tx_ant); if (cfg(priv)->rx_with_siso_diversity) hw_params(priv).rx_chains_num = 1; else hw_params(priv).rx_chains_num = - num_of_ant(cfg(priv)->valid_rx_ant); - hw_params(priv).valid_tx_ant = cfg(priv)->valid_tx_ant; - hw_params(priv).valid_rx_ant = cfg(priv)->valid_rx_ant; + num_of_ant(hw_params(priv).valid_rx_ant); iwl6000_set_ct_threshold(priv); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c index 12acc81ed419..84fc5ce91b35 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c @@ -848,7 +848,7 @@ static void iwl_find_disconn_antenna(struct iwl_priv *priv, u32* average_sig, * connect the first valid tx chain */ first_chain = - find_first_chain(cfg(priv)->valid_tx_ant); + find_first_chain(hw_params(priv).valid_tx_ant); data->disconn_array[first_chain] = 0; active_chains |= BIT(first_chain); IWL_DEBUG_CALIB(priv, @@ -1082,7 +1082,7 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv) iwlagn_gain_computation(priv, average_noise, min_average_noise_antenna_i, min_average_noise, - find_first_chain(cfg(priv)->valid_rx_ant)); + find_first_chain(hw_params(priv).valid_rx_ant)); /* Some power changes may have been made during the calibration. * Update and commit the RXON diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index e1bf12578f87..6cec7e63c171 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -699,7 +699,7 @@ int iwl_alive_start(struct iwl_priv *priv) priv->active_rate = IWL_RATES_MASK; /* Configure Tx antenna selection based on H/W config */ - iwlagn_send_tx_ant_config(priv, cfg(priv)->valid_tx_ant); + iwlagn_send_tx_ant_config(priv, hw_params(priv).valid_tx_ant); if (iwl_is_associated_ctx(ctx) && !priv->shrd->wowlan) { struct iwl_rxon_cmd *active_rxon = diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index dd502e82e410..b6740c33b519 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c @@ -1546,15 +1546,18 @@ static ssize_t iwl_dbgfs_ucode_tx_stats_read(struct file *file, if (tx->tx_power.ant_a || tx->tx_power.ant_b || tx->tx_power.ant_c) { pos += scnprintf(buf + pos, bufsz - pos, "tx power: (1/2 dB step)\n"); - if ((cfg(priv)->valid_tx_ant & ANT_A) && tx->tx_power.ant_a) + if ((hw_params(priv).valid_tx_ant & ANT_A) && + tx->tx_power.ant_a) pos += scnprintf(buf + pos, bufsz - pos, fmt_hex, "antenna A:", tx->tx_power.ant_a); - if ((cfg(priv)->valid_tx_ant & ANT_B) && tx->tx_power.ant_b) + if ((hw_params(priv).valid_tx_ant & ANT_B) && + tx->tx_power.ant_b) pos += scnprintf(buf + pos, bufsz - pos, fmt_hex, "antenna B:", tx->tx_power.ant_b); - if ((cfg(priv)->valid_tx_ant & ANT_C) && tx->tx_power.ant_c) + if ((hw_params(priv).valid_tx_ant & ANT_C) && + tx->tx_power.ant_c) pos += scnprintf(buf + pos, bufsz - pos, fmt_hex, "antenna C:", tx->tx_power.ant_c); diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c index d8668bccc083..6915b33add36 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c @@ -271,25 +271,27 @@ int iwl_eeprom_init_hw_params(struct iwl_priv *priv) IWL_INFO(priv, "Device SKU: 0x%X\n", hw_params(priv).sku); - if (!cfg(priv)->valid_tx_ant && !cfg(priv)->valid_rx_ant) { - /* not using .cfg overwrite */ - radio_cfg = iwl_eeprom_query16(shrd, EEPROM_RADIO_CONFIG); - cfg(priv)->valid_tx_ant = EEPROM_RF_CFG_TX_ANT_MSK(radio_cfg); - cfg(priv)->valid_rx_ant = EEPROM_RF_CFG_RX_ANT_MSK(radio_cfg); - if (!cfg(priv)->valid_tx_ant || !cfg(priv)->valid_rx_ant) { - IWL_ERR(priv, "Invalid chain (0x%X, 0x%X)\n", - cfg(priv)->valid_tx_ant, - cfg(priv)->valid_rx_ant); - return -EINVAL; - } - IWL_INFO(priv, "Valid Tx ant: 0x%X, Valid Rx ant: 0x%X\n", - cfg(priv)->valid_tx_ant, cfg(priv)->valid_rx_ant); + radio_cfg = iwl_eeprom_query16(shrd, EEPROM_RADIO_CONFIG); + + hw_params(priv).valid_tx_ant = EEPROM_RF_CFG_TX_ANT_MSK(radio_cfg); + hw_params(priv).valid_rx_ant = EEPROM_RF_CFG_RX_ANT_MSK(radio_cfg); + + /* check overrides (some devices have wrong EEPROM) */ + if (cfg(priv)->valid_tx_ant) + hw_params(priv).valid_tx_ant = cfg(priv)->valid_tx_ant; + if (cfg(priv)->valid_rx_ant) + hw_params(priv).valid_rx_ant = cfg(priv)->valid_rx_ant; + + if (!hw_params(priv).valid_tx_ant || !hw_params(priv).valid_rx_ant) { + IWL_ERR(priv, "Invalid chain (0x%X, 0x%X)\n", + hw_params(priv).valid_tx_ant, + hw_params(priv).valid_rx_ant); + return -EINVAL; } - /* - * for some special cases, - * EEPROM did not reflect the correct antenna setting - * so overwrite the valid tx/rx antenna from .cfg - */ + + IWL_INFO(priv, "Valid Tx ant: 0x%X, Valid Rx ant: 0x%X\n", + hw_params(priv).valid_tx_ant, hw_params(priv).valid_rx_ant); + return 0; } -- cgit From 706c4ff67cb86134a3a93413a595a7c5559b7cc2 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 5 Mar 2012 11:24:33 -0800 Subject: iwlwifi: make config const Writing to the global config structures is always wrong. To protect against such mistakes in the future, mark them const. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-1000.c | 8 +-- drivers/net/wireless/iwlwifi/iwl-2000.c | 12 ++--- drivers/net/wireless/iwlwifi/iwl-5000.c | 14 +++--- drivers/net/wireless/iwlwifi/iwl-6000.c | 49 +++++++++--------- drivers/net/wireless/iwlwifi/iwl-cfg.h | 82 +++++++++++++++---------------- drivers/net/wireless/iwlwifi/iwl-drv.c | 2 +- drivers/net/wireless/iwlwifi/iwl-drv.h | 2 +- drivers/net/wireless/iwlwifi/iwl-eeprom.c | 2 +- drivers/net/wireless/iwlwifi/iwl-pci.c | 2 +- drivers/net/wireless/iwlwifi/iwl-shared.h | 2 +- drivers/net/wireless/iwlwifi/iwl-ucode.c | 4 +- 11 files changed, 90 insertions(+), 89 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index 22eb0622ac21..2199a0e5c4f0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c @@ -196,13 +196,13 @@ static struct iwl_ht_params iwl1000_ht_params = { .base_params = &iwl1000_base_params, \ .led_mode = IWL_LED_BLINK -struct iwl_cfg iwl1000_bgn_cfg = { +const struct iwl_cfg iwl1000_bgn_cfg = { .name = "Intel(R) Centrino(R) Wireless-N 1000 BGN", IWL_DEVICE_1000, .ht_params = &iwl1000_ht_params, }; -struct iwl_cfg iwl1000_bg_cfg = { +const struct iwl_cfg iwl1000_bg_cfg = { .name = "Intel(R) Centrino(R) Wireless-N 1000 BG", IWL_DEVICE_1000, }; @@ -221,13 +221,13 @@ struct iwl_cfg iwl1000_bg_cfg = { .led_mode = IWL_LED_RF_STATE, \ .rx_with_siso_diversity = true -struct iwl_cfg iwl100_bgn_cfg = { +const struct iwl_cfg iwl100_bgn_cfg = { .name = "Intel(R) Centrino(R) Wireless-N 100 BGN", IWL_DEVICE_100, .ht_params = &iwl1000_ht_params, }; -struct iwl_cfg iwl100_bg_cfg = { +const struct iwl_cfg iwl100_bg_cfg = { .name = "Intel(R) Centrino(R) Wireless-N 100 BG", IWL_DEVICE_100, }; diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c index 43d17a4564e3..1ba020723537 100644 --- a/drivers/net/wireless/iwlwifi/iwl-2000.c +++ b/drivers/net/wireless/iwlwifi/iwl-2000.c @@ -248,13 +248,13 @@ static struct iwl_bt_params iwl2030_bt_params = { .led_mode = IWL_LED_RF_STATE, \ .iq_invert = true \ -struct iwl_cfg iwl2000_2bgn_cfg = { +const struct iwl_cfg iwl2000_2bgn_cfg = { .name = "Intel(R) Centrino(R) Wireless-N 2200 BGN", IWL_DEVICE_2000, .ht_params = &iwl2000_ht_params, }; -struct iwl_cfg iwl2000_2bgn_d_cfg = { +const struct iwl_cfg iwl2000_2bgn_d_cfg = { .name = "Intel(R) Centrino(R) Wireless-N 2200D BGN", IWL_DEVICE_2000, .ht_params = &iwl2000_ht_params, @@ -278,7 +278,7 @@ struct iwl_cfg iwl2000_2bgn_d_cfg = { .adv_pm = true, \ .iq_invert = true \ -struct iwl_cfg iwl2030_2bgn_cfg = { +const struct iwl_cfg iwl2030_2bgn_cfg = { .name = "Intel(R) Centrino(R) Wireless-N 2230 BGN", IWL_DEVICE_2030, .ht_params = &iwl2000_ht_params, @@ -302,13 +302,13 @@ struct iwl_cfg iwl2030_2bgn_cfg = { .rx_with_siso_diversity = true, \ .iq_invert = true \ -struct iwl_cfg iwl105_bgn_cfg = { +const struct iwl_cfg iwl105_bgn_cfg = { .name = "Intel(R) Centrino(R) Wireless-N 105 BGN", IWL_DEVICE_105, .ht_params = &iwl2000_ht_params, }; -struct iwl_cfg iwl105_bgn_d_cfg = { +const struct iwl_cfg iwl105_bgn_d_cfg = { .name = "Intel(R) Centrino(R) Wireless-N 105D BGN", IWL_DEVICE_105, .ht_params = &iwl2000_ht_params, @@ -333,7 +333,7 @@ struct iwl_cfg iwl105_bgn_d_cfg = { .rx_with_siso_diversity = true, \ .iq_invert = true \ -struct iwl_cfg iwl135_bgn_cfg = { +const struct iwl_cfg iwl135_bgn_cfg = { .name = "Intel(R) Centrino(R) Wireless-N 135 BGN", IWL_DEVICE_135, .ht_params = &iwl2000_ht_params, diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index 8cdc4a35a973..dff75a09eb48 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -349,7 +349,7 @@ static struct iwl_ht_params iwl5000_ht_params = { .base_params = &iwl5000_base_params, \ .led_mode = IWL_LED_BLINK -struct iwl_cfg iwl5300_agn_cfg = { +const struct iwl_cfg iwl5300_agn_cfg = { .name = "Intel(R) Ultimate N WiFi Link 5300 AGN", IWL_DEVICE_5000, /* at least EEPROM 0x11A has wrong info */ @@ -358,7 +358,7 @@ struct iwl_cfg iwl5300_agn_cfg = { .ht_params = &iwl5000_ht_params, }; -struct iwl_cfg iwl5100_bgn_cfg = { +const struct iwl_cfg iwl5100_bgn_cfg = { .name = "Intel(R) WiFi Link 5100 BGN", IWL_DEVICE_5000, .valid_tx_ant = ANT_B, /* .cfg overwrite */ @@ -366,14 +366,14 @@ struct iwl_cfg iwl5100_bgn_cfg = { .ht_params = &iwl5000_ht_params, }; -struct iwl_cfg iwl5100_abg_cfg = { +const struct iwl_cfg iwl5100_abg_cfg = { .name = "Intel(R) WiFi Link 5100 ABG", IWL_DEVICE_5000, .valid_tx_ant = ANT_B, /* .cfg overwrite */ .valid_rx_ant = ANT_AB, /* .cfg overwrite */ }; -struct iwl_cfg iwl5100_agn_cfg = { +const struct iwl_cfg iwl5100_agn_cfg = { .name = "Intel(R) WiFi Link 5100 AGN", IWL_DEVICE_5000, .valid_tx_ant = ANT_B, /* .cfg overwrite */ @@ -381,7 +381,7 @@ struct iwl_cfg iwl5100_agn_cfg = { .ht_params = &iwl5000_ht_params, }; -struct iwl_cfg iwl5350_agn_cfg = { +const struct iwl_cfg iwl5350_agn_cfg = { .name = "Intel(R) WiMAX/WiFi Link 5350 AGN", .fw_name_pre = IWL5000_FW_PRE, .ucode_api_max = IWL5000_UCODE_API_MAX, @@ -411,14 +411,14 @@ struct iwl_cfg iwl5350_agn_cfg = { .led_mode = IWL_LED_BLINK, \ .internal_wimax_coex = true -struct iwl_cfg iwl5150_agn_cfg = { +const struct iwl_cfg iwl5150_agn_cfg = { .name = "Intel(R) WiMAX/WiFi Link 5150 AGN", IWL_DEVICE_5150, .ht_params = &iwl5000_ht_params, }; -struct iwl_cfg iwl5150_abg_cfg = { +const struct iwl_cfg iwl5150_abg_cfg = { .name = "Intel(R) WiMAX/WiFi Link 5150 ABG", IWL_DEVICE_5150, }; diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index 720e8e6e62ae..ef896630625d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -354,40 +354,41 @@ static struct iwl_bt_params iwl6000_bt_params = { .need_temp_offset_calib = true, \ .led_mode = IWL_LED_RF_STATE -struct iwl_cfg iwl6005_2agn_cfg = { +const struct iwl_cfg iwl6005_2agn_cfg = { .name = "Intel(R) Centrino(R) Advanced-N 6205 AGN", IWL_DEVICE_6005, .ht_params = &iwl6000_ht_params, }; -struct iwl_cfg iwl6005_2abg_cfg = { +const struct iwl_cfg iwl6005_2abg_cfg = { .name = "Intel(R) Centrino(R) Advanced-N 6205 ABG", IWL_DEVICE_6005, }; -struct iwl_cfg iwl6005_2bg_cfg = { +const struct iwl_cfg iwl6005_2bg_cfg = { .name = "Intel(R) Centrino(R) Advanced-N 6205 BG", IWL_DEVICE_6005, }; -struct iwl_cfg iwl6005_2agn_sff_cfg = { +const struct iwl_cfg iwl6005_2agn_sff_cfg = { .name = "Intel(R) Centrino(R) Advanced-N 6205S AGN", IWL_DEVICE_6005, .ht_params = &iwl6000_ht_params, }; -struct iwl_cfg iwl6005_2agn_d_cfg = { +const struct iwl_cfg iwl6005_2agn_d_cfg = { .name = "Intel(R) Centrino(R) Advanced-N 6205D AGN", IWL_DEVICE_6005, .ht_params = &iwl6000_ht_params, }; -struct iwl_cfg iwl6005_2agn_mow1_cfg = { +const struct iwl_cfg iwl6005_2agn_mow1_cfg = { .name = "Intel(R) Centrino(R) Advanced-N 6206 AGN", IWL_DEVICE_6005, .ht_params = &iwl6000_ht_params, }; -struct iwl_cfg iwl6005_2agn_mow2_cfg = { + +const struct iwl_cfg iwl6005_2agn_mow2_cfg = { .name = "Intel(R) Centrino(R) Advanced-N 6207 AGN", IWL_DEVICE_6005, .ht_params = &iwl6000_ht_params, @@ -409,53 +410,53 @@ struct iwl_cfg iwl6005_2agn_mow2_cfg = { .led_mode = IWL_LED_RF_STATE, \ .adv_pm = true \ -struct iwl_cfg iwl6030_2agn_cfg = { +const struct iwl_cfg iwl6030_2agn_cfg = { .name = "Intel(R) Centrino(R) Advanced-N 6230 AGN", IWL_DEVICE_6030, .ht_params = &iwl6000_ht_params, }; -struct iwl_cfg iwl6030_2abg_cfg = { +const struct iwl_cfg iwl6030_2abg_cfg = { .name = "Intel(R) Centrino(R) Advanced-N 6230 ABG", IWL_DEVICE_6030, }; -struct iwl_cfg iwl6030_2bgn_cfg = { +const struct iwl_cfg iwl6030_2bgn_cfg = { .name = "Intel(R) Centrino(R) Advanced-N 6230 BGN", IWL_DEVICE_6030, .ht_params = &iwl6000_ht_params, }; -struct iwl_cfg iwl6030_2bg_cfg = { +const struct iwl_cfg iwl6030_2bg_cfg = { .name = "Intel(R) Centrino(R) Advanced-N 6230 BG", IWL_DEVICE_6030, }; -struct iwl_cfg iwl6035_2agn_cfg = { +const struct iwl_cfg iwl6035_2agn_cfg = { .name = "Intel(R) Centrino(R) Advanced-N 6235 AGN", IWL_DEVICE_6030, .ht_params = &iwl6000_ht_params, }; -struct iwl_cfg iwl1030_bgn_cfg = { +const struct iwl_cfg iwl1030_bgn_cfg = { .name = "Intel(R) Centrino(R) Wireless-N 1030 BGN", IWL_DEVICE_6030, .ht_params = &iwl6000_ht_params, }; -struct iwl_cfg iwl1030_bg_cfg = { +const struct iwl_cfg iwl1030_bg_cfg = { .name = "Intel(R) Centrino(R) Wireless-N 1030 BG", IWL_DEVICE_6030, }; -struct iwl_cfg iwl130_bgn_cfg = { +const struct iwl_cfg iwl130_bgn_cfg = { .name = "Intel(R) Centrino(R) Wireless-N 130 BGN", IWL_DEVICE_6030, .ht_params = &iwl6000_ht_params, .rx_with_siso_diversity = true, }; -struct iwl_cfg iwl130_bg_cfg = { +const struct iwl_cfg iwl130_bg_cfg = { .name = "Intel(R) Centrino(R) Wireless-N 130 BG", IWL_DEVICE_6030, .rx_with_siso_diversity = true, @@ -480,18 +481,18 @@ struct iwl_cfg iwl130_bg_cfg = { .pa_type = IWL_PA_INTERNAL, \ .led_mode = IWL_LED_BLINK -struct iwl_cfg iwl6000i_2agn_cfg = { +const struct iwl_cfg iwl6000i_2agn_cfg = { .name = "Intel(R) Centrino(R) Advanced-N 6200 AGN", IWL_DEVICE_6000i, .ht_params = &iwl6000_ht_params, }; -struct iwl_cfg iwl6000i_2abg_cfg = { +const struct iwl_cfg iwl6000i_2abg_cfg = { .name = "Intel(R) Centrino(R) Advanced-N 6200 ABG", IWL_DEVICE_6000i, }; -struct iwl_cfg iwl6000i_2bg_cfg = { +const struct iwl_cfg iwl6000i_2bg_cfg = { .name = "Intel(R) Centrino(R) Advanced-N 6200 BG", IWL_DEVICE_6000i, }; @@ -512,13 +513,13 @@ struct iwl_cfg iwl6000i_2bg_cfg = { .led_mode = IWL_LED_BLINK, \ .internal_wimax_coex = true -struct iwl_cfg iwl6050_2agn_cfg = { +const struct iwl_cfg iwl6050_2agn_cfg = { .name = "Intel(R) Centrino(R) Advanced-N + WiMAX 6250 AGN", IWL_DEVICE_6050, .ht_params = &iwl6000_ht_params, }; -struct iwl_cfg iwl6050_2abg_cfg = { +const struct iwl_cfg iwl6050_2abg_cfg = { .name = "Intel(R) Centrino(R) Advanced-N + WiMAX 6250 ABG", IWL_DEVICE_6050, }; @@ -537,18 +538,18 @@ struct iwl_cfg iwl6050_2abg_cfg = { .led_mode = IWL_LED_BLINK, \ .internal_wimax_coex = true -struct iwl_cfg iwl6150_bgn_cfg = { +const struct iwl_cfg iwl6150_bgn_cfg = { .name = "Intel(R) Centrino(R) Wireless-N + WiMAX 6150 BGN", IWL_DEVICE_6150, .ht_params = &iwl6000_ht_params, }; -struct iwl_cfg iwl6150_bg_cfg = { +const struct iwl_cfg iwl6150_bg_cfg = { .name = "Intel(R) Centrino(R) Wireless-N + WiMAX 6150 BG", IWL_DEVICE_6150, }; -struct iwl_cfg iwl6000_3agn_cfg = { +const struct iwl_cfg iwl6000_3agn_cfg = { .name = "Intel(R) Centrino(R) Ultimate-N 6300 AGN", .fw_name_pre = IWL6000_FW_PRE, .ucode_api_max = IWL6000_UCODE_API_MAX, diff --git a/drivers/net/wireless/iwlwifi/iwl-cfg.h b/drivers/net/wireless/iwlwifi/iwl-cfg.h index 1ad14bbccc99..82152311d73b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-cfg.h +++ b/drivers/net/wireless/iwlwifi/iwl-cfg.h @@ -68,46 +68,46 @@ * This file declares the config structures for all devices. */ -extern struct iwl_cfg iwl5300_agn_cfg; -extern struct iwl_cfg iwl5100_agn_cfg; -extern struct iwl_cfg iwl5350_agn_cfg; -extern struct iwl_cfg iwl5100_bgn_cfg; -extern struct iwl_cfg iwl5100_abg_cfg; -extern struct iwl_cfg iwl5150_agn_cfg; -extern struct iwl_cfg iwl5150_abg_cfg; -extern struct iwl_cfg iwl6005_2agn_cfg; -extern struct iwl_cfg iwl6005_2abg_cfg; -extern struct iwl_cfg iwl6005_2bg_cfg; -extern struct iwl_cfg iwl6005_2agn_sff_cfg; -extern struct iwl_cfg iwl6005_2agn_d_cfg; -extern struct iwl_cfg iwl6005_2agn_mow1_cfg; -extern struct iwl_cfg iwl6005_2agn_mow2_cfg; -extern struct iwl_cfg iwl1030_bgn_cfg; -extern struct iwl_cfg iwl1030_bg_cfg; -extern struct iwl_cfg iwl6030_2agn_cfg; -extern struct iwl_cfg iwl6030_2abg_cfg; -extern struct iwl_cfg iwl6030_2bgn_cfg; -extern struct iwl_cfg iwl6030_2bg_cfg; -extern struct iwl_cfg iwl6000i_2agn_cfg; -extern struct iwl_cfg iwl6000i_2abg_cfg; -extern struct iwl_cfg iwl6000i_2bg_cfg; -extern struct iwl_cfg iwl6000_3agn_cfg; -extern struct iwl_cfg iwl6050_2agn_cfg; -extern struct iwl_cfg iwl6050_2abg_cfg; -extern struct iwl_cfg iwl6150_bgn_cfg; -extern struct iwl_cfg iwl6150_bg_cfg; -extern struct iwl_cfg iwl1000_bgn_cfg; -extern struct iwl_cfg iwl1000_bg_cfg; -extern struct iwl_cfg iwl100_bgn_cfg; -extern struct iwl_cfg iwl100_bg_cfg; -extern struct iwl_cfg iwl130_bgn_cfg; -extern struct iwl_cfg iwl130_bg_cfg; -extern struct iwl_cfg iwl2000_2bgn_cfg; -extern struct iwl_cfg iwl2000_2bgn_d_cfg; -extern struct iwl_cfg iwl2030_2bgn_cfg; -extern struct iwl_cfg iwl6035_2agn_cfg; -extern struct iwl_cfg iwl105_bgn_cfg; -extern struct iwl_cfg iwl105_bgn_d_cfg; -extern struct iwl_cfg iwl135_bgn_cfg; +extern const struct iwl_cfg iwl5300_agn_cfg; +extern const struct iwl_cfg iwl5100_agn_cfg; +extern const struct iwl_cfg iwl5350_agn_cfg; +extern const struct iwl_cfg iwl5100_bgn_cfg; +extern const struct iwl_cfg iwl5100_abg_cfg; +extern const struct iwl_cfg iwl5150_agn_cfg; +extern const struct iwl_cfg iwl5150_abg_cfg; +extern const struct iwl_cfg iwl6005_2agn_cfg; +extern const struct iwl_cfg iwl6005_2abg_cfg; +extern const struct iwl_cfg iwl6005_2bg_cfg; +extern const struct iwl_cfg iwl6005_2agn_sff_cfg; +extern const struct iwl_cfg iwl6005_2agn_d_cfg; +extern const struct iwl_cfg iwl6005_2agn_mow1_cfg; +extern const struct iwl_cfg iwl6005_2agn_mow2_cfg; +extern const struct iwl_cfg iwl1030_bgn_cfg; +extern const struct iwl_cfg iwl1030_bg_cfg; +extern const struct iwl_cfg iwl6030_2agn_cfg; +extern const struct iwl_cfg iwl6030_2abg_cfg; +extern const struct iwl_cfg iwl6030_2bgn_cfg; +extern const struct iwl_cfg iwl6030_2bg_cfg; +extern const struct iwl_cfg iwl6000i_2agn_cfg; +extern const struct iwl_cfg iwl6000i_2abg_cfg; +extern const struct iwl_cfg iwl6000i_2bg_cfg; +extern const struct iwl_cfg iwl6000_3agn_cfg; +extern const struct iwl_cfg iwl6050_2agn_cfg; +extern const struct iwl_cfg iwl6050_2abg_cfg; +extern const struct iwl_cfg iwl6150_bgn_cfg; +extern const struct iwl_cfg iwl6150_bg_cfg; +extern const struct iwl_cfg iwl1000_bgn_cfg; +extern const struct iwl_cfg iwl1000_bg_cfg; +extern const struct iwl_cfg iwl100_bgn_cfg; +extern const struct iwl_cfg iwl100_bg_cfg; +extern const struct iwl_cfg iwl130_bgn_cfg; +extern const struct iwl_cfg iwl130_bg_cfg; +extern const struct iwl_cfg iwl2000_2bgn_cfg; +extern const struct iwl_cfg iwl2000_2bgn_d_cfg; +extern const struct iwl_cfg iwl2030_2bgn_cfg; +extern const struct iwl_cfg iwl6035_2agn_cfg; +extern const struct iwl_cfg iwl105_bgn_cfg; +extern const struct iwl_cfg iwl105_bgn_d_cfg; +extern const struct iwl_cfg iwl135_bgn_cfg; #endif /* __iwl_pci_h__ */ diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.c b/drivers/net/wireless/iwlwifi/iwl-drv.c index 8ff52568cf6e..76fc4407b19e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-drv.c +++ b/drivers/net/wireless/iwlwifi/iwl-drv.c @@ -68,7 +68,7 @@ #include "iwl-op-mode.h" int iwl_drv_start(struct iwl_shared *shrd, - struct iwl_trans *trans, struct iwl_cfg *cfg) + struct iwl_trans *trans, const struct iwl_cfg *cfg) { int ret; diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.h b/drivers/net/wireless/iwlwifi/iwl-drv.h index 90534a23ddc8..3b771c1d9096 100644 --- a/drivers/net/wireless/iwlwifi/iwl-drv.h +++ b/drivers/net/wireless/iwlwifi/iwl-drv.h @@ -105,7 +105,7 @@ * function. */ int iwl_drv_start(struct iwl_shared *shrd, - struct iwl_trans *trans, struct iwl_cfg *cfg); + struct iwl_trans *trans, const struct iwl_cfg *cfg); /** * iwl_drv_stop - stop the drv diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c index 6915b33add36..f965ee333920 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c @@ -512,7 +512,7 @@ static int iwl_find_otp_image(struct iwl_trans *trans, * iwl_get_max_txpower_avg - get the highest tx power from all chains. * find the highest tx power from all chains for the channel */ -static s8 iwl_get_max_txpower_avg(struct iwl_cfg *cfg, +static s8 iwl_get_max_txpower_avg(const struct iwl_cfg *cfg, struct iwl_eeprom_enhanced_txpwr *enhanced_txpower, int element, s8 *max_txpower_in_half_dbm) { diff --git a/drivers/net/wireless/iwlwifi/iwl-pci.c b/drivers/net/wireless/iwlwifi/iwl-pci.c index 06e004157dcc..d109b0f32e33 100644 --- a/drivers/net/wireless/iwlwifi/iwl-pci.c +++ b/drivers/net/wireless/iwlwifi/iwl-pci.c @@ -263,7 +263,7 @@ MODULE_DEVICE_TABLE(pci, iwl_hw_card_ids); static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { - struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data); + const struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data); struct iwl_shared *shrd; struct iwl_trans *iwl_trans; int err; diff --git a/drivers/net/wireless/iwlwifi/iwl-shared.h b/drivers/net/wireless/iwlwifi/iwl-shared.h index 11184f1c4365..4efc9e13f9ec 100644 --- a/drivers/net/wireless/iwlwifi/iwl-shared.h +++ b/drivers/net/wireless/iwlwifi/iwl-shared.h @@ -374,7 +374,7 @@ struct iwl_shared { bool wowlan; u8 valid_contexts; - struct iwl_cfg *cfg; + const struct iwl_cfg *cfg; struct iwl_priv *priv; struct iwl_trans *trans; struct iwl_nic *nic; diff --git a/drivers/net/wireless/iwlwifi/iwl-ucode.c b/drivers/net/wireless/iwlwifi/iwl-ucode.c index b16efc00ba6e..206a61c991dd 100644 --- a/drivers/net/wireless/iwlwifi/iwl-ucode.c +++ b/drivers/net/wireless/iwlwifi/iwl-ucode.c @@ -692,7 +692,7 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context); int __must_check iwl_request_firmware(struct iwl_nic *nic, bool first) { - struct iwl_cfg *cfg = cfg(nic); + const struct iwl_cfg *cfg = cfg(nic); const char *name_pre = cfg->fw_name_pre; char tag[8]; @@ -1045,7 +1045,7 @@ static int iwl_parse_tlv_firmware(struct iwl_nic *nic, static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) { struct iwl_nic *nic = context; - struct iwl_cfg *cfg = cfg(nic); + const struct iwl_cfg *cfg = cfg(nic); struct iwl_fw *fw = &nic->fw; struct iwl_ucode_header *ucode; int err; -- cgit From ce9e80af4f2c5dffb0df470538573d473c91d540 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 5 Mar 2012 11:24:34 -0800 Subject: iwlwifi: reduce IDI code ifdef The code in the two branches of the #ifdef is almost the same so move the common code outside the #ifdef. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-pci.c | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-pci.c b/drivers/net/wireless/iwlwifi/iwl-pci.c index d109b0f32e33..c5e339ee918b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-pci.c +++ b/drivers/net/wireless/iwlwifi/iwl-pci.c @@ -278,17 +278,9 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) #ifdef CONFIG_IWLWIFI_IDI iwl_trans = iwl_trans_idi_alloc(shrd, pdev, ent); - if (iwl_trans == NULL) { - err = -ENOMEM; - goto out_free_bus; - } - - shrd->trans = iwl_trans; - pci_set_drvdata(pdev, iwl_trans); - - err = iwl_drv_start(shrd, iwl_trans, cfg); #else iwl_trans = iwl_trans_pcie_alloc(shrd, pdev, ent); +#endif if (iwl_trans == NULL) { err = -ENOMEM; goto out_free_bus; @@ -298,7 +290,6 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) pci_set_drvdata(pdev, iwl_trans); err = iwl_drv_start(shrd, iwl_trans, cfg); -#endif if (err) goto out_free_trans; -- cgit From 2dd4f9f731f593a52a3fdca20bb32a78d917baf7 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 5 Mar 2012 11:24:35 -0800 Subject: iwlwifi: clean up (wowlan) suspend flow In the WoWLAN suspend flow, instead of accessing registers directly, ask the transport to do the required setup at the end of suspend. If the transport doesn't implement this, don't tell the stack we support WoWLAN. When the device suspends w/o WoWLAN, mac80211 will have stopped it already, which has already called iwl_apm_stop() via stop_hw(). Thus, it isn't necessary to call it again in pcie_suspend and we can simply do nothing there. This unifies the regular and WoWLAN suspend. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-mac80211.c | 5 ++--- drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | 32 +++++++++++---------------- drivers/net/wireless/iwlwifi/iwl-trans.h | 11 +++++++++ 3 files changed, 26 insertions(+), 22 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-mac80211.c b/drivers/net/wireless/iwlwifi/iwl-mac80211.c index 8b26f3217823..8c7ca7318c00 100644 --- a/drivers/net/wireless/iwlwifi/iwl-mac80211.c +++ b/drivers/net/wireless/iwlwifi/iwl-mac80211.c @@ -196,6 +196,7 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv, WIPHY_FLAG_IBSS_RSN; if (nic(priv)->fw.ucode_wowlan.code.len && + trans(priv)->ops->wowlan_suspend && device_can_wakeup(trans(priv)->dev)) { hw->wiphy->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_DISCONNECT | @@ -412,9 +413,7 @@ static int iwlagn_mac_suspend(struct ieee80211_hw *hw, device_set_wakeup_enable(trans(priv)->dev, true); - /* Now let the ucode operate on its own */ - iwl_write32(trans(priv), CSR_UCODE_DRV_GP1_SET, - CSR_UCODE_DRV_GP1_BIT_D3_CFG_COMPLETE); + iwl_trans_wowlan_suspend(trans(priv)); goto out; diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c index f47426a5ef4d..bb8f2fdf1281 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c @@ -1303,6 +1303,17 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans) iwl_write32(trans, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET); } +static void iwl_trans_pcie_wowlan_suspend(struct iwl_trans *trans) +{ + /* let the ucode operate on its own */ + iwl_write32(trans, CSR_UCODE_DRV_GP1_SET, + CSR_UCODE_DRV_GP1_BIT_D3_CFG_COMPLETE); + + iwl_disable_interrupts(trans); + iwl_clear_bit(trans, CSR_GP_CNTRL, + CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); +} + static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, struct iwl_device_cmd *dev_cmd, enum iwl_rxon_context_id ctx, u8 sta_id, u8 tid) @@ -1641,25 +1652,6 @@ static void iwl_trans_pcie_free(struct iwl_trans *trans) #ifdef CONFIG_PM_SLEEP static int iwl_trans_pcie_suspend(struct iwl_trans *trans) { - /* - * This function is called when system goes into suspend state - * mac80211 will call iwlagn_mac_stop() from the mac80211 suspend - * function first but since iwlagn_mac_stop() has no knowledge of - * who the caller is, - * it will not call apm_ops.stop() to stop the DMA operation. - * Calling apm_ops.stop here to make sure we stop the DMA. - * - * But of course ... if we have configured WoWLAN then we did other - * things already :-) - */ - if (!trans->shrd->wowlan) { - iwl_apm_stop(trans); - } else { - iwl_disable_interrupts(trans); - iwl_clear_bit(trans, CSR_GP_CNTRL, - CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); - } - return 0; } @@ -2227,6 +2219,8 @@ const struct iwl_trans_ops trans_ops_pcie = { .start_fw = iwl_trans_pcie_start_fw, .stop_device = iwl_trans_pcie_stop_device, + .wowlan_suspend = iwl_trans_pcie_wowlan_suspend, + .wake_any_queue = iwl_trans_pcie_wake_any_queue, .send_cmd = iwl_trans_pcie_send_cmd, diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index e2f21cfc2cd4..83f04c9d77e5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h @@ -210,6 +210,9 @@ struct iwl_host_cmd { * @wake_any_queue: wake all the queues of a specfic context IWL_RXON_CTX_* * @stop_device:stops the whole device (embedded CPU put to reset) * May sleep + * @wowlan_suspend: put the device into the correct mode for WoWLAN during + * suspend. This is optional, if not implemented WoWLAN will not be + * supported. This callback may sleep. * @send_cmd:send a host command * May sleep only if CMD_SYNC is set * @tx: send an skb @@ -247,6 +250,8 @@ struct iwl_trans_ops { void (*fw_alive)(struct iwl_trans *trans); void (*stop_device)(struct iwl_trans *trans); + void (*wowlan_suspend)(struct iwl_trans *trans); + void (*wake_any_queue)(struct iwl_trans *trans, enum iwl_rxon_context_id ctx, const char *msg); @@ -396,6 +401,12 @@ static inline void iwl_trans_stop_device(struct iwl_trans *trans) trans->state = IWL_TRANS_NO_FW; } +static inline void iwl_trans_wowlan_suspend(struct iwl_trans *trans) +{ + might_sleep(); + trans->ops->wowlan_suspend(trans); +} + static inline void iwl_trans_wake_any_queue(struct iwl_trans *trans, enum iwl_rxon_context_id ctx, const char *msg) -- cgit From 15b86bff995525a38126eb44a951765a57ea2f4c Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 5 Mar 2012 11:24:36 -0800 Subject: iwlwifi: move wowlan bool into priv With the new WoWLAN flow into the transport there no longer is a need for this to be shared, so move it into priv. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 2 +- drivers/net/wireless/iwlwifi/iwl-agn-sta.c | 2 +- drivers/net/wireless/iwlwifi/iwl-agn-tx.c | 2 +- drivers/net/wireless/iwlwifi/iwl-agn.c | 4 ++-- drivers/net/wireless/iwlwifi/iwl-dev.h | 2 ++ drivers/net/wireless/iwlwifi/iwl-mac80211.c | 4 ++-- drivers/net/wireless/iwlwifi/iwl-power.c | 2 +- drivers/net/wireless/iwlwifi/iwl-shared.h | 1 - 8 files changed, 10 insertions(+), 9 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index 79ac7cb1701b..626b0d184729 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -1193,7 +1193,7 @@ int iwlagn_suspend(struct iwl_priv *priv, iwl_trans_stop_device(trans(priv)); - priv->shrd->wowlan = true; + priv->wowlan = true; ret = iwl_load_ucode_wait_alive(trans(priv), IWL_UCODE_WOWLAN); if (ret) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c index 222a8f46365f..7a713ba9bdee 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c @@ -586,7 +586,7 @@ void iwl_restore_stations(struct iwl_priv *priv, struct iwl_rxon_context *ctx) sizeof(struct iwl_addsta_cmd)); send_lq = false; if (priv->stations[i].lq) { - if (priv->shrd->wowlan) + if (priv->wowlan) iwl_sta_fill_lq(priv, ctx, i, &lq); else memcpy(&lq, priv->stations[i].lq, diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c index 2b722ccb730a..e5ebc36a14c8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c @@ -126,7 +126,7 @@ static void iwlagn_tx_cmd_build_rate(struct iwl_priv *priv, u8 data_retry_limit; u8 rate_plcp; - if (priv->shrd->wowlan) { + if (priv->wowlan) { rts_retry_limit = IWLAGN_LOW_RETRY_LIMIT; data_retry_limit = IWLAGN_LOW_RETRY_LIMIT; } else { diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 6cec7e63c171..6dd4faead7cd 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -701,7 +701,7 @@ int iwl_alive_start(struct iwl_priv *priv) /* Configure Tx antenna selection based on H/W config */ iwlagn_send_tx_ant_config(priv, hw_params(priv).valid_tx_ant); - if (iwl_is_associated_ctx(ctx) && !priv->shrd->wowlan) { + if (iwl_is_associated_ctx(ctx) && !priv->wowlan) { struct iwl_rxon_cmd *active_rxon = (struct iwl_rxon_cmd *)&ctx->active; /* apply any changes in staging */ @@ -716,7 +716,7 @@ int iwl_alive_start(struct iwl_priv *priv) iwlagn_set_rxon_chain(priv, ctx); } - if (!priv->shrd->wowlan) { + if (!priv->wowlan) { /* WoWLAN ucode will not reply in the same way, skip it */ iwl_reset_run_time_calib(priv); } diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 9ea9002cc839..ef71463e84ea 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -787,6 +787,8 @@ struct iwl_priv { bool new_scan_threshold_behaviour; + bool wowlan; + /* EEPROM MAC addresses */ struct mac_address addresses[2]; diff --git a/drivers/net/wireless/iwlwifi/iwl-mac80211.c b/drivers/net/wireless/iwlwifi/iwl-mac80211.c index 8c7ca7318c00..8160f615f71a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-mac80211.c +++ b/drivers/net/wireless/iwlwifi/iwl-mac80211.c @@ -418,7 +418,7 @@ static int iwlagn_mac_suspend(struct ieee80211_hw *hw, goto out; error: - priv->shrd->wowlan = false; + priv->wowlan = false; iwlagn_prepare_restart(priv); ieee80211_restart_hw(priv->hw); out: @@ -474,7 +474,7 @@ static int iwlagn_mac_resume(struct ieee80211_hw *hw) /* we'll clear ctx->vif during iwlagn_prepare_restart() */ vif = ctx->vif; - priv->shrd->wowlan = false; + priv->wowlan = false; device_set_wakeup_enable(trans(priv)->dev, false); diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c index fd008c4e41fd..1ef3c4da1605 100644 --- a/drivers/net/wireless/iwlwifi/iwl-power.c +++ b/drivers/net/wireless/iwlwifi/iwl-power.c @@ -348,7 +348,7 @@ static void iwl_power_build_cmd(struct iwl_priv *priv, dtimper = priv->hw->conf.ps_dtim_period ?: 1; - if (priv->shrd->wowlan) + if (priv->wowlan) iwl_static_sleep_cmd(priv, cmd, IWL_POWER_INDEX_5, dtimper); else if (!cfg(priv)->base_params->no_idle_support && priv->hw->conf.flags & IEEE80211_CONF_IDLE) diff --git a/drivers/net/wireless/iwlwifi/iwl-shared.h b/drivers/net/wireless/iwlwifi/iwl-shared.h index 4efc9e13f9ec..a7dbcabafc96 100644 --- a/drivers/net/wireless/iwlwifi/iwl-shared.h +++ b/drivers/net/wireless/iwlwifi/iwl-shared.h @@ -371,7 +371,6 @@ struct iwl_shared { u8 ucode_owner; u8 cmd_queue; unsigned long status; - bool wowlan; u8 valid_contexts; const struct iwl_cfg *cfg; -- cgit From 2c6ab7ff8fa9af22a2a616656da6e5a0567da285 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 5 Mar 2012 11:24:37 -0800 Subject: iwlwifi: use ieee80211_tx_status We currently use the _irqsafe version, but that isn't recommended together with ieee80211_rx() as it can cause races. If the device reports a TX-status and RX in that order then with the current combination mac80211 might process them in the other order, which can cause issues with powersaving clients. Use ieee80211_tx_status() to avoid this race. Since we don't want to call it with locks held, process the frame queues later -- this is fine as they are on the stack. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-tx.c | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c index e5ebc36a14c8..1914bee1891e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c @@ -1007,6 +1007,8 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb, if (is_agg) iwl_rx_reply_tx_agg(priv, tx_resp); + __skb_queue_head_init(&skbs); + if (tx_resp->frame_count == 1) { u16 next_reclaimed = le16_to_cpu(tx_resp->seq_ctl); next_reclaimed = SEQ_TO_SN(next_reclaimed + 0x10); @@ -1026,8 +1028,6 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb, next_reclaimed = ssn; } - __skb_queue_head_init(&skbs); - if (tid != IWL_TID_NON_QOS) { priv->tid_data[sta_id][tid].next_reclaimed = next_reclaimed; @@ -1040,8 +1040,9 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb, ssn, status, &skbs)); iwlagn_check_ratid_empty(priv, sta_id, tid); freed = 0; - while (!skb_queue_empty(&skbs)) { - skb = __skb_dequeue(&skbs); + + /* process frames */ + skb_queue_walk(&skbs, skb) { hdr = (struct ieee80211_hdr *)skb->data; if (!ieee80211_is_data_qos(hdr->frame_control)) @@ -1083,8 +1084,6 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb, if (!is_agg) iwlagn_non_agg_tx_status(priv, ctx, hdr->addr1); - ieee80211_tx_status_irqsafe(priv->hw, skb); - freed++; } @@ -1093,6 +1092,12 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb, iwl_check_abort_status(priv, tx_resp->frame_count, status); spin_unlock(&priv->sta_lock); + + while (!skb_queue_empty(&skbs)) { + skb = __skb_dequeue(&skbs); + ieee80211_tx_status(priv->hw, skb); + } + return 0; } @@ -1186,9 +1191,8 @@ int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv, iwlagn_check_ratid_empty(priv, sta_id, tid); freed = 0; - while (!skb_queue_empty(&reclaimed_skbs)) { - skb = __skb_dequeue(&reclaimed_skbs); + skb_queue_walk(&reclaimed_skbs, skb) { hdr = (struct ieee80211_hdr *)skb->data; if (ieee80211_is_data_qos(hdr->frame_control)) @@ -1211,10 +1215,14 @@ int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv, iwlagn_hwrate_to_tx_control(priv, agg->rate_n_flags, info); } - - ieee80211_tx_status_irqsafe(priv->hw, skb); } spin_unlock(&priv->sta_lock); + + while (!skb_queue_empty(&reclaimed_skbs)) { + skb = __skb_dequeue(&reclaimed_skbs); + ieee80211_tx_status(priv->hw, skb); + } + return 0; } -- cgit From 65b94a4abfd55b3304be25ffed9832455d41e1dd Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 5 Mar 2012 11:24:38 -0800 Subject: iwlwifi: pass response packet directly When CMD_WANT_SKB is set for a (synchronous) command, the response is passed back to the caller which is then responsible for freeing it. Make this more abstract with real API, passing directly the response packet in the new cmd.resp_pkt member and also introduce iwl_free_resp() to free the pages -- this way the upper layers don't have to directly touch the page implementation. NOTE: This breaks IDI -- the new code isn't reflected there yet! Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-sta.c | 6 +++--- drivers/net/wireless/iwlwifi/iwl-scan.c | 4 ++-- drivers/net/wireless/iwlwifi/iwl-shared.h | 5 ----- drivers/net/wireless/iwlwifi/iwl-testmode.c | 4 ++-- drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c | 16 ++++++++++------ drivers/net/wireless/iwlwifi/iwl-trans.h | 13 +++++++++++-- 6 files changed, 28 insertions(+), 20 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c index 7a713ba9bdee..9ef8da47ad04 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c @@ -160,7 +160,7 @@ int iwl_send_add_sta(struct iwl_priv *priv, /*else the command was successfully sent in SYNC mode, need to free * the reply page */ - iwl_free_pages(priv->shrd, cmd.reply_page); + iwl_free_resp(&cmd); if (cmd.handler_status) IWL_ERR(priv, "%s - error in the CMD response %d", __func__, @@ -415,7 +415,7 @@ static int iwl_send_remove_station(struct iwl_priv *priv, if (ret) return ret; - pkt = (struct iwl_rx_packet *)cmd.reply_page; + pkt = cmd.resp_pkt; if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) { IWL_ERR(priv, "Bad return from REPLY_REMOVE_STA (0x%08X)\n", pkt->hdr.flags); @@ -438,7 +438,7 @@ static int iwl_send_remove_station(struct iwl_priv *priv, break; } } - iwl_free_pages(priv->shrd, cmd.reply_page); + iwl_free_resp(&cmd); return ret; } diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index 766572b9ac89..c0fc3687a2fd 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c @@ -76,7 +76,7 @@ static int iwl_send_scan_abort(struct iwl_priv *priv) if (ret) return ret; - pkt = (struct iwl_rx_packet *)cmd.reply_page; + pkt = cmd.resp_pkt; if (pkt->u.status != CAN_ABORT_STATUS) { /* The scan abort will return 1 for success or * 2 for "failure". A failure condition can be @@ -88,7 +88,7 @@ static int iwl_send_scan_abort(struct iwl_priv *priv) ret = -EIO; } - iwl_free_pages(priv->shrd, cmd.reply_page); + iwl_free_resp(&cmd); return ret; } diff --git a/drivers/net/wireless/iwlwifi/iwl-shared.h b/drivers/net/wireless/iwlwifi/iwl-shared.h index a7dbcabafc96..53244d88f1ab 100644 --- a/drivers/net/wireless/iwlwifi/iwl-shared.h +++ b/drivers/net/wireless/iwlwifi/iwl-shared.h @@ -413,11 +413,6 @@ static inline bool iwl_have_debug_level(u32 level) return iwlagn_mod_params.debug_level & level; } -static inline void iwl_free_pages(struct iwl_shared *shrd, unsigned long page) -{ - free_pages(page, shrd->hw_params.rx_page_order); -} - /** * iwl_queue_inc_wrap - increment queue index, wrap back to beginning * @index -- current index diff --git a/drivers/net/wireless/iwlwifi/iwl-testmode.c b/drivers/net/wireless/iwlwifi/iwl-testmode.c index 23eea06a74ad..cc1f3e990ad6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-testmode.c +++ b/drivers/net/wireless/iwlwifi/iwl-testmode.c @@ -292,7 +292,7 @@ static int iwl_testmode_ucode(struct ieee80211_hw *hw, struct nlattr **tb) return ret; /* Handling return of SKB to the user */ - pkt = (struct iwl_rx_packet *)cmd.reply_page; + pkt = cmd.resp_pkt; if (!pkt) { IWL_ERR(priv, "HCMD received a null response packet\n"); return ret; @@ -309,7 +309,7 @@ static int iwl_testmode_ucode(struct ieee80211_hw *hw, struct nlattr **tb) /* The reply is in a page, that we cannot send to user space. */ memcpy(reply_buf, &(pkt->hdr), reply_len); - iwl_free_pages(priv->shrd, cmd.reply_page); + iwl_free_resp(&cmd); NLA_PUT_U32(skb, IWL_TM_ATTR_COMMAND, IWL_TM_CMD_DEV2APP_UCODE_RX_PKT); NLA_PUT(skb, IWL_TM_ATTR_UCODE_RX_PKT, reply_len, reply_buf); diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c index de2a0d91d658..771fae2f9fd8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c @@ -879,9 +879,13 @@ void iwl_tx_cmd_complete(struct iwl_trans *trans, struct iwl_rx_mem_buffer *rxb, /* Input error checking is done when commands are added to queue. */ if (meta->flags & CMD_WANT_SKB) { - meta->source->reply_page = (unsigned long)rxb_addr(rxb); - meta->source->handler_status = handler_status; + struct page *p = rxb->page; + rxb->page = NULL; + meta->source->resp_pkt = pkt; + meta->source->_rx_page_addr = (unsigned long)page_address(p); + meta->source->_rx_page_order = hw_params(trans).rx_page_order; + meta->source->handler_status = handler_status; } iwl_hcmd_queue_reclaim(trans, txq_id, index); @@ -985,7 +989,7 @@ static int iwl_send_cmd_sync(struct iwl_trans *trans, struct iwl_host_cmd *cmd) } } - if ((cmd->flags & CMD_WANT_SKB) && !cmd->reply_page) { + if ((cmd->flags & CMD_WANT_SKB) && !cmd->resp_pkt) { IWL_ERR(trans, "Error: Response NULL in '%s'\n", get_cmd_string(cmd->id)); ret = -EIO; @@ -1006,9 +1010,9 @@ cancel: ~CMD_WANT_SKB; } - if (cmd->reply_page) { - iwl_free_pages(trans->shrd, cmd->reply_page); - cmd->reply_page = 0; + if (cmd->resp_pkt) { + iwl_free_resp(cmd); + cmd->resp_pkt = NULL; } return ret; diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index 83f04c9d77e5..e8ab8d8ca484 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h @@ -173,7 +173,9 @@ enum iwl_hcmd_dataflag { * struct iwl_host_cmd - Host command to the uCode * * @data: array of chunks that composes the data of the host command - * @reply_page: pointer to the page that holds the response to the host command + * @resp_pkt: response packet, if %CMD_WANT_SKB was set + * @_rx_page_order: (internally used to free response packet) + * @_rx_page_addr: (internally used to free response packet) * @handler_status: return value of the handler of the command * (put in setup_rx_handlers) - valid for SYNC mode only * @flags: can be CMD_* @@ -183,7 +185,9 @@ enum iwl_hcmd_dataflag { */ struct iwl_host_cmd { const void *data[IWL_MAX_CMD_TFDS]; - unsigned long reply_page; + struct iwl_rx_packet *resp_pkt; + unsigned long _rx_page_addr; + u32 _rx_page_order; int handler_status; u32 flags; @@ -192,6 +196,11 @@ struct iwl_host_cmd { u8 id; }; +static inline void iwl_free_resp(struct iwl_host_cmd *cmd) +{ + free_pages(cmd->_rx_page_addr, cmd->_rx_page_order); +} + /** * struct iwl_trans_ops - transport specific operations * -- cgit From 48a2d66f58d2bf1818acf5ff7ed9897a9977a96e Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 5 Mar 2012 11:24:39 -0800 Subject: iwlwifi: don't pass iwl_rx_mem_buffer to upper layers struct iwl_rx_mem_buffer implementation details (DMA address, list pointers) that the upper layers don't need. Introduce iwl_rx_cmd_buffer that is passed upstream and only contains the needed data (the page). Additionally, access this data only via accessor functions, allowing us to change the implementation in the future. These accessors are rxb_addr() (as before) and rxb_steal_page() to take ownership of the data. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 2 +- drivers/net/wireless/iwlwifi/iwl-agn-rx.c | 41 ++++++++++++----------- drivers/net/wireless/iwlwifi/iwl-agn-sta.c | 2 +- drivers/net/wireless/iwlwifi/iwl-agn-tx.c | 4 +-- drivers/net/wireless/iwlwifi/iwl-agn.h | 12 +++---- drivers/net/wireless/iwlwifi/iwl-dev.h | 4 +-- drivers/net/wireless/iwlwifi/iwl-op-mode.h | 6 ++-- drivers/net/wireless/iwlwifi/iwl-scan.c | 8 ++--- drivers/net/wireless/iwlwifi/iwl-shared.h | 18 +++++++--- drivers/net/wireless/iwlwifi/iwl-testmode.c | 4 +-- drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h | 8 ++++- drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c | 21 ++++++++---- drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c | 5 ++- drivers/net/wireless/iwlwifi/iwl-ucode.c | 2 +- 14 files changed, 80 insertions(+), 57 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index 626b0d184729..e96af5133e06 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -707,7 +707,7 @@ static void iwlagn_set_kill_msk(struct iwl_priv *priv, } int iwlagn_bt_coex_profile_notif(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb, + struct iwl_rx_cmd_buffer *rxb, struct iwl_device_cmd *cmd) { struct iwl_rx_packet *pkt = rxb_addr(rxb); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c index bc21586aed63..8e025e0df50d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c @@ -131,7 +131,7 @@ const char *get_cmd_string(u8 cmd) ******************************************************************************/ static int iwlagn_rx_reply_error(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb, + struct iwl_rx_cmd_buffer *rxb, struct iwl_device_cmd *cmd) { struct iwl_rx_packet *pkt = rxb_addr(rxb); @@ -146,7 +146,7 @@ static int iwlagn_rx_reply_error(struct iwl_priv *priv, return 0; } -static int iwlagn_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb, +static int iwlagn_rx_csa(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb, struct iwl_device_cmd *cmd) { struct iwl_rx_packet *pkt = rxb_addr(rxb); @@ -177,7 +177,7 @@ static int iwlagn_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb, static int iwlagn_rx_spectrum_measure_notif(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb, + struct iwl_rx_cmd_buffer *rxb, struct iwl_device_cmd *cmd) { struct iwl_rx_packet *pkt = rxb_addr(rxb); @@ -195,7 +195,7 @@ static int iwlagn_rx_spectrum_measure_notif(struct iwl_priv *priv, } static int iwlagn_rx_pm_sleep_notif(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb, + struct iwl_rx_cmd_buffer *rxb, struct iwl_device_cmd *cmd) { #ifdef CONFIG_IWLWIFI_DEBUG @@ -208,7 +208,7 @@ static int iwlagn_rx_pm_sleep_notif(struct iwl_priv *priv, } static int iwlagn_rx_pm_debug_statistics_notif(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb, + struct iwl_rx_cmd_buffer *rxb, struct iwl_device_cmd *cmd) { struct iwl_rx_packet *pkt = rxb_addr(rxb); @@ -222,7 +222,7 @@ static int iwlagn_rx_pm_debug_statistics_notif(struct iwl_priv *priv, } static int iwlagn_rx_beacon_notif(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb, + struct iwl_rx_cmd_buffer *rxb, struct iwl_device_cmd *cmd) { struct iwl_rx_packet *pkt = rxb_addr(rxb); @@ -489,7 +489,7 @@ iwlagn_accumulative_statistics(struct iwl_priv *priv, #endif static int iwlagn_rx_statistics(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb, + struct iwl_rx_cmd_buffer *rxb, struct iwl_device_cmd *cmd) { unsigned long stamp = jiffies; @@ -597,7 +597,7 @@ static int iwlagn_rx_statistics(struct iwl_priv *priv, } static int iwlagn_rx_reply_statistics(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb, + struct iwl_rx_cmd_buffer *rxb, struct iwl_device_cmd *cmd) { struct iwl_rx_packet *pkt = rxb_addr(rxb); @@ -620,7 +620,7 @@ static int iwlagn_rx_reply_statistics(struct iwl_priv *priv, /* Handle notification from uCode that card's power state is changing * due to software, hardware, or critical temperature RFKILL */ static int iwlagn_rx_card_state_notif(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb, + struct iwl_rx_cmd_buffer *rxb, struct iwl_device_cmd *cmd) { struct iwl_rx_packet *pkt = rxb_addr(rxb); @@ -673,7 +673,7 @@ static int iwlagn_rx_card_state_notif(struct iwl_priv *priv, } static int iwlagn_rx_missed_beacon_notif(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb, + struct iwl_rx_cmd_buffer *rxb, struct iwl_device_cmd *cmd) { @@ -698,7 +698,7 @@ static int iwlagn_rx_missed_beacon_notif(struct iwl_priv *priv, /* Cache phy data (Rx signal strength, etc) for HT frame (REPLY_RX_PHY_CMD). * This will be used later in iwl_rx_reply_rx() for REPLY_RX_MPDU_CMD. */ static int iwlagn_rx_reply_rx_phy(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb, + struct iwl_rx_cmd_buffer *rxb, struct iwl_device_cmd *cmd) { struct iwl_rx_packet *pkt = rxb_addr(rxb); @@ -765,12 +765,14 @@ static void iwlagn_pass_packet_to_mac80211(struct iwl_priv *priv, struct ieee80211_hdr *hdr, u16 len, u32 ampdu_status, - struct iwl_rx_mem_buffer *rxb, + struct iwl_rx_cmd_buffer *rxb, struct ieee80211_rx_status *stats) { struct sk_buff *skb; __le16 fc = hdr->frame_control; struct iwl_rxon_context *ctx; + struct page *p; + int offset; /* We only process data packets if the interface is open */ if (unlikely(!priv->is_open)) { @@ -790,7 +792,9 @@ static void iwlagn_pass_packet_to_mac80211(struct iwl_priv *priv, return; } - skb_add_rx_frag(skb, 0, rxb->page, (void *)hdr - rxb_addr(rxb), len); + offset = (void *)hdr - rxb_addr(rxb); + p = rxb_steal_page(rxb); + skb_add_rx_frag(skb, 0, p, offset, len); iwl_update_stats(priv, false, fc, len); @@ -817,7 +821,6 @@ static void iwlagn_pass_packet_to_mac80211(struct iwl_priv *priv, memcpy(IEEE80211_SKB_RXCB(skb), stats, sizeof(*stats)); ieee80211_rx(priv->hw, skb); - rxb->page = NULL; } static u32 iwlagn_translate_rx_status(struct iwl_priv *priv, u32 decrypt_in) @@ -923,7 +926,7 @@ static int iwlagn_calc_rssi(struct iwl_priv *priv, /* Called for REPLY_RX (legacy ABG frames), or * REPLY_RX_MPDU_CMD (HT high-throughput N frames). */ static int iwlagn_rx_reply_rx(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb, + struct iwl_rx_cmd_buffer *rxb, struct iwl_device_cmd *cmd) { struct ieee80211_hdr *header; @@ -1043,7 +1046,7 @@ static int iwlagn_rx_reply_rx(struct iwl_priv *priv, } static int iwlagn_rx_noa_notification(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb, + struct iwl_rx_cmd_buffer *rxb, struct iwl_device_cmd *cmd) { struct iwl_wipan_noa_data *new_data, *old_data; @@ -1094,7 +1097,7 @@ static int iwlagn_rx_noa_notification(struct iwl_priv *priv, */ void iwl_setup_rx_handlers(struct iwl_priv *priv) { - int (**handlers)(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb, + int (**handlers)(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb, struct iwl_device_cmd *cmd); handlers = priv->rx_handlers; @@ -1149,8 +1152,8 @@ void iwl_setup_rx_handlers(struct iwl_priv *priv) } -int iwl_rx_dispatch(struct iwl_op_mode *op_mode, struct iwl_rx_mem_buffer *rxb, - struct iwl_device_cmd *cmd) +int iwl_rx_dispatch(struct iwl_op_mode *op_mode, struct iwl_rx_cmd_buffer *rxb, + struct iwl_device_cmd *cmd) { struct iwl_rx_packet *pkt = rxb_addr(rxb); struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c index 9ef8da47ad04..736f8dc404df 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c @@ -123,7 +123,7 @@ static int iwl_process_add_sta_resp(struct iwl_priv *priv, return ret; } -int iwl_add_sta_callback(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb, +int iwl_add_sta_callback(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb, struct iwl_device_cmd *cmd) { struct iwl_rx_packet *pkt = rxb_addr(rxb); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c index 1914bee1891e..dd28785e1a5c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c @@ -977,7 +977,7 @@ static void iwl_check_abort_status(struct iwl_priv *priv, } } -int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb, +int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb, struct iwl_device_cmd *cmd) { struct iwl_rx_packet *pkt = rxb_addr(rxb); @@ -1108,7 +1108,7 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb, * of frames sent via aggregation. */ int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb, + struct iwl_rx_cmd_buffer *rxb, struct iwl_device_cmd *cmd) { struct iwl_rx_packet *pkt = rxb_addr(rxb); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index a142a197b2e4..a9c018a7b8ba 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h @@ -82,7 +82,7 @@ void iwl_cancel_deferred_work(struct iwl_priv *priv); void iwlagn_prepare_restart(struct iwl_priv *priv); void iwl_free_skb(struct iwl_op_mode *op_mode, struct sk_buff *skb); int __must_check iwl_rx_dispatch(struct iwl_op_mode *op_mode, - struct iwl_rx_mem_buffer *rxb, + struct iwl_rx_cmd_buffer *rxb, struct iwl_device_cmd *cmd); void iwl_stop_sw_queue(struct iwl_op_mode *op_mode, u8 ac); void iwl_wake_sw_queue(struct iwl_op_mode *op_mode, u8 ac); @@ -110,7 +110,7 @@ void iwlagn_config_ht40(struct ieee80211_conf *conf, /* uCode */ int iwlagn_rx_calib_result(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb, + struct iwl_rx_cmd_buffer *rxb, struct iwl_device_cmd *cmd); void iwl_init_context(struct iwl_priv *priv, u32 ucode_flags); @@ -142,9 +142,9 @@ int iwlagn_tx_agg_oper(struct iwl_priv *priv, struct ieee80211_vif *vif, int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif, struct ieee80211_sta *sta, u16 tid); int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb, + struct iwl_rx_cmd_buffer *rxb, struct iwl_device_cmd *cmd); -int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb, +int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb, struct iwl_device_cmd *cmd); static inline u32 iwl_tx_status_to_mac80211(u32 status) @@ -179,7 +179,7 @@ void iwlagn_disable_roc(struct iwl_priv *priv); /* bt coex */ void iwlagn_send_advance_bt_config(struct iwl_priv *priv); int iwlagn_bt_coex_profile_notif(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb, + struct iwl_rx_cmd_buffer *rxb, struct iwl_device_cmd *cmd); void iwlagn_bt_rx_handler_setup(struct iwl_priv *priv); void iwlagn_bt_setup_deferred_work(struct iwl_priv *priv); @@ -227,7 +227,7 @@ void iwl_sta_fill_lq(struct iwl_priv *priv, struct iwl_rxon_context *ctx, u8 sta_id, struct iwl_link_quality_cmd *link_cmd); int iwl_send_lq_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx, struct iwl_link_quality_cmd *lq, u8 flags, bool init); -int iwl_add_sta_callback(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb, +int iwl_add_sta_callback(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb, struct iwl_device_cmd *cmd); diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index ef71463e84ea..5957209b2f37 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -729,9 +729,9 @@ struct iwl_priv { enum ieee80211_band band; void (*pre_rx_handler)(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb); + struct iwl_rx_cmd_buffer *rxb); int (*rx_handlers[REPLY_MAX])(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb, + struct iwl_rx_cmd_buffer *rxb, struct iwl_device_cmd *cmd); struct ieee80211_supported_band bands[IEEE80211_NUM_BANDS]; diff --git a/drivers/net/wireless/iwlwifi/iwl-op-mode.h b/drivers/net/wireless/iwlwifi/iwl-op-mode.h index d4fc9be2d2f3..41e58a136715 100644 --- a/drivers/net/wireless/iwlwifi/iwl-op-mode.h +++ b/drivers/net/wireless/iwlwifi/iwl-op-mode.h @@ -67,7 +67,7 @@ struct iwl_op_mode; struct iwl_trans; struct sk_buff; struct iwl_device_cmd; -struct iwl_rx_mem_buffer; +struct iwl_rx_cmd_buffer; /** * DOC: Operational mode - what is it ? @@ -125,7 +125,7 @@ struct iwl_rx_mem_buffer; struct iwl_op_mode_ops { struct iwl_op_mode *(*start)(struct iwl_trans *trans); void (*stop)(struct iwl_op_mode *op_mode); - int (*rx)(struct iwl_op_mode *op_mode, struct iwl_rx_mem_buffer *rxb, + int (*rx)(struct iwl_op_mode *op_mode, struct iwl_rx_cmd_buffer *rxb, struct iwl_device_cmd *cmd); void (*queue_full)(struct iwl_op_mode *op_mode, u8 ac); void (*queue_not_full)(struct iwl_op_mode *op_mode, u8 ac); @@ -156,7 +156,7 @@ static inline void iwl_op_mode_stop(struct iwl_op_mode *op_mode) } static inline int iwl_op_mode_rx(struct iwl_op_mode *op_mode, - struct iwl_rx_mem_buffer *rxb, + struct iwl_rx_cmd_buffer *rxb, struct iwl_device_cmd *cmd) { return op_mode->ops->rx(op_mode, rxb, cmd); diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index c0fc3687a2fd..28899dabe6fb 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c @@ -260,7 +260,7 @@ void iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms) /* Service response to REPLY_SCAN_CMD (0x80) */ static int iwl_rx_reply_scan(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb, + struct iwl_rx_cmd_buffer *rxb, struct iwl_device_cmd *cmd) { #ifdef CONFIG_IWLWIFI_DEBUG @@ -275,7 +275,7 @@ static int iwl_rx_reply_scan(struct iwl_priv *priv, /* Service SCAN_START_NOTIFICATION (0x82) */ static int iwl_rx_scan_start_notif(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb, + struct iwl_rx_cmd_buffer *rxb, struct iwl_device_cmd *cmd) { struct iwl_rx_packet *pkt = rxb_addr(rxb); @@ -302,7 +302,7 @@ static int iwl_rx_scan_start_notif(struct iwl_priv *priv, /* Service SCAN_RESULTS_NOTIFICATION (0x83) */ static int iwl_rx_scan_results_notif(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb, + struct iwl_rx_cmd_buffer *rxb, struct iwl_device_cmd *cmd) { #ifdef CONFIG_IWLWIFI_DEBUG @@ -328,7 +328,7 @@ static int iwl_rx_scan_results_notif(struct iwl_priv *priv, /* Service SCAN_COMPLETE_NOTIFICATION (0x84) */ static int iwl_rx_scan_complete_notif(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb, + struct iwl_rx_cmd_buffer *rxb, struct iwl_device_cmd *cmd) { struct iwl_rx_packet *pkt = rxb_addr(rxb); diff --git a/drivers/net/wireless/iwlwifi/iwl-shared.h b/drivers/net/wireless/iwlwifi/iwl-shared.h index 53244d88f1ab..ed1811d43550 100644 --- a/drivers/net/wireless/iwlwifi/iwl-shared.h +++ b/drivers/net/wireless/iwlwifi/iwl-shared.h @@ -433,13 +433,21 @@ static inline int iwl_queue_dec_wrap(int index, int n_bd) return --index & (n_bd - 1); } -struct iwl_rx_mem_buffer { - dma_addr_t page_dma; - struct page *page; - struct list_head list; +struct iwl_rx_cmd_buffer { + struct page *_page; }; -#define rxb_addr(r) page_address(r->page) +static inline void *rxb_addr(struct iwl_rx_cmd_buffer *r) +{ + return page_address(r->_page); +} + +static inline struct page *rxb_steal_page(struct iwl_rx_cmd_buffer *r) +{ + struct page *p = r->_page; + r->_page = NULL; + return p; +} /* * mac80211 queues, ACs, hardware queues, FIFOs. diff --git a/drivers/net/wireless/iwlwifi/iwl-testmode.c b/drivers/net/wireless/iwlwifi/iwl-testmode.c index cc1f3e990ad6..b24b166a9482 100644 --- a/drivers/net/wireless/iwlwifi/iwl-testmode.c +++ b/drivers/net/wireless/iwlwifi/iwl-testmode.c @@ -131,7 +131,7 @@ struct nla_policy iwl_testmode_gnl_msg_policy[IWL_TM_ATTR_MAX] = { * See the struct iwl_rx_packet in iwl-commands.h for the format of the * received events from the device */ -static inline int get_event_length(struct iwl_rx_mem_buffer *rxb) +static inline int get_event_length(struct iwl_rx_cmd_buffer *rxb) { struct iwl_rx_packet *pkt = rxb_addr(rxb); if (pkt) @@ -162,7 +162,7 @@ static inline int get_event_length(struct iwl_rx_mem_buffer *rxb) */ static void iwl_testmode_ucode_rx_pkt(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb) + struct iwl_rx_cmd_buffer *rxb) { struct ieee80211_hw *hw = priv->hw; struct sk_buff *skb; diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h index b1029468ccbd..632d4099900e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h @@ -49,6 +49,12 @@ struct iwl_host_cmd; /*This file includes the declaration that are internal to the * trans_pcie layer */ +struct iwl_rx_mem_buffer { + dma_addr_t page_dma; + struct page *page; + struct list_head list; +}; + /** * struct isr_statistics - interrupt statistics * @@ -287,7 +293,7 @@ int iwlagn_txq_attach_buf_to_tfd(struct iwl_trans *trans, int iwl_queue_init(struct iwl_queue *q, int count, int slots_num, u32 id); int iwl_trans_pcie_send_cmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd); void iwl_tx_cmd_complete(struct iwl_trans *trans, - struct iwl_rx_mem_buffer *rxb, int handler_status); + struct iwl_rx_cmd_buffer *rxb, int handler_status); void iwl_trans_txq_update_byte_cnt_tbl(struct iwl_trans *trans, struct iwl_tx_queue *txq, u16 byte_cnt); diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c index 6495945637b9..68e89be60bef 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c @@ -367,8 +367,6 @@ void iwl_bg_rx_replenish(struct work_struct *data) */ static void iwl_rx_handle(struct iwl_trans *trans) { - struct iwl_rx_mem_buffer *rxb; - struct iwl_rx_packet *pkt; struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); struct iwl_rx_queue *rxq = &trans_pcie->rxq; @@ -402,6 +400,9 @@ static void iwl_rx_handle(struct iwl_trans *trans) while (i != r) { int len, err; u16 sequence; + struct iwl_rx_mem_buffer *rxb; + struct iwl_rx_cmd_buffer rxcb; + struct iwl_rx_packet *pkt; rxb = rxq->queue[i]; @@ -418,7 +419,9 @@ static void iwl_rx_handle(struct iwl_trans *trans) dma_unmap_page(trans->dev, rxb->page_dma, PAGE_SIZE << hw_params(trans).rx_page_order, DMA_FROM_DEVICE); - pkt = rxb_addr(rxb); + + rxcb._page = rxb->page; + pkt = rxb_addr(&rxcb); IWL_DEBUG_RX(trans, "r = %d, i = %d, %s, 0x%02x\n", r, i, get_cmd_string(pkt->hdr.cmd), pkt->hdr.cmd); @@ -461,10 +464,10 @@ static void iwl_rx_handle(struct iwl_trans *trans) "reclaim is false, SEQ_RX_FRAME unset: %s\n", get_cmd_string(pkt->hdr.cmd)); - err = iwl_op_mode_rx(trans->op_mode, rxb, cmd); + err = iwl_op_mode_rx(trans->op_mode, &rxcb, cmd); /* - * XXX: After here, we should always check rxb->page + * XXX: After here, we should always check rxcb._page * against NULL before touching it or its virtual * memory (pkt). Because some rx_handler might have * already taken or freed the pages. @@ -475,12 +478,16 @@ static void iwl_rx_handle(struct iwl_trans *trans) * and fire off the (possibly) blocking * iwl_trans_send_cmd() * as we reclaim the driver command queue */ - if (rxb->page) - iwl_tx_cmd_complete(trans, rxb, err); + if (rxcb._page) + iwl_tx_cmd_complete(trans, &rxcb, err); else IWL_WARN(trans, "Claim null rxb?\n"); } + /* page was stolen from us */ + if (rxcb._page == NULL) + rxb->page = NULL; + /* Reuse the page if possible. For notification packets and * SKBs that fail to Rx correctly, add them back into the * rx_free list for reuse later. */ diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c index 771fae2f9fd8..0513b90da040 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c @@ -841,7 +841,7 @@ static void iwl_hcmd_queue_reclaim(struct iwl_trans *trans, int txq_id, * will be executed. The attached skb (if present) will only be freed * if the callback returns 1 */ -void iwl_tx_cmd_complete(struct iwl_trans *trans, struct iwl_rx_mem_buffer *rxb, +void iwl_tx_cmd_complete(struct iwl_trans *trans, struct iwl_rx_cmd_buffer *rxb, int handler_status) { struct iwl_rx_packet *pkt = rxb_addr(rxb); @@ -879,9 +879,8 @@ void iwl_tx_cmd_complete(struct iwl_trans *trans, struct iwl_rx_mem_buffer *rxb, /* Input error checking is done when commands are added to queue. */ if (meta->flags & CMD_WANT_SKB) { - struct page *p = rxb->page; + struct page *p = rxb_steal_page(rxb); - rxb->page = NULL; meta->source->resp_pkt = pkt; meta->source->_rx_page_addr = (unsigned long)page_address(p); meta->source->_rx_page_order = hw_params(trans).rx_page_order; diff --git a/drivers/net/wireless/iwlwifi/iwl-ucode.c b/drivers/net/wireless/iwlwifi/iwl-ucode.c index 206a61c991dd..12e79d04374f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-ucode.c +++ b/drivers/net/wireless/iwlwifi/iwl-ucode.c @@ -228,7 +228,7 @@ static int iwl_send_calib_cfg(struct iwl_trans *trans) } int iwlagn_rx_calib_result(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb, + struct iwl_rx_cmd_buffer *rxb, struct iwl_device_cmd *cmd) { struct iwl_rx_packet *pkt = rxb_addr(rxb); -- cgit From df2f3216ccde52bb43df78e0b869a0dd1637cf15 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 5 Mar 2012 11:24:40 -0800 Subject: iwlwifi: refactor PCI-E RX path Just make the code easier to read with less indentation. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c | 216 ++++++++++++----------- 1 file changed, 110 insertions(+), 106 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c index 68e89be60bef..bf560e9f87b7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c @@ -358,6 +358,113 @@ void iwl_bg_rx_replenish(struct work_struct *data) iwlagn_rx_replenish(trans_pcie->trans); } +static void iwl_rx_handle_rxbuf(struct iwl_trans *trans, + struct iwl_rx_mem_buffer *rxb) +{ + struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); + struct iwl_rx_queue *rxq = &trans_pcie->rxq; + struct iwl_tx_queue *txq = &trans_pcie->txq[trans->shrd->cmd_queue]; + struct iwl_device_cmd *cmd; + unsigned long flags; + int len, err; + u16 sequence; + struct iwl_rx_cmd_buffer rxcb; + struct iwl_rx_packet *pkt; + bool reclaim; + int index, cmd_index; + + if (WARN_ON(!rxb)) + return; + + dma_unmap_page(trans->dev, rxb->page_dma, + PAGE_SIZE << hw_params(trans).rx_page_order, + DMA_FROM_DEVICE); + + rxcb._page = rxb->page; + pkt = rxb_addr(&rxcb); + + IWL_DEBUG_RX(trans, "%s, 0x%02x\n", + get_cmd_string(pkt->hdr.cmd), pkt->hdr.cmd); + + + len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK; + len += sizeof(u32); /* account for status word */ + trace_iwlwifi_dev_rx(priv(trans), pkt, len); + + /* Reclaim a command buffer only if this packet is a response + * to a (driver-originated) command. + * If the packet (e.g. Rx frame) originated from uCode, + * there is no command buffer to reclaim. + * Ucode should set SEQ_RX_FRAME bit if ucode-originated, + * but apparently a few don't get set; catch them here. */ + reclaim = !(pkt->hdr.sequence & SEQ_RX_FRAME) && + (pkt->hdr.cmd != REPLY_RX_PHY_CMD) && + (pkt->hdr.cmd != REPLY_RX) && + (pkt->hdr.cmd != REPLY_RX_MPDU_CMD) && + (pkt->hdr.cmd != REPLY_COMPRESSED_BA) && + (pkt->hdr.cmd != STATISTICS_NOTIFICATION) && + (pkt->hdr.cmd != REPLY_TX); + + sequence = le16_to_cpu(pkt->hdr.sequence); + index = SEQ_TO_INDEX(sequence); + cmd_index = get_cmd_index(&txq->q, index); + + if (reclaim) + cmd = txq->cmd[cmd_index]; + else + cmd = NULL; + + /* warn if this is cmd response / notification and the uCode + * didn't set the SEQ_RX_FRAME for a frame that is + * uCode-originated + * If you saw this code after the second half of 2012, then + * please remove it + */ + WARN(pkt->hdr.cmd != REPLY_TX && reclaim == false && + (!(pkt->hdr.sequence & SEQ_RX_FRAME)), + "reclaim is false, SEQ_RX_FRAME unset: %s\n", + get_cmd_string(pkt->hdr.cmd)); + + err = iwl_op_mode_rx(trans->op_mode, &rxcb, cmd); + + /* + * XXX: After here, we should always check rxcb._page + * against NULL before touching it or its virtual + * memory (pkt). Because some rx_handler might have + * already taken or freed the pages. + */ + + if (reclaim) { + /* Invoke any callbacks, transfer the buffer to caller, + * and fire off the (possibly) blocking + * iwl_trans_send_cmd() + * as we reclaim the driver command queue */ + if (rxcb._page) + iwl_tx_cmd_complete(trans, &rxcb, err); + else + IWL_WARN(trans, "Claim null rxb?\n"); + } + + /* page was stolen from us */ + if (rxcb._page == NULL) + rxb->page = NULL; + + /* Reuse the page if possible. For notification packets and + * SKBs that fail to Rx correctly, add them back into the + * rx_free list for reuse later. */ + spin_lock_irqsave(&rxq->lock, flags); + if (rxb->page != NULL) { + rxb->page_dma = + dma_map_page(trans->dev, rxb->page, 0, + PAGE_SIZE << hw_params(trans).rx_page_order, + DMA_FROM_DEVICE); + list_add_tail(&rxb->list, &rxq->rx_free); + rxq->free_count++; + } else + list_add_tail(&rxb->list, &rxq->rx_used); + spin_unlock_irqrestore(&rxq->lock, flags); +} + /** * iwl_rx_handle - Main entry function for receiving responses from uCode * @@ -367,18 +474,12 @@ void iwl_bg_rx_replenish(struct work_struct *data) */ static void iwl_rx_handle(struct iwl_trans *trans) { - struct iwl_trans_pcie *trans_pcie = - IWL_TRANS_GET_PCIE_TRANS(trans); + struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); struct iwl_rx_queue *rxq = &trans_pcie->rxq; - struct iwl_tx_queue *txq = &trans_pcie->txq[trans->shrd->cmd_queue]; - struct iwl_device_cmd *cmd; u32 r, i; - int reclaim; - unsigned long flags; u8 fill_rx = 0; u32 count = 8; int total_empty; - int index, cmd_index; /* uCode's read index (stored in shared DRAM) indicates the last Rx * buffer that the driver may process (last buffer filled by ucode). */ @@ -398,111 +499,14 @@ static void iwl_rx_handle(struct iwl_trans *trans) fill_rx = 1; while (i != r) { - int len, err; - u16 sequence; struct iwl_rx_mem_buffer *rxb; - struct iwl_rx_cmd_buffer rxcb; - struct iwl_rx_packet *pkt; rxb = rxq->queue[i]; - - /* If an RXB doesn't have a Rx queue slot associated with it, - * then a bug has been introduced in the queue refilling - * routines -- catch it here */ - if (WARN_ON(rxb == NULL)) { - i = (i + 1) & RX_QUEUE_MASK; - continue; - } - rxq->queue[i] = NULL; - dma_unmap_page(trans->dev, rxb->page_dma, - PAGE_SIZE << hw_params(trans).rx_page_order, - DMA_FROM_DEVICE); - - rxcb._page = rxb->page; - pkt = rxb_addr(&rxcb); - - IWL_DEBUG_RX(trans, "r = %d, i = %d, %s, 0x%02x\n", r, - i, get_cmd_string(pkt->hdr.cmd), pkt->hdr.cmd); - - len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK; - len += sizeof(u32); /* account for status word */ - trace_iwlwifi_dev_rx(priv(trans), pkt, len); - - /* Reclaim a command buffer only if this packet is a response - * to a (driver-originated) command. - * If the packet (e.g. Rx frame) originated from uCode, - * there is no command buffer to reclaim. - * Ucode should set SEQ_RX_FRAME bit if ucode-originated, - * but apparently a few don't get set; catch them here. */ - reclaim = !(pkt->hdr.sequence & SEQ_RX_FRAME) && - (pkt->hdr.cmd != REPLY_RX_PHY_CMD) && - (pkt->hdr.cmd != REPLY_RX) && - (pkt->hdr.cmd != REPLY_RX_MPDU_CMD) && - (pkt->hdr.cmd != REPLY_COMPRESSED_BA) && - (pkt->hdr.cmd != STATISTICS_NOTIFICATION) && - (pkt->hdr.cmd != REPLY_TX); - - sequence = le16_to_cpu(pkt->hdr.sequence); - index = SEQ_TO_INDEX(sequence); - cmd_index = get_cmd_index(&txq->q, index); - - if (reclaim) - cmd = txq->cmd[cmd_index]; - else - cmd = NULL; - - /* warn if this is cmd response / notification and the uCode - * didn't set the SEQ_RX_FRAME for a frame that is - * uCode-originated - * If you saw this code after the second half of 2012, then - * please remove it - */ - WARN(pkt->hdr.cmd != REPLY_TX && reclaim == false && - (!(pkt->hdr.sequence & SEQ_RX_FRAME)), - "reclaim is false, SEQ_RX_FRAME unset: %s\n", - get_cmd_string(pkt->hdr.cmd)); - - err = iwl_op_mode_rx(trans->op_mode, &rxcb, cmd); - - /* - * XXX: After here, we should always check rxcb._page - * against NULL before touching it or its virtual - * memory (pkt). Because some rx_handler might have - * already taken or freed the pages. - */ - - if (reclaim) { - /* Invoke any callbacks, transfer the buffer to caller, - * and fire off the (possibly) blocking - * iwl_trans_send_cmd() - * as we reclaim the driver command queue */ - if (rxcb._page) - iwl_tx_cmd_complete(trans, &rxcb, err); - else - IWL_WARN(trans, "Claim null rxb?\n"); - } - - /* page was stolen from us */ - if (rxcb._page == NULL) - rxb->page = NULL; + IWL_DEBUG_RX(trans, "rxbuf: r = %d, i = %d (%p)\n", rxb); - /* Reuse the page if possible. For notification packets and - * SKBs that fail to Rx correctly, add them back into the - * rx_free list for reuse later. */ - spin_lock_irqsave(&rxq->lock, flags); - if (rxb->page != NULL) { - rxb->page_dma = dma_map_page(trans->dev, rxb->page, - 0, PAGE_SIZE << - hw_params(trans).rx_page_order, - DMA_FROM_DEVICE); - list_add_tail(&rxb->list, &rxq->rx_free); - rxq->free_count++; - } else - list_add_tail(&rxb->list, &rxq->rx_used); - - spin_unlock_irqrestore(&rxq->lock, flags); + iwl_rx_handle_rxbuf(trans, rxb); i = (i + 1) & RX_QUEUE_MASK; /* If there are a lot of unused frames, -- cgit From c977a33d84fb3d706faa0b62f9671f49b16dde34 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 5 Mar 2012 11:24:41 -0800 Subject: iwlwifi: transport's tx_agg_alloc must not sleep The annotation/documentation is wrong, we call it in a context that can't sleep. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-trans.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index e8ab8d8ca484..0197f31f3bec 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h @@ -229,7 +229,7 @@ static inline void iwl_free_resp(struct iwl_host_cmd *cmd) * @reclaim: free packet until ssn. Returns a list of freed packets. * Must be atomic * @tx_agg_alloc: allocate resources for a TX BA session - * May sleep + * Must be atomic * @tx_agg_setup: setup a tx queue for AMPDU - will be called once the HW is * ready and a successful ADDBA response has been received. * May sleep @@ -474,8 +474,6 @@ static inline int iwl_trans_tx_agg_disable(struct iwl_trans *trans, static inline int iwl_trans_tx_agg_alloc(struct iwl_trans *trans, int sta_id, int tid) { - might_sleep(); - if (trans->state != IWL_TRANS_FW_ALIVE) IWL_ERR(trans, "%s bad state = %d", __func__, trans->state); -- cgit From bffc66ce2210b149fd171eccad2aef9802c0b35d Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 5 Mar 2012 11:24:42 -0800 Subject: iwlwifi: move queue functions to PCI-E iwl_queue_inc_wrap/iwl_queue_dec_wrap aren't shared functions, they are PCI-E specific, so move them into the appropriate header. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-shared.h | 20 -------------------- drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h | 20 ++++++++++++++++++++ 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-shared.h b/drivers/net/wireless/iwlwifi/iwl-shared.h index ed1811d43550..787d726efbc8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-shared.h +++ b/drivers/net/wireless/iwlwifi/iwl-shared.h @@ -413,26 +413,6 @@ static inline bool iwl_have_debug_level(u32 level) return iwlagn_mod_params.debug_level & level; } -/** - * iwl_queue_inc_wrap - increment queue index, wrap back to beginning - * @index -- current index - * @n_bd -- total number of entries in queue (must be power of 2) - */ -static inline int iwl_queue_inc_wrap(int index, int n_bd) -{ - return ++index & (n_bd - 1); -} - -/** - * iwl_queue_dec_wrap - decrement queue index, wrap back to end - * @index -- current index - * @n_bd -- total number of entries in queue (must be power of 2) - */ -static inline int iwl_queue_dec_wrap(int index, int n_bd) -{ - return --index & (n_bd - 1); -} - struct iwl_rx_cmd_buffer { struct page *_page; }; diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h index 632d4099900e..44952c371d33 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h @@ -115,6 +115,26 @@ struct iwl_dma_ptr { size_t size; }; +/** + * iwl_queue_inc_wrap - increment queue index, wrap back to beginning + * @index -- current index + * @n_bd -- total number of entries in queue (must be power of 2) + */ +static inline int iwl_queue_inc_wrap(int index, int n_bd) +{ + return ++index & (n_bd - 1); +} + +/** + * iwl_queue_dec_wrap - decrement queue index, wrap back to end + * @index -- current index + * @n_bd -- total number of entries in queue (must be power of 2) + */ +static inline int iwl_queue_dec_wrap(int index, int n_bd) +{ + return --index & (n_bd - 1); +} + /* * This queue number is required for proper operation * because the ucode will stop/start the scheduler as -- cgit From 930dfd5f20eba2cef41cdb2db04108b359b97594 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 5 Mar 2012 11:24:43 -0800 Subject: iwlwifi: iwl_rx_cmd_buffer belongs to transport API This is how the transport passes things up into higher layers, so it belongs to the transport API. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-shared.h | 17 ----------------- drivers/net/wireless/iwlwifi/iwl-trans.h | 17 +++++++++++++++++ 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-shared.h b/drivers/net/wireless/iwlwifi/iwl-shared.h index 787d726efbc8..2b9d21a7207d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-shared.h +++ b/drivers/net/wireless/iwlwifi/iwl-shared.h @@ -67,7 +67,6 @@ #include #include #include -#include /* for page_address */ #include #include "iwl-commands.h" @@ -413,22 +412,6 @@ static inline bool iwl_have_debug_level(u32 level) return iwlagn_mod_params.debug_level & level; } -struct iwl_rx_cmd_buffer { - struct page *_page; -}; - -static inline void *rxb_addr(struct iwl_rx_cmd_buffer *r) -{ - return page_address(r->_page); -} - -static inline struct page *rxb_steal_page(struct iwl_rx_cmd_buffer *r) -{ - struct page *p = r->_page; - r->_page = NULL; - return p; -} - /* * mac80211 queues, ACs, hardware queues, FIFOs. * diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index 0197f31f3bec..b09192a028de 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h @@ -64,6 +64,7 @@ #define __iwl_trans_h__ #include +#include /* for page_address */ #include "iwl-shared.h" #include "iwl-debug.h" @@ -201,6 +202,22 @@ static inline void iwl_free_resp(struct iwl_host_cmd *cmd) free_pages(cmd->_rx_page_addr, cmd->_rx_page_order); } +struct iwl_rx_cmd_buffer { + struct page *_page; +}; + +static inline void *rxb_addr(struct iwl_rx_cmd_buffer *r) +{ + return page_address(r->_page); +} + +static inline struct page *rxb_steal_page(struct iwl_rx_cmd_buffer *r) +{ + struct page *p = r->_page; + r->_page = NULL; + return p; +} + /** * struct iwl_trans_ops - transport specific operations * -- cgit From 70a18c5d57998433d9f4de058a5286fbd16ed839 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 5 Mar 2012 11:24:44 -0800 Subject: iwlwifi: move tid_to_ac to PCI-E Currently, queue mapping is handled in the transport. This may change, but until then the code for it can be close to where it's used rather than in iwl-shared.h. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-shared.h | 46 ------------------------ drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c | 46 ++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 46 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-shared.h b/drivers/net/wireless/iwlwifi/iwl-shared.h index 2b9d21a7207d..740a058b22ee 100644 --- a/drivers/net/wireless/iwlwifi/iwl-shared.h +++ b/drivers/net/wireless/iwlwifi/iwl-shared.h @@ -412,52 +412,6 @@ static inline bool iwl_have_debug_level(u32 level) return iwlagn_mod_params.debug_level & level; } -/* - * mac80211 queues, ACs, hardware queues, FIFOs. - * - * Cf. http://wireless.kernel.org/en/developers/Documentation/mac80211/queues - * - * Mac80211 uses the following numbers, which we get as from it - * by way of skb_get_queue_mapping(skb): - * - * VO 0 - * VI 1 - * BE 2 - * BK 3 - * - * - * Regular (not A-MPDU) frames are put into hardware queues corresponding - * to the FIFOs, see comments in iwl-prph.h. Aggregated frames get their - * own queue per aggregation session (RA/TID combination), such queues are - * set up to map into FIFOs too, for which we need an AC->FIFO mapping. In - * order to map frames to the right queue, we also need an AC->hw queue - * mapping. This is implemented here. - * - * Due to the way hw queues are set up (by the hw specific modules like - * iwl-4965.c, iwl-5000.c etc.), the AC->hw queue mapping is the identity - * mapping. - */ - -static const u8 tid_to_ac[] = { - IEEE80211_AC_BE, - IEEE80211_AC_BK, - IEEE80211_AC_BK, - IEEE80211_AC_BE, - IEEE80211_AC_VI, - IEEE80211_AC_VI, - IEEE80211_AC_VO, - IEEE80211_AC_VO -}; - -static inline int get_ac_from_tid(u16 tid) -{ - if (likely(tid < ARRAY_SIZE(tid_to_ac))) - return tid_to_ac[tid]; - - /* no support for TIDs 8-15 yet */ - return -EINVAL; -} - enum iwl_rxon_context_id { IWL_RXON_CTX_BSS, IWL_RXON_CTX_PAN, diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c index 0513b90da040..0164154f9c97 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c @@ -41,6 +41,43 @@ #define IWL_TX_CRC_SIZE 4 #define IWL_TX_DELIMITER_SIZE 4 +/* + * mac80211 queues, ACs, hardware queues, FIFOs. + * + * Cf. http://wireless.kernel.org/en/developers/Documentation/mac80211/queues + * + * Mac80211 uses the following numbers, which we get as from it + * by way of skb_get_queue_mapping(skb): + * + * VO 0 + * VI 1 + * BE 2 + * BK 3 + * + * + * Regular (not A-MPDU) frames are put into hardware queues corresponding + * to the FIFOs, see comments in iwl-prph.h. Aggregated frames get their + * own queue per aggregation session (RA/TID combination), such queues are + * set up to map into FIFOs too, for which we need an AC->FIFO mapping. In + * order to map frames to the right queue, we also need an AC->hw queue + * mapping. This is implemented here. + * + * Due to the way hw queues are set up (by the hw specific code), the AC->hw + * queue mapping is the identity mapping. + */ + +static const u8 tid_to_ac[] = { + IEEE80211_AC_BE, + IEEE80211_AC_BK, + IEEE80211_AC_BK, + IEEE80211_AC_BE, + IEEE80211_AC_VI, + IEEE80211_AC_VI, + IEEE80211_AC_VO, + IEEE80211_AC_VO +}; + + /** * iwl_trans_txq_update_byte_cnt_tbl - Set up entry in Tx byte-count array */ @@ -442,6 +479,15 @@ void iwl_trans_tx_queue_set_status(struct iwl_trans *trans, scd_retry ? "BA" : "AC/CMD", txq_id); } +static inline int get_ac_from_tid(u16 tid) +{ + if (likely(tid < ARRAY_SIZE(tid_to_ac))) + return tid_to_ac[tid]; + + /* no support for TIDs 8-15 yet */ + return -EINVAL; +} + static inline int get_fifo_from_tid(struct iwl_trans_pcie *trans_pcie, u8 ctx, u16 tid) { -- cgit From 0439bb6200153406abb81b469b82d2336be0d175 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 5 Mar 2012 11:24:45 -0800 Subject: iwlwifi: move IWL_MASK into file using it Only used in two places in the same file, no need to be in iwl-shared.h. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-shared.h | 1 - drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | 2 ++ 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-shared.h b/drivers/net/wireless/iwlwifi/iwl-shared.h index 740a058b22ee..976e6c584ac7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-shared.h +++ b/drivers/net/wireless/iwlwifi/iwl-shared.h @@ -444,7 +444,6 @@ iwl_remove_notification(struct iwl_shared *shrd, struct iwl_notification_wait *wait_entry); #define IWL_CMD(x) case x: return #x -#define IWL_MASK(lo, hi) ((1 << (hi)) | ((1 << (hi)) - (1 << (lo)))) #define IWL_TRAFFIC_ENTRIES (256) #define IWL_TRAFFIC_ENTRY_SIZE (64) diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c index bb8f2fdf1281..3ae2fd720ed8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c @@ -78,6 +78,8 @@ #include "iwl-core.h" #include "iwl-ucode.h" +#define IWL_MASK(lo, hi) ((1 << (hi)) | ((1 << (hi)) - (1 << (lo)))) + static int iwl_trans_rx_alloc(struct iwl_trans *trans) { struct iwl_trans_pcie *trans_pcie = -- cgit From 61f0439277abb4f65d99b362b62cbabbde7032a0 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 5 Mar 2012 11:24:46 -0800 Subject: iwlwifi: move traffic log definitions These are DVM specific, and shouldn't be in iwl-shared.h. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-core.h | 4 ++++ drivers/net/wireless/iwlwifi/iwl-shared.h | 3 --- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 42630f5e8de7..db44115a6775 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -265,6 +265,10 @@ int __must_check iwl_scan_initiate(struct iwl_priv *priv, #define IWL_SCAN_CHECK_WATCHDOG (HZ * 7) +/* traffic log definitions */ +#define IWL_TRAFFIC_ENTRIES (256) +#define IWL_TRAFFIC_ENTRY_SIZE (64) + /***************************************************** * S e n d i n g H o s t C o m m a n d s * *****************************************************/ diff --git a/drivers/net/wireless/iwlwifi/iwl-shared.h b/drivers/net/wireless/iwlwifi/iwl-shared.h index 976e6c584ac7..b816e70d1445 100644 --- a/drivers/net/wireless/iwlwifi/iwl-shared.h +++ b/drivers/net/wireless/iwlwifi/iwl-shared.h @@ -445,9 +445,6 @@ iwl_remove_notification(struct iwl_shared *shrd, #define IWL_CMD(x) case x: return #x -#define IWL_TRAFFIC_ENTRIES (256) -#define IWL_TRAFFIC_ENTRY_SIZE (64) - /***************************************************** * DRIVER STATUS FUNCTIONS ******************************************************/ -- cgit From ab0bd5b32a9c7ea2e7cc69d56c82a96be340c269 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 5 Mar 2012 11:24:47 -0800 Subject: iwlwifi: fix station HT parameters My patch "iwlwifi: simplify auth/assoc flow" caused a serious throughput degradation due to me forgetting that there are HT settings in the station table. To restore throughput, set these parameters correctly when the sta moves to assoc state. This patch should probably be merged with the auth/assoc redesign patch for upstream. In that case, this paragraph should be added to the commit log as the third paragraph (before talking about RXON): However, as we only get the station HT data when the station moves into assoc state, we also need to program this into the device (and copy it into our database) then. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-sta.c | 81 +++++++++++++++++++++-------- drivers/net/wireless/iwlwifi/iwl-agn.h | 2 + drivers/net/wireless/iwlwifi/iwl-mac80211.c | 18 +++++-- 3 files changed, 75 insertions(+), 26 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c index 736f8dc404df..ca080265a829 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c @@ -169,34 +169,38 @@ int iwl_send_add_sta(struct iwl_priv *priv, return cmd.handler_status; } -static void iwl_set_ht_add_station(struct iwl_priv *priv, u8 index, - struct ieee80211_sta *sta, - struct iwl_rxon_context *ctx) +static void iwl_sta_calc_ht_flags(struct iwl_priv *priv, + struct ieee80211_sta *sta, + struct iwl_rxon_context *ctx, + __le32 *flags, __le32 *mask) { struct ieee80211_sta_ht_cap *sta_ht_inf = &sta->ht_cap; - __le32 sta_flags; u8 mimo_ps_mode; + *mask = STA_FLG_RTS_MIMO_PROT_MSK | + STA_FLG_MIMO_DIS_MSK | + STA_FLG_HT40_EN_MSK | + STA_FLG_MAX_AGG_SIZE_MSK | + STA_FLG_AGG_MPDU_DENSITY_MSK; + *flags = 0; + if (!sta || !sta_ht_inf->ht_supported) - goto done; + return; mimo_ps_mode = (sta_ht_inf->cap & IEEE80211_HT_CAP_SM_PS) >> 2; - IWL_DEBUG_ASSOC(priv, "spatial multiplexing power save mode: %s\n", + + IWL_DEBUG_INFO(priv, "STA %pM SM PS mode: %s\n", (mimo_ps_mode == WLAN_HT_CAP_SM_PS_STATIC) ? "static" : (mimo_ps_mode == WLAN_HT_CAP_SM_PS_DYNAMIC) ? "dynamic" : "disabled"); - sta_flags = priv->stations[index].sta.station_flags; - - sta_flags &= ~(STA_FLG_RTS_MIMO_PROT_MSK | STA_FLG_MIMO_DIS_MSK); - switch (mimo_ps_mode) { case WLAN_HT_CAP_SM_PS_STATIC: - sta_flags |= STA_FLG_MIMO_DIS_MSK; + *flags |= STA_FLG_MIMO_DIS_MSK; break; case WLAN_HT_CAP_SM_PS_DYNAMIC: - sta_flags |= STA_FLG_RTS_MIMO_PROT_MSK; + *flags |= STA_FLG_RTS_MIMO_PROT_MSK; break; case WLAN_HT_CAP_SM_PS_DISABLED: break; @@ -205,20 +209,53 @@ static void iwl_set_ht_add_station(struct iwl_priv *priv, u8 index, break; } - sta_flags |= cpu_to_le32( - (u32)sta_ht_inf->ampdu_factor << STA_FLG_MAX_AGG_SIZE_POS); + *flags |= cpu_to_le32( + (u32)sta_ht_inf->ampdu_factor << STA_FLG_MAX_AGG_SIZE_POS); - sta_flags |= cpu_to_le32( - (u32)sta_ht_inf->ampdu_density << STA_FLG_AGG_MPDU_DENSITY_POS); + *flags |= cpu_to_le32( + (u32)sta_ht_inf->ampdu_density << STA_FLG_AGG_MPDU_DENSITY_POS); if (iwl_is_ht40_tx_allowed(priv, ctx, &sta->ht_cap)) - sta_flags |= STA_FLG_HT40_EN_MSK; - else - sta_flags &= ~STA_FLG_HT40_EN_MSK; + *flags |= STA_FLG_HT40_EN_MSK; +} + +int iwl_sta_update_ht(struct iwl_priv *priv, struct iwl_rxon_context *ctx, + struct ieee80211_sta *sta) +{ + u8 sta_id = iwl_sta_id(sta); + __le32 flags, mask; + struct iwl_addsta_cmd cmd; + + if (WARN_ON_ONCE(sta_id == IWL_INVALID_STATION)) + return -EINVAL; - priv->stations[index].sta.station_flags = sta_flags; - done: - return; + iwl_sta_calc_ht_flags(priv, sta, ctx, &flags, &mask); + + spin_lock_bh(&priv->sta_lock); + priv->stations[sta_id].sta.station_flags &= ~mask; + priv->stations[sta_id].sta.station_flags |= flags; + spin_unlock_bh(&priv->sta_lock); + + memset(&cmd, 0, sizeof(cmd)); + cmd.mode = STA_CONTROL_MODIFY_MSK; + cmd.station_flags_msk = mask; + cmd.station_flags = flags; + cmd.sta.sta_id = sta_id; + + return iwl_send_add_sta(priv, &cmd, CMD_SYNC); +} + +static void iwl_set_ht_add_station(struct iwl_priv *priv, u8 index, + struct ieee80211_sta *sta, + struct iwl_rxon_context *ctx) +{ + __le32 flags, mask; + + iwl_sta_calc_ht_flags(priv, sta, ctx, &flags, &mask); + + lockdep_assert_held(&priv->sta_lock); + priv->stations[index].sta.station_flags &= ~mask; + priv->stations[index].sta.station_flags |= flags; } /** diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index a9c018a7b8ba..70100f9a2e5c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h @@ -229,6 +229,8 @@ int iwl_send_lq_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx, struct iwl_link_quality_cmd *lq, u8 flags, bool init); int iwl_add_sta_callback(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb, struct iwl_device_cmd *cmd); +int iwl_sta_update_ht(struct iwl_priv *priv, struct iwl_rxon_context *ctx, + struct ieee80211_sta *sta); static inline int iwl_sta_id(struct ieee80211_sta *sta) diff --git a/drivers/net/wireless/iwlwifi/iwl-mac80211.c b/drivers/net/wireless/iwlwifi/iwl-mac80211.c index 8160f615f71a..7f937151a8af 100644 --- a/drivers/net/wireless/iwlwifi/iwl-mac80211.c +++ b/drivers/net/wireless/iwlwifi/iwl-mac80211.c @@ -740,8 +740,9 @@ static int iwlagn_mac_sta_state(struct ieee80211_hw *hw, enum ieee80211_sta_state new_state) { struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); + struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; enum { - NONE, ADD, REMOVE, RATE_INIT, ADD_RATE_INIT, + NONE, ADD, REMOVE, HT_RATE_INIT, ADD_RATE_INIT, } op = NONE; int ret; @@ -758,7 +759,7 @@ static int iwlagn_mac_sta_state(struct ieee80211_hw *hw, op = REMOVE; else if (old_state == IEEE80211_STA_AUTH && new_state == IEEE80211_STA_ASSOC) - op = RATE_INIT; + op = HT_RATE_INIT; } else { if (old_state == IEEE80211_STA_AUTH && new_state == IEEE80211_STA_ASSOC) @@ -779,8 +780,6 @@ static int iwlagn_mac_sta_state(struct ieee80211_hw *hw, ret = iwlagn_mac_sta_add(hw, vif, sta); if (ret) break; - /* fall through */ - case RATE_INIT: /* Initialize rate scaling */ IWL_DEBUG_INFO(priv, "Initializing rate scaling for station %pM\n", @@ -788,6 +787,17 @@ static int iwlagn_mac_sta_state(struct ieee80211_hw *hw, iwl_rs_rate_init(priv, sta, iwl_sta_id(sta)); ret = 0; break; + case HT_RATE_INIT: + /* Initialize rate scaling */ + ret = iwl_sta_update_ht(priv, vif_priv->ctx, sta); + if (ret) + break; + IWL_DEBUG_INFO(priv, + "Initializing rate scaling for station %pM\n", + sta->addr); + iwl_rs_rate_init(priv, sta, iwl_sta_id(sta)); + ret = 0; + break; default: ret = 0; break; -- cgit From 7db5b989a0e28a40ce61ef0b26da1af18289d711 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 5 Mar 2012 11:24:48 -0800 Subject: iwlwifi: move uCode deallocation to drv This shouldn't be in the op_mode, as it will later be switchable at runtime. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn.c | 2 -- drivers/net/wireless/iwlwifi/iwl-drv.c | 2 ++ 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 6dd4faead7cd..c3b594647def 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -1385,8 +1385,6 @@ static void iwl_op_mode_dvm_stop(struct iwl_op_mode *op_mode) /*This will stop the queues, move the device to low power state */ iwl_trans_stop_device(trans(priv)); - iwl_dealloc_ucode(nic(priv)); - iwl_eeprom_free(priv->shrd); /*netif_stop_queue(dev); */ diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.c b/drivers/net/wireless/iwlwifi/iwl-drv.c index 76fc4407b19e..590f57662754 100644 --- a/drivers/net/wireless/iwlwifi/iwl-drv.c +++ b/drivers/net/wireless/iwlwifi/iwl-drv.c @@ -99,5 +99,7 @@ void iwl_drv_stop(struct iwl_shared *shrd) if (shrd->nic->op_mode) iwl_op_mode_stop(shrd->nic->op_mode); + iwl_dealloc_ucode(shrd->nic); + kfree(shrd->nic); } -- cgit From 702e0630ee50c5f72e84da59daf5b23729140b62 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 5 Mar 2012 11:24:49 -0800 Subject: iwlwifi: move iwl_base_params to shared header This is used from there, so should be in it. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-core.h | 42 ------------------------------ drivers/net/wireless/iwlwifi/iwl-shared.h | 43 +++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 42 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index db44115a6775..7259cbf77da4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -95,48 +95,6 @@ struct iwl_lib_ops { void (*temperature)(struct iwl_priv *priv); }; -/* - * @max_ll_items: max number of OTP blocks - * @shadow_ram_support: shadow support for OTP memory - * @led_compensation: compensate on the led on/off time per HW according - * to the deviation to achieve the desired led frequency. - * The detail algorithm is described in iwl-led.c - * @chain_noise_num_beacons: number of beacons used to compute chain noise - * @adv_thermal_throttle: support advance thermal throttle - * @support_ct_kill_exit: support ct kill exit condition - * @support_wimax_coexist: support wimax/wifi co-exist - * @plcp_delta_threshold: plcp error rate threshold used to trigger - * radio tuning when there is a high receiving plcp error rate - * @chain_noise_scale: default chain noise scale used for gain computation - * @wd_timeout: TX queues watchdog timeout - * @max_event_log_size: size of event log buffer size for ucode event logging - * @shadow_reg_enable: HW shadhow register bit - * @no_idle_support: do not support idle mode - * @hd_v2: v2 of enhanced sensitivity value, used for 2000 series and up - * wd_disable: disable watchdog timer - */ -struct iwl_base_params { - int eeprom_size; - int num_of_queues; /* def: HW dependent */ - int num_of_ampdu_queues;/* def: HW dependent */ - /* for iwl_apm_init() */ - u32 pll_cfg_val; - - const u16 max_ll_items; - const bool shadow_ram_support; - u16 led_compensation; - bool adv_thermal_throttle; - bool support_ct_kill_exit; - const bool support_wimax_coexist; - u8 plcp_delta_threshold; - s32 chain_noise_scale; - unsigned int wd_timeout; - u32 max_event_log_size; - const bool shadow_reg_enable; - const bool no_idle_support; - const bool hd_v2; - const bool wd_disable; -}; /* * @advanced_bt_coexist: support advanced bt coexist * @bt_init_traffic_load: specify initial bt traffic load diff --git a/drivers/net/wireless/iwlwifi/iwl-shared.h b/drivers/net/wireless/iwlwifi/iwl-shared.h index b816e70d1445..ef80e0386c30 100644 --- a/drivers/net/wireless/iwlwifi/iwl-shared.h +++ b/drivers/net/wireless/iwlwifi/iwl-shared.h @@ -267,6 +267,49 @@ enum iwl_led_mode { IWL_LED_DISABLE, }; +/* + * @max_ll_items: max number of OTP blocks + * @shadow_ram_support: shadow support for OTP memory + * @led_compensation: compensate on the led on/off time per HW according + * to the deviation to achieve the desired led frequency. + * The detail algorithm is described in iwl-led.c + * @chain_noise_num_beacons: number of beacons used to compute chain noise + * @adv_thermal_throttle: support advance thermal throttle + * @support_ct_kill_exit: support ct kill exit condition + * @support_wimax_coexist: support wimax/wifi co-exist + * @plcp_delta_threshold: plcp error rate threshold used to trigger + * radio tuning when there is a high receiving plcp error rate + * @chain_noise_scale: default chain noise scale used for gain computation + * @wd_timeout: TX queues watchdog timeout + * @max_event_log_size: size of event log buffer size for ucode event logging + * @shadow_reg_enable: HW shadhow register bit + * @hd_v2: v2 of enhanced sensitivity value, used for 2000 series and up + * @no_idle_support: do not support idle mode + * wd_disable: disable watchdog timer + */ +struct iwl_base_params { + int eeprom_size; + int num_of_queues; /* def: HW dependent */ + int num_of_ampdu_queues;/* def: HW dependent */ + /* for iwl_apm_init() */ + u32 pll_cfg_val; + + const u16 max_ll_items; + const bool shadow_ram_support; + u16 led_compensation; + bool adv_thermal_throttle; + bool support_ct_kill_exit; + const bool support_wimax_coexist; + u8 plcp_delta_threshold; + s32 chain_noise_scale; + unsigned int wd_timeout; + u32 max_event_log_size; + const bool shadow_reg_enable; + const bool hd_v2; + const bool no_idle_support; + const bool wd_disable; +}; + /** * struct iwl_cfg * @name: Offical name of the device -- cgit From 15854ef94f54ae8fa8b95eb66a2cfa5dcff481e9 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 5 Mar 2012 11:24:50 -0800 Subject: iwlwifi: move firmware request into drv Firmware request is a base driver flow, it isn't related to any specific mode. Move the code related to it into the base driver file iwl-drv.c. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-drv.c | 625 +++++++++++++++++++++++++++++++ drivers/net/wireless/iwlwifi/iwl-ucode.c | 622 ------------------------------ drivers/net/wireless/iwlwifi/iwl-wifi.h | 5 - 3 files changed, 625 insertions(+), 627 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.c b/drivers/net/wireless/iwlwifi/iwl-drv.c index 590f57662754..343f41eb4e4f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-drv.c +++ b/drivers/net/wireless/iwlwifi/iwl-drv.c @@ -61,12 +61,637 @@ * *****************************************************************************/ #include +#include +#include +#include #include "iwl-drv.h" #include "iwl-trans.h" #include "iwl-wifi.h" +#include "iwl-shared.h" #include "iwl-op-mode.h" +static void iwl_free_fw_desc(struct iwl_nic *nic, struct fw_desc *desc) +{ + if (desc->v_addr) + dma_free_coherent(trans(nic)->dev, desc->len, + desc->v_addr, desc->p_addr); + desc->v_addr = NULL; + desc->len = 0; +} + +static void iwl_free_fw_img(struct iwl_nic *nic, struct fw_img *img) +{ + iwl_free_fw_desc(nic, &img->code); + iwl_free_fw_desc(nic, &img->data); +} + +static void iwl_dealloc_ucode(struct iwl_nic *nic) +{ + iwl_free_fw_img(nic, &nic->fw.ucode_rt); + iwl_free_fw_img(nic, &nic->fw.ucode_init); + iwl_free_fw_img(nic, &nic->fw.ucode_wowlan); +} + +static int iwl_alloc_fw_desc(struct iwl_nic *nic, struct fw_desc *desc, + const void *data, size_t len) +{ + if (!len) { + desc->v_addr = NULL; + return -EINVAL; + } + + desc->v_addr = dma_alloc_coherent(trans(nic)->dev, len, + &desc->p_addr, GFP_KERNEL); + if (!desc->v_addr) + return -ENOMEM; + + desc->len = len; + memcpy(desc->v_addr, data, len); + return 0; +} + +static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context); + +#define UCODE_EXPERIMENTAL_INDEX 100 +#define UCODE_EXPERIMENTAL_TAG "exp" + +static int iwl_request_firmware(struct iwl_nic *nic, bool first) +{ + const struct iwl_cfg *cfg = cfg(nic); + const char *name_pre = cfg->fw_name_pre; + char tag[8]; + + if (first) { +#ifdef CONFIG_IWLWIFI_DEBUG_EXPERIMENTAL_UCODE + nic->fw_index = UCODE_EXPERIMENTAL_INDEX; + strcpy(tag, UCODE_EXPERIMENTAL_TAG); + } else if (nic->fw_index == UCODE_EXPERIMENTAL_INDEX) { +#endif + nic->fw_index = cfg->ucode_api_max; + sprintf(tag, "%d", nic->fw_index); + } else { + nic->fw_index--; + sprintf(tag, "%d", nic->fw_index); + } + + if (nic->fw_index < cfg->ucode_api_min) { + IWL_ERR(nic, "no suitable firmware found!\n"); + return -ENOENT; + } + + sprintf(nic->firmware_name, "%s%s%s", name_pre, tag, ".ucode"); + + IWL_DEBUG_INFO(nic, "attempting to load firmware %s'%s'\n", + (nic->fw_index == UCODE_EXPERIMENTAL_INDEX) + ? "EXPERIMENTAL " : "", + nic->firmware_name); + + return request_firmware_nowait(THIS_MODULE, 1, nic->firmware_name, + trans(nic)->dev, + GFP_KERNEL, nic, iwl_ucode_callback); +} + +struct iwlagn_firmware_pieces { + const void *inst, *data, *init, *init_data, *wowlan_inst, *wowlan_data; + size_t inst_size, data_size, init_size, init_data_size, + wowlan_inst_size, wowlan_data_size; + + u32 init_evtlog_ptr, init_evtlog_size, init_errlog_ptr; + u32 inst_evtlog_ptr, inst_evtlog_size, inst_errlog_ptr; +}; + +static int iwl_parse_v1_v2_firmware(struct iwl_nic *nic, + const struct firmware *ucode_raw, + struct iwlagn_firmware_pieces *pieces) +{ + struct iwl_ucode_header *ucode = (void *)ucode_raw->data; + u32 api_ver, hdr_size, build; + char buildstr[25]; + const u8 *src; + + nic->fw.ucode_ver = le32_to_cpu(ucode->ver); + api_ver = IWL_UCODE_API(nic->fw.ucode_ver); + + switch (api_ver) { + default: + hdr_size = 28; + if (ucode_raw->size < hdr_size) { + IWL_ERR(nic, "File size too small!\n"); + return -EINVAL; + } + build = le32_to_cpu(ucode->u.v2.build); + pieces->inst_size = le32_to_cpu(ucode->u.v2.inst_size); + pieces->data_size = le32_to_cpu(ucode->u.v2.data_size); + pieces->init_size = le32_to_cpu(ucode->u.v2.init_size); + pieces->init_data_size = + le32_to_cpu(ucode->u.v2.init_data_size); + src = ucode->u.v2.data; + break; + case 0: + case 1: + case 2: + hdr_size = 24; + if (ucode_raw->size < hdr_size) { + IWL_ERR(nic, "File size too small!\n"); + return -EINVAL; + } + build = 0; + pieces->inst_size = le32_to_cpu(ucode->u.v1.inst_size); + pieces->data_size = le32_to_cpu(ucode->u.v1.data_size); + pieces->init_size = le32_to_cpu(ucode->u.v1.init_size); + pieces->init_data_size = + le32_to_cpu(ucode->u.v1.init_data_size); + src = ucode->u.v1.data; + break; + } + + if (build) + sprintf(buildstr, " build %u%s", build, + (nic->fw_index == UCODE_EXPERIMENTAL_INDEX) + ? " (EXP)" : ""); + else + buildstr[0] = '\0'; + + snprintf(nic->fw.fw_version, + sizeof(nic->fw.fw_version), + "%u.%u.%u.%u%s", + IWL_UCODE_MAJOR(nic->fw.ucode_ver), + IWL_UCODE_MINOR(nic->fw.ucode_ver), + IWL_UCODE_API(nic->fw.ucode_ver), + IWL_UCODE_SERIAL(nic->fw.ucode_ver), + buildstr); + + /* Verify size of file vs. image size info in file's header */ + if (ucode_raw->size != hdr_size + pieces->inst_size + + pieces->data_size + pieces->init_size + + pieces->init_data_size) { + + IWL_ERR(nic, + "uCode file size %d does not match expected size\n", + (int)ucode_raw->size); + return -EINVAL; + } + + pieces->inst = src; + src += pieces->inst_size; + pieces->data = src; + src += pieces->data_size; + pieces->init = src; + src += pieces->init_size; + pieces->init_data = src; + src += pieces->init_data_size; + + return 0; +} + +static int iwl_parse_tlv_firmware(struct iwl_nic *nic, + const struct firmware *ucode_raw, + struct iwlagn_firmware_pieces *pieces, + struct iwl_ucode_capabilities *capa) +{ + struct iwl_tlv_ucode_header *ucode = (void *)ucode_raw->data; + struct iwl_ucode_tlv *tlv; + size_t len = ucode_raw->size; + const u8 *data; + int wanted_alternative = iwlagn_mod_params.wanted_ucode_alternative; + int tmp; + u64 alternatives; + u32 tlv_len; + enum iwl_ucode_tlv_type tlv_type; + const u8 *tlv_data; + char buildstr[25]; + u32 build; + + if (len < sizeof(*ucode)) { + IWL_ERR(nic, "uCode has invalid length: %zd\n", len); + return -EINVAL; + } + + if (ucode->magic != cpu_to_le32(IWL_TLV_UCODE_MAGIC)) { + IWL_ERR(nic, "invalid uCode magic: 0X%x\n", + le32_to_cpu(ucode->magic)); + return -EINVAL; + } + + /* + * Check which alternatives are present, and "downgrade" + * when the chosen alternative is not present, warning + * the user when that happens. Some files may not have + * any alternatives, so don't warn in that case. + */ + alternatives = le64_to_cpu(ucode->alternatives); + tmp = wanted_alternative; + if (wanted_alternative > 63) + wanted_alternative = 63; + while (wanted_alternative && !(alternatives & BIT(wanted_alternative))) + wanted_alternative--; + if (wanted_alternative && wanted_alternative != tmp) + IWL_WARN(nic, + "uCode alternative %d not available, choosing %d\n", + tmp, wanted_alternative); + + nic->fw.ucode_ver = le32_to_cpu(ucode->ver); + build = le32_to_cpu(ucode->build); + + if (build) + sprintf(buildstr, " build %u%s", build, + (nic->fw_index == UCODE_EXPERIMENTAL_INDEX) + ? " (EXP)" : ""); + else + buildstr[0] = '\0'; + + snprintf(nic->fw.fw_version, + sizeof(nic->fw.fw_version), + "%u.%u.%u.%u%s", + IWL_UCODE_MAJOR(nic->fw.ucode_ver), + IWL_UCODE_MINOR(nic->fw.ucode_ver), + IWL_UCODE_API(nic->fw.ucode_ver), + IWL_UCODE_SERIAL(nic->fw.ucode_ver), + buildstr); + + data = ucode->data; + + len -= sizeof(*ucode); + + while (len >= sizeof(*tlv)) { + u16 tlv_alt; + + len -= sizeof(*tlv); + tlv = (void *)data; + + tlv_len = le32_to_cpu(tlv->length); + tlv_type = le16_to_cpu(tlv->type); + tlv_alt = le16_to_cpu(tlv->alternative); + tlv_data = tlv->data; + + if (len < tlv_len) { + IWL_ERR(nic, "invalid TLV len: %zd/%u\n", + len, tlv_len); + return -EINVAL; + } + len -= ALIGN(tlv_len, 4); + data += sizeof(*tlv) + ALIGN(tlv_len, 4); + + /* + * Alternative 0 is always valid. + * + * Skip alternative TLVs that are not selected. + */ + if (tlv_alt != 0 && tlv_alt != wanted_alternative) + continue; + + switch (tlv_type) { + case IWL_UCODE_TLV_INST: + pieces->inst = tlv_data; + pieces->inst_size = tlv_len; + break; + case IWL_UCODE_TLV_DATA: + pieces->data = tlv_data; + pieces->data_size = tlv_len; + break; + case IWL_UCODE_TLV_INIT: + pieces->init = tlv_data; + pieces->init_size = tlv_len; + break; + case IWL_UCODE_TLV_INIT_DATA: + pieces->init_data = tlv_data; + pieces->init_data_size = tlv_len; + break; + case IWL_UCODE_TLV_BOOT: + IWL_ERR(nic, "Found unexpected BOOT ucode\n"); + break; + case IWL_UCODE_TLV_PROBE_MAX_LEN: + if (tlv_len != sizeof(u32)) + goto invalid_tlv_len; + capa->max_probe_length = + le32_to_cpup((__le32 *)tlv_data); + break; + case IWL_UCODE_TLV_PAN: + if (tlv_len) + goto invalid_tlv_len; + capa->flags |= IWL_UCODE_TLV_FLAGS_PAN; + break; + case IWL_UCODE_TLV_FLAGS: + /* must be at least one u32 */ + if (tlv_len < sizeof(u32)) + goto invalid_tlv_len; + /* and a proper number of u32s */ + if (tlv_len % sizeof(u32)) + goto invalid_tlv_len; + /* + * This driver only reads the first u32 as + * right now no more features are defined, + * if that changes then either the driver + * will not work with the new firmware, or + * it'll not take advantage of new features. + */ + capa->flags = le32_to_cpup((__le32 *)tlv_data); + break; + case IWL_UCODE_TLV_INIT_EVTLOG_PTR: + if (tlv_len != sizeof(u32)) + goto invalid_tlv_len; + pieces->init_evtlog_ptr = + le32_to_cpup((__le32 *)tlv_data); + break; + case IWL_UCODE_TLV_INIT_EVTLOG_SIZE: + if (tlv_len != sizeof(u32)) + goto invalid_tlv_len; + pieces->init_evtlog_size = + le32_to_cpup((__le32 *)tlv_data); + break; + case IWL_UCODE_TLV_INIT_ERRLOG_PTR: + if (tlv_len != sizeof(u32)) + goto invalid_tlv_len; + pieces->init_errlog_ptr = + le32_to_cpup((__le32 *)tlv_data); + break; + case IWL_UCODE_TLV_RUNT_EVTLOG_PTR: + if (tlv_len != sizeof(u32)) + goto invalid_tlv_len; + pieces->inst_evtlog_ptr = + le32_to_cpup((__le32 *)tlv_data); + break; + case IWL_UCODE_TLV_RUNT_EVTLOG_SIZE: + if (tlv_len != sizeof(u32)) + goto invalid_tlv_len; + pieces->inst_evtlog_size = + le32_to_cpup((__le32 *)tlv_data); + break; + case IWL_UCODE_TLV_RUNT_ERRLOG_PTR: + if (tlv_len != sizeof(u32)) + goto invalid_tlv_len; + pieces->inst_errlog_ptr = + le32_to_cpup((__le32 *)tlv_data); + break; + case IWL_UCODE_TLV_ENHANCE_SENS_TBL: + if (tlv_len) + goto invalid_tlv_len; + nic->fw.enhance_sensitivity_table = true; + break; + case IWL_UCODE_TLV_WOWLAN_INST: + pieces->wowlan_inst = tlv_data; + pieces->wowlan_inst_size = tlv_len; + break; + case IWL_UCODE_TLV_WOWLAN_DATA: + pieces->wowlan_data = tlv_data; + pieces->wowlan_data_size = tlv_len; + break; + case IWL_UCODE_TLV_PHY_CALIBRATION_SIZE: + if (tlv_len != sizeof(u32)) + goto invalid_tlv_len; + capa->standard_phy_calibration_size = + le32_to_cpup((__le32 *)tlv_data); + break; + default: + IWL_DEBUG_INFO(nic, "unknown TLV: %d\n", tlv_type); + break; + } + } + + if (len) { + IWL_ERR(nic, "invalid TLV after parsing: %zd\n", len); + iwl_print_hex_dump(nic, IWL_DL_FW, (u8 *)data, len); + return -EINVAL; + } + + return 0; + + invalid_tlv_len: + IWL_ERR(nic, "TLV %d has invalid size: %u\n", tlv_type, tlv_len); + iwl_print_hex_dump(nic, IWL_DL_FW, tlv_data, tlv_len); + + return -EINVAL; +} + +/** + * iwl_ucode_callback - callback when firmware was loaded + * + * If loaded successfully, copies the firmware into buffers + * for the card to fetch (via DMA). + */ +static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) +{ + struct iwl_nic *nic = context; + const struct iwl_cfg *cfg = cfg(nic); + struct iwl_fw *fw = &nic->fw; + struct iwl_ucode_header *ucode; + int err; + struct iwlagn_firmware_pieces pieces; + const unsigned int api_max = cfg->ucode_api_max; + unsigned int api_ok = cfg->ucode_api_ok; + const unsigned int api_min = cfg->ucode_api_min; + u32 api_ver; + + fw->ucode_capa.max_probe_length = 200; + fw->ucode_capa.standard_phy_calibration_size = + IWL_DEFAULT_STANDARD_PHY_CALIBRATE_TBL_SIZE; + + if (!api_ok) + api_ok = api_max; + + memset(&pieces, 0, sizeof(pieces)); + + if (!ucode_raw) { + if (nic->fw_index <= api_ok) + IWL_ERR(nic, + "request for firmware file '%s' failed.\n", + nic->firmware_name); + goto try_again; + } + + IWL_DEBUG_INFO(nic, "Loaded firmware file '%s' (%zd bytes).\n", + nic->firmware_name, ucode_raw->size); + + /* Make sure that we got at least the API version number */ + if (ucode_raw->size < 4) { + IWL_ERR(nic, "File size way too small!\n"); + goto try_again; + } + + /* Data from ucode file: header followed by uCode images */ + ucode = (struct iwl_ucode_header *)ucode_raw->data; + + if (ucode->ver) + err = iwl_parse_v1_v2_firmware(nic, ucode_raw, &pieces); + else + err = iwl_parse_tlv_firmware(nic, ucode_raw, &pieces, + &fw->ucode_capa); + + if (err) + goto try_again; + + api_ver = IWL_UCODE_API(nic->fw.ucode_ver); + + /* + * api_ver should match the api version forming part of the + * firmware filename ... but we don't check for that and only rely + * on the API version read from firmware header from here on forward + */ + /* no api version check required for experimental uCode */ + if (nic->fw_index != UCODE_EXPERIMENTAL_INDEX) { + if (api_ver < api_min || api_ver > api_max) { + IWL_ERR(nic, + "Driver unable to support your firmware API. " + "Driver supports v%u, firmware is v%u.\n", + api_max, api_ver); + goto try_again; + } + + if (api_ver < api_ok) { + if (api_ok != api_max) + IWL_ERR(nic, "Firmware has old API version, " + "expected v%u through v%u, got v%u.\n", + api_ok, api_max, api_ver); + else + IWL_ERR(nic, "Firmware has old API version, " + "expected v%u, got v%u.\n", + api_max, api_ver); + IWL_ERR(nic, "New firmware can be obtained from " + "http://www.intellinuxwireless.org/.\n"); + } + } + + IWL_INFO(nic, "loaded firmware version %s", nic->fw.fw_version); + + /* + * For any of the failures below (before allocating pci memory) + * we will try to load a version with a smaller API -- maybe the + * user just got a corrupted version of the latest API. + */ + + IWL_DEBUG_INFO(nic, "f/w package hdr ucode version raw = 0x%x\n", + nic->fw.ucode_ver); + IWL_DEBUG_INFO(nic, "f/w package hdr runtime inst size = %Zd\n", + pieces.inst_size); + IWL_DEBUG_INFO(nic, "f/w package hdr runtime data size = %Zd\n", + pieces.data_size); + IWL_DEBUG_INFO(nic, "f/w package hdr init inst size = %Zd\n", + pieces.init_size); + IWL_DEBUG_INFO(nic, "f/w package hdr init data size = %Zd\n", + pieces.init_data_size); + + /* Verify that uCode images will fit in card's SRAM */ + if (pieces.inst_size > cfg->max_inst_size) { + IWL_ERR(nic, "uCode instr len %Zd too large to fit in\n", + pieces.inst_size); + goto try_again; + } + + if (pieces.data_size > cfg->max_data_size) { + IWL_ERR(nic, "uCode data len %Zd too large to fit in\n", + pieces.data_size); + goto try_again; + } + + if (pieces.init_size > cfg->max_inst_size) { + IWL_ERR(nic, "uCode init instr len %Zd too large to fit in\n", + pieces.init_size); + goto try_again; + } + + if (pieces.init_data_size > cfg->max_data_size) { + IWL_ERR(nic, "uCode init data len %Zd too large to fit in\n", + pieces.init_data_size); + goto try_again; + } + + /* Allocate ucode buffers for card's bus-master loading ... */ + + /* Runtime instructions and 2 copies of data: + * 1) unmodified from disk + * 2) backup cache for save/restore during power-downs */ + if (iwl_alloc_fw_desc(nic, &nic->fw.ucode_rt.code, + pieces.inst, pieces.inst_size)) + goto err_pci_alloc; + if (iwl_alloc_fw_desc(nic, &nic->fw.ucode_rt.data, + pieces.data, pieces.data_size)) + goto err_pci_alloc; + + /* Initialization instructions and data */ + if (pieces.init_size && pieces.init_data_size) { + if (iwl_alloc_fw_desc(nic, + &nic->fw.ucode_init.code, + pieces.init, pieces.init_size)) + goto err_pci_alloc; + if (iwl_alloc_fw_desc(nic, + &nic->fw.ucode_init.data, + pieces.init_data, pieces.init_data_size)) + goto err_pci_alloc; + } + + /* WoWLAN instructions and data */ + if (pieces.wowlan_inst_size && pieces.wowlan_data_size) { + if (iwl_alloc_fw_desc(nic, + &nic->fw.ucode_wowlan.code, + pieces.wowlan_inst, + pieces.wowlan_inst_size)) + goto err_pci_alloc; + if (iwl_alloc_fw_desc(nic, + &nic->fw.ucode_wowlan.data, + pieces.wowlan_data, + pieces.wowlan_data_size)) + goto err_pci_alloc; + } + + /* Now that we can no longer fail, copy information */ + + /* + * The (size - 16) / 12 formula is based on the information recorded + * for each event, which is of mode 1 (including timestamp) for all + * new microcodes that include this information. + */ + nic->init_evtlog_ptr = pieces.init_evtlog_ptr; + if (pieces.init_evtlog_size) + nic->init_evtlog_size = (pieces.init_evtlog_size - 16)/12; + else + nic->init_evtlog_size = + cfg->base_params->max_event_log_size; + nic->init_errlog_ptr = pieces.init_errlog_ptr; + nic->inst_evtlog_ptr = pieces.inst_evtlog_ptr; + if (pieces.inst_evtlog_size) + nic->inst_evtlog_size = (pieces.inst_evtlog_size - 16)/12; + else + nic->inst_evtlog_size = + cfg->base_params->max_event_log_size; + nic->inst_errlog_ptr = pieces.inst_errlog_ptr; + + /* + * figure out the offset of chain noise reset and gain commands + * base on the size of standard phy calibration commands table size + */ + if (fw->ucode_capa.standard_phy_calibration_size > + IWL_MAX_PHY_CALIBRATE_TBL_SIZE) + fw->ucode_capa.standard_phy_calibration_size = + IWL_MAX_STANDARD_PHY_CALIBRATE_TBL_SIZE; + + /* We have our copies now, allow OS release its copies */ + release_firmware(ucode_raw); + complete(&nic->request_firmware_complete); + + nic->op_mode = iwl_dvm_ops.start(nic->shrd->trans); + + if (!nic->op_mode) + goto out_unbind; + + return; + + try_again: + /* try next, if any */ + release_firmware(ucode_raw); + if (iwl_request_firmware(nic, false)) + goto out_unbind; + return; + + err_pci_alloc: + IWL_ERR(nic, "failed to allocate pci memory\n"); + iwl_dealloc_ucode(nic); + release_firmware(ucode_raw); + out_unbind: + complete(&nic->request_firmware_complete); + device_release_driver(trans(nic)->dev); +} + int iwl_drv_start(struct iwl_shared *shrd, struct iwl_trans *trans, const struct iwl_cfg *cfg) { diff --git a/drivers/net/wireless/iwlwifi/iwl-ucode.c b/drivers/net/wireless/iwlwifi/iwl-ucode.c index 12e79d04374f..64a9c5ce5f89 100644 --- a/drivers/net/wireless/iwlwifi/iwl-ucode.c +++ b/drivers/net/wireless/iwlwifi/iwl-ucode.c @@ -28,11 +28,8 @@ *****************************************************************************/ #include -#include #include #include -#include -#include #include "iwl-ucode.h" #include "iwl-wifi.h" @@ -83,46 +80,6 @@ static struct iwl_wimax_coex_event_entry cu_priorities[COEX_NUM_OF_EVENTS] = { * ******************************************************************************/ -static void iwl_free_fw_desc(struct iwl_nic *nic, struct fw_desc *desc) -{ - if (desc->v_addr) - dma_free_coherent(trans(nic)->dev, desc->len, - desc->v_addr, desc->p_addr); - desc->v_addr = NULL; - desc->len = 0; -} - -static void iwl_free_fw_img(struct iwl_nic *nic, struct fw_img *img) -{ - iwl_free_fw_desc(nic, &img->code); - iwl_free_fw_desc(nic, &img->data); -} - -void iwl_dealloc_ucode(struct iwl_nic *nic) -{ - iwl_free_fw_img(nic, &nic->fw.ucode_rt); - iwl_free_fw_img(nic, &nic->fw.ucode_init); - iwl_free_fw_img(nic, &nic->fw.ucode_wowlan); -} - -static int iwl_alloc_fw_desc(struct iwl_nic *nic, struct fw_desc *desc, - const void *data, size_t len) -{ - if (!len) { - desc->v_addr = NULL; - return -EINVAL; - } - - desc->v_addr = dma_alloc_coherent(trans(nic)->dev, len, - &desc->p_addr, GFP_KERNEL); - if (!desc->v_addr) - return -ENOMEM; - - desc->len = len; - memcpy(desc->v_addr, data, len); - return 0; -} - static inline struct fw_img *iwl_get_ucode_image(struct iwl_nic *nic, enum iwl_ucode_type ucode_type) { @@ -685,582 +642,3 @@ int iwl_run_init_ucode(struct iwl_trans *trans) iwl_trans_stop_device(trans); return ret; } - -static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context); - -#define UCODE_EXPERIMENTAL_TAG "exp" - -int __must_check iwl_request_firmware(struct iwl_nic *nic, bool first) -{ - const struct iwl_cfg *cfg = cfg(nic); - const char *name_pre = cfg->fw_name_pre; - char tag[8]; - - if (first) { -#ifdef CONFIG_IWLWIFI_DEBUG_EXPERIMENTAL_UCODE - nic->fw_index = UCODE_EXPERIMENTAL_INDEX; - strcpy(tag, UCODE_EXPERIMENTAL_TAG); - } else if (nic->fw_index == UCODE_EXPERIMENTAL_INDEX) { -#endif - nic->fw_index = cfg->ucode_api_max; - sprintf(tag, "%d", nic->fw_index); - } else { - nic->fw_index--; - sprintf(tag, "%d", nic->fw_index); - } - - if (nic->fw_index < cfg->ucode_api_min) { - IWL_ERR(nic, "no suitable firmware found!\n"); - return -ENOENT; - } - - sprintf(nic->firmware_name, "%s%s%s", name_pre, tag, ".ucode"); - - IWL_DEBUG_INFO(nic, "attempting to load firmware %s'%s'\n", - (nic->fw_index == UCODE_EXPERIMENTAL_INDEX) - ? "EXPERIMENTAL " : "", - nic->firmware_name); - - return request_firmware_nowait(THIS_MODULE, 1, nic->firmware_name, - trans(nic)->dev, - GFP_KERNEL, nic, iwl_ucode_callback); -} - -struct iwlagn_firmware_pieces { - const void *inst, *data, *init, *init_data, *wowlan_inst, *wowlan_data; - size_t inst_size, data_size, init_size, init_data_size, - wowlan_inst_size, wowlan_data_size; - - u32 init_evtlog_ptr, init_evtlog_size, init_errlog_ptr; - u32 inst_evtlog_ptr, inst_evtlog_size, inst_errlog_ptr; -}; - -static int iwl_parse_v1_v2_firmware(struct iwl_nic *nic, - const struct firmware *ucode_raw, - struct iwlagn_firmware_pieces *pieces) -{ - struct iwl_ucode_header *ucode = (void *)ucode_raw->data; - u32 api_ver, hdr_size, build; - char buildstr[25]; - const u8 *src; - - nic->fw.ucode_ver = le32_to_cpu(ucode->ver); - api_ver = IWL_UCODE_API(nic->fw.ucode_ver); - - switch (api_ver) { - default: - hdr_size = 28; - if (ucode_raw->size < hdr_size) { - IWL_ERR(nic, "File size too small!\n"); - return -EINVAL; - } - build = le32_to_cpu(ucode->u.v2.build); - pieces->inst_size = le32_to_cpu(ucode->u.v2.inst_size); - pieces->data_size = le32_to_cpu(ucode->u.v2.data_size); - pieces->init_size = le32_to_cpu(ucode->u.v2.init_size); - pieces->init_data_size = le32_to_cpu(ucode->u.v2.init_data_size); - src = ucode->u.v2.data; - break; - case 0: - case 1: - case 2: - hdr_size = 24; - if (ucode_raw->size < hdr_size) { - IWL_ERR(nic, "File size too small!\n"); - return -EINVAL; - } - build = 0; - pieces->inst_size = le32_to_cpu(ucode->u.v1.inst_size); - pieces->data_size = le32_to_cpu(ucode->u.v1.data_size); - pieces->init_size = le32_to_cpu(ucode->u.v1.init_size); - pieces->init_data_size = le32_to_cpu(ucode->u.v1.init_data_size); - src = ucode->u.v1.data; - break; - } - - if (build) - sprintf(buildstr, " build %u%s", build, - (nic->fw_index == UCODE_EXPERIMENTAL_INDEX) - ? " (EXP)" : ""); - else - buildstr[0] = '\0'; - - snprintf(nic->fw.fw_version, - sizeof(nic->fw.fw_version), - "%u.%u.%u.%u%s", - IWL_UCODE_MAJOR(nic->fw.ucode_ver), - IWL_UCODE_MINOR(nic->fw.ucode_ver), - IWL_UCODE_API(nic->fw.ucode_ver), - IWL_UCODE_SERIAL(nic->fw.ucode_ver), - buildstr); - - /* Verify size of file vs. image size info in file's header */ - if (ucode_raw->size != hdr_size + pieces->inst_size + - pieces->data_size + pieces->init_size + - pieces->init_data_size) { - - IWL_ERR(nic, - "uCode file size %d does not match expected size\n", - (int)ucode_raw->size); - return -EINVAL; - } - - pieces->inst = src; - src += pieces->inst_size; - pieces->data = src; - src += pieces->data_size; - pieces->init = src; - src += pieces->init_size; - pieces->init_data = src; - src += pieces->init_data_size; - - return 0; -} - -static int iwl_parse_tlv_firmware(struct iwl_nic *nic, - const struct firmware *ucode_raw, - struct iwlagn_firmware_pieces *pieces, - struct iwl_ucode_capabilities *capa) -{ - struct iwl_tlv_ucode_header *ucode = (void *)ucode_raw->data; - struct iwl_ucode_tlv *tlv; - size_t len = ucode_raw->size; - const u8 *data; - int wanted_alternative = iwlagn_mod_params.wanted_ucode_alternative; - int tmp; - u64 alternatives; - u32 tlv_len; - enum iwl_ucode_tlv_type tlv_type; - const u8 *tlv_data; - char buildstr[25]; - u32 build; - - if (len < sizeof(*ucode)) { - IWL_ERR(nic, "uCode has invalid length: %zd\n", len); - return -EINVAL; - } - - if (ucode->magic != cpu_to_le32(IWL_TLV_UCODE_MAGIC)) { - IWL_ERR(nic, "invalid uCode magic: 0X%x\n", - le32_to_cpu(ucode->magic)); - return -EINVAL; - } - - /* - * Check which alternatives are present, and "downgrade" - * when the chosen alternative is not present, warning - * the user when that happens. Some files may not have - * any alternatives, so don't warn in that case. - */ - alternatives = le64_to_cpu(ucode->alternatives); - tmp = wanted_alternative; - if (wanted_alternative > 63) - wanted_alternative = 63; - while (wanted_alternative && !(alternatives & BIT(wanted_alternative))) - wanted_alternative--; - if (wanted_alternative && wanted_alternative != tmp) - IWL_WARN(nic, - "uCode alternative %d not available, choosing %d\n", - tmp, wanted_alternative); - - nic->fw.ucode_ver = le32_to_cpu(ucode->ver); - build = le32_to_cpu(ucode->build); - - if (build) - sprintf(buildstr, " build %u%s", build, - (nic->fw_index == UCODE_EXPERIMENTAL_INDEX) - ? " (EXP)" : ""); - else - buildstr[0] = '\0'; - - snprintf(nic->fw.fw_version, - sizeof(nic->fw.fw_version), - "%u.%u.%u.%u%s", - IWL_UCODE_MAJOR(nic->fw.ucode_ver), - IWL_UCODE_MINOR(nic->fw.ucode_ver), - IWL_UCODE_API(nic->fw.ucode_ver), - IWL_UCODE_SERIAL(nic->fw.ucode_ver), - buildstr); - - data = ucode->data; - - len -= sizeof(*ucode); - - while (len >= sizeof(*tlv)) { - u16 tlv_alt; - - len -= sizeof(*tlv); - tlv = (void *)data; - - tlv_len = le32_to_cpu(tlv->length); - tlv_type = le16_to_cpu(tlv->type); - tlv_alt = le16_to_cpu(tlv->alternative); - tlv_data = tlv->data; - - if (len < tlv_len) { - IWL_ERR(nic, "invalid TLV len: %zd/%u\n", - len, tlv_len); - return -EINVAL; - } - len -= ALIGN(tlv_len, 4); - data += sizeof(*tlv) + ALIGN(tlv_len, 4); - - /* - * Alternative 0 is always valid. - * - * Skip alternative TLVs that are not selected. - */ - if (tlv_alt != 0 && tlv_alt != wanted_alternative) - continue; - - switch (tlv_type) { - case IWL_UCODE_TLV_INST: - pieces->inst = tlv_data; - pieces->inst_size = tlv_len; - break; - case IWL_UCODE_TLV_DATA: - pieces->data = tlv_data; - pieces->data_size = tlv_len; - break; - case IWL_UCODE_TLV_INIT: - pieces->init = tlv_data; - pieces->init_size = tlv_len; - break; - case IWL_UCODE_TLV_INIT_DATA: - pieces->init_data = tlv_data; - pieces->init_data_size = tlv_len; - break; - case IWL_UCODE_TLV_BOOT: - IWL_ERR(nic, "Found unexpected BOOT ucode\n"); - break; - case IWL_UCODE_TLV_PROBE_MAX_LEN: - if (tlv_len != sizeof(u32)) - goto invalid_tlv_len; - capa->max_probe_length = - le32_to_cpup((__le32 *)tlv_data); - break; - case IWL_UCODE_TLV_PAN: - if (tlv_len) - goto invalid_tlv_len; - capa->flags |= IWL_UCODE_TLV_FLAGS_PAN; - break; - case IWL_UCODE_TLV_FLAGS: - /* must be at least one u32 */ - if (tlv_len < sizeof(u32)) - goto invalid_tlv_len; - /* and a proper number of u32s */ - if (tlv_len % sizeof(u32)) - goto invalid_tlv_len; - /* - * This driver only reads the first u32 as - * right now no more features are defined, - * if that changes then either the driver - * will not work with the new firmware, or - * it'll not take advantage of new features. - */ - capa->flags = le32_to_cpup((__le32 *)tlv_data); - break; - case IWL_UCODE_TLV_INIT_EVTLOG_PTR: - if (tlv_len != sizeof(u32)) - goto invalid_tlv_len; - pieces->init_evtlog_ptr = - le32_to_cpup((__le32 *)tlv_data); - break; - case IWL_UCODE_TLV_INIT_EVTLOG_SIZE: - if (tlv_len != sizeof(u32)) - goto invalid_tlv_len; - pieces->init_evtlog_size = - le32_to_cpup((__le32 *)tlv_data); - break; - case IWL_UCODE_TLV_INIT_ERRLOG_PTR: - if (tlv_len != sizeof(u32)) - goto invalid_tlv_len; - pieces->init_errlog_ptr = - le32_to_cpup((__le32 *)tlv_data); - break; - case IWL_UCODE_TLV_RUNT_EVTLOG_PTR: - if (tlv_len != sizeof(u32)) - goto invalid_tlv_len; - pieces->inst_evtlog_ptr = - le32_to_cpup((__le32 *)tlv_data); - break; - case IWL_UCODE_TLV_RUNT_EVTLOG_SIZE: - if (tlv_len != sizeof(u32)) - goto invalid_tlv_len; - pieces->inst_evtlog_size = - le32_to_cpup((__le32 *)tlv_data); - break; - case IWL_UCODE_TLV_RUNT_ERRLOG_PTR: - if (tlv_len != sizeof(u32)) - goto invalid_tlv_len; - pieces->inst_errlog_ptr = - le32_to_cpup((__le32 *)tlv_data); - break; - case IWL_UCODE_TLV_ENHANCE_SENS_TBL: - if (tlv_len) - goto invalid_tlv_len; - nic->fw.enhance_sensitivity_table = true; - break; - case IWL_UCODE_TLV_WOWLAN_INST: - pieces->wowlan_inst = tlv_data; - pieces->wowlan_inst_size = tlv_len; - break; - case IWL_UCODE_TLV_WOWLAN_DATA: - pieces->wowlan_data = tlv_data; - pieces->wowlan_data_size = tlv_len; - break; - case IWL_UCODE_TLV_PHY_CALIBRATION_SIZE: - if (tlv_len != sizeof(u32)) - goto invalid_tlv_len; - capa->standard_phy_calibration_size = - le32_to_cpup((__le32 *)tlv_data); - break; - default: - IWL_DEBUG_INFO(nic, "unknown TLV: %d\n", tlv_type); - break; - } - } - - if (len) { - IWL_ERR(nic, "invalid TLV after parsing: %zd\n", len); - iwl_print_hex_dump(nic, IWL_DL_FW, (u8 *)data, len); - return -EINVAL; - } - - return 0; - - invalid_tlv_len: - IWL_ERR(nic, "TLV %d has invalid size: %u\n", tlv_type, tlv_len); - iwl_print_hex_dump(nic, IWL_DL_FW, tlv_data, tlv_len); - - return -EINVAL; -} - -/** - * iwl_ucode_callback - callback when firmware was loaded - * - * If loaded successfully, copies the firmware into buffers - * for the card to fetch (via DMA). - */ -static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) -{ - struct iwl_nic *nic = context; - const struct iwl_cfg *cfg = cfg(nic); - struct iwl_fw *fw = &nic->fw; - struct iwl_ucode_header *ucode; - int err; - struct iwlagn_firmware_pieces pieces; - const unsigned int api_max = cfg->ucode_api_max; - unsigned int api_ok = cfg->ucode_api_ok; - const unsigned int api_min = cfg->ucode_api_min; - u32 api_ver; - - fw->ucode_capa.max_probe_length = 200; - fw->ucode_capa.standard_phy_calibration_size = - IWL_DEFAULT_STANDARD_PHY_CALIBRATE_TBL_SIZE; - - if (!api_ok) - api_ok = api_max; - - memset(&pieces, 0, sizeof(pieces)); - - if (!ucode_raw) { - if (nic->fw_index <= api_ok) - IWL_ERR(nic, - "request for firmware file '%s' failed.\n", - nic->firmware_name); - goto try_again; - } - - IWL_DEBUG_INFO(nic, "Loaded firmware file '%s' (%zd bytes).\n", - nic->firmware_name, ucode_raw->size); - - /* Make sure that we got at least the API version number */ - if (ucode_raw->size < 4) { - IWL_ERR(nic, "File size way too small!\n"); - goto try_again; - } - - /* Data from ucode file: header followed by uCode images */ - ucode = (struct iwl_ucode_header *)ucode_raw->data; - - if (ucode->ver) - err = iwl_parse_v1_v2_firmware(nic, ucode_raw, &pieces); - else - err = iwl_parse_tlv_firmware(nic, ucode_raw, &pieces, - &fw->ucode_capa); - - if (err) - goto try_again; - - api_ver = IWL_UCODE_API(nic->fw.ucode_ver); - - /* - * api_ver should match the api version forming part of the - * firmware filename ... but we don't check for that and only rely - * on the API version read from firmware header from here on forward - */ - /* no api version check required for experimental uCode */ - if (nic->fw_index != UCODE_EXPERIMENTAL_INDEX) { - if (api_ver < api_min || api_ver > api_max) { - IWL_ERR(nic, - "Driver unable to support your firmware API. " - "Driver supports v%u, firmware is v%u.\n", - api_max, api_ver); - goto try_again; - } - - if (api_ver < api_ok) { - if (api_ok != api_max) - IWL_ERR(nic, "Firmware has old API version, " - "expected v%u through v%u, got v%u.\n", - api_ok, api_max, api_ver); - else - IWL_ERR(nic, "Firmware has old API version, " - "expected v%u, got v%u.\n", - api_max, api_ver); - IWL_ERR(nic, "New firmware can be obtained from " - "http://www.intellinuxwireless.org/.\n"); - } - } - - IWL_INFO(nic, "loaded firmware version %s", nic->fw.fw_version); - - /* - * For any of the failures below (before allocating pci memory) - * we will try to load a version with a smaller API -- maybe the - * user just got a corrupted version of the latest API. - */ - - IWL_DEBUG_INFO(nic, "f/w package hdr ucode version raw = 0x%x\n", - nic->fw.ucode_ver); - IWL_DEBUG_INFO(nic, "f/w package hdr runtime inst size = %Zd\n", - pieces.inst_size); - IWL_DEBUG_INFO(nic, "f/w package hdr runtime data size = %Zd\n", - pieces.data_size); - IWL_DEBUG_INFO(nic, "f/w package hdr init inst size = %Zd\n", - pieces.init_size); - IWL_DEBUG_INFO(nic, "f/w package hdr init data size = %Zd\n", - pieces.init_data_size); - - /* Verify that uCode images will fit in card's SRAM */ - if (pieces.inst_size > cfg->max_inst_size) { - IWL_ERR(nic, "uCode instr len %Zd too large to fit in\n", - pieces.inst_size); - goto try_again; - } - - if (pieces.data_size > cfg->max_data_size) { - IWL_ERR(nic, "uCode data len %Zd too large to fit in\n", - pieces.data_size); - goto try_again; - } - - if (pieces.init_size > cfg->max_inst_size) { - IWL_ERR(nic, "uCode init instr len %Zd too large to fit in\n", - pieces.init_size); - goto try_again; - } - - if (pieces.init_data_size > cfg->max_data_size) { - IWL_ERR(nic, "uCode init data len %Zd too large to fit in\n", - pieces.init_data_size); - goto try_again; - } - - /* Allocate ucode buffers for card's bus-master loading ... */ - - /* Runtime instructions and 2 copies of data: - * 1) unmodified from disk - * 2) backup cache for save/restore during power-downs */ - if (iwl_alloc_fw_desc(nic, &nic->fw.ucode_rt.code, - pieces.inst, pieces.inst_size)) - goto err_pci_alloc; - if (iwl_alloc_fw_desc(nic, &nic->fw.ucode_rt.data, - pieces.data, pieces.data_size)) - goto err_pci_alloc; - - /* Initialization instructions and data */ - if (pieces.init_size && pieces.init_data_size) { - if (iwl_alloc_fw_desc(nic, - &nic->fw.ucode_init.code, - pieces.init, pieces.init_size)) - goto err_pci_alloc; - if (iwl_alloc_fw_desc(nic, - &nic->fw.ucode_init.data, - pieces.init_data, pieces.init_data_size)) - goto err_pci_alloc; - } - - /* WoWLAN instructions and data */ - if (pieces.wowlan_inst_size && pieces.wowlan_data_size) { - if (iwl_alloc_fw_desc(nic, - &nic->fw.ucode_wowlan.code, - pieces.wowlan_inst, - pieces.wowlan_inst_size)) - goto err_pci_alloc; - if (iwl_alloc_fw_desc(nic, - &nic->fw.ucode_wowlan.data, - pieces.wowlan_data, - pieces.wowlan_data_size)) - goto err_pci_alloc; - } - - /* Now that we can no longer fail, copy information */ - - /* - * The (size - 16) / 12 formula is based on the information recorded - * for each event, which is of mode 1 (including timestamp) for all - * new microcodes that include this information. - */ - nic->init_evtlog_ptr = pieces.init_evtlog_ptr; - if (pieces.init_evtlog_size) - nic->init_evtlog_size = (pieces.init_evtlog_size - 16)/12; - else - nic->init_evtlog_size = - cfg->base_params->max_event_log_size; - nic->init_errlog_ptr = pieces.init_errlog_ptr; - nic->inst_evtlog_ptr = pieces.inst_evtlog_ptr; - if (pieces.inst_evtlog_size) - nic->inst_evtlog_size = (pieces.inst_evtlog_size - 16)/12; - else - nic->inst_evtlog_size = - cfg->base_params->max_event_log_size; - nic->inst_errlog_ptr = pieces.inst_errlog_ptr; - - /* - * figure out the offset of chain noise reset and gain commands - * base on the size of standard phy calibration commands table size - */ - if (fw->ucode_capa.standard_phy_calibration_size > - IWL_MAX_PHY_CALIBRATE_TBL_SIZE) - fw->ucode_capa.standard_phy_calibration_size = - IWL_MAX_STANDARD_PHY_CALIBRATE_TBL_SIZE; - - /* We have our copies now, allow OS release its copies */ - release_firmware(ucode_raw); - complete(&nic->request_firmware_complete); - - nic->op_mode = iwl_dvm_ops.start(nic->shrd->trans); - - if (!nic->op_mode) - goto out_unbind; - - return; - - try_again: - /* try next, if any */ - release_firmware(ucode_raw); - if (iwl_request_firmware(nic, false)) - goto out_unbind; - return; - - err_pci_alloc: - IWL_ERR(nic, "failed to allocate pci memory\n"); - iwl_dealloc_ucode(nic); - release_firmware(ucode_raw); - out_unbind: - complete(&nic->request_firmware_complete); - device_release_driver(trans(nic)->dev); -} - diff --git a/drivers/net/wireless/iwlwifi/iwl-wifi.h b/drivers/net/wireless/iwlwifi/iwl-wifi.h index d5cba07a24c8..d157931e1e95 100644 --- a/drivers/net/wireless/iwlwifi/iwl-wifi.h +++ b/drivers/net/wireless/iwlwifi/iwl-wifi.h @@ -66,8 +66,6 @@ #include "iwl-shared.h" #include "iwl-ucode.h" -#define UCODE_EXPERIMENTAL_INDEX 100 - /** * struct iwl_nic - nic common data * @fw: the iwl_fw structure @@ -99,9 +97,6 @@ struct iwl_nic { }; -int __must_check iwl_request_firmware(struct iwl_nic *nic, bool first); -void iwl_dealloc_ucode(struct iwl_nic *nic); - int iwl_send_bt_env(struct iwl_trans *trans, u8 action, u8 type); void iwl_send_prio_tbl(struct iwl_trans *trans); int iwl_init_alive_start(struct iwl_trans *trans); -- cgit From 2e7eb117586198386e5a06d0bc4279a9d7cbaeb6 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 5 Mar 2012 11:24:51 -0800 Subject: iwlwifi: move firmware completion wait This doesn't belong into the op_mode, it has to be in the drv stop flow instead. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn.c | 2 -- drivers/net/wireless/iwlwifi/iwl-drv.c | 2 ++ 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index c3b594647def..8bb3f173bfa0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -1371,8 +1371,6 @@ static void iwl_op_mode_dvm_stop(struct iwl_op_mode *op_mode) { struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); - wait_for_completion(&nic(priv)->request_firmware_complete); - IWL_DEBUG_INFO(priv, "*** UNLOAD DRIVER ***\n"); iwl_dbgfs_unregister(priv); diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.c b/drivers/net/wireless/iwlwifi/iwl-drv.c index 343f41eb4e4f..1a588f36b591 100644 --- a/drivers/net/wireless/iwlwifi/iwl-drv.c +++ b/drivers/net/wireless/iwlwifi/iwl-drv.c @@ -720,6 +720,8 @@ int iwl_drv_start(struct iwl_shared *shrd, void iwl_drv_stop(struct iwl_shared *shrd) { + wait_for_completion(&shrd->nic->request_firmware_complete); + /* op_mode can be NULL if its start failed */ if (shrd->nic->op_mode) iwl_op_mode_stop(shrd->nic->op_mode); -- cgit From 8097e1494459a4f9cdbaba7440334d9bd11a39f0 Mon Sep 17 00:00:00 2001 From: Thomas Pedersen Date: Mon, 5 Mar 2012 15:31:47 -0800 Subject: cfg80211: expose cfg80211_calculate_bitrate() Signed-off-by: Thomas Pedersen Reviewed-by: Johannes Berg Signed-off-by: John W. Linville --- include/net/cfg80211.h | 8 ++++++++ net/wireless/util.c | 1 + 2 files changed, 9 insertions(+) diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 4682c35a92c4..57c9fddc2acf 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -3337,6 +3337,14 @@ int cfg80211_can_beacon_sec_chan(struct wiphy *wiphy, struct ieee80211_channel *chan, enum nl80211_channel_type channel_type); +/* + * cfg80211_calculate_bitrate - calculate actual bitrate (in 100Kbps units) + * @rate: given rate_info to calculate bitrate from + * + * return 0 if MCS index >= 32 + */ +u16 cfg80211_calculate_bitrate(struct rate_info *rate); + /* Logging, debugging and troubleshooting/diagnostic helpers. */ /* wiphy_printk helpers, similar to dev_printk */ diff --git a/net/wireless/util.c b/net/wireless/util.c index 9aa9db6c8141..1b7a08df933c 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c @@ -904,6 +904,7 @@ u16 cfg80211_calculate_bitrate(struct rate_info *rate) /* do NOT round down here */ return (bitrate + 50000) / 100000; } +EXPORT_SYMBOL(cfg80211_calculate_bitrate); int cfg80211_validate_beacon_int(struct cfg80211_registered_device *rdev, u32 beacon_int) -- cgit From 6b62bf326393deede630731a933713de9d574128 Mon Sep 17 00:00:00 2001 From: Thomas Pedersen Date: Mon, 5 Mar 2012 15:31:48 -0800 Subject: mac80211: fix mesh airtime link metric estimating Airtime link metric estimation was broken in HT mesh, use cfg80211_calculate_bitrate to get the right rate value. Also factor out tx rate copying from sta_set_sinfo(). Signed-off-by: Thomas Pedersen Reviewed-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/cfg.c | 23 +++++++++++++++-------- net/mac80211/mesh_hwmp.c | 6 ++++-- net/mac80211/sta_info.h | 3 +++ 3 files changed, 22 insertions(+), 10 deletions(-) diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index ab31cc56a2fb..677d65929780 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -336,6 +336,20 @@ static void rate_idx_to_bitrate(struct rate_info *rate, struct sta_info *sta, in rate->mcs = idx; } +void sta_set_rate_info_tx(struct sta_info *sta, + const struct ieee80211_tx_rate *rate, + struct rate_info *rinfo) +{ + rinfo->flags = 0; + if (rate->flags & IEEE80211_TX_RC_MCS) + rinfo->flags |= RATE_INFO_FLAGS_MCS; + if (rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) + rinfo->flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH; + if (rate->flags & IEEE80211_TX_RC_SHORT_GI) + rinfo->flags |= RATE_INFO_FLAGS_SHORT_GI; + rate_idx_to_bitrate(rinfo, sta, rate->idx); +} + static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) { struct ieee80211_sub_if_data *sdata = sta->sdata; @@ -378,14 +392,7 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) sinfo->signal_avg = (s8) -ewma_read(&sta->avg_signal); } - sinfo->txrate.flags = 0; - if (sta->last_tx_rate.flags & IEEE80211_TX_RC_MCS) - sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS; - if (sta->last_tx_rate.flags & IEEE80211_TX_RC_40_MHZ_WIDTH) - sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH; - if (sta->last_tx_rate.flags & IEEE80211_TX_RC_SHORT_GI) - sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI; - rate_idx_to_bitrate(&sinfo->txrate, sta, sta->last_tx_rate.idx); + sta_set_rate_info_tx(sta, &sta->last_tx_rate, &sinfo->txrate); sinfo->rxrate.flags = 0; if (sta->last_rx_rate_flag & RX_FLAG_HT) diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c index 4a993f2d1ae1..1c6f3d02aebf 100644 --- a/net/mac80211/mesh_hwmp.c +++ b/net/mac80211/mesh_hwmp.c @@ -324,6 +324,7 @@ static u32 airtime_link_metric_get(struct ieee80211_local *local, struct sta_info *sta) { struct ieee80211_supported_band *sband; + struct rate_info rinfo; /* This should be adjusted for each device */ int device_constant = 1 << ARITH_SHIFT; int test_frame_len = TEST_FRAME_LEN << ARITH_SHIFT; @@ -337,7 +338,9 @@ static u32 airtime_link_metric_get(struct ieee80211_local *local, if (sta->fail_avg >= 100) return MAX_METRIC; - if (sta->last_tx_rate.flags & IEEE80211_TX_RC_MCS) + sta_set_rate_info_tx(sta, &sta->last_tx_rate, &rinfo); + rate = cfg80211_calculate_bitrate(&rinfo); + if (WARN_ON(!rate)) return MAX_METRIC; err = (sta->fail_avg << ARITH_SHIFT) / 100; @@ -345,7 +348,6 @@ static u32 airtime_link_metric_get(struct ieee80211_local *local, /* bitrate is in units of 100 Kbps, while we need rate in units of * 1Mbps. This will be corrected on tx_time computation. */ - rate = sband->bitrates[sta->last_tx_rate.idx].bitrate; tx_time = (device_constant + 10 * test_frame_len / rate); estimated_retx = ((1 << (2 * ARITH_SHIFT)) / (s_unit - err)); result = (tx_time * estimated_retx) >> (2 * ARITH_SHIFT) ; diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h index 3336d54e5558..ab0576827baf 100644 --- a/net/mac80211/sta_info.h +++ b/net/mac80211/sta_info.h @@ -529,6 +529,9 @@ void sta_info_init(struct ieee80211_local *local); void sta_info_stop(struct ieee80211_local *local); int sta_info_flush(struct ieee80211_local *local, struct ieee80211_sub_if_data *sdata); +void sta_set_rate_info_tx(struct sta_info *sta, + const struct ieee80211_tx_rate *rate, + struct rate_info *rinfo); void ieee80211_sta_expire(struct ieee80211_sub_if_data *sdata, unsigned long exp_time); -- cgit From 2f40b9404903dba89d70d706ee71263f9babd109 Mon Sep 17 00:00:00 2001 From: Javier Cardona Date: Mon, 5 Mar 2012 17:20:37 -0800 Subject: mac80211_hwsim: Add tsf to beacons, probe responses and radiotap header. Generate a tsf from internal kernel clock. Prepare the path for having different tsf offsets on each phy. This will be useful for testing mesh synchronization algorithms. Signed-off-by: Javier Cardona Reviewed-by: Johannes Berg Signed-off-by: John W. Linville --- drivers/net/wireless/mac80211_hwsim.c | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index ba16f05df0fc..14a3cac19a30 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include "mac80211_hwsim.h" @@ -321,11 +322,15 @@ struct mac80211_hwsim_data { struct dentry *debugfs_group; int power_level; + + /* difference between this hw's clock and the real clock, in usecs */ + u64 tsf_offset; }; struct hwsim_radiotap_hdr { struct ieee80211_radiotap_header hdr; + __le64 rt_tsft; u8 rt_flags; u8 rt_rate; __le16 rt_channel; @@ -367,6 +372,12 @@ static netdev_tx_t hwsim_mon_xmit(struct sk_buff *skb, return NETDEV_TX_OK; } +static __le64 __mac80211_hwsim_get_tsf(struct mac80211_hwsim_data *data) +{ + struct timeval tv = ktime_to_timeval(ktime_get_real()); + u64 now = tv.tv_sec * USEC_PER_SEC + tv.tv_usec; + return cpu_to_le64(now + data->tsf_offset); +} static void mac80211_hwsim_monitor_rx(struct ieee80211_hw *hw, struct sk_buff *tx_skb) @@ -391,7 +402,9 @@ static void mac80211_hwsim_monitor_rx(struct ieee80211_hw *hw, hdr->hdr.it_len = cpu_to_le16(sizeof(*hdr)); hdr->hdr.it_present = cpu_to_le32((1 << IEEE80211_RADIOTAP_FLAGS) | (1 << IEEE80211_RADIOTAP_RATE) | + (1 << IEEE80211_RADIOTAP_TSFT) | (1 << IEEE80211_RADIOTAP_CHANNEL)); + hdr->rt_tsft = __mac80211_hwsim_get_tsf(data); hdr->rt_flags = 0; hdr->rt_rate = txrate->bitrate / 5; hdr->rt_channel = cpu_to_le16(data->channel->center_freq); @@ -610,7 +623,8 @@ static bool mac80211_hwsim_tx_frame_no_nl(struct ieee80211_hw *hw, } memset(&rx_status, 0, sizeof(rx_status)); - /* TODO: set mactime */ + rx_status.mactime = le64_to_cpu(__mac80211_hwsim_get_tsf(data)); + rx_status.flag |= RX_FLAG_MACTIME_MPDU; rx_status.freq = data->channel->center_freq; rx_status.band = data->channel->band; rx_status.rate_idx = info->control.rates[0].idx; @@ -667,6 +681,12 @@ static void mac80211_hwsim_tx(struct ieee80211_hw *hw, struct sk_buff *skb) bool ack; struct ieee80211_tx_info *txi; u32 _pid; + struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) skb->data; + struct mac80211_hwsim_data *data = hw->priv; + + if (ieee80211_is_beacon(mgmt->frame_control) || + ieee80211_is_probe_resp(mgmt->frame_control)) + mgmt->u.beacon.timestamp = __mac80211_hwsim_get_tsf(data); mac80211_hwsim_monitor_rx(hw, skb); @@ -763,9 +783,11 @@ static void mac80211_hwsim_beacon_tx(void *arg, u8 *mac, struct ieee80211_vif *vif) { struct ieee80211_hw *hw = arg; + struct mac80211_hwsim_data *data = hw->priv; struct sk_buff *skb; struct ieee80211_tx_info *info; u32 _pid; + struct ieee80211_mgmt *mgmt; hwsim_check_magic(vif); @@ -779,6 +801,9 @@ static void mac80211_hwsim_beacon_tx(void *arg, u8 *mac, return; info = IEEE80211_SKB_CB(skb); + mgmt = (struct ieee80211_mgmt *) skb->data; + mgmt->u.beacon.timestamp = __mac80211_hwsim_get_tsf(data); + mac80211_hwsim_monitor_rx(hw, skb); /* wmediumd mode check */ -- cgit From 12ce8ba3eb09bb83509a459835917a3100ad8db1 Mon Sep 17 00:00:00 2001 From: Javier Cardona Date: Mon, 5 Mar 2012 17:20:38 -0800 Subject: mac80211: Modify tsf via debugfs in mesh interfaces Signed-off-by: Javier Cardona Reviewed-by: Johannes Berg Signed-off-by: John W. Linville --- drivers/net/wireless/mac80211_hwsim.c | 18 ++++++++++++++++++ net/mac80211/debugfs_netdev.c | 7 ++++++- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index 14a3cac19a30..b4f6cb3298a4 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c @@ -379,6 +379,22 @@ static __le64 __mac80211_hwsim_get_tsf(struct mac80211_hwsim_data *data) return cpu_to_le64(now + data->tsf_offset); } +static u64 mac80211_hwsim_get_tsf(struct ieee80211_hw *hw, + struct ieee80211_vif *vif) +{ + struct mac80211_hwsim_data *data = hw->priv; + return le64_to_cpu(__mac80211_hwsim_get_tsf(data)); +} + +static void mac80211_hwsim_set_tsf(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, u64 tsf) +{ + struct mac80211_hwsim_data *data = hw->priv; + struct timeval tv = ktime_to_timeval(ktime_get_real()); + u64 now = tv.tv_sec * USEC_PER_SEC + tv.tv_usec; + data->tsf_offset = tsf - now; +} + static void mac80211_hwsim_monitor_rx(struct ieee80211_hw *hw, struct sk_buff *tx_skb) { @@ -1224,6 +1240,8 @@ static struct ieee80211_ops mac80211_hwsim_ops = .sw_scan_start = mac80211_hwsim_sw_scan, .sw_scan_complete = mac80211_hwsim_sw_scan_complete, .flush = mac80211_hwsim_flush, + .get_tsf = mac80211_hwsim_get_tsf, + .set_tsf = mac80211_hwsim_set_tsf, }; diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c index 9f484d8905fd..f6de8a65f402 100644 --- a/net/mac80211/debugfs_netdev.c +++ b/net/mac80211/debugfs_netdev.c @@ -538,11 +538,15 @@ static void add_monitor_files(struct ieee80211_sub_if_data *sdata) #ifdef CONFIG_MAC80211_MESH +static void add_mesh_files(struct ieee80211_sub_if_data *sdata) +{ + DEBUGFS_ADD_MODE(tsf, 0600); +} + static void add_mesh_stats(struct ieee80211_sub_if_data *sdata) { struct dentry *dir = debugfs_create_dir("mesh_stats", sdata->debugfs.dir); - #define MESHSTATS_ADD(name)\ debugfs_create_file(#name, 0400, dir, sdata, &name##_ops); @@ -595,6 +599,7 @@ static void add_files(struct ieee80211_sub_if_data *sdata) switch (sdata->vif.type) { case NL80211_IFTYPE_MESH_POINT: #ifdef CONFIG_MAC80211_MESH + add_mesh_files(sdata); add_mesh_stats(sdata); add_mesh_config(sdata); #endif -- cgit From 62e2c102cc1d2600381410c089ca9a37359577d2 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Tue, 6 Mar 2012 11:06:37 +0100 Subject: ath5k: do not stop queues for full calibration Some calibration types interfere with tx activity, but the queue stop does not prevent that. In fact, some calibration types need tx activity to properly function, so stopping the queues for them is counterproductive. In some tests this patch has been shown to improve stability, especially in AP or ad-hoc mode. Signed-off-by: Felix Fietkau Acked-by: Nick Kossifidis Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/base.c | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index b51d58c414d2..0e643b016b32 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -2332,15 +2332,6 @@ ath5k_calibrate_work(struct work_struct *work) "got new rfgain, resetting\n"); ieee80211_queue_work(ah->hw, &ah->reset_work); } - - /* TODO: On full calibration we should stop TX here, - * so that it doesn't interfere (mostly due to gain_f - * calibration that messes with tx packets -see phy.c). - * - * NOTE: Stopping the queues from above is not enough - * to stop TX but saves us from disconecting (at least - * we don't lose packets). */ - ieee80211_stop_queues(ah->hw); } else ah->ah_cal_mask |= AR5K_CALIBRATION_SHORT; @@ -2355,10 +2346,9 @@ ath5k_calibrate_work(struct work_struct *work) ah->curchan->center_freq)); /* Clear calibration flags */ - if (ah->ah_cal_mask & AR5K_CALIBRATION_FULL) { - ieee80211_wake_queues(ah->hw); + if (ah->ah_cal_mask & AR5K_CALIBRATION_FULL) ah->ah_cal_mask &= ~AR5K_CALIBRATION_FULL; - } else if (ah->ah_cal_mask & AR5K_CALIBRATION_SHORT) + else if (ah->ah_cal_mask & AR5K_CALIBRATION_SHORT) ah->ah_cal_mask &= ~AR5K_CALIBRATION_SHORT; } -- cgit From 5c17ddc4a047c59638c7eb8537aa887a1ddb9b0b Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Tue, 6 Mar 2012 11:06:38 +0100 Subject: ath5k: do not re-run AGC calibration periodically All other Atheros drivers run the AGC gain calibration and DC offset calibration only after reset. Running them periodically has caused stability issues on some (primarily AR2315/2413/5413/5414 based) devices, leading to messages such as: ath5k phy0: gain calibration timeout (2462MHz) ath5k phy0: calibration of channel 11 failed Related bug reports: https://dev.openwrt.org/ticket/10574 https://bugzilla.redhat.com/show_bug.cgi?id=795141 Signed-off-by: Felix Fietkau Acked-by: Nick Kossifidis Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/phy.c | 34 +++++++++------------------------- 1 file changed, 9 insertions(+), 25 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c index e1f8613426a9..3a2845489a1b 100644 --- a/drivers/net/wireless/ath/ath5k/phy.c +++ b/drivers/net/wireless/ath/ath5k/phy.c @@ -1871,31 +1871,15 @@ ath5k_hw_phy_calibrate(struct ath5k_hw *ah, ret = 0; } - /* On full calibration do an AGC calibration and - * request a PAPD probe for gainf calibration if - * needed */ - if (ah->ah_cal_mask & AR5K_CALIBRATION_FULL) { - - AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL, - AR5K_PHY_AGCCTL_CAL); - - ret = ath5k_hw_register_timeout(ah, AR5K_PHY_AGCCTL, - AR5K_PHY_AGCCTL_CAL | AR5K_PHY_AGCCTL_NF, - 0, false); - if (ret) { - ATH5K_ERR(ah, - "gain calibration timeout (%uMHz)\n", - channel->center_freq); - } - - if ((ah->ah_radio == AR5K_RF5111 || - ah->ah_radio == AR5K_RF5112) - && (channel->hw_value != AR5K_MODE_11B)) - ath5k_hw_request_rfgain_probe(ah); - } - - /* Update noise floor - * XXX: Only do this after AGC calibration */ + /* On full calibration request a PAPD probe for + * gainf calibration if needed */ + if ((ah->ah_cal_mask & AR5K_CALIBRATION_FULL) && + (ah->ah_radio == AR5K_RF5111 || + ah->ah_radio == AR5K_RF5112) && + channel->hw_value != AR5K_MODE_11B) + ath5k_hw_request_rfgain_probe(ah); + + /* Update noise floor */ if (!(ah->ah_cal_mask & AR5K_CALIBRATION_NF)) ath5k_hw_update_noise_floor(ah); -- cgit From 4ac887cfdad909f16ee1886fe4fa19b452fc7fd3 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Tue, 6 Mar 2012 15:50:47 +0100 Subject: bcma: return error in bcma_sprom_get() when fallback fails When not SPROM is available a fallback mechanism is used. However, when that fails the code currently continues. This patch assures that the bcma_sprom_get() function aborts when that happens. Cc: Rafal Milecki Cc: Hauke Mehrtens Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/bcma/sprom.c | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/drivers/bcma/sprom.c b/drivers/bcma/sprom.c index 916ae255ff64..fba8066857d2 100644 --- a/drivers/bcma/sprom.c +++ b/drivers/bcma/sprom.c @@ -49,10 +49,23 @@ int bcma_arch_register_fallback_sprom(int (*sprom_callback)(struct bcma_bus *bus static int bcma_fill_sprom_with_fallback(struct bcma_bus *bus, struct ssb_sprom *out) { - if (!get_fallback_sprom) - return -ENOENT; + int err; - return get_fallback_sprom(bus, out); + if (!get_fallback_sprom) { + err = -ENOENT; + goto fail; + } + + err = get_fallback_sprom(bus, out); + if (err) + goto fail; + + pr_debug("Using SPROM revision %d provided by" + " platform.\n", bus->sprom.revision); + return 0; +fail: + pr_warn("Using fallback SPROM failed (err %d)\n", err); + return err; } /************************************************** @@ -317,13 +330,7 @@ int bcma_sprom_get(struct bcma_bus *bus) * available for this device in some other storage. */ err = bcma_fill_sprom_with_fallback(bus, &bus->sprom); - if (err) { - pr_warn("Using fallback SPROM failed (err %d)\n", err); - } else { - pr_debug("Using SPROM revision %d provided by" - " platform.\n", bus->sprom.revision); - return 0; - } + return err; } sprom = kcalloc(SSB_SPROMSIZE_WORDS_R4, sizeof(u16), -- cgit From 10d8493cd9efd38b1947b7a74276dbdc8311aa1a Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Tue, 6 Mar 2012 15:50:48 +0100 Subject: bcma: add support for on-chip OTP memory used for SPROM storage Wireless Broadcom chips can have either their SPROM data stored on either external SPROM or on-chip OTP memory. Both are accessed through the same register space. This patch adds support for the on-chip OTP memory. Tested with: BCM43224 OTP and SPROM BCM4331 SPROM BCM4313 OTP This patch is in response to linux-wireless thread [1]. [1] http://article.gmane.org/gmane.linux.kernel.wireless.general/85426 Tested-by: Saul St. John Tested-by: Rafal Milecki Tested-by: Hauke Mehrtens Cc: Larry Finger Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/bcma/sprom.c | 126 +++++++++++++++++++++++----- include/linux/bcma/bcma_driver_chipcommon.h | 10 ++- 2 files changed, 115 insertions(+), 21 deletions(-) diff --git a/drivers/bcma/sprom.c b/drivers/bcma/sprom.c index fba8066857d2..cdcf75c0954f 100644 --- a/drivers/bcma/sprom.c +++ b/drivers/bcma/sprom.c @@ -300,37 +300,128 @@ static void bcma_sprom_extract_r8(struct bcma_bus *bus, const u16 *sprom) SSB_SROM8_FEM_ANTSWLUT_SHIFT); } -static bool bcma_is_sprom_available(struct bcma_bus *bus) +/* + * Indicates the presence of external SPROM. + */ +static bool bcma_sprom_ext_available(struct bcma_bus *bus) { - u32 sromctrl; + u32 chip_status; + u32 srom_control; + u32 present_mask; - if (!(bus->drv_cc.capabilities & BCMA_CC_CAP_SPROM)) - return false; + if (bus->drv_cc.core->id.rev >= 31) { + if (!(bus->drv_cc.capabilities & BCMA_CC_CAP_SPROM)) + return false; - if (bus->drv_cc.core->id.rev >= 32) { - sromctrl = bcma_read32(bus->drv_cc.core, BCMA_CC_SROM_CONTROL); - return sromctrl & BCMA_CC_SROM_CONTROL_PRESENT; + srom_control = bcma_read32(bus->drv_cc.core, + BCMA_CC_SROM_CONTROL); + return srom_control & BCMA_CC_SROM_CONTROL_PRESENT; } - return true; + + /* older chipcommon revisions use chip status register */ + chip_status = bcma_read32(bus->drv_cc.core, BCMA_CC_CHIPSTAT); + switch (bus->chipinfo.id) { + case 0x4313: + present_mask = BCMA_CC_CHIPST_4313_SPROM_PRESENT; + break; + + case 0x4331: + present_mask = BCMA_CC_CHIPST_4331_SPROM_PRESENT; + break; + + default: + return true; + } + + return chip_status & present_mask; +} + +/* + * Indicates that on-chip OTP memory is present and enabled. + */ +static bool bcma_sprom_onchip_available(struct bcma_bus *bus) +{ + u32 chip_status; + u32 otpsize = 0; + bool present; + + chip_status = bcma_read32(bus->drv_cc.core, BCMA_CC_CHIPSTAT); + switch (bus->chipinfo.id) { + case 0x4313: + present = chip_status & BCMA_CC_CHIPST_4313_OTP_PRESENT; + break; + + case 0x4331: + present = chip_status & BCMA_CC_CHIPST_4331_OTP_PRESENT; + break; + + case 43224: + case 43225: + /* for these chips OTP is always available */ + present = true; + break; + + default: + present = false; + break; + } + + if (present) { + otpsize = bus->drv_cc.capabilities & BCMA_CC_CAP_OTPS; + otpsize >>= BCMA_CC_CAP_OTPS_SHIFT; + } + + return otpsize != 0; +} + +/* + * Verify OTP is filled and determine the byte + * offset where SPROM data is located. + * + * On error, returns 0; byte offset otherwise. + */ +static int bcma_sprom_onchip_offset(struct bcma_bus *bus) +{ + struct bcma_device *cc = bus->drv_cc.core; + u32 offset; + + /* verify OTP status */ + if ((bcma_read32(cc, BCMA_CC_OTPS) & BCMA_CC_OTPS_GU_PROG_HW) == 0) + return 0; + + /* obtain bit offset from otplayout register */ + offset = (bcma_read32(cc, BCMA_CC_OTPL) & BCMA_CC_OTPL_GURGN_OFFSET); + return BCMA_CC_SPROM + (offset >> 3); } int bcma_sprom_get(struct bcma_bus *bus) { - u16 offset; + u16 offset = BCMA_CC_SPROM; u16 *sprom; int err = 0; if (!bus->drv_cc.core) return -EOPNOTSUPP; - if (!bcma_is_sprom_available(bus)) { + if (!bcma_sprom_ext_available(bus)) { /* - * Maybe there is no SPROM on the device? - * Now we ask the arch code if there is some sprom - * available for this device in some other storage. + * External SPROM takes precedence so check + * on-chip OTP only when no external SPROM + * is present. */ - err = bcma_fill_sprom_with_fallback(bus, &bus->sprom); - return err; + if (bcma_sprom_onchip_available(bus)) { + /* determine offset */ + offset = bcma_sprom_onchip_offset(bus); + } + if (!offset) { + /* + * Maybe there is no SPROM on the device? + * Now we ask the arch code if there is some sprom + * available for this device in some other storage. + */ + err = bcma_fill_sprom_with_fallback(bus, &bus->sprom); + return err; + } } sprom = kcalloc(SSB_SPROMSIZE_WORDS_R4, sizeof(u16), @@ -341,11 +432,6 @@ int bcma_sprom_get(struct bcma_bus *bus) if (bus->chipinfo.id == 0x4331) bcma_chipco_bcm4331_ext_pa_lines_ctl(&bus->drv_cc, false); - /* Most cards have SPROM moved by additional offset 0x30 (48 dwords). - * According to brcm80211 this applies to cards with PCIe rev >= 6 - * TODO: understand this condition and use it */ - offset = (bus->chipinfo.id == 0x4331) ? BCMA_CC_SPROM : - BCMA_CC_SPROM_PCIE6; pr_debug("SPROM offset 0x%x\n", offset); bcma_sprom_read(bus, offset, sprom); diff --git a/include/linux/bcma/bcma_driver_chipcommon.h b/include/linux/bcma/bcma_driver_chipcommon.h index e72938b10714..8bbfe31fbac8 100644 --- a/include/linux/bcma/bcma_driver_chipcommon.h +++ b/include/linux/bcma/bcma_driver_chipcommon.h @@ -56,6 +56,9 @@ #define BCMA_CC_OTPS_HW_PROTECT 0x00000001 #define BCMA_CC_OTPS_SW_PROTECT 0x00000002 #define BCMA_CC_OTPS_CID_PROTECT 0x00000004 +#define BCMA_CC_OTPS_GU_PROG_IND 0x00000F00 /* General Use programmed indication */ +#define BCMA_CC_OTPS_GU_PROG_IND_SHIFT 8 +#define BCMA_CC_OTPS_GU_PROG_HW 0x00000100 /* HW region programmed */ #define BCMA_CC_OTPC 0x0014 /* OTP control */ #define BCMA_CC_OTPC_RECWAIT 0xFF000000 #define BCMA_CC_OTPC_PROGWAIT 0x00FFFF00 @@ -72,6 +75,8 @@ #define BCMA_CC_OTPP_READ 0x40000000 #define BCMA_CC_OTPP_START 0x80000000 #define BCMA_CC_OTPP_BUSY 0x80000000 +#define BCMA_CC_OTPL 0x001C /* OTP layout */ +#define BCMA_CC_OTPL_GURGN_OFFSET 0x00000FFF /* offset of general use region */ #define BCMA_CC_IRQSTAT 0x0020 #define BCMA_CC_IRQMASK 0x0024 #define BCMA_CC_IRQ_GPIO 0x00000001 /* gpio intr */ @@ -79,6 +84,10 @@ #define BCMA_CC_IRQ_WDRESET 0x80000000 /* watchdog reset occurred */ #define BCMA_CC_CHIPCTL 0x0028 /* Rev >= 11 only */ #define BCMA_CC_CHIPSTAT 0x002C /* Rev >= 11 only */ +#define BCMA_CC_CHIPST_4313_SPROM_PRESENT 1 +#define BCMA_CC_CHIPST_4313_OTP_PRESENT 2 +#define BCMA_CC_CHIPST_4331_SPROM_PRESENT 2 +#define BCMA_CC_CHIPST_4331_OTP_PRESENT 4 #define BCMA_CC_JCMD 0x0030 /* Rev >= 10 only */ #define BCMA_CC_JCMD_START 0x80000000 #define BCMA_CC_JCMD_BUSY 0x80000000 @@ -256,7 +265,6 @@ #define BCMA_CC_PLLCTL_ADDR 0x0660 #define BCMA_CC_PLLCTL_DATA 0x0664 #define BCMA_CC_SPROM 0x0800 /* SPROM beginning */ -#define BCMA_CC_SPROM_PCIE6 0x0830 /* SPROM beginning on PCIe rev >= 6 */ /* Divider allocation in 4716/47162/5356 */ #define BCMA_CC_PMU5_MAINPLL_CPU 1 -- cgit From c3b1e1e8a76fdaa507daaa95ba7bd1d8d0c74b6b Mon Sep 17 00:00:00 2001 From: Samuel Ortiz Date: Mon, 5 Mar 2012 01:03:33 +0100 Subject: NFC: Export NFCID1 from pn533 Signed-off-by: Samuel Ortiz Signed-off-by: John W. Linville --- drivers/nfc/pn533.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/nfc/pn533.c b/drivers/nfc/pn533.c index 1a1500bc8452..8be0ae626d73 100644 --- a/drivers/nfc/pn533.c +++ b/drivers/nfc/pn533.c @@ -736,6 +736,8 @@ static int pn533_target_found_type_a(struct nfc_target *nfc_tgt, u8 *tgt_data, nfc_tgt->sens_res = be16_to_cpu(tgt_type_a->sens_res); nfc_tgt->sel_res = tgt_type_a->sel_res; + nfc_tgt->nfcid1_len = tgt_type_a->nfcid_len; + memcpy(nfc_tgt->nfcid1, tgt_type_a->nfcid_data, nfc_tgt->nfcid1_len); return 0; } -- cgit From c970a1ac4e75a5d31c7b6e8e9f0bb192b0a511e7 Mon Sep 17 00:00:00 2001 From: Samuel Ortiz Date: Mon, 5 Mar 2012 01:03:34 +0100 Subject: NFC: Add device powered netlink attribute For user space to know if a device is up or down. Signed-off-by: Samuel Ortiz Signed-off-by: John W. Linville --- include/linux/nfc.h | 1 + net/nfc/netlink.c | 3 +++ 2 files changed, 4 insertions(+) diff --git a/include/linux/nfc.h b/include/linux/nfc.h index b4999abcb2a2..39c1fcf089c0 100644 --- a/include/linux/nfc.h +++ b/include/linux/nfc.h @@ -107,6 +107,7 @@ enum nfc_attrs { NFC_ATTR_TARGET_SENSF_RES, NFC_ATTR_COMM_MODE, NFC_ATTR_RF_MODE, + NFC_ATTR_DEVICE_POWERED, /* private: internal use only */ __NFC_ATTR_AFTER_LAST }; diff --git a/net/nfc/netlink.c b/net/nfc/netlink.c index 07f0348aabf5..a1388e4efd6f 100644 --- a/net/nfc/netlink.c +++ b/net/nfc/netlink.c @@ -48,6 +48,7 @@ static const struct nla_policy nfc_genl_policy[NFC_ATTR_MAX + 1] = { [NFC_ATTR_PROTOCOLS] = { .type = NLA_U32 }, [NFC_ATTR_COMM_MODE] = { .type = NLA_U8 }, [NFC_ATTR_RF_MODE] = { .type = NLA_U8 }, + [NFC_ATTR_DEVICE_POWERED] = { .type = NLA_U8 }, }; static int nfc_genl_send_target(struct sk_buff *msg, struct nfc_target *target, @@ -200,6 +201,7 @@ int nfc_genl_device_added(struct nfc_dev *dev) NLA_PUT_STRING(msg, NFC_ATTR_DEVICE_NAME, nfc_device_name(dev)); NLA_PUT_U32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx); NLA_PUT_U32(msg, NFC_ATTR_PROTOCOLS, dev->supported_protocols); + NLA_PUT_U8(msg, NFC_ATTR_DEVICE_POWERED, dev->dev_up); genlmsg_end(msg, hdr); @@ -261,6 +263,7 @@ static int nfc_genl_send_device(struct sk_buff *msg, struct nfc_dev *dev, NLA_PUT_STRING(msg, NFC_ATTR_DEVICE_NAME, nfc_device_name(dev)); NLA_PUT_U32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx); NLA_PUT_U32(msg, NFC_ATTR_PROTOCOLS, dev->supported_protocols); + NLA_PUT_U8(msg, NFC_ATTR_DEVICE_POWERED, dev->dev_up); return genlmsg_end(msg, hdr); -- cgit From 4722d2b70b80098e1e429e093a7e04aad360260a Mon Sep 17 00:00:00 2001 From: Samuel Ortiz Date: Mon, 5 Mar 2012 01:03:35 +0100 Subject: NFC: Factorize the I frame queueing routine This one will be called from the I frame command sending. Signed-off-by: Samuel Ortiz Signed-off-by: John W. Linville --- net/nfc/llcp/llcp.c | 45 ++++++++++++++++++++++++++++----------------- net/nfc/llcp/llcp.h | 1 + 2 files changed, 29 insertions(+), 17 deletions(-) diff --git a/net/nfc/llcp/llcp.c b/net/nfc/llcp/llcp.c index 1d32680807d6..8510a2fb3da8 100644 --- a/net/nfc/llcp/llcp.c +++ b/net/nfc/llcp/llcp.c @@ -616,6 +616,33 @@ fail: } +void nfc_llcp_queue_i_frames(struct nfc_llcp_sock *sock) +{ + struct nfc_llcp_local *local = sock->local; + + pr_debug("Remote ready %d tx queue len %d remote rw %d", + sock->remote_ready, skb_queue_len(&sock->tx_pending_queue), + local->remote_rw); + + /* Try to queue some I frames for transmission */ + while (sock->remote_ready && + skb_queue_len(&sock->tx_pending_queue) < local->remote_rw) { + struct sk_buff *pdu, *pending_pdu; + + pdu = skb_dequeue(&sock->tx_queue); + if (pdu == NULL) + break; + + /* Update N(S)/N(R) */ + nfc_llcp_set_nrns(sock, pdu); + + pending_pdu = skb_clone(pdu, GFP_KERNEL); + + skb_queue_tail(&local->tx_queue, pdu); + skb_queue_tail(&sock->tx_pending_queue, pending_pdu); + } +} + static void nfc_llcp_recv_hdlc(struct nfc_llcp_local *local, struct sk_buff *skb) { @@ -673,23 +700,7 @@ static void nfc_llcp_recv_hdlc(struct nfc_llcp_local *local, } } - /* Queue some I frames for transmission */ - while (llcp_sock->remote_ready && - skb_queue_len(&llcp_sock->tx_pending_queue) <= local->remote_rw) { - struct sk_buff *pdu, *pending_pdu; - - pdu = skb_dequeue(&llcp_sock->tx_queue); - if (pdu == NULL) - break; - - /* Update N(S)/N(R) */ - nfc_llcp_set_nrns(llcp_sock, pdu); - - pending_pdu = skb_clone(pdu, GFP_KERNEL); - - skb_queue_tail(&local->tx_queue, pdu); - skb_queue_tail(&llcp_sock->tx_pending_queue, pending_pdu); - } + nfc_llcp_queue_i_frames(llcp_sock); release_sock(sk); nfc_llcp_sock_put(llcp_sock); diff --git a/net/nfc/llcp/llcp.h b/net/nfc/llcp/llcp.h index 0ad2e3361584..0a72ee627641 100644 --- a/net/nfc/llcp/llcp.h +++ b/net/nfc/llcp/llcp.h @@ -165,6 +165,7 @@ u8 nfc_llcp_get_sdp_ssap(struct nfc_llcp_local *local, struct nfc_llcp_sock *sock); u8 nfc_llcp_get_local_ssap(struct nfc_llcp_local *local); void nfc_llcp_put_ssap(struct nfc_llcp_local *local, u8 ssap); +void nfc_llcp_queue_i_frames(struct nfc_llcp_sock *sock); /* Sock API */ struct sock *nfc_llcp_sock_alloc(struct socket *sock, int type, gfp_t gfp); -- cgit From 53aef92054e7fbffe66d3e2f95d122f39a33c211 Mon Sep 17 00:00:00 2001 From: Samuel Ortiz Date: Mon, 5 Mar 2012 01:03:36 +0100 Subject: NFC: Handle Receiver Not Ready LLCP frame Signed-off-by: Samuel Ortiz Signed-off-by: John W. Linville --- net/nfc/llcp/llcp.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/net/nfc/llcp/llcp.c b/net/nfc/llcp/llcp.c index 8510a2fb3da8..bbfaa2750ea8 100644 --- a/net/nfc/llcp/llcp.c +++ b/net/nfc/llcp/llcp.c @@ -671,15 +671,15 @@ static void nfc_llcp_recv_hdlc(struct nfc_llcp_local *local, nfc_llcp_sock_put(llcp_sock); } - if (ns == llcp_sock->recv_n) - llcp_sock->recv_n = (llcp_sock->recv_n + 1) % 16; - else - pr_err("Received out of sequence I PDU\n"); - /* Pass the payload upstream */ if (ptype == LLCP_PDU_I) { pr_debug("I frame, queueing on %p\n", &llcp_sock->sk); + if (ns == llcp_sock->recv_n) + llcp_sock->recv_n = (llcp_sock->recv_n + 1) % 16; + else + pr_err("Received out of sequence I PDU\n"); + skb_pull(skb, LLCP_HEADER_SIZE + LLCP_SEQUENCE_SIZE); if (sock_queue_rcv_skb(&llcp_sock->sk, skb)) { pr_err("receive queue is full\n"); @@ -700,6 +700,11 @@ static void nfc_llcp_recv_hdlc(struct nfc_llcp_local *local, } } + if (ptype == LLCP_PDU_RR) + llcp_sock->remote_ready = true; + else if (ptype == LLCP_PDU_RNR) + llcp_sock->remote_ready = false; + nfc_llcp_queue_i_frames(llcp_sock); release_sock(sk); @@ -813,6 +818,7 @@ static void nfc_llcp_rx_work(struct work_struct *work) case LLCP_PDU_I: case LLCP_PDU_RR: + case LLCP_PDU_RNR: pr_debug("I frame\n"); nfc_llcp_recv_hdlc(local, skb); break; -- cgit From 53a0ac2ee810cf82ec374b686a1dc3c32399265a Mon Sep 17 00:00:00 2001 From: Samuel Ortiz Date: Mon, 5 Mar 2012 01:03:37 +0100 Subject: NFC: LLCP socket sendmsg implemetation Signed-off-by: Samuel Ortiz Signed-off-by: John W. Linville --- net/nfc/llcp/commands.c | 31 +++++++++++++++++++++++++++++++ net/nfc/llcp/llcp.h | 2 ++ net/nfc/llcp/sock.c | 30 +++++++++++++++++++++++++++++- 3 files changed, 62 insertions(+), 1 deletion(-) diff --git a/net/nfc/llcp/commands.c b/net/nfc/llcp/commands.c index 151f2ef429c4..f6c2257c11aa 100644 --- a/net/nfc/llcp/commands.c +++ b/net/nfc/llcp/commands.c @@ -397,3 +397,34 @@ int nfc_llcp_send_disconnect(struct nfc_llcp_sock *sock) return 0; } + +int nfc_llcp_send_i_frame(struct nfc_llcp_sock *sock, + struct msghdr *msg, size_t len) +{ + struct sk_buff *pdu; + struct sock *sk; + + pr_debug("Send I frame\n"); + + pdu = llcp_allocate_pdu(sock, LLCP_PDU_I, len + LLCP_SEQUENCE_SIZE); + if (pdu == NULL) + return -ENOMEM; + + skb_put(pdu, LLCP_SEQUENCE_SIZE); + + if (memcpy_fromiovec(skb_put(pdu, len), msg->msg_iov, len)) { + kfree_skb(pdu); + return -EFAULT; + } + + skb_queue_head(&sock->tx_queue, pdu); + + sk = &sock->sk; + lock_sock(sk); + + nfc_llcp_queue_i_frames(sock); + + release_sock(sk); + + return 0; +} diff --git a/net/nfc/llcp/llcp.h b/net/nfc/llcp/llcp.h index 0a72ee627641..36d8572c8beb 100644 --- a/net/nfc/llcp/llcp.h +++ b/net/nfc/llcp/llcp.h @@ -188,6 +188,8 @@ int nfc_llcp_send_connect(struct nfc_llcp_sock *sock); int nfc_llcp_send_cc(struct nfc_llcp_sock *sock); int nfc_llcp_send_dm(struct nfc_llcp_local *local, u8 ssap, u8 dsap, u8 reason); int nfc_llcp_send_disconnect(struct nfc_llcp_sock *sock); +int nfc_llcp_send_i_frame(struct nfc_llcp_sock *sock, + struct msghdr *msg, size_t len); /* Socket API */ int __init nfc_llcp_sock_init(void); diff --git a/net/nfc/llcp/sock.c b/net/nfc/llcp/sock.c index f738ccd535f1..b8bef367ee49 100644 --- a/net/nfc/llcp/sock.c +++ b/net/nfc/llcp/sock.c @@ -482,6 +482,34 @@ error: return ret; } +static int llcp_sock_sendmsg(struct kiocb *iocb, struct socket *sock, + struct msghdr *msg, size_t len) +{ + struct sock *sk = sock->sk; + struct nfc_llcp_sock *llcp_sock = nfc_llcp_sock(sk); + int ret; + + pr_debug("sock %p sk %p", sock, sk); + + ret = sock_error(sk); + if (ret) + return ret; + + if (msg->msg_flags & MSG_OOB) + return -EOPNOTSUPP; + + lock_sock(sk); + + if (sk->sk_state != LLCP_CONNECTED) { + release_sock(sk); + return -ENOTCONN; + } + + release_sock(sk); + + return nfc_llcp_send_i_frame(llcp_sock, msg, len); +} + static int llcp_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len, int flags) { @@ -567,7 +595,7 @@ static const struct proto_ops llcp_sock_ops = { .shutdown = sock_no_shutdown, .setsockopt = sock_no_setsockopt, .getsockopt = sock_no_getsockopt, - .sendmsg = sock_no_sendmsg, + .sendmsg = llcp_sock_sendmsg, .recvmsg = llcp_sock_recvmsg, .mmap = sock_no_mmap, }; -- cgit From 1762c17c9c38ed21090bee8cd02e2b470c5c2308 Mon Sep 17 00:00:00 2001 From: Samuel Ortiz Date: Mon, 5 Mar 2012 01:03:38 +0100 Subject: NFC: Fix bitops usage in LLCP Signed-off-by: Samuel Ortiz Signed-off-by: John W. Linville --- net/nfc/llcp/llcp.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/net/nfc/llcp/llcp.c b/net/nfc/llcp/llcp.c index bbfaa2750ea8..443407e964ca 100644 --- a/net/nfc/llcp/llcp.c +++ b/net/nfc/llcp/llcp.c @@ -176,7 +176,7 @@ u8 nfc_llcp_get_sdp_ssap(struct nfc_llcp_local *local, return LLCP_SAP_MAX; } - set_bit(BIT(ssap), &local->local_wks); + set_bit(ssap, &local->local_wks); mutex_unlock(&local->sdp_lock); return ssap; @@ -195,25 +195,25 @@ u8 nfc_llcp_get_sdp_ssap(struct nfc_llcp_local *local, pr_debug("SDP ssap %d\n", LLCP_WKS_NUM_SAP + ssap); - set_bit(BIT(ssap), &local->local_sdp); + set_bit(ssap, &local->local_sdp); mutex_unlock(&local->sdp_lock); return LLCP_WKS_NUM_SAP + ssap; } else if (sock->ssap != 0) { if (sock->ssap < LLCP_WKS_NUM_SAP) { - if (!(local->local_wks & BIT(sock->ssap))) { - set_bit(BIT(sock->ssap), &local->local_wks); + if (!test_bit(sock->ssap, &local->local_wks)) { + set_bit(sock->ssap, &local->local_wks); mutex_unlock(&local->sdp_lock); return sock->ssap; } } else if (sock->ssap < LLCP_SDP_NUM_SAP) { - if (!(local->local_sdp & - BIT(sock->ssap - LLCP_WKS_NUM_SAP))) { - set_bit(BIT(sock->ssap - LLCP_WKS_NUM_SAP), - &local->local_sdp); + if (!test_bit(sock->ssap - LLCP_WKS_NUM_SAP, + &local->local_sdp)) { + set_bit(sock->ssap - LLCP_WKS_NUM_SAP, + &local->local_sdp); mutex_unlock(&local->sdp_lock); return sock->ssap; @@ -238,7 +238,7 @@ u8 nfc_llcp_get_local_ssap(struct nfc_llcp_local *local) return LLCP_SAP_MAX; } - set_bit(BIT(local_ssap), &local->local_sap); + set_bit(local_ssap, &local->local_sap); mutex_unlock(&local->sdp_lock); @@ -265,7 +265,7 @@ void nfc_llcp_put_ssap(struct nfc_llcp_local *local, u8 ssap) mutex_lock(&local->sdp_lock); - clear_bit(1 << local_ssap, sdp); + clear_bit(local_ssap, sdp); mutex_unlock(&local->sdp_lock); } -- cgit From 98b3ac1b980b0c0ffff24fda8d13ab8c216df4d1 Mon Sep 17 00:00:00 2001 From: Samuel Ortiz Date: Mon, 5 Mar 2012 01:03:39 +0100 Subject: NFC: Clear pn533 target structure The polled target structure should be memset to 0 in order to avoid sel_res and sens_res garbage. Signed-off-by: Samuel Ortiz Signed-off-by: John W. Linville --- drivers/nfc/pn533.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/nfc/pn533.c b/drivers/nfc/pn533.c index 8be0ae626d73..a5766042f0ee 100644 --- a/drivers/nfc/pn533.c +++ b/drivers/nfc/pn533.c @@ -904,6 +904,8 @@ static int pn533_target_found(struct pn533 *dev, if (resp->tg != 1) return -EPROTO; + memset(&nfc_tgt, 0, sizeof(struct nfc_target)); + target_data_len = resp_len - sizeof(struct pn533_poll_response); switch (dev->poll_mod_curr) { -- cgit From b9a76f1d3c6da47b2fa115ff1c0de229e8d06f8f Mon Sep 17 00:00:00 2001 From: Samuel Ortiz Date: Mon, 5 Mar 2012 01:03:40 +0100 Subject: NFC: Clear LLCP SDPs whan MAC goes down Signed-off-by: Samuel Ortiz Signed-off-by: John W. Linville --- net/nfc/llcp/llcp.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/net/nfc/llcp/llcp.c b/net/nfc/llcp/llcp.c index 443407e964ca..577bcb92ea9b 100644 --- a/net/nfc/llcp/llcp.c +++ b/net/nfc/llcp/llcp.c @@ -97,6 +97,17 @@ static void nfc_llcp_socket_release(struct nfc_llcp_local *local) mutex_unlock(&local->socket_lock); } +static void nfc_llcp_clear_sdp(struct nfc_llcp_local *local) +{ + mutex_lock(&local->sdp_lock); + + local->local_wks = 0; + local->local_sdp = 0; + local->local_sap = 0; + + mutex_unlock(&local->sdp_lock); +} + static void nfc_llcp_timeout_work(struct work_struct *work) { struct nfc_llcp_local *local = container_of(work, struct nfc_llcp_local, @@ -857,6 +868,8 @@ void nfc_llcp_mac_is_down(struct nfc_dev *dev) if (local == NULL) return; + nfc_llcp_clear_sdp(local); + /* Close and purge all existing sockets */ nfc_llcp_socket_release(local); } -- cgit From 0767a7fa87ff18f6a11e3de954c5386a45b9d96e Mon Sep 17 00:00:00 2001 From: Samuel Ortiz Date: Mon, 5 Mar 2012 01:03:41 +0100 Subject: NFC: Set the right LLCP N(R) value for I frames Signed-off-by: Samuel Ortiz Signed-off-by: John W. Linville --- net/nfc/llcp/llcp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/nfc/llcp/llcp.c b/net/nfc/llcp/llcp.c index 577bcb92ea9b..2506810cd780 100644 --- a/net/nfc/llcp/llcp.c +++ b/net/nfc/llcp/llcp.c @@ -419,7 +419,7 @@ static u8 nfc_llcp_nr(struct sk_buff *pdu) static void nfc_llcp_set_nrns(struct nfc_llcp_sock *sock, struct sk_buff *pdu) { - pdu->data[2] = (sock->send_n << 4) | ((sock->recv_n - 1) % 16); + pdu->data[2] = (sock->send_n << 4) | (sock->recv_n % 16); sock->send_n = (sock->send_n + 1) % 16; sock->recv_ack_n = (sock->recv_n - 1) % 16; } -- cgit From d094afa155273e03b82981ea818d39c7a2dfba86 Mon Sep 17 00:00:00 2001 From: Samuel Ortiz Date: Mon, 5 Mar 2012 01:03:42 +0100 Subject: NFC: Send LLCP RR frames to acknowledge received I frames In order to acknowledge an I frame, we have to either queue pending local I frames or queue a receiver ready frame. Signed-off-by: Samuel Ortiz Signed-off-by: John W. Linville --- net/nfc/llcp/commands.c | 24 ++++++++++++++++++++++++ net/nfc/llcp/llcp.c | 9 +++++++-- net/nfc/llcp/llcp.h | 3 ++- 3 files changed, 33 insertions(+), 3 deletions(-) diff --git a/net/nfc/llcp/commands.c b/net/nfc/llcp/commands.c index f6c2257c11aa..8ebd322b11eb 100644 --- a/net/nfc/llcp/commands.c +++ b/net/nfc/llcp/commands.c @@ -428,3 +428,27 @@ int nfc_llcp_send_i_frame(struct nfc_llcp_sock *sock, return 0; } + +int nfc_llcp_send_rr(struct nfc_llcp_sock *sock) +{ + struct sk_buff *skb; + struct nfc_llcp_local *local; + + pr_debug("Send rr nr %d\n", sock->recv_n); + + local = sock->local; + if (local == NULL) + return -ENODEV; + + skb = llcp_allocate_pdu(sock, LLCP_PDU_RR, LLCP_SEQUENCE_SIZE); + if (skb == NULL) + return -ENOMEM; + + skb_put(skb, LLCP_SEQUENCE_SIZE); + + skb->data[2] = sock->recv_n % 16; + + skb_queue_head(&local->tx_queue, skb); + + return 0; +} diff --git a/net/nfc/llcp/llcp.c b/net/nfc/llcp/llcp.c index 2506810cd780..a0cb133c610a 100644 --- a/net/nfc/llcp/llcp.c +++ b/net/nfc/llcp/llcp.c @@ -627,8 +627,9 @@ fail: } -void nfc_llcp_queue_i_frames(struct nfc_llcp_sock *sock) +int nfc_llcp_queue_i_frames(struct nfc_llcp_sock *sock) { + int nr_frames = 0; struct nfc_llcp_local *local = sock->local; pr_debug("Remote ready %d tx queue len %d remote rw %d", @@ -651,7 +652,10 @@ void nfc_llcp_queue_i_frames(struct nfc_llcp_sock *sock) skb_queue_tail(&local->tx_queue, pdu); skb_queue_tail(&sock->tx_pending_queue, pending_pdu); + nr_frames++; } + + return nr_frames; } static void nfc_llcp_recv_hdlc(struct nfc_llcp_local *local, @@ -716,7 +720,8 @@ static void nfc_llcp_recv_hdlc(struct nfc_llcp_local *local, else if (ptype == LLCP_PDU_RNR) llcp_sock->remote_ready = false; - nfc_llcp_queue_i_frames(llcp_sock); + if (nfc_llcp_queue_i_frames(llcp_sock) == 0) + nfc_llcp_send_rr(llcp_sock); release_sock(sk); nfc_llcp_sock_put(llcp_sock); diff --git a/net/nfc/llcp/llcp.h b/net/nfc/llcp/llcp.h index 36d8572c8beb..054c64ffdaa7 100644 --- a/net/nfc/llcp/llcp.h +++ b/net/nfc/llcp/llcp.h @@ -165,7 +165,7 @@ u8 nfc_llcp_get_sdp_ssap(struct nfc_llcp_local *local, struct nfc_llcp_sock *sock); u8 nfc_llcp_get_local_ssap(struct nfc_llcp_local *local); void nfc_llcp_put_ssap(struct nfc_llcp_local *local, u8 ssap); -void nfc_llcp_queue_i_frames(struct nfc_llcp_sock *sock); +int nfc_llcp_queue_i_frames(struct nfc_llcp_sock *sock); /* Sock API */ struct sock *nfc_llcp_sock_alloc(struct socket *sock, int type, gfp_t gfp); @@ -190,6 +190,7 @@ int nfc_llcp_send_dm(struct nfc_llcp_local *local, u8 ssap, u8 dsap, u8 reason); int nfc_llcp_send_disconnect(struct nfc_llcp_sock *sock); int nfc_llcp_send_i_frame(struct nfc_llcp_sock *sock, struct msghdr *msg, size_t len); +int nfc_llcp_send_rr(struct nfc_llcp_sock *sock); /* Socket API */ int __init nfc_llcp_sock_init(void); -- cgit From eda21f16a5ed2476c1740e83a7dfaae34d893d9b Mon Sep 17 00:00:00 2001 From: Samuel Ortiz Date: Mon, 5 Mar 2012 01:03:43 +0100 Subject: NFC: Set MIU and RW values from CONNECT and CC LLCP frames We use the maximum values for the LLCP Maximum Information Unit and Receive Window Size. Signed-off-by: Samuel Ortiz Signed-off-by: John W. Linville --- net/nfc/llcp/commands.c | 48 +++++++++++++++++++++++++++++++++++++++++++++--- net/nfc/llcp/llcp.h | 4 ++++ 2 files changed, 49 insertions(+), 3 deletions(-) diff --git a/net/nfc/llcp/commands.c b/net/nfc/llcp/commands.c index 8ebd322b11eb..a02292ba25c7 100644 --- a/net/nfc/llcp/commands.c +++ b/net/nfc/llcp/commands.c @@ -284,6 +284,9 @@ int nfc_llcp_send_connect(struct nfc_llcp_sock *sock) struct nfc_llcp_local *local; struct sk_buff *skb; u8 *service_name_tlv = NULL, service_name_tlv_length; + u8 *miux_tlv = NULL, miux_tlv_length; + u8 *rw_tlv = NULL, rw_tlv_length, rw; + __be16 miux; int err; u16 size = 0; @@ -301,6 +304,14 @@ int nfc_llcp_send_connect(struct nfc_llcp_sock *sock) size += service_name_tlv_length; } + miux = cpu_to_be16(LLCP_MAX_MIUX); + miux_tlv = nfc_llcp_build_tlv(LLCP_TLV_MIUX, (u8 *)&miux, 0, &miux_tlv_length); + size += miux_tlv_length; + + rw = LLCP_MAX_RW; + rw_tlv = nfc_llcp_build_tlv(LLCP_TLV_RW, &rw, 0, &rw_tlv_length); + size += rw_tlv_length; + pr_debug("SKB size %d SN length %zu\n", size, sock->service_name_len); skb = llcp_allocate_pdu(sock, LLCP_PDU_CONNECT, size); @@ -313,6 +324,9 @@ int nfc_llcp_send_connect(struct nfc_llcp_sock *sock) skb = llcp_add_tlv(skb, service_name_tlv, service_name_tlv_length); + skb = llcp_add_tlv(skb, miux_tlv, miux_tlv_length); + skb = llcp_add_tlv(skb, rw_tlv, rw_tlv_length); + skb_queue_tail(&local->tx_queue, skb); return 0; @@ -321,6 +335,8 @@ error_tlv: pr_err("error %d\n", err); kfree(service_name_tlv); + kfree(miux_tlv); + kfree(rw_tlv); return err; } @@ -329,6 +345,11 @@ int nfc_llcp_send_cc(struct nfc_llcp_sock *sock) { struct nfc_llcp_local *local; struct sk_buff *skb; + u8 *miux_tlv = NULL, miux_tlv_length; + u8 *rw_tlv = NULL, rw_tlv_length, rw; + __be16 miux; + int err; + u16 size = 0; pr_debug("Sending CC\n"); @@ -336,13 +357,34 @@ int nfc_llcp_send_cc(struct nfc_llcp_sock *sock) if (local == NULL) return -ENODEV; - skb = llcp_allocate_pdu(sock, LLCP_PDU_CC, 0); - if (skb == NULL) - return -ENOMEM; + miux = cpu_to_be16(LLCP_MAX_MIUX); + miux_tlv = nfc_llcp_build_tlv(LLCP_TLV_MIUX, (u8 *)&miux, 0, &miux_tlv_length); + size += miux_tlv_length; + + rw = LLCP_MAX_RW; + rw_tlv = nfc_llcp_build_tlv(LLCP_TLV_RW, &rw, 0, &rw_tlv_length); + size += rw_tlv_length; + + skb = llcp_allocate_pdu(sock, LLCP_PDU_CC, size); + if (skb == NULL) { + err = -ENOMEM; + goto error_tlv; + } + + skb = llcp_add_tlv(skb, miux_tlv, miux_tlv_length); + skb = llcp_add_tlv(skb, rw_tlv, rw_tlv_length); skb_queue_tail(&local->tx_queue, skb); return 0; + +error_tlv: + pr_err("error %d\n", err); + + kfree(miux_tlv); + kfree(rw_tlv); + + return err; } int nfc_llcp_send_dm(struct nfc_llcp_local *local, u8 ssap, u8 dsap, u8 reason) diff --git a/net/nfc/llcp/llcp.h b/net/nfc/llcp/llcp.h index 054c64ffdaa7..70e1762d6e8d 100644 --- a/net/nfc/llcp/llcp.h +++ b/net/nfc/llcp/llcp.h @@ -28,6 +28,10 @@ enum llcp_state { #define LLCP_DEFAULT_RW 1 #define LLCP_DEFAULT_MIU 128 +#define LLCP_MAX_LTO 0xff +#define LLCP_MAX_RW 15 +#define LLCP_MAX_MIUX 0x7ff + #define LLCP_WKS_NUM_SAP 16 #define LLCP_SDP_NUM_SAP 16 #define LLCP_LOCAL_NUM_SAP 32 -- cgit From e65b0f46edfda746ba8c66ada28ccb97c682b7c0 Mon Sep 17 00:00:00 2001 From: Samuel Ortiz Date: Mon, 5 Mar 2012 01:03:44 +0100 Subject: NFC: Fragment LLCP I frames Based on the receiver MIU, we have to fragment the frame to be transmitted. Signed-off-by: Samuel Ortiz Signed-off-by: John W. Linville --- net/nfc/llcp/commands.c | 57 +++++++++++++++++++++++++++++++++++++------------ 1 file changed, 43 insertions(+), 14 deletions(-) diff --git a/net/nfc/llcp/commands.c b/net/nfc/llcp/commands.c index a02292ba25c7..bfe35b8f225e 100644 --- a/net/nfc/llcp/commands.c +++ b/net/nfc/llcp/commands.c @@ -444,29 +444,58 @@ int nfc_llcp_send_i_frame(struct nfc_llcp_sock *sock, struct msghdr *msg, size_t len) { struct sk_buff *pdu; - struct sock *sk; + struct sock *sk = &sock->sk; + struct nfc_llcp_local *local; + size_t frag_len = 0, remaining_len; + u8 *msg_data, *msg_ptr; - pr_debug("Send I frame\n"); + pr_debug("Send I frame len %zd\n", len); - pdu = llcp_allocate_pdu(sock, LLCP_PDU_I, len + LLCP_SEQUENCE_SIZE); - if (pdu == NULL) - return -ENOMEM; + local = sock->local; + if (local == NULL) + return -ENODEV; - skb_put(pdu, LLCP_SEQUENCE_SIZE); + msg_data = kzalloc(len, GFP_KERNEL); + if (msg_data == NULL) + return -ENOMEM; - if (memcpy_fromiovec(skb_put(pdu, len), msg->msg_iov, len)) { - kfree_skb(pdu); - return -EFAULT; + if (memcpy_fromiovec(msg_data, msg->msg_iov, len)) { + kfree(msg_data); + return -EFAULT; } - skb_queue_head(&sock->tx_queue, pdu); + remaining_len = len; + msg_ptr = msg_data; + + while (remaining_len > 0) { + + frag_len = min_t(u16, local->remote_miu, remaining_len); - sk = &sock->sk; - lock_sock(sk); + pr_debug("Fragment %zd bytes remaining %zd", + frag_len, remaining_len); - nfc_llcp_queue_i_frames(sock); + pdu = llcp_allocate_pdu(sock, LLCP_PDU_I, + frag_len + LLCP_SEQUENCE_SIZE); + if (pdu == NULL) + return -ENOMEM; + + skb_put(pdu, LLCP_SEQUENCE_SIZE); + + memcpy(skb_put(pdu, frag_len), msg_ptr, frag_len); + + skb_queue_head(&sock->tx_queue, pdu); + + lock_sock(sk); + + nfc_llcp_queue_i_frames(sock); + + release_sock(sk); + + remaining_len -= frag_len; + msg_ptr += len; + } - release_sock(sk); + kfree(msg_data); return 0; } -- cgit From 7975754f61b8e87ad0b34509a94c54c8d19ea15d Mon Sep 17 00:00:00 2001 From: Samuel Ortiz Date: Mon, 5 Mar 2012 01:03:45 +0100 Subject: NFC: Export sensf from pn533 sensf is the detection response for Felica NFC tags. Signed-off-by: Samuel Ortiz Signed-off-by: John W. Linville --- drivers/nfc/pn533.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/nfc/pn533.c b/drivers/nfc/pn533.c index a5766042f0ee..353bab775d7d 100644 --- a/drivers/nfc/pn533.c +++ b/drivers/nfc/pn533.c @@ -783,6 +783,9 @@ static int pn533_target_found_felica(struct nfc_target *nfc_tgt, u8 *tgt_data, else nfc_tgt->supported_protocols = NFC_PROTO_FELICA_MASK; + memcpy(nfc_tgt->sensf_res, &tgt_felica->opcode, 9); + nfc_tgt->sensf_res_len = 9; + return 0; } -- cgit From d8dc107248d336695ca6a964c5ffdc2f4d160a04 Mon Sep 17 00:00:00 2001 From: Samuel Ortiz Date: Mon, 5 Mar 2012 01:03:46 +0100 Subject: NFC: Export Jewel/Topaz ID from pn533 The jewel ID is the NFCID1 for Topaz NFC tags. Signed-off-by: Samuel Ortiz Signed-off-by: John W. Linville --- drivers/nfc/pn533.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/nfc/pn533.c b/drivers/nfc/pn533.c index 353bab775d7d..f5da5ae67ec1 100644 --- a/drivers/nfc/pn533.c +++ b/drivers/nfc/pn533.c @@ -828,6 +828,8 @@ static int pn533_target_found_jewel(struct nfc_target *nfc_tgt, u8 *tgt_data, nfc_tgt->supported_protocols = NFC_PROTO_JEWEL_MASK; nfc_tgt->sens_res = be16_to_cpu(tgt_jewel->sens_res); + nfc_tgt->nfcid1_len = 4; + memcpy(nfc_tgt->nfcid1, tgt_jewel->jewelid, nfc_tgt->nfcid1_len); return 0; } -- cgit From 2fbabfa467ce945deb92bf04c745b4d101fc21ee Mon Sep 17 00:00:00 2001 From: Samuel Ortiz Date: Mon, 5 Mar 2012 01:03:47 +0100 Subject: NFC: Export NFCID when detecting a p2p target with pn533 Signed-off-by: Samuel Ortiz Signed-off-by: John W. Linville --- drivers/nfc/pn533.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/nfc/pn533.c b/drivers/nfc/pn533.c index f5da5ae67ec1..ef33f64143b5 100644 --- a/drivers/nfc/pn533.c +++ b/drivers/nfc/pn533.c @@ -1316,6 +1316,8 @@ static int pn533_in_dep_link_up_complete(struct pn533 *dev, void *arg, nfc_dev_dbg(&dev->interface->dev, "Creating new target"); nfc_target.supported_protocols = NFC_PROTO_NFC_DEP_MASK; + nfc_target.nfcid1_len = 10; + memcpy(nfc_target.nfcid1, resp->nfcid3t, nfc_target.nfcid1_len); rc = nfc_targets_found(dev->nfc_dev, &nfc_target, 1); if (rc) return 0; -- cgit From 0c31835993e622fa9d407807e384c0f9b971d53b Mon Sep 17 00:00:00 2001 From: Samuel Ortiz Date: Mon, 5 Mar 2012 01:03:48 +0100 Subject: NFC: Unlink LLCP child sockets from llcp_sock_release The parent socket (the bound one) could be freed before its children, so we should unlink the children without trying to reach it through the parent. Signed-off-by: Samuel Ortiz Signed-off-by: John W. Linville --- net/nfc/llcp/sock.c | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/net/nfc/llcp/sock.c b/net/nfc/llcp/sock.c index b8bef367ee49..d3861773fab0 100644 --- a/net/nfc/llcp/sock.c +++ b/net/nfc/llcp/sock.c @@ -327,20 +327,10 @@ static int llcp_sock_release(struct socket *sock) mutex_lock(&local->socket_lock); - if (llcp_sock == local->sockets[llcp_sock->ssap]) { + if (llcp_sock == local->sockets[llcp_sock->ssap]) local->sockets[llcp_sock->ssap] = NULL; - } else { - struct nfc_llcp_sock *parent, *s, *n; - - parent = local->sockets[llcp_sock->ssap]; - - list_for_each_entry_safe(s, n, &parent->list, list) - if (llcp_sock == s) { - list_del(&s->list); - break; - } - - } + else + list_del(&llcp_sock->list); mutex_unlock(&local->socket_lock); -- cgit From 9dda50f4c98f84e32a5f6dc4d9dd7af6085add43 Mon Sep 17 00:00:00 2001 From: Samuel Ortiz Date: Mon, 5 Mar 2012 01:03:49 +0100 Subject: NFC: SN is not an invalid GT value We just don't do anything with it when parsing the general bytes. We handle it from the CONNECT reception code. Signed-off-by: Samuel Ortiz Signed-off-by: John W. Linville --- net/nfc/llcp/commands.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/net/nfc/llcp/commands.c b/net/nfc/llcp/commands.c index bfe35b8f225e..7c74b82f2161 100644 --- a/net/nfc/llcp/commands.c +++ b/net/nfc/llcp/commands.c @@ -152,6 +152,8 @@ int nfc_llcp_parse_tlv(struct nfc_llcp_local *local, case LLCP_TLV_RW: local->remote_rw = llcp_tlv_rw(tlv); break; + case LLCP_TLV_SN: + break; default: pr_err("Invalid gt tlv value 0x%x\n", type); break; -- cgit From 47807d3dbb62e93850cbcb797db1a9ee1806f986 Mon Sep 17 00:00:00 2001 From: Samuel Ortiz Date: Mon, 5 Mar 2012 01:03:50 +0100 Subject: NFC: Remove the rf mode parameter from the DEP link up routine When calling nfc_dep_link_up, we implicitely are in initiator mode. Which means we also can provide the general bytes as a function argument, as all drivers will eventually request them. Signed-off-by: Samuel Ortiz Signed-off-by: John W. Linville --- drivers/nfc/pn533.c | 20 +++++--------------- include/net/nfc/nfc.h | 6 ++---- net/nfc/core.c | 22 +++++++++++----------- net/nfc/llcp/llcp.c | 2 +- net/nfc/netlink.c | 11 +++-------- net/nfc/nfc.h | 5 ++--- 6 files changed, 24 insertions(+), 42 deletions(-) diff --git a/drivers/nfc/pn533.c b/drivers/nfc/pn533.c index ef33f64143b5..cb6204f78300 100644 --- a/drivers/nfc/pn533.c +++ b/drivers/nfc/pn533.c @@ -1340,21 +1340,15 @@ static int pn533_in_dep_link_up_complete(struct pn533 *dev, void *arg, } static int pn533_dep_link_up(struct nfc_dev *nfc_dev, int target_idx, - u8 comm_mode, u8 rf_mode) + u8 comm_mode, u8* gb, size_t gb_len) { struct pn533 *dev = nfc_get_drvdata(nfc_dev); struct pn533_cmd_jump_dep *cmd; - u8 cmd_len, local_gt_len, *local_gt; + u8 cmd_len; int rc; nfc_dev_dbg(&dev->interface->dev, "%s", __func__); - if (rf_mode == NFC_RF_TARGET) { - nfc_dev_err(&dev->interface->dev, "Target mode not supported"); - return -EOPNOTSUPP; - } - - if (dev->poll_mod_count) { nfc_dev_err(&dev->interface->dev, "Cannot bring the DEP link up while polling"); @@ -1367,11 +1361,7 @@ static int pn533_dep_link_up(struct nfc_dev *nfc_dev, int target_idx, return -EBUSY; } - local_gt = nfc_get_local_general_bytes(dev->nfc_dev, &local_gt_len); - if (local_gt_len > NFC_MAX_GT_LEN) - return -EINVAL; - - cmd_len = sizeof(struct pn533_cmd_jump_dep) + local_gt_len; + cmd_len = sizeof(struct pn533_cmd_jump_dep) + gb_len; cmd = kzalloc(cmd_len, GFP_KERNEL); if (cmd == NULL) return -ENOMEM; @@ -1380,9 +1370,9 @@ static int pn533_dep_link_up(struct nfc_dev *nfc_dev, int target_idx, cmd->active = !comm_mode; cmd->baud = 0; - if (local_gt != NULL) { + if (gb != NULL && gb_len > 0) { cmd->next = 4; /* We have some Gi */ - memcpy(cmd->gt, local_gt, local_gt_len); + memcpy(cmd->gt, gb, gb_len); } else { cmd->next = 0; } diff --git a/include/net/nfc/nfc.h b/include/net/nfc/nfc.h index d253278e5a96..d608e4eac66f 100644 --- a/include/net/nfc/nfc.h +++ b/include/net/nfc/nfc.h @@ -53,8 +53,8 @@ struct nfc_ops { int (*dev_down)(struct nfc_dev *dev); int (*start_poll)(struct nfc_dev *dev, u32 protocols); void (*stop_poll)(struct nfc_dev *dev); - int (*dep_link_up)(struct nfc_dev *dev, int target_idx, - u8 comm_mode, u8 rf_mode); + int (*dep_link_up)(struct nfc_dev *dev, int target_idx, u8 comm_mode, + u8 *gb, size_t gb_len); int (*dep_link_down)(struct nfc_dev *dev); int (*activate_target)(struct nfc_dev *dev, u32 target_idx, u32 protocol); @@ -179,8 +179,6 @@ struct sk_buff *nfc_alloc_recv_skb(unsigned int size, gfp_t gfp); int nfc_set_remote_general_bytes(struct nfc_dev *dev, u8 *gt, u8 gt_len); -u8 *nfc_get_local_general_bytes(struct nfc_dev *dev, u8 *gt_len); - int nfc_targets_found(struct nfc_dev *dev, struct nfc_target *targets, int ntargets); diff --git a/net/nfc/core.c b/net/nfc/core.c index 6089aca67b14..f4f526f73217 100644 --- a/net/nfc/core.c +++ b/net/nfc/core.c @@ -181,13 +181,13 @@ error: return rc; } -int nfc_dep_link_up(struct nfc_dev *dev, int target_index, - u8 comm_mode, u8 rf_mode) +int nfc_dep_link_up(struct nfc_dev *dev, int target_index, u8 comm_mode) { int rc = 0; + u8 *gb; + size_t gb_len; - pr_debug("dev_name=%s comm:%d rf:%d\n", - dev_name(&dev->dev), comm_mode, rf_mode); + pr_debug("dev_name=%s comm %d\n", dev_name(&dev->dev), comm_mode); if (!dev->ops->dep_link_up) return -EOPNOTSUPP; @@ -204,7 +204,13 @@ int nfc_dep_link_up(struct nfc_dev *dev, int target_index, goto error; } - rc = dev->ops->dep_link_up(dev, target_index, comm_mode, rf_mode); + gb = nfc_llcp_general_bytes(dev, &gb_len); + if (gb_len > NFC_MAX_GT_LEN) { + rc = -EINVAL; + goto error; + } + + rc = dev->ops->dep_link_up(dev, target_index, comm_mode, gb, gb_len); error: device_unlock(&dev->dev); @@ -367,12 +373,6 @@ int nfc_set_remote_general_bytes(struct nfc_dev *dev, u8 *gb, u8 gb_len) } EXPORT_SYMBOL(nfc_set_remote_general_bytes); -u8 *nfc_get_local_general_bytes(struct nfc_dev *dev, u8 *gt_len) -{ - return nfc_llcp_general_bytes(dev, gt_len); -} -EXPORT_SYMBOL(nfc_get_local_general_bytes); - /** * nfc_alloc_send_skb - allocate a skb for data exchange responses * diff --git a/net/nfc/llcp/llcp.c b/net/nfc/llcp/llcp.c index a0cb133c610a..3ce646e35f6b 100644 --- a/net/nfc/llcp/llcp.c +++ b/net/nfc/llcp/llcp.c @@ -281,7 +281,7 @@ void nfc_llcp_put_ssap(struct nfc_llcp_local *local, u8 ssap) mutex_unlock(&local->sdp_lock); } -u8 *nfc_llcp_general_bytes(struct nfc_dev *dev, u8 *general_bytes_len) +u8 *nfc_llcp_general_bytes(struct nfc_dev *dev, size_t *general_bytes_len) { struct nfc_llcp_local *local; diff --git a/net/nfc/netlink.c b/net/nfc/netlink.c index a1388e4efd6f..fa620d03799e 100644 --- a/net/nfc/netlink.c +++ b/net/nfc/netlink.c @@ -542,13 +542,12 @@ static int nfc_genl_dep_link_up(struct sk_buff *skb, struct genl_info *info) struct nfc_dev *dev; int rc, tgt_idx; u32 idx; - u8 comm, rf; + u8 comm; pr_debug("DEP link up\n"); if (!info->attrs[NFC_ATTR_DEVICE_INDEX] || - !info->attrs[NFC_ATTR_COMM_MODE] || - !info->attrs[NFC_ATTR_RF_MODE]) + !info->attrs[NFC_ATTR_COMM_MODE]) return -EINVAL; idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]); @@ -558,19 +557,15 @@ static int nfc_genl_dep_link_up(struct sk_buff *skb, struct genl_info *info) tgt_idx = nla_get_u32(info->attrs[NFC_ATTR_TARGET_INDEX]); comm = nla_get_u8(info->attrs[NFC_ATTR_COMM_MODE]); - rf = nla_get_u8(info->attrs[NFC_ATTR_RF_MODE]); if (comm != NFC_COMM_ACTIVE && comm != NFC_COMM_PASSIVE) return -EINVAL; - if (rf != NFC_RF_INITIATOR && comm != NFC_RF_TARGET) - return -EINVAL; - dev = nfc_get_device(idx); if (!dev) return -ENODEV; - rc = nfc_dep_link_up(dev, tgt_idx, comm, rf); + rc = nfc_dep_link_up(dev, tgt_idx, comm); nfc_put_device(dev); diff --git a/net/nfc/nfc.h b/net/nfc/nfc.h index 6d28d75995b0..2fd83b16df68 100644 --- a/net/nfc/nfc.h +++ b/net/nfc/nfc.h @@ -54,7 +54,7 @@ void nfc_llcp_mac_is_up(struct nfc_dev *dev, u32 target_idx, int nfc_llcp_register_device(struct nfc_dev *dev); void nfc_llcp_unregister_device(struct nfc_dev *dev); int nfc_llcp_set_remote_gb(struct nfc_dev *dev, u8 *gb, u8 gb_len); -u8 *nfc_llcp_general_bytes(struct nfc_dev *dev, u8 *general_bytes_len); +u8 *nfc_llcp_general_bytes(struct nfc_dev *dev, size_t *general_bytes_len); int __init nfc_llcp_init(void); void nfc_llcp_exit(void); @@ -160,8 +160,7 @@ int nfc_start_poll(struct nfc_dev *dev, u32 protocols); int nfc_stop_poll(struct nfc_dev *dev); -int nfc_dep_link_up(struct nfc_dev *dev, int target_idx, - u8 comm_mode, u8 rf_mode); +int nfc_dep_link_up(struct nfc_dev *dev, int target_idx, u8 comm_mode); int nfc_dep_link_down(struct nfc_dev *dev); -- cgit From 40c75f81d6852bb4fd08491074889187f77b8d1f Mon Sep 17 00:00:00 2001 From: Samuel Ortiz Date: Mon, 5 Mar 2012 01:03:51 +0100 Subject: NFC: Fix LLCP sockets releasing path The socket local pointer needs to be set to NULL when the adapter is removed or the MAC goes down. If the socket release code is called after such an event, the socket reference count still needs to be decreased in order for the socket to eventually be freed. Signed-off-by: Samuel Ortiz Signed-off-by: John W. Linville --- net/nfc/llcp/llcp.c | 15 +++++++++++---- net/nfc/llcp/sock.c | 23 +++++++++++++++-------- 2 files changed, 26 insertions(+), 12 deletions(-) diff --git a/net/nfc/llcp/llcp.c b/net/nfc/llcp/llcp.c index 3ce646e35f6b..8af896dc759e 100644 --- a/net/nfc/llcp/llcp.c +++ b/net/nfc/llcp/llcp.c @@ -47,7 +47,7 @@ static void nfc_llcp_socket_release(struct nfc_llcp_local *local) /* Release all child sockets */ list_for_each_entry_safe(s, n, &parent->list, list) { - list_del(&s->list); + list_del_init(&s->list); sk = &s->sk; lock_sock(sk); @@ -56,9 +56,12 @@ static void nfc_llcp_socket_release(struct nfc_llcp_local *local) nfc_put_device(s->dev); sk->sk_state = LLCP_CLOSED; - sock_set_flag(sk, SOCK_DEAD); release_sock(sk); + + sock_orphan(sk); + + s->local = NULL; } parent_sk = &parent->sk; @@ -77,11 +80,12 @@ static void nfc_llcp_socket_release(struct nfc_llcp_local *local) nfc_llcp_accept_unlink(accept_sk); accept_sk->sk_state = LLCP_CLOSED; - sock_set_flag(accept_sk, SOCK_DEAD); release_sock(accept_sk); sock_orphan(accept_sk); + + lsk->local = NULL; } } @@ -89,9 +93,12 @@ static void nfc_llcp_socket_release(struct nfc_llcp_local *local) nfc_put_device(parent->dev); parent_sk->sk_state = LLCP_CLOSED; - sock_set_flag(parent_sk, SOCK_DEAD); release_sock(parent_sk); + + sock_orphan(parent_sk); + + parent->local = NULL; } mutex_unlock(&local->socket_lock); diff --git a/net/nfc/llcp/sock.c b/net/nfc/llcp/sock.c index d3861773fab0..35825e20163a 100644 --- a/net/nfc/llcp/sock.c +++ b/net/nfc/llcp/sock.c @@ -315,6 +315,7 @@ static int llcp_sock_release(struct socket *sock) struct sock *sk = sock->sk; struct nfc_llcp_local *local; struct nfc_llcp_sock *llcp_sock = nfc_llcp_sock(sk); + int err = 0; if (!sk) return 0; @@ -322,15 +323,17 @@ static int llcp_sock_release(struct socket *sock) pr_debug("%p\n", sk); local = llcp_sock->local; - if (local == NULL) - return -ENODEV; + if (local == NULL) { + err = -ENODEV; + goto out; + } mutex_lock(&local->socket_lock); if (llcp_sock == local->sockets[llcp_sock->ssap]) local->sockets[llcp_sock->ssap] = NULL; else - list_del(&llcp_sock->list); + list_del_init(&llcp_sock->list); mutex_unlock(&local->socket_lock); @@ -354,9 +357,7 @@ static int llcp_sock_release(struct socket *sock) release_sock(accept_sk); - sock_set_flag(sk, SOCK_DEAD); sock_orphan(accept_sk); - sock_put(accept_sk); } } @@ -367,14 +368,13 @@ static int llcp_sock_release(struct socket *sock) sk->sk_state == LLCP_LISTEN) nfc_llcp_put_ssap(llcp_sock->local, llcp_sock->ssap); - sock_set_flag(sk, SOCK_DEAD); - release_sock(sk); +out: sock_orphan(sk); sock_put(sk); - return 0; + return err; } static int llcp_sock_connect(struct socket *sock, struct sockaddr *_addr, @@ -645,6 +645,8 @@ struct sock *nfc_llcp_sock_alloc(struct socket *sock, int type, gfp_t gfp) void nfc_llcp_sock_free(struct nfc_llcp_sock *sock) { + struct nfc_llcp_local *local = sock->local; + kfree(sock->service_name); skb_queue_purge(&sock->tx_queue); @@ -653,6 +655,11 @@ void nfc_llcp_sock_free(struct nfc_llcp_sock *sock) list_del_init(&sock->accept_queue); + if (local != NULL && sock == local->sockets[sock->ssap]) + local->sockets[sock->ssap] = NULL; + else + list_del_init(&sock->list); + sock->parent = NULL; } -- cgit From 427a2eb1f568c9c5934a36105232c94553db9b69 Mon Sep 17 00:00:00 2001 From: Samuel Ortiz Date: Mon, 5 Mar 2012 01:03:52 +0100 Subject: NFC: LLCP code identation fixes Signed-off-by: Samuel Ortiz Signed-off-by: John W. Linville --- net/nfc/llcp/commands.c | 39 +++++++++++---------- net/nfc/llcp/llcp.c | 93 +++++++++++++++++++++++++------------------------ net/nfc/llcp/llcp.h | 6 ++-- net/nfc/llcp/sock.c | 55 +++++++++++++++-------------- 4 files changed, 100 insertions(+), 93 deletions(-) diff --git a/net/nfc/llcp/commands.c b/net/nfc/llcp/commands.c index 7c74b82f2161..7b76eb7192f3 100644 --- a/net/nfc/llcp/commands.c +++ b/net/nfc/llcp/commands.c @@ -118,7 +118,7 @@ u8 *nfc_llcp_build_tlv(u8 type, u8 *value, u8 value_length, u8 *tlv_length) } int nfc_llcp_parse_tlv(struct nfc_llcp_local *local, - u8 *tlv_array, u16 tlv_array_len) + u8 *tlv_array, u16 tlv_array_len) { u8 *tlv = tlv_array, type, length, offset = 0; @@ -164,15 +164,15 @@ int nfc_llcp_parse_tlv(struct nfc_llcp_local *local, } pr_debug("version 0x%x miu %d lto %d opt 0x%x wks 0x%x rw %d\n", - local->remote_version, local->remote_miu, - local->remote_lto, local->remote_opt, - local->remote_wks, local->remote_rw); + local->remote_version, local->remote_miu, + local->remote_lto, local->remote_opt, + local->remote_wks, local->remote_rw); return 0; } static struct sk_buff *llcp_add_header(struct sk_buff *pdu, - u8 dsap, u8 ssap, u8 ptype) + u8 dsap, u8 ssap, u8 ptype) { u8 header[2]; @@ -188,7 +188,8 @@ static struct sk_buff *llcp_add_header(struct sk_buff *pdu, return pdu; } -static struct sk_buff *llcp_add_tlv(struct sk_buff *pdu, u8 *tlv, u8 tlv_length) +static struct sk_buff *llcp_add_tlv(struct sk_buff *pdu, u8 *tlv, + u8 tlv_length) { /* XXX Add an skb length check */ @@ -201,7 +202,7 @@ static struct sk_buff *llcp_add_tlv(struct sk_buff *pdu, u8 *tlv, u8 tlv_length) } static struct sk_buff *llcp_allocate_pdu(struct nfc_llcp_sock *sock, - u8 cmd, u16 size) + u8 cmd, u16 size) { struct sk_buff *skb; int err; @@ -210,7 +211,7 @@ static struct sk_buff *llcp_allocate_pdu(struct nfc_llcp_sock *sock, return NULL; skb = nfc_alloc_send_skb(sock->dev, &sock->sk, MSG_DONTWAIT, - size + LLCP_HEADER_SIZE, &err); + size + LLCP_HEADER_SIZE, &err); if (skb == NULL) { pr_err("Could not allocate PDU\n"); return NULL; @@ -278,7 +279,7 @@ int nfc_llcp_send_symm(struct nfc_dev *dev) skb = llcp_add_header(skb, 0, 0, LLCP_PDU_SYMM); return nfc_data_exchange(dev, local->target_idx, skb, - nfc_llcp_recv, local); + nfc_llcp_recv, local); } int nfc_llcp_send_connect(struct nfc_llcp_sock *sock) @@ -300,14 +301,15 @@ int nfc_llcp_send_connect(struct nfc_llcp_sock *sock) if (sock->service_name != NULL) { service_name_tlv = nfc_llcp_build_tlv(LLCP_TLV_SN, - sock->service_name, - sock->service_name_len, - &service_name_tlv_length); + sock->service_name, + sock->service_name_len, + &service_name_tlv_length); size += service_name_tlv_length; } miux = cpu_to_be16(LLCP_MAX_MIUX); - miux_tlv = nfc_llcp_build_tlv(LLCP_TLV_MIUX, (u8 *)&miux, 0, &miux_tlv_length); + miux_tlv = nfc_llcp_build_tlv(LLCP_TLV_MIUX, (u8 *)&miux, 0, + &miux_tlv_length); size += miux_tlv_length; rw = LLCP_MAX_RW; @@ -324,7 +326,7 @@ int nfc_llcp_send_connect(struct nfc_llcp_sock *sock) if (service_name_tlv != NULL) skb = llcp_add_tlv(skb, service_name_tlv, - service_name_tlv_length); + service_name_tlv_length); skb = llcp_add_tlv(skb, miux_tlv, miux_tlv_length); skb = llcp_add_tlv(skb, rw_tlv, rw_tlv_length); @@ -360,7 +362,8 @@ int nfc_llcp_send_cc(struct nfc_llcp_sock *sock) return -ENODEV; miux = cpu_to_be16(LLCP_MAX_MIUX); - miux_tlv = nfc_llcp_build_tlv(LLCP_TLV_MIUX, (u8 *)&miux, 0, &miux_tlv_length); + miux_tlv = nfc_llcp_build_tlv(LLCP_TLV_MIUX, (u8 *)&miux, 0, + &miux_tlv_length); size += miux_tlv_length; rw = LLCP_MAX_RW; @@ -443,7 +446,7 @@ int nfc_llcp_send_disconnect(struct nfc_llcp_sock *sock) } int nfc_llcp_send_i_frame(struct nfc_llcp_sock *sock, - struct msghdr *msg, size_t len) + struct msghdr *msg, size_t len) { struct sk_buff *pdu; struct sock *sk = &sock->sk; @@ -462,8 +465,8 @@ int nfc_llcp_send_i_frame(struct nfc_llcp_sock *sock, return -ENOMEM; if (memcpy_fromiovec(msg_data, msg->msg_iov, len)) { - kfree(msg_data); - return -EFAULT; + kfree(msg_data); + return -EFAULT; } remaining_len = len; diff --git a/net/nfc/llcp/llcp.c b/net/nfc/llcp/llcp.c index 8af896dc759e..17a578f641f1 100644 --- a/net/nfc/llcp/llcp.c +++ b/net/nfc/llcp/llcp.c @@ -37,7 +37,6 @@ static void nfc_llcp_socket_release(struct nfc_llcp_local *local) struct sock *sk, *parent_sk; int i; - mutex_lock(&local->socket_lock); for (i = 0; i < LLCP_MAX_SAP; i++) { @@ -73,7 +72,7 @@ static void nfc_llcp_socket_release(struct nfc_llcp_local *local) struct sock *accept_sk; list_for_each_entry_safe(lsk, n, &parent->accept_queue, - accept_queue) { + accept_queue) { accept_sk = &lsk->sk; lock_sock(accept_sk); @@ -118,7 +117,7 @@ static void nfc_llcp_clear_sdp(struct nfc_llcp_local *local) static void nfc_llcp_timeout_work(struct work_struct *work) { struct nfc_llcp_local *local = container_of(work, struct nfc_llcp_local, - timeout_work); + timeout_work); nfc_dep_link_down(local->dev); } @@ -164,7 +163,7 @@ static int nfc_llcp_wks_sap(char *service_name, size_t service_name_len) num_wks = ARRAY_SIZE(wks); - for (sap = 0 ; sap < num_wks; sap++) { + for (sap = 0; sap < num_wks; sap++) { if (wks[sap] == NULL) continue; @@ -176,13 +175,13 @@ static int nfc_llcp_wks_sap(char *service_name, size_t service_name_len) } u8 nfc_llcp_get_sdp_ssap(struct nfc_llcp_local *local, - struct nfc_llcp_sock *sock) + struct nfc_llcp_sock *sock) { mutex_lock(&local->sdp_lock); if (sock->service_name != NULL && sock->service_name_len > 0) { int ssap = nfc_llcp_wks_sap(sock->service_name, - sock->service_name_len); + sock->service_name_len); if (ssap > 0) { pr_debug("WKS %d\n", ssap); @@ -312,7 +311,7 @@ static int nfc_llcp_build_gb(struct nfc_llcp_local *local) version = LLCP_VERSION_11; version_tlv = nfc_llcp_build_tlv(LLCP_TLV_VERSION, &version, - 1, &version_length); + 1, &version_length); gb_len += version_length; /* 1500 ms */ @@ -322,7 +321,7 @@ static int nfc_llcp_build_gb(struct nfc_llcp_local *local) pr_debug("Local wks 0x%lx\n", local->local_wks); wks_tlv = nfc_llcp_build_tlv(LLCP_TLV_WKS, (u8 *)&local->local_wks, 2, - &wks_length); + &wks_length); gb_len += wks_length; gb_len += ARRAY_SIZE(llcp_magic); @@ -367,8 +366,7 @@ int nfc_llcp_set_remote_gb(struct nfc_dev *dev, u8 *gb, u8 gb_len) memcpy(local->remote_gb, gb, gb_len); local->remote_gb_len = gb_len; - if (local->remote_gb == NULL || - local->remote_gb_len == 0) + if (local->remote_gb == NULL || local->remote_gb_len == 0) return -ENODEV; if (memcmp(local->remote_gb, llcp_magic, 3)) { @@ -377,26 +375,27 @@ int nfc_llcp_set_remote_gb(struct nfc_dev *dev, u8 *gb, u8 gb_len) } return nfc_llcp_parse_tlv(local, - &local->remote_gb[3], local->remote_gb_len - 3); + &local->remote_gb[3], + local->remote_gb_len - 3); } static void nfc_llcp_tx_work(struct work_struct *work) { struct nfc_llcp_local *local = container_of(work, struct nfc_llcp_local, - tx_work); + tx_work); struct sk_buff *skb; skb = skb_dequeue(&local->tx_queue); if (skb != NULL) { pr_debug("Sending pending skb\n"); nfc_data_exchange(local->dev, local->target_idx, - skb, nfc_llcp_recv, local); + skb, nfc_llcp_recv, local); } else { nfc_llcp_send_symm(local->dev); } mod_timer(&local->link_timer, - jiffies + msecs_to_jiffies(local->remote_lto)); + jiffies + msecs_to_jiffies(local->remote_lto)); } static u8 nfc_llcp_dsap(struct sk_buff *pdu) @@ -432,7 +431,7 @@ static void nfc_llcp_set_nrns(struct nfc_llcp_sock *sock, struct sk_buff *pdu) } static struct nfc_llcp_sock *nfc_llcp_sock_get(struct nfc_llcp_local *local, - u8 ssap, u8 dsap) + u8 ssap, u8 dsap) { struct nfc_llcp_sock *sock, *llcp_sock, *n; @@ -456,7 +455,7 @@ static struct nfc_llcp_sock *nfc_llcp_sock_get(struct nfc_llcp_local *local, list_for_each_entry_safe(llcp_sock, n, &sock->list, list) { pr_debug("llcp_sock %p sk %p dsap %d\n", llcp_sock, - &llcp_sock->sk, llcp_sock->dsap); + &llcp_sock->sk, llcp_sock->dsap); if (llcp_sock->dsap == dsap) { sock_hold(&llcp_sock->sk); mutex_unlock(&local->socket_lock); @@ -500,7 +499,7 @@ static u8 *nfc_llcp_connect_sn(struct sk_buff *skb, size_t *sn_len) } static void nfc_llcp_recv_connect(struct nfc_llcp_local *local, - struct sk_buff *skb) + struct sk_buff *skb) { struct sock *new_sk, *parent; struct nfc_llcp_sock *sock, *new_sock; @@ -512,7 +511,7 @@ static void nfc_llcp_recv_connect(struct nfc_llcp_local *local, pr_debug("%d %d\n", dsap, ssap); nfc_llcp_parse_tlv(local, &skb->data[LLCP_HEADER_SIZE], - skb->len - LLCP_HEADER_SIZE); + skb->len - LLCP_HEADER_SIZE); if (dsap != LLCP_SAP_SDP) { bound_sap = dsap; @@ -531,7 +530,7 @@ static void nfc_llcp_recv_connect(struct nfc_llcp_local *local, lock_sock(&sock->sk); if (sock->dsap == LLCP_SAP_SDP && - sock->sk.sk_state == LLCP_LISTEN) + sock->sk.sk_state == LLCP_LISTEN) goto enqueue; } else { u8 *sn; @@ -547,23 +546,23 @@ static void nfc_llcp_recv_connect(struct nfc_llcp_local *local, mutex_lock(&local->socket_lock); for (bound_sap = 0; bound_sap < LLCP_LOCAL_SAP_OFFSET; - bound_sap++) { + bound_sap++) { sock = local->sockets[bound_sap]; if (sock == NULL) continue; if (sock->service_name == NULL || - sock->service_name_len == 0) + sock->service_name_len == 0) continue; if (sock->service_name_len != sn_len) continue; if (sock->dsap == LLCP_SAP_SDP && - sock->sk.sk_state == LLCP_LISTEN && - !memcmp(sn, sock->service_name, sn_len)) { + sock->sk.sk_state == LLCP_LISTEN && + !memcmp(sn, sock->service_name, sn_len)) { pr_debug("Found service name at SAP %d\n", - bound_sap); + bound_sap); sock_hold(&sock->sk); mutex_unlock(&local->socket_lock); @@ -588,8 +587,7 @@ enqueue: goto fail; } - new_sk = nfc_llcp_sock_alloc(NULL, parent->sk_type, - GFP_ATOMIC); + new_sk = nfc_llcp_sock_alloc(NULL, parent->sk_type, GFP_ATOMIC); if (new_sk == NULL) { reason = LLCP_DM_REJ; release_sock(&sock->sk); @@ -640,12 +638,12 @@ int nfc_llcp_queue_i_frames(struct nfc_llcp_sock *sock) struct nfc_llcp_local *local = sock->local; pr_debug("Remote ready %d tx queue len %d remote rw %d", - sock->remote_ready, skb_queue_len(&sock->tx_pending_queue), - local->remote_rw); + sock->remote_ready, skb_queue_len(&sock->tx_pending_queue), + local->remote_rw); /* Try to queue some I frames for transmission */ while (sock->remote_ready && - skb_queue_len(&sock->tx_pending_queue) < local->remote_rw) { + skb_queue_len(&sock->tx_pending_queue) < local->remote_rw) { struct sk_buff *pdu, *pending_pdu; pdu = skb_dequeue(&sock->tx_queue); @@ -666,7 +664,7 @@ int nfc_llcp_queue_i_frames(struct nfc_llcp_sock *sock) } static void nfc_llcp_recv_hdlc(struct nfc_llcp_local *local, - struct sk_buff *skb) + struct sk_buff *skb) { struct nfc_llcp_sock *llcp_sock; struct sock *sk; @@ -724,7 +722,7 @@ static void nfc_llcp_recv_hdlc(struct nfc_llcp_local *local, if (ptype == LLCP_PDU_RR) llcp_sock->remote_ready = true; - else if (ptype == LLCP_PDU_RNR) + else if (ptype == LLCP_PDU_RNR) llcp_sock->remote_ready = false; if (nfc_llcp_queue_i_frames(llcp_sock) == 0) @@ -735,7 +733,7 @@ static void nfc_llcp_recv_hdlc(struct nfc_llcp_local *local, } static void nfc_llcp_recv_disc(struct nfc_llcp_local *local, - struct sk_buff *skb) + struct sk_buff *skb) { struct nfc_llcp_sock *llcp_sock; struct sock *sk; @@ -757,7 +755,6 @@ static void nfc_llcp_recv_disc(struct nfc_llcp_local *local, nfc_llcp_sock_put(llcp_sock); } - if (sk->sk_state == LLCP_CONNECTED) { nfc_put_device(local->dev); sk->sk_state = LLCP_CLOSED; @@ -770,13 +767,11 @@ static void nfc_llcp_recv_disc(struct nfc_llcp_local *local, nfc_llcp_sock_put(llcp_sock); } -static void nfc_llcp_recv_cc(struct nfc_llcp_local *local, - struct sk_buff *skb) +static void nfc_llcp_recv_cc(struct nfc_llcp_local *local, struct sk_buff *skb) { struct nfc_llcp_sock *llcp_sock; u8 dsap, ssap; - dsap = nfc_llcp_dsap(skb); ssap = nfc_llcp_ssap(skb); @@ -795,7 +790,7 @@ static void nfc_llcp_recv_cc(struct nfc_llcp_local *local, llcp_sock->dsap = ssap; nfc_llcp_parse_tlv(local, &skb->data[LLCP_HEADER_SIZE], - skb->len - LLCP_HEADER_SIZE); + skb->len - LLCP_HEADER_SIZE); nfc_llcp_sock_put(llcp_sock); } @@ -803,7 +798,7 @@ static void nfc_llcp_recv_cc(struct nfc_llcp_local *local, static void nfc_llcp_rx_work(struct work_struct *work) { struct nfc_llcp_local *local = container_of(work, struct nfc_llcp_local, - rx_work); + rx_work); u8 dsap, ssap, ptype; struct sk_buff *skb; @@ -861,7 +856,7 @@ void nfc_llcp_recv(void *data, struct sk_buff *skb, int err) pr_debug("Received an LLCP PDU\n"); if (err < 0) { - pr_err("err %d", err); + pr_err("err %d\n", err); return; } @@ -907,7 +902,7 @@ void nfc_llcp_mac_is_up(struct nfc_dev *dev, u32 target_idx, queue_work(local->tx_wq, &local->tx_work); } else { mod_timer(&local->link_timer, - jiffies + msecs_to_jiffies(local->remote_lto)); + jiffies + msecs_to_jiffies(local->remote_lto)); } } @@ -933,8 +928,10 @@ int nfc_llcp_register_device(struct nfc_dev *ndev) skb_queue_head_init(&local->tx_queue); INIT_WORK(&local->tx_work, nfc_llcp_tx_work); snprintf(name, sizeof(name), "%s_llcp_tx_wq", dev_name(dev)); - local->tx_wq = alloc_workqueue(name, - WQ_NON_REENTRANT | WQ_UNBOUND | WQ_MEM_RECLAIM, 1); + local->tx_wq = + alloc_workqueue(name, + WQ_NON_REENTRANT | WQ_UNBOUND | WQ_MEM_RECLAIM, + 1); if (local->tx_wq == NULL) { err = -ENOMEM; goto err_local; @@ -943,8 +940,10 @@ int nfc_llcp_register_device(struct nfc_dev *ndev) local->rx_pending = NULL; INIT_WORK(&local->rx_work, nfc_llcp_rx_work); snprintf(name, sizeof(name), "%s_llcp_rx_wq", dev_name(dev)); - local->rx_wq = alloc_workqueue(name, - WQ_NON_REENTRANT | WQ_UNBOUND | WQ_MEM_RECLAIM, 1); + local->rx_wq = + alloc_workqueue(name, + WQ_NON_REENTRANT | WQ_UNBOUND | WQ_MEM_RECLAIM, + 1); if (local->rx_wq == NULL) { err = -ENOMEM; goto err_tx_wq; @@ -952,8 +951,10 @@ int nfc_llcp_register_device(struct nfc_dev *ndev) INIT_WORK(&local->timeout_work, nfc_llcp_timeout_work); snprintf(name, sizeof(name), "%s_llcp_timeout_wq", dev_name(dev)); - local->timeout_wq = alloc_workqueue(name, - WQ_NON_REENTRANT | WQ_UNBOUND | WQ_MEM_RECLAIM, 1); + local->timeout_wq = + alloc_workqueue(name, + WQ_NON_REENTRANT | WQ_UNBOUND | WQ_MEM_RECLAIM, + 1); if (local->timeout_wq == NULL) { err = -ENOMEM; goto err_rx_wq; diff --git a/net/nfc/llcp/llcp.h b/net/nfc/llcp/llcp.h index 70e1762d6e8d..50680ce5ae43 100644 --- a/net/nfc/llcp/llcp.h +++ b/net/nfc/llcp/llcp.h @@ -166,7 +166,7 @@ struct nfc_llcp_sock { struct nfc_llcp_local *nfc_llcp_find_local(struct nfc_dev *dev); u8 nfc_llcp_get_sdp_ssap(struct nfc_llcp_local *local, - struct nfc_llcp_sock *sock); + struct nfc_llcp_sock *sock); u8 nfc_llcp_get_local_ssap(struct nfc_llcp_local *local); void nfc_llcp_put_ssap(struct nfc_llcp_local *local, u8 ssap); int nfc_llcp_queue_i_frames(struct nfc_llcp_sock *sock); @@ -180,7 +180,7 @@ struct sock *nfc_llcp_accept_dequeue(struct sock *sk, struct socket *newsock); /* TLV API */ int nfc_llcp_parse_tlv(struct nfc_llcp_local *local, - u8 *tlv_array, u16 tlv_array_len); + u8 *tlv_array, u16 tlv_array_len); /* Commands API */ void nfc_llcp_recv(void *data, struct sk_buff *skb, int err); @@ -193,7 +193,7 @@ int nfc_llcp_send_cc(struct nfc_llcp_sock *sock); int nfc_llcp_send_dm(struct nfc_llcp_local *local, u8 ssap, u8 dsap, u8 reason); int nfc_llcp_send_disconnect(struct nfc_llcp_sock *sock); int nfc_llcp_send_i_frame(struct nfc_llcp_sock *sock, - struct msghdr *msg, size_t len); + struct msghdr *msg, size_t len); int nfc_llcp_send_rr(struct nfc_llcp_sock *sock); /* Socket API */ diff --git a/net/nfc/llcp/sock.c b/net/nfc/llcp/sock.c index 35825e20163a..c13e02ebdef9 100644 --- a/net/nfc/llcp/sock.c +++ b/net/nfc/llcp/sock.c @@ -78,9 +78,11 @@ static int llcp_sock_bind(struct socket *sock, struct sockaddr *addr, int alen) llcp_sock->local = local; llcp_sock->nfc_protocol = llcp_addr.nfc_protocol; llcp_sock->service_name_len = min_t(unsigned int, - llcp_addr.service_name_len, NFC_LLCP_MAX_SERVICE_NAME); + llcp_addr.service_name_len, + NFC_LLCP_MAX_SERVICE_NAME); llcp_sock->service_name = kmemdup(llcp_addr.service_name, - llcp_sock->service_name_len, GFP_KERNEL); + llcp_sock->service_name_len, + GFP_KERNEL); llcp_sock->ssap = nfc_llcp_get_sdp_ssap(local, llcp_sock); if (llcp_sock->ssap == LLCP_MAX_SAP) @@ -110,7 +112,7 @@ static int llcp_sock_listen(struct socket *sock, int backlog) lock_sock(sk); if ((sock->type != SOCK_SEQPACKET && sock->type != SOCK_STREAM) - || sk->sk_state != LLCP_BOUND) { + || sk->sk_state != LLCP_BOUND) { ret = -EBADFD; goto error; } @@ -149,13 +151,13 @@ void nfc_llcp_accept_enqueue(struct sock *parent, struct sock *sk) sock_hold(sk); list_add_tail(&llcp_sock->accept_queue, - &llcp_sock_parent->accept_queue); + &llcp_sock_parent->accept_queue); llcp_sock->parent = parent; sk_acceptq_added(parent); } struct sock *nfc_llcp_accept_dequeue(struct sock *parent, - struct socket *newsock) + struct socket *newsock) { struct nfc_llcp_sock *lsk, *n, *llcp_parent; struct sock *sk; @@ -163,7 +165,7 @@ struct sock *nfc_llcp_accept_dequeue(struct sock *parent, llcp_parent = nfc_llcp_sock(parent); list_for_each_entry_safe(lsk, n, &llcp_parent->accept_queue, - accept_queue) { + accept_queue) { sk = &lsk->sk; lock_sock(sk); @@ -192,7 +194,7 @@ struct sock *nfc_llcp_accept_dequeue(struct sock *parent, } static int llcp_sock_accept(struct socket *sock, struct socket *newsock, - int flags) + int flags) { DECLARE_WAITQUEUE(wait, current); struct sock *sk = sock->sk, *new_sk; @@ -248,7 +250,7 @@ error: static int llcp_sock_getname(struct socket *sock, struct sockaddr *addr, int *len, int peer) { - struct sockaddr_nfc_llcp *llcp_addr = (struct sockaddr_nfc_llcp *) addr; + struct sockaddr_nfc_llcp *llcp_addr = (struct sockaddr_nfc_llcp *)addr; struct sock *sk = sock->sk; struct nfc_llcp_sock *llcp_sock = nfc_llcp_sock(sk); @@ -262,7 +264,7 @@ static int llcp_sock_getname(struct socket *sock, struct sockaddr *addr, llcp_addr->ssap = llcp_sock->ssap; llcp_addr->service_name_len = llcp_sock->service_name_len; memcpy(llcp_addr->service_name, llcp_sock->service_name, - llcp_addr->service_name_len); + llcp_addr->service_name_len); return 0; } @@ -275,7 +277,7 @@ static inline unsigned int llcp_accept_poll(struct sock *parent) parent_sock = nfc_llcp_sock(parent); list_for_each_entry_safe(llcp_sock, n, &parent_sock->accept_queue, - accept_queue) { + accept_queue) { sk = &llcp_sock->sk; if (sk->sk_state == LLCP_CONNECTED) @@ -286,7 +288,7 @@ static inline unsigned int llcp_accept_poll(struct sock *parent) } static unsigned int llcp_sock_poll(struct file *file, struct socket *sock, - poll_table *wait) + poll_table *wait) { struct sock *sk = sock->sk; unsigned int mask = 0; @@ -348,7 +350,7 @@ static int llcp_sock_release(struct socket *sock) struct sock *accept_sk; list_for_each_entry_safe(lsk, n, &llcp_sock->accept_queue, - accept_queue) { + accept_queue) { accept_sk = &lsk->sk; lock_sock(accept_sk); @@ -363,9 +365,8 @@ static int llcp_sock_release(struct socket *sock) /* Freeing the SAP */ if ((sk->sk_state == LLCP_CONNECTED - && llcp_sock->ssap > LLCP_LOCAL_SAP_OFFSET) || - sk->sk_state == LLCP_BOUND || - sk->sk_state == LLCP_LISTEN) + && llcp_sock->ssap > LLCP_LOCAL_SAP_OFFSET) || + sk->sk_state == LLCP_BOUND || sk->sk_state == LLCP_LISTEN) nfc_llcp_put_ssap(llcp_sock->local, llcp_sock->ssap); release_sock(sk); @@ -378,7 +379,7 @@ out: } static int llcp_sock_connect(struct socket *sock, struct sockaddr *_addr, - int len, int flags) + int len, int flags) { struct sock *sk = sock->sk; struct nfc_llcp_sock *llcp_sock = nfc_llcp_sock(sk); @@ -390,7 +391,7 @@ static int llcp_sock_connect(struct socket *sock, struct sockaddr *_addr, pr_debug("sock %p sk %p flags 0x%x\n", sock, sk, flags); if (!addr || len < sizeof(struct sockaddr_nfc) || - addr->sa_family != AF_NFC) { + addr->sa_family != AF_NFC) { pr_err("Invalid socket\n"); return -EINVAL; } @@ -401,7 +402,7 @@ static int llcp_sock_connect(struct socket *sock, struct sockaddr *_addr, } pr_debug("addr dev_idx=%u target_idx=%u protocol=%u\n", addr->dev_idx, - addr->target_idx, addr->nfc_protocol); + addr->target_idx, addr->nfc_protocol); lock_sock(sk); @@ -431,7 +432,7 @@ static int llcp_sock_connect(struct socket *sock, struct sockaddr *_addr, device_unlock(&dev->dev); if (local->rf_mode == NFC_RF_INITIATOR && - addr->target_idx != local->target_idx) { + addr->target_idx != local->target_idx) { ret = -ENOLINK; goto put_dev; } @@ -449,9 +450,11 @@ static int llcp_sock_connect(struct socket *sock, struct sockaddr *_addr, llcp_sock->dsap = LLCP_SAP_SDP; llcp_sock->nfc_protocol = addr->nfc_protocol; llcp_sock->service_name_len = min_t(unsigned int, - addr->service_name_len, NFC_LLCP_MAX_SERVICE_NAME); + addr->service_name_len, + NFC_LLCP_MAX_SERVICE_NAME); llcp_sock->service_name = kmemdup(addr->service_name, - llcp_sock->service_name_len, GFP_KERNEL); + llcp_sock->service_name_len, + GFP_KERNEL); local->sockets[llcp_sock->ssap] = llcp_sock; @@ -473,7 +476,7 @@ error: } static int llcp_sock_sendmsg(struct kiocb *iocb, struct socket *sock, - struct msghdr *msg, size_t len) + struct msghdr *msg, size_t len) { struct sock *sk = sock->sk; struct nfc_llcp_sock *llcp_sock = nfc_llcp_sock(sk); @@ -514,7 +517,7 @@ static int llcp_sock_recvmsg(struct kiocb *iocb, struct socket *sock, lock_sock(sk); if (sk->sk_state == LLCP_CLOSED && - skb_queue_empty(&sk->sk_receive_queue)) { + skb_queue_empty(&sk->sk_receive_queue)) { release_sock(sk); return 0; } @@ -527,7 +530,7 @@ static int llcp_sock_recvmsg(struct kiocb *iocb, struct socket *sock, skb = skb_recv_datagram(sk, flags, noblock, &err); if (!skb) { pr_err("Recv datagram failed state %d %d %d", - sk->sk_state, err, sock_error(sk)); + sk->sk_state, err, sock_error(sk)); if (sk->sk_shutdown & RCV_SHUTDOWN) return 0; @@ -535,7 +538,7 @@ static int llcp_sock_recvmsg(struct kiocb *iocb, struct socket *sock, return err; } - rlen = skb->len; /* real length of skb */ + rlen = skb->len; /* real length of skb */ copied = min_t(unsigned int, rlen, len); cskb = skb; @@ -664,7 +667,7 @@ void nfc_llcp_sock_free(struct nfc_llcp_sock *sock) } static int llcp_sock_create(struct net *net, struct socket *sock, - const struct nfc_protocol *nfc_proto) + const struct nfc_protocol *nfc_proto) { struct sock *sk; -- cgit From 0a40acb24602783fcf6881f915659148aa9807d7 Mon Sep 17 00:00:00 2001 From: Samuel Ortiz Date: Mon, 5 Mar 2012 01:03:53 +0100 Subject: NFC: Core code identation fixes Signed-off-by: Samuel Ortiz Signed-off-by: John W. Linville --- include/net/nfc/nfc.h | 24 +++++++++++----------- net/nfc/af_nfc.c | 2 +- net/nfc/core.c | 28 +++++++++++-------------- net/nfc/netlink.c | 57 ++++++++++++++++++++++++--------------------------- net/nfc/nfc.h | 13 ++++++------ net/nfc/rawsock.c | 16 +++++++-------- 6 files changed, 66 insertions(+), 74 deletions(-) diff --git a/include/net/nfc/nfc.h b/include/net/nfc/nfc.h index d608e4eac66f..bac070bf3514 100644 --- a/include/net/nfc/nfc.h +++ b/include/net/nfc/nfc.h @@ -57,11 +57,11 @@ struct nfc_ops { u8 *gb, size_t gb_len); int (*dep_link_down)(struct nfc_dev *dev); int (*activate_target)(struct nfc_dev *dev, u32 target_idx, - u32 protocol); + u32 protocol); void (*deactivate_target)(struct nfc_dev *dev, u32 target_idx); int (*data_exchange)(struct nfc_dev *dev, u32 target_idx, - struct sk_buff *skb, data_exchange_cb_t cb, - void *cb_context); + struct sk_buff *skb, data_exchange_cb_t cb, + void *cb_context); }; #define NFC_TARGET_IDX_ANY -1 @@ -110,9 +110,9 @@ struct nfc_dev { extern struct class nfc_class; struct nfc_dev *nfc_allocate_device(struct nfc_ops *ops, - u32 supported_protocols, - int tx_headroom, - int tx_tailroom); + u32 supported_protocols, + int tx_headroom, + int tx_tailroom); /** * nfc_free_device - free nfc device @@ -135,7 +135,7 @@ void nfc_unregister_device(struct nfc_dev *dev); * @dev: The parent device */ static inline void nfc_set_parent_dev(struct nfc_dev *nfc_dev, - struct device *dev) + struct device *dev) { nfc_dev->dev.parent = dev; } @@ -172,15 +172,15 @@ static inline const char *nfc_device_name(struct nfc_dev *dev) } struct sk_buff *nfc_alloc_send_skb(struct nfc_dev *dev, struct sock *sk, - unsigned int flags, unsigned int size, - unsigned int *err); + unsigned int flags, unsigned int size, + unsigned int *err); struct sk_buff *nfc_alloc_recv_skb(unsigned int size, gfp_t gfp); int nfc_set_remote_general_bytes(struct nfc_dev *dev, - u8 *gt, u8 gt_len); + u8 *gt, u8 gt_len); -int nfc_targets_found(struct nfc_dev *dev, struct nfc_target *targets, - int ntargets); +int nfc_targets_found(struct nfc_dev *dev, + struct nfc_target *targets, int ntargets); int nfc_dep_link_is_up(struct nfc_dev *dev, u32 target_idx, u8 comm_mode, u8 rf_mode); diff --git a/net/nfc/af_nfc.c b/net/nfc/af_nfc.c index da67756425ce..9d68441e2a5a 100644 --- a/net/nfc/af_nfc.c +++ b/net/nfc/af_nfc.c @@ -30,7 +30,7 @@ static DEFINE_RWLOCK(proto_tab_lock); static const struct nfc_protocol *proto_tab[NFC_SOCKPROTO_MAX]; static int nfc_sock_create(struct net *net, struct socket *sock, int proto, - int kern) + int kern) { int rc = -EPROTONOSUPPORT; diff --git a/net/nfc/core.c b/net/nfc/core.c index f4f526f73217..295d129864d2 100644 --- a/net/nfc/core.c +++ b/net/nfc/core.c @@ -256,7 +256,7 @@ error: } int nfc_dep_link_is_up(struct nfc_dev *dev, u32 target_idx, - u8 comm_mode, u8 rf_mode) + u8 comm_mode, u8 rf_mode) { dev->dep_link_up = true; dev->dep_rf_mode = rf_mode; @@ -336,10 +336,8 @@ error: * * The user must wait for the callback before calling this function again. */ -int nfc_data_exchange(struct nfc_dev *dev, u32 target_idx, - struct sk_buff *skb, - data_exchange_cb_t cb, - void *cb_context) +int nfc_data_exchange(struct nfc_dev *dev, u32 target_idx, struct sk_buff *skb, + data_exchange_cb_t cb, void *cb_context) { int rc; @@ -363,8 +361,7 @@ error: int nfc_set_remote_general_bytes(struct nfc_dev *dev, u8 *gb, u8 gb_len) { - pr_debug("dev_name=%s gb_len=%d\n", - dev_name(&dev->dev), gb_len); + pr_debug("dev_name=%s gb_len=%d\n", dev_name(&dev->dev), gb_len); if (gb_len > NFC_MAX_GT_LEN) return -EINVAL; @@ -380,8 +377,8 @@ EXPORT_SYMBOL(nfc_set_remote_general_bytes); * @gfp: gfp flags */ struct sk_buff *nfc_alloc_send_skb(struct nfc_dev *dev, struct sock *sk, - unsigned int flags, unsigned int size, - unsigned int *err) + unsigned int flags, unsigned int size, + unsigned int *err) { struct sk_buff *skb; unsigned int total_size; @@ -428,8 +425,8 @@ EXPORT_SYMBOL(nfc_alloc_recv_skb); * are found. After calling this function, the device driver must stop * polling for targets. */ -int nfc_targets_found(struct nfc_dev *dev, struct nfc_target *targets, - int n_targets) +int nfc_targets_found(struct nfc_dev *dev, + struct nfc_target *targets, int n_targets) { pr_debug("dev_name=%s n_targets=%d\n", dev_name(&dev->dev), n_targets); @@ -441,7 +438,7 @@ int nfc_targets_found(struct nfc_dev *dev, struct nfc_target *targets, kfree(dev->targets); dev->targets = kmemdup(targets, n_targets * sizeof(struct nfc_target), - GFP_ATOMIC); + GFP_ATOMIC); if (!dev->targets) { dev->n_targets = 0; @@ -501,15 +498,14 @@ struct nfc_dev *nfc_get_device(unsigned idx) * @supported_protocols: NFC protocols supported by the device */ struct nfc_dev *nfc_allocate_device(struct nfc_ops *ops, - u32 supported_protocols, - int tx_headroom, - int tx_tailroom) + u32 supported_protocols, + int tx_headroom, int tx_tailroom) { static atomic_t dev_no = ATOMIC_INIT(0); struct nfc_dev *dev; if (!ops->start_poll || !ops->stop_poll || !ops->activate_target || - !ops->deactivate_target || !ops->data_exchange) + !ops->deactivate_target || !ops->data_exchange) return NULL; if (!supported_protocols) diff --git a/net/nfc/netlink.c b/net/nfc/netlink.c index fa620d03799e..6404052d6c07 100644 --- a/net/nfc/netlink.c +++ b/net/nfc/netlink.c @@ -52,31 +52,30 @@ static const struct nla_policy nfc_genl_policy[NFC_ATTR_MAX + 1] = { }; static int nfc_genl_send_target(struct sk_buff *msg, struct nfc_target *target, - struct netlink_callback *cb, int flags) + struct netlink_callback *cb, int flags) { void *hdr; hdr = genlmsg_put(msg, NETLINK_CB(cb->skb).pid, cb->nlh->nlmsg_seq, - &nfc_genl_family, flags, NFC_CMD_GET_TARGET); + &nfc_genl_family, flags, NFC_CMD_GET_TARGET); if (!hdr) return -EMSGSIZE; genl_dump_check_consistent(cb, hdr, &nfc_genl_family); NLA_PUT_U32(msg, NFC_ATTR_TARGET_INDEX, target->idx); - NLA_PUT_U32(msg, NFC_ATTR_PROTOCOLS, - target->supported_protocols); + NLA_PUT_U32(msg, NFC_ATTR_PROTOCOLS, target->supported_protocols); NLA_PUT_U16(msg, NFC_ATTR_TARGET_SENS_RES, target->sens_res); NLA_PUT_U8(msg, NFC_ATTR_TARGET_SEL_RES, target->sel_res); if (target->nfcid1_len > 0) NLA_PUT(msg, NFC_ATTR_TARGET_NFCID1, target->nfcid1_len, - target->nfcid1); + target->nfcid1); if (target->sensb_res_len > 0) NLA_PUT(msg, NFC_ATTR_TARGET_SENSB_RES, target->sensb_res_len, - target->sensb_res); + target->sensb_res); if (target->sensf_res_len > 0) NLA_PUT(msg, NFC_ATTR_TARGET_SENSF_RES, target->sensf_res_len, - target->sensf_res); + target->sensf_res); return genlmsg_end(msg, hdr); @@ -92,9 +91,9 @@ static struct nfc_dev *__get_device_from_cb(struct netlink_callback *cb) u32 idx; rc = nlmsg_parse(cb->nlh, GENL_HDRLEN + nfc_genl_family.hdrsize, - nfc_genl_family.attrbuf, - nfc_genl_family.maxattr, - nfc_genl_policy); + nfc_genl_family.attrbuf, + nfc_genl_family.maxattr, + nfc_genl_policy); if (rc < 0) return ERR_PTR(rc); @@ -111,7 +110,7 @@ static struct nfc_dev *__get_device_from_cb(struct netlink_callback *cb) } static int nfc_genl_dump_targets(struct sk_buff *skb, - struct netlink_callback *cb) + struct netlink_callback *cb) { int i = cb->args[0]; struct nfc_dev *dev = (struct nfc_dev *) cb->args[1]; @@ -131,7 +130,7 @@ static int nfc_genl_dump_targets(struct sk_buff *skb, while (i < dev->n_targets) { rc = nfc_genl_send_target(skb, &dev->targets[i], cb, - NLM_F_MULTI); + NLM_F_MULTI); if (rc < 0) break; @@ -167,7 +166,7 @@ int nfc_genl_targets_found(struct nfc_dev *dev) return -ENOMEM; hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0, - NFC_EVENT_TARGETS_FOUND); + NFC_EVENT_TARGETS_FOUND); if (!hdr) goto free_msg; @@ -194,7 +193,7 @@ int nfc_genl_device_added(struct nfc_dev *dev) return -ENOMEM; hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0, - NFC_EVENT_DEVICE_ADDED); + NFC_EVENT_DEVICE_ADDED); if (!hdr) goto free_msg; @@ -226,7 +225,7 @@ int nfc_genl_device_removed(struct nfc_dev *dev) return -ENOMEM; hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0, - NFC_EVENT_DEVICE_REMOVED); + NFC_EVENT_DEVICE_REMOVED); if (!hdr) goto free_msg; @@ -246,14 +245,14 @@ free_msg: } static int nfc_genl_send_device(struct sk_buff *msg, struct nfc_dev *dev, - u32 pid, u32 seq, - struct netlink_callback *cb, - int flags) + u32 pid, u32 seq, + struct netlink_callback *cb, + int flags) { void *hdr; hdr = genlmsg_put(msg, pid, seq, &nfc_genl_family, flags, - NFC_CMD_GET_DEVICE); + NFC_CMD_GET_DEVICE); if (!hdr) return -EMSGSIZE; @@ -273,7 +272,7 @@ nla_put_failure: } static int nfc_genl_dump_devices(struct sk_buff *skb, - struct netlink_callback *cb) + struct netlink_callback *cb) { struct class_dev_iter *iter = (struct class_dev_iter *) cb->args[0]; struct nfc_dev *dev = (struct nfc_dev *) cb->args[1]; @@ -300,8 +299,7 @@ static int nfc_genl_dump_devices(struct sk_buff *skb, int rc; rc = nfc_genl_send_device(skb, dev, NETLINK_CB(cb->skb).pid, - cb->nlh->nlmsg_seq, - cb, NLM_F_MULTI); + cb->nlh->nlmsg_seq, cb, NLM_F_MULTI); if (rc < 0) break; @@ -326,7 +324,7 @@ static int nfc_genl_dump_devices_done(struct netlink_callback *cb) } int nfc_genl_dep_link_up_event(struct nfc_dev *dev, u32 target_idx, - u8 comm_mode, u8 rf_mode) + u8 comm_mode, u8 rf_mode) { struct sk_buff *msg; void *hdr; @@ -337,8 +335,7 @@ int nfc_genl_dep_link_up_event(struct nfc_dev *dev, u32 target_idx, if (!msg) return -ENOMEM; - hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0, - NFC_CMD_DEP_LINK_UP); + hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0, NFC_CMD_DEP_LINK_UP); if (!hdr) goto free_msg; @@ -375,7 +372,7 @@ int nfc_genl_dep_link_down_event(struct nfc_dev *dev) return -ENOMEM; hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0, - NFC_CMD_DEP_LINK_DOWN); + NFC_CMD_DEP_LINK_DOWN); if (!hdr) goto free_msg; @@ -417,7 +414,7 @@ static int nfc_genl_get_device(struct sk_buff *skb, struct genl_info *info) } rc = nfc_genl_send_device(msg, dev, info->snd_pid, info->snd_seq, - NULL, 0); + NULL, 0); if (rc < 0) goto out_free; @@ -484,7 +481,7 @@ static int nfc_genl_start_poll(struct sk_buff *skb, struct genl_info *info) pr_debug("Poll start\n"); if (!info->attrs[NFC_ATTR_DEVICE_INDEX] || - !info->attrs[NFC_ATTR_PROTOCOLS]) + !info->attrs[NFC_ATTR_PROTOCOLS]) return -EINVAL; idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]); @@ -640,7 +637,7 @@ static struct genl_ops nfc_genl_ops[] = { }; static int nfc_genl_rcv_nl_event(struct notifier_block *this, - unsigned long event, void *ptr) + unsigned long event, void *ptr) { struct netlink_notify *n = ptr; struct class_dev_iter iter; @@ -693,7 +690,7 @@ int __init nfc_genl_init(void) int rc; rc = genl_register_family_with_ops(&nfc_genl_family, nfc_genl_ops, - ARRAY_SIZE(nfc_genl_ops)); + ARRAY_SIZE(nfc_genl_ops)); if (rc) return rc; diff --git a/net/nfc/nfc.h b/net/nfc/nfc.h index 2fd83b16df68..ec8794c1099c 100644 --- a/net/nfc/nfc.h +++ b/net/nfc/nfc.h @@ -32,7 +32,7 @@ struct nfc_protocol { struct proto *proto; struct module *owner; int (*create)(struct net *net, struct socket *sock, - const struct nfc_protocol *nfc_proto); + const struct nfc_protocol *nfc_proto); }; struct nfc_rawsock { @@ -65,7 +65,7 @@ static inline void nfc_llcp_mac_is_down(struct nfc_dev *dev) } static inline void nfc_llcp_mac_is_up(struct nfc_dev *dev, u32 target_idx, - u8 comm_mode, u8 rf_mode) + u8 comm_mode, u8 rf_mode) { } @@ -78,7 +78,8 @@ static inline void nfc_llcp_unregister_device(struct nfc_dev *dev) { } -static inline int nfc_llcp_set_remote_gb(struct nfc_dev *dev, u8 *gb, u8 gb_len) +static inline int nfc_llcp_set_remote_gb(struct nfc_dev *dev, + u8 *gb, u8 gb_len) { return 0; } @@ -168,9 +169,7 @@ int nfc_activate_target(struct nfc_dev *dev, u32 target_idx, u32 protocol); int nfc_deactivate_target(struct nfc_dev *dev, u32 target_idx); -int nfc_data_exchange(struct nfc_dev *dev, u32 target_idx, - struct sk_buff *skb, - data_exchange_cb_t cb, - void *cb_context); +int nfc_data_exchange(struct nfc_dev *dev, u32 target_idx, struct sk_buff *skb, + data_exchange_cb_t cb, void *cb_context); #endif /* __LOCAL_NFC_H */ diff --git a/net/nfc/rawsock.c b/net/nfc/rawsock.c index 5325439b0c60..5a839ceb2e82 100644 --- a/net/nfc/rawsock.c +++ b/net/nfc/rawsock.c @@ -63,7 +63,7 @@ static int rawsock_release(struct socket *sock) } static int rawsock_connect(struct socket *sock, struct sockaddr *_addr, - int len, int flags) + int len, int flags) { struct sock *sk = sock->sk; struct sockaddr_nfc *addr = (struct sockaddr_nfc *)_addr; @@ -73,7 +73,7 @@ static int rawsock_connect(struct socket *sock, struct sockaddr *_addr, pr_debug("sock=%p sk=%p flags=%d\n", sock, sk, flags); if (!addr || len < sizeof(struct sockaddr_nfc) || - addr->sa_family != AF_NFC) + addr->sa_family != AF_NFC) return -EINVAL; pr_debug("addr dev_idx=%u target_idx=%u protocol=%u\n", @@ -120,7 +120,7 @@ static int rawsock_add_header(struct sk_buff *skb) } static void rawsock_data_exchange_complete(void *context, struct sk_buff *skb, - int err) + int err) { struct sock *sk = (struct sock *) context; @@ -173,7 +173,7 @@ static void rawsock_tx_work(struct work_struct *work) sock_hold(sk); rc = nfc_data_exchange(dev, target_idx, skb, - rawsock_data_exchange_complete, sk); + rawsock_data_exchange_complete, sk); if (rc) { rawsock_report_error(sk, rc); sock_put(sk); @@ -181,7 +181,7 @@ static void rawsock_tx_work(struct work_struct *work) } static int rawsock_sendmsg(struct kiocb *iocb, struct socket *sock, - struct msghdr *msg, size_t len) + struct msghdr *msg, size_t len) { struct sock *sk = sock->sk; struct nfc_dev *dev = nfc_rawsock(sk)->dev; @@ -218,7 +218,7 @@ static int rawsock_sendmsg(struct kiocb *iocb, struct socket *sock, } static int rawsock_recvmsg(struct kiocb *iocb, struct socket *sock, - struct msghdr *msg, size_t len, int flags) + struct msghdr *msg, size_t len, int flags) { int noblock = flags & MSG_DONTWAIT; struct sock *sk = sock->sk; @@ -274,7 +274,7 @@ static void rawsock_destruct(struct sock *sk) if (sk->sk_state == TCP_ESTABLISHED) { nfc_deactivate_target(nfc_rawsock(sk)->dev, - nfc_rawsock(sk)->target_idx); + nfc_rawsock(sk)->target_idx); nfc_put_device(nfc_rawsock(sk)->dev); } @@ -287,7 +287,7 @@ static void rawsock_destruct(struct sock *sk) } static int rawsock_create(struct net *net, struct socket *sock, - const struct nfc_protocol *nfc_proto) + const struct nfc_protocol *nfc_proto) { struct sock *sk; -- cgit From eb9bc6e9a0ac668d2283b8fea1534f8ba31d1692 Mon Sep 17 00:00:00 2001 From: Samuel Ortiz Date: Mon, 5 Mar 2012 01:03:54 +0100 Subject: NFC: NCI code identation fixes Signed-off-by: Samuel Ortiz Signed-off-by: John W. Linville --- include/net/nfc/nci_core.h | 10 ++-- net/nfc/nci/core.c | 113 ++++++++++++++++++++++----------------------- net/nfc/nci/data.c | 28 +++++------ net/nfc/nci/ntf.c | 75 ++++++++++++++---------------- net/nfc/nci/rsp.c | 17 ++++--- 5 files changed, 116 insertions(+), 127 deletions(-) diff --git a/include/net/nfc/nci_core.h b/include/net/nfc/nci_core.h index 86fee8b5c65c..feba74027ff8 100644 --- a/include/net/nfc/nci_core.h +++ b/include/net/nfc/nci_core.h @@ -141,17 +141,17 @@ struct nci_dev { /* ----- NCI Devices ----- */ struct nci_dev *nci_allocate_device(struct nci_ops *ops, - __u32 supported_protocols, - int tx_headroom, - int tx_tailroom); + __u32 supported_protocols, + int tx_headroom, + int tx_tailroom); void nci_free_device(struct nci_dev *ndev); int nci_register_device(struct nci_dev *ndev); void nci_unregister_device(struct nci_dev *ndev); int nci_recv_frame(struct sk_buff *skb); static inline struct sk_buff *nci_skb_alloc(struct nci_dev *ndev, - unsigned int len, - gfp_t how) + unsigned int len, + gfp_t how) { struct sk_buff *skb; diff --git a/net/nfc/nci/core.c b/net/nfc/nci/core.c index a47e90c7d9d1..9ec065bb9ee1 100644 --- a/net/nfc/nci/core.c +++ b/net/nfc/nci/core.c @@ -66,9 +66,8 @@ static void nci_req_cancel(struct nci_dev *ndev, int err) /* Execute request and wait for completion. */ static int __nci_request(struct nci_dev *ndev, - void (*req)(struct nci_dev *ndev, unsigned long opt), - unsigned long opt, - __u32 timeout) + void (*req)(struct nci_dev *ndev, unsigned long opt), + unsigned long opt, __u32 timeout) { int rc = 0; long completion_rc; @@ -77,9 +76,9 @@ static int __nci_request(struct nci_dev *ndev, init_completion(&ndev->req_completion); req(ndev, opt); - completion_rc = wait_for_completion_interruptible_timeout( - &ndev->req_completion, - timeout); + completion_rc = + wait_for_completion_interruptible_timeout(&ndev->req_completion, + timeout); pr_debug("wait_for_completion return %ld\n", completion_rc); @@ -110,8 +109,9 @@ static int __nci_request(struct nci_dev *ndev, } static inline int nci_request(struct nci_dev *ndev, - void (*req)(struct nci_dev *ndev, unsigned long opt), - unsigned long opt, __u32 timeout) + void (*req)(struct nci_dev *ndev, + unsigned long opt), + unsigned long opt, __u32 timeout) { int rc; @@ -152,14 +152,14 @@ static void nci_init_complete_req(struct nci_dev *ndev, unsigned long opt) /* by default mapping is set to NCI_RF_INTERFACE_FRAME */ for (i = 0; i < ndev->num_supported_rf_interfaces; i++) { if (ndev->supported_rf_interfaces[i] == - NCI_RF_INTERFACE_ISO_DEP) { + NCI_RF_INTERFACE_ISO_DEP) { cfg[*num].rf_protocol = NCI_RF_PROTOCOL_ISO_DEP; cfg[*num].mode = NCI_DISC_MAP_MODE_POLL | NCI_DISC_MAP_MODE_LISTEN; cfg[*num].rf_interface = NCI_RF_INTERFACE_ISO_DEP; (*num)++; } else if (ndev->supported_rf_interfaces[i] == - NCI_RF_INTERFACE_NFC_DEP) { + NCI_RF_INTERFACE_NFC_DEP) { cfg[*num].rf_protocol = NCI_RF_PROTOCOL_NFC_DEP; cfg[*num].mode = NCI_DISC_MAP_MODE_POLL | NCI_DISC_MAP_MODE_LISTEN; @@ -172,8 +172,7 @@ static void nci_init_complete_req(struct nci_dev *ndev, unsigned long opt) } nci_send_cmd(ndev, NCI_OP_RF_DISCOVER_MAP_CMD, - (1 + ((*num)*sizeof(struct disc_map_config))), - &cmd); + (1 + ((*num) * sizeof(struct disc_map_config))), &cmd); } static void nci_rf_discover_req(struct nci_dev *ndev, unsigned long opt) @@ -184,36 +183,36 @@ static void nci_rf_discover_req(struct nci_dev *ndev, unsigned long opt) cmd.num_disc_configs = 0; if ((cmd.num_disc_configs < NCI_MAX_NUM_RF_CONFIGS) && - (protocols & NFC_PROTO_JEWEL_MASK - || protocols & NFC_PROTO_MIFARE_MASK - || protocols & NFC_PROTO_ISO14443_MASK - || protocols & NFC_PROTO_NFC_DEP_MASK)) { + (protocols & NFC_PROTO_JEWEL_MASK + || protocols & NFC_PROTO_MIFARE_MASK + || protocols & NFC_PROTO_ISO14443_MASK + || protocols & NFC_PROTO_NFC_DEP_MASK)) { cmd.disc_configs[cmd.num_disc_configs].rf_tech_and_mode = - NCI_NFC_A_PASSIVE_POLL_MODE; + NCI_NFC_A_PASSIVE_POLL_MODE; cmd.disc_configs[cmd.num_disc_configs].frequency = 1; cmd.num_disc_configs++; } if ((cmd.num_disc_configs < NCI_MAX_NUM_RF_CONFIGS) && - (protocols & NFC_PROTO_ISO14443_MASK)) { + (protocols & NFC_PROTO_ISO14443_MASK)) { cmd.disc_configs[cmd.num_disc_configs].rf_tech_and_mode = - NCI_NFC_B_PASSIVE_POLL_MODE; + NCI_NFC_B_PASSIVE_POLL_MODE; cmd.disc_configs[cmd.num_disc_configs].frequency = 1; cmd.num_disc_configs++; } if ((cmd.num_disc_configs < NCI_MAX_NUM_RF_CONFIGS) && - (protocols & NFC_PROTO_FELICA_MASK - || protocols & NFC_PROTO_NFC_DEP_MASK)) { + (protocols & NFC_PROTO_FELICA_MASK + || protocols & NFC_PROTO_NFC_DEP_MASK)) { cmd.disc_configs[cmd.num_disc_configs].rf_tech_and_mode = - NCI_NFC_F_PASSIVE_POLL_MODE; + NCI_NFC_F_PASSIVE_POLL_MODE; cmd.disc_configs[cmd.num_disc_configs].frequency = 1; cmd.num_disc_configs++; } nci_send_cmd(ndev, NCI_OP_RF_DISCOVER_CMD, - (1 + (cmd.num_disc_configs*sizeof(struct disc_config))), - &cmd); + (1 + (cmd.num_disc_configs * sizeof(struct disc_config))), + &cmd); } struct nci_rf_discover_select_param { @@ -224,7 +223,7 @@ struct nci_rf_discover_select_param { static void nci_rf_discover_select_req(struct nci_dev *ndev, unsigned long opt) { struct nci_rf_discover_select_param *param = - (struct nci_rf_discover_select_param *)opt; + (struct nci_rf_discover_select_param *)opt; struct nci_rf_discover_select_cmd cmd; cmd.rf_discovery_id = param->rf_discovery_id; @@ -245,8 +244,7 @@ static void nci_rf_discover_select_req(struct nci_dev *ndev, unsigned long opt) } nci_send_cmd(ndev, NCI_OP_RF_DISCOVER_SELECT_CMD, - sizeof(struct nci_rf_discover_select_cmd), - &cmd); + sizeof(struct nci_rf_discover_select_cmd), &cmd); } static void nci_rf_deactivate_req(struct nci_dev *ndev, unsigned long opt) @@ -256,8 +254,7 @@ static void nci_rf_deactivate_req(struct nci_dev *ndev, unsigned long opt) cmd.type = NCI_DEACTIVATE_TYPE_IDLE_MODE; nci_send_cmd(ndev, NCI_OP_RF_DEACTIVATE_CMD, - sizeof(struct nci_rf_deactivate_cmd), - &cmd); + sizeof(struct nci_rf_deactivate_cmd), &cmd); } static int nci_open_device(struct nci_dev *ndev) @@ -281,16 +278,16 @@ static int nci_open_device(struct nci_dev *ndev) set_bit(NCI_INIT, &ndev->flags); rc = __nci_request(ndev, nci_reset_req, 0, - msecs_to_jiffies(NCI_RESET_TIMEOUT)); + msecs_to_jiffies(NCI_RESET_TIMEOUT)); if (!rc) { rc = __nci_request(ndev, nci_init_req, 0, - msecs_to_jiffies(NCI_INIT_TIMEOUT)); + msecs_to_jiffies(NCI_INIT_TIMEOUT)); } if (!rc) { rc = __nci_request(ndev, nci_init_complete_req, 0, - msecs_to_jiffies(NCI_INIT_TIMEOUT)); + msecs_to_jiffies(NCI_INIT_TIMEOUT)); } clear_bit(NCI_INIT, &ndev->flags); @@ -340,7 +337,7 @@ static int nci_close_device(struct nci_dev *ndev) set_bit(NCI_INIT, &ndev->flags); __nci_request(ndev, nci_reset_req, 0, - msecs_to_jiffies(NCI_RESET_TIMEOUT)); + msecs_to_jiffies(NCI_RESET_TIMEOUT)); clear_bit(NCI_INIT, &ndev->flags); /* Flush cmd wq */ @@ -396,7 +393,7 @@ static int nci_start_poll(struct nfc_dev *nfc_dev, __u32 protocols) int rc; if ((atomic_read(&ndev->state) == NCI_DISCOVERY) || - (atomic_read(&ndev->state) == NCI_W4_ALL_DISCOVERIES)) { + (atomic_read(&ndev->state) == NCI_W4_ALL_DISCOVERIES)) { pr_err("unable to start poll, since poll is already active\n"); return -EBUSY; } @@ -407,17 +404,17 @@ static int nci_start_poll(struct nfc_dev *nfc_dev, __u32 protocols) } if ((atomic_read(&ndev->state) == NCI_W4_HOST_SELECT) || - (atomic_read(&ndev->state) == NCI_POLL_ACTIVE)) { + (atomic_read(&ndev->state) == NCI_POLL_ACTIVE)) { pr_debug("target active or w4 select, implicitly deactivate\n"); rc = nci_request(ndev, nci_rf_deactivate_req, 0, - msecs_to_jiffies(NCI_RF_DEACTIVATE_TIMEOUT)); + msecs_to_jiffies(NCI_RF_DEACTIVATE_TIMEOUT)); if (rc) return -EBUSY; } rc = nci_request(ndev, nci_rf_discover_req, protocols, - msecs_to_jiffies(NCI_RF_DISC_TIMEOUT)); + msecs_to_jiffies(NCI_RF_DISC_TIMEOUT)); if (!rc) ndev->poll_prots = protocols; @@ -430,17 +427,17 @@ static void nci_stop_poll(struct nfc_dev *nfc_dev) struct nci_dev *ndev = nfc_get_drvdata(nfc_dev); if ((atomic_read(&ndev->state) != NCI_DISCOVERY) && - (atomic_read(&ndev->state) != NCI_W4_ALL_DISCOVERIES)) { + (atomic_read(&ndev->state) != NCI_W4_ALL_DISCOVERIES)) { pr_err("unable to stop poll, since poll is not active\n"); return; } nci_request(ndev, nci_rf_deactivate_req, 0, - msecs_to_jiffies(NCI_RF_DEACTIVATE_TIMEOUT)); + msecs_to_jiffies(NCI_RF_DEACTIVATE_TIMEOUT)); } static int nci_activate_target(struct nfc_dev *nfc_dev, __u32 target_idx, - __u32 protocol) + __u32 protocol) { struct nci_dev *ndev = nfc_get_drvdata(nfc_dev); struct nci_rf_discover_select_param param; @@ -451,7 +448,7 @@ static int nci_activate_target(struct nfc_dev *nfc_dev, __u32 target_idx, pr_debug("target_idx %d, protocol 0x%x\n", target_idx, protocol); if ((atomic_read(&ndev->state) != NCI_W4_HOST_SELECT) && - (atomic_read(&ndev->state) != NCI_POLL_ACTIVE)) { + (atomic_read(&ndev->state) != NCI_POLL_ACTIVE)) { pr_err("there is no available target to activate\n"); return -EINVAL; } @@ -494,8 +491,8 @@ static int nci_activate_target(struct nfc_dev *nfc_dev, __u32 target_idx, param.rf_protocol = NCI_RF_PROTOCOL_NFC_DEP; rc = nci_request(ndev, nci_rf_discover_select_req, - (unsigned long)¶m, - msecs_to_jiffies(NCI_RF_DISC_SELECT_TIMEOUT)); + (unsigned long)¶m, + msecs_to_jiffies(NCI_RF_DISC_SELECT_TIMEOUT)); } if (!rc) @@ -519,14 +516,13 @@ static void nci_deactivate_target(struct nfc_dev *nfc_dev, __u32 target_idx) if (atomic_read(&ndev->state) == NCI_POLL_ACTIVE) { nci_request(ndev, nci_rf_deactivate_req, 0, - msecs_to_jiffies(NCI_RF_DEACTIVATE_TIMEOUT)); + msecs_to_jiffies(NCI_RF_DEACTIVATE_TIMEOUT)); } } static int nci_data_exchange(struct nfc_dev *nfc_dev, __u32 target_idx, - struct sk_buff *skb, - data_exchange_cb_t cb, - void *cb_context) + struct sk_buff *skb, + data_exchange_cb_t cb, void *cb_context) { struct nci_dev *ndev = nfc_get_drvdata(nfc_dev); int rc; @@ -571,9 +567,8 @@ static struct nfc_ops nci_nfc_ops = { * @supported_protocols: NFC protocols supported by the device */ struct nci_dev *nci_allocate_device(struct nci_ops *ops, - __u32 supported_protocols, - int tx_headroom, - int tx_tailroom) + __u32 supported_protocols, + int tx_headroom, int tx_tailroom) { struct nci_dev *ndev; @@ -594,9 +589,9 @@ struct nci_dev *nci_allocate_device(struct nci_ops *ops, ndev->tx_tailroom = tx_tailroom; ndev->nfc_dev = nfc_allocate_device(&nci_nfc_ops, - supported_protocols, - tx_headroom + NCI_DATA_HDR_SIZE, - tx_tailroom); + supported_protocols, + tx_headroom + NCI_DATA_HDR_SIZE, + tx_tailroom); if (!ndev->nfc_dev) goto free_exit; @@ -668,9 +663,9 @@ int nci_register_device(struct nci_dev *ndev) skb_queue_head_init(&ndev->tx_q); setup_timer(&ndev->cmd_timer, nci_cmd_timer, - (unsigned long) ndev); + (unsigned long) ndev); setup_timer(&ndev->data_timer, nci_data_timer, - (unsigned long) ndev); + (unsigned long) ndev); mutex_init(&ndev->req_lock); @@ -719,7 +714,7 @@ int nci_recv_frame(struct sk_buff *skb) pr_debug("len %d\n", skb->len); if (!ndev || (!test_bit(NCI_UP, &ndev->flags) - && !test_bit(NCI_INIT, &ndev->flags))) { + && !test_bit(NCI_INIT, &ndev->flags))) { kfree_skb(skb); return -ENXIO; } @@ -799,7 +794,7 @@ static void nci_tx_work(struct work_struct *work) /* Check if data flow control is used */ if (atomic_read(&ndev->credits_cnt) != - NCI_DATA_FLOW_CONTROL_NOT_USED) + NCI_DATA_FLOW_CONTROL_NOT_USED) atomic_dec(&ndev->credits_cnt); pr_debug("NCI TX: MT=data, PBF=%d, conn_id=%d, plen=%d\n", @@ -810,7 +805,7 @@ static void nci_tx_work(struct work_struct *work) nci_send_frame(skb); mod_timer(&ndev->data_timer, - jiffies + msecs_to_jiffies(NCI_DATA_TIMEOUT)); + jiffies + msecs_to_jiffies(NCI_DATA_TIMEOUT)); } } @@ -879,6 +874,6 @@ static void nci_cmd_work(struct work_struct *work) nci_send_frame(skb); mod_timer(&ndev->cmd_timer, - jiffies + msecs_to_jiffies(NCI_CMD_TIMEOUT)); + jiffies + msecs_to_jiffies(NCI_CMD_TIMEOUT)); } } diff --git a/net/nfc/nci/data.c b/net/nfc/nci/data.c index 7880ae924d5e..a0bc326308a5 100644 --- a/net/nfc/nci/data.c +++ b/net/nfc/nci/data.c @@ -35,8 +35,7 @@ #include /* Complete data exchange transaction and forward skb to nfc core */ -void nci_data_exchange_complete(struct nci_dev *ndev, - struct sk_buff *skb, +void nci_data_exchange_complete(struct nci_dev *ndev, struct sk_buff *skb, int err) { data_exchange_cb_t cb = ndev->data_exchange_cb; @@ -67,9 +66,9 @@ void nci_data_exchange_complete(struct nci_dev *ndev, /* ----------------- NCI TX Data ----------------- */ static inline void nci_push_data_hdr(struct nci_dev *ndev, - __u8 conn_id, - struct sk_buff *skb, - __u8 pbf) + __u8 conn_id, + struct sk_buff *skb, + __u8 pbf) { struct nci_data_hdr *hdr; int plen = skb->len; @@ -86,8 +85,8 @@ static inline void nci_push_data_hdr(struct nci_dev *ndev, } static int nci_queue_tx_data_frags(struct nci_dev *ndev, - __u8 conn_id, - struct sk_buff *skb) { + __u8 conn_id, + struct sk_buff *skb) { int total_len = skb->len; unsigned char *data = skb->data; unsigned long flags; @@ -105,8 +104,8 @@ static int nci_queue_tx_data_frags(struct nci_dev *ndev, min_t(int, total_len, ndev->max_data_pkt_payload_size); skb_frag = nci_skb_alloc(ndev, - (NCI_DATA_HDR_SIZE + frag_len), - GFP_KERNEL); + (NCI_DATA_HDR_SIZE + frag_len), + GFP_KERNEL); if (skb_frag == NULL) { rc = -ENOMEM; goto free_exit; @@ -118,7 +117,8 @@ static int nci_queue_tx_data_frags(struct nci_dev *ndev, /* second, set the header */ nci_push_data_hdr(ndev, conn_id, skb_frag, - ((total_len == frag_len) ? (NCI_PBF_LAST) : (NCI_PBF_CONT))); + ((total_len == frag_len) ? + (NCI_PBF_LAST) : (NCI_PBF_CONT))); __skb_queue_tail(&frags_q, skb_frag); @@ -186,8 +186,8 @@ exit: /* ----------------- NCI RX Data ----------------- */ static void nci_add_rx_data_frag(struct nci_dev *ndev, - struct sk_buff *skb, - __u8 pbf) + struct sk_buff *skb, + __u8 pbf) { int reassembly_len; int err = 0; @@ -211,8 +211,8 @@ static void nci_add_rx_data_frag(struct nci_dev *ndev, /* second, combine the two fragments */ memcpy(skb_push(skb, reassembly_len), - ndev->rx_data_reassembly->data, - reassembly_len); + ndev->rx_data_reassembly->data, + reassembly_len); /* third, free old reassembly */ kfree_skb(ndev->rx_data_reassembly); diff --git a/net/nfc/nci/ntf.c b/net/nfc/nci/ntf.c index 03e7b4626a3e..2e3dee42196d 100644 --- a/net/nfc/nci/ntf.c +++ b/net/nfc/nci/ntf.c @@ -40,7 +40,7 @@ /* Handle NCI Notification packets */ static void nci_core_conn_credits_ntf_packet(struct nci_dev *ndev, - struct sk_buff *skb) + struct sk_buff *skb) { struct nci_core_conn_credit_ntf *ntf = (void *) skb->data; int i; @@ -62,7 +62,7 @@ static void nci_core_conn_credits_ntf_packet(struct nci_dev *ndev, if (ntf->conn_entries[i].conn_id == NCI_STATIC_RF_CONN_ID) { /* found static rf connection */ atomic_add(ntf->conn_entries[i].credits, - &ndev->credits_cnt); + &ndev->credits_cnt); } } @@ -72,7 +72,7 @@ static void nci_core_conn_credits_ntf_packet(struct nci_dev *ndev, } static void nci_core_generic_error_ntf_packet(struct nci_dev *ndev, - struct sk_buff *skb) + struct sk_buff *skb) { __u8 status = skb->data[0]; @@ -80,7 +80,7 @@ static void nci_core_generic_error_ntf_packet(struct nci_dev *ndev, if (atomic_read(&ndev->state) == NCI_W4_HOST_SELECT) { /* Activation failed, so complete the request - (the state remains the same) */ + (the state remains the same) */ nci_req_complete(ndev, status); } } @@ -101,7 +101,7 @@ static void nci_core_conn_intf_error_ntf_packet(struct nci_dev *ndev, static __u8 *nci_extract_rf_params_nfca_passive_poll(struct nci_dev *ndev, struct rf_tech_specific_params_nfca_poll *nfca_poll, - __u8 *data) + __u8 *data) { nfca_poll->sens_res = __le16_to_cpu(*((__u16 *)data)); data += 2; @@ -128,7 +128,7 @@ static __u8 *nci_extract_rf_params_nfca_passive_poll(struct nci_dev *ndev, static __u8 *nci_extract_rf_params_nfcb_passive_poll(struct nci_dev *ndev, struct rf_tech_specific_params_nfcb_poll *nfcb_poll, - __u8 *data) + __u8 *data) { nfcb_poll->sensb_res_len = *data++; @@ -142,13 +142,13 @@ static __u8 *nci_extract_rf_params_nfcb_passive_poll(struct nci_dev *ndev, static __u8 *nci_extract_rf_params_nfcf_passive_poll(struct nci_dev *ndev, struct rf_tech_specific_params_nfcf_poll *nfcf_poll, - __u8 *data) + __u8 *data) { nfcf_poll->bit_rate = *data++; nfcf_poll->sensf_res_len = *data++; pr_debug("bit_rate %d, sensf_res_len %d\n", - nfcf_poll->bit_rate, nfcf_poll->sensf_res_len); + nfcf_poll->bit_rate, nfcf_poll->sensf_res_len); memcpy(nfcf_poll->sensf_res, data, nfcf_poll->sensf_res_len); data += nfcf_poll->sensf_res_len; @@ -189,7 +189,7 @@ static int nci_add_new_protocol(struct nci_dev *ndev, target->nfcid1_len = nfca_poll->nfcid1_len; if (target->nfcid1_len > 0) { memcpy(target->nfcid1, nfca_poll->nfcid1, - target->nfcid1_len); + target->nfcid1_len); } } else if (rf_tech_and_mode == NCI_NFC_B_PASSIVE_POLL_MODE) { nfcb_poll = (struct rf_tech_specific_params_nfcb_poll *)params; @@ -197,7 +197,7 @@ static int nci_add_new_protocol(struct nci_dev *ndev, target->sensb_res_len = nfcb_poll->sensb_res_len; if (target->sensb_res_len > 0) { memcpy(target->sensb_res, nfcb_poll->sensb_res, - target->sensb_res_len); + target->sensb_res_len); } } else if (rf_tech_and_mode == NCI_NFC_F_PASSIVE_POLL_MODE) { nfcf_poll = (struct rf_tech_specific_params_nfcf_poll *)params; @@ -205,7 +205,7 @@ static int nci_add_new_protocol(struct nci_dev *ndev, target->sensf_res_len = nfcf_poll->sensf_res_len; if (target->sensf_res_len > 0) { memcpy(target->sensf_res, nfcf_poll->sensf_res, - target->sensf_res_len); + target->sensf_res_len); } } else { pr_err("unsupported rf_tech_and_mode 0x%x\n", rf_tech_and_mode); @@ -220,7 +220,7 @@ static int nci_add_new_protocol(struct nci_dev *ndev, } static void nci_add_new_target(struct nci_dev *ndev, - struct nci_rf_discover_ntf *ntf) + struct nci_rf_discover_ntf *ntf) { struct nfc_target *target; int i, rc; @@ -230,8 +230,8 @@ static void nci_add_new_target(struct nci_dev *ndev, if (target->idx == ntf->rf_discovery_id) { /* This target already exists, add the new protocol */ nci_add_new_protocol(ndev, target, ntf->rf_protocol, - ntf->rf_tech_and_mode, - &ntf->rf_tech_specific_params); + ntf->rf_tech_and_mode, + &ntf->rf_tech_specific_params); return; } } @@ -245,27 +245,27 @@ static void nci_add_new_target(struct nci_dev *ndev, target = &ndev->targets[ndev->n_targets]; rc = nci_add_new_protocol(ndev, target, ntf->rf_protocol, - ntf->rf_tech_and_mode, - &ntf->rf_tech_specific_params); + ntf->rf_tech_and_mode, + &ntf->rf_tech_specific_params); if (!rc) { target->idx = ntf->rf_discovery_id; ndev->n_targets++; pr_debug("target_idx %d, n_targets %d\n", target->idx, - ndev->n_targets); + ndev->n_targets); } } void nci_clear_target_list(struct nci_dev *ndev) { memset(ndev->targets, 0, - (sizeof(struct nfc_target)*NCI_MAX_DISCOVERED_TARGETS)); + (sizeof(struct nfc_target)*NCI_MAX_DISCOVERED_TARGETS)); ndev->n_targets = 0; } static void nci_rf_discover_ntf_packet(struct nci_dev *ndev, - struct sk_buff *skb) + struct sk_buff *skb) { struct nci_rf_discover_ntf ntf; __u8 *data = skb->data; @@ -280,7 +280,7 @@ static void nci_rf_discover_ntf_packet(struct nci_dev *ndev, pr_debug("rf_protocol 0x%x\n", ntf.rf_protocol); pr_debug("rf_tech_and_mode 0x%x\n", ntf.rf_tech_and_mode); pr_debug("rf_tech_specific_params_len %d\n", - ntf.rf_tech_specific_params_len); + ntf.rf_tech_specific_params_len); if (ntf.rf_tech_specific_params_len > 0) { switch (ntf.rf_tech_and_mode) { @@ -318,7 +318,7 @@ static void nci_rf_discover_ntf_packet(struct nci_dev *ndev, } else { atomic_set(&ndev->state, NCI_W4_HOST_SELECT); nfc_targets_found(ndev->nfc_dev, ndev->targets, - ndev->n_targets); + ndev->n_targets); } } @@ -335,20 +335,17 @@ static int nci_extract_activation_params_iso_dep(struct nci_dev *ndev, pr_debug("rats_res_len %d\n", nfca_poll->rats_res_len); if (nfca_poll->rats_res_len > 0) { memcpy(nfca_poll->rats_res, - data, - nfca_poll->rats_res_len); + data, nfca_poll->rats_res_len); } break; case NCI_NFC_B_PASSIVE_POLL_MODE: nfcb_poll = &ntf->activation_params.nfcb_poll_iso_dep; nfcb_poll->attrib_res_len = *data++; - pr_debug("attrib_res_len %d\n", - nfcb_poll->attrib_res_len); + pr_debug("attrib_res_len %d\n", nfcb_poll->attrib_res_len); if (nfcb_poll->attrib_res_len > 0) { memcpy(nfcb_poll->attrib_res, - data, - nfcb_poll->attrib_res_len); + data, nfcb_poll->attrib_res_len); } break; @@ -362,7 +359,7 @@ static int nci_extract_activation_params_iso_dep(struct nci_dev *ndev, } static void nci_target_auto_activated(struct nci_dev *ndev, - struct nci_rf_intf_activated_ntf *ntf) + struct nci_rf_intf_activated_ntf *ntf) { struct nfc_target *target; int rc; @@ -370,8 +367,8 @@ static void nci_target_auto_activated(struct nci_dev *ndev, target = &ndev->targets[ndev->n_targets]; rc = nci_add_new_protocol(ndev, target, ntf->rf_protocol, - ntf->activation_rf_tech_and_mode, - &ntf->rf_tech_specific_params); + ntf->activation_rf_tech_and_mode, + &ntf->rf_tech_specific_params); if (rc) return; @@ -384,7 +381,7 @@ static void nci_target_auto_activated(struct nci_dev *ndev, } static void nci_rf_intf_activated_ntf_packet(struct nci_dev *ndev, - struct sk_buff *skb) + struct sk_buff *skb) { struct nci_rf_intf_activated_ntf ntf; __u8 *data = skb->data; @@ -405,7 +402,8 @@ static void nci_rf_intf_activated_ntf_packet(struct nci_dev *ndev, ntf.activation_rf_tech_and_mode); pr_debug("max_data_pkt_payload_size 0x%x\n", ntf.max_data_pkt_payload_size); - pr_debug("initial_num_credits 0x%x\n", ntf.initial_num_credits); + pr_debug("initial_num_credits 0x%x\n", + ntf.initial_num_credits); pr_debug("rf_tech_specific_params_len %d\n", ntf.rf_tech_specific_params_len); @@ -441,18 +439,15 @@ static void nci_rf_intf_activated_ntf_packet(struct nci_dev *ndev, pr_debug("data_exch_rf_tech_and_mode 0x%x\n", ntf.data_exch_rf_tech_and_mode); - pr_debug("data_exch_tx_bit_rate 0x%x\n", - ntf.data_exch_tx_bit_rate); - pr_debug("data_exch_rx_bit_rate 0x%x\n", - ntf.data_exch_rx_bit_rate); - pr_debug("activation_params_len %d\n", - ntf.activation_params_len); + pr_debug("data_exch_tx_bit_rate 0x%x\n", ntf.data_exch_tx_bit_rate); + pr_debug("data_exch_rx_bit_rate 0x%x\n", ntf.data_exch_rx_bit_rate); + pr_debug("activation_params_len %d\n", ntf.activation_params_len); if (ntf.activation_params_len > 0) { switch (ntf.rf_interface) { case NCI_RF_INTERFACE_ISO_DEP: err = nci_extract_activation_params_iso_dep(ndev, - &ntf, data); + &ntf, data); break; case NCI_RF_INTERFACE_FRAME: @@ -489,7 +484,7 @@ exit: } static void nci_rf_deactivate_ntf_packet(struct nci_dev *ndev, - struct sk_buff *skb) + struct sk_buff *skb) { struct nci_rf_deactivate_ntf *ntf = (void *) skb->data; diff --git a/net/nfc/nci/rsp.c b/net/nfc/nci/rsp.c index aa63b1e99188..3003c3390e49 100644 --- a/net/nfc/nci/rsp.c +++ b/net/nfc/nci/rsp.c @@ -67,19 +67,18 @@ static void nci_core_init_rsp_packet(struct nci_dev *ndev, struct sk_buff *skb) ndev->num_supported_rf_interfaces = rsp_1->num_supported_rf_interfaces; if (ndev->num_supported_rf_interfaces > - NCI_MAX_SUPPORTED_RF_INTERFACES) { + NCI_MAX_SUPPORTED_RF_INTERFACES) { ndev->num_supported_rf_interfaces = NCI_MAX_SUPPORTED_RF_INTERFACES; } memcpy(ndev->supported_rf_interfaces, - rsp_1->supported_rf_interfaces, - ndev->num_supported_rf_interfaces); + rsp_1->supported_rf_interfaces, + ndev->num_supported_rf_interfaces); rsp_2 = (void *) (skb->data + 6 + rsp_1->num_supported_rf_interfaces); - ndev->max_logical_connections = - rsp_2->max_logical_connections; + ndev->max_logical_connections = rsp_2->max_logical_connections; ndev->max_routing_table_size = __le16_to_cpu(rsp_2->max_routing_table_size); ndev->max_ctrl_pkt_payload_len = @@ -121,7 +120,7 @@ exit: } static void nci_rf_disc_map_rsp_packet(struct nci_dev *ndev, - struct sk_buff *skb) + struct sk_buff *skb) { __u8 status = skb->data[0]; @@ -143,7 +142,7 @@ static void nci_rf_disc_rsp_packet(struct nci_dev *ndev, struct sk_buff *skb) } static void nci_rf_disc_select_rsp_packet(struct nci_dev *ndev, - struct sk_buff *skb) + struct sk_buff *skb) { __u8 status = skb->data[0]; @@ -155,7 +154,7 @@ static void nci_rf_disc_select_rsp_packet(struct nci_dev *ndev, } static void nci_rf_deactivate_rsp_packet(struct nci_dev *ndev, - struct sk_buff *skb) + struct sk_buff *skb) { __u8 status = skb->data[0]; @@ -163,7 +162,7 @@ static void nci_rf_deactivate_rsp_packet(struct nci_dev *ndev, /* If target was active, complete the request only in deactivate_ntf */ if ((status != NCI_STATUS_OK) || - (atomic_read(&ndev->state) != NCI_POLL_ACTIVE)) { + (atomic_read(&ndev->state) != NCI_POLL_ACTIVE)) { nci_clear_target_list(ndev); atomic_set(&ndev->state, NCI_IDLE); nci_req_complete(ndev, status); -- cgit From fcff4f108dce0692410f390a05565f4b1b84577f Mon Sep 17 00:00:00 2001 From: Paul Stewart Date: Thu, 23 Feb 2012 17:59:53 -0800 Subject: mac80211: Filter duplicate IE ids mac80211 is lenient with respect to reception of corrupted beacons. Even if the frame is corrupted as a whole, the available IE elements are still passed back and accepted, sometimes replacing legitimate data. It is unknown to what extent this "feature" is made use of, but it is clear that in some cases, this is detrimental. One such case is reported in http://crosbug.com/26832 where an AP corrupts its beacons but not its probe responses. One approach would be to completely reject frames with invaid data (for example, if the last tag extends beyond the end of the enclosing PDU). The enclosed approach is much more conservative: we simply prevent later IEs from overwriting the state from previous ones. This approach hopes that there might be some salient data in the IE stream before the corruption, and seeks to at least prevent that data from being overwritten. This approach will fix the case above. Further, we flag element structures that contain data we think might be corrupted, so that as we fill the mac80211 BSS structure, we try not to replace data from an un-corrupted probe response with that of a corrupted beacon, for example. Short of any statistics gathering in the various forms of AP breakage, it's not possible to ascertain the side effects of more stringent discarding of data. Signed-off-by: Paul Stewart Cc: Sam Leffler Cc: Eliad Peller Acked-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/ieee80211_i.h | 41 ++++++++++++++++++++++++++ net/mac80211/mlme.c | 14 +++++++++ net/mac80211/scan.c | 71 +++++++++++++++++++++++++++++++++------------- net/mac80211/util.c | 37 ++++++++++++++++++++++-- 4 files changed, 141 insertions(+), 22 deletions(-) diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 24cb1080e238..796b13bfc953 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -105,6 +105,44 @@ struct ieee80211_bss { */ bool has_erp_value; u8 erp_value; + + /* Keep track of the corruption of the last beacon/probe response. */ + u8 corrupt_data; + + /* Keep track of what bits of information we have valid info for. */ + u8 valid_data; +}; + +/** + * enum ieee80211_corrupt_data_flags - BSS data corruption flags + * @IEEE80211_BSS_CORRUPT_BEACON: last beacon frame received was corrupted + * @IEEE80211_BSS_CORRUPT_PROBE_RESP: last probe response received was corrupted + * + * These are bss flags that are attached to a bss in the + * @corrupt_data field of &struct ieee80211_bss. + */ +enum ieee80211_bss_corrupt_data_flags { + IEEE80211_BSS_CORRUPT_BEACON = BIT(0), + IEEE80211_BSS_CORRUPT_PROBE_RESP = BIT(1) +}; + +/** + * enum ieee80211_valid_data_flags - BSS valid data flags + * @IEEE80211_BSS_VALID_DTIM: DTIM data was gathered from non-corrupt IE + * @IEEE80211_BSS_VALID_WMM: WMM/UAPSD data was gathered from non-corrupt IE + * @IEEE80211_BSS_VALID_RATES: Supported rates were gathered from non-corrupt IE + * @IEEE80211_BSS_VALID_ERP: ERP flag was gathered from non-corrupt IE + * + * These are bss flags that are attached to a bss in the + * @valid_data field of &struct ieee80211_bss. They show which parts + * of the data structure were recieved as a result of an un-corrupted + * beacon/probe response. + */ +enum ieee80211_bss_valid_data_flags { + IEEE80211_BSS_VALID_DTIM = BIT(0), + IEEE80211_BSS_VALID_WMM = BIT(1), + IEEE80211_BSS_VALID_RATES = BIT(2), + IEEE80211_BSS_VALID_ERP = BIT(3) }; static inline u8 *bss_mesh_cfg(struct ieee80211_bss *bss) @@ -1120,6 +1158,9 @@ struct ieee802_11_elems { u8 quiet_elem_len; u8 num_of_quiet_elem; /* can be more the one */ u8 timeout_int_len; + + /* whether a parse error occurred while retrieving these elements */ + bool parse_error; }; static inline struct ieee80211_local *hw_to_local( diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 92c5eb124d6f..c08924aeac00 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -3446,6 +3446,20 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, } run_again(ifmgd, assoc_data->timeout); + if (bss->corrupt_data) { + char *corrupt_type = "data"; + if (bss->corrupt_data & IEEE80211_BSS_CORRUPT_BEACON) { + if (bss->corrupt_data & + IEEE80211_BSS_CORRUPT_PROBE_RESP) + corrupt_type = "beacon and probe response"; + else + corrupt_type = "beacon"; + } else if (bss->corrupt_data & IEEE80211_BSS_CORRUPT_PROBE_RESP) + corrupt_type = "probe response"; + printk(KERN_DEBUG "%s: associating with AP with corrupt %s\n", + sdata->name, corrupt_type); + } + err = 0; goto out; err_clear: diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index a9d7235df7c3..33cd16901378 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c @@ -104,16 +104,35 @@ ieee80211_bss_info_update(struct ieee80211_local *local, cbss->free_priv = ieee80211_rx_bss_free; bss = (void *)cbss->priv; + if (elems->parse_error) { + if (beacon) + bss->corrupt_data |= IEEE80211_BSS_CORRUPT_BEACON; + else + bss->corrupt_data |= IEEE80211_BSS_CORRUPT_PROBE_RESP; + } else { + if (beacon) + bss->corrupt_data &= ~IEEE80211_BSS_CORRUPT_BEACON; + else + bss->corrupt_data &= ~IEEE80211_BSS_CORRUPT_PROBE_RESP; + } + /* save the ERP value so that it is available at association time */ - if (elems->erp_info && elems->erp_info_len >= 1) { + if (elems->erp_info && elems->erp_info_len >= 1 && + (!elems->parse_error || + !(bss->valid_data & IEEE80211_BSS_VALID_ERP))) { bss->erp_value = elems->erp_info[0]; bss->has_erp_value = true; + if (!elems->parse_error) + bss->valid_data |= IEEE80211_BSS_VALID_ERP; } - if (elems->tim) { + if (elems->tim && (!elems->parse_error || + !(bss->valid_data & IEEE80211_BSS_VALID_DTIM))) { struct ieee80211_tim_ie *tim_ie = (struct ieee80211_tim_ie *)elems->tim; bss->dtim_period = tim_ie->dtim_period; + if (!elems->parse_error) + bss->valid_data |= IEEE80211_BSS_VALID_DTIM; } /* If the beacon had no TIM IE, or it was invalid, use 1 */ @@ -121,26 +140,38 @@ ieee80211_bss_info_update(struct ieee80211_local *local, bss->dtim_period = 1; /* replace old supported rates if we get new values */ - srlen = 0; - if (elems->supp_rates) { - clen = IEEE80211_MAX_SUPP_RATES; - if (clen > elems->supp_rates_len) - clen = elems->supp_rates_len; - memcpy(bss->supp_rates, elems->supp_rates, clen); - srlen += clen; - } - if (elems->ext_supp_rates) { - clen = IEEE80211_MAX_SUPP_RATES - srlen; - if (clen > elems->ext_supp_rates_len) - clen = elems->ext_supp_rates_len; - memcpy(bss->supp_rates + srlen, elems->ext_supp_rates, clen); - srlen += clen; + if (!elems->parse_error || + !(bss->valid_data & IEEE80211_BSS_VALID_RATES)) { + srlen = 0; + if (elems->supp_rates) { + clen = IEEE80211_MAX_SUPP_RATES; + if (clen > elems->supp_rates_len) + clen = elems->supp_rates_len; + memcpy(bss->supp_rates, elems->supp_rates, clen); + srlen += clen; + } + if (elems->ext_supp_rates) { + clen = IEEE80211_MAX_SUPP_RATES - srlen; + if (clen > elems->ext_supp_rates_len) + clen = elems->ext_supp_rates_len; + memcpy(bss->supp_rates + srlen, elems->ext_supp_rates, + clen); + srlen += clen; + } + if (srlen) { + bss->supp_rates_len = srlen; + if (!elems->parse_error) + bss->valid_data |= IEEE80211_BSS_VALID_RATES; + } } - if (srlen) - bss->supp_rates_len = srlen; - bss->wmm_used = elems->wmm_param || elems->wmm_info; - bss->uapsd_supported = is_uapsd_supported(elems); + if (!elems->parse_error || + !(bss->valid_data & IEEE80211_BSS_VALID_WMM)) { + bss->wmm_used = elems->wmm_param || elems->wmm_info; + bss->uapsd_supported = is_uapsd_supported(elems); + if (!elems->parse_error) + bss->valid_data |= IEEE80211_BSS_VALID_WMM; + } if (!beacon) bss->last_probe_resp = jiffies; diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 0a5ad95ac8b0..32f7a3b3d43c 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -572,24 +572,40 @@ u32 ieee802_11_parse_elems_crc(u8 *start, size_t len, size_t left = len; u8 *pos = start; bool calc_crc = filter != 0; + DECLARE_BITMAP(seen_elems, 256); + bitmap_zero(seen_elems, 256); memset(elems, 0, sizeof(*elems)); elems->ie_start = start; elems->total_len = len; while (left >= 2) { u8 id, elen; + bool elem_parse_failed; id = *pos++; elen = *pos++; left -= 2; - if (elen > left) + if (elen > left) { + elems->parse_error = true; break; + } + + if (id != WLAN_EID_VENDOR_SPECIFIC && + id != WLAN_EID_QUIET && + test_bit(id, seen_elems)) { + elems->parse_error = true; + left -= elen; + pos += elen; + continue; + } if (calc_crc && id < 64 && (filter & (1ULL << id))) crc = crc32_be(crc, pos - 2, elen + 2); + elem_parse_failed = false; + switch (id) { case WLAN_EID_SSID: elems->ssid = pos; @@ -615,7 +631,8 @@ u32 ieee802_11_parse_elems_crc(u8 *start, size_t len, if (elen >= sizeof(struct ieee80211_tim_ie)) { elems->tim = (void *)pos; elems->tim_len = elen; - } + } else + elem_parse_failed = true; break; case WLAN_EID_IBSS_PARAMS: elems->ibss_params = pos; @@ -664,10 +681,14 @@ u32 ieee802_11_parse_elems_crc(u8 *start, size_t len, case WLAN_EID_HT_CAPABILITY: if (elen >= sizeof(struct ieee80211_ht_cap)) elems->ht_cap_elem = (void *)pos; + else + elem_parse_failed = true; break; case WLAN_EID_HT_INFORMATION: if (elen >= sizeof(struct ieee80211_ht_info)) elems->ht_info_elem = (void *)pos; + else + elem_parse_failed = true; break; case WLAN_EID_MESH_ID: elems->mesh_id = pos; @@ -676,6 +697,8 @@ u32 ieee802_11_parse_elems_crc(u8 *start, size_t len, case WLAN_EID_MESH_CONFIG: if (elen >= sizeof(struct ieee80211_meshconf_ie)) elems->mesh_config = (void *)pos; + else + elem_parse_failed = true; break; case WLAN_EID_PEER_MGMT: elems->peering = pos; @@ -696,6 +719,8 @@ u32 ieee802_11_parse_elems_crc(u8 *start, size_t len, case WLAN_EID_RANN: if (elen >= sizeof(struct ieee80211_rann_ie)) elems->rann = (void *)pos; + else + elem_parse_failed = true; break; case WLAN_EID_CHANNEL_SWITCH: elems->ch_switch_elem = pos; @@ -724,10 +749,18 @@ u32 ieee802_11_parse_elems_crc(u8 *start, size_t len, break; } + if (elem_parse_failed) + elems->parse_error = true; + else + set_bit(id, seen_elems); + left -= elen; pos += elen; } + if (left != 0) + elems->parse_error = true; + return crc; } -- cgit From 9c083af8683808e486c20ca1f36da520d82e5981 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sat, 3 Mar 2012 15:17:02 +0100 Subject: ath9k_hw: use cold instead of warm reset on AR9280 Cold reset is more reliable for getting the hardware out of some specific stuck states. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hw.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 8c840cad3ac2..d582cf73098f 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -1386,10 +1386,16 @@ static bool ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 type) static bool ath9k_hw_chip_reset(struct ath_hw *ah, struct ath9k_channel *chan) { - if (AR_SREV_9280(ah) && ah->eep_ops->get_eeprom(ah, EEP_OL_PWRCTRL)) { - if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_POWER_ON)) - return false; - } else if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_WARM)) + int reset_type = ATH9K_RESET_WARM; + + if (AR_SREV_9280(ah)) { + if (ah->eep_ops->get_eeprom(ah, EEP_OL_PWRCTRL)) + reset_type = ATH9K_RESET_POWER_ON; + else + reset_type = ATH9K_RESET_COLD; + } + + if (!ath9k_hw_set_reset_reg(ah, reset_type)) return false; if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) -- cgit From 5baec7422c8c8f70c62b9493acf31d4854b09070 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sat, 3 Mar 2012 15:17:03 +0100 Subject: ath9k: make MAC sample statistics optional They're more expensive than some of the other debug options and only used in very rare situations, so it sometimes makes sense to disable them while leaving in debugfs support. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/Kconfig | 8 ++++++++ drivers/net/wireless/ath/ath9k/debug.c | 10 ++++++++++ drivers/net/wireless/ath/ath9k/debug.h | 20 +++++++++++++++----- drivers/net/wireless/ath/ath9k/init.c | 4 +++- 4 files changed, 36 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/Kconfig b/drivers/net/wireless/ath/ath9k/Kconfig index 595a272aa96e..e507e78398f3 100644 --- a/drivers/net/wireless/ath/ath9k/Kconfig +++ b/drivers/net/wireless/ath/ath9k/Kconfig @@ -81,6 +81,14 @@ config ATH9K_DFS_CERTIFIED developed. At this point enabling this option won't do anything except increase code size. +config ATH9K_MAC_DEBUG + bool "Atheros MAC statistics" + depends on ATH9K_DEBUGFS + default y + ---help--- + This option enables collection of statistics for Rx/Tx status + data and some other MAC related statistics + config ATH9K_RATE_CONTROL bool "Atheros ath9k rate control" depends on ATH9K diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c index 228c18189a3a..03a474092e8b 100644 --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c @@ -818,6 +818,7 @@ void ath_debug_stat_tx(struct ath_softc *sc, struct ath_buf *bf, if (ts->ts_flags & ATH9K_TX_DELIM_UNDERRUN) TX_STAT_INC(qnum, delim_underrun); +#ifdef CONFIG_ATH9K_MAC_DEBUG spin_lock(&sc->debug.samp_lock); TX_SAMP_DBG(jiffies) = jiffies; TX_SAMP_DBG(rssi_ctl0) = ts->ts_rssi_ctl0; @@ -844,6 +845,7 @@ void ath_debug_stat_tx(struct ath_softc *sc, struct ath_buf *bf, sc->debug.tsidx = (sc->debug.tsidx + 1) % ATH_DBG_MAX_SAMPLES; spin_unlock(&sc->debug.samp_lock); +#endif #undef TX_SAMP_DBG } @@ -1019,6 +1021,7 @@ void ath_debug_stat_rx(struct ath_softc *sc, struct ath_rx_status *rs) sc->debug.stats.rxstats.rs_antenna = rs->rs_antenna; +#ifdef CONFIG_ATH9K_MAC_DEBUG spin_lock(&sc->debug.samp_lock); RX_SAMP_DBG(jiffies) = jiffies; RX_SAMP_DBG(rssi_ctl0) = rs->rs_rssi_ctl0; @@ -1035,6 +1038,8 @@ void ath_debug_stat_rx(struct ath_softc *sc, struct ath_rx_status *rs) sc->debug.rsidx = (sc->debug.rsidx + 1) % ATH_DBG_MAX_SAMPLES; spin_unlock(&sc->debug.samp_lock); +#endif + #undef RX_STAT_INC #undef RX_PHY_ERR_INC #undef RX_SAMP_DBG @@ -1278,6 +1283,8 @@ static const struct file_operations fops_modal_eeprom = { .llseek = default_llseek, }; +#ifdef CONFIG_ATH9K_MAC_DEBUG + void ath9k_debug_samp_bb_mac(struct ath_softc *sc) { #define ATH_SAMP_DBG(c) (sc->debug.bb_mac_samp[sc->debug.sampidx].c) @@ -1551,6 +1558,7 @@ static const struct file_operations fops_samps = { .llseek = default_llseek, }; +#endif int ath9k_init_debug(struct ath_hw *ah) { @@ -1604,8 +1612,10 @@ int ath9k_init_debug(struct ath_hw *ah) &fops_base_eeprom); debugfs_create_file("modal_eeprom", S_IRUSR, sc->debug.debugfs_phy, sc, &fops_modal_eeprom); +#ifdef CONFIG_ATH9K_MAC_DEBUG debugfs_create_file("samples", S_IRUSR, sc->debug.debugfs_phy, sc, &fops_samps); +#endif debugfs_create_u32("gpio_mask", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, &sc->sc_ah->gpio_mask); diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h index 776a24ada600..7a519582232a 100644 --- a/drivers/net/wireless/ath/ath9k/debug.h +++ b/drivers/net/wireless/ath/ath9k/debug.h @@ -235,16 +235,17 @@ struct ath9k_debug { struct dentry *debugfs_phy; u32 regidx; struct ath_stats stats; +#ifdef CONFIG_ATH9K_MAC_DEBUG spinlock_t samp_lock; struct ath_dbg_bb_mac_samp bb_mac_samp[ATH_DBG_MAX_SAMPLES]; u8 sampidx; u8 tsidx; u8 rsidx; +#endif }; int ath9k_init_debug(struct ath_hw *ah); -void ath9k_debug_samp_bb_mac(struct ath_softc *sc); void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status); void ath_debug_stat_tx(struct ath_softc *sc, struct ath_buf *bf, struct ath_tx_status *ts, struct ath_txq *txq, @@ -258,10 +259,6 @@ static inline int ath9k_init_debug(struct ath_hw *ah) return 0; } -static inline void ath9k_debug_samp_bb_mac(struct ath_softc *sc) -{ -} - static inline void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status) { @@ -282,4 +279,17 @@ static inline void ath_debug_stat_rx(struct ath_softc *sc, #endif /* CONFIG_ATH9K_DEBUGFS */ +#ifdef CONFIG_ATH9K_MAC_DEBUG + +void ath9k_debug_samp_bb_mac(struct ath_softc *sc); + +#else + +static inline void ath9k_debug_samp_bb_mac(struct ath_softc *sc) +{ +} + +#endif + + #endif /* DEBUG_H */ diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index d8b05961f7e3..944e9b518f19 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c @@ -555,8 +555,10 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, mutex_init(&sc->mutex); #ifdef CONFIG_ATH9K_DEBUGFS spin_lock_init(&sc->nodes_lock); - spin_lock_init(&sc->debug.samp_lock); INIT_LIST_HEAD(&sc->nodes); +#endif +#ifdef CONFIG_ATH9K_MAC_DEBUG + spin_lock_init(&sc->debug.samp_lock); #endif tasklet_init(&sc->intr_tq, ath9k_tasklet, (unsigned long)sc); tasklet_init(&sc->bcon_tasklet, ath_beacon_tasklet, -- cgit From fc16fd8808968063929bbb198eb8bb46d40e36ce Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sat, 3 Mar 2012 15:17:04 +0100 Subject: ath9k: remove rssi/antenna information from recv debug stats The way this is implemented (simply storing the last value) is absolutely worthless for debugging anything, and the same information is also available through the MAC sample feature, so there's no point in keeping this around. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/debug.c | 31 ------------------------------- drivers/net/wireless/ath/ath9k/debug.h | 7 ------- 2 files changed, 38 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c index 03a474092e8b..c2edf688da49 100644 --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c @@ -943,27 +943,6 @@ static ssize_t read_file_recv(struct file *file, char __user *user_buf, PHY_ERR("HT-LENGTH ERR", ATH9K_PHYERR_HT_LENGTH_ILLEGAL); PHY_ERR("HT-RATE ERR", ATH9K_PHYERR_HT_RATE_ILLEGAL); - len += snprintf(buf + len, size - len, - "%22s : %10d\n", "RSSI-CTL0", - sc->debug.stats.rxstats.rs_rssi_ctl0); - len += snprintf(buf + len, size - len, - "%22s : %10d\n", "RSSI-CTL1", - sc->debug.stats.rxstats.rs_rssi_ctl1); - len += snprintf(buf + len, size - len, - "%22s : %10d\n", "RSSI-CTL2", - sc->debug.stats.rxstats.rs_rssi_ctl2); - len += snprintf(buf + len, size - len, - "%22s : %10d\n", "RSSI-EXT0", - sc->debug.stats.rxstats.rs_rssi_ext0); - len += snprintf(buf + len, size - len, - "%22s : %10d\n", "RSSI-EXT1", - sc->debug.stats.rxstats.rs_rssi_ext1); - len += snprintf(buf + len, size - len, - "%22s : %10d\n", "RSSI-EXT2", - sc->debug.stats.rxstats.rs_rssi_ext2); - len += snprintf(buf + len, size - len, - "%22s : %10d\n", "Rx Antenna", - sc->debug.stats.rxstats.rs_antenna); len += snprintf(buf + len, size - len, "%22s : %10u\n", "RX-Pkts-All", sc->debug.stats.rxstats.rx_pkts_all); @@ -1011,16 +990,6 @@ void ath_debug_stat_rx(struct ath_softc *sc, struct ath_rx_status *rs) RX_PHY_ERR_INC(rs->rs_phyerr); } - sc->debug.stats.rxstats.rs_rssi_ctl0 = rs->rs_rssi_ctl0; - sc->debug.stats.rxstats.rs_rssi_ctl1 = rs->rs_rssi_ctl1; - sc->debug.stats.rxstats.rs_rssi_ctl2 = rs->rs_rssi_ctl2; - - sc->debug.stats.rxstats.rs_rssi_ext0 = rs->rs_rssi_ext0; - sc->debug.stats.rxstats.rs_rssi_ext1 = rs->rs_rssi_ext1; - sc->debug.stats.rxstats.rs_rssi_ext2 = rs->rs_rssi_ext2; - - sc->debug.stats.rxstats.rs_antenna = rs->rs_antenna; - #ifdef CONFIG_ATH9K_MAC_DEBUG spin_lock(&sc->debug.samp_lock); RX_SAMP_DBG(jiffies) = jiffies; diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h index 7a519582232a..64fcfad467bf 100644 --- a/drivers/net/wireless/ath/ath9k/debug.h +++ b/drivers/net/wireless/ath/ath9k/debug.h @@ -165,13 +165,6 @@ struct ath_rx_stats { u32 post_delim_crc_err; u32 decrypt_busy_err; u32 phy_err_stats[ATH9K_PHYERR_MAX]; - int8_t rs_rssi_ctl0; - int8_t rs_rssi_ctl1; - int8_t rs_rssi_ctl2; - int8_t rs_rssi_ext0; - int8_t rs_rssi_ext1; - int8_t rs_rssi_ext2; - u8 rs_antenna; }; enum ath_reset_type { -- cgit From 3a2923e83c6036f55ad4a39c8ee9a7d4accd9539 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sat, 3 Mar 2012 15:17:05 +0100 Subject: ath9k: get rid of double queueing of rx frames on EDMA Process rx status directly instead of separating the completion test from the actual rx status processing. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_mac.c | 18 ++++-------- drivers/net/wireless/ath/ath9k/ath9k.h | 1 - drivers/net/wireless/ath/ath9k/recv.c | 45 ++++++++++++++--------------- 3 files changed, 28 insertions(+), 36 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.c b/drivers/net/wireless/ath/ath9k/ar9003_mac.c index 01d5c1a4d746..a66a13b76848 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c @@ -436,20 +436,14 @@ int ath9k_hw_process_rxdesc_edma(struct ath_hw *ah, struct ath_rx_status *rxs, struct ar9003_rxs *rxsp = (struct ar9003_rxs *) buf_addr; unsigned int phyerr; - /* TODO: byte swap on big endian for ar9300_10 */ - - if (!rxs) { - if ((rxsp->status11 & AR_RxDone) == 0) - return -EINPROGRESS; - - if (MS(rxsp->ds_info, AR_DescId) != 0x168c) - return -EINVAL; + if ((rxsp->status11 & AR_RxDone) == 0) + return -EINPROGRESS; - if ((rxsp->ds_info & (AR_TxRxDesc | AR_CtrlStat)) != 0) - return -EINPROGRESS; + if (MS(rxsp->ds_info, AR_DescId) != 0x168c) + return -EINVAL; - return 0; - } + if ((rxsp->ds_info & (AR_TxRxDesc | AR_CtrlStat)) != 0) + return -EINPROGRESS; rxs->rs_status = 0; rxs->rs_flags = 0; diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index c2ccba676eca..3d8e51cd5d8f 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -299,7 +299,6 @@ struct ath_tx { struct ath_rx_edma { struct sk_buff_head rx_fifo; - struct sk_buff_head rx_buffers; u32 rx_fifo_hwsize; }; diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index 4633f513a80b..c95b77cdf3bb 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c @@ -227,7 +227,6 @@ static void ath_rx_edma_cleanup(struct ath_softc *sc) static void ath_rx_edma_init_queue(struct ath_rx_edma *rx_edma, int size) { skb_queue_head_init(&rx_edma->rx_fifo); - skb_queue_head_init(&rx_edma->rx_buffers); rx_edma->rx_fifo_hwsize = size; } @@ -653,7 +652,9 @@ static void ath_rx_ps(struct ath_softc *sc, struct sk_buff *skb, bool mybeacon) } static bool ath_edma_get_buffers(struct ath_softc *sc, - enum ath9k_rx_qtype qtype) + enum ath9k_rx_qtype qtype, + struct ath_rx_status *rs, + struct ath_buf **dest) { struct ath_rx_edma *rx_edma = &sc->rx.rx_edma[qtype]; struct ath_hw *ah = sc->sc_ah; @@ -672,7 +673,7 @@ static bool ath_edma_get_buffers(struct ath_softc *sc, dma_sync_single_for_cpu(sc->dev, bf->bf_buf_addr, common->rx_bufsize, DMA_FROM_DEVICE); - ret = ath9k_hw_process_rxdesc_edma(ah, NULL, skb->data); + ret = ath9k_hw_process_rxdesc_edma(ah, rs, skb->data); if (ret == -EINPROGRESS) { /*let device gain the buffer again*/ dma_sync_single_for_device(sc->dev, bf->bf_buf_addr, @@ -685,20 +686,21 @@ static bool ath_edma_get_buffers(struct ath_softc *sc, /* corrupt descriptor, skip this one and the following one */ list_add_tail(&bf->list, &sc->rx.rxbuf); ath_rx_edma_buf_link(sc, qtype); - skb = skb_peek(&rx_edma->rx_fifo); - if (!skb) - return true; - bf = SKB_CB_ATHBUF(skb); - BUG_ON(!bf); + skb = skb_peek(&rx_edma->rx_fifo); + if (skb) { + bf = SKB_CB_ATHBUF(skb); + BUG_ON(!bf); - __skb_unlink(skb, &rx_edma->rx_fifo); - list_add_tail(&bf->list, &sc->rx.rxbuf); - ath_rx_edma_buf_link(sc, qtype); - return true; + __skb_unlink(skb, &rx_edma->rx_fifo); + list_add_tail(&bf->list, &sc->rx.rxbuf); + ath_rx_edma_buf_link(sc, qtype); + } else { + bf = NULL; + } } - skb_queue_tail(&rx_edma->rx_buffers, skb); + *dest = bf; return true; } @@ -706,18 +708,15 @@ static struct ath_buf *ath_edma_get_next_rx_buf(struct ath_softc *sc, struct ath_rx_status *rs, enum ath9k_rx_qtype qtype) { - struct ath_rx_edma *rx_edma = &sc->rx.rx_edma[qtype]; - struct sk_buff *skb; - struct ath_buf *bf; + struct ath_buf *bf = NULL; - while (ath_edma_get_buffers(sc, qtype)); - skb = __skb_dequeue(&rx_edma->rx_buffers); - if (!skb) - return NULL; + while (ath_edma_get_buffers(sc, qtype, rs, &bf)) { + if (!bf) + continue; - bf = SKB_CB_ATHBUF(skb); - ath9k_hw_process_rxdesc_edma(sc->sc_ah, rs, skb->data); - return bf; + return bf; + } + return NULL; } static struct ath_buf *ath_get_next_rx_buf(struct ath_softc *sc, -- cgit From 2ef167557c0a26c88162ecffb017bfcc51eb7b29 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sat, 3 Mar 2012 15:17:06 +0100 Subject: ath9k: fix signal strength reporting issues On A-MPDU frames, the hardware only reports valid signal strength data for the last subframe. The driver also mangled rx_stats->rs_rssi using the ATH_EP_RND macro in a way that may make sense for ANI, but definitely not for reporting to mac80211. This patch changes the code to calculate the signal strength from the rssi directly instead of taking the average value, and flag everything but the last subframe in an A-MPDU to tell mac80211 to ignore the signal strength entirely, fixing signal strength fluctuation issues reported by various users. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/recv.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index c95b77cdf3bb..1b1b279c304a 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c @@ -948,6 +948,7 @@ static void ath9k_process_rssi(struct ath_common *common, struct ath_softc *sc = hw->priv; struct ath_hw *ah = common->ah; int last_rssi; + int rssi = rx_stats->rs_rssi; if (!rx_stats->is_mybeacon || ((ah->opmode != NL80211_IFTYPE_STATION) && @@ -959,13 +960,12 @@ static void ath9k_process_rssi(struct ath_common *common, last_rssi = sc->last_rssi; if (likely(last_rssi != ATH_RSSI_DUMMY_MARKER)) - rx_stats->rs_rssi = ATH_EP_RND(last_rssi, - ATH_RSSI_EP_MULTIPLIER); - if (rx_stats->rs_rssi < 0) - rx_stats->rs_rssi = 0; + rssi = ATH_EP_RND(last_rssi, ATH_RSSI_EP_MULTIPLIER); + if (rssi < 0) + rssi = 0; /* Update Beacon RSSI, this is used by ANI. */ - ah->stats.avgbrssi = rx_stats->rs_rssi; + ah->stats.avgbrssi = rssi; } /* @@ -1005,6 +1005,8 @@ static int ath9k_rx_skb_preprocess(struct ath_common *common, rx_status->signal = ah->noise + rx_stats->rs_rssi; rx_status->antenna = rx_stats->rs_antenna; rx_status->flag |= RX_FLAG_MACTIME_MPDU; + if (rx_stats->rs_moreaggr) + rx_status->flag |= RX_FLAG_NO_SIGNAL_VAL; return 0; } -- cgit From 3d4f96997263d97cd4d60373f1ed8184ee6df31b Mon Sep 17 00:00:00 2001 From: Ashok Nagarajan Date: Tue, 6 Mar 2012 12:48:30 -0800 Subject: mac80211: Fix potential null pointer dereferencing The patch "{nl,cfg,mac}80211: Implement RSSI threshold for mesh peering" has a potential null pointer dereferencing problem. Thanks to Dan Carpenter for pointing out. This patch will fix the issue. Signed-off-by: Ashok Nagarajan Signed-off-by: John W. Linville --- net/mac80211/mesh_plink.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c index 80ce52772538..4e53c4cbca9e 100644 --- a/net/mac80211/mesh_plink.c +++ b/net/mac80211/mesh_plink.c @@ -31,10 +31,11 @@ #define dot11MeshHoldingTimeout(s) (s->u.mesh.mshcfg.dot11MeshHoldingTimeout) #define dot11MeshMaxPeerLinks(s) (s->u.mesh.mshcfg.dot11MeshMaxPeerLinks) -#define sta_meets_rssi_threshold(sta, sdata) \ +/* We only need a valid sta if user configured a minimum rssi_threshold. */ +#define rssi_threshold_check(sta, sdata) \ (sdata->u.mesh.mshcfg.rssi_threshold == 0 ||\ - (s8) -ewma_read(&sta->avg_signal) > \ - sdata->u.mesh.mshcfg.rssi_threshold) + (sta && (s8) -ewma_read(&sta->avg_signal) > \ + sdata->u.mesh.mshcfg.rssi_threshold)) enum plink_event { PLINK_UNDEFINED, @@ -307,7 +308,7 @@ void mesh_neighbour_update(u8 *hw_addr, u32 rates, sta->plink_state == NL80211_PLINK_LISTEN && sdata->u.mesh.accepting_plinks && sdata->u.mesh.mshcfg.auto_open_plinks && - sta_meets_rssi_threshold(sta, sdata)) + rssi_threshold_check(sta, sdata)) mesh_plink_open(sta); rcu_read_unlock(); @@ -538,9 +539,9 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m } if (ftype == WLAN_SP_MESH_PEERING_OPEN && - !sta_meets_rssi_threshold(sta, sdata)) { + !rssi_threshold_check(sta, sdata)) { mpl_dbg("Mesh plink: %pM does not meet rssi threshold\n", - sta->sta.addr); + mgmt->sa); rcu_read_unlock(); return; } -- cgit From e19918855dc4822a24787a6d0048205b011e5ecb Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 6 Mar 2012 13:30:36 -0800 Subject: iwlwifi: move ucode loading to op_mode uCode loading belongs to the op_mode, as it is dependent on various things there and the commands sent during it are specific to it. Move the prototypes to iwl-agn.h to indicate this. To make this possible, also move all the calibration handling (which is op_mode dependent after all). Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-calib.c | 26 ++-- drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 2 +- drivers/net/wireless/iwlwifi/iwl-agn-rx.c | 2 +- drivers/net/wireless/iwlwifi/iwl-agn.c | 9 +- drivers/net/wireless/iwlwifi/iwl-agn.h | 10 ++ drivers/net/wireless/iwlwifi/iwl-dev.h | 2 + drivers/net/wireless/iwlwifi/iwl-mac80211.c | 4 +- drivers/net/wireless/iwlwifi/iwl-shared.h | 14 +- drivers/net/wireless/iwlwifi/iwl-testmode.c | 8 +- drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | 1 - drivers/net/wireless/iwlwifi/iwl-trans.h | 19 --- drivers/net/wireless/iwlwifi/iwl-ucode.c | 205 +++++++++++++------------- drivers/net/wireless/iwlwifi/iwl-wifi.h | 8 - 13 files changed, 150 insertions(+), 160 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c index 84fc5ce91b35..29f94597b55f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c @@ -75,6 +75,14 @@ * INIT calibrations framework *****************************************************************************/ +/* Opaque calibration results */ +struct iwl_calib_result { + struct list_head list; + size_t cmd_len; + struct iwl_calib_hdr hdr; + /* data follows */ +}; + struct statistics_general_data { u32 beacon_silence_rssi_a; u32 beacon_silence_rssi_b; @@ -84,7 +92,7 @@ struct statistics_general_data { u32 beacon_energy_c; }; -int iwl_send_calib_results(struct iwl_trans *trans) +int iwl_send_calib_results(struct iwl_priv *priv) { struct iwl_host_cmd hcmd = { .id = REPLY_PHY_CALIBRATION_CMD, @@ -92,15 +100,15 @@ int iwl_send_calib_results(struct iwl_trans *trans) }; struct iwl_calib_result *res; - list_for_each_entry(res, &trans->calib_results, list) { + list_for_each_entry(res, &priv->calib_results, list) { int ret; hcmd.len[0] = res->cmd_len; hcmd.data[0] = &res->hdr; hcmd.dataflags[0] = IWL_HCMD_DFL_NOCOPY; - ret = iwl_trans_send_cmd(trans, &hcmd); + ret = iwl_trans_send_cmd(trans(priv), &hcmd); if (ret) { - IWL_ERR(trans, "Error %d on calib cmd %d\n", + IWL_ERR(priv, "Error %d on calib cmd %d\n", ret, res->hdr.op_code); return ret; } @@ -109,7 +117,7 @@ int iwl_send_calib_results(struct iwl_trans *trans) return 0; } -int iwl_calib_set(struct iwl_trans *trans, +int iwl_calib_set(struct iwl_priv *priv, const struct iwl_calib_hdr *cmd, int len) { struct iwl_calib_result *res, *tmp; @@ -121,7 +129,7 @@ int iwl_calib_set(struct iwl_trans *trans, memcpy(&res->hdr, cmd, len); res->cmd_len = len; - list_for_each_entry(tmp, &trans->calib_results, list) { + list_for_each_entry(tmp, &priv->calib_results, list) { if (tmp->hdr.op_code == res->hdr.op_code) { list_replace(&tmp->list, &res->list); kfree(tmp); @@ -130,16 +138,16 @@ int iwl_calib_set(struct iwl_trans *trans, } /* wasn't in list already */ - list_add_tail(&res->list, &trans->calib_results); + list_add_tail(&res->list, &priv->calib_results); return 0; } -void iwl_calib_free_results(struct iwl_trans *trans) +void iwl_calib_free_results(struct iwl_priv *priv) { struct iwl_calib_result *res, *tmp; - list_for_each_entry_safe(res, tmp, &trans->calib_results, list) { + list_for_each_entry_safe(res, tmp, &priv->calib_results, list) { list_del(&res->list); kfree(res); } diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index e96af5133e06..45b060a45d9d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -1195,7 +1195,7 @@ int iwlagn_suspend(struct iwl_priv *priv, priv->wowlan = true; - ret = iwl_load_ucode_wait_alive(trans(priv), IWL_UCODE_WOWLAN); + ret = iwl_load_ucode_wait_alive(priv, IWL_UCODE_WOWLAN); if (ret) goto out; diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c index 8e025e0df50d..d16e73d1b5c9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c @@ -1177,7 +1177,7 @@ int iwl_rx_dispatch(struct iwl_op_mode *op_mode, struct iwl_rx_cmd_buffer *rxb, pkt->hdr.cmd); w->triggered = true; if (w->fn) - w->fn(trans(priv), pkt, w->fn_data); + w->fn(priv, pkt, w->fn_data); } spin_unlock(&priv->shrd->notif_wait_lock); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 8bb3f173bfa0..f53308fb428e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -671,14 +671,14 @@ int iwl_alive_start(struct iwl_priv *priv) priv->bt_valid = IWLAGN_BT_VALID_ENABLE_FLAGS; priv->cur_rssi_ctx = NULL; - iwl_send_prio_tbl(trans(priv)); + iwl_send_prio_tbl(priv); /* FIXME: w/a to force change uCode BT state machine */ - ret = iwl_send_bt_env(trans(priv), IWL_BT_COEX_ENV_OPEN, + ret = iwl_send_bt_env(priv, IWL_BT_COEX_ENV_OPEN, BT_COEX_PRIO_TBL_EVT_INIT_CALIB2); if (ret) return ret; - ret = iwl_send_bt_env(trans(priv), IWL_BT_COEX_ENV_CLOSE, + ret = iwl_send_bt_env(priv, IWL_BT_COEX_ENV_CLOSE, BT_COEX_PRIO_TBL_EVT_INIT_CALIB2); if (ret) return ret; @@ -1040,7 +1040,7 @@ static int iwl_init_drv(struct iwl_priv *priv) mutex_init(&priv->shrd->mutex); - INIT_LIST_HEAD(&trans(priv)->calib_results); + INIT_LIST_HEAD(&priv->calib_results); priv->ieee_channels = NULL; priv->ieee_rates = NULL; @@ -1105,6 +1105,7 @@ static void iwl_uninit_drv(struct iwl_priv *priv) kfree(priv->scan_cmd); kfree(priv->beacon_cmd); kfree(rcu_dereference_raw(priv->noa_data)); + iwl_calib_free_results(priv); #ifdef CONFIG_IWLWIFI_DEBUGFS kfree(priv->wowlan_sram); #endif diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index 70100f9a2e5c..2a90d779eecf 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h @@ -113,6 +113,16 @@ int iwlagn_rx_calib_result(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb, struct iwl_device_cmd *cmd); void iwl_init_context(struct iwl_priv *priv, u32 ucode_flags); +int iwl_send_bt_env(struct iwl_priv *priv, u8 action, u8 type); +void iwl_send_prio_tbl(struct iwl_priv *priv); +int iwl_init_alive_start(struct iwl_priv *priv); +int iwl_run_init_ucode(struct iwl_priv *priv); +int iwl_load_ucode_wait_alive(struct iwl_priv *priv, + enum iwl_ucode_type ucode_type); +int iwl_send_calib_results(struct iwl_priv *priv); +int iwl_calib_set(struct iwl_priv *priv, + const struct iwl_calib_hdr *cmd, int len); +void iwl_calib_free_results(struct iwl_priv *priv); /* lib */ int iwlagn_send_tx_power(struct iwl_priv *priv); diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 5957209b2f37..7199748faaab 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -724,6 +724,8 @@ struct iwl_priv { struct ieee80211_rate *ieee_rates; struct kmem_cache *tx_cmd_pool; + struct list_head calib_results; + struct workqueue_struct *workqueue; enum ieee80211_band band; diff --git a/drivers/net/wireless/iwlwifi/iwl-mac80211.c b/drivers/net/wireless/iwlwifi/iwl-mac80211.c index 7f937151a8af..37330addce79 100644 --- a/drivers/net/wireless/iwlwifi/iwl-mac80211.c +++ b/drivers/net/wireless/iwlwifi/iwl-mac80211.c @@ -278,13 +278,13 @@ static int __iwl_up(struct iwl_priv *priv) } } - ret = iwl_run_init_ucode(trans(priv)); + ret = iwl_run_init_ucode(priv); if (ret) { IWL_ERR(priv, "Failed to run INIT ucode: %d\n", ret); goto error; } - ret = iwl_load_ucode_wait_alive(trans(priv), IWL_UCODE_REGULAR); + ret = iwl_load_ucode_wait_alive(priv, IWL_UCODE_REGULAR); if (ret) { IWL_ERR(priv, "Failed to start RT ucode: %d\n", ret); goto error; diff --git a/drivers/net/wireless/iwlwifi/iwl-shared.h b/drivers/net/wireless/iwlwifi/iwl-shared.h index ef80e0386c30..dc5544653bc0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-shared.h +++ b/drivers/net/wireless/iwlwifi/iwl-shared.h @@ -233,7 +233,7 @@ enum iwl_ucode_type { struct iwl_notification_wait { struct list_head list; - void (*fn)(struct iwl_trans *trans, struct iwl_rx_packet *pkt, + void (*fn)(struct iwl_priv *priv, struct iwl_rx_packet *pkt, void *data); void *fn_data; @@ -472,12 +472,12 @@ bool iwl_check_for_ct_kill(struct iwl_priv *priv); void iwl_abort_notification_waits(struct iwl_shared *shrd); void __acquires(wait_entry) iwl_init_notification_wait(struct iwl_shared *shrd, - struct iwl_notification_wait *wait_entry, - u8 cmd, - void (*fn)(struct iwl_trans *trans, - struct iwl_rx_packet *pkt, - void *data), - void *fn_data); + struct iwl_notification_wait *wait_entry, + u8 cmd, + void (*fn)(struct iwl_priv *priv, + struct iwl_rx_packet *pkt, + void *data), + void *fn_data); int __must_check __releases(wait_entry) iwl_wait_notification(struct iwl_shared *shrd, struct iwl_notification_wait *wait_entry, diff --git a/drivers/net/wireless/iwlwifi/iwl-testmode.c b/drivers/net/wireless/iwlwifi/iwl-testmode.c index b24b166a9482..ec803ea08675 100644 --- a/drivers/net/wireless/iwlwifi/iwl-testmode.c +++ b/drivers/net/wireless/iwlwifi/iwl-testmode.c @@ -422,7 +422,7 @@ static int iwl_testmode_cfg_init_calib(struct iwl_priv *priv) iwl_init_notification_wait(priv->shrd, &calib_wait, CALIBRATION_COMPLETE_NOTIFICATION, NULL, NULL); - ret = iwl_init_alive_start(trans(priv)); + ret = iwl_init_alive_start(priv); if (ret) { IWL_ERR(priv, "Fail init calibration: %d\n", ret); goto cfg_init_calib_error; @@ -484,7 +484,7 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb) break; case IWL_TM_CMD_APP2DEV_LOAD_INIT_FW: - status = iwl_load_ucode_wait_alive(trans, IWL_UCODE_INIT); + status = iwl_load_ucode_wait_alive(priv, IWL_UCODE_INIT); if (status) IWL_ERR(priv, "Error loading init ucode: %d\n", status); break; @@ -495,7 +495,7 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb) break; case IWL_TM_CMD_APP2DEV_LOAD_RUNTIME_FW: - status = iwl_load_ucode_wait_alive(trans, IWL_UCODE_REGULAR); + status = iwl_load_ucode_wait_alive(priv, IWL_UCODE_REGULAR); if (status) { IWL_ERR(priv, "Error loading runtime ucode: %d\n", status); @@ -510,7 +510,7 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb) case IWL_TM_CMD_APP2DEV_LOAD_WOWLAN_FW: iwl_scan_cancel_timeout(priv, 200); iwl_trans_stop_device(trans); - status = iwl_load_ucode_wait_alive(trans, IWL_UCODE_WOWLAN); + status = iwl_load_ucode_wait_alive(priv, IWL_UCODE_WOWLAN); if (status) { IWL_ERR(priv, "Error loading WOWLAN ucode: %d\n", status); diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c index 3ae2fd720ed8..f49aa181f4af 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c @@ -1632,7 +1632,6 @@ static void iwl_trans_pcie_free(struct iwl_trans *trans) struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); - iwl_calib_free_results(trans); iwl_trans_pcie_tx_free(trans); #ifndef CONFIG_IWLWIFI_IDI iwl_trans_pcie_rx_free(trans); diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index b09192a028de..6fa0c860a5e2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h @@ -315,14 +315,6 @@ struct iwl_trans_ops { u32 (*read32)(struct iwl_trans *trans, u32 ofs); }; -/* Opaque calibration results */ -struct iwl_calib_result { - struct list_head list; - size_t cmd_len; - struct iwl_calib_hdr hdr; - /* data follows */ -}; - /** * enum iwl_trans_state - state of the transport layer * @@ -349,7 +341,6 @@ enum iwl_trans_state { * @ucode_write_complete: indicates that the ucode has been copied. * @nvm_device_type: indicates OTP or eeprom * @pm_support: set to true in start_hw if link pm is supported - * @calib_results: list head for init calibration results */ struct iwl_trans { const struct iwl_trans_ops *ops; @@ -369,8 +360,6 @@ struct iwl_trans { int nvm_device_type; bool pm_support; - struct list_head calib_results; - /* pointer to trans specific struct */ /*Ensure that this pointer will always be aligned to sizeof pointer */ char trans_specific[0] __aligned(sizeof(void *)); @@ -573,14 +562,6 @@ static inline u32 iwl_trans_read32(struct iwl_trans *trans, u32 ofs) return trans->ops->read32(trans, ofs); } -/***************************************************** -* Utils functions -******************************************************/ -int iwl_send_calib_results(struct iwl_trans *trans); -int iwl_calib_set(struct iwl_trans *trans, - const struct iwl_calib_hdr *cmd, int len); -void iwl_calib_free_results(struct iwl_trans *trans); - /***************************************************** * Transport layers implementations + their allocation function ******************************************************/ diff --git a/drivers/net/wireless/iwlwifi/iwl-ucode.c b/drivers/net/wireless/iwlwifi/iwl-ucode.c index 64a9c5ce5f89..340575a01ead 100644 --- a/drivers/net/wireless/iwlwifi/iwl-ucode.c +++ b/drivers/net/wireless/iwlwifi/iwl-ucode.c @@ -80,16 +80,16 @@ static struct iwl_wimax_coex_event_entry cu_priorities[COEX_NUM_OF_EVENTS] = { * ******************************************************************************/ -static inline struct fw_img *iwl_get_ucode_image(struct iwl_nic *nic, - enum iwl_ucode_type ucode_type) +static inline struct fw_img *iwl_get_ucode_image(struct iwl_priv *priv, + enum iwl_ucode_type ucode_type) { switch (ucode_type) { case IWL_UCODE_INIT: - return &nic->fw.ucode_init; + return &nic(priv)->fw.ucode_init; case IWL_UCODE_WOWLAN: - return &nic->fw.ucode_wowlan; + return &nic(priv)->fw.ucode_wowlan; case IWL_UCODE_REGULAR: - return &nic->fw.ucode_rt; + return &nic(priv)->fw.ucode_rt; case IWL_UCODE_NONE: break; } @@ -99,23 +99,23 @@ static inline struct fw_img *iwl_get_ucode_image(struct iwl_nic *nic, /* * Calibration */ -static int iwl_set_Xtal_calib(struct iwl_trans *trans) +static int iwl_set_Xtal_calib(struct iwl_priv *priv) { struct iwl_calib_xtal_freq_cmd cmd; __le16 *xtal_calib = - (__le16 *)iwl_eeprom_query_addr(trans->shrd, EEPROM_XTAL); + (__le16 *)iwl_eeprom_query_addr(priv->shrd, EEPROM_XTAL); iwl_set_calib_hdr(&cmd.hdr, IWL_PHY_CALIBRATE_CRYSTAL_FRQ_CMD); cmd.cap_pin1 = le16_to_cpu(xtal_calib[0]); cmd.cap_pin2 = le16_to_cpu(xtal_calib[1]); - return iwl_calib_set(trans, (void *)&cmd, sizeof(cmd)); + return iwl_calib_set(priv, (void *)&cmd, sizeof(cmd)); } -static int iwl_set_temperature_offset_calib(struct iwl_trans *trans) +static int iwl_set_temperature_offset_calib(struct iwl_priv *priv) { struct iwl_calib_temperature_offset_cmd cmd; __le16 *offset_calib = - (__le16 *)iwl_eeprom_query_addr(trans->shrd, + (__le16 *)iwl_eeprom_query_addr(priv->shrd, EEPROM_RAW_TEMPERATURE); memset(&cmd, 0, sizeof(cmd)); @@ -124,48 +124,48 @@ static int iwl_set_temperature_offset_calib(struct iwl_trans *trans) if (!(cmd.radio_sensor_offset)) cmd.radio_sensor_offset = DEFAULT_RADIO_SENSOR_OFFSET; - IWL_DEBUG_CALIB(trans, "Radio sensor offset: %d\n", + IWL_DEBUG_CALIB(priv, "Radio sensor offset: %d\n", le16_to_cpu(cmd.radio_sensor_offset)); - return iwl_calib_set(trans, (void *)&cmd, sizeof(cmd)); + return iwl_calib_set(priv, (void *)&cmd, sizeof(cmd)); } -static int iwl_set_temperature_offset_calib_v2(struct iwl_trans *trans) +static int iwl_set_temperature_offset_calib_v2(struct iwl_priv *priv) { struct iwl_calib_temperature_offset_v2_cmd cmd; - __le16 *offset_calib_high = (__le16 *)iwl_eeprom_query_addr(trans->shrd, + __le16 *offset_calib_high = (__le16 *)iwl_eeprom_query_addr(priv->shrd, EEPROM_KELVIN_TEMPERATURE); __le16 *offset_calib_low = - (__le16 *)iwl_eeprom_query_addr(trans->shrd, + (__le16 *)iwl_eeprom_query_addr(priv->shrd, EEPROM_RAW_TEMPERATURE); struct iwl_eeprom_calib_hdr *hdr; memset(&cmd, 0, sizeof(cmd)); iwl_set_calib_hdr(&cmd.hdr, IWL_PHY_CALIBRATE_TEMP_OFFSET_CMD); - hdr = (struct iwl_eeprom_calib_hdr *)iwl_eeprom_query_addr(trans->shrd, + hdr = (struct iwl_eeprom_calib_hdr *)iwl_eeprom_query_addr(priv->shrd, EEPROM_CALIB_ALL); memcpy(&cmd.radio_sensor_offset_high, offset_calib_high, sizeof(*offset_calib_high)); memcpy(&cmd.radio_sensor_offset_low, offset_calib_low, sizeof(*offset_calib_low)); if (!(cmd.radio_sensor_offset_low)) { - IWL_DEBUG_CALIB(trans, "no info in EEPROM, use default\n"); + IWL_DEBUG_CALIB(priv, "no info in EEPROM, use default\n"); cmd.radio_sensor_offset_low = DEFAULT_RADIO_SENSOR_OFFSET; cmd.radio_sensor_offset_high = DEFAULT_RADIO_SENSOR_OFFSET; } memcpy(&cmd.burntVoltageRef, &hdr->voltage, sizeof(hdr->voltage)); - IWL_DEBUG_CALIB(trans, "Radio sensor offset high: %d\n", + IWL_DEBUG_CALIB(priv, "Radio sensor offset high: %d\n", le16_to_cpu(cmd.radio_sensor_offset_high)); - IWL_DEBUG_CALIB(trans, "Radio sensor offset low: %d\n", + IWL_DEBUG_CALIB(priv, "Radio sensor offset low: %d\n", le16_to_cpu(cmd.radio_sensor_offset_low)); - IWL_DEBUG_CALIB(trans, "Voltage Ref: %d\n", + IWL_DEBUG_CALIB(priv, "Voltage Ref: %d\n", le16_to_cpu(cmd.burntVoltageRef)); - return iwl_calib_set(trans, (void *)&cmd, sizeof(cmd)); + return iwl_calib_set(priv, (void *)&cmd, sizeof(cmd)); } -static int iwl_send_calib_cfg(struct iwl_trans *trans) +static int iwl_send_calib_cfg(struct iwl_priv *priv) { struct iwl_calib_cfg_cmd calib_cfg_cmd; struct iwl_host_cmd cmd = { @@ -181,7 +181,7 @@ static int iwl_send_calib_cfg(struct iwl_trans *trans) calib_cfg_cmd.ucd_calib_cfg.flags = IWL_CALIB_CFG_FLAG_SEND_COMPLETE_NTFY_MSK; - return iwl_trans_send_cmd(trans, &cmd); + return iwl_trans_send_cmd(trans(priv), &cmd); } int iwlagn_rx_calib_result(struct iwl_priv *priv, @@ -195,33 +195,33 @@ int iwlagn_rx_calib_result(struct iwl_priv *priv, /* reduce the size of the length field itself */ len -= 4; - if (iwl_calib_set(trans(priv), hdr, len)) + if (iwl_calib_set(priv, hdr, len)) IWL_ERR(priv, "Failed to record calibration data %d\n", hdr->op_code); return 0; } -int iwl_init_alive_start(struct iwl_trans *trans) +int iwl_init_alive_start(struct iwl_priv *priv) { int ret; - if (cfg(trans)->bt_params && - cfg(trans)->bt_params->advanced_bt_coexist) { + if (cfg(priv)->bt_params && + cfg(priv)->bt_params->advanced_bt_coexist) { /* * Tell uCode we are ready to perform calibration * need to perform this before any calibration * no need to close the envlope since we are going * to load the runtime uCode later. */ - ret = iwl_send_bt_env(trans, IWL_BT_COEX_ENV_OPEN, + ret = iwl_send_bt_env(priv, IWL_BT_COEX_ENV_OPEN, BT_COEX_PRIO_TBL_EVT_INIT_CALIB2); if (ret) return ret; } - ret = iwl_send_calib_cfg(trans); + ret = iwl_send_calib_cfg(priv); if (ret) return ret; @@ -229,21 +229,21 @@ int iwl_init_alive_start(struct iwl_trans *trans) * temperature offset calibration is only needed for runtime ucode, * so prepare the value now. */ - if (cfg(trans)->need_temp_offset_calib) { - if (cfg(trans)->temp_offset_v2) - return iwl_set_temperature_offset_calib_v2(trans); + if (cfg(priv)->need_temp_offset_calib) { + if (cfg(priv)->temp_offset_v2) + return iwl_set_temperature_offset_calib_v2(priv); else - return iwl_set_temperature_offset_calib(trans); + return iwl_set_temperature_offset_calib(priv); } return 0; } -static int iwl_send_wimax_coex(struct iwl_trans *trans) +static int iwl_send_wimax_coex(struct iwl_priv *priv) { struct iwl_wimax_coex_cmd coex_cmd; - if (cfg(trans)->base_params->support_wimax_coexist) { + if (cfg(priv)->base_params->support_wimax_coexist) { /* UnMask wake up src at associated sleep */ coex_cmd.flags = COEX_FLAGS_ASSOC_WA_UNMASK_MSK; @@ -262,7 +262,7 @@ static int iwl_send_wimax_coex(struct iwl_trans *trans) /* coexistence is disabled */ memset(&coex_cmd, 0, sizeof(coex_cmd)); } - return iwl_trans_send_cmd_pdu(trans, + return iwl_trans_send_cmd_pdu(trans(priv), COEX_PRIORITY_TABLE_CMD, CMD_SYNC, sizeof(coex_cmd), &coex_cmd); } @@ -289,37 +289,36 @@ static const u8 iwl_bt_prio_tbl[BT_COEX_PRIO_TBL_EVT_MAX] = { 0, 0, 0, 0, 0, 0, 0 }; -void iwl_send_prio_tbl(struct iwl_trans *trans) +void iwl_send_prio_tbl(struct iwl_priv *priv) { struct iwl_bt_coex_prio_table_cmd prio_tbl_cmd; memcpy(prio_tbl_cmd.prio_tbl, iwl_bt_prio_tbl, sizeof(iwl_bt_prio_tbl)); - if (iwl_trans_send_cmd_pdu(trans, + if (iwl_trans_send_cmd_pdu(trans(priv), REPLY_BT_COEX_PRIO_TABLE, CMD_SYNC, sizeof(prio_tbl_cmd), &prio_tbl_cmd)) - IWL_ERR(trans, "failed to send BT prio tbl command\n"); + IWL_ERR(priv, "failed to send BT prio tbl command\n"); } -int iwl_send_bt_env(struct iwl_trans *trans, u8 action, u8 type) +int iwl_send_bt_env(struct iwl_priv *priv, u8 action, u8 type) { struct iwl_bt_coex_prot_env_cmd env_cmd; int ret; env_cmd.action = action; env_cmd.type = type; - ret = iwl_trans_send_cmd_pdu(trans, + ret = iwl_trans_send_cmd_pdu(trans(priv), REPLY_BT_COEX_PROT_ENV, CMD_SYNC, sizeof(env_cmd), &env_cmd); if (ret) - IWL_ERR(trans, "failed to send BT env command\n"); + IWL_ERR(priv, "failed to send BT env command\n"); return ret; } -static int iwl_alive_notify(struct iwl_trans *trans) +static int iwl_alive_notify(struct iwl_priv *priv) { - struct iwl_priv *priv = priv(trans); struct iwl_rxon_context *ctx; int ret; @@ -332,21 +331,21 @@ static int iwl_alive_notify(struct iwl_trans *trans) if (!priv->tx_cmd_pool) return -ENOMEM; - iwl_trans_fw_alive(trans); + iwl_trans_fw_alive(trans(priv)); for_each_context(priv, ctx) ctx->last_tx_rejected = false; - ret = iwl_send_wimax_coex(trans); + ret = iwl_send_wimax_coex(priv); if (ret) return ret; if (!cfg(priv)->no_xtal_calib) { - ret = iwl_set_Xtal_calib(trans); + ret = iwl_set_Xtal_calib(priv); if (ret) return ret; } - return iwl_send_calib_results(trans); + return iwl_send_calib_results(priv); } @@ -355,24 +354,23 @@ static int iwl_alive_notify(struct iwl_trans *trans) * using sample data 100 bytes apart. If these sample points are good, * it's a pretty good bet that everything between them is good, too. */ -static int iwl_verify_inst_sparse(struct iwl_nic *nic, - struct fw_desc *fw_desc) +static int iwl_verify_inst_sparse(struct iwl_priv *priv, + struct fw_desc *fw_desc) { - struct iwl_trans *trans = trans(nic); __le32 *image = (__le32 *)fw_desc->v_addr; u32 len = fw_desc->len; u32 val; u32 i; - IWL_DEBUG_FW(nic, "ucode inst image size is %u\n", len); + IWL_DEBUG_FW(priv, "ucode inst image size is %u\n", len); for (i = 0; i < len; i += 100, image += 100/sizeof(u32)) { /* read data comes through single port, auto-incr addr */ /* NOTE: Use the debugless read so we don't flood kernel log * if IWL_DL_IO is set */ - iwl_write_direct32(trans, HBUS_TARG_MEM_RADDR, + iwl_write_direct32(trans(priv), HBUS_TARG_MEM_RADDR, i + IWLAGN_RTC_INST_LOWER_BOUND); - val = iwl_read32(trans, HBUS_TARG_MEM_RDAT); + val = iwl_read32(trans(priv), HBUS_TARG_MEM_RDAT); if (val != le32_to_cpu(*image)) return -EIO; } @@ -380,28 +378,27 @@ static int iwl_verify_inst_sparse(struct iwl_nic *nic, return 0; } -static void iwl_print_mismatch_inst(struct iwl_nic *nic, +static void iwl_print_mismatch_inst(struct iwl_priv *priv, struct fw_desc *fw_desc) { - struct iwl_trans *trans = trans(nic); __le32 *image = (__le32 *)fw_desc->v_addr; u32 len = fw_desc->len; u32 val; u32 offs; int errors = 0; - IWL_DEBUG_FW(nic, "ucode inst image size is %u\n", len); + IWL_DEBUG_FW(priv, "ucode inst image size is %u\n", len); - iwl_write_direct32(trans, HBUS_TARG_MEM_RADDR, + iwl_write_direct32(trans(priv), HBUS_TARG_MEM_RADDR, IWLAGN_RTC_INST_LOWER_BOUND); for (offs = 0; offs < len && errors < 20; offs += sizeof(u32), image++) { /* read data comes through single port, auto-incr addr */ - val = iwl_read32(trans, HBUS_TARG_MEM_RDAT); + val = iwl_read32(trans(priv), HBUS_TARG_MEM_RDAT); if (val != le32_to_cpu(*image)) { - IWL_ERR(nic, "uCode INST section at " + IWL_ERR(priv, "uCode INST section at " "offset 0x%x, is 0x%x, s/b 0x%x\n", offs, val, le32_to_cpu(*image)); errors++; @@ -413,24 +410,24 @@ static void iwl_print_mismatch_inst(struct iwl_nic *nic, * iwl_verify_ucode - determine which instruction image is in SRAM, * and verify its contents */ -static int iwl_verify_ucode(struct iwl_nic *nic, +static int iwl_verify_ucode(struct iwl_priv *priv, enum iwl_ucode_type ucode_type) { - struct fw_img *img = iwl_get_ucode_image(nic, ucode_type); + struct fw_img *img = iwl_get_ucode_image(priv, ucode_type); if (!img) { - IWL_ERR(nic, "Invalid ucode requested (%d)\n", ucode_type); + IWL_ERR(priv, "Invalid ucode requested (%d)\n", ucode_type); return -EINVAL; } - if (!iwl_verify_inst_sparse(nic, &img->code)) { - IWL_DEBUG_FW(nic, "uCode is good in inst SRAM\n"); + if (!iwl_verify_inst_sparse(priv, &img->code)) { + IWL_DEBUG_FW(priv, "uCode is good in inst SRAM\n"); return 0; } - IWL_ERR(nic, "UCODE IMAGE IN INSTRUCTION SRAM NOT VALID!!\n"); + IWL_ERR(priv, "UCODE IMAGE IN INSTRUCTION SRAM NOT VALID!!\n"); - iwl_print_mismatch_inst(nic, &img->code); + iwl_print_mismatch_inst(priv, &img->code); return -EIO; } @@ -439,7 +436,7 @@ struct iwl_alive_data { u8 subtype; }; -static void iwl_alive_fn(struct iwl_trans *trans, +static void iwl_alive_fn(struct iwl_priv *priv, struct iwl_rx_packet *pkt, void *data) { @@ -448,14 +445,14 @@ static void iwl_alive_fn(struct iwl_trans *trans, palive = &pkt->u.alive_frame; - IWL_DEBUG_FW(trans, "Alive ucode status 0x%08X revision " + IWL_DEBUG_FW(priv, "Alive ucode status 0x%08X revision " "0x%01X 0x%01X\n", palive->is_valid, palive->ver_type, palive->ver_subtype); - trans->shrd->device_pointers.error_event_table = + priv->shrd->device_pointers.error_event_table = le32_to_cpu(palive->error_event_table_ptr); - trans->shrd->device_pointers.log_event_table = + priv->shrd->device_pointers.log_event_table = le32_to_cpu(palive->log_event_table_ptr); alive_data->subtype = palive->ver_subtype; @@ -464,12 +461,12 @@ static void iwl_alive_fn(struct iwl_trans *trans, /* notification wait support */ void iwl_init_notification_wait(struct iwl_shared *shrd, - struct iwl_notification_wait *wait_entry, - u8 cmd, - void (*fn)(struct iwl_trans *trans, - struct iwl_rx_packet *pkt, - void *data), - void *fn_data) + struct iwl_notification_wait *wait_entry, + u8 cmd, + void (*fn)(struct iwl_priv *priv, + struct iwl_rx_packet *pkt, + void *data), + void *fn_data) { wait_entry->fn = fn; wait_entry->fn_data = fn_data; @@ -529,7 +526,7 @@ void iwl_abort_notification_waits(struct iwl_shared *shrd) #define UCODE_ALIVE_TIMEOUT HZ #define UCODE_CALIB_TIMEOUT (2*HZ) -int iwl_load_ucode_wait_alive(struct iwl_trans *trans, +int iwl_load_ucode_wait_alive(struct iwl_priv *priv, enum iwl_ucode_type ucode_type) { struct iwl_notification_wait alive_wait; @@ -538,20 +535,20 @@ int iwl_load_ucode_wait_alive(struct iwl_trans *trans, int ret; enum iwl_ucode_type old_type; - iwl_init_notification_wait(trans->shrd, &alive_wait, REPLY_ALIVE, + iwl_init_notification_wait(priv->shrd, &alive_wait, REPLY_ALIVE, iwl_alive_fn, &alive_data); - old_type = trans->shrd->ucode_type; - trans->shrd->ucode_type = ucode_type; - fw = iwl_get_ucode_image(nic(trans), ucode_type); + old_type = priv->shrd->ucode_type; + priv->shrd->ucode_type = ucode_type; + fw = iwl_get_ucode_image(priv, ucode_type); if (!fw) return -EINVAL; - ret = iwl_trans_start_fw(trans, fw); + ret = iwl_trans_start_fw(trans(priv), fw); if (ret) { - trans->shrd->ucode_type = old_type; - iwl_remove_notification(trans->shrd, &alive_wait); + priv->shrd->ucode_type = old_type; + iwl_remove_notification(priv->shrd, &alive_wait); return ret; } @@ -559,16 +556,16 @@ int iwl_load_ucode_wait_alive(struct iwl_trans *trans, * Some things may run in the background now, but we * just wait for the ALIVE notification here. */ - ret = iwl_wait_notification(trans->shrd, &alive_wait, + ret = iwl_wait_notification(priv->shrd, &alive_wait, UCODE_ALIVE_TIMEOUT); if (ret) { - trans->shrd->ucode_type = old_type; + priv->shrd->ucode_type = old_type; return ret; } if (!alive_data.valid) { - IWL_ERR(trans, "Loaded ucode is not valid!\n"); - trans->shrd->ucode_type = old_type; + IWL_ERR(priv, "Loaded ucode is not valid!\n"); + priv->shrd->ucode_type = old_type; return -EIO; } @@ -578,9 +575,9 @@ int iwl_load_ucode_wait_alive(struct iwl_trans *trans, * skip it for WoWLAN. */ if (ucode_type != IWL_UCODE_WOWLAN) { - ret = iwl_verify_ucode(nic(trans), ucode_type); + ret = iwl_verify_ucode(priv, ucode_type); if (ret) { - trans->shrd->ucode_type = old_type; + priv->shrd->ucode_type = old_type; return ret; } @@ -588,41 +585,41 @@ int iwl_load_ucode_wait_alive(struct iwl_trans *trans, msleep(5); } - ret = iwl_alive_notify(trans); + ret = iwl_alive_notify(priv); if (ret) { - IWL_WARN(trans, + IWL_WARN(priv, "Could not complete ALIVE transition: %d\n", ret); - trans->shrd->ucode_type = old_type; + priv->shrd->ucode_type = old_type; return ret; } return 0; } -int iwl_run_init_ucode(struct iwl_trans *trans) +int iwl_run_init_ucode(struct iwl_priv *priv) { struct iwl_notification_wait calib_wait; int ret; - lockdep_assert_held(&trans->shrd->mutex); + lockdep_assert_held(&priv->shrd->mutex); /* No init ucode required? Curious, but maybe ok */ - if (!nic(trans)->fw.ucode_init.code.len) + if (!nic(priv)->fw.ucode_init.code.len) return 0; - if (trans->shrd->ucode_type != IWL_UCODE_NONE) + if (priv->shrd->ucode_type != IWL_UCODE_NONE) return 0; - iwl_init_notification_wait(trans->shrd, &calib_wait, + iwl_init_notification_wait(priv->shrd, &calib_wait, CALIBRATION_COMPLETE_NOTIFICATION, NULL, NULL); /* Will also start the device */ - ret = iwl_load_ucode_wait_alive(trans, IWL_UCODE_INIT); + ret = iwl_load_ucode_wait_alive(priv, IWL_UCODE_INIT); if (ret) goto error; - ret = iwl_init_alive_start(trans); + ret = iwl_init_alive_start(priv); if (ret) goto error; @@ -630,15 +627,15 @@ int iwl_run_init_ucode(struct iwl_trans *trans) * Some things may run in the background now, but we * just wait for the calibration complete notification. */ - ret = iwl_wait_notification(trans->shrd, &calib_wait, + ret = iwl_wait_notification(priv->shrd, &calib_wait, UCODE_CALIB_TIMEOUT); goto out; error: - iwl_remove_notification(trans->shrd, &calib_wait); + iwl_remove_notification(priv->shrd, &calib_wait); out: /* Whatever happened, stop the device */ - iwl_trans_stop_device(trans); + iwl_trans_stop_device(trans(priv)); return ret; } diff --git a/drivers/net/wireless/iwlwifi/iwl-wifi.h b/drivers/net/wireless/iwlwifi/iwl-wifi.h index d157931e1e95..753e338e77d0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-wifi.h +++ b/drivers/net/wireless/iwlwifi/iwl-wifi.h @@ -95,12 +95,4 @@ struct iwl_nic { struct completion request_firmware_complete; }; - - -int iwl_send_bt_env(struct iwl_trans *trans, u8 action, u8 type); -void iwl_send_prio_tbl(struct iwl_trans *trans); -int iwl_init_alive_start(struct iwl_trans *trans); -int iwl_run_init_ucode(struct iwl_trans *trans); -int iwl_load_ucode_wait_alive(struct iwl_trans *trans, - enum iwl_ucode_type ucode_type); #endif /* __iwl_wifi_h__ */ -- cgit From 0692fe41b36159be5d8c7d4eef0699e79c383c85 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 6 Mar 2012 13:30:37 -0800 Subject: iwlwifi: split out firmware store Through the driver, struct iwl_fw will store the firmware. Split this out into a separate file, iwl-fw.h, and make all other code use it. To do this, also move the log pointers into it, and remove the knowledge of "nic" from everything. Now the op_mode has a fw pointer, and (unfortunately) for now the shared data also needs to keep one for the transport to access dump the error log -- I think that will move later. Since I wanted to constify the firmware pointers, some more changes were needed. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-calib.c | 5 +- drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 2 +- drivers/net/wireless/iwlwifi/iwl-agn.c | 10 +- drivers/net/wireless/iwlwifi/iwl-agn.h | 2 +- drivers/net/wireless/iwlwifi/iwl-commands.h | 12 -- drivers/net/wireless/iwlwifi/iwl-debugfs.c | 9 +- drivers/net/wireless/iwlwifi/iwl-dev.h | 1 + drivers/net/wireless/iwlwifi/iwl-drv.c | 49 ++++---- drivers/net/wireless/iwlwifi/iwl-fw.h | 146 +++++++++++++++++++++++ drivers/net/wireless/iwlwifi/iwl-mac80211.c | 10 +- drivers/net/wireless/iwlwifi/iwl-op-mode.h | 4 +- drivers/net/wireless/iwlwifi/iwl-shared.h | 5 +- drivers/net/wireless/iwlwifi/iwl-testmode.c | 16 +-- drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c | 23 ++-- drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | 9 +- drivers/net/wireless/iwlwifi/iwl-trans.h | 5 +- drivers/net/wireless/iwlwifi/iwl-ucode.c | 21 ++-- drivers/net/wireless/iwlwifi/iwl-ucode.h | 60 ---------- drivers/net/wireless/iwlwifi/iwl-wifi.h | 10 -- 19 files changed, 236 insertions(+), 163 deletions(-) create mode 100644 drivers/net/wireless/iwlwifi/iwl-fw.h diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c index 29f94597b55f..4928f6f52bf1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c @@ -69,7 +69,6 @@ #include "iwl-trans.h" #include "iwl-agn.h" #include "iwl-wifi.h" -#include "iwl-ucode.h" /***************************************************************************** * INIT calibrations framework @@ -644,7 +643,7 @@ void iwl_init_sensitivity(struct iwl_priv *priv) data->last_bad_plcp_cnt_cck = 0; data->last_fa_cnt_cck = 0; - if (nic(priv)->fw.enhance_sensitivity_table) + if (priv->fw->enhance_sensitivity_table) ret |= iwl_enhance_sensitivity_write(priv); else ret |= iwl_sensitivity_write(priv); @@ -754,7 +753,7 @@ void iwl_sensitivity_calibration(struct iwl_priv *priv) iwl_sens_auto_corr_ofdm(priv, norm_fa_ofdm, rx_enable_time); iwl_sens_energy_cck(priv, norm_fa_cck, rx_enable_time, &statis); - if (nic(priv)->fw.enhance_sensitivity_table) + if (priv->fw->enhance_sensitivity_table) iwl_enhance_sensitivity_write(priv); else iwl_sensitivity_write(priv); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index 45b060a45d9d..89be05615dd9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -77,7 +77,7 @@ int iwlagn_send_tx_power(struct iwl_priv *priv) tx_power_cmd.flags = IWLAGN_TX_POWER_NO_CLOSED; tx_power_cmd.srv_chan_lmt = IWLAGN_TX_POWER_AUTO; - if (IWL_UCODE_API(nic(priv)->fw.ucode_ver) == 1) + if (IWL_UCODE_API(priv->fw->ucode_ver) == 1) tx_ant_cfg_cmd = REPLY_TX_POWER_DBM_CMD_V1; else tx_ant_cfg_cmd = REPLY_TX_POWER_DBM_CMD; diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index f53308fb428e..c3040ad86e89 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -41,7 +41,6 @@ #include -#include "iwl-ucode.h" #include "iwl-eeprom.h" #include "iwl-wifi.h" #include "iwl-dev.h" @@ -616,7 +615,7 @@ static int iwlagn_send_tx_ant_config(struct iwl_priv *priv, u8 valid_tx_ant) .valid = cpu_to_le32(valid_tx_ant), }; - if (IWL_UCODE_API(nic(priv)->fw.ucode_ver) > 1) { + if (IWL_UCODE_API(priv->fw->ucode_ver) > 1) { IWL_DEBUG_HC(priv, "select valid tx ant: %u\n", valid_tx_ant); return iwl_trans_send_cmd_pdu(trans(priv), TX_ANT_CONFIGURATION_CMD, @@ -1174,9 +1173,9 @@ static void iwl_debug_config(struct iwl_priv *priv) #endif } -static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans) +static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans, + const struct iwl_fw *fw) { - struct iwl_fw *fw = &nic(trans)->fw; int err = 0; struct iwl_priv *priv; struct ieee80211_hw *hw; @@ -1200,6 +1199,9 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans) priv = IWL_OP_MODE_GET_DVM(op_mode); priv->shrd = trans->shrd; priv->shrd->priv = priv; + priv->fw = fw; + /* TODO: remove fw from shared data later */ + priv->shrd->fw = fw; iwl_trans_configure(trans(priv), op_mode); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index 2a90d779eecf..f55243828698 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h @@ -93,7 +93,7 @@ void iwl_nic_error(struct iwl_op_mode *op_mode); /* MAC80211 */ struct ieee80211_hw *iwl_alloc_all(void); int iwlagn_mac_setup_register(struct iwl_priv *priv, - struct iwl_ucode_capabilities *capa); + const struct iwl_ucode_capabilities *capa); void iwlagn_mac_unregister(struct iwl_priv *priv); /* RXON */ diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index c20618d92268..aa8993065cdf 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h @@ -74,13 +74,6 @@ struct iwl_priv; -/* uCode version contains 4 values: Major/Minor/API/Serial */ -#define IWL_UCODE_MAJOR(ver) (((ver) & 0xFF000000) >> 24) -#define IWL_UCODE_MINOR(ver) (((ver) & 0x00FF0000) >> 16) -#define IWL_UCODE_API(ver) (((ver) & 0x0000FF00) >> 8) -#define IWL_UCODE_SERIAL(ver) ((ver) & 0x000000FF) - - /* Tx rates */ #define IWL_CCK_RATES 4 #define IWL_OFDM_RATES 8 @@ -3151,8 +3144,6 @@ struct iwl_enhance_sensitivity_cmd { */ /* Phy calibration command for series */ -/* The default calibrate table size if not specified by firmware */ -#define IWL_DEFAULT_STANDARD_PHY_CALIBRATE_TBL_SIZE 18 enum { IWL_PHY_CALIBRATE_DC_CMD = 8, IWL_PHY_CALIBRATE_LO_CMD = 9, @@ -3161,11 +3152,8 @@ enum { IWL_PHY_CALIBRATE_BASE_BAND_CMD = 16, IWL_PHY_CALIBRATE_TX_IQ_PERD_CMD = 17, IWL_PHY_CALIBRATE_TEMP_OFFSET_CMD = 18, - IWL_MAX_STANDARD_PHY_CALIBRATE_TBL_SIZE = 19, }; -#define IWL_MAX_PHY_CALIBRATE_TBL_SIZE (253) - /* This enum defines the bitmap of various calibrations to enable in both * init ucode and runtime ucode through CALIBRATION_CFG_CMD. */ diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index b6740c33b519..0e63cb70c713 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c @@ -235,12 +235,11 @@ static ssize_t iwl_dbgfs_sram_read(struct file *file, /* default is to dump the entire data segment */ if (!priv->dbgfs_sram_offset && !priv->dbgfs_sram_len) { - struct iwl_nic *nic = nic(priv); priv->dbgfs_sram_offset = 0x800000; - if (nic->shrd->ucode_type == IWL_UCODE_INIT) - priv->dbgfs_sram_len = nic->fw.ucode_init.data.len; + if (priv->shrd->ucode_type == IWL_UCODE_INIT) + priv->dbgfs_sram_len = priv->fw->ucode_init.data.len; else - priv->dbgfs_sram_len = nic->fw.ucode_rt.data.len; + priv->dbgfs_sram_len = priv->fw->ucode_rt.data.len; } len = priv->dbgfs_sram_len; @@ -343,7 +342,7 @@ static ssize_t iwl_dbgfs_wowlan_sram_read(struct file *file, return simple_read_from_buffer(user_buf, count, ppos, priv->wowlan_sram, - nic(priv)->fw.ucode_wowlan.data.len); + priv->fw->ucode_wowlan.data.len); } static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 7199748faaab..4def9f961891 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -715,6 +715,7 @@ struct iwl_priv { /*data shared among all the driver's layers */ struct iwl_shared *shrd; + const struct iwl_fw *fw; spinlock_t sta_lock; diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.c b/drivers/net/wireless/iwlwifi/iwl-drv.c index 1a588f36b591..351b2f908383 100644 --- a/drivers/net/wireless/iwlwifi/iwl-drv.c +++ b/drivers/net/wireless/iwlwifi/iwl-drv.c @@ -71,6 +71,9 @@ #include "iwl-shared.h" #include "iwl-op-mode.h" +/* private includes */ +#include "iwl-ucode.h" + static void iwl_free_fw_desc(struct iwl_nic *nic, struct fw_desc *desc) { if (desc->v_addr) @@ -641,20 +644,20 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) * for each event, which is of mode 1 (including timestamp) for all * new microcodes that include this information. */ - nic->init_evtlog_ptr = pieces.init_evtlog_ptr; + fw->init_evtlog_ptr = pieces.init_evtlog_ptr; if (pieces.init_evtlog_size) - nic->init_evtlog_size = (pieces.init_evtlog_size - 16)/12; + fw->init_evtlog_size = (pieces.init_evtlog_size - 16)/12; else - nic->init_evtlog_size = + fw->init_evtlog_size = cfg->base_params->max_event_log_size; - nic->init_errlog_ptr = pieces.init_errlog_ptr; - nic->inst_evtlog_ptr = pieces.inst_evtlog_ptr; + fw->init_errlog_ptr = pieces.init_errlog_ptr; + fw->inst_evtlog_ptr = pieces.inst_evtlog_ptr; if (pieces.inst_evtlog_size) - nic->inst_evtlog_size = (pieces.inst_evtlog_size - 16)/12; + fw->inst_evtlog_size = (pieces.inst_evtlog_size - 16)/12; else - nic->inst_evtlog_size = + fw->inst_evtlog_size = cfg->base_params->max_event_log_size; - nic->inst_errlog_ptr = pieces.inst_errlog_ptr; + fw->inst_errlog_ptr = pieces.inst_errlog_ptr; /* * figure out the offset of chain noise reset and gain commands @@ -669,7 +672,7 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) release_firmware(ucode_raw); complete(&nic->request_firmware_complete); - nic->op_mode = iwl_dvm_ops.start(nic->shrd->trans); + nic->op_mode = iwl_dvm_ops.start(nic->shrd->trans, &nic->fw); if (!nic->op_mode) goto out_unbind; @@ -695,24 +698,27 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) int iwl_drv_start(struct iwl_shared *shrd, struct iwl_trans *trans, const struct iwl_cfg *cfg) { + struct iwl_nic *nic; int ret; shrd->cfg = cfg; - shrd->nic = kzalloc(sizeof(*shrd->nic), GFP_KERNEL); - if (!shrd->nic) { + nic = kzalloc(sizeof(*nic), GFP_KERNEL); + if (!nic) { dev_printk(KERN_ERR, trans->dev, "Couldn't allocate iwl_nic"); return -ENOMEM; } - shrd->nic->shrd = shrd; + nic->shrd = shrd; + shrd->nic = nic; - init_completion(&shrd->nic->request_firmware_complete); + init_completion(&nic->request_firmware_complete); - ret = iwl_request_firmware(shrd->nic, true); + ret = iwl_request_firmware(nic, true); if (ret) { dev_printk(KERN_ERR, trans->dev, "Couldn't request the fw"); - kfree(shrd->nic); + kfree(nic); + shrd->nic = NULL; } return ret; @@ -720,13 +726,16 @@ int iwl_drv_start(struct iwl_shared *shrd, void iwl_drv_stop(struct iwl_shared *shrd) { - wait_for_completion(&shrd->nic->request_firmware_complete); + struct iwl_nic *nic = shrd->nic; + + wait_for_completion(&nic->request_firmware_complete); /* op_mode can be NULL if its start failed */ - if (shrd->nic->op_mode) - iwl_op_mode_stop(shrd->nic->op_mode); + if (nic->op_mode) + iwl_op_mode_stop(nic->op_mode); - iwl_dealloc_ucode(shrd->nic); + iwl_dealloc_ucode(nic); - kfree(shrd->nic); + kfree(nic); + shrd->nic = NULL; } diff --git a/drivers/net/wireless/iwlwifi/iwl-fw.h b/drivers/net/wireless/iwlwifi/iwl-fw.h new file mode 100644 index 000000000000..453812a21176 --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-fw.h @@ -0,0 +1,146 @@ +/****************************************************************************** + * + * This file is provided under a dual BSD/GPLv2 license. When using or + * redistributing this file, you may do so under either license. + * + * GPL LICENSE SUMMARY + * + * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, + * USA + * + * The full GNU General Public License is included in this distribution + * in the file called LICENSE.GPL. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + * BSD LICENSE + * + * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, 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. + * * 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 Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER 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, WHETHER IN 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. + *****************************************************************************/ + +#ifndef __iwl_fw_h__ +#define __iwl_fw_h__ +#include + +/** + * enum iwl_ucode_tlv_flag - ucode API flags + * @IWL_UCODE_TLV_FLAGS_PAN: This is PAN capable microcode; this previously + * was a separate TLV but moved here to save space. + * @IWL_UCODE_TLV_FLAGS_NEWSCAN: new uCode scan behaviour on hidden SSID, + * treats good CRC threshold as a boolean + * @IWL_UCODE_TLV_FLAGS_MFP: This uCode image supports MFP (802.11w). + * @IWL_UCODE_TLV_FLAGS_P2P: This uCode image supports P2P. + */ +enum iwl_ucode_tlv_flag { + IWL_UCODE_TLV_FLAGS_PAN = BIT(0), + IWL_UCODE_TLV_FLAGS_NEWSCAN = BIT(1), + IWL_UCODE_TLV_FLAGS_MFP = BIT(2), + IWL_UCODE_TLV_FLAGS_P2P = BIT(3), +}; + +/* The default calibrate table size if not specified by firmware file */ +#define IWL_DEFAULT_STANDARD_PHY_CALIBRATE_TBL_SIZE 18 +#define IWL_MAX_STANDARD_PHY_CALIBRATE_TBL_SIZE 19 +#define IWL_MAX_PHY_CALIBRATE_TBL_SIZE 253 + +struct iwl_ucode_capabilities { + u32 max_probe_length; + u32 standard_phy_calibration_size; + u32 flags; +}; + +/* one for each uCode image (inst/data, boot/init/runtime) */ +struct fw_desc { + dma_addr_t p_addr; /* hardware address */ + void *v_addr; /* software address */ + u32 len; /* size in bytes */ +}; + +struct fw_img { + struct fw_desc code; /* firmware code image */ + struct fw_desc data; /* firmware data image */ +}; + +/* uCode version contains 4 values: Major/Minor/API/Serial */ +#define IWL_UCODE_MAJOR(ver) (((ver) & 0xFF000000) >> 24) +#define IWL_UCODE_MINOR(ver) (((ver) & 0x00FF0000) >> 16) +#define IWL_UCODE_API(ver) (((ver) & 0x0000FF00) >> 8) +#define IWL_UCODE_SERIAL(ver) ((ver) & 0x000000FF) + +/** + * struct iwl_fw - variables associated with the firmware + * + * @ucode_ver: ucode version from the ucode file + * @fw_version: firmware version string + * @ucode_rt: run time ucode image + * @ucode_init: init ucode image + * @ucode_wowlan: wake on wireless ucode image (optional) + * @ucode_capa: capabilities parsed from the ucode file. + * @enhance_sensitivity_table: device can do enhanced sensitivity. + * @init_evtlog_ptr: event log offset for init ucode. + * @init_evtlog_size: event log size for init ucode. + * @init_errlog_ptr: error log offfset for init ucode. + * @inst_evtlog_ptr: event log offset for runtime ucode. + * @inst_evtlog_size: event log size for runtime ucode. + * @inst_errlog_ptr: error log offfset for runtime ucode. + */ +struct iwl_fw { + u32 ucode_ver; + + char fw_version[ETHTOOL_BUSINFO_LEN]; + + /* ucode images */ + struct fw_img ucode_rt; + struct fw_img ucode_init; + struct fw_img ucode_wowlan; + + struct iwl_ucode_capabilities ucode_capa; + bool enhance_sensitivity_table; + + u32 init_evtlog_ptr, init_evtlog_size, init_errlog_ptr; + u32 inst_evtlog_ptr, inst_evtlog_size, inst_errlog_ptr; +}; + +#endif /* __iwl_fw_h__ */ diff --git a/drivers/net/wireless/iwlwifi/iwl-mac80211.c b/drivers/net/wireless/iwlwifi/iwl-mac80211.c index 37330addce79..3bcd2a766074 100644 --- a/drivers/net/wireless/iwlwifi/iwl-mac80211.c +++ b/drivers/net/wireless/iwlwifi/iwl-mac80211.c @@ -42,7 +42,6 @@ #include -#include "iwl-ucode.h" #include "iwl-eeprom.h" #include "iwl-wifi.h" #include "iwl-dev.h" @@ -136,7 +135,7 @@ iwlagn_iface_combinations_p2p[] = { * other mac80211 functions grouped here. */ int iwlagn_mac_setup_register(struct iwl_priv *priv, - struct iwl_ucode_capabilities *capa) + const struct iwl_ucode_capabilities *capa) { int ret; struct ieee80211_hw *hw = priv->hw; @@ -195,7 +194,7 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv, WIPHY_FLAG_DISABLE_BEACON_HINTS | WIPHY_FLAG_IBSS_RSN; - if (nic(priv)->fw.ucode_wowlan.code.len && + if (priv->fw->ucode_wowlan.code.len && trans(priv)->ops->wowlan_suspend && device_can_wakeup(trans(priv)->dev)) { hw->wiphy->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT | @@ -456,17 +455,16 @@ static int iwlagn_mac_resume(struct ieee80211_hw *hw) #ifdef CONFIG_IWLWIFI_DEBUGFS if (ret == 0) { - struct iwl_nic *nic = nic(priv); if (!priv->wowlan_sram) priv->wowlan_sram = - kzalloc(nic->fw.ucode_wowlan.data.len, + kzalloc(priv->fw->ucode_wowlan.data.len, GFP_KERNEL); if (priv->wowlan_sram) _iwl_read_targ_mem_words( trans(priv), 0x800000, priv->wowlan_sram, - nic->fw.ucode_wowlan.data.len / 4); + priv->fw->ucode_wowlan.data.len / 4); } #endif } diff --git a/drivers/net/wireless/iwlwifi/iwl-op-mode.h b/drivers/net/wireless/iwlwifi/iwl-op-mode.h index 41e58a136715..55b8b27a9560 100644 --- a/drivers/net/wireless/iwlwifi/iwl-op-mode.h +++ b/drivers/net/wireless/iwlwifi/iwl-op-mode.h @@ -68,6 +68,7 @@ struct iwl_trans; struct sk_buff; struct iwl_device_cmd; struct iwl_rx_cmd_buffer; +struct iwl_fw; /** * DOC: Operational mode - what is it ? @@ -123,7 +124,8 @@ struct iwl_rx_cmd_buffer; * @nic_error: error notification. Must be atomic */ struct iwl_op_mode_ops { - struct iwl_op_mode *(*start)(struct iwl_trans *trans); + struct iwl_op_mode *(*start)(struct iwl_trans *trans, + const struct iwl_fw *fw); void (*stop)(struct iwl_op_mode *op_mode); int (*rx)(struct iwl_op_mode *op_mode, struct iwl_rx_cmd_buffer *rxb, struct iwl_device_cmd *cmd); diff --git a/drivers/net/wireless/iwlwifi/iwl-shared.h b/drivers/net/wireless/iwlwifi/iwl-shared.h index dc5544653bc0..3754c35a1a50 100644 --- a/drivers/net/wireless/iwlwifi/iwl-shared.h +++ b/drivers/net/wireless/iwlwifi/iwl-shared.h @@ -70,6 +70,7 @@ #include #include "iwl-commands.h" +#include "iwl-fw.h" /** * DOC: shared area - role and goal @@ -418,8 +419,9 @@ struct iwl_shared { const struct iwl_cfg *cfg; struct iwl_priv *priv; struct iwl_trans *trans; - struct iwl_nic *nic; + void *nic; struct iwl_hw_params hw_params; + const struct iwl_fw *fw; struct mutex mutex; @@ -446,7 +448,6 @@ struct iwl_shared { /*Whatever _m is (iwl_trans, iwl_priv, these macros will work */ #define priv(_m) ((_m)->shrd->priv) #define cfg(_m) ((_m)->shrd->cfg) -#define nic(_m) ((_m)->shrd->nic) #define trans(_m) ((_m)->shrd->trans) #define hw_params(_m) ((_m)->shrd->hw_params) diff --git a/drivers/net/wireless/iwlwifi/iwl-testmode.c b/drivers/net/wireless/iwlwifi/iwl-testmode.c index ec803ea08675..fd25dd1d62e0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-testmode.c +++ b/drivers/net/wireless/iwlwifi/iwl-testmode.c @@ -553,7 +553,7 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb) case IWL_TM_CMD_APP2DEV_GET_FW_VERSION: IWL_INFO(priv, "uCode version raw: 0x%x\n", - nic(priv)->fw.ucode_ver); + priv->fw->ucode_ver); skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, 20); if (!skb) { @@ -561,7 +561,7 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb) return -ENOMEM; } NLA_PUT_U32(skb, IWL_TM_ATTR_FW_VERSION, - nic(priv)->fw.ucode_ver); + priv->fw->ucode_ver); status = cfg80211_testmode_reply(skb); if (status < 0) IWL_ERR(priv, "Error sending msg : %d\n", status); @@ -590,16 +590,16 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb) } switch (priv->shrd->ucode_type) { case IWL_UCODE_REGULAR: - inst_size = nic(priv)->fw.ucode_rt.code.len; - data_size = nic(priv)->fw.ucode_rt.data.len; + inst_size = priv->fw->ucode_rt.code.len; + data_size = priv->fw->ucode_rt.data.len; break; case IWL_UCODE_INIT: - inst_size = nic(priv)->fw.ucode_init.code.len; - data_size = nic(priv)->fw.ucode_init.data.len; + inst_size = priv->fw->ucode_init.code.len; + data_size = priv->fw->ucode_init.data.len; break; case IWL_UCODE_WOWLAN: - inst_size = nic(priv)->fw.ucode_wowlan.code.len; - data_size = nic(priv)->fw.ucode_wowlan.data.len; + inst_size = priv->fw->ucode_wowlan.code.len; + data_size = priv->fw->ucode_wowlan.data.len; break; case IWL_UCODE_NONE: IWL_ERR(priv, "No uCode has not been loaded\n"); diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c index bf560e9f87b7..69e4544afe24 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c @@ -602,17 +602,16 @@ static void iwl_dump_nic_error_log(struct iwl_trans *trans) { u32 base; struct iwl_error_event_table table; - struct iwl_nic *nic = nic(trans); struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); base = trans->shrd->device_pointers.error_event_table; if (trans->shrd->ucode_type == IWL_UCODE_INIT) { if (!base) - base = nic->init_errlog_ptr; + base = trans->shrd->fw->init_errlog_ptr; } else { if (!base) - base = nic->inst_errlog_ptr; + base = trans->shrd->fw->inst_errlog_ptr; } if (!iwlagn_hw_valid_rtc_data_addr(base)) { @@ -634,7 +633,7 @@ static void iwl_dump_nic_error_log(struct iwl_trans *trans) trans_pcie->isr_stats.err_code = table.error_id; - trace_iwlwifi_dev_ucode_error(priv(nic), table.error_id, table.tsf_low, + trace_iwlwifi_dev_ucode_error(priv(trans), table.error_id, table.tsf_low, table.data1, table.data2, table.line, table.blink1, table.blink2, table.ilink1, table.ilink2, table.bcon_time, table.gp1, @@ -700,7 +699,7 @@ static void iwl_irq_handle_error(struct iwl_trans *trans) } IWL_ERR(trans, "Loaded firmware version: %s\n", - nic(trans)->fw.fw_version); + trans->shrd->fw->fw_version); iwl_dump_nic_error_log(trans); iwl_dump_csr(trans); @@ -726,7 +725,6 @@ static int iwl_print_event_log(struct iwl_trans *trans, u32 start_idx, u32 ptr; /* SRAM byte address of log data */ u32 ev, time, data; /* event log data */ unsigned long reg_flags; - struct iwl_nic *nic = nic(trans); if (num_events == 0) return pos; @@ -734,10 +732,10 @@ static int iwl_print_event_log(struct iwl_trans *trans, u32 start_idx, base = trans->shrd->device_pointers.log_event_table; if (trans->shrd->ucode_type == IWL_UCODE_INIT) { if (!base) - base = nic->init_evtlog_ptr; + base = trans->shrd->fw->init_evtlog_ptr; } else { if (!base) - base = nic->inst_evtlog_ptr; + base = trans->shrd->fw->inst_evtlog_ptr; } if (mode == 0) @@ -843,17 +841,16 @@ int iwl_dump_nic_event_log(struct iwl_trans *trans, bool full_log, u32 logsize; int pos = 0; size_t bufsz = 0; - struct iwl_nic *nic = nic(trans); base = trans->shrd->device_pointers.log_event_table; if (trans->shrd->ucode_type == IWL_UCODE_INIT) { - logsize = nic->init_evtlog_size; + logsize = trans->shrd->fw->init_evtlog_size; if (!base) - base = nic->init_evtlog_ptr; + base = trans->shrd->fw->init_evtlog_ptr; } else { - logsize = nic->inst_evtlog_size; + logsize = trans->shrd->fw->inst_evtlog_size; if (!base) - base = nic->inst_evtlog_ptr; + base = trans->shrd->fw->inst_evtlog_ptr; } if (!iwlagn_hw_valid_rtc_data_addr(base)) { diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c index f49aa181f4af..d7dbd80eb108 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c @@ -76,7 +76,6 @@ #include "iwl-eeprom.h" #include "iwl-agn-hw.h" #include "iwl-core.h" -#include "iwl-ucode.h" #define IWL_MASK(lo, hi) ((1 << (hi)) | ((1 << (hi)) - (1 << (lo)))) @@ -947,7 +946,7 @@ static const u8 iwlagn_pan_ac_to_queue[] = { * ucode */ static int iwl_load_section(struct iwl_trans *trans, const char *name, - struct fw_desc *image, u32 dst_addr) + const struct fw_desc *image, u32 dst_addr) { dma_addr_t phy_addr = image->p_addr; u32 byte_cnt = image->len; @@ -995,7 +994,8 @@ static int iwl_load_section(struct iwl_trans *trans, const char *name, return 0; } -static int iwl_load_given_ucode(struct iwl_trans *trans, struct fw_img *image) +static int iwl_load_given_ucode(struct iwl_trans *trans, + const struct fw_img *image) { int ret = 0; @@ -1015,7 +1015,8 @@ static int iwl_load_given_ucode(struct iwl_trans *trans, struct fw_img *image) return 0; } -static int iwl_trans_pcie_start_fw(struct iwl_trans *trans, struct fw_img *fw) +static int iwl_trans_pcie_start_fw(struct iwl_trans *trans, + const struct fw_img *fw) { int ret; struct iwl_trans_pcie *trans_pcie = diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index 6fa0c860a5e2..ec5249c8a7f4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h @@ -272,7 +272,7 @@ struct iwl_trans_ops { int (*start_hw)(struct iwl_trans *iwl_trans); void (*stop_hw)(struct iwl_trans *iwl_trans); - int (*start_fw)(struct iwl_trans *trans, struct fw_img *fw); + int (*start_fw)(struct iwl_trans *trans, const struct fw_img *fw); void (*fw_alive)(struct iwl_trans *trans); void (*stop_device)(struct iwl_trans *trans); @@ -400,7 +400,8 @@ static inline void iwl_trans_fw_alive(struct iwl_trans *trans) trans->state = IWL_TRANS_FW_ALIVE; } -static inline int iwl_trans_start_fw(struct iwl_trans *trans, struct fw_img *fw) +static inline int iwl_trans_start_fw(struct iwl_trans *trans, + const struct fw_img *fw) { might_sleep(); diff --git a/drivers/net/wireless/iwlwifi/iwl-ucode.c b/drivers/net/wireless/iwlwifi/iwl-ucode.c index 340575a01ead..f78b1552ef7c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-ucode.c +++ b/drivers/net/wireless/iwlwifi/iwl-ucode.c @@ -31,7 +31,6 @@ #include #include -#include "iwl-ucode.h" #include "iwl-wifi.h" #include "iwl-dev.h" #include "iwl-core.h" @@ -80,16 +79,16 @@ static struct iwl_wimax_coex_event_entry cu_priorities[COEX_NUM_OF_EVENTS] = { * ******************************************************************************/ -static inline struct fw_img *iwl_get_ucode_image(struct iwl_priv *priv, - enum iwl_ucode_type ucode_type) +static inline const struct fw_img * +iwl_get_ucode_image(struct iwl_priv *priv, enum iwl_ucode_type ucode_type) { switch (ucode_type) { case IWL_UCODE_INIT: - return &nic(priv)->fw.ucode_init; + return &priv->fw->ucode_init; case IWL_UCODE_WOWLAN: - return &nic(priv)->fw.ucode_wowlan; + return &priv->fw->ucode_wowlan; case IWL_UCODE_REGULAR: - return &nic(priv)->fw.ucode_rt; + return &priv->fw->ucode_rt; case IWL_UCODE_NONE: break; } @@ -355,7 +354,7 @@ static int iwl_alive_notify(struct iwl_priv *priv) * it's a pretty good bet that everything between them is good, too. */ static int iwl_verify_inst_sparse(struct iwl_priv *priv, - struct fw_desc *fw_desc) + const struct fw_desc *fw_desc) { __le32 *image = (__le32 *)fw_desc->v_addr; u32 len = fw_desc->len; @@ -379,7 +378,7 @@ static int iwl_verify_inst_sparse(struct iwl_priv *priv, } static void iwl_print_mismatch_inst(struct iwl_priv *priv, - struct fw_desc *fw_desc) + const struct fw_desc *fw_desc) { __le32 *image = (__le32 *)fw_desc->v_addr; u32 len = fw_desc->len; @@ -413,7 +412,7 @@ static void iwl_print_mismatch_inst(struct iwl_priv *priv, static int iwl_verify_ucode(struct iwl_priv *priv, enum iwl_ucode_type ucode_type) { - struct fw_img *img = iwl_get_ucode_image(priv, ucode_type); + const struct fw_img *img = iwl_get_ucode_image(priv, ucode_type); if (!img) { IWL_ERR(priv, "Invalid ucode requested (%d)\n", ucode_type); @@ -531,7 +530,7 @@ int iwl_load_ucode_wait_alive(struct iwl_priv *priv, { struct iwl_notification_wait alive_wait; struct iwl_alive_data alive_data; - struct fw_img *fw; + const struct fw_img *fw; int ret; enum iwl_ucode_type old_type; @@ -604,7 +603,7 @@ int iwl_run_init_ucode(struct iwl_priv *priv) lockdep_assert_held(&priv->shrd->mutex); /* No init ucode required? Curious, but maybe ok */ - if (!nic(priv)->fw.ucode_init.code.len) + if (!priv->fw->ucode_init.code.len) return 0; if (priv->shrd->ucode_type != IWL_UCODE_NONE) diff --git a/drivers/net/wireless/iwlwifi/iwl-ucode.h b/drivers/net/wireless/iwlwifi/iwl-ucode.h index 8bebeb003bef..cdab28784404 100644 --- a/drivers/net/wireless/iwlwifi/iwl-ucode.h +++ b/drivers/net/wireless/iwlwifi/iwl-ucode.h @@ -126,22 +126,6 @@ enum iwl_ucode_tlv_type { IWL_UCODE_TLV_FLAGS = 18, }; -/** - * enum iwl_ucode_tlv_flag - ucode API flags - * @IWL_UCODE_TLV_FLAGS_PAN: This is PAN capable microcode; this previously - * was a separate TLV but moved here to save space. - * @IWL_UCODE_TLV_FLAGS_NEWSCAN: new uCode scan behaviour on hidden SSID, - * treats good CRC threshold as a boolean - * @IWL_UCODE_TLV_FLAGS_MFP: This uCode image supports MFP (802.11w). - * @IWL_UCODE_TLV_FLAGS_P2P: This uCode image supports P2P. - */ -enum iwl_ucode_tlv_flag { - IWL_UCODE_TLV_FLAGS_PAN = BIT(0), - IWL_UCODE_TLV_FLAGS_NEWSCAN = BIT(1), - IWL_UCODE_TLV_FLAGS_MFP = BIT(2), - IWL_UCODE_TLV_FLAGS_P2P = BIT(3), -}; - struct iwl_ucode_tlv { __le16 type; /* see above */ __le16 alternative; /* see comment */ @@ -173,48 +157,4 @@ struct iwl_tlv_ucode_header { u8 data[0]; }; -struct iwl_ucode_capabilities { - u32 max_probe_length; - u32 standard_phy_calibration_size; - u32 flags; -}; - -/* one for each uCode image (inst/data, boot/init/runtime) */ -struct fw_desc { - dma_addr_t p_addr; /* hardware address */ - void *v_addr; /* software address */ - u32 len; /* size in bytes */ -}; - -struct fw_img { - struct fw_desc code; /* firmware code image */ - struct fw_desc data; /* firmware data image */ -}; - -/** - * struct iwl_fw - variables associated with the firmware - * - * @ucode_ver: ucode version from the ucode file - * @fw_version: firmware version string - * @ucode_rt: run time ucode image - * @ucode_init: init ucode image - * @ucode_wowlan: wake on wireless ucode image (optional) - * @ucode_capa: capabilities parsed from the ucode file. - * @enhance_sensitivity_table: device can do enhanced sensitivity. - */ -struct iwl_fw { - - u32 ucode_ver; - - char fw_version[ETHTOOL_BUSINFO_LEN]; - - /* ucode images */ - struct fw_img ucode_rt; - struct fw_img ucode_init; - struct fw_img ucode_wowlan; - - struct iwl_ucode_capabilities ucode_capa; - bool enhance_sensitivity_table; -}; - #endif /* __iwl_ucode_h__ */ diff --git a/drivers/net/wireless/iwlwifi/iwl-wifi.h b/drivers/net/wireless/iwlwifi/iwl-wifi.h index 753e338e77d0..a71624d3ea23 100644 --- a/drivers/net/wireless/iwlwifi/iwl-wifi.h +++ b/drivers/net/wireless/iwlwifi/iwl-wifi.h @@ -64,7 +64,6 @@ #define __iwl_wifi_h__ #include "iwl-shared.h" -#include "iwl-ucode.h" /** * struct iwl_nic - nic common data @@ -73,12 +72,6 @@ * @op_mode: the running op_mode * @fw_index: firmware revision to try loading * @firmware_name: composite filename of ucode file to load - * @init_evtlog_ptr: event log offset for init ucode. - * @init_evtlog_size: event log size for init ucode. - * @init_errlog_ptr: error log offfset for init ucode. - * @inst_evtlog_ptr: event log offset for runtime ucode. - * @inst_evtlog_size: event log size for runtime ucode. - * @inst_errlog_ptr: error log offfset for runtime ucode. * @request_firmware_complete: the firmware has been obtained from user space */ struct iwl_nic { @@ -90,9 +83,6 @@ struct iwl_nic { int fw_index; /* firmware we're trying to load */ char firmware_name[25]; /* name of firmware file to load */ - u32 init_evtlog_ptr, init_evtlog_size, init_errlog_ptr; - u32 inst_evtlog_ptr, inst_evtlog_size, inst_errlog_ptr; - struct completion request_firmware_complete; }; #endif /* __iwl_wifi_h__ */ -- cgit From 965974a631756ab2729469b9ecadfe61ee44dfc5 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 6 Mar 2012 13:30:38 -0800 Subject: iwlwifi: remove iwl-wifi.h This file was recently introduced, but then directly abused -- it contained private data that shouldn't have been used by anything but the implementation of firmware requests and some very core code. Now that it is no longer accessed by any code but the code in iwl-drv.c, we can dissolve it. Also rename the iwl_nic struct to iwl_drv to better reflect where and how it is used. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-calib.c | 1 - drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 1 - drivers/net/wireless/iwlwifi/iwl-agn.c | 1 - drivers/net/wireless/iwlwifi/iwl-core.c | 1 - drivers/net/wireless/iwlwifi/iwl-debugfs.c | 1 - drivers/net/wireless/iwlwifi/iwl-drv.c | 272 ++++++++++++----------- drivers/net/wireless/iwlwifi/iwl-mac80211.c | 1 - drivers/net/wireless/iwlwifi/iwl-shared.h | 2 +- drivers/net/wireless/iwlwifi/iwl-testmode.c | 1 - drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c | 1 - drivers/net/wireless/iwlwifi/iwl-ucode.c | 1 - drivers/net/wireless/iwlwifi/iwl-wifi.h | 88 -------- 12 files changed, 148 insertions(+), 223 deletions(-) delete mode 100644 drivers/net/wireless/iwlwifi/iwl-wifi.h diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c index 4928f6f52bf1..588d107b82f4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c @@ -68,7 +68,6 @@ #include "iwl-agn-calib.h" #include "iwl-trans.h" #include "iwl-agn.h" -#include "iwl-wifi.h" /***************************************************************************** * INIT calibrations framework diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index 89be05615dd9..b06283282283 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -32,7 +32,6 @@ #include #include -#include "iwl-wifi.h" #include "iwl-dev.h" #include "iwl-core.h" #include "iwl-io.h" diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index c3040ad86e89..cdfe76151072 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -42,7 +42,6 @@ #include #include "iwl-eeprom.h" -#include "iwl-wifi.h" #include "iwl-dev.h" #include "iwl-core.h" #include "iwl-io.h" diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index c5df3e3d975b..9ae17c3bb885 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -41,7 +41,6 @@ #include "iwl-shared.h" #include "iwl-agn.h" #include "iwl-trans.h" -#include "iwl-wifi.h" const u8 iwl_bcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index 0e63cb70c713..bc3e267ed4c0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c @@ -40,7 +40,6 @@ #include "iwl-core.h" #include "iwl-io.h" #include "iwl-agn.h" -#include "iwl-wifi.h" /* create and remove of files */ #define DEBUGFS_ADD_FILE(name, parent, mode) do { \ diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.c b/drivers/net/wireless/iwlwifi/iwl-drv.c index 351b2f908383..f1beeab1e601 100644 --- a/drivers/net/wireless/iwlwifi/iwl-drv.c +++ b/drivers/net/wireless/iwlwifi/iwl-drv.c @@ -67,36 +67,58 @@ #include "iwl-drv.h" #include "iwl-trans.h" -#include "iwl-wifi.h" #include "iwl-shared.h" #include "iwl-op-mode.h" /* private includes */ #include "iwl-ucode.h" -static void iwl_free_fw_desc(struct iwl_nic *nic, struct fw_desc *desc) +/** + * struct iwl_drv - drv common data + * @fw: the iwl_fw structure + * @shrd: pointer to common shared structure + * @op_mode: the running op_mode + * @fw_index: firmware revision to try loading + * @firmware_name: composite filename of ucode file to load + * @request_firmware_complete: the firmware has been obtained from user space + */ +struct iwl_drv { + struct iwl_fw fw; + + struct iwl_shared *shrd; + struct iwl_op_mode *op_mode; + + int fw_index; /* firmware we're trying to load */ + char firmware_name[25]; /* name of firmware file to load */ + + struct completion request_firmware_complete; +}; + + + +static void iwl_free_fw_desc(struct iwl_drv *drv, struct fw_desc *desc) { if (desc->v_addr) - dma_free_coherent(trans(nic)->dev, desc->len, + dma_free_coherent(trans(drv)->dev, desc->len, desc->v_addr, desc->p_addr); desc->v_addr = NULL; desc->len = 0; } -static void iwl_free_fw_img(struct iwl_nic *nic, struct fw_img *img) +static void iwl_free_fw_img(struct iwl_drv *drv, struct fw_img *img) { - iwl_free_fw_desc(nic, &img->code); - iwl_free_fw_desc(nic, &img->data); + iwl_free_fw_desc(drv, &img->code); + iwl_free_fw_desc(drv, &img->data); } -static void iwl_dealloc_ucode(struct iwl_nic *nic) +static void iwl_dealloc_ucode(struct iwl_drv *drv) { - iwl_free_fw_img(nic, &nic->fw.ucode_rt); - iwl_free_fw_img(nic, &nic->fw.ucode_init); - iwl_free_fw_img(nic, &nic->fw.ucode_wowlan); + iwl_free_fw_img(drv, &drv->fw.ucode_rt); + iwl_free_fw_img(drv, &drv->fw.ucode_init); + iwl_free_fw_img(drv, &drv->fw.ucode_wowlan); } -static int iwl_alloc_fw_desc(struct iwl_nic *nic, struct fw_desc *desc, +static int iwl_alloc_fw_desc(struct iwl_drv *drv, struct fw_desc *desc, const void *data, size_t len) { if (!len) { @@ -104,7 +126,7 @@ static int iwl_alloc_fw_desc(struct iwl_nic *nic, struct fw_desc *desc, return -EINVAL; } - desc->v_addr = dma_alloc_coherent(trans(nic)->dev, len, + desc->v_addr = dma_alloc_coherent(trans(drv)->dev, len, &desc->p_addr, GFP_KERNEL); if (!desc->v_addr) return -ENOMEM; @@ -119,40 +141,40 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context); #define UCODE_EXPERIMENTAL_INDEX 100 #define UCODE_EXPERIMENTAL_TAG "exp" -static int iwl_request_firmware(struct iwl_nic *nic, bool first) +static int iwl_request_firmware(struct iwl_drv *drv, bool first) { - const struct iwl_cfg *cfg = cfg(nic); + const struct iwl_cfg *cfg = cfg(drv); const char *name_pre = cfg->fw_name_pre; char tag[8]; if (first) { #ifdef CONFIG_IWLWIFI_DEBUG_EXPERIMENTAL_UCODE - nic->fw_index = UCODE_EXPERIMENTAL_INDEX; + drv->fw_index = UCODE_EXPERIMENTAL_INDEX; strcpy(tag, UCODE_EXPERIMENTAL_TAG); - } else if (nic->fw_index == UCODE_EXPERIMENTAL_INDEX) { + } else if (drv->fw_index == UCODE_EXPERIMENTAL_INDEX) { #endif - nic->fw_index = cfg->ucode_api_max; - sprintf(tag, "%d", nic->fw_index); + drv->fw_index = cfg->ucode_api_max; + sprintf(tag, "%d", drv->fw_index); } else { - nic->fw_index--; - sprintf(tag, "%d", nic->fw_index); + drv->fw_index--; + sprintf(tag, "%d", drv->fw_index); } - if (nic->fw_index < cfg->ucode_api_min) { - IWL_ERR(nic, "no suitable firmware found!\n"); + if (drv->fw_index < cfg->ucode_api_min) { + IWL_ERR(drv, "no suitable firmware found!\n"); return -ENOENT; } - sprintf(nic->firmware_name, "%s%s%s", name_pre, tag, ".ucode"); + sprintf(drv->firmware_name, "%s%s%s", name_pre, tag, ".ucode"); - IWL_DEBUG_INFO(nic, "attempting to load firmware %s'%s'\n", - (nic->fw_index == UCODE_EXPERIMENTAL_INDEX) + IWL_DEBUG_INFO(drv, "attempting to load firmware %s'%s'\n", + (drv->fw_index == UCODE_EXPERIMENTAL_INDEX) ? "EXPERIMENTAL " : "", - nic->firmware_name); + drv->firmware_name); - return request_firmware_nowait(THIS_MODULE, 1, nic->firmware_name, - trans(nic)->dev, - GFP_KERNEL, nic, iwl_ucode_callback); + return request_firmware_nowait(THIS_MODULE, 1, drv->firmware_name, + trans(drv)->dev, + GFP_KERNEL, drv, iwl_ucode_callback); } struct iwlagn_firmware_pieces { @@ -164,7 +186,7 @@ struct iwlagn_firmware_pieces { u32 inst_evtlog_ptr, inst_evtlog_size, inst_errlog_ptr; }; -static int iwl_parse_v1_v2_firmware(struct iwl_nic *nic, +static int iwl_parse_v1_v2_firmware(struct iwl_drv *drv, const struct firmware *ucode_raw, struct iwlagn_firmware_pieces *pieces) { @@ -173,14 +195,14 @@ static int iwl_parse_v1_v2_firmware(struct iwl_nic *nic, char buildstr[25]; const u8 *src; - nic->fw.ucode_ver = le32_to_cpu(ucode->ver); - api_ver = IWL_UCODE_API(nic->fw.ucode_ver); + drv->fw.ucode_ver = le32_to_cpu(ucode->ver); + api_ver = IWL_UCODE_API(drv->fw.ucode_ver); switch (api_ver) { default: hdr_size = 28; if (ucode_raw->size < hdr_size) { - IWL_ERR(nic, "File size too small!\n"); + IWL_ERR(drv, "File size too small!\n"); return -EINVAL; } build = le32_to_cpu(ucode->u.v2.build); @@ -196,7 +218,7 @@ static int iwl_parse_v1_v2_firmware(struct iwl_nic *nic, case 2: hdr_size = 24; if (ucode_raw->size < hdr_size) { - IWL_ERR(nic, "File size too small!\n"); + IWL_ERR(drv, "File size too small!\n"); return -EINVAL; } build = 0; @@ -211,18 +233,18 @@ static int iwl_parse_v1_v2_firmware(struct iwl_nic *nic, if (build) sprintf(buildstr, " build %u%s", build, - (nic->fw_index == UCODE_EXPERIMENTAL_INDEX) + (drv->fw_index == UCODE_EXPERIMENTAL_INDEX) ? " (EXP)" : ""); else buildstr[0] = '\0'; - snprintf(nic->fw.fw_version, - sizeof(nic->fw.fw_version), + snprintf(drv->fw.fw_version, + sizeof(drv->fw.fw_version), "%u.%u.%u.%u%s", - IWL_UCODE_MAJOR(nic->fw.ucode_ver), - IWL_UCODE_MINOR(nic->fw.ucode_ver), - IWL_UCODE_API(nic->fw.ucode_ver), - IWL_UCODE_SERIAL(nic->fw.ucode_ver), + IWL_UCODE_MAJOR(drv->fw.ucode_ver), + IWL_UCODE_MINOR(drv->fw.ucode_ver), + IWL_UCODE_API(drv->fw.ucode_ver), + IWL_UCODE_SERIAL(drv->fw.ucode_ver), buildstr); /* Verify size of file vs. image size info in file's header */ @@ -230,7 +252,7 @@ static int iwl_parse_v1_v2_firmware(struct iwl_nic *nic, pieces->data_size + pieces->init_size + pieces->init_data_size) { - IWL_ERR(nic, + IWL_ERR(drv, "uCode file size %d does not match expected size\n", (int)ucode_raw->size); return -EINVAL; @@ -248,7 +270,7 @@ static int iwl_parse_v1_v2_firmware(struct iwl_nic *nic, return 0; } -static int iwl_parse_tlv_firmware(struct iwl_nic *nic, +static int iwl_parse_tlv_firmware(struct iwl_drv *drv, const struct firmware *ucode_raw, struct iwlagn_firmware_pieces *pieces, struct iwl_ucode_capabilities *capa) @@ -267,12 +289,12 @@ static int iwl_parse_tlv_firmware(struct iwl_nic *nic, u32 build; if (len < sizeof(*ucode)) { - IWL_ERR(nic, "uCode has invalid length: %zd\n", len); + IWL_ERR(drv, "uCode has invalid length: %zd\n", len); return -EINVAL; } if (ucode->magic != cpu_to_le32(IWL_TLV_UCODE_MAGIC)) { - IWL_ERR(nic, "invalid uCode magic: 0X%x\n", + IWL_ERR(drv, "invalid uCode magic: 0X%x\n", le32_to_cpu(ucode->magic)); return -EINVAL; } @@ -290,27 +312,27 @@ static int iwl_parse_tlv_firmware(struct iwl_nic *nic, while (wanted_alternative && !(alternatives & BIT(wanted_alternative))) wanted_alternative--; if (wanted_alternative && wanted_alternative != tmp) - IWL_WARN(nic, + IWL_WARN(drv, "uCode alternative %d not available, choosing %d\n", tmp, wanted_alternative); - nic->fw.ucode_ver = le32_to_cpu(ucode->ver); + drv->fw.ucode_ver = le32_to_cpu(ucode->ver); build = le32_to_cpu(ucode->build); if (build) sprintf(buildstr, " build %u%s", build, - (nic->fw_index == UCODE_EXPERIMENTAL_INDEX) + (drv->fw_index == UCODE_EXPERIMENTAL_INDEX) ? " (EXP)" : ""); else buildstr[0] = '\0'; - snprintf(nic->fw.fw_version, - sizeof(nic->fw.fw_version), + snprintf(drv->fw.fw_version, + sizeof(drv->fw.fw_version), "%u.%u.%u.%u%s", - IWL_UCODE_MAJOR(nic->fw.ucode_ver), - IWL_UCODE_MINOR(nic->fw.ucode_ver), - IWL_UCODE_API(nic->fw.ucode_ver), - IWL_UCODE_SERIAL(nic->fw.ucode_ver), + IWL_UCODE_MAJOR(drv->fw.ucode_ver), + IWL_UCODE_MINOR(drv->fw.ucode_ver), + IWL_UCODE_API(drv->fw.ucode_ver), + IWL_UCODE_SERIAL(drv->fw.ucode_ver), buildstr); data = ucode->data; @@ -329,7 +351,7 @@ static int iwl_parse_tlv_firmware(struct iwl_nic *nic, tlv_data = tlv->data; if (len < tlv_len) { - IWL_ERR(nic, "invalid TLV len: %zd/%u\n", + IWL_ERR(drv, "invalid TLV len: %zd/%u\n", len, tlv_len); return -EINVAL; } @@ -362,7 +384,7 @@ static int iwl_parse_tlv_firmware(struct iwl_nic *nic, pieces->init_data_size = tlv_len; break; case IWL_UCODE_TLV_BOOT: - IWL_ERR(nic, "Found unexpected BOOT ucode\n"); + IWL_ERR(drv, "Found unexpected BOOT ucode\n"); break; case IWL_UCODE_TLV_PROBE_MAX_LEN: if (tlv_len != sizeof(u32)) @@ -430,7 +452,7 @@ static int iwl_parse_tlv_firmware(struct iwl_nic *nic, case IWL_UCODE_TLV_ENHANCE_SENS_TBL: if (tlv_len) goto invalid_tlv_len; - nic->fw.enhance_sensitivity_table = true; + drv->fw.enhance_sensitivity_table = true; break; case IWL_UCODE_TLV_WOWLAN_INST: pieces->wowlan_inst = tlv_data; @@ -447,22 +469,22 @@ static int iwl_parse_tlv_firmware(struct iwl_nic *nic, le32_to_cpup((__le32 *)tlv_data); break; default: - IWL_DEBUG_INFO(nic, "unknown TLV: %d\n", tlv_type); + IWL_DEBUG_INFO(drv, "unknown TLV: %d\n", tlv_type); break; } } if (len) { - IWL_ERR(nic, "invalid TLV after parsing: %zd\n", len); - iwl_print_hex_dump(nic, IWL_DL_FW, (u8 *)data, len); + IWL_ERR(drv, "invalid TLV after parsing: %zd\n", len); + iwl_print_hex_dump(drv, IWL_DL_FW, (u8 *)data, len); return -EINVAL; } return 0; invalid_tlv_len: - IWL_ERR(nic, "TLV %d has invalid size: %u\n", tlv_type, tlv_len); - iwl_print_hex_dump(nic, IWL_DL_FW, tlv_data, tlv_len); + IWL_ERR(drv, "TLV %d has invalid size: %u\n", tlv_type, tlv_len); + iwl_print_hex_dump(drv, IWL_DL_FW, tlv_data, tlv_len); return -EINVAL; } @@ -475,9 +497,9 @@ static int iwl_parse_tlv_firmware(struct iwl_nic *nic, */ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) { - struct iwl_nic *nic = context; - const struct iwl_cfg *cfg = cfg(nic); - struct iwl_fw *fw = &nic->fw; + struct iwl_drv *drv = context; + const struct iwl_cfg *cfg = cfg(drv); + struct iwl_fw *fw = &drv->fw; struct iwl_ucode_header *ucode; int err; struct iwlagn_firmware_pieces pieces; @@ -496,19 +518,19 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) memset(&pieces, 0, sizeof(pieces)); if (!ucode_raw) { - if (nic->fw_index <= api_ok) - IWL_ERR(nic, + if (drv->fw_index <= api_ok) + IWL_ERR(drv, "request for firmware file '%s' failed.\n", - nic->firmware_name); + drv->firmware_name); goto try_again; } - IWL_DEBUG_INFO(nic, "Loaded firmware file '%s' (%zd bytes).\n", - nic->firmware_name, ucode_raw->size); + IWL_DEBUG_INFO(drv, "Loaded firmware file '%s' (%zd bytes).\n", + drv->firmware_name, ucode_raw->size); /* Make sure that we got at least the API version number */ if (ucode_raw->size < 4) { - IWL_ERR(nic, "File size way too small!\n"); + IWL_ERR(drv, "File size way too small!\n"); goto try_again; } @@ -516,15 +538,15 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) ucode = (struct iwl_ucode_header *)ucode_raw->data; if (ucode->ver) - err = iwl_parse_v1_v2_firmware(nic, ucode_raw, &pieces); + err = iwl_parse_v1_v2_firmware(drv, ucode_raw, &pieces); else - err = iwl_parse_tlv_firmware(nic, ucode_raw, &pieces, + err = iwl_parse_tlv_firmware(drv, ucode_raw, &pieces, &fw->ucode_capa); if (err) goto try_again; - api_ver = IWL_UCODE_API(nic->fw.ucode_ver); + api_ver = IWL_UCODE_API(drv->fw.ucode_ver); /* * api_ver should match the api version forming part of the @@ -532,9 +554,9 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) * on the API version read from firmware header from here on forward */ /* no api version check required for experimental uCode */ - if (nic->fw_index != UCODE_EXPERIMENTAL_INDEX) { + if (drv->fw_index != UCODE_EXPERIMENTAL_INDEX) { if (api_ver < api_min || api_ver > api_max) { - IWL_ERR(nic, + IWL_ERR(drv, "Driver unable to support your firmware API. " "Driver supports v%u, firmware is v%u.\n", api_max, api_ver); @@ -543,19 +565,19 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) if (api_ver < api_ok) { if (api_ok != api_max) - IWL_ERR(nic, "Firmware has old API version, " + IWL_ERR(drv, "Firmware has old API version, " "expected v%u through v%u, got v%u.\n", api_ok, api_max, api_ver); else - IWL_ERR(nic, "Firmware has old API version, " + IWL_ERR(drv, "Firmware has old API version, " "expected v%u, got v%u.\n", api_max, api_ver); - IWL_ERR(nic, "New firmware can be obtained from " + IWL_ERR(drv, "New firmware can be obtained from " "http://www.intellinuxwireless.org/.\n"); } } - IWL_INFO(nic, "loaded firmware version %s", nic->fw.fw_version); + IWL_INFO(drv, "loaded firmware version %s", drv->fw.fw_version); /* * For any of the failures below (before allocating pci memory) @@ -563,38 +585,38 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) * user just got a corrupted version of the latest API. */ - IWL_DEBUG_INFO(nic, "f/w package hdr ucode version raw = 0x%x\n", - nic->fw.ucode_ver); - IWL_DEBUG_INFO(nic, "f/w package hdr runtime inst size = %Zd\n", + IWL_DEBUG_INFO(drv, "f/w package hdr ucode version raw = 0x%x\n", + drv->fw.ucode_ver); + IWL_DEBUG_INFO(drv, "f/w package hdr runtime inst size = %Zd\n", pieces.inst_size); - IWL_DEBUG_INFO(nic, "f/w package hdr runtime data size = %Zd\n", + IWL_DEBUG_INFO(drv, "f/w package hdr runtime data size = %Zd\n", pieces.data_size); - IWL_DEBUG_INFO(nic, "f/w package hdr init inst size = %Zd\n", + IWL_DEBUG_INFO(drv, "f/w package hdr init inst size = %Zd\n", pieces.init_size); - IWL_DEBUG_INFO(nic, "f/w package hdr init data size = %Zd\n", + IWL_DEBUG_INFO(drv, "f/w package hdr init data size = %Zd\n", pieces.init_data_size); /* Verify that uCode images will fit in card's SRAM */ if (pieces.inst_size > cfg->max_inst_size) { - IWL_ERR(nic, "uCode instr len %Zd too large to fit in\n", + IWL_ERR(drv, "uCode instr len %Zd too large to fit in\n", pieces.inst_size); goto try_again; } if (pieces.data_size > cfg->max_data_size) { - IWL_ERR(nic, "uCode data len %Zd too large to fit in\n", + IWL_ERR(drv, "uCode data len %Zd too large to fit in\n", pieces.data_size); goto try_again; } if (pieces.init_size > cfg->max_inst_size) { - IWL_ERR(nic, "uCode init instr len %Zd too large to fit in\n", + IWL_ERR(drv, "uCode init instr len %Zd too large to fit in\n", pieces.init_size); goto try_again; } if (pieces.init_data_size > cfg->max_data_size) { - IWL_ERR(nic, "uCode init data len %Zd too large to fit in\n", + IWL_ERR(drv, "uCode init data len %Zd too large to fit in\n", pieces.init_data_size); goto try_again; } @@ -604,34 +626,34 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) /* Runtime instructions and 2 copies of data: * 1) unmodified from disk * 2) backup cache for save/restore during power-downs */ - if (iwl_alloc_fw_desc(nic, &nic->fw.ucode_rt.code, + if (iwl_alloc_fw_desc(drv, &drv->fw.ucode_rt.code, pieces.inst, pieces.inst_size)) goto err_pci_alloc; - if (iwl_alloc_fw_desc(nic, &nic->fw.ucode_rt.data, + if (iwl_alloc_fw_desc(drv, &drv->fw.ucode_rt.data, pieces.data, pieces.data_size)) goto err_pci_alloc; /* Initialization instructions and data */ if (pieces.init_size && pieces.init_data_size) { - if (iwl_alloc_fw_desc(nic, - &nic->fw.ucode_init.code, + if (iwl_alloc_fw_desc(drv, + &drv->fw.ucode_init.code, pieces.init, pieces.init_size)) goto err_pci_alloc; - if (iwl_alloc_fw_desc(nic, - &nic->fw.ucode_init.data, + if (iwl_alloc_fw_desc(drv, + &drv->fw.ucode_init.data, pieces.init_data, pieces.init_data_size)) goto err_pci_alloc; } /* WoWLAN instructions and data */ if (pieces.wowlan_inst_size && pieces.wowlan_data_size) { - if (iwl_alloc_fw_desc(nic, - &nic->fw.ucode_wowlan.code, + if (iwl_alloc_fw_desc(drv, + &drv->fw.ucode_wowlan.code, pieces.wowlan_inst, pieces.wowlan_inst_size)) goto err_pci_alloc; - if (iwl_alloc_fw_desc(nic, - &nic->fw.ucode_wowlan.data, + if (iwl_alloc_fw_desc(drv, + &drv->fw.ucode_wowlan.data, pieces.wowlan_data, pieces.wowlan_data_size)) goto err_pci_alloc; @@ -670,11 +692,11 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) /* We have our copies now, allow OS release its copies */ release_firmware(ucode_raw); - complete(&nic->request_firmware_complete); + complete(&drv->request_firmware_complete); - nic->op_mode = iwl_dvm_ops.start(nic->shrd->trans, &nic->fw); + drv->op_mode = iwl_dvm_ops.start(drv->shrd->trans, &drv->fw); - if (!nic->op_mode) + if (!drv->op_mode) goto out_unbind; return; @@ -682,43 +704,43 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) try_again: /* try next, if any */ release_firmware(ucode_raw); - if (iwl_request_firmware(nic, false)) + if (iwl_request_firmware(drv, false)) goto out_unbind; return; err_pci_alloc: - IWL_ERR(nic, "failed to allocate pci memory\n"); - iwl_dealloc_ucode(nic); + IWL_ERR(drv, "failed to allocate pci memory\n"); + iwl_dealloc_ucode(drv); release_firmware(ucode_raw); out_unbind: - complete(&nic->request_firmware_complete); - device_release_driver(trans(nic)->dev); + complete(&drv->request_firmware_complete); + device_release_driver(trans(drv)->dev); } int iwl_drv_start(struct iwl_shared *shrd, struct iwl_trans *trans, const struct iwl_cfg *cfg) { - struct iwl_nic *nic; + struct iwl_drv *drv; int ret; shrd->cfg = cfg; - nic = kzalloc(sizeof(*nic), GFP_KERNEL); - if (!nic) { - dev_printk(KERN_ERR, trans->dev, "Couldn't allocate iwl_nic"); + drv = kzalloc(sizeof(*drv), GFP_KERNEL); + if (!drv) { + dev_printk(KERN_ERR, trans->dev, "Couldn't allocate iwl_drv"); return -ENOMEM; } - nic->shrd = shrd; - shrd->nic = nic; + drv->shrd = shrd; + shrd->drv = drv; - init_completion(&nic->request_firmware_complete); + init_completion(&drv->request_firmware_complete); - ret = iwl_request_firmware(nic, true); + ret = iwl_request_firmware(drv, true); if (ret) { dev_printk(KERN_ERR, trans->dev, "Couldn't request the fw"); - kfree(nic); - shrd->nic = NULL; + kfree(drv); + shrd->drv = NULL; } return ret; @@ -726,16 +748,16 @@ int iwl_drv_start(struct iwl_shared *shrd, void iwl_drv_stop(struct iwl_shared *shrd) { - struct iwl_nic *nic = shrd->nic; + struct iwl_drv *drv = shrd->drv; - wait_for_completion(&nic->request_firmware_complete); + wait_for_completion(&drv->request_firmware_complete); /* op_mode can be NULL if its start failed */ - if (nic->op_mode) - iwl_op_mode_stop(nic->op_mode); + if (drv->op_mode) + iwl_op_mode_stop(drv->op_mode); - iwl_dealloc_ucode(nic); + iwl_dealloc_ucode(drv); - kfree(nic); - shrd->nic = NULL; + kfree(drv); + shrd->drv = NULL; } diff --git a/drivers/net/wireless/iwlwifi/iwl-mac80211.c b/drivers/net/wireless/iwlwifi/iwl-mac80211.c index 3bcd2a766074..3c9a8faba4e6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-mac80211.c +++ b/drivers/net/wireless/iwlwifi/iwl-mac80211.c @@ -43,7 +43,6 @@ #include #include "iwl-eeprom.h" -#include "iwl-wifi.h" #include "iwl-dev.h" #include "iwl-core.h" #include "iwl-io.h" diff --git a/drivers/net/wireless/iwlwifi/iwl-shared.h b/drivers/net/wireless/iwlwifi/iwl-shared.h index 3754c35a1a50..bb34766609db 100644 --- a/drivers/net/wireless/iwlwifi/iwl-shared.h +++ b/drivers/net/wireless/iwlwifi/iwl-shared.h @@ -419,7 +419,7 @@ struct iwl_shared { const struct iwl_cfg *cfg; struct iwl_priv *priv; struct iwl_trans *trans; - void *nic; + void *drv; struct iwl_hw_params hw_params; const struct iwl_fw *fw; diff --git a/drivers/net/wireless/iwlwifi/iwl-testmode.c b/drivers/net/wireless/iwlwifi/iwl-testmode.c index fd25dd1d62e0..c1ecf0fba372 100644 --- a/drivers/net/wireless/iwlwifi/iwl-testmode.c +++ b/drivers/net/wireless/iwlwifi/iwl-testmode.c @@ -70,7 +70,6 @@ #include #include -#include "iwl-wifi.h" #include "iwl-dev.h" #include "iwl-core.h" #include "iwl-debug.h" diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c index 69e4544afe24..c3c2de3b3169 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c @@ -34,7 +34,6 @@ #include "iwl-core.h" #include "iwl-io.h" #include "iwl-trans-pcie-int.h" -#include "iwl-wifi.h" #include "iwl-op-mode.h" #ifdef CONFIG_IWLWIFI_IDI diff --git a/drivers/net/wireless/iwlwifi/iwl-ucode.c b/drivers/net/wireless/iwlwifi/iwl-ucode.c index f78b1552ef7c..3747edb7c292 100644 --- a/drivers/net/wireless/iwlwifi/iwl-ucode.c +++ b/drivers/net/wireless/iwlwifi/iwl-ucode.c @@ -31,7 +31,6 @@ #include #include -#include "iwl-wifi.h" #include "iwl-dev.h" #include "iwl-core.h" #include "iwl-io.h" diff --git a/drivers/net/wireless/iwlwifi/iwl-wifi.h b/drivers/net/wireless/iwlwifi/iwl-wifi.h deleted file mode 100644 index a71624d3ea23..000000000000 --- a/drivers/net/wireless/iwlwifi/iwl-wifi.h +++ /dev/null @@ -1,88 +0,0 @@ -/****************************************************************************** - * - * This file is provided under a dual BSD/GPLv2 license. When using or - * redistributing this file, you may do so under either license. - * - * GPL LICENSE SUMMARY - * - * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, - * USA - * - * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. - * - * Contact Information: - * Intel Linux Wireless - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - * - * BSD LICENSE - * - * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, 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. - * * 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 Intel Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER 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, WHETHER IN 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. - *****************************************************************************/ - -#ifndef __iwl_wifi_h__ -#define __iwl_wifi_h__ - -#include "iwl-shared.h" - -/** - * struct iwl_nic - nic common data - * @fw: the iwl_fw structure - * @shrd: pointer to common shared structure - * @op_mode: the running op_mode - * @fw_index: firmware revision to try loading - * @firmware_name: composite filename of ucode file to load - * @request_firmware_complete: the firmware has been obtained from user space - */ -struct iwl_nic { - struct iwl_fw fw; - - struct iwl_shared *shrd; - struct iwl_op_mode *op_mode; - - int fw_index; /* firmware we're trying to load */ - char firmware_name[25]; /* name of firmware file to load */ - - struct completion request_firmware_complete; -}; -#endif /* __iwl_wifi_h__ */ -- cgit From e10a0533a9172471b52bd9512838d766420a3baf Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 6 Mar 2012 13:30:39 -0800 Subject: iwlwifi: add wrappers for command sending Add wrappers to send commands from the DVM op-mode (which essentially consists of the current driver). This will allow us to move specific sanity checks there. Also, this removes iwl_trans_send_cmd_pdu() since that can now be taken care of in the DVM-specific wrapper. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/Makefile | 1 - drivers/net/wireless/iwlwifi/iwl-5000.c | 2 +- drivers/net/wireless/iwlwifi/iwl-6000.c | 2 +- drivers/net/wireless/iwlwifi/iwl-agn-calib.c | 8 +-- drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 38 ++++++++++---- drivers/net/wireless/iwlwifi/iwl-agn-rxon.c | 16 +++--- drivers/net/wireless/iwlwifi/iwl-agn-sta.c | 8 +-- drivers/net/wireless/iwlwifi/iwl-agn.c | 10 ++-- drivers/net/wireless/iwlwifi/iwl-agn.h | 5 ++ drivers/net/wireless/iwlwifi/iwl-core.c | 10 ++-- drivers/net/wireless/iwlwifi/iwl-led.c | 2 +- drivers/net/wireless/iwlwifi/iwl-power.c | 2 +- drivers/net/wireless/iwlwifi/iwl-scan.c | 4 +- drivers/net/wireless/iwlwifi/iwl-testmode.c | 2 +- drivers/net/wireless/iwlwifi/iwl-trans.c | 77 ---------------------------- drivers/net/wireless/iwlwifi/iwl-trans.h | 3 -- drivers/net/wireless/iwlwifi/iwl-ucode.c | 8 +-- 17 files changed, 70 insertions(+), 128 deletions(-) delete mode 100644 drivers/net/wireless/iwlwifi/iwl-trans.c diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile index afa0bb8f3245..f2a903d01aa9 100644 --- a/drivers/net/wireless/iwlwifi/Makefile +++ b/drivers/net/wireless/iwlwifi/Makefile @@ -14,7 +14,6 @@ iwlwifi-objs += iwl-1000.o iwlwifi-objs += iwl-2000.o iwlwifi-objs += iwl-pci.o iwlwifi-objs += iwl-drv.o -iwlwifi-objs += iwl-trans.o iwlwifi-objs += iwl-trans-pcie.o iwl-trans-pcie-rx.o iwl-trans-pcie-tx.o iwlwifi-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index dff75a09eb48..aebdfd7e01a5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -281,7 +281,7 @@ static int iwl5000_hw_channel_switch(struct iwl_priv *priv, return -EFAULT; } - return iwl_trans_send_cmd(trans(priv), &hcmd); + return iwl_dvm_send_cmd(priv, &hcmd); } static struct iwl_lib_ops iwl5000_lib = { diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index ef896630625d..150bef078609 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -232,7 +232,7 @@ static int iwl6000_hw_channel_switch(struct iwl_priv *priv, return -EFAULT; } - return iwl_trans_send_cmd(trans(priv), &hcmd); + return iwl_dvm_send_cmd(priv, &hcmd); } static struct iwl_lib_ops iwl6000_lib = { diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c index 588d107b82f4..579679edd5f1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c @@ -104,7 +104,7 @@ int iwl_send_calib_results(struct iwl_priv *priv) hcmd.len[0] = res->cmd_len; hcmd.data[0] = &res->hdr; hcmd.dataflags[0] = IWL_HCMD_DFL_NOCOPY; - ret = iwl_trans_send_cmd(trans(priv), &hcmd); + ret = iwl_dvm_send_cmd(priv, &hcmd); if (ret) { IWL_ERR(priv, "Error %d on calib cmd %d\n", ret, res->hdr.op_code); @@ -500,7 +500,7 @@ static int iwl_sensitivity_write(struct iwl_priv *priv) memcpy(&(priv->sensitivity_tbl[0]), &(cmd.table[0]), sizeof(u16)*HD_TABLE_SIZE); - return iwl_trans_send_cmd(trans(priv), &cmd_out); + return iwl_dvm_send_cmd(priv, &cmd_out); } /* Prepare a SENSITIVITY_CMD, send to uCode if values have changed */ @@ -589,7 +589,7 @@ static int iwl_enhance_sensitivity_write(struct iwl_priv *priv) &(cmd.enhance_table[HD_INA_NON_SQUARE_DET_OFDM_INDEX]), sizeof(u16)*ENHANCE_HD_TABLE_ENTRIES); - return iwl_trans_send_cmd(trans(priv), &cmd_out); + return iwl_dvm_send_cmd(priv, &cmd_out); } void iwl_init_sensitivity(struct iwl_priv *priv) @@ -930,7 +930,7 @@ static void iwlagn_gain_computation(struct iwl_priv *priv, priv->phy_calib_chain_noise_gain_cmd); cmd.delta_gain_1 = data->delta_gain_code[1]; cmd.delta_gain_2 = data->delta_gain_code[2]; - iwl_trans_send_cmd_pdu(trans(priv), REPLY_PHY_CALIBRATION_CMD, + iwl_dvm_send_cmd_pdu(priv, REPLY_PHY_CALIBRATION_CMD, CMD_ASYNC, sizeof(cmd), &cmd); data->radio_write = 1; diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index b06283282283..4c777dfc0db0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -81,7 +81,7 @@ int iwlagn_send_tx_power(struct iwl_priv *priv) else tx_ant_cfg_cmd = REPLY_TX_POWER_DBM_CMD; - return iwl_trans_send_cmd_pdu(trans(priv), tx_ant_cfg_cmd, CMD_SYNC, + return iwl_dvm_send_cmd_pdu(priv, tx_ant_cfg_cmd, CMD_SYNC, sizeof(tx_power_cmd), &tx_power_cmd); } @@ -241,7 +241,7 @@ int iwlagn_txfifo_flush(struct iwl_priv *priv, u16 flush_control) flush_cmd.fifo_control); flush_cmd.flush_control = cpu_to_le16(flush_control); - return iwl_trans_send_cmd(trans(priv), &cmd); + return iwl_dvm_send_cmd(priv, &cmd); } void iwlagn_dev_txfifo_flush(struct iwl_priv *priv, u16 flush_control) @@ -435,12 +435,12 @@ void iwlagn_send_advance_bt_config(struct iwl_priv *priv) if (cfg(priv)->bt_params->bt_session_2) { memcpy(&bt_cmd_2000.basic, &basic, sizeof(basic)); - ret = iwl_trans_send_cmd_pdu(trans(priv), REPLY_BT_CONFIG, + ret = iwl_dvm_send_cmd_pdu(priv, REPLY_BT_CONFIG, CMD_SYNC, sizeof(bt_cmd_2000), &bt_cmd_2000); } else { memcpy(&bt_cmd_6000.basic, &basic, sizeof(basic)); - ret = iwl_trans_send_cmd_pdu(trans(priv), REPLY_BT_CONFIG, + ret = iwl_dvm_send_cmd_pdu(priv, REPLY_BT_CONFIG, CMD_SYNC, sizeof(bt_cmd_6000), &bt_cmd_6000); } if (ret) @@ -1115,7 +1115,7 @@ int iwlagn_send_patterns(struct iwl_priv *priv, } cmd.data[0] = pattern_cmd; - err = iwl_trans_send_cmd(trans(priv), &cmd); + err = iwl_dvm_send_cmd(priv, &cmd); kfree(pattern_cmd); return err; } @@ -1241,13 +1241,13 @@ int iwlagn_suspend(struct iwl_priv *priv, .len[0] = sizeof(key_data.rsc_tsc), }; - ret = iwl_trans_send_cmd(trans(priv), &rsc_tsc_cmd); + ret = iwl_dvm_send_cmd(priv, &rsc_tsc_cmd); if (ret) goto out; } if (key_data.use_tkip) { - ret = iwl_trans_send_cmd_pdu(trans(priv), + ret = iwl_dvm_send_cmd_pdu(priv, REPLY_WOWLAN_TKIP_PARAMS, CMD_SYNC, sizeof(tkip_cmd), &tkip_cmd); @@ -1263,7 +1263,7 @@ int iwlagn_suspend(struct iwl_priv *priv, kek_kck_cmd.kek_len = cpu_to_le16(NL80211_KEK_LEN); kek_kck_cmd.replay_ctr = priv->replay_ctr; - ret = iwl_trans_send_cmd_pdu(trans(priv), + ret = iwl_dvm_send_cmd_pdu(priv, REPLY_WOWLAN_KEK_KCK_MATERIAL, CMD_SYNC, sizeof(kek_kck_cmd), &kek_kck_cmd); @@ -1272,12 +1272,12 @@ int iwlagn_suspend(struct iwl_priv *priv, } } - ret = iwl_trans_send_cmd_pdu(trans(priv), REPLY_D3_CONFIG, CMD_SYNC, + ret = iwl_dvm_send_cmd_pdu(priv, REPLY_D3_CONFIG, CMD_SYNC, sizeof(d3_cfg_cmd), &d3_cfg_cmd); if (ret) goto out; - ret = iwl_trans_send_cmd_pdu(trans(priv), REPLY_WOWLAN_WAKEUP_FILTER, + ret = iwl_dvm_send_cmd_pdu(priv, REPLY_WOWLAN_WAKEUP_FILTER, CMD_SYNC, sizeof(wakeup_filter_cmd), &wakeup_filter_cmd); if (ret) @@ -1289,3 +1289,21 @@ int iwlagn_suspend(struct iwl_priv *priv, return ret; } #endif + +int iwl_dvm_send_cmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) +{ + return iwl_trans_send_cmd(trans(priv), cmd); +} + +int iwl_dvm_send_cmd_pdu(struct iwl_priv *priv, u8 id, + u32 flags, u16 len, const void *data) +{ + struct iwl_host_cmd cmd = { + .id = id, + .len = { len, }, + .data = { data, }, + .flags = flags, + }; + + return iwl_dvm_send_cmd(priv, &cmd); +} diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c index e806ad82e7e3..53114db9c9c3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c @@ -39,7 +39,7 @@ static int iwlagn_disable_bss(struct iwl_priv *priv, int ret; send->filter_flags &= ~RXON_FILTER_ASSOC_MSK; - ret = iwl_trans_send_cmd_pdu(trans(priv), ctx->rxon_cmd, + ret = iwl_dvm_send_cmd_pdu(priv, ctx->rxon_cmd, CMD_SYNC, sizeof(*send), send); send->filter_flags = old_filter; @@ -66,7 +66,7 @@ static int iwlagn_disable_pan(struct iwl_priv *priv, send->filter_flags &= ~RXON_FILTER_ASSOC_MSK; send->dev_type = RXON_DEV_TYPE_P2P; - ret = iwl_trans_send_cmd_pdu(trans(priv), ctx->rxon_cmd, + ret = iwl_dvm_send_cmd_pdu(priv, ctx->rxon_cmd, CMD_SYNC, sizeof(*send), send); send->filter_flags = old_filter; @@ -92,7 +92,7 @@ static int iwlagn_disconn_pan(struct iwl_priv *priv, int ret; send->filter_flags &= ~RXON_FILTER_ASSOC_MSK; - ret = iwl_trans_send_cmd_pdu(trans(priv), ctx->rxon_cmd, CMD_SYNC, + ret = iwl_dvm_send_cmd_pdu(priv, ctx->rxon_cmd, CMD_SYNC, sizeof(*send), send); send->filter_flags = old_filter; @@ -121,7 +121,7 @@ static void iwlagn_update_qos(struct iwl_priv *priv, ctx->qos_data.qos_active, ctx->qos_data.def_qos_parm.qos_flags); - ret = iwl_trans_send_cmd_pdu(trans(priv), ctx->qos_cmd, CMD_SYNC, + ret = iwl_dvm_send_cmd_pdu(priv, ctx->qos_cmd, CMD_SYNC, sizeof(struct iwl_qosparam_cmd), &ctx->qos_data.def_qos_parm); if (ret) @@ -180,7 +180,7 @@ static int iwlagn_send_rxon_assoc(struct iwl_priv *priv, ctx->staging.ofdm_ht_triple_stream_basic_rates; rxon_assoc.acquisition_data = ctx->staging.acquisition_data; - ret = iwl_trans_send_cmd_pdu(trans(priv), ctx->rxon_assoc_cmd, + ret = iwl_dvm_send_cmd_pdu(priv, ctx->rxon_assoc_cmd, CMD_ASYNC, sizeof(rxon_assoc), &rxon_assoc); return ret; } @@ -266,7 +266,7 @@ static int iwlagn_rxon_connect(struct iwl_priv *priv, * Associated RXON doesn't clear the station table in uCode, * so we don't need to restore stations etc. after this. */ - ret = iwl_trans_send_cmd_pdu(trans(priv), ctx->rxon_cmd, CMD_SYNC, + ret = iwl_dvm_send_cmd_pdu(priv, ctx->rxon_cmd, CMD_SYNC, sizeof(struct iwl_rxon_cmd), &ctx->staging); if (ret) { IWL_ERR(priv, "Error setting new RXON (%d)\n", ret); @@ -385,7 +385,7 @@ int iwlagn_set_pan_params(struct iwl_priv *priv) cmd.slots[0].width = cpu_to_le16(slot0); cmd.slots[1].width = cpu_to_le16(slot1); - ret = iwl_trans_send_cmd_pdu(trans(priv), REPLY_WIPAN_PARAMS, CMD_SYNC, + ret = iwl_dvm_send_cmd_pdu(priv, REPLY_WIPAN_PARAMS, CMD_SYNC, sizeof(cmd), &cmd); if (ret) IWL_ERR(priv, "Error setting PAN parameters (%d)\n", ret); @@ -771,7 +771,7 @@ static void iwlagn_chain_noise_reset(struct iwl_priv *priv) memset(&cmd, 0, sizeof(cmd)); iwl_set_calib_hdr(&cmd.hdr, priv->phy_calib_chain_noise_reset_cmd); - ret = iwl_trans_send_cmd_pdu(trans(priv), + ret = iwl_dvm_send_cmd_pdu(priv, REPLY_PHY_CALIBRATION_CMD, CMD_SYNC, sizeof(cmd), &cmd); if (ret) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c index ca080265a829..73a25f48cd53 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c @@ -153,7 +153,7 @@ int iwl_send_add_sta(struct iwl_priv *priv, might_sleep(); } - ret = iwl_trans_send_cmd(trans(priv), &cmd); + ret = iwl_dvm_send_cmd(priv, &cmd); if (ret || (flags & CMD_ASYNC)) return ret; @@ -447,7 +447,7 @@ static int iwl_send_remove_station(struct iwl_priv *priv, cmd.flags |= CMD_WANT_SKB; - ret = iwl_trans_send_cmd(trans(priv), &cmd); + ret = iwl_dvm_send_cmd(priv, &cmd); if (ret) return ret; @@ -785,7 +785,7 @@ int iwl_send_lq_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx, return -EINVAL; if (is_lq_table_valid(priv, ctx, lq)) - ret = iwl_trans_send_cmd(trans(priv), &cmd); + ret = iwl_dvm_send_cmd(priv, &cmd); else ret = -EINVAL; @@ -970,7 +970,7 @@ static int iwl_send_static_wepkey_cmd(struct iwl_priv *priv, cmd.len[0] = cmd_size; if (not_empty || send_if_empty) - return iwl_trans_send_cmd(trans(priv), &cmd); + return iwl_dvm_send_cmd(priv, &cmd); else return 0; } diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index cdfe76151072..3f59a773b3e0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -197,7 +197,7 @@ int iwlagn_send_beacon_cmd(struct iwl_priv *priv) cmd.data[1] = priv->beacon_skb->data; cmd.dataflags[1] = IWL_HCMD_DFL_NOCOPY; - return iwl_trans_send_cmd(trans(priv), &cmd); + return iwl_dvm_send_cmd(priv, &cmd); } static void iwl_bg_beacon_update(struct work_struct *work) @@ -563,7 +563,7 @@ static void iwl_rf_kill_ct_config(struct iwl_priv *priv) adv_cmd.critical_temperature_exit = cpu_to_le32(hw_params(priv).ct_kill_exit_threshold); - ret = iwl_trans_send_cmd_pdu(trans(priv), + ret = iwl_dvm_send_cmd_pdu(priv, REPLY_CT_KILL_CONFIG_CMD, CMD_SYNC, sizeof(adv_cmd), &adv_cmd); if (ret) @@ -578,7 +578,7 @@ static void iwl_rf_kill_ct_config(struct iwl_priv *priv) cmd.critical_temperature_R = cpu_to_le32(hw_params(priv).ct_kill_threshold); - ret = iwl_trans_send_cmd_pdu(trans(priv), + ret = iwl_dvm_send_cmd_pdu(priv, REPLY_CT_KILL_CONFIG_CMD, CMD_SYNC, sizeof(cmd), &cmd); if (ret) @@ -604,7 +604,7 @@ static int iwlagn_send_calib_cfg_rt(struct iwl_priv *priv, u32 cfg) calib_cfg_cmd.ucd_calib_cfg.once.is_enable = IWL_CALIB_RT_CFG_ALL; calib_cfg_cmd.ucd_calib_cfg.once.start = cpu_to_le32(cfg); - return iwl_trans_send_cmd(trans(priv), &cmd); + return iwl_dvm_send_cmd(priv, &cmd); } @@ -616,7 +616,7 @@ static int iwlagn_send_tx_ant_config(struct iwl_priv *priv, u8 valid_tx_ant) if (IWL_UCODE_API(priv->fw->ucode_ver) > 1) { IWL_DEBUG_HC(priv, "select valid tx ant: %u\n", valid_tx_ant); - return iwl_trans_send_cmd_pdu(trans(priv), + return iwl_dvm_send_cmd_pdu(priv, TX_ANT_CONFIGURATION_CMD, CMD_SYNC, sizeof(struct iwl_tx_ant_config_cmd), diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index f55243828698..dfd86f288dee 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h @@ -96,6 +96,11 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv, const struct iwl_ucode_capabilities *capa); void iwlagn_mac_unregister(struct iwl_priv *priv); +/* commands */ +int iwl_dvm_send_cmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd); +int iwl_dvm_send_cmd_pdu(struct iwl_priv *priv, u8 id, + u32 flags, u16 len, const void *data); + /* RXON */ int iwlagn_set_pan_params(struct iwl_priv *priv); int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx); diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 9ae17c3bb885..aaea51ee4185 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -369,7 +369,7 @@ int iwl_send_rxon_timing(struct iwl_priv *priv, struct iwl_rxon_context *ctx) le32_to_cpu(ctx->timing.beacon_init_val), le16_to_cpu(ctx->timing.atim_window)); - return iwl_trans_send_cmd_pdu(trans(priv), ctx->rxon_timing_cmd, + return iwl_dvm_send_cmd_pdu(priv, ctx->rxon_timing_cmd, CMD_SYNC, sizeof(ctx->timing), &ctx->timing); } @@ -958,7 +958,7 @@ void iwl_send_bt_config(struct iwl_priv *priv) IWL_DEBUG_INFO(priv, "BT coex %s\n", (bt_cmd.flags == BT_COEX_DISABLE) ? "disable" : "active"); - if (iwl_trans_send_cmd_pdu(trans(priv), REPLY_BT_CONFIG, + if (iwl_dvm_send_cmd_pdu(priv, REPLY_BT_CONFIG, CMD_SYNC, sizeof(struct iwl_bt_cmd), &bt_cmd)) IWL_ERR(priv, "failed to send BT Coex Config\n"); } @@ -971,12 +971,12 @@ int iwl_send_statistics_request(struct iwl_priv *priv, u8 flags, bool clear) }; if (flags & CMD_ASYNC) - return iwl_trans_send_cmd_pdu(trans(priv), REPLY_STATISTICS_CMD, + return iwl_dvm_send_cmd_pdu(priv, REPLY_STATISTICS_CMD, CMD_ASYNC, sizeof(struct iwl_statistics_cmd), &statistics_cmd); else - return iwl_trans_send_cmd_pdu(trans(priv), REPLY_STATISTICS_CMD, + return iwl_dvm_send_cmd_pdu(priv, REPLY_STATISTICS_CMD, CMD_SYNC, sizeof(struct iwl_statistics_cmd), &statistics_cmd); @@ -1300,7 +1300,7 @@ int iwl_cmd_echo_test(struct iwl_priv *priv) .flags = CMD_SYNC, }; - ret = iwl_trans_send_cmd(trans(priv), &cmd); + ret = iwl_dvm_send_cmd(priv, &cmd); if (ret) IWL_ERR(priv, "echo testing fail: 0X%x\n", ret); else diff --git a/drivers/net/wireless/iwlwifi/iwl-led.c b/drivers/net/wireless/iwlwifi/iwl-led.c index 5c7741f07aa0..f2f706f084a5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-led.c +++ b/drivers/net/wireless/iwlwifi/iwl-led.c @@ -112,7 +112,7 @@ static int iwl_send_led_cmd(struct iwl_priv *priv, struct iwl_led_cmd *led_cmd) iwl_write32(trans(priv), CSR_LED_REG, reg & CSR_LED_BSM_CTRL_MSK); - return iwl_trans_send_cmd(trans(priv), &cmd); + return iwl_dvm_send_cmd(priv, &cmd); } /* Set led pattern command */ diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c index 1ef3c4da1605..46ca82062c2e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-power.c +++ b/drivers/net/wireless/iwlwifi/iwl-power.c @@ -336,7 +336,7 @@ static int iwl_set_power(struct iwl_priv *priv, struct iwl_powertable_cmd *cmd) le32_to_cpu(cmd->sleep_interval[3]), le32_to_cpu(cmd->sleep_interval[4])); - return iwl_trans_send_cmd_pdu(trans(priv), POWER_TABLE_CMD, CMD_SYNC, + return iwl_dvm_send_cmd_pdu(priv, POWER_TABLE_CMD, CMD_SYNC, sizeof(struct iwl_powertable_cmd), cmd); } diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index 28899dabe6fb..dcba74883307 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c @@ -72,7 +72,7 @@ static int iwl_send_scan_abort(struct iwl_priv *priv) test_bit(STATUS_FW_ERROR, &priv->shrd->status)) return -EIO; - ret = iwl_trans_send_cmd(trans(priv), &cmd); + ret = iwl_dvm_send_cmd(priv, &cmd); if (ret) return ret; @@ -887,7 +887,7 @@ static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) if (ret) return ret; - ret = iwl_trans_send_cmd(trans(priv), &cmd); + ret = iwl_dvm_send_cmd(priv, &cmd); if (ret) { clear_bit(STATUS_SCAN_HW, &priv->shrd->status); iwlagn_set_pan_params(priv); diff --git a/drivers/net/wireless/iwlwifi/iwl-testmode.c b/drivers/net/wireless/iwlwifi/iwl-testmode.c index c1ecf0fba372..f26765b3a661 100644 --- a/drivers/net/wireless/iwlwifi/iwl-testmode.c +++ b/drivers/net/wireless/iwlwifi/iwl-testmode.c @@ -282,7 +282,7 @@ static int iwl_testmode_ucode(struct ieee80211_hw *hw, struct nlattr **tb) IWL_DEBUG_INFO(priv, "testmode ucode command ID 0x%x, flags 0x%x," " len %d\n", cmd.id, cmd.flags, cmd.len[0]); - ret = iwl_trans_send_cmd(trans(priv), &cmd); + ret = iwl_dvm_send_cmd(priv, &cmd); if (ret) { IWL_ERR(priv, "Failed to send hcmd\n"); return ret; diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.c b/drivers/net/wireless/iwlwifi/iwl-trans.c deleted file mode 100644 index 506c062343b2..000000000000 --- a/drivers/net/wireless/iwlwifi/iwl-trans.c +++ /dev/null @@ -1,77 +0,0 @@ -/****************************************************************************** - * - * This file is provided under a dual BSD/GPLv2 license. When using or - * redistributing this file, you may do so under either license. - * - * GPL LICENSE SUMMARY - * - * Copyright(c) 2007 - 2012 Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, - * USA - * - * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. - * - * Contact Information: - * Intel Linux Wireless - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - * - * BSD LICENSE - * - * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, 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. - * * 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 Intel Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER 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, WHETHER IN 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 "iwl-trans.h" - -int iwl_trans_send_cmd_pdu(struct iwl_trans *trans, u8 id, - u32 flags, u16 len, const void *data) -{ - struct iwl_host_cmd cmd = { - .id = id, - .len = { len, }, - .data = { data, }, - .flags = flags, - }; - - return iwl_trans_send_cmd(trans, &cmd); -} diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index ec5249c8a7f4..a8d476a44c58 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h @@ -443,9 +443,6 @@ static inline int iwl_trans_send_cmd(struct iwl_trans *trans, return trans->ops->send_cmd(trans, cmd); } -int iwl_trans_send_cmd_pdu(struct iwl_trans *trans, u8 id, - u32 flags, u16 len, const void *data); - static inline int iwl_trans_tx(struct iwl_trans *trans, struct sk_buff *skb, struct iwl_device_cmd *dev_cmd, enum iwl_rxon_context_id ctx, u8 sta_id, u8 tid) diff --git a/drivers/net/wireless/iwlwifi/iwl-ucode.c b/drivers/net/wireless/iwlwifi/iwl-ucode.c index 3747edb7c292..1cbe8e9926f1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-ucode.c +++ b/drivers/net/wireless/iwlwifi/iwl-ucode.c @@ -179,7 +179,7 @@ static int iwl_send_calib_cfg(struct iwl_priv *priv) calib_cfg_cmd.ucd_calib_cfg.flags = IWL_CALIB_CFG_FLAG_SEND_COMPLETE_NTFY_MSK; - return iwl_trans_send_cmd(trans(priv), &cmd); + return iwl_dvm_send_cmd(priv, &cmd); } int iwlagn_rx_calib_result(struct iwl_priv *priv, @@ -260,7 +260,7 @@ static int iwl_send_wimax_coex(struct iwl_priv *priv) /* coexistence is disabled */ memset(&coex_cmd, 0, sizeof(coex_cmd)); } - return iwl_trans_send_cmd_pdu(trans(priv), + return iwl_dvm_send_cmd_pdu(priv, COEX_PRIORITY_TABLE_CMD, CMD_SYNC, sizeof(coex_cmd), &coex_cmd); } @@ -293,7 +293,7 @@ void iwl_send_prio_tbl(struct iwl_priv *priv) memcpy(prio_tbl_cmd.prio_tbl, iwl_bt_prio_tbl, sizeof(iwl_bt_prio_tbl)); - if (iwl_trans_send_cmd_pdu(trans(priv), + if (iwl_dvm_send_cmd_pdu(priv, REPLY_BT_COEX_PRIO_TABLE, CMD_SYNC, sizeof(prio_tbl_cmd), &prio_tbl_cmd)) IWL_ERR(priv, "failed to send BT prio tbl command\n"); @@ -306,7 +306,7 @@ int iwl_send_bt_env(struct iwl_priv *priv, u8 action, u8 type) env_cmd.action = action; env_cmd.type = type; - ret = iwl_trans_send_cmd_pdu(trans(priv), + ret = iwl_dvm_send_cmd_pdu(priv, REPLY_BT_COEX_PROT_ENV, CMD_SYNC, sizeof(env_cmd), &env_cmd); if (ret) -- cgit From 721c32f72d8007dc0148ee88c046a4ade794a7b7 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 6 Mar 2012 13:30:40 -0800 Subject: iwlwifi: move RF/CT kill check to command wrapper Currently, we cannot send any commands when the uCode is in RF or CT kill, but that will not be true for all new uCode versions, so we need to move the check into the uCode specific code. Also remove the duplicate rfkill check. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 6 ++++++ drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c | 19 ++++--------------- 2 files changed, 10 insertions(+), 15 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index 4c777dfc0db0..11f24110d3fe 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -1292,6 +1292,12 @@ int iwlagn_suspend(struct iwl_priv *priv, int iwl_dvm_send_cmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) { + if (iwl_is_rfkill(priv->shrd) || iwl_is_ctkill(priv->shrd)) { + IWL_WARN(priv, "Not sending command - %s KILL\n", + iwl_is_rfkill(priv->shrd) ? "RF" : "CT"); + return -EIO; + } + return iwl_trans_send_cmd(trans(priv), cmd); } diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c index 0164154f9c97..c85975e63d75 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c @@ -721,12 +721,6 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd) if (WARN_ON(copy_size > TFD_MAX_PAYLOAD_SIZE)) return -EINVAL; - if (iwl_is_rfkill(trans->shrd) || iwl_is_ctkill(trans->shrd)) { - IWL_WARN(trans, "Not sending command - %s KILL\n", - iwl_is_rfkill(trans->shrd) ? "RF" : "CT"); - return -EIO; - } - spin_lock_bh(&txq->lock); if (iwl_queue_space(q) < ((cmd->flags & CMD_ASYNC) ? 2 : 1)) { @@ -965,7 +959,7 @@ static int iwl_send_cmd_async(struct iwl_trans *trans, struct iwl_host_cmd *cmd) ret = iwl_enqueue_hcmd(trans, cmd); if (ret < 0) { - IWL_DEBUG_QUIET_RFKILL(trans, + IWL_ERR(trans, "Error sending %s: enqueue_hcmd failed: %d\n", get_cmd_string(cmd->id), ret); return ret; @@ -984,11 +978,6 @@ static int iwl_send_cmd_sync(struct iwl_trans *trans, struct iwl_host_cmd *cmd) IWL_DEBUG_INFO(trans, "Attempting to send sync command %s\n", get_cmd_string(cmd->id)); - if (test_bit(STATUS_RF_KILL_HW, &trans->shrd->status)) { - IWL_ERR(trans, "Command %s aborted: RF KILL Switch\n", - get_cmd_string(cmd->id)); - return -ECANCELED; - } if (test_bit(STATUS_FW_ERROR, &trans->shrd->status)) { IWL_ERR(trans, "Command %s failed: FW Error\n", get_cmd_string(cmd->id)); @@ -1002,7 +991,7 @@ static int iwl_send_cmd_sync(struct iwl_trans *trans, struct iwl_host_cmd *cmd) if (cmd_idx < 0) { ret = cmd_idx; clear_bit(STATUS_HCMD_ACTIVE, &trans->shrd->status); - IWL_DEBUG_QUIET_RFKILL(trans, + IWL_ERR(trans, "Error sending %s: enqueue_hcmd failed: %d\n", get_cmd_string(cmd->id), ret); return ret; @@ -1017,12 +1006,12 @@ static int iwl_send_cmd_sync(struct iwl_trans *trans, struct iwl_host_cmd *cmd) &trans_pcie->txq[trans->shrd->cmd_queue]; struct iwl_queue *q = &txq->q; - IWL_DEBUG_QUIET_RFKILL(trans, + IWL_ERR(trans, "Error sending %s: time out after %dms.\n", get_cmd_string(cmd->id), jiffies_to_msecs(HOST_COMPLETE_TIMEOUT)); - IWL_DEBUG_QUIET_RFKILL(trans, + IWL_ERR(trans, "Current CMD queue read_ptr %d write_ptr %d\n", q->read_ptr, q->write_ptr); -- cgit From 2cc39c94c15ba1d5f6f71ab73f3369f9c17856ad Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 6 Mar 2012 13:30:41 -0800 Subject: iwlwifi: move lockdep assertion into DVM The fact that the mutex must be held is an implementation detail of DVM, but something has to ensure that no two synchronous cmds are submitted concurrently. Move the lockdep assertion into the DVM-specific code, but also make the transport abort if there are two concurrently commands. The assertion is much more useful though as the transport check can only catch it when it actually happens, while the assertion makes sure it can't possibly happen. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 8 ++++++++ drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c | 11 ++++++++--- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index 11f24110d3fe..238f824c2f3e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -1298,6 +1298,14 @@ int iwl_dvm_send_cmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) return -EIO; } + /* + * Synchronous commands from this op-mode must hold + * the mutex, this ensures we don't try to send two + * (or more) synchronous commands at a time. + */ + if (cmd->flags & CMD_SYNC) + lockdep_assert_held(&priv->shrd->mutex); + return iwl_trans_send_cmd(trans(priv), cmd); } diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c index c85975e63d75..ca4ceeacc989 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c @@ -973,8 +973,6 @@ static int iwl_send_cmd_sync(struct iwl_trans *trans, struct iwl_host_cmd *cmd) int cmd_idx; int ret; - lockdep_assert_held(&trans->shrd->mutex); - IWL_DEBUG_INFO(trans, "Attempting to send sync command %s\n", get_cmd_string(cmd->id)); @@ -983,7 +981,14 @@ static int iwl_send_cmd_sync(struct iwl_trans *trans, struct iwl_host_cmd *cmd) get_cmd_string(cmd->id)); return -EIO; } - set_bit(STATUS_HCMD_ACTIVE, &trans->shrd->status); + + if (WARN_ON(test_and_set_bit(STATUS_HCMD_ACTIVE, + &trans->shrd->status))) { + IWL_ERR(trans, "Command %s: a command is already active!\n", + get_cmd_string(cmd->id)); + return -EIO; + } + IWL_DEBUG_INFO(trans, "Setting HCMD_ACTIVE for command %s\n", get_cmd_string(cmd->id)); -- cgit From b1eea297d6b522b801c95b60b1e64fb61228c6c7 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 6 Mar 2012 13:30:42 -0800 Subject: iwlwifi: move mutex out of shared Now the mutex no longer needs to be shared, so move it into iwl_priv. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 20 +++---- drivers/net/wireless/iwlwifi/iwl-agn-rxon.c | 20 +++---- drivers/net/wireless/iwlwifi/iwl-agn-sta.c | 18 +++---- drivers/net/wireless/iwlwifi/iwl-agn-tt.c | 8 +-- drivers/net/wireless/iwlwifi/iwl-agn.c | 32 +++++------ drivers/net/wireless/iwlwifi/iwl-core.c | 4 +- drivers/net/wireless/iwlwifi/iwl-debugfs.c | 12 ++--- drivers/net/wireless/iwlwifi/iwl-dev.h | 2 + drivers/net/wireless/iwlwifi/iwl-mac80211.c | 82 ++++++++++++++--------------- drivers/net/wireless/iwlwifi/iwl-power.c | 2 +- drivers/net/wireless/iwlwifi/iwl-scan.c | 32 +++++------ drivers/net/wireless/iwlwifi/iwl-shared.h | 4 -- drivers/net/wireless/iwlwifi/iwl-testmode.c | 8 +-- drivers/net/wireless/iwlwifi/iwl-ucode.c | 2 +- 14 files changed, 122 insertions(+), 124 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index 238f824c2f3e..90f1f8a506f2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -246,7 +246,7 @@ int iwlagn_txfifo_flush(struct iwl_priv *priv, u16 flush_control) void iwlagn_dev_txfifo_flush(struct iwl_priv *priv, u16 flush_control) { - mutex_lock(&priv->shrd->mutex); + mutex_lock(&priv->mutex); ieee80211_stop_queues(priv->hw); if (iwlagn_txfifo_flush(priv, IWL_DROP_ALL)) { IWL_ERR(priv, "flush request fail\n"); @@ -256,7 +256,7 @@ void iwlagn_dev_txfifo_flush(struct iwl_priv *priv, u16 flush_control) iwl_trans_wait_tx_queue_empty(trans(priv)); done: ieee80211_wake_queues(priv->hw); - mutex_unlock(&priv->shrd->mutex); + mutex_unlock(&priv->mutex); } /* @@ -453,7 +453,7 @@ void iwlagn_bt_adjust_rssi_monitor(struct iwl_priv *priv, bool rssi_ena) struct iwl_rxon_context *ctx, *found_ctx = NULL; bool found_ap = false; - lockdep_assert_held(&priv->shrd->mutex); + lockdep_assert_held(&priv->mutex); /* Check whether AP or GO mode is active. */ if (rssi_ena) { @@ -566,7 +566,7 @@ static void iwlagn_bt_traffic_change_work(struct work_struct *work) break; } - mutex_lock(&priv->shrd->mutex); + mutex_lock(&priv->mutex); /* * We can not send command to firmware while scanning. When the scan @@ -594,7 +594,7 @@ static void iwlagn_bt_traffic_change_work(struct work_struct *work) */ iwlagn_bt_coex_rssi_monitor(priv); out: - mutex_unlock(&priv->shrd->mutex); + mutex_unlock(&priv->mutex); } /* @@ -969,7 +969,7 @@ static void iwlagn_wowlan_program_keys(struct ieee80211_hw *hw, u16 p1k[IWLAGN_P1K_SIZE]; int ret, i; - mutex_lock(&priv->shrd->mutex); + mutex_lock(&priv->mutex); if ((key->cipher == WLAN_CIPHER_SUITE_WEP40 || key->cipher == WLAN_CIPHER_SUITE_WEP104) && @@ -1075,7 +1075,7 @@ static void iwlagn_wowlan_program_keys(struct ieee80211_hw *hw, break; } - mutex_unlock(&priv->shrd->mutex); + mutex_unlock(&priv->mutex); } int iwlagn_send_patterns(struct iwl_priv *priv, @@ -1222,11 +1222,11 @@ int iwlagn_suspend(struct iwl_priv *priv, * constraints. Since we're in the suspend path * that isn't really a problem though. */ - mutex_unlock(&priv->shrd->mutex); + mutex_unlock(&priv->mutex); ieee80211_iter_keys(priv->hw, ctx->vif, iwlagn_wowlan_program_keys, &key_data); - mutex_lock(&priv->shrd->mutex); + mutex_lock(&priv->mutex); if (key_data.error) { ret = -EIO; goto out; @@ -1304,7 +1304,7 @@ int iwl_dvm_send_cmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) * (or more) synchronous commands at a time. */ if (cmd->flags & CMD_SYNC) - lockdep_assert_held(&priv->shrd->mutex); + lockdep_assert_held(&priv->mutex); return iwl_trans_send_cmd(trans(priv), cmd); } diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c index 53114db9c9c3..2c5e7ec697e9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c @@ -131,7 +131,7 @@ static void iwlagn_update_qos(struct iwl_priv *priv, static int iwlagn_update_beacon(struct iwl_priv *priv, struct ieee80211_vif *vif) { - lockdep_assert_held(&priv->shrd->mutex); + lockdep_assert_held(&priv->mutex); dev_kfree_skb(priv->beacon_skb); priv->beacon_skb = ieee80211_beacon_get(priv->hw, vif); @@ -313,7 +313,7 @@ int iwlagn_set_pan_params(struct iwl_priv *priv) BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2); - lockdep_assert_held(&priv->shrd->mutex); + lockdep_assert_held(&priv->mutex); ctx_bss = &priv->contexts[IWL_RXON_CTX_BSS]; ctx_pan = &priv->contexts[IWL_RXON_CTX_PAN]; @@ -418,7 +418,7 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) bool new_assoc = !!(ctx->staging.filter_flags & RXON_FILTER_ASSOC_MSK); int ret; - lockdep_assert_held(&priv->shrd->mutex); + lockdep_assert_held(&priv->mutex); if (!iwl_is_alive(priv->shrd)) return -EBUSY; @@ -549,7 +549,7 @@ int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed) IWL_DEBUG_MAC80211(priv, "enter: changed %#x", changed); - mutex_lock(&priv->shrd->mutex); + mutex_lock(&priv->mutex); if (unlikely(test_bit(STATUS_SCANNING, &priv->shrd->status))) { IWL_DEBUG_MAC80211(priv, "leave - scanning\n"); @@ -650,7 +650,7 @@ int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed) iwlagn_commit_rxon(priv, ctx); } out: - mutex_unlock(&priv->shrd->mutex); + mutex_unlock(&priv->mutex); IWL_DEBUG_MAC80211(priv, "leave\n"); return ret; @@ -667,7 +667,7 @@ static void iwlagn_check_needed_chains(struct iwl_priv *priv, struct ieee80211_sta_ht_cap *ht_cap; bool need_multiple; - lockdep_assert_held(&priv->shrd->mutex); + lockdep_assert_held(&priv->mutex); switch (vif->type) { case NL80211_IFTYPE_STATION: @@ -792,17 +792,17 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw, int ret; bool force = false; - mutex_lock(&priv->shrd->mutex); + mutex_lock(&priv->mutex); if (unlikely(!iwl_is_ready(priv->shrd))) { IWL_DEBUG_MAC80211(priv, "leave - not ready\n"); - mutex_unlock(&priv->shrd->mutex); + mutex_unlock(&priv->mutex); return; } if (unlikely(!ctx->vif)) { IWL_DEBUG_MAC80211(priv, "leave - vif is NULL\n"); - mutex_unlock(&priv->shrd->mutex); + mutex_unlock(&priv->mutex); return; } @@ -931,7 +931,7 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw, IWL_ERR(priv, "Error sending IBSS beacon\n"); } - mutex_unlock(&priv->shrd->mutex); + mutex_unlock(&priv->mutex); } void iwlagn_post_scan(struct iwl_priv *priv) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c index 73a25f48cd53..14fbdecccd26 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c @@ -811,7 +811,7 @@ void iwl_sta_fill_lq(struct iwl_priv *priv, struct iwl_rxon_context *ctx, u32 rate_flags = 0; __le32 rate_n_flags; - lockdep_assert_held(&priv->shrd->mutex); + lockdep_assert_held(&priv->mutex); memset(link_cmd, 0, sizeof(*link_cmd)); @@ -978,7 +978,7 @@ static int iwl_send_static_wepkey_cmd(struct iwl_priv *priv, int iwl_restore_default_wep_keys(struct iwl_priv *priv, struct iwl_rxon_context *ctx) { - lockdep_assert_held(&priv->shrd->mutex); + lockdep_assert_held(&priv->mutex); return iwl_send_static_wepkey_cmd(priv, ctx, false); } @@ -989,7 +989,7 @@ int iwl_remove_default_wep_key(struct iwl_priv *priv, { int ret; - lockdep_assert_held(&priv->shrd->mutex); + lockdep_assert_held(&priv->mutex); IWL_DEBUG_WEP(priv, "Removing default WEP key: idx=%d\n", keyconf->keyidx); @@ -1014,7 +1014,7 @@ int iwl_set_default_wep_key(struct iwl_priv *priv, { int ret; - lockdep_assert_held(&priv->shrd->mutex); + lockdep_assert_held(&priv->mutex); if (keyconf->keylen != WEP_KEY_LEN_128 && keyconf->keylen != WEP_KEY_LEN_64) { @@ -1166,7 +1166,7 @@ int iwl_remove_dynamic_key(struct iwl_priv *priv, if (sta_id == IWL_INVALID_STATION) return 0; - lockdep_assert_held(&priv->shrd->mutex); + lockdep_assert_held(&priv->mutex); ctx->key_mapping_keys--; @@ -1206,7 +1206,7 @@ int iwl_set_dynamic_key(struct iwl_priv *priv, if (sta_id == IWL_INVALID_STATION) return -EINVAL; - lockdep_assert_held(&priv->shrd->mutex); + lockdep_assert_held(&priv->mutex); keyconf->hw_key_idx = iwl_get_free_ucode_key_offset(priv); if (keyconf->hw_key_idx == WEP_INVALID_OFFSET) @@ -1340,7 +1340,7 @@ int iwl_sta_tx_modify_enable_tid(struct iwl_priv *priv, int sta_id, int tid) { struct iwl_addsta_cmd sta_cmd; - lockdep_assert_held(&priv->shrd->mutex); + lockdep_assert_held(&priv->mutex); /* Remove "disable" flag, to enable Tx for this TID */ spin_lock_bh(&priv->sta_lock); @@ -1359,7 +1359,7 @@ int iwl_sta_rx_agg_start(struct iwl_priv *priv, struct ieee80211_sta *sta, int sta_id; struct iwl_addsta_cmd sta_cmd; - lockdep_assert_held(&priv->shrd->mutex); + lockdep_assert_held(&priv->mutex); sta_id = iwl_sta_id(sta); if (sta_id == IWL_INVALID_STATION) @@ -1383,7 +1383,7 @@ int iwl_sta_rx_agg_stop(struct iwl_priv *priv, struct ieee80211_sta *sta, int sta_id; struct iwl_addsta_cmd sta_cmd; - lockdep_assert_held(&priv->shrd->mutex); + lockdep_assert_held(&priv->mutex); sta_id = iwl_sta_id(sta); if (sta_id == IWL_INVALID_STATION) { diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tt.c b/drivers/net/wireless/iwlwifi/iwl-agn-tt.c index 56d7c0e38163..85fe590ee721 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tt.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tt.c @@ -310,7 +310,7 @@ static void iwl_legacy_tt_handler(struct iwl_priv *priv, s32 temp, bool force) tt->tt_power_mode = IWL_POWER_INDEX_5; break; } - mutex_lock(&priv->shrd->mutex); + mutex_lock(&priv->mutex); if (old_state == IWL_TI_CT_KILL) clear_bit(STATUS_CT_KILL, &priv->shrd->status); if (tt->state != IWL_TI_CT_KILL && @@ -341,7 +341,7 @@ static void iwl_legacy_tt_handler(struct iwl_priv *priv, s32 temp, bool force) IWL_DEBUG_TEMP(priv, "Power Index change to %u\n", tt->tt_power_mode); } - mutex_unlock(&priv->shrd->mutex); + mutex_unlock(&priv->mutex); } } @@ -451,7 +451,7 @@ static void iwl_advance_tt_handler(struct iwl_priv *priv, s32 temp, bool force) * in case get disabled before */ iwl_set_rxon_ht(priv, &priv->current_ht_config); } - mutex_lock(&priv->shrd->mutex); + mutex_lock(&priv->mutex); if (old_state == IWL_TI_CT_KILL) clear_bit(STATUS_CT_KILL, &priv->shrd->status); if (tt->state != IWL_TI_CT_KILL && @@ -486,7 +486,7 @@ static void iwl_advance_tt_handler(struct iwl_priv *priv, s32 temp, bool force) iwl_perform_ct_kill_task(priv, false); } } - mutex_unlock(&priv->shrd->mutex); + mutex_unlock(&priv->mutex); } } diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 3f59a773b3e0..863c27e20dbc 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -132,7 +132,7 @@ int iwlagn_send_beacon_cmd(struct iwl_priv *priv) * beacon contents. */ - lockdep_assert_held(&priv->shrd->mutex); + lockdep_assert_held(&priv->mutex); if (!priv->beacon_ctx) { IWL_ERR(priv, "trying to build beacon w/o beacon context!\n"); @@ -206,7 +206,7 @@ static void iwl_bg_beacon_update(struct work_struct *work) container_of(work, struct iwl_priv, beacon_update); struct sk_buff *beacon; - mutex_lock(&priv->shrd->mutex); + mutex_lock(&priv->mutex); if (!priv->beacon_ctx) { IWL_ERR(priv, "updating beacon w/o beacon context!\n"); goto out; @@ -236,7 +236,7 @@ static void iwl_bg_beacon_update(struct work_struct *work) iwlagn_send_beacon_cmd(priv); out: - mutex_unlock(&priv->shrd->mutex); + mutex_unlock(&priv->mutex); } static void iwl_bg_bt_runtime_config(struct work_struct *work) @@ -259,7 +259,7 @@ static void iwl_bg_bt_full_concurrency(struct work_struct *work) container_of(work, struct iwl_priv, bt_full_concurrency); struct iwl_rxon_context *ctx; - mutex_lock(&priv->shrd->mutex); + mutex_lock(&priv->mutex); if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) goto out; @@ -283,7 +283,7 @@ static void iwl_bg_bt_full_concurrency(struct work_struct *work) iwlagn_send_advance_bt_config(priv); out: - mutex_unlock(&priv->shrd->mutex); + mutex_unlock(&priv->mutex); } /** @@ -774,7 +774,7 @@ void iwl_down(struct iwl_priv *priv) IWL_DEBUG_INFO(priv, DRV_NAME " is going down\n"); - lockdep_assert_held(&priv->shrd->mutex); + lockdep_assert_held(&priv->mutex); iwl_scan_cancel_timeout(priv, 200); @@ -844,11 +844,11 @@ static void iwl_bg_run_time_calib_work(struct work_struct *work) struct iwl_priv *priv = container_of(work, struct iwl_priv, run_time_calib_work); - mutex_lock(&priv->shrd->mutex); + mutex_lock(&priv->mutex); if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status) || test_bit(STATUS_SCANNING, &priv->shrd->status)) { - mutex_unlock(&priv->shrd->mutex); + mutex_unlock(&priv->mutex); return; } @@ -857,7 +857,7 @@ static void iwl_bg_run_time_calib_work(struct work_struct *work) iwl_sensitivity_calibration(priv); } - mutex_unlock(&priv->shrd->mutex); + mutex_unlock(&priv->mutex); } void iwlagn_prepare_restart(struct iwl_priv *priv) @@ -869,7 +869,7 @@ void iwlagn_prepare_restart(struct iwl_priv *priv) u8 bt_status; bool bt_is_sco; - lockdep_assert_held(&priv->shrd->mutex); + lockdep_assert_held(&priv->mutex); for_each_context(priv, ctx) ctx->vif = NULL; @@ -907,9 +907,9 @@ static void iwl_bg_restart(struct work_struct *data) return; if (test_and_clear_bit(STATUS_FW_ERROR, &priv->shrd->status)) { - mutex_lock(&priv->shrd->mutex); + mutex_lock(&priv->mutex); iwlagn_prepare_restart(priv); - mutex_unlock(&priv->shrd->mutex); + mutex_unlock(&priv->mutex); iwl_cancel_deferred_work(priv); ieee80211_restart_hw(priv->hw); } else { @@ -924,7 +924,7 @@ void iwlagn_disable_roc(struct iwl_priv *priv) { struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_PAN]; - lockdep_assert_held(&priv->shrd->mutex); + lockdep_assert_held(&priv->mutex); if (!priv->hw_roc_setup) return; @@ -947,9 +947,9 @@ static void iwlagn_disable_roc_work(struct work_struct *work) struct iwl_priv *priv = container_of(work, struct iwl_priv, hw_roc_disable_work.work); - mutex_lock(&priv->shrd->mutex); + mutex_lock(&priv->mutex); iwlagn_disable_roc(priv); - mutex_unlock(&priv->shrd->mutex); + mutex_unlock(&priv->mutex); } /***************************************************************************** @@ -1036,7 +1036,7 @@ static int iwl_init_drv(struct iwl_priv *priv) spin_lock_init(&priv->sta_lock); - mutex_init(&priv->shrd->mutex); + mutex_init(&priv->mutex); INIT_LIST_HEAD(&priv->calib_results); diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index aaea51ee4185..387eeeedb41d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -316,7 +316,7 @@ int iwl_send_rxon_timing(struct iwl_priv *priv, struct iwl_rxon_context *ctx) conf = &priv->hw->conf; - lockdep_assert_held(&priv->shrd->mutex); + lockdep_assert_held(&priv->mutex); memset(&ctx->timing, 0, sizeof(struct iwl_rxon_time_cmd)); @@ -892,7 +892,7 @@ int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force) bool defer; struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; - lockdep_assert_held(&priv->shrd->mutex); + lockdep_assert_held(&priv->mutex); if (priv->tx_power_user_lmt == tx_power && !force) return 0; diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index bc3e267ed4c0..b9b6d628f59a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c @@ -761,9 +761,9 @@ static ssize_t iwl_dbgfs_sleep_level_override_write(struct file *file, priv->power_data.debug_sleep_level_override = value; - mutex_lock(&priv->shrd->mutex); + mutex_lock(&priv->mutex); iwl_power_update_mode(priv, true); - mutex_unlock(&priv->shrd->mutex); + mutex_unlock(&priv->mutex); return count; } @@ -1708,9 +1708,9 @@ static ssize_t iwl_dbgfs_ucode_bt_stats_read(struct file *file, return -EINVAL; /* make request to uCode to retrieve statistics information */ - mutex_lock(&priv->shrd->mutex); + mutex_lock(&priv->mutex); ret = iwl_send_statistics_request(priv, CMD_SYNC, false); - mutex_unlock(&priv->shrd->mutex); + mutex_unlock(&priv->mutex); if (ret) { IWL_ERR(priv, @@ -2106,9 +2106,9 @@ static ssize_t iwl_dbgfs_clear_ucode_statistics_write(struct file *file, return -EFAULT; /* make request to uCode to retrieve statistics information */ - mutex_lock(&priv->shrd->mutex); + mutex_lock(&priv->mutex); iwl_send_statistics_request(priv, CMD_SYNC, true); - mutex_unlock(&priv->shrd->mutex); + mutex_unlock(&priv->mutex); return count; } diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 4def9f961891..73acbab6c248 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -36,6 +36,7 @@ #include #include #include +#include #include #include "iwl-eeprom.h" @@ -718,6 +719,7 @@ struct iwl_priv { const struct iwl_fw *fw; spinlock_t sta_lock; + struct mutex mutex; /* ieee device used by generic ieee processing code */ struct ieee80211_hw *hw; diff --git a/drivers/net/wireless/iwlwifi/iwl-mac80211.c b/drivers/net/wireless/iwlwifi/iwl-mac80211.c index 3c9a8faba4e6..30861765b512 100644 --- a/drivers/net/wireless/iwlwifi/iwl-mac80211.c +++ b/drivers/net/wireless/iwlwifi/iwl-mac80211.c @@ -261,7 +261,7 @@ static int __iwl_up(struct iwl_priv *priv) struct iwl_rxon_context *ctx; int ret; - lockdep_assert_held(&priv->shrd->mutex); + lockdep_assert_held(&priv->mutex); if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) { IWL_WARN(priv, "Exit pending; will not bring the NIC up\n"); @@ -310,9 +310,9 @@ static int iwlagn_mac_start(struct ieee80211_hw *hw) IWL_DEBUG_MAC80211(priv, "enter\n"); /* we should be verifying the device is ready to be opened */ - mutex_lock(&priv->shrd->mutex); + mutex_lock(&priv->mutex); ret = __iwl_up(priv); - mutex_unlock(&priv->shrd->mutex); + mutex_unlock(&priv->mutex); if (ret) return ret; @@ -340,9 +340,9 @@ static void iwlagn_mac_stop(struct ieee80211_hw *hw) priv->is_open = 0; - mutex_lock(&priv->shrd->mutex); + mutex_lock(&priv->mutex); iwl_down(priv); - mutex_unlock(&priv->shrd->mutex); + mutex_unlock(&priv->mutex); iwl_cancel_deferred_work(priv); @@ -367,7 +367,7 @@ static void iwlagn_mac_set_rekey_data(struct ieee80211_hw *hw, return; IWL_DEBUG_MAC80211(priv, "enter\n"); - mutex_lock(&priv->shrd->mutex); + mutex_lock(&priv->mutex); if (priv->contexts[IWL_RXON_CTX_BSS].vif != vif) goto out; @@ -379,7 +379,7 @@ static void iwlagn_mac_set_rekey_data(struct ieee80211_hw *hw, priv->have_rekey_data = true; out: - mutex_unlock(&priv->shrd->mutex); + mutex_unlock(&priv->mutex); IWL_DEBUG_MAC80211(priv, "leave\n"); } @@ -396,7 +396,7 @@ static int iwlagn_mac_suspend(struct ieee80211_hw *hw, return -EINVAL; IWL_DEBUG_MAC80211(priv, "enter\n"); - mutex_lock(&priv->shrd->mutex); + mutex_lock(&priv->mutex); /* Don't attempt WoWLAN when not associated, tear down instead. */ if (!ctx->vif || ctx->vif->type != NL80211_IFTYPE_STATION || @@ -420,7 +420,7 @@ static int iwlagn_mac_suspend(struct ieee80211_hw *hw, iwlagn_prepare_restart(priv); ieee80211_restart_hw(priv->hw); out: - mutex_unlock(&priv->shrd->mutex); + mutex_unlock(&priv->mutex); IWL_DEBUG_MAC80211(priv, "leave\n"); return ret; @@ -436,7 +436,7 @@ static int iwlagn_mac_resume(struct ieee80211_hw *hw) int ret = -EIO; IWL_DEBUG_MAC80211(priv, "enter\n"); - mutex_lock(&priv->shrd->mutex); + mutex_lock(&priv->mutex); iwl_write32(trans(priv), CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_DRV_GP1_BIT_D3_CFG_COMPLETE); @@ -481,7 +481,7 @@ static int iwlagn_mac_resume(struct ieee80211_hw *hw) iwl_connection_init_rx_config(priv, ctx); iwlagn_set_rxon_chain(priv, ctx); - mutex_unlock(&priv->shrd->mutex); + mutex_unlock(&priv->mutex); IWL_DEBUG_MAC80211(priv, "leave\n"); ieee80211_resume_disconnect(vif); @@ -559,7 +559,7 @@ static int iwlagn_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, if (cmd == DISABLE_KEY && key->hw_key_idx == WEP_INVALID_OFFSET) return 0; - mutex_lock(&priv->shrd->mutex); + mutex_lock(&priv->mutex); iwl_scan_cancel_timeout(priv, 100); BUILD_BUG_ON(WEP_INVALID_OFFSET == IWLAGN_HW_KEY_DEFAULT); @@ -610,7 +610,7 @@ static int iwlagn_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, ret = -EINVAL; } - mutex_unlock(&priv->shrd->mutex); + mutex_unlock(&priv->mutex); IWL_DEBUG_MAC80211(priv, "leave\n"); return ret; @@ -633,7 +633,7 @@ static int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw, return -EACCES; IWL_DEBUG_MAC80211(priv, "enter\n"); - mutex_lock(&priv->shrd->mutex); + mutex_lock(&priv->mutex); switch (action) { case IEEE80211_AMPDU_RX_START: @@ -675,7 +675,7 @@ static int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw, ret = iwlagn_tx_agg_oper(priv, vif, sta, tid, buf_size); break; } - mutex_unlock(&priv->shrd->mutex); + mutex_unlock(&priv->mutex); IWL_DEBUG_MAC80211(priv, "leave\n"); return ret; } @@ -746,7 +746,7 @@ static int iwlagn_mac_sta_state(struct ieee80211_hw *hw, IWL_DEBUG_MAC80211(priv, "station %pM state change %d->%d\n", sta->addr, old_state, new_state); - mutex_lock(&priv->shrd->mutex); + mutex_lock(&priv->mutex); if (vif->type == NL80211_IFTYPE_STATION) { if (old_state == IEEE80211_STA_NOTEXIST && new_state == IEEE80211_STA_NONE) @@ -807,7 +807,7 @@ static int iwlagn_mac_sta_state(struct ieee80211_hw *hw, if (iwl_is_rfkill(priv->shrd)) ret = 0; - mutex_unlock(&priv->shrd->mutex); + mutex_unlock(&priv->mutex); IWL_DEBUG_MAC80211(priv, "leave\n"); return ret; @@ -834,7 +834,7 @@ static void iwlagn_mac_channel_switch(struct ieee80211_hw *hw, IWL_DEBUG_MAC80211(priv, "enter\n"); - mutex_lock(&priv->shrd->mutex); + mutex_lock(&priv->mutex); if (iwl_is_rfkill(priv->shrd)) goto out; @@ -890,7 +890,7 @@ static void iwlagn_mac_channel_switch(struct ieee80211_hw *hw, } out: - mutex_unlock(&priv->shrd->mutex); + mutex_unlock(&priv->mutex); IWL_DEBUG_MAC80211(priv, "leave\n"); } @@ -920,7 +920,7 @@ static void iwlagn_configure_filter(struct ieee80211_hw *hw, #undef CHK - mutex_lock(&priv->shrd->mutex); + mutex_lock(&priv->mutex); for_each_context(priv, ctx) { ctx->staging.filter_flags &= ~filter_nand; @@ -932,7 +932,7 @@ static void iwlagn_configure_filter(struct ieee80211_hw *hw, */ } - mutex_unlock(&priv->shrd->mutex); + mutex_unlock(&priv->mutex); /* * Receiving all multicast frames is always enabled by the @@ -948,7 +948,7 @@ static void iwlagn_mac_flush(struct ieee80211_hw *hw, bool drop) { struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); - mutex_lock(&priv->shrd->mutex); + mutex_lock(&priv->mutex); IWL_DEBUG_MAC80211(priv, "enter\n"); if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) { @@ -974,7 +974,7 @@ static void iwlagn_mac_flush(struct ieee80211_hw *hw, bool drop) IWL_DEBUG_MAC80211(priv, "wait transmit/flush all frames\n"); iwl_trans_wait_tx_queue_empty(trans(priv)); done: - mutex_unlock(&priv->shrd->mutex); + mutex_unlock(&priv->mutex); IWL_DEBUG_MAC80211(priv, "leave\n"); } @@ -994,7 +994,7 @@ static int iwlagn_mac_remain_on_channel(struct ieee80211_hw *hw, return -EOPNOTSUPP; IWL_DEBUG_MAC80211(priv, "enter\n"); - mutex_lock(&priv->shrd->mutex); + mutex_lock(&priv->mutex); if (test_bit(STATUS_SCAN_HW, &priv->shrd->status)) { err = -EBUSY; @@ -1065,7 +1065,7 @@ static int iwlagn_mac_remain_on_channel(struct ieee80211_hw *hw, iwlagn_disable_roc(priv); out: - mutex_unlock(&priv->shrd->mutex); + mutex_unlock(&priv->mutex); IWL_DEBUG_MAC80211(priv, "leave\n"); return err; @@ -1079,10 +1079,10 @@ static int iwlagn_mac_cancel_remain_on_channel(struct ieee80211_hw *hw) return -EOPNOTSUPP; IWL_DEBUG_MAC80211(priv, "enter\n"); - mutex_lock(&priv->shrd->mutex); + mutex_lock(&priv->mutex); iwl_scan_cancel_timeout(priv, priv->hw_roc_duration); iwlagn_disable_roc(priv); - mutex_unlock(&priv->shrd->mutex); + mutex_unlock(&priv->mutex); IWL_DEBUG_MAC80211(priv, "leave\n"); return 0; @@ -1094,7 +1094,7 @@ static void iwlagn_mac_rssi_callback(struct ieee80211_hw *hw, struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); IWL_DEBUG_MAC80211(priv, "enter\n"); - mutex_lock(&priv->shrd->mutex); + mutex_lock(&priv->mutex); if (cfg(priv)->bt_params && cfg(priv)->bt_params->advanced_bt_coexist) { @@ -1109,7 +1109,7 @@ static void iwlagn_mac_rssi_callback(struct ieee80211_hw *hw, "ignoring RSSI callback\n"); } - mutex_unlock(&priv->shrd->mutex); + mutex_unlock(&priv->mutex); IWL_DEBUG_MAC80211(priv, "leave\n"); } @@ -1149,7 +1149,7 @@ static int iwlagn_mac_conf_tx(struct ieee80211_hw *hw, q = AC_NUM - 1 - queue; - mutex_lock(&priv->shrd->mutex); + mutex_lock(&priv->mutex); ctx->qos_data.def_qos_parm.ac[q].cw_min = cpu_to_le16(params->cw_min); @@ -1161,7 +1161,7 @@ static int iwlagn_mac_conf_tx(struct ieee80211_hw *hw, ctx->qos_data.def_qos_parm.ac[q].reserved1 = 0; - mutex_unlock(&priv->shrd->mutex); + mutex_unlock(&priv->mutex); IWL_DEBUG_MAC80211(priv, "leave\n"); return 0; @@ -1189,7 +1189,7 @@ static int iwl_setup_interface(struct iwl_priv *priv, struct ieee80211_vif *vif = ctx->vif; int err; - lockdep_assert_held(&priv->shrd->mutex); + lockdep_assert_held(&priv->mutex); /* * This variable will be correct only when there's just @@ -1234,7 +1234,7 @@ static int iwlagn_mac_add_interface(struct ieee80211_hw *hw, cancel_delayed_work_sync(&priv->hw_roc_disable_work); - mutex_lock(&priv->shrd->mutex); + mutex_lock(&priv->mutex); iwlagn_disable_roc(priv); @@ -1281,7 +1281,7 @@ static int iwlagn_mac_add_interface(struct ieee80211_hw *hw, ctx->vif = NULL; priv->iw_mode = NL80211_IFTYPE_STATION; out: - mutex_unlock(&priv->shrd->mutex); + mutex_unlock(&priv->mutex); IWL_DEBUG_MAC80211(priv, "leave\n"); return err; @@ -1293,7 +1293,7 @@ static void iwl_teardown_interface(struct iwl_priv *priv, { struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif); - lockdep_assert_held(&priv->shrd->mutex); + lockdep_assert_held(&priv->mutex); if (priv->scan_vif == vif) { iwl_scan_cancel_timeout(priv, 200); @@ -1325,7 +1325,7 @@ static void iwlagn_mac_remove_interface(struct ieee80211_hw *hw, IWL_DEBUG_MAC80211(priv, "enter\n"); - mutex_lock(&priv->shrd->mutex); + mutex_lock(&priv->mutex); if (WARN_ON(ctx->vif != vif)) { struct iwl_rxon_context *tmp; @@ -1338,7 +1338,7 @@ static void iwlagn_mac_remove_interface(struct ieee80211_hw *hw, iwl_teardown_interface(priv, vif, false); - mutex_unlock(&priv->shrd->mutex); + mutex_unlock(&priv->mutex); IWL_DEBUG_MAC80211(priv, "leave\n"); @@ -1360,7 +1360,7 @@ static int iwlagn_mac_change_interface(struct ieee80211_hw *hw, newtype = ieee80211_iftype_p2p(newtype, newp2p); - mutex_lock(&priv->shrd->mutex); + mutex_lock(&priv->mutex); if (!ctx->vif || !iwl_is_ready_rf(priv->shrd)) { /* @@ -1424,7 +1424,7 @@ static int iwlagn_mac_change_interface(struct ieee80211_hw *hw, err = 0; out: - mutex_unlock(&priv->shrd->mutex); + mutex_unlock(&priv->mutex); IWL_DEBUG_MAC80211(priv, "leave\n"); return err; @@ -1442,7 +1442,7 @@ static int iwlagn_mac_hw_scan(struct ieee80211_hw *hw, if (req->n_channels == 0) return -EINVAL; - mutex_lock(&priv->shrd->mutex); + mutex_lock(&priv->mutex); /* * If an internal scan is in progress, just set @@ -1471,7 +1471,7 @@ static int iwlagn_mac_hw_scan(struct ieee80211_hw *hw, IWL_DEBUG_MAC80211(priv, "leave\n"); - mutex_unlock(&priv->shrd->mutex); + mutex_unlock(&priv->mutex); return ret; } diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c index 46ca82062c2e..d76ff239d5f1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-power.c +++ b/drivers/net/wireless/iwlwifi/iwl-power.c @@ -383,7 +383,7 @@ int iwl_power_set_mode(struct iwl_priv *priv, struct iwl_powertable_cmd *cmd, int ret; bool update_chains; - lockdep_assert_held(&priv->shrd->mutex); + lockdep_assert_held(&priv->mutex); /* Don't update the RX chain when chain noise calibration is running */ update_chains = priv->chain_noise_data.state == IWL_CHAIN_NOISE_DONE || diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index dcba74883307..6cf2cb318882 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c @@ -115,7 +115,7 @@ static void iwl_process_scan_complete(struct iwl_priv *priv) { bool aborted; - lockdep_assert_held(&priv->shrd->mutex); + lockdep_assert_held(&priv->mutex); if (!test_and_clear_bit(STATUS_SCAN_COMPLETE, &priv->shrd->status)) return; @@ -172,7 +172,7 @@ out_settings: void iwl_force_scan_end(struct iwl_priv *priv) { - lockdep_assert_held(&priv->shrd->mutex); + lockdep_assert_held(&priv->mutex); if (!test_bit(STATUS_SCANNING, &priv->shrd->status)) { IWL_DEBUG_SCAN(priv, "Forcing scan end while not scanning\n"); @@ -191,7 +191,7 @@ static void iwl_do_scan_abort(struct iwl_priv *priv) { int ret; - lockdep_assert_held(&priv->shrd->mutex); + lockdep_assert_held(&priv->mutex); if (!test_bit(STATUS_SCANNING, &priv->shrd->status)) { IWL_DEBUG_SCAN(priv, "Not performing scan to abort\n"); @@ -230,7 +230,7 @@ void iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms) { unsigned long timeout = jiffies + msecs_to_jiffies(ms); - lockdep_assert_held(&priv->shrd->mutex); + lockdep_assert_held(&priv->mutex); IWL_DEBUG_SCAN(priv, "Scan cancel timeout\n"); @@ -595,7 +595,7 @@ static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) u8 scan_tx_antennas = hw_params(priv).valid_tx_ant; int ret; - lockdep_assert_held(&priv->shrd->mutex); + lockdep_assert_held(&priv->mutex); if (vif) ctx = iwl_rxon_ctx_from_vif(vif); @@ -912,7 +912,7 @@ int __must_check iwl_scan_initiate(struct iwl_priv *priv, { int ret; - lockdep_assert_held(&priv->shrd->mutex); + lockdep_assert_held(&priv->mutex); cancel_delayed_work(&priv->scan_check); @@ -972,7 +972,7 @@ static void iwl_bg_start_internal_scan(struct work_struct *work) IWL_DEBUG_SCAN(priv, "Start internal scan\n"); - mutex_lock(&priv->shrd->mutex); + mutex_lock(&priv->mutex); if (priv->scan_type == IWL_SCAN_RADIO_RESET) { IWL_DEBUG_SCAN(priv, "Internal scan already in progress\n"); @@ -987,7 +987,7 @@ static void iwl_bg_start_internal_scan(struct work_struct *work) if (iwl_scan_initiate(priv, NULL, IWL_SCAN_RADIO_RESET, priv->band)) IWL_DEBUG_SCAN(priv, "failed to start internal short scan\n"); unlock: - mutex_unlock(&priv->shrd->mutex); + mutex_unlock(&priv->mutex); } static void iwl_bg_scan_check(struct work_struct *data) @@ -1000,9 +1000,9 @@ static void iwl_bg_scan_check(struct work_struct *data) /* Since we are here firmware does not finish scan and * most likely is in bad shape, so we don't bother to * send abort command, just force scan complete to mac80211 */ - mutex_lock(&priv->shrd->mutex); + mutex_lock(&priv->mutex); iwl_force_scan_end(priv); - mutex_unlock(&priv->shrd->mutex); + mutex_unlock(&priv->mutex); } /** @@ -1060,9 +1060,9 @@ static void iwl_bg_abort_scan(struct work_struct *work) /* We keep scan_check work queued in case when firmware will not * report back scan completed notification */ - mutex_lock(&priv->shrd->mutex); + mutex_lock(&priv->mutex); iwl_scan_cancel_timeout(priv, 200); - mutex_unlock(&priv->shrd->mutex); + mutex_unlock(&priv->mutex); } static void iwl_bg_scan_completed(struct work_struct *work) @@ -1070,9 +1070,9 @@ static void iwl_bg_scan_completed(struct work_struct *work) struct iwl_priv *priv = container_of(work, struct iwl_priv, scan_completed); - mutex_lock(&priv->shrd->mutex); + mutex_lock(&priv->mutex); iwl_process_scan_complete(priv); - mutex_unlock(&priv->shrd->mutex); + mutex_unlock(&priv->mutex); } void iwl_setup_scan_deferred_work(struct iwl_priv *priv) @@ -1090,8 +1090,8 @@ void iwl_cancel_scan_deferred_work(struct iwl_priv *priv) cancel_work_sync(&priv->scan_completed); if (cancel_delayed_work_sync(&priv->scan_check)) { - mutex_lock(&priv->shrd->mutex); + mutex_lock(&priv->mutex); iwl_force_scan_end(priv); - mutex_unlock(&priv->shrd->mutex); + mutex_unlock(&priv->mutex); } } diff --git a/drivers/net/wireless/iwlwifi/iwl-shared.h b/drivers/net/wireless/iwlwifi/iwl-shared.h index bb34766609db..30b942f77814 100644 --- a/drivers/net/wireless/iwlwifi/iwl-shared.h +++ b/drivers/net/wireless/iwlwifi/iwl-shared.h @@ -65,7 +65,6 @@ #include #include -#include #include #include @@ -399,7 +398,6 @@ struct iwl_cfg { * @nic: pointer to the nic data * @hw_params: see struct iwl_hw_params * @lock: protect general shared data - * @mutex: * @wait_command_queue: the wait_queue for SYNC host command nad uCode load * @eeprom: pointer to the eeprom/OTP image * @ucode_type: indicator of loaded ucode image @@ -423,8 +421,6 @@ struct iwl_shared { struct iwl_hw_params hw_params; const struct iwl_fw *fw; - struct mutex mutex; - wait_queue_head_t wait_command_queue; /* eeprom -- this is in the card's little endian byte order */ diff --git a/drivers/net/wireless/iwlwifi/iwl-testmode.c b/drivers/net/wireless/iwlwifi/iwl-testmode.c index f26765b3a661..095d71dc99c4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-testmode.c +++ b/drivers/net/wireless/iwlwifi/iwl-testmode.c @@ -975,7 +975,7 @@ int iwlagn_mac_testmode_cmd(struct ieee80211_hw *hw, void *data, int len) return -ENOMSG; } /* in case multiple accesses to the device happens */ - mutex_lock(&priv->shrd->mutex); + mutex_lock(&priv->mutex); switch (nla_get_u32(tb[IWL_TM_ATTR_COMMAND])) { case IWL_TM_CMD_APP2DEV_UCODE: @@ -1027,7 +1027,7 @@ int iwlagn_mac_testmode_cmd(struct ieee80211_hw *hw, void *data, int len) break; } - mutex_unlock(&priv->shrd->mutex); + mutex_unlock(&priv->mutex); return result; } @@ -1062,7 +1062,7 @@ int iwlagn_mac_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *skb, } /* in case multiple accesses to the device happens */ - mutex_lock(&priv->shrd->mutex); + mutex_lock(&priv->mutex); switch (cmd) { case IWL_TM_CMD_APP2DEV_READ_TRACE: IWL_DEBUG_INFO(priv, "uCode trace cmd to driver\n"); @@ -1077,6 +1077,6 @@ int iwlagn_mac_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *skb, break; } - mutex_unlock(&priv->shrd->mutex); + mutex_unlock(&priv->mutex); return result; } diff --git a/drivers/net/wireless/iwlwifi/iwl-ucode.c b/drivers/net/wireless/iwlwifi/iwl-ucode.c index 1cbe8e9926f1..c1c5e1f2223a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-ucode.c +++ b/drivers/net/wireless/iwlwifi/iwl-ucode.c @@ -599,7 +599,7 @@ int iwl_run_init_ucode(struct iwl_priv *priv) struct iwl_notification_wait calib_wait; int ret; - lockdep_assert_held(&priv->shrd->mutex); + lockdep_assert_held(&priv->mutex); /* No init ucode required? Curious, but maybe ok */ if (!priv->fw->ucode_init.code.len) -- cgit From c9eec95cb429359efd39a3c87fb1544fe2b77bc5 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 6 Mar 2012 13:30:43 -0800 Subject: iwlwifi: move rfkill status handling out of transport The transport layer should only check the hardware RF kill status, not impose any policy or reaction based on it, so move that out of it into the op_mode. For now keep the restriction on loading firmware, that will have to be removed later. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-core.c | 5 +++ drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c | 24 +++------------ drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | 39 ++++++++---------------- 3 files changed, 22 insertions(+), 46 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 387eeeedb41d..a2ef78c6af60 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -1460,6 +1460,11 @@ void iwl_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state) { struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); + if (state) + set_bit(STATUS_RF_KILL_HW, &priv->shrd->status); + else + clear_bit(STATUS_RF_KILL_HW, &priv->shrd->status); + wiphy_rfkill_set_hw_state(priv->hw->wiphy, state); } diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c index c3c2de3b3169..e8d3129d5bde 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c @@ -1016,30 +1016,16 @@ void iwl_irq_tasklet(struct iwl_trans *trans) /* HW RF KILL switch toggled */ if (inta & CSR_INT_BIT_RF_KILL) { - int hw_rf_kill = 0; - if (!(iwl_read32(trans, CSR_GP_CNTRL) & - CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)) - hw_rf_kill = 1; + bool hw_rfkill; + hw_rfkill = !(iwl_read32(trans, CSR_GP_CNTRL) & + CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW); IWL_WARN(trans, "RF_KILL bit toggled to %s.\n", - hw_rf_kill ? "disable radio" : "enable radio"); + hw_rfkill ? "disable radio" : "enable radio"); isr_stats->rfkill++; - /* driver only loads ucode once setting the interface up. - * the driver allows loading the ucode even if the radio - * is killed. Hence update the killswitch state here. The - * rfkill handler will care about restarting if needed. - */ - if (!test_bit(STATUS_ALIVE, &trans->shrd->status)) { - if (hw_rf_kill) - set_bit(STATUS_RF_KILL_HW, - &trans->shrd->status); - else - clear_bit(STATUS_RF_KILL_HW, - &trans->shrd->status); - iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rf_kill); - } + iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rfkill); handled |= CSR_INT_BIT_RF_KILL; } diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c index d7dbd80eb108..4a05216242a9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c @@ -1021,6 +1021,7 @@ static int iwl_trans_pcie_start_fw(struct iwl_trans *trans, int ret; struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); + bool hw_rfkill; trans->shrd->ucode_owner = IWL_OWNERSHIP_DRIVER; trans_pcie->ac_to_queue[IWL_RXON_CTX_BSS] = iwlagn_bss_ac_to_queue; @@ -1039,14 +1040,11 @@ static int iwl_trans_pcie_start_fw(struct iwl_trans *trans, } /* If platform's RF_KILL switch is NOT set to KILL */ - if (iwl_read32(trans, CSR_GP_CNTRL) & - CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW) - clear_bit(STATUS_RF_KILL_HW, &trans->shrd->status); - else - set_bit(STATUS_RF_KILL_HW, &trans->shrd->status); + hw_rfkill = !(iwl_read32(trans, CSR_GP_CNTRL) & + CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW); + iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rfkill); - if (iwl_is_rfkill(trans->shrd)) { - iwl_op_mode_hw_rf_kill(trans->op_mode, true); + if (hw_rfkill) { iwl_enable_interrupts(trans); return -ERFKILL; } @@ -1506,6 +1504,7 @@ static int iwl_trans_pcie_start_hw(struct iwl_trans *trans) struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); int err; + bool hw_rfkill; trans_pcie->inta_mask = CSR_INI_SET_MASK; @@ -1535,16 +1534,9 @@ static int iwl_trans_pcie_start_hw(struct iwl_trans *trans) iwl_apm_init(trans); - /* If platform's RF_KILL switch is NOT set to KILL */ - if (iwl_read32(trans, - CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW) - clear_bit(STATUS_RF_KILL_HW, &trans->shrd->status); - else - set_bit(STATUS_RF_KILL_HW, &trans->shrd->status); - - iwl_op_mode_hw_rf_kill(trans->op_mode, - test_bit(STATUS_RF_KILL_HW, - &trans->shrd->status)); + hw_rfkill = !(iwl_read32(trans, CSR_GP_CNTRL) & + CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW); + iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rfkill); return err; @@ -1659,19 +1651,12 @@ static int iwl_trans_pcie_suspend(struct iwl_trans *trans) static int iwl_trans_pcie_resume(struct iwl_trans *trans) { - bool hw_rfkill = false; + bool hw_rfkill; iwl_enable_interrupts(trans); - if (!(iwl_read32(trans, CSR_GP_CNTRL) & - CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)) - hw_rfkill = true; - - if (hw_rfkill) - set_bit(STATUS_RF_KILL_HW, &trans->shrd->status); - else - clear_bit(STATUS_RF_KILL_HW, &trans->shrd->status); - + hw_rfkill = !(iwl_read32(trans, CSR_GP_CNTRL) & + CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW); iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rfkill); return 0; -- cgit From 3995deafdae1b802a117b3d6d18bc9e5ce3d1340 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 6 Mar 2012 13:30:44 -0800 Subject: iwlwifi: rename ucode.h to fw-file.h That name better reflects the contents of the file and the fact that it isn't related to iwl-ucode.c. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-drv.c | 2 +- drivers/net/wireless/iwlwifi/iwl-fw-file.h | 160 +++++++++++++++++++++++++++++ drivers/net/wireless/iwlwifi/iwl-ucode.h | 160 ----------------------------- 3 files changed, 161 insertions(+), 161 deletions(-) create mode 100644 drivers/net/wireless/iwlwifi/iwl-fw-file.h delete mode 100644 drivers/net/wireless/iwlwifi/iwl-ucode.h diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.c b/drivers/net/wireless/iwlwifi/iwl-drv.c index f1beeab1e601..29a3ae48df6d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-drv.c +++ b/drivers/net/wireless/iwlwifi/iwl-drv.c @@ -71,7 +71,7 @@ #include "iwl-op-mode.h" /* private includes */ -#include "iwl-ucode.h" +#include "iwl-fw-file.h" /** * struct iwl_drv - drv common data diff --git a/drivers/net/wireless/iwlwifi/iwl-fw-file.h b/drivers/net/wireless/iwlwifi/iwl-fw-file.h new file mode 100644 index 000000000000..7ca6c9526357 --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-fw-file.h @@ -0,0 +1,160 @@ +/****************************************************************************** + * + * This file is provided under a dual BSD/GPLv2 license. When using or + * redistributing this file, you may do so under either license. + * + * GPL LICENSE SUMMARY + * + * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, + * USA + * + * The full GNU General Public License is included in this distribution + * in the file called LICENSE.GPL. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + * BSD LICENSE + * + * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, 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. + * * 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 Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER 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, WHETHER IN 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. + *****************************************************************************/ + +#ifndef __iwl_fw_file_h__ +#define __iwl_fw_file_h__ + +#include + +/* v1/v2 uCode file layout */ +struct iwl_ucode_header { + __le32 ver; /* major/minor/API/serial */ + union { + struct { + __le32 inst_size; /* bytes of runtime code */ + __le32 data_size; /* bytes of runtime data */ + __le32 init_size; /* bytes of init code */ + __le32 init_data_size; /* bytes of init data */ + __le32 boot_size; /* bytes of bootstrap code */ + u8 data[0]; /* in same order as sizes */ + } v1; + struct { + __le32 build; /* build number */ + __le32 inst_size; /* bytes of runtime code */ + __le32 data_size; /* bytes of runtime data */ + __le32 init_size; /* bytes of init code */ + __le32 init_data_size; /* bytes of init data */ + __le32 boot_size; /* bytes of bootstrap code */ + u8 data[0]; /* in same order as sizes */ + } v2; + } u; +}; + +/* + * new TLV uCode file layout + * + * The new TLV file format contains TLVs, that each specify + * some piece of data. To facilitate "groups", for example + * different instruction image with different capabilities, + * bundled with the same init image, an alternative mechanism + * is provided: + * When the alternative field is 0, that means that the item + * is always valid. When it is non-zero, then it is only + * valid in conjunction with items of the same alternative, + * in which case the driver (user) selects one alternative + * to use. + */ + +enum iwl_ucode_tlv_type { + IWL_UCODE_TLV_INVALID = 0, /* unused */ + IWL_UCODE_TLV_INST = 1, + IWL_UCODE_TLV_DATA = 2, + IWL_UCODE_TLV_INIT = 3, + IWL_UCODE_TLV_INIT_DATA = 4, + IWL_UCODE_TLV_BOOT = 5, + IWL_UCODE_TLV_PROBE_MAX_LEN = 6, /* a u32 value */ + IWL_UCODE_TLV_PAN = 7, + IWL_UCODE_TLV_RUNT_EVTLOG_PTR = 8, + IWL_UCODE_TLV_RUNT_EVTLOG_SIZE = 9, + IWL_UCODE_TLV_RUNT_ERRLOG_PTR = 10, + IWL_UCODE_TLV_INIT_EVTLOG_PTR = 11, + IWL_UCODE_TLV_INIT_EVTLOG_SIZE = 12, + IWL_UCODE_TLV_INIT_ERRLOG_PTR = 13, + IWL_UCODE_TLV_ENHANCE_SENS_TBL = 14, + IWL_UCODE_TLV_PHY_CALIBRATION_SIZE = 15, + IWL_UCODE_TLV_WOWLAN_INST = 16, + IWL_UCODE_TLV_WOWLAN_DATA = 17, + IWL_UCODE_TLV_FLAGS = 18, +}; + +struct iwl_ucode_tlv { + __le16 type; /* see above */ + __le16 alternative; /* see comment */ + __le32 length; /* not including type/length fields */ + u8 data[0]; +}; + +#define IWL_TLV_UCODE_MAGIC 0x0a4c5749 + +struct iwl_tlv_ucode_header { + /* + * The TLV style ucode header is distinguished from + * the v1/v2 style header by first four bytes being + * zero, as such is an invalid combination of + * major/minor/API/serial versions. + */ + __le32 zero; + __le32 magic; + u8 human_readable[64]; + __le32 ver; /* major/minor/API/serial */ + __le32 build; + __le64 alternatives; /* bitmask of valid alternatives */ + /* + * The data contained herein has a TLV layout, + * see above for the TLV header and types. + * Note that each TLV is padded to a length + * that is a multiple of 4 for alignment. + */ + u8 data[0]; +}; + +#endif /* __iwl_fw_file_h__ */ diff --git a/drivers/net/wireless/iwlwifi/iwl-ucode.h b/drivers/net/wireless/iwlwifi/iwl-ucode.h deleted file mode 100644 index cdab28784404..000000000000 --- a/drivers/net/wireless/iwlwifi/iwl-ucode.h +++ /dev/null @@ -1,160 +0,0 @@ -/****************************************************************************** - * - * This file is provided under a dual BSD/GPLv2 license. When using or - * redistributing this file, you may do so under either license. - * - * GPL LICENSE SUMMARY - * - * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, - * USA - * - * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. - * - * Contact Information: - * Intel Linux Wireless - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - * - * BSD LICENSE - * - * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, 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. - * * 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 Intel Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER 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, WHETHER IN 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. - *****************************************************************************/ - -#ifndef __iwl_ucode_h__ -#define __iwl_ucode_h__ - -#include - -/* v1/v2 uCode file layout */ -struct iwl_ucode_header { - __le32 ver; /* major/minor/API/serial */ - union { - struct { - __le32 inst_size; /* bytes of runtime code */ - __le32 data_size; /* bytes of runtime data */ - __le32 init_size; /* bytes of init code */ - __le32 init_data_size; /* bytes of init data */ - __le32 boot_size; /* bytes of bootstrap code */ - u8 data[0]; /* in same order as sizes */ - } v1; - struct { - __le32 build; /* build number */ - __le32 inst_size; /* bytes of runtime code */ - __le32 data_size; /* bytes of runtime data */ - __le32 init_size; /* bytes of init code */ - __le32 init_data_size; /* bytes of init data */ - __le32 boot_size; /* bytes of bootstrap code */ - u8 data[0]; /* in same order as sizes */ - } v2; - } u; -}; - -/* - * new TLV uCode file layout - * - * The new TLV file format contains TLVs, that each specify - * some piece of data. To facilitate "groups", for example - * different instruction image with different capabilities, - * bundled with the same init image, an alternative mechanism - * is provided: - * When the alternative field is 0, that means that the item - * is always valid. When it is non-zero, then it is only - * valid in conjunction with items of the same alternative, - * in which case the driver (user) selects one alternative - * to use. - */ - -enum iwl_ucode_tlv_type { - IWL_UCODE_TLV_INVALID = 0, /* unused */ - IWL_UCODE_TLV_INST = 1, - IWL_UCODE_TLV_DATA = 2, - IWL_UCODE_TLV_INIT = 3, - IWL_UCODE_TLV_INIT_DATA = 4, - IWL_UCODE_TLV_BOOT = 5, - IWL_UCODE_TLV_PROBE_MAX_LEN = 6, /* a u32 value */ - IWL_UCODE_TLV_PAN = 7, - IWL_UCODE_TLV_RUNT_EVTLOG_PTR = 8, - IWL_UCODE_TLV_RUNT_EVTLOG_SIZE = 9, - IWL_UCODE_TLV_RUNT_ERRLOG_PTR = 10, - IWL_UCODE_TLV_INIT_EVTLOG_PTR = 11, - IWL_UCODE_TLV_INIT_EVTLOG_SIZE = 12, - IWL_UCODE_TLV_INIT_ERRLOG_PTR = 13, - IWL_UCODE_TLV_ENHANCE_SENS_TBL = 14, - IWL_UCODE_TLV_PHY_CALIBRATION_SIZE = 15, - IWL_UCODE_TLV_WOWLAN_INST = 16, - IWL_UCODE_TLV_WOWLAN_DATA = 17, - IWL_UCODE_TLV_FLAGS = 18, -}; - -struct iwl_ucode_tlv { - __le16 type; /* see above */ - __le16 alternative; /* see comment */ - __le32 length; /* not including type/length fields */ - u8 data[0]; -}; - -#define IWL_TLV_UCODE_MAGIC 0x0a4c5749 - -struct iwl_tlv_ucode_header { - /* - * The TLV style ucode header is distinguished from - * the v1/v2 style header by first four bytes being - * zero, as such is an invalid combination of - * major/minor/API/serial versions. - */ - __le32 zero; - __le32 magic; - u8 human_readable[64]; - __le32 ver; /* major/minor/API/serial */ - __le32 build; - __le64 alternatives; /* bitmask of valid alternatives */ - /* - * The data contained herein has a TLV layout, - * see above for the TLV header and types. - * Note that each TLV is padded to a length - * that is a multiple of 4 for alignment. - */ - u8 data[0]; -}; - -#endif /* __iwl_ucode_h__ */ -- cgit From 496bab39b5a8ef9c916cdb961dec5bbb5ba263f7 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 6 Mar 2012 13:30:45 -0800 Subject: iwlwifi: remove AMT check from transport As iwl_prepare_card_hw() is idempotent (and many cards support AMT anyway) there's no point in calling iwl_prepare_card_hw() only for AMT capable devices -- call it always and simplify the code that way. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c index 4a05216242a9..4a2d4b58cdc8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c @@ -1033,8 +1033,8 @@ static int iwl_trans_pcie_start_fw(struct iwl_trans *trans, trans_pcie->mcast_queue[IWL_RXON_CTX_BSS] = 0; trans_pcie->mcast_queue[IWL_RXON_CTX_PAN] = IWL_IPAN_MCAST_QUEUE; - if ((hw_params(trans).sku & EEPROM_SKU_CAP_AMT_ENABLE) && - iwl_prepare_card_hw(trans)) { + /* This may fail if AMT took ownership of the device */ + if (iwl_prepare_card_hw(trans)) { IWL_WARN(trans, "Exit HW not ready\n"); return -EIO; } -- cgit From 0dde86b2f2999a25dcc62a27cb768c35a418890a Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 6 Mar 2012 13:30:46 -0800 Subject: iwlwifi: remove shadow_reg_enable from hw_params There's no need to copy shadow_reg_enable into hw_params since it is a pure hardware parameter that will never change, we can access it from the config directly. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn.c | 2 -- drivers/net/wireless/iwlwifi/iwl-power.c | 4 ++-- drivers/net/wireless/iwlwifi/iwl-shared.h | 1 - drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c | 2 +- drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c | 2 +- drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | 2 +- 6 files changed, 5 insertions(+), 8 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 863c27e20dbc..f8163717d7d1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -1127,8 +1127,6 @@ static void iwl_set_hw_params(struct iwl_priv *priv) hw_params(priv).num_ampdu_queues = cfg(priv)->base_params->num_of_ampdu_queues; - hw_params(priv).shadow_reg_enable = - cfg(priv)->base_params->shadow_reg_enable; hw_params(priv).wd_timeout = cfg(priv)->base_params->wd_timeout; /* Device-specific setup */ diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c index d76ff239d5f1..f79ff16e29f4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-power.c +++ b/drivers/net/wireless/iwlwifi/iwl-power.c @@ -215,7 +215,7 @@ static void iwl_static_sleep_cmd(struct iwl_priv *priv, else cmd->flags &= ~IWL_POWER_SLEEP_OVER_DTIM_MSK; - if (hw_params(priv).shadow_reg_enable) + if (cfg(priv)->base_params->shadow_reg_enable) cmd->flags |= IWL_POWER_SHADOW_REG_ENA; else cmd->flags &= ~IWL_POWER_SHADOW_REG_ENA; @@ -301,7 +301,7 @@ static void iwl_power_fill_sleep_cmd(struct iwl_priv *priv, if (priv->power_data.bus_pm) cmd->flags |= IWL_POWER_PCI_PM_MSK; - if (hw_params(priv).shadow_reg_enable) + if (cfg(priv)->base_params->shadow_reg_enable) cmd->flags |= IWL_POWER_SHADOW_REG_ENA; else cmd->flags &= ~IWL_POWER_SHADOW_REG_ENA; diff --git a/drivers/net/wireless/iwlwifi/iwl-shared.h b/drivers/net/wireless/iwlwifi/iwl-shared.h index 30b942f77814..a5ab58ce0307 100644 --- a/drivers/net/wireless/iwlwifi/iwl-shared.h +++ b/drivers/net/wireless/iwlwifi/iwl-shared.h @@ -185,7 +185,6 @@ struct iwl_hw_params { u8 valid_tx_ant; u8 valid_rx_ant; u8 ht40_channel; - bool shadow_reg_enable; u16 sku; u32 rx_page_order; u32 ct_kill_threshold; diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c index e8d3129d5bde..911a9f113f1f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c @@ -141,7 +141,7 @@ void iwl_rx_queue_update_write_ptr(struct iwl_trans *trans, if (q->need_update == 0) goto exit_unlock; - if (hw_params(trans).shadow_reg_enable) { + if (cfg(trans)->base_params->shadow_reg_enable) { /* shadow register enabled */ /* Device expects a multiple of 8 */ q->write_actual = (q->write & ~0x7); diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c index ca4ceeacc989..2573f7149f16 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c @@ -136,7 +136,7 @@ void iwl_txq_update_write_ptr(struct iwl_trans *trans, struct iwl_tx_queue *txq) if (txq->need_update == 0) return; - if (hw_params(trans).shadow_reg_enable) { + if (cfg(trans)->base_params->shadow_reg_enable) { /* shadow register enabled */ iwl_write32(trans, HBUS_TARG_WRPTR, txq->q.write_ptr | (txq_id << 8)); diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c index 4a2d4b58cdc8..44050fa414d1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c @@ -828,7 +828,7 @@ static int iwl_nic_init(struct iwl_trans *trans) if (iwl_tx_init(trans)) return -ENOMEM; - if (hw_params(trans).shadow_reg_enable) { + if (cfg(trans)->base_params->shadow_reg_enable) { /* enable shadow regs in HW */ iwl_set_bit(trans, CSR_MAC_SHADOW_REG_CTRL, 0x800FFFFF); -- cgit From 84abd2cc066fc077c424d0faf7618be348a7efb2 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 6 Mar 2012 13:30:47 -0800 Subject: iwlwifi: move status check functions out of shared They are only used in the DVM op_mode. Also move the rfkill debug macros that depend on them. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-tt.c | 1 + drivers/net/wireless/iwlwifi/iwl-agn.h | 64 +++++++++++++++++++++++++++++++ drivers/net/wireless/iwlwifi/iwl-debug.h | 16 -------- drivers/net/wireless/iwlwifi/iwl-shared.h | 42 -------------------- 4 files changed, 65 insertions(+), 58 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tt.c b/drivers/net/wireless/iwlwifi/iwl-agn-tt.c index 85fe590ee721..7712c5537370 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tt.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tt.c @@ -34,6 +34,7 @@ #include +#include "iwl-agn.h" #include "iwl-eeprom.h" #include "iwl-dev.h" #include "iwl-core.h" diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index dfd86f288dee..1f62d6d1fc65 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h @@ -383,4 +383,68 @@ static inline void iwl_print_rx_config_cmd(struct iwl_priv *priv, } #endif +/* status checks */ + +static inline int iwl_is_ready(struct iwl_shared *shrd) +{ + /* The adapter is 'ready' if READY and GEO_CONFIGURED bits are + * set but EXIT_PENDING is not */ + return test_bit(STATUS_READY, &shrd->status) && + test_bit(STATUS_GEO_CONFIGURED, &shrd->status) && + !test_bit(STATUS_EXIT_PENDING, &shrd->status); +} + +static inline int iwl_is_alive(struct iwl_shared *shrd) +{ + return test_bit(STATUS_ALIVE, &shrd->status); +} + +static inline int iwl_is_init(struct iwl_shared *shrd) +{ + return test_bit(STATUS_INIT, &shrd->status); +} + +static inline int iwl_is_rfkill_hw(struct iwl_shared *shrd) +{ + return test_bit(STATUS_RF_KILL_HW, &shrd->status); +} + +static inline int iwl_is_rfkill(struct iwl_shared *shrd) +{ + return iwl_is_rfkill_hw(shrd); +} + +static inline int iwl_is_ctkill(struct iwl_shared *shrd) +{ + return test_bit(STATUS_CT_KILL, &shrd->status); +} + +static inline int iwl_is_ready_rf(struct iwl_shared *shrd) +{ + if (iwl_is_rfkill(shrd)) + return 0; + + return iwl_is_ready(shrd); +} + +#ifdef CONFIG_IWLWIFI_DEBUG +#define IWL_DEBUG_QUIET_RFKILL(m, fmt, args...) \ +do { \ + if (!iwl_is_rfkill((m)->shrd)) \ + IWL_ERR(m, fmt, ##args); \ + else \ + __iwl_err(trans(m)->dev, true, \ + !iwl_have_debug_level(IWL_DL_RADIO), \ + fmt, ##args); \ +} while (0) +#else +#define IWL_DEBUG_QUIET_RFKILL(m, fmt, args...) \ +do { \ + if (!iwl_is_rfkill((m)->shrd)) \ + IWL_ERR(m, fmt, ##args); \ + else \ + __iwl_err(trans(m)->dev, true, true, fmt, ##args); \ +} while (0) +#endif /* CONFIG_IWLWIFI_DEBUG */ + #endif /* __iwl_agn_h__ */ diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.h b/drivers/net/wireless/iwlwifi/iwl-debug.h index 163d259198be..a6b32a11e103 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debug.h +++ b/drivers/net/wireless/iwlwifi/iwl-debug.h @@ -76,24 +76,8 @@ do { \ print_hex_dump(KERN_DEBUG, "iwl data: ", \ DUMP_PREFIX_OFFSET, 16, 1, p, len, 1); \ } while (0) -#define IWL_DEBUG_QUIET_RFKILL(m, fmt, args...) \ -do { \ - if (!iwl_is_rfkill((m)->shrd)) \ - IWL_ERR(m, fmt, ##args); \ - else \ - __iwl_err(trans(m)->dev, true, \ - !iwl_have_debug_level(IWL_DL_RADIO), \ - fmt, ##args); \ -} while (0) #else #define iwl_print_hex_dump(m, level, p, len) -#define IWL_DEBUG_QUIET_RFKILL(m, fmt, args...) \ -do { \ - if (!iwl_is_rfkill((m)->shrd)) \ - IWL_ERR(m, fmt, ##args); \ - else \ - __iwl_err(trans(m)->dev, true, true, fmt, ##args); \ -} while (0) #endif /* CONFIG_IWLWIFI_DEBUG */ #ifdef CONFIG_IWLWIFI_DEBUGFS diff --git a/drivers/net/wireless/iwlwifi/iwl-shared.h b/drivers/net/wireless/iwlwifi/iwl-shared.h index a5ab58ce0307..5e12b504aacf 100644 --- a/drivers/net/wireless/iwlwifi/iwl-shared.h +++ b/drivers/net/wireless/iwlwifi/iwl-shared.h @@ -508,46 +508,4 @@ iwl_remove_notification(struct iwl_shared *shrd, #define STATUS_CHANNEL_SWITCH_PENDING 19 #define STATUS_SCAN_COMPLETE 20 -static inline int iwl_is_ready(struct iwl_shared *shrd) -{ - /* The adapter is 'ready' if READY and GEO_CONFIGURED bits are - * set but EXIT_PENDING is not */ - return test_bit(STATUS_READY, &shrd->status) && - test_bit(STATUS_GEO_CONFIGURED, &shrd->status) && - !test_bit(STATUS_EXIT_PENDING, &shrd->status); -} - -static inline int iwl_is_alive(struct iwl_shared *shrd) -{ - return test_bit(STATUS_ALIVE, &shrd->status); -} - -static inline int iwl_is_init(struct iwl_shared *shrd) -{ - return test_bit(STATUS_INIT, &shrd->status); -} - -static inline int iwl_is_rfkill_hw(struct iwl_shared *shrd) -{ - return test_bit(STATUS_RF_KILL_HW, &shrd->status); -} - -static inline int iwl_is_rfkill(struct iwl_shared *shrd) -{ - return iwl_is_rfkill_hw(shrd); -} - -static inline int iwl_is_ctkill(struct iwl_shared *shrd) -{ - return test_bit(STATUS_CT_KILL, &shrd->status); -} - -static inline int iwl_is_ready_rf(struct iwl_shared *shrd) -{ - if (iwl_is_rfkill(shrd)) - return 0; - - return iwl_is_ready(shrd); -} - #endif /* #__iwl_shared_h__ */ -- cgit From 6c1011e1918be17f7f8ccca5442cd517f9c29d17 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 6 Mar 2012 13:30:48 -0800 Subject: iwlwifi: make tracing use device as identifier Tracing used the priv pointer as an identifier, which has the problem that we don't have it in all code, and also some people say no pointers should be "leaked" to userspace. Use the device name instead, it is more useful anyway. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn.c | 9 +- drivers/net/wireless/iwlwifi/iwl-devtrace.h | 141 ++++++++++++----------- drivers/net/wireless/iwlwifi/iwl-io.h | 6 +- drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c | 16 +-- drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c | 2 +- drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | 2 +- 6 files changed, 90 insertions(+), 86 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index f8163717d7d1..276570025e52 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -353,11 +353,12 @@ static void iwl_print_cont_event_trace(struct iwl_priv *priv, u32 base, ev = iwl_read32(trans(priv), HBUS_TARG_MEM_RDAT); time = iwl_read32(trans(priv), HBUS_TARG_MEM_RDAT); if (mode == 0) { - trace_iwlwifi_dev_ucode_cont_event(priv, 0, time, ev); + trace_iwlwifi_dev_ucode_cont_event( + trans(priv)->dev, 0, time, ev); } else { data = iwl_read32(trans(priv), HBUS_TARG_MEM_RDAT); - trace_iwlwifi_dev_ucode_cont_event(priv, time, - data, ev); + trace_iwlwifi_dev_ucode_cont_event( + trans(priv)->dev, time, data, ev); } } /* Allow device to power down */ @@ -422,7 +423,7 @@ static void iwl_continuous_event_trace(struct iwl_priv *priv) else priv->event_log.wraps_once_count++; - trace_iwlwifi_dev_ucode_wrap_event(priv, + trace_iwlwifi_dev_ucode_wrap_event(trans(priv)->dev, num_wraps - priv->event_log.num_wraps, next_entry, priv->event_log.next_entry); diff --git a/drivers/net/wireless/iwlwifi/iwl-devtrace.h b/drivers/net/wireless/iwlwifi/iwl-devtrace.h index 96e62338cec0..06203d6a1d86 100644 --- a/drivers/net/wireless/iwlwifi/iwl-devtrace.h +++ b/drivers/net/wireless/iwlwifi/iwl-devtrace.h @@ -41,130 +41,134 @@ static inline void trace_ ## name(proto) {} static inline void trace_ ## name(proto) {} #endif -#define PRIV_ENTRY __field(void *, priv) -#define PRIV_ASSIGN __entry->priv = priv +#define DEV_ENTRY __string(dev, dev_name(dev)) +#define DEV_ASSIGN __assign_str(dev, dev_name(dev)) #undef TRACE_SYSTEM #define TRACE_SYSTEM iwlwifi_io TRACE_EVENT(iwlwifi_dev_ioread32, - TP_PROTO(void *priv, u32 offs, u32 val), - TP_ARGS(priv, offs, val), + TP_PROTO(const struct device *dev, u32 offs, u32 val), + TP_ARGS(dev, offs, val), TP_STRUCT__entry( - PRIV_ENTRY + DEV_ENTRY __field(u32, offs) __field(u32, val) ), TP_fast_assign( - PRIV_ASSIGN; + DEV_ASSIGN; __entry->offs = offs; __entry->val = val; ), - TP_printk("[%p] read io[%#x] = %#x", __entry->priv, __entry->offs, __entry->val) + TP_printk("[%s] read io[%#x] = %#x", + __get_str(dev), __entry->offs, __entry->val) ); TRACE_EVENT(iwlwifi_dev_iowrite8, - TP_PROTO(void *priv, u32 offs, u8 val), - TP_ARGS(priv, offs, val), + TP_PROTO(const struct device *dev, u32 offs, u8 val), + TP_ARGS(dev, offs, val), TP_STRUCT__entry( - PRIV_ENTRY + DEV_ENTRY __field(u32, offs) __field(u8, val) ), TP_fast_assign( - PRIV_ASSIGN; + DEV_ASSIGN; __entry->offs = offs; __entry->val = val; ), - TP_printk("[%p] write io[%#x] = %#x)", __entry->priv, __entry->offs, __entry->val) + TP_printk("[%s] write io[%#x] = %#x)", + __get_str(dev), __entry->offs, __entry->val) ); TRACE_EVENT(iwlwifi_dev_iowrite32, - TP_PROTO(void *priv, u32 offs, u32 val), - TP_ARGS(priv, offs, val), + TP_PROTO(const struct device *dev, u32 offs, u32 val), + TP_ARGS(dev, offs, val), TP_STRUCT__entry( - PRIV_ENTRY + DEV_ENTRY __field(u32, offs) __field(u32, val) ), TP_fast_assign( - PRIV_ASSIGN; + DEV_ASSIGN; __entry->offs = offs; __entry->val = val; ), - TP_printk("[%p] write io[%#x] = %#x)", __entry->priv, __entry->offs, __entry->val) + TP_printk("[%s] write io[%#x] = %#x)", + __get_str(dev), __entry->offs, __entry->val) ); TRACE_EVENT(iwlwifi_dev_irq, - TP_PROTO(void *priv), - TP_ARGS(priv), + TP_PROTO(const struct device *dev), + TP_ARGS(dev), TP_STRUCT__entry( - PRIV_ENTRY + DEV_ENTRY ), TP_fast_assign( - PRIV_ASSIGN; + DEV_ASSIGN; ), /* TP_printk("") doesn't compile */ TP_printk("%d", 0) ); TRACE_EVENT(iwlwifi_dev_ict_read, - TP_PROTO(void *priv, u32 index, u32 value), - TP_ARGS(priv, index, value), + TP_PROTO(const struct device *dev, u32 index, u32 value), + TP_ARGS(dev, index, value), TP_STRUCT__entry( - PRIV_ENTRY + DEV_ENTRY __field(u32, index) __field(u32, value) ), TP_fast_assign( - PRIV_ASSIGN; + DEV_ASSIGN; __entry->index = index; __entry->value = value; ), - TP_printk("read ict[%d] = %#.8x", __entry->index, __entry->value) + TP_printk("[%s] read ict[%d] = %#.8x", + __get_str(dev), __entry->index, __entry->value) ); #undef TRACE_SYSTEM #define TRACE_SYSTEM iwlwifi_ucode TRACE_EVENT(iwlwifi_dev_ucode_cont_event, - TP_PROTO(void *priv, u32 time, u32 data, u32 ev), - TP_ARGS(priv, time, data, ev), + TP_PROTO(const struct device *dev, u32 time, u32 data, u32 ev), + TP_ARGS(dev, time, data, ev), TP_STRUCT__entry( - PRIV_ENTRY + DEV_ENTRY __field(u32, time) __field(u32, data) __field(u32, ev) ), TP_fast_assign( - PRIV_ASSIGN; + DEV_ASSIGN; __entry->time = time; __entry->data = data; __entry->ev = ev; ), - TP_printk("[%p] EVT_LOGT:%010u:0x%08x:%04u", - __entry->priv, __entry->time, __entry->data, __entry->ev) + TP_printk("[%s] EVT_LOGT:%010u:0x%08x:%04u", + __get_str(dev), __entry->time, __entry->data, __entry->ev) ); TRACE_EVENT(iwlwifi_dev_ucode_wrap_event, - TP_PROTO(void *priv, u32 wraps, u32 n_entry, u32 p_entry), - TP_ARGS(priv, wraps, n_entry, p_entry), + TP_PROTO(const struct device *dev, u32 wraps, u32 n_entry, u32 p_entry), + TP_ARGS(dev, wraps, n_entry, p_entry), TP_STRUCT__entry( - PRIV_ENTRY + DEV_ENTRY __field(u32, wraps) __field(u32, n_entry) __field(u32, p_entry) ), TP_fast_assign( - PRIV_ASSIGN; + DEV_ASSIGN; __entry->wraps = wraps; __entry->n_entry = n_entry; __entry->p_entry = p_entry; ), - TP_printk("[%p] wraps=#%02d n=0x%X p=0x%X", - __entry->priv, __entry->wraps, __entry->n_entry, + TP_printk("[%s] wraps=#%02d n=0x%X p=0x%X", + __get_str(dev), __entry->wraps, __entry->n_entry, __entry->p_entry) ); @@ -232,52 +236,52 @@ TRACE_EVENT(iwlwifi_dbg, #define TRACE_SYSTEM iwlwifi TRACE_EVENT(iwlwifi_dev_hcmd, - TP_PROTO(void *priv, u32 flags, + TP_PROTO(const struct device *dev, u32 flags, const void *hcmd0, size_t len0, const void *hcmd1, size_t len1, const void *hcmd2, size_t len2), - TP_ARGS(priv, flags, hcmd0, len0, hcmd1, len1, hcmd2, len2), + TP_ARGS(dev, flags, hcmd0, len0, hcmd1, len1, hcmd2, len2), TP_STRUCT__entry( - PRIV_ENTRY + DEV_ENTRY __dynamic_array(u8, hcmd0, len0) __dynamic_array(u8, hcmd1, len1) __dynamic_array(u8, hcmd2, len2) __field(u32, flags) ), TP_fast_assign( - PRIV_ASSIGN; + DEV_ASSIGN; memcpy(__get_dynamic_array(hcmd0), hcmd0, len0); memcpy(__get_dynamic_array(hcmd1), hcmd1, len1); memcpy(__get_dynamic_array(hcmd2), hcmd2, len2); __entry->flags = flags; ), - TP_printk("[%p] hcmd %#.2x (%ssync)", - __entry->priv, ((u8 *)__get_dynamic_array(hcmd0))[0], + TP_printk("[%s] hcmd %#.2x (%ssync)", + __get_str(dev), ((u8 *)__get_dynamic_array(hcmd0))[0], __entry->flags & CMD_ASYNC ? "a" : "") ); TRACE_EVENT(iwlwifi_dev_rx, - TP_PROTO(void *priv, void *rxbuf, size_t len), - TP_ARGS(priv, rxbuf, len), + TP_PROTO(const struct device *dev, void *rxbuf, size_t len), + TP_ARGS(dev, rxbuf, len), TP_STRUCT__entry( - PRIV_ENTRY + DEV_ENTRY __dynamic_array(u8, rxbuf, len) ), TP_fast_assign( - PRIV_ASSIGN; + DEV_ASSIGN; memcpy(__get_dynamic_array(rxbuf), rxbuf, len); ), - TP_printk("[%p] RX cmd %#.2x", - __entry->priv, ((u8 *)__get_dynamic_array(rxbuf))[4]) + TP_printk("[%s] RX cmd %#.2x", + __get_str(dev), ((u8 *)__get_dynamic_array(rxbuf))[4]) ); TRACE_EVENT(iwlwifi_dev_tx, - TP_PROTO(void *priv, void *tfd, size_t tfdlen, + TP_PROTO(const struct device *dev, void *tfd, size_t tfdlen, void *buf0, size_t buf0_len, void *buf1, size_t buf1_len), - TP_ARGS(priv, tfd, tfdlen, buf0, buf0_len, buf1, buf1_len), + TP_ARGS(dev, tfd, tfdlen, buf0, buf0_len, buf1, buf1_len), TP_STRUCT__entry( - PRIV_ENTRY + DEV_ENTRY __field(size_t, framelen) __dynamic_array(u8, tfd, tfdlen) @@ -291,29 +295,28 @@ TRACE_EVENT(iwlwifi_dev_tx, __dynamic_array(u8, buf1, buf1_len) ), TP_fast_assign( - PRIV_ASSIGN; + DEV_ASSIGN; __entry->framelen = buf0_len + buf1_len; memcpy(__get_dynamic_array(tfd), tfd, tfdlen); memcpy(__get_dynamic_array(buf0), buf0, buf0_len); memcpy(__get_dynamic_array(buf1), buf1, buf1_len); ), - TP_printk("[%p] TX %.2x (%zu bytes)", - __entry->priv, - ((u8 *)__get_dynamic_array(buf0))[0], + TP_printk("[%s] TX %.2x (%zu bytes)", + __get_str(dev), ((u8 *)__get_dynamic_array(buf0))[0], __entry->framelen) ); TRACE_EVENT(iwlwifi_dev_ucode_error, - TP_PROTO(void *priv, u32 desc, u32 tsf_low, + TP_PROTO(const struct device *dev, u32 desc, u32 tsf_low, u32 data1, u32 data2, u32 line, u32 blink1, u32 blink2, u32 ilink1, u32 ilink2, u32 bcon_time, u32 gp1, u32 gp2, u32 gp3, u32 ucode_ver, u32 hw_ver, u32 brd_ver), - TP_ARGS(priv, desc, tsf_low, data1, data2, line, + TP_ARGS(dev, desc, tsf_low, data1, data2, line, blink1, blink2, ilink1, ilink2, bcon_time, gp1, gp2, gp3, ucode_ver, hw_ver, brd_ver), TP_STRUCT__entry( - PRIV_ENTRY + DEV_ENTRY __field(u32, desc) __field(u32, tsf_low) __field(u32, data1) @@ -332,7 +335,7 @@ TRACE_EVENT(iwlwifi_dev_ucode_error, __field(u32, brd_ver) ), TP_fast_assign( - PRIV_ASSIGN; + DEV_ASSIGN; __entry->desc = desc; __entry->tsf_low = tsf_low; __entry->data1 = data1; @@ -350,11 +353,11 @@ TRACE_EVENT(iwlwifi_dev_ucode_error, __entry->hw_ver = hw_ver; __entry->brd_ver = brd_ver; ), - TP_printk("[%p] #%02d %010u data 0x%08X 0x%08X line %u, " + TP_printk("[%s] #%02d %010u data 0x%08X 0x%08X line %u, " "blink 0x%05X 0x%05X ilink 0x%05X 0x%05X " "bcon_tm %010u gp 0x%08X 0x%08X 0x%08X uCode 0x%08X " "hw 0x%08X brd 0x%08X", - __entry->priv, __entry->desc, __entry->tsf_low, + __get_str(dev), __entry->desc, __entry->tsf_low, __entry->data1, __entry->data2, __entry->line, __entry->blink1, __entry->blink2, __entry->ilink1, __entry->ilink2, @@ -364,23 +367,23 @@ TRACE_EVENT(iwlwifi_dev_ucode_error, ); TRACE_EVENT(iwlwifi_dev_ucode_event, - TP_PROTO(void *priv, u32 time, u32 data, u32 ev), - TP_ARGS(priv, time, data, ev), + TP_PROTO(const struct device *dev, u32 time, u32 data, u32 ev), + TP_ARGS(dev, time, data, ev), TP_STRUCT__entry( - PRIV_ENTRY + DEV_ENTRY __field(u32, time) __field(u32, data) __field(u32, ev) ), TP_fast_assign( - PRIV_ASSIGN; + DEV_ASSIGN; __entry->time = time; __entry->data = data; __entry->ev = ev; ), - TP_printk("[%p] EVT_LOGT:%010u:0x%08x:%04u", - __entry->priv, __entry->time, __entry->data, __entry->ev) + TP_printk("[%s] EVT_LOGT:%010u:0x%08x:%04u", + __get_str(dev), __entry->time, __entry->data, __entry->ev) ); #endif /* __IWLWIFI_DEVICE_TRACE */ diff --git a/drivers/net/wireless/iwlwifi/iwl-io.h b/drivers/net/wireless/iwlwifi/iwl-io.h index 782486fc2f8f..1136dc19936a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-io.h +++ b/drivers/net/wireless/iwlwifi/iwl-io.h @@ -35,20 +35,20 @@ static inline void iwl_write8(struct iwl_trans *trans, u32 ofs, u8 val) { - trace_iwlwifi_dev_iowrite8(priv(trans), ofs, val); + trace_iwlwifi_dev_iowrite8(trans->dev, ofs, val); iwl_trans_write8(trans, ofs, val); } static inline void iwl_write32(struct iwl_trans *trans, u32 ofs, u32 val) { - trace_iwlwifi_dev_iowrite32(priv(trans), ofs, val); + trace_iwlwifi_dev_iowrite32(trans->dev, ofs, val); iwl_trans_write32(trans, ofs, val); } static inline u32 iwl_read32(struct iwl_trans *trans, u32 ofs) { u32 val = iwl_trans_read32(trans, ofs); - trace_iwlwifi_dev_ioread32(priv(trans), ofs, val); + trace_iwlwifi_dev_ioread32(trans->dev, ofs, val); return val; } diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c index 911a9f113f1f..33a933b78e52 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c @@ -388,7 +388,7 @@ static void iwl_rx_handle_rxbuf(struct iwl_trans *trans, len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK; len += sizeof(u32); /* account for status word */ - trace_iwlwifi_dev_rx(priv(trans), pkt, len); + trace_iwlwifi_dev_rx(trans->dev, pkt, len); /* Reclaim a command buffer only if this packet is a response * to a (driver-originated) command. @@ -632,7 +632,7 @@ static void iwl_dump_nic_error_log(struct iwl_trans *trans) trans_pcie->isr_stats.err_code = table.error_id; - trace_iwlwifi_dev_ucode_error(priv(trans), table.error_id, table.tsf_low, + trace_iwlwifi_dev_ucode_error(trans->dev, table.error_id, table.tsf_low, table.data1, table.data2, table.line, table.blink1, table.blink2, table.ilink1, table.ilink2, table.bcon_time, table.gp1, @@ -764,7 +764,7 @@ static int iwl_print_event_log(struct iwl_trans *trans, u32 start_idx, "EVT_LOG:0x%08x:%04u\n", time, ev); } else { - trace_iwlwifi_dev_ucode_event(priv(trans), 0, + trace_iwlwifi_dev_ucode_event(trans->dev, 0, time, ev); IWL_ERR(trans, "EVT_LOG:0x%08x:%04u\n", time, ev); @@ -778,7 +778,7 @@ static int iwl_print_event_log(struct iwl_trans *trans, u32 start_idx, } else { IWL_ERR(trans, "EVT_LOGT:%010u:0x%08x:%04u\n", time, data, ev); - trace_iwlwifi_dev_ucode_event(priv(trans), time, + trace_iwlwifi_dev_ucode_event(trans->dev, time, data, ev); } } @@ -1262,7 +1262,7 @@ static irqreturn_t iwl_isr(int irq, void *data) if (!trans) return IRQ_NONE; - trace_iwlwifi_dev_irq(priv(trans)); + trace_iwlwifi_dev_irq(trans->dev); trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); @@ -1352,7 +1352,7 @@ irqreturn_t iwl_isr_ict(int irq, void *data) if (!trans_pcie->use_ict) return iwl_isr(irq, data); - trace_iwlwifi_dev_irq(priv(trans)); + trace_iwlwifi_dev_irq(trans->dev); spin_lock_irqsave(&trans_pcie->irq_lock, flags); @@ -1369,7 +1369,7 @@ irqreturn_t iwl_isr_ict(int irq, void *data) * This may be due to IRQ shared with another device, * or due to sporadic interrupts thrown from our NIC. */ read = le32_to_cpu(trans_pcie->ict_tbl[trans_pcie->ict_index]); - trace_iwlwifi_dev_ict_read(priv(trans), trans_pcie->ict_index, read); + trace_iwlwifi_dev_ict_read(trans->dev, trans_pcie->ict_index, read); if (!read) { IWL_DEBUG_ISR(trans, "Ignore interrupt, inta == 0\n"); goto none; @@ -1388,7 +1388,7 @@ irqreturn_t iwl_isr_ict(int irq, void *data) iwl_queue_inc_wrap(trans_pcie->ict_index, ICT_COUNT); read = le32_to_cpu(trans_pcie->ict_tbl[trans_pcie->ict_index]); - trace_iwlwifi_dev_ict_read(priv(trans), trans_pcie->ict_index, + trace_iwlwifi_dev_ict_read(trans->dev, trans_pcie->ict_index, read); } while (read); diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c index 2573f7149f16..844606b436ed 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c @@ -820,7 +820,7 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd) /* check that tracing gets all possible blocks */ BUILD_BUG_ON(IWL_MAX_CMD_TFDS + 1 != 3); #ifdef CONFIG_IWLWIFI_DEVICE_TRACING - trace_iwlwifi_dev_hcmd(priv(trans), cmd->flags, + trace_iwlwifi_dev_hcmd(trans->dev, cmd->flags, trace_bufs[0], trace_lens[0], trace_bufs[1], trace_lens[1], trace_bufs[2], trace_lens[2]); diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c index 44050fa414d1..ef4e1222a318 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c @@ -1468,7 +1468,7 @@ static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, dma_sync_single_for_device(trans->dev, txcmd_phys, firstlen, DMA_BIDIRECTIONAL); - trace_iwlwifi_dev_tx(priv(trans), + trace_iwlwifi_dev_tx(trans->dev, &((struct iwl_tfd *)txq->tfds)[txq->q.write_ptr], sizeof(struct iwl_tfd), &dev_cmd->hdr, firstlen, -- cgit From 0e781842cb25ed3a9d0a91bdf05c0717150c9343 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 6 Mar 2012 13:30:49 -0800 Subject: iwlwifi: virtualize command queue full behaviour When the command queue is full, the transport will return -ENOSPC, but the reaction to that depends on the op_mode. Virtualize that, the DVM op_mode checks for CT-kill and restarts the hardware otherwise. We may be able to get rid of this callback by putting the behaviour check into the wrapper but that needs more careful evaluation. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn.c | 11 +++++++++++ drivers/net/wireless/iwlwifi/iwl-agn.h | 2 ++ drivers/net/wireless/iwlwifi/iwl-op-mode.h | 7 +++++++ drivers/net/wireless/iwlwifi/iwl-shared.h | 2 -- drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c | 7 +------ 5 files changed, 21 insertions(+), 8 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 276570025e52..7c3165ed85bc 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -1403,6 +1403,16 @@ static void iwl_op_mode_dvm_stop(struct iwl_op_mode *op_mode) ieee80211_free_hw(priv->hw); } +static void iwl_cmd_queue_full(struct iwl_op_mode *op_mode) +{ + struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); + + if (!iwl_check_for_ct_kill(priv)) { + IWL_ERR(priv, "Restarting adapter queue is full\n"); + iwl_nic_error(op_mode); + } +} + const struct iwl_op_mode_ops iwl_dvm_ops = { .start = iwl_op_mode_dvm_start, .stop = iwl_op_mode_dvm_stop, @@ -1412,6 +1422,7 @@ const struct iwl_op_mode_ops iwl_dvm_ops = { .hw_rf_kill = iwl_set_hw_rfkill_state, .free_skb = iwl_free_skb, .nic_error = iwl_nic_error, + .cmd_queue_full = iwl_cmd_queue_full, }; /***************************************************************************** diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index 1f62d6d1fc65..ec3a90c42efb 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h @@ -90,6 +90,8 @@ void iwl_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state); void iwl_stop_sw_queue(struct iwl_op_mode *op_mode, u8 ac); void iwl_nic_error(struct iwl_op_mode *op_mode); +bool iwl_check_for_ct_kill(struct iwl_priv *priv); + /* MAC80211 */ struct ieee80211_hw *iwl_alloc_all(void); int iwlagn_mac_setup_register(struct iwl_priv *priv, diff --git a/drivers/net/wireless/iwlwifi/iwl-op-mode.h b/drivers/net/wireless/iwlwifi/iwl-op-mode.h index 55b8b27a9560..a4a4907803ca 100644 --- a/drivers/net/wireless/iwlwifi/iwl-op-mode.h +++ b/drivers/net/wireless/iwlwifi/iwl-op-mode.h @@ -122,6 +122,7 @@ struct iwl_fw; * there are Tx packets pending in the transport layer. * Must be atomic * @nic_error: error notification. Must be atomic + * @cmd_queue_full: Called when the command queue gets full. Must be atomic. */ struct iwl_op_mode_ops { struct iwl_op_mode *(*start)(struct iwl_trans *trans, @@ -134,6 +135,7 @@ struct iwl_op_mode_ops { void (*hw_rf_kill)(struct iwl_op_mode *op_mode, bool state); void (*free_skb)(struct iwl_op_mode *op_mode, struct sk_buff *skb); void (*nic_error)(struct iwl_op_mode *op_mode); + void (*cmd_queue_full)(struct iwl_op_mode *op_mode); }; /** @@ -192,6 +194,11 @@ static inline void iwl_op_mode_nic_error(struct iwl_op_mode *op_mode) op_mode->ops->nic_error(op_mode); } +static inline void iwl_op_mode_cmd_queue_full(struct iwl_op_mode *op_mode) +{ + op_mode->ops->cmd_queue_full(op_mode); +} + /***************************************************** * Op mode layers implementations ******************************************************/ diff --git a/drivers/net/wireless/iwlwifi/iwl-shared.h b/drivers/net/wireless/iwlwifi/iwl-shared.h index 5e12b504aacf..8ee528479c95 100644 --- a/drivers/net/wireless/iwlwifi/iwl-shared.h +++ b/drivers/net/wireless/iwlwifi/iwl-shared.h @@ -461,8 +461,6 @@ enum iwl_rxon_context_id { int iwlagn_hw_valid_rtc_data_addr(u32 addr); void iwl_nic_config(struct iwl_priv *priv); const char *get_cmd_string(u8 cmd); -bool iwl_check_for_ct_kill(struct iwl_priv *priv); - /* notification wait support */ void iwl_abort_notification_waits(struct iwl_shared *shrd); diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c index 844606b436ed..7feeb2d52146 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c @@ -671,7 +671,6 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd) dma_addr_t phys_addr; u32 idx; u16 copy_size, cmd_size; - bool is_ct_kill = false; bool had_nocopy = false; int i; u8 *cmd_dest; @@ -727,11 +726,7 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd) spin_unlock_bh(&txq->lock); IWL_ERR(trans, "No space in command queue\n"); - is_ct_kill = iwl_check_for_ct_kill(priv(trans)); - if (!is_ct_kill) { - IWL_ERR(trans, "Restarting adapter queue is full\n"); - iwl_op_mode_nic_error(trans->op_mode); - } + iwl_op_mode_cmd_queue_full(trans->op_mode); return -ENOSPC; } -- cgit From 1b29dc94ac2e96c9a31b566dc609bf1d4eb87cc2 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 6 Mar 2012 13:30:50 -0800 Subject: iwlwifi: clean up iwl-core.h inclusions The transport doesn't need to include iwl-core.h any more. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c | 3 +-- drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c index 33a933b78e52..f1456211c294 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c @@ -30,8 +30,7 @@ #include #include -/*TODO: Remove include to iwl-core.h*/ -#include "iwl-core.h" +#include "iwl-prph.h" #include "iwl-io.h" #include "iwl-trans-pcie-int.h" #include "iwl-op-mode.h" diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c index ef4e1222a318..6090e9800ce4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c @@ -75,7 +75,6 @@ #include "iwl-shared.h" #include "iwl-eeprom.h" #include "iwl-agn-hw.h" -#include "iwl-core.h" #define IWL_MASK(lo, hi) ((1 << (hi)) | ((1 << (hi)) - (1 << (lo)))) -- cgit From ae9625a1a947f33579c244b730001f2ea7d15045 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 6 Mar 2012 13:30:51 -0800 Subject: iwlwifi: remove num_of_queues module parameter This is a hardware parameter, so it shouldn't be configurable by the user. Users can disable aggregation (which is the only thing affected) with 11n_disable. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-1000.c | 5 ----- drivers/net/wireless/iwlwifi/iwl-2000.c | 5 ----- drivers/net/wireless/iwlwifi/iwl-5000.c | 10 ---------- drivers/net/wireless/iwlwifi/iwl-6000.c | 5 ----- drivers/net/wireless/iwlwifi/iwl-agn.c | 2 -- drivers/net/wireless/iwlwifi/iwl-shared.h | 2 -- 6 files changed, 29 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index 2199a0e5c4f0..5039a9a47767 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c @@ -122,11 +122,6 @@ static struct iwl_sensitivity_ranges iwl1000_sensitivity = { static void iwl1000_hw_set_hw_params(struct iwl_priv *priv) { - if (iwlagn_mod_params.num_of_queues >= IWL_MIN_NUM_QUEUES && - iwlagn_mod_params.num_of_queues <= IWLAGN_NUM_QUEUES) - cfg(priv)->base_params->num_of_queues = - iwlagn_mod_params.num_of_queues; - hw_params(priv).max_txq_num = cfg(priv)->base_params->num_of_queues; hw_params(priv).ht40_channel = BIT(IEEE80211_BAND_2GHZ); diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c index 1ba020723537..c1739626aeb4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-2000.c +++ b/drivers/net/wireless/iwlwifi/iwl-2000.c @@ -118,11 +118,6 @@ static struct iwl_sensitivity_ranges iwl2000_sensitivity = { static void iwl2000_hw_set_hw_params(struct iwl_priv *priv) { - if (iwlagn_mod_params.num_of_queues >= IWL_MIN_NUM_QUEUES && - iwlagn_mod_params.num_of_queues <= IWLAGN_NUM_QUEUES) - cfg(priv)->base_params->num_of_queues = - iwlagn_mod_params.num_of_queues; - hw_params(priv).max_txq_num = cfg(priv)->base_params->num_of_queues; hw_params(priv).ht40_channel = BIT(IEEE80211_BAND_2GHZ); diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index aebdfd7e01a5..fc6ec07de877 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -157,11 +157,6 @@ static void iwl5000_set_ct_threshold(struct iwl_priv *priv) static void iwl5000_hw_set_hw_params(struct iwl_priv *priv) { - if (iwlagn_mod_params.num_of_queues >= IWL_MIN_NUM_QUEUES && - iwlagn_mod_params.num_of_queues <= IWLAGN_NUM_QUEUES) - cfg(priv)->base_params->num_of_queues = - iwlagn_mod_params.num_of_queues; - hw_params(priv).max_txq_num = cfg(priv)->base_params->num_of_queues; hw_params(priv).ht40_channel = BIT(IEEE80211_BAND_2GHZ) | @@ -180,11 +175,6 @@ static void iwl5000_hw_set_hw_params(struct iwl_priv *priv) static void iwl5150_hw_set_hw_params(struct iwl_priv *priv) { - if (iwlagn_mod_params.num_of_queues >= IWL_MIN_NUM_QUEUES && - iwlagn_mod_params.num_of_queues <= IWLAGN_NUM_QUEUES) - cfg(priv)->base_params->num_of_queues = - iwlagn_mod_params.num_of_queues; - hw_params(priv).max_txq_num = cfg(priv)->base_params->num_of_queues; hw_params(priv).ht40_channel = BIT(IEEE80211_BAND_2GHZ) | diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index 150bef078609..a64f0f281249 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -139,11 +139,6 @@ static struct iwl_sensitivity_ranges iwl6000_sensitivity = { static void iwl6000_hw_set_hw_params(struct iwl_priv *priv) { - if (iwlagn_mod_params.num_of_queues >= IWL_MIN_NUM_QUEUES && - iwlagn_mod_params.num_of_queues <= IWLAGN_NUM_QUEUES) - cfg(priv)->base_params->num_of_queues = - iwlagn_mod_params.num_of_queues; - hw_params(priv).max_txq_num = cfg(priv)->base_params->num_of_queues; hw_params(priv).ht40_channel = BIT(IEEE80211_BAND_2GHZ) | diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 7c3165ed85bc..8cf149cd20ca 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -1471,8 +1471,6 @@ MODULE_PARM_DESC(debug, "debug output mask"); module_param_named(swcrypto, iwlagn_mod_params.sw_crypto, int, S_IRUGO); MODULE_PARM_DESC(swcrypto, "using crypto in software (default 0 [hardware])"); -module_param_named(queues_num, iwlagn_mod_params.num_of_queues, int, S_IRUGO); -MODULE_PARM_DESC(queues_num, "number of hw queues."); module_param_named(11n_disable, iwlagn_mod_params.disable_11n, uint, S_IRUGO); MODULE_PARM_DESC(11n_disable, "disable 11n functionality, bitmap: 1: full, 2: agg TX, 4: agg RX"); diff --git a/drivers/net/wireless/iwlwifi/iwl-shared.h b/drivers/net/wireless/iwlwifi/iwl-shared.h index 8ee528479c95..ab2e1f771a11 100644 --- a/drivers/net/wireless/iwlwifi/iwl-shared.h +++ b/drivers/net/wireless/iwlwifi/iwl-shared.h @@ -115,7 +115,6 @@ extern struct iwl_mod_params iwlagn_mod_params; * Holds the module parameters * * @sw_crypto: using hardware encryption, default = 0 - * @num_of_queues: number of tx queue, HW dependent * @disable_11n: disable 11n capabilities, default = 0, * use IWL_DISABLE_HT_* constants * @amsdu_size_8K: enable 8K amsdu size, default = 1 @@ -137,7 +136,6 @@ extern struct iwl_mod_params iwlagn_mod_params; */ struct iwl_mod_params { int sw_crypto; - int num_of_queues; unsigned int disable_11n; int amsdu_size_8K; int antenna; -- cgit From 3cc241ad713dcc4e193aec40307e9070bf817908 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 6 Mar 2012 13:30:52 -0800 Subject: iwlwifi: remove max_txq_num from hw_params This can be used directly from the config now. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index a2ef78c6af60..25fdb805abc3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -1345,7 +1345,7 @@ void iwl_bg_watchdog(unsigned long data) return; /* monitor and check for stuck queues */ - for (cnt = 0; cnt < hw_params(priv).max_txq_num; cnt++) + for (cnt = 0; cnt < cfg(priv)->base_params->num_of_queues; cnt++) if (iwl_check_stuck_queue(priv, cnt)) return; -- cgit From ab5c0f1f2d525ed17f1abf727d213cf220ed26a8 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 6 Mar 2012 13:30:53 -0800 Subject: iwlwifi: keep plcp_delta_threshold in priv The base_params shouldn't be writable, so keep a copy of this in priv that can be modified. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-rx.c | 2 +- drivers/net/wireless/iwlwifi/iwl-agn.c | 3 +++ drivers/net/wireless/iwlwifi/iwl-debugfs.c | 6 +++--- drivers/net/wireless/iwlwifi/iwl-dev.h | 2 ++ 4 files changed, 9 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c index d16e73d1b5c9..5c9c88b8609f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c @@ -320,7 +320,7 @@ static bool iwlagn_good_plcp_health(struct iwl_priv *priv, unsigned int msecs) { int delta; - int threshold = cfg(priv)->base_params->plcp_delta_threshold; + int threshold = priv->plcp_delta_threshold; if (threshold == IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE) { IWL_DEBUG_RADIO(priv, "plcp_err check disabled\n"); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 8cf149cd20ca..ac23aa3dd6d7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -1045,6 +1045,9 @@ static int iwl_init_drv(struct iwl_priv *priv) priv->ieee_rates = NULL; priv->band = IEEE80211_BAND_2GHZ; + priv->plcp_delta_threshold = + cfg(priv)->base_params->plcp_delta_threshold; + priv->iw_mode = NL80211_IFTYPE_STATION; priv->current_ht_config.smps = IEEE80211_SMPS_STATIC; priv->missed_beacon_threshold = IWL_MISSED_BEACON_THRESHOLD_DEF; diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index b9b6d628f59a..ade4134fc1ec 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c @@ -2241,7 +2241,7 @@ static ssize_t iwl_dbgfs_plcp_delta_read(struct file *file, const size_t bufsz = sizeof(buf); pos += scnprintf(buf + pos, bufsz - pos, "%u\n", - cfg(priv)->base_params->plcp_delta_threshold); + priv->plcp_delta_threshold); return simple_read_from_buffer(user_buf, count, ppos, buf, pos); } @@ -2263,10 +2263,10 @@ static ssize_t iwl_dbgfs_plcp_delta_write(struct file *file, return -EINVAL; if ((plcp < IWL_MAX_PLCP_ERR_THRESHOLD_MIN) || (plcp > IWL_MAX_PLCP_ERR_THRESHOLD_MAX)) - cfg(priv)->base_params->plcp_delta_threshold = + priv->plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE; else - cfg(priv)->base_params->plcp_delta_threshold = plcp; + priv->plcp_delta_threshold = plcp; return count; } diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 73acbab6c248..0c397fd635a3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -770,6 +770,8 @@ struct iwl_priv { struct iwl_channel_info *channel_info; /* channel info array */ u8 channel_count; /* # of channels */ + u8 plcp_delta_threshold; + /* thermal calibration */ s32 temperature; /* Celsius */ s32 last_temperature; -- cgit From e7a09438b3369732b9c5cfbca24d3bc894fc1ec1 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 6 Mar 2012 13:30:54 -0800 Subject: iwlwifi: use watchdog timeout from hw_params This is the version that can be modified, the config params should be read-only. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-core.c | 4 ++-- drivers/net/wireless/iwlwifi/iwl-debugfs.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 25fdb805abc3..2422eef6d15f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -1340,7 +1340,7 @@ void iwl_bg_watchdog(unsigned long data) if (iwl_is_rfkill(priv->shrd)) return; - timeout = cfg(priv)->base_params->wd_timeout; + timeout = hw_params(priv).wd_timeout; if (timeout == 0) return; @@ -1355,7 +1355,7 @@ void iwl_bg_watchdog(unsigned long data) void iwl_setup_watchdog(struct iwl_priv *priv) { - unsigned int timeout = cfg(priv)->base_params->wd_timeout; + unsigned int timeout = hw_params(priv).wd_timeout; if (!iwlagn_mod_params.wd_disable) { /* use system default */ diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index ade4134fc1ec..116c7851f3b1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c @@ -2368,7 +2368,7 @@ static ssize_t iwl_dbgfs_wd_timeout_write(struct file *file, if (timeout < 0 || timeout > IWL_MAX_WD_TIMEOUT) timeout = IWL_DEF_WD_TIMEOUT; - cfg(priv)->base_params->wd_timeout = timeout; + hw_params(priv).wd_timeout = timeout; iwl_setup_watchdog(priv); return count; } -- cgit From b9ad70da6a7ed166539b188a95e0aef119555e14 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 6 Mar 2012 13:30:55 -0800 Subject: iwlwifi: put use_rts_for_aggregation into hw_params The hardware config ht_params shouldn't be modified, so copy the use_rts_for_aggregation parameter into hw_params and use/modify it there. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-rxon.c | 3 +-- drivers/net/wireless/iwlwifi/iwl-agn-tx.c | 3 +-- drivers/net/wireless/iwlwifi/iwl-agn.c | 4 ++++ drivers/net/wireless/iwlwifi/iwl-debugfs.c | 6 +++--- drivers/net/wireless/iwlwifi/iwl-mac80211.c | 4 ++-- drivers/net/wireless/iwlwifi/iwl-shared.h | 2 ++ 6 files changed, 13 insertions(+), 9 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c index 2c5e7ec697e9..e191d394cfa0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c @@ -436,8 +436,7 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) * force CTS-to-self frames protection if RTS-CTS is not preferred * one aggregation protection method */ - if (!(cfg(priv)->ht_params && - cfg(priv)->ht_params->use_rts_for_aggregation)) + if (!hw_params(priv).use_rts_for_aggregation) ctx->staging.flags |= RXON_FLG_SELF_CTS_EN; if ((ctx->vif && ctx->vif->bss_conf.use_short_slot) || diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c index dd28785e1a5c..151400cf51e0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c @@ -594,8 +594,7 @@ int iwlagn_tx_agg_oper(struct iwl_priv *priv, struct ieee80211_vif *vif, sta_priv->max_agg_bufsize = min(sta_priv->max_agg_bufsize, buf_size); - if (cfg(priv)->ht_params && - cfg(priv)->ht_params->use_rts_for_aggregation) { + if (hw_params(priv).use_rts_for_aggregation) { /* * switch to RTS/CTS if it is the prefer protection * method for HT traffic diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index ac23aa3dd6d7..ce62a2fcd67f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -1119,6 +1119,10 @@ static void iwl_uninit_drv(struct iwl_priv *priv) static void iwl_set_hw_params(struct iwl_priv *priv) { + if (cfg(priv)->ht_params) + hw_params(priv).use_rts_for_aggregation = + cfg(priv)->ht_params->use_rts_for_aggregation; + if (iwlagn_mod_params.amsdu_size_8K) hw_params(priv).rx_page_order = get_order(IWL_RX_BUF_SIZE_8K); diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index 116c7851f3b1..0a898c54c733 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c @@ -2431,7 +2431,7 @@ static ssize_t iwl_dbgfs_protection_mode_read(struct file *file, if (cfg(priv)->ht_params) pos += scnprintf(buf + pos, bufsz - pos, "use %s for aggregation\n", - (cfg(priv)->ht_params->use_rts_for_aggregation) ? + (hw_params(priv).use_rts_for_aggregation) ? "rts/cts" : "cts-to-self"); else pos += scnprintf(buf + pos, bufsz - pos, "N/A"); @@ -2458,9 +2458,9 @@ static ssize_t iwl_dbgfs_protection_mode_write(struct file *file, if (sscanf(buf, "%d", &rts) != 1) return -EINVAL; if (rts) - cfg(priv)->ht_params->use_rts_for_aggregation = true; + hw_params(priv).use_rts_for_aggregation = true; else - cfg(priv)->ht_params->use_rts_for_aggregation = false; + hw_params(priv).use_rts_for_aggregation = false; return count; } diff --git a/drivers/net/wireless/iwlwifi/iwl-mac80211.c b/drivers/net/wireless/iwlwifi/iwl-mac80211.c index 30861765b512..d2c1d714c89c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-mac80211.c +++ b/drivers/net/wireless/iwlwifi/iwl-mac80211.c @@ -660,8 +660,8 @@ static int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw, IWL_DEBUG_HT(priv, "priv->agg_tids_count = %u\n", priv->agg_tids_count); } - if (!priv->agg_tids_count && cfg(priv)->ht_params && - cfg(priv)->ht_params->use_rts_for_aggregation) { + if (!priv->agg_tids_count && + hw_params(priv).use_rts_for_aggregation) { /* * switch off RTS/CTS if it was previously enabled */ diff --git a/drivers/net/wireless/iwlwifi/iwl-shared.h b/drivers/net/wireless/iwlwifi/iwl-shared.h index ab2e1f771a11..7c9502703e82 100644 --- a/drivers/net/wireless/iwlwifi/iwl-shared.h +++ b/drivers/net/wireless/iwlwifi/iwl-shared.h @@ -174,6 +174,7 @@ struct iwl_mod_params { * relevant for 1000, 6000 and up * @wd_timeout: TX queues watchdog timeout * @struct iwl_sensitivity_ranges: range of sensitivity values + * @use_rts_for_aggregation: use rts/cts protection for HT traffic */ struct iwl_hw_params { u8 max_txq_num; @@ -183,6 +184,7 @@ struct iwl_hw_params { u8 valid_tx_ant; u8 valid_rx_ant; u8 ht40_channel; + bool use_rts_for_aggregation; u16 sku; u32 rx_page_order; u32 ct_kill_threshold; -- cgit From 6794f3ee1dc4a2f7ebed99a4c075f00bbebbcfdc Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 6 Mar 2012 13:30:56 -0800 Subject: iwlwifi: constify remaining config data The HW configuration settings base_params, ht_params and bt_params all should be const, make it so. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-1000.c | 5 +++-- drivers/net/wireless/iwlwifi/iwl-2000.c | 8 ++++---- drivers/net/wireless/iwlwifi/iwl-5000.c | 5 +++-- drivers/net/wireless/iwlwifi/iwl-6000.c | 11 ++++++----- drivers/net/wireless/iwlwifi/iwl-shared.h | 6 +++--- 5 files changed, 19 insertions(+), 16 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index 5039a9a47767..5abebc355f7f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c @@ -157,7 +157,7 @@ static struct iwl_lib_ops iwl1000_lib = { .temperature = iwlagn_temperature, }; -static struct iwl_base_params iwl1000_base_params = { +static const struct iwl_base_params iwl1000_base_params = { .num_of_queues = IWLAGN_NUM_QUEUES, .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, .eeprom_size = OTP_LOW_IMAGE_SIZE, @@ -172,7 +172,8 @@ static struct iwl_base_params iwl1000_base_params = { .max_event_log_size = 128, .wd_disable = true, }; -static struct iwl_ht_params iwl1000_ht_params = { + +static const struct iwl_ht_params iwl1000_ht_params = { .ht_greenfield_support = true, .use_rts_for_aggregation = true, /* use rts/cts protection */ .smps_mode = IEEE80211_SMPS_DYNAMIC, diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c index c1739626aeb4..446d010dfe84 100644 --- a/drivers/net/wireless/iwlwifi/iwl-2000.c +++ b/drivers/net/wireless/iwlwifi/iwl-2000.c @@ -175,7 +175,7 @@ static struct iwl_lib_ops iwl2030_lib = { .temperature = iwlagn_temperature, }; -static struct iwl_base_params iwl2000_base_params = { +static const struct iwl_base_params iwl2000_base_params = { .eeprom_size = OTP_LOW_IMAGE_SIZE, .num_of_queues = IWLAGN_NUM_QUEUES, .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, @@ -194,7 +194,7 @@ static struct iwl_base_params iwl2000_base_params = { }; -static struct iwl_base_params iwl2030_base_params = { +static const struct iwl_base_params iwl2030_base_params = { .eeprom_size = OTP_LOW_IMAGE_SIZE, .num_of_queues = IWLAGN_NUM_QUEUES, .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, @@ -212,12 +212,12 @@ static struct iwl_base_params iwl2030_base_params = { .hd_v2 = true, }; -static struct iwl_ht_params iwl2000_ht_params = { +static const struct iwl_ht_params iwl2000_ht_params = { .ht_greenfield_support = true, .use_rts_for_aggregation = true, /* use rts/cts protection */ }; -static struct iwl_bt_params iwl2030_bt_params = { +static const struct iwl_bt_params iwl2030_bt_params = { /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ .advanced_bt_coexist = true, .agg_time_limit = BT_AGG_THRESHOLD_DEF, diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index fc6ec07de877..821ed3a36e52 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -310,7 +310,7 @@ static struct iwl_lib_ops iwl5150_lib = { .temperature = iwl5150_temperature, }; -static struct iwl_base_params iwl5000_base_params = { +static const struct iwl_base_params iwl5000_base_params = { .eeprom_size = IWLAGN_EEPROM_IMG_SIZE, .num_of_queues = IWLAGN_NUM_QUEUES, .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, @@ -323,7 +323,8 @@ static struct iwl_base_params iwl5000_base_params = { .no_idle_support = true, .wd_disable = true, }; -static struct iwl_ht_params iwl5000_ht_params = { + +static const struct iwl_ht_params iwl5000_ht_params = { .ht_greenfield_support = true, }; diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index a64f0f281249..d2e24824fc08 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -271,7 +271,7 @@ static struct iwl_lib_ops iwl6030_lib = { .temperature = iwlagn_temperature, }; -static struct iwl_base_params iwl6000_base_params = { +static const struct iwl_base_params iwl6000_base_params = { .eeprom_size = OTP_LOW_IMAGE_SIZE, .num_of_queues = IWLAGN_NUM_QUEUES, .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, @@ -288,7 +288,7 @@ static struct iwl_base_params iwl6000_base_params = { .shadow_reg_enable = true, }; -static struct iwl_base_params iwl6050_base_params = { +static const struct iwl_base_params iwl6050_base_params = { .eeprom_size = OTP_LOW_IMAGE_SIZE, .num_of_queues = IWLAGN_NUM_QUEUES, .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, @@ -304,7 +304,8 @@ static struct iwl_base_params iwl6050_base_params = { .max_event_log_size = 1024, .shadow_reg_enable = true, }; -static struct iwl_base_params iwl6000_g2_base_params = { + +static const struct iwl_base_params iwl6000_g2_base_params = { .eeprom_size = OTP_LOW_IMAGE_SIZE, .num_of_queues = IWLAGN_NUM_QUEUES, .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, @@ -321,12 +322,12 @@ static struct iwl_base_params iwl6000_g2_base_params = { .shadow_reg_enable = true, }; -static struct iwl_ht_params iwl6000_ht_params = { +static const struct iwl_ht_params iwl6000_ht_params = { .ht_greenfield_support = true, .use_rts_for_aggregation = true, /* use rts/cts protection */ }; -static struct iwl_bt_params iwl6000_bt_params = { +static const struct iwl_bt_params iwl6000_bt_params = { /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ .advanced_bt_coexist = true, .agg_time_limit = BT_AGG_THRESHOLD_DEF, diff --git a/drivers/net/wireless/iwlwifi/iwl-shared.h b/drivers/net/wireless/iwlwifi/iwl-shared.h index 7c9502703e82..5a67fa141744 100644 --- a/drivers/net/wireless/iwlwifi/iwl-shared.h +++ b/drivers/net/wireless/iwlwifi/iwl-shared.h @@ -366,10 +366,10 @@ struct iwl_cfg { const struct iwl_lib_ops *lib; void (*additional_nic_config)(struct iwl_priv *priv); /* params not likely to change within a device family */ - struct iwl_base_params *base_params; + const struct iwl_base_params *base_params; /* params likely to change within a device family */ - struct iwl_ht_params *ht_params; - struct iwl_bt_params *bt_params; + const struct iwl_ht_params *ht_params; + const struct iwl_bt_params *bt_params; enum iwl_pa_type pa_type; /* if used set to IWL_PA_SYSTEM */ const bool need_temp_offset_calib; /* if used set to true */ const bool no_xtal_calib; -- cgit From f47208934b2aba432722baeb86a72fcbfd26b593 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 6 Mar 2012 13:30:57 -0800 Subject: iwlwifi: fix notification wait bug In "iwlwifi: consolidate the start_device flow" Emmanuel added the return if the fw isn't there but forgot to take into account that the struct for notification wait needs to be added only after the check -- fix that. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-ucode.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-ucode.c b/drivers/net/wireless/iwlwifi/iwl-ucode.c index c1c5e1f2223a..686d456d226e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-ucode.c +++ b/drivers/net/wireless/iwlwifi/iwl-ucode.c @@ -533,9 +533,6 @@ int iwl_load_ucode_wait_alive(struct iwl_priv *priv, int ret; enum iwl_ucode_type old_type; - iwl_init_notification_wait(priv->shrd, &alive_wait, REPLY_ALIVE, - iwl_alive_fn, &alive_data); - old_type = priv->shrd->ucode_type; priv->shrd->ucode_type = ucode_type; fw = iwl_get_ucode_image(priv, ucode_type); @@ -543,6 +540,9 @@ int iwl_load_ucode_wait_alive(struct iwl_priv *priv, if (!fw) return -EINVAL; + iwl_init_notification_wait(priv->shrd, &alive_wait, REPLY_ALIVE, + iwl_alive_fn, &alive_data); + ret = iwl_trans_start_fw(trans(priv), fw); if (ret) { priv->shrd->ucode_type = old_type; -- cgit From 4bd14dd5f77bbe3c51f50f4e86d3b8960e6a518c Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 6 Mar 2012 13:30:58 -0800 Subject: iwlwifi: abstract out notification wait support This will be sharable, but needs to live in the op_mode as it is dependent on command processing. Make a library out of the notification wait code. Since I wrote all of the code originally and only Intel employees changed it, we can also relicense it to dual BSD/GPL. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/Makefile | 1 + drivers/net/wireless/iwlwifi/iwl-agn-rx.c | 24 +--- drivers/net/wireless/iwlwifi/iwl-agn-rxon.c | 11 +- drivers/net/wireless/iwlwifi/iwl-core.c | 2 +- drivers/net/wireless/iwlwifi/iwl-dev.h | 3 + drivers/net/wireless/iwlwifi/iwl-notif-wait.c | 157 ++++++++++++++++++++++++++ drivers/net/wireless/iwlwifi/iwl-notif-wait.h | 130 +++++++++++++++++++++ drivers/net/wireless/iwlwifi/iwl-shared.h | 55 --------- drivers/net/wireless/iwlwifi/iwl-testmode.c | 10 +- drivers/net/wireless/iwlwifi/iwl-ucode.c | 81 ++----------- 10 files changed, 314 insertions(+), 160 deletions(-) create mode 100644 drivers/net/wireless/iwlwifi/iwl-notif-wait.c create mode 100644 drivers/net/wireless/iwlwifi/iwl-notif-wait.h diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile index f2a903d01aa9..85d163ed3db1 100644 --- a/drivers/net/wireless/iwlwifi/Makefile +++ b/drivers/net/wireless/iwlwifi/Makefile @@ -14,6 +14,7 @@ iwlwifi-objs += iwl-1000.o iwlwifi-objs += iwl-2000.o iwlwifi-objs += iwl-pci.o iwlwifi-objs += iwl-drv.o +iwlwifi-objs += iwl-notif-wait.o iwlwifi-objs += iwl-trans-pcie.o iwl-trans-pcie-rx.o iwl-trans-pcie-tx.o iwlwifi-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c index 5c9c88b8609f..f17142bb5df1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c @@ -1142,9 +1142,7 @@ void iwl_setup_rx_handlers(struct iwl_priv *priv) priv->rx_handlers[REPLY_TX] = iwlagn_rx_reply_tx; /* set up notification wait support */ - spin_lock_init(&priv->shrd->notif_wait_lock); - INIT_LIST_HEAD(&priv->shrd->notif_waits); - init_waitqueue_head(&priv->shrd->notif_waitq); + iwl_notification_wait_init(&priv->notif_wait); /* Set up BT Rx handlers */ if (cfg(priv)->lib->bt_rx_handler_setup) @@ -1164,25 +1162,7 @@ int iwl_rx_dispatch(struct iwl_op_mode *op_mode, struct iwl_rx_cmd_buffer *rxb, * even if the RX handler consumes the RXB we have * access to it in the notification wait entry. */ - if (!list_empty(&priv->shrd->notif_waits)) { - struct iwl_notification_wait *w; - - spin_lock(&priv->shrd->notif_wait_lock); - list_for_each_entry(w, &priv->shrd->notif_waits, list) { - if (w->cmd != pkt->hdr.cmd) - continue; - IWL_DEBUG_RX(priv, - "Notif: %s, 0x%02x - wake the callers up\n", - get_cmd_string(pkt->hdr.cmd), - pkt->hdr.cmd); - w->triggered = true; - if (w->fn) - w->fn(priv, pkt, w->fn_data); - } - spin_unlock(&priv->shrd->notif_wait_lock); - - wake_up_all(&priv->shrd->notif_waitq); - } + iwl_notification_wait_notify(&priv->notif_wait, pkt); if (priv->pre_rx_handler && priv->shrd->ucode_owner == IWL_OWNERSHIP_TM) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c index e191d394cfa0..9d955fa387e5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c @@ -60,9 +60,9 @@ static int iwlagn_disable_pan(struct iwl_priv *priv, u8 old_dev_type = send->dev_type; int ret; - iwl_init_notification_wait(priv->shrd, &disable_wait, - REPLY_WIPAN_DEACTIVATION_COMPLETE, - NULL, NULL); + iwl_init_notification_wait(&priv->notif_wait, &disable_wait, + REPLY_WIPAN_DEACTIVATION_COMPLETE, + NULL, NULL); send->filter_flags &= ~RXON_FILTER_ASSOC_MSK; send->dev_type = RXON_DEV_TYPE_P2P; @@ -74,9 +74,10 @@ static int iwlagn_disable_pan(struct iwl_priv *priv, if (ret) { IWL_ERR(priv, "Error disabling PAN (%d)\n", ret); - iwl_remove_notification(priv->shrd, &disable_wait); + iwl_remove_notification(&priv->notif_wait, &disable_wait); } else { - ret = iwl_wait_notification(priv->shrd, &disable_wait, HZ); + ret = iwl_wait_notification(&priv->notif_wait, + &disable_wait, HZ); if (ret) IWL_ERR(priv, "Timed out waiting for PAN disable\n"); } diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 2422eef6d15f..5f0e07c0b50c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -845,7 +845,7 @@ static void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand) /* Cancel currently queued command. */ clear_bit(STATUS_HCMD_ACTIVE, &priv->shrd->status); - iwl_abort_notification_waits(priv->shrd); + iwl_abort_notification_waits(&priv->notif_wait); /* Keep the restart process from trying to send host * commands by clearing the ready bit */ diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 0c397fd635a3..c57e605b26b7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -51,6 +51,7 @@ #include "iwl-trans.h" #include "iwl-shared.h" #include "iwl-op-mode.h" +#include "iwl-notif-wait.h" struct iwl_tx_queue; @@ -739,6 +740,8 @@ struct iwl_priv { struct iwl_rx_cmd_buffer *rxb, struct iwl_device_cmd *cmd); + struct iwl_notif_wait_data notif_wait; + struct ieee80211_supported_band bands[IEEE80211_NUM_BANDS]; /* spectrum measurement report caching */ diff --git a/drivers/net/wireless/iwlwifi/iwl-notif-wait.c b/drivers/net/wireless/iwlwifi/iwl-notif-wait.c new file mode 100644 index 000000000000..88dc4a0f96b4 --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-notif-wait.c @@ -0,0 +1,157 @@ +/****************************************************************************** + * + * This file is provided under a dual BSD/GPLv2 license. When using or + * redistributing this file, you may do so under either license. + * + * GPL LICENSE SUMMARY + * + * Copyright(c) 2007 - 2012 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, + * USA + * + * The full GNU General Public License is included in this distribution + * in the file called LICENSE.GPL. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + * BSD LICENSE + * + * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, 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. + * * 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 Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER 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, WHETHER IN 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 + +#include "iwl-notif-wait.h" + + +void iwl_notification_wait_init(struct iwl_notif_wait_data *notif_wait) +{ + spin_lock_init(¬if_wait->notif_wait_lock); + INIT_LIST_HEAD(¬if_wait->notif_waits); + init_waitqueue_head(¬if_wait->notif_waitq); +} + +void iwl_notification_wait_notify(struct iwl_notif_wait_data *notif_wait, + struct iwl_rx_packet *pkt) +{ + if (!list_empty(¬if_wait->notif_waits)) { + struct iwl_notification_wait *w; + + spin_lock(¬if_wait->notif_wait_lock); + list_for_each_entry(w, ¬if_wait->notif_waits, list) { + if (w->cmd != pkt->hdr.cmd) + continue; + w->triggered = true; + if (w->fn) + w->fn(notif_wait, pkt, w->fn_data); + } + spin_unlock(¬if_wait->notif_wait_lock); + + wake_up_all(¬if_wait->notif_waitq); + } +} + +void iwl_abort_notification_waits(struct iwl_notif_wait_data *notif_wait) +{ + unsigned long flags; + struct iwl_notification_wait *wait_entry; + + spin_lock_irqsave(¬if_wait->notif_wait_lock, flags); + list_for_each_entry(wait_entry, ¬if_wait->notif_waits, list) + wait_entry->aborted = true; + spin_unlock_irqrestore(¬if_wait->notif_wait_lock, flags); + + wake_up_all(¬if_wait->notif_waitq); +} + + +void +iwl_init_notification_wait(struct iwl_notif_wait_data *notif_wait, + struct iwl_notification_wait *wait_entry, + u8 cmd, + void (*fn)(struct iwl_notif_wait_data *notif_wait, + struct iwl_rx_packet *pkt, void *data), + void *fn_data) +{ + wait_entry->fn = fn; + wait_entry->fn_data = fn_data; + wait_entry->cmd = cmd; + wait_entry->triggered = false; + wait_entry->aborted = false; + + spin_lock_bh(¬if_wait->notif_wait_lock); + list_add(&wait_entry->list, ¬if_wait->notif_waits); + spin_unlock_bh(¬if_wait->notif_wait_lock); +} + +int iwl_wait_notification(struct iwl_notif_wait_data *notif_wait, + struct iwl_notification_wait *wait_entry, + unsigned long timeout) +{ + int ret; + + ret = wait_event_timeout(notif_wait->notif_waitq, + wait_entry->triggered || wait_entry->aborted, + timeout); + + spin_lock_bh(¬if_wait->notif_wait_lock); + list_del(&wait_entry->list); + spin_unlock_bh(¬if_wait->notif_wait_lock); + + if (wait_entry->aborted) + return -EIO; + + /* return value is always >= 0 */ + if (ret <= 0) + return -ETIMEDOUT; + return 0; +} + +void iwl_remove_notification(struct iwl_notif_wait_data *notif_wait, + struct iwl_notification_wait *wait_entry) +{ + spin_lock_bh(¬if_wait->notif_wait_lock); + list_del(&wait_entry->list); + spin_unlock_bh(¬if_wait->notif_wait_lock); +} diff --git a/drivers/net/wireless/iwlwifi/iwl-notif-wait.h b/drivers/net/wireless/iwlwifi/iwl-notif-wait.h new file mode 100644 index 000000000000..419f1ad65441 --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-notif-wait.h @@ -0,0 +1,130 @@ +/****************************************************************************** + * + * This file is provided under a dual BSD/GPLv2 license. When using or + * redistributing this file, you may do so under either license. + * + * GPL LICENSE SUMMARY + * + * Copyright(c) 2007 - 2012 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, + * USA + * + * The full GNU General Public License is included in this distribution + * in the file called LICENSE.GPL. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + * BSD LICENSE + * + * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, 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. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * distribution. + * * Neither the name Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER 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, WHETHER IN 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. + * + *****************************************************************************/ +#ifndef __iwl_notif_wait_h__ +#define __iwl_notif_wait_h__ + +#include + +/* TODO: remove later */ +#include "iwl-commands.h" + +struct iwl_notif_wait_data { + struct list_head notif_waits; + spinlock_t notif_wait_lock; + wait_queue_head_t notif_waitq; +}; + +/** + * struct iwl_notification_wait - notification wait entry + * @list: list head for global list + * @fn: function called with the notification + * @cmd: command ID + * + * This structure is not used directly, to wait for a + * notification declare it on the stack, and call + * iwlagn_init_notification_wait() with appropriate + * parameters. Then do whatever will cause the ucode + * to notify the driver, and to wait for that then + * call iwlagn_wait_notification(). + * + * Each notification is one-shot. If at some point we + * need to support multi-shot notifications (which + * can't be allocated on the stack) we need to modify + * the code for them. + */ +struct iwl_notification_wait { + struct list_head list; + + void (*fn)(struct iwl_notif_wait_data *notif_data, + struct iwl_rx_packet *pkt, void *data); + void *fn_data; + + u8 cmd; + bool triggered, aborted; +}; + + +/* caller functions */ +void iwl_notification_wait_init(struct iwl_notif_wait_data *notif_data); +void iwl_notification_wait_notify(struct iwl_notif_wait_data *notif_data, + struct iwl_rx_packet *pkt); +void iwl_abort_notification_waits(struct iwl_notif_wait_data *notif_data); + +/* user functions */ +void __acquires(wait_entry) +iwl_init_notification_wait(struct iwl_notif_wait_data *notif_data, + struct iwl_notification_wait *wait_entry, + u8 cmd, + void (*fn)(struct iwl_notif_wait_data *notif_data, + struct iwl_rx_packet *pkt, void *data), + void *fn_data); + +int __must_check __releases(wait_entry) +iwl_wait_notification(struct iwl_notif_wait_data *notif_data, + struct iwl_notification_wait *wait_entry, + unsigned long timeout); + +void __releases(wait_entry) +iwl_remove_notification(struct iwl_notif_wait_data *notif_data, + struct iwl_notification_wait *wait_entry); + +#endif /* __iwl_notif_wait_h__ */ diff --git a/drivers/net/wireless/iwlwifi/iwl-shared.h b/drivers/net/wireless/iwlwifi/iwl-shared.h index 5a67fa141744..8ffc76079121 100644 --- a/drivers/net/wireless/iwlwifi/iwl-shared.h +++ b/drivers/net/wireless/iwlwifi/iwl-shared.h @@ -211,35 +211,6 @@ enum iwl_ucode_type { IWL_UCODE_WOWLAN, }; -/** - * struct iwl_notification_wait - notification wait entry - * @list: list head for global list - * @fn: function called with the notification - * @cmd: command ID - * - * This structure is not used directly, to wait for a - * notification declare it on the stack, and call - * iwlagn_init_notification_wait() with appropriate - * parameters. Then do whatever will cause the ucode - * to notify the driver, and to wait for that then - * call iwlagn_wait_notification(). - * - * Each notification is one-shot. If at some point we - * need to support multi-shot notifications (which - * can't be allocated on the stack) we need to modify - * the code for them. - */ -struct iwl_notification_wait { - struct list_head list; - - void (*fn)(struct iwl_priv *priv, struct iwl_rx_packet *pkt, - void *data); - void *fn_data; - - u8 cmd; - bool triggered, aborted; -}; - /** * enum iwl_pa_type - Power Amplifier type * @IWL_PA_SYSTEM: based on uCode configuration @@ -400,9 +371,6 @@ struct iwl_cfg { * @wait_command_queue: the wait_queue for SYNC host command nad uCode load * @eeprom: pointer to the eeprom/OTP image * @ucode_type: indicator of loaded ucode image - * @notif_waits: things waiting for notification - * @notif_wait_lock: lock protecting notification - * @notif_waitq: head of notification wait queue * @device_pointers: pointers to ucode event tables */ struct iwl_shared { @@ -428,11 +396,6 @@ struct iwl_shared { /* ucode related variables */ enum iwl_ucode_type ucode_type; - /* notification wait support */ - struct list_head notif_waits; - spinlock_t notif_wait_lock; - wait_queue_head_t notif_waitq; - struct { u32 error_event_table; u32 log_event_table; @@ -462,24 +425,6 @@ int iwlagn_hw_valid_rtc_data_addr(u32 addr); void iwl_nic_config(struct iwl_priv *priv); const char *get_cmd_string(u8 cmd); -/* notification wait support */ -void iwl_abort_notification_waits(struct iwl_shared *shrd); -void __acquires(wait_entry) -iwl_init_notification_wait(struct iwl_shared *shrd, - struct iwl_notification_wait *wait_entry, - u8 cmd, - void (*fn)(struct iwl_priv *priv, - struct iwl_rx_packet *pkt, - void *data), - void *fn_data); -int __must_check __releases(wait_entry) -iwl_wait_notification(struct iwl_shared *shrd, - struct iwl_notification_wait *wait_entry, - unsigned long timeout); -void __releases(wait_entry) -iwl_remove_notification(struct iwl_shared *shrd, - struct iwl_notification_wait *wait_entry); - #define IWL_CMD(x) case x: return #x /***************************************************** diff --git a/drivers/net/wireless/iwlwifi/iwl-testmode.c b/drivers/net/wireless/iwlwifi/iwl-testmode.c index 095d71dc99c4..cc049d22151f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-testmode.c +++ b/drivers/net/wireless/iwlwifi/iwl-testmode.c @@ -418,23 +418,23 @@ static int iwl_testmode_cfg_init_calib(struct iwl_priv *priv) struct iwl_notification_wait calib_wait; int ret; - iwl_init_notification_wait(priv->shrd, &calib_wait, - CALIBRATION_COMPLETE_NOTIFICATION, - NULL, NULL); + iwl_init_notification_wait(&priv->notif_wait, &calib_wait, + CALIBRATION_COMPLETE_NOTIFICATION, + NULL, NULL); ret = iwl_init_alive_start(priv); if (ret) { IWL_ERR(priv, "Fail init calibration: %d\n", ret); goto cfg_init_calib_error; } - ret = iwl_wait_notification(priv->shrd, &calib_wait, 2 * HZ); + ret = iwl_wait_notification(&priv->notif_wait, &calib_wait, 2 * HZ); if (ret) IWL_ERR(priv, "Error detecting" " CALIBRATION_COMPLETE_NOTIFICATION: %d\n", ret); return ret; cfg_init_calib_error: - iwl_remove_notification(priv->shrd, &calib_wait); + iwl_remove_notification(&priv->notif_wait, &calib_wait); return ret; } diff --git a/drivers/net/wireless/iwlwifi/iwl-ucode.c b/drivers/net/wireless/iwlwifi/iwl-ucode.c index 686d456d226e..4d34327f9425 100644 --- a/drivers/net/wireless/iwlwifi/iwl-ucode.c +++ b/drivers/net/wireless/iwlwifi/iwl-ucode.c @@ -29,7 +29,6 @@ #include #include -#include #include "iwl-dev.h" #include "iwl-core.h" @@ -434,10 +433,12 @@ struct iwl_alive_data { u8 subtype; }; -static void iwl_alive_fn(struct iwl_priv *priv, +static void iwl_alive_fn(struct iwl_notif_wait_data *notif_wait, struct iwl_rx_packet *pkt, void *data) { + struct iwl_priv *priv = + container_of(notif_wait, struct iwl_priv, notif_wait); struct iwl_alive_data *alive_data = data; struct iwl_alive_resp *palive; @@ -457,70 +458,6 @@ static void iwl_alive_fn(struct iwl_priv *priv, alive_data->valid = palive->is_valid == UCODE_VALID_OK; } -/* notification wait support */ -void iwl_init_notification_wait(struct iwl_shared *shrd, - struct iwl_notification_wait *wait_entry, - u8 cmd, - void (*fn)(struct iwl_priv *priv, - struct iwl_rx_packet *pkt, - void *data), - void *fn_data) -{ - wait_entry->fn = fn; - wait_entry->fn_data = fn_data; - wait_entry->cmd = cmd; - wait_entry->triggered = false; - wait_entry->aborted = false; - - spin_lock_bh(&shrd->notif_wait_lock); - list_add(&wait_entry->list, &shrd->notif_waits); - spin_unlock_bh(&shrd->notif_wait_lock); -} - -int iwl_wait_notification(struct iwl_shared *shrd, - struct iwl_notification_wait *wait_entry, - unsigned long timeout) -{ - int ret; - - ret = wait_event_timeout(shrd->notif_waitq, - wait_entry->triggered || wait_entry->aborted, - timeout); - - spin_lock_bh(&shrd->notif_wait_lock); - list_del(&wait_entry->list); - spin_unlock_bh(&shrd->notif_wait_lock); - - if (wait_entry->aborted) - return -EIO; - - /* return value is always >= 0 */ - if (ret <= 0) - return -ETIMEDOUT; - return 0; -} - -void iwl_remove_notification(struct iwl_shared *shrd, - struct iwl_notification_wait *wait_entry) -{ - spin_lock_bh(&shrd->notif_wait_lock); - list_del(&wait_entry->list); - spin_unlock_bh(&shrd->notif_wait_lock); -} - -void iwl_abort_notification_waits(struct iwl_shared *shrd) -{ - unsigned long flags; - struct iwl_notification_wait *wait_entry; - - spin_lock_irqsave(&shrd->notif_wait_lock, flags); - list_for_each_entry(wait_entry, &shrd->notif_waits, list) - wait_entry->aborted = true; - spin_unlock_irqrestore(&shrd->notif_wait_lock, flags); - - wake_up_all(&shrd->notif_waitq); -} - #define UCODE_ALIVE_TIMEOUT HZ #define UCODE_CALIB_TIMEOUT (2*HZ) @@ -540,13 +477,13 @@ int iwl_load_ucode_wait_alive(struct iwl_priv *priv, if (!fw) return -EINVAL; - iwl_init_notification_wait(priv->shrd, &alive_wait, REPLY_ALIVE, + iwl_init_notification_wait(&priv->notif_wait, &alive_wait, REPLY_ALIVE, iwl_alive_fn, &alive_data); ret = iwl_trans_start_fw(trans(priv), fw); if (ret) { priv->shrd->ucode_type = old_type; - iwl_remove_notification(priv->shrd, &alive_wait); + iwl_remove_notification(&priv->notif_wait, &alive_wait); return ret; } @@ -554,7 +491,7 @@ int iwl_load_ucode_wait_alive(struct iwl_priv *priv, * Some things may run in the background now, but we * just wait for the ALIVE notification here. */ - ret = iwl_wait_notification(priv->shrd, &alive_wait, + ret = iwl_wait_notification(&priv->notif_wait, &alive_wait, UCODE_ALIVE_TIMEOUT); if (ret) { priv->shrd->ucode_type = old_type; @@ -608,7 +545,7 @@ int iwl_run_init_ucode(struct iwl_priv *priv) if (priv->shrd->ucode_type != IWL_UCODE_NONE) return 0; - iwl_init_notification_wait(priv->shrd, &calib_wait, + iwl_init_notification_wait(&priv->notif_wait, &calib_wait, CALIBRATION_COMPLETE_NOTIFICATION, NULL, NULL); @@ -625,13 +562,13 @@ int iwl_run_init_ucode(struct iwl_priv *priv) * Some things may run in the background now, but we * just wait for the calibration complete notification. */ - ret = iwl_wait_notification(priv->shrd, &calib_wait, + ret = iwl_wait_notification(&priv->notif_wait, &calib_wait, UCODE_CALIB_TIMEOUT); goto out; error: - iwl_remove_notification(priv->shrd, &calib_wait); + iwl_remove_notification(&priv->notif_wait, &calib_wait); out: /* Whatever happened, stop the device */ iwl_trans_stop_device(trans(priv)); -- cgit From 947a9407e34e7c8d44a0f4d95bbb1e5eae5459c0 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 6 Mar 2012 13:30:59 -0800 Subject: iwlwifi: move ucode_owner to priv The transport doesn't really need to know as we can enforce it in the command wrapper. Move the ucode_owner variable into priv and do all enforcing there. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 6 ++++++ drivers/net/wireless/iwlwifi/iwl-agn-rx.c | 2 +- drivers/net/wireless/iwlwifi/iwl-agn.c | 2 ++ drivers/net/wireless/iwlwifi/iwl-dev.h | 4 ++++ drivers/net/wireless/iwlwifi/iwl-shared.h | 4 ---- drivers/net/wireless/iwlwifi/iwl-testmode.c | 2 +- drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c | 6 ------ drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | 1 - 8 files changed, 14 insertions(+), 13 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index 90f1f8a506f2..dec2693c8cba 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -1306,6 +1306,12 @@ int iwl_dvm_send_cmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) if (cmd->flags & CMD_SYNC) lockdep_assert_held(&priv->mutex); + if (priv->ucode_owner == IWL_OWNERSHIP_TM && + !(cmd->flags & CMD_ON_DEMAND)) { + IWL_DEBUG_HC(priv, "tm own the uCode, no regular hcmd send\n"); + return -EIO; + } + return iwl_trans_send_cmd(trans(priv), cmd); } diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c index f17142bb5df1..08de306c4c22 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c @@ -1165,7 +1165,7 @@ int iwl_rx_dispatch(struct iwl_op_mode *op_mode, struct iwl_rx_cmd_buffer *rxb, iwl_notification_wait_notify(&priv->notif_wait, pkt); if (priv->pre_rx_handler && - priv->shrd->ucode_owner == IWL_OWNERSHIP_TM) + priv->ucode_owner == IWL_OWNERSHIP_TM) priv->pre_rx_handler(priv, rxb); else { /* Based on type of command response or notification, diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index ce62a2fcd67f..afded2947edd 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -1053,6 +1053,8 @@ static int iwl_init_drv(struct iwl_priv *priv) priv->missed_beacon_threshold = IWL_MISSED_BEACON_THRESHOLD_DEF; priv->agg_tids_count = 0; + priv->ucode_owner = IWL_OWNERSHIP_DRIVER; + /* initialize force reset */ priv->force_reset[IWL_RF_RESET].reset_duration = IWL_DELAY_NEXT_FORCE_RF_RESET; diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index c57e605b26b7..a301daf18fbc 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -748,6 +748,10 @@ struct iwl_priv { struct iwl_spectrum_notification measure_report; u8 measurement_status; +#define IWL_OWNERSHIP_DRIVER 0 +#define IWL_OWNERSHIP_TM 1 + u8 ucode_owner; + /* ucode beacon time */ u32 ucode_beacon_time; int missed_beacon_threshold; diff --git a/drivers/net/wireless/iwlwifi/iwl-shared.h b/drivers/net/wireless/iwlwifi/iwl-shared.h index 8ffc76079121..a648a2b4934a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-shared.h +++ b/drivers/net/wireless/iwlwifi/iwl-shared.h @@ -356,7 +356,6 @@ struct iwl_cfg { /** * struct iwl_shared - shared fields for all the layers of the driver * - * @ucode_owner: IWL_OWNERSHIP_* * @cmd_queue: command queue number * @status: STATUS_* * @wowlan: are we running wowlan uCode @@ -374,9 +373,6 @@ struct iwl_cfg { * @device_pointers: pointers to ucode event tables */ struct iwl_shared { -#define IWL_OWNERSHIP_DRIVER 0 -#define IWL_OWNERSHIP_TM 1 - u8 ucode_owner; u8 cmd_queue; unsigned long status; u8 valid_contexts; diff --git a/drivers/net/wireless/iwlwifi/iwl-testmode.c b/drivers/net/wireless/iwlwifi/iwl-testmode.c index cc049d22151f..63868df32263 100644 --- a/drivers/net/wireless/iwlwifi/iwl-testmode.c +++ b/drivers/net/wireless/iwlwifi/iwl-testmode.c @@ -770,7 +770,7 @@ static int iwl_testmode_ownership(struct ieee80211_hw *hw, struct nlattr **tb) owner = nla_get_u8(tb[IWL_TM_ATTR_UCODE_OWNER]); if ((owner == IWL_OWNERSHIP_DRIVER) || (owner == IWL_OWNERSHIP_TM)) - priv->shrd->ucode_owner = owner; + priv->ucode_owner = owner; else { IWL_ERR(priv, "Invalid owner\n"); return -EINVAL; diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c index 7feeb2d52146..73febc9726cb 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c @@ -685,12 +685,6 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd) return -EIO; } - if ((trans->shrd->ucode_owner == IWL_OWNERSHIP_TM) && - !(cmd->flags & CMD_ON_DEMAND)) { - IWL_DEBUG_HC(trans, "tm own the uCode, no regular hcmd send\n"); - return -EIO; - } - copy_size = sizeof(out_cmd->hdr); cmd_size = sizeof(out_cmd->hdr); diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c index 6090e9800ce4..598a92d50895 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c @@ -1022,7 +1022,6 @@ static int iwl_trans_pcie_start_fw(struct iwl_trans *trans, IWL_TRANS_GET_PCIE_TRANS(trans); bool hw_rfkill; - trans->shrd->ucode_owner = IWL_OWNERSHIP_DRIVER; trans_pcie->ac_to_queue[IWL_RXON_CTX_BSS] = iwlagn_bss_ac_to_queue; trans_pcie->ac_to_queue[IWL_RXON_CTX_PAN] = iwlagn_pan_ac_to_queue; -- cgit From 13df1aab4aa3cd99693c0cdeb7177e5359218431 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 6 Mar 2012 13:31:00 -0800 Subject: iwlwifi: move all uCode load variables All variables related to uCode loading (the waitqueue and done indication) should be in the PCI-E transport's private data as this is transport specific. Move them there. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-shared.h | 2 +- drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h | 6 ++++++ drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c | 4 ++-- drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | 8 +++++--- drivers/net/wireless/iwlwifi/iwl-trans.h | 3 --- 5 files changed, 14 insertions(+), 9 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-shared.h b/drivers/net/wireless/iwlwifi/iwl-shared.h index a648a2b4934a..6b1c29b9bae8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-shared.h +++ b/drivers/net/wireless/iwlwifi/iwl-shared.h @@ -367,7 +367,7 @@ struct iwl_cfg { * @nic: pointer to the nic data * @hw_params: see struct iwl_hw_params * @lock: protect general shared data - * @wait_command_queue: the wait_queue for SYNC host command nad uCode load + * @wait_command_queue: the wait_queue for SYNC host commands * @eeprom: pointer to the eeprom/OTP image * @ucode_type: indicator of loaded ucode image * @device_pointers: pointers to ucode event tables diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h index 44952c371d33..93f49acac31b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h @@ -32,6 +32,7 @@ #include #include #include +#include #include #include "iwl-fh.h" @@ -243,6 +244,8 @@ struct iwl_tx_queue { * queue_stop_count: tracks what SW queue is stopped * @pci_dev: basic pci-network driver stuff * @hw_base: pci hardware address support + * @ucode_write_complete: indicates that the ucode has been copied. + * @ucode_write_waitq: wait queue for uCode load */ struct iwl_trans_pcie { struct iwl_rx_queue rxq; @@ -279,6 +282,9 @@ struct iwl_trans_pcie { /* PCI bus related data */ struct pci_dev *pci_dev; void __iomem *hw_base; + + bool ucode_write_complete; + wait_queue_head_t ucode_write_waitq; }; #define IWL_TRANS_GET_PCIE_TRANS(_iwl_trans) \ diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c index f1456211c294..83cc60e8f607 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c @@ -1114,8 +1114,8 @@ void iwl_irq_tasklet(struct iwl_trans *trans) isr_stats->tx++; handled |= CSR_INT_BIT_FH_TX; /* Wake up uCode load routine, now that load is complete */ - trans->ucode_write_complete = 1; - wake_up(&trans->shrd->wait_command_queue); + trans_pcie->ucode_write_complete = true; + wake_up(&trans_pcie->ucode_write_waitq); } if (inta & ~handled) { diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c index 598a92d50895..6ee46cba2c21 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c @@ -947,11 +947,12 @@ static const u8 iwlagn_pan_ac_to_queue[] = { static int iwl_load_section(struct iwl_trans *trans, const char *name, const struct fw_desc *image, u32 dst_addr) { + struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); dma_addr_t phy_addr = image->p_addr; u32 byte_cnt = image->len; int ret; - trans->ucode_write_complete = 0; + trans_pcie->ucode_write_complete = false; iwl_write_direct32(trans, FH_TCSR_CHNL_TX_CONFIG_REG(FH_SRVC_CHNL), @@ -982,8 +983,8 @@ static int iwl_load_section(struct iwl_trans *trans, const char *name, FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_ENDTFD); IWL_DEBUG_FW(trans, "%s uCode section being loaded...\n", name); - ret = wait_event_timeout(trans->shrd->wait_command_queue, - trans->ucode_write_complete, 5 * HZ); + ret = wait_event_timeout(trans_pcie->ucode_write_waitq, + trans_pcie->ucode_write_complete, 5 * HZ); if (!ret) { IWL_ERR(trans, "Could not load the %s uCode section\n", name); @@ -2255,6 +2256,7 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct iwl_shared *shrd, trans->shrd = shrd; trans_pcie->trans = trans; spin_lock_init(&trans_pcie->irq_lock); + init_waitqueue_head(&trans_pcie->ucode_write_waitq); /* W/A - seems to solve weird behavior. We need to remove this if we * don't want to stay in L1 all the time. This wastes a lot of power */ diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index a8d476a44c58..dcad69491786 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h @@ -338,7 +338,6 @@ enum iwl_trans_state { * @hw_id: a u32 with the ID of the device / subdevice. * Set during transport allocation. * @hw_id_str: a string with info about HW ID. Set during transport allocation. - * @ucode_write_complete: indicates that the ucode has been copied. * @nvm_device_type: indicates OTP or eeprom * @pm_support: set to true in start_hw if link pm is supported */ @@ -355,8 +354,6 @@ struct iwl_trans { u32 hw_id; char hw_id_str[52]; - u8 ucode_write_complete; - int nvm_device_type; bool pm_support; -- cgit From 7559553660da6cda3aa798c4e8eb681b63402819 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 6 Mar 2012 13:31:01 -0800 Subject: iwlwifi: move irq to PCIe Even if the variable might also be used by other transports, there's no need for anything outside of the transport itself to access it, so move it into the private area. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h | 2 ++ drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | 12 ++++++------ drivers/net/wireless/iwlwifi/iwl-trans.h | 2 -- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h index 93f49acac31b..d13b8d1f08fa 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h @@ -231,6 +231,7 @@ struct iwl_tx_queue { * @rxq: all the RX queue data * @rx_replenish: work that will be called when buffers need to be allocated * @trans: pointer to the generic transport area + * @irq - the irq number for the device * @irq_requested: true when the irq has been requested * @scd_base_addr: scheduler sram base address in SRAM * @scd_bc_tbls: pointer to the byte count table of the scheduler @@ -262,6 +263,7 @@ struct iwl_trans_pcie { struct tasklet_struct irq_tasklet; struct isr_statistics isr_stats; + unsigned int irq; spinlock_t irq_lock; u32 inta_mask; u32 scd_base_addr; diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c index 6ee46cba2c21..16cb4a3511e1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c @@ -1294,7 +1294,7 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans) spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); /* wait to make sure we flush pending tasklet*/ - synchronize_irq(trans->irq); + synchronize_irq(trans_pcie->irq); tasklet_kill(&trans_pcie->irq_tasklet); cancel_work_sync(&trans_pcie->rx_replenish); @@ -1513,11 +1513,11 @@ static int iwl_trans_pcie_start_hw(struct iwl_trans *trans) iwl_alloc_isr_ict(trans); - err = request_irq(trans->irq, iwl_isr_ict, IRQF_SHARED, + err = request_irq(trans_pcie->irq, iwl_isr_ict, IRQF_SHARED, DRV_NAME, trans); if (err) { IWL_ERR(trans, "Error allocating IRQ %d\n", - trans->irq); + trans_pcie->irq); goto error; } @@ -1540,7 +1540,7 @@ static int iwl_trans_pcie_start_hw(struct iwl_trans *trans) return err; err_free_irq: - free_irq(trans->irq, trans); + free_irq(trans_pcie->irq, trans); error: iwl_free_isr_ict(trans); tasklet_kill(&trans_pcie->irq_tasklet); @@ -1629,7 +1629,7 @@ static void iwl_trans_pcie_free(struct iwl_trans *trans) iwl_trans_pcie_rx_free(trans); #endif if (trans_pcie->irq_requested == true) { - free_irq(trans->irq, trans); + free_irq(trans_pcie->irq, trans); iwl_free_isr_ict(trans); } @@ -2318,7 +2318,7 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct iwl_shared *shrd, "pci_enable_msi failed(0X%x)", err); trans->dev = &pdev->dev; - trans->irq = pdev->irq; + trans_pcie->irq = pdev->irq; trans_pcie->pci_dev = pdev; trans->hw_rev = iwl_read32(trans, CSR_HW_REV); trans->hw_id = (pdev->device << 16) + pdev->subsystem_device; diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index dcad69491786..a4a9efce7a7c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h @@ -334,7 +334,6 @@ enum iwl_trans_state { * @shrd - pointer to iwl_shared which holds shared data from the upper layer * @reg_lock - protect hw register access * @dev - pointer to struct device * that represents the device - * @irq - the irq number for the device * @hw_id: a u32 with the ID of the device / subdevice. * Set during transport allocation. * @hw_id_str: a string with info about HW ID. Set during transport allocation. @@ -349,7 +348,6 @@ struct iwl_trans { spinlock_t reg_lock; struct device *dev; - unsigned int irq; u32 hw_rev; u32 hw_id; char hw_id_str[52]; -- cgit From f8d7c1a18d5e77b17b5cc1ebefa21eaea7f2d0fa Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 6 Mar 2012 13:31:02 -0800 Subject: iwlwifi: move packet to transport The base packet structure will (hopefully) be the same for all transports, but what is in it differs. Remove the union of all the possible contents and move the packet itself into the transport header file. This requires changing all users of the union to just use pkt->data. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 2 +- drivers/net/wireless/iwlwifi/iwl-agn-rx.c | 50 ++++++++-------- drivers/net/wireless/iwlwifi/iwl-agn-sta.c | 8 ++- drivers/net/wireless/iwlwifi/iwl-agn-tx.c | 4 +- drivers/net/wireless/iwlwifi/iwl-commands.h | 84 --------------------------- drivers/net/wireless/iwlwifi/iwl-notif-wait.h | 3 +- drivers/net/wireless/iwlwifi/iwl-scan.c | 21 ++++--- drivers/net/wireless/iwlwifi/iwl-trans.h | 56 ++++++++++++++++++ drivers/net/wireless/iwlwifi/iwl-ucode.c | 4 +- 9 files changed, 103 insertions(+), 129 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index dec2693c8cba..b2ee1f9373c0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -710,7 +710,7 @@ int iwlagn_bt_coex_profile_notif(struct iwl_priv *priv, struct iwl_device_cmd *cmd) { struct iwl_rx_packet *pkt = rxb_addr(rxb); - struct iwl_bt_coex_profile_notif *coex = &pkt->u.bt_coex_profile_notif; + struct iwl_bt_coex_profile_notif *coex = (void *)pkt->data; struct iwl_bt_uart_msg *uart_msg = &coex->last_bt_uart_msg; if (priv->bt_enable_flag == IWLAGN_BT_FLAG_COEX_MODE_DISABLED) { diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c index 08de306c4c22..521c820ea10a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c @@ -135,14 +135,15 @@ static int iwlagn_rx_reply_error(struct iwl_priv *priv, struct iwl_device_cmd *cmd) { struct iwl_rx_packet *pkt = rxb_addr(rxb); + struct iwl_error_resp *err_resp = (void *)pkt->data; IWL_ERR(priv, "Error Reply type 0x%08X cmd %s (0x%02X) " "seq 0x%04X ser 0x%08X\n", - le32_to_cpu(pkt->u.err_resp.error_type), - get_cmd_string(pkt->u.err_resp.cmd_id), - pkt->u.err_resp.cmd_id, - le16_to_cpu(pkt->u.err_resp.bad_cmd_seq_num), - le32_to_cpu(pkt->u.err_resp.error_info)); + le32_to_cpu(err_resp->error_type), + get_cmd_string(err_resp->cmd_id), + err_resp->cmd_id, + le16_to_cpu(err_resp->bad_cmd_seq_num), + le32_to_cpu(err_resp->error_info)); return 0; } @@ -150,7 +151,7 @@ static int iwlagn_rx_csa(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb, struct iwl_device_cmd *cmd) { struct iwl_rx_packet *pkt = rxb_addr(rxb); - struct iwl_csa_notification *csa = &(pkt->u.csa_notif); + struct iwl_csa_notification *csa = (void *)pkt->data; /* * MULTI-FIXME * See iwlagn_mac_channel_switch. @@ -181,7 +182,7 @@ static int iwlagn_rx_spectrum_measure_notif(struct iwl_priv *priv, struct iwl_device_cmd *cmd) { struct iwl_rx_packet *pkt = rxb_addr(rxb); - struct iwl_spectrum_notification *report = &(pkt->u.spectrum_notif); + struct iwl_spectrum_notification *report = (void *)pkt->data; if (!report->state) { IWL_DEBUG_11H(priv, @@ -200,7 +201,7 @@ static int iwlagn_rx_pm_sleep_notif(struct iwl_priv *priv, { #ifdef CONFIG_IWLWIFI_DEBUG struct iwl_rx_packet *pkt = rxb_addr(rxb); - struct iwl_sleep_notification *sleep = &(pkt->u.sleep_notif); + struct iwl_sleep_notification *sleep = (void *)pkt->data; IWL_DEBUG_RX(priv, "sleep mode: %d, src: %d\n", sleep->pm_sleep_mode, sleep->pm_wakeup_src); #endif @@ -217,7 +218,7 @@ static int iwlagn_rx_pm_debug_statistics_notif(struct iwl_priv *priv, IWL_DEBUG_RADIO(priv, "Dumping %d bytes of unhandled " "notification for %s:\n", len, get_cmd_string(pkt->hdr.cmd)); - iwl_print_hex_dump(priv, IWL_DL_RADIO, pkt->u.raw, len); + iwl_print_hex_dump(priv, IWL_DL_RADIO, pkt->data, len); return 0; } @@ -226,7 +227,7 @@ static int iwlagn_rx_beacon_notif(struct iwl_priv *priv, struct iwl_device_cmd *cmd) { struct iwl_rx_packet *pkt = rxb_addr(rxb); - struct iwlagn_beacon_notif *beacon = (void *)pkt->u.raw; + struct iwlagn_beacon_notif *beacon = (void *)pkt->data; #ifdef CONFIG_IWLWIFI_DEBUG u16 status = le16_to_cpu(beacon->beacon_notify_hdr.status.status); u8 rate = iwl_hw_get_rate(beacon->beacon_notify_hdr.rate_n_flags); @@ -515,7 +516,7 @@ static int iwlagn_rx_statistics(struct iwl_priv *priv, if (len == sizeof(struct iwl_bt_notif_statistics)) { struct iwl_bt_notif_statistics *stats; - stats = &pkt->u.stats_bt; + stats = (void *)&pkt->data; flag = &stats->flag; common = &stats->general.common; rx_non_phy = &stats->rx.general.common; @@ -533,7 +534,7 @@ static int iwlagn_rx_statistics(struct iwl_priv *priv, #endif } else if (len == sizeof(struct iwl_notif_statistics)) { struct iwl_notif_statistics *stats; - stats = &pkt->u.stats; + stats = (void *)&pkt->data; flag = &stats->flag; common = &stats->general.common; rx_non_phy = &stats->rx.general; @@ -601,8 +602,9 @@ static int iwlagn_rx_reply_statistics(struct iwl_priv *priv, struct iwl_device_cmd *cmd) { struct iwl_rx_packet *pkt = rxb_addr(rxb); + struct iwl_notif_statistics *stats = (void *)pkt->data; - if (le32_to_cpu(pkt->u.stats.flag) & UCODE_STATISTICS_CLEAR_MSK) { + if (le32_to_cpu(stats->flag) & UCODE_STATISTICS_CLEAR_MSK) { #ifdef CONFIG_IWLWIFI_DEBUGFS memset(&priv->accum_stats, 0, sizeof(priv->accum_stats)); @@ -624,7 +626,8 @@ static int iwlagn_rx_card_state_notif(struct iwl_priv *priv, struct iwl_device_cmd *cmd) { struct iwl_rx_packet *pkt = rxb_addr(rxb); - u32 flags = le32_to_cpu(pkt->u.card_state_notif.flags); + struct iwl_card_state_notif *card_state_notif = (void *)pkt->data; + u32 flags = le32_to_cpu(card_state_notif->flags); unsigned long status = priv->shrd->status; IWL_DEBUG_RF_KILL(priv, "Card state received: HW:%s SW:%s CT:%s\n", @@ -678,9 +681,8 @@ static int iwlagn_rx_missed_beacon_notif(struct iwl_priv *priv, { struct iwl_rx_packet *pkt = rxb_addr(rxb); - struct iwl_missed_beacon_notif *missed_beacon; + struct iwl_missed_beacon_notif *missed_beacon = (void *)pkt->data; - missed_beacon = &pkt->u.missed_beacon; if (le32_to_cpu(missed_beacon->consecutive_missed_beacons) > priv->missed_beacon_threshold) { IWL_DEBUG_CALIB(priv, @@ -704,7 +706,7 @@ static int iwlagn_rx_reply_rx_phy(struct iwl_priv *priv, struct iwl_rx_packet *pkt = rxb_addr(rxb); priv->last_phy_res_valid = true; - memcpy(&priv->last_phy_res, pkt->u.raw, + memcpy(&priv->last_phy_res, pkt->data, sizeof(struct iwl_rx_phy_res)); return 0; } @@ -949,12 +951,12 @@ static int iwlagn_rx_reply_rx(struct iwl_priv *priv, * received. */ if (pkt->hdr.cmd == REPLY_RX) { - phy_res = (struct iwl_rx_phy_res *)pkt->u.raw; - header = (struct ieee80211_hdr *)(pkt->u.raw + sizeof(*phy_res) + phy_res = (struct iwl_rx_phy_res *)pkt->data; + header = (struct ieee80211_hdr *)(pkt->data + sizeof(*phy_res) + phy_res->cfg_phy_cnt); len = le16_to_cpu(phy_res->byte_count); - rx_pkt_status = *(__le32 *)(pkt->u.raw + sizeof(*phy_res) + + rx_pkt_status = *(__le32 *)(pkt->data + sizeof(*phy_res) + phy_res->cfg_phy_cnt + len); ampdu_status = le32_to_cpu(rx_pkt_status); } else { @@ -963,10 +965,10 @@ static int iwlagn_rx_reply_rx(struct iwl_priv *priv, return 0; } phy_res = &priv->last_phy_res; - amsdu = (struct iwl_rx_mpdu_res_start *)pkt->u.raw; - header = (struct ieee80211_hdr *)(pkt->u.raw + sizeof(*amsdu)); + amsdu = (struct iwl_rx_mpdu_res_start *)pkt->data; + header = (struct ieee80211_hdr *)(pkt->data + sizeof(*amsdu)); len = le16_to_cpu(amsdu->byte_count); - rx_pkt_status = *(__le32 *)(pkt->u.raw + sizeof(*amsdu) + len); + rx_pkt_status = *(__le32 *)(pkt->data + sizeof(*amsdu) + len); ampdu_status = iwlagn_translate_rx_status(priv, le32_to_cpu(rx_pkt_status)); } @@ -1051,7 +1053,7 @@ static int iwlagn_rx_noa_notification(struct iwl_priv *priv, { struct iwl_wipan_noa_data *new_data, *old_data; struct iwl_rx_packet *pkt = rxb_addr(rxb); - struct iwl_wipan_noa_notification *noa_notif = (void *)pkt->u.raw; + struct iwl_wipan_noa_notification *noa_notif = (void *)pkt->data; /* no condition -- we're in softirq */ old_data = rcu_dereference_protected(priv->noa_data, true); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c index 14fbdecccd26..cb6c2300cf44 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c @@ -64,6 +64,7 @@ static int iwl_process_add_sta_resp(struct iwl_priv *priv, struct iwl_addsta_cmd *addsta, struct iwl_rx_packet *pkt) { + struct iwl_add_sta_resp *add_sta_resp = (void *)pkt->data; u8 sta_id = addsta->sta.sta_id; int ret = -EIO; @@ -78,7 +79,7 @@ static int iwl_process_add_sta_resp(struct iwl_priv *priv, spin_lock(&priv->sta_lock); - switch (pkt->u.add_sta.status) { + switch (add_sta_resp->status) { case ADD_STA_SUCCESS_MSK: IWL_DEBUG_INFO(priv, "REPLY_ADD_STA PASSED\n"); ret = iwl_sta_ucode_activate(priv, sta_id); @@ -97,7 +98,7 @@ static int iwl_process_add_sta_resp(struct iwl_priv *priv, break; default: IWL_DEBUG_ASSOC(priv, "Received REPLY_ADD_STA:(0x%08X)\n", - pkt->u.add_sta.status); + add_sta_resp->status); break; } @@ -460,7 +461,8 @@ static int iwl_send_remove_station(struct iwl_priv *priv, } if (!ret) { - switch (pkt->u.rem_sta.status) { + struct iwl_rem_sta_resp *rem_sta_resp = (void *)pkt->data; + switch (rem_sta_resp->status) { case REM_STA_SUCCESS_MSK: if (!temporary) { spin_lock_bh(&priv->sta_lock); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c index 151400cf51e0..0ef59d9a99ee 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c @@ -983,7 +983,7 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb, u16 sequence = le16_to_cpu(pkt->hdr.sequence); int txq_id = SEQ_TO_QUEUE(sequence); int cmd_index __maybe_unused = SEQ_TO_INDEX(sequence); - struct iwlagn_tx_resp *tx_resp = (void *)&pkt->u.raw[0]; + struct iwlagn_tx_resp *tx_resp = (void *)pkt->data; struct ieee80211_hdr *hdr; u32 status = le16_to_cpu(tx_resp->status.status); u16 ssn = iwlagn_get_scd_ssn(tx_resp); @@ -1111,7 +1111,7 @@ int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv, struct iwl_device_cmd *cmd) { struct iwl_rx_packet *pkt = rxb_addr(rxb); - struct iwl_compressed_ba_resp *ba_resp = &pkt->u.compressed_ba; + struct iwl_compressed_ba_resp *ba_resp = (void *)pkt->data; struct iwl_ht_agg *agg; struct sk_buff_head reclaimed_skbs; struct ieee80211_tx_info *info; diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index aa8993065cdf..70ba962732f7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h @@ -206,48 +206,6 @@ enum { /* iwl_cmd_header flags value */ #define IWL_CMD_FAILED_MSK 0x40 -#define SEQ_TO_QUEUE(s) (((s) >> 8) & 0x1f) -#define QUEUE_TO_SEQ(q) (((q) & 0x1f) << 8) -#define SEQ_TO_INDEX(s) ((s) & 0xff) -#define INDEX_TO_SEQ(i) ((i) & 0xff) -#define SEQ_RX_FRAME cpu_to_le16(0x8000) - -/** - * struct iwl_cmd_header - * - * This header format appears in the beginning of each command sent from the - * driver, and each response/notification received from uCode. - */ -struct iwl_cmd_header { - u8 cmd; /* Command ID: REPLY_RXON, etc. */ - u8 flags; /* 0:5 reserved, 6 abort, 7 internal */ - /* - * The driver sets up the sequence number to values of its choosing. - * uCode does not use this value, but passes it back to the driver - * when sending the response to each driver-originated command, so - * the driver can match the response to the command. Since the values - * don't get used by uCode, the driver may set up an arbitrary format. - * - * There is one exception: uCode sets bit 15 when it originates - * the response/notification, i.e. when the response/notification - * is not a direct response to a command sent by the driver. For - * example, uCode issues REPLY_RX when it sends a received frame - * to the driver; it is not a direct response to any driver command. - * - * The Linux driver uses the following format: - * - * 0:7 tfd index - position within TX queue - * 8:12 TX queue id - * 13:14 reserved - * 15 unsolicited RX or uCode-originated notification - */ - __le16 sequence; - - /* command or response/notification data follows immediately */ - u8 data[0]; -} __packed; - - /** * iwlagn rate_n_flags bit fields * @@ -3893,48 +3851,6 @@ struct iwlagn_wowlan_kek_kck_material_cmd { __le64 replay_ctr; } __packed; -/****************************************************************************** - * (13) - * Union of all expected notifications/responses: - * - *****************************************************************************/ -#define FH_RSCSR_FRAME_SIZE_MSK (0x00003FFF) /* bits 0-13 */ - -struct iwl_rx_packet { - /* - * The first 4 bytes of the RX frame header contain both the RX frame - * size and some flags. - * Bit fields: - * 31: flag flush RB request - * 30: flag ignore TC (terminal counter) request - * 29: flag fast IRQ request - * 28-14: Reserved - * 13-00: RX frame size - */ - __le32 len_n_flags; - struct iwl_cmd_header hdr; - union { - struct iwl_alive_resp alive_frame; - struct iwl_spectrum_notification spectrum_notif; - struct iwl_csa_notification csa_notif; - struct iwl_error_resp err_resp; - struct iwl_card_state_notif card_state_notif; - struct iwl_add_sta_resp add_sta; - struct iwl_rem_sta_resp rem_sta; - struct iwl_sleep_notification sleep_notif; - struct iwl_spectrum_resp spectrum; - struct iwl_notif_statistics stats; - struct iwl_bt_notif_statistics stats_bt; - struct iwl_compressed_ba_resp compressed_ba; - struct iwl_missed_beacon_notif missed_beacon; - struct iwl_coex_medium_notification coex_medium_notif; - struct iwl_coex_event_resp coex_event; - struct iwl_bt_coex_profile_notif bt_coex_profile_notif; - __le32 status; - u8 raw[0]; - } u; -} __packed; - int iwl_agn_check_rxon_cmd(struct iwl_priv *priv); /* diff --git a/drivers/net/wireless/iwlwifi/iwl-notif-wait.h b/drivers/net/wireless/iwlwifi/iwl-notif-wait.h index 419f1ad65441..5e8af957aa7b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-notif-wait.h +++ b/drivers/net/wireless/iwlwifi/iwl-notif-wait.h @@ -64,8 +64,7 @@ #include -/* TODO: remove later */ -#include "iwl-commands.h" +#include "iwl-trans.h" struct iwl_notif_wait_data { struct list_head notif_waits; diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index 6cf2cb318882..91a14577b8a8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c @@ -57,11 +57,11 @@ static int iwl_send_scan_abort(struct iwl_priv *priv) { int ret; - struct iwl_rx_packet *pkt; struct iwl_host_cmd cmd = { .id = REPLY_SCAN_ABORT_CMD, .flags = CMD_SYNC | CMD_WANT_SKB, }; + __le32 *status; /* Exit instantly with error when device is not ready * to receive scan abort command or it does not perform @@ -76,15 +76,16 @@ static int iwl_send_scan_abort(struct iwl_priv *priv) if (ret) return ret; - pkt = cmd.resp_pkt; - if (pkt->u.status != CAN_ABORT_STATUS) { + status = (void *)cmd.resp_pkt->data; + if (*status != CAN_ABORT_STATUS) { /* The scan abort will return 1 for success or * 2 for "failure". A failure condition can be * due to simply not being in an active scan which * can occur if we send the scan abort before we * the microcode has notified us that a scan is * completed. */ - IWL_DEBUG_SCAN(priv, "SCAN_ABORT ret %d.\n", pkt->u.status); + IWL_DEBUG_SCAN(priv, "SCAN_ABORT ret %d.\n", + le32_to_cpu(*status)); ret = -EIO; } @@ -265,8 +266,7 @@ static int iwl_rx_reply_scan(struct iwl_priv *priv, { #ifdef CONFIG_IWLWIFI_DEBUG struct iwl_rx_packet *pkt = rxb_addr(rxb); - struct iwl_scanreq_notification *notif = - (struct iwl_scanreq_notification *)pkt->u.raw; + struct iwl_scanreq_notification *notif = (void *)pkt->data; IWL_DEBUG_SCAN(priv, "Scan request status = 0x%x\n", notif->status); #endif @@ -279,8 +279,8 @@ static int iwl_rx_scan_start_notif(struct iwl_priv *priv, struct iwl_device_cmd *cmd) { struct iwl_rx_packet *pkt = rxb_addr(rxb); - struct iwl_scanstart_notification *notif = - (struct iwl_scanstart_notification *)pkt->u.raw; + struct iwl_scanstart_notification *notif = (void *)pkt->data; + priv->scan_start_tsf = le32_to_cpu(notif->tsf_low); IWL_DEBUG_SCAN(priv, "Scan start: " "%d [802.11%s] " @@ -307,8 +307,7 @@ static int iwl_rx_scan_results_notif(struct iwl_priv *priv, { #ifdef CONFIG_IWLWIFI_DEBUG struct iwl_rx_packet *pkt = rxb_addr(rxb); - struct iwl_scanresults_notification *notif = - (struct iwl_scanresults_notification *)pkt->u.raw; + struct iwl_scanresults_notification *notif = (void *)pkt->data; IWL_DEBUG_SCAN(priv, "Scan ch.res: " "%d [802.11%s] " @@ -332,7 +331,7 @@ static int iwl_rx_scan_complete_notif(struct iwl_priv *priv, struct iwl_device_cmd *cmd) { struct iwl_rx_packet *pkt = rxb_addr(rxb); - struct iwl_scancomplete_notification *scan_notif = (void *)pkt->u.raw; + struct iwl_scancomplete_notification *scan_notif = (void *)pkt->data; IWL_DEBUG_SCAN(priv, "Scan complete: %d channels (TSF 0x%08X:%08X) - %d\n", scan_notif->scanned_channels, diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index a4a9efce7a7c..15bb208ab347 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h @@ -122,6 +122,62 @@ struct dentry; #define SEQ_TO_SN(seq) (((seq) & IEEE80211_SCTL_SEQ) >> 4) #define SN_TO_SEQ(ssn) (((ssn) << 4) & IEEE80211_SCTL_SEQ) #define MAX_SN ((IEEE80211_SCTL_SEQ) >> 4) +#define SEQ_TO_QUEUE(s) (((s) >> 8) & 0x1f) +#define QUEUE_TO_SEQ(q) (((q) & 0x1f) << 8) +#define SEQ_TO_INDEX(s) ((s) & 0xff) +#define INDEX_TO_SEQ(i) ((i) & 0xff) +#define SEQ_RX_FRAME cpu_to_le16(0x8000) + +/** + * struct iwl_cmd_header + * + * This header format appears in the beginning of each command sent from the + * driver, and each response/notification received from uCode. + */ +struct iwl_cmd_header { + u8 cmd; /* Command ID: REPLY_RXON, etc. */ + u8 flags; /* 0:5 reserved, 6 abort, 7 internal */ + /* + * The driver sets up the sequence number to values of its choosing. + * uCode does not use this value, but passes it back to the driver + * when sending the response to each driver-originated command, so + * the driver can match the response to the command. Since the values + * don't get used by uCode, the driver may set up an arbitrary format. + * + * There is one exception: uCode sets bit 15 when it originates + * the response/notification, i.e. when the response/notification + * is not a direct response to a command sent by the driver. For + * example, uCode issues REPLY_RX when it sends a received frame + * to the driver; it is not a direct response to any driver command. + * + * The Linux driver uses the following format: + * + * 0:7 tfd index - position within TX queue + * 8:12 TX queue id + * 13:14 reserved + * 15 unsolicited RX or uCode-originated notification + */ + __le16 sequence; +} __packed; + + +#define FH_RSCSR_FRAME_SIZE_MSK 0x00003FFF /* bits 0-13 */ + +struct iwl_rx_packet { + /* + * The first 4 bytes of the RX frame header contain both the RX frame + * size and some flags. + * Bit fields: + * 31: flag flush RB request + * 30: flag ignore TC (terminal counter) request + * 29: flag fast IRQ request + * 28-14: Reserved + * 13-00: RX frame size + */ + __le32 len_n_flags; + struct iwl_cmd_header hdr; + u8 data[]; +} __packed; /** * enum CMD_MODE - how to send the host commands ? diff --git a/drivers/net/wireless/iwlwifi/iwl-ucode.c b/drivers/net/wireless/iwlwifi/iwl-ucode.c index 4d34327f9425..8267dbe869d5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-ucode.c +++ b/drivers/net/wireless/iwlwifi/iwl-ucode.c @@ -186,7 +186,7 @@ int iwlagn_rx_calib_result(struct iwl_priv *priv, struct iwl_device_cmd *cmd) { struct iwl_rx_packet *pkt = rxb_addr(rxb); - struct iwl_calib_hdr *hdr = (struct iwl_calib_hdr *)pkt->u.raw; + struct iwl_calib_hdr *hdr = (struct iwl_calib_hdr *)pkt->data; int len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK; /* reduce the size of the length field itself */ @@ -442,7 +442,7 @@ static void iwl_alive_fn(struct iwl_notif_wait_data *notif_wait, struct iwl_alive_data *alive_data = data; struct iwl_alive_resp *palive; - palive = &pkt->u.alive_frame; + palive = (void *)pkt->data; IWL_DEBUG_FW(priv, "Alive ucode status 0x%08X revision " "0x%01X 0x%01X\n", -- cgit From ecdb975c92c6ff63673f6380b87ab1e696dfae38 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 6 Mar 2012 13:31:03 -0800 Subject: iwlwifi: virtualize nic_config The nic_config sets uCode dependent register bits, so it must be virtual in the op_mode. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn.c | 8 ++++++++ drivers/net/wireless/iwlwifi/iwl-core.c | 5 ----- drivers/net/wireless/iwlwifi/iwl-op-mode.h | 9 +++++++++ drivers/net/wireless/iwlwifi/iwl-shared.h | 1 - drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | 2 +- 5 files changed, 18 insertions(+), 7 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index afded2947edd..98f32e57f7f0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -1422,6 +1422,13 @@ static void iwl_cmd_queue_full(struct iwl_op_mode *op_mode) } } +static void iwl_nic_config(struct iwl_op_mode *op_mode) +{ + struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); + + cfg(priv)->lib->nic_config(priv); +} + const struct iwl_op_mode_ops iwl_dvm_ops = { .start = iwl_op_mode_dvm_start, .stop = iwl_op_mode_dvm_stop, @@ -1432,6 +1439,7 @@ const struct iwl_op_mode_ops iwl_dvm_ops = { .free_skb = iwl_free_skb, .nic_error = iwl_nic_error, .cmd_queue_full = iwl_cmd_queue_full, + .nic_config = iwl_nic_config, }; /***************************************************************************** diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 5f0e07c0b50c..f43f51d1570e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -1468,11 +1468,6 @@ void iwl_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state) wiphy_rfkill_set_hw_state(priv->hw->wiphy, state); } -void iwl_nic_config(struct iwl_priv *priv) -{ - cfg(priv)->lib->nic_config(priv); -} - void iwl_free_skb(struct iwl_op_mode *op_mode, struct sk_buff *skb) { struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); diff --git a/drivers/net/wireless/iwlwifi/iwl-op-mode.h b/drivers/net/wireless/iwlwifi/iwl-op-mode.h index a4a4907803ca..6ea4163ff56a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-op-mode.h +++ b/drivers/net/wireless/iwlwifi/iwl-op-mode.h @@ -123,6 +123,8 @@ struct iwl_fw; * Must be atomic * @nic_error: error notification. Must be atomic * @cmd_queue_full: Called when the command queue gets full. Must be atomic. + * @nic_config: configure NIC, called before firmware is started. + * May sleep */ struct iwl_op_mode_ops { struct iwl_op_mode *(*start)(struct iwl_trans *trans, @@ -136,6 +138,7 @@ struct iwl_op_mode_ops { void (*free_skb)(struct iwl_op_mode *op_mode, struct sk_buff *skb); void (*nic_error)(struct iwl_op_mode *op_mode); void (*cmd_queue_full)(struct iwl_op_mode *op_mode); + void (*nic_config)(struct iwl_op_mode *op_mode); }; /** @@ -199,6 +202,12 @@ static inline void iwl_op_mode_cmd_queue_full(struct iwl_op_mode *op_mode) op_mode->ops->cmd_queue_full(op_mode); } +static inline void iwl_op_mode_nic_config(struct iwl_op_mode *op_mode) +{ + might_sleep(); + op_mode->ops->nic_config(op_mode); +} + /***************************************************** * Op mode layers implementations ******************************************************/ diff --git a/drivers/net/wireless/iwlwifi/iwl-shared.h b/drivers/net/wireless/iwlwifi/iwl-shared.h index 6b1c29b9bae8..26894dbadef2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-shared.h +++ b/drivers/net/wireless/iwlwifi/iwl-shared.h @@ -418,7 +418,6 @@ enum iwl_rxon_context_id { }; int iwlagn_hw_valid_rtc_data_addr(u32 addr); -void iwl_nic_config(struct iwl_priv *priv); const char *get_cmd_string(u8 cmd); #define IWL_CMD(x) case x: return #x diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c index 16cb4a3511e1..26bb44242090 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c @@ -816,7 +816,7 @@ static int iwl_nic_init(struct iwl_trans *trans) iwl_set_pwr_vmain(trans); - iwl_nic_config(priv(trans)); + iwl_op_mode_nic_config(trans->op_mode); #ifndef CONFIG_IWLWIFI_IDI /* Allocate the RX queue, or reset if it is already allocated */ -- cgit From ef0ef9c8de7e7a069bc2c80a8687c4ab9fa9aff2 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 6 Mar 2012 13:31:04 -0800 Subject: iwlwifi: remove priv from shared Finally nothing needs to access priv from shared any more, so remove it. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn.c | 1 - drivers/net/wireless/iwlwifi/iwl-shared.h | 2 -- 2 files changed, 3 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 98f32e57f7f0..4cd375c811e2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -1205,7 +1205,6 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans, op_mode->ops = &iwl_dvm_ops; priv = IWL_OP_MODE_GET_DVM(op_mode); priv->shrd = trans->shrd; - priv->shrd->priv = priv; priv->fw = fw; /* TODO: remove fw from shared data later */ priv->shrd->fw = fw; diff --git a/drivers/net/wireless/iwlwifi/iwl-shared.h b/drivers/net/wireless/iwlwifi/iwl-shared.h index 26894dbadef2..f8bef163dea3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-shared.h +++ b/drivers/net/wireless/iwlwifi/iwl-shared.h @@ -378,7 +378,6 @@ struct iwl_shared { u8 valid_contexts; const struct iwl_cfg *cfg; - struct iwl_priv *priv; struct iwl_trans *trans; void *drv; struct iwl_hw_params hw_params; @@ -400,7 +399,6 @@ struct iwl_shared { }; /*Whatever _m is (iwl_trans, iwl_priv, these macros will work */ -#define priv(_m) ((_m)->shrd->priv) #define cfg(_m) ((_m)->shrd->cfg) #define trans(_m) ((_m)->shrd->trans) #define hw_params(_m) ((_m)->shrd->hw_params) -- cgit From 55bba9eafbaa1d63df8158967fbe69c1a4aa71b1 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 6 Mar 2012 13:31:05 -0800 Subject: iwlwifi: remove PA type configuration No need to have a special config variable for the PA type, we can just use the additional NIC config function to config the hardware correctly. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-6000.c | 17 +++++++++-------- drivers/net/wireless/iwlwifi/iwl-shared.h | 12 ------------ 2 files changed, 9 insertions(+), 20 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index d2e24824fc08..d299f05dfc9b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -96,20 +96,21 @@ static void iwl6150_additional_nic_config(struct iwl_priv *priv) CSR_GP_DRIVER_REG_BIT_6050_1x2); } +static void iwl6000i_additional_nic_config(struct iwl_priv *priv) +{ + /* 2x2 IPA phy type */ + iwl_write32(trans(priv), CSR_GP_DRIVER_REG, + CSR_GP_DRIVER_REG_BIT_RADIO_SKU_2x2_IPA); +} + /* NIC configuration for 6000 series */ static void iwl6000_nic_config(struct iwl_priv *priv) { iwl_rf_config(priv); - /* no locking required for register write */ - if (cfg(priv)->pa_type == IWL_PA_INTERNAL) { - /* 2x2 IPA phy type */ - iwl_write32(trans(priv), CSR_GP_DRIVER_REG, - CSR_GP_DRIVER_REG_BIT_RADIO_SKU_2x2_IPA); - } /* do additional nic configuration if needed */ if (cfg(priv)->additional_nic_config) - cfg(priv)->additional_nic_config(priv); + cfg(priv)->additional_nic_config(priv); } static struct iwl_sensitivity_ranges iwl6000_sensitivity = { @@ -473,8 +474,8 @@ const struct iwl_cfg iwl130_bg_cfg = { .eeprom_ver = EEPROM_6000_EEPROM_VERSION, \ .eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION, \ .lib = &iwl6000_lib, \ + .additional_nic_config = iwl6000i_additional_nic_config,\ .base_params = &iwl6000_base_params, \ - .pa_type = IWL_PA_INTERNAL, \ .led_mode = IWL_LED_BLINK const struct iwl_cfg iwl6000i_2agn_cfg = { diff --git a/drivers/net/wireless/iwlwifi/iwl-shared.h b/drivers/net/wireless/iwlwifi/iwl-shared.h index f8bef163dea3..ff3394c47635 100644 --- a/drivers/net/wireless/iwlwifi/iwl-shared.h +++ b/drivers/net/wireless/iwlwifi/iwl-shared.h @@ -211,16 +211,6 @@ enum iwl_ucode_type { IWL_UCODE_WOWLAN, }; -/** - * enum iwl_pa_type - Power Amplifier type - * @IWL_PA_SYSTEM: based on uCode configuration - * @IWL_PA_INTERNAL: use Internal only - */ -enum iwl_pa_type { - IWL_PA_SYSTEM = 0, - IWL_PA_INTERNAL = 1, -}; - /* * LED mode * IWL_LED_DEFAULT: use device default @@ -301,7 +291,6 @@ struct iwl_base_params { * @base_params: pointer to basic parameters * @ht_params: point to ht patameters * @bt_params: pointer to bt parameters - * @pa_type: used by 6000 series only to identify the type of Power Amplifier * @need_temp_offset_calib: need to perform temperature offset calibration * @no_xtal_calib: some devices do not need crystal calibration data, * don't send it to those @@ -341,7 +330,6 @@ struct iwl_cfg { /* params likely to change within a device family */ const struct iwl_ht_params *ht_params; const struct iwl_bt_params *bt_params; - enum iwl_pa_type pa_type; /* if used set to IWL_PA_SYSTEM */ const bool need_temp_offset_calib; /* if used set to true */ const bool no_xtal_calib; u8 scan_rx_antennas[IEEE80211_NUM_BANDS]; -- cgit From eae63b858f9a238a8868846dc5f27fc5e1865659 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 6 Mar 2012 13:31:06 -0800 Subject: iwlwifi: don't include iwl-prph.h everywhere It's only needed in a few places. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-1000.c | 1 + drivers/net/wireless/iwlwifi/iwl-5000.c | 1 + drivers/net/wireless/iwlwifi/iwl-dev.h | 2 -- drivers/net/wireless/iwlwifi/iwl-eeprom.c | 1 + drivers/net/wireless/iwlwifi/iwl-testmode.c | 1 + 5 files changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index 5abebc355f7f..f6e6f57aade5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c @@ -43,6 +43,7 @@ #include "iwl-agn-hw.h" #include "iwl-shared.h" #include "iwl-cfg.h" +#include "iwl-prph.h" /* Highest firmware API version supported */ #define IWL1000_UCODE_API_MAX 6 diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index 821ed3a36e52..907a0b22f7b2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -45,6 +45,7 @@ #include "iwl-trans.h" #include "iwl-shared.h" #include "iwl-cfg.h" +#include "iwl-prph.h" /* Highest firmware API version supported */ #define IWL5000_UCODE_API_MAX 5 diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index a301daf18fbc..d1e722bd9f5b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -37,11 +37,9 @@ #include #include #include -#include #include "iwl-eeprom.h" #include "iwl-csr.h" -#include "iwl-prph.h" #include "iwl-debug.h" #include "iwl-agn-hw.h" #include "iwl-led.h" diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c index f965ee333920..e2d80849001f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c @@ -75,6 +75,7 @@ #include "iwl-agn.h" #include "iwl-eeprom.h" #include "iwl-io.h" +#include "iwl-prph.h" /************************** EEPROM BANDS **************************** * diff --git a/drivers/net/wireless/iwlwifi/iwl-testmode.c b/drivers/net/wireless/iwlwifi/iwl-testmode.c index 63868df32263..5b06916be610 100644 --- a/drivers/net/wireless/iwlwifi/iwl-testmode.c +++ b/drivers/net/wireless/iwlwifi/iwl-testmode.c @@ -78,6 +78,7 @@ #include "iwl-testmode.h" #include "iwl-trans.h" #include "iwl-fh.h" +#include "iwl-prph.h" /* Periphery registers absolute lower bound. This is used in order to -- cgit From e7a0d0c4499c4dadec752459c6b15b240db4c3a8 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 6 Mar 2012 13:31:07 -0800 Subject: iwlwifi: clean up iwl-commands.h Do some cleanups here: * remove an unused prototype * remove some unused constants * clean up includes Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-sta.c | 2 +- drivers/net/wireless/iwlwifi/iwl-commands.h | 10 +--------- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c index cb6c2300cf44..cf5cc1060cf4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c @@ -26,7 +26,7 @@ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 * *****************************************************************************/ - +#include #include #include "iwl-dev.h" diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index 70ba962732f7..9ed73e5154be 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h @@ -69,15 +69,9 @@ #ifndef __iwl_commands_h__ #define __iwl_commands_h__ -#include #include +#include -struct iwl_priv; - -/* Tx rates */ -#define IWL_CCK_RATES 4 -#define IWL_OFDM_RATES 8 -#define IWL_MAX_RATES (IWL_CCK_RATES + IWL_OFDM_RATES) enum { REPLY_ALIVE = 0x1, @@ -3851,8 +3845,6 @@ struct iwlagn_wowlan_kek_kck_material_cmd { __le64 replay_ctr; } __packed; -int iwl_agn_check_rxon_cmd(struct iwl_priv *priv); - /* * REPLY_WIPAN_PARAMS = 0xb2 (Commands and Notification) */ -- cgit From b443d8d8a2b4c3def4b47c17a44bb17ea0a3202f Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 6 Mar 2012 13:31:08 -0800 Subject: iwlwifi: make iwl_fill_probe_req static This function is only used in iwl-scan.c, so if we move it up a little in the file it can be made static. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-core.h | 2 - drivers/net/wireless/iwlwifi/iwl-scan.c | 98 ++++++++++++++++----------------- 2 files changed, 49 insertions(+), 51 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 7259cbf77da4..e0423c4c01c7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -202,8 +202,6 @@ void iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms); void iwl_force_scan_end(struct iwl_priv *priv); void iwl_internal_short_hw_scan(struct iwl_priv *priv); int iwl_force_reset(struct iwl_priv *priv, int mode, bool external); -u16 iwl_fill_probe_req(struct iwl_priv *priv, struct ieee80211_mgmt *frame, - const u8 *ta, const u8 *ie, int ie_len, int left); void iwl_setup_rx_scan_handlers(struct iwl_priv *priv); void iwl_setup_scan_deferred_work(struct iwl_priv *priv); void iwl_cancel_scan_deferred_work(struct iwl_priv *priv); diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index 91a14577b8a8..8c3fb3233d9f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c @@ -572,6 +572,53 @@ static int iwl_get_channels_for_scan(struct iwl_priv *priv, return added; } +/** + * iwl_fill_probe_req - fill in all required fields and IE for probe request + */ + +static u16 iwl_fill_probe_req(struct ieee80211_mgmt *frame, const u8 *ta, + const u8 *ies, int ie_len, int left) +{ + int len = 0; + u8 *pos = NULL; + + /* Make sure there is enough space for the probe request, + * two mandatory IEs and the data */ + left -= 24; + if (left < 0) + return 0; + + frame->frame_control = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ); + memcpy(frame->da, iwl_bcast_addr, ETH_ALEN); + memcpy(frame->sa, ta, ETH_ALEN); + memcpy(frame->bssid, iwl_bcast_addr, ETH_ALEN); + frame->seq_ctrl = 0; + + len += 24; + + /* ...next IE... */ + pos = &frame->u.probe_req.variable[0]; + + /* fill in our indirect SSID IE */ + left -= 2; + if (left < 0) + return 0; + *pos++ = WLAN_EID_SSID; + *pos++ = 0; + + len += 2; + + if (WARN_ON(left < ie_len)) + return len; + + if (ies && ie_len) { + memcpy(pos, ies, ie_len); + len += ie_len; + } + + return (u16)len; +} + static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) { struct iwl_host_cmd cmd = { @@ -791,7 +838,7 @@ static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) scan->rx_chain = cpu_to_le16(rx_chain); switch (priv->scan_type) { case IWL_SCAN_NORMAL: - cmd_len = iwl_fill_probe_req(priv, + cmd_len = iwl_fill_probe_req( (struct ieee80211_mgmt *)scan->data, vif->addr, priv->scan_request->ie, @@ -801,7 +848,7 @@ static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) case IWL_SCAN_RADIO_RESET: case IWL_SCAN_ROC: /* use bcast addr, will not be transmitted but must be valid */ - cmd_len = iwl_fill_probe_req(priv, + cmd_len = iwl_fill_probe_req( (struct ieee80211_mgmt *)scan->data, iwl_bcast_addr, NULL, 0, IWL_MAX_SCAN_SIZE - sizeof(*scan)); @@ -1004,53 +1051,6 @@ static void iwl_bg_scan_check(struct work_struct *data) mutex_unlock(&priv->mutex); } -/** - * iwl_fill_probe_req - fill in all required fields and IE for probe request - */ - -u16 iwl_fill_probe_req(struct iwl_priv *priv, struct ieee80211_mgmt *frame, - const u8 *ta, const u8 *ies, int ie_len, int left) -{ - int len = 0; - u8 *pos = NULL; - - /* Make sure there is enough space for the probe request, - * two mandatory IEs and the data */ - left -= 24; - if (left < 0) - return 0; - - frame->frame_control = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ); - memcpy(frame->da, iwl_bcast_addr, ETH_ALEN); - memcpy(frame->sa, ta, ETH_ALEN); - memcpy(frame->bssid, iwl_bcast_addr, ETH_ALEN); - frame->seq_ctrl = 0; - - len += 24; - - /* ...next IE... */ - pos = &frame->u.probe_req.variable[0]; - - /* fill in our indirect SSID IE */ - left -= 2; - if (left < 0) - return 0; - *pos++ = WLAN_EID_SSID; - *pos++ = 0; - - len += 2; - - if (WARN_ON(left < ie_len)) - return len; - - if (ies && ie_len) { - memcpy(pos, ies, ie_len); - len += ie_len; - } - - return (u16)len; -} - static void iwl_bg_abort_scan(struct work_struct *work) { struct iwl_priv *priv = container_of(work, struct iwl_priv, abort_scan); -- cgit From f06c7885c3dd3db8eb771e10615ee41425607e95 Mon Sep 17 00:00:00 2001 From: Thomas Pedersen Date: Tue, 6 Mar 2012 16:42:09 -0800 Subject: mac80211: fix smatch lock errors in mesh smatch was complaining: CHECK net/mac80211/mesh_pathtbl.c net/mac80211/mesh_pathtbl.c:562 mesh_path_add() error: double lock 'bottom_half:' net/mac80211/mesh_pathtbl.c:580 mesh_path_add() error: double unlock 'bottom_half:' net/mac80211/mesh_pathtbl.c:589 mesh_path_add() error: double unlock 'bottom_half:' net/mac80211/mesh_pathtbl.c:691 mpp_path_add() error: double lock 'bottom_half:' net/mac80211/mesh_pathtbl.c:707 mpp_path_add() error: double unlock 'bottom_half:' net/mac80211/mesh_pathtbl.c:716 mpp_path_add() error: double unlock 'bottom_half:' net/mac80211/mesh_pathtbl.c:814 mesh_path_flush_by_nexthop() error: double lock 'bottom_half:' net/mac80211/mesh_pathtbl.c:819 mesh_path_flush_by_nexthop() error: double unlock 'bottom_half:' net/mac80211/mesh_pathtbl.c:887 mesh_path_del() error: double lock 'bottom_half:' net/mac80211/mesh_pathtbl.c:901 mesh_path_del() error: double unlock 'bottom_half:' So don't lock / unlock with _bh() while bottom halves are already disabled. Reported-by: Johannes Berg Signed-off-by: Thomas Pedersen Signed-off-by: John W. Linville --- net/mac80211/mesh_pathtbl.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c index 157642f780b9..be1361b5f7ad 100644 --- a/net/mac80211/mesh_pathtbl.c +++ b/net/mac80211/mesh_pathtbl.c @@ -559,7 +559,7 @@ int mesh_path_add(u8 *dst, struct ieee80211_sub_if_data *sdata) hash_idx = mesh_table_hash(dst, sdata, tbl); bucket = &tbl->hash_buckets[hash_idx]; - spin_lock_bh(&tbl->hashwlock[hash_idx]); + spin_lock(&tbl->hashwlock[hash_idx]); err = -EEXIST; hlist_for_each_entry(node, n, bucket, list) { @@ -576,7 +576,7 @@ int mesh_path_add(u8 *dst, struct ieee80211_sub_if_data *sdata) mesh_paths_generation++; - spin_unlock_bh(&tbl->hashwlock[hash_idx]); + spin_unlock(&tbl->hashwlock[hash_idx]); read_unlock_bh(&pathtbl_resize_lock); if (grow) { set_bit(MESH_WORK_GROW_MPATH_TABLE, &ifmsh->wrkq_flags); @@ -585,7 +585,7 @@ int mesh_path_add(u8 *dst, struct ieee80211_sub_if_data *sdata) return 0; err_exists: - spin_unlock_bh(&tbl->hashwlock[hash_idx]); + spin_unlock(&tbl->hashwlock[hash_idx]); read_unlock_bh(&pathtbl_resize_lock); kfree(new_node); err_node_alloc: @@ -688,7 +688,7 @@ int mpp_path_add(u8 *dst, u8 *mpp, struct ieee80211_sub_if_data *sdata) hash_idx = mesh_table_hash(dst, sdata, tbl); bucket = &tbl->hash_buckets[hash_idx]; - spin_lock_bh(&tbl->hashwlock[hash_idx]); + spin_lock(&tbl->hashwlock[hash_idx]); err = -EEXIST; hlist_for_each_entry(node, n, bucket, list) { @@ -703,7 +703,7 @@ int mpp_path_add(u8 *dst, u8 *mpp, struct ieee80211_sub_if_data *sdata) tbl->mean_chain_len * (tbl->hash_mask + 1)) grow = 1; - spin_unlock_bh(&tbl->hashwlock[hash_idx]); + spin_unlock(&tbl->hashwlock[hash_idx]); read_unlock_bh(&pathtbl_resize_lock); if (grow) { set_bit(MESH_WORK_GROW_MPP_TABLE, &ifmsh->wrkq_flags); @@ -712,7 +712,7 @@ int mpp_path_add(u8 *dst, u8 *mpp, struct ieee80211_sub_if_data *sdata) return 0; err_exists: - spin_unlock_bh(&tbl->hashwlock[hash_idx]); + spin_unlock(&tbl->hashwlock[hash_idx]); read_unlock_bh(&pathtbl_resize_lock); kfree(new_node); err_node_alloc: @@ -811,9 +811,9 @@ void mesh_path_flush_by_nexthop(struct sta_info *sta) for_each_mesh_entry(tbl, p, node, i) { mpath = node->mpath; if (rcu_dereference(mpath->next_hop) == sta) { - spin_lock_bh(&tbl->hashwlock[i]); + spin_lock(&tbl->hashwlock[i]); __mesh_path_del(tbl, node); - spin_unlock_bh(&tbl->hashwlock[i]); + spin_unlock(&tbl->hashwlock[i]); } } read_unlock_bh(&pathtbl_resize_lock); @@ -884,7 +884,7 @@ int mesh_path_del(u8 *addr, struct ieee80211_sub_if_data *sdata) hash_idx = mesh_table_hash(addr, sdata, tbl); bucket = &tbl->hash_buckets[hash_idx]; - spin_lock_bh(&tbl->hashwlock[hash_idx]); + spin_lock(&tbl->hashwlock[hash_idx]); hlist_for_each_entry(node, n, bucket, list) { mpath = node->mpath; if (mpath->sdata == sdata && @@ -897,7 +897,7 @@ int mesh_path_del(u8 *addr, struct ieee80211_sub_if_data *sdata) err = -ENXIO; enddel: mesh_paths_generation++; - spin_unlock_bh(&tbl->hashwlock[hash_idx]); + spin_unlock(&tbl->hashwlock[hash_idx]); read_unlock_bh(&pathtbl_resize_lock); return err; } -- cgit From 0d33cd782990b13d992109d16e11205e1ac547bb Mon Sep 17 00:00:00 2001 From: RafaÅ‚ MiÅ‚ecki Date: Wed, 7 Mar 2012 09:11:22 +0100 Subject: bcma: silence PMU warning for BCM4331 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: RafaÅ‚ MiÅ‚ecki Signed-off-by: John W. Linville --- drivers/bcma/driver_chipcommon_pmu.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/bcma/driver_chipcommon_pmu.c b/drivers/bcma/driver_chipcommon_pmu.c index 800163c8c2e7..a058842f14fd 100644 --- a/drivers/bcma/driver_chipcommon_pmu.c +++ b/drivers/bcma/driver_chipcommon_pmu.c @@ -80,6 +80,7 @@ static void bcma_pmu_resources_init(struct bcma_drv_cc *cc) min_msk = 0x200D; max_msk = 0xFFFF; break; + case 0x4331: case 43224: case 43225: break; -- cgit From 41b58f189ada1a12d3c9417c3eedd5b910d8d09f Mon Sep 17 00:00:00 2001 From: Attila Fazekas Date: Thu, 23 Feb 2012 19:50:35 +0100 Subject: rtl8187: Add AD-HOC support Add AD-HOC support to the rtl8187 based on the rtl8180 source Signed-off-by: Attila Fazekas Acked-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtl818x/rtl8187/dev.c | 110 ++++++++++++++++++++----- drivers/net/wireless/rtl818x/rtl8187/rtl8187.h | 9 ++ 2 files changed, 100 insertions(+), 19 deletions(-) diff --git a/drivers/net/wireless/rtl818x/rtl8187/dev.c b/drivers/net/wireless/rtl818x/rtl8187/dev.c index 638fbef693e6..cf53ac9d6f23 100644 --- a/drivers/net/wireless/rtl818x/rtl8187/dev.c +++ b/drivers/net/wireless/rtl818x/rtl8187/dev.c @@ -8,7 +8,7 @@ * Copyright 2005 Andrea Merello , et al. * * The driver was extended to the RTL8187B in 2008 by: - * Herton Ronaldo Krzesinski + * Herton Ronaldo Krzesinski * Hin-Tak Leung * Larry Finger * @@ -232,6 +232,7 @@ static void rtl8187_tx(struct ieee80211_hw *dev, struct sk_buff *skb) { struct rtl8187_priv *priv = dev->priv; struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + struct ieee80211_hdr *tx_hdr = (struct ieee80211_hdr *)(skb->data); unsigned int ep; void *buf; struct urb *urb; @@ -249,7 +250,7 @@ static void rtl8187_tx(struct ieee80211_hw *dev, struct sk_buff *skb) flags |= RTL818X_TX_DESC_FLAG_NO_ENC; flags |= ieee80211_get_tx_rate(dev, info)->hw_value << 24; - if (ieee80211_has_morefrags(((struct ieee80211_hdr *)skb->data)->frame_control)) + if (ieee80211_has_morefrags(tx_hdr->frame_control)) flags |= RTL818X_TX_DESC_FLAG_MOREFRAG; if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) { flags |= RTL818X_TX_DESC_FLAG_RTS; @@ -261,6 +262,13 @@ static void rtl8187_tx(struct ieee80211_hw *dev, struct sk_buff *skb) flags |= ieee80211_get_rts_cts_rate(dev, info)->hw_value << 19; } + if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { + if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT) + priv->seqno += 0x10; + tx_hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG); + tx_hdr->seq_ctrl |= cpu_to_le16(priv->seqno); + } + if (!priv->is_rtl8187b) { struct rtl8187_tx_hdr *hdr = (struct rtl8187_tx_hdr *)skb_push(skb, sizeof(*hdr)); @@ -274,8 +282,6 @@ static void rtl8187_tx(struct ieee80211_hw *dev, struct sk_buff *skb) } else { /* fc needs to be calculated before skb_push() */ unsigned int epmap[4] = { 6, 7, 5, 4 }; - struct ieee80211_hdr *tx_hdr = - (struct ieee80211_hdr *)(skb->data); u16 fc = le16_to_cpu(tx_hdr->frame_control); struct rtl8187b_tx_hdr *hdr = @@ -1031,10 +1037,61 @@ static void rtl8187_stop(struct ieee80211_hw *dev) cancel_delayed_work_sync(&priv->work); } +static u64 rtl8187_get_tsf(struct ieee80211_hw *dev, struct ieee80211_vif *vif) +{ + struct rtl8187_priv *priv = dev->priv; + + return rtl818x_ioread32(priv, &priv->map->TSFT[0]) | + (u64)(rtl818x_ioread32(priv, &priv->map->TSFT[1])) << 32; +} + + +static void rtl8187_beacon_work(struct work_struct *work) +{ + struct rtl8187_vif *vif_priv = + container_of(work, struct rtl8187_vif, beacon_work.work); + struct ieee80211_vif *vif = + container_of((void *)vif_priv, struct ieee80211_vif, drv_priv); + struct ieee80211_hw *dev = vif_priv->dev; + struct ieee80211_mgmt *mgmt; + struct sk_buff *skb; + + /* don't overflow the tx ring */ + if (ieee80211_queue_stopped(dev, 0)) + goto resched; + + /* grab a fresh beacon */ + skb = ieee80211_beacon_get(dev, vif); + if (!skb) + goto resched; + + /* + * update beacon timestamp w/ TSF value + * TODO: make hardware update beacon timestamp + */ + mgmt = (struct ieee80211_mgmt *)skb->data; + mgmt->u.beacon.timestamp = cpu_to_le64(rtl8187_get_tsf(dev, vif)); + + /* TODO: use actual beacon queue */ + skb_set_queue_mapping(skb, 0); + + rtl8187_tx(dev, skb); + +resched: + /* + * schedule next beacon + * TODO: use hardware support for beacon timing + */ + schedule_delayed_work(&vif_priv->beacon_work, + usecs_to_jiffies(1024 * vif->bss_conf.beacon_int)); +} + + static int rtl8187_add_interface(struct ieee80211_hw *dev, struct ieee80211_vif *vif) { struct rtl8187_priv *priv = dev->priv; + struct rtl8187_vif *vif_priv; int i; int ret = -EOPNOTSUPP; @@ -1044,6 +1101,7 @@ static int rtl8187_add_interface(struct ieee80211_hw *dev, switch (vif->type) { case NL80211_IFTYPE_STATION: + case NL80211_IFTYPE_ADHOC: break; default: goto exit; @@ -1052,6 +1110,13 @@ static int rtl8187_add_interface(struct ieee80211_hw *dev, ret = 0; priv->vif = vif; + /* Initialize driver private area */ + vif_priv = (struct rtl8187_vif *)&vif->drv_priv; + vif_priv->dev = dev; + INIT_DELAYED_WORK(&vif_priv->beacon_work, rtl8187_beacon_work); + vif_priv->enable_beacon = false; + + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); for (i = 0; i < ETH_ALEN; i++) rtl818x_iowrite8(priv, &priv->map->MAC[i], @@ -1175,9 +1240,12 @@ static void rtl8187_bss_info_changed(struct ieee80211_hw *dev, u32 changed) { struct rtl8187_priv *priv = dev->priv; + struct rtl8187_vif *vif_priv; int i; u8 reg; + vif_priv = (struct rtl8187_vif *)&vif->drv_priv; + if (changed & BSS_CHANGED_BSSID) { mutex_lock(&priv->conf_mutex); for (i = 0; i < ETH_ALEN; i++) @@ -1189,8 +1257,12 @@ static void rtl8187_bss_info_changed(struct ieee80211_hw *dev, else reg = 0; - if (is_valid_ether_addr(info->bssid)) - reg |= RTL818X_MSR_INFRA; + if (is_valid_ether_addr(info->bssid)) { + if (vif->type == NL80211_IFTYPE_ADHOC) + reg |= RTL818X_MSR_ADHOC; + else + reg |= RTL818X_MSR_INFRA; + } else reg |= RTL818X_MSR_NO_LINK; @@ -1202,6 +1274,16 @@ static void rtl8187_bss_info_changed(struct ieee80211_hw *dev, if (changed & (BSS_CHANGED_ERP_SLOT | BSS_CHANGED_ERP_PREAMBLE)) rtl8187_conf_erp(priv, info->use_short_slot, info->use_short_preamble); + + if (changed & BSS_CHANGED_BEACON_ENABLED) + vif_priv->enable_beacon = info->enable_beacon; + + if (changed & (BSS_CHANGED_BEACON_ENABLED | BSS_CHANGED_BEACON)) { + cancel_delayed_work_sync(&vif_priv->beacon_work); + if (vif_priv->enable_beacon) + schedule_work(&vif_priv->beacon_work.work); + } + } static u64 rtl8187_prepare_multicast(struct ieee80211_hw *dev, @@ -1279,13 +1361,6 @@ static int rtl8187_conf_tx(struct ieee80211_hw *dev, return 0; } -static u64 rtl8187_get_tsf(struct ieee80211_hw *dev, struct ieee80211_vif *vif) -{ - struct rtl8187_priv *priv = dev->priv; - - return rtl818x_ioread32(priv, &priv->map->TSFT[0]) | - (u64)(rtl818x_ioread32(priv, &priv->map->TSFT[1])) << 32; -} static const struct ieee80211_ops rtl8187_ops = { .tx = rtl8187_tx, @@ -1514,12 +1589,9 @@ static int __devinit rtl8187_probe(struct usb_interface *intf, if (reg & 0xFF00) priv->rfkill_mask = RFKILL_MASK_8198; } - - /* - * XXX: Once this driver supports anything that requires - * beacons it must implement IEEE80211_TX_CTL_ASSIGN_SEQ. - */ - dev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION); + dev->vif_data_size = sizeof(struct rtl8187_vif); + dev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | + BIT(NL80211_IFTYPE_ADHOC) ; if ((id->driver_info == DEVICE_RTL8187) && priv->is_rtl8187b) printk(KERN_INFO "rtl8187: inconsistency between id with OEM" diff --git a/drivers/net/wireless/rtl818x/rtl8187/rtl8187.h b/drivers/net/wireless/rtl818x/rtl8187/rtl8187.h index f1cc90751dbf..e19a20a8e955 100644 --- a/drivers/net/wireless/rtl818x/rtl8187/rtl8187.h +++ b/drivers/net/wireless/rtl818x/rtl8187/rtl8187.h @@ -89,6 +89,14 @@ enum { DEVICE_RTL8187B }; +struct rtl8187_vif { + struct ieee80211_hw *dev; + + /* beaconing */ + struct delayed_work beacon_work; + bool enable_beacon; +}; + struct rtl8187_priv { /* common between rtl818x drivers */ struct rtl818x_csr *map; @@ -141,6 +149,7 @@ struct rtl8187_priv { __le32 bits32; } *io_dmabuf; bool rfkill_off; + u16 seqno; }; void rtl8187_write_phy(struct ieee80211_hw *dev, u8 addr, u32 data); -- cgit From 55df5afb13718cda49128fa5985556df91d07765 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Sat, 3 Mar 2012 22:18:00 +0200 Subject: wl12xx: implement SW Tx watchdog Track freed FW blocks during Tx. If no blocks were freed during a predefined timeout, initiate a HW recovery. This helps in situations when the FW watchdog fails. Don't trigger recovery during activities that can temporarily stop Tx. This includes: - scanning - buffering packets for sleeping stations (AP role) - ROC on any role Signed-off-by: Arik Nemtsov Signed-off-by: Eliad Peller Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/cmd.c | 8 +++ drivers/net/wireless/wl12xx/conf.h | 3 + drivers/net/wireless/wl12xx/main.c | 110 +++++++++++++++++++++++++++++++++++ drivers/net/wireless/wl12xx/scan.c | 6 ++ drivers/net/wireless/wl12xx/tx.c | 4 ++ drivers/net/wireless/wl12xx/tx.h | 1 + drivers/net/wireless/wl12xx/wl12xx.h | 3 + 7 files changed, 135 insertions(+) diff --git a/drivers/net/wireless/wl12xx/cmd.c b/drivers/net/wireless/wl12xx/cmd.c index 1ef212f6440f..3414fc11e9ba 100644 --- a/drivers/net/wireless/wl12xx/cmd.c +++ b/drivers/net/wireless/wl12xx/cmd.c @@ -1818,6 +1818,14 @@ int wl12xx_croc(struct wl1271 *wl, u8 role_id) goto out; __clear_bit(role_id, wl->roc_map); + + /* + * Rearm the tx watchdog when removing the last ROC. This prevents + * recoveries due to just finished ROCs - when Tx hasn't yet had + * a chance to get out. + */ + if (find_first_bit(wl->roc_map, WL12XX_MAX_ROLES) >= WL12XX_MAX_ROLES) + wl12xx_rearm_tx_watchdog_locked(wl); out: return ret; } diff --git a/drivers/net/wireless/wl12xx/conf.h b/drivers/net/wireless/wl12xx/conf.h index cc50faaf03d1..3e581e19424c 100644 --- a/drivers/net/wireless/wl12xx/conf.h +++ b/drivers/net/wireless/wl12xx/conf.h @@ -690,6 +690,9 @@ struct conf_tx_settings { */ u8 tmpl_short_retry_limit; u8 tmpl_long_retry_limit; + + /* Time in ms for Tx watchdog timer to expire */ + u32 tx_watchdog_timeout; }; enum { diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index 95a76a5f9eeb..39002363611e 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -217,6 +217,7 @@ static struct conf_drv_settings default_conf = { .basic_rate_5 = CONF_HW_BIT_RATE_6MBPS, .tmpl_short_retry_limit = 10, .tmpl_long_retry_limit = 10, + .tx_watchdog_timeout = 5000, }, .conn = { .wake_up_event = CONF_WAKE_UP_EVENT_DTIM, @@ -553,6 +554,80 @@ static void wl1271_rx_streaming_timer(unsigned long data) ieee80211_queue_work(wl->hw, &wlvif->rx_streaming_disable_work); } +/* wl->mutex must be taken */ +void wl12xx_rearm_tx_watchdog_locked(struct wl1271 *wl) +{ + /* if the watchdog is not armed, don't do anything */ + if (wl->tx_allocated_blocks == 0) + return; + + cancel_delayed_work(&wl->tx_watchdog_work); + ieee80211_queue_delayed_work(wl->hw, &wl->tx_watchdog_work, + msecs_to_jiffies(wl->conf.tx.tx_watchdog_timeout)); +} + +static void wl12xx_tx_watchdog_work(struct work_struct *work) +{ + struct delayed_work *dwork; + struct wl1271 *wl; + + dwork = container_of(work, struct delayed_work, work); + wl = container_of(dwork, struct wl1271, tx_watchdog_work); + + mutex_lock(&wl->mutex); + + if (unlikely(wl->state == WL1271_STATE_OFF)) + goto out; + + /* Tx went out in the meantime - everything is ok */ + if (unlikely(wl->tx_allocated_blocks == 0)) + goto out; + + /* + * if a ROC is in progress, we might not have any Tx for a long + * time (e.g. pending Tx on the non-ROC channels) + */ + if (find_first_bit(wl->roc_map, WL12XX_MAX_ROLES) < WL12XX_MAX_ROLES) { + wl1271_debug(DEBUG_TX, "No Tx (in FW) for %d ms due to ROC", + wl->conf.tx.tx_watchdog_timeout); + wl12xx_rearm_tx_watchdog_locked(wl); + goto out; + } + + /* + * if a scan is in progress, we might not have any Tx for a long + * time + */ + if (wl->scan.state != WL1271_SCAN_STATE_IDLE) { + wl1271_debug(DEBUG_TX, "No Tx (in FW) for %d ms due to scan", + wl->conf.tx.tx_watchdog_timeout); + wl12xx_rearm_tx_watchdog_locked(wl); + goto out; + } + + /* + * AP might cache a frame for a long time for a sleeping station, + * so rearm the timer if there's an AP interface with stations. If + * Tx is genuinely stuck we will most hopefully discover it when all + * stations are removed due to inactivity. + */ + if (wl->active_sta_count) { + wl1271_debug(DEBUG_TX, "No Tx (in FW) for %d ms. AP has " + " %d stations", + wl->conf.tx.tx_watchdog_timeout, + wl->active_sta_count); + wl12xx_rearm_tx_watchdog_locked(wl); + goto out; + } + + wl1271_error("Tx stuck (in FW) for %d ms. Starting recovery", + wl->conf.tx.tx_watchdog_timeout); + wl12xx_queue_recovery_work(wl); + +out: + mutex_unlock(&wl->mutex); +} + static void wl1271_conf_init(struct wl1271 *wl) { @@ -745,6 +820,18 @@ static void wl12xx_fw_status(struct wl1271 *wl, wl->tx_allocated_blocks -= freed_blocks; + /* + * If the FW freed some blocks: + * If we still have allocated blocks - re-arm the timer, Tx is + * not stuck. Otherwise, cancel the timer (no Tx currently). + */ + if (freed_blocks) { + if (wl->tx_allocated_blocks) + wl12xx_rearm_tx_watchdog_locked(wl); + else + cancel_delayed_work(&wl->tx_watchdog_work); + } + avail = le32_to_cpu(status->tx_total) - wl->tx_allocated_blocks; /* @@ -1418,6 +1505,7 @@ int wl1271_plt_stop(struct wl1271 *wl) cancel_work_sync(&wl->netstack_work); cancel_work_sync(&wl->recovery_work); cancel_delayed_work_sync(&wl->elp_work); + cancel_delayed_work_sync(&wl->tx_watchdog_work); mutex_lock(&wl->mutex); wl1271_power_off(wl); @@ -1789,6 +1877,7 @@ static void wl1271_op_stop(struct ieee80211_hw *hw) cancel_work_sync(&wl->netstack_work); cancel_work_sync(&wl->tx_work); cancel_delayed_work_sync(&wl->elp_work); + cancel_delayed_work_sync(&wl->tx_watchdog_work); /* let's notify MAC80211 about the remaining pending TX frames */ wl12xx_tx_reset(wl, true); @@ -2218,6 +2307,12 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl, if (wl->scan.state != WL1271_SCAN_STATE_IDLE && wl->scan_vif == vif) { + /* + * Rearm the tx watchdog just before idling scan. This + * prevents just-finished scans from triggering the watchdog + */ + wl12xx_rearm_tx_watchdog_locked(wl); + wl->scan.state = WL1271_SCAN_STATE_IDLE; memset(wl->scan.scanned_ch, 0, sizeof(wl->scan.scanned_ch)); wl->scan_vif = NULL; @@ -3129,6 +3224,13 @@ static void wl1271_op_cancel_hw_scan(struct ieee80211_hw *hw, if (ret < 0) goto out_sleep; } + + /* + * Rearm the tx watchdog just before idling scan. This + * prevents just-finished scans from triggering the watchdog + */ + wl12xx_rearm_tx_watchdog_locked(wl); + wl->scan.state = WL1271_SCAN_STATE_IDLE; memset(wl->scan.scanned_ch, 0, sizeof(wl->scan.scanned_ch)); wl->scan_vif = NULL; @@ -4138,6 +4240,13 @@ void wl1271_free_sta(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 hlid) __clear_bit(hlid, (unsigned long *)&wl->ap_fw_ps_map); wl12xx_free_link(wl, wlvif, &hlid); wl->active_sta_count--; + + /* + * rearm the tx watchdog when the last STA is freed - give the FW a + * chance to return STA-buffered packets before complaining. + */ + if (wl->active_sta_count == 0) + wl12xx_rearm_tx_watchdog_locked(wl); } static int wl12xx_sta_add(struct wl1271 *wl, @@ -5212,6 +5321,7 @@ static struct ieee80211_hw *wl1271_alloc_hw(void) INIT_WORK(&wl->tx_work, wl1271_tx_work); INIT_WORK(&wl->recovery_work, wl1271_recovery_work); INIT_DELAYED_WORK(&wl->scan_complete_work, wl1271_scan_complete_work); + INIT_DELAYED_WORK(&wl->tx_watchdog_work, wl12xx_tx_watchdog_work); wl->freezable_wq = create_freezable_workqueue("wl12xx_wq"); if (!wl->freezable_wq) { diff --git a/drivers/net/wireless/wl12xx/scan.c b/drivers/net/wireless/wl12xx/scan.c index e43a6b2c1d91..fcba055ef196 100644 --- a/drivers/net/wireless/wl12xx/scan.c +++ b/drivers/net/wireless/wl12xx/scan.c @@ -55,6 +55,12 @@ void wl1271_scan_complete_work(struct work_struct *work) vif = wl->scan_vif; wlvif = wl12xx_vif_to_data(vif); + /* + * Rearm the tx watchdog just before idling scan. This + * prevents just-finished scans from triggering the watchdog + */ + wl12xx_rearm_tx_watchdog_locked(wl); + wl->scan.state = WL1271_SCAN_STATE_IDLE; memset(wl->scan.scanned_ch, 0, sizeof(wl->scan.scanned_ch)); wl->scan.req = NULL; diff --git a/drivers/net/wireless/wl12xx/tx.c b/drivers/net/wireless/wl12xx/tx.c index 8f78fddcb723..43ae49143d68 100644 --- a/drivers/net/wireless/wl12xx/tx.c +++ b/drivers/net/wireless/wl12xx/tx.c @@ -226,6 +226,10 @@ static int wl1271_tx_allocate(struct wl1271 *wl, struct wl12xx_vif *wlvif, wl->tx_blocks_available -= total_blocks; wl->tx_allocated_blocks += total_blocks; + /* If the FW was empty before, arm the Tx watchdog */ + if (wl->tx_allocated_blocks == total_blocks) + wl12xx_rearm_tx_watchdog_locked(wl); + ac = wl1271_tx_get_queue(skb_get_queue_mapping(skb)); wl->tx_allocated_pkts[ac]++; diff --git a/drivers/net/wireless/wl12xx/tx.h b/drivers/net/wireless/wl12xx/tx.h index e3977b55a710..5cf8c32d40d1 100644 --- a/drivers/net/wireless/wl12xx/tx.h +++ b/drivers/net/wireless/wl12xx/tx.h @@ -227,5 +227,6 @@ void wl12xx_rearm_rx_streaming(struct wl1271 *wl, unsigned long *active_hlids); /* from main.c */ void wl1271_free_sta(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 hlid); +void wl12xx_rearm_tx_watchdog_locked(struct wl1271 *wl); #endif diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/wl12xx/wl12xx.h index 6e13a3073e9f..749a15a75d38 100644 --- a/drivers/net/wireless/wl12xx/wl12xx.h +++ b/drivers/net/wireless/wl12xx/wl12xx.h @@ -495,6 +495,9 @@ struct wl1271 { /* last wlvif we transmitted from */ struct wl12xx_vif *last_wlvif; + + /* work to fire when Tx is stuck */ + struct delayed_work tx_watchdog_work; }; struct wl1271_station { -- cgit From fdeff46586e01c4b8ceb461a72a46fc6ef00a771 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 7 Mar 2012 09:52:10 -0800 Subject: iwlwifi: remove unused arguments from iwlagn_gain_computation The function has two arguments it never uses, remove them. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-calib.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c index 579679edd5f1..84cbe7bb504c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c @@ -879,10 +879,8 @@ static void iwl_find_disconn_antenna(struct iwl_priv *priv, u32* average_sig, } static void iwlagn_gain_computation(struct iwl_priv *priv, - u32 average_noise[NUM_RX_CHAINS], - u16 min_average_noise_antenna_i, - u32 min_average_noise, - u8 default_chain) + u32 average_noise[NUM_RX_CHAINS], + u8 default_chain) { int i; s32 delta_g; @@ -1087,7 +1085,6 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv) min_average_noise, min_average_noise_antenna_i); iwlagn_gain_computation(priv, average_noise, - min_average_noise_antenna_i, min_average_noise, find_first_chain(hw_params(priv).valid_rx_ant)); /* Some power changes may have been made during the calibration. -- cgit From 9b6ca44823a1414a26054fd0b5cd94f31c105ac8 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 7 Mar 2012 09:52:11 -0800 Subject: iwlwifi: remove unused argument from rs_initialize_lq The function never uses its conf argument, so remove it. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-rs.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c index 9895b807246b..53f8c51cfcdb 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c @@ -2677,7 +2677,6 @@ out: * which requires station table entry to exist). */ static void rs_initialize_lq(struct iwl_priv *priv, - struct ieee80211_conf *conf, struct ieee80211_sta *sta, struct iwl_lq_sta *lq_sta) { @@ -2912,7 +2911,7 @@ void iwl_rs_rate_init(struct iwl_priv *priv, struct ieee80211_sta *sta, u8 sta_i lq_sta->dbg_fixed_rate = 0; #endif - rs_initialize_lq(priv, conf, sta, lq_sta); + rs_initialize_lq(priv, sta, lq_sta); } static void rs_fill_link_cmd(struct iwl_priv *priv, -- cgit From 955570fc662194c6a1128028a579d7e9014c30aa Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 7 Mar 2012 09:52:12 -0800 Subject: iwlwifi: move iwl_sta_id_or_broadcast to user There's only one user, so the function can be moved into the correct file. It also loses an argument along the way. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-tx.c | 31 ++++++++++++++++++++++++++++++- drivers/net/wireless/iwlwifi/iwl-agn.h | 31 ------------------------------- 2 files changed, 30 insertions(+), 32 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c index 0ef59d9a99ee..c454c6782395 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c @@ -248,6 +248,35 @@ static void iwlagn_tx_cmd_build_hwcrypto(struct iwl_priv *priv, } } +/** + * iwl_sta_id_or_broadcast - return sta_id or broadcast sta + * @context: the current context + * @sta: mac80211 station + * + * In certain circumstances mac80211 passes a station pointer + * that may be %NULL, for example during TX or key setup. In + * that case, we need to use the broadcast station, so this + * inline wraps that pattern. + */ +static int iwl_sta_id_or_broadcast(struct iwl_rxon_context *context, + struct ieee80211_sta *sta) +{ + int sta_id; + + if (!sta) + return context->bcast_sta_id; + + sta_id = iwl_sta_id(sta); + + /* + * mac80211 should not be passing a partially + * initialised station! + */ + WARN_ON(sta_id == IWL_INVALID_STATION); + + return sta_id; +} + /* * start REPLY_TX command process */ @@ -304,7 +333,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) sta_id = ctx->bcast_sta_id; else { /* Find index into station table for destination station */ - sta_id = iwl_sta_id_or_broadcast(priv, ctx, info->control.sta); + sta_id = iwl_sta_id_or_broadcast(ctx, info->control.sta); if (sta_id == IWL_INVALID_STATION) { IWL_DEBUG_DROP(priv, "Dropping - INVALID STATION: %pM\n", hdr->addr1); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index ec3a90c42efb..8384c057babb 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h @@ -258,37 +258,6 @@ static inline int iwl_sta_id(struct ieee80211_sta *sta) return ((struct iwl_station_priv *)sta->drv_priv)->sta_id; } -/** - * iwl_sta_id_or_broadcast - return sta_id or broadcast sta - * @priv: iwl priv - * @context: the current context - * @sta: mac80211 station - * - * In certain circumstances mac80211 passes a station pointer - * that may be %NULL, for example during TX or key setup. In - * that case, we need to use the broadcast station, so this - * inline wraps that pattern. - */ -static inline int iwl_sta_id_or_broadcast(struct iwl_priv *priv, - struct iwl_rxon_context *context, - struct ieee80211_sta *sta) -{ - int sta_id; - - if (!sta) - return context->bcast_sta_id; - - sta_id = iwl_sta_id(sta); - - /* - * mac80211 should not be passing a partially - * initialised station! - */ - WARN_ON(sta_id == IWL_INVALID_STATION); - - return sta_id; -} - int iwlagn_alloc_bcast_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx); int iwlagn_add_bssid_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx, -- cgit From 03dadf96aa48acbd2501f21d1c1b5740b93b7c72 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 7 Mar 2012 09:52:13 -0800 Subject: iwlwifi: remove unused argument from iwl_init_hw_rates The function never uses the priv argument as it only fills in the passed data, so remove the argument. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 4cd375c811e2..397faf9023e4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -1010,8 +1010,7 @@ void iwl_cancel_deferred_work(struct iwl_priv *priv) del_timer_sync(&priv->ucode_trace); } -static void iwl_init_hw_rates(struct iwl_priv *priv, - struct ieee80211_rate *rates) +static void iwl_init_hw_rates(struct ieee80211_rate *rates) { int i; @@ -1090,7 +1089,7 @@ static int iwl_init_drv(struct iwl_priv *priv) IWL_ERR(priv, "initializing geos failed: %d\n", ret); goto err_free_channel_map; } - iwl_init_hw_rates(priv, priv->ieee_rates); + iwl_init_hw_rates(priv->ieee_rates); return 0; -- cgit From c1803c9459a9cd751eb46da9e60e49728aae7a5a Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 7 Mar 2012 09:52:14 -0800 Subject: iwlwifi: remove two unused arguments in testmode The dump functions never access the incoming attributes, so don't pass them. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-testmode.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-testmode.c b/drivers/net/wireless/iwlwifi/iwl-testmode.c index 5b06916be610..1d732092ebe7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-testmode.c +++ b/drivers/net/wireless/iwlwifi/iwl-testmode.c @@ -713,7 +713,7 @@ nla_put_failure: return -EMSGSIZE; } -static int iwl_testmode_trace_dump(struct ieee80211_hw *hw, struct nlattr **tb, +static int iwl_testmode_trace_dump(struct ieee80211_hw *hw, struct sk_buff *skb, struct netlink_callback *cb) { @@ -905,9 +905,9 @@ static int iwl_testmode_indirect_mem(struct ieee80211_hw *hw, } } -static int iwl_testmode_buffer_dump(struct ieee80211_hw *hw, struct nlattr **tb, - struct sk_buff *skb, - struct netlink_callback *cb) +static int iwl_testmode_buffer_dump(struct ieee80211_hw *hw, + struct sk_buff *skb, + struct netlink_callback *cb) { struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); int idx, length; @@ -1067,11 +1067,11 @@ int iwlagn_mac_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *skb, switch (cmd) { case IWL_TM_CMD_APP2DEV_READ_TRACE: IWL_DEBUG_INFO(priv, "uCode trace cmd to driver\n"); - result = iwl_testmode_trace_dump(hw, tb, skb, cb); + result = iwl_testmode_trace_dump(hw, skb, cb); break; case IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_DUMP: IWL_DEBUG_INFO(priv, "testmode sram dump cmd to driver\n"); - result = iwl_testmode_buffer_dump(hw, tb, skb, cb); + result = iwl_testmode_buffer_dump(hw, skb, cb); break; default: result = -EINVAL; -- cgit From ea886a6014024d027fa207b8765e46d746cd2a18 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 7 Mar 2012 09:52:15 -0800 Subject: iwlwifi: remove unused argument from iwlagn_suspend There's not much point in passing priv and hw pointers since they can be derived from each other, and the function doesn't use the hw pointer anyway. Remove it. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 3 +-- drivers/net/wireless/iwlwifi/iwl-agn.h | 3 +-- drivers/net/wireless/iwlwifi/iwl-mac80211.c | 2 +- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index b2ee1f9373c0..6d8a8578778c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -1120,8 +1120,7 @@ int iwlagn_send_patterns(struct iwl_priv *priv, return err; } -int iwlagn_suspend(struct iwl_priv *priv, - struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) +int iwlagn_suspend(struct iwl_priv *priv, struct cfg80211_wowlan *wowlan) { struct iwlagn_wowlan_wakeup_filter_cmd wakeup_filter_cmd; struct iwl_rxon_cmd rxon; diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index 8384c057babb..82930ef86ad1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h @@ -141,8 +141,7 @@ int iwlagn_send_beacon_cmd(struct iwl_priv *priv); #ifdef CONFIG_PM_SLEEP int iwlagn_send_patterns(struct iwl_priv *priv, struct cfg80211_wowlan *wowlan); -int iwlagn_suspend(struct iwl_priv *priv, - struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan); +int iwlagn_suspend(struct iwl_priv *priv, struct cfg80211_wowlan *wowlan); #endif /* rx */ diff --git a/drivers/net/wireless/iwlwifi/iwl-mac80211.c b/drivers/net/wireless/iwlwifi/iwl-mac80211.c index d2c1d714c89c..bdcbbd0d3467 100644 --- a/drivers/net/wireless/iwlwifi/iwl-mac80211.c +++ b/drivers/net/wireless/iwlwifi/iwl-mac80211.c @@ -405,7 +405,7 @@ static int iwlagn_mac_suspend(struct ieee80211_hw *hw, goto out; } - ret = iwlagn_suspend(priv, hw, wowlan); + ret = iwlagn_suspend(priv, wowlan); if (ret) goto error; -- cgit From e755f882b7e72c48da820acc24196532977cfd07 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 7 Mar 2012 09:52:16 -0800 Subject: iwlwifi: redesign PASSIVE_NO_RX workaround The PASSIVE_NO_RX workaround currently crosses through the op_mode and transport layers, which is a bit odd. This also isn't necessary, if the transport simply reports when queues are full (or no longer full) the op_mode can keep track of this state, and report to mac80211 only what *it* thinks is appropriate. What is appropriate can then be based on whether queues should be stopped to wait for RX or not. This significantly simplifies the transport API, it no longer needs to expose anything to stop a queue, nor to wake "any" queue, this can all be handled in the upper layer completely. Also simplify the handling to not be dependent on the context, that makes little sense as the queues are shared and both contexts have to be on the same channel anyway. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-rx.c | 8 ++--- drivers/net/wireless/iwlwifi/iwl-agn-rxon.c | 8 ++--- drivers/net/wireless/iwlwifi/iwl-agn-tx.c | 12 ++++---- drivers/net/wireless/iwlwifi/iwl-agn.c | 33 +++++++++++++++++++++ drivers/net/wireless/iwlwifi/iwl-agn.h | 5 ++-- drivers/net/wireless/iwlwifi/iwl-core.c | 14 --------- drivers/net/wireless/iwlwifi/iwl-dev.h | 5 ++-- drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h | 12 -------- drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | 36 ++--------------------- drivers/net/wireless/iwlwifi/iwl-trans.h | 36 ++--------------------- drivers/net/wireless/iwlwifi/iwl-ucode.c | 6 ++-- 11 files changed, 56 insertions(+), 119 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c index 521c820ea10a..a9bdbad6663e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c @@ -807,16 +807,12 @@ static void iwlagn_pass_packet_to_mac80211(struct iwl_priv *priv, * sometimes even after already having transmitted frames for the * association because the new RXON may reset the information. */ - if (unlikely(ieee80211_is_beacon(fc))) { + if (unlikely(ieee80211_is_beacon(fc) && priv->passive_no_rx)) { for_each_context(priv, ctx) { - if (!ctx->last_tx_rejected) - continue; if (compare_ether_addr(hdr->addr3, ctx->active.bssid_addr)) continue; - ctx->last_tx_rejected = false; - iwl_trans_wake_any_queue(trans(priv), ctx->ctxid, - "channel got active"); + iwlagn_lift_passive_no_rx(priv); } } diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c index 9d955fa387e5..66e9a71aaac6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c @@ -833,12 +833,8 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw, * not get stuck in this case either since it * can happen if userspace gets confused. */ - if (ctx->last_tx_rejected) { - ctx->last_tx_rejected = false; - iwl_trans_wake_any_queue(trans(priv), - ctx->ctxid, - "Disassoc: flush queue"); - } + iwlagn_lift_passive_no_rx(priv); + ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; if (ctx->ctxid == IWL_RXON_CTX_BSS) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c index c454c6782395..a19db4c0c9fa 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c @@ -1064,8 +1064,8 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb, } /*we can free until ssn % q.n_bd not inclusive */ - WARN_ON(iwl_trans_reclaim(trans(priv), sta_id, tid, txq_id, - ssn, status, &skbs)); + WARN_ON(iwl_trans_reclaim(trans(priv), sta_id, tid, + txq_id, ssn, &skbs)); iwlagn_check_ratid_empty(priv, sta_id, tid); freed = 0; @@ -1086,9 +1086,9 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb, if (status == TX_STATUS_FAIL_PASSIVE_NO_RX && iwl_is_associated_ctx(ctx) && ctx->vif && ctx->vif->type == NL80211_IFTYPE_STATION) { - ctx->last_tx_rejected = true; - iwl_trans_stop_queue(trans(priv), txq_id, - "Tx on passive channel"); + /* block and stop all queues */ + priv->passive_no_rx = true; + ieee80211_stop_queues(priv->hw); IWL_DEBUG_TX_REPLY(priv, "TXQ %d status %s (0x%08x) " @@ -1182,7 +1182,7 @@ int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv, * block-ack window (we assume that they've been successfully * transmitted ... if not, it's too late anyway). */ if (iwl_trans_reclaim(trans(priv), sta_id, tid, scd_flow, - ba_resp_scd_ssn, 0, &reclaimed_skbs)) { + ba_resp_scd_ssn, &reclaimed_skbs)) { spin_unlock(&priv->sta_lock); return 0; } diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 397faf9023e4..29f40eab9715 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -1427,6 +1427,39 @@ static void iwl_nic_config(struct iwl_op_mode *op_mode) cfg(priv)->lib->nic_config(priv); } +static void iwl_stop_sw_queue(struct iwl_op_mode *op_mode, u8 ac) +{ + struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); + + set_bit(ac, &priv->transport_queue_stop); + ieee80211_stop_queue(priv->hw, ac); +} + +static void iwl_wake_sw_queue(struct iwl_op_mode *op_mode, u8 ac) +{ + struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); + + clear_bit(ac, &priv->transport_queue_stop); + + if (!priv->passive_no_rx) + ieee80211_wake_queue(priv->hw, ac); +} + +void iwlagn_lift_passive_no_rx(struct iwl_priv *priv) +{ + int ac; + + if (!priv->passive_no_rx) + return; + + for (ac = IEEE80211_AC_VO; ac < IEEE80211_NUM_ACS; ac++) { + if (!test_bit(ac, &priv->transport_queue_stop)) + ieee80211_wake_queue(priv->hw, ac); + } + + priv->passive_no_rx = false; +} + const struct iwl_op_mode_ops iwl_dvm_ops = { .start = iwl_op_mode_dvm_start, .stop = iwl_op_mode_dvm_stop, diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index 82930ef86ad1..b56498b796c2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h @@ -84,14 +84,13 @@ void iwl_free_skb(struct iwl_op_mode *op_mode, struct sk_buff *skb); int __must_check iwl_rx_dispatch(struct iwl_op_mode *op_mode, struct iwl_rx_cmd_buffer *rxb, struct iwl_device_cmd *cmd); -void iwl_stop_sw_queue(struct iwl_op_mode *op_mode, u8 ac); -void iwl_wake_sw_queue(struct iwl_op_mode *op_mode, u8 ac); void iwl_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state); -void iwl_stop_sw_queue(struct iwl_op_mode *op_mode, u8 ac); void iwl_nic_error(struct iwl_op_mode *op_mode); bool iwl_check_for_ct_kill(struct iwl_priv *priv); +void iwlagn_lift_passive_no_rx(struct iwl_priv *priv); + /* MAC80211 */ struct ieee80211_hw *iwl_alloc_all(void); int iwlagn_mac_setup_register(struct iwl_priv *priv, diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index f43f51d1570e..f50bd4263b88 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -1477,17 +1477,3 @@ void iwl_free_skb(struct iwl_op_mode *op_mode, struct sk_buff *skb) kmem_cache_free(priv->tx_cmd_pool, (info->driver_data[1])); dev_kfree_skb_any(skb); } - -void iwl_stop_sw_queue(struct iwl_op_mode *op_mode, u8 ac) -{ - struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); - - ieee80211_stop_queue(priv->hw, ac); -} - -void iwl_wake_sw_queue(struct iwl_op_mode *op_mode, u8 ac) -{ - struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); - - ieee80211_wake_queue(priv->hw, ac); -} diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index d1e722bd9f5b..74429702b130 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -670,8 +670,6 @@ struct iwl_rxon_context { bool enabled, is_40mhz; u8 extension_chan_offset; } ht; - - bool last_tx_rejected; }; enum iwl_scan_type { @@ -720,6 +718,9 @@ struct iwl_priv { spinlock_t sta_lock; struct mutex mutex; + unsigned long transport_queue_stop; + bool passive_no_rx; + /* ieee device used by generic ieee processing code */ struct ieee80211_hw *hw; struct ieee80211_channel *ieee_channels; diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h index d13b8d1f08fa..4f73a6d06509 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h @@ -451,18 +451,6 @@ static inline void iwl_stop_queue(struct iwl_trans *trans, } } -#ifdef ieee80211_stop_queue -#undef ieee80211_stop_queue -#endif - -#define ieee80211_stop_queue DO_NOT_USE_ieee80211_stop_queue - -#ifdef ieee80211_wake_queue -#undef ieee80211_wake_queue -#endif - -#define ieee80211_wake_queue DO_NOT_USE_ieee80211_wake_queue - static inline void iwl_txq_ctx_activate(struct iwl_trans_pcie *trans_pcie, int txq_id) { diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c index 26bb44242090..1c4fbcd348a8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c @@ -1559,8 +1559,7 @@ static void iwl_trans_pcie_stop_hw(struct iwl_trans *trans) } static int iwl_trans_pcie_reclaim(struct iwl_trans *trans, int sta_id, int tid, - int txq_id, int ssn, u32 status, - struct sk_buff_head *skbs) + int txq_id, int ssn, struct sk_buff_head *skbs) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); struct iwl_tx_queue *txq = &trans_pcie->txq[txq_id]; @@ -1593,9 +1592,7 @@ static int iwl_trans_pcie_reclaim(struct iwl_trans *trans, int sta_id, int tid, txq_id, iwl_get_queue_ac(txq), txq->q.read_ptr, tfd_num, ssn); freed = iwl_tx_queue_reclaim(trans, txq_id, tfd_num, skbs); - if (iwl_queue_space(&txq->q) > txq->q.low_mark && - (!txq->sched_retry || - status != TX_STATUS_FAIL_PASSIVE_NO_RX)) + if (iwl_queue_space(&txq->q) > txq->q.low_mark) iwl_wake_queue(trans, txq, "Packets reclaimed"); } @@ -1662,32 +1659,6 @@ static int iwl_trans_pcie_resume(struct iwl_trans *trans) } #endif /* CONFIG_PM_SLEEP */ -static void iwl_trans_pcie_wake_any_queue(struct iwl_trans *trans, - enum iwl_rxon_context_id ctx, - const char *msg) -{ - u8 ac, txq_id; - struct iwl_trans_pcie *trans_pcie = - IWL_TRANS_GET_PCIE_TRANS(trans); - - for (ac = 0; ac < AC_NUM; ac++) { - txq_id = trans_pcie->ac_to_queue[ctx][ac]; - IWL_DEBUG_TX_QUEUES(trans, "Queue Status: Q[%d] %s\n", - ac, - (atomic_read(&trans_pcie->queue_stop_count[ac]) > 0) - ? "stopped" : "awake"); - iwl_wake_queue(trans, &trans_pcie->txq[txq_id], msg); - } -} - -static void iwl_trans_pcie_stop_queue(struct iwl_trans *trans, int txq_id, - const char *msg) -{ - struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); - - iwl_stop_queue(trans, &trans_pcie->txq[txq_id], msg); -} - #define IWL_FLUSH_WAIT_MS 2000 static int iwl_trans_pcie_wait_tx_queue_empty(struct iwl_trans *trans) @@ -2207,8 +2178,6 @@ const struct iwl_trans_ops trans_ops_pcie = { .wowlan_suspend = iwl_trans_pcie_wowlan_suspend, - .wake_any_queue = iwl_trans_pcie_wake_any_queue, - .send_cmd = iwl_trans_pcie_send_cmd, .tx = iwl_trans_pcie_tx, @@ -2219,7 +2188,6 @@ const struct iwl_trans_ops trans_ops_pcie = { .tx_agg_setup = iwl_trans_pcie_tx_agg_setup, .free = iwl_trans_pcie_free, - .stop_queue = iwl_trans_pcie_stop_queue, .dbgfs_register = iwl_trans_pcie_dbgfs_register, diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index 15bb208ab347..609949f0299c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h @@ -289,7 +289,6 @@ static inline struct page *rxb_steal_page(struct iwl_rx_cmd_buffer *r) * May sleep * @fw_alive: called when the fw sends alive notification * May sleep - * @wake_any_queue: wake all the queues of a specfic context IWL_RXON_CTX_* * @stop_device:stops the whole device (embedded CPU put to reset) * May sleep * @wowlan_suspend: put the device into the correct mode for WoWLAN during @@ -312,7 +311,6 @@ static inline struct page *rxb_steal_page(struct iwl_rx_cmd_buffer *r) * irq, tasklet etc... From this point on, the device may not issue * any interrupt (incl. RFKILL). * May sleep - * @stop_queue: stop a specific queue * @check_stuck_queue: check if a specific queue is stuck * @wait_tx_queue_empty: wait until all tx queues are empty * May sleep @@ -334,18 +332,13 @@ struct iwl_trans_ops { void (*wowlan_suspend)(struct iwl_trans *trans); - void (*wake_any_queue)(struct iwl_trans *trans, - enum iwl_rxon_context_id ctx, - const char *msg); - int (*send_cmd)(struct iwl_trans *trans, struct iwl_host_cmd *cmd); int (*tx)(struct iwl_trans *trans, struct sk_buff *skb, struct iwl_device_cmd *dev_cmd, enum iwl_rxon_context_id ctx, u8 sta_id, u8 tid); int (*reclaim)(struct iwl_trans *trans, int sta_id, int tid, - int txq_id, int ssn, u32 status, - struct sk_buff_head *skbs); + int txq_id, int ssn, struct sk_buff_head *skbs); int (*tx_agg_disable)(struct iwl_trans *trans, int sta_id, int tid); @@ -357,8 +350,6 @@ struct iwl_trans_ops { void (*free)(struct iwl_trans *trans); - void (*stop_queue)(struct iwl_trans *trans, int q, const char *msg); - int (*dbgfs_register)(struct iwl_trans *trans, struct dentry* dir); int (*check_stuck_queue)(struct iwl_trans *trans, int q); int (*wait_tx_queue_empty)(struct iwl_trans *trans); @@ -474,17 +465,6 @@ static inline void iwl_trans_wowlan_suspend(struct iwl_trans *trans) trans->ops->wowlan_suspend(trans); } -static inline void iwl_trans_wake_any_queue(struct iwl_trans *trans, - enum iwl_rxon_context_id ctx, - const char *msg) -{ - if (trans->state != IWL_TRANS_FW_ALIVE) - IWL_ERR(trans, "%s bad state = %d", __func__, trans->state); - - trans->ops->wake_any_queue(trans, ctx, msg); -} - - static inline int iwl_trans_send_cmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd) { @@ -505,14 +485,13 @@ static inline int iwl_trans_tx(struct iwl_trans *trans, struct sk_buff *skb, } static inline int iwl_trans_reclaim(struct iwl_trans *trans, int sta_id, - int tid, int txq_id, int ssn, u32 status, + int tid, int txq_id, int ssn, struct sk_buff_head *skbs) { if (trans->state != IWL_TRANS_FW_ALIVE) IWL_ERR(trans, "%s bad state = %d", __func__, trans->state); - return trans->ops->reclaim(trans, sta_id, tid, txq_id, ssn, - status, skbs); + return trans->ops->reclaim(trans, sta_id, tid, txq_id, ssn, skbs); } static inline int iwl_trans_tx_agg_disable(struct iwl_trans *trans, @@ -554,15 +533,6 @@ static inline void iwl_trans_free(struct iwl_trans *trans) trans->ops->free(trans); } -static inline void iwl_trans_stop_queue(struct iwl_trans *trans, int q, - const char *msg) -{ - if (trans->state != IWL_TRANS_FW_ALIVE) - IWL_ERR(trans, "%s bad state = %d", __func__, trans->state); - - trans->ops->stop_queue(trans, q, msg); -} - static inline int iwl_trans_wait_tx_queue_empty(struct iwl_trans *trans) { if (trans->state != IWL_TRANS_FW_ALIVE) diff --git a/drivers/net/wireless/iwlwifi/iwl-ucode.c b/drivers/net/wireless/iwlwifi/iwl-ucode.c index 8267dbe869d5..404fd8e7958b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-ucode.c +++ b/drivers/net/wireless/iwlwifi/iwl-ucode.c @@ -316,7 +316,6 @@ int iwl_send_bt_env(struct iwl_priv *priv, u8 action, u8 type) static int iwl_alive_notify(struct iwl_priv *priv) { - struct iwl_rxon_context *ctx; int ret; if (!priv->tx_cmd_pool) @@ -329,8 +328,9 @@ static int iwl_alive_notify(struct iwl_priv *priv) return -ENOMEM; iwl_trans_fw_alive(trans(priv)); - for_each_context(priv, ctx) - ctx->last_tx_rejected = false; + + priv->passive_no_rx = false; + priv->transport_queue_stop = 0; ret = iwl_send_wimax_coex(priv); if (ret) -- cgit From b0b4619273dd8b9414a4632f8f229e4f2897ff45 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 7 Mar 2012 09:52:17 -0800 Subject: iwlwifi: transport's tx_agg_disable must be atomic At least as long as it is called from the reclaim flow (iwlagn_check_ratid_empty) it must be atomic. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-trans.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index 609949f0299c..ed6ab449e439 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h @@ -306,7 +306,7 @@ static inline struct page *rxb_steal_page(struct iwl_rx_cmd_buffer *r) * ready and a successful ADDBA response has been received. * May sleep * @tx_agg_disable: de-configure a Tx queue to send AMPDUs - * May sleep + * Must be atomic * @free: release all the ressource for the transport layer itself such as * irq, tasklet etc... From this point on, the device may not issue * any interrupt (incl. RFKILL). @@ -497,8 +497,6 @@ static inline int iwl_trans_reclaim(struct iwl_trans *trans, int sta_id, static inline int iwl_trans_tx_agg_disable(struct iwl_trans *trans, int sta_id, int tid) { - might_sleep(); - if (trans->state != IWL_TRANS_FW_ALIVE) IWL_ERR(trans, "%s bad state = %d", __func__, trans->state); -- cgit From 562f08eb8020cf3672c3743752f82d962ecb7788 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 7 Mar 2012 09:52:18 -0800 Subject: iwlwifi: remove BT handlers from lib_ops There's no need to have operations for these as they simply depend on whether the device has built-in bluetooth, so just duplicate the information already there (whether bt_params is present or not). Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-2000.c | 3 --- drivers/net/wireless/iwlwifi/iwl-6000.c | 3 --- drivers/net/wireless/iwlwifi/iwl-agn-rx.c | 5 ++--- drivers/net/wireless/iwlwifi/iwl-agn.c | 8 ++++---- drivers/net/wireless/iwlwifi/iwl-core.h | 6 ------ 5 files changed, 6 insertions(+), 19 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c index 446d010dfe84..d6ba8419c940 100644 --- a/drivers/net/wireless/iwlwifi/iwl-2000.c +++ b/drivers/net/wireless/iwlwifi/iwl-2000.c @@ -156,9 +156,6 @@ static struct iwl_lib_ops iwl2000_lib = { static struct iwl_lib_ops iwl2030_lib = { .set_hw_params = iwl2000_hw_set_hw_params, - .bt_rx_handler_setup = iwlagn_bt_rx_handler_setup, - .bt_setup_deferred_work = iwlagn_bt_setup_deferred_work, - .cancel_deferred_work = iwlagn_bt_cancel_deferred_work, .nic_config = iwl2000_nic_config, .eeprom_ops = { .regulatory_bands = { diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index d299f05dfc9b..904c50af92fd 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -252,9 +252,6 @@ static struct iwl_lib_ops iwl6000_lib = { static struct iwl_lib_ops iwl6030_lib = { .set_hw_params = iwl6000_hw_set_hw_params, - .bt_rx_handler_setup = iwlagn_bt_rx_handler_setup, - .bt_setup_deferred_work = iwlagn_bt_setup_deferred_work, - .cancel_deferred_work = iwlagn_bt_cancel_deferred_work, .set_channel_switch = iwl6000_hw_channel_switch, .nic_config = iwl6000_nic_config, .eeprom_ops = { diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c index a9bdbad6663e..e504675f2637 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c @@ -1143,9 +1143,8 @@ void iwl_setup_rx_handlers(struct iwl_priv *priv) iwl_notification_wait_init(&priv->notif_wait); /* Set up BT Rx handlers */ - if (cfg(priv)->lib->bt_rx_handler_setup) - cfg(priv)->lib->bt_rx_handler_setup(priv); - + if (cfg(priv)->bt_params) + iwlagn_bt_rx_handler_setup(priv); } int iwl_rx_dispatch(struct iwl_op_mode *op_mode, struct iwl_rx_cmd_buffer *rxb, diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 29f40eab9715..5f390f8d3b8b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -976,8 +976,8 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv) iwl_setup_scan_deferred_work(priv); - if (cfg(priv)->lib->bt_setup_deferred_work) - cfg(priv)->lib->bt_setup_deferred_work(priv); + if (cfg(priv)->bt_params) + iwlagn_bt_setup_deferred_work(priv); init_timer(&priv->statistics_periodic); priv->statistics_periodic.data = (unsigned long)priv; @@ -994,8 +994,8 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv) void iwl_cancel_deferred_work(struct iwl_priv *priv) { - if (cfg(priv)->lib->cancel_deferred_work) - cfg(priv)->lib->cancel_deferred_work(priv); + if (cfg(priv)->bt_params) + iwlagn_bt_cancel_deferred_work(priv); cancel_work_sync(&priv->run_time_calib_work); cancel_work_sync(&priv->beacon_update); diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index e0423c4c01c7..95f6b7b0abf7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -77,12 +77,6 @@ struct iwl_cmd; struct iwl_lib_ops { /* set hw dependent parameters */ void (*set_hw_params)(struct iwl_priv *priv); - /* setup BT Rx handler */ - void (*bt_rx_handler_setup)(struct iwl_priv *priv); - /* setup BT related deferred work */ - void (*bt_setup_deferred_work)(struct iwl_priv *priv); - /* cancel deferred work */ - void (*cancel_deferred_work)(struct iwl_priv *priv); int (*set_channel_switch)(struct iwl_priv *priv, struct ieee80211_channel_switch *ch_switch); /* device specific configuration */ -- cgit From a75a79a84ffd7fea9e10f327d1e2f2fa25770375 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 7 Mar 2012 09:52:19 -0800 Subject: iwlwifi: move BT/HT params to shared Hardware parameters will be shared, so move the definitions into the shared header file. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-core.h | 24 ------------------------ drivers/net/wireless/iwlwifi/iwl-shared.h | 24 ++++++++++++++++++++++++ 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 95f6b7b0abf7..635eb685edeb 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -89,30 +89,6 @@ struct iwl_lib_ops { void (*temperature)(struct iwl_priv *priv); }; -/* - * @advanced_bt_coexist: support advanced bt coexist - * @bt_init_traffic_load: specify initial bt traffic load - * @bt_prio_boost: default bt priority boost value - * @agg_time_limit: maximum number of uSec in aggregation - * @bt_sco_disable: uCode should not response to BT in SCO/ESCO mode - */ -struct iwl_bt_params { - bool advanced_bt_coexist; - u8 bt_init_traffic_load; - u8 bt_prio_boost; - u16 agg_time_limit; - bool bt_sco_disable; - bool bt_session_2; -}; -/* - * @use_rts_for_aggregation: use rts/cts protection for HT traffic - */ -struct iwl_ht_params { - const bool ht_greenfield_support; /* if used set to true */ - bool use_rts_for_aggregation; - enum ieee80211_smps_mode smps_mode; -}; - /*************************** * L i b * ***************************/ diff --git a/drivers/net/wireless/iwlwifi/iwl-shared.h b/drivers/net/wireless/iwlwifi/iwl-shared.h index ff3394c47635..45409fcfbbd7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-shared.h +++ b/drivers/net/wireless/iwlwifi/iwl-shared.h @@ -270,6 +270,30 @@ struct iwl_base_params { const bool wd_disable; }; +/* + * @advanced_bt_coexist: support advanced bt coexist + * @bt_init_traffic_load: specify initial bt traffic load + * @bt_prio_boost: default bt priority boost value + * @agg_time_limit: maximum number of uSec in aggregation + * @bt_sco_disable: uCode should not response to BT in SCO/ESCO mode + */ +struct iwl_bt_params { + bool advanced_bt_coexist; + u8 bt_init_traffic_load; + u8 bt_prio_boost; + u16 agg_time_limit; + bool bt_sco_disable; + bool bt_session_2; +}; +/* + * @use_rts_for_aggregation: use rts/cts protection for HT traffic + */ +struct iwl_ht_params { + const bool ht_greenfield_support; /* if used set to true */ + bool use_rts_for_aggregation; + enum ieee80211_smps_mode smps_mode; +}; + /** * struct iwl_cfg * @name: Offical name of the device -- cgit From 51dc51d12bd609644bbe9877825a1a25a6016639 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 7 Mar 2012 09:52:20 -0800 Subject: iwlwifi: make EEPROM enhanced TX power a bool There's no need to carry around the function pointer when a boolean indicating that the EEPROM stores enhanced TX power information is sufficient. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-2000.c | 4 ++-- drivers/net/wireless/iwlwifi/iwl-6000.c | 4 ++-- drivers/net/wireless/iwlwifi/iwl-agn.h | 1 - drivers/net/wireless/iwlwifi/iwl-eeprom.c | 6 +++--- drivers/net/wireless/iwlwifi/iwl-eeprom.h | 2 +- 5 files changed, 8 insertions(+), 9 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c index d6ba8419c940..14ce83bc71a5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-2000.c +++ b/drivers/net/wireless/iwlwifi/iwl-2000.c @@ -149,7 +149,7 @@ static struct iwl_lib_ops iwl2000_lib = { EEPROM_6000_REG_BAND_24_HT40_CHANNELS, EEPROM_REGULATORY_BAND_NO_HT40, }, - .update_enhanced_txpower = iwl_eeprom_enhanced_txpower, + .enhanced_txpower = true, }, .temperature = iwlagn_temperature, }; @@ -167,7 +167,7 @@ static struct iwl_lib_ops iwl2030_lib = { EEPROM_6000_REG_BAND_24_HT40_CHANNELS, EEPROM_REGULATORY_BAND_NO_HT40, }, - .update_enhanced_txpower = iwl_eeprom_enhanced_txpower, + .enhanced_txpower = true, }, .temperature = iwlagn_temperature, }; diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index 904c50af92fd..0f89e45da1a2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -245,7 +245,7 @@ static struct iwl_lib_ops iwl6000_lib = { EEPROM_6000_REG_BAND_24_HT40_CHANNELS, EEPROM_REG_BAND_52_HT40_CHANNELS }, - .update_enhanced_txpower = iwl_eeprom_enhanced_txpower, + .enhanced_txpower = true, }, .temperature = iwlagn_temperature, }; @@ -264,7 +264,7 @@ static struct iwl_lib_ops iwl6030_lib = { EEPROM_6000_REG_BAND_24_HT40_CHANNELS, EEPROM_REG_BAND_52_HT40_CHANNELS }, - .update_enhanced_txpower = iwl_eeprom_enhanced_txpower, + .enhanced_txpower = true, }, .temperature = iwlagn_temperature, }; diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index b56498b796c2..6345ab0f2a96 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h @@ -305,7 +305,6 @@ static inline __le32 iwl_hw_set_rate_n_flags(u8 rate, u32 flags) } /* eeprom */ -void iwl_eeprom_enhanced_txpower(struct iwl_priv *priv); void iwl_eeprom_get_mac(const struct iwl_shared *shrd, u8 *mac); extern int iwl_alive_start(struct iwl_priv *priv); diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c index e2d80849001f..23cea42b9495 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c @@ -589,7 +589,7 @@ iwl_eeprom_enh_txp_read_element(struct iwl_priv *priv, #define TXP_CHECK_AND_PRINT(x) ((txp->flags & IWL_EEPROM_ENH_TXP_FL_##x) \ ? # x " " : "") -void iwl_eeprom_enhanced_txpower(struct iwl_priv *priv) +static void iwl_eeprom_enhanced_txpower(struct iwl_priv *priv) { struct iwl_shared *shrd = priv->shrd; struct iwl_eeprom_enhanced_txpwr *txp_array, *txp; @@ -1025,8 +1025,8 @@ int iwl_init_channel_map(struct iwl_priv *priv) * driver need to process addition information * to determine the max channel tx power limits */ - if (cfg(priv)->lib->eeprom_ops.update_enhanced_txpower) - cfg(priv)->lib->eeprom_ops.update_enhanced_txpower(priv); + if (cfg(priv)->lib->eeprom_ops.enhanced_txpower) + iwl_eeprom_enhanced_txpower(priv); return 0; } diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.h b/drivers/net/wireless/iwlwifi/iwl-eeprom.h index 3b17056d5675..e4a758340996 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.h +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.h @@ -302,7 +302,7 @@ extern const u8 iwl_eeprom_band_1[14]; struct iwl_eeprom_ops { const u32 regulatory_bands[7]; - void (*update_enhanced_txpower) (struct iwl_priv *priv); + bool enhanced_txpower; }; -- cgit From 9563fe1696fa0ced8cfa3f935736d4662a81c1c3 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 7 Mar 2012 09:52:21 -0800 Subject: iwlwifi: remove unused max_nrg_cck from sensitivity and constify The sensitivity parameters are never modified, so they should be const. Also remove the unused max_nrg_cck value to save some space. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-1000.c | 3 +-- drivers/net/wireless/iwlwifi/iwl-2000.c | 3 +-- drivers/net/wireless/iwlwifi/iwl-5000.c | 4 +--- drivers/net/wireless/iwlwifi/iwl-6000.c | 3 +-- drivers/net/wireless/iwlwifi/iwl-dev.h | 1 - 5 files changed, 4 insertions(+), 10 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index f6e6f57aade5..450250332e4b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c @@ -96,9 +96,8 @@ static void iwl1000_nic_config(struct iwl_priv *priv) ~APMG_SVR_VOLTAGE_CONFIG_BIT_MSK); } -static struct iwl_sensitivity_ranges iwl1000_sensitivity = { +static const struct iwl_sensitivity_ranges iwl1000_sensitivity = { .min_nrg_cck = 95, - .max_nrg_cck = 0, /* not used, set to 0 */ .auto_corr_min_ofdm = 90, .auto_corr_min_ofdm_mrc = 170, .auto_corr_min_ofdm_x1 = 120, diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c index 14ce83bc71a5..abfd901e81a2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-2000.c +++ b/drivers/net/wireless/iwlwifi/iwl-2000.c @@ -91,9 +91,8 @@ static void iwl2000_nic_config(struct iwl_priv *priv) CSR_GP_DRIVER_REG_BIT_RADIO_IQ_INVER); } -static struct iwl_sensitivity_ranges iwl2000_sensitivity = { +static const struct iwl_sensitivity_ranges iwl2000_sensitivity = { .min_nrg_cck = 97, - .max_nrg_cck = 0, /* not used, set to 0 */ .auto_corr_min_ofdm = 80, .auto_corr_min_ofdm_mrc = 128, .auto_corr_min_ofdm_x1 = 105, diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index 907a0b22f7b2..9e187f8f5ae4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -75,9 +75,8 @@ static void iwl5000_nic_config(struct iwl_priv *priv) ~APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS); } -static struct iwl_sensitivity_ranges iwl5000_sensitivity = { +static const struct iwl_sensitivity_ranges iwl5000_sensitivity = { .min_nrg_cck = 100, - .max_nrg_cck = 0, /* not used, set to 0 */ .auto_corr_min_ofdm = 90, .auto_corr_min_ofdm_mrc = 170, .auto_corr_min_ofdm_x1 = 105, @@ -102,7 +101,6 @@ static struct iwl_sensitivity_ranges iwl5000_sensitivity = { static struct iwl_sensitivity_ranges iwl5150_sensitivity = { .min_nrg_cck = 95, - .max_nrg_cck = 0, /* not used, set to 0 */ .auto_corr_min_ofdm = 90, .auto_corr_min_ofdm_mrc = 170, .auto_corr_min_ofdm_x1 = 105, diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index 0f89e45da1a2..e64bc6b7bcbf 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -113,9 +113,8 @@ static void iwl6000_nic_config(struct iwl_priv *priv) cfg(priv)->additional_nic_config(priv); } -static struct iwl_sensitivity_ranges iwl6000_sensitivity = { +static const struct iwl_sensitivity_ranges iwl6000_sensitivity = { .min_nrg_cck = 110, - .max_nrg_cck = 0, /* not used, set to 0 */ .auto_corr_min_ofdm = 80, .auto_corr_min_ofdm_mrc = 128, .auto_corr_min_ofdm_x1 = 105, diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 74429702b130..c3f372e2c142 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -294,7 +294,6 @@ struct iwl_vif_priv { struct iwl_sensitivity_ranges { u16 min_nrg_cck; - u16 max_nrg_cck; u16 nrg_th_cck; u16 nrg_th_ofdm; -- cgit From 9441b85d59ec9d06cbe749e12a59a06c09e601fa Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 7 Mar 2012 09:52:22 -0800 Subject: iwlwifi: return error if loading uCode failed In "iwlwifi: consolidate the start_device flow" the code flow changed and the firmware is now loaded by the transport layer, but the change unfortunately lost error checking -- restore. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c index 1c4fbcd348a8..ef76a3916189 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c @@ -1070,9 +1070,7 @@ static int iwl_trans_pcie_start_fw(struct iwl_trans *trans, iwl_write32(trans, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); /* Load the given image to the HW */ - iwl_load_given_ucode(trans, fw); - - return 0; + return iwl_load_given_ucode(trans, fw); } /* -- cgit From aa5affbacb24cb5d8fd6f7c66e57d62164ed6d34 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Wed, 7 Mar 2012 09:52:23 -0800 Subject: iwlwifi: dump stack when fail to gain access to the device Print dump stack when the device is not responding. This should give some more clue about the reason of failure. Also change the message we print, since "MAC in deep sleep" is kinda confusing. On the way add unlikely(), as fail to gain NIC access is hmm ... unlikely. Signed-off-by: Stanislaw Gruszka Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-io.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-io.c b/drivers/net/wireless/iwlwifi/iwl-io.c index e2e3b5c9cf7f..fc365350a3e7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-io.c +++ b/drivers/net/wireless/iwlwifi/iwl-io.c @@ -121,10 +121,10 @@ int iwl_grab_nic_access_silent(struct iwl_trans *trans) int iwl_grab_nic_access(struct iwl_trans *trans) { int ret = iwl_grab_nic_access_silent(trans); - if (ret) { + if (unlikely(ret)) { u32 val = iwl_read32(trans, CSR_GP_CNTRL); - IWL_ERR(trans, - "MAC is in deep sleep!. CSR_GP_CNTRL = 0x%08X\n", val); + WARN_ONCE(1, "Timeout waiting for hardware access " + "(CSR_GP_CNTRL 0x%08x)\n", val); } return ret; -- cgit From bfe4b80e9f7385f34986736cdc094be56782109a Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Wed, 7 Mar 2012 09:52:24 -0800 Subject: iwlwifi: always check if got h/w access before write Before we write to the device registers always check if iwl_grap_nic_access() was successful. On the way change return type of grab_nic_access() to bool, and add likely()/unlikely() statement. Signed-off-by: Stanislaw Gruszka Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-tt.c | 2 +- drivers/net/wireless/iwlwifi/iwl-agn.c | 2 +- drivers/net/wireless/iwlwifi/iwl-io.c | 53 +++++++++++++----------- drivers/net/wireless/iwlwifi/iwl-io.h | 2 +- drivers/net/wireless/iwlwifi/iwl-mac80211.c | 2 +- drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c | 4 +- 6 files changed, 35 insertions(+), 30 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tt.c b/drivers/net/wireless/iwlwifi/iwl-agn-tt.c index 7712c5537370..9a12b70c7d4f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tt.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tt.c @@ -189,7 +189,7 @@ static void iwl_tt_check_exit_ct_kill(unsigned long data) } iwl_read32(trans(priv), CSR_UCODE_DRV_GP1); spin_lock_irqsave(&trans(priv)->reg_lock, flags); - if (!iwl_grab_nic_access(trans(priv))) + if (likely(iwl_grab_nic_access(trans(priv)))) iwl_release_nic_access(trans(priv)); spin_unlock_irqrestore(&trans(priv)->reg_lock, flags); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 5f390f8d3b8b..ce9ebeb89e4c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -327,7 +327,7 @@ static void iwl_print_cont_event_trace(struct iwl_priv *priv, u32 base, /* Make sure device is powered up for SRAM reads */ spin_lock_irqsave(&trans(priv)->reg_lock, reg_flags); - if (iwl_grab_nic_access(trans(priv))) { + if (unlikely(!iwl_grab_nic_access(trans(priv)))) { spin_unlock_irqrestore(&trans(priv)->reg_lock, reg_flags); return; } diff --git a/drivers/net/wireless/iwlwifi/iwl-io.c b/drivers/net/wireless/iwlwifi/iwl-io.c index fc365350a3e7..fa69845954cf 100644 --- a/drivers/net/wireless/iwlwifi/iwl-io.c +++ b/drivers/net/wireless/iwlwifi/iwl-io.c @@ -118,16 +118,17 @@ int iwl_grab_nic_access_silent(struct iwl_trans *trans) return 0; } -int iwl_grab_nic_access(struct iwl_trans *trans) +bool iwl_grab_nic_access(struct iwl_trans *trans) { int ret = iwl_grab_nic_access_silent(trans); if (unlikely(ret)) { u32 val = iwl_read32(trans, CSR_GP_CNTRL); WARN_ONCE(1, "Timeout waiting for hardware access " "(CSR_GP_CNTRL 0x%08x)\n", val); + return false; } - return ret; + return true; } void iwl_release_nic_access(struct iwl_trans *trans) @@ -156,7 +157,7 @@ void iwl_write_direct32(struct iwl_trans *trans, u32 reg, u32 value) unsigned long flags; spin_lock_irqsave(&trans->reg_lock, flags); - if (!iwl_grab_nic_access(trans)) { + if (likely(iwl_grab_nic_access(trans))) { iwl_write32(trans, reg, value); iwl_release_nic_access(trans); } @@ -211,7 +212,7 @@ void iwl_write_prph(struct iwl_trans *trans, u32 addr, u32 val) unsigned long flags; spin_lock_irqsave(&trans->reg_lock, flags); - if (!iwl_grab_nic_access(trans)) { + if (likely(iwl_grab_nic_access(trans))) { __iwl_write_prph(trans, addr, val); iwl_release_nic_access(trans); } @@ -223,9 +224,11 @@ void iwl_set_bits_prph(struct iwl_trans *trans, u32 reg, u32 mask) unsigned long flags; spin_lock_irqsave(&trans->reg_lock, flags); - iwl_grab_nic_access(trans); - __iwl_write_prph(trans, reg, __iwl_read_prph(trans, reg) | mask); - iwl_release_nic_access(trans); + if (likely(iwl_grab_nic_access(trans))) { + __iwl_write_prph(trans, reg, + __iwl_read_prph(trans, reg) | mask); + iwl_release_nic_access(trans); + } spin_unlock_irqrestore(&trans->reg_lock, flags); } @@ -235,10 +238,11 @@ void iwl_set_bits_mask_prph(struct iwl_trans *trans, u32 reg, unsigned long flags; spin_lock_irqsave(&trans->reg_lock, flags); - iwl_grab_nic_access(trans); - __iwl_write_prph(trans, reg, - (__iwl_read_prph(trans, reg) & mask) | bits); - iwl_release_nic_access(trans); + if (likely(iwl_grab_nic_access(trans))) { + __iwl_write_prph(trans, reg, + (__iwl_read_prph(trans, reg) & mask) | bits); + iwl_release_nic_access(trans); + } spin_unlock_irqrestore(&trans->reg_lock, flags); } @@ -248,10 +252,11 @@ void iwl_clear_bits_prph(struct iwl_trans *trans, u32 reg, u32 mask) u32 val; spin_lock_irqsave(&trans->reg_lock, flags); - iwl_grab_nic_access(trans); - val = __iwl_read_prph(trans, reg); - __iwl_write_prph(trans, reg, (val & ~mask)); - iwl_release_nic_access(trans); + if (likely(iwl_grab_nic_access(trans))) { + val = __iwl_read_prph(trans, reg); + __iwl_write_prph(trans, reg, (val & ~mask)); + iwl_release_nic_access(trans); + } spin_unlock_irqrestore(&trans->reg_lock, flags); } @@ -263,15 +268,13 @@ void _iwl_read_targ_mem_words(struct iwl_trans *trans, u32 addr, u32 *vals = buf; spin_lock_irqsave(&trans->reg_lock, flags); - iwl_grab_nic_access(trans); - - iwl_write32(trans, HBUS_TARG_MEM_RADDR, addr); - rmb(); - - for (offs = 0; offs < words; offs++) - vals[offs] = iwl_read32(trans, HBUS_TARG_MEM_RDAT); - - iwl_release_nic_access(trans); + if (likely(iwl_grab_nic_access(trans))) { + iwl_write32(trans, HBUS_TARG_MEM_RADDR, addr); + rmb(); + for (offs = 0; offs < words; offs++) + vals[offs] = iwl_read32(trans, HBUS_TARG_MEM_RDAT); + iwl_release_nic_access(trans); + } spin_unlock_irqrestore(&trans->reg_lock, flags); } @@ -292,7 +295,7 @@ int _iwl_write_targ_mem_words(struct iwl_trans *trans, u32 addr, u32 *vals = buf; spin_lock_irqsave(&trans->reg_lock, flags); - if (!iwl_grab_nic_access(trans)) { + if (likely(iwl_grab_nic_access(trans))) { iwl_write32(trans, HBUS_TARG_MEM_WADDR, addr); wmb(); diff --git a/drivers/net/wireless/iwlwifi/iwl-io.h b/drivers/net/wireless/iwlwifi/iwl-io.h index 1136dc19936a..09b856768f62 100644 --- a/drivers/net/wireless/iwlwifi/iwl-io.h +++ b/drivers/net/wireless/iwlwifi/iwl-io.h @@ -61,7 +61,7 @@ int iwl_poll_direct_bit(struct iwl_trans *trans, u32 addr, u32 mask, int timeout); int iwl_grab_nic_access_silent(struct iwl_trans *trans); -int iwl_grab_nic_access(struct iwl_trans *trans); +bool iwl_grab_nic_access(struct iwl_trans *trans); void iwl_release_nic_access(struct iwl_trans *trans); u32 iwl_read_direct32(struct iwl_trans *trans, u32 reg); diff --git a/drivers/net/wireless/iwlwifi/iwl-mac80211.c b/drivers/net/wireless/iwlwifi/iwl-mac80211.c index bdcbbd0d3467..91a42c3261aa 100644 --- a/drivers/net/wireless/iwlwifi/iwl-mac80211.c +++ b/drivers/net/wireless/iwlwifi/iwl-mac80211.c @@ -445,7 +445,7 @@ static int iwlagn_mac_resume(struct ieee80211_hw *hw) if (iwlagn_hw_valid_rtc_data_addr(base)) { spin_lock_irqsave(&trans(priv)->reg_lock, flags); ret = iwl_grab_nic_access_silent(trans(priv)); - if (ret == 0) { + if (likely(ret == 0)) { iwl_write32(trans(priv), HBUS_TARG_MEM_RADDR, base); status = iwl_read32(trans(priv), HBUS_TARG_MEM_RDAT); iwl_release_nic_access(trans(priv)); diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c index 83cc60e8f607..5d1fc7b1b0a3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c @@ -745,7 +745,8 @@ static int iwl_print_event_log(struct iwl_trans *trans, u32 start_idx, /* Make sure device is powered up for SRAM reads */ spin_lock_irqsave(&trans->reg_lock, reg_flags); - iwl_grab_nic_access(trans); + if (unlikely(!iwl_grab_nic_access(trans))) + goto out_unlock; /* Set starting address; reads will auto-increment */ iwl_write32(trans, HBUS_TARG_MEM_RADDR, ptr); @@ -785,6 +786,7 @@ static int iwl_print_event_log(struct iwl_trans *trans, u32 start_idx, /* Allow device to power down */ iwl_release_nic_access(trans); +out_unlock: spin_unlock_irqrestore(&trans->reg_lock, reg_flags); return pos; } -- cgit From 3a73a30049f20a0ff3ef1c5c10170a9c5539e042 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Wed, 7 Mar 2012 09:52:25 -0800 Subject: iwlwifi: cleanup/fix memory barriers wmb(), rmb() are not needed when writel(), readl() are used as accessors for MMIO. We use them indirectly via iowrite32(), ioread32(). What is needed mmiowb(), for synchronizing writes coming from different CPUs on PCIe bridge (see in patch comments). This fortunately is not needed on x86, where mmiowb() is just defined as compiler barrier. As iwlwifi devices are most likely not used on anything other than x86, this is not so important fix. Signed-off-by: Stanislaw Gruszka Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn.c | 1 - drivers/net/wireless/iwlwifi/iwl-io.c | 12 +++++++----- drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c | 1 - 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index ce9ebeb89e4c..64bc2859dd1b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -334,7 +334,6 @@ static void iwl_print_cont_event_trace(struct iwl_priv *priv, u32 base, /* Set starting address; reads will auto-increment */ iwl_write32(trans(priv), HBUS_TARG_MEM_RADDR, ptr); - rmb(); /* * Refuse to read more than would have fit into the log from diff --git a/drivers/net/wireless/iwlwifi/iwl-io.c b/drivers/net/wireless/iwlwifi/iwl-io.c index fa69845954cf..081dd34d2387 100644 --- a/drivers/net/wireless/iwlwifi/iwl-io.c +++ b/drivers/net/wireless/iwlwifi/iwl-io.c @@ -136,6 +136,13 @@ void iwl_release_nic_access(struct iwl_trans *trans) lockdep_assert_held(&trans->reg_lock); __iwl_clear_bit(trans, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); + /* + * Above we read the CSR_GP_CNTRL register, which will flush + * any previous writes, but we need the write that clears the + * MAC_ACCESS_REQ bit to be performed before any other writes + * scheduled on different CPUs (after we drop reg_lock). + */ + mmiowb(); } u32 iwl_read_direct32(struct iwl_trans *trans, u32 reg) @@ -182,7 +189,6 @@ int iwl_poll_direct_bit(struct iwl_trans *trans, u32 addr, u32 mask, static inline u32 __iwl_read_prph(struct iwl_trans *trans, u32 reg) { iwl_write32(trans, HBUS_TARG_PRPH_RADDR, reg | (3 << 24)); - rmb(); return iwl_read32(trans, HBUS_TARG_PRPH_RDAT); } @@ -190,7 +196,6 @@ static inline void __iwl_write_prph(struct iwl_trans *trans, u32 addr, u32 val) { iwl_write32(trans, HBUS_TARG_PRPH_WADDR, ((addr & 0x0000FFFF) | (3 << 24))); - wmb(); iwl_write32(trans, HBUS_TARG_PRPH_WDAT, val); } @@ -270,7 +275,6 @@ void _iwl_read_targ_mem_words(struct iwl_trans *trans, u32 addr, spin_lock_irqsave(&trans->reg_lock, flags); if (likely(iwl_grab_nic_access(trans))) { iwl_write32(trans, HBUS_TARG_MEM_RADDR, addr); - rmb(); for (offs = 0; offs < words; offs++) vals[offs] = iwl_read32(trans, HBUS_TARG_MEM_RDAT); iwl_release_nic_access(trans); @@ -297,8 +301,6 @@ int _iwl_write_targ_mem_words(struct iwl_trans *trans, u32 addr, spin_lock_irqsave(&trans->reg_lock, flags); if (likely(iwl_grab_nic_access(trans))) { iwl_write32(trans, HBUS_TARG_MEM_WADDR, addr); - wmb(); - for (offs = 0; offs < words; offs++) iwl_write32(trans, HBUS_TARG_MEM_WDAT, vals[offs]); iwl_release_nic_access(trans); diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c index 5d1fc7b1b0a3..787229b352f6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c @@ -750,7 +750,6 @@ static int iwl_print_event_log(struct iwl_trans *trans, u32 start_idx, /* Set starting address; reads will auto-increment */ iwl_write32(trans, HBUS_TARG_MEM_RADDR, ptr); - rmb(); /* "time" is actually "data" for mode 0 (no timestamp). * place event id # at far right for easier visual parsing. */ -- cgit From 05f5b97ee0013fefbd9139cf8c3eda5f2a88c04a Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Wed, 7 Mar 2012 09:52:26 -0800 Subject: iwlwifi: use writeb,writel,readl directly That change will save us some CPU cycles at run time. Having port-based I/O seems to be not possible for PCIe devices. Signed-off-by: Stanislaw Gruszka Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/Kconfig | 2 +- drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | 13 ++++++------- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig index ae08498dfcad..5afd06ef0d8b 100644 --- a/drivers/net/wireless/iwlwifi/Kconfig +++ b/drivers/net/wireless/iwlwifi/Kconfig @@ -1,6 +1,6 @@ config IWLWIFI tristate "Intel Wireless WiFi Next Gen AGN - Wireless-N/Advanced-N/Ultimate-N (iwlwifi) " - depends on PCI && MAC80211 + depends on PCI && MAC80211 && HAS_IOMEM select FW_LOADER select NEW_LEDS select LEDS_CLASS diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c index ef76a3916189..389f99e6a8eb 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c @@ -1600,18 +1600,17 @@ static int iwl_trans_pcie_reclaim(struct iwl_trans *trans, int sta_id, int tid, static void iwl_trans_pcie_write8(struct iwl_trans *trans, u32 ofs, u8 val) { - iowrite8(val, IWL_TRANS_GET_PCIE_TRANS(trans)->hw_base + ofs); + writeb(val, IWL_TRANS_GET_PCIE_TRANS(trans)->hw_base + ofs); } static void iwl_trans_pcie_write32(struct iwl_trans *trans, u32 ofs, u32 val) { - iowrite32(val, IWL_TRANS_GET_PCIE_TRANS(trans)->hw_base + ofs); + writel(val, IWL_TRANS_GET_PCIE_TRANS(trans)->hw_base + ofs); } static u32 iwl_trans_pcie_read32(struct iwl_trans *trans, u32 ofs) { - u32 val = ioread32(IWL_TRANS_GET_PCIE_TRANS(trans)->hw_base + ofs); - return val; + return readl(IWL_TRANS_GET_PCIE_TRANS(trans)->hw_base + ofs); } static void iwl_trans_pcie_free(struct iwl_trans *trans) @@ -1629,7 +1628,7 @@ static void iwl_trans_pcie_free(struct iwl_trans *trans) } pci_disable_msi(trans_pcie->pci_dev); - pci_iounmap(trans_pcie->pci_dev, trans_pcie->hw_base); + iounmap(trans_pcie->hw_base); pci_release_regions(trans_pcie->pci_dev); pci_disable_device(trans_pcie->pci_dev); @@ -2258,9 +2257,9 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct iwl_shared *shrd, goto out_pci_disable_device; } - trans_pcie->hw_base = pci_iomap(pdev, 0, 0); + trans_pcie->hw_base = pci_ioremap_bar(pdev, 0); if (!trans_pcie->hw_base) { - dev_printk(KERN_ERR, &pdev->dev, "pci_iomap failed"); + dev_printk(KERN_ERR, &pdev->dev, "pci_ioremap_bar failed"); err = -ENODEV; goto out_pci_release_regions; } -- cgit From c2945f390dbc725f3c3ef044a6a3f4e3909a7758 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Wed, 7 Mar 2012 09:52:27 -0800 Subject: iwlwifi: print DMA stop timeout error only if it happened iwl_poll_direct_bit() return negative error value on timeout, positive values do not indicate an error. Signed-off-by: Stanislaw Gruszka Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c index 389f99e6a8eb..aced6f8ae1e9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c @@ -1211,7 +1211,7 @@ static void iwl_trans_pcie_fw_alive(struct iwl_trans *trans) */ static int iwl_trans_tx_stop(struct iwl_trans *trans) { - int ch, txq_id; + int ch, txq_id, ret; unsigned long flags; struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); @@ -1224,9 +1224,10 @@ static int iwl_trans_tx_stop(struct iwl_trans *trans) for (ch = 0; ch < FH_TCSR_CHNL_NUM; ch++) { iwl_write_direct32(trans, FH_TCSR_CHNL_TX_CONFIG_REG(ch), 0x0); - if (iwl_poll_direct_bit(trans, FH_TSSR_TX_STATUS_REG, + ret = iwl_poll_direct_bit(trans, FH_TSSR_TX_STATUS_REG, FH_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(ch), - 1000)) + 1000); + if (ret < 0) IWL_ERR(trans, "Failing on timeout while stopping" " DMA channel %d [0x%08x]", ch, iwl_read_direct32(trans, -- cgit From 8722c899a07f45457464803142bd1c2d2a2c3bd8 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Wed, 7 Mar 2012 09:52:28 -0800 Subject: iwlwifi: reintroduce iwl_enable_rfkill_int If device is disabled by rfkill switch, do not enable all interrupts, but only CSR_INT_BIT_RF_KILL to receive rfkill state change. Unblocking other interrupts might cause problems, since driver can not be prepared for receive them. Signed-off-by: Stanislaw Gruszka Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h | 6 ++++++ drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c | 6 ++---- drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | 13 ++++++++----- 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h index 4f73a6d06509..93d89a375a1c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h @@ -376,6 +376,12 @@ static inline void iwl_enable_interrupts(struct iwl_trans *trans) iwl_write32(trans, CSR_INT_MASK, trans_pcie->inta_mask); } +static inline void iwl_enable_rfkill_int(struct iwl_trans *trans) +{ + IWL_DEBUG_ISR(trans, "Enabling rfkill interrupt\n"); + iwl_write32(trans, CSR_INT_MASK, CSR_INT_BIT_RF_KILL); +} + /* * we have 8 bits used like this: * diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c index 787229b352f6..2d6ea42b0d8e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c @@ -1134,10 +1134,8 @@ void iwl_irq_tasklet(struct iwl_trans *trans) if (test_bit(STATUS_INT_ENABLED, &trans->shrd->status)) iwl_enable_interrupts(trans); /* Re-enable RF_KILL if it occurred */ - else if (handled & CSR_INT_BIT_RF_KILL) { - IWL_DEBUG_ISR(trans, "Enabling rfkill interrupt\n"); - iwl_write32(trans, CSR_INT_MASK, CSR_INT_BIT_RF_KILL); - } + else if (handled & CSR_INT_BIT_RF_KILL) + iwl_enable_rfkill_int(trans); } /****************************************************************************** diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c index aced6f8ae1e9..88e1c427f8f5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c @@ -1044,7 +1044,7 @@ static int iwl_trans_pcie_start_fw(struct iwl_trans *trans, iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rfkill); if (hw_rfkill) { - iwl_enable_interrupts(trans); + iwl_enable_rfkill_int(trans); return -ERFKILL; } @@ -1553,8 +1553,7 @@ static void iwl_trans_pcie_stop_hw(struct iwl_trans *trans) iwl_write32(trans, CSR_INT, 0xFFFFFFFF); /* Even if we stop the HW, we still want the RF kill interrupt */ - IWL_DEBUG_ISR(trans, "Enabling rfkill interrupt\n"); - iwl_write32(trans, CSR_INT_MASK, CSR_INT_BIT_RF_KILL); + iwl_enable_rfkill_int(trans); } static int iwl_trans_pcie_reclaim(struct iwl_trans *trans, int sta_id, int tid, @@ -1647,10 +1646,14 @@ static int iwl_trans_pcie_resume(struct iwl_trans *trans) { bool hw_rfkill; - iwl_enable_interrupts(trans); - hw_rfkill = !(iwl_read32(trans, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW); + + if (hw_rfkill) + iwl_enable_rfkill_int(trans); + else + iwl_enable_interrupts(trans); + iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rfkill); return 0; -- cgit From 0aef8ddc8bedac1db4c96fddc9fb1b44b730cf4f Mon Sep 17 00:00:00 2001 From: Amit Beka Date: Wed, 7 Mar 2012 09:52:29 -0800 Subject: iwlwifi: add testmode command for rx forwarding Added a testmode command which tells iwl_rx_dispatch to send the RX both as a notification to nl80211 and with the registered RX handlers. This is used for monitoring RX from userspace while preserving the regular flows in the driver. Signed-off-by: Amit Beka Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-rx.c | 20 ++++++++++++++---- drivers/net/wireless/iwlwifi/iwl-testmode.c | 32 ++++++++++++++++++++++++++--- drivers/net/wireless/iwlwifi/iwl-testmode.h | 13 ++++++++++-- 3 files changed, 56 insertions(+), 9 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c index e504675f2637..8e7cdfaf10cc 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c @@ -1152,6 +1152,8 @@ int iwl_rx_dispatch(struct iwl_op_mode *op_mode, struct iwl_rx_cmd_buffer *rxb, { struct iwl_rx_packet *pkt = rxb_addr(rxb); struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); + void (*pre_rx_handler)(struct iwl_priv *, + struct iwl_rx_cmd_buffer *); int err = 0; /* @@ -1161,10 +1163,20 @@ int iwl_rx_dispatch(struct iwl_op_mode *op_mode, struct iwl_rx_cmd_buffer *rxb, */ iwl_notification_wait_notify(&priv->notif_wait, pkt); - if (priv->pre_rx_handler && - priv->ucode_owner == IWL_OWNERSHIP_TM) - priv->pre_rx_handler(priv, rxb); - else { + /* RX data may be forwarded to userspace (using pre_rx_handler) in one + * of two cases: the first, that the user owns the uCode through + * testmode - in such case the pre_rx_handler is set and no further + * processing takes place. The other case is when the user want to + * monitor the rx w/o affecting the regular flow - the pre_rx_handler + * will be set but the ownership flag != IWL_OWNERSHIP_TM and the flow + * continues. + * We need to use ACCESS_ONCE to prevent a case where the handler + * changes between the check and the call. + */ + pre_rx_handler = ACCESS_ONCE(priv->pre_rx_handler); + if (pre_rx_handler) + pre_rx_handler(priv, rxb); + if (priv->ucode_owner != IWL_OWNERSHIP_TM) { /* Based on type of command response or notification, * handle those that need handling via function in * rx_handlers table. See iwl_setup_rx_handlers() */ diff --git a/drivers/net/wireless/iwlwifi/iwl-testmode.c b/drivers/net/wireless/iwlwifi/iwl-testmode.c index 1d732092ebe7..b8044bcd5044 100644 --- a/drivers/net/wireless/iwlwifi/iwl-testmode.c +++ b/drivers/net/wireless/iwlwifi/iwl-testmode.c @@ -125,6 +125,8 @@ struct nla_policy iwl_testmode_gnl_msg_policy[IWL_TM_ATTR_MAX] = { [IWL_TM_ATTR_FW_TYPE] = { .type = NLA_U32, }, [IWL_TM_ATTR_FW_INST_SIZE] = { .type = NLA_U32, }, [IWL_TM_ATTR_FW_DATA_SIZE] = { .type = NLA_U32, }, + + [IWL_TM_ATTR_ENABLE_NOTIFICATION] = {.type = NLA_FLAG, }, }; /* @@ -194,7 +196,7 @@ nla_put_failure: void iwl_testmode_init(struct iwl_priv *priv) { - priv->pre_rx_handler = iwl_testmode_ucode_rx_pkt; + priv->pre_rx_handler = NULL; priv->testmode_trace.trace_enabled = false; priv->testmode_mem.read_in_progress = false; } @@ -770,9 +772,13 @@ static int iwl_testmode_ownership(struct ieee80211_hw *hw, struct nlattr **tb) } owner = nla_get_u8(tb[IWL_TM_ATTR_UCODE_OWNER]); - if ((owner == IWL_OWNERSHIP_DRIVER) || (owner == IWL_OWNERSHIP_TM)) + if (owner == IWL_OWNERSHIP_DRIVER) { priv->ucode_owner = owner; - else { + priv->pre_rx_handler = NULL; + } else if (owner == IWL_OWNERSHIP_TM) { + priv->pre_rx_handler = iwl_testmode_ucode_rx_pkt; + priv->ucode_owner = owner; + } else { IWL_ERR(priv, "Invalid owner\n"); return -EINVAL; } @@ -937,6 +943,20 @@ static int iwl_testmode_buffer_dump(struct ieee80211_hw *hw, return -ENOBUFS; } +static int iwl_testmode_notifications(struct ieee80211_hw *hw, + struct nlattr **tb) +{ + struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); + bool enable; + + enable = nla_get_flag(tb[IWL_TM_ATTR_ENABLE_NOTIFICATION]); + if (enable) + priv->pre_rx_handler = iwl_testmode_ucode_rx_pkt; + else + priv->pre_rx_handler = NULL; + return 0; +} + /* The testmode gnl message handler that takes the gnl message from the * user space and parses it per the policy iwl_testmode_gnl_msg_policy, then @@ -1022,6 +1042,12 @@ int iwlagn_mac_testmode_cmd(struct ieee80211_hw *hw, void *data, int len) result = iwl_testmode_indirect_mem(hw, tb); break; + case IWL_TM_CMD_APP2DEV_NOTIFICATIONS: + IWL_DEBUG_INFO(priv, "testmode notifications cmd " + "to driver\n"); + result = iwl_testmode_notifications(hw, tb); + break; + default: IWL_ERR(priv, "Unknown testmode command\n"); result = -ENOSYS; diff --git a/drivers/net/wireless/iwlwifi/iwl-testmode.h b/drivers/net/wireless/iwlwifi/iwl-testmode.h index 69b2e80f4071..6ba211b09426 100644 --- a/drivers/net/wireless/iwlwifi/iwl-testmode.h +++ b/drivers/net/wireless/iwlwifi/iwl-testmode.h @@ -122,6 +122,9 @@ * Fore reading, a READ command is sent from the userspace and the data * is returned when the user calls a DUMP command. * For writing, only a WRITE command is used. + * @IWL_TM_CMD_APP2DEV_NOTIFICATIONS: + * Command to enable/disable notifications (currently RX packets) from the + * driver to userspace. */ enum iwl_tm_cmd_t { IWL_TM_CMD_APP2DEV_UCODE = 1, @@ -152,7 +155,8 @@ enum iwl_tm_cmd_t { IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_READ = 26, IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_DUMP = 27, IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_WRITE = 28, - IWL_TM_CMD_MAX = 29, + IWL_TM_CMD_APP2DEV_NOTIFICATIONS = 29, + IWL_TM_CMD_MAX = 30, }; /* @@ -256,6 +260,10 @@ enum iwl_tm_cmd_t { * When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_UCODE this flag * indicates that the user wants to receive the response of the command * in a reply SKB. If it's not present, the response is not returned. + * @IWL_TM_ATTR_ENABLE_NOTIFICATIONS: + * When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_NOTIFICATIONS, this + * flag enables (if present) or disables (if not) the forwarding + * to userspace. */ enum iwl_tm_attr_t { IWL_TM_ATTR_NOT_APPLICABLE = 0, @@ -282,7 +290,8 @@ enum iwl_tm_attr_t { IWL_TM_ATTR_FW_INST_SIZE = 21, IWL_TM_ATTR_FW_DATA_SIZE = 22, IWL_TM_ATTR_UCODE_CMD_SKB = 23, - IWL_TM_ATTR_MAX = 24, + IWL_TM_ATTR_ENABLE_NOTIFICATION = 24, + IWL_TM_ATTR_MAX = 25, }; /* uCode trace buffer */ -- cgit From 8e81f65fdc7f5d292bb3c115b748767d921823c1 Mon Sep 17 00:00:00 2001 From: Amit Beka Date: Wed, 7 Mar 2012 09:52:30 -0800 Subject: iwlwifi: fixed testmode notifications length The length of iwl_rx_packet doesn't include the dword for the length itself, so add it manually. Signed-off-by: Amit Beka Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-testmode.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-testmode.c b/drivers/net/wireless/iwlwifi/iwl-testmode.c index b8044bcd5044..b06c6763cb7a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-testmode.c +++ b/drivers/net/wireless/iwlwifi/iwl-testmode.c @@ -185,7 +185,8 @@ static void iwl_testmode_ucode_rx_pkt(struct iwl_priv *priv, return; } NLA_PUT_U32(skb, IWL_TM_ATTR_COMMAND, IWL_TM_CMD_DEV2APP_UCODE_RX_PKT); - NLA_PUT(skb, IWL_TM_ATTR_UCODE_RX_PKT, length, data); + /* the length doesn't include len_n_flags field, so add it manually */ + NLA_PUT(skb, IWL_TM_ATTR_UCODE_RX_PKT, length + sizeof(__le32), data); cfg80211_testmode_event(skb, GFP_ATOMIC); return; -- cgit From 18c57d3c1e31a91a5925da001c19d521178d00bd Mon Sep 17 00:00:00 2001 From: David Spinadel Date: Wed, 7 Mar 2012 09:52:31 -0800 Subject: iwlwifi: add option to test MFP Add a Kconfig symbol to enable MFP for testing even if the firmware file doesn't advertise it. Signed-off-by: David Spinadel Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/Kconfig | 9 +++++++++ drivers/net/wireless/iwlwifi/iwl-mac80211.c | 3 +++ 2 files changed, 12 insertions(+) diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig index 5afd06ef0d8b..2fe62730dddd 100644 --- a/drivers/net/wireless/iwlwifi/Kconfig +++ b/drivers/net/wireless/iwlwifi/Kconfig @@ -127,3 +127,12 @@ config IWLWIFI_P2P support when it is loaded. Say Y only if you want to experiment with P2P. + +config IWLWIFI_EXPERIMENTAL_MFP + bool "support MFP (802.11w) even if uCode doesn't advertise" + depends on IWLWIFI + help + This option enables experimental MFP (802.11W) support + even if the microcode doesn't advertise it. + + Say Y only if you want to experiment with MFP. diff --git a/drivers/net/wireless/iwlwifi/iwl-mac80211.c b/drivers/net/wireless/iwlwifi/iwl-mac80211.c index 91a42c3261aa..dcf39f84f239 100644 --- a/drivers/net/wireless/iwlwifi/iwl-mac80211.c +++ b/drivers/net/wireless/iwlwifi/iwl-mac80211.c @@ -163,7 +163,10 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv, hw->flags |= IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS | IEEE80211_HW_SUPPORTS_STATIC_SMPS; +#ifndef CONFIG_IWLWIFI_EXPERIMENTAL_MFP + /* enable 11w if the uCode advertise */ if (capa->flags & IWL_UCODE_TLV_FLAGS_MFP) +#endif /* !CONFIG_IWLWIFI_EXPERIMENTAL_MFP */ hw->flags |= IEEE80211_HW_MFP_CAPABLE; hw->sta_data_size = sizeof(struct iwl_station_priv); -- cgit From 9a716863ae4a2f039bc4d0b2b2bb4b24a1dc7a91 Mon Sep 17 00:00:00 2001 From: Don Fry Date: Wed, 7 Mar 2012 09:52:32 -0800 Subject: iwlwifi: separate status to priv and trans The shared status bits are a mixture of transport and op mode bits. Some are used just by one or the other, some are shared. Begin the de-tangling of these bits. Signed-off-by: Don Fry Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 2 +- drivers/net/wireless/iwlwifi/iwl-agn-tt.c | 16 +++++++--------- drivers/net/wireless/iwlwifi/iwl-agn.h | 9 ++------- drivers/net/wireless/iwlwifi/iwl-debugfs.c | 6 +----- drivers/net/wireless/iwlwifi/iwl-dev.h | 1 + drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h | 2 ++ drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | 2 -- 7 files changed, 14 insertions(+), 24 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index 6d8a8578778c..3fed4bbb7e82 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -1291,7 +1291,7 @@ int iwlagn_suspend(struct iwl_priv *priv, struct cfg80211_wowlan *wowlan) int iwl_dvm_send_cmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) { - if (iwl_is_rfkill(priv->shrd) || iwl_is_ctkill(priv->shrd)) { + if (iwl_is_rfkill(priv->shrd) || iwl_is_ctkill(priv)) { IWL_WARN(priv, "Not sending command - %s KILL\n", iwl_is_rfkill(priv->shrd) ? "RF" : "CT"); return -EIO; diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tt.c b/drivers/net/wireless/iwlwifi/iwl-agn-tt.c index 9a12b70c7d4f..fa9415309cd6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tt.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tt.c @@ -233,7 +233,7 @@ static void iwl_tt_ready_for_ct_kill(unsigned long data) IWL_DEBUG_TEMP(priv, "entering CT_KILL state when " "temperature timer expired\n"); tt->state = IWL_TI_CT_KILL; - set_bit(STATUS_CT_KILL, &priv->shrd->status); + set_bit(STATUS_CT_KILL, &priv->status); iwl_perform_ct_kill_task(priv, true); } } @@ -313,22 +313,21 @@ static void iwl_legacy_tt_handler(struct iwl_priv *priv, s32 temp, bool force) } mutex_lock(&priv->mutex); if (old_state == IWL_TI_CT_KILL) - clear_bit(STATUS_CT_KILL, &priv->shrd->status); + clear_bit(STATUS_CT_KILL, &priv->status); if (tt->state != IWL_TI_CT_KILL && iwl_power_update_mode(priv, true)) { /* TT state not updated * try again during next temperature read */ if (old_state == IWL_TI_CT_KILL) - set_bit(STATUS_CT_KILL, &priv->shrd->status); + set_bit(STATUS_CT_KILL, &priv->status); tt->state = old_state; IWL_ERR(priv, "Cannot update power mode, " "TT state not updated\n"); } else { if (tt->state == IWL_TI_CT_KILL) { if (force) { - set_bit(STATUS_CT_KILL, - &priv->shrd->status); + set_bit(STATUS_CT_KILL, &priv->status); iwl_perform_ct_kill_task(priv, true); } else { iwl_prepare_ct_kill_task(priv); @@ -454,7 +453,7 @@ static void iwl_advance_tt_handler(struct iwl_priv *priv, s32 temp, bool force) } mutex_lock(&priv->mutex); if (old_state == IWL_TI_CT_KILL) - clear_bit(STATUS_CT_KILL, &priv->shrd->status); + clear_bit(STATUS_CT_KILL, &priv->status); if (tt->state != IWL_TI_CT_KILL && iwl_power_update_mode(priv, true)) { /* TT state not updated @@ -463,7 +462,7 @@ static void iwl_advance_tt_handler(struct iwl_priv *priv, s32 temp, bool force) IWL_ERR(priv, "Cannot update power mode, " "TT state not updated\n"); if (old_state == IWL_TI_CT_KILL) - set_bit(STATUS_CT_KILL, &priv->shrd->status); + set_bit(STATUS_CT_KILL, &priv->status); tt->state = old_state; } else { IWL_DEBUG_TEMP(priv, @@ -474,8 +473,7 @@ static void iwl_advance_tt_handler(struct iwl_priv *priv, s32 temp, bool force) if (force) { IWL_DEBUG_TEMP(priv, "Enter IWL_TI_CT_KILL\n"); - set_bit(STATUS_CT_KILL, - &priv->shrd->status); + set_bit(STATUS_CT_KILL, &priv->status); iwl_perform_ct_kill_task(priv, true); } else { iwl_prepare_ct_kill_task(priv); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index 6345ab0f2a96..ede1852b1d7e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h @@ -367,11 +367,6 @@ static inline int iwl_is_alive(struct iwl_shared *shrd) return test_bit(STATUS_ALIVE, &shrd->status); } -static inline int iwl_is_init(struct iwl_shared *shrd) -{ - return test_bit(STATUS_INIT, &shrd->status); -} - static inline int iwl_is_rfkill_hw(struct iwl_shared *shrd) { return test_bit(STATUS_RF_KILL_HW, &shrd->status); @@ -382,9 +377,9 @@ static inline int iwl_is_rfkill(struct iwl_shared *shrd) return iwl_is_rfkill_hw(shrd); } -static inline int iwl_is_ctkill(struct iwl_shared *shrd) +static inline int iwl_is_ctkill(struct iwl_priv *priv) { - return test_bit(STATUS_CT_KILL, &shrd->status); + return test_bit(STATUS_CT_KILL, &priv->status); } static inline int iwl_is_ready_rf(struct iwl_shared *shrd) diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index 0a898c54c733..1c235d685ae6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c @@ -530,15 +530,11 @@ static ssize_t iwl_dbgfs_status_read(struct file *file, pos += scnprintf(buf + pos, bufsz - pos, "STATUS_RF_KILL_HW:\t %d\n", test_bit(STATUS_RF_KILL_HW, &priv->shrd->status)); pos += scnprintf(buf + pos, bufsz - pos, "STATUS_CT_KILL:\t\t %d\n", - test_bit(STATUS_CT_KILL, &priv->shrd->status)); - pos += scnprintf(buf + pos, bufsz - pos, "STATUS_INIT:\t\t %d\n", - test_bit(STATUS_INIT, &priv->shrd->status)); + test_bit(STATUS_CT_KILL, &priv->status)); pos += scnprintf(buf + pos, bufsz - pos, "STATUS_ALIVE:\t\t %d\n", test_bit(STATUS_ALIVE, &priv->shrd->status)); pos += scnprintf(buf + pos, bufsz - pos, "STATUS_READY:\t\t %d\n", test_bit(STATUS_READY, &priv->shrd->status)); - pos += scnprintf(buf + pos, bufsz - pos, "STATUS_TEMPERATURE:\t %d\n", - test_bit(STATUS_TEMPERATURE, &priv->shrd->status)); pos += scnprintf(buf + pos, bufsz - pos, "STATUS_GEO_CONFIGURED:\t %d\n", test_bit(STATUS_GEO_CONFIGURED, &priv->shrd->status)); pos += scnprintf(buf + pos, bufsz - pos, "STATUS_EXIT_PENDING:\t %d\n", diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index c3f372e2c142..1b05faea7965 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -713,6 +713,7 @@ struct iwl_priv { /*data shared among all the driver's layers */ struct iwl_shared *shrd; const struct iwl_fw *fw; + unsigned long status; spinlock_t sta_lock; struct mutex mutex; diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h index 93d89a375a1c..16a32ae4046e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h @@ -247,6 +247,7 @@ struct iwl_tx_queue { * @hw_base: pci hardware address support * @ucode_write_complete: indicates that the ucode has been copied. * @ucode_write_waitq: wait queue for uCode load + * @status - transport specific status flags */ struct iwl_trans_pcie { struct iwl_rx_queue rxq; @@ -287,6 +288,7 @@ struct iwl_trans_pcie { bool ucode_write_complete; wait_queue_head_t ucode_write_waitq; + unsigned long status; }; #define IWL_TRANS_GET_PCIE_TRANS(_iwl_trans) \ diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c index 88e1c427f8f5..e78098e79ee1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c @@ -833,8 +833,6 @@ static int iwl_nic_init(struct iwl_trans *trans) 0x800FFFFF); } - set_bit(STATUS_INIT, &trans->shrd->status); - return 0; } -- cgit From 354928dd00d0437149991fad7637c411ba1c62f0 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Wed, 7 Mar 2012 09:52:33 -0800 Subject: iwlwifi: make tx_cmd_pool kmem cache global Otherwise we are not able to run more than one device per driver: [ 24.743045] kmem_cache_create: duplicate cache iwl_dev_cmd [ 24.743051] Pid: 3165, comm: NetworkManager Not tainted 3.3.0-rc2-wl+ #5 [ 24.743054] Call Trace: [ 24.743066] [] kmem_cache_create+0x655/0x700 [ 24.743101] [] iwl_alive_notify+0x1cb/0x1f0 [iwlwifi] [ 24.743111] [] iwl_load_ucode_wait_alive+0x1b2/0x220 [iwlwifi] [ 24.743142] [] iwl_run_init_ucode+0x73/0x100 [iwlwifi] [ 24.743152] [] __iwl_up+0x81/0x220 [iwlwifi] [ 24.743161] [] iwlagn_mac_start+0x80/0x190 [iwlwifi] [ 24.743188] [] ieee80211_do_open+0x293/0x770 [mac80211] Signed-off-by: Stanislaw Gruszka Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-tx.c | 8 ++++---- drivers/net/wireless/iwlwifi/iwl-agn.c | 21 +++++++++++++++------ drivers/net/wireless/iwlwifi/iwl-core.c | 3 +-- drivers/net/wireless/iwlwifi/iwl-dev.h | 2 +- drivers/net/wireless/iwlwifi/iwl-ucode.c | 9 --------- 5 files changed, 21 insertions(+), 22 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c index a19db4c0c9fa..97ebfd26212e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c @@ -367,7 +367,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) if (info->flags & IEEE80211_TX_CTL_AMPDU) is_agg = true; - dev_cmd = kmem_cache_alloc(priv->tx_cmd_pool, GFP_ATOMIC); + dev_cmd = kmem_cache_alloc(iwl_tx_cmd_pool, GFP_ATOMIC); if (unlikely(!dev_cmd)) goto drop_unlock_priv; @@ -458,7 +458,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) drop_unlock_sta: if (dev_cmd) - kmem_cache_free(priv->tx_cmd_pool, dev_cmd); + kmem_cache_free(iwl_tx_cmd_pool, dev_cmd); spin_unlock(&priv->sta_lock); drop_unlock_priv: return -1; @@ -1078,7 +1078,7 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb, info = IEEE80211_SKB_CB(skb); ctx = info->driver_data[0]; - kmem_cache_free(priv->tx_cmd_pool, + kmem_cache_free(iwl_tx_cmd_pool, (info->driver_data[1])); memset(&info->status, 0, sizeof(info->status)); @@ -1229,7 +1229,7 @@ int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv, WARN_ON_ONCE(1); info = IEEE80211_SKB_CB(skb); - kmem_cache_free(priv->tx_cmd_pool, (info->driver_data[1])); + kmem_cache_free(iwl_tx_cmd_pool, (info->driver_data[1])); if (freed == 1) { /* this is the first skb we deliver in this batch */ diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 64bc2859dd1b..7927e3e11097 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -1102,8 +1102,6 @@ static void iwl_uninit_drv(struct iwl_priv *priv) { iwl_free_geos(priv); iwl_free_channel_map(priv); - if (priv->tx_cmd_pool) - kmem_cache_destroy(priv->tx_cmd_pool); kfree(priv->scan_cmd); kfree(priv->beacon_cmd); kfree(rcu_dereference_raw(priv->noa_data)); @@ -1477,6 +1475,9 @@ const struct iwl_op_mode_ops iwl_dvm_ops = { * driver and module entry point * *****************************************************************************/ + +struct kmem_cache *iwl_tx_cmd_pool; + static int __init iwl_init(void) { @@ -1484,20 +1485,27 @@ static int __init iwl_init(void) pr_info(DRV_DESCRIPTION ", " DRV_VERSION "\n"); pr_info(DRV_COPYRIGHT "\n"); + iwl_tx_cmd_pool = kmem_cache_create("iwl_dev_cmd", + sizeof(struct iwl_device_cmd), + sizeof(void *), 0, NULL); + if (!iwl_tx_cmd_pool) + return -ENOMEM; + ret = iwlagn_rate_control_register(); if (ret) { pr_err("Unable to register rate control algorithm: %d\n", ret); - return ret; + goto error_rc_register; } ret = iwl_pci_register_driver(); - if (ret) - goto error_register; + goto error_pci_register; return ret; -error_register: +error_pci_register: iwlagn_rate_control_unregister(); +error_rc_register: + kmem_cache_destroy(iwl_tx_cmd_pool); return ret; } @@ -1505,6 +1513,7 @@ static void __exit iwl_exit(void) { iwl_pci_unregister_driver(); iwlagn_rate_control_unregister(); + kmem_cache_destroy(iwl_tx_cmd_pool); } module_exit(iwl_exit); diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index f50bd4263b88..df7b165b290c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -1470,10 +1470,9 @@ void iwl_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state) void iwl_free_skb(struct iwl_op_mode *op_mode, struct sk_buff *skb) { - struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); struct ieee80211_tx_info *info; info = IEEE80211_SKB_CB(skb); - kmem_cache_free(priv->tx_cmd_pool, (info->driver_data[1])); + kmem_cache_free(iwl_tx_cmd_pool, (info->driver_data[1])); dev_kfree_skb_any(skb); } diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 1b05faea7965..aa4b3b122da4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -725,7 +725,6 @@ struct iwl_priv { struct ieee80211_hw *hw; struct ieee80211_channel *ieee_channels; struct ieee80211_rate *ieee_rates; - struct kmem_cache *tx_cmd_pool; struct list_head calib_results; @@ -983,6 +982,7 @@ struct iwl_priv { bool have_rekey_data; }; /*iwl_priv */ +extern struct kmem_cache *iwl_tx_cmd_pool; extern struct iwl_mod_params iwlagn_mod_params; static inline struct iwl_rxon_context * diff --git a/drivers/net/wireless/iwlwifi/iwl-ucode.c b/drivers/net/wireless/iwlwifi/iwl-ucode.c index 404fd8e7958b..d97cf44b75ba 100644 --- a/drivers/net/wireless/iwlwifi/iwl-ucode.c +++ b/drivers/net/wireless/iwlwifi/iwl-ucode.c @@ -318,15 +318,6 @@ static int iwl_alive_notify(struct iwl_priv *priv) { int ret; - if (!priv->tx_cmd_pool) - priv->tx_cmd_pool = - kmem_cache_create("iwl_dev_cmd", - sizeof(struct iwl_device_cmd), - sizeof(void *), 0, NULL); - - if (!priv->tx_cmd_pool) - return -ENOMEM; - iwl_trans_fw_alive(trans(priv)); priv->passive_no_rx = false; -- cgit From 3251715dc51a8cbd2cd030ff94fe36f37b4b9e74 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Wed, 7 Mar 2012 09:52:34 -0800 Subject: iwlwifi: log stop / wake queues There were a few missing occurences when we get PASSIVE_NO_RX notification. Signed-off-by: Emmanuel Grumbach Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-tx.c | 2 ++ drivers/net/wireless/iwlwifi/iwl-agn.c | 6 +++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c index 97ebfd26212e..ac5c1311ef33 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c @@ -1088,6 +1088,8 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb, ctx->vif->type == NL80211_IFTYPE_STATION) { /* block and stop all queues */ priv->passive_no_rx = true; + IWL_DEBUG_TX_QUEUES(priv, "stop all queues: " + "passive channel"); ieee80211_stop_queues(priv->hw); IWL_DEBUG_TX_REPLY(priv, diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 7927e3e11097..6ed2f782177b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -1450,8 +1450,12 @@ void iwlagn_lift_passive_no_rx(struct iwl_priv *priv) return; for (ac = IEEE80211_AC_VO; ac < IEEE80211_NUM_ACS; ac++) { - if (!test_bit(ac, &priv->transport_queue_stop)) + if (!test_bit(ac, &priv->transport_queue_stop)) { + IWL_DEBUG_TX_QUEUES(priv, "Wake queue %d"); ieee80211_wake_queue(priv->hw, ac); + } else { + IWL_DEBUG_TX_QUEUES(priv, "Don't wake queue %d"); + } } priv->passive_no_rx = false; -- cgit From 92d743ae105314a865b3fca9128da11525d22203 Mon Sep 17 00:00:00 2001 From: Meenakshi Venkataraman Date: Wed, 7 Mar 2012 09:52:35 -0800 Subject: iwlwifi: configure transport layer from dvm op mode Introduce the iwl_trans_config struct which contains state variables that only the op mode can determine, but which the transport layer needs to know. Signed-off-by: Meenakshi Venkataraman Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn.c | 10 +++++++++- drivers/net/wireless/iwlwifi/iwl-trans.h | 14 ++++++++++++-- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 6ed2f782177b..83018ec11bc7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -1185,6 +1185,7 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans, struct iwl_op_mode *op_mode; u16 num_mac; u32 ucode_flags; + struct iwl_trans_config trans_cfg; /************************ * 1. Allocating HW data @@ -1205,7 +1206,14 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans, /* TODO: remove fw from shared data later */ priv->shrd->fw = fw; - iwl_trans_configure(trans(priv), op_mode); + /* + * Populate the state variables that the transport layer needs + * to know about. + */ + trans_cfg.op_mode = op_mode; + + /* Configure transport layer */ + iwl_trans_configure(trans(priv), &trans_cfg); /* At this point both hw and priv are allocated. */ diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index ed6ab449e439..b6fd42779624 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h @@ -274,6 +274,16 @@ static inline struct page *rxb_steal_page(struct iwl_rx_cmd_buffer *r) return p; } +/** + * struct iwl_trans_config - transport configuration + * + * @op_mode: pointer to the upper layer. + * Must be set before any other call. + */ +struct iwl_trans_config { + struct iwl_op_mode *op_mode; +}; + /** * struct iwl_trans_ops - transport specific operations * @@ -408,13 +418,13 @@ struct iwl_trans { }; static inline void iwl_trans_configure(struct iwl_trans *trans, - struct iwl_op_mode *op_mode) + const struct iwl_trans_config *trans_cfg) { /* * only set the op_mode for the moment. Later on, this function will do * more */ - trans->op_mode = op_mode; + trans->op_mode = trans_cfg->op_mode; } static inline int iwl_trans_start_hw(struct iwl_trans *trans) -- cgit From 9bdfbfadc4f0b3a756b54e7ec7cfaf92c22ce258 Mon Sep 17 00:00:00 2001 From: Meenakshi Venkataraman Date: Wed, 7 Mar 2012 09:52:36 -0800 Subject: iwlwifi: move setting up fw parameters Gather parameters required to configure the transport layer before invoking the transport configuration API. Change-Id: I5b39da284af6d9b5432a08911b4e1173a4d7207d Signed-off-by: Meenakshi Venkataraman Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn.c | 45 ++++++++++++++++++---------------- 1 file changed, 24 insertions(+), 21 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 83018ec11bc7..397342402d1e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -1206,6 +1206,30 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans, /* TODO: remove fw from shared data later */ priv->shrd->fw = fw; + /************************ + * 2. Setup HW constants + ************************/ + iwl_set_hw_params(priv); + + ucode_flags = fw->ucode_capa.flags; + +#ifndef CONFIG_IWLWIFI_P2P + ucode_flags &= ~IWL_UCODE_TLV_FLAGS_PAN; +#endif + if (!(hw_params(priv).sku & EEPROM_SKU_CAP_IPAN_ENABLE)) + ucode_flags &= ~IWL_UCODE_TLV_FLAGS_PAN; + + /* + * if not PAN, then don't support P2P -- might be a uCode + * packaging bug or due to the eeprom check above + */ + if (!(ucode_flags & IWL_UCODE_TLV_FLAGS_PAN)) + ucode_flags &= ~IWL_UCODE_TLV_FLAGS_P2P; + + + /***************************** + * Configure transport layer + *****************************/ /* * Populate the state variables that the transport layer needs * to know about. @@ -1286,27 +1310,6 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans, priv->hw->wiphy->n_addresses++; } - /************************ - * 5. Setup HW constants - ************************/ - iwl_set_hw_params(priv); - - ucode_flags = fw->ucode_capa.flags; - -#ifndef CONFIG_IWLWIFI_P2P - ucode_flags &= ~IWL_UCODE_TLV_FLAGS_PAN; -#endif - if (!(hw_params(priv).sku & EEPROM_SKU_CAP_IPAN_ENABLE)) - ucode_flags &= ~IWL_UCODE_TLV_FLAGS_PAN; - - /* - * if not PAN, then don't support P2P -- might be a uCode - * packaging bug or due to the eeprom check above - */ - if (!(ucode_flags & IWL_UCODE_TLV_FLAGS_PAN)) - ucode_flags &= ~IWL_UCODE_TLV_FLAGS_P2P; - - /******************* * 6. Setup priv *******************/ -- cgit From 83626404a70da74c67f32f119e53c0ba032ba2d8 Mon Sep 17 00:00:00 2001 From: Don Fry Date: Wed, 7 Mar 2012 09:52:37 -0800 Subject: iwlwifi: more status bit factoring Continue splitting the status bits between transport and op_mode. All but a few are separated. Signed-off-by: Don Fry Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 8 ++-- drivers/net/wireless/iwlwifi/iwl-agn-rx.c | 18 ++++---- drivers/net/wireless/iwlwifi/iwl-agn-rxon.c | 14 +++---- drivers/net/wireless/iwlwifi/iwl-agn-sta.c | 6 +-- drivers/net/wireless/iwlwifi/iwl-agn-tt.c | 20 ++++----- drivers/net/wireless/iwlwifi/iwl-agn-tx.c | 4 +- drivers/net/wireless/iwlwifi/iwl-agn.c | 40 +++++++++--------- drivers/net/wireless/iwlwifi/iwl-agn.h | 31 ++++++-------- drivers/net/wireless/iwlwifi/iwl-core.c | 31 +++++++------- drivers/net/wireless/iwlwifi/iwl-debugfs.c | 38 ++++++++--------- drivers/net/wireless/iwlwifi/iwl-led.c | 2 +- drivers/net/wireless/iwlwifi/iwl-mac80211.c | 34 +++++++-------- drivers/net/wireless/iwlwifi/iwl-power.c | 4 +- drivers/net/wireless/iwlwifi/iwl-scan.c | 50 +++++++++++------------ drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h | 8 ++-- drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c | 10 ++--- drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | 8 ++-- 17 files changed, 160 insertions(+), 166 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index 3fed4bbb7e82..915183a3a873 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -51,7 +51,7 @@ int iwlagn_send_tx_power(struct iwl_priv *priv) struct iwlagn_tx_power_dbm_cmd tx_power_cmd; u8 tx_ant_cfg_cmd; - if (WARN_ONCE(test_bit(STATUS_SCAN_HW, &priv->shrd->status), + if (WARN_ONCE(test_bit(STATUS_SCAN_HW, &priv->status), "TX Power requested while scanning!\n")) return -EAGAIN; @@ -575,7 +575,7 @@ static void iwlagn_bt_traffic_change_work(struct work_struct *work) * STATUS_SCANNING to avoid race when queue_work two times from * different notifications, but quit and not perform any work at all. */ - if (test_bit(STATUS_SCAN_HW, &priv->shrd->status)) + if (test_bit(STATUS_SCAN_HW, &priv->status)) goto out; iwl_update_chain_flags(priv); @@ -1291,9 +1291,9 @@ int iwlagn_suspend(struct iwl_priv *priv, struct cfg80211_wowlan *wowlan) int iwl_dvm_send_cmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) { - if (iwl_is_rfkill(priv->shrd) || iwl_is_ctkill(priv)) { + if (iwl_is_rfkill(priv) || iwl_is_ctkill(priv)) { IWL_WARN(priv, "Not sending command - %s KILL\n", - iwl_is_rfkill(priv->shrd) ? "RF" : "CT"); + iwl_is_rfkill(priv) ? "RF" : "CT"); return -EIO; } diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c index 8e7cdfaf10cc..3ad43330f6a1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c @@ -159,7 +159,7 @@ static int iwlagn_rx_csa(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb, struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; struct iwl_rxon_cmd *rxon = (void *)&ctx->active; - if (!test_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->shrd->status)) + if (!test_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status)) return 0; if (!le32_to_cpu(csa->status) && csa->channel == priv->switch_channel) { @@ -355,7 +355,7 @@ static void iwlagn_recover_from_statistics(struct iwl_priv *priv, { unsigned int msecs; - if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) return; msecs = jiffies_to_msecs(stamp - priv->rx_statistics_jiffies); @@ -575,7 +575,7 @@ static int iwlagn_rx_statistics(struct iwl_priv *priv, priv->rx_statistics_jiffies = stamp; - set_bit(STATUS_STATISTICS, &priv->shrd->status); + set_bit(STATUS_STATISTICS, &priv->status); /* Reschedule the statistics timer to occur in * reg_recalib_period seconds to ensure we get a @@ -584,7 +584,7 @@ static int iwlagn_rx_statistics(struct iwl_priv *priv, mod_timer(&priv->statistics_periodic, jiffies + msecs_to_jiffies(reg_recalib_period * 1000)); - if (unlikely(!test_bit(STATUS_SCANNING, &priv->shrd->status)) && + if (unlikely(!test_bit(STATUS_SCANNING, &priv->status)) && (pkt->hdr.cmd == STATISTICS_NOTIFICATION)) { iwlagn_rx_calc_noise(priv); queue_work(priv->workqueue, &priv->run_time_calib_work); @@ -658,18 +658,18 @@ static int iwlagn_rx_card_state_notif(struct iwl_priv *priv, iwl_tt_exit_ct_kill(priv); if (flags & HW_CARD_DISABLED) - set_bit(STATUS_RF_KILL_HW, &priv->shrd->status); + set_bit(STATUS_RF_KILL_HW, &priv->status); else - clear_bit(STATUS_RF_KILL_HW, &priv->shrd->status); + clear_bit(STATUS_RF_KILL_HW, &priv->status); if (!(flags & RXON_CARD_DISABLED)) iwl_scan_cancel(priv); if ((test_bit(STATUS_RF_KILL_HW, &status) != - test_bit(STATUS_RF_KILL_HW, &priv->shrd->status))) + test_bit(STATUS_RF_KILL_HW, &priv->status))) wiphy_rfkill_set_hw_state(priv->hw->wiphy, - test_bit(STATUS_RF_KILL_HW, &priv->shrd->status)); + test_bit(STATUS_RF_KILL_HW, &priv->status)); else wake_up(&priv->shrd->wait_command_queue); return 0; @@ -691,7 +691,7 @@ static int iwlagn_rx_missed_beacon_notif(struct iwl_priv *priv, le32_to_cpu(missed_beacon->total_missed_becons), le32_to_cpu(missed_beacon->num_recvd_beacons), le32_to_cpu(missed_beacon->num_expected_beacons)); - if (!test_bit(STATUS_SCANNING, &priv->shrd->status)) + if (!test_bit(STATUS_SCANNING, &priv->status)) iwl_init_sensitivity(priv); } return 0; diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c index 66e9a71aaac6..36909077f994 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c @@ -361,7 +361,7 @@ int iwlagn_set_pan_params(struct iwl_priv *priv) slot0 = bcnint / 2; slot1 = bcnint - slot0; - if (test_bit(STATUS_SCAN_HW, &priv->shrd->status) || + if (test_bit(STATUS_SCAN_HW, &priv->status) || (!ctx_bss->vif->bss_conf.idle && !ctx_bss->vif->bss_conf.assoc)) { slot0 = dtim * bcnint * 3 - IWL_MIN_SLOT_TIME; @@ -377,7 +377,7 @@ int iwlagn_set_pan_params(struct iwl_priv *priv) ctx_pan->beacon_int; slot1 = max_t(int, DEFAULT_BEACON_INTERVAL, slot1); - if (test_bit(STATUS_SCAN_HW, &priv->shrd->status)) { + if (test_bit(STATUS_SCAN_HW, &priv->status)) { slot0 = slot1 * 3 - IWL_MIN_SLOT_TIME; slot1 = IWL_MIN_SLOT_TIME; } @@ -421,7 +421,7 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) lockdep_assert_held(&priv->mutex); - if (!iwl_is_alive(priv->shrd)) + if (!iwl_is_alive(priv)) return -EBUSY; /* This function hardcodes a bunch of dual-mode assumptions */ @@ -457,7 +457,7 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) * receive commit_rxon request * abort any previous channel switch if still in process */ - if (test_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->shrd->status) && + if (test_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status) && (priv->switch_channel != ctx->staging.channel)) { IWL_DEBUG_11H(priv, "abort channel switch on %d\n", le16_to_cpu(priv->switch_channel)); @@ -551,12 +551,12 @@ int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed) mutex_lock(&priv->mutex); - if (unlikely(test_bit(STATUS_SCANNING, &priv->shrd->status))) { + if (unlikely(test_bit(STATUS_SCANNING, &priv->status))) { IWL_DEBUG_MAC80211(priv, "leave - scanning\n"); goto out; } - if (!iwl_is_ready(priv->shrd)) { + if (!iwl_is_ready(priv)) { IWL_DEBUG_MAC80211(priv, "leave - not ready\n"); goto out; } @@ -794,7 +794,7 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw, mutex_lock(&priv->mutex); - if (unlikely(!iwl_is_ready(priv->shrd))) { + if (unlikely(!iwl_is_ready(priv))) { IWL_DEBUG_MAC80211(priv, "leave - not ready\n"); mutex_unlock(&priv->mutex); return; diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c index cf5cc1060cf4..23e9eab477bb 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c @@ -490,7 +490,7 @@ int iwl_remove_station(struct iwl_priv *priv, const u8 sta_id, { u8 tid; - if (!iwl_is_ready(priv->shrd)) { + if (!iwl_is_ready(priv)) { IWL_DEBUG_INFO(priv, "Unable to remove station %pM, device not ready.\n", addr); @@ -598,7 +598,7 @@ void iwl_restore_stations(struct iwl_priv *priv, struct iwl_rxon_context *ctx) int ret; bool send_lq; - if (!iwl_is_ready(priv->shrd)) { + if (!iwl_is_ready(priv)) { IWL_DEBUG_INFO(priv, "Not ready yet, not restoring any stations.\n"); return; @@ -997,7 +997,7 @@ int iwl_remove_default_wep_key(struct iwl_priv *priv, keyconf->keyidx); memset(&ctx->wep_keys[keyconf->keyidx], 0, sizeof(ctx->wep_keys[0])); - if (iwl_is_rfkill(priv->shrd)) { + if (iwl_is_rfkill(priv)) { IWL_DEBUG_WEP(priv, "Not sending REPLY_WEPKEY command due to RFKILL.\n"); /* but keys in device are clear anyway so return success */ diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tt.c b/drivers/net/wireless/iwlwifi/iwl-agn-tt.c index fa9415309cd6..baaf5ba2fc38 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tt.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tt.c @@ -174,7 +174,7 @@ static void iwl_tt_check_exit_ct_kill(unsigned long data) struct iwl_tt_mgmt *tt = &priv->thermal_throttle; unsigned long flags; - if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) return; if (tt->state == IWL_TI_CT_KILL) { @@ -225,7 +225,7 @@ static void iwl_tt_ready_for_ct_kill(unsigned long data) struct iwl_priv *priv = (struct iwl_priv *)data; struct iwl_tt_mgmt *tt = &priv->thermal_throttle; - if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) return; /* temperature timer expired, ready to go into CT_KILL state */ @@ -504,10 +504,10 @@ static void iwl_bg_ct_enter(struct work_struct *work) struct iwl_priv *priv = container_of(work, struct iwl_priv, ct_enter); struct iwl_tt_mgmt *tt = &priv->thermal_throttle; - if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) return; - if (!iwl_is_ready(priv->shrd)) + if (!iwl_is_ready(priv)) return; if (tt->state != IWL_TI_CT_KILL) { @@ -533,10 +533,10 @@ static void iwl_bg_ct_exit(struct work_struct *work) struct iwl_priv *priv = container_of(work, struct iwl_priv, ct_exit); struct iwl_tt_mgmt *tt = &priv->thermal_throttle; - if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) return; - if (!iwl_is_ready(priv->shrd)) + if (!iwl_is_ready(priv)) return; /* stop ct_kill_exit_tm timer */ @@ -563,7 +563,7 @@ static void iwl_bg_ct_exit(struct work_struct *work) void iwl_tt_enter_ct_kill(struct iwl_priv *priv) { - if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) return; IWL_DEBUG_TEMP(priv, "Queueing critical temperature enter.\n"); @@ -572,7 +572,7 @@ void iwl_tt_enter_ct_kill(struct iwl_priv *priv) void iwl_tt_exit_ct_kill(struct iwl_priv *priv) { - if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) return; IWL_DEBUG_TEMP(priv, "Queueing critical temperature exit.\n"); @@ -584,7 +584,7 @@ static void iwl_bg_tt_work(struct work_struct *work) struct iwl_priv *priv = container_of(work, struct iwl_priv, tt_work); s32 temp = priv->temperature; /* degrees CELSIUS except specified */ - if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) return; if (!priv->thermal_throttle.advanced_tt) @@ -595,7 +595,7 @@ static void iwl_bg_tt_work(struct work_struct *work) void iwl_tt_handler(struct iwl_priv *priv) { - if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) return; IWL_DEBUG_TEMP(priv, "Queueing thermal throttling work.\n"); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c index ac5c1311ef33..9f224548b636 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c @@ -297,7 +297,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) if (info->control.vif) ctx = iwl_rxon_ctx_from_vif(info->control.vif); - if (iwl_is_rfkill(priv->shrd)) { + if (iwl_is_rfkill(priv)) { IWL_DEBUG_DROP(priv, "Dropping - RF KILL\n"); goto drop_unlock_priv; } @@ -1000,7 +1000,7 @@ static void iwl_check_abort_status(struct iwl_priv *priv, { if (frame_count == 1 && status == TX_STATUS_FAIL_RFKILL_FLUSH) { IWL_ERR(priv, "Tx flush command to flush out all frames\n"); - if (!test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) + if (!test_bit(STATUS_EXIT_PENDING, &priv->status)) queue_work(priv->workqueue, &priv->tx_flush); } } diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 397342402d1e..d45def33d0f6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -244,11 +244,11 @@ static void iwl_bg_bt_runtime_config(struct work_struct *work) struct iwl_priv *priv = container_of(work, struct iwl_priv, bt_runtime_config); - if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) return; /* dont send host command if rf-kill is on */ - if (!iwl_is_ready_rf(priv->shrd)) + if (!iwl_is_ready_rf(priv)) return; iwlagn_send_advance_bt_config(priv); } @@ -261,11 +261,11 @@ static void iwl_bg_bt_full_concurrency(struct work_struct *work) mutex_lock(&priv->mutex); - if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) goto out; /* dont send host command if rf-kill is on */ - if (!iwl_is_ready_rf(priv->shrd)) + if (!iwl_is_ready_rf(priv)) goto out; IWL_DEBUG_INFO(priv, "BT coex in %s mode\n", @@ -300,11 +300,11 @@ static void iwl_bg_statistics_periodic(unsigned long data) { struct iwl_priv *priv = (struct iwl_priv *)data; - if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) return; /* dont send host command if rf-kill is on */ - if (!iwl_is_ready_rf(priv->shrd)) + if (!iwl_is_ready_rf(priv)) return; iwl_send_statistics_request(priv, CMD_ASYNC, false); @@ -461,7 +461,7 @@ static void iwl_bg_ucode_trace(unsigned long data) { struct iwl_priv *priv = (struct iwl_priv *)data; - if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) return; if (priv->event_log.ucode_trace) { @@ -477,11 +477,11 @@ static void iwl_bg_tx_flush(struct work_struct *work) struct iwl_priv *priv = container_of(work, struct iwl_priv, tx_flush); - if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) return; /* do nothing if rf-kill is on */ - if (!iwl_is_ready_rf(priv->shrd)) + if (!iwl_is_ready_rf(priv)) return; IWL_DEBUG_INFO(priv, "device request: flush all tx frames\n"); @@ -640,12 +640,12 @@ int iwl_alive_start(struct iwl_priv *priv) IWL_DEBUG_INFO(priv, "Runtime Alive received.\n"); /* After the ALIVE response, we can send host commands to the uCode */ - set_bit(STATUS_ALIVE, &priv->shrd->status); + set_bit(STATUS_ALIVE, &priv->status); /* Enable watchdog to monitor the driver tx queues */ iwl_setup_watchdog(priv); - if (iwl_is_rfkill(priv->shrd)) + if (iwl_is_rfkill(priv)) return -ERFKILL; if (priv->event_log.ucode_trace) { @@ -719,7 +719,7 @@ int iwl_alive_start(struct iwl_priv *priv) iwl_reset_run_time_calib(priv); } - set_bit(STATUS_READY, &priv->shrd->status); + set_bit(STATUS_READY, &priv->status); /* Configure the adapter for unassociated operation */ ret = iwlagn_commit_rxon(priv, ctx); @@ -786,7 +786,7 @@ void iwl_down(struct iwl_priv *priv) ieee80211_remain_on_channel_expired(priv->hw); exit_pending = - test_and_set_bit(STATUS_EXIT_PENDING, &priv->shrd->status); + test_and_set_bit(STATUS_EXIT_PENDING, &priv->status); /* Stop TX queues watchdog. We need to have STATUS_EXIT_PENDING bit set * to prevent rearm timer */ @@ -811,7 +811,7 @@ void iwl_down(struct iwl_priv *priv) /* Wipe out the EXIT_PENDING status bit if we are not actually * exiting the module */ if (!exit_pending) - clear_bit(STATUS_EXIT_PENDING, &priv->shrd->status); + clear_bit(STATUS_EXIT_PENDING, &priv->status); if (priv->mac80211_registered) ieee80211_stop_queues(priv->hw); @@ -820,13 +820,13 @@ void iwl_down(struct iwl_priv *priv) /* Clear out all status bits but a few that are stable across reset */ priv->shrd->status &= - test_bit(STATUS_RF_KILL_HW, &priv->shrd->status) << + test_bit(STATUS_RF_KILL_HW, &priv->status) << STATUS_RF_KILL_HW | - test_bit(STATUS_GEO_CONFIGURED, &priv->shrd->status) << + test_bit(STATUS_GEO_CONFIGURED, &priv->status) << STATUS_GEO_CONFIGURED | test_bit(STATUS_FW_ERROR, &priv->shrd->status) << STATUS_FW_ERROR | - test_bit(STATUS_EXIT_PENDING, &priv->shrd->status) << + test_bit(STATUS_EXIT_PENDING, &priv->status) << STATUS_EXIT_PENDING; dev_kfree_skb(priv->beacon_skb); @@ -846,8 +846,8 @@ static void iwl_bg_run_time_calib_work(struct work_struct *work) mutex_lock(&priv->mutex); - if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status) || - test_bit(STATUS_SCANNING, &priv->shrd->status)) { + if (test_bit(STATUS_EXIT_PENDING, &priv->status) || + test_bit(STATUS_SCANNING, &priv->status)) { mutex_unlock(&priv->mutex); return; } @@ -903,7 +903,7 @@ static void iwl_bg_restart(struct work_struct *data) { struct iwl_priv *priv = container_of(data, struct iwl_priv, restart); - if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) return; if (test_and_clear_bit(STATUS_FW_ERROR, &priv->shrd->status)) { diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index ede1852b1d7e..eb96855ddf8d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h @@ -353,28 +353,23 @@ static inline void iwl_print_rx_config_cmd(struct iwl_priv *priv, /* status checks */ -static inline int iwl_is_ready(struct iwl_shared *shrd) +static inline int iwl_is_ready(struct iwl_priv *priv) { /* The adapter is 'ready' if READY and GEO_CONFIGURED bits are * set but EXIT_PENDING is not */ - return test_bit(STATUS_READY, &shrd->status) && - test_bit(STATUS_GEO_CONFIGURED, &shrd->status) && - !test_bit(STATUS_EXIT_PENDING, &shrd->status); + return test_bit(STATUS_READY, &priv->status) && + test_bit(STATUS_GEO_CONFIGURED, &priv->status) && + !test_bit(STATUS_EXIT_PENDING, &priv->status); } -static inline int iwl_is_alive(struct iwl_shared *shrd) +static inline int iwl_is_alive(struct iwl_priv *priv) { - return test_bit(STATUS_ALIVE, &shrd->status); + return test_bit(STATUS_ALIVE, &priv->status); } -static inline int iwl_is_rfkill_hw(struct iwl_shared *shrd) +static inline int iwl_is_rfkill(struct iwl_priv *priv) { - return test_bit(STATUS_RF_KILL_HW, &shrd->status); -} - -static inline int iwl_is_rfkill(struct iwl_shared *shrd) -{ - return iwl_is_rfkill_hw(shrd); + return test_bit(STATUS_RF_KILL_HW, &priv->status); } static inline int iwl_is_ctkill(struct iwl_priv *priv) @@ -382,18 +377,18 @@ static inline int iwl_is_ctkill(struct iwl_priv *priv) return test_bit(STATUS_CT_KILL, &priv->status); } -static inline int iwl_is_ready_rf(struct iwl_shared *shrd) +static inline int iwl_is_ready_rf(struct iwl_priv *priv) { - if (iwl_is_rfkill(shrd)) + if (iwl_is_rfkill(priv)) return 0; - return iwl_is_ready(shrd); + return iwl_is_ready(priv); } #ifdef CONFIG_IWLWIFI_DEBUG #define IWL_DEBUG_QUIET_RFKILL(m, fmt, args...) \ do { \ - if (!iwl_is_rfkill((m)->shrd)) \ + if (!iwl_is_rfkill((m))) \ IWL_ERR(m, fmt, ##args); \ else \ __iwl_err(trans(m)->dev, true, \ @@ -403,7 +398,7 @@ do { \ #else #define IWL_DEBUG_QUIET_RFKILL(m, fmt, args...) \ do { \ - if (!iwl_is_rfkill((m)->shrd)) \ + if (!iwl_is_rfkill((m))) \ IWL_ERR(m, fmt, ##args); \ else \ __iwl_err(trans(m)->dev, true, true, fmt, ##args); \ diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index df7b165b290c..8b85940731f2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -113,7 +113,7 @@ int iwl_init_geos(struct iwl_priv *priv) if (priv->bands[IEEE80211_BAND_2GHZ].n_bitrates || priv->bands[IEEE80211_BAND_5GHZ].n_bitrates) { IWL_DEBUG_INFO(priv, "Geography modes already initialized.\n"); - set_bit(STATUS_GEO_CONFIGURED, &priv->shrd->status); + set_bit(STATUS_GEO_CONFIGURED, &priv->status); return 0; } @@ -212,7 +212,7 @@ int iwl_init_geos(struct iwl_priv *priv) priv->bands[IEEE80211_BAND_2GHZ].n_channels, priv->bands[IEEE80211_BAND_5GHZ].n_channels); - set_bit(STATUS_GEO_CONFIGURED, &priv->shrd->status); + set_bit(STATUS_GEO_CONFIGURED, &priv->status); return 0; } @@ -224,7 +224,7 @@ void iwl_free_geos(struct iwl_priv *priv) { kfree(priv->ieee_channels); kfree(priv->ieee_rates); - clear_bit(STATUS_GEO_CONFIGURED, &priv->shrd->status); + clear_bit(STATUS_GEO_CONFIGURED, &priv->status); } static bool iwl_is_channel_extension(struct iwl_priv *priv, @@ -798,11 +798,10 @@ void iwl_chswitch_done(struct iwl_priv *priv, bool is_success) */ struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; - if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) return; - if (test_and_clear_bit(STATUS_CHANNEL_SWITCH_PENDING, - &priv->shrd->status)) + if (test_and_clear_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status)) ieee80211_chswitch_done(ctx->vif, is_success); } @@ -849,7 +848,7 @@ static void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand) /* Keep the restart process from trying to send host * commands by clearing the ready bit */ - clear_bit(STATUS_READY, &priv->shrd->status); + clear_bit(STATUS_READY, &priv->status); wake_up(&priv->shrd->wait_command_queue); @@ -874,7 +873,7 @@ static void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand) priv->reload_count = 0; } - if (!test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) { + if (!test_bit(STATUS_EXIT_PENDING, &priv->status)) { if (iwlagn_mod_params.restart_fw) { IWL_DEBUG_FW_ERRORS(priv, "Restarting adapter due to uCode error.\n"); @@ -912,7 +911,7 @@ int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force) return -EINVAL; } - if (!iwl_is_ready_rf(priv->shrd)) + if (!iwl_is_ready_rf(priv)) return -EIO; /* scan complete and commit_rxon use tx_power_next value, @@ -920,7 +919,7 @@ int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force) priv->tx_power_next = tx_power; /* do not set tx power when scanning or channel changing */ - defer = test_bit(STATUS_SCANNING, &priv->shrd->status) || + defer = test_bit(STATUS_SCANNING, &priv->status) || memcmp(&ctx->active, &ctx->staging, sizeof(ctx->staging)); if (defer && !force) { IWL_DEBUG_INFO(priv, "Deferring tx power set\n"); @@ -1219,7 +1218,7 @@ void iwl_update_stats(struct iwl_priv *priv, bool is_tx, __le16 fc, u16 len) static void iwl_force_rf_reset(struct iwl_priv *priv) { - if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) return; if (!iwl_is_any_associated(priv)) { @@ -1244,7 +1243,7 @@ int iwl_force_reset(struct iwl_priv *priv, int mode, bool external) { struct iwl_force_reset *force_reset; - if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) return -EINVAL; if (mode >= IWL_MAX_FORCE_RESET) { @@ -1334,10 +1333,10 @@ void iwl_bg_watchdog(unsigned long data) int cnt; unsigned long timeout; - if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) return; - if (iwl_is_rfkill(priv->shrd)) + if (iwl_is_rfkill(priv)) return; timeout = hw_params(priv).wd_timeout; @@ -1461,9 +1460,9 @@ void iwl_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state) struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); if (state) - set_bit(STATUS_RF_KILL_HW, &priv->shrd->status); + set_bit(STATUS_RF_KILL_HW, &priv->status); else - clear_bit(STATUS_RF_KILL_HW, &priv->shrd->status); + clear_bit(STATUS_RF_KILL_HW, &priv->status); wiphy_rfkill_set_hw_state(priv->hw->wiphy, state); } diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index 1c235d685ae6..7a1334e8c358 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c @@ -454,7 +454,7 @@ static ssize_t iwl_dbgfs_channels_read(struct file *file, char __user *user_buf, char *buf; ssize_t ret; - if (!test_bit(STATUS_GEO_CONFIGURED, &priv->shrd->status)) + if (!test_bit(STATUS_GEO_CONFIGURED, &priv->status)) return -EAGAIN; buf = kzalloc(bufsz, GFP_KERNEL); @@ -525,28 +525,26 @@ static ssize_t iwl_dbgfs_status_read(struct file *file, pos += scnprintf(buf + pos, bufsz - pos, "STATUS_HCMD_ACTIVE:\t %d\n", test_bit(STATUS_HCMD_ACTIVE, &priv->shrd->status)); - pos += scnprintf(buf + pos, bufsz - pos, "STATUS_INT_ENABLED:\t %d\n", - test_bit(STATUS_INT_ENABLED, &priv->shrd->status)); pos += scnprintf(buf + pos, bufsz - pos, "STATUS_RF_KILL_HW:\t %d\n", - test_bit(STATUS_RF_KILL_HW, &priv->shrd->status)); + test_bit(STATUS_RF_KILL_HW, &priv->status)); pos += scnprintf(buf + pos, bufsz - pos, "STATUS_CT_KILL:\t\t %d\n", test_bit(STATUS_CT_KILL, &priv->status)); pos += scnprintf(buf + pos, bufsz - pos, "STATUS_ALIVE:\t\t %d\n", - test_bit(STATUS_ALIVE, &priv->shrd->status)); + test_bit(STATUS_ALIVE, &priv->status)); pos += scnprintf(buf + pos, bufsz - pos, "STATUS_READY:\t\t %d\n", - test_bit(STATUS_READY, &priv->shrd->status)); + test_bit(STATUS_READY, &priv->status)); pos += scnprintf(buf + pos, bufsz - pos, "STATUS_GEO_CONFIGURED:\t %d\n", - test_bit(STATUS_GEO_CONFIGURED, &priv->shrd->status)); + test_bit(STATUS_GEO_CONFIGURED, &priv->status)); pos += scnprintf(buf + pos, bufsz - pos, "STATUS_EXIT_PENDING:\t %d\n", - test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)); + test_bit(STATUS_EXIT_PENDING, &priv->status)); pos += scnprintf(buf + pos, bufsz - pos, "STATUS_STATISTICS:\t %d\n", - test_bit(STATUS_STATISTICS, &priv->shrd->status)); + test_bit(STATUS_STATISTICS, &priv->status)); pos += scnprintf(buf + pos, bufsz - pos, "STATUS_SCANNING:\t %d\n", - test_bit(STATUS_SCANNING, &priv->shrd->status)); + test_bit(STATUS_SCANNING, &priv->status)); pos += scnprintf(buf + pos, bufsz - pos, "STATUS_SCAN_ABORTING:\t %d\n", - test_bit(STATUS_SCAN_ABORTING, &priv->shrd->status)); + test_bit(STATUS_SCAN_ABORTING, &priv->status)); pos += scnprintf(buf + pos, bufsz - pos, "STATUS_SCAN_HW:\t\t %d\n", - test_bit(STATUS_SCAN_HW, &priv->shrd->status)); + test_bit(STATUS_SCAN_HW, &priv->status)); pos += scnprintf(buf + pos, bufsz - pos, "STATUS_POWER_PMI:\t %d\n", test_bit(STATUS_POWER_PMI, &priv->shrd->status)); pos += scnprintf(buf + pos, bufsz - pos, "STATUS_FW_ERROR:\t %d\n", @@ -752,7 +750,7 @@ static ssize_t iwl_dbgfs_sleep_level_override_write(struct file *file, if (value != -1 && (value < 0 || value >= IWL_POWER_NUM)) return -EINVAL; - if (!iwl_is_ready_rf(priv->shrd)) + if (!iwl_is_ready_rf(priv)) return -EAGAIN; priv->power_data.debug_sleep_level_override = value; @@ -947,7 +945,7 @@ static ssize_t iwl_dbgfs_ucode_rx_stats_read(struct file *file, struct statistics_rx_non_phy *delta_general, *max_general; struct statistics_rx_ht_phy *ht, *accum_ht, *delta_ht, *max_ht; - if (!iwl_is_alive(priv->shrd)) + if (!iwl_is_alive(priv)) return -EAGAIN; buf = kzalloc(bufsz, GFP_KERNEL); @@ -1376,7 +1374,7 @@ static ssize_t iwl_dbgfs_ucode_tx_stats_read(struct file *file, ssize_t ret; struct statistics_tx *tx, *accum_tx, *delta_tx, *max_tx; - if (!iwl_is_alive(priv->shrd)) + if (!iwl_is_alive(priv)) return -EAGAIN; buf = kzalloc(bufsz, GFP_KERNEL); @@ -1578,7 +1576,7 @@ static ssize_t iwl_dbgfs_ucode_general_stats_read(struct file *file, struct statistics_dbg *dbg, *accum_dbg, *delta_dbg, *max_dbg; struct statistics_div *div, *accum_div, *delta_div, *max_div; - if (!iwl_is_alive(priv->shrd)) + if (!iwl_is_alive(priv)) return -EAGAIN; buf = kzalloc(bufsz, GFP_KERNEL); @@ -1697,7 +1695,7 @@ static ssize_t iwl_dbgfs_ucode_bt_stats_read(struct file *file, ssize_t ret; struct statistics_bt_activity *bt, *accum_bt; - if (!iwl_is_alive(priv->shrd)) + if (!iwl_is_alive(priv)) return -EAGAIN; if (!priv->bt_enable_flag) @@ -1790,7 +1788,7 @@ static ssize_t iwl_dbgfs_reply_tx_error_read(struct file *file, (sizeof(struct reply_agg_tx_error_statistics) * 24) + 200; ssize_t ret; - if (!iwl_is_alive(priv->shrd)) + if (!iwl_is_alive(priv)) return -EAGAIN; buf = kzalloc(bufsz, GFP_KERNEL); @@ -2148,7 +2146,7 @@ static ssize_t iwl_dbgfs_ucode_tracing_write(struct file *file, if (trace) { priv->event_log.ucode_trace = true; - if (iwl_is_alive(priv->shrd)) { + if (iwl_is_alive(priv)) { /* start collecting data now */ mod_timer(&priv->ucode_trace, jiffies); } @@ -2338,7 +2336,7 @@ static ssize_t iwl_dbgfs_txfifo_flush_write(struct file *file, if (sscanf(buf, "%d", &flush) != 1) return -EINVAL; - if (iwl_is_rfkill(priv->shrd)) + if (iwl_is_rfkill(priv)) return -EFAULT; iwlagn_dev_txfifo_flush(priv, IWL_DROP_ALL); diff --git a/drivers/net/wireless/iwlwifi/iwl-led.c b/drivers/net/wireless/iwlwifi/iwl-led.c index f2f706f084a5..1993a2b7ae63 100644 --- a/drivers/net/wireless/iwlwifi/iwl-led.c +++ b/drivers/net/wireless/iwlwifi/iwl-led.c @@ -126,7 +126,7 @@ static int iwl_led_cmd(struct iwl_priv *priv, }; int ret; - if (!test_bit(STATUS_READY, &priv->shrd->status)) + if (!test_bit(STATUS_READY, &priv->status)) return -EBUSY; if (priv->blink_on == on && priv->blink_off == off) diff --git a/drivers/net/wireless/iwlwifi/iwl-mac80211.c b/drivers/net/wireless/iwlwifi/iwl-mac80211.c index dcf39f84f239..54d3709c0a6c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-mac80211.c +++ b/drivers/net/wireless/iwlwifi/iwl-mac80211.c @@ -266,7 +266,7 @@ static int __iwl_up(struct iwl_priv *priv) lockdep_assert_held(&priv->mutex); - if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) { + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) { IWL_WARN(priv, "Exit pending; will not bring the NIC up\n"); return -EIO; } @@ -297,9 +297,9 @@ static int __iwl_up(struct iwl_priv *priv) return 0; error: - set_bit(STATUS_EXIT_PENDING, &priv->shrd->status); + set_bit(STATUS_EXIT_PENDING, &priv->status); iwl_down(priv); - clear_bit(STATUS_EXIT_PENDING, &priv->shrd->status); + clear_bit(STATUS_EXIT_PENDING, &priv->status); IWL_ERR(priv, "Unable to initialize device.\n"); return ret; @@ -322,7 +322,7 @@ static int iwlagn_mac_start(struct ieee80211_hw *hw) IWL_DEBUG_INFO(priv, "Start UP work done.\n"); /* Now we should be done, and the READY bit should be set. */ - if (WARN_ON(!test_bit(STATUS_READY, &priv->shrd->status))) + if (WARN_ON(!test_bit(STATUS_READY, &priv->status))) ret = -EIO; iwlagn_led_enable(priv); @@ -807,7 +807,7 @@ static int iwlagn_mac_sta_state(struct ieee80211_hw *hw, * mac80211 might WARN if we fail, but due the way we * (badly) handle hard rfkill, we might fail here */ - if (iwl_is_rfkill(priv->shrd)) + if (iwl_is_rfkill(priv)) ret = 0; mutex_unlock(&priv->mutex); @@ -839,12 +839,12 @@ static void iwlagn_mac_channel_switch(struct ieee80211_hw *hw, mutex_lock(&priv->mutex); - if (iwl_is_rfkill(priv->shrd)) + if (iwl_is_rfkill(priv)) goto out; - if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status) || - test_bit(STATUS_SCANNING, &priv->shrd->status) || - test_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->shrd->status)) + if (test_bit(STATUS_EXIT_PENDING, &priv->status) || + test_bit(STATUS_SCANNING, &priv->status) || + test_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status)) goto out; if (!iwl_is_associated_ctx(ctx)) @@ -884,10 +884,10 @@ static void iwlagn_mac_channel_switch(struct ieee80211_hw *hw, * at this point, staging_rxon has the * configuration for channel switch */ - set_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->shrd->status); + set_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status); priv->switch_channel = cpu_to_le16(ch); if (cfg(priv)->lib->set_channel_switch(priv, ch_switch)) { - clear_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->shrd->status); + clear_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status); priv->switch_channel = 0; ieee80211_chswitch_done(ctx->vif, false); } @@ -954,11 +954,11 @@ static void iwlagn_mac_flush(struct ieee80211_hw *hw, bool drop) mutex_lock(&priv->mutex); IWL_DEBUG_MAC80211(priv, "enter\n"); - if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) { + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) { IWL_DEBUG_TX(priv, "Aborting flush due to device shutdown\n"); goto done; } - if (iwl_is_rfkill(priv->shrd)) { + if (iwl_is_rfkill(priv)) { IWL_DEBUG_TX(priv, "Aborting flush due to RF Kill\n"); goto done; } @@ -999,7 +999,7 @@ static int iwlagn_mac_remain_on_channel(struct ieee80211_hw *hw, IWL_DEBUG_MAC80211(priv, "enter\n"); mutex_lock(&priv->mutex); - if (test_bit(STATUS_SCAN_HW, &priv->shrd->status)) { + if (test_bit(STATUS_SCAN_HW, &priv->status)) { err = -EBUSY; goto out; } @@ -1140,7 +1140,7 @@ static int iwlagn_mac_conf_tx(struct ieee80211_hw *hw, IWL_DEBUG_MAC80211(priv, "enter\n"); - if (!iwl_is_ready_rf(priv->shrd)) { + if (!iwl_is_ready_rf(priv)) { IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n"); return -EIO; } @@ -1241,7 +1241,7 @@ static int iwlagn_mac_add_interface(struct ieee80211_hw *hw, iwlagn_disable_roc(priv); - if (!iwl_is_ready_rf(priv->shrd)) { + if (!iwl_is_ready_rf(priv)) { IWL_WARN(priv, "Try to add interface when device not ready\n"); err = -EINVAL; goto out; @@ -1365,7 +1365,7 @@ static int iwlagn_mac_change_interface(struct ieee80211_hw *hw, mutex_lock(&priv->mutex); - if (!ctx->vif || !iwl_is_ready_rf(priv->shrd)) { + if (!ctx->vif || !iwl_is_ready_rf(priv)) { /* * Huh? But wait ... this can maybe happen when * we're in the middle of a firmware restart! diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c index f79ff16e29f4..958d9d09aee3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-power.c +++ b/drivers/net/wireless/iwlwifi/iwl-power.c @@ -392,12 +392,12 @@ int iwl_power_set_mode(struct iwl_priv *priv, struct iwl_powertable_cmd *cmd, if (!memcmp(&priv->power_data.sleep_cmd, cmd, sizeof(*cmd)) && !force) return 0; - if (!iwl_is_ready_rf(priv->shrd)) + if (!iwl_is_ready_rf(priv)) return -EIO; /* scan complete use sleep_power_next, need to be updated */ memcpy(&priv->power_data.sleep_cmd_next, cmd, sizeof(*cmd)); - if (test_bit(STATUS_SCANNING, &priv->shrd->status) && !force) { + if (test_bit(STATUS_SCANNING, &priv->status) && !force) { IWL_DEBUG_INFO(priv, "Defer power set mode while scanning\n"); return 0; } diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index 8c3fb3233d9f..902efe4bc898 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c @@ -66,9 +66,9 @@ static int iwl_send_scan_abort(struct iwl_priv *priv) /* Exit instantly with error when device is not ready * to receive scan abort command or it does not perform * hardware scan currently */ - if (!test_bit(STATUS_READY, &priv->shrd->status) || - !test_bit(STATUS_GEO_CONFIGURED, &priv->shrd->status) || - !test_bit(STATUS_SCAN_HW, &priv->shrd->status) || + if (!test_bit(STATUS_READY, &priv->status) || + !test_bit(STATUS_GEO_CONFIGURED, &priv->status) || + !test_bit(STATUS_SCAN_HW, &priv->status) || test_bit(STATUS_FW_ERROR, &priv->shrd->status)) return -EIO; @@ -118,18 +118,18 @@ static void iwl_process_scan_complete(struct iwl_priv *priv) lockdep_assert_held(&priv->mutex); - if (!test_and_clear_bit(STATUS_SCAN_COMPLETE, &priv->shrd->status)) + if (!test_and_clear_bit(STATUS_SCAN_COMPLETE, &priv->status)) return; IWL_DEBUG_SCAN(priv, "Completed scan.\n"); cancel_delayed_work(&priv->scan_check); - aborted = test_and_clear_bit(STATUS_SCAN_ABORTING, &priv->shrd->status); + aborted = test_and_clear_bit(STATUS_SCAN_ABORTING, &priv->status); if (aborted) IWL_DEBUG_SCAN(priv, "Aborted scan completed.\n"); - if (!test_and_clear_bit(STATUS_SCANNING, &priv->shrd->status)) { + if (!test_and_clear_bit(STATUS_SCANNING, &priv->status)) { IWL_DEBUG_SCAN(priv, "Scan already completed.\n"); goto out_settings; } @@ -165,7 +165,7 @@ out_complete: out_settings: /* Can we still talk to firmware ? */ - if (!iwl_is_ready_rf(priv->shrd)) + if (!iwl_is_ready_rf(priv)) return; iwlagn_post_scan(priv); @@ -175,16 +175,16 @@ void iwl_force_scan_end(struct iwl_priv *priv) { lockdep_assert_held(&priv->mutex); - if (!test_bit(STATUS_SCANNING, &priv->shrd->status)) { + if (!test_bit(STATUS_SCANNING, &priv->status)) { IWL_DEBUG_SCAN(priv, "Forcing scan end while not scanning\n"); return; } IWL_DEBUG_SCAN(priv, "Forcing scan end\n"); - clear_bit(STATUS_SCANNING, &priv->shrd->status); - clear_bit(STATUS_SCAN_HW, &priv->shrd->status); - clear_bit(STATUS_SCAN_ABORTING, &priv->shrd->status); - clear_bit(STATUS_SCAN_COMPLETE, &priv->shrd->status); + clear_bit(STATUS_SCANNING, &priv->status); + clear_bit(STATUS_SCAN_HW, &priv->status); + clear_bit(STATUS_SCAN_ABORTING, &priv->status); + clear_bit(STATUS_SCAN_COMPLETE, &priv->status); iwl_complete_scan(priv, true); } @@ -194,12 +194,12 @@ static void iwl_do_scan_abort(struct iwl_priv *priv) lockdep_assert_held(&priv->mutex); - if (!test_bit(STATUS_SCANNING, &priv->shrd->status)) { + if (!test_bit(STATUS_SCANNING, &priv->status)) { IWL_DEBUG_SCAN(priv, "Not performing scan to abort\n"); return; } - if (test_and_set_bit(STATUS_SCAN_ABORTING, &priv->shrd->status)) { + if (test_and_set_bit(STATUS_SCAN_ABORTING, &priv->status)) { IWL_DEBUG_SCAN(priv, "Scan abort in progress\n"); return; } @@ -238,7 +238,7 @@ void iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms) iwl_do_scan_abort(priv); while (time_before_eq(jiffies, timeout)) { - if (!test_bit(STATUS_SCAN_HW, &priv->shrd->status)) + if (!test_bit(STATUS_SCAN_HW, &priv->status)) goto finished; msleep(20); } @@ -350,8 +350,8 @@ static int iwl_rx_scan_complete_notif(struct iwl_priv *priv, * to clear, we need to set SCAN_COMPLETE before clearing SCAN_HW * to avoid a race there. */ - set_bit(STATUS_SCAN_COMPLETE, &priv->shrd->status); - clear_bit(STATUS_SCAN_HW, &priv->shrd->status); + set_bit(STATUS_SCAN_COMPLETE, &priv->status); + clear_bit(STATUS_SCAN_HW, &priv->status); queue_work(priv->workqueue, &priv->scan_completed); if (priv->iw_mode != NL80211_IFTYPE_ADHOC && @@ -927,7 +927,7 @@ static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) scan->len = cpu_to_le16(cmd.len[0]); /* set scan bit here for PAN params */ - set_bit(STATUS_SCAN_HW, &priv->shrd->status); + set_bit(STATUS_SCAN_HW, &priv->status); ret = iwlagn_set_pan_params(priv); if (ret) @@ -935,7 +935,7 @@ static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) ret = iwl_dvm_send_cmd(priv, &cmd); if (ret) { - clear_bit(STATUS_SCAN_HW, &priv->shrd->status); + clear_bit(STATUS_SCAN_HW, &priv->status); iwlagn_set_pan_params(priv); } @@ -962,18 +962,18 @@ int __must_check iwl_scan_initiate(struct iwl_priv *priv, cancel_delayed_work(&priv->scan_check); - if (!iwl_is_ready_rf(priv->shrd)) { + if (!iwl_is_ready_rf(priv)) { IWL_WARN(priv, "Request scan called when driver not ready.\n"); return -EIO; } - if (test_bit(STATUS_SCAN_HW, &priv->shrd->status)) { + if (test_bit(STATUS_SCAN_HW, &priv->status)) { IWL_DEBUG_SCAN(priv, "Multiple concurrent scan requests in parallel.\n"); return -EBUSY; } - if (test_bit(STATUS_SCAN_ABORTING, &priv->shrd->status)) { + if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) { IWL_DEBUG_SCAN(priv, "Scan request while abort pending.\n"); return -EBUSY; } @@ -983,14 +983,14 @@ int __must_check iwl_scan_initiate(struct iwl_priv *priv, scan_type == IWL_SCAN_ROC ? "remain-on-channel " : "internal short "); - set_bit(STATUS_SCANNING, &priv->shrd->status); + set_bit(STATUS_SCANNING, &priv->status); priv->scan_type = scan_type; priv->scan_start = jiffies; priv->scan_band = band; ret = iwlagn_request_scan(priv, vif); if (ret) { - clear_bit(STATUS_SCANNING, &priv->shrd->status); + clear_bit(STATUS_SCANNING, &priv->status); priv->scan_type = IWL_SCAN_NORMAL; return ret; } @@ -1025,7 +1025,7 @@ static void iwl_bg_start_internal_scan(struct work_struct *work) goto unlock; } - if (test_bit(STATUS_SCANNING, &priv->shrd->status)) { + if (test_bit(STATUS_SCANNING, &priv->status)) { IWL_DEBUG_SCAN(priv, "Scan already in progress.\n"); goto unlock; } diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h index 16a32ae4046e..dd64e69b1569 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h @@ -356,7 +356,8 @@ void iwl_dump_csr(struct iwl_trans *trans); ******************************************************/ static inline void iwl_disable_interrupts(struct iwl_trans *trans) { - clear_bit(STATUS_INT_ENABLED, &trans->shrd->status); + struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); + clear_bit(STATUS_INT_ENABLED, &trans_pcie->status); /* disable interrupts from uCode/NIC to host */ iwl_write32(trans, CSR_INT_MASK, 0x00000000); @@ -370,11 +371,10 @@ static inline void iwl_disable_interrupts(struct iwl_trans *trans) static inline void iwl_enable_interrupts(struct iwl_trans *trans) { - struct iwl_trans_pcie *trans_pcie = - IWL_TRANS_GET_PCIE_TRANS(trans); + struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); IWL_DEBUG_ISR(trans, "Enabling interrupts\n"); - set_bit(STATUS_INT_ENABLED, &trans->shrd->status); + set_bit(STATUS_INT_ENABLED, &trans_pcie->status); iwl_write32(trans, CSR_INT_MASK, trans_pcie->inta_mask); } diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c index 2d6ea42b0d8e..32820913a2fd 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c @@ -1131,7 +1131,7 @@ void iwl_irq_tasklet(struct iwl_trans *trans) /* Re-enable all interrupts */ /* only Re-enable if disabled by irq */ - if (test_bit(STATUS_INT_ENABLED, &trans->shrd->status)) + if (test_bit(STATUS_INT_ENABLED, &trans_pcie->status)) iwl_enable_interrupts(trans); /* Re-enable RF_KILL if it occurred */ else if (handled & CSR_INT_BIT_RF_KILL) @@ -1303,7 +1303,7 @@ static irqreturn_t iwl_isr(int irq, void *data) /* iwl_irq_tasklet() will service interrupts and re-enable them */ if (likely(inta)) tasklet_schedule(&trans_pcie->irq_tasklet); - else if (test_bit(STATUS_INT_ENABLED, &trans->shrd->status) && + else if (test_bit(STATUS_INT_ENABLED, &trans_pcie->status) && !trans_pcie->inta) iwl_enable_interrupts(trans); @@ -1314,7 +1314,7 @@ static irqreturn_t iwl_isr(int irq, void *data) none: /* re-enable interrupts here since we don't have anything to service. */ /* only Re-enable if disabled by irq and no schedules tasklet. */ - if (test_bit(STATUS_INT_ENABLED, &trans->shrd->status) && + if (test_bit(STATUS_INT_ENABLED, &trans_pcie->status) && !trans_pcie->inta) iwl_enable_interrupts(trans); @@ -1414,7 +1414,7 @@ irqreturn_t iwl_isr_ict(int irq, void *data) /* iwl_irq_tasklet() will service interrupts and re-enable them */ if (likely(inta)) tasklet_schedule(&trans_pcie->irq_tasklet); - else if (test_bit(STATUS_INT_ENABLED, &trans->shrd->status) && + else if (test_bit(STATUS_INT_ENABLED, &trans_pcie->status) && !trans_pcie->inta) { /* Allow interrupt if was disabled by this handler and * no tasklet was schedules, We should not enable interrupt, @@ -1430,7 +1430,7 @@ irqreturn_t iwl_isr_ict(int irq, void *data) /* re-enable interrupts here since we don't have anything to service. * only Re-enable if disabled by irq. */ - if (test_bit(STATUS_INT_ENABLED, &trans->shrd->status) && + if (test_bit(STATUS_INT_ENABLED, &trans_pcie->status) && !trans_pcie->inta) iwl_enable_interrupts(trans); diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c index e78098e79ee1..3b8a5fb771f6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c @@ -684,6 +684,7 @@ static void iwl_apm_config(struct iwl_trans *trans) */ static int iwl_apm_init(struct iwl_trans *trans) { + struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); int ret = 0; IWL_DEBUG_INFO(trans, "Init card's basic functions\n"); @@ -753,7 +754,7 @@ static int iwl_apm_init(struct iwl_trans *trans) iwl_set_bits_prph(trans, APMG_PCIDEV_STT_REG, APMG_PCIDEV_STT_VAL_L1_ACT_DIS); - set_bit(STATUS_DEVICE_ENABLED, &trans->shrd->status); + set_bit(STATUS_DEVICE_ENABLED, &trans_pcie->status); out: return ret; @@ -779,9 +780,10 @@ static int iwl_apm_stop_master(struct iwl_trans *trans) static void iwl_apm_stop(struct iwl_trans *trans) { + struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); IWL_DEBUG_INFO(trans, "Stop card, put in low power state\n"); - clear_bit(STATUS_DEVICE_ENABLED, &trans->shrd->status); + clear_bit(STATUS_DEVICE_ENABLED, &trans_pcie->status); /* Stop device's DMA activity */ iwl_apm_stop_master(trans); @@ -1265,7 +1267,7 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans) * restart. So don't process again if the device is * already dead. */ - if (test_bit(STATUS_DEVICE_ENABLED, &trans->shrd->status)) { + if (test_bit(STATUS_DEVICE_ENABLED, &trans_pcie->status)) { iwl_trans_tx_stop(trans); #ifndef CONFIG_IWLWIFI_IDI iwl_trans_rx_stop(trans); -- cgit From bada991b4590122c847520ed2b651b679c16afd3 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 7 Mar 2012 09:52:39 -0800 Subject: iwlwifi: remove messages from queue wake/stop The only reason we ever stop/wake queues at the transport level is now that they become full (or non-full), so the messages aren't useful any more -- remove them. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h | 36 +++++++++++------------ drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | 4 +-- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h index dd64e69b1569..c0e68097fcb5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h @@ -409,7 +409,7 @@ static inline u8 iwl_get_queue_ac(struct iwl_tx_queue *txq) } static inline void iwl_wake_queue(struct iwl_trans *trans, - struct iwl_tx_queue *txq, const char *msg) + struct iwl_tx_queue *txq) { u8 queue = txq->swq_id; u8 ac = queue & 3; @@ -420,19 +420,19 @@ static inline void iwl_wake_queue(struct iwl_trans *trans, if (test_and_clear_bit(hwq, trans_pcie->queue_stopped)) { if (atomic_dec_return(&trans_pcie->queue_stop_count[ac]) <= 0) { iwl_op_mode_queue_not_full(trans->op_mode, ac); - IWL_DEBUG_TX_QUEUES(trans, "Wake hwq %d ac %d. %s", - hwq, ac, msg); + IWL_DEBUG_TX_QUEUES(trans, "Wake hwq %d ac %d", + hwq, ac); } else { - IWL_DEBUG_TX_QUEUES(trans, "Don't wake hwq %d ac %d" - " stop count %d. %s", - hwq, ac, atomic_read(&trans_pcie-> - queue_stop_count[ac]), msg); + IWL_DEBUG_TX_QUEUES(trans, + "Don't wake hwq %d ac %d stop count %d", + hwq, ac, + atomic_read(&trans_pcie->queue_stop_count[ac])); } } } static inline void iwl_stop_queue(struct iwl_trans *trans, - struct iwl_tx_queue *txq, const char *msg) + struct iwl_tx_queue *txq) { u8 queue = txq->swq_id; u8 ac = queue & 3; @@ -443,19 +443,19 @@ static inline void iwl_stop_queue(struct iwl_trans *trans, if (!test_and_set_bit(hwq, trans_pcie->queue_stopped)) { if (atomic_inc_return(&trans_pcie->queue_stop_count[ac]) > 0) { iwl_op_mode_queue_full(trans->op_mode, ac); - IWL_DEBUG_TX_QUEUES(trans, "Stop hwq %d ac %d" - " stop count %d. %s", - hwq, ac, atomic_read(&trans_pcie-> - queue_stop_count[ac]), msg); + IWL_DEBUG_TX_QUEUES(trans, + "Stop hwq %d ac %d stop count %d", + hwq, ac, + atomic_read(&trans_pcie->queue_stop_count[ac])); } else { - IWL_DEBUG_TX_QUEUES(trans, "Don't stop hwq %d ac %d" - " stop count %d. %s", - hwq, ac, atomic_read(&trans_pcie-> - queue_stop_count[ac]), msg); + IWL_DEBUG_TX_QUEUES(trans, + "Don't stop hwq %d ac %d stop count %d", + hwq, ac, + atomic_read(&trans_pcie->queue_stop_count[ac])); } } else { - IWL_DEBUG_TX_QUEUES(trans, "stop hwq %d, but it is stopped/ %s", - hwq, msg); + IWL_DEBUG_TX_QUEUES(trans, "stop hwq %d, but it is stopped", + hwq); } } diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c index 3b8a5fb771f6..6172651d7e25 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c @@ -1487,7 +1487,7 @@ static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, txq->need_update = 1; iwl_txq_update_write_ptr(trans, txq); } else { - iwl_stop_queue(trans, txq, "Queue is full"); + iwl_stop_queue(trans, txq); } } spin_unlock(&txq->lock); @@ -1591,7 +1591,7 @@ static int iwl_trans_pcie_reclaim(struct iwl_trans *trans, int sta_id, int tid, tfd_num, ssn); freed = iwl_tx_queue_reclaim(trans, txq_id, tfd_num, skbs); if (iwl_queue_space(&txq->q) > txq->q.low_mark) - iwl_wake_queue(trans, txq, "Packets reclaimed"); + iwl_wake_queue(trans, txq); } spin_unlock(&txq->lock); -- cgit From e6dd5838acf312516fcc4eb34516de5bc45e2980 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 7 Mar 2012 09:52:40 -0800 Subject: iwlwifi: make iwl_init_context static It's not needed anywhere but during init. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn.c | 2 +- drivers/net/wireless/iwlwifi/iwl-agn.h | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index d45def33d0f6..8c21db81ba5f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -488,7 +488,7 @@ static void iwl_bg_tx_flush(struct work_struct *work) iwlagn_dev_txfifo_flush(priv, IWL_DROP_ALL); } -void iwl_init_context(struct iwl_priv *priv, u32 ucode_flags) +static void iwl_init_context(struct iwl_priv *priv, u32 ucode_flags) { int i; diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index eb96855ddf8d..5410dfd40694 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h @@ -118,7 +118,6 @@ void iwlagn_config_ht40(struct ieee80211_conf *conf, int iwlagn_rx_calib_result(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb, struct iwl_device_cmd *cmd); -void iwl_init_context(struct iwl_priv *priv, u32 ucode_flags); int iwl_send_bt_env(struct iwl_priv *priv, u8 action, u8 type); void iwl_send_prio_tbl(struct iwl_priv *priv); int iwl_init_alive_start(struct iwl_priv *priv); -- cgit From 974205153be8944539890084a170e3ad407164bc Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 7 Mar 2012 09:52:42 -0800 Subject: iwlwifi: don't delete AP station directly With the mac80211 deauth sequence changes, the station is deleted before the device is set unassociated. This can cause the device to get confused as it expects the station to be there while the associated bit is set. To fix this, do not delete the AP station from the device when mac80211 asks for deletion, instead just mark it as unused and rely on the unassociated RXON to drop it from the station database in the device. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-sta.c | 35 +++++++++++++++++++++++++++++ drivers/net/wireless/iwlwifi/iwl-agn.h | 2 ++ drivers/net/wireless/iwlwifi/iwl-mac80211.c | 22 +++++++++++++----- 3 files changed, 53 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c index 23e9eab477bb..c4175603864b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c @@ -546,6 +546,41 @@ out_err: return -EINVAL; } +void iwl_deactivate_station(struct iwl_priv *priv, const u8 sta_id, + const u8 *addr) +{ + u8 tid; + + if (!iwl_is_ready(priv)) { + IWL_DEBUG_INFO(priv, + "Unable to remove station %pM, device not ready.\n", + addr); + return; + } + + IWL_DEBUG_ASSOC(priv, "Deactivating STA: %pM (%d)\n", addr, sta_id); + + if (WARN_ON_ONCE(sta_id == IWL_INVALID_STATION)) + return; + + spin_lock_bh(&priv->sta_lock); + + WARN_ON_ONCE(!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE)); + + for (tid = 0; tid < IWL_MAX_TID_COUNT; tid++) + memset(&priv->tid_data[sta_id][tid], 0, + sizeof(priv->tid_data[sta_id][tid])); + + priv->stations[sta_id].used &= ~IWL_STA_DRIVER_ACTIVE; + + priv->num_stations--; + + if (WARN_ON_ONCE(priv->num_stations < 0)) + priv->num_stations = 0; + + spin_unlock_bh(&priv->sta_lock); +} + /** * iwl_clear_ucode_stations - clear ucode station table bits * diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index 5410dfd40694..3780a03f2716 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h @@ -234,6 +234,8 @@ int iwl_add_station_common(struct iwl_priv *priv, struct iwl_rxon_context *ctx, struct ieee80211_sta *sta, u8 *sta_id_r); int iwl_remove_station(struct iwl_priv *priv, const u8 sta_id, const u8 *addr); +void iwl_deactivate_station(struct iwl_priv *priv, const u8 sta_id, + const u8 *addr); u8 iwl_prep_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx, const u8 *addr, bool is_ap, struct ieee80211_sta *sta); diff --git a/drivers/net/wireless/iwlwifi/iwl-mac80211.c b/drivers/net/wireless/iwlwifi/iwl-mac80211.c index 54d3709c0a6c..9212ee3bef9b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-mac80211.c +++ b/drivers/net/wireless/iwlwifi/iwl-mac80211.c @@ -724,12 +724,22 @@ static int iwlagn_mac_sta_remove(struct ieee80211_hw *hw, struct iwl_station_priv *sta_priv = (void *)sta->drv_priv; int ret; - IWL_DEBUG_INFO(priv, "proceeding to remove station %pM\n", - sta->addr); - ret = iwl_remove_station(priv, sta_priv->sta_id, sta->addr); - if (ret) - IWL_DEBUG_QUIET_RFKILL(priv, "Error removing station %pM\n", - sta->addr); + IWL_DEBUG_INFO(priv, "proceeding to remove station %pM\n", sta->addr); + + if (vif->type == NL80211_IFTYPE_STATION) { + /* + * Station will be removed from device when the RXON + * is set to unassociated -- just deactivate it here + * to avoid re-programming it. + */ + ret = 0; + iwl_deactivate_station(priv, sta_priv->sta_id, sta->addr); + } else { + ret = iwl_remove_station(priv, sta_priv->sta_id, sta->addr); + if (ret) + IWL_DEBUG_QUIET_RFKILL(priv, + "Error removing station %pM\n", sta->addr); + } return ret; } -- cgit From 1353a7ba7ebe62dedc60a5ba75c434cfad960ede Mon Sep 17 00:00:00 2001 From: Don Fry Date: Wed, 7 Mar 2012 09:52:43 -0800 Subject: iwlwifi: correct status bit refactoring errors I missed a couple of status bits in my refactoring changes. This fixes the ones I missed. Signed-off-by: Don Fry Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-rx.c | 2 +- drivers/net/wireless/iwlwifi/iwl-agn.c | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c index 3ad43330f6a1..cc0227c1f352 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c @@ -628,7 +628,7 @@ static int iwlagn_rx_card_state_notif(struct iwl_priv *priv, struct iwl_rx_packet *pkt = rxb_addr(rxb); struct iwl_card_state_notif *card_state_notif = (void *)pkt->data; u32 flags = le32_to_cpu(card_state_notif->flags); - unsigned long status = priv->shrd->status; + unsigned long status = priv->status; IWL_DEBUG_RF_KILL(priv, "Card state received: HW:%s SW:%s CT:%s\n", (flags & HW_CARD_DISABLED) ? "Kill" : "On", diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 8c21db81ba5f..60f1dc640c94 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -819,15 +819,15 @@ void iwl_down(struct iwl_priv *priv) iwl_trans_stop_device(trans(priv)); /* Clear out all status bits but a few that are stable across reset */ - priv->shrd->status &= - test_bit(STATUS_RF_KILL_HW, &priv->status) << + priv->status &= test_bit(STATUS_RF_KILL_HW, &priv->status) << STATUS_RF_KILL_HW | test_bit(STATUS_GEO_CONFIGURED, &priv->status) << STATUS_GEO_CONFIGURED | - test_bit(STATUS_FW_ERROR, &priv->shrd->status) << - STATUS_FW_ERROR | test_bit(STATUS_EXIT_PENDING, &priv->status) << STATUS_EXIT_PENDING; + priv->shrd->status &= + test_bit(STATUS_FW_ERROR, &priv->shrd->status) << + STATUS_FW_ERROR; dev_kfree_skb(priv->beacon_skb); priv->beacon_skb = NULL; -- cgit From f44d4eb54432a0109ff15b2669c91f061428ff39 Mon Sep 17 00:00:00 2001 From: Simon Wunderlich Date: Wed, 7 Mar 2012 21:31:13 +0100 Subject: mac80211: update ieee80211_tx_rate_control kerneldoc * add entry for rate_idx_mcs_mask * fix order of entries to represent the structs' order Signed-off-by: Simon Wunderlich Signed-off-by: John W. Linville --- include/net/mac80211.h | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/include/net/mac80211.h b/include/net/mac80211.h index c06974accfa6..f7917f765cbc 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -3568,6 +3568,8 @@ enum rate_control_changed { * @hw: The hardware the algorithm is invoked for. * @sband: The band this frame is being transmitted on. * @bss_conf: the current BSS configuration + * @skb: the skb that will be transmitted, the control information in it needs + * to be filled in * @reported_rate: The rate control algorithm can fill this in to indicate * which rate should be reported to userspace as the current rate and * used for rate calculations in the mesh network. @@ -3575,12 +3577,11 @@ enum rate_control_changed { * RTS threshold * @short_preamble: whether mac80211 will request short-preamble transmission * if the selected rate supports it - * @max_rate_idx: user-requested maximum rate (not MCS for now) + * @max_rate_idx: user-requested maximum (legacy) rate * (deprecated; this will be removed once drivers get updated to use * rate_idx_mask) - * @rate_idx_mask: user-requested rate mask (not MCS for now) - * @skb: the skb that will be transmitted, the control information in it needs - * to be filled in + * @rate_idx_mask: user-requested (legacy) rate mask + * @rate_idx_mcs_mask: user-requested MCS rate mask * @bss: whether this frame is sent out in AP or IBSS mode */ struct ieee80211_tx_rate_control { -- cgit From d11f0ca0121996461b17e93941e9dfa0a9eebbd1 Mon Sep 17 00:00:00 2001 From: Stanislav Yakovlev Date: Wed, 7 Mar 2012 19:32:40 -0500 Subject: net/wireless: ipw2x00: remove WEXT_USECHANNELS define Driver does not use it any more. Signed-off-by: Stanislav Yakovlev Signed-off-by: John W. Linville --- drivers/net/wireless/ipw2x00/ipw2100.c | 2 -- drivers/net/wireless/ipw2x00/ipw2200.h | 2 -- 2 files changed, 4 deletions(-) diff --git a/drivers/net/wireless/ipw2x00/ipw2100.c b/drivers/net/wireless/ipw2x00/ipw2100.c index 5d7e97e63def..ddf340f914da 100644 --- a/drivers/net/wireless/ipw2x00/ipw2100.c +++ b/drivers/net/wireless/ipw2x00/ipw2100.c @@ -298,8 +298,6 @@ static const char *command_types[] = { }; #endif -#define WEXT_USECHANNELS 1 - static const long ipw2100_frequencies[] = { 2412, 2417, 2422, 2427, 2432, 2437, 2442, 2447, diff --git a/drivers/net/wireless/ipw2x00/ipw2200.h b/drivers/net/wireless/ipw2x00/ipw2200.h index ecb561d7a7a0..66e84ec0eb55 100644 --- a/drivers/net/wireless/ipw2x00/ipw2200.h +++ b/drivers/net/wireless/ipw2x00/ipw2200.h @@ -27,8 +27,6 @@ #ifndef __ipw2200_h__ #define __ipw2200_h__ -#define WEXT_USECHANNELS 1 - #include #include #include -- cgit From 8763848e03a9098e5b6f81428a98738dc960a436 Mon Sep 17 00:00:00 2001 From: Amitkumar Karwar Date: Wed, 7 Mar 2012 19:36:07 -0800 Subject: mwifiex: correction in number of bitrates In recent commit "mwifiex: correct bitrates advertised..", we have removed 22Mbps and 72Mbps bitrates from supported bitrate array. It means number of bitrates has reduced from 14 to 12. Initialize ".n_bitrates" to array size instead of hardcoding it. Signed-off-by: Amitkumar Karwar Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/cfg80211.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index b4890a01ba92..84508b065265 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c @@ -646,7 +646,7 @@ static struct ieee80211_supported_band mwifiex_band_2ghz = { .channels = mwifiex_channels_2ghz, .n_channels = ARRAY_SIZE(mwifiex_channels_2ghz), .bitrates = mwifiex_rates, - .n_bitrates = 14, + .n_bitrates = ARRAY_SIZE(mwifiex_rates), }; static struct ieee80211_channel mwifiex_channels_5ghz[] = { -- cgit From c6f600fcfe8a7e4f594fc4c80b2c7b66f248958b Mon Sep 17 00:00:00 2001 From: Meenakshi Venkataraman Date: Thu, 8 Mar 2012 11:29:12 -0800 Subject: iwlwifi: move command queue number out of the iwl_shared struct The command queue number is required by the transport layer, but it can be determined only by the op mode. Move this parameter to the dvm op mode, and configure the transport layer using an API. Signed-off-by: Meenakshi Venkataraman Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn.c | 16 +++++------ drivers/net/wireless/iwlwifi/iwl-shared.h | 2 -- drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h | 2 ++ drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c | 2 +- drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c | 24 ++++++++-------- drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | 34 ++++++++++++++++------- drivers/net/wireless/iwlwifi/iwl-trans.h | 9 ++++++ 7 files changed, 56 insertions(+), 33 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 60f1dc640c94..1e6b5e41a72b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -1236,6 +1236,14 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans, */ trans_cfg.op_mode = op_mode; + if (ucode_flags & IWL_UCODE_TLV_FLAGS_PAN) { + priv->sta_key_max_num = STA_KEY_MAX_NUM_PAN; + trans_cfg.cmd_queue = IWL_IPAN_CMD_QUEUE_NUM; + } else { + priv->sta_key_max_num = STA_KEY_MAX_NUM; + trans_cfg.cmd_queue = IWL_DEFAULT_CMD_QUEUE_NUM; + } + /* Configure transport layer */ iwl_trans_configure(trans(priv), &trans_cfg); @@ -1336,14 +1344,6 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans, priv->new_scan_threshold_behaviour = !!(ucode_flags & IWL_UCODE_TLV_FLAGS_NEWSCAN); - if (ucode_flags & IWL_UCODE_TLV_FLAGS_PAN) { - priv->sta_key_max_num = STA_KEY_MAX_NUM_PAN; - priv->shrd->cmd_queue = IWL_IPAN_CMD_QUEUE_NUM; - } else { - priv->sta_key_max_num = STA_KEY_MAX_NUM; - priv->shrd->cmd_queue = IWL_DEFAULT_CMD_QUEUE_NUM; - } - priv->phy_calib_chain_noise_reset_cmd = fw->ucode_capa.standard_phy_calibration_size; priv->phy_calib_chain_noise_gain_cmd = diff --git a/drivers/net/wireless/iwlwifi/iwl-shared.h b/drivers/net/wireless/iwlwifi/iwl-shared.h index 45409fcfbbd7..0d957ca3d6c6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-shared.h +++ b/drivers/net/wireless/iwlwifi/iwl-shared.h @@ -368,7 +368,6 @@ struct iwl_cfg { /** * struct iwl_shared - shared fields for all the layers of the driver * - * @cmd_queue: command queue number * @status: STATUS_* * @wowlan: are we running wowlan uCode * @valid_contexts: microcode/device supports multiple contexts @@ -385,7 +384,6 @@ struct iwl_cfg { * @device_pointers: pointers to ucode event tables */ struct iwl_shared { - u8 cmd_queue; unsigned long status; u8 valid_contexts; diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h index c0e68097fcb5..67965599bb30 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h @@ -248,6 +248,7 @@ struct iwl_tx_queue { * @ucode_write_complete: indicates that the ucode has been copied. * @ucode_write_waitq: wait queue for uCode load * @status - transport specific status flags + * @cmd_queue - command queue number */ struct iwl_trans_pcie { struct iwl_rx_queue rxq; @@ -289,6 +290,7 @@ struct iwl_trans_pcie { bool ucode_write_complete; wait_queue_head_t ucode_write_waitq; unsigned long status; + u8 cmd_queue; }; #define IWL_TRANS_GET_PCIE_TRANS(_iwl_trans) \ diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c index 32820913a2fd..a5547a155b95 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c @@ -361,7 +361,7 @@ static void iwl_rx_handle_rxbuf(struct iwl_trans *trans, { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); struct iwl_rx_queue *rxq = &trans_pcie->rxq; - struct iwl_tx_queue *txq = &trans_pcie->txq[trans->shrd->cmd_queue]; + struct iwl_tx_queue *txq = &trans_pcie->txq[trans_pcie->cmd_queue]; struct iwl_device_cmd *cmd; unsigned long flags; int len, err; diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c index 73febc9726cb..2b1df0092aee 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c @@ -397,7 +397,7 @@ static void iwlagn_txq_inval_byte_cnt_tbl(struct iwl_trans *trans, WARN_ON(read_ptr >= TFD_QUEUE_SIZE_MAX); - if (txq_id != trans->shrd->cmd_queue) + if (txq_id != trans_pcie->cmd_queue) sta_id = tx_cmd->sta_id; bc_ent = cpu_to_le16(1 | (sta_id << 12)); @@ -664,7 +664,7 @@ int iwl_trans_pcie_tx_agg_disable(struct iwl_trans *trans, int sta_id, int tid) static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); - struct iwl_tx_queue *txq = &trans_pcie->txq[trans->shrd->cmd_queue]; + struct iwl_tx_queue *txq = &trans_pcie->txq[trans_pcie->cmd_queue]; struct iwl_queue *q = &txq->q; struct iwl_device_cmd *out_cmd; struct iwl_cmd_meta *out_meta; @@ -737,7 +737,7 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd) out_cmd->hdr.cmd = cmd->id; out_cmd->hdr.flags = 0; out_cmd->hdr.sequence = - cpu_to_le16(QUEUE_TO_SEQ(trans->shrd->cmd_queue) | + cpu_to_le16(QUEUE_TO_SEQ(trans_pcie->cmd_queue) | INDEX_TO_SEQ(q->write_ptr)); /* and copy the data that needs to be copied */ @@ -757,7 +757,7 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd) get_cmd_string(out_cmd->hdr.cmd), out_cmd->hdr.cmd, le16_to_cpu(out_cmd->hdr.sequence), cmd_size, - q->write_ptr, idx, trans->shrd->cmd_queue); + q->write_ptr, idx, trans_pcie->cmd_queue); phys_addr = dma_map_single(trans->dev, &out_cmd->hdr, copy_size, DMA_BIDIRECTIONAL); @@ -881,16 +881,16 @@ void iwl_tx_cmd_complete(struct iwl_trans *trans, struct iwl_rx_cmd_buffer *rxb, struct iwl_device_cmd *cmd; struct iwl_cmd_meta *meta; struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); - struct iwl_tx_queue *txq = &trans_pcie->txq[trans->shrd->cmd_queue]; + struct iwl_tx_queue *txq = &trans_pcie->txq[trans_pcie->cmd_queue]; /* If a Tx command is being handled and it isn't in the actual * command queue then there a command routing bug has been introduced * in the queue management code. */ - if (WARN(txq_id != trans->shrd->cmd_queue, + if (WARN(txq_id != trans_pcie->cmd_queue, "wrong command queue %d (should be %d), sequence 0x%X readp=%d writep=%d\n", - txq_id, trans->shrd->cmd_queue, sequence, - trans_pcie->txq[trans->shrd->cmd_queue].q.read_ptr, - trans_pcie->txq[trans->shrd->cmd_queue].q.write_ptr)) { + txq_id, trans_pcie->cmd_queue, sequence, + trans_pcie->txq[trans_pcie->cmd_queue].q.read_ptr, + trans_pcie->txq[trans_pcie->cmd_queue].q.write_ptr)) { iwl_print_hex_error(trans, pkt, 32); return; } @@ -997,7 +997,7 @@ static int iwl_send_cmd_sync(struct iwl_trans *trans, struct iwl_host_cmd *cmd) if (!ret) { if (test_bit(STATUS_HCMD_ACTIVE, &trans->shrd->status)) { struct iwl_tx_queue *txq = - &trans_pcie->txq[trans->shrd->cmd_queue]; + &trans_pcie->txq[trans_pcie->cmd_queue]; struct iwl_queue *q = &txq->q; IWL_ERR(trans, @@ -1034,7 +1034,7 @@ cancel: * in later, it will possibly set an invalid * address (cmd->meta.source). */ - trans_pcie->txq[trans->shrd->cmd_queue].meta[cmd_idx].flags &= + trans_pcie->txq[trans_pcie->cmd_queue].meta[cmd_idx].flags &= ~CMD_WANT_SKB; } @@ -1065,7 +1065,7 @@ int iwl_tx_queue_reclaim(struct iwl_trans *trans, int txq_id, int index, int freed = 0; /* This function is not meant to release cmd queue*/ - if (WARN_ON(txq_id == trans->shrd->cmd_queue)) + if (WARN_ON(txq_id == trans_pcie->cmd_queue)) return 0; lockdep_assert_held(&txq->lock); diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c index 6172651d7e25..8170133d8173 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c @@ -78,6 +78,10 @@ #define IWL_MASK(lo, hi) ((1 << (hi)) | ((1 << (hi)) - (1 << (lo)))) +#define SCD_QUEUECHAIN_SEL_ALL(trans, trans_pcie) \ + (((1<base_params->num_of_queues) - 1) &\ + (~(1<<(trans_pcie)->cmd_queue))) + static int iwl_trans_rx_alloc(struct iwl_trans *trans) { struct iwl_trans_pcie *trans_pcie = @@ -301,6 +305,7 @@ static int iwl_trans_txq_alloc(struct iwl_trans *trans, { size_t tfd_sz = sizeof(struct iwl_tfd) * TFD_QUEUE_SIZE_MAX; int i; + struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); if (WARN_ON(txq->meta || txq->cmd || txq->skbs || txq->tfds)) return -EINVAL; @@ -313,7 +318,7 @@ static int iwl_trans_txq_alloc(struct iwl_trans *trans, if (!txq->meta || !txq->cmd) goto error; - if (txq_id == trans->shrd->cmd_queue) + if (txq_id == trans_pcie->cmd_queue) for (i = 0; i < slots_num; i++) { txq->cmd[i] = kmalloc(sizeof(struct iwl_device_cmd), GFP_KERNEL); @@ -324,7 +329,7 @@ static int iwl_trans_txq_alloc(struct iwl_trans *trans, /* Alloc driver data array and TFD circular buffer */ /* Driver private data, only for Tx (not command) queues, * not shared with device. */ - if (txq_id != trans->shrd->cmd_queue) { + if (txq_id != trans_pcie->cmd_queue) { txq->skbs = kcalloc(TFD_QUEUE_SIZE_MAX, sizeof(txq->skbs[0]), GFP_KERNEL); if (!txq->skbs) { @@ -352,7 +357,7 @@ error: txq->skbs = NULL; /* since txq->cmd has been zeroed, * all non allocated cmd[i] will be NULL */ - if (txq->cmd && txq_id == trans->shrd->cmd_queue) + if (txq->cmd && txq_id == trans_pcie->cmd_queue) for (i = 0; i < slots_num; i++) kfree(txq->cmd[i]); kfree(txq->meta); @@ -418,7 +423,7 @@ static void iwl_tx_queue_unmap(struct iwl_trans *trans, int txq_id) /* In the command queue, all the TBs are mapped as BIDI * so unmap them as such. */ - if (txq_id == trans->shrd->cmd_queue) + if (txq_id == trans_pcie->cmd_queue) dma_dir = DMA_BIDIRECTIONAL; else dma_dir = DMA_TO_DEVICE; @@ -454,7 +459,7 @@ static void iwl_tx_queue_free(struct iwl_trans *trans, int txq_id) /* De-alloc array of command/tx buffers */ - if (txq_id == trans->shrd->cmd_queue) + if (txq_id == trans_pcie->cmd_queue) for (i = 0; i < txq->q.n_window; i++) kfree(txq->cmd[i]); @@ -551,7 +556,7 @@ static int iwl_trans_tx_alloc(struct iwl_trans *trans) /* Alloc and init all Tx queues, including the command queue (#4/#9) */ for (txq_id = 0; txq_id < hw_params(trans).max_txq_num; txq_id++) { - slots_num = (txq_id == trans->shrd->cmd_queue) ? + slots_num = (txq_id == trans->cmd_queue) ? TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS; ret = iwl_trans_txq_alloc(trans, &trans_pcie->txq[txq_id], slots_num, txq_id); @@ -596,7 +601,7 @@ static int iwl_tx_init(struct iwl_trans *trans) /* Alloc and init all Tx queues, including the command queue (#4/#9) */ for (txq_id = 0; txq_id < hw_params(trans).max_txq_num; txq_id++) { - slots_num = (txq_id == trans->shrd->cmd_queue) ? + slots_num = (txq_id == trans->cmd_queue) ? TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS; ret = iwl_trans_txq_init(trans, &trans_pcie->txq[txq_id], slots_num, txq_id); @@ -1130,7 +1135,7 @@ static void iwl_tx_start(struct iwl_trans *trans) reg_val | FH_TX_CHICKEN_BITS_SCD_AUTO_RETRY_EN); iwl_write_prph(trans, SCD_QUEUECHAIN_SEL, - SCD_QUEUECHAIN_SEL_ALL(trans)); + SCD_QUEUECHAIN_SEL_ALL(trans, trans_pcie)); iwl_write_prph(trans, SCD_AGGR_SEL, 0); /* initiate the queues */ @@ -1162,7 +1167,7 @@ static void iwl_tx_start(struct iwl_trans *trans) else queue_to_fifo = iwlagn_default_queue_to_tx_fifo; - iwl_trans_set_wr_ptrs(trans, trans->shrd->cmd_queue, 0); + iwl_trans_set_wr_ptrs(trans, trans_pcie->cmd_queue, 0); /* make sure all queue are not stopped */ memset(&trans_pcie->queue_stopped[0], 0, @@ -1613,6 +1618,14 @@ static u32 iwl_trans_pcie_read32(struct iwl_trans *trans, u32 ofs) return readl(IWL_TRANS_GET_PCIE_TRANS(trans)->hw_base + ofs); } +static void iwl_trans_pcie_configure(struct iwl_trans *trans, + const struct iwl_trans_config *trans_cfg) +{ + struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); + + trans_pcie->cmd_queue = trans_cfg->cmd_queue; +} + static void iwl_trans_pcie_free(struct iwl_trans *trans) { struct iwl_trans_pcie *trans_pcie = @@ -1673,7 +1686,7 @@ static int iwl_trans_pcie_wait_tx_queue_empty(struct iwl_trans *trans) /* waiting for all the tx frames complete might take a while */ for (cnt = 0; cnt < hw_params(trans).max_txq_num; cnt++) { - if (cnt == trans->shrd->cmd_queue) + if (cnt == trans->cmd_queue) continue; txq = &trans_pcie->txq[cnt]; q = &txq->q; @@ -2202,6 +2215,7 @@ const struct iwl_trans_ops trans_ops_pcie = { .write8 = iwl_trans_pcie_write8, .write32 = iwl_trans_pcie_write32, .read32 = iwl_trans_pcie_read32, + .configure = iwl_trans_pcie_configure, }; struct iwl_trans *iwl_trans_pcie_alloc(struct iwl_shared *shrd, diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index b6fd42779624..a40c2726c190 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h @@ -279,9 +279,12 @@ static inline struct page *rxb_steal_page(struct iwl_rx_cmd_buffer *r) * * @op_mode: pointer to the upper layer. * Must be set before any other call. + * @cmd_queue: the index of the command queue. + * Must be set before start_fw. */ struct iwl_trans_config { struct iwl_op_mode *op_mode; + u8 cmd_queue; }; /** @@ -331,6 +334,8 @@ struct iwl_trans_config { * @write8: write a u8 to a register at offset ofs from the BAR * @write32: write a u32 to a register at offset ofs from the BAR * @read32: read a u32 register at offset ofs from the BAR + * @configure: configure parameters required by the transport layer from + * the op_mode. */ struct iwl_trans_ops { @@ -370,6 +375,8 @@ struct iwl_trans_ops { void (*write8)(struct iwl_trans *trans, u32 ofs, u8 val); void (*write32)(struct iwl_trans *trans, u32 ofs, u32 val); u32 (*read32)(struct iwl_trans *trans, u32 ofs); + void (*configure)(struct iwl_trans *trans, + const struct iwl_trans_config *trans_cfg); }; /** @@ -425,6 +432,8 @@ static inline void iwl_trans_configure(struct iwl_trans *trans, * more */ trans->op_mode = trans_cfg->op_mode; + + trans->ops->configure(trans, trans_cfg); } static inline int iwl_trans_start_hw(struct iwl_trans *trans) -- cgit From 3dc420be8ce72688bd333afdab6d911e3ceb94e7 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Wed, 7 Mar 2012 09:52:41 -0800 Subject: iwlwifi: restore PAN support in iwlwifi: move setting up fw parameters Meenakshi moved code up to configure the transport layer, but this code read the sku before it was set (from the EEPROM). This killed P2P. Only the ucode_flags are needed to configure the transport layer, not the sku which _must_ be set after the EEPROM is read. We need to reconfigure the transport in case the EEPROM disabled PAN support. This is not the nicest thing to do, but we have no choice. Document that we are allowed to configure the transport several times before start_fw, but not after. Signed-off-by: Emmanuel Grumbach Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn.c | 59 ++++++++++++++++---------------- drivers/net/wireless/iwlwifi/iwl-trans.h | 3 +- 2 files changed, 32 insertions(+), 30 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 1e6b5e41a72b..28422c03d673 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -1206,35 +1206,17 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans, /* TODO: remove fw from shared data later */ priv->shrd->fw = fw; - /************************ - * 2. Setup HW constants - ************************/ - iwl_set_hw_params(priv); + /* + * Populate the state variables that the transport layer needs + * to know about. + */ + trans_cfg.op_mode = op_mode; ucode_flags = fw->ucode_capa.flags; #ifndef CONFIG_IWLWIFI_P2P ucode_flags &= ~IWL_UCODE_TLV_FLAGS_PAN; #endif - if (!(hw_params(priv).sku & EEPROM_SKU_CAP_IPAN_ENABLE)) - ucode_flags &= ~IWL_UCODE_TLV_FLAGS_PAN; - - /* - * if not PAN, then don't support P2P -- might be a uCode - * packaging bug or due to the eeprom check above - */ - if (!(ucode_flags & IWL_UCODE_TLV_FLAGS_PAN)) - ucode_flags &= ~IWL_UCODE_TLV_FLAGS_P2P; - - - /***************************** - * Configure transport layer - *****************************/ - /* - * Populate the state variables that the transport layer needs - * to know about. - */ - trans_cfg.op_mode = op_mode; if (ucode_flags & IWL_UCODE_TLV_FLAGS_PAN) { priv->sta_key_max_num = STA_KEY_MAX_NUM_PAN; @@ -1277,7 +1259,7 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans, spin_lock_init(&priv->statistics.lock); /*********************** - * 3. Read REV register + * 2. Read REV register ***********************/ IWL_INFO(priv, "Detected %s, REV=0x%X\n", cfg(priv)->name, trans(priv)->hw_rev); @@ -1287,9 +1269,8 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans, goto out_free_traffic_mem; /***************** - * 4. Read EEPROM + * 3. Read EEPROM *****************/ - /* Read the EEPROM */ err = iwl_eeprom_init(trans(priv), trans(priv)->hw_rev); /* Reset chip to save power until we load uCode during "up". */ iwl_trans_stop_hw(trans(priv)); @@ -1318,8 +1299,28 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans, priv->hw->wiphy->n_addresses++; } + /************************ + * 4. Setup HW constants + ************************/ + iwl_set_hw_params(priv); + + if (!(hw_params(priv).sku & EEPROM_SKU_CAP_IPAN_ENABLE)) { + IWL_DEBUG_INFO(priv, "Your EEPROM disabled PAN"); + ucode_flags &= ~IWL_UCODE_TLV_FLAGS_PAN; + /* + * if not PAN, then don't support P2P -- might be a uCode + * packaging bug or due to the eeprom check above + */ + ucode_flags &= ~IWL_UCODE_TLV_FLAGS_P2P; + priv->sta_key_max_num = STA_KEY_MAX_NUM; + trans_cfg.cmd_queue = IWL_DEFAULT_CMD_QUEUE_NUM; + + /* Configure transport layer again*/ + iwl_trans_configure(trans(priv), &trans_cfg); + } + /******************* - * 6. Setup priv + * 5. Setup priv *******************/ err = iwl_init_drv(priv); @@ -1328,7 +1329,7 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans, /* At this point both hw and priv are initialized. */ /******************** - * 7. Setup services + * 6. Setup services ********************/ iwl_setup_deferred_work(priv); iwl_setup_rx_handlers(priv); @@ -1355,7 +1356,7 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans, /************************************************** * This is still part of probe() in a sense... * - * 9. Setup and register with mac80211 and debugfs + * 7. Setup and register with mac80211 and debugfs **************************************************/ err = iwlagn_mac_setup_register(priv, &fw->ucode_capa); if (err) diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index a40c2726c190..7d1990c7f658 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h @@ -335,7 +335,8 @@ struct iwl_trans_config { * @write32: write a u32 to a register at offset ofs from the BAR * @read32: read a u32 register at offset ofs from the BAR * @configure: configure parameters required by the transport layer from - * the op_mode. + * the op_mode. May be called several times before start_fw, can't be + * called after that. */ struct iwl_trans_ops { -- cgit From 9ba1947a89938ee83e7c16709ee4095ae3e36c44 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Fri, 9 Mar 2012 10:12:42 -0800 Subject: iwlwifi: fix cmd_queue number merge iwlwifi: move command queue number out of the iwl_shared struct move the cmd_queue out of iwl_shared struct, but for some reason the patch is half done and fail compile Here is the fix John, could you apply this patch to wireless-next to address the issue Thanks Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-prph.h | 4 ---- drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | 6 +++--- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-prph.h b/drivers/net/wireless/iwlwifi/iwl-prph.h index a4d11016c3b4..75dc20bd965b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-prph.h +++ b/drivers/net/wireless/iwlwifi/iwl-prph.h @@ -216,10 +216,6 @@ #define SCD_TRANS_TBL_OFFSET_QUEUE(x) \ ((SCD_TRANS_TBL_MEM_LOWER_BOUND + ((x) * 2)) & 0xfffc) -#define SCD_QUEUECHAIN_SEL_ALL(priv) \ - (((1<shrd->cmd_queue))) - #define SCD_BASE (PRPH_BASE + 0xa02c00) #define SCD_SRAM_BASE_ADDR (SCD_BASE + 0x0) diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c index 8170133d8173..a3ac6d814637 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c @@ -556,7 +556,7 @@ static int iwl_trans_tx_alloc(struct iwl_trans *trans) /* Alloc and init all Tx queues, including the command queue (#4/#9) */ for (txq_id = 0; txq_id < hw_params(trans).max_txq_num; txq_id++) { - slots_num = (txq_id == trans->cmd_queue) ? + slots_num = (txq_id == trans_pcie->cmd_queue) ? TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS; ret = iwl_trans_txq_alloc(trans, &trans_pcie->txq[txq_id], slots_num, txq_id); @@ -601,7 +601,7 @@ static int iwl_tx_init(struct iwl_trans *trans) /* Alloc and init all Tx queues, including the command queue (#4/#9) */ for (txq_id = 0; txq_id < hw_params(trans).max_txq_num; txq_id++) { - slots_num = (txq_id == trans->cmd_queue) ? + slots_num = (txq_id == trans_pcie->cmd_queue) ? TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS; ret = iwl_trans_txq_init(trans, &trans_pcie->txq[txq_id], slots_num, txq_id); @@ -1686,7 +1686,7 @@ static int iwl_trans_pcie_wait_tx_queue_empty(struct iwl_trans *trans) /* waiting for all the tx frames complete might take a while */ for (cnt = 0; cnt < hw_params(trans).max_txq_num; cnt++) { - if (cnt == trans->cmd_queue) + if (cnt == trans_pcie->cmd_queue) continue; txq = &trans_pcie->txq[cnt]; q = &txq->q; -- cgit From 1745e4405b2c0da6db2ec4b6bc0ad930612d8295 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Fri, 9 Mar 2012 11:13:40 -0800 Subject: iwlwifi: fix the delta for remove max_txq_num patch BIg portion of "iwlwifi: remove max_txq_num from hw_params" was missing during merge, here is the fix for it. Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-1000.c | 2 -- drivers/net/wireless/iwlwifi/iwl-2000.c | 2 -- drivers/net/wireless/iwlwifi/iwl-5000.c | 4 ---- drivers/net/wireless/iwlwifi/iwl-6000.c | 2 -- drivers/net/wireless/iwlwifi/iwl-agn-tx.c | 2 +- drivers/net/wireless/iwlwifi/iwl-debugfs.c | 2 +- drivers/net/wireless/iwlwifi/iwl-shared.h | 2 -- drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c | 2 +- drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c | 3 ++- drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | 30 ++++++++++++++---------- 10 files changed, 23 insertions(+), 28 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index 450250332e4b..5b0d888f746b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c @@ -122,8 +122,6 @@ static const struct iwl_sensitivity_ranges iwl1000_sensitivity = { static void iwl1000_hw_set_hw_params(struct iwl_priv *priv) { - hw_params(priv).max_txq_num = cfg(priv)->base_params->num_of_queues; - hw_params(priv).ht40_channel = BIT(IEEE80211_BAND_2GHZ); hw_params(priv).tx_chains_num = diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c index abfd901e81a2..5635b9e2c69e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-2000.c +++ b/drivers/net/wireless/iwlwifi/iwl-2000.c @@ -117,8 +117,6 @@ static const struct iwl_sensitivity_ranges iwl2000_sensitivity = { static void iwl2000_hw_set_hw_params(struct iwl_priv *priv) { - hw_params(priv).max_txq_num = cfg(priv)->base_params->num_of_queues; - hw_params(priv).ht40_channel = BIT(IEEE80211_BAND_2GHZ); hw_params(priv).tx_chains_num = diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index 9e187f8f5ae4..a805e97b89af 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -156,8 +156,6 @@ static void iwl5000_set_ct_threshold(struct iwl_priv *priv) static void iwl5000_hw_set_hw_params(struct iwl_priv *priv) { - hw_params(priv).max_txq_num = cfg(priv)->base_params->num_of_queues; - hw_params(priv).ht40_channel = BIT(IEEE80211_BAND_2GHZ) | BIT(IEEE80211_BAND_5GHZ); @@ -174,8 +172,6 @@ static void iwl5000_hw_set_hw_params(struct iwl_priv *priv) static void iwl5150_hw_set_hw_params(struct iwl_priv *priv) { - hw_params(priv).max_txq_num = cfg(priv)->base_params->num_of_queues; - hw_params(priv).ht40_channel = BIT(IEEE80211_BAND_2GHZ) | BIT(IEEE80211_BAND_5GHZ); diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index e64bc6b7bcbf..64060cd738b5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -139,8 +139,6 @@ static const struct iwl_sensitivity_ranges iwl6000_sensitivity = { static void iwl6000_hw_set_hw_params(struct iwl_priv *priv) { - hw_params(priv).max_txq_num = cfg(priv)->base_params->num_of_queues; - hw_params(priv).ht40_channel = BIT(IEEE80211_BAND_2GHZ) | BIT(IEEE80211_BAND_5GHZ); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c index 9f224548b636..34adedc74d35 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c @@ -1159,7 +1159,7 @@ int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv, * (in Tx queue's circular buffer) of first TFD/frame in window */ u16 ba_resp_scd_ssn = le16_to_cpu(ba_resp->scd_ssn); - if (scd_flow >= hw_params(priv).max_txq_num) { + if (scd_flow >= cfg(priv)->base_params->num_of_queues) { IWL_ERR(priv, "BUG_ON scd_flow is bigger than number of queues\n"); return 0; diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index 7a1334e8c358..9b71c87847c2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c @@ -828,7 +828,7 @@ static ssize_t iwl_dbgfs_traffic_log_read(struct file *file, char *buf; int bufsz = ((IWL_TRAFFIC_ENTRIES * IWL_TRAFFIC_ENTRY_SIZE * 64) * 2) + - (hw_params(priv).max_txq_num * 32 * 8) + 400; + (cfg(priv)->base_params->num_of_queues * 32 * 8) + 400; const u8 *ptr; ssize_t ret; diff --git a/drivers/net/wireless/iwlwifi/iwl-shared.h b/drivers/net/wireless/iwlwifi/iwl-shared.h index 0d957ca3d6c6..cf34087aa2fe 100644 --- a/drivers/net/wireless/iwlwifi/iwl-shared.h +++ b/drivers/net/wireless/iwlwifi/iwl-shared.h @@ -160,7 +160,6 @@ struct iwl_mod_params { * * Holds the module parameters * - * @max_txq_num: Max # Tx queues supported * @num_ampdu_queues: num of ampdu queues * @tx_chains_num: Number of TX chains * @rx_chains_num: Number of RX chains @@ -177,7 +176,6 @@ struct iwl_mod_params { * @use_rts_for_aggregation: use rts/cts protection for HT traffic */ struct iwl_hw_params { - u8 max_txq_num; u8 num_ampdu_queues; u8 tx_chains_num; u8 rx_chains_num; diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c index a5547a155b95..9bc3c73af5e9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c @@ -1050,7 +1050,7 @@ void iwl_irq_tasklet(struct iwl_trans *trans) if (inta & CSR_INT_BIT_WAKEUP) { IWL_DEBUG_ISR(trans, "Wakeup interrupt\n"); iwl_rx_queue_update_write_ptr(trans, &trans_pcie->rxq); - for (i = 0; i < hw_params(trans).max_txq_num; i++) + for (i = 0; i < cfg(trans)->base_params->num_of_queues; i++) iwl_txq_update_write_ptr(trans, &trans_pcie->txq[i]); diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c index 2b1df0092aee..565c664f6dce 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c @@ -595,7 +595,8 @@ static int iwlagn_txq_ctx_activate_free(struct iwl_trans *trans) struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); int txq_id; - for (txq_id = 0; txq_id < hw_params(trans).max_txq_num; txq_id++) + for (txq_id = 0; txq_id < cfg(trans)->base_params->num_of_queues; + txq_id++) if (!test_and_set_bit(txq_id, &trans_pcie->txq_ctx_active_msk)) return txq_id; diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c index a3ac6d814637..91628565409f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c @@ -497,7 +497,7 @@ static void iwl_trans_pcie_tx_free(struct iwl_trans *trans) /* Tx queues */ if (trans_pcie->txq) { for (txq_id = 0; - txq_id < hw_params(trans).max_txq_num; txq_id++) + txq_id < cfg(trans)->base_params->num_of_queues; txq_id++) iwl_tx_queue_free(trans, txq_id); } @@ -522,7 +522,7 @@ static int iwl_trans_tx_alloc(struct iwl_trans *trans) int txq_id, slots_num; struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); - u16 scd_bc_tbls_size = hw_params(trans).max_txq_num * + u16 scd_bc_tbls_size = cfg(trans)->base_params->num_of_queues * sizeof(struct iwlagn_scd_bc_tbl); /*It is not allowed to alloc twice, so warn when this happens. @@ -546,7 +546,7 @@ static int iwl_trans_tx_alloc(struct iwl_trans *trans) goto error; } - trans_pcie->txq = kcalloc(hw_params(trans).max_txq_num, + trans_pcie->txq = kcalloc(cfg(trans)->base_params->num_of_queues, sizeof(struct iwl_tx_queue), GFP_KERNEL); if (!trans_pcie->txq) { IWL_ERR(trans, "Not enough memory for txq\n"); @@ -555,7 +555,8 @@ static int iwl_trans_tx_alloc(struct iwl_trans *trans) } /* Alloc and init all Tx queues, including the command queue (#4/#9) */ - for (txq_id = 0; txq_id < hw_params(trans).max_txq_num; txq_id++) { + for (txq_id = 0; txq_id < cfg(trans)->base_params->num_of_queues; + txq_id++) { slots_num = (txq_id == trans_pcie->cmd_queue) ? TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS; ret = iwl_trans_txq_alloc(trans, &trans_pcie->txq[txq_id], @@ -600,7 +601,8 @@ static int iwl_tx_init(struct iwl_trans *trans) spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); /* Alloc and init all Tx queues, including the command queue (#4/#9) */ - for (txq_id = 0; txq_id < hw_params(trans).max_txq_num; txq_id++) { + for (txq_id = 0; txq_id < cfg(trans)->base_params->num_of_queues; + txq_id++) { slots_num = (txq_id == trans_pcie->cmd_queue) ? TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS; ret = iwl_trans_txq_init(trans, &trans_pcie->txq[txq_id], @@ -1116,7 +1118,8 @@ static void iwl_tx_start(struct iwl_trans *trans) a += 4) iwl_write_targ_mem(trans, a, 0); for (; a < trans_pcie->scd_base_addr + - SCD_TRANS_TBL_OFFSET_QUEUE(hw_params(trans).max_txq_num); + SCD_TRANS_TBL_OFFSET_QUEUE( + cfg(trans)->base_params->num_of_queues); a += 4) iwl_write_targ_mem(trans, a, 0); @@ -1139,7 +1142,7 @@ static void iwl_tx_start(struct iwl_trans *trans) iwl_write_prph(trans, SCD_AGGR_SEL, 0); /* initiate the queues */ - for (i = 0; i < hw_params(trans).max_txq_num; i++) { + for (i = 0; i < cfg(trans)->base_params->num_of_queues; i++) { iwl_write_prph(trans, SCD_QUEUE_RDPTR(i), 0); iwl_write_direct32(trans, HBUS_TARG_WRPTR, 0 | (i << 8)); iwl_write_targ_mem(trans, trans_pcie->scd_base_addr + @@ -1156,7 +1159,7 @@ static void iwl_tx_start(struct iwl_trans *trans) } iwl_write_prph(trans, SCD_INTERRUPT_MASK, - IWL_MASK(0, hw_params(trans).max_txq_num)); + IWL_MASK(0, cfg(trans)->base_params->num_of_queues)); /* Activate all Tx DMA/FIFO channels */ iwl_trans_txq_set_sched(trans, IWL_MASK(0, 7)); @@ -1246,7 +1249,8 @@ static int iwl_trans_tx_stop(struct iwl_trans *trans) } /* Unmap DMA from host system and free skb's */ - for (txq_id = 0; txq_id < hw_params(trans).max_txq_num; txq_id++) + for (txq_id = 0; txq_id < cfg(trans)->base_params->num_of_queues; + txq_id++) iwl_tx_queue_unmap(trans, txq_id); return 0; @@ -1685,7 +1689,7 @@ static int iwl_trans_pcie_wait_tx_queue_empty(struct iwl_trans *trans) int ret = 0; /* waiting for all the tx frames complete might take a while */ - for (cnt = 0; cnt < hw_params(trans).max_txq_num; cnt++) { + for (cnt = 0; cnt < cfg(trans)->base_params->num_of_queues; cnt++) { if (cnt == trans_pcie->cmd_queue) continue; txq = &trans_pcie->txq[cnt]; @@ -1931,7 +1935,9 @@ static ssize_t iwl_dbgfs_tx_queue_read(struct file *file, int pos = 0; int cnt; int ret; - const size_t bufsz = sizeof(char) * 64 * hw_params(trans).max_txq_num; + size_t bufsz; + + bufsz = sizeof(char) * 64 * cfg(trans)->base_params->num_of_queues; if (!trans_pcie->txq) { IWL_ERR(trans, "txq not ready\n"); @@ -1941,7 +1947,7 @@ static ssize_t iwl_dbgfs_tx_queue_read(struct file *file, if (!buf) return -ENOMEM; - for (cnt = 0; cnt < hw_params(trans).max_txq_num; cnt++) { + for (cnt = 0; cnt < cfg(trans)->base_params->num_of_queues; cnt++) { txq = &trans_pcie->txq[cnt]; q = &txq->q; pos += scnprintf(buf + pos, bufsz - pos, -- cgit From bff2ec2b916cc85628f3025e08660c0350f03650 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Mon, 12 Mar 2012 07:51:07 +0530 Subject: ath9k: Fix BTCOEX shutdown Flush MCI profiles only if MCI is being actually used. This fixes a panic on driver unload when non-MCI devices are being used and btcoex_enable is set. BUG: unable to handle kernel NULL pointer dereference at (null) IP: [] ath_mci_flush_profile+0x12/0x100 [ath9k] Call Trace: [] ath9k_stop_btcoex+0x5e/0x80 [ath9k] [] ath9k_stop+0xb7/0x230 [ath9k] [] ieee80211_stop_device+0x50/0x180 [mac80211] [] ieee80211_do_stop+0x2af/0x6a0 [mac80211] [] ieee80211_stop+0x1a/0x20 [mac80211] [] __dev_close_many+0x86/0xe0 [] dev_close_many+0xa0/0x110 [] rollback_registered_many+0xe8/0x260 [] unregister_netdevice_many+0x1b/0x80 [] ieee80211_remove_interfaces+0xd0/0x110 [mac80211] [] ieee80211_unregister_hw+0x53/0x120 [mac80211] [] ath9k_deinit_device+0x44/0x70 [ath9k] [] ath_pci_remove+0x54/0xa0 [ath9k] [] pci_device_remove+0x46/0x110 [] __device_release_driver+0x7c/0xe0 [] driver_detach+0xd0/0xe0 [] bus_remove_driver+0x88/0xe0 [] driver_unregister+0x62/0xa0 [] pci_unregister_driver+0x44/0xc0 [] ath_pci_exit+0x15/0x20 [ath9k] [] ath9k_exit+0x15/0x31 [ath9k] [] sys_delete_module+0x18c/0x270 [] ? retint_swapgs+0x13/0x1b [] ? trace_hardirqs_on_thunk+0x3a/0x3f [] system_call_fastpath+0x16/0x1b Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/gpio.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/gpio.c b/drivers/net/wireless/ath/ath9k/gpio.c index 63e4c4b1cb3d..fbe23de1297f 100644 --- a/drivers/net/wireless/ath/ath9k/gpio.c +++ b/drivers/net/wireless/ath/ath9k/gpio.c @@ -362,7 +362,8 @@ void ath9k_stop_btcoex(struct ath_softc *sc) ath9k_hw_btcoex_disable(ah); if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_3WIRE) ath9k_btcoex_timer_pause(sc); - ath_mci_flush_profile(&sc->btcoex.mci); + if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_MCI) + ath_mci_flush_profile(&sc->btcoex.mci); } } -- cgit From 4486ea987efdaa546bdda569e3dfacdc14a9fb13 Mon Sep 17 00:00:00 2001 From: Bala Shanmugam Date: Wed, 7 Mar 2012 17:27:12 +0530 Subject: cfg80211: Add background scan period attribute. Receive background scan period as part of connect command and pass the same to the driver. Signed-off-by: Bala Shanmugam Signed-off-by: John W. Linville --- include/linux/nl80211.h | 10 ++++++++++ include/net/cfg80211.h | 3 +++ net/wireless/nl80211.c | 8 ++++++++ net/wireless/wext-sme.c | 3 +++ 4 files changed, 24 insertions(+) diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h index c37d67add090..e474f6e780cc 100644 --- a/include/linux/nl80211.h +++ b/include/linux/nl80211.h @@ -369,6 +369,11 @@ * %NL80211_ATTR_WIPHY_FREQ, %NL80211_ATTR_CONTROL_PORT, * %NL80211_ATTR_CONTROL_PORT_ETHERTYPE and * %NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT. + * Background scan period can optionally be + * specified in %NL80211_ATTR_BG_SCAN_PERIOD, + * if not specified default background scan configuration + * in driver is used and if period value is 0, bg scan will be disabled. + * This attribute is ignored if driver does not support roam scan. * It is also sent as an event, with the BSSID and response IEs when the * connection is established or failed to be established. This can be * determined by the STATUS_CODE attribute. @@ -1207,6 +1212,9 @@ enum nl80211_commands { * this attribute is (depending on the driver capabilities) added to * received frames indicated with %NL80211_CMD_FRAME. * + * @NL80211_ATTR_BG_SCAN_PERIOD: Background scan period in seconds + * or 0 to disable background scan. + * * @NL80211_ATTR_MAX: highest attribute number currently defined * @__NL80211_ATTR_AFTER_LAST: internal use */ @@ -1456,6 +1464,8 @@ enum nl80211_attrs { NL80211_ATTR_RX_SIGNAL_DBM, + NL80211_ATTR_BG_SCAN_PERIOD, + /* add attributes here, update the policy in nl80211.c */ __NL80211_ATTR_AFTER_LAST, diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 57c9fddc2acf..66f460325e24 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -1203,6 +1203,8 @@ struct cfg80211_ibss_params { * @key_idx: index of WEP key for shared key authentication * @key: WEP key for shared key authentication * @flags: See &enum cfg80211_assoc_req_flags + * @bg_scan_period: Background scan period in seconds + * or -1 to indicate that default value is to be used. * @ht_capa: HT Capabilities over-rides. Values set in ht_capa_mask * will be used in ht_capa. Un-supported values will be ignored. * @ht_capa_mask: The bits of ht_capa which are to be used. @@ -1220,6 +1222,7 @@ struct cfg80211_connect_params { const u8 *key; u8 key_len, key_idx; u32 flags; + int bg_scan_period; struct ieee80211_ht_cap ht_capa; struct ieee80211_ht_cap ht_capa_mask; }; diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 39dbdf2adb12..4c1eb9472ddb 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -205,6 +205,7 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = { }, [NL80211_ATTR_NOACK_MAP] = { .type = NLA_U16 }, [NL80211_ATTR_INACTIVITY_TIMEOUT] = { .type = NLA_U16 }, + [NL80211_ATTR_BG_SCAN_PERIOD] = { .type = NLA_U16 }, }; /* policy for the key attributes */ @@ -5116,6 +5117,13 @@ static int nl80211_connect(struct sk_buff *skb, struct genl_info *info) wiphy = &rdev->wiphy; + connect.bg_scan_period = -1; + if (info->attrs[NL80211_ATTR_BG_SCAN_PERIOD] && + (wiphy->flags & WIPHY_FLAG_SUPPORTS_FW_ROAM)) { + connect.bg_scan_period = + nla_get_u16(info->attrs[NL80211_ATTR_BG_SCAN_PERIOD]); + } + if (info->attrs[NL80211_ATTR_MAC]) connect.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]); connect.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]); diff --git a/net/wireless/wext-sme.c b/net/wireless/wext-sme.c index 326750b99151..7c01c2f3b6cf 100644 --- a/net/wireless/wext-sme.c +++ b/net/wireless/wext-sme.c @@ -30,6 +30,9 @@ int cfg80211_mgd_wext_connect(struct cfg80211_registered_device *rdev, wdev->wext.connect.ie = wdev->wext.ie; wdev->wext.connect.ie_len = wdev->wext.ie_len; + /* Use default background scan period */ + wdev->wext.connect.bg_scan_period = -1; + if (wdev->wext.keys) { wdev->wext.keys->def = wdev->wext.default_key; wdev->wext.keys->defmgmt = wdev->wext.default_mgmt_key; -- cgit From aa4545806025c63ec12cfe17528de16dca36b785 Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Wed, 7 Mar 2012 17:20:30 +0100 Subject: mac80211: Limit TID buffering during BA session setup/teardown While setting up or tearing down a BA session mac80211 is buffering pending frames for the according TID. However, there's currently no limit on how many frames are buffered possibly leading to an out-of- memory situation. This can happen on systems with little memory when the CPU is fully loaded since the BA session work is executed in process context while frames can still come via softirq. Apply a limitation to the TIDs pending queue to avoid consuming too much memory in this situation. Signed-off-by: Helmut Schaa Signed-off-by: John W. Linville --- net/mac80211/tx.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 570737df2d22..d9e791d2b543 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -1065,6 +1065,7 @@ static bool ieee80211_tx_prep_agg(struct ieee80211_tx_data *tx, { bool queued = false; bool reset_agg_timer = false; + struct sk_buff *purge_skb = NULL; if (test_bit(HT_AGG_STATE_OPERATIONAL, &tid_tx->state)) { info->flags |= IEEE80211_TX_CTL_AMPDU; @@ -1106,8 +1107,13 @@ static bool ieee80211_tx_prep_agg(struct ieee80211_tx_data *tx, info->control.vif = &tx->sdata->vif; info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING; __skb_queue_tail(&tid_tx->pending, skb); + if (skb_queue_len(&tid_tx->pending) > STA_MAX_TX_BUFFER) + purge_skb = __skb_dequeue(&tid_tx->pending); } spin_unlock(&tx->sta->lock); + + if (purge_skb) + dev_kfree_skb(purge_skb); } /* reset session timer */ -- cgit From 4e13f092f755df5ed8169c8d8bfb952dc057e1aa Mon Sep 17 00:00:00 2001 From: Ashok Nagarajan Date: Thu, 8 Mar 2012 09:27:34 -0800 Subject: mac80211_hwsim: Fix set mactime on receiver hwsim radio The patch "mac80211_hwsim: Add tsf to beacons, probe responses and radiotap header" was setting the mactime on wrong hwsim radio. This patch fixes it. Signed-off-by: Ashok Nagarajan Signed-off-by: Javier Cardona Signed-off-by: John W. Linville --- drivers/net/wireless/mac80211_hwsim.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index b4f6cb3298a4..b7ce6a6e355f 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c @@ -639,7 +639,6 @@ static bool mac80211_hwsim_tx_frame_no_nl(struct ieee80211_hw *hw, } memset(&rx_status, 0, sizeof(rx_status)); - rx_status.mactime = le64_to_cpu(__mac80211_hwsim_get_tsf(data)); rx_status.flag |= RX_FLAG_MACTIME_MPDU; rx_status.freq = data->channel->center_freq; rx_status.band = data->channel->band; @@ -684,6 +683,8 @@ static bool mac80211_hwsim_tx_frame_no_nl(struct ieee80211_hw *hw, if (mac80211_hwsim_addr_match(data2, hdr->addr1)) ack = true; + rx_status.mactime = + le64_to_cpu(__mac80211_hwsim_get_tsf(data2)); memcpy(IEEE80211_SKB_RXCB(nskb), &rx_status, sizeof(rx_status)); ieee80211_rx_irqsafe(data2->hw, nskb); } -- cgit From 98b36a029550def4b3e76cc44d4345bf20a729bd Mon Sep 17 00:00:00 2001 From: Ben Greear Date: Thu, 8 Mar 2012 10:20:55 -0800 Subject: ath9k: Add wiphy name to log messages. On systems with multiple NICs, it's nice to know which one is producing warnings. Here is an example of the new ouput: ath: wiphy0: Failed to stop TX DMA, queues=0x005! Signed-off-by: Ben Greear Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath.h | 26 +++++++++++--------------- drivers/net/wireless/ath/main.c | 9 +++++++-- 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h index efc01110dc34..c54b7d37bff1 100644 --- a/drivers/net/wireless/ath/ath.h +++ b/drivers/net/wireless/ath/ath.h @@ -174,28 +174,24 @@ bool ath_hw_keyreset(struct ath_common *common, u16 entry); void ath_hw_cycle_counters_update(struct ath_common *common); int32_t ath_hw_get_listen_time(struct ath_common *common); -extern __printf(2, 3) void ath_printk(const char *level, const char *fmt, ...); - -#define _ath_printk(level, common, fmt, ...) \ -do { \ - __always_unused struct ath_common *unused = common; \ - ath_printk(level, fmt, ##__VA_ARGS__); \ -} while (0) +__printf(3, 4) +void ath_printk(const char *level, const struct ath_common *common, + const char *fmt, ...); #define ath_emerg(common, fmt, ...) \ - _ath_printk(KERN_EMERG, common, fmt, ##__VA_ARGS__) + ath_printk(KERN_EMERG, common, fmt, ##__VA_ARGS__) #define ath_alert(common, fmt, ...) \ - _ath_printk(KERN_ALERT, common, fmt, ##__VA_ARGS__) + ath_printk(KERN_ALERT, common, fmt, ##__VA_ARGS__) #define ath_crit(common, fmt, ...) \ - _ath_printk(KERN_CRIT, common, fmt, ##__VA_ARGS__) + ath_printk(KERN_CRIT, common, fmt, ##__VA_ARGS__) #define ath_err(common, fmt, ...) \ - _ath_printk(KERN_ERR, common, fmt, ##__VA_ARGS__) + ath_printk(KERN_ERR, common, fmt, ##__VA_ARGS__) #define ath_warn(common, fmt, ...) \ - _ath_printk(KERN_WARNING, common, fmt, ##__VA_ARGS__) + ath_printk(KERN_WARNING, common, fmt, ##__VA_ARGS__) #define ath_notice(common, fmt, ...) \ - _ath_printk(KERN_NOTICE, common, fmt, ##__VA_ARGS__) + ath_printk(KERN_NOTICE, common, fmt, ##__VA_ARGS__) #define ath_info(common, fmt, ...) \ - _ath_printk(KERN_INFO, common, fmt, ##__VA_ARGS__) + ath_printk(KERN_INFO, common, fmt, ##__VA_ARGS__) /** * enum ath_debug_level - atheros wireless debug level @@ -256,7 +252,7 @@ enum ATH_DEBUG { #define ath_dbg(common, dbg_mask, fmt, ...) \ do { \ if ((common)->debug_mask & ATH_DBG_##dbg_mask) \ - _ath_printk(KERN_DEBUG, common, fmt, ##__VA_ARGS__); \ + ath_printk(KERN_DEBUG, common, fmt, ##__VA_ARGS__); \ } while (0) #define ATH_DBG_WARN(foo, arg...) WARN(foo, arg) diff --git a/drivers/net/wireless/ath/main.c b/drivers/net/wireless/ath/main.c index d9218fe02036..ea2c737138d3 100644 --- a/drivers/net/wireless/ath/main.c +++ b/drivers/net/wireless/ath/main.c @@ -57,7 +57,8 @@ struct sk_buff *ath_rxbuf_alloc(struct ath_common *common, } EXPORT_SYMBOL(ath_rxbuf_alloc); -void ath_printk(const char *level, const char *fmt, ...) +void ath_printk(const char *level, const struct ath_common* common, + const char *fmt, ...) { struct va_format vaf; va_list args; @@ -67,7 +68,11 @@ void ath_printk(const char *level, const char *fmt, ...) vaf.fmt = fmt; vaf.va = &args; - printk("%sath: %pV", level, &vaf); + if (common && common->hw && common->hw->wiphy) + printk("%sath: %s: %pV", + level, wiphy_name(common->hw->wiphy), &vaf); + else + printk("%sath: %pV", level, &vaf); va_end(args); } -- cgit From 138f07edb6b5a905cedf5c4fe96d6b2a45d8fb30 Mon Sep 17 00:00:00 2001 From: Stanislav Yakovlev Date: Thu, 8 Mar 2012 19:06:50 -0500 Subject: net/wireless: ipw2x00: remove unused definitions for regulatory domain ipw2200 driver does not use these defines, it uses geo struct instead. Therefore remove them from its header. Note: we keep them in the ipw2100 driver's header, because the driver still uses them. Signed-off-by: Stanislav Yakovlev Signed-off-by: John W. Linville --- drivers/net/wireless/ipw2x00/ipw2200.h | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/drivers/net/wireless/ipw2x00/ipw2200.h b/drivers/net/wireless/ipw2x00/ipw2200.h index 66e84ec0eb55..570d6fb88967 100644 --- a/drivers/net/wireless/ipw2x00/ipw2200.h +++ b/drivers/net/wireless/ipw2x00/ipw2200.h @@ -1997,18 +1997,6 @@ struct ipw_cmd_log { #define CFG_SYS_ANTENNA_B 0x03 /* force antenna B */ #define CFG_SYS_ANTENNA_SLOW_DIV 0x02 /* consider background noise */ -/* - * The definitions below were lifted off the ipw2100 driver, which only - * supports 'b' mode, so I'm sure these are not exactly correct. - * - * Somebody fix these!! - */ -#define REG_MIN_CHANNEL 0 -#define REG_MAX_CHANNEL 14 - -#define REG_CHANNEL_MASK 0x00003FFF -#define IPW_IBSS_11B_DEFAULT_MASK 0x87ff - #define IPW_MAX_CONFIG_RETRIES 10 #endif /* __ipw2200_h__ */ -- cgit From 3789d59c24cb142e4590492c3b5137a7c3dec352 Mon Sep 17 00:00:00 2001 From: Mohammed Shafi Shajakhan Date: Fri, 9 Mar 2012 12:01:55 +0530 Subject: ath9k_hw: Fix enabling of MCI and RTT tested in AR9462 Rev:2, both hardware capability flag are set Signed-off-by: Mohammed Shafi Shajakhan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hw.c | 13 +++++++++++-- drivers/net/wireless/ath/ath9k/reg.h | 1 + 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index d582cf73098f..02cc1ce3dd6a 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -2390,8 +2390,17 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) if (AR_SREV_9485_OR_LATER(ah)) ah->enabled_cals |= TX_IQ_ON_AGC_CAL; } - if (AR_SREV_9462(ah)) - pCap->hw_caps |= ATH9K_HW_CAP_RTT | ATH9K_HW_CAP_MCI; + + if (AR_SREV_9462(ah)) { + + if (!(ah->ent_mode & AR_ENT_OTP_49GHZ_DISABLE)) + pCap->hw_caps |= ATH9K_HW_CAP_MCI; + + if (AR_SREV_9462_20(ah)) + pCap->hw_caps |= ATH9K_HW_CAP_RTT; + + } + return 0; } diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h index 80b1856f817d..458f81b4a7cb 100644 --- a/drivers/net/wireless/ath/ath9k/reg.h +++ b/drivers/net/wireless/ath/ath9k/reg.h @@ -1151,6 +1151,7 @@ enum { #define AR_INTR_PRIO_ASYNC_ENABLE (AR_SREV_9340(ah) ? 0x4094 : 0x40d4) #define AR_ENT_OTP 0x40d8 #define AR_ENT_OTP_CHAIN2_DISABLE 0x00020000 +#define AR_ENT_OTP_49GHZ_DISABLE 0x00100000 #define AR_ENT_OTP_MIN_PKT_SIZE_DISABLE 0x00800000 #define AR_CH0_BB_DPLL1 0x16180 -- cgit From 177958e9679c23537411066cc41b205635dacb14 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 9 Mar 2012 12:49:21 +0100 Subject: mac80211: remove tx_sync When the station state callback was added, this was no longer needed in theory. With the iwlwifi changes to remove use of it landing, we can kill the entire tx-sync framework again, RIP. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- include/net/mac80211.h | 41 ----------------------------------------- net/mac80211/driver-ops.h | 35 ----------------------------------- net/mac80211/driver-trace.h | 43 ------------------------------------------- net/mac80211/ieee80211_i.h | 1 - net/mac80211/mlme.c | 41 ----------------------------------------- 5 files changed, 161 deletions(-) diff --git a/include/net/mac80211.h b/include/net/mac80211.h index f7917f765cbc..44e4dfcb5722 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -1765,20 +1765,6 @@ enum ieee80211_ampdu_mlme_action { IEEE80211_AMPDU_TX_OPERATIONAL, }; -/** - * enum ieee80211_tx_sync_type - TX sync type - * @IEEE80211_TX_SYNC_AUTH: sync TX for authentication - * (and possibly also before direct probe) - * @IEEE80211_TX_SYNC_ASSOC: sync TX for association - * @IEEE80211_TX_SYNC_ACTION: sync TX for action frame - * (not implemented yet) - */ -enum ieee80211_tx_sync_type { - IEEE80211_TX_SYNC_AUTH, - IEEE80211_TX_SYNC_ASSOC, - IEEE80211_TX_SYNC_ACTION, -}; - /** * enum ieee80211_frame_release_type - frame release reason * @IEEE80211_FRAME_RELEASE_PSPOLL: frame released for PS-Poll @@ -1889,26 +1875,6 @@ enum ieee80211_frame_release_type { * of the bss parameters has changed when a call is made. The callback * can sleep. * - * @tx_sync: Called before a frame is sent to an AP/GO. In the GO case, the - * driver should sync with the GO's powersaving so the device doesn't - * transmit the frame while the GO is asleep. In the regular AP case - * it may be used by drivers for devices implementing other restrictions - * on talking to APs, e.g. due to regulatory enforcement or just HW - * restrictions. - * This function is called for every authentication, association and - * action frame separately since applications might attempt to auth - * with multiple APs before chosing one to associate to. If it returns - * an error, the corresponding authentication, association or frame - * transmission is aborted and reported as having failed. It is always - * called after tuning to the correct channel. - * The callback might be called multiple times before @finish_tx_sync - * (but @finish_tx_sync will be called once for each) but in practice - * this is unlikely to happen. It can also refuse in that case if the - * driver cannot handle that situation. - * This callback can sleep. - * @finish_tx_sync: Called as a counterpart to @tx_sync, unless that returned - * an error. This callback can sleep. - * * @prepare_multicast: Prepare for multicast filter configuration. * This callback is optional, and its return value is passed * to configure_filter(). This callback must be atomic. @@ -2180,13 +2146,6 @@ struct ieee80211_ops { struct ieee80211_bss_conf *info, u32 changed); - int (*tx_sync)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, - const u8 *bssid, enum ieee80211_tx_sync_type type); - void (*finish_tx_sync)(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - const u8 *bssid, - enum ieee80211_tx_sync_type type); - u64 (*prepare_multicast)(struct ieee80211_hw *hw, struct netdev_hw_addr_list *mc_list); void (*configure_filter)(struct ieee80211_hw *hw, diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h index 70dfb6415c20..af4691fed645 100644 --- a/net/mac80211/driver-ops.h +++ b/net/mac80211/driver-ops.h @@ -168,41 +168,6 @@ static inline void drv_bss_info_changed(struct ieee80211_local *local, trace_drv_return_void(local); } -static inline int drv_tx_sync(struct ieee80211_local *local, - struct ieee80211_sub_if_data *sdata, - const u8 *bssid, - enum ieee80211_tx_sync_type type) -{ - int ret = 0; - - might_sleep(); - - check_sdata_in_driver(sdata); - - trace_drv_tx_sync(local, sdata, bssid, type); - if (local->ops->tx_sync) - ret = local->ops->tx_sync(&local->hw, &sdata->vif, - bssid, type); - trace_drv_return_int(local, ret); - return ret; -} - -static inline void drv_finish_tx_sync(struct ieee80211_local *local, - struct ieee80211_sub_if_data *sdata, - const u8 *bssid, - enum ieee80211_tx_sync_type type) -{ - might_sleep(); - - check_sdata_in_driver(sdata); - - trace_drv_finish_tx_sync(local, sdata, bssid, type); - if (local->ops->finish_tx_sync) - local->ops->finish_tx_sync(&local->hw, &sdata->vif, - bssid, type); - trace_drv_return_void(local); -} - static inline u64 drv_prepare_multicast(struct ieee80211_local *local, struct netdev_hw_addr_list *mc_list) { diff --git a/net/mac80211/driver-trace.h b/net/mac80211/driver-trace.h index 384e2f08c187..7034209ad3f4 100644 --- a/net/mac80211/driver-trace.h +++ b/net/mac80211/driver-trace.h @@ -308,49 +308,6 @@ TRACE_EVENT(drv_bss_info_changed, ) ); -DECLARE_EVENT_CLASS(tx_sync_evt, - TP_PROTO(struct ieee80211_local *local, - struct ieee80211_sub_if_data *sdata, - const u8 *bssid, - enum ieee80211_tx_sync_type type), - TP_ARGS(local, sdata, bssid, type), - - TP_STRUCT__entry( - LOCAL_ENTRY - VIF_ENTRY - __array(char, bssid, ETH_ALEN) - __field(u32, sync_type) - ), - - TP_fast_assign( - LOCAL_ASSIGN; - VIF_ASSIGN; - memcpy(__entry->bssid, bssid, ETH_ALEN); - __entry->sync_type = type; - ), - - TP_printk( - LOCAL_PR_FMT VIF_PR_FMT " bssid:%pM type:%d", - LOCAL_PR_ARG, VIF_PR_ARG, __entry->bssid, __entry->sync_type - ) -); - -DEFINE_EVENT(tx_sync_evt, drv_tx_sync, - TP_PROTO(struct ieee80211_local *local, - struct ieee80211_sub_if_data *sdata, - const u8 *bssid, - enum ieee80211_tx_sync_type type), - TP_ARGS(local, sdata, bssid, type) -); - -DEFINE_EVENT(tx_sync_evt, drv_finish_tx_sync, - TP_PROTO(struct ieee80211_local *local, - struct ieee80211_sub_if_data *sdata, - const u8 *bssid, - enum ieee80211_tx_sync_type type), - TP_ARGS(local, sdata, bssid, type) -); - TRACE_EVENT(drv_prepare_multicast, TP_PROTO(struct ieee80211_local *local, int mc_count), diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 796b13bfc953..3c62ded64e32 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -388,7 +388,6 @@ struct ieee80211_mgd_auth_data { u8 key[WLAN_KEY_LEN_WEP104]; u8 key_len, key_idx; - bool synced; bool done; size_t ie_len; diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index c08924aeac00..1d09df248c56 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -1770,11 +1770,6 @@ static void ieee80211_destroy_auth_data(struct ieee80211_sub_if_data *sdata, lockdep_assert_held(&sdata->u.mgd.mtx); - if (auth_data->synced) - drv_finish_tx_sync(sdata->local, sdata, - auth_data->bss->bssid, - IEEE80211_TX_SYNC_AUTH); - if (!assoc) { sta_info_destroy_addr(sdata, auth_data->bss->bssid); @@ -1862,10 +1857,6 @@ ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata, printk(KERN_DEBUG "%s: authenticated\n", sdata->name); out: - if (ifmgd->auth_data->synced) - drv_finish_tx_sync(sdata->local, sdata, bssid, - IEEE80211_TX_SYNC_AUTH); - ifmgd->auth_data->synced = false; ifmgd->auth_data->done = true; ifmgd->auth_data->timeout = jiffies + IEEE80211_AUTH_WAIT_ASSOC; run_again(ifmgd, ifmgd->auth_data->timeout); @@ -2005,11 +1996,6 @@ static void ieee80211_destroy_assoc_data(struct ieee80211_sub_if_data *sdata, lockdep_assert_held(&sdata->u.mgd.mtx); - if (assoc_data->synced) - drv_finish_tx_sync(sdata->local, sdata, - assoc_data->bss->bssid, - IEEE80211_TX_SYNC_ASSOC); - if (!assoc) { sta_info_destroy_addr(sdata, assoc_data->bss->bssid); @@ -2255,14 +2241,6 @@ ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, } else { printk(KERN_DEBUG "%s: associated\n", sdata->name); - /* tell driver about sync done first */ - if (assoc_data->synced) { - drv_finish_tx_sync(sdata->local, sdata, - assoc_data->bss->bssid, - IEEE80211_TX_SYNC_ASSOC); - assoc_data->synced = false; - } - if (!ieee80211_assoc_success(sdata, *bss, mgmt, len)) { /* oops -- internal error -- send timeout for now */ ieee80211_destroy_assoc_data(sdata, true); @@ -2747,14 +2725,6 @@ static int ieee80211_probe_auth(struct ieee80211_sub_if_data *sdata) if (WARN_ON_ONCE(!auth_data)) return -EINVAL; - if (!auth_data->synced) { - int ret = drv_tx_sync(local, sdata, auth_data->bss->bssid, - IEEE80211_TX_SYNC_AUTH); - if (ret) - return ret; - } - auth_data->synced = true; - auth_data->tries++; if (auth_data->tries > IEEE80211_AUTH_MAX_TRIES) { @@ -2811,14 +2781,6 @@ static int ieee80211_do_assoc(struct ieee80211_sub_if_data *sdata) lockdep_assert_held(&sdata->u.mgd.mtx); - if (!assoc_data->synced) { - int ret = drv_tx_sync(local, sdata, assoc_data->bss->bssid, - IEEE80211_TX_SYNC_ASSOC); - if (ret) - return ret; - } - assoc_data->synced = true; - assoc_data->tries++; if (assoc_data->tries > IEEE80211_ASSOC_MAX_TRIES) { printk(KERN_DEBUG "%s: association with %pM timed out\n", @@ -3245,9 +3207,6 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata, err = ieee80211_probe_auth(sdata); if (err) { - if (auth_data->synced) - drv_finish_tx_sync(local, sdata, req->bss->bssid, - IEEE80211_TX_SYNC_AUTH); sta_info_destroy_addr(sdata, req->bss->bssid); goto err_clear; } -- cgit From 3cc5240b5e036abb565c8ac7cffdcceb06a13517 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 9 Mar 2012 13:12:35 +0100 Subject: mac80211: set channel back after disassociating As we've discussed, we want to avoid channel changes while associated. While the part when we actually associate needs a bit more work, the bit that happens on disassociating can be changed quite easily. Move the channel type change later in the disassociate process to set the channel only after the driver was told that it's now disassociated. As the driver could expect powersave to be enabled only when associated, this thus results in splitting the config call, but overall what happens makes more sense this way. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/mlme.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 1d09df248c56..5c2ba80c2932 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -1394,7 +1394,7 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; struct ieee80211_local *local = sdata->local; struct sta_info *sta; - u32 changed = 0, config_changed = 0; + u32 changed = 0; u8 bssid[ETH_ALEN]; ASSERT_MGD_MTX(ifmgd); @@ -1454,9 +1454,6 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, changed |= BSS_CHANGED_ASSOC; sdata->vif.bss_conf.assoc = false; - /* channel(_type) changes are handled by ieee80211_hw_config */ - WARN_ON(!ieee80211_set_channel_type(local, sdata, NL80211_CHAN_NO_HT)); - /* on the next assoc, re-program HT parameters */ sdata->ht_opmode_valid = false; memset(&ifmgd->ht_capa, 0, sizeof(ifmgd->ht_capa)); @@ -1469,12 +1466,10 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, if (local->hw.conf.flags & IEEE80211_CONF_PS) { local->hw.conf.flags &= ~IEEE80211_CONF_PS; - config_changed |= IEEE80211_CONF_CHANGE_PS; + ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS); } local->ps_sdata = NULL; - ieee80211_hw_config(local, config_changed); - /* Disable ARP filtering */ if (sdata->vif.bss_conf.arp_filter_enabled) { sdata->vif.bss_conf.arp_filter_enabled = false; @@ -1488,6 +1483,10 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, changed |= BSS_CHANGED_BSSID | BSS_CHANGED_HT; ieee80211_bss_info_change_notify(sdata, changed); + /* channel(_type) changes are handled by ieee80211_hw_config */ + WARN_ON(!ieee80211_set_channel_type(local, sdata, NL80211_CHAN_NO_HT)); + ieee80211_hw_config(local, 0); + /* disassociated - set to defaults now */ ieee80211_set_wmm_default(sdata, false); -- cgit From e9219779f943dfa1010ccbb63de14d49a47c43ee Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Fri, 9 Mar 2012 14:13:45 +0100 Subject: mac80211: Disable MCS > 7 in minstrel_ht when STA uses static SMPS Disable multi stream rates (MCS > 7) when a STA is in static SMPS mode since it has only one active rx chain. Hence, it doesn't even make sense to sample multi stream rates. Signed-off-by: Helmut Schaa Signed-off-by: John W. Linville --- net/mac80211/rc80211_minstrel_ht.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c index ff5f7b84e825..2b42564d6e29 100644 --- a/net/mac80211/rc80211_minstrel_ht.c +++ b/net/mac80211/rc80211_minstrel_ht.c @@ -692,6 +692,7 @@ minstrel_ht_update_caps(void *priv, struct ieee80211_supported_band *sband, int ack_dur; int stbc; int i; + unsigned int smps; /* fall back to the old minstrel for legacy stations */ if (!sta->ht_cap.ht_supported) @@ -731,6 +732,9 @@ minstrel_ht_update_caps(void *priv, struct ieee80211_supported_band *sband, oper_chan_type != NL80211_CHAN_HT40PLUS) sta_cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40; + smps = (sta_cap & IEEE80211_HT_CAP_SM_PS) >> + IEEE80211_HT_CAP_SM_PS_SHIFT; + for (i = 0; i < ARRAY_SIZE(mi->groups); i++) { u16 req = 0; @@ -748,6 +752,11 @@ minstrel_ht_update_caps(void *priv, struct ieee80211_supported_band *sband, if ((sta_cap & req) != req) continue; + /* Mark MCS > 7 as unsupported if STA is in static SMPS mode */ + if (smps == WLAN_HT_CAP_SM_PS_STATIC && + minstrel_mcs_groups[i].streams > 1) + continue; + mi->groups[i].supported = mcs->rx_mask[minstrel_mcs_groups[i].streams - 1]; -- cgit From 290d60891eb659e52204ec209e08cc0cabc5b99f Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Fri, 9 Mar 2012 15:31:50 +0100 Subject: rt2x00: Fix beacon skew in rt2800pci rt2800pci is suffering from beacon skew in AP mode. Some powersaving clients (like VOIP phones) are getting into trouble after some time when the beacon skew is getting too big. The ralink legacy drivers contain a function that indicates that the beacon timer is off by 1us per tbtt. And this function works around that by reducing the beacon interval for every 64th beacon transmission by 64us (the smallest possible value). Do the same in rt2800pci. This allows proper powersaving when rt2800pci is used in AP mode. Signed-off-by: Helmut Schaa Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800.h | 7 +++++++ drivers/net/wireless/rt2x00/rt2800pci.c | 26 ++++++++++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h index e5c05d8c7448..063bfa8b91f4 100644 --- a/drivers/net/wireless/rt2x00/rt2800.h +++ b/drivers/net/wireless/rt2x00/rt2800.h @@ -2474,6 +2474,12 @@ struct mac_iveiv_entry { */ #define EIRP_MAX_TX_POWER_LIMIT 0x50 +/* + * Number of TBTT intervals after which we have to adjust + * the hw beacon timer. + */ +#define BCN_TBTT_OFFSET 64 + /* * RT2800 driver data structure */ @@ -2484,6 +2490,7 @@ struct rt2800_drv_data { u8 bbp26; u8 txmixer_gain_24g; u8 txmixer_gain_5g; + unsigned int tbtt_tick; }; #endif /* RT2800_H */ diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index 9375db455456..0397bbf0ce01 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c @@ -809,7 +809,33 @@ static void rt2800pci_pretbtt_tasklet(unsigned long data) static void rt2800pci_tbtt_tasklet(unsigned long data) { struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data; + struct rt2800_drv_data *drv_data = rt2x00dev->drv_data; + u32 reg; + rt2x00lib_beacondone(rt2x00dev); + + if (rt2x00dev->intf_ap_count) { + /* + * The rt2800pci hardware tbtt timer is off by 1us per tbtt + * causing beacon skew and as a result causing problems with + * some powersaving clients over time. Shorten the beacon + * interval every 64 beacons by 64us to mitigate this effect. + */ + if (drv_data->tbtt_tick == (BCN_TBTT_OFFSET - 2)) { + rt2x00pci_register_read(rt2x00dev, BCN_TIME_CFG, ®); + rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_INTERVAL, + (rt2x00dev->beacon_int * 16) - 1); + rt2x00pci_register_write(rt2x00dev, BCN_TIME_CFG, reg); + } else if (drv_data->tbtt_tick == (BCN_TBTT_OFFSET - 1)) { + rt2x00pci_register_read(rt2x00dev, BCN_TIME_CFG, ®); + rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_INTERVAL, + (rt2x00dev->beacon_int * 16)); + rt2x00pci_register_write(rt2x00dev, BCN_TIME_CFG, reg); + } + drv_data->tbtt_tick++; + drv_data->tbtt_tick %= BCN_TBTT_OFFSET; + } + if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) rt2800pci_enable_interrupt(rt2x00dev, INT_MASK_CSR_TBTT); } -- cgit From 3cd7920a2be893ed0ba58baaed8fc2930e822fc7 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 9 Mar 2012 17:25:33 +0100 Subject: mac80211: add auth/assoc/deauth flow diagram I've been working on some documentation, so let's add this diagram to the kernel tree where at least it has a chance of being maintained :-) Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- .../networking/mac80211-auth-assoc-deauth.txt | 99 ++++++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 Documentation/networking/mac80211-auth-assoc-deauth.txt diff --git a/Documentation/networking/mac80211-auth-assoc-deauth.txt b/Documentation/networking/mac80211-auth-assoc-deauth.txt new file mode 100644 index 000000000000..721773d2b9d2 --- /dev/null +++ b/Documentation/networking/mac80211-auth-assoc-deauth.txt @@ -0,0 +1,99 @@ +# +# This outlines the Linux authentication/association and +# deauthentication/disassociation flows. +# +# This can be converted into a diagram using the service +# at http://www.websequencediagrams.com/ +# + +participant userspace +participant mac80211 +participant driver + +alt authentication needed (not FT) +userspace->mac80211: authenticate + +alt authenticated/authenticating already +mac80211->driver: sta_state(AP, not-exist) +mac80211->driver: bss_info_changed(clear BSSID) +else associated +note over mac80211,driver +like deauth/disassoc, without sending the +BA session stop & deauth/disassoc frames +end note +end + +mac80211->driver: config(channel, non-HT) +mac80211->driver: bss_info_changed(set BSSID, basic rate bitmap) +mac80211->driver: sta_state(AP, exists) + +alt no probe request data known +mac80211->driver: TX directed probe request +driver->mac80211: RX probe response +end + +mac80211->driver: TX auth frame +driver->mac80211: RX auth frame + +alt WEP shared key auth +mac80211->driver: TX auth frame +driver->mac80211: RX auth frame +end + +mac80211->driver: sta_state(AP, authenticated) +mac80211->userspace: RX auth frame + +end + +userspace->mac80211: associate +alt authenticated or associated +note over mac80211,driver: cleanup like for authenticate +end + +alt not previously authenticated (FT) +mac80211->driver: config(channel, non-HT) +mac80211->driver: bss_info_changed(set BSSID, basic rate bitmap) +mac80211->driver: sta_state(AP, exists) +mac80211->driver: sta_state(AP, authenticated) +end +mac80211->driver: TX assoc +driver->mac80211: RX assoc response +note over mac80211: init rate control +mac80211->driver: sta_state(AP, associated) + +alt not using WPA +mac80211->driver: sta_state(AP, authorized) +end + +mac80211->driver: set up QoS parameters + +alt is HT channel +mac80211->driver: config(channel, HT params) +end + +mac80211->driver: bss_info_changed(QoS, HT, associated with AID) +mac80211->userspace: associated + +note left of userspace: associated now + +alt using WPA +note over userspace +do 4-way-handshake +(data frames) +end note +userspace->mac80211: authorized +mac80211->driver: sta_state(AP, authorized) +end + +userspace->mac80211: deauthenticate/disassociate +mac80211->driver: stop BA sessions +mac80211->driver: TX deauth/disassoc +mac80211->driver: flush frames +mac80211->driver: sta_state(AP,associated) +mac80211->driver: sta_state(AP,authenticated) +mac80211->driver: sta_state(AP,exist) +mac80211->driver: sta_state(AP,not-exist) +mac80211->driver: turn off powersave +mac80211->driver: bss_info_changed(clear BSSID, not associated, no QoS, ...) +mac80211->driver: config(non-HT channel type) +mac80211->userspace: disconnected -- cgit From 9f61903ca24e67c22c02de9fd223a98e03f7797a Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Sat, 10 Mar 2012 05:06:49 +0530 Subject: ath9k: configure bss info at assoc notification The proper place to configure bss info is at assoc notification. So that ath9k continues to work if the supirous bssid notification will be removed in future. Cc: Johannes Berg Reported-by: Sujith Manoharan Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index cc2535c38bed..33403a92e45f 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -1973,7 +1973,7 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, ath9k_ps_wakeup(sc); mutex_lock(&sc->mutex); - if (changed & BSS_CHANGED_BSSID) { + if (changed & BSS_CHANGED_ASSOC) { ath9k_config_bss(sc, vif); ath_dbg(common, CONFIG, "BSSID: %pM aid: 0x%x\n", -- cgit From ffb1c56a9706c7e4f1911faa14626b2bb3973479 Mon Sep 17 00:00:00 2001 From: Ashok Nagarajan Date: Fri, 9 Mar 2012 18:57:39 -0800 Subject: ath9k: Fix mactime from being clobbered in rx_status mactime was being overwritten by the function ath9k_rx_skb_preprocess. Fixed by memsetting rx_status in ath_rx_tasklet. Signed-off-by: Ashok Nagarajan Signed-off-by: Javier Cardona Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/recv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index 1b1b279c304a..f4ae3ba994a8 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c @@ -982,8 +982,6 @@ static int ath9k_rx_skb_preprocess(struct ath_common *common, { struct ath_hw *ah = common->ah; - memset(rx_status, 0, sizeof(struct ieee80211_rx_status)); - /* * everything but the rate is checked here, the rate check is done * separately to avoid doing two lookups for a rate for each frame. @@ -1841,6 +1839,8 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) if (sc->sc_flags & SC_OP_RXFLUSH) goto requeue_drop_frag; + memset(rxs, 0, sizeof(struct ieee80211_rx_status)); + rxs->mactime = (tsf & ~0xffffffffULL) | rs.rs_tstamp; if (rs.rs_tstamp > tsf_lower && unlikely(rs.rs_tstamp - tsf_lower > 0x10000000)) -- cgit From c1afdaff90538ef085b756454f12b29575411214 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sat, 10 Mar 2012 13:57:04 +0100 Subject: ath9k: fix going to full-sleep on PS idle The check for PS_WAIT_FOR_TX_ACK was inverted, the hardware should only go to full sleep if no tx is pending. Reported-by: Sujith Manoharan Signed-off-by: Felix Fietkau Cc: stable@vger.kernel.org Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/main.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 33403a92e45f..4a9901090811 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -118,13 +118,15 @@ void ath9k_ps_restore(struct ath_softc *sc) if (--sc->ps_usecount != 0) goto unlock; - if (sc->ps_idle && (sc->ps_flags & PS_WAIT_FOR_TX_ACK)) + if (sc->ps_flags & PS_WAIT_FOR_TX_ACK) + goto unlock; + + if (sc->ps_idle) mode = ATH9K_PM_FULL_SLEEP; else if (sc->ps_enabled && !(sc->ps_flags & (PS_WAIT_FOR_BEACON | PS_WAIT_FOR_CAB | - PS_WAIT_FOR_PSPOLL_DATA | - PS_WAIT_FOR_TX_ACK))) + PS_WAIT_FOR_PSPOLL_DATA))) mode = ATH9K_PM_NETWORK_SLEEP; else goto unlock; -- cgit From 10d8f31ebbd6ea9aa8d65d2f04ebef63225052de Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Sat, 10 Mar 2012 13:00:06 -0800 Subject: iwlwifi: remove TX hex debug Tracing is much better for this, so remove the hex printk debug for the TX command. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c index 91628565409f..14b0361d46ea 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c @@ -1466,8 +1466,6 @@ static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, IWL_DEBUG_TX(trans, "sequence nr = 0X%x\n", le16_to_cpu(dev_cmd->hdr.sequence)); IWL_DEBUG_TX(trans, "tx_flags = 0X%x\n", le32_to_cpu(tx_cmd->tx_flags)); - iwl_print_hex_dump(trans, IWL_DL_TX, (u8 *)tx_cmd, sizeof(*tx_cmd)); - iwl_print_hex_dump(trans, IWL_DL_TX, (u8 *)tx_cmd->hdr, hdr_len); /* Set up entry for this TFD in Tx byte-count array */ iwl_trans_txq_update_byte_cnt_tbl(trans, txq, le16_to_cpu(tx_cmd->len)); -- cgit From d663ee73f62903aed334eca25832a76c4a7e4c1c Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Sat, 10 Mar 2012 13:00:07 -0800 Subject: iwlwifi: abstract out missing SEQ_RX_FRAME workaround Mohammed Shafi ran into [1] the SEQ_RX_FRAME workaround warning with a statistics notification, this means we can't just remove it as we'd hoped. Abstract it out so that the higher layer can configure this as a kind of "filter" in the transport. [1] http://mid.gmane.org/CAD2nsn1_DzbRHuSbS_1rFNzuux_9pW1-pABEasQ01_y7-ndO5w@mail.gmail.com Reported-by: Mohammed Shafi Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn.c | 10 ++++++++ drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h | 2 ++ drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c | 29 +++++++++-------------- drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | 7 ++++++ drivers/net/wireless/iwlwifi/iwl-trans.h | 9 +++++++ 5 files changed, 39 insertions(+), 18 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 28422c03d673..5ef15855be2f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -1186,6 +1186,14 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans, u16 num_mac; u32 ucode_flags; struct iwl_trans_config trans_cfg; + static const u8 no_reclaim_cmds[] = { + REPLY_RX_PHY_CMD, + REPLY_RX, + REPLY_RX_MPDU_CMD, + REPLY_COMPRESSED_BA, + STATISTICS_NOTIFICATION, + REPLY_TX, + }; /************************ * 1. Allocating HW data @@ -1211,6 +1219,8 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans, * to know about. */ trans_cfg.op_mode = op_mode; + trans_cfg.no_reclaim_cmds = no_reclaim_cmds; + trans_cfg.n_no_reclaim_cmds = ARRAY_SIZE(no_reclaim_cmds); ucode_flags = fw->ucode_capa.flags; diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h index 67965599bb30..1c2fe87bd7e2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h @@ -291,6 +291,8 @@ struct iwl_trans_pcie { wait_queue_head_t ucode_write_waitq; unsigned long status; u8 cmd_queue; + u8 n_no_reclaim_cmds; + u8 no_reclaim_cmds[MAX_NO_RECLAIM_CMDS]; }; #define IWL_TRANS_GET_PCIE_TRANS(_iwl_trans) \ diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c index 9bc3c73af5e9..8bec0e1ccb54 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c @@ -395,13 +395,17 @@ static void iwl_rx_handle_rxbuf(struct iwl_trans *trans, * there is no command buffer to reclaim. * Ucode should set SEQ_RX_FRAME bit if ucode-originated, * but apparently a few don't get set; catch them here. */ - reclaim = !(pkt->hdr.sequence & SEQ_RX_FRAME) && - (pkt->hdr.cmd != REPLY_RX_PHY_CMD) && - (pkt->hdr.cmd != REPLY_RX) && - (pkt->hdr.cmd != REPLY_RX_MPDU_CMD) && - (pkt->hdr.cmd != REPLY_COMPRESSED_BA) && - (pkt->hdr.cmd != STATISTICS_NOTIFICATION) && - (pkt->hdr.cmd != REPLY_TX); + reclaim = !(pkt->hdr.sequence & SEQ_RX_FRAME); + if (reclaim) { + int i; + + for (i = 0; i < trans_pcie->n_no_reclaim_cmds; i++) { + if (trans_pcie->no_reclaim_cmds[i] == pkt->hdr.cmd) { + reclaim = false; + break; + } + } + } sequence = le16_to_cpu(pkt->hdr.sequence); index = SEQ_TO_INDEX(sequence); @@ -412,17 +416,6 @@ static void iwl_rx_handle_rxbuf(struct iwl_trans *trans, else cmd = NULL; - /* warn if this is cmd response / notification and the uCode - * didn't set the SEQ_RX_FRAME for a frame that is - * uCode-originated - * If you saw this code after the second half of 2012, then - * please remove it - */ - WARN(pkt->hdr.cmd != REPLY_TX && reclaim == false && - (!(pkt->hdr.sequence & SEQ_RX_FRAME)), - "reclaim is false, SEQ_RX_FRAME unset: %s\n", - get_cmd_string(pkt->hdr.cmd)); - err = iwl_op_mode_rx(trans->op_mode, &rxcb, cmd); /* diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c index 14b0361d46ea..4900dfa59df7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c @@ -1626,6 +1626,13 @@ static void iwl_trans_pcie_configure(struct iwl_trans *trans, struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); trans_pcie->cmd_queue = trans_cfg->cmd_queue; + if (WARN_ON(trans_cfg->n_no_reclaim_cmds > MAX_NO_RECLAIM_CMDS)) + trans_pcie->n_no_reclaim_cmds = 0; + else + trans_pcie->n_no_reclaim_cmds = trans_cfg->n_no_reclaim_cmds; + if (trans_pcie->n_no_reclaim_cmds) + memcpy(trans_pcie->no_reclaim_cmds, trans_cfg->no_reclaim_cmds, + trans_pcie->n_no_reclaim_cmds * sizeof(u8)); } static void iwl_trans_pcie_free(struct iwl_trans *trans) diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index 7d1990c7f658..95f3faf4e866 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h @@ -274,6 +274,8 @@ static inline struct page *rxb_steal_page(struct iwl_rx_cmd_buffer *r) return p; } +#define MAX_NO_RECLAIM_CMDS 6 + /** * struct iwl_trans_config - transport configuration * @@ -281,10 +283,17 @@ static inline struct page *rxb_steal_page(struct iwl_rx_cmd_buffer *r) * Must be set before any other call. * @cmd_queue: the index of the command queue. * Must be set before start_fw. + * @no_reclaim_cmds: Some devices erroneously don't set the + * SEQ_RX_FRAME bit on some notifications, this is the + * list of such notifications to filter. Max length is + * %MAX_NO_RECLAIM_CMDS. + * @n_no_reclaim_cmds: # of commands in list */ struct iwl_trans_config { struct iwl_op_mode *op_mode; u8 cmd_queue; + const u8 *no_reclaim_cmds; + int n_no_reclaim_cmds; }; /** -- cgit From f0d120af8f55649571c681f49c920b0822050fa5 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Sat, 10 Mar 2012 13:00:08 -0800 Subject: iwlwifi: convert bad state message into warning Looking at logs, I see that we did get the bad state message a few times for some reason, but it doesn't indicate why or where it came from, so make it a warning in order to identify it. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-trans.h | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index 95f3faf4e866..782cb0ddc962 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h @@ -497,8 +497,8 @@ static inline void iwl_trans_wowlan_suspend(struct iwl_trans *trans) static inline int iwl_trans_send_cmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd) { - if (trans->state != IWL_TRANS_FW_ALIVE) - IWL_ERR(trans, "%s bad state = %d", __func__, trans->state); + WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE, + "%s bad state = %d", __func__, trans->state); return trans->ops->send_cmd(trans, cmd); } @@ -517,8 +517,8 @@ static inline int iwl_trans_reclaim(struct iwl_trans *trans, int sta_id, int tid, int txq_id, int ssn, struct sk_buff_head *skbs) { - if (trans->state != IWL_TRANS_FW_ALIVE) - IWL_ERR(trans, "%s bad state = %d", __func__, trans->state); + WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE, + "%s bad state = %d", __func__, trans->state); return trans->ops->reclaim(trans, sta_id, tid, txq_id, ssn, skbs); } @@ -526,8 +526,8 @@ static inline int iwl_trans_reclaim(struct iwl_trans *trans, int sta_id, static inline int iwl_trans_tx_agg_disable(struct iwl_trans *trans, int sta_id, int tid) { - if (trans->state != IWL_TRANS_FW_ALIVE) - IWL_ERR(trans, "%s bad state = %d", __func__, trans->state); + WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE, + "%s bad state = %d", __func__, trans->state); return trans->ops->tx_agg_disable(trans, sta_id, tid); } @@ -535,8 +535,8 @@ static inline int iwl_trans_tx_agg_disable(struct iwl_trans *trans, static inline int iwl_trans_tx_agg_alloc(struct iwl_trans *trans, int sta_id, int tid) { - if (trans->state != IWL_TRANS_FW_ALIVE) - IWL_ERR(trans, "%s bad state = %d", __func__, trans->state); + WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE, + "%s bad state = %d", __func__, trans->state); return trans->ops->tx_agg_alloc(trans, sta_id, tid); } @@ -549,8 +549,8 @@ static inline void iwl_trans_tx_agg_setup(struct iwl_trans *trans, { might_sleep(); - if (trans->state != IWL_TRANS_FW_ALIVE) - IWL_ERR(trans, "%s bad state = %d", __func__, trans->state); + WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE, + "%s bad state = %d", __func__, trans->state); trans->ops->tx_agg_setup(trans, ctx, sta_id, tid, frame_limit, ssn); } @@ -562,16 +562,16 @@ static inline void iwl_trans_free(struct iwl_trans *trans) static inline int iwl_trans_wait_tx_queue_empty(struct iwl_trans *trans) { - if (trans->state != IWL_TRANS_FW_ALIVE) - IWL_ERR(trans, "%s bad state = %d", __func__, trans->state); + WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE, + "%s bad state = %d", __func__, trans->state); return trans->ops->wait_tx_queue_empty(trans); } static inline int iwl_trans_check_stuck_queue(struct iwl_trans *trans, int q) { - if (trans->state != IWL_TRANS_FW_ALIVE) - IWL_ERR(trans, "%s bad state = %d", __func__, trans->state); + WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE, + "%s bad state = %d", __func__, trans->state); return trans->ops->check_stuck_queue(trans, q); } -- cgit From 69a10b29eb87cf186cac20921b4884e349b59c97 Mon Sep 17 00:00:00 2001 From: Meenakshi Venkataraman Date: Sat, 10 Mar 2012 13:00:09 -0800 Subject: iwlwifi: move wait_command_queue from shared to trans This wait queue really belongs to the transport layer, as it is used for sending synchronous commands to the HW. However, only op_mode knows about errors and exceptional conditions, so make this queue accessible by the op_mode. Signed-off-by: Meenakshi Venkataraman Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-rx.c | 2 +- drivers/net/wireless/iwlwifi/iwl-agn.c | 2 -- drivers/net/wireless/iwlwifi/iwl-core.c | 2 +- drivers/net/wireless/iwlwifi/iwl-shared.h | 3 --- drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c | 2 +- drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c | 4 ++-- drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | 3 +++ drivers/net/wireless/iwlwifi/iwl-trans.h | 3 +++ 8 files changed, 11 insertions(+), 10 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c index cc0227c1f352..44c6f712b77d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c @@ -671,7 +671,7 @@ static int iwlagn_rx_card_state_notif(struct iwl_priv *priv, wiphy_rfkill_set_hw_state(priv->hw->wiphy, test_bit(STATUS_RF_KILL_HW, &priv->status)); else - wake_up(&priv->shrd->wait_command_queue); + wake_up(&trans(priv)->wait_command_queue); return 0; } diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 5ef15855be2f..66d7446ff07b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -962,8 +962,6 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv) { priv->workqueue = create_singlethread_workqueue(DRV_NAME); - init_waitqueue_head(&priv->shrd->wait_command_queue); - INIT_WORK(&priv->restart, iwl_bg_restart); INIT_WORK(&priv->beacon_update, iwl_bg_beacon_update); INIT_WORK(&priv->run_time_calib_work, iwl_bg_run_time_calib_work); diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 8b85940731f2..e3eda50a5a67 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -850,7 +850,7 @@ static void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand) * commands by clearing the ready bit */ clear_bit(STATUS_READY, &priv->status); - wake_up(&priv->shrd->wait_command_queue); + wake_up(&trans(priv)->wait_command_queue); if (!ondemand) { /* diff --git a/drivers/net/wireless/iwlwifi/iwl-shared.h b/drivers/net/wireless/iwlwifi/iwl-shared.h index cf34087aa2fe..29d2a85232fc 100644 --- a/drivers/net/wireless/iwlwifi/iwl-shared.h +++ b/drivers/net/wireless/iwlwifi/iwl-shared.h @@ -376,7 +376,6 @@ struct iwl_cfg { * @nic: pointer to the nic data * @hw_params: see struct iwl_hw_params * @lock: protect general shared data - * @wait_command_queue: the wait_queue for SYNC host commands * @eeprom: pointer to the eeprom/OTP image * @ucode_type: indicator of loaded ucode image * @device_pointers: pointers to ucode event tables @@ -391,8 +390,6 @@ struct iwl_shared { struct iwl_hw_params hw_params; const struct iwl_fw *fw; - wait_queue_head_t wait_command_queue; - /* eeprom -- this is in the card's little endian byte order */ u8 *eeprom; diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c index 8bec0e1ccb54..8b1a7988e176 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c @@ -684,7 +684,7 @@ static void iwl_irq_handle_error(struct iwl_trans *trans) */ clear_bit(STATUS_READY, &trans->shrd->status); clear_bit(STATUS_HCMD_ACTIVE, &trans->shrd->status); - wake_up(&trans->shrd->wait_command_queue); + wake_up(&trans->wait_command_queue); IWL_ERR(trans, "RF is used by WiMAX\n"); return; } diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c index 565c664f6dce..a66ad9b590a4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c @@ -928,7 +928,7 @@ void iwl_tx_cmd_complete(struct iwl_trans *trans, struct iwl_rx_cmd_buffer *rxb, clear_bit(STATUS_HCMD_ACTIVE, &trans->shrd->status); IWL_DEBUG_INFO(trans, "Clearing HCMD_ACTIVE for command %s\n", get_cmd_string(cmd->hdr.cmd)); - wake_up(&trans->shrd->wait_command_queue); + wake_up(&trans->wait_command_queue); } meta->flags = 0; @@ -992,7 +992,7 @@ static int iwl_send_cmd_sync(struct iwl_trans *trans, struct iwl_host_cmd *cmd) return ret; } - ret = wait_event_timeout(trans->shrd->wait_command_queue, + ret = wait_event_timeout(trans->wait_command_queue, !test_bit(STATUS_HCMD_ACTIVE, &trans->shrd->status), HOST_COMPLETE_TIMEOUT); if (!ret) { diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c index 4900dfa59df7..0e8e31a53c7a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c @@ -2327,6 +2327,9 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct iwl_shared *shrd, pci_write_config_word(pdev, PCI_COMMAND, pci_cmd); } + /* Initialize the wait queue for commands */ + init_waitqueue_head(&trans->wait_command_queue); + return trans; out_pci_release_regions: diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index 782cb0ddc962..0c81cbaa8088 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h @@ -413,6 +413,7 @@ enum iwl_trans_state { * @hw_id_str: a string with info about HW ID. Set during transport allocation. * @nvm_device_type: indicates OTP or eeprom * @pm_support: set to true in start_hw if link pm is supported + * @wait_command_queue: the wait_queue for SYNC host commands */ struct iwl_trans { const struct iwl_trans_ops *ops; @@ -429,6 +430,8 @@ struct iwl_trans { int nvm_device_type; bool pm_support; + wait_queue_head_t wait_command_queue; + /* pointer to trans specific struct */ /*Ensure that this pointer will always be aligned to sizeof pointer */ char trans_specific[0] __aligned(sizeof(void *)); -- cgit From 8f7ffbe2b275e5315773322161945a24518e31f4 Mon Sep 17 00:00:00 2001 From: David Spinadel Date: Sat, 10 Mar 2012 13:00:10 -0800 Subject: iwlwifi: avoid some operations if no uCode loaded Printing the SRAM and similar testmode operations could be triggered when no uCode is loaded; prevent those invalid operations by tracking whether uCode is loaded. Signed-off-by: David Spinadel Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 1 + drivers/net/wireless/iwlwifi/iwl-agn.c | 2 ++ drivers/net/wireless/iwlwifi/iwl-core.c | 3 +++ drivers/net/wireless/iwlwifi/iwl-debugfs.c | 15 +++++++++-- drivers/net/wireless/iwlwifi/iwl-dev.h | 1 + drivers/net/wireless/iwlwifi/iwl-testmode.c | 40 ++++++++++++++++------------- drivers/net/wireless/iwlwifi/iwl-ucode.c | 6 +++++ 7 files changed, 48 insertions(+), 20 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index 915183a3a873..3e1698dc995f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -1189,6 +1189,7 @@ int iwlagn_suspend(struct iwl_priv *priv, struct cfg80211_wowlan *wowlan) memcpy(&rxon, &ctx->active, sizeof(rxon)); + priv->ucode_loaded = false; iwl_trans_stop_device(trans(priv)); priv->wowlan = true; diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 66d7446ff07b..f1226dbf789d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -816,6 +816,7 @@ void iwl_down(struct iwl_priv *priv) if (priv->mac80211_registered) ieee80211_stop_queues(priv->hw); + priv->ucode_loaded = false; iwl_trans_stop_device(trans(priv)); /* Clear out all status bits but a few that are stable across reset */ @@ -1406,6 +1407,7 @@ static void iwl_op_mode_dvm_stop(struct iwl_op_mode *op_mode) iwl_tt_exit(priv); /*This will stop the queues, move the device to low power state */ + priv->ucode_loaded = false; iwl_trans_stop_device(trans(priv)); iwl_eeprom_free(priv->shrd); diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index e3eda50a5a67..46490d3b95b9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -838,6 +838,9 @@ static void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand) iwl_print_rx_config_cmd(priv, IWL_RXON_CTX_BSS); #endif + /* uCode is no longer loaded. */ + priv->ucode_loaded = false; + /* Set the FW error flag -- cleared on iwl_down */ set_bit(STATUS_FW_ERROR, &priv->shrd->status); diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index 9b71c87847c2..89cb9a7a3b56 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c @@ -235,10 +235,21 @@ static ssize_t iwl_dbgfs_sram_read(struct file *file, /* default is to dump the entire data segment */ if (!priv->dbgfs_sram_offset && !priv->dbgfs_sram_len) { priv->dbgfs_sram_offset = 0x800000; - if (priv->shrd->ucode_type == IWL_UCODE_INIT) + if (!priv->ucode_loaded) { + IWL_ERR(priv, "No uCode has been loadded.\n"); + return -EINVAL; + } + if (priv->shrd->ucode_type == IWL_UCODE_INIT) { priv->dbgfs_sram_len = priv->fw->ucode_init.data.len; - else + } else if (priv->shrd->ucode_type == IWL_UCODE_REGULAR) { priv->dbgfs_sram_len = priv->fw->ucode_rt.data.len; + } else if (priv->shrd->ucode_type == IWL_UCODE_WOWLAN) { + priv->dbgfs_sram_len = priv->fw->ucode_wowlan.data.len; + } else { + IWL_ERR(priv, "Unsupported type of uCode loaded?" + " that shouldn't happen.\n"); + return -EINVAL; + } } len = priv->dbgfs_sram_len; diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index aa4b3b122da4..01dbe1162f96 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -769,6 +769,7 @@ struct iwl_priv { /* firmware reload counter and timestamp */ unsigned long reload_jiffies; int reload_count; + bool ucode_loaded; /* we allocate array of iwl_channel_info for NIC's valid channels. * Access via channel # using indirect index array */ diff --git a/drivers/net/wireless/iwlwifi/iwl-testmode.c b/drivers/net/wireless/iwlwifi/iwl-testmode.c index b06c6763cb7a..c6c084f45b72 100644 --- a/drivers/net/wireless/iwlwifi/iwl-testmode.c +++ b/drivers/net/wireless/iwlwifi/iwl-testmode.c @@ -494,6 +494,7 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb) case IWL_TM_CMD_APP2DEV_CFG_INIT_CALIB: iwl_testmode_cfg_init_calib(priv); + priv->ucode_loaded = false; iwl_trans_stop_device(trans); break; @@ -512,6 +513,7 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb) case IWL_TM_CMD_APP2DEV_LOAD_WOWLAN_FW: iwl_scan_cancel_timeout(priv, 200); + priv->ucode_loaded = false; iwl_trans_stop_device(trans); status = iwl_load_ucode_wait_alive(priv, IWL_UCODE_WOWLAN); if (status) { @@ -591,25 +593,27 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb) IWL_ERR(priv, "Memory allocation fail\n"); return -ENOMEM; } - switch (priv->shrd->ucode_type) { - case IWL_UCODE_REGULAR: - inst_size = priv->fw->ucode_rt.code.len; - data_size = priv->fw->ucode_rt.data.len; - break; - case IWL_UCODE_INIT: - inst_size = priv->fw->ucode_init.code.len; - data_size = priv->fw->ucode_init.data.len; - break; - case IWL_UCODE_WOWLAN: - inst_size = priv->fw->ucode_wowlan.code.len; - data_size = priv->fw->ucode_wowlan.data.len; - break; - case IWL_UCODE_NONE: + if (!priv->ucode_loaded) { IWL_ERR(priv, "No uCode has not been loaded\n"); - break; - default: - IWL_ERR(priv, "Unsupported uCode type\n"); - break; + return -EINVAL; + } else { + switch (priv->shrd->ucode_type) { + case IWL_UCODE_REGULAR: + inst_size = priv->fw->ucode_rt.code.len; + data_size = priv->fw->ucode_rt.data.len; + break; + case IWL_UCODE_INIT: + inst_size = priv->fw->ucode_init.code.len; + data_size = priv->fw->ucode_init.data.len; + break; + case IWL_UCODE_WOWLAN: + inst_size = priv->fw->ucode_wowlan.code.len; + data_size = priv->fw->ucode_wowlan.data.len; + break; + default: + IWL_ERR(priv, "Unsupported uCode type\n"); + break; + } } NLA_PUT_U32(skb, IWL_TM_ATTR_FW_TYPE, priv->shrd->ucode_type); NLA_PUT_U32(skb, IWL_TM_ATTR_FW_INST_SIZE, inst_size); diff --git a/drivers/net/wireless/iwlwifi/iwl-ucode.c b/drivers/net/wireless/iwlwifi/iwl-ucode.c index d97cf44b75ba..ae935c0e3563 100644 --- a/drivers/net/wireless/iwlwifi/iwl-ucode.c +++ b/drivers/net/wireless/iwlwifi/iwl-ucode.c @@ -465,6 +465,8 @@ int iwl_load_ucode_wait_alive(struct iwl_priv *priv, priv->shrd->ucode_type = ucode_type; fw = iwl_get_ucode_image(priv, ucode_type); + priv->ucode_loaded = false; + if (!fw) return -EINVAL; @@ -519,6 +521,8 @@ int iwl_load_ucode_wait_alive(struct iwl_priv *priv, return ret; } + priv->ucode_loaded = true; + return 0; } @@ -563,5 +567,7 @@ int iwl_run_init_ucode(struct iwl_priv *priv) out: /* Whatever happened, stop the device */ iwl_trans_stop_device(trans(priv)); + priv->ucode_loaded = false; + return ret; } -- cgit From b5ea1624833b816184aa262c190f2774b8d2ea63 Mon Sep 17 00:00:00 2001 From: David Spinadel Date: Sat, 10 Mar 2012 13:00:11 -0800 Subject: iwlwifi: explicitly track whether INIT uCode was run Remove IWL_UCODE_NONE from enum iwl_ucode_type which, by being the default value in 0-initialized memory, implicitly allowed us to track whether any uCode had ever been loaded successfully (which would have been the INIT uCode) and instead explicitly track whether or not INIT uCode has been run. Signed-off-by: David Spinadel Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-dev.h | 1 + drivers/net/wireless/iwlwifi/iwl-shared.h | 4 +--- drivers/net/wireless/iwlwifi/iwl-ucode.c | 6 ++++-- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 01dbe1162f96..16956b777f96 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -770,6 +770,7 @@ struct iwl_priv { unsigned long reload_jiffies; int reload_count; bool ucode_loaded; + bool init_ucode_run; /* Don't run init uCode again */ /* we allocate array of iwl_channel_info for NIC's valid channels. * Access via channel # using indirect index array */ diff --git a/drivers/net/wireless/iwlwifi/iwl-shared.h b/drivers/net/wireless/iwlwifi/iwl-shared.h index 29d2a85232fc..4cd2eced8a4c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-shared.h +++ b/drivers/net/wireless/iwlwifi/iwl-shared.h @@ -195,15 +195,13 @@ struct iwl_hw_params { /** * enum iwl_ucode_type * - * The type of ucode currently loaded on the hardware. + * The type of ucode. * - * @IWL_UCODE_NONE: No ucode loaded * @IWL_UCODE_REGULAR: Normal runtime ucode * @IWL_UCODE_INIT: Initial ucode * @IWL_UCODE_WOWLAN: Wake on Wireless enabled ucode */ enum iwl_ucode_type { - IWL_UCODE_NONE, IWL_UCODE_REGULAR, IWL_UCODE_INIT, IWL_UCODE_WOWLAN, diff --git a/drivers/net/wireless/iwlwifi/iwl-ucode.c b/drivers/net/wireless/iwlwifi/iwl-ucode.c index ae935c0e3563..0908880dd7ac 100644 --- a/drivers/net/wireless/iwlwifi/iwl-ucode.c +++ b/drivers/net/wireless/iwlwifi/iwl-ucode.c @@ -87,7 +87,7 @@ iwl_get_ucode_image(struct iwl_priv *priv, enum iwl_ucode_type ucode_type) return &priv->fw->ucode_wowlan; case IWL_UCODE_REGULAR: return &priv->fw->ucode_rt; - case IWL_UCODE_NONE: + default: break; } return NULL; @@ -537,7 +537,7 @@ int iwl_run_init_ucode(struct iwl_priv *priv) if (!priv->fw->ucode_init.code.len) return 0; - if (priv->shrd->ucode_type != IWL_UCODE_NONE) + if (priv->init_ucode_run) return 0; iwl_init_notification_wait(&priv->notif_wait, &calib_wait, @@ -559,6 +559,8 @@ int iwl_run_init_ucode(struct iwl_priv *priv) */ ret = iwl_wait_notification(&priv->notif_wait, &calib_wait, UCODE_CALIB_TIMEOUT); + if (!ret) + priv->init_ucode_run = true; goto out; -- cgit From 0cedacc5797bbae5b07e5e861fbe7b8e33f2ef78 Mon Sep 17 00:00:00 2001 From: David Spinadel Date: Sat, 10 Mar 2012 13:00:12 -0800 Subject: iwlwifi: more modularity in fw images and sections Changed iwl_firmware_pieces structure to support an array of separate images, and an array of sections for each image. In fw_sec and fw_desc structures, added a field for offset from the HW address, to support 16.0 uCode that provides an offset instead of any other data about the section. This field is filled with default values when parsing instruction or data section. Signed-off-by: David Spinadel Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-drv.c | 280 ++++++++++++++++++++++-------- drivers/net/wireless/iwlwifi/iwl-fw.h | 3 +- drivers/net/wireless/iwlwifi/iwl-shared.h | 1 + 3 files changed, 207 insertions(+), 77 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.c b/drivers/net/wireless/iwlwifi/iwl-drv.c index 29a3ae48df6d..a21af3df6c8a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-drv.c +++ b/drivers/net/wireless/iwlwifi/iwl-drv.c @@ -69,6 +69,7 @@ #include "iwl-trans.h" #include "iwl-shared.h" #include "iwl-op-mode.h" +#include "iwl-agn-hw.h" /* private includes */ #include "iwl-fw-file.h" @@ -96,6 +97,16 @@ struct iwl_drv { +/* + * struct fw_sec: Just for the image parsing proccess. + * For the fw storage we are using struct fw_desc. + */ +struct fw_sec { + const void *data; /* the sec data */ + size_t size; /* section size */ + u32 offset; /* offset of writing in the device */ +}; + static void iwl_free_fw_desc(struct iwl_drv *drv, struct fw_desc *desc) { if (desc->v_addr) @@ -119,20 +130,21 @@ static void iwl_dealloc_ucode(struct iwl_drv *drv) } static int iwl_alloc_fw_desc(struct iwl_drv *drv, struct fw_desc *desc, - const void *data, size_t len) + struct fw_sec *sec) { - if (!len) { + if (!sec || !sec->size) { desc->v_addr = NULL; return -EINVAL; } - desc->v_addr = dma_alloc_coherent(trans(drv)->dev, len, + desc->v_addr = dma_alloc_coherent(trans(drv)->dev, sec->size, &desc->p_addr, GFP_KERNEL); if (!desc->v_addr) return -ENOMEM; - desc->len = len; - memcpy(desc->v_addr, data, len); + desc->len = sec->size; + desc->offset = sec->offset; + memcpy(desc->v_addr, sec->data, sec->size); return 0; } @@ -177,18 +189,77 @@ static int iwl_request_firmware(struct iwl_drv *drv, bool first) GFP_KERNEL, drv, iwl_ucode_callback); } -struct iwlagn_firmware_pieces { - const void *inst, *data, *init, *init_data, *wowlan_inst, *wowlan_data; - size_t inst_size, data_size, init_size, init_data_size, - wowlan_inst_size, wowlan_data_size; +/* + * enumeration of ucode section. + * This enumeration is used for legacy tlv style (before 16.0 uCode). + */ +enum iwl_ucode_sec { + IWL_UCODE_SECTION_INST, + IWL_UCODE_SECTION_DATA, +}; +/* + * For 16.0 uCode and above, there is no differentiation between section, + * just an offset to the HW address. + */ +#define UCODE_SECTION_MAX 4 + +struct fw_img_parsing { + struct fw_sec sec[UCODE_SECTION_MAX]; + int sec_counter; +}; + +struct iwl_firmware_pieces { + struct fw_img_parsing img[IWL_UCODE_TYPE_MAX]; u32 init_evtlog_ptr, init_evtlog_size, init_errlog_ptr; u32 inst_evtlog_ptr, inst_evtlog_size, inst_errlog_ptr; }; +/* + * These functions are just to extract uCode section data from the pieces + * structure. + */ +static struct fw_sec *get_sec(struct iwl_firmware_pieces *pieces, + enum iwl_ucode_type type, + int sec) +{ + return &pieces->img[type].sec[sec]; +} + +static void set_sec_data(struct iwl_firmware_pieces *pieces, + enum iwl_ucode_type type, + int sec, + const void *data) +{ + pieces->img[type].sec[sec].data = data; +} + +static void set_sec_size(struct iwl_firmware_pieces *pieces, + enum iwl_ucode_type type, + int sec, + size_t size) +{ + pieces->img[type].sec[sec].size = size; +} + +static size_t get_sec_size(struct iwl_firmware_pieces *pieces, + enum iwl_ucode_type type, + int sec) +{ + return pieces->img[type].sec[sec].size; +} + +static void set_sec_offset(struct iwl_firmware_pieces *pieces, + enum iwl_ucode_type type, + int sec, + u32 offset) +{ + pieces->img[type].sec[sec].offset = offset; +} + static int iwl_parse_v1_v2_firmware(struct iwl_drv *drv, - const struct firmware *ucode_raw, - struct iwlagn_firmware_pieces *pieces) + const struct firmware *ucode_raw, + struct iwl_firmware_pieces *pieces) { struct iwl_ucode_header *ucode = (void *)ucode_raw->data; u32 api_ver, hdr_size, build; @@ -206,11 +277,14 @@ static int iwl_parse_v1_v2_firmware(struct iwl_drv *drv, return -EINVAL; } build = le32_to_cpu(ucode->u.v2.build); - pieces->inst_size = le32_to_cpu(ucode->u.v2.inst_size); - pieces->data_size = le32_to_cpu(ucode->u.v2.data_size); - pieces->init_size = le32_to_cpu(ucode->u.v2.init_size); - pieces->init_data_size = - le32_to_cpu(ucode->u.v2.init_data_size); + set_sec_size(pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_INST, + le32_to_cpu(ucode->u.v2.inst_size)); + set_sec_size(pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_DATA, + le32_to_cpu(ucode->u.v2.data_size)); + set_sec_size(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_INST, + le32_to_cpu(ucode->u.v2.init_size)); + set_sec_size(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_DATA, + le32_to_cpu(ucode->u.v2.init_data_size)); src = ucode->u.v2.data; break; case 0: @@ -222,11 +296,14 @@ static int iwl_parse_v1_v2_firmware(struct iwl_drv *drv, return -EINVAL; } build = 0; - pieces->inst_size = le32_to_cpu(ucode->u.v1.inst_size); - pieces->data_size = le32_to_cpu(ucode->u.v1.data_size); - pieces->init_size = le32_to_cpu(ucode->u.v1.init_size); - pieces->init_data_size = - le32_to_cpu(ucode->u.v1.init_data_size); + set_sec_size(pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_INST, + le32_to_cpu(ucode->u.v1.inst_size)); + set_sec_size(pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_DATA, + le32_to_cpu(ucode->u.v1.data_size)); + set_sec_size(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_INST, + le32_to_cpu(ucode->u.v1.init_size)); + set_sec_size(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_DATA, + le32_to_cpu(ucode->u.v1.init_data_size)); src = ucode->u.v1.data; break; } @@ -248,9 +325,12 @@ static int iwl_parse_v1_v2_firmware(struct iwl_drv *drv, buildstr); /* Verify size of file vs. image size info in file's header */ - if (ucode_raw->size != hdr_size + pieces->inst_size + - pieces->data_size + pieces->init_size + - pieces->init_data_size) { + + if (ucode_raw->size != hdr_size + + get_sec_size(pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_INST) + + get_sec_size(pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_DATA) + + get_sec_size(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_INST) + + get_sec_size(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_DATA)) { IWL_ERR(drv, "uCode file size %d does not match expected size\n", @@ -258,21 +338,29 @@ static int iwl_parse_v1_v2_firmware(struct iwl_drv *drv, return -EINVAL; } - pieces->inst = src; - src += pieces->inst_size; - pieces->data = src; - src += pieces->data_size; - pieces->init = src; - src += pieces->init_size; - pieces->init_data = src; - src += pieces->init_data_size; + set_sec_data(pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_INST, src); + src += get_sec_size(pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_INST); + set_sec_offset(pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_INST, + IWLAGN_RTC_INST_LOWER_BOUND); + set_sec_data(pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_DATA, src); + src += get_sec_size(pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_DATA); + set_sec_offset(pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_DATA, + IWLAGN_RTC_DATA_LOWER_BOUND); + set_sec_data(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_INST, src); + src += get_sec_size(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_INST); + set_sec_offset(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_INST, + IWLAGN_RTC_INST_LOWER_BOUND); + set_sec_data(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_DATA, src); + src += get_sec_size(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_DATA); + set_sec_offset(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_DATA, + IWLAGN_RTC_DATA_LOWER_BOUND); return 0; } static int iwl_parse_tlv_firmware(struct iwl_drv *drv, const struct firmware *ucode_raw, - struct iwlagn_firmware_pieces *pieces, + struct iwl_firmware_pieces *pieces, struct iwl_ucode_capabilities *capa) { struct iwl_tlv_ucode_header *ucode = (void *)ucode_raw->data; @@ -368,20 +456,40 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv, switch (tlv_type) { case IWL_UCODE_TLV_INST: - pieces->inst = tlv_data; - pieces->inst_size = tlv_len; + set_sec_data(pieces, IWL_UCODE_REGULAR, + IWL_UCODE_SECTION_INST, tlv_data); + set_sec_size(pieces, IWL_UCODE_REGULAR, + IWL_UCODE_SECTION_INST, tlv_len); + set_sec_offset(pieces, IWL_UCODE_REGULAR, + IWL_UCODE_SECTION_INST, + IWLAGN_RTC_INST_LOWER_BOUND); break; case IWL_UCODE_TLV_DATA: - pieces->data = tlv_data; - pieces->data_size = tlv_len; + set_sec_data(pieces, IWL_UCODE_REGULAR, + IWL_UCODE_SECTION_DATA, tlv_data); + set_sec_size(pieces, IWL_UCODE_REGULAR, + IWL_UCODE_SECTION_DATA, tlv_len); + set_sec_offset(pieces, IWL_UCODE_REGULAR, + IWL_UCODE_SECTION_DATA, + IWLAGN_RTC_DATA_LOWER_BOUND); break; case IWL_UCODE_TLV_INIT: - pieces->init = tlv_data; - pieces->init_size = tlv_len; + set_sec_data(pieces, IWL_UCODE_INIT, + IWL_UCODE_SECTION_INST, tlv_data); + set_sec_size(pieces, IWL_UCODE_INIT, + IWL_UCODE_SECTION_INST, tlv_len); + set_sec_offset(pieces, IWL_UCODE_INIT, + IWL_UCODE_SECTION_INST, + IWLAGN_RTC_INST_LOWER_BOUND); break; case IWL_UCODE_TLV_INIT_DATA: - pieces->init_data = tlv_data; - pieces->init_data_size = tlv_len; + set_sec_data(pieces, IWL_UCODE_INIT, + IWL_UCODE_SECTION_DATA, tlv_data); + set_sec_size(pieces, IWL_UCODE_INIT, + IWL_UCODE_SECTION_DATA, tlv_len); + set_sec_offset(pieces, IWL_UCODE_INIT, + IWL_UCODE_SECTION_DATA, + IWLAGN_RTC_DATA_LOWER_BOUND); break; case IWL_UCODE_TLV_BOOT: IWL_ERR(drv, "Found unexpected BOOT ucode\n"); @@ -455,12 +563,22 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv, drv->fw.enhance_sensitivity_table = true; break; case IWL_UCODE_TLV_WOWLAN_INST: - pieces->wowlan_inst = tlv_data; - pieces->wowlan_inst_size = tlv_len; + set_sec_data(pieces, IWL_UCODE_WOWLAN, + IWL_UCODE_SECTION_INST, tlv_data); + set_sec_size(pieces, IWL_UCODE_WOWLAN, + IWL_UCODE_SECTION_INST, tlv_len); + set_sec_offset(pieces, IWL_UCODE_WOWLAN, + IWL_UCODE_SECTION_INST, + IWLAGN_RTC_INST_LOWER_BOUND); break; case IWL_UCODE_TLV_WOWLAN_DATA: - pieces->wowlan_data = tlv_data; - pieces->wowlan_data_size = tlv_len; + set_sec_data(pieces, IWL_UCODE_WOWLAN, + IWL_UCODE_SECTION_DATA, tlv_data); + set_sec_size(pieces, IWL_UCODE_WOWLAN, + IWL_UCODE_SECTION_DATA, tlv_len); + set_sec_offset(pieces, IWL_UCODE_WOWLAN, + IWL_UCODE_SECTION_DATA, + IWLAGN_RTC_DATA_LOWER_BOUND); break; case IWL_UCODE_TLV_PHY_CALIBRATION_SIZE: if (tlv_len != sizeof(u32)) @@ -502,7 +620,7 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) struct iwl_fw *fw = &drv->fw; struct iwl_ucode_header *ucode; int err; - struct iwlagn_firmware_pieces pieces; + struct iwl_firmware_pieces pieces; const unsigned int api_max = cfg->ucode_api_max; unsigned int api_ok = cfg->ucode_api_ok; const unsigned int api_min = cfg->ucode_api_min; @@ -588,36 +706,46 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) IWL_DEBUG_INFO(drv, "f/w package hdr ucode version raw = 0x%x\n", drv->fw.ucode_ver); IWL_DEBUG_INFO(drv, "f/w package hdr runtime inst size = %Zd\n", - pieces.inst_size); + get_sec_size(&pieces, IWL_UCODE_REGULAR, + IWL_UCODE_SECTION_INST)); IWL_DEBUG_INFO(drv, "f/w package hdr runtime data size = %Zd\n", - pieces.data_size); + get_sec_size(&pieces, IWL_UCODE_REGULAR, + IWL_UCODE_SECTION_DATA)); IWL_DEBUG_INFO(drv, "f/w package hdr init inst size = %Zd\n", - pieces.init_size); + get_sec_size(&pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_INST)); IWL_DEBUG_INFO(drv, "f/w package hdr init data size = %Zd\n", - pieces.init_data_size); + get_sec_size(&pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_DATA)); /* Verify that uCode images will fit in card's SRAM */ - if (pieces.inst_size > cfg->max_inst_size) { + if (get_sec_size(&pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_INST) > + cfg->max_inst_size) { IWL_ERR(drv, "uCode instr len %Zd too large to fit in\n", - pieces.inst_size); + get_sec_size(&pieces, IWL_UCODE_REGULAR, + IWL_UCODE_SECTION_INST)); goto try_again; } - if (pieces.data_size > cfg->max_data_size) { + if (get_sec_size(&pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_DATA) > + cfg->max_data_size) { IWL_ERR(drv, "uCode data len %Zd too large to fit in\n", - pieces.data_size); + get_sec_size(&pieces, IWL_UCODE_REGULAR, + IWL_UCODE_SECTION_DATA)); goto try_again; } - if (pieces.init_size > cfg->max_inst_size) { + if (get_sec_size(&pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_INST) > + cfg->max_inst_size) { IWL_ERR(drv, "uCode init instr len %Zd too large to fit in\n", - pieces.init_size); + get_sec_size(&pieces, IWL_UCODE_INIT, + IWL_UCODE_SECTION_INST)); goto try_again; } - if (pieces.init_data_size > cfg->max_data_size) { + if (get_sec_size(&pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_DATA) > + cfg->max_data_size) { IWL_ERR(drv, "uCode init data len %Zd too large to fit in\n", - pieces.init_data_size); + get_sec_size(&pieces, IWL_UCODE_REGULAR, + IWL_UCODE_SECTION_DATA)); goto try_again; } @@ -627,35 +755,35 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) * 1) unmodified from disk * 2) backup cache for save/restore during power-downs */ if (iwl_alloc_fw_desc(drv, &drv->fw.ucode_rt.code, - pieces.inst, pieces.inst_size)) + get_sec(&pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_INST))) goto err_pci_alloc; if (iwl_alloc_fw_desc(drv, &drv->fw.ucode_rt.data, - pieces.data, pieces.data_size)) + get_sec(&pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_DATA))) goto err_pci_alloc; /* Initialization instructions and data */ - if (pieces.init_size && pieces.init_data_size) { - if (iwl_alloc_fw_desc(drv, - &drv->fw.ucode_init.code, - pieces.init, pieces.init_size)) + if (get_sec_size(&pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_INST) && + get_sec_size(&pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_DATA)) { + if (iwl_alloc_fw_desc(drv, &drv->fw.ucode_init.code, + get_sec(&pieces, IWL_UCODE_INIT, + IWL_UCODE_SECTION_INST))) goto err_pci_alloc; - if (iwl_alloc_fw_desc(drv, - &drv->fw.ucode_init.data, - pieces.init_data, pieces.init_data_size)) + if (iwl_alloc_fw_desc(drv, &drv->fw.ucode_init.data, + get_sec(&pieces, IWL_UCODE_INIT, + IWL_UCODE_SECTION_DATA))) goto err_pci_alloc; } /* WoWLAN instructions and data */ - if (pieces.wowlan_inst_size && pieces.wowlan_data_size) { - if (iwl_alloc_fw_desc(drv, - &drv->fw.ucode_wowlan.code, - pieces.wowlan_inst, - pieces.wowlan_inst_size)) + if (get_sec_size(&pieces, IWL_UCODE_WOWLAN, IWL_UCODE_SECTION_INST) && + get_sec_size(&pieces, IWL_UCODE_WOWLAN, IWL_UCODE_SECTION_DATA)) { + if (iwl_alloc_fw_desc(drv, &drv->fw.ucode_wowlan.code, + get_sec(&pieces, IWL_UCODE_WOWLAN, + IWL_UCODE_SECTION_INST))) goto err_pci_alloc; - if (iwl_alloc_fw_desc(drv, - &drv->fw.ucode_wowlan.data, - pieces.wowlan_data, - pieces.wowlan_data_size)) + if (iwl_alloc_fw_desc(drv, &drv->fw.ucode_wowlan.data, + get_sec(&pieces, IWL_UCODE_WOWLAN, + IWL_UCODE_SECTION_DATA))) goto err_pci_alloc; } diff --git a/drivers/net/wireless/iwlwifi/iwl-fw.h b/drivers/net/wireless/iwlwifi/iwl-fw.h index 453812a21176..253f7e501d46 100644 --- a/drivers/net/wireless/iwlwifi/iwl-fw.h +++ b/drivers/net/wireless/iwlwifi/iwl-fw.h @@ -91,11 +91,12 @@ struct iwl_ucode_capabilities { u32 flags; }; -/* one for each uCode image (inst/data, boot/init/runtime) */ +/* one for each uCode image (inst/data, init/runtime/wowlan) */ struct fw_desc { dma_addr_t p_addr; /* hardware address */ void *v_addr; /* software address */ u32 len; /* size in bytes */ + u32 offset; /* offset in the device */ }; struct fw_img { diff --git a/drivers/net/wireless/iwlwifi/iwl-shared.h b/drivers/net/wireless/iwlwifi/iwl-shared.h index 4cd2eced8a4c..d899c5c40e07 100644 --- a/drivers/net/wireless/iwlwifi/iwl-shared.h +++ b/drivers/net/wireless/iwlwifi/iwl-shared.h @@ -205,6 +205,7 @@ enum iwl_ucode_type { IWL_UCODE_REGULAR, IWL_UCODE_INIT, IWL_UCODE_WOWLAN, + IWL_UCODE_TYPE_MAX, }; /* -- cgit From ed8c8365c4431eeb733def3dd314cf303e1b12ea Mon Sep 17 00:00:00 2001 From: David Spinadel Date: Sat, 10 Mar 2012 13:00:13 -0800 Subject: iwlwifi: Add TLVs and fields for 16.0 uCode New TLVs for ucode sections that are not known as instruction or data. New TLVs for phy-configuration and default calibrations. Add default calib and phy config fields to iwl_fw. Signed-off-by: David Spinadel Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-drv.c | 84 ++++++++++++++++++++++++++++++ drivers/net/wireless/iwlwifi/iwl-fw-file.h | 5 ++ drivers/net/wireless/iwlwifi/iwl-fw.h | 19 +++++++ drivers/net/wireless/iwlwifi/iwl-shared.h | 16 ------ 4 files changed, 108 insertions(+), 16 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.c b/drivers/net/wireless/iwlwifi/iwl-drv.c index a21af3df6c8a..19ccd36a55b3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-drv.c +++ b/drivers/net/wireless/iwlwifi/iwl-drv.c @@ -208,6 +208,25 @@ struct fw_img_parsing { int sec_counter; }; +/* + * struct fw_sec_parsing: to extract fw section and it's offset from tlv + */ +struct fw_sec_parsing { + __le32 offset; + const u8 data[]; +} __packed; + +/** + * struct iwl_tlv_calib_data - parse the default calib data from TLV + * + * @ucode_type: the uCode to which the following default calib relates. + * @calib: default calibrations. + */ +struct iwl_tlv_calib_data { + __le32 ucode_type; + __le64 calib; +} __packed; + struct iwl_firmware_pieces { struct fw_img_parsing img[IWL_UCODE_TYPE_MAX]; @@ -257,6 +276,47 @@ static void set_sec_offset(struct iwl_firmware_pieces *pieces, pieces->img[type].sec[sec].offset = offset; } +/* + * Gets uCode section from tlv. + */ +static int iwl_store_ucode_sec(struct iwl_firmware_pieces *pieces, + const void *data, enum iwl_ucode_type type, + int size) +{ + struct fw_img_parsing *img; + struct fw_sec *sec; + struct fw_sec_parsing *sec_parse; + + if (WARN_ON(!pieces || !data || type >= IWL_UCODE_TYPE_MAX)) + return -1; + + sec_parse = (struct fw_sec_parsing *)data; + + img = &pieces->img[type]; + sec = &img->sec[img->sec_counter]; + + sec->offset = le32_to_cpu(sec_parse->offset); + sec->data = sec_parse->data; + + ++img->sec_counter; + + return 0; +} + +static int iwl_set_default_calib(struct iwl_drv *drv, const u8 *data) +{ + struct iwl_tlv_calib_data *def_calib = + (struct iwl_tlv_calib_data *)data; + u32 ucode_type = le32_to_cpu(def_calib->ucode_type); + if (ucode_type >= IWL_UCODE_TYPE_MAX) { + IWL_ERR(drv, "Wrong ucode_type %u for default calibration.\n", + ucode_type); + return -EINVAL; + } + drv->fw.default_calib[ucode_type] = le64_to_cpu(def_calib->calib); + return 0; +} + static int iwl_parse_v1_v2_firmware(struct iwl_drv *drv, const struct firmware *ucode_raw, struct iwl_firmware_pieces *pieces) @@ -586,6 +646,29 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv, capa->standard_phy_calibration_size = le32_to_cpup((__le32 *)tlv_data); break; + case IWL_UCODE_TLV_SEC_RT: + iwl_store_ucode_sec(pieces, tlv_data, IWL_UCODE_REGULAR, + tlv_len); + break; + case IWL_UCODE_TLV_SEC_INIT: + iwl_store_ucode_sec(pieces, tlv_data, IWL_UCODE_INIT, + tlv_len); + break; + case IWL_UCODE_TLV_SEC_WOWLAN: + iwl_store_ucode_sec(pieces, tlv_data, IWL_UCODE_WOWLAN, + tlv_len); + break; + case IWL_UCODE_TLV_DEF_CALIB: + if (tlv_len != sizeof(struct iwl_tlv_calib_data)) + goto invalid_tlv_len; + if (iwl_set_default_calib(drv, tlv_data)) + goto tlv_error; + break; + case IWL_UCODE_TLV_PHY_SKU: + if (tlv_len != sizeof(u32)) + goto invalid_tlv_len; + drv->fw.phy_config = le32_to_cpup((__le32 *)tlv_data); + break; default: IWL_DEBUG_INFO(drv, "unknown TLV: %d\n", tlv_type); break; @@ -602,6 +685,7 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv, invalid_tlv_len: IWL_ERR(drv, "TLV %d has invalid size: %u\n", tlv_type, tlv_len); + tlv_error: iwl_print_hex_dump(drv, IWL_DL_FW, tlv_data, tlv_len); return -EINVAL; diff --git a/drivers/net/wireless/iwlwifi/iwl-fw-file.h b/drivers/net/wireless/iwlwifi/iwl-fw-file.h index 7ca6c9526357..c924ccb93c8c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-fw-file.h +++ b/drivers/net/wireless/iwlwifi/iwl-fw-file.h @@ -124,6 +124,11 @@ enum iwl_ucode_tlv_type { IWL_UCODE_TLV_WOWLAN_INST = 16, IWL_UCODE_TLV_WOWLAN_DATA = 17, IWL_UCODE_TLV_FLAGS = 18, + IWL_UCODE_TLV_SEC_RT = 19, + IWL_UCODE_TLV_SEC_INIT = 20, + IWL_UCODE_TLV_SEC_WOWLAN = 21, + IWL_UCODE_TLV_DEF_CALIB = 22, + IWL_UCODE_TLV_PHY_SKU = 23, }; struct iwl_ucode_tlv { diff --git a/drivers/net/wireless/iwlwifi/iwl-fw.h b/drivers/net/wireless/iwlwifi/iwl-fw.h index 253f7e501d46..c99a7fd1d29a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-fw.h +++ b/drivers/net/wireless/iwlwifi/iwl-fw.h @@ -85,6 +85,22 @@ enum iwl_ucode_tlv_flag { #define IWL_MAX_STANDARD_PHY_CALIBRATE_TBL_SIZE 19 #define IWL_MAX_PHY_CALIBRATE_TBL_SIZE 253 +/** + * enum iwl_ucode_type + * + * The type of ucode. + * + * @IWL_UCODE_REGULAR: Normal runtime ucode + * @IWL_UCODE_INIT: Initial ucode + * @IWL_UCODE_WOWLAN: Wake on Wireless enabled ucode + */ +enum iwl_ucode_type { + IWL_UCODE_REGULAR, + IWL_UCODE_INIT, + IWL_UCODE_WOWLAN, + IWL_UCODE_TYPE_MAX, +}; + struct iwl_ucode_capabilities { u32 max_probe_length; u32 standard_phy_calibration_size; @@ -142,6 +158,9 @@ struct iwl_fw { u32 init_evtlog_ptr, init_evtlog_size, init_errlog_ptr; u32 inst_evtlog_ptr, inst_evtlog_size, inst_errlog_ptr; + + u64 default_calib[IWL_UCODE_TYPE_MAX]; + u32 phy_config; }; #endif /* __iwl_fw_h__ */ diff --git a/drivers/net/wireless/iwlwifi/iwl-shared.h b/drivers/net/wireless/iwlwifi/iwl-shared.h index d899c5c40e07..b515d657a0ad 100644 --- a/drivers/net/wireless/iwlwifi/iwl-shared.h +++ b/drivers/net/wireless/iwlwifi/iwl-shared.h @@ -192,22 +192,6 @@ struct iwl_hw_params { const struct iwl_sensitivity_ranges *sens; }; -/** - * enum iwl_ucode_type - * - * The type of ucode. - * - * @IWL_UCODE_REGULAR: Normal runtime ucode - * @IWL_UCODE_INIT: Initial ucode - * @IWL_UCODE_WOWLAN: Wake on Wireless enabled ucode - */ -enum iwl_ucode_type { - IWL_UCODE_REGULAR, - IWL_UCODE_INIT, - IWL_UCODE_WOWLAN, - IWL_UCODE_TYPE_MAX, -}; - /* * LED mode * IWL_LED_DEFAULT: use device default -- cgit From 6dfa8d019cd21d08634ceb65a3fb90d0648bd93b Mon Sep 17 00:00:00 2001 From: David Spinadel Date: Sat, 10 Mar 2012 13:00:14 -0800 Subject: iwlwifi: change struct iwl_fw Change iwl_fw struct to hold an array of fw_img instead of three separated instances. Change fw_img to hold an array of fw_desc instead of two separate descriptors for instructions and data. Change load_given_ucode, load_section, verification functions etc. to support this structure. Signed-off-by: David Spinadel Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-debugfs.c | 17 +--- drivers/net/wireless/iwlwifi/iwl-drv.c | 141 ++++++++++++++------------ drivers/net/wireless/iwlwifi/iwl-fw.h | 25 +++-- drivers/net/wireless/iwlwifi/iwl-mac80211.c | 15 +-- drivers/net/wireless/iwlwifi/iwl-testmode.c | 21 +--- drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | 32 +++--- drivers/net/wireless/iwlwifi/iwl-ucode.c | 29 ++---- 7 files changed, 139 insertions(+), 141 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index 89cb9a7a3b56..b7b1c04f2fba 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c @@ -230,6 +230,7 @@ static ssize_t iwl_dbgfs_sram_read(struct file *file, int pos = 0; int sram; struct iwl_priv *priv = file->private_data; + const struct fw_img *img; size_t bufsz; /* default is to dump the entire data segment */ @@ -239,17 +240,8 @@ static ssize_t iwl_dbgfs_sram_read(struct file *file, IWL_ERR(priv, "No uCode has been loadded.\n"); return -EINVAL; } - if (priv->shrd->ucode_type == IWL_UCODE_INIT) { - priv->dbgfs_sram_len = priv->fw->ucode_init.data.len; - } else if (priv->shrd->ucode_type == IWL_UCODE_REGULAR) { - priv->dbgfs_sram_len = priv->fw->ucode_rt.data.len; - } else if (priv->shrd->ucode_type == IWL_UCODE_WOWLAN) { - priv->dbgfs_sram_len = priv->fw->ucode_wowlan.data.len; - } else { - IWL_ERR(priv, "Unsupported type of uCode loaded?" - " that shouldn't happen.\n"); - return -EINVAL; - } + img = &priv->fw->img[priv->shrd->ucode_type]; + priv->dbgfs_sram_len = img->sec[IWL_UCODE_SECTION_DATA].len; } len = priv->dbgfs_sram_len; @@ -346,13 +338,14 @@ static ssize_t iwl_dbgfs_wowlan_sram_read(struct file *file, size_t count, loff_t *ppos) { struct iwl_priv *priv = file->private_data; + const struct fw_img *img = &priv->fw->img[IWL_UCODE_WOWLAN]; if (!priv->wowlan_sram) return -ENODATA; return simple_read_from_buffer(user_buf, count, ppos, priv->wowlan_sram, - priv->fw->ucode_wowlan.data.len); + img->sec[IWL_UCODE_SECTION_DATA].len); } static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.c b/drivers/net/wireless/iwlwifi/iwl-drv.c index 19ccd36a55b3..54e09696fc9d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-drv.c +++ b/drivers/net/wireless/iwlwifi/iwl-drv.c @@ -118,15 +118,16 @@ static void iwl_free_fw_desc(struct iwl_drv *drv, struct fw_desc *desc) static void iwl_free_fw_img(struct iwl_drv *drv, struct fw_img *img) { - iwl_free_fw_desc(drv, &img->code); - iwl_free_fw_desc(drv, &img->data); + int i; + for (i = 0; i < IWL_UCODE_SECTION_MAX; i++) + iwl_free_fw_desc(drv, &img->sec[i]); } static void iwl_dealloc_ucode(struct iwl_drv *drv) { - iwl_free_fw_img(drv, &drv->fw.ucode_rt); - iwl_free_fw_img(drv, &drv->fw.ucode_init); - iwl_free_fw_img(drv, &drv->fw.ucode_wowlan); + int i; + for (i = 0; i < IWL_UCODE_TYPE_MAX; i++) + iwl_free_fw_img(drv, drv->fw.img + i); } static int iwl_alloc_fw_desc(struct iwl_drv *drv, struct fw_desc *desc, @@ -189,22 +190,8 @@ static int iwl_request_firmware(struct iwl_drv *drv, bool first) GFP_KERNEL, drv, iwl_ucode_callback); } -/* - * enumeration of ucode section. - * This enumeration is used for legacy tlv style (before 16.0 uCode). - */ -enum iwl_ucode_sec { - IWL_UCODE_SECTION_INST, - IWL_UCODE_SECTION_DATA, -}; -/* - * For 16.0 uCode and above, there is no differentiation between section, - * just an offset to the HW address. - */ -#define UCODE_SECTION_MAX 4 - struct fw_img_parsing { - struct fw_sec sec[UCODE_SECTION_MAX]; + struct fw_sec sec[IWL_UCODE_SECTION_MAX]; int sec_counter; }; @@ -691,6 +678,71 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv, return -EINVAL; } +static int alloc_pci_desc(struct iwl_drv *drv, + struct iwl_firmware_pieces *pieces, + enum iwl_ucode_type type) +{ + int i; + for (i = 0; + i < IWL_UCODE_SECTION_MAX && get_sec_size(pieces, type, i); + i++) + if (iwl_alloc_fw_desc(drv, &(drv->fw.img[type].sec[i]), + get_sec(pieces, type, i))) + return -1; + return 0; +} + +static int validate_sec_sizes(struct iwl_drv *drv, + struct iwl_firmware_pieces *pieces, + const struct iwl_cfg *cfg) +{ + IWL_DEBUG_INFO(drv, "f/w package hdr runtime inst size = %Zd\n", + get_sec_size(pieces, IWL_UCODE_REGULAR, + IWL_UCODE_SECTION_INST)); + IWL_DEBUG_INFO(drv, "f/w package hdr runtime data size = %Zd\n", + get_sec_size(pieces, IWL_UCODE_REGULAR, + IWL_UCODE_SECTION_DATA)); + IWL_DEBUG_INFO(drv, "f/w package hdr init inst size = %Zd\n", + get_sec_size(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_INST)); + IWL_DEBUG_INFO(drv, "f/w package hdr init data size = %Zd\n", + get_sec_size(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_DATA)); + + /* Verify that uCode images will fit in card's SRAM. */ + if (get_sec_size(pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_INST) > + cfg->max_inst_size) { + IWL_ERR(drv, "uCode instr len %Zd too large to fit in\n", + get_sec_size(pieces, IWL_UCODE_REGULAR, + IWL_UCODE_SECTION_INST)); + return -1; + } + + if (get_sec_size(pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_DATA) > + cfg->max_data_size) { + IWL_ERR(drv, "uCode data len %Zd too large to fit in\n", + get_sec_size(pieces, IWL_UCODE_REGULAR, + IWL_UCODE_SECTION_DATA)); + return -1; + } + + if (get_sec_size(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_INST) > + cfg->max_inst_size) { + IWL_ERR(drv, "uCode init instr len %Zd too large to fit in\n", + get_sec_size(pieces, IWL_UCODE_INIT, + IWL_UCODE_SECTION_INST)); + return -1; + } + + if (get_sec_size(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_DATA) > + cfg->max_data_size) { + IWL_ERR(drv, "uCode init data len %Zd too large to fit in\n", + get_sec_size(pieces, IWL_UCODE_REGULAR, + IWL_UCODE_SECTION_DATA)); + return -1; + } + return 0; +} + + /** * iwl_ucode_callback - callback when firmware was loaded * @@ -709,6 +761,7 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) unsigned int api_ok = cfg->ucode_api_ok; const unsigned int api_min = cfg->ucode_api_min; u32 api_ver; + int i; fw->ucode_capa.max_probe_length = 200; fw->ucode_capa.standard_phy_calibration_size = @@ -817,59 +870,17 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) goto try_again; } - if (get_sec_size(&pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_INST) > - cfg->max_inst_size) { - IWL_ERR(drv, "uCode init instr len %Zd too large to fit in\n", - get_sec_size(&pieces, IWL_UCODE_INIT, - IWL_UCODE_SECTION_INST)); + if (validate_sec_sizes(drv, &pieces, cfg)) goto try_again; - } - - if (get_sec_size(&pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_DATA) > - cfg->max_data_size) { - IWL_ERR(drv, "uCode init data len %Zd too large to fit in\n", - get_sec_size(&pieces, IWL_UCODE_REGULAR, - IWL_UCODE_SECTION_DATA)); - goto try_again; - } /* Allocate ucode buffers for card's bus-master loading ... */ /* Runtime instructions and 2 copies of data: * 1) unmodified from disk * 2) backup cache for save/restore during power-downs */ - if (iwl_alloc_fw_desc(drv, &drv->fw.ucode_rt.code, - get_sec(&pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_INST))) - goto err_pci_alloc; - if (iwl_alloc_fw_desc(drv, &drv->fw.ucode_rt.data, - get_sec(&pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_DATA))) - goto err_pci_alloc; - - /* Initialization instructions and data */ - if (get_sec_size(&pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_INST) && - get_sec_size(&pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_DATA)) { - if (iwl_alloc_fw_desc(drv, &drv->fw.ucode_init.code, - get_sec(&pieces, IWL_UCODE_INIT, - IWL_UCODE_SECTION_INST))) - goto err_pci_alloc; - if (iwl_alloc_fw_desc(drv, &drv->fw.ucode_init.data, - get_sec(&pieces, IWL_UCODE_INIT, - IWL_UCODE_SECTION_DATA))) + for (i = 0; i < IWL_UCODE_TYPE_MAX; i++) + if (alloc_pci_desc(drv, &pieces, i)) goto err_pci_alloc; - } - - /* WoWLAN instructions and data */ - if (get_sec_size(&pieces, IWL_UCODE_WOWLAN, IWL_UCODE_SECTION_INST) && - get_sec_size(&pieces, IWL_UCODE_WOWLAN, IWL_UCODE_SECTION_DATA)) { - if (iwl_alloc_fw_desc(drv, &drv->fw.ucode_wowlan.code, - get_sec(&pieces, IWL_UCODE_WOWLAN, - IWL_UCODE_SECTION_INST))) - goto err_pci_alloc; - if (iwl_alloc_fw_desc(drv, &drv->fw.ucode_wowlan.data, - get_sec(&pieces, IWL_UCODE_WOWLAN, - IWL_UCODE_SECTION_DATA))) - goto err_pci_alloc; - } /* Now that we can no longer fail, copy information */ diff --git a/drivers/net/wireless/iwlwifi/iwl-fw.h b/drivers/net/wireless/iwlwifi/iwl-fw.h index c99a7fd1d29a..5d634f3db929 100644 --- a/drivers/net/wireless/iwlwifi/iwl-fw.h +++ b/drivers/net/wireless/iwlwifi/iwl-fw.h @@ -101,6 +101,20 @@ enum iwl_ucode_type { IWL_UCODE_TYPE_MAX, }; +/* + * enumeration of ucode section. + * This enumeration is used for legacy tlv style (before 16.0 uCode). + */ +enum iwl_ucode_sec { + IWL_UCODE_SECTION_INST, + IWL_UCODE_SECTION_DATA, +}; +/* + * For 16.0 uCode and above, there is no differentiation between sections, + * just an offset to the HW address. + */ +#define IWL_UCODE_SECTION_MAX 4 + struct iwl_ucode_capabilities { u32 max_probe_length; u32 standard_phy_calibration_size; @@ -116,8 +130,7 @@ struct fw_desc { }; struct fw_img { - struct fw_desc code; /* firmware code image */ - struct fw_desc data; /* firmware data image */ + struct fw_desc sec[IWL_UCODE_SECTION_MAX]; }; /* uCode version contains 4 values: Major/Minor/API/Serial */ @@ -131,9 +144,7 @@ struct fw_img { * * @ucode_ver: ucode version from the ucode file * @fw_version: firmware version string - * @ucode_rt: run time ucode image - * @ucode_init: init ucode image - * @ucode_wowlan: wake on wireless ucode image (optional) + * @img: ucode image like ucode_rt, ucode_init, ucode_wowlan. * @ucode_capa: capabilities parsed from the ucode file. * @enhance_sensitivity_table: device can do enhanced sensitivity. * @init_evtlog_ptr: event log offset for init ucode. @@ -149,9 +160,7 @@ struct iwl_fw { char fw_version[ETHTOOL_BUSINFO_LEN]; /* ucode images */ - struct fw_img ucode_rt; - struct fw_img ucode_init; - struct fw_img ucode_wowlan; + struct fw_img img[IWL_UCODE_TYPE_MAX]; struct iwl_ucode_capabilities ucode_capa; bool enhance_sensitivity_table; diff --git a/drivers/net/wireless/iwlwifi/iwl-mac80211.c b/drivers/net/wireless/iwlwifi/iwl-mac80211.c index 9212ee3bef9b..b6805f8e9a01 100644 --- a/drivers/net/wireless/iwlwifi/iwl-mac80211.c +++ b/drivers/net/wireless/iwlwifi/iwl-mac80211.c @@ -196,7 +196,7 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv, WIPHY_FLAG_DISABLE_BEACON_HINTS | WIPHY_FLAG_IBSS_RSN; - if (priv->fw->ucode_wowlan.code.len && + if (priv->fw->img[IWL_UCODE_WOWLAN].sec[0].len && trans(priv)->ops->wowlan_suspend && device_can_wakeup(trans(priv)->dev)) { hw->wiphy->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT | @@ -437,6 +437,7 @@ static int iwlagn_mac_resume(struct ieee80211_hw *hw) unsigned long flags; u32 base, status = 0xffffffff; int ret = -EIO; + const struct fw_img *img; IWL_DEBUG_MAC80211(priv, "enter\n"); mutex_lock(&priv->mutex); @@ -457,16 +458,18 @@ static int iwlagn_mac_resume(struct ieee80211_hw *hw) #ifdef CONFIG_IWLWIFI_DEBUGFS if (ret == 0) { - if (!priv->wowlan_sram) + img = &(priv->fw->img[IWL_UCODE_WOWLAN]); + if (!priv->wowlan_sram) { priv->wowlan_sram = - kzalloc(priv->fw->ucode_wowlan.data.len, + kzalloc(img->sec[IWL_UCODE_SECTION_DATA].len, GFP_KERNEL); + } if (priv->wowlan_sram) _iwl_read_targ_mem_words( - trans(priv), 0x800000, - priv->wowlan_sram, - priv->fw->ucode_wowlan.data.len / 4); + trans(priv), 0x800000, + priv->wowlan_sram, + img->sec[IWL_UCODE_SECTION_DATA].len / 4); } #endif } diff --git a/drivers/net/wireless/iwlwifi/iwl-testmode.c b/drivers/net/wireless/iwlwifi/iwl-testmode.c index c6c084f45b72..76f7f9251436 100644 --- a/drivers/net/wireless/iwlwifi/iwl-testmode.c +++ b/drivers/net/wireless/iwlwifi/iwl-testmode.c @@ -466,6 +466,7 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb) unsigned char *rsp_data_ptr = NULL; int status = 0, rsp_data_len = 0; u32 devid, inst_size = 0, data_size = 0; + const struct fw_img *img; switch (nla_get_u32(tb[IWL_TM_ATTR_COMMAND])) { case IWL_TM_CMD_APP2DEV_GET_DEVICENAME: @@ -597,23 +598,9 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb) IWL_ERR(priv, "No uCode has not been loaded\n"); return -EINVAL; } else { - switch (priv->shrd->ucode_type) { - case IWL_UCODE_REGULAR: - inst_size = priv->fw->ucode_rt.code.len; - data_size = priv->fw->ucode_rt.data.len; - break; - case IWL_UCODE_INIT: - inst_size = priv->fw->ucode_init.code.len; - data_size = priv->fw->ucode_init.data.len; - break; - case IWL_UCODE_WOWLAN: - inst_size = priv->fw->ucode_wowlan.code.len; - data_size = priv->fw->ucode_wowlan.data.len; - break; - default: - IWL_ERR(priv, "Unsupported uCode type\n"); - break; - } + img = &priv->fw->img[priv->shrd->ucode_type]; + inst_size = img->sec[IWL_UCODE_SECTION_INST].len; + data_size = img->sec[IWL_UCODE_SECTION_DATA].len; } NLA_PUT_U32(skb, IWL_TM_ATTR_FW_TYPE, priv->shrd->ucode_type); NLA_PUT_U32(skb, IWL_TM_ATTR_FW_INST_SIZE, inst_size); diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c index 0e8e31a53c7a..b4f796c82e1e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c @@ -951,12 +951,13 @@ static const u8 iwlagn_pan_ac_to_queue[] = { /* * ucode */ -static int iwl_load_section(struct iwl_trans *trans, const char *name, - const struct fw_desc *image, u32 dst_addr) +static int iwl_load_section(struct iwl_trans *trans, u8 section_num, + const struct fw_desc *section) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); - dma_addr_t phy_addr = image->p_addr; - u32 byte_cnt = image->len; + dma_addr_t phy_addr = section->p_addr; + u32 byte_cnt = section->len; + u32 dst_addr = section->offset; int ret; trans_pcie->ucode_write_complete = false; @@ -989,12 +990,13 @@ static int iwl_load_section(struct iwl_trans *trans, const char *name, FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_DISABLE | FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_ENDTFD); - IWL_DEBUG_FW(trans, "%s uCode section being loaded...\n", name); + IWL_DEBUG_FW(trans, "[%d] uCode section being loaded...\n", + section_num); ret = wait_event_timeout(trans_pcie->ucode_write_waitq, trans_pcie->ucode_write_complete, 5 * HZ); if (!ret) { - IWL_ERR(trans, "Could not load the %s uCode section\n", - name); + IWL_ERR(trans, "Could not load the [%d] uCode section\n", + section_num); return -ETIMEDOUT; } @@ -1005,16 +1007,16 @@ static int iwl_load_given_ucode(struct iwl_trans *trans, const struct fw_img *image) { int ret = 0; + int i; - ret = iwl_load_section(trans, "INST", &image->code, - IWLAGN_RTC_INST_LOWER_BOUND); - if (ret) - return ret; + for (i = 0; i < IWL_UCODE_SECTION_MAX; i++) { + if (!image->sec[i].p_addr) + break; - ret = iwl_load_section(trans, "DATA", &image->data, - IWLAGN_RTC_DATA_LOWER_BOUND); - if (ret) - return ret; + ret = iwl_load_section(trans, i, &image->sec[i]); + if (ret) + return ret; + } /* Remove all resets to allow NIC to operate */ iwl_write32(trans, CSR_RESET, 0); diff --git a/drivers/net/wireless/iwlwifi/iwl-ucode.c b/drivers/net/wireless/iwlwifi/iwl-ucode.c index 0908880dd7ac..252828728837 100644 --- a/drivers/net/wireless/iwlwifi/iwl-ucode.c +++ b/drivers/net/wireless/iwlwifi/iwl-ucode.c @@ -80,17 +80,10 @@ static struct iwl_wimax_coex_event_entry cu_priorities[COEX_NUM_OF_EVENTS] = { static inline const struct fw_img * iwl_get_ucode_image(struct iwl_priv *priv, enum iwl_ucode_type ucode_type) { - switch (ucode_type) { - case IWL_UCODE_INIT: - return &priv->fw->ucode_init; - case IWL_UCODE_WOWLAN: - return &priv->fw->ucode_wowlan; - case IWL_UCODE_REGULAR: - return &priv->fw->ucode_rt; - default: - break; - } - return NULL; + if (ucode_type >= IWL_UCODE_TYPE_MAX) + return NULL; + + return &priv->fw->img[ucode_type]; } /* @@ -342,7 +335,7 @@ static int iwl_alive_notify(struct iwl_priv *priv) * using sample data 100 bytes apart. If these sample points are good, * it's a pretty good bet that everything between them is good, too. */ -static int iwl_verify_inst_sparse(struct iwl_priv *priv, +static int iwl_verify_sec_sparse(struct iwl_priv *priv, const struct fw_desc *fw_desc) { __le32 *image = (__le32 *)fw_desc->v_addr; @@ -357,7 +350,7 @@ static int iwl_verify_inst_sparse(struct iwl_priv *priv, /* NOTE: Use the debugless read so we don't flood kernel log * if IWL_DL_IO is set */ iwl_write_direct32(trans(priv), HBUS_TARG_MEM_RADDR, - i + IWLAGN_RTC_INST_LOWER_BOUND); + i + fw_desc->offset); val = iwl_read32(trans(priv), HBUS_TARG_MEM_RDAT); if (val != le32_to_cpu(*image)) return -EIO; @@ -366,7 +359,7 @@ static int iwl_verify_inst_sparse(struct iwl_priv *priv, return 0; } -static void iwl_print_mismatch_inst(struct iwl_priv *priv, +static void iwl_print_mismatch_sec(struct iwl_priv *priv, const struct fw_desc *fw_desc) { __le32 *image = (__le32 *)fw_desc->v_addr; @@ -378,7 +371,7 @@ static void iwl_print_mismatch_inst(struct iwl_priv *priv, IWL_DEBUG_FW(priv, "ucode inst image size is %u\n", len); iwl_write_direct32(trans(priv), HBUS_TARG_MEM_RADDR, - IWLAGN_RTC_INST_LOWER_BOUND); + fw_desc->offset); for (offs = 0; offs < len && errors < 20; @@ -408,14 +401,14 @@ static int iwl_verify_ucode(struct iwl_priv *priv, return -EINVAL; } - if (!iwl_verify_inst_sparse(priv, &img->code)) { + if (!iwl_verify_sec_sparse(priv, &img->sec[IWL_UCODE_SECTION_INST])) { IWL_DEBUG_FW(priv, "uCode is good in inst SRAM\n"); return 0; } IWL_ERR(priv, "UCODE IMAGE IN INSTRUCTION SRAM NOT VALID!!\n"); - iwl_print_mismatch_inst(priv, &img->code); + iwl_print_mismatch_sec(priv, &img->sec[IWL_UCODE_SECTION_INST]); return -EIO; } @@ -534,7 +527,7 @@ int iwl_run_init_ucode(struct iwl_priv *priv) lockdep_assert_held(&priv->mutex); /* No init ucode required? Curious, but maybe ok */ - if (!priv->fw->ucode_init.code.len) + if (!priv->fw->img[IWL_UCODE_INIT].sec[0].len) return 0; if (priv->init_ucode_run) -- cgit From 4db2c9aeb28762ea7416122d03a7e5c8d87eb924 Mon Sep 17 00:00:00 2001 From: David Spinadel Date: Sat, 10 Mar 2012 13:00:15 -0800 Subject: iwlwifi: Add bool mvm_ucode to iwl_fw mvm_ucode is true when mvm TLVs arive. Signed-off-by: David Spinadel Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-drv.c | 9 ++++++++- drivers/net/wireless/iwlwifi/iwl-fw.h | 2 ++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.c b/drivers/net/wireless/iwlwifi/iwl-drv.c index 54e09696fc9d..6f312c77af5e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-drv.c +++ b/drivers/net/wireless/iwlwifi/iwl-drv.c @@ -636,14 +636,17 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv, case IWL_UCODE_TLV_SEC_RT: iwl_store_ucode_sec(pieces, tlv_data, IWL_UCODE_REGULAR, tlv_len); + drv->fw.mvm_fw = true; break; case IWL_UCODE_TLV_SEC_INIT: iwl_store_ucode_sec(pieces, tlv_data, IWL_UCODE_INIT, tlv_len); + drv->fw.mvm_fw = true; break; case IWL_UCODE_TLV_SEC_WOWLAN: iwl_store_ucode_sec(pieces, tlv_data, IWL_UCODE_WOWLAN, tlv_len); + drv->fw.mvm_fw = true; break; case IWL_UCODE_TLV_DEF_CALIB: if (tlv_len != sizeof(struct iwl_tlv_calib_data)) @@ -870,7 +873,11 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) goto try_again; } - if (validate_sec_sizes(drv, &pieces, cfg)) + /* + * In mvm uCode there is no difference between data and instructions + * sections. + */ + if (!fw->mvm_fw && validate_sec_sizes(drv, &pieces, cfg)) goto try_again; /* Allocate ucode buffers for card's bus-master loading ... */ diff --git a/drivers/net/wireless/iwlwifi/iwl-fw.h b/drivers/net/wireless/iwlwifi/iwl-fw.h index 5d634f3db929..8e36bdc1e522 100644 --- a/drivers/net/wireless/iwlwifi/iwl-fw.h +++ b/drivers/net/wireless/iwlwifi/iwl-fw.h @@ -170,6 +170,8 @@ struct iwl_fw { u64 default_calib[IWL_UCODE_TYPE_MAX]; u32 phy_config; + + bool mvm_fw; }; #endif /* __iwl_fw_h__ */ -- cgit From de5036aae635b7ea5a920e56fcf074a333b325ca Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 8 Mar 2012 15:02:03 +0100 Subject: mac80211: move misplaced comment Looks like some changes in this area moved the code but not the comment that belongs to the code, move it to the right place. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/mlme.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 5c2ba80c2932..059a4eba9fec 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -3274,6 +3274,13 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, ifmgd->beacon_crc_valid = false; + /* + * IEEE802.11n does not allow TKIP/WEP as pairwise ciphers in HT mode. + * We still associate in non-HT mode (11a/b/g) if any one of these + * ciphers is configured as pairwise. + * We can set this to true for non-11n hardware, that'll be checked + * separately along with the peer capabilities. + */ for (i = 0; i < req->crypto.n_ciphers_pairwise; i++) if (req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_WEP40 || req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_TKIP || @@ -3302,13 +3309,6 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, } else ifmgd->ap_smps = ifmgd->req_smps; - /* - * IEEE802.11n does not allow TKIP/WEP as pairwise ciphers in HT mode. - * We still associate in non-HT mode (11a/b/g) if any one of these - * ciphers is configured as pairwise. - * We can set this to true for non-11n hardware, that'll be checked - * separately along with the peer capabilities. - */ assoc_data->capability = req->bss->capability; assoc_data->wmm_used = bss->wmm_used; assoc_data->supp_rates = bss->supp_rates; -- cgit From 4e74bfdb30f79e9bf87aa359eff29fbdb93cc12a Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 8 Mar 2012 15:02:04 +0100 Subject: mac80211: simplify HT checks Always set/use IEEE80211_STA_DISABLE_11N instead of duplicating the queue, WMM and HT checks in all places. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/mlme.c | 57 ++++++++++++++++++++++++----------------------------- 1 file changed, 26 insertions(+), 31 deletions(-) diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 059a4eba9fec..5dfc1e8a1a22 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -192,33 +192,27 @@ static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata, enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT; sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; - prev_chantype = sdata->vif.bss_conf.channel_type; - /* HT is not supported */ - if (!sband->ht_cap.ht_supported) - enable_ht = false; - if (enable_ht) { - hti_cfreq = ieee80211_channel_to_frequency(hti->control_chan, - sband->band); - /* check that channel matches the right operating channel */ - if (local->hw.conf.channel->center_freq != hti_cfreq) { - /* Some APs mess this up, evidently. - * Netgear WNDR3700 sometimes reports 4 higher than - * the actual channel, for instance. - */ - printk(KERN_DEBUG - "%s: Wrong control channel in association" - " response: configured center-freq: %d" - " hti-cfreq: %d hti->control_chan: %d" - " band: %d. Disabling HT.\n", - sdata->name, - local->hw.conf.channel->center_freq, - hti_cfreq, hti->control_chan, - sband->band); - enable_ht = false; - } + hti_cfreq = ieee80211_channel_to_frequency(hti->control_chan, + sband->band); + /* check that channel matches the right operating channel */ + if (local->hw.conf.channel->center_freq != hti_cfreq) { + /* Some APs mess this up, evidently. + * Netgear WNDR3700 sometimes reports 4 higher than + * the actual channel, for instance. + */ + printk(KERN_DEBUG + "%s: Wrong control channel in association" + " response: configured center-freq: %d" + " hti-cfreq: %d hti->control_chan: %d" + " band: %d. Disabling HT.\n", + sdata->name, + local->hw.conf.channel->center_freq, + hti_cfreq, hti->control_chan, + sband->band); + enable_ht = false; } if (enable_ht) { @@ -335,9 +329,6 @@ static void ieee80211_add_ht_ie(struct ieee80211_sub_if_data *sdata, BUILD_BUG_ON(sizeof(ht_cap) != sizeof(sband->ht_cap)); - if (!sband->ht_cap.ht_supported) - return; - if (!ht_info_ie) return; @@ -405,7 +396,6 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata) u16 capab; struct ieee80211_supported_band *sband; u32 rates = 0; - struct ieee80211_bss *bss = (void *)assoc_data->bss->priv; lockdep_assert_held(&ifmgd->mtx); @@ -566,8 +556,7 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata) offset = noffset; } - if (!(ifmgd->flags & IEEE80211_STA_DISABLE_11N) && - bss->wmm_used && local->hw.queues >= 4) + if (!(ifmgd->flags & IEEE80211_STA_DISABLE_11N)) ieee80211_add_ht_ie(sdata, skb, assoc_data->ht_information_ie, sband, local->oper_channel, ifmgd->ap_smps); @@ -2147,7 +2136,6 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata, changed |= BSS_CHANGED_QOS; if (elems.ht_info_elem && elems.wmm_param && - (sdata->local->hw.queues >= 4) && !(ifmgd->flags & IEEE80211_STA_DISABLE_11N)) changed |= ieee80211_enable_ht(sdata, elems.ht_info_elem, cbss->bssid, ap_ht_cap_flags, @@ -3232,6 +3220,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; struct ieee80211_bss *bss = (void *)req->bss->priv; struct ieee80211_mgd_assoc_data *assoc_data; + struct ieee80211_supported_band *sband; struct sta_info *sta; const u8 *ssidie; int i, err; @@ -3290,6 +3279,12 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, if (req->flags & ASSOC_REQ_DISABLE_HT) ifmgd->flags |= IEEE80211_STA_DISABLE_11N; + /* Also disable HT if we don't support it or the AP doesn't use WMM */ + sband = local->hw.wiphy->bands[req->bss->channel->band]; + if (!sband->ht_cap.ht_supported || + local->hw.queues < 4 || !bss->wmm_used) + ifmgd->flags |= IEEE80211_STA_DISABLE_11N; + memcpy(&ifmgd->ht_capa, &req->ht_capa, sizeof(ifmgd->ht_capa)); memcpy(&ifmgd->ht_capa_mask, &req->ht_capa_mask, sizeof(ifmgd->ht_capa_mask)); -- cgit From 76f0303d61b3c7f1918ab63a64e77450a4418a60 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 8 Mar 2012 15:02:05 +0100 Subject: mac80211: simplify wmm check during association Instead of setting assoc_data->wmm_used solely based on the BSS also take into account our own capabilities and later check those. Also rename "wmm_used" and "uapsd_used" to just "wmm" and "uapsd". Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/ieee80211_i.h | 2 +- net/mac80211/mlme.c | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 3c62ded64e32..173c1396070d 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -407,7 +407,7 @@ struct ieee80211_mgd_assoc_data { u8 ssid[IEEE80211_MAX_SSID_LEN]; u8 ssid_len; u8 supp_rates_len; - bool wmm_used, uapsd_used; + bool wmm, uapsd; bool have_beacon; bool sent_assoc; bool synced; diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 5dfc1e8a1a22..b60768368ce5 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -570,8 +570,8 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata) offset = noffset; } - if (assoc_data->wmm_used && local->hw.queues >= 4) { - if (assoc_data->uapsd_used) { + if (assoc_data->wmm) { + if (assoc_data->uapsd) { qos_info = local->uapsd_queues; qos_info |= (local->uapsd_max_sp_len << IEEE80211_WMM_IE_STA_QOSINFO_SP_SHIFT); @@ -3305,7 +3305,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, ifmgd->ap_smps = ifmgd->req_smps; assoc_data->capability = req->bss->capability; - assoc_data->wmm_used = bss->wmm_used; + assoc_data->wmm = bss->wmm_used && (local->hw.queues >= 4); assoc_data->supp_rates = bss->supp_rates; assoc_data->supp_rates_len = bss->supp_rates_len; assoc_data->ht_information_ie = @@ -3313,10 +3313,10 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, if (bss->wmm_used && bss->uapsd_supported && (sdata->local->hw.flags & IEEE80211_HW_SUPPORTS_UAPSD)) { - assoc_data->uapsd_used = true; + assoc_data->uapsd = true; ifmgd->flags |= IEEE80211_STA_UAPSD_ENABLED; } else { - assoc_data->uapsd_used = false; + assoc_data->uapsd = false; ifmgd->flags &= ~IEEE80211_STA_UAPSD_ENABLED; } -- cgit From 0775f9f90cdaf40fbf69b3192b3dddb2b3436f45 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 8 Mar 2012 15:02:06 +0100 Subject: mac80211: remove spurious BSSID change flag The BSSID has been set a lot earlier already and didn't change again in ieee80211_set_associated(). Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/mlme.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index b60768368ce5..5c82354d18c4 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -1351,9 +1351,6 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata, */ bss_info_changed |= BSS_CHANGED_BASIC_RATES; - /* And the BSSID changed - we're associated now */ - bss_info_changed |= BSS_CHANGED_BSSID; - /* Tell the driver to monitor connection quality (if supported) */ if (sdata->vif.driver_flags & IEEE80211_VIF_SUPPORTS_CQM_RSSI && bss_conf->cqm_rssi_thold) -- cgit From a1cf775deae9d0f1e5475337ab13c593ad427cee Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 8 Mar 2012 15:02:07 +0100 Subject: mac80211: refactor common auth/assoc setup code As associating is possible without first authenticating (for FT over DS) association also has to be able to switch to the right channel, insert the station entry etc. Factor out this common code into a new function called ieee80211_prep_connection(). Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/mlme.c | 121 +++++++++++++++++++++++++--------------------------- 1 file changed, 59 insertions(+), 62 deletions(-) diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 5c82354d18c4..81e0124e68ce 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -3089,6 +3089,60 @@ int ieee80211_max_network_latency(struct notifier_block *nb, return 0; } +static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata, + struct cfg80211_bss *bss, bool assoc) +{ + struct ieee80211_local *local = sdata->local; + struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; + struct sta_info *sta; + bool have_sta = false; + int err; + + if (WARN_ON(!ifmgd->auth_data && !ifmgd->assoc_data)) + return -EINVAL; + + if (assoc) { + rcu_read_lock(); + have_sta = sta_info_get(sdata, bss->bssid); + rcu_read_unlock(); + } + + if (!have_sta) { + sta = sta_info_alloc(sdata, bss->bssid, GFP_KERNEL); + if (!sta) + return -ENOMEM; + } + + mutex_lock(&local->mtx); + ieee80211_recalc_idle(sdata->local); + mutex_unlock(&local->mtx); + + /* switch to the right channel */ + local->oper_channel = bss->channel; + ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); + + if (!have_sta) { + /* set BSSID - if STA already there this will be set too */ + memcpy(ifmgd->bssid, bss->bssid, ETH_ALEN); + ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BSSID); + + if (assoc) + sta_info_pre_move_state(sta, IEEE80211_STA_AUTH); + + err = sta_info_insert(sta); + sta = NULL; + if (err) { + printk(KERN_DEBUG + "%s: failed to insert STA entry for the AP (error %d)\n", + sdata->name, err); + return err; + } + } else + WARN_ON_ONCE(compare_ether_addr(ifmgd->bssid, bss->bssid)); + + return 0; +} + /* config hooks */ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata, struct cfg80211_auth_request *req) @@ -3096,7 +3150,6 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata, struct ieee80211_local *local = sdata->local; struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; struct ieee80211_mgd_auth_data *auth_data; - struct sta_info *sta; u16 auth_alg; int err; @@ -3162,32 +3215,9 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata, printk(KERN_DEBUG "%s: authenticate with %pM\n", sdata->name, req->bss->bssid); - mutex_lock(&local->mtx); - ieee80211_recalc_idle(sdata->local); - mutex_unlock(&local->mtx); - - /* switch to the right channel */ - local->oper_channel = req->bss->channel; - ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); - - /* set BSSID */ - memcpy(ifmgd->bssid, req->bss->bssid, ETH_ALEN); - ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BSSID); - - /* add station entry */ - sta = sta_info_alloc(sdata, req->bss->bssid, GFP_KERNEL); - if (!sta) { - err = -ENOMEM; - goto err_clear; - } - - err = sta_info_insert(sta); - if (err) { - printk(KERN_DEBUG - "%s: failed to insert STA entry for the AP %pM (error %d)\n", - sdata->name, req->bss->bssid, err); + err = ieee80211_prep_connection(sdata, req->bss, false); + if (err) goto err_clear; - } err = ieee80211_probe_auth(sdata); if (err) { @@ -3218,7 +3248,6 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, struct ieee80211_bss *bss = (void *)req->bss->priv; struct ieee80211_mgd_assoc_data *assoc_data; struct ieee80211_supported_band *sband; - struct sta_info *sta; const u8 *ssidie; int i, err; @@ -3343,41 +3372,9 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, ifmgd->assoc_data = assoc_data; - mutex_lock(&local->mtx); - ieee80211_recalc_idle(sdata->local); - mutex_unlock(&local->mtx); - - /* switch to the right channel */ - local->oper_channel = req->bss->channel; - ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); - - rcu_read_lock(); - sta = sta_info_get(sdata, req->bss->bssid); - rcu_read_unlock(); - - if (!sta) { - /* set BSSID */ - memcpy(ifmgd->bssid, req->bss->bssid, ETH_ALEN); - ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BSSID); - - sta = sta_info_alloc(sdata, req->bss->bssid, GFP_KERNEL); - if (!sta) { - err = -ENOMEM; - goto err_clear; - } - - sta_info_pre_move_state(sta, IEEE80211_STA_AUTH); - - err = sta_info_insert(sta); - sta = NULL; - if (err) { - printk(KERN_DEBUG - "%s: failed to insert STA entry for the AP (error %d)\n", - sdata->name, err); - goto err_clear; - } - } else - WARN_ON_ONCE(compare_ether_addr(ifmgd->bssid, req->bss->bssid)); + err = ieee80211_prep_connection(sdata, req->bss, true); + if (err) + goto err_clear; if (!bss->dtim_period && sdata->local->hw.flags & IEEE80211_HW_NEED_DTIM_PERIOD) { -- cgit From 5d6a1b069b7f72298aff2306a2d02b0188668218 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 8 Mar 2012 15:02:08 +0100 Subject: mac80211: set basic rates earlier The authentication and association handshake already happens in the context of the new BSS, and the basic rates are needed at least for the ACK response frame to the authentication or association response frames. Therefore the basic rates should already be configured into the driver when those frames are sent. Change the logic to set up the basic rates in the connection preparation that happens for authentication and association (if needed). Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/mlme.c | 97 +++++++++++++++++++++++++++-------------------------- 1 file changed, 49 insertions(+), 48 deletions(-) diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 81e0124e68ce..39c13939008b 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -1344,12 +1344,6 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata, bss_conf->dtim_period = 0; bss_conf->assoc = 1; - /* - * For now just always ask the driver to update the basic rateset - * when we have associated, we aren't checking whether it actually - * changed or not. - */ - bss_info_changed |= BSS_CHANGED_BASIC_RATES; /* Tell the driver to monitor connection quality (if supported) */ if (sdata->vif.driver_flags & IEEE80211_VIF_SUPPORTS_CQM_RSSI && @@ -2001,15 +1995,12 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata, struct ieee80211_supported_band *sband; struct sta_info *sta; u8 *pos; - u32 rates, basic_rates; u16 capab_info, aid; struct ieee802_11_elems elems; struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf; u32 changed = 0; int err; - bool have_higher_than_11mbit = false; u16 ap_ht_cap_flags; - int min_rate = INT_MAX, min_rate_index = -1; /* AssocResp and ReassocResp have identical structure */ @@ -2054,39 +2045,8 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata, return false; } - rates = 0; - basic_rates = 0; sband = local->hw.wiphy->bands[local->oper_channel->band]; - ieee80211_get_rates(sband, elems.supp_rates, elems.supp_rates_len, - &rates, &basic_rates, &have_higher_than_11mbit, - &min_rate, &min_rate_index); - - ieee80211_get_rates(sband, elems.ext_supp_rates, - elems.ext_supp_rates_len, &rates, &basic_rates, - &have_higher_than_11mbit, - &min_rate, &min_rate_index); - - /* - * some buggy APs don't advertise basic_rates. use the lowest - * supported rate instead. - */ - if (unlikely(!basic_rates) && min_rate_index >= 0) { - printk(KERN_DEBUG "%s: No basic rates in AssocResp. " - "Using min supported rate instead.\n", sdata->name); - basic_rates = BIT(min_rate_index); - } - - sta->sta.supp_rates[local->oper_channel->band] = rates; - sdata->vif.bss_conf.basic_rates = basic_rates; - - /* cf. IEEE 802.11 9.2.12 */ - if (local->oper_channel->band == IEEE80211_BAND_2GHZ && - have_higher_than_11mbit) - sdata->flags |= IEEE80211_SDATA_OPERATING_GMODE; - else - sdata->flags &= ~IEEE80211_SDATA_OPERATING_GMODE; - if (elems.ht_cap_elem && !(ifmgd->flags & IEEE80211_STA_DISABLE_11N)) ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, sband, elems.ht_cap_elem, &sta->sta.ht_cap); @@ -3090,10 +3050,11 @@ int ieee80211_max_network_latency(struct notifier_block *nb, } static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata, - struct cfg80211_bss *bss, bool assoc) + struct cfg80211_bss *cbss, bool assoc) { struct ieee80211_local *local = sdata->local; struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; + struct ieee80211_bss *bss = (void *)cbss->priv; struct sta_info *sta; bool have_sta = false; int err; @@ -3103,12 +3064,12 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata, if (assoc) { rcu_read_lock(); - have_sta = sta_info_get(sdata, bss->bssid); + have_sta = sta_info_get(sdata, cbss->bssid); rcu_read_unlock(); } if (!have_sta) { - sta = sta_info_alloc(sdata, bss->bssid, GFP_KERNEL); + sta = sta_info_alloc(sdata, cbss->bssid, GFP_KERNEL); if (!sta) return -ENOMEM; } @@ -3118,13 +3079,53 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata, mutex_unlock(&local->mtx); /* switch to the right channel */ - local->oper_channel = bss->channel; + local->oper_channel = cbss->channel; ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); if (!have_sta) { - /* set BSSID - if STA already there this will be set too */ - memcpy(ifmgd->bssid, bss->bssid, ETH_ALEN); - ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BSSID); + struct ieee80211_supported_band *sband; + u32 rates = 0, basic_rates = 0; + bool have_higher_than_11mbit; + int min_rate = INT_MAX, min_rate_index = -1; + + sband = sdata->local->hw.wiphy->bands[cbss->channel->band]; + + ieee80211_get_rates(sband, bss->supp_rates, + bss->supp_rates_len, + &rates, &basic_rates, + &have_higher_than_11mbit, + &min_rate, &min_rate_index); + + /* + * This used to be a workaround for basic rates missing + * in the association response frame. Now that we no + * longer use the basic rates from there, it probably + * doesn't happen any more, but keep the workaround so + * in case some *other* APs are buggy in different ways + * we can connect -- with a warning. + */ + if (!basic_rates && min_rate_index >= 0) { + printk(KERN_DEBUG + "%s: No basic rates, using min rate instead.\n", + sdata->name); + basic_rates = BIT(min_rate_index); + } + + sta->sta.supp_rates[cbss->channel->band] = rates; + sdata->vif.bss_conf.basic_rates = basic_rates; + + /* cf. IEEE 802.11 9.2.12 */ + if (local->oper_channel->band == IEEE80211_BAND_2GHZ && + have_higher_than_11mbit) + sdata->flags |= IEEE80211_SDATA_OPERATING_GMODE; + else + sdata->flags &= ~IEEE80211_SDATA_OPERATING_GMODE; + + memcpy(ifmgd->bssid, cbss->bssid, ETH_ALEN); + + /* tell driver about BSSID and basic rates */ + ieee80211_bss_info_change_notify(sdata, + BSS_CHANGED_BSSID | BSS_CHANGED_BASIC_RATES); if (assoc) sta_info_pre_move_state(sta, IEEE80211_STA_AUTH); @@ -3138,7 +3139,7 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata, return err; } } else - WARN_ON_ONCE(compare_ether_addr(ifmgd->bssid, bss->bssid)); + WARN_ON_ONCE(compare_ether_addr(ifmgd->bssid, cbss->bssid)); return 0; } -- cgit From a3ea2c76b193be5794e0de6aff66e14c21b904f8 Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Thu, 8 Mar 2012 22:25:57 -0600 Subject: b43legacy: Load firmware from work queue instead of from probe routine Recent changes in udev are causing problems for drivers that load firmware from the probe routine. As b43legacy has such a structure, it must be changed. As this driver loads 3 or 4 firmware files, changing to the asynchronous routine request_firmware_nowait() would be complicated. In this implementation, the probe routine starts a work queue that calls the firmware loading routines. Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/b43legacy/b43legacy.h | 3 +++ drivers/net/wireless/b43legacy/main.c | 33 ++++++++++++++++++------------ 2 files changed, 23 insertions(+), 13 deletions(-) diff --git a/drivers/net/wireless/b43legacy/b43legacy.h b/drivers/net/wireless/b43legacy/b43legacy.h index 98e3d44400c6..a29da674e69d 100644 --- a/drivers/net/wireless/b43legacy/b43legacy.h +++ b/drivers/net/wireless/b43legacy/b43legacy.h @@ -581,6 +581,9 @@ struct b43legacy_wl { struct mutex mutex; /* locks wireless core state */ spinlock_t leds_lock; /* lock for leds */ + /* firmware loading work */ + struct work_struct firmware_load; + /* We can only have one operating interface (802.11 core) * at a time. General information about this interface follows. */ diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c index 75e70bce40f6..df7e16dfb36c 100644 --- a/drivers/net/wireless/b43legacy/main.c +++ b/drivers/net/wireless/b43legacy/main.c @@ -1557,8 +1557,15 @@ err_format: return -EPROTO; } -static int b43legacy_request_firmware(struct b43legacy_wldev *dev) +static int b43legacy_one_core_attach(struct ssb_device *dev, + struct b43legacy_wl *wl); +static void b43legacy_one_core_detach(struct ssb_device *dev); + +static void b43legacy_request_firmware(struct work_struct *work) { + struct b43legacy_wl *wl = container_of(work, + struct b43legacy_wl, firmware_load); + struct b43legacy_wldev *dev = wl->current_dev; struct b43legacy_firmware *fw = &dev->fw; const u8 rev = dev->dev->id.revision; const char *filename; @@ -1624,8 +1631,14 @@ static int b43legacy_request_firmware(struct b43legacy_wldev *dev) if (err) goto err_load; } + err = ieee80211_register_hw(wl->hw); + if (err) + goto err_one_core_detach; + return; - return 0; +err_one_core_detach: + b43legacy_one_core_detach(dev->dev); + goto error; err_load: b43legacy_print_fw_helptext(dev->wl); @@ -1639,7 +1652,7 @@ err_no_initvals: error: b43legacy_release_firmware(dev); - return err; + return; } static int b43legacy_upload_microcode(struct b43legacy_wldev *dev) @@ -2153,9 +2166,6 @@ static int b43legacy_chip_init(struct b43legacy_wldev *dev) macctl |= B43legacy_MACCTL_INFRA; b43legacy_write32(dev, B43legacy_MMIO_MACCTL, macctl); - err = b43legacy_request_firmware(dev); - if (err) - goto out; err = b43legacy_upload_microcode(dev); if (err) goto out; /* firmware is released later */ @@ -3860,17 +3870,13 @@ static int b43legacy_probe(struct ssb_device *dev, if (err) goto err_wireless_exit; - if (first) { - err = ieee80211_register_hw(wl->hw); - if (err) - goto err_one_core_detach; - } + /* setup and start work to load firmware */ + INIT_WORK(&wl->firmware_load, b43legacy_request_firmware); + schedule_work(&wl->firmware_load); out: return err; -err_one_core_detach: - b43legacy_one_core_detach(dev); err_wireless_exit: if (first) b43legacy_wireless_exit(dev, wl); @@ -3885,6 +3891,7 @@ static void b43legacy_remove(struct ssb_device *dev) /* We must cancel any work here before unregistering from ieee80211, * as the ieee80211 unreg will destroy the workqueue. */ cancel_work_sync(&wldev->restart_work); + cancel_work_sync(&wl->firmware_load); B43legacy_WARN_ON(!wl); if (wl->current_dev == wldev) -- cgit From 6b6fa5868eec26bdc6a83543cebb8cf832a2645a Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Thu, 8 Mar 2012 22:27:46 -0600 Subject: b43: Load firmware from a work queue and not from the probe routine Recent changes in udev are causing problems for drivers that load firmware from the probe routine. As b43 has such a structure, it must be changed. As this driver loads more than 1 firmware file, changing to the asynchronous routine request_firmware_nowait() would be complicated. In this implementation, the probe routine starts a queue that calls the firmware loading routines. Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/b43/b43.h | 3 +++ drivers/net/wireless/b43/main.c | 59 ++++++++++++++++++++++------------------- 2 files changed, 35 insertions(+), 27 deletions(-) diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h index 835462dc1206..67c13af6f206 100644 --- a/drivers/net/wireless/b43/b43.h +++ b/drivers/net/wireless/b43/b43.h @@ -932,6 +932,9 @@ struct b43_wl { /* Flag that implement the queues stopping. */ bool tx_queue_stopped[B43_QOS_QUEUE_NUM]; + /* firmware loading work */ + struct work_struct firmware_load; + /* The device LEDs. */ struct b43_leds leds; diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index 1d633f3b3274..c79e6638c88d 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -2390,8 +2390,14 @@ error: return err; } -static int b43_request_firmware(struct b43_wldev *dev) +static int b43_one_core_attach(struct b43_bus_dev *dev, struct b43_wl *wl); +static void b43_one_core_detach(struct b43_bus_dev *dev); + +static void b43_request_firmware(struct work_struct *work) { + struct b43_wl *wl = container_of(work, + struct b43_wl, firmware_load); + struct b43_wldev *dev = wl->current_dev; struct b43_request_fw_context *ctx; unsigned int i; int err; @@ -2399,23 +2405,23 @@ static int b43_request_firmware(struct b43_wldev *dev) ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); if (!ctx) - return -ENOMEM; + return; ctx->dev = dev; ctx->req_type = B43_FWTYPE_PROPRIETARY; err = b43_try_request_fw(ctx); if (!err) - goto out; /* Successfully loaded it. */ - err = ctx->fatal_failure; - if (err) + goto start_ieee80211; /* Successfully loaded it. */ + /* Was fw version known? */ + if (ctx->fatal_failure) goto out; + /* proprietary fw not found, try open source */ ctx->req_type = B43_FWTYPE_OPENSOURCE; err = b43_try_request_fw(ctx); if (!err) - goto out; /* Successfully loaded it. */ - err = ctx->fatal_failure; - if (err) + goto start_ieee80211; /* Successfully loaded it. */ + if(ctx->fatal_failure) goto out; /* Could not find a usable firmware. Print the errors. */ @@ -2425,11 +2431,20 @@ static int b43_request_firmware(struct b43_wldev *dev) b43err(dev->wl, errmsg); } b43_print_fw_helptext(dev->wl, 1); - err = -ENOENT; + goto out; + +start_ieee80211: + err = ieee80211_register_hw(wl->hw); + if (err) + goto err_one_core_detach; + b43_leds_register(wl->current_dev); + goto out; + +err_one_core_detach: + b43_one_core_detach(dev->dev); out: kfree(ctx); - return err; } static int b43_upload_microcode(struct b43_wldev *dev) @@ -3023,9 +3038,6 @@ static int b43_chip_init(struct b43_wldev *dev) macctl |= B43_MACCTL_INFRA; b43_write32(dev, B43_MMIO_MACCTL, macctl); - err = b43_request_firmware(dev); - if (err) - goto out; err = b43_upload_microcode(dev); if (err) goto out; /* firmware is released later */ @@ -4155,6 +4167,7 @@ redo: mutex_unlock(&wl->mutex); cancel_delayed_work_sync(&dev->periodic_work); cancel_work_sync(&wl->tx_work); + cancel_work_sync(&wl->firmware_load); mutex_lock(&wl->mutex); dev = wl->current_dev; if (!dev || b43_status(dev) < B43_STAT_STARTED) { @@ -5314,16 +5327,13 @@ static int b43_bcma_probe(struct bcma_device *core) if (err) goto bcma_err_wireless_exit; - err = ieee80211_register_hw(wl->hw); - if (err) - goto bcma_err_one_core_detach; - b43_leds_register(wl->current_dev); + /* setup and start work to load firmware */ + INIT_WORK(&wl->firmware_load, b43_request_firmware); + schedule_work(&wl->firmware_load); bcma_out: return err; -bcma_err_one_core_detach: - b43_one_core_detach(dev); bcma_err_wireless_exit: ieee80211_free_hw(wl->hw); return err; @@ -5390,18 +5400,13 @@ int b43_ssb_probe(struct ssb_device *sdev, const struct ssb_device_id *id) if (err) goto err_wireless_exit; - if (first) { - err = ieee80211_register_hw(wl->hw); - if (err) - goto err_one_core_detach; - b43_leds_register(wl->current_dev); - } + /* setup and start work to load firmware */ + INIT_WORK(&wl->firmware_load, b43_request_firmware); + schedule_work(&wl->firmware_load); out: return err; - err_one_core_detach: - b43_one_core_detach(dev); err_wireless_exit: if (first) b43_wireless_exit(dev, wl); -- cgit From 617bbde878604adfcd557fc2a8952f77ab4ebd95 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 12 Mar 2012 13:49:13 +0100 Subject: mac80211: move RX WEP weak IV counting This is better done inside the WEP decrypt function where it doesn't have to check all the conditions any more since they've been tested already. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/rx.c | 7 ------- net/mac80211/wep.c | 10 ++++++---- net/mac80211/wep.h | 1 - 3 files changed, 6 insertions(+), 12 deletions(-) diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 5f6e32ca0858..b38da13e2a88 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -1070,13 +1070,6 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) switch (rx->key->conf.cipher) { case WLAN_CIPHER_SUITE_WEP40: case WLAN_CIPHER_SUITE_WEP104: - /* Check for weak IVs if possible */ - if (rx->sta && ieee80211_is_data(fc) && - (!(status->flag & RX_FLAG_IV_STRIPPED) || - !(status->flag & RX_FLAG_DECRYPTED)) && - ieee80211_wep_is_weak_iv(rx->skb, rx->key)) - rx->sta->wep_weak_iv_count++; - result = ieee80211_crypto_wep_decrypt(rx); break; case WLAN_CIPHER_SUITE_TKIP: diff --git a/net/mac80211/wep.c b/net/mac80211/wep.c index 68ad351479df..5cd87ba11bb7 100644 --- a/net/mac80211/wep.c +++ b/net/mac80211/wep.c @@ -263,16 +263,14 @@ static int ieee80211_wep_decrypt(struct ieee80211_local *local, } -bool ieee80211_wep_is_weak_iv(struct sk_buff *skb, struct ieee80211_key *key) +static bool ieee80211_wep_is_weak_iv(struct sk_buff *skb, + struct ieee80211_key *key) { struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; unsigned int hdrlen; u8 *ivpos; u32 iv; - if (!ieee80211_has_protected(hdr->frame_control)) - return false; - hdrlen = ieee80211_hdrlen(hdr->frame_control); ivpos = skb->data + hdrlen; iv = (ivpos[0] << 16) | (ivpos[1] << 8) | ivpos[2]; @@ -292,9 +290,13 @@ ieee80211_crypto_wep_decrypt(struct ieee80211_rx_data *rx) return RX_CONTINUE; if (!(status->flag & RX_FLAG_DECRYPTED)) { + if (rx->sta && ieee80211_wep_is_weak_iv(rx->skb, rx->key)) + rx->sta->wep_weak_iv_count++; if (ieee80211_wep_decrypt(rx->local, rx->skb, rx->key)) return RX_DROP_UNUSABLE; } else if (!(status->flag & RX_FLAG_IV_STRIPPED)) { + if (rx->sta && ieee80211_wep_is_weak_iv(rx->skb, rx->key)) + rx->sta->wep_weak_iv_count++; ieee80211_wep_remove_iv(rx->local, rx->skb, rx->key); /* remove ICV */ skb_trim(rx->skb, rx->skb->len - WEP_ICV_LEN); diff --git a/net/mac80211/wep.h b/net/mac80211/wep.h index 01e54840a628..9615749d1f65 100644 --- a/net/mac80211/wep.h +++ b/net/mac80211/wep.h @@ -25,7 +25,6 @@ int ieee80211_wep_encrypt(struct ieee80211_local *local, const u8 *key, int keylen, int keyidx); int ieee80211_wep_decrypt_data(struct crypto_cipher *tfm, u8 *rc4key, size_t klen, u8 *data, size_t data_len); -bool ieee80211_wep_is_weak_iv(struct sk_buff *skb, struct ieee80211_key *key); ieee80211_rx_result ieee80211_crypto_wep_decrypt(struct ieee80211_rx_data *rx); -- cgit From a8286911881948c7a2ecc63ee4224c258cce2da3 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 12 Mar 2012 13:49:14 +0100 Subject: mac80211: linearize SKBs as needed for crypto Not linearizing every SKB will help actually pass non-linear SKBs all the way up when on an encrypted connection. For now, linearize TKIP completely as it is lower performance and I don't quite grok all the details. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/rx.c | 6 ++---- net/mac80211/wep.c | 11 ++++++++--- net/mac80211/wpa.c | 22 +++++++++++++++++++++- 3 files changed, 31 insertions(+), 8 deletions(-) diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index b38da13e2a88..53c88d145472 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -1063,10 +1063,6 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) return RX_DROP_MONITOR; } - if (skb_linearize(rx->skb)) - return RX_DROP_UNUSABLE; - /* the hdr variable is invalid now! */ - switch (rx->key->conf.cipher) { case WLAN_CIPHER_SUITE_WEP40: case WLAN_CIPHER_SUITE_WEP104: @@ -1089,6 +1085,8 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) return RX_DROP_UNUSABLE; } + /* the hdr variable is invalid after the decrypt handlers */ + /* either the frame has been decrypted or will be dropped */ status->flag |= RX_FLAG_DECRYPTED; diff --git a/net/mac80211/wep.c b/net/mac80211/wep.c index 5cd87ba11bb7..7aa31bbfaa3b 100644 --- a/net/mac80211/wep.c +++ b/net/mac80211/wep.c @@ -284,22 +284,27 @@ ieee80211_crypto_wep_decrypt(struct ieee80211_rx_data *rx) struct sk_buff *skb = rx->skb; struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; + __le16 fc = hdr->frame_control; - if (!ieee80211_is_data(hdr->frame_control) && - !ieee80211_is_auth(hdr->frame_control)) + if (!ieee80211_is_data(fc) && !ieee80211_is_auth(fc)) return RX_CONTINUE; if (!(status->flag & RX_FLAG_DECRYPTED)) { + if (skb_linearize(rx->skb)) + return RX_DROP_UNUSABLE; if (rx->sta && ieee80211_wep_is_weak_iv(rx->skb, rx->key)) rx->sta->wep_weak_iv_count++; if (ieee80211_wep_decrypt(rx->local, rx->skb, rx->key)) return RX_DROP_UNUSABLE; } else if (!(status->flag & RX_FLAG_IV_STRIPPED)) { + if (!pskb_may_pull(rx->skb, ieee80211_hdrlen(fc) + WEP_IV_LEN)) + return RX_DROP_UNUSABLE; if (rx->sta && ieee80211_wep_is_weak_iv(rx->skb, rx->key)) rx->sta->wep_weak_iv_count++; ieee80211_wep_remove_iv(rx->local, rx->skb, rx->key); /* remove ICV */ - skb_trim(rx->skb, rx->skb->len - WEP_ICV_LEN); + if (pskb_trim(rx->skb, rx->skb->len - WEP_ICV_LEN)) + return RX_DROP_UNUSABLE; } return RX_CONTINUE; diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c index b758350919ff..0ae23c60968c 100644 --- a/net/mac80211/wpa.c +++ b/net/mac80211/wpa.c @@ -138,6 +138,10 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx) if (skb->len < hdrlen + MICHAEL_MIC_LEN) return RX_DROP_UNUSABLE; + if (skb_linearize(rx->skb)) + return RX_DROP_UNUSABLE; + hdr = (void *)skb->data; + data = skb->data + hdrlen; data_len = skb->len - hdrlen - MICHAEL_MIC_LEN; key = &rx->key->conf.key[NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY]; @@ -253,6 +257,11 @@ ieee80211_crypto_tkip_decrypt(struct ieee80211_rx_data *rx) if (!rx->sta || skb->len - hdrlen < 12) return RX_DROP_UNUSABLE; + /* it may be possible to optimize this a bit more */ + if (skb_linearize(rx->skb)) + return RX_DROP_UNUSABLE; + hdr = (void *)skb->data; + /* * Let TKIP code verify IV, but skip decryption. * In the case where hardware checks the IV as well, @@ -484,6 +493,14 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx) if (!rx->sta || data_len < 0) return RX_DROP_UNUSABLE; + if (status->flag & RX_FLAG_DECRYPTED) { + if (!pskb_may_pull(rx->skb, hdrlen + CCMP_HDR_LEN)) + return RX_DROP_UNUSABLE; + } else { + if (skb_linearize(rx->skb)) + return RX_DROP_UNUSABLE; + } + ccmp_hdr2pn(pn, skb->data + hdrlen); queue = rx->security_idx; @@ -509,7 +526,8 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx) memcpy(key->u.ccmp.rx_pn[queue], pn, CCMP_PN_LEN); /* Remove CCMP header and MIC */ - skb_trim(skb, skb->len - CCMP_MIC_LEN); + if (pskb_trim(skb, skb->len - CCMP_MIC_LEN)) + return RX_DROP_UNUSABLE; memmove(skb->data + CCMP_HDR_LEN, skb->data, hdrlen); skb_pull(skb, CCMP_HDR_LEN); @@ -609,6 +627,8 @@ ieee80211_crypto_aes_cmac_decrypt(struct ieee80211_rx_data *rx) if (!ieee80211_is_mgmt(hdr->frame_control)) return RX_CONTINUE; + /* management frames are already linear */ + if (skb->len < 24 + sizeof(*mmie)) return RX_DROP_UNUSABLE; -- cgit From 3e822635a79c55a7768ec38cd5007081dae95171 Mon Sep 17 00:00:00 2001 From: Yogesh Ashok Powar Date: Mon, 12 Mar 2012 19:35:08 -0700 Subject: mwifiex: rename long function names to shorter ones This saves some space and adds better readability. Signed-off-by: Yogesh Ashok Powar Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/11n.c | 60 +++++++++++++--------------- drivers/net/wireless/mwifiex/11n.h | 9 ++--- drivers/net/wireless/mwifiex/11n_rxreorder.c | 6 +-- drivers/net/wireless/mwifiex/11n_rxreorder.h | 5 +-- drivers/net/wireless/mwifiex/main.h | 6 +-- drivers/net/wireless/mwifiex/wmm.c | 10 ++--- 6 files changed, 43 insertions(+), 53 deletions(-) diff --git a/drivers/net/wireless/mwifiex/11n.c b/drivers/net/wireless/mwifiex/11n.c index 34bba5234294..aeb456d6396f 100644 --- a/drivers/net/wireless/mwifiex/11n.c +++ b/drivers/net/wireless/mwifiex/11n.c @@ -69,8 +69,8 @@ mwifiex_fill_cap_info(struct mwifiex_private *priv, u8 radio_type, * table which matches the requested BA status. */ static struct mwifiex_tx_ba_stream_tbl * -mwifiex_11n_get_tx_ba_stream_status(struct mwifiex_private *priv, - enum mwifiex_ba_status ba_status) +mwifiex_get_ba_status(struct mwifiex_private *priv, + enum mwifiex_ba_status ba_status) { struct mwifiex_tx_ba_stream_tbl *tx_ba_tsr_tbl; unsigned long flags; @@ -107,12 +107,11 @@ int mwifiex_ret_11n_delba(struct mwifiex_private *priv, tid = del_ba_param_set >> DELBA_TID_POS; if (del_ba->del_result == BA_RESULT_SUCCESS) { - mwifiex_11n_delete_ba_stream_tbl(priv, tid, - del_ba->peer_mac_addr, TYPE_DELBA_SENT, - INITIATOR_BIT(del_ba_param_set)); + mwifiex_del_ba_tbl(priv, tid, del_ba->peer_mac_addr, + TYPE_DELBA_SENT, + INITIATOR_BIT(del_ba_param_set)); - tx_ba_tbl = mwifiex_11n_get_tx_ba_stream_status(priv, - BA_STREAM_SETUP_INPROGRESS); + tx_ba_tbl = mwifiex_get_ba_status(priv, BA_SETUP_INPROGRESS); if (tx_ba_tbl) mwifiex_send_addba(priv, tx_ba_tbl->tid, tx_ba_tbl->ra); @@ -120,18 +119,17 @@ int mwifiex_ret_11n_delba(struct mwifiex_private *priv, * In case of failure, recreate the deleted stream in case * we initiated the ADDBA */ - if (INITIATOR_BIT(del_ba_param_set)) { - mwifiex_11n_create_tx_ba_stream_tbl(priv, - del_ba->peer_mac_addr, tid, - BA_STREAM_SETUP_INPROGRESS); - - tx_ba_tbl = mwifiex_11n_get_tx_ba_stream_status(priv, - BA_STREAM_SETUP_INPROGRESS); - if (tx_ba_tbl) - mwifiex_11n_delete_ba_stream_tbl(priv, - tx_ba_tbl->tid, tx_ba_tbl->ra, - TYPE_DELBA_SENT, true); - } + if (!INITIATOR_BIT(del_ba_param_set)) + return 0; + + mwifiex_create_ba_tbl(priv, del_ba->peer_mac_addr, tid, + BA_SETUP_INPROGRESS); + + tx_ba_tbl = mwifiex_get_ba_status(priv, BA_SETUP_INPROGRESS); + + if (tx_ba_tbl) + mwifiex_del_ba_tbl(priv, tx_ba_tbl->tid, tx_ba_tbl->ra, + TYPE_DELBA_SENT, true); } return 0; @@ -160,18 +158,17 @@ int mwifiex_ret_11n_addba_req(struct mwifiex_private *priv, & IEEE80211_ADDBA_PARAM_TID_MASK) >> BLOCKACKPARAM_TID_POS; if (le16_to_cpu(add_ba_rsp->status_code) == BA_RESULT_SUCCESS) { - tx_ba_tbl = mwifiex_11n_get_tx_ba_stream_tbl(priv, tid, + tx_ba_tbl = mwifiex_get_ba_tbl(priv, tid, add_ba_rsp->peer_mac_addr); if (tx_ba_tbl) { dev_dbg(priv->adapter->dev, "info: BA stream complete\n"); - tx_ba_tbl->ba_status = BA_STREAM_SETUP_COMPLETE; + tx_ba_tbl->ba_status = BA_SETUP_COMPLETE; } else { dev_err(priv->adapter->dev, "BA stream not created\n"); } } else { - mwifiex_11n_delete_ba_stream_tbl(priv, tid, - add_ba_rsp->peer_mac_addr, - TYPE_DELBA_SENT, true); + mwifiex_del_ba_tbl(priv, tid, add_ba_rsp->peer_mac_addr, + TYPE_DELBA_SENT, true); if (add_ba_rsp->add_rsp_result != BA_RESULT_TIMEOUT) priv->aggr_prio_tbl[tid].ampdu_ap = BA_STREAM_NOT_ALLOWED; @@ -544,8 +541,7 @@ void mwifiex_11n_delete_all_tx_ba_stream_tbl(struct mwifiex_private *priv) * table which matches the given RA/TID pair. */ struct mwifiex_tx_ba_stream_tbl * -mwifiex_11n_get_tx_ba_stream_tbl(struct mwifiex_private *priv, - int tid, u8 *ra) +mwifiex_get_ba_tbl(struct mwifiex_private *priv, int tid, u8 *ra) { struct mwifiex_tx_ba_stream_tbl *tx_ba_tsr_tbl; unsigned long flags; @@ -567,14 +563,13 @@ mwifiex_11n_get_tx_ba_stream_tbl(struct mwifiex_private *priv, * This function creates an entry in Tx BA stream table for the * given RA/TID pair. */ -void mwifiex_11n_create_tx_ba_stream_tbl(struct mwifiex_private *priv, - u8 *ra, int tid, - enum mwifiex_ba_status ba_status) +void mwifiex_create_ba_tbl(struct mwifiex_private *priv, u8 *ra, int tid, + enum mwifiex_ba_status ba_status) { struct mwifiex_tx_ba_stream_tbl *new_node; unsigned long flags; - if (!mwifiex_11n_get_tx_ba_stream_tbl(priv, tid, ra)) { + if (!mwifiex_get_ba_tbl(priv, tid, ra)) { new_node = kzalloc(sizeof(struct mwifiex_tx_ba_stream_tbl), GFP_ATOMIC); if (!new_node) { @@ -668,9 +663,8 @@ void mwifiex_11n_delete_ba_stream(struct mwifiex_private *priv, u8 *del_ba) tid = del_ba_param_set >> DELBA_TID_POS; - mwifiex_11n_delete_ba_stream_tbl(priv, tid, cmd_del_ba->peer_mac_addr, - TYPE_DELBA_RECEIVE, - INITIATOR_BIT(del_ba_param_set)); + mwifiex_del_ba_tbl(priv, tid, cmd_del_ba->peer_mac_addr, + TYPE_DELBA_RECEIVE, INITIATOR_BIT(del_ba_param_set)); } /* diff --git a/drivers/net/wireless/mwifiex/11n.h b/drivers/net/wireless/mwifiex/11n.h index 90b421e343d4..139aa6ee1fbe 100644 --- a/drivers/net/wireless/mwifiex/11n.h +++ b/drivers/net/wireless/mwifiex/11n.h @@ -46,13 +46,12 @@ void mwifiex_11n_delete_tx_ba_stream_tbl_entry(struct mwifiex_private *priv, struct mwifiex_tx_ba_stream_tbl *tx_tbl); void mwifiex_11n_delete_all_tx_ba_stream_tbl(struct mwifiex_private *priv); -struct mwifiex_tx_ba_stream_tbl *mwifiex_11n_get_tx_ba_stream_tbl(struct +struct mwifiex_tx_ba_stream_tbl *mwifiex_get_ba_tbl(struct mwifiex_private *priv, int tid, u8 *ra); -void mwifiex_11n_create_tx_ba_stream_tbl(struct mwifiex_private *priv, u8 *ra, - int tid, - enum mwifiex_ba_status ba_status); +void mwifiex_create_ba_tbl(struct mwifiex_private *priv, u8 *ra, int tid, + enum mwifiex_ba_status ba_status); int mwifiex_send_addba(struct mwifiex_private *priv, int tid, u8 *peer_mac); int mwifiex_send_delba(struct mwifiex_private *priv, int tid, u8 *peer_mac, int initiator); @@ -154,7 +153,7 @@ mwifiex_is_ba_stream_setup(struct mwifiex_private *priv, { struct mwifiex_tx_ba_stream_tbl *tx_tbl; - tx_tbl = mwifiex_11n_get_tx_ba_stream_tbl(priv, tid, ptr->ra); + tx_tbl = mwifiex_get_ba_tbl(priv, tid, ptr->ra); if (tx_tbl && IS_BASTREAM_SETUP(tx_tbl)) return true; diff --git a/drivers/net/wireless/mwifiex/11n_rxreorder.c b/drivers/net/wireless/mwifiex/11n_rxreorder.c index 681d3f2a4c28..ad41fab970b5 100644 --- a/drivers/net/wireless/mwifiex/11n_rxreorder.c +++ b/drivers/net/wireless/mwifiex/11n_rxreorder.c @@ -480,8 +480,8 @@ int mwifiex_11n_rx_reorder_pkt(struct mwifiex_private *priv, * The TID/TA are taken from del BA event body. */ void -mwifiex_11n_delete_ba_stream_tbl(struct mwifiex_private *priv, int tid, - u8 *peer_mac, u8 type, int initiator) +mwifiex_del_ba_tbl(struct mwifiex_private *priv, int tid, u8 *peer_mac, + u8 type, int initiator) { struct mwifiex_rx_reorder_tbl *rx_reor_tbl_ptr; struct mwifiex_tx_ba_stream_tbl *ptx_tbl; @@ -506,7 +506,7 @@ mwifiex_11n_delete_ba_stream_tbl(struct mwifiex_private *priv, int tid, } mwifiex_11n_delete_rx_reorder_tbl_entry(priv, rx_reor_tbl_ptr); } else { - ptx_tbl = mwifiex_11n_get_tx_ba_stream_tbl(priv, tid, peer_mac); + ptx_tbl = mwifiex_get_ba_tbl(priv, tid, peer_mac); if (!ptx_tbl) { dev_dbg(priv->adapter->dev, "event: TID, RA not found in table\n"); diff --git a/drivers/net/wireless/mwifiex/11n_rxreorder.h b/drivers/net/wireless/mwifiex/11n_rxreorder.h index 033c8adbdcd4..f1bffebabc60 100644 --- a/drivers/net/wireless/mwifiex/11n_rxreorder.h +++ b/drivers/net/wireless/mwifiex/11n_rxreorder.h @@ -41,9 +41,8 @@ int mwifiex_11n_rx_reorder_pkt(struct mwifiex_private *, u16 seqNum, u16 tid, u8 *ta, u8 pkttype, void *payload); -void mwifiex_11n_delete_ba_stream_tbl(struct mwifiex_private *priv, int Tid, - u8 *PeerMACAddr, u8 type, - int initiator); +void mwifiex_del_ba_tbl(struct mwifiex_private *priv, int Tid, + u8 *PeerMACAddr, u8 type, int initiator); void mwifiex_11n_ba_stream_timeout(struct mwifiex_private *priv, struct host_cmd_ds_11n_batimeout *event); int mwifiex_ret_11n_addba_resp(struct mwifiex_private *priv, diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h index 6dc116647411..58748b143609 100644 --- a/drivers/net/wireless/mwifiex/main.h +++ b/drivers/net/wireless/mwifiex/main.h @@ -462,9 +462,9 @@ struct mwifiex_private { }; enum mwifiex_ba_status { - BA_STREAM_NOT_SETUP = 0, - BA_STREAM_SETUP_INPROGRESS, - BA_STREAM_SETUP_COMPLETE + BA_SETUP_NONE = 0, + BA_SETUP_INPROGRESS, + BA_SETUP_COMPLETE }; struct mwifiex_tx_ba_stream_tbl { diff --git a/drivers/net/wireless/mwifiex/wmm.c b/drivers/net/wireless/mwifiex/wmm.c index 75f79ef9f6cf..5757ebd2163a 100644 --- a/drivers/net/wireless/mwifiex/wmm.c +++ b/drivers/net/wireless/mwifiex/wmm.c @@ -1218,15 +1218,13 @@ mwifiex_dequeue_tx_packet(struct mwifiex_adapter *adapter) } else { if (mwifiex_is_ampdu_allowed(priv, tid)) { if (mwifiex_space_avail_for_new_ba_stream(adapter)) { - mwifiex_11n_create_tx_ba_stream_tbl(priv, - ptr->ra, tid, - BA_STREAM_SETUP_INPROGRESS); + mwifiex_create_ba_tbl(priv, ptr->ra, tid, + BA_SETUP_INPROGRESS); mwifiex_send_addba(priv, tid, ptr->ra); } else if (mwifiex_find_stream_to_delete (priv, tid, &tid_del, ra)) { - mwifiex_11n_create_tx_ba_stream_tbl(priv, - ptr->ra, tid, - BA_STREAM_SETUP_INPROGRESS); + mwifiex_create_ba_tbl(priv, ptr->ra, tid, + BA_SETUP_INPROGRESS); mwifiex_send_delba(priv, tid_del, ra, 1); } } -- cgit From 985d68a3bb7678d6b4d5175f52d70b7f3abb992a Mon Sep 17 00:00:00 2001 From: Yogesh Ashok Powar Date: Mon, 12 Mar 2012 19:35:09 -0700 Subject: mwifiex: rearrange switch statement Fixing coding style by rearranging the switch statement Signed-off-by: Yogesh Ashok Powar Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/sta_cmdresp.c | 198 +++++++++++++---------------- 1 file changed, 87 insertions(+), 111 deletions(-) diff --git a/drivers/net/wireless/mwifiex/sta_cmdresp.c b/drivers/net/wireless/mwifiex/sta_cmdresp.c index 0d8618a8443f..3f13ff0cd262 100644 --- a/drivers/net/wireless/mwifiex/sta_cmdresp.c +++ b/drivers/net/wireless/mwifiex/sta_cmdresp.c @@ -420,38 +420,34 @@ static int mwifiex_ret_tx_power_cfg(struct mwifiex_private *priv, switch (action) { case HostCmd_ACT_GEN_GET: - { - pg_tlv_hdr = - (struct mwifiex_types_power_group *) ((u8 *) - txp_cfg + - sizeof - (struct - host_cmd_ds_txpwr_cfg)); - pg = (struct mwifiex_power_group *) ((u8 *) - pg_tlv_hdr + - sizeof(struct - mwifiex_types_power_group)); - if (adapter->hw_status == - MWIFIEX_HW_STATUS_INITIALIZING) - mwifiex_get_power_level(priv, txp_cfg); - priv->tx_power_level = (u16) pg->power_min; - break; - } + pg_tlv_hdr = (struct mwifiex_types_power_group *) + ((u8 *) txp_cfg + + sizeof(struct host_cmd_ds_txpwr_cfg)); + + pg = (struct mwifiex_power_group *) + ((u8 *) pg_tlv_hdr + + sizeof(struct mwifiex_types_power_group)); + + if (adapter->hw_status == MWIFIEX_HW_STATUS_INITIALIZING) + mwifiex_get_power_level(priv, txp_cfg); + + priv->tx_power_level = (u16) pg->power_min; + break; + case HostCmd_ACT_GEN_SET: - if (le32_to_cpu(txp_cfg->mode)) { - pg_tlv_hdr = - (struct mwifiex_types_power_group *) ((u8 *) - txp_cfg + - sizeof - (struct - host_cmd_ds_txpwr_cfg)); - pg = (struct mwifiex_power_group *) ((u8 *) pg_tlv_hdr - + - sizeof(struct - mwifiex_types_power_group)); - if (pg->power_max == pg->power_min) - priv->tx_power_level = (u16) pg->power_min; - } + if (!le32_to_cpu(txp_cfg->mode)) + break; + + pg_tlv_hdr = (struct mwifiex_types_power_group *) + ((u8 *) txp_cfg + + sizeof(struct host_cmd_ds_txpwr_cfg)); + + pg = (struct mwifiex_power_group *) + ((u8 *) pg_tlv_hdr + + sizeof(struct mwifiex_types_power_group)); + + if (pg->power_max == pg->power_min) + priv->tx_power_level = (u16) pg->power_min; break; default: dev_err(adapter->dev, "CMD_RESP: unknown cmd action %d\n", @@ -679,90 +675,70 @@ static int mwifiex_ret_reg_access(u16 type, struct host_cmd_ds_command *resp, { struct mwifiex_ds_reg_rw *reg_rw; struct mwifiex_ds_read_eeprom *eeprom; + union reg { + struct host_cmd_ds_mac_reg_access *mac; + struct host_cmd_ds_bbp_reg_access *bbp; + struct host_cmd_ds_rf_reg_access *rf; + struct host_cmd_ds_pmic_reg_access *pmic; + struct host_cmd_ds_802_11_eeprom_access *eeprom; + } r; + + if (!data_buf) + return 0; - if (data_buf) { - reg_rw = data_buf; - eeprom = data_buf; - switch (type) { - case HostCmd_CMD_MAC_REG_ACCESS: - { - struct host_cmd_ds_mac_reg_access *reg; - reg = (struct host_cmd_ds_mac_reg_access *) - &resp->params.mac_reg; - reg_rw->offset = cpu_to_le32( - (u32) le16_to_cpu(reg->offset)); - reg_rw->value = reg->value; - break; - } - case HostCmd_CMD_BBP_REG_ACCESS: - { - struct host_cmd_ds_bbp_reg_access *reg; - reg = (struct host_cmd_ds_bbp_reg_access *) - &resp->params.bbp_reg; - reg_rw->offset = cpu_to_le32( - (u32) le16_to_cpu(reg->offset)); - reg_rw->value = cpu_to_le32((u32) reg->value); - break; - } + reg_rw = data_buf; + eeprom = data_buf; + switch (type) { + case HostCmd_CMD_MAC_REG_ACCESS: + r.mac = (struct host_cmd_ds_mac_reg_access *) + &resp->params.mac_reg; + reg_rw->offset = cpu_to_le32((u32) le16_to_cpu(r.mac->offset)); + reg_rw->value = r.mac->value; + break; + case HostCmd_CMD_BBP_REG_ACCESS: + r.bbp = (struct host_cmd_ds_bbp_reg_access *) + &resp->params.bbp_reg; + reg_rw->offset = cpu_to_le32((u32) le16_to_cpu(r.bbp->offset)); + reg_rw->value = cpu_to_le32((u32) r.bbp->value); + break; - case HostCmd_CMD_RF_REG_ACCESS: - { - struct host_cmd_ds_rf_reg_access *reg; - reg = (struct host_cmd_ds_rf_reg_access *) - &resp->params.rf_reg; - reg_rw->offset = cpu_to_le32( - (u32) le16_to_cpu(reg->offset)); - reg_rw->value = cpu_to_le32((u32) reg->value); - break; - } - case HostCmd_CMD_PMIC_REG_ACCESS: - { - struct host_cmd_ds_pmic_reg_access *reg; - reg = (struct host_cmd_ds_pmic_reg_access *) - &resp->params.pmic_reg; - reg_rw->offset = cpu_to_le32( - (u32) le16_to_cpu(reg->offset)); - reg_rw->value = cpu_to_le32((u32) reg->value); - break; - } - case HostCmd_CMD_CAU_REG_ACCESS: - { - struct host_cmd_ds_rf_reg_access *reg; - reg = (struct host_cmd_ds_rf_reg_access *) - &resp->params.rf_reg; - reg_rw->offset = cpu_to_le32( - (u32) le16_to_cpu(reg->offset)); - reg_rw->value = cpu_to_le32((u32) reg->value); - break; - } - case HostCmd_CMD_802_11_EEPROM_ACCESS: - { - struct host_cmd_ds_802_11_eeprom_access - *cmd_eeprom = - (struct host_cmd_ds_802_11_eeprom_access - *) &resp->params.eeprom; - pr_debug("info: EEPROM read len=%x\n", - cmd_eeprom->byte_count); - if (le16_to_cpu(eeprom->byte_count) < - le16_to_cpu( - cmd_eeprom->byte_count)) { - eeprom->byte_count = cpu_to_le16(0); - pr_debug("info: EEPROM read " - "length is too big\n"); - return -1; - } - eeprom->offset = cmd_eeprom->offset; - eeprom->byte_count = cmd_eeprom->byte_count; - if (le16_to_cpu(eeprom->byte_count) > 0) - memcpy(&eeprom->value, - &cmd_eeprom->value, - le16_to_cpu(eeprom->byte_count)); - - break; - } - default: + case HostCmd_CMD_RF_REG_ACCESS: + r.rf = (struct host_cmd_ds_rf_reg_access *) + &resp->params.rf_reg; + reg_rw->offset = cpu_to_le32((u32) le16_to_cpu(r.rf->offset)); + reg_rw->value = cpu_to_le32((u32) r.bbp->value); + break; + case HostCmd_CMD_PMIC_REG_ACCESS: + r.pmic = (struct host_cmd_ds_pmic_reg_access *) + &resp->params.pmic_reg; + reg_rw->offset = cpu_to_le32((u32) le16_to_cpu(r.pmic->offset)); + reg_rw->value = cpu_to_le32((u32) r.pmic->value); + break; + case HostCmd_CMD_CAU_REG_ACCESS: + r.rf = (struct host_cmd_ds_rf_reg_access *) + &resp->params.rf_reg; + reg_rw->offset = cpu_to_le32((u32) le16_to_cpu(r.rf->offset)); + reg_rw->value = cpu_to_le32((u32) r.rf->value); + break; + case HostCmd_CMD_802_11_EEPROM_ACCESS: + r.eeprom = (struct host_cmd_ds_802_11_eeprom_access *) + &resp->params.eeprom; + pr_debug("info: EEPROM read len=%x\n", r.eeprom->byte_count); + if (le16_to_cpu(eeprom->byte_count) < + le16_to_cpu(r.eeprom->byte_count)) { + eeprom->byte_count = cpu_to_le16(0); + pr_debug("info: EEPROM read length is too big\n"); return -1; } + eeprom->offset = r.eeprom->offset; + eeprom->byte_count = r.eeprom->byte_count; + if (le16_to_cpu(eeprom->byte_count) > 0) + memcpy(&eeprom->value, &r.eeprom->value, + le16_to_cpu(r.eeprom->byte_count)); + + break; + default: + return -1; } return 0; } -- cgit From 6685d109f4b60604fd206cff01355094a2e3b419 Mon Sep 17 00:00:00 2001 From: Yogesh Ashok Powar Date: Mon, 12 Mar 2012 19:35:10 -0700 Subject: mwifiex: merge functions to derive cfp by chan & freq in one There exist different functions with very long names to derive the channel frequency and power tripplet based on band and channel/freq. Signed-off-by: Yogesh Ashok Powar Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/cfp.c | 86 +++++++++++--------------------- drivers/net/wireless/mwifiex/join.c | 9 ++-- drivers/net/wireless/mwifiex/main.h | 9 +--- drivers/net/wireless/mwifiex/scan.c | 11 ++-- drivers/net/wireless/mwifiex/sta_ioctl.c | 13 ++--- 5 files changed, 46 insertions(+), 82 deletions(-) diff --git a/drivers/net/wireless/mwifiex/cfp.c b/drivers/net/wireless/mwifiex/cfp.c index 1782a77f15dc..7541d9a4a6ed 100644 --- a/drivers/net/wireless/mwifiex/cfp.c +++ b/drivers/net/wireless/mwifiex/cfp.c @@ -169,59 +169,18 @@ u32 mwifiex_get_active_data_rates(struct mwifiex_private *priv, u8 *rates) /* * This function locates the Channel-Frequency-Power triplet based upon - * band and channel parameters. + * band and channel/frequency parameters. */ struct mwifiex_chan_freq_power * -mwifiex_get_cfp_by_band_and_channel_from_cfg80211(struct mwifiex_private - *priv, u8 band, u16 channel) +mwifiex_get_cfp(struct mwifiex_private *priv, u8 band, u16 channel, u32 freq) { struct mwifiex_chan_freq_power *cfp = NULL; struct ieee80211_supported_band *sband; - struct ieee80211_channel *ch; + struct ieee80211_channel *ch = NULL; int i; - if (mwifiex_band_to_radio_type(band) == HostCmd_SCAN_RADIO_TYPE_BG) - sband = priv->wdev->wiphy->bands[IEEE80211_BAND_2GHZ]; - else - sband = priv->wdev->wiphy->bands[IEEE80211_BAND_5GHZ]; - - if (!sband) { - dev_err(priv->adapter->dev, "%s: cannot find cfp by band %d" - " & channel %d\n", __func__, band, channel); + if (!channel && !freq) return cfp; - } - - for (i = 0; i < sband->n_channels; i++) { - ch = &sband->channels[i]; - if (((ch->hw_value == channel) || - (channel == FIRST_VALID_CHANNEL)) - && !(ch->flags & IEEE80211_CHAN_DISABLED)) { - priv->cfp.channel = channel; - priv->cfp.freq = ch->center_freq; - priv->cfp.max_tx_power = ch->max_power; - cfp = &priv->cfp; - break; - } - } - if (i == sband->n_channels) - dev_err(priv->adapter->dev, "%s: cannot find cfp by band %d" - " & channel %d\n", __func__, band, channel); - - return cfp; -} - -/* - * This function locates the Channel-Frequency-Power triplet based upon - * band and frequency parameters. - */ -struct mwifiex_chan_freq_power * -mwifiex_get_cfp_by_band_and_freq_from_cfg80211(struct mwifiex_private *priv, - u8 band, u32 freq) -{ - struct mwifiex_chan_freq_power *cfp = NULL; - struct ieee80211_supported_band *sband; - struct ieee80211_channel *ch; - int i; if (mwifiex_band_to_radio_type(band) == HostCmd_SCAN_RADIO_TYPE_BG) sband = priv->wdev->wiphy->bands[IEEE80211_BAND_2GHZ]; @@ -229,25 +188,40 @@ mwifiex_get_cfp_by_band_and_freq_from_cfg80211(struct mwifiex_private *priv, sband = priv->wdev->wiphy->bands[IEEE80211_BAND_5GHZ]; if (!sband) { - dev_err(priv->adapter->dev, "%s: cannot find cfp by band %d" - " & freq %d\n", __func__, band, freq); + dev_err(priv->adapter->dev, "%s: cannot find cfp by band %d\n", + __func__, band); return cfp; } for (i = 0; i < sband->n_channels; i++) { ch = &sband->channels[i]; - if ((ch->center_freq == freq) && - !(ch->flags & IEEE80211_CHAN_DISABLED)) { - priv->cfp.channel = ch->hw_value; - priv->cfp.freq = freq; - priv->cfp.max_tx_power = ch->max_power; - cfp = &priv->cfp; - break; + + if (ch->flags & IEEE80211_CHAN_DISABLED) + continue; + + if (freq) { + if (ch->center_freq == freq) + break; + } else { + /* find by valid channel*/ + if (ch->hw_value == channel || + channel == FIRST_VALID_CHANNEL) + break; } } - if (i == sband->n_channels) + if (i == sband->n_channels) { dev_err(priv->adapter->dev, "%s: cannot find cfp by band %d" - " & freq %d\n", __func__, band, freq); + " & channel=%d freq=%d\n", __func__, band, channel, + freq); + } else { + if (!ch) + return cfp; + + priv->cfp.channel = ch->hw_value; + priv->cfp.freq = ch->center_freq; + priv->cfp.max_tx_power = ch->max_power; + cfp = &priv->cfp; + } return cfp; } diff --git a/drivers/net/wireless/mwifiex/join.c b/drivers/net/wireless/mwifiex/join.c index bce9991612c8..803275f58c78 100644 --- a/drivers/net/wireless/mwifiex/join.c +++ b/drivers/net/wireless/mwifiex/join.c @@ -777,12 +777,11 @@ mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv, adhoc_start->phy_param_set.ds_param_set.element_id = DS_PARA_IE_ID; adhoc_start->phy_param_set.ds_param_set.len = DS_PARA_IE_LEN; - if (!mwifiex_get_cfp_by_band_and_channel_from_cfg80211 - (priv, adapter->adhoc_start_band, (u16) - priv->adhoc_channel)) { + if (!mwifiex_get_cfp(priv, adapter->adhoc_start_band, + (u16) priv->adhoc_channel, 0)) { struct mwifiex_chan_freq_power *cfp; - cfp = mwifiex_get_cfp_by_band_and_channel_from_cfg80211(priv, - adapter->adhoc_start_band, FIRST_VALID_CHANNEL); + cfp = mwifiex_get_cfp(priv, adapter->adhoc_start_band, + FIRST_VALID_CHANNEL, 0); if (cfp) priv->adhoc_channel = (u8) cfp->channel; } diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h index 58748b143609..c0df48f63e11 100644 --- a/drivers/net/wireless/mwifiex/main.h +++ b/drivers/net/wireless/mwifiex/main.h @@ -771,13 +771,8 @@ int mwifiex_cmd_802_11_ad_hoc_join(struct mwifiex_private *priv, int mwifiex_ret_802_11_ad_hoc(struct mwifiex_private *priv, struct host_cmd_ds_command *resp); int mwifiex_cmd_802_11_bg_scan_query(struct host_cmd_ds_command *cmd); -struct mwifiex_chan_freq_power * - mwifiex_get_cfp_by_band_and_channel_from_cfg80211( - struct mwifiex_private *priv, - u8 band, u16 channel); -struct mwifiex_chan_freq_power *mwifiex_get_cfp_by_band_and_freq_from_cfg80211( - struct mwifiex_private *priv, - u8 band, u32 freq); +struct mwifiex_chan_freq_power *mwifiex_get_cfp(struct mwifiex_private *priv, + u8 band, u16 channel, u32 freq); u32 mwifiex_index_to_data_rate(struct mwifiex_private *priv, u8 index, u8 ht_info); u32 mwifiex_find_freq_from_band_chan(u8, u8); diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c index fd0302fe5bd8..0a0c2890adfa 100644 --- a/drivers/net/wireless/mwifiex/scan.c +++ b/drivers/net/wireless/mwifiex/scan.c @@ -1434,8 +1434,8 @@ int mwifiex_check_network_compatibility(struct mwifiex_private *priv, if (!bss_desc) return -1; - if ((mwifiex_get_cfp_by_band_and_channel_from_cfg80211(priv, - (u8) bss_desc->bss_band, (u16) bss_desc->channel))) { + if ((mwifiex_get_cfp(priv, (u8) bss_desc->bss_band, + (u16) bss_desc->channel, 0))) { switch (priv->bss_mode) { case NL80211_IFTYPE_STATION: case NL80211_IFTYPE_ADHOC: @@ -1625,7 +1625,7 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, s32 rssi; const u8 *ie_buf; size_t ie_len; - int channel = -1; + u16 channel = 0; u64 network_tsf = 0; u16 beacon_size = 0; u32 curr_bcn_bytes; @@ -1723,7 +1723,7 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, &tsf_tlv->tsf_data[idx * TSF_DATA_SIZE], sizeof(network_tsf)); - if (channel != -1) { + if (channel) { struct ieee80211_channel *chan; u8 band; @@ -1736,8 +1736,7 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, & (BIT(0) | BIT(1))); } - cfp = mwifiex_get_cfp_by_band_and_channel_from_cfg80211( - priv, (u8)band, (u16)channel); + cfp = mwifiex_get_cfp(priv, band, channel, 0); freq = cfp ? cfp->freq : 0; diff --git a/drivers/net/wireless/mwifiex/sta_ioctl.c b/drivers/net/wireless/mwifiex/sta_ioctl.c index 0ae1209646c1..a3d79f4a6192 100644 --- a/drivers/net/wireless/mwifiex/sta_ioctl.c +++ b/drivers/net/wireless/mwifiex/sta_ioctl.c @@ -529,11 +529,10 @@ int mwifiex_bss_set_channel(struct mwifiex_private *priv, adapter->adhoc_start_band = BAND_G | BAND_B; if (chan->channel) { if (chan->channel <= MAX_CHANNEL_BAND_BG) - cfp = mwifiex_get_cfp_by_band_and_channel_from_cfg80211 - (priv, 0, (u16) chan->channel); + cfp = mwifiex_get_cfp(priv, 0, (u16) chan->channel, 0); if (!cfp) { - cfp = mwifiex_get_cfp_by_band_and_channel_from_cfg80211 - (priv, BAND_A, (u16) chan->channel); + cfp = mwifiex_get_cfp(priv, BAND_A, + (u16) chan->channel, 0); if (cfp) { if (adapter->adhoc_11n_enabled) adapter->adhoc_start_band = BAND_A @@ -544,11 +543,9 @@ int mwifiex_bss_set_channel(struct mwifiex_private *priv, } } else { if (chan->freq <= MAX_FREQUENCY_BAND_BG) - cfp = mwifiex_get_cfp_by_band_and_freq_from_cfg80211( - priv, 0, chan->freq); + cfp = mwifiex_get_cfp(priv, 0, 0, chan->freq); if (!cfp) { - cfp = mwifiex_get_cfp_by_band_and_freq_from_cfg80211 - (priv, BAND_A, chan->freq); + cfp = mwifiex_get_cfp(priv, BAND_A, 0, chan->freq); if (cfp) { if (adapter->adhoc_11n_enabled) adapter->adhoc_start_band = BAND_A -- cgit From e7891ba2de9a67f22e5fd2a137f98d89cfb71348 Mon Sep 17 00:00:00 2001 From: Yogesh Ashok Powar Date: Mon, 12 Mar 2012 19:35:11 -0700 Subject: mwifiex: use usleep_range instead of udelay For the delay of 10 uSec or more usleep_range is prefered. Unlike udelay, sleep_range avoids large number of undesired interrupts. Ref Documentation/timers/timers-howto.txt Signed-off-by: Yogesh Ashok Powar Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/pcie.c | 6 +++--- drivers/net/wireless/mwifiex/sdio.c | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/mwifiex/pcie.c b/drivers/net/wireless/mwifiex/pcie.c index 405350940a45..1033f00a775f 100644 --- a/drivers/net/wireless/mwifiex/pcie.c +++ b/drivers/net/wireless/mwifiex/pcie.c @@ -288,7 +288,7 @@ static int mwifiex_pm_wakeup_card(struct mwifiex_adapter *adapter) while (mwifiex_pcie_ok_to_access_hw(adapter)) { i++; - udelay(10); + usleep_range(10, 20); /* 50ms max wait */ if (i == 50000) break; @@ -1088,7 +1088,7 @@ static int mwifiex_pcie_process_cmd_complete(struct mwifiex_adapter *adapter) card->cmdrsp_buf->len); while (mwifiex_pcie_ok_to_access_hw(adapter) && (count++ < 10)) - udelay(50); + usleep_range(50, 60); } else { dev_err(adapter->dev, "There is no command but " "got cmdrsp\n"); @@ -1337,7 +1337,7 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, } if (len) break; - udelay(10); + usleep_range(10, 20); } if (!len) { diff --git a/drivers/net/wireless/mwifiex/sdio.c b/drivers/net/wireless/mwifiex/sdio.c index d39d8457f252..fe6fbc123b2e 100644 --- a/drivers/net/wireless/mwifiex/sdio.c +++ b/drivers/net/wireless/mwifiex/sdio.c @@ -583,7 +583,7 @@ mwifiex_sdio_poll_card_status(struct mwifiex_adapter *adapter, u8 bits) else if ((cs & bits) == bits) return 0; - udelay(10); + usleep_range(10, 20); } dev_err(adapter->dev, "poll card status failed, tries = %d\n", @@ -761,7 +761,7 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, if (len) break; - udelay(10); + usleep_range(10, 20); } if (!len) { -- cgit From bb7de2bad5cb527e5fdc6b64d7f5d6e5009f2962 Mon Sep 17 00:00:00 2001 From: Yogesh Ashok Powar Date: Mon, 12 Mar 2012 19:35:12 -0700 Subject: mwifiex: rearrange if and else blocks to avoid extra indentation This adds better readability. Signed-off-by: Yogesh Ashok Powar Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/11n_rxreorder.c | 15 +++-- drivers/net/wireless/mwifiex/sta_cmdresp.c | 93 +++++++++++++--------------- drivers/net/wireless/mwifiex/wmm.c | 30 ++++----- 3 files changed, 68 insertions(+), 70 deletions(-) diff --git a/drivers/net/wireless/mwifiex/11n_rxreorder.c b/drivers/net/wireless/mwifiex/11n_rxreorder.c index ad41fab970b5..491cd85cb6f2 100644 --- a/drivers/net/wireless/mwifiex/11n_rxreorder.c +++ b/drivers/net/wireless/mwifiex/11n_rxreorder.c @@ -205,14 +205,17 @@ mwifiex_flush_data(unsigned long context) int start_win; start_win = mwifiex_11n_find_last_seq_num(reorder_cnxt->ptr); - if (start_win >= 0) { - dev_dbg(reorder_cnxt->priv->adapter->dev, - "info: flush data %d\n", start_win); + + if (start_win < 0) + return; + + dev_dbg(reorder_cnxt->priv->adapter->dev, "info: flush data %d\n", + start_win); mwifiex_11n_dispatch_pkt_until_start_win(reorder_cnxt->priv, reorder_cnxt->ptr, - ((reorder_cnxt->ptr->start_win + - start_win + 1) & (MAX_TID_VALUE - 1))); - } + ((reorder_cnxt->ptr->start_win + + start_win + 1) & + (MAX_TID_VALUE - 1))); } /* diff --git a/drivers/net/wireless/mwifiex/sta_cmdresp.c b/drivers/net/wireless/mwifiex/sta_cmdresp.c index 3f13ff0cd262..a2a9c513e26b 100644 --- a/drivers/net/wireless/mwifiex/sta_cmdresp.c +++ b/drivers/net/wireless/mwifiex/sta_cmdresp.c @@ -327,31 +327,26 @@ static int mwifiex_ret_tx_rate_cfg(struct mwifiex_private *priv, HostCmd_CMD_802_11_TX_RATE_QUERY, HostCmd_ACT_GEN_GET, 0, NULL); - if (ds_rate) { - if (le16_to_cpu(rate_cfg->action) == HostCmd_ACT_GEN_GET) { - if (priv->is_data_rate_auto) { - ds_rate->is_rate_auto = 1; - } else { - ds_rate->rate = mwifiex_get_rate_index(priv-> - bitmap_rates, - sizeof(priv-> - bitmap_rates)); - if (ds_rate->rate >= - MWIFIEX_RATE_BITMAP_OFDM0 - && ds_rate->rate <= - MWIFIEX_RATE_BITMAP_OFDM7) - ds_rate->rate -= - (MWIFIEX_RATE_BITMAP_OFDM0 - - MWIFIEX_RATE_INDEX_OFDM0); - if (ds_rate->rate >= - MWIFIEX_RATE_BITMAP_MCS0 - && ds_rate->rate <= - MWIFIEX_RATE_BITMAP_MCS127) - ds_rate->rate -= - (MWIFIEX_RATE_BITMAP_MCS0 - - MWIFIEX_RATE_INDEX_MCS0); - } - } + if (!ds_rate) + return ret; + + if (le16_to_cpu(rate_cfg->action) == HostCmd_ACT_GEN_GET) { + if (priv->is_data_rate_auto) { + ds_rate->is_rate_auto = 1; + return ret; + } + ds_rate->rate = mwifiex_get_rate_index(priv->bitmap_rates, + sizeof(priv->bitmap_rates)); + + if (ds_rate->rate >= MWIFIEX_RATE_BITMAP_OFDM0 && + ds_rate->rate <= MWIFIEX_RATE_BITMAP_OFDM7) + ds_rate->rate -= (MWIFIEX_RATE_BITMAP_OFDM0 - + MWIFIEX_RATE_INDEX_OFDM0); + + if (ds_rate->rate >= MWIFIEX_RATE_BITMAP_MCS0 && + ds_rate->rate <= MWIFIEX_RATE_BITMAP_MCS127) + ds_rate->rate -= (MWIFIEX_RATE_BITMAP_MCS0 - + MWIFIEX_RATE_INDEX_MCS0); } return ret; @@ -369,34 +364,32 @@ static int mwifiex_get_power_level(struct mwifiex_private *priv, void *data_buf) struct mwifiex_types_power_group *pg_tlv_hdr; struct mwifiex_power_group *pg; - if (data_buf) { - pg_tlv_hdr = - (struct mwifiex_types_power_group *) ((u8 *) data_buf - + sizeof(struct host_cmd_ds_txpwr_cfg)); - pg = (struct mwifiex_power_group *) ((u8 *) pg_tlv_hdr + - sizeof(struct mwifiex_types_power_group)); - length = pg_tlv_hdr->length; - if (length > 0) { + if (!data_buf) + return -1; + + pg_tlv_hdr = (struct mwifiex_types_power_group *) + ((u8 *) data_buf + sizeof(struct host_cmd_ds_txpwr_cfg)); + pg = (struct mwifiex_power_group *) + ((u8 *) pg_tlv_hdr + sizeof(struct mwifiex_types_power_group)); + length = pg_tlv_hdr->length; + if (length > 0) { + max_power = pg->power_max; + min_power = pg->power_min; + length -= sizeof(struct mwifiex_power_group); + } + while (length) { + pg++; + if (max_power < pg->power_max) max_power = pg->power_max; - min_power = pg->power_min; - length -= sizeof(struct mwifiex_power_group); - } - while (length) { - pg++; - if (max_power < pg->power_max) - max_power = pg->power_max; - if (min_power > pg->power_min) - min_power = pg->power_min; + if (min_power > pg->power_min) + min_power = pg->power_min; - length -= sizeof(struct mwifiex_power_group); - } - if (pg_tlv_hdr->length > 0) { - priv->min_tx_power_level = (u8) min_power; - priv->max_tx_power_level = (u8) max_power; - } - } else { - return -1; + length -= sizeof(struct mwifiex_power_group); + } + if (pg_tlv_hdr->length > 0) { + priv->min_tx_power_level = (u8) min_power; + priv->max_tx_power_level = (u8) max_power; } return 0; diff --git a/drivers/net/wireless/mwifiex/wmm.c b/drivers/net/wireless/mwifiex/wmm.c index 5757ebd2163a..6f0cc210f79a 100644 --- a/drivers/net/wireless/mwifiex/wmm.c +++ b/drivers/net/wireless/mwifiex/wmm.c @@ -850,6 +850,7 @@ mwifiex_wmm_get_highest_priolist_ptr(struct mwifiex_adapter *adapter, struct mwifiex_ra_list_tbl *ptr, *head; struct mwifiex_bss_prio_node *bssprio_node, *bssprio_head; struct mwifiex_tid_tbl *tid_ptr; + atomic_t *hqp; int is_list_empty; unsigned long flags; int i, j; @@ -879,12 +880,8 @@ mwifiex_wmm_get_highest_priolist_ptr(struct mwifiex_adapter *adapter, } do { - atomic_t *hqp; - spinlock_t *lock; - priv_tmp = bssprio_node->priv; hqp = &priv_tmp->wmm.highest_queued_prio; - lock = &priv_tmp->wmm.ra_list_spinlock; for (i = atomic_read(hqp); i >= LOW_PRIO_TID; --i) { @@ -923,16 +920,10 @@ mwifiex_wmm_get_highest_priolist_ptr(struct mwifiex_adapter *adapter, do { is_list_empty = skb_queue_empty(&ptr->skb_head); - if (!is_list_empty) { - spin_lock_irqsave(lock, flags); - if (atomic_read(hqp) > i) - atomic_set(hqp, i); - spin_unlock_irqrestore(lock, - flags); - *priv = priv_tmp; - *tid = tos_to_tid[i]; - return ptr; - } + + if (!is_list_empty) + goto found; + /* Get next ra */ ptr = list_first_entry(&ptr->list, struct mwifiex_ra_list_tbl, @@ -969,6 +960,17 @@ mwifiex_wmm_get_highest_priolist_ptr(struct mwifiex_adapter *adapter, } while (bssprio_node != bssprio_head); } return NULL; + +found: + spin_lock_irqsave(&priv_tmp->wmm.ra_list_spinlock, flags); + if (atomic_read(hqp) > i) + atomic_set(hqp, i); + spin_unlock_irqrestore(&priv_tmp->wmm.ra_list_spinlock, flags); + + *priv = priv_tmp; + *tid = tos_to_tid[i]; + + return ptr; } /* -- cgit From 8c00228e98bd2c8ab92b6f364f196cb60a7ff76d Mon Sep 17 00:00:00 2001 From: Yogesh Ashok Powar Date: Mon, 12 Mar 2012 19:35:13 -0700 Subject: mwifiex: rename fuctions and variables for better readability Renaming the long fuctions and variable names from 11n_rxreoder.c file to shorter ones for better readability. Signed-off-by: Yogesh Ashok Powar Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/11n_rxreorder.c | 160 ++++++++++++--------------- 1 file changed, 73 insertions(+), 87 deletions(-) diff --git a/drivers/net/wireless/mwifiex/11n_rxreorder.c b/drivers/net/wireless/mwifiex/11n_rxreorder.c index 491cd85cb6f2..06f5d3684027 100644 --- a/drivers/net/wireless/mwifiex/11n_rxreorder.c +++ b/drivers/net/wireless/mwifiex/11n_rxreorder.c @@ -27,31 +27,31 @@ #include "11n_rxreorder.h" /* - * This function dispatches all packets in the Rx reorder table. + * This function dispatches all packets in the Rx reorder table until the + * start window. * * There could be holes in the buffer, which are skipped by the function. * Since the buffer is linear, the function uses rotation to simulate * circular buffer. */ static void -mwifiex_11n_dispatch_pkt_until_start_win(struct mwifiex_private *priv, - struct mwifiex_rx_reorder_tbl - *rx_reor_tbl_ptr, int start_win) +mwifiex_11n_dispatch_pkt(struct mwifiex_private *priv, + struct mwifiex_rx_reorder_tbl *tbl, int start_win) { - int no_pkt_to_send, i; + int pkt_to_send, i; void *rx_tmp_ptr; unsigned long flags; - no_pkt_to_send = (start_win > rx_reor_tbl_ptr->start_win) ? - min((start_win - rx_reor_tbl_ptr->start_win), - rx_reor_tbl_ptr->win_size) : rx_reor_tbl_ptr->win_size; + pkt_to_send = (start_win > tbl->start_win) ? + min((start_win - tbl->start_win), tbl->win_size) : + tbl->win_size; - for (i = 0; i < no_pkt_to_send; ++i) { + for (i = 0; i < pkt_to_send; ++i) { spin_lock_irqsave(&priv->rx_pkt_lock, flags); rx_tmp_ptr = NULL; - if (rx_reor_tbl_ptr->rx_reorder_ptr[i]) { - rx_tmp_ptr = rx_reor_tbl_ptr->rx_reorder_ptr[i]; - rx_reor_tbl_ptr->rx_reorder_ptr[i] = NULL; + if (tbl->rx_reorder_ptr[i]) { + rx_tmp_ptr = tbl->rx_reorder_ptr[i]; + tbl->rx_reorder_ptr[i] = NULL; } spin_unlock_irqrestore(&priv->rx_pkt_lock, flags); if (rx_tmp_ptr) @@ -63,13 +63,12 @@ mwifiex_11n_dispatch_pkt_until_start_win(struct mwifiex_private *priv, * We don't have a circular buffer, hence use rotation to simulate * circular buffer */ - for (i = 0; i < rx_reor_tbl_ptr->win_size - no_pkt_to_send; ++i) { - rx_reor_tbl_ptr->rx_reorder_ptr[i] = - rx_reor_tbl_ptr->rx_reorder_ptr[no_pkt_to_send + i]; - rx_reor_tbl_ptr->rx_reorder_ptr[no_pkt_to_send + i] = NULL; + for (i = 0; i < tbl->win_size - pkt_to_send; ++i) { + tbl->rx_reorder_ptr[i] = tbl->rx_reorder_ptr[pkt_to_send + i]; + tbl->rx_reorder_ptr[pkt_to_send + i] = NULL; } - rx_reor_tbl_ptr->start_win = start_win; + tbl->start_win = start_win; spin_unlock_irqrestore(&priv->rx_pkt_lock, flags); } @@ -83,20 +82,20 @@ mwifiex_11n_dispatch_pkt_until_start_win(struct mwifiex_private *priv, */ static void mwifiex_11n_scan_and_dispatch(struct mwifiex_private *priv, - struct mwifiex_rx_reorder_tbl *rx_reor_tbl_ptr) + struct mwifiex_rx_reorder_tbl *tbl) { int i, j, xchg; void *rx_tmp_ptr; unsigned long flags; - for (i = 0; i < rx_reor_tbl_ptr->win_size; ++i) { + for (i = 0; i < tbl->win_size; ++i) { spin_lock_irqsave(&priv->rx_pkt_lock, flags); - if (!rx_reor_tbl_ptr->rx_reorder_ptr[i]) { + if (!tbl->rx_reorder_ptr[i]) { spin_unlock_irqrestore(&priv->rx_pkt_lock, flags); break; } - rx_tmp_ptr = rx_reor_tbl_ptr->rx_reorder_ptr[i]; - rx_reor_tbl_ptr->rx_reorder_ptr[i] = NULL; + rx_tmp_ptr = tbl->rx_reorder_ptr[i]; + tbl->rx_reorder_ptr[i] = NULL; spin_unlock_irqrestore(&priv->rx_pkt_lock, flags); mwifiex_process_rx_packet(priv->adapter, rx_tmp_ptr); } @@ -107,15 +106,13 @@ mwifiex_11n_scan_and_dispatch(struct mwifiex_private *priv, * circular buffer */ if (i > 0) { - xchg = rx_reor_tbl_ptr->win_size - i; + xchg = tbl->win_size - i; for (j = 0; j < xchg; ++j) { - rx_reor_tbl_ptr->rx_reorder_ptr[j] = - rx_reor_tbl_ptr->rx_reorder_ptr[i + j]; - rx_reor_tbl_ptr->rx_reorder_ptr[i + j] = NULL; + tbl->rx_reorder_ptr[j] = tbl->rx_reorder_ptr[i + j]; + tbl->rx_reorder_ptr[i + j] = NULL; } } - rx_reor_tbl_ptr->start_win = (rx_reor_tbl_ptr->start_win + i) - &(MAX_TID_VALUE - 1); + tbl->start_win = (tbl->start_win + i) & (MAX_TID_VALUE - 1); spin_unlock_irqrestore(&priv->rx_pkt_lock, flags); } @@ -126,28 +123,25 @@ mwifiex_11n_scan_and_dispatch(struct mwifiex_private *priv, * pending packets in the Rx reorder table before deletion. */ static void -mwifiex_11n_delete_rx_reorder_tbl_entry(struct mwifiex_private *priv, - struct mwifiex_rx_reorder_tbl - *rx_reor_tbl_ptr) +mwifiex_del_rx_reorder_entry(struct mwifiex_private *priv, + struct mwifiex_rx_reorder_tbl *tbl) { unsigned long flags; - if (!rx_reor_tbl_ptr) + if (!tbl) return; - mwifiex_11n_dispatch_pkt_until_start_win(priv, rx_reor_tbl_ptr, - (rx_reor_tbl_ptr->start_win + - rx_reor_tbl_ptr->win_size) - &(MAX_TID_VALUE - 1)); + mwifiex_11n_dispatch_pkt(priv, tbl, (tbl->start_win + tbl->win_size) & + (MAX_TID_VALUE - 1)); - del_timer(&rx_reor_tbl_ptr->timer_context.timer); + del_timer(&tbl->timer_context.timer); spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags); - list_del(&rx_reor_tbl_ptr->list); + list_del(&tbl->list); spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags); - kfree(rx_reor_tbl_ptr->rx_reorder_ptr); - kfree(rx_reor_tbl_ptr); + kfree(tbl->rx_reorder_ptr); + kfree(tbl); } /* @@ -157,16 +151,15 @@ mwifiex_11n_delete_rx_reorder_tbl_entry(struct mwifiex_private *priv, static struct mwifiex_rx_reorder_tbl * mwifiex_11n_get_rx_reorder_tbl(struct mwifiex_private *priv, int tid, u8 *ta) { - struct mwifiex_rx_reorder_tbl *rx_reor_tbl_ptr; + struct mwifiex_rx_reorder_tbl *tbl; unsigned long flags; spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags); - list_for_each_entry(rx_reor_tbl_ptr, &priv->rx_reorder_tbl_ptr, list) { - if ((!memcmp(rx_reor_tbl_ptr->ta, ta, ETH_ALEN)) - && (rx_reor_tbl_ptr->tid == tid)) { + list_for_each_entry(tbl, &priv->rx_reorder_tbl_ptr, list) { + if (!memcmp(tbl->ta, ta, ETH_ALEN) && tbl->tid == tid) { spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags); - return rx_reor_tbl_ptr; + return tbl; } } spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags); @@ -200,22 +193,19 @@ mwifiex_11n_find_last_seq_num(struct mwifiex_rx_reorder_tbl *rx_reorder_tbl_ptr) static void mwifiex_flush_data(unsigned long context) { - struct reorder_tmr_cnxt *reorder_cnxt = + struct reorder_tmr_cnxt *ctx = (struct reorder_tmr_cnxt *) context; int start_win; - start_win = mwifiex_11n_find_last_seq_num(reorder_cnxt->ptr); + start_win = mwifiex_11n_find_last_seq_num(ctx->ptr); if (start_win < 0) return; - dev_dbg(reorder_cnxt->priv->adapter->dev, "info: flush data %d\n", - start_win); - mwifiex_11n_dispatch_pkt_until_start_win(reorder_cnxt->priv, - reorder_cnxt->ptr, - ((reorder_cnxt->ptr->start_win - + start_win + 1) & - (MAX_TID_VALUE - 1))); + dev_dbg(ctx->priv->adapter->dev, "info: flush data %d\n", start_win); + mwifiex_11n_dispatch_pkt(ctx->priv, ctx->ptr, + (ctx->ptr->start_win + start_win + 1) & + (MAX_TID_VALUE - 1)); } /* @@ -233,7 +223,7 @@ mwifiex_11n_create_rx_reorder_tbl(struct mwifiex_private *priv, u8 *ta, int tid, int win_size, int seq_num) { int i; - struct mwifiex_rx_reorder_tbl *rx_reor_tbl_ptr, *new_node; + struct mwifiex_rx_reorder_tbl *tbl, *new_node; u16 last_seq = 0; unsigned long flags; @@ -241,13 +231,12 @@ mwifiex_11n_create_rx_reorder_tbl(struct mwifiex_private *priv, u8 *ta, * If we get a TID, ta pair which is already present dispatch all the * the packets and move the window size until the ssn */ - rx_reor_tbl_ptr = mwifiex_11n_get_rx_reorder_tbl(priv, tid, ta); - if (rx_reor_tbl_ptr) { - mwifiex_11n_dispatch_pkt_until_start_win(priv, rx_reor_tbl_ptr, - seq_num); + tbl = mwifiex_11n_get_rx_reorder_tbl(priv, tid, ta); + if (tbl) { + mwifiex_11n_dispatch_pkt(priv, tbl, seq_num); return; } - /* if !rx_reor_tbl_ptr then create one */ + /* if !tbl then create one */ new_node = kzalloc(sizeof(struct mwifiex_rx_reorder_tbl), GFP_KERNEL); if (!new_node) { dev_err(priv->adapter->dev, "%s: failed to alloc new_node\n", @@ -404,24 +393,23 @@ int mwifiex_11n_rx_reorder_pkt(struct mwifiex_private *priv, u16 seq_num, u16 tid, u8 *ta, u8 pkt_type, void *payload) { - struct mwifiex_rx_reorder_tbl *rx_reor_tbl_ptr; + struct mwifiex_rx_reorder_tbl *tbl; int start_win, end_win, win_size; u16 pkt_index; - rx_reor_tbl_ptr = - mwifiex_11n_get_rx_reorder_tbl((struct mwifiex_private *) priv, - tid, ta); - if (!rx_reor_tbl_ptr) { + tbl = mwifiex_11n_get_rx_reorder_tbl((struct mwifiex_private *) priv, + tid, ta); + if (!tbl) { if (pkt_type != PKT_TYPE_BAR) mwifiex_process_rx_packet(priv->adapter, payload); return 0; } - start_win = rx_reor_tbl_ptr->start_win; - win_size = rx_reor_tbl_ptr->win_size; + start_win = tbl->start_win; + win_size = tbl->win_size; end_win = ((start_win + win_size) - 1) & (MAX_TID_VALUE - 1); - del_timer(&rx_reor_tbl_ptr->timer_context.timer); - mod_timer(&rx_reor_tbl_ptr->timer_context.timer, jiffies - + (MIN_FLUSH_TIMER_MS * win_size * HZ) / 1000); + del_timer(&tbl->timer_context.timer); + mod_timer(&tbl->timer_context.timer, + jiffies + (MIN_FLUSH_TIMER_MS * win_size * HZ) / 1000); /* * If seq_num is less then starting win then ignore and drop the @@ -452,8 +440,7 @@ int mwifiex_11n_rx_reorder_pkt(struct mwifiex_private *priv, start_win = (end_win - win_size) + 1; else start_win = (MAX_TID_VALUE - (win_size - seq_num)) + 1; - mwifiex_11n_dispatch_pkt_until_start_win(priv, - rx_reor_tbl_ptr, start_win); + mwifiex_11n_dispatch_pkt(priv, tbl, start_win); } if (pkt_type != PKT_TYPE_BAR) { @@ -462,17 +449,17 @@ int mwifiex_11n_rx_reorder_pkt(struct mwifiex_private *priv, else pkt_index = (seq_num+MAX_TID_VALUE) - start_win; - if (rx_reor_tbl_ptr->rx_reorder_ptr[pkt_index]) + if (tbl->rx_reorder_ptr[pkt_index]) return -1; - rx_reor_tbl_ptr->rx_reorder_ptr[pkt_index] = payload; + tbl->rx_reorder_ptr[pkt_index] = payload; } /* * Dispatch all packets sequentially from start_win until a * hole is found and adjust the start_win appropriately */ - mwifiex_11n_scan_and_dispatch(priv, rx_reor_tbl_ptr); + mwifiex_11n_scan_and_dispatch(priv, tbl); return 0; } @@ -486,7 +473,7 @@ void mwifiex_del_ba_tbl(struct mwifiex_private *priv, int tid, u8 *peer_mac, u8 type, int initiator) { - struct mwifiex_rx_reorder_tbl *rx_reor_tbl_ptr; + struct mwifiex_rx_reorder_tbl *tbl; struct mwifiex_tx_ba_stream_tbl *ptx_tbl; u8 cleanup_rx_reorder_tbl; unsigned long flags; @@ -500,14 +487,14 @@ mwifiex_del_ba_tbl(struct mwifiex_private *priv, int tid, u8 *peer_mac, "initiator=%d\n", peer_mac, tid, initiator); if (cleanup_rx_reorder_tbl) { - rx_reor_tbl_ptr = mwifiex_11n_get_rx_reorder_tbl(priv, tid, + tbl = mwifiex_11n_get_rx_reorder_tbl(priv, tid, peer_mac); - if (!rx_reor_tbl_ptr) { + if (!tbl) { dev_dbg(priv->adapter->dev, "event: TID, TA not found in table\n"); return; } - mwifiex_11n_delete_rx_reorder_tbl_entry(priv, rx_reor_tbl_ptr); + mwifiex_del_rx_reorder_entry(priv, tbl); } else { ptx_tbl = mwifiex_get_ba_tbl(priv, tid, peer_mac); if (!ptx_tbl) { @@ -535,7 +522,7 @@ int mwifiex_ret_11n_addba_resp(struct mwifiex_private *priv, (struct host_cmd_ds_11n_addba_rsp *) &resp->params.add_ba_rsp; int tid, win_size; - struct mwifiex_rx_reorder_tbl *rx_reor_tbl_ptr; + struct mwifiex_rx_reorder_tbl *tbl; uint16_t block_ack_param_set; block_ack_param_set = le16_to_cpu(add_ba_rsp->block_ack_param_set); @@ -557,13 +544,12 @@ int mwifiex_ret_11n_addba_resp(struct mwifiex_private *priv, tid, add_ba_rsp->ssn, win_size); } else { dev_err(priv->adapter->dev, "ADDBA RSP: failed %pM tid=%d)\n", - add_ba_rsp->peer_mac_addr, tid); + add_ba_rsp->peer_mac_addr, tid); - rx_reor_tbl_ptr = mwifiex_11n_get_rx_reorder_tbl(priv, - tid, add_ba_rsp->peer_mac_addr); - if (rx_reor_tbl_ptr) - mwifiex_11n_delete_rx_reorder_tbl_entry(priv, - rx_reor_tbl_ptr); + tbl = mwifiex_11n_get_rx_reorder_tbl(priv, tid, + add_ba_rsp->peer_mac_addr); + if (tbl) + mwifiex_del_rx_reorder_entry(priv, tbl); } return 0; @@ -602,7 +588,7 @@ void mwifiex_11n_cleanup_reorder_tbl(struct mwifiex_private *priv) list_for_each_entry_safe(del_tbl_ptr, tmp_node, &priv->rx_reorder_tbl_ptr, list) { spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags); - mwifiex_11n_delete_rx_reorder_tbl_entry(priv, del_tbl_ptr); + mwifiex_del_rx_reorder_entry(priv, del_tbl_ptr); spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags); } spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags); -- cgit From 6d430c2566467aaa6f39cbf7d0f6da5090db7007 Mon Sep 17 00:00:00 2001 From: Yegor Yefremov Date: Tue, 13 Mar 2012 10:57:51 +0100 Subject: Documentation: make exists consistent Signed-off-by: Yegor Yefremov Signed-off-by: John W. Linville --- Documentation/networking/mac80211-auth-assoc-deauth.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Documentation/networking/mac80211-auth-assoc-deauth.txt b/Documentation/networking/mac80211-auth-assoc-deauth.txt index 721773d2b9d2..e0a2aa585ca3 100644 --- a/Documentation/networking/mac80211-auth-assoc-deauth.txt +++ b/Documentation/networking/mac80211-auth-assoc-deauth.txt @@ -14,7 +14,7 @@ alt authentication needed (not FT) userspace->mac80211: authenticate alt authenticated/authenticating already -mac80211->driver: sta_state(AP, not-exist) +mac80211->driver: sta_state(AP, not-exists) mac80211->driver: bss_info_changed(clear BSSID) else associated note over mac80211,driver @@ -91,8 +91,8 @@ mac80211->driver: TX deauth/disassoc mac80211->driver: flush frames mac80211->driver: sta_state(AP,associated) mac80211->driver: sta_state(AP,authenticated) -mac80211->driver: sta_state(AP,exist) -mac80211->driver: sta_state(AP,not-exist) +mac80211->driver: sta_state(AP,exists) +mac80211->driver: sta_state(AP,not-exists) mac80211->driver: turn off powersave mac80211->driver: bss_info_changed(clear BSSID, not associated, no QoS, ...) mac80211->driver: config(non-HT channel type) -- cgit From 8e6cffb3b42f03a47a56ede928b006f117628646 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 13 Mar 2012 13:57:03 +0100 Subject: brmc80211: dont use jiffies for BSS TSF The cfg80211_inform_bss() timestamp argument is intended to be the TSF, not any form of host timestamp. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c index 15d7f00513be..d13ae9c299f2 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c @@ -2003,7 +2003,6 @@ static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_priv *cfg_priv, s32 err = 0; u16 channel; u32 freq; - u64 notify_timestamp; u16 notify_capability; u16 notify_interval; u8 *notify_ie; @@ -2026,7 +2025,6 @@ static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_priv *cfg_priv, freq = ieee80211_channel_to_frequency(channel, band->band); notify_channel = ieee80211_get_channel(wiphy, freq); - notify_timestamp = jiffies_to_msecs(jiffies)*1000; /* uSec */ notify_capability = le16_to_cpu(bi->capability); notify_interval = le16_to_cpu(bi->beacon_period); notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset); @@ -2040,10 +2038,9 @@ static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_priv *cfg_priv, WL_CONN("Capability: %X\n", notify_capability); WL_CONN("Beacon interval: %d\n", notify_interval); WL_CONN("Signal: %d\n", notify_signal); - WL_CONN("notify_timestamp: %#018llx\n", notify_timestamp); bss = cfg80211_inform_bss(wiphy, notify_channel, (const u8 *)bi->BSSID, - notify_timestamp, notify_capability, notify_interval, notify_ie, + 0, notify_capability, notify_interval, notify_ie, notify_ielen, notify_signal, GFP_KERNEL); if (!bss) @@ -2098,7 +2095,6 @@ static s32 wl_inform_ibss(struct brcmf_cfg80211_priv *cfg_priv, s32 err = 0; u16 channel; u32 freq; - u64 notify_timestamp; u16 notify_capability; u16 notify_interval; u8 *notify_ie; @@ -2134,7 +2130,6 @@ static s32 wl_inform_ibss(struct brcmf_cfg80211_priv *cfg_priv, freq = ieee80211_channel_to_frequency(channel, band->band); notify_channel = ieee80211_get_channel(wiphy, freq); - notify_timestamp = jiffies_to_msecs(jiffies)*1000; /* uSec */ notify_capability = le16_to_cpu(bi->capability); notify_interval = le16_to_cpu(bi->beacon_period); notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset); @@ -2145,10 +2140,9 @@ static s32 wl_inform_ibss(struct brcmf_cfg80211_priv *cfg_priv, WL_CONN("capability: %X\n", notify_capability); WL_CONN("beacon interval: %d\n", notify_interval); WL_CONN("signal: %d\n", notify_signal); - WL_CONN("notify_timestamp: %#018llx\n", notify_timestamp); bss = cfg80211_inform_bss(wiphy, notify_channel, bssid, - notify_timestamp, notify_capability, notify_interval, + 0, notify_capability, notify_interval, notify_ie, notify_ielen, notify_signal, GFP_KERNEL); if (!bss) { -- cgit From 7b8bcff2e0f11981dd6840f9feefe0914e4ea521 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 13 Mar 2012 13:57:04 +0100 Subject: cfg80211: clarify timestamp in cfg80211_inform_bss This is intended to be the timestamp sent by the peer in the beacon/probe response, not any form of host timestamp. Clarify the documentation and variable names. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- include/net/cfg80211.h | 7 +++---- net/wireless/scan.c | 7 +++---- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 66f460325e24..69b7ad3a9925 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -2697,7 +2697,7 @@ cfg80211_inform_bss_frame(struct wiphy *wiphy, * @wiphy: the wiphy reporting the BSS * @channel: The channel the frame was received on * @bssid: the BSSID of the BSS - * @timestamp: the TSF timestamp sent by the peer + * @tsf: the TSF sent by the peer in the beacon/probe response (or 0) * @capability: the capability field sent by the peer * @beacon_interval: the beacon interval announced by the peer * @ie: additional IEs sent by the peer @@ -2713,9 +2713,8 @@ cfg80211_inform_bss_frame(struct wiphy *wiphy, struct cfg80211_bss * __must_check cfg80211_inform_bss(struct wiphy *wiphy, struct ieee80211_channel *channel, - const u8 *bssid, - u64 timestamp, u16 capability, u16 beacon_interval, - const u8 *ie, size_t ielen, + const u8 *bssid, u64 tsf, u16 capability, + u16 beacon_interval, const u8 *ie, size_t ielen, s32 signal, gfp_t gfp); struct cfg80211_bss *cfg80211_get_bss(struct wiphy *wiphy, diff --git a/net/wireless/scan.c b/net/wireless/scan.c index afde7e5f0010..70faadf16a32 100644 --- a/net/wireless/scan.c +++ b/net/wireless/scan.c @@ -734,9 +734,8 @@ cfg80211_bss_update(struct cfg80211_registered_device *dev, struct cfg80211_bss* cfg80211_inform_bss(struct wiphy *wiphy, struct ieee80211_channel *channel, - const u8 *bssid, - u64 timestamp, u16 capability, u16 beacon_interval, - const u8 *ie, size_t ielen, + const u8 *bssid, u64 tsf, u16 capability, + u16 beacon_interval, const u8 *ie, size_t ielen, s32 signal, gfp_t gfp) { struct cfg80211_internal_bss *res; @@ -758,7 +757,7 @@ cfg80211_inform_bss(struct wiphy *wiphy, memcpy(res->pub.bssid, bssid, ETH_ALEN); res->pub.channel = channel; res->pub.signal = signal; - res->pub.tsf = timestamp; + res->pub.tsf = tsf; res->pub.beacon_interval = beacon_interval; res->pub.capability = capability; /* -- cgit From e9ac0745c734d39cb55ce45f1fb03a85c972b35a Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 13 Mar 2012 14:29:30 +0100 Subject: mac80211: rename bss_conf timestamp to last_tsf This value is not really very useful by itself, yet some drivers (including iwlwifi until I can figure out what it should do) use it. At least rename it to "last_tsf" to indicate the meaning and add a note that it may be really old. I suspect the value may become useful combined with the rx_status->mactime, but we don't (yet) store that value and pass it to the driver. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- drivers/net/wireless/iwlegacy/common.c | 2 +- drivers/net/wireless/iwlwifi/iwl-agn-rxon.c | 2 +- drivers/net/wireless/rt2x00/rt2x00config.c | 2 +- include/net/mac80211.h | 5 +++-- net/mac80211/driver-trace.h | 2 +- net/mac80211/mlme.c | 2 +- 6 files changed, 8 insertions(+), 7 deletions(-) diff --git a/drivers/net/wireless/iwlegacy/common.c b/drivers/net/wireless/iwlegacy/common.c index b42052b47d8e..e5ac04739bcc 100644 --- a/drivers/net/wireless/iwlegacy/common.c +++ b/drivers/net/wireless/iwlegacy/common.c @@ -5355,7 +5355,7 @@ il_mac_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, if (changes & BSS_CHANGED_ASSOC) { D_MAC80211("ASSOC %d\n", bss_conf->assoc); if (bss_conf->assoc) { - il->timestamp = bss_conf->timestamp; + il->timestamp = bss_conf->last_tsf; if (!il_is_rfkill(il)) il->ops->post_associate(il); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c index 36909077f994..2e1a31797a9e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c @@ -822,7 +822,7 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw, if (changes & BSS_CHANGED_ASSOC) { if (bss_conf->assoc) { - priv->timestamp = bss_conf->timestamp; + priv->timestamp = bss_conf->last_tsf; ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK; } else { /* diff --git a/drivers/net/wireless/rt2x00/rt2x00config.c b/drivers/net/wireless/rt2x00/rt2x00config.c index d7c0f86c9e43..293676bfa571 100644 --- a/drivers/net/wireless/rt2x00/rt2x00config.c +++ b/drivers/net/wireless/rt2x00/rt2x00config.c @@ -102,7 +102,7 @@ void rt2x00lib_config_erp(struct rt2x00_dev *rt2x00dev, /* Update the AID, this is needed for dynamic PS support */ rt2x00dev->aid = bss_conf->assoc ? bss_conf->aid : 0; - rt2x00dev->last_beacon = bss_conf->timestamp; + rt2x00dev->last_beacon = bss_conf->last_tsf; /* Update global beacon interval time, this is needed for PS support */ rt2x00dev->beacon_int = bss_conf->beacon_int; diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 44e4dfcb5722..9a012be615ff 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -229,7 +229,8 @@ enum ieee80211_rssi_event { * valid in station mode only while @assoc is true and if also * requested by %IEEE80211_HW_NEED_DTIM_PERIOD (cf. also hw conf * @ps_dtim_period) - * @timestamp: beacon timestamp + * @last_tsf: last beacon's/probe response's TSF timestamp (could be old + * as it may have been received during scanning long ago) * @beacon_int: beacon interval * @assoc_capability: capabilities taken from assoc resp * @basic_rates: bitmap of basic rates, each bit stands for an @@ -276,7 +277,7 @@ struct ieee80211_bss_conf { u8 dtim_period; u16 beacon_int; u16 assoc_capability; - u64 timestamp; + u64 last_tsf; u32 basic_rates; int mcast_rate[IEEE80211_NUM_BANDS]; u16 ht_operation_mode; diff --git a/net/mac80211/driver-trace.h b/net/mac80211/driver-trace.h index 7034209ad3f4..21d6f5290a1c 100644 --- a/net/mac80211/driver-trace.h +++ b/net/mac80211/driver-trace.h @@ -296,7 +296,7 @@ TRACE_EVENT(drv_bss_info_changed, __entry->dtimper = info->dtim_period; __entry->bcnint = info->beacon_int; __entry->assoc_cap = info->assoc_capability; - __entry->timestamp = info->timestamp; + __entry->timestamp = info->last_tsf; __entry->basic_rates = info->basic_rates; __entry->enable_beacon = info->enable_beacon; __entry->ht_operation_mode = info->ht_operation_mode; diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 39c13939008b..90d1db36cdef 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -1318,7 +1318,7 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata, bss_info_changed |= BSS_CHANGED_ASSOC; /* set timing information */ bss_conf->beacon_int = cbss->beacon_interval; - bss_conf->timestamp = cbss->tsf; + bss_conf->last_tsf = cbss->tsf; bss_info_changed |= BSS_CHANGED_BEACON_INT; bss_info_changed |= ieee80211_handle_bss_capability(sdata, -- cgit From 3117bbdb7899d43927c8ce4fe885ab7c1231c121 Mon Sep 17 00:00:00 2001 From: Paul Stewart Date: Tue, 13 Mar 2012 07:46:18 -0700 Subject: mac80211: Don't let regulatory make us deaf When regulatory information changes our HT behavior (e.g, when we get a country code from the AP we have just associated with), we should use this information to change the power with which we transmit, and what channels we transmit. Sometimes the channel parameters we derive from regulatory information contradicts the parameters we used in association. For example, we could have associated specifying HT40, but the regulatory rules we apply may forbid HT40 operation. In the situation above, we should reconfigure ourselves to transmit in HT20 only, however it makes no sense for us to disable receive in HT40, since if we associated with these parameters, the AP has every reason to expect we can and will receive packets this way. The code in mac80211 does not have the capability of sending the appropriate action frames to signal a change in HT behaviour so the AP has no clue we can no longer receive frames encoded this way. In some broken AP implementations, this can leave us effectively deaf if the AP never retries in lower HT rates. This change breaks up the channel_type parameter in the ieee80211_enable_ht function into a separate receive and transmit part. It honors the channel flags set by regulatory in order to configure the rate control algorithm, but uses the capability flags to configure the channel on the radio, since these were used in association to set the AP's transmit rate. Signed-off-by: Paul Stewart Cc: Sam Leffler Cc: Johannes Berg Reviewed-by: Luis R Rodriguez Signed-off-by: John W. Linville --- net/mac80211/chan.c | 27 +++++++++++++++++++++++++++ net/mac80211/ieee80211_i.h | 3 +++ net/mac80211/mlme.c | 32 ++++++++++++++++---------------- net/mac80211/rx.c | 8 +++++--- 4 files changed, 51 insertions(+), 19 deletions(-) diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c index d1f7abddb182..e00ce8c3e28e 100644 --- a/net/mac80211/chan.c +++ b/net/mac80211/chan.c @@ -3,6 +3,7 @@ */ #include +#include #include "ieee80211_i.h" static enum ieee80211_chan_mode @@ -134,3 +135,29 @@ bool ieee80211_set_channel_type(struct ieee80211_local *local, return result; } + +/* + * ieee80211_get_tx_channel_type returns the channel type we should + * use for packet transmission, given the channel capability and + * whatever regulatory flags we have been given. + */ +enum nl80211_channel_type ieee80211_get_tx_channel_type( + struct ieee80211_local *local, + enum nl80211_channel_type channel_type) +{ + switch (channel_type) { + case NL80211_CHAN_HT40PLUS: + if (local->hw.conf.channel->flags & + IEEE80211_CHAN_NO_HT40PLUS) + return NL80211_CHAN_HT20; + break; + case NL80211_CHAN_HT40MINUS: + if (local->hw.conf.channel->flags & + IEEE80211_CHAN_NO_HT40MINUS) + return NL80211_CHAN_HT20; + break; + default: + break; + } + return channel_type; +} diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 173c1396070d..63fb0eb79d8e 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -1502,6 +1502,9 @@ bool ieee80211_set_channel_type(struct ieee80211_local *local, enum nl80211_channel_type chantype); enum nl80211_channel_type ieee80211_ht_info_to_channel_type(struct ieee80211_ht_info *ht_info); +enum nl80211_channel_type ieee80211_get_tx_channel_type( + struct ieee80211_local *local, + enum nl80211_channel_type channel_type); #ifdef CONFIG_MAC80211_NOINLINE #define debug_noinline noinline diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 90d1db36cdef..0df22372af8d 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -189,7 +189,8 @@ static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata, u16 ht_opmode; bool enable_ht = true; enum nl80211_channel_type prev_chantype; - enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT; + enum nl80211_channel_type rx_channel_type = NL80211_CHAN_NO_HT; + enum nl80211_channel_type tx_channel_type; sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; prev_chantype = sdata->vif.bss_conf.channel_type; @@ -216,7 +217,7 @@ static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata, } if (enable_ht) { - channel_type = NL80211_CHAN_HT20; + rx_channel_type = NL80211_CHAN_HT20; if (!(ap_ht_cap_flags & IEEE80211_HT_CAP_40MHZ_INTOLERANT) && !ieee80111_cfg_override_disables_ht40(sdata) && @@ -224,29 +225,28 @@ static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata, (hti->ht_param & IEEE80211_HT_PARAM_CHAN_WIDTH_ANY)) { switch(hti->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) { case IEEE80211_HT_PARAM_CHA_SEC_ABOVE: - if (!(local->hw.conf.channel->flags & - IEEE80211_CHAN_NO_HT40PLUS)) - channel_type = NL80211_CHAN_HT40PLUS; + rx_channel_type = NL80211_CHAN_HT40PLUS; break; case IEEE80211_HT_PARAM_CHA_SEC_BELOW: - if (!(local->hw.conf.channel->flags & - IEEE80211_CHAN_NO_HT40MINUS)) - channel_type = NL80211_CHAN_HT40MINUS; + rx_channel_type = NL80211_CHAN_HT40MINUS; break; } } } + tx_channel_type = ieee80211_get_tx_channel_type(local, rx_channel_type); + if (local->tmp_channel) - local->tmp_channel_type = channel_type; + local->tmp_channel_type = rx_channel_type; - if (!ieee80211_set_channel_type(local, sdata, channel_type)) { + if (!ieee80211_set_channel_type(local, sdata, rx_channel_type)) { /* can only fail due to HT40+/- mismatch */ - channel_type = NL80211_CHAN_HT20; - WARN_ON(!ieee80211_set_channel_type(local, sdata, channel_type)); + rx_channel_type = NL80211_CHAN_HT20; + WARN_ON(!ieee80211_set_channel_type(local, sdata, + rx_channel_type)); } - if (beacon_htcap_ie && (prev_chantype != channel_type)) { + if (beacon_htcap_ie && (prev_chantype != rx_channel_type)) { /* * Whenever the AP announces the HT mode change that can be * 40MHz intolerant or etc., it would be safer to stop tx @@ -264,13 +264,13 @@ static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata, /* channel_type change automatically detected */ ieee80211_hw_config(local, 0); - if (prev_chantype != channel_type) { + if (prev_chantype != tx_channel_type) { rcu_read_lock(); sta = sta_info_get(sdata, bssid); if (sta) rate_control_rate_update(local, sband, sta, IEEE80211_RC_HT_CHANGED, - channel_type); + tx_channel_type); rcu_read_unlock(); if (beacon_htcap_ie) @@ -283,7 +283,7 @@ static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata, /* if bss configuration changed store the new one */ if (sdata->ht_opmode_valid != enable_ht || sdata->vif.bss_conf.ht_operation_mode != ht_opmode || - prev_chantype != channel_type) { + prev_chantype != rx_channel_type) { changed |= BSS_CHANGED_HT; sdata->vif.bss_conf.ht_operation_mode = ht_opmode; sdata->ht_opmode_valid = enable_ht; diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 53c88d145472..bcfe8c77c839 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -2269,9 +2269,11 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) sband = rx->local->hw.wiphy->bands[status->band]; - rate_control_rate_update(local, sband, rx->sta, - IEEE80211_RC_SMPS_CHANGED, - local->_oper_channel_type); + rate_control_rate_update( + local, sband, rx->sta, + IEEE80211_RC_SMPS_CHANGED, + ieee80211_get_tx_channel_type( + local, local->_oper_channel_type)); goto handled; } default: -- cgit From 842668417c13f5fca19d9db29f508500cd621af0 Mon Sep 17 00:00:00 2001 From: Yogesh Ashok Powar Date: Tue, 13 Mar 2012 19:22:34 -0700 Subject: mwifiex: fix checkpatch --strict warnings/errors Part 1 For files 11n.c, 11n.h, 11n_aggr.c, 11n_rxreorder.c Signed-off-by: Yogesh Ashok Powar Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/11n.c | 22 +++++++-------- drivers/net/wireless/mwifiex/11n.h | 7 ++--- drivers/net/wireless/mwifiex/11n_aggr.c | 15 +++++----- drivers/net/wireless/mwifiex/11n_rxreorder.c | 42 +++++++++++++++------------- 4 files changed, 43 insertions(+), 43 deletions(-) diff --git a/drivers/net/wireless/mwifiex/11n.c b/drivers/net/wireless/mwifiex/11n.c index aeb456d6396f..a5e182b5e944 100644 --- a/drivers/net/wireless/mwifiex/11n.c +++ b/drivers/net/wireless/mwifiex/11n.c @@ -44,16 +44,16 @@ mwifiex_fill_cap_info(struct mwifiex_private *priv, u8 radio_type, ht_cap->ht_cap.ampdu_params_info = (sband->ht_cap.ampdu_factor & - IEEE80211_HT_AMPDU_PARM_FACTOR)| + IEEE80211_HT_AMPDU_PARM_FACTOR) | ((sband->ht_cap.ampdu_density << IEEE80211_HT_AMPDU_PARM_DENSITY_SHIFT) & IEEE80211_HT_AMPDU_PARM_DENSITY); memcpy((u8 *) &ht_cap->ht_cap.mcs, &sband->ht_cap.mcs, - sizeof(sband->ht_cap.mcs)); + sizeof(sband->ht_cap.mcs)); if (priv->bss_mode == NL80211_IFTYPE_STATION || - (sband->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40)) + sband->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) /* Set MCS32 for infra mode or ad-hoc mode with 40MHz support */ SETHT_MCS32(ht_cap->ht_cap.mcs.rx_mask); @@ -389,9 +389,9 @@ mwifiex_cmd_append_11n_tlv(struct mwifiex_private *priv, chan_list->chan_scan_param[0].radio_type = mwifiex_band_to_radio_type((u8) bss_desc->bss_band); - if ((sband->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) - && (bss_desc->bcn_ht_info->ht_param & - IEEE80211_HT_PARAM_CHAN_WIDTH_ANY)) + if (sband->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40 && + bss_desc->bcn_ht_info->ht_param & + IEEE80211_HT_PARAM_CHAN_WIDTH_ANY) SET_SECONDARYCHAN(chan_list->chan_scan_param[0]. radio_type, (bss_desc->bcn_ht_info->ht_param & @@ -464,7 +464,7 @@ mwifiex_cfg_tx_buf(struct mwifiex_private *priv, tx_buf = min(priv->adapter->max_tx_buf_size, max_amsdu); dev_dbg(priv->adapter->dev, "info: max_amsdu=%d, max_tx_buf=%d\n", - max_amsdu, priv->adapter->max_tx_buf_size); + max_amsdu, priv->adapter->max_tx_buf_size); if (priv->adapter->curr_tx_buf_size <= MWIFIEX_TX_DATA_BUF_SIZE_2K) curr_tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K; @@ -504,7 +504,7 @@ void mwifiex_11n_delete_tx_ba_stream_tbl_entry(struct mwifiex_private *priv, struct mwifiex_tx_ba_stream_tbl *tx_ba_tsr_tbl) { if (!tx_ba_tsr_tbl && - mwifiex_is_tx_ba_stream_ptr_valid(priv, tx_ba_tsr_tbl)) + mwifiex_is_tx_ba_stream_ptr_valid(priv, tx_ba_tsr_tbl)) return; dev_dbg(priv->adapter->dev, "info: tx_ba_tsr_tbl %p\n", tx_ba_tsr_tbl); @@ -548,8 +548,8 @@ mwifiex_get_ba_tbl(struct mwifiex_private *priv, int tid, u8 *ra) spin_lock_irqsave(&priv->tx_ba_stream_tbl_lock, flags); list_for_each_entry(tx_ba_tsr_tbl, &priv->tx_ba_stream_tbl_ptr, list) { - if ((!memcmp(tx_ba_tsr_tbl->ra, ra, ETH_ALEN)) - && (tx_ba_tsr_tbl->tid == tid)) { + if (!memcmp(tx_ba_tsr_tbl->ra, ra, ETH_ALEN) && + tx_ba_tsr_tbl->tid == tid) { spin_unlock_irqrestore(&priv->tx_ba_stream_tbl_lock, flags); return tx_ba_tsr_tbl; @@ -718,7 +718,7 @@ int mwifiex_get_tx_ba_stream_tbl(struct mwifiex_private *priv, list_for_each_entry(tx_ba_tsr_tbl, &priv->tx_ba_stream_tbl_ptr, list) { rx_reo_tbl->tid = (u16) tx_ba_tsr_tbl->tid; dev_dbg(priv->adapter->dev, "data: %s tid=%d\n", - __func__, rx_reo_tbl->tid); + __func__, rx_reo_tbl->tid); memcpy(rx_reo_tbl->ra, tx_ba_tsr_tbl->ra, ETH_ALEN); rx_reo_tbl++; count++; diff --git a/drivers/net/wireless/mwifiex/11n.h b/drivers/net/wireless/mwifiex/11n.h index 139aa6ee1fbe..77646d777dce 100644 --- a/drivers/net/wireless/mwifiex/11n.h +++ b/drivers/net/wireless/mwifiex/11n.h @@ -86,9 +86,8 @@ mwifiex_is_ampdu_allowed(struct mwifiex_private *priv, int tid) static inline u8 mwifiex_is_amsdu_allowed(struct mwifiex_private *priv, int tid) { - return (((priv->aggr_prio_tbl[tid].amsdu != BA_STREAM_NOT_ALLOWED) - && ((priv->is_data_rate_auto) - || !((priv->bitmap_rates[2]) & 0x03))) + return (((priv->aggr_prio_tbl[tid].amsdu != BA_STREAM_NOT_ALLOWED) && + (priv->is_data_rate_auto || !(priv->bitmap_rates[2] & 0x03))) ? true : false); } @@ -149,7 +148,7 @@ mwifiex_find_stream_to_delete(struct mwifiex_private *priv, int ptr_tid, */ static inline int mwifiex_is_ba_stream_setup(struct mwifiex_private *priv, - struct mwifiex_ra_list_tbl *ptr, int tid) + struct mwifiex_ra_list_tbl *ptr, int tid) { struct mwifiex_tx_ba_stream_tbl *tx_tbl; diff --git a/drivers/net/wireless/mwifiex/11n_aggr.c b/drivers/net/wireless/mwifiex/11n_aggr.c index ea6832dc6677..9eefb2a0ce9f 100644 --- a/drivers/net/wireless/mwifiex/11n_aggr.c +++ b/drivers/net/wireless/mwifiex/11n_aggr.c @@ -84,7 +84,7 @@ mwifiex_11n_form_amsdu_pkt(struct sk_buff *skb_aggr, /* Add payload */ skb_put(skb_aggr, skb_src->len); memcpy(skb_aggr->data + sizeof(*tx_header), skb_src->data, - skb_src->len); + skb_src->len); *pad = (((skb_src->len + LLC_SNAP_LEN) & 3)) ? (4 - (((skb_src->len + LLC_SNAP_LEN)) & 3)) : 0; skb_put(skb_aggr, *pad); @@ -119,14 +119,14 @@ mwifiex_11n_form_amsdu_txpd(struct mwifiex_private *priv, local_tx_pd->tx_pkt_offset = cpu_to_le16(sizeof(struct txpd)); local_tx_pd->tx_pkt_type = cpu_to_le16(PKT_TYPE_AMSDU); local_tx_pd->tx_pkt_length = cpu_to_le16(skb->len - - sizeof(*local_tx_pd)); + sizeof(*local_tx_pd)); if (local_tx_pd->tx_control == 0) /* TxCtrl set by user or default */ local_tx_pd->tx_control = cpu_to_le32(priv->pkt_tx_ctrl); - if ((GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA) && - (priv->adapter->pps_uapsd_mode)) { + if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA && + priv->adapter->pps_uapsd_mode) { if (true == mwifiex_check_last_packet_indication(priv)) { priv->adapter->tx_lock_flag = true; local_tx_pd->flags = @@ -257,9 +257,8 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv, mwifiex_write_data_complete(adapter, skb_aggr, -1); return -1; } - if ((GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA) && - (adapter->pps_uapsd_mode) && - (adapter->tx_lock_flag)) { + if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA && + adapter->pps_uapsd_mode && adapter->tx_lock_flag) { priv->adapter->tx_lock_flag = false; if (ptx_pd) ptx_pd->flags = 0; @@ -279,7 +278,7 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv, case -1: adapter->data_sent = false; dev_err(adapter->dev, "%s: host_to_card failed: %#x\n", - __func__, ret); + __func__, ret); adapter->dbg.num_tx_host_to_card_failure++; mwifiex_write_data_complete(adapter, skb_aggr, ret); return 0; diff --git a/drivers/net/wireless/mwifiex/11n_rxreorder.c b/drivers/net/wireless/mwifiex/11n_rxreorder.c index 06f5d3684027..9c44088054dd 100644 --- a/drivers/net/wireless/mwifiex/11n_rxreorder.c +++ b/drivers/net/wireless/mwifiex/11n_rxreorder.c @@ -220,7 +220,7 @@ mwifiex_flush_data(unsigned long context) */ static void mwifiex_11n_create_rx_reorder_tbl(struct mwifiex_private *priv, u8 *ta, - int tid, int win_size, int seq_num) + int tid, int win_size, int seq_num) { int i; struct mwifiex_rx_reorder_tbl *tbl, *new_node; @@ -240,7 +240,7 @@ mwifiex_11n_create_rx_reorder_tbl(struct mwifiex_private *priv, u8 *ta, new_node = kzalloc(sizeof(struct mwifiex_rx_reorder_tbl), GFP_KERNEL); if (!new_node) { dev_err(priv->adapter->dev, "%s: failed to alloc new_node\n", - __func__); + __func__); return; } @@ -352,7 +352,8 @@ int mwifiex_cmd_11n_addba_rsp_gen(struct mwifiex_private *priv, cmd_addba_req->block_ack_param_set = cpu_to_le16(block_ack_param_set); mwifiex_11n_create_rx_reorder_tbl(priv, cmd_addba_req->peer_mac_addr, - tid, win_size, le16_to_cpu(cmd_addba_req->ssn)); + tid, win_size, + le16_to_cpu(cmd_addba_req->ssn)); return 0; } @@ -416,11 +417,11 @@ int mwifiex_11n_rx_reorder_pkt(struct mwifiex_private *priv, * packet */ if ((start_win + TWOPOW11) > (MAX_TID_VALUE - 1)) {/* Wrap */ - if (seq_num >= ((start_win + (TWOPOW11)) & (MAX_TID_VALUE - 1)) - && (seq_num < start_win)) + if (seq_num >= ((start_win + TWOPOW11) & + (MAX_TID_VALUE - 1)) && (seq_num < start_win)) return -1; - } else if ((seq_num < start_win) - || (seq_num > (start_win + (TWOPOW11)))) { + } else if ((seq_num < start_win) || + (seq_num > (start_win + TWOPOW11))) { return -1; } @@ -431,10 +432,11 @@ int mwifiex_11n_rx_reorder_pkt(struct mwifiex_private *priv, if (pkt_type == PKT_TYPE_BAR) seq_num = ((seq_num + win_size) - 1) & (MAX_TID_VALUE - 1); - if (((end_win < start_win) - && (seq_num < (TWOPOW11 - (MAX_TID_VALUE - start_win))) - && (seq_num > end_win)) || ((end_win > start_win) - && ((seq_num > end_win) || (seq_num < start_win)))) { + if (((end_win < start_win) && + (seq_num < (TWOPOW11 - (MAX_TID_VALUE - start_win))) && + (seq_num > end_win)) || + ((end_win > start_win) && ((seq_num > end_win) || + (seq_num < start_win)))) { end_win = seq_num; if (((seq_num - win_size) + 1) >= 0) start_win = (end_win - win_size) + 1; @@ -483,15 +485,15 @@ mwifiex_del_ba_tbl(struct mwifiex_private *priv, int tid, u8 *peer_mac, else cleanup_rx_reorder_tbl = (initiator) ? false : true; - dev_dbg(priv->adapter->dev, "event: DELBA: %pM tid=%d, " - "initiator=%d\n", peer_mac, tid, initiator); + dev_dbg(priv->adapter->dev, "event: DELBA: %pM tid=%d initiator=%d\n", + peer_mac, tid, initiator); if (cleanup_rx_reorder_tbl) { tbl = mwifiex_11n_get_rx_reorder_tbl(priv, tid, peer_mac); if (!tbl) { dev_dbg(priv->adapter->dev, - "event: TID, TA not found in table\n"); + "event: TID, TA not found in table\n"); return; } mwifiex_del_rx_reorder_entry(priv, tbl); @@ -499,7 +501,7 @@ mwifiex_del_ba_tbl(struct mwifiex_private *priv, int tid, u8 *peer_mac, ptx_tbl = mwifiex_get_ba_tbl(priv, tid, peer_mac); if (!ptx_tbl) { dev_dbg(priv->adapter->dev, - "event: TID, RA not found in table\n"); + "event: TID, RA not found in table\n"); return; } @@ -538,13 +540,13 @@ int mwifiex_ret_11n_addba_resp(struct mwifiex_private *priv, IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK) >> BLOCKACKPARAM_WINSIZE_POS; - dev_dbg(priv->adapter->dev, "cmd: ADDBA RSP: %pM" - " tid=%d ssn=%d win_size=%d\n", - add_ba_rsp->peer_mac_addr, - tid, add_ba_rsp->ssn, win_size); + dev_dbg(priv->adapter->dev, + "cmd: ADDBA RSP: %pM tid=%d ssn=%d win_size=%d\n", + add_ba_rsp->peer_mac_addr, tid, + add_ba_rsp->ssn, win_size); } else { dev_err(priv->adapter->dev, "ADDBA RSP: failed %pM tid=%d)\n", - add_ba_rsp->peer_mac_addr, tid); + add_ba_rsp->peer_mac_addr, tid); tbl = mwifiex_11n_get_rx_reorder_tbl(priv, tid, add_ba_rsp->peer_mac_addr); -- cgit From aea0701e221e46c267a68187f9e6e0881e9a6a49 Mon Sep 17 00:00:00 2001 From: Yogesh Ashok Powar Date: Tue, 13 Mar 2012 19:22:35 -0700 Subject: mwifiex: fix checkpatch --strict warnings/errors Part 2 For files cfg80211.c, cfp.c, and cmdevt.c Signed-off-by: Yogesh Ashok Powar Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/cfg80211.c | 90 +++++++++-------- drivers/net/wireless/mwifiex/cfp.c | 4 +- drivers/net/wireless/mwifiex/cmdevt.c | 166 +++++++++++++++++--------------- 3 files changed, 133 insertions(+), 127 deletions(-) diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index 84508b065265..65050384c42b 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c @@ -127,8 +127,7 @@ mwifiex_cfg80211_set_power_mgmt(struct wiphy *wiphy, if (timeout) wiphy_dbg(wiphy, - "info: ignoring the timeout value" - " for IEEE power save\n"); + "info: ignore timeout value for IEEE Power Save\n"); ps_mode = enabled; @@ -168,7 +167,7 @@ mwifiex_cfg80211_add_key(struct wiphy *wiphy, struct net_device *netdev, struct mwifiex_private *priv = mwifiex_netdev_get_priv(netdev); if (mwifiex_set_encode(priv, params->key, params->key_len, - key_index, 0)) { + key_index, 0)) { wiphy_err(wiphy, "crypto keys added\n"); return -EFAULT; } @@ -225,7 +224,7 @@ static int mwifiex_send_domain_info_cmd_fw(struct wiphy *wiphy) } if (ch->hw_value == next_chan + 1 && - ch->max_power == max_pwr) { + ch->max_power == max_pwr) { next_chan++; no_of_parsed_chan++; } else { @@ -252,7 +251,7 @@ static int mwifiex_send_domain_info_cmd_fw(struct wiphy *wiphy) domain_info->no_of_triplet = no_of_triplet; if (mwifiex_send_cmd_async(priv, HostCmd_CMD_802_11D_DOMAIN_INFO, - HostCmd_ACT_GEN_SET, 0, NULL)) { + HostCmd_ACT_GEN_SET, 0, NULL)) { wiphy_err(wiphy, "11D: setting domain info in FW\n"); return -1; } @@ -271,7 +270,7 @@ static int mwifiex_send_domain_info_cmd_fw(struct wiphy *wiphy) * - Set bt Country IE */ static int mwifiex_reg_notifier(struct wiphy *wiphy, - struct regulatory_request *request) + struct regulatory_request *request) { struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy); @@ -316,7 +315,7 @@ mwifiex_set_rf_channel(struct mwifiex_private *priv, if (chan->band == IEEE80211_BAND_2GHZ) { if (channel_type == NL80211_CHAN_NO_HT) if (priv->adapter->config_bands == BAND_B || - priv->adapter->config_bands == BAND_G) + priv->adapter->config_bands == BAND_G) config_bands = priv->adapter->config_bands; else @@ -336,7 +335,7 @@ mwifiex_set_rf_channel(struct mwifiex_private *priv, if (priv->bss_mode == NL80211_IFTYPE_ADHOC) { adapter->adhoc_start_band = config_bands; if ((config_bands & BAND_GN) || - (config_bands & BAND_AN)) + (config_bands & BAND_AN)) adapter->adhoc_11n_enabled = true; else adapter->adhoc_11n_enabled = false; @@ -350,9 +349,8 @@ mwifiex_set_rf_channel(struct mwifiex_private *priv, mwifiex_send_domain_info_cmd_fw(wiphy); } - wiphy_dbg(wiphy, "info: setting band %d, channel offset %d and " - "mode %d\n", config_bands, adapter->sec_chan_offset, - priv->bss_mode); + wiphy_dbg(wiphy, "info: setting band %d, chan offset %d, mode %d\n", + config_bands, adapter->sec_chan_offset, priv->bss_mode); if (!chan) return 0; @@ -403,8 +401,8 @@ mwifiex_set_frag(struct mwifiex_private *priv, u32 frag_thr) { int ret; - if (frag_thr < MWIFIEX_FRAG_MIN_VALUE - || frag_thr > MWIFIEX_FRAG_MAX_VALUE) + if (frag_thr < MWIFIEX_FRAG_MIN_VALUE || + frag_thr > MWIFIEX_FRAG_MAX_VALUE) return -EINVAL; /* Send request to firmware */ @@ -746,8 +744,7 @@ static int mwifiex_cfg80211_set_bitrate_mask(struct wiphy *wiphy, adapter->channel_type = NL80211_CHAN_NO_HT; wiphy_debug(wiphy, "info: device configured in 802.11%s%s mode\n", - (mode & BAND_B) ? "b" : "", - (mode & BAND_G) ? "g" : ""); + (mode & BAND_B) ? "b" : "", (mode & BAND_G) ? "g" : ""); return 0; } @@ -802,8 +799,7 @@ static int mwifiex_cfg80211_inform_ibss_bss(struct mwifiex_private *priv) ie_buf[1] = bss_info.ssid.ssid_len; memcpy(&ie_buf[sizeof(struct ieee_types_header)], - &bss_info.ssid.ssid, - bss_info.ssid.ssid_len); + &bss_info.ssid.ssid, bss_info.ssid.ssid_len); ie_len = ie_buf[1] + sizeof(struct ieee_types_header); band = mwifiex_band_to_radio_type(priv->curr_bss_params.band); @@ -812,8 +808,8 @@ static int mwifiex_cfg80211_inform_ibss_bss(struct mwifiex_private *priv) band)); bss = cfg80211_inform_bss(priv->wdev->wiphy, chan, - bss_info.bssid, 0, WLAN_CAPABILITY_IBSS, - 0, ie_buf, ie_len, 0, GFP_KERNEL); + bss_info.bssid, 0, WLAN_CAPABILITY_IBSS, + 0, ie_buf, ie_len, 0, GFP_KERNEL); cfg80211_put_bss(bss); memcpy(priv->cfg_bssid, bss_info.bssid, ETH_ALEN); @@ -952,14 +948,15 @@ done: if (!bss) { if (is_scanning_required) { - dev_warn(priv->adapter->dev, "assoc: requested " - "bss not found in scan results\n"); + dev_warn(priv->adapter->dev, + "assoc: requested bss not found in scan results\n"); break; } is_scanning_required = 1; } else { - dev_dbg(priv->adapter->dev, "info: trying to associate to %s and bssid %pM\n", - (char *) req_ssid.ssid, bss->bssid); + dev_dbg(priv->adapter->dev, + "info: trying to associate to '%s' bssid %pM\n", + (char *) req_ssid.ssid, bss->bssid); memcpy(&priv->cfg_bssid, bss->bssid, ETH_ALEN); break; } @@ -999,7 +996,7 @@ mwifiex_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, } wiphy_dbg(wiphy, "info: Trying to associate to %s and bssid %pM\n", - (char *) sme->ssid, sme->bssid); + (char *) sme->ssid, sme->bssid); ret = mwifiex_cfg80211_assoc(priv, sme->ssid_len, sme->ssid, sme->bssid, priv->bss_mode, sme->channel, sme, 0); @@ -1041,11 +1038,11 @@ mwifiex_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev, } wiphy_dbg(wiphy, "info: trying to join to %s and bssid %pM\n", - (char *) params->ssid, params->bssid); + (char *) params->ssid, params->bssid); ret = mwifiex_cfg80211_assoc(priv, params->ssid_len, params->ssid, - params->bssid, priv->bss_mode, - params->channel, NULL, params->privacy); + params->bssid, priv->bss_mode, + params->channel, NULL, params->privacy); done: if (!ret) { cfg80211_ibss_joined(priv->netdev, priv->cfg_bssid, GFP_KERNEL); @@ -1072,7 +1069,7 @@ mwifiex_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev) struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); wiphy_dbg(wiphy, "info: disconnecting from essid %pM\n", - priv->cfg_bssid); + priv->cfg_bssid); if (mwifiex_deauthenticate(priv, NULL)) return -EFAULT; @@ -1101,7 +1098,7 @@ mwifiex_cfg80211_scan(struct wiphy *wiphy, struct net_device *dev, priv->scan_request = request; priv->user_scan_cfg = kzalloc(sizeof(struct mwifiex_user_scan_cfg), - GFP_KERNEL); + GFP_KERNEL); if (!priv->user_scan_cfg) { dev_err(priv->adapter->dev, "failed to alloc scan_req\n"); return -ENOMEM; @@ -1117,10 +1114,10 @@ mwifiex_cfg80211_scan(struct wiphy *wiphy, struct net_device *dev, if (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN) priv->user_scan_cfg->chan_list[i].scan_type = - MWIFIEX_SCAN_TYPE_PASSIVE; + MWIFIEX_SCAN_TYPE_PASSIVE; else priv->user_scan_cfg->chan_list[i].scan_type = - MWIFIEX_SCAN_TYPE_ACTIVE; + MWIFIEX_SCAN_TYPE_ACTIVE; priv->user_scan_cfg->chan_list[i].scan_time = 0; } @@ -1191,9 +1188,9 @@ mwifiex_setup_ht_caps(struct ieee80211_sta_ht_cap *ht_info, memset(mcs, 0xff, rx_mcs_supp); /* Clear all the other values */ memset(&mcs[rx_mcs_supp], 0, - sizeof(struct ieee80211_mcs_info) - rx_mcs_supp); + sizeof(struct ieee80211_mcs_info) - rx_mcs_supp); if (priv->bss_mode == NL80211_IFTYPE_STATION || - ISSUPP_CHANWIDTH40(adapter->hw_dot_11n_dev_cap)) + ISSUPP_CHANWIDTH40(adapter->hw_dot_11n_dev_cap)) /* Set MCS32 for infra mode or ad-hoc mode with 40MHz support */ SETHT_MCS32(mcs_set.rx_mask); @@ -1206,10 +1203,10 @@ mwifiex_setup_ht_caps(struct ieee80211_sta_ht_cap *ht_info, * create a new virtual interface with the given name */ struct net_device *mwifiex_add_virtual_intf(struct wiphy *wiphy, - char *name, - enum nl80211_iftype type, - u32 *flags, - struct vif_params *params) + char *name, + enum nl80211_iftype type, + u32 *flags, + struct vif_params *params) { struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy); struct mwifiex_adapter *adapter; @@ -1367,11 +1364,12 @@ int mwifiex_register_cfg80211(struct mwifiex_private *priv) int ret; void *wdev_priv; struct wireless_dev *wdev; + struct ieee80211_sta_ht_cap *ht_info; wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL); if (!wdev) { dev_err(priv->adapter->dev, "%s: allocating wireless device\n", - __func__); + __func__); return -ENOMEM; } wdev->wiphy = @@ -1383,17 +1381,17 @@ int mwifiex_register_cfg80211(struct mwifiex_private *priv) } wdev->iftype = NL80211_IFTYPE_STATION; wdev->wiphy->max_scan_ssids = 10; - wdev->wiphy->interface_modes = - BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC); + wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | + BIT(NL80211_IFTYPE_ADHOC); wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &mwifiex_band_2ghz; - mwifiex_setup_ht_caps( - &wdev->wiphy->bands[IEEE80211_BAND_2GHZ]->ht_cap, priv); + ht_info = &wdev->wiphy->bands[IEEE80211_BAND_2GHZ]->ht_cap; + mwifiex_setup_ht_caps(ht_info, priv); if (priv->adapter->config_bands & BAND_A) { wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &mwifiex_band_5ghz; - mwifiex_setup_ht_caps( - &wdev->wiphy->bands[IEEE80211_BAND_5GHZ]->ht_cap, priv); + ht_info = &wdev->wiphy->bands[IEEE80211_BAND_5GHZ]->ht_cap; + mwifiex_setup_ht_caps(ht_info, priv); } else { wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = NULL; } @@ -1420,13 +1418,13 @@ int mwifiex_register_cfg80211(struct mwifiex_private *priv) ret = wiphy_register(wdev->wiphy); if (ret < 0) { dev_err(priv->adapter->dev, "%s: registering cfg80211 device\n", - __func__); + __func__); wiphy_free(wdev->wiphy); kfree(wdev); return ret; } else { dev_dbg(priv->adapter->dev, - "info: successfully registered wiphy device\n"); + "info: successfully registered wiphy device\n"); } priv->wdev = wdev; diff --git a/drivers/net/wireless/mwifiex/cfp.c b/drivers/net/wireless/mwifiex/cfp.c index 7541d9a4a6ed..2fe1c33765b8 100644 --- a/drivers/net/wireless/mwifiex/cfp.c +++ b/drivers/net/wireless/mwifiex/cfp.c @@ -163,8 +163,8 @@ u32 mwifiex_get_active_data_rates(struct mwifiex_private *priv, u8 *rates) return mwifiex_get_supported_rates(priv, rates); else return mwifiex_copy_rates(rates, 0, - priv->curr_bss_params.data_rates, - priv->curr_bss_params.num_of_rates); + priv->curr_bss_params.data_rates, + priv->curr_bss_params.num_of_rates); } /* diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c index c82eb7ff2fa2..07f6e0092552 100644 --- a/drivers/net/wireless/mwifiex/cmdevt.c +++ b/drivers/net/wireless/mwifiex/cmdevt.c @@ -67,7 +67,7 @@ mwifiex_get_cmd_node(struct mwifiex_adapter *adapter) return NULL; } cmd_node = list_first_entry(&adapter->cmd_free_q, - struct cmd_ctrl_node, list); + struct cmd_ctrl_node, list); list_del(&cmd_node->list); spin_unlock_irqrestore(&adapter->cmd_free_q_lock, flags); @@ -158,8 +158,9 @@ static int mwifiex_dnld_cmd_to_fw(struct mwifiex_private *priv, /* Set command sequence number */ adapter->seq_num++; host_cmd->seq_num = cpu_to_le16(HostCmd_SET_SEQ_NO_BSS_INFO - (adapter->seq_num, cmd_node->priv->bss_num, - cmd_node->priv->bss_type)); + (adapter->seq_num, + cmd_node->priv->bss_num, + cmd_node->priv->bss_type)); spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags); adapter->curr_cmd = cmd_node; @@ -174,8 +175,8 @@ static int mwifiex_dnld_cmd_to_fw(struct mwifiex_private *priv, dev_dbg(adapter->dev, "cmd: DNLD_CMD: (%lu.%lu): %#x, act %#x, len %d," " seqno %#x\n", tstamp.tv_sec, tstamp.tv_usec, cmd_code, - le16_to_cpu(*(__le16 *) ((u8 *) host_cmd + S_DS_GEN)), cmd_size, - le16_to_cpu(host_cmd->seq_num)); + le16_to_cpu(*(__le16 *) ((u8 *) host_cmd + S_DS_GEN)), cmd_size, + le16_to_cpu(host_cmd->seq_num)); skb_push(cmd_node->cmd_skb, INTF_HEADER_LEN); @@ -200,17 +201,17 @@ static int mwifiex_dnld_cmd_to_fw(struct mwifiex_private *priv, /* Save the last command id and action to debug log */ adapter->dbg.last_cmd_index = - (adapter->dbg.last_cmd_index + 1) % DBG_CMD_NUM; + (adapter->dbg.last_cmd_index + 1) % DBG_CMD_NUM; adapter->dbg.last_cmd_id[adapter->dbg.last_cmd_index] = cmd_code; adapter->dbg.last_cmd_act[adapter->dbg.last_cmd_index] = - le16_to_cpu(*(__le16 *) ((u8 *) host_cmd + S_DS_GEN)); + le16_to_cpu(*(__le16 *) ((u8 *) host_cmd + S_DS_GEN)); /* Clear BSS_NO_BITS from HostCmd */ cmd_code &= HostCmd_CMD_ID_MASK; /* Setup the timer after transmit command */ mod_timer(&adapter->cmd_timer, - jiffies + (MWIFIEX_TIMER_10S * HZ) / 1000); + jiffies + (MWIFIEX_TIMER_10S * HZ) / 1000); return 0; } @@ -230,7 +231,7 @@ static int mwifiex_dnld_sleep_confirm_cmd(struct mwifiex_adapter *adapter) struct mwifiex_private *priv; struct mwifiex_opt_sleep_confirm *sleep_cfm_buf = (struct mwifiex_opt_sleep_confirm *) - adapter->sleep_cfm->data; + adapter->sleep_cfm->data; priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY); sleep_cfm_buf->seq_num = @@ -250,7 +251,7 @@ static int mwifiex_dnld_sleep_confirm_cmd(struct mwifiex_adapter *adapter) return -1; } if (GET_BSS_ROLE(mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY)) - == MWIFIEX_BSS_ROLE_STA) { + == MWIFIEX_BSS_ROLE_STA) { if (!sleep_cfm_buf->resp_ctrl) /* Response is not needed for sleep confirm command */ @@ -258,12 +259,12 @@ static int mwifiex_dnld_sleep_confirm_cmd(struct mwifiex_adapter *adapter) else adapter->ps_state = PS_STATE_SLEEP_CFM; - if (!sleep_cfm_buf->resp_ctrl - && (adapter->is_hs_configured - && !adapter->sleep_period.period)) { + if (!sleep_cfm_buf->resp_ctrl && + (adapter->is_hs_configured && + !adapter->sleep_period.period)) { adapter->pm_wakeup_card_req = true; - mwifiex_hs_activated_event(mwifiex_get_priv(adapter, - MWIFIEX_BSS_ROLE_STA), true); + mwifiex_hs_activated_event(mwifiex_get_priv + (adapter, MWIFIEX_BSS_ROLE_STA), true); } } @@ -293,7 +294,7 @@ int mwifiex_alloc_cmd_buffer(struct mwifiex_adapter *adapter) cmd_array = kzalloc(buf_size, GFP_KERNEL); if (!cmd_array) { dev_err(adapter->dev, "%s: failed to alloc cmd_array\n", - __func__); + __func__); return -ENOMEM; } @@ -376,9 +377,9 @@ int mwifiex_process_event(struct mwifiex_adapter *adapter) /* Save the last event to debug log */ adapter->dbg.last_event_index = - (adapter->dbg.last_event_index + 1) % DBG_CMD_NUM; + (adapter->dbg.last_event_index + 1) % DBG_CMD_NUM; adapter->dbg.last_event[adapter->dbg.last_event_index] = - (u16) eventcause; + (u16) eventcause; /* Get BSS number and corresponding priv */ priv = mwifiex_get_priv_by_id(adapter, EVENT_GET_BSS_NUM(eventcause), @@ -398,7 +399,7 @@ int mwifiex_process_event(struct mwifiex_adapter *adapter) if (eventcause != EVENT_PS_SLEEP && eventcause != EVENT_PS_AWAKE) { do_gettimeofday(&tstamp); dev_dbg(adapter->dev, "event: %lu.%lu: cause: %#x\n", - tstamp.tv_sec, tstamp.tv_usec, eventcause); + tstamp.tv_sec, tstamp.tv_usec, eventcause); } ret = mwifiex_process_sta_event(priv); @@ -509,7 +510,7 @@ int mwifiex_send_cmd_async(struct mwifiex_private *priv, uint16_t cmd_no, /* Return error, since the command preparation failed */ if (ret) { dev_err(adapter->dev, "PREP_CMD: cmd %#x preparation failed\n", - cmd_no); + cmd_no); mwifiex_insert_cmd_to_free_q(adapter, cmd_node); return -1; } @@ -577,9 +578,9 @@ mwifiex_insert_cmd_to_pending_q(struct mwifiex_adapter *adapter, /* Exit_PS command needs to be queued in the header always. */ if (command == HostCmd_CMD_802_11_PS_MODE_ENH) { struct host_cmd_ds_802_11_ps_mode_enh *pm = - &host_cmd->params.psmode_enh; - if ((le16_to_cpu(pm->action) == DIS_PS) - || (le16_to_cpu(pm->action) == DIS_AUTO_PS)) { + &host_cmd->params.psmode_enh; + if ((le16_to_cpu(pm->action) == DIS_PS) || + (le16_to_cpu(pm->action) == DIS_AUTO_PS)) { if (adapter->ps_state != PS_STATE_AWAKE) add_tail = false; } @@ -692,7 +693,7 @@ int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter) if (!adapter->curr_cmd || !adapter->curr_cmd->resp_skb) { resp = (struct host_cmd_ds_command *) adapter->upld_buf; dev_err(adapter->dev, "CMD_RESP: NULL curr_cmd, %#x\n", - le16_to_cpu(resp->command)); + le16_to_cpu(resp->command)); return -1; } @@ -701,7 +702,7 @@ int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter) resp = (struct host_cmd_ds_command *) adapter->curr_cmd->resp_skb->data; if (adapter->curr_cmd->cmd_flag & CMD_F_CANCELED) { dev_err(adapter->dev, "CMD_RESP: %#x been canceled\n", - le16_to_cpu(resp->command)); + le16_to_cpu(resp->command)); mwifiex_insert_cmd_to_free_q(adapter, adapter->curr_cmd); spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags); adapter->curr_cmd = NULL; @@ -725,8 +726,8 @@ int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter) /* Get BSS number and corresponding priv */ priv = mwifiex_get_priv_by_id(adapter, - HostCmd_GET_BSS_NO(le16_to_cpu(resp->seq_num)), - HostCmd_GET_BSS_TYPE(le16_to_cpu(resp->seq_num))); + HostCmd_GET_BSS_NO(le16_to_cpu(resp->seq_num)), + HostCmd_GET_BSS_TYPE(le16_to_cpu(resp->seq_num))); if (!priv) priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY); /* Clear RET_BIT from HostCmd */ @@ -737,9 +738,9 @@ int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter) /* Save the last command response to debug log */ adapter->dbg.last_cmd_resp_index = - (adapter->dbg.last_cmd_resp_index + 1) % DBG_CMD_NUM; + (adapter->dbg.last_cmd_resp_index + 1) % DBG_CMD_NUM; adapter->dbg.last_cmd_resp_id[adapter->dbg.last_cmd_resp_index] = - orig_cmdresp_no; + orig_cmdresp_no; do_gettimeofday(&tstamp); dev_dbg(adapter->dev, "cmd: CMD_RESP: (%lu.%lu): 0x%x, result %d," @@ -761,8 +762,8 @@ int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter) if (adapter->curr_cmd->cmd_flag & CMD_F_HOSTCMD) { adapter->curr_cmd->cmd_flag &= ~CMD_F_HOSTCMD; - if ((cmdresp_result == HostCmd_RESULT_OK) - && (cmdresp_no == HostCmd_CMD_802_11_HS_CFG_ENH)) + if ((cmdresp_result == HostCmd_RESULT_OK) && + (cmdresp_no == HostCmd_CMD_802_11_HS_CFG_ENH)) ret = mwifiex_ret_802_11_hs_cfg(priv, resp); } else { /* handle response */ @@ -824,44 +825,45 @@ mwifiex_cmd_timeout_func(unsigned long function_context) adapter->dbg.timeout_cmd_act = adapter->dbg.last_cmd_act[adapter->dbg.last_cmd_index]; do_gettimeofday(&tstamp); - dev_err(adapter->dev, "%s: Timeout cmd id (%lu.%lu) = %#x," - " act = %#x\n", __func__, - tstamp.tv_sec, tstamp.tv_usec, - adapter->dbg.timeout_cmd_id, - adapter->dbg.timeout_cmd_act); + dev_err(adapter->dev, + "%s: Timeout cmd id (%lu.%lu) = %#x, act = %#x\n", + __func__, tstamp.tv_sec, tstamp.tv_usec, + adapter->dbg.timeout_cmd_id, + adapter->dbg.timeout_cmd_act); dev_err(adapter->dev, "num_data_h2c_failure = %d\n", - adapter->dbg.num_tx_host_to_card_failure); + adapter->dbg.num_tx_host_to_card_failure); dev_err(adapter->dev, "num_cmd_h2c_failure = %d\n", - adapter->dbg.num_cmd_host_to_card_failure); + adapter->dbg.num_cmd_host_to_card_failure); dev_err(adapter->dev, "num_cmd_timeout = %d\n", - adapter->dbg.num_cmd_timeout); + adapter->dbg.num_cmd_timeout); dev_err(adapter->dev, "num_tx_timeout = %d\n", - adapter->dbg.num_tx_timeout); + adapter->dbg.num_tx_timeout); dev_err(adapter->dev, "last_cmd_index = %d\n", - adapter->dbg.last_cmd_index); + adapter->dbg.last_cmd_index); print_hex_dump_bytes("last_cmd_id: ", DUMP_PREFIX_OFFSET, - adapter->dbg.last_cmd_id, DBG_CMD_NUM); + adapter->dbg.last_cmd_id, DBG_CMD_NUM); print_hex_dump_bytes("last_cmd_act: ", DUMP_PREFIX_OFFSET, - adapter->dbg.last_cmd_act, DBG_CMD_NUM); + adapter->dbg.last_cmd_act, DBG_CMD_NUM); dev_err(adapter->dev, "last_cmd_resp_index = %d\n", - adapter->dbg.last_cmd_resp_index); + adapter->dbg.last_cmd_resp_index); print_hex_dump_bytes("last_cmd_resp_id: ", DUMP_PREFIX_OFFSET, - adapter->dbg.last_cmd_resp_id, DBG_CMD_NUM); + adapter->dbg.last_cmd_resp_id, + DBG_CMD_NUM); dev_err(adapter->dev, "last_event_index = %d\n", - adapter->dbg.last_event_index); + adapter->dbg.last_event_index); print_hex_dump_bytes("last_event: ", DUMP_PREFIX_OFFSET, - adapter->dbg.last_event, DBG_CMD_NUM); + adapter->dbg.last_event, DBG_CMD_NUM); dev_err(adapter->dev, "data_sent=%d cmd_sent=%d\n", - adapter->data_sent, adapter->cmd_sent); + adapter->data_sent, adapter->cmd_sent); dev_err(adapter->dev, "ps_mode=%d ps_state=%d\n", - adapter->ps_mode, adapter->ps_state); + adapter->ps_mode, adapter->ps_state); } if (adapter->hw_status == MWIFIEX_HW_STATUS_INITIALIZING) mwifiex_init_fw_complete(adapter); @@ -942,7 +944,7 @@ mwifiex_cancel_pending_ioctl(struct mwifiex_adapter *adapter) uint16_t cancel_scan_cmd = false; if ((adapter->curr_cmd) && - (adapter->curr_cmd->wait_q_enabled)) { + (adapter->curr_cmd->wait_q_enabled)) { spin_lock_irqsave(&adapter->mwifiex_cmd_lock, cmd_flags); cmd_node = adapter->curr_cmd; cmd_node->wait_q_enabled = false; @@ -996,9 +998,9 @@ mwifiex_check_ps_cond(struct mwifiex_adapter *adapter) else dev_dbg(adapter->dev, "cmd: Delay Sleep Confirm (%s%s%s)\n", - (adapter->cmd_sent) ? "D" : "", - (adapter->curr_cmd) ? "C" : "", - (IS_CARD_RX_RCVD(adapter)) ? "R" : ""); + (adapter->cmd_sent) ? "D" : "", + (adapter->curr_cmd) ? "C" : "", + (IS_CARD_RX_RCVD(adapter)) ? "R" : ""); } /* @@ -1050,8 +1052,8 @@ int mwifiex_ret_802_11_hs_cfg(struct mwifiex_private *priv, dev_dbg(adapter->dev, "cmd: CMD_RESP: HS_CFG cmd reply" " result=%#x, conditions=0x%x gpio=0x%x gap=0x%x\n", resp->result, conditions, - phs_cfg->params.hs_config.gpio, - phs_cfg->params.hs_config.gap); + phs_cfg->params.hs_config.gpio, + phs_cfg->params.hs_config.gap); } if (conditions != HOST_SLEEP_CFG_CANCEL) { adapter->is_hs_configured = true; @@ -1078,7 +1080,8 @@ mwifiex_process_hs_config(struct mwifiex_adapter *adapter) adapter->hs_activated = false; adapter->is_hs_configured = false; mwifiex_hs_activated_event(mwifiex_get_priv(adapter, - MWIFIEX_BSS_ROLE_ANY), false); + MWIFIEX_BSS_ROLE_ANY), + false); } /* @@ -1114,22 +1117,24 @@ mwifiex_process_sleep_confirm_resp(struct mwifiex_adapter *adapter, command &= HostCmd_CMD_ID_MASK; if (command != HostCmd_CMD_802_11_PS_MODE_ENH) { - dev_err(adapter->dev, "%s: received unexpected response for" - " cmd %x, result = %x\n", __func__, command, result); + dev_err(adapter->dev, + "%s: rcvd unexpected resp for cmd %#x, result = %x\n", + __func__, command, result); return; } if (result) { dev_err(adapter->dev, "%s: sleep confirm cmd failed\n", - __func__); + __func__); adapter->pm_wakeup_card_req = false; adapter->ps_state = PS_STATE_AWAKE; return; } adapter->pm_wakeup_card_req = true; if (adapter->is_hs_configured) - mwifiex_hs_activated_event(mwifiex_get_priv(adapter, - MWIFIEX_BSS_ROLE_ANY), true); + mwifiex_hs_activated_event(mwifiex_get_priv + (adapter, MWIFIEX_BSS_ROLE_ANY), + true); adapter->ps_state = PS_STATE_SLEEP; cmd->command = cpu_to_le16(command); cmd->seq_num = cpu_to_le16(seq_num); @@ -1163,17 +1168,17 @@ int mwifiex_cmd_enh_power_mode(struct mwifiex_private *priv, psmode_enh->action = cpu_to_le16(DIS_AUTO_PS); psmode_enh->params.ps_bitmap = cpu_to_le16(ps_bitmap); cmd->size = cpu_to_le16(S_DS_GEN + sizeof(psmode_enh->action) + - sizeof(psmode_enh->params.ps_bitmap)); + sizeof(psmode_enh->params.ps_bitmap)); } else if (cmd_action == GET_PS) { psmode_enh->action = cpu_to_le16(GET_PS); psmode_enh->params.ps_bitmap = cpu_to_le16(ps_bitmap); cmd->size = cpu_to_le16(S_DS_GEN + sizeof(psmode_enh->action) + - sizeof(psmode_enh->params.ps_bitmap)); + sizeof(psmode_enh->params.ps_bitmap)); } else if (cmd_action == EN_AUTO_PS) { psmode_enh->action = cpu_to_le16(EN_AUTO_PS); psmode_enh->params.ps_bitmap = cpu_to_le16(ps_bitmap); cmd_size = S_DS_GEN + sizeof(psmode_enh->action) + - sizeof(psmode_enh->params.ps_bitmap); + sizeof(psmode_enh->params.ps_bitmap); tlv = (u8 *) cmd + cmd_size; if (ps_bitmap & BITMAP_STA_PS) { struct mwifiex_adapter *adapter = priv->adapter; @@ -1187,19 +1192,18 @@ int mwifiex_cmd_enh_power_mode(struct mwifiex_private *priv, tlv += sizeof(*ps_tlv); dev_dbg(adapter->dev, "cmd: PS Command: Enter PS\n"); ps_mode->null_pkt_interval = - cpu_to_le16(adapter->null_pkt_interval); + cpu_to_le16(adapter->null_pkt_interval); ps_mode->multiple_dtims = - cpu_to_le16(adapter->multiple_dtim); + cpu_to_le16(adapter->multiple_dtim); ps_mode->bcn_miss_timeout = - cpu_to_le16(adapter->bcn_miss_time_out); + cpu_to_le16(adapter->bcn_miss_time_out); ps_mode->local_listen_interval = cpu_to_le16(adapter->local_listen_interval); ps_mode->adhoc_wake_period = cpu_to_le16(adapter->adhoc_awake_period); ps_mode->delay_to_ps = - cpu_to_le16(adapter->delay_to_ps); - ps_mode->mode = - cpu_to_le16(adapter->enhanced_ps_mode); + cpu_to_le16(adapter->delay_to_ps); + ps_mode->mode = cpu_to_le16(adapter->enhanced_ps_mode); } if (ps_bitmap & BITMAP_AUTO_DS) { @@ -1217,7 +1221,7 @@ int mwifiex_cmd_enh_power_mode(struct mwifiex_private *priv, if (auto_ds) idletime = auto_ds->idle_time; dev_dbg(priv->adapter->dev, - "cmd: PS Command: Enter Auto Deep Sleep\n"); + "cmd: PS Command: Enter Auto Deep Sleep\n"); auto_ds_tlv->deep_sleep_timeout = cpu_to_le16(idletime); } cmd->size = cpu_to_le16(cmd_size); @@ -1244,8 +1248,9 @@ int mwifiex_ret_enh_power_mode(struct mwifiex_private *priv, uint16_t auto_ps_bitmap = le16_to_cpu(ps_mode->params.ps_bitmap); - dev_dbg(adapter->dev, "info: %s: PS_MODE cmd reply result=%#x action=%#X\n", - __func__, resp->result, action); + dev_dbg(adapter->dev, + "info: %s: PS_MODE cmd reply result=%#x action=%#X\n", + __func__, resp->result, action); if (action == EN_AUTO_PS) { if (auto_ps_bitmap & BITMAP_AUTO_DS) { dev_dbg(adapter->dev, "cmd: Enabled auto deep sleep\n"); @@ -1254,7 +1259,8 @@ int mwifiex_ret_enh_power_mode(struct mwifiex_private *priv, if (auto_ps_bitmap & BITMAP_STA_PS) { dev_dbg(adapter->dev, "cmd: Enabled STA power save\n"); if (adapter->sleep_period.period) - dev_dbg(adapter->dev, "cmd: set to uapsd/pps mode\n"); + dev_dbg(adapter->dev, + "cmd: set to uapsd/pps mode\n"); } } else if (action == DIS_AUTO_PS) { if (ps_bitmap & BITMAP_AUTO_DS) { @@ -1373,12 +1379,13 @@ int mwifiex_ret_get_hw_spec(struct mwifiex_private *priv, adapter->number_of_antenna = le16_to_cpu(hw_spec->number_of_antenna); dev_dbg(adapter->dev, "info: GET_HW_SPEC: fw_release_number- %#x\n", - adapter->fw_release_number); + adapter->fw_release_number); dev_dbg(adapter->dev, "info: GET_HW_SPEC: permanent addr: %pM\n", - hw_spec->permanent_addr); - dev_dbg(adapter->dev, "info: GET_HW_SPEC: hw_if_version=%#x version=%#x\n", + hw_spec->permanent_addr); + dev_dbg(adapter->dev, + "info: GET_HW_SPEC: hw_if_version=%#x version=%#x\n", le16_to_cpu(hw_spec->hw_if_version), - le16_to_cpu(hw_spec->version)); + le16_to_cpu(hw_spec->version)); if (priv->curr_addr[0] == 0xff) memmove(priv->curr_addr, hw_spec->permanent_addr, ETH_ALEN); @@ -1393,7 +1400,8 @@ int mwifiex_ret_get_hw_spec(struct mwifiex_private *priv, /* If it's unidentified region code, use the default (USA) */ if (i >= MWIFIEX_MAX_REGION_CODE) { adapter->region_code = 0x10; - dev_dbg(adapter->dev, "cmd: unknown region code, use default (USA)\n"); + dev_dbg(adapter->dev, + "cmd: unknown region code, use default (USA)\n"); } adapter->hw_dot_11n_dev_cap = le32_to_cpu(hw_spec->dot_11n_dev_cap); -- cgit From 931f15842a9e1251d46a681bd10d2033f6fb1ffd Mon Sep 17 00:00:00 2001 From: Yogesh Ashok Powar Date: Tue, 13 Mar 2012 19:22:36 -0700 Subject: mwifiex: fix checkpatch --strict warnings/errors Part 3 For files fw.h, init.c and join.c Signed-off-by: Yogesh Ashok Powar Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/fw.h | 4 +- drivers/net/wireless/mwifiex/init.c | 31 +++---- drivers/net/wireless/mwifiex/join.c | 164 ++++++++++++++++++------------------ 3 files changed, 98 insertions(+), 101 deletions(-) diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h index fc4ffee6c6b9..e98fc5af73dc 100644 --- a/drivers/net/wireless/mwifiex/fw.h +++ b/drivers/net/wireless/mwifiex/fw.h @@ -117,8 +117,8 @@ enum MWIFIEX_802_11_PRIVACY_FILTER { #define BA_STREAM_NOT_ALLOWED 0xff #define IS_11N_ENABLED(priv) ((priv->adapter->config_bands & BAND_GN || \ - priv->adapter->config_bands & BAND_AN) \ - && priv->curr_bss_params.bss_descriptor.bcn_ht_cap) + priv->adapter->config_bands & BAND_AN) && \ + priv->curr_bss_params.bss_descriptor.bcn_ht_cap) #define INITIATOR_BIT(DelBAParamSet) (((DelBAParamSet) &\ BIT(DELBA_INITIATOR_POS)) >> DELBA_INITIATOR_POS) diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c index e81bf6ef1666..54bb4839b57c 100644 --- a/drivers/net/wireless/mwifiex/init.c +++ b/drivers/net/wireless/mwifiex/init.c @@ -35,28 +35,24 @@ static int mwifiex_add_bss_prio_tbl(struct mwifiex_private *priv) { struct mwifiex_adapter *adapter = priv->adapter; struct mwifiex_bss_prio_node *bss_prio; + struct mwifiex_bss_prio_tbl *tbl = adapter->bss_prio_tbl; unsigned long flags; bss_prio = kzalloc(sizeof(struct mwifiex_bss_prio_node), GFP_KERNEL); if (!bss_prio) { dev_err(adapter->dev, "%s: failed to alloc bss_prio\n", - __func__); + __func__); return -ENOMEM; } bss_prio->priv = priv; INIT_LIST_HEAD(&bss_prio->list); - if (!adapter->bss_prio_tbl[priv->bss_priority].bss_prio_cur) - adapter->bss_prio_tbl[priv->bss_priority].bss_prio_cur = - bss_prio; - - spin_lock_irqsave(&adapter->bss_prio_tbl[priv->bss_priority] - .bss_prio_lock, flags); - list_add_tail(&bss_prio->list, - &adapter->bss_prio_tbl[priv->bss_priority] - .bss_prio_head); - spin_unlock_irqrestore(&adapter->bss_prio_tbl[priv->bss_priority] - .bss_prio_lock, flags); + if (!tbl[priv->bss_priority].bss_prio_cur) + tbl[priv->bss_priority].bss_prio_cur = bss_prio; + + spin_lock_irqsave(&tbl[priv->bss_priority].bss_prio_lock, flags); + list_add_tail(&bss_prio->list, &tbl[priv->bss_priority].bss_prio_head); + spin_unlock_irqrestore(&tbl[priv->bss_priority].bss_prio_lock, flags); return 0; } @@ -157,13 +153,13 @@ static int mwifiex_allocate_adapter(struct mwifiex_adapter *adapter) ret = mwifiex_alloc_cmd_buffer(adapter); if (ret) { dev_err(adapter->dev, "%s: failed to alloc cmd buffer\n", - __func__); + __func__); return -1; } adapter->sleep_cfm = dev_alloc_skb(sizeof(struct mwifiex_opt_sleep_confirm) - + INTF_HEADER_LEN); + + INTF_HEADER_LEN); if (!adapter->sleep_cfm) { dev_err(adapter->dev, "%s: failed to alloc sleep cfm" @@ -520,7 +516,7 @@ static void mwifiex_delete_bss_prio_tbl(struct mwifiex_private *priv) struct mwifiex_adapter *adapter = priv->adapter; struct mwifiex_bss_prio_node *bssprio_node, *tmp_node, **cur; struct list_head *head; - spinlock_t *lock; + spinlock_t *lock; /* bss priority lock */ unsigned long flags; for (i = 0; i < adapter->priv_num; ++i) { @@ -638,7 +634,7 @@ int mwifiex_dnld_fw(struct mwifiex_adapter *adapter, ret = adapter->if_ops.check_fw_status(adapter, poll_num); if (!ret) { dev_notice(adapter->dev, - "WLAN FW already running! Skip FW download\n"); + "WLAN FW already running! Skip FW download\n"); goto done; } poll_num = MAX_FIRMWARE_POLL_TRIES; @@ -646,8 +642,7 @@ int mwifiex_dnld_fw(struct mwifiex_adapter *adapter, /* Check if we are the winner for downloading FW */ if (!adapter->winner) { dev_notice(adapter->dev, - "Other interface already running!" - " Skip FW download\n"); + "Other intf already running! Skip FW download\n"); poll_num = MAX_MULTI_INTERFACE_POLL_TRIES; goto poll_fw; } diff --git a/drivers/net/wireless/mwifiex/join.c b/drivers/net/wireless/mwifiex/join.c index 803275f58c78..8f9382b9c3ca 100644 --- a/drivers/net/wireless/mwifiex/join.c +++ b/drivers/net/wireless/mwifiex/join.c @@ -52,8 +52,9 @@ mwifiex_cmd_append_generic_ie(struct mwifiex_private *priv, u8 **buffer) * parameter buffer pointer. */ if (priv->gen_ie_buf_len) { - dev_dbg(priv->adapter->dev, "info: %s: append generic %d to %p\n", - __func__, priv->gen_ie_buf_len, *buffer); + dev_dbg(priv->adapter->dev, + "info: %s: append generic ie len %d to %p\n", + __func__, priv->gen_ie_buf_len, *buffer); /* Wrap the generic IE buffer with a pass through TLV type */ ie_header.type = cpu_to_le16(TLV_TYPE_PASSTHROUGH); @@ -123,8 +124,9 @@ mwifiex_cmd_append_tsf_tlv(struct mwifiex_private *priv, u8 **buffer, memcpy(&tsf_val, bss_desc->time_stamp, sizeof(tsf_val)); - dev_dbg(priv->adapter->dev, "info: %s: TSF offset calc: %016llx - " - "%016llx\n", __func__, tsf_val, bss_desc->network_tsf); + dev_dbg(priv->adapter->dev, + "info: %s: TSF offset calc: %016llx - %016llx\n", + __func__, tsf_val, bss_desc->network_tsf); memcpy(*buffer, &tsf_val, sizeof(tsf_val)); *buffer += sizeof(tsf_val); @@ -167,7 +169,7 @@ static int mwifiex_get_common_rates(struct mwifiex_private *priv, u8 *rate1, } dev_dbg(priv->adapter->dev, "info: Tx data rate set to %#x\n", - priv->data_rate); + priv->data_rate); if (!priv->is_data_rate_auto) { while (*ptr) { @@ -212,7 +214,7 @@ mwifiex_setup_rates_from_bssdesc(struct mwifiex_private *priv, card_rates, card_rates_size)) { *out_rates_size = 0; dev_err(priv->adapter->dev, "%s: cannot get common rates\n", - __func__); + __func__); return -1; } @@ -248,7 +250,7 @@ mwifiex_cmd_append_wapi_ie(struct mwifiex_private *priv, u8 **buffer) */ if (priv->wapi_ie_len) { dev_dbg(priv->adapter->dev, "cmd: append wapi ie %d to %p\n", - priv->wapi_ie_len, *buffer); + priv->wapi_ie_len, *buffer); /* Wrap the generic IE buffer with a pass through TLV type */ ie_header.type = cpu_to_le16(TLV_TYPE_WAPI_IE); @@ -293,10 +295,10 @@ static int mwifiex_append_rsn_ie_wpa_wpa2(struct mwifiex_private *priv, le16_to_cpu(rsn_ie_tlv->header.type) & 0x00FF); rsn_ie_tlv->header.len = cpu_to_le16((u16) priv->wpa_ie[1]); rsn_ie_tlv->header.len = cpu_to_le16(le16_to_cpu(rsn_ie_tlv->header.len) - & 0x00FF); + & 0x00FF); if (le16_to_cpu(rsn_ie_tlv->header.len) <= (sizeof(priv->wpa_ie) - 2)) memcpy(rsn_ie_tlv->rsn_ie, &priv->wpa_ie[2], - le16_to_cpu(rsn_ie_tlv->header.len)); + le16_to_cpu(rsn_ie_tlv->header.len)); else return -1; @@ -379,7 +381,7 @@ int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv, ssid_tlv->header.type = cpu_to_le16(WLAN_EID_SSID); ssid_tlv->header.len = cpu_to_le16((u16) bss_desc->ssid.ssid_len); memcpy(ssid_tlv->ssid, bss_desc->ssid.ssid, - le16_to_cpu(ssid_tlv->header.len)); + le16_to_cpu(ssid_tlv->header.len)); pos += sizeof(ssid_tlv->header) + le16_to_cpu(ssid_tlv->header.len); phy_tlv = (struct mwifiex_ie_types_phy_param_set *) pos; @@ -411,7 +413,7 @@ int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv, memcpy(rates_tlv->rates, rates, rates_size); pos += sizeof(rates_tlv->header) + rates_size; dev_dbg(priv->adapter->dev, "info: ASSOC_CMD: rates size = %d\n", - rates_size); + rates_size); /* Add the Authentication type to be used for Auth frames */ auth_tlv = (struct mwifiex_ie_types_auth_type *) pos; @@ -425,12 +427,12 @@ int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv, pos += sizeof(auth_tlv->header) + le16_to_cpu(auth_tlv->header.len); - if (IS_SUPPORT_MULTI_BANDS(priv->adapter) - && !(ISSUPP_11NENABLED(priv->adapter->fw_cap_info) - && (!bss_desc->disable_11n) - && (priv->adapter->config_bands & BAND_GN - || priv->adapter->config_bands & BAND_AN) - && (bss_desc->bcn_ht_cap) + if (IS_SUPPORT_MULTI_BANDS(priv->adapter) && + !(ISSUPP_11NENABLED(priv->adapter->fw_cap_info) && + (!bss_desc->disable_11n) && + (priv->adapter->config_bands & BAND_GN || + priv->adapter->config_bands & BAND_AN) && + (bss_desc->bcn_ht_cap) ) ) { /* Append a channel TLV for the channel the attempted AP was @@ -445,13 +447,13 @@ int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv, chan_tlv->chan_scan_param[0].chan_number = (bss_desc->phy_param_set.ds_param_set.current_chan); dev_dbg(priv->adapter->dev, "info: Assoc: TLV Chan = %d\n", - chan_tlv->chan_scan_param[0].chan_number); + chan_tlv->chan_scan_param[0].chan_number); chan_tlv->chan_scan_param[0].radio_type = mwifiex_band_to_radio_type((u8) bss_desc->bss_band); dev_dbg(priv->adapter->dev, "info: Assoc: TLV Band = %d\n", - chan_tlv->chan_scan_param[0].radio_type); + chan_tlv->chan_scan_param[0].radio_type); pos += sizeof(chan_tlv->header) + sizeof(struct mwifiex_chan_scan_param_set); } @@ -464,10 +466,10 @@ int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv, return -1; } - if (ISSUPP_11NENABLED(priv->adapter->fw_cap_info) - && (!bss_desc->disable_11n) - && (priv->adapter->config_bands & BAND_GN - || priv->adapter->config_bands & BAND_AN)) + if (ISSUPP_11NENABLED(priv->adapter->fw_cap_info) && + (!bss_desc->disable_11n) && + (priv->adapter->config_bands & BAND_GN || + priv->adapter->config_bands & BAND_AN)) mwifiex_cmd_append_11n_tlv(priv, bss_desc, &pos); /* Append vendor specific IE TLV */ @@ -493,7 +495,7 @@ int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv, tmp_cap &= CAPINFO_MASK; dev_dbg(priv->adapter->dev, "info: ASSOC_CMD: tmp_cap=%4X CAPINFO_MASK=%4lX\n", - tmp_cap, CAPINFO_MASK); + tmp_cap, CAPINFO_MASK); assoc->cap_info_bitmap = cpu_to_le16(tmp_cap); return 0; @@ -573,17 +575,17 @@ int mwifiex_ret_802_11_associate(struct mwifiex_private *priv, assoc_rsp = (struct ieee_types_assoc_rsp *) &resp->params; priv->assoc_rsp_size = min(le16_to_cpu(resp->size) - S_DS_GEN, - sizeof(priv->assoc_rsp_buf)); + sizeof(priv->assoc_rsp_buf)); memcpy(priv->assoc_rsp_buf, &resp->params, priv->assoc_rsp_size); if (le16_to_cpu(assoc_rsp->status_code)) { priv->adapter->dbg.num_cmd_assoc_failure++; - dev_err(priv->adapter->dev, "ASSOC_RESP: association failed, " - "status code = %d, error = 0x%x, a_id = 0x%x\n", - le16_to_cpu(assoc_rsp->status_code), - le16_to_cpu(assoc_rsp->cap_info_bitmap), - le16_to_cpu(assoc_rsp->a_id)); + dev_err(priv->adapter->dev, + "ASSOC_RESP: failed, status code=%d err=%#x a_id=%#x\n", + le16_to_cpu(assoc_rsp->status_code), + le16_to_cpu(assoc_rsp->cap_info_bitmap), + le16_to_cpu(assoc_rsp->a_id)); ret = le16_to_cpu(assoc_rsp->status_code); goto done; @@ -600,7 +602,7 @@ int mwifiex_ret_802_11_associate(struct mwifiex_private *priv, bss_desc = priv->attempted_bss_desc; dev_dbg(priv->adapter->dev, "info: ASSOC_RESP: %s\n", - bss_desc->ssid.ssid); + bss_desc->ssid.ssid); /* Make a copy of current BSSID descriptor */ memcpy(&priv->curr_bss_params.bss_descriptor, @@ -617,8 +619,8 @@ int mwifiex_ret_802_11_associate(struct mwifiex_private *priv, else priv->curr_bss_params.wmm_enabled = false; - if ((priv->wmm_required || bss_desc->bcn_ht_cap) - && priv->curr_bss_params.wmm_enabled) + if ((priv->wmm_required || bss_desc->bcn_ht_cap) && + priv->curr_bss_params.wmm_enabled) priv->wmm_enabled = true; else priv->wmm_enabled = false; @@ -631,7 +633,7 @@ int mwifiex_ret_802_11_associate(struct mwifiex_private *priv, IEEE80211_WMM_IE_AP_QOSINFO_UAPSD) ? 1 : 0); dev_dbg(priv->adapter->dev, "info: ASSOC_RESP: curr_pkt_filter is %#x\n", - priv->curr_pkt_filter); + priv->curr_pkt_filter); if (priv->sec_info.wpa_enabled || priv->sec_info.wpa2_enabled) priv->wpa_is_gtk_set = false; @@ -755,7 +757,7 @@ mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv, memcpy(adhoc_start->ssid, req_ssid->ssid, req_ssid->ssid_len); dev_dbg(adapter->dev, "info: ADHOC_S_CMD: SSID = %s\n", - adhoc_start->ssid); + adhoc_start->ssid); memset(bss_desc->ssid.ssid, 0, IEEE80211_MAX_SSID_LEN); memcpy(bss_desc->ssid.ssid, req_ssid->ssid, req_ssid->ssid_len); @@ -792,7 +794,7 @@ mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv, } dev_dbg(adapter->dev, "info: ADHOC_S_CMD: creating ADHOC on channel %d\n", - priv->adhoc_channel); + priv->adhoc_channel); priv->curr_bss_params.bss_descriptor.channel = priv->adhoc_channel; priv->curr_bss_params.band = adapter->adhoc_start_band; @@ -813,7 +815,7 @@ mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv, adhoc_start->ss_param_set.ibss_param_set.element_id = IBSS_PARA_IE_ID; adhoc_start->ss_param_set.ibss_param_set.len = IBSS_PARA_IE_LEN; adhoc_start->ss_param_set.ibss_param_set.atim_window - = cpu_to_le16(priv->atim_window); + = cpu_to_le16(priv->atim_window); memcpy(&bss_desc->ss_param_set, &adhoc_start->ss_param_set, sizeof(union ieee_types_ss_param_set)); @@ -841,10 +843,10 @@ mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv, if ((adapter->adhoc_start_band & BAND_G) && (priv->curr_pkt_filter & HostCmd_ACT_MAC_ADHOC_G_PROTECTION_ON)) { if (mwifiex_send_cmd_async(priv, HostCmd_CMD_MAC_CONTROL, - HostCmd_ACT_GEN_SET, 0, - &priv->curr_pkt_filter)) { + HostCmd_ACT_GEN_SET, 0, + &priv->curr_pkt_filter)) { dev_err(adapter->dev, - "ADHOC_S_CMD: G Protection config failed\n"); + "ADHOC_S_CMD: G Protection config failed\n"); return -1; } } @@ -860,8 +862,8 @@ mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv, &adhoc_start->data_rate, priv->curr_bss_params.num_of_rates); dev_dbg(adapter->dev, "info: ADHOC_S_CMD: rates=%02x %02x %02x %02x\n", - adhoc_start->data_rate[0], adhoc_start->data_rate[1], - adhoc_start->data_rate[2], adhoc_start->data_rate[3]); + adhoc_start->data_rate[0], adhoc_start->data_rate[1], + adhoc_start->data_rate[2], adhoc_start->data_rate[3]); dev_dbg(adapter->dev, "info: ADHOC_S_CMD: AD-HOC Start command is ready\n"); @@ -878,12 +880,12 @@ mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv, (u8) priv->curr_bss_params.bss_descriptor.channel; dev_dbg(adapter->dev, "info: ADHOC_S_CMD: TLV Chan = %d\n", - chan_tlv->chan_scan_param[0].chan_number); + chan_tlv->chan_scan_param[0].chan_number); chan_tlv->chan_scan_param[0].radio_type = mwifiex_band_to_radio_type(priv->curr_bss_params.band); - if (adapter->adhoc_start_band & BAND_GN - || adapter->adhoc_start_band & BAND_AN) { + if (adapter->adhoc_start_band & BAND_GN || + adapter->adhoc_start_band & BAND_AN) { if (adapter->sec_chan_offset == IEEE80211_HT_PARAM_CHA_SEC_ABOVE) chan_tlv->chan_scan_param[0].radio_type |= @@ -894,7 +896,7 @@ mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv, (IEEE80211_HT_PARAM_CHA_SEC_BELOW << 4); } dev_dbg(adapter->dev, "info: ADHOC_S_CMD: TLV Band = %d\n", - chan_tlv->chan_scan_param[0].radio_type); + chan_tlv->chan_scan_param[0].radio_type); pos += sizeof(chan_tlv->header) + sizeof(struct mwifiex_chan_scan_param_set); cmd_append_size += @@ -925,15 +927,14 @@ mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv, mwifiex_fill_cap_info(priv, radio_type, ht_cap); pos += sizeof(struct mwifiex_ie_types_htcap); - cmd_append_size += - sizeof(struct mwifiex_ie_types_htcap); + cmd_append_size += sizeof(struct mwifiex_ie_types_htcap); /* Fill HT INFORMATION */ ht_info = (struct mwifiex_ie_types_htinfo *) pos; memset(ht_info, 0, sizeof(struct mwifiex_ie_types_htinfo)); ht_info->header.type = cpu_to_le16(WLAN_EID_HT_INFORMATION); ht_info->header.len = - cpu_to_le16(sizeof(struct ieee80211_ht_info)); + cpu_to_le16(sizeof(struct ieee80211_ht_info)); ht_info->ht_info.control_chan = (u8) priv->curr_bss_params.bss_descriptor.channel; @@ -947,12 +948,12 @@ mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv, ht_info->ht_info.basic_set[0] = 0xff; pos += sizeof(struct mwifiex_ie_types_htinfo); cmd_append_size += - sizeof(struct mwifiex_ie_types_htinfo); + sizeof(struct mwifiex_ie_types_htinfo); } - cmd->size = cpu_to_le16((u16) - (sizeof(struct host_cmd_ds_802_11_ad_hoc_start) - + S_DS_GEN + cmd_append_size)); + cmd->size = + cpu_to_le16((u16)(sizeof(struct host_cmd_ds_802_11_ad_hoc_start) + + S_DS_GEN + cmd_append_size)); if (adapter->adhoc_start_band == BAND_B) tmp_cap &= ~WLAN_CAPABILITY_SHORT_SLOT_TIME; @@ -1005,10 +1006,10 @@ mwifiex_cmd_802_11_ad_hoc_join(struct mwifiex_private *priv, curr_pkt_filter | HostCmd_ACT_MAC_ADHOC_G_PROTECTION_ON; if (mwifiex_send_cmd_async(priv, HostCmd_CMD_MAC_CONTROL, - HostCmd_ACT_GEN_SET, 0, - &curr_pkt_filter)) { + HostCmd_ACT_GEN_SET, 0, + &curr_pkt_filter)) { dev_err(priv->adapter->dev, - "ADHOC_J_CMD: G Protection config failed\n"); + "ADHOC_J_CMD: G Protection config failed\n"); return -1; } } @@ -1039,13 +1040,14 @@ mwifiex_cmd_802_11_ad_hoc_join(struct mwifiex_private *priv, tmp_cap &= CAPINFO_MASK; - dev_dbg(priv->adapter->dev, "info: ADHOC_J_CMD: tmp_cap=%4X" - " CAPINFO_MASK=%4lX\n", tmp_cap, CAPINFO_MASK); + dev_dbg(priv->adapter->dev, + "info: ADHOC_J_CMD: tmp_cap=%4X CAPINFO_MASK=%4lX\n", + tmp_cap, CAPINFO_MASK); /* Information on BSSID descriptor passed to FW */ - dev_dbg(priv->adapter->dev, "info: ADHOC_J_CMD: BSSID = %pM, SSID = %s\n", - adhoc_join->bss_descriptor.bssid, - adhoc_join->bss_descriptor.ssid); + dev_dbg(priv->adapter->dev, "info: ADHOC_J_CMD: BSSID=%pM, SSID='%s'\n", + adhoc_join->bss_descriptor.bssid, + adhoc_join->bss_descriptor.ssid); for (i = 0; bss_desc->supported_rates[i] && i < MWIFIEX_SUPPORTED_RATES; @@ -1082,18 +1084,18 @@ mwifiex_cmd_802_11_ad_hoc_join(struct mwifiex_private *priv, sizeof(struct mwifiex_chan_scan_param_set)); chan_tlv->chan_scan_param[0].chan_number = (bss_desc->phy_param_set.ds_param_set.current_chan); - dev_dbg(priv->adapter->dev, "info: ADHOC_J_CMD: TLV Chan = %d\n", - chan_tlv->chan_scan_param[0].chan_number); + dev_dbg(priv->adapter->dev, "info: ADHOC_J_CMD: TLV Chan=%d\n", + chan_tlv->chan_scan_param[0].chan_number); chan_tlv->chan_scan_param[0].radio_type = mwifiex_band_to_radio_type((u8) bss_desc->bss_band); - dev_dbg(priv->adapter->dev, "info: ADHOC_J_CMD: TLV Band = %d\n", - chan_tlv->chan_scan_param[0].radio_type); + dev_dbg(priv->adapter->dev, "info: ADHOC_J_CMD: TLV Band=%d\n", + chan_tlv->chan_scan_param[0].radio_type); pos += sizeof(chan_tlv->header) + - sizeof(struct mwifiex_chan_scan_param_set); + sizeof(struct mwifiex_chan_scan_param_set); cmd_append_size += sizeof(chan_tlv->header) + - sizeof(struct mwifiex_chan_scan_param_set); + sizeof(struct mwifiex_chan_scan_param_set); } if (priv->sec_info.wpa_enabled) @@ -1110,9 +1112,9 @@ mwifiex_cmd_802_11_ad_hoc_join(struct mwifiex_private *priv, cmd_append_size += mwifiex_cmd_append_vsie_tlv(priv, MWIFIEX_VSIE_MASK_ADHOC, &pos); - cmd->size = cpu_to_le16((u16) - (sizeof(struct host_cmd_ds_802_11_ad_hoc_join) - + S_DS_GEN + cmd_append_size)); + cmd->size = cpu_to_le16 + ((u16) (sizeof(struct host_cmd_ds_802_11_ad_hoc_join) + + S_DS_GEN + cmd_append_size)); adhoc_join->bss_descriptor.cap_info_bitmap = cpu_to_le16(tmp_cap); @@ -1157,7 +1159,7 @@ int mwifiex_ret_802_11_ad_hoc(struct mwifiex_private *priv, if (le16_to_cpu(resp->command) == HostCmd_CMD_802_11_AD_HOC_START) { dev_dbg(priv->adapter->dev, "info: ADHOC_S_RESP %s\n", - bss_desc->ssid.ssid); + bss_desc->ssid.ssid); /* Update the created network descriptor with the new BSSID */ memcpy(bss_desc->mac_address, @@ -1170,7 +1172,7 @@ int mwifiex_ret_802_11_ad_hoc(struct mwifiex_private *priv, * If BSSID has changed use SSID to compare instead of BSSID */ dev_dbg(priv->adapter->dev, "info: ADHOC_J_RESP %s\n", - bss_desc->ssid.ssid); + bss_desc->ssid.ssid); /* * Make a copy of current BSSID descriptor, only needed for @@ -1184,9 +1186,9 @@ int mwifiex_ret_802_11_ad_hoc(struct mwifiex_private *priv, } dev_dbg(priv->adapter->dev, "info: ADHOC_RESP: channel = %d\n", - priv->adhoc_channel); + priv->adhoc_channel); dev_dbg(priv->adapter->dev, "info: ADHOC_RESP: BSSID = %pM\n", - priv->curr_bss_params.bss_descriptor.mac_address); + priv->curr_bss_params.bss_descriptor.mac_address); if (!netif_carrier_ok(priv->netdev)) netif_carrier_on(priv->netdev); @@ -1249,9 +1251,9 @@ mwifiex_adhoc_start(struct mwifiex_private *priv, dev_dbg(priv->adapter->dev, "info: Adhoc Channel = %d\n", priv->adhoc_channel); dev_dbg(priv->adapter->dev, "info: curr_bss_params.channel = %d\n", - priv->curr_bss_params.bss_descriptor.channel); + priv->curr_bss_params.bss_descriptor.channel); dev_dbg(priv->adapter->dev, "info: curr_bss_params.band = %d\n", - priv->curr_bss_params.band); + priv->curr_bss_params.band); return mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_AD_HOC_START, HostCmd_ACT_GEN_SET, 0, adhoc_ssid); @@ -1267,13 +1269,13 @@ int mwifiex_adhoc_join(struct mwifiex_private *priv, struct mwifiex_bssdescriptor *bss_desc) { dev_dbg(priv->adapter->dev, "info: adhoc join: curr_bss ssid =%s\n", - priv->curr_bss_params.bss_descriptor.ssid.ssid); + priv->curr_bss_params.bss_descriptor.ssid.ssid); dev_dbg(priv->adapter->dev, "info: adhoc join: curr_bss ssid_len =%u\n", - priv->curr_bss_params.bss_descriptor.ssid.ssid_len); + priv->curr_bss_params.bss_descriptor.ssid.ssid_len); dev_dbg(priv->adapter->dev, "info: adhoc join: ssid =%s\n", bss_desc->ssid.ssid); dev_dbg(priv->adapter->dev, "info: adhoc join: ssid_len =%u\n", - bss_desc->ssid.ssid_len); + bss_desc->ssid.ssid_len); /* Check if the requested SSID is already joined */ if (priv->curr_bss_params.bss_descriptor.ssid.ssid_len && @@ -1287,9 +1289,9 @@ int mwifiex_adhoc_join(struct mwifiex_private *priv, } dev_dbg(priv->adapter->dev, "info: curr_bss_params.channel = %d\n", - priv->curr_bss_params.bss_descriptor.channel); + priv->curr_bss_params.bss_descriptor.channel); dev_dbg(priv->adapter->dev, "info: curr_bss_params.band = %c\n", - priv->curr_bss_params.band); + priv->curr_bss_params.band); return mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_AD_HOC_JOIN, HostCmd_ACT_GEN_SET, 0, bss_desc); -- cgit From f57c1edc1e0622d2cf883850f37978827bcef573 Mon Sep 17 00:00:00 2001 From: Yogesh Ashok Powar Date: Tue, 13 Mar 2012 19:22:37 -0700 Subject: mwifiex: fix checkpatch --strict warnings/errors Part 4 For files main.c, main.h and pcie.c Signed-off-by: Yogesh Ashok Powar Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/main.c | 49 +++-- drivers/net/wireless/mwifiex/main.h | 4 +- drivers/net/wireless/mwifiex/pcie.c | 384 +++++++++++++++++++----------------- 3 files changed, 226 insertions(+), 211 deletions(-) diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c index 790a3796483c..9d1b3ca6334b 100644 --- a/drivers/net/wireless/mwifiex/main.c +++ b/drivers/net/wireless/mwifiex/main.c @@ -64,11 +64,10 @@ static int mwifiex_register(void *card, struct mwifiex_if_ops *if_ops, adapter->priv_num = 0; /* Allocate memory for private structure */ - adapter->priv[0] = kzalloc(sizeof(struct mwifiex_private), - GFP_KERNEL); + adapter->priv[0] = kzalloc(sizeof(struct mwifiex_private), GFP_KERNEL); if (!adapter->priv[0]) { - dev_err(adapter->dev, "%s: failed to alloc priv[0]\n", - __func__); + dev_err(adapter->dev, + "%s: failed to alloc priv[0]\n", __func__); goto error; } @@ -169,8 +168,8 @@ process_start: if ((adapter->ps_state == PS_STATE_SLEEP) && (adapter->pm_wakeup_card_req && !adapter->pm_wakeup_fw_try) && - (is_command_pending(adapter) - || !mwifiex_wmm_lists_empty(adapter))) { + (is_command_pending(adapter) || + !mwifiex_wmm_lists_empty(adapter))) { adapter->pm_wakeup_fw_try = true; adapter->if_ops.wakeup(adapter); continue; @@ -187,10 +186,10 @@ process_start: adapter->tx_lock_flag) break; - if (adapter->scan_processing || adapter->data_sent - || mwifiex_wmm_lists_empty(adapter)) { - if (adapter->cmd_sent || adapter->curr_cmd - || (!is_command_pending(adapter))) + if (adapter->scan_processing || adapter->data_sent || + mwifiex_wmm_lists_empty(adapter)) { + if (adapter->cmd_sent || adapter->curr_cmd || + (!is_command_pending(adapter))) break; } } @@ -223,10 +222,10 @@ process_start: /* * The ps_state may have been changed during processing of * Sleep Request event. */ - if ((adapter->ps_state == PS_STATE_SLEEP) - || (adapter->ps_state == PS_STATE_PRE_SLEEP) - || (adapter->ps_state == PS_STATE_SLEEP_CFM) - || adapter->tx_lock_flag) + if ((adapter->ps_state == PS_STATE_SLEEP) || + (adapter->ps_state == PS_STATE_PRE_SLEEP) || + (adapter->ps_state == PS_STATE_SLEEP_CFM) || + adapter->tx_lock_flag) continue; if (!adapter->cmd_sent && !adapter->curr_cmd) { @@ -249,8 +248,8 @@ process_start: } if (adapter->delay_null_pkt && !adapter->cmd_sent && - !adapter->curr_cmd && !is_command_pending(adapter) - && mwifiex_wmm_lists_empty(adapter)) { + !adapter->curr_cmd && !is_command_pending(adapter) && + mwifiex_wmm_lists_empty(adapter)) { if (!mwifiex_send_null_packet (mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA), MWIFIEX_TxPD_POWER_MGMT_NULL_PACKET | @@ -371,7 +370,7 @@ mwifiex_fill_buffer(struct sk_buff *skb) iph = ip_hdr(skb); tid = IPTOS_PREC(iph->tos); pr_debug("data: packet type ETH_P_IP: %04x, tid=%#x prio=%#x\n", - eth->h_proto, tid, skb->priority); + eth->h_proto, tid, skb->priority); break; case __constant_htons(ETH_P_ARP): pr_debug("data: ARP packet: %04x\n", eth->h_proto); @@ -425,7 +424,7 @@ mwifiex_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) struct mwifiex_txinfo *tx_info; dev_dbg(priv->adapter->dev, "data: %lu BSS(%d-%d): Data <= kernel\n", - jiffies, priv->bss_type, priv->bss_num); + jiffies, priv->bss_type, priv->bss_num); if (priv->adapter->surprise_removed) { kfree_skb(skb); @@ -441,7 +440,7 @@ mwifiex_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) if (skb_headroom(skb) < MWIFIEX_MIN_DATA_HEADER_LEN) { dev_dbg(priv->adapter->dev, "data: Tx: insufficient skb headroom %d\n", - skb_headroom(skb)); + skb_headroom(skb)); /* Insufficient skb headroom - allocate a new skb */ new_skb = skb_realloc_headroom(skb, MWIFIEX_MIN_DATA_HEADER_LEN); @@ -454,7 +453,7 @@ mwifiex_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) kfree_skb(skb); skb = new_skb; dev_dbg(priv->adapter->dev, "info: new skb headroomd %d\n", - skb_headroom(skb)); + skb_headroom(skb)); } tx_info = MWIFIEX_SKB_TXCB(skb); @@ -494,8 +493,8 @@ mwifiex_set_mac_address(struct net_device *dev, void *addr) if (!ret) memcpy(priv->netdev->dev_addr, priv->curr_addr, ETH_ALEN); else - dev_err(priv->adapter->dev, "set mac address failed: ret=%d" - "\n", ret); + dev_err(priv->adapter->dev, + "set mac address failed: ret=%d\n", ret); memcpy(dev->dev_addr, priv->curr_addr, ETH_ALEN); @@ -533,7 +532,7 @@ mwifiex_tx_timeout(struct net_device *dev) struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); dev_err(priv->adapter->dev, "%lu : Tx timeout, bss_type-num = %d-%d\n", - jiffies, priv->bss_type, priv->bss_num); + jiffies, priv->bss_type, priv->bss_num); mwifiex_set_trans_start(dev); priv->num_tx_timeout++; } @@ -704,7 +703,7 @@ mwifiex_add_card(void *card, struct semaphore *sem, rtnl_lock(); /* Create station interface by default */ if (!mwifiex_add_virtual_intf(priv->wdev->wiphy, "mlan%d", - NL80211_IFTYPE_STATION, NULL, NULL)) { + NL80211_IFTYPE_STATION, NULL, NULL)) { rtnl_unlock(); dev_err(adapter->dev, "cannot create default station" " interface\n"); @@ -781,7 +780,7 @@ int mwifiex_remove_card(struct mwifiex_adapter *adapter, struct semaphore *sem) if (priv && priv->netdev) { if (!netif_queue_stopped(priv->netdev)) mwifiex_stop_net_dev_queue(priv->netdev, - adapter); + adapter); if (netif_carrier_ok(priv->netdev)) netif_carrier_off(priv->netdev); } diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h index c0df48f63e11..35225e9b1080 100644 --- a/drivers/net/wireless/mwifiex/main.h +++ b/drivers/net/wireless/mwifiex/main.h @@ -841,8 +841,8 @@ mwifiex_get_priv_by_id(struct mwifiex_adapter *adapter, for (i = 0; i < adapter->priv_num; i++) { if (adapter->priv[i]) { - if ((adapter->priv[i]->bss_num == bss_num) - && (adapter->priv[i]->bss_type == bss_type)) + if ((adapter->priv[i]->bss_num == bss_num) && + (adapter->priv[i]->bss_type == bss_type)) break; } } diff --git a/drivers/net/wireless/mwifiex/pcie.c b/drivers/net/wireless/mwifiex/pcie.c index 1033f00a775f..e1f45ecf39a5 100644 --- a/drivers/net/wireless/mwifiex/pcie.c +++ b/drivers/net/wireless/mwifiex/pcie.c @@ -83,7 +83,7 @@ static int mwifiex_pcie_probe(struct pci_dev *pdev, struct pcie_service_card *card; pr_debug("info: vendor=0x%4.04X device=0x%4.04X rev=%d\n", - pdev->vendor, pdev->device, pdev->revision); + pdev->vendor, pdev->device, pdev->revision); card = kzalloc(sizeof(struct pcie_service_card), GFP_KERNEL); if (!card) { @@ -110,6 +110,7 @@ static void mwifiex_pcie_remove(struct pci_dev *pdev) { struct pcie_service_card *card; struct mwifiex_adapter *adapter; + struct mwifiex_private *priv; int i; card = pci_get_drvdata(pdev); @@ -128,16 +129,15 @@ static void mwifiex_pcie_remove(struct pci_dev *pdev) for (i = 0; i < adapter->priv_num; i++) if ((GET_BSS_ROLE(adapter->priv[i]) == - MWIFIEX_BSS_ROLE_STA) && - adapter->priv[i]->media_connected) + MWIFIEX_BSS_ROLE_STA) && + adapter->priv[i]->media_connected) mwifiex_deauthenticate(adapter->priv[i], NULL); - mwifiex_disable_auto_ds(mwifiex_get_priv(adapter, - MWIFIEX_BSS_ROLE_ANY)); + priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY); - mwifiex_init_shutdown_fw(mwifiex_get_priv(adapter, - MWIFIEX_BSS_ROLE_ANY), - MWIFIEX_FUNC_SHUTDOWN); + mwifiex_disable_auto_ds(priv); + + mwifiex_init_shutdown_fw(priv, MWIFIEX_FUNC_SHUTDOWN); } mwifiex_remove_card(card->adapter, &add_remove_card_sem); @@ -221,7 +221,7 @@ static int mwifiex_pcie_resume(struct pci_dev *pdev) netif_carrier_on(adapter->priv[i]->netdev); mwifiex_cancel_hs(mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA), - MWIFIEX_ASYNC_CMD); + MWIFIEX_ASYNC_CMD); return 0; } @@ -380,26 +380,26 @@ static int mwifiex_pcie_create_txbd_ring(struct mwifiex_adapter *adapter) /* allocate shared memory for the BD ring and divide the same in to several descriptors */ card->txbd_ring_size = sizeof(struct mwifiex_pcie_buf_desc) * - MWIFIEX_MAX_TXRX_BD; + MWIFIEX_MAX_TXRX_BD; dev_dbg(adapter->dev, "info: txbd_ring: Allocating %d bytes\n", - card->txbd_ring_size); + card->txbd_ring_size); card->txbd_ring_vbase = kzalloc(card->txbd_ring_size, GFP_KERNEL); if (!card->txbd_ring_vbase) { - dev_err(adapter->dev, "Unable to allocate buffer for txbd ring.\n"); + dev_err(adapter->dev, "Unable to alloc buffer for txbd ring\n"); return -ENOMEM; } card->txbd_ring_pbase = virt_to_phys(card->txbd_ring_vbase); - dev_dbg(adapter->dev, "info: txbd_ring - base: %p, pbase: %#x:%x," - "len: %x\n", card->txbd_ring_vbase, - (u32)card->txbd_ring_pbase, - (u32)((u64)card->txbd_ring_pbase >> 32), - card->txbd_ring_size); + dev_dbg(adapter->dev, + "info: txbd_ring - base: %p, pbase: %#x:%x, len: %x\n", + card->txbd_ring_vbase, (u32)card->txbd_ring_pbase, + (u32)((u64)card->txbd_ring_pbase >> 32), card->txbd_ring_size); for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) { card->txbd_ring[i] = (struct mwifiex_pcie_buf_desc *) - (card->txbd_ring_vbase + - (sizeof(struct mwifiex_pcie_buf_desc) * i)); + (card->txbd_ring_vbase + + (sizeof(struct mwifiex_pcie_buf_desc) + * i)); /* Allocate buffer here so that firmware can DMA data from it */ skb = dev_alloc_skb(MWIFIEX_RX_DATA_BUF_SIZE); @@ -412,10 +412,9 @@ static int mwifiex_pcie_create_txbd_ring(struct mwifiex_adapter *adapter) skb_put(skb, MWIFIEX_RX_DATA_BUF_SIZE); dev_dbg(adapter->dev, "info: TX ring: add new skb base: %p, " - "buf_base: %p, buf_pbase: %#x:%x, " - "buf_len: %#x\n", skb, skb->data, - (u32)*buf_pa, (u32)(((u64)*buf_pa >> 32)), - skb->len); + "buf_base: %p, buf_pbase: %#x:%x, buf_len: %#x\n", + skb, skb->data, (u32)*buf_pa, + (u32)(((u64)*buf_pa >> 32)), skb->len); card->tx_buf_list[i] = skb; card->txbd_ring[i]->paddr = *buf_pa; @@ -469,9 +468,9 @@ static int mwifiex_pcie_create_rxbd_ring(struct mwifiex_adapter *adapter) card->rxbd_rdptr |= MWIFIEX_BD_FLAG_ROLLOVER_IND; card->rxbd_ring_size = sizeof(struct mwifiex_pcie_buf_desc) * - MWIFIEX_MAX_TXRX_BD; + MWIFIEX_MAX_TXRX_BD; dev_dbg(adapter->dev, "info: rxbd_ring: Allocating %d bytes\n", - card->rxbd_ring_size); + card->rxbd_ring_size); card->rxbd_ring_vbase = kzalloc(card->rxbd_ring_size, GFP_KERNEL); if (!card->rxbd_ring_vbase) { dev_err(adapter->dev, "Unable to allocate buffer for " @@ -480,21 +479,23 @@ static int mwifiex_pcie_create_rxbd_ring(struct mwifiex_adapter *adapter) } card->rxbd_ring_pbase = virt_to_phys(card->rxbd_ring_vbase); - dev_dbg(adapter->dev, "info: rxbd_ring - base: %p, pbase: %#x:%x," - "len: %#x\n", card->rxbd_ring_vbase, - (u32)card->rxbd_ring_pbase, - (u32)((u64)card->rxbd_ring_pbase >> 32), - card->rxbd_ring_size); + dev_dbg(adapter->dev, + "info: rxbd_ring - base: %p, pbase: %#x:%x, len: %#x\n", + card->rxbd_ring_vbase, (u32)card->rxbd_ring_pbase, + (u32)((u64)card->rxbd_ring_pbase >> 32), + card->rxbd_ring_size); for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) { card->rxbd_ring[i] = (struct mwifiex_pcie_buf_desc *) - (card->rxbd_ring_vbase + - (sizeof(struct mwifiex_pcie_buf_desc) * i)); + (card->rxbd_ring_vbase + + (sizeof(struct mwifiex_pcie_buf_desc) + * i)); /* Allocate skb here so that firmware can DMA data from it */ skb = dev_alloc_skb(MWIFIEX_RX_DATA_BUF_SIZE); if (!skb) { - dev_err(adapter->dev, "Unable to allocate skb for RX ring.\n"); + dev_err(adapter->dev, + "Unable to allocate skb for RX ring.\n"); kfree(card->rxbd_ring_vbase); return -ENOMEM; } @@ -502,10 +503,9 @@ static int mwifiex_pcie_create_rxbd_ring(struct mwifiex_adapter *adapter) skb_put(skb, MWIFIEX_RX_DATA_BUF_SIZE); dev_dbg(adapter->dev, "info: RX ring: add new skb base: %p, " - "buf_base: %p, buf_pbase: %#x:%x, " - "buf_len: %#x\n", skb, skb->data, - (u32)*buf_pa, (u32)((u64)*buf_pa >> 32), - skb->len); + "buf_base: %p, buf_pbase: %#x:%x, buf_len: %#x\n", + skb, skb->data, (u32)*buf_pa, (u32)((u64)*buf_pa >> 32), + skb->len); card->rx_buf_list[i] = skb; card->rxbd_ring[i]->paddr = *buf_pa; @@ -562,32 +562,34 @@ static int mwifiex_pcie_create_evtbd_ring(struct mwifiex_adapter *adapter) card->evtbd_rdptr |= MWIFIEX_BD_FLAG_ROLLOVER_IND; card->evtbd_ring_size = sizeof(struct mwifiex_pcie_buf_desc) * - MWIFIEX_MAX_EVT_BD; + MWIFIEX_MAX_EVT_BD; dev_dbg(adapter->dev, "info: evtbd_ring: Allocating %d bytes\n", - card->evtbd_ring_size); + card->evtbd_ring_size); card->evtbd_ring_vbase = kzalloc(card->evtbd_ring_size, GFP_KERNEL); if (!card->evtbd_ring_vbase) { - dev_err(adapter->dev, "Unable to allocate buffer. " - "Terminating download\n"); + dev_err(adapter->dev, + "Unable to allocate buffer. Terminating download\n"); return -ENOMEM; } card->evtbd_ring_pbase = virt_to_phys(card->evtbd_ring_vbase); - dev_dbg(adapter->dev, "info: CMDRSP/EVT bd_ring - base: %p, " - "pbase: %#x:%x, len: %#x\n", card->evtbd_ring_vbase, - (u32)card->evtbd_ring_pbase, - (u32)((u64)card->evtbd_ring_pbase >> 32), - card->evtbd_ring_size); + dev_dbg(adapter->dev, + "info: CMDRSP/EVT bd_ring - base: %p pbase: %#x:%x len: %#x\n", + card->evtbd_ring_vbase, (u32)card->evtbd_ring_pbase, + (u32)((u64)card->evtbd_ring_pbase >> 32), + card->evtbd_ring_size); for (i = 0; i < MWIFIEX_MAX_EVT_BD; i++) { card->evtbd_ring[i] = (struct mwifiex_pcie_buf_desc *) - (card->evtbd_ring_vbase + - (sizeof(struct mwifiex_pcie_buf_desc) * i)); + (card->evtbd_ring_vbase + + (sizeof(struct mwifiex_pcie_buf_desc) + * i)); /* Allocate skb here so that firmware can DMA data from it */ skb = dev_alloc_skb(MAX_EVENT_SIZE); if (!skb) { - dev_err(adapter->dev, "Unable to allocate skb for EVENT buf.\n"); + dev_err(adapter->dev, + "Unable to allocate skb for EVENT buf.\n"); kfree(card->evtbd_ring_vbase); return -ENOMEM; } @@ -595,10 +597,9 @@ static int mwifiex_pcie_create_evtbd_ring(struct mwifiex_adapter *adapter) skb_put(skb, MAX_EVENT_SIZE); dev_dbg(adapter->dev, "info: Evt ring: add new skb. base: %p, " - "buf_base: %p, buf_pbase: %#x:%x, " - "buf_len: %#x\n", skb, skb->data, - (u32)*buf_pa, (u32)((u64)*buf_pa >> 32), - skb->len); + "buf_base: %p, buf_pbase: %#x:%x, buf_len: %#x\n", + skb, skb->data, (u32)*buf_pa, (u32)((u64)*buf_pa >> 32), + skb->len); card->evt_buf_list[i] = skb; card->evtbd_ring[i]->paddr = *buf_pa; @@ -647,8 +648,8 @@ static int mwifiex_pcie_alloc_cmdrsp_buf(struct mwifiex_adapter *adapter) /* Allocate memory for receiving command response data */ skb = dev_alloc_skb(MWIFIEX_UPLD_SIZE); if (!skb) { - dev_err(adapter->dev, "Unable to allocate skb for command " - "response data.\n"); + dev_err(adapter->dev, + "Unable to allocate skb for command response data.\n"); return -ENOMEM; } mwifiex_update_sk_buff_pa(skb); @@ -659,8 +660,8 @@ static int mwifiex_pcie_alloc_cmdrsp_buf(struct mwifiex_adapter *adapter) /* Allocate memory for sending command to firmware */ skb = dev_alloc_skb(MWIFIEX_SIZE_OF_CMD_BUFFER); if (!skb) { - dev_err(adapter->dev, "Unable to allocate skb for command " - "data.\n"); + dev_err(adapter->dev, + "Unable to allocate skb for command data.\n"); return -ENOMEM; } mwifiex_update_sk_buff_pa(skb); @@ -702,8 +703,8 @@ static int mwifiex_pcie_alloc_sleep_cookie_buf(struct mwifiex_adapter *adapter) /* Allocate memory for sleep cookie */ skb = dev_alloc_skb(sizeof(u32)); if (!skb) { - dev_err(adapter->dev, "Unable to allocate skb for sleep " - "cookie!\n"); + dev_err(adapter->dev, + "Unable to allocate skb for sleep cookie!\n"); return -ENOMEM; } mwifiex_update_sk_buff_pa(skb); @@ -713,7 +714,7 @@ static int mwifiex_pcie_alloc_sleep_cookie_buf(struct mwifiex_adapter *adapter) *(u32 *)skb->data = FW_AWAKE_COOKIE; dev_dbg(adapter->dev, "alloc_scook: sleep cookie=0x%x\n", - *((u32 *)skb->data)); + *((u32 *)skb->data)); /* Save the sleep cookie */ card->sleep_cookie = skb; @@ -757,15 +758,15 @@ mwifiex_pcie_send_data(struct mwifiex_adapter *adapter, struct sk_buff *skb) /* Read the TX ring read pointer set by firmware */ if (mwifiex_read_reg(adapter, REG_TXBD_RDPTR, &rdptr)) { - dev_err(adapter->dev, "SEND DATA: failed to read " - "REG_TXBD_RDPTR\n"); + dev_err(adapter->dev, + "SEND DATA: failed to read REG_TXBD_RDPTR\n"); return -1; } wrindx = card->txbd_wrptr & MWIFIEX_TXBD_MASK; dev_dbg(adapter->dev, "info: SEND DATA: \n", rdptr, - card->txbd_wrptr); + card->txbd_wrptr); if (((card->txbd_wrptr & MWIFIEX_TXBD_MASK) != (rdptr & MWIFIEX_TXBD_MASK)) || ((card->txbd_wrptr & MWIFIEX_BD_FLAG_ROLLOVER_IND) != @@ -797,32 +798,31 @@ mwifiex_pcie_send_data(struct mwifiex_adapter *adapter, struct sk_buff *skb) /* Write the TX ring write pointer in to REG_TXBD_WRPTR */ if (mwifiex_write_reg(adapter, REG_TXBD_WRPTR, - card->txbd_wrptr)) { - dev_err(adapter->dev, "SEND DATA: failed to write " - "REG_TXBD_WRPTR\n"); + card->txbd_wrptr)) { + dev_err(adapter->dev, + "SEND DATA: failed to write REG_TXBD_WRPTR\n"); return 0; } /* Send the TX ready interrupt */ if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT, CPU_INTR_DNLD_RDY)) { - dev_err(adapter->dev, "SEND DATA: failed to assert " - "door-bell interrupt.\n"); + dev_err(adapter->dev, + "SEND DATA: failed to assert door-bell intr\n"); return -1; } dev_dbg(adapter->dev, "info: SEND DATA: Updated and sent packet to firmware " - "successfully\n", rdptr, - card->txbd_wrptr); + "%#x> and sent packet to firmware successfully\n", + rdptr, card->txbd_wrptr); } else { - dev_dbg(adapter->dev, "info: TX Ring full, can't send anymore " - "packets to firmware\n"); + dev_dbg(adapter->dev, + "info: TX Ring full, can't send packets to fw\n"); adapter->data_sent = true; /* Send the TX ready interrupt */ if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT, CPU_INTR_DNLD_RDY)) - dev_err(adapter->dev, "SEND DATA: failed to assert " - "door-bell interrupt\n"); + dev_err(adapter->dev, + "SEND DATA: failed to assert door-bell intr\n"); return -EBUSY; } @@ -842,8 +842,8 @@ static int mwifiex_pcie_process_recv_data(struct mwifiex_adapter *adapter) /* Read the RX ring Write pointer set by firmware */ if (mwifiex_read_reg(adapter, REG_RXBD_WRPTR, &wrptr)) { - dev_err(adapter->dev, "RECV DATA: failed to read " - "REG_TXBD_RDPTR\n"); + dev_err(adapter->dev, + "RECV DATA: failed to read REG_TXBD_RDPTR\n"); ret = -1; goto done; } @@ -861,12 +861,13 @@ static int mwifiex_pcie_process_recv_data(struct mwifiex_adapter *adapter) /* Get data length from interface header - first byte is len, second byte is type */ rx_len = *((u16 *)skb_data->data); - dev_dbg(adapter->dev, "info: RECV DATA: Rd=%#x, Wr=%#x, " - "Len=%d\n", card->rxbd_rdptr, wrptr, rx_len); + dev_dbg(adapter->dev, + "info: RECV DATA: Rd=%#x, Wr=%#x, Len=%d\n", + card->rxbd_rdptr, wrptr, rx_len); skb_tmp = dev_alloc_skb(rx_len); if (!skb_tmp) { - dev_dbg(adapter->dev, "info: Failed to alloc skb " - "for RX\n"); + dev_dbg(adapter->dev, + "info: Failed to alloc skb for RX\n"); ret = -EBUSY; goto done; } @@ -881,26 +882,26 @@ static int mwifiex_pcie_process_recv_data(struct mwifiex_adapter *adapter) MWIFIEX_BD_FLAG_ROLLOVER_IND); } dev_dbg(adapter->dev, "info: RECV DATA: \n", - card->rxbd_rdptr, wrptr); + card->rxbd_rdptr, wrptr); /* Write the RX ring read pointer in to REG_RXBD_RDPTR */ if (mwifiex_write_reg(adapter, REG_RXBD_RDPTR, card->rxbd_rdptr)) { - dev_err(adapter->dev, "RECV DATA: failed to " - "write REG_RXBD_RDPTR\n"); + dev_err(adapter->dev, + "RECV DATA: failed to write REG_RXBD_RDPTR\n"); ret = -1; goto done; } /* Read the RX ring Write pointer set by firmware */ if (mwifiex_read_reg(adapter, REG_RXBD_WRPTR, &wrptr)) { - dev_err(adapter->dev, "RECV DATA: failed to read " - "REG_TXBD_RDPTR\n"); + dev_err(adapter->dev, + "RECV DATA: failed to read REG_TXBD_RDPTR\n"); ret = -1; goto done; } - dev_dbg(adapter->dev, "info: RECV DATA: Received packet from " - "firmware successfully\n"); + dev_dbg(adapter->dev, + "info: RECV DATA: Rcvd packet from fw successfully\n"); mwifiex_handle_rx_packet(adapter, skb_tmp); } @@ -919,17 +920,19 @@ mwifiex_pcie_send_boot_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb) phys_addr_t *buf_pa = MWIFIEX_SKB_PACB(skb); if (!(skb->data && skb->len && *buf_pa)) { - dev_err(adapter->dev, "Invalid parameter in %s <%p, %#x:%x, " - "%x>\n", __func__, skb->data, skb->len, - (u32)*buf_pa, (u32)((u64)*buf_pa >> 32)); + dev_err(adapter->dev, + "Invalid parameter in %s <%p, %#x:%x, %x>\n", + __func__, skb->data, skb->len, + (u32)*buf_pa, (u32)((u64)*buf_pa >> 32)); return -1; } /* Write the lower 32bits of the physical address to scratch * register 0 */ if (mwifiex_write_reg(adapter, PCIE_SCRATCH_0_REG, (u32)*buf_pa)) { - dev_err(adapter->dev, "%s: failed to write download command " - "to boot code.\n", __func__); + dev_err(adapter->dev, + "%s: failed to write download command to boot code.\n", + __func__); return -1; } @@ -937,23 +940,25 @@ mwifiex_pcie_send_boot_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb) * register 1 */ if (mwifiex_write_reg(adapter, PCIE_SCRATCH_1_REG, (u32)((u64)*buf_pa >> 32))) { - dev_err(adapter->dev, "%s: failed to write download command " - "to boot code.\n", __func__); + dev_err(adapter->dev, + "%s: failed to write download command to boot code.\n", + __func__); return -1; } /* Write the command length to scratch register 2 */ if (mwifiex_write_reg(adapter, PCIE_SCRATCH_2_REG, skb->len)) { - dev_err(adapter->dev, "%s: failed to write command length to " - "scratch register 2\n", __func__); + dev_err(adapter->dev, + "%s: failed to write command len to scratch reg 2\n", + __func__); return -1; } /* Ring the door bell */ if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT, CPU_INTR_DOOR_BELL)) { - dev_err(adapter->dev, "%s: failed to assert door-bell " - "interrupt.\n", __func__); + dev_err(adapter->dev, + "%s: failed to assert door-bell intr\n", __func__); return -1; } @@ -973,14 +978,14 @@ mwifiex_pcie_send_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb) if (!(skb->data && skb->len)) { dev_err(adapter->dev, "Invalid parameter in %s <%p, %#x>\n", - __func__, skb->data, skb->len); + __func__, skb->data, skb->len); return -1; } /* Make sure a command response buffer is available */ if (!card->cmdrsp_buf) { - dev_err(adapter->dev, "No response buffer available, send " - "command failed\n"); + dev_err(adapter->dev, + "No response buffer available, send command failed\n"); return -EBUSY; } @@ -1011,17 +1016,18 @@ mwifiex_pcie_send_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb) /* Write the lower 32bits of the cmdrsp buffer physical address */ if (mwifiex_write_reg(adapter, REG_CMDRSP_ADDR_LO, - (u32)*cmdrsp_buf_pa)) { - dev_err(adapter->dev, "Failed to write download command to boot code.\n"); + (u32)*cmdrsp_buf_pa)) { + dev_err(adapter->dev, + "Failed to write download cmd to boot code.\n"); ret = -1; goto done; } /* Write the upper 32bits of the cmdrsp buffer physical address */ if (mwifiex_write_reg(adapter, REG_CMDRSP_ADDR_HI, - (u32)((u64)*cmdrsp_buf_pa >> 32))) { - dev_err(adapter->dev, "Failed to write download command" - " to boot code.\n"); + (u32)((u64)*cmdrsp_buf_pa >> 32))) { + dev_err(adapter->dev, + "Failed to write download cmd to boot code.\n"); ret = -1; goto done; } @@ -1029,27 +1035,25 @@ mwifiex_pcie_send_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb) cmd_buf_pa = MWIFIEX_SKB_PACB(card->cmd_buf); /* Write the lower 32bits of the physical address to REG_CMD_ADDR_LO */ - if (mwifiex_write_reg(adapter, REG_CMD_ADDR_LO, - (u32)*cmd_buf_pa)) { - dev_err(adapter->dev, "Failed to write download command " - "to boot code.\n"); + if (mwifiex_write_reg(adapter, REG_CMD_ADDR_LO, (u32)*cmd_buf_pa)) { + dev_err(adapter->dev, + "Failed to write download cmd to boot code.\n"); ret = -1; goto done; } /* Write the upper 32bits of the physical address to REG_CMD_ADDR_HI */ if (mwifiex_write_reg(adapter, REG_CMD_ADDR_HI, - (u32)((u64)*cmd_buf_pa >> 32))) { - dev_err(adapter->dev, "Failed to write download command " - "to boot code.\n"); + (u32)((u64)*cmd_buf_pa >> 32))) { + dev_err(adapter->dev, + "Failed to write download cmd to boot code.\n"); ret = -1; goto done; } /* Write the command length to REG_CMD_SIZE */ - if (mwifiex_write_reg(adapter, REG_CMD_SIZE, - card->cmd_buf->len)) { - dev_err(adapter->dev, "Failed to write command length to " - "REG_CMD_SIZE\n"); + if (mwifiex_write_reg(adapter, REG_CMD_SIZE, card->cmd_buf->len)) { + dev_err(adapter->dev, + "Failed to write cmd len to REG_CMD_SIZE\n"); ret = -1; goto done; } @@ -1057,8 +1061,8 @@ mwifiex_pcie_send_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb) /* Ring the door bell */ if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT, CPU_INTR_DOOR_BELL)) { - dev_err(adapter->dev, "Failed to assert door-bell " - "interrupt.\n"); + dev_err(adapter->dev, + "Failed to assert door-bell intr\n"); ret = -1; goto done; } @@ -1076,30 +1080,29 @@ done: static int mwifiex_pcie_process_cmd_complete(struct mwifiex_adapter *adapter) { struct pcie_service_card *card = adapter->card; + struct sk_buff *skb = card->cmdrsp_buf; int count = 0; dev_dbg(adapter->dev, "info: Rx CMD Response\n"); if (!adapter->curr_cmd) { - skb_pull(card->cmdrsp_buf, INTF_HEADER_LEN); + skb_pull(skb, INTF_HEADER_LEN); if (adapter->ps_state == PS_STATE_SLEEP_CFM) { - mwifiex_process_sleep_confirm_resp(adapter, - card->cmdrsp_buf->data, - card->cmdrsp_buf->len); + mwifiex_process_sleep_confirm_resp(adapter, skb->data, + skb->len); while (mwifiex_pcie_ok_to_access_hw(adapter) && (count++ < 10)) usleep_range(50, 60); } else { - dev_err(adapter->dev, "There is no command but " - "got cmdrsp\n"); + dev_err(adapter->dev, + "There is no command but got cmdrsp\n"); } - memcpy(adapter->upld_buf, card->cmdrsp_buf->data, - min_t(u32, MWIFIEX_SIZE_OF_CMD_BUFFER, - card->cmdrsp_buf->len)); - skb_push(card->cmdrsp_buf, INTF_HEADER_LEN); + memcpy(adapter->upld_buf, skb->data, + min_t(u32, MWIFIEX_SIZE_OF_CMD_BUFFER, skb->len)); + skb_push(skb, INTF_HEADER_LEN); } else if (mwifiex_pcie_ok_to_access_hw(adapter)) { - skb_pull(card->cmdrsp_buf, INTF_HEADER_LEN); - adapter->curr_cmd->resp_skb = card->cmdrsp_buf; + skb_pull(skb, INTF_HEADER_LEN); + adapter->curr_cmd->resp_skb = skb; adapter->cmd_resp_received = true; /* Take the pointer and set it to CMD node and will return in the response complete callback */ @@ -1109,15 +1112,15 @@ static int mwifiex_pcie_process_cmd_complete(struct mwifiex_adapter *adapter) will prevent firmware from writing to the same response buffer again. */ if (mwifiex_write_reg(adapter, REG_CMDRSP_ADDR_LO, 0)) { - dev_err(adapter->dev, "cmd_done: failed to clear " - "cmd_rsp address.\n"); + dev_err(adapter->dev, + "cmd_done: failed to clear cmd_rsp_addr_lo\n"); return -1; } /* Write the upper 32bits of the cmdrsp buffer physical address */ if (mwifiex_write_reg(adapter, REG_CMDRSP_ADDR_HI, 0)) { - dev_err(adapter->dev, "cmd_done: failed to clear " - "cmd_rsp address.\n"); + dev_err(adapter->dev, + "cmd_done: failed to clear cmd_rsp_addr_hi\n"); return -1; } } @@ -1151,8 +1154,8 @@ static int mwifiex_pcie_process_event_ready(struct mwifiex_adapter *adapter) u32 wrptr, event; if (adapter->event_received) { - dev_dbg(adapter->dev, "info: Event being processed, "\ - "do not process this interrupt just yet\n"); + dev_dbg(adapter->dev, "info: Event being processed, " + "do not process this interrupt just yet\n"); return 0; } @@ -1163,14 +1166,15 @@ static int mwifiex_pcie_process_event_ready(struct mwifiex_adapter *adapter) /* Read the event ring write pointer set by firmware */ if (mwifiex_read_reg(adapter, REG_EVTBD_WRPTR, &wrptr)) { - dev_err(adapter->dev, "EventReady: failed to read REG_EVTBD_WRPTR\n"); + dev_err(adapter->dev, + "EventReady: failed to read REG_EVTBD_WRPTR\n"); return -1; } dev_dbg(adapter->dev, "info: EventReady: Initial ", - card->evtbd_rdptr, wrptr); - if (((wrptr & MWIFIEX_EVTBD_MASK) != - (card->evtbd_rdptr & MWIFIEX_EVTBD_MASK)) || + card->evtbd_rdptr, wrptr); + if (((wrptr & MWIFIEX_EVTBD_MASK) != (card->evtbd_rdptr + & MWIFIEX_EVTBD_MASK)) || ((wrptr & MWIFIEX_BD_FLAG_ROLLOVER_IND) == (card->evtbd_rdptr & MWIFIEX_BD_FLAG_ROLLOVER_IND))) { struct sk_buff *skb_cmd; @@ -1230,13 +1234,14 @@ static int mwifiex_pcie_event_complete(struct mwifiex_adapter *adapter, if (rdptr >= MWIFIEX_MAX_EVT_BD) { dev_err(adapter->dev, "event_complete: Invalid rdptr 0x%x\n", - rdptr); + rdptr); return -EINVAL; } /* Read the event ring write pointer set by firmware */ if (mwifiex_read_reg(adapter, REG_EVTBD_WRPTR, &wrptr)) { - dev_err(adapter->dev, "event_complete: failed to read REG_EVTBD_WRPTR\n"); + dev_err(adapter->dev, + "event_complete: failed to read REG_EVTBD_WRPTR\n"); return -1; } @@ -1249,9 +1254,9 @@ static int mwifiex_pcie_event_complete(struct mwifiex_adapter *adapter, card->evtbd_ring[rdptr]->flags = 0; skb = NULL; } else { - dev_dbg(adapter->dev, "info: ERROR: Buffer is still valid at " - "index %d, <%p, %p>\n", rdptr, - card->evt_buf_list[rdptr], skb); + dev_dbg(adapter->dev, + "info: ERROR: buf still valid at index %d, <%p, %p>\n", + rdptr, card->evt_buf_list[rdptr], skb); } if ((++card->evtbd_rdptr & MWIFIEX_EVTBD_MASK) == MWIFIEX_MAX_EVT_BD) { @@ -1261,11 +1266,12 @@ static int mwifiex_pcie_event_complete(struct mwifiex_adapter *adapter, } dev_dbg(adapter->dev, "info: Updated ", - card->evtbd_rdptr, wrptr); + card->evtbd_rdptr, wrptr); /* Write the event ring read pointer in to REG_EVTBD_RDPTR */ if (mwifiex_write_reg(adapter, REG_EVTBD_RDPTR, card->evtbd_rdptr)) { - dev_err(adapter->dev, "event_complete: failed to read REG_EVTBD_RDPTR\n"); + dev_err(adapter->dev, + "event_complete: failed to read REG_EVTBD_RDPTR\n"); return -1; } @@ -1299,17 +1305,17 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, } if (!firmware || !firmware_len) { - dev_err(adapter->dev, "No firmware image found! " - "Terminating download\n"); + dev_err(adapter->dev, + "No firmware image found! Terminating download\n"); return -1; } dev_dbg(adapter->dev, "info: Downloading FW image (%d bytes)\n", - firmware_len); + firmware_len); if (mwifiex_pcie_disable_host_int(adapter)) { - dev_err(adapter->dev, "%s: Disabling interrupts" - " failed.\n", __func__); + dev_err(adapter->dev, + "%s: Disabling interrupts failed.\n", __func__); return -1; } @@ -1332,7 +1338,8 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, ret = mwifiex_read_reg(adapter, PCIE_SCRATCH_2_REG, &len); if (ret) { - dev_warn(adapter->dev, "Failed reading length from boot code\n"); + dev_warn(adapter->dev, + "Failed reading len from boot code\n"); goto done; } if (len) @@ -1344,7 +1351,7 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, break; } else if (len > MWIFIEX_UPLD_SIZE) { pr_err("FW download failure @ %d, invalid length %d\n", - offset, len); + offset, len); ret = -1; goto done; } @@ -1360,8 +1367,8 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, goto done; } dev_err(adapter->dev, "FW CRC error indicated by the " - "helper: len = 0x%04X, txlen = " - "%d\n", len, txlen); + "helper: len = 0x%04X, txlen = %d\n", + len, txlen); len &= ~BIT(0); /* Setting this to 0 to resend from same offset */ txlen = 0; @@ -1374,9 +1381,9 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, dev_dbg(adapter->dev, "."); - tx_blocks = - (txlen + MWIFIEX_PCIE_BLOCK_SIZE_FW_DNLD - 1) / - MWIFIEX_PCIE_BLOCK_SIZE_FW_DNLD; + tx_blocks = (txlen + + MWIFIEX_PCIE_BLOCK_SIZE_FW_DNLD - 1) / + MWIFIEX_PCIE_BLOCK_SIZE_FW_DNLD; /* Copy payload to buffer */ memmove(skb->data, &firmware[offset], txlen); @@ -1387,7 +1394,8 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, /* Send the boot command to device */ if (mwifiex_pcie_send_boot_cmd(adapter, skb)) { - dev_err(adapter->dev, "Failed to send firmware download command\n"); + dev_err(adapter->dev, + "Failed to send firmware download command\n"); ret = -1; goto done; } @@ -1396,8 +1404,8 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, if (mwifiex_read_reg(adapter, PCIE_CPU_INT_STATUS, &ireg_intr)) { dev_err(adapter->dev, "%s: Failed to read " - "interrupt status during " - "fw dnld.\n", __func__); + "interrupt status during fw dnld.\n", + __func__); ret = -1; goto done; } @@ -1407,7 +1415,7 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, } while (true); dev_dbg(adapter->dev, "info:\nFW download over, size %d bytes\n", - offset); + offset); ret = 0; @@ -1430,14 +1438,15 @@ mwifiex_check_fw_status(struct mwifiex_adapter *adapter, u32 poll_num) /* Mask spurios interrupts */ if (mwifiex_write_reg(adapter, PCIE_HOST_INT_STATUS_MASK, - HOST_INTR_MASK)) { + HOST_INTR_MASK)) { dev_warn(adapter->dev, "Write register failed\n"); return -1; } dev_dbg(adapter->dev, "Setting driver ready signature\n"); if (mwifiex_write_reg(adapter, REG_DRV_READY, FIRMWARE_READY_PCIE)) { - dev_err(adapter->dev, "Failed to write driver ready signature\n"); + dev_err(adapter->dev, + "Failed to write driver ready signature\n"); return -1; } @@ -1468,8 +1477,9 @@ mwifiex_check_fw_status(struct mwifiex_adapter *adapter, u32 poll_num) adapter->winner = 1; ret = -1; } else { - dev_err(adapter->dev, "PCI-E is not the winner <%#x, %d>, exit download\n", - ret, adapter->winner); + dev_err(adapter->dev, + "PCI-E is not the winner <%#x,%d>, exit dnld\n", + ret, adapter->winner); ret = 0; } } @@ -1512,10 +1522,11 @@ static void mwifiex_interrupt_status(struct mwifiex_adapter *adapter) (adapter->ps_state == PS_STATE_SLEEP)) { mwifiex_pcie_enable_host_int(adapter); if (mwifiex_write_reg(adapter, - PCIE_CPU_INT_EVENT, - CPU_INTR_SLEEP_CFM_DONE)) { - dev_warn(adapter->dev, "Write register" - " failed\n"); + PCIE_CPU_INT_EVENT, + CPU_INTR_SLEEP_CFM_DONE) + ) { + dev_warn(adapter->dev, + "Write register failed\n"); return; } @@ -1551,7 +1562,7 @@ static irqreturn_t mwifiex_pcie_interrupt(int irq, void *context) card = (struct pcie_service_card *) pci_get_drvdata(pdev); if (!card || !card->adapter) { pr_debug("info: %s: card=%p adapter=%p\n", __func__, card, - card ? card->adapter : NULL); + card ? card->adapter : NULL); goto exit; } adapter = card->adapter; @@ -1594,7 +1605,7 @@ static int mwifiex_process_int_status(struct mwifiex_adapter *adapter) if (adapter->int_status & HOST_INTR_DNLD_DONE) { adapter->int_status &= ~HOST_INTR_DNLD_DONE; if (adapter->data_sent) { - dev_dbg(adapter->dev, "info: DATA sent Interrupt\n"); + dev_dbg(adapter->dev, "info: DATA sent intr\n"); adapter->data_sent = false; } } @@ -1616,7 +1627,8 @@ static int mwifiex_process_int_status(struct mwifiex_adapter *adapter) if (adapter->int_status & HOST_INTR_CMD_DONE) { adapter->int_status &= ~HOST_INTR_CMD_DONE; if (adapter->cmd_sent) { - dev_dbg(adapter->dev, "info: CMD sent Interrupt\n"); + dev_dbg(adapter->dev, + "info: CMD sent Interrupt\n"); adapter->cmd_sent = false; } /* Handle command response */ @@ -1628,15 +1640,17 @@ static int mwifiex_process_int_status(struct mwifiex_adapter *adapter) if (mwifiex_pcie_ok_to_access_hw(adapter)) { if (mwifiex_read_reg(adapter, PCIE_HOST_INT_STATUS, &pcie_ireg)) { - dev_warn(adapter->dev, "Read register failed\n"); + dev_warn(adapter->dev, + "Read register failed\n"); return -1; } if ((pcie_ireg != 0xFFFFFFFF) && (pcie_ireg)) { if (mwifiex_write_reg(adapter, - PCIE_HOST_INT_STATUS, ~pcie_ireg)) { - dev_warn(adapter->dev, "Write register" - " failed\n"); + PCIE_HOST_INT_STATUS, + ~pcie_ireg)) { + dev_warn(adapter->dev, + "Write register failed\n"); return -1; } adapter->int_status |= pcie_ireg; @@ -1646,7 +1660,7 @@ static int mwifiex_process_int_status(struct mwifiex_adapter *adapter) } } dev_dbg(adapter->dev, "info: cmd_sent=%d data_sent=%d\n", - adapter->cmd_sent, adapter->data_sent); + adapter->cmd_sent, adapter->data_sent); mwifiex_pcie_enable_host_int(adapter); return 0; @@ -1737,8 +1751,9 @@ static int mwifiex_pcie_init(struct mwifiex_adapter *adapter) goto err_iomap2; } - dev_dbg(adapter->dev, "PCI memory map Virt0: %p PCI memory map Virt2: " - "%p\n", card->pci_mmap, card->pci_mmap1); + dev_dbg(adapter->dev, + "PCI memory map Virt0: %p PCI memory map Virt2: %p\n", + card->pci_mmap, card->pci_mmap1); card->cmdrsp_buf = NULL; ret = mwifiex_pcie_create_txbd_ring(adapter); @@ -1808,7 +1823,8 @@ static void mwifiex_pcie_cleanup(struct mwifiex_adapter *adapter) dev_dbg(adapter->dev, "Clearing driver ready signature\n"); if (user_rmmod) { if (mwifiex_write_reg(adapter, REG_DRV_READY, 0x00000000)) - dev_err(adapter->dev, "Failed to write driver not-ready signature\n"); + dev_err(adapter->dev, + "Failed to write driver not-ready signature\n"); } if (pdev) { -- cgit From cff23cec822cd6bd0878c2a6afe6140f04c17dcf Mon Sep 17 00:00:00 2001 From: Yogesh Ashok Powar Date: Tue, 13 Mar 2012 19:22:38 -0700 Subject: mwifiex: fix checkpatch --strict warnings/errors Part 5 For file scan.c Signed-off-by: Yogesh Ashok Powar Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/scan.c | 343 ++++++++++++++++++------------------ 1 file changed, 170 insertions(+), 173 deletions(-) diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c index 0a0c2890adfa..aff9cd763f2b 100644 --- a/drivers/net/wireless/mwifiex/scan.c +++ b/drivers/net/wireless/mwifiex/scan.c @@ -125,7 +125,7 @@ mwifiex_is_rsn_oui_present(struct mwifiex_bssdescriptor *bss_desc, u32 cipher) ieee_hdr.element_id == WLAN_EID_RSN))) { iebody = (struct ie_body *) (((u8 *) bss_desc->bcn_rsn_ie->data) + - RSN_GTK_OUI_OFFSET); + RSN_GTK_OUI_OFFSET); oui = &mwifiex_rsn_oui[cipher][0]; ret = mwifiex_search_oui_in_ie(iebody, oui); if (ret) @@ -148,8 +148,9 @@ mwifiex_is_wpa_oui_present(struct mwifiex_bssdescriptor *bss_desc, u32 cipher) struct ie_body *iebody; u8 ret = MWIFIEX_OUI_NOT_PRESENT; - if (((bss_desc->bcn_wpa_ie) && ((*(bss_desc->bcn_wpa_ie)). - vend_hdr.element_id == WLAN_EID_WPA))) { + if (((bss_desc->bcn_wpa_ie) && + ((*(bss_desc->bcn_wpa_ie)).vend_hdr.element_id == + WLAN_EID_WPA))) { iebody = (struct ie_body *) bss_desc->bcn_wpa_ie->data; oui = &mwifiex_wpa_oui[cipher][0]; ret = mwifiex_search_oui_in_ie(iebody, oui); @@ -175,8 +176,8 @@ mwifiex_ssid_cmp(struct cfg80211_ssid *ssid1, struct cfg80211_ssid *ssid2) * compatible with it. */ static bool -mwifiex_is_network_compatible_for_wapi(struct mwifiex_private *priv, - struct mwifiex_bssdescriptor *bss_desc) +mwifiex_is_bss_wapi(struct mwifiex_private *priv, + struct mwifiex_bssdescriptor *bss_desc) { if (priv->sec_info.wapi_enabled && (bss_desc->bcn_wapi_ie && @@ -192,18 +193,17 @@ mwifiex_is_network_compatible_for_wapi(struct mwifiex_private *priv, * scanned network is compatible with it. */ static bool -mwifiex_is_network_compatible_for_no_sec(struct mwifiex_private *priv, - struct mwifiex_bssdescriptor *bss_desc) +mwifiex_is_bss_no_sec(struct mwifiex_private *priv, + struct mwifiex_bssdescriptor *bss_desc) { if (!priv->sec_info.wep_enabled && !priv->sec_info.wpa_enabled && !priv->sec_info.wpa2_enabled && ((!bss_desc->bcn_wpa_ie) || ((*(bss_desc->bcn_wpa_ie)).vend_hdr.element_id != - WLAN_EID_WPA)) - && ((!bss_desc->bcn_rsn_ie) || + WLAN_EID_WPA)) && + ((!bss_desc->bcn_rsn_ie) || ((*(bss_desc->bcn_rsn_ie)).ieee_hdr.element_id != - WLAN_EID_RSN)) - && !priv->sec_info.encryption_mode - && !bss_desc->privacy) { + WLAN_EID_RSN)) && + !priv->sec_info.encryption_mode && !bss_desc->privacy) { return true; } return false; @@ -214,8 +214,8 @@ mwifiex_is_network_compatible_for_no_sec(struct mwifiex_private *priv, * is compatible with it. */ static bool -mwifiex_is_network_compatible_for_static_wep(struct mwifiex_private *priv, - struct mwifiex_bssdescriptor *bss_desc) +mwifiex_is_bss_static_wep(struct mwifiex_private *priv, + struct mwifiex_bssdescriptor *bss_desc) { if (priv->sec_info.wep_enabled && !priv->sec_info.wpa_enabled && !priv->sec_info.wpa2_enabled && bss_desc->privacy) { @@ -229,8 +229,8 @@ mwifiex_is_network_compatible_for_static_wep(struct mwifiex_private *priv, * compatible with it. */ static bool -mwifiex_is_network_compatible_for_wpa(struct mwifiex_private *priv, - struct mwifiex_bssdescriptor *bss_desc) +mwifiex_is_bss_wpa(struct mwifiex_private *priv, + struct mwifiex_bssdescriptor *bss_desc) { if (!priv->sec_info.wep_enabled && priv->sec_info.wpa_enabled && !priv->sec_info.wpa2_enabled && ((bss_desc->bcn_wpa_ie) && @@ -264,17 +264,18 @@ mwifiex_is_network_compatible_for_wpa(struct mwifiex_private *priv, * compatible with it. */ static bool -mwifiex_is_network_compatible_for_wpa2(struct mwifiex_private *priv, - struct mwifiex_bssdescriptor *bss_desc) +mwifiex_is_bss_wpa2(struct mwifiex_private *priv, + struct mwifiex_bssdescriptor *bss_desc) { - if (!priv->sec_info.wep_enabled && !priv->sec_info.wpa_enabled && - priv->sec_info.wpa2_enabled && ((bss_desc->bcn_rsn_ie) && - ((*(bss_desc->bcn_rsn_ie)).ieee_hdr.element_id == WLAN_EID_RSN)) - /* - * Privacy bit may NOT be set in some APs like - * LinkSys WRT54G && bss_desc->privacy - */ - ) { + if (!priv->sec_info.wep_enabled && + !priv->sec_info.wpa_enabled && + priv->sec_info.wpa2_enabled && + ((bss_desc->bcn_rsn_ie) && + ((*(bss_desc->bcn_rsn_ie)).ieee_hdr.element_id == WLAN_EID_RSN))) { + /* + * Privacy bit may NOT be set in some APs like + * LinkSys WRT54G && bss_desc->privacy + */ dev_dbg(priv->adapter->dev, "info: %s: WPA2: " " wpa_ie=%#x wpa2_ie=%#x WEP=%s WPA=%s WPA2=%s " "EncMode=%#x privacy=%#x\n", __func__, @@ -299,16 +300,16 @@ mwifiex_is_network_compatible_for_wpa2(struct mwifiex_private *priv, * compatible with it. */ static bool -mwifiex_is_network_compatible_for_adhoc_aes(struct mwifiex_private *priv, - struct mwifiex_bssdescriptor *bss_desc) +mwifiex_is_bss_adhoc_aes(struct mwifiex_private *priv, + struct mwifiex_bssdescriptor *bss_desc) { if (!priv->sec_info.wep_enabled && !priv->sec_info.wpa_enabled && - !priv->sec_info.wpa2_enabled && ((!bss_desc->bcn_wpa_ie) || - ((*(bss_desc->bcn_wpa_ie)).vend_hdr.element_id != WLAN_EID_WPA)) - && ((!bss_desc->bcn_rsn_ie) || ((*(bss_desc->bcn_rsn_ie)).ieee_hdr. - element_id != WLAN_EID_RSN)) - && !priv->sec_info.encryption_mode - && bss_desc->privacy) { + !priv->sec_info.wpa2_enabled && + ((!bss_desc->bcn_wpa_ie) || + ((*(bss_desc->bcn_wpa_ie)).vend_hdr.element_id != WLAN_EID_WPA)) && + ((!bss_desc->bcn_rsn_ie) || + ((*(bss_desc->bcn_rsn_ie)).ieee_hdr.element_id != WLAN_EID_RSN)) && + !priv->sec_info.encryption_mode && bss_desc->privacy) { return true; } return false; @@ -319,16 +320,16 @@ mwifiex_is_network_compatible_for_adhoc_aes(struct mwifiex_private *priv, * is compatible with it. */ static bool -mwifiex_is_network_compatible_for_dynamic_wep(struct mwifiex_private *priv, - struct mwifiex_bssdescriptor *bss_desc) +mwifiex_is_bss_dynamic_wep(struct mwifiex_private *priv, + struct mwifiex_bssdescriptor *bss_desc) { if (!priv->sec_info.wep_enabled && !priv->sec_info.wpa_enabled && - !priv->sec_info.wpa2_enabled && ((!bss_desc->bcn_wpa_ie) || - ((*(bss_desc->bcn_wpa_ie)).vend_hdr.element_id != WLAN_EID_WPA)) - && ((!bss_desc->bcn_rsn_ie) || ((*(bss_desc->bcn_rsn_ie)).ieee_hdr. - element_id != WLAN_EID_RSN)) - && priv->sec_info.encryption_mode - && bss_desc->privacy) { + !priv->sec_info.wpa2_enabled && + ((!bss_desc->bcn_wpa_ie) || + ((*(bss_desc->bcn_wpa_ie)).vend_hdr.element_id != WLAN_EID_WPA)) && + ((!bss_desc->bcn_rsn_ie) || + ((*(bss_desc->bcn_rsn_ie)).ieee_hdr.element_id != WLAN_EID_RSN)) && + priv->sec_info.encryption_mode && bss_desc->privacy) { dev_dbg(priv->adapter->dev, "info: %s: dynamic " "WEP: wpa_ie=%#x wpa2_ie=%#x " "EncMode=%#x privacy=%#x\n", @@ -373,8 +374,9 @@ mwifiex_is_network_compatible(struct mwifiex_private *priv, bss_desc->disable_11n = false; /* Don't check for compatibility if roaming */ - if (priv->media_connected && (priv->bss_mode == NL80211_IFTYPE_STATION) - && (bss_desc->bss_mode == NL80211_IFTYPE_STATION)) + if (priv->media_connected && + (priv->bss_mode == NL80211_IFTYPE_STATION) && + (bss_desc->bss_mode == NL80211_IFTYPE_STATION)) return 0; if (priv->wps.session_enable) { @@ -383,32 +385,30 @@ mwifiex_is_network_compatible(struct mwifiex_private *priv, return 0; } - if (mwifiex_is_network_compatible_for_wapi(priv, bss_desc)) { + if (mwifiex_is_bss_wapi(priv, bss_desc)) { dev_dbg(adapter->dev, "info: return success for WAPI AP\n"); return 0; } if (bss_desc->bss_mode == mode) { - if (mwifiex_is_network_compatible_for_no_sec(priv, bss_desc)) { + if (mwifiex_is_bss_no_sec(priv, bss_desc)) { /* No security */ return 0; - } else if (mwifiex_is_network_compatible_for_static_wep(priv, - bss_desc)) { + } else if (mwifiex_is_bss_static_wep(priv, bss_desc)) { /* Static WEP enabled */ dev_dbg(adapter->dev, "info: Disable 11n in WEP mode.\n"); bss_desc->disable_11n = true; return 0; - } else if (mwifiex_is_network_compatible_for_wpa(priv, - bss_desc)) { + } else if (mwifiex_is_bss_wpa(priv, bss_desc)) { /* WPA enabled */ - if (((priv->adapter->config_bands & BAND_GN - || priv->adapter->config_bands & BAND_AN) - && bss_desc->bcn_ht_cap) - && !mwifiex_is_wpa_oui_present(bss_desc, - CIPHER_SUITE_CCMP)) { - - if (mwifiex_is_wpa_oui_present(bss_desc, - CIPHER_SUITE_TKIP)) { + if (((priv->adapter->config_bands & BAND_GN || + priv->adapter->config_bands & BAND_AN) && + bss_desc->bcn_ht_cap) && + !mwifiex_is_wpa_oui_present(bss_desc, + CIPHER_SUITE_CCMP)) { + + if (mwifiex_is_wpa_oui_present + (bss_desc, CIPHER_SUITE_TKIP)) { dev_dbg(adapter->dev, "info: Disable 11n if AES " "is not supported by AP\n"); @@ -418,17 +418,16 @@ mwifiex_is_network_compatible(struct mwifiex_private *priv, } } return 0; - } else if (mwifiex_is_network_compatible_for_wpa2(priv, - bss_desc)) { + } else if (mwifiex_is_bss_wpa2(priv, bss_desc)) { /* WPA2 enabled */ - if (((priv->adapter->config_bands & BAND_GN - || priv->adapter->config_bands & BAND_AN) - && bss_desc->bcn_ht_cap) - && !mwifiex_is_rsn_oui_present(bss_desc, - CIPHER_SUITE_CCMP)) { - - if (mwifiex_is_rsn_oui_present(bss_desc, - CIPHER_SUITE_TKIP)) { + if (((priv->adapter->config_bands & BAND_GN || + priv->adapter->config_bands & BAND_AN) && + bss_desc->bcn_ht_cap) && + !mwifiex_is_rsn_oui_present(bss_desc, + CIPHER_SUITE_CCMP)) { + + if (mwifiex_is_rsn_oui_present + (bss_desc, CIPHER_SUITE_TKIP)) { dev_dbg(adapter->dev, "info: Disable 11n if AES " "is not supported by AP\n"); @@ -438,31 +437,26 @@ mwifiex_is_network_compatible(struct mwifiex_private *priv, } } return 0; - } else if (mwifiex_is_network_compatible_for_adhoc_aes(priv, - bss_desc)) { + } else if (mwifiex_is_bss_adhoc_aes(priv, bss_desc)) { /* Ad-hoc AES enabled */ return 0; - } else if (mwifiex_is_network_compatible_for_dynamic_wep(priv, - bss_desc)) { + } else if (mwifiex_is_bss_dynamic_wep(priv, bss_desc)) { /* Dynamic WEP enabled */ return 0; } /* Security doesn't match */ - dev_dbg(adapter->dev, "info: %s: failed: " - "wpa_ie=%#x wpa2_ie=%#x WEP=%s WPA=%s WPA2=%s EncMode" - "=%#x privacy=%#x\n", - __func__, - (bss_desc->bcn_wpa_ie) ? - (*(bss_desc->bcn_wpa_ie)).vend_hdr. - element_id : 0, - (bss_desc->bcn_rsn_ie) ? - (*(bss_desc->bcn_rsn_ie)).ieee_hdr. - element_id : 0, - (priv->sec_info.wep_enabled) ? "e" : "d", - (priv->sec_info.wpa_enabled) ? "e" : "d", - (priv->sec_info.wpa2_enabled) ? "e" : "d", - priv->sec_info.encryption_mode, bss_desc->privacy); + dev_dbg(adapter->dev, + "info: %s: failed: wpa_ie=%#x wpa2_ie=%#x WEP=%s " + "WPA=%s WPA2=%s EncMode=%#x privacy=%#x\n", __func__, + (bss_desc->bcn_wpa_ie) ? + (*(bss_desc->bcn_wpa_ie)).vend_hdr.element_id : 0, + (bss_desc->bcn_rsn_ie) ? + (*(bss_desc->bcn_rsn_ie)).ieee_hdr.element_id : 0, + (priv->sec_info.wep_enabled) ? "e" : "d", + (priv->sec_info.wpa_enabled) ? "e" : "d", + (priv->sec_info.wpa2_enabled) ? "e" : "d", + priv->sec_info.encryption_mode, bss_desc->privacy); return -1; } @@ -479,11 +473,11 @@ mwifiex_is_network_compatible(struct mwifiex_private *priv, */ static void mwifiex_scan_create_channel_list(struct mwifiex_private *priv, - const struct mwifiex_user_scan_cfg - *user_scan_in, - struct mwifiex_chan_scan_param_set - *scan_chan_list, - u8 filtered_scan) + const struct mwifiex_user_scan_cfg + *user_scan_in, + struct mwifiex_chan_scan_param_set + *scan_chan_list, + u8 filtered_scan) { enum ieee80211_band band; struct ieee80211_supported_band *sband; @@ -505,7 +499,7 @@ mwifiex_scan_create_channel_list(struct mwifiex_private *priv, scan_chan_list[chan_idx].radio_type = band; if (user_scan_in && - user_scan_in->chan_list[0].scan_time) + user_scan_in->chan_list[0].scan_time) scan_chan_list[chan_idx].max_scan_time = cpu_to_le16((u16) user_scan_in-> chan_list[0].scan_time); @@ -594,19 +588,19 @@ mwifiex_scan_channel_list(struct mwifiex_private *priv, * - done_early is set (controlling individual scanning of * 1,6,11) */ - while (tlv_idx < max_chan_per_scan - && tmp_chan_list->chan_number && !done_early) { + while (tlv_idx < max_chan_per_scan && + tmp_chan_list->chan_number && !done_early) { dev_dbg(priv->adapter->dev, "info: Scan: Chan(%3d), Radio(%d)," " Mode(%d, %d), Dur(%d)\n", - tmp_chan_list->chan_number, - tmp_chan_list->radio_type, - tmp_chan_list->chan_scan_mode_bitmap - & MWIFIEX_PASSIVE_SCAN, - (tmp_chan_list->chan_scan_mode_bitmap - & MWIFIEX_DISABLE_CHAN_FILT) >> 1, - le16_to_cpu(tmp_chan_list->max_scan_time)); + tmp_chan_list->chan_number, + tmp_chan_list->radio_type, + tmp_chan_list->chan_scan_mode_bitmap + & MWIFIEX_PASSIVE_SCAN, + (tmp_chan_list->chan_scan_mode_bitmap + & MWIFIEX_DISABLE_CHAN_FILT) >> 1, + le16_to_cpu(tmp_chan_list->max_scan_time)); /* Copy the current channel TLV to the command being prepared */ @@ -648,9 +642,10 @@ mwifiex_scan_channel_list(struct mwifiex_private *priv, /* Stop the loop if the *current* channel is in the 1,6,11 set and we are not filtering on a BSSID or SSID. */ - if (!filtered_scan && (tmp_chan_list->chan_number == 1 - || tmp_chan_list->chan_number == 6 - || tmp_chan_list->chan_number == 11)) + if (!filtered_scan && + (tmp_chan_list->chan_number == 1 || + tmp_chan_list->chan_number == 6 || + tmp_chan_list->chan_number == 11)) done_early = true; /* Increment the tmp pointer to the next channel to @@ -660,9 +655,10 @@ mwifiex_scan_channel_list(struct mwifiex_private *priv, /* Stop the loop if the *next* channel is in the 1,6,11 set. This will cause it to be the only channel scanned on the next interation */ - if (!filtered_scan && (tmp_chan_list->chan_number == 1 - || tmp_chan_list->chan_number == 6 - || tmp_chan_list->chan_number == 11)) + if (!filtered_scan && + (tmp_chan_list->chan_number == 1 || + tmp_chan_list->chan_number == 6 || + tmp_chan_list->chan_number == 11)) done_early = true; } @@ -714,15 +710,13 @@ mwifiex_scan_channel_list(struct mwifiex_private *priv, * If the number of probes is not set, adapter default setting is used. */ static void -mwifiex_scan_setup_scan_config(struct mwifiex_private *priv, - const struct mwifiex_user_scan_cfg *user_scan_in, - struct mwifiex_scan_cmd_config *scan_cfg_out, - struct mwifiex_ie_types_chan_list_param_set - **chan_list_out, - struct mwifiex_chan_scan_param_set - *scan_chan_list, - u8 *max_chan_per_scan, u8 *filtered_scan, - u8 *scan_current_only) +mwifiex_config_scan(struct mwifiex_private *priv, + const struct mwifiex_user_scan_cfg *user_scan_in, + struct mwifiex_scan_cmd_config *scan_cfg_out, + struct mwifiex_ie_types_chan_list_param_set **chan_list_out, + struct mwifiex_chan_scan_param_set *scan_chan_list, + u8 *max_chan_per_scan, u8 *filtered_scan, + u8 *scan_current_only) { struct mwifiex_adapter *adapter = priv->adapter; struct mwifiex_ie_types_num_probes *num_probes_tlv; @@ -840,9 +834,9 @@ mwifiex_scan_setup_scan_config(struct mwifiex_private *priv, * truncate scan results. That is not an issue with an SSID * or BSSID filter applied to the scan results in the firmware. */ - if ((i && ssid_filter) - || memcmp(scan_cfg_out->specific_bssid, &zero_mac, - sizeof(zero_mac))) + if ((i && ssid_filter) || + memcmp(scan_cfg_out->specific_bssid, &zero_mac, + sizeof(zero_mac))) *filtered_scan = true; } else { scan_cfg_out->bss_mode = (u8) adapter->scan_mode; @@ -863,7 +857,7 @@ mwifiex_scan_setup_scan_config(struct mwifiex_private *priv, if (num_probes) { dev_dbg(adapter->dev, "info: scan: num_probes = %d\n", - num_probes); + num_probes); num_probes_tlv = (struct mwifiex_ie_types_num_probes *) tlv_pos; num_probes_tlv->header.type = cpu_to_le16(TLV_TYPE_NUMPROBES); @@ -889,9 +883,9 @@ mwifiex_scan_setup_scan_config(struct mwifiex_private *priv, dev_dbg(adapter->dev, "info: SCAN_CMD: Rates size = %d\n", rates_size); - if (ISSUPP_11NENABLED(priv->adapter->fw_cap_info) - && (priv->adapter->config_bands & BAND_GN - || priv->adapter->config_bands & BAND_AN)) { + if (ISSUPP_11NENABLED(priv->adapter->fw_cap_info) && + (priv->adapter->config_bands & BAND_GN || + priv->adapter->config_bands & BAND_AN)) { ht_cap = (struct mwifiex_ie_types_htcap *) tlv_pos; memset(ht_cap, 0, sizeof(struct mwifiex_ie_types_htcap)); ht_cap->header.type = cpu_to_le16(WLAN_EID_HT_CAPABILITY); @@ -920,8 +914,8 @@ mwifiex_scan_setup_scan_config(struct mwifiex_private *priv, dev_dbg(adapter->dev, "info: Scan: Using supplied channel list\n"); for (chan_idx = 0; - chan_idx < MWIFIEX_USER_SCAN_CHAN_MAX - && user_scan_in->chan_list[chan_idx].chan_number; + chan_idx < MWIFIEX_USER_SCAN_CHAN_MAX && + user_scan_in->chan_list[chan_idx].chan_number; chan_idx++) { channel = user_scan_in->chan_list[chan_idx].chan_number; @@ -961,9 +955,9 @@ mwifiex_scan_setup_scan_config(struct mwifiex_private *priv, } /* Check if we are only scanning the current channel */ - if ((chan_idx == 1) - && (user_scan_in->chan_list[0].chan_number - == priv->curr_bss_params.bss_descriptor.channel)) { + if ((chan_idx == 1) && + (user_scan_in->chan_list[0].chan_number == + priv->curr_bss_params.bss_descriptor.channel)) { *scan_current_only = true; dev_dbg(adapter->dev, "info: Scan: Scanning current channel only\n"); @@ -971,7 +965,7 @@ mwifiex_scan_setup_scan_config(struct mwifiex_private *priv, } else { dev_dbg(adapter->dev, - "info: Scan: Creating full region channel list\n"); + "info: Scan: Creating full region channel list\n"); mwifiex_scan_create_channel_list(priv, user_scan_in, scan_chan_list, *filtered_scan); @@ -1003,7 +997,7 @@ mwifiex_ret_802_11_scan_get_tlv_ptrs(struct mwifiex_adapter *adapter, *tlv_data = NULL; dev_dbg(adapter->dev, "info: SCAN_RESP: tlv_buf_size = %d\n", - tlv_buf_size); + tlv_buf_size); while (tlv_buf_left >= sizeof(struct mwifiex_ie_types_header)) { @@ -1100,8 +1094,9 @@ mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter, bss_entry->ssid.ssid_len = element_len; memcpy(bss_entry->ssid.ssid, (current_ptr + 2), element_len); - dev_dbg(adapter->dev, "info: InterpretIE: ssid: " - "%-32s\n", bss_entry->ssid.ssid); + dev_dbg(adapter->dev, + "info: InterpretIE: ssid: %-32s\n", + bss_entry->ssid.ssid); break; case WLAN_EID_SUPP_RATES: @@ -1189,13 +1184,13 @@ mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter, bss_entry->bcn_wpa_ie = (struct ieee_types_vendor_specific *) current_ptr; - bss_entry->wpa_offset = (u16) (current_ptr - - bss_entry->beacon_buf); + bss_entry->wpa_offset = (u16) + (current_ptr - bss_entry->beacon_buf); } else if (!memcmp(vendor_ie->vend_hdr.oui, wmm_oui, sizeof(wmm_oui))) { if (total_ie_len == - sizeof(struct ieee_types_wmm_parameter) - || total_ie_len == + sizeof(struct ieee_types_wmm_parameter) || + total_ie_len == sizeof(struct ieee_types_wmm_info)) /* * Only accept and copy the WMM IE if @@ -1316,14 +1311,14 @@ static int mwifiex_scan_networks(struct mwifiex_private *priv, } scan_cfg_out = kzalloc(sizeof(union mwifiex_scan_cmd_config_tlv), - GFP_KERNEL); + GFP_KERNEL); if (!scan_cfg_out) { dev_err(adapter->dev, "failed to alloc scan_cfg_out\n"); return -ENOMEM; } buf_size = sizeof(struct mwifiex_chan_scan_param_set) * - MWIFIEX_USER_SCAN_CHAN_MAX; + MWIFIEX_USER_SCAN_CHAN_MAX; scan_chan_list = kzalloc(buf_size, GFP_KERNEL); if (!scan_chan_list) { dev_err(adapter->dev, "failed to alloc scan_chan_list\n"); @@ -1331,10 +1326,9 @@ static int mwifiex_scan_networks(struct mwifiex_private *priv, return -ENOMEM; } - mwifiex_scan_setup_scan_config(priv, user_scan_in, - &scan_cfg_out->config, &chan_list_out, - scan_chan_list, &max_chan_per_scan, - &filtered_scan, &scan_current_chan_only); + mwifiex_config_scan(priv, user_scan_in, &scan_cfg_out->config, + &chan_list_out, scan_chan_list, &max_chan_per_scan, + &filtered_scan, &scan_current_chan_only); ret = mwifiex_scan_channel_list(priv, max_chan_per_scan, filtered_scan, &scan_cfg_out->config, chan_list_out, @@ -1345,10 +1339,10 @@ static int mwifiex_scan_networks(struct mwifiex_private *priv, spin_lock_irqsave(&adapter->scan_pending_q_lock, flags); if (!list_empty(&adapter->scan_pending_q)) { cmd_node = list_first_entry(&adapter->scan_pending_q, - struct cmd_ctrl_node, list); + struct cmd_ctrl_node, list); list_del(&cmd_node->list); spin_unlock_irqrestore(&adapter->scan_pending_q_lock, - flags); + flags); adapter->cmd_queued = cmd_node; mwifiex_insert_cmd_to_pending_q(adapter, cmd_node, true); @@ -1514,7 +1508,7 @@ mwifiex_update_curr_bss_params(struct mwifiex_private *priv, u8 *bssid, /* Make a copy of current BSSID descriptor */ memcpy(&priv->curr_bss_params.bss_descriptor, bss_desc, - sizeof(priv->curr_bss_params.bss_descriptor)); + sizeof(priv->curr_bss_params.bss_descriptor)); mwifiex_save_curr_bcn(priv); spin_unlock_irqrestore(&priv->curr_bcn_buf_lock, flags); @@ -1565,7 +1559,7 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, struct cfg80211_bss *bss; is_bgscan_resp = (le16_to_cpu(resp->command) - == HostCmd_CMD_802_11_BG_SCAN_QUERY); + == HostCmd_CMD_802_11_BG_SCAN_QUERY); if (is_bgscan_resp) scan_rsp = &resp->params.bg_scan_query_resp.scan_resp; else @@ -1574,20 +1568,20 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, if (scan_rsp->number_of_sets > MWIFIEX_MAX_AP) { dev_err(adapter->dev, "SCAN_RESP: too many AP returned (%d)\n", - scan_rsp->number_of_sets); + scan_rsp->number_of_sets); ret = -1; goto done; } bytes_left = le16_to_cpu(scan_rsp->bss_descript_size); dev_dbg(adapter->dev, "info: SCAN_RESP: bss_descript_size %d\n", - bytes_left); + bytes_left); scan_resp_size = le16_to_cpu(resp->size); dev_dbg(adapter->dev, "info: SCAN_RESP: returned %d APs before parsing\n", - scan_rsp->number_of_sets); + scan_rsp->number_of_sets); bss_info = scan_rsp->bss_desc_and_tlv_buffer; @@ -1663,7 +1657,8 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, * and capability information */ if (curr_bcn_bytes < sizeof(struct mwifiex_bcn_param)) { - dev_err(adapter->dev, "InterpretIE: not enough bytes left\n"); + dev_err(adapter->dev, + "InterpretIE: not enough bytes left\n"); continue; } bcn_param = (struct mwifiex_bcn_param *)current_ptr; @@ -1673,20 +1668,20 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, memcpy(bssid, bcn_param->bssid, ETH_ALEN); rssi = (s32) (bcn_param->rssi); - dev_dbg(adapter->dev, "info: InterpretIE: RSSI=%02X\n", - rssi); + dev_dbg(adapter->dev, "info: InterpretIE: RSSI=%02X\n", rssi); beacon_period = le16_to_cpu(bcn_param->beacon_period); cap_info_bitmap = le16_to_cpu(bcn_param->cap_info_bitmap); dev_dbg(adapter->dev, "info: InterpretIE: capabilities=0x%X\n", - cap_info_bitmap); + cap_info_bitmap); /* Rest of the current buffer are IE's */ ie_buf = current_ptr; ie_len = curr_bcn_bytes; - dev_dbg(adapter->dev, "info: InterpretIE: IELength for this AP" - " = %d\n", curr_bcn_bytes); + dev_dbg(adapter->dev, + "info: InterpretIE: IELength for this AP = %d\n", + curr_bcn_bytes); while (curr_bcn_bytes >= sizeof(struct ieee_types_header)) { u8 element_id, element_len; @@ -1695,8 +1690,8 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, element_len = *(current_ptr + 1); if (curr_bcn_bytes < element_len + sizeof(struct ieee_types_header)) { - dev_err(priv->adapter->dev, "%s: in processing" - " IE, bytes left < IE length\n", + dev_err(priv->adapter->dev, + "%s: bytes left < IE length\n", __func__); goto done; } @@ -1720,8 +1715,8 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, */ if (tsf_tlv) memcpy(&network_tsf, - &tsf_tlv->tsf_data[idx * TSF_DATA_SIZE], - sizeof(network_tsf)); + &tsf_tlv->tsf_data[idx * TSF_DATA_SIZE], + sizeof(network_tsf)); if (channel) { struct ieee80211_channel *chan; @@ -1750,13 +1745,15 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, *(u8 *)bss->priv = band; cfg80211_put_bss(bss); - if (priv->media_connected && !memcmp(bssid, - priv->curr_bss_params.bss_descriptor - .mac_address, ETH_ALEN)) - mwifiex_update_curr_bss_params(priv, - bssid, rssi, ie_buf, - ie_len, beacon_period, - cap_info_bitmap, band); + if (priv->media_connected && + !memcmp(bssid, + priv->curr_bss_params.bss_descriptor + .mac_address, ETH_ALEN)) + mwifiex_update_curr_bss_params + (priv, bssid, rssi, + ie_buf, ie_len, + beacon_period, + cap_info_bitmap, band); } } else { dev_dbg(adapter->dev, "missing BSS channel IE\n"); @@ -1783,8 +1780,8 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, } if (priv->user_scan_cfg) { - dev_dbg(priv->adapter->dev, "info: %s: sending scan " - "results\n", __func__); + dev_dbg(priv->adapter->dev, + "info: %s: sending scan results\n", __func__); cfg80211_scan_done(priv->scan_request, 0); priv->scan_request = NULL; kfree(priv->user_scan_cfg); @@ -1900,7 +1897,7 @@ int mwifiex_request_scan(struct mwifiex_private *priv, if (down_interruptible(&priv->async_sem)) { dev_err(priv->adapter->dev, "%s: acquire semaphore\n", - __func__); + __func__); return -1; } priv->scan_pending_on_block = true; @@ -1985,21 +1982,21 @@ mwifiex_save_curr_bcn(struct mwifiex_private *priv) /* allocate beacon buffer at 1st time; or if it's size has changed */ if (!priv->curr_bcn_buf || - priv->curr_bcn_size != curr_bss->beacon_buf_size) { + priv->curr_bcn_size != curr_bss->beacon_buf_size) { priv->curr_bcn_size = curr_bss->beacon_buf_size; kfree(priv->curr_bcn_buf); priv->curr_bcn_buf = kmalloc(curr_bss->beacon_buf_size, - GFP_ATOMIC); + GFP_ATOMIC); if (!priv->curr_bcn_buf) { dev_err(priv->adapter->dev, - "failed to alloc curr_bcn_buf\n"); + "failed to alloc curr_bcn_buf\n"); return; } } memcpy(priv->curr_bcn_buf, curr_bss->beacon_buf, - curr_bss->beacon_buf_size); + curr_bss->beacon_buf_size); dev_dbg(priv->adapter->dev, "info: current beacon saved %d\n", priv->curr_bcn_size); -- cgit From 5dbd326ca7acc54320c38bdc474600c811f8ad6b Mon Sep 17 00:00:00 2001 From: Yogesh Ashok Powar Date: Tue, 13 Mar 2012 19:22:39 -0700 Subject: mwifiex: fix checkpatch --strict warnings/errors Part 6 For file sdio.c Signed-off-by: Yogesh Ashok Powar Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/sdio.c | 188 ++++++++++++++++++------------------ 1 file changed, 96 insertions(+), 92 deletions(-) diff --git a/drivers/net/wireless/mwifiex/sdio.c b/drivers/net/wireless/mwifiex/sdio.c index fe6fbc123b2e..3f597f4a3f5e 100644 --- a/drivers/net/wireless/mwifiex/sdio.c +++ b/drivers/net/wireless/mwifiex/sdio.c @@ -67,7 +67,7 @@ mwifiex_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id) struct sdio_mmc_card *card = NULL; pr_debug("info: vendor=0x%4.04X device=0x%4.04X class=%d function=%d\n", - func->vendor, func->device, func->class, func->num); + func->vendor, func->device, func->class, func->num); card = kzalloc(sizeof(struct sdio_mmc_card), GFP_KERNEL); if (!card) { @@ -112,6 +112,7 @@ mwifiex_sdio_remove(struct sdio_func *func) { struct sdio_mmc_card *card; struct mwifiex_adapter *adapter; + struct mwifiex_private *priv; int i; pr_debug("info: SDIO func num=%d\n", func->num); @@ -131,15 +132,12 @@ mwifiex_sdio_remove(struct sdio_func *func) for (i = 0; i < adapter->priv_num; i++) if ((GET_BSS_ROLE(adapter->priv[i]) == MWIFIEX_BSS_ROLE_STA) && - adapter->priv[i]->media_connected) + adapter->priv[i]->media_connected) mwifiex_deauthenticate(adapter->priv[i], NULL); - mwifiex_disable_auto_ds(mwifiex_get_priv(adapter, - MWIFIEX_BSS_ROLE_ANY)); - - mwifiex_init_shutdown_fw(mwifiex_get_priv(adapter, - MWIFIEX_BSS_ROLE_ANY), - MWIFIEX_FUNC_SHUTDOWN); + priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY); + mwifiex_disable_auto_ds(priv); + mwifiex_init_shutdown_fw(priv, MWIFIEX_FUNC_SHUTDOWN); } mwifiex_remove_card(card->adapter, &add_remove_card_sem); @@ -169,7 +167,7 @@ static int mwifiex_sdio_suspend(struct device *dev) if (func) { pm_flag = sdio_get_host_pm_caps(func); pr_debug("cmd: %s: suspend: PM flag = 0x%x\n", - sdio_func_id(func), pm_flag); + sdio_func_id(func), pm_flag); if (!(pm_flag & MMC_PM_KEEP_POWER)) { pr_err("%s: cannot remain alive while host is" " suspended\n", sdio_func_id(func)); @@ -363,12 +361,11 @@ static int mwifiex_read_data_sync(struct mwifiex_adapter *adapter, u8 *buffer, { struct sdio_mmc_card *card = adapter->card; int ret = -1; - u8 blk_mode = - (port & MWIFIEX_SDIO_BYTE_MODE_MASK) ? BYTE_MODE : BLOCK_MODE; + u8 blk_mode = (port & MWIFIEX_SDIO_BYTE_MODE_MASK) ? BYTE_MODE + : BLOCK_MODE; u32 blk_size = (blk_mode == BLOCK_MODE) ? MWIFIEX_SDIO_BLOCK_SIZE : 1; - u32 blk_cnt = - (blk_mode == - BLOCK_MODE) ? (len / MWIFIEX_SDIO_BLOCK_SIZE) : len; + u32 blk_cnt = (blk_mode == BLOCK_MODE) ? (len / MWIFIEX_SDIO_BLOCK_SIZE) + : len; u32 ioport = (port & MWIFIEX_SDIO_IO_PORT_MASK); if (claim) @@ -472,8 +469,7 @@ static int mwifiex_write_data_to_card(struct mwifiex_adapter *adapter, i++; dev_err(adapter->dev, "host_to_card, write iomem" " (%d) failed: %d\n", i, ret); - if (mwifiex_write_reg(adapter, - CONFIGURATION_REG, 0x04)) + if (mwifiex_write_reg(adapter, CONFIGURATION_REG, 0x04)) dev_err(adapter->dev, "write CFG reg failed\n"); ret = -1; @@ -507,11 +503,11 @@ static int mwifiex_get_rd_port(struct mwifiex_adapter *adapter, u8 *port) card->mp_rd_bitmap &= (u16) (~CTRL_PORT_MASK); *port = CTRL_PORT; dev_dbg(adapter->dev, "data: port=%d mp_rd_bitmap=0x%04x\n", - *port, card->mp_rd_bitmap); + *port, card->mp_rd_bitmap); } else { if (card->mp_rd_bitmap & (1 << card->curr_rd_port)) { - card->mp_rd_bitmap &= - (u16) (~(1 << card->curr_rd_port)); + card->mp_rd_bitmap &= (u16) + (~(1 << card->curr_rd_port)); *port = card->curr_rd_port; if (++card->curr_rd_port == MAX_PORT) @@ -522,7 +518,7 @@ static int mwifiex_get_rd_port(struct mwifiex_adapter *adapter, u8 *port) dev_dbg(adapter->dev, "data: port=%d mp_rd_bitmap=0x%04x -> 0x%04x\n", - *port, rd_bitmap, card->mp_rd_bitmap); + *port, rd_bitmap, card->mp_rd_bitmap); } return 0; } @@ -556,14 +552,14 @@ static int mwifiex_get_wr_port_data(struct mwifiex_adapter *adapter, u8 *port) if (*port == CTRL_PORT) { dev_err(adapter->dev, "invalid data port=%d cur port=%d" - " mp_wr_bitmap=0x%04x -> 0x%04x\n", - *port, card->curr_wr_port, wr_bitmap, - card->mp_wr_bitmap); + " mp_wr_bitmap=0x%04x -> 0x%04x\n", + *port, card->curr_wr_port, wr_bitmap, + card->mp_wr_bitmap); return -1; } dev_dbg(adapter->dev, "data: port=%d mp_wr_bitmap=0x%04x -> 0x%04x\n", - *port, wr_bitmap, card->mp_wr_bitmap); + *port, wr_bitmap, card->mp_wr_bitmap); return 0; } @@ -586,8 +582,8 @@ mwifiex_sdio_poll_card_status(struct mwifiex_adapter *adapter, u8 bits) usleep_range(10, 20); } - dev_err(adapter->dev, "poll card status failed, tries = %d\n", - tries); + dev_err(adapter->dev, "poll card status failed, tries = %d\n", tries); + return -1; } @@ -670,14 +666,14 @@ static int mwifiex_sdio_card_to_host(struct mwifiex_adapter *adapter, if (ret) { dev_err(adapter->dev, "%s: read iomem failed: %d\n", __func__, - ret); + ret); return -1; } nb = le16_to_cpu(*(__le16 *) (buffer)); if (nb > npayload) { - dev_err(adapter->dev, "%s: invalid packet, nb=%d, npayload=%d\n", - __func__, nb, npayload); + dev_err(adapter->dev, "%s: invalid packet, nb=%d npayload=%d\n", + __func__, nb, npayload); return -1; } @@ -707,19 +703,19 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, u32 i = 0; if (!firmware_len) { - dev_err(adapter->dev, "firmware image not found!" - " Terminating download\n"); + dev_err(adapter->dev, + "firmware image not found! Terminating download\n"); return -1; } dev_dbg(adapter->dev, "info: downloading FW image (%d bytes)\n", - firmware_len); + firmware_len); /* Assume that the allocated buffer is 8-byte aligned */ fwbuf = kzalloc(MWIFIEX_UPLD_SIZE, GFP_KERNEL); if (!fwbuf) { - dev_err(adapter->dev, "unable to alloc buffer for firmware." - " Terminating download\n"); + dev_err(adapter->dev, + "unable to alloc buffer for FW. Terminating dnld\n"); return -ENOMEM; } @@ -731,7 +727,7 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, DN_LD_CARD_RDY); if (ret) { dev_err(adapter->dev, "FW download with helper:" - " poll status timeout @ %d\n", offset); + " poll status timeout @ %d\n", offset); goto done; } @@ -743,17 +739,19 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, ret = mwifiex_read_reg(adapter, HOST_F1_RD_BASE_0, &base0); if (ret) { - dev_err(adapter->dev, "dev BASE0 register read" - " failed: base0=0x%04X(%d). Terminating " - "download\n", base0, base0); + dev_err(adapter->dev, + "dev BASE0 register read failed: " + "base0=%#04X(%d). Terminating dnld\n", + base0, base0); goto done; } ret = mwifiex_read_reg(adapter, HOST_F1_RD_BASE_1, &base1); if (ret) { - dev_err(adapter->dev, "dev BASE1 register read" - " failed: base1=0x%04X(%d). Terminating " - "download\n", base1, base1); + dev_err(adapter->dev, + "dev BASE1 register read failed: " + "base1=%#04X(%d). Terminating dnld\n", + base1, base1); goto done; } len = (u16) (((base1 & 0xff) << 8) | (base0 & 0xff)); @@ -767,8 +765,9 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, if (!len) { break; } else if (len > MWIFIEX_UPLD_SIZE) { - dev_err(adapter->dev, "FW download failed @ %d," - " invalid length %d\n", offset, len); + dev_err(adapter->dev, + "FW dnld failed @ %d, invalid length %d\n", + offset, len); ret = -1; goto done; } @@ -778,13 +777,14 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, if (len & BIT(0)) { i++; if (i > MAX_WRITE_IOMEM_RETRY) { - dev_err(adapter->dev, "FW download failed @" - " %d, over max retry count\n", offset); + dev_err(adapter->dev, + "FW dnld failed @ %d, over max retry\n", + offset); ret = -1; goto done; } dev_err(adapter->dev, "CRC indicated by the helper:" - " len = 0x%04X, txlen = %d\n", len, txlen); + " len = 0x%04X, txlen = %d\n", len, txlen); len &= ~BIT(0); /* Setting this to 0 to resend from same offset */ txlen = 0; @@ -796,8 +796,8 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, if (firmware_len - offset < txlen) txlen = firmware_len - offset; - tx_blocks = (txlen + MWIFIEX_SDIO_BLOCK_SIZE - - 1) / MWIFIEX_SDIO_BLOCK_SIZE; + tx_blocks = (txlen + MWIFIEX_SDIO_BLOCK_SIZE - 1) + / MWIFIEX_SDIO_BLOCK_SIZE; /* Copy payload to buffer */ memmove(fwbuf, &firmware[offset], txlen); @@ -807,8 +807,9 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, MWIFIEX_SDIO_BLOCK_SIZE, adapter->ioport); if (ret) { - dev_err(adapter->dev, "FW download, write iomem (%d)" - " failed @ %d\n", i, offset); + dev_err(adapter->dev, + "FW download, write iomem (%d) failed @ %d\n", + i, offset); if (mwifiex_write_reg(adapter, CONFIGURATION_REG, 0x04)) dev_err(adapter->dev, "write CFG reg failed\n"); @@ -820,7 +821,7 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, } while (true); dev_dbg(adapter->dev, "info: FW download over, size %d bytes\n", - offset); + offset); ret = 0; done: @@ -912,7 +913,7 @@ mwifiex_sdio_interrupt(struct sdio_func *func) card = sdio_get_drvdata(func); if (!card || !card->adapter) { pr_debug("int: func=%p card=%p adapter=%p\n", - func, card, card ? card->adapter : NULL); + func, card, card ? card->adapter : NULL); return; } adapter = card->adapter; @@ -955,10 +956,12 @@ static int mwifiex_decode_rx_packet(struct mwifiex_adapter *adapter, if (adapter->ps_state == PS_STATE_SLEEP_CFM) mwifiex_process_sleep_confirm_resp(adapter, - skb->data, skb->len); + skb->data, + skb->len); - memcpy(cmd_buf, skb->data, min_t(u32, - MWIFIEX_SIZE_OF_CMD_BUFFER, skb->len)); + memcpy(cmd_buf, skb->data, + min_t(u32, MWIFIEX_SIZE_OF_CMD_BUFFER, + skb->len)); dev_kfree_skb_any(skb); } else { @@ -1016,7 +1019,7 @@ static int mwifiex_sdio_card_to_host_mp_aggr(struct mwifiex_adapter *adapter, if (port == CTRL_PORT) { /* Read the command Resp without aggr */ dev_dbg(adapter->dev, "info: %s: no aggregation for cmd " - "response\n", __func__); + "response\n", __func__); f_do_rx_cur = 1; goto rx_curr_single; @@ -1024,7 +1027,7 @@ static int mwifiex_sdio_card_to_host_mp_aggr(struct mwifiex_adapter *adapter, if (!card->mpa_rx.enabled) { dev_dbg(adapter->dev, "info: %s: rx aggregation disabled\n", - __func__); + __func__); f_do_rx_cur = 1; goto rx_curr_single; @@ -1071,7 +1074,7 @@ static int mwifiex_sdio_card_to_host_mp_aggr(struct mwifiex_adapter *adapter, if (MP_RX_AGGR_PKT_LIMIT_REACHED(card) || MP_RX_AGGR_PORT_LIMIT_REACHED(card)) { dev_dbg(adapter->dev, "info: %s: aggregated packet " - "limit reached\n", __func__); + "limit reached\n", __func__); /* No more pkts allowed in Aggr buf, rx it */ f_do_rx_aggr = 1; } @@ -1080,7 +1083,7 @@ static int mwifiex_sdio_card_to_host_mp_aggr(struct mwifiex_adapter *adapter, if (f_do_rx_aggr) { /* do aggr RX now */ dev_dbg(adapter->dev, "info: do_rx_aggr: num of packets: %d\n", - card->mpa_rx.pkt_cnt); + card->mpa_rx.pkt_cnt); if (mwifiex_read_data_sync(adapter, card->mpa_rx.buf, card->mpa_rx.buf_len, @@ -1194,7 +1197,7 @@ static int mwifiex_process_int_status(struct mwifiex_adapter *adapter) card->mp_wr_bitmap = ((u16) card->mp_regs[WR_BITMAP_U]) << 8; card->mp_wr_bitmap |= (u16) card->mp_regs[WR_BITMAP_L]; dev_dbg(adapter->dev, "int: DNLD: wr_bitmap=0x%04x\n", - card->mp_wr_bitmap); + card->mp_wr_bitmap); if (adapter->data_sent && (card->mp_wr_bitmap & card->mp_data_port_mask)) { dev_dbg(adapter->dev, @@ -1216,12 +1219,12 @@ static int mwifiex_process_int_status(struct mwifiex_adapter *adapter) } dev_dbg(adapter->dev, "info: cmd_sent=%d data_sent=%d\n", - adapter->cmd_sent, adapter->data_sent); + adapter->cmd_sent, adapter->data_sent); if (sdio_ireg & UP_LD_HOST_INT_STATUS) { card->mp_rd_bitmap = ((u16) card->mp_regs[RD_BITMAP_U]) << 8; card->mp_rd_bitmap |= (u16) card->mp_regs[RD_BITMAP_L]; dev_dbg(adapter->dev, "int: UPLD: rd_bitmap=0x%04x\n", - card->mp_rd_bitmap); + card->mp_rd_bitmap); while (true) { ret = mwifiex_get_rd_port(adapter, &port); @@ -1235,15 +1238,15 @@ static int mwifiex_process_int_status(struct mwifiex_adapter *adapter) rx_len = ((u16) card->mp_regs[len_reg_u]) << 8; rx_len |= (u16) card->mp_regs[len_reg_l]; dev_dbg(adapter->dev, "info: RX: port=%d rx_len=%u\n", - port, rx_len); + port, rx_len); rx_blocks = (rx_len + MWIFIEX_SDIO_BLOCK_SIZE - 1) / MWIFIEX_SDIO_BLOCK_SIZE; - if (rx_len <= INTF_HEADER_LEN - || (rx_blocks * MWIFIEX_SDIO_BLOCK_SIZE) > - MWIFIEX_RX_DATA_BUF_SIZE) { + if (rx_len <= INTF_HEADER_LEN || + (rx_blocks * MWIFIEX_SDIO_BLOCK_SIZE) > + MWIFIEX_RX_DATA_BUF_SIZE) { dev_err(adapter->dev, "invalid rx_len=%d\n", - rx_len); + rx_len); return -1; } rx_len = (u16) (rx_blocks * MWIFIEX_SDIO_BLOCK_SIZE); @@ -1252,42 +1255,42 @@ static int mwifiex_process_int_status(struct mwifiex_adapter *adapter) if (!skb) { dev_err(adapter->dev, "%s: failed to alloc skb", - __func__); + __func__); return -1; } skb_put(skb, rx_len); dev_dbg(adapter->dev, "info: rx_len = %d skb->len = %d\n", - rx_len, skb->len); + rx_len, skb->len); if (mwifiex_sdio_card_to_host_mp_aggr(adapter, skb, port)) { u32 cr = 0; dev_err(adapter->dev, "card_to_host_mpa failed:" - " int status=%#x\n", sdio_ireg); + " int status=%#x\n", sdio_ireg); if (mwifiex_read_reg(adapter, CONFIGURATION_REG, &cr)) dev_err(adapter->dev, - "read CFG reg failed\n"); + "read CFG reg failed\n"); dev_dbg(adapter->dev, - "info: CFG reg val = %d\n", cr); + "info: CFG reg val = %d\n", cr); if (mwifiex_write_reg(adapter, CONFIGURATION_REG, (cr | 0x04))) dev_err(adapter->dev, - "write CFG reg failed\n"); + "write CFG reg failed\n"); dev_dbg(adapter->dev, "info: write success\n"); if (mwifiex_read_reg(adapter, CONFIGURATION_REG, &cr)) dev_err(adapter->dev, - "read CFG reg failed\n"); + "read CFG reg failed\n"); dev_dbg(adapter->dev, - "info: CFG reg val =%x\n", cr); + "info: CFG reg val =%x\n", cr); return -1; } } @@ -1323,7 +1326,7 @@ static int mwifiex_host_to_card_mp_aggr(struct mwifiex_adapter *adapter, if ((!card->mpa_tx.enabled) || (port == CTRL_PORT)) { dev_dbg(adapter->dev, "info: %s: tx aggregation disabled\n", - __func__); + __func__); f_send_cur_buf = 1; goto tx_curr_single; @@ -1332,7 +1335,7 @@ static int mwifiex_host_to_card_mp_aggr(struct mwifiex_adapter *adapter, if (next_pkt_len) { /* More pkt in TX queue */ dev_dbg(adapter->dev, "info: %s: more packets in queue.\n", - __func__); + __func__); if (MP_TX_AGGR_IN_PROGRESS(card)) { if (!MP_TX_AGGR_PORT_LIMIT_REACHED(card) && @@ -1340,9 +1343,9 @@ static int mwifiex_host_to_card_mp_aggr(struct mwifiex_adapter *adapter, f_precopy_cur_buf = 1; if (!(card->mp_wr_bitmap & - (1 << card->curr_wr_port)) - || !MP_TX_AGGR_BUF_HAS_ROOM( - card, pkt_len + next_pkt_len)) + (1 << card->curr_wr_port)) || + !MP_TX_AGGR_BUF_HAS_ROOM( + card, pkt_len + next_pkt_len)) f_send_aggr_buf = 1; } else { /* No room in Aggr buf, send it */ @@ -1356,8 +1359,8 @@ static int mwifiex_host_to_card_mp_aggr(struct mwifiex_adapter *adapter, f_postcopy_cur_buf = 1; } } else { - if (MP_TX_AGGR_BUF_HAS_ROOM(card, pkt_len) - && (card->mp_wr_bitmap & (1 << card->curr_wr_port))) + if (MP_TX_AGGR_BUF_HAS_ROOM(card, pkt_len) && + (card->mp_wr_bitmap & (1 << card->curr_wr_port))) f_precopy_cur_buf = 1; else f_send_cur_buf = 1; @@ -1365,7 +1368,7 @@ static int mwifiex_host_to_card_mp_aggr(struct mwifiex_adapter *adapter, } else { /* Last pkt in TX queue */ dev_dbg(adapter->dev, "info: %s: Last packet in Tx Queue.\n", - __func__); + __func__); if (MP_TX_AGGR_IN_PROGRESS(card)) { /* some packs in Aggr buf already */ @@ -1383,7 +1386,7 @@ static int mwifiex_host_to_card_mp_aggr(struct mwifiex_adapter *adapter, if (f_precopy_cur_buf) { dev_dbg(adapter->dev, "data: %s: precopy current buffer\n", - __func__); + __func__); MP_TX_AGGR_BUF_PUT(card, payload, pkt_len, port); if (MP_TX_AGGR_PKT_LIMIT_REACHED(card) || @@ -1394,7 +1397,7 @@ static int mwifiex_host_to_card_mp_aggr(struct mwifiex_adapter *adapter, if (f_send_aggr_buf) { dev_dbg(adapter->dev, "data: %s: send aggr buffer: %d %d\n", - __func__, + __func__, card->mpa_tx.start_port, card->mpa_tx.ports); ret = mwifiex_write_data_to_card(adapter, card->mpa_tx.buf, card->mpa_tx.buf_len, @@ -1408,14 +1411,14 @@ static int mwifiex_host_to_card_mp_aggr(struct mwifiex_adapter *adapter, tx_curr_single: if (f_send_cur_buf) { dev_dbg(adapter->dev, "data: %s: send current buffer %d\n", - __func__, port); + __func__, port); ret = mwifiex_write_data_to_card(adapter, payload, pkt_len, adapter->ioport + port); } if (f_postcopy_cur_buf) { dev_dbg(adapter->dev, "data: %s: postcopy current buffer\n", - __func__); + __func__); MP_TX_AGGR_BUF_PUT(card, payload, pkt_len, port); } @@ -1460,7 +1463,7 @@ static int mwifiex_sdio_host_to_card(struct mwifiex_adapter *adapter, ret = mwifiex_get_wr_port_data(adapter, &port); if (ret) { dev_err(adapter->dev, "%s: no wr_port available\n", - __func__); + __func__); return ret; } } else { @@ -1470,7 +1473,7 @@ static int mwifiex_sdio_host_to_card(struct mwifiex_adapter *adapter, if (pkt_len <= INTF_HEADER_LEN || pkt_len > MWIFIEX_UPLD_SIZE) dev_err(adapter->dev, "%s: payload=%p, nb=%d\n", - __func__, payload, pkt_len); + __func__, payload, pkt_len); } /* Transfer data to card */ @@ -1478,10 +1481,11 @@ static int mwifiex_sdio_host_to_card(struct mwifiex_adapter *adapter, if (tx_param) ret = mwifiex_host_to_card_mp_aggr(adapter, payload, pkt_len, - port, tx_param->next_pkt_len); + port, tx_param->next_pkt_len + ); else ret = mwifiex_host_to_card_mp_aggr(adapter, payload, pkt_len, - port, 0); + port, 0); if (ret) { if (type == MWIFIEX_TYPE_CMD) @@ -1734,7 +1738,7 @@ mwifiex_update_mp_end_port(struct mwifiex_adapter *adapter, u16 port) card->curr_wr_port = 1; dev_dbg(adapter->dev, "cmd: mp_end_port %d, data port mask 0x%x\n", - port, card->mp_data_port_mask); + port, card->mp_data_port_mask); } static struct mwifiex_if_ops sdio_ops = { -- cgit From 9c05fd72042bafdf86c6273e3b63bb8571f66177 Mon Sep 17 00:00:00 2001 From: Yogesh Ashok Powar Date: Tue, 13 Mar 2012 19:22:40 -0700 Subject: mwifiex: fix checkpatch --strict warnings/errors Part 7 For sta_cmd.c and sta_cmdresp.c Signed-off-by: Yogesh Ashok Powar Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/sta_cmd.c | 175 ++++++++++++++--------------- drivers/net/wireless/mwifiex/sta_cmdresp.c | 60 +++++----- 2 files changed, 114 insertions(+), 121 deletions(-) diff --git a/drivers/net/wireless/mwifiex/sta_cmd.c b/drivers/net/wireless/mwifiex/sta_cmd.c index 324c651527cb..6c8e4594b48b 100644 --- a/drivers/net/wireless/mwifiex/sta_cmd.c +++ b/drivers/net/wireless/mwifiex/sta_cmd.c @@ -110,7 +110,7 @@ static int mwifiex_cmd_802_11_snmp_mib(struct mwifiex_private *priv, dev_dbg(priv->adapter->dev, "cmd: SNMP_CMD: cmd_oid = 0x%x\n", cmd_oid); cmd->command = cpu_to_le16(HostCmd_CMD_802_11_SNMP_MIB); cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_802_11_snmp_mib) - - 1 + S_DS_GEN); + - 1 + S_DS_GEN); snmp_mib->oid = cpu_to_le16((u16)cmd_oid); if (cmd_action == HostCmd_ACT_GEN_GET) { @@ -127,8 +127,8 @@ static int mwifiex_cmd_802_11_snmp_mib(struct mwifiex_private *priv, dev_dbg(priv->adapter->dev, "cmd: SNMP_CMD: Action=0x%x, OID=0x%x, OIDSize=0x%x," " Value=0x%x\n", - cmd_action, cmd_oid, le16_to_cpu(snmp_mib->buf_size), - le16_to_cpu(*(__le16 *) snmp_mib->value)); + cmd_action, cmd_oid, le16_to_cpu(snmp_mib->buf_size), + le16_to_cpu(*(__le16 *) snmp_mib->value)); return 0; } @@ -174,8 +174,8 @@ static int mwifiex_cmd_tx_rate_cfg(struct mwifiex_private *priv, rate_scope = (struct mwifiex_rate_scope *) ((u8 *) rate_cfg + sizeof(struct host_cmd_ds_tx_rate_cfg)); rate_scope->type = cpu_to_le16(TLV_TYPE_RATE_SCOPE); - rate_scope->length = cpu_to_le16(sizeof(struct mwifiex_rate_scope) - - sizeof(struct mwifiex_ie_types_header)); + rate_scope->length = cpu_to_le16 + (sizeof(*rate_scope) - sizeof(struct mwifiex_ie_types_header)); if (pbitmap_rates != NULL) { rate_scope->hr_dsss_rate_bitmap = cpu_to_le16(pbitmap_rates[0]); rate_scope->ofdm_rate_bitmap = cpu_to_le16(pbitmap_rates[1]); @@ -197,7 +197,7 @@ static int mwifiex_cmd_tx_rate_cfg(struct mwifiex_private *priv, } rate_drop = (struct mwifiex_rate_drop_pattern *) ((u8 *) rate_scope + - sizeof(struct mwifiex_rate_scope)); + sizeof(struct mwifiex_rate_scope)); rate_drop->type = cpu_to_le16(TLV_TYPE_RATE_DROP_CONTROL); rate_drop->length = cpu_to_le16(sizeof(rate_drop->rate_drop_mode)); rate_drop->rate_drop_mode = 0; @@ -284,22 +284,22 @@ mwifiex_cmd_802_11_hs_cfg(struct mwifiex_private *priv, cmd->command = cpu_to_le16(HostCmd_CMD_802_11_HS_CFG_ENH); if (!hs_activate && - (hscfg_param->conditions - != cpu_to_le32(HOST_SLEEP_CFG_CANCEL)) - && ((adapter->arp_filter_size > 0) - && (adapter->arp_filter_size <= ARP_FILTER_MAX_BUF_SIZE))) { + (hscfg_param->conditions != cpu_to_le32(HOST_SLEEP_CFG_CANCEL)) && + ((adapter->arp_filter_size > 0) && + (adapter->arp_filter_size <= ARP_FILTER_MAX_BUF_SIZE))) { dev_dbg(adapter->dev, "cmd: Attach %d bytes ArpFilter to HSCfg cmd\n", - adapter->arp_filter_size); + adapter->arp_filter_size); memcpy(((u8 *) hs_cfg) + sizeof(struct host_cmd_ds_802_11_hs_cfg_enh), adapter->arp_filter, adapter->arp_filter_size); - cmd->size = cpu_to_le16(adapter->arp_filter_size + - sizeof(struct host_cmd_ds_802_11_hs_cfg_enh) - + S_DS_GEN); + cmd->size = cpu_to_le16 + (adapter->arp_filter_size + + sizeof(struct host_cmd_ds_802_11_hs_cfg_enh) + + S_DS_GEN); } else { cmd->size = cpu_to_le16(S_DS_GEN + sizeof(struct - host_cmd_ds_802_11_hs_cfg_enh)); + host_cmd_ds_802_11_hs_cfg_enh)); } if (hs_activate) { hs_cfg->action = cpu_to_le16(HS_ACTIVATE); @@ -467,7 +467,7 @@ mwifiex_set_keyparamset_wep(struct mwifiex_private *priv, key_param_set = (struct mwifiex_ie_type_key_param_set *) ((u8 *)key_param_set + - cur_key_param_len); + cur_key_param_len); } else if (!priv->wep_key[i].key_length) { continue; } else { @@ -527,13 +527,13 @@ mwifiex_cmd_802_11_key_material(struct mwifiex_private *priv, if (enc_key->is_wapi_key) { dev_dbg(priv->adapter->dev, "info: Set WAPI Key\n"); key_material->key_param_set.key_type_id = - cpu_to_le16(KEY_TYPE_ID_WAPI); + cpu_to_le16(KEY_TYPE_ID_WAPI); if (cmd_oid == KEY_INFO_ENABLED) key_material->key_param_set.key_info = - cpu_to_le16(KEY_ENABLED); + cpu_to_le16(KEY_ENABLED); else key_material->key_param_set.key_info = - cpu_to_le16(!KEY_ENABLED); + cpu_to_le16(!KEY_ENABLED); key_material->key_param_set.key[0] = enc_key->key_index; if (!priv->sec_info.wapi_key_on) @@ -553,9 +553,9 @@ mwifiex_cmd_802_11_key_material(struct mwifiex_private *priv, } key_material->key_param_set.type = - cpu_to_le16(TLV_TYPE_KEY_MATERIAL); + cpu_to_le16(TLV_TYPE_KEY_MATERIAL); key_material->key_param_set.key_len = - cpu_to_le16(WAPI_KEY_LEN); + cpu_to_le16(WAPI_KEY_LEN); memcpy(&key_material->key_param_set.key[2], enc_key->key_material, enc_key->key_len); memcpy(&key_material->key_param_set.key[2 + enc_key->key_len], @@ -565,49 +565,49 @@ mwifiex_cmd_802_11_key_material(struct mwifiex_private *priv, key_param_len = (WAPI_KEY_LEN + KEYPARAMSET_FIXED_LEN) + sizeof(struct mwifiex_ie_types_header); - cmd->size = cpu_to_le16(key_param_len + - sizeof(key_material->action) + S_DS_GEN); + cmd->size = cpu_to_le16(sizeof(key_material->action) + + S_DS_GEN + key_param_len); return ret; } if (enc_key->key_len == WLAN_KEY_LEN_CCMP) { dev_dbg(priv->adapter->dev, "cmd: WPA_AES\n"); key_material->key_param_set.key_type_id = - cpu_to_le16(KEY_TYPE_ID_AES); + cpu_to_le16(KEY_TYPE_ID_AES); if (cmd_oid == KEY_INFO_ENABLED) key_material->key_param_set.key_info = - cpu_to_le16(KEY_ENABLED); + cpu_to_le16(KEY_ENABLED); else key_material->key_param_set.key_info = - cpu_to_le16(!KEY_ENABLED); + cpu_to_le16(!KEY_ENABLED); if (enc_key->key_index & MWIFIEX_KEY_INDEX_UNICAST) /* AES pairwise key: unicast */ key_material->key_param_set.key_info |= - cpu_to_le16(KEY_UNICAST); + cpu_to_le16(KEY_UNICAST); else /* AES group key: multicast */ key_material->key_param_set.key_info |= - cpu_to_le16(KEY_MCAST); + cpu_to_le16(KEY_MCAST); } else if (enc_key->key_len == WLAN_KEY_LEN_TKIP) { dev_dbg(priv->adapter->dev, "cmd: WPA_TKIP\n"); key_material->key_param_set.key_type_id = - cpu_to_le16(KEY_TYPE_ID_TKIP); + cpu_to_le16(KEY_TYPE_ID_TKIP); key_material->key_param_set.key_info = - cpu_to_le16(KEY_ENABLED); + cpu_to_le16(KEY_ENABLED); if (enc_key->key_index & MWIFIEX_KEY_INDEX_UNICAST) /* TKIP pairwise key: unicast */ key_material->key_param_set.key_info |= - cpu_to_le16(KEY_UNICAST); + cpu_to_le16(KEY_UNICAST); else /* TKIP group key: multicast */ key_material->key_param_set.key_info |= - cpu_to_le16(KEY_MCAST); + cpu_to_le16(KEY_MCAST); } if (key_material->key_param_set.key_type_id) { key_material->key_param_set.type = - cpu_to_le16(TLV_TYPE_KEY_MATERIAL); + cpu_to_le16(TLV_TYPE_KEY_MATERIAL); key_material->key_param_set.key_len = - cpu_to_le16((u16) enc_key->key_len); + cpu_to_le16((u16) enc_key->key_len); memcpy(key_material->key_param_set.key, enc_key->key_material, enc_key->key_len); key_material->key_param_set.length = @@ -615,10 +615,10 @@ mwifiex_cmd_802_11_key_material(struct mwifiex_private *priv, KEYPARAMSET_FIXED_LEN); key_param_len = (u16) (enc_key->key_len + KEYPARAMSET_FIXED_LEN) - + sizeof(struct mwifiex_ie_types_header); + + sizeof(struct mwifiex_ie_types_header); - cmd->size = cpu_to_le16(key_param_len + - sizeof(key_material->action) + S_DS_GEN); + cmd->size = cpu_to_le16(sizeof(key_material->action) + S_DS_GEN + + key_param_len); } return ret; @@ -655,21 +655,22 @@ static int mwifiex_cmd_802_11d_domain_info(struct mwifiex_private *priv, /* Set domain info fields */ domain->header.type = cpu_to_le16(WLAN_EID_COUNTRY); memcpy(domain->country_code, adapter->domain_reg.country_code, - sizeof(domain->country_code)); + sizeof(domain->country_code)); - domain->header.len = cpu_to_le16((no_of_triplet * - sizeof(struct ieee80211_country_ie_triplet)) + - sizeof(domain->country_code)); + domain->header.len = + cpu_to_le16((no_of_triplet * + sizeof(struct ieee80211_country_ie_triplet)) + + sizeof(domain->country_code)); if (no_of_triplet) { memcpy(domain->triplet, adapter->domain_reg.triplet, - no_of_triplet * - sizeof(struct ieee80211_country_ie_triplet)); + no_of_triplet * sizeof(struct + ieee80211_country_ie_triplet)); cmd->size = cpu_to_le16(sizeof(domain_info->action) + - le16_to_cpu(domain->header.len) + - sizeof(struct mwifiex_ie_types_header) - + S_DS_GEN); + le16_to_cpu(domain->header.len) + + sizeof(struct mwifiex_ie_types_header) + + S_DS_GEN); } else { cmd->size = cpu_to_le16(sizeof(domain_info->action) + S_DS_GEN); } @@ -698,8 +699,8 @@ static int mwifiex_cmd_802_11_rf_channel(struct mwifiex_private *priv, + S_DS_GEN); if (cmd_action == HostCmd_ACT_GEN_SET) { - if ((priv->adapter->adhoc_start_band & BAND_A) - || (priv->adapter->adhoc_start_band & BAND_AN)) + if ((priv->adapter->adhoc_start_band & BAND_A) || + (priv->adapter->adhoc_start_band & BAND_AN)) rf_chan->rf_type = cpu_to_le16(HostCmd_SCAN_RADIO_TYPE_A); @@ -777,7 +778,7 @@ static int mwifiex_cmd_reg_access(struct host_cmd_ds_command *cmd, cmd->size = cpu_to_le16(sizeof(*mac_reg) + S_DS_GEN); mac_reg = (struct host_cmd_ds_mac_reg_access *) &cmd-> - params.mac_reg; + params.mac_reg; mac_reg->action = cpu_to_le16(cmd_action); mac_reg->offset = cpu_to_le16((u16) le32_to_cpu(reg_rw->offset)); @@ -789,8 +790,8 @@ static int mwifiex_cmd_reg_access(struct host_cmd_ds_command *cmd, struct host_cmd_ds_bbp_reg_access *bbp_reg; cmd->size = cpu_to_le16(sizeof(*bbp_reg) + S_DS_GEN); - bbp_reg = (struct host_cmd_ds_bbp_reg_access *) &cmd-> - params.bbp_reg; + bbp_reg = (struct host_cmd_ds_bbp_reg_access *) + &cmd->params.bbp_reg; bbp_reg->action = cpu_to_le16(cmd_action); bbp_reg->offset = cpu_to_le16((u16) le32_to_cpu(reg_rw->offset)); @@ -802,11 +803,10 @@ static int mwifiex_cmd_reg_access(struct host_cmd_ds_command *cmd, struct host_cmd_ds_rf_reg_access *rf_reg; cmd->size = cpu_to_le16(sizeof(*rf_reg) + S_DS_GEN); - rf_reg = (struct host_cmd_ds_rf_reg_access *) &cmd-> - params.rf_reg; + rf_reg = (struct host_cmd_ds_rf_reg_access *) + &cmd->params.rf_reg; rf_reg->action = cpu_to_le16(cmd_action); - rf_reg->offset = - cpu_to_le16((u16) le32_to_cpu(reg_rw->offset)); + rf_reg->offset = cpu_to_le16((u16) le32_to_cpu(reg_rw->offset)); rf_reg->value = (u8) le32_to_cpu(reg_rw->value); break; } @@ -819,7 +819,7 @@ static int mwifiex_cmd_reg_access(struct host_cmd_ds_command *cmd, params.pmic_reg; pmic_reg->action = cpu_to_le16(cmd_action); pmic_reg->offset = - cpu_to_le16((u16) le32_to_cpu(reg_rw->offset)); + cpu_to_le16((u16) le32_to_cpu(reg_rw->offset)); pmic_reg->value = (u8) le32_to_cpu(reg_rw->value); break; } @@ -828,11 +828,11 @@ static int mwifiex_cmd_reg_access(struct host_cmd_ds_command *cmd, struct host_cmd_ds_rf_reg_access *cau_reg; cmd->size = cpu_to_le16(sizeof(*cau_reg) + S_DS_GEN); - cau_reg = (struct host_cmd_ds_rf_reg_access *) &cmd-> - params.rf_reg; + cau_reg = (struct host_cmd_ds_rf_reg_access *) + &cmd->params.rf_reg; cau_reg->action = cpu_to_le16(cmd_action); cau_reg->offset = - cpu_to_le16((u16) le32_to_cpu(reg_rw->offset)); + cpu_to_le16((u16) le32_to_cpu(reg_rw->offset)); cau_reg->value = (u8) le32_to_cpu(reg_rw->value); break; } @@ -868,7 +868,7 @@ static int mwifiex_cmd_reg_access(struct host_cmd_ds_command *cmd, */ static int mwifiex_cmd_pcie_host_spec(struct mwifiex_private *priv, - struct host_cmd_ds_command *cmd, u16 action) + struct host_cmd_ds_command *cmd, u16 action) { struct host_cmd_ds_pcie_details *host_spec = &cmd->params.pcie_host_spec; @@ -882,29 +882,25 @@ mwifiex_cmd_pcie_host_spec(struct mwifiex_private *priv, memset(host_spec, 0, sizeof(struct host_cmd_ds_pcie_details)); - if (action == HostCmd_ACT_GEN_SET) { - /* Send the ring base addresses and count to firmware */ - host_spec->txbd_addr_lo = (u32)(card->txbd_ring_pbase); - host_spec->txbd_addr_hi = - (u32)(((u64)card->txbd_ring_pbase)>>32); - host_spec->txbd_count = MWIFIEX_MAX_TXRX_BD; - host_spec->rxbd_addr_lo = (u32)(card->rxbd_ring_pbase); - host_spec->rxbd_addr_hi = - (u32)(((u64)card->rxbd_ring_pbase)>>32); - host_spec->rxbd_count = MWIFIEX_MAX_TXRX_BD; - host_spec->evtbd_addr_lo = - (u32)(card->evtbd_ring_pbase); - host_spec->evtbd_addr_hi = - (u32)(((u64)card->evtbd_ring_pbase)>>32); - host_spec->evtbd_count = MWIFIEX_MAX_EVT_BD; - if (card->sleep_cookie) { - buf_pa = MWIFIEX_SKB_PACB(card->sleep_cookie); - host_spec->sleep_cookie_addr_lo = (u32) *buf_pa; - host_spec->sleep_cookie_addr_hi = - (u32) (((u64)*buf_pa) >> 32); - dev_dbg(priv->adapter->dev, "sleep_cook_lo phy addr: " - "0x%x\n", host_spec->sleep_cookie_addr_lo); - } + if (action != HostCmd_ACT_GEN_SET) + return 0; + + /* Send the ring base addresses and count to firmware */ + host_spec->txbd_addr_lo = (u32)(card->txbd_ring_pbase); + host_spec->txbd_addr_hi = (u32)(((u64)card->txbd_ring_pbase)>>32); + host_spec->txbd_count = MWIFIEX_MAX_TXRX_BD; + host_spec->rxbd_addr_lo = (u32)(card->rxbd_ring_pbase); + host_spec->rxbd_addr_hi = (u32)(((u64)card->rxbd_ring_pbase)>>32); + host_spec->rxbd_count = MWIFIEX_MAX_TXRX_BD; + host_spec->evtbd_addr_lo = (u32)(card->evtbd_ring_pbase); + host_spec->evtbd_addr_hi = (u32)(((u64)card->evtbd_ring_pbase)>>32); + host_spec->evtbd_count = MWIFIEX_MAX_EVT_BD; + if (card->sleep_cookie) { + buf_pa = MWIFIEX_SKB_PACB(card->sleep_cookie); + host_spec->sleep_cookie_addr_lo = (u32) *buf_pa; + host_spec->sleep_cookie_addr_hi = (u32) (((u64)*buf_pa) >> 32); + dev_dbg(priv->adapter->dev, "sleep_cook_lo phy addr: 0x%x\n", + host_spec->sleep_cookie_addr_lo); } return 0; @@ -1036,12 +1032,12 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no, break; case HostCmd_CMD_802_11_KEY_MATERIAL: ret = mwifiex_cmd_802_11_key_material(priv, cmd_ptr, - cmd_action, cmd_oid, - data_buf); + cmd_action, cmd_oid, + data_buf); break; case HostCmd_CMD_802_11D_DOMAIN_INFO: ret = mwifiex_cmd_802_11d_domain_info(priv, cmd_ptr, - cmd_action); + cmd_action); break; case HostCmd_CMD_RECONFIGURE_TX_BUFF: ret = mwifiex_cmd_recfg_tx_buf(priv, cmd_ptr, cmd_action, @@ -1052,8 +1048,7 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no, data_buf); break; case HostCmd_CMD_11N_CFG: - ret = mwifiex_cmd_11n_cfg(cmd_ptr, cmd_action, - data_buf); + ret = mwifiex_cmd_11n_cfg(cmd_ptr, cmd_action, data_buf); break; case HostCmd_CMD_WMM_GET_STATUS: dev_dbg(priv->adapter->dev, @@ -1131,8 +1126,8 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta) if (first_sta) { if (priv->adapter->iface_type == MWIFIEX_PCIE) { ret = mwifiex_send_cmd_async(priv, - HostCmd_CMD_PCIE_DESC_DETAILS, - HostCmd_ACT_GEN_SET, 0, NULL); + HostCmd_CMD_PCIE_DESC_DETAILS, + HostCmd_ACT_GEN_SET, 0, NULL); if (ret) return -1; } diff --git a/drivers/net/wireless/mwifiex/sta_cmdresp.c b/drivers/net/wireless/mwifiex/sta_cmdresp.c index a2a9c513e26b..4da19ed0f078 100644 --- a/drivers/net/wireless/mwifiex/sta_cmdresp.c +++ b/drivers/net/wireless/mwifiex/sta_cmdresp.c @@ -49,7 +49,7 @@ mwifiex_process_cmdresp_error(struct mwifiex_private *priv, unsigned long flags; dev_err(adapter->dev, "CMD_RESP: cmd %#x error, result=%#x\n", - resp->command, resp->result); + resp->command, resp->result); if (adapter->curr_cmd->wait_q_enabled) adapter->cmd_wait_q.status = -1; @@ -57,13 +57,13 @@ mwifiex_process_cmdresp_error(struct mwifiex_private *priv, switch (le16_to_cpu(resp->command)) { case HostCmd_CMD_802_11_PS_MODE_ENH: pm = &resp->params.psmode_enh; - dev_err(adapter->dev, "PS_MODE_ENH cmd failed: " - "result=0x%x action=0x%X\n", - resp->result, le16_to_cpu(pm->action)); + dev_err(adapter->dev, + "PS_MODE_ENH cmd failed: result=0x%x action=0x%X\n", + resp->result, le16_to_cpu(pm->action)); /* We do not re-try enter-ps command in ad-hoc mode. */ if (le16_to_cpu(pm->action) == EN_AUTO_PS && - (le16_to_cpu(pm->params.ps_bitmap) & BITMAP_STA_PS) && - priv->bss_mode == NL80211_IFTYPE_ADHOC) + (le16_to_cpu(pm->params.ps_bitmap) & BITMAP_STA_PS) && + priv->bss_mode == NL80211_IFTYPE_ADHOC) adapter->ps_mode = MWIFIEX_802_11_POWER_MODE_CAM; break; @@ -123,7 +123,7 @@ static int mwifiex_ret_802_11_rssi_info(struct mwifiex_private *priv, struct mwifiex_ds_get_signal *signal) { struct host_cmd_ds_802_11_rssi_info_rsp *rssi_info_rsp = - &resp->params.rssi_info_rsp; + &resp->params.rssi_info_rsp; priv->data_rssi_last = le16_to_cpu(rssi_info_rsp->data_rssi_last); priv->data_nf_last = le16_to_cpu(rssi_info_rsp->data_nf_last); @@ -191,8 +191,8 @@ static int mwifiex_ret_802_11_snmp_mib(struct mwifiex_private *priv, u32 ul_temp; dev_dbg(priv->adapter->dev, "info: SNMP_RESP: oid value = %#x," - " query_type = %#x, buf size = %#x\n", - oid, query_type, le16_to_cpu(smib->buf_size)); + " query_type = %#x, buf size = %#x\n", + oid, query_type, le16_to_cpu(smib->buf_size)); if (query_type == HostCmd_ACT_GEN_GET) { ul_temp = le16_to_cpu(*((__le16 *) (smib->value))); if (data_buf) @@ -444,7 +444,7 @@ static int mwifiex_ret_tx_power_cfg(struct mwifiex_private *priv, break; default: dev_err(adapter->dev, "CMD_RESP: unknown cmd action %d\n", - action); + action); return 0; } dev_dbg(adapter->dev, @@ -464,7 +464,7 @@ static int mwifiex_ret_802_11_mac_address(struct mwifiex_private *priv, struct host_cmd_ds_command *resp) { struct host_cmd_ds_802_11_mac_address *cmd_mac_addr = - &resp->params.mac_addr; + &resp->params.mac_addr; memcpy(priv->curr_addr, cmd_mac_addr->mac_addr, ETH_ALEN); @@ -549,7 +549,7 @@ static int mwifiex_ret_802_11_key_material(struct mwifiex_private *priv, struct host_cmd_ds_command *resp) { struct host_cmd_ds_802_11_key_material *key = - &resp->params.key_material; + &resp->params.key_material; if (le16_to_cpu(key->action) == HostCmd_ACT_GEN_SET) { if ((le16_to_cpu(key->key_param_set.key_info) & KEY_MCAST)) { @@ -580,17 +580,18 @@ static int mwifiex_ret_802_11d_domain_info(struct mwifiex_private *priv, u16 action = le16_to_cpu(domain_info->action); u8 no_of_triplet; - no_of_triplet = (u8) ((le16_to_cpu(domain->header.len) - - IEEE80211_COUNTRY_STRING_LEN) / - sizeof(struct ieee80211_country_ie_triplet)); + no_of_triplet = (u8) ((le16_to_cpu(domain->header.len) + - IEEE80211_COUNTRY_STRING_LEN) + / sizeof(struct ieee80211_country_ie_triplet)); - dev_dbg(priv->adapter->dev, "info: 11D Domain Info Resp:" - " no_of_triplet=%d\n", no_of_triplet); + dev_dbg(priv->adapter->dev, + "info: 11D Domain Info Resp: no_of_triplet=%d\n", + no_of_triplet); if (no_of_triplet > MWIFIEX_MAX_TRIPLET_802_11D) { dev_warn(priv->adapter->dev, - "11D: invalid number of triplets %d " - "returned!!\n", no_of_triplet); + "11D: invalid number of triplets %d returned\n", + no_of_triplet); return -1; } @@ -624,8 +625,8 @@ static int mwifiex_ret_802_11_rf_channel(struct mwifiex_private *priv, if (priv->curr_bss_params.bss_descriptor.channel != new_channel) { dev_dbg(priv->adapter->dev, "cmd: Channel Switch: %d to %d\n", - priv->curr_bss_params.bss_descriptor.channel, - new_channel); + priv->curr_bss_params.bss_descriptor.channel, + new_channel); /* Update the channel again */ priv->curr_bss_params.bss_descriptor.channel = new_channel; } @@ -747,7 +748,7 @@ static int mwifiex_ret_ibss_coalescing_status(struct mwifiex_private *priv, struct host_cmd_ds_command *resp) { struct host_cmd_ds_802_11_ibss_status *ibss_coal_resp = - &(resp->params.ibss_coalescing); + &(resp->params.ibss_coalescing); u8 zero_mac[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 }; if (le16_to_cpu(ibss_coal_resp->action) == HostCmd_ACT_GEN_SET) @@ -887,20 +888,17 @@ int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, u16 cmdresp_no, case HostCmd_CMD_RECONFIGURE_TX_BUFF: adapter->tx_buf_size = (u16) le16_to_cpu(resp->params. tx_buf.buff_size); - adapter->tx_buf_size = (adapter->tx_buf_size / - MWIFIEX_SDIO_BLOCK_SIZE) * - MWIFIEX_SDIO_BLOCK_SIZE; + adapter->tx_buf_size = (adapter->tx_buf_size + / MWIFIEX_SDIO_BLOCK_SIZE) + * MWIFIEX_SDIO_BLOCK_SIZE; adapter->curr_tx_buf_size = adapter->tx_buf_size; dev_dbg(adapter->dev, "cmd: max_tx_buf_size=%d, tx_buf_size=%d\n", - adapter->max_tx_buf_size, adapter->tx_buf_size); + adapter->max_tx_buf_size, adapter->tx_buf_size); if (adapter->if_ops.update_mp_end_port) adapter->if_ops.update_mp_end_port(adapter, - le16_to_cpu(resp-> - params. - tx_buf. - mp_end_port)); + le16_to_cpu(resp->params.tx_buf.mp_end_port)); break; case HostCmd_CMD_AMSDU_AGGR_CTRL: ret = mwifiex_ret_amsdu_aggr_ctrl(resp, data_buf); @@ -928,7 +926,7 @@ int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, u16 cmdresp_no, break; default: dev_err(adapter->dev, "CMD_RESP: unknown cmd response %#x\n", - resp->command); + resp->command); break; } -- cgit From 500f747c73ec9bff7692db0031a3fb726166f4d5 Mon Sep 17 00:00:00 2001 From: Yogesh Ashok Powar Date: Tue, 13 Mar 2012 19:22:41 -0700 Subject: mwifiex: fix checkpatch --strict warnings/errors Part 8 For files sta_event.c and sta_ioctl.c Signed-off-by: Yogesh Ashok Powar Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/sta_event.c | 41 +++++++------ drivers/net/wireless/mwifiex/sta_ioctl.c | 102 +++++++++++++++---------------- 2 files changed, 73 insertions(+), 70 deletions(-) diff --git a/drivers/net/wireless/mwifiex/sta_event.c b/drivers/net/wireless/mwifiex/sta_event.c index b9b59db60454..cc531b536a56 100644 --- a/drivers/net/wireless/mwifiex/sta_event.c +++ b/drivers/net/wireless/mwifiex/sta_event.c @@ -93,11 +93,11 @@ mwifiex_reset_connect_state(struct mwifiex_private *priv) */ dev_dbg(adapter->dev, "info: previous SSID=%s, SSID len=%u\n", - priv->prev_ssid.ssid, priv->prev_ssid.ssid_len); + priv->prev_ssid.ssid, priv->prev_ssid.ssid_len); dev_dbg(adapter->dev, "info: current SSID=%s, SSID len=%u\n", - priv->curr_bss_params.bss_descriptor.ssid.ssid, - priv->curr_bss_params.bss_descriptor.ssid.ssid_len); + priv->curr_bss_params.bss_descriptor.ssid.ssid, + priv->curr_bss_params.bss_descriptor.ssid.ssid_len); memcpy(&priv->prev_ssid, &priv->curr_bss_params.bss_descriptor.ssid, @@ -115,9 +115,9 @@ mwifiex_reset_connect_state(struct mwifiex_private *priv) if (adapter->num_cmd_timeout && adapter->curr_cmd) return; priv->media_connected = false; - dev_dbg(adapter->dev, "info: successfully disconnected from" - " %pM: reason code %d\n", priv->cfg_bssid, - WLAN_REASON_DEAUTH_LEAVING); + dev_dbg(adapter->dev, + "info: successfully disconnected from %pM: reason code %d\n", + priv->cfg_bssid, WLAN_REASON_DEAUTH_LEAVING); if (priv->bss_mode == NL80211_IFTYPE_STATION) { cfg80211_disconnected(priv->netdev, WLAN_REASON_DEAUTH_LEAVING, NULL, 0, GFP_KERNEL); @@ -192,8 +192,8 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv) switch (eventcause) { case EVENT_DUMMY_HOST_WAKEUP_SIGNAL: - dev_err(adapter->dev, "invalid EVENT: DUMMY_HOST_WAKEUP_SIGNAL," - " ignoring it\n"); + dev_err(adapter->dev, + "invalid EVENT: DUMMY_HOST_WAKEUP_SIGNAL, ignore it\n"); break; case EVENT_LINK_SENSED: dev_dbg(adapter->dev, "event: LINK_SENSED\n"); @@ -235,8 +235,7 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv) case EVENT_PS_AWAKE: dev_dbg(adapter->dev, "info: EVENT: AWAKE\n"); if (!adapter->pps_uapsd_mode && - priv->media_connected && - adapter->sleep_period.period) { + priv->media_connected && adapter->sleep_period.period) { adapter->pps_uapsd_mode = true; dev_dbg(adapter->dev, "event: PPS/UAPSD mode activated\n"); @@ -244,15 +243,19 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv) adapter->tx_lock_flag = false; if (adapter->pps_uapsd_mode && adapter->gen_null_pkt) { if (mwifiex_check_last_packet_indication(priv)) { - if (!adapter->data_sent) { - if (!mwifiex_send_null_packet(priv, - MWIFIEX_TxPD_POWER_MGMT_NULL_PACKET - | - MWIFIEX_TxPD_POWER_MGMT_LAST_PACKET)) + if (adapter->data_sent) { + adapter->ps_state = PS_STATE_AWAKE; + adapter->pm_wakeup_card_req = false; + adapter->pm_wakeup_fw_try = false; + break; + } + if (!mwifiex_send_null_packet + (priv, + MWIFIEX_TxPD_POWER_MGMT_NULL_PACKET | + MWIFIEX_TxPD_POWER_MGMT_LAST_PACKET)) adapter->ps_state = PS_STATE_SLEEP; return 0; - } } } adapter->ps_state = PS_STATE_AWAKE; @@ -371,12 +374,12 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv) break; case EVENT_AMSDU_AGGR_CTRL: dev_dbg(adapter->dev, "event: AMSDU_AGGR_CTRL %d\n", - *(u16 *) adapter->event_body); + *(u16 *) adapter->event_body); adapter->tx_buf_size = min(adapter->curr_tx_buf_size, le16_to_cpu(*(__le16 *) adapter->event_body)); dev_dbg(adapter->dev, "event: tx_buf_size %d\n", - adapter->tx_buf_size); + adapter->tx_buf_size); break; case EVENT_WEP_ICV_ERR: @@ -392,7 +395,7 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv) break; default: dev_dbg(adapter->dev, "event: unknown event id: %#x\n", - eventcause); + eventcause); break; } diff --git a/drivers/net/wireless/mwifiex/sta_ioctl.c b/drivers/net/wireless/mwifiex/sta_ioctl.c index a3d79f4a6192..64e0b1010850 100644 --- a/drivers/net/wireless/mwifiex/sta_ioctl.c +++ b/drivers/net/wireless/mwifiex/sta_ioctl.c @@ -71,7 +71,7 @@ int mwifiex_wait_queue_complete(struct mwifiex_adapter *adapter) /* Wait for completion */ wait_event_interruptible(adapter->cmd_wait_q.wait, - *(cmd_queued->condition)); + *(cmd_queued->condition)); if (!*(cmd_queued->condition)) cancel_flag = true; @@ -266,9 +266,8 @@ int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss, /* Adhoc mode */ /* If the requested SSID matches current SSID, return */ if (bss_desc && bss_desc->ssid.ssid_len && - (!mwifiex_ssid_cmp - (&priv->curr_bss_params.bss_descriptor.ssid, - &bss_desc->ssid))) { + (!mwifiex_ssid_cmp(&priv->curr_bss_params.bss_descriptor. + ssid, &bss_desc->ssid))) { kfree(bss_desc); kfree(beacon_ie); return 0; @@ -350,9 +349,8 @@ static int mwifiex_set_hs_params(struct mwifiex_private *priv, u16 action, adapter->hs_cfg.gpio = (u8)hs_cfg->gpio; if (hs_cfg->gap) adapter->hs_cfg.gap = (u8)hs_cfg->gap; - } else if (adapter->hs_cfg.conditions == - cpu_to_le32( - HOST_SLEEP_CFG_CANCEL)) { + } else if (adapter->hs_cfg.conditions + == cpu_to_le32(HOST_SLEEP_CFG_CANCEL)) { /* Return failure if no parameters for HS enable */ status = -1; @@ -374,7 +372,7 @@ static int mwifiex_set_hs_params(struct mwifiex_private *priv, u16 action, cpu_to_le32(prev_cond); } else { adapter->hs_cfg.conditions = - cpu_to_le32(hs_cfg->conditions); + cpu_to_le32(hs_cfg->conditions); adapter->hs_cfg.gpio = (u8)hs_cfg->gpio; adapter->hs_cfg.gap = (u8)hs_cfg->gap; } @@ -431,7 +429,7 @@ int mwifiex_enable_hs(struct mwifiex_adapter *adapter) hscfg.is_invoke_hostcmd = true; if (mwifiex_set_hs_params(mwifiex_get_priv(adapter, - MWIFIEX_BSS_ROLE_STA), + MWIFIEX_BSS_ROLE_STA), HostCmd_ACT_GEN_SET, MWIFIEX_SYNC_CMD, &hscfg)) { dev_err(adapter->dev, "IOCTL request HS enable failed\n"); @@ -439,7 +437,7 @@ int mwifiex_enable_hs(struct mwifiex_adapter *adapter) } wait_event_interruptible(adapter->hs_activate_wait_q, - adapter->hs_activate_wait_q_woken); + adapter->hs_activate_wait_q_woken); return true; } @@ -536,7 +534,7 @@ int mwifiex_bss_set_channel(struct mwifiex_private *priv, if (cfp) { if (adapter->adhoc_11n_enabled) adapter->adhoc_start_band = BAND_A - | BAND_AN; + | BAND_AN; else adapter->adhoc_start_band = BAND_A; } @@ -549,7 +547,7 @@ int mwifiex_bss_set_channel(struct mwifiex_private *priv, if (cfp) { if (adapter->adhoc_11n_enabled) adapter->adhoc_start_band = BAND_A - | BAND_AN; + | BAND_AN; else adapter->adhoc_start_band = BAND_A; } @@ -585,7 +583,7 @@ static int mwifiex_bss_ioctl_ibss_channel(struct mwifiex_private *priv, } return mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_RF_CHANNEL, - action, 0, channel); + action, 0, channel); } /* @@ -631,7 +629,7 @@ mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, u16 channel) goto done; } dev_dbg(priv->adapter->dev, "cmd: updating channel from %d to %d\n", - curr_chan, channel); + curr_chan, channel); if (!bss_info.media_connected) { ret = 0; @@ -653,7 +651,8 @@ mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, u16 channel) band = mwifiex_band_to_radio_type(priv->curr_bss_params.band); chan = __ieee80211_get_channel(priv->wdev->wiphy, - ieee80211_channel_to_frequency(channel, band)); + ieee80211_channel_to_frequency(channel, + band)); /* Find the BSS we want using available scan results */ bss = cfg80211_get_bss(priv->wdev->wiphy, chan, bss_info.bssid, @@ -661,7 +660,7 @@ mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, u16 channel) WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS); if (!bss) wiphy_warn(priv->wdev->wiphy, "assoc: bss %pM not in scan results\n", - bss_info.bssid); + bss_info.bssid); ret = mwifiex_bss_start(priv, bss, &bss_info.ssid); done: @@ -790,7 +789,9 @@ int mwifiex_drv_get_data_rate(struct mwifiex_private *priv, if (!ret) { if (rate->is_rate_auto) rate->rate = mwifiex_index_to_data_rate(priv, - priv->tx_rate, priv->tx_htinfo); + priv->tx_rate, + priv->tx_htinfo + ); else rate->rate = priv->data_rate; } else { @@ -827,16 +828,16 @@ int mwifiex_set_tx_power(struct mwifiex_private *priv, if ((dbm < priv->min_tx_power_level) || (dbm > priv->max_tx_power_level)) { dev_err(priv->adapter->dev, "txpower value %d dBm" - " is out of range (%d dBm-%d dBm)\n", - dbm, priv->min_tx_power_level, - priv->max_tx_power_level); + " is out of range (%d dBm-%d dBm)\n", + dbm, priv->min_tx_power_level, + priv->max_tx_power_level); return -1; } } buf = kzalloc(MWIFIEX_SIZE_OF_CMD_BUFFER, GFP_KERNEL); if (!buf) { dev_err(priv->adapter->dev, "%s: failed to alloc cmd buffer\n", - __func__); + __func__); return -ENOMEM; } @@ -844,13 +845,13 @@ int mwifiex_set_tx_power(struct mwifiex_private *priv, txp_cfg->action = cpu_to_le16(HostCmd_ACT_GEN_SET); if (!power_cfg->is_power_auto) { txp_cfg->mode = cpu_to_le32(1); - pg_tlv = (struct mwifiex_types_power_group *) (buf + - sizeof(struct host_cmd_ds_txpwr_cfg)); + pg_tlv = (struct mwifiex_types_power_group *) + (buf + sizeof(struct host_cmd_ds_txpwr_cfg)); pg_tlv->type = TLV_TYPE_POWER_GROUP; pg_tlv->length = 4 * sizeof(struct mwifiex_power_group); - pg = (struct mwifiex_power_group *) (buf + - sizeof(struct host_cmd_ds_txpwr_cfg) + - sizeof(struct mwifiex_types_power_group)); + pg = (struct mwifiex_power_group *) + (buf + sizeof(struct host_cmd_ds_txpwr_cfg) + + sizeof(struct mwifiex_types_power_group)); /* Power group for modulation class HR/DSSS */ pg->first_rate_code = 0x00; pg->last_rate_code = 0x03; @@ -913,8 +914,8 @@ int mwifiex_drv_set_power(struct mwifiex_private *priv, u32 *ps_mode) sub_cmd, BITMAP_STA_PS, NULL); if ((!ret) && (sub_cmd == DIS_AUTO_PS)) ret = mwifiex_send_cmd_async(priv, - HostCmd_CMD_802_11_PS_MODE_ENH, GET_PS, - 0, NULL); + HostCmd_CMD_802_11_PS_MODE_ENH, + GET_PS, 0, NULL); return ret; } @@ -938,7 +939,7 @@ static int mwifiex_set_wpa_ie_helper(struct mwifiex_private *priv, memcpy(priv->wpa_ie, ie_data_ptr, ie_len); priv->wpa_ie_len = (u8) ie_len; dev_dbg(priv->adapter->dev, "cmd: Set Wpa_ie_len=%d IE=%#x\n", - priv->wpa_ie_len, priv->wpa_ie[0]); + priv->wpa_ie_len, priv->wpa_ie[0]); if (priv->wpa_ie[0] == WLAN_EID_WPA) { priv->sec_info.wpa_enabled = true; @@ -979,7 +980,7 @@ static int mwifiex_set_wapi_ie(struct mwifiex_private *priv, memcpy(priv->wapi_ie, ie_data_ptr, ie_len); priv->wapi_ie_len = ie_len; dev_dbg(priv->adapter->dev, "cmd: Set wapi_ie_len=%d IE=%#x\n", - priv->wapi_ie_len, priv->wapi_ie[0]); + priv->wapi_ie_len, priv->wapi_ie[0]); if (priv->wapi_ie[0] == WLAN_EID_BSS_AC_ACCESS_DELAY) priv->sec_info.wapi_enabled = true; @@ -1005,8 +1006,8 @@ static int mwifiex_sec_ioctl_set_wapi_key(struct mwifiex_private *priv, { return mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_KEY_MATERIAL, - HostCmd_ACT_GEN_SET, KEY_INFO_ENABLED, - encrypt_key); + HostCmd_ACT_GEN_SET, KEY_INFO_ENABLED, + encrypt_key); } /* @@ -1100,9 +1101,9 @@ static int mwifiex_sec_ioctl_set_wpa_key(struct mwifiex_private *priv, /* Send the key as PTK to firmware */ encrypt_key->key_index = MWIFIEX_KEY_INDEX_UNICAST; ret = mwifiex_send_cmd_async(priv, - HostCmd_CMD_802_11_KEY_MATERIAL, - HostCmd_ACT_GEN_SET, KEY_INFO_ENABLED, - encrypt_key); + HostCmd_CMD_802_11_KEY_MATERIAL, + HostCmd_ACT_GEN_SET, + KEY_INFO_ENABLED, encrypt_key); if (ret) return ret; @@ -1127,14 +1128,14 @@ static int mwifiex_sec_ioctl_set_wpa_key(struct mwifiex_private *priv, if (remove_key) ret = mwifiex_send_cmd_sync(priv, - HostCmd_CMD_802_11_KEY_MATERIAL, - HostCmd_ACT_GEN_SET, !(KEY_INFO_ENABLED), - encrypt_key); + HostCmd_CMD_802_11_KEY_MATERIAL, + HostCmd_ACT_GEN_SET, + !KEY_INFO_ENABLED, encrypt_key); else ret = mwifiex_send_cmd_sync(priv, - HostCmd_CMD_802_11_KEY_MATERIAL, - HostCmd_ACT_GEN_SET, KEY_INFO_ENABLED, - encrypt_key); + HostCmd_CMD_802_11_KEY_MATERIAL, + HostCmd_ACT_GEN_SET, + KEY_INFO_ENABLED, encrypt_key); return ret; } @@ -1253,7 +1254,7 @@ mwifiex_get_ver_ext(struct mwifiex_private *priv) memset(&ver_ext, 0, sizeof(struct host_cmd_ds_version_ext)); if (mwifiex_send_cmd_sync(priv, HostCmd_CMD_VERSION_EXT, - HostCmd_ACT_GEN_GET, 0, &ver_ext)) + HostCmd_ACT_GEN_GET, 0, &ver_ext)) return -1; return 0; @@ -1270,7 +1271,7 @@ mwifiex_get_stats_info(struct mwifiex_private *priv, struct mwifiex_ds_get_stats *log) { return mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_GET_LOG, - HostCmd_ACT_GEN_GET, 0, log); + HostCmd_ACT_GEN_GET, 0, log); } /* @@ -1410,9 +1411,9 @@ mwifiex_set_gen_ie_helper(struct mwifiex_private *priv, u8 *ie_data_ptr, } pvendor_ie = (struct ieee_types_vendor_header *) ie_data_ptr; /* Test to see if it is a WPA IE, if not, then it is a gen IE */ - if (((pvendor_ie->element_id == WLAN_EID_WPA) - && (!memcmp(pvendor_ie->oui, wpa_oui, sizeof(wpa_oui)))) - || (pvendor_ie->element_id == WLAN_EID_RSN)) { + if (((pvendor_ie->element_id == WLAN_EID_WPA) && + (!memcmp(pvendor_ie->oui, wpa_oui, sizeof(wpa_oui)))) || + (pvendor_ie->element_id == WLAN_EID_RSN)) { /* IE is a WPA/WPA2 IE so call set_wpa function */ ret = mwifiex_set_wpa_ie_helper(priv, ie_data_ptr, ie_len); @@ -1435,9 +1436,8 @@ mwifiex_set_gen_ie_helper(struct mwifiex_private *priv, u8 *ie_data_ptr, * wps session flag */ pvendor_ie = (struct ieee_types_vendor_header *) ie_data_ptr; - if ((pvendor_ie->element_id == WLAN_EID_VENDOR_SPECIFIC) - && (!memcmp(pvendor_ie->oui, wps_oui, - sizeof(wps_oui)))) { + if ((pvendor_ie->element_id == WLAN_EID_VENDOR_SPECIFIC) && + (!memcmp(pvendor_ie->oui, wps_oui, sizeof(wps_oui)))) { priv->wps.session_enable = true; dev_dbg(priv->adapter->dev, "info: WPS Session Enabled.\n"); @@ -1446,7 +1446,7 @@ mwifiex_set_gen_ie_helper(struct mwifiex_private *priv, u8 *ie_data_ptr, /* Append the passed data to the end of the genIeBuffer */ memcpy(priv->gen_ie_buf + priv->gen_ie_buf_len, ie_data_ptr, - ie_len); + ie_len); /* Increment the stored buffer length by the size passed */ priv->gen_ie_buf_len += ie_len; @@ -1490,7 +1490,7 @@ static int mwifiex_misc_ioctl_gen_ie(struct mwifiex_private *priv, return -1; } else { memcpy(adapter->arp_filter, gen_ie->ie_data, - gen_ie->len); + gen_ie->len); adapter->arp_filter_size = gen_ie->len; } break; -- cgit From c65a30f35f938b421ac67c34a9e70b0e49e6019a Mon Sep 17 00:00:00 2001 From: Yogesh Ashok Powar Date: Tue, 13 Mar 2012 19:22:42 -0700 Subject: mwifiex: fix checkpatch --strict warnings/errors Part 9 For files sta_rx.c, sta_tx.c, txrx.c, util.c and wmm.c Signed-off-by: Yogesh Ashok Powar Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/sta_rx.c | 12 ++-- drivers/net/wireless/mwifiex/sta_tx.c | 22 +++--- drivers/net/wireless/mwifiex/txrx.c | 13 ++-- drivers/net/wireless/mwifiex/util.c | 20 +++--- drivers/net/wireless/mwifiex/wmm.c | 122 +++++++++++++++++----------------- 5 files changed, 94 insertions(+), 95 deletions(-) diff --git a/drivers/net/wireless/mwifiex/sta_rx.c b/drivers/net/wireless/mwifiex/sta_rx.c index d7a5d7616f22..750b695aca12 100644 --- a/drivers/net/wireless/mwifiex/sta_rx.c +++ b/drivers/net/wireless/mwifiex/sta_rx.c @@ -43,8 +43,9 @@ int mwifiex_process_rx_packet(struct mwifiex_adapter *adapter, { int ret; struct mwifiex_rxinfo *rx_info = MWIFIEX_SKB_RXCB(skb); - struct mwifiex_private *priv = mwifiex_get_priv_by_id(adapter, - rx_info->bss_num, rx_info->bss_type); + struct mwifiex_private *priv = + mwifiex_get_priv_by_id(adapter, rx_info->bss_num, + rx_info->bss_type); struct rx_packet_hdr *rx_pkt_hdr; struct rxpd *local_rx_pd; int hdr_chop; @@ -125,8 +126,9 @@ int mwifiex_process_sta_rx_packet(struct mwifiex_adapter *adapter, struct rx_packet_hdr *rx_pkt_hdr; u8 ta[ETH_ALEN]; u16 rx_pkt_type; - struct mwifiex_private *priv = mwifiex_get_priv_by_id(adapter, - rx_info->bss_num, rx_info->bss_type); + struct mwifiex_private *priv = + mwifiex_get_priv_by_id(adapter, rx_info->bss_num, + rx_info->bss_type); if (!priv) return -1; @@ -157,7 +159,7 @@ int mwifiex_process_sta_rx_packet(struct mwifiex_adapter *adapter, skb_trim(skb, local_rx_pd->rx_pkt_length); ieee80211_amsdu_to_8023s(skb, &list, priv->curr_addr, - priv->wdev->iftype, 0, false); + priv->wdev->iftype, 0, false); while (!skb_queue_empty(&list)) { rx_skb = __skb_dequeue(&list); diff --git a/drivers/net/wireless/mwifiex/sta_tx.c b/drivers/net/wireless/mwifiex/sta_tx.c index 94d31a94620a..7af534feb420 100644 --- a/drivers/net/wireless/mwifiex/sta_tx.c +++ b/drivers/net/wireless/mwifiex/sta_tx.c @@ -50,8 +50,7 @@ void *mwifiex_process_sta_txpd(struct mwifiex_private *priv, u8 pad; if (!skb->len) { - dev_err(adapter->dev, "Tx: bad packet length: %d\n", - skb->len); + dev_err(adapter->dev, "Tx: bad packet length: %d\n", skb->len); tx_info->status_code = -1; return skb->data; } @@ -60,19 +59,20 @@ void *mwifiex_process_sta_txpd(struct mwifiex_private *priv, pad = (4 - (((void *)skb->data - NULL) & 0x3)) % 4; BUG_ON(skb_headroom(skb) < (sizeof(*local_tx_pd) + INTF_HEADER_LEN - + pad)); + + pad)); skb_push(skb, sizeof(*local_tx_pd) + pad); local_tx_pd = (struct txpd *) skb->data; memset(local_tx_pd, 0, sizeof(struct txpd)); local_tx_pd->bss_num = priv->bss_num; local_tx_pd->bss_type = priv->bss_type; - local_tx_pd->tx_pkt_length = cpu_to_le16((u16) (skb->len - - (sizeof(struct txpd) + pad))); + local_tx_pd->tx_pkt_length = cpu_to_le16((u16)(skb->len - + (sizeof(struct txpd) + + pad))); local_tx_pd->priority = (u8) skb->priority; local_tx_pd->pkt_delay_2ms = - mwifiex_wmm_compute_drv_pkt_delay(priv, skb); + mwifiex_wmm_compute_drv_pkt_delay(priv, skb); if (local_tx_pd->priority < ARRAY_SIZE(priv->wmm.user_pri_pkt_tx_ctrl)) @@ -82,7 +82,7 @@ void *mwifiex_process_sta_txpd(struct mwifiex_private *priv, */ local_tx_pd->tx_control = cpu_to_le32(priv->wmm.user_pri_pkt_tx_ctrl[local_tx_pd-> - priority]); + priority]); if (adapter->pps_uapsd_mode) { if (mwifiex_check_last_packet_indication(priv)) { @@ -160,13 +160,13 @@ int mwifiex_send_null_packet(struct mwifiex_private *priv, u8 flags) case -1: dev_kfree_skb_any(skb); dev_err(adapter->dev, "%s: host_to_card failed: ret=%d\n", - __func__, ret); + __func__, ret); adapter->dbg.num_tx_host_to_card_failure++; break; case 0: dev_kfree_skb_any(skb); dev_dbg(adapter->dev, "data: %s: host_to_card succeeded\n", - __func__); + __func__); adapter->tx_lock_flag = true; break; case -EINPROGRESS: @@ -192,8 +192,8 @@ mwifiex_check_last_packet_indication(struct mwifiex_private *priv) if (mwifiex_wmm_lists_empty(adapter)) ret = true; - if (ret && !adapter->cmd_sent && !adapter->curr_cmd - && !is_command_pending(adapter)) { + if (ret && !adapter->cmd_sent && !adapter->curr_cmd && + !is_command_pending(adapter)) { adapter->delay_null_pkt = false; ret = true; } else { diff --git a/drivers/net/wireless/mwifiex/txrx.c b/drivers/net/wireless/mwifiex/txrx.c index 9a6eacc9d6f9..d2af8cb98541 100644 --- a/drivers/net/wireless/mwifiex/txrx.c +++ b/drivers/net/wireless/mwifiex/txrx.c @@ -85,8 +85,7 @@ int mwifiex_process_tx(struct mwifiex_private *priv, struct sk_buff *skb, switch (ret) { case -EBUSY: if ((GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA) && - (adapter->pps_uapsd_mode) && - (adapter->tx_lock_flag)) { + (adapter->pps_uapsd_mode) && (adapter->tx_lock_flag)) { priv->adapter->tx_lock_flag = false; if (local_tx_pd) local_tx_pd->flags = 0; @@ -96,7 +95,7 @@ int mwifiex_process_tx(struct mwifiex_private *priv, struct sk_buff *skb, case -1: adapter->data_sent = false; dev_err(adapter->dev, "mwifiex_write_data_async failed: 0x%X\n", - ret); + ret); adapter->dbg.num_tx_host_to_card_failure++; mwifiex_write_data_complete(adapter, skb, ret); break; @@ -132,7 +131,7 @@ int mwifiex_write_data_complete(struct mwifiex_adapter *adapter, tx_info = MWIFIEX_SKB_TXCB(skb); priv = mwifiex_get_priv_by_id(adapter, tx_info->bss_num, - tx_info->bss_type); + tx_info->bss_type); if (!priv) goto done; @@ -151,11 +150,11 @@ int mwifiex_write_data_complete(struct mwifiex_adapter *adapter, tpriv = adapter->priv[i]; - if ((GET_BSS_ROLE(tpriv) == MWIFIEX_BSS_ROLE_STA) - && (tpriv->media_connected)) { + if ((GET_BSS_ROLE(tpriv) == MWIFIEX_BSS_ROLE_STA) && + (tpriv->media_connected)) { if (netif_queue_stopped(tpriv->netdev)) mwifiex_wake_up_net_dev_queue(tpriv->netdev, - adapter); + adapter); } } done: diff --git a/drivers/net/wireless/mwifiex/util.c b/drivers/net/wireless/mwifiex/util.c index 9c48f37069f7..6b399976d6c8 100644 --- a/drivers/net/wireless/mwifiex/util.c +++ b/drivers/net/wireless/mwifiex/util.c @@ -93,10 +93,10 @@ int mwifiex_get_debug_info(struct mwifiex_private *priv, sizeof(priv->wmm.packets_out)); info->max_tx_buf_size = (u32) adapter->max_tx_buf_size; info->tx_buf_size = (u32) adapter->tx_buf_size; - info->rx_tbl_num = mwifiex_get_rx_reorder_tbl( - priv, info->rx_tbl); - info->tx_tbl_num = mwifiex_get_tx_ba_stream_tbl( - priv, info->tx_tbl); + info->rx_tbl_num = mwifiex_get_rx_reorder_tbl(priv, + info->rx_tbl); + info->tx_tbl_num = mwifiex_get_tx_ba_stream_tbl(priv, + info->tx_tbl); info->ps_mode = adapter->ps_mode; info->ps_state = adapter->ps_state; info->is_deep_sleep = adapter->is_deep_sleep; @@ -105,19 +105,19 @@ int mwifiex_get_debug_info(struct mwifiex_private *priv, info->is_hs_configured = adapter->is_hs_configured; info->hs_activated = adapter->hs_activated; info->num_cmd_host_to_card_failure - = adapter->dbg.num_cmd_host_to_card_failure; + = adapter->dbg.num_cmd_host_to_card_failure; info->num_cmd_sleep_cfm_host_to_card_failure = adapter->dbg.num_cmd_sleep_cfm_host_to_card_failure; info->num_tx_host_to_card_failure - = adapter->dbg.num_tx_host_to_card_failure; + = adapter->dbg.num_tx_host_to_card_failure; info->num_event_deauth = adapter->dbg.num_event_deauth; info->num_event_disassoc = adapter->dbg.num_event_disassoc; info->num_event_link_lost = adapter->dbg.num_event_link_lost; info->num_cmd_deauth = adapter->dbg.num_cmd_deauth; info->num_cmd_assoc_success = - adapter->dbg.num_cmd_assoc_success; + adapter->dbg.num_cmd_assoc_success; info->num_cmd_assoc_failure = - adapter->dbg.num_cmd_assoc_failure; + adapter->dbg.num_cmd_assoc_failure; info->num_tx_timeout = adapter->dbg.num_tx_timeout; info->num_cmd_timeout = adapter->dbg.num_cmd_timeout; info->timeout_cmd_id = adapter->dbg.timeout_cmd_id; @@ -160,7 +160,7 @@ int mwifiex_recv_packet(struct mwifiex_adapter *adapter, struct sk_buff *skb) rx_info = MWIFIEX_SKB_RXCB(skb); priv = mwifiex_get_priv_by_id(adapter, rx_info->bss_num, - rx_info->bss_type); + rx_info->bss_type); if (!priv) return -1; @@ -191,7 +191,7 @@ int mwifiex_complete_cmd(struct mwifiex_adapter *adapter, { atomic_dec(&adapter->cmd_pending); dev_dbg(adapter->dev, "cmd completed: status=%d\n", - adapter->cmd_wait_q.status); + adapter->cmd_wait_q.status); *(cmd_node->condition) = true; diff --git a/drivers/net/wireless/mwifiex/wmm.c b/drivers/net/wireless/mwifiex/wmm.c index 6f0cc210f79a..5a7316c6f125 100644 --- a/drivers/net/wireless/mwifiex/wmm.c +++ b/drivers/net/wireless/mwifiex/wmm.c @@ -87,15 +87,15 @@ mwifiex_wmm_ac_debug_print(const struct ieee_types_wmm_ac_parameters *ac_param) const char *ac_str[] = { "BK", "BE", "VI", "VO" }; pr_debug("info: WMM AC_%s: ACI=%d, ACM=%d, Aifsn=%d, " - "EcwMin=%d, EcwMax=%d, TxopLimit=%d\n", - ac_str[wmm_aci_to_qidx_map[(ac_param->aci_aifsn_bitmap - & MWIFIEX_ACI) >> 5]], - (ac_param->aci_aifsn_bitmap & MWIFIEX_ACI) >> 5, - (ac_param->aci_aifsn_bitmap & MWIFIEX_ACM) >> 4, - ac_param->aci_aifsn_bitmap & MWIFIEX_AIFSN, - ac_param->ecw_bitmap & MWIFIEX_ECW_MIN, - (ac_param->ecw_bitmap & MWIFIEX_ECW_MAX) >> 4, - le16_to_cpu(ac_param->tx_op_limit)); + "EcwMin=%d, EcwMax=%d, TxopLimit=%d\n", + ac_str[wmm_aci_to_qidx_map[(ac_param->aci_aifsn_bitmap + & MWIFIEX_ACI) >> 5]], + (ac_param->aci_aifsn_bitmap & MWIFIEX_ACI) >> 5, + (ac_param->aci_aifsn_bitmap & MWIFIEX_ACM) >> 4, + ac_param->aci_aifsn_bitmap & MWIFIEX_AIFSN, + ac_param->ecw_bitmap & MWIFIEX_ECW_MIN, + (ac_param->ecw_bitmap & MWIFIEX_ECW_MAX) >> 4, + le16_to_cpu(ac_param->tx_op_limit)); } /* @@ -112,7 +112,7 @@ mwifiex_wmm_allocate_ralist_node(struct mwifiex_adapter *adapter, u8 *ra) if (!ra_list) { dev_err(adapter->dev, "%s: failed to alloc ra_list\n", - __func__); + __func__); return NULL; } INIT_LIST_HEAD(&ra_list->list); @@ -154,7 +154,7 @@ mwifiex_ralist_add(struct mwifiex_private *priv, u8 *ra) ra_list, ra_list->is_11n_enabled); list_add_tail(&ra_list->list, - &priv->wmm.tid_tbl_ptr[i].ra_list); + &priv->wmm.tid_tbl_ptr[i].ra_list); if (!priv->wmm.tid_tbl_ptr[i].ra_list_curr) priv->wmm.tid_tbl_ptr[i].ra_list_curr = ra_list; @@ -217,22 +217,19 @@ mwifiex_wmm_setup_queue_priorities(struct mwifiex_private *priv, wmm_ie->reserved); for (num_ac = 0; num_ac < ARRAY_SIZE(wmm_ie->ac_params); num_ac++) { - cw_min = (1 << (wmm_ie->ac_params[num_ac].ecw_bitmap & - MWIFIEX_ECW_MIN)) - 1; - avg_back_off = (cw_min >> 1) + - (wmm_ie->ac_params[num_ac].aci_aifsn_bitmap & - MWIFIEX_AIFSN); - - ac_idx = wmm_aci_to_qidx_map[(wmm_ie->ac_params[num_ac]. - aci_aifsn_bitmap & - MWIFIEX_ACI) >> 5]; + u8 ecw = wmm_ie->ac_params[num_ac].ecw_bitmap; + u8 aci_aifsn = wmm_ie->ac_params[num_ac].aci_aifsn_bitmap; + cw_min = (1 << (ecw & MWIFIEX_ECW_MIN)) - 1; + avg_back_off = (cw_min >> 1) + (aci_aifsn & MWIFIEX_AIFSN); + + ac_idx = wmm_aci_to_qidx_map[(aci_aifsn & MWIFIEX_ACI) >> 5]; priv->wmm.queue_priority[ac_idx] = ac_idx; tmp[ac_idx] = avg_back_off; - dev_dbg(priv->adapter->dev, "info: WMM: CWmax=%d CWmin=%d Avg Back-off=%d\n", - (1 << ((wmm_ie->ac_params[num_ac].ecw_bitmap & - MWIFIEX_ECW_MAX) >> 4)) - 1, - cw_min, avg_back_off); + dev_dbg(priv->adapter->dev, + "info: WMM: CWmax=%d CWmin=%d Avg Back-off=%d\n", + (1 << ((ecw & MWIFIEX_ECW_MAX) >> 4)) - 1, + cw_min, avg_back_off); mwifiex_wmm_ac_debug_print(&wmm_ie->ac_params[num_ac]); } @@ -312,13 +309,14 @@ mwifiex_wmm_setup_ac_downgrade(struct mwifiex_private *priv) /* WMM is not enabled, default priorities */ for (ac_val = WMM_AC_BK; ac_val <= WMM_AC_VO; ac_val++) priv->wmm.ac_down_graded_vals[ac_val] = - (enum mwifiex_wmm_ac_e) ac_val; + (enum mwifiex_wmm_ac_e) ac_val; } else { for (ac_val = WMM_AC_BK; ac_val <= WMM_AC_VO; ac_val++) { priv->wmm.ac_down_graded_vals[ac_val] = mwifiex_wmm_eval_downgrade_ac(priv, (enum mwifiex_wmm_ac_e) ac_val); - dev_dbg(priv->adapter->dev, "info: WMM: AC PRIO %d maps to %d\n", + dev_dbg(priv->adapter->dev, + "info: WMM: AC PRIO %d maps to %d\n", ac_val, priv->wmm.ac_down_graded_vals[ac_val]); } } @@ -394,13 +392,13 @@ mwifiex_wmm_init(struct mwifiex_adapter *adapter) } priv->aggr_prio_tbl[6].amsdu - = priv->aggr_prio_tbl[6].ampdu_ap - = priv->aggr_prio_tbl[6].ampdu_user - = BA_STREAM_NOT_ALLOWED; + = priv->aggr_prio_tbl[6].ampdu_ap + = priv->aggr_prio_tbl[6].ampdu_user + = BA_STREAM_NOT_ALLOWED; priv->aggr_prio_tbl[7].amsdu = priv->aggr_prio_tbl[7].ampdu_ap - = priv->aggr_prio_tbl[7].ampdu_user - = BA_STREAM_NOT_ALLOWED; + = priv->aggr_prio_tbl[7].ampdu_user + = BA_STREAM_NOT_ALLOWED; priv->add_ba_param.timeout = MWIFIEX_DEFAULT_BLOCK_ACK_TIMEOUT; priv->add_ba_param.tx_win_size = MWIFIEX_AMPDU_DEF_TXWINSIZE; @@ -472,7 +470,7 @@ static void mwifiex_wmm_cleanup_queues(struct mwifiex_private *priv) for (i = 0; i < MAX_NUM_TID; i++) mwifiex_wmm_del_pkts_in_ralist(priv, &priv->wmm.tid_tbl_ptr[i]. - ra_list); + ra_list); atomic_set(&priv->wmm.tx_pkts_queued, 0); atomic_set(&priv->wmm.highest_queued_prio, HIGH_PRIO_TID); @@ -488,9 +486,10 @@ static void mwifiex_wmm_delete_all_ralist(struct mwifiex_private *priv) for (i = 0; i < MAX_NUM_TID; ++i) { dev_dbg(priv->adapter->dev, - "info: ra_list: freeing buf for tid %d\n", i); + "info: ra_list: freeing buf for tid %d\n", i); list_for_each_entry_safe(ra_list, tmp_node, - &priv->wmm.tid_tbl_ptr[i].ra_list, list) { + &priv->wmm.tid_tbl_ptr[i].ra_list, + list) { list_del(&ra_list->list); kfree(ra_list); } @@ -652,7 +651,7 @@ mwifiex_wmm_add_buf_txqueue(struct mwifiex_private *priv, if (atomic_read(&priv->wmm.highest_queued_prio) < tos_to_tid_inv[tid_down]) atomic_set(&priv->wmm.highest_queued_prio, - tos_to_tid_inv[tid_down]); + tos_to_tid_inv[tid_down]); spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, flags); } @@ -681,7 +680,7 @@ int mwifiex_ret_wmm_get_status(struct mwifiex_private *priv, struct mwifiex_wmm_ac_status *ac_status; dev_dbg(priv->adapter->dev, "info: WMM: WMM_GET_STATUS cmdresp received: %d\n", - resp_len); + resp_len); while ((resp_len >= sizeof(tlv_hdr->header)) && valid) { tlv_hdr = (struct mwifiex_ie_types_data *) curr; @@ -695,15 +694,15 @@ int mwifiex_ret_wmm_get_status(struct mwifiex_private *priv, dev_dbg(priv->adapter->dev, "info: CMD_RESP: WMM_GET_STATUS:" " QSTATUS TLV: %d, %d, %d\n", - tlv_wmm_qstatus->queue_index, - tlv_wmm_qstatus->flow_required, - tlv_wmm_qstatus->disabled); + tlv_wmm_qstatus->queue_index, + tlv_wmm_qstatus->flow_required, + tlv_wmm_qstatus->disabled); ac_status = &priv->wmm.ac_status[tlv_wmm_qstatus-> queue_index]; ac_status->disabled = tlv_wmm_qstatus->disabled; ac_status->flow_required = - tlv_wmm_qstatus->flow_required; + tlv_wmm_qstatus->flow_required; ac_status->flow_created = tlv_wmm_qstatus->flow_created; break; @@ -772,29 +771,27 @@ mwifiex_wmm_process_association_req(struct mwifiex_private *priv, if (!wmm_ie) return 0; - dev_dbg(priv->adapter->dev, "info: WMM: process assoc req:" - "bss->wmmIe=0x%x\n", - wmm_ie->vend_hdr.element_id); + dev_dbg(priv->adapter->dev, + "info: WMM: process assoc req: bss->wmm_ie=%#x\n", + wmm_ie->vend_hdr.element_id); - if ((priv->wmm_required - || (ht_cap && (priv->adapter->config_bands & BAND_GN - || priv->adapter->config_bands & BAND_AN)) - ) - && wmm_ie->vend_hdr.element_id == WLAN_EID_VENDOR_SPECIFIC) { + if ((priv->wmm_required || + (ht_cap && (priv->adapter->config_bands & BAND_GN || + priv->adapter->config_bands & BAND_AN))) && + wmm_ie->vend_hdr.element_id == WLAN_EID_VENDOR_SPECIFIC) { wmm_tlv = (struct mwifiex_ie_types_wmm_param_set *) *assoc_buf; wmm_tlv->header.type = cpu_to_le16((u16) wmm_info_ie[0]); wmm_tlv->header.len = cpu_to_le16((u16) wmm_info_ie[1]); memcpy(wmm_tlv->wmm_ie, &wmm_info_ie[2], - le16_to_cpu(wmm_tlv->header.len)); + le16_to_cpu(wmm_tlv->header.len)); if (wmm_ie->qos_info_bitmap & IEEE80211_WMM_IE_AP_QOSINFO_UAPSD) memcpy((u8 *) (wmm_tlv->wmm_ie - + le16_to_cpu(wmm_tlv->header.len) - - sizeof(priv->wmm_qosinfo)), - &priv->wmm_qosinfo, - sizeof(priv->wmm_qosinfo)); + + le16_to_cpu(wmm_tlv->header.len) + - sizeof(priv->wmm_qosinfo)), + &priv->wmm_qosinfo, sizeof(priv->wmm_qosinfo)); ret_len = sizeof(wmm_tlv->header) - + le16_to_cpu(wmm_tlv->header.len); + + le16_to_cpu(wmm_tlv->header.len); *assoc_buf += ret_len; } @@ -813,7 +810,7 @@ mwifiex_wmm_process_association_req(struct mwifiex_private *priv, */ u8 mwifiex_wmm_compute_drv_pkt_delay(struct mwifiex_private *priv, - const struct sk_buff *skb) + const struct sk_buff *skb) { u8 ret_val; struct timeval out_tstamp, in_tstamp; @@ -857,11 +854,11 @@ mwifiex_wmm_get_highest_priolist_ptr(struct mwifiex_adapter *adapter, for (j = adapter->priv_num - 1; j >= 0; --j) { spin_lock_irqsave(&adapter->bss_prio_tbl[j].bss_prio_lock, - flags); + flags); is_list_empty = list_empty(&adapter->bss_prio_tbl[j] - .bss_prio_head); + .bss_prio_head); spin_unlock_irqrestore(&adapter->bss_prio_tbl[j].bss_prio_lock, - flags); + flags); if (is_list_empty) continue; @@ -1210,10 +1207,11 @@ mwifiex_dequeue_tx_packet(struct mwifiex_adapter *adapter) return 0; } - if (!ptr->is_11n_enabled || mwifiex_is_ba_stream_setup(priv, ptr, tid) - || ((priv->sec_info.wpa_enabled - || priv->sec_info.wpa2_enabled) && !priv->wpa_is_gtk_set) - ) { + if (!ptr->is_11n_enabled || + mwifiex_is_ba_stream_setup(priv, ptr, tid) || + ((priv->sec_info.wpa_enabled || + priv->sec_info.wpa2_enabled) && + !priv->wpa_is_gtk_set)) { mwifiex_send_single_packet(priv, ptr, ptr_index, flags); /* ra_list_spinlock has been freed in mwifiex_send_single_packet() */ -- cgit From b093863edd20b64fa444b770a8701ddcbe9faea1 Mon Sep 17 00:00:00 2001 From: Amitkumar Karwar Date: Tue, 13 Mar 2012 19:36:49 -0700 Subject: mwifiex: correction in structure name passed to sizeof() "hscfg" is declared as struct mwifiex_ds_hs_cfg. Use same structure name for calculating it's size. Signed-off-by: Amitkumar Karwar Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/sta_ioctl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/mwifiex/sta_ioctl.c b/drivers/net/wireless/mwifiex/sta_ioctl.c index 64e0b1010850..d7b11defafe0 100644 --- a/drivers/net/wireless/mwifiex/sta_ioctl.c +++ b/drivers/net/wireless/mwifiex/sta_ioctl.c @@ -425,7 +425,7 @@ int mwifiex_enable_hs(struct mwifiex_adapter *adapter) adapter->hs_activate_wait_q_woken = false; - memset(&hscfg, 0, sizeof(struct mwifiex_hs_config_param)); + memset(&hscfg, 0, sizeof(struct mwifiex_ds_hs_cfg)); hscfg.is_invoke_hostcmd = true; if (mwifiex_set_hs_params(mwifiex_get_priv(adapter, -- cgit From 9d4f09b80fb69985eca86aaf4df195b80e3d02a8 Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Wed, 14 Mar 2012 08:56:47 +0100 Subject: rt2x00: Set IEEE80211_HW_REPORTS_TX_ACK_STATUS in rt2800 rt2800 already reports the tx ack status of each frame back to mac80211. Advertise this by setting IEEE80211_HW_REPORTS_TX_ACK_STATUS for rt2800. This allows some mac80211 features like frame loss notifications to work with rt2800. Signed-off-by: Helmut Schaa Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800lib.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 474b5b9e6238..6c0a12ea6a15 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -4500,7 +4500,9 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_SUPPORTS_PS | IEEE80211_HW_PS_NULLFUNC_STACK | - IEEE80211_HW_AMPDU_AGGREGATION; + IEEE80211_HW_AMPDU_AGGREGATION | + IEEE80211_HW_REPORTS_TX_ACK_STATUS; + /* * Don't set IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING for USB devices * unless we are capable of sending the buffered frames out after the -- cgit From bf106e14735d5e82e995c5c03bf07bce54e5d530 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Wed, 14 Mar 2012 14:40:20 +0530 Subject: ath9k: Remove unnecessary initialization There is no need to mask out SWBA/BMISS from the interrupt mask in start(). Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/main.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 4a9901090811..db38a4e5a6e3 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -1049,9 +1049,6 @@ static int ath9k_start(struct ieee80211_hw *hw) sc->sc_flags &= ~SC_OP_INVALID; sc->sc_ah->is_monitoring = false; - /* Disable BMISS interrupt when we're not associated */ - ah->imask &= ~(ATH9K_INT_SWBA | ATH9K_INT_BMISS); - if (!ath_complete_reset(sc, false)) { r = -EIO; spin_unlock_bh(&sc->sc_pcu_lock); -- cgit From 62450b88032287db805ba54de142e58052a98090 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Wed, 14 Mar 2012 14:40:31 +0530 Subject: ath9k: Remove unused variables Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 2 -- drivers/net/wireless/ath/ath9k/main.c | 4 ---- 2 files changed, 6 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 3d8e51cd5d8f..fa5eb3080e24 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -624,8 +624,6 @@ struct ath_softc { struct ieee80211_hw *hw; struct device *dev; - int chan_idx; - int chan_is_ht; struct survey_info *cur_survey; struct survey_info survey[ATH9K_NUM_CHANNELS]; diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index db38a4e5a6e3..fe1d7961eefd 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -995,12 +995,8 @@ static int ath9k_start(struct ieee80211_hw *hw) curchan->center_freq); ath9k_ps_wakeup(sc); - mutex_lock(&sc->mutex); - /* setup initial channel */ - sc->chan_idx = curchan->hw_value; - init_channel = ath9k_cmn_get_curchannel(hw, ah); /* Reset SERDES registers */ -- cgit From bcf6f96e192d71864685ba7253c94c2002615875 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Wed, 14 Mar 2012 14:40:38 +0530 Subject: ath9k: Remove 'other' VIF count It is not needed and will not be used anyway since unsupported interfaces are not allowed to be created. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 1 - drivers/net/wireless/ath/ath9k/debug.c | 4 ++-- drivers/net/wireless/ath/ath9k/main.c | 1 - 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index fa5eb3080e24..419bf4e4dc73 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -617,7 +617,6 @@ struct ath9k_vif_iter_data { int nstations; /* number of station vifs */ int nwds; /* number of WDS vifs */ int nadhocs; /* number of adhoc vifs */ - int nothers; /* number of vifs not specified above. */ }; struct ath_softc { diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c index c2edf688da49..35d1c8e91d1c 100644 --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c @@ -738,9 +738,9 @@ static ssize_t read_file_misc(struct file *file, char __user *user_buf, len += snprintf(buf + len, sizeof(buf) - len, "VIF-COUNTS: AP: %i STA: %i MESH: %i WDS: %i" - " ADHOC: %i OTHER: %i TOTAL: %hi BEACON-VIF: %hi\n", + " ADHOC: %i TOTAL: %hi BEACON-VIF: %hi\n", iter_data.naps, iter_data.nstations, iter_data.nmeshes, - iter_data.nwds, iter_data.nadhocs, iter_data.nothers, + iter_data.nwds, iter_data.nadhocs, sc->nvifs, sc->nbcnvifs); if (len > sizeof(buf)) diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index fe1d7961eefd..77c61bcd34ea 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -1272,7 +1272,6 @@ static void ath9k_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif) iter_data->nwds++; break; default: - iter_data->nothers++; break; } } -- cgit From caed6579c2f9756d3f5a95e8186fa4c04d64cae2 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Wed, 14 Mar 2012 14:40:46 +0530 Subject: ath9k_hw: Cleanup FastChannelChange The logic to determine whether to use FCC is a bit convoluted. Use a small helper function to decide whether FCC is to be used. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hw.c | 104 ++++++++++++++++++++++++---------- drivers/net/wireless/ath/ath9k/hw.h | 2 +- drivers/net/wireless/ath/ath9k/main.c | 4 -- 3 files changed, 74 insertions(+), 36 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 02cc1ce3dd6a..780ecd8aff6e 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -1521,17 +1521,81 @@ bool ath9k_hw_check_alive(struct ath_hw *ah) } EXPORT_SYMBOL(ath9k_hw_check_alive); +/* + * Fast channel change: + * (Change synthesizer based on channel freq without resetting chip) + * + * Don't do FCC when + * - Flag is not set + * - Chip is just coming out of full sleep + * - Channel to be set is same as current channel + * - Channel flags are different, (eg.,moving from 2GHz to 5GHz channel) + */ +static int ath9k_hw_do_fastcc(struct ath_hw *ah, struct ath9k_channel *chan) +{ + struct ath_common *common = ath9k_hw_common(ah); + int ret; + + if (AR_SREV_9280(ah) && common->bus_ops->ath_bus_type == ATH_PCI) + goto fail; + + if (ah->chip_fullsleep) + goto fail; + + if (!ah->curchan) + goto fail; + + if (chan->channel == ah->curchan->channel) + goto fail; + + if ((chan->channelFlags & CHANNEL_ALL) != + (ah->curchan->channelFlags & CHANNEL_ALL)) + goto fail; + + if (!ath9k_hw_check_alive(ah)) + goto fail; + + /* + * For AR9462, make sure that calibration data for + * re-using are present. + */ + if (AR_SREV_9462(ah) && (!ah->caldata || + !ah->caldata->done_txiqcal_once || + !ah->caldata->done_txclcal_once || + !ah->caldata->rtt_hist.num_readings)) + goto fail; + + ath_dbg(common, RESET, "FastChannelChange for %d -> %d\n", + ah->curchan->channel, chan->channel); + + ret = ath9k_hw_channel_change(ah, chan); + if (!ret) + goto fail; + + ath9k_hw_loadnf(ah, ah->curchan); + ath9k_hw_start_nfcal(ah, true); + + if ((ah->caps.hw_caps & ATH9K_HW_CAP_MCI) && ar9003_mci_is_ready(ah)) + ar9003_mci_2g5g_switch(ah, true); + + if (AR_SREV_9271(ah)) + ar9002_hw_load_ani_reg(ah, chan); + + return 0; +fail: + return -EINVAL; +} + int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, - struct ath9k_hw_cal_data *caldata, bool bChannelChange) + struct ath9k_hw_cal_data *caldata, bool fastcc) { struct ath_common *common = ath9k_hw_common(ah); u32 saveLedState; - struct ath9k_channel *curchan = ah->curchan; u32 saveDefAntenna; u32 macStaId1; u64 tsf = 0; int i, r; - bool allow_fbs = false, start_mci_reset = false; + bool start_mci_reset = false; bool mci = !!(ah->caps.hw_caps & ATH9K_HW_CAP_MCI); bool save_fullsleep = ah->chip_fullsleep; @@ -1544,8 +1608,8 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) return -EIO; - if (curchan && !ah->chip_fullsleep) - ath9k_hw_getnf(ah, curchan); + if (ah->curchan && !ah->chip_fullsleep) + ath9k_hw_getnf(ah, ah->curchan); ah->caldata = caldata; if (caldata && @@ -1558,32 +1622,10 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, } ah->noise = ath9k_hw_getchan_noise(ah, chan); - if (AR_SREV_9280(ah) && common->bus_ops->ath_bus_type == ATH_PCI) - bChannelChange = false; - - if (caldata && - caldata->done_txiqcal_once && - caldata->done_txclcal_once && - caldata->rtt_hist.num_readings) - allow_fbs = true; - - if (bChannelChange && - (ah->chip_fullsleep != true) && - (ah->curchan != NULL) && - (chan->channel != ah->curchan->channel) && - (allow_fbs || - ((chan->channelFlags & CHANNEL_ALL) == - (ah->curchan->channelFlags & CHANNEL_ALL)))) { - if (ath9k_hw_channel_change(ah, chan)) { - ath9k_hw_loadnf(ah, ah->curchan); - ath9k_hw_start_nfcal(ah, true); - if (mci && ar9003_mci_is_ready(ah)) - ar9003_mci_2g5g_switch(ah, true); - - if (AR_SREV_9271(ah)) - ar9002_hw_load_ani_reg(ah, chan); - return 0; - } + if (fastcc) { + r = ath9k_hw_do_fastcc(ah, chan); + if (!r) + return r; } if (mci) diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index 1707137e0a30..23c8dfae29f7 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -924,7 +924,7 @@ const char *ath9k_hw_probe(u16 vendorid, u16 devid); void ath9k_hw_deinit(struct ath_hw *ah); int ath9k_hw_init(struct ath_hw *ah); int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, - struct ath9k_hw_cal_data *caldata, bool bChannelChange); + struct ath9k_hw_cal_data *caldata, bool fastcc); int ath9k_hw_fill_cap_info(struct ath_hw *ah); u32 ath9k_regd_get_ctl(struct ath_regulatory *reg, struct ath9k_channel *chan); diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 77c61bcd34ea..a07565c730b7 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -334,10 +334,6 @@ static int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan, hchan = ah->curchan; } - if (fastcc && (ah->chip_fullsleep || - !ath9k_hw_check_alive(ah))) - fastcc = false; - if (!ath_prepare_reset(sc, retry_tx, flush)) fastcc = false; -- cgit From 3d4e20f2d1e720c63887aee6a985e7870baf4ba1 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Wed, 14 Mar 2012 14:40:58 +0530 Subject: ath9k: Remove aggregation flags SC_OP_TXAGGR and SC_OP_RXAGGR are not really needed. The HT capabilities of the station and HW can be used instead. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 24 +++++++++++------------- drivers/net/wireless/ath/ath9k/init.c | 9 +-------- drivers/net/wireless/ath/ath9k/main.c | 12 ++++-------- drivers/net/wireless/ath/ath9k/rc.c | 9 ++++----- drivers/net/wireless/ath/ath9k/xmit.c | 21 +++++++++------------ 5 files changed, 29 insertions(+), 46 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 419bf4e4dc73..5ecec83117d6 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -583,19 +583,17 @@ struct ath_ant_comb { #define SC_OP_INVALID BIT(0) #define SC_OP_BEACONS BIT(1) -#define SC_OP_RXAGGR BIT(2) -#define SC_OP_TXAGGR BIT(3) -#define SC_OP_OFFCHANNEL BIT(4) -#define SC_OP_PREAMBLE_SHORT BIT(5) -#define SC_OP_PROTECT_ENABLE BIT(6) -#define SC_OP_RXFLUSH BIT(7) -#define SC_OP_LED_ASSOCIATED BIT(8) -#define SC_OP_LED_ON BIT(9) -#define SC_OP_TSF_RESET BIT(11) -#define SC_OP_BT_PRIORITY_DETECTED BIT(12) -#define SC_OP_BT_SCAN BIT(13) -#define SC_OP_ANI_RUN BIT(14) -#define SC_OP_PRIM_STA_VIF BIT(15) +#define SC_OP_OFFCHANNEL BIT(2) +#define SC_OP_PREAMBLE_SHORT BIT(3) +#define SC_OP_PROTECT_ENABLE BIT(4) +#define SC_OP_RXFLUSH BIT(5) +#define SC_OP_LED_ASSOCIATED BIT(6) +#define SC_OP_LED_ON BIT(7) +#define SC_OP_TSF_RESET BIT(8) +#define SC_OP_BT_PRIORITY_DETECTED BIT(9) +#define SC_OP_BT_SCAN BIT(10) +#define SC_OP_ANI_RUN BIT(11) +#define SC_OP_PRIM_STA_VIF BIT(12) /* Powersave flags */ #define PS_WAIT_FOR_BEACON BIT(0) diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index 944e9b518f19..2708d1fc2c10 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c @@ -484,19 +484,12 @@ static void ath9k_init_misc(struct ath_softc *sc) { struct ath_common *common = ath9k_hw_common(sc->sc_ah); int i = 0; + setup_timer(&common->ani.timer, ath_ani_calibrate, (unsigned long)sc); sc->config.txpowlimit = ATH_TXPOWER_MAX; - - if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) { - sc->sc_flags |= SC_OP_TXAGGR; - sc->sc_flags |= SC_OP_RXAGGR; - } - sc->rx.defant = ath9k_hw_getdefantenna(sc->sc_ah); - memcpy(common->bssidmask, ath_bcast_mac, ETH_ALEN); - sc->beacon.slottime = ATH9K_SLOT_TIME_9; for (i = 0; i < ARRAY_SIZE(sc->beacon.bslot); i++) diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index a07565c730b7..3f00daa0ea06 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -639,7 +639,8 @@ static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta, #endif an->sta = sta; an->vif = vif; - if (sc->sc_flags & SC_OP_TXAGGR) { + + if (sta->ht_cap.ht_supported) { ath_tx_node_init(sc, an); an->maxampdu = 1 << (IEEE80211_HT_MAX_AMPDU_FACTOR + sta->ht_cap.ampdu_factor); @@ -658,7 +659,7 @@ static void ath_node_detach(struct ath_softc *sc, struct ieee80211_sta *sta) an->sta = NULL; #endif - if (sc->sc_flags & SC_OP_TXAGGR) + if (sta->ht_cap.ht_supported) ath_tx_node_cleanup(sc, an); } @@ -1751,7 +1752,7 @@ static void ath9k_sta_notify(struct ieee80211_hw *hw, struct ath_softc *sc = hw->priv; struct ath_node *an = (struct ath_node *) sta->drv_priv; - if (!(sc->sc_flags & SC_OP_TXAGGR)) + if (!sta->ht_cap.ht_supported) return; switch (cmd) { @@ -2119,15 +2120,10 @@ static int ath9k_ampdu_action(struct ieee80211_hw *hw, switch (action) { case IEEE80211_AMPDU_RX_START: - if (!(sc->sc_flags & SC_OP_RXAGGR)) - ret = -ENOTSUPP; break; case IEEE80211_AMPDU_RX_STOP: break; case IEEE80211_AMPDU_TX_START: - if (!(sc->sc_flags & SC_OP_TXAGGR)) - return -EOPNOTSUPP; - ath9k_ps_wakeup(sc); ret = ath_tx_aggr_start(sc, sta, tid, ssn); if (!ret) diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c index 6407af22f7b9..f26e9847bb2e 100644 --- a/drivers/net/wireless/ath/ath9k/rc.c +++ b/drivers/net/wireless/ath/ath9k/rc.c @@ -1298,12 +1298,13 @@ static u8 ath_rc_build_ht_caps(struct ath_softc *sc, struct ieee80211_sta *sta, return caps; } -static bool ath_tx_aggr_check(struct ath_softc *sc, struct ath_node *an, +static bool ath_tx_aggr_check(struct ath_softc *sc, struct ieee80211_sta *sta, u8 tidno) { + struct ath_node *an = (struct ath_node *)sta->drv_priv; struct ath_atx_tid *txtid; - if (!(sc->sc_flags & SC_OP_TXAGGR)) + if (!sta->ht_cap.ht_supported) return false; txtid = ATH_AN_2_TID(an, tidno); @@ -1374,13 +1375,11 @@ static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband, if (ieee80211_is_data_qos(fc) && skb_get_queue_mapping(skb) != IEEE80211_AC_VO) { u8 *qc, tid; - struct ath_node *an; qc = ieee80211_get_qos_ctl(hdr); tid = qc[0] & 0xf; - an = (struct ath_node *)sta->drv_priv; - if(ath_tx_aggr_check(sc, an, tid)) + if(ath_tx_aggr_check(sc, sta, tid)) ieee80211_start_tx_ba_session(sta, tid, 0); } } diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 9f785015a7dc..d2c635d84fbc 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -1290,14 +1290,11 @@ void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid an = (struct ath_node *)sta->drv_priv; - if (sc->sc_flags & SC_OP_TXAGGR) { - txtid = ATH_AN_2_TID(an, tid); - txtid->baw_size = - IEEE80211_MIN_AMPDU_BUF << sta->ht_cap.ampdu_factor; - txtid->state |= AGGR_ADDBA_COMPLETE; - txtid->state &= ~AGGR_ADDBA_PROGRESS; - ath_tx_resume_tid(sc, txtid); - } + txtid = ATH_AN_2_TID(an, tid); + txtid->baw_size = IEEE80211_MIN_AMPDU_BUF << sta->ht_cap.ampdu_factor; + txtid->state |= AGGR_ADDBA_COMPLETE; + txtid->state &= ~AGGR_ADDBA_PROGRESS; + ath_tx_resume_tid(sc, txtid); } /********************/ @@ -1523,7 +1520,7 @@ void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx) ath_drain_txq_list(sc, txq, &txq->axq_q, retry_tx); /* flush any pending frames if aggregation is enabled */ - if ((sc->sc_flags & SC_OP_TXAGGR) && !retry_tx) + if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) && !retry_tx) ath_txq_drain_pending_buffers(sc, txq); ath_txq_unlock_complete(sc, txq); @@ -1871,7 +1868,7 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct sk_buff *skb, struct ath_buf *bf; u8 tidno; - if ((sc->sc_flags & SC_OP_TXAGGR) && txctl->an && + if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) && txctl->an && ieee80211_is_data_qos(hdr->frame_control)) { tidno = ieee80211_get_qos_ctl(hdr)[0] & IEEE80211_QOS_CTL_TID_MASK; @@ -2141,7 +2138,7 @@ static void ath_tx_process_buffer(struct ath_softc *sc, struct ath_txq *txq, } else ath_tx_complete_aggr(sc, txq, bf, bf_head, ts, txok, true); - if (sc->sc_flags & SC_OP_TXAGGR) + if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) ath_txq_schedule(sc, txq); } @@ -2166,7 +2163,7 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) if (list_empty(&txq->axq_q)) { txq->axq_link = NULL; - if (sc->sc_flags & SC_OP_TXAGGR) + if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) ath_txq_schedule(sc, txq); break; } -- cgit From d47a61aa228709fe1704e18a2f444661c10b81c0 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Wed, 14 Mar 2012 14:41:05 +0530 Subject: ath9k: Fix multi-VIF BSS handling mac80211 provides short preamble information and ERP protection information on a per-BSS basis, which can be used. Remove flags stored in the driver, which was incorrect since they were being used in a global manner. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 16 ++++++---------- drivers/net/wireless/ath/ath9k/beacon.c | 6 +++--- drivers/net/wireless/ath/ath9k/main.c | 19 ------------------- drivers/net/wireless/ath/ath9k/rc.c | 3 ++- drivers/net/wireless/ath/ath9k/xmit.c | 4 +++- 5 files changed, 14 insertions(+), 34 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 5ecec83117d6..8c84049682ab 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -584,16 +584,12 @@ struct ath_ant_comb { #define SC_OP_INVALID BIT(0) #define SC_OP_BEACONS BIT(1) #define SC_OP_OFFCHANNEL BIT(2) -#define SC_OP_PREAMBLE_SHORT BIT(3) -#define SC_OP_PROTECT_ENABLE BIT(4) -#define SC_OP_RXFLUSH BIT(5) -#define SC_OP_LED_ASSOCIATED BIT(6) -#define SC_OP_LED_ON BIT(7) -#define SC_OP_TSF_RESET BIT(8) -#define SC_OP_BT_PRIORITY_DETECTED BIT(9) -#define SC_OP_BT_SCAN BIT(10) -#define SC_OP_ANI_RUN BIT(11) -#define SC_OP_PRIM_STA_VIF BIT(12) +#define SC_OP_RXFLUSH BIT(3) +#define SC_OP_TSF_RESET BIT(4) +#define SC_OP_BT_PRIORITY_DETECTED BIT(5) +#define SC_OP_BT_SCAN BIT(6) +#define SC_OP_ANI_RUN BIT(7) +#define SC_OP_PRIM_STA_VIF BIT(8) /* Powersave flags */ #define PS_WAIT_FOR_BEACON BIT(0) diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c index 43882f9e25c4..626418222c85 100644 --- a/drivers/net/wireless/ath/ath9k/beacon.c +++ b/drivers/net/wireless/ath/ath9k/beacon.c @@ -67,7 +67,7 @@ int ath_beaconq_config(struct ath_softc *sc) * up rate codes, and channel flags. Beacons are always sent out at the * lowest rate, and are not retried. */ -static void ath_beacon_setup(struct ath_softc *sc, struct ath_vif *avp, +static void ath_beacon_setup(struct ath_softc *sc, struct ieee80211_vif *vif, struct ath_buf *bf, int rateidx) { struct sk_buff *skb = bf->bf_mpdu; @@ -82,7 +82,7 @@ static void ath_beacon_setup(struct ath_softc *sc, struct ath_vif *avp, sband = &sc->sbands[common->hw->conf.channel->band]; rate = sband->bitrates[rateidx].hw_value; - if (sc->sc_flags & SC_OP_PREAMBLE_SHORT) + if (vif->bss_conf.use_short_preamble) rate |= sband->bitrates[rateidx].hw_value_short; memset(&info, 0, sizeof(info)); @@ -209,7 +209,7 @@ static struct ath_buf *ath_beacon_generate(struct ieee80211_hw *hw, } } - ath_beacon_setup(sc, avp, bf, info->control.rates[0].idx); + ath_beacon_setup(sc, vif, bf, info->control.rates[0].idx); while (skb) { ath_tx_cabq(hw, skb); diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 3f00daa0ea06..38794850f005 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -2044,25 +2044,6 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, ath_beacon_config(sc, vif); } - if (changed & BSS_CHANGED_ERP_PREAMBLE) { - ath_dbg(common, CONFIG, "BSS Changed PREAMBLE %d\n", - bss_conf->use_short_preamble); - if (bss_conf->use_short_preamble) - sc->sc_flags |= SC_OP_PREAMBLE_SHORT; - else - sc->sc_flags &= ~SC_OP_PREAMBLE_SHORT; - } - - if (changed & BSS_CHANGED_ERP_CTS_PROT) { - ath_dbg(common, CONFIG, "BSS Changed CTS PROT %d\n", - bss_conf->use_cts_prot); - if (bss_conf->use_cts_prot && - hw->conf.channel->band != IEEE80211_BAND_5GHZ) - sc->sc_flags |= SC_OP_PROTECT_ENABLE; - else - sc->sc_flags &= ~SC_OP_PROTECT_ENABLE; - } - mutex_unlock(&sc->mutex); ath9k_ps_restore(sc); } diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c index f26e9847bb2e..4f848493fece 100644 --- a/drivers/net/wireless/ath/ath9k/rc.c +++ b/drivers/net/wireless/ath/ath9k/rc.c @@ -748,7 +748,8 @@ static void ath_rc_rate_set_rtscts(struct ath_softc *sc, * If 802.11g protection is enabled, determine whether to use RTS/CTS or * just CTS. Note that this is only done for OFDM/HT unicast frames. */ - if ((sc->sc_flags & SC_OP_PROTECT_ENABLE) && + if ((tx_info->control.vif && + tx_info->control.vif->bss_conf.use_cts_prot) && (rate_table->info[rix].phy == WLAN_RC_PHY_OFDM || WLAN_RC_PHY_HT(rate_table->info[rix].phy))) { rates[0].flags |= IEEE80211_TX_RC_USE_CTS_PROTECT; diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index d2c635d84fbc..5faec1e04d65 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -955,7 +955,9 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, */ rate = ieee80211_get_rts_cts_rate(sc->hw, tx_info); info->rtscts_rate = rate->hw_value; - if (sc->sc_flags & SC_OP_PREAMBLE_SHORT) + + if (tx_info->control.vif && + tx_info->control.vif->bss_conf.use_short_preamble) info->rtscts_rate |= rate->hw_value_short; for (i = 0; i < 4; i++) { -- cgit From 627fdaf763f80a4db41289c4af7dc279dcba7363 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Wed, 14 Mar 2012 11:16:17 +0100 Subject: rt2x00: rt2800usb: move additional txdone into new function Signed-off-by: Stanislaw Gruszka Acked-by: Gertjan van Wingerde Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800usb.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index 2c11137c1eb0..8e1855a478be 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c @@ -528,15 +528,11 @@ static void rt2800usb_txdone(struct rt2x00_dev *rt2x00dev) } } -static void rt2800usb_work_txdone(struct work_struct *work) +static void rt2800usb_txdone_nostatus(struct rt2x00_dev *rt2x00dev) { - struct rt2x00_dev *rt2x00dev = - container_of(work, struct rt2x00_dev, txdone_work); struct data_queue *queue; struct queue_entry *entry; - rt2800usb_txdone(rt2x00dev); - /* * Process any trailing TX status reports for IO failures, * we loop until we find the first non-IO error entry. This @@ -560,6 +556,16 @@ static void rt2800usb_work_txdone(struct work_struct *work) break; } } +} + +static void rt2800usb_work_txdone(struct work_struct *work) +{ + struct rt2x00_dev *rt2x00dev = + container_of(work, struct rt2x00_dev, txdone_work); + + rt2800usb_txdone(rt2x00dev); + + rt2800usb_txdone_nostatus(rt2x00dev); /* * The hw may delay sending the packet after DMA complete -- cgit From ed61e2b02027935520d1be884fac0b2ffce8379a Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Wed, 14 Mar 2012 11:16:18 +0100 Subject: rt2x00: rt2800usb: rework txdone code Patch change txdone code to make it similar like txdone in rt2800pci, process only one entry from queue matching tx status. Before we processed all pending entries from queue until PACKEDID match, that caused that we do not report tx statuses correctly. Signed-off-by: Stanislaw Gruszka Acked-by: Gertjan van Wingerde Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800usb.c | 72 ++++++++++++++------------------- 1 file changed, 31 insertions(+), 41 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index 8e1855a478be..4eaa6280f367 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c @@ -438,35 +438,25 @@ static int rt2800usb_get_tx_data_len(struct queue_entry *entry) /* * TX control handlers */ -static bool rt2800usb_txdone_entry_check(struct queue_entry *entry, u32 reg) +static enum txdone_entry_desc_flags +rt2800usb_txdone_entry_check(struct queue_entry *entry, u32 reg) { __le32 *txwi; u32 word; int wcid, ack, pid; int tx_wcid, tx_ack, tx_pid; - if (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags) || - !test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags)) { - WARNING(entry->queue->rt2x00dev, - "Data pending for entry %u in queue %u\n", - entry->entry_idx, entry->queue->qid); - cond_resched(); - return false; - } - - wcid = rt2x00_get_field32(reg, TX_STA_FIFO_WCID); - ack = rt2x00_get_field32(reg, TX_STA_FIFO_TX_ACK_REQUIRED); - pid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_TYPE); - /* * This frames has returned with an IO error, * so the status report is not intended for this * frame. */ - if (test_bit(ENTRY_DATA_IO_FAILED, &entry->flags)) { - rt2x00lib_txdone_noinfo(entry, TXDONE_FAILURE); - return false; - } + if (test_bit(ENTRY_DATA_IO_FAILED, &entry->flags)) + return TXDONE_FAILURE; + + wcid = rt2x00_get_field32(reg, TX_STA_FIFO_WCID); + ack = rt2x00_get_field32(reg, TX_STA_FIFO_TX_ACK_REQUIRED); + pid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_TYPE); /* * Validate if this TX status report is intended for @@ -482,12 +472,11 @@ static bool rt2800usb_txdone_entry_check(struct queue_entry *entry, u32 reg) if ((wcid != tx_wcid) || (ack != tx_ack) || (pid != tx_pid)) { WARNING(entry->queue->rt2x00dev, "TX status report missed for queue %d entry %d\n", - entry->queue->qid, entry->entry_idx); - rt2x00lib_txdone_noinfo(entry, TXDONE_UNKNOWN); - return false; + entry->queue->qid, entry->entry_idx); + return TXDONE_UNKNOWN; } - return true; + return TXDONE_SUCCESS; } static void rt2800usb_txdone(struct rt2x00_dev *rt2x00dev) @@ -496,35 +485,36 @@ static void rt2800usb_txdone(struct rt2x00_dev *rt2x00dev) struct queue_entry *entry; u32 reg; u8 qid; + enum txdone_entry_desc_flags done_status; while (kfifo_get(&rt2x00dev->txstatus_fifo, ®)) { - - /* TX_STA_FIFO_PID_QUEUE is a 2-bit field, thus - * qid is guaranteed to be one of the TX QIDs + /* + * TX_STA_FIFO_PID_QUEUE is a 2-bit field, thus qid is + * guaranteed to be one of the TX QIDs . */ qid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_QUEUE); queue = rt2x00queue_get_tx_queue(rt2x00dev, qid); - if (unlikely(!queue)) { - WARNING(rt2x00dev, "Got TX status for an unavailable " + + if (unlikely(rt2x00queue_empty(queue))) { + WARNING(rt2x00dev, "Got TX status for an empty " "queue %u, dropping\n", qid); - continue; + break; } - /* - * Inside each queue, we process each entry in a chronological - * order. We first check that the queue is not empty. - */ - entry = NULL; - while (!rt2x00queue_empty(queue)) { - entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE); - if (rt2800usb_txdone_entry_check(entry, reg)) - break; - entry = NULL; + entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE); + + if (unlikely(test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags) || + !test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags))) { + WARNING(rt2x00dev, "Data pending for entry %u " + "in queue %u\n", entry->entry_idx, qid); + break; } - if (entry) - rt2800_txdone_entry(entry, reg, - rt2800usb_get_txwi(entry)); + done_status = rt2800usb_txdone_entry_check(entry, reg); + if (likely(done_status == TXDONE_SUCCESS)) + rt2800_txdone_entry(entry, reg, rt2800usb_get_txwi(entry)); + else + rt2x00lib_txdone_noinfo(entry, done_status); } } -- cgit From f421111b5e69020c047eb3ff057e50f446c3c7a2 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Wed, 14 Mar 2012 11:16:19 +0100 Subject: rt2x00: rt2800usb: rework txstatus code Currently we read tx status register after each urb data transfer. As callback procedure also trigger reading, that causing we have many "threads" of reading status. To prevent that introduce TX_STATUS_READING flags, and check if we are already in process of sequential reading TX_STA_FIFO, before requesting new reads. Change timer to hrtimer, that make TX_STA_FIFO overruns less possible. Use 200 us for initial timeout, and then reschedule in 100 us period, this values probably have to be tuned. Make changes on txdone work. Schedule it from rt2800usb_tx_sta_fifo_read_completed() callback when first valid status show up. Check in callback if tx status timeout happens, and schedule work on that condition too. That make possible to remove tx status timeout from generic watchdog. I moved that to rt2800usb. Loop in txdone work, that should prevent situation when we queue work, which is already processed, and after finish work is not rescheduled again. Signed-off-by: Stanislaw Gruszka Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800usb.c | 120 ++++++++++++++++++++++-------- drivers/net/wireless/rt2x00/rt2x00.h | 10 ++- drivers/net/wireless/rt2x00/rt2x00dev.c | 2 +- drivers/net/wireless/rt2x00/rt2x00queue.h | 12 --- drivers/net/wireless/rt2x00/rt2x00usb.c | 21 +----- 5 files changed, 101 insertions(+), 64 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index 4eaa6280f367..eacf94b2f382 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c @@ -114,45 +114,103 @@ static bool rt2800usb_txstatus_pending(struct rt2x00_dev *rt2x00dev) return false; } +static inline bool rt2800usb_entry_txstatus_timeout(struct queue_entry *entry) +{ + bool tout; + + if (!test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags)) + return false; + + tout = time_after(jiffies, entry->last_action + msecs_to_jiffies(100)); + if (unlikely(tout)) + WARNING(entry->queue->rt2x00dev, + "TX status timeout for entry %d in queue %d\n", + entry->entry_idx, entry->queue->qid); + return tout; + +} + +static bool rt2800usb_txstatus_timeout(struct rt2x00_dev *rt2x00dev) +{ + struct data_queue *queue; + struct queue_entry *entry; + + tx_queue_for_each(rt2x00dev, queue) { + entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE); + if (rt2800usb_entry_txstatus_timeout(entry)) + return true; + } + return false; +} + static bool rt2800usb_tx_sta_fifo_read_completed(struct rt2x00_dev *rt2x00dev, int urb_status, u32 tx_status) { + bool valid; + if (urb_status) { - WARNING(rt2x00dev, "rt2x00usb_register_read_async failed: %d\n", urb_status); - return false; + WARNING(rt2x00dev, "TX status read failed %d\n", urb_status); + + goto stop_reading; } - /* try to read all TX_STA_FIFO entries before scheduling txdone_work */ - if (rt2x00_get_field32(tx_status, TX_STA_FIFO_VALID)) { - if (!kfifo_put(&rt2x00dev->txstatus_fifo, &tx_status)) { - WARNING(rt2x00dev, "TX status FIFO overrun, " - "drop tx status report.\n"); - queue_work(rt2x00dev->workqueue, &rt2x00dev->txdone_work); - } else - return true; - } else if (!kfifo_is_empty(&rt2x00dev->txstatus_fifo)) { + valid = rt2x00_get_field32(tx_status, TX_STA_FIFO_VALID); + if (valid) { + if (!kfifo_put(&rt2x00dev->txstatus_fifo, &tx_status)) + WARNING(rt2x00dev, "TX status FIFO overrun\n"); + queue_work(rt2x00dev->workqueue, &rt2x00dev->txdone_work); + + /* Reschedule urb to read TX status again instantly */ + return true; } else if (rt2800usb_txstatus_pending(rt2x00dev)) { - mod_timer(&rt2x00dev->txstatus_timer, jiffies + msecs_to_jiffies(2)); + /* Read register after 250 us */ + hrtimer_start(&rt2x00dev->txstatus_timer, ktime_set(0, 250000), + HRTIMER_MODE_REL); + return false; } - return false; +stop_reading: + clear_bit(TX_STATUS_READING, &rt2x00dev->flags); + /* + * There is small race window above, between txstatus pending check and + * clear_bit someone could do rt2x00usb_interrupt_txdone, so recheck + * here again if status reading is needed. + */ + if (rt2800usb_txstatus_pending(rt2x00dev) && + test_and_set_bit(TX_STATUS_READING, &rt2x00dev->flags)) + return true; + else + return false; +} + +static void rt2800usb_async_read_tx_status(struct rt2x00_dev *rt2x00dev) +{ + + if (test_and_set_bit(TX_STATUS_READING, &rt2x00dev->flags)) + return; + + /* Read TX_STA_FIFO register after 500 us */ + hrtimer_start(&rt2x00dev->txstatus_timer, ktime_set(0, 500000), + HRTIMER_MODE_REL); } static void rt2800usb_tx_dma_done(struct queue_entry *entry) { struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; - rt2x00usb_register_read_async(rt2x00dev, TX_STA_FIFO, - rt2800usb_tx_sta_fifo_read_completed); + rt2800usb_async_read_tx_status(rt2x00dev); } -static void rt2800usb_tx_sta_fifo_timeout(unsigned long data) +static enum hrtimer_restart rt2800usb_tx_sta_fifo_timeout(struct hrtimer *timer) { - struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data; + struct rt2x00_dev *rt2x00dev = + container_of(timer, struct rt2x00_dev, txstatus_timer); rt2x00usb_register_read_async(rt2x00dev, TX_STA_FIFO, rt2800usb_tx_sta_fifo_read_completed); + + return HRTIMER_NORESTART; } /* @@ -540,7 +598,7 @@ static void rt2800usb_txdone_nostatus(struct rt2x00_dev *rt2x00dev) if (test_bit(ENTRY_DATA_IO_FAILED, &entry->flags)) rt2x00lib_txdone_noinfo(entry, TXDONE_FAILURE); - else if (rt2x00queue_status_timeout(entry)) + else if (rt2800usb_entry_txstatus_timeout(entry)) rt2x00lib_txdone_noinfo(entry, TXDONE_UNKNOWN); else break; @@ -553,17 +611,21 @@ static void rt2800usb_work_txdone(struct work_struct *work) struct rt2x00_dev *rt2x00dev = container_of(work, struct rt2x00_dev, txdone_work); - rt2800usb_txdone(rt2x00dev); + while (!kfifo_is_empty(&rt2x00dev->txstatus_fifo) || + rt2800usb_txstatus_timeout(rt2x00dev)) { - rt2800usb_txdone_nostatus(rt2x00dev); + rt2800usb_txdone(rt2x00dev); - /* - * The hw may delay sending the packet after DMA complete - * if the medium is busy, thus the TX_STA_FIFO entry is - * also delayed -> use a timer to retrieve it. - */ - if (rt2800usb_txstatus_pending(rt2x00dev)) - mod_timer(&rt2x00dev->txstatus_timer, jiffies + msecs_to_jiffies(2)); + rt2800usb_txdone_nostatus(rt2x00dev); + + /* + * The hw may delay sending the packet after DMA complete + * if the medium is busy, thus the TX_STA_FIFO entry is + * also delayed -> use a timer to retrieve it. + */ + if (rt2800usb_txstatus_pending(rt2x00dev)) + rt2800usb_async_read_tx_status(rt2x00dev); + } } /* @@ -705,9 +767,7 @@ static int rt2800usb_probe_hw(struct rt2x00_dev *rt2x00dev) __set_bit(REQUIRE_TXSTATUS_FIFO, &rt2x00dev->cap_flags); __set_bit(REQUIRE_PS_AUTOWAKE, &rt2x00dev->cap_flags); - setup_timer(&rt2x00dev->txstatus_timer, - rt2800usb_tx_sta_fifo_timeout, - (unsigned long) rt2x00dev); + rt2x00dev->txstatus_timer.function = rt2800usb_tx_sta_fifo_timeout, /* * Set the rssi offset. diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index 65275efcf279..471f87cab4ab 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h @@ -38,7 +38,7 @@ #include #include #include -#include +#include #include @@ -692,6 +692,12 @@ enum rt2x00_state_flags { */ CONFIG_CHANNEL_HT40, CONFIG_POWERSAVING, + + /* + * Mark we currently are sequentially reading TX_STA_FIFO register + * FIXME: this is for only rt2800usb, should go to private data + */ + TX_STATUS_READING, }; /* @@ -974,7 +980,7 @@ struct rt2x00_dev { /* * Timer to ensure tx status reports are read (rt2800usb). */ - struct timer_list txstatus_timer; + struct hrtimer txstatus_timer; /* * Tasklet for processing tx status reports (rt2800pci). diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index 49a51b4195ef..cffcf2ec990f 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c @@ -1232,7 +1232,7 @@ void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev) cancel_delayed_work_sync(&rt2x00dev->autowakeup_work); cancel_work_sync(&rt2x00dev->sleep_work); if (rt2x00_is_usb(rt2x00dev)) { - del_timer_sync(&rt2x00dev->txstatus_timer); + hrtimer_cancel(&rt2x00dev->txstatus_timer); cancel_work_sync(&rt2x00dev->rxdone_work); cancel_work_sync(&rt2x00dev->txdone_work); } diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h index 349008d1fb28..5f1392c72673 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.h +++ b/drivers/net/wireless/rt2x00/rt2x00queue.h @@ -636,18 +636,6 @@ static inline int rt2x00queue_threshold(struct data_queue *queue) { return rt2x00queue_available(queue) < queue->threshold; } - -/** - * rt2x00queue_status_timeout - Check if a timeout occurred for STATUS reports - * @entry: Queue entry to check. - */ -static inline int rt2x00queue_status_timeout(struct queue_entry *entry) -{ - if (!test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags)) - return false; - return time_after(jiffies, entry->last_action + msecs_to_jiffies(100)); -} - /** * rt2x00queue_dma_timeout - Check if a timeout occurred for DMA transfers * @entry: Queue entry to check. diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c index 2eea3866504d..66094eb21b61 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.c +++ b/drivers/net/wireless/rt2x00/rt2x00usb.c @@ -526,22 +526,6 @@ static void rt2x00usb_watchdog_tx_dma(struct data_queue *queue) rt2x00queue_flush_queue(queue, true); } -static void rt2x00usb_watchdog_tx_status(struct data_queue *queue) -{ - WARNING(queue->rt2x00dev, "TX queue %d status timed out," - " invoke forced tx handler\n", queue->qid); - - queue_work(queue->rt2x00dev->workqueue, &queue->rt2x00dev->txdone_work); -} - -static int rt2x00usb_status_timeout(struct data_queue *queue) -{ - struct queue_entry *entry; - - entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE); - return rt2x00queue_status_timeout(entry); -} - static int rt2x00usb_dma_timeout(struct data_queue *queue) { struct queue_entry *entry; @@ -558,8 +542,6 @@ void rt2x00usb_watchdog(struct rt2x00_dev *rt2x00dev) if (!rt2x00queue_empty(queue)) { if (rt2x00usb_dma_timeout(queue)) rt2x00usb_watchdog_tx_dma(queue); - if (rt2x00usb_status_timeout(queue)) - rt2x00usb_watchdog_tx_status(queue); } } } @@ -829,7 +811,8 @@ int rt2x00usb_probe(struct usb_interface *usb_intf, INIT_WORK(&rt2x00dev->rxdone_work, rt2x00usb_work_rxdone); INIT_WORK(&rt2x00dev->txdone_work, rt2x00usb_work_txdone); - init_timer(&rt2x00dev->txstatus_timer); + hrtimer_init(&rt2x00dev->txstatus_timer, CLOCK_MONOTONIC, + HRTIMER_MODE_REL); retval = rt2x00usb_alloc_reg(rt2x00dev); if (retval) -- cgit From 5f8f718ae1e1a6b4e16e67e9e67aff1864419f2e Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Wed, 14 Mar 2012 11:16:20 +0100 Subject: rt2x00: rt2800usb: do not check packedid for aggregated frames Tx statuses of aggregated subframes contain packetid of first subframe in the AMPDU. We can not identify AMPDU subframes based on packedid, so simply assume that status match first pending frame in the queue. Thats mostly the same what 2800pci do. Signed-off-by: Stanislaw Gruszka Acked-by: Gertjan van Wingerde Acked-by: Helmut Schaa Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800usb.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index eacf94b2f382..8c1d2c0df854 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c @@ -502,7 +502,7 @@ rt2800usb_txdone_entry_check(struct queue_entry *entry, u32 reg) __le32 *txwi; u32 word; int wcid, ack, pid; - int tx_wcid, tx_ack, tx_pid; + int tx_wcid, tx_ack, tx_pid, is_agg; /* * This frames has returned with an IO error, @@ -515,6 +515,7 @@ rt2800usb_txdone_entry_check(struct queue_entry *entry, u32 reg) wcid = rt2x00_get_field32(reg, TX_STA_FIFO_WCID); ack = rt2x00_get_field32(reg, TX_STA_FIFO_TX_ACK_REQUIRED); pid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_TYPE); + is_agg = rt2x00_get_field32(reg, TX_STA_FIFO_TX_AGGRE); /* * Validate if this TX status report is intended for @@ -527,7 +528,7 @@ rt2800usb_txdone_entry_check(struct queue_entry *entry, u32 reg) tx_ack = rt2x00_get_field32(word, TXWI_W1_ACK); tx_pid = rt2x00_get_field32(word, TXWI_W1_PACKETID); - if ((wcid != tx_wcid) || (ack != tx_ack) || (pid != tx_pid)) { + if (wcid != tx_wcid || ack != tx_ack || (!is_agg && pid != tx_pid)) { WARNING(entry->queue->rt2x00dev, "TX status report missed for queue %d entry %d\n", entry->queue->qid, entry->entry_idx); -- cgit From 0d9be8a4b7da71ef3b4ac8f6aa4fa225c1cb8e98 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Wed, 14 Mar 2012 11:16:21 +0100 Subject: rt2x00: rt2800usb: limit tx queues length TX status fifo is limited to 16 elements. When we send more frames than that, we can easily loose status, what is not good for rate scaling algorithm. On my testing the change does not degrade performance, actually make is slightly better. Additionally with the patch I can see much less various rt2x00 warnings in dmesg. Signed-off-by: Stanislaw Gruszka Acked-by: Gertjan van Wingerde Acked-by: Helmut Schaa Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800usb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index 8c1d2c0df854..cd490abced91 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c @@ -870,7 +870,7 @@ static const struct data_queue_desc rt2800usb_queue_rx = { }; static const struct data_queue_desc rt2800usb_queue_tx = { - .entry_num = 64, + .entry_num = 16, .data_size = AGGREGATION_SIZE, .desc_size = TXINFO_DESC_SIZE + TXWI_DESC_SIZE, .priv_size = sizeof(struct queue_entry_priv_usb), -- cgit From ba6fa29c6dd51a1245a109f4b460092b51cad0f0 Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Wed, 14 Mar 2012 13:31:11 +0100 Subject: mac80211: Don't sample max throughput rate in minstrel_ht The current max throughput rate is known to be good as otherwise it wouldn't be the max throughput rate. Since rate sampling can introduce some overhead (by adding RTS for example or due to not aggregating the frame) don't sample the max throughput rate. Signed-off-by: Helmut Schaa Acked-by: Felix Fietkau Signed-off-by: John W. Linville --- net/mac80211/rc80211_minstrel_ht.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c index 2b42564d6e29..16e0b277b9a8 100644 --- a/net/mac80211/rc80211_minstrel_ht.c +++ b/net/mac80211/rc80211_minstrel_ht.c @@ -567,6 +567,13 @@ minstrel_get_sample_rate(struct minstrel_priv *mp, struct minstrel_ht_sta *mi) sample_idx += mi->sample_group * MCS_GROUP_RATES; minstrel_next_sample_idx(mi); + /* + * Sampling might add some overhead (RTS, no aggregation) + * to the frame. Hence, don't use sampling for the currently + * used max TP rate. + */ + if (sample_idx == mi->max_tp_rate) + return -1; /* * When not using MRR, do not sample if the probability is already * higher than 95% to avoid wasting airtime -- cgit From ada577c12f7cd8851c999a9f19f62df06df7c39a Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Wed, 14 Mar 2012 16:15:02 +0200 Subject: mac80211: add NULL terminator to debugfs_netdev write buf Some debugfs write functions call kstrto* functions, which assume the string is null-terminated. Make it valid by changing ieee80211_if_write() to use static buffer instead of allocating one, and set the last char to NULL. (The write functions try to parse some integer/mac address, so 64 bytes buffer should be enough) Signed-off-by: Eliad Peller Signed-off-by: John W. Linville --- net/mac80211/debugfs_netdev.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c index f6de8a65f402..ef5cf2685657 100644 --- a/net/mac80211/debugfs_netdev.c +++ b/net/mac80211/debugfs_netdev.c @@ -49,16 +49,15 @@ static ssize_t ieee80211_if_write( size_t count, loff_t *ppos, ssize_t (*write)(struct ieee80211_sub_if_data *, const char *, int)) { - u8 *buf; + char buf[64]; ssize_t ret; - buf = kmalloc(count, GFP_KERNEL); - if (!buf) - return -ENOMEM; + if (count >= sizeof(buf)) + return -E2BIG; - ret = -EFAULT; if (copy_from_user(buf, userbuf, count)) - goto freebuf; + return -EFAULT; + buf[count] = '\0'; ret = -ENODEV; rtnl_lock(); @@ -66,8 +65,6 @@ static ssize_t ieee80211_if_write( ret = (*write)(sdata, buf, count); rtnl_unlock(); -freebuf: - kfree(buf); return ret; } -- cgit From dc41e4d474bb18e60bc6678e58adc52ed227f105 Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Wed, 14 Mar 2012 16:15:03 +0200 Subject: mac80211: make uapsd_* keys per-vif uapsd_queues and uapsd_max_sp_len are relevant only for managed interfaces, and can be configured differently for each vif. Move them from the local struct to sdata->u.mgd, and update the debugfs functions accordingly. Signed-off-by: Eliad Peller Signed-off-by: John W. Linville --- net/mac80211/debugfs.c | 81 ------------------------------------------- net/mac80211/debugfs_netdev.c | 58 +++++++++++++++++++++++++++++++ net/mac80211/ieee80211_i.h | 28 +++++++-------- net/mac80211/main.c | 2 -- net/mac80211/mlme.c | 8 +++-- net/mac80211/tx.c | 4 +-- 6 files changed, 79 insertions(+), 102 deletions(-) diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c index 483e96ed95c1..cc5b7a6e7e0b 100644 --- a/net/mac80211/debugfs.c +++ b/net/mac80211/debugfs.c @@ -97,85 +97,6 @@ static const struct file_operations reset_ops = { .llseek = noop_llseek, }; -static ssize_t uapsd_queues_read(struct file *file, char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct ieee80211_local *local = file->private_data; - return mac80211_format_buffer(user_buf, count, ppos, "0x%x\n", - local->uapsd_queues); -} - -static ssize_t uapsd_queues_write(struct file *file, - const char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct ieee80211_local *local = file->private_data; - u8 val; - int ret; - - ret = kstrtou8_from_user(user_buf, count, 0, &val); - if (ret) - return ret; - - if (val & ~IEEE80211_WMM_IE_STA_QOSINFO_AC_MASK) - return -ERANGE; - - local->uapsd_queues = val; - - return count; -} - -static const struct file_operations uapsd_queues_ops = { - .read = uapsd_queues_read, - .write = uapsd_queues_write, - .open = mac80211_open_file_generic, - .llseek = default_llseek, -}; - -static ssize_t uapsd_max_sp_len_read(struct file *file, char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct ieee80211_local *local = file->private_data; - - return mac80211_format_buffer(user_buf, count, ppos, "0x%x\n", - local->uapsd_max_sp_len); -} - -static ssize_t uapsd_max_sp_len_write(struct file *file, - const char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct ieee80211_local *local = file->private_data; - unsigned long val; - char buf[10]; - size_t len; - int ret; - - len = min(count, sizeof(buf) - 1); - if (copy_from_user(buf, user_buf, len)) - return -EFAULT; - buf[len] = '\0'; - - ret = kstrtoul(buf, 0, &val); - - if (ret) - return -EINVAL; - - if (val & ~IEEE80211_WMM_IE_STA_QOSINFO_SP_MASK) - return -ERANGE; - - local->uapsd_max_sp_len = val; - - return count; -} - -static const struct file_operations uapsd_max_sp_len_ops = { - .read = uapsd_max_sp_len_read, - .write = uapsd_max_sp_len_write, - .open = mac80211_open_file_generic, - .llseek = default_llseek, -}; - static ssize_t channel_type_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { @@ -362,8 +283,6 @@ void debugfs_hw_add(struct ieee80211_local *local) DEBUGFS_ADD(wep_iv); DEBUGFS_ADD(queues); DEBUGFS_ADD_MODE(reset, 0200); - DEBUGFS_ADD(uapsd_queues); - DEBUGFS_ADD(uapsd_max_sp_len); DEBUGFS_ADD(channel_type); DEBUGFS_ADD(hwflags); DEBUGFS_ADD(user_power); diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c index ef5cf2685657..a32eeda04aa3 100644 --- a/net/mac80211/debugfs_netdev.c +++ b/net/mac80211/debugfs_netdev.c @@ -337,6 +337,62 @@ static ssize_t ieee80211_if_parse_tkip_mic_test( __IEEE80211_IF_FILE_W(tkip_mic_test); +static ssize_t ieee80211_if_fmt_uapsd_queues( + const struct ieee80211_sub_if_data *sdata, char *buf, int buflen) +{ + const struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; + + return snprintf(buf, buflen, "0x%x\n", ifmgd->uapsd_queues); +} + +static ssize_t ieee80211_if_parse_uapsd_queues( + struct ieee80211_sub_if_data *sdata, const char *buf, int buflen) +{ + struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; + u8 val; + int ret; + + ret = kstrtou8(buf, 0, &val); + if (ret) + return ret; + + if (val & ~IEEE80211_WMM_IE_STA_QOSINFO_AC_MASK) + return -ERANGE; + + ifmgd->uapsd_queues = val; + + return buflen; +} +__IEEE80211_IF_FILE_W(uapsd_queues); + +static ssize_t ieee80211_if_fmt_uapsd_max_sp_len( + const struct ieee80211_sub_if_data *sdata, char *buf, int buflen) +{ + const struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; + + return snprintf(buf, buflen, "0x%x\n", ifmgd->uapsd_max_sp_len); +} + +static ssize_t ieee80211_if_parse_uapsd_max_sp_len( + struct ieee80211_sub_if_data *sdata, const char *buf, int buflen) +{ + struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; + unsigned long val; + int ret; + + ret = kstrtoul(buf, 0, &val); + if (ret) + return -EINVAL; + + if (val & ~IEEE80211_WMM_IE_STA_QOSINFO_SP_MASK) + return -ERANGE; + + ifmgd->uapsd_max_sp_len = val; + + return buflen; +} +__IEEE80211_IF_FILE_W(uapsd_max_sp_len); + /* AP attributes */ IEEE80211_IF_FILE(num_sta_authorized, u.ap.num_sta_authorized, ATOMIC); IEEE80211_IF_FILE(num_sta_ps, u.ap.num_sta_ps, ATOMIC); @@ -469,6 +525,8 @@ static void add_sta_files(struct ieee80211_sub_if_data *sdata) DEBUGFS_ADD(ave_beacon); DEBUGFS_ADD_MODE(smps, 0600); DEBUGFS_ADD_MODE(tkip_mic_test, 0200); + DEBUGFS_ADD_MODE(uapsd_queues, 0600); + DEBUGFS_ADD_MODE(uapsd_max_sp_len, 0600); } static void add_ap_files(struct ieee80211_sub_if_data *sdata) diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 63fb0eb79d8e..d9798a307f20 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -459,6 +459,20 @@ struct ieee80211_if_managed { IEEE80211_MFP_REQUIRED } mfp; /* management frame protection */ + /* + * Bitmask of enabled u-apsd queues, + * IEEE80211_WMM_IE_STA_QOSINFO_AC_BE & co. Needs a new association + * to take effect. + */ + unsigned int uapsd_queues; + + /* + * Maximum number of buffered frames AP can deliver during a + * service period, IEEE80211_WMM_IE_STA_QOSINFO_SP_ALL or similar. + * Needs a new association to take effect. + */ + unsigned int uapsd_max_sp_len; + int wmm_last_param_set; u8 use_4addr; @@ -1017,20 +1031,6 @@ struct ieee80211_local { */ unsigned int wmm_acm; /* bit field of ACM bits (BIT(802.1D tag)) */ - /* - * Bitmask of enabled u-apsd queues, - * IEEE80211_WMM_IE_STA_QOSINFO_AC_BE & co. Needs a new association - * to take effect. - */ - unsigned int uapsd_queues; - - /* - * Maximum number of buffered frames AP can deliver during a - * service period, IEEE80211_WMM_IE_STA_QOSINFO_SP_ALL or similar. - * Needs a new association to take effect. - */ - unsigned int uapsd_max_sp_len; - bool pspolling; bool offchannel_ps_enabled; /* diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 36fa8051296c..b581a24fa15c 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -595,8 +595,6 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, local->hw.conf.long_frame_max_tx_count = wiphy->retry_long; local->hw.conf.short_frame_max_tx_count = wiphy->retry_short; local->user_power_level = -1; - local->uapsd_queues = IEEE80211_DEFAULT_UAPSD_QUEUES; - local->uapsd_max_sp_len = IEEE80211_DEFAULT_MAX_SP_LEN; wiphy->ht_capa_mod_mask = &mac80211_ht_capa_mod_mask; INIT_LIST_HEAD(&local->interfaces); diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 0df22372af8d..576fb25456dd 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -572,8 +572,8 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata) if (assoc_data->wmm) { if (assoc_data->uapsd) { - qos_info = local->uapsd_queues; - qos_info |= (local->uapsd_max_sp_len << + qos_info = ifmgd->uapsd_queues; + qos_info |= (ifmgd->uapsd_max_sp_len << IEEE80211_WMM_IE_STA_QOSINFO_SP_SHIFT); } else { qos_info = 0; @@ -1192,7 +1192,7 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local, return; if (ifmgd->flags & IEEE80211_STA_UAPSD_ENABLED) - uapsd_queues = local->uapsd_queues; + uapsd_queues = ifmgd->uapsd_queues; count = wmm_param[6] & 0x0f; if (count == ifmgd->wmm_last_param_set) @@ -3013,6 +3013,8 @@ void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata) ifmgd->flags = 0; ifmgd->powersave = sdata->wdev.ps; + ifmgd->uapsd_queues = IEEE80211_DEFAULT_UAPSD_QUEUES; + ifmgd->uapsd_max_sp_len = IEEE80211_DEFAULT_MAX_SP_LEN; mutex_init(&ifmgd->mtx); diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index d9e791d2b543..782a60198df4 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -226,12 +226,12 @@ ieee80211_tx_h_dynamic_ps(struct ieee80211_tx_data *tx) * have correct qos tag for some reason, due the network or the * peer application. * - * Note: local->uapsd_queues access is racy here. If the value is + * Note: ifmgd->uapsd_queues access is racy here. If the value is * changed via debugfs, user needs to reassociate manually to have * everything in sync. */ if ((ifmgd->flags & IEEE80211_STA_UAPSD_ENABLED) - && (local->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VO) + && (ifmgd->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VO) && skb_get_queue_mapping(tx->skb) == 0) return TX_CONTINUE; -- cgit From 7e03072edd6a915812c418e5662204f83bbb0c84 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 14 Mar 2012 16:40:21 +0100 Subject: ath9k_hw: simplify tx queue interrupt mask handling Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/mac.c | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c index 5f4ae6c9a93c..13b6afd67826 100644 --- a/drivers/net/wireless/ath/ath9k/mac.c +++ b/drivers/net/wireless/ath/ath9k/mac.c @@ -340,6 +340,15 @@ int ath9k_hw_setuptxqueue(struct ath_hw *ah, enum ath9k_tx_queue type, } EXPORT_SYMBOL(ath9k_hw_setuptxqueue); +static void ath9k_hw_clear_queue_interrupts(struct ath_hw *ah, u32 q) +{ + ah->txok_interrupt_mask &= ~(1 << q); + ah->txerr_interrupt_mask &= ~(1 << q); + ah->txdesc_interrupt_mask &= ~(1 << q); + ah->txeol_interrupt_mask &= ~(1 << q); + ah->txurn_interrupt_mask &= ~(1 << q); +} + bool ath9k_hw_releasetxqueue(struct ath_hw *ah, u32 q) { struct ath_common *common = ath9k_hw_common(ah); @@ -354,11 +363,7 @@ bool ath9k_hw_releasetxqueue(struct ath_hw *ah, u32 q) ath_dbg(common, QUEUE, "Release TX queue: %u\n", q); qi->tqi_type = ATH9K_TX_QUEUE_INACTIVE; - ah->txok_interrupt_mask &= ~(1 << q); - ah->txerr_interrupt_mask &= ~(1 << q); - ah->txdesc_interrupt_mask &= ~(1 << q); - ah->txeol_interrupt_mask &= ~(1 << q); - ah->txurn_interrupt_mask &= ~(1 << q); + ath9k_hw_clear_queue_interrupts(ah, q); ath9k_hw_set_txq_interrupts(ah, qi); return true; @@ -510,26 +515,17 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q) if (AR_SREV_9300_20_OR_LATER(ah)) REG_WRITE(ah, AR_Q_DESC_CRCCHK, AR_Q_DESC_CRCCHK_EN); + ath9k_hw_clear_queue_interrupts(ah, q); if (qi->tqi_qflags & TXQ_FLAG_TXOKINT_ENABLE) ah->txok_interrupt_mask |= 1 << q; - else - ah->txok_interrupt_mask &= ~(1 << q); if (qi->tqi_qflags & TXQ_FLAG_TXERRINT_ENABLE) ah->txerr_interrupt_mask |= 1 << q; - else - ah->txerr_interrupt_mask &= ~(1 << q); if (qi->tqi_qflags & TXQ_FLAG_TXDESCINT_ENABLE) ah->txdesc_interrupt_mask |= 1 << q; - else - ah->txdesc_interrupt_mask &= ~(1 << q); if (qi->tqi_qflags & TXQ_FLAG_TXEOLINT_ENABLE) ah->txeol_interrupt_mask |= 1 << q; - else - ah->txeol_interrupt_mask &= ~(1 << q); if (qi->tqi_qflags & TXQ_FLAG_TXURNINT_ENABLE) ah->txurn_interrupt_mask |= 1 << q; - else - ah->txurn_interrupt_mask &= ~(1 << q); ath9k_hw_set_txq_interrupts(ah, qi); return true; -- cgit From ce8fdf6ef6bc2e299d2e1572c55325e0dca7e85f Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 14 Mar 2012 16:40:22 +0100 Subject: ath9k_hw: clean up tx completion interrupt handling TXQ_FLAG_TXOKINT_ENABLE and TXQ_FLAG_TXERRINT_ENABLE are always set and used together, and they share the same bitmask in enum ath9k_tx_queue_flags. Simplify the code that tests for these flags. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/mac.c | 7 +++---- drivers/net/wireless/ath/ath9k/mac.h | 3 +-- drivers/net/wireless/ath/ath9k/xmit.c | 3 +-- 3 files changed, 5 insertions(+), 8 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c index 13b6afd67826..bfb95e5d263c 100644 --- a/drivers/net/wireless/ath/ath9k/mac.c +++ b/drivers/net/wireless/ath/ath9k/mac.c @@ -516,10 +516,10 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q) REG_WRITE(ah, AR_Q_DESC_CRCCHK, AR_Q_DESC_CRCCHK_EN); ath9k_hw_clear_queue_interrupts(ah, q); - if (qi->tqi_qflags & TXQ_FLAG_TXOKINT_ENABLE) + if (qi->tqi_qflags & TXQ_FLAG_TXINT_ENABLE) { ah->txok_interrupt_mask |= 1 << q; - if (qi->tqi_qflags & TXQ_FLAG_TXERRINT_ENABLE) ah->txerr_interrupt_mask |= 1 << q; + } if (qi->tqi_qflags & TXQ_FLAG_TXDESCINT_ENABLE) ah->txdesc_interrupt_mask |= 1 << q; if (qi->tqi_qflags & TXQ_FLAG_TXEOLINT_ENABLE) @@ -743,8 +743,7 @@ int ath9k_hw_beaconq_setup(struct ath_hw *ah) qi.tqi_cwmax = 0; if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) - qi.tqi_qflags = TXQ_FLAG_TXOKINT_ENABLE | - TXQ_FLAG_TXERRINT_ENABLE; + qi.tqi_qflags = TXQ_FLAG_TXINT_ENABLE; return ath9k_hw_setuptxqueue(ah, ATH9K_TX_QUEUE_BEACON, &qi); } diff --git a/drivers/net/wireless/ath/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h index 11dbd1473a13..6476d9073202 100644 --- a/drivers/net/wireless/ath/ath9k/mac.h +++ b/drivers/net/wireless/ath/ath9k/mac.h @@ -583,8 +583,7 @@ enum ath9k_tx_queue { #define ATH9K_WME_UPSD 4 enum ath9k_tx_queue_flags { - TXQ_FLAG_TXOKINT_ENABLE = 0x0001, - TXQ_FLAG_TXERRINT_ENABLE = 0x0001, + TXQ_FLAG_TXINT_ENABLE = 0x0001, TXQ_FLAG_TXDESCINT_ENABLE = 0x0002, TXQ_FLAG_TXEOLINT_ENABLE = 0x0004, TXQ_FLAG_TXURNINT_ENABLE = 0x0008, diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 5faec1e04d65..c6b93f619843 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -1355,8 +1355,7 @@ struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype) * based intr on the EOSP frames. */ if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) { - qi.tqi_qflags = TXQ_FLAG_TXOKINT_ENABLE | - TXQ_FLAG_TXERRINT_ENABLE; + qi.tqi_qflags = TXQ_FLAG_TXINT_ENABLE; } else { if (qtype == ATH9K_TX_QUEUE_UAPSD) qi.tqi_qflags = TXQ_FLAG_TXDESCINT_ENABLE; -- cgit From 8efa7a813233affeafd9fd7770709e9bda6855b6 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 14 Mar 2012 16:40:23 +0100 Subject: ath9k_hw: remove ath9k_hw_htc_resetinit Automatically set the ah->htc_reset_init on init and after PHY disable. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc_drv_main.c | 1 - drivers/net/wireless/ath/ath9k/hw.c | 8 ++------ drivers/net/wireless/ath/ath9k/hw.h | 3 --- 3 files changed, 2 insertions(+), 10 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index 2a29a7cdef18..2b8f61c210e1 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -919,7 +919,6 @@ static int ath9k_htc_start(struct ieee80211_hw *hw) /* setup initial channel */ init_channel = ath9k_cmn_get_curchannel(hw, ah); - ath9k_hw_htc_resetinit(ah); ret = ath9k_hw_reset(ah, init_channel, ah->caldata, false); if (ret) { ath_err(common, diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 780ecd8aff6e..d3df943ac124 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -449,6 +449,7 @@ static void ath9k_hw_init_defaults(struct ath_hw *ah) ah->slottime = ATH9K_SLOT_TIME_9; ah->globaltxtimeout = (u32) -1; ah->power_mode = ATH9K_PM_UNDEFINED; + ah->htc_reset_init = true; } static int ath9k_hw_init_macaddr(struct ath_hw *ah) @@ -2631,6 +2632,7 @@ bool ath9k_hw_phy_disable(struct ath_hw *ah) return false; ath9k_hw_init_pll(ah, NULL); + ah->htc_reset_init = true; return true; } EXPORT_SYMBOL(ath9k_hw_phy_disable); @@ -2991,12 +2993,6 @@ EXPORT_SYMBOL(ath_gen_timer_isr); /* HTC */ /********/ -void ath9k_hw_htc_resetinit(struct ath_hw *ah) -{ - ah->htc_reset_init = true; -} -EXPORT_SYMBOL(ath9k_hw_htc_resetinit); - static struct { u32 version; const char * name; diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index 23c8dfae29f7..7ce60fb1d91e 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -988,9 +988,6 @@ void ath_gen_timer_isr(struct ath_hw *hw); void ath9k_hw_name(struct ath_hw *ah, char *hw_name, size_t len); -/* HTC */ -void ath9k_hw_htc_resetinit(struct ath_hw *ah); - /* PHY */ void ath9k_hw_get_delta_slope_vals(struct ath_hw *ah, u32 coef_scaled, u32 *coef_mantissa, u32 *coef_exponent); -- cgit From 99ac8cd6ff44e733acdff0d36475dce2d3fe6a6b Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 14 Mar 2012 16:40:24 +0100 Subject: ath9k_hw: remove ath9k_hw_getdefantenna The default antenna (as programmed by the INI file) is always 0 anyway. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hw.c | 6 ------ drivers/net/wireless/ath/ath9k/hw.h | 1 - drivers/net/wireless/ath/ath9k/init.c | 1 - 3 files changed, 8 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index d3df943ac124..b92cf01cfd19 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -2569,12 +2569,6 @@ void ath9k_hw_set_gpio(struct ath_hw *ah, u32 gpio, u32 val) } EXPORT_SYMBOL(ath9k_hw_set_gpio); -u32 ath9k_hw_getdefantenna(struct ath_hw *ah) -{ - return REG_READ(ah, AR_DEF_ANTENNA) & 0x7; -} -EXPORT_SYMBOL(ath9k_hw_getdefantenna); - void ath9k_hw_setantenna(struct ath_hw *ah, u32 antenna) { REG_WRITE(ah, AR_DEF_ANTENNA, (antenna & 0x7)); diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index 7ce60fb1d91e..5036f95c48c1 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -934,7 +934,6 @@ u32 ath9k_hw_gpio_get(struct ath_hw *ah, u32 gpio); void ath9k_hw_cfg_output(struct ath_hw *ah, u32 gpio, u32 ah_signal_type); void ath9k_hw_set_gpio(struct ath_hw *ah, u32 gpio, u32 val); -u32 ath9k_hw_getdefantenna(struct ath_hw *ah); void ath9k_hw_setantenna(struct ath_hw *ah, u32 antenna); /* General Operation */ diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index 2708d1fc2c10..8cb37429b216 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c @@ -488,7 +488,6 @@ static void ath9k_init_misc(struct ath_softc *sc) setup_timer(&common->ani.timer, ath_ani_calibrate, (unsigned long)sc); sc->config.txpowlimit = ATH_TXPOWER_MAX; - sc->rx.defant = ath9k_hw_getdefantenna(sc->sc_ah); memcpy(common->bssidmask, ath_bcast_mac, ETH_ALEN); sc->beacon.slottime = ATH9K_SLOT_TIME_9; -- cgit From f3eef64521f82330b4b173584d776b8a04b3e795 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 14 Mar 2012 16:40:25 +0100 Subject: ath9k: optimize register access functions By checking for NR_CPUS, the compiler can optimize out register access serialization code on non-SMP kernels Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hw.c | 2 +- drivers/net/wireless/ath/ath9k/init.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index b92cf01cfd19..ce9577ebaf2b 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -556,7 +556,7 @@ static int __ath9k_hw_init(struct ath_hw *ah) return -EIO; } - if (ah->config.serialize_regmode == SER_REG_MODE_AUTO) { + if (NR_CPUS > 1 && ah->config.serialize_regmode == SER_REG_MODE_AUTO) { if (ah->hw_version.macVersion == AR_SREV_VERSION_5416_PCI || ((AR_SREV_9160(ah) || AR_SREV_9280(ah)) && !ah->is_pciexpress)) { diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index 8cb37429b216..60159f4ee532 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c @@ -172,7 +172,7 @@ static void ath9k_iowrite32(void *hw_priv, u32 val, u32 reg_offset) struct ath_common *common = ath9k_hw_common(ah); struct ath_softc *sc = (struct ath_softc *) common->priv; - if (ah->config.serialize_regmode == SER_REG_MODE_ON) { + if (NR_CPUS > 1 && ah->config.serialize_regmode == SER_REG_MODE_ON) { unsigned long flags; spin_lock_irqsave(&sc->sc_serial_rw, flags); iowrite32(val, sc->mem + reg_offset); @@ -188,7 +188,7 @@ static unsigned int ath9k_ioread32(void *hw_priv, u32 reg_offset) struct ath_softc *sc = (struct ath_softc *) common->priv; u32 val; - if (ah->config.serialize_regmode == SER_REG_MODE_ON) { + if (NR_CPUS > 1 && ah->config.serialize_regmode == SER_REG_MODE_ON) { unsigned long flags; spin_lock_irqsave(&sc->sc_serial_rw, flags); val = ioread32(sc->mem + reg_offset); @@ -219,7 +219,7 @@ static unsigned int ath9k_reg_rmw(void *hw_priv, u32 reg_offset, u32 set, u32 cl unsigned long uninitialized_var(flags); u32 val; - if (ah->config.serialize_regmode == SER_REG_MODE_ON) { + if (NR_CPUS > 1 && ah->config.serialize_regmode == SER_REG_MODE_ON) { spin_lock_irqsave(&sc->sc_serial_rw, flags); val = __ath9k_reg_rmw(sc, reg_offset, set, clr); spin_unlock_irqrestore(&sc->sc_serial_rw, flags); -- cgit From 239c795d6ba9ada0811cdb4f87304552de29e81b Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 14 Mar 2012 16:40:26 +0100 Subject: ath9k_hw: remove ath9k_hw_gettxintrtxqs The driver can just check the mask directly Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/mac.c | 7 ------- drivers/net/wireless/ath/ath9k/mac.h | 1 - drivers/net/wireless/ath/ath9k/xmit.c | 5 ++--- 3 files changed, 2 insertions(+), 11 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c index bfb95e5d263c..f7bd2532269c 100644 --- a/drivers/net/wireless/ath/ath9k/mac.c +++ b/drivers/net/wireless/ath/ath9k/mac.c @@ -185,13 +185,6 @@ bool ath9k_hw_stop_dma_queue(struct ath_hw *ah, u32 q) } EXPORT_SYMBOL(ath9k_hw_stop_dma_queue); -void ath9k_hw_gettxintrtxqs(struct ath_hw *ah, u32 *txqs) -{ - *txqs &= ah->intr_txqs; - ah->intr_txqs &= ~(*txqs); -} -EXPORT_SYMBOL(ath9k_hw_gettxintrtxqs); - bool ath9k_hw_set_txq_props(struct ath_hw *ah, int q, const struct ath9k_tx_queue_info *qinfo) { diff --git a/drivers/net/wireless/ath/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h index 6476d9073202..21c955609e6c 100644 --- a/drivers/net/wireless/ath/ath9k/mac.h +++ b/drivers/net/wireless/ath/ath9k/mac.h @@ -713,7 +713,6 @@ u32 ath9k_hw_numtxpending(struct ath_hw *ah, u32 q); bool ath9k_hw_updatetxtriglevel(struct ath_hw *ah, bool bIncTrigLevel); bool ath9k_hw_stop_dma_queue(struct ath_hw *ah, u32 q); void ath9k_hw_abort_tx_dma(struct ath_hw *ah); -void ath9k_hw_gettxintrtxqs(struct ath_hw *ah, u32 *txqs); bool ath9k_hw_set_txq_props(struct ath_hw *ah, int q, const struct ath9k_tx_queue_info *qinfo); bool ath9k_hw_get_txq_props(struct ath_hw *ah, int q, diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index c6b93f619843..834e6bc45e8b 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -2261,10 +2261,9 @@ static void ath_tx_complete_poll_work(struct work_struct *work) void ath_tx_tasklet(struct ath_softc *sc) { + struct ath_hw *ah = sc->sc_ah; + u32 qcumask = ((1 << ATH9K_NUM_TX_QUEUES) - 1) & ah->intr_txqs; int i; - u32 qcumask = ((1 << ATH9K_NUM_TX_QUEUES) - 1); - - ath9k_hw_gettxintrtxqs(sc->sc_ah, &qcumask); for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) { if (ATH_TXQ_SETUP(sc, i) && (qcumask & (1 << i))) -- cgit From aebc0a88ddf514ef2b3cdba0b3f14883b8b0e339 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 14 Mar 2012 16:40:27 +0100 Subject: ath9k_hw: clean up ath9k_hw_setuprxdesc The ATH9K_HW_CAP_AUTOSLEEP check is bogus, the rx status area needs to be cleared on all non-EDMA PCI/AHB based chipsets anyway. Limit the memset to the rx status area to improve performance. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9002_mac.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9002_mac.c b/drivers/net/wireless/ath/ath9k/ar9002_mac.c index 7b6417b5212e..aa2abaf31cba 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_mac.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_mac.c @@ -347,15 +347,12 @@ void ath9k_hw_setuprxdesc(struct ath_hw *ah, struct ath_desc *ds, u32 size, u32 flags) { struct ar5416_desc *ads = AR5416DESC(ds); - struct ath9k_hw_capabilities *pCap = &ah->caps; ads->ds_ctl1 = size & AR_BufLen; if (flags & ATH9K_RXDESC_INTREQ) ads->ds_ctl1 |= AR_RxIntrReq; - ads->ds_rxstatus8 &= ~AR_RxDone; - if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) - memset(&(ads->u), 0, sizeof(ads->u)); + memset(&ads->u.rx, 0, sizeof(ads->u.rx)); } EXPORT_SYMBOL(ath9k_hw_setuprxdesc); -- cgit From bbf2b30c0ee0860ab10af856f7d8570c8652d9fd Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 14 Mar 2012 16:40:28 +0100 Subject: ath9k_hw: remove iniCommon_*_cck_fir_coeff_9271 These arrays are unused Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9002_hw.c | 6 ------ drivers/net/wireless/ath/ath9k/hw.h | 2 -- 2 files changed, 8 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9002_hw.c b/drivers/net/wireless/ath/ath9k/ar9002_hw.c index e3f268900763..2829c8c75e86 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_hw.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_hw.c @@ -34,12 +34,6 @@ static void ar9002_hw_init_mode_regs(struct ath_hw *ah) ARRAY_SIZE(ar9271Modes_9271), 5); INIT_INI_ARRAY(&ah->iniCommon, ar9271Common_9271, ARRAY_SIZE(ar9271Common_9271), 2); - INIT_INI_ARRAY(&ah->iniCommon_normal_cck_fir_coeff_9271, - ar9287Common_normal_cck_fir_coeff_9287_1_1, - ARRAY_SIZE(ar9287Common_normal_cck_fir_coeff_9287_1_1), 2); - INIT_INI_ARRAY(&ah->iniCommon_japan_2484_cck_fir_coeff_9271, - ar9287Common_japan_2484_cck_fir_coeff_9287_1_1, - ARRAY_SIZE(ar9287Common_japan_2484_cck_fir_coeff_9287_1_1), 2); INIT_INI_ARRAY(&ah->iniModes_9271_1_0_only, ar9271Modes_9271_1_0_only, ARRAY_SIZE(ar9271Modes_9271_1_0_only), 5); diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index 5036f95c48c1..043df3cf54fe 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -835,8 +835,6 @@ struct ath_hw { struct ar5416IniArray iniCckfirNormal; struct ar5416IniArray iniCckfirJapan2484; struct ar5416IniArray ini_japan2484; - struct ar5416IniArray iniCommon_normal_cck_fir_coeff_9271; - struct ar5416IniArray iniCommon_japan_2484_cck_fir_coeff_9271; struct ar5416IniArray iniModes_9271_ANI_reg; struct ar5416IniArray iniModes_high_power_tx_gain_9271; struct ar5416IniArray iniModes_normal_power_tx_gain_9271; -- cgit From c8664d13a58f7cccc673c0840efcc698f7872172 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 14 Mar 2012 16:40:29 +0100 Subject: ath9k_hw: fold ar9002_hw_cck_chan14_spread into mode regs initialization Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9002_hw.c | 5 ----- drivers/net/wireless/ath/ath9k/hw.c | 3 --- drivers/net/wireless/ath/ath9k/hw.h | 1 - 3 files changed, 9 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9002_hw.c b/drivers/net/wireless/ath/ath9k/ar9002_hw.c index 2829c8c75e86..1d06dab27030 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_hw.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_hw.c @@ -154,11 +154,6 @@ static void ar9002_hw_init_mode_regs(struct ath_hw *ah) INI_RA(addac, 31,1) = 0; } } -} - -/* Support for Japan ch.14 (2484) spread */ -void ar9002_hw_cck_chan14_spread(struct ath_hw *ah) -{ if (AR_SREV_9287_11_OR_LATER(ah)) { INIT_INI_ARRAY(&ah->iniCckfirNormal, ar9287Common_normal_cck_fir_coeff_9287_1_1, diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index ce9577ebaf2b..3022c4e4d103 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -620,9 +620,6 @@ static int __ath9k_hw_init(struct ath_hw *ah) if (!ah->is_pciexpress) ath9k_hw_disablepcie(ah); - if (!AR_SREV_9300_20_OR_LATER(ah)) - ar9002_hw_cck_chan14_spread(ah); - r = ath9k_hw_post_init(ah); if (r) return r; diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index 043df3cf54fe..4bd2c89654d4 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -994,7 +994,6 @@ void ath9k_hw_apply_txpower(struct ath_hw *ah, struct ath9k_channel *chan); * Code Specific to AR5008, AR9001 or AR9002, * we stuff these here to avoid callbacks for AR9003. */ -void ar9002_hw_cck_chan14_spread(struct ath_hw *ah); int ar9002_hw_rf_claim(struct ath_hw *ah); void ar9002_hw_enable_async_fifo(struct ath_hw *ah); -- cgit From 9951c4d042dbc325b147cce5bd6f6436adb2c7fc Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 14 Mar 2012 16:40:30 +0100 Subject: ath9k_hw: fix AR9380 register settings for channel 14 Program the ah->ini_japan2484 INI values which were left out by accident Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_phy.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c index 70e27d2a5e43..99b64f27bb22 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c @@ -691,6 +691,9 @@ static int ar9003_hw_process_ini(struct ath_hw *ah, if (AR_SREV_9462(ah)) ar9003_hw_prog_ini(ah, &ah->ini_BTCOEX_MAX_TXPWR, 1); + if (chan->channel == 2484) + ar9003_hw_prog_ini(ah, &ah->ini_japan2484, 1); + ah->modes_index = modesIndex; ar9003_hw_override_ini(ah); ar9003_hw_set_channel_regs(ah, chan); -- cgit From c7d36f9fe73ed29760042276295ac42c17849f32 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 14 Mar 2012 16:40:31 +0100 Subject: ath9k_hw: clean up iniModesAdditional use iniModesFastClock for 5 ghz fast clock specific settings, and iniAdditional for clock/chip specific initval overrides Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar5008_phy.c | 5 ++--- drivers/net/wireless/ath/ath9k/ar9002_hw.c | 2 +- drivers/net/wireless/ath/ath9k/ar9003_hw.c | 25 +++++++++++++------------ drivers/net/wireless/ath/ath9k/ar9003_phy.c | 16 ++++------------ drivers/net/wireless/ath/ath9k/hw.h | 4 ++-- 5 files changed, 22 insertions(+), 30 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar5008_phy.c b/drivers/net/wireless/ath/ath9k/ar5008_phy.c index 86a891f93fc9..5d34e57ce50b 100644 --- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c @@ -869,10 +869,9 @@ static int ar5008_hw_process_ini(struct ath_hw *ah, REG_WRITE_ARRAY(&ah->iniBB_RfGain, freqIndex, regWrites); - if (IS_CHAN_A_FAST_CLOCK(ah, chan)) { - REG_WRITE_ARRAY(&ah->iniModesAdditional, modesIndex, + if (IS_CHAN_A_FAST_CLOCK(ah, chan)) + REG_WRITE_ARRAY(&ah->iniModesFastClock, modesIndex, regWrites); - } ar5008_hw_override_ini(ah, chan); ar5008_hw_set_channel_regs(ah, chan); diff --git a/drivers/net/wireless/ath/ath9k/ar9002_hw.c b/drivers/net/wireless/ath/ath9k/ar9002_hw.c index 1d06dab27030..7098cd8eee60 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_hw.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_hw.c @@ -73,7 +73,7 @@ static void ar9002_hw_init_mode_regs(struct ath_hw *ah) INIT_INI_ARRAY(&ah->iniCommon, ar9280Common_9280_2, ARRAY_SIZE(ar9280Common_9280_2), 2); - INIT_INI_ARRAY(&ah->iniModesAdditional, + INIT_INI_ARRAY(&ah->iniModesFastClock, ar9280Modes_fast_clock_9280_2, ARRAY_SIZE(ar9280Modes_fast_clock_9280_2), 3); } else if (AR_SREV_9160_10_OR_LATER(ah)) { diff --git a/drivers/net/wireless/ath/ath9k/ar9003_hw.c b/drivers/net/wireless/ath/ath9k/ar9003_hw.c index 7b4aa000cc2e..0f56e322dd3b 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_hw.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_hw.c @@ -87,11 +87,11 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah) /* additional clock settings */ if (ah->is_clk_25mhz) - INIT_INI_ARRAY(&ah->iniModesAdditional, + INIT_INI_ARRAY(&ah->iniAdditional, ar9331_1p1_xtal_25M, ARRAY_SIZE(ar9331_1p1_xtal_25M), 2); else - INIT_INI_ARRAY(&ah->iniModesAdditional, + INIT_INI_ARRAY(&ah->iniAdditional, ar9331_1p1_xtal_40M, ARRAY_SIZE(ar9331_1p1_xtal_40M), 2); } else if (AR_SREV_9330_12(ah)) { @@ -140,11 +140,11 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah) /* additional clock settings */ if (ah->is_clk_25mhz) - INIT_INI_ARRAY(&ah->iniModesAdditional, + INIT_INI_ARRAY(&ah->iniAdditional, ar9331_1p2_xtal_25M, ARRAY_SIZE(ar9331_1p2_xtal_25M), 2); else - INIT_INI_ARRAY(&ah->iniModesAdditional, + INIT_INI_ARRAY(&ah->iniAdditional, ar9331_1p2_xtal_40M, ARRAY_SIZE(ar9331_1p2_xtal_40M), 2); } else if (AR_SREV_9340(ah)) { @@ -194,15 +194,16 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah) ARRAY_SIZE(ar9340Modes_high_ob_db_tx_gain_table_1p0), 5); - INIT_INI_ARRAY(&ah->iniModesAdditional, + INIT_INI_ARRAY(&ah->iniModesFastClock, ar9340Modes_fast_clock_1p0, ARRAY_SIZE(ar9340Modes_fast_clock_1p0), 3); - INIT_INI_ARRAY(&ah->iniModesAdditional_40M, - ar9340_1p0_radio_core_40M, - ARRAY_SIZE(ar9340_1p0_radio_core_40M), - 2); + if (!ah->is_clk_25mhz) + INIT_INI_ARRAY(&ah->iniAdditional, + ar9340_1p0_radio_core_40M, + ARRAY_SIZE(ar9340_1p0_radio_core_40M), + 2); } else if (AR_SREV_9485_11(ah)) { /* mac */ INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0); @@ -321,7 +322,7 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah) 2); /* Fast clock modal settings */ - INIT_INI_ARRAY(&ah->iniModesAdditional, + INIT_INI_ARRAY(&ah->iniModesFastClock, ar9462_modes_fast_clock_2p0, ARRAY_SIZE(ar9462_modes_fast_clock_2p0), 3); @@ -378,7 +379,7 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah) ARRAY_SIZE(ar9580_1p0_low_ob_db_tx_gain_table), 5); - INIT_INI_ARRAY(&ah->iniModesAdditional, + INIT_INI_ARRAY(&ah->iniModesFastClock, ar9580_1p0_modes_fast_clock, ARRAY_SIZE(ar9580_1p0_modes_fast_clock), 3); @@ -445,7 +446,7 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah) 2); /* Fast clock modal settings */ - INIT_INI_ARRAY(&ah->iniModesAdditional, + INIT_INI_ARRAY(&ah->iniModesFastClock, ar9300Modes_fast_clock_2p2, ARRAY_SIZE(ar9300Modes_fast_clock_2p2), 3); diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c index 99b64f27bb22..bc992b237ae5 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c @@ -679,14 +679,10 @@ static int ar9003_hw_process_ini(struct ath_hw *ah, * different modal values. */ if (IS_CHAN_A_FAST_CLOCK(ah, chan)) - REG_WRITE_ARRAY(&ah->iniModesAdditional, + REG_WRITE_ARRAY(&ah->iniModesFastClock, modesIndex, regWrites); - if (AR_SREV_9330(ah)) - REG_WRITE_ARRAY(&ah->iniModesAdditional, 1, regWrites); - - if (AR_SREV_9340(ah) && !ah->is_clk_25mhz) - REG_WRITE_ARRAY(&ah->iniModesAdditional_40M, 1, regWrites); + REG_WRITE_ARRAY(&ah->iniAdditional, 1, regWrites); if (AR_SREV_9462(ah)) ar9003_hw_prog_ini(ah, &ah->ini_BTCOEX_MAX_TXPWR, 1); @@ -1323,13 +1319,9 @@ static int ar9003_hw_fast_chan_change(struct ath_hw *ah, * different modal values. */ if (IS_CHAN_A_FAST_CLOCK(ah, chan)) - REG_WRITE_ARRAY(&ah->iniModesAdditional, modesIndex, regWrites); - - if (AR_SREV_9330(ah)) - REG_WRITE_ARRAY(&ah->iniModesAdditional, 1, regWrites); + REG_WRITE_ARRAY(&ah->iniModesFastClock, modesIndex, regWrites); - if (AR_SREV_9340(ah) && !ah->is_clk_25mhz) - REG_WRITE_ARRAY(&ah->iniModesAdditional_40M, 1, regWrites); + REG_WRITE_ARRAY(&ah->iniAdditional, 1, regWrites); ah->modes_index = modesIndex; *ini_reloaded = true; diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index 4bd2c89654d4..7822d5ecbf8b 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -827,8 +827,8 @@ struct ath_hw { struct ar5416IniArray iniAddac; struct ar5416IniArray iniPcieSerdes; struct ar5416IniArray iniPcieSerdesLowPower; - struct ar5416IniArray iniModesAdditional; - struct ar5416IniArray iniModesAdditional_40M; + struct ar5416IniArray iniModesFastClock; + struct ar5416IniArray iniAdditional; struct ar5416IniArray iniModesRxGain; struct ar5416IniArray iniModesTxGain; struct ar5416IniArray iniModes_9271_1_0_only; -- cgit From aa0e5786b6e0cf2adaa26d72770cb5a0ad263026 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 14 Mar 2012 16:40:32 +0100 Subject: ath9k_hw: remove iniModes_*_tx_gain_9271 Program tx gain through iniModesTxGain like on AR9287 Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar5008_phy.c | 9 -------- drivers/net/wireless/ath/ath9k/ar9002_hw.c | 34 ++++++++++++++++------------- drivers/net/wireless/ath/ath9k/hw.h | 2 -- 3 files changed, 19 insertions(+), 26 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar5008_phy.c b/drivers/net/wireless/ath/ath9k/ar5008_phy.c index 5d34e57ce50b..3e108c8b1d32 100644 --- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c @@ -858,15 +858,6 @@ static int ar5008_hw_process_ini(struct ath_hw *ah, REGWRITE_BUFFER_FLUSH(ah); - if (AR_SREV_9271(ah)) { - if (ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE) == 1) - REG_WRITE_ARRAY(&ah->iniModes_high_power_tx_gain_9271, - modesIndex, regWrites); - else - REG_WRITE_ARRAY(&ah->iniModes_normal_power_tx_gain_9271, - modesIndex, regWrites); - } - REG_WRITE_ARRAY(&ah->iniBB_RfGain, freqIndex, regWrites); if (IS_CHAN_A_FAST_CLOCK(ah, chan)) diff --git a/drivers/net/wireless/ath/ath9k/ar9002_hw.c b/drivers/net/wireless/ath/ath9k/ar9002_hw.c index 7098cd8eee60..99d2dd979d1c 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_hw.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_hw.c @@ -39,12 +39,6 @@ static void ar9002_hw_init_mode_regs(struct ath_hw *ah) ARRAY_SIZE(ar9271Modes_9271_1_0_only), 5); INIT_INI_ARRAY(&ah->iniModes_9271_ANI_reg, ar9271Modes_9271_ANI_reg, ARRAY_SIZE(ar9271Modes_9271_ANI_reg), 5); - INIT_INI_ARRAY(&ah->iniModes_high_power_tx_gain_9271, - ar9271Modes_high_power_tx_gain_9271, - ARRAY_SIZE(ar9271Modes_high_power_tx_gain_9271), 5); - INIT_INI_ARRAY(&ah->iniModes_normal_power_tx_gain_9271, - ar9271Modes_normal_power_tx_gain_9271, - ARRAY_SIZE(ar9271Modes_normal_power_tx_gain_9271), 5); return; } @@ -193,14 +187,10 @@ static void ar9280_20_hw_init_rxgain_ini(struct ath_hw *ah) } } -static void ar9280_20_hw_init_txgain_ini(struct ath_hw *ah) +static void ar9280_20_hw_init_txgain_ini(struct ath_hw *ah, u32 txgain_type) { - u32 txgain_type; - if (ah->eep_ops->get_eeprom(ah, EEP_MINOR_REV) >= AR5416_EEP_MINOR_VER_19) { - txgain_type = ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE); - if (txgain_type == AR5416_EEP_TXGAIN_HIGH_POWER) INIT_INI_ARRAY(&ah->iniModesTxGain, ar9280Modes_high_power_tx_gain_9280_2, @@ -216,8 +206,22 @@ static void ar9280_20_hw_init_txgain_ini(struct ath_hw *ah) } } +static void ar9271_hw_init_txgain_ini(struct ath_hw *ah, u32 txgain_type) +{ + if (txgain_type == AR5416_EEP_TXGAIN_HIGH_POWER) + INIT_INI_ARRAY(&ah->iniModesTxGain, + ar9271Modes_high_power_tx_gain_9271, + ARRAY_SIZE(ar9271Modes_high_power_tx_gain_9271), 5); + else + INIT_INI_ARRAY(&ah->iniModesTxGain, + ar9271Modes_normal_power_tx_gain_9271, + ARRAY_SIZE(ar9271Modes_normal_power_tx_gain_9271), 5); +} + static void ar9002_hw_init_mode_gain_regs(struct ath_hw *ah) { + u32 txgain_type = ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE); + if (AR_SREV_9287_11_OR_LATER(ah)) INIT_INI_ARRAY(&ah->iniModesRxGain, ar9287Modes_rx_gain_9287_1_1, @@ -225,15 +229,15 @@ static void ar9002_hw_init_mode_gain_regs(struct ath_hw *ah) else if (AR_SREV_9280_20(ah)) ar9280_20_hw_init_rxgain_ini(ah); - if (AR_SREV_9287_11_OR_LATER(ah)) { + if (AR_SREV_9271(ah)) { + ar9271_hw_init_txgain_ini(ah, txgain_type); + } else if (AR_SREV_9287_11_OR_LATER(ah)) { INIT_INI_ARRAY(&ah->iniModesTxGain, ar9287Modes_tx_gain_9287_1_1, ARRAY_SIZE(ar9287Modes_tx_gain_9287_1_1), 5); } else if (AR_SREV_9280_20(ah)) { - ar9280_20_hw_init_txgain_ini(ah); + ar9280_20_hw_init_txgain_ini(ah, txgain_type); } else if (AR_SREV_9285_12_OR_LATER(ah)) { - u32 txgain_type = ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE); - /* txgain table */ if (txgain_type == AR5416_EEP_TXGAIN_HIGH_POWER) { if (AR_SREV_9285E_20(ah)) { diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index 7822d5ecbf8b..ca673a8757d6 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -836,8 +836,6 @@ struct ath_hw { struct ar5416IniArray iniCckfirJapan2484; struct ar5416IniArray ini_japan2484; struct ar5416IniArray iniModes_9271_ANI_reg; - struct ar5416IniArray iniModes_high_power_tx_gain_9271; - struct ar5416IniArray iniModes_normal_power_tx_gain_9271; struct ar5416IniArray ini_radio_post_sys2ant; struct ar5416IniArray ini_BTCOEX_MAX_TXPWR; -- cgit From c7effd35932b948c2a18159e96a07e1686703e62 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 14 Mar 2012 16:40:33 +0100 Subject: ath9k: inline AR9271 1.0 INI overrides Makes them more readable and reduces code size Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar5008_phy.c | 7 ++++--- drivers/net/wireless/ath/ath9k/ar9002_hw.c | 3 --- drivers/net/wireless/ath/ath9k/ar9002_initvals.h | 6 ------ drivers/net/wireless/ath/ath9k/ar9002_phy.h | 2 ++ drivers/net/wireless/ath/ath9k/hw.h | 1 - 5 files changed, 6 insertions(+), 13 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar5008_phy.c b/drivers/net/wireless/ath/ath9k/ar5008_phy.c index 3e108c8b1d32..d7d8e9199140 100644 --- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c @@ -834,9 +834,10 @@ static int ar5008_hw_process_ini(struct ath_hw *ah, AR_SREV_9287_11_OR_LATER(ah)) REG_WRITE_ARRAY(&ah->iniModesTxGain, modesIndex, regWrites); - if (AR_SREV_9271_10(ah)) - REG_WRITE_ARRAY(&ah->iniModes_9271_1_0_only, - modesIndex, regWrites); + if (AR_SREV_9271_10(ah)) { + REG_SET_BIT(ah, AR_PHY_SPECTRAL_SCAN, AR_PHY_SPECTRAL_SCAN_ENA); + REG_RMW_FIELD(ah, AR_PHY_RF_CTL3, AR_PHY_TX_END_TO_ADC_ON, 0xa); + } ENABLE_REGWRITE_BUFFER(ah); diff --git a/drivers/net/wireless/ath/ath9k/ar9002_hw.c b/drivers/net/wireless/ath/ath9k/ar9002_hw.c index 99d2dd979d1c..d9a69fc470cd 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_hw.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_hw.c @@ -34,9 +34,6 @@ static void ar9002_hw_init_mode_regs(struct ath_hw *ah) ARRAY_SIZE(ar9271Modes_9271), 5); INIT_INI_ARRAY(&ah->iniCommon, ar9271Common_9271, ARRAY_SIZE(ar9271Common_9271), 2); - INIT_INI_ARRAY(&ah->iniModes_9271_1_0_only, - ar9271Modes_9271_1_0_only, - ARRAY_SIZE(ar9271Modes_9271_1_0_only), 5); INIT_INI_ARRAY(&ah->iniModes_9271_ANI_reg, ar9271Modes_9271_ANI_reg, ARRAY_SIZE(ar9271Modes_9271_ANI_reg), 5); return; diff --git a/drivers/net/wireless/ath/ath9k/ar9002_initvals.h b/drivers/net/wireless/ath/ath9k/ar9002_initvals.h index d571c329ee59..4d18c66a6790 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar9002_initvals.h @@ -3092,12 +3092,6 @@ static const u32 ar9271Common_9271[][2] = { {0x0000d384, 0xf3307ff0}, }; -static const u32 ar9271Modes_9271_1_0_only[][5] = { - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ - {0x00009910, 0x30002311, 0x30002311, 0x30002311, 0x30002311}, - {0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001}, -}; - static const u32 ar9271Modes_9271_ANI_reg[][5] = { /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ {0x00009850, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2}, diff --git a/drivers/net/wireless/ath/ath9k/ar9002_phy.h b/drivers/net/wireless/ath/ath9k/ar9002_phy.h index 453af6dc514b..f9eb2c357169 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_phy.h +++ b/drivers/net/wireless/ath/ath9k/ar9002_phy.h @@ -60,6 +60,8 @@ #define AR_PHY_RF_CTL3 0x9828 #define AR_PHY_TX_END_TO_A2_RX_ON 0x00FF0000 #define AR_PHY_TX_END_TO_A2_RX_ON_S 16 +#define AR_PHY_TX_END_TO_ADC_ON 0xFF000000 +#define AR_PHY_TX_END_TO_ADC_ON_S 24 #define AR_PHY_ADC_CTL 0x982C #define AR_PHY_ADC_CTL_OFF_INBUFGAIN 0x00000003 diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index ca673a8757d6..aa1680a0c7fd 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -831,7 +831,6 @@ struct ath_hw { struct ar5416IniArray iniAdditional; struct ar5416IniArray iniModesRxGain; struct ar5416IniArray iniModesTxGain; - struct ar5416IniArray iniModes_9271_1_0_only; struct ar5416IniArray iniCckfirNormal; struct ar5416IniArray iniCckfirJapan2484; struct ar5416IniArray ini_japan2484; -- cgit From 783b732ac61dd6c653cc2367f389a6234db8cc16 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 14 Mar 2012 16:40:34 +0100 Subject: ath9k_hw: remove unused initvals Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- .../net/wireless/ath/ath9k/ar9003_2p2_initvals.h | 302 --------------------- 1 file changed, 302 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h index 026f9de15d15..46c79a3d4737 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h @@ -295,266 +295,6 @@ static const u32 ar9300_2p2_radio_core[][2] = { {0x00016bd4, 0x00000000}, }; -static const u32 ar9300Common_rx_gain_table_merlin_2p2[][2] = { - /* Addr allmodes */ - {0x0000a000, 0x02000101}, - {0x0000a004, 0x02000102}, - {0x0000a008, 0x02000103}, - {0x0000a00c, 0x02000104}, - {0x0000a010, 0x02000200}, - {0x0000a014, 0x02000201}, - {0x0000a018, 0x02000202}, - {0x0000a01c, 0x02000203}, - {0x0000a020, 0x02000204}, - {0x0000a024, 0x02000205}, - {0x0000a028, 0x02000208}, - {0x0000a02c, 0x02000302}, - {0x0000a030, 0x02000303}, - {0x0000a034, 0x02000304}, - {0x0000a038, 0x02000400}, - {0x0000a03c, 0x02010300}, - {0x0000a040, 0x02010301}, - {0x0000a044, 0x02010302}, - {0x0000a048, 0x02000500}, - {0x0000a04c, 0x02010400}, - {0x0000a050, 0x02020300}, - {0x0000a054, 0x02020301}, - {0x0000a058, 0x02020302}, - {0x0000a05c, 0x02020303}, - {0x0000a060, 0x02020400}, - {0x0000a064, 0x02030300}, - {0x0000a068, 0x02030301}, - {0x0000a06c, 0x02030302}, - {0x0000a070, 0x02030303}, - {0x0000a074, 0x02030400}, - {0x0000a078, 0x02040300}, - {0x0000a07c, 0x02040301}, - {0x0000a080, 0x02040302}, - {0x0000a084, 0x02040303}, - {0x0000a088, 0x02030500}, - {0x0000a08c, 0x02040400}, - {0x0000a090, 0x02050203}, - {0x0000a094, 0x02050204}, - {0x0000a098, 0x02050205}, - {0x0000a09c, 0x02040500}, - {0x0000a0a0, 0x02050301}, - {0x0000a0a4, 0x02050302}, - {0x0000a0a8, 0x02050303}, - {0x0000a0ac, 0x02050400}, - {0x0000a0b0, 0x02050401}, - {0x0000a0b4, 0x02050402}, - {0x0000a0b8, 0x02050403}, - {0x0000a0bc, 0x02050500}, - {0x0000a0c0, 0x02050501}, - {0x0000a0c4, 0x02050502}, - {0x0000a0c8, 0x02050503}, - {0x0000a0cc, 0x02050504}, - {0x0000a0d0, 0x02050600}, - {0x0000a0d4, 0x02050601}, - {0x0000a0d8, 0x02050602}, - {0x0000a0dc, 0x02050603}, - {0x0000a0e0, 0x02050604}, - {0x0000a0e4, 0x02050700}, - {0x0000a0e8, 0x02050701}, - {0x0000a0ec, 0x02050702}, - {0x0000a0f0, 0x02050703}, - {0x0000a0f4, 0x02050704}, - {0x0000a0f8, 0x02050705}, - {0x0000a0fc, 0x02050708}, - {0x0000a100, 0x02050709}, - {0x0000a104, 0x0205070a}, - {0x0000a108, 0x0205070b}, - {0x0000a10c, 0x0205070c}, - {0x0000a110, 0x0205070d}, - {0x0000a114, 0x02050710}, - {0x0000a118, 0x02050711}, - {0x0000a11c, 0x02050712}, - {0x0000a120, 0x02050713}, - {0x0000a124, 0x02050714}, - {0x0000a128, 0x02050715}, - {0x0000a12c, 0x02050730}, - {0x0000a130, 0x02050731}, - {0x0000a134, 0x02050732}, - {0x0000a138, 0x02050733}, - {0x0000a13c, 0x02050734}, - {0x0000a140, 0x02050735}, - {0x0000a144, 0x02050750}, - {0x0000a148, 0x02050751}, - {0x0000a14c, 0x02050752}, - {0x0000a150, 0x02050753}, - {0x0000a154, 0x02050754}, - {0x0000a158, 0x02050755}, - {0x0000a15c, 0x02050770}, - {0x0000a160, 0x02050771}, - {0x0000a164, 0x02050772}, - {0x0000a168, 0x02050773}, - {0x0000a16c, 0x02050774}, - {0x0000a170, 0x02050775}, - {0x0000a174, 0x00000776}, - {0x0000a178, 0x00000776}, - {0x0000a17c, 0x00000776}, - {0x0000a180, 0x00000776}, - {0x0000a184, 0x00000776}, - {0x0000a188, 0x00000776}, - {0x0000a18c, 0x00000776}, - {0x0000a190, 0x00000776}, - {0x0000a194, 0x00000776}, - {0x0000a198, 0x00000776}, - {0x0000a19c, 0x00000776}, - {0x0000a1a0, 0x00000776}, - {0x0000a1a4, 0x00000776}, - {0x0000a1a8, 0x00000776}, - {0x0000a1ac, 0x00000776}, - {0x0000a1b0, 0x00000776}, - {0x0000a1b4, 0x00000776}, - {0x0000a1b8, 0x00000776}, - {0x0000a1bc, 0x00000776}, - {0x0000a1c0, 0x00000776}, - {0x0000a1c4, 0x00000776}, - {0x0000a1c8, 0x00000776}, - {0x0000a1cc, 0x00000776}, - {0x0000a1d0, 0x00000776}, - {0x0000a1d4, 0x00000776}, - {0x0000a1d8, 0x00000776}, - {0x0000a1dc, 0x00000776}, - {0x0000a1e0, 0x00000776}, - {0x0000a1e4, 0x00000776}, - {0x0000a1e8, 0x00000776}, - {0x0000a1ec, 0x00000776}, - {0x0000a1f0, 0x00000776}, - {0x0000a1f4, 0x00000776}, - {0x0000a1f8, 0x00000776}, - {0x0000a1fc, 0x00000776}, - {0x0000b000, 0x02000101}, - {0x0000b004, 0x02000102}, - {0x0000b008, 0x02000103}, - {0x0000b00c, 0x02000104}, - {0x0000b010, 0x02000200}, - {0x0000b014, 0x02000201}, - {0x0000b018, 0x02000202}, - {0x0000b01c, 0x02000203}, - {0x0000b020, 0x02000204}, - {0x0000b024, 0x02000205}, - {0x0000b028, 0x02000208}, - {0x0000b02c, 0x02000302}, - {0x0000b030, 0x02000303}, - {0x0000b034, 0x02000304}, - {0x0000b038, 0x02000400}, - {0x0000b03c, 0x02010300}, - {0x0000b040, 0x02010301}, - {0x0000b044, 0x02010302}, - {0x0000b048, 0x02000500}, - {0x0000b04c, 0x02010400}, - {0x0000b050, 0x02020300}, - {0x0000b054, 0x02020301}, - {0x0000b058, 0x02020302}, - {0x0000b05c, 0x02020303}, - {0x0000b060, 0x02020400}, - {0x0000b064, 0x02030300}, - {0x0000b068, 0x02030301}, - {0x0000b06c, 0x02030302}, - {0x0000b070, 0x02030303}, - {0x0000b074, 0x02030400}, - {0x0000b078, 0x02040300}, - {0x0000b07c, 0x02040301}, - {0x0000b080, 0x02040302}, - {0x0000b084, 0x02040303}, - {0x0000b088, 0x02030500}, - {0x0000b08c, 0x02040400}, - {0x0000b090, 0x02050203}, - {0x0000b094, 0x02050204}, - {0x0000b098, 0x02050205}, - {0x0000b09c, 0x02040500}, - {0x0000b0a0, 0x02050301}, - {0x0000b0a4, 0x02050302}, - {0x0000b0a8, 0x02050303}, - {0x0000b0ac, 0x02050400}, - {0x0000b0b0, 0x02050401}, - {0x0000b0b4, 0x02050402}, - {0x0000b0b8, 0x02050403}, - {0x0000b0bc, 0x02050500}, - {0x0000b0c0, 0x02050501}, - {0x0000b0c4, 0x02050502}, - {0x0000b0c8, 0x02050503}, - {0x0000b0cc, 0x02050504}, - {0x0000b0d0, 0x02050600}, - {0x0000b0d4, 0x02050601}, - {0x0000b0d8, 0x02050602}, - {0x0000b0dc, 0x02050603}, - {0x0000b0e0, 0x02050604}, - {0x0000b0e4, 0x02050700}, - {0x0000b0e8, 0x02050701}, - {0x0000b0ec, 0x02050702}, - {0x0000b0f0, 0x02050703}, - {0x0000b0f4, 0x02050704}, - {0x0000b0f8, 0x02050705}, - {0x0000b0fc, 0x02050708}, - {0x0000b100, 0x02050709}, - {0x0000b104, 0x0205070a}, - {0x0000b108, 0x0205070b}, - {0x0000b10c, 0x0205070c}, - {0x0000b110, 0x0205070d}, - {0x0000b114, 0x02050710}, - {0x0000b118, 0x02050711}, - {0x0000b11c, 0x02050712}, - {0x0000b120, 0x02050713}, - {0x0000b124, 0x02050714}, - {0x0000b128, 0x02050715}, - {0x0000b12c, 0x02050730}, - {0x0000b130, 0x02050731}, - {0x0000b134, 0x02050732}, - {0x0000b138, 0x02050733}, - {0x0000b13c, 0x02050734}, - {0x0000b140, 0x02050735}, - {0x0000b144, 0x02050750}, - {0x0000b148, 0x02050751}, - {0x0000b14c, 0x02050752}, - {0x0000b150, 0x02050753}, - {0x0000b154, 0x02050754}, - {0x0000b158, 0x02050755}, - {0x0000b15c, 0x02050770}, - {0x0000b160, 0x02050771}, - {0x0000b164, 0x02050772}, - {0x0000b168, 0x02050773}, - {0x0000b16c, 0x02050774}, - {0x0000b170, 0x02050775}, - {0x0000b174, 0x00000776}, - {0x0000b178, 0x00000776}, - {0x0000b17c, 0x00000776}, - {0x0000b180, 0x00000776}, - {0x0000b184, 0x00000776}, - {0x0000b188, 0x00000776}, - {0x0000b18c, 0x00000776}, - {0x0000b190, 0x00000776}, - {0x0000b194, 0x00000776}, - {0x0000b198, 0x00000776}, - {0x0000b19c, 0x00000776}, - {0x0000b1a0, 0x00000776}, - {0x0000b1a4, 0x00000776}, - {0x0000b1a8, 0x00000776}, - {0x0000b1ac, 0x00000776}, - {0x0000b1b0, 0x00000776}, - {0x0000b1b4, 0x00000776}, - {0x0000b1b8, 0x00000776}, - {0x0000b1bc, 0x00000776}, - {0x0000b1c0, 0x00000776}, - {0x0000b1c4, 0x00000776}, - {0x0000b1c8, 0x00000776}, - {0x0000b1cc, 0x00000776}, - {0x0000b1d0, 0x00000776}, - {0x0000b1d4, 0x00000776}, - {0x0000b1d8, 0x00000776}, - {0x0000b1dc, 0x00000776}, - {0x0000b1e0, 0x00000776}, - {0x0000b1e4, 0x00000776}, - {0x0000b1e8, 0x00000776}, - {0x0000b1ec, 0x00000776}, - {0x0000b1f0, 0x00000776}, - {0x0000b1f4, 0x00000776}, - {0x0000b1f8, 0x00000776}, - {0x0000b1fc, 0x00000776}, -}; - static const u32 ar9300_2p2_mac_postamble[][5] = { /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160}, @@ -572,48 +312,6 @@ static const u32 ar9300_2p2_soc_postamble[][5] = { {0x00007010, 0x00000023, 0x00000023, 0x00000023, 0x00000023}, }; -static const u32 ar9200_merlin_2p2_radio_core[][2] = { - /* Addr allmodes */ - {0x00007800, 0x00040000}, - {0x00007804, 0xdb005012}, - {0x00007808, 0x04924914}, - {0x0000780c, 0x21084210}, - {0x00007810, 0x6d801300}, - {0x00007814, 0x0019beff}, - {0x00007818, 0x07e41000}, - {0x0000781c, 0x00392000}, - {0x00007820, 0x92592480}, - {0x00007824, 0x00040000}, - {0x00007828, 0xdb005012}, - {0x0000782c, 0x04924914}, - {0x00007830, 0x21084210}, - {0x00007834, 0x6d801300}, - {0x00007838, 0x0019beff}, - {0x0000783c, 0x07e40000}, - {0x00007840, 0x00392000}, - {0x00007844, 0x92592480}, - {0x00007848, 0x00100000}, - {0x0000784c, 0x773f0567}, - {0x00007850, 0x54214514}, - {0x00007854, 0x12035828}, - {0x00007858, 0x92592692}, - {0x0000785c, 0x00000000}, - {0x00007860, 0x56400000}, - {0x00007864, 0x0a8e370e}, - {0x00007868, 0xc0102850}, - {0x0000786c, 0x812d4000}, - {0x00007870, 0x807ec400}, - {0x00007874, 0x001b6db0}, - {0x00007878, 0x00376b63}, - {0x0000787c, 0x06db6db6}, - {0x00007880, 0x006d8000}, - {0x00007884, 0xffeffffe}, - {0x00007888, 0xffeffffe}, - {0x0000788c, 0x00010000}, - {0x00007890, 0x02060aeb}, - {0x00007894, 0x5a108000}, -}; - static const u32 ar9300_2p2_baseband_postamble[][5] = { /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8011, 0xd00a8011}, -- cgit From 377526578f2c343ea281a918b18ece1fca65005c Mon Sep 17 00:00:00 2001 From: Daniel Drake Date: Wed, 14 Mar 2012 22:34:33 +0000 Subject: libertas: remove dump_survey implementation libertas provides a dump_survey implementation based on reading of a RSSI value. However, this RSSI value is calculated based on the last received beacon from the associated AP - it is not a good way of surveying a channel in general, and even causes an error if the card is not associated to a network. As this is not appropriate as a survey, remove it. This fixes an issue where something in userspace is repeatedly calling site-survey during boot, resulting in many repeated errors as the RSSI value cannot be read before associating. Signed-off-by: Daniel Drake Signed-off-by: John W. Linville --- drivers/net/wireless/libertas/cfg.c | 37 ------------------------------------- 1 file changed, 37 deletions(-) diff --git a/drivers/net/wireless/libertas/cfg.c b/drivers/net/wireless/libertas/cfg.c index a7cd311cb1b7..3fa1ecebadfd 100644 --- a/drivers/net/wireless/libertas/cfg.c +++ b/drivers/net/wireless/libertas/cfg.c @@ -1630,42 +1630,6 @@ static int lbs_cfg_get_station(struct wiphy *wiphy, struct net_device *dev, -/* - * "Site survey", here just current channel and noise level - */ - -static int lbs_get_survey(struct wiphy *wiphy, struct net_device *dev, - int idx, struct survey_info *survey) -{ - struct lbs_private *priv = wiphy_priv(wiphy); - s8 signal, noise; - int ret; - - if (dev == priv->mesh_dev) - return -EOPNOTSUPP; - - if (idx != 0) - ret = -ENOENT; - - lbs_deb_enter(LBS_DEB_CFG80211); - - survey->channel = ieee80211_get_channel(wiphy, - ieee80211_channel_to_frequency(priv->channel, - IEEE80211_BAND_2GHZ)); - - ret = lbs_get_rssi(priv, &signal, &noise); - if (ret == 0) { - survey->filled = SURVEY_INFO_NOISE_DBM; - survey->noise = noise; - } - - lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret); - return ret; -} - - - - /* * Change interface */ @@ -2068,7 +2032,6 @@ static struct cfg80211_ops lbs_cfg80211_ops = { .del_key = lbs_cfg_del_key, .set_default_key = lbs_cfg_set_default_key, .get_station = lbs_cfg_get_station, - .dump_survey = lbs_get_survey, .change_virtual_intf = lbs_change_intf, .join_ibss = lbs_join_ibss, .leave_ibss = lbs_leave_ibss, -- cgit