Cumulative patch from commit fcd85d9a3f2d9d63d0fa57e93446ad467db75b23

fcd85d9 Add QCA vendor commands/attributes for indoor location
d1723c5 wpa_supplicant: Allow FTM functionality to be published
faecb39 hostapd: Allow FTM functionality to be published
fc72a48 hostapd: Use stations nsts capability in (Re)Association Response frame
22950d0 QCA vendor subcommand for LL_STATS extension
b44d9c7 D-Bus: Add ConfigFile parameter into the interface properties
7dcec24 mka: Clean up key allocation
95e9460 mka: Get rid of struct ieee802_1x_cp_conf
07a6bfe mka: Store cipher suite ID in a u64 instead of u8 pointer
535a8b8 mka: Make csindex unsigned
343eb3b mka: Reorganize live peer creation and key server election
34dbe90 mka: Share a single delete mka implementation
0dabf79 mka: Introduce compare_priorities()
53080f7 mka: Clean up ieee802_1x_kay_mkpdu_sanity_check()
05283e7 mka: Simplify ieee802_1x_mka_dist_sak_body_present()
87b19c8 mka: Replace participant->kay with a local kay variable
f9ea083 mka: Fix typos in grammar in variable names and comments
921171f mka: Use named initializers for mka_body_handler[]
86bef17 mka: Remove unused enum mka_created_mode values
ec958ae mka: Remove cs_len argument from the set_current_cipher_suite functions
46bbda2 mka: Clean up ieee802_1x_mka_decode_potential_peer_body()
cf375eb mka: Simplify ieee802_1x_mka_encode_icv_body() memory copying
8b4a148 mka: Simplify ieee802_1x_mka_sak_use_body_present()
b3df783 mka: Reorganize loops in number of KaY functions
de7f533 mka: Remove unused body_peer incrementation
2b13bca mka: Add reset_participant_mi() helper
3ceb458 mka: Clean up printf formats
8fab9e1 mka: Use named initializers for static structs
d4f668f mka: Add MKA_ALIGN_LENGTH macro
1de7a9f mka: Add helper functions for dumping and creating peer
d9639d1 mka: Clean up ieee802_1x_kay_get_cipher_suite() lookup function
7c547cf mka: Refactor the get_*_peer() functions
515bc1a mka: Fix a typo in mka_body_handler (mak to mka)
a33e3c3 mka: Add a helper function, sci_equal(), for sci comparison
cefeb8e mka: Use less bitfields in the IEEE 802.1X-2010 structs
2e94489 mka: Fix a typo in macsec_capbility
f2f8616 Initialize hapd->nr_db in hostapd_alloc_bss_data()
30e0745 Fix TRACK_STA_LIST before BSS enabled
1f3b8b4 Check for driver initialization before doing driver operations
833d0d4 radius: Sanity check for NULL pointer segfault

Change-Id: I500fe4f62e1a0010ea82c277f73becd2ac2dfa43
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
index 64daf4c..8c8f7e2 100644
--- a/src/ap/ap_config.h
+++ b/src/ap/ap_config.h
@@ -582,6 +582,7 @@
 	u8 radio_measurements[RRM_CAPABILITIES_IE_LEN];
 
 	int vendor_vht;
+	int use_sta_nsts;
 
 	char *no_probe_resp_if_seen_on;
 	char *no_auth_if_seen_on;
@@ -591,6 +592,9 @@
 #ifdef CONFIG_MBO
 	int mbo_enabled;
 #endif /* CONFIG_MBO */
+
+	int ftm_responder;
+	int ftm_initiator;
 };
 
 
