コード例 #1
0
ファイル: iwl-agn-tx.c プロジェクト: 33d/linux-2.6.21-hh20
int iwlagn_tx_agg_oper(struct iwl_priv *priv, struct ieee80211_vif *vif,
			struct ieee80211_sta *sta, u16 tid, u8 buf_size)
{
	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);
	ssn = priv->tid_data[sta_priv->sta_id][tid].agg.ssn;
	spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);

	iwl_trans_tx_agg_setup(trans(priv), ctx->ctxid, sta_priv->sta_id, tid,
			       buf_size, ssn);

	/*
	 * If the limit is 0, then it wasn't initialised yet,
	 * use the default. We can do that since we take the
	 * minimum below, and we don't want to go above our
	 * default due to hardware restrictions.
	 */
	if (sta_priv->max_agg_bufsize == 0)
		sta_priv->max_agg_bufsize =
			LINK_QUAL_AGG_FRAME_LIMIT_DEF;

	/*
	 * Even though in theory the peer could have different
	 * aggregation reorder buffer sizes for different sessions,
	 * our ucode doesn't allow for that and has a global limit
	 * for each station. Therefore, use the minimum of all the
	 * aggregation sessions and our default value.
	 */
	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) {
		/*
		 * switch to RTS/CTS if it is the prefer protection
		 * method for HT traffic
		 */

		sta_priv->lq_sta.lq.general_params.flags |=
			LINK_QUAL_FLAGS_SET_STA_TLC_RTS_MSK;
	}
	priv->agg_tids_count++;
	IWL_DEBUG_HT(priv, "priv->agg_tids_count = %u\n",
		     priv->agg_tids_count);

	sta_priv->lq_sta.lq.agg_params.agg_frame_cnt_limit =
		sta_priv->max_agg_bufsize;

	IWL_INFO(priv, "Tx aggregation enabled on ra = %pM tid = %d\n",
		 sta->addr, tid);

	return iwl_send_lq_cmd(priv, ctx,
			&sta_priv->lq_sta.lq, CMD_ASYNC, false);
}
コード例 #2
0
/**
 * Program the device to use fixed rate for frame transmit
 * This is for debugging/testing only
 * once the device start use fixed rate, we need to reload the module
 * to being back the normal operation.
 */
static void rs_program_fix_rate(struct iwl_priv *priv,
				struct iwl_lq_sta *lq_sta)
{
	struct iwl_station_priv *sta_priv =
		container_of(lq_sta, struct iwl_station_priv, lq_sta);
	struct iwl_rxon_context *ctx = sta_priv->ctx;

	lq_sta->active_legacy_rate = 0x0FFF;	/* 1 - 54 MBits, includes CCK */
	lq_sta->active_siso_rate   = 0x1FD0;	/* 6 - 60 MBits, no 9, no CCK */
	lq_sta->active_mimo2_rate  = 0x1FD0;	/* 6 - 60 MBits, no 9, no CCK */
	lq_sta->active_mimo3_rate  = 0x1FD0;	/* 6 - 60 MBits, no 9, no CCK */

#ifdef CONFIG_IWLWIFI_DEVICE_TESTMODE
	/* testmode has higher priority to overwirte the fixed rate */
	if (priv->tm_fixed_rate)
		lq_sta->dbg_fixed_rate = priv->tm_fixed_rate;
#endif

	IWL_DEBUG_RATE(priv, "sta_id %d rate 0x%X\n",
		lq_sta->lq.sta_id, lq_sta->dbg_fixed_rate);

	if (lq_sta->dbg_fixed_rate) {
		rs_fill_link_cmd(NULL, lq_sta, lq_sta->dbg_fixed_rate);
		iwl_send_lq_cmd(lq_sta->drv, ctx, &lq_sta->lq, CMD_ASYNC,
				false);
	}
}
コード例 #3
0
ファイル: iwl-agn-sta.c プロジェクト: padovan/bluetooth-next
/*
 * iwlagn_add_bssid_station - Add the special IBSS BSSID station
 *
 * Function sleeps.
 */
int iwlagn_add_bssid_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
			     const u8 *addr, u8 *sta_id_r)
{
	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;

	ret = iwl_add_station_common(priv, ctx, addr, 0, NULL, &sta_id);
	if (ret) {
		IWL_ERR(priv, "Unable to add station %pM\n", addr);
		return ret;
	}

	if (sta_id_r)
		*sta_id_r = sta_id;

	spin_lock_irqsave(&priv->shrd->sta_lock, flags);
	priv->stations[sta_id].used |= IWL_STA_LOCAL;
	spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);

	/* Set up default rate scaling table in device's station table */
	link_cmd = iwl_sta_alloc_lq(priv, ctx, sta_id);
	if (!link_cmd) {
		IWL_ERR(priv, "Unable to initialize rate scaling for station %pM.\n",
			addr);
		return -ENOMEM;
	}

	ret = iwl_send_lq_cmd(priv, ctx, link_cmd, CMD_SYNC, true);
	if (ret)
		IWL_ERR(priv, "Link quality command failed (%d)\n", ret);

	spin_lock_irqsave(&priv->shrd->sta_lock, flags);
	priv->stations[sta_id].lq = link_cmd;
	spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);

	return 0;
}
コード例 #4
0
ファイル: iwl-sta.c プロジェクト: ARMP/android_kernel_lge_x3
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;

	spin_lock_irqsave(&priv->sta_lock, flags);
	if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE)) {
		spin_unlock_irqrestore(&priv->sta_lock, flags);
		return;
	}

	memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(sta_cmd));
	sta_cmd.mode = 0;
	memcpy(&lq, priv->stations[sta_id].lq, sizeof(lq));

	active = priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE;
	priv->stations[sta_id].used &= ~IWL_STA_DRIVER_ACTIVE;
	spin_unlock_irqrestore(&priv->sta_lock, flags);

	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_irqsave(&priv->sta_lock, flags);
	priv->stations[sta_id].used |= IWL_STA_DRIVER_ACTIVE;
	spin_unlock_irqrestore(&priv->sta_lock, flags);

	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);
	iwl_send_lq_cmd(priv, ctx, &lq, CMD_SYNC, true);
}
コード例 #5
0
ファイル: iwl-sta.c プロジェクト: ARMP/android_kernel_lge_x3
/**
 * iwl_restore_stations() - Restore driver known stations to device
 *
 * All stations considered active by driver, but not present in ucode, is
 * restored.
 *
 * Function sleeps.
 */
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;
	bool send_lq;

	if (!iwl_is_ready(priv)) {
		IWL_DEBUG_INFO(priv, "Not ready yet, not restoring any stations.\n");
		return;
	}

	IWL_DEBUG_ASSOC(priv, "Restoring all known stations ... start.\n");
	spin_lock_irqsave(&priv->sta_lock, flags_spin);
	for (i = 0; i < priv->hw_params.max_stations; i++) {
		if (ctx->ctxid != priv->stations[i].ctxid)
			continue;
		if ((priv->stations[i].used & IWL_STA_DRIVER_ACTIVE) &&
			    !(priv->stations[i].used & IWL_STA_UCODE_ACTIVE)) {
			IWL_DEBUG_ASSOC(priv, "Restoring sta %pM\n",
					priv->stations[i].sta.sta.addr);
			priv->stations[i].sta.mode = 0;
			priv->stations[i].used |= IWL_STA_UCODE_INPROGRESS;
			found = true;
		}
	}

	for (i = 0; i < priv->hw_params.max_stations; i++) {
		if ((priv->stations[i].used & IWL_STA_UCODE_INPROGRESS)) {
			memcpy(&sta_cmd, &priv->stations[i].sta,
			       sizeof(struct iwl_addsta_cmd));
			send_lq = false;
			if (priv->stations[i].lq) {
				memcpy(&lq, priv->stations[i].lq,
				       sizeof(struct iwl_link_quality_cmd));
				send_lq = true;
			}
			spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
			ret = iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC);
			if (ret) {
				spin_lock_irqsave(&priv->sta_lock, flags_spin);
				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->sta_lock, flags_spin);
			}
			/*
			 * Rate scaling has already been initialized, send
			 * current LQ command
			 */
			if (send_lq)
				iwl_send_lq_cmd(priv, ctx, &lq, CMD_SYNC, true);
			spin_lock_irqsave(&priv->sta_lock, flags_spin);
			priv->stations[i].used &= ~IWL_STA_UCODE_INPROGRESS;
		}
	}

	spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
	if (!found)
		IWL_DEBUG_INFO(priv, "Restoring all known stations .... no stations to be restored.\n");
	else
		IWL_DEBUG_INFO(priv, "Restoring all known stations .... complete.\n");
}