xref: /OK3568_Linux_fs/kernel/drivers/net/wireless/rockchip_wlan/mvl88w8977/mlan/esa/common/parser_rom.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /** @file parser_rom.c
2  *
3  *  @brief This file define the  function for 802.11 Management Frames Parsing
4  *
5  * Copyright (C) 2014-2017, Marvell International Ltd.
6  *
7  * This software file (the "File") is distributed by Marvell International
8  * Ltd. under the terms of the GNU General Public License Version 2, June 1991
9  * (the "License").  You may use, redistribute and/or modify this File in
10  * accordance with the terms and conditions of the License, a copy of which
11  * is available by writing to the Free Software Foundation, Inc.,
12  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
13  * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
14  *
15  * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
17  * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about
18  * this warranty disclaimer.
19  */
20 
21 /******************************************************
22 Change log:
23     03/07/2014: Initial version
24 ******************************************************/
25 #include "parser_rom.h"
26 
27 #include "hostsa_ext_def.h"
28 #include "authenticator.h"
29 
30 #define WMM_IE_MIN_LEN  7
31 
32 VendorSpecificIEType_e
IsWMMElement(void * priv,uint8 * pBuffer)33 IsWMMElement(void *priv, uint8 *pBuffer)
34 {
35 	phostsa_private psapriv = (phostsa_private)priv;
36 	hostsa_util_fns *util_fns = &psapriv->util_fns;
37 
38 	VendorSpecificIEType_e retVal = VendSpecIE_Other;
39 	const uint8 szMatchingInfoElement[] = { 0x00, 0x50, 0xf2,
40 		0x02, 0x00, 0x01
41 	};
42 	const uint8 szMatchingParamElement[] = { 0x00, 0x50, 0xf2,
43 		0x02, 0x01, 0x01
44 	};
45 	const uint8 szMatchingTspecElement[] = { 0x00, 0x50, 0xf2,
46 		0x02, 0x02, 0x01
47 	};
48 
49 	if (!memcmp(util_fns, pBuffer,
50 		    szMatchingInfoElement, sizeof(szMatchingInfoElement))) {
51 		retVal = VendSpecIE_WMM_Info;
52 	} else if (!memcmp(util_fns, pBuffer,
53 			   szMatchingParamElement,
54 			   sizeof(szMatchingParamElement))) {
55 		retVal = VendSpecIE_WMM_Param;
56 	} else if (!memcmp(util_fns, pBuffer,
57 			   szMatchingTspecElement,
58 			   sizeof(szMatchingTspecElement))) {
59 		retVal = VendSpecIE_TSPEC;
60 	}
61 
62 	return retVal;
63 }
64 
65 VendorSpecificIEType_e
IsWPAElement(void * priv,uint8 * pBuffer)66 IsWPAElement(void *priv, uint8 *pBuffer)
67 {
68 	phostsa_private psapriv = (phostsa_private)priv;
69 	hostsa_util_fns *util_fns = &psapriv->util_fns;
70 
71 	VendorSpecificIEType_e retVal = VendSpecIE_Other;
72 	const uint8 szMatchingInfoElement[] = { 0x00, 0x50, 0xf2,
73 		0x01, 0x01, 0x00
74 	};
75 
76 	if (!memcmp(util_fns, pBuffer,
77 		    szMatchingInfoElement, sizeof(szMatchingInfoElement))) {
78 		retVal = VendSpecIE_WPA;
79 	}
80 
81 	return retVal;
82 }
83 
84 BOOLEAN
ROM_parser_getIEPtr(void * priv,uint8 * pIe,IEPointers_t * pIePointers)85 ROM_parser_getIEPtr(void *priv, uint8 *pIe, IEPointers_t *pIePointers)
86 {
87 	BOOLEAN status = TRUE;
88 	switch (*pIe) {
89 	case ELEM_ID_SSID:
90 		pIePointers->pSsid = (IEEEtypes_SsIdElement_t *)pIe;
91 		break;
92 
93 	case ELEM_ID_DS_PARAM_SET:
94 		pIePointers->pDsParam = (IEEEtypes_DsParamElement_t *)pIe;
95 		break;
96 
97 	case ELEM_ID_TIM:
98 		pIePointers->pTim = (IEEEtypes_TimElement_t *)pIe;
99 		break;
100 
101 	case ELEM_ID_SUPPORTED_RATES:
102 		pIePointers->pSupportedRates =
103 			(IEEEtypes_SuppRatesElement_t *)pIe;
104 		break;
105 
106 	case ELEM_ID_EXT_SUPPORTED_RATES:
107 		pIePointers->pExtSupportedRates
108 			= (IEEEtypes_ExtSuppRatesElement_t *)pIe;
109 		break;
110 
111 	case ELEM_ID_ERP_INFO:
112 		pIePointers->pErpInfo = (IEEEtypes_ERPInfoElement_t *)pIe;
113 		break;
114 
115 	case ELEM_ID_IBSS_PARAM_SET:
116 		pIePointers->pIbssParam = (IEEEtypes_IbssParamElement_t *)pIe;
117 		break;
118 
119 	case ELEM_ID_COUNTRY:
120 		pIePointers->pCountry = (IEEEtypes_CountryInfoElement_t *)pIe;
121 		break;
122 
123 	case ELEM_ID_RSN:
124 		pIePointers->pRsn = (IEEEtypes_RSNElement_t *)pIe;
125 		break;
126 
127 	case ELEM_ID_VENDOR_SPECIFIC:
128 
129 		if (IsWPAElement(priv, (pIe + 2))) {
130 			pIePointers->pWpa = (IEEEtypes_WPAElement_t *)pIe;
131 		} else {
132 			switch (IsWMMElement(priv, (pIe + 2))) {
133 			case VendSpecIE_Other:
134 			case VendSpecIE_TSPEC:
135 			default:
136 				status = FALSE;
137 				break;
138 
139 			case VendSpecIE_WMM_Info:
140 				pIePointers->pWmmInfo =
141 					(IEEEtypes_WMM_InfoElement_t *)pIe;
142 				break;
143 
144 			case VendSpecIE_WMM_Param:
145 				pIePointers->pWmmParam
146 					= (IEEEtypes_WMM_ParamElement_t *)pIe;
147 				break;
148 			}
149 
150 		}
151 		break;
152 	default:
153 		status = FALSE;
154 		break;
155 	}
156 
157 	return status;
158 }
159 
160 BOOLEAN
ROM_parser_getAssocIEPtr(void * priv,uint8 * pIe,AssocIePointers_t * pIePointers)161 ROM_parser_getAssocIEPtr(void *priv, uint8 *pIe, AssocIePointers_t *pIePointers)
162 {
163 	BOOLEAN status = TRUE;
164 	switch (*pIe) {
165 	case ELEM_ID_SSID:
166 		pIePointers->pSsid = (IEEEtypes_SsIdElement_t *)pIe;
167 		break;
168 
169 	case ELEM_ID_COUNTRY:
170 		pIePointers->pCountry = (IEEEtypes_CountryInfoElement_t *)pIe;
171 		break;
172 
173 	case ELEM_ID_DS_PARAM_SET:
174 		pIePointers->pDsParam = (IEEEtypes_DsParamElement_t *)pIe;
175 		break;
176 
177 	case ELEM_ID_SUPPORTED_RATES:
178 		pIePointers->pSupportedRates =
179 			(IEEEtypes_SuppRatesElement_t *)pIe;
180 		break;
181 
182 	case ELEM_ID_EXT_SUPPORTED_RATES:
183 		pIePointers->pExtSupportedRates
184 			= (IEEEtypes_ExtSuppRatesElement_t *)pIe;
185 		break;
186 
187 	case ELEM_ID_RSN:
188 		pIePointers->pRsn = (IEEEtypes_RSNElement_t *)pIe;
189 		break;
190 
191 	case ELEM_ID_VENDOR_SPECIFIC:
192 		if (IsWPAElement(priv, (pIe + 2))) {
193 			pIePointers->pWpa = (IEEEtypes_WPAElement_t *)pIe;
194 		} else {
195 			switch (IsWMMElement(priv, (pIe + 2))) {
196 			case VendSpecIE_Other:
197 			case VendSpecIE_TSPEC:
198 			default:
199 				status = FALSE;
200 				break;
201 
202 			case VendSpecIE_WMM_Info:
203 				pIePointers->pWmmInfo
204 					= (IEEEtypes_WMM_InfoElement_t *)pIe;
205 				break;
206 
207 			case VendSpecIE_WMM_Param:
208 				pIePointers->pWmmParam
209 					= (IEEEtypes_WMM_ParamElement_t *)pIe;
210 				break;
211 			}
212 		}
213 		break;
214 	default:
215 		status = FALSE;
216 		break;
217 	}
218 
219 	return status;
220 }
221 
222 IEEEtypes_InfoElementHdr_t *
parser_getSpecificIE(IEEEtypes_ElementId_e elemId,UINT8 * pIe,int bufLen)223 parser_getSpecificIE(IEEEtypes_ElementId_e elemId, UINT8 *pIe, int bufLen)
224 {
225 	if (!pIe) {
226 		return NULL;
227 	}
228 
229 	while (bufLen) {
230 		if (bufLen < (*(pIe + 1) + 2)) {
231 			break;
232 		}
233 
234 		if (*pIe == elemId) {
235 			return (IEEEtypes_InfoElementHdr_t *)pIe;
236 		}
237 
238 		bufLen -= *(pIe + 1) + 2;
239 		pIe += *(pIe + 1) + 2;
240 	}
241 
242 	return NULL;
243 }
244