| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470 |
- /******************************************************************************
- *
- * Copyright(c) 2007 - 2017 Realtek Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- *****************************************************************************/
- #include <drv_types.h>
- #include <hal_data.h>
- #include "rtw_rm_fsm.h"
- #define pstr(s) s+strlen(s)
- u8 rm_post_event_hdl(_adapter *padapter, u8 *pbuf)
- {
- #ifdef CONFIG_RTW_80211K
- struct rm_event *pev = (struct rm_event *)pbuf;
- _rm_post_event(padapter, pev->rmid, pev->evid);
- rm_handler(padapter, pev);
- #endif
- return H2C_SUCCESS;
- }
- #ifdef CONFIG_RTW_80211K
- /* 802.11-2012 Table E-1 Operationg classes in United States */
- static RT_OPERATING_CLASS RTW_OP_CLASS_US[] = {
- /* 0, OP_CLASS_NULL */ { 0, 0, {}},
- /* 1, OP_CLASS_1 */ {115, 4, {36, 40, 44, 48}},
- /* 2, OP_CLASS_2 */ {118, 4, {52, 56, 60, 64}},
- /* 3, OP_CLASS_3 */ {124, 4, {149, 153, 157, 161}},
- /* 4, OP_CLASS_4 */ {121, 11, {100, 104, 108, 112, 116, 120, 124,
- 128, 132, 136, 140}},
- /* 5, OP_CLASS_5 */ {125, 5, {149, 153, 157, 161, 165}},
- /* 6, OP_CLASS_12 */ { 81, 11, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}}
- };
- struct cmd_meas_type_ {
- u8 id;
- char *name;
- };
- char *rm_type_req_name(u8 meas_type) {
- switch (meas_type) {
- case basic_req:
- return "basic_req";
- case cca_req:
- return "cca_req";
- case rpi_histo_req:
- return "rpi_histo_req";
- case ch_load_req:
- return "ch_load_req";
- case noise_histo_req:
- return "noise_histo_req";
- case bcn_req:
- return "bcn_req";
- case frame_req:
- return "frame_req";
- case sta_statis_req:
- return "sta_statis_req";
- }
- return "unknown_req";
- };
- char *rm_type_rep_name(u8 meas_type) {
- switch (meas_type) {
- case basic_rep:
- return "basic_rep";
- case cca_rep:
- return "cca_rep";
- case rpi_histo_rep:
- return "rpi_histo_rep";
- case ch_load_rep:
- return "ch_load_rep";
- case noise_histo_rep:
- return "noise_histo_rep";
- case bcn_rep:
- return "bcn_rep";
- case frame_rep:
- return "frame_rep";
- case sta_statis_rep:
- return "sta_statis_rep";
- }
- return "unknown_rep";
- };
- char *rm_en_cap_name(enum rm_cap_en en)
- {
- switch (en) {
- case RM_LINK_MEAS_CAP_EN:
- return "RM_LINK_MEAS_CAP_EN";
- case RM_NB_REP_CAP_EN:
- return "RM_NB_REP_CAP_EN";
- case RM_PARAL_MEAS_CAP_EN:
- return "RM_PARAL_MEAS_CAP_EN";
- case RM_REPEAT_MEAS_CAP_EN:
- return "RM_REPEAT_MEAS_CAP_EN";
- case RM_BCN_PASSIVE_MEAS_CAP_EN:
- return "RM_BCN_PASSIVE_MEAS_CAP_EN";
- case RM_BCN_ACTIVE_MEAS_CAP_EN:
- return "RM_BCN_ACTIVE_MEAS_CAP_EN";
- case RM_BCN_TABLE_MEAS_CAP_EN:
- return "RM_BCN_TABLE_MEAS_CAP_EN";
- case RM_BCN_MEAS_REP_COND_CAP_EN:
- return "RM_BCN_MEAS_REP_COND_CAP_EN";
- case RM_FRAME_MEAS_CAP_EN:
- return "RM_FRAME_MEAS_CAP_EN";
- case RM_CH_LOAD_CAP_EN:
- return "RM_CH_LOAD_CAP_EN";
- case RM_NOISE_HISTO_CAP_EN:
- return "RM_NOISE_HISTO_CAP_EN";
- case RM_STATIS_MEAS_CAP_EN:
- return "RM_STATIS_MEAS_CAP_EN";
- case RM_LCI_MEAS_CAP_EN:
- return "RM_LCI_MEAS_CAP_EN";
- case RM_LCI_AMIMUTH_CAP_EN:
- return "RM_LCI_AMIMUTH_CAP_EN";
- case RM_TRANS_STREAM_CAT_MEAS_CAP_EN:
- return "RM_TRANS_STREAM_CAT_MEAS_CAP_EN";
- case RM_TRIG_TRANS_STREAM_CAT_MEAS_CAP_EN:
- return "RM_TRIG_TRANS_STREAM_CAT_MEAS_CAP_EN";
- case RM_AP_CH_REP_CAP_EN:
- return "RM_AP_CH_REP_CAP_EN";
- case RM_RM_MIB_CAP_EN:
- return "RM_RM_MIB_CAP_EN";
- case RM_OP_CH_MAX_MEAS_DUR0:
- return "RM_OP_CH_MAX_MEAS_DUR0";
- case RM_OP_CH_MAX_MEAS_DUR1:
- return "RM_OP_CH_MAX_MEAS_DUR1";
- case RM_OP_CH_MAX_MEAS_DUR2:
- return "RM_OP_CH_MAX_MEAS_DUR2";
- case RM_NONOP_CH_MAX_MEAS_DUR0:
- return "RM_NONOP_CH_MAX_MEAS_DUR0";
- case RM_NONOP_CH_MAX_MEAS_DUR1:
- return "RM_NONOP_CH_MAX_MEAS_DUR1";
- case RM_NONOP_CH_MAX_MEAS_DUR2:
- return "RM_NONOP_CH_MAX_MEAS_DUR2";
- case RM_MEAS_PILOT_CAP0:
- return "RM_MEAS_PILOT_CAP0"; /* 24-26 */
- case RM_MEAS_PILOT_CAP1:
- return "RM_MEAS_PILOT_CAP1";
- case RM_MEAS_PILOT_CAP2:
- return "RM_MEAS_PILOT_CAP2";
- case RM_MEAS_PILOT_TRANS_INFO_CAP_EN:
- return "RM_MEAS_PILOT_TRANS_INFO_CAP_EN";
- case RM_NB_REP_TSF_OFFSET_CAP_EN:
- return "RM_NB_REP_TSF_OFFSET_CAP_EN";
- case RM_RCPI_MEAS_CAP_EN:
- return "RM_RCPI_MEAS_CAP_EN"; /* 29 */
- case RM_RSNI_MEAS_CAP_EN:
- return "RM_RSNI_MEAS_CAP_EN";
- case RM_BSS_AVG_ACCESS_DELAY_CAP_EN:
- return "RM_BSS_AVG_ACCESS_DELAY_CAP_EN";
- case RM_AVALB_ADMIS_CAPACITY_CAP_EN:
- return "RM_AVALB_ADMIS_CAPACITY_CAP_EN";
- case RM_ANT_CAP_EN:
- return "RM_ANT_CAP_EN";
- case RM_RSVD:
- case RM_MAX:
- default:
- break;
- }
- return "unknown";
- }
- int rm_en_cap_chk_and_set(struct rm_obj *prm, enum rm_cap_en en)
- {
- int idx;
- u8 cap;
- if (en >= RM_MAX)
- return _FALSE;
- idx = en / 8;
- cap = prm->psta->padapter->rmpriv.rm_en_cap_def[idx];
- if (!(cap & BIT(en - (idx*8)))) {
- RTW_INFO("RM: %s incapable\n",rm_en_cap_name(en));
- rm_set_rep_mode(prm, MEAS_REP_MOD_INCAP);
- return _FALSE;
- }
- return _SUCCESS;
- }
- static u8 rm_get_oper_class_via_ch(u8 ch)
- {
- int i,j,sz;
- sz = sizeof(RTW_OP_CLASS_US)/sizeof(struct _RT_OPERATING_CLASS);
- for (i = 0; i < sz; i++) {
- for (j = 0; j < RTW_OP_CLASS_US[i].Len; j++) {
- if ( ch == RTW_OP_CLASS_US[i].Channel[j]) {
- RTW_INFO("RM: ch %u in oper_calss %u\n",
- ch, RTW_OP_CLASS_US[i].global_op_class);
- return RTW_OP_CLASS_US[i].global_op_class;
- break;
- }
- }
- }
- return 0;
- }
- static u8 rm_get_ch_set(
- struct rtw_ieee80211_channel *pch_set, u8 op_class, u8 ch_num)
- {
- int i,j,sz;
- u8 ch_amount = 0;
- sz = sizeof(RTW_OP_CLASS_US)/sizeof(struct _RT_OPERATING_CLASS);
- if (ch_num != 0) {
- pch_set[0].hw_value = ch_num;
- ch_amount = 1;
- RTW_INFO("RM: meas_ch->hw_value = %u\n", pch_set->hw_value);
- goto done;
- }
- for (i = 0; i < sz; i++) {
- if (RTW_OP_CLASS_US[i].global_op_class == op_class) {
- for (j = 0; j < RTW_OP_CLASS_US[i].Len; j++) {
- pch_set[j].hw_value =
- RTW_OP_CLASS_US[i].Channel[j];
- RTW_INFO("RM: meas_ch[%d].hw_value = %u\n",
- j, pch_set[j].hw_value);
- }
- ch_amount = RTW_OP_CLASS_US[i].Len;
- break;
- }
- }
- done:
- return ch_amount;
- }
- static int is_wildcard_bssid(u8 *bssid)
- {
- int i;
- u8 val8 = 0xff;
- for (i=0;i<6;i++)
- val8 &= bssid[i];
- if (val8 == 0xff)
- return _SUCCESS;
- return _FALSE;
- }
- /* for caller outside rm */
- u8 rm_add_nb_req(_adapter *padapter, struct sta_info *psta)
- {
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
- struct rm_obj *prm;
- prm = rm_alloc_rmobj(padapter);
- if (prm == NULL) {
- RTW_ERR("RM: unable to alloc rm obj for requeset\n");
- return _FALSE;
- }
- prm->psta = psta;
- prm->q.category = RTW_WLAN_CATEGORY_RADIO_MEAS;
- prm->q.diag_token = pmlmeinfo->dialogToken++;
- prm->q.m_token = 1;
- prm->rmid = psta->cmn.aid << 16
- | prm->q.diag_token << 8
- | RM_MASTER;
- prm->q.action_code = RM_ACT_NB_REP_REQ;
- #if 0
- if (pmac) { /* find sta_info according to bssid */
- pmac += 4; /* skip mac= */
- if (hwaddr_parse(pmac, bssid) == NULL) {
- sprintf(pstr(s), "Err: \nincorrect mac format\n");
- return _FAIL;
- }
- psta = rm_get_sta(padapter, 0xff, bssid);
- }
- #endif
- /* enquee rmobj */
- rm_enqueue_rmobj(padapter, prm, _FALSE);
- RTW_INFO("RM: rmid=%x add req to " MAC_FMT "\n",
- prm->rmid, MAC_ARG(psta->cmn.mac_addr));
- return _SUCCESS;
- }
- static u8 *build_wlan_hdr(_adapter *padapter, struct xmit_frame *pmgntframe,
- struct sta_info *psta, u16 frame_type)
- {
- u8 *pframe;
- u16 *fctrl;
- struct pkt_attrib *pattr;
- struct rtw_ieee80211_hdr *pwlanhdr;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
- /* update attribute */
- pattr = &pmgntframe->attrib;
- update_mgntframe_attrib(padapter, pattr);
- _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
- pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
- pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
- fctrl = &(pwlanhdr->frame_ctl);
- *(fctrl) = 0;
- _rtw_memcpy(pwlanhdr->addr1, psta->cmn.mac_addr, ETH_ALEN);
- _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
- _rtw_memcpy(pwlanhdr->addr3,
- get_my_bssid(&(pmlmeinfo->network)),ETH_ALEN);
- RTW_INFO("RM: dst = " MAC_FMT "\n", MAC_ARG(pwlanhdr->addr1));
- SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
- pmlmeext->mgnt_seq++;
- SetFragNum(pframe, 0);
- set_frame_sub_type(pframe, WIFI_ACTION);
- pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
- pattr->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
- return pframe;
- }
- void rm_set_rep_mode(struct rm_obj *prm, u8 mode)
- {
- RTW_INFO("RM: rmid=%x set %s\n",
- prm->rmid,
- mode|MEAS_REP_MOD_INCAP?"INCAP":
- mode|MEAS_REP_MOD_REFUSE?"REFUSE":
- mode|MEAS_REP_MOD_LATE?"LATE":"");
- prm->p.m_mode |= mode;
- }
- int issue_null_reply(struct rm_obj *prm)
- {
- int len=0, my_len;
- u8 *pframe, m_mode;
- _adapter *padapter = prm->psta->padapter;
- struct pkt_attrib *pattr;
- struct xmit_frame *pmgntframe;
- struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
- m_mode = prm->p.m_mode;
- if (m_mode || prm->p.rpt == 0) {
- RTW_INFO("RM: rmid=%x reply (%s repeat=%d)\n",
- prm->rmid,
- m_mode&MEAS_REP_MOD_INCAP?"INCAP":
- m_mode&MEAS_REP_MOD_REFUSE?"REFUSE":
- m_mode&MEAS_REP_MOD_LATE?"LATE":"no content",
- prm->p.rpt);
- }
- switch (prm->p.action_code) {
- case RM_ACT_RADIO_MEAS_REQ:
- len = 8;
- break;
- case RM_ACT_NB_REP_REQ:
- len = 3;
- break;
- case RM_ACT_LINK_MEAS_REQ:
- len = 3;
- break;
- default:
- break;
- }
- if (len==0)
- return _FALSE;
- pmgntframe = alloc_mgtxmitframe(pxmitpriv);
- if (pmgntframe == NULL) {
- RTW_ERR("RM: %s alloc xmit_frame fail\n",__func__);
- return _FALSE;
- }
- pattr = &pmgntframe->attrib;
- pframe = build_wlan_hdr(padapter, pmgntframe, prm->psta, WIFI_ACTION);
- pframe = rtw_set_fixed_ie(pframe, 3, &prm->p.category, &pattr->pktlen);
- my_len = 0;
- if (len>5) {
- prm->p.len = len - 3 - 2;
- pframe = rtw_set_fixed_ie(pframe, len - 3,
- &prm->p.e_id, &my_len);
- }
- pattr->pktlen += my_len;
- pattr->last_txcmdsz = pattr->pktlen;
- dump_mgntframe(padapter, pmgntframe);
- return _SUCCESS;
- }
- int ready_for_scan(struct rm_obj *prm)
- {
- _adapter *padapter = prm->psta->padapter;
- u8 ssc_chk;
- if (!rtw_is_adapter_up(padapter))
- return _FALSE;
- ssc_chk = rtw_sitesurvey_condition_check(padapter, _FALSE);
- if (ssc_chk == SS_ALLOW)
- return _SUCCESS;
- return _FALSE;
- }
- int rm_sitesurvey(struct rm_obj *prm)
- {
- int meas_ch_num=0;
- u8 ch_num=0, op_class=0, val8;
- struct rtw_ieee80211_channel *pch_set;
- struct sitesurvey_parm parm;
- RTW_INFO("RM: rmid=%x %s\n",prm->rmid, __func__);
- pch_set = &prm->q.ch_set[0];
- _rtw_memset(pch_set, 0,
- sizeof(struct rtw_ieee80211_channel) * MAX_OP_CHANNEL_SET_NUM);
- if (prm->q.ch_num == 0) {
- /* ch_num=0 : scan all ch in operating class */
- op_class = prm->q.op_class;
- } else if (prm->q.ch_num == 255) {
- /* 802.11 p.499 */
- /* ch_num=255 : scan all ch in current operating class */
- op_class = rm_get_oper_class_via_ch(
- (u8)prm->psta->padapter->mlmeextpriv.cur_channel);
- } else
- ch_num = prm->q.ch_num;
- /* get means channel */
- meas_ch_num = rm_get_ch_set(pch_set, op_class, ch_num);
- prm->q.ch_set_ch_amount = meas_ch_num;
- _rtw_memset(&parm, 0, sizeof(struct sitesurvey_parm));
- _rtw_memcpy(parm.ch, pch_set,
- sizeof(struct rtw_ieee80211_channel) * MAX_OP_CHANNEL_SET_NUM);
- _rtw_memcpy(&parm.ssid[0], &prm->q.opt.bcn.ssid, IW_ESSID_MAX_SIZE);
- parm.ssid_num = 1;
- parm.scan_mode = prm->q.m_mode;
- parm.ch_num = meas_ch_num;
- parm.igi = 0;
- parm.token = prm->rmid;
- parm.duration = prm->q.meas_dur;
- /* parm.bw = BW_20M; */
- rtw_sitesurvey_cmd(prm->psta->padapter, &parm);
- return _SUCCESS;
- }
- static u8 translate_percentage_to_rcpi(u32 SignalStrengthIndex)
- {
- s32 SignalPower; /* in dBm. */
- u8 rcpi;
- /* Translate to dBm (x=y-100) */
- SignalPower = SignalStrengthIndex - 100;
- /* RCPI = Int{(Power in dBm + 110)*2} for 0dBm > Power > -110dBm
- * 0 : power <= -110.0 dBm
- * 1 : power = -109.5 dBm
- * 2 : power = -109.0 dBm
- */
- rcpi = (SignalPower + 110)*2;
- return rcpi;
- }
- static int rm_parse_ch_load_s_elem(struct rm_obj *prm, u8 *pbody, int req_len)
- {
- u8 *popt_id;
- int i, p=0; /* position */
- int len = req_len;
- prm->q.opt_s_elem_len = len;
- #if (RM_MORE_DBG_MSG)
- RTW_INFO("RM: opt_s_elem_len=%d\n", len);
- #endif
- while (len) {
- switch (pbody[p]) {
- case ch_load_rep_info:
- /* check RM_EN */
- rm_en_cap_chk_and_set(prm, RM_CH_LOAD_CAP_EN);
- _rtw_memcpy(&(prm->q.opt.clm.rep_cond),
- &pbody[p+2], sizeof(prm->q.opt.clm.rep_cond));
- RTW_INFO("RM: ch_load_rep_info=%u:%u\n",
- prm->q.opt.clm.rep_cond.cond,
- prm->q.opt.clm.rep_cond.threshold);
- break;
- default:
- break;
- }
- len = len - (int)pbody[p+1] - 2;
- p = p + (int)pbody[p+1] + 2;
- #if (RM_MORE_DBG_MSG)
- RTW_INFO("RM: opt_s_elem_len=%d\n",len);
- #endif
- }
- return _SUCCESS;
- }
- static int rm_parse_noise_histo_s_elem(struct rm_obj *prm,
- u8 *pbody, int req_len)
- {
- u8 *popt_id;
- int i, p=0; /* position */
- int len = req_len;
- prm->q.opt_s_elem_len = len;
- #if (RM_MORE_DBG_MSG)
- RTW_INFO("RM: opt_s_elem_len=%d\n", len);
- #endif
- while (len) {
- switch (pbody[p]) {
- case noise_histo_rep_info:
- /* check RM_EN */
- rm_en_cap_chk_and_set(prm, RM_NOISE_HISTO_CAP_EN);
- _rtw_memcpy(&(prm->q.opt.nhm.rep_cond),
- &pbody[p+2], sizeof(prm->q.opt.nhm.rep_cond));
- RTW_INFO("RM: noise_histo_rep_info=%u:%u\n",
- prm->q.opt.nhm.rep_cond.cond,
- prm->q.opt.nhm.rep_cond.threshold);
- break;
- default:
- break;
- }
- len = len - (int)pbody[p+1] - 2;
- p = p + (int)pbody[p+1] + 2;
- #if (RM_MORE_DBG_MSG)
- RTW_INFO("RM: opt_s_elem_len=%d\n",len);
- #endif
- }
- return _SUCCESS;
- }
- static int rm_parse_bcn_req_s_elem(struct rm_obj *prm, u8 *pbody, int req_len)
- {
- u8 *popt_id;
- int i, p=0; /* position */
- int len = req_len;
- /* opt length,2:pbody[0]+ pbody[1] */
- /* first opt id : pbody[18] */
- prm->q.opt_s_elem_len = len;
- #if (RM_MORE_DBG_MSG)
- RTW_INFO("RM: opt_s_elem_len=%d\n", len);
- #endif
- popt_id = prm->q.opt.bcn.opt_id;
- while (len && prm->q.opt.bcn.opt_id_num < BCN_REQ_OPT_MAX_NUM) {
- switch (pbody[p]) {
- case bcn_req_ssid:
- RTW_INFO("bcn_req_ssid\n");
- #if (DBG_BCN_REQ_WILDCARD)
- RTW_INFO("DBG set ssid to WILDCARD\n");
- #else
- #if (DBG_BCN_REQ_SSID)
- RTW_INFO("DBG set ssid to %s\n",DBG_BCN_REQ_SSID_NAME);
- i = strlen(DBG_BCN_REQ_SSID_NAME);
- prm->q.opt.bcn.ssid.SsidLength = i;
- _rtw_memcpy(&(prm->q.opt.bcn.ssid.Ssid),
- DBG_BCN_REQ_SSID_NAME, i);
- #else /* original */
- prm->q.opt.bcn.ssid.SsidLength = pbody[p+1];
- _rtw_memcpy(&(prm->q.opt.bcn.ssid.Ssid),
- &pbody[p+2], pbody[p+1]);
- #endif
- #endif
- RTW_INFO("RM: bcn_req_ssid=%s\n",
- prm->q.opt.bcn.ssid.Ssid);
- popt_id[prm->q.opt.bcn.opt_id_num++] = pbody[p];
- break;
- case bcn_req_rep_info:
- /* check RM_EN */
- rm_en_cap_chk_and_set(prm, RM_BCN_MEAS_REP_COND_CAP_EN);
- _rtw_memcpy(&(prm->q.opt.bcn.rep_cond),
- &pbody[p+2], sizeof(prm->q.opt.bcn.rep_cond));
- RTW_INFO("bcn_req_rep_info=%u:%u\n",
- prm->q.opt.bcn.rep_cond.cond,
- prm->q.opt.bcn.rep_cond.threshold);
- /*popt_id[prm->q.opt.bcn.opt_id_num++] = pbody[p];*/
- break;
- case bcn_req_rep_detail:
- #if DBG_BCN_REQ_DETAIL
- prm->q.opt.bcn.rep_detail = 2; /* all IE in beacon */
- #else
- prm->q.opt.bcn.rep_detail = pbody[p+2];
- #endif
- popt_id[prm->q.opt.bcn.opt_id_num++] = pbody[p];
- #if (RM_MORE_DBG_MSG)
- RTW_INFO("RM: report_detail=%d\n",
- prm->q.opt.bcn.rep_detail);
- #endif
- break;
- case bcn_req_req:
- RTW_INFO("RM: bcn_req_req\n");
- prm->q.opt.bcn.req_start = rtw_malloc(pbody[p+1]);
- if (prm->q.opt.bcn.req_start == NULL) {
- RTW_ERR("RM: req_start malloc fail!!\n");
- break;
- }
- for (i = 0; i < pbody[p+1]; i++)
- *((prm->q.opt.bcn.req_start)+i) =
- pbody[p+2+i];
- prm->q.opt.bcn.req_len = pbody[p+1];
- popt_id[prm->q.opt.bcn.opt_id_num++] = pbody[p];
- break;
- case bcn_req_ac_ch_rep:
- #if (RM_MORE_DBG_MSG)
- RTW_INFO("RM: bcn_req_ac_ch_rep\n");
- #endif
- popt_id[prm->q.opt.bcn.opt_id_num++] = pbody[p];
- break;
- default:
- break;
- }
- len = len - (int)pbody[p+1] - 2;
- p = p + (int)pbody[p+1] + 2;
- #if (RM_MORE_DBG_MSG)
- RTW_INFO("RM: opt_s_elem_len=%d\n",len);
- #endif
- }
- return _SUCCESS;
- }
- static int rm_parse_meas_req(struct rm_obj *prm, u8 *pbody)
- {
- int p; /* position */
- int req_len;
- req_len = (int)pbody[1];
- p = 5;
- prm->q.op_class = pbody[p++];
- prm->q.ch_num = pbody[p++];
- prm->q.rand_intvl = le16_to_cpu(*(u16*)(&pbody[p]));
- p+=2;
- prm->q.meas_dur = le16_to_cpu(*(u16*)(&pbody[p]));
- p+=2;
- if (prm->q.m_type == bcn_req) {
- /*
- * 0: passive
- * 1: active
- * 2: bcn_table
- */
- prm->q.m_mode = pbody[p++];
- /* BSSID */
- _rtw_memcpy(&(prm->q.bssid), &pbody[p], 6);
- p+=6;
- /*
- * default, used when Reporting detail subelement
- * is not included in Beacon Request
- */
- prm->q.opt.bcn.rep_detail = 2;
- }
- if (req_len-(p-2) <= 0) /* without sub-element */
- return _SUCCESS;
- switch (prm->q.m_type) {
- case bcn_req:
- rm_parse_bcn_req_s_elem(prm, &pbody[p], req_len-(p-2));
- break;
- case ch_load_req:
- rm_parse_ch_load_s_elem(prm, &pbody[p], req_len-(p-2));
- break;
- case noise_histo_req:
- rm_parse_noise_histo_s_elem(prm, &pbody[p], req_len-(p-2));
- break;
- default:
- break;
- }
- return _SUCCESS;
- }
- /* receive measurement request */
- int rm_recv_radio_mens_req(_adapter *padapter,
- union recv_frame *precv_frame, struct sta_info *psta)
- {
- struct rm_obj *prm;
- struct rm_priv *prmpriv = &padapter->rmpriv;
- u8 *pdiag_body = (u8 *)(precv_frame->u.hdr.rx_data +
- sizeof(struct rtw_ieee80211_hdr_3addr));
- u8 *pmeas_body = &pdiag_body[5];
- u8 rmid, update = 0;
- #if 0
- /* search existing rm_obj */
- rmid = psta->cmn.aid << 16
- | pdiag_body[2] << 8
- | RM_SLAVE;
- prm = rm_get_rmobj(padapter, rmid);
- if (prm) {
- RTW_INFO("RM: Found an exist meas rmid=%u\n", rmid);
- update = 1;
- } else
- #endif
- prm = rm_alloc_rmobj(padapter);
- if (prm == NULL) {
- RTW_ERR("RM: unable to alloc rm obj for requeset\n");
- return _FALSE;
- }
- prm->psta = psta;
- prm->q.diag_token = pdiag_body[2];
- prm->q.rpt = le16_to_cpu(*(u16*)(&pdiag_body[3]));
- /* Figure 8-104 Measurement Requested format */
- prm->q.e_id = pmeas_body[0];
- prm->q.m_token = pmeas_body[2];
- prm->q.m_mode = pmeas_body[3];
- prm->q.m_type = pmeas_body[4];
- prm->rmid = psta->cmn.aid << 16
- | prm->q.diag_token << 8
- | RM_SLAVE;
- RTW_INFO("RM: rmid=%x, bssid " MAC_FMT "\n", prm->rmid,
- MAC_ARG(prm->psta->cmn.mac_addr));
- #if (RM_MORE_DBG_MSG)
- RTW_INFO("RM: element_id = %d\n", prm->q.e_id);
- RTW_INFO("RM: length = %d\n", (int)pmeas_body[1]);
- RTW_INFO("RM: meas_token = %d\n", prm->q.m_token);
- RTW_INFO("RM: meas_mode = %d\n", prm->q.m_mode);
- RTW_INFO("RM: meas_type = %d\n", prm->q.m_type);
- #endif
- if (prm->q.e_id != _MEAS_REQ_IE_) /* 38 */
- return _FALSE;
- switch (prm->q.m_type) {
- case bcn_req:
- RTW_INFO("RM: recv beacon_request\n");
- switch (prm->q.m_mode) {
- case bcn_req_passive:
- rm_en_cap_chk_and_set(prm, RM_BCN_PASSIVE_MEAS_CAP_EN);
- break;
- case bcn_req_active:
- rm_en_cap_chk_and_set(prm, RM_BCN_ACTIVE_MEAS_CAP_EN);
- break;
- case bcn_req_bcn_table:
- rm_en_cap_chk_and_set(prm, RM_BCN_TABLE_MEAS_CAP_EN);
- break;
- default:
- rm_set_rep_mode(prm, MEAS_REP_MOD_INCAP);
- break;
- }
- break;
- case ch_load_req:
- RTW_INFO("RM: recv ch_load_request\n");
- rm_en_cap_chk_and_set(prm, RM_CH_LOAD_CAP_EN);
- break;
- case noise_histo_req:
- RTW_INFO("RM: recv noise_histogram_request\n");
- rm_en_cap_chk_and_set(prm, RM_NOISE_HISTO_CAP_EN);
- break;
- default:
- RTW_INFO("RM: recv unknown request type 0x%02x\n",
- prm->q.m_type);
- rm_set_rep_mode(prm, MEAS_REP_MOD_INCAP);
- goto done;
- }
- rm_parse_meas_req(prm, pmeas_body);
- done:
- if (!update)
- rm_enqueue_rmobj(padapter, prm, _FALSE);
- return _SUCCESS;
- }
- /* receive measurement report */
- int rm_recv_radio_mens_rep(_adapter *padapter,
- union recv_frame *precv_frame, struct sta_info *psta)
- {
- int ret = _FALSE;
- struct rm_obj *prm;
- u32 rmid;
- u8 *pdiag_body = (u8 *)(precv_frame->u.hdr.rx_data +
- sizeof(struct rtw_ieee80211_hdr_3addr));
- u8 *pmeas_body = &pdiag_body[3];
- rmid = psta->cmn.aid << 16
- | pdiag_body[2] << 8
- | RM_MASTER;
- prm = rm_get_rmobj(padapter, rmid);
- if (prm == NULL)
- return _FALSE;
- prm->p.action_code = pdiag_body[1];
- prm->p.diag_token = pdiag_body[2];
- /* Figure 8-140 Measuremnt Report format */
- prm->p.e_id = pmeas_body[0];
- prm->p.m_token = pmeas_body[2];
- prm->p.m_mode = pmeas_body[3];
- prm->p.m_type = pmeas_body[4];
- RTW_INFO("RM: rmid=%x, bssid " MAC_FMT "\n", prm->rmid,
- MAC_ARG(prm->psta->cmn.mac_addr));
- #if (RM_MORE_DBG_MSG)
- RTW_INFO("RM: element_id = %d\n", prm->p.e_id);
- RTW_INFO("RM: length = %d\n", (int)pmeas_body[1]);
- RTW_INFO("RM: meas_token = %d\n", prm->p.m_token);
- RTW_INFO("RM: meas_mode = %d\n", prm->p.m_mode);
- RTW_INFO("RM: meas_type = %d\n", prm->p.m_type);
- #endif
- if (prm->p.e_id != _MEAS_RSP_IE_) /* 39 */
- return _FALSE;
- RTW_INFO("RM: recv %s\n", rm_type_rep_name(prm->p.m_type));
- rm_post_event(padapter, prm->rmid, RM_EV_recv_rep);
- return ret;
- }
- int rm_radio_mens_nb_rep(_adapter *padapter,
- union recv_frame *precv_frame, struct sta_info *psta)
- {
- u8 *pdiag_body = (u8 *)(precv_frame->u.hdr.rx_data +
- sizeof(struct rtw_ieee80211_hdr_3addr));
- u8 *pmeas_body = &pdiag_body[3];
- u32 len = precv_frame->u.hdr.len;
- u32 rmid;
- struct rm_obj *prm;
- rmid = psta->cmn.aid << 16
- | pdiag_body[2] << 8
- | RM_MASTER;
- prm = rm_get_rmobj(padapter, rmid);
- if (prm == NULL)
- return _FALSE;
- prm->p.action_code = pdiag_body[1];
- prm->p.diag_token = pdiag_body[2];
- prm->p.e_id = pmeas_body[0];
- RTW_INFO("RM: rmid=%x, bssid " MAC_FMT "\n", prm->rmid,
- MAC_ARG(prm->psta->cmn.mac_addr));
- #if (RM_MORE_DBG_MSG)
- RTW_INFO("RM: element_id = %d\n", prm->p.e_id);
- RTW_INFO("RM: length = %d\n", (int)pmeas_body[1]);
- #endif
- rm_post_event(padapter, prm->rmid, RM_EV_recv_rep);
- #ifdef CONFIG_LAYER2_ROAMING
- if (rtw_wnm_btm_candidates_survey(padapter
- ,(pdiag_body + 3)
- ,(len - sizeof(struct rtw_ieee80211_hdr_3addr))
- ,_FALSE) == _FAIL)
- return _FALSE;
- #endif
- rtw_cfg80211_rx_rrm_action(padapter, precv_frame);
- return _TRUE;
- }
- unsigned int rm_on_action(_adapter *padapter, union recv_frame *precv_frame)
- {
- u32 ret = _FAIL;
- u8 *pframe = NULL;
- u8 *pframe_body = NULL;
- u8 action_code = 0;
- u8 diag_token = 0;
- struct rtw_ieee80211_hdr_3addr *whdr;
- struct sta_info *psta;
- pframe = precv_frame->u.hdr.rx_data;
- /* check RA matches or not */
- if (!_rtw_memcmp(adapter_mac_addr(padapter),
- GetAddr1Ptr(pframe), ETH_ALEN))
- goto exit;
- whdr = (struct rtw_ieee80211_hdr_3addr *)pframe;
- RTW_INFO("RM: %s bssid = " MAC_FMT "\n",
- __func__, MAC_ARG(whdr->addr2));
- psta = rtw_get_stainfo(&padapter->stapriv, whdr->addr2);
- if (!psta) {
- RTW_ERR("RM: psta not found\n");
- goto exit;
- }
- pframe_body = (unsigned char *)(pframe +
- sizeof(struct rtw_ieee80211_hdr_3addr));
- /* Figure 8-438 radio measurement request frame Action field format */
- /* Category = pframe_body[0] = 5 (Radio Measurement) */
- action_code = pframe_body[1];
- diag_token = pframe_body[2];
- #if (RM_MORE_DBG_MSG)
- RTW_INFO("RM: %s radio_action=%x, diag_token=%x\n", __func__,
- action_code, diag_token);
- #endif
- switch (action_code) {
- case RM_ACT_RADIO_MEAS_REQ:
- RTW_INFO("RM: RM_ACT_RADIO_MEAS_REQ\n");
- ret = rm_recv_radio_mens_req(padapter, precv_frame, psta);
- break;
- case RM_ACT_RADIO_MEAS_REP:
- RTW_INFO("RM: RM_ACT_RADIO_MEAS_REP\n");
- ret = rm_recv_radio_mens_rep(padapter, precv_frame, psta);
- break;
- case RM_ACT_LINK_MEAS_REQ:
- RTW_INFO("RM: RM_ACT_LINK_MEAS_REQ\n");
- break;
- case RM_ACT_LINK_MEAS_REP:
- RTW_INFO("RM: RM_ACT_LINK_MEAS_REP\n");
- break;
- case RM_ACT_NB_REP_REQ:
- RTW_INFO("RM: RM_ACT_NB_REP_REQ\n");
- break;
- case RM_ACT_NB_REP_RESP:
- RTW_INFO("RM: RM_ACT_NB_REP_RESP\n");
- ret = rm_radio_mens_nb_rep(padapter, precv_frame, psta);
- break;
- default:
- /* TODO reply incabable */
- RTW_ERR("RM: unknown specturm management action %2x\n",
- action_code);
- break;
- }
- exit:
- return ret;
- }
- static u8 *rm_gen_bcn_detail_elem(_adapter *padapter, u8 *pframe,
- struct rm_obj *prm, struct wlan_network *pnetwork,
- unsigned int *fr_len)
- {
- WLAN_BSSID_EX *pbss = &pnetwork->network;
- unsigned int my_len;
- int j, k, len;
- u8 *plen;
- u8 *ptr;
- u8 val8, eid;
- my_len = 0;
- /* Reporting Detail values
- * 0: No fixed length fields or elements
- * 1: All fixed length fields and any requested elements
- * in the Request info element if present
- * 2: All fixed length fields and elements
- * 3-255: Reserved
- */
- /* report_detail = 0 */
- if (prm->q.opt.bcn.rep_detail == 0
- || prm->q.opt.bcn.rep_detail > 2) {
- return pframe;
- }
- /* ID */
- val8 = 1; /* 1:reported frame body */
- pframe = rtw_set_fixed_ie(pframe, 1, &val8, &my_len);
- plen = pframe;
- val8 = 0;
- pframe = rtw_set_fixed_ie(pframe, 1, &val8, &my_len);
- /* report_detail = 2 */
- if (prm->q.opt.bcn.rep_detail == 2) {
- pframe = rtw_set_fixed_ie(pframe, pbss->IELength - 4,
- pbss->IEs, &my_len); /* -4 remove FCS */
- goto done;
- }
- /* report_detail = 1 */
- /* all fixed lenght fields */
- pframe = rtw_set_fixed_ie(pframe,
- _FIXED_IE_LENGTH_, pbss->IEs, &my_len);
- for (j = 0; j < prm->q.opt.bcn.opt_id_num; j++) {
- switch (prm->q.opt.bcn.opt_id[j]) {
- case bcn_req_ssid:
- /* SSID */
- #if (RM_MORE_DBG_MSG)
- RTW_INFO("RM: bcn_req_ssid\n");
- #endif
- pframe = rtw_set_ie(pframe, _SSID_IE_,
- pbss->Ssid.SsidLength,
- pbss->Ssid.Ssid, &my_len);
- break;
- case bcn_req_req:
- if (prm->q.opt.bcn.req_start == NULL)
- break;
- #if (RM_MORE_DBG_MSG)
- RTW_INFO("RM: bcn_req_req");
- #endif
- for (k=0; k<prm->q.opt.bcn.req_len; k++) {
- eid = prm->q.opt.bcn.req_start[k];
- val8 = pbss->IELength - _FIXED_IE_LENGTH_;
- ptr = rtw_get_ie(pbss->IEs + _FIXED_IE_LENGTH_,
- eid, &len, val8);
- if (!ptr)
- continue;
- #if (RM_MORE_DBG_MSG)
- switch (eid) {
- case EID_QBSSLoad:
- RTW_INFO("RM: EID_QBSSLoad\n");
- break;
- case EID_HTCapability:
- RTW_INFO("RM: EID_HTCapability\n");
- break;
- case _MDIE_:
- RTW_INFO("RM: EID_MobilityDomain\n");
- break;
- default:
- RTW_INFO("RM: EID %d todo\n",eid);
- break;
- }
- #endif
- pframe = rtw_set_ie(pframe, eid,
- len,ptr+2, &my_len);
- } /* for() */
- break;
- case bcn_req_ac_ch_rep:
- default:
- RTW_INFO("RM: OPT %d TODO\n",prm->q.opt.bcn.opt_id[j]);
- break;
- }
- }
- done:
- /*
- * update my length
- * content length does NOT include ID and LEN
- */
- val8 = my_len - 2;
- rtw_set_fixed_ie(plen, 1, &val8, &j);
- /* update length to caller */
- *fr_len += my_len;
- return pframe;
- }
- static u8 rm_get_rcpi(struct rm_obj *prm, struct wlan_network *pnetwork)
- {
- return translate_percentage_to_rcpi(
- pnetwork->network.PhyInfo.SignalStrength);
- }
- static u8 rm_get_rsni(struct rm_obj *prm, struct wlan_network *pnetwork)
- {
- int i;
- u8 val8, snr;
- HAL_DATA_TYPE *pHalData = GET_HAL_DATA(prm->psta->padapter);
- if (pnetwork->network.PhyInfo.is_cck_rate) {
- /* current HW doesn't have CCK RSNI */
- /* 255 indicates RSNI is unavailable */
- val8 = 255;
- } else {
- snr = 0;
- for (i = 0; i < pHalData->NumTotalRFPath; i++) {
- snr += pnetwork->network.PhyInfo.rx_snr[i];
- }
- snr = snr / pHalData->NumTotalRFPath;
- val8 = (u8)(snr + 10)*2;
- }
- return val8;
- }
- u8 rm_bcn_req_cond_mach(struct rm_obj *prm, struct wlan_network *pnetwork)
- {
- u8 val8;
- switch(prm->q.opt.bcn.rep_cond.cond) {
- case bcn_rep_cond_immediately:
- return _SUCCESS;
- case bcn_req_cond_rcpi_greater:
- val8 = rm_get_rcpi(prm, pnetwork);
- if (val8 > prm->q.opt.bcn.rep_cond.threshold)
- return _SUCCESS;
- break;
- case bcn_req_cond_rcpi_less:
- val8 = rm_get_rcpi(prm, pnetwork);
- if (val8 < prm->q.opt.bcn.rep_cond.threshold)
- return _SUCCESS;
- break;
- case bcn_req_cond_rsni_greater:
- val8 = rm_get_rsni(prm, pnetwork);
- if (val8 != 255 && val8 > prm->q.opt.bcn.rep_cond.threshold)
- return _SUCCESS;
- break;
- case bcn_req_cond_rsni_less:
- val8 = rm_get_rsni(prm, pnetwork);
- if (val8 != 255 && val8 < prm->q.opt.bcn.rep_cond.threshold)
- return _SUCCESS;
- break;
- default:
- RTW_ERR("RM: bcn_req cond %u not support\n",
- prm->q.opt.bcn.rep_cond.cond);
- break;
- }
- return _FALSE;
- }
- static u8 *rm_bcn_rep_fill_scan_resule (struct rm_obj *prm,
- u8 *pframe, struct wlan_network *pnetwork, unsigned int *fr_len)
- {
- int snr, i;
- u8 val8, *plen;
- u16 val16;
- u32 val32;
- u64 val64;
- PWLAN_BSSID_EX pbss;
- unsigned int my_len;
- _adapter *padapter = prm->psta->padapter;
- my_len = 0;
- /* meas ID */
- val8 = EID_MeasureReport;
- pframe = rtw_set_fixed_ie(pframe, 1, &val8, &my_len);
- /* remember position form elelment length */
- plen = pframe;
- /* meas_rpt_len */
- /* default 3 = mode + token + type but no beacon content */
- val8 = 3;
- pframe = rtw_set_fixed_ie(pframe, 1, &val8, &my_len);
- /* meas_token */
- val8 = prm->q.m_token;
- pframe = rtw_set_fixed_ie(pframe, 1, &val8, &my_len);
- /* meas_rpt_mode F8-141 */
- val8 = prm->p.m_mode;
- pframe = rtw_set_fixed_ie(pframe, 1, &val8, &my_len);
- /* meas_type T8-81 */
- val8 = bcn_rep;
- pframe = rtw_set_fixed_ie(pframe, 1, &val8, &my_len);
- if (pnetwork == NULL)
- goto done;
- pframe = rtw_set_fixed_ie(pframe, 1, &prm->q.op_class, &my_len);
- /* channel */
- pbss = &pnetwork->network;
- val8 = pbss->Configuration.DSConfig;
- pframe = rtw_set_fixed_ie(pframe, 1, &val8, &my_len);
- /* Actual Measurement StartTime */
- val64 = cpu_to_le64(prm->meas_start_time);
- pframe = rtw_set_fixed_ie(pframe, 8, (u8 *)&val64, &my_len);
- /* Measurement Duration */
- val16 = prm->meas_end_time - prm->meas_start_time;
- val16 = cpu_to_le16(val16);
- pframe = rtw_set_fixed_ie(pframe, 2, (u8 *)&val16, &my_len);
- /* TODO
- * ReportedFrameInformation:
- * 0 :beacon or probe rsp
- * 1 :pilot frame
- */
- val8 = 0; /* report frame info */
- pframe = rtw_set_fixed_ie(pframe, 1, &val8, &my_len);
- /* RCPI */
- val8 = rm_get_rcpi(prm, pnetwork);
- pframe = rtw_set_fixed_ie(pframe, 1, &val8, &my_len);
- /* RSNI */
- val8 = rm_get_rsni(prm, pnetwork);
- pframe = rtw_set_fixed_ie(pframe, 1, &val8, &my_len);
- /* BSSID */
- pframe = rtw_set_fixed_ie(pframe, 6, (u8 *)&pbss->MacAddress, &my_len);
- /*
- * AntennaID
- * 0: unknown
- * 255: multiple antenna (Diversity)
- */
- val8 = 0;
- pframe = rtw_set_fixed_ie(pframe, 1, &val8, &my_len);
- /* ParentTSF */
- val32 = prm->meas_start_time + pnetwork->network.PhyInfo.free_cnt;
- pframe = rtw_set_fixed_ie(pframe, 4, (u8 *)&val32, &my_len);
- /*
- * Generate Beacon detail
- */
- pframe = rm_gen_bcn_detail_elem(padapter, pframe,
- prm, pnetwork, &my_len);
- done:
- /*
- * update my length
- * content length does NOT include ID and LEN
- */
- val8 = my_len - 2;
- rtw_set_fixed_ie(plen, 1, &val8, &i);
- /* update length to caller */
- *fr_len += my_len;
- return pframe;
- }
- static u8 *rm_gen_bcn_rep_ie (struct rm_obj *prm,
- u8 *pframe, struct wlan_network *pnetwork, unsigned int *fr_len)
- {
- int snr, i;
- u8 val8, *plen;
- u16 val16;
- u32 val32;
- u64 val64;
- unsigned int my_len;
- _adapter *padapter = prm->psta->padapter;
- my_len = 0;
- plen = pframe + 1;
- pframe = rtw_set_fixed_ie(pframe, 7, &prm->p.e_id, &my_len);
- /* Actual Measurement StartTime */
- val64 = cpu_to_le64(prm->meas_start_time);
- pframe = rtw_set_fixed_ie(pframe, 8, (u8 *)&val64, &my_len);
- /* Measurement Duration */
- val16 = prm->meas_end_time - prm->meas_start_time;
- val16 = cpu_to_le16(val16);
- pframe = rtw_set_fixed_ie(pframe, 2, (u8*)&val16, &my_len);
- /* TODO
- * ReportedFrameInformation:
- * 0 :beacon or probe rsp
- * 1 :pilot frame
- */
- val8 = 0; /* report frame info */
- pframe = rtw_set_fixed_ie(pframe, 1, &val8, &my_len);
- /* RCPI */
- val8 = rm_get_rcpi(prm, pnetwork);
- pframe = rtw_set_fixed_ie(pframe, 1, &val8, &my_len);
- /* RSNI */
- val8 = rm_get_rsni(prm, pnetwork);
- pframe = rtw_set_fixed_ie(pframe, 1, &val8, &my_len);
- /* BSSID */
- pframe = rtw_set_fixed_ie(pframe, 6,
- (u8 *)&pnetwork->network.MacAddress, &my_len);
- /*
- * AntennaID
- * 0: unknown
- * 255: multiple antenna (Diversity)
- */
- val8 = 0;
- pframe = rtw_set_fixed_ie(pframe, 1, &val8, &my_len);
- /* ParentTSF */
- val32 = prm->meas_start_time + pnetwork->network.PhyInfo.free_cnt;
- pframe = rtw_set_fixed_ie(pframe, 4, (u8 *)&val32, &my_len);
- /* Generate Beacon detail */
- pframe = rm_gen_bcn_detail_elem(padapter, pframe,
- prm, pnetwork, &my_len);
- done:
- /*
- * update my length
- * content length does NOT include ID and LEN
- */
- val8 = my_len - 2;
- rtw_set_fixed_ie(plen, 1, &val8, &i);
- /* update length to caller */
- *fr_len += my_len;
- return pframe;
- }
- static int retrieve_scan_result(struct rm_obj *prm)
- {
- _irqL irqL;
- _list *plist, *phead;
- _queue *queue;
- _adapter *padapter = prm->psta->padapter;
- struct rtw_ieee80211_channel *pch_set;
- struct wlan_network *pnetwork = NULL;
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- int i, meas_ch_num=0;
- PWLAN_BSSID_EX pbss;
- unsigned int matched_network;
- int len, my_len;
- u8 buf_idx, *pbuf = NULL, *tmp_buf = NULL;
- tmp_buf = rtw_malloc(MAX_XMIT_EXTBUF_SZ);
- if (tmp_buf == NULL)
- return 0;
- my_len = 0;
- buf_idx = 0;
- matched_network = 0;
- queue = &(pmlmepriv->scanned_queue);
- _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
- phead = get_list_head(queue);
- plist = get_next(phead);
- /* get requested measurement channel set */
- pch_set = prm->q.ch_set;
- meas_ch_num = prm->q.ch_set_ch_amount;
- /* search scan queue to find requested SSID */
- while (1) {
- if (rtw_end_of_queue_search(phead, plist) == _TRUE)
- break;
- pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
- pbss = &pnetwork->network;
- /*
- * report network if requested channel set contains
- * the channel matchs selected network
- */
- if (rtw_chset_search_ch(adapter_to_chset(padapter),
- pbss->Configuration.DSConfig) == 0)
- goto next;
- if (rtw_mlme_band_check(padapter, pbss->Configuration.DSConfig)
- == _FALSE)
- goto next;
- if (rtw_validate_ssid(&(pbss->Ssid)) == _FALSE)
- goto next;
- /* go through measurement requested channels */
- for (i = 0; i < meas_ch_num; i++) {
- /* match channel */
- if (pch_set[i].hw_value != pbss->Configuration.DSConfig)
- continue;
- /* match bssid */
- if (is_wildcard_bssid(prm->q.bssid) == FALSE)
- if (_rtw_memcmp(prm->q.bssid,
- pbss->MacAddress, 6) == _FALSE) {
- continue;
- }
- /*
- * default wildcard SSID. wildcard SSID:
- * A SSID value (null) used to represent all SSIDs
- */
- /* match ssid */
- if ((prm->q.opt.bcn.ssid.SsidLength > 0) &&
- _rtw_memcmp(prm->q.opt.bcn.ssid.Ssid,
- pbss->Ssid.Ssid,
- prm->q.opt.bcn.ssid.SsidLength) == _FALSE)
- continue;
- /* match condition */
- if (rm_bcn_req_cond_mach(prm, pnetwork) == _FALSE) {
- RTW_INFO("RM: condition mismatch ch %u ssid %s bssid "MAC_FMT"\n",
- pch_set[i].hw_value, pbss->Ssid.Ssid,
- MAC_ARG(pbss->MacAddress));
- RTW_INFO("RM: condition %u:%u\n",
- prm->q.opt.bcn.rep_cond.cond,
- prm->q.opt.bcn.rep_cond.threshold);
- continue;
- }
- /* Found a matched SSID */
- matched_network++;
- RTW_INFO("RM: ch %u Found %s bssid "MAC_FMT"\n",
- pch_set[i].hw_value, pbss->Ssid.Ssid,
- MAC_ARG(pbss->MacAddress));
- len = 0;
- _rtw_memset(tmp_buf, 0, MAX_XMIT_EXTBUF_SZ);
- rm_gen_bcn_rep_ie(prm, tmp_buf, pnetwork, &len);
- new_packet:
- if (my_len == 0) {
- pbuf = rtw_malloc(MAX_XMIT_EXTBUF_SZ);
- if (pbuf == NULL)
- goto fail;
- prm->buf[buf_idx].pbuf = pbuf;
- }
- if ((MAX_XMIT_EXTBUF_SZ - (my_len+len+24+4)) > 0) {
- pbuf = rtw_set_fixed_ie(pbuf,
- len, tmp_buf, &my_len);
- prm->buf[buf_idx].len = my_len;
- } else {
- if (my_len == 0) /* not enough space */
- goto fail;
- my_len = 0;
- buf_idx++;
- goto new_packet;
- }
- } /* for() */
- next:
- plist = get_next(plist);
- } /* while() */
- fail:
- _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
- if (tmp_buf)
- rtw_mfree(tmp_buf, MAX_XMIT_EXTBUF_SZ);
- RTW_INFO("RM: Found %d matched %s\n", matched_network,
- prm->q.opt.bcn.ssid.Ssid);
- if (prm->buf[buf_idx].pbuf)
- return buf_idx+1;
- return 0;
- }
- int issue_beacon_rep(struct rm_obj *prm)
- {
- int i, my_len;
- u8 *pframe;
- _adapter *padapter = prm->psta->padapter;
- struct pkt_attrib *pattr;
- struct xmit_frame *pmgntframe;
- struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
- int pkt_num;
- pkt_num = retrieve_scan_result(prm);
- if (pkt_num == 0) {
- issue_null_reply(prm);
- return _SUCCESS;
- }
- for (i=0;i<pkt_num;i++) {
- pmgntframe = alloc_mgtxmitframe(pxmitpriv);
- if (pmgntframe == NULL) {
- RTW_ERR("RM: %s alloc xmit_frame fail\n",__func__);
- goto fail;
- }
- pattr = &pmgntframe->attrib;
- pframe = build_wlan_hdr(padapter,
- pmgntframe, prm->psta, WIFI_ACTION);
- pframe = rtw_set_fixed_ie(pframe,
- 3, &prm->p.category, &pattr->pktlen);
- my_len = 0;
- pframe = rtw_set_fixed_ie(pframe,
- prm->buf[i].len, prm->buf[i].pbuf, &my_len);
- pattr->pktlen += my_len;
- pattr->last_txcmdsz = pattr->pktlen;
- dump_mgntframe(padapter, pmgntframe);
- }
- fail:
- for (i=0;i<pkt_num;i++) {
- if (prm->buf[i].pbuf) {
- rtw_mfree(prm->buf[i].pbuf, MAX_XMIT_EXTBUF_SZ);
- prm->buf[i].pbuf = NULL;
- prm->buf[i].len = 0;
- }
- }
- return _SUCCESS;
- }
- /* neighbor request */
- int issue_nb_req(struct rm_obj *prm)
- {
- _adapter *padapter = prm->psta->padapter;
- struct sta_info *psta = prm->psta;
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
- struct xmit_frame *pmgntframe = NULL;
- struct pkt_attrib *pattr = NULL;
- u8 val8;
- u8 *pframe = NULL;
- RTW_INFO("RM: %s\n", __func__);
- pmgntframe = alloc_mgtxmitframe(pxmitpriv);
- if (pmgntframe == NULL) {
- RTW_ERR("RM: %s alloc xmit_frame fail\n",__func__);
- return _FALSE;
- }
- pattr = &pmgntframe->attrib;
- pframe = build_wlan_hdr(padapter, pmgntframe, psta, WIFI_ACTION);
- pframe = rtw_set_fixed_ie(pframe,
- 3, &prm->q.category, &pattr->pktlen);
- if (prm->q.pssid) {
- u8 sub_ie[64] = {0};
- u8 *pie = &sub_ie[2];
- RTW_INFO("RM: Send NB Req to "MAC_FMT" for(SSID) %s searching\n",
- MAC_ARG(pmlmepriv->cur_network.network.MacAddress),
- pmlmepriv->cur_network.network.Ssid.Ssid);
- val8 = strlen(prm->q.pssid);
- sub_ie[0] = 0; /*SSID*/
- sub_ie[1] = val8;
- _rtw_memcpy(pie, prm->q.pssid, val8);
- pframe = rtw_set_fixed_ie(pframe, val8 + 2,
- sub_ie, &pattr->pktlen);
- } else {
- if (!pmlmepriv->cur_network.network.Ssid.SsidLength)
- RTW_INFO("RM: Send NB Req to "MAC_FMT"\n",
- MAC_ARG(pmlmepriv->cur_network.network.MacAddress));
- else {
- u8 sub_ie[64] = {0};
- u8 *pie = &sub_ie[2];
- RTW_INFO("RM: Send NB Req to "MAC_FMT" for(SSID) %s searching\n",
- MAC_ARG(pmlmepriv->cur_network.network.MacAddress),
- pmlmepriv->cur_network.network.Ssid.Ssid);
- sub_ie[0] = 0; /*SSID*/
- sub_ie[1] = pmlmepriv->cur_network.network.Ssid.SsidLength;
- _rtw_memcpy(pie, pmlmepriv->cur_network.network.Ssid.Ssid,
- pmlmepriv->cur_network.network.Ssid.SsidLength);
- pframe = rtw_set_fixed_ie(pframe,
- pmlmepriv->cur_network.network.Ssid.SsidLength + 2,
- sub_ie, &pattr->pktlen);
- }
- }
- pattr->last_txcmdsz = pattr->pktlen;
- dump_mgntframe(padapter, pmgntframe);
- return _SUCCESS;
- }
- static u8 *rm_gen_bcn_req_s_elem(_adapter *padapter,
- u8 *pframe, unsigned int *fr_len)
- {
- u8 val8;
- unsigned int my_len = 0;
- u8 bssid[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
- val8 = bcn_req_active; /* measurement mode T8-64 */
- pframe = rtw_set_fixed_ie(pframe, 1, &val8, &my_len);
- pframe = rtw_set_fixed_ie(pframe, 6, bssid, &my_len);
- /* update length to caller */
- *fr_len += my_len;
- /* optional subelements */
- return pframe;
- }
- static u8 *rm_gen_ch_load_req_s_elem(_adapter *padapter,
- u8 *pframe, unsigned int *fr_len)
- {
- u8 val8;
- unsigned int my_len = 0;
- val8 = 1; /* 1: channel load T8-60 */
- pframe = rtw_set_fixed_ie(pframe, 1, &val8, &my_len);
- val8 = 2; /* channel load length = 2 (extensible) */
- pframe = rtw_set_fixed_ie(pframe, 1, &val8, &my_len);
- val8 = 0; /* channel load condition : 0 (issue when meas done) T8-61 */
- pframe = rtw_set_fixed_ie(pframe, 1, &val8, &my_len);
- val8 = 0; /* channel load reference value : 0 */
- pframe = rtw_set_fixed_ie(pframe, 1, &val8, &my_len);
- /* update length to caller */
- *fr_len += my_len;
- return pframe;
- }
- static u8 *rm_gen_noise_histo_req_s_elem(_adapter *padapter,
- u8 *pframe, unsigned int *fr_len)
- {
- u8 val8;
- unsigned int my_len = 0;
- val8 = 1; /* 1: noise histogram T8-62 */
- pframe = rtw_set_fixed_ie(pframe, 1, &val8, &my_len);
- val8 = 2; /* noise histogram length = 2 (extensible) */
- pframe = rtw_set_fixed_ie(pframe, 1, &val8, &my_len);
- val8 = 0; /* noise histogram condition : 0 (issue when meas done) T8-63 */
- pframe = rtw_set_fixed_ie(pframe, 1, &val8, &my_len);
- val8 = 0; /* noise histogram reference value : 0 */
- pframe = rtw_set_fixed_ie(pframe, 1, &val8, &my_len);
- /* update length to caller */
- *fr_len += my_len;
- return pframe;
- }
- int issue_radio_meas_req(struct rm_obj *prm)
- {
- u8 val8;
- u8 *pframe;
- u8 *plen;
- u16 val16;
- int my_len, i;
- struct xmit_frame *pmgntframe;
- struct pkt_attrib *pattr;
- _adapter *padapter = prm->psta->padapter;
- struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
- RTW_INFO("RM: %s - %s\n", __func__, rm_type_req_name(prm->q.m_type));
- pmgntframe = alloc_mgtxmitframe(pxmitpriv);
- if (pmgntframe == NULL) {
- RTW_ERR("RM: %s alloc xmit_frame fail\n",__func__);
- return _FALSE;
- }
- pattr = &pmgntframe->attrib;
- pframe = build_wlan_hdr(padapter, pmgntframe, prm->psta, WIFI_ACTION);
- pframe = rtw_set_fixed_ie(pframe, 3, &prm->q.category, &pattr->pktlen);
- /* repeat */
- val16 = cpu_to_le16(prm->q.rpt);
- pframe = rtw_set_fixed_ie(pframe, 2,
- (unsigned char *)&(val16), &pattr->pktlen);
- my_len = 0;
- plen = pframe + 1;
- pframe = rtw_set_fixed_ie(pframe, 7, &prm->q.e_id, &my_len);
- /* random interval */
- val16 = 100; /* 100 TU */
- val16 = cpu_to_le16(val16);
- pframe = rtw_set_fixed_ie(pframe, 2, (u8 *)&val16, &my_len);
- /* measurement duration */
- val16 = 100;
- val16 = cpu_to_le16(val16);
- pframe = rtw_set_fixed_ie(pframe, 2, (u8 *)&val16, &my_len);
- /* optional subelement */
- switch (prm->q.m_type) {
- case bcn_req:
- pframe = rm_gen_bcn_req_s_elem(padapter, pframe, &my_len);
- break;
- case ch_load_req:
- pframe = rm_gen_ch_load_req_s_elem(padapter, pframe, &my_len);
- break;
- case noise_histo_req:
- pframe = rm_gen_noise_histo_req_s_elem(padapter,
- pframe, &my_len);
- break;
- case basic_req:
- default:
- break;
- }
- /* length */
- val8 = (u8)my_len - 2;
- rtw_set_fixed_ie(plen, 1, &val8, &i);
- pattr->pktlen += my_len;
- pattr->last_txcmdsz = pattr->pktlen;
- dump_mgntframe(padapter, pmgntframe);
- return _SUCCESS;
- }
- /* noise histogram */
- static u8 rm_get_anpi(struct rm_obj *prm, struct wlan_network *pnetwork)
- {
- return translate_percentage_to_rcpi(
- pnetwork->network.PhyInfo.SignalStrength);
- }
- int rm_radio_meas_report_cond(struct rm_obj *prm)
- {
- u8 val8;
- int i;
- switch (prm->q.m_type) {
- case ch_load_req:
- val8 = prm->p.ch_load;
- switch (prm->q.opt.clm.rep_cond.cond) {
- case ch_load_cond_immediately:
- return _SUCCESS;
- case ch_load_cond_anpi_equal_greater:
- if (val8 >= prm->q.opt.clm.rep_cond.threshold)
- return _SUCCESS;
- case ch_load_cond_anpi_equal_less:
- if (val8 <= prm->q.opt.clm.rep_cond.threshold)
- return _SUCCESS;
- default:
- break;
- }
- break;
- case noise_histo_req:
- val8 = prm->p.anpi;
- switch (prm->q.opt.nhm.rep_cond.cond) {
- case noise_histo_cond_immediately:
- return _SUCCESS;
- case noise_histo_cond_anpi_equal_greater:
- if (val8 >= prm->q.opt.nhm.rep_cond.threshold)
- return _SUCCESS;
- break;
- case noise_histo_cond_anpi_equal_less:
- if (val8 <= prm->q.opt.nhm.rep_cond.threshold)
- return _SUCCESS;
- break;
- default:
- break;
- }
- break;
- default:
- break;
- }
- return _FAIL;
- }
- int retrieve_radio_meas_result(struct rm_obj *prm)
- {
- HAL_DATA_TYPE *hal_data = GET_HAL_DATA(prm->psta->padapter);
- int i, ch = -1;
- u8 val8;
- ch = rtw_chset_search_ch(adapter_to_chset(prm->psta->padapter),
- prm->q.ch_num);
- if ((ch == -1) || (ch >= MAX_CHANNEL_NUM)) {
- RTW_ERR("RM: get ch(CH:%d) fail\n", prm->q.ch_num);
- ch = 0;
- }
- switch (prm->q.m_type) {
- case ch_load_req:
- #ifdef CONFIG_RTW_ACS
- val8 = hal_data->acs.clm_ratio[ch];
- #else
- val8 = 0;
- #endif
- prm->p.ch_load = val8;
- break;
- case noise_histo_req:
- #ifdef CONFIG_RTW_ACS
- /* ANPI */
- prm->p.anpi = hal_data->acs.nhm_ratio[ch];
- /* IPI 0~10 */
- for (i=0;i<11;i++)
- prm->p.ipi[i] = hal_data->acs.nhm[ch][i];
-
- #else
- val8 = 0;
- prm->p.anpi = val8;
- for (i=0;i<11;i++)
- prm->p.ipi[i] = val8;
- #endif
- break;
- default:
- break;
- }
- return _SUCCESS;
- }
- int issue_radio_meas_rep(struct rm_obj *prm)
- {
- u8 val8;
- u8 *pframe;
- u8 *plen;
- u16 val16;
- u64 val64;
- unsigned int my_len;
- _adapter *padapter = prm->psta->padapter;
- struct xmit_frame *pmgntframe;
- struct pkt_attrib *pattr;
- struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
- struct sta_info *psta = prm->psta;
- int i;
- RTW_INFO("RM: %s\n", __func__);
- pmgntframe = alloc_mgtxmitframe(pxmitpriv);
- if (pmgntframe == NULL) {
- RTW_ERR("RM: ERR %s alloc xmit_frame fail\n",__func__);
- return _FALSE;
- }
- pattr = &pmgntframe->attrib;
- pframe = build_wlan_hdr(padapter, pmgntframe, psta, WIFI_ACTION);
- pframe = rtw_set_fixed_ie(pframe, 3,
- &prm->p.category, &pattr->pktlen);
- my_len = 0;
- plen = pframe + 1;
- pframe = rtw_set_fixed_ie(pframe, 7, &prm->p.e_id, &my_len);
- /* Actual Meas start time - 8 bytes */
- val64 = cpu_to_le64(prm->meas_start_time);
- pframe = rtw_set_fixed_ie(pframe, 8, (u8 *)&val64, &my_len);
- /* measurement duration */
- val16 = prm->meas_end_time - prm->meas_start_time;
- val16 = cpu_to_le16(val16);
- pframe = rtw_set_fixed_ie(pframe, 2, (u8 *)&val16, &my_len);
- /* optional subelement */
- switch (prm->q.m_type) {
- case ch_load_req:
- val8 = prm->p.ch_load;
- pframe = rtw_set_fixed_ie(pframe, 1, &val8, &my_len);
- break;
- case noise_histo_req:
- /*
- * AntennaID
- * 0: unknown
- * 255: multiple antenna (Diversity)
- */
- val8 = 0;
- pframe = rtw_set_fixed_ie(pframe, 1, &val8, &my_len);
- /* ANPI */
- val8 = prm->p.anpi;
- pframe = rtw_set_fixed_ie(pframe, 1, &val8, &my_len);
- /* IPI 0~10 */
- for (i=0;i<11;i++) {
- val8 = prm->p.ipi[i];
- pframe = rtw_set_fixed_ie(pframe, 1, &val8, &my_len);
- }
- break;
- default:
- break;
- }
- done:
- /* length */
- val8 = (u8)my_len-2;
- rtw_set_fixed_ie(plen, 1, &val8, &i); /* use variable i to ignore it */
- pattr->pktlen += my_len;
- pattr->last_txcmdsz = pattr->pktlen;
- dump_mgntframe(padapter, pmgntframe);
- return _SUCCESS;
- }
- void rtw_ap_parse_sta_rm_en_cap(_adapter *padapter,
- struct sta_info *psta, struct rtw_ieee802_11_elems *elem)
- {
- if (elem->rm_en_cap) {
- RTW_INFO("assoc.rm_en_cap="RM_CAP_FMT"\n",
- RM_CAP_ARG(elem->rm_en_cap));
- _rtw_memcpy(psta->rm_en_cap,
- (elem->rm_en_cap), elem->rm_en_cap_len);
- }
- }
- void RM_IE_handler(_adapter *padapter, PNDIS_802_11_VARIABLE_IEs pIE)
- {
- int i;
- _rtw_memcpy(&padapter->rmpriv.rm_en_cap_assoc, pIE->data, pIE->Length);
- RTW_INFO("assoc.rm_en_cap="RM_CAP_FMT"\n", RM_CAP_ARG(pIE->data));
- }
- /* Debug command */
- #if (RM_SUPPORT_IWPRIV_DBG)
- static int hex2num(char c)
- {
- if (c >= '0' && c <= '9')
- return c - '0';
- if (c >= 'a' && c <= 'f')
- return c - 'a' + 10;
- if (c >= 'A' && c <= 'F')
- return c - 'A' + 10;
- return -1;
- }
- int hex2byte(const char *hex)
- {
- int a, b;
- a = hex2num(*hex++);
- if (a < 0)
- return -1;
- b = hex2num(*hex++);
- if (b < 0)
- return -1;
- return (a << 4) | b;
- }
- static char * hwaddr_parse(char *txt, u8 *addr)
- {
- size_t i;
- for (i = 0; i < ETH_ALEN; i++) {
- int a;
- a = hex2byte(txt);
- if (a < 0)
- return NULL;
- txt += 2;
- addr[i] = a;
- if (i < ETH_ALEN - 1 && *txt++ != ':')
- return NULL;
- }
- return txt;
- }
- void rm_dbg_list_sta(_adapter *padapter, char *s)
- {
- int i;
- _irqL irqL;
- struct sta_info *psta;
- struct sta_priv *pstapriv = &padapter->stapriv;
- _list *plist, *phead;
- sprintf(pstr(s), "\n");
- _enter_critical_bh(&pstapriv->sta_hash_lock, &irqL);
- for (i = 0; i < NUM_STA; i++) {
- phead = &(pstapriv->sta_hash[i]);
- plist = get_next(phead);
- while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) {
- psta = LIST_CONTAINOR(plist,
- struct sta_info, hash_list);
- plist = get_next(plist);
- sprintf(pstr(s), "=========================================\n");
- sprintf(pstr(s), "mac=" MAC_FMT "\n",
- MAC_ARG(psta->cmn.mac_addr));
- sprintf(pstr(s), "state=0x%x, aid=%d, macid=%d\n",
- psta->state, psta->cmn.aid, psta->cmn.mac_id);
- sprintf(pstr(s), "rm_cap="RM_CAP_FMT"\n",
- RM_CAP_ARG(psta->rm_en_cap));
- }
- }
- _exit_critical_bh(&pstapriv->sta_hash_lock, &irqL);
- sprintf(pstr(s), "=========================================\n");
- }
- void rm_dbg_help(_adapter *padapter, char *s)
- {
- int i;
- sprintf(pstr(s), "\n");
- sprintf(pstr(s), "rrm list_sta\n");
- sprintf(pstr(s), "rrm list_meas\n");
- sprintf(pstr(s), "rrm add_meas <aid=1|mac=>,m=<bcn|clm|nhm|nb>,rpt=\n");
- sprintf(pstr(s), "rrm run_meas <aid=1|evid=>\n");
- sprintf(pstr(s), "rrm del_meas\n");
- sprintf(pstr(s), "rrm run_meas rmid=xxxx,ev=xx\n");
- sprintf(pstr(s), "rrm activate\n");
- for (i=0;i<RM_EV_max;i++)
- sprintf(pstr(s), "\t%2d %s\n",i, rm_event_name(i) );
- sprintf(pstr(s), "\n");
- }
- struct sta_info *rm_get_sta(_adapter *padapter, u16 aid, u8* pbssid)
- {
- int i;
- _irqL irqL;
- struct sta_info *psta = NULL;
- struct sta_priv *pstapriv = &padapter->stapriv;
- _list *plist, *phead;
- _enter_critical_bh(&pstapriv->sta_hash_lock, &irqL);
- for (i = 0; i < NUM_STA; i++) {
- phead = &(pstapriv->sta_hash[i]);
- plist = get_next(phead);
- while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) {
- psta = LIST_CONTAINOR(plist,
- struct sta_info, hash_list);
- plist = get_next(plist);
- if (psta->cmn.aid == aid)
- goto done;
- if (pbssid && _rtw_memcmp(psta->cmn.mac_addr,
- pbssid, 6))
- goto done;
- }
- }
- psta = NULL;
- done:
- _exit_critical_bh(&pstapriv->sta_hash_lock, &irqL);
- return psta;
- }
- static int rm_dbg_modify_meas(_adapter *padapter, char *s)
- {
- struct rm_priv *prmpriv = &padapter->rmpriv;
- struct mlme_ext_info *pmlmeinfo = &padapter->mlmeextpriv.mlmext_info;
- struct rm_obj *prm;
- struct sta_info *psta;
- char *pmac, *ptr, *paid, *prpt, *pnbp, *pclm, *pnhm, *pbcn;
- unsigned val;
- u8 bssid[ETH_ALEN];
- /* example :
- * rrm add_meas <aid=1|mac=>,m=<nb|clm|nhm|bcn>,<rept=>
- * rrm run_meas <aid=1|evid=>
- */
- paid = strstr(s, "aid=");
- pmac = strstr(s, "mac=");
- pbcn = strstr(s, "m=bcn");
- pclm = strstr(s, "m=clm");
- pnhm = strstr(s, "m=nhm");
- pnbp = strstr(s, "m=nb");
- prpt = strstr(s, "rpt=");
- /* set all ',' to NULL (end of line) */
- ptr = s;
- while (ptr) {
- ptr = strchr(ptr, ',');
- if (ptr) {
- *(ptr) = 0x0;
- ptr++;
- }
- }
- prm = (struct rm_obj *)prmpriv->prm_sel;
- prm->q.m_token = 1;
- psta = prm->psta;
- if (paid) { /* find sta_info according to aid */
- paid += 4; /* skip aid= */
- sscanf(paid, "%u", &val); /* aid=x */
- psta = rm_get_sta(padapter, val, NULL);
- } else if (pmac) { /* find sta_info according to bssid */
- pmac += 4; /* skip mac= */
- if (hwaddr_parse(pmac, bssid) == NULL) {
- sprintf(pstr(s), "Err: \nincorrect mac format\n");
- return _FAIL;
- }
- psta = rm_get_sta(padapter, 0xff, bssid);
- }
- if (psta) {
- prm->psta = psta;
- #if 0
- prm->q.diag_token = psta->rm_diag_token++;
- #else
- /* TODO dialog should base on sta_info */
- prm->q.diag_token = pmlmeinfo->dialogToken++;
- #endif
- prm->rmid = psta->cmn.aid << 16
- | prm->q.diag_token << 8
- | RM_MASTER;
- } else
- return _FAIL;
- prm->q.action_code = RM_ACT_RADIO_MEAS_REQ;
- if (pbcn) {
- prm->q.m_type = bcn_req;
- } else if (pnhm) {
- prm->q.m_type = noise_histo_req;
- } else if (pclm) {
- prm->q.m_type = ch_load_req;
- } else if (pnbp) {
- prm->q.action_code = RM_ACT_NB_REP_REQ;
- } else
- return _FAIL;
- if (prpt) {
- prpt += 4; /* skip rpt= */
- sscanf(prpt, "%u", &val);
- prm->q.rpt = (u8)val;
- }
- return _SUCCESS;
- }
- static void rm_dbg_activate_meas(_adapter *padapter, char *s)
- {
- struct rm_priv *prmpriv = &(padapter->rmpriv);
- struct rm_obj *prm;
- if (prmpriv->prm_sel == NULL) {
- sprintf(pstr(s), "\nErr: No inActivate measurement\n");
- return;
- }
- prm = (struct rm_obj *)prmpriv->prm_sel;
- /* verify attributes */
- if (prm->psta == NULL) {
- sprintf(pstr(s), "\nErr: inActivate meas has no psta\n");
- return;
- }
- /* measure current channel */
- prm->q.ch_num = padapter->mlmeextpriv.cur_channel;
- prm->q.op_class = rm_get_oper_class_via_ch(prm->q.ch_num);
- /* enquee rmobj */
- rm_enqueue_rmobj(padapter, prm, _FALSE);
- sprintf(pstr(s), "\nActivate rmid=%x, state=%s, meas_type=%s\n",
- prm->rmid, rm_state_name(prm->state),
- rm_type_req_name(prm->q.m_type));
- sprintf(pstr(s), "aid=%d, mac=" MAC_FMT "\n",
- prm->psta->cmn.aid, MAC_ARG(prm->psta->cmn.mac_addr));
- /* clearn inActivate prm info */
- prmpriv->prm_sel = NULL;
- }
- static void rm_dbg_add_meas(_adapter *padapter, char *s)
- {
- struct rm_priv *prmpriv = &(padapter->rmpriv);
- struct rm_obj *prm;
- char *pact;
- /* example :
- * rrm add_meas <aid=1|mac=>,m=<nb_req|clm_req|nhm_req>
- * rrm run_meas <aid=1|evid=>
- */
- prm = (struct rm_obj *)prmpriv->prm_sel;
- if (prm == NULL)
- prm = rm_alloc_rmobj(padapter);
- if (prm == NULL) {
- sprintf(pstr(s), "\nErr: alloc meas fail\n");
- return;
- }
- prmpriv->prm_sel = prm;
- pact = strstr(s, "act");
- if (rm_dbg_modify_meas(padapter, s) == _FAIL) {
- sprintf(pstr(s), "\nErr: add meas fail\n");
- rm_free_rmobj(prm);
- prmpriv->prm_sel = NULL;
- return;
- }
- prm->q.category = RTW_WLAN_CATEGORY_RADIO_MEAS;
- prm->q.e_id = _MEAS_REQ_IE_; /* 38 */
- if (prm->q.action_code == RM_ACT_RADIO_MEAS_REQ)
- sprintf(pstr(s), "\nAdd rmid=%x, meas_type=%s ok\n",
- prm->rmid, rm_type_req_name(prm->q.m_type));
- else if (prm->q.action_code == RM_ACT_NB_REP_REQ)
- sprintf(pstr(s), "\nAdd rmid=%x, meas_type=bcn_req ok\n",
- prm->rmid);
- if (prm->psta)
- sprintf(pstr(s), "mac="MAC_FMT"\n",
- MAC_ARG(prm->psta->cmn.mac_addr));
- if (pact)
- rm_dbg_activate_meas(padapter, pstr(s));
- }
- static void rm_dbg_del_meas(_adapter *padapter, char *s)
- {
- struct rm_priv *prmpriv = &padapter->rmpriv;
- struct rm_obj *prm = (struct rm_obj *)prmpriv->prm_sel;
- if (prm) {
- sprintf(pstr(s), "\ndelete rmid=%x\n",prm->rmid);
- /* free inActivate meas - enqueue yet */
- prmpriv->prm_sel = NULL;
- rtw_mfree(prmpriv->prm_sel, sizeof(struct rm_obj));
- } else
- sprintf(pstr(s), "Err: no inActivate measurement\n");
- }
- static void rm_dbg_run_meas(_adapter *padapter, char *s)
- {
- struct rm_obj *prm;
- char *pevid, *prmid;
- u32 rmid, evid;
- prmid = strstr(s, "rmid="); /* hex */
- pevid = strstr(s, "evid="); /* dec */
- if (prmid && pevid) {
- prmid += 5; /* rmid= */
- sscanf(prmid, "%x", &rmid);
- pevid += 5; /* evid= */
- sscanf(pevid, "%u", &evid);
- } else {
- sprintf(pstr(s), "\nErr: incorrect attribute\n");
- return;
- }
- prm = rm_get_rmobj(padapter, rmid);
- if (!prm) {
- sprintf(pstr(s), "\nErr: measurement not found\n");
- return;
- }
- if (evid >= RM_EV_max) {
- sprintf(pstr(s), "\nErr: wrong event id\n");
- return;
- }
- rm_post_event(padapter, prm->rmid, evid);
- sprintf(pstr(s), "\npost %s to rmid=%x\n",rm_event_name(evid), rmid);
- }
- static void rm_dbg_show_meas(struct rm_obj *prm, char *s)
- {
- struct sta_info *psta;
- psta = prm->psta;
- if (prm->q.action_code == RM_ACT_RADIO_MEAS_REQ) {
- sprintf(pstr(s), "\nrmid=%x, meas_type=%s\n",
- prm->rmid, rm_type_req_name(prm->q.m_type));
- } else if (prm->q.action_code == RM_ACT_NB_REP_REQ) {
- sprintf(pstr(s), "\nrmid=%x, action=neighbor_req\n",
- prm->rmid);
- } else
- sprintf(pstr(s), "\nrmid=%x, action=unknown\n",
- prm->rmid);
- if (psta)
- sprintf(pstr(s), "aid=%d, mac="MAC_FMT"\n",
- psta->cmn.aid, MAC_ARG(psta->cmn.mac_addr));
- sprintf(pstr(s), "clock=%d, state=%s, rpt=%u/%u\n",
- (int)ATOMIC_READ(&prm->pclock->counter),
- rm_state_name(prm->state), prm->p.rpt, prm->q.rpt);
- }
- static void rm_dbg_list_meas(_adapter *padapter, char *s)
- {
- int meas_amount;
- _irqL irqL;
- struct rm_obj *prm;
- struct sta_info *psta;
- struct rm_priv *prmpriv = &padapter->rmpriv;
- _queue *queue = &prmpriv->rm_queue;
- _list *plist, *phead;
- sprintf(pstr(s), "\n");
- _enter_critical(&queue->lock, &irqL);
- phead = get_list_head(queue);
- plist = get_next(phead);
- meas_amount = 0;
- while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) {
- prm = LIST_CONTAINOR(plist, struct rm_obj, list);
- meas_amount++;
- plist = get_next(plist);
- psta = prm->psta;
- sprintf(pstr(s), "=========================================\n");
- rm_dbg_show_meas(prm, s);
- }
- _exit_critical(&queue->lock, &irqL);
- sprintf(pstr(s), "=========================================\n");
- if (meas_amount==0) {
- sprintf(pstr(s), "No Activate measurement\n");
- sprintf(pstr(s), "=========================================\n");
- }
- if (prmpriv->prm_sel == NULL)
- sprintf(pstr(s), "\nNo inActivate measurement\n");
- else {
- sprintf(pstr(s), "\ninActivate measurement\n");
- rm_dbg_show_meas((struct rm_obj *)prmpriv->prm_sel, s);
- }
- }
- #endif /* RM_SUPPORT_IWPRIV_DBG */
- void rm_dbg_cmd(_adapter *padapter, char *s)
- {
- unsigned val;
- char *paid;
- struct sta_info *psta=NULL;
- #if (RM_SUPPORT_IWPRIV_DBG)
- if (_rtw_memcmp(s, "help", 4)) {
- rm_dbg_help(padapter, s);
- } else if (_rtw_memcmp(s, "list_sta", 8)) {
- rm_dbg_list_sta(padapter, s);
- } else if (_rtw_memcmp(s, "list_meas", 9)) {
- rm_dbg_list_meas(padapter, s);
- } else if (_rtw_memcmp(s, "add_meas", 8)) {
- rm_dbg_add_meas(padapter, s);
- } else if (_rtw_memcmp(s, "del_meas", 8)) {
- rm_dbg_del_meas(padapter, s);
- } else if (_rtw_memcmp(s, "activate", 8)) {
- rm_dbg_activate_meas(padapter, s);
- } else if (_rtw_memcmp(s, "run_meas", 8)) {
- rm_dbg_run_meas(padapter, s);
- } else if (_rtw_memcmp(s, "nb", 2)) {
- paid = strstr(s, "aid=");
- if (paid) { /* find sta_info according to aid */
- paid += 4; /* skip aid= */
- sscanf(paid, "%u", &val); /* aid=x */
- psta = rm_get_sta(padapter, val, NULL);
- if (psta)
- rm_add_nb_req(padapter, psta);
- }
- }
- #else
- sprintf(pstr(s), "\n");
- sprintf(pstr(s), "rrm debug command was disabled\n");
- #endif
- }
- #endif /* CONFIG_RTW_80211K */
|