Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 258483
b: refs/heads/master
c: 5829656
h: refs/heads/master
i:
  258481: a818c5d
  258479: 5041424
v: v3
  • Loading branch information
Christian Lamparter authored and John W. Linville committed Jul 18, 2011
1 parent 680ce70 commit bd556fd
Show file tree
Hide file tree
Showing 2 changed files with 109 additions and 84 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 943c33996f9b0851c4122dc96cae08d4ba8debf0
refs/heads/master: 582965672831180b2e1f5e15ea1f7dc6f5b93018
191 changes: 108 additions & 83 deletions trunk/drivers/net/wireless/ath/carl9170/tx.c
Original file line number Diff line number Diff line change
Expand Up @@ -661,11 +661,67 @@ void carl9170_tx_process_status(struct ar9170 *ar,
}
}

static void carl9170_tx_rate_tpc_chains(struct ar9170 *ar,
struct ieee80211_tx_info *info, struct ieee80211_tx_rate *txrate,
unsigned int *phyrate, unsigned int *tpc, unsigned int *chains)
{
struct ieee80211_rate *rate = NULL;
u8 *txpower;
unsigned int idx;

idx = txrate->idx;
*tpc = 0;
*phyrate = 0;

if (txrate->flags & IEEE80211_TX_RC_MCS) {
if (txrate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) {
/* +1 dBm for HT40 */
*tpc += 2;

if (info->band == IEEE80211_BAND_2GHZ)
txpower = ar->power_2G_ht40;
else
txpower = ar->power_5G_ht40;
} else {
if (info->band == IEEE80211_BAND_2GHZ)
txpower = ar->power_2G_ht20;
else
txpower = ar->power_5G_ht20;
}

*phyrate = txrate->idx;
*tpc += txpower[idx & 7];
} else {
if (info->band == IEEE80211_BAND_2GHZ) {
if (idx < 4)
txpower = ar->power_2G_cck;
else
txpower = ar->power_2G_ofdm;
} else {
txpower = ar->power_5G_leg;
idx += 4;
}

rate = &__carl9170_ratetable[idx];
*tpc += txpower[(rate->hw_value & 0x30) >> 4];
*phyrate = rate->hw_value & 0xf;
}

if (ar->eeprom.tx_mask == 1) {
*chains = AR9170_TX_PHY_TXCHAIN_1;
} else {
if (!(txrate->flags & IEEE80211_TX_RC_MCS) &&
rate && rate->bitrate >= 360)
*chains = AR9170_TX_PHY_TXCHAIN_1;
else
*chains = AR9170_TX_PHY_TXCHAIN_2;
}
}

