diff options
author | David S. Miller <davem@davemloft.net> | 2018-02-27 11:14:57 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2018-02-27 11:14:57 -0500 |
commit | afdd6ae352527b83a3e13c040b22f455fe6537db (patch) | |
tree | afe045b5090b2e38629c68623bd7a9daa1648970 | |
parent | 23363b87a80a2eeb366c9b5b93248b7d73125ba8 (diff) | |
parent | 8c6ad9cc51574c8f20b5777e97b42457802ac36d (diff) |
Merge branch 'ieee802154-for-davem-2018-02-26' of git://git.kernel.org/pub/scm/linux/kernel/git/sschmidt/wpan-next
Stefan Schmidt says:
====================
pull-request: ieee802154-next 2018-02-26
An update from ieee802154 for *net-next*
Alexander corrected a setting which got lost during some 6lowpan rework
a while back and Xue Liu provided us with a new driver for the MCR20A
transceiver.
If there are any issues let me know. If not, please pull.
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | Documentation/devicetree/bindings/net/ieee802154/mcr20a.txt | 23 | ||||
-rw-r--r-- | MAINTAINERS | 9 | ||||
-rw-r--r-- | drivers/net/ieee802154/Kconfig | 11 | ||||
-rw-r--r-- | drivers/net/ieee802154/Makefile | 1 | ||||
-rw-r--r-- | drivers/net/ieee802154/mcr20a.c | 1413 | ||||
-rw-r--r-- | drivers/net/ieee802154/mcr20a.h | 498 | ||||
-rw-r--r-- | net/ieee802154/6lowpan/core.c | 1 |
7 files changed, 1956 insertions, 0 deletions
diff --git a/Documentation/devicetree/bindings/net/ieee802154/mcr20a.txt b/Documentation/devicetree/bindings/net/ieee802154/mcr20a.txt new file mode 100644 index 000000000000..2aaef567c5be --- /dev/null +++ b/Documentation/devicetree/bindings/net/ieee802154/mcr20a.txt | |||
@@ -0,0 +1,23 @@ | |||
1 | * MCR20A IEEE 802.15.4 * | ||
2 | |||
3 | Required properties: | ||
4 | - compatible: should be "nxp,mcr20a" | ||
5 | - spi-max-frequency: maximal bus speed, should be set to a frequency | ||
6 | lower than 9000000 depends sync or async operation mode | ||
7 | - reg: the chipselect index | ||
8 | - interrupts: the interrupt generated by the device. Non high-level | ||
9 | can occur deadlocks while handling isr. | ||
10 | |||
11 | Optional properties: | ||
12 | - rst_b-gpio: GPIO spec for the RST_B pin | ||
13 | |||
14 | Example: | ||
15 | |||
16 | mcr20a@0 { | ||
17 | compatible = "nxp,mcr20a"; | ||
18 | spi-max-frequency = <9000000>; | ||
19 | reg = <0>; | ||
20 | interrupts = <17 2>; | ||
21 | interrupt-parent = <&gpio>; | ||
22 | rst_b-gpio = <&gpio 27 1> | ||
23 | }; | ||
diff --git a/MAINTAINERS b/MAINTAINERS index 93a12af4f180..e0b39004edc0 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -8592,6 +8592,15 @@ S: Maintained | |||
8592 | F: Documentation/ABI/testing/sysfs-bus-iio-potentiometer-mcp4531 | 8592 | F: Documentation/ABI/testing/sysfs-bus-iio-potentiometer-mcp4531 |
8593 | F: drivers/iio/potentiometer/mcp4531.c | 8593 | F: drivers/iio/potentiometer/mcp4531.c |
8594 | 8594 | ||
8595 | MCR20A IEEE-802.15.4 RADIO DRIVER | ||
8596 | M: Xue Liu <liuxuenetmail@gmail.com> | ||
8597 | L: linux-wpan@vger.kernel.org | ||
8598 | W: https://github.com/xueliu/mcr20a-linux | ||
8599 | S: Maintained | ||
8600 | F: drivers/net/ieee802154/mcr20a.c | ||
8601 | F: drivers/net/ieee802154/mcr20a.h | ||
8602 | F: Documentation/devicetree/bindings/net/ieee802154/mcr20a.txt | ||
8603 | |||
8595 | MEASUREMENT COMPUTING CIO-DAC IIO DRIVER | 8604 | MEASUREMENT COMPUTING CIO-DAC IIO DRIVER |
8596 | M: William Breathitt Gray <vilhelm.gray@gmail.com> | 8605 | M: William Breathitt Gray <vilhelm.gray@gmail.com> |
8597 | L: linux-iio@vger.kernel.org | 8606 | L: linux-iio@vger.kernel.org |
diff --git a/drivers/net/ieee802154/Kconfig b/drivers/net/ieee802154/Kconfig index 303ba4133920..8782f5655e3f 100644 --- a/drivers/net/ieee802154/Kconfig +++ b/drivers/net/ieee802154/Kconfig | |||
@@ -104,3 +104,14 @@ config IEEE802154_CA8210_DEBUGFS | |||
104 | exposes a debugfs node for each CA8210 instance which allows | 104 | exposes a debugfs node for each CA8210 instance which allows |
105 | direct use of the Cascoda API, exposing the 802.15.4 MAC | 105 | direct use of the Cascoda API, exposing the 802.15.4 MAC |
106 | management entities. | 106 | management entities. |
107 | |||
108 | config IEEE802154_MCR20A | ||
109 | tristate "MCR20A transceiver driver" | ||
110 | depends on IEEE802154_DRIVERS && MAC802154 | ||
111 | depends on SPI | ||
112 | ---help--- | ||
113 | Say Y here to enable the MCR20A SPI 802.15.4 wireless | ||
114 | controller. | ||
115 | |||
116 | This driver can also be built as a module. To do so, say M here. | ||
117 | the module will be called 'mcr20a'. | ||
diff --git a/drivers/net/ieee802154/Makefile b/drivers/net/ieee802154/Makefile index bea1de5e726c..104744d5a668 100644 --- a/drivers/net/ieee802154/Makefile +++ b/drivers/net/ieee802154/Makefile | |||
@@ -6,3 +6,4 @@ obj-$(CONFIG_IEEE802154_CC2520) += cc2520.o | |||
6 | obj-$(CONFIG_IEEE802154_ATUSB) += atusb.o | 6 | obj-$(CONFIG_IEEE802154_ATUSB) += atusb.o |
7 | obj-$(CONFIG_IEEE802154_ADF7242) += adf7242.o | 7 | obj-$(CONFIG_IEEE802154_ADF7242) += adf7242.o |
8 | obj-$(CONFIG_IEEE802154_CA8210) += ca8210.o | 8 | obj-$(CONFIG_IEEE802154_CA8210) += ca8210.o |
9 | obj-$(CONFIG_IEEE802154_MCR20A) += mcr20a.o | ||
diff --git a/drivers/net/ieee802154/mcr20a.c b/drivers/net/ieee802154/mcr20a.c new file mode 100644 index 000000000000..d9eb22a52551 --- /dev/null +++ b/drivers/net/ieee802154/mcr20a.c | |||
@@ -0,0 +1,1413 @@ | |||
1 | /* | ||
2 | * Driver for NXP MCR20A 802.15.4 Wireless-PAN Networking controller | ||
3 | * | ||
4 | * Copyright (C) 2018 Xue Liu <liuxuenetmail@gmail.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 | ||
8 | * as published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | */ | ||
16 | #include <linux/kernel.h> | ||
17 | #include <linux/module.h> | ||
18 | #include <linux/gpio.h> | ||
19 | #include <linux/spi/spi.h> | ||
20 | #include <linux/workqueue.h> | ||
21 | #include <linux/interrupt.h> | ||
22 | #include <linux/skbuff.h> | ||
23 | #include <linux/of_gpio.h> | ||
24 | #include <linux/regmap.h> | ||
25 | #include <linux/ieee802154.h> | ||
26 | #include <linux/debugfs.h> | ||
27 | |||
28 | #include <net/mac802154.h> | ||
29 | #include <net/cfg802154.h> | ||
30 | |||
31 | #include <linux/device.h> | ||
32 | |||
33 | #include "mcr20a.h" | ||
34 | |||
35 | #define SPI_COMMAND_BUFFER 3 | ||
36 | |||
37 | #define REGISTER_READ BIT(7) | ||
38 | #define REGISTER_WRITE (0 << 7) | ||
39 | #define REGISTER_ACCESS (0 << 6) | ||
40 | #define PACKET_BUFF_BURST_ACCESS BIT(6) | ||
41 | #define PACKET_BUFF_BYTE_ACCESS BIT(5) | ||
42 | |||
43 | #define MCR20A_WRITE_REG(x) (x) | ||
44 | #define MCR20A_READ_REG(x) (REGISTER_READ | (x)) | ||
45 | #define MCR20A_BURST_READ_PACKET_BUF (0xC0) | ||
46 | #define MCR20A_BURST_WRITE_PACKET_BUF (0x40) | ||
47 | |||
48 | #define MCR20A_CMD_REG 0x80 | ||
49 | #define MCR20A_CMD_REG_MASK 0x3f | ||
50 | #define MCR20A_CMD_WRITE 0x40 | ||
51 | #define MCR20A_CMD_FB 0x20 | ||
52 | |||
53 | /* Number of Interrupt Request Status Register */ | ||
54 | #define MCR20A_IRQSTS_NUM 2 /* only IRQ_STS1 and IRQ_STS2 */ | ||
55 | |||
56 | /* MCR20A CCA Type */ | ||
57 | enum { | ||
58 | MCR20A_CCA_ED, // energy detect - CCA bit not active, | ||
59 | // not to be used for T and CCCA sequences | ||
60 | MCR20A_CCA_MODE1, // energy detect - CCA bit ACTIVE | ||
61 | MCR20A_CCA_MODE2, // 802.15.4 compliant signal detect - CCA bit ACTIVE | ||
62 | MCR20A_CCA_MODE3 | ||
63 | }; | ||
64 | |||
65 | enum { | ||
66 | MCR20A_XCVSEQ_IDLE = 0x00, | ||
67 | MCR20A_XCVSEQ_RX = 0x01, | ||
68 | MCR20A_XCVSEQ_TX = 0x02, | ||
69 | MCR20A_XCVSEQ_CCA = 0x03, | ||
70 | MCR20A_XCVSEQ_TR = 0x04, | ||
71 | MCR20A_XCVSEQ_CCCA = 0x05, | ||
72 | }; | ||
73 | |||
74 | /* IEEE-802.15.4 defined constants (2.4 GHz logical channels) */ | ||
75 | #define MCR20A_MIN_CHANNEL (11) | ||
76 | #define MCR20A_MAX_CHANNEL (26) | ||
77 | #define MCR20A_CHANNEL_SPACING (5) | ||
78 | |||
79 | /* MCR20A CCA Threshold constans */ | ||
80 | #define MCR20A_MIN_CCA_THRESHOLD (0x6EU) | ||
81 | #define MCR20A_MAX_CCA_THRESHOLD (0x00U) | ||
82 | |||
83 | /* version 0C */ | ||
84 | #define MCR20A_OVERWRITE_VERSION (0x0C) | ||
85 | |||
86 | /* MCR20A PLL configurations */ | ||
87 | static const u8 PLL_INT[16] = { | ||
88 | /* 2405 */ 0x0B, /* 2410 */ 0x0B, /* 2415 */ 0x0B, | ||
89 | /* 2420 */ 0x0B, /* 2425 */ 0x0B, /* 2430 */ 0x0B, | ||
90 | /* 2435 */ 0x0C, /* 2440 */ 0x0C, /* 2445 */ 0x0C, | ||
91 | /* 2450 */ 0x0C, /* 2455 */ 0x0C, /* 2460 */ 0x0C, | ||
92 | /* 2465 */ 0x0D, /* 2470 */ 0x0D, /* 2475 */ 0x0D, | ||
93 | /* 2480 */ 0x0D | ||
94 | }; | ||
95 | |||
96 | static const u8 PLL_FRAC[16] = { | ||
97 | /* 2405 */ 0x28, /* 2410 */ 0x50, /* 2415 */ 0x78, | ||
98 | /* 2420 */ 0xA0, /* 2425 */ 0xC8, /* 2430 */ 0xF0, | ||
99 | /* 2435 */ 0x18, /* 2440 */ 0x40, /* 2445 */ 0x68, | ||
100 | /* 2450 */ 0x90, /* 2455 */ 0xB8, /* 2460 */ 0xE0, | ||
101 | /* 2465 */ 0x08, /* 2470 */ 0x30, /* 2475 */ 0x58, | ||
102 | /* 2480 */ 0x80 | ||
103 | }; | ||
104 | |||
105 | static const struct reg_sequence mar20a_iar_overwrites[] = { | ||
106 | { IAR_MISC_PAD_CTRL, 0x02 }, | ||
107 | { IAR_VCO_CTRL1, 0xB3 }, | ||
108 | { IAR_VCO_CTRL2, 0x07 }, | ||
109 | { IAR_PA_TUNING, 0x71 }, | ||
110 | { IAR_CHF_IBUF, 0x2F }, | ||
111 | { IAR_CHF_QBUF, 0x2F }, | ||
112 | { IAR_CHF_IRIN, 0x24 }, | ||
113 | { IAR_CHF_QRIN, 0x24 }, | ||
114 | { IAR_CHF_IL, 0x24 }, | ||
115 | { IAR_CHF_QL, 0x24 }, | ||
116 | { IAR_CHF_CC1, 0x32 }, | ||
117 | { IAR_CHF_CCL, 0x1D }, | ||
118 | { IAR_CHF_CC2, 0x2D }, | ||
119 | { IAR_CHF_IROUT, 0x24 }, | ||
120 | { IAR_CHF_QROUT, 0x24 }, | ||
121 | { IAR_PA_CAL, 0x28 }, | ||
122 | { IAR_AGC_THR1, 0x55 }, | ||
123 | { IAR_AGC_THR2, 0x2D }, | ||
124 | { IAR_ATT_RSSI1, 0x5F }, | ||
125 | { IAR_ATT_RSSI2, 0x8F }, | ||
126 | { IAR_RSSI_OFFSET, 0x61 }, | ||
127 | { IAR_CHF_PMA_GAIN, 0x03 }, | ||
128 | { IAR_CCA1_THRESH, 0x50 }, | ||
129 | { IAR_CORR_NVAL, 0x13 }, | ||
130 | { IAR_ACKDELAY, 0x3D }, | ||
131 | }; | ||
132 | |||
133 | #define MCR20A_VALID_CHANNELS (0x07FFF800) | ||
134 | |||
135 | struct mcr20a_platform_data { | ||
136 | int rst_gpio; | ||
137 | }; | ||
138 | |||
139 | #define MCR20A_MAX_BUF (127) | ||
140 | |||
141 | #define printdev(X) (&X->spi->dev) | ||
142 | |||
143 | /* regmap information for Direct Access Register (DAR) access */ | ||
144 | #define MCR20A_DAR_WRITE 0x01 | ||
145 | #define MCR20A_DAR_READ 0x00 | ||
146 | #define MCR20A_DAR_NUMREGS 0x3F | ||
147 | |||
148 | /* regmap information for Indirect Access Register (IAR) access */ | ||
149 | #define MCR20A_IAR_ACCESS 0x80 | ||
150 | #define MCR20A_IAR_NUMREGS 0xBEFF | ||
151 | |||
152 | /* Read/Write SPI Commands for DAR and IAR registers. */ | ||
153 | #define MCR20A_READSHORT(reg) ((reg) << 1) | ||
154 | #define MCR20A_WRITESHORT(reg) ((reg) << 1 | 1) | ||
155 | #define MCR20A_READLONG(reg) (1 << 15 | (reg) << 5) | ||
156 | #define MCR20A_WRITELONG(reg) (1 << 15 | (reg) << 5 | 1 << 4) | ||
157 | |||
158 | /* Type definitions for link configuration of instantiable layers */ | ||
159 | #define MCR20A_PHY_INDIRECT_QUEUE_SIZE (12) | ||
160 | |||
161 | static bool | ||
162 | mcr20a_dar_writeable(struct device *dev, unsigned int reg) | ||
163 | { | ||
164 | switch (reg) { | ||
165 | case DAR_IRQ_STS1: | ||
166 | case DAR_IRQ_STS2: | ||
167 | case DAR_IRQ_STS3: | ||
168 | case DAR_PHY_CTRL1: | ||
169 | case DAR_PHY_CTRL2: | ||
170 | case DAR_PHY_CTRL3: | ||
171 | case DAR_PHY_CTRL4: | ||
172 | case DAR_SRC_CTRL: | ||
173 | case DAR_SRC_ADDRS_SUM_LSB: | ||
174 | case DAR_SRC_ADDRS_SUM_MSB: | ||
175 | case DAR_T3CMP_LSB: | ||
176 | case DAR_T3CMP_MSB: | ||
177 | case DAR_T3CMP_USB: | ||
178 | case DAR_T2PRIMECMP_LSB: | ||
179 | case DAR_T2PRIMECMP_MSB: | ||
180 | case DAR_T1CMP_LSB: | ||
181 | case DAR_T1CMP_MSB: | ||
182 | case DAR_T1CMP_USB: | ||
183 | case DAR_T2CMP_LSB: | ||
184 | case DAR_T2CMP_MSB: | ||
185 | case DAR_T2CMP_USB: | ||
186 | case DAR_T4CMP_LSB: | ||
187 | case DAR_T4CMP_MSB: | ||
188 | case DAR_T4CMP_USB: | ||
189 | case DAR_PLL_INT0: | ||
190 | case DAR_PLL_FRAC0_LSB: | ||
191 | case DAR_PLL_FRAC0_MSB: | ||
192 | case DAR_PA_PWR: | ||
193 | /* no DAR_ACM */ | ||
194 | case DAR_OVERWRITE_VER: | ||
195 | case DAR_CLK_OUT_CTRL: | ||
196 | case DAR_PWR_MODES: | ||
197 | return true; | ||
198 | default: | ||
199 | return false; | ||
200 | } | ||
201 | } | ||
202 | |||
203 | static bool | ||
204 | mcr20a_dar_readable(struct device *dev, unsigned int reg) | ||
205 | { | ||
206 | bool rc; | ||
207 | |||
208 | /* all writeable are also readable */ | ||
209 | rc = mcr20a_dar_writeable(dev, reg); | ||
210 | if (rc) | ||
211 | return rc; | ||
212 | |||
213 | /* readonly regs */ | ||
214 | switch (reg) { | ||
215 | case DAR_RX_FRM_LEN: | ||
216 | case DAR_CCA1_ED_FNL: | ||
217 | case DAR_EVENT_TMR_LSB: | ||
218 | case DAR_EVENT_TMR_MSB: | ||
219 | case DAR_EVENT_TMR_USB: | ||
220 | case DAR_TIMESTAMP_LSB: | ||
221 | case DAR_TIMESTAMP_MSB: | ||
222 | case DAR_TIMESTAMP_USB: | ||
223 | case DAR_SEQ_STATE: | ||
224 | case DAR_LQI_VALUE: | ||
225 | case DAR_RSSI_CCA_CONT: | ||
226 | return true; | ||
227 | default: | ||
228 | return false; | ||
229 | } | ||
230 | } | ||
231 | |||
232 | static bool | ||
233 | mcr20a_dar_volatile(struct device *dev, unsigned int reg) | ||
234 | { | ||
235 | /* can be changed during runtime */ | ||
236 | switch (reg) { | ||
237 | case DAR_IRQ_STS1: | ||
238 | case DAR_IRQ_STS2: | ||
239 | case DAR_IRQ_STS3: | ||
240 | /* use them in spi_async and regmap so it's volatile */ | ||
241 | return true; | ||
242 | default: | ||
243 | return false; | ||
244 | } | ||
245 | } | ||
246 | |||
247 | static bool | ||
248 | mcr20a_dar_precious(struct device *dev, unsigned int reg) | ||
249 | { | ||
250 | /* don't clear irq line on read */ | ||
251 | switch (reg) { | ||
252 | case DAR_IRQ_STS1: | ||
253 | case DAR_IRQ_STS2: | ||
254 | case DAR_IRQ_STS3: | ||
255 | return true; | ||
256 | default: | ||
257 | return false; | ||
258 | } | ||
259 | } | ||
260 | |||
261 | static const struct regmap_config mcr20a_dar_regmap = { | ||
262 | .name = "mcr20a_dar", | ||
263 | .reg_bits = 8, | ||
264 | .val_bits = 8, | ||
265 | .write_flag_mask = REGISTER_ACCESS | REGISTER_WRITE, | ||
266 | .read_flag_mask = REGISTER_ACCESS | REGISTER_READ, | ||
267 | .cache_type = REGCACHE_RBTREE, | ||
268 | .writeable_reg = mcr20a_dar_writeable, | ||
269 | .readable_reg = mcr20a_dar_readable, | ||
270 | .volatile_reg = mcr20a_dar_volatile, | ||
271 | .precious_reg = mcr20a_dar_precious, | ||
272 | .fast_io = true, | ||
273 | .can_multi_write = true, | ||
274 | }; | ||
275 | |||
276 | static bool | ||
277 | mcr20a_iar_writeable(struct device *dev, unsigned int reg) | ||
278 | { | ||
279 | switch (reg) { | ||
280 | case IAR_XTAL_TRIM: | ||
281 | case IAR_PMC_LP_TRIM: | ||
282 | case IAR_MACPANID0_LSB: | ||
283 | case IAR_MACPANID0_MSB: | ||
284 | case IAR_MACSHORTADDRS0_LSB: | ||
285 | case IAR_MACSHORTADDRS0_MSB: | ||
286 | case IAR_MACLONGADDRS0_0: | ||
287 | case IAR_MACLONGADDRS0_8: | ||
288 | case IAR_MACLONGADDRS0_16: | ||
289 | case IAR_MACLONGADDRS0_24: | ||
290 | case IAR_MACLONGADDRS0_32: | ||
291 | case IAR_MACLONGADDRS0_40: | ||
292 | case IAR_MACLONGADDRS0_48: | ||
293 | case IAR_MACLONGADDRS0_56: | ||
294 | case IAR_RX_FRAME_FILTER: | ||
295 | case IAR_PLL_INT1: | ||
296 | case IAR_PLL_FRAC1_LSB: | ||
297 | case IAR_PLL_FRAC1_MSB: | ||
298 | case IAR_MACPANID1_LSB: | ||
299 | case IAR_MACPANID1_MSB: | ||
300 | case IAR_MACSHORTADDRS1_LSB: | ||
301 | case IAR_MACSHORTADDRS1_MSB: | ||
302 | case IAR_MACLONGADDRS1_0: | ||
303 | case IAR_MACLONGADDRS1_8: | ||
304 | case IAR_MACLONGADDRS1_16: | ||
305 | case IAR_MACLONGADDRS1_24: | ||
306 | case IAR_MACLONGADDRS1_32: | ||
307 | case IAR_MACLONGADDRS1_40: | ||
308 | case IAR_MACLONGADDRS1_48: | ||
309 | case IAR_MACLONGADDRS1_56: | ||
310 | case IAR_DUAL_PAN_CTRL: | ||
311 | case IAR_DUAL_PAN_DWELL: | ||
312 | case IAR_CCA1_THRESH: | ||
313 | case IAR_CCA1_ED_OFFSET_COMP: | ||
314 | case IAR_LQI_OFFSET_COMP: | ||
315 | case IAR_CCA_CTRL: | ||
316 | case IAR_CCA2_CORR_PEAKS: | ||
317 | case IAR_CCA2_CORR_THRESH: | ||
318 | case IAR_TMR_PRESCALE: | ||
319 | case IAR_ANT_PAD_CTRL: | ||
320 | case IAR_MISC_PAD_CTRL: | ||
321 | case IAR_BSM_CTRL: | ||
322 | case IAR_RNG: | ||
323 | case IAR_RX_WTR_MARK: | ||
324 | case IAR_SOFT_RESET: | ||
325 | case IAR_TXDELAY: | ||
326 | case IAR_ACKDELAY: | ||
327 | case IAR_CORR_NVAL: | ||
328 | case IAR_ANT_AGC_CTRL: | ||
329 | case IAR_AGC_THR1: | ||
330 | case IAR_AGC_THR2: | ||
331 | case IAR_PA_CAL: | ||
332 | case IAR_ATT_RSSI1: | ||
333 | case IAR_ATT_RSSI2: | ||
334 | case IAR_RSSI_OFFSET: | ||
335 | case IAR_XTAL_CTRL: | ||
336 | case IAR_CHF_PMA_GAIN: | ||
337 | case IAR_CHF_IBUF: | ||
338 | case IAR_CHF_QBUF: | ||
339 | case IAR_CHF_IRIN: | ||
340 | case IAR_CHF_QRIN: | ||
341 | case IAR_CHF_IL: | ||
342 | case IAR_CHF_QL: | ||
343 | case IAR_CHF_CC1: | ||
344 | case IAR_CHF_CCL: | ||
345 | case IAR_CHF_CC2: | ||
346 | case IAR_CHF_IROUT: | ||
347 | case IAR_CHF_QROUT: | ||
348 | case IAR_PA_TUNING: | ||
349 | case IAR_VCO_CTRL1: | ||
350 | case IAR_VCO_CTRL2: | ||
351 | return true; | ||
352 | default: | ||
353 | return false; | ||
354 | } | ||
355 | } | ||
356 | |||
357 | static bool | ||
358 | mcr20a_iar_readable(struct device *dev, unsigned int reg) | ||
359 | { | ||
360 | bool rc; | ||
361 | |||
362 | /* all writeable are also readable */ | ||
363 | rc = mcr20a_iar_writeable(dev, reg); | ||
364 | if (rc) | ||
365 | return rc; | ||
366 | |||
367 | /* readonly regs */ | ||
368 | switch (reg) { | ||
369 | case IAR_PART_ID: | ||
370 | case IAR_DUAL_PAN_STS: | ||
371 | case IAR_RX_BYTE_COUNT: | ||
372 | case IAR_FILTERFAIL_CODE1: | ||
373 | case IAR_FILTERFAIL_CODE2: | ||
374 | case IAR_RSSI: | ||
375 | return true; | ||
376 | default: | ||
377 | return false; | ||
378 | } | ||
379 | } | ||
380 | |||
381 | static bool | ||
382 | mcr20a_iar_volatile(struct device *dev, unsigned int reg) | ||
383 | { | ||
384 | /* can be changed during runtime */ | ||
385 | switch (reg) { | ||
386 | case IAR_DUAL_PAN_STS: | ||
387 | case IAR_RX_BYTE_COUNT: | ||
388 | case IAR_FILTERFAIL_CODE1: | ||
389 | case IAR_FILTERFAIL_CODE2: | ||
390 | case IAR_RSSI: | ||
391 | return true; | ||
392 | default: | ||
393 | return false; | ||
394 | } | ||
395 | } | ||
396 | |||
397 | static const struct regmap_config mcr20a_iar_regmap = { | ||
398 | .name = "mcr20a_iar", | ||
399 | .reg_bits = 16, | ||
400 | .val_bits = 8, | ||
401 | .write_flag_mask = REGISTER_ACCESS | REGISTER_WRITE | IAR_INDEX, | ||
402 | .read_flag_mask = REGISTER_ACCESS | REGISTER_READ | IAR_INDEX, | ||
403 | .cache_type = REGCACHE_RBTREE, | ||
404 | .writeable_reg = mcr20a_iar_writeable, | ||
405 | .readable_reg = mcr20a_iar_readable, | ||
406 | .volatile_reg = mcr20a_iar_volatile, | ||
407 | .fast_io = true, | ||
408 | }; | ||
409 | |||
410 | struct mcr20a_local { | ||
411 | struct spi_device *spi; | ||
412 | |||
413 | struct ieee802154_hw *hw; | ||
414 | struct mcr20a_platform_data *pdata; | ||
415 | struct regmap *regmap_dar; | ||
416 | struct regmap *regmap_iar; | ||
417 | |||
418 | u8 *buf; | ||
419 | |||
420 | bool is_tx; | ||
421 | |||
422 | /* for writing tx buffer */ | ||
423 | struct spi_message tx_buf_msg; | ||
424 | u8 tx_header[1]; | ||
425 | /* burst buffer write command */ | ||
426 | struct spi_transfer tx_xfer_header; | ||
427 | u8 tx_len[1]; | ||
428 | /* len of tx packet */ | ||
429 | struct spi_transfer tx_xfer_len; | ||
430 | /* data of tx packet */ | ||
431 | struct spi_transfer tx_xfer_buf; | ||
432 | struct sk_buff *tx_skb; | ||
433 | |||
434 | /* for read length rxfifo */ | ||
435 | struct spi_message reg_msg; | ||
436 | u8 reg_cmd[1]; | ||
437 | u8 reg_data[MCR20A_IRQSTS_NUM]; | ||
438 | struct spi_transfer reg_xfer_cmd; | ||
439 | struct spi_transfer reg_xfer_data; | ||
440 | |||
441 | /* receive handling */ | ||
442 | struct spi_message rx_buf_msg; | ||
443 | u8 rx_header[1]; | ||
444 | struct spi_transfer rx_xfer_header; | ||
445 | u8 rx_lqi[1]; | ||
446 | struct spi_transfer rx_xfer_lqi; | ||
447 | u8 rx_buf[MCR20A_MAX_BUF]; | ||
448 | struct spi_transfer rx_xfer_buf; | ||
449 | |||
450 | /* isr handling for reading intstat */ | ||
451 | struct spi_message irq_msg; | ||
452 | u8 irq_header[1]; | ||
453 | u8 irq_data[MCR20A_IRQSTS_NUM]; | ||
454 | struct spi_transfer irq_xfer_data; | ||
455 | struct spi_transfer irq_xfer_header; | ||
456 | }; | ||
457 | |||
458 | static void | ||
459 | mcr20a_write_tx_buf_complete(void *context) | ||
460 | { | ||
461 | struct mcr20a_local *lp = context; | ||
462 | int ret; | ||
463 | |||
464 | dev_dbg(printdev(lp), "%s\n", __func__); | ||
465 | |||
466 | lp->reg_msg.complete = NULL; | ||
467 | lp->reg_cmd[0] = MCR20A_WRITE_REG(DAR_PHY_CTRL1); | ||
468 | lp->reg_data[0] = MCR20A_XCVSEQ_TX; | ||
469 | lp->reg_xfer_data.len = 1; | ||
470 | |||
471 | ret = spi_async(lp->spi, &lp->reg_msg); | ||
472 | if (ret) | ||
473 | dev_err(printdev(lp), "failed to set SEQ TX\n"); | ||
474 | } | ||
475 | |||
476 | static int | ||
477 | mcr20a_xmit(struct ieee802154_hw *hw, struct sk_buff *skb) | ||
478 | { | ||
479 | struct mcr20a_local *lp = hw->priv; | ||
480 | |||
481 | dev_dbg(printdev(lp), "%s\n", __func__); | ||
482 | |||
483 | lp->tx_skb = skb; | ||
484 | |||
485 | print_hex_dump_debug("mcr20a tx: ", DUMP_PREFIX_OFFSET, 16, 1, | ||
486 | skb->data, skb->len, 0); | ||
487 | |||
488 | lp->is_tx = 1; | ||
489 | |||
490 | lp->reg_msg.complete = NULL; | ||
491 | lp->reg_cmd[0] = MCR20A_WRITE_REG(DAR_PHY_CTRL1); | ||
492 | lp->reg_data[0] = MCR20A_XCVSEQ_IDLE; | ||
493 | lp->reg_xfer_data.len = 1; | ||
494 | |||
495 | return spi_async(lp->spi, &lp->reg_msg); | ||
496 | } | ||
497 | |||
498 | static int | ||
499 | mcr20a_ed(struct ieee802154_hw *hw, u8 *level) | ||
500 | { | ||
501 | WARN_ON(!level); | ||
502 | *level = 0xbe; | ||
503 | return 0; | ||
504 | } | ||
505 | |||
506 | static int | ||
507 | mcr20a_set_channel(struct ieee802154_hw *hw, u8 page, u8 channel) | ||
508 | { | ||
509 | struct mcr20a_local *lp = hw->priv; | ||
510 | int ret; | ||
511 | |||
512 | dev_dbg(printdev(lp), "%s\n", __func__); | ||
513 | |||
514 | /* freqency = ((PLL_INT+64) + (PLL_FRAC/65536)) * 32 MHz */ | ||
515 | ret = regmap_write(lp->regmap_dar, DAR_PLL_INT0, PLL_INT[channel - 11]); | ||
516 | if (ret) | ||
517 | return ret; | ||
518 | ret = regmap_write(lp->regmap_dar, DAR_PLL_FRAC0_LSB, 0x00); | ||
519 | if (ret) | ||
520 | return ret; | ||
521 | ret = regmap_write(lp->regmap_dar, DAR_PLL_FRAC0_MSB, | ||
522 | PLL_FRAC[channel - 11]); | ||
523 | if (ret) | ||
524 | return ret; | ||
525 | |||
526 | return 0; | ||
527 | } | ||
528 | |||
529 | static int | ||
530 | mcr20a_start(struct ieee802154_hw *hw) | ||
531 | { | ||
532 | struct mcr20a_local *lp = hw->priv; | ||
533 | int ret; | ||
534 | |||
535 | dev_dbg(printdev(lp), "%s\n", __func__); | ||
536 | |||
537 | /* No slotted operation */ | ||
538 | dev_dbg(printdev(lp), "no slotted operation\n"); | ||
539 | ret = regmap_update_bits(lp->regmap_dar, DAR_PHY_CTRL1, | ||
540 | DAR_PHY_CTRL1_SLOTTED, 0x0); | ||
541 | |||
542 | /* enable irq */ | ||
543 | enable_irq(lp->spi->irq); | ||
544 | |||
545 | /* Unmask SEQ interrupt */ | ||
546 | ret = regmap_update_bits(lp->regmap_dar, DAR_PHY_CTRL2, | ||
547 | DAR_PHY_CTRL2_SEQMSK, 0x0); | ||
548 | |||
549 | /* Start the RX sequence */ | ||
550 | dev_dbg(printdev(lp), "start the RX sequence\n"); | ||
551 | ret = regmap_update_bits(lp->regmap_dar, DAR_PHY_CTRL1, | ||
552 | DAR_PHY_CTRL1_XCVSEQ_MASK, MCR20A_XCVSEQ_RX); | ||
553 | |||
554 | return 0; | ||
555 | } | ||
556 | |||
557 | static void | ||
558 | mcr20a_stop(struct ieee802154_hw *hw) | ||
559 | { | ||
560 | struct mcr20a_local *lp = hw->priv; | ||
561 | |||
562 | dev_dbg(printdev(lp), "%s\n", __func__); | ||
563 | |||
564 | /* stop all running sequence */ | ||
565 | regmap_update_bits(lp->regmap_dar, DAR_PHY_CTRL1, | ||
566 | DAR_PHY_CTRL1_XCVSEQ_MASK, MCR20A_XCVSEQ_IDLE); | ||
567 | |||
568 | /* disable irq */ | ||
569 | disable_irq(lp->spi->irq); | ||
570 | } | ||
571 | |||
572 | static int | ||
573 | mcr20a_set_hw_addr_filt(struct ieee802154_hw *hw, | ||
574 | struct ieee802154_hw_addr_filt *filt, | ||
575 | unsigned long changed) | ||
576 | { | ||
577 | struct mcr20a_local *lp = hw->priv; | ||
578 | |||
579 | dev_dbg(printdev(lp), "%s\n", __func__); | ||
580 | |||
581 | if (changed & IEEE802154_AFILT_SADDR_CHANGED) { | ||
582 | u16 addr = le16_to_cpu(filt->short_addr); | ||
583 | |||
584 | regmap_write(lp->regmap_iar, IAR_MACSHORTADDRS0_LSB, addr); | ||
585 | regmap_write(lp->regmap_iar, IAR_MACSHORTADDRS0_MSB, addr >> 8); | ||
586 | } | ||
587 | |||
588 | if (changed & IEEE802154_AFILT_PANID_CHANGED) { | ||
589 | u16 pan = le16_to_cpu(filt->pan_id); | ||
590 | |||
591 | regmap_write(lp->regmap_iar, IAR_MACPANID0_LSB, pan); | ||
592 | regmap_write(lp->regmap_iar, IAR_MACPANID0_MSB, pan >> 8); | ||
593 | } | ||
594 | |||
595 | if (changed & IEEE802154_AFILT_IEEEADDR_CHANGED) { | ||
596 | u8 addr[8], i; | ||
597 | |||
598 | memcpy(addr, &filt->ieee_addr, 8); | ||
599 | for (i = 0; i < 8; i++) | ||
600 | regmap_write(lp->regmap_iar, | ||
601 | IAR_MACLONGADDRS0_0 + i, addr[i]); | ||
602 | } | ||
603 | |||
604 | if (changed & IEEE802154_AFILT_PANC_CHANGED) { | ||
605 | if (filt->pan_coord) { | ||
606 | regmap_update_bits(lp->regmap_dar, DAR_PHY_CTRL4, | ||
607 | DAR_PHY_CTRL4_PANCORDNTR0, 0x10); | ||
608 | } else { | ||
609 | regmap_update_bits(lp->regmap_dar, DAR_PHY_CTRL4, | ||
610 | DAR_PHY_CTRL4_PANCORDNTR0, 0x00); | ||
611 | } | ||
612 | } | ||
613 | |||
614 | return 0; | ||
615 | } | ||
616 | |||
617 | /* -30 dBm to 10 dBm */ | ||
618 | #define MCR20A_MAX_TX_POWERS 0x14 | ||
619 | static const s32 mcr20a_powers[MCR20A_MAX_TX_POWERS + 1] = { | ||
620 | -3000, -2800, -2600, -2400, -2200, -2000, -1800, -1600, -1400, | ||
621 | -1200, -1000, -800, -600, -400, -200, 0, 200, 400, 600, 800, 1000 | ||
622 | }; | ||
623 | |||
624 | static int | ||
625 | mcr20a_set_txpower(struct ieee802154_hw *hw, s32 mbm) | ||
626 | { | ||
627 | struct mcr20a_local *lp = hw->priv; | ||
628 | u32 i; | ||
629 | |||
630 | dev_dbg(printdev(lp), "%s(%d)\n", __func__, mbm); | ||
631 | |||
632 | for (i = 0; i < lp->hw->phy->supported.tx_powers_size; i++) { | ||
633 | if (lp->hw->phy->supported.tx_powers[i] == mbm) | ||
634 | return regmap_write(lp->regmap_dar, DAR_PA_PWR, | ||
635 | ((i + 8) & 0x1F)); | ||
636 | } | ||
637 | |||
638 | return -EINVAL; | ||
639 | } | ||
640 | |||
641 | #define MCR20A_MAX_ED_LEVELS MCR20A_MIN_CCA_THRESHOLD | ||
642 | static s32 mcr20a_ed_levels[MCR20A_MAX_ED_LEVELS + 1]; | ||
643 | |||
644 | static int | ||
645 | mcr20a_set_cca_mode(struct ieee802154_hw *hw, | ||
646 | const struct wpan_phy_cca *cca) | ||
647 | { | ||
648 | struct mcr20a_local *lp = hw->priv; | ||
649 | unsigned int cca_mode = 0xff; | ||
650 | bool cca_mode_and = false; | ||
651 | int ret; | ||
652 | |||
653 | dev_dbg(printdev(lp), "%s\n", __func__); | ||
654 | |||
655 | /* mapping 802.15.4 to driver spec */ | ||
656 | switch (cca->mode) { | ||
657 | case NL802154_CCA_ENERGY: | ||
658 | cca_mode = MCR20A_CCA_MODE1; | ||
659 | break; | ||
660 | case NL802154_CCA_CARRIER: | ||
661 | cca_mode = MCR20A_CCA_MODE2; | ||
662 | break; | ||
663 | case NL802154_CCA_ENERGY_CARRIER: | ||
664 | switch (cca->opt) { | ||
665 | case NL802154_CCA_OPT_ENERGY_CARRIER_AND: | ||
666 | cca_mode = MCR20A_CCA_MODE3; | ||
667 | cca_mode_and = true; | ||
668 | break; | ||
669 | case NL802154_CCA_OPT_ENERGY_CARRIER_OR: | ||
670 | cca_mode = MCR20A_CCA_MODE3; | ||
671 | cca_mode_and = false; | ||
672 | break; | ||
673 | default: | ||
674 | return -EINVAL; | ||
675 | } | ||
676 | break; | ||
677 | default: | ||
678 | return -EINVAL; | ||
679 | } | ||
680 | ret = regmap_update_bits(lp->regmap_dar, DAR_PHY_CTRL4, | ||
681 | DAR_PHY_CTRL4_CCATYPE_MASK, | ||
682 | cca_mode << DAR_PHY_CTRL4_CCATYPE_SHIFT); | ||
683 | if (ret < 0) | ||
684 | return ret; | ||
685 | |||
686 | if (cca_mode == MCR20A_CCA_MODE3) { | ||
687 | if (cca_mode_and) { | ||
688 | ret = regmap_update_bits(lp->regmap_iar, IAR_CCA_CTRL, | ||
689 | IAR_CCA_CTRL_CCA3_AND_NOT_OR, | ||
690 | 0x08); | ||
691 | } else { | ||
692 | ret = regmap_update_bits(lp->regmap_iar, | ||
693 | IAR_CCA_CTRL, | ||
694 | IAR_CCA_CTRL_CCA3_AND_NOT_OR, | ||
695 | 0x00); | ||
696 | } | ||
697 | if (ret < 0) | ||
698 | return ret; | ||
699 | } | ||
700 | |||
701 | return ret; | ||
702 | } | ||
703 | |||
704 | static int | ||
705 | mcr20a_set_cca_ed_level(struct ieee802154_hw *hw, s32 mbm) | ||
706 | { | ||
707 | struct mcr20a_local *lp = hw->priv; | ||
708 | u32 i; | ||
709 | |||
710 | dev_dbg(printdev(lp), "%s\n", __func__); | ||
711 | |||
712 | for (i = 0; i < hw->phy->supported.cca_ed_levels_size; i++) { | ||
713 | if (hw->phy->supported.cca_ed_levels[i] == mbm) | ||
714 | return regmap_write(lp->regmap_iar, IAR_CCA1_THRESH, i); | ||
715 | } | ||
716 | |||
717 | return 0; | ||
718 | } | ||
719 | |||
720 | static int | ||
721 | mcr20a_set_promiscuous_mode(struct ieee802154_hw *hw, const bool on) | ||
722 | { | ||
723 | struct mcr20a_local *lp = hw->priv; | ||
724 | int ret; | ||
725 | u8 rx_frame_filter_reg = 0x0; | ||
726 | u8 val; | ||
727 | |||
728 | dev_dbg(printdev(lp), "%s(%d)\n", __func__, on); | ||
729 | |||
730 | if (on) { | ||
731 | /* All frame types accepted*/ | ||
732 | val |= DAR_PHY_CTRL4_PROMISCUOUS; | ||
733 | rx_frame_filter_reg &= ~(IAR_RX_FRAME_FLT_FRM_VER); | ||
734 | rx_frame_filter_reg |= (IAR_RX_FRAME_FLT_ACK_FT | | ||
735 | IAR_RX_FRAME_FLT_NS_FT); | ||
736 | |||
737 | ret = regmap_update_bits(lp->regmap_dar, DAR_PHY_CTRL4, | ||
738 | DAR_PHY_CTRL4_PROMISCUOUS, | ||
739 | DAR_PHY_CTRL4_PROMISCUOUS); | ||
740 | if (ret < 0) | ||
741 | return ret; | ||
742 | |||
743 | ret = regmap_write(lp->regmap_iar, IAR_RX_FRAME_FILTER, | ||
744 | rx_frame_filter_reg); | ||
745 | if (ret < 0) | ||
746 | return ret; | ||
747 | } else { | ||
748 | ret = regmap_update_bits(lp->regmap_dar, DAR_PHY_CTRL4, | ||
749 | DAR_PHY_CTRL4_PROMISCUOUS, 0x0); | ||
750 | if (ret < 0) | ||
751 | return ret; | ||
752 | |||
753 | ret = regmap_write(lp->regmap_iar, IAR_RX_FRAME_FILTER, | ||
754 | IAR_RX_FRAME_FLT_FRM_VER | | ||
755 | IAR_RX_FRAME_FLT_BEACON_FT | | ||
756 | IAR_RX_FRAME_FLT_DATA_FT | | ||
757 | IAR_RX_FRAME_FLT_CMD_FT); | ||
758 | if (ret < 0) | ||
759 | return ret; | ||
760 | } | ||
761 | |||
762 | return 0; | ||
763 | } | ||
764 | |||
765 | static const struct ieee802154_ops mcr20a_hw_ops = { | ||
766 | .owner = THIS_MODULE, | ||
767 | .xmit_async = mcr20a_xmit, | ||
768 | .ed = mcr20a_ed, | ||
769 | .set_channel = mcr20a_set_channel, | ||
770 | .start = mcr20a_start, | ||
771 | .stop = mcr20a_stop, | ||
772 | .set_hw_addr_filt = mcr20a_set_hw_addr_filt, | ||
773 | .set_txpower = mcr20a_set_txpower, | ||
774 | .set_cca_mode = mcr20a_set_cca_mode, | ||
775 | .set_cca_ed_level = mcr20a_set_cca_ed_level, | ||
776 | .set_promiscuous_mode = mcr20a_set_promiscuous_mode, | ||
777 | }; | ||
778 | |||
779 | static int | ||
780 | mcr20a_request_rx(struct mcr20a_local *lp) | ||
781 | { | ||
782 | dev_dbg(printdev(lp), "%s\n", __func__); | ||
783 | |||
784 | /* Start the RX sequence */ | ||
785 | regmap_update_bits_async(lp->regmap_dar, DAR_PHY_CTRL1, | ||
786 | DAR_PHY_CTRL1_XCVSEQ_MASK, MCR20A_XCVSEQ_RX); | ||
787 | |||
788 | return 0; | ||
789 | } | ||
790 | |||
791 | static void | ||
792 | mcr20a_handle_rx_read_buf_complete(void *context) | ||
793 | { | ||
794 | struct mcr20a_local *lp = context; | ||
795 | u8 len = lp->reg_data[0] & DAR_RX_FRAME_LENGTH_MASK; | ||
796 | struct sk_buff *skb; | ||
797 | |||
798 | dev_dbg(printdev(lp), "%s\n", __func__); | ||
799 | |||
800 | dev_dbg(printdev(lp), "RX is done\n"); | ||
801 | |||
802 | if (!ieee802154_is_valid_psdu_len(len)) { | ||
803 | dev_vdbg(&lp->spi->dev, "corrupted frame received\n"); | ||
804 | len = IEEE802154_MTU; | ||
805 | } | ||
806 | |||
807 | len = len - 2; /* get rid of frame check field */ | ||
808 | |||
809 | skb = dev_alloc_skb(len); | ||
810 | if (!skb) | ||
811 | return; | ||
812 | |||
813 | memcpy(skb_put(skb, len), lp->rx_buf, len); | ||
814 | ieee802154_rx_irqsafe(lp->hw, skb, lp->rx_lqi[0]); | ||
815 | |||
816 | print_hex_dump_debug("mcr20a rx: ", DUMP_PREFIX_OFFSET, 16, 1, | ||
817 | lp->rx_buf, len, 0); | ||
818 | pr_debug("mcr20a rx: lqi: %02hhx\n", lp->rx_lqi[0]); | ||
819 | |||
820 | /* start RX sequence */ | ||
821 | mcr20a_request_rx(lp); | ||
822 | } | ||
823 | |||
824 | static void | ||
825 | mcr20a_handle_rx_read_len_complete(void *context) | ||
826 | { | ||
827 | struct mcr20a_local *lp = context; | ||
828 | u8 len; | ||
829 | int ret; | ||
830 | |||
831 | dev_dbg(printdev(lp), "%s\n", __func__); | ||
832 | |||
833 | /* get the length of received frame */ | ||
834 | len = lp->reg_data[0] & DAR_RX_FRAME_LENGTH_MASK; | ||
835 | dev_dbg(printdev(lp), "frame len : %d\n", len); | ||
836 | |||
837 | /* prepare to read the rx buf */ | ||
838 | lp->rx_buf_msg.complete = mcr20a_handle_rx_read_buf_complete; | ||
839 | lp->rx_header[0] = MCR20A_BURST_READ_PACKET_BUF; | ||
840 | lp->rx_xfer_buf.len = len; | ||
841 | |||
842 | ret = spi_async(lp->spi, &lp->rx_buf_msg); | ||
843 | if (ret) | ||
844 | dev_err(printdev(lp), "failed to read rx buffer length\n"); | ||
845 | } | ||
846 | |||
847 | static int | ||
848 | mcr20a_handle_rx(struct mcr20a_local *lp) | ||
849 | { | ||
850 | dev_dbg(printdev(lp), "%s\n", __func__); | ||
851 | lp->reg_msg.complete = mcr20a_handle_rx_read_len_complete; | ||
852 | lp->reg_cmd[0] = MCR20A_READ_REG(DAR_RX_FRM_LEN); | ||
853 | lp->reg_xfer_data.len = 1; | ||
854 | |||
855 | return spi_async(lp->spi, &lp->reg_msg); | ||
856 | } | ||
857 | |||
858 | static int | ||
859 | mcr20a_handle_tx_complete(struct mcr20a_local *lp) | ||
860 | { | ||
861 | dev_dbg(printdev(lp), "%s\n", __func__); | ||
862 | |||
863 | ieee802154_xmit_complete(lp->hw, lp->tx_skb, false); | ||
864 | |||
865 | return mcr20a_request_rx(lp); | ||
866 | } | ||
867 | |||
868 | static int | ||
869 | mcr20a_handle_tx(struct mcr20a_local *lp) | ||
870 | { | ||
871 | int ret; | ||
872 | |||
873 | dev_dbg(printdev(lp), "%s\n", __func__); | ||
874 | |||
875 | /* write tx buffer */ | ||
876 | lp->tx_header[0] = MCR20A_BURST_WRITE_PACKET_BUF; | ||
877 | /* add 2 bytes of FCS */ | ||
878 | lp->tx_len[0] = lp->tx_skb->len + 2; | ||
879 | lp->tx_xfer_buf.tx_buf = lp->tx_skb->data; | ||
880 | /* add 1 byte psduLength */ | ||
881 | lp->tx_xfer_buf.len = lp->tx_skb->len + 1; | ||
882 | |||
883 | ret = spi_async(lp->spi, &lp->tx_buf_msg); | ||
884 | if (ret) { | ||
885 | dev_err(printdev(lp), "SPI write Failed for TX buf\n"); | ||
886 | return ret; | ||
887 | } | ||
888 | |||
889 | return 0; | ||
890 | } | ||
891 | |||
892 | static void | ||
893 | mcr20a_irq_clean_complete(void *context) | ||
894 | { | ||
895 | struct mcr20a_local *lp = context; | ||
896 | u8 seq_state = lp->irq_data[DAR_IRQ_STS1] & DAR_PHY_CTRL1_XCVSEQ_MASK; | ||
897 | |||
898 | dev_dbg(printdev(lp), "%s\n", __func__); | ||
899 | |||
900 | enable_irq(lp->spi->irq); | ||
901 | |||
902 | dev_dbg(printdev(lp), "IRQ STA1 (%02x) STA2 (%02x)\n", | ||
903 | lp->irq_data[DAR_IRQ_STS1], lp->irq_data[DAR_IRQ_STS2]); | ||
904 | |||
905 | switch (seq_state) { | ||
906 | /* TX IRQ, RX IRQ and SEQ IRQ */ | ||
907 | case (0x03): | ||
908 | if (lp->is_tx) { | ||
909 | lp->is_tx = 0; | ||
910 | dev_dbg(printdev(lp), "TX is done. No ACK\n"); | ||
911 | mcr20a_handle_tx_complete(lp); | ||
912 | } | ||
913 | break; | ||
914 | case (0x05): | ||
915 | /* rx is starting */ | ||
916 | dev_dbg(printdev(lp), "RX is starting\n"); | ||
917 | mcr20a_handle_rx(lp); | ||
918 | break; | ||
919 | case (0x07): | ||
920 | if (lp->is_tx) { | ||
921 | /* tx is done */ | ||
922 | lp->is_tx = 0; | ||
923 | dev_dbg(printdev(lp), "TX is done. Get ACK\n"); | ||
924 | mcr20a_handle_tx_complete(lp); | ||
925 | } else { | ||
926 | /* rx is starting */ | ||
927 | dev_dbg(printdev(lp), "RX is starting\n"); | ||
928 | mcr20a_handle_rx(lp); | ||
929 | } | ||
930 | break; | ||
931 | case (0x01): | ||
932 | if (lp->is_tx) { | ||
933 | dev_dbg(printdev(lp), "TX is starting\n"); | ||
934 | mcr20a_handle_tx(lp); | ||
935 | } else { | ||
936 | dev_dbg(printdev(lp), "MCR20A is stop\n"); | ||
937 | } | ||
938 | break; | ||
939 | } | ||
940 | } | ||
941 | |||
942 | static void mcr20a_irq_status_complete(void *context) | ||
943 | { | ||
944 | int ret; | ||
945 | struct mcr20a_local *lp = context; | ||
946 | |||
947 | dev_dbg(printdev(lp), "%s\n", __func__); | ||
948 | regmap_update_bits_async(lp->regmap_dar, DAR_PHY_CTRL1, | ||
949 | DAR_PHY_CTRL1_XCVSEQ_MASK, MCR20A_XCVSEQ_IDLE); | ||
950 | |||
951 | lp->reg_msg.complete = mcr20a_irq_clean_complete; | ||
952 | lp->reg_cmd[0] = MCR20A_WRITE_REG(DAR_IRQ_STS1); | ||
953 | memcpy(lp->reg_data, lp->irq_data, MCR20A_IRQSTS_NUM); | ||
954 | lp->reg_xfer_data.len = MCR20A_IRQSTS_NUM; | ||
955 | |||
956 | ret = spi_async(lp->spi, &lp->reg_msg); | ||
957 | |||
958 | if (ret) | ||
959 | dev_err(printdev(lp), "failed to clean irq status\n"); | ||
960 | } | ||
961 | |||
962 | static irqreturn_t mcr20a_irq_isr(int irq, void *data) | ||
963 | { | ||
964 | struct mcr20a_local *lp = data; | ||
965 | int ret; | ||
966 | |||
967 | disable_irq_nosync(irq); | ||
968 | |||
969 | lp->irq_header[0] = MCR20A_READ_REG(DAR_IRQ_STS1); | ||
970 | /* read IRQSTSx */ | ||
971 | ret = spi_async(lp->spi, &lp->irq_msg); | ||
972 | if (ret) { | ||
973 | enable_irq(irq); | ||
974 | return IRQ_NONE; | ||
975 | } | ||
976 | |||
977 | return IRQ_HANDLED; | ||
978 | } | ||
979 | |||
980 | static int mcr20a_get_platform_data(struct spi_device *spi, | ||
981 | struct mcr20a_platform_data *pdata) | ||
982 | { | ||
983 | int ret = 0; | ||
984 | |||
985 | if (!spi->dev.of_node) | ||
986 | return -EINVAL; | ||
987 | |||
988 | pdata->rst_gpio = of_get_named_gpio(spi->dev.of_node, "rst_b-gpio", 0); | ||
989 | dev_dbg(&spi->dev, "rst_b-gpio: %d\n", pdata->rst_gpio); | ||
990 | |||
991 | return ret; | ||
992 | } | ||
993 | |||
994 | static void mcr20a_hw_setup(struct mcr20a_local *lp) | ||
995 | { | ||
996 | u8 i; | ||
997 | struct ieee802154_hw *hw = lp->hw; | ||
998 | struct wpan_phy *phy = lp->hw->phy; | ||
999 | |||
1000 | dev_dbg(printdev(lp), "%s\n", __func__); | ||
1001 | |||
1002 | phy->symbol_duration = 16; | ||
1003 | phy->lifs_period = 40; | ||
1004 | phy->sifs_period = 12; | ||
1005 | |||
1006 | hw->flags = IEEE802154_HW_TX_OMIT_CKSUM | | ||
1007 | IEEE802154_HW_AFILT | | ||
1008 | IEEE802154_HW_PROMISCUOUS; | ||
1009 | |||
1010 | phy->flags = WPAN_PHY_FLAG_TXPOWER | WPAN_PHY_FLAG_CCA_ED_LEVEL | | ||
1011 | WPAN_PHY_FLAG_CCA_MODE; | ||
1012 | |||
1013 | phy->supported.cca_modes = BIT(NL802154_CCA_ENERGY) | | ||
1014 | BIT(NL802154_CCA_CARRIER) | BIT(NL802154_CCA_ENERGY_CARRIER); | ||
1015 | phy->supported.cca_opts = BIT(NL802154_CCA_OPT_ENERGY_CARRIER_AND) | | ||
1016 | BIT(NL802154_CCA_OPT_ENERGY_CARRIER_OR); | ||
1017 | |||
1018 | /* initiating cca_ed_levels */ | ||
1019 | for (i = MCR20A_MAX_CCA_THRESHOLD; i < MCR20A_MIN_CCA_THRESHOLD + 1; | ||
1020 | ++i) { | ||
1021 | mcr20a_ed_levels[i] = -i * 100; | ||
1022 | } | ||
1023 | |||
1024 | phy->supported.cca_ed_levels = mcr20a_ed_levels; | ||
1025 | phy->supported.cca_ed_levels_size = ARRAY_SIZE(mcr20a_ed_levels); | ||
1026 | |||
1027 | phy->cca.mode = NL802154_CCA_ENERGY; | ||
1028 | |||
1029 | phy->supported.channels[0] = MCR20A_VALID_CHANNELS; | ||
1030 | phy->current_page = 0; | ||
1031 | /* MCR20A default reset value */ | ||
1032 | phy->current_channel = 20; | ||
1033 | phy->symbol_duration = 16; | ||
1034 | phy->supported.tx_powers = mcr20a_powers; | ||
1035 | phy->supported.tx_powers_size = ARRAY_SIZE(mcr20a_powers); | ||
1036 | phy->cca_ed_level = phy->supported.cca_ed_levels[75]; | ||
1037 | phy->transmit_power = phy->supported.tx_powers[0x0F]; | ||
1038 | } | ||
1039 | |||
1040 | static void | ||
1041 | mcr20a_setup_tx_spi_messages(struct mcr20a_local *lp) | ||
1042 | { | ||
1043 | spi_message_init(&lp->tx_buf_msg); | ||
1044 | lp->tx_buf_msg.context = lp; | ||
1045 | lp->tx_buf_msg.complete = mcr20a_write_tx_buf_complete; | ||
1046 | |||
1047 | lp->tx_xfer_header.len = 1; | ||
1048 | lp->tx_xfer_header.tx_buf = lp->tx_header; | ||
1049 | |||
1050 | lp->tx_xfer_len.len = 1; | ||
1051 | lp->tx_xfer_len.tx_buf = lp->tx_len; | ||
1052 | |||
1053 | spi_message_add_tail(&lp->tx_xfer_header, &lp->tx_buf_msg); | ||
1054 | spi_message_add_tail(&lp->tx_xfer_len, &lp->tx_buf_msg); | ||
1055 | spi_message_add_tail(&lp->tx_xfer_buf, &lp->tx_buf_msg); | ||
1056 | } | ||
1057 | |||
1058 | static void | ||
1059 | mcr20a_setup_rx_spi_messages(struct mcr20a_local *lp) | ||
1060 | { | ||
1061 | spi_message_init(&lp->reg_msg); | ||
1062 | lp->reg_msg.context = lp; | ||
1063 | |||
1064 | lp->reg_xfer_cmd.len = 1; | ||
1065 | lp->reg_xfer_cmd.tx_buf = lp->reg_cmd; | ||
1066 | lp->reg_xfer_cmd.rx_buf = lp->reg_cmd; | ||
1067 | |||
1068 | lp->reg_xfer_data.rx_buf = lp->reg_data; | ||
1069 | lp->reg_xfer_data.tx_buf = lp->reg_data; | ||
1070 | |||
1071 | spi_message_add_tail(&lp->reg_xfer_cmd, &lp->reg_msg); | ||
1072 | spi_message_add_tail(&lp->reg_xfer_data, &lp->reg_msg); | ||
1073 | |||
1074 | spi_message_init(&lp->rx_buf_msg); | ||
1075 | lp->rx_buf_msg.context = lp; | ||
1076 | lp->rx_buf_msg.complete = mcr20a_handle_rx_read_buf_complete; | ||
1077 | lp->rx_xfer_header.len = 1; | ||
1078 | lp->rx_xfer_header.tx_buf = lp->rx_header; | ||
1079 | lp->rx_xfer_header.rx_buf = lp->rx_header; | ||
1080 | |||
1081 | lp->rx_xfer_buf.rx_buf = lp->rx_buf; | ||
1082 | |||
1083 | lp->rx_xfer_lqi.len = 1; | ||
1084 | lp->rx_xfer_lqi.rx_buf = lp->rx_lqi; | ||
1085 | |||
1086 | spi_message_add_tail(&lp->rx_xfer_header, &lp->rx_buf_msg); | ||
1087 | spi_message_add_tail(&lp->rx_xfer_buf, &lp->rx_buf_msg); | ||
1088 | spi_message_add_tail(&lp->rx_xfer_lqi, &lp->rx_buf_msg); | ||
1089 | } | ||
1090 | |||
1091 | static void | ||
1092 | mcr20a_setup_irq_spi_messages(struct mcr20a_local *lp) | ||
1093 | { | ||
1094 | spi_message_init(&lp->irq_msg); | ||
1095 | lp->irq_msg.context = lp; | ||
1096 | lp->irq_msg.complete = mcr20a_irq_status_complete; | ||
1097 | lp->irq_xfer_header.len = 1; | ||
1098 | lp->irq_xfer_header.tx_buf = lp->irq_header; | ||
1099 | lp->irq_xfer_header.rx_buf = lp->irq_header; | ||
1100 | |||
1101 | lp->irq_xfer_data.len = MCR20A_IRQSTS_NUM; | ||
1102 | lp->irq_xfer_data.rx_buf = lp->irq_data; | ||
1103 | |||
1104 | spi_message_add_tail(&lp->irq_xfer_header, &lp->irq_msg); | ||
1105 | spi_message_add_tail(&lp->irq_xfer_data, &lp->irq_msg); | ||
1106 | } | ||
1107 | |||
1108 | static int | ||
1109 | mcr20a_phy_init(struct mcr20a_local *lp) | ||
1110 | { | ||
1111 | u8 index; | ||
1112 | unsigned int phy_reg = 0; | ||
1113 | int ret; | ||
1114 | |||
1115 | dev_dbg(printdev(lp), "%s\n", __func__); | ||
1116 | |||
1117 | /* Disable Tristate on COCO MISO for SPI reads */ | ||
1118 | ret = regmap_write(lp->regmap_iar, IAR_MISC_PAD_CTRL, 0x02); | ||
1119 | if (ret) | ||
1120 | goto err_ret; | ||
1121 | |||
1122 | /* Clear all PP IRQ bits in IRQSTS1 to avoid unexpected interrupts | ||
1123 | * immediately after init | ||
1124 | */ | ||
1125 | ret = regmap_write(lp->regmap_dar, DAR_IRQ_STS1, 0xEF); | ||
1126 | if (ret) | ||
1127 | goto err_ret; | ||
1128 | |||
1129 | /* Clear all PP IRQ bits in IRQSTS2 */ | ||
1130 | ret = regmap_write(lp->regmap_dar, DAR_IRQ_STS2, | ||
1131 | DAR_IRQSTS2_ASM_IRQ | DAR_IRQSTS2_PB_ERR_IRQ | | ||
1132 | DAR_IRQSTS2_WAKE_IRQ); | ||
1133 | if (ret) | ||
1134 | goto err_ret; | ||
1135 | |||
1136 | /* Disable all timer interrupts */ | ||
1137 | ret = regmap_write(lp->regmap_dar, DAR_IRQ_STS3, 0xFF); | ||
1138 | if (ret) | ||
1139 | goto err_ret; | ||
1140 | |||
1141 | /* PHY_CTRL1 : default HW settings + AUTOACK enabled */ | ||
1142 | ret = regmap_update_bits(lp->regmap_dar, DAR_PHY_CTRL1, | ||
1143 | DAR_PHY_CTRL1_AUTOACK, DAR_PHY_CTRL1_AUTOACK); | ||
1144 | |||
1145 | /* PHY_CTRL2 : disable all interrupts */ | ||
1146 | ret = regmap_write(lp->regmap_dar, DAR_PHY_CTRL2, 0xFF); | ||
1147 | if (ret) | ||
1148 | goto err_ret; | ||
1149 | |||
1150 | /* PHY_CTRL3 : disable all timers and remaining interrupts */ | ||
1151 | ret = regmap_write(lp->regmap_dar, DAR_PHY_CTRL3, | ||
1152 | DAR_PHY_CTRL3_ASM_MSK | DAR_PHY_CTRL3_PB_ERR_MSK | | ||
1153 | DAR_PHY_CTRL3_WAKE_MSK); | ||
1154 | if (ret) | ||
1155 | goto err_ret; | ||
1156 | |||
1157 | /* SRC_CTRL : enable Acknowledge Frame Pending and | ||
1158 | * Source Address Matching Enable | ||
1159 | */ | ||
1160 | ret = regmap_write(lp->regmap_dar, DAR_SRC_CTRL, | ||
1161 | DAR_SRC_CTRL_ACK_FRM_PND | | ||
1162 | (DAR_SRC_CTRL_INDEX << DAR_SRC_CTRL_INDEX_SHIFT)); | ||
1163 | if (ret) | ||
1164 | goto err_ret; | ||
1165 | |||
1166 | /* RX_FRAME_FILTER */ | ||
1167 | /* FRM_VER[1:0] = b11. Accept FrameVersion 0 and 1 packets */ | ||
1168 | ret = regmap_write(lp->regmap_iar, IAR_RX_FRAME_FILTER, | ||
1169 | IAR_RX_FRAME_FLT_FRM_VER | | ||
1170 | IAR_RX_FRAME_FLT_BEACON_FT | | ||
1171 | IAR_RX_FRAME_FLT_DATA_FT | | ||
1172 | IAR_RX_FRAME_FLT_CMD_FT); | ||
1173 | if (ret) | ||
1174 | goto err_ret; | ||
1175 | |||
1176 | dev_info(printdev(lp), "MCR20A DAR overwrites version: 0x%02x\n", | ||
1177 | MCR20A_OVERWRITE_VERSION); | ||
1178 | |||
1179 | /* Overwrites direct registers */ | ||
1180 | ret = regmap_write(lp->regmap_dar, DAR_OVERWRITE_VER, | ||
1181 | MCR20A_OVERWRITE_VERSION); | ||
1182 | if (ret) | ||
1183 | goto err_ret; | ||
1184 | |||
1185 | /* Overwrites indirect registers */ | ||
1186 | ret = regmap_multi_reg_write(lp->regmap_iar, mar20a_iar_overwrites, | ||
1187 | ARRAY_SIZE(mar20a_iar_overwrites)); | ||
1188 | if (ret) | ||
1189 | goto err_ret; | ||
1190 | |||
1191 | /* Clear HW indirect queue */ | ||
1192 | dev_dbg(printdev(lp), "clear HW indirect queue\n"); | ||
1193 | for (index = 0; index < MCR20A_PHY_INDIRECT_QUEUE_SIZE; index++) { | ||
1194 | phy_reg = (u8)(((index & DAR_SRC_CTRL_INDEX) << | ||
1195 | DAR_SRC_CTRL_INDEX_SHIFT) | ||
1196 | | (DAR_SRC_CTRL_SRCADDR_EN) | ||
1197 | | (DAR_SRC_CTRL_INDEX_DISABLE)); | ||
1198 | ret = regmap_write(lp->regmap_dar, DAR_SRC_CTRL, phy_reg); | ||
1199 | if (ret) | ||
1200 | goto err_ret; | ||
1201 | phy_reg = 0; | ||
1202 | } | ||
1203 | |||
1204 | /* Assign HW Indirect hash table to PAN0 */ | ||
1205 | ret = regmap_read(lp->regmap_iar, IAR_DUAL_PAN_CTRL, &phy_reg); | ||
1206 | if (ret) | ||
1207 | goto err_ret; | ||
1208 | |||
1209 | /* Clear current lvl */ | ||
1210 | phy_reg &= ~IAR_DUAL_PAN_CTRL_DUAL_PAN_SAM_LVL_MSK; | ||
1211 | |||
1212 | /* Set new lvl */ | ||
1213 | phy_reg |= MCR20A_PHY_INDIRECT_QUEUE_SIZE << | ||
1214 | IAR_DUAL_PAN_CTRL_DUAL_PAN_SAM_LVL_SHIFT; | ||
1215 | ret = regmap_write(lp->regmap_iar, IAR_DUAL_PAN_CTRL, phy_reg); | ||
1216 | if (ret) | ||
1217 | goto err_ret; | ||
1218 | |||
1219 | /* Set CCA threshold to -75 dBm */ | ||
1220 | ret = regmap_write(lp->regmap_iar, IAR_CCA1_THRESH, 0x4B); | ||
1221 | if (ret) | ||
1222 | goto err_ret; | ||
1223 | |||
1224 | /* Set prescaller to obtain 1 symbol (16us) timebase */ | ||
1225 | ret = regmap_write(lp->regmap_iar, IAR_TMR_PRESCALE, 0x05); | ||
1226 | if (ret) | ||
1227 | goto err_ret; | ||
1228 | |||
1229 | /* Enable autodoze mode. */ | ||
1230 | ret = regmap_update_bits(lp->regmap_dar, DAR_PWR_MODES, | ||
1231 | DAR_PWR_MODES_AUTODOZE, | ||
1232 | DAR_PWR_MODES_AUTODOZE); | ||
1233 | if (ret) | ||
1234 | goto err_ret; | ||
1235 | |||
1236 | /* Disable clk_out */ | ||
1237 | ret = regmap_update_bits(lp->regmap_dar, DAR_CLK_OUT_CTRL, | ||
1238 | DAR_CLK_OUT_CTRL_EN, 0x0); | ||
1239 | if (ret) | ||
1240 | goto err_ret; | ||
1241 | |||
1242 | return 0; | ||
1243 | |||
1244 | err_ret: | ||
1245 | return ret; | ||
1246 | } | ||
1247 | |||
1248 | static int | ||
1249 | mcr20a_probe(struct spi_device *spi) | ||
1250 | { | ||
1251 | struct ieee802154_hw *hw; | ||
1252 | struct mcr20a_local *lp; | ||
1253 | struct mcr20a_platform_data *pdata; | ||
1254 | int irq_type; | ||
1255 | int ret = -ENOMEM; | ||
1256 | |||
1257 | dev_dbg(&spi->dev, "%s\n", __func__); | ||
1258 | |||
1259 | if (!spi->irq) { | ||
1260 | dev_err(&spi->dev, "no IRQ specified\n"); | ||
1261 | return -EINVAL; | ||
1262 | } | ||
1263 | |||
1264 | pdata = kmalloc(sizeof(*pdata), GFP_KERNEL); | ||
1265 | if (!pdata) | ||
1266 | return -ENOMEM; | ||
1267 | |||
1268 | /* set mcr20a platform data */ | ||
1269 | ret = mcr20a_get_platform_data(spi, pdata); | ||
1270 | if (ret < 0) { | ||
1271 | dev_crit(&spi->dev, "mcr20a_get_platform_data failed.\n"); | ||
1272 | return ret; | ||
1273 | } | ||
1274 | |||
1275 | /* init reset gpio */ | ||
1276 | if (gpio_is_valid(pdata->rst_gpio)) { | ||
1277 | ret = devm_gpio_request_one(&spi->dev, pdata->rst_gpio, | ||
1278 | GPIOF_OUT_INIT_HIGH, "reset"); | ||
1279 | if (ret) | ||
1280 | return ret; | ||
1281 | } | ||
1282 | |||
1283 | /* reset mcr20a */ | ||
1284 | if (gpio_is_valid(pdata->rst_gpio)) { | ||
1285 | usleep_range(10, 20); | ||
1286 | gpio_set_value_cansleep(pdata->rst_gpio, 0); | ||
1287 | usleep_range(10, 20); | ||
1288 | gpio_set_value_cansleep(pdata->rst_gpio, 1); | ||
1289 | usleep_range(120, 240); | ||
1290 | } | ||
1291 | |||
1292 | /* allocate ieee802154_hw and private data */ | ||
1293 | hw = ieee802154_alloc_hw(sizeof(*lp), &mcr20a_hw_ops); | ||
1294 | if (!hw) { | ||
1295 | dev_crit(&spi->dev, "ieee802154_alloc_hw failed\n"); | ||
1296 | return -ENOMEM; | ||
1297 | } | ||
1298 | |||
1299 | /* init mcr20a local data */ | ||
1300 | lp = hw->priv; | ||
1301 | lp->hw = hw; | ||
1302 | lp->spi = spi; | ||
1303 | lp->spi->dev.platform_data = pdata; | ||
1304 | lp->pdata = pdata; | ||
1305 | |||
1306 | /* init ieee802154_hw */ | ||
1307 | hw->parent = &spi->dev; | ||
1308 | ieee802154_random_extended_addr(&hw->phy->perm_extended_addr); | ||
1309 | |||
1310 | /* init buf */ | ||
1311 | lp->buf = devm_kzalloc(&spi->dev, SPI_COMMAND_BUFFER, GFP_KERNEL); | ||
1312 | |||
1313 | if (!lp->buf) | ||
1314 | return -ENOMEM; | ||
1315 | |||
1316 | mcr20a_setup_tx_spi_messages(lp); | ||
1317 | mcr20a_setup_rx_spi_messages(lp); | ||
1318 | mcr20a_setup_irq_spi_messages(lp); | ||
1319 | |||
1320 | /* setup regmap */ | ||
1321 | lp->regmap_dar = devm_regmap_init_spi(spi, &mcr20a_dar_regmap); | ||
1322 | if (IS_ERR(lp->regmap_dar)) { | ||
1323 | ret = PTR_ERR(lp->regmap_dar); | ||
1324 | dev_err(&spi->dev, "Failed to allocate dar map: %d\n", | ||
1325 | ret); | ||
1326 | goto free_dev; | ||
1327 | } | ||
1328 | |||
1329 | lp->regmap_iar = devm_regmap_init_spi(spi, &mcr20a_iar_regmap); | ||
1330 | if (IS_ERR(lp->regmap_iar)) { | ||
1331 | ret = PTR_ERR(lp->regmap_iar); | ||
1332 | dev_err(&spi->dev, "Failed to allocate iar map: %d\n", ret); | ||
1333 | goto free_dev; | ||
1334 | } | ||
1335 | |||
1336 | mcr20a_hw_setup(lp); | ||
1337 | |||
1338 | spi_set_drvdata(spi, lp); | ||
1339 | |||
1340 | ret = mcr20a_phy_init(lp); | ||
1341 | if (ret < 0) { | ||
1342 | dev_crit(&spi->dev, "mcr20a_phy_init failed\n"); | ||
1343 | goto free_dev; | ||
1344 | } | ||
1345 | |||
1346 | irq_type = irq_get_trigger_type(spi->irq); | ||
1347 | if (!irq_type) | ||
1348 | irq_type = IRQF_TRIGGER_FALLING; | ||
1349 | |||
1350 | ret = devm_request_irq(&spi->dev, spi->irq, mcr20a_irq_isr, | ||
1351 | irq_type, dev_name(&spi->dev), lp); | ||
1352 | if (ret) { | ||
1353 | dev_err(&spi->dev, "could not request_irq for mcr20a\n"); | ||
1354 | ret = -ENODEV; | ||
1355 | goto free_dev; | ||
1356 | } | ||
1357 | |||
1358 | /* disable_irq by default and wait for starting hardware */ | ||
1359 | disable_irq(spi->irq); | ||
1360 | |||
1361 | ret = ieee802154_register_hw(hw); | ||
1362 | if (ret) { | ||
1363 | dev_crit(&spi->dev, "ieee802154_register_hw failed\n"); | ||
1364 | goto free_dev; | ||
1365 | } | ||
1366 | |||
1367 | return ret; | ||
1368 | |||
1369 | free_dev: | ||
1370 | ieee802154_free_hw(lp->hw); | ||
1371 | |||
1372 | return ret; | ||
1373 | } | ||
1374 | |||
1375 | static int mcr20a_remove(struct spi_device *spi) | ||
1376 | { | ||
1377 | struct mcr20a_local *lp = spi_get_drvdata(spi); | ||
1378 | |||
1379 | dev_dbg(&spi->dev, "%s\n", __func__); | ||
1380 | |||
1381 | ieee802154_unregister_hw(lp->hw); | ||
1382 | ieee802154_free_hw(lp->hw); | ||
1383 | |||
1384 | return 0; | ||
1385 | } | ||
1386 | |||
1387 | static const struct of_device_id mcr20a_of_match[] = { | ||
1388 | { .compatible = "nxp,mcr20a", }, | ||
1389 | { }, | ||
1390 | }; | ||
1391 | MODULE_DEVICE_TABLE(of, mcr20a_of_match); | ||
1392 | |||
1393 | static const struct spi_device_id mcr20a_device_id[] = { | ||
1394 | { .name = "mcr20a", }, | ||
1395 | { }, | ||
1396 | }; | ||
1397 | MODULE_DEVICE_TABLE(spi, mcr20a_device_id); | ||
1398 | |||
1399 | static struct spi_driver mcr20a_driver = { | ||
1400 | .id_table = mcr20a_device_id, | ||
1401 | .driver = { | ||
1402 | .of_match_table = of_match_ptr(mcr20a_of_match), | ||
1403 | .name = "mcr20a", | ||
1404 | }, | ||
1405 | .probe = mcr20a_probe, | ||
1406 | .remove = mcr20a_remove, | ||
1407 | }; | ||
1408 | |||
1409 | module_spi_driver(mcr20a_driver); | ||
1410 | |||
1411 | MODULE_DESCRIPTION("MCR20A Transceiver Driver"); | ||
1412 | MODULE_LICENSE("GPL v2"); | ||
1413 | MODULE_AUTHOR("Xue Liu <liuxuenetmail@gmail>"); | ||
diff --git a/drivers/net/ieee802154/mcr20a.h b/drivers/net/ieee802154/mcr20a.h new file mode 100644 index 000000000000..6da4fd00b3c5 --- /dev/null +++ b/drivers/net/ieee802154/mcr20a.h | |||
@@ -0,0 +1,498 @@ | |||
1 | /* | ||
2 | * Driver for NXP MCR20A 802.15.4 Wireless-PAN Networking controller | ||
3 | * | ||
4 | * Copyright (C) 2018 Xue Liu <liuxuenetmail@gmail.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 | ||
8 | * as published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | */ | ||
16 | #ifndef _MCR20A_H | ||
17 | #define _MCR20A_H | ||
18 | |||
19 | /* Direct Accress Register */ | ||
20 | #define DAR_IRQ_STS1 0x00 | ||
21 | #define DAR_IRQ_STS2 0x01 | ||
22 | #define DAR_IRQ_STS3 0x02 | ||
23 | #define DAR_PHY_CTRL1 0x03 | ||
24 | #define DAR_PHY_CTRL2 0x04 | ||
25 | #define DAR_PHY_CTRL3 0x05 | ||
26 | #define DAR_RX_FRM_LEN 0x06 | ||
27 | #define DAR_PHY_CTRL4 0x07 | ||
28 | #define DAR_SRC_CTRL 0x08 | ||
29 | #define DAR_SRC_ADDRS_SUM_LSB 0x09 | ||
30 | #define DAR_SRC_ADDRS_SUM_MSB 0x0A | ||
31 | #define DAR_CCA1_ED_FNL 0x0B | ||
32 | #define DAR_EVENT_TMR_LSB 0x0C | ||
33 | #define DAR_EVENT_TMR_MSB 0x0D | ||
34 | #define DAR_EVENT_TMR_USB 0x0E | ||
35 | #define DAR_TIMESTAMP_LSB 0x0F | ||
36 | #define DAR_TIMESTAMP_MSB 0x10 | ||
37 | #define DAR_TIMESTAMP_USB 0x11 | ||
38 | #define DAR_T3CMP_LSB 0x12 | ||
39 | #define DAR_T3CMP_MSB 0x13 | ||
40 | #define DAR_T3CMP_USB 0x14 | ||
41 | #define DAR_T2PRIMECMP_LSB 0x15 | ||
42 | #define DAR_T2PRIMECMP_MSB 0x16 | ||
43 | #define DAR_T1CMP_LSB 0x17 | ||
44 | #define DAR_T1CMP_MSB 0x18 | ||
45 | #define DAR_T1CMP_USB 0x19 | ||
46 | #define DAR_T2CMP_LSB 0x1A | ||
47 | #define DAR_T2CMP_MSB 0x1B | ||
48 | #define DAR_T2CMP_USB 0x1C | ||
49 | #define DAR_T4CMP_LSB 0x1D | ||
50 | #define DAR_T4CMP_MSB 0x1E | ||
51 | #define DAR_T4CMP_USB 0x1F | ||
52 | #define DAR_PLL_INT0 0x20 | ||
53 | #define DAR_PLL_FRAC0_LSB 0x21 | ||
54 | #define DAR_PLL_FRAC0_MSB 0x22 | ||
55 | #define DAR_PA_PWR 0x23 | ||
56 | #define DAR_SEQ_STATE 0x24 | ||
57 | #define DAR_LQI_VALUE 0x25 | ||
58 | #define DAR_RSSI_CCA_CONT 0x26 | ||
59 | /*------------------ 0x27 */ | ||
60 | #define DAR_ASM_CTRL1 0x28 | ||
61 | #define DAR_ASM_CTRL2 0x29 | ||
62 | #define DAR_ASM_DATA_0 0x2A | ||
63 | #define DAR_ASM_DATA_1 0x2B | ||
64 | #define DAR_ASM_DATA_2 0x2C | ||
65 | #define DAR_ASM_DATA_3 0x2D | ||
66 | #define DAR_ASM_DATA_4 0x2E | ||
67 | #define DAR_ASM_DATA_5 0x2F | ||
68 | #define DAR_ASM_DATA_6 0x30 | ||
69 | #define DAR_ASM_DATA_7 0x31 | ||
70 | #define DAR_ASM_DATA_8 0x32 | ||
71 | #define DAR_ASM_DATA_9 0x33 | ||
72 | #define DAR_ASM_DATA_A 0x34 | ||
73 | #define DAR_ASM_DATA_B 0x35 | ||
74 | #define DAR_ASM_DATA_C 0x36 | ||
75 | #define DAR_ASM_DATA_D 0x37 | ||
76 | #define DAR_ASM_DATA_E 0x38 | ||
77 | #define DAR_ASM_DATA_F 0x39 | ||
78 | /*----------------------- 0x3A */ | ||
79 | #define DAR_OVERWRITE_VER 0x3B | ||
80 | #define DAR_CLK_OUT_CTRL 0x3C | ||
81 | #define DAR_PWR_MODES 0x3D | ||
82 | #define IAR_INDEX 0x3E | ||
83 | #define IAR_DATA 0x3F | ||
84 | |||
85 | /* Indirect Resgister Memory */ | ||
86 | #define IAR_PART_ID 0x00 | ||
87 | #define IAR_XTAL_TRIM 0x01 | ||
88 | #define IAR_PMC_LP_TRIM 0x02 | ||
89 | #define IAR_MACPANID0_LSB 0x03 | ||
90 | #define IAR_MACPANID0_MSB 0x04 | ||
91 | #define IAR_MACSHORTADDRS0_LSB 0x05 | ||
92 | #define IAR_MACSHORTADDRS0_MSB 0x06 | ||
93 | #define IAR_MACLONGADDRS0_0 0x07 | ||
94 | #define IAR_MACLONGADDRS0_8 0x08 | ||
95 | #define IAR_MACLONGADDRS0_16 0x09 | ||
96 | #define IAR_MACLONGADDRS0_24 0x0A | ||
97 | #define IAR_MACLONGADDRS0_32 0x0B | ||
98 | #define IAR_MACLONGADDRS0_40 0x0C | ||
99 | #define IAR_MACLONGADDRS0_48 0x0D | ||
100 | #define IAR_MACLONGADDRS0_56 0x0E | ||
101 | #define IAR_RX_FRAME_FILTER 0x0F | ||
102 | #define IAR_PLL_INT1 0x10 | ||
103 | #define IAR_PLL_FRAC1_LSB 0x11 | ||
104 | #define IAR_PLL_FRAC1_MSB 0x12 | ||
105 | #define IAR_MACPANID1_LSB 0x13 | ||
106 | #define IAR_MACPANID1_MSB 0x14 | ||
107 | #define IAR_MACSHORTADDRS1_LSB 0x15 | ||
108 | #define IAR_MACSHORTADDRS1_MSB 0x16 | ||
109 | #define IAR_MACLONGADDRS1_0 0x17 | ||
110 | #define IAR_MACLONGADDRS1_8 0x18 | ||
111 | #define IAR_MACLONGADDRS1_16 0x19 | ||
112 | #define IAR_MACLONGADDRS1_24 0x1A | ||
113 | #define IAR_MACLONGADDRS1_32 0x1B | ||
114 | #define IAR_MACLONGADDRS1_40 0x1C | ||
115 | #define IAR_MACLONGADDRS1_48 0x1D | ||
116 | #define IAR_MACLONGADDRS1_56 0x1E | ||
117 | #define IAR_DUAL_PAN_CTRL 0x1F | ||
118 | #define IAR_DUAL_PAN_DWELL 0x20 | ||
119 | #define IAR_DUAL_PAN_STS 0x21 | ||
120 | #define IAR_CCA1_THRESH 0x22 | ||
121 | #define IAR_CCA1_ED_OFFSET_COMP 0x23 | ||
122 | #define IAR_LQI_OFFSET_COMP 0x24 | ||
123 | #define IAR_CCA_CTRL 0x25 | ||
124 | #define IAR_CCA2_CORR_PEAKS 0x26 | ||
125 | #define IAR_CCA2_CORR_THRESH 0x27 | ||
126 | #define IAR_TMR_PRESCALE 0x28 | ||
127 | /*-------------------- 0x29 */ | ||
128 | #define IAR_GPIO_DATA 0x2A | ||
129 | #define IAR_GPIO_DIR 0x2B | ||
130 | #define IAR_GPIO_PUL_EN 0x2C | ||
131 | #define IAR_GPIO_PUL_SEL 0x2D | ||
132 | #define IAR_GPIO_DS 0x2E | ||
133 | /*------------------ 0x2F */ | ||
134 | #define IAR_ANT_PAD_CTRL 0x30 | ||
135 | #define IAR_MISC_PAD_CTRL 0x31 | ||
136 | #define IAR_BSM_CTRL 0x32 | ||
137 | /*------------------- 0x33 */ | ||
138 | #define IAR_RNG 0x34 | ||
139 | #define IAR_RX_BYTE_COUNT 0x35 | ||
140 | #define IAR_RX_WTR_MARK 0x36 | ||
141 | #define IAR_SOFT_RESET 0x37 | ||
142 | #define IAR_TXDELAY 0x38 | ||
143 | #define IAR_ACKDELAY 0x39 | ||
144 | #define IAR_SEQ_MGR_CTRL 0x3A | ||
145 | #define IAR_SEQ_MGR_STS 0x3B | ||
146 | #define IAR_SEQ_T_STS 0x3C | ||
147 | #define IAR_ABORT_STS 0x3D | ||
148 | #define IAR_CCCA_BUSY_CNT 0x3E | ||
149 | #define IAR_SRC_ADDR_CHECKSUM1 0x3F | ||
150 | #define IAR_SRC_ADDR_CHECKSUM2 0x40 | ||
151 | #define IAR_SRC_TBL_VALID1 0x41 | ||
152 | #define IAR_SRC_TBL_VALID2 0x42 | ||
153 | #define IAR_FILTERFAIL_CODE1 0x43 | ||
154 | #define IAR_FILTERFAIL_CODE2 0x44 | ||
155 | #define IAR_SLOT_PRELOAD 0x45 | ||
156 | /*-------------------- 0x46 */ | ||
157 | #define IAR_CORR_VT 0x47 | ||
158 | #define IAR_SYNC_CTRL 0x48 | ||
159 | #define IAR_PN_LSB_0 0x49 | ||
160 | #define IAR_PN_LSB_1 0x4A | ||
161 | #define IAR_PN_MSB_0 0x4B | ||
162 | #define IAR_PN_MSB_1 0x4C | ||
163 | #define IAR_CORR_NVAL 0x4D | ||
164 | #define IAR_TX_MODE_CTRL 0x4E | ||
165 | #define IAR_SNF_THR 0x4F | ||
166 | #define IAR_FAD_THR 0x50 | ||
167 | #define IAR_ANT_AGC_CTRL 0x51 | ||
168 | #define IAR_AGC_THR1 0x52 | ||
169 | #define IAR_AGC_THR2 0x53 | ||
170 | #define IAR_AGC_HYS 0x54 | ||
171 | #define IAR_AFC 0x55 | ||
172 | /*------------------- 0x56 */ | ||
173 | /*------------------- 0x57 */ | ||
174 | #define IAR_PHY_STS 0x58 | ||
175 | #define IAR_RX_MAX_CORR 0x59 | ||
176 | #define IAR_RX_MAX_PREAMBLE 0x5A | ||
177 | #define IAR_RSSI 0x5B | ||
178 | /*------------------- 0x5C */ | ||
179 | /*------------------- 0x5D */ | ||
180 | #define IAR_PLL_DIG_CTRL 0x5E | ||
181 | #define IAR_VCO_CAL 0x5F | ||
182 | #define IAR_VCO_BEST_DIFF 0x60 | ||
183 | #define IAR_VCO_BIAS 0x61 | ||
184 | #define IAR_KMOD_CTRL 0x62 | ||
185 | #define IAR_KMOD_CAL 0x63 | ||
186 | #define IAR_PA_CAL 0x64 | ||
187 | #define IAR_PA_PWRCAL 0x65 | ||
188 | #define IAR_ATT_RSSI1 0x66 | ||
189 | #define IAR_ATT_RSSI2 0x67 | ||
190 | #define IAR_RSSI_OFFSET 0x68 | ||
191 | #define IAR_RSSI_SLOPE 0x69 | ||
192 | #define IAR_RSSI_CAL1 0x6A | ||
193 | #define IAR_RSSI_CAL2 0x6B | ||
194 | /*------------------- 0x6C */ | ||
195 | /*------------------- 0x6D */ | ||
196 | #define IAR_XTAL_CTRL 0x6E | ||
197 | #define IAR_XTAL_COMP_MIN 0x6F | ||
198 | #define IAR_XTAL_COMP_MAX 0x70 | ||
199 | #define IAR_XTAL_GM 0x71 | ||
200 | /*------------------- 0x72 */ | ||
201 | /*------------------- 0x73 */ | ||
202 | #define IAR_LNA_TUNE 0x74 | ||
203 | #define IAR_LNA_AGCGAIN 0x75 | ||
204 | /*------------------- 0x76 */ | ||
205 | /*------------------- 0x77 */ | ||
206 | #define IAR_CHF_PMA_GAIN 0x78 | ||
207 | #define IAR_CHF_IBUF 0x79 | ||
208 | #define IAR_CHF_QBUF 0x7A | ||
209 | #define IAR_CHF_IRIN 0x7B | ||
210 | #define IAR_CHF_QRIN 0x7C | ||
211 | #define IAR_CHF_IL 0x7D | ||
212 | #define IAR_CHF_QL 0x7E | ||
213 | #define IAR_CHF_CC1 0x7F | ||
214 | #define IAR_CHF_CCL 0x80 | ||
215 | #define IAR_CHF_CC2 0x81 | ||
216 | #define IAR_CHF_IROUT 0x82 | ||
217 | #define IAR_CHF_QROUT 0x83 | ||
218 | /*------------------- 0x84 */ | ||
219 | /*------------------- 0x85 */ | ||
220 | #define IAR_RSSI_CTRL 0x86 | ||
221 | /*------------------- 0x87 */ | ||
222 | /*------------------- 0x88 */ | ||
223 | #define IAR_PA_BIAS 0x89 | ||
224 | #define IAR_PA_TUNING 0x8A | ||
225 | /*------------------- 0x8B */ | ||
226 | /*------------------- 0x8C */ | ||
227 | #define IAR_PMC_HP_TRIM 0x8D | ||
228 | #define IAR_VREGA_TRIM 0x8E | ||
229 | /*------------------- 0x8F */ | ||
230 | /*------------------- 0x90 */ | ||
231 | #define IAR_VCO_CTRL1 0x91 | ||
232 | #define IAR_VCO_CTRL2 0x92 | ||
233 | /*------------------- 0x93 */ | ||
234 | /*------------------- 0x94 */ | ||
235 | #define IAR_ANA_SPARE_OUT1 0x95 | ||
236 | #define IAR_ANA_SPARE_OUT2 0x96 | ||
237 | #define IAR_ANA_SPARE_IN 0x97 | ||
238 | #define IAR_MISCELLANEOUS 0x98 | ||
239 | /*------------------- 0x99 */ | ||
240 | #define IAR_SEQ_MGR_OVRD0 0x9A | ||
241 | #define IAR_SEQ_MGR_OVRD1 0x9B | ||
242 | #define IAR_SEQ_MGR_OVRD2 0x9C | ||
243 | #define IAR_SEQ_MGR_OVRD3 0x9D | ||
244 | #define IAR_SEQ_MGR_OVRD4 0x9E | ||
245 | #define IAR_SEQ_MGR_OVRD5 0x9F | ||
246 | #define IAR_SEQ_MGR_OVRD6 0xA0 | ||
247 | #define IAR_SEQ_MGR_OVRD7 0xA1 | ||
248 | /*------------------- 0xA2 */ | ||
249 | #define IAR_TESTMODE_CTRL 0xA3 | ||
250 | #define IAR_DTM_CTRL1 0xA4 | ||
251 | #define IAR_DTM_CTRL2 0xA5 | ||
252 | #define IAR_ATM_CTRL1 0xA6 | ||
253 | #define IAR_ATM_CTRL2 0xA7 | ||
254 | #define IAR_ATM_CTRL3 0xA8 | ||
255 | /*------------------- 0xA9 */ | ||
256 | #define IAR_LIM_FE_TEST_CTRL 0xAA | ||
257 | #define IAR_CHF_TEST_CTRL 0xAB | ||
258 | #define IAR_VCO_TEST_CTRL 0xAC | ||
259 | #define IAR_PLL_TEST_CTRL 0xAD | ||
260 | #define IAR_PA_TEST_CTRL 0xAE | ||
261 | #define IAR_PMC_TEST_CTRL 0xAF | ||
262 | #define IAR_SCAN_DTM_PROTECT_1 0xFE | ||
263 | #define IAR_SCAN_DTM_PROTECT_0 0xFF | ||
264 | |||
265 | /* IRQSTS1 bits */ | ||
266 | #define DAR_IRQSTS1_RX_FRM_PEND BIT(7) | ||
267 | #define DAR_IRQSTS1_PLL_UNLOCK_IRQ BIT(6) | ||
268 | #define DAR_IRQSTS1_FILTERFAIL_IRQ BIT(5) | ||
269 | #define DAR_IRQSTS1_RXWTRMRKIRQ BIT(4) | ||
270 | #define DAR_IRQSTS1_CCAIRQ BIT(3) | ||
271 | #define DAR_IRQSTS1_RXIRQ BIT(2) | ||
272 | #define DAR_IRQSTS1_TXIRQ BIT(1) | ||
273 | #define DAR_IRQSTS1_SEQIRQ BIT(0) | ||
274 | |||
275 | /* IRQSTS2 bits */ | ||
276 | #define DAR_IRQSTS2_CRCVALID BIT(7) | ||
277 | #define DAR_IRQSTS2_CCA BIT(6) | ||
278 | #define DAR_IRQSTS2_SRCADDR BIT(5) | ||
279 | #define DAR_IRQSTS2_PI BIT(4) | ||
280 | #define DAR_IRQSTS2_TMRSTATUS BIT(3) | ||
281 | #define DAR_IRQSTS2_ASM_IRQ BIT(2) | ||
282 | #define DAR_IRQSTS2_PB_ERR_IRQ BIT(1) | ||
283 | #define DAR_IRQSTS2_WAKE_IRQ BIT(0) | ||
284 | |||
285 | /* IRQSTS3 bits */ | ||
286 | #define DAR_IRQSTS3_TMR4MSK BIT(7) | ||
287 | #define DAR_IRQSTS3_TMR3MSK BIT(6) | ||
288 | #define DAR_IRQSTS3_TMR2MSK BIT(5) | ||
289 | #define DAR_IRQSTS3_TMR1MSK BIT(4) | ||
290 | #define DAR_IRQSTS3_TMR4IRQ BIT(3) | ||
291 | #define DAR_IRQSTS3_TMR3IRQ BIT(2) | ||
292 | #define DAR_IRQSTS3_TMR2IRQ BIT(1) | ||
293 | #define DAR_IRQSTS3_TMR1IRQ BIT(0) | ||
294 | |||
295 | /* PHY_CTRL1 bits */ | ||
296 | #define DAR_PHY_CTRL1_TMRTRIGEN BIT(7) | ||
297 | #define DAR_PHY_CTRL1_SLOTTED BIT(6) | ||
298 | #define DAR_PHY_CTRL1_CCABFRTX BIT(5) | ||
299 | #define DAR_PHY_CTRL1_CCABFRTX_SHIFT 5 | ||
300 | #define DAR_PHY_CTRL1_RXACKRQD BIT(4) | ||
301 | #define DAR_PHY_CTRL1_AUTOACK BIT(3) | ||
302 | #define DAR_PHY_CTRL1_XCVSEQ_MASK 0x07 | ||
303 | |||
304 | /* PHY_CTRL2 bits */ | ||
305 | #define DAR_PHY_CTRL2_CRC_MSK BIT(7) | ||
306 | #define DAR_PHY_CTRL2_PLL_UNLOCK_MSK BIT(6) | ||
307 | #define DAR_PHY_CTRL2_FILTERFAIL_MSK BIT(5) | ||
308 | #define DAR_PHY_CTRL2_RX_WMRK_MSK BIT(4) | ||
309 | #define DAR_PHY_CTRL2_CCAMSK BIT(3) | ||
310 | #define DAR_PHY_CTRL2_RXMSK BIT(2) | ||
311 | #define DAR_PHY_CTRL2_TXMSK BIT(1) | ||
312 | #define DAR_PHY_CTRL2_SEQMSK BIT(0) | ||
313 | |||
314 | /* PHY_CTRL3 bits */ | ||
315 | #define DAR_PHY_CTRL3_TMR4CMP_EN BIT(7) | ||
316 | #define DAR_PHY_CTRL3_TMR3CMP_EN BIT(6) | ||
317 | #define DAR_PHY_CTRL3_TMR2CMP_EN BIT(5) | ||
318 | #define DAR_PHY_CTRL3_TMR1CMP_EN BIT(4) | ||
319 | #define DAR_PHY_CTRL3_ASM_MSK BIT(2) | ||
320 | #define DAR_PHY_CTRL3_PB_ERR_MSK BIT(1) | ||
321 | #define DAR_PHY_CTRL3_WAKE_MSK BIT(0) | ||
322 | |||
323 | /* RX_FRM_LEN bits */ | ||
324 | #define DAR_RX_FRAME_LENGTH_MASK (0x7F) | ||
325 | |||
326 | /* PHY_CTRL4 bits */ | ||
327 | #define DAR_PHY_CTRL4_TRCV_MSK BIT(7) | ||
328 | #define DAR_PHY_CTRL4_TC3TMOUT BIT(6) | ||
329 | #define DAR_PHY_CTRL4_PANCORDNTR0 BIT(5) | ||
330 | #define DAR_PHY_CTRL4_CCATYPE (3) | ||
331 | #define DAR_PHY_CTRL4_CCATYPE_SHIFT (3) | ||
332 | #define DAR_PHY_CTRL4_CCATYPE_MASK (0x18) | ||
333 | #define DAR_PHY_CTRL4_TMRLOAD BIT(2) | ||
334 | #define DAR_PHY_CTRL4_PROMISCUOUS BIT(1) | ||
335 | #define DAR_PHY_CTRL4_TC2PRIME_EN BIT(0) | ||
336 | |||
337 | /* SRC_CTRL bits */ | ||
338 | #define DAR_SRC_CTRL_INDEX (0x0F) | ||
339 | #define DAR_SRC_CTRL_INDEX_SHIFT (4) | ||
340 | #define DAR_SRC_CTRL_ACK_FRM_PND BIT(3) | ||
341 | #define DAR_SRC_CTRL_SRCADDR_EN BIT(2) | ||
342 | #define DAR_SRC_CTRL_INDEX_EN BIT(1) | ||
343 | #define DAR_SRC_CTRL_INDEX_DISABLE BIT(0) | ||
344 | |||
345 | /* DAR_ASM_CTRL1 bits */ | ||
346 | #define DAR_ASM_CTRL1_CLEAR BIT(7) | ||
347 | #define DAR_ASM_CTRL1_START BIT(6) | ||
348 | #define DAR_ASM_CTRL1_SELFTST BIT(5) | ||
349 | #define DAR_ASM_CTRL1_CTR BIT(4) | ||
350 | #define DAR_ASM_CTRL1_CBC BIT(3) | ||
351 | #define DAR_ASM_CTRL1_AES BIT(2) | ||
352 | #define DAR_ASM_CTRL1_LOAD_MAC BIT(1) | ||
353 | |||
354 | /* DAR_ASM_CTRL2 bits */ | ||
355 | #define DAR_ASM_CTRL2_DATA_REG_TYPE_SEL (7) | ||
356 | #define DAR_ASM_CTRL2_DATA_REG_TYPE_SEL_SHIFT (5) | ||
357 | #define DAR_ASM_CTRL2_TSTPAS BIT(1) | ||
358 | |||
359 | /* DAR_CLK_OUT_CTRL bits */ | ||
360 | #define DAR_CLK_OUT_CTRL_EXTEND BIT(7) | ||
361 | #define DAR_CLK_OUT_CTRL_HIZ BIT(6) | ||
362 | #define DAR_CLK_OUT_CTRL_SR BIT(5) | ||
363 | #define DAR_CLK_OUT_CTRL_DS BIT(4) | ||
364 | #define DAR_CLK_OUT_CTRL_EN BIT(3) | ||
365 | #define DAR_CLK_OUT_CTRL_DIV (7) | ||
366 | |||
367 | /* DAR_PWR_MODES bits */ | ||
368 | #define DAR_PWR_MODES_XTAL_READY BIT(5) | ||
369 | #define DAR_PWR_MODES_XTALEN BIT(4) | ||
370 | #define DAR_PWR_MODES_ASM_CLK_EN BIT(3) | ||
371 | #define DAR_PWR_MODES_AUTODOZE BIT(1) | ||
372 | #define DAR_PWR_MODES_PMC_MODE BIT(0) | ||
373 | |||
374 | /* RX_FRAME_FILTER bits */ | ||
375 | #define IAR_RX_FRAME_FLT_FRM_VER (0xC0) | ||
376 | #define IAR_RX_FRAME_FLT_FRM_VER_SHIFT (6) | ||
377 | #define IAR_RX_FRAME_FLT_ACTIVE_PROMISCUOUS BIT(5) | ||
378 | #define IAR_RX_FRAME_FLT_NS_FT BIT(4) | ||
379 | #define IAR_RX_FRAME_FLT_CMD_FT BIT(3) | ||
380 | #define IAR_RX_FRAME_FLT_ACK_FT BIT(2) | ||
381 | #define IAR_RX_FRAME_FLT_DATA_FT BIT(1) | ||
382 | #define IAR_RX_FRAME_FLT_BEACON_FT BIT(0) | ||
383 | |||
384 | /* DUAL_PAN_CTRL bits */ | ||
385 | #define IAR_DUAL_PAN_CTRL_DUAL_PAN_SAM_LVL_MSK (0xF0) | ||
386 | #define IAR_DUAL_PAN_CTRL_DUAL_PAN_SAM_LVL_SHIFT (4) | ||
387 | #define IAR_DUAL_PAN_CTRL_CURRENT_NETWORK BIT(3) | ||
388 | #define IAR_DUAL_PAN_CTRL_PANCORDNTR1 BIT(2) | ||
389 | #define IAR_DUAL_PAN_CTRL_DUAL_PAN_AUTO BIT(1) | ||
390 | #define IAR_DUAL_PAN_CTRL_ACTIVE_NETWORK BIT(0) | ||
391 | |||
392 | /* DUAL_PAN_STS bits */ | ||
393 | #define IAR_DUAL_PAN_STS_RECD_ON_PAN1 BIT(7) | ||
394 | #define IAR_DUAL_PAN_STS_RECD_ON_PAN0 BIT(6) | ||
395 | #define IAR_DUAL_PAN_STS_DUAL_PAN_REMAIN (0x3F) | ||
396 | |||
397 | /* CCA_CTRL bits */ | ||
398 | #define IAR_CCA_CTRL_AGC_FRZ_EN BIT(6) | ||
399 | #define IAR_CCA_CTRL_CONT_RSSI_EN BIT(5) | ||
400 | #define IAR_CCA_CTRL_LQI_RSSI_NOT_CORR BIT(4) | ||
401 | #define IAR_CCA_CTRL_CCA3_AND_NOT_OR BIT(3) | ||
402 | #define IAR_CCA_CTRL_POWER_COMP_EN_LQI BIT(2) | ||
403 | #define IAR_CCA_CTRL_POWER_COMP_EN_ED BIT(1) | ||
404 | #define IAR_CCA_CTRL_POWER_COMP_EN_CCA1 BIT(0) | ||
405 | |||
406 | /* ANT_PAD_CTRL bits */ | ||
407 | #define IAR_ANT_PAD_CTRL_ANTX_POL (0x0F) | ||
408 | #define IAR_ANT_PAD_CTRL_ANTX_POL_SHIFT (4) | ||
409 | #define IAR_ANT_PAD_CTRL_ANTX_CTRLMODE BIT(3) | ||
410 | #define IAR_ANT_PAD_CTRL_ANTX_HZ BIT(2) | ||
411 | #define IAR_ANT_PAD_CTRL_ANTX_EN (3) | ||
412 | |||
413 | /* MISC_PAD_CTRL bits */ | ||
414 | #define IAR_MISC_PAD_CTRL_MISO_HIZ_EN BIT(3) | ||
415 | #define IAR_MISC_PAD_CTRL_IRQ_B_OD BIT(2) | ||
416 | #define IAR_MISC_PAD_CTRL_NON_GPIO_DS BIT(1) | ||
417 | #define IAR_MISC_PAD_CTRL_ANTX_CURR (1) | ||
418 | |||
419 | /* ANT_AGC_CTRL bits */ | ||
420 | #define IAR_ANT_AGC_CTRL_FAD_EN_SHIFT (0) | ||
421 | #define IAR_ANT_AGC_CTRL_FAD_EN_MASK (1) | ||
422 | #define IAR_ANT_AGC_CTRL_ANTX_SHIFT (1) | ||
423 | #define IAR_ANT_AGC_CTRL_ANTX_MASK BIT(AR_ANT_AGC_CTRL_ANTX_SHIFT) | ||
424 | |||
425 | /* BSM_CTRL bits */ | ||
426 | #define BSM_CTRL_BSM_EN (1) | ||
427 | |||
428 | /* SOFT_RESET bits */ | ||
429 | #define IAR_SOFT_RESET_SOG_RST BIT(7) | ||
430 | #define IAR_SOFT_RESET_REGS_RST BIT(4) | ||
431 | #define IAR_SOFT_RESET_PLL_RST BIT(3) | ||
432 | #define IAR_SOFT_RESET_TX_RST BIT(2) | ||
433 | #define IAR_SOFT_RESET_RX_RST BIT(1) | ||
434 | #define IAR_SOFT_RESET_SEQ_MGR_RST BIT(0) | ||
435 | |||
436 | /* SEQ_MGR_CTRL bits */ | ||
437 | #define IAR_SEQ_MGR_CTRL_SEQ_STATE_CTRL (3) | ||
438 | #define IAR_SEQ_MGR_CTRL_SEQ_STATE_CTRL_SHIFT (6) | ||
439 | #define IAR_SEQ_MGR_CTRL_NO_RX_RECYCLE BIT(5) | ||
440 | #define IAR_SEQ_MGR_CTRL_LATCH_PREAMBLE BIT(4) | ||
441 | #define IAR_SEQ_MGR_CTRL_EVENT_TMR_DO_NOT_LATCH BIT(3) | ||
442 | #define IAR_SEQ_MGR_CTRL_CLR_NEW_SEQ_INHIBIT BIT(2) | ||
443 | #define IAR_SEQ_MGR_CTRL_PSM_LOCK_DIS BIT(1) | ||
444 | #define IAR_SEQ_MGR_CTRL_PLL_ABORT_OVRD BIT(0) | ||
445 | |||
446 | /* SEQ_MGR_STS bits */ | ||
447 | #define IAR_SEQ_MGR_STS_TMR2_SEQ_TRIG_ARMED BIT(7) | ||
448 | #define IAR_SEQ_MGR_STS_RX_MODE BIT(6) | ||
449 | #define IAR_SEQ_MGR_STS_RX_TIMEOUT_PENDING BIT(5) | ||
450 | #define IAR_SEQ_MGR_STS_NEW_SEQ_INHIBIT BIT(4) | ||
451 | #define IAR_SEQ_MGR_STS_SEQ_IDLE BIT(3) | ||
452 | #define IAR_SEQ_MGR_STS_XCVSEQ_ACTUAL (7) | ||
453 | |||
454 | /* ABORT_STS bits */ | ||
455 | #define IAR_ABORT_STS_PLL_ABORTED BIT(2) | ||
456 | #define IAR_ABORT_STS_TC3_ABORTED BIT(1) | ||
457 | #define IAR_ABORT_STS_SW_ABORTED BIT(0) | ||
458 | |||
459 | /* IAR_FILTERFAIL_CODE2 bits */ | ||
460 | #define IAR_FILTERFAIL_CODE2_PAN_SEL BIT(7) | ||
461 | #define IAR_FILTERFAIL_CODE2_9_8 (3) | ||
462 | |||
463 | /* PHY_STS bits */ | ||
464 | #define IAR_PHY_STS_PLL_UNLOCK BIT(7) | ||
465 | #define IAR_PHY_STS_PLL_LOCK_ERR BIT(6) | ||
466 | #define IAR_PHY_STS_PLL_LOCK BIT(5) | ||
467 | #define IAR_PHY_STS_CRCVALID BIT(3) | ||
468 | #define IAR_PHY_STS_FILTERFAIL_FLAG_SEL BIT(2) | ||
469 | #define IAR_PHY_STS_SFD_DET BIT(1) | ||
470 | #define IAR_PHY_STS_PREAMBLE_DET BIT(0) | ||
471 | |||
472 | /* TESTMODE_CTRL bits */ | ||
473 | #define IAR_TEST_MODE_CTRL_HOT_ANT BIT(4) | ||
474 | #define IAR_TEST_MODE_CTRL_IDEAL_RSSI_EN BIT(3) | ||
475 | #define IAR_TEST_MODE_CTRL_IDEAL_PFC_EN BIT(2) | ||
476 | #define IAR_TEST_MODE_CTRL_CONTINUOUS_EN BIT(1) | ||
477 | #define IAR_TEST_MODE_CTRL_FPGA_EN BIT(0) | ||
478 | |||
479 | /* DTM_CTRL1 bits */ | ||
480 | #define IAR_DTM_CTRL1_ATM_LOCKED BIT(7) | ||
481 | #define IAR_DTM_CTRL1_DTM_EN BIT(6) | ||
482 | #define IAR_DTM_CTRL1_PAGE5 BIT(5) | ||
483 | #define IAR_DTM_CTRL1_PAGE4 BIT(4) | ||
484 | #define IAR_DTM_CTRL1_PAGE3 BIT(3) | ||
485 | #define IAR_DTM_CTRL1_PAGE2 BIT(2) | ||
486 | #define IAR_DTM_CTRL1_PAGE1 BIT(1) | ||
487 | #define IAR_DTM_CTRL1_PAGE0 BIT(0) | ||
488 | |||
489 | /* TX_MODE_CTRL */ | ||
490 | #define IAR_TX_MODE_CTRL_TX_INV BIT(4) | ||
491 | #define IAR_TX_MODE_CTRL_BT_EN BIT(3) | ||
492 | #define IAR_TX_MODE_CTRL_DTS2 BIT(2) | ||
493 | #define IAR_TX_MODE_CTRL_DTS1 BIT(1) | ||
494 | #define IAR_TX_MODE_CTRL_DTS0 BIT(0) | ||
495 | |||
496 | #define TX_MODE_CTRL_DTS_MASK (7) | ||
497 | |||
498 | #endif /* _MCR20A_H */ | ||
diff --git a/net/ieee802154/6lowpan/core.c b/net/ieee802154/6lowpan/core.c index 974765b7d92a..e4f305320519 100644 --- a/net/ieee802154/6lowpan/core.c +++ b/net/ieee802154/6lowpan/core.c | |||
@@ -104,6 +104,7 @@ static void lowpan_setup(struct net_device *ldev) | |||
104 | /* We need an ipv6hdr as minimum len when calling xmit */ | 104 | /* We need an ipv6hdr as minimum len when calling xmit */ |
105 | ldev->hard_header_len = sizeof(struct ipv6hdr); | 105 | ldev->hard_header_len = sizeof(struct ipv6hdr); |
106 | ldev->flags = IFF_BROADCAST | IFF_MULTICAST; | 106 | ldev->flags = IFF_BROADCAST | IFF_MULTICAST; |
107 | ldev->priv_flags |= IFF_NO_QUEUE; | ||
107 | 108 | ||
108 | ldev->netdev_ops = &lowpan_netdev_ops; | 109 | ldev->netdev_ops = &lowpan_netdev_ops; |
109 | ldev->header_ops = &lowpan_header_ops; | 110 | ldev->header_ops = &lowpan_header_ops; |