diff --git a/src/ap/ap_drv_ops.c b/src/ap/ap_drv_ops.c
index 532b72f..f139465 100644
--- a/src/ap/ap_drv_ops.c
+++ b/src/ap/ap_drv_ops.c
@@ -623,7 +623,7 @@
 int hostapd_drv_send_mlme(struct hostapd_data *hapd,
 			  const void *msg, size_t len, int noack)
 {
-	if (hapd->driver == NULL || hapd->driver->send_mlme == NULL)
+	if (!hapd->driver || !hapd->driver->send_mlme || !hapd->drv_priv)
 		return 0;
 	return hapd->driver->send_mlme(hapd->drv_priv, msg, len, noack, 0,
 				       NULL, 0);
@@ -644,7 +644,7 @@
 int hostapd_drv_sta_deauth(struct hostapd_data *hapd,
 			   const u8 *addr, int reason)
 {
-	if (hapd->driver == NULL || hapd->driver->sta_deauth == NULL)
+	if (!hapd->driver || !hapd->driver->sta_deauth || !hapd->drv_priv)
 		return 0;
 	return hapd->driver->sta_deauth(hapd->drv_priv, hapd->own_addr, addr,
 					reason);
@@ -654,7 +654,7 @@
 int hostapd_drv_sta_disassoc(struct hostapd_data *hapd,
 			     const u8 *addr, int reason)
 {
-	if (hapd->driver == NULL || hapd->driver->sta_disassoc == NULL)
+	if (!hapd->driver || !hapd->driver->sta_disassoc || !hapd->drv_priv)
 		return 0;
 	return hapd->driver->sta_disassoc(hapd->drv_priv, hapd->own_addr, addr,
 					  reason);
@@ -680,7 +680,7 @@
 		0xff, 0xff, 0xff, 0xff, 0xff, 0xff
 	};
 
-	if (hapd->driver == NULL || hapd->driver->send_action == NULL)
+	if (!hapd->driver || !hapd->driver->send_action || !hapd->drv_priv)
 		return 0;
 	bssid = hapd->own_addr;
 	if (!is_multicast_ether_addr(dst) &&
@@ -754,7 +754,7 @@
 int hostapd_drv_set_qos_map(struct hostapd_data *hapd,
 			    const u8 *qos_map_set, u8 qos_map_set_len)
 {
-	if (hapd->driver == NULL || hapd->driver->set_qos_map == NULL)
+	if (!hapd->driver || !hapd->driver->set_qos_map || !hapd->drv_priv)
 		return 0;
 	return hapd->driver->set_qos_map(hapd->drv_priv, qos_map_set,
 					 qos_map_set_len);
diff --git a/src/ap/ap_drv_ops.h b/src/ap/ap_drv_ops.h
index 6406d13..0bb7954 100644
--- a/src/ap/ap_drv_ops.h
+++ b/src/ap/ap_drv_ops.h
@@ -160,7 +160,7 @@
 static inline int hostapd_drv_sta_remove(struct hostapd_data *hapd,
 					 const u8 *addr)
 {
-	if (hapd->driver == NULL || hapd->driver->sta_remove == NULL)
+	if (!hapd->driver || !hapd->driver->sta_remove || !hapd->drv_priv)
 		return 0;
 	return hapd->driver->sta_remove(hapd->drv_priv, addr);
 }
@@ -283,7 +283,7 @@
 static inline int hostapd_drv_status(struct hostapd_data *hapd, char *buf,
 				     size_t buflen)
 {
-	if (hapd->driver == NULL || hapd->driver->status == NULL)
+	if (!hapd->driver || !hapd->driver->status || !hapd->drv_priv)
 		return -1;
 	return hapd->driver->status(hapd->drv_priv, buf, buflen);
 }
@@ -342,7 +342,7 @@
 
 static inline int hostapd_drv_stop_ap(struct hostapd_data *hapd)
 {
-	if (hapd->driver == NULL || hapd->driver->stop_ap == NULL)
+	if (!hapd->driver || !hapd->driver->stop_ap || !hapd->drv_priv)
 		return 0;
 	return hapd->driver->stop_ap(hapd->drv_priv);
 }
diff --git a/src/ap/beacon.c b/src/ap/beacon.c
index 0570ab7..202abe6 100644
--- a/src/ap/beacon.c
+++ b/src/ap/beacon.c
@@ -485,7 +485,7 @@
 
 #ifdef CONFIG_IEEE80211AC
 	if (hapd->iconf->ieee80211ac && !hapd->conf->disable_11ac) {
-		pos = hostapd_eid_vht_capabilities(hapd, pos);
+		pos = hostapd_eid_vht_capabilities(hapd, pos, 0);
 		pos = hostapd_eid_vht_operation(hapd, pos);
 		pos = hostapd_eid_txpower_envelope(hapd, pos);
 		pos = hostapd_eid_wb_chsw_wrapper(hapd, pos);
@@ -1105,7 +1105,7 @@
 
 #ifdef CONFIG_IEEE80211AC
 	if (hapd->iconf->ieee80211ac && !hapd->conf->disable_11ac) {
-		tailpos = hostapd_eid_vht_capabilities(hapd, tailpos);
+		tailpos = hostapd_eid_vht_capabilities(hapd, tailpos, 0);
 		tailpos = hostapd_eid_vht_operation(hapd, tailpos);
 		tailpos = hostapd_eid_txpower_envelope(hapd, tailpos);
 		tailpos = hostapd_eid_wb_chsw_wrapper(hapd, tailpos);
diff --git a/src/ap/ctrl_iface_ap.c b/src/ap/ctrl_iface_ap.c
index 17a3ea4..23c8c60 100644
--- a/src/ap/ctrl_iface_ap.c
+++ b/src/ap/ctrl_iface_ap.c
@@ -258,7 +258,7 @@
 	int ret;
 	u8 *pos;
 
-	if (hapd->driver->send_frame == NULL)
+	if (!hapd->drv_priv || !hapd->driver->send_frame)
 		return -1;
 
 	mgmt = os_zalloc(sizeof(*mgmt) + 100);
@@ -325,7 +325,7 @@
 	if (pos) {
 		struct ieee80211_mgmt mgmt;
 		int encrypt;
-		if (hapd->driver->send_frame == NULL)
+		if (!hapd->drv_priv || !hapd->driver->send_frame)
 			return -1;
 		pos += 6;
 		encrypt = atoi(pos);
@@ -388,7 +388,7 @@
 	if (pos) {
 		struct ieee80211_mgmt mgmt;
 		int encrypt;
-		if (hapd->driver->send_frame == NULL)
+		if (!hapd->drv_priv || !hapd->driver->send_frame)
 			return -1;
 		pos += 6;
 		encrypt = atoi(pos);
diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c
index 65f513d..a09d423 100644
--- a/src/ap/hostapd.c
+++ b/src/ap/hostapd.c
@@ -912,7 +912,6 @@
 		return -1;
 	}
 	hapd->started = 1;
-	dl_list_init(&hapd->nr_db);
 
 	if (!first || first == -1) {
 		u8 *addr = hapd->own_addr;
@@ -2002,6 +2001,7 @@
 	hapd->driver = hapd->iconf->driver;
 	hapd->ctrl_sock = -1;
 	dl_list_init(&hapd->ctrl_dst);
+	dl_list_init(&hapd->nr_db);
 
 	return hapd;
 }
diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c
index eed5483..2ecd78f 100644
--- a/src/ap/ieee802_11.c
+++ b/src/ap/ieee802_11.c
@@ -1944,7 +1944,23 @@
 
 #ifdef CONFIG_IEEE80211AC
 	if (hapd->iconf->ieee80211ac && !hapd->conf->disable_11ac) {
-		p = hostapd_eid_vht_capabilities(hapd, p);
+		u32 nsts = 0, sta_nsts;
+
+		if (hapd->conf->use_sta_nsts && sta->vht_capabilities) {
+			struct ieee80211_vht_capabilities *capa;
+
+			nsts = (hapd->iface->conf->vht_capab >>
+				VHT_CAP_BEAMFORMEE_STS_OFFSET) & 7;
+			capa = sta->vht_capabilities;
+			sta_nsts = (le_to_host32(capa->vht_capabilities_info) >>
+				    VHT_CAP_BEAMFORMEE_STS_OFFSET) & 7;
+
+			if (nsts < sta_nsts)
+				nsts = 0;
+			else
+				nsts = sta_nsts;
+		}
+		p = hostapd_eid_vht_capabilities(hapd, p, nsts);
 		p = hostapd_eid_vht_operation(hapd, p);
 	}
 #endif /* CONFIG_IEEE80211AC */
diff --git a/src/ap/ieee802_11.h b/src/ap/ieee802_11.h
index 71b3b49..0327dec 100644
--- a/src/ap/ieee802_11.h
+++ b/src/ap/ieee802_11.h
@@ -50,7 +50,7 @@
 u8 * hostapd_eid_ht_capabilities(struct hostapd_data *hapd, u8 *eid);
 u8 * hostapd_eid_ht_operation(struct hostapd_data *hapd, u8 *eid);
 u8 * hostapd_eid_secondary_channel(struct hostapd_data *hapd, u8 *eid);
-u8 * hostapd_eid_vht_capabilities(struct hostapd_data *hapd, u8 *eid);
+u8 * hostapd_eid_vht_capabilities(struct hostapd_data *hapd, u8 *eid, u32 nsts);
 u8 * hostapd_eid_vht_operation(struct hostapd_data *hapd, u8 *eid);
 u8 * hostapd_eid_vendor_vht(struct hostapd_data *hapd, u8 *eid);
 u8 * hostapd_eid_wb_chsw_wrapper(struct hostapd_data *hapd, u8 *eid);
diff --git a/src/ap/ieee802_11_shared.c b/src/ap/ieee802_11_shared.c
index af858f0..259413b 100644
--- a/src/ap/ieee802_11_shared.c
+++ b/src/ap/ieee802_11_shared.c
@@ -218,6 +218,12 @@
 		if (hapd->conf->ssid.utf8_ssid)
 			*pos |= 0x01; /* Bit 48 - UTF-8 SSID */
 		break;
+	case 8: /* Bits 64-71 */
+		if (hapd->conf->ftm_responder)
+			*pos |= 0x40; /* Bit 70 - FTM responder */
+		if (hapd->conf->ftm_initiator)
+			*pos |= 0x80; /* Bit 71 - FTM initiator */
+		break;
 	}
 }
 
@@ -237,6 +243,9 @@
 		len = 1;
 	if (len < 7 && hapd->conf->ssid.utf8_ssid)
 		len = 7;
+	if (len < 9 &&
+	    (hapd->conf->ftm_initiator || hapd->conf->ftm_responder))
+		len = 9;
 #ifdef CONFIG_WNM
 	if (len < 4)
 		len = 4;
diff --git a/src/ap/ieee802_11_vht.c b/src/ap/ieee802_11_vht.c
index 0841898..f30f63b 100644
--- a/src/ap/ieee802_11_vht.c
+++ b/src/ap/ieee802_11_vht.c
@@ -20,7 +20,7 @@
 #include "dfs.h"
 
 
-u8 * hostapd_eid_vht_capabilities(struct hostapd_data *hapd, u8 *eid)
+u8 * hostapd_eid_vht_capabilities(struct hostapd_data *hapd, u8 *eid, u32 nsts)
 {
 	struct ieee80211_vht_capabilities *cap;
 	struct hostapd_hw_modes *mode = hapd->iface->current_mode;
@@ -50,6 +50,18 @@
 	cap->vht_capabilities_info = host_to_le32(
 		hapd->iface->conf->vht_capab);
 
+	if (nsts != 0) {
+		u32 hapd_nsts;
+
+		hapd_nsts = le_to_host32(cap->vht_capabilities_info);
+		hapd_nsts = (hapd_nsts >> VHT_CAP_BEAMFORMEE_STS_OFFSET) & 7;
+		cap->vht_capabilities_info &=
+			~(host_to_le32(hapd_nsts <<
+				       VHT_CAP_BEAMFORMEE_STS_OFFSET));
+		cap->vht_capabilities_info |=
+			host_to_le32(nsts << VHT_CAP_BEAMFORMEE_STS_OFFSET);
+	}
+
 	/* Supported MCS set comes from hw */
 	os_memcpy(&cap->vht_supported_mcs_set, mode->vht_mcs_set, 8);
 
@@ -398,7 +410,7 @@
 	WPA_PUT_BE32(pos, (OUI_BROADCOM << 8) | VENDOR_VHT_TYPE);
 	pos += 4;
 	*pos++ = VENDOR_VHT_SUBTYPE;
-	pos = hostapd_eid_vht_capabilities(hapd, pos);
+	pos = hostapd_eid_vht_capabilities(hapd, pos, 0);
 	pos = hostapd_eid_vht_operation(hapd, pos);
 
 	return pos;
diff --git a/src/common/ieee802_1x_defs.h b/src/common/ieee802_1x_defs.h
index cc88caa..a0c1d1b 100644
--- a/src/common/ieee802_1x_defs.h
+++ b/src/common/ieee802_1x_defs.h
@@ -10,7 +10,7 @@
 #define IEEE802_1X_DEFS_H
 
 #define CS_ID_LEN		8
-#define CS_ID_GCM_AES_128	{0x00, 0x80, 0x02, 0x00, 0x01, 0x00, 0x00, 0x01}
+#define CS_ID_GCM_AES_128	0x0080020001000001ULL
 #define CS_NAME_GCM_AES_128	"GCM-AES-128"
 
 enum macsec_policy {
diff --git a/src/common/qca-vendor.h b/src/common/qca-vendor.h
index 2312b22..0f36e66 100644
--- a/src/common/qca-vendor.h
+++ b/src/common/qca-vendor.h
@@ -124,6 +124,61 @@
  *	capabilities are to be fetched and other
  *	enum qca_wlan_vendor_attr_get_hw_capability attributes to return the
  *	requested capabilities.
+ *
+ * @QCA_NL80211_VENDOR_SUBCMD_LL_STATS_EXT: Link layer statistics extension.
+ *	enum qca_wlan_vendor_attr_ll_stats_ext attributes are used with this
+ *	command and event.
+ *
+ * @QCA_NL80211_VENDOR_SUBCMD_LOC_GET_CAPA: Get capabilities for
+ *	indoor location features. Capabilities are reported in
+ *	QCA_WLAN_VENDOR_ATTR_LOC_CAPA.
+ *
+ * @QCA_NL80211_VENDOR_SUBCMD_FTM_START_SESSION: Start an FTM
+ *	(fine timing measurement) session with one or more peers.
+ *	Specify Session cookie in QCA_WLAN_VENDOR_ATTR_FTM_SESSION_COOKIE and
+ *	peer information in QCA_WLAN_VENDOR_ATTR_FTM_MEAS_PEERS.
+ *	On success, 0 or more QCA_NL80211_VENDOR_SUBCMD_FTM_MEAS_RESULT
+ *	events will be reported, followed by
+ *	QCA_NL80211_VENDOR_SUBCMD_FTM_SESSION_DONE event to indicate
+ *	end of session.
+ *	Refer to IEEE P802.11-REVmc/D7.0, 11.24.6
+ *
+ * @QCA_NL80211_VENDOR_SUBCMD_FTM_ABORT_SESSION: Abort a running session.
+ *	A QCA_NL80211_VENDOR_SUBCMD_FTM_SESSION_DONE will be reported with
+ *	status code indicating session was aborted.
+ *
+ * @QCA_NL80211_VENDOR_SUBCMD_FTM_MEAS_RESULT: Event with measurement
+ *	results for one peer. Results are reported in
+ *	QCA_WLAN_VENDOR_ATTR_FTM_MEAS_PEER_RESULTS.
+ *
+ * @QCA_NL80211_VENDOR_SUBCMD_FTM_SESSION_DONE: Event triggered when
+ *	FTM session is finished, either successfully or aborted by
+ *	request.
+ *
+ * @QCA_NL80211_VENDOR_SUBCMD_FTM_CFG_RESPONDER: Configure FTM responder
+ *	mode. QCA_WLAN_VENDOR_ATTR_FTM_RESPONDER_ENABLE specifies whether
+ *	to enable or disable the responder. LCI/LCR reports can be
+ *	configured with QCA_WLAN_VENDOR_ATTR_FTM_LCI and
+ *	QCA_WLAN_VENDOR_ATTR_FTM_LCR. Can be called multiple
+ *	times to update the LCI/LCR reports.
+ *
+ * @QCA_NL80211_VENDOR_SUBCMD_AOA_MEAS: Perform a standalone AOA (angle of
+ *	arrival) measurement with a single peer. Specify peer MAC address in
+ *	QCA_WLAN_VENDOR_ATTR_MAC_ADDR and measurement type in
+ *	QCA_WLAN_VENDOR_ATTR_AOA_TYPE. Measurement result is reported in
+ *	QCA_NL80211_VENDOR_SUBCMD_AOA_MEAS_RESULT event.
+ *
+ * @QCA_NL80211_VENDOR_SUBCMD_AOA_ABORT_MEAS: Abort an AOA measurement. Specify
+ *	peer MAC address in QCA_WLAN_VENDOR_ATTR_MAC_ADDR.
+ *
+ * @QCA_NL80211_VENDOR_SUBCMD_AOA_MEAS_RESULT: Event that reports
+ *	the AOA measurement result.
+ *	Peer MAC address reported in QCA_WLAN_VENDOR_ATTR_MAC_ADDR.
+ *	success/failure status is reported in
+ *	QCA_WLAN_VENDOR_ATTR_LOC_SESSION_STATUS.
+ *	Measurement data is reported in QCA_WLAN_VENDOR_ATTR_AOA_MEAS_RESULT.
+ *	The antenna array(s) used in the measurement are reported in
+ *	QCA_WLAN_VENDOR_ATTR_LOC_ANTENNA_ARRAY_MASK.
  */
 enum qca_nl80211_vendor_subcmds {
 	QCA_NL80211_VENDOR_SUBCMD_UNSPEC = 0,
@@ -211,6 +266,17 @@
 	QCA_NL80211_VENDOR_SUBCMD_SAP_CONDITIONAL_CHAN_SWITCH = 124,
 	QCA_NL80211_VENDOR_SUBCMD_GPIO_CONFIG_COMMAND = 125,
 	QCA_NL80211_VENDOR_SUBCMD_GET_HW_CAPABILITY = 126,
+	QCA_NL80211_VENDOR_SUBCMD_LL_STATS_EXT = 127,
+	/* FTM/indoor location subcommands */
+	QCA_NL80211_VENDOR_SUBCMD_LOC_GET_CAPA = 128,
+	QCA_NL80211_VENDOR_SUBCMD_FTM_START_SESSION = 129,
+	QCA_NL80211_VENDOR_SUBCMD_FTM_ABORT_SESSION = 130,
+	QCA_NL80211_VENDOR_SUBCMD_FTM_MEAS_RESULT = 131,
+	QCA_NL80211_VENDOR_SUBCMD_FTM_SESSION_DONE = 132,
+	QCA_NL80211_VENDOR_SUBCMD_FTM_CFG_RESPONDER = 133,
+	QCA_NL80211_VENDOR_SUBCMD_AOA_MEAS = 134,
+	QCA_NL80211_VENDOR_SUBCMD_AOA_ABORT_MEAS = 135,
+	QCA_NL80211_VENDOR_SUBCMD_AOA_MEAS_RESULT = 136,
 };
 
 
@@ -240,6 +306,77 @@
 	QCA_WLAN_VENDOR_ATTR_MAX_CONCURRENT_CHANNELS_5_0_BAND = 11,
 	/* Unsigned 32-bit value from enum qca_set_band. */
 	QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE = 12,
+	/* Dummy (NOP) attribute for 64 bit padding */
+	QCA_WLAN_VENDOR_ATTR_PAD = 13,
+	/* Unique FTM session cookie (Unsigned 64 bit). Specified in
+	 * QCA_NL80211_VENDOR_SUBCMD_FTM_START_SESSION. Reported in
+	 * the session in QCA_NL80211_VENDOR_SUBCMD_FTM_MEAS_RESULT and
+	 * QCA_NL80211_VENDOR_SUBCMD_FTM_SESSION_DONE.
+	 */
+	QCA_WLAN_VENDOR_ATTR_FTM_SESSION_COOKIE = 14,
+	/* Indoor location capabilities, returned by
+	 * QCA_NL80211_VENDOR_SUBCMD_LOC_GET_CAPA.
+	 * see enum qca_wlan_vendor_attr_loc_capa.
+	 */
+	QCA_WLAN_VENDOR_ATTR_LOC_CAPA = 15,
+	/* Array of nested attributes containing information about each peer
+	 * in FTM measurement session. See enum qca_wlan_vendor_attr_peer_info
+	 * for supported attributes for each peer.
+	 */
+	QCA_WLAN_VENDOR_ATTR_FTM_MEAS_PEERS = 16,
+	/* Array of nested attributes containing measurement results for
+	 * one or more peers, reported by the
+	 * QCA_NL80211_VENDOR_SUBCMD_FTM_MEAS_RESULT event.
+	 * See enum qca_wlan_vendor_attr_peer_result for list of supported
+	 * attributes.
+	 */
+	QCA_WLAN_VENDOR_ATTR_FTM_MEAS_PEER_RESULTS = 17,
+	/* Flag attribute for enabling or disabling responder functionality. */
+	QCA_WLAN_VENDOR_ATTR_FTM_RESPONDER_ENABLE = 18,
+	/* Used in the QCA_NL80211_VENDOR_SUBCMD_FTM_CFG_RESPONDER
+	 * command to specify the LCI report that will be sent by
+	 * the responder during a measurement exchange. The format is
+	 * defined in IEEE P802.11-REVmc/D7.0, 9.4.2.22.10.
+	 */
+	QCA_WLAN_VENDOR_ATTR_FTM_LCI = 19,
+	/* Used in the QCA_NL80211_VENDOR_SUBCMD_FTM_CFG_RESPONDER
+	 * command to specify the location civic report that will
+	 * be sent by the responder during a measurement exchange.
+	 * The format is defined in IEEE P802.11-REVmc/D7.0, 9.4.2.22.13.
+	 */
+	QCA_WLAN_VENDOR_ATTR_FTM_LCR = 20,
+	/* Session/measurement completion status code,
+	 * reported in QCA_NL80211_VENDOR_SUBCMD_FTM_SESSION_DONE and
+	 * QCA_NL80211_VENDOR_SUBCMD_AOA_MEAS_RESULT
+	 * see enum qca_vendor_attr_loc_session_status.
+	 */
+	QCA_WLAN_VENDOR_ATTR_LOC_SESSION_STATUS = 21,
+	/* Initial dialog token used by responder (0 if not specified),
+	 * unsigned 8 bit value.
+	 */
+	QCA_WLAN_VENDOR_ATTR_FTM_INITIAL_TOKEN = 22,
+	/* AOA measurement type. Requested in QCA_NL80211_VENDOR_SUBCMD_AOA_MEAS
+	 * and optionally in QCA_NL80211_VENDOR_SUBCMD_FTM_START_SESSION if
+	 * AOA measurements are needed as part of an FTM session.
+	 * Reported by QCA_NL80211_VENDOR_SUBCMD_AOA_MEAS_RESULT. See
+	 * enum qca_wlan_vendor_attr_aoa_type.
+	 */
+	QCA_WLAN_VENDOR_ATTR_AOA_TYPE = 23,
+	/* A bit mask (unsigned 32 bit value) of antenna arrays used
+	 * by indoor location measurements. Refers to the antenna
+	 * arrays described by QCA_VENDOR_ATTR_LOC_CAPA_ANTENNA_ARRAYS.
+	 */
+	QCA_WLAN_VENDOR_ATTR_LOC_ANTENNA_ARRAY_MASK = 24,
+	/* AOA measurement data. Its contents depends on the AOA measurement
+	 * type and antenna array mask:
+	 * QCA_WLAN_VENDOR_ATTR_AOA_TYPE_TOP_CIR_PHASE: array of U16 values,
+	 * phase of the strongest CIR path for each antenna in the measured
+	 * array(s).
+	 * QCA_WLAN_VENDOR_ATTR_AOA_TYPE_TOP_CIR_PHASE_AMP: array of 2 U16
+	 * values, phase and amplitude of the strongest CIR path for each
+	 * antenna in the measured array(s).
+	 */
+	QCA_WLAN_VENDOR_ATTR_AOA_MEAS_RESULT = 25,
 	/* keep last */
 	QCA_WLAN_VENDOR_ATTR_AFTER_LAST,
 	QCA_WLAN_VENDOR_ATTR_MAX	= QCA_WLAN_VENDOR_ATTR_AFTER_LAST - 1,
@@ -832,4 +969,352 @@
 	QCA_WLAN_VENDOR_ATTR_HW_CAPABILITY_AFTER_LAST - 1,
 };
 
+/**
+ * enum qca_wlan_vendor_attr_ll_stats_ext - Attributes for MAC layer monitoring
+ *    offload which is an extension for LL_STATS.
+ * @QCA_WLAN_VENDOR_ATTR_LL_STATS_CFG_PERIOD: Monitoring period. Unit in ms.
+ *    If MAC counters do not exceed the threshold, FW will report monitored
+ *    link layer counters periodically as this setting. The first report is
+ *    always triggered by this timer.
+ * @QCA_WLAN_VENDOR_ATTR_LL_STATS_CFG_THRESHOLD: It is a percentage (1-99).
+ *    For each MAC layer counter, FW holds two copies. One is the current value.
+ *    The other is the last report. Once a current counter's increment is larger
+ *    than the threshold, FW will indicate that counter to host even if the
+ *    monitoring timer does not expire.
+ * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_PEER_PS_CHG: Peer STA power state change
+ * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TID: TID of MSDU
+ * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_NUM_MSDU: Count of MSDU with the same
+ *    failure code.
+ * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_STATUS: TX failure code
+ *    1: TX packet discarded
+ *    2: No ACK
+ *    3: Postpone
+ */
+enum qca_wlan_vendor_attr_ll_stats_ext {
+	QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_INVALID = 0,
+
+	/* Attributes for configurations */
+	QCA_WLAN_VENDOR_ATTR_LL_STATS_CFG_PERIOD,
+	QCA_WLAN_VENDOR_ATTR_LL_STATS_CFG_THRESHOLD,
+
+	/* Attributes for events */
+	QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_PEER_PS_CHG,
+
+	/* TX failure event */
+	QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TID,
+	QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_NUM_MSDU,
+	QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_STATUS,
+
+	QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_LAST,
+	QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_MAX =
+		QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_LAST - 1
+};
+
+/* Attributes for FTM commands and events */
+
+/**
+ * enum qca_wlan_vendor_attr_loc_capa - Indoor location capabilities
+ *
+ * @QCA_WLAN_VENDOR_ATTR_LOC_CAPA_FLAGS: Various flags. See
+ *	enum qca_wlan_vendor_attr_loc_capa_flags.
+ * @QCA_WLAN_VENDOR_ATTR_FTM_CAPA_MAX_NUM_SESSIONS: Maximum number
+ *	of measurement sessions that can run concurrently.
+ *	Default is one session (no session concurrency).
+ * @QCA_WLAN_VENDOR_ATTR_FTM_CAPA_MAX_NUM_PEERS: The total number of unique
+ *	peers that are supported in running sessions. For example,
+ *	if the value is 8 and maximum number of sessions is 2, you can
+ *	have one session with 8 unique peers, or 2 sessions with 4 unique
+ *	peers each, and so on.
+ * @QCA_WLAN_VENDOR_ATTR_FTM_CAPA_MAX_NUM_BURSTS_EXP: Maximum number
+ *	of bursts per peer, as an exponent (2^value). Default is 0,
+ *	meaning no multi-burst support.
+ * @QCA_WLAN_VENDOR_ATTR_FTM_CAPA_MAX_MEAS_PER_BURST: Maximum number
+ *	of measurement exchanges allowed in a single burst.
+ * @QCA_WLAN_VENDOR_ATTR_AOA_CAPA_SUPPORTED_TYPES: Supported AOA measurement
+ *	types. A bit mask (unsigned 32 bit value), each bit corresponds
+ *	to an AOA type as defined by enum qca_vendor_attr_aoa_type.
+ */
+enum qca_wlan_vendor_attr_loc_capa {
+	QCA_WLAN_VENDOR_ATTR_LOC_CAPA_INVALID,
+	QCA_WLAN_VENDOR_ATTR_LOC_CAPA_FLAGS,
+	QCA_WLAN_VENDOR_ATTR_FTM_CAPA_MAX_NUM_SESSIONS,
+	QCA_WLAN_VENDOR_ATTR_FTM_CAPA_MAX_NUM_PEERS,
+	QCA_WLAN_VENDOR_ATTR_FTM_CAPA_MAX_NUM_BURSTS_EXP,
+	QCA_WLAN_VENDOR_ATTR_FTM_CAPA_MAX_MEAS_PER_BURST,
+	QCA_WLAN_VENDOR_ATTR_AOA_CAPA_SUPPORTED_TYPES,
+	/* keep last */
+	QCA_WLAN_VENDOR_ATTR_LOC_CAPA_AFTER_LAST,
+	QCA_WLAN_VENDOR_ATTR_LOC_CAPA_MAX =
+	QCA_WLAN_VENDOR_ATTR_LOC_CAPA_AFTER_LAST - 1,
+};
+
+/**
+ * enum qca_wlan_vendor_attr_loc_capa_flags: Indoor location capability flags
+ *
+ * @QCA_WLAN_VENDOR_ATTR_LOC_CAPA_FLAG_FTM_RESPONDER: Set if driver
+ *	can be configured as an FTM responder (for example, an AP that
+ *	services FTM requests). QCA_NL80211_VENDOR_SUBCMD_FTM_CFG_RESPONDER
+ *	will be supported if set.
+ * @QCA_WLAN_VENDOR_ATTR_LOC_CAPA_FLAG_FTM_INITIATOR: Set if driver
+ *	can run FTM sessions. QCA_NL80211_VENDOR_SUBCMD_FTM_START_SESSION
+ *	will be supported if set.
+* @QCA_WLAN_VENDOR_ATTR_LOC_CAPA_FLAG_ASAP: Set if FTM responder
+ *	supports immediate (ASAP) response.
+ * @QCA_WLAN_VENDOR_ATTR_LOC_CAPA_FLAG_AOA: Set if driver supports standalone
+ *	AOA measurement using QCA_NL80211_VENDOR_SUBCMD_AOA_MEAS.
+ * @QCA_WLAN_VENDOR_ATTR_LOC_CAPA_FLAG_AOA_IN_FTM: Set if driver supports
+ *	requesting AOA measurements as part of an FTM session.
+ */
+enum qca_wlan_vendor_attr_loc_capa_flags {
+	QCA_WLAN_VENDOR_ATTR_LOC_CAPA_FLAG_FTM_RESPONDER = 1 << 0,
+	QCA_WLAN_VENDOR_ATTR_LOC_CAPA_FLAG_FTM_INITIATOR = 1 << 1,
+	QCA_WLAN_VENDOR_ATTR_LOC_CAPA_FLAG_ASAP = 1 << 2,
+	QCA_WLAN_VENDOR_ATTR_LOC_CAPA_FLAG_AOA = 1 << 3,
+	QCA_WLAN_VENDOR_ATTR_LOC_CAPA_FLAG_AOA_IN_FTM = 1 << 4,
+};
+
+/**
+ * enum qca_wlan_vendor_attr_ftm_peer_info: Information about
+ *	a single peer in a measurement session.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_FTM_PEER_MAC_ADDR: The MAC address of the peer.
+ * @QCA_WLAN_VENDOR_ATTR_FTM_PEER_MEAS_FLAGS: Various flags related
+ *	to measurement. See enum qca_wlan_vendor_attr_ftm_peer_meas_flags.
+ * @QCA_WLAN_VENDOR_ATTR_FTM_PEER_MEAS_PARAM: Nested attribute of
+ *	FTM measurement parameters, as specified by IEEE P802.11-REVmc/D7.0
+ *	9.4.2.167. See enum qca_wlan_vendor_attr_ftm_meas_param for
+ *	list of supported attributes.
+ * @QCA_WLAN_VENDOR_ATTR_FTM_PEER_SECURE_TOKEN_ID: Initial token ID for
+ *	secure measurement.
+ * @QCA_WLAN_VENDOR_ATTR_FTM_PEER_AOA_BURST_PERIOD: Request AOA
+ *	measurement every <value> bursts. If 0 or not specified,
+ *	AOA measurements will be disabled for this peer.
+ */
+enum qca_wlan_vendor_attr_ftm_peer_info {
+	QCA_WLAN_VENDOR_ATTR_FTM_PEER_INVALID,
+	QCA_WLAN_VENDOR_ATTR_FTM_PEER_MAC_ADDR,
+	QCA_WLAN_VENDOR_ATTR_FTM_PEER_MEAS_FLAGS,
+	QCA_WLAN_VENDOR_ATTR_FTM_PEER_MEAS_PARAM,
+	QCA_WLAN_VENDOR_ATTR_FTM_PEER_SECURE_TOKEN_ID,
+	QCA_WLAN_VENDOR_ATTR_FTM_PEER_AOA_BURST_PERIOD,
+	/* keep last */
+	QCA_WLAN_VENDOR_ATTR_FTM_PEER_AFTER_LAST,
+	QCA_WLAN_VENDOR_ATTR_FTM_PEER_MAX =
+	QCA_WLAN_VENDOR_ATTR_FTM_PEER_AFTER_LAST - 1,
+};
+
+/**
+ * enum qca_wlan_vendor_attr_ftm_peer_meas_flags: Measurement request flags,
+ *	per-peer
+ *
+ * @QCA_WLAN_VENDOR_ATTR_FTM_PEER_MEAS_FLAG_ASAP: If set, request
+ *	immediate (ASAP) response from peer.
+ * @QCA_WLAN_VENDOR_ATTR_FTM_PEER_MEAS_FLAG_LCI: If set, request
+ *	LCI report from peer. The LCI report includes the absolute
+ *	location of the peer in "official" coordinates (similar to GPS).
+ *	See IEEE P802.11-REVmc/D7.0, 11.24.6.7 for more information.
+ * @QCA_WLAN_VENDOR_ATTR_FTM_PEER_MEAS_FLAG_LCR: If set, request
+ *	Location civic report from peer. The LCR includes the location
+ *	of the peer in free-form format. See IEEE P802.11-REVmc/D7.0,
+ *	11.24.6.7 for more information.
+ * @QCA_WLAN_VENDOR_ATTR_FTM_PEER_MEAS_FLAG_SECURE: If set,
+ *	request a secure measurement.
+ *	QCA_WLAN_VENDOR_ATTR_FTM_PEER_SECURE_TOKEN_ID must also be provided.
+ */
+enum qca_wlan_vendor_attr_ftm_peer_meas_flags {
+	QCA_WLAN_VENDOR_ATTR_FTM_PEER_MEAS_FLAG_ASAP	= 1 << 0,
+	QCA_WLAN_VENDOR_ATTR_FTM_PEER_MEAS_FLAG_LCI	= 1 << 1,
+	QCA_WLAN_VENDOR_ATTR_FTM_PEER_MEAS_FLAG_LCR	= 1 << 2,
+	QCA_WLAN_VENDOR_ATTR_FTM_PEER_MEAS_FLAG_SECURE	= 1 << 3,
+};
+
+/**
+ * enum qca_wlan_vendor_attr_ftm_meas_param: Measurement parameters
+ *
+ * @QCA_WLAN_VENDOR_ATTR_FTM_PARAM_MEAS_PER_BURST: Number of measurements
+ *	to perform in a single burst.
+ * @QCA_WLAN_VENDOR_ATTR_FTM_PARAM_NUM_BURSTS_EXP: Number of bursts to
+ *	perform, specified as an exponent (2^value).
+ * @QCA_WLAN_VENDOR_ATTR_FTM_PARAM_BURST_DURATION: Duration of burst
+ *	instance, as specified in IEEE P802.11-REVmc/D7.0, 9.4.2.167.
+ * @QCA_WLAN_VENDOR_ATTR_FTM_PARAM_BURST_PERIOD: Time between bursts,
+ *	as specified in IEEE P802.11-REVmc/D7.0, 9.4.2.167. Must
+ *	be larger than QCA_WLAN_VENDOR_ATTR_FTM_PARAM_BURST_DURATION.
+ */
+enum qca_wlan_vendor_attr_ftm_meas_param {
+	QCA_WLAN_VENDOR_ATTR_FTM_PARAM_INVALID,
+	QCA_WLAN_VENDOR_ATTR_FTM_PARAM_MEAS_PER_BURST,
+	QCA_WLAN_VENDOR_ATTR_FTM_PARAM_NUM_BURSTS_EXP,
+	QCA_WLAN_VENDOR_ATTR_FTM_PARAM_BURST_DURATION,
+	QCA_WLAN_VENDOR_ATTR_FTM_PARAM_BURST_PERIOD,
+	/* keep last */
+	QCA_WLAN_VENDOR_ATTR_FTM_PARAM_AFTER_LAST,
+	QCA_WLAN_VENDOR_ATTR_FTM_PARAM_MAX =
+	QCA_WLAN_VENDOR_ATTR_FTM_PARAM_AFTER_LAST - 1,
+};
+
+/**
+ * enum qca_wlan_vendor_attr_ftm_peer_result: Per-peer results
+ *
+ * @QCA_WLAN_VENDOR_ATTR_FTM_PEER_RES_MAC_ADDR: MAC address of the reported
+ *	 peer.
+ * @QCA_WLAN_VENDOR_ATTR_FTM_PEER_RES_STATUS: Status of measurement
+ *	request for this peer.
+ *	See enum qca_wlan_vendor_attr_ftm_peer_result_status.
+ * @QCA_WLAN_VENDOR_ATTR_FTM_PEER_RES_FLAGS: Various flags related
+ *	to measurement results for this peer.
+ *	See enum qca_wlan_vendor_attr_ftm_peer_result_flags.
+ * @QCA_WLAN_VENDOR_ATTR_FTM_PEER_RES_VALUE_SECONDS: Specified when
+ *	request failed and peer requested not to send an additional request
+ *	for this number of seconds.
+ * @QCA_WLAN_VENDOR_ATTR_FTM_PEER_RES_LCI: LCI report when received
+ *	from peer. In the format specified by IEEE P802.11-REVmc/D7.0,
+ *	9.4.2.22.10.
+ * @QCA_WLAN_VENDOR_ATTR_FTM_PEER_RES_LCR: Location civic report when
+ *	received from peer. In the format specified by IEEE P802.11-REVmc/D7.0,
+ *	9.4.2.22.13.
+ * @QCA_WLAN_VENDOR_ATTR_FTM_PEER_RES_MEAS_PARAMS: Reported when peer
+ *	overridden some measurement request parameters. See
+ *	enum qca_wlan_vendor_attr_ftm_meas_param.
+ * @QCA_WLAN_VENDOR_ATTR_FTM_PEER_RES_AOA_MEAS: AOA measurement
+ *	for this peer. Same contents as @QCA_WLAN_VENDOR_ATTR_AOA_MEAS_RESULT.
+ * @QCA_WLAN_VENDOR_ATTR_FTM_PEER_RES_MEAS: Array of measurement
+ *	results. Each entry is a nested attribute defined
+ *	by enum qca_wlan_vendor_attr_ftm_meas.
+ */
+enum qca_wlan_vendor_attr_ftm_peer_result {
+	QCA_WLAN_VENDOR_ATTR_FTM_PEER_RES_INVALID,
+	QCA_WLAN_VENDOR_ATTR_FTM_PEER_RES_MAC_ADDR,
+	QCA_WLAN_VENDOR_ATTR_FTM_PEER_RES_STATUS,
+	QCA_WLAN_VENDOR_ATTR_FTM_PEER_RES_FLAGS,
+	QCA_WLAN_VENDOR_ATTR_FTM_PEER_RES_VALUE_SECONDS,
+	QCA_WLAN_VENDOR_ATTR_FTM_PEER_RES_LCI,
+	QCA_WLAN_VENDOR_ATTR_FTM_PEER_RES_LCR,
+	QCA_WLAN_VENDOR_ATTR_FTM_PEER_RES_MEAS_PARAMS,
+	QCA_WLAN_VENDOR_ATTR_FTM_PEER_RES_AOA_MEAS,
+	QCA_WLAN_VENDOR_ATTR_FTM_PEER_RES_MEAS,
+	/* keep last */
+	QCA_WLAN_VENDOR_ATTR_FTM_PEER_RES_AFTER_LAST,
+	QCA_WLAN_VENDOR_ATTR_FTM_PEER_RES_MAX =
+	QCA_WLAN_VENDOR_ATTR_FTM_PEER_RES_AFTER_LAST - 1,
+};
+
+/**
+ * enum qca_wlan_vendor_attr_ftm_peer_result_status
+ *
+ * @QCA_WLAN_VENDOR_ATTR_FTM_PEER_RES_STATUS_OK: Request sent ok and results
+ *	will be provided. Peer may have overridden some measurement parameters,
+ *	in which case overridden parameters will be report by
+ *	QCA_WLAN_VENDOR_ATTR_FTM_PEER_RES_MEAS_PARAM attribute.
+ * @QCA_WLAN_VENDOR_ATTR_FTM_PEER_RES_STATUS_INCAPABLE: Peer is incapable
+ *	of performing the measurement request. No more results will be sent
+ *	for this peer in this session.
+ * @QCA_WLAN_VENDOR_ATTR_FTM_PEER_RES_STATUS_FAILED: Peer reported request
+ *	failed, and requested not to send an additional request for number
+ *	of seconds specified by QCA_WLAN_VENDOR_ATTR_FTM_PEER_RES_VALUE_SECONDS
+ *	attribute.
+ * @QCA_WLAN_VENDOR_ATTR_FTM_PEER_RES_STATUS_INVALID: Request validation
+ *	failed. Request was not sent over the air.
+ */
+enum qca_wlan_vendor_attr_ftm_peer_result_status {
+	QCA_WLAN_VENDOR_ATTR_FTM_PEER_RES_STATUS_OK,
+	QCA_WLAN_VENDOR_ATTR_FTM_PEER_RES_STATUS_INCAPABLE,
+	QCA_WLAN_VENDOR_ATTR_FTM_PEER_RES_STATUS_FAILED,
+	QCA_WLAN_VENDOR_ATTR_FTM_PEER_RES_STATUS_INVALID,
+};
+
+/**
+ * enum qca_wlan_vendor_attr_ftm_peer_result_flags: Various flags
+ *  for measurement result, per-peer
+ *
+ * @QCA_WLAN_VENDOR_ATTR_FTM_PEER_RES_FLAG_DONE: If set,
+ *	measurement completed for this peer. No more results will be reported
+ *	for this peer in this session.
+ */
+enum qca_wlan_vendor_attr_ftm_peer_result_flags {
+	QCA_WLAN_VENDOR_ATTR_FTM_PEER_RES_FLAG_DONE = 1 << 0,
+};
+
+/**
+ * enum qca_vendor_attr_loc_session_status: Session completion status code
+ *
+ * @QCA_WLAN_VENDOR_ATTR_LOC_SESSION_STATUS_OK: Session completed
+ *	successfully.
+ * @QCA_WLAN_VENDOR_ATTR_LOC_SESSION_STATUS_ABORTED: Session aborted
+ *	by request.
+ * @QCA_WLAN_VENDOR_ATTR_LOC_SESSION_STATUS_INVALID: Session request
+ *	was invalid and was not started.
+ * @QCA_WLAN_VENDOR_ATTR_LOC_SESSION_STATUS_FAILED: Session had an error
+ *	and did not complete normally (for example out of resources).
+ */
+enum qca_vendor_attr_loc_session_status {
+	QCA_WLAN_VENDOR_ATTR_LOC_SESSION_STATUS_OK,
+	QCA_WLAN_VENDOR_ATTR_LOC_SESSION_STATUS_ABORTED,
+	QCA_WLAN_VENDOR_ATTR_LOC_SESSION_STATUS_INVALID,
+	QCA_WLAN_VENDOR_ATTR_LOC_SESSION_STATUS_FAILED,
+};
+
+/**
+ * enum qca_wlan_vendor_attr_ftm_meas: Single measurement data
+ *
+ * @QCA_WLAN_VENDOR_ATTR_FTM_MEAS_T1: Time of departure (TOD) of FTM packet as
+ *	recorded by responder, in picoseconds.
+ *	See IEEE P802.11-REVmc/D7.0, 11.24.6.4 for more information.
+ * @QCA_WLAN_VENDOR_ATTR_FTM_MEAS_T2: Time of arrival (TOA) of FTM packet at
+ *	initiator, in picoseconds.
+ *	See IEEE P802.11-REVmc/D7.0, 11.24.6.4 for more information.
+ * @QCA_WLAN_VENDOR_ATTR_FTM_MEAS_T3: TOD of ACK packet as recorded by
+ *	initiator, in picoseconds.
+ *	See IEEE P802.11-REVmc/D7.0, 11.24.6.4 for more information.
+ * @QCA_WLAN_VENDOR_ATTR_FTM_MEAS_T4: TOA of ACK packet at
+ *	responder, in picoseconds.
+ *	See IEEE P802.11-REVmc/D7.0, 11.24.6.4 for more information.
+ * @QCA_WLAN_VENDOR_ATTR_FTM_MEAS_RSSI: RSSI (signal level) as recorded
+ *	during this measurement exchange. Optional and will be provided if
+ *	the hardware can measure it.
+ * @QCA_WLAN_VENDOR_ATTR_FTM_MEAS_TOD_ERR: TOD error reported by
+ *	responder. Not always provided.
+ *	See IEEE P802.11-REVmc/D7.0, 9.6.8.33 for more information.
+ * @QCA_WLAN_VENDOR_ATTR_FTM_MEAS_TOA_ERR: TOA error reported by
+ *	responder. Not always provided.
+ *	See IEEE P802.11-REVmc/D7.0, 9.6.8.33 for more information.
+ * @QCA_WLAN_VENDOR_ATTR_FTM_MEAS_INITIATOR_TOD_ERR: TOD error measured by
+ *	initiator. Not always provided.
+ *	See IEEE P802.11-REVmc/D7.0, 9.6.8.33 for more information.
+ * @QCA_WLAN_VENDOR_ATTR_FTM_MEAS_INITIATOR_TOA_ERR: TOA error measured by
+ *	initiator. Not always provided.
+ *	See IEEE P802.11-REVmc/D7.0, 9.6.8.33 for more information.
+ * @QCA_WLAN_VENDOR_ATTR_FTM_MEAS_PAD: Dummy attribute for padding.
+ */
+enum qca_wlan_vendor_attr_ftm_meas {
+	QCA_WLAN_VENDOR_ATTR_FTM_MEAS_T1,
+	QCA_WLAN_VENDOR_ATTR_FTM_MEAS_T2,
+	QCA_WLAN_VENDOR_ATTR_FTM_MEAS_T3,
+	QCA_WLAN_VENDOR_ATTR_FTM_MEAS_T4,
+	QCA_WLAN_VENDOR_ATTR_FTM_MEAS_RSSI,
+	QCA_WLAN_VENDOR_ATTR_FTM_MEAS_TOD_ERR,
+	QCA_WLAN_VENDOR_ATTR_FTM_MEAS_TOA_ERR,
+	QCA_WLAN_VENDOR_ATTR_FTM_MEAS_INITIATOR_TOD_ERR,
+	QCA_WLAN_VENDOR_ATTR_FTM_MEAS_INITIATOR_TOA_ERR,
+	QCA_WLAN_VENDOR_ATTR_FTM_MEAS_PAD,
+	/* keep last */
+	QCA_WLAN_VENDOR_ATTR_FTM_MEAS_AFTER_LAST,
+	QCA_WLAN_VENDOR_ATTR_FTM_MEAS_MAX =
+	QCA_WLAN_VENDOR_ATTR_FTM_MEAS_AFTER_LAST - 1,
+};
+
+/**
+ * enum qca_wlan_vendor_attr_aoa_type - AOA measurement type
+ *
+ * @QCA_WLAN_VENDOR_ATTR_AOA_TYPE_TOP_CIR_PHASE: Phase of the strongest
+ *	CIR (channel impulse response) path for each antenna.
+ * @QCA_WLAN_VENDOR_ATTR_AOA_TYPE_TOP_CIR_PHASE_AMP: Phase and amplitude
+ *	of the strongest CIR path for each antenna.
+ */
+enum qca_wlan_vendor_attr_aoa_type {
+	QCA_WLAN_VENDOR_ATTR_AOA_TYPE_TOP_CIR_PHASE,
+	QCA_WLAN_VENDOR_ATTR_AOA_TYPE_TOP_CIR_PHASE_AMP,
+	QCA_WLAN_VENDOR_ATTR_AOA_TYPE_MAX
+};
+
 #endif /* QCA_VENDOR_H */
diff --git a/src/drivers/driver.h b/src/drivers/driver.h
index a5c5c1b..a449cc9 100644
--- a/src/drivers/driver.h
+++ b/src/drivers/driver.h
@@ -3317,11 +3317,9 @@
 	 * set_current_cipher_suite - Set current cipher suite
 	 * @priv: Private driver interface data
 	 * @cs: EUI64 identifier
-	 * @cs_len: Length of the cs buffer in octets
 	 * Returns: 0 on success, -1 on failure (or if not supported)
 	 */
-	int (*set_current_cipher_suite)(void *priv, const u8 *cs,
-					size_t cs_len);
+	int (*set_current_cipher_suite)(void *priv, u64 cs);
 
 	/**
 	 * enable_controlled_port - Set controlled port status
diff --git a/src/drivers/driver_macsec_qca.c b/src/drivers/driver_macsec_qca.c
index 3eae2f8..826d3cc 100644
--- a/src/drivers/driver_macsec_qca.c
+++ b/src/drivers/driver_macsec_qca.c
@@ -11,6 +11,7 @@
 #include "includes.h"
 #include <sys/ioctl.h>
 #include <net/if.h>
+#include <inttypes.h>
 #ifdef __linux__
 #include <netpacket/packet.h>
 #include <net/if_arp.h>
@@ -485,15 +486,12 @@
 }
 
 
-static int macsec_qca_set_current_cipher_suite(void *priv, const u8 *cs,
-					       size_t cs_len)
+static int macsec_qca_set_current_cipher_suite(void *priv, u64 cs)
 {
-	u8 default_cs_id[] = CS_ID_GCM_AES_128;
-
-	if (cs_len != CS_ID_LEN ||
-	    os_memcmp(cs, default_cs_id, cs_len) != 0) {
-		wpa_hexdump(MSG_ERROR, "macsec: NOT supported CipherSuite",
-			    cs, cs_len);
+	if (cs != CS_ID_GCM_AES_128) {
+		wpa_printf(MSG_ERROR,
+			   "%s: NOT supported CipherSuite: %016" PRIx64,
+			   __func__, cs);
 		return -1;
 	}
 
diff --git a/src/pae/ieee802_1x_cp.c b/src/pae/ieee802_1x_cp.c
index cf43c59..e294e64 100644
--- a/src/pae/ieee802_1x_cp.c
+++ b/src/pae/ieee802_1x_cp.c
@@ -20,7 +20,7 @@
 #define STATE_MACHINE_DATA struct ieee802_1x_cp_sm
 #define STATE_MACHINE_DEBUG_PREFIX "CP"
 
-static u8 default_cs_id[] = CS_ID_GCM_AES_128;
+static u64 default_cs_id = CS_ID_GCM_AES_128;
 
 /* The variable defined in clause 12 in IEEE Std 802.1X-2010 */
 enum connect_type { PENDING, UNAUTHENTICATED, AUTHENTICATED, SECURE };
@@ -45,7 +45,7 @@
 	Boolean elected_self;
 	u8 *authorization_data1;
 	enum confidentiality_offset cipher_offset;
-	u8 *cipher_suite;
+	u64 cipher_suite;
 	Boolean new_sak; /* clear by CP */
 	struct ieee802_1x_mka_ki distributed_ki;
 	u8 distributed_an;
@@ -71,7 +71,7 @@
 	Boolean replay_protect;
 	u32 replay_window;
 
-	u8 *current_cipher_suite;
+	u64 current_cipher_suite;
 	enum confidentiality_offset confidentiality_offset;
 	Boolean controlled_port_enabled;
 
@@ -97,8 +97,7 @@
 static int changed_cipher(struct ieee802_1x_cp_sm *sm)
 {
 	return sm->confidentiality_offset != sm->cipher_offset ||
-		os_memcmp(sm->current_cipher_suite, sm->cipher_suite,
-			  CS_ID_LEN) != 0;
+		sm->current_cipher_suite != sm->cipher_suite;
 }
 
 
@@ -185,21 +184,17 @@
 
 SM_STATE(CP, SECURED)
 {
-	struct ieee802_1x_cp_conf conf;
-
 	SM_ENTRY(CP, SECURED);
 
 	sm->chgd_server = FALSE;
 
-	ieee802_1x_kay_cp_conf(sm->kay, &conf);
-	sm->protect_frames = conf.protect;
-	sm->replay_protect = conf.replay_protect;
-	sm->validate_frames = conf.validate;
+	sm->protect_frames = sm->kay->macsec_protect;
+	sm->replay_protect = sm->kay->macsec_replay_protect;
+	sm->validate_frames = sm->kay->macsec_validate;
 
-	/* NOTE: now no other than default cipher suiter(AES-GCM-128) */
-	os_memcpy(sm->current_cipher_suite, sm->cipher_suite, CS_ID_LEN);
-	secy_cp_control_current_cipher_suite(sm->kay, sm->current_cipher_suite,
-					     CS_ID_LEN);
+	/* NOTE: now no other than default cipher suite (AES-GCM-128) */
+	sm->current_cipher_suite = sm->cipher_suite;
+	secy_cp_control_current_cipher_suite(sm->kay, sm->current_cipher_suite);
 
 	sm->confidentiality_offset = sm->cipher_offset;
 
@@ -428,9 +423,7 @@
 /**
  * ieee802_1x_cp_sm_init -
  */
-struct ieee802_1x_cp_sm * ieee802_1x_cp_sm_init(
-	struct ieee802_1x_kay *kay,
-	struct ieee802_1x_cp_conf *pcp_conf)
+struct ieee802_1x_cp_sm * ieee802_1x_cp_sm_init(struct ieee802_1x_kay *kay)
 {
 	struct ieee802_1x_cp_sm *sm;
 
@@ -446,10 +439,10 @@
 
 	sm->chgd_server = FALSE;
 
-	sm->protect_frames = pcp_conf->protect;
-	sm->validate_frames = pcp_conf->validate;
-	sm->replay_protect = pcp_conf->replay_protect;
-	sm->replay_window = pcp_conf->replay_window;
+	sm->protect_frames = kay->macsec_protect;
+	sm->validate_frames = kay->macsec_validate;
+	sm->replay_protect = kay->macsec_replay_protect;
+	sm->replay_window = kay->macsec_replay_window;
 
 	sm->controlled_port_enabled = FALSE;
 
@@ -460,17 +453,8 @@
 	sm->orx = FALSE;
 	sm->otx = FALSE;
 
-	sm->cipher_suite = os_zalloc(CS_ID_LEN);
-	sm->current_cipher_suite = os_zalloc(CS_ID_LEN);
-	if (!sm->cipher_suite || !sm->current_cipher_suite) {
-		wpa_printf(MSG_ERROR, "CP-%s: out of memory", __func__);
-		os_free(sm->cipher_suite);
-		os_free(sm->current_cipher_suite);
-		os_free(sm);
-		return NULL;
-	}
-	os_memcpy(sm->current_cipher_suite, default_cs_id, CS_ID_LEN);
-	os_memcpy(sm->cipher_suite, default_cs_id, CS_ID_LEN);
+	sm->current_cipher_suite = default_cs_id;
+	sm->cipher_suite = default_cs_id;
 	sm->cipher_offset = CONFIDENTIALITY_OFFSET_0;
 	sm->confidentiality_offset = sm->cipher_offset;
 	sm->transmit_delay = MKA_LIFE_TIME;
@@ -530,8 +514,6 @@
 	eloop_cancel_timeout(ieee802_1x_cp_step_cb, sm, NULL);
 	os_free(sm->lki);
 	os_free(sm->oki);
-	os_free(sm->cipher_suite);
-	os_free(sm->current_cipher_suite);
 	os_free(sm->authorization_data);
 	os_free(sm);
 }
@@ -618,10 +600,10 @@
 /**
  * ieee802_1x_cp_set_ciphersuite -
  */
-void ieee802_1x_cp_set_ciphersuite(void *cp_ctx, void *pid)
+void ieee802_1x_cp_set_ciphersuite(void *cp_ctx, u64 cs)
 {
 	struct ieee802_1x_cp_sm *sm = cp_ctx;
-	os_memcpy(sm->cipher_suite, pid, CS_ID_LEN);
+	sm->cipher_suite = cs;
 }
 
 
diff --git a/src/pae/ieee802_1x_cp.h b/src/pae/ieee802_1x_cp.h
index 773c930..695629e 100644
--- a/src/pae/ieee802_1x_cp.h
+++ b/src/pae/ieee802_1x_cp.h
@@ -16,17 +16,7 @@
 struct ieee802_1x_kay;
 struct ieee802_1x_mka_ki;
 
-struct ieee802_1x_cp_conf {
-	Boolean protect;
-	Boolean replay_protect;
-	enum validate_frames validate;
-	u32 replay_window;
-};
-
-
-struct ieee802_1x_cp_sm *
-ieee802_1x_cp_sm_init(struct ieee802_1x_kay *kay,
-		      struct ieee802_1x_cp_conf *pcp_conf);
+struct ieee802_1x_cp_sm * ieee802_1x_cp_sm_init(struct ieee802_1x_kay *kay);
 void ieee802_1x_cp_sm_deinit(struct ieee802_1x_cp_sm *sm);
 void ieee802_1x_cp_sm_step(void *cp_ctx);
 void ieee802_1x_cp_connect_pending(void *cp_ctx);
@@ -36,7 +26,7 @@
 void ieee802_1x_cp_signal_chgdserver(void *cp_ctx);
 void ieee802_1x_cp_set_electedself(void *cp_ctx, Boolean status);
 void ieee802_1x_cp_set_authorizationdata(void *cp_ctx, u8 *pdata, int len);
-void ieee802_1x_cp_set_ciphersuite(void *cp_ctx, void *pid);
+void ieee802_1x_cp_set_ciphersuite(void *cp_ctx, u64 cs);
 void ieee802_1x_cp_set_offset(void *cp_ctx, enum confidentiality_offset offset);
 void ieee802_1x_cp_signal_newsak(void *cp_ctx);
 void ieee802_1x_cp_set_distributedki(void *cp_ctx,
diff --git a/src/pae/ieee802_1x_kay.c b/src/pae/ieee802_1x_kay.c
index dfc5870..a8e7efc 100644
--- a/src/pae/ieee802_1x_kay.c
+++ b/src/pae/ieee802_1x_kay.c
@@ -29,6 +29,8 @@
 
 #define PENDING_PN_EXHAUSTION 0xC0000000
 
+#define MKA_ALIGN_LENGTH(len) (((len) + 0x3) & ~0x3)
+
 /* IEEE Std 802.1X-2010, Table 9-1 - MKA Algorithm Agility */
 #define MKA_ALGO_AGILITY_2009 { 0x00, 0x80, 0xC2, 0x01 }
 static u8 mka_algo_agility[4] = MKA_ALGO_AGILITY_2009;
@@ -37,12 +39,11 @@
 static struct macsec_ciphersuite cipher_suite_tbl[] = {
 	/* GCM-AES-128 */
 	{
-		CS_ID_GCM_AES_128,
-		CS_NAME_GCM_AES_128,
-		MACSEC_CAP_INTEG_AND_CONF_0_30_50,
-		16,
-
-		0 /* index */
+		.id = CS_ID_GCM_AES_128,
+		.name = CS_NAME_GCM_AES_128,
+		.capable = MACSEC_CAP_INTEG_AND_CONF_0_30_50,
+		.sak_len = DEFAULT_SA_KEY_LEN,
+		.index = 0,
 	},
 };
 #define CS_TABLE_SIZE (ARRAY_SIZE(cipher_suite_tbl))
@@ -50,16 +51,21 @@
 
 static struct mka_alg mka_alg_tbl[] = {
 	{
-		MKA_ALGO_AGILITY_2009,
-		/* 128-bit CAK, KEK, ICK, ICV */
-		16, 16,	16, 16,
-		ieee802_1x_cak_128bits_aes_cmac,
-		ieee802_1x_ckn_128bits_aes_cmac,
-		ieee802_1x_kek_128bits_aes_cmac,
-		ieee802_1x_ick_128bits_aes_cmac,
-		ieee802_1x_icv_128bits_aes_cmac,
+		.parameter = MKA_ALGO_AGILITY_2009,
 
-		1, /* index */
+		/* 128-bit CAK, KEK, ICK, ICV */
+		.cak_len = DEFAULT_ICV_LEN,
+		.kek_len = DEFAULT_ICV_LEN,
+		.ick_len = DEFAULT_ICV_LEN,
+		.icv_len = DEFAULT_ICV_LEN,
+
+		.cak_trfm = ieee802_1x_cak_128bits_aes_cmac,
+		.ckn_trfm = ieee802_1x_ckn_128bits_aes_cmac,
+		.kek_trfm = ieee802_1x_kek_128bits_aes_cmac,
+		.ick_trfm = ieee802_1x_ick_128bits_aes_cmac,
+		.icv_hash = ieee802_1x_icv_128bits_aes_cmac,
+
+		.index = 1,
 	},
 };
 #define MKA_ALG_TABLE_SIZE (ARRAY_SIZE(mka_alg_tbl))
@@ -73,16 +79,6 @@
 }
 
 
-struct mka_param_body_handler {
-	int (*body_tx)(struct ieee802_1x_mka_participant *participant,
-		       struct wpabuf *buf);
-	int (*body_rx)(struct ieee802_1x_mka_participant *participant,
-		       const u8 *mka_msg, size_t msg_len);
-	int (*body_length)(struct ieee802_1x_mka_participant *participant);
-	Boolean (*body_present)(struct ieee802_1x_mka_participant *participant);
-};
-
-
 static void set_mka_param_body_len(void *body, unsigned int len)
 {
 	struct ieee802_1x_mka_hdr *hdr = body;
@@ -122,8 +118,8 @@
 	wpa_printf(MSG_DEBUG, "\tPriority......: %d", body->priority);
 	wpa_printf(MSG_DEBUG, "\tKeySvr........: %d", body->key_server);
 	wpa_printf(MSG_DEBUG, "\tMACSecDesired.: %d", body->macsec_desired);
-	wpa_printf(MSG_DEBUG, "\tMACSecCapable.: %d", body->macsec_capbility);
-	wpa_printf(MSG_DEBUG, "\tBody Length...: %d", (int) body_len);
+	wpa_printf(MSG_DEBUG, "\tMACSecCapable.: %d", body->macsec_capability);
+	wpa_printf(MSG_DEBUG, "\tBody Length...: %zu", body_len);
 	wpa_printf(MSG_DEBUG, "\tSCI MAC.......: " MACSTR,
 		   MAC2STR(body->actor_sci.addr));
 	wpa_printf(MSG_DEBUG, "\tSCI Port .....: %d",
@@ -156,10 +152,10 @@
 	body_len = get_mka_param_body_len(body);
 	if (body->type == MKA_LIVE_PEER_LIST) {
 		wpa_printf(MSG_DEBUG, "*** Live Peer List ***");
-		wpa_printf(MSG_DEBUG, "\tBody Length...: %d", (int) body_len);
+		wpa_printf(MSG_DEBUG, "\tBody Length...: %zu", body_len);
 	} else if (body->type == MKA_POTENTIAL_PEER_LIST) {
 		wpa_printf(MSG_DEBUG, "*** Potential Live Peer List ***");
-		wpa_printf(MSG_DEBUG, "\tBody Length...: %d", (int) body_len);
+		wpa_printf(MSG_DEBUG, "\tBody Length...: %zu", body_len);
 	}
 
 	for (i = 0; i < body_len; i += MI_LEN + sizeof(mn)) {
@@ -187,7 +183,7 @@
 	wpa_printf(MSG_INFO, "\tDistributed AN........: %d", body->dan);
 	wpa_printf(MSG_INFO, "\tConfidentiality Offset: %d",
 		   body->confid_offset);
-	wpa_printf(MSG_INFO, "\tBody Length...........: %d", (int) body_len);
+	wpa_printf(MSG_INFO, "\tBody Length...........: %zu", body_len);
 	if (!body_len)
 		return;
 
@@ -280,7 +276,7 @@
 			return participant;
 	}
 
-	wpa_printf(MSG_DEBUG, "KaY: principal participant is not founded");
+	wpa_printf(MSG_DEBUG, "KaY: principal participant is not found");
 	return NULL;
 }
 
@@ -300,52 +296,12 @@
 
 
 /**
- * ieee802_1x_kay_is_in_potential_peer
- */
-static Boolean
-ieee802_1x_kay_is_in_potential_peer(
-	struct ieee802_1x_mka_participant *participant, const u8 *mi)
-{
-	return get_peer_mi(&participant->potential_peers, mi) != NULL;
-}
-
-
-/**
- * ieee802_1x_kay_is_in_live_peer
- */
-static Boolean
-ieee802_1x_kay_is_in_live_peer(
-	struct ieee802_1x_mka_participant *participant, const u8 *mi)
-{
-	return get_peer_mi(&participant->live_peers, mi) != NULL;
-}
-
-
-/**
- * ieee802_1x_kay_is_in_peer
- */
-static Boolean
-ieee802_1x_kay_is_in_peer(struct ieee802_1x_mka_participant *participant,
-			  const u8 *mi)
-{
-	return ieee802_1x_kay_is_in_live_peer(participant, mi) ||
-		ieee802_1x_kay_is_in_potential_peer(participant, mi);
-}
-
-
-/**
- * ieee802_1x_kay_get_peer
+ * ieee802_1x_kay_get_potential_peer
  */
 static struct ieee802_1x_kay_peer *
-ieee802_1x_kay_get_peer(struct ieee802_1x_mka_participant *participant,
-			const u8 *mi)
+ieee802_1x_kay_get_potential_peer(
+	struct ieee802_1x_mka_participant *participant, const u8 *mi)
 {
-	struct ieee802_1x_kay_peer *peer;
-
-	peer = get_peer_mi(&participant->live_peers, mi);
-	if (peer)
-		return peer;
-
 	return get_peer_mi(&participant->potential_peers, mi);
 }
 
@@ -362,22 +318,71 @@
 
 
 /**
+ * ieee802_1x_kay_is_in_potential_peer
+ */
+static Boolean
+ieee802_1x_kay_is_in_potential_peer(
+	struct ieee802_1x_mka_participant *participant, const u8 *mi)
+{
+	return ieee802_1x_kay_get_potential_peer(participant, mi) != NULL;
+}
+
+
+/**
+ * ieee802_1x_kay_is_in_live_peer
+ */
+static Boolean
+ieee802_1x_kay_is_in_live_peer(
+	struct ieee802_1x_mka_participant *participant, const u8 *mi)
+{
+	return ieee802_1x_kay_get_live_peer(participant, mi) != NULL;
+}
+
+
+/**
+ * ieee802_1x_kay_get_peer
+ */
+static struct ieee802_1x_kay_peer *
+ieee802_1x_kay_get_peer(struct ieee802_1x_mka_participant *participant,
+			const u8 *mi)
+{
+	struct ieee802_1x_kay_peer *peer;
+
+	peer = ieee802_1x_kay_get_live_peer(participant, mi);
+	if (peer)
+		return peer;
+
+	return ieee802_1x_kay_get_potential_peer(participant, mi);
+}
+
+
+/**
  * ieee802_1x_kay_get_cipher_suite
  */
 static struct macsec_ciphersuite *
 ieee802_1x_kay_get_cipher_suite(struct ieee802_1x_mka_participant *participant,
-				u8 *cs_id)
+				const u8 *cs_id)
 {
 	unsigned int i;
+	u64 cs;
+	be64 _cs;
+
+	os_memcpy(&_cs, cs_id, CS_ID_LEN);
+	cs = be_to_host64(_cs);
 
 	for (i = 0; i < CS_TABLE_SIZE; i++) {
-		if (os_memcmp(cipher_suite_tbl[i].id, cs_id, CS_ID_LEN) == 0)
-			break;
+		if (cipher_suite_tbl[i].id == cs)
+			return &cipher_suite_tbl[i];
 	}
-	if (i >= CS_TABLE_SIZE)
-		return NULL;
 
-	return &cipher_suite_tbl[i];
+	return NULL;
+}
+
+
+static Boolean sci_equal(const struct ieee802_1x_mka_sci *a,
+			 const struct ieee802_1x_mka_sci *b)
+{
+	return os_memcmp(a, b, sizeof(struct ieee802_1x_mka_sci)) == 0;
 }
 
 
@@ -392,13 +397,13 @@
 
 	dl_list_for_each(peer, &participant->live_peers,
 			 struct ieee802_1x_kay_peer, list) {
-		if (os_memcmp(&peer->sci, sci, sizeof(peer->sci)) == 0)
+		if (sci_equal(&peer->sci, sci))
 			return peer;
 	}
 
 	dl_list_for_each(peer, &participant->potential_peers,
 			 struct ieee802_1x_kay_peer, list) {
-		if (os_memcmp(&peer->sci, sci, sizeof(peer->sci)) == 0)
+		if (sci_equal(&peer->sci, sci))
 			return peer;
 	}
 
@@ -435,8 +440,8 @@
 
 	dl_list_add(&psc->sa_list, &psa->list);
 	wpa_printf(MSG_DEBUG,
-		   "KaY: Create receive SA(AN: %d lowest_pn: %u of SC(channel: %d)",
-		   (int) an, lowest_pn, psc->channel);
+		   "KaY: Create receive SA(AN: %hhu lowest_pn: %u of SC(channel: %d)",
+		   an, lowest_pn, psc->channel);
 
 	return psa;
 }
@@ -449,8 +454,8 @@
 {
 	psa->pkey = NULL;
 	wpa_printf(MSG_DEBUG,
-		   "KaY: Delete receive SA(an: %d) of SC(channel: %d)",
-		   psa->an, psa->sc->channel);
+		   "KaY: Delete receive SA(an: %hhu) of SC",
+		   psa->an);
 	dl_list_del(&psa->list);
 	os_free(psa);
 }
@@ -509,19 +514,22 @@
 }
 
 
-/**
- * ieee802_1x_kay_create_live_peer
- */
+static void ieee802_1x_kay_dump_peer(struct ieee802_1x_kay_peer *peer)
+{
+	wpa_hexdump(MSG_DEBUG, "\tMI: ", peer->mi, sizeof(peer->mi));
+	wpa_printf(MSG_DEBUG, "\tMN: %d", peer->mn);
+	wpa_hexdump(MSG_DEBUG, "\tSCI Addr: ", peer->sci.addr, ETH_ALEN);
+	wpa_printf(MSG_DEBUG, "\tPort: %d", peer->sci.port);
+}
+
+
 static struct ieee802_1x_kay_peer *
-ieee802_1x_kay_create_live_peer(struct ieee802_1x_mka_participant *participant,
-				u8 *mi, u32 mn)
+ieee802_1x_kay_create_peer(const u8 *mi, u32 mn)
 {
 	struct ieee802_1x_kay_peer *peer;
-	struct receive_sc *rxsc;
-	u32 sc_ch = 0;
 
 	peer = os_zalloc(sizeof(*peer));
-	if (peer == NULL) {
+	if (!peer) {
 		wpa_printf(MSG_ERROR, "KaY-%s: out of memory", __func__);
 		return NULL;
 	}
@@ -530,6 +538,26 @@
 	peer->mn = mn;
 	peer->expire = time(NULL) + MKA_LIFE_TIME / 1000;
 	peer->sak_used = FALSE;
+
+	return peer;
+}
+
+
+/**
+ * ieee802_1x_kay_create_live_peer
+ */
+static struct ieee802_1x_kay_peer *
+ieee802_1x_kay_create_live_peer(struct ieee802_1x_mka_participant *participant,
+				const u8 *mi, u32 mn)
+{
+	struct ieee802_1x_kay_peer *peer;
+	struct receive_sc *rxsc;
+	u32 sc_ch = 0;
+
+	peer = ieee802_1x_kay_create_peer(mi, mn);
+	if (!peer)
+		return NULL;
+
 	os_memcpy(&peer->sci, &participant->current_peer_sci,
 		  sizeof(peer->sci));
 
@@ -546,10 +574,7 @@
 	secy_create_receive_sc(participant->kay, rxsc);
 
 	wpa_printf(MSG_DEBUG, "KaY: Live peer created");
-	wpa_hexdump(MSG_DEBUG, "\tMI: ", peer->mi, sizeof(peer->mi));
-	wpa_printf(MSG_DEBUG, "\tMN: %d", peer->mn);
-	wpa_hexdump(MSG_DEBUG, "\tSCI Addr: ", peer->sci.addr, ETH_ALEN);
-	wpa_printf(MSG_DEBUG, "\tPort: %d", peer->sci.port);
+	ieee802_1x_kay_dump_peer(peer);
 
 	return peer;
 }
@@ -564,24 +589,14 @@
 {
 	struct ieee802_1x_kay_peer *peer;
 
-	peer = os_zalloc(sizeof(*peer));
-	if (peer == NULL) {
-		wpa_printf(MSG_ERROR, "KaY-%s: out of memory", __func__);
+	peer = ieee802_1x_kay_create_peer(mi, mn);
+	if (!peer)
 		return NULL;
-	}
-
-	os_memcpy(peer->mi, mi, MI_LEN);
-	peer->mn = mn;
-	peer->expire = time(NULL) + MKA_LIFE_TIME / 1000;
-	peer->sak_used = FALSE;
 
 	dl_list_add(&participant->potential_peers, &peer->list);
 
 	wpa_printf(MSG_DEBUG, "KaY: potential peer created");
-	wpa_hexdump(MSG_DEBUG, "\tMI: ", peer->mi, sizeof(peer->mi));
-	wpa_printf(MSG_DEBUG, "\tMN: %d", peer->mn);
-	wpa_hexdump(MSG_DEBUG, "\tSCI Addr: ", peer->sci.addr, ETH_ALEN);
-	wpa_printf(MSG_DEBUG, "\tPort: %d", peer->sci.port);
+	ieee802_1x_kay_dump_peer(peer);
 
 	return peer;
 }
@@ -598,11 +613,7 @@
 	struct receive_sc *rxsc;
 	u32 sc_ch = 0;
 
-	dl_list_for_each(peer, &participant->potential_peers,
-			 struct ieee802_1x_kay_peer, list) {
-		if (os_memcmp(peer->mi, mi, MI_LEN) == 0)
-			break;
-	}
+	peer = ieee802_1x_kay_get_potential_peer(participant, mi);
 
 	rxsc = ieee802_1x_kay_init_receive_sc(&participant->current_peer_sci,
 					      sc_ch);
@@ -615,10 +626,7 @@
 	peer->expire = time(NULL) + MKA_LIFE_TIME / 1000;
 
 	wpa_printf(MSG_DEBUG, "KaY: move potential peer to live peer");
-	wpa_hexdump(MSG_DEBUG, "\tMI: ", peer->mi, sizeof(peer->mi));
-	wpa_printf(MSG_DEBUG, "\tMN: %d", peer->mn);
-	wpa_hexdump(MSG_DEBUG, "\tSCI Addr: ", peer->sci.addr, ETH_ALEN);
-	wpa_printf(MSG_DEBUG, "\tPort: %d", peer->sci.port);
+	ieee802_1x_kay_dump_peer(peer);
 
 	dl_list_del(&peer->list);
 	dl_list_add_tail(&participant->live_peers, &peer->list);
@@ -654,7 +662,7 @@
 
 	length = sizeof(struct ieee802_1x_mka_basic_body);
 	length += participant->ckn.len;
-	return (length + 0x3) & ~0x3;
+	return MKA_ALIGN_LENGTH(length);
 }
 
 
@@ -680,7 +688,7 @@
 		body->key_server = participant->can_be_key_server;
 
 	body->macsec_desired = kay->macsec_desired;
-	body->macsec_capbility = kay->macsec_capable;
+	body->macsec_capability = kay->macsec_capable;
 	set_mka_param_body_len(body, length - MKA_HDR_LEN);
 
 	os_memcpy(body->actor_sci.addr, kay->actor_sci.addr,
@@ -690,7 +698,7 @@
 	os_memcpy(body->actor_mi, participant->mi, sizeof(body->actor_mi));
 	participant->mn = participant->mn + 1;
 	body->actor_mn = host_to_be32(participant->mn);
-	os_memcpy(body->algo_agility, participant->kay->algo_agility,
+	os_memcpy(body->algo_agility, kay->algo_agility,
 		  sizeof(body->algo_agility));
 
 	os_memcpy(body->ckn, participant->ckn.name, participant->ckn.len);
@@ -701,6 +709,17 @@
 }
 
 
+static Boolean
+reset_participant_mi(struct ieee802_1x_mka_participant *participant)
+{
+	if (os_get_random(participant->mi, sizeof(participant->mi)) < 0)
+		return FALSE;
+	participant->mn = 0;
+
+	return TRUE;
+}
+
+
 /**
  * ieee802_1x_mka_decode_basic_body -
  */
@@ -732,9 +751,8 @@
 
 	/* If the peer's MI is my MI, I will choose new MI */
 	if (os_memcmp(body->actor_mi, participant->mi, MI_LEN) == 0) {
-		if (os_get_random(participant->mi, sizeof(participant->mi)) < 0)
+		if (!reset_participant_mi(participant))
 			return NULL;
-		participant->mn = 0;
 	}
 
 	os_memcpy(participant->current_peer_id.mi, body->actor_mi, MI_LEN);
@@ -766,14 +784,14 @@
 			return NULL;
 
 		peer->macsec_desired = body->macsec_desired;
-		peer->macsec_capbility = body->macsec_capbility;
+		peer->macsec_capability = body->macsec_capability;
 		peer->is_key_server = (Boolean) body->key_server;
 		peer->key_server_priority = body->priority;
 	} else if (peer->mn < be_to_host32(body->actor_mn)) {
 		peer->mn = be_to_host32(body->actor_mn);
 		peer->expire = time(NULL) + MKA_LIFE_TIME / 1000;
 		peer->macsec_desired = body->macsec_desired;
-		peer->macsec_capbility = body->macsec_capbility;
+		peer->macsec_capability = body->macsec_capability;
 		peer->is_key_server = (Boolean) body->key_server;
 		peer->key_server_priority = body->priority;
 	} else {
@@ -810,7 +828,7 @@
 			 struct ieee802_1x_kay_peer, list)
 		len += sizeof(struct ieee802_1x_mka_peer_id);
 
-	return (len + 0x3) & ~0x3;
+	return MKA_ALIGN_LENGTH(len);
 }
 
 
@@ -839,7 +857,6 @@
 				       sizeof(struct ieee802_1x_mka_peer_id));
 		os_memcpy(body_peer->mi, peer->mi, MI_LEN);
 		body_peer->mn = host_to_be32(peer->mn);
-		body_peer++;
 	}
 
 	ieee802_1x_mka_dump_peer_body(body);
