|
@@ -174,6 +174,301 @@ mlme_fill_freq_in_scan_start_request(struct wlan_objmgr_vdev *vdev,
|
|
|
return QDF_STATUS_SUCCESS;
|
|
|
}
|
|
|
|
|
|
+#ifdef WLAN_FEATURE_11BE
|
|
|
+static enum scan_phy_mode mlme_get_scan_phy_mode(void)
|
|
|
+{
|
|
|
+ return SCAN_PHY_MODE_11BE_EHT160;
|
|
|
+}
|
|
|
+
|
|
|
+static enum scan_phy_mode
|
|
|
+wlan_scan_get_11be_scan_phy_mode(enum wlan_phymode ch_phymode)
|
|
|
+{
|
|
|
+ enum scan_phy_mode scan_phymode;
|
|
|
+
|
|
|
+ switch (ch_phymode) {
|
|
|
+ case WLAN_PHYMODE_11BEA_EHT20:
|
|
|
+ scan_phymode = SCAN_PHY_MODE_11BE_EHT20;
|
|
|
+ break;
|
|
|
+ case WLAN_PHYMODE_11BEG_EHT20:
|
|
|
+ scan_phymode = SCAN_PHY_MODE_11BE_EHT20_2G;
|
|
|
+ break;
|
|
|
+ case WLAN_PHYMODE_11BEA_EHT40:
|
|
|
+ scan_phymode = SCAN_PHY_MODE_11BE_EHT40;
|
|
|
+ break;
|
|
|
+ case WLAN_PHYMODE_11BEG_EHT40:
|
|
|
+ scan_phymode = SCAN_PHY_MODE_11BE_EHT40_2G;
|
|
|
+ break;
|
|
|
+ case WLAN_PHYMODE_11BEA_EHT80:
|
|
|
+ scan_phymode = SCAN_PHY_MODE_11BE_EHT80;
|
|
|
+ break;
|
|
|
+ case WLAN_PHYMODE_11BEG_EHT80:
|
|
|
+ scan_phymode = SCAN_PHY_MODE_11BE_EHT80_2G;
|
|
|
+ break;
|
|
|
+ case WLAN_PHYMODE_11BEA_EHT160:
|
|
|
+ scan_phymode = SCAN_PHY_MODE_11BE_EHT160;
|
|
|
+ break;
|
|
|
+ case WLAN_PHYMODE_11BEA_EHT320:
|
|
|
+ scan_phymode = SCAN_PHY_MODE_11BE_EHT320;
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ scan_phymode = SCAN_PHY_MODE_UNKNOWN;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ return scan_phymode;
|
|
|
+}
|
|
|
+#else
|
|
|
+static inline enum scan_phy_mode mlme_get_scan_phy_mode(void)
|
|
|
+{
|
|
|
+ return SCAN_PHY_MODE_UNKNOWN;
|
|
|
+}
|
|
|
+
|
|
|
+static inline enum scan_phy_mode
|
|
|
+wlan_scan_get_11be_scan_phy_mode(enum wlan_phymode ch_phymode)
|
|
|
+{
|
|
|
+ return SCAN_PHY_MODE_UNKNOWN;
|
|
|
+}
|
|
|
+#endif
|
|
|
+
|
|
|
+/**
|
|
|
+ * wlan_scan_get_scan_phy_mode() - get scan phymode from channel phy mode
|
|
|
+ * @vdev: vdev common object
|
|
|
+ * @op_freq: operational frequency
|
|
|
+ * @vdev_id: vdev id
|
|
|
+ *
|
|
|
+ * Return: enum scan_phy_mode
|
|
|
+ */
|
|
|
+static enum scan_phy_mode
|
|
|
+wlan_scan_get_scan_phy_mode(struct wlan_objmgr_vdev *vdev, qdf_freq_t op_freq,
|
|
|
+ uint32_t vdev_id)
|
|
|
+{
|
|
|
+ struct wlan_channel *des_chan;
|
|
|
+ enum scan_phy_mode scan_phymode = SCAN_PHY_MODE_UNKNOWN;
|
|
|
+
|
|
|
+ des_chan = wlan_vdev_mlme_get_des_chan(vdev);
|
|
|
+ if (!des_chan) {
|
|
|
+ mlme_debug("vdev %d : des_chan is null", vdev_id);
|
|
|
+ return scan_phymode;
|
|
|
+ }
|
|
|
+
|
|
|
+ switch (des_chan->ch_phymode) {
|
|
|
+ case WLAN_PHYMODE_11A:
|
|
|
+ scan_phymode = SCAN_PHY_MODE_11A;
|
|
|
+ break;
|
|
|
+ case WLAN_PHYMODE_11B:
|
|
|
+ scan_phymode = SCAN_PHY_MODE_11B;
|
|
|
+ break;
|
|
|
+ case WLAN_PHYMODE_11G:
|
|
|
+ scan_phymode = SCAN_PHY_MODE_11G;
|
|
|
+ break;
|
|
|
+ case WLAN_PHYMODE_11G_ONLY:
|
|
|
+ scan_phymode = SCAN_PHY_MODE_11GONLY;
|
|
|
+ break;
|
|
|
+ case WLAN_PHYMODE_11NA_HT20:
|
|
|
+ scan_phymode = SCAN_PHY_MODE_11NA_HT20;
|
|
|
+ break;
|
|
|
+ case WLAN_PHYMODE_11NG_HT20:
|
|
|
+ scan_phymode = SCAN_PHY_MODE_11NG_HT20;
|
|
|
+ break;
|
|
|
+ case WLAN_PHYMODE_11NA_HT40:
|
|
|
+ scan_phymode = SCAN_PHY_MODE_11NA_HT40;
|
|
|
+ break;
|
|
|
+ case WLAN_PHYMODE_11NG_HT40:
|
|
|
+ scan_phymode = SCAN_PHY_MODE_11NG_HT40;
|
|
|
+ break;
|
|
|
+ case WLAN_PHYMODE_11AC_VHT20:
|
|
|
+ scan_phymode = SCAN_PHY_MODE_11AC_VHT20;
|
|
|
+ break;
|
|
|
+ case WLAN_PHYMODE_11AC_VHT40:
|
|
|
+ scan_phymode = SCAN_PHY_MODE_11AC_VHT40;
|
|
|
+ break;
|
|
|
+ case WLAN_PHYMODE_11AC_VHT80:
|
|
|
+ scan_phymode = SCAN_PHY_MODE_11AC_VHT80;
|
|
|
+ break;
|
|
|
+ case WLAN_PHYMODE_11AC_VHT20_2G:
|
|
|
+ scan_phymode = SCAN_PHY_MODE_11AC_VHT20_2G;
|
|
|
+ break;
|
|
|
+ case WLAN_PHYMODE_11AC_VHT40_2G:
|
|
|
+ scan_phymode = SCAN_PHY_MODE_11AC_VHT40_2G;
|
|
|
+ break;
|
|
|
+ case WLAN_PHYMODE_11AC_VHT80_2G:
|
|
|
+ scan_phymode = SCAN_PHY_MODE_11AC_VHT80_2G;
|
|
|
+ break;
|
|
|
+ case WLAN_PHYMODE_11AC_VHT80_80:
|
|
|
+ scan_phymode = SCAN_PHY_MODE_11AC_VHT80_80;
|
|
|
+ break;
|
|
|
+ case WLAN_PHYMODE_11AC_VHT160:
|
|
|
+ scan_phymode = SCAN_PHY_MODE_11AC_VHT160;
|
|
|
+ break;
|
|
|
+ case WLAN_PHYMODE_11AXA_HE20:
|
|
|
+ scan_phymode = SCAN_PHY_MODE_11AX_HE20;
|
|
|
+ break;
|
|
|
+ case WLAN_PHYMODE_11AXG_HE20:
|
|
|
+ scan_phymode = SCAN_PHY_MODE_11AX_HE20_2G;
|
|
|
+ break;
|
|
|
+ case WLAN_PHYMODE_11AXA_HE40:
|
|
|
+ scan_phymode = SCAN_PHY_MODE_11AX_HE40;
|
|
|
+ break;
|
|
|
+ case WLAN_PHYMODE_11AXG_HE40:
|
|
|
+ scan_phymode = SCAN_PHY_MODE_11AX_HE40_2G;
|
|
|
+ break;
|
|
|
+ case WLAN_PHYMODE_11AXA_HE80:
|
|
|
+ scan_phymode = SCAN_PHY_MODE_11AX_HE80;
|
|
|
+ break;
|
|
|
+ case WLAN_PHYMODE_11AXG_HE80:
|
|
|
+ scan_phymode = SCAN_PHY_MODE_11AX_HE80_2G;
|
|
|
+ break;
|
|
|
+ case WLAN_PHYMODE_11AXA_HE80_80:
|
|
|
+ scan_phymode = SCAN_PHY_MODE_11AX_HE80_80;
|
|
|
+ break;
|
|
|
+ case WLAN_PHYMODE_11AXA_HE160:
|
|
|
+ scan_phymode = SCAN_PHY_MODE_11AX_HE160;
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ scan_phymode = SCAN_PHY_MODE_UNKNOWN;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (scan_phymode != SCAN_PHY_MODE_UNKNOWN)
|
|
|
+ return scan_phymode;
|
|
|
+
|
|
|
+ scan_phymode = wlan_scan_get_11be_scan_phy_mode(des_chan->ch_phymode);
|
|
|
+
|
|
|
+ return scan_phymode;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * mlme_update_freq_in_scan_start_req() - Fill frequencies in wide
|
|
|
+ * band scan req for mlo connection
|
|
|
+ * @vdev: vdev common object
|
|
|
+ * @req: pointer to scan request
|
|
|
+ * @associated_ch_width: channel width at the time of initial connection
|
|
|
+ *
|
|
|
+ * Return: QDF_STATUS
|
|
|
+ */
|
|
|
+static QDF_STATUS
|
|
|
+mlme_update_freq_in_scan_start_req(struct wlan_objmgr_vdev *vdev,
|
|
|
+ struct scan_start_request *req,
|
|
|
+ enum phy_ch_width associated_ch_width)
|
|
|
+{
|
|
|
+ const struct bonded_channel_freq *range;
|
|
|
+ uint8_t num_chan;
|
|
|
+ qdf_freq_t op_freq;
|
|
|
+ enum scan_phy_mode phymode = SCAN_PHY_MODE_UNKNOWN;
|
|
|
+
|
|
|
+ op_freq = wlan_get_operation_chan_freq(vdev);
|
|
|
+
|
|
|
+ if (associated_ch_width == CH_WIDTH_320MHZ) {
|
|
|
+ range = wlan_reg_get_bonded_chan_entry(op_freq,
|
|
|
+ associated_ch_width, 0);
|
|
|
+ if (!range) {
|
|
|
+ mlme_debug("vdev %d : range is null for freq %d",
|
|
|
+ req->scan_req.vdev_id,
|
|
|
+ op_freq);
|
|
|
+ return QDF_STATUS_E_FAILURE;
|
|
|
+ }
|
|
|
+
|
|
|
+ phymode = mlme_get_scan_phy_mode();
|
|
|
+ if (phymode == SCAN_PHY_MODE_UNKNOWN) {
|
|
|
+ mlme_debug("vdev %d : invalid scan phymode for freq %d",
|
|
|
+ req->scan_req.vdev_id,
|
|
|
+ op_freq);
|
|
|
+ return QDF_STATUS_E_FAILURE;
|
|
|
+ }
|
|
|
+ num_chan = req->scan_req.chan_list.num_chan;
|
|
|
+ req->scan_req.chan_list.chan[num_chan].freq = range->start_freq;
|
|
|
+ req->scan_req.chan_list.chan[num_chan].phymode = phymode;
|
|
|
+ num_chan += 1;
|
|
|
+ req->scan_req.chan_list.chan[num_chan].freq = range->end_freq;
|
|
|
+ req->scan_req.chan_list.chan[num_chan].phymode = phymode;
|
|
|
+ num_chan += 1;
|
|
|
+ req->scan_req.chan_list.num_chan = num_chan;
|
|
|
+ } else {
|
|
|
+ phymode = wlan_scan_get_scan_phy_mode(vdev, op_freq,
|
|
|
+ req->scan_req.vdev_id);
|
|
|
+ if (phymode == SCAN_PHY_MODE_UNKNOWN) {
|
|
|
+ mlme_debug("vdev %d : invalid scan phymode for freq %d",
|
|
|
+ req->scan_req.vdev_id,
|
|
|
+ op_freq);
|
|
|
+ return QDF_STATUS_E_FAILURE;
|
|
|
+ }
|
|
|
+
|
|
|
+ num_chan = req->scan_req.chan_list.num_chan;
|
|
|
+ req->scan_req.chan_list.chan[num_chan].freq = op_freq;
|
|
|
+ req->scan_req.chan_list.chan[num_chan].phymode = phymode;
|
|
|
+ req->scan_req.chan_list.num_chan += 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ return QDF_STATUS_SUCCESS;
|
|
|
+}
|
|
|
+
|
|
|
+#ifdef WLAN_FEATURE_11BE_MLO
|
|
|
+/**
|
|
|
+ * mlme_fill_freq_in_mlo_wide_band_scan_start_req() - Fill frequencies in wide
|
|
|
+ * band scan req for mlo connection
|
|
|
+ * @vdev: vdev common object
|
|
|
+ * @req: pointer to scan request
|
|
|
+ * @associated_ch_width: channel width at the time of initial connection
|
|
|
+ *
|
|
|
+ * Return: QDF_STATUS
|
|
|
+ */
|
|
|
+static QDF_STATUS
|
|
|
+mlme_fill_freq_in_mlo_wide_band_scan_start_req(struct wlan_objmgr_vdev *vdev,
|
|
|
+ struct scan_start_request *req,
|
|
|
+ enum phy_ch_width associated_ch_width)
|
|
|
+{
|
|
|
+ struct wlan_mlo_dev_context *mlo_dev_ctx;
|
|
|
+ struct wlan_mlo_sta *sta_ctx = NULL;
|
|
|
+ struct wlan_channel *chan;
|
|
|
+ uint8_t i;
|
|
|
+ QDF_STATUS status;
|
|
|
+ struct wlan_objmgr_vdev *mlo_vdev;
|
|
|
+
|
|
|
+ mlo_dev_ctx = vdev->mlo_dev_ctx;
|
|
|
+ if (!mlo_dev_ctx) {
|
|
|
+ mlme_err("vdev %d :mlo_dev_ctx is NULL", req->scan_req.vdev_id);
|
|
|
+ return QDF_STATUS_E_FAILURE;
|
|
|
+ }
|
|
|
+
|
|
|
+ sta_ctx = mlo_dev_ctx->sta_ctx;
|
|
|
+ if (!sta_ctx) {
|
|
|
+ mlme_err("vdev %d :mlo_dev_ctx is NULL", req->scan_req.vdev_id);
|
|
|
+ return QDF_STATUS_E_FAILURE;
|
|
|
+ }
|
|
|
+
|
|
|
+ for (i = 0; i < WLAN_UMAC_MLO_MAX_VDEVS; i++) {
|
|
|
+ if (!mlo_dev_ctx->wlan_vdev_list[i])
|
|
|
+ continue;
|
|
|
+ if (qdf_test_bit(i, sta_ctx->wlan_connected_links)) {
|
|
|
+ chan = wlan_vdev_get_active_channel(vdev);
|
|
|
+ if (!chan) {
|
|
|
+ mlme_err("vdev %d :failed to get freq info",
|
|
|
+ req->scan_req.vdev_id);
|
|
|
+ return QDF_STATUS_E_FAILURE;
|
|
|
+ }
|
|
|
+
|
|
|
+ mlo_vdev = mlo_dev_ctx->wlan_vdev_list[i];
|
|
|
+ status = mlme_update_freq_in_scan_start_req(mlo_vdev,
|
|
|
+ req, associated_ch_width);
|
|
|
+ if (QDF_IS_STATUS_ERROR(status))
|
|
|
+ return QDF_STATUS_E_FAILURE;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ mlme_debug("vdev %d :trigger wide band scan for mlo conn, num freq %d",
|
|
|
+ req->scan_req.vdev_id, req->scan_req.chan_list.num_chan);
|
|
|
+ return QDF_STATUS_SUCCESS;
|
|
|
+}
|
|
|
+#else
|
|
|
+static inline QDF_STATUS
|
|
|
+mlme_fill_freq_in_mlo_wide_band_scan_start_req(struct wlan_objmgr_vdev *vdev,
|
|
|
+ struct scan_start_request *req,
|
|
|
+ enum phy_ch_width associated_ch_width)
|
|
|
+{
|
|
|
+ return QDF_STATUS_E_FAILURE;
|
|
|
+}
|
|
|
+#endif
|
|
|
+
|
|
|
/**
|
|
|
* mlme_fill_freq_in_wide_scan_start_request() - Fill frequencies in wide band
|
|
|
* scan req
|
|
@@ -186,50 +481,37 @@ static QDF_STATUS
|
|
|
mlme_fill_freq_in_wide_scan_start_request(struct wlan_objmgr_vdev *vdev,
|
|
|
struct scan_start_request *req)
|
|
|
{
|
|
|
- const struct bonded_channel_freq *range;
|
|
|
struct mlme_legacy_priv *mlme_priv;
|
|
|
enum phy_ch_width associated_ch_width;
|
|
|
- qdf_freq_t operation_chan_freq;
|
|
|
+ QDF_STATUS status;
|
|
|
|
|
|
mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev);
|
|
|
if (!mlme_priv)
|
|
|
return QDF_STATUS_E_FAILURE;
|
|
|
|
|
|
- operation_chan_freq = wlan_get_operation_chan_freq(vdev);
|
|
|
associated_ch_width = mlme_priv->connect_info.ch_width_orig;
|
|
|
-
|
|
|
if (associated_ch_width == CH_WIDTH_INVALID) {
|
|
|
- mlme_debug("vdev %d :Invalid assoc ch width, freq %d",
|
|
|
- req->scan_req.vdev_id, operation_chan_freq);
|
|
|
+ mlme_debug("vdev %d :Invalid associated ch_width",
|
|
|
+ req->scan_req.vdev_id);
|
|
|
return QDF_STATUS_E_FAILURE;
|
|
|
}
|
|
|
|
|
|
- if (associated_ch_width == CH_WIDTH_320MHZ) {
|
|
|
- range = wlan_reg_get_bonded_chan_entry(operation_chan_freq,
|
|
|
- associated_ch_width, 0);
|
|
|
- if (!range) {
|
|
|
- mlme_debug("vdev %d : range is null for freq %d",
|
|
|
- req->scan_req.vdev_id, operation_chan_freq);
|
|
|
- return QDF_STATUS_E_FAILURE;
|
|
|
- }
|
|
|
-
|
|
|
- mlme_debug("vdev %d :trigger wide band scan for freq %d bw %d, range [%d-%d], total freq %d",
|
|
|
- req->scan_req.vdev_id, operation_chan_freq,
|
|
|
- associated_ch_width, range->start_freq,
|
|
|
- range->end_freq, req->scan_req.chan_list.num_chan);
|
|
|
+ req->scan_req.chan_list.num_chan = 0;
|
|
|
|
|
|
-
|
|
|
- req->scan_req.chan_list.num_chan = 2;
|
|
|
- req->scan_req.chan_list.chan[0].freq = range->start_freq;
|
|
|
- req->scan_req.chan_list.chan[1].freq = range->end_freq;
|
|
|
- } else {
|
|
|
- mlme_debug("vdev %d : trigger wide band scan for freq %d bw %d",
|
|
|
- req->scan_req.vdev_id, operation_chan_freq,
|
|
|
- associated_ch_width);
|
|
|
- req->scan_req.chan_list.num_chan = 1;
|
|
|
- req->scan_req.chan_list.chan[0].freq = operation_chan_freq;
|
|
|
+ if (wlan_vdev_mlme_is_mlo_vdev(vdev)) {
|
|
|
+ status = mlme_fill_freq_in_mlo_wide_band_scan_start_req(vdev,
|
|
|
+ req, associated_ch_width);
|
|
|
+ if (QDF_IS_STATUS_ERROR(status))
|
|
|
+ return QDF_STATUS_E_FAILURE;
|
|
|
+ goto update_param;
|
|
|
}
|
|
|
|
|
|
+ status = mlme_update_freq_in_scan_start_req(vdev, req,
|
|
|
+ associated_ch_width);
|
|
|
+ if (QDF_IS_STATUS_ERROR(status))
|
|
|
+ return QDF_STATUS_E_FAILURE;
|
|
|
+
|
|
|
+update_param:
|
|
|
req->scan_req.dwell_time_passive =
|
|
|
MLME_GET_CHAN_STATS_WIDE_BAND_PASSIVE_SCAN_TIME;
|
|
|
req->scan_req.dwell_time_passive_6g =
|
|
@@ -266,13 +548,6 @@ QDF_STATUS mlme_connected_chan_stats_request(struct wlan_objmgr_psoc *psoc,
|
|
|
return QDF_STATUS_E_FAILURE;
|
|
|
}
|
|
|
|
|
|
- if (wlan_vdev_mlme_is_mlo_vdev(vdev)) {
|
|
|
- mlme_debug("vdev %d :reject get_cu req for mlo connection",
|
|
|
- vdev_id);
|
|
|
- wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_NB_ID);
|
|
|
- return QDF_STATUS_E_NOSUPPORT;
|
|
|
- }
|
|
|
-
|
|
|
req = qdf_mem_malloc(sizeof(*req));
|
|
|
if (!req) {
|
|
|
wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_NB_ID);
|