Browse Source

qcacld-3.0: On CSA complete, check if all peer need to be disconnected

CSA on DFS channels requires CAC period after RESTART response, peers
can leave during CAC period due to HB failure. But peers remain
connected in SAP and are not deleted.
Now if vdev down is called during CAC wait period, the peer delete
all is not called, and vdev delete is sent without sending peer
delete to firmare leading to assert.

This change adds the logic to internally disconnect all peers before
channel switch if CAC is required on new channel, i.e new channel is
DFS and pre-CAC is not done and ignore cac is not set.

Change-Id: I923fd11d1b9d4a2c606b19ff94baaf44397d3e20
CRs-Fixed: 2449104
Abhishek Singh 6 years ago
parent
commit
f3d79aeeac

+ 2 - 0
mlme/core/inc/wlan_mlme_main.h

@@ -72,6 +72,7 @@ enum vdev_assoc_type {
  *                                   in progress
  * @vdev_start_failed: flag to indicate that vdev start failed.
  * @connection_fail: flag to indicate connection failed
+ * @cac_required_for_new_channel: if CAC is required for new channel
  * @assoc_type: vdev associate/reassociate type
  * @dynamic_cfg: current configuration of nss, chains for vdev.
  * @ini_cfg: Max configuration of nss, chains supported for vdev.
@@ -82,6 +83,7 @@ struct mlme_legacy_priv {
 	bool hidden_ssid_restart_in_progress;
 	bool vdev_start_failed;
 	bool connection_fail;
+	bool cac_required_for_new_channel;
 	enum vdev_assoc_type assoc_type;
 	struct wlan_mlme_nss_chains dynamic_cfg;
 	struct wlan_mlme_nss_chains ini_cfg;

+ 18 - 0
mlme/core/inc/wlan_mlme_vdev_mgr_interface.h

@@ -129,6 +129,24 @@ mlme_set_connection_fail(struct wlan_objmgr_vdev *vdev, bool val);
  */
 bool mlme_get_vdev_start_failed(struct wlan_objmgr_vdev *vdev);
 
+/**
+ * mlme_get_cac_required() - get if cac is required for new channel
+ * @vdev: vdev pointer
+ *
+ * Return: if cac is required
+ */
+bool mlme_get_cac_required(struct wlan_objmgr_vdev *vdev);
+
+/**
+ * mlme_set_cac_required() - set if cac is required for new channel
+ * @vdev: vdev pointer
+ * @val: value to be set
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS
+mlme_set_cac_required(struct wlan_objmgr_vdev *vdev, bool val);
+
 /**
  * mlme_is_vdev_in_beaconning_mode() - check if vdev is beaconing mode
  * @vdev_opmode: vdev opmode

+ 63 - 0
mlme/core/src/wlan_mlme_vdev_mgr_interface.c

@@ -424,6 +424,33 @@ static QDF_STATUS ap_mlme_vdev_stop_send(struct vdev_mlme_obj *vdev_mlme,
 	return lim_ap_mlme_vdev_stop_send(vdev_mlme, data_len, data);
 }
 
+/**
+ * ap_mlme_vdev_is_newchan_no_cac - VDEV SM CSA complete notification
+ * @vdev_mlme:  VDEV MLME comp object
+ *
+ * On CSA complete, checks whether Channel does not needs CAC period, if
+ * it doesn't need cac return SUCCESS else FAILURE
+ *
+ * Return: SUCCESS if new channel doesn't need cac
+ *         else FAILURE
+ */
+static QDF_STATUS
+ap_mlme_vdev_is_newchan_no_cac(struct vdev_mlme_obj *vdev_mlme)
+{
+	bool cac_required;
+
+	cac_required = mlme_get_cac_required(vdev_mlme->vdev);
+	mlme_legacy_debug("vdev id = %d cac_required %d",
+			  vdev_mlme->vdev->vdev_objmgr.vdev_id, cac_required);
+
+	if (!cac_required)
+		return QDF_STATUS_SUCCESS;
+
+	mlme_set_cac_required(vdev_mlme->vdev, false);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
 /**
  * ap_mlme_vdev_down_send() - callback to send vdev down req
  * @vdev_mlme: vdev mlme object
@@ -691,6 +718,39 @@ bool mlme_get_vdev_start_failed(struct wlan_objmgr_vdev *vdev)
 	return mlme_priv->vdev_start_failed;
 }
 
+QDF_STATUS mlme_set_cac_required(struct wlan_objmgr_vdev *vdev, bool val)
+{
+	struct vdev_mlme_obj *vdev_mlme;
+	struct mlme_legacy_priv *mlme_priv;
+
+	vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev);
+	if (!vdev_mlme) {
+		mlme_legacy_err("vdev component object is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	mlme_priv = (struct mlme_legacy_priv *)vdev_mlme->ext_vdev_ptr;
+
+	mlme_priv->cac_required_for_new_channel = val;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+bool mlme_get_cac_required(struct wlan_objmgr_vdev *vdev)
+{
+	struct vdev_mlme_obj *vdev_mlme;
+	struct mlme_legacy_priv *mlme_priv;
+
+	vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev);
+	if (!vdev_mlme) {
+		mlme_legacy_err("vdev component object is NULL");
+		return false;
+	}
+
+	mlme_priv = (struct mlme_legacy_priv *)vdev_mlme->ext_vdev_ptr;
+
+	return mlme_priv->cac_required_for_new_channel;
+}
 
 /**
  * vdevmgr_mlme_ext_hdl_create () - Create mlme legacy priv object
@@ -818,6 +878,8 @@ static struct vdev_mlme_ops sta_mlme_ops = {
  *                                      MLME down operation
  * @mlme_vdev_notify_down_complete:     callback to notify VDEV MLME on moving
  *                                      to INIT state
+ * @mlme_vdev_is_newchan_no_cac:        callback to check if new channel is DFS
+ *                                      and cac is not required
  */
 static struct vdev_mlme_ops ap_mlme_ops = {
 	.mlme_vdev_start_send = ap_mlme_vdev_start_send,
@@ -834,6 +896,7 @@ static struct vdev_mlme_ops ap_mlme_ops = {
 	.mlme_vdev_stop_continue = vdevmgr_mlme_stop_continue,
 	.mlme_vdev_down_send = vdevmgr_mlme_vdev_down_send,
 	.mlme_vdev_notify_down_complete = vdevmgr_notify_down_complete,
+	.mlme_vdev_is_newchan_no_cac = ap_mlme_vdev_is_newchan_no_cac,
 };
 
 /**