2 *****************************************************************************
6 * Copyright (C) ESWIN 2015-2020
8 *****************************************************************************
11 #include <linux/string.h>
14 const struct ecrnx_legrate legrates_lut[] = {
15 [0] = { .idx = 0, .rate = 10 },
16 [1] = { .idx = 1, .rate = 20 },
17 [2] = { .idx = 2, .rate = 55 },
18 [3] = { .idx = 3, .rate = 110 },
19 [4] = { .idx = -1, .rate = 0 },
20 [5] = { .idx = -1, .rate = 0 },
21 [6] = { .idx = -1, .rate = 0 },
22 [7] = { .idx = -1, .rate = 0 },
23 [8] = { .idx = 10, .rate = 480 },
24 [9] = { .idx = 8, .rate = 240 },
25 [10] = { .idx = 6, .rate = 120 },
26 [11] = { .idx = 4, .rate = 60 },
27 [12] = { .idx = 11, .rate = 540 },
28 [13] = { .idx = 9, .rate = 360 },
29 [14] = { .idx = 7, .rate = 180 },
30 [15] = { .idx = 5, .rate = 90 },
34 * ecrnx_machw_type - Return type (NX or HE) MAC HW is used
37 int ecrnx_machw_type(uint32_t machw_version_2)
39 uint32_t machw_um_ver_maj = (machw_version_2 >> 4) & 0x7;
41 if (machw_um_ver_maj >= 4)
42 return ECRNX_MACHW_HE;
44 return ECRNX_MACHW_NX;
48 * ecrnx_rx_vector_convert - Convert in place a RX vector from NX hardware into
49 * a RX vector formatted by HE hardware.
51 * @machw_type: Type of MACHW in use.
52 * @rx_vect1: Rx vector 1 descriptor of the received frame.
53 * @rx_vect2: Rx vector 2 descriptor of the received frame.
55 void ecrnx_rx_vector_convert(int machw_type,
56 struct rx_vector_1 *rx_vect1,
57 struct rx_vector_2 *rx_vect2)
59 struct rx_vector_1_nx rx_vect1_nx;
60 struct rx_vector_2_nx rx_vect2_nx;
62 // Check if we need to do the conversion. Only if old modem is used
63 if (machw_type == ECRNX_MACHW_HE) {
64 rx_vect1->rssi1 = rx_vect1->rssi_leg;
68 // Copy the received vector locally
69 memcpy(&rx_vect1_nx, rx_vect1, sizeof(struct rx_vector_1_nx));
72 memset(rx_vect1, 0, sizeof(struct rx_vector_1));
74 // Perform the conversion
75 rx_vect1->format_mod = rx_vect1_nx.format_mod;
76 rx_vect1->ch_bw = rx_vect1_nx.ch_bw;
77 rx_vect1->pre_type = rx_vect1_nx.pre_type;
78 rx_vect1->antenna_set = rx_vect1_nx.antenna_set;
79 rx_vect1->leg_length = rx_vect1_nx.leg_length;
80 rx_vect1->leg_rate = rx_vect1_nx.leg_rate;
81 rx_vect1->rssi1 = rx_vect1_nx.rssi1;
83 switch (rx_vect1->format_mod) {
84 case FORMATMOD_NON_HT:
85 case FORMATMOD_NON_HT_DUP_OFDM:
86 rx_vect1->leg.dyn_bw_in_non_ht = rx_vect1_nx.dyn_bw;
87 rx_vect1->leg.chn_bw_in_non_ht = rx_vect1_nx.ch_bw;
88 rx_vect1->leg.lsig_valid = rx_vect1_nx.lsig_valid;
92 rx_vect1->ht.sounding = rx_vect1_nx.sounding;
93 rx_vect1->ht.smoothing = rx_vect1_nx.smoothing;
94 rx_vect1->ht.short_gi = rx_vect1_nx.short_gi;
95 rx_vect1->ht.aggregation = rx_vect1_nx.aggregation;
96 rx_vect1->ht.stbc = rx_vect1_nx.stbc;
97 rx_vect1->ht.num_extn_ss = rx_vect1_nx.num_extn_ss;
98 rx_vect1->ht.lsig_valid = rx_vect1_nx.lsig_valid;
99 rx_vect1->ht.mcs = rx_vect1_nx.mcs;
100 rx_vect1->ht.fec = rx_vect1_nx.fec_coding;
101 rx_vect1->ht.length = rx_vect1_nx.ht_length;
104 rx_vect1->vht.sounding = rx_vect1_nx.sounding;
105 rx_vect1->vht.beamformed = !rx_vect1_nx.smoothing;
106 rx_vect1->vht.short_gi = rx_vect1_nx.short_gi;
107 rx_vect1->vht.stbc = rx_vect1_nx.stbc;
108 rx_vect1->vht.doze_not_allowed = rx_vect1_nx.doze_not_allowed;
109 rx_vect1->vht.first_user = rx_vect1_nx.first_user;
110 rx_vect1->vht.partial_aid = rx_vect1_nx.partial_aid;
111 rx_vect1->vht.group_id = rx_vect1_nx.group_id;
112 rx_vect1->vht.mcs = rx_vect1_nx.mcs;
113 rx_vect1->vht.nss = rx_vect1_nx.stbc ? rx_vect1_nx.n_sts/2 : rx_vect1_nx.n_sts;
114 rx_vect1->vht.fec = rx_vect1_nx.fec_coding;
115 rx_vect1->vht.length = (rx_vect1_nx._ht_length << 16) | rx_vect1_nx.ht_length;
122 // Copy the received vector 2 locally
123 memcpy(&rx_vect2_nx, rx_vect2, sizeof(struct rx_vector_2_nx));
126 memset(rx_vect2, 0, sizeof(struct rx_vector_2));
128 rx_vect2->rcpi1 = rx_vect2_nx.rcpi;
129 rx_vect2->rcpi2 = rx_vect2_nx.rcpi;
130 rx_vect2->rcpi3 = rx_vect2_nx.rcpi;
131 rx_vect2->rcpi4 = rx_vect2_nx.rcpi;
133 rx_vect2->evm1 = rx_vect2_nx.evm1;
134 rx_vect2->evm2 = rx_vect2_nx.evm2;
135 rx_vect2->evm3 = rx_vect2_nx.evm3;
136 rx_vect2->evm4 = rx_vect2_nx.evm4;
141 * ecrnx_rx_status_convert - Convert in place a legacy MPDU status from NX hardware
142 * into a MPDU status formatted by HE hardware.
144 * @machw_type: Type of MACHW in use.
145 * @status: Rx MPDU status of the received frame.
147 void ecrnx_rx_status_convert(int machw_type, struct mpdu_status *status)
149 struct mpdu_status_nx *status_nx;
151 if (machw_type == ECRNX_MACHW_HE)
154 status_nx = (struct mpdu_status_nx *)status;
155 status->undef_err = status_nx->undef_err;
157 switch (status_nx->decr_status) {
158 case ECRNX_RX_HD_NX_DECR_UNENC:
159 status->decr_type = ECRNX_RX_HD_DECR_UNENC;
160 status->decr_err = 0;
162 case ECRNX_RX_HD_NX_DECR_ICVFAIL:
163 status->decr_type = ECRNX_RX_HD_DECR_WEP;
164 status->decr_err = 1;
166 case ECRNX_RX_HD_NX_DECR_CCMPFAIL:
167 case ECRNX_RX_HD_NX_DECR_AMSDUDISCARD:
168 status->decr_type = ECRNX_RX_HD_DECR_CCMP128;
169 status->decr_err = 1;
171 case ECRNX_RX_HD_NX_DECR_NULLKEY:
172 status->decr_type = ECRNX_RX_HD_DECR_NULLKEY;
173 status->decr_err = 1;
175 case ECRNX_RX_HD_NX_DECR_WEPSUCCESS:
176 status->decr_type = ECRNX_RX_HD_DECR_WEP;
177 status->decr_err = 0;
179 case ECRNX_RX_HD_NX_DECR_TKIPSUCCESS:
180 status->decr_type = ECRNX_RX_HD_DECR_TKIP;
181 status->decr_err = 0;
183 case ECRNX_RX_HD_NX_DECR_CCMPSUCCESS:
184 status->decr_type = ECRNX_RX_HD_DECR_CCMP128;
185 status->decr_err = 0;