|
@@ -7230,6 +7230,96 @@ static int wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
+static const struct
|
|
|
+nla_policy qca_wlan_vendor_attr[QCA_WLAN_VENDOR_ATTR_MAX+1] = {
|
|
|
+ [QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY] = {.type = NLA_U32},
|
|
|
+ [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = {.type = NLA_BINARY,
|
|
|
+ .len = QDF_MAC_ADDR_SIZE},
|
|
|
+};
|
|
|
+
|
|
|
+/**
|
|
|
+ * __wlan_hdd_cfg80211_set_fast_roaming() - enable/disable roaming
|
|
|
+ * @wiphy: Pointer to wireless phy
|
|
|
+ * @wdev: Pointer to wireless device
|
|
|
+ * @data: Pointer to data
|
|
|
+ * @data_len: Length of @data
|
|
|
+ *
|
|
|
+ * This function is used to enable/disable roaming using vendor commands
|
|
|
+ *
|
|
|
+ * Return: 0 on success, negative errno on failure
|
|
|
+ */
|
|
|
+static int __wlan_hdd_cfg80211_set_fast_roaming(struct wiphy *wiphy,
|
|
|
+ struct wireless_dev *wdev,
|
|
|
+ const void *data, int data_len)
|
|
|
+{
|
|
|
+ hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
|
|
|
+ struct net_device *dev = wdev->netdev;
|
|
|
+ hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
|
|
|
+ struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
|
|
|
+ uint32_t is_fast_roam_enabled;
|
|
|
+ int ret;
|
|
|
+
|
|
|
+ ENTER_DEV(dev);
|
|
|
+
|
|
|
+ ret = wlan_hdd_validate_context(hdd_ctx);
|
|
|
+ if (0 != ret)
|
|
|
+ return ret;
|
|
|
+
|
|
|
+ if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
|
|
|
+ hdd_err("Command not allowed in FTM mode");
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
+
|
|
|
+ ret = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
|
|
|
+ qca_wlan_vendor_attr);
|
|
|
+ if (ret) {
|
|
|
+ hdd_err("Invalid ATTR");
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Parse and fetch Enable flag */
|
|
|
+ if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]) {
|
|
|
+ hdd_err("attr enable failed");
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
+
|
|
|
+ is_fast_roam_enabled = nla_get_u32(
|
|
|
+ tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]);
|
|
|
+ hdd_notice("isFastRoamEnabled %d", is_fast_roam_enabled);
|
|
|
+
|
|
|
+ /* Update roaming */
|
|
|
+ ret = sme_config_fast_roaming(hdd_ctx->hHal, adapter->sessionId,
|
|
|
+ is_fast_roam_enabled);
|
|
|
+ if (ret)
|
|
|
+ hdd_err("sme_config_fast_roaming failed");
|
|
|
+ EXIT();
|
|
|
+ return ret;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * wlan_hdd_cfg80211_set_fast_roaming() - enable/disable roaming
|
|
|
+ * @wiphy: Pointer to wireless phy
|
|
|
+ * @wdev: Pointer to wireless device
|
|
|
+ * @data: Pointer to data
|
|
|
+ * @data_len: Length of @data
|
|
|
+ *
|
|
|
+ * Wrapper function of __wlan_hdd_cfg80211_set_fast_roaming()
|
|
|
+ *
|
|
|
+ * Return: 0 on success, negative errno on failure
|
|
|
+ */
|
|
|
+static int wlan_hdd_cfg80211_set_fast_roaming(struct wiphy *wiphy,
|
|
|
+ struct wireless_dev *wdev,
|
|
|
+ const void *data, int data_len)
|
|
|
+{
|
|
|
+ int ret;
|
|
|
+
|
|
|
+ cds_ssr_protect(__func__);
|
|
|
+ ret = __wlan_hdd_cfg80211_set_fast_roaming(wiphy, wdev, data, data_len);
|
|
|
+ cds_ssr_unprotect(__func__);
|
|
|
+
|
|
|
+ return ret;
|
|
|
+}
|
|
|
+
|
|
|
const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] = {
|
|
|
{
|
|
|
.info.vendor_id = QCA_NL80211_VENDOR_ID,
|
|
@@ -7785,6 +7875,14 @@ const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] = {
|
|
|
WIPHY_VENDOR_CMD_NEED_NETDEV |
|
|
|
WIPHY_VENDOR_CMD_NEED_RUNNING,
|
|
|
.doit = wlan_hdd_cfg80211_setband
|
|
|
+ },
|
|
|
+ {
|
|
|
+ .info.vendor_id = QCA_NL80211_VENDOR_ID,
|
|
|
+ .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ROAMING,
|
|
|
+ .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
|
|
|
+ WIPHY_VENDOR_CMD_NEED_NETDEV |
|
|
|
+ WIPHY_VENDOR_CMD_NEED_RUNNING,
|
|
|
+ .doit = wlan_hdd_cfg80211_set_fast_roaming
|
|
|
}
|
|
|
};
|
|
|
|