diff options
author | Johannes Berg <johannes.berg@intel.com> | 2010-08-23 04:46:47 -0400 |
---|---|---|
committer | Wey-Yi Guy <wey-yi.w.guy@intel.com> | 2010-08-27 12:27:44 -0400 |
commit | 76d048151cf935281998b591e070581fc438e27e (patch) | |
tree | d1a81aa9d0d2bf8a7fd481aed1510b821ec96ec4 /drivers/net/wireless | |
parent | 7e6a588601eb85feb10c7e8898f1f69c3b229a20 (diff) |
iwlwifi: introduce beacon context
Only one context can be beaconing at a time,
but we need to track which one. Introduce a
new variable priv->beacon_ctx to do that.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-agn.c | 32 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-core.c | 30 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-core.h | 3 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-dev.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl3945-base.c | 3 |
5 files changed, 50 insertions, 20 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 4efca99b2a9c..55d1cd4c1369 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c | |||
@@ -345,6 +345,13 @@ static unsigned int iwl_hw_get_beacon_cmd(struct iwl_priv *priv, | |||
345 | * beacon contents. | 345 | * beacon contents. |
346 | */ | 346 | */ |
347 | 347 | ||
348 | lockdep_assert_held(&priv->mutex); | ||
349 | |||
350 | if (!priv->beacon_ctx) { | ||
351 | IWL_ERR(priv, "trying to build beacon w/o beacon context!\n"); | ||
352 | return -EINVAL; | ||
353 | } | ||
354 | |||
348 | /* Initialize memory */ | 355 | /* Initialize memory */ |
349 | tx_beacon_cmd = &frame->u.beacon; | 356 | tx_beacon_cmd = &frame->u.beacon; |
350 | memset(tx_beacon_cmd, 0, sizeof(*tx_beacon_cmd)); | 357 | memset(tx_beacon_cmd, 0, sizeof(*tx_beacon_cmd)); |
@@ -357,9 +364,7 @@ static unsigned int iwl_hw_get_beacon_cmd(struct iwl_priv *priv, | |||
357 | 364 | ||
358 | /* Set up TX command fields */ | 365 | /* Set up TX command fields */ |
359 | tx_beacon_cmd->tx.len = cpu_to_le16((u16)frame_size); | 366 | tx_beacon_cmd->tx.len = cpu_to_le16((u16)frame_size); |
360 | #warning "Use proper STA ID" | 367 | tx_beacon_cmd->tx.sta_id = priv->beacon_ctx->bcast_sta_id; |
361 | tx_beacon_cmd->tx.sta_id = | ||
362 | priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id; | ||
363 | tx_beacon_cmd->tx.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE; | 368 | tx_beacon_cmd->tx.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE; |
364 | tx_beacon_cmd->tx.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK | | 369 | tx_beacon_cmd->tx.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK | |
365 | TX_CMD_FLG_TSF_MSK | TX_CMD_FLG_STA_RATE_MSK; | 370 | TX_CMD_FLG_TSF_MSK | TX_CMD_FLG_STA_RATE_MSK; |
@@ -369,7 +374,7 @@ static unsigned int iwl_hw_get_beacon_cmd(struct iwl_priv *priv, | |||
369 | frame_size); | 374 | frame_size); |
370 | 375 | ||
371 | /* Set up packet rate and flags */ | 376 | /* Set up packet rate and flags */ |
372 | rate = iwl_rate_get_lowest_plcp(priv); | 377 | rate = iwl_rate_get_lowest_plcp(priv, priv->beacon_ctx); |
373 | priv->mgmt_tx_ant = iwl_toggle_tx_ant(priv, priv->mgmt_tx_ant, | 378 | priv->mgmt_tx_ant = iwl_toggle_tx_ant(priv, priv->mgmt_tx_ant, |
374 | priv->hw_params.valid_tx_ant); | 379 | priv->hw_params.valid_tx_ant); |
375 | rate_flags = iwl_ant_idx_to_flags(priv->mgmt_tx_ant); | 380 | rate_flags = iwl_ant_idx_to_flags(priv->mgmt_tx_ant); |
@@ -602,25 +607,28 @@ static void iwl_bg_beacon_update(struct work_struct *work) | |||
602 | container_of(work, struct iwl_priv, beacon_update); | 607 | container_of(work, struct iwl_priv, beacon_update); |
603 | struct sk_buff *beacon; | 608 | struct sk_buff *beacon; |
604 | 609 | ||
605 | /* Pull updated AP beacon from mac80211. will fail if not in AP mode */ | 610 | mutex_lock(&priv->mutex); |
606 | #warning "introduce and use beacon context" | 611 | if (!priv->beacon_ctx) { |
607 | beacon = ieee80211_beacon_get(priv->hw, | 612 | IWL_ERR(priv, "updating beacon w/o beacon context!\n"); |
608 | priv->contexts[IWL_RXON_CTX_BSS].vif); | 613 | goto out; |
614 | } | ||
609 | 615 | ||
616 | /* Pull updated AP beacon from mac80211. will fail if not in AP mode */ | ||
617 | beacon = ieee80211_beacon_get(priv->hw, priv->beacon_ctx->vif); | ||
610 | if (!beacon) { | 618 | if (!beacon) { |
611 | IWL_ERR(priv, "update beacon failed\n"); | 619 | IWL_ERR(priv, "update beacon failed\n"); |
612 | return; | 620 | goto out; |
613 | } | 621 | } |
614 | 622 | ||
615 | mutex_lock(&priv->mutex); | ||
616 | /* new beacon skb is allocated every time; dispose previous.*/ | 623 | /* new beacon skb is allocated every time; dispose previous.*/ |
617 | if (priv->ibss_beacon) | 624 | if (priv->ibss_beacon) |
618 | dev_kfree_skb(priv->ibss_beacon); | 625 | dev_kfree_skb(priv->ibss_beacon); |
619 | 626 | ||
620 | priv->ibss_beacon = beacon; | 627 | priv->ibss_beacon = beacon; |
621 | mutex_unlock(&priv->mutex); | ||
622 | 628 | ||
623 | iwl_send_beacon_cmd(priv); | 629 | iwl_send_beacon_cmd(priv); |
630 | out: | ||
631 | mutex_unlock(&priv->mutex); | ||
624 | } | 632 | } |
625 | 633 | ||
626 | static void iwl_bg_bt_runtime_config(struct work_struct *work) | 634 | static void iwl_bg_bt_runtime_config(struct work_struct *work) |
@@ -3477,6 +3485,8 @@ void iwl_config_ap(struct iwl_priv *priv, struct ieee80211_vif *vif) | |||
3477 | struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif); | 3485 | struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif); |
3478 | int ret = 0; | 3486 | int ret = 0; |
3479 | 3487 | ||
3488 | lockdep_assert_held(&priv->mutex); | ||
3489 | |||
3480 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | 3490 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) |
3481 | return; | 3491 | return; |
3482 | 3492 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 8ec042d4e375..fb9173b1e5aa 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c | |||
@@ -699,11 +699,9 @@ int iwl_full_rxon_required(struct iwl_priv *priv, | |||
699 | } | 699 | } |
700 | EXPORT_SYMBOL(iwl_full_rxon_required); | 700 | EXPORT_SYMBOL(iwl_full_rxon_required); |
701 | 701 | ||
702 | u8 iwl_rate_get_lowest_plcp(struct iwl_priv *priv) | 702 | u8 iwl_rate_get_lowest_plcp(struct iwl_priv *priv, |
703 | struct iwl_rxon_context *ctx) | ||
703 | { | 704 | { |
704 | #if !TODO | ||
705 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; | ||
706 | #endif | ||
707 | /* | 705 | /* |
708 | * Assign the lowest rate -- should really get this from | 706 | * Assign the lowest rate -- should really get this from |
709 | * the beacon skb from mac80211. | 707 | * the beacon skb from mac80211. |
@@ -1723,6 +1721,14 @@ static int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
1723 | 1721 | ||
1724 | IWL_DEBUG_MAC80211(priv, "enter\n"); | 1722 | IWL_DEBUG_MAC80211(priv, "enter\n"); |
1725 | 1723 | ||
1724 | lockdep_assert_held(&priv->mutex); | ||
1725 | |||
1726 | if (!priv->beacon_ctx) { | ||
1727 | IWL_ERR(priv, "update beacon but no beacon context!\n"); | ||
1728 | dev_kfree_skb(skb); | ||
1729 | return -EINVAL; | ||
1730 | } | ||
1731 | |||
1726 | if (!iwl_is_ready_rf(priv)) { | 1732 | if (!iwl_is_ready_rf(priv)) { |
1727 | IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n"); | 1733 | IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n"); |
1728 | return -EIO; | 1734 | return -EIO; |
@@ -1741,9 +1747,7 @@ static int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
1741 | IWL_DEBUG_MAC80211(priv, "leave\n"); | 1747 | IWL_DEBUG_MAC80211(priv, "leave\n"); |
1742 | spin_unlock_irqrestore(&priv->lock, flags); | 1748 | spin_unlock_irqrestore(&priv->lock, flags); |
1743 | 1749 | ||
1744 | #warning "use beacon context?" | 1750 | priv->cfg->ops->lib->post_associate(priv, priv->beacon_ctx->vif); |
1745 | priv->cfg->ops->lib->post_associate( | ||
1746 | priv, priv->contexts[IWL_RXON_CTX_BSS].vif); | ||
1747 | 1751 | ||
1748 | return 0; | 1752 | return 0; |
1749 | } | 1753 | } |
@@ -1773,6 +1777,18 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw, | |||
1773 | spin_unlock_irqrestore(&priv->lock, flags); | 1777 | spin_unlock_irqrestore(&priv->lock, flags); |
1774 | } | 1778 | } |
1775 | 1779 | ||
1780 | if (changes & BSS_CHANGED_BEACON_ENABLED) { | ||
1781 | /* | ||
1782 | * the add_interface code must make sure we only ever | ||
1783 | * have a single interface that could be beaconing at | ||
1784 | * any time. | ||
1785 | */ | ||
1786 | if (vif->bss_conf.enable_beacon) | ||
1787 | priv->beacon_ctx = ctx; | ||
1788 | else | ||
1789 | priv->beacon_ctx = NULL; | ||
1790 | } | ||
1791 | |||
1776 | if (changes & BSS_CHANGED_BEACON && vif->type == NL80211_IFTYPE_AP) { | 1792 | if (changes & BSS_CHANGED_BEACON && vif->type == NL80211_IFTYPE_AP) { |
1777 | dev_kfree_skb(priv->ibss_beacon); | 1793 | dev_kfree_skb(priv->ibss_beacon); |
1778 | priv->ibss_beacon = ieee80211_beacon_get(hw, vif); | 1794 | priv->ibss_beacon = ieee80211_beacon_get(hw, vif); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 289fef8a881b..d2ee55d6811d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h | |||
@@ -523,7 +523,8 @@ int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force); | |||
523 | 523 | ||
524 | int iwl_hwrate_to_plcp_idx(u32 rate_n_flags); | 524 | int iwl_hwrate_to_plcp_idx(u32 rate_n_flags); |
525 | 525 | ||
526 | u8 iwl_rate_get_lowest_plcp(struct iwl_priv *priv); | 526 | u8 iwl_rate_get_lowest_plcp(struct iwl_priv *priv, |
527 | struct iwl_rxon_context *ctx); | ||
527 | 528 | ||
528 | u8 iwl_toggle_tx_ant(struct iwl_priv *priv, u8 ant_idx, u8 valid); | 529 | u8 iwl_toggle_tx_ant(struct iwl_priv *priv, u8 ant_idx, u8 valid); |
529 | 530 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index c17c67f767e6..e1565f734599 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h | |||
@@ -1437,6 +1437,8 @@ struct iwl_priv { | |||
1437 | struct work_struct rx_replenish; | 1437 | struct work_struct rx_replenish; |
1438 | struct work_struct abort_scan; | 1438 | struct work_struct abort_scan; |
1439 | struct work_struct beacon_update; | 1439 | struct work_struct beacon_update; |
1440 | struct iwl_rxon_context *beacon_ctx; | ||
1441 | |||
1440 | struct work_struct tt_work; | 1442 | struct work_struct tt_work; |
1441 | struct work_struct ct_enter; | 1443 | struct work_struct ct_enter; |
1442 | struct work_struct ct_exit; | 1444 | struct work_struct ct_exit; |
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index c048c1db42fd..e81c438b3348 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c | |||
@@ -343,7 +343,8 @@ static int iwl3945_send_beacon_cmd(struct iwl_priv *priv) | |||
343 | return -ENOMEM; | 343 | return -ENOMEM; |
344 | } | 344 | } |
345 | 345 | ||
346 | rate = iwl_rate_get_lowest_plcp(priv); | 346 | rate = iwl_rate_get_lowest_plcp(priv, |
347 | &priv->contexts[IWL_RXON_CTX_BSS]); | ||
347 | 348 | ||
348 | frame_size = iwl3945_hw_get_beacon_cmd(priv, frame, rate); | 349 | frame_size = iwl3945_hw_get_beacon_cmd(priv, frame, rate); |
349 | 350 | ||