Loading drivers/net/wireless/ath/wil6210/cfg80211.c +14 −1 Original line number Diff line number Diff line Loading @@ -530,6 +530,8 @@ static const char * const key_usage_str[] = { [WMI_KEY_USE_PAIRWISE] = "PTK", [WMI_KEY_USE_RX_GROUP] = "RX_GTK", [WMI_KEY_USE_TX_GROUP] = "TX_GTK", [WMI_KEY_USE_STORE_PTK] = "STORE_PTK", [WMI_KEY_USE_APPLY_PTK] = "APPLY_PTK", }; int wil_iftype_nl2wmi(enum nl80211_iftype type) Loading Loading @@ -741,7 +743,7 @@ static int wil_cfg80211_get_station(struct wiphy *wiphy, /* * Find @idx-th active STA for specific MID for station dump. */ static int wil_find_cid_by_idx(struct wil6210_priv *wil, u8 mid, int idx) int wil_find_cid_by_idx(struct wil6210_priv *wil, u8 mid, int idx) { int i; Loading Loading @@ -1781,6 +1783,7 @@ void wil_set_crypto_rx(u8 key_index, enum wmi_key_usage key_usage, return; switch (key_usage) { case WMI_KEY_USE_STORE_PTK: case WMI_KEY_USE_PAIRWISE: for (tid = 0; tid < WIL_STA_TID_NUM; tid++) { cc = &cs->tid_crypto_rx[tid].key_id[key_index]; Loading Loading @@ -1878,6 +1881,16 @@ static int wil_cfg80211_add_key(struct wiphy *wiphy, return -EINVAL; } spin_lock_bh(&wil->eap_lock); if (pairwise && wdev->iftype == NL80211_IFTYPE_STATION && (vif->ptk_rekey_state == WIL_REKEY_M3_RECEIVED || vif->ptk_rekey_state == WIL_REKEY_WAIT_M4_SENT)) { key_usage = WMI_KEY_USE_STORE_PTK; vif->ptk_rekey_state = WIL_REKEY_WAIT_M4_SENT; wil_dbg_misc(wil, "Store EAPOL key\n"); } spin_unlock_bh(&wil->eap_lock); rc = wmi_add_cipher_key(vif, key_index, mac_addr, params->key_len, params->key, key_usage); if (!rc && !IS_ERR(cs)) { Loading drivers/net/wireless/ath/wil6210/main.c +4 −0 Original line number Diff line number Diff line Loading @@ -378,6 +378,7 @@ static void _wil6210_disconnect_complete(struct wil6210_vif *vif, } clear_bit(wil_vif_fwconnecting, vif->status); clear_bit(wil_vif_ft_roam, vif->status); vif->ptk_rekey_state = WIL_REKEY_IDLE; break; case NL80211_IFTYPE_AP: Loading Loading @@ -749,6 +750,8 @@ int wil_priv_init(struct wil6210_priv *wil) INIT_LIST_HEAD(&wil->pending_wmi_ev); spin_lock_init(&wil->wmi_ev_lock); spin_lock_init(&wil->net_queue_lock); spin_lock_init(&wil->eap_lock); init_waitqueue_head(&wil->wq); init_rwsem(&wil->mem_lock); Loading Loading @@ -1745,6 +1748,7 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw) cancel_work_sync(&vif->disconnect_worker); wil6210_disconnect(vif, NULL, WLAN_REASON_DEAUTH_LEAVING); vif->ptk_rekey_state = WIL_REKEY_IDLE; } } wil_bcast_fini_all(wil); Loading drivers/net/wireless/ath/wil6210/netdev.c +3 −0 Original line number Diff line number Diff line Loading @@ -276,6 +276,7 @@ static void wil_vif_deinit(struct wil6210_vif *vif) cancel_work_sync(&vif->p2p.delayed_listen_work); wil_probe_client_flush(vif); cancel_work_sync(&vif->probe_client_worker); cancel_work_sync(&vif->enable_tx_key_worker); } void wil_vif_free(struct wil6210_vif *vif) Loading Loading @@ -343,6 +344,7 @@ static void wil_vif_init(struct wil6210_vif *vif) INIT_WORK(&vif->disconnect_worker, wil_disconnect_worker); INIT_WORK(&vif->p2p.discovery_expired_work, wil_p2p_listen_expired); INIT_WORK(&vif->p2p.delayed_listen_work, wil_p2p_delayed_listen_work); INIT_WORK(&vif->enable_tx_key_worker, wil_enable_tx_key_worker); INIT_LIST_HEAD(&vif->probe_client_pending); Loading Loading @@ -613,6 +615,7 @@ void wil_vif_remove(struct wil6210_priv *wil, u8 mid) cancel_work_sync(&vif->disconnect_worker); wil_probe_client_flush(vif); cancel_work_sync(&vif->probe_client_worker); cancel_work_sync(&vif->enable_tx_key_worker); /* for VIFs, ndev will be freed by destructor after RTNL is unlocked. * the main interface will be freed in wil_if_free, we need to keep it * a bit longer so logging macros will work. Loading drivers/net/wireless/ath/wil6210/txrx.c +184 −0 Original line number Diff line number Diff line Loading @@ -738,6 +738,182 @@ static void wil_get_netif_rx_params(struct sk_buff *skb, int *cid, *security = wil_rxdesc_security(d); } /* * Check if skb is ptk eapol key message * * returns a pointer to the start of the eapol key structure, NULL * if frame is not PTK eapol key */ static struct wil_eapol_key *wil_is_ptk_eapol_key(struct wil6210_priv *wil, struct sk_buff *skb) { u8 *buf; const struct wil_1x_hdr *hdr; struct wil_eapol_key *key; u16 key_info; int len = skb->len; if (!skb_mac_header_was_set(skb)) { wil_err(wil, "mac header was not set\n"); return NULL; } len -= skb_mac_offset(skb); if (len < sizeof(struct ethhdr) + sizeof(struct wil_1x_hdr) + sizeof(struct wil_eapol_key)) return NULL; buf = skb_mac_header(skb) + sizeof(struct ethhdr); hdr = (const struct wil_1x_hdr *)buf; if (hdr->type != WIL_1X_TYPE_EAPOL_KEY) return NULL; key = (struct wil_eapol_key *)(buf + sizeof(struct wil_1x_hdr)); if (key->type != WIL_EAPOL_KEY_TYPE_WPA && key->type != WIL_EAPOL_KEY_TYPE_RSN) return NULL; key_info = be16_to_cpu(key->key_info); if (!(key_info & WIL_KEY_INFO_KEY_TYPE)) /* check if pairwise */ return NULL; return key; } static bool wil_skb_is_eap_3(struct wil6210_priv *wil, struct sk_buff *skb) { struct wil_eapol_key *key; u16 key_info; key = wil_is_ptk_eapol_key(wil, skb); if (!key) return false; key_info = be16_to_cpu(key->key_info); if (key_info & (WIL_KEY_INFO_MIC | WIL_KEY_INFO_ENCR_KEY_DATA)) { /* 3/4 of 4-Way Handshake */ wil_dbg_misc(wil, "EAPOL key message 3\n"); return true; } /* 1/4 of 4-Way Handshake */ wil_dbg_misc(wil, "EAPOL key message 1\n"); return false; } static bool wil_skb_is_eap_4(struct wil6210_priv *wil, struct sk_buff *skb) { struct wil_eapol_key *key; u32 *nonce, i; key = wil_is_ptk_eapol_key(wil, skb); if (!key) return false; nonce = (u32 *)key->key_nonce; for (i = 0; i < WIL_EAP_NONCE_LEN / sizeof(u32); i++, nonce++) { if (*nonce != 0) { /* message 2/4 */ wil_dbg_misc(wil, "EAPOL key message 2\n"); return false; } } wil_dbg_misc(wil, "EAPOL key message 4\n"); return true; } void wil_enable_tx_key_worker(struct work_struct *work) { struct wil6210_vif *vif = container_of(work, struct wil6210_vif, enable_tx_key_worker); struct wil6210_priv *wil = vif_to_wil(vif); int rc, cid; rtnl_lock(); if (vif->ptk_rekey_state != WIL_REKEY_WAIT_M4_SENT) { wil_dbg_misc(wil, "Invalid rekey state = %d\n", vif->ptk_rekey_state); rtnl_unlock(); return; } cid = wil_find_cid_by_idx(wil, vif->mid, 0); if (!wil_cid_valid(cid)) { wil_err(wil, "Invalid cid = %d\n", cid); rtnl_unlock(); return; } wil_dbg_misc(wil, "Apply PTK key after eapol was sent out\n"); rc = wmi_add_cipher_key(vif, 0, wil->sta[cid].addr, 0, NULL, WMI_KEY_USE_APPLY_PTK); vif->ptk_rekey_state = WIL_REKEY_IDLE; rtnl_unlock(); if (rc) wil_err(wil, "Apply PTK key failed %d\n", rc); } void wil_tx_complete_handle_eapol(struct wil6210_vif *vif, struct sk_buff *skb) { struct wil6210_priv *wil = vif_to_wil(vif); struct wireless_dev *wdev = vif_to_wdev(vif); bool q = false; if (wdev->iftype != NL80211_IFTYPE_STATION || !test_bit(WMI_FW_CAPABILITY_SPLIT_REKEY, wil->fw_capabilities)) return; /* check if skb is an EAP message 4/4 */ if (!wil_skb_is_eap_4(wil, skb)) return; spin_lock_bh(&wil->eap_lock); switch (vif->ptk_rekey_state) { case WIL_REKEY_IDLE: /* ignore idle state, can happen due to M4 retransmission */ break; case WIL_REKEY_M3_RECEIVED: vif->ptk_rekey_state = WIL_REKEY_IDLE; break; case WIL_REKEY_WAIT_M4_SENT: q = true; break; default: wil_err(wil, "Unknown rekey state = %d", vif->ptk_rekey_state); } spin_unlock_bh(&wil->eap_lock); if (q) { q = queue_work(wil->wmi_wq, &vif->enable_tx_key_worker); wil_dbg_misc(wil, "queue_work of enable_tx_key_worker -> %d\n", q); } } static void wil_rx_handle_eapol(struct wil6210_vif *vif, struct sk_buff *skb) { struct wil6210_priv *wil = vif_to_wil(vif); struct wireless_dev *wdev = vif_to_wdev(vif); if (wdev->iftype != NL80211_IFTYPE_STATION || !test_bit(WMI_FW_CAPABILITY_SPLIT_REKEY, wil->fw_capabilities)) return; /* check if skb is a EAP message 3/4 */ if (!wil_skb_is_eap_3(wil, skb)) return; if (vif->ptk_rekey_state == WIL_REKEY_IDLE) vif->ptk_rekey_state = WIL_REKEY_M3_RECEIVED; } /* * Pass Rx packet to the netif. Update statistics. * Called in softirq context (NAPI poll). Loading Loading @@ -810,6 +986,10 @@ void wil_netif_rx(struct sk_buff *skb, struct net_device *ndev, int cid, if (skb) { /* deliver to local stack */ skb->protocol = eth_type_trans(skb, ndev); skb->dev = ndev; if (skb->protocol == cpu_to_be16(ETH_P_PAE)) wil_rx_handle_eapol(vif, skb); if (gro) rc = napi_gro_receive(&wil->napi_rx, skb); else Loading Loading @@ -2408,6 +2588,10 @@ int wil_tx_complete(struct wil6210_vif *vif, int ringid) if (stats) stats->tx_errors++; } if (skb->protocol == cpu_to_be16(ETH_P_PAE)) wil_tx_complete_handle_eapol(vif, skb); wil_consume_skb(skb, d->dma.error == 0); } memset(ctx, 0, sizeof(*ctx)); Loading drivers/net/wireless/ath/wil6210/txrx.h +40 −0 Original line number Diff line number Diff line Loading @@ -412,6 +412,46 @@ struct vring_rx_mac { #define RX_DMA_STATUS_PHY_INFO BIT(6) #define RX_DMA_STATUS_FFM BIT(7) /* EtherType Flex Filter Match */ /* IEEE 802.11, 8.5.2 EAPOL-Key frames */ #define WIL_KEY_INFO_KEY_TYPE BIT(3) /* val of 1 = Pairwise, 0 = Group key */ #define WIL_KEY_INFO_MIC BIT(8) #define WIL_KEY_INFO_ENCR_KEY_DATA BIT(12) /* for rsn only */ #define WIL_EAP_NONCE_LEN 32 #define WIL_EAP_KEY_RSC_LEN 8 #define WIL_EAP_REPLAY_COUNTER_LEN 8 #define WIL_EAP_KEY_IV_LEN 16 #define WIL_EAP_KEY_ID_LEN 8 enum { WIL_1X_TYPE_EAP_PACKET = 0, WIL_1X_TYPE_EAPOL_START = 1, WIL_1X_TYPE_EAPOL_LOGOFF = 2, WIL_1X_TYPE_EAPOL_KEY = 3, }; #define WIL_EAPOL_KEY_TYPE_RSN 2 #define WIL_EAPOL_KEY_TYPE_WPA 254 struct wil_1x_hdr { u8 version; u8 type; __be16 length; /* followed by data */ } __packed; struct wil_eapol_key { u8 type; __be16 key_info; __be16 key_length; u8 replay_counter[WIL_EAP_REPLAY_COUNTER_LEN]; u8 key_nonce[WIL_EAP_NONCE_LEN]; u8 key_iv[WIL_EAP_KEY_IV_LEN]; u8 key_rsc[WIL_EAP_KEY_RSC_LEN]; u8 key_id[WIL_EAP_KEY_ID_LEN]; } __packed; struct vring_rx_dma { u32 d0; struct wil_ring_dma_addr addr; Loading Loading
drivers/net/wireless/ath/wil6210/cfg80211.c +14 −1 Original line number Diff line number Diff line Loading @@ -530,6 +530,8 @@ static const char * const key_usage_str[] = { [WMI_KEY_USE_PAIRWISE] = "PTK", [WMI_KEY_USE_RX_GROUP] = "RX_GTK", [WMI_KEY_USE_TX_GROUP] = "TX_GTK", [WMI_KEY_USE_STORE_PTK] = "STORE_PTK", [WMI_KEY_USE_APPLY_PTK] = "APPLY_PTK", }; int wil_iftype_nl2wmi(enum nl80211_iftype type) Loading Loading @@ -741,7 +743,7 @@ static int wil_cfg80211_get_station(struct wiphy *wiphy, /* * Find @idx-th active STA for specific MID for station dump. */ static int wil_find_cid_by_idx(struct wil6210_priv *wil, u8 mid, int idx) int wil_find_cid_by_idx(struct wil6210_priv *wil, u8 mid, int idx) { int i; Loading Loading @@ -1781,6 +1783,7 @@ void wil_set_crypto_rx(u8 key_index, enum wmi_key_usage key_usage, return; switch (key_usage) { case WMI_KEY_USE_STORE_PTK: case WMI_KEY_USE_PAIRWISE: for (tid = 0; tid < WIL_STA_TID_NUM; tid++) { cc = &cs->tid_crypto_rx[tid].key_id[key_index]; Loading Loading @@ -1878,6 +1881,16 @@ static int wil_cfg80211_add_key(struct wiphy *wiphy, return -EINVAL; } spin_lock_bh(&wil->eap_lock); if (pairwise && wdev->iftype == NL80211_IFTYPE_STATION && (vif->ptk_rekey_state == WIL_REKEY_M3_RECEIVED || vif->ptk_rekey_state == WIL_REKEY_WAIT_M4_SENT)) { key_usage = WMI_KEY_USE_STORE_PTK; vif->ptk_rekey_state = WIL_REKEY_WAIT_M4_SENT; wil_dbg_misc(wil, "Store EAPOL key\n"); } spin_unlock_bh(&wil->eap_lock); rc = wmi_add_cipher_key(vif, key_index, mac_addr, params->key_len, params->key, key_usage); if (!rc && !IS_ERR(cs)) { Loading
drivers/net/wireless/ath/wil6210/main.c +4 −0 Original line number Diff line number Diff line Loading @@ -378,6 +378,7 @@ static void _wil6210_disconnect_complete(struct wil6210_vif *vif, } clear_bit(wil_vif_fwconnecting, vif->status); clear_bit(wil_vif_ft_roam, vif->status); vif->ptk_rekey_state = WIL_REKEY_IDLE; break; case NL80211_IFTYPE_AP: Loading Loading @@ -749,6 +750,8 @@ int wil_priv_init(struct wil6210_priv *wil) INIT_LIST_HEAD(&wil->pending_wmi_ev); spin_lock_init(&wil->wmi_ev_lock); spin_lock_init(&wil->net_queue_lock); spin_lock_init(&wil->eap_lock); init_waitqueue_head(&wil->wq); init_rwsem(&wil->mem_lock); Loading Loading @@ -1745,6 +1748,7 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw) cancel_work_sync(&vif->disconnect_worker); wil6210_disconnect(vif, NULL, WLAN_REASON_DEAUTH_LEAVING); vif->ptk_rekey_state = WIL_REKEY_IDLE; } } wil_bcast_fini_all(wil); Loading
drivers/net/wireless/ath/wil6210/netdev.c +3 −0 Original line number Diff line number Diff line Loading @@ -276,6 +276,7 @@ static void wil_vif_deinit(struct wil6210_vif *vif) cancel_work_sync(&vif->p2p.delayed_listen_work); wil_probe_client_flush(vif); cancel_work_sync(&vif->probe_client_worker); cancel_work_sync(&vif->enable_tx_key_worker); } void wil_vif_free(struct wil6210_vif *vif) Loading Loading @@ -343,6 +344,7 @@ static void wil_vif_init(struct wil6210_vif *vif) INIT_WORK(&vif->disconnect_worker, wil_disconnect_worker); INIT_WORK(&vif->p2p.discovery_expired_work, wil_p2p_listen_expired); INIT_WORK(&vif->p2p.delayed_listen_work, wil_p2p_delayed_listen_work); INIT_WORK(&vif->enable_tx_key_worker, wil_enable_tx_key_worker); INIT_LIST_HEAD(&vif->probe_client_pending); Loading Loading @@ -613,6 +615,7 @@ void wil_vif_remove(struct wil6210_priv *wil, u8 mid) cancel_work_sync(&vif->disconnect_worker); wil_probe_client_flush(vif); cancel_work_sync(&vif->probe_client_worker); cancel_work_sync(&vif->enable_tx_key_worker); /* for VIFs, ndev will be freed by destructor after RTNL is unlocked. * the main interface will be freed in wil_if_free, we need to keep it * a bit longer so logging macros will work. Loading
drivers/net/wireless/ath/wil6210/txrx.c +184 −0 Original line number Diff line number Diff line Loading @@ -738,6 +738,182 @@ static void wil_get_netif_rx_params(struct sk_buff *skb, int *cid, *security = wil_rxdesc_security(d); } /* * Check if skb is ptk eapol key message * * returns a pointer to the start of the eapol key structure, NULL * if frame is not PTK eapol key */ static struct wil_eapol_key *wil_is_ptk_eapol_key(struct wil6210_priv *wil, struct sk_buff *skb) { u8 *buf; const struct wil_1x_hdr *hdr; struct wil_eapol_key *key; u16 key_info; int len = skb->len; if (!skb_mac_header_was_set(skb)) { wil_err(wil, "mac header was not set\n"); return NULL; } len -= skb_mac_offset(skb); if (len < sizeof(struct ethhdr) + sizeof(struct wil_1x_hdr) + sizeof(struct wil_eapol_key)) return NULL; buf = skb_mac_header(skb) + sizeof(struct ethhdr); hdr = (const struct wil_1x_hdr *)buf; if (hdr->type != WIL_1X_TYPE_EAPOL_KEY) return NULL; key = (struct wil_eapol_key *)(buf + sizeof(struct wil_1x_hdr)); if (key->type != WIL_EAPOL_KEY_TYPE_WPA && key->type != WIL_EAPOL_KEY_TYPE_RSN) return NULL; key_info = be16_to_cpu(key->key_info); if (!(key_info & WIL_KEY_INFO_KEY_TYPE)) /* check if pairwise */ return NULL; return key; } static bool wil_skb_is_eap_3(struct wil6210_priv *wil, struct sk_buff *skb) { struct wil_eapol_key *key; u16 key_info; key = wil_is_ptk_eapol_key(wil, skb); if (!key) return false; key_info = be16_to_cpu(key->key_info); if (key_info & (WIL_KEY_INFO_MIC | WIL_KEY_INFO_ENCR_KEY_DATA)) { /* 3/4 of 4-Way Handshake */ wil_dbg_misc(wil, "EAPOL key message 3\n"); return true; } /* 1/4 of 4-Way Handshake */ wil_dbg_misc(wil, "EAPOL key message 1\n"); return false; } static bool wil_skb_is_eap_4(struct wil6210_priv *wil, struct sk_buff *skb) { struct wil_eapol_key *key; u32 *nonce, i; key = wil_is_ptk_eapol_key(wil, skb); if (!key) return false; nonce = (u32 *)key->key_nonce; for (i = 0; i < WIL_EAP_NONCE_LEN / sizeof(u32); i++, nonce++) { if (*nonce != 0) { /* message 2/4 */ wil_dbg_misc(wil, "EAPOL key message 2\n"); return false; } } wil_dbg_misc(wil, "EAPOL key message 4\n"); return true; } void wil_enable_tx_key_worker(struct work_struct *work) { struct wil6210_vif *vif = container_of(work, struct wil6210_vif, enable_tx_key_worker); struct wil6210_priv *wil = vif_to_wil(vif); int rc, cid; rtnl_lock(); if (vif->ptk_rekey_state != WIL_REKEY_WAIT_M4_SENT) { wil_dbg_misc(wil, "Invalid rekey state = %d\n", vif->ptk_rekey_state); rtnl_unlock(); return; } cid = wil_find_cid_by_idx(wil, vif->mid, 0); if (!wil_cid_valid(cid)) { wil_err(wil, "Invalid cid = %d\n", cid); rtnl_unlock(); return; } wil_dbg_misc(wil, "Apply PTK key after eapol was sent out\n"); rc = wmi_add_cipher_key(vif, 0, wil->sta[cid].addr, 0, NULL, WMI_KEY_USE_APPLY_PTK); vif->ptk_rekey_state = WIL_REKEY_IDLE; rtnl_unlock(); if (rc) wil_err(wil, "Apply PTK key failed %d\n", rc); } void wil_tx_complete_handle_eapol(struct wil6210_vif *vif, struct sk_buff *skb) { struct wil6210_priv *wil = vif_to_wil(vif); struct wireless_dev *wdev = vif_to_wdev(vif); bool q = false; if (wdev->iftype != NL80211_IFTYPE_STATION || !test_bit(WMI_FW_CAPABILITY_SPLIT_REKEY, wil->fw_capabilities)) return; /* check if skb is an EAP message 4/4 */ if (!wil_skb_is_eap_4(wil, skb)) return; spin_lock_bh(&wil->eap_lock); switch (vif->ptk_rekey_state) { case WIL_REKEY_IDLE: /* ignore idle state, can happen due to M4 retransmission */ break; case WIL_REKEY_M3_RECEIVED: vif->ptk_rekey_state = WIL_REKEY_IDLE; break; case WIL_REKEY_WAIT_M4_SENT: q = true; break; default: wil_err(wil, "Unknown rekey state = %d", vif->ptk_rekey_state); } spin_unlock_bh(&wil->eap_lock); if (q) { q = queue_work(wil->wmi_wq, &vif->enable_tx_key_worker); wil_dbg_misc(wil, "queue_work of enable_tx_key_worker -> %d\n", q); } } static void wil_rx_handle_eapol(struct wil6210_vif *vif, struct sk_buff *skb) { struct wil6210_priv *wil = vif_to_wil(vif); struct wireless_dev *wdev = vif_to_wdev(vif); if (wdev->iftype != NL80211_IFTYPE_STATION || !test_bit(WMI_FW_CAPABILITY_SPLIT_REKEY, wil->fw_capabilities)) return; /* check if skb is a EAP message 3/4 */ if (!wil_skb_is_eap_3(wil, skb)) return; if (vif->ptk_rekey_state == WIL_REKEY_IDLE) vif->ptk_rekey_state = WIL_REKEY_M3_RECEIVED; } /* * Pass Rx packet to the netif. Update statistics. * Called in softirq context (NAPI poll). Loading Loading @@ -810,6 +986,10 @@ void wil_netif_rx(struct sk_buff *skb, struct net_device *ndev, int cid, if (skb) { /* deliver to local stack */ skb->protocol = eth_type_trans(skb, ndev); skb->dev = ndev; if (skb->protocol == cpu_to_be16(ETH_P_PAE)) wil_rx_handle_eapol(vif, skb); if (gro) rc = napi_gro_receive(&wil->napi_rx, skb); else Loading Loading @@ -2408,6 +2588,10 @@ int wil_tx_complete(struct wil6210_vif *vif, int ringid) if (stats) stats->tx_errors++; } if (skb->protocol == cpu_to_be16(ETH_P_PAE)) wil_tx_complete_handle_eapol(vif, skb); wil_consume_skb(skb, d->dma.error == 0); } memset(ctx, 0, sizeof(*ctx)); Loading
drivers/net/wireless/ath/wil6210/txrx.h +40 −0 Original line number Diff line number Diff line Loading @@ -412,6 +412,46 @@ struct vring_rx_mac { #define RX_DMA_STATUS_PHY_INFO BIT(6) #define RX_DMA_STATUS_FFM BIT(7) /* EtherType Flex Filter Match */ /* IEEE 802.11, 8.5.2 EAPOL-Key frames */ #define WIL_KEY_INFO_KEY_TYPE BIT(3) /* val of 1 = Pairwise, 0 = Group key */ #define WIL_KEY_INFO_MIC BIT(8) #define WIL_KEY_INFO_ENCR_KEY_DATA BIT(12) /* for rsn only */ #define WIL_EAP_NONCE_LEN 32 #define WIL_EAP_KEY_RSC_LEN 8 #define WIL_EAP_REPLAY_COUNTER_LEN 8 #define WIL_EAP_KEY_IV_LEN 16 #define WIL_EAP_KEY_ID_LEN 8 enum { WIL_1X_TYPE_EAP_PACKET = 0, WIL_1X_TYPE_EAPOL_START = 1, WIL_1X_TYPE_EAPOL_LOGOFF = 2, WIL_1X_TYPE_EAPOL_KEY = 3, }; #define WIL_EAPOL_KEY_TYPE_RSN 2 #define WIL_EAPOL_KEY_TYPE_WPA 254 struct wil_1x_hdr { u8 version; u8 type; __be16 length; /* followed by data */ } __packed; struct wil_eapol_key { u8 type; __be16 key_info; __be16 key_length; u8 replay_counter[WIL_EAP_REPLAY_COUNTER_LEN]; u8 key_nonce[WIL_EAP_NONCE_LEN]; u8 key_iv[WIL_EAP_KEY_IV_LEN]; u8 key_rsc[WIL_EAP_KEY_RSC_LEN]; u8 key_id[WIL_EAP_KEY_ID_LEN]; } __packed; struct vring_rx_dma { u32 d0; struct wil_ring_dma_addr addr; Loading