1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* |
3 | * AT86RF230/RF231 driver |
4 | * |
5 | * Copyright (C) 2009-2012 Siemens AG |
6 | * |
7 | * Written by: |
8 | * Dmitry Eremin-Solenikov <dbaryshkov@gmail.com> |
9 | * Alexander Smirnov <alex.bluesman.smirnov@gmail.com> |
10 | * Alexander Aring <aar@pengutronix.de> |
11 | */ |
12 | #include <linux/kernel.h> |
13 | #include <linux/module.h> |
14 | #include <linux/hrtimer.h> |
15 | #include <linux/jiffies.h> |
16 | #include <linux/interrupt.h> |
17 | #include <linux/irq.h> |
18 | #include <linux/gpio.h> |
19 | #include <linux/delay.h> |
20 | #include <linux/property.h> |
21 | #include <linux/spi/spi.h> |
22 | #include <linux/regmap.h> |
23 | #include <linux/skbuff.h> |
24 | #include <linux/of_gpio.h> |
25 | #include <linux/ieee802154.h> |
26 | |
27 | #include <net/mac802154.h> |
28 | #include <net/cfg802154.h> |
29 | |
30 | #include "at86rf230.h" |
31 | |
32 | struct at86rf230_local; |
33 | /* at86rf2xx chip depend data. |
34 | * All timings are in us. |
35 | */ |
36 | struct at86rf2xx_chip_data { |
37 | u16 t_sleep_cycle; |
38 | u16 t_channel_switch; |
39 | u16 t_reset_to_off; |
40 | u16 t_off_to_aack; |
41 | u16 t_off_to_tx_on; |
42 | u16 t_off_to_sleep; |
43 | u16 t_sleep_to_off; |
44 | u16 t_frame; |
45 | u16 t_p_ack; |
46 | int ; |
47 | |
48 | int (*set_channel)(struct at86rf230_local *, u8, u8); |
49 | int (*set_txpower)(struct at86rf230_local *, s32); |
50 | }; |
51 | |
52 | #define AT86RF2XX_MAX_BUF (127 + 3) |
53 | /* tx retries to access the TX_ON state |
54 | * if it's above then force change will be started. |
55 | * |
56 | * We assume the max_frame_retries (7) value of 802.15.4 here. |
57 | */ |
58 | #define AT86RF2XX_MAX_TX_RETRIES 7 |
59 | /* We use the recommended 5 minutes timeout to recalibrate */ |
60 | #define AT86RF2XX_CAL_LOOP_TIMEOUT (5 * 60 * HZ) |
61 | |
62 | struct at86rf230_state_change { |
63 | struct at86rf230_local *lp; |
64 | int irq; |
65 | |
66 | struct hrtimer timer; |
67 | struct spi_message msg; |
68 | struct spi_transfer trx; |
69 | u8 buf[AT86RF2XX_MAX_BUF]; |
70 | |
71 | void (*complete)(void *context); |
72 | u8 from_state; |
73 | u8 to_state; |
74 | int trac; |
75 | |
76 | bool free; |
77 | }; |
78 | |
79 | struct at86rf230_local { |
80 | struct spi_device *spi; |
81 | |
82 | struct ieee802154_hw *hw; |
83 | struct at86rf2xx_chip_data *data; |
84 | struct regmap *regmap; |
85 | struct gpio_desc *slp_tr; |
86 | bool sleep; |
87 | |
88 | struct completion state_complete; |
89 | struct at86rf230_state_change state; |
90 | |
91 | unsigned long cal_timeout; |
92 | bool is_tx; |
93 | bool is_tx_from_off; |
94 | bool was_tx; |
95 | u8 tx_retry; |
96 | struct sk_buff *tx_skb; |
97 | struct at86rf230_state_change tx; |
98 | }; |
99 | |
100 | #define AT86RF2XX_NUMREGS 0x3F |
101 | |
102 | static void |
103 | at86rf230_async_state_change(struct at86rf230_local *lp, |
104 | struct at86rf230_state_change *ctx, |
105 | const u8 state, void (*complete)(void *context)); |
106 | |
107 | static inline void |
108 | at86rf230_sleep(struct at86rf230_local *lp) |
109 | { |
110 | if (lp->slp_tr) { |
111 | gpiod_set_value(desc: lp->slp_tr, value: 1); |
112 | usleep_range(min: lp->data->t_off_to_sleep, |
113 | max: lp->data->t_off_to_sleep + 10); |
114 | lp->sleep = true; |
115 | } |
116 | } |
117 | |
118 | static inline void |
119 | at86rf230_awake(struct at86rf230_local *lp) |
120 | { |
121 | if (lp->slp_tr) { |
122 | gpiod_set_value(desc: lp->slp_tr, value: 0); |
123 | usleep_range(min: lp->data->t_sleep_to_off, |
124 | max: lp->data->t_sleep_to_off + 100); |
125 | lp->sleep = false; |
126 | } |
127 | } |
128 | |
129 | static inline int |
130 | __at86rf230_write(struct at86rf230_local *lp, |
131 | unsigned int addr, unsigned int data) |
132 | { |
133 | bool sleep = lp->sleep; |
134 | int ret; |
135 | |
136 | /* awake for register setting if sleep */ |
137 | if (sleep) |
138 | at86rf230_awake(lp); |
139 | |
140 | ret = regmap_write(map: lp->regmap, reg: addr, val: data); |
141 | |
142 | /* sleep again if was sleeping */ |
143 | if (sleep) |
144 | at86rf230_sleep(lp); |
145 | |
146 | return ret; |
147 | } |
148 | |
149 | static inline int |
150 | __at86rf230_read(struct at86rf230_local *lp, |
151 | unsigned int addr, unsigned int *data) |
152 | { |
153 | bool sleep = lp->sleep; |
154 | int ret; |
155 | |
156 | /* awake for register setting if sleep */ |
157 | if (sleep) |
158 | at86rf230_awake(lp); |
159 | |
160 | ret = regmap_read(map: lp->regmap, reg: addr, val: data); |
161 | |
162 | /* sleep again if was sleeping */ |
163 | if (sleep) |
164 | at86rf230_sleep(lp); |
165 | |
166 | return ret; |
167 | } |
168 | |
169 | static inline int |
170 | at86rf230_read_subreg(struct at86rf230_local *lp, |
171 | unsigned int addr, unsigned int mask, |
172 | unsigned int shift, unsigned int *data) |
173 | { |
174 | int rc; |
175 | |
176 | rc = __at86rf230_read(lp, addr, data); |
177 | if (!rc) |
178 | *data = (*data & mask) >> shift; |
179 | |
180 | return rc; |
181 | } |
182 | |
183 | static inline int |
184 | at86rf230_write_subreg(struct at86rf230_local *lp, |
185 | unsigned int addr, unsigned int mask, |
186 | unsigned int shift, unsigned int data) |
187 | { |
188 | bool sleep = lp->sleep; |
189 | int ret; |
190 | |
191 | /* awake for register setting if sleep */ |
192 | if (sleep) |
193 | at86rf230_awake(lp); |
194 | |
195 | ret = regmap_update_bits(map: lp->regmap, reg: addr, mask, val: data << shift); |
196 | |
197 | /* sleep again if was sleeping */ |
198 | if (sleep) |
199 | at86rf230_sleep(lp); |
200 | |
201 | return ret; |
202 | } |
203 | |
204 | static inline void |
205 | at86rf230_slp_tr_rising_edge(struct at86rf230_local *lp) |
206 | { |
207 | gpiod_set_value(desc: lp->slp_tr, value: 1); |
208 | udelay(1); |
209 | gpiod_set_value(desc: lp->slp_tr, value: 0); |
210 | } |
211 | |
212 | static bool |
213 | at86rf230_reg_writeable(struct device *dev, unsigned int reg) |
214 | { |
215 | switch (reg) { |
216 | case RG_TRX_STATE: |
217 | case RG_TRX_CTRL_0: |
218 | case RG_TRX_CTRL_1: |
219 | case RG_PHY_TX_PWR: |
220 | case RG_PHY_ED_LEVEL: |
221 | case RG_PHY_CC_CCA: |
222 | case RG_CCA_THRES: |
223 | case RG_RX_CTRL: |
224 | case RG_SFD_VALUE: |
225 | case RG_TRX_CTRL_2: |
226 | case RG_ANT_DIV: |
227 | case RG_IRQ_MASK: |
228 | case RG_VREG_CTRL: |
229 | case RG_BATMON: |
230 | case RG_XOSC_CTRL: |
231 | case RG_RX_SYN: |
232 | case RG_XAH_CTRL_1: |
233 | case RG_FTN_CTRL: |
234 | case RG_PLL_CF: |
235 | case RG_PLL_DCU: |
236 | case RG_SHORT_ADDR_0: |
237 | case RG_SHORT_ADDR_1: |
238 | case RG_PAN_ID_0: |
239 | case RG_PAN_ID_1: |
240 | case RG_IEEE_ADDR_0: |
241 | case RG_IEEE_ADDR_1: |
242 | case RG_IEEE_ADDR_2: |
243 | case RG_IEEE_ADDR_3: |
244 | case RG_IEEE_ADDR_4: |
245 | case RG_IEEE_ADDR_5: |
246 | case RG_IEEE_ADDR_6: |
247 | case RG_IEEE_ADDR_7: |
248 | case RG_XAH_CTRL_0: |
249 | case RG_CSMA_SEED_0: |
250 | case RG_CSMA_SEED_1: |
251 | case RG_CSMA_BE: |
252 | return true; |
253 | default: |
254 | return false; |
255 | } |
256 | } |
257 | |
258 | static bool |
259 | at86rf230_reg_readable(struct device *dev, unsigned int reg) |
260 | { |
261 | bool rc; |
262 | |
263 | /* all writeable are also readable */ |
264 | rc = at86rf230_reg_writeable(dev, reg); |
265 | if (rc) |
266 | return rc; |
267 | |
268 | /* readonly regs */ |
269 | switch (reg) { |
270 | case RG_TRX_STATUS: |
271 | case RG_PHY_RSSI: |
272 | case RG_IRQ_STATUS: |
273 | case RG_PART_NUM: |
274 | case RG_VERSION_NUM: |
275 | case RG_MAN_ID_1: |
276 | case RG_MAN_ID_0: |
277 | return true; |
278 | default: |
279 | return false; |
280 | } |
281 | } |
282 | |
283 | static bool |
284 | at86rf230_reg_volatile(struct device *dev, unsigned int reg) |
285 | { |
286 | /* can be changed during runtime */ |
287 | switch (reg) { |
288 | case RG_TRX_STATUS: |
289 | case RG_TRX_STATE: |
290 | case RG_PHY_RSSI: |
291 | case RG_PHY_ED_LEVEL: |
292 | case RG_IRQ_STATUS: |
293 | case RG_VREG_CTRL: |
294 | case RG_PLL_CF: |
295 | case RG_PLL_DCU: |
296 | return true; |
297 | default: |
298 | return false; |
299 | } |
300 | } |
301 | |
302 | static bool |
303 | at86rf230_reg_precious(struct device *dev, unsigned int reg) |
304 | { |
305 | /* don't clear irq line on read */ |
306 | switch (reg) { |
307 | case RG_IRQ_STATUS: |
308 | return true; |
309 | default: |
310 | return false; |
311 | } |
312 | } |
313 | |
314 | static const struct regmap_config at86rf230_regmap_spi_config = { |
315 | .reg_bits = 8, |
316 | .val_bits = 8, |
317 | .write_flag_mask = CMD_REG | CMD_WRITE, |
318 | .read_flag_mask = CMD_REG, |
319 | .cache_type = REGCACHE_RBTREE, |
320 | .max_register = AT86RF2XX_NUMREGS, |
321 | .writeable_reg = at86rf230_reg_writeable, |
322 | .readable_reg = at86rf230_reg_readable, |
323 | .volatile_reg = at86rf230_reg_volatile, |
324 | .precious_reg = at86rf230_reg_precious, |
325 | }; |
326 | |
327 | static void |
328 | at86rf230_async_error_recover_complete(void *context) |
329 | { |
330 | struct at86rf230_state_change *ctx = context; |
331 | struct at86rf230_local *lp = ctx->lp; |
332 | |
333 | if (ctx->free) |
334 | kfree(objp: ctx); |
335 | |
336 | if (lp->was_tx) { |
337 | lp->was_tx = 0; |
338 | ieee802154_xmit_hw_error(hw: lp->hw, skb: lp->tx_skb); |
339 | } |
340 | } |
341 | |
342 | static void |
343 | at86rf230_async_error_recover(void *context) |
344 | { |
345 | struct at86rf230_state_change *ctx = context; |
346 | struct at86rf230_local *lp = ctx->lp; |
347 | |
348 | if (lp->is_tx) { |
349 | lp->was_tx = 1; |
350 | lp->is_tx = 0; |
351 | } |
352 | |
353 | at86rf230_async_state_change(lp, ctx, STATE_RX_AACK_ON, |
354 | complete: at86rf230_async_error_recover_complete); |
355 | } |
356 | |
357 | static inline void |
358 | at86rf230_async_error(struct at86rf230_local *lp, |
359 | struct at86rf230_state_change *ctx, int rc) |
360 | { |
361 | dev_err(&lp->spi->dev, "spi_async error %d\n" , rc); |
362 | |
363 | at86rf230_async_state_change(lp, ctx, STATE_FORCE_TRX_OFF, |
364 | complete: at86rf230_async_error_recover); |
365 | } |
366 | |
367 | /* Generic function to get some register value in async mode */ |
368 | static void |
369 | at86rf230_async_read_reg(struct at86rf230_local *lp, u8 reg, |
370 | struct at86rf230_state_change *ctx, |
371 | void (*complete)(void *context)) |
372 | { |
373 | int rc; |
374 | |
375 | u8 *tx_buf = ctx->buf; |
376 | |
377 | tx_buf[0] = (reg & CMD_REG_MASK) | CMD_REG; |
378 | ctx->msg.complete = complete; |
379 | rc = spi_async(spi: lp->spi, message: &ctx->msg); |
380 | if (rc) |
381 | at86rf230_async_error(lp, ctx, rc); |
382 | } |
383 | |
384 | static void |
385 | at86rf230_async_write_reg(struct at86rf230_local *lp, u8 reg, u8 val, |
386 | struct at86rf230_state_change *ctx, |
387 | void (*complete)(void *context)) |
388 | { |
389 | int rc; |
390 | |
391 | ctx->buf[0] = (reg & CMD_REG_MASK) | CMD_REG | CMD_WRITE; |
392 | ctx->buf[1] = val; |
393 | ctx->msg.complete = complete; |
394 | rc = spi_async(spi: lp->spi, message: &ctx->msg); |
395 | if (rc) |
396 | at86rf230_async_error(lp, ctx, rc); |
397 | } |
398 | |
399 | static void |
400 | at86rf230_async_state_assert(void *context) |
401 | { |
402 | struct at86rf230_state_change *ctx = context; |
403 | struct at86rf230_local *lp = ctx->lp; |
404 | const u8 *buf = ctx->buf; |
405 | const u8 trx_state = buf[1] & TRX_STATE_MASK; |
406 | |
407 | /* Assert state change */ |
408 | if (trx_state != ctx->to_state) { |
409 | /* Special handling if transceiver state is in |
410 | * STATE_BUSY_RX_AACK and a SHR was detected. |
411 | */ |
412 | if (trx_state == STATE_BUSY_RX_AACK) { |
413 | /* Undocumented race condition. If we send a state |
414 | * change to STATE_RX_AACK_ON the transceiver could |
415 | * change his state automatically to STATE_BUSY_RX_AACK |
416 | * if a SHR was detected. This is not an error, but we |
417 | * can't assert this. |
418 | */ |
419 | if (ctx->to_state == STATE_RX_AACK_ON) |
420 | goto done; |
421 | |
422 | /* If we change to STATE_TX_ON without forcing and |
423 | * transceiver state is STATE_BUSY_RX_AACK, we wait |
424 | * 'tFrame + tPAck' receiving time. In this time the |
425 | * PDU should be received. If the transceiver is still |
426 | * in STATE_BUSY_RX_AACK, we run a force state change |
427 | * to STATE_TX_ON. This is a timeout handling, if the |
428 | * transceiver stucks in STATE_BUSY_RX_AACK. |
429 | * |
430 | * Additional we do several retries to try to get into |
431 | * TX_ON state without forcing. If the retries are |
432 | * higher or equal than AT86RF2XX_MAX_TX_RETRIES we |
433 | * will do a force change. |
434 | */ |
435 | if (ctx->to_state == STATE_TX_ON || |
436 | ctx->to_state == STATE_TRX_OFF) { |
437 | u8 state = ctx->to_state; |
438 | |
439 | if (lp->tx_retry >= AT86RF2XX_MAX_TX_RETRIES) |
440 | state = STATE_FORCE_TRX_OFF; |
441 | lp->tx_retry++; |
442 | |
443 | at86rf230_async_state_change(lp, ctx, state, |
444 | complete: ctx->complete); |
445 | return; |
446 | } |
447 | } |
448 | |
449 | dev_warn(&lp->spi->dev, "unexcept state change from 0x%02x to 0x%02x. Actual state: 0x%02x\n" , |
450 | ctx->from_state, ctx->to_state, trx_state); |
451 | } |
452 | |
453 | done: |
454 | if (ctx->complete) |
455 | ctx->complete(context); |
456 | } |
457 | |
458 | static enum hrtimer_restart at86rf230_async_state_timer(struct hrtimer *timer) |
459 | { |
460 | struct at86rf230_state_change *ctx = |
461 | container_of(timer, struct at86rf230_state_change, timer); |
462 | struct at86rf230_local *lp = ctx->lp; |
463 | |
464 | at86rf230_async_read_reg(lp, RG_TRX_STATUS, ctx, |
465 | complete: at86rf230_async_state_assert); |
466 | |
467 | return HRTIMER_NORESTART; |
468 | } |
469 | |
470 | /* Do state change timing delay. */ |
471 | static void |
472 | at86rf230_async_state_delay(void *context) |
473 | { |
474 | struct at86rf230_state_change *ctx = context; |
475 | struct at86rf230_local *lp = ctx->lp; |
476 | struct at86rf2xx_chip_data *c = lp->data; |
477 | bool force = false; |
478 | ktime_t tim; |
479 | |
480 | /* The force state changes are will show as normal states in the |
481 | * state status subregister. We change the to_state to the |
482 | * corresponding one and remember if it was a force change, this |
483 | * differs if we do a state change from STATE_BUSY_RX_AACK. |
484 | */ |
485 | switch (ctx->to_state) { |
486 | case STATE_FORCE_TX_ON: |
487 | ctx->to_state = STATE_TX_ON; |
488 | force = true; |
489 | break; |
490 | case STATE_FORCE_TRX_OFF: |
491 | ctx->to_state = STATE_TRX_OFF; |
492 | force = true; |
493 | break; |
494 | default: |
495 | break; |
496 | } |
497 | |
498 | switch (ctx->from_state) { |
499 | case STATE_TRX_OFF: |
500 | switch (ctx->to_state) { |
501 | case STATE_RX_AACK_ON: |
502 | tim = c->t_off_to_aack * NSEC_PER_USEC; |
503 | /* state change from TRX_OFF to RX_AACK_ON to do a |
504 | * calibration, we need to reset the timeout for the |
505 | * next one. |
506 | */ |
507 | lp->cal_timeout = jiffies + AT86RF2XX_CAL_LOOP_TIMEOUT; |
508 | goto change; |
509 | case STATE_TX_ARET_ON: |
510 | case STATE_TX_ON: |
511 | tim = c->t_off_to_tx_on * NSEC_PER_USEC; |
512 | /* state change from TRX_OFF to TX_ON or ARET_ON to do |
513 | * a calibration, we need to reset the timeout for the |
514 | * next one. |
515 | */ |
516 | lp->cal_timeout = jiffies + AT86RF2XX_CAL_LOOP_TIMEOUT; |
517 | goto change; |
518 | default: |
519 | break; |
520 | } |
521 | break; |
522 | case STATE_BUSY_RX_AACK: |
523 | switch (ctx->to_state) { |
524 | case STATE_TRX_OFF: |
525 | case STATE_TX_ON: |
526 | /* Wait for worst case receiving time if we |
527 | * didn't make a force change from BUSY_RX_AACK |
528 | * to TX_ON or TRX_OFF. |
529 | */ |
530 | if (!force) { |
531 | tim = (c->t_frame + c->t_p_ack) * NSEC_PER_USEC; |
532 | goto change; |
533 | } |
534 | break; |
535 | default: |
536 | break; |
537 | } |
538 | break; |
539 | /* Default value, means RESET state */ |
540 | case STATE_P_ON: |
541 | switch (ctx->to_state) { |
542 | case STATE_TRX_OFF: |
543 | tim = c->t_reset_to_off * NSEC_PER_USEC; |
544 | goto change; |
545 | default: |
546 | break; |
547 | } |
548 | break; |
549 | default: |
550 | break; |
551 | } |
552 | |
553 | /* Default delay is 1us in the most cases */ |
554 | udelay(1); |
555 | at86rf230_async_state_timer(timer: &ctx->timer); |
556 | return; |
557 | |
558 | change: |
559 | hrtimer_start(timer: &ctx->timer, tim, mode: HRTIMER_MODE_REL); |
560 | } |
561 | |
562 | static void |
563 | at86rf230_async_state_change_start(void *context) |
564 | { |
565 | struct at86rf230_state_change *ctx = context; |
566 | struct at86rf230_local *lp = ctx->lp; |
567 | u8 *buf = ctx->buf; |
568 | const u8 trx_state = buf[1] & TRX_STATE_MASK; |
569 | |
570 | /* Check for "possible" STATE_TRANSITION_IN_PROGRESS */ |
571 | if (trx_state == STATE_TRANSITION_IN_PROGRESS) { |
572 | udelay(1); |
573 | at86rf230_async_read_reg(lp, RG_TRX_STATUS, ctx, |
574 | complete: at86rf230_async_state_change_start); |
575 | return; |
576 | } |
577 | |
578 | /* Check if we already are in the state which we change in */ |
579 | if (trx_state == ctx->to_state) { |
580 | if (ctx->complete) |
581 | ctx->complete(context); |
582 | return; |
583 | } |
584 | |
585 | /* Set current state to the context of state change */ |
586 | ctx->from_state = trx_state; |
587 | |
588 | /* Going into the next step for a state change which do a timing |
589 | * relevant delay. |
590 | */ |
591 | at86rf230_async_write_reg(lp, RG_TRX_STATE, val: ctx->to_state, ctx, |
592 | complete: at86rf230_async_state_delay); |
593 | } |
594 | |
595 | static void |
596 | at86rf230_async_state_change(struct at86rf230_local *lp, |
597 | struct at86rf230_state_change *ctx, |
598 | const u8 state, void (*complete)(void *context)) |
599 | { |
600 | /* Initialization for the state change context */ |
601 | ctx->to_state = state; |
602 | ctx->complete = complete; |
603 | at86rf230_async_read_reg(lp, RG_TRX_STATUS, ctx, |
604 | complete: at86rf230_async_state_change_start); |
605 | } |
606 | |
607 | static void |
608 | at86rf230_sync_state_change_complete(void *context) |
609 | { |
610 | struct at86rf230_state_change *ctx = context; |
611 | struct at86rf230_local *lp = ctx->lp; |
612 | |
613 | complete(&lp->state_complete); |
614 | } |
615 | |
616 | /* This function do a sync framework above the async state change. |
617 | * Some callbacks of the IEEE 802.15.4 driver interface need to be |
618 | * handled synchronously. |
619 | */ |
620 | static int |
621 | at86rf230_sync_state_change(struct at86rf230_local *lp, unsigned int state) |
622 | { |
623 | unsigned long rc; |
624 | |
625 | at86rf230_async_state_change(lp, ctx: &lp->state, state, |
626 | complete: at86rf230_sync_state_change_complete); |
627 | |
628 | rc = wait_for_completion_timeout(x: &lp->state_complete, |
629 | timeout: msecs_to_jiffies(m: 100)); |
630 | if (!rc) { |
631 | at86rf230_async_error(lp, ctx: &lp->state, rc: -ETIMEDOUT); |
632 | return -ETIMEDOUT; |
633 | } |
634 | |
635 | return 0; |
636 | } |
637 | |
638 | static void |
639 | at86rf230_tx_complete(void *context) |
640 | { |
641 | struct at86rf230_state_change *ctx = context; |
642 | struct at86rf230_local *lp = ctx->lp; |
643 | |
644 | if (ctx->trac == IEEE802154_SUCCESS) |
645 | ieee802154_xmit_complete(hw: lp->hw, skb: lp->tx_skb, ifs_handling: false); |
646 | else |
647 | ieee802154_xmit_error(hw: lp->hw, skb: lp->tx_skb, reason: ctx->trac); |
648 | |
649 | kfree(objp: ctx); |
650 | } |
651 | |
652 | static void |
653 | at86rf230_tx_on(void *context) |
654 | { |
655 | struct at86rf230_state_change *ctx = context; |
656 | struct at86rf230_local *lp = ctx->lp; |
657 | |
658 | at86rf230_async_state_change(lp, ctx, STATE_RX_AACK_ON, |
659 | complete: at86rf230_tx_complete); |
660 | } |
661 | |
662 | static void |
663 | at86rf230_tx_trac_check(void *context) |
664 | { |
665 | struct at86rf230_state_change *ctx = context; |
666 | struct at86rf230_local *lp = ctx->lp; |
667 | u8 trac = TRAC_MASK(ctx->buf[1]); |
668 | |
669 | switch (trac) { |
670 | case TRAC_SUCCESS: |
671 | case TRAC_SUCCESS_DATA_PENDING: |
672 | ctx->trac = IEEE802154_SUCCESS; |
673 | break; |
674 | case TRAC_CHANNEL_ACCESS_FAILURE: |
675 | ctx->trac = IEEE802154_CHANNEL_ACCESS_FAILURE; |
676 | break; |
677 | case TRAC_NO_ACK: |
678 | ctx->trac = IEEE802154_NO_ACK; |
679 | break; |
680 | default: |
681 | ctx->trac = IEEE802154_SYSTEM_ERROR; |
682 | } |
683 | |
684 | at86rf230_async_state_change(lp, ctx, STATE_TX_ON, complete: at86rf230_tx_on); |
685 | } |
686 | |
687 | static void |
688 | at86rf230_rx_read_frame_complete(void *context) |
689 | { |
690 | struct at86rf230_state_change *ctx = context; |
691 | struct at86rf230_local *lp = ctx->lp; |
692 | const u8 *buf = ctx->buf; |
693 | struct sk_buff *skb; |
694 | u8 len, lqi; |
695 | |
696 | len = buf[1]; |
697 | if (!ieee802154_is_valid_psdu_len(len)) { |
698 | dev_vdbg(&lp->spi->dev, "corrupted frame received\n" ); |
699 | len = IEEE802154_MTU; |
700 | } |
701 | lqi = buf[2 + len]; |
702 | |
703 | skb = dev_alloc_skb(IEEE802154_MTU); |
704 | if (!skb) { |
705 | dev_vdbg(&lp->spi->dev, "failed to allocate sk_buff\n" ); |
706 | kfree(objp: ctx); |
707 | return; |
708 | } |
709 | |
710 | skb_put_data(skb, data: buf + 2, len); |
711 | ieee802154_rx_irqsafe(hw: lp->hw, skb, lqi); |
712 | kfree(objp: ctx); |
713 | } |
714 | |
715 | static void |
716 | at86rf230_rx_trac_check(void *context) |
717 | { |
718 | struct at86rf230_state_change *ctx = context; |
719 | struct at86rf230_local *lp = ctx->lp; |
720 | u8 *buf = ctx->buf; |
721 | int rc; |
722 | |
723 | buf[0] = CMD_FB; |
724 | ctx->trx.len = AT86RF2XX_MAX_BUF; |
725 | ctx->msg.complete = at86rf230_rx_read_frame_complete; |
726 | rc = spi_async(spi: lp->spi, message: &ctx->msg); |
727 | if (rc) { |
728 | ctx->trx.len = 2; |
729 | at86rf230_async_error(lp, ctx, rc); |
730 | } |
731 | } |
732 | |
733 | static void |
734 | at86rf230_irq_trx_end(void *context) |
735 | { |
736 | struct at86rf230_state_change *ctx = context; |
737 | struct at86rf230_local *lp = ctx->lp; |
738 | |
739 | if (lp->is_tx) { |
740 | lp->is_tx = 0; |
741 | at86rf230_async_read_reg(lp, RG_TRX_STATE, ctx, |
742 | complete: at86rf230_tx_trac_check); |
743 | } else { |
744 | at86rf230_async_read_reg(lp, RG_TRX_STATE, ctx, |
745 | complete: at86rf230_rx_trac_check); |
746 | } |
747 | } |
748 | |
749 | static void |
750 | at86rf230_irq_status(void *context) |
751 | { |
752 | struct at86rf230_state_change *ctx = context; |
753 | struct at86rf230_local *lp = ctx->lp; |
754 | const u8 *buf = ctx->buf; |
755 | u8 irq = buf[1]; |
756 | |
757 | enable_irq(irq: lp->spi->irq); |
758 | |
759 | if (irq & IRQ_TRX_END) { |
760 | at86rf230_irq_trx_end(context: ctx); |
761 | } else { |
762 | dev_err(&lp->spi->dev, "not supported irq %02x received\n" , |
763 | irq); |
764 | kfree(objp: ctx); |
765 | } |
766 | } |
767 | |
768 | static void |
769 | at86rf230_setup_spi_messages(struct at86rf230_local *lp, |
770 | struct at86rf230_state_change *state) |
771 | { |
772 | state->lp = lp; |
773 | state->irq = lp->spi->irq; |
774 | spi_message_init(m: &state->msg); |
775 | state->msg.context = state; |
776 | state->trx.len = 2; |
777 | state->trx.tx_buf = state->buf; |
778 | state->trx.rx_buf = state->buf; |
779 | spi_message_add_tail(t: &state->trx, m: &state->msg); |
780 | hrtimer_init(timer: &state->timer, CLOCK_MONOTONIC, mode: HRTIMER_MODE_REL); |
781 | state->timer.function = at86rf230_async_state_timer; |
782 | } |
783 | |
784 | static irqreturn_t at86rf230_isr(int irq, void *data) |
785 | { |
786 | struct at86rf230_local *lp = data; |
787 | struct at86rf230_state_change *ctx; |
788 | int rc; |
789 | |
790 | disable_irq_nosync(irq); |
791 | |
792 | ctx = kzalloc(size: sizeof(*ctx), GFP_ATOMIC); |
793 | if (!ctx) { |
794 | enable_irq(irq); |
795 | return IRQ_NONE; |
796 | } |
797 | |
798 | at86rf230_setup_spi_messages(lp, state: ctx); |
799 | /* tell on error handling to free ctx */ |
800 | ctx->free = true; |
801 | |
802 | ctx->buf[0] = (RG_IRQ_STATUS & CMD_REG_MASK) | CMD_REG; |
803 | ctx->msg.complete = at86rf230_irq_status; |
804 | rc = spi_async(spi: lp->spi, message: &ctx->msg); |
805 | if (rc) { |
806 | at86rf230_async_error(lp, ctx, rc); |
807 | enable_irq(irq); |
808 | return IRQ_NONE; |
809 | } |
810 | |
811 | return IRQ_HANDLED; |
812 | } |
813 | |
814 | static void |
815 | at86rf230_write_frame_complete(void *context) |
816 | { |
817 | struct at86rf230_state_change *ctx = context; |
818 | struct at86rf230_local *lp = ctx->lp; |
819 | |
820 | ctx->trx.len = 2; |
821 | |
822 | if (lp->slp_tr) |
823 | at86rf230_slp_tr_rising_edge(lp); |
824 | else |
825 | at86rf230_async_write_reg(lp, RG_TRX_STATE, STATE_BUSY_TX, ctx, |
826 | NULL); |
827 | } |
828 | |
829 | static void |
830 | at86rf230_write_frame(void *context) |
831 | { |
832 | struct at86rf230_state_change *ctx = context; |
833 | struct at86rf230_local *lp = ctx->lp; |
834 | struct sk_buff *skb = lp->tx_skb; |
835 | u8 *buf = ctx->buf; |
836 | int rc; |
837 | |
838 | lp->is_tx = 1; |
839 | |
840 | buf[0] = CMD_FB | CMD_WRITE; |
841 | buf[1] = skb->len + 2; |
842 | memcpy(buf + 2, skb->data, skb->len); |
843 | ctx->trx.len = skb->len + 2; |
844 | ctx->msg.complete = at86rf230_write_frame_complete; |
845 | rc = spi_async(spi: lp->spi, message: &ctx->msg); |
846 | if (rc) { |
847 | ctx->trx.len = 2; |
848 | at86rf230_async_error(lp, ctx, rc); |
849 | } |
850 | } |
851 | |
852 | static void |
853 | at86rf230_xmit_tx_on(void *context) |
854 | { |
855 | struct at86rf230_state_change *ctx = context; |
856 | struct at86rf230_local *lp = ctx->lp; |
857 | |
858 | at86rf230_async_state_change(lp, ctx, STATE_TX_ARET_ON, |
859 | complete: at86rf230_write_frame); |
860 | } |
861 | |
862 | static void |
863 | at86rf230_xmit_start(void *context) |
864 | { |
865 | struct at86rf230_state_change *ctx = context; |
866 | struct at86rf230_local *lp = ctx->lp; |
867 | |
868 | /* check if we change from off state */ |
869 | if (lp->is_tx_from_off) |
870 | at86rf230_async_state_change(lp, ctx, STATE_TX_ARET_ON, |
871 | complete: at86rf230_write_frame); |
872 | else |
873 | at86rf230_async_state_change(lp, ctx, STATE_TX_ON, |
874 | complete: at86rf230_xmit_tx_on); |
875 | } |
876 | |
877 | static int |
878 | at86rf230_xmit(struct ieee802154_hw *hw, struct sk_buff *skb) |
879 | { |
880 | struct at86rf230_local *lp = hw->priv; |
881 | struct at86rf230_state_change *ctx = &lp->tx; |
882 | |
883 | lp->tx_skb = skb; |
884 | lp->tx_retry = 0; |
885 | |
886 | /* After 5 minutes in PLL and the same frequency we run again the |
887 | * calibration loops which is recommended by at86rf2xx datasheets. |
888 | * |
889 | * The calibration is initiate by a state change from TRX_OFF |
890 | * to TX_ON, the lp->cal_timeout should be reinit by state_delay |
891 | * function then to start in the next 5 minutes. |
892 | */ |
893 | if (time_is_before_jiffies(lp->cal_timeout)) { |
894 | lp->is_tx_from_off = true; |
895 | at86rf230_async_state_change(lp, ctx, STATE_TRX_OFF, |
896 | complete: at86rf230_xmit_start); |
897 | } else { |
898 | lp->is_tx_from_off = false; |
899 | at86rf230_xmit_start(context: ctx); |
900 | } |
901 | |
902 | return 0; |
903 | } |
904 | |
905 | static int |
906 | at86rf230_ed(struct ieee802154_hw *hw, u8 *level) |
907 | { |
908 | WARN_ON(!level); |
909 | *level = 0xbe; |
910 | return 0; |
911 | } |
912 | |
913 | static int |
914 | at86rf230_start(struct ieee802154_hw *hw) |
915 | { |
916 | struct at86rf230_local *lp = hw->priv; |
917 | |
918 | at86rf230_awake(lp); |
919 | enable_irq(irq: lp->spi->irq); |
920 | |
921 | return at86rf230_sync_state_change(lp, STATE_RX_AACK_ON); |
922 | } |
923 | |
924 | static void |
925 | at86rf230_stop(struct ieee802154_hw *hw) |
926 | { |
927 | struct at86rf230_local *lp = hw->priv; |
928 | u8 csma_seed[2]; |
929 | |
930 | at86rf230_sync_state_change(lp, STATE_FORCE_TRX_OFF); |
931 | |
932 | disable_irq(irq: lp->spi->irq); |
933 | |
934 | /* It's recommended to set random new csma_seeds before sleep state. |
935 | * Makes only sense in the stop callback, not doing this inside of |
936 | * at86rf230_sleep, this is also used when we don't transmit afterwards |
937 | * when calling start callback again. |
938 | */ |
939 | get_random_bytes(buf: csma_seed, ARRAY_SIZE(csma_seed)); |
940 | at86rf230_write_subreg(lp, SR_CSMA_SEED_0, data: csma_seed[0]); |
941 | at86rf230_write_subreg(lp, SR_CSMA_SEED_1, data: csma_seed[1]); |
942 | |
943 | at86rf230_sleep(lp); |
944 | } |
945 | |
946 | static int |
947 | at86rf23x_set_channel(struct at86rf230_local *lp, u8 page, u8 channel) |
948 | { |
949 | return at86rf230_write_subreg(lp, SR_CHANNEL, data: channel); |
950 | } |
951 | |
952 | #define AT86RF2XX_MAX_ED_LEVELS 0xF |
953 | static const s32 at86rf233_ed_levels[AT86RF2XX_MAX_ED_LEVELS + 1] = { |
954 | -9400, -9200, -9000, -8800, -8600, -8400, -8200, -8000, -7800, -7600, |
955 | -7400, -7200, -7000, -6800, -6600, -6400, |
956 | }; |
957 | |
958 | static const s32 at86rf231_ed_levels[AT86RF2XX_MAX_ED_LEVELS + 1] = { |
959 | -9100, -8900, -8700, -8500, -8300, -8100, -7900, -7700, -7500, -7300, |
960 | -7100, -6900, -6700, -6500, -6300, -6100, |
961 | }; |
962 | |
963 | static const s32 at86rf212_ed_levels_100[AT86RF2XX_MAX_ED_LEVELS + 1] = { |
964 | -10000, -9800, -9600, -9400, -9200, -9000, -8800, -8600, -8400, -8200, |
965 | -8000, -7800, -7600, -7400, -7200, -7000, |
966 | }; |
967 | |
968 | static const s32 at86rf212_ed_levels_98[AT86RF2XX_MAX_ED_LEVELS + 1] = { |
969 | -9800, -9600, -9400, -9200, -9000, -8800, -8600, -8400, -8200, -8000, |
970 | -7800, -7600, -7400, -7200, -7000, -6800, |
971 | }; |
972 | |
973 | static inline int |
974 | at86rf212_update_cca_ed_level(struct at86rf230_local *lp, int ) |
975 | { |
976 | unsigned int cca_ed_thres; |
977 | int rc; |
978 | |
979 | rc = at86rf230_read_subreg(lp, SR_CCA_ED_THRES, data: &cca_ed_thres); |
980 | if (rc < 0) |
981 | return rc; |
982 | |
983 | switch (rssi_base_val) { |
984 | case -98: |
985 | lp->hw->phy->supported.cca_ed_levels = at86rf212_ed_levels_98; |
986 | lp->hw->phy->supported.cca_ed_levels_size = ARRAY_SIZE(at86rf212_ed_levels_98); |
987 | lp->hw->phy->cca_ed_level = at86rf212_ed_levels_98[cca_ed_thres]; |
988 | break; |
989 | case -100: |
990 | lp->hw->phy->supported.cca_ed_levels = at86rf212_ed_levels_100; |
991 | lp->hw->phy->supported.cca_ed_levels_size = ARRAY_SIZE(at86rf212_ed_levels_100); |
992 | lp->hw->phy->cca_ed_level = at86rf212_ed_levels_100[cca_ed_thres]; |
993 | break; |
994 | default: |
995 | WARN_ON(1); |
996 | } |
997 | |
998 | return 0; |
999 | } |
1000 | |
1001 | static int |
1002 | at86rf212_set_channel(struct at86rf230_local *lp, u8 page, u8 channel) |
1003 | { |
1004 | int rc; |
1005 | |
1006 | if (channel == 0) |
1007 | rc = at86rf230_write_subreg(lp, SR_SUB_MODE, data: 0); |
1008 | else |
1009 | rc = at86rf230_write_subreg(lp, SR_SUB_MODE, data: 1); |
1010 | if (rc < 0) |
1011 | return rc; |
1012 | |
1013 | if (page == 0) { |
1014 | rc = at86rf230_write_subreg(lp, SR_BPSK_QPSK, data: 0); |
1015 | lp->data->rssi_base_val = -100; |
1016 | } else { |
1017 | rc = at86rf230_write_subreg(lp, SR_BPSK_QPSK, data: 1); |
1018 | lp->data->rssi_base_val = -98; |
1019 | } |
1020 | if (rc < 0) |
1021 | return rc; |
1022 | |
1023 | rc = at86rf212_update_cca_ed_level(lp, rssi_base_val: lp->data->rssi_base_val); |
1024 | if (rc < 0) |
1025 | return rc; |
1026 | |
1027 | return at86rf230_write_subreg(lp, SR_CHANNEL, data: channel); |
1028 | } |
1029 | |
1030 | static int |
1031 | at86rf230_channel(struct ieee802154_hw *hw, u8 page, u8 channel) |
1032 | { |
1033 | struct at86rf230_local *lp = hw->priv; |
1034 | int rc; |
1035 | |
1036 | rc = lp->data->set_channel(lp, page, channel); |
1037 | /* Wait for PLL */ |
1038 | usleep_range(min: lp->data->t_channel_switch, |
1039 | max: lp->data->t_channel_switch + 10); |
1040 | |
1041 | lp->cal_timeout = jiffies + AT86RF2XX_CAL_LOOP_TIMEOUT; |
1042 | return rc; |
1043 | } |
1044 | |
1045 | static int |
1046 | at86rf230_set_hw_addr_filt(struct ieee802154_hw *hw, |
1047 | struct ieee802154_hw_addr_filt *filt, |
1048 | unsigned long changed) |
1049 | { |
1050 | struct at86rf230_local *lp = hw->priv; |
1051 | |
1052 | if (changed & IEEE802154_AFILT_SADDR_CHANGED) { |
1053 | u16 addr = le16_to_cpu(filt->short_addr); |
1054 | |
1055 | dev_vdbg(&lp->spi->dev, "%s called for saddr\n" , __func__); |
1056 | __at86rf230_write(lp, RG_SHORT_ADDR_0, data: addr); |
1057 | __at86rf230_write(lp, RG_SHORT_ADDR_1, data: addr >> 8); |
1058 | } |
1059 | |
1060 | if (changed & IEEE802154_AFILT_PANID_CHANGED) { |
1061 | u16 pan = le16_to_cpu(filt->pan_id); |
1062 | |
1063 | dev_vdbg(&lp->spi->dev, "%s called for pan id\n" , __func__); |
1064 | __at86rf230_write(lp, RG_PAN_ID_0, data: pan); |
1065 | __at86rf230_write(lp, RG_PAN_ID_1, data: pan >> 8); |
1066 | } |
1067 | |
1068 | if (changed & IEEE802154_AFILT_IEEEADDR_CHANGED) { |
1069 | u8 i, addr[8]; |
1070 | |
1071 | memcpy(addr, &filt->ieee_addr, 8); |
1072 | dev_vdbg(&lp->spi->dev, "%s called for IEEE addr\n" , __func__); |
1073 | for (i = 0; i < 8; i++) |
1074 | __at86rf230_write(lp, RG_IEEE_ADDR_0 + i, data: addr[i]); |
1075 | } |
1076 | |
1077 | if (changed & IEEE802154_AFILT_PANC_CHANGED) { |
1078 | dev_vdbg(&lp->spi->dev, "%s called for panc change\n" , __func__); |
1079 | if (filt->pan_coord) |
1080 | at86rf230_write_subreg(lp, SR_AACK_I_AM_COORD, data: 1); |
1081 | else |
1082 | at86rf230_write_subreg(lp, SR_AACK_I_AM_COORD, data: 0); |
1083 | } |
1084 | |
1085 | return 0; |
1086 | } |
1087 | |
1088 | #define AT86RF23X_MAX_TX_POWERS 0xF |
1089 | static const s32 at86rf233_powers[AT86RF23X_MAX_TX_POWERS + 1] = { |
1090 | 400, 370, 340, 300, 250, 200, 100, 0, -100, -200, -300, -400, -600, |
1091 | -800, -1200, -1700, |
1092 | }; |
1093 | |
1094 | static const s32 at86rf231_powers[AT86RF23X_MAX_TX_POWERS + 1] = { |
1095 | 300, 280, 230, 180, 130, 70, 0, -100, -200, -300, -400, -500, -700, |
1096 | -900, -1200, -1700, |
1097 | }; |
1098 | |
1099 | #define AT86RF212_MAX_TX_POWERS 0x1F |
1100 | static const s32 at86rf212_powers[AT86RF212_MAX_TX_POWERS + 1] = { |
1101 | 500, 400, 300, 200, 100, 0, -100, -200, -300, -400, -500, -600, -700, |
1102 | -800, -900, -1000, -1100, -1200, -1300, -1400, -1500, -1600, -1700, |
1103 | -1800, -1900, -2000, -2100, -2200, -2300, -2400, -2500, -2600, |
1104 | }; |
1105 | |
1106 | static int |
1107 | at86rf23x_set_txpower(struct at86rf230_local *lp, s32 mbm) |
1108 | { |
1109 | u32 i; |
1110 | |
1111 | for (i = 0; i < lp->hw->phy->supported.tx_powers_size; i++) { |
1112 | if (lp->hw->phy->supported.tx_powers[i] == mbm) |
1113 | return at86rf230_write_subreg(lp, SR_TX_PWR_23X, data: i); |
1114 | } |
1115 | |
1116 | return -EINVAL; |
1117 | } |
1118 | |
1119 | static int |
1120 | at86rf212_set_txpower(struct at86rf230_local *lp, s32 mbm) |
1121 | { |
1122 | u32 i; |
1123 | |
1124 | for (i = 0; i < lp->hw->phy->supported.tx_powers_size; i++) { |
1125 | if (lp->hw->phy->supported.tx_powers[i] == mbm) |
1126 | return at86rf230_write_subreg(lp, SR_TX_PWR_212, data: i); |
1127 | } |
1128 | |
1129 | return -EINVAL; |
1130 | } |
1131 | |
1132 | static int |
1133 | at86rf230_set_txpower(struct ieee802154_hw *hw, s32 mbm) |
1134 | { |
1135 | struct at86rf230_local *lp = hw->priv; |
1136 | |
1137 | return lp->data->set_txpower(lp, mbm); |
1138 | } |
1139 | |
1140 | static int |
1141 | at86rf230_set_lbt(struct ieee802154_hw *hw, bool on) |
1142 | { |
1143 | struct at86rf230_local *lp = hw->priv; |
1144 | |
1145 | return at86rf230_write_subreg(lp, SR_CSMA_LBT_MODE, data: on); |
1146 | } |
1147 | |
1148 | static int |
1149 | at86rf230_set_cca_mode(struct ieee802154_hw *hw, |
1150 | const struct wpan_phy_cca *cca) |
1151 | { |
1152 | struct at86rf230_local *lp = hw->priv; |
1153 | u8 val; |
1154 | |
1155 | /* mapping 802.15.4 to driver spec */ |
1156 | switch (cca->mode) { |
1157 | case NL802154_CCA_ENERGY: |
1158 | val = 1; |
1159 | break; |
1160 | case NL802154_CCA_CARRIER: |
1161 | val = 2; |
1162 | break; |
1163 | case NL802154_CCA_ENERGY_CARRIER: |
1164 | switch (cca->opt) { |
1165 | case NL802154_CCA_OPT_ENERGY_CARRIER_AND: |
1166 | val = 3; |
1167 | break; |
1168 | case NL802154_CCA_OPT_ENERGY_CARRIER_OR: |
1169 | val = 0; |
1170 | break; |
1171 | default: |
1172 | return -EINVAL; |
1173 | } |
1174 | break; |
1175 | default: |
1176 | return -EINVAL; |
1177 | } |
1178 | |
1179 | return at86rf230_write_subreg(lp, SR_CCA_MODE, data: val); |
1180 | } |
1181 | |
1182 | static int |
1183 | at86rf230_set_cca_ed_level(struct ieee802154_hw *hw, s32 mbm) |
1184 | { |
1185 | struct at86rf230_local *lp = hw->priv; |
1186 | u32 i; |
1187 | |
1188 | for (i = 0; i < hw->phy->supported.cca_ed_levels_size; i++) { |
1189 | if (hw->phy->supported.cca_ed_levels[i] == mbm) |
1190 | return at86rf230_write_subreg(lp, SR_CCA_ED_THRES, data: i); |
1191 | } |
1192 | |
1193 | return -EINVAL; |
1194 | } |
1195 | |
1196 | static int |
1197 | at86rf230_set_csma_params(struct ieee802154_hw *hw, u8 min_be, u8 max_be, |
1198 | u8 retries) |
1199 | { |
1200 | struct at86rf230_local *lp = hw->priv; |
1201 | int rc; |
1202 | |
1203 | rc = at86rf230_write_subreg(lp, SR_MIN_BE, data: min_be); |
1204 | if (rc) |
1205 | return rc; |
1206 | |
1207 | rc = at86rf230_write_subreg(lp, SR_MAX_BE, data: max_be); |
1208 | if (rc) |
1209 | return rc; |
1210 | |
1211 | return at86rf230_write_subreg(lp, SR_MAX_CSMA_RETRIES, data: retries); |
1212 | } |
1213 | |
1214 | static int |
1215 | at86rf230_set_frame_retries(struct ieee802154_hw *hw, s8 retries) |
1216 | { |
1217 | struct at86rf230_local *lp = hw->priv; |
1218 | |
1219 | return at86rf230_write_subreg(lp, SR_MAX_FRAME_RETRIES, data: retries); |
1220 | } |
1221 | |
1222 | static int |
1223 | at86rf230_set_promiscuous_mode(struct ieee802154_hw *hw, const bool on) |
1224 | { |
1225 | struct at86rf230_local *lp = hw->priv; |
1226 | int rc; |
1227 | |
1228 | if (on) { |
1229 | rc = at86rf230_write_subreg(lp, SR_AACK_DIS_ACK, data: 1); |
1230 | if (rc < 0) |
1231 | return rc; |
1232 | |
1233 | rc = at86rf230_write_subreg(lp, SR_AACK_PROM_MODE, data: 1); |
1234 | if (rc < 0) |
1235 | return rc; |
1236 | } else { |
1237 | rc = at86rf230_write_subreg(lp, SR_AACK_PROM_MODE, data: 0); |
1238 | if (rc < 0) |
1239 | return rc; |
1240 | |
1241 | rc = at86rf230_write_subreg(lp, SR_AACK_DIS_ACK, data: 0); |
1242 | if (rc < 0) |
1243 | return rc; |
1244 | } |
1245 | |
1246 | return 0; |
1247 | } |
1248 | |
1249 | static const struct ieee802154_ops at86rf230_ops = { |
1250 | .owner = THIS_MODULE, |
1251 | .xmit_async = at86rf230_xmit, |
1252 | .ed = at86rf230_ed, |
1253 | .set_channel = at86rf230_channel, |
1254 | .start = at86rf230_start, |
1255 | .stop = at86rf230_stop, |
1256 | .set_hw_addr_filt = at86rf230_set_hw_addr_filt, |
1257 | .set_txpower = at86rf230_set_txpower, |
1258 | .set_lbt = at86rf230_set_lbt, |
1259 | .set_cca_mode = at86rf230_set_cca_mode, |
1260 | .set_cca_ed_level = at86rf230_set_cca_ed_level, |
1261 | .set_csma_params = at86rf230_set_csma_params, |
1262 | .set_frame_retries = at86rf230_set_frame_retries, |
1263 | .set_promiscuous_mode = at86rf230_set_promiscuous_mode, |
1264 | }; |
1265 | |
1266 | static struct at86rf2xx_chip_data at86rf233_data = { |
1267 | .t_sleep_cycle = 330, |
1268 | .t_channel_switch = 11, |
1269 | .t_reset_to_off = 26, |
1270 | .t_off_to_aack = 80, |
1271 | .t_off_to_tx_on = 80, |
1272 | .t_off_to_sleep = 35, |
1273 | .t_sleep_to_off = 1000, |
1274 | .t_frame = 4096, |
1275 | .t_p_ack = 545, |
1276 | .rssi_base_val = -94, |
1277 | .set_channel = at86rf23x_set_channel, |
1278 | .set_txpower = at86rf23x_set_txpower, |
1279 | }; |
1280 | |
1281 | static struct at86rf2xx_chip_data at86rf231_data = { |
1282 | .t_sleep_cycle = 330, |
1283 | .t_channel_switch = 24, |
1284 | .t_reset_to_off = 37, |
1285 | .t_off_to_aack = 110, |
1286 | .t_off_to_tx_on = 110, |
1287 | .t_off_to_sleep = 35, |
1288 | .t_sleep_to_off = 1000, |
1289 | .t_frame = 4096, |
1290 | .t_p_ack = 545, |
1291 | .rssi_base_val = -91, |
1292 | .set_channel = at86rf23x_set_channel, |
1293 | .set_txpower = at86rf23x_set_txpower, |
1294 | }; |
1295 | |
1296 | static struct at86rf2xx_chip_data at86rf212_data = { |
1297 | .t_sleep_cycle = 330, |
1298 | .t_channel_switch = 11, |
1299 | .t_reset_to_off = 26, |
1300 | .t_off_to_aack = 200, |
1301 | .t_off_to_tx_on = 200, |
1302 | .t_off_to_sleep = 35, |
1303 | .t_sleep_to_off = 1000, |
1304 | .t_frame = 4096, |
1305 | .t_p_ack = 545, |
1306 | .rssi_base_val = -100, |
1307 | .set_channel = at86rf212_set_channel, |
1308 | .set_txpower = at86rf212_set_txpower, |
1309 | }; |
1310 | |
1311 | static int at86rf230_hw_init(struct at86rf230_local *lp, u8 xtal_trim) |
1312 | { |
1313 | int rc, irq_type, irq_pol = IRQ_ACTIVE_HIGH; |
1314 | unsigned int dvdd; |
1315 | u8 csma_seed[2]; |
1316 | |
1317 | rc = at86rf230_sync_state_change(lp, STATE_FORCE_TRX_OFF); |
1318 | if (rc) |
1319 | return rc; |
1320 | |
1321 | irq_type = irq_get_trigger_type(irq: lp->spi->irq); |
1322 | if (irq_type == IRQ_TYPE_EDGE_FALLING || |
1323 | irq_type == IRQ_TYPE_LEVEL_LOW) |
1324 | irq_pol = IRQ_ACTIVE_LOW; |
1325 | |
1326 | rc = at86rf230_write_subreg(lp, SR_IRQ_POLARITY, data: irq_pol); |
1327 | if (rc) |
1328 | return rc; |
1329 | |
1330 | rc = at86rf230_write_subreg(lp, SR_RX_SAFE_MODE, data: 1); |
1331 | if (rc) |
1332 | return rc; |
1333 | |
1334 | rc = at86rf230_write_subreg(lp, SR_IRQ_MASK, IRQ_TRX_END); |
1335 | if (rc) |
1336 | return rc; |
1337 | |
1338 | /* reset values differs in at86rf231 and at86rf233 */ |
1339 | rc = at86rf230_write_subreg(lp, SR_IRQ_MASK_MODE, data: 0); |
1340 | if (rc) |
1341 | return rc; |
1342 | |
1343 | get_random_bytes(buf: csma_seed, ARRAY_SIZE(csma_seed)); |
1344 | rc = at86rf230_write_subreg(lp, SR_CSMA_SEED_0, data: csma_seed[0]); |
1345 | if (rc) |
1346 | return rc; |
1347 | rc = at86rf230_write_subreg(lp, SR_CSMA_SEED_1, data: csma_seed[1]); |
1348 | if (rc) |
1349 | return rc; |
1350 | |
1351 | /* CLKM changes are applied immediately */ |
1352 | rc = at86rf230_write_subreg(lp, SR_CLKM_SHA_SEL, data: 0x00); |
1353 | if (rc) |
1354 | return rc; |
1355 | |
1356 | /* Turn CLKM Off */ |
1357 | rc = at86rf230_write_subreg(lp, SR_CLKM_CTRL, data: 0x00); |
1358 | if (rc) |
1359 | return rc; |
1360 | /* Wait the next SLEEP cycle */ |
1361 | usleep_range(min: lp->data->t_sleep_cycle, |
1362 | max: lp->data->t_sleep_cycle + 100); |
1363 | |
1364 | /* xtal_trim value is calculated by: |
1365 | * CL = 0.5 * (CX + CTRIM + CPAR) |
1366 | * |
1367 | * whereas: |
1368 | * CL = capacitor of used crystal |
1369 | * CX = connected capacitors at xtal pins |
1370 | * CPAR = in all at86rf2xx datasheets this is a constant value 3 pF, |
1371 | * but this is different on each board setup. You need to fine |
1372 | * tuning this value via CTRIM. |
1373 | * CTRIM = variable capacitor setting. Resolution is 0.3 pF range is |
1374 | * 0 pF upto 4.5 pF. |
1375 | * |
1376 | * Examples: |
1377 | * atben transceiver: |
1378 | * |
1379 | * CL = 8 pF |
1380 | * CX = 12 pF |
1381 | * CPAR = 3 pF (We assume the magic constant from datasheet) |
1382 | * CTRIM = 0.9 pF |
1383 | * |
1384 | * (12+0.9+3)/2 = 7.95 which is nearly at 8 pF |
1385 | * |
1386 | * xtal_trim = 0x3 |
1387 | * |
1388 | * openlabs transceiver: |
1389 | * |
1390 | * CL = 16 pF |
1391 | * CX = 22 pF |
1392 | * CPAR = 3 pF (We assume the magic constant from datasheet) |
1393 | * CTRIM = 4.5 pF |
1394 | * |
1395 | * (22+4.5+3)/2 = 14.75 which is the nearest value to 16 pF |
1396 | * |
1397 | * xtal_trim = 0xf |
1398 | */ |
1399 | rc = at86rf230_write_subreg(lp, SR_XTAL_TRIM, data: xtal_trim); |
1400 | if (rc) |
1401 | return rc; |
1402 | |
1403 | rc = at86rf230_read_subreg(lp, SR_DVDD_OK, data: &dvdd); |
1404 | if (rc) |
1405 | return rc; |
1406 | if (!dvdd) { |
1407 | dev_err(&lp->spi->dev, "DVDD error\n" ); |
1408 | return -EINVAL; |
1409 | } |
1410 | |
1411 | /* Force setting slotted operation bit to 0. Sometimes the atben |
1412 | * sets this bit and I don't know why. We set this always force |
1413 | * to zero while probing. |
1414 | */ |
1415 | return at86rf230_write_subreg(lp, SR_SLOTTED_OPERATION, data: 0); |
1416 | } |
1417 | |
1418 | static int |
1419 | at86rf230_detect_device(struct at86rf230_local *lp) |
1420 | { |
1421 | unsigned int part, version, val; |
1422 | u16 man_id = 0; |
1423 | const char *chip; |
1424 | int rc; |
1425 | |
1426 | rc = __at86rf230_read(lp, RG_MAN_ID_0, data: &val); |
1427 | if (rc) |
1428 | return rc; |
1429 | man_id |= val; |
1430 | |
1431 | rc = __at86rf230_read(lp, RG_MAN_ID_1, data: &val); |
1432 | if (rc) |
1433 | return rc; |
1434 | man_id |= (val << 8); |
1435 | |
1436 | rc = __at86rf230_read(lp, RG_PART_NUM, data: &part); |
1437 | if (rc) |
1438 | return rc; |
1439 | |
1440 | rc = __at86rf230_read(lp, RG_VERSION_NUM, data: &version); |
1441 | if (rc) |
1442 | return rc; |
1443 | |
1444 | if (man_id != 0x001f) { |
1445 | dev_err(&lp->spi->dev, "Non-Atmel dev found (MAN_ID %02x %02x)\n" , |
1446 | man_id >> 8, man_id & 0xFF); |
1447 | return -EINVAL; |
1448 | } |
1449 | |
1450 | lp->hw->flags = IEEE802154_HW_TX_OMIT_CKSUM | |
1451 | IEEE802154_HW_CSMA_PARAMS | |
1452 | IEEE802154_HW_FRAME_RETRIES | IEEE802154_HW_AFILT | |
1453 | IEEE802154_HW_PROMISCUOUS; |
1454 | |
1455 | lp->hw->phy->flags = WPAN_PHY_FLAG_TXPOWER | |
1456 | WPAN_PHY_FLAG_CCA_ED_LEVEL | |
1457 | WPAN_PHY_FLAG_CCA_MODE; |
1458 | |
1459 | lp->hw->phy->supported.cca_modes = BIT(NL802154_CCA_ENERGY) | |
1460 | BIT(NL802154_CCA_CARRIER) | BIT(NL802154_CCA_ENERGY_CARRIER); |
1461 | lp->hw->phy->supported.cca_opts = BIT(NL802154_CCA_OPT_ENERGY_CARRIER_AND) | |
1462 | BIT(NL802154_CCA_OPT_ENERGY_CARRIER_OR); |
1463 | |
1464 | lp->hw->phy->cca.mode = NL802154_CCA_ENERGY; |
1465 | |
1466 | switch (part) { |
1467 | case 2: |
1468 | chip = "at86rf230" ; |
1469 | rc = -ENOTSUPP; |
1470 | goto not_supp; |
1471 | case 3: |
1472 | chip = "at86rf231" ; |
1473 | lp->data = &at86rf231_data; |
1474 | lp->hw->phy->supported.channels[0] = 0x7FFF800; |
1475 | lp->hw->phy->current_channel = 11; |
1476 | lp->hw->phy->supported.tx_powers = at86rf231_powers; |
1477 | lp->hw->phy->supported.tx_powers_size = ARRAY_SIZE(at86rf231_powers); |
1478 | lp->hw->phy->supported.cca_ed_levels = at86rf231_ed_levels; |
1479 | lp->hw->phy->supported.cca_ed_levels_size = ARRAY_SIZE(at86rf231_ed_levels); |
1480 | break; |
1481 | case 7: |
1482 | chip = "at86rf212" ; |
1483 | lp->data = &at86rf212_data; |
1484 | lp->hw->flags |= IEEE802154_HW_LBT; |
1485 | lp->hw->phy->supported.channels[0] = 0x00007FF; |
1486 | lp->hw->phy->supported.channels[2] = 0x00007FF; |
1487 | lp->hw->phy->current_channel = 5; |
1488 | lp->hw->phy->supported.lbt = NL802154_SUPPORTED_BOOL_BOTH; |
1489 | lp->hw->phy->supported.tx_powers = at86rf212_powers; |
1490 | lp->hw->phy->supported.tx_powers_size = ARRAY_SIZE(at86rf212_powers); |
1491 | lp->hw->phy->supported.cca_ed_levels = at86rf212_ed_levels_100; |
1492 | lp->hw->phy->supported.cca_ed_levels_size = ARRAY_SIZE(at86rf212_ed_levels_100); |
1493 | break; |
1494 | case 11: |
1495 | chip = "at86rf233" ; |
1496 | lp->data = &at86rf233_data; |
1497 | lp->hw->phy->supported.channels[0] = 0x7FFF800; |
1498 | lp->hw->phy->current_channel = 13; |
1499 | lp->hw->phy->supported.tx_powers = at86rf233_powers; |
1500 | lp->hw->phy->supported.tx_powers_size = ARRAY_SIZE(at86rf233_powers); |
1501 | lp->hw->phy->supported.cca_ed_levels = at86rf233_ed_levels; |
1502 | lp->hw->phy->supported.cca_ed_levels_size = ARRAY_SIZE(at86rf233_ed_levels); |
1503 | break; |
1504 | default: |
1505 | chip = "unknown" ; |
1506 | rc = -ENOTSUPP; |
1507 | goto not_supp; |
1508 | } |
1509 | |
1510 | lp->hw->phy->cca_ed_level = lp->hw->phy->supported.cca_ed_levels[7]; |
1511 | lp->hw->phy->transmit_power = lp->hw->phy->supported.tx_powers[0]; |
1512 | |
1513 | not_supp: |
1514 | dev_info(&lp->spi->dev, "Detected %s chip version %d\n" , chip, version); |
1515 | |
1516 | return rc; |
1517 | } |
1518 | |
1519 | static int at86rf230_probe(struct spi_device *spi) |
1520 | { |
1521 | struct ieee802154_hw *hw; |
1522 | struct at86rf230_local *lp; |
1523 | struct gpio_desc *slp_tr; |
1524 | struct gpio_desc *rstn; |
1525 | unsigned int status; |
1526 | int rc, irq_type; |
1527 | u8 xtal_trim; |
1528 | |
1529 | if (!spi->irq) { |
1530 | dev_err(&spi->dev, "no IRQ specified\n" ); |
1531 | return -EINVAL; |
1532 | } |
1533 | |
1534 | rc = device_property_read_u8(dev: &spi->dev, propname: "xtal-trim" , val: &xtal_trim); |
1535 | if (rc < 0) { |
1536 | if (rc != -EINVAL) { |
1537 | dev_err(&spi->dev, |
1538 | "failed to parse xtal-trim: %d\n" , rc); |
1539 | return rc; |
1540 | } |
1541 | xtal_trim = 0; |
1542 | } |
1543 | |
1544 | rstn = devm_gpiod_get_optional(dev: &spi->dev, con_id: "reset" , flags: GPIOD_OUT_LOW); |
1545 | rc = PTR_ERR_OR_ZERO(ptr: rstn); |
1546 | if (rc) |
1547 | return rc; |
1548 | |
1549 | gpiod_set_consumer_name(desc: rstn, name: "rstn" ); |
1550 | |
1551 | slp_tr = devm_gpiod_get_optional(dev: &spi->dev, con_id: "sleep" , flags: GPIOD_OUT_LOW); |
1552 | rc = PTR_ERR_OR_ZERO(ptr: slp_tr); |
1553 | if (rc) |
1554 | return rc; |
1555 | |
1556 | gpiod_set_consumer_name(desc: slp_tr, name: "slp_tr" ); |
1557 | |
1558 | /* Reset */ |
1559 | if (rstn) { |
1560 | udelay(1); |
1561 | gpiod_set_value_cansleep(desc: rstn, value: 1); |
1562 | udelay(1); |
1563 | gpiod_set_value_cansleep(desc: rstn, value: 0); |
1564 | usleep_range(min: 120, max: 240); |
1565 | } |
1566 | |
1567 | hw = ieee802154_alloc_hw(priv_data_len: sizeof(*lp), ops: &at86rf230_ops); |
1568 | if (!hw) |
1569 | return -ENOMEM; |
1570 | |
1571 | lp = hw->priv; |
1572 | lp->hw = hw; |
1573 | lp->spi = spi; |
1574 | lp->slp_tr = slp_tr; |
1575 | hw->parent = &spi->dev; |
1576 | ieee802154_random_extended_addr(addr: &hw->phy->perm_extended_addr); |
1577 | |
1578 | lp->regmap = devm_regmap_init_spi(spi, &at86rf230_regmap_spi_config); |
1579 | if (IS_ERR(ptr: lp->regmap)) { |
1580 | rc = PTR_ERR(ptr: lp->regmap); |
1581 | dev_err(&spi->dev, "Failed to allocate register map: %d\n" , |
1582 | rc); |
1583 | goto free_dev; |
1584 | } |
1585 | |
1586 | at86rf230_setup_spi_messages(lp, state: &lp->state); |
1587 | at86rf230_setup_spi_messages(lp, state: &lp->tx); |
1588 | |
1589 | rc = at86rf230_detect_device(lp); |
1590 | if (rc < 0) |
1591 | goto free_dev; |
1592 | |
1593 | init_completion(x: &lp->state_complete); |
1594 | |
1595 | spi_set_drvdata(spi, data: lp); |
1596 | |
1597 | rc = at86rf230_hw_init(lp, xtal_trim); |
1598 | if (rc) |
1599 | goto free_dev; |
1600 | |
1601 | /* Read irq status register to reset irq line */ |
1602 | rc = at86rf230_read_subreg(lp, RG_IRQ_STATUS, mask: 0xff, shift: 0, data: &status); |
1603 | if (rc) |
1604 | goto free_dev; |
1605 | |
1606 | irq_type = irq_get_trigger_type(irq: spi->irq); |
1607 | if (!irq_type) |
1608 | irq_type = IRQF_TRIGGER_HIGH; |
1609 | |
1610 | rc = devm_request_irq(dev: &spi->dev, irq: spi->irq, handler: at86rf230_isr, |
1611 | IRQF_SHARED | irq_type, devname: dev_name(dev: &spi->dev), dev_id: lp); |
1612 | if (rc) |
1613 | goto free_dev; |
1614 | |
1615 | /* disable_irq by default and wait for starting hardware */ |
1616 | disable_irq(irq: spi->irq); |
1617 | |
1618 | /* going into sleep by default */ |
1619 | at86rf230_sleep(lp); |
1620 | |
1621 | rc = ieee802154_register_hw(hw: lp->hw); |
1622 | if (rc) |
1623 | goto free_dev; |
1624 | |
1625 | return rc; |
1626 | |
1627 | free_dev: |
1628 | ieee802154_free_hw(hw: lp->hw); |
1629 | |
1630 | return rc; |
1631 | } |
1632 | |
1633 | static void at86rf230_remove(struct spi_device *spi) |
1634 | { |
1635 | struct at86rf230_local *lp = spi_get_drvdata(spi); |
1636 | |
1637 | /* mask all at86rf230 irq's */ |
1638 | at86rf230_write_subreg(lp, SR_IRQ_MASK, data: 0); |
1639 | ieee802154_unregister_hw(hw: lp->hw); |
1640 | ieee802154_free_hw(hw: lp->hw); |
1641 | dev_dbg(&spi->dev, "unregistered at86rf230\n" ); |
1642 | } |
1643 | |
1644 | static const struct of_device_id at86rf230_of_match[] = { |
1645 | { .compatible = "atmel,at86rf230" , }, |
1646 | { .compatible = "atmel,at86rf231" , }, |
1647 | { .compatible = "atmel,at86rf233" , }, |
1648 | { .compatible = "atmel,at86rf212" , }, |
1649 | { }, |
1650 | }; |
1651 | MODULE_DEVICE_TABLE(of, at86rf230_of_match); |
1652 | |
1653 | static const struct spi_device_id at86rf230_device_id[] = { |
1654 | { .name = "at86rf230" , }, |
1655 | { .name = "at86rf231" , }, |
1656 | { .name = "at86rf233" , }, |
1657 | { .name = "at86rf212" , }, |
1658 | { }, |
1659 | }; |
1660 | MODULE_DEVICE_TABLE(spi, at86rf230_device_id); |
1661 | |
1662 | static struct spi_driver at86rf230_driver = { |
1663 | .id_table = at86rf230_device_id, |
1664 | .driver = { |
1665 | .of_match_table = at86rf230_of_match, |
1666 | .name = "at86rf230" , |
1667 | }, |
1668 | .probe = at86rf230_probe, |
1669 | .remove = at86rf230_remove, |
1670 | }; |
1671 | |
1672 | module_spi_driver(at86rf230_driver); |
1673 | |
1674 | MODULE_DESCRIPTION("AT86RF230 Transceiver Driver" ); |
1675 | MODULE_LICENSE("GPL v2" ); |
1676 | |