@@ -871,7 +888,7 @@
 			 struct ieee802_1x_kay_peer, list)
 		len += sizeof(struct ieee802_1x_mka_peer_id);
 
-	return (len + 0x3) & ~0x3;
+	return MKA_ALIGN_LENGTH(len);
 }
 
 
@@ -900,7 +917,6 @@
 				       sizeof(struct ieee802_1x_mka_peer_id));
 		os_memcpy(body_peer->mi, peer->mi, MI_LEN);
 		body_peer->mn = host_to_be32(peer->mn);
-		body_peer++;
 	}
 
 	ieee802_1x_mka_dump_peer_body(body);
@@ -915,64 +931,54 @@
 ieee802_1x_mka_i_in_peerlist(struct ieee802_1x_mka_participant *participant,
 			     const u8 *mka_msg, size_t msg_len)
 {
-	Boolean included = FALSE;
 	struct ieee802_1x_mka_hdr *hdr;
 	size_t body_len;
 	size_t left_len;
 	u8 body_type;
-	u32 peer_mn;
-	be32 _peer_mn;
-	const u8 *peer_mi;
 	const u8 *pos;
 	size_t i;
 
-	pos = mka_msg;
-	left_len = msg_len;
-	while (left_len > (MKA_HDR_LEN + DEFAULT_ICV_LEN)) {
+	for (pos = mka_msg, left_len = msg_len;
+	     left_len > MKA_HDR_LEN + DEFAULT_ICV_LEN;
+	     left_len -= body_len + MKA_HDR_LEN,
+		     pos += body_len + MKA_HDR_LEN) {
 		hdr = (struct ieee802_1x_mka_hdr *) pos;
 		body_len = get_mka_param_body_len(hdr);
 		body_type = get_mka_param_body_type(hdr);
 
 		if (body_type != MKA_LIVE_PEER_LIST &&
 		    body_type != MKA_POTENTIAL_PEER_LIST)
-			goto SKIP_PEER;
+			continue;
 
 		ieee802_1x_mka_dump_peer_body(
 			(struct ieee802_1x_mka_peer_body *)pos);
 
 		if (left_len < (MKA_HDR_LEN + body_len + DEFAULT_ICV_LEN)) {
 			wpa_printf(MSG_ERROR,
-				   "KaY: MKA Peer Packet Body Length (%d bytes) is less than the Parameter Set Header Length (%d bytes) + the Parameter Set Body Length (%d bytes) + %d bytes of ICV",
-				   (int) left_len, (int) MKA_HDR_LEN,
-				   (int) body_len, DEFAULT_ICV_LEN);
-			goto SKIP_PEER;
+				   "KaY: MKA Peer Packet Body Length (%zu bytes) is less than the Parameter Set Header Length (%zu bytes) + the Parameter Set Body Length (%zu bytes) + %d bytes of ICV",
+				   left_len, MKA_HDR_LEN,
+				   body_len, DEFAULT_ICV_LEN);
+			continue;
 		}
 
 		if ((body_len % 16) != 0) {
 			wpa_printf(MSG_ERROR,
-				   "KaY: MKA Peer Packet Body Length (%d bytes) should multiple of 16 octets",
-				   (int) body_len);
-			goto SKIP_PEER;
+				   "KaY: MKA Peer Packet Body Length (%zu bytes) should be a multiple of 16 octets",
+				   body_len);
+			continue;
 		}
 
-		for (i = 0; i < body_len; i += MI_LEN + sizeof(peer_mn)) {
-			peer_mi = MKA_HDR_LEN + pos + i;
-			os_memcpy(&_peer_mn, peer_mi + MI_LEN,
-				  sizeof(_peer_mn));
-			peer_mn = be_to_host32(_peer_mn);
-			if (os_memcmp(peer_mi, participant->mi, MI_LEN) == 0 &&
-			    peer_mn == participant->mn) {
-				included = TRUE;
-				break;
-			}
+		for (i = 0; i < body_len;
+		     i += sizeof(struct ieee802_1x_mka_peer_id)) {
+			const struct ieee802_1x_mka_peer_id *peer_mi;
+
+			peer_mi = (const struct ieee802_1x_mka_peer_id *)
+				(pos + MKA_HDR_LEN + i);
+			if (os_memcmp(peer_mi->mi, participant->mi,
+				      MI_LEN) == 0 &&
+			    be_to_host32(peer_mi->mn) == participant->mn)
+				return TRUE;
 		}
-
-		if (included)
-			return TRUE;
-
-SKIP_PEER:
-		left_len -= body_len + MKA_HDR_LEN;
-		pos += body_len + MKA_HDR_LEN;
 	}
 
 	return FALSE;
@@ -989,9 +995,6 @@
 	const struct ieee802_1x_mka_hdr *hdr;
 	struct ieee802_1x_kay_peer *peer;
 	size_t body_len;
-	u32 peer_mn;
-	be32 _peer_mn;
-	const u8 *peer_mi;
 	size_t i;
 	Boolean is_included;
 
@@ -1007,35 +1010,33 @@
 		return -1;
 	}
 
