wmi_unified_roam_tlv.c 93 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806
  1. /*
  2. * Copyright (c) 2013-2020 The Linux Foundation. All rights reserved.
  3. *
  4. * Permission to use, copy, modify, and/or distribute this software for
  5. * any purpose with or without fee is hereby granted, provided that the
  6. * above copyright notice and this permission notice appear in all
  7. * copies.
  8. *
  9. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
  10. * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
  11. * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
  12. * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
  13. * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
  14. * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
  15. * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  16. * PERFORMANCE OF THIS SOFTWARE.
  17. */
  18. /**
  19. * DOC: Implement API's specific to roaming component.
  20. */
  21. #include <wmi_unified_priv.h>
  22. #include <wmi_unified_roam_api.h>
  23. #include "wmi.h"
  24. #ifdef FEATURE_LFR_SUBNET_DETECTION
  25. /**
  26. * send_set_gateway_params_cmd_tlv() - set gateway parameters
  27. * @wmi_handle: wmi handle
  28. * @req: gateway parameter update request structure
  29. *
  30. * This function reads the incoming @req and fill in the destination
  31. * WMI structure and sends down the gateway configs down to the firmware
  32. *
  33. * Return: QDF_STATUS
  34. */
  35. static QDF_STATUS send_set_gateway_params_cmd_tlv(wmi_unified_t wmi_handle,
  36. struct gateway_update_req_param *req)
  37. {
  38. wmi_roam_subnet_change_config_fixed_param *cmd;
  39. wmi_buf_t buf;
  40. QDF_STATUS ret;
  41. int len = sizeof(*cmd);
  42. buf = wmi_buf_alloc(wmi_handle, len);
  43. if (!buf) {
  44. return QDF_STATUS_E_NOMEM;
  45. }
  46. cmd = (wmi_roam_subnet_change_config_fixed_param *) wmi_buf_data(buf);
  47. WMITLV_SET_HDR(&cmd->tlv_header,
  48. WMITLV_TAG_STRUC_wmi_roam_subnet_change_config_fixed_param,
  49. WMITLV_GET_STRUCT_TLVLEN(
  50. wmi_roam_subnet_change_config_fixed_param));
  51. cmd->vdev_id = req->vdev_id;
  52. qdf_mem_copy(&cmd->inet_gw_ip_v4_addr, req->ipv4_addr,
  53. QDF_IPV4_ADDR_SIZE);
  54. qdf_mem_copy(&cmd->inet_gw_ip_v6_addr, req->ipv6_addr,
  55. QDF_IPV6_ADDR_SIZE);
  56. WMI_CHAR_ARRAY_TO_MAC_ADDR(req->gw_mac_addr.bytes,
  57. &cmd->inet_gw_mac_addr);
  58. cmd->max_retries = req->max_retries;
  59. cmd->timeout = req->timeout;
  60. cmd->num_skip_subnet_change_detection_bssid_list = 0;
  61. cmd->flag = 0;
  62. if (req->ipv4_addr_type)
  63. WMI_SET_ROAM_SUBNET_CHANGE_FLAG_IP4_ENABLED(cmd->flag);
  64. if (req->ipv6_addr_type)
  65. WMI_SET_ROAM_SUBNET_CHANGE_FLAG_IP6_ENABLED(cmd->flag);
  66. wmi_mtrace(WMI_ROAM_SUBNET_CHANGE_CONFIG_CMDID, cmd->vdev_id, 0);
  67. ret = wmi_unified_cmd_send(wmi_handle, buf, len,
  68. WMI_ROAM_SUBNET_CHANGE_CONFIG_CMDID);
  69. if (QDF_IS_STATUS_ERROR(ret)) {
  70. WMI_LOGE("Failed to send gw config parameter to fw, ret: %d",
  71. ret);
  72. wmi_buf_free(buf);
  73. }
  74. return ret;
  75. }
  76. void wmi_lfr_subnet_detection_attach_tlv(struct wmi_unified *wmi_handle)
  77. {
  78. struct wmi_ops *ops = wmi_handle->ops;
  79. ops->send_set_gateway_params_cmd = send_set_gateway_params_cmd_tlv;
  80. }
  81. #endif /* FEATURE_LFR_SUBNET_DETECTION */
  82. #ifdef FEATURE_RSSI_MONITOR
  83. /**
  84. * send_set_rssi_monitoring_cmd_tlv() - set rssi monitoring
  85. * @wmi_handle: wmi handle
  86. * @req: rssi monitoring request structure
  87. *
  88. * This function reads the incoming @req and fill in the destination
  89. * WMI structure and send down the rssi monitoring configs down to the firmware
  90. *
  91. * Return: 0 on success; error number otherwise
  92. */
  93. static QDF_STATUS send_set_rssi_monitoring_cmd_tlv(wmi_unified_t wmi_handle,
  94. struct rssi_monitor_param *req)
  95. {
  96. wmi_rssi_breach_monitor_config_fixed_param *cmd;
  97. wmi_buf_t buf;
  98. QDF_STATUS ret;
  99. uint32_t len = sizeof(*cmd);
  100. buf = wmi_buf_alloc(wmi_handle, len);
  101. if (!buf) {
  102. return QDF_STATUS_E_NOMEM;
  103. }
  104. cmd = (wmi_rssi_breach_monitor_config_fixed_param *) wmi_buf_data(buf);
  105. WMITLV_SET_HDR(&cmd->tlv_header,
  106. WMITLV_TAG_STRUC_wmi_rssi_breach_monitor_config_fixed_param,
  107. WMITLV_GET_STRUCT_TLVLEN(
  108. wmi_rssi_breach_monitor_config_fixed_param));
  109. cmd->vdev_id = req->vdev_id;
  110. cmd->request_id = req->request_id;
  111. cmd->lo_rssi_reenable_hysteresis = 0;
  112. cmd->hi_rssi_reenable_histeresis = 0;
  113. cmd->min_report_interval = 0;
  114. cmd->max_num_report = 1;
  115. if (req->control) {
  116. /* enable one threshold for each min/max */
  117. cmd->enabled_bitmap = 0x09;
  118. cmd->low_rssi_breach_threshold[0] = req->min_rssi;
  119. cmd->hi_rssi_breach_threshold[0] = req->max_rssi;
  120. } else {
  121. cmd->enabled_bitmap = 0;
  122. cmd->low_rssi_breach_threshold[0] = 0;
  123. cmd->hi_rssi_breach_threshold[0] = 0;
  124. }
  125. wmi_mtrace(WMI_RSSI_BREACH_MONITOR_CONFIG_CMDID, cmd->vdev_id, 0);
  126. ret = wmi_unified_cmd_send(wmi_handle, buf, len,
  127. WMI_RSSI_BREACH_MONITOR_CONFIG_CMDID);
  128. if (QDF_IS_STATUS_ERROR(ret)) {
  129. WMI_LOGE("Failed to send WMI_RSSI_BREACH_MONITOR_CONFIG_CMDID");
  130. wmi_buf_free(buf);
  131. }
  132. WMI_LOGD("Sent WMI_RSSI_BREACH_MONITOR_CONFIG_CMDID to FW");
  133. return ret;
  134. }
  135. void wmi_rssi_monitor_attach_tlv(struct wmi_unified *wmi_handle)
  136. {
  137. struct wmi_ops *ops = wmi_handle->ops;
  138. ops->send_set_rssi_monitoring_cmd = send_set_rssi_monitoring_cmd_tlv;
  139. }
  140. #endif /* FEATURE_RSSI_MONITOR */
  141. /**
  142. * send_roam_scan_offload_rssi_thresh_cmd_tlv() - set scan offload
  143. * rssi threashold
  144. * @wmi_handle: wmi handle
  145. * @roam_req: Roaming request buffer
  146. *
  147. * Send WMI_ROAM_SCAN_RSSI_THRESHOLD TLV to firmware
  148. *
  149. * Return: QDF status
  150. */
  151. static QDF_STATUS send_roam_scan_offload_rssi_thresh_cmd_tlv(wmi_unified_t wmi_handle,
  152. struct roam_offload_scan_rssi_params *roam_req)
  153. {
  154. wmi_buf_t buf = NULL;
  155. QDF_STATUS status;
  156. int len;
  157. uint8_t *buf_ptr;
  158. wmi_roam_scan_rssi_threshold_fixed_param *rssi_threshold_fp;
  159. wmi_roam_scan_extended_threshold_param *ext_thresholds = NULL;
  160. wmi_roam_earlystop_rssi_thres_param *early_stop_thresholds = NULL;
  161. wmi_roam_dense_thres_param *dense_thresholds = NULL;
  162. wmi_roam_bg_scan_roaming_param *bg_scan_params = NULL;
  163. len = sizeof(wmi_roam_scan_rssi_threshold_fixed_param);
  164. len += WMI_TLV_HDR_SIZE; /* TLV for ext_thresholds*/
  165. len += sizeof(wmi_roam_scan_extended_threshold_param);
  166. len += WMI_TLV_HDR_SIZE;
  167. len += sizeof(wmi_roam_earlystop_rssi_thres_param);
  168. len += WMI_TLV_HDR_SIZE; /* TLV for dense thresholds*/
  169. len += sizeof(wmi_roam_dense_thres_param);
  170. len += WMI_TLV_HDR_SIZE; /* TLV for BG Scan*/
  171. len += sizeof(wmi_roam_bg_scan_roaming_param);
  172. buf = wmi_buf_alloc(wmi_handle, len);
  173. if (!buf) {
  174. return QDF_STATUS_E_NOMEM;
  175. }
  176. buf_ptr = (uint8_t *) wmi_buf_data(buf);
  177. rssi_threshold_fp =
  178. (wmi_roam_scan_rssi_threshold_fixed_param *) buf_ptr;
  179. WMITLV_SET_HDR(&rssi_threshold_fp->tlv_header,
  180. WMITLV_TAG_STRUC_wmi_roam_scan_rssi_threshold_fixed_param,
  181. WMITLV_GET_STRUCT_TLVLEN
  182. (wmi_roam_scan_rssi_threshold_fixed_param));
  183. /* fill in threshold values */
  184. rssi_threshold_fp->vdev_id = roam_req->vdev_id;
  185. rssi_threshold_fp->roam_scan_rssi_thresh = roam_req->rssi_thresh;
  186. rssi_threshold_fp->roam_rssi_thresh_diff = roam_req->rssi_thresh_diff;
  187. rssi_threshold_fp->hirssi_scan_max_count =
  188. roam_req->hi_rssi_scan_max_count;
  189. rssi_threshold_fp->hirssi_scan_delta =
  190. roam_req->hi_rssi_scan_rssi_delta;
  191. rssi_threshold_fp->hirssi_upper_bound = roam_req->hi_rssi_scan_rssi_ub;
  192. rssi_threshold_fp->rssi_thresh_offset_5g =
  193. roam_req->rssi_thresh_offset_5g;
  194. buf_ptr += sizeof(wmi_roam_scan_rssi_threshold_fixed_param);
  195. WMITLV_SET_HDR(buf_ptr,
  196. WMITLV_TAG_ARRAY_STRUC,
  197. sizeof(wmi_roam_scan_extended_threshold_param));
  198. buf_ptr += WMI_TLV_HDR_SIZE;
  199. ext_thresholds = (wmi_roam_scan_extended_threshold_param *) buf_ptr;
  200. ext_thresholds->penalty_threshold_5g = roam_req->penalty_threshold_5g;
  201. if (roam_req->raise_rssi_thresh_5g >= WMI_NOISE_FLOOR_DBM_DEFAULT)
  202. ext_thresholds->boost_threshold_5g =
  203. roam_req->boost_threshold_5g;
  204. ext_thresholds->boost_algorithm_5g =
  205. WMI_ROAM_5G_BOOST_PENALIZE_ALGO_LINEAR;
  206. ext_thresholds->boost_factor_5g = roam_req->raise_factor_5g;
  207. ext_thresholds->penalty_algorithm_5g =
  208. WMI_ROAM_5G_BOOST_PENALIZE_ALGO_LINEAR;
  209. ext_thresholds->penalty_factor_5g = roam_req->drop_factor_5g;
  210. ext_thresholds->max_boost_5g = roam_req->max_raise_rssi_5g;
  211. ext_thresholds->max_penalty_5g = roam_req->max_drop_rssi_5g;
  212. ext_thresholds->good_rssi_threshold = roam_req->good_rssi_threshold;
  213. WMITLV_SET_HDR(&ext_thresholds->tlv_header,
  214. WMITLV_TAG_STRUC_wmi_roam_scan_extended_threshold_param,
  215. WMITLV_GET_STRUCT_TLVLEN
  216. (wmi_roam_scan_extended_threshold_param));
  217. buf_ptr += sizeof(wmi_roam_scan_extended_threshold_param);
  218. WMITLV_SET_HDR(buf_ptr,
  219. WMITLV_TAG_ARRAY_STRUC,
  220. sizeof(wmi_roam_earlystop_rssi_thres_param));
  221. buf_ptr += WMI_TLV_HDR_SIZE;
  222. early_stop_thresholds = (wmi_roam_earlystop_rssi_thres_param *) buf_ptr;
  223. early_stop_thresholds->roam_earlystop_thres_min =
  224. roam_req->roam_earlystop_thres_min;
  225. early_stop_thresholds->roam_earlystop_thres_max =
  226. roam_req->roam_earlystop_thres_max;
  227. WMITLV_SET_HDR(&early_stop_thresholds->tlv_header,
  228. WMITLV_TAG_STRUC_wmi_roam_earlystop_rssi_thres_param,
  229. WMITLV_GET_STRUCT_TLVLEN
  230. (wmi_roam_earlystop_rssi_thres_param));
  231. buf_ptr += sizeof(wmi_roam_earlystop_rssi_thres_param);
  232. WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
  233. sizeof(wmi_roam_dense_thres_param));
  234. buf_ptr += WMI_TLV_HDR_SIZE;
  235. dense_thresholds = (wmi_roam_dense_thres_param *) buf_ptr;
  236. dense_thresholds->roam_dense_rssi_thres_offset =
  237. roam_req->dense_rssi_thresh_offset;
  238. dense_thresholds->roam_dense_min_aps = roam_req->dense_min_aps_cnt;
  239. dense_thresholds->roam_dense_traffic_thres =
  240. roam_req->traffic_threshold;
  241. dense_thresholds->roam_dense_status = roam_req->initial_dense_status;
  242. WMITLV_SET_HDR(&dense_thresholds->tlv_header,
  243. WMITLV_TAG_STRUC_wmi_roam_dense_thres_param,
  244. WMITLV_GET_STRUCT_TLVLEN(wmi_roam_dense_thres_param));
  245. buf_ptr += sizeof(wmi_roam_dense_thres_param);
  246. WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
  247. sizeof(wmi_roam_bg_scan_roaming_param));
  248. buf_ptr += WMI_TLV_HDR_SIZE;
  249. bg_scan_params = (wmi_roam_bg_scan_roaming_param *) buf_ptr;
  250. bg_scan_params->roam_bg_scan_bad_rssi_thresh =
  251. roam_req->bg_scan_bad_rssi_thresh;
  252. bg_scan_params->roam_bg_scan_client_bitmap =
  253. roam_req->bg_scan_client_bitmap;
  254. bg_scan_params->bad_rssi_thresh_offset_2g =
  255. roam_req->roam_bad_rssi_thresh_offset_2g;
  256. bg_scan_params->flags = roam_req->flags;
  257. WMITLV_SET_HDR(&bg_scan_params->tlv_header,
  258. WMITLV_TAG_STRUC_wmi_roam_bg_scan_roaming_param,
  259. WMITLV_GET_STRUCT_TLVLEN
  260. (wmi_roam_bg_scan_roaming_param));
  261. wmi_mtrace(WMI_ROAM_SCAN_RSSI_THRESHOLD, NO_SESSION, 0);
  262. status = wmi_unified_cmd_send(wmi_handle, buf,
  263. len, WMI_ROAM_SCAN_RSSI_THRESHOLD);
  264. if (QDF_IS_STATUS_ERROR(status)) {
  265. WMI_LOGE("cmd WMI_ROAM_SCAN_RSSI_THRESHOLD returned Error %d",
  266. status);
  267. wmi_buf_free(buf);
  268. }
  269. return status;
  270. }
  271. static QDF_STATUS send_roam_mawc_params_cmd_tlv(wmi_unified_t wmi_handle,
  272. struct wmi_mawc_roam_params *params)
  273. {
  274. wmi_buf_t buf = NULL;
  275. QDF_STATUS status;
  276. int len;
  277. uint8_t *buf_ptr;
  278. wmi_roam_configure_mawc_cmd_fixed_param *wmi_roam_mawc_params;
  279. len = sizeof(*wmi_roam_mawc_params);
  280. buf = wmi_buf_alloc(wmi_handle, len);
  281. if (!buf) {
  282. return QDF_STATUS_E_NOMEM;
  283. }
  284. buf_ptr = (uint8_t *) wmi_buf_data(buf);
  285. wmi_roam_mawc_params =
  286. (wmi_roam_configure_mawc_cmd_fixed_param *) buf_ptr;
  287. WMITLV_SET_HDR(&wmi_roam_mawc_params->tlv_header,
  288. WMITLV_TAG_STRUC_wmi_roam_configure_mawc_cmd_fixed_param,
  289. WMITLV_GET_STRUCT_TLVLEN
  290. (wmi_roam_configure_mawc_cmd_fixed_param));
  291. wmi_roam_mawc_params->vdev_id = params->vdev_id;
  292. if (params->enable)
  293. wmi_roam_mawc_params->enable = 1;
  294. else
  295. wmi_roam_mawc_params->enable = 0;
  296. wmi_roam_mawc_params->traffic_load_threshold =
  297. params->traffic_load_threshold;
  298. wmi_roam_mawc_params->best_ap_rssi_threshold =
  299. params->best_ap_rssi_threshold;
  300. wmi_roam_mawc_params->rssi_stationary_high_adjust =
  301. params->rssi_stationary_high_adjust;
  302. wmi_roam_mawc_params->rssi_stationary_low_adjust =
  303. params->rssi_stationary_low_adjust;
  304. WMI_LOGD(FL("MAWC roam en=%d, vdev=%d, tr=%d, ap=%d, high=%d, low=%d"),
  305. wmi_roam_mawc_params->enable, wmi_roam_mawc_params->vdev_id,
  306. wmi_roam_mawc_params->traffic_load_threshold,
  307. wmi_roam_mawc_params->best_ap_rssi_threshold,
  308. wmi_roam_mawc_params->rssi_stationary_high_adjust,
  309. wmi_roam_mawc_params->rssi_stationary_low_adjust);
  310. wmi_mtrace(WMI_ROAM_CONFIGURE_MAWC_CMDID, NO_SESSION, 0);
  311. status = wmi_unified_cmd_send(wmi_handle, buf,
  312. len, WMI_ROAM_CONFIGURE_MAWC_CMDID);
  313. if (QDF_IS_STATUS_ERROR(status)) {
  314. WMI_LOGE("WMI_ROAM_CONFIGURE_MAWC_CMDID failed, Error %d",
  315. status);
  316. wmi_buf_free(buf);
  317. return status;
  318. }
  319. return QDF_STATUS_SUCCESS;
  320. }
  321. /**
  322. * send_roam_scan_filter_cmd_tlv() - Filter to be applied while roaming
  323. * @wmi_handle: wmi handle
  324. * @roam_req: Request which contains the filters
  325. *
  326. * There are filters such as whitelist, blacklist and preferred
  327. * list that need to be applied to the scan results to form the
  328. * probable candidates for roaming.
  329. *
  330. * Return: Return success upon successfully passing the
  331. * parameters to the firmware, otherwise failure.
  332. */
  333. static QDF_STATUS send_roam_scan_filter_cmd_tlv(wmi_unified_t wmi_handle,
  334. struct roam_scan_filter_params *roam_req)
  335. {
  336. wmi_buf_t buf = NULL;
  337. QDF_STATUS status;
  338. uint32_t i;
  339. uint32_t len, blist_len = 0;
  340. uint8_t *buf_ptr;
  341. wmi_roam_filter_fixed_param *roam_filter;
  342. uint8_t *bssid_src_ptr = NULL;
  343. wmi_mac_addr *bssid_dst_ptr = NULL;
  344. wmi_ssid *ssid_ptr = NULL;
  345. uint32_t *bssid_preferred_factor_ptr = NULL;
  346. wmi_roam_lca_disallow_config_tlv_param *blist_param;
  347. wmi_roam_rssi_rejection_oce_config_param *rssi_rej;
  348. len = sizeof(wmi_roam_filter_fixed_param);
  349. len += WMI_TLV_HDR_SIZE;
  350. if (roam_req->num_bssid_black_list)
  351. len += roam_req->num_bssid_black_list * sizeof(wmi_mac_addr);
  352. len += WMI_TLV_HDR_SIZE;
  353. if (roam_req->num_ssid_white_list)
  354. len += roam_req->num_ssid_white_list * sizeof(wmi_ssid);
  355. len += 2 * WMI_TLV_HDR_SIZE;
  356. if (roam_req->num_bssid_preferred_list) {
  357. len += roam_req->num_bssid_preferred_list * sizeof(wmi_mac_addr);
  358. len += roam_req->num_bssid_preferred_list * sizeof(uint32_t);
  359. }
  360. len += WMI_TLV_HDR_SIZE;
  361. if (roam_req->lca_disallow_config_present) {
  362. len += sizeof(*blist_param);
  363. blist_len = sizeof(*blist_param);
  364. }
  365. len += WMI_TLV_HDR_SIZE;
  366. if (roam_req->num_rssi_rejection_ap)
  367. len += roam_req->num_rssi_rejection_ap * sizeof(*rssi_rej);
  368. buf = wmi_buf_alloc(wmi_handle, len);
  369. if (!buf) {
  370. return QDF_STATUS_E_NOMEM;
  371. }
  372. buf_ptr = (u_int8_t *) wmi_buf_data(buf);
  373. roam_filter = (wmi_roam_filter_fixed_param *) buf_ptr;
  374. WMITLV_SET_HDR(&roam_filter->tlv_header,
  375. WMITLV_TAG_STRUC_wmi_roam_filter_fixed_param,
  376. WMITLV_GET_STRUCT_TLVLEN(wmi_roam_filter_fixed_param));
  377. /* fill in fixed values */
  378. roam_filter->vdev_id = roam_req->vdev_id;
  379. roam_filter->flags = 0;
  380. roam_filter->op_bitmap = roam_req->op_bitmap;
  381. roam_filter->num_bssid_black_list = roam_req->num_bssid_black_list;
  382. roam_filter->num_ssid_white_list = roam_req->num_ssid_white_list;
  383. roam_filter->num_bssid_preferred_list =
  384. roam_req->num_bssid_preferred_list;
  385. roam_filter->num_rssi_rejection_ap =
  386. roam_req->num_rssi_rejection_ap;
  387. roam_filter->delta_rssi = roam_req->delta_rssi;
  388. buf_ptr += sizeof(wmi_roam_filter_fixed_param);
  389. WMITLV_SET_HDR((buf_ptr),
  390. WMITLV_TAG_ARRAY_FIXED_STRUC,
  391. (roam_req->num_bssid_black_list * sizeof(wmi_mac_addr)));
  392. bssid_src_ptr = (uint8_t *)&roam_req->bssid_avoid_list;
  393. bssid_dst_ptr = (wmi_mac_addr *)(buf_ptr + WMI_TLV_HDR_SIZE);
  394. for (i = 0; i < roam_req->num_bssid_black_list; i++) {
  395. WMI_CHAR_ARRAY_TO_MAC_ADDR(bssid_src_ptr, bssid_dst_ptr);
  396. bssid_src_ptr += ATH_MAC_LEN;
  397. bssid_dst_ptr++;
  398. }
  399. buf_ptr += WMI_TLV_HDR_SIZE +
  400. (roam_req->num_bssid_black_list * sizeof(wmi_mac_addr));
  401. WMITLV_SET_HDR((buf_ptr),
  402. WMITLV_TAG_ARRAY_FIXED_STRUC,
  403. (roam_req->num_ssid_white_list * sizeof(wmi_ssid)));
  404. ssid_ptr = (wmi_ssid *)(buf_ptr + WMI_TLV_HDR_SIZE);
  405. for (i = 0; i < roam_req->num_ssid_white_list; i++) {
  406. qdf_mem_copy(&ssid_ptr->ssid,
  407. &roam_req->ssid_allowed_list[i].mac_ssid,
  408. roam_req->ssid_allowed_list[i].length);
  409. ssid_ptr->ssid_len = roam_req->ssid_allowed_list[i].length;
  410. ssid_ptr++;
  411. }
  412. buf_ptr += WMI_TLV_HDR_SIZE + (roam_req->num_ssid_white_list *
  413. sizeof(wmi_ssid));
  414. WMITLV_SET_HDR((buf_ptr),
  415. WMITLV_TAG_ARRAY_FIXED_STRUC,
  416. (roam_req->num_bssid_preferred_list * sizeof(wmi_mac_addr)));
  417. bssid_src_ptr = (uint8_t *)&roam_req->bssid_favored;
  418. bssid_dst_ptr = (wmi_mac_addr *)(buf_ptr + WMI_TLV_HDR_SIZE);
  419. for (i = 0; i < roam_req->num_bssid_preferred_list; i++) {
  420. WMI_CHAR_ARRAY_TO_MAC_ADDR(bssid_src_ptr,
  421. (wmi_mac_addr *)bssid_dst_ptr);
  422. bssid_src_ptr += ATH_MAC_LEN;
  423. bssid_dst_ptr++;
  424. }
  425. buf_ptr += WMI_TLV_HDR_SIZE +
  426. (roam_req->num_bssid_preferred_list * sizeof(wmi_mac_addr));
  427. WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32,
  428. (roam_req->num_bssid_preferred_list * sizeof(uint32_t)));
  429. bssid_preferred_factor_ptr = (uint32_t *)(buf_ptr + WMI_TLV_HDR_SIZE);
  430. for (i = 0; i < roam_req->num_bssid_preferred_list; i++) {
  431. *bssid_preferred_factor_ptr =
  432. roam_req->bssid_favored_factor[i];
  433. bssid_preferred_factor_ptr++;
  434. }
  435. buf_ptr += WMI_TLV_HDR_SIZE +
  436. (roam_req->num_bssid_preferred_list * sizeof(uint32_t));
  437. WMITLV_SET_HDR(buf_ptr,
  438. WMITLV_TAG_ARRAY_STRUC, blist_len);
  439. buf_ptr += WMI_TLV_HDR_SIZE;
  440. if (roam_req->lca_disallow_config_present) {
  441. blist_param =
  442. (wmi_roam_lca_disallow_config_tlv_param *) buf_ptr;
  443. WMITLV_SET_HDR(&blist_param->tlv_header,
  444. WMITLV_TAG_STRUC_wmi_roam_lca_disallow_config_tlv_param,
  445. WMITLV_GET_STRUCT_TLVLEN(
  446. wmi_roam_lca_disallow_config_tlv_param));
  447. blist_param->disallow_duration = roam_req->disallow_duration;
  448. blist_param->rssi_channel_penalization =
  449. roam_req->rssi_channel_penalization;
  450. blist_param->num_disallowed_aps = roam_req->num_disallowed_aps;
  451. blist_param->disallow_lca_enable_source_bitmap =
  452. (WMI_ROAM_LCA_DISALLOW_SOURCE_PER |
  453. WMI_ROAM_LCA_DISALLOW_SOURCE_BACKGROUND);
  454. buf_ptr += (sizeof(wmi_roam_lca_disallow_config_tlv_param));
  455. }
  456. WMITLV_SET_HDR(buf_ptr,
  457. WMITLV_TAG_ARRAY_STRUC,
  458. (roam_req->num_rssi_rejection_ap * sizeof(*rssi_rej)));
  459. buf_ptr += WMI_TLV_HDR_SIZE;
  460. for (i = 0; i < roam_req->num_rssi_rejection_ap; i++) {
  461. rssi_rej =
  462. (wmi_roam_rssi_rejection_oce_config_param *) buf_ptr;
  463. WMITLV_SET_HDR(&rssi_rej->tlv_header,
  464. WMITLV_TAG_STRUC_wmi_roam_rssi_rejection_oce_config_param,
  465. WMITLV_GET_STRUCT_TLVLEN(
  466. wmi_roam_rssi_rejection_oce_config_param));
  467. WMI_CHAR_ARRAY_TO_MAC_ADDR(
  468. roam_req->rssi_rejection_ap[i].bssid.bytes,
  469. &rssi_rej->bssid);
  470. rssi_rej->remaining_disallow_duration =
  471. roam_req->rssi_rejection_ap[i].reject_duration;
  472. rssi_rej->requested_rssi =
  473. (int32_t)roam_req->rssi_rejection_ap[i].expected_rssi;
  474. buf_ptr +=
  475. (sizeof(wmi_roam_rssi_rejection_oce_config_param));
  476. }
  477. wmi_mtrace(WMI_ROAM_FILTER_CMDID, NO_SESSION, 0);
  478. status = wmi_unified_cmd_send(wmi_handle, buf,
  479. len, WMI_ROAM_FILTER_CMDID);
  480. if (QDF_IS_STATUS_ERROR(status)) {
  481. WMI_LOGE("cmd WMI_ROAM_FILTER_CMDID returned Error %d",
  482. status);
  483. wmi_buf_free(buf);
  484. }
  485. return status;
  486. }
  487. #ifdef FEATURE_WLAN_ESE
  488. /**
  489. * send_plm_stop_cmd_tlv() - plm stop request
  490. * @wmi_handle: wmi handle
  491. * @plm: plm request parameters
  492. *
  493. * This function request FW to stop PLM.
  494. *
  495. * Return: CDF status
  496. */
  497. static QDF_STATUS send_plm_stop_cmd_tlv(wmi_unified_t wmi_handle,
  498. const struct plm_req_params *plm)
  499. {
  500. wmi_vdev_plmreq_stop_cmd_fixed_param *cmd;
  501. int32_t len;
  502. wmi_buf_t buf;
  503. uint8_t *buf_ptr;
  504. int ret;
  505. len = sizeof(*cmd);
  506. buf = wmi_buf_alloc(wmi_handle, len);
  507. if (!buf) {
  508. return QDF_STATUS_E_NOMEM;
  509. }
  510. cmd = (wmi_vdev_plmreq_stop_cmd_fixed_param *) wmi_buf_data(buf);
  511. buf_ptr = (uint8_t *) cmd;
  512. WMITLV_SET_HDR(&cmd->tlv_header,
  513. WMITLV_TAG_STRUC_wmi_vdev_plmreq_stop_cmd_fixed_param,
  514. WMITLV_GET_STRUCT_TLVLEN
  515. (wmi_vdev_plmreq_stop_cmd_fixed_param));
  516. cmd->vdev_id = plm->vdev_id;
  517. cmd->meas_token = plm->meas_token;
  518. WMI_LOGD("vdev %d meas token %d", cmd->vdev_id, cmd->meas_token);
  519. wmi_mtrace(WMI_VDEV_PLMREQ_STOP_CMDID, cmd->vdev_id, 0);
  520. ret = wmi_unified_cmd_send(wmi_handle, buf, len,
  521. WMI_VDEV_PLMREQ_STOP_CMDID);
  522. if (ret) {
  523. WMI_LOGE("%s: Failed to send plm stop wmi cmd", __func__);
  524. wmi_buf_free(buf);
  525. return QDF_STATUS_E_FAILURE;
  526. }
  527. return QDF_STATUS_SUCCESS;
  528. }
  529. /**
  530. * send_plm_start_cmd_tlv() - plm start request
  531. * @wmi_handle: wmi handle
  532. * @plm: plm request parameters
  533. *
  534. * This function request FW to start PLM.
  535. *
  536. * Return: CDF status
  537. */
  538. static QDF_STATUS send_plm_start_cmd_tlv(wmi_unified_t wmi_handle,
  539. const struct plm_req_params *plm)
  540. {
  541. wmi_vdev_plmreq_start_cmd_fixed_param *cmd;
  542. uint32_t *channel_list;
  543. int32_t len;
  544. wmi_buf_t buf;
  545. uint8_t *buf_ptr;
  546. uint8_t count;
  547. int ret;
  548. /* TLV place holder for channel_list */
  549. len = sizeof(*cmd) + WMI_TLV_HDR_SIZE;
  550. len += sizeof(uint32_t) * plm->plm_num_ch;
  551. buf = wmi_buf_alloc(wmi_handle, len);
  552. if (!buf) {
  553. return QDF_STATUS_E_NOMEM;
  554. }
  555. cmd = (wmi_vdev_plmreq_start_cmd_fixed_param *) wmi_buf_data(buf);
  556. buf_ptr = (uint8_t *) cmd;
  557. WMITLV_SET_HDR(&cmd->tlv_header,
  558. WMITLV_TAG_STRUC_wmi_vdev_plmreq_start_cmd_fixed_param,
  559. WMITLV_GET_STRUCT_TLVLEN
  560. (wmi_vdev_plmreq_start_cmd_fixed_param));
  561. cmd->vdev_id = plm->vdev_id;
  562. cmd->meas_token = plm->meas_token;
  563. cmd->dialog_token = plm->diag_token;
  564. cmd->number_bursts = plm->num_bursts;
  565. cmd->burst_interval = WMI_SEC_TO_MSEC(plm->burst_int);
  566. cmd->off_duration = plm->meas_duration;
  567. cmd->burst_cycle = plm->burst_len;
  568. cmd->tx_power = plm->desired_tx_pwr;
  569. WMI_CHAR_ARRAY_TO_MAC_ADDR(plm->mac_addr.bytes, &cmd->dest_mac);
  570. cmd->num_chans = plm->plm_num_ch;
  571. buf_ptr += sizeof(wmi_vdev_plmreq_start_cmd_fixed_param);
  572. WMI_LOGD("vdev : %d measu token : %d", cmd->vdev_id, cmd->meas_token);
  573. WMI_LOGD("dialog_token: %d", cmd->dialog_token);
  574. WMI_LOGD("number_bursts: %d", cmd->number_bursts);
  575. WMI_LOGD("burst_interval: %d", cmd->burst_interval);
  576. WMI_LOGD("off_duration: %d", cmd->off_duration);
  577. WMI_LOGD("burst_cycle: %d", cmd->burst_cycle);
  578. WMI_LOGD("tx_power: %d", cmd->tx_power);
  579. WMI_LOGD("Number of channels : %d", cmd->num_chans);
  580. WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32,
  581. (cmd->num_chans * sizeof(uint32_t)));
  582. buf_ptr += WMI_TLV_HDR_SIZE;
  583. if (cmd->num_chans) {
  584. channel_list = (uint32_t *) buf_ptr;
  585. for (count = 0; count < cmd->num_chans; count++) {
  586. channel_list[count] = plm->plm_ch_freq_list[count];
  587. WMI_LOGD("Ch[%d]: %d MHz", count, channel_list[count]);
  588. }
  589. buf_ptr += cmd->num_chans * sizeof(uint32_t);
  590. }
  591. wmi_mtrace(WMI_VDEV_PLMREQ_START_CMDID, cmd->vdev_id, 0);
  592. ret = wmi_unified_cmd_send(wmi_handle, buf, len,
  593. WMI_VDEV_PLMREQ_START_CMDID);
  594. if (ret) {
  595. WMI_LOGE("%s: Failed to send plm start wmi cmd", __func__);
  596. wmi_buf_free(buf);
  597. return QDF_STATUS_E_FAILURE;
  598. }
  599. return QDF_STATUS_SUCCESS;
  600. }
  601. void wmi_ese_attach_tlv(wmi_unified_t wmi_handle)
  602. {
  603. struct wmi_ops *ops = wmi_handle->ops;
  604. ops->send_plm_stop_cmd = send_plm_stop_cmd_tlv;
  605. ops->send_plm_start_cmd = send_plm_start_cmd_tlv;
  606. }
  607. #endif /* FEATURE_WLAN_ESE */
  608. #ifdef WLAN_FEATURE_ROAM_OFFLOAD
  609. /* send_set_ric_req_cmd_tlv() - set ric request element
  610. * @wmi_handle: wmi handle
  611. * @msg: message
  612. * @is_add_ts: is addts required
  613. *
  614. * This function sets ric request element for 11r roaming.
  615. *
  616. * Return: CDF status
  617. */
  618. static QDF_STATUS send_set_ric_req_cmd_tlv(wmi_unified_t wmi_handle,
  619. void *msg, uint8_t is_add_ts)
  620. {
  621. wmi_ric_request_fixed_param *cmd;
  622. wmi_ric_tspec *tspec_param;
  623. wmi_buf_t buf;
  624. uint8_t *buf_ptr;
  625. struct mac_tspec_ie *tspec_ie = NULL;
  626. int32_t len = sizeof(wmi_ric_request_fixed_param) +
  627. WMI_TLV_HDR_SIZE + sizeof(wmi_ric_tspec);
  628. buf = wmi_buf_alloc(wmi_handle, len);
  629. if (!buf) {
  630. return QDF_STATUS_E_NOMEM;
  631. }
  632. buf_ptr = (uint8_t *) wmi_buf_data(buf);
  633. cmd = (wmi_ric_request_fixed_param *) buf_ptr;
  634. WMITLV_SET_HDR(&cmd->tlv_header,
  635. WMITLV_TAG_STRUC_wmi_ric_request_fixed_param,
  636. WMITLV_GET_STRUCT_TLVLEN(wmi_ric_request_fixed_param));
  637. if (is_add_ts)
  638. cmd->vdev_id = ((struct add_ts_param *)msg)->vdev_id;
  639. else
  640. cmd->vdev_id = ((struct del_ts_params *)msg)->sessionId;
  641. cmd->num_ric_request = 1;
  642. cmd->is_add_ric = is_add_ts;
  643. buf_ptr += sizeof(wmi_ric_request_fixed_param);
  644. WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, sizeof(wmi_ric_tspec));
  645. buf_ptr += WMI_TLV_HDR_SIZE;
  646. tspec_param = (wmi_ric_tspec *) buf_ptr;
  647. WMITLV_SET_HDR(&tspec_param->tlv_header,
  648. WMITLV_TAG_STRUC_wmi_ric_tspec,
  649. WMITLV_GET_STRUCT_TLVLEN(wmi_ric_tspec));
  650. if (is_add_ts)
  651. tspec_ie = &(((struct add_ts_param *) msg)->tspec);
  652. else
  653. tspec_ie = &(((struct del_ts_params *) msg)->delTsInfo.tspec);
  654. if (tspec_ie) {
  655. /* Fill the tsinfo in the format expected by firmware */
  656. #ifndef ANI_LITTLE_BIT_ENDIAN
  657. qdf_mem_copy(((uint8_t *) &tspec_param->ts_info) + 1,
  658. ((uint8_t *) &tspec_ie->tsinfo) + 1, 2);
  659. #else
  660. qdf_mem_copy(((uint8_t *) &tspec_param->ts_info),
  661. ((uint8_t *) &tspec_ie->tsinfo) + 1, 2);
  662. #endif /* ANI_LITTLE_BIT_ENDIAN */
  663. tspec_param->nominal_msdu_size = tspec_ie->nomMsduSz;
  664. tspec_param->maximum_msdu_size = tspec_ie->maxMsduSz;
  665. tspec_param->min_service_interval = tspec_ie->minSvcInterval;
  666. tspec_param->max_service_interval = tspec_ie->maxSvcInterval;
  667. tspec_param->inactivity_interval = tspec_ie->inactInterval;
  668. tspec_param->suspension_interval = tspec_ie->suspendInterval;
  669. tspec_param->svc_start_time = tspec_ie->svcStartTime;
  670. tspec_param->min_data_rate = tspec_ie->minDataRate;
  671. tspec_param->mean_data_rate = tspec_ie->meanDataRate;
  672. tspec_param->peak_data_rate = tspec_ie->peakDataRate;
  673. tspec_param->max_burst_size = tspec_ie->maxBurstSz;
  674. tspec_param->delay_bound = tspec_ie->delayBound;
  675. tspec_param->min_phy_rate = tspec_ie->minPhyRate;
  676. tspec_param->surplus_bw_allowance = tspec_ie->surplusBw;
  677. tspec_param->medium_time = 0;
  678. }
  679. WMI_LOGI("%s: Set RIC Req is_add_ts:%d", __func__, is_add_ts);
  680. wmi_mtrace(WMI_ROAM_SET_RIC_REQUEST_CMDID, cmd->vdev_id, 0);
  681. if (wmi_unified_cmd_send(wmi_handle, buf, len,
  682. WMI_ROAM_SET_RIC_REQUEST_CMDID)) {
  683. WMI_LOGP("%s: Failed to send vdev Set RIC Req command",
  684. __func__);
  685. if (is_add_ts)
  686. ((struct add_ts_param *) msg)->status =
  687. QDF_STATUS_E_FAILURE;
  688. wmi_buf_free(buf);
  689. return QDF_STATUS_E_FAILURE;
  690. }
  691. return QDF_STATUS_SUCCESS;
  692. }
  693. /**
  694. * send_process_roam_synch_complete_cmd_tlv() - roam synch complete command to fw.
  695. * @wmi_handle: wmi handle
  696. * @vdev_id: vdev id
  697. *
  698. * This function sends roam synch complete event to fw.
  699. *
  700. * Return: CDF STATUS
  701. */
  702. static QDF_STATUS send_process_roam_synch_complete_cmd_tlv(wmi_unified_t wmi_handle,
  703. uint8_t vdev_id)
  704. {
  705. wmi_roam_synch_complete_fixed_param *cmd;
  706. wmi_buf_t wmi_buf;
  707. uint8_t *buf_ptr;
  708. uint16_t len;
  709. len = sizeof(wmi_roam_synch_complete_fixed_param);
  710. wmi_buf = wmi_buf_alloc(wmi_handle, len);
  711. if (!wmi_buf) {
  712. return QDF_STATUS_E_NOMEM;
  713. }
  714. cmd = (wmi_roam_synch_complete_fixed_param *) wmi_buf_data(wmi_buf);
  715. buf_ptr = (uint8_t *) cmd;
  716. WMITLV_SET_HDR(&cmd->tlv_header,
  717. WMITLV_TAG_STRUC_wmi_roam_synch_complete_fixed_param,
  718. WMITLV_GET_STRUCT_TLVLEN
  719. (wmi_roam_synch_complete_fixed_param));
  720. cmd->vdev_id = vdev_id;
  721. wmi_mtrace(WMI_ROAM_SYNCH_COMPLETE, cmd->vdev_id, 0);
  722. if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
  723. WMI_ROAM_SYNCH_COMPLETE)) {
  724. WMI_LOGP("%s: failed to send roam synch confirmation",
  725. __func__);
  726. wmi_buf_free(wmi_buf);
  727. return QDF_STATUS_E_FAILURE;
  728. }
  729. return QDF_STATUS_SUCCESS;
  730. }
  731. /**
  732. * send_roam_invoke_cmd_tlv() - send roam invoke command to fw.
  733. * @wmi_handle: wma handle
  734. * @roaminvoke: roam invoke command
  735. *
  736. * Send roam invoke command to fw for fastreassoc.
  737. *
  738. * Return: CDF STATUS
  739. */
  740. static QDF_STATUS send_roam_invoke_cmd_tlv(wmi_unified_t wmi_handle,
  741. struct wmi_roam_invoke_cmd *roaminvoke,
  742. uint32_t ch_hz)
  743. {
  744. wmi_roam_invoke_cmd_fixed_param *cmd;
  745. wmi_buf_t wmi_buf;
  746. u_int8_t *buf_ptr;
  747. u_int16_t len, args_tlv_len;
  748. uint32_t *channel_list;
  749. wmi_mac_addr *bssid_list;
  750. wmi_tlv_buf_len_param *buf_len_tlv;
  751. args_tlv_len = (4 * WMI_TLV_HDR_SIZE) + sizeof(uint32_t) +
  752. sizeof(wmi_mac_addr) + sizeof(wmi_tlv_buf_len_param) +
  753. roundup(roaminvoke->frame_len, sizeof(uint32_t));
  754. len = sizeof(wmi_roam_invoke_cmd_fixed_param) + args_tlv_len;
  755. wmi_buf = wmi_buf_alloc(wmi_handle, len);
  756. if (!wmi_buf) {
  757. return QDF_STATUS_E_NOMEM;
  758. }
  759. cmd = (wmi_roam_invoke_cmd_fixed_param *)wmi_buf_data(wmi_buf);
  760. buf_ptr = (u_int8_t *) cmd;
  761. WMITLV_SET_HDR(&cmd->tlv_header,
  762. WMITLV_TAG_STRUC_wmi_roam_invoke_cmd_fixed_param,
  763. WMITLV_GET_STRUCT_TLVLEN(wmi_roam_invoke_cmd_fixed_param));
  764. cmd->vdev_id = roaminvoke->vdev_id;
  765. cmd->flags |= (1 << WMI_ROAM_INVOKE_FLAG_REPORT_FAILURE);
  766. if (roaminvoke->is_same_bssid)
  767. cmd->flags |= (1 << WMI_ROAM_INVOKE_FLAG_NO_NULL_FRAME_TO_AP);
  768. if (roaminvoke->frame_len) {
  769. cmd->roam_scan_mode = WMI_ROAM_INVOKE_SCAN_MODE_SKIP;
  770. /* packing 1 beacon/probe_rsp frame with WMI cmd */
  771. cmd->num_buf = 1;
  772. } else {
  773. cmd->roam_scan_mode = WMI_ROAM_INVOKE_SCAN_MODE_FIXED_CH;
  774. cmd->num_buf = 0;
  775. }
  776. cmd->roam_ap_sel_mode = 0;
  777. cmd->roam_delay = 0;
  778. cmd->num_chan = 1;
  779. cmd->num_bssid = 1;
  780. if (roaminvoke->forced_roaming) {
  781. cmd->num_chan = 0;
  782. cmd->num_bssid = 0;
  783. cmd->roam_scan_mode = WMI_ROAM_INVOKE_SCAN_MODE_CACHE_MAP;
  784. }
  785. buf_ptr += sizeof(wmi_roam_invoke_cmd_fixed_param);
  786. WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32,
  787. (sizeof(u_int32_t)));
  788. channel_list = (uint32_t *)(buf_ptr + WMI_TLV_HDR_SIZE);
  789. *channel_list = ch_hz;
  790. buf_ptr += sizeof(uint32_t) + WMI_TLV_HDR_SIZE;
  791. WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC,
  792. (sizeof(wmi_mac_addr)));
  793. bssid_list = (wmi_mac_addr *)(buf_ptr + WMI_TLV_HDR_SIZE);
  794. WMI_CHAR_ARRAY_TO_MAC_ADDR(roaminvoke->bssid, bssid_list);
  795. /* move to next tlv i.e. bcn_prb_buf_list */
  796. buf_ptr += WMI_TLV_HDR_SIZE + sizeof(wmi_mac_addr);
  797. WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC,
  798. sizeof(wmi_tlv_buf_len_param));
  799. buf_len_tlv = (wmi_tlv_buf_len_param *)(buf_ptr + WMI_TLV_HDR_SIZE);
  800. buf_len_tlv->buf_len = roaminvoke->frame_len;
  801. /* move to next tlv i.e. bcn_prb_frm */
  802. buf_ptr += WMI_TLV_HDR_SIZE + sizeof(wmi_tlv_buf_len_param);
  803. WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE,
  804. roundup(roaminvoke->frame_len, sizeof(uint32_t)));
  805. /* copy frame after the header */
  806. qdf_mem_copy(buf_ptr + WMI_TLV_HDR_SIZE,
  807. roaminvoke->frame_buf,
  808. roaminvoke->frame_len);
  809. WMI_LOGD(FL("flag:%d, MODE scn:%d, ap:%d, dly:%d, n_ch:%d, n_bssid:%d, channel:%d, is_same_bssid:%d"),
  810. cmd->flags, cmd->roam_scan_mode,
  811. cmd->roam_ap_sel_mode, cmd->roam_delay,
  812. cmd->num_chan, cmd->num_bssid, ch_hz,
  813. roaminvoke->is_same_bssid);
  814. wmi_mtrace(WMI_ROAM_INVOKE_CMDID, cmd->vdev_id, 0);
  815. if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
  816. WMI_ROAM_INVOKE_CMDID)) {
  817. WMI_LOGP("%s: failed to send roam invoke command", __func__);
  818. wmi_buf_free(wmi_buf);
  819. return QDF_STATUS_E_FAILURE;
  820. }
  821. return QDF_STATUS_SUCCESS;
  822. }
  823. void wmi_roam_offload_attach_tlv(wmi_unified_t wmi_handle)
  824. {
  825. struct wmi_ops *ops = wmi_handle->ops;
  826. ops->send_set_ric_req_cmd = send_set_ric_req_cmd_tlv;
  827. ops->send_process_roam_synch_complete_cmd =
  828. send_process_roam_synch_complete_cmd_tlv;
  829. ops->send_roam_invoke_cmd = send_roam_invoke_cmd_tlv;
  830. }
  831. #endif /* WLAN_FEATURE_ROAM_OFFLOAD */
  832. #if defined(WLAN_FEATURE_FILS_SK) && defined(WLAN_FEATURE_ROAM_OFFLOAD)
  833. /**
  834. * wmi_add_fils_tlv() - Add FILS TLV to roam scan offload command
  835. * @wmi_handle: wmi handle
  836. * @roam_req: Roam scan offload params
  837. * @buf_ptr: command buffer to send
  838. * @fils_tlv_len: fils tlv length
  839. *
  840. * Return: Updated buffer pointer
  841. */
  842. static uint8_t *wmi_add_fils_tlv(wmi_unified_t wmi_handle,
  843. struct roam_offload_scan_params *roam_req,
  844. uint8_t *buf_ptr, uint32_t fils_tlv_len)
  845. {
  846. wmi_roam_fils_offload_tlv_param *fils_tlv;
  847. wmi_erp_info *erp_info;
  848. struct roam_fils_params *roam_fils_params;
  849. if (!roam_req->add_fils_tlv)
  850. return buf_ptr;
  851. WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
  852. sizeof(*fils_tlv));
  853. buf_ptr += WMI_TLV_HDR_SIZE;
  854. fils_tlv = (wmi_roam_fils_offload_tlv_param *)buf_ptr;
  855. WMITLV_SET_HDR(&fils_tlv->tlv_header,
  856. WMITLV_TAG_STRUC_wmi_roam_fils_offload_tlv_param,
  857. WMITLV_GET_STRUCT_TLVLEN
  858. (wmi_roam_fils_offload_tlv_param));
  859. roam_fils_params = &roam_req->roam_fils_params;
  860. erp_info = (wmi_erp_info *)(&fils_tlv->vdev_erp_info);
  861. erp_info->username_length = roam_fils_params->username_length;
  862. qdf_mem_copy(erp_info->username, roam_fils_params->username,
  863. erp_info->username_length);
  864. erp_info->next_erp_seq_num = roam_fils_params->next_erp_seq_num;
  865. erp_info->rRk_length = roam_fils_params->rrk_length;
  866. qdf_mem_copy(erp_info->rRk, roam_fils_params->rrk,
  867. erp_info->rRk_length);
  868. erp_info->rIk_length = roam_fils_params->rik_length;
  869. qdf_mem_copy(erp_info->rIk, roam_fils_params->rik,
  870. erp_info->rIk_length);
  871. erp_info->realm_len = roam_fils_params->realm_len;
  872. qdf_mem_copy(erp_info->realm, roam_fils_params->realm,
  873. erp_info->realm_len);
  874. buf_ptr += sizeof(*fils_tlv);
  875. return buf_ptr;
  876. }
  877. #else
  878. static inline uint8_t *wmi_add_fils_tlv(wmi_unified_t wmi_handle,
  879. struct roam_offload_scan_params *roam_req,
  880. uint8_t *buf_ptr, uint32_t fils_tlv_len)
  881. {
  882. return buf_ptr;
  883. }
  884. #endif
  885. #ifdef WLAN_FEATURE_ROAM_OFFLOAD
  886. /**
  887. * fill_roam_offload_11r_params() - Fill roam scan params to send it to fw
  888. * @auth_mode: Authentication mode
  889. * @roam_offload_11r: TLV to be filled with 11r params
  890. * @roam_req: roam request param
  891. */
  892. static void
  893. fill_roam_offload_11r_params(uint32_t auth_mode,
  894. wmi_roam_11r_offload_tlv_param *roam_offload_11r,
  895. struct roam_offload_scan_params *roam_req)
  896. {
  897. uint8_t *psk_msk, len;
  898. if (auth_mode == WMI_AUTH_FT_RSNA_FILS_SHA256 ||
  899. auth_mode == WMI_AUTH_FT_RSNA_FILS_SHA384) {
  900. psk_msk = roam_req->roam_fils_params.fils_ft;
  901. len = roam_req->roam_fils_params.fils_ft_len;
  902. } else {
  903. psk_msk = roam_req->psk_pmk;
  904. len = roam_req->pmk_len;
  905. }
  906. /*
  907. * For SHA384 based akm, the pmk length is 48 bytes. So fill
  908. * first 32 bytes in roam_offload_11r->psk_msk and the remaining
  909. * bytes in roam_offload_11r->psk_msk_ext buffer
  910. */
  911. roam_offload_11r->psk_msk_len = len > ROAM_OFFLOAD_PSK_MSK_BYTES ?
  912. ROAM_OFFLOAD_PSK_MSK_BYTES : len;
  913. qdf_mem_copy(roam_offload_11r->psk_msk, psk_msk,
  914. roam_offload_11r->psk_msk_len);
  915. roam_offload_11r->psk_msk_ext_len = 0;
  916. if (len > ROAM_OFFLOAD_PSK_MSK_BYTES) {
  917. roam_offload_11r->psk_msk_ext_len =
  918. len - roam_offload_11r->psk_msk_len;
  919. qdf_mem_copy(roam_offload_11r->psk_msk_ext,
  920. &psk_msk[roam_offload_11r->psk_msk_len],
  921. roam_offload_11r->psk_msk_ext_len);
  922. }
  923. }
  924. /**
  925. * wmi_fill_sae_single_pmk_param() - Fill sae single pmk flag to indicate fw to
  926. * use same PMKID for WPA3 SAE roaming.
  927. * @params: roam request param
  928. * @roam_offload_11i: pointer to 11i params
  929. *
  930. * Return: None
  931. */
  932. static inline void
  933. wmi_fill_sae_single_pmk_param(struct roam_offload_scan_params *params,
  934. wmi_roam_11i_offload_tlv_param *roam_offload_11i)
  935. {
  936. if (params->is_sae_same_pmk)
  937. roam_offload_11i->flags |=
  938. 1 << WMI_ROAM_OFFLOAD_FLAG_SAE_SAME_PMKID;
  939. }
  940. #else
  941. static inline void
  942. wmi_fill_sae_single_pmk_param(struct roam_offload_scan_params *params,
  943. wmi_roam_11i_offload_tlv_param *roam_offload_11i)
  944. {
  945. }
  946. #endif
  947. /**
  948. * send_roam_scan_offload_mode_cmd_tlv() - send roam scan mode request to fw
  949. * @wmi_handle: wmi handle
  950. * @scan_cmd_fp: start scan command ptr
  951. * @roam_req: roam request param
  952. *
  953. * send WMI_ROAM_SCAN_MODE TLV to firmware. It has a piggyback
  954. * of WMI_ROAM_SCAN_MODE.
  955. *
  956. * Return: QDF status
  957. */
  958. static QDF_STATUS
  959. send_roam_scan_offload_mode_cmd_tlv(wmi_unified_t wmi_handle,
  960. wmi_start_scan_cmd_fixed_param *scan_cmd_fp,
  961. struct roam_offload_scan_params *roam_req)
  962. {
  963. wmi_buf_t buf = NULL;
  964. QDF_STATUS status;
  965. int len;
  966. uint8_t *buf_ptr;
  967. wmi_roam_scan_mode_fixed_param *roam_scan_mode_fp;
  968. #ifdef WLAN_FEATURE_ROAM_OFFLOAD
  969. int auth_mode = roam_req->auth_mode;
  970. roam_offload_param *req_offload_params =
  971. &roam_req->roam_offload_params;
  972. wmi_roam_offload_tlv_param *roam_offload_params;
  973. wmi_roam_11i_offload_tlv_param *roam_offload_11i;
  974. wmi_roam_11r_offload_tlv_param *roam_offload_11r;
  975. wmi_roam_ese_offload_tlv_param *roam_offload_ese;
  976. wmi_tlv_buf_len_param *assoc_ies;
  977. uint32_t fils_tlv_len = 0;
  978. #endif /* WLAN_FEATURE_ROAM_OFFLOAD */
  979. /* Need to create a buf with roam_scan command at
  980. * front and piggyback with scan command */
  981. len = sizeof(wmi_roam_scan_mode_fixed_param) +
  982. #ifdef WLAN_FEATURE_ROAM_OFFLOAD
  983. (2 * WMI_TLV_HDR_SIZE) +
  984. #endif /* WLAN_FEATURE_ROAM_OFFLOAD */
  985. sizeof(wmi_start_scan_cmd_fixed_param);
  986. #ifdef WLAN_FEATURE_ROAM_OFFLOAD
  987. wmi_debug("auth_mode = %d", auth_mode);
  988. if (roam_req->is_roam_req_valid &&
  989. roam_req->roam_offload_enabled) {
  990. len += sizeof(wmi_roam_offload_tlv_param);
  991. len += WMI_TLV_HDR_SIZE;
  992. if ((auth_mode != WMI_AUTH_NONE) &&
  993. ((auth_mode != WMI_AUTH_OPEN) ||
  994. (auth_mode == WMI_AUTH_OPEN &&
  995. roam_req->mdid.mdie_present &&
  996. roam_req->is_11r_assoc) ||
  997. roam_req->is_ese_assoc)) {
  998. len += WMI_TLV_HDR_SIZE;
  999. if (roam_req->is_ese_assoc)
  1000. len += sizeof(wmi_roam_ese_offload_tlv_param);
  1001. else if ((auth_mode == WMI_AUTH_FT_RSNA) ||
  1002. (auth_mode == WMI_AUTH_FT_RSNA_PSK) ||
  1003. (auth_mode == WMI_AUTH_FT_RSNA_SAE) ||
  1004. (auth_mode ==
  1005. WMI_AUTH_FT_RSNA_SUITE_B_8021X_SHA384) ||
  1006. (auth_mode ==
  1007. WMI_AUTH_FT_RSNA_FILS_SHA256) ||
  1008. (auth_mode ==
  1009. WMI_AUTH_FT_RSNA_FILS_SHA384) ||
  1010. (auth_mode == WMI_AUTH_OPEN &&
  1011. roam_req->mdid.mdie_present &&
  1012. roam_req->is_11r_assoc))
  1013. len += sizeof(wmi_roam_11r_offload_tlv_param);
  1014. else
  1015. len += sizeof(wmi_roam_11i_offload_tlv_param);
  1016. } else {
  1017. len += WMI_TLV_HDR_SIZE;
  1018. }
  1019. len += (sizeof(*assoc_ies) + (2*WMI_TLV_HDR_SIZE)
  1020. + roundup(roam_req->assoc_ie_length, sizeof(uint32_t)));
  1021. if (roam_req->add_fils_tlv) {
  1022. fils_tlv_len = sizeof(wmi_roam_fils_offload_tlv_param);
  1023. len += WMI_TLV_HDR_SIZE + fils_tlv_len;
  1024. }
  1025. } else {
  1026. if (roam_req->is_roam_req_valid)
  1027. WMI_LOGD("%s : roam offload = %d", __func__,
  1028. roam_req->roam_offload_enabled);
  1029. len += (4 * WMI_TLV_HDR_SIZE);
  1030. }
  1031. if (roam_req->is_roam_req_valid && roam_req->roam_offload_enabled)
  1032. roam_req->mode |= WMI_ROAM_SCAN_MODE_ROAMOFFLOAD;
  1033. #endif /* WLAN_FEATURE_ROAM_OFFLOAD */
  1034. if (roam_req->mode ==
  1035. (WMI_ROAM_SCAN_MODE_NONE | WMI_ROAM_SCAN_MODE_ROAMOFFLOAD))
  1036. len = sizeof(wmi_roam_scan_mode_fixed_param);
  1037. buf = wmi_buf_alloc(wmi_handle, len);
  1038. if (!buf)
  1039. return QDF_STATUS_E_NOMEM;
  1040. buf_ptr = (uint8_t *) wmi_buf_data(buf);
  1041. roam_scan_mode_fp = (wmi_roam_scan_mode_fixed_param *) buf_ptr;
  1042. WMITLV_SET_HDR(&roam_scan_mode_fp->tlv_header,
  1043. WMITLV_TAG_STRUC_wmi_roam_scan_mode_fixed_param,
  1044. WMITLV_GET_STRUCT_TLVLEN(wmi_roam_scan_mode_fixed_param));
  1045. roam_scan_mode_fp->min_delay_roam_trigger_reason_bitmask =
  1046. roam_req->roam_trigger_reason_bitmask;
  1047. roam_scan_mode_fp->min_delay_btw_scans =
  1048. WMI_SEC_TO_MSEC(roam_req->min_delay_btw_roam_scans);
  1049. roam_scan_mode_fp->roam_scan_mode = roam_req->mode;
  1050. roam_scan_mode_fp->vdev_id = roam_req->vdev_id;
  1051. if (roam_req->mode ==
  1052. (WMI_ROAM_SCAN_MODE_NONE | WMI_ROAM_SCAN_MODE_ROAMOFFLOAD)) {
  1053. roam_scan_mode_fp->flags |=
  1054. WMI_ROAM_SCAN_MODE_FLAG_REPORT_STATUS;
  1055. goto send_roam_scan_mode_cmd;
  1056. }
  1057. /* Fill in scan parameters suitable for roaming scan */
  1058. buf_ptr += sizeof(wmi_roam_scan_mode_fixed_param);
  1059. qdf_mem_copy(buf_ptr, scan_cmd_fp,
  1060. sizeof(wmi_start_scan_cmd_fixed_param));
  1061. /* Ensure there is no additional IEs */
  1062. scan_cmd_fp->ie_len = 0;
  1063. WMITLV_SET_HDR(buf_ptr,
  1064. WMITLV_TAG_STRUC_wmi_start_scan_cmd_fixed_param,
  1065. WMITLV_GET_STRUCT_TLVLEN(wmi_start_scan_cmd_fixed_param));
  1066. #ifdef WLAN_FEATURE_ROAM_OFFLOAD
  1067. buf_ptr += sizeof(wmi_start_scan_cmd_fixed_param);
  1068. if (roam_req->is_roam_req_valid && roam_req->roam_offload_enabled) {
  1069. WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
  1070. sizeof(wmi_roam_offload_tlv_param));
  1071. buf_ptr += WMI_TLV_HDR_SIZE;
  1072. roam_offload_params = (wmi_roam_offload_tlv_param *) buf_ptr;
  1073. WMITLV_SET_HDR(buf_ptr,
  1074. WMITLV_TAG_STRUC_wmi_roam_offload_tlv_param,
  1075. WMITLV_GET_STRUCT_TLVLEN
  1076. (wmi_roam_offload_tlv_param));
  1077. roam_offload_params->prefer_5g = roam_req->prefer_5ghz;
  1078. roam_offload_params->rssi_cat_gap = roam_req->roam_rssi_cat_gap;
  1079. roam_offload_params->select_5g_margin =
  1080. roam_req->select_5ghz_margin;
  1081. roam_offload_params->handoff_delay_for_rx =
  1082. req_offload_params->ho_delay_for_rx;
  1083. roam_offload_params->max_mlme_sw_retries =
  1084. req_offload_params->roam_preauth_retry_count;
  1085. roam_offload_params->no_ack_timeout =
  1086. req_offload_params->roam_preauth_no_ack_timeout;
  1087. roam_offload_params->reassoc_failure_timeout =
  1088. roam_req->reassoc_failure_timeout;
  1089. roam_offload_params->roam_candidate_validity_time =
  1090. roam_req->rct_validity_timer;
  1091. /* Fill the capabilities */
  1092. roam_offload_params->capability =
  1093. req_offload_params->capability;
  1094. roam_offload_params->ht_caps_info =
  1095. req_offload_params->ht_caps_info;
  1096. roam_offload_params->ampdu_param =
  1097. req_offload_params->ampdu_param;
  1098. roam_offload_params->ht_ext_cap =
  1099. req_offload_params->ht_ext_cap;
  1100. roam_offload_params->ht_txbf = req_offload_params->ht_txbf;
  1101. roam_offload_params->asel_cap = req_offload_params->asel_cap;
  1102. roam_offload_params->qos_caps = req_offload_params->qos_caps;
  1103. roam_offload_params->qos_enabled =
  1104. req_offload_params->qos_enabled;
  1105. roam_offload_params->wmm_caps = req_offload_params->wmm_caps;
  1106. qdf_mem_copy((uint8_t *)roam_offload_params->mcsset,
  1107. (uint8_t *)req_offload_params->mcsset,
  1108. ROAM_OFFLOAD_NUM_MCS_SET);
  1109. buf_ptr += sizeof(wmi_roam_offload_tlv_param);
  1110. /* The TLV's are in the order of 11i, 11R, ESE. Hence,
  1111. * they are filled in the same order.Depending on the
  1112. * authentication type, the other mode TLV's are nullified
  1113. * and only headers are filled.*/
  1114. if ((auth_mode != WMI_AUTH_NONE) &&
  1115. ((auth_mode != WMI_AUTH_OPEN) ||
  1116. (auth_mode == WMI_AUTH_OPEN
  1117. && roam_req->mdid.mdie_present &&
  1118. roam_req->is_11r_assoc) ||
  1119. roam_req->is_ese_assoc)) {
  1120. if (roam_req->is_ese_assoc) {
  1121. WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
  1122. WMITLV_GET_STRUCT_TLVLEN(0));
  1123. buf_ptr += WMI_TLV_HDR_SIZE;
  1124. WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
  1125. WMITLV_GET_STRUCT_TLVLEN(0));
  1126. buf_ptr += WMI_TLV_HDR_SIZE;
  1127. WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
  1128. sizeof(wmi_roam_ese_offload_tlv_param));
  1129. buf_ptr += WMI_TLV_HDR_SIZE;
  1130. roam_offload_ese =
  1131. (wmi_roam_ese_offload_tlv_param *) buf_ptr;
  1132. qdf_mem_copy(roam_offload_ese->krk,
  1133. roam_req->krk,
  1134. sizeof(roam_req->krk));
  1135. qdf_mem_copy(roam_offload_ese->btk,
  1136. roam_req->btk,
  1137. sizeof(roam_req->btk));
  1138. WMITLV_SET_HDR(&roam_offload_ese->tlv_header,
  1139. WMITLV_TAG_STRUC_wmi_roam_ese_offload_tlv_param,
  1140. WMITLV_GET_STRUCT_TLVLEN
  1141. (wmi_roam_ese_offload_tlv_param));
  1142. buf_ptr +=
  1143. sizeof(wmi_roam_ese_offload_tlv_param);
  1144. } else if (auth_mode == WMI_AUTH_FT_RSNA ||
  1145. auth_mode == WMI_AUTH_FT_RSNA_PSK ||
  1146. auth_mode == WMI_AUTH_FT_RSNA_SAE ||
  1147. (auth_mode ==
  1148. WMI_AUTH_FT_RSNA_SUITE_B_8021X_SHA384) ||
  1149. (auth_mode ==
  1150. WMI_AUTH_FT_RSNA_FILS_SHA256) ||
  1151. (auth_mode ==
  1152. WMI_AUTH_FT_RSNA_FILS_SHA384) ||
  1153. (auth_mode == WMI_AUTH_OPEN
  1154. && roam_req->mdid.mdie_present &&
  1155. roam_req->is_11r_assoc)) {
  1156. WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
  1157. 0);
  1158. buf_ptr += WMI_TLV_HDR_SIZE;
  1159. WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
  1160. sizeof(wmi_roam_11r_offload_tlv_param));
  1161. buf_ptr += WMI_TLV_HDR_SIZE;
  1162. roam_offload_11r =
  1163. (wmi_roam_11r_offload_tlv_param *) buf_ptr;
  1164. roam_offload_11r->r0kh_id_len =
  1165. roam_req->rokh_id_length;
  1166. qdf_mem_copy(roam_offload_11r->r0kh_id,
  1167. roam_req->rokh_id,
  1168. roam_offload_11r->r0kh_id_len);
  1169. fill_roam_offload_11r_params(auth_mode,
  1170. roam_offload_11r,
  1171. roam_req);
  1172. roam_offload_11r->mdie_present =
  1173. roam_req->mdid.mdie_present;
  1174. roam_offload_11r->mdid =
  1175. roam_req->mdid.mobility_domain;
  1176. roam_offload_11r->adaptive_11r =
  1177. roam_req->is_adaptive_11r;
  1178. if (auth_mode == WMI_AUTH_OPEN) {
  1179. /* If FT-Open ensure pmk length
  1180. and r0khid len are zero */
  1181. roam_offload_11r->r0kh_id_len = 0;
  1182. roam_offload_11r->psk_msk_len = 0;
  1183. }
  1184. WMITLV_SET_HDR(&roam_offload_11r->tlv_header,
  1185. WMITLV_TAG_STRUC_wmi_roam_11r_offload_tlv_param,
  1186. WMITLV_GET_STRUCT_TLVLEN
  1187. (wmi_roam_11r_offload_tlv_param));
  1188. buf_ptr +=
  1189. sizeof(wmi_roam_11r_offload_tlv_param);
  1190. WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
  1191. WMITLV_GET_STRUCT_TLVLEN(0));
  1192. buf_ptr += WMI_TLV_HDR_SIZE;
  1193. WMI_LOGD("psk_msk_len = %d psk_msk_ext:%d",
  1194. roam_offload_11r->psk_msk_len,
  1195. roam_offload_11r->psk_msk_ext_len);
  1196. if (roam_offload_11r->psk_msk_len)
  1197. QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI,
  1198. QDF_TRACE_LEVEL_DEBUG,
  1199. roam_offload_11r->psk_msk,
  1200. roam_offload_11r->psk_msk_len);
  1201. } else {
  1202. WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
  1203. sizeof(wmi_roam_11i_offload_tlv_param));
  1204. buf_ptr += WMI_TLV_HDR_SIZE;
  1205. roam_offload_11i =
  1206. (wmi_roam_11i_offload_tlv_param *) buf_ptr;
  1207. if (roam_req->fw_okc) {
  1208. WMI_SET_ROAM_OFFLOAD_OKC_ENABLED
  1209. (roam_offload_11i->flags);
  1210. WMI_LOGI("LFR3:OKC enabled");
  1211. } else {
  1212. WMI_SET_ROAM_OFFLOAD_OKC_DISABLED
  1213. (roam_offload_11i->flags);
  1214. WMI_LOGI("LFR3:OKC disabled");
  1215. }
  1216. if (roam_req->fw_pmksa_cache) {
  1217. WMI_SET_ROAM_OFFLOAD_PMK_CACHE_ENABLED
  1218. (roam_offload_11i->flags);
  1219. WMI_LOGI("LFR3:PMKSA caching enabled");
  1220. } else {
  1221. WMI_SET_ROAM_OFFLOAD_PMK_CACHE_DISABLED
  1222. (roam_offload_11i->flags);
  1223. WMI_LOGI("LFR3:PMKSA caching disabled");
  1224. }
  1225. wmi_fill_sae_single_pmk_param(roam_req,
  1226. roam_offload_11i);
  1227. roam_offload_11i->pmk_len = roam_req->pmk_len >
  1228. ROAM_OFFLOAD_PMK_BYTES ?
  1229. ROAM_OFFLOAD_PMK_BYTES :
  1230. roam_req->pmk_len;
  1231. qdf_mem_copy(roam_offload_11i->pmk,
  1232. roam_req->psk_pmk,
  1233. roam_offload_11i->pmk_len);
  1234. WMITLV_SET_HDR(&roam_offload_11i->tlv_header,
  1235. WMITLV_TAG_STRUC_wmi_roam_11i_offload_tlv_param,
  1236. WMITLV_GET_STRUCT_TLVLEN
  1237. (wmi_roam_11i_offload_tlv_param));
  1238. buf_ptr +=
  1239. sizeof(wmi_roam_11i_offload_tlv_param);
  1240. WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
  1241. 0);
  1242. buf_ptr += WMI_TLV_HDR_SIZE;
  1243. WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
  1244. 0);
  1245. buf_ptr += WMI_TLV_HDR_SIZE;
  1246. WMI_LOGD("pmk_len = %d",
  1247. roam_offload_11i->pmk_len);
  1248. if (roam_offload_11i->pmk_len)
  1249. QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI,
  1250. QDF_TRACE_LEVEL_DEBUG,
  1251. roam_offload_11i->pmk,
  1252. roam_offload_11i->pmk_len);
  1253. }
  1254. } else {
  1255. WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
  1256. WMITLV_GET_STRUCT_TLVLEN(0));
  1257. buf_ptr += WMI_TLV_HDR_SIZE;
  1258. WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
  1259. WMITLV_GET_STRUCT_TLVLEN(0));
  1260. buf_ptr += WMI_TLV_HDR_SIZE;
  1261. WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
  1262. WMITLV_GET_STRUCT_TLVLEN(0));
  1263. buf_ptr += WMI_TLV_HDR_SIZE;
  1264. }
  1265. WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
  1266. sizeof(*assoc_ies));
  1267. buf_ptr += WMI_TLV_HDR_SIZE;
  1268. assoc_ies = (wmi_tlv_buf_len_param *) buf_ptr;
  1269. WMITLV_SET_HDR(&assoc_ies->tlv_header,
  1270. WMITLV_TAG_STRUC_wmi_tlv_buf_len_param,
  1271. WMITLV_GET_STRUCT_TLVLEN(wmi_tlv_buf_len_param));
  1272. assoc_ies->buf_len = roam_req->assoc_ie_length;
  1273. buf_ptr += sizeof(*assoc_ies);
  1274. WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE,
  1275. roundup(assoc_ies->buf_len, sizeof(uint32_t)));
  1276. buf_ptr += WMI_TLV_HDR_SIZE;
  1277. if (assoc_ies->buf_len != 0) {
  1278. qdf_mem_copy(buf_ptr, roam_req->assoc_ie,
  1279. assoc_ies->buf_len);
  1280. }
  1281. buf_ptr += qdf_roundup(assoc_ies->buf_len, sizeof(uint32_t));
  1282. buf_ptr = wmi_add_fils_tlv(wmi_handle, roam_req,
  1283. buf_ptr, fils_tlv_len);
  1284. } else {
  1285. WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
  1286. WMITLV_GET_STRUCT_TLVLEN(0));
  1287. buf_ptr += WMI_TLV_HDR_SIZE;
  1288. WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
  1289. WMITLV_GET_STRUCT_TLVLEN(0));
  1290. buf_ptr += WMI_TLV_HDR_SIZE;
  1291. WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
  1292. WMITLV_GET_STRUCT_TLVLEN(0));
  1293. buf_ptr += WMI_TLV_HDR_SIZE;
  1294. WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
  1295. WMITLV_GET_STRUCT_TLVLEN(0));
  1296. buf_ptr += WMI_TLV_HDR_SIZE;
  1297. WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
  1298. WMITLV_GET_STRUCT_TLVLEN(0));
  1299. buf_ptr += WMI_TLV_HDR_SIZE;
  1300. WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE,
  1301. WMITLV_GET_STRUCT_TLVLEN(0));
  1302. }
  1303. #endif /* WLAN_FEATURE_ROAM_OFFLOAD */
  1304. send_roam_scan_mode_cmd:
  1305. wmi_mtrace(WMI_ROAM_SCAN_MODE, NO_SESSION, 0);
  1306. status = wmi_unified_cmd_send(wmi_handle, buf,
  1307. len, WMI_ROAM_SCAN_MODE);
  1308. if (QDF_IS_STATUS_ERROR(status))
  1309. wmi_buf_free(buf);
  1310. return status;
  1311. }
  1312. /**
  1313. * convert_roam_trigger_reason() - Function to convert unified Roam trigger
  1314. * enum to TLV specific WMI_ROAM_TRIGGER_REASON_ID
  1315. * @reason: Roam trigger reason
  1316. *
  1317. * Return: WMI_ROAM_TRIGGER_REASON_ID
  1318. */
  1319. static WMI_ROAM_TRIGGER_REASON_ID
  1320. convert_roam_trigger_reason(enum roam_trigger_reason trigger_reason) {
  1321. switch (trigger_reason) {
  1322. case ROAM_TRIGGER_REASON_NONE:
  1323. return WMI_ROAM_TRIGGER_REASON_NONE;
  1324. case ROAM_TRIGGER_REASON_PER:
  1325. return WMI_ROAM_TRIGGER_REASON_PER;
  1326. case ROAM_TRIGGER_REASON_BMISS:
  1327. return WMI_ROAM_TRIGGER_REASON_BMISS;
  1328. case ROAM_TRIGGER_REASON_LOW_RSSI:
  1329. return WMI_ROAM_TRIGGER_REASON_LOW_RSSI;
  1330. case ROAM_TRIGGER_REASON_HIGH_RSSI:
  1331. return WMI_ROAM_TRIGGER_REASON_HIGH_RSSI;
  1332. case ROAM_TRIGGER_REASON_PERIODIC:
  1333. return WMI_ROAM_TRIGGER_REASON_PERIODIC;
  1334. case ROAM_TRIGGER_REASON_MAWC:
  1335. return WMI_ROAM_TRIGGER_REASON_MAWC;
  1336. case ROAM_TRIGGER_REASON_DENSE:
  1337. return WMI_ROAM_TRIGGER_REASON_DENSE;
  1338. case ROAM_TRIGGER_REASON_BACKGROUND:
  1339. return WMI_ROAM_TRIGGER_REASON_BACKGROUND;
  1340. case ROAM_TRIGGER_REASON_FORCED:
  1341. return WMI_ROAM_TRIGGER_REASON_FORCED;
  1342. case ROAM_TRIGGER_REASON_BTM:
  1343. return WMI_ROAM_TRIGGER_REASON_BTM;
  1344. case ROAM_TRIGGER_REASON_UNIT_TEST:
  1345. return WMI_ROAM_TRIGGER_REASON_UNIT_TEST;
  1346. case ROAM_TRIGGER_REASON_BSS_LOAD:
  1347. return WMI_ROAM_TRIGGER_REASON_BSS_LOAD;
  1348. case ROAM_TRIGGER_REASON_DEAUTH:
  1349. return WMI_ROAM_TRIGGER_REASON_DEAUTH;
  1350. case ROAM_TRIGGER_REASON_IDLE:
  1351. return WMI_ROAM_TRIGGER_REASON_IDLE;
  1352. case ROAM_TRIGGER_REASON_MAX:
  1353. return WMI_ROAM_TRIGGER_REASON_MAX;
  1354. default:
  1355. return WMI_ROAM_TRIGGER_REASON_NONE;
  1356. }
  1357. }
  1358. /**
  1359. * send_roam_scan_offload_ap_profile_cmd_tlv() - set roam ap profile in fw
  1360. * @wmi_handle: wmi handle
  1361. * @ap_profile_p: ap profile
  1362. *
  1363. * Send WMI_ROAM_AP_PROFILE to firmware
  1364. *
  1365. * Return: CDF status
  1366. */
  1367. static QDF_STATUS
  1368. send_roam_scan_offload_ap_profile_cmd_tlv(wmi_unified_t wmi_handle,
  1369. struct ap_profile_params *ap_profile)
  1370. {
  1371. wmi_buf_t buf = NULL;
  1372. QDF_STATUS status;
  1373. size_t len;
  1374. uint8_t *buf_ptr;
  1375. wmi_roam_ap_profile_fixed_param *roam_ap_profile_fp;
  1376. wmi_roam_cnd_scoring_param *score_param;
  1377. wmi_ap_profile *profile;
  1378. wmi_roam_score_delta_param *score_delta_param;
  1379. wmi_roam_cnd_min_rssi_param *min_rssi_param;
  1380. enum roam_trigger_reason trig_reason;
  1381. len = sizeof(wmi_roam_ap_profile_fixed_param) + sizeof(wmi_ap_profile);
  1382. len += sizeof(*score_param);
  1383. len += WMI_TLV_HDR_SIZE;
  1384. len += NUM_OF_ROAM_TRIGGERS * sizeof(*score_delta_param);
  1385. len += WMI_TLV_HDR_SIZE;
  1386. len += NUM_OF_ROAM_TRIGGERS * sizeof(*min_rssi_param);
  1387. buf = wmi_buf_alloc(wmi_handle, len);
  1388. if (!buf) {
  1389. return QDF_STATUS_E_NOMEM;
  1390. }
  1391. buf_ptr = (uint8_t *) wmi_buf_data(buf);
  1392. roam_ap_profile_fp = (wmi_roam_ap_profile_fixed_param *) buf_ptr;
  1393. WMITLV_SET_HDR(&roam_ap_profile_fp->tlv_header,
  1394. WMITLV_TAG_STRUC_wmi_roam_ap_profile_fixed_param,
  1395. WMITLV_GET_STRUCT_TLVLEN
  1396. (wmi_roam_ap_profile_fixed_param));
  1397. /* fill in threshold values */
  1398. roam_ap_profile_fp->vdev_id = ap_profile->vdev_id;
  1399. roam_ap_profile_fp->id = 0;
  1400. buf_ptr += sizeof(wmi_roam_ap_profile_fixed_param);
  1401. profile = (wmi_ap_profile *)buf_ptr;
  1402. WMITLV_SET_HDR(&profile->tlv_header,
  1403. WMITLV_TAG_STRUC_wmi_ap_profile,
  1404. WMITLV_GET_STRUCT_TLVLEN(wmi_ap_profile));
  1405. profile->flags = ap_profile->profile.flags;
  1406. profile->rssi_threshold = ap_profile->profile.rssi_threshold;
  1407. profile->ssid.ssid_len = ap_profile->profile.ssid.length;
  1408. qdf_mem_copy(profile->ssid.ssid, ap_profile->profile.ssid.mac_ssid,
  1409. profile->ssid.ssid_len);
  1410. profile->rsn_authmode = ap_profile->profile.rsn_authmode;
  1411. profile->rsn_ucastcipherset = ap_profile->profile.rsn_ucastcipherset;
  1412. profile->rsn_mcastcipherset = ap_profile->profile.rsn_mcastcipherset;
  1413. profile->rsn_mcastmgmtcipherset =
  1414. ap_profile->profile.rsn_mcastmgmtcipherset;
  1415. profile->rssi_abs_thresh = ap_profile->profile.rssi_abs_thresh;
  1416. WMI_LOGD("AP PROFILE: flags %x rssi_threshold %d ssid:%.*s authmode %d uc cipher %d mc cipher %d mc mgmt cipher %d rssi abs thresh %d",
  1417. profile->flags, profile->rssi_threshold,
  1418. profile->ssid.ssid_len, ap_profile->profile.ssid.mac_ssid,
  1419. profile->rsn_authmode, profile->rsn_ucastcipherset,
  1420. profile->rsn_mcastcipherset, profile->rsn_mcastmgmtcipherset,
  1421. profile->rssi_abs_thresh);
  1422. buf_ptr += sizeof(wmi_ap_profile);
  1423. score_param = (wmi_roam_cnd_scoring_param *)buf_ptr;
  1424. WMITLV_SET_HDR(&score_param->tlv_header,
  1425. WMITLV_TAG_STRUC_wmi_roam_cnd_scoring_param,
  1426. WMITLV_GET_STRUCT_TLVLEN(wmi_roam_cnd_scoring_param));
  1427. score_param->disable_bitmap = ap_profile->param.disable_bitmap;
  1428. score_param->rssi_weightage_pcnt =
  1429. ap_profile->param.rssi_weightage;
  1430. score_param->ht_weightage_pcnt = ap_profile->param.ht_weightage;
  1431. score_param->vht_weightage_pcnt = ap_profile->param.vht_weightage;
  1432. score_param->he_weightage_pcnt = ap_profile->param.he_weightage;
  1433. score_param->bw_weightage_pcnt = ap_profile->param.bw_weightage;
  1434. score_param->band_weightage_pcnt = ap_profile->param.band_weightage;
  1435. score_param->nss_weightage_pcnt = ap_profile->param.nss_weightage;
  1436. score_param->esp_qbss_weightage_pcnt =
  1437. ap_profile->param.esp_qbss_weightage;
  1438. score_param->beamforming_weightage_pcnt =
  1439. ap_profile->param.beamforming_weightage;
  1440. score_param->pcl_weightage_pcnt = ap_profile->param.pcl_weightage;
  1441. score_param->oce_wan_weightage_pcnt =
  1442. ap_profile->param.oce_wan_weightage;
  1443. score_param->vendor_roam_score_algorithm_id =
  1444. ap_profile->param.vendor_roam_score_algorithm;
  1445. WMI_LOGD("Score params weightage: disable_bitmap %x rssi %d ht %d vht %d he %d BW %d band %d NSS %d ESP %d BF %d PCL %d OCE WAN %d roam score algo %d",
  1446. score_param->disable_bitmap, score_param->rssi_weightage_pcnt,
  1447. score_param->ht_weightage_pcnt,
  1448. score_param->vht_weightage_pcnt,
  1449. score_param->he_weightage_pcnt, score_param->bw_weightage_pcnt,
  1450. score_param->band_weightage_pcnt,
  1451. score_param->nss_weightage_pcnt,
  1452. score_param->esp_qbss_weightage_pcnt,
  1453. score_param->beamforming_weightage_pcnt,
  1454. score_param->pcl_weightage_pcnt,
  1455. score_param->oce_wan_weightage_pcnt,
  1456. score_param->vendor_roam_score_algorithm_id);
  1457. score_param->bw_scoring.score_pcnt = ap_profile->param.bw_index_score;
  1458. score_param->band_scoring.score_pcnt =
  1459. ap_profile->param.band_index_score;
  1460. score_param->nss_scoring.score_pcnt =
  1461. ap_profile->param.nss_index_score;
  1462. WMI_LOGD("Params index score bitmask: bw_index_score %x band_index_score %x nss_index_score %x",
  1463. score_param->bw_scoring.score_pcnt,
  1464. score_param->band_scoring.score_pcnt,
  1465. score_param->nss_scoring.score_pcnt);
  1466. score_param->rssi_scoring.best_rssi_threshold =
  1467. (-1) * ap_profile->param.rssi_scoring.best_rssi_threshold;
  1468. score_param->rssi_scoring.good_rssi_threshold =
  1469. (-1) * ap_profile->param.rssi_scoring.good_rssi_threshold;
  1470. score_param->rssi_scoring.bad_rssi_threshold =
  1471. (-1) * ap_profile->param.rssi_scoring.bad_rssi_threshold;
  1472. score_param->rssi_scoring.good_rssi_pcnt =
  1473. ap_profile->param.rssi_scoring.good_rssi_pcnt;
  1474. score_param->rssi_scoring.bad_rssi_pcnt =
  1475. ap_profile->param.rssi_scoring.bad_rssi_pcnt;
  1476. score_param->rssi_scoring.good_bucket_size =
  1477. ap_profile->param.rssi_scoring.good_bucket_size;
  1478. score_param->rssi_scoring.bad_bucket_size =
  1479. ap_profile->param.rssi_scoring.bad_bucket_size;
  1480. score_param->rssi_scoring.rssi_pref_5g_rssi_thresh =
  1481. (-1) * ap_profile->param.rssi_scoring.rssi_pref_5g_rssi_thresh;
  1482. WMI_LOGD("Rssi scoring threshold: best RSSI %d good RSSI %d bad RSSI %d prefer 5g threshold %d",
  1483. score_param->rssi_scoring.best_rssi_threshold,
  1484. score_param->rssi_scoring.good_rssi_threshold,
  1485. score_param->rssi_scoring.bad_rssi_threshold,
  1486. score_param->rssi_scoring.rssi_pref_5g_rssi_thresh);
  1487. WMI_LOGD("Good RSSI score for each slot %d bad RSSI score for each slot %d good bucket %d bad bucket %d",
  1488. score_param->rssi_scoring.good_rssi_pcnt,
  1489. score_param->rssi_scoring.bad_rssi_pcnt,
  1490. score_param->rssi_scoring.good_bucket_size,
  1491. score_param->rssi_scoring.bad_bucket_size);
  1492. score_param->esp_qbss_scoring.num_slot =
  1493. ap_profile->param.esp_qbss_scoring.num_slot;
  1494. score_param->esp_qbss_scoring.score_pcnt3_to_0 =
  1495. ap_profile->param.esp_qbss_scoring.score_pcnt3_to_0;
  1496. score_param->esp_qbss_scoring.score_pcnt7_to_4 =
  1497. ap_profile->param.esp_qbss_scoring.score_pcnt7_to_4;
  1498. score_param->esp_qbss_scoring.score_pcnt11_to_8 =
  1499. ap_profile->param.esp_qbss_scoring.score_pcnt11_to_8;
  1500. score_param->esp_qbss_scoring.score_pcnt15_to_12 =
  1501. ap_profile->param.esp_qbss_scoring.score_pcnt15_to_12;
  1502. WMI_LOGD("ESP QBSS index weight: slots %d weight 0to3 %x weight 4to7 %x weight 8to11 %x weight 12to15 %x",
  1503. score_param->esp_qbss_scoring.num_slot,
  1504. score_param->esp_qbss_scoring.score_pcnt3_to_0,
  1505. score_param->esp_qbss_scoring.score_pcnt7_to_4,
  1506. score_param->esp_qbss_scoring.score_pcnt11_to_8,
  1507. score_param->esp_qbss_scoring.score_pcnt15_to_12);
  1508. score_param->oce_wan_scoring.num_slot =
  1509. ap_profile->param.oce_wan_scoring.num_slot;
  1510. score_param->oce_wan_scoring.score_pcnt3_to_0 =
  1511. ap_profile->param.oce_wan_scoring.score_pcnt3_to_0;
  1512. score_param->oce_wan_scoring.score_pcnt7_to_4 =
  1513. ap_profile->param.oce_wan_scoring.score_pcnt7_to_4;
  1514. score_param->oce_wan_scoring.score_pcnt11_to_8 =
  1515. ap_profile->param.oce_wan_scoring.score_pcnt11_to_8;
  1516. score_param->oce_wan_scoring.score_pcnt15_to_12 =
  1517. ap_profile->param.oce_wan_scoring.score_pcnt15_to_12;
  1518. WMI_LOGD("OCE WAN index weight: slots %d weight 0to3 %x weight 4to7 %x weight 8to11 %x weight 12to15 %x",
  1519. score_param->oce_wan_scoring.num_slot,
  1520. score_param->oce_wan_scoring.score_pcnt3_to_0,
  1521. score_param->oce_wan_scoring.score_pcnt7_to_4,
  1522. score_param->oce_wan_scoring.score_pcnt11_to_8,
  1523. score_param->oce_wan_scoring.score_pcnt15_to_12);
  1524. score_param->roam_score_delta_pcnt = ap_profile->param.roam_score_delta;
  1525. score_param->roam_score_delta_mask =
  1526. ap_profile->param.roam_trigger_bitmap;
  1527. score_param->candidate_min_roam_score_delta =
  1528. ap_profile->param.cand_min_roam_score_delta;
  1529. WMI_LOGD("Roam score delta:%d Roam_trigger_bitmap:%x cand min score delta = %d",
  1530. score_param->roam_score_delta_pcnt,
  1531. score_param->roam_score_delta_mask,
  1532. score_param->candidate_min_roam_score_delta);
  1533. buf_ptr += sizeof(*score_param);
  1534. WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
  1535. (NUM_OF_ROAM_TRIGGERS * sizeof(*score_delta_param)));
  1536. buf_ptr += WMI_TLV_HDR_SIZE;
  1537. score_delta_param = (wmi_roam_score_delta_param *)buf_ptr;
  1538. WMITLV_SET_HDR(&score_delta_param->tlv_header,
  1539. WMITLV_TAG_STRUC_wmi_roam_score_delta_param,
  1540. WMITLV_GET_STRUCT_TLVLEN(wmi_roam_score_delta_param));
  1541. trig_reason =
  1542. ap_profile->score_delta_param[IDLE_ROAM_TRIGGER].trigger_reason;
  1543. score_delta_param->roam_trigger_reason =
  1544. convert_roam_trigger_reason(trig_reason);
  1545. score_delta_param->roam_score_delta =
  1546. ap_profile->score_delta_param[IDLE_ROAM_TRIGGER].roam_score_delta;
  1547. buf_ptr += sizeof(*score_delta_param);
  1548. score_delta_param = (wmi_roam_score_delta_param *)buf_ptr;
  1549. WMITLV_SET_HDR(&score_delta_param->tlv_header,
  1550. WMITLV_TAG_STRUC_wmi_roam_score_delta_param,
  1551. WMITLV_GET_STRUCT_TLVLEN(wmi_roam_score_delta_param));
  1552. trig_reason =
  1553. ap_profile->score_delta_param[BTM_ROAM_TRIGGER].trigger_reason;
  1554. score_delta_param->roam_trigger_reason =
  1555. convert_roam_trigger_reason(trig_reason);
  1556. score_delta_param->roam_score_delta =
  1557. ap_profile->score_delta_param[BTM_ROAM_TRIGGER].roam_score_delta;
  1558. buf_ptr += sizeof(*score_delta_param);
  1559. WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
  1560. (NUM_OF_ROAM_TRIGGERS * sizeof(*min_rssi_param)));
  1561. buf_ptr += WMI_TLV_HDR_SIZE;
  1562. min_rssi_param = (wmi_roam_cnd_min_rssi_param *)buf_ptr;
  1563. WMITLV_SET_HDR(&min_rssi_param->tlv_header,
  1564. WMITLV_TAG_STRUC_wmi_roam_cnd_min_rssi_param,
  1565. WMITLV_GET_STRUCT_TLVLEN(wmi_roam_cnd_min_rssi_param));
  1566. trig_reason =
  1567. ap_profile->min_rssi_params[DEAUTH_MIN_RSSI].trigger_reason;
  1568. min_rssi_param->roam_trigger_reason =
  1569. convert_roam_trigger_reason(trig_reason);
  1570. min_rssi_param->candidate_min_rssi =
  1571. ap_profile->min_rssi_params[DEAUTH_MIN_RSSI].min_rssi;
  1572. buf_ptr += sizeof(*min_rssi_param);
  1573. min_rssi_param = (wmi_roam_cnd_min_rssi_param *)buf_ptr;
  1574. WMITLV_SET_HDR(&min_rssi_param->tlv_header,
  1575. WMITLV_TAG_STRUC_wmi_roam_cnd_min_rssi_param,
  1576. WMITLV_GET_STRUCT_TLVLEN(wmi_roam_cnd_min_rssi_param));
  1577. trig_reason =
  1578. ap_profile->min_rssi_params[BMISS_MIN_RSSI].trigger_reason;
  1579. min_rssi_param->roam_trigger_reason =
  1580. convert_roam_trigger_reason(trig_reason);
  1581. min_rssi_param->candidate_min_rssi =
  1582. ap_profile->min_rssi_params[BMISS_MIN_RSSI].min_rssi;
  1583. wmi_mtrace(WMI_ROAM_AP_PROFILE, NO_SESSION, 0);
  1584. status = wmi_unified_cmd_send(wmi_handle, buf,
  1585. len, WMI_ROAM_AP_PROFILE);
  1586. if (QDF_IS_STATUS_ERROR(status)) {
  1587. WMI_LOGE("wmi_unified_cmd_send WMI_ROAM_AP_PROFILE returned Error %d",
  1588. status);
  1589. wmi_buf_free(buf);
  1590. }
  1591. return status;
  1592. }
  1593. /**
  1594. * send_roam_scan_offload_cmd_tlv() - set roam offload command
  1595. * @wmi_handle: wmi handle
  1596. * @command: command
  1597. * @vdev_id: vdev id
  1598. *
  1599. * This function set roam offload command to fw.
  1600. *
  1601. * Return: CDF status
  1602. */
  1603. static QDF_STATUS send_roam_scan_offload_cmd_tlv(wmi_unified_t wmi_handle,
  1604. uint32_t command, uint32_t vdev_id)
  1605. {
  1606. QDF_STATUS status;
  1607. wmi_roam_scan_cmd_fixed_param *cmd_fp;
  1608. wmi_buf_t buf = NULL;
  1609. int len;
  1610. uint8_t *buf_ptr;
  1611. len = sizeof(wmi_roam_scan_cmd_fixed_param);
  1612. buf = wmi_buf_alloc(wmi_handle, len);
  1613. if (!buf) {
  1614. return QDF_STATUS_E_NOMEM;
  1615. }
  1616. buf_ptr = (uint8_t *) wmi_buf_data(buf);
  1617. cmd_fp = (wmi_roam_scan_cmd_fixed_param *) buf_ptr;
  1618. WMITLV_SET_HDR(&cmd_fp->tlv_header,
  1619. WMITLV_TAG_STRUC_wmi_roam_scan_cmd_fixed_param,
  1620. WMITLV_GET_STRUCT_TLVLEN(wmi_roam_scan_cmd_fixed_param));
  1621. cmd_fp->vdev_id = vdev_id;
  1622. cmd_fp->command_arg = command;
  1623. wmi_mtrace(WMI_ROAM_SCAN_CMD, NO_SESSION, 0);
  1624. status = wmi_unified_cmd_send(wmi_handle, buf,
  1625. len, WMI_ROAM_SCAN_CMD);
  1626. if (QDF_IS_STATUS_ERROR(status)) {
  1627. WMI_LOGE("wmi_unified_cmd_send WMI_ROAM_SCAN_CMD returned Error %d",
  1628. status);
  1629. goto error;
  1630. }
  1631. WMI_LOGI("%s: WMI --> WMI_ROAM_SCAN_CMD", __func__);
  1632. return QDF_STATUS_SUCCESS;
  1633. error:
  1634. wmi_buf_free(buf);
  1635. return status;
  1636. }
  1637. /**
  1638. * send_roam_scan_offload_scan_period_cmd_tlv() - set roam offload scan period
  1639. * @wmi_handle: wmi handle
  1640. * @param: roam scan parameters to be sent to firmware
  1641. *
  1642. * Send WMI_ROAM_SCAN_PERIOD parameters to fw.
  1643. *
  1644. * Return: QDF status
  1645. */
  1646. static QDF_STATUS
  1647. send_roam_scan_offload_scan_period_cmd_tlv(
  1648. wmi_unified_t wmi_handle,
  1649. struct roam_scan_period_params *param)
  1650. {
  1651. QDF_STATUS status;
  1652. wmi_buf_t buf = NULL;
  1653. int len;
  1654. uint8_t *buf_ptr;
  1655. wmi_roam_scan_period_fixed_param *scan_period_fp;
  1656. /* Send scan period values */
  1657. len = sizeof(wmi_roam_scan_period_fixed_param);
  1658. buf = wmi_buf_alloc(wmi_handle, len);
  1659. if (!buf) {
  1660. return QDF_STATUS_E_NOMEM;
  1661. }
  1662. buf_ptr = (uint8_t *) wmi_buf_data(buf);
  1663. scan_period_fp = (wmi_roam_scan_period_fixed_param *) buf_ptr;
  1664. WMITLV_SET_HDR(&scan_period_fp->tlv_header,
  1665. WMITLV_TAG_STRUC_wmi_roam_scan_period_fixed_param,
  1666. WMITLV_GET_STRUCT_TLVLEN
  1667. (wmi_roam_scan_period_fixed_param));
  1668. /* fill in scan period values */
  1669. scan_period_fp->vdev_id = param->vdev_id;
  1670. scan_period_fp->roam_scan_period = param->scan_period;
  1671. scan_period_fp->roam_scan_age = param->scan_age;
  1672. scan_period_fp->inactivity_time_period =
  1673. param->roam_scan_inactivity_time;
  1674. scan_period_fp->roam_inactive_count =
  1675. param->roam_inactive_data_packet_count;
  1676. scan_period_fp->roam_scan_period_after_inactivity =
  1677. param->roam_scan_period_after_inactivity;
  1678. /* Firmware expects the full scan preriod in msec whereas host
  1679. * provides the same in seconds.
  1680. * Convert it to msec and send to firmware
  1681. */
  1682. scan_period_fp->roam_full_scan_period = param->full_scan_period * 1000;
  1683. WMI_LOGD("%s: roam_scan_period=%d, roam_scan_age=%d, full_scan_period= %u",
  1684. __func__, scan_period_fp->roam_scan_period,
  1685. scan_period_fp->roam_scan_age,
  1686. scan_period_fp->roam_full_scan_period);
  1687. WMI_LOGD("%s: inactiviy period:%d inactive count:%d period after inactivity:%d",
  1688. __func__, scan_period_fp->inactivity_time_period,
  1689. scan_period_fp->roam_inactive_count,
  1690. scan_period_fp->roam_scan_period_after_inactivity);
  1691. wmi_mtrace(WMI_ROAM_SCAN_PERIOD, NO_SESSION, 0);
  1692. status = wmi_unified_cmd_send(wmi_handle, buf, len,
  1693. WMI_ROAM_SCAN_PERIOD);
  1694. if (QDF_IS_STATUS_ERROR(status)) {
  1695. wmi_buf_free(buf);
  1696. return status;
  1697. }
  1698. return QDF_STATUS_SUCCESS;
  1699. }
  1700. /**
  1701. * send_roam_scan_offload_chan_list_cmd_tlv() - set roam offload channel list
  1702. * @wmi_handle: wmi handle
  1703. * @chan_count: channel count
  1704. * @chan_list: channel list
  1705. * @list_type: list type
  1706. * @vdev_id: vdev id
  1707. *
  1708. * Set roam offload channel list.
  1709. *
  1710. * Return: CDF status
  1711. */
  1712. static QDF_STATUS send_roam_scan_offload_chan_list_cmd_tlv(wmi_unified_t wmi_handle,
  1713. uint8_t chan_count,
  1714. uint32_t *chan_list,
  1715. uint8_t list_type, uint32_t vdev_id)
  1716. {
  1717. wmi_buf_t buf = NULL;
  1718. QDF_STATUS status;
  1719. int len, list_tlv_len;
  1720. int i;
  1721. uint8_t *buf_ptr;
  1722. wmi_roam_chan_list_fixed_param *chan_list_fp;
  1723. uint32_t *roam_chan_list_array;
  1724. /* Channel list is a table of 2 TLV's */
  1725. list_tlv_len = WMI_TLV_HDR_SIZE + chan_count * sizeof(uint32_t);
  1726. len = sizeof(wmi_roam_chan_list_fixed_param) + list_tlv_len;
  1727. buf = wmi_buf_alloc(wmi_handle, len);
  1728. if (!buf) {
  1729. return QDF_STATUS_E_NOMEM;
  1730. }
  1731. buf_ptr = (uint8_t *) wmi_buf_data(buf);
  1732. chan_list_fp = (wmi_roam_chan_list_fixed_param *) buf_ptr;
  1733. WMITLV_SET_HDR(&chan_list_fp->tlv_header,
  1734. WMITLV_TAG_STRUC_wmi_roam_chan_list_fixed_param,
  1735. WMITLV_GET_STRUCT_TLVLEN
  1736. (wmi_roam_chan_list_fixed_param));
  1737. chan_list_fp->vdev_id = vdev_id;
  1738. chan_list_fp->num_chan = chan_count;
  1739. if (list_type == WMI_CHANNEL_LIST_STATIC) {
  1740. /* external app is controlling channel list */
  1741. chan_list_fp->chan_list_type =
  1742. WMI_ROAM_SCAN_CHAN_LIST_TYPE_STATIC;
  1743. } else {
  1744. /* umac supplied occupied channel list in LFR */
  1745. chan_list_fp->chan_list_type =
  1746. WMI_ROAM_SCAN_CHAN_LIST_TYPE_DYNAMIC;
  1747. }
  1748. buf_ptr += sizeof(wmi_roam_chan_list_fixed_param);
  1749. WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32,
  1750. (chan_list_fp->num_chan * sizeof(uint32_t)));
  1751. roam_chan_list_array = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE);
  1752. for (i = 0; ((i < chan_list_fp->num_chan) &&
  1753. (i < WMI_ROAM_MAX_CHANNELS)); i++)
  1754. roam_chan_list_array[i] = chan_list[i];
  1755. wmi_mtrace(WMI_ROAM_CHAN_LIST, NO_SESSION, 0);
  1756. status = wmi_unified_cmd_send(wmi_handle, buf,
  1757. len, WMI_ROAM_CHAN_LIST);
  1758. if (QDF_IS_STATUS_ERROR(status)) {
  1759. WMI_LOGE("wmi_unified_cmd_send WMI_ROAM_CHAN_LIST returned Error %d",
  1760. status);
  1761. goto error;
  1762. }
  1763. return QDF_STATUS_SUCCESS;
  1764. error:
  1765. wmi_buf_free(buf);
  1766. return status;
  1767. }
  1768. /**
  1769. * send_roam_scan_offload_rssi_change_cmd_tlv() - set roam offload RSSI th
  1770. * @wmi_handle: wmi handle
  1771. * @rssi_change_thresh: RSSI Change threshold
  1772. * @bcn_rssi_weight: beacon RSSI weight
  1773. * @vdev_id: vdev id
  1774. *
  1775. * Send WMI_ROAM_SCAN_RSSI_CHANGE_THRESHOLD parameters to fw.
  1776. *
  1777. * Return: CDF status
  1778. */
  1779. static QDF_STATUS send_roam_scan_offload_rssi_change_cmd_tlv(wmi_unified_t wmi_handle,
  1780. uint32_t vdev_id,
  1781. int32_t rssi_change_thresh,
  1782. uint32_t bcn_rssi_weight,
  1783. uint32_t hirssi_delay_btw_scans)
  1784. {
  1785. wmi_buf_t buf = NULL;
  1786. QDF_STATUS status;
  1787. int len;
  1788. uint8_t *buf_ptr;
  1789. wmi_roam_scan_rssi_change_threshold_fixed_param *rssi_change_fp;
  1790. /* Send rssi change parameters */
  1791. len = sizeof(wmi_roam_scan_rssi_change_threshold_fixed_param);
  1792. buf = wmi_buf_alloc(wmi_handle, len);
  1793. if (!buf) {
  1794. return QDF_STATUS_E_NOMEM;
  1795. }
  1796. buf_ptr = (uint8_t *) wmi_buf_data(buf);
  1797. rssi_change_fp =
  1798. (wmi_roam_scan_rssi_change_threshold_fixed_param *) buf_ptr;
  1799. WMITLV_SET_HDR(&rssi_change_fp->tlv_header,
  1800. WMITLV_TAG_STRUC_wmi_roam_scan_rssi_change_threshold_fixed_param,
  1801. WMITLV_GET_STRUCT_TLVLEN
  1802. (wmi_roam_scan_rssi_change_threshold_fixed_param));
  1803. /* fill in rssi change threshold (hysteresis) values */
  1804. rssi_change_fp->vdev_id = vdev_id;
  1805. rssi_change_fp->roam_scan_rssi_change_thresh = rssi_change_thresh;
  1806. rssi_change_fp->bcn_rssi_weight = bcn_rssi_weight;
  1807. rssi_change_fp->hirssi_delay_btw_scans = hirssi_delay_btw_scans;
  1808. wmi_mtrace(WMI_ROAM_SCAN_RSSI_CHANGE_THRESHOLD, NO_SESSION, 0);
  1809. status = wmi_unified_cmd_send(wmi_handle, buf,
  1810. len, WMI_ROAM_SCAN_RSSI_CHANGE_THRESHOLD);
  1811. if (QDF_IS_STATUS_ERROR(status)) {
  1812. WMI_LOGE("wmi_unified_cmd_send WMI_ROAM_SCAN_RSSI_CHANGE_THRESHOLD returned Error %d",
  1813. status);
  1814. goto error;
  1815. }
  1816. wmi_nofl_debug("roam_scan_rssi_change_thresh %d bcn_rssi_weight %d hirssi_delay_btw_scans %d",
  1817. rssi_change_thresh, bcn_rssi_weight,
  1818. hirssi_delay_btw_scans);
  1819. return QDF_STATUS_SUCCESS;
  1820. error:
  1821. wmi_buf_free(buf);
  1822. return status;
  1823. }
  1824. /**
  1825. * send_per_roam_config_cmd_tlv() - set per roaming config to FW
  1826. * @wmi_handle: wmi handle
  1827. * @req_buf: per roam config buffer
  1828. *
  1829. * Return: QDF status
  1830. */
  1831. static QDF_STATUS send_per_roam_config_cmd_tlv(wmi_unified_t wmi_handle,
  1832. struct wmi_per_roam_config_req *req_buf)
  1833. {
  1834. wmi_buf_t buf = NULL;
  1835. QDF_STATUS status;
  1836. int len;
  1837. uint8_t *buf_ptr;
  1838. wmi_roam_per_config_fixed_param *wmi_per_config;
  1839. len = sizeof(wmi_roam_per_config_fixed_param);
  1840. buf = wmi_buf_alloc(wmi_handle, len);
  1841. if (!buf) {
  1842. return QDF_STATUS_E_NOMEM;
  1843. }
  1844. buf_ptr = (uint8_t *) wmi_buf_data(buf);
  1845. wmi_per_config =
  1846. (wmi_roam_per_config_fixed_param *) buf_ptr;
  1847. WMITLV_SET_HDR(&wmi_per_config->tlv_header,
  1848. WMITLV_TAG_STRUC_wmi_roam_per_config_fixed_param,
  1849. WMITLV_GET_STRUCT_TLVLEN
  1850. (wmi_roam_per_config_fixed_param));
  1851. /* fill in per roam config values */
  1852. wmi_per_config->vdev_id = req_buf->vdev_id;
  1853. wmi_per_config->enable = req_buf->per_config.enable;
  1854. wmi_per_config->high_rate_thresh =
  1855. (req_buf->per_config.tx_high_rate_thresh << 16) |
  1856. (req_buf->per_config.rx_high_rate_thresh & 0x0000ffff);
  1857. wmi_per_config->low_rate_thresh =
  1858. (req_buf->per_config.tx_low_rate_thresh << 16) |
  1859. (req_buf->per_config.rx_low_rate_thresh & 0x0000ffff);
  1860. wmi_per_config->pkt_err_rate_thresh_pct =
  1861. (req_buf->per_config.tx_rate_thresh_percnt << 16) |
  1862. (req_buf->per_config.rx_rate_thresh_percnt & 0x0000ffff);
  1863. wmi_per_config->per_rest_time = req_buf->per_config.per_rest_time;
  1864. wmi_per_config->pkt_err_rate_mon_time =
  1865. (req_buf->per_config.tx_per_mon_time << 16) |
  1866. (req_buf->per_config.rx_per_mon_time & 0x0000ffff);
  1867. wmi_per_config->min_candidate_rssi =
  1868. req_buf->per_config.min_candidate_rssi;
  1869. /* Send per roam config parameters */
  1870. wmi_mtrace(WMI_ROAM_PER_CONFIG_CMDID, NO_SESSION, 0);
  1871. status = wmi_unified_cmd_send(wmi_handle, buf,
  1872. len, WMI_ROAM_PER_CONFIG_CMDID);
  1873. if (QDF_IS_STATUS_ERROR(status)) {
  1874. WMI_LOGE("WMI_ROAM_PER_CONFIG_CMDID failed, Error %d",
  1875. status);
  1876. wmi_buf_free(buf);
  1877. return status;
  1878. }
  1879. WMI_LOGD(FL("per roam enable=%d, vdev=%d"),
  1880. req_buf->per_config.enable, req_buf->vdev_id);
  1881. return QDF_STATUS_SUCCESS;
  1882. }
  1883. /**
  1884. * send_limit_off_chan_cmd_tlv() - send wmi cmd of limit off chan
  1885. * configuration params
  1886. * @wmi_handle: wmi handler
  1887. * @limit_off_chan_param: pointer to wmi_off_chan_param
  1888. *
  1889. * Return: 0 for success and non zero for failure
  1890. */
  1891. static
  1892. QDF_STATUS send_limit_off_chan_cmd_tlv(wmi_unified_t wmi_handle,
  1893. struct wmi_limit_off_chan_param *limit_off_chan_param)
  1894. {
  1895. wmi_vdev_limit_offchan_cmd_fixed_param *cmd;
  1896. wmi_buf_t buf;
  1897. uint32_t len = sizeof(*cmd);
  1898. int err;
  1899. buf = wmi_buf_alloc(wmi_handle, len);
  1900. if (!buf) {
  1901. return QDF_STATUS_E_NOMEM;
  1902. }
  1903. cmd = (wmi_vdev_limit_offchan_cmd_fixed_param *)wmi_buf_data(buf);
  1904. WMITLV_SET_HDR(&cmd->tlv_header,
  1905. WMITLV_TAG_STRUC_wmi_vdev_limit_offchan_cmd_fixed_param,
  1906. WMITLV_GET_STRUCT_TLVLEN(
  1907. wmi_vdev_limit_offchan_cmd_fixed_param));
  1908. cmd->vdev_id = limit_off_chan_param->vdev_id;
  1909. cmd->flags &= 0;
  1910. if (limit_off_chan_param->status)
  1911. cmd->flags |= WMI_VDEV_LIMIT_OFFCHAN_ENABLE;
  1912. if (limit_off_chan_param->skip_dfs_chans)
  1913. cmd->flags |= WMI_VDEV_LIMIT_OFFCHAN_SKIP_DFS;
  1914. cmd->max_offchan_time = limit_off_chan_param->max_offchan_time;
  1915. cmd->rest_time = limit_off_chan_param->rest_time;
  1916. WMI_LOGE("%s: vdev_id=%d, flags =%x, max_offchan_time=%d, rest_time=%d",
  1917. __func__, cmd->vdev_id, cmd->flags, cmd->max_offchan_time,
  1918. cmd->rest_time);
  1919. wmi_mtrace(WMI_VDEV_LIMIT_OFFCHAN_CMDID, cmd->vdev_id, 0);
  1920. err = wmi_unified_cmd_send(wmi_handle, buf,
  1921. len, WMI_VDEV_LIMIT_OFFCHAN_CMDID);
  1922. if (QDF_IS_STATUS_ERROR(err)) {
  1923. WMI_LOGE("Failed to send limit off chan cmd err=%d", err);
  1924. wmi_buf_free(buf);
  1925. return QDF_STATUS_E_FAILURE;
  1926. }
  1927. return QDF_STATUS_SUCCESS;
  1928. }
  1929. #ifdef WLAN_FEATURE_FILS_SK
  1930. static QDF_STATUS send_roam_scan_send_hlp_cmd_tlv(wmi_unified_t wmi_handle,
  1931. struct hlp_params *params)
  1932. {
  1933. uint32_t len;
  1934. uint8_t *buf_ptr;
  1935. wmi_buf_t buf = NULL;
  1936. wmi_pdev_update_fils_hlp_pkt_cmd_fixed_param *hlp_params;
  1937. len = sizeof(wmi_pdev_update_fils_hlp_pkt_cmd_fixed_param);
  1938. len += WMI_TLV_HDR_SIZE;
  1939. len += qdf_roundup(params->hlp_ie_len, sizeof(uint32_t));
  1940. buf = wmi_buf_alloc(wmi_handle, len);
  1941. if (!buf) {
  1942. return QDF_STATUS_E_NOMEM;
  1943. }
  1944. buf_ptr = (uint8_t *) wmi_buf_data(buf);
  1945. hlp_params = (wmi_pdev_update_fils_hlp_pkt_cmd_fixed_param *) buf_ptr;
  1946. WMITLV_SET_HDR(&hlp_params->tlv_header,
  1947. WMITLV_TAG_STRUC_wmi_pdev_update_fils_hlp_pkt_cmd_fixed_param,
  1948. WMITLV_GET_STRUCT_TLVLEN(
  1949. wmi_pdev_update_fils_hlp_pkt_cmd_fixed_param));
  1950. hlp_params->vdev_id = params->vdev_id;
  1951. hlp_params->size = params->hlp_ie_len;
  1952. hlp_params->pkt_type = WMI_FILS_HLP_PKT_TYPE_DHCP_DISCOVER;
  1953. buf_ptr += sizeof(*hlp_params);
  1954. WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE,
  1955. round_up(params->hlp_ie_len,
  1956. sizeof(uint32_t)));
  1957. buf_ptr += WMI_TLV_HDR_SIZE;
  1958. qdf_mem_copy(buf_ptr, params->hlp_ie, params->hlp_ie_len);
  1959. WMI_LOGD(FL("send FILS HLP pkt vdev %d len %d"),
  1960. hlp_params->vdev_id, hlp_params->size);
  1961. wmi_mtrace(WMI_PDEV_UPDATE_FILS_HLP_PKT_CMDID, NO_SESSION, 0);
  1962. if (wmi_unified_cmd_send(wmi_handle, buf, len,
  1963. WMI_PDEV_UPDATE_FILS_HLP_PKT_CMDID)) {
  1964. WMI_LOGE(FL("Failed to send FILS HLP pkt cmd"));
  1965. wmi_buf_free(buf);
  1966. return QDF_STATUS_E_FAILURE;
  1967. }
  1968. return QDF_STATUS_SUCCESS;
  1969. }
  1970. void wmi_fils_sk_attach_tlv(wmi_unified_t wmi_handle)
  1971. {
  1972. struct wmi_ops *ops = wmi_handle->ops;
  1973. ops->send_roam_scan_hlp_cmd = send_roam_scan_send_hlp_cmd_tlv;
  1974. }
  1975. #endif /* WLAN_FEATURE_FILS_SK */
  1976. /*
  1977. * send_btm_config_cmd_tlv() - Send wmi cmd for BTM config
  1978. * @wmi_handle: wmi handle
  1979. * @params: pointer to wmi_btm_config
  1980. *
  1981. * Return: QDF_STATUS
  1982. */
  1983. static QDF_STATUS send_btm_config_cmd_tlv(wmi_unified_t wmi_handle,
  1984. struct wmi_btm_config *params)
  1985. {
  1986. wmi_btm_config_fixed_param *cmd;
  1987. wmi_buf_t buf;
  1988. uint32_t len;
  1989. len = sizeof(*cmd);
  1990. buf = wmi_buf_alloc(wmi_handle, len);
  1991. if (!buf) {
  1992. return QDF_STATUS_E_NOMEM;
  1993. }
  1994. cmd = (wmi_btm_config_fixed_param *)wmi_buf_data(buf);
  1995. WMITLV_SET_HDR(&cmd->tlv_header,
  1996. WMITLV_TAG_STRUC_wmi_btm_config_fixed_param,
  1997. WMITLV_GET_STRUCT_TLVLEN(wmi_btm_config_fixed_param));
  1998. cmd->vdev_id = params->vdev_id;
  1999. cmd->flags = params->btm_offload_config;
  2000. cmd->max_attempt_cnt = params->btm_max_attempt_cnt;
  2001. cmd->solicited_timeout_ms = params->btm_solicited_timeout;
  2002. cmd->stick_time_seconds = params->btm_sticky_time;
  2003. cmd->disassoc_timer_threshold = params->disassoc_timer_threshold;
  2004. cmd->btm_bitmap = params->btm_query_bitmask;
  2005. cmd->btm_candidate_min_score = params->btm_candidate_min_score;
  2006. wmi_mtrace(WMI_ROAM_BTM_CONFIG_CMDID, cmd->vdev_id, 0);
  2007. if (wmi_unified_cmd_send(wmi_handle, buf, len,
  2008. WMI_ROAM_BTM_CONFIG_CMDID)) {
  2009. WMI_LOGE("%s: failed to send WMI_ROAM_BTM_CONFIG_CMDID",
  2010. __func__);
  2011. wmi_buf_free(buf);
  2012. return QDF_STATUS_E_FAILURE;
  2013. }
  2014. return QDF_STATUS_SUCCESS;
  2015. }
  2016. /**
  2017. * send_roam_bss_load_config_tlv() - send roam load bss trigger configuration
  2018. * @wmi_handle: wmi handle
  2019. * @parms: pointer to wmi_bss_load_config
  2020. *
  2021. * This function sends the roam load bss trigger configuration to fw.
  2022. * the bss_load_threshold parameter is used to configure the maximum
  2023. * bss load percentage, above which the firmware should trigger roaming
  2024. *
  2025. * Return: QDF status
  2026. */
  2027. static QDF_STATUS
  2028. send_roam_bss_load_config_tlv(wmi_unified_t wmi_handle,
  2029. struct wmi_bss_load_config *params)
  2030. {
  2031. wmi_roam_bss_load_config_cmd_fixed_param *cmd;
  2032. wmi_buf_t buf;
  2033. uint32_t len;
  2034. len = sizeof(*cmd);
  2035. buf = wmi_buf_alloc(wmi_handle, len);
  2036. if (!buf)
  2037. return QDF_STATUS_E_NOMEM;
  2038. cmd = (wmi_roam_bss_load_config_cmd_fixed_param *)wmi_buf_data(buf);
  2039. WMITLV_SET_HDR(
  2040. &cmd->tlv_header,
  2041. WMITLV_TAG_STRUC_wmi_roam_bss_load_config_cmd_fixed_param,
  2042. WMITLV_GET_STRUCT_TLVLEN(wmi_roam_bss_load_config_cmd_fixed_param));
  2043. cmd->vdev_id = params->vdev_id;
  2044. cmd->bss_load_threshold = params->bss_load_threshold;
  2045. cmd->monitor_time_window = params->bss_load_sample_time;
  2046. cmd->rssi_2g_threshold = params->rssi_threshold_24ghz;
  2047. cmd->rssi_5g_threshold = params->rssi_threshold_5ghz;
  2048. WMI_LOGD("%s: vdev:%d bss_load_thres:%d monitor_time:%d rssi_2g:%d rssi_5g:%d",
  2049. __func__, cmd->vdev_id, cmd->bss_load_threshold,
  2050. cmd->monitor_time_window, cmd->rssi_2g_threshold,
  2051. cmd->rssi_5g_threshold);
  2052. wmi_mtrace(WMI_ROAM_BSS_LOAD_CONFIG_CMDID, cmd->vdev_id, 0);
  2053. if (wmi_unified_cmd_send(wmi_handle, buf, len,
  2054. WMI_ROAM_BSS_LOAD_CONFIG_CMDID)) {
  2055. WMI_LOGE("%s: failed to send WMI_ROAM_BSS_LOAD_CONFIG_CMDID ",
  2056. __func__);
  2057. wmi_buf_free(buf);
  2058. return QDF_STATUS_E_FAILURE;
  2059. }
  2060. return QDF_STATUS_SUCCESS;
  2061. }
  2062. #ifdef WLAN_FEATURE_ROAM_OFFLOAD
  2063. /**
  2064. * send_disconnect_roam_params_tlv() - send disconnect roam trigger parameters
  2065. * @wmi_handle: wmi handle
  2066. * @disconnect_roam: pointer to wmi_disconnect_roam_params which carries the
  2067. * disconnect_roam_trigger parameters from CSR
  2068. *
  2069. * This function sends the disconnect roam trigger parameters to fw.
  2070. *
  2071. * Return: QDF status
  2072. */
  2073. static QDF_STATUS
  2074. send_disconnect_roam_params_tlv(wmi_unified_t wmi_handle,
  2075. struct wmi_disconnect_roam_params *req)
  2076. {
  2077. wmi_roam_deauth_config_cmd_fixed_param *cmd;
  2078. wmi_buf_t buf;
  2079. uint32_t len;
  2080. len = sizeof(*cmd);
  2081. buf = wmi_buf_alloc(wmi_handle, len);
  2082. if (!buf)
  2083. return QDF_STATUS_E_NOMEM;
  2084. cmd = (wmi_roam_deauth_config_cmd_fixed_param *)wmi_buf_data(buf);
  2085. WMITLV_SET_HDR(
  2086. &cmd->tlv_header,
  2087. WMITLV_TAG_STRUC_wmi_roam_deauth_config_cmd_fixed_param,
  2088. WMITLV_GET_STRUCT_TLVLEN(wmi_roam_deauth_config_cmd_fixed_param));
  2089. cmd->vdev_id = req->vdev_id;
  2090. cmd->enable = req->enable;
  2091. WMI_LOGD("%s: Send WMI_ROAM_DEAUTH_CONFIG vdev_id:%d enable:%d",
  2092. __func__, cmd->vdev_id, cmd->enable);
  2093. wmi_mtrace(WMI_ROAM_DEAUTH_CONFIG_CMDID, cmd->vdev_id, 0);
  2094. if (wmi_unified_cmd_send(wmi_handle, buf, len,
  2095. WMI_ROAM_DEAUTH_CONFIG_CMDID)) {
  2096. WMI_LOGE("%s: failed to send WMI_ROAM_DEAUTH_CONFIG_CMDID",
  2097. __func__);
  2098. wmi_buf_free(buf);
  2099. return QDF_STATUS_E_FAILURE;
  2100. }
  2101. return QDF_STATUS_SUCCESS;
  2102. }
  2103. /**
  2104. * send_idle_roam_params_tlv() - send idle roam trigger parameters
  2105. * @wmi_handle: wmi handle
  2106. * @idle_roam_params: pointer to wmi_idle_roam_params which carries the
  2107. * idle roam parameters from CSR
  2108. *
  2109. * This function sends the idle roam trigger parameters to fw.
  2110. *
  2111. * Return: QDF status
  2112. */
  2113. static QDF_STATUS
  2114. send_idle_roam_params_tlv(wmi_unified_t wmi_handle,
  2115. struct wmi_idle_roam_params *idle_roam_params)
  2116. {
  2117. wmi_roam_idle_config_cmd_fixed_param *cmd;
  2118. wmi_buf_t buf;
  2119. uint32_t len;
  2120. len = sizeof(*cmd);
  2121. buf = wmi_buf_alloc(wmi_handle, len);
  2122. if (!buf)
  2123. return QDF_STATUS_E_NOMEM;
  2124. cmd = (wmi_roam_idle_config_cmd_fixed_param *)wmi_buf_data(buf);
  2125. WMITLV_SET_HDR(
  2126. &cmd->tlv_header,
  2127. WMITLV_TAG_STRUC_wmi_roam_idle_config_cmd_fixed_param,
  2128. WMITLV_GET_STRUCT_TLVLEN(wmi_roam_idle_config_cmd_fixed_param));
  2129. cmd->vdev_id = idle_roam_params->vdev_id;
  2130. cmd->enable = idle_roam_params->enable;
  2131. cmd->band = idle_roam_params->band;
  2132. cmd->rssi_delta = idle_roam_params->conn_ap_rssi_delta;
  2133. cmd->min_rssi = idle_roam_params->conn_ap_min_rssi;
  2134. cmd->idle_time = idle_roam_params->inactive_time;
  2135. cmd->data_packet_count = idle_roam_params->data_pkt_count;
  2136. WMI_LOGD("%s: Send WMI_ROAM_IDLE_CONFIG_CMDID vdev_id:%d enable:%d",
  2137. __func__, cmd->vdev_id, cmd->enable);
  2138. WMI_LOGD("%s: band:%d rssi_delta:%d min_rssi:%d idle_time:%d data_pkt:%d",
  2139. __func__, cmd->band, cmd->rssi_delta, cmd->min_rssi,
  2140. cmd->idle_time, cmd->data_packet_count);
  2141. wmi_mtrace(WMI_ROAM_IDLE_CONFIG_CMDID, cmd->vdev_id, 0);
  2142. if (wmi_unified_cmd_send(wmi_handle, buf, len,
  2143. WMI_ROAM_IDLE_CONFIG_CMDID)) {
  2144. WMI_LOGE("%s: failed to send WMI_ROAM_IDLE_CONFIG_CMDID",
  2145. __func__);
  2146. wmi_buf_free(buf);
  2147. return QDF_STATUS_E_FAILURE;
  2148. }
  2149. return QDF_STATUS_SUCCESS;
  2150. }
  2151. /**
  2152. * send_roam_preauth_status_tlv() - send roam pre-authentication status
  2153. * @wmi_handle: wmi handle
  2154. * @params: pre-auth status params
  2155. *
  2156. * This function sends the roam pre-authentication status for WPA3 SAE
  2157. * pre-auth to target.
  2158. *
  2159. * Return: QDF status
  2160. */
  2161. static QDF_STATUS
  2162. send_roam_preauth_status_tlv(wmi_unified_t wmi_handle,
  2163. struct wmi_roam_auth_status_params *params)
  2164. {
  2165. wmi_roam_preauth_status_cmd_fixed_param *cmd;
  2166. wmi_buf_t buf;
  2167. uint32_t len;
  2168. uint8_t *buf_ptr;
  2169. len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + PMKID_LEN;
  2170. buf = wmi_buf_alloc(wmi_handle, len);
  2171. if (!buf)
  2172. return QDF_STATUS_E_NOMEM;
  2173. buf_ptr = (uint8_t *)wmi_buf_data(buf);
  2174. cmd = (wmi_roam_preauth_status_cmd_fixed_param *)buf_ptr;
  2175. WMITLV_SET_HDR(
  2176. &cmd->tlv_header,
  2177. WMITLV_TAG_STRUC_wmi_roam_preauth_status_cmd_fixed_param,
  2178. WMITLV_GET_STRUCT_TLVLEN(wmi_roam_preauth_status_cmd_fixed_param));
  2179. cmd->vdev_id = params->vdev_id;
  2180. cmd->preauth_status = params->preauth_status;
  2181. WMI_CHAR_ARRAY_TO_MAC_ADDR(params->bssid.bytes,
  2182. &cmd->candidate_ap_bssid);
  2183. buf_ptr += sizeof(wmi_roam_preauth_status_cmd_fixed_param);
  2184. WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, PMKID_LEN);
  2185. buf_ptr += WMI_TLV_HDR_SIZE;
  2186. qdf_mem_copy(buf_ptr, params->pmkid, PMKID_LEN);
  2187. WMI_LOGD("%s: vdev_id:%d status:%d bssid:%pM", __func__, cmd->vdev_id,
  2188. cmd->preauth_status, params->bssid.bytes);
  2189. wmi_mtrace(WMI_ROAM_PREAUTH_STATUS_CMDID, cmd->vdev_id, 0);
  2190. if (wmi_unified_cmd_send(wmi_handle, buf, len,
  2191. WMI_ROAM_PREAUTH_STATUS_CMDID)) {
  2192. wmi_buf_free(buf);
  2193. return QDF_STATUS_E_FAILURE;
  2194. }
  2195. return QDF_STATUS_SUCCESS;
  2196. }
  2197. /**
  2198. * convert_control_roam_trigger_reason_bitmap() - Convert roam trigger bitmap
  2199. *
  2200. * @trigger_reason_bitmap: Roam trigger reason bitmap received from upper layers
  2201. *
  2202. * Converts the controlled roam trigger reason bitmap of
  2203. * type @roam_control_trigger_reason to firmware trigger
  2204. * reason bitmap as defined in
  2205. * trigger_reason_bitmask @wmi_roam_enable_disable_trigger_reason_fixed_param
  2206. *
  2207. * Return: trigger_reason_bitmask as defined in
  2208. * wmi_roam_enable_disable_trigger_reason_fixed_param
  2209. */
  2210. static uint32_t
  2211. convert_control_roam_trigger_reason_bitmap(uint32_t trigger_reason_bitmap)
  2212. {
  2213. uint32_t fw_trigger_bitmap = 0, all_bitmap;
  2214. /* Enable the complete trigger bitmap when all bits are set in
  2215. * the control config bitmap
  2216. */
  2217. all_bitmap = BIT(ROAM_TRIGGER_REASON_MAX) - 1;
  2218. if (trigger_reason_bitmap == all_bitmap)
  2219. return BIT(WMI_ROAM_TRIGGER_EXT_REASON_MAX) - 1;
  2220. if (trigger_reason_bitmap & BIT(ROAM_TRIGGER_REASON_NONE))
  2221. fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_NONE);
  2222. if (trigger_reason_bitmap & BIT(ROAM_TRIGGER_REASON_PER))
  2223. fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_PER);
  2224. if (trigger_reason_bitmap & BIT(ROAM_TRIGGER_REASON_BMISS))
  2225. fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_BMISS);
  2226. if (trigger_reason_bitmap & BIT(ROAM_TRIGGER_REASON_LOW_RSSI))
  2227. fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_LOW_RSSI);
  2228. if (trigger_reason_bitmap & BIT(ROAM_TRIGGER_REASON_HIGH_RSSI))
  2229. fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_HIGH_RSSI);
  2230. if (trigger_reason_bitmap & BIT(ROAM_TRIGGER_REASON_PERIODIC))
  2231. fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_PERIODIC);
  2232. if (trigger_reason_bitmap & BIT(ROAM_TRIGGER_REASON_MAWC))
  2233. fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_MAWC);
  2234. if (trigger_reason_bitmap & BIT(ROAM_TRIGGER_REASON_DENSE))
  2235. fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_DENSE);
  2236. if (trigger_reason_bitmap & BIT(ROAM_TRIGGER_REASON_BACKGROUND))
  2237. fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_BACKGROUND);
  2238. if (trigger_reason_bitmap & BIT(ROAM_TRIGGER_REASON_FORCED))
  2239. fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_FORCED);
  2240. if (trigger_reason_bitmap & BIT(ROAM_TRIGGER_REASON_BTM))
  2241. fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_BTM);
  2242. if (trigger_reason_bitmap & BIT(ROAM_TRIGGER_REASON_UNIT_TEST))
  2243. fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_UNIT_TEST);
  2244. if (trigger_reason_bitmap & BIT(ROAM_TRIGGER_REASON_BSS_LOAD))
  2245. fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_BSS_LOAD);
  2246. if (trigger_reason_bitmap & BIT(ROAM_TRIGGER_REASON_DEAUTH))
  2247. fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_DEAUTH);
  2248. if (trigger_reason_bitmap & BIT(ROAM_TRIGGER_REASON_IDLE))
  2249. fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_IDLE);
  2250. if (trigger_reason_bitmap & BIT(ROAM_TRIGGER_REASON_STA_KICKOUT))
  2251. fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_STA_KICKOUT);
  2252. return fw_trigger_bitmap;
  2253. }
  2254. /**
  2255. * get_internal_mandatory_roam_triggers() - Internal triggers to be added
  2256. *
  2257. * Return: the bitmap of mandatory triggers to be sent to firmware but not given
  2258. * by user.
  2259. */
  2260. static uint32_t
  2261. get_internal_mandatory_roam_triggers(void)
  2262. {
  2263. return BIT(WMI_ROAM_TRIGGER_REASON_FORCED);
  2264. }
  2265. /**
  2266. * send_set_roam_trigger_cmd_tlv() - send set roam triggers to fw
  2267. *
  2268. * @wmi_handle: wmi handle
  2269. * @vdev_id: vdev id
  2270. * @trigger_bitmap: roam trigger bitmap to be enabled
  2271. *
  2272. * Send WMI_ROAM_ENABLE_DISABLE_TRIGGER_REASON_CMDID to fw.
  2273. *
  2274. * Return: QDF_STATUS
  2275. */
  2276. static QDF_STATUS send_set_roam_trigger_cmd_tlv(wmi_unified_t wmi_handle,
  2277. uint32_t vdev_id,
  2278. uint32_t trigger_bitmap)
  2279. {
  2280. wmi_buf_t buf;
  2281. wmi_roam_enable_disable_trigger_reason_fixed_param *cmd;
  2282. uint16_t len = sizeof(*cmd);
  2283. int ret;
  2284. buf = wmi_buf_alloc(wmi_handle, len);
  2285. if (!buf) {
  2286. WMI_LOGE("%s: Failed to allocate wmi buffer", __func__);
  2287. return QDF_STATUS_E_NOMEM;
  2288. }
  2289. cmd = (wmi_roam_enable_disable_trigger_reason_fixed_param *)
  2290. wmi_buf_data(buf);
  2291. WMITLV_SET_HDR(&cmd->tlv_header,
  2292. WMITLV_TAG_STRUC_wmi_roam_enable_disable_trigger_reason_fixed_param,
  2293. WMITLV_GET_STRUCT_TLVLEN
  2294. (wmi_roam_enable_disable_trigger_reason_fixed_param));
  2295. cmd->vdev_id = vdev_id;
  2296. cmd->trigger_reason_bitmask =
  2297. convert_control_roam_trigger_reason_bitmap(trigger_bitmap);
  2298. WMI_LOGD("Received trigger bitmap: 0x%x converted trigger_bitmap: 0x%x",
  2299. trigger_bitmap, cmd->trigger_reason_bitmask);
  2300. cmd->trigger_reason_bitmask |= get_internal_mandatory_roam_triggers();
  2301. WMI_LOGD("WMI_ROAM_ENABLE_DISABLE_TRIGGER_REASON_CMDID vdev id: %d final trigger_bitmap: 0x%x",
  2302. cmd->vdev_id, cmd->trigger_reason_bitmask);
  2303. wmi_mtrace(WMI_ROAM_ENABLE_DISABLE_TRIGGER_REASON_CMDID, vdev_id, 0);
  2304. ret = wmi_unified_cmd_send(wmi_handle, buf, len,
  2305. WMI_ROAM_ENABLE_DISABLE_TRIGGER_REASON_CMDID);
  2306. if (QDF_IS_STATUS_ERROR(ret)) {
  2307. WMI_LOGE("Failed to send set roam triggers command ret = %d",
  2308. ret);
  2309. wmi_buf_free(buf);
  2310. }
  2311. return ret;
  2312. }
  2313. #else
  2314. static inline QDF_STATUS
  2315. send_disconnect_roam_params_tlv(wmi_unified_t wmi_handle,
  2316. struct wmi_disconnect_roam_params *req)
  2317. {
  2318. return QDF_STATUS_E_FAILURE;
  2319. }
  2320. static inline QDF_STATUS
  2321. send_idle_roam_params_tlv(wmi_unified_t wmi_handle,
  2322. struct wmi_idle_roam_params *idle_roam_params)
  2323. {
  2324. return QDF_STATUS_E_FAILURE;
  2325. }
  2326. static inline QDF_STATUS
  2327. send_roam_preauth_status_tlv(wmi_unified_t wmi_handle,
  2328. struct wmi_roam_auth_status_params *params)
  2329. {
  2330. return QDF_STATUS_E_FAILURE;
  2331. }
  2332. static QDF_STATUS
  2333. send_set_roam_trigger_cmd_tlv(wmi_unified_t wmi_handle,
  2334. uint32_t vdev_id,
  2335. uint32_t trigger_bitmap)
  2336. {
  2337. return QDF_STATUS_E_FAILURE;
  2338. }
  2339. #endif
  2340. /**
  2341. * send_offload_11k_cmd_tlv() - send wmi cmd with 11k offload params
  2342. * @wmi_handle: wmi handler
  2343. * @params: pointer to 11k offload params
  2344. *
  2345. * Return: 0 for success and non zero for failure
  2346. */
  2347. static QDF_STATUS send_offload_11k_cmd_tlv(wmi_unified_t wmi_handle,
  2348. struct wmi_11k_offload_params *params)
  2349. {
  2350. wmi_11k_offload_report_fixed_param *cmd;
  2351. wmi_buf_t buf;
  2352. QDF_STATUS status;
  2353. uint8_t *buf_ptr;
  2354. wmi_neighbor_report_11k_offload_tlv_param
  2355. *neighbor_report_offload_params;
  2356. wmi_neighbor_report_offload *neighbor_report_offload;
  2357. uint32_t len = sizeof(*cmd);
  2358. if (params->offload_11k_bitmask &
  2359. WMI_11K_OFFLOAD_BITMAP_NEIGHBOR_REPORT_REQ)
  2360. len += WMI_TLV_HDR_SIZE +
  2361. sizeof(wmi_neighbor_report_11k_offload_tlv_param);
  2362. buf = wmi_buf_alloc(wmi_handle, len);
  2363. if (!buf) {
  2364. return QDF_STATUS_E_NOMEM;
  2365. }
  2366. buf_ptr = (uint8_t *) wmi_buf_data(buf);
  2367. cmd = (wmi_11k_offload_report_fixed_param *) buf_ptr;
  2368. WMITLV_SET_HDR(&cmd->tlv_header,
  2369. WMITLV_TAG_STRUC_wmi_offload_11k_report_fixed_param,
  2370. WMITLV_GET_STRUCT_TLVLEN(
  2371. wmi_11k_offload_report_fixed_param));
  2372. cmd->vdev_id = params->vdev_id;
  2373. cmd->offload_11k = params->offload_11k_bitmask;
  2374. if (params->offload_11k_bitmask &
  2375. WMI_11K_OFFLOAD_BITMAP_NEIGHBOR_REPORT_REQ) {
  2376. buf_ptr += sizeof(wmi_11k_offload_report_fixed_param);
  2377. WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
  2378. sizeof(wmi_neighbor_report_11k_offload_tlv_param));
  2379. buf_ptr += WMI_TLV_HDR_SIZE;
  2380. neighbor_report_offload_params =
  2381. (wmi_neighbor_report_11k_offload_tlv_param *)buf_ptr;
  2382. WMITLV_SET_HDR(&neighbor_report_offload_params->tlv_header,
  2383. WMITLV_TAG_STRUC_wmi_neighbor_report_offload_tlv_param,
  2384. WMITLV_GET_STRUCT_TLVLEN(
  2385. wmi_neighbor_report_11k_offload_tlv_param));
  2386. neighbor_report_offload = &neighbor_report_offload_params->
  2387. neighbor_rep_ofld_params;
  2388. neighbor_report_offload->time_offset =
  2389. params->neighbor_report_params.time_offset;
  2390. neighbor_report_offload->low_rssi_offset =
  2391. params->neighbor_report_params.low_rssi_offset;
  2392. neighbor_report_offload->bmiss_count_trigger =
  2393. params->neighbor_report_params.bmiss_count_trigger;
  2394. neighbor_report_offload->per_threshold_offset =
  2395. params->neighbor_report_params.per_threshold_offset;
  2396. neighbor_report_offload->neighbor_report_cache_timeout =
  2397. params->neighbor_report_params.
  2398. neighbor_report_cache_timeout;
  2399. neighbor_report_offload->max_neighbor_report_req_cap =
  2400. params->neighbor_report_params.
  2401. max_neighbor_report_req_cap;
  2402. neighbor_report_offload->ssid.ssid_len =
  2403. params->neighbor_report_params.ssid.length;
  2404. qdf_mem_copy(neighbor_report_offload->ssid.ssid,
  2405. &params->neighbor_report_params.ssid.mac_ssid,
  2406. neighbor_report_offload->ssid.ssid_len);
  2407. }
  2408. wmi_mtrace(WMI_11K_OFFLOAD_REPORT_CMDID, cmd->vdev_id, 0);
  2409. status = wmi_unified_cmd_send(wmi_handle, buf, len,
  2410. WMI_11K_OFFLOAD_REPORT_CMDID);
  2411. if (status != QDF_STATUS_SUCCESS) {
  2412. WMI_LOGE("%s: failed to send 11k offload command %d",
  2413. __func__, status);
  2414. wmi_buf_free(buf);
  2415. }
  2416. return status;
  2417. }
  2418. /**
  2419. * send_invoke_neighbor_report_cmd_tlv() - send invoke 11k neighbor report
  2420. * command
  2421. * @wmi_handle: wmi handler
  2422. * @params: pointer to neighbor report invoke params
  2423. *
  2424. * Return: 0 for success and non zero for failure
  2425. */
  2426. static QDF_STATUS send_invoke_neighbor_report_cmd_tlv(wmi_unified_t wmi_handle,
  2427. struct wmi_invoke_neighbor_report_params *params)
  2428. {
  2429. wmi_11k_offload_invoke_neighbor_report_fixed_param *cmd;
  2430. wmi_buf_t buf;
  2431. QDF_STATUS status;
  2432. uint8_t *buf_ptr;
  2433. uint32_t len = sizeof(*cmd);
  2434. buf = wmi_buf_alloc(wmi_handle, len);
  2435. if (!buf) {
  2436. return QDF_STATUS_E_NOMEM;
  2437. }
  2438. buf_ptr = (uint8_t *) wmi_buf_data(buf);
  2439. cmd = (wmi_11k_offload_invoke_neighbor_report_fixed_param *) buf_ptr;
  2440. WMITLV_SET_HDR(&cmd->tlv_header,
  2441. WMITLV_TAG_STRUC_wmi_invoke_neighbor_report_fixed_param,
  2442. WMITLV_GET_STRUCT_TLVLEN(
  2443. wmi_11k_offload_invoke_neighbor_report_fixed_param));
  2444. cmd->vdev_id = params->vdev_id;
  2445. cmd->flags = params->send_resp_to_host;
  2446. cmd->ssid.ssid_len = params->ssid.length;
  2447. qdf_mem_copy(cmd->ssid.ssid,
  2448. &params->ssid.mac_ssid,
  2449. cmd->ssid.ssid_len);
  2450. wmi_mtrace(WMI_11K_INVOKE_NEIGHBOR_REPORT_CMDID, cmd->vdev_id, 0);
  2451. status = wmi_unified_cmd_send(wmi_handle, buf, len,
  2452. WMI_11K_INVOKE_NEIGHBOR_REPORT_CMDID);
  2453. if (status != QDF_STATUS_SUCCESS) {
  2454. WMI_LOGE("%s: failed to send invoke neighbor report command %d",
  2455. __func__, status);
  2456. wmi_buf_free(buf);
  2457. }
  2458. return status;
  2459. }
  2460. void wmi_roam_attach_tlv(wmi_unified_t wmi_handle)
  2461. {
  2462. struct wmi_ops *ops = wmi_handle->ops;
  2463. ops->send_roam_scan_offload_rssi_thresh_cmd =
  2464. send_roam_scan_offload_rssi_thresh_cmd_tlv;
  2465. ops->send_roam_mawc_params_cmd = send_roam_mawc_params_cmd_tlv;
  2466. ops->send_roam_scan_filter_cmd =
  2467. send_roam_scan_filter_cmd_tlv;
  2468. ops->send_roam_scan_offload_mode_cmd =
  2469. send_roam_scan_offload_mode_cmd_tlv;
  2470. ops->send_roam_scan_offload_ap_profile_cmd =
  2471. send_roam_scan_offload_ap_profile_cmd_tlv;
  2472. ops->send_roam_scan_offload_cmd = send_roam_scan_offload_cmd_tlv;
  2473. ops->send_roam_scan_offload_scan_period_cmd =
  2474. send_roam_scan_offload_scan_period_cmd_tlv;
  2475. ops->send_roam_scan_offload_chan_list_cmd =
  2476. send_roam_scan_offload_chan_list_cmd_tlv;
  2477. ops->send_roam_scan_offload_rssi_change_cmd =
  2478. send_roam_scan_offload_rssi_change_cmd_tlv;
  2479. ops->send_per_roam_config_cmd = send_per_roam_config_cmd_tlv;
  2480. ops->send_limit_off_chan_cmd = send_limit_off_chan_cmd_tlv;
  2481. ops->send_btm_config = send_btm_config_cmd_tlv;
  2482. ops->send_offload_11k_cmd = send_offload_11k_cmd_tlv;
  2483. ops->send_invoke_neighbor_report_cmd =
  2484. send_invoke_neighbor_report_cmd_tlv;
  2485. ops->send_roam_bss_load_config = send_roam_bss_load_config_tlv;
  2486. ops->send_idle_roam_params = send_idle_roam_params_tlv;
  2487. ops->send_disconnect_roam_params = send_disconnect_roam_params_tlv;
  2488. ops->send_roam_preauth_status = send_roam_preauth_status_tlv;
  2489. ops->send_set_roam_trigger_cmd = send_set_roam_trigger_cmd_tlv,
  2490. wmi_lfr_subnet_detection_attach_tlv(wmi_handle);
  2491. wmi_rssi_monitor_attach_tlv(wmi_handle);
  2492. wmi_ese_attach_tlv(wmi_handle);
  2493. wmi_roam_offload_attach_tlv(wmi_handle);
  2494. wmi_fils_sk_attach_tlv(wmi_handle);
  2495. }