Loading drivers/net/wireless/ath/wil6210/cfg80211.c +72 −0 Original line number Diff line number Diff line Loading @@ -150,13 +150,28 @@ enum wil_nl_60g_evt_type { NL_60G_EVT_FW_WMI, NL_60G_EVT_DRIVER_SHUTOWN, NL_60G_EVT_DRIVER_DEBUG_EVENT, NL_60G_EVT_DRIVER_GENERIC, }; enum wil_nl_60g_generic_evt { NL_60G_GEN_EVT_FW_STATE, }; struct wil_nl_60g_generic_event { /* NL_60G_EVT_DRIVER_GENERIC */ u32 evt_id; /* wil_nl_60g_generic_evt */ } __packed; struct wil_nl_60g_fw_state_event { struct wil_nl_60g_generic_event hdr; u32 fw_state; /* wil_fw_state */ } __packed; enum wil_nl_60g_debug_cmd { NL_60G_DBG_FORCE_WMI_SEND, NL_60G_GEN_RADAR_ALLOC_BUFFER, NL_60G_GEN_FW_RESET, NL_60G_GEN_GET_DRIVER_CAPA, NL_60G_GEN_GET_FW_STATE, }; struct wil_nl_60g_send_receive_wmi { Loading Loading @@ -3716,6 +3731,62 @@ static int wil_brp_set_ant_limit(struct wiphy *wiphy, struct wireless_dev *wdev, antenna_num_limit); } static void wil_nl_60g_fw_state_evt(struct wil6210_priv *wil) { struct sk_buff *vendor_event = NULL; struct wil_nl_60g_event *evt; struct wil_nl_60g_fw_state_event *fw_state_event; if (!wil->publish_nl_evt) return; wil_dbg_misc(wil, "report fw_state event to user-space (%d)\n", wil->fw_state); evt = kzalloc(sizeof(*evt) + sizeof(*fw_state_event), GFP_KERNEL); if (!evt) return; evt->evt_type = NL_60G_EVT_DRIVER_GENERIC; evt->buf_len = sizeof(*fw_state_event); fw_state_event = (struct wil_nl_60g_fw_state_event *)evt->buf; fw_state_event->hdr.evt_id = NL_60G_GEN_EVT_FW_STATE; fw_state_event->fw_state = wil->fw_state; vendor_event = cfg80211_vendor_event_alloc(wil_to_wiphy(wil), NULL, 4 + NLMSG_HDRLEN + sizeof(*evt) + sizeof(*fw_state_event), QCA_EVENT_UNSPEC_INDEX, GFP_KERNEL); if (!vendor_event) { wil_err(wil, "failed to allocate vendor_event\n"); goto out; } if (nla_put(vendor_event, WIL_ATTR_60G_BUF, sizeof(*evt) + sizeof(*fw_state_event), evt)) { wil_err(wil, "failed to fill WIL_ATTR_60G_BUF\n"); kfree_skb(vendor_event); goto out; } cfg80211_vendor_event(vendor_event, GFP_KERNEL); out: kfree(evt); } void wil_nl_60g_fw_state_change(struct wil6210_priv *wil, enum wil_fw_state fw_state) { wil_dbg_misc(wil, "fw_state change:%d => %d", wil->fw_state, fw_state); wil->fw_state = fw_state; wil_nl_60g_fw_state_evt(wil); } static int wil_nl_60g_handle_cmd(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int data_len) { Loading Loading @@ -3757,6 +3828,7 @@ static int wil_nl_60g_handle_cmd(struct wiphy *wiphy, struct wireless_dev *wdev, wil_dbg_wmi(wil, "Publish wmi event %s\n", publish ? "enabled" : "disabled"); wil_nl_60g_fw_state_evt(wil); break; case NL_60G_CMD_DEBUG: if (!tb[WIL_ATTR_60G_BUF]) { Loading drivers/net/wireless/ath/wil6210/main.c +10 −0 Original line number Diff line number Diff line Loading @@ -621,6 +621,12 @@ static void wil_fw_error_worker(struct work_struct *work) struct net_device *ndev = wil->main_ndev; wil_dbg_misc(wil, "fw error worker\n"); if (wil->fw_state == WIL_FW_STATE_READY) wil_nl_60g_fw_state_change(wil, WIL_FW_STATE_ERROR); else wil_nl_60g_fw_state_change(wil, WIL_FW_STATE_ERROR_BEFORE_READY); if (!ndev || !(ndev->flags & IFF_UP)) { wil_info(wil, "No recovery - interface is down\n"); Loading Loading @@ -798,6 +804,7 @@ int wil_priv_init(struct wil6210_priv *wil) wil->rx_buff_id_count = WIL_RX_BUFF_ARR_SIZE_DEFAULT; wil->amsdu_en = 1; wil->fw_state = WIL_FW_STATE_DOWN; return 0; Loading Loading @@ -1508,6 +1515,7 @@ static int wil_wait_for_fw_ready(struct wil6210_priv *wil) } else { wil_info(wil, "FW ready after %d ms. HW version 0x%08x\n", jiffies_to_msecs(to-left), wil->hw_version); wil_nl_60g_fw_state_change(wil, WIL_FW_STATE_READY); } return 0; } Loading Loading @@ -1703,6 +1711,7 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw) ether_addr_copy(ndev->perm_addr, mac); ether_addr_copy(ndev->dev_addr, ndev->perm_addr); wil->fw_state = WIL_FW_STATE_UNKNOWN; return 0; } Loading Loading @@ -1737,6 +1746,7 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw) rc); } wil_nl_60g_fw_state_change(wil, WIL_FW_STATE_DOWN); set_bit(wil_status_resetting, wil->status); mutex_lock(&wil->vif_mutex); wil_abort_scan_all_vifs(wil, false); Loading drivers/net/wireless/ath/wil6210/pcie_bus.c +7 −0 Original line number Diff line number Diff line Loading @@ -387,6 +387,13 @@ static int wil_platform_rop_notify(void *wil_handle, set_bit(wil_status_resetting, wil->status); set_bit(wil_status_pci_linkdown, wil->status); if (wil->fw_state == WIL_FW_STATE_READY) wil_nl_60g_fw_state_change(wil, WIL_FW_STATE_ERROR); else wil_nl_60g_fw_state_change(wil, WIL_FW_STATE_ERROR_BEFORE_READY); schedule_work(&wil->pci_linkdown_recovery_worker); break; default: Loading drivers/net/wireless/ath/wil6210/wil6210.h +15 −0 Original line number Diff line number Diff line Loading @@ -960,6 +960,17 @@ struct wil_ftm_offsets { unsigned int rx_offset; }; enum wil_fw_state { /* When driver loaded with debug_fw the FW state is unknown */ WIL_FW_STATE_UNKNOWN, WIL_FW_STATE_DOWN, /* FW not loaded or not ready yet */ WIL_FW_STATE_READY,/* FW is ready*/ /* Detected FW error before FW sent ready indication */ WIL_FW_STATE_ERROR_BEFORE_READY, /* Detected FW error after FW sent ready indication */ WIL_FW_STATE_ERROR, }; struct wil6210_priv { struct pci_dev *pdev; u32 bar_size; Loading Loading @@ -1124,6 +1135,7 @@ struct wil6210_priv { u32 max_agg_wsize; u32 max_ampdu_size; enum wil_fw_state fw_state; struct work_struct pci_linkdown_recovery_worker; void *ipa_handle; Loading Loading @@ -1387,6 +1399,9 @@ int wil_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, struct cfg80211_mgmt_tx_params *params, u64 *cookie); void wil_cfg80211_ap_recovery(struct wil6210_priv *wil); void wil_nl_60g_fw_state_change(struct wil6210_priv *wil, enum wil_fw_state fw_state); int wil_cfg80211_iface_combinations_from_fw( struct wil6210_priv *wil, const struct wil_fw_record_concurrency *conc); Loading Loading
drivers/net/wireless/ath/wil6210/cfg80211.c +72 −0 Original line number Diff line number Diff line Loading @@ -150,13 +150,28 @@ enum wil_nl_60g_evt_type { NL_60G_EVT_FW_WMI, NL_60G_EVT_DRIVER_SHUTOWN, NL_60G_EVT_DRIVER_DEBUG_EVENT, NL_60G_EVT_DRIVER_GENERIC, }; enum wil_nl_60g_generic_evt { NL_60G_GEN_EVT_FW_STATE, }; struct wil_nl_60g_generic_event { /* NL_60G_EVT_DRIVER_GENERIC */ u32 evt_id; /* wil_nl_60g_generic_evt */ } __packed; struct wil_nl_60g_fw_state_event { struct wil_nl_60g_generic_event hdr; u32 fw_state; /* wil_fw_state */ } __packed; enum wil_nl_60g_debug_cmd { NL_60G_DBG_FORCE_WMI_SEND, NL_60G_GEN_RADAR_ALLOC_BUFFER, NL_60G_GEN_FW_RESET, NL_60G_GEN_GET_DRIVER_CAPA, NL_60G_GEN_GET_FW_STATE, }; struct wil_nl_60g_send_receive_wmi { Loading Loading @@ -3716,6 +3731,62 @@ static int wil_brp_set_ant_limit(struct wiphy *wiphy, struct wireless_dev *wdev, antenna_num_limit); } static void wil_nl_60g_fw_state_evt(struct wil6210_priv *wil) { struct sk_buff *vendor_event = NULL; struct wil_nl_60g_event *evt; struct wil_nl_60g_fw_state_event *fw_state_event; if (!wil->publish_nl_evt) return; wil_dbg_misc(wil, "report fw_state event to user-space (%d)\n", wil->fw_state); evt = kzalloc(sizeof(*evt) + sizeof(*fw_state_event), GFP_KERNEL); if (!evt) return; evt->evt_type = NL_60G_EVT_DRIVER_GENERIC; evt->buf_len = sizeof(*fw_state_event); fw_state_event = (struct wil_nl_60g_fw_state_event *)evt->buf; fw_state_event->hdr.evt_id = NL_60G_GEN_EVT_FW_STATE; fw_state_event->fw_state = wil->fw_state; vendor_event = cfg80211_vendor_event_alloc(wil_to_wiphy(wil), NULL, 4 + NLMSG_HDRLEN + sizeof(*evt) + sizeof(*fw_state_event), QCA_EVENT_UNSPEC_INDEX, GFP_KERNEL); if (!vendor_event) { wil_err(wil, "failed to allocate vendor_event\n"); goto out; } if (nla_put(vendor_event, WIL_ATTR_60G_BUF, sizeof(*evt) + sizeof(*fw_state_event), evt)) { wil_err(wil, "failed to fill WIL_ATTR_60G_BUF\n"); kfree_skb(vendor_event); goto out; } cfg80211_vendor_event(vendor_event, GFP_KERNEL); out: kfree(evt); } void wil_nl_60g_fw_state_change(struct wil6210_priv *wil, enum wil_fw_state fw_state) { wil_dbg_misc(wil, "fw_state change:%d => %d", wil->fw_state, fw_state); wil->fw_state = fw_state; wil_nl_60g_fw_state_evt(wil); } static int wil_nl_60g_handle_cmd(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int data_len) { Loading Loading @@ -3757,6 +3828,7 @@ static int wil_nl_60g_handle_cmd(struct wiphy *wiphy, struct wireless_dev *wdev, wil_dbg_wmi(wil, "Publish wmi event %s\n", publish ? "enabled" : "disabled"); wil_nl_60g_fw_state_evt(wil); break; case NL_60G_CMD_DEBUG: if (!tb[WIL_ATTR_60G_BUF]) { Loading
drivers/net/wireless/ath/wil6210/main.c +10 −0 Original line number Diff line number Diff line Loading @@ -621,6 +621,12 @@ static void wil_fw_error_worker(struct work_struct *work) struct net_device *ndev = wil->main_ndev; wil_dbg_misc(wil, "fw error worker\n"); if (wil->fw_state == WIL_FW_STATE_READY) wil_nl_60g_fw_state_change(wil, WIL_FW_STATE_ERROR); else wil_nl_60g_fw_state_change(wil, WIL_FW_STATE_ERROR_BEFORE_READY); if (!ndev || !(ndev->flags & IFF_UP)) { wil_info(wil, "No recovery - interface is down\n"); Loading Loading @@ -798,6 +804,7 @@ int wil_priv_init(struct wil6210_priv *wil) wil->rx_buff_id_count = WIL_RX_BUFF_ARR_SIZE_DEFAULT; wil->amsdu_en = 1; wil->fw_state = WIL_FW_STATE_DOWN; return 0; Loading Loading @@ -1508,6 +1515,7 @@ static int wil_wait_for_fw_ready(struct wil6210_priv *wil) } else { wil_info(wil, "FW ready after %d ms. HW version 0x%08x\n", jiffies_to_msecs(to-left), wil->hw_version); wil_nl_60g_fw_state_change(wil, WIL_FW_STATE_READY); } return 0; } Loading Loading @@ -1703,6 +1711,7 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw) ether_addr_copy(ndev->perm_addr, mac); ether_addr_copy(ndev->dev_addr, ndev->perm_addr); wil->fw_state = WIL_FW_STATE_UNKNOWN; return 0; } Loading Loading @@ -1737,6 +1746,7 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw) rc); } wil_nl_60g_fw_state_change(wil, WIL_FW_STATE_DOWN); set_bit(wil_status_resetting, wil->status); mutex_lock(&wil->vif_mutex); wil_abort_scan_all_vifs(wil, false); Loading
drivers/net/wireless/ath/wil6210/pcie_bus.c +7 −0 Original line number Diff line number Diff line Loading @@ -387,6 +387,13 @@ static int wil_platform_rop_notify(void *wil_handle, set_bit(wil_status_resetting, wil->status); set_bit(wil_status_pci_linkdown, wil->status); if (wil->fw_state == WIL_FW_STATE_READY) wil_nl_60g_fw_state_change(wil, WIL_FW_STATE_ERROR); else wil_nl_60g_fw_state_change(wil, WIL_FW_STATE_ERROR_BEFORE_READY); schedule_work(&wil->pci_linkdown_recovery_worker); break; default: Loading
drivers/net/wireless/ath/wil6210/wil6210.h +15 −0 Original line number Diff line number Diff line Loading @@ -960,6 +960,17 @@ struct wil_ftm_offsets { unsigned int rx_offset; }; enum wil_fw_state { /* When driver loaded with debug_fw the FW state is unknown */ WIL_FW_STATE_UNKNOWN, WIL_FW_STATE_DOWN, /* FW not loaded or not ready yet */ WIL_FW_STATE_READY,/* FW is ready*/ /* Detected FW error before FW sent ready indication */ WIL_FW_STATE_ERROR_BEFORE_READY, /* Detected FW error after FW sent ready indication */ WIL_FW_STATE_ERROR, }; struct wil6210_priv { struct pci_dev *pdev; u32 bar_size; Loading Loading @@ -1124,6 +1135,7 @@ struct wil6210_priv { u32 max_agg_wsize; u32 max_ampdu_size; enum wil_fw_state fw_state; struct work_struct pci_linkdown_recovery_worker; void *ipa_handle; Loading Loading @@ -1387,6 +1399,9 @@ int wil_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, struct cfg80211_mgmt_tx_params *params, u64 *cookie); void wil_cfg80211_ap_recovery(struct wil6210_priv *wil); void wil_nl_60g_fw_state_change(struct wil6210_priv *wil, enum wil_fw_state fw_state); int wil_cfg80211_iface_combinations_from_fw( struct wil6210_priv *wil, const struct wil_fw_record_concurrency *conc); Loading