.. | .. |
---|
1 | | -/** |
---|
| 1 | +/* |
---|
2 | 2 | * Copyright (c) 2014 Redpine Signals Inc. |
---|
3 | 3 | * |
---|
4 | 4 | * Permission to use, copy, modify, and/or distribute this software for any |
---|
.. | .. |
---|
230 | 230 | return 0; |
---|
231 | 231 | } |
---|
232 | 232 | |
---|
| 233 | +static int rsi_mac80211_hw_scan_start(struct ieee80211_hw *hw, |
---|
| 234 | + struct ieee80211_vif *vif, |
---|
| 235 | + struct ieee80211_scan_request *hw_req) |
---|
| 236 | +{ |
---|
| 237 | + struct cfg80211_scan_request *scan_req = &hw_req->req; |
---|
| 238 | + struct rsi_hw *adapter = hw->priv; |
---|
| 239 | + struct rsi_common *common = adapter->priv; |
---|
| 240 | + struct ieee80211_bss_conf *bss = &vif->bss_conf; |
---|
| 241 | + |
---|
| 242 | + rsi_dbg(INFO_ZONE, "***** Hardware scan start *****\n"); |
---|
| 243 | + common->mac_ops_resumed = false; |
---|
| 244 | + |
---|
| 245 | + if (common->fsm_state != FSM_MAC_INIT_DONE) |
---|
| 246 | + return -ENODEV; |
---|
| 247 | + |
---|
| 248 | + if ((common->wow_flags & RSI_WOW_ENABLED) || |
---|
| 249 | + scan_req->n_channels == 0) |
---|
| 250 | + return -EINVAL; |
---|
| 251 | + |
---|
| 252 | + /* Scan already in progress. So return */ |
---|
| 253 | + if (common->bgscan_en) |
---|
| 254 | + return -EBUSY; |
---|
| 255 | + |
---|
| 256 | + /* If STA is not connected, return with special value 1, in order |
---|
| 257 | + * to start sw_scan in mac80211 |
---|
| 258 | + */ |
---|
| 259 | + if (!bss->assoc) |
---|
| 260 | + return 1; |
---|
| 261 | + |
---|
| 262 | + mutex_lock(&common->mutex); |
---|
| 263 | + common->hwscan = scan_req; |
---|
| 264 | + if (!rsi_send_bgscan_params(common, RSI_START_BGSCAN)) { |
---|
| 265 | + if (!rsi_send_bgscan_probe_req(common, vif)) { |
---|
| 266 | + rsi_dbg(INFO_ZONE, "Background scan started...\n"); |
---|
| 267 | + common->bgscan_en = true; |
---|
| 268 | + } |
---|
| 269 | + } |
---|
| 270 | + mutex_unlock(&common->mutex); |
---|
| 271 | + |
---|
| 272 | + return 0; |
---|
| 273 | +} |
---|
| 274 | + |
---|
| 275 | +static void rsi_mac80211_cancel_hw_scan(struct ieee80211_hw *hw, |
---|
| 276 | + struct ieee80211_vif *vif) |
---|
| 277 | +{ |
---|
| 278 | + struct rsi_hw *adapter = hw->priv; |
---|
| 279 | + struct rsi_common *common = adapter->priv; |
---|
| 280 | + struct cfg80211_scan_info info; |
---|
| 281 | + |
---|
| 282 | + rsi_dbg(INFO_ZONE, "***** Hardware scan stop *****\n"); |
---|
| 283 | + mutex_lock(&common->mutex); |
---|
| 284 | + |
---|
| 285 | + if (common->bgscan_en) { |
---|
| 286 | + if (!rsi_send_bgscan_params(common, RSI_STOP_BGSCAN)) |
---|
| 287 | + common->bgscan_en = false; |
---|
| 288 | + info.aborted = false; |
---|
| 289 | + ieee80211_scan_completed(adapter->hw, &info); |
---|
| 290 | + rsi_dbg(INFO_ZONE, "Back ground scan cancelled\n"); |
---|
| 291 | + } |
---|
| 292 | + common->hwscan = NULL; |
---|
| 293 | + mutex_unlock(&common->mutex); |
---|
| 294 | +} |
---|
| 295 | + |
---|
233 | 296 | /** |
---|
234 | 297 | * rsi_mac80211_detach() - This function is used to de-initialize the |
---|
235 | 298 | * Mac80211 stack. |
---|
.. | .. |
---|
309 | 372 | { |
---|
310 | 373 | struct rsi_hw *adapter = hw->priv; |
---|
311 | 374 | struct rsi_common *common = adapter->priv; |
---|
| 375 | + struct ieee80211_hdr *wlh = (struct ieee80211_hdr *)skb->data; |
---|
| 376 | + |
---|
| 377 | + if (ieee80211_is_auth(wlh->frame_control)) |
---|
| 378 | + common->mac_ops_resumed = false; |
---|
312 | 379 | |
---|
313 | 380 | rsi_core_xmit(common, skb); |
---|
314 | 381 | } |
---|
.. | .. |
---|
615 | 682 | } |
---|
616 | 683 | |
---|
617 | 684 | /* Power save parameters */ |
---|
618 | | - if (changed & IEEE80211_CONF_CHANGE_PS) { |
---|
| 685 | + if ((changed & IEEE80211_CONF_CHANGE_PS) && |
---|
| 686 | + !common->mac_ops_resumed) { |
---|
619 | 687 | struct ieee80211_vif *vif, *sta_vif = NULL; |
---|
620 | 688 | unsigned long flags; |
---|
621 | 689 | int i, set_ps = 1; |
---|
.. | .. |
---|
662 | 730 | /** |
---|
663 | 731 | * rsi_get_connected_channel() - This function is used to get the current |
---|
664 | 732 | * connected channel number. |
---|
665 | | - * @adapter: Pointer to the adapter structure. |
---|
| 733 | + * @vif: Pointer to the ieee80211_vif structure. |
---|
666 | 734 | * |
---|
667 | 735 | * Return: Current connected AP's channel number is returned. |
---|
668 | 736 | */ |
---|
.. | .. |
---|
748 | 816 | adapter->ps_info.dtim_interval_duration = bss->dtim_period; |
---|
749 | 817 | adapter->ps_info.listen_interval = conf->listen_interval; |
---|
750 | 818 | |
---|
751 | | - /* If U-APSD is updated, send ps parameters to firmware */ |
---|
752 | | - if (bss->assoc) { |
---|
753 | | - if (common->uapsd_bitmap) { |
---|
754 | | - rsi_dbg(INFO_ZONE, "Configuring UAPSD\n"); |
---|
755 | | - rsi_conf_uapsd(adapter, vif); |
---|
| 819 | + /* If U-APSD is updated, send ps parameters to firmware */ |
---|
| 820 | + if (bss->assoc) { |
---|
| 821 | + if (common->uapsd_bitmap) { |
---|
| 822 | + rsi_dbg(INFO_ZONE, "Configuring UAPSD\n"); |
---|
| 823 | + rsi_conf_uapsd(adapter, vif); |
---|
| 824 | + } |
---|
| 825 | + } else { |
---|
| 826 | + common->uapsd_bitmap = 0; |
---|
756 | 827 | } |
---|
757 | | - } else { |
---|
758 | | - common->uapsd_bitmap = 0; |
---|
759 | | - } |
---|
760 | 828 | } |
---|
761 | 829 | |
---|
762 | 830 | if (changed & BSS_CHANGED_CQM) { |
---|
763 | 831 | common->cqm_info.last_cqm_event_rssi = 0; |
---|
764 | 832 | common->cqm_info.rssi_thold = bss_conf->cqm_rssi_thold; |
---|
765 | 833 | common->cqm_info.rssi_hyst = bss_conf->cqm_rssi_hyst; |
---|
766 | | - rsi_dbg(INFO_ZONE, "RSSI throld & hysteresis are: %d %d\n", |
---|
| 834 | + rsi_dbg(INFO_ZONE, "RSSI threshold & hysteresis are: %d %d\n", |
---|
767 | 835 | common->cqm_info.rssi_thold, |
---|
768 | 836 | common->cqm_info.rssi_hyst); |
---|
769 | 837 | } |
---|
.. | .. |
---|
786 | 854 | /** |
---|
787 | 855 | * rsi_mac80211_conf_filter() - This function configure the device's RX filter. |
---|
788 | 856 | * @hw: Pointer to the ieee80211_hw structure. |
---|
789 | | - * @changed: Changed flags set. |
---|
| 857 | + * @changed_flags: Changed flags set. |
---|
790 | 858 | * @total_flags: Total initial flags set. |
---|
791 | 859 | * @multicast: Multicast. |
---|
792 | 860 | * |
---|
.. | .. |
---|
867 | 935 | * @hw: Pointer to the ieee80211_hw structure. |
---|
868 | 936 | * @vif: Pointer to the ieee80211_vif structure. |
---|
869 | 937 | * @key: Pointer to the ieee80211_key_conf structure. |
---|
| 938 | + * @sta: Pointer to the ieee80211_sta structure. |
---|
870 | 939 | * |
---|
871 | 940 | * Return: status: 0 on success, negative error codes on failure. |
---|
872 | 941 | */ |
---|
.. | .. |
---|
924 | 993 | if (status) |
---|
925 | 994 | return status; |
---|
926 | 995 | |
---|
927 | | - if (vif->type == NL80211_IFTYPE_STATION && key->key && |
---|
| 996 | + if (vif->type == NL80211_IFTYPE_STATION && |
---|
928 | 997 | (key->cipher == WLAN_CIPHER_SUITE_WEP104 || |
---|
929 | 998 | key->cipher == WLAN_CIPHER_SUITE_WEP40)) { |
---|
930 | 999 | if (!rsi_send_block_unblock_frame(adapter->priv, false)) |
---|
.. | .. |
---|
1068 | 1137 | else if ((vif->type == NL80211_IFTYPE_AP) || |
---|
1069 | 1138 | (vif->type == NL80211_IFTYPE_P2P_GO)) |
---|
1070 | 1139 | rsta->seq_start[tid] = seq_no; |
---|
1071 | | - ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); |
---|
1072 | | - status = 0; |
---|
| 1140 | + status = IEEE80211_AMPDU_TX_START_IMMEDIATE; |
---|
1073 | 1141 | break; |
---|
1074 | 1142 | |
---|
1075 | 1143 | case IEEE80211_AMPDU_TX_STOP_CONT: |
---|
.. | .. |
---|
1178 | 1246 | * @common: Pointer to the driver private structure. |
---|
1179 | 1247 | * @bssid: pointer to the bssid. |
---|
1180 | 1248 | * @rssi: RSSI value. |
---|
| 1249 | + * @vif: Pointer to the ieee80211_vif structure. |
---|
1181 | 1250 | */ |
---|
1182 | 1251 | static void rsi_perform_cqm(struct rsi_common *common, |
---|
1183 | 1252 | u8 *bssid, |
---|
.. | .. |
---|
1279 | 1348 | } |
---|
1280 | 1349 | |
---|
1281 | 1350 | /** |
---|
1282 | | - * rsi_indicate_pkt_to_os() - This function sends recieved packet to mac80211. |
---|
| 1351 | + * rsi_indicate_pkt_to_os() - This function sends received packet to mac80211. |
---|
1283 | 1352 | * @common: Pointer to the driver private structure. |
---|
1284 | 1353 | * @skb: Pointer to the socket buffer structure. |
---|
1285 | 1354 | * |
---|
.. | .. |
---|
1717 | 1786 | return status; |
---|
1718 | 1787 | } |
---|
1719 | 1788 | |
---|
1720 | | -static int rsi_mac80211_cancel_roc(struct ieee80211_hw *hw) |
---|
| 1789 | +static int rsi_mac80211_cancel_roc(struct ieee80211_hw *hw, |
---|
| 1790 | + struct ieee80211_vif *vif) |
---|
1721 | 1791 | { |
---|
1722 | 1792 | struct rsi_hw *adapter = hw->priv; |
---|
1723 | 1793 | struct rsi_common *common = adapter->priv; |
---|
.. | .. |
---|
1801 | 1871 | return 0; |
---|
1802 | 1872 | } |
---|
1803 | 1873 | rsi_dbg(INFO_ZONE, "TRIGGERS %x\n", triggers); |
---|
| 1874 | + |
---|
| 1875 | + if (common->coex_mode > 1) |
---|
| 1876 | + rsi_disable_ps(adapter, adapter->vifs[0]); |
---|
| 1877 | + |
---|
1804 | 1878 | rsi_send_wowlan_request(common, triggers, 1); |
---|
1805 | 1879 | |
---|
1806 | 1880 | /** |
---|
.. | .. |
---|
1844 | 1918 | |
---|
1845 | 1919 | rsi_dbg(INFO_ZONE, "%s: mac80211 resume\n", __func__); |
---|
1846 | 1920 | |
---|
1847 | | - if (common->hibernate_resume) |
---|
1848 | | - return 0; |
---|
| 1921 | + if (common->hibernate_resume) { |
---|
| 1922 | + common->mac_ops_resumed = true; |
---|
| 1923 | + /* Device need a complete restart of all MAC operations. |
---|
| 1924 | + * returning 1 will serve this purpose. |
---|
| 1925 | + */ |
---|
| 1926 | + return 1; |
---|
| 1927 | + } |
---|
1849 | 1928 | |
---|
1850 | 1929 | mutex_lock(&common->mutex); |
---|
1851 | 1930 | rsi_send_wowlan_request(common, 0, 0); |
---|
.. | .. |
---|
1885 | 1964 | .suspend = rsi_mac80211_suspend, |
---|
1886 | 1965 | .resume = rsi_mac80211_resume, |
---|
1887 | 1966 | #endif |
---|
| 1967 | + .hw_scan = rsi_mac80211_hw_scan_start, |
---|
| 1968 | + .cancel_hw_scan = rsi_mac80211_cancel_hw_scan, |
---|
1888 | 1969 | }; |
---|
1889 | 1970 | |
---|
1890 | 1971 | /** |
---|
.. | .. |
---|
1972 | 2053 | common->max_stations = wiphy->max_ap_assoc_sta; |
---|
1973 | 2054 | rsi_dbg(ERR_ZONE, "Max Stations Allowed = %d\n", common->max_stations); |
---|
1974 | 2055 | hw->sta_data_size = sizeof(struct rsi_sta); |
---|
| 2056 | + |
---|
| 2057 | + wiphy->max_scan_ssids = RSI_MAX_SCAN_SSIDS; |
---|
| 2058 | + wiphy->max_scan_ie_len = RSI_MAX_SCAN_IE_LEN; |
---|
1975 | 2059 | wiphy->flags = WIPHY_FLAG_REPORTS_OBSS; |
---|
1976 | 2060 | wiphy->flags |= WIPHY_FLAG_AP_UAPSD; |
---|
1977 | 2061 | wiphy->features |= NL80211_FEATURE_INACTIVITY_TIMER; |
---|