-	for (i = 0; i < body_len; i += MI_LEN + sizeof(peer_mn)) {
-		peer_mi = MKA_HDR_LEN + peer_msg + i;
-		os_memcpy(&_peer_mn, peer_mi + MI_LEN, sizeof(_peer_mn));
-		peer_mn = be_to_host32(_peer_mn);
+	for (i = 0; i < body_len; i += sizeof(struct ieee802_1x_mka_peer_id)) {
+		const struct ieee802_1x_mka_peer_id *peer_mi;
+		u32 peer_mn;
+
+		peer_mi = (const struct ieee802_1x_mka_peer_id *)
+			(peer_msg + MKA_HDR_LEN + i);
+		peer_mn = be_to_host32(peer_mi->mn);
 
 		/* it is myself */
 		if (os_memcmp(peer_mi, participant->mi, MI_LEN) == 0) {
 			/* My message id is used by other participant */
-			if (peer_mn > participant->mn) {
-				if (os_get_random(participant->mi,
-						  sizeof(participant->mi)) < 0)
-					wpa_printf(MSG_DEBUG,
-						   "KaY: Could not update mi");
-				participant->mn = 0;
-			}
+			if (peer_mn > participant->mn &&
+			    !reset_participant_mi(participant))
+				wpa_printf(MSG_DEBUG, "KaY: Could not update mi");
 			continue;
 		}
+
 		if (!is_included)
 			continue;
 
-		peer = ieee802_1x_kay_get_peer(participant, peer_mi);
-		if (NULL != peer) {
+		peer = ieee802_1x_kay_get_peer(participant, peer_mi->mi);
+		if (peer) {
 			peer->mn = peer_mn;
 			peer->expire = time(NULL) + MKA_LIFE_TIME / 1000;
-		} else {
-			if (!ieee802_1x_kay_create_potential_peer(
-				participant, peer_mi, peer_mn)) {
-				return -1;
-			}
+		} else if (!ieee802_1x_kay_create_potential_peer(
+				participant, peer_mi->mi, peer_mn)) {
+			return -1;
 		}
 	}
 
@@ -1051,14 +1052,11 @@
 	struct ieee802_1x_mka_participant *participant,
 	const u8 *peer_msg, size_t msg_len)
 {
-	struct ieee802_1x_mka_hdr *hdr;
+	const struct ieee802_1x_mka_hdr *hdr;
 	size_t body_len;
-	u32 peer_mn;
-	be32 _peer_mn;
-	const u8 *peer_mi;
 	size_t i;
 
-	hdr = (struct ieee802_1x_mka_hdr *) peer_msg;
+	hdr = (const struct ieee802_1x_mka_hdr *) peer_msg;
 	body_len = get_mka_param_body_len(hdr);
 	if (body_len % 16 != 0) {
 		wpa_printf(MSG_ERROR,
@@ -1067,21 +1065,20 @@
 		return -1;
 	}
 
-	for (i = 0; i < body_len; i += MI_LEN + sizeof(peer_mn)) {
-		peer_mi = MKA_HDR_LEN + peer_msg + i;
-		os_memcpy(&_peer_mn, peer_mi + MI_LEN, sizeof(_peer_mn));
-		peer_mn = be_to_host32(_peer_mn);
+	for (i = 0; i < body_len; i += sizeof(struct ieee802_1x_mka_peer_id)) {
+		const struct ieee802_1x_mka_peer_id *peer_mi;
+		u32 peer_mn;
+
+		peer_mi = (struct ieee802_1x_mka_peer_id *)
+			(peer_msg + MKA_HDR_LEN + i);
+		peer_mn = be_to_host32(peer_mi->mn);
 
 		/* it is myself */
 		if (os_memcmp(peer_mi, participant->mi, MI_LEN) == 0) {
 			/* My message id is used by other participant */
-			if (peer_mn > participant->mn) {
-				if (os_get_random(participant->mi,
-						  sizeof(participant->mi)) < 0)
-					wpa_printf(MSG_DEBUG,
-						   "KaY: Could not update mi");
-				participant->mn = 0;
-			}
+			if (peer_mn > participant->mn &&
+			    !reset_participant_mi(participant))
+				wpa_printf(MSG_DEBUG, "KaY: Could not update mi");
 			continue;
 		}
 	}
@@ -1097,10 +1094,7 @@
 ieee802_1x_mka_sak_use_body_present(
 	struct ieee802_1x_mka_participant *participant)
 {
-	if (participant->to_use_sak)
-		return TRUE;
-	else
-		return FALSE;
+	return participant->to_use_sak;
 }
 
 
@@ -1115,12 +1109,8 @@
 
 	if (participant->kay->macsec_desired && participant->advised_desired)
 		length = sizeof(struct ieee802_1x_mka_sak_use_body);
-	else
-		length = MKA_HDR_LEN;
 
-	length = (length + 0x3) & ~0x3;
-
-	return length;
+	return MKA_ALIGN_LENGTH(length);
 }
 
 
@@ -1165,6 +1155,7 @@
 	struct wpabuf *buf)
 {
 	struct ieee802_1x_mka_sak_use_body *body;
+	struct ieee802_1x_kay *kay = participant->kay;
 	unsigned int length;
 	u32 pn = 1;
 
@@ -1185,9 +1176,9 @@
 	}
 
 	/* data protect, lowest accept packet number */
-	body->delay_protect = participant->kay->macsec_replay_protect;
+	body->delay_protect = kay->macsec_replay_protect;
 	pn = ieee802_1x_mka_get_lpn(participant, &participant->lki);
-	if (pn > participant->kay->pn_exhaustion) {
+	if (pn > kay->pn_exhaustion) {
 		wpa_printf(MSG_WARNING, "KaY: My LPN exhaustion");
 		if (participant->is_key_server)
 			participant->new_sak = TRUE;
@@ -1198,20 +1189,12 @@
 	body->olpn = host_to_be32(pn);
 
 	/* plain tx, plain rx */
-	if (participant->kay->macsec_protect)
-		body->ptx = FALSE;
-	else
-		body->ptx = TRUE;
-
-	if (participant->kay->macsec_validate == Strict)
-		body->prx = FALSE;
-	else
-		body->prx = TRUE;
+	body->ptx = !kay->macsec_protect;
+	body->prx = kay->macsec_validate != Strict;
 
 	/* latest key: rx, tx, key server member identifier key number */
 	body->lan = participant->lan;
-	os_memcpy(body->lsrv_mi, participant->lki.mi,
-		  sizeof(body->lsrv_mi));
+	os_memcpy(body->lsrv_mi, participant->lki.mi, sizeof(body->lsrv_mi));
 	body->lkn = host_to_be32(participant->lki.kn);
 	body->lrx = participant->lrx;
 	body->ltx = participant->ltx;
@@ -1232,16 +1215,11 @@
 
 	/* set CP's variable */
 	if (body->ltx) {
-		if (!participant->kay->tx_enable)
-			participant->kay->tx_enable = TRUE;
-
-		if (!participant->kay->port_enable)
-			participant->kay->port_enable = TRUE;
+		kay->tx_enable = TRUE;
+		kay->port_enable = TRUE;
 	}
-	if (body->lrx) {
-		if (!participant->kay->rx_enable)
-			participant->kay->rx_enable = TRUE;
-	}
+	if (body->lrx)
+		kay->rx_enable = TRUE;
 
 	ieee802_1x_mka_dump_sak_use_body(body);
 	return 0;
@@ -1265,7 +1243,8 @@
 	struct ieee802_1x_mka_ki ki;
 	u32 lpn;
 	Boolean all_receiving;
-	Boolean founded;
+	Boolean found;
+	struct ieee802_1x_kay *kay = participant->kay;
 
 	if (!participant->principal) {
 		wpa_printf(MSG_WARNING, "KaY: Participant is not principal");
@@ -1285,8 +1264,8 @@
 
 	if ((body_len != 0) && (body_len < 40)) {
 		wpa_printf(MSG_ERROR,
-			   "KaY: MKA Use SAK Packet Body Length (%d bytes) should be 0, 40, or more octets",
-			   (int) body_len);
+			   "KaY: MKA Use SAK Packet Body Length (%zu bytes) should be 0, 40, or more octets",
+			   body_len);
 		return -1;
 	}
 
@@ -1307,17 +1286,17 @@
 
 	/* check latest key is valid */
 	if (body->ltx || body->lrx) {
-		founded = FALSE;
+		found = FALSE;
 		os_memcpy(ki.mi, body->lsrv_mi, sizeof(ki.mi));
 		ki.kn = be_to_host32(body->lkn);
 		dl_list_for_each(sa_key, &participant->sak_list,
 				 struct data_key, list) {
 			if (is_ki_equal(&sa_key->key_identifier, &ki)) {
-				founded = TRUE;
+				found = TRUE;
 				break;
 			}
 		}
-		if (!founded) {
+		if (!found) {
 			wpa_printf(MSG_WARNING, "KaY: Latest key is invalid");
 			return -1;
 		}
@@ -1328,9 +1307,8 @@
 			peer->sak_used = TRUE;
 		}
 		if (body->ltx && peer->is_key_server) {
-			ieee802_1x_cp_set_servertransmitting(
-				participant->kay->cp, TRUE);
-			ieee802_1x_cp_sm_step(participant->kay->cp);
+			ieee802_1x_cp_set_servertransmitting(kay->cp, TRUE);
+			ieee802_1x_cp_sm_step(kay->cp);
 		}
 	}
 
@@ -1364,28 +1342,28 @@
 	}
 	if (all_receiving) {
 		participant->to_dist_sak = FALSE;
-		ieee802_1x_cp_set_allreceiving(participant->kay->cp, TRUE);
-		ieee802_1x_cp_sm_step(participant->kay->cp);
+		ieee802_1x_cp_set_allreceiving(kay->cp, TRUE);
+		ieee802_1x_cp_sm_step(kay->cp);
 	}
 
 	/* if i'm key server, and detects peer member pn exhaustion, rekey.*/
 	lpn = be_to_host32(body->llpn);
-	if (lpn > participant->kay->pn_exhaustion) {
+	if (lpn > kay->pn_exhaustion) {
 		if (participant->is_key_server) {
 			participant->new_sak = TRUE;
 			wpa_printf(MSG_WARNING, "KaY: Peer LPN exhaustion");
 		}
 	}
 
-	founded = FALSE;
+	found = FALSE;
 	dl_list_for_each(txsa, &participant->txsc->sa_list,
 			 struct transmit_sa, list) {
 		if (sa_key != NULL && txsa->pkey == sa_key) {
-			founded = TRUE;
+			found = TRUE;
 			break;
 		}
 	}
-	if (!founded) {
+	if (!found) {
 		wpa_printf(MSG_WARNING, "KaY: Can't find txsa");
 		return -1;
 	}
@@ -1393,9 +1371,9 @@
 	/* FIXME: Secy creates txsa with default npn. If MKA detected Latest Key
 	 * npn is larger than txsa's npn, set it to txsa.
 	 */
-	secy_get_transmit_next_pn(participant->kay, txsa);
+	secy_get_transmit_next_pn(kay, txsa);
 	if (lpn > txsa->next_pn) {
-		secy_set_transmit_next_pn(participant->kay, txsa);
+		secy_set_transmit_next_pn(kay, txsa);
 		wpa_printf(MSG_INFO, "KaY: update lpn =0x%x", lpn);
 	}
 
@@ -1410,10 +1388,7 @@
 ieee802_1x_mka_dist_sak_body_present(
 	struct ieee802_1x_mka_participant *participant)
 {
-	if (!participant->to_dist_sak || !participant->new_key)
-		return FALSE;
-
-	return TRUE;
+	return participant->to_dist_sak && participant->new_key;
 }
 
 
@@ -1424,21 +1399,18 @@
 ieee802_1x_mka_get_dist_sak_length(
 	struct ieee802_1x_mka_participant *participant)
 {
-	int length;
-	int cs_index = participant->kay->macsec_csindex;
+	int length = MKA_HDR_LEN;
+	unsigned int cs_index = participant->kay->macsec_csindex;
 
-	if (participant->advised_desired) {
+	if (participant->advised_desired && cs_index < CS_TABLE_SIZE) {
 		length = sizeof(struct ieee802_1x_mka_dist_sak_body);
 		if (cs_index != DEFAULT_CS_INDEX)
 			length += CS_ID_LEN;
 
 		length += cipher_suite_tbl[cs_index].sak_len + 8;
-	} else {
-		length = MKA_HDR_LEN;
 	}
-	length = (length + 0x3) & ~0x3;
 
-	return length;
+	return MKA_ALIGN_LENGTH(length);
 }
 
 
@@ -1453,7 +1425,7 @@
 	struct ieee802_1x_mka_dist_sak_body *body;
 	struct data_key *sak;
 	unsigned int length;
-	int cs_index;
+	unsigned int cs_index;
 	int sak_pos;
 
 	length = ieee802_1x_mka_get_dist_sak_length(participant);
@@ -1472,8 +1444,13 @@
 	body->kn = host_to_be32(sak->key_identifier.kn);
 	cs_index = participant->kay->macsec_csindex;
 	sak_pos = 0;
+	if (cs_index >= CS_TABLE_SIZE)
+		return -1;
 	if (cs_index != DEFAULT_CS_INDEX) {
-		os_memcpy(body->sak, cipher_suite_tbl[cs_index].id, CS_ID_LEN);
+		be64 cs;
+
+		cs = host_to_be64(cipher_suite_tbl[cs_index].id);
+		os_memcpy(body->sak, &cs, CS_ID_LEN);
 		sak_pos = CS_ID_LEN;
 	}
 	if (aes_wrap(participant->kek.key, 16,
@@ -1492,39 +1469,13 @@
 /**
  * ieee802_1x_kay_init_data_key -
  */
-static struct data_key *
-ieee802_1x_kay_init_data_key(const struct key_conf *conf)
+static void ieee802_1x_kay_init_data_key(struct data_key *pkey)
 {
-	struct data_key *pkey;
-
-	if (!conf)
-		return NULL;
-
-	pkey = os_zalloc(sizeof(*pkey));
-	if (pkey == NULL) {
-		wpa_printf(MSG_ERROR, "%s: out of memory", __func__);
-		return NULL;
-	}
-
-	pkey->key = os_zalloc(conf->key_len);
-	if (pkey->key == NULL) {
-		wpa_printf(MSG_ERROR, "%s: out of memory", __func__);
-		os_free(pkey);
-		return NULL;
-	}
-
-	os_memcpy(pkey->key, conf->key, conf->key_len);
-	os_memcpy(&pkey->key_identifier, &conf->ki,
-		  sizeof(pkey->key_identifier));
-	pkey->confidentiality_offset = conf->offset;
-	pkey->an = conf->an;
-	pkey->transmits = conf->tx;
-	pkey->receives = conf->rx;
+	pkey->transmits = TRUE;
+	pkey->receives = TRUE;
 	os_get_time(&pkey->created_time);
 
 	pkey->user = 1;
-
-	return pkey;
 }
 
 
@@ -1541,19 +1492,18 @@
 	struct ieee802_1x_kay_peer *peer;
 	struct macsec_ciphersuite *cs;
 	size_t body_len;
-	struct key_conf *conf;
 	struct data_key *sa_key = NULL;
-	struct ieee802_1x_mka_ki sak_ki;
 	int sak_len;
 	u8 *wrap_sak;
 	u8 *unwrap_sak;
+	struct ieee802_1x_kay *kay = participant->kay;
 
 	hdr = (struct ieee802_1x_mka_hdr *) mka_msg;
 	body_len = get_mka_param_body_len(hdr);
 	if ((body_len != 0) && (body_len != 28) && (body_len < 36)) {
 		wpa_printf(MSG_ERROR,
-			   "KaY: MKA Use SAK Packet Body Length (%d bytes) should be 0, 28, 36, or more octets",
-			   (int) body_len);
+			   "KaY: MKA Use SAK Packet Body Length (%zu bytes) should be 0, 28, 36, or more octets",
+			   body_len);
 		return -1;
 	}
 
@@ -1567,8 +1517,8 @@
 			   "KaY: I can't accept the distributed SAK as myself is key server ");
 		return -1;
 	}
-	if (!participant->kay->macsec_desired ||
-	    participant->kay->macsec_capable == MACSEC_CAP_NOT_IMPLEMENTED) {
+	if (!kay->macsec_desired ||
+	    kay->macsec_capable == MACSEC_CAP_NOT_IMPLEMENTED) {
 		wpa_printf(MSG_ERROR,
 			   "KaY: I am not MACsec-desired or without MACsec capable");
 		return -1;
@@ -1581,28 +1531,29 @@
 			   "KaY: The key server is not in my live peers list");
 		return -1;
 	}
-	if (os_memcmp(&participant->kay->key_server_sci,
-		      &peer->sci, sizeof(struct ieee802_1x_mka_sci)) != 0) {
+	if (!sci_equal(&kay->key_server_sci, &peer->sci)) {
 		wpa_printf(MSG_ERROR, "KaY: The key server is not elected");
 		return -1;
 	}
+
 	if (body_len == 0) {
-		participant->kay->authenticated = TRUE;
-		participant->kay->secured = FALSE;
-		participant->kay->failed = FALSE;
+		kay->authenticated = TRUE;
+		kay->secured = FALSE;
+		kay->failed = FALSE;
 		participant->advised_desired = FALSE;
-		ieee802_1x_cp_connect_authenticated(participant->kay->cp);
-		ieee802_1x_cp_sm_step(participant->kay->cp);
+		ieee802_1x_cp_connect_authenticated(kay->cp);
+		ieee802_1x_cp_sm_step(kay->cp);
 		wpa_printf(MSG_WARNING, "KaY:The Key server advise no MACsec");
 		participant->to_use_sak = TRUE;
 		return 0;
 	}
+
 	participant->advised_desired = TRUE;
-	participant->kay->authenticated = FALSE;
-	participant->kay->secured = TRUE;
-	participant->kay->failed = FALSE;
-	ieee802_1x_cp_connect_secure(participant->kay->cp);
-	ieee802_1x_cp_sm_step(participant->kay->cp);
+	kay->authenticated = FALSE;
+	kay->secured = TRUE;
+	kay->failed = FALSE;
+	ieee802_1x_cp_connect_secure(kay->cp);
+	ieee802_1x_cp_sm_step(kay->cp);
 
 	body = (struct ieee802_1x_mka_dist_sak_body *)mka_msg;
 	ieee802_1x_mka_dump_dist_sak_body(body);
@@ -1615,10 +1566,12 @@
 			return 0;
 		}
 	}
+
 	if (body_len == 28) {
 		sak_len = DEFAULT_SA_KEY_LEN;
 		wrap_sak =  body->sak;
-		participant->kay->macsec_csindex = DEFAULT_CS_INDEX;
+		kay->macsec_csindex = DEFAULT_CS_INDEX;
+		cs = &cipher_suite_tbl[kay->macsec_csindex];
 	} else {
 		cs = ieee802_1x_kay_get_cipher_suite(participant, body->sak);
 		if (!cs) {
@@ -1628,7 +1581,7 @@
 		}
 		sak_len = cs->sak_len;
 		wrap_sak = body->sak + CS_ID_LEN;
-		participant->kay->macsec_csindex = cs->index;
+		kay->macsec_csindex = cs->index;
 	}
 
 	unwrap_sak = os_zalloc(sak_len);
@@ -1644,62 +1597,36 @@
 	}
 	wpa_hexdump(MSG_DEBUG, "\tAES Key Unwrap of SAK:", unwrap_sak, sak_len);
 
-	conf = os_zalloc(sizeof(*conf));
-	if (!conf) {
-		wpa_printf(MSG_ERROR, "KaY-%s: Out of memory", __func__);
-		os_free(unwrap_sak);
-		return -1;
-	}
-	conf->key_len = sak_len;
-
-	conf->key = os_zalloc(conf->key_len);
-	if (!conf->key) {
-		wpa_printf(MSG_ERROR, "KaY-%s: Out of memory", __func__);
-		os_free(unwrap_sak);
-		os_free(conf);
-		return -1;
-	}
-
-	os_memcpy(conf->key, unwrap_sak, conf->key_len);
-
-	os_memcpy(&sak_ki.mi, &participant->current_peer_id.mi,
-		  sizeof(sak_ki.mi));
-	sak_ki.kn = be_to_host32(body->kn);
-
-	os_memcpy(conf->ki.mi, sak_ki.mi, MI_LEN);
-	conf->ki.kn = sak_ki.kn;
-	conf->an = body->dan;
-	conf->offset = body->confid_offset;
-	conf->rx = TRUE;
-	conf->tx = TRUE;
-
-	sa_key = ieee802_1x_kay_init_data_key(conf);
+	sa_key = os_zalloc(sizeof(*sa_key));
 	if (!sa_key) {
 		os_free(unwrap_sak);
-		os_free(conf->key);
-		os_free(conf);
 		return -1;
 	}
 
+	os_memcpy(&sa_key->key_identifier.mi, &participant->current_peer_id.mi,
+		  MI_LEN);
+	sa_key->key_identifier.kn = be_to_host32(body->kn);
+
+	sa_key->key = unwrap_sak;
+	sa_key->key_len = sak_len;
+
+	sa_key->confidentiality_offset = body->confid_offset;
+	sa_key->an = body->dan;
+	ieee802_1x_kay_init_data_key(sa_key);
+
 	dl_list_add(&participant->sak_list, &sa_key->list);
 
-	ieee802_1x_cp_set_ciphersuite(
-		participant->kay->cp,
-		cipher_suite_tbl[participant->kay->macsec_csindex].id);
-	ieee802_1x_cp_sm_step(participant->kay->cp);
-	ieee802_1x_cp_set_offset(participant->kay->cp, body->confid_offset);
-	ieee802_1x_cp_sm_step(participant->kay->cp);
-	ieee802_1x_cp_set_distributedki(participant->kay->cp, &sak_ki);
-	ieee802_1x_cp_set_distributedan(participant->kay->cp, body->dan);
-	ieee802_1x_cp_signal_newsak(participant->kay->cp);
-	ieee802_1x_cp_sm_step(participant->kay->cp);
+	ieee802_1x_cp_set_ciphersuite(kay->cp, cs->id);
+	ieee802_1x_cp_sm_step(kay->cp);
+	ieee802_1x_cp_set_offset(kay->cp, body->confid_offset);
+	ieee802_1x_cp_sm_step(kay->cp);
+	ieee802_1x_cp_set_distributedki(kay->cp, &sa_key->key_identifier);
+	ieee802_1x_cp_set_distributedan(kay->cp, body->dan);
+	ieee802_1x_cp_signal_newsak(kay->cp);
+	ieee802_1x_cp_sm_step(kay->cp);
 
 	participant->to_use_sak = TRUE;
 
-	os_free(unwrap_sak);
-	os_free(conf->key);
-	os_free(conf);
-
 	return 0;
 }
 
@@ -1725,7 +1652,7 @@
 	length = sizeof(struct ieee802_1x_mka_icv_body);
 	length += mka_alg_tbl[participant->kay->mka_algindex].icv_len;
 
-	return (length + 0x3) & ~0x3;
+	return MKA_ALIGN_LENGTH(length);
 }
 
 
@@ -1753,12 +1680,9 @@
 		return -1;
 	}
 
