Loading drivers/net/wireless/ath/wil6210/cfg80211.c +11 −3 Original line number Diff line number Diff line Loading @@ -973,7 +973,7 @@ int wil_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, u64 *cookie) { const u8 *buf = params->buf; size_t len = params->len; size_t len = params->len, total; struct wil6210_priv *wil = wiphy_to_wil(wiphy); int rc; bool tx_status = false; Loading @@ -998,7 +998,11 @@ int wil_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, if (len < sizeof(struct ieee80211_hdr_3addr)) return -EINVAL; cmd = kmalloc(sizeof(*cmd) + len, GFP_KERNEL); total = sizeof(*cmd) + len; if (total < len) return -EINVAL; cmd = kmalloc(total, GFP_KERNEL); if (!cmd) { rc = -ENOMEM; goto out; Loading @@ -1008,7 +1012,7 @@ int wil_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, cmd->len = cpu_to_le16(len); memcpy(cmd->payload, buf, len); rc = wmi_call(wil, WMI_SW_TX_REQ_CMDID, cmd, sizeof(*cmd) + len, rc = wmi_call(wil, WMI_SW_TX_REQ_CMDID, cmd, total, WMI_SW_TX_COMPLETE_EVENTID, &evt, sizeof(evt), 2000); if (rc == 0) tx_status = !evt.evt.status; Loading Loading @@ -1799,9 +1803,13 @@ static int wil_cfg80211_suspend(struct wiphy *wiphy, wil_dbg_pm(wil, "suspending\n"); mutex_lock(&wil->mutex); wil_p2p_stop_discovery(wil); mutex_lock(&wil->p2p_wdev_mutex); wil_abort_scan(wil, true); mutex_unlock(&wil->p2p_wdev_mutex); mutex_unlock(&wil->mutex); out: return rc; Loading drivers/net/wireless/ath/wil6210/debugfs.c +89 −7 Original line number Diff line number Diff line Loading @@ -242,12 +242,19 @@ static void wil_print_ring(struct seq_file *s, const char *prefix, static int wil_mbox_debugfs_show(struct seq_file *s, void *data) { struct wil6210_priv *wil = s->private; int ret; ret = wil_pm_runtime_get(wil); if (ret < 0) return ret; wil_print_ring(s, "tx", wil->csr + HOST_MBOX + offsetof(struct wil6210_mbox_ctl, tx)); wil_print_ring(s, "rx", wil->csr + HOST_MBOX + offsetof(struct wil6210_mbox_ctl, rx)); wil_pm_runtime_put(wil); return 0; } Loading @@ -265,15 +272,38 @@ static const struct file_operations fops_mbox = { static int wil_debugfs_iomem_x32_set(void *data, u64 val) { writel(val, (void __iomem *)data); struct wil_debugfs_iomem_data *d = (struct wil_debugfs_iomem_data *)data; struct wil6210_priv *wil = d->wil; int ret; ret = wil_pm_runtime_get(wil); if (ret < 0) return ret; writel_relaxed(val, (void __iomem *)d->offset); wmb(); /* make sure write propagated to HW */ wil_pm_runtime_put(wil); return 0; } static int wil_debugfs_iomem_x32_get(void *data, u64 *val) { *val = readl((void __iomem *)data); struct wil_debugfs_iomem_data *d = (struct wil_debugfs_iomem_data *)data; struct wil6210_priv *wil = d->wil; int ret; ret = wil_pm_runtime_get(wil); if (ret < 0) return ret; *val = readl_relaxed((void __iomem *)d->offset); wil_pm_runtime_put(wil); return 0; } Loading @@ -284,10 +314,21 @@ DEFINE_SIMPLE_ATTRIBUTE(fops_iomem_x32, wil_debugfs_iomem_x32_get, static struct dentry *wil_debugfs_create_iomem_x32(const char *name, umode_t mode, struct dentry *parent, void *value) void *value, struct wil6210_priv *wil) { return debugfs_create_file(name, mode, parent, value, &fops_iomem_x32); struct dentry *file; struct wil_debugfs_iomem_data *data = &wil->dbg_data.data_arr[ wil->dbg_data.iomem_data_count]; data->wil = wil; data->offset = value; file = debugfs_create_file(name, mode, parent, data, &fops_iomem_x32); if (!IS_ERR_OR_NULL(file)) wil->dbg_data.iomem_data_count++; return file; } static int wil_debugfs_ulong_set(void *data, u64 val) Loading Loading @@ -346,7 +387,8 @@ static void wil6210_debugfs_init_offset(struct wil6210_priv *wil, case doff_io32: f = wil_debugfs_create_iomem_x32(tbl[i].name, tbl[i].mode, dbg, base + tbl[i].off); base + tbl[i].off, wil); break; case doff_u8: f = debugfs_create_u8(tbl[i].name, tbl[i].mode, dbg, Loading Loading @@ -475,13 +517,22 @@ static int wil6210_debugfs_create_ITR_CNT(struct wil6210_priv *wil, static int wil_memread_debugfs_show(struct seq_file *s, void *data) { struct wil6210_priv *wil = s->private; void __iomem *a = wmi_buffer(wil, cpu_to_le32(mem_addr)); void __iomem *a; int ret; ret = wil_pm_runtime_get(wil); if (ret < 0) return ret; a = wmi_buffer(wil, cpu_to_le32(mem_addr)); if (a) seq_printf(s, "[0x%08x] = 0x%08x\n", mem_addr, readl(a)); else seq_printf(s, "[0x%08x] = INVALID\n", mem_addr); wil_pm_runtime_put(wil); return 0; } Loading @@ -502,10 +553,12 @@ static ssize_t wil_read_file_ioblob(struct file *file, char __user *user_buf, { enum { max_count = 4096 }; struct wil_blob_wrapper *wil_blob = file->private_data; struct wil6210_priv *wil = wil_blob->wil; loff_t pos = *ppos; size_t available = wil_blob->blob.size; void *buf; size_t ret; int rc; if (test_bit(wil_status_suspending, wil_blob->wil->status) || test_bit(wil_status_suspended, wil_blob->wil->status)) Loading @@ -526,10 +579,19 @@ static ssize_t wil_read_file_ioblob(struct file *file, char __user *user_buf, if (!buf) return -ENOMEM; rc = wil_pm_runtime_get(wil); if (rc < 0) { kfree(buf); return rc; } wil_memcpy_fromio_32(buf, (const void __iomem *) wil_blob->blob.data + pos, count); ret = copy_to_user(user_buf, buf, count); wil_pm_runtime_put(wil); kfree(buf); if (ret == count) return -EFAULT; Loading Loading @@ -1781,6 +1843,13 @@ static const struct dbg_off dbg_statics[] = { {}, }; static const int dbg_off_count = 4 * (ARRAY_SIZE(isr_off) - 1) + ARRAY_SIZE(dbg_wil_regs) - 1 + ARRAY_SIZE(pseudo_isr_off) - 1 + ARRAY_SIZE(lgc_itr_cnt_off) - 1 + ARRAY_SIZE(tx_itr_cnt_off) - 1 + ARRAY_SIZE(rx_itr_cnt_off) - 1; int wil6210_debugfs_init(struct wil6210_priv *wil) { struct dentry *dbg = wil->debug = debugfs_create_dir(WIL_NAME, Loading @@ -1789,6 +1858,17 @@ int wil6210_debugfs_init(struct wil6210_priv *wil) if (IS_ERR_OR_NULL(dbg)) return -ENODEV; wil->dbg_data.data_arr = kcalloc(dbg_off_count, sizeof(struct wil_debugfs_iomem_data), GFP_KERNEL); if (!wil->dbg_data.data_arr) { debugfs_remove_recursive(dbg); wil->debug = NULL; return -ENOMEM; } wil->dbg_data.iomem_data_count = 0; wil_pmc_init(wil); wil6210_debugfs_init_files(wil, dbg); Loading @@ -1813,6 +1893,8 @@ void wil6210_debugfs_remove(struct wil6210_priv *wil) debugfs_remove_recursive(wil->debug); wil->debug = NULL; kfree(wil->dbg_data.data_arr); /* free pmc memory without sending command to fw, as it will * be reset on the way down anyway */ Loading drivers/net/wireless/ath/wil6210/ethtool.c +15 −0 Original line number Diff line number Diff line Loading @@ -47,9 +47,14 @@ static int wil_ethtoolops_get_coalesce(struct net_device *ndev, struct wil6210_priv *wil = ndev_to_wil(ndev); u32 tx_itr_en, tx_itr_val = 0; u32 rx_itr_en, rx_itr_val = 0; int ret; wil_dbg_misc(wil, "ethtoolops_get_coalesce\n"); ret = wil_pm_runtime_get(wil); if (ret < 0) return ret; tx_itr_en = wil_r(wil, RGF_DMA_ITR_TX_CNT_CTL); if (tx_itr_en & BIT_DMA_ITR_TX_CNT_CTL_EN) tx_itr_val = wil_r(wil, RGF_DMA_ITR_TX_CNT_TRSH); Loading @@ -58,6 +63,8 @@ static int wil_ethtoolops_get_coalesce(struct net_device *ndev, if (rx_itr_en & BIT_DMA_ITR_RX_CNT_CTL_EN) rx_itr_val = wil_r(wil, RGF_DMA_ITR_RX_CNT_TRSH); wil_pm_runtime_put(wil); cp->tx_coalesce_usecs = tx_itr_val; cp->rx_coalesce_usecs = rx_itr_val; return 0; Loading @@ -67,6 +74,7 @@ static int wil_ethtoolops_set_coalesce(struct net_device *ndev, struct ethtool_coalesce *cp) { struct wil6210_priv *wil = ndev_to_wil(ndev); int ret; wil_dbg_misc(wil, "ethtoolops_set_coalesce: rx %d usec, tx %d usec\n", cp->rx_coalesce_usecs, cp->tx_coalesce_usecs); Loading @@ -86,8 +94,15 @@ static int wil_ethtoolops_set_coalesce(struct net_device *ndev, wil->tx_max_burst_duration = cp->tx_coalesce_usecs; wil->rx_max_burst_duration = cp->rx_coalesce_usecs; ret = wil_pm_runtime_get(wil); if (ret < 0) return ret; wil_configure_interrupt_moderation(wil); wil_pm_runtime_put(wil); return 0; out_bad: Loading drivers/net/wireless/ath/wil6210/fw_inc.c +46 −33 Original line number Diff line number Diff line Loading @@ -26,14 +26,17 @@ prefix_type, rowsize, \ groupsize, buf, len, ascii) #define FW_ADDR_CHECK(ioaddr, val, msg) do { \ ioaddr = wmi_buffer(wil, val); \ if (!ioaddr) { \ wil_err_fw(wil, "bad " msg ": 0x%08x\n", \ le32_to_cpu(val)); \ return -EINVAL; \ } \ } while (0) static bool wil_fw_addr_check(struct wil6210_priv *wil, void __iomem **ioaddr, __le32 val, u32 size, const char *msg) { *ioaddr = wmi_buffer_block(wil, val, size); if (!(*ioaddr)) { wil_err_fw(wil, "bad %s: 0x%08x\n", msg, le32_to_cpu(val)); return false; } return true; } /** * wil_fw_verify - verify firmware file validity Loading Loading @@ -124,24 +127,19 @@ static int fw_ignore_section(struct wil6210_priv *wil, const void *data, return 0; } static int fw_handle_comment(struct wil6210_priv *wil, const void *data, size_t size) { wil_hex_dump_fw("", DUMP_PREFIX_OFFSET, 16, 1, data, size, true); return 0; } static int fw_handle_capabilities(struct wil6210_priv *wil, const void *data, fw_handle_comment(struct wil6210_priv *wil, const void *data, size_t size) { const struct wil_fw_record_capabilities *rec = data; size_t capa_size; if (size < sizeof(*rec) || le32_to_cpu(rec->magic) != WIL_FW_CAPABILITIES_MAGIC) le32_to_cpu(rec->magic) != WIL_FW_CAPABILITIES_MAGIC) { wil_hex_dump_fw("", DUMP_PREFIX_OFFSET, 16, 1, data, size, true); return 0; } capa_size = size - offsetof(struct wil_fw_record_capabilities, capabilities); Loading @@ -165,7 +163,8 @@ static int fw_handle_data(struct wil6210_priv *wil, const void *data, return -EINVAL; } FW_ADDR_CHECK(dst, d->addr, "address"); if (!wil_fw_addr_check(wil, &dst, d->addr, s, "address")) return -EINVAL; wil_dbg_fw(wil, "write [0x%08x] <== %zu bytes\n", le32_to_cpu(d->addr), s); wil_memcpy_toio_32(dst, d->data, s); Loading Loading @@ -197,7 +196,8 @@ static int fw_handle_fill(struct wil6210_priv *wil, const void *data, return -EINVAL; } FW_ADDR_CHECK(dst, d->addr, "address"); if (!wil_fw_addr_check(wil, &dst, d->addr, s, "address")) return -EINVAL; v = le32_to_cpu(d->value); wil_dbg_fw(wil, "fill [0x%08x] <== 0x%08x, %zu bytes\n", Loading Loading @@ -253,7 +253,8 @@ static int fw_handle_direct_write(struct wil6210_priv *wil, const void *data, u32 v = le32_to_cpu(block[i].value); u32 x, y; FW_ADDR_CHECK(dst, block[i].addr, "address"); if (!wil_fw_addr_check(wil, &dst, block[i].addr, 0, "address")) return -EINVAL; x = readl(dst); y = (x & m) | (v & ~m); Loading Loading @@ -319,10 +320,15 @@ static int fw_handle_gateway_data(struct wil6210_priv *wil, const void *data, wil_dbg_fw(wil, "gw write record [%3d] blocks, cmd 0x%08x\n", n, gw_cmd); FW_ADDR_CHECK(gwa_addr, d->gateway_addr_addr, "gateway_addr_addr"); FW_ADDR_CHECK(gwa_val, d->gateway_value_addr, "gateway_value_addr"); FW_ADDR_CHECK(gwa_cmd, d->gateway_cmd_addr, "gateway_cmd_addr"); FW_ADDR_CHECK(gwa_ctl, d->gateway_ctrl_address, "gateway_ctrl_address"); if (!wil_fw_addr_check(wil, &gwa_addr, d->gateway_addr_addr, 0, "gateway_addr_addr") || !wil_fw_addr_check(wil, &gwa_val, d->gateway_value_addr, 0, "gateway_value_addr") || !wil_fw_addr_check(wil, &gwa_cmd, d->gateway_cmd_addr, 0, "gateway_cmd_addr") || !wil_fw_addr_check(wil, &gwa_ctl, d->gateway_ctrl_address, 0, "gateway_ctrl_address")) return -EINVAL; wil_dbg_fw(wil, "gw addresses: addr 0x%08x val 0x%08x" " cmd 0x%08x ctl 0x%08x\n", Loading Loading @@ -378,12 +384,19 @@ static int fw_handle_gateway_data4(struct wil6210_priv *wil, const void *data, wil_dbg_fw(wil, "gw4 write record [%3d] blocks, cmd 0x%08x\n", n, gw_cmd); FW_ADDR_CHECK(gwa_addr, d->gateway_addr_addr, "gateway_addr_addr"); if (!wil_fw_addr_check(wil, &gwa_addr, d->gateway_addr_addr, 0, "gateway_addr_addr")) return -EINVAL; for (k = 0; k < ARRAY_SIZE(block->value); k++) FW_ADDR_CHECK(gwa_val[k], d->gateway_value_addr[k], "gateway_value_addr"); FW_ADDR_CHECK(gwa_cmd, d->gateway_cmd_addr, "gateway_cmd_addr"); FW_ADDR_CHECK(gwa_ctl, d->gateway_ctrl_address, "gateway_ctrl_address"); if (!wil_fw_addr_check(wil, &gwa_val[k], d->gateway_value_addr[k], 0, "gateway_value_addr")) return -EINVAL; if (!wil_fw_addr_check(wil, &gwa_cmd, d->gateway_cmd_addr, 0, "gateway_cmd_addr") || !wil_fw_addr_check(wil, &gwa_ctl, d->gateway_ctrl_address, 0, "gateway_ctrl_address")) return -EINVAL; wil_dbg_fw(wil, "gw4 addresses: addr 0x%08x cmd 0x%08x ctl 0x%08x\n", le32_to_cpu(d->gateway_addr_addr), Loading Loading @@ -422,7 +435,7 @@ static const struct { int (*parse_handler)(struct wil6210_priv *wil, const void *data, size_t size); } wil_fw_handlers[] = { {wil_fw_type_comment, fw_handle_comment, fw_handle_capabilities}, {wil_fw_type_comment, fw_handle_comment, fw_handle_comment}, {wil_fw_type_data, fw_handle_data, fw_ignore_section}, {wil_fw_type_fill, fw_handle_fill, fw_ignore_section}, /* wil_fw_type_action */ Loading Loading @@ -517,7 +530,7 @@ int wil_request_firmware(struct wil6210_priv *wil, const char *name, rc = request_firmware(&fw, name, wil_to_dev(wil)); if (rc) { wil_err_fw(wil, "Failed to load firmware %s\n", name); wil_err_fw(wil, "Failed to load firmware %s rc %d\n", name, rc); return rc; } wil_dbg_fw(wil, "Loading <%s>, %zu bytes\n", name, fw->size); Loading drivers/net/wireless/ath/wil6210/interrupt.c +21 −1 Original line number Diff line number Diff line Loading @@ -358,6 +358,25 @@ static void wil_cache_mbox_regs(struct wil6210_priv *wil) wil_mbox_ring_le2cpus(&wil->mbox_ctl.tx); } static bool wil_validate_mbox_regs(struct wil6210_priv *wil) { size_t min_size = sizeof(struct wil6210_mbox_hdr) + sizeof(struct wmi_cmd_hdr); if (wil->mbox_ctl.rx.entry_size < min_size) { wil_err(wil, "rx mbox entry too small (%d)\n", wil->mbox_ctl.rx.entry_size); return false; } if (wil->mbox_ctl.tx.entry_size < min_size) { wil_err(wil, "tx mbox entry too small (%d)\n", wil->mbox_ctl.tx.entry_size); return false; } return true; } static irqreturn_t wil6210_irq_misc(int irq, void *cookie) { struct wil6210_priv *wil = cookie; Loading Loading @@ -393,6 +412,7 @@ static irqreturn_t wil6210_irq_misc(int irq, void *cookie) if (isr & ISR_MISC_FW_READY) { wil_dbg_irq(wil, "IRQ: FW ready\n"); wil_cache_mbox_regs(wil); if (wil_validate_mbox_regs(wil)) set_bit(wil_status_mbox_ready, wil->status); /** * Actual FW ready indicated by the Loading Loading
drivers/net/wireless/ath/wil6210/cfg80211.c +11 −3 Original line number Diff line number Diff line Loading @@ -973,7 +973,7 @@ int wil_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, u64 *cookie) { const u8 *buf = params->buf; size_t len = params->len; size_t len = params->len, total; struct wil6210_priv *wil = wiphy_to_wil(wiphy); int rc; bool tx_status = false; Loading @@ -998,7 +998,11 @@ int wil_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, if (len < sizeof(struct ieee80211_hdr_3addr)) return -EINVAL; cmd = kmalloc(sizeof(*cmd) + len, GFP_KERNEL); total = sizeof(*cmd) + len; if (total < len) return -EINVAL; cmd = kmalloc(total, GFP_KERNEL); if (!cmd) { rc = -ENOMEM; goto out; Loading @@ -1008,7 +1012,7 @@ int wil_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, cmd->len = cpu_to_le16(len); memcpy(cmd->payload, buf, len); rc = wmi_call(wil, WMI_SW_TX_REQ_CMDID, cmd, sizeof(*cmd) + len, rc = wmi_call(wil, WMI_SW_TX_REQ_CMDID, cmd, total, WMI_SW_TX_COMPLETE_EVENTID, &evt, sizeof(evt), 2000); if (rc == 0) tx_status = !evt.evt.status; Loading Loading @@ -1799,9 +1803,13 @@ static int wil_cfg80211_suspend(struct wiphy *wiphy, wil_dbg_pm(wil, "suspending\n"); mutex_lock(&wil->mutex); wil_p2p_stop_discovery(wil); mutex_lock(&wil->p2p_wdev_mutex); wil_abort_scan(wil, true); mutex_unlock(&wil->p2p_wdev_mutex); mutex_unlock(&wil->mutex); out: return rc; Loading
drivers/net/wireless/ath/wil6210/debugfs.c +89 −7 Original line number Diff line number Diff line Loading @@ -242,12 +242,19 @@ static void wil_print_ring(struct seq_file *s, const char *prefix, static int wil_mbox_debugfs_show(struct seq_file *s, void *data) { struct wil6210_priv *wil = s->private; int ret; ret = wil_pm_runtime_get(wil); if (ret < 0) return ret; wil_print_ring(s, "tx", wil->csr + HOST_MBOX + offsetof(struct wil6210_mbox_ctl, tx)); wil_print_ring(s, "rx", wil->csr + HOST_MBOX + offsetof(struct wil6210_mbox_ctl, rx)); wil_pm_runtime_put(wil); return 0; } Loading @@ -265,15 +272,38 @@ static const struct file_operations fops_mbox = { static int wil_debugfs_iomem_x32_set(void *data, u64 val) { writel(val, (void __iomem *)data); struct wil_debugfs_iomem_data *d = (struct wil_debugfs_iomem_data *)data; struct wil6210_priv *wil = d->wil; int ret; ret = wil_pm_runtime_get(wil); if (ret < 0) return ret; writel_relaxed(val, (void __iomem *)d->offset); wmb(); /* make sure write propagated to HW */ wil_pm_runtime_put(wil); return 0; } static int wil_debugfs_iomem_x32_get(void *data, u64 *val) { *val = readl((void __iomem *)data); struct wil_debugfs_iomem_data *d = (struct wil_debugfs_iomem_data *)data; struct wil6210_priv *wil = d->wil; int ret; ret = wil_pm_runtime_get(wil); if (ret < 0) return ret; *val = readl_relaxed((void __iomem *)d->offset); wil_pm_runtime_put(wil); return 0; } Loading @@ -284,10 +314,21 @@ DEFINE_SIMPLE_ATTRIBUTE(fops_iomem_x32, wil_debugfs_iomem_x32_get, static struct dentry *wil_debugfs_create_iomem_x32(const char *name, umode_t mode, struct dentry *parent, void *value) void *value, struct wil6210_priv *wil) { return debugfs_create_file(name, mode, parent, value, &fops_iomem_x32); struct dentry *file; struct wil_debugfs_iomem_data *data = &wil->dbg_data.data_arr[ wil->dbg_data.iomem_data_count]; data->wil = wil; data->offset = value; file = debugfs_create_file(name, mode, parent, data, &fops_iomem_x32); if (!IS_ERR_OR_NULL(file)) wil->dbg_data.iomem_data_count++; return file; } static int wil_debugfs_ulong_set(void *data, u64 val) Loading Loading @@ -346,7 +387,8 @@ static void wil6210_debugfs_init_offset(struct wil6210_priv *wil, case doff_io32: f = wil_debugfs_create_iomem_x32(tbl[i].name, tbl[i].mode, dbg, base + tbl[i].off); base + tbl[i].off, wil); break; case doff_u8: f = debugfs_create_u8(tbl[i].name, tbl[i].mode, dbg, Loading Loading @@ -475,13 +517,22 @@ static int wil6210_debugfs_create_ITR_CNT(struct wil6210_priv *wil, static int wil_memread_debugfs_show(struct seq_file *s, void *data) { struct wil6210_priv *wil = s->private; void __iomem *a = wmi_buffer(wil, cpu_to_le32(mem_addr)); void __iomem *a; int ret; ret = wil_pm_runtime_get(wil); if (ret < 0) return ret; a = wmi_buffer(wil, cpu_to_le32(mem_addr)); if (a) seq_printf(s, "[0x%08x] = 0x%08x\n", mem_addr, readl(a)); else seq_printf(s, "[0x%08x] = INVALID\n", mem_addr); wil_pm_runtime_put(wil); return 0; } Loading @@ -502,10 +553,12 @@ static ssize_t wil_read_file_ioblob(struct file *file, char __user *user_buf, { enum { max_count = 4096 }; struct wil_blob_wrapper *wil_blob = file->private_data; struct wil6210_priv *wil = wil_blob->wil; loff_t pos = *ppos; size_t available = wil_blob->blob.size; void *buf; size_t ret; int rc; if (test_bit(wil_status_suspending, wil_blob->wil->status) || test_bit(wil_status_suspended, wil_blob->wil->status)) Loading @@ -526,10 +579,19 @@ static ssize_t wil_read_file_ioblob(struct file *file, char __user *user_buf, if (!buf) return -ENOMEM; rc = wil_pm_runtime_get(wil); if (rc < 0) { kfree(buf); return rc; } wil_memcpy_fromio_32(buf, (const void __iomem *) wil_blob->blob.data + pos, count); ret = copy_to_user(user_buf, buf, count); wil_pm_runtime_put(wil); kfree(buf); if (ret == count) return -EFAULT; Loading Loading @@ -1781,6 +1843,13 @@ static const struct dbg_off dbg_statics[] = { {}, }; static const int dbg_off_count = 4 * (ARRAY_SIZE(isr_off) - 1) + ARRAY_SIZE(dbg_wil_regs) - 1 + ARRAY_SIZE(pseudo_isr_off) - 1 + ARRAY_SIZE(lgc_itr_cnt_off) - 1 + ARRAY_SIZE(tx_itr_cnt_off) - 1 + ARRAY_SIZE(rx_itr_cnt_off) - 1; int wil6210_debugfs_init(struct wil6210_priv *wil) { struct dentry *dbg = wil->debug = debugfs_create_dir(WIL_NAME, Loading @@ -1789,6 +1858,17 @@ int wil6210_debugfs_init(struct wil6210_priv *wil) if (IS_ERR_OR_NULL(dbg)) return -ENODEV; wil->dbg_data.data_arr = kcalloc(dbg_off_count, sizeof(struct wil_debugfs_iomem_data), GFP_KERNEL); if (!wil->dbg_data.data_arr) { debugfs_remove_recursive(dbg); wil->debug = NULL; return -ENOMEM; } wil->dbg_data.iomem_data_count = 0; wil_pmc_init(wil); wil6210_debugfs_init_files(wil, dbg); Loading @@ -1813,6 +1893,8 @@ void wil6210_debugfs_remove(struct wil6210_priv *wil) debugfs_remove_recursive(wil->debug); wil->debug = NULL; kfree(wil->dbg_data.data_arr); /* free pmc memory without sending command to fw, as it will * be reset on the way down anyway */ Loading
drivers/net/wireless/ath/wil6210/ethtool.c +15 −0 Original line number Diff line number Diff line Loading @@ -47,9 +47,14 @@ static int wil_ethtoolops_get_coalesce(struct net_device *ndev, struct wil6210_priv *wil = ndev_to_wil(ndev); u32 tx_itr_en, tx_itr_val = 0; u32 rx_itr_en, rx_itr_val = 0; int ret; wil_dbg_misc(wil, "ethtoolops_get_coalesce\n"); ret = wil_pm_runtime_get(wil); if (ret < 0) return ret; tx_itr_en = wil_r(wil, RGF_DMA_ITR_TX_CNT_CTL); if (tx_itr_en & BIT_DMA_ITR_TX_CNT_CTL_EN) tx_itr_val = wil_r(wil, RGF_DMA_ITR_TX_CNT_TRSH); Loading @@ -58,6 +63,8 @@ static int wil_ethtoolops_get_coalesce(struct net_device *ndev, if (rx_itr_en & BIT_DMA_ITR_RX_CNT_CTL_EN) rx_itr_val = wil_r(wil, RGF_DMA_ITR_RX_CNT_TRSH); wil_pm_runtime_put(wil); cp->tx_coalesce_usecs = tx_itr_val; cp->rx_coalesce_usecs = rx_itr_val; return 0; Loading @@ -67,6 +74,7 @@ static int wil_ethtoolops_set_coalesce(struct net_device *ndev, struct ethtool_coalesce *cp) { struct wil6210_priv *wil = ndev_to_wil(ndev); int ret; wil_dbg_misc(wil, "ethtoolops_set_coalesce: rx %d usec, tx %d usec\n", cp->rx_coalesce_usecs, cp->tx_coalesce_usecs); Loading @@ -86,8 +94,15 @@ static int wil_ethtoolops_set_coalesce(struct net_device *ndev, wil->tx_max_burst_duration = cp->tx_coalesce_usecs; wil->rx_max_burst_duration = cp->rx_coalesce_usecs; ret = wil_pm_runtime_get(wil); if (ret < 0) return ret; wil_configure_interrupt_moderation(wil); wil_pm_runtime_put(wil); return 0; out_bad: Loading
drivers/net/wireless/ath/wil6210/fw_inc.c +46 −33 Original line number Diff line number Diff line Loading @@ -26,14 +26,17 @@ prefix_type, rowsize, \ groupsize, buf, len, ascii) #define FW_ADDR_CHECK(ioaddr, val, msg) do { \ ioaddr = wmi_buffer(wil, val); \ if (!ioaddr) { \ wil_err_fw(wil, "bad " msg ": 0x%08x\n", \ le32_to_cpu(val)); \ return -EINVAL; \ } \ } while (0) static bool wil_fw_addr_check(struct wil6210_priv *wil, void __iomem **ioaddr, __le32 val, u32 size, const char *msg) { *ioaddr = wmi_buffer_block(wil, val, size); if (!(*ioaddr)) { wil_err_fw(wil, "bad %s: 0x%08x\n", msg, le32_to_cpu(val)); return false; } return true; } /** * wil_fw_verify - verify firmware file validity Loading Loading @@ -124,24 +127,19 @@ static int fw_ignore_section(struct wil6210_priv *wil, const void *data, return 0; } static int fw_handle_comment(struct wil6210_priv *wil, const void *data, size_t size) { wil_hex_dump_fw("", DUMP_PREFIX_OFFSET, 16, 1, data, size, true); return 0; } static int fw_handle_capabilities(struct wil6210_priv *wil, const void *data, fw_handle_comment(struct wil6210_priv *wil, const void *data, size_t size) { const struct wil_fw_record_capabilities *rec = data; size_t capa_size; if (size < sizeof(*rec) || le32_to_cpu(rec->magic) != WIL_FW_CAPABILITIES_MAGIC) le32_to_cpu(rec->magic) != WIL_FW_CAPABILITIES_MAGIC) { wil_hex_dump_fw("", DUMP_PREFIX_OFFSET, 16, 1, data, size, true); return 0; } capa_size = size - offsetof(struct wil_fw_record_capabilities, capabilities); Loading @@ -165,7 +163,8 @@ static int fw_handle_data(struct wil6210_priv *wil, const void *data, return -EINVAL; } FW_ADDR_CHECK(dst, d->addr, "address"); if (!wil_fw_addr_check(wil, &dst, d->addr, s, "address")) return -EINVAL; wil_dbg_fw(wil, "write [0x%08x] <== %zu bytes\n", le32_to_cpu(d->addr), s); wil_memcpy_toio_32(dst, d->data, s); Loading Loading @@ -197,7 +196,8 @@ static int fw_handle_fill(struct wil6210_priv *wil, const void *data, return -EINVAL; } FW_ADDR_CHECK(dst, d->addr, "address"); if (!wil_fw_addr_check(wil, &dst, d->addr, s, "address")) return -EINVAL; v = le32_to_cpu(d->value); wil_dbg_fw(wil, "fill [0x%08x] <== 0x%08x, %zu bytes\n", Loading Loading @@ -253,7 +253,8 @@ static int fw_handle_direct_write(struct wil6210_priv *wil, const void *data, u32 v = le32_to_cpu(block[i].value); u32 x, y; FW_ADDR_CHECK(dst, block[i].addr, "address"); if (!wil_fw_addr_check(wil, &dst, block[i].addr, 0, "address")) return -EINVAL; x = readl(dst); y = (x & m) | (v & ~m); Loading Loading @@ -319,10 +320,15 @@ static int fw_handle_gateway_data(struct wil6210_priv *wil, const void *data, wil_dbg_fw(wil, "gw write record [%3d] blocks, cmd 0x%08x\n", n, gw_cmd); FW_ADDR_CHECK(gwa_addr, d->gateway_addr_addr, "gateway_addr_addr"); FW_ADDR_CHECK(gwa_val, d->gateway_value_addr, "gateway_value_addr"); FW_ADDR_CHECK(gwa_cmd, d->gateway_cmd_addr, "gateway_cmd_addr"); FW_ADDR_CHECK(gwa_ctl, d->gateway_ctrl_address, "gateway_ctrl_address"); if (!wil_fw_addr_check(wil, &gwa_addr, d->gateway_addr_addr, 0, "gateway_addr_addr") || !wil_fw_addr_check(wil, &gwa_val, d->gateway_value_addr, 0, "gateway_value_addr") || !wil_fw_addr_check(wil, &gwa_cmd, d->gateway_cmd_addr, 0, "gateway_cmd_addr") || !wil_fw_addr_check(wil, &gwa_ctl, d->gateway_ctrl_address, 0, "gateway_ctrl_address")) return -EINVAL; wil_dbg_fw(wil, "gw addresses: addr 0x%08x val 0x%08x" " cmd 0x%08x ctl 0x%08x\n", Loading Loading @@ -378,12 +384,19 @@ static int fw_handle_gateway_data4(struct wil6210_priv *wil, const void *data, wil_dbg_fw(wil, "gw4 write record [%3d] blocks, cmd 0x%08x\n", n, gw_cmd); FW_ADDR_CHECK(gwa_addr, d->gateway_addr_addr, "gateway_addr_addr"); if (!wil_fw_addr_check(wil, &gwa_addr, d->gateway_addr_addr, 0, "gateway_addr_addr")) return -EINVAL; for (k = 0; k < ARRAY_SIZE(block->value); k++) FW_ADDR_CHECK(gwa_val[k], d->gateway_value_addr[k], "gateway_value_addr"); FW_ADDR_CHECK(gwa_cmd, d->gateway_cmd_addr, "gateway_cmd_addr"); FW_ADDR_CHECK(gwa_ctl, d->gateway_ctrl_address, "gateway_ctrl_address"); if (!wil_fw_addr_check(wil, &gwa_val[k], d->gateway_value_addr[k], 0, "gateway_value_addr")) return -EINVAL; if (!wil_fw_addr_check(wil, &gwa_cmd, d->gateway_cmd_addr, 0, "gateway_cmd_addr") || !wil_fw_addr_check(wil, &gwa_ctl, d->gateway_ctrl_address, 0, "gateway_ctrl_address")) return -EINVAL; wil_dbg_fw(wil, "gw4 addresses: addr 0x%08x cmd 0x%08x ctl 0x%08x\n", le32_to_cpu(d->gateway_addr_addr), Loading Loading @@ -422,7 +435,7 @@ static const struct { int (*parse_handler)(struct wil6210_priv *wil, const void *data, size_t size); } wil_fw_handlers[] = { {wil_fw_type_comment, fw_handle_comment, fw_handle_capabilities}, {wil_fw_type_comment, fw_handle_comment, fw_handle_comment}, {wil_fw_type_data, fw_handle_data, fw_ignore_section}, {wil_fw_type_fill, fw_handle_fill, fw_ignore_section}, /* wil_fw_type_action */ Loading Loading @@ -517,7 +530,7 @@ int wil_request_firmware(struct wil6210_priv *wil, const char *name, rc = request_firmware(&fw, name, wil_to_dev(wil)); if (rc) { wil_err_fw(wil, "Failed to load firmware %s\n", name); wil_err_fw(wil, "Failed to load firmware %s rc %d\n", name, rc); return rc; } wil_dbg_fw(wil, "Loading <%s>, %zu bytes\n", name, fw->size); Loading
drivers/net/wireless/ath/wil6210/interrupt.c +21 −1 Original line number Diff line number Diff line Loading @@ -358,6 +358,25 @@ static void wil_cache_mbox_regs(struct wil6210_priv *wil) wil_mbox_ring_le2cpus(&wil->mbox_ctl.tx); } static bool wil_validate_mbox_regs(struct wil6210_priv *wil) { size_t min_size = sizeof(struct wil6210_mbox_hdr) + sizeof(struct wmi_cmd_hdr); if (wil->mbox_ctl.rx.entry_size < min_size) { wil_err(wil, "rx mbox entry too small (%d)\n", wil->mbox_ctl.rx.entry_size); return false; } if (wil->mbox_ctl.tx.entry_size < min_size) { wil_err(wil, "tx mbox entry too small (%d)\n", wil->mbox_ctl.tx.entry_size); return false; } return true; } static irqreturn_t wil6210_irq_misc(int irq, void *cookie) { struct wil6210_priv *wil = cookie; Loading Loading @@ -393,6 +412,7 @@ static irqreturn_t wil6210_irq_misc(int irq, void *cookie) if (isr & ISR_MISC_FW_READY) { wil_dbg_irq(wil, "IRQ: FW ready\n"); wil_cache_mbox_regs(wil); if (wil_validate_mbox_regs(wil)) set_bit(wil_status_mbox_ready, wil->status); /** * Actual FW ready indicated by the Loading