Loading drivers/net/wireless/ath/wil6210/cfg80211.c +6 −6 Original line number Diff line number Diff line Loading @@ -162,7 +162,7 @@ int wil_cid_fill_sinfo(struct wil6210_priv *wil, int cid, sinfo->tx_packets = stats->tx_packets; sinfo->tx_failed = stats->tx_errors; if (test_bit(wil_status_fwconnected, &wil->status)) { if (test_bit(wil_status_fwconnected, wil->status)) { sinfo->filled |= STATION_INFO_SIGNAL; sinfo->signal = reply.evt.sqi; } Loading Loading @@ -282,7 +282,7 @@ static int wil_cfg80211_scan(struct wiphy *wiphy, } /* FW don't support scan after connection attempt */ if (test_bit(wil_status_dontscan, &wil->status)) { if (test_bit(wil_status_dontscan, wil->status)) { wil_err(wil, "Can't scan now\n"); return -EBUSY; } Loading Loading @@ -362,8 +362,8 @@ static int wil_cfg80211_connect(struct wiphy *wiphy, int ch; int rc = 0; if (test_bit(wil_status_fwconnecting, &wil->status) || test_bit(wil_status_fwconnected, &wil->status)) if (test_bit(wil_status_fwconnecting, wil->status) || test_bit(wil_status_fwconnected, wil->status)) return -EALREADY; wil_print_connect_params(wil, sme); Loading Loading @@ -450,7 +450,7 @@ static int wil_cfg80211_connect(struct wiphy *wiphy, memcpy(conn.bssid, bss->bssid, ETH_ALEN); memcpy(conn.dst_mac, bss->bssid, ETH_ALEN); set_bit(wil_status_fwconnecting, &wil->status); set_bit(wil_status_fwconnecting, wil->status); rc = wmi_send(wil, WMI_CONNECT_CMDID, &conn, sizeof(conn)); if (rc == 0) { Loading @@ -458,7 +458,7 @@ static int wil_cfg80211_connect(struct wiphy *wiphy, mod_timer(&wil->connect_timer, jiffies + msecs_to_jiffies(2000)); } else { clear_bit(wil_status_fwconnecting, &wil->status); clear_bit(wil_status_fwconnecting, wil->status); } out: Loading drivers/net/wireless/ath/wil6210/debugfs.c +148 −16 Original line number Diff line number Diff line Loading @@ -50,6 +50,7 @@ static void wil_print_vring(struct seq_file *s, struct wil6210_priv *wil, char _s, char _h) { void __iomem *x = wmi_addr(wil, vring->hwtail); u32 v; seq_printf(s, "VRING %s = {\n", name); seq_printf(s, " pa = %pad\n", &vring->pa); Loading @@ -58,10 +59,12 @@ static void wil_print_vring(struct seq_file *s, struct wil6210_priv *wil, seq_printf(s, " swtail = %d\n", vring->swtail); seq_printf(s, " swhead = %d\n", vring->swhead); seq_printf(s, " hwtail = [0x%08x] -> ", vring->hwtail); if (x) seq_printf(s, "0x%08x\n", ioread32(x)); else if (x) { v = ioread32(x); seq_printf(s, "0x%08x = %d\n", v, v); } else { seq_puts(s, "???\n"); } if (vring->va && (vring->size < 1025)) { uint i; Loading Loading @@ -101,8 +104,8 @@ static int wil_vring_debugfs_show(struct seq_file *s, void *data) char name[10]; /* performance monitoring */ cycles_t now = get_cycles(); cycles_t idle = txdata->idle * 100; cycles_t total = now - txdata->begin; uint64_t idle = txdata->idle * 100; uint64_t total = now - txdata->begin; do_div(idle, total); txdata->begin = now; Loading @@ -110,9 +113,12 @@ static int wil_vring_debugfs_show(struct seq_file *s, void *data) snprintf(name, sizeof(name), "tx_%2d", i); seq_printf(s, "\n%pM CID %d TID %d [%3d|%3d] idle %3d%%\n", wil->sta[cid].addr, cid, tid, used, avail, (int)idle); seq_printf(s, "\n%pM CID %d TID %d BACK([%d] %d TU A%s) [%3d|%3d] idle %3d%%\n", wil->sta[cid].addr, cid, tid, txdata->agg_wsize, txdata->agg_timeout, txdata->agg_amsdu ? "+" : "-", used, avail, (int)idle); wil_print_vring(s, wil, name, vring, '_', 'H'); } Loading Loading @@ -384,24 +390,67 @@ static int wil6210_debugfs_create_pseudo_ISR(struct wil6210_priv *wil, return 0; } static const struct dbg_off itr_cnt_off[] = { static const struct dbg_off lgc_itr_cnt_off[] = { {"TRSH", S_IRUGO | S_IWUSR, HOSTADDR(RGF_DMA_ITR_CNT_TRSH), doff_io32}, {"DATA", S_IRUGO | S_IWUSR, HOSTADDR(RGF_DMA_ITR_CNT_DATA), doff_io32}, {"CTL", S_IRUGO | S_IWUSR, HOSTADDR(RGF_DMA_ITR_CNT_CRL), doff_io32}, {}, }; static const struct dbg_off tx_itr_cnt_off[] = { {"TRSH", S_IRUGO | S_IWUSR, HOSTADDR(RGF_DMA_ITR_TX_CNT_TRSH), doff_io32}, {"DATA", S_IRUGO | S_IWUSR, HOSTADDR(RGF_DMA_ITR_TX_CNT_DATA), doff_io32}, {"CTL", S_IRUGO | S_IWUSR, HOSTADDR(RGF_DMA_ITR_TX_CNT_CTL), doff_io32}, {"IDL_TRSH", S_IRUGO | S_IWUSR, HOSTADDR(RGF_DMA_ITR_TX_IDL_CNT_TRSH), doff_io32}, {"IDL_DATA", S_IRUGO | S_IWUSR, HOSTADDR(RGF_DMA_ITR_TX_IDL_CNT_DATA), doff_io32}, {"IDL_CTL", S_IRUGO | S_IWUSR, HOSTADDR(RGF_DMA_ITR_TX_IDL_CNT_CTL), doff_io32}, {}, }; static const struct dbg_off rx_itr_cnt_off[] = { {"TRSH", S_IRUGO | S_IWUSR, HOSTADDR(RGF_DMA_ITR_RX_CNT_TRSH), doff_io32}, {"DATA", S_IRUGO | S_IWUSR, HOSTADDR(RGF_DMA_ITR_RX_CNT_DATA), doff_io32}, {"CTL", S_IRUGO | S_IWUSR, HOSTADDR(RGF_DMA_ITR_RX_CNT_CTL), doff_io32}, {"IDL_TRSH", S_IRUGO | S_IWUSR, HOSTADDR(RGF_DMA_ITR_RX_IDL_CNT_TRSH), doff_io32}, {"IDL_DATA", S_IRUGO | S_IWUSR, HOSTADDR(RGF_DMA_ITR_RX_IDL_CNT_DATA), doff_io32}, {"IDL_CTL", S_IRUGO | S_IWUSR, HOSTADDR(RGF_DMA_ITR_RX_IDL_CNT_CTL), doff_io32}, {}, }; static int wil6210_debugfs_create_ITR_CNT(struct wil6210_priv *wil, struct dentry *parent) { struct dentry *d = debugfs_create_dir("ITR_CNT", parent); struct dentry *d, *dtx, *drx; d = debugfs_create_dir("ITR_CNT", parent); if (IS_ERR_OR_NULL(d)) return -ENODEV; dtx = debugfs_create_dir("TX", d); drx = debugfs_create_dir("RX", d); if (IS_ERR_OR_NULL(dtx) || IS_ERR_OR_NULL(drx)) return -ENODEV; wil6210_debugfs_init_offset(wil, d, (void * __force)wil->csr, itr_cnt_off); lgc_itr_cnt_off); wil6210_debugfs_init_offset(wil, dtx, (void * __force)wil->csr, tx_itr_cnt_off); wil6210_debugfs_init_offset(wil, drx, (void * __force)wil->csr, rx_itr_cnt_off); return 0; } Loading Loading @@ -558,6 +607,87 @@ static const struct file_operations fops_rxon = { .open = simple_open, }; /* block ack control, write: * - "add <ringid> <agg_size> <timeout>" to trigger ADDBA * - "del_tx <ringid> <reason>" to trigger DELBA for Tx side * - "del_rx <CID> <TID> <reason>" to trigger DELBA for Rx side */ static ssize_t wil_write_back(struct file *file, const char __user *buf, size_t len, loff_t *ppos) { struct wil6210_priv *wil = file->private_data; int rc; char *kbuf = kmalloc(len + 1, GFP_KERNEL); char cmd[8]; int p1, p2, p3; if (!kbuf) return -ENOMEM; rc = simple_write_to_buffer(kbuf, len, ppos, buf, len); if (rc != len) { kfree(kbuf); return rc >= 0 ? -EIO : rc; } kbuf[len] = '\0'; rc = sscanf(kbuf, "%8s %d %d %d", cmd, &p1, &p2, &p3); kfree(kbuf); if (rc < 0) return rc; if (rc < 2) return -EINVAL; if (0 == strcmp(cmd, "add")) { if (rc < 3) { wil_err(wil, "BACK: add require at least 2 params\n"); return -EINVAL; } if (rc < 4) p3 = 0; wmi_addba(wil, p1, p2, p3); } else if (0 == strcmp(cmd, "del_tx")) { if (rc < 3) p2 = WLAN_REASON_QSTA_LEAVE_QBSS; wmi_delba_tx(wil, p1, p2); } else if (0 == strcmp(cmd, "del_rx")) { if (rc < 3) { wil_err(wil, "BACK: del_rx require at least 2 params\n"); return -EINVAL; } if (rc < 4) p3 = WLAN_REASON_QSTA_LEAVE_QBSS; wmi_delba_rx(wil, mk_cidxtid(p1, p2), p3); } else { wil_err(wil, "BACK: Unrecognized command \"%s\"\n", cmd); return -EINVAL; } return len; } static ssize_t wil_read_back(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { static const char text[] = "block ack control, write:\n" " - \"add <ringid> <agg_size> <timeout>\" to trigger ADDBA\n" "If missing, <timeout> defaults to 0\n" " - \"del_tx <ringid> <reason>\" to trigger DELBA for Tx side\n" " - \"del_rx <CID> <TID> <reason>\" to trigger DELBA for Rx side\n" "If missing, <reason> set to \"STA_LEAVING\" (36)\n"; return simple_read_from_buffer(user_buf, count, ppos, text, sizeof(text)); } static const struct file_operations fops_back = { .read = wil_read_back, .write = wil_write_back, .open = simple_open, }; /*---tx_mgmt---*/ /* Write mgmt frame to this file to send it */ static ssize_t wil_write_file_txmgmt(struct file *file, const char __user *buf, Loading Loading @@ -1112,7 +1242,8 @@ static void wil_print_rxtid(struct seq_file *s, struct wil_tid_ampdu_rx *r) int i; u16 index = ((r->head_seq_num - r->ssn) & 0xfff) % r->buf_size; seq_printf(s, "0x%03x [", r->head_seq_num); seq_printf(s, "([%2d] %3d TU) 0x%03x [", r->buf_size, r->timeout, r->head_seq_num); for (i = 0; i < r->buf_size; i++) { if (i == index) seq_printf(s, "%c", r->reorder_buf[i] ? 'O' : '|'); Loading @@ -1123,10 +1254,10 @@ static void wil_print_rxtid(struct seq_file *s, struct wil_tid_ampdu_rx *r) } static int wil_sta_debugfs_show(struct seq_file *s, void *data) __acquires(&p->tid_rx_lock) __releases(&p->tid_rx_lock) { struct wil6210_priv *wil = s->private; int i, tid; unsigned long flags; for (i = 0; i < ARRAY_SIZE(wil->sta); i++) { struct wil_sta_info *p = &wil->sta[i]; Loading @@ -1147,7 +1278,7 @@ static int wil_sta_debugfs_show(struct seq_file *s, void *data) (p->data_port_open ? " data_port_open" : "")); if (p->status == wil_sta_connected) { spin_lock_irqsave(&p->tid_rx_lock, flags); spin_lock_bh(&p->tid_rx_lock); for (tid = 0; tid < WIL_STA_TID_NUM; tid++) { struct wil_tid_ampdu_rx *r = p->tid_rx[tid]; Loading @@ -1156,7 +1287,7 @@ static int wil_sta_debugfs_show(struct seq_file *s, void *data) wil_print_rxtid(s, r); } } spin_unlock_irqrestore(&p->tid_rx_lock, flags); spin_unlock_bh(&p->tid_rx_lock); } } Loading Loading @@ -1213,6 +1344,7 @@ static const struct { {"rxon", S_IWUSR, &fops_rxon}, {"tx_mgmt", S_IWUSR, &fops_txmgmt}, {"wmi_send", S_IWUSR, &fops_wmi}, {"back", S_IRUGO | S_IWUSR, &fops_back}, {"temp", S_IRUGO, &fops_temp}, {"freq", S_IRUGO, &fops_freq}, {"link", S_IRUGO, &fops_link}, Loading Loading @@ -1257,7 +1389,7 @@ static void wil6210_debugfs_init_isr(struct wil6210_priv *wil, /* fields in struct wil6210_priv */ static const struct dbg_off dbg_wil_off[] = { WIL_FIELD(secure_pcp, S_IRUGO | S_IWUSR, doff_u32), WIL_FIELD(status, S_IRUGO | S_IWUSR, doff_ulong), WIL_FIELD(status[0], S_IRUGO | S_IWUSR, doff_ulong), WIL_FIELD(fw_version, S_IRUGO, doff_u32), WIL_FIELD(hw_version, S_IRUGO, doff_x32), WIL_FIELD(recovery_count, S_IRUGO, doff_u32), Loading drivers/net/wireless/ath/wil6210/ethtool.c +34 −12 Original line number Diff line number Diff line Loading @@ -45,16 +45,35 @@ static int wil_ethtoolops_get_coalesce(struct net_device *ndev, struct ethtool_coalesce *cp) { struct wil6210_priv *wil = ndev_to_wil(ndev); u32 itr_en, itr_val = 0; u32 tx_itr_en, tx_itr_val = 0; u32 rx_itr_en, rx_itr_val = 0; wil_dbg_misc(wil, "%s()\n", __func__); itr_en = ioread32(wil->csr + HOSTADDR(RGF_DMA_ITR_CNT_CRL)); if (itr_en & BIT_DMA_ITR_CNT_CRL_EN) itr_val = ioread32(wil->csr + HOSTADDR(RGF_DMA_ITR_CNT_TRSH)); cp->rx_coalesce_usecs = itr_val; if (test_bit(hw_capability_advanced_itr_moderation, wil->hw_capabilities)) { tx_itr_en = ioread32(wil->csr + HOSTADDR(RGF_DMA_ITR_TX_CNT_CTL)); if (tx_itr_en & BIT_DMA_ITR_TX_CNT_CTL_EN) tx_itr_val = ioread32(wil->csr + HOSTADDR(RGF_DMA_ITR_TX_CNT_TRSH)); rx_itr_en = ioread32(wil->csr + HOSTADDR(RGF_DMA_ITR_RX_CNT_CTL)); if (rx_itr_en & BIT_DMA_ITR_RX_CNT_CTL_EN) rx_itr_val = ioread32(wil->csr + HOSTADDR(RGF_DMA_ITR_RX_CNT_TRSH)); } else { rx_itr_en = ioread32(wil->csr + HOSTADDR(RGF_DMA_ITR_CNT_CRL)); if (rx_itr_en & BIT_DMA_ITR_CNT_CRL_EN) rx_itr_val = ioread32(wil->csr + HOSTADDR(RGF_DMA_ITR_CNT_TRSH)); } cp->tx_coalesce_usecs = tx_itr_val; cp->rx_coalesce_usecs = rx_itr_val; return 0; } Loading @@ -63,22 +82,25 @@ static int wil_ethtoolops_set_coalesce(struct net_device *ndev, { struct wil6210_priv *wil = ndev_to_wil(ndev); wil_dbg_misc(wil, "%s(%d usec)\n", __func__, cp->rx_coalesce_usecs); wil_dbg_misc(wil, "%s(rx %d usec, tx %d usec)\n", __func__, cp->rx_coalesce_usecs, cp->tx_coalesce_usecs); if (wil->wdev->iftype == NL80211_IFTYPE_MONITOR) { wil_dbg_misc(wil, "No IRQ coalescing in monitor mode\n"); return -EINVAL; } /* only @rx_coalesce_usecs supported, ignore * other parameters /* only @rx_coalesce_usecs and @tx_coalesce_usecs supported, * ignore other parameters */ if (cp->rx_coalesce_usecs > WIL6210_ITR_TRSH_MAX) if (cp->rx_coalesce_usecs > WIL6210_ITR_TRSH_MAX || cp->tx_coalesce_usecs > WIL6210_ITR_TRSH_MAX) goto out_bad; wil->itr_trsh = cp->rx_coalesce_usecs; wil_set_itr_trsh(wil); wil->tx_max_burst_duration = cp->tx_coalesce_usecs; wil->rx_max_burst_duration = cp->rx_coalesce_usecs; wil_configure_interrupt_moderation(wil); return 0; Loading drivers/net/wireless/ath/wil6210/interrupt.c +93 −16 Original line number Diff line number Diff line Loading @@ -102,7 +102,7 @@ static void wil6210_mask_irq_pseudo(struct wil6210_priv *wil) iowrite32(WIL6210_IRQ_DISABLE, wil->csr + HOSTADDR(RGF_DMA_PSEUDO_CAUSE_MASK_SW)); clear_bit(wil_status_irqen, &wil->status); clear_bit(wil_status_irqen, wil->status); } void wil6210_unmask_irq_tx(struct wil6210_priv *wil) Loading Loading @@ -130,7 +130,7 @@ static void wil6210_unmask_irq_pseudo(struct wil6210_priv *wil) { wil_dbg_irq(wil, "%s()\n", __func__); set_bit(wil_status_irqen, &wil->status); set_bit(wil_status_irqen, wil->status); iowrite32(WIL6210_IRQ_PSEUDO_MASK, wil->csr + HOSTADDR(RGF_DMA_PSEUDO_CAUSE_MASK_SW)); Loading @@ -157,15 +157,91 @@ void wil_unmask_irq(struct wil6210_priv *wil) iowrite32(WIL_ICR_ICC_VALUE, wil->csr + HOSTADDR(RGF_DMA_EP_MISC_ICR) + offsetof(struct RGF_ICR, ICC)); /* interrupt moderation parameters */ wil_set_itr_trsh(wil); wil6210_unmask_irq_pseudo(wil); wil6210_unmask_irq_tx(wil); wil6210_unmask_irq_rx(wil); wil6210_unmask_irq_misc(wil); } /* target write operation */ #define W(a, v) do { iowrite32(v, wil->csr + HOSTADDR(a)); wmb(); } while (0) static void wil_configure_interrupt_moderation_new(struct wil6210_priv *wil) { /* Disable and clear tx counter before (re)configuration */ W(RGF_DMA_ITR_TX_CNT_CTL, BIT_DMA_ITR_TX_CNT_CTL_CLR); W(RGF_DMA_ITR_TX_CNT_TRSH, wil->tx_max_burst_duration); wil_info(wil, "set ITR_TX_CNT_TRSH = %d usec\n", wil->tx_max_burst_duration); /* Configure TX max burst duration timer to use usec units */ W(RGF_DMA_ITR_TX_CNT_CTL, BIT_DMA_ITR_TX_CNT_CTL_EN | BIT_DMA_ITR_TX_CNT_CTL_EXT_TIC_SEL); /* Disable and clear tx idle counter before (re)configuration */ W(RGF_DMA_ITR_TX_IDL_CNT_CTL, BIT_DMA_ITR_TX_IDL_CNT_CTL_CLR); W(RGF_DMA_ITR_TX_IDL_CNT_TRSH, wil->tx_interframe_timeout); wil_info(wil, "set ITR_TX_IDL_CNT_TRSH = %d usec\n", wil->tx_interframe_timeout); /* Configure TX max burst duration timer to use usec units */ W(RGF_DMA_ITR_TX_IDL_CNT_CTL, BIT_DMA_ITR_TX_IDL_CNT_CTL_EN | BIT_DMA_ITR_TX_IDL_CNT_CTL_EXT_TIC_SEL); /* Disable and clear rx counter before (re)configuration */ W(RGF_DMA_ITR_RX_CNT_CTL, BIT_DMA_ITR_RX_CNT_CTL_CLR); W(RGF_DMA_ITR_RX_CNT_TRSH, wil->rx_max_burst_duration); wil_info(wil, "set ITR_RX_CNT_TRSH = %d usec\n", wil->rx_max_burst_duration); /* Configure TX max burst duration timer to use usec units */ W(RGF_DMA_ITR_RX_CNT_CTL, BIT_DMA_ITR_RX_CNT_CTL_EN | BIT_DMA_ITR_RX_CNT_CTL_EXT_TIC_SEL); /* Disable and clear rx idle counter before (re)configuration */ W(RGF_DMA_ITR_RX_IDL_CNT_CTL, BIT_DMA_ITR_RX_IDL_CNT_CTL_CLR); W(RGF_DMA_ITR_RX_IDL_CNT_TRSH, wil->rx_interframe_timeout); wil_info(wil, "set ITR_RX_IDL_CNT_TRSH = %d usec\n", wil->rx_interframe_timeout); /* Configure TX max burst duration timer to use usec units */ W(RGF_DMA_ITR_RX_IDL_CNT_CTL, BIT_DMA_ITR_RX_IDL_CNT_CTL_EN | BIT_DMA_ITR_RX_IDL_CNT_CTL_EXT_TIC_SEL); } static void wil_configure_interrupt_moderation_lgc(struct wil6210_priv *wil) { /* disable, use usec resolution */ W(RGF_DMA_ITR_CNT_CRL, BIT_DMA_ITR_CNT_CRL_CLR); wil_info(wil, "set ITR_TRSH = %d usec\n", wil->rx_max_burst_duration); W(RGF_DMA_ITR_CNT_TRSH, wil->rx_max_burst_duration); /* start it */ W(RGF_DMA_ITR_CNT_CRL, BIT_DMA_ITR_CNT_CRL_EN | BIT_DMA_ITR_CNT_CRL_EXT_TICK); } #undef W void wil_configure_interrupt_moderation(struct wil6210_priv *wil) { wil_dbg_irq(wil, "%s()\n", __func__); /* disable interrupt moderation for monitor * to get better timestamp precision */ if (wil->wdev->iftype == NL80211_IFTYPE_MONITOR) return; if (test_bit(hw_capability_advanced_itr_moderation, wil->hw_capabilities)) wil_configure_interrupt_moderation_new(wil); else { /* Advanced interrupt moderation is not available before * Sparrow v2. Will use legacy interrupt moderation */ wil_configure_interrupt_moderation_lgc(wil); } } static irqreturn_t wil6210_irq_rx(int irq, void *cookie) { struct wil6210_priv *wil = cookie; Loading Loading @@ -194,18 +270,19 @@ static irqreturn_t wil6210_irq_rx(int irq, void *cookie) wil_dbg_irq(wil, "RX done\n"); if (isr & BIT_DMA_EP_RX_ICR_RX_HTRSH) wil_err_ratelimited(wil, "Received \"Rx buffer is in risk " "of overflow\" interrupt\n"); wil_err_ratelimited(wil, "Received \"Rx buffer is in risk of overflow\" interrupt\n"); isr &= ~(BIT_DMA_EP_RX_ICR_RX_DONE | BIT_DMA_EP_RX_ICR_RX_HTRSH); if (test_bit(wil_status_reset_done, &wil->status)) { if (test_bit(wil_status_napi_en, &wil->status)) { isr &= ~(BIT_DMA_EP_RX_ICR_RX_DONE | BIT_DMA_EP_RX_ICR_RX_HTRSH); if (test_bit(wil_status_reset_done, wil->status)) { if (test_bit(wil_status_napi_en, wil->status)) { wil_dbg_txrx(wil, "NAPI(Rx) schedule\n"); need_unmask = false; napi_schedule(&wil->napi_rx); } else { wil_err(wil, "Got Rx interrupt while " "stopping interface\n"); wil_err(wil, "Got Rx interrupt while stopping interface\n"); } } else { wil_err(wil, "Got Rx interrupt while in reset\n"); Loading Loading @@ -248,7 +325,7 @@ static irqreturn_t wil6210_irq_tx(int irq, void *cookie) isr &= ~BIT_DMA_EP_TX_ICR_TX_DONE; /* clear also all VRING interrupts */ isr &= ~(BIT(25) - 1UL); if (test_bit(wil_status_reset_done, &wil->status)) { if (test_bit(wil_status_reset_done, wil->status)) { wil_dbg_txrx(wil, "NAPI(Tx) schedule\n"); need_unmask = false; napi_schedule(&wil->napi_tx); Loading Loading @@ -310,7 +387,7 @@ static irqreturn_t wil6210_irq_misc(int irq, void *cookie) if (isr & ISR_MISC_FW_ERROR) { wil_err(wil, "Firmware error detected\n"); clear_bit(wil_status_fwready, &wil->status); clear_bit(wil_status_fwready, wil->status); /* * do not clear @isr here - we do 2-nd part in thread * there, user space get notified, and it should be done Loading @@ -321,7 +398,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); set_bit(wil_status_reset_done, &wil->status); set_bit(wil_status_reset_done, wil->status); /** * Actual FW ready indicated by the * WMI_FW_READY_EVENTID Loading Loading @@ -394,7 +471,7 @@ static irqreturn_t wil6210_thread_irq(int irq, void *cookie) */ static int wil6210_debug_irq_mask(struct wil6210_priv *wil, u32 pseudo_cause) { if (!test_bit(wil_status_irqen, &wil->status)) { if (!test_bit(wil_status_irqen, wil->status)) { u32 icm_rx = wil_ioread32_and_clear(wil->csr + HOSTADDR(RGF_DMA_EP_RX_ICR) + offsetof(struct RGF_ICR, ICM)); Loading drivers/net/wireless/ath/wil6210/main.c +116 −78 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
drivers/net/wireless/ath/wil6210/cfg80211.c +6 −6 Original line number Diff line number Diff line Loading @@ -162,7 +162,7 @@ int wil_cid_fill_sinfo(struct wil6210_priv *wil, int cid, sinfo->tx_packets = stats->tx_packets; sinfo->tx_failed = stats->tx_errors; if (test_bit(wil_status_fwconnected, &wil->status)) { if (test_bit(wil_status_fwconnected, wil->status)) { sinfo->filled |= STATION_INFO_SIGNAL; sinfo->signal = reply.evt.sqi; } Loading Loading @@ -282,7 +282,7 @@ static int wil_cfg80211_scan(struct wiphy *wiphy, } /* FW don't support scan after connection attempt */ if (test_bit(wil_status_dontscan, &wil->status)) { if (test_bit(wil_status_dontscan, wil->status)) { wil_err(wil, "Can't scan now\n"); return -EBUSY; } Loading Loading @@ -362,8 +362,8 @@ static int wil_cfg80211_connect(struct wiphy *wiphy, int ch; int rc = 0; if (test_bit(wil_status_fwconnecting, &wil->status) || test_bit(wil_status_fwconnected, &wil->status)) if (test_bit(wil_status_fwconnecting, wil->status) || test_bit(wil_status_fwconnected, wil->status)) return -EALREADY; wil_print_connect_params(wil, sme); Loading Loading @@ -450,7 +450,7 @@ static int wil_cfg80211_connect(struct wiphy *wiphy, memcpy(conn.bssid, bss->bssid, ETH_ALEN); memcpy(conn.dst_mac, bss->bssid, ETH_ALEN); set_bit(wil_status_fwconnecting, &wil->status); set_bit(wil_status_fwconnecting, wil->status); rc = wmi_send(wil, WMI_CONNECT_CMDID, &conn, sizeof(conn)); if (rc == 0) { Loading @@ -458,7 +458,7 @@ static int wil_cfg80211_connect(struct wiphy *wiphy, mod_timer(&wil->connect_timer, jiffies + msecs_to_jiffies(2000)); } else { clear_bit(wil_status_fwconnecting, &wil->status); clear_bit(wil_status_fwconnecting, wil->status); } out: Loading
drivers/net/wireless/ath/wil6210/debugfs.c +148 −16 Original line number Diff line number Diff line Loading @@ -50,6 +50,7 @@ static void wil_print_vring(struct seq_file *s, struct wil6210_priv *wil, char _s, char _h) { void __iomem *x = wmi_addr(wil, vring->hwtail); u32 v; seq_printf(s, "VRING %s = {\n", name); seq_printf(s, " pa = %pad\n", &vring->pa); Loading @@ -58,10 +59,12 @@ static void wil_print_vring(struct seq_file *s, struct wil6210_priv *wil, seq_printf(s, " swtail = %d\n", vring->swtail); seq_printf(s, " swhead = %d\n", vring->swhead); seq_printf(s, " hwtail = [0x%08x] -> ", vring->hwtail); if (x) seq_printf(s, "0x%08x\n", ioread32(x)); else if (x) { v = ioread32(x); seq_printf(s, "0x%08x = %d\n", v, v); } else { seq_puts(s, "???\n"); } if (vring->va && (vring->size < 1025)) { uint i; Loading Loading @@ -101,8 +104,8 @@ static int wil_vring_debugfs_show(struct seq_file *s, void *data) char name[10]; /* performance monitoring */ cycles_t now = get_cycles(); cycles_t idle = txdata->idle * 100; cycles_t total = now - txdata->begin; uint64_t idle = txdata->idle * 100; uint64_t total = now - txdata->begin; do_div(idle, total); txdata->begin = now; Loading @@ -110,9 +113,12 @@ static int wil_vring_debugfs_show(struct seq_file *s, void *data) snprintf(name, sizeof(name), "tx_%2d", i); seq_printf(s, "\n%pM CID %d TID %d [%3d|%3d] idle %3d%%\n", wil->sta[cid].addr, cid, tid, used, avail, (int)idle); seq_printf(s, "\n%pM CID %d TID %d BACK([%d] %d TU A%s) [%3d|%3d] idle %3d%%\n", wil->sta[cid].addr, cid, tid, txdata->agg_wsize, txdata->agg_timeout, txdata->agg_amsdu ? "+" : "-", used, avail, (int)idle); wil_print_vring(s, wil, name, vring, '_', 'H'); } Loading Loading @@ -384,24 +390,67 @@ static int wil6210_debugfs_create_pseudo_ISR(struct wil6210_priv *wil, return 0; } static const struct dbg_off itr_cnt_off[] = { static const struct dbg_off lgc_itr_cnt_off[] = { {"TRSH", S_IRUGO | S_IWUSR, HOSTADDR(RGF_DMA_ITR_CNT_TRSH), doff_io32}, {"DATA", S_IRUGO | S_IWUSR, HOSTADDR(RGF_DMA_ITR_CNT_DATA), doff_io32}, {"CTL", S_IRUGO | S_IWUSR, HOSTADDR(RGF_DMA_ITR_CNT_CRL), doff_io32}, {}, }; static const struct dbg_off tx_itr_cnt_off[] = { {"TRSH", S_IRUGO | S_IWUSR, HOSTADDR(RGF_DMA_ITR_TX_CNT_TRSH), doff_io32}, {"DATA", S_IRUGO | S_IWUSR, HOSTADDR(RGF_DMA_ITR_TX_CNT_DATA), doff_io32}, {"CTL", S_IRUGO | S_IWUSR, HOSTADDR(RGF_DMA_ITR_TX_CNT_CTL), doff_io32}, {"IDL_TRSH", S_IRUGO | S_IWUSR, HOSTADDR(RGF_DMA_ITR_TX_IDL_CNT_TRSH), doff_io32}, {"IDL_DATA", S_IRUGO | S_IWUSR, HOSTADDR(RGF_DMA_ITR_TX_IDL_CNT_DATA), doff_io32}, {"IDL_CTL", S_IRUGO | S_IWUSR, HOSTADDR(RGF_DMA_ITR_TX_IDL_CNT_CTL), doff_io32}, {}, }; static const struct dbg_off rx_itr_cnt_off[] = { {"TRSH", S_IRUGO | S_IWUSR, HOSTADDR(RGF_DMA_ITR_RX_CNT_TRSH), doff_io32}, {"DATA", S_IRUGO | S_IWUSR, HOSTADDR(RGF_DMA_ITR_RX_CNT_DATA), doff_io32}, {"CTL", S_IRUGO | S_IWUSR, HOSTADDR(RGF_DMA_ITR_RX_CNT_CTL), doff_io32}, {"IDL_TRSH", S_IRUGO | S_IWUSR, HOSTADDR(RGF_DMA_ITR_RX_IDL_CNT_TRSH), doff_io32}, {"IDL_DATA", S_IRUGO | S_IWUSR, HOSTADDR(RGF_DMA_ITR_RX_IDL_CNT_DATA), doff_io32}, {"IDL_CTL", S_IRUGO | S_IWUSR, HOSTADDR(RGF_DMA_ITR_RX_IDL_CNT_CTL), doff_io32}, {}, }; static int wil6210_debugfs_create_ITR_CNT(struct wil6210_priv *wil, struct dentry *parent) { struct dentry *d = debugfs_create_dir("ITR_CNT", parent); struct dentry *d, *dtx, *drx; d = debugfs_create_dir("ITR_CNT", parent); if (IS_ERR_OR_NULL(d)) return -ENODEV; dtx = debugfs_create_dir("TX", d); drx = debugfs_create_dir("RX", d); if (IS_ERR_OR_NULL(dtx) || IS_ERR_OR_NULL(drx)) return -ENODEV; wil6210_debugfs_init_offset(wil, d, (void * __force)wil->csr, itr_cnt_off); lgc_itr_cnt_off); wil6210_debugfs_init_offset(wil, dtx, (void * __force)wil->csr, tx_itr_cnt_off); wil6210_debugfs_init_offset(wil, drx, (void * __force)wil->csr, rx_itr_cnt_off); return 0; } Loading Loading @@ -558,6 +607,87 @@ static const struct file_operations fops_rxon = { .open = simple_open, }; /* block ack control, write: * - "add <ringid> <agg_size> <timeout>" to trigger ADDBA * - "del_tx <ringid> <reason>" to trigger DELBA for Tx side * - "del_rx <CID> <TID> <reason>" to trigger DELBA for Rx side */ static ssize_t wil_write_back(struct file *file, const char __user *buf, size_t len, loff_t *ppos) { struct wil6210_priv *wil = file->private_data; int rc; char *kbuf = kmalloc(len + 1, GFP_KERNEL); char cmd[8]; int p1, p2, p3; if (!kbuf) return -ENOMEM; rc = simple_write_to_buffer(kbuf, len, ppos, buf, len); if (rc != len) { kfree(kbuf); return rc >= 0 ? -EIO : rc; } kbuf[len] = '\0'; rc = sscanf(kbuf, "%8s %d %d %d", cmd, &p1, &p2, &p3); kfree(kbuf); if (rc < 0) return rc; if (rc < 2) return -EINVAL; if (0 == strcmp(cmd, "add")) { if (rc < 3) { wil_err(wil, "BACK: add require at least 2 params\n"); return -EINVAL; } if (rc < 4) p3 = 0; wmi_addba(wil, p1, p2, p3); } else if (0 == strcmp(cmd, "del_tx")) { if (rc < 3) p2 = WLAN_REASON_QSTA_LEAVE_QBSS; wmi_delba_tx(wil, p1, p2); } else if (0 == strcmp(cmd, "del_rx")) { if (rc < 3) { wil_err(wil, "BACK: del_rx require at least 2 params\n"); return -EINVAL; } if (rc < 4) p3 = WLAN_REASON_QSTA_LEAVE_QBSS; wmi_delba_rx(wil, mk_cidxtid(p1, p2), p3); } else { wil_err(wil, "BACK: Unrecognized command \"%s\"\n", cmd); return -EINVAL; } return len; } static ssize_t wil_read_back(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { static const char text[] = "block ack control, write:\n" " - \"add <ringid> <agg_size> <timeout>\" to trigger ADDBA\n" "If missing, <timeout> defaults to 0\n" " - \"del_tx <ringid> <reason>\" to trigger DELBA for Tx side\n" " - \"del_rx <CID> <TID> <reason>\" to trigger DELBA for Rx side\n" "If missing, <reason> set to \"STA_LEAVING\" (36)\n"; return simple_read_from_buffer(user_buf, count, ppos, text, sizeof(text)); } static const struct file_operations fops_back = { .read = wil_read_back, .write = wil_write_back, .open = simple_open, }; /*---tx_mgmt---*/ /* Write mgmt frame to this file to send it */ static ssize_t wil_write_file_txmgmt(struct file *file, const char __user *buf, Loading Loading @@ -1112,7 +1242,8 @@ static void wil_print_rxtid(struct seq_file *s, struct wil_tid_ampdu_rx *r) int i; u16 index = ((r->head_seq_num - r->ssn) & 0xfff) % r->buf_size; seq_printf(s, "0x%03x [", r->head_seq_num); seq_printf(s, "([%2d] %3d TU) 0x%03x [", r->buf_size, r->timeout, r->head_seq_num); for (i = 0; i < r->buf_size; i++) { if (i == index) seq_printf(s, "%c", r->reorder_buf[i] ? 'O' : '|'); Loading @@ -1123,10 +1254,10 @@ static void wil_print_rxtid(struct seq_file *s, struct wil_tid_ampdu_rx *r) } static int wil_sta_debugfs_show(struct seq_file *s, void *data) __acquires(&p->tid_rx_lock) __releases(&p->tid_rx_lock) { struct wil6210_priv *wil = s->private; int i, tid; unsigned long flags; for (i = 0; i < ARRAY_SIZE(wil->sta); i++) { struct wil_sta_info *p = &wil->sta[i]; Loading @@ -1147,7 +1278,7 @@ static int wil_sta_debugfs_show(struct seq_file *s, void *data) (p->data_port_open ? " data_port_open" : "")); if (p->status == wil_sta_connected) { spin_lock_irqsave(&p->tid_rx_lock, flags); spin_lock_bh(&p->tid_rx_lock); for (tid = 0; tid < WIL_STA_TID_NUM; tid++) { struct wil_tid_ampdu_rx *r = p->tid_rx[tid]; Loading @@ -1156,7 +1287,7 @@ static int wil_sta_debugfs_show(struct seq_file *s, void *data) wil_print_rxtid(s, r); } } spin_unlock_irqrestore(&p->tid_rx_lock, flags); spin_unlock_bh(&p->tid_rx_lock); } } Loading Loading @@ -1213,6 +1344,7 @@ static const struct { {"rxon", S_IWUSR, &fops_rxon}, {"tx_mgmt", S_IWUSR, &fops_txmgmt}, {"wmi_send", S_IWUSR, &fops_wmi}, {"back", S_IRUGO | S_IWUSR, &fops_back}, {"temp", S_IRUGO, &fops_temp}, {"freq", S_IRUGO, &fops_freq}, {"link", S_IRUGO, &fops_link}, Loading Loading @@ -1257,7 +1389,7 @@ static void wil6210_debugfs_init_isr(struct wil6210_priv *wil, /* fields in struct wil6210_priv */ static const struct dbg_off dbg_wil_off[] = { WIL_FIELD(secure_pcp, S_IRUGO | S_IWUSR, doff_u32), WIL_FIELD(status, S_IRUGO | S_IWUSR, doff_ulong), WIL_FIELD(status[0], S_IRUGO | S_IWUSR, doff_ulong), WIL_FIELD(fw_version, S_IRUGO, doff_u32), WIL_FIELD(hw_version, S_IRUGO, doff_x32), WIL_FIELD(recovery_count, S_IRUGO, doff_u32), Loading
drivers/net/wireless/ath/wil6210/ethtool.c +34 −12 Original line number Diff line number Diff line Loading @@ -45,16 +45,35 @@ static int wil_ethtoolops_get_coalesce(struct net_device *ndev, struct ethtool_coalesce *cp) { struct wil6210_priv *wil = ndev_to_wil(ndev); u32 itr_en, itr_val = 0; u32 tx_itr_en, tx_itr_val = 0; u32 rx_itr_en, rx_itr_val = 0; wil_dbg_misc(wil, "%s()\n", __func__); itr_en = ioread32(wil->csr + HOSTADDR(RGF_DMA_ITR_CNT_CRL)); if (itr_en & BIT_DMA_ITR_CNT_CRL_EN) itr_val = ioread32(wil->csr + HOSTADDR(RGF_DMA_ITR_CNT_TRSH)); cp->rx_coalesce_usecs = itr_val; if (test_bit(hw_capability_advanced_itr_moderation, wil->hw_capabilities)) { tx_itr_en = ioread32(wil->csr + HOSTADDR(RGF_DMA_ITR_TX_CNT_CTL)); if (tx_itr_en & BIT_DMA_ITR_TX_CNT_CTL_EN) tx_itr_val = ioread32(wil->csr + HOSTADDR(RGF_DMA_ITR_TX_CNT_TRSH)); rx_itr_en = ioread32(wil->csr + HOSTADDR(RGF_DMA_ITR_RX_CNT_CTL)); if (rx_itr_en & BIT_DMA_ITR_RX_CNT_CTL_EN) rx_itr_val = ioread32(wil->csr + HOSTADDR(RGF_DMA_ITR_RX_CNT_TRSH)); } else { rx_itr_en = ioread32(wil->csr + HOSTADDR(RGF_DMA_ITR_CNT_CRL)); if (rx_itr_en & BIT_DMA_ITR_CNT_CRL_EN) rx_itr_val = ioread32(wil->csr + HOSTADDR(RGF_DMA_ITR_CNT_TRSH)); } cp->tx_coalesce_usecs = tx_itr_val; cp->rx_coalesce_usecs = rx_itr_val; return 0; } Loading @@ -63,22 +82,25 @@ static int wil_ethtoolops_set_coalesce(struct net_device *ndev, { struct wil6210_priv *wil = ndev_to_wil(ndev); wil_dbg_misc(wil, "%s(%d usec)\n", __func__, cp->rx_coalesce_usecs); wil_dbg_misc(wil, "%s(rx %d usec, tx %d usec)\n", __func__, cp->rx_coalesce_usecs, cp->tx_coalesce_usecs); if (wil->wdev->iftype == NL80211_IFTYPE_MONITOR) { wil_dbg_misc(wil, "No IRQ coalescing in monitor mode\n"); return -EINVAL; } /* only @rx_coalesce_usecs supported, ignore * other parameters /* only @rx_coalesce_usecs and @tx_coalesce_usecs supported, * ignore other parameters */ if (cp->rx_coalesce_usecs > WIL6210_ITR_TRSH_MAX) if (cp->rx_coalesce_usecs > WIL6210_ITR_TRSH_MAX || cp->tx_coalesce_usecs > WIL6210_ITR_TRSH_MAX) goto out_bad; wil->itr_trsh = cp->rx_coalesce_usecs; wil_set_itr_trsh(wil); wil->tx_max_burst_duration = cp->tx_coalesce_usecs; wil->rx_max_burst_duration = cp->rx_coalesce_usecs; wil_configure_interrupt_moderation(wil); return 0; Loading
drivers/net/wireless/ath/wil6210/interrupt.c +93 −16 Original line number Diff line number Diff line Loading @@ -102,7 +102,7 @@ static void wil6210_mask_irq_pseudo(struct wil6210_priv *wil) iowrite32(WIL6210_IRQ_DISABLE, wil->csr + HOSTADDR(RGF_DMA_PSEUDO_CAUSE_MASK_SW)); clear_bit(wil_status_irqen, &wil->status); clear_bit(wil_status_irqen, wil->status); } void wil6210_unmask_irq_tx(struct wil6210_priv *wil) Loading Loading @@ -130,7 +130,7 @@ static void wil6210_unmask_irq_pseudo(struct wil6210_priv *wil) { wil_dbg_irq(wil, "%s()\n", __func__); set_bit(wil_status_irqen, &wil->status); set_bit(wil_status_irqen, wil->status); iowrite32(WIL6210_IRQ_PSEUDO_MASK, wil->csr + HOSTADDR(RGF_DMA_PSEUDO_CAUSE_MASK_SW)); Loading @@ -157,15 +157,91 @@ void wil_unmask_irq(struct wil6210_priv *wil) iowrite32(WIL_ICR_ICC_VALUE, wil->csr + HOSTADDR(RGF_DMA_EP_MISC_ICR) + offsetof(struct RGF_ICR, ICC)); /* interrupt moderation parameters */ wil_set_itr_trsh(wil); wil6210_unmask_irq_pseudo(wil); wil6210_unmask_irq_tx(wil); wil6210_unmask_irq_rx(wil); wil6210_unmask_irq_misc(wil); } /* target write operation */ #define W(a, v) do { iowrite32(v, wil->csr + HOSTADDR(a)); wmb(); } while (0) static void wil_configure_interrupt_moderation_new(struct wil6210_priv *wil) { /* Disable and clear tx counter before (re)configuration */ W(RGF_DMA_ITR_TX_CNT_CTL, BIT_DMA_ITR_TX_CNT_CTL_CLR); W(RGF_DMA_ITR_TX_CNT_TRSH, wil->tx_max_burst_duration); wil_info(wil, "set ITR_TX_CNT_TRSH = %d usec\n", wil->tx_max_burst_duration); /* Configure TX max burst duration timer to use usec units */ W(RGF_DMA_ITR_TX_CNT_CTL, BIT_DMA_ITR_TX_CNT_CTL_EN | BIT_DMA_ITR_TX_CNT_CTL_EXT_TIC_SEL); /* Disable and clear tx idle counter before (re)configuration */ W(RGF_DMA_ITR_TX_IDL_CNT_CTL, BIT_DMA_ITR_TX_IDL_CNT_CTL_CLR); W(RGF_DMA_ITR_TX_IDL_CNT_TRSH, wil->tx_interframe_timeout); wil_info(wil, "set ITR_TX_IDL_CNT_TRSH = %d usec\n", wil->tx_interframe_timeout); /* Configure TX max burst duration timer to use usec units */ W(RGF_DMA_ITR_TX_IDL_CNT_CTL, BIT_DMA_ITR_TX_IDL_CNT_CTL_EN | BIT_DMA_ITR_TX_IDL_CNT_CTL_EXT_TIC_SEL); /* Disable and clear rx counter before (re)configuration */ W(RGF_DMA_ITR_RX_CNT_CTL, BIT_DMA_ITR_RX_CNT_CTL_CLR); W(RGF_DMA_ITR_RX_CNT_TRSH, wil->rx_max_burst_duration); wil_info(wil, "set ITR_RX_CNT_TRSH = %d usec\n", wil->rx_max_burst_duration); /* Configure TX max burst duration timer to use usec units */ W(RGF_DMA_ITR_RX_CNT_CTL, BIT_DMA_ITR_RX_CNT_CTL_EN | BIT_DMA_ITR_RX_CNT_CTL_EXT_TIC_SEL); /* Disable and clear rx idle counter before (re)configuration */ W(RGF_DMA_ITR_RX_IDL_CNT_CTL, BIT_DMA_ITR_RX_IDL_CNT_CTL_CLR); W(RGF_DMA_ITR_RX_IDL_CNT_TRSH, wil->rx_interframe_timeout); wil_info(wil, "set ITR_RX_IDL_CNT_TRSH = %d usec\n", wil->rx_interframe_timeout); /* Configure TX max burst duration timer to use usec units */ W(RGF_DMA_ITR_RX_IDL_CNT_CTL, BIT_DMA_ITR_RX_IDL_CNT_CTL_EN | BIT_DMA_ITR_RX_IDL_CNT_CTL_EXT_TIC_SEL); } static void wil_configure_interrupt_moderation_lgc(struct wil6210_priv *wil) { /* disable, use usec resolution */ W(RGF_DMA_ITR_CNT_CRL, BIT_DMA_ITR_CNT_CRL_CLR); wil_info(wil, "set ITR_TRSH = %d usec\n", wil->rx_max_burst_duration); W(RGF_DMA_ITR_CNT_TRSH, wil->rx_max_burst_duration); /* start it */ W(RGF_DMA_ITR_CNT_CRL, BIT_DMA_ITR_CNT_CRL_EN | BIT_DMA_ITR_CNT_CRL_EXT_TICK); } #undef W void wil_configure_interrupt_moderation(struct wil6210_priv *wil) { wil_dbg_irq(wil, "%s()\n", __func__); /* disable interrupt moderation for monitor * to get better timestamp precision */ if (wil->wdev->iftype == NL80211_IFTYPE_MONITOR) return; if (test_bit(hw_capability_advanced_itr_moderation, wil->hw_capabilities)) wil_configure_interrupt_moderation_new(wil); else { /* Advanced interrupt moderation is not available before * Sparrow v2. Will use legacy interrupt moderation */ wil_configure_interrupt_moderation_lgc(wil); } } static irqreturn_t wil6210_irq_rx(int irq, void *cookie) { struct wil6210_priv *wil = cookie; Loading Loading @@ -194,18 +270,19 @@ static irqreturn_t wil6210_irq_rx(int irq, void *cookie) wil_dbg_irq(wil, "RX done\n"); if (isr & BIT_DMA_EP_RX_ICR_RX_HTRSH) wil_err_ratelimited(wil, "Received \"Rx buffer is in risk " "of overflow\" interrupt\n"); wil_err_ratelimited(wil, "Received \"Rx buffer is in risk of overflow\" interrupt\n"); isr &= ~(BIT_DMA_EP_RX_ICR_RX_DONE | BIT_DMA_EP_RX_ICR_RX_HTRSH); if (test_bit(wil_status_reset_done, &wil->status)) { if (test_bit(wil_status_napi_en, &wil->status)) { isr &= ~(BIT_DMA_EP_RX_ICR_RX_DONE | BIT_DMA_EP_RX_ICR_RX_HTRSH); if (test_bit(wil_status_reset_done, wil->status)) { if (test_bit(wil_status_napi_en, wil->status)) { wil_dbg_txrx(wil, "NAPI(Rx) schedule\n"); need_unmask = false; napi_schedule(&wil->napi_rx); } else { wil_err(wil, "Got Rx interrupt while " "stopping interface\n"); wil_err(wil, "Got Rx interrupt while stopping interface\n"); } } else { wil_err(wil, "Got Rx interrupt while in reset\n"); Loading Loading @@ -248,7 +325,7 @@ static irqreturn_t wil6210_irq_tx(int irq, void *cookie) isr &= ~BIT_DMA_EP_TX_ICR_TX_DONE; /* clear also all VRING interrupts */ isr &= ~(BIT(25) - 1UL); if (test_bit(wil_status_reset_done, &wil->status)) { if (test_bit(wil_status_reset_done, wil->status)) { wil_dbg_txrx(wil, "NAPI(Tx) schedule\n"); need_unmask = false; napi_schedule(&wil->napi_tx); Loading Loading @@ -310,7 +387,7 @@ static irqreturn_t wil6210_irq_misc(int irq, void *cookie) if (isr & ISR_MISC_FW_ERROR) { wil_err(wil, "Firmware error detected\n"); clear_bit(wil_status_fwready, &wil->status); clear_bit(wil_status_fwready, wil->status); /* * do not clear @isr here - we do 2-nd part in thread * there, user space get notified, and it should be done Loading @@ -321,7 +398,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); set_bit(wil_status_reset_done, &wil->status); set_bit(wil_status_reset_done, wil->status); /** * Actual FW ready indicated by the * WMI_FW_READY_EVENTID Loading Loading @@ -394,7 +471,7 @@ static irqreturn_t wil6210_thread_irq(int irq, void *cookie) */ static int wil6210_debug_irq_mask(struct wil6210_priv *wil, u32 pseudo_cause) { if (!test_bit(wil_status_irqen, &wil->status)) { if (!test_bit(wil_status_irqen, wil->status)) { u32 icm_rx = wil_ioread32_and_clear(wil->csr + HOSTADDR(RGF_DMA_EP_RX_ICR) + offsetof(struct RGF_ICR, ICM)); Loading
drivers/net/wireless/ath/wil6210/main.c +116 −78 File changed.Preview size limit exceeded, changes collapsed. Show changes