Sfoglia il codice sorgente

qcacmn: Add TDLS user command getTDLSPeers

Add TDLS user command getTDLSPeers for TDLS functional verification

Change-Id: Ia02461a364ca604672d728f7dad7c3537e78f067
CRs-Fixed: 2146626
Kabilan Kannan 7 anni fa
parent
commit
70113f22aa

+ 16 - 0
os_if/linux/tdls/inc/wlan_cfg80211_tdls.h

@@ -44,8 +44,11 @@
  * @tdls_mgmt_comp: Completion to send tdls mgmt packets
  * @tdls_link_establish_req_comp: Completion to establish link, sync to
  * send establish params to firmware, not used today.
+ * @tdls_teardown_comp: tdls teardown completion event
+ * @tdls_user_cmd_comp: tdls user command completion event
  * @tdls_add_peer_status: Peer status after add peer
  * @mgmt_tx_completion_status: Tdls mgmt frames TX completion status code
+ * @tdls_user_cmd_len: tdls user command written buffer length
  */
 struct osif_tdls_vdev {
 	struct completion tdls_add_peer_comp;
@@ -53,8 +56,10 @@ struct osif_tdls_vdev {
 	struct completion tdls_mgmt_comp;
 	struct completion tdls_link_establish_req_comp;
 	struct completion tdls_teardown_comp;
+	struct completion tdls_user_cmd_comp;
 	QDF_STATUS tdls_add_peer_status;
 	uint32_t mgmt_tx_completion_status;
+	uint32_t tdls_user_cmd_len;
 };
 
 /**
@@ -146,6 +151,17 @@ int wlan_cfg80211_tdls_oper(struct wlan_objmgr_pdev *pdev,
 			    const uint8_t *peer,
 			    enum nl80211_tdls_operation oper);
 
+/**
+ * wlan_cfg80211_tdls_get_all_peers() - get all the TDLS peers from the list
+ * @vdev: vdev object
+ * @buf: output buffer
+ * @buflen: valid length of the output error
+ *
+ * Return: length of the output buffer
+ */
+int wlan_cfg80211_tdls_get_all_peers(struct wlan_objmgr_vdev *vdev,
+				char *buf, int buflen);
+
 /**
  * wlan_cfg80211_tdls_mgmt() - process tdls management frames from the supplicant
  * @pdev: pdev object

+ 56 - 0
os_if/linux/tdls/src/wlan_cfg80211_tdls.c

@@ -67,6 +67,7 @@ QDF_STATUS wlan_cfg80211_tdls_priv_init(struct vdev_osif_priv *osif_priv)
 	init_completion(&tdls_priv->tdls_mgmt_comp);
 	init_completion(&tdls_priv->tdls_link_establish_req_comp);
 	init_completion(&tdls_priv->tdls_teardown_comp);
+	init_completion(&tdls_priv->tdls_user_cmd_comp);
 
 	osif_priv->osif_tdls = tdls_priv;
 
@@ -636,6 +637,56 @@ fail:
 	wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID);
 }
 
+int wlan_cfg80211_tdls_get_all_peers(struct wlan_objmgr_vdev *vdev,
+				char *buf, int buflen)
+{
+	struct vdev_osif_priv *osif_priv;
+	struct osif_tdls_vdev *tdls_priv;
+	int32_t len;
+	QDF_STATUS status;
+	unsigned long rc;
+
+	if (wlan_objmgr_vdev_try_get_ref(vdev, WLAN_OSIF_ID) !=
+							QDF_STATUS_SUCCESS) {
+		len = scnprintf(buf, buflen,
+				"\nNo TDLS VDEV is null\n");
+		return len;
+	}
+
+	osif_priv = wlan_vdev_get_ospriv(vdev);
+	tdls_priv = osif_priv->osif_tdls;
+
+	reinit_completion(&tdls_priv->tdls_user_cmd_comp);
+	status = ucfg_tdls_get_all_peers(vdev, buf, buflen);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		cfg80211_err("ucfg_tdls_get_all_peers failed err %d", status);
+		len = scnprintf(buf, buflen,
+				"\nucfg_tdls_send_mgmt failed\n");
+		goto error_get_tdls_peers;
+	}
+
+	cfg80211_info("Wait for tdls_user_cmd_comp. Timeout %u ms",
+		WAIT_TIME_FOR_TDLS_USER_CMD);
+
+	rc = wait_for_completion_timeout(
+		&tdls_priv->tdls_user_cmd_comp,
+		msecs_to_jiffies(WAIT_TIME_FOR_TDLS_USER_CMD));
+
+	if (0 == rc) {
+		cfg80211_err("TDLS user cmd get all peers timed out rc %ld",
+			     rc);
+		len = scnprintf(buf, buflen,
+				"\nTDLS user cmd get all peers timed out\n");
+		goto error_get_tdls_peers;
+	}
+
+	len = tdls_priv->tdls_user_cmd_len;
+
+error_get_tdls_peers:
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_OSIF_ID);
+	return len;
+}
+
 int wlan_cfg80211_tdls_mgmt(struct wlan_objmgr_pdev *pdev,
 				struct net_device *dev, const uint8_t *peer_mac,
 				uint8_t action_code, uint8_t dialog_token,
@@ -840,6 +891,11 @@ void wlan_cfg80211_tdls_event_callback(void *user_data,
 	case TDLS_EVENT_TEARDOWN_LINKS_DONE:
 		complete(&tdls_priv->tdls_teardown_comp);
 		break;
+	case TDLS_EVENT_USER_CMD:
+		tdls_priv->tdls_user_cmd_len = ind->status;
+		complete(&tdls_priv->tdls_user_cmd_comp);
+		break;
+
 	default:
 		break;
 	}

+ 94 - 0
umac/tdls/core/src/wlan_tdls_main.c

@@ -293,6 +293,9 @@ QDF_STATUS tdls_process_cmd(struct scheduler_msg *msg)
 	case TDLS_NOTIFY_RESET_ADAPTERS:
 		tdls_notify_reset_adapter(msg->bodyptr);
 		break;
+	case TDLS_CMD_GET_ALL_PEERS:
+		tdls_get_all_peers_from_list(msg->bodyptr);
+		break;
 	default:
 		break;
 	}
@@ -1001,6 +1004,97 @@ static void tdls_process_reset_adapter(struct wlan_objmgr_vdev *vdev)
 	tdls_timers_stop(tdls_vdev);
 }
 
+static int __tdls_get_all_peers_from_list(
+			struct tdls_get_all_peers *get_tdls_peers)
+{
+	int i;
+	int len, init_len;
+	qdf_list_t *head;
+	qdf_list_node_t *p_node;
+	struct tdls_peer *curr_peer;
+	char *buf;
+	int buf_len;
+	struct tdls_vdev_priv_obj *tdls_vdev;
+	QDF_STATUS status;
+
+	tdls_notice("Enter ");
+
+	buf = get_tdls_peers->buf;
+	buf_len = get_tdls_peers->buf_len;
+
+	if (!tdls_is_vdev_connected(get_tdls_peers->vdev)) {
+		len = qdf_scnprintf(buf, buf_len,
+				"\nSTA is not associated\n");
+		return len;
+	}
+
+	tdls_vdev = wlan_vdev_get_tdls_vdev_obj(get_tdls_peers->vdev);
+
+	if (!tdls_vdev) {
+		len = qdf_scnprintf(buf, buf_len, "TDLS not enabled\n");
+		return len;
+	}
+
+	init_len = buf_len;
+	len = qdf_scnprintf(buf, buf_len,
+			"\n%-18s%-3s%-4s%-3s%-5s\n",
+			"MAC", "Id", "cap", "up", "RSSI");
+	buf += len;
+	buf_len -= len;
+	len = qdf_scnprintf(buf, buf_len,
+			    "---------------------------------\n");
+	buf += len;
+	buf_len -= len;
+
+	for (i = 0; i < WLAN_TDLS_PEER_LIST_SIZE; i++) {
+		head = &tdls_vdev->peer_list[i];
+		status = qdf_list_peek_front(head, &p_node);
+		while (QDF_IS_STATUS_SUCCESS(status)) {
+			curr_peer = qdf_container_of(p_node,
+						     struct tdls_peer, node);
+			if (buf_len < 32 + 1)
+				break;
+			len = qdf_scnprintf(buf, buf_len,
+				QDF_MAC_ADDRESS_STR "%3d%4s%3s%5d\n",
+				QDF_MAC_ADDR_ARRAY(curr_peer->peer_mac.bytes),
+				curr_peer->sta_id,
+				(curr_peer->tdls_support ==
+				 TDLS_CAP_SUPPORTED) ? "Y" : "N",
+				TDLS_IS_LINK_CONNECTED(curr_peer) ? "Y" :
+				"N", curr_peer->rssi);
+			buf += len;
+			buf_len -= len;
+			status = qdf_list_peek_next(head, p_node, &p_node);
+		}
+	}
+
+	tdls_notice("Exit ");
+	return init_len - buf_len;
+}
+
+void tdls_get_all_peers_from_list(
+			struct tdls_get_all_peers *get_tdls_peers)
+{
+	int32_t len;
+	struct tdls_soc_priv_obj *tdls_soc_obj;
+	struct tdls_osif_indication indication;
+
+	if (!get_tdls_peers->vdev)
+		qdf_mem_free(get_tdls_peers);
+
+	len = __tdls_get_all_peers_from_list(get_tdls_peers);
+
+	indication.status = len;
+	indication.vdev = get_tdls_peers->vdev;
+
+	tdls_soc_obj = wlan_vdev_get_tdls_soc_obj(get_tdls_peers->vdev);
+	if (tdls_soc_obj && tdls_soc_obj->tdls_event_cb)
+		tdls_soc_obj->tdls_event_cb(tdls_soc_obj->tdls_evt_cb_data,
+			TDLS_EVENT_USER_CMD, &indication);
+
+	qdf_mem_free(get_tdls_peers);
+}
+
 void tdls_notify_reset_adapter(struct wlan_objmgr_vdev *vdev)
 {
 	if (!vdev) {

+ 10 - 0
umac/tdls/core/src/wlan_tdls_main.h

@@ -574,6 +574,16 @@ QDF_STATUS tdls_notify_sta_connect(struct tdls_sta_notify_params *notify);
  */
 QDF_STATUS tdls_notify_sta_disconnect(struct tdls_sta_notify_params *notify);
 
+
+/**
+ * tdls_get_all_peers_from_list() - get all the tdls peers from the list
+ * @get_tdls_peers: get_tdls_peers object
+ *
+ * Return: None
+ */
+void tdls_get_all_peers_from_list(
+		struct tdls_get_all_peers *get_tdls_peers);
+
 /**
  * tdls_notify_reset_adapter() - notify reset adapter
  * @vdev: vdev object manager

+ 20 - 0
umac/tdls/dispatcher/inc/wlan_tdls_public_structs.h

@@ -62,6 +62,9 @@
 /** Maximum time(ms) to wait for tdls mgmt to complete **/
 #define WAIT_TIME_FOR_TDLS_MGMT         11000
 
+/** Maximum time(ms) to wait for tdls mgmt to complete **/
+#define WAIT_TIME_FOR_TDLS_USER_CMD     11000
+
 /** Maximum waittime for TDLS teardown links **/
 #define WAIT_TIME_FOR_TDLS_TEARDOWN_LINKS 10000
 
@@ -181,6 +184,7 @@ enum tdls_feature_mode {
  * @TDLS_CMD_SESSION_DECREMENT: notify session decrement
  * @TDLS_CMD_TEARDOWN_LINKS: notify teardown
  * @TDLS_NOTIFY_RESET_ADAPTERS: notify adapater reset
+ * @TDLS_CMD_GET_ALL_PEERS: get all the tdls peers from the list
  */
 enum tdls_command_type {
 	TDLS_CMD_TX_ACTION = 1,
@@ -201,6 +205,7 @@ enum tdls_command_type {
 	TDLS_CMD_SESSION_DECREMENT,
 	TDLS_CMD_TEARDOWN_LINKS,
 	TDLS_NOTIFY_RESET_ADAPTERS,
+	TDLS_CMD_GET_ALL_PEERS,
 };
 
 /**
@@ -213,6 +218,8 @@ enum tdls_command_type {
  * @TDLS_EVENT_DISCOVERY_REQ: dicovery request
  * @TDLS_EVENT_TEARDOWN_REQ: teardown request
  * @TDLS_EVENT_SETUP_REQ: setup request
+ * @TDLS_EVENT_TEARDOWN_LINKS_DONE: teardown completion event
+ * @TDLS_EVENT_USER_CMD: tdls user command
  */
 enum tdls_event_type {
 	TDLS_EVENT_VDEV_STATE_CHANGE = 0,
@@ -224,6 +231,7 @@ enum tdls_event_type {
 	TDLS_EVENT_TEARDOWN_REQ,
 	TDLS_EVENT_SETUP_REQ,
 	TDLS_EVENT_TEARDOWN_LINKS_DONE,
+	TDLS_EVENT_USER_CMD,
 };
 
 /**
@@ -968,6 +976,18 @@ struct tdls_validate_action_req {
 	int max_sta_failed;
 };
 
+/**
+ * struct tdls_get_all_peers - get all peers from the list
+ * @vdev: vdev object
+ * @buf: output string buffer to hold the peer info
+ * @buf_len: the size of output string buffer
+ */
+struct tdls_get_all_peers {
+	struct wlan_objmgr_vdev *vdev;
+	char *buf;
+	int buf_len;
+};
+
 /**
  * struct tdls_send_action_frame_request - tdls send mgmt request
  * @vdev: vdev object

+ 11 - 0
umac/tdls/dispatcher/inc/wlan_tdls_ucfg_api.h

@@ -119,6 +119,17 @@ QDF_STATUS ucfg_tdls_update_peer(struct wlan_objmgr_vdev *vdev,
 QDF_STATUS ucfg_tdls_oper(struct wlan_objmgr_vdev *vdev,
 			  const uint8_t *macaddr, enum tdls_command_type cmd);
 
+/**
+ * ucfg_tdls_get_all_peers() - get all tdls peers from the list
+ * @vdev: vdev object
+ * @buf: output buffer
+ * @buflen: length of written data
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS ucfg_tdls_get_all_peers(struct wlan_objmgr_vdev *vdev,
+				   char *buf, int buflen);
+
 /**
  * ucfg_tdls_send_mgmt_frame() - send TDLS mgmt frame
  * @mgmt_req: pointer to TDLS action frame request struct

+ 29 - 0
umac/tdls/dispatcher/src/wlan_tdls_ucfg_api.c

@@ -485,6 +485,35 @@ error:
 	return status;
 }
 
+QDF_STATUS ucfg_tdls_get_all_peers(struct wlan_objmgr_vdev *vdev,
+				   char *buf, int buflen)
+{
+	struct scheduler_msg msg = {0, };
+	struct tdls_get_all_peers *tdls_peers;
+	QDF_STATUS status;
+
+	tdls_peers = qdf_mem_malloc(sizeof(*tdls_peers));
+
+	if (!tdls_peers) {
+		tdls_err("mem allocate fail");
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	tdls_peers->vdev = vdev;
+	tdls_peers->buf_len = buflen;
+	tdls_peers->buf = buf;
+
+	msg.bodyptr = tdls_peers;
+	msg.callback = tdls_process_cmd;
+	msg.type = TDLS_CMD_GET_ALL_PEERS;
+	status = scheduler_post_msg(QDF_MODULE_ID_OS_IF, &msg);
+
+	if (status != QDF_STATUS_SUCCESS)
+		qdf_mem_free(tdls_peers);
+
+	return QDF_STATUS_SUCCESS;
+}
+
 QDF_STATUS ucfg_tdls_send_mgmt_frame(
 				struct tdls_action_frame_request *req)
 {