.. | .. |
---|
| 1 | +// SPDX-License-Identifier: ISC |
---|
1 | 2 | /* |
---|
2 | 3 | * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name> |
---|
3 | | - * |
---|
4 | | - * Permission to use, copy, modify, and/or distribute this software for any |
---|
5 | | - * purpose with or without fee is hereby granted, provided that the above |
---|
6 | | - * copyright notice and this permission notice appear in all copies. |
---|
7 | | - * |
---|
8 | | - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
---|
9 | | - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
---|
10 | | - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
---|
11 | | - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
---|
12 | | - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
---|
13 | | - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
---|
14 | | - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
---|
15 | 4 | */ |
---|
16 | 5 | |
---|
17 | 6 | #include <linux/module.h> |
---|
.. | .. |
---|
24 | 13 | |
---|
25 | 14 | timeout /= 10; |
---|
26 | 15 | do { |
---|
27 | | - cur = dev->bus->rr(dev, offset) & mask; |
---|
| 16 | + cur = __mt76_rr(dev, offset) & mask; |
---|
28 | 17 | if (cur == val) |
---|
29 | 18 | return true; |
---|
30 | 19 | |
---|
.. | .. |
---|
42 | 31 | |
---|
43 | 32 | timeout /= 10; |
---|
44 | 33 | do { |
---|
45 | | - cur = dev->bus->rr(dev, offset) & mask; |
---|
| 34 | + cur = __mt76_rr(dev, offset) & mask; |
---|
46 | 35 | if (cur == val) |
---|
47 | 36 | return true; |
---|
48 | 37 | |
---|
.. | .. |
---|
53 | 42 | } |
---|
54 | 43 | EXPORT_SYMBOL_GPL(__mt76_poll_msec); |
---|
55 | 44 | |
---|
56 | | -int mt76_wcid_alloc(unsigned long *mask, int size) |
---|
| 45 | +int mt76_wcid_alloc(u32 *mask, int size) |
---|
57 | 46 | { |
---|
58 | 47 | int i, idx = 0, cur; |
---|
59 | 48 | |
---|
60 | | - for (i = 0; i < size / BITS_PER_LONG; i++) { |
---|
| 49 | + for (i = 0; i < DIV_ROUND_UP(size, 32); i++) { |
---|
61 | 50 | idx = ffs(~mask[i]); |
---|
62 | 51 | if (!idx) |
---|
63 | 52 | continue; |
---|
64 | 53 | |
---|
65 | 54 | idx--; |
---|
66 | | - cur = i * BITS_PER_LONG + idx; |
---|
| 55 | + cur = i * 32 + idx; |
---|
67 | 56 | if (cur >= size) |
---|
68 | 57 | break; |
---|
69 | 58 | |
---|
.. | .. |
---|
75 | 64 | } |
---|
76 | 65 | EXPORT_SYMBOL_GPL(mt76_wcid_alloc); |
---|
77 | 66 | |
---|
| 67 | +int mt76_get_min_avg_rssi(struct mt76_dev *dev, bool ext_phy) |
---|
| 68 | +{ |
---|
| 69 | + struct mt76_wcid *wcid; |
---|
| 70 | + int i, j, min_rssi = 0; |
---|
| 71 | + s8 cur_rssi; |
---|
| 72 | + |
---|
| 73 | + local_bh_disable(); |
---|
| 74 | + rcu_read_lock(); |
---|
| 75 | + |
---|
| 76 | + for (i = 0; i < ARRAY_SIZE(dev->wcid_mask); i++) { |
---|
| 77 | + u32 mask = dev->wcid_mask[i]; |
---|
| 78 | + u32 phy_mask = dev->wcid_phy_mask[i]; |
---|
| 79 | + |
---|
| 80 | + if (!mask) |
---|
| 81 | + continue; |
---|
| 82 | + |
---|
| 83 | + for (j = i * 32; mask; j++, mask >>= 1, phy_mask >>= 1) { |
---|
| 84 | + if (!(mask & 1)) |
---|
| 85 | + continue; |
---|
| 86 | + |
---|
| 87 | + if (!!(phy_mask & 1) != ext_phy) |
---|
| 88 | + continue; |
---|
| 89 | + |
---|
| 90 | + wcid = rcu_dereference(dev->wcid[j]); |
---|
| 91 | + if (!wcid) |
---|
| 92 | + continue; |
---|
| 93 | + |
---|
| 94 | + spin_lock(&dev->rx_lock); |
---|
| 95 | + if (wcid->inactive_count++ < 5) |
---|
| 96 | + cur_rssi = -ewma_signal_read(&wcid->rssi); |
---|
| 97 | + else |
---|
| 98 | + cur_rssi = 0; |
---|
| 99 | + spin_unlock(&dev->rx_lock); |
---|
| 100 | + |
---|
| 101 | + if (cur_rssi < min_rssi) |
---|
| 102 | + min_rssi = cur_rssi; |
---|
| 103 | + } |
---|
| 104 | + } |
---|
| 105 | + |
---|
| 106 | + rcu_read_unlock(); |
---|
| 107 | + local_bh_enable(); |
---|
| 108 | + |
---|
| 109 | + return min_rssi; |
---|
| 110 | +} |
---|
| 111 | +EXPORT_SYMBOL_GPL(mt76_get_min_avg_rssi); |
---|
| 112 | + |
---|
| 113 | +int __mt76_worker_fn(void *ptr) |
---|
| 114 | +{ |
---|
| 115 | + struct mt76_worker *w = ptr; |
---|
| 116 | + |
---|
| 117 | + while (!kthread_should_stop()) { |
---|
| 118 | + set_current_state(TASK_INTERRUPTIBLE); |
---|
| 119 | + |
---|
| 120 | + if (kthread_should_park()) { |
---|
| 121 | + kthread_parkme(); |
---|
| 122 | + continue; |
---|
| 123 | + } |
---|
| 124 | + |
---|
| 125 | + if (!test_and_clear_bit(MT76_WORKER_SCHEDULED, &w->state)) { |
---|
| 126 | + schedule(); |
---|
| 127 | + continue; |
---|
| 128 | + } |
---|
| 129 | + |
---|
| 130 | + set_bit(MT76_WORKER_RUNNING, &w->state); |
---|
| 131 | + set_current_state(TASK_RUNNING); |
---|
| 132 | + w->fn(w); |
---|
| 133 | + cond_resched(); |
---|
| 134 | + clear_bit(MT76_WORKER_RUNNING, &w->state); |
---|
| 135 | + } |
---|
| 136 | + |
---|
| 137 | + return 0; |
---|
| 138 | +} |
---|
| 139 | +EXPORT_SYMBOL_GPL(__mt76_worker_fn); |
---|
| 140 | + |
---|
78 | 141 | MODULE_LICENSE("Dual BSD/GPL"); |
---|