static __le32 carl9170_tx_physet(struct ar9170 *ar,
struct ieee80211_tx_info *info, struct ieee80211_tx_rate *txrate)
{
struct ieee80211_rate *rate = NULL;
u32 power, chains;
unsigned int power = 0, chains = 0, phyrate = 0;
__le32 tmp;

tmp = cpu_to_le32(0);
Expand All @@ -682,35 +738,12 @@ static __le32 carl9170_tx_physet(struct ar9170 *ar,
tmp |= cpu_to_le32(AR9170_TX_PHY_SHORT_GI);

if (txrate->flags & IEEE80211_TX_RC_MCS) {
u32 r = txrate->idx;
u8 *txpower;
SET_VAL(AR9170_TX_PHY_MCS, phyrate, txrate->idx);

/* heavy clip control */
tmp |= cpu_to_le32((r & 0x7) <<
tmp |= cpu_to_le32((txrate->idx & 0x7) <<
AR9170_TX_PHY_TX_HEAVY_CLIP_S);

if (txrate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) {
if (info->band == IEEE80211_BAND_5GHZ)
txpower = ar->power_5G_ht40;
else
txpower = ar->power_2G_ht40;
} else {
if (info->band == IEEE80211_BAND_5GHZ)
txpower = ar->power_5G_ht20;
else
txpower = ar->power_2G_ht20;
}

power = txpower[r & 7];

/* +1 dBm for HT40 */
if (txrate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
power += 2;

r <<= AR9170_TX_PHY_MCS_S;
BUG_ON(r & ~AR9170_TX_PHY_MCS);

tmp |= cpu_to_le32(r & AR9170_TX_PHY_MCS);
tmp |= cpu_to_le32(AR9170_TX_PHY_MOD_HT);

/*
Expand All @@ -720,58 +753,28 @@ static __le32 carl9170_tx_physet(struct ar9170 *ar,
* tmp |= cpu_to_le32(AR9170_TX_PHY_GREENFIELD);
*/
} else {
u8 *txpower;
u32 mod;
u32 phyrate;
u8 idx = txrate->idx;

if (info->band != IEEE80211_BAND_2GHZ) {
idx += 4;
txpower = ar->power_5G_leg;
mod = AR9170_TX_PHY_MOD_OFDM;
if (info->band == IEEE80211_BAND_2GHZ) {
if (txrate->idx <= AR9170_TX_PHY_RATE_CCK_11M)
tmp |= cpu_to_le32(AR9170_TX_PHY_MOD_CCK);
else
tmp |= cpu_to_le32(AR9170_TX_PHY_MOD_OFDM);
} else {
if (idx < 4) {
txpower = ar->power_2G_cck;
mod = AR9170_TX_PHY_MOD_CCK;
} else {
mod = AR9170_TX_PHY_MOD_OFDM;
txpower = ar->power_2G_ofdm;
}
tmp |= cpu_to_le32(AR9170_TX_PHY_MOD_OFDM);
}

rate = &__carl9170_ratetable[idx];

phyrate = rate->hw_value & 0xF;
power = txpower[(rate->hw_value & 0x30) >> 4];
phyrate <<= AR9170_TX_PHY_MCS_S;

tmp |= cpu_to_le32(mod);
tmp |= cpu_to_le32(phyrate);

/*
* short preamble seems to be broken too.
*
* if (txrate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
* tmp |= cpu_to_le32(AR9170_TX_PHY_SHORT_PREAMBLE);
*/
}
power <<= AR9170_TX_PHY_TX_PWR_S;
power &= AR9170_TX_PHY_TX_PWR;
tmp |= cpu_to_le32(power);

/* set TX chains */
if (ar->eeprom.tx_mask == 1) {
chains = AR9170_TX_PHY_TXCHAIN_1;
} else {
chains = AR9170_TX_PHY_TXCHAIN_2;

/* >= 36M legacy OFDM - use only one chain */
if (rate && rate->bitrate >= 360 &&
!(txrate->flags & IEEE80211_TX_RC_MCS))
chains = AR9170_TX_PHY_TXCHAIN_1;
}
tmp |= cpu_to_le32(chains << AR9170_TX_PHY_TXCHAIN_S);
carl9170_tx_rate_tpc_chains(ar, info, txrate,
&phyrate, &power, &chains);

tmp |= cpu_to_le32(SET_CONSTVAL(AR9170_TX_PHY_MCS, phyrate));
tmp |= cpu_to_le32(SET_CONSTVAL(AR9170_TX_PHY_TX_PWR, power));
tmp |= cpu_to_le32(SET_CONSTVAL(AR9170_TX_PHY_TXCHAIN, chains));
return tmp;
}

Expand Down Expand Up @@ -1444,8 +1447,10 @@ int carl9170_update_beacon(struct ar9170 *ar, const bool submit)
struct sk_buff *skb = NULL;
struct carl9170_vif_info *cvif;
struct ieee80211_tx_info *txinfo;
struct ieee80211_tx_rate *rate;
__le32 *data, *old = NULL;
u32 word, off, addr, len;
unsigned int plcp, power, chains;
u32 word, ht1, off, addr, len;
int i = 0, err = 0;

rcu_read_lock();
Expand Down Expand Up @@ -1476,11 +1481,6 @@ int carl9170_update_beacon(struct ar9170 *ar, const bool submit)
}

txinfo = IEEE80211_SKB_CB(skb);
if (txinfo->control.rates[0].flags & IEEE80211_TX_RC_MCS) {
err = -EINVAL;
goto err_free;
}

spin_lock_bh(&ar->beacon_lock);
data = (__le32 *)skb->data;
if (cvif->beacon)
Expand Down Expand Up @@ -1510,18 +1510,43 @@ int carl9170_update_beacon(struct ar9170 *ar, const bool submit)
goto err_unlock;
}

i = txinfo->control.rates[0].idx;
if (txinfo->band != IEEE80211_BAND_2GHZ)
i += 4;
ht1 = AR9170_MAC_BCN_HT1_TX_ANT0;
rate = &txinfo->control.rates[0];
carl9170_tx_rate_tpc_chains(ar, txinfo, rate, &plcp, &power, &chains);
if (!(txinfo->control.rates[0].flags & IEEE80211_TX_RC_MCS)) {
if (plcp <= AR9170_TX_PHY_RATE_CCK_11M)
plcp |= ((skb->len + FCS_LEN) << (3 + 16)) + 0x0400;
else
plcp |= ((skb->len + FCS_LEN) << 16) + 0x0010;
} else {
ht1 |= AR9170_MAC_BCN_HT1_HT_EN;
if (rate->flags & IEEE80211_TX_RC_SHORT_GI)
plcp |= AR9170_MAC_BCN_HT2_SGI;

word = __carl9170_ratetable[i].hw_value & 0xf;
if (i < 4)
word |= ((skb->len + FCS_LEN) << (3 + 16)) + 0x0400;
else
word |= ((skb->len + FCS_LEN) << 16) + 0x0010;
if (rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) {
ht1 |= AR9170_MAC_BCN_HT1_BWC_40M_SHARED;
plcp |= AR9170_MAC_BCN_HT2_BW40;
}
if (rate->flags & IEEE80211_TX_RC_DUP_DATA) {
ht1 |= AR9170_MAC_BCN_HT1_BWC_40M_DUP;
plcp |= AR9170_MAC_BCN_HT2_BW40;
}

SET_VAL(AR9170_MAC_BCN_HT2_LEN, plcp, skb->len + FCS_LEN);
}

SET_VAL(AR9170_MAC_BCN_HT1_PWR_CTRL, ht1, 7);
SET_VAL(AR9170_MAC_BCN_HT1_TPC, ht1, power);
SET_VAL(AR9170_MAC_BCN_HT1_CHAIN_MASK, ht1, chains);
if (chains == AR9170_TX_PHY_TXCHAIN_2)
ht1 |= AR9170_MAC_BCN_HT1_TX_ANT1;

carl9170_async_regwrite_begin(ar);
carl9170_async_regwrite(AR9170_MAC_REG_BCN_PLCP, word);
carl9170_async_regwrite(AR9170_MAC_REG_BCN_HT1, ht1);
if (!(txinfo->control.rates[0].flags & IEEE80211_TX_RC_MCS))
carl9170_async_regwrite(AR9170_MAC_REG_BCN_PLCP, plcp);
else
carl9170_async_regwrite(AR9170_MAC_REG_BCN_HT2, plcp);

for (i = 0; i < DIV_ROUND_UP(skb->len, 4); i++) {
/*
Expand Down

0 comments on commit bd556fd

Please sign in to comment.