-	if (length != DEFAULT_ICV_LEN)  {
-		os_memcpy(wpabuf_put(buf, length - MKA_HDR_LEN), cmac,
-			  length - MKA_HDR_LEN);
-	} else {
-		os_memcpy(wpabuf_put(buf, length), cmac, length);
-	}
+	if (length != DEFAULT_ICV_LEN)
+		length -= MKA_HDR_LEN;
+	os_memcpy(wpabuf_put(buf, length), cmac, length);
 
 	return 0;
 }
@@ -1821,8 +1745,8 @@
 	body_len = get_mka_param_body_len(hdr);
 	if (body_len < 28) {
 		wpa_printf(MSG_ERROR,
-			   "KaY: MKA Use SAK Packet Body Length (%d bytes) should be 28 or more octets",
-			   (int) body_len);
+			   "KaY: MKA Use SAK Packet Body Length (%zu bytes) should be 28 or more octets",
+			   body_len);
 		return -1;
 	}
 
@@ -1845,8 +1769,8 @@
 	body_len = get_mka_param_body_len(hdr);
 	if (body_len < 5) {
 		wpa_printf(MSG_ERROR,
-			   "KaY: MKA Use SAK Packet Body Length (%d bytes) should be 5 or more octets",
-			   (int) body_len);
+			   "KaY: MKA Use SAK Packet Body Length (%zu bytes) should be 5 or more octets",
+			   body_len);
 		return -1;
 	}
 
