|
@@ -2956,6 +2956,72 @@ static int iwl_mac_cancel_remain_on_channel(struct ieee80211_hw *hw)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+static int iwl_mac_tx_sync(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
|
|
+ const u8 *bssid, enum ieee80211_tx_sync_type type)
|
|
|
+{
|
|
|
+ struct iwl_priv *priv = hw->priv;
|
|
|
+ struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv;
|
|
|
+ struct iwl_rxon_context *ctx = vif_priv->ctx;
|
|
|
+ int ret;
|
|
|
+ u8 sta_id;
|
|
|
+
|
|
|
+ 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);
|
|
|
+ return ret;
|
|
|
+}
|
|
|
+
|
|
|
+static void iwl_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 = hw->priv;
|
|
|
+ struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv;
|
|
|
+ struct iwl_rxon_context *ctx = vif_priv->ctx;
|
|
|
+
|
|
|
+ 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);
|
|
|
+}
|
|
|
+
|
|
|
/*****************************************************************************
|
|
|
*
|
|
|
* driver setup and teardown
|
|
@@ -3164,6 +3230,8 @@ struct ieee80211_ops iwlagn_hw_ops = {
|
|
|
.rssi_callback = iwl_mac_rssi_callback,
|
|
|
CFG80211_TESTMODE_CMD(iwl_testmode_cmd)
|
|
|
CFG80211_TESTMODE_DUMP(iwl_testmode_dump)
|
|
|
+ .tx_sync = iwl_mac_tx_sync,
|
|
|
+ .finish_tx_sync = iwl_mac_finish_tx_sync,
|
|
|
};
|
|
|
|
|
|
static u32 iwl_hw_detect(struct iwl_priv *priv)
|