aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl-mac80211.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-mac80211.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-mac80211.c71
1 files changed, 71 insertions, 0 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-mac80211.c b/drivers/net/wireless/iwlwifi/iwl-mac80211.c
index 6df08bb63ff..b46702c3471 100644
--- a/drivers/net/wireless/iwlwifi/iwl-mac80211.c
+++ b/drivers/net/wireless/iwlwifi/iwl-mac80211.c
@@ -1847,6 +1847,77 @@ static int iwlagn_mac_hw_scan(struct ieee80211_hw *hw,
1847 return ret; 1847 return ret;
1848} 1848}
1849 1849
1850static int iwlagn_mac_sta_remove(struct ieee80211_hw *hw,
1851 struct ieee80211_vif *vif,
1852 struct ieee80211_sta *sta)
1853{
1854 struct iwl_priv *priv = hw->priv;
1855 struct iwl_station_priv *sta_priv = (void *)sta->drv_priv;
1856 int ret;
1857
1858 IWL_DEBUG_MAC80211(priv, "enter: received request to remove "
1859 "station %pM\n", sta->addr);
1860 mutex_lock(&priv->shrd->mutex);
1861 IWL_DEBUG_INFO(priv, "proceeding to remove station %pM\n",
1862 sta->addr);
1863 ret = iwl_remove_station(priv, sta_priv->sta_id, sta->addr);
1864 if (ret)
1865 IWL_DEBUG_QUIET_RFKILL(priv, "Error removing station %pM\n",
1866 sta->addr);
1867 mutex_unlock(&priv->shrd->mutex);
1868 IWL_DEBUG_MAC80211(priv, "leave\n");
1869
1870 return ret;
1871}
1872
1873static void iwl_sta_modify_ps_wake(struct iwl_priv *priv, int sta_id)
1874{
1875 unsigned long flags;
1876
1877 spin_lock_irqsave(&priv->shrd->sta_lock, flags);
1878 priv->stations[sta_id].sta.station_flags &= ~STA_FLG_PWR_SAVE_MSK;
1879 priv->stations[sta_id].sta.station_flags_msk = STA_FLG_PWR_SAVE_MSK;
1880 priv->stations[sta_id].sta.sta.modify_mask = 0;
1881 priv->stations[sta_id].sta.sleep_tx_count = 0;
1882 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
1883 iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC);
1884 spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
1885
1886}
1887
1888static void iwlagn_mac_sta_notify(struct ieee80211_hw *hw,
1889 struct ieee80211_vif *vif,
1890 enum sta_notify_cmd cmd,
1891 struct ieee80211_sta *sta)
1892{
1893 struct iwl_priv *priv = hw->priv;
1894 struct iwl_station_priv *sta_priv = (void *)sta->drv_priv;
1895 int sta_id;
1896
1897 IWL_DEBUG_MAC80211(priv, "enter\n");
1898
1899 switch (cmd) {
1900 case STA_NOTIFY_SLEEP:
1901 WARN_ON(!sta_priv->client);
1902 sta_priv->asleep = true;
1903 if (atomic_read(&sta_priv->pending_frames) > 0)
1904 ieee80211_sta_block_awake(hw, sta, true);
1905 break;
1906 case STA_NOTIFY_AWAKE:
1907 WARN_ON(!sta_priv->client);
1908 if (!sta_priv->asleep)
1909 break;
1910 sta_priv->asleep = false;
1911 sta_id = iwl_sta_id(sta);
1912 if (sta_id != IWL_INVALID_STATION)
1913 iwl_sta_modify_ps_wake(priv, sta_id);
1914 break;
1915 default:
1916 break;
1917 }
1918 IWL_DEBUG_MAC80211(priv, "leave\n");
1919}
1920
1850struct ieee80211_ops iwlagn_hw_ops = { 1921struct ieee80211_ops iwlagn_hw_ops = {
1851 .tx = iwlagn_mac_tx, 1922 .tx = iwlagn_mac_tx,
1852 .start = iwlagn_mac_start, 1923 .start = iwlagn_mac_start,