Changeset View
Changeset View
Standalone View
Standalone View
sys/dev/rtwn/if_rtwn_ridx.h
Show All 20 Lines | |||||
*/ | */ | ||||
#ifndef IF_RTWN_RIDX_H | #ifndef IF_RTWN_RIDX_H | ||||
#define IF_RTWN_RIDX_H | #define IF_RTWN_RIDX_H | ||||
/* HW rate indices. */ | /* HW rate indices. */ | ||||
#define RTWN_RIDX_CCK1 0 | #define RTWN_RIDX_CCK1 0 | ||||
#define RTWN_RIDX_CCK2 1 | #define RTWN_RIDX_CCK2 1 | ||||
#define RTWN_RIDX_CCK55 2 | #define RTWN_RIDX_CCK5 2 | ||||
#define RTWN_RIDX_CCK11 3 | #define RTWN_RIDX_CCK11 3 | ||||
#define RTWN_RIDX_OFDM6 4 | #define RTWN_RIDX_OFDM6 4 | ||||
#define RTWN_RIDX_OFDM9 5 | #define RTWN_RIDX_OFDM9 5 | ||||
#define RTWN_RIDX_OFDM12 6 | #define RTWN_RIDX_OFDM12 6 | ||||
#define RTWN_RIDX_OFDM18 7 | #define RTWN_RIDX_OFDM18 7 | ||||
#define RTWN_RIDX_OFDM24 8 | #define RTWN_RIDX_OFDM24 8 | ||||
#define RTWN_RIDX_OFDM36 9 | #define RTWN_RIDX_OFDM36 9 | ||||
#define RTWN_RIDX_OFDM48 10 | #define RTWN_RIDX_OFDM48 10 | ||||
#define RTWN_RIDX_OFDM54 11 | #define RTWN_RIDX_OFDM54 11 | ||||
#define RTWN_RIDX_HT_MCS_SHIFT 12 | #define RTWN_RIDX_HT_MCS_SHIFT 12 | ||||
#define RTWN_RIDX_HT_MCS(i) (RTWN_RIDX_HT_MCS_SHIFT + (i)) | #define RTWN_RIDX_HT_MCS(i) (RTWN_RIDX_HT_MCS_SHIFT + (i)) | ||||
#define RTWN_RIDX_COUNT 28 | #define RTWN_RIDX_VHT_MCS_SHIFT 44 | ||||
#define RTWN_RIDX_VHT_MCS(i) (RTWN_RIDX_VHT_MCS_SHIFT + (i)) | |||||
#define RTWN_RIDX_COUNT 28 /* NB: obsolete (will be removed) */ | |||||
#define RTWN_RIDX_UNKNOWN (uint8_t)-1 | #define RTWN_RIDX_UNKNOWN (uint8_t)-1 | ||||
#define RTWN_RATE_IS_CCK(rate) ((rate) <= RTWN_RIDX_CCK11) | #define RTWN_RATE_IS_CCK(rate) ((rate) <= RTWN_RIDX_CCK11) | ||||
#define RTWN_RATE_IS_OFDM(rate) \ | #define RTWN_RATE_IS_OFDM(rate) \ | ||||
((rate) >= RTWN_RIDX_OFDM6 && (rate) != RTWN_RIDX_UNKNOWN) | ((rate) >= RTWN_RIDX_OFDM6 && (rate) != RTWN_RIDX_UNKNOWN) | ||||
static const uint8_t ridx2rate[] = | static const uint8_t ridx2rate[] = | ||||
{ 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108 }; | { 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108 }; | ||||
static __inline uint8_t | static __inline uint16_t | ||||
rate2ridx(uint8_t rate) | ridx2rate_idx(device_t dev, uint8_t ridx) | ||||
{ | { | ||||
if (rate & IEEE80211_RATE_MCS) { | #define RTWN_MAX_CHAINS 2 | ||||
return ((rate & 0xf) + RTWN_RIDX_HT_MCS_SHIFT); | #define RTWN_MIN_RIDX_HT RTWN_RIDX_HT_MCS(0) | ||||
#define RTWN_MAX_RIDX_HT \ | |||||
RTWN_RIDX_HT_MCS(IEEE80211_HT_MCS_CHAIN * RTWN_MAX_CHAINS - 1) | |||||
#define RTWN_MIN_RIDX_VHT RTWN_RIDX_VHT_MCS(0) | |||||
#define RTWN_MAX_RIDX_VHT \ | |||||
RTWN_RIDX_VHT_MCS(IEEE80211_VHT_MCS_CHAIN * RTWN_MAX_CHAINS - 1) | |||||
#define RTWN_CHECK_RATE(rate) \ | |||||
case RTWN_RIDX_##rate: \ | |||||
return (IEEE80211_RATE_INDEX_##rate); | |||||
if (RTWN_MIN_RIDX_VHT <= ridx && ridx <= RTWN_MAX_RIDX_VHT) { | |||||
int mcs, chains; | |||||
ridx -= RTWN_RIDX_VHT_MCS_SHIFT; | |||||
mcs = ridx / RTWN_RIDX_VHT_MCS_SHIFT; | |||||
chains = ridx % RTWN_RIDX_VHT_MCS_SHIFT; | |||||
return (IEEE80211_RATE_INDEX_VHT(mcs, chains)); | |||||
} | } | ||||
switch (rate) { | |||||
/* 11g */ | if (RTWN_MIN_RIDX_HT <= ridx && ridx <= RTWN_MAX_RIDX_HT) { | ||||
ridx -= RTWN_RIDX_HT_MCS_SHIFT; | |||||
return (IEEE80211_RATE_INDEX_HT(ridx)); | |||||
} | |||||
switch (ridx) { | |||||
RTWN_CHECK_RATE(CCK1); | |||||
RTWN_CHECK_RATE(CCK2); | |||||
RTWN_CHECK_RATE(CCK5); | |||||
RTWN_CHECK_RATE(CCK11); | |||||
RTWN_CHECK_RATE(OFDM6); | |||||
RTWN_CHECK_RATE(OFDM9); | |||||
RTWN_CHECK_RATE(OFDM12); | |||||
RTWN_CHECK_RATE(OFDM18); | |||||
RTWN_CHECK_RATE(OFDM24); | |||||
RTWN_CHECK_RATE(OFDM36); | |||||
RTWN_CHECK_RATE(OFDM48); | |||||
RTWN_CHECK_RATE(OFDM54); | |||||
default: | |||||
break; | |||||
} | |||||
device_printf(dev, "unknown rate index %u\n", ridx); | |||||
return (IEEE80211_RATE_NONEXISTENT); | |||||
#undef RTWN_CHECK_RATE | |||||
#undef RTWN_MAX_RIDX_VHT | |||||
#undef RTWN_MIN_RIDX_VHT | |||||
#undef RTWN_MAX_RIDX_HT | |||||
#undef RTWN_MIN_RIDX_HT | |||||
#undef RTWN_MAX_CHAINS | |||||
} | |||||
static __inline uint8_t | |||||
rate2ridx(const struct ieee80211_rate_t *rate) | |||||
{ | |||||
switch (rate->type) { | |||||
case IEEE80211_T_VHT: | |||||
return RTWN_RIDX_VHT_MCS(rate->value); | |||||
case IEEE80211_T_HT: | |||||
return RTWN_RIDX_HT_MCS(rate->value); | |||||
case IEEE80211_T_OFDM: | |||||
switch (rate->value) { | |||||
case 12: return 4; | case 12: return 4; | ||||
case 18: return 5; | case 18: return 5; | ||||
case 24: return 6; | case 24: return 6; | ||||
case 36: return 7; | case 36: return 7; | ||||
case 48: return 8; | case 48: return 8; | ||||
case 72: return 9; | case 72: return 9; | ||||
case 96: return 10; | case 96: return 10; | ||||
case 108: return 11; | case 108: return 11; | ||||
/* 11b */ | default: return RTWN_RIDX_UNKNOWN; | ||||
} | |||||
case IEEE80211_T_CCK: | |||||
switch (rate->value) { | |||||
case 2: return 0; | case 2: return 0; | ||||
case 4: return 1; | case 4: return 1; | ||||
case 11: return 2; | case 11: return 2; | ||||
case 22: return 3; | case 22: return 3; | ||||
default: return RTWN_RIDX_UNKNOWN; | default: return RTWN_RIDX_UNKNOWN; | ||||
} | } | ||||
default: | |||||
return (RTWN_RIDX_UNKNOWN); | |||||
} | } | ||||
} | |||||
/* XXX move to net80211 */ | static __inline uint8_t | ||||
static __inline__ uint8_t | rate_idx2ridx(uint16_t rate_idx) | ||||
rtwn_ctl_mcsrate(const struct ieee80211_rate_table *rt, uint8_t ridx) | |||||
{ | { | ||||
uint8_t cix, rate; | #define RTWN_MAX_CHAINS 2 | ||||
#define MIN_HT_RATE_IDX IEEE80211_RATE_INDEX_HT(0) | |||||
#define MAX_HT_RATE_IDX \ | |||||
IEEE80211_RATE_INDEX_HT(IEEE80211_HT_MCS_CHAIN * RTWN_MAX_CHAINS - 1) | |||||
#define MIN_VHT_RATE_IDX IEEE80211_RATE_INDEX_VHT(0, 1) | |||||
#define MAX_VHT_RATE_IDX \ | |||||
IEEE80211_RATE_INDEX_VHT(IEEE80211_VHT_MCS_CHAIN - 1, RTWN_MAX_CHAINS) | |||||
/* Check if we are using MCS rate. */ | if (MIN_VHT_RATE_IDX <= rate_idx && rate_idx <= MAX_VHT_RATE_IDX) | ||||
KASSERT(ridx >= RTWN_RIDX_HT_MCS(0) && ridx != RTWN_RIDX_UNKNOWN, | return (rate_idx - MIN_VHT_RATE_IDX + RTWN_RIDX_VHT_MCS_SHIFT); | ||||
("bad mcs rate index %d", ridx)); | |||||
rate = (ridx - RTWN_RIDX_HT_MCS(0)) | IEEE80211_RATE_MCS; | if (MIN_HT_RATE_IDX <= rate_idx && rate_idx <= MAX_HT_RATE_IDX) | ||||
cix = rt->info[rt->rateCodeToIndex[rate]].ctlRateIndex; | return (rate_idx - MIN_HT_RATE_IDX + RTWN_RIDX_HT_MCS_SHIFT); | ||||
KASSERT(cix != (uint8_t)-1, ("rate %d (%d) has no info", rate, ridx)); | |||||
return rt->info[cix].dot11Rate; | switch (rate_idx) { | ||||
case IEEE80211_RATE_INDEX_OFDM6: return RTWN_RIDX_OFDM6; | |||||
case IEEE80211_RATE_INDEX_OFDM9: return RTWN_RIDX_OFDM9; | |||||
case IEEE80211_RATE_INDEX_OFDM12: return RTWN_RIDX_OFDM12; | |||||
case IEEE80211_RATE_INDEX_OFDM18: return RTWN_RIDX_OFDM18; | |||||
case IEEE80211_RATE_INDEX_OFDM24: return RTWN_RIDX_OFDM24; | |||||
case IEEE80211_RATE_INDEX_OFDM36: return RTWN_RIDX_OFDM36; | |||||
case IEEE80211_RATE_INDEX_OFDM48: return RTWN_RIDX_OFDM48; | |||||
case IEEE80211_RATE_INDEX_OFDM54: return RTWN_RIDX_OFDM54; | |||||
case IEEE80211_RATE_INDEX_CCK1: return RTWN_RIDX_CCK1; | |||||
case IEEE80211_RATE_INDEX_CCK2: return RTWN_RIDX_CCK2; | |||||
case IEEE80211_RATE_INDEX_CCK5: return RTWN_RIDX_CCK5; | |||||
case IEEE80211_RATE_INDEX_CCK11: return RTWN_RIDX_CCK11; | |||||
default: break; | |||||
} | |||||
return (RTWN_RIDX_UNKNOWN); | |||||
#undef MAX_VHT_RATE_IDX | |||||
#undef MIN_VHT_RATE_IDX | |||||
#undef MAX_HT_RATE_IDX | |||||
#undef MIN_HT_RATE_IDX | |||||
#undef RTWN_MAX_CHAINS | |||||
} | } | ||||
#endif /* IF_RTWN_RIDX_H */ | #endif /* IF_RTWN_RIDX_H */ |