CONFIG_SCSC_WLAN_WIFI_SHARING=y
# CONFIG_SCSC_WLAN_SINGLE_ANTENNA is not set
# CONFIG_SCSC_WLAN_MHS_STATIC_INTERFACE is not set
+CONFIG_SCSC_WLAN_SAE_CONFIG=y
CONFIG_INPUT_EVDEV=y
CONFIG_INPUT_KEYRESET=y
CONFIG_KEYBOARD_GPIO=y
---help---
This option tells if wifi sharing is supported or not.
+config SCSC_WLAN_SAE_CONFIG
+ bool "Wpa3 Support"
+ default n
+ ---help---
+ This option tells if wpa3 is supported or not.
+
config SCSC_WLAN_ENABLE_MAC_RANDOMISATION
bool "Wifi Mac Randomization Support"
default n
*/
netif_carrier_on(dev);
ndev_vif->sta.vif_status = SLSI_VIF_STATUS_CONNECTING;
- r = slsi_mlme_connect(sdev, dev, sme, channel, bssid);
+ if (sme->auth_type == NL80211_AUTHTYPE_SAE && (sme->flags & CONNECT_REQ_EXTERNAL_AUTH_SUPPORT)) {
+ const u8 *rsn;
+
+ ndev_vif->sta.crypto.wpa_versions = 3;
+ rsn = cfg80211_find_ie(WLAN_EID_RSN, ndev_vif->sta.sta_bss->ies->data, ndev_vif->sta.sta_bss->ies->len);
+ if (rsn) {
+ int pos;
+
+ pos = 7 + 2 + (rsn[8] * 4) + 2;
+ ndev_vif->sta.crypto.akm_suites[0] = ((rsn[pos + 4] << 24) | (rsn[pos + 3] << 16) | (rsn[pos + 2] << 8) | (rsn[pos + 1]));
+ }
+
+ SLSI_NET_DBG1(dev, SLSI_CFG80211, "RSN IE: : %1d\n", ndev_vif->sta.crypto.akm_suites[0]);
+ } else {
+ ndev_vif->sta.crypto.wpa_versions = 0;
+ }
+ r = slsi_mlme_connect(sdev, dev, sme, channel, bssid);
if (r != 0) {
ndev_vif->sta.is_wps = false;
SLSI_NET_ERR(dev, "connect failed: %d\n", r);
int r = 0;
struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf;
- slsi_wlan_dump_public_action_subtype(sdev, mgmt, true);
-
+ if (!ieee80211_is_auth(mgmt->frame_control))
+ slsi_wlan_dump_public_action_subtype(sdev, mgmt, true);
if (!ndev_vif->activated) {
r = slsi_wlan_unsync_vif_activate(sdev, dev, chan, wait);
if (r)
queue_delayed_work(sdev->device_wq, &ndev_vif->unsync.hs2_del_vif_work, msecs_to_jiffies(wait));
} else {
/* vif is active*/
- if (ndev_vif->vif_type == FAPI_VIFTYPE_UNSYNCHRONISED) {
+ if (ieee80211_is_auth(mgmt->frame_control)) {
+ SLSI_NET_DBG1(dev, SLSI_CFG80211, "Transmit on the current frequency\n");
+ r = slsi_mlme_send_frame_mgmt(sdev, dev, buf, len, FAPI_DATAUNITDESCRIPTOR_IEEE802_11_FRAME, FAPI_MESSAGETYPE_IEEE80211_MGMT_NOT_ACTION, host_tag, 0, wait * 1000, 0);
+ if (r)
+ return r;
+ } else if (ndev_vif->vif_type == FAPI_VIFTYPE_UNSYNCHRONISED) {
cancel_delayed_work(&ndev_vif->unsync.hs2_del_vif_work);
/*even if we fail to cancel the delayed work, we shall go ahead and send action frames*/
if (ndev_vif->driver_channel != chan->hw_value) {
SLSI_MUTEX_LOCK(ndev_vif->vif_mutex);
- SLSI_NET_DBG2(dev, SLSI_CFG80211, "Mgmt Frame Tx: iface_num = %d, channel = %d, wait = %d, noAck = %d,"
- "offchannel = %d, mgmt->frame_control = %d, vif_type = %d\n", ndev_vif->ifnum, chan->hw_value,
- wait, dont_wait_for_ack, offchan, mgmt->frame_control, ndev_vif->vif_type);
+ if (!(ieee80211_is_auth(mgmt->frame_control))) {
+ SLSI_NET_DBG2(dev, SLSI_CFG80211, "Mgmt Frame Tx: iface_num = %d, channel = %d, wait = %d, noAck = %d,"
+ "offchannel = %d, mgmt->frame_control = %d, vif_type = %d\n", ndev_vif->ifnum, chan->hw_value,
+ wait, dont_wait_for_ack, offchan, mgmt->frame_control, ndev_vif->vif_type);
+ } else {
+ SLSI_NET_DBG2(dev, SLSI_CFG80211, "Received Auth Frame");
+ }
if (!(ieee80211_is_mgmt(mgmt->frame_control))) {
SLSI_NET_ERR(dev, "Drop Tx frame: Not a Management frame\n");
r = -EINVAL;
goto exit;
}
-
if (SLSI_IS_VIF_INDEX_WLAN(ndev_vif)) {
r = slsi_wlan_mgmt_tx(SDEV_FROM_WIPHY(wiphy), dev, chan, wait, buf, len, dont_wait_for_ack, cookie);
goto exit;
return r;
}
+int slsi_synchronised_response(struct wiphy *wiphy, struct net_device *dev,
+ struct cfg80211_external_auth_params *params)
+{
+ struct slsi_dev *sdev = SDEV_FROM_WIPHY(wiphy);
+ struct netdev_vif *ndev_vif = netdev_priv(dev);
+ int r;
+
+ SLSI_MUTEX_LOCK(ndev_vif->vif_mutex);
+ r = slsi_mlme_synchronised_response(sdev, dev, params);
+ SLSI_MUTEX_UNLOCK(ndev_vif->vif_mutex);
+ return r;
+}
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 9))
static int slsi_update_ft_ies(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_update_ft_ies_params *ftie)
{
.mgmt_tx = slsi_mgmt_tx,
.mgmt_tx_cancel_wait = slsi_mgmt_tx_cancel_wait,
.set_txq_params = slsi_set_txq_params,
+ .external_auth = slsi_synchronised_response,
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 9))
.set_mac_acl = slsi_set_mac_acl,
.update_ft_ies = slsi_update_ft_ies,
ieee80211_default_mgmt_stypes[NUM_NL80211_IFTYPES] = {
[NL80211_IFTYPE_AP] = {
.tx = 0xffff,
- .rx = BIT(IEEE80211_STYPE_ACTION >> 4)
+ .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
+ BIT(IEEE80211_STYPE_AUTH >> 4)
},
[NL80211_IFTYPE_STATION] = {
.tx = 0xffff,
.rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
- BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
+ BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
+ BIT(IEEE80211_STYPE_AUTH >> 4)
},
[NL80211_IFTYPE_P2P_GO] = {
.tx = 0xffff,
#ifdef CONFIG_SCSC_WLAN_ENABLE_MAC_RANDOMISATION
wiphy->features |= NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR;
#endif
+#endif
+#ifdef CONFIG_SCSC_WLAN_SAE_CONFIG
+ wiphy->features |= NL80211_FEATURE_SAE;
#endif
return sdev;
}
/*This structure is used to store last disconnected bss info and valid even when vif is deactivated. */
struct slsi_last_connected_bss last_connected_bss;
+ struct cfg80211_crypto_settings crypto;
};
struct slsi_vif_unsync {
#define FAPI_MESSAGETYPE_WAI_MESSAGE 0x0007
#define FAPI_MESSAGETYPE_PERIODIC_OFFLOAD 0x0008
#define FAPI_MESSAGETYPE_IEEE80211_ACTION 0x0010
+/* TBD: Auto generate to add this */
+#define FAPI_MESSAGETYPE_IEEE80211_MGMT_NOT_ACTION 0x0011
#define FAPI_MODE_SOURCE 0x0001
#define FAPI_MODE_SINK 0x0002
case NL80211_AUTHTYPE_OPEN_SYSTEM:
case NL80211_AUTHTYPE_SHARED_KEY:
break;
+ case NL80211_AUTHTYPE_SAE:
+ auth_type = NL80211_AUTHTYPE_NETWORK_EAP;
+ break;
case NL80211_AUTHTYPE_AUTOMATIC:
/* In case of WEP, need to try both open and shared.
* FW does this if auth is shared_key. So set it to shared.
return slsi_mlme_powermgt_unlocked(sdev, dev, power_mode);
}
+int slsi_mlme_synchronised_response(struct slsi_dev *sdev, struct net_device *dev,
+ struct cfg80211_external_auth_params *params)
+{
+ struct netdev_vif *ndev_vif = netdev_priv(dev);
+ struct sk_buff *req;
+ struct sk_buff *cfm;
+ if (ndev_vif->activated) {
+ SLSI_NET_DBG3(dev, SLSI_MLME, "MLME_SPARE_SIGNAL_1_RES\n");
+
+ req = fapi_alloc(mlme_spare_signal_1_res, MLME_SPARE_SIGNAL_1_RES, ndev_vif->ifnum, 0);
+ if (!req)
+ return -ENOMEM;
+
+ fapi_set_low16_u32(req, u.mlme_spare_signal_1_res.spare_1, params->status);
+ fapi_set_high16_u32(req, u.mlme_spare_signal_1_res.spare_1, *(u16 *)(¶ms->bssid[0]));
+ fapi_set_u32(req, u.mlme_spare_signal_1_res.spare_2, *(u32 *)(¶ms->bssid[2]));
+
+ SLSI_NET_DBG2(dev, SLSI_MLME, "mlme_synchronised_response(vif:%d) status:%d\n",
+ ndev_vif->ifnum, params->status);
+ cfm = slsi_mlme_req_no_cfm(sdev, dev, req);
+ if (cfm)
+ SLSI_NET_ERR(dev, "Received cfm for MLME_SPARE_SIGNAL_1_RES\n");
+ } else
+ SLSI_NET_DBG1(dev, SLSI_MLME, "vif is not active");
+
+ return 0;
+}
int slsi_mlme_register_action_frame(struct slsi_dev *sdev, struct net_device *dev, u32 af_bitmap_active, u32 af_bitmap_suspended)
{
struct netdev_vif *ndev_vif = netdev_priv(dev);
int slsi_mlme_powermgt(struct slsi_dev *sdev, struct net_device *dev, u16 ps_mode);
int slsi_mlme_powermgt_unlocked(struct slsi_dev *sdev, struct net_device *dev, u16 ps_mode);
int slsi_mlme_register_action_frame(struct slsi_dev *sdev, struct net_device *dev, u32 af_bitmap_active, u32 af_bitmap_suspended);
+int slsi_mlme_synchronised_response(struct slsi_dev *sdev, struct net_device *dev,
+ struct cfg80211_external_auth_params *params);
int slsi_mlme_channel_switch(struct slsi_dev *sdev, struct net_device *dev, u16 center_freq, u16 chan_info);
int slsi_mlme_add_info_elements(struct slsi_dev *sdev, struct net_device *dev, u16 purpose, const u8 *ies, const u16 ies_len);
int slsi_mlme_send_frame_mgmt(struct slsi_dev *sdev, struct net_device *dev, const u8 *frame, int frame_len, u16 data_desc, u16 msg_type, u16 host_tag, u16 freq, u32 dwell_time, u32 period);
}
}
+void slsi_rx_synchronised_ind(struct slsi_dev *sdev, struct net_device *dev, struct sk_buff *skb)
+{
+ struct netdev_vif *ndev_vif = netdev_priv(dev);
+ const u8 *connecting_ssid = NULL;
+ struct cfg80211_external_auth_params auth_request;
+ int r;
+
+ SLSI_MUTEX_LOCK(ndev_vif->vif_mutex);
+ SLSI_NET_DBG1(dev, SLSI_MLME, "Received slsi_rx_synchronised_ind\n");
+ if (ndev_vif->sta.sta_bss->ies->len)
+ connecting_ssid = cfg80211_find_ie(WLAN_EID_SSID, ndev_vif->sta.sta_bss->ies->data,
+ ndev_vif->sta.sta_bss->ies->len);
+
+ auth_request.action = NL80211_EXTERNAL_AUTH_START;
+ memcpy(auth_request.bssid, ndev_vif->sta.sta_bss->bssid, ETH_ALEN);
+ if (connecting_ssid && (connecting_ssid[1] > 0)) {
+ memcpy(auth_request.ssid.ssid, &connecting_ssid[2], connecting_ssid[1]);
+ auth_request.ssid.ssid_len = connecting_ssid[1];
+ }
+ auth_request.key_mgmt_suite = ndev_vif->sta.crypto.akm_suites[0];
+ r = cfg80211_external_auth_request(dev, &auth_request, GFP_KERNEL);
+ if (r)
+ SLSI_NET_DBG1(dev, SLSI_MLME, "cfg80211_external_auth_request failed");
+ SLSI_MUTEX_UNLOCK(ndev_vif->vif_mutex);
+}
+
void slsi_rx_connected_ind(struct slsi_dev *sdev, struct net_device *dev, struct sk_buff *skb)
{
struct netdev_vif *ndev_vif = netdev_priv(dev);
scsc_log_collector_schedule_collection(SCSC_LOG_HOST_WLAN, SCSC_LOG_HOST_WLAN_REASON_CONNECT_ERR);
#endif
status = fw_result_code;
+#ifdef CONFIG_SCSC_WLAN_SAE_CONFIG
+ if (ndev_vif->sta.crypto.wpa_versions == 3) {
+ const u8 *connecting_ssid = NULL;
+ int r;
+ struct cfg80211_external_auth_params auth_request;
+
+ if (ndev_vif->sta.sta_bss->ies->len)
+ connecting_ssid = cfg80211_find_ie(WLAN_EID_SSID, ndev_vif->sta.sta_bss->ies->data,
+ ndev_vif->sta.sta_bss->ies->len);
+
+ auth_request.action = NL80211_EXTERNAL_AUTH_ABORT;
+ memcpy(auth_request.bssid, ndev_vif->sta.sta_bss->bssid, ETH_ALEN);
+ if (connecting_ssid && (connecting_ssid[1] > 0)) {
+ memcpy(auth_request.ssid.ssid, &connecting_ssid[2], connecting_ssid[1]);
+ auth_request.ssid.ssid_len = connecting_ssid[1];
+ }
+ auth_request.key_mgmt_suite = ndev_vif->sta.crypto.akm_suites[0];
+ r = cfg80211_external_auth_request(dev, &auth_request, GFP_KERNEL);
+ if (r)
+ SLSI_NET_DBG1(dev, SLSI_MLME, "cfg80211_external_auth_request Abort failed");
+ }
+#endif
} else {
SLSI_INFO(sdev, "Received Association Response\n");
if (!peer || !peer->assoc_ie) {
if (!mgmt_len)
goto exit;
mgmt = fapi_get_mgmt(skb);
+ if (ieee80211_is_auth(mgmt->frame_control)) {
+ cfg80211_rx_mgmt(&ndev_vif->wdev, frequency, 0, (const u8 *)mgmt, mgmt_len, GFP_ATOMIC);
+ goto exit;
+ }
if (WARN_ON(!(ieee80211_is_action(mgmt->frame_control))))
goto exit;
-
if (SLSI_IS_VIF_INDEX_WLAN(ndev_vif)) {
#ifdef CONFIG_SCSC_WLAN_WES_NCHO
if (slsi_is_wes_action_frame(mgmt)) {
slsi_kfree_skb(skb);
break;
#endif
+ case MLME_SPARE_SIGNAL_1_IND:
+ slsi_rx_synchronised_ind(sdev, dev, skb);
+ slsi_kfree_skb(skb);
+ break;
default:
slsi_kfree_skb(skb);
SLSI_NET_ERR(dev, "Unhandled Ind: 0x%.4x\n", id);
void slsi_rx_scan_ind(struct slsi_dev *sdev, struct net_device *dev, struct sk_buff *skb);
void slsi_rx_scan_done_ind(struct slsi_dev *sdev, struct net_device *dev, struct sk_buff *skb);
void slsi_rx_channel_switched_ind(struct slsi_dev *sdev, struct net_device *dev, struct sk_buff *skb);
+void slsi_rx_synchronised_ind(struct slsi_dev *sdev, struct net_device *dev, struct sk_buff *skb);
void slsi_rx_connect_ind(struct slsi_dev *sdev, struct net_device *dev, struct sk_buff *skb);
void slsi_rx_connected_ind(struct slsi_dev *sdev, struct net_device *dev, struct sk_buff *skb);
void slsi_rx_received_frame_ind(struct slsi_dev *sdev, struct net_device *dev, struct sk_buff *skb);
* @ASSOC_REQ_DISABLE_HT: Disable HT (802.11n)
* @ASSOC_REQ_DISABLE_VHT: Disable VHT
* @ASSOC_REQ_USE_RRM: Declare RRM capability in this association
+ * @CONNECT_REQ_EXTERNAL_AUTH_SUPPORT: User space indicates external
+ * authentication capability. Drivers can offload authentication to
+ * userspace if this flag is set. Only applicable for cfg80211_connect()
+ * request (connect callback).
*/
enum cfg80211_assoc_req_flags {
- ASSOC_REQ_DISABLE_HT = BIT(0),
- ASSOC_REQ_DISABLE_VHT = BIT(1),
- ASSOC_REQ_USE_RRM = BIT(2),
+ ASSOC_REQ_DISABLE_HT = BIT(0),
+ ASSOC_REQ_DISABLE_VHT = BIT(1),
+ ASSOC_REQ_USE_RRM = BIT(2),
+#ifdef CONFIG_CFG80211_SLSI_SAE
+ CONNECT_REQ_EXTERNAL_AUTH_SUPPORT = BIT(3),
+#endif
};
/**
const u8 *pmk;
const u8 *pmk_r0_name;
};
+#ifdef CONFIG_CFG80211_SLSI_SAE
+/**
+ * struct cfg80211_external_auth_params - Trigger External authentication.
+ *
+ * Commonly used across the external auth request and event interfaces.
+ *
+ * @action: action type / trigger for external authentication. Only significant
+ * for the authentication request event interface (driver to user space).
+ * @bssid: BSSID of the peer with which the authentication has
+ * to happen. Used by both the authentication request event and
+ * authentication response command interface.
+ * @ssid: SSID of the AP. Used by both the authentication request event and
+ * authentication response command interface.
+ * @key_mgmt_suite: AKM suite of the respective authentication. Used by the
+ * authentication request event interface.
+ * @status: status code, %WLAN_STATUS_SUCCESS for successful authentication,
+ * use %WLAN_STATUS_UNSPECIFIED_FAILURE if user space cannot give you
+ * the real status code for failures. Used only for the authentication
+ * response command interface (user space to driver).
+ */
+struct cfg80211_external_auth_params {
+ enum nl80211_external_auth_action action;
+ u8 bssid[ETH_ALEN] __aligned(2);
+ struct cfg80211_ssid ssid;
+ unsigned int key_mgmt_suite;
+ u16 status;
+};
+#endif
/**
* struct cfg80211_ops - backend description for wireless configuration
* (invoked with the wireless_dev mutex held)
* @del_pmk: delete the previously configured PMK for the given authenticator.
* (invoked with the wireless_dev mutex held)
+ *
+ * @external_auth: indicates result of offloaded authentication processing from
+ * user space
*/
struct cfg80211_ops {
int (*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow);
const struct cfg80211_pmk_conf *conf);
int (*del_pmk)(struct wiphy *wiphy, struct net_device *dev,
const u8 *aa);
+#ifdef CONFIG_CFG80211_SLSI_SAE
+ int (*external_auth)(struct wiphy *wiphy, struct net_device *dev,
+ struct cfg80211_external_auth_params *params);
+#endif
};
/*
/* ethtool helper */
void cfg80211_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info);
+#ifdef CONFIG_CFG80211_SLSI_SAE
+/**
+ * cfg80211_external_auth_request - userspace request for authentication
+ * @netdev: network device
+ * @params: External authentication parameters
+ * @gfp: allocation flags
+ * Returns: 0 on success, < 0 on error
+ */
+int cfg80211_external_auth_request(struct net_device *netdev,
+ struct cfg80211_external_auth_params *params,
+ gfp_t gfp);
+#endif
+
/* Logging, debugging and troubleshooting/diagnostic helpers. */
/* wiphy_printk helpers, similar to dev_printk */
* configured PMK for the authenticator address identified by
* &NL80211_ATTR_MAC.
*
+ * @NL80211_CMD_EXTERNAL_AUTH: This interface is exclusively defined for host
+ * drivers that do not define separate commands for authentication and
+ * association, but rely on user space for the authentication to happen.
+ * This interface acts both as the event request (driver to user space)
+ * to trigger the authentication and command response (userspace to
+ * driver) to indicate the authentication status.
+ *
+ * User space uses the %NL80211_CMD_CONNECT command to the host driver to
+ * trigger a connection. The host driver selects a BSS and further uses
+ * this interface to offload only the authentication part to the user
+ * space. Authentication frames are passed between the driver and user
+ * space through the %NL80211_CMD_FRAME interface. Host driver proceeds
+ * further with the association after getting successful authentication
+ * status. User space indicates the authentication status through
+ * %NL80211_ATTR_STATUS_CODE attribute in %NL80211_CMD_EXTERNAL_AUTH
+ * command interface.
+ *
+ * Host driver reports this status on an authentication failure to the
+ * user space through the connect result as the user space would have
+ * initiated the connection through the connect request.
+ *
* @NL80211_CMD_MAX: highest used command number
* @__NL80211_CMD_AFTER_LAST: internal use
*/
NL80211_CMD_SET_PMK,
NL80211_CMD_DEL_PMK,
-
+#ifdef CONFIG_CFG80211_SLSI_SAE
+ NL80211_CMD_EXTERNAL_AUTH,
+#endif
/* add new commands above here */
/* used to define NL80211_CMD_MAX below */
* the driver or is not needed (because roaming used the Fast Transition
* protocol).
*
+ * @NL80211_ATTR_EXTERNAL_AUTH_ACTION: Identify the requested external
+ * authentication operation (u32 attribute with an
+ * &enum nl80211_external_auth_action value). This is used with the
+ * &NL80211_CMD_EXTERNAL_AUTH request event.
+ * @NL80211_ATTR_EXTERNAL_AUTH_SUPPORT: Flag attribute indicating that the user
+ * space supports external authentication. This attribute shall be used
+ * only with %NL80211_CMD_CONNECT request. The driver may offload
+ * authentication processing to user space if this capability is indicated
+ * in NL80211_CMD_CONNECT requests from the user space.
+ *
* @NUM_NL80211_ATTR: total number of nl80211_attrs available
* @NL80211_ATTR_MAX: highest attribute number currently defined
* @__NL80211_ATTR_AFTER_LAST: internal use
NL80211_ATTR_WANT_1X_4WAY_HS,
NL80211_ATTR_PMKR0_NAME,
NL80211_ATTR_PORT_AUTHORIZED,
+#ifdef CONFIG_CFG80211_SLSI_SAE
+ NL80211_ATTR_EXTERNAL_AUTH_ACTION,
+ NL80211_ATTR_EXTERNAL_AUTH_SUPPORT,
+#endif
/* add attributes here, update the policy in nl80211.c */
NUM_NL80211_NAN_MATCH_ATTR,
NL80211_NAN_MATCH_ATTR_MAX = NUM_NL80211_NAN_MATCH_ATTR - 1
};
-
+#ifdef CONFIG_CFG80211_SLSI_SAE
+/**
+ * nl80211_external_auth_action - Action to perform with external
+ * authentication request. Used by NL80211_ATTR_EXTERNAL_AUTH_ACTION.
+ * @NL80211_EXTERNAL_AUTH_START: Start the authentication.
+ * @NL80211_EXTERNAL_AUTH_ABORT: Abort the ongoing authentication.
+ */
+enum nl80211_external_auth_action {
+ NL80211_EXTERNAL_AUTH_START,
+ NL80211_EXTERNAL_AUTH_ABORT,
+};
+#endif
#endif /* __LINUX_NL80211_H */
applications instead -- they need to register their network
latency requirement, see Documentation/power/pm_qos_interface.txt.
+config CFG80211_SLSI_SAE
+ bool "Enable SAE in Kernel"
+ depends on CFG80211
+ default y
+ help
+ This option enables sae in kernel.
+
+ This Option enables SAE in CFG.
+ This option needs to be enabled if the kernel version by default doesnt
+ support SAE.
+
config CFG80211_DEBUGFS
bool "cfg80211 DebugFS entries"
depends on CFG80211
[NL80211_ATTR_FILS_CACHE_ID] = { .len = 2 },
[NL80211_ATTR_PMK] = { .type = NLA_BINARY, .len = PMK_MAX_LEN },
[NL80211_ATTR_SCHED_SCAN_MULTI] = { .type = NLA_FLAG },
+#ifdef CONFIG_CFG80211_SLSI_SAE
+ [NL80211_ATTR_EXTERNAL_AUTH_SUPPORT] = { .type = NLA_FLAG },
+#endif
};
/* policy for the key attributes */
return false;
return true;
case NL80211_CMD_CONNECT:
- /* SAE not supported yet */
- if (auth_type == NL80211_AUTHTYPE_SAE)
+ if (!(rdev->wiphy.features & NL80211_FEATURE_SAE) &&
+ auth_type == NL80211_AUTHTYPE_SAE)
return false;
/* FILS with SK PFS or PK not supported yet */
if (auth_type == NL80211_AUTHTYPE_FILS_SK_PFS ||
kzfree(connkeys);
return -EINVAL;
}
-
+#ifdef CONFIG_CFG80211_SLSI_SAE
+ if (nla_get_flag(info->attrs[NL80211_ATTR_EXTERNAL_AUTH_SUPPORT]))
+ connect.flags |= CONNECT_REQ_EXTERNAL_AUTH_SUPPORT;
+#endif
wdev_lock(dev->ieee80211_ptr);
err = cfg80211_connect(rdev, dev, &connect, connkeys,
return ret;
}
+#ifdef CONFIG_CFG80211_SLSI_SAE
+static int nl80211_external_auth(struct sk_buff *skb, struct genl_info *info)
+{
+ struct cfg80211_registered_device *rdev = info->user_ptr[0];
+ struct net_device *dev = info->user_ptr[1];
+ struct cfg80211_external_auth_params params;
+
+ if (!rdev->ops->external_auth)
+ return -EOPNOTSUPP;
+
+ if (!info->attrs[NL80211_ATTR_SSID])
+ return -EINVAL;
+
+ if (!info->attrs[NL80211_ATTR_BSSID])
+ return -EINVAL;
+
+ if (!info->attrs[NL80211_ATTR_STATUS_CODE])
+ return -EINVAL;
+
+ memset(¶ms, 0, sizeof(params));
+
+ params.ssid.ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
+ if (params.ssid.ssid_len == 0 ||
+ params.ssid.ssid_len > IEEE80211_MAX_SSID_LEN)
+ return -EINVAL;
+ memcpy(params.ssid.ssid, nla_data(info->attrs[NL80211_ATTR_SSID]),
+ params.ssid.ssid_len);
+
+ memcpy(params.bssid, nla_data(info->attrs[NL80211_ATTR_BSSID]),
+ ETH_ALEN);
+
+ params.status = nla_get_u16(info->attrs[NL80211_ATTR_STATUS_CODE]);
+
+ return rdev_external_auth(rdev, dev, ¶ms);
+}
+#endif
+
#define NL80211_FLAG_NEED_WIPHY 0x01
#define NL80211_FLAG_NEED_NETDEV 0x02
#define NL80211_FLAG_NEED_RTNL 0x04
.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
NL80211_FLAG_NEED_RTNL,
},
+#ifdef CONFIG_CFG80211_SLSI_SAE
+ {
+ .cmd = NL80211_CMD_EXTERNAL_AUTH,
+ .doit = nl80211_external_auth,
+ .policy = nl80211_policy,
+ .flags = GENL_ADMIN_PERM,
+ .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
+ NL80211_FLAG_NEED_RTNL,
+ },
+#endif
};
{
struct sk_buff *msg;
void *hdr;
-
msg = nlmsg_new(100 + len, gfp);
if (!msg)
return;
nlmsg_free(msg);
}
+#ifdef CONFIG_CFG80211_SLSI_SAE
+int cfg80211_external_auth_request(struct net_device *dev,
+ struct cfg80211_external_auth_params *params,
+ gfp_t gfp)
+{
+ struct wireless_dev *wdev = dev->ieee80211_ptr;
+ struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
+ struct sk_buff *msg;
+ void *hdr;
+
+ if (!wdev->conn_owner_nlportid)
+ return -EINVAL;
+
+ msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
+ if (!msg)
+ return -ENOMEM;
+
+ hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_EXTERNAL_AUTH);
+ if (!hdr)
+ goto nla_put_failure;
+
+ if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
+ nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
+ nla_put_u32(msg, NL80211_ATTR_AKM_SUITES, params->key_mgmt_suite) ||
+ nla_put_u32(msg, NL80211_ATTR_EXTERNAL_AUTH_ACTION,
+ params->action) ||
+ nla_put(msg, NL80211_ATTR_BSSID, ETH_ALEN, params->bssid) ||
+ nla_put(msg, NL80211_ATTR_SSID, params->ssid.ssid_len,
+ params->ssid.ssid))
+ goto nla_put_failure;
+
+ genlmsg_end(msg, hdr);
+ genlmsg_unicast(wiphy_net(&rdev->wiphy), msg,
+ wdev->conn_owner_nlportid);
+ return 0;
+
+ nla_put_failure:
+ nlmsg_free(msg);
+ return -ENOBUFS;
+}
+EXPORT_SYMBOL(cfg80211_external_auth_request);
+#endif
/* initialisation/exit functions */
int __init nl80211_init(void)
trace_rdev_return_int(&rdev->wiphy, ret);
return ret;
}
+
+#ifdef CONFIG_CFG80211_SLSI_SAE
+static inline int
+rdev_external_auth(struct cfg80211_registered_device *rdev,
+ struct net_device *dev,
+ struct cfg80211_external_auth_params *params)
+{
+ int ret = -EOPNOTSUPP;
+
+ trace_rdev_external_auth(&rdev->wiphy, dev, params);
+ if (rdev->ops->external_auth)
+ ret = rdev->ops->external_auth(&rdev->wiphy, dev, params);
+ trace_rdev_return_int(&rdev->wiphy, ret);
+ return ret;
+}
+#endif
+
#endif /* __CFG80211_RDEV_OPS */
WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(aa))
);
+#ifdef CONFIG_CFG80211_SLSI_SAE
+TRACE_EVENT(rdev_external_auth,
+ TP_PROTO(struct wiphy *wiphy, struct net_device *netdev,
+ struct cfg80211_external_auth_params *params),
+ TP_ARGS(wiphy, netdev, params),
+ TP_STRUCT__entry(WIPHY_ENTRY
+ NETDEV_ENTRY
+ MAC_ENTRY(bssid)
+ __array(u8, ssid, IEEE80211_MAX_SSID_LEN + 1)
+ __field(u16, status)
+ ),
+ TP_fast_assign(WIPHY_ASSIGN;
+ NETDEV_ASSIGN;
+ MAC_ASSIGN(bssid, params->bssid);
+ memset(__entry->ssid, 0, IEEE80211_MAX_SSID_LEN + 1);
+ memcpy(__entry->ssid, params->ssid.ssid,
+ params->ssid.ssid_len);
+ __entry->status = params->status;
+ ),
+ TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", bssid: " MAC_PR_FMT
+ ", ssid: %s, status: %u", WIPHY_PR_ARG, NETDEV_PR_ARG,
+ __entry->bssid, __entry->ssid, __entry->status)
+);
+#endif
+
/*************************************************************
* cfg80211 exported functions traces *
*************************************************************/