@@ -1865,77 +1789,87 @@
 }
 
 
-static struct mka_param_body_handler mak_body_handler[] = {
+struct mka_param_body_handler {
+	int (*body_tx)(struct ieee802_1x_mka_participant *participant,
+		       struct wpabuf *buf);
+	int (*body_rx)(struct ieee802_1x_mka_participant *participant,
+		       const u8 *mka_msg, size_t msg_len);
+	int (*body_length)(struct ieee802_1x_mka_participant *participant);
+	Boolean (*body_present)(struct ieee802_1x_mka_participant *participant);
+};
+
+
+static struct mka_param_body_handler mka_body_handler[] = {
 	/* basic parameter set */
 	{
-		ieee802_1x_mka_encode_basic_body,
-		NULL,
-		ieee802_1x_mka_basic_body_length,
-		ieee802_1x_mka_basic_body_present
+		.body_tx      = ieee802_1x_mka_encode_basic_body,
+		.body_rx      = NULL,
+		.body_length  = ieee802_1x_mka_basic_body_length,
+		.body_present = ieee802_1x_mka_basic_body_present
 	},
 
 	/* live peer list parameter set */
 	{
-		ieee802_1x_mka_encode_live_peer_body,
-		ieee802_1x_mka_decode_live_peer_body,
-		ieee802_1x_mka_get_live_peer_length,
-		ieee802_1x_mka_live_peer_body_present
+		.body_tx      = ieee802_1x_mka_encode_live_peer_body,
+		.body_rx      = ieee802_1x_mka_decode_live_peer_body,
+		.body_length  = ieee802_1x_mka_get_live_peer_length,
+		.body_present = ieee802_1x_mka_live_peer_body_present
 	},
 
 	/* potential peer list parameter set */
 	{
-		ieee802_1x_mka_encode_potential_peer_body,
-		ieee802_1x_mka_decode_potential_peer_body,
-		ieee802_1x_mka_get_potential_peer_length,
-		ieee802_1x_mka_potential_peer_body_present
+		.body_tx      = ieee802_1x_mka_encode_potential_peer_body,
+		.body_rx      = ieee802_1x_mka_decode_potential_peer_body,
+		.body_length  = ieee802_1x_mka_get_potential_peer_length,
+		.body_present = ieee802_1x_mka_potential_peer_body_present
 	},
 
 	/* sak use parameter set */
 	{
-		ieee802_1x_mka_encode_sak_use_body,
-		ieee802_1x_mka_decode_sak_use_body,
-		ieee802_1x_mka_get_sak_use_length,
-		ieee802_1x_mka_sak_use_body_present
+		.body_tx      = ieee802_1x_mka_encode_sak_use_body,
+		.body_rx      = ieee802_1x_mka_decode_sak_use_body,
+		.body_length  = ieee802_1x_mka_get_sak_use_length,
+		.body_present = ieee802_1x_mka_sak_use_body_present
 	},
 
 	/* distribute sak parameter set */
 	{
-		ieee802_1x_mka_encode_dist_sak_body,
-		ieee802_1x_mka_decode_dist_sak_body,
-		ieee802_1x_mka_get_dist_sak_length,
-		ieee802_1x_mka_dist_sak_body_present
+		.body_tx      = ieee802_1x_mka_encode_dist_sak_body,
+		.body_rx      = ieee802_1x_mka_decode_dist_sak_body,
+		.body_length  = ieee802_1x_mka_get_dist_sak_length,
+		.body_present = ieee802_1x_mka_dist_sak_body_present
 	},
 
 	/* distribute cak parameter set */
 	{
-		NULL,
-		ieee802_1x_mka_decode_dist_cak_body,
-		NULL,
-		NULL
+		.body_tx      = NULL,
+		.body_rx      = ieee802_1x_mka_decode_dist_cak_body,
+		.body_length  = NULL,
+		.body_present = NULL
 	},
 
 	/* kmd parameter set */
 	{
-		NULL,
-		ieee802_1x_mka_decode_kmd_body,
-		NULL,
-		NULL
+		.body_tx      = NULL,
+		.body_rx      = ieee802_1x_mka_decode_kmd_body,
+		.body_length  = NULL,
+		.body_present = NULL
 	},
 
 	/* announce parameter set */
 	{
-		NULL,
-		ieee802_1x_mka_decode_announce_body,
-		NULL,
-		NULL
+		.body_tx      = NULL,
+		.body_rx      = ieee802_1x_mka_decode_announce_body,
+		.body_length  = NULL,
+		.body_present = NULL
 	},
 
 	/* icv parameter set */
 	{
-		ieee802_1x_mka_encode_icv_body,
-		NULL,
-		ieee802_1x_mka_get_icv_length,
-		ieee802_1x_mka_icv_body_present
+		.body_tx      = ieee802_1x_mka_encode_icv_body,
+		.body_rx      = NULL,
+		.body_length  = ieee802_1x_mka_get_icv_length,
+		.body_present = ieee802_1x_mka_icv_body_present
 	},
 };
 
@@ -1965,11 +1899,13 @@
 ieee802_1x_kay_generate_new_sak(struct ieee802_1x_mka_participant *participant)
 {
 	struct data_key *sa_key = NULL;
-	struct key_conf *conf;
 	struct ieee802_1x_kay_peer *peer;
 	struct ieee802_1x_kay *kay = participant->kay;
 	int ctx_len, ctx_offset;
 	u8 *context;
+	unsigned int key_len;
+	u8 *key;
+	struct macsec_ciphersuite *cs;
 
 	/* check condition for generating a fresh SAK:
 	 * must have one live peer
@@ -1996,40 +1932,29 @@
 		return -1;
 	}
 
-	conf = os_zalloc(sizeof(*conf));
-	if (!conf) {
-		wpa_printf(MSG_ERROR, "KaY-%s: Out of memory", __func__);
-		return -1;
-	}
-	conf->key_len = cipher_suite_tbl[kay->macsec_csindex].sak_len;
-
-	conf->key = os_zalloc(conf->key_len);
-	if (!conf->key) {
-		os_free(conf);
+	cs = &cipher_suite_tbl[kay->macsec_csindex];
+	key_len = cs->sak_len;
+	key = os_zalloc(key_len);
+	if (!key) {
 		wpa_printf(MSG_ERROR, "KaY-%s: Out of memory", __func__);
 		return -1;
 	}
 
-	ctx_len = conf->key_len + sizeof(kay->dist_kn);
+	ctx_len = key_len + sizeof(kay->dist_kn);
 	dl_list_for_each(peer, &participant->live_peers,
 			 struct ieee802_1x_kay_peer, list)
 		ctx_len += sizeof(peer->mi);
 	ctx_len += sizeof(participant->mi);
 
 	context = os_zalloc(ctx_len);
-	if (!context) {
-		os_free(conf->key);
-		os_free(conf);
-		return -1;
-	}
+	if (!context)
+		goto fail;
+
 	ctx_offset = 0;
-	if (os_get_random(context + ctx_offset, conf->key_len) < 0) {
-		os_free(context);
-		os_free(conf->key);
-		os_free(conf);
-		return -1;
-	}
-	ctx_offset += conf->key_len;
+	if (os_get_random(context + ctx_offset, key_len) < 0)
+		goto fail;
+
+	ctx_offset += key_len;
 	dl_list_for_each(peer, &participant->live_peers,
 			 struct ieee802_1x_kay_peer, list) {
 		os_memcpy(context + ctx_offset, peer->mi, sizeof(peer->mi));
@@ -2040,46 +1965,44 @@
 	ctx_offset += sizeof(participant->mi);
 	os_memcpy(context + ctx_offset, &kay->dist_kn, sizeof(kay->dist_kn));
 
-	if (conf->key_len == 16) {
+	if (key_len == 16) {
 		ieee802_1x_sak_128bits_aes_cmac(participant->cak.key,
-						context, ctx_len, conf->key);
-	} else if (conf->key_len == 32) {
+						context, ctx_len, key);
+	} else if (key_len == 32) {
 		ieee802_1x_sak_128bits_aes_cmac(participant->cak.key,
-						context, ctx_len, conf->key);
+						context, ctx_len, key);
 	} else {
 		wpa_printf(MSG_ERROR, "KaY: SAK Length not support");
-		os_free(conf->key);
-		os_free(conf);
-		os_free(context);
-		return -1;
+		goto fail;
 	}
-	wpa_hexdump(MSG_DEBUG, "KaY: generated new SAK",
-		    conf->key, conf->key_len);
+	wpa_hexdump(MSG_DEBUG, "KaY: generated new SAK", key, key_len);
+	os_free(context);
+	context = NULL;
 
-	os_memcpy(conf->ki.mi, participant->mi, MI_LEN);
-	conf->ki.kn = participant->kay->dist_kn;
-	conf->an = participant->kay->dist_an;
-	conf->offset = kay->macsec_confidentiality;
-	conf->rx = TRUE;
-	conf->tx = TRUE;
-
-	sa_key = ieee802_1x_kay_init_data_key(conf);
+	sa_key = os_zalloc(sizeof(*sa_key));
 	if (!sa_key) {
-		os_free(conf->key);
-		os_free(conf);
-		os_free(context);
-		return -1;
+		wpa_printf(MSG_ERROR, "KaY-%s: Out of memory", __func__);
+		goto fail;
 	}
+
+	sa_key->key = key;
+	sa_key->key_len = key_len;
+	os_memcpy(sa_key->key_identifier.mi, participant->mi, MI_LEN);
+	sa_key->key_identifier.kn = kay->dist_kn;
+
+	sa_key->confidentiality_offset = kay->macsec_confidentiality;
+	sa_key->an = kay->dist_an;
+	ieee802_1x_kay_init_data_key(sa_key);
+
 	participant->new_key = sa_key;
 
 	dl_list_add(&participant->sak_list, &sa_key->list);
-	ieee802_1x_cp_set_ciphersuite(participant->kay->cp,
-				      cipher_suite_tbl[kay->macsec_csindex].id);
+	ieee802_1x_cp_set_ciphersuite(kay->cp, cs->id);
 	ieee802_1x_cp_sm_step(kay->cp);
-	ieee802_1x_cp_set_offset(kay->cp, conf->offset);
+	ieee802_1x_cp_set_offset(kay->cp, kay->macsec_confidentiality);
 	ieee802_1x_cp_sm_step(kay->cp);
-	ieee802_1x_cp_set_distributedki(kay->cp, &conf->ki);
-	ieee802_1x_cp_set_distributedan(kay->cp, conf->an);
+	ieee802_1x_cp_set_distributedki(kay->cp, &sa_key->key_identifier);
+	ieee802_1x_cp_set_distributedan(kay->cp, sa_key->an);
 	ieee802_1x_cp_signal_newsak(kay->cp);
 	ieee802_1x_cp_sm_step(kay->cp);
 
@@ -2087,17 +2010,31 @@
 			 struct ieee802_1x_kay_peer, list)
 		peer->sak_used = FALSE;
 
-	participant->kay->dist_kn++;
-	participant->kay->dist_an++;
-	if (participant->kay->dist_an > 3)
-		participant->kay->dist_an = 0;
+	kay->dist_kn++;
+	kay->dist_an++;
+	if (kay->dist_an > 3)
+		kay->dist_an = 0;
 
-	participant->kay->dist_time = time(NULL);
+	kay->dist_time = time(NULL);
 
-	os_free(conf->key);
-	os_free(conf);
-	os_free(context);
 	return 0;
+
+fail:
+	os_free(key);
+	os_free(context);
+	return -1;
+}
+
+
+static int compare_priorities(const struct ieee802_1x_kay_peer *peer,
+			      const struct ieee802_1x_kay_peer *other)
+{
+	if (peer->key_server_priority < other->key_server_priority)
+		return -1;
+	if (other->key_server_priority < peer->key_server_priority)
+		return 1;
+
+	return os_memcmp(peer->sci.addr, other->sci.addr, ETH_ALEN);
 }
 
 
@@ -2131,37 +2068,26 @@
 			continue;
 		}
 
-		if (peer->key_server_priority <
-		    key_server->key_server_priority) {
+		if (compare_priorities(peer, key_server) < 0)
 			key_server = peer;
-		} else if (peer->key_server_priority ==
-			   key_server->key_server_priority) {
-			if (os_memcmp(peer->sci.addr, key_server->sci.addr,
-				      ETH_ALEN) < 0)
-				key_server = peer;
-		}
 	}
 
 	/* elect the key server between me and the above elected peer */
 	i_is_key_server = FALSE;
 	if (key_server && participant->can_be_key_server) {
-		if (kay->actor_priority
-			   < key_server->key_server_priority) {
+		struct ieee802_1x_kay_peer tmp;
+
+		tmp.key_server_priority = kay->actor_priority;
+		os_memcpy(&tmp.sci, &kay->actor_sci, sizeof(tmp.sci));
+		if (compare_priorities(&tmp, key_server) < 0)
 			i_is_key_server = TRUE;
-		} else if (kay->actor_priority
-					== key_server->key_server_priority) {
-			if (os_memcmp(kay->actor_sci.addr, key_server->sci.addr,
-				      ETH_ALEN) < 0)
-				i_is_key_server = TRUE;
-		}
 	} else if (participant->can_be_key_server) {
 		i_is_key_server = TRUE;
 	}
 
 	if (i_is_key_server) {
 		ieee802_1x_cp_set_electedself(kay->cp, TRUE);
-		if (os_memcmp(&kay->key_server_sci, &kay->actor_sci,
-			      sizeof(kay->key_server_sci))) {
+		if (!sci_equal(&kay->key_server_sci, &kay->actor_sci)) {
 			ieee802_1x_cp_signal_chgdserver(kay->cp);
 			ieee802_1x_cp_sm_step(kay->cp);
 		}
@@ -2178,8 +2104,7 @@
 		kay->key_server_priority = kay->actor_priority;
 	} else if (key_server) {
 		ieee802_1x_cp_set_electedself(kay->cp, FALSE);
-		if (os_memcmp(&kay->key_server_sci, &key_server->sci,
-			      sizeof(kay->key_server_sci))) {
+		if (!sci_equal(&kay->key_server_sci, &key_server->sci)) {
 			ieee802_1x_cp_signal_chgdserver(kay->cp);
 			ieee802_1x_cp_sm_step(kay->cp);
 		}
@@ -2237,11 +2162,11 @@
 		if (!peer->macsec_desired)
 			continue;
 
-		if (peer->macsec_capbility == MACSEC_CAP_NOT_IMPLEMENTED)
+		if (peer->macsec_capability == MACSEC_CAP_NOT_IMPLEMENTED)
 			continue;
 
-		less_capability = (less_capability < peer->macsec_capbility) ?
-			less_capability : peer->macsec_capbility;
+		less_capability = (less_capability < peer->macsec_capability) ?
+			less_capability : peer->macsec_capability;
 		has_peer = TRUE;
 	}
 
@@ -2302,10 +2227,10 @@
 	eapol_hdr->type = IEEE802_1X_TYPE_EAPOL_MKA;
 	eapol_hdr->length = host_to_be16(pbuf->size - pbuf->used);
 
-	for (i = 0; i < ARRAY_SIZE(mak_body_handler); i++) {
-		if (mak_body_handler[i].body_present &&
-		    mak_body_handler[i].body_present(participant)) {
-			if (mak_body_handler[i].body_tx(participant, pbuf))
+	for (i = 0; i < ARRAY_SIZE(mka_body_handler); i++) {
+		if (mka_body_handler[i].body_present &&
+		    mka_body_handler[i].body_present(participant)) {
+			if (mka_body_handler[i].body_tx(participant, pbuf))
 				return -1;
 		}
 	}
@@ -2327,10 +2252,10 @@
 
 	wpa_printf(MSG_DEBUG, "KaY: to enpacket and send the MKPDU");
 	length += sizeof(struct ieee802_1x_hdr) + sizeof(struct ieee8023_hdr);
-	for (i = 0; i < ARRAY_SIZE(mak_body_handler); i++) {
-		if (mak_body_handler[i].body_present &&
-		    mak_body_handler[i].body_present(participant))
-			length += mak_body_handler[i].body_length(participant);
+	for (i = 0; i < ARRAY_SIZE(mka_body_handler); i++) {
+		if (mka_body_handler[i].body_present &&
+		    mka_body_handler[i].body_present(participant))
+			length += mka_body_handler[i].body_length(participant);
 	}
 
 	buf = wpabuf_alloc(length);
@@ -2371,27 +2296,16 @@
 	participant = (struct ieee802_1x_mka_participant *)eloop_ctx;
 	kay = participant->kay;
 	if (participant->cak_life) {
-		if (now > participant->cak_life) {
-			kay->authenticated = FALSE;
-			kay->secured = FALSE;
-			kay->failed = TRUE;
-			ieee802_1x_kay_delete_mka(kay, &participant->ckn);
-			return;
-		}
+		if (now > participant->cak_life)
+			goto delete_mka;
 	}
 
 	/* should delete MKA instance if there are not live peers
 	 * when the MKA life elapsed since its creating */
 	if (participant->mka_life) {
 		if (dl_list_empty(&participant->live_peers)) {
-			if (now > participant->mka_life) {
-				kay->authenticated = FALSE;
-				kay->secured = FALSE;
-				kay->failed = TRUE;
-				ieee802_1x_kay_delete_mka(kay,
-							  &participant->ckn);
-				return;
-			}
+			if (now > participant->mka_life)
+				goto delete_mka;
 		} else {
 			participant->mka_life = 0;
 		}
@@ -2408,8 +2322,7 @@
 			dl_list_for_each_safe(rxsc, pre_rxsc,
 					      &participant->rxsc_list,
 					      struct receive_sc, list) {
-				if (os_memcmp(&rxsc->sci, &peer->sci,
-					      sizeof(rxsc->sci)) == 0) {
+				if (sci_equal(&rxsc->sci, &peer->sci)) {
 					secy_delete_receive_sc(kay, rxsc);
 					ieee802_1x_kay_deinit_receive_sc(
 						participant, rxsc);
@@ -2480,6 +2393,14 @@
 	eloop_register_timeout(MKA_HELLO_TIME / 1000, 0,
 			       ieee802_1x_participant_timer,
 			       participant, NULL);
+
+	return;
+
+delete_mka:
+	kay->authenticated = FALSE;
+	kay->secured = FALSE;
+	kay->failed = TRUE;
+	ieee802_1x_kay_delete_mka(kay, &participant->ckn);
 }
 
 
@@ -2517,8 +2438,8 @@
 
 	dl_list_add(&psc->sa_list, &psa->list);
 	wpa_printf(MSG_DEBUG,
-		   "KaY: Create transmit SA(an: %d, next_PN: %u) of SC(channel: %d)",
-		   (int) an, next_PN, psc->channel);
+		   "KaY: Create transmit SA(an: %hhu, next_PN: %u) of SC(channel: %d)",
+		   an, next_PN, psc->channel);
 
 	return psa;
 }
@@ -2531,8 +2452,8 @@
 {
 	psa->pkey = NULL;
 	wpa_printf(MSG_DEBUG,
-		   "KaY: Delete transmit SA(an: %d) of SC(channel: %d)",
-		   psa->an, psa->sc->channel);
+		   "KaY: Delete transmit SA(an: %hhu) of SC",
+		   psa->an);
 	dl_list_del(&psa->list);
 	os_free(psa);
 }
@@ -2848,38 +2769,6 @@
 
 
 /**
- * ieee802_1x_kay_cp_conf -
- */
-int ieee802_1x_kay_cp_conf(struct ieee802_1x_kay *kay,
-			   struct ieee802_1x_cp_conf *pconf)
-{
-	pconf->protect = kay->macsec_protect;
-	pconf->replay_protect = kay->macsec_replay_protect;
-	pconf->validate = kay->macsec_validate;
-
-	return 0;
-}
-
-
-/**
- * ieee802_1x_kay_alloc_cp_sm -
- */
-static struct ieee802_1x_cp_sm *
-ieee802_1x_kay_alloc_cp_sm(struct ieee802_1x_kay *kay)
-{
-	struct ieee802_1x_cp_conf conf;
-
-	os_memset(&conf, 0, sizeof(conf));
-	conf.protect = kay->macsec_protect;
-	conf.replay_protect = kay->macsec_replay_protect;
-	conf.validate = kay->macsec_validate;
-	conf.replay_window = kay->macsec_replay_window;
-
-	return ieee802_1x_cp_sm_init(kay, &conf);
-}
-
-
-/**
  * ieee802_1x_kay_mkpdu_sanity_check -
  *     sanity check specified in clause 11.11.2 of IEEE802.1X-2010
  */
@@ -2907,13 +2796,13 @@
 		return -1;
 	}
 
-	/* MKPDU should not less than 32 octets */
+	/* MKPDU should not be less than 32 octets */
 	mka_msg_len = be_to_host16(eapol_hdr->length);
 	if (mka_msg_len < 32) {
 		wpa_printf(MSG_MSGDUMP, "KaY: MKPDU is less than 32 octets");
 		return -1;
 	}
-	/* MKPDU should multiple 4 octets */
+	/* MKPDU should be a multiple of 4 octets */
 	if ((mka_msg_len % 4) != 0) {
 		wpa_printf(MSG_MSGDUMP,
 			   "KaY: MKPDU is not multiple of 4 octets");
@@ -2926,9 +2815,9 @@
 	/* EAPOL-MKA body should comprise basic parameter set and ICV */
 	if (mka_msg_len < MKA_HDR_LEN + body_len + DEFAULT_ICV_LEN) {
 		wpa_printf(MSG_ERROR,
-			   "KaY: Received EAPOL-MKA Packet Body Length (%d bytes) is less than the Basic Parameter Set Header Length (%d bytes) + the Basic Parameter Set Body Length (%d bytes) + %d bytes of ICV",
-			   (int) mka_msg_len, (int) MKA_HDR_LEN,
-			   (int) body_len, DEFAULT_ICV_LEN);
+			   "KaY: Received EAPOL-MKA Packet Body Length (%zu bytes) is less than the Basic Parameter Set Header Length (%zu bytes) + the Basic Parameter Set Body Length (%zu bytes) + %d bytes of ICV",
+			   mka_msg_len, MKA_HDR_LEN,
+			   body_len, DEFAULT_ICV_LEN);
 		return -1;
 	}
 
@@ -2959,21 +2848,19 @@
 		wpa_printf(MSG_ERROR, "KaY: omac1_aes_128 failed");
 		return -1;
 	}
+
 	msg_icv = ieee802_1x_mka_decode_icv_body(participant, (u8 *) mka_hdr,
 						 mka_msg_len);
-
-	if (msg_icv) {
-		if (os_memcmp_const(msg_icv, icv,
-				    mka_alg_tbl[kay->mka_algindex].icv_len) !=
-		    0) {
-			wpa_printf(MSG_ERROR,
-				   "KaY: Computed ICV is not equal to Received ICV");
-		return -1;
-		}
-	} else {
+	if (!msg_icv) {
 		wpa_printf(MSG_ERROR, "KaY: No ICV");
 		return -1;
 	}
+	if (os_memcmp_const(msg_icv, icv,
+			    mka_alg_tbl[kay->mka_algindex].icv_len) != 0) {
+		wpa_printf(MSG_ERROR,
+			   "KaY: Computed ICV is not equal to Received ICV");
+		return -1;
+	}
 
 	return 0;
 }
@@ -2992,7 +2879,6 @@
 	u8 body_type;
 	int i;
 	const u8 *pos;
-	Boolean my_included;
 	Boolean handled[256];
 
 	if (ieee802_1x_kay_mkpdu_sanity_check(kay, buf, len))
@@ -3013,21 +2899,10 @@
 	left_len -= body_len + MKA_HDR_LEN;
 
 	/* check i am in the peer's peer list */
-	my_included = ieee802_1x_mka_i_in_peerlist(participant, pos, left_len);
-	if (my_included) {
+	if (ieee802_1x_mka_i_in_peerlist(participant, pos, left_len) &&
+	    !ieee802_1x_kay_is_in_live_peer(participant,
+					    participant->current_peer_id.mi)) {
 		/* accept the peer as live peer */
-		if (!ieee802_1x_kay_is_in_peer(
-			    participant,
-			    participant->current_peer_id.mi)) {
-			if (!ieee802_1x_kay_create_live_peer(
-				    participant,
-				    participant->current_peer_id.mi,
-				    be_to_host32(
-					    participant->current_peer_id.mn)))
-				return -1;
-			ieee802_1x_kay_elect_key_server(participant);
-			ieee802_1x_kay_decide_macsec_use(participant);
-		}
 		if (ieee802_1x_kay_is_in_potential_peer(
 			    participant, participant->current_peer_id.mi)) {
 			if (!ieee802_1x_kay_move_live_peer(
@@ -3036,9 +2911,15 @@
 				    be_to_host32(participant->
 						 current_peer_id.mn)))
 				return -1;
-			ieee802_1x_kay_elect_key_server(participant);
-			ieee802_1x_kay_decide_macsec_use(participant);
+		} else if (!ieee802_1x_kay_create_live_peer(
+				   participant, participant->current_peer_id.mi,
+				   be_to_host32(participant->
+						current_peer_id.mn))) {
+				return -1;
 		}
+
+		ieee802_1x_kay_elect_key_server(participant);
+		ieee802_1x_kay_decide_macsec_use(participant);
 	}
 
 	/*
@@ -3049,7 +2930,9 @@
 		handled[i] = FALSE;
 
 	handled[0] = TRUE;
-	while (left_len > MKA_HDR_LEN + DEFAULT_ICV_LEN) {
+	for (; left_len > MKA_HDR_LEN + DEFAULT_ICV_LEN;
+	     pos += body_len + MKA_HDR_LEN,
+		     left_len -= body_len + MKA_HDR_LEN) {
 		hdr = (struct ieee802_1x_mka_hdr *) pos;
 		body_len = get_mka_param_body_len(hdr);
 		body_type = get_mka_param_body_type(hdr);
@@ -3059,29 +2942,25 @@
 
 		if (left_len < (MKA_HDR_LEN + body_len + DEFAULT_ICV_LEN)) {
 			wpa_printf(MSG_ERROR,
-				   "KaY: MKA Peer Packet Body Length (%d bytes) is less than the Parameter Set Header Length (%d bytes) + the Parameter Set Body Length (%d bytes) + %d bytes of ICV",
-				   (int) left_len, (int) MKA_HDR_LEN,
-				   (int) body_len, DEFAULT_ICV_LEN);
-			goto next_para_set;
+				   "KaY: MKA Peer Packet Body Length (%zu bytes) is less than the Parameter Set Header Length (%zu bytes) + the Parameter Set Body Length (%zu bytes) + %d bytes of ICV",
+				   left_len, MKA_HDR_LEN,
+				   body_len, DEFAULT_ICV_LEN);
+			continue;
 		}
 
 		if (handled[body_type])
-			goto next_para_set;
+			continue;
 
 		handled[body_type] = TRUE;
-		if (body_type < ARRAY_SIZE(mak_body_handler) &&
-		    mak_body_handler[body_type].body_rx) {
-			mak_body_handler[body_type].body_rx
+		if (body_type < ARRAY_SIZE(mka_body_handler) &&
+		    mka_body_handler[body_type].body_rx) {
+			mka_body_handler[body_type].body_rx
 				(participant, pos, left_len);
 		} else {
 			wpa_printf(MSG_ERROR,
-				   "The type %d not supported in this MKA version %d",
+				   "The type %d is not supported in this MKA version %d",
 				   body_type, MKA_VERSION_ID);
 		}
-
-next_para_set:
-		pos += body_len + MKA_HDR_LEN;
-		left_len -= body_len + MKA_HDR_LEN;
 	}
 
 	kay->active = TRUE;
@@ -3208,7 +3087,7 @@
 	wpa_printf(MSG_DEBUG, "KaY: secy init macsec done");
 
 	/* init CP */
-	kay->cp = ieee802_1x_kay_alloc_cp_sm(kay);
+	kay->cp = ieee802_1x_cp_sm_init(kay);
 	if (kay->cp == NULL) {
 		ieee802_1x_kay_deinit(kay);
 		return NULL;
@@ -3351,9 +3230,8 @@
 	participant->retry_count = 0;
 	participant->kay = kay;
 
-	if (os_get_random(participant->mi, sizeof(participant->mi)) < 0)
+	if (!reset_participant_mi(participant))
 		goto fail;
-	participant->mn = 0;
 
 	participant->lrx = FALSE;
 	participant->ltx = FALSE;
@@ -3527,14 +3405,15 @@
  * ieee802_1x_kay_change_cipher_suite -
  */
 int
-ieee802_1x_kay_change_cipher_suite(struct ieee802_1x_kay *kay, int cs_index)
+ieee802_1x_kay_change_cipher_suite(struct ieee802_1x_kay *kay,
+				   unsigned int cs_index)
 {
 	struct ieee802_1x_mka_participant *participant;
 
 	if (!kay)
 		return -1;
 
-	if ((unsigned int) cs_index >= CS_TABLE_SIZE) {
+	if (cs_index >= CS_TABLE_SIZE) {
 		wpa_printf(MSG_ERROR,
 			   "KaY: Configured cipher suite index is out of range");
 		return -1;
diff --git a/src/pae/ieee802_1x_kay.h b/src/pae/ieee802_1x_kay.h
index ea15335..afbaa33 100644
--- a/src/pae/ieee802_1x_kay.h
+++ b/src/pae/ieee802_1x_kay.h
@@ -14,7 +14,6 @@
 #include "common/ieee802_1x_defs.h"
 
 struct macsec_init_params;
-struct ieee802_1x_cp_conf;
 
 #define MI_LEN			12
 #define MAX_KEY_LEN		32  /* 32 bytes, 256 bits */
@@ -48,8 +47,6 @@
 enum mka_created_mode {
 	PSK,
 	EAP_EXCHANGE,
-	DISTRIBUTED,
-	CACHED,
 };
 
 struct ieee802_1x_kay_ctx {
@@ -61,7 +58,7 @@
 	int (*macsec_deinit)(void *ctx);
 	int (*enable_protect_frames)(void *ctx, Boolean enabled);
 	int (*set_replay_protect)(void *ctx, Boolean enabled, u32 window);
-	int (*set_current_cipher_suite)(void *ctx, const u8 *cs, size_t cs_len);
+	int (*set_current_cipher_suite)(void *ctx, u64 cs);
 	int (*enable_controlled_port)(void *ctx, Boolean enabled);
 	int (*get_receive_lowest_pn)(void *ctx, u32 channel, u8 an,
 				     u32 *lowest_pn);
@@ -126,7 +123,7 @@
 	Boolean is_obliged_key_server;
 	char if_name[IFNAMSIZ];
 
-	int macsec_csindex;  /*  MACsec cipher suite table index */
+	unsigned int macsec_csindex;  /* MACsec cipher suite table index */
 	int mka_algindex;  /* MKA alg table index */
 
 	u32 dist_kn;
@@ -171,7 +168,7 @@
 				    Boolean status);
 int ieee802_1x_kay_new_sak(struct ieee802_1x_kay *kay);
 int ieee802_1x_kay_change_cipher_suite(struct ieee802_1x_kay *kay,
-				       int cs_index);
+				       unsigned int cs_index);
 
 int ieee802_1x_kay_set_latest_sa_attr(struct ieee802_1x_kay *kay,
 				      struct ieee802_1x_mka_ki *lki, u8 lan,
@@ -188,7 +185,5 @@
 int ieee802_1x_kay_enable_rx_sas(struct ieee802_1x_kay *kay,
 				 struct ieee802_1x_mka_ki *lki);
 int ieee802_1x_kay_enable_new_info(struct ieee802_1x_kay *kay);
-int ieee802_1x_kay_cp_conf(struct ieee802_1x_kay *kay,
-			   struct ieee802_1x_cp_conf *pconf);
 
 #endif /* IEEE802_1X_KAY_H */
diff --git a/src/pae/ieee802_1x_kay_i.h b/src/pae/ieee802_1x_kay_i.h
index 72c7d0b..622282e 100644
--- a/src/pae/ieee802_1x_kay_i.h
+++ b/src/pae/ieee802_1x_kay_i.h
@@ -49,21 +49,11 @@
 	Boolean is_key_server;
 	u8 key_server_priority;
 	Boolean macsec_desired;
-	enum macsec_cap macsec_capbility;
+	enum macsec_cap macsec_capability;
 	Boolean sak_used;
 	struct dl_list list;
 };
 
-struct key_conf {
-	u8 *key;
-	struct ieee802_1x_mka_ki ki;
-	enum confidentiality_offset offset;
-	u8 an;
-	Boolean tx;
-	Boolean rx;
-	int key_len; /* unit: byte */
-};
-
 struct data_key {
 	u8 *key;
 	int key_len;
@@ -147,7 +137,7 @@
 };
 
 struct macsec_ciphersuite {
-	u8 id[CS_ID_LEN];
+	u64 id;
 	char name[32];
 	enum macsec_cap capable;
 	int sak_len; /* unit: byte */
@@ -241,44 +231,44 @@
 
 struct ieee802_1x_mka_hdr {
 	/* octet 1 */
-	u32 type:8;
+	u8 type;
 	/* octet 2 */
-	u32 reserve:8;
+	u8 reserve;
 	/* octet 3 */
 #if __BYTE_ORDER == __LITTLE_ENDIAN
-	u32 length:4;
-	u32 reserve1:4;
+	u8 length:4;
+	u8 reserve1:4;
 #elif __BYTE_ORDER == __BIG_ENDIAN
-	u32 reserve1:4;
-	u32 length:4;
+	u8 reserve1:4;
+	u8 length:4;
 #else
 #error "Please fix <bits/endian.h>"
 #endif
 	/* octet 4 */
-	u32 length1:8;
+	u8 length1;
 };
 
 #define MKA_HDR_LEN sizeof(struct ieee802_1x_mka_hdr)
 
 struct ieee802_1x_mka_basic_body {
 	/* octet 1 */
-	u32 version:8;
+	u8 version;
 	/* octet 2 */
-	u32 priority:8;
+	u8 priority;
 	/* octet 3 */
 #if __BYTE_ORDER == __LITTLE_ENDIAN
-	u32 length:4;
-	u32 macsec_capbility:2;
-	u32 macsec_desired:1;
-	u32 key_server:1;
+	u8 length:4;
+	u8 macsec_capability:2;
+	u8 macsec_desired:1;
+	u8 key_server:1;
 #elif __BYTE_ORDER == __BIG_ENDIAN
-	u32 key_server:1;
-	u32 macsec_desired:1;
-	u32 macsec_capbility:2;
-	u32 length:4;
+	u8 key_server:1;
+	u8 macsec_desired:1;
+	u8 macsec_capability:2;
+	u8 length:4;
 #endif
 	/* octet 4 */
-	u32 length1:8;
+	u8 length1;
 
 	struct ieee802_1x_mka_sci actor_sci;
 	u8 actor_mi[MI_LEN];
@@ -291,19 +281,19 @@
 
 struct ieee802_1x_mka_peer_body {
 	/* octet 1 */
-	u32 type:8;
+	u8 type;
 	/* octet 2 */
-	u32 reserve:8;
+	u8 reserve;
 	/* octet 3 */
 #if __BYTE_ORDER == __LITTLE_ENDIAN
-	u32 length:4;
-	u32 reserve1:4;
+	u8 length:4;
+	u8 reserve1:4;
 #elif __BYTE_ORDER == __BIG_ENDIAN
-	u32 reserve1:4;
-	u32 length:4;
+	u8 reserve1:4;
+	u8 length:4;
 #endif
 	/* octet 4 */
-	u32 length1:8;
+	u8 length1;
 
 	u8 peer[0];
 	/* followed by Peers */
@@ -311,41 +301,41 @@
 
 struct ieee802_1x_mka_sak_use_body {
 	/* octet 1 */
-	u32 type:8;
+	u8 type;
 	/* octet 2 */
 #if __BYTE_ORDER == __LITTLE_ENDIAN
-	u32 orx:1;
-	u32 otx:1;
-	u32 oan:2;
-	u32 lrx:1;
-	u32 ltx:1;
-	u32 lan:2;
+	u8 orx:1;
+	u8 otx:1;
+	u8 oan:2;
+	u8 lrx:1;
+	u8 ltx:1;
+	u8 lan:2;
 #elif __BYTE_ORDER == __BIG_ENDIAN
-	u32 lan:2;
-	u32 ltx:1;
-	u32 lrx:1;
-	u32 oan:2;
-	u32 otx:1;
-	u32 orx:1;
+	u8 lan:2;
+	u8 ltx:1;
+	u8 lrx:1;
+	u8 oan:2;
+	u8 otx:1;
+	u8 orx:1;
 #endif
 
 	/* octet 3 */
 #if __BYTE_ORDER == __LITTLE_ENDIAN
-	u32 length:4;
-	u32 delay_protect:1;
-	u32 reserve:1;
-	u32 prx:1;
-	u32 ptx:1;
+	u8 length:4;
+	u8 delay_protect:1;
+	u8 reserve:1;
+	u8 prx:1;
+	u8 ptx:1;
 #elif __BYTE_ORDER == __BIG_ENDIAN
-	u32 ptx:1;
-	u32 prx:1;
-	u32 reserve:1;
-	u32 delay_protect:1;
-	u32 length:4;
+	u8 ptx:1;
+	u8 prx:1;
+	u8 reserve:1;
+	u8 delay_protect:1;
+	u8 length:4;
 #endif
 
 	/* octet 4 */
-	u32 length1:8;
+	u8 length1;
 
 	/* octet 5 - 16 */
 	u8 lsrv_mi[MI_LEN];
@@ -365,27 +355,27 @@
 
 struct ieee802_1x_mka_dist_sak_body {
 	/* octet 1 */
-	u32 type:8;
+	u8 type;
 	/* octet 2 */
 #if __BYTE_ORDER == __LITTLE_ENDIAN
-	u32 reserve:4;
-	u32 confid_offset:2;
-	u32 dan:2;
+	u8 reserve:4;
+	u8 confid_offset:2;
+	u8 dan:2;
 #elif __BYTE_ORDER == __BIG_ENDIAN
-	u32 dan:2;
-	u32 confid_offset:2;
-	u32 reserve:4;
+	u8 dan:2;
+	u8 confid_offset:2;
+	u8 reserve:4;
 #endif
 	/* octet 3 */
 #if __BYTE_ORDER == __LITTLE_ENDIAN
-	u32 length:4;
-	u32 reserve1:4;
+	u8 length:4;
+	u8 reserve1:4;
 #elif __BYTE_ORDER == __BIG_ENDIAN
-	u32 reserve1:4;
-	u32 length:4;
+	u8 reserve1:4;
+	u8 length:4;
 #endif
 	/* octet 4 */
-	u32 length1:8;
+	u8 length1;
 	/* octet 5 - 8 */
 	be32 kn;
 
@@ -398,19 +388,19 @@
 
 struct ieee802_1x_mka_icv_body {
 	/* octet 1 */
-	u32 type:8;
+	u8 type;
 	/* octet 2 */
-	u32 reserve:8;
+	u8 reserve;
 	/* octet 3 */
 #if __BYTE_ORDER == __LITTLE_ENDIAN
-	u32 length:4;
-	u32 reserve1:4;
+	u8 length:4;
+	u8 reserve1:4;
 #elif __BYTE_ORDER == __BIG_ENDIAN
-	u32 reserve1:4;
-	u32 length:4;
+	u8 reserve1:4;
+	u8 length:4;
 #endif
 	/* octet 4 */
-	u32 length1:8;
+	u8 length1;
 
 	/* octet 5 - */
 	u8 icv[0];
diff --git a/src/pae/ieee802_1x_secy_ops.c b/src/pae/ieee802_1x_secy_ops.c
index fbe05dc..2d12911 100644
--- a/src/pae/ieee802_1x_secy_ops.c
+++ b/src/pae/ieee802_1x_secy_ops.c
@@ -65,8 +65,7 @@
 }
 
 
-int secy_cp_control_current_cipher_suite(struct ieee802_1x_kay *kay,
-					 const u8 *cs, size_t cs_len)
+int secy_cp_control_current_cipher_suite(struct ieee802_1x_kay *kay, u64 cs)
 {
 	struct ieee802_1x_kay_ctx *ops;
 
@@ -82,7 +81,7 @@
 		return -1;
 	}
 
-	return ops->set_current_cipher_suite(ops->ctx, cs, cs_len);
+	return ops->set_current_cipher_suite(ops->ctx, cs);
 }
 
 
diff --git a/src/pae/ieee802_1x_secy_ops.h b/src/pae/ieee802_1x_secy_ops.h
index 295b823..f5057ee 100644
--- a/src/pae/ieee802_1x_secy_ops.h
+++ b/src/pae/ieee802_1x_secy_ops.h
@@ -26,8 +26,7 @@
 				    enum validate_frames vf);
 int secy_cp_control_protect_frames(struct ieee802_1x_kay *kay, Boolean flag);
 int secy_cp_control_replay(struct ieee802_1x_kay *kay, Boolean flag, u32 win);
-int secy_cp_control_current_cipher_suite(struct ieee802_1x_kay *kay,
-					 const u8 *cs, size_t cs_len);
+int secy_cp_control_current_cipher_suite(struct ieee802_1x_kay *kay, u64 cs);
 int secy_cp_control_confidentiality_offset(struct ieee802_1x_kay *kay,
 					   enum confidentiality_offset co);
 int secy_cp_control_enable_port(struct ieee802_1x_kay *kay, Boolean flag);
diff --git a/src/radius/radius_client.c b/src/radius/radius_client.c
index a4edd5f..06c804d 100644
--- a/src/radius/radius_client.c
+++ b/src/radius/radius_client.c
@@ -1636,11 +1636,16 @@
 int radius_client_get_mib(struct radius_client_data *radius, char *buf,
 			  size_t buflen)
 {
-	struct hostapd_radius_servers *conf = radius->conf;
+	struct hostapd_radius_servers *conf;
 	int i;
 	struct hostapd_radius_server *serv;
 	int count = 0;
 
+	if (!radius)
+		return 0;
+
+	conf = radius->conf;
+
 	if (conf->auth_servers) {
 		for (i = 0; i < conf->num_auth_servers; i++) {
 			serv = &conf->auth_servers[i];