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