1 /* $OpenBSD: if_urtwn.c,v 1.16 2011/02/10 17:26:40 jakemsr Exp $ */ 2 3 /*- 4 * Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr> 5 * Copyright (c) 2014 Kevin Lo <kevlo@FreeBSD.org> 6 * Copyright (c) 2015-2016 Andriy Voskoboinyk <avos@FreeBSD.org> 7 * 8 * Permission to use, copy, modify, and distribute this software for any 9 * purpose with or without fee is hereby granted, provided that the above 10 * copyright notice and this permission notice appear in all copies. 11 * 12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 13 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 14 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 15 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 16 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 17 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 18 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 19 */ 20 21 #ifndef IF_RTWN_RIDX_H 22 #define IF_RTWN_RIDX_H 23 24 /* HW rate indices. */ 25 26 /* 27 * Note - these are also used as offsets into the TX power table 28 * array. 29 */ 30 #define RTWN_RIDX_CCK1 0 31 #define RTWN_RIDX_CCK2 1 32 #define RTWN_RIDX_CCK55 2 33 #define RTWN_RIDX_CCK11 3 34 #define RTWN_RIDX_OFDM6 4 35 #define RTWN_RIDX_OFDM9 5 36 #define RTWN_RIDX_OFDM12 6 37 #define RTWN_RIDX_OFDM18 7 38 #define RTWN_RIDX_OFDM24 8 39 #define RTWN_RIDX_OFDM36 9 40 #define RTWN_RIDX_OFDM48 10 41 #define RTWN_RIDX_OFDM54 11 42 43 #define RTWN_RIDX_HT_MCS_SHIFT 12 44 #define RTWN_RIDX_HT_MCS(i) (RTWN_RIDX_HT_MCS_SHIFT + (i)) 45 #define RTWN_RIDX_TO_MCS(ridx) ((ridx) - RTWN_RIDX_HT_MCS_SHIFT) 46 47 /* HT supports up to MCS31, so goes from 12 -> 43 */ 48 49 #define RTWN_RIDX_LEGACY_HT_COUNT 44 50 51 /* 52 * VHT supports MCS0..9 for up to 4 spatial streams, so 53 * goes from 44 -> 83. 54 */ 55 #define RTWN_RIDX_VHT_MCS_SHIFT 44 56 #define RTWN_RIDX_VHT_MCS(s, i) (RTWN_RIDX_VHT_MCS_SHIFT + ((10*s) + i)) 57 58 /* 59 * The total amount of rate indexes, CCK, OFDM, HT MCS0..31, 60 * VHT MCS0..9 for 1-4 streams. 61 */ 62 #define RTWN_RIDX_COUNT 84 63 64 #define RTWN_RIDX_UNKNOWN (uint8_t)-1 65 66 #define RTWN_RATE_IS_CCK(rate) ((rate) <= RTWN_RIDX_CCK11) 67 #define RTWN_RATE_IS_OFDM(rate) \ 68 ((rate) >= RTWN_RIDX_OFDM6 && (rate) <= RTWN_RIDX_OFDM54) 69 #define RTWN_RATE_IS_HT(rate) \ 70 ((rate) >= RTWN_RIDX_HT_MCS_SHIFT && (rate) < RTWN_RIDX_VHT_MCS_SHIFT) 71 #define RTWN_RATE_IS_VHT(rate) \ 72 ((rate) >= RTWN_RIDX_VHT_MCS_SHIFT && (rate) <= RTWN_RIDX_COUNT) 73 74 static const uint8_t ridx2rate[] = 75 { 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108 }; 76 77 static __inline uint8_t 78 rate2ridx(uint8_t rate) 79 { 80 if (rate & IEEE80211_RATE_MCS) { 81 return ((rate & 0xf) + RTWN_RIDX_HT_MCS_SHIFT); 82 } 83 switch (rate) { 84 /* 11g */ 85 case 12: return 4; 86 case 18: return 5; 87 case 24: return 6; 88 case 36: return 7; 89 case 48: return 8; 90 case 72: return 9; 91 case 96: return 10; 92 case 108: return 11; 93 /* 11b */ 94 case 2: return 0; 95 case 4: return 1; 96 case 11: return 2; 97 case 22: return 3; 98 default: return RTWN_RIDX_UNKNOWN; 99 } 100 } 101 102 /* XXX move to net80211 */ 103 static __inline__ uint8_t 104 rtwn_ctl_mcsrate(const struct ieee80211_rate_table *rt, uint8_t ridx) 105 { 106 uint8_t cix, rate; 107 108 /* Check if we are using MCS rate. */ 109 KASSERT(RTWN_RATE_IS_HT(ridx), ("bad mcs rate index %d", ridx)); 110 111 rate = (ridx - RTWN_RIDX_HT_MCS(0)) | IEEE80211_RATE_MCS; 112 cix = rt->info[rt->rateCodeToIndex[rate]].ctlRateIndex; 113 KASSERT(cix != (uint8_t)-1, ("rate %d (%d) has no info", rate, ridx)); 114 return rt->info[cix].dot11Rate; 115 } 116 117 #endif /* IF_RTWN_RIDX_H */ 118