2 ** $Id: //Department/DaVinci/BRANCHES/HS2_DEV_SW/MT6620_WIFI_DRIVER_V2_1_HS_2_0/mgmt/hs20.c#2 $
6 \brief This file including the hotspot 2.0 related function.
8 This file provided the macros and functions library support for the
9 protocol layer hotspot 2.0 related function.
20 /*******************************************************************************
21 * C O M P I L E R F L A G S
22 ********************************************************************************
25 /*******************************************************************************
26 * E X T E R N A L R E F E R E N C E S
27 ********************************************************************************
31 #if CFG_SUPPORT_PASSPOINT
33 /*******************************************************************************
35 ********************************************************************************
38 /*******************************************************************************
40 ********************************************************************************
43 /*******************************************************************************
45 ********************************************************************************
48 /*******************************************************************************
49 * P R I V A T E D A T A
50 ********************************************************************************
53 /*******************************************************************************
55 ********************************************************************************
58 /*******************************************************************************
59 * F U N C T I O N D E C L A R A T I O N S
60 ********************************************************************************
63 /*******************************************************************************
65 ********************************************************************************
68 /*----------------------------------------------------------------------------*/
70 * \brief This function is called to generate Interworking IE for Probe Rsp, Bcn, Assoc Req/Rsp.
72 * \param[in] prAdapter Pointer of ADAPTER_T
73 * \param[out] prMsduInfo Pointer of the Msdu Info
77 /*----------------------------------------------------------------------------*/
78 VOID
hs20GenerateInterworkingIE(IN P_ADAPTER_T prAdapter
, OUT P_MSDU_INFO_T prMsduInfo
)
82 /*----------------------------------------------------------------------------*/
84 * \brief This function is called to generate Roaming Consortium IE for Probe Rsp, Bcn, Assoc Req/Rsp.
86 * \param[in] prAdapter Pointer of ADAPTER_T
87 * \param[out] prMsduInfo Pointer of the Msdu Info
91 /*----------------------------------------------------------------------------*/
92 VOID
hs20GenerateRoamingConsortiumIE(IN P_ADAPTER_T prAdapter
, OUT P_MSDU_INFO_T prMsduInfo
)
96 /*----------------------------------------------------------------------------*/
98 * \brief This function is called to generate HS2.0 IE for Probe Rsp, Bcn, Assoc Req/Rsp.
100 * \param[in] prAdapter Pointer of ADAPTER_T
101 * \param[out] prMsduInfo Pointer of the Msdu Info
105 /*----------------------------------------------------------------------------*/
106 VOID
hs20GenerateHS20IE(IN P_ADAPTER_T prAdapter
, OUT P_MSDU_INFO_T prMsduInfo
)
113 if (prMsduInfo
->ucBssIndex
!= KAL_NETWORK_TYPE_AIS_INDEX
) {
114 pr_info("[%s] prMsduInfo->ucBssIndex(%d) is not KAL_NETWORK_TYPE_AIS_INDEX\n",
115 __func__
, prMsduInfo
->ucBssIndex
);
119 pucBuffer
= (PUINT_8
) ((ULONG
) prMsduInfo
->prPacket
+
120 (ULONG
) prMsduInfo
->u2FrameLength
);
122 /* ASSOC INFO IE ID: 221 :0xDD */
123 if (prAdapter
->prGlueInfo
->u2HS20AssocInfoIELen
) {
124 kalMemCopy(pucBuffer
, &prAdapter
->prGlueInfo
->aucHS20AssocInfoIE
,
125 prAdapter
->prGlueInfo
->u2HS20AssocInfoIELen
);
126 prMsduInfo
->u2FrameLength
+= prAdapter
->prGlueInfo
->u2HS20AssocInfoIELen
;
132 VOID
hs20FillExtCapIE(P_ADAPTER_T prAdapter
, P_BSS_INFO_T prBssInfo
, P_MSDU_INFO_T prMsduInfo
)
134 P_EXT_CAP_T prExtCap
;
139 /* Add Extended Capabilities IE */
140 prExtCap
= (P_EXT_CAP_T
)
141 (((PUINT_8
) prMsduInfo
->prPacket
) + prMsduInfo
->u2FrameLength
);
143 prExtCap
->ucId
= ELEM_ID_EXTENDED_CAP
;
144 if (prAdapter
->prGlueInfo
->fgConnectHS20AP
== TRUE
)
145 prExtCap
->ucLength
= ELEM_MAX_LEN_EXT_CAP
;
147 prExtCap
->ucLength
= 3 - ELEM_HDR_LEN
;
149 kalMemZero(prExtCap
->aucCapabilities
, prExtCap
->ucLength
);
151 prExtCap
->aucCapabilities
[0] = ELEM_EXT_CAP_DEFAULT_VAL
;
153 if (prBssInfo
->eCurrentOPMode
!= OP_MODE_INFRASTRUCTURE
) {
154 prExtCap
->aucCapabilities
[0] &= ~ELEM_EXT_CAP_PSMP_CAP
;
157 if (prAdapter
->prGlueInfo
->fgConnectHS20AP
== TRUE
) {
158 SET_EXT_CAP(prExtCap
->aucCapabilities
, ELEM_MAX_LEN_EXT_CAP
,
159 ELEM_EXT_CAP_BSS_TRANSITION_BIT
);
160 SET_EXT_CAP(prExtCap
->aucCapabilities
, ELEM_MAX_LEN_EXT_CAP
,
161 ELEM_EXT_CAP_UTC_TSF_OFFSET_BIT
);
162 SET_EXT_CAP(prExtCap
->aucCapabilities
, ELEM_MAX_LEN_EXT_CAP
,
163 ELEM_EXT_CAP_INTERWORKING_BIT
);
165 /* For R2 WNM-Notification */
166 SET_EXT_CAP(prExtCap
->aucCapabilities
, ELEM_MAX_LEN_EXT_CAP
,
167 ELEM_EXT_CAP_WNM_NOTIFICATION_BIT
);
170 pr_info("IE_SIZE(prExtCap) = %d, %d %d\n", IE_SIZE(prExtCap
), ELEM_HDR_LEN
,
171 ELEM_MAX_LEN_EXT_CAP
);
172 ASSERT(IE_SIZE(prExtCap
) <= (ELEM_HDR_LEN
+ ELEM_MAX_LEN_EXT_CAP
));
174 prMsduInfo
->u2FrameLength
+= IE_SIZE(prExtCap
);
178 /*----------------------------------------------------------------------------*/
180 * \brief This function is called to fill up the content of Ext Cap IE bit 31.
182 * \param[in] prAdapter Pointer of ADAPTER_T
183 * \param[out] pucIE Pointer of the IE buffer
187 /*----------------------------------------------------------------------------*/
188 VOID
hs20FillProreqExtCapIE(IN P_ADAPTER_T prAdapter
, OUT PUINT_8 pucIE
)
190 P_EXT_CAP_T prExtCap
;
194 /* Add Extended Capabilities IE */
195 prExtCap
= (P_EXT_CAP_T
) pucIE
;
197 prExtCap
->ucId
= ELEM_ID_EXTENDED_CAP
;
198 if (prAdapter
->prGlueInfo
->fgConnectHS20AP
== TRUE
)
199 prExtCap
->ucLength
= ELEM_MAX_LEN_EXT_CAP
;
201 prExtCap
->ucLength
= 3 - ELEM_HDR_LEN
;
203 kalMemZero(prExtCap
->aucCapabilities
, prExtCap
->ucLength
);
205 prExtCap
->aucCapabilities
[0] = ELEM_EXT_CAP_DEFAULT_VAL
;
207 if (prAdapter
->prGlueInfo
->fgConnectHS20AP
== TRUE
) {
208 SET_EXT_CAP(prExtCap
->aucCapabilities
, ELEM_MAX_LEN_EXT_CAP
,
209 ELEM_EXT_CAP_BSS_TRANSITION_BIT
);
210 SET_EXT_CAP(prExtCap
->aucCapabilities
, ELEM_MAX_LEN_EXT_CAP
,
211 ELEM_EXT_CAP_UTC_TSF_OFFSET_BIT
);
212 SET_EXT_CAP(prExtCap
->aucCapabilities
, ELEM_MAX_LEN_EXT_CAP
,
213 ELEM_EXT_CAP_INTERWORKING_BIT
);
215 /* For R2 WNM-Notification */
216 SET_EXT_CAP(prExtCap
->aucCapabilities
, ELEM_MAX_LEN_EXT_CAP
,
217 ELEM_EXT_CAP_WNM_NOTIFICATION_BIT
);
222 /*----------------------------------------------------------------------------*/
224 * \brief This function is called to fill up the content of HS2.0 IE.
226 * \param[in] prAdapter Pointer of ADAPTER_T
227 * \param[out] pucIE Pointer of the IE buffer
231 /*----------------------------------------------------------------------------*/
232 VOID
hs20FillHS20IE(IN P_ADAPTER_T prAdapter
, OUT PUINT_8 pucIE
)
234 P_IE_HS20_INDICATION_T prHS20IndicationIe
;
235 /* P_HS20_INFO_T prHS20Info; */
236 UINT_8 aucWfaOui
[] = VENDOR_OUI_WFA_SPECIFIC
;
238 /* prHS20Info = &(prAdapter->rWifiVar.rHS20Info); */
240 prHS20IndicationIe
= (P_IE_HS20_INDICATION_T
) pucIE
;
242 prHS20IndicationIe
->ucId
= ELEM_ID_VENDOR
;
243 prHS20IndicationIe
->ucLength
= sizeof(IE_HS20_INDICATION_T
) - ELEM_HDR_LEN
;
244 prHS20IndicationIe
->aucOui
[0] = aucWfaOui
[0];
245 prHS20IndicationIe
->aucOui
[1] = aucWfaOui
[1];
246 prHS20IndicationIe
->aucOui
[2] = aucWfaOui
[2];
247 prHS20IndicationIe
->ucType
= VENDOR_OUI_TYPE_HS20
;
249 /* prHS20IndicationIe->ucHotspotConfig = 0x00; */ /* For PASSPOINT_R1 */
250 prHS20IndicationIe
->ucHotspotConfig
= 0x10; /* For PASSPOINT_R2 */
255 /*----------------------------------------------------------------------------*/
257 * \brief This function is called while calculating length of hotspot 2.0 indication IE for Probe Request.
259 * \param[in] prAdapter Pointer of ADAPTER_T
260 * \param[in] pucTargetBSSID Pointer of target HESSID
262 * \return the length of composed HS20 IE
264 /*----------------------------------------------------------------------------*/
265 UINT_32
hs20CalculateHS20RelatedIEForProbeReq(IN P_ADAPTER_T prAdapter
, IN PUINT_8 pucTargetBSSID
)
269 if (0) /* Todo:: Not HS20 STA */
273 sizeof(IE_HS20_INDICATION_T
) + /* sizeof(IE_INTERWORKING_T) */ + (ELEM_HDR_LEN
+
274 ELEM_MAX_LEN_EXT_CAP
);
276 if (!pucTargetBSSID
) {
277 /* u4IeLength -= MAC_ADDR_LEN; */
284 /*----------------------------------------------------------------------------*/
286 * \brief This function is called while composing hotspot 2.0 indication IE for Probe Request.
288 * \param[in] prAdapter Pointer of ADAPTER_T
289 * \param[in] pucTargetBSSID Pointer of target HESSID
290 * \param[out] prIE Pointer of the IE buffer
292 * \return the wlan status
294 /*----------------------------------------------------------------------------*/
296 hs20GenerateHS20RelatedIEForProbeReq(IN P_ADAPTER_T prAdapter
,
297 IN PUINT_8 pucTargetBSSID
, OUT PUINT_8 prIE
)
299 if (0) /* Todo:: Not HS20 STA */
302 P_HS20_INFO_T prHS20Info
;
304 prHS20Info
= &(prAdapter
->rWifiVar
.rHS20Info
);
308 * Generate 802.11u Interworking IE (107)
310 hs20FillInterworkingIE(prAdapter
,
311 prHS20Info
->ucAccessNetworkOptions
,
312 prHS20Info
->ucVenueGroup
,
313 prHS20Info
->ucVenueType
, pucTargetBSSID
, prIE
);
314 prIE
+= IE_SIZE(prIE
);
317 * Generate Ext Cap IE (127)
319 hs20FillProreqExtCapIE(prAdapter
, prIE
);
320 prIE
+= IE_SIZE(prIE
);
323 * Generate HS2.0 Indication IE (221)
325 hs20FillHS20IE(prAdapter
, prIE
);
326 prIE
+= IE_SIZE(prIE
);
328 return WLAN_STATUS_SUCCESS
;
331 BOOLEAN
hs20IsGratuitousArp(IN P_ADAPTER_T prAdapter
, IN P_SW_RFB_T prCurrSwRfb
)
333 PUINT_8 pucSenderIP
= prCurrSwRfb
->pvHeader
+ ETHER_HEADER_LEN
+ ARP_SENDER_IP_OFFSET
;
334 PUINT_8 pucTargetIP
= prCurrSwRfb
->pvHeader
+ ETHER_HEADER_LEN
+ ARP_TARGET_IP_OFFSET
;
335 PUINT_8 pucSenderMac
=
336 ((PUINT_8
) prCurrSwRfb
->pvHeader
+ ETHER_HEADER_LEN
+ ARP_SNEDER_MAC_OFFSET
);
337 #if CFG_HS20_DEBUG && 0
338 /* UINT_8 aucIpAllZero[4] = {0,0,0,0}; */
339 /* UINT_8 aucMACAllZero[MAC_ADDR_LEN] = {0,0,0,0,0,0}; */
340 PUINT_8 pucTargetMac
=
341 ((PUINT_8
) prCurrSwRfb
->pvHeader
+ ETHER_HEADER_LEN
+ ARP_TARGET_MAC_OFFSET
);
344 #if CFG_HS20_DEBUG && 0
345 PUINT_16 pu2ArpOper
=
346 (PUINT_16
) ((PUINT_8
) prCurrSwRfb
->pvHeader
+ ETHER_HEADER_LEN
+ ARP_OPERATION_OFFSET
);
348 kalPrint("Recv ARP 0x%04X\n", htons(*pu2ArpOper
));
349 kalPrint("SENDER[" MACSTR
"] [%d:%d:%d:%d]\n", MAC2STR(pucSenderMac
), *pucSenderIP
,
350 *(pucSenderIP
+ 1), *(pucSenderIP
+ 2), *(pucSenderIP
+ 3));
351 kalPrint("TARGET[" MACSTR
"] [%d:%d:%d:%d]\n", MAC2STR(pucTargetMac
), *pucTargetIP
,
352 *(pucTargetIP
+ 1), *(pucTargetIP
+ 2), *(pucTargetIP
+ 3));
355 /* IsGratuitousArp */
356 if (!kalMemCmp(pucSenderIP
, pucTargetIP
, 4)) {
357 kalPrint("Drop Gratuitous ARP from [" MACSTR
"] [%d:%d:%d:%d]\n",
358 MAC2STR(pucSenderMac
), *pucTargetIP
, *(pucTargetIP
+ 1),
359 *(pucTargetIP
+ 2), *(pucTargetIP
+ 3));
365 BOOLEAN
hs20IsUnsolicitedNeighborAdv(IN P_ADAPTER_T prAdapter
, IN P_SW_RFB_T prCurrSwRfb
)
367 PUINT_8 pucIpv6Protocol
=
368 ((PUINT_8
) prCurrSwRfb
->pvHeader
+ ETHER_HEADER_LEN
+ IPV6_HDR_IP_PROTOCOL_OFFSET
);
370 /* kalPrint("pucIpv6Protocol [%02X:%02X]\n", *pucIpv6Protocol, IPV6_PROTOCOL_ICMPV6); */
371 if (*pucIpv6Protocol
== IPV6_PROTOCOL_ICMPV6
) {
372 PUINT_8 pucICMPv6Type
=
373 ((PUINT_8
) prCurrSwRfb
->pvHeader
+ ETHER_HEADER_LEN
+ IPV6_HDR_LEN
+
375 /* kalPrint("pucICMPv6Type [%02X:%02X]\n", *pucICMPv6Type, ICMPV6_TYPE_NEIGHBOR_ADVERTISEMENT); */
376 if (*pucICMPv6Type
== ICMPV6_TYPE_NEIGHBOR_ADVERTISEMENT
) {
377 PUINT_8 pucICMPv6Flag
=
378 ((PUINT_8
) prCurrSwRfb
->pvHeader
+ ETHER_HEADER_LEN
+ IPV6_HDR_LEN
+
380 PUINT_8 pucSrcMAC
= ((PUINT_8
) prCurrSwRfb
->pvHeader
+ MAC_ADDR_LEN
);
383 kalPrint("NAdv Flag [%02X] [R(%d)\\S(%d)\\O(%d)]\n",
385 (UINT_8
) (*pucICMPv6Flag
& ICMPV6_FLAG_ROUTER_BIT
) >> 7,
386 (UINT_8
) (*pucICMPv6Flag
& ICMPV6_FLAG_SOLICITED_BIT
) >> 6,
387 (UINT_8
) (*pucICMPv6Flag
& ICMPV6_FLAG_OVERWRITE_BIT
) >> 5);
389 if (!(*pucICMPv6Flag
& ICMPV6_FLAG_SOLICITED_BIT
)) {
390 kalPrint("Drop Unsolicited Neighbor Advertisement from [" MACSTR
391 "]\n", MAC2STR(pucSrcMAC
));
401 #if CFG_ENABLE_GTK_FRAME_FILTER
403 hs20IsForgedGTKFrame(IN P_ADAPTER_T prAdapter
, IN P_BSS_INFO_T prBssInfo
, IN P_SW_RFB_T prCurrSwRfb
)
405 P_CONNECTION_SETTINGS_T prConnSettings
= &prAdapter
->rWifiVar
.rConnSettings
;
406 PUINT_8 pucEthDestAddr
= prCurrSwRfb
->pvHeader
;
408 /* 3 TODO: Need to verify this function before enable it */
411 if ((prConnSettings
->eEncStatus
!= ENUM_ENCRYPTION_DISABLED
)
412 && IS_BMCAST_MAC_ADDR(pucEthDestAddr
)) {
414 PUINT_32 prIpAddr
, prPacketDA
;
415 PUINT_16 pu2PktIpVer
=
416 (PUINT_16
) ((PUINT_8
) prCurrSwRfb
->pvHeader
+
417 (ETHER_HEADER_LEN
- ETHER_TYPE_LEN
));
419 if (*pu2PktIpVer
== htons(ETH_P_IPV4
)) {
420 if (!prBssInfo
->prIpV4NetAddrList
) {
423 for (ucIdx
= 0; ucIdx
< prBssInfo
->prIpV4NetAddrList
->ucAddrCount
; ucIdx
++) {
425 (PUINT_32
) &prBssInfo
->prIpV4NetAddrList
->arNetAddr
[ucIdx
].
428 (PUINT_32
) ((PUINT_8
) prCurrSwRfb
->pvHeader
+ ETHER_HEADER_LEN
+
429 IPV4_HDR_IP_DST_ADDR_OFFSET
);
431 if (kalMemCmp(prIpAddr
, prPacketDA
, 4) == 0) {
432 kalPrint("Drop FORGED IPv4 packet\n");
438 else if (*pu2PktIpVer
== htons(ETH_P_IPV6
)) {
439 UINT_8 aucIPv6Mac
[MAC_ADDR_LEN
];
441 prCurrSwRfb
->pvHeader
+ ETHER_HEADER_LEN
+
442 IPV6_HDR_IP_DST_ADDR_MAC_HIGH_OFFSET
;
444 kalMemCopy(&aucIPv6Mac
[0], pucIdx
, 3);
446 kalMemCopy(&aucIPv6Mac
[3], pucIdx
, 3);
447 kalPrint("Get IPv6 frame Dst IP MAC part " MACSTR
"\n",
448 MAC2STR(aucIPv6Mac
));
449 if (EQUAL_MAC_ADDR(aucIPv6Mac
, prBssInfo
->aucOwnMacAddr
)) {
450 kalPrint("Drop FORGED IPv6 packet\n");
462 hs20IsUnsecuredFrame(IN P_ADAPTER_T prAdapter
, IN P_BSS_INFO_T prBssInfo
, IN P_SW_RFB_T prCurrSwRfb
)
464 PUINT_16 pu2PktIpVer
=
465 (PUINT_16
) ((PUINT_8
) prCurrSwRfb
->pvHeader
+ (ETHER_HEADER_LEN
- ETHER_TYPE_LEN
));
467 /* kalPrint("IPVER 0x%4X\n", htons(*pu2PktIpVer)); */
468 #if CFG_HS20_DEBUG & 0
471 kalPrint("===============================================");
472 for (i
= 0; i
< 96; i
++) {
476 kalPrint("%02X ", *((PUINT_8
) prCurrSwRfb
->pvHeader
+ i
));
481 #if CFG_ENABLE_GTK_FRAME_FILTER
482 if (hs20IsForgedGTKFrame(prAdapter
, prBssInfo
, prCurrSwRfb
)) {
486 if (*pu2PktIpVer
== htons(ETH_P_ARP
)) {
487 return hs20IsGratuitousArp(prAdapter
, prCurrSwRfb
);
488 } else if (*pu2PktIpVer
== htons(ETH_P_IPV6
)) {
489 return hs20IsUnsolicitedNeighborAdv(prAdapter
, prCurrSwRfb
);
495 BOOLEAN
hs20IsFrameFilterEnabled(IN P_ADAPTER_T prAdapter
, IN P_BSS_INFO_T prBssInfo
)
498 if (prAdapter
->prGlueInfo
->fgConnectHS20AP
) {
502 PARAM_SSID_T rParamSsid
;
503 P_BSS_DESC_T prBssDesc
;
505 rParamSsid
.u4SsidLen
= prBssInfo
->ucSSIDLen
;
506 COPY_SSID(rParamSsid
.aucSsid
, rParamSsid
.u4SsidLen
, prBssInfo
->aucSSID
,
507 prBssInfo
->ucSSIDLen
);
510 scanSearchBssDescByBssidAndSsid(prAdapter
, prBssInfo
->aucBSSID
, TRUE
, &rParamSsid
);
515 if (prBssDesc
->fgIsSupportHS20
) {
516 if (!(prBssDesc
->ucHotspotConfig
& ELEM_HS_CONFIG_DGAF_DISABLED_MASK
)) {
519 /* Disable frame filter only if DGAF == 1 */
525 /* For Now, always return true to run hs20 check even for legacy AP */
531 hs20SetBssidPool(IN P_ADAPTER_T prAdapter
,
532 IN PVOID pvBuffer
, IN ENUM_KAL_NETWORK_TYPE_INDEX_T eNetTypeIdx
)
534 P_PARAM_HS20_SET_BSSID_POOL prParamBssidPool
= (P_PARAM_HS20_SET_BSSID_POOL
) pvBuffer
;
535 P_HS20_INFO_T prHS20Info
;
538 prHS20Info
= &(prAdapter
->rWifiVar
.rHS20Info
);
540 pr_info("[%s]Set Bssid Pool! enable[%d] num[%d]\n", __func__
, prParamBssidPool
->fgIsEnable
,
541 prParamBssidPool
->ucNumBssidPool
);
543 for (ucIdx
= 0; ucIdx
< prParamBssidPool
->ucNumBssidPool
; ucIdx
++) {
544 COPY_MAC_ADDR(prHS20Info
->arBssidPool
[ucIdx
].aucBSSID
,
545 &prParamBssidPool
->arBSSID
[ucIdx
]);
546 pr_info("[%s][%d][" MACSTR
"]\n", __func__
, ucIdx
,
547 MAC2STR(prHS20Info
->arBssidPool
[ucIdx
].aucBSSID
));
549 prHS20Info
->fgIsHS2SigmaMode
= prParamBssidPool
->fgIsEnable
;
550 prHS20Info
->ucNumBssidPoolEntry
= prParamBssidPool
->ucNumBssidPool
;
553 wlanClearScanningResult(prAdapter
);
556 return WLAN_STATUS_SUCCESS
;
560 #endif /* CFG_SUPPORT_PASSPOINT */