u8 *rtw_get_wps_ie_from_scan_queue(u8 *in_ie, uint in_len, u8 *wps_ie, uint *wps_ielen, u8 frame_type) { u8* wps = NULL; DBG_871X( "[%s] frame_type = %d\n", __FUNCTION__, frame_type ); switch( frame_type ) { case 1: case 3: { // Beacon or Probe Response wps = rtw_get_wps_ie(in_ie + _PROBERSP_IE_OFFSET_, in_len - _PROBERSP_IE_OFFSET_, wps_ie, wps_ielen); break; } case 2: { // Probe Request wps = rtw_get_wps_ie(in_ie + _PROBEREQ_IE_OFFSET_ , in_len - _PROBEREQ_IE_OFFSET_ , wps_ie, wps_ielen); break; } } return wps; }
static void update_bcn_wps_ie(struct adapter *padapter) { u8 *pwps_ie = NULL, *pwps_ie_src; u8 *premainder_ie, *pbackup_remainder_ie = NULL; uint wps_ielen = 0, wps_offset, remainder_ielen; struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; struct wlan_bssid_ex *pnetwork = &pmlmeinfo->network; unsigned char *ie = pnetwork->ies; u32 ielen = pnetwork->ie_length; DBG_88E("%s\n", __func__); pwps_ie_src = pmlmepriv->wps_beacon_ie; if (!pwps_ie_src) return; pwps_ie = rtw_get_wps_ie(ie + _FIXED_IE_LENGTH_, ielen - _FIXED_IE_LENGTH_, NULL, &wps_ielen); if (!pwps_ie || wps_ielen == 0) return; wps_offset = (uint)(pwps_ie - ie); premainder_ie = pwps_ie + wps_ielen; remainder_ielen = ielen - wps_offset - wps_ielen; if (remainder_ielen > 0) { pbackup_remainder_ie = rtw_malloc(remainder_ielen); if (pbackup_remainder_ie) memcpy(pbackup_remainder_ie, premainder_ie, remainder_ielen); } wps_ielen = (uint)pwps_ie_src[1];/* to get ie data len */ if (wps_offset + wps_ielen + 2 + remainder_ielen <= MAX_IE_SZ) { memcpy(pwps_ie, pwps_ie_src, wps_ielen + 2); pwps_ie += wps_ielen + 2; if (pbackup_remainder_ie) memcpy(pwps_ie, pbackup_remainder_ie, remainder_ielen); /* update ie_length */ pnetwork->ie_length = wps_offset + wps_ielen + 2 + remainder_ielen; } kfree(pbackup_remainder_ie); }
void dump_wps_ie(u8 *ie, u32 ie_len) { u8 *pos = (u8 *)ie; u16 id; u16 len; u8 *wps_ie; uint wps_ielen; wps_ie = rtw_get_wps_ie(ie, ie_len, NULL, &wps_ielen); if (wps_ie != ie || wps_ielen == 0) return; pos += 6; while (pos-ie < ie_len) { id = get_unaligned_be16(pos); len = get_unaligned_be16(pos + 2); DBG_88E("%s ID:0x%04x, LEN:%u\n", __func__, id, len); pos += (4+len); } }
void dump_wps_ie(u8 *ie, u32 ie_len) { u8* pos = (u8*)ie; u16 id; u16 len; u8 *wps_ie; uint wps_ielen; wps_ie = rtw_get_wps_ie(ie, ie_len, NULL, &wps_ielen); if(wps_ie != ie || wps_ielen == 0) return; pos+=6; while(pos-ie < ie_len){ id = RTW_GET_BE16(pos); len = RTW_GET_BE16(pos + 2); DBG_871X("%s ID:0x%04x, LEN:%u\n", __FUNCTION__, id, len); pos+=(4+len); } }
static void start_bss_network(struct adapter *padapter, u8 *pbuf) { u8 *p; u8 val8, cur_channel, cur_bwmode, cur_ch_offset; u16 bcn_interval; u32 acparm; uint ie_len; struct registry_priv *pregpriv = &padapter->registrypriv; struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct security_priv *psecuritypriv = &padapter->securitypriv; struct wlan_bssid_ex *pnetwork = (struct wlan_bssid_ex *)&pmlmepriv->cur_network.network; struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; struct wlan_bssid_ex *pnetwork_mlmeext = &pmlmeinfo->network; struct HT_info_element *pht_info = NULL; bcn_interval = (u16)pnetwork->Configuration.BeaconPeriod; cur_channel = pnetwork->Configuration.DSConfig; cur_bwmode = HT_CHANNEL_WIDTH_20; cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; /* check if there is wps ie, * if there is wpsie in beacon, the hostapd will update * beacon twice when stating hostapd, and at first time the * security ie (RSN/WPA IE) will not include in beacon. */ if (!rtw_get_wps_ie(pnetwork->ies + _FIXED_IE_LENGTH_, pnetwork->ie_length - _FIXED_IE_LENGTH_, NULL, NULL)) pmlmeext->bstart_bss = true; /* todo: update wmm, ht cap */ if (pmlmepriv->qospriv.qos_option) pmlmeinfo->WMM_enable = true; if (pmlmepriv->htpriv.ht_option) { pmlmeinfo->WMM_enable = true; pmlmeinfo->HT_enable = true; update_hw_ht_param(padapter); } /* setting only at first time */ if (pmlmepriv->cur_network.join_res != true) { /* WEP Key will be set before this function, do not * clear CAM. */ if ((psecuritypriv->dot11PrivacyAlgrthm != _WEP40_) && (psecuritypriv->dot11PrivacyAlgrthm != _WEP104_)) flush_all_cam_entry(padapter); /* clear CAM */ } /* set MSR to AP_Mode */ Set_MSR(padapter, _HW_STATE_AP_); /* Set BSSID REG */ rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, pnetwork->MacAddress); /* Set EDCA param reg */ acparm = 0x002F3217; /* VO */ rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VO, (u8 *)(&acparm)); acparm = 0x005E4317; /* VI */ rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VI, (u8 *)(&acparm)); acparm = 0x005ea42b; rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BE, (u8 *)(&acparm)); acparm = 0x0000A444; /* BK */ rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BK, (u8 *)(&acparm)); /* Set Security */ val8 = (psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) ? 0xcc : 0xcf; rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8)); /* Beacon Control related register */ rtw_hal_set_hwreg(padapter, HW_VAR_BEACON_INTERVAL, (u8 *)(&bcn_interval)); UpdateBrateTbl(padapter, pnetwork->SupportedRates); rtw_hal_set_hwreg(padapter, HW_VAR_BASIC_RATE, pnetwork->SupportedRates); if (!pmlmepriv->cur_network.join_res) { /* setting only at first time */ /* turn on all dynamic functions */ Switch_DM_Func(padapter, DYNAMIC_ALL_FUNC_ENABLE, true); } /* set channel, bwmode */ p = rtw_get_ie((pnetwork->ies + sizeof(struct ndis_802_11_fixed_ie)), _HT_ADD_INFO_IE_, &ie_len, (pnetwork->ie_length - sizeof(struct ndis_802_11_fixed_ie))); if (p && ie_len) { pht_info = (struct HT_info_element *)(p + 2); if ((pregpriv->cbw40_enable) && (pht_info->infos[0] & BIT(2))) { /* switch to the 40M Hz mode */ cur_bwmode = HT_CHANNEL_WIDTH_40; switch (pht_info->infos[0] & 0x3) { case 1: cur_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER; break; case 3: cur_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER; break; default: cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; break; } } } /* TODO: need to judge the phy parameters on concurrent * mode for single phy */ set_channel_bwmode(padapter, cur_channel, cur_ch_offset, cur_bwmode); DBG_88E("CH =%d, BW =%d, offset =%d\n", cur_channel, cur_bwmode, cur_ch_offset); /* */ pmlmeext->cur_channel = cur_channel; pmlmeext->cur_bwmode = cur_bwmode; pmlmeext->cur_ch_offset = cur_ch_offset; pmlmeext->cur_wireless_mode = pmlmepriv->cur_network.network_type; /* update cur_wireless_mode */ update_wireless_mode(padapter); /* update capability after cur_wireless_mode updated */ update_capinfo(padapter, rtw_get_capability((struct wlan_bssid_ex *)pnetwork)); /* let pnetwork_mlmeext == pnetwork_mlme. */ memcpy(pnetwork_mlmeext, pnetwork, pnetwork->Length); if (pmlmeext->bstart_bss) { update_beacon(padapter, _TIM_IE_, NULL, false); /* issue beacon frame */ if (send_beacon(padapter) == _FAIL) DBG_88E("send_beacon, fail!\n"); } /* update bc/mc sta_info */ update_bmc_sta(padapter); }