dp_mlo.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803
  1. /*
  2. * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
  3. *
  4. * Permission to use, copy, modify, and/or distribute this software for any
  5. * purpose with or without fee is hereby granted, provided that the above
  6. * copyright notice and this permission notice appear in all copies.
  7. *
  8. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  9. * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  10. * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  11. * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  12. * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  13. * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  14. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  15. */
  16. #include <wlan_utility.h>
  17. #include <dp_internal.h>
  18. #include <dp_htt.h>
  19. #include <hal_be_api.h>
  20. #include "dp_mlo.h"
  21. #include <dp_be.h>
  22. #include <dp_htt.h>
  23. #include <dp_internal.h>
  24. #include <wlan_cfg.h>
  25. #include <wlan_mlo_mgr_cmn.h>
  26. /*
  27. * dp_mlo_ctxt_attach_wifi3 () – Attach DP MLO context
  28. *
  29. * Return: DP MLO context handle on success, NULL on failure
  30. */
  31. struct cdp_mlo_ctxt *
  32. dp_mlo_ctxt_attach_wifi3(struct cdp_ctrl_mlo_mgr *ctrl_ctxt)
  33. {
  34. struct dp_mlo_ctxt *mlo_ctxt =
  35. qdf_mem_malloc(sizeof(struct dp_mlo_ctxt));
  36. if (!mlo_ctxt) {
  37. dp_err("Failed to allocate DP MLO Context");
  38. return NULL;
  39. }
  40. mlo_ctxt->ctrl_ctxt = ctrl_ctxt;
  41. if (dp_mlo_peer_find_hash_attach_be
  42. (mlo_ctxt, DP_MAX_MLO_PEER) != QDF_STATUS_SUCCESS) {
  43. dp_err("Failed to allocate peer hash");
  44. qdf_mem_free(mlo_ctxt);
  45. return NULL;
  46. }
  47. qdf_get_random_bytes(mlo_ctxt->toeplitz_hash_ipv4,
  48. (sizeof(mlo_ctxt->toeplitz_hash_ipv4[0]) *
  49. LRO_IPV4_SEED_ARR_SZ));
  50. qdf_get_random_bytes(mlo_ctxt->toeplitz_hash_ipv6,
  51. (sizeof(mlo_ctxt->toeplitz_hash_ipv6[0]) *
  52. LRO_IPV6_SEED_ARR_SZ));
  53. qdf_spinlock_create(&mlo_ctxt->ml_soc_list_lock);
  54. return dp_mlo_ctx_to_cdp(mlo_ctxt);
  55. }
  56. qdf_export_symbol(dp_mlo_ctxt_attach_wifi3);
  57. /*
  58. * dp_mlo_ctxt_detach_wifi3 () – Detach DP MLO context
  59. *
  60. * @ml_ctxt: pointer to DP MLO context
  61. *
  62. * Return: void
  63. */
  64. void dp_mlo_ctxt_detach_wifi3(struct cdp_mlo_ctxt *cdp_ml_ctxt)
  65. {
  66. struct dp_mlo_ctxt *mlo_ctxt = cdp_mlo_ctx_to_dp(cdp_ml_ctxt);
  67. if (!cdp_ml_ctxt)
  68. return;
  69. qdf_spinlock_destroy(&mlo_ctxt->ml_soc_list_lock);
  70. dp_mlo_peer_find_hash_detach_be(mlo_ctxt);
  71. qdf_mem_free(mlo_ctxt);
  72. }
  73. qdf_export_symbol(dp_mlo_ctxt_detach_wifi3);
  74. /*
  75. * dp_mlo_set_soc_by_chip_id() – Add DP soc to ML context soc list
  76. *
  77. * @ml_ctxt: DP ML context handle
  78. * @soc: DP soc handle
  79. * @chip_id: MLO chip id
  80. *
  81. * Return: void
  82. */
  83. void dp_mlo_set_soc_by_chip_id(struct dp_mlo_ctxt *ml_ctxt,
  84. struct dp_soc *soc,
  85. uint8_t chip_id)
  86. {
  87. qdf_spin_lock_bh(&ml_ctxt->ml_soc_list_lock);
  88. ml_ctxt->ml_soc_list[chip_id] = soc;
  89. qdf_spin_unlock_bh(&ml_ctxt->ml_soc_list_lock);
  90. }
  91. /*
  92. * dp_mlo_get_soc_ref_by_chip_id() – Get DP soc from DP ML context.
  93. * This API will increment a reference count for DP soc. Caller has
  94. * to take care for decrementing refcount.
  95. *
  96. * @ml_ctxt: DP ML context handle
  97. * @chip_id: MLO chip id
  98. *
  99. * Return: dp_soc
  100. */
  101. struct dp_soc*
  102. dp_mlo_get_soc_ref_by_chip_id(struct dp_mlo_ctxt *ml_ctxt,
  103. uint8_t chip_id)
  104. {
  105. struct dp_soc *soc = NULL;
  106. if (!ml_ctxt) {
  107. dp_warn("MLO context not created, MLO not enabled");
  108. return NULL;
  109. }
  110. qdf_spin_lock_bh(&ml_ctxt->ml_soc_list_lock);
  111. soc = ml_ctxt->ml_soc_list[chip_id];
  112. if (!soc) {
  113. qdf_spin_unlock_bh(&ml_ctxt->ml_soc_list_lock);
  114. return NULL;
  115. }
  116. qdf_atomic_inc(&soc->ref_count);
  117. qdf_spin_unlock_bh(&ml_ctxt->ml_soc_list_lock);
  118. return soc;
  119. }
  120. static QDF_STATUS dp_partner_soc_rx_hw_cc_init(struct dp_mlo_ctxt *mlo_ctxt,
  121. struct dp_soc_be *be_soc)
  122. {
  123. uint8_t i;
  124. struct dp_soc *partner_soc;
  125. struct dp_soc_be *be_partner_soc;
  126. uint8_t pool_id;
  127. QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
  128. for (i = 0; i < WLAN_MAX_MLO_CHIPS; i++) {
  129. partner_soc = dp_mlo_get_soc_ref_by_chip_id(mlo_ctxt, i);
  130. if (!partner_soc) {
  131. dp_err("partner_soc is NULL");
  132. continue;
  133. }
  134. be_partner_soc = dp_get_be_soc_from_dp_soc(partner_soc);
  135. for (pool_id = 0; pool_id < MAX_RXDESC_POOLS; pool_id++) {
  136. qdf_status =
  137. dp_hw_cookie_conversion_init
  138. (be_soc,
  139. &be_partner_soc->rx_cc_ctx[pool_id]);
  140. if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
  141. dp_alert("MLO partner soc RX CC init failed");
  142. return qdf_status;
  143. }
  144. }
  145. }
  146. return qdf_status;
  147. }
  148. static void dp_mlo_soc_setup(struct cdp_soc_t *soc_hdl,
  149. struct cdp_mlo_ctxt *cdp_ml_ctxt)
  150. {
  151. struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
  152. struct dp_mlo_ctxt *mlo_ctxt = cdp_mlo_ctx_to_dp(cdp_ml_ctxt);
  153. struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(soc);
  154. if (!cdp_ml_ctxt)
  155. return;
  156. dp_mlo_set_soc_by_chip_id(mlo_ctxt, soc, be_soc->mlo_chip_id);
  157. }
  158. static void dp_mlo_soc_teardown(struct cdp_soc_t *soc_hdl,
  159. struct cdp_mlo_ctxt *cdp_ml_ctxt)
  160. {
  161. struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
  162. struct dp_mlo_ctxt *mlo_ctxt = cdp_mlo_ctx_to_dp(cdp_ml_ctxt);
  163. struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(soc);
  164. if (!cdp_ml_ctxt)
  165. return;
  166. dp_mlo_set_soc_by_chip_id(mlo_ctxt, NULL, be_soc->mlo_chip_id);
  167. }
  168. static QDF_STATUS dp_mlo_add_ptnr_vdev(struct dp_vdev *vdev1,
  169. struct dp_vdev *vdev2,
  170. struct dp_soc *soc, uint8_t pdev_id)
  171. {
  172. struct dp_soc_be *soc_be = dp_get_be_soc_from_dp_soc(soc);
  173. struct dp_vdev_be *vdev2_be = dp_get_be_vdev_from_dp_vdev(vdev2);
  174. /* return when valid entry exists */
  175. if (vdev2_be->partner_vdev_list[soc_be->mlo_chip_id][pdev_id] !=
  176. CDP_INVALID_VDEV_ID)
  177. return QDF_STATUS_SUCCESS;
  178. if (dp_vdev_get_ref(soc, vdev1, DP_MOD_ID_RX) !=
  179. QDF_STATUS_SUCCESS) {
  180. qdf_info("%pK: unable to get vdev reference vdev %pK vdev_id %u",
  181. soc, vdev1, vdev1->vdev_id);
  182. return QDF_STATUS_E_FAILURE;
  183. }
  184. vdev2_be->partner_vdev_list[soc_be->mlo_chip_id][pdev_id] =
  185. vdev1->vdev_id;
  186. mlo_debug("Add vdev%d to vdev%d list, mlo_chip_id = %d pdev_id = %d\n",
  187. vdev1->vdev_id, vdev2->vdev_id, soc_be->mlo_chip_id, pdev_id);
  188. return QDF_STATUS_SUCCESS;
  189. }
  190. QDF_STATUS dp_update_mlo_ptnr_list(struct cdp_soc_t *soc_hdl,
  191. int8_t partner_vdev_ids[], uint8_t num_vdevs,
  192. uint8_t self_vdev_id)
  193. {
  194. int i, j;
  195. struct dp_soc *self_soc = cdp_soc_t_to_dp_soc(soc_hdl);
  196. struct dp_vdev *self_vdev;
  197. QDF_STATUS ret = QDF_STATUS_SUCCESS;
  198. struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(self_soc);
  199. struct dp_mlo_ctxt *dp_mlo = be_soc->ml_ctxt;
  200. if (!dp_mlo)
  201. return QDF_STATUS_E_FAILURE;
  202. self_vdev = dp_vdev_get_ref_by_id(self_soc, self_vdev_id, DP_MOD_ID_RX);
  203. if (!self_vdev)
  204. return QDF_STATUS_E_FAILURE;
  205. /* go through the input vdev id list and if there are partner vdevs,
  206. * - then add the current vdev's id to partner vdev's list using pdev_id and
  207. * increase the reference
  208. * - add partner vdev to self list and increase the reference
  209. */
  210. for (i = 0; i < num_vdevs; i++) {
  211. if (partner_vdev_ids[i] == CDP_INVALID_VDEV_ID)
  212. continue;
  213. for (j = 0; j < WLAN_MAX_MLO_CHIPS; j++) {
  214. struct dp_soc *soc =
  215. dp_mlo_get_soc_ref_by_chip_id(dp_mlo, j);
  216. if (soc) {
  217. struct dp_vdev *vdev;
  218. vdev = dp_vdev_get_ref_by_id(soc,
  219. partner_vdev_ids[i], DP_MOD_ID_RX);
  220. if (vdev) {
  221. if (vdev == self_vdev) {
  222. dp_vdev_unref_delete(soc,
  223. vdev, DP_MOD_ID_RX);
  224. /*dp_soc_unref_delete(soc); */
  225. continue;
  226. }
  227. if (qdf_is_macaddr_equal(
  228. (struct qdf_mac_addr *)self_vdev->mld_mac_addr.raw,
  229. (struct qdf_mac_addr *)vdev->mld_mac_addr.raw)) {
  230. if (dp_mlo_add_ptnr_vdev(self_vdev,
  231. vdev, self_soc,
  232. self_vdev->pdev->pdev_id) !=
  233. QDF_STATUS_SUCCESS) {
  234. dp_err("Unable to add self to partner vdev's list");
  235. dp_vdev_unref_delete(soc,
  236. vdev, DP_MOD_ID_RX);
  237. /* TODO - release soc ref here */
  238. /* dp_soc_unref_delete(soc);*/
  239. ret = QDF_STATUS_E_FAILURE;
  240. goto exit;
  241. }
  242. /* add to self list */
  243. if (dp_mlo_add_ptnr_vdev(vdev, self_vdev, soc,
  244. vdev->pdev->pdev_id) !=
  245. QDF_STATUS_SUCCESS) {
  246. dp_err("Unable to add vdev to self vdev's list");
  247. dp_vdev_unref_delete(self_soc,
  248. vdev, DP_MOD_ID_RX);
  249. /* TODO - relase soc ref here */
  250. /* dp_soc_unref_delete(soc);*/
  251. ret = QDF_STATUS_E_FAILURE;
  252. goto exit;
  253. }
  254. }
  255. dp_vdev_unref_delete(soc, vdev,
  256. DP_MOD_ID_RX);
  257. } /* vdev */
  258. /* TODO - release soc ref here */
  259. /* dp_soc_unref_delete(soc); */
  260. } /* soc */
  261. } /* for */
  262. } /* for */
  263. exit:
  264. dp_vdev_unref_delete(self_soc, self_vdev, DP_MOD_ID_RX);
  265. return ret;
  266. }
  267. void dp_clr_mlo_ptnr_list(struct dp_soc *soc, struct dp_vdev *vdev)
  268. {
  269. struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(soc);
  270. struct dp_vdev_be *vdev_be = dp_get_be_vdev_from_dp_vdev(vdev);
  271. struct dp_mlo_ctxt *dp_mlo = be_soc->ml_ctxt;
  272. uint8_t soc_id = be_soc->mlo_chip_id;
  273. uint8_t pdev_id = vdev->pdev->pdev_id;
  274. int i, j;
  275. for (i = 0; i < WLAN_MAX_MLO_CHIPS; i++) {
  276. for (j = 0; j < WLAN_MAX_MLO_LINKS_PER_SOC; j++) {
  277. struct dp_vdev *pr_vdev;
  278. struct dp_soc *pr_soc;
  279. struct dp_soc_be *pr_soc_be;
  280. struct dp_pdev *pr_pdev;
  281. struct dp_vdev_be *pr_vdev_be;
  282. if (vdev_be->partner_vdev_list[i][j] ==
  283. CDP_INVALID_VDEV_ID)
  284. continue;
  285. pr_soc = dp_mlo_get_soc_ref_by_chip_id(dp_mlo, i);
  286. if (!pr_soc)
  287. continue;
  288. pr_soc_be = dp_get_be_soc_from_dp_soc(pr_soc);
  289. pr_vdev = dp_vdev_get_ref_by_id(pr_soc,
  290. vdev_be->partner_vdev_list[i][j],
  291. DP_MOD_ID_RX);
  292. if (!pr_vdev)
  293. continue;
  294. /* release ref and remove self vdev from partner list */
  295. pr_vdev_be = dp_get_be_vdev_from_dp_vdev(pr_vdev);
  296. dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_RX);
  297. pr_vdev_be->partner_vdev_list[soc_id][pdev_id] =
  298. CDP_INVALID_VDEV_ID;
  299. /* release ref and remove partner vdev from self list */
  300. dp_vdev_unref_delete(pr_soc, pr_vdev, DP_MOD_ID_RX);
  301. pr_pdev = pr_vdev->pdev;
  302. vdev_be->partner_vdev_list[pr_soc_be->mlo_chip_id][pr_pdev->pdev_id] =
  303. CDP_INVALID_VDEV_ID;
  304. dp_vdev_unref_delete(pr_soc, pr_vdev, DP_MOD_ID_RX);
  305. }
  306. }
  307. }
  308. static void dp_mlo_setup_complete(struct cdp_mlo_ctxt *cdp_ml_ctxt)
  309. {
  310. struct dp_mlo_ctxt *mlo_ctxt = cdp_mlo_ctx_to_dp(cdp_ml_ctxt);
  311. int i;
  312. struct dp_soc *soc;
  313. struct dp_soc_be *be_soc;
  314. QDF_STATUS qdf_status;
  315. if (!cdp_ml_ctxt)
  316. return;
  317. for (i = 0; i < WLAN_MAX_MLO_CHIPS; i++) {
  318. soc = dp_mlo_get_soc_ref_by_chip_id(mlo_ctxt, i);
  319. if (!soc)
  320. continue;
  321. be_soc = dp_get_be_soc_from_dp_soc(soc);
  322. qdf_status = dp_partner_soc_rx_hw_cc_init(mlo_ctxt, be_soc);
  323. if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
  324. dp_alert("MLO partner SOC Rx desc CC init failed");
  325. qdf_assert_always(0);
  326. }
  327. }
  328. }
  329. static void dp_mlo_update_delta_tsf2(struct cdp_soc_t *soc_hdl,
  330. uint8_t pdev_id, uint64_t delta_tsf2)
  331. {
  332. struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
  333. struct dp_pdev *pdev;
  334. struct dp_pdev_be *be_pdev;
  335. pdev = dp_get_pdev_from_soc_pdev_id_wifi3((struct dp_soc *)soc,
  336. pdev_id);
  337. if (!pdev) {
  338. dp_err("pdev is NULL for pdev_id %u", pdev_id);
  339. return;
  340. }
  341. be_pdev = dp_get_be_pdev_from_dp_pdev(pdev);
  342. be_pdev->delta_tsf2 = delta_tsf2;
  343. }
  344. static void dp_mlo_update_delta_tqm(struct cdp_soc_t *soc_hdl,
  345. uint64_t delta_tqm)
  346. {
  347. struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
  348. struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(soc);
  349. be_soc->delta_tqm = delta_tqm;
  350. }
  351. static void dp_mlo_update_mlo_ts_offset(struct cdp_soc_t *soc_hdl,
  352. uint64_t offset)
  353. {
  354. struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
  355. struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(soc);
  356. be_soc->mlo_tstamp_offset = offset;
  357. }
  358. static struct cdp_mlo_ops dp_mlo_ops = {
  359. .mlo_soc_setup = dp_mlo_soc_setup,
  360. .mlo_soc_teardown = dp_mlo_soc_teardown,
  361. .update_mlo_ptnr_list = dp_update_mlo_ptnr_list,
  362. .mlo_setup_complete = dp_mlo_setup_complete,
  363. .mlo_update_delta_tsf2 = dp_mlo_update_delta_tsf2,
  364. .mlo_update_delta_tqm = dp_mlo_update_delta_tqm,
  365. .mlo_update_mlo_ts_offset = dp_mlo_update_mlo_ts_offset,
  366. };
  367. void dp_soc_mlo_fill_params(struct dp_soc *soc,
  368. struct cdp_soc_attach_params *params)
  369. {
  370. struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(soc);
  371. if (!params->mlo_enabled) {
  372. dp_warn("MLO not enabled on SOC");
  373. return;
  374. }
  375. be_soc->mlo_chip_id = params->mlo_chip_id;
  376. be_soc->ml_ctxt = cdp_mlo_ctx_to_dp(params->ml_context);
  377. be_soc->mlo_enabled = 1;
  378. soc->cdp_soc.ops->mlo_ops = &dp_mlo_ops;
  379. }
  380. void dp_mlo_update_link_to_pdev_map(struct dp_soc *soc, struct dp_pdev *pdev)
  381. {
  382. struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(soc);
  383. struct dp_pdev_be *be_pdev = dp_get_be_pdev_from_dp_pdev(pdev);
  384. struct dp_mlo_ctxt *ml_ctxt = be_soc->ml_ctxt;
  385. uint8_t link_id;
  386. if (!be_soc->mlo_enabled)
  387. return;
  388. if (!ml_ctxt)
  389. return;
  390. link_id = be_pdev->mlo_link_id;
  391. if (link_id < WLAN_MAX_MLO_CHIPS * WLAN_MAX_MLO_LINKS_PER_SOC) {
  392. if (!ml_ctxt->link_to_pdev_map[link_id])
  393. ml_ctxt->link_to_pdev_map[link_id] = be_pdev;
  394. else
  395. dp_alert("Attempt to update existing map for link %u",
  396. link_id);
  397. }
  398. }
  399. void dp_mlo_update_link_to_pdev_unmap(struct dp_soc *soc, struct dp_pdev *pdev)
  400. {
  401. struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(soc);
  402. struct dp_pdev_be *be_pdev = dp_get_be_pdev_from_dp_pdev(pdev);
  403. struct dp_mlo_ctxt *ml_ctxt = be_soc->ml_ctxt;
  404. uint8_t link_id;
  405. if (!be_soc->mlo_enabled)
  406. return;
  407. if (!ml_ctxt)
  408. return;
  409. link_id = be_pdev->mlo_link_id;
  410. if (link_id < WLAN_MAX_MLO_CHIPS * WLAN_MAX_MLO_LINKS_PER_SOC)
  411. ml_ctxt->link_to_pdev_map[link_id] = NULL;
  412. }
  413. static struct dp_pdev_be *
  414. dp_mlo_get_be_pdev_from_link_id(struct dp_mlo_ctxt *ml_ctxt, uint8_t link_id)
  415. {
  416. if (link_id < WLAN_MAX_MLO_CHIPS * WLAN_MAX_MLO_LINKS_PER_SOC)
  417. return ml_ctxt->link_to_pdev_map[link_id];
  418. return NULL;
  419. }
  420. void dp_pdev_mlo_fill_params(struct dp_pdev *pdev,
  421. struct cdp_pdev_attach_params *params)
  422. {
  423. struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(pdev->soc);
  424. struct dp_pdev_be *be_pdev = dp_get_be_pdev_from_dp_pdev(pdev);
  425. if (!be_soc->mlo_enabled) {
  426. dp_info("MLO not enabled on SOC");
  427. return;
  428. }
  429. be_pdev->mlo_link_id = params->mlo_link_id;
  430. }
  431. void dp_mlo_partner_chips_map(struct dp_soc *soc,
  432. struct dp_peer *peer,
  433. uint16_t peer_id)
  434. {
  435. struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(soc);
  436. struct dp_mlo_ctxt *mlo_ctxt = NULL;
  437. bool is_ml_peer_id =
  438. HTT_RX_PEER_META_DATA_V1_ML_PEER_VALID_GET(peer_id);
  439. uint8_t chip_id;
  440. struct dp_soc *temp_soc;
  441. /* for non ML peer dont map on partner chips*/
  442. if (!is_ml_peer_id)
  443. return;
  444. mlo_ctxt = be_soc->ml_ctxt;
  445. if (!mlo_ctxt)
  446. return;
  447. qdf_spin_lock_bh(&mlo_ctxt->ml_soc_list_lock);
  448. for (chip_id = 0; chip_id < DP_MAX_MLO_CHIPS; chip_id++) {
  449. temp_soc = mlo_ctxt->ml_soc_list[chip_id];
  450. if (!temp_soc)
  451. continue;
  452. /* skip if this is current soc */
  453. if (temp_soc == soc)
  454. continue;
  455. dp_peer_find_id_to_obj_add(temp_soc, peer, peer_id);
  456. }
  457. qdf_spin_unlock_bh(&mlo_ctxt->ml_soc_list_lock);
  458. }
  459. qdf_export_symbol(dp_mlo_partner_chips_map);
  460. void dp_mlo_partner_chips_unmap(struct dp_soc *soc,
  461. uint16_t peer_id)
  462. {
  463. struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(soc);
  464. struct dp_mlo_ctxt *mlo_ctxt = be_soc->ml_ctxt;
  465. bool is_ml_peer_id =
  466. HTT_RX_PEER_META_DATA_V1_ML_PEER_VALID_GET(peer_id);
  467. uint8_t chip_id;
  468. struct dp_soc *temp_soc;
  469. if (!is_ml_peer_id)
  470. return;
  471. if (!mlo_ctxt)
  472. return;
  473. qdf_spin_lock_bh(&mlo_ctxt->ml_soc_list_lock);
  474. for (chip_id = 0; chip_id < DP_MAX_MLO_CHIPS; chip_id++) {
  475. temp_soc = mlo_ctxt->ml_soc_list[chip_id];
  476. if (!temp_soc)
  477. continue;
  478. /* skip if this is current soc */
  479. if (temp_soc == soc)
  480. continue;
  481. dp_peer_find_id_to_obj_remove(temp_soc, peer_id);
  482. }
  483. qdf_spin_unlock_bh(&mlo_ctxt->ml_soc_list_lock);
  484. }
  485. qdf_export_symbol(dp_mlo_partner_chips_unmap);
  486. uint8_t dp_mlo_get_chip_id(struct dp_soc *soc)
  487. {
  488. struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(soc);
  489. return be_soc->mlo_chip_id;
  490. }
  491. qdf_export_symbol(dp_mlo_get_chip_id);
  492. struct dp_peer *
  493. dp_link_peer_hash_find_by_chip_id(struct dp_soc *soc,
  494. uint8_t *peer_mac_addr,
  495. int mac_addr_is_aligned,
  496. uint8_t vdev_id,
  497. uint8_t chip_id,
  498. enum dp_mod_id mod_id)
  499. {
  500. struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(soc);
  501. struct dp_mlo_ctxt *mlo_ctxt = be_soc->ml_ctxt;
  502. struct dp_soc *link_peer_soc = NULL;
  503. struct dp_peer *peer = NULL;
  504. if (!mlo_ctxt)
  505. return NULL;
  506. link_peer_soc = dp_mlo_get_soc_ref_by_chip_id(mlo_ctxt, chip_id);
  507. if (!link_peer_soc)
  508. return NULL;
  509. peer = dp_peer_find_hash_find(link_peer_soc, peer_mac_addr,
  510. mac_addr_is_aligned, vdev_id,
  511. mod_id);
  512. qdf_atomic_dec(&link_peer_soc->ref_count);
  513. return peer;
  514. }
  515. qdf_export_symbol(dp_link_peer_hash_find_by_chip_id);
  516. void dp_mlo_get_rx_hash_key(struct dp_soc *soc,
  517. struct cdp_lro_hash_config *lro_hash)
  518. {
  519. struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(soc);
  520. struct dp_mlo_ctxt *ml_ctxt = be_soc->ml_ctxt;
  521. if (!be_soc->mlo_enabled || !ml_ctxt)
  522. return dp_get_rx_hash_key_bytes(lro_hash);
  523. qdf_mem_copy(lro_hash->toeplitz_hash_ipv4, ml_ctxt->toeplitz_hash_ipv4,
  524. (sizeof(lro_hash->toeplitz_hash_ipv4[0]) *
  525. LRO_IPV4_SEED_ARR_SZ));
  526. qdf_mem_copy(lro_hash->toeplitz_hash_ipv6, ml_ctxt->toeplitz_hash_ipv6,
  527. (sizeof(lro_hash->toeplitz_hash_ipv6[0]) *
  528. LRO_IPV6_SEED_ARR_SZ));
  529. }
  530. struct dp_soc *
  531. dp_rx_replensih_soc_get(struct dp_soc *soc, uint8_t chip_id)
  532. {
  533. struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(soc);
  534. struct dp_mlo_ctxt *mlo_ctxt = be_soc->ml_ctxt;
  535. struct dp_soc *replenish_soc;
  536. if (!be_soc->mlo_enabled || !mlo_ctxt)
  537. return soc;
  538. replenish_soc = dp_mlo_get_soc_ref_by_chip_id(mlo_ctxt, chip_id);
  539. if (qdf_unlikely(!replenish_soc)) {
  540. dp_alert("replenish SOC is NULL");
  541. qdf_assert_always(0);
  542. }
  543. return replenish_soc;
  544. }
  545. #ifdef WLAN_MCAST_MLO
  546. void dp_mcast_mlo_iter_ptnr_soc(struct dp_soc_be *be_soc,
  547. dp_ptnr_soc_iter_func func,
  548. void *arg)
  549. {
  550. int i = 0;
  551. struct dp_mlo_ctxt *dp_mlo = be_soc->ml_ctxt;
  552. for (i = 0; i < WLAN_MAX_MLO_CHIPS ; i++) {
  553. struct dp_soc *ptnr_soc =
  554. dp_mlo_get_soc_ref_by_chip_id(dp_mlo, i);
  555. if (!ptnr_soc)
  556. continue;
  557. (*func)(ptnr_soc, arg);
  558. }
  559. }
  560. qdf_export_symbol(dp_mcast_mlo_iter_ptnr_soc);
  561. void dp_mcast_mlo_iter_ptnr_vdev(struct dp_soc_be *be_soc,
  562. struct dp_vdev_be *be_vdev,
  563. dp_ptnr_vdev_iter_func func,
  564. void *arg,
  565. enum dp_mod_id mod_id)
  566. {
  567. int i = 0;
  568. int j = 0;
  569. struct dp_mlo_ctxt *dp_mlo = be_soc->ml_ctxt;
  570. for (i = 0; i < WLAN_MAX_MLO_CHIPS ; i++) {
  571. struct dp_soc *ptnr_soc =
  572. dp_mlo_get_soc_ref_by_chip_id(dp_mlo, i);
  573. if (!ptnr_soc)
  574. continue;
  575. for (j = 0 ; j < WLAN_MAX_MLO_LINKS_PER_SOC ; j++) {
  576. struct dp_vdev *ptnr_vdev;
  577. ptnr_vdev = dp_vdev_get_ref_by_id(
  578. ptnr_soc,
  579. be_vdev->partner_vdev_list[i][j],
  580. mod_id);
  581. if (!ptnr_vdev)
  582. continue;
  583. (*func)(be_vdev, ptnr_vdev, arg);
  584. dp_vdev_unref_delete(ptnr_vdev->pdev->soc,
  585. ptnr_vdev,
  586. mod_id);
  587. }
  588. }
  589. }
  590. qdf_export_symbol(dp_mcast_mlo_iter_ptnr_vdev);
  591. struct dp_vdev *dp_mlo_get_mcast_primary_vdev(struct dp_soc_be *be_soc,
  592. struct dp_vdev_be *be_vdev,
  593. enum dp_mod_id mod_id)
  594. {
  595. int i = 0;
  596. int j = 0;
  597. struct dp_mlo_ctxt *dp_mlo = be_soc->ml_ctxt;
  598. for (i = 0; i < WLAN_MAX_MLO_CHIPS ; i++) {
  599. struct dp_soc *ptnr_soc =
  600. dp_mlo_get_soc_ref_by_chip_id(dp_mlo, i);
  601. if (!ptnr_soc)
  602. continue;
  603. for (j = 0 ; j < WLAN_MAX_MLO_LINKS_PER_SOC ; j++) {
  604. struct dp_vdev *ptnr_vdev = NULL;
  605. struct dp_vdev_be *be_ptnr_vdev = NULL;
  606. ptnr_vdev = dp_vdev_get_ref_by_id(
  607. ptnr_soc,
  608. be_vdev->partner_vdev_list[i][j],
  609. mod_id);
  610. if (!ptnr_vdev)
  611. continue;
  612. be_ptnr_vdev = dp_get_be_vdev_from_dp_vdev(ptnr_vdev);
  613. if (be_ptnr_vdev->mcast_primary)
  614. return ptnr_vdev;
  615. dp_vdev_unref_delete(be_ptnr_vdev->vdev.pdev->soc,
  616. &be_ptnr_vdev->vdev,
  617. mod_id);
  618. }
  619. }
  620. return NULL;
  621. }
  622. qdf_export_symbol(dp_mlo_get_mcast_primary_vdev);
  623. #endif
  624. static inline uint64_t dp_mlo_get_mlo_ts_offset(struct dp_pdev_be *be_pdev)
  625. {
  626. struct dp_soc *soc;
  627. struct dp_pdev *pdev;
  628. struct dp_soc_be *be_soc;
  629. uint32_t mlo_offset;
  630. pdev = &be_pdev->pdev;
  631. soc = pdev->soc;
  632. be_soc = dp_get_be_soc_from_dp_soc(soc);
  633. mlo_offset = be_soc->mlo_tstamp_offset;
  634. return mlo_offset;
  635. }
  636. int32_t dp_mlo_get_delta_tsf2_wrt_mlo_offset(struct dp_soc *soc,
  637. uint8_t hw_link_id)
  638. {
  639. struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(soc);
  640. struct dp_mlo_ctxt *ml_ctxt = be_soc->ml_ctxt;
  641. struct dp_pdev_be *be_pdev;
  642. int32_t delta_tsf2_mlo_offset;
  643. int32_t mlo_offset, delta_tsf2;
  644. if (!ml_ctxt)
  645. return 0;
  646. be_pdev = dp_mlo_get_be_pdev_from_link_id(ml_ctxt, hw_link_id);
  647. if (!be_pdev)
  648. return 0;
  649. mlo_offset = dp_mlo_get_mlo_ts_offset(be_pdev);
  650. delta_tsf2 = be_pdev->delta_tsf2;
  651. delta_tsf2_mlo_offset = mlo_offset - delta_tsf2;
  652. return delta_tsf2_mlo_offset;
  653. }
  654. int32_t dp_mlo_get_delta_tqm_wrt_mlo_offset(struct dp_soc *soc)
  655. {
  656. struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(soc);
  657. int32_t delta_tqm_mlo_offset;
  658. int32_t mlo_offset, delta_tqm;
  659. mlo_offset = be_soc->mlo_tstamp_offset;
  660. delta_tqm = be_soc->delta_tqm;
  661. delta_tqm_mlo_offset = mlo_offset - delta_tqm;
  662. return delta_tqm_mlo_offset;
  663. }