From ce4022edaa668d65f3201835bd00b0e66e893128 Mon Sep 17 00:00:00 2001 From: Maya Erez Date: Tue, 30 Apr 2019 18:53:45 +0300 Subject: [PATCH 1/4] wil6210: add support for sensing over SPI Add new module param (support_sensing_over_spi) to notify FW to enable SPI for sensing. The device will handle the sensing data in parallel to the networking data. Change-Id: Ib6638096318016295e631cd0ffbeaf49ed08bda0 Signed-off-by: Maya Erez --- drivers/net/wireless/ath/wil6210/main.c | 13 +++++++++++++ drivers/net/wireless/ath/wil6210/wil6210.h | 1 + 2 files changed, 14 insertions(+) diff --git a/drivers/net/wireless/ath/wil6210/main.c b/drivers/net/wireless/ath/wil6210/main.c index 9ccfe43d8cec..54261a820ead 100644 --- a/drivers/net/wireless/ath/wil6210/main.c +++ b/drivers/net/wireless/ath/wil6210/main.c @@ -104,6 +104,11 @@ MODULE_PARM_DESC(tx_ring_order, " Tx ring order; size = 1 << order"); module_param_cb(bcast_ring_order, &ring_order_ops, &bcast_ring_order, 0444); MODULE_PARM_DESC(bcast_ring_order, " Bcast ring order; size = 1 << order"); +static u8 support_sensing_over_spi; +module_param(support_sensing_over_spi, byte, 0444); +MODULE_PARM_DESC(support_sensing_over_spi, + " notify FW to enable SPI for sensing"); + enum { WIL_BOOT_ERR, WIL_BOOT_VANILLA, @@ -1675,6 +1680,14 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw) wil_s(wil, RGF_USER_USAGE_8, BIT_USER_EXT_CLK); } + if (support_sensing_over_spi) { + wil_dbg_misc(wil, "notify FW to enable SPI for sensing\n"); + wil_s(wil, RGF_USER_USAGE_6, BIT_SPI_SENSING_SUPPORT); + } else { + wil_dbg_misc(wil, "notify FW to disable SPI for sensing\n"); + wil_c(wil, RGF_USER_USAGE_6, BIT_SPI_SENSING_SUPPORT); + } + if (wil->platform_ops.notify) { rc = wil->platform_ops.notify(wil->platform_handle, WIL_PLATFORM_EVT_PRE_RESET); diff --git a/drivers/net/wireless/ath/wil6210/wil6210.h b/drivers/net/wireless/ath/wil6210/wil6210.h index f4022c780302..a074fac5f082 100644 --- a/drivers/net/wireless/ath/wil6210/wil6210.h +++ b/drivers/net/wireless/ath/wil6210/wil6210.h @@ -181,6 +181,7 @@ struct RGF_ICR { #define RGF_USER_USAGE_1 (0x880004) #define RGF_USER_USAGE_2 (0x880008) #define RGF_USER_USAGE_6 (0x880018) + #define BIT_SPI_SENSING_SUPPORT BIT(28) #define BIT_USER_OOB_MODE BIT(31) #define BIT_USER_OOB_R2_MODE BIT(30) #define RGF_USER_USAGE_8 (0x880020) From 4c846aaf943c59e627f7669599dcaf43c4249fbf Mon Sep 17 00:00:00 2001 From: Ahmad Masri Date: Wed, 4 Dec 2019 11:24:37 +0200 Subject: [PATCH 2/4] wil6210: support VR profiles Allow wil6210 to configure the system in Virtual Reality (VR) mode. When system is in VR mode it should have a low latency, and a high responsive to events in the system. Wil6210 will set the rx interrupt moderation to lower threshold and will drop packets when the transmit queue is full. Disallow changing power save profile while in VR mode. New sysfs "vr_profile" can be used by userspace to enable and set VR profile. WMI_SET_VR_PROFILE_CMDID is used to configure the FW into different VR profile configurations. Change-Id: If9e0a5eb3323f1479d76b259c848310508e7009c Signed-off-by: Ahmad Masri Signed-off-by: Dedy Lansky Signed-off-by: Alexei Avshalom Lazar --- drivers/net/wireless/ath/wil6210/cfg80211.c | 4 ++ drivers/net/wireless/ath/wil6210/main.c | 38 +++++++++++++++ drivers/net/wireless/ath/wil6210/pm.c | 7 +++ drivers/net/wireless/ath/wil6210/sysfs.c | 54 +++++++++++++++++++++ drivers/net/wireless/ath/wil6210/wil6210.h | 8 +++ drivers/net/wireless/ath/wil6210/wmi.c | 51 +++++++++++++++++++ drivers/net/wireless/ath/wil6210/wmi.h | 28 +++++++++++ 7 files changed, 190 insertions(+) diff --git a/drivers/net/wireless/ath/wil6210/cfg80211.c b/drivers/net/wireless/ath/wil6210/cfg80211.c index b612cdfc5a31..23c8042809ca 100644 --- a/drivers/net/wireless/ath/wil6210/cfg80211.c +++ b/drivers/net/wireless/ath/wil6210/cfg80211.c @@ -2646,6 +2646,10 @@ static int wil_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct wil6210_priv *wil = wiphy_to_wil(wiphy); enum wmi_ps_profile_type ps_profile; + if (wil->vr_profile != WMI_VR_PROFILE_DISABLED) + /* disallow in VR mode */ + return -EINVAL; + wil_dbg_misc(wil, "enabled=%d, timeout=%d\n", enabled, timeout); diff --git a/drivers/net/wireless/ath/wil6210/main.c b/drivers/net/wireless/ath/wil6210/main.c index 54261a820ead..c658ab3334aa 100644 --- a/drivers/net/wireless/ath/wil6210/main.c +++ b/drivers/net/wireless/ath/wil6210/main.c @@ -20,6 +20,8 @@ #define WAIT_FOR_SCAN_ABORT_MS 1000 #define WIL_DEFAULT_NUM_RX_STATUS_RINGS 1 #define WIL_BOARD_FILE_MAX_NAMELEN 128 +#define WIL6210_ITR_VR_RX_MAX_BURST_DURATION (5) /* usec */ +#define WIL6210_VR_TX_RING_ORDER 10 bool debug_fw; /* = false; */ module_param(debug_fw, bool, 0444); @@ -1565,6 +1567,38 @@ int wil_ps_update(struct wil6210_priv *wil, enum wmi_ps_profile_type ps_profile) return rc; } +int wil_vr_update_profile(struct wil6210_priv *wil, u8 profile) +{ + int rc; + + if (profile == WMI_VR_PROFILE_DISABLED) { + /* Switch from VR mode to normal (non-VR) mode is not + * supported at runtime - it requires FW re-loading. + * It is assumed here that FW is not running when VR disable + * is requested + */ + wil->ps_profile = WMI_PS_PROFILE_TYPE_DEFAULT; + tx_ring_order = WIL_TX_RING_SIZE_ORDER_DEFAULT; + drop_if_ring_full = false; + wil->rx_max_burst_duration = + WIL6210_ITR_RX_MAX_BURST_DURATION_DEFAULT; + + return 0; + } + + rc = wmi_set_vr_profile(wil, profile); + if (rc) + return rc; + + /* VR default configuration */ + wil->ps_profile = WMI_PS_PROFILE_TYPE_PS_DISABLED; + tx_ring_order = WIL6210_VR_TX_RING_ORDER; + drop_if_ring_full = true; + wil->rx_max_burst_duration = WIL6210_ITR_VR_RX_MAX_BURST_DURATION; + + return 0; +} + static void wil_pre_fw_config(struct wil6210_priv *wil) { wil_clear_fw_log_addr(wil); @@ -1815,6 +1849,10 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw) return rc; } + /* Update VR mode before configuring interrupt moderation */ + if (wil->vr_profile != WMI_VR_PROFILE_DISABLED) + wil_vr_update_profile(wil, wil->vr_profile); + wil->txrx_ops.configure_interrupt_moderation(wil); /* Enable OFU rdy valid bug fix, to prevent hang in oful34_rx diff --git a/drivers/net/wireless/ath/wil6210/pm.c b/drivers/net/wireless/ath/wil6210/pm.c index 34f5ea8e6520..2f67bd218f58 100644 --- a/drivers/net/wireless/ath/wil6210/pm.c +++ b/drivers/net/wireless/ath/wil6210/pm.c @@ -51,6 +51,13 @@ wil_can_suspend_vif(struct wil6210_priv *wil, struct wil6210_vif *vif, /* for STA-like interface, don't runtime suspend */ case NL80211_IFTYPE_STATION: + if (test_bit(wil_vif_fwconnected, vif->status) && + wil->vr_profile != WMI_VR_PROFILE_DISABLED) { + wil_dbg_pm(wil, + "Reject suspend in VR mode when connected\n"); + return false; + } + /* fallthrough */ case NL80211_IFTYPE_P2P_CLIENT: if (test_bit(wil_vif_fwconnecting, vif->status)) { wil_dbg_pm(wil, "Delay suspend when connecting\n"); diff --git a/drivers/net/wireless/ath/wil6210/sysfs.c b/drivers/net/wireless/ath/wil6210/sysfs.c index f872e8358033..7f3e658f0f76 100644 --- a/drivers/net/wireless/ath/wil6210/sysfs.c +++ b/drivers/net/wireless/ath/wil6210/sysfs.c @@ -297,6 +297,59 @@ out: static DEVICE_ATTR_RW(fst_link_loss); +static ssize_t +vr_profile_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct wil6210_priv *wil = dev_get_drvdata(dev); + ssize_t len; + + len = snprintf(buf, PAGE_SIZE, "%s\n", + wil_get_vr_profile_name(wil->vr_profile)); + + return len; +} + +static ssize_t +vr_profile_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct wil6210_priv *wil = dev_get_drvdata(dev); + u8 profile; + int rc = 0; + + if (kstrtou8(buf, 0, &profile)) + return -EINVAL; + + if (test_bit(wil_status_fwready, wil->status)) { + wil_err(wil, "Cannot set VR while interface is up\n"); + return -EIO; + } + + if (profile == wil->vr_profile) { + wil_info(wil, "Ignore same VR profile %s\n", + wil_get_vr_profile_name(wil->vr_profile)); + return count; + } + + wil_info(wil, "Sysfs: set VR profile to %s\n", + wil_get_vr_profile_name(profile)); + + /* Enabling of VR mode is done from wil_reset after FW is ready. + * Disabling is done from here. + */ + if (profile == WMI_VR_PROFILE_DISABLED) { + rc = wil_vr_update_profile(wil, profile); + if (rc) + return rc; + } + wil->vr_profile = profile; + + return count; +} + +static DEVICE_ATTR_RW(vr_profile); + static ssize_t snr_thresh_show(struct device *dev, struct device_attribute *attr, char *buf) @@ -339,6 +392,7 @@ static struct attribute *wil6210_sysfs_entries[] = { &dev_attr_thermal_throttling.attr, &dev_attr_fst_link_loss.attr, &dev_attr_snr_thresh.attr, + &dev_attr_vr_profile.attr, NULL }; diff --git a/drivers/net/wireless/ath/wil6210/wil6210.h b/drivers/net/wireless/ath/wil6210/wil6210.h index a074fac5f082..972f8516ed90 100644 --- a/drivers/net/wireless/ath/wil6210/wil6210.h +++ b/drivers/net/wireless/ath/wil6210/wil6210.h @@ -1052,6 +1052,9 @@ struct wil6210_priv { short direct; } snr_thresh; + /* VR profile, VR is disabled on profile 0 */ + u8 vr_profile; + /* current reg domain configured in kernel */ char regdomain[3]; /* alpha2 */ @@ -1255,6 +1258,7 @@ void wil_mbox_ring_le2cpus(struct wil6210_mbox_ring *r); int wil_find_cid(struct wil6210_priv *wil, u8 mid, const u8 *mac); int wil_find_cid_by_idx(struct wil6210_priv *wil, u8 mid, int idx); void wil_set_ethtoolops(struct net_device *ndev); +int wil_vr_update_profile(struct wil6210_priv *wil, u8 profile); struct fw_map *wil_find_fw_mapping(const char *section); void __iomem *wmi_buffer_block(struct wil6210_priv *wil, __le32 ptr, u32 size); @@ -1450,6 +1454,10 @@ void wil_halp_unvote(struct wil6210_priv *wil); void wil6210_set_halp(struct wil6210_priv *wil); void wil6210_clear_halp(struct wil6210_priv *wil); +int wmi_set_vr_profile(struct wil6210_priv *wil, u8 profile); +const char * +wil_get_vr_profile_name(enum wmi_vr_profile profile); + void wil_ftm_init(struct wil6210_vif *vif); void wil_ftm_deinit(struct wil6210_vif *vif); void wil_ftm_stop_operations(struct wil6210_priv *wil); diff --git a/drivers/net/wireless/ath/wil6210/wmi.c b/drivers/net/wireless/ath/wil6210/wmi.c index c72024d61e06..751ada06333d 100644 --- a/drivers/net/wireless/ath/wil6210/wmi.c +++ b/drivers/net/wireless/ath/wil6210/wmi.c @@ -478,6 +478,8 @@ static const char *cmdid2name(u16 cmdid) return "WMI_RBUFCAP_CFG_CMD"; case WMI_TEMP_SENSE_ALL_CMDID: return "WMI_TEMP_SENSE_ALL_CMDID"; + case WMI_SET_VR_PROFILE_CMDID: + return "WMI_SET_VR_PROFILE_CMD"; default: return "Untracked CMD"; } @@ -626,6 +628,8 @@ static const char *eventid2name(u16 eventid) return "WMI_RBUFCAP_CFG_EVENT"; case WMI_TEMP_SENSE_ALL_DONE_EVENTID: return "WMI_TEMP_SENSE_ALL_DONE_EVENTID"; + case WMI_SET_VR_PROFILE_EVENTID: + return "WMI_SET_VR_PROFILE_EVENT"; default: return "Untracked EVENT"; } @@ -4211,3 +4215,50 @@ int wmi_link_stats_cfg(struct wil6210_vif *vif, u32 type, u8 cid, u32 interval) return 0; } + +const char * +wil_get_vr_profile_name(enum wmi_vr_profile profile) +{ + switch (profile) { + case WMI_VR_PROFILE_DISABLED: + return "DISABLED"; + case WMI_VR_PROFILE_COMMON_AP: + return "COMMON_AP"; + case WMI_VR_PROFILE_COMMON_STA: + return "COMMON_STA"; + default: + return "unknown"; + } +} + +int wmi_set_vr_profile(struct wil6210_priv *wil, u8 profile) +{ + int rc; + struct net_device *ndev = wil->main_ndev; + struct wil6210_vif *vif = ndev_to_vif(ndev); + struct wmi_set_vr_profile_cmd cmd = {0}; + struct { + struct wmi_cmd_hdr hdr; + struct wmi_set_vr_profile_event evt; + } __packed reply = { + .evt = {.status = WMI_FW_STATUS_FAILURE}, + }; + + cmd.profile = profile; + wil_info(wil, "sending set vr config command, profile=%d\n", profile); + rc = wmi_call(wil, WMI_SET_VR_PROFILE_CMDID, vif->mid, &cmd, + sizeof(cmd), WMI_SET_VR_PROFILE_EVENTID, + &reply, sizeof(reply), WIL_WMI_CALL_GENERAL_TO_MS); + if (rc) { + wil_err(wil, "WMI_SET_VR_PROFILE_CMDID failed, rc %d\n", rc); + return rc; + } + + if (reply.evt.status != WMI_FW_STATUS_SUCCESS) { + wil_err(wil, "set vr profile failed, status %d\n", + reply.evt.status); + return -EINVAL; + } + + return 0; +} diff --git a/drivers/net/wireless/ath/wil6210/wmi.h b/drivers/net/wireless/ath/wil6210/wmi.h index 87138708f32b..431404f0c330 100644 --- a/drivers/net/wireless/ath/wil6210/wmi.h +++ b/drivers/net/wireless/ath/wil6210/wmi.h @@ -284,6 +284,7 @@ enum wmi_command_id { WMI_GET_ASSOC_LIST_CMDID = 0xA06, WMI_GET_CCA_INDICATIONS_CMDID = 0xA07, WMI_SET_CCA_INDICATIONS_BI_AVG_NUM_CMDID = 0xA08, + WMI_SET_VR_PROFILE_CMDID = 0xA09, WMI_INTERNAL_FW_IOCTL_CMDID = 0xA0B, WMI_LINK_STATS_CMDID = 0xA0C, WMI_SET_GRANT_MCS_CMDID = 0xA0E, @@ -2110,6 +2111,7 @@ enum wmi_event_id { WMI_GET_ASSOC_LIST_RES_EVENTID = 0x1A06, WMI_GET_CCA_INDICATIONS_EVENTID = 0x1A07, WMI_SET_CCA_INDICATIONS_BI_AVG_NUM_EVENTID = 0x1A08, + WMI_SET_VR_PROFILE_EVENTID = 0x1A09, WMI_INTERNAL_FW_EVENT_EVENTID = 0x1A0A, WMI_INTERNAL_FW_IOCTL_EVENTID = 0x1A0B, WMI_LINK_STATS_CONFIG_DONE_EVENTID = 0x1A0C, @@ -4158,6 +4160,32 @@ struct wmi_rbufcap_cfg_cmd { __le16 rx_desc_threshold; } __packed; +enum wmi_vr_profile { + WMI_VR_PROFILE_DISABLED = 0, + WMI_VR_PROFILE_COMMON_AP = 1, + WMI_VR_PROFILE_COMMON_STA = 2, + WMI_VR_PROFILE_RESERVED0 = 250, + WMI_VR_PROFILE_RESERVED1 = 251, + WMI_VR_PROFILE_RESERVED2 = 252, + WMI_VR_PROFILE_RESERVED3 = 253, + WMI_VR_PROFILE_RESERVED4 = 254, + WMI_VR_PROFILE_RESERVED5 = 255, +}; + +/* WMI_SET_VR_PROFILE_CMDID */ +struct wmi_set_vr_profile_cmd { + /* enum wmi_vr_profile */ + u8 profile; + u8 reserved[3]; +} __packed; + +/* WMI_SET_VR_PROFILE_EVENTID */ +struct wmi_set_vr_profile_event { + /* enum wmi_fw_status */ + u8 status; + u8 reserved[3]; +} __packed; + /* WMI_RBUFCAP_CFG_EVENTID */ struct wmi_rbufcap_cfg_event { /* enum wmi_fw_status */ From 727f25c03a954b955b5c540bb333a30d9b390df2 Mon Sep 17 00:00:00 2001 From: Maya Erez Date: Sun, 15 Dec 2019 13:31:30 +0200 Subject: [PATCH 3/4] wil6210: add support for spi slave reset As SPI core is not being reset in SW reset, FW needs to disable it before the reset, to ensure proper SPI re-initialization after the reset. Add a new WMI command to notify FW to reset SPI slave before performing SW reset. Change-Id: I12d23560dbb28daa64cbebec155847fe32625b63 Signed-off-by: Maya Erez --- drivers/net/wireless/ath/wil6210/main.c | 1 + drivers/net/wireless/ath/wil6210/wil6210.h | 1 + drivers/net/wireless/ath/wil6210/wmi.c | 53 ++++++++++++++++++++-- drivers/net/wireless/ath/wil6210/wmi.h | 14 ++++++ 4 files changed, 66 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/ath/wil6210/main.c b/drivers/net/wireless/ath/wil6210/main.c index c658ab3334aa..819595071ee1 100644 --- a/drivers/net/wireless/ath/wil6210/main.c +++ b/drivers/net/wireless/ath/wil6210/main.c @@ -1717,6 +1717,7 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw) if (support_sensing_over_spi) { wil_dbg_misc(wil, "notify FW to enable SPI for sensing\n"); wil_s(wil, RGF_USER_USAGE_6, BIT_SPI_SENSING_SUPPORT); + wmi_reset_spi_slave(wil); } else { wil_dbg_misc(wil, "notify FW to disable SPI for sensing\n"); wil_c(wil, RGF_USER_USAGE_6, BIT_SPI_SENSING_SUPPORT); diff --git a/drivers/net/wireless/ath/wil6210/wil6210.h b/drivers/net/wireless/ath/wil6210/wil6210.h index 972f8516ed90..0c1870479a4f 100644 --- a/drivers/net/wireless/ath/wil6210/wil6210.h +++ b/drivers/net/wireless/ath/wil6210/wil6210.h @@ -1511,6 +1511,7 @@ int wmi_addba_rx_resp_edma(struct wil6210_priv *wil, u8 mid, u8 cid, u16 agg_wsize, u16 timeout); void update_supported_bands(struct wil6210_priv *wil); +int wmi_reset_spi_slave(struct wil6210_priv *wil); void wil_clear_fw_log_addr(struct wil6210_priv *wil); #endif /* __WIL6210_H__ */ diff --git a/drivers/net/wireless/ath/wil6210/wmi.c b/drivers/net/wireless/ath/wil6210/wmi.c index 751ada06333d..16aea74398e1 100644 --- a/drivers/net/wireless/ath/wil6210/wmi.c +++ b/drivers/net/wireless/ath/wil6210/wmi.c @@ -32,6 +32,7 @@ MODULE_PARM_DESC(led_id, #define WIL_WAIT_FOR_SUSPEND_RESUME_COMP 200 #define WIL_WMI_PCP_STOP_TO_MS 5000 +#define WIL_WMI_SPI_SLAVE_RESET_TO_MS 500 /** * WMI event receiving - theory of operations @@ -480,6 +481,8 @@ static const char *cmdid2name(u16 cmdid) return "WMI_TEMP_SENSE_ALL_CMDID"; case WMI_SET_VR_PROFILE_CMDID: return "WMI_SET_VR_PROFILE_CMD"; + case WMI_RESET_SPI_SLAVE_CMDID: + return "WMI_RESET_SPI_SLAVE_CMD"; default: return "Untracked CMD"; } @@ -630,6 +633,8 @@ static const char *eventid2name(u16 eventid) return "WMI_TEMP_SENSE_ALL_DONE_EVENTID"; case WMI_SET_VR_PROFILE_EVENTID: return "WMI_SET_VR_PROFILE_EVENT"; + case WMI_RESET_SPI_SLAVE_EVENTID: + return "WMI_RESET_SPI_SLAVE_EVENT"; default: return "Untracked EVENT"; } @@ -2074,8 +2079,9 @@ void wmi_recv_cmd(struct wil6210_priv *wil) n - num_immed_reply, num_immed_reply); } -int wmi_call(struct wil6210_priv *wil, u16 cmdid, u8 mid, void *buf, u16 len, - u16 reply_id, void *reply, u16 reply_size, int to_msec) +static int __wmi_call(struct wil6210_priv *wil, u16 cmdid, u8 mid, void *buf, + u16 len, u16 reply_id, void *reply, u16 reply_size, + int to_msec, bool force_send) { int rc; unsigned long remain; @@ -2091,7 +2097,7 @@ int wmi_call(struct wil6210_priv *wil, u16 cmdid, u8 mid, void *buf, u16 len, reinit_completion(&wil->wmi_call); spin_unlock_irqrestore(&wil->wmi_ev_lock, flags); - rc = __wmi_send(wil, cmdid, mid, buf, len, false); + rc = __wmi_send(wil, cmdid, mid, buf, len, force_send); if (rc) goto out; @@ -2121,6 +2127,13 @@ out: return rc; } +int wmi_call(struct wil6210_priv *wil, u16 cmdid, u8 mid, void *buf, u16 len, + u16 reply_id, void *reply, u16 reply_size, int to_msec) +{ + return __wmi_call(wil, cmdid, mid, buf, len, reply_id, reply, + reply_size, to_msec, false); +} + int wmi_echo(struct wil6210_priv *wil) { struct wil6210_vif *vif = ndev_to_vif(wil->main_ndev); @@ -4262,3 +4275,37 @@ int wmi_set_vr_profile(struct wil6210_priv *wil, u8 profile) return 0; } + +int wmi_reset_spi_slave(struct wil6210_priv *wil) +{ + struct net_device *ndev = wil->main_ndev; + struct wil6210_vif *vif = ndev_to_vif(ndev); + struct wmi_reset_spi_slave_cmd cmd = { {0} }; + struct { + struct wmi_cmd_hdr wmi; + struct wmi_reset_spi_slave_event evt; + } __packed reply = { + .evt = {.status = WMI_FW_STATUS_FAILURE}, + }; + int rc; + + if (!(ndev->flags & IFF_UP)) + return 0; + + /* Force sending SPI slave reset to guarantee safe SPI reset */ + rc = __wmi_call(wil, WMI_RESET_SPI_SLAVE_CMDID, vif->mid, &cmd, + sizeof(cmd), WMI_RESET_SPI_SLAVE_EVENTID, &reply, + sizeof(reply), WIL_WMI_SPI_SLAVE_RESET_TO_MS, true); + if (rc) { + wil_err(wil, "WMI_RESET_SPI_SLAVE_CMDID failed, rc %d\n", rc); + return rc; + } + + if (reply.evt.status != WMI_FW_STATUS_SUCCESS) { + wil_err(wil, "spi slave reset failed, status %d\n", + reply.evt.status); + return -EINVAL; + } + + return 0; +} diff --git a/drivers/net/wireless/ath/wil6210/wmi.h b/drivers/net/wireless/ath/wil6210/wmi.h index 431404f0c330..c2d4eac96fb3 100644 --- a/drivers/net/wireless/ath/wil6210/wmi.h +++ b/drivers/net/wireless/ath/wil6210/wmi.h @@ -140,6 +140,7 @@ enum wmi_command_id { WMI_RADAR_SET_MODE_CMDID = 0x103, WMI_RADAR_CONTROL_CMDID = 0x104, WMI_RADAR_PCI_CONTROL_CMDID = 0x105, + WMI_RESET_SPI_SLAVE_CMDID = 0x106, WMI_MEM_READ_CMDID = 0x800, WMI_MEM_WR_CMDID = 0x801, WMI_ECHO_CMDID = 0x803, @@ -693,6 +694,11 @@ struct wmi_radar_pci_control_cmd { __le32 reserved; } __packed; +/* WMI_RESET_SPI_SLAVE_CMDID */ +struct wmi_reset_spi_slave_cmd { + u8 reserved[4]; +} __packed; + /* WMI_RF_MGMT_CMDID */ enum wmi_rf_mgmt_type { WMI_RF_MGMT_W_DISABLE = 0x00, @@ -1735,6 +1741,13 @@ struct wmi_radar_pci_control_event { u8 reserved[3]; } __packed; +/* WMI_RESET_SPI_SLAVE_EVENTID */ +struct wmi_reset_spi_slave_event { + /* wmi_fw_status */ + u8 status; + u8 reserved[3]; +} __packed; + /* WMI_SET_LONG_RANGE_CONFIG_CMDID */ struct wmi_set_long_range_config_cmd { __le32 reserved; @@ -1981,6 +1994,7 @@ enum wmi_event_id { WMI_RADAR_SET_MODE_EVENTID = 0x1103, WMI_RADAR_CONTROL_EVENTID = 0x1104, WMI_RADAR_PCI_CONTROL_EVENTID = 0x1105, + WMI_RESET_SPI_SLAVE_EVENTID = 0x1106, WMI_RD_MEM_RSP_EVENTID = 0x1800, WMI_FW_READY_EVENTID = 0x1801, WMI_EXIT_FAST_MEM_ACC_MODE_EVENTID = 0x200, From c4194623d34ec5d8af617c8bdd5bb1aab1ba765d Mon Sep 17 00:00:00 2001 From: Alexei Avshalom Lazar Date: Thu, 23 May 2019 10:24:25 +0300 Subject: [PATCH 4/4] wil6210: extend bus voting support for wider bandwidth In connect or start AP there is no distinction between 11ad bandwidth and 11ay bandwidth. Add support for 11ay connection/start AP bandwidth for the bus voting. Change-Id: I388d2c6e58cfa8f49e04837054270d263123184f Signed-off-by: Alexei Avshalom Lazar --- drivers/net/wireless/ath/wil6210/cfg80211.c | 19 +++++++++++++++---- drivers/net/wireless/ath/wil6210/wil6210.h | 2 ++ 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/ath/wil6210/cfg80211.c b/drivers/net/wireless/ath/wil6210/cfg80211.c index 23c8042809ca..d172e753de11 100644 --- a/drivers/net/wireless/ath/wil6210/cfg80211.c +++ b/drivers/net/wireless/ath/wil6210/cfg80211.c @@ -1551,8 +1551,14 @@ static int wil_cfg80211_connect(struct wiphy *wiphy, rc = wmi_send(wil, WMI_CONNECT_CMDID, vif->mid, &conn, sizeof(conn)); if (rc == 0) { netif_carrier_on(ndev); - if (!wil_has_other_active_ifaces(wil, ndev, false, true)) - wil6210_bus_request(wil, WIL_MAX_BUS_REQUEST_KBPS); + if (!wil_has_other_active_ifaces(wil, ndev, false, true)) { + if (wil->force_edmg_channel) + wil6210_bus_request(wil, + WIL_11AY_BUS_REQUEST_KBPS); + else + wil6210_bus_request(wil, + WIL_11AD_BUS_REQUEST_KBPS); + } vif->bss = bss; /* Connect can take lots of time */ mod_timer(&vif->connect_timer, @@ -2207,8 +2213,13 @@ static int _wil_cfg80211_start_ap(struct wiphy *wiphy, } netif_carrier_on(ndev); - if (!wil_has_other_active_ifaces(wil, ndev, false, true)) - wil6210_bus_request(wil, WIL_MAX_BUS_REQUEST_KBPS); + if (!wil_has_other_active_ifaces(wil, ndev, false, true)) { + if (wil->force_edmg_channel) + wil6210_bus_request(wil, WIL_11AY_BUS_REQUEST_KBPS); + else + wil6210_bus_request(wil, WIL_11AD_BUS_REQUEST_KBPS); + } + rc = wmi_pcp_start(vif, bi, wmi_nettype, chan, wmi_edmg_channel, hidden_ssid, is_go); diff --git a/drivers/net/wireless/ath/wil6210/wil6210.h b/drivers/net/wireless/ath/wil6210/wil6210.h index 0c1870479a4f..e5bd9eea2377 100644 --- a/drivers/net/wireless/ath/wil6210/wil6210.h +++ b/drivers/net/wireless/ath/wil6210/wil6210.h @@ -52,6 +52,8 @@ union wil_tx_desc; #define WIL_DEFAULT_BUS_REQUEST_KBPS 128000 /* ~1Gbps */ #define WIL_MAX_BUS_REQUEST_KBPS 800000 /* ~6.1Gbps */ +#define WIL_11AD_BUS_REQUEST_KBPS 600000 /* ~4.6Gbps */ +#define WIL_11AY_BUS_REQUEST_KBPS 1300000 /* ~10.1Gbps */ #define WIL_NUM_LATENCY_BINS 200