123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383 |
- /*
- * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved.
- *
- * Permission to use, copy, modify, and/or distribute this software for
- * any purpose with or without fee is hereby granted, provided that the
- * above copyright notice and this permission notice appear in all
- * copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
- * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
- * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
- * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
- * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
- /**
- * DOC: wlan_tdls_tgt_api.c
- *
- * TDLS south bound interface definitions
- */
- #include "qdf_status.h"
- #include <wlan_tdls_tgt_api.h>
- #include "../../core/src/wlan_tdls_main.h"
- #include "../../core/src/wlan_tdls_cmds_process.h"
- #include "../../core/src/wlan_tdls_mgmt.h"
- static inline struct wlan_lmac_if_tdls_tx_ops *
- wlan_psoc_get_tdls_txops(struct wlan_objmgr_psoc *psoc)
- {
- return &psoc->soc_cb.tx_ops.tdls_tx_ops;
- }
- static inline struct wlan_lmac_if_tdls_rx_ops *
- wlan_psoc_get_tdls_rxops(struct wlan_objmgr_psoc *psoc)
- {
- return &psoc->soc_cb.rx_ops.tdls_rx_ops;
- }
- QDF_STATUS tgt_tdls_set_fw_state(struct wlan_objmgr_psoc *psoc,
- struct tdls_info *tdls_param)
- {
- struct wlan_lmac_if_tdls_tx_ops *tdls_ops = NULL;
- tdls_ops = wlan_psoc_get_tdls_txops(psoc);
- if (tdls_ops && tdls_ops->update_fw_state)
- return tdls_ops->update_fw_state(psoc, tdls_param);
- else
- return QDF_STATUS_SUCCESS;
- }
- QDF_STATUS tgt_tdls_set_peer_state(struct wlan_objmgr_psoc *psoc,
- struct tdls_peer_update_state *peer_param)
- {
- struct wlan_lmac_if_tdls_tx_ops *tdls_ops = NULL;
- tdls_ops = wlan_psoc_get_tdls_txops(psoc);
- if (tdls_ops && tdls_ops->update_peer_state)
- return tdls_ops->update_peer_state(psoc, peer_param);
- else
- return QDF_STATUS_SUCCESS;
- }
- QDF_STATUS tgt_tdls_set_offchan_mode(struct wlan_objmgr_psoc *psoc,
- struct tdls_channel_switch_params *param)
- {
- struct wlan_lmac_if_tdls_tx_ops *tdls_ops = NULL;
- tdls_ops = wlan_psoc_get_tdls_txops(psoc);
- if (tdls_ops && tdls_ops->set_offchan_mode)
- return tdls_ops->set_offchan_mode(psoc, param);
- else
- return QDF_STATUS_SUCCESS;
- }
- QDF_STATUS tgt_tdls_set_uapsd(struct wlan_objmgr_psoc *psoc,
- struct sta_uapsd_trig_params *params)
- {
- struct wlan_lmac_if_tdls_tx_ops *tdls_ops = NULL;
- tdls_ops = wlan_psoc_get_tdls_txops(psoc);
- if (tdls_ops && tdls_ops->tdls_set_uapsd)
- return tdls_ops->tdls_set_uapsd(psoc, params);
- else
- return QDF_STATUS_SUCCESS;
- }
- QDF_STATUS tgt_tdls_send_mgmt_tx_completion(struct scheduler_msg *pmsg)
- {
- QDF_STATUS status = QDF_STATUS_SUCCESS;
- if (!pmsg || !pmsg->bodyptr) {
- tdls_err("msg: 0x%pK", pmsg);
- QDF_ASSERT(0);
- return QDF_STATUS_E_NULL_VALUE;
- }
- status = tdls_send_mgmt_tx_completion(pmsg->bodyptr);
- return status;
- }
- QDF_STATUS tgt_tdls_send_mgmt_rsp(struct scheduler_msg *pmsg)
- {
- QDF_STATUS status = QDF_STATUS_SUCCESS;
- if (!pmsg || !pmsg->bodyptr) {
- tdls_err("msg: 0x%pK", pmsg);
- QDF_ASSERT(0);
- return QDF_STATUS_E_NULL_VALUE;
- }
- status = tdls_process_send_mgmt_rsp(pmsg->bodyptr);
- return status;
- }
- QDF_STATUS tgt_tdls_add_peer_rsp(struct scheduler_msg *pmsg)
- {
- QDF_STATUS status = QDF_STATUS_SUCCESS;
- if (!pmsg || !pmsg->bodyptr) {
- tdls_err("msg: 0x%pK", pmsg);
- QDF_ASSERT(0);
- return QDF_STATUS_E_NULL_VALUE;
- }
- status = tdls_process_add_peer_rsp(pmsg->bodyptr);
- return status;
- }
- QDF_STATUS tgt_tdls_del_peer_rsp(struct scheduler_msg *pmsg)
- {
- QDF_STATUS status = QDF_STATUS_SUCCESS;
- if (!pmsg || !pmsg->bodyptr) {
- tdls_err("msg: 0x%pK", pmsg);
- QDF_ASSERT(0);
- return QDF_STATUS_E_NULL_VALUE;
- }
- status = tdls_process_del_peer_rsp(pmsg->bodyptr);
- return status;
- }
- QDF_STATUS tgt_tdls_register_ev_handler(struct wlan_objmgr_psoc *psoc)
- {
- struct wlan_lmac_if_tdls_tx_ops *tdls_ops = NULL;
- tdls_ops = wlan_psoc_get_tdls_txops(psoc);
- if (tdls_ops && tdls_ops->tdls_reg_ev_handler)
- return tdls_ops->tdls_reg_ev_handler(psoc, NULL);
- else
- return QDF_STATUS_SUCCESS;
- }
- QDF_STATUS tgt_tdls_unregister_ev_handler(struct wlan_objmgr_psoc *psoc)
- {
- struct wlan_lmac_if_tdls_tx_ops *tdls_ops = NULL;
- tdls_ops = wlan_psoc_get_tdls_txops(psoc);
- if (tdls_ops->tdls_unreg_ev_handler)
- return tdls_ops->tdls_unreg_ev_handler(psoc, NULL);
- else
- return QDF_STATUS_SUCCESS;
- }
- static QDF_STATUS tgt_tdls_event_flush_cb(struct scheduler_msg *msg)
- {
- struct tdls_event_notify *notify;
- notify = msg->bodyptr;
- if (notify && notify->vdev) {
- wlan_objmgr_vdev_release_ref(notify->vdev, WLAN_TDLS_SB_ID);
- qdf_mem_free(notify);
- }
- return QDF_STATUS_SUCCESS;
- }
- QDF_STATUS
- tgt_tdls_event_handler(struct wlan_objmgr_psoc *psoc,
- struct tdls_event_info *info)
- {
- struct scheduler_msg msg = {0,};
- struct tdls_event_notify *notify;
- uint8_t vdev_id;
- QDF_STATUS status;
- if (!psoc || !info) {
- tdls_err("psoc: 0x%pK, info: 0x%pK", psoc, info);
- return QDF_STATUS_E_NULL_VALUE;
- }
- tdls_debug("vdev: %d, type: %d, reason: %d" QDF_MAC_ADDR_STR,
- info->vdev_id, info->message_type, info->peer_reason,
- QDF_MAC_ADDR_ARRAY(info->peermac.bytes));
- notify = qdf_mem_malloc(sizeof(*notify));
- if (!notify) {
- tdls_err("mem allocate fail");
- return QDF_STATUS_E_NOMEM;
- }
- vdev_id = info->vdev_id;
- notify->vdev =
- wlan_objmgr_get_vdev_by_id_from_psoc(psoc,
- vdev_id, WLAN_TDLS_SB_ID);
- if (!notify->vdev) {
- tdls_err("null vdev, vdev_id: %d, psoc: 0x%pK", vdev_id, psoc);
- return QDF_STATUS_E_INVAL;
- }
- qdf_mem_copy(¬ify->event, info, sizeof(*info));
- msg.bodyptr = notify;
- msg.callback = tdls_process_evt;
- msg.flush_callback = tgt_tdls_event_flush_cb;
- status = scheduler_post_message(QDF_MODULE_ID_TDLS,
- QDF_MODULE_ID_TDLS,
- QDF_MODULE_ID_TARGET_IF, &msg);
- if (QDF_IS_STATUS_ERROR(status)) {
- tdls_err("can't post msg to handle tdls event");
- wlan_objmgr_vdev_release_ref(notify->vdev, WLAN_TDLS_SB_ID);
- qdf_mem_free(notify);
- }
- return status;
- }
- static QDF_STATUS tgt_tdls_mgmt_frame_rx_flush_cb(struct scheduler_msg *msg)
- {
- struct tdls_rx_mgmt_event *rx_mgmt_event;
- rx_mgmt_event = msg->bodyptr;
- if (rx_mgmt_event) {
- if (rx_mgmt_event->rx_mgmt)
- qdf_mem_free(rx_mgmt_event->rx_mgmt);
- qdf_mem_free(rx_mgmt_event);
- }
- msg->bodyptr = NULL;
- return QDF_STATUS_SUCCESS;
- }
- static
- QDF_STATUS tgt_tdls_mgmt_frame_process_rx_cb(
- struct wlan_objmgr_psoc *psoc,
- struct wlan_objmgr_peer *peer,
- qdf_nbuf_t buf,
- struct mgmt_rx_event_params *mgmt_rx_params,
- enum mgmt_frame_type frm_type)
- {
- struct tdls_rx_mgmt_frame *rx_mgmt;
- struct tdls_rx_mgmt_event *rx_mgmt_event;
- struct tdls_soc_priv_obj *tdls_soc_obj;
- struct scheduler_msg msg = {0};
- struct wlan_objmgr_vdev *vdev;
- uint32_t vdev_id;
- uint8_t *pdata;
- QDF_STATUS status;
- tdls_soc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc,
- WLAN_UMAC_COMP_TDLS);
- if (!tdls_soc_obj) {
- tdls_err("tdls ctx is NULL, drop this frame");
- return QDF_STATUS_E_FAILURE;
- }
- if (!peer) {
- vdev = tdls_get_vdev(psoc, WLAN_TDLS_SB_ID);
- if (!vdev) {
- tdls_err("current tdls vdev is null, can't get vdev id");
- return QDF_STATUS_E_FAILURE;
- }
- vdev_id = wlan_vdev_get_id(vdev);
- wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_SB_ID);
- } else {
- vdev = wlan_peer_get_vdev(peer);
- if (!vdev) {
- tdls_err("vdev is NULL in peer, drop this frame");
- return QDF_STATUS_E_FAILURE;
- }
- vdev_id = wlan_vdev_get_id(vdev);
- }
- rx_mgmt_event = qdf_mem_malloc(sizeof(*rx_mgmt_event));
- if (!rx_mgmt_event) {
- tdls_err("Failed to allocate rx mgmt event");
- return QDF_STATUS_E_NOMEM;
- }
- rx_mgmt = qdf_mem_malloc(sizeof(*rx_mgmt) +
- mgmt_rx_params->buf_len);
- if (!rx_mgmt) {
- tdls_err("Failed to allocate rx mgmt frame");
- qdf_mem_free(rx_mgmt_event);
- return QDF_STATUS_E_NOMEM;
- }
- pdata = (uint8_t *)qdf_nbuf_data(buf);
- rx_mgmt->frame_len = mgmt_rx_params->buf_len;
- rx_mgmt->rx_chan = mgmt_rx_params->channel;
- rx_mgmt->vdev_id = vdev_id;
- rx_mgmt->frm_type = frm_type;
- rx_mgmt->rx_rssi = mgmt_rx_params->rssi;
- rx_mgmt_event->rx_mgmt = rx_mgmt;
- rx_mgmt_event->tdls_soc_obj = tdls_soc_obj;
- qdf_mem_copy(rx_mgmt->buf, pdata, mgmt_rx_params->buf_len);
- msg.type = TDLS_EVENT_RX_MGMT;
- msg.bodyptr = rx_mgmt_event;
- msg.callback = tdls_process_rx_frame;
- msg.flush_callback = tgt_tdls_mgmt_frame_rx_flush_cb;
- status = scheduler_post_message(QDF_MODULE_ID_TDLS,
- QDF_MODULE_ID_TDLS,
- QDF_MODULE_ID_TARGET_IF, &msg);
- if (QDF_IS_STATUS_ERROR(status)) {
- qdf_mem_free(rx_mgmt);
- qdf_mem_free(rx_mgmt_event);
- }
- qdf_nbuf_free(buf);
- return status;
- }
- QDF_STATUS tgt_tdls_mgmt_frame_rx_cb(
- struct wlan_objmgr_psoc *psoc,
- struct wlan_objmgr_peer *peer,
- qdf_nbuf_t buf,
- struct mgmt_rx_event_params *mgmt_rx_params,
- enum mgmt_frame_type frm_type)
- {
- QDF_STATUS status;
- tdls_debug("psoc:%pK, peer:%pK, type:%d", psoc, peer, frm_type);
- if (!buf) {
- tdls_err("rx frame buff is null buf:%pK", buf);
- return QDF_STATUS_E_INVAL;
- }
- if (!mgmt_rx_params || !psoc) {
- tdls_err("input is NULL mgmt_rx_params:%pK psoc:%pK, peer:%pK",
- mgmt_rx_params, psoc, peer);
- status = QDF_STATUS_E_INVAL;
- goto release_nbuf;
- }
- status = wlan_objmgr_peer_try_get_ref(peer, WLAN_TDLS_SB_ID);
- if (QDF_STATUS_SUCCESS != status)
- goto release_nbuf;
- status = tgt_tdls_mgmt_frame_process_rx_cb(psoc, peer, buf,
- mgmt_rx_params, frm_type);
- wlan_objmgr_peer_release_ref(peer, WLAN_TDLS_SB_ID);
- if (QDF_STATUS_SUCCESS != status)
- release_nbuf:
- qdf_nbuf_free(buf);
- return status;
- }
- void tgt_tdls_peers_deleted_notification(struct wlan_objmgr_psoc *psoc,
- uint32_t session_id)
- {
- tdls_peers_deleted_notification(psoc, session_id);
- }
- void tgt_tdls_delete_all_peers_indication(struct wlan_objmgr_psoc *psoc,
- uint32_t session_id)
- {
- tdls_delete_all_peers_indication(psoc, session_id);
- }
|