1 /* SPDX-License-Identifier: GPL-2.0-only */ 2 /* 3 * Copyright (c) 2017-2026 Morse Micro 4 */ 5 6 #ifndef _MM81X_RATE_CODE_H_ 7 #define _MM81X_RATE_CODE_H_ 8 9 #include <linux/types.h> 10 11 enum dot11_bandwidth { 12 DOT11_BANDWIDTH_1MHZ = 0, 13 DOT11_BANDWIDTH_2MHZ = 1, 14 DOT11_BANDWIDTH_4MHZ = 2, 15 DOT11_BANDWIDTH_8MHZ = 3, 16 DOT11_BANDWIDTH_16MHZ = 4, 17 18 DOT11_MAX_BANDWIDTH = DOT11_BANDWIDTH_16MHZ, 19 DOT11_INVALID_BANDWIDTH = 5 20 }; 21 22 enum mm81x_rate_preamble { 23 /* S1G LONG format (with SIG-A and SIG-B) */ 24 MM81X_RATE_PREAMBLE_S1G_LONG = 0, 25 /* This is the most common format used */ 26 MM81X_RATE_PREAMBLE_S1G_SHORT = 1, 27 /* S1G 1M format */ 28 MM81X_RATE_PREAMBLE_S1G_1M = 2, 29 30 MM81X_RATE_MAX_PREAMBLE = MM81X_RATE_PREAMBLE_S1G_1M, 31 MM81X_RATE_INVALID_PREAMBLE = 7 32 }; 33 34 typedef __le32 mm81x_rate_code_t; 35 36 #define MM81X_RATECODE_PREAMBLE (0x0000000F) 37 #define MM81X_RATECODE_MCS_INDEX (0x000000F0) 38 #define MM81X_RATECODE_NSS_INDEX (0x00000700) 39 #define MM81X_RATECODE_BW_INDEX (0x00003800) 40 #define MM81X_RATECODE_RTS_FLAG (0x00010000) 41 #define MM81X_RATECODE_SHORT_GI_FLAG (0x00040000) 42 #define MM81X_RATECODE_DUP_BW_INDEX (0x01C00000) 43 44 static inline enum mm81x_rate_preamble 45 mm81x_ratecode_preamble_get(mm81x_rate_code_t rc) 46 { 47 return (enum mm81x_rate_preamble)( 48 le32_get_bits(rc, MM81X_RATECODE_PREAMBLE)); 49 } 50 51 static inline u8 mm81x_ratecode_mcs_index_get(mm81x_rate_code_t rc) 52 { 53 return le32_get_bits(rc, MM81X_RATECODE_MCS_INDEX); 54 } 55 56 static inline u8 mm81x_ratecode_nss_index_get(mm81x_rate_code_t rc) 57 { 58 return le32_get_bits(rc, MM81X_RATECODE_NSS_INDEX); 59 } 60 61 static inline enum dot11_bandwidth 62 mm81x_ratecode_bw_index_get(mm81x_rate_code_t rc) 63 { 64 return (enum dot11_bandwidth)( 65 le32_get_bits(rc, MM81X_RATECODE_BW_INDEX)); 66 } 67 68 static inline bool mm81x_ratecode_rts_get(mm81x_rate_code_t rc) 69 { 70 return le32_get_bits(rc, MM81X_RATECODE_RTS_FLAG); 71 } 72 73 static inline bool mm81x_ratecode_sgi_get(mm81x_rate_code_t rc) 74 { 75 return le32_get_bits(rc, MM81X_RATECODE_SHORT_GI_FLAG); 76 } 77 78 static inline enum dot11_bandwidth 79 mm81x_ratecode_dup_bw_index_get(mm81x_rate_code_t rc) 80 { 81 return (enum dot11_bandwidth)( 82 le32_get_bits(rc, MM81X_RATECODE_DUP_BW_INDEX)); 83 } 84 85 #define MM81X_RATECODE_INIT(bw_idx, nss_idx, mcs_idx, preamble) \ 86 (le32_encode_bits((bw_idx), MM81X_RATECODE_BW_INDEX) | \ 87 le32_encode_bits((nss_idx), MM81X_RATECODE_NSS_INDEX) | \ 88 le32_encode_bits((mcs_idx), MM81X_RATECODE_MCS_INDEX) | \ 89 le32_encode_bits((preamble), MM81X_RATECODE_PREAMBLE)) 90 91 static inline mm81x_rate_code_t 92 mm81x_ratecode_init(enum dot11_bandwidth bw_index, u32 nss_index, u32 mcs_index, 93 enum mm81x_rate_preamble preamble) 94 { 95 return MM81X_RATECODE_INIT(bw_index, nss_index, mcs_index, preamble); 96 } 97 98 static inline void 99 mm81x_ratecode_preamble_set(mm81x_rate_code_t *rc, 100 enum mm81x_rate_preamble preamble) 101 { 102 *rc = (*rc & cpu_to_le32(~MM81X_RATECODE_PREAMBLE)) | 103 le32_encode_bits(preamble, MM81X_RATECODE_PREAMBLE); 104 } 105 106 static inline void mm81x_ratecode_mcs_index_set(mm81x_rate_code_t *rc, 107 u32 mcs_index) 108 { 109 *rc = (*rc & cpu_to_le32(~MM81X_RATECODE_MCS_INDEX)) | 110 le32_encode_bits(mcs_index, MM81X_RATECODE_MCS_INDEX); 111 } 112 113 static inline void mm81x_ratecode_nss_index_set(mm81x_rate_code_t *rc, 114 u32 nss_index) 115 { 116 *rc = (*rc & cpu_to_le32(~MM81X_RATECODE_NSS_INDEX)) | 117 le32_encode_bits(nss_index, MM81X_RATECODE_NSS_INDEX); 118 } 119 120 static inline void mm81x_ratecode_bw_index_set(mm81x_rate_code_t *rc, 121 enum dot11_bandwidth bw_index) 122 { 123 *rc = (*rc & cpu_to_le32(~MM81X_RATECODE_BW_INDEX)) | 124 le32_encode_bits(bw_index, MM81X_RATECODE_BW_INDEX); 125 } 126 127 static inline void 128 mm81x_ratecode_update_s1g_bw_preamble(mm81x_rate_code_t *rc, 129 enum dot11_bandwidth bw_index) 130 { 131 enum mm81x_rate_preamble pream = MM81X_RATE_PREAMBLE_S1G_SHORT; 132 133 if (bw_index == DOT11_BANDWIDTH_1MHZ) 134 pream = MM81X_RATE_PREAMBLE_S1G_1M; 135 136 mm81x_ratecode_preamble_set(rc, pream); 137 mm81x_ratecode_bw_index_set(rc, bw_index); 138 } 139 140 static inline void 141 mm81x_ratecode_dup_bw_index_set(mm81x_rate_code_t *rc, 142 enum dot11_bandwidth dup_bw_index) 143 { 144 *rc = (*rc & cpu_to_le32(~MM81X_RATECODE_DUP_BW_INDEX)) | 145 le32_encode_bits(dup_bw_index, MM81X_RATECODE_DUP_BW_INDEX); 146 } 147 148 static inline void mm81x_ratecode_enable_rts(mm81x_rate_code_t *rc) 149 { 150 *rc |= cpu_to_le32(MM81X_RATECODE_RTS_FLAG); 151 } 152 153 static inline void mm81x_ratecode_enable_sgi(mm81x_rate_code_t *rc) 154 { 155 *rc |= cpu_to_le32(MM81X_RATECODE_SHORT_GI_FLAG); 156 } 157 158 static inline enum dot11_bandwidth mm81x_ratecode_bw_mhz_to_bw_index(u8 bw_mhz) 159 { 160 return ((bw_mhz == 1) ? DOT11_BANDWIDTH_1MHZ : 161 (bw_mhz == 2) ? DOT11_BANDWIDTH_2MHZ : 162 (bw_mhz == 4) ? DOT11_BANDWIDTH_4MHZ : 163 (bw_mhz == 8) ? DOT11_BANDWIDTH_8MHZ : 164 DOT11_BANDWIDTH_2MHZ); 165 } 166 167 static inline u8 168 mm81x_ratecode_bw_index_to_s1g_bw_mhz(enum dot11_bandwidth bw_idx) 169 { 170 return ((bw_idx == DOT11_BANDWIDTH_1MHZ) ? 1 : 171 (bw_idx == DOT11_BANDWIDTH_2MHZ) ? 2 : 172 (bw_idx == DOT11_BANDWIDTH_4MHZ) ? 4 : 173 (bw_idx == DOT11_BANDWIDTH_8MHZ) ? 8 : 174 2); 175 } 176 177 #endif 178