Skip to content

Commit

Permalink
rtlwifi: Convert rc routines for addition of rtl8192se and rtl8192de
Browse files Browse the repository at this point in the history
Convert rc routines for addition of RTL8192SE and RTL8192DE code

Signed-off-by: Chaoming_Li <chaoming_li@realsil.com.cn>
Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
  • Loading branch information
Chaoming_Li authored and John W. Linville committed Apr 26, 2011
1 parent cc7dc0c commit c6a9de0
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 126 deletions.
212 changes: 87 additions & 125 deletions drivers/net/wireless/rtlwifi/rc.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,17 +38,14 @@
*CCK11M or OFDM_54M based on wireless mode.
*/
static u8 _rtl_rc_get_highest_rix(struct rtl_priv *rtlpriv,
struct ieee80211_sta *sta,
struct sk_buff *skb, bool not_data)
{
struct rtl_mac *rtlmac = rtl_mac(rtlpriv);

/*
*mgt use 1M, although we have check it
*before this function use rate_control_send_low,
*we still check it here
*/
if (not_data)
return rtlpriv->cfg->maps[RTL_RC_CCK_RATE1M];
struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
struct rtl_phy *rtlphy = &(rtlpriv->phy);
struct rtl_sta_info *sta_entry = NULL;
u8 wireless_mode = 0;

/*
*this rate is no use for true rate, firmware
Expand All @@ -57,35 +54,78 @@ static u8 _rtl_rc_get_highest_rix(struct rtl_priv *rtlpriv,
*2.in rtl_get_tcb_desc when we check rate is
* 1M we will not use FW rate but user rate.
*/
if (rtl_is_special_data(rtlpriv->mac80211.hw, skb, true)) {
return rtlpriv->cfg->maps[RTL_RC_CCK_RATE1M];
if (rtlmac->opmode == NL80211_IFTYPE_AP ||
rtlmac->opmode == NL80211_IFTYPE_ADHOC) {
if (sta) {
sta_entry = (struct rtl_sta_info *) sta->drv_priv;
wireless_mode = sta_entry->wireless_mode;
} else {
return 0;
}
} else {
wireless_mode = rtlmac->mode;
}

if (rtl_is_special_data(rtlpriv->mac80211.hw, skb, true) ||
not_data) {
return 0;
} else {
if (rtlmac->mode == WIRELESS_MODE_B)
return rtlpriv->cfg->maps[RTL_RC_CCK_RATE11M];
else
return rtlpriv->cfg->maps[RTL_RC_OFDM_RATE54M];
if (rtlhal->current_bandtype == BAND_ON_2_4G) {
if (wireless_mode == WIRELESS_MODE_B) {
return B_MODE_MAX_RIX;
} else if (wireless_mode == WIRELESS_MODE_G) {
return G_MODE_MAX_RIX;
} else {
if (get_rf_type(rtlphy) != RF_2T2R)
return N_MODE_MCS7_RIX;
else
return N_MODE_MCS15_RIX;
}
} else {
if (wireless_mode == WIRELESS_MODE_A) {
return A_MODE_MAX_RIX;
} else {
if (get_rf_type(rtlphy) != RF_2T2R)
return N_MODE_MCS7_RIX;
else
return N_MODE_MCS15_RIX;
}
}
}
}

static void _rtl_rc_rate_set_series(struct rtl_priv *rtlpriv,
struct ieee80211_sta *sta,
struct ieee80211_tx_rate *rate,
struct ieee80211_tx_rate_control *txrc,
u8 tries, u8 rix, int rtsctsenable,
u8 tries, char rix, int rtsctsenable,
bool not_data)
{
struct rtl_mac *mac = rtl_mac(rtlpriv);
u8 sgi_20 = 0, sgi_40 = 0;

if (sta) {
sgi_20 = sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20;
sgi_40 = sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40;
}
rate->count = tries;
rate->idx = (rix > 0x2) ? rix : 0x2;
rate->idx = rix >= 0x00 ? rix : 0x00;

if (!not_data) {
if (txrc->short_preamble)
rate->flags |= IEEE80211_TX_RC_USE_SHORT_PREAMBLE;
if (mac->bw_40)
rate->flags |= IEEE80211_TX_RC_40_MHZ_WIDTH;
if (mac->sgi_20 || mac->sgi_40)
if (mac->opmode == NL80211_IFTYPE_AP ||
mac->opmode == NL80211_IFTYPE_ADHOC) {
if (sta && (sta->ht_cap.cap &
IEEE80211_HT_CAP_SUP_WIDTH_20_40))
rate->flags |= IEEE80211_TX_RC_40_MHZ_WIDTH;
} else {
if (mac->bw_40)
rate->flags |= IEEE80211_TX_RC_40_MHZ_WIDTH;
}
if (sgi_20 || sgi_40)
rate->flags |= IEEE80211_TX_RC_SHORT_GI;
if (mac->ht_enable)
if (sta && sta->ht_cap.ht_supported)
rate->flags |= IEEE80211_TX_RC_MCS;
}
}
Expand All @@ -97,39 +137,39 @@ static void rtl_get_rate(void *ppriv, struct ieee80211_sta *sta,
struct sk_buff *skb = txrc->skb;
struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
struct ieee80211_tx_rate *rates = tx_info->control.rates;
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
__le16 fc = hdr->frame_control;
__le16 fc = rtl_get_fc(skb);
u8 try_per_rate, i, rix;
bool not_data = !ieee80211_is_data(fc);

if (rate_control_send_low(sta, priv_sta, txrc))
return;

rix = _rtl_rc_get_highest_rix(rtlpriv, skb, not_data);

rix = _rtl_rc_get_highest_rix(rtlpriv, sta, skb, not_data);
try_per_rate = 1;
_rtl_rc_rate_set_series(rtlpriv, &rates[0], txrc,
_rtl_rc_rate_set_series(rtlpriv, sta, &rates[0], txrc,
try_per_rate, rix, 1, not_data);

if (!not_data) {
for (i = 1; i < 4; i++)
_rtl_rc_rate_set_series(rtlpriv, &rates[i],
_rtl_rc_rate_set_series(rtlpriv, sta, &rates[i],
txrc, i, (rix - i), 1,
not_data);
}
}

static bool _rtl_tx_aggr_check(struct rtl_priv *rtlpriv, u16 tid)
static bool _rtl_tx_aggr_check(struct rtl_priv *rtlpriv,
struct rtl_sta_info *sta_entry, u16 tid)
{
struct rtl_mac *mac = rtl_mac(rtlpriv);

if (mac->act_scanning)
return false;

if (mac->cnt_after_linked < 3)
if (mac->opmode == NL80211_IFTYPE_STATION &&
mac->cnt_after_linked < 3)
return false;

if (mac->tids[tid].agg.agg_state == RTL_AGG_OFF)
if (sta_entry->tids[tid].agg.agg_state == RTL_AGG_STOP)
return true;

return false;
Expand All @@ -143,11 +183,9 @@ static void rtl_tx_status(void *ppriv,
{
struct rtl_priv *rtlpriv = ppriv;
struct rtl_mac *mac = rtl_mac(rtlpriv);
struct ieee80211_hdr *hdr;
__le16 fc;

hdr = (struct ieee80211_hdr *)skb->data;
fc = hdr->frame_control;
struct ieee80211_hdr *hdr = rtl_get_hdr(skb);
__le16 fc = rtl_get_fc(skb);
struct rtl_sta_info *sta_entry;

if (!priv_sta || !ieee80211_is_data(fc))
return;
Expand All @@ -159,17 +197,21 @@ static void rtl_tx_status(void *ppriv,
|| is_broadcast_ether_addr(ieee80211_get_DA(hdr)))
return;

/* Check if aggregation has to be enabled for this tid */
if (conf_is_ht(&mac->hw->conf) &&
!(skb->protocol == cpu_to_be16(ETH_P_PAE))) {
if (ieee80211_is_data_qos(fc)) {
u8 *qc, tid;

qc = ieee80211_get_qos_ctl(hdr);
tid = qc[0] & 0xf;

if (_rtl_tx_aggr_check(rtlpriv, tid))
ieee80211_start_tx_ba_session(sta, tid, 5000);
if (sta) {
/* Check if aggregation has to be enabled for this tid */
sta_entry = (struct rtl_sta_info *) sta->drv_priv;
if ((sta->ht_cap.ht_supported == true) &&
!(skb->protocol == cpu_to_be16(ETH_P_PAE))) {
if (ieee80211_is_data_qos(fc)) {
u8 tid = rtl_get_tid(skb);
if (_rtl_tx_aggr_check(rtlpriv, sta_entry,
tid)) {
sta_entry->tids[tid].agg.agg_state =
RTL_AGG_PROGRESS;
ieee80211_start_tx_ba_session(sta,
tid, 5000);
}
}
}
}
}
Expand All @@ -178,43 +220,6 @@ static void rtl_rate_init(void *ppriv,
struct ieee80211_supported_band *sband,
struct ieee80211_sta *sta, void *priv_sta)
{
struct rtl_priv *rtlpriv = ppriv;
struct rtl_mac *mac = rtl_mac(rtlpriv);
u8 is_ht = conf_is_ht(&mac->hw->conf);

if ((mac->opmode == NL80211_IFTYPE_STATION) ||
(mac->opmode == NL80211_IFTYPE_MESH_POINT) ||
(mac->opmode == NL80211_IFTYPE_ADHOC)) {

switch (sband->band) {
case IEEE80211_BAND_2GHZ:
rtlpriv->rate_priv->cur_ratetab_idx =
RATR_INX_WIRELESS_G;
if (is_ht)
rtlpriv->rate_priv->cur_ratetab_idx =
RATR_INX_WIRELESS_NGB;
break;
case IEEE80211_BAND_5GHZ:
rtlpriv->rate_priv->cur_ratetab_idx =
RATR_INX_WIRELESS_A;
if (is_ht)
rtlpriv->rate_priv->cur_ratetab_idx =
RATR_INX_WIRELESS_NGB;
break;
default:
RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
("Invalid band\n"));
rtlpriv->rate_priv->cur_ratetab_idx =
RATR_INX_WIRELESS_NGB;
break;
}

RT_TRACE(rtlpriv, COMP_RATE, DBG_DMESG,
("Choosing rate table index: %d\n",
rtlpriv->rate_priv->cur_ratetab_idx));

}

}

static void rtl_rate_update(void *ppriv,
Expand All @@ -223,49 +228,6 @@ static void rtl_rate_update(void *ppriv,
u32 changed,
enum nl80211_channel_type oper_chan_type)
{
struct rtl_priv *rtlpriv = ppriv;
struct rtl_mac *mac = rtl_mac(rtlpriv);
struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
bool oper_cw40 = false, oper_sgi40;
bool local_cw40 = mac->bw_40;
bool local_sgi40 = mac->sgi_40;
u8 is_ht = conf_is_ht(&mac->hw->conf);

if (changed & IEEE80211_RC_HT_CHANGED) {
if (mac->opmode != NL80211_IFTYPE_STATION)
return;

if (rtlhal->hw->conf.channel_type == NL80211_CHAN_HT40MINUS ||
rtlhal->hw->conf.channel_type == NL80211_CHAN_HT40PLUS)
oper_cw40 = true;

oper_sgi40 = mac->sgi_40;

if ((local_cw40 != oper_cw40) || (local_sgi40 != oper_sgi40)) {
switch (sband->band) {
case IEEE80211_BAND_2GHZ:
rtlpriv->rate_priv->cur_ratetab_idx =
RATR_INX_WIRELESS_G;
if (is_ht)
rtlpriv->rate_priv->cur_ratetab_idx =
RATR_INX_WIRELESS_NGB;
break;
case IEEE80211_BAND_5GHZ:
rtlpriv->rate_priv->cur_ratetab_idx =
RATR_INX_WIRELESS_A;
if (is_ht)
rtlpriv->rate_priv->cur_ratetab_idx =
RATR_INX_WIRELESS_NGB;
break;
default:
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
("Invalid band\n"));
rtlpriv->rate_priv->cur_ratetab_idx =
RATR_INX_WIRELESS_NGB;
break;
}
}
}
}

static void *rtl_rate_alloc(struct ieee80211_hw *hw,
Expand Down
9 changes: 8 additions & 1 deletion drivers/net/wireless/rtlwifi/rc.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,15 @@
#ifndef __RTL_RC_H__
#define __RTL_RC_H__

#define B_MODE_MAX_RIX 3
#define G_MODE_MAX_RIX 11
#define A_MODE_MAX_RIX 7

/* in mac80211 mcs0-mcs15 is idx0-idx15*/
#define N_MODE_MCS7_RIX 7
#define N_MODE_MCS15_RIX 15

struct rtl_rate_priv {
u8 cur_ratetab_idx;
u8 ht_cap;
};

Expand Down

0 comments on commit c6a9de0

Please sign in to comment.