20
20
#include <linux/kernel.h>
21
21
#include <linux/module.h>
22
22
#include <linux/hrtimer.h>
23
+ #include <linux/jiffies.h>
23
24
#include <linux/interrupt.h>
24
25
#include <linux/irq.h>
25
26
#include <linux/gpio.h>
@@ -60,6 +61,8 @@ struct at86rf2xx_chip_data {
60
61
* We assume the max_frame_retries (7) value of 802.15.4 here.
61
62
*/
62
63
#define AT86RF2XX_MAX_TX_RETRIES 7
64
+ /* We use the recommended 5 minutes timeout to recalibrate */
65
+ #define AT86RF2XX_CAL_LOOP_TIMEOUT (5 * 60 * HZ)
63
66
64
67
struct at86rf230_state_change {
65
68
struct at86rf230_local * lp ;
@@ -90,6 +93,7 @@ struct at86rf230_local {
90
93
struct at86rf230_state_change irq ;
91
94
92
95
bool tx_aret ;
96
+ unsigned long cal_timeout ;
93
97
s8 max_frame_retries ;
94
98
bool is_tx ;
95
99
/* spinlock for is_tx protection */
@@ -491,6 +495,14 @@ at86rf230_async_read_reg(struct at86rf230_local *lp, const u8 reg,
491
495
}
492
496
}
493
497
498
+ static inline u8 at86rf230_state_to_force (u8 state )
499
+ {
500
+ if (state == STATE_TX_ON )
501
+ return STATE_FORCE_TX_ON ;
502
+ else
503
+ return STATE_FORCE_TRX_OFF ;
504
+ }
505
+
494
506
static void
495
507
at86rf230_async_state_assert (void * context )
496
508
{
@@ -527,11 +539,12 @@ at86rf230_async_state_assert(void *context)
527
539
* higher or equal than AT86RF2XX_MAX_TX_RETRIES we
528
540
* will do a force change.
529
541
*/
530
- if (ctx -> to_state == STATE_TX_ON ) {
531
- u8 state = STATE_TX_ON ;
542
+ if (ctx -> to_state == STATE_TX_ON ||
543
+ ctx -> to_state == STATE_TRX_OFF ) {
544
+ u8 state = ctx -> to_state ;
532
545
533
546
if (lp -> tx_retry >= AT86RF2XX_MAX_TX_RETRIES )
534
- state = STATE_FORCE_TX_ON ;
547
+ state = at86rf230_state_to_force ( state ) ;
535
548
lp -> tx_retry ++ ;
536
549
537
550
at86rf230_async_state_change (lp , ctx , state ,
@@ -599,17 +612,23 @@ at86rf230_async_state_delay(void *context)
599
612
goto change ;
600
613
case STATE_TX_ON :
601
614
tim = ktime_set (0 , c -> t_off_to_tx_on * NSEC_PER_USEC );
615
+ /* state change from TRX_OFF to TX_ON to do a
616
+ * calibration, we need to reset the timeout for the
617
+ * next one.
618
+ */
619
+ lp -> cal_timeout = jiffies + AT86RF2XX_CAL_LOOP_TIMEOUT ;
602
620
goto change ;
603
621
default :
604
622
break ;
605
623
}
606
624
break ;
607
625
case STATE_BUSY_RX_AACK :
608
626
switch (ctx -> to_state ) {
627
+ case STATE_TRX_OFF :
609
628
case STATE_TX_ON :
610
629
/* Wait for worst case receiving time if we
611
630
* didn't make a force change from BUSY_RX_AACK
612
- * to TX_ON.
631
+ * to TX_ON or TRX_OFF .
613
632
*/
614
633
if (!force ) {
615
634
tim = ktime_set (0 , (c -> t_frame + c -> t_p_ack ) *
@@ -969,25 +988,45 @@ at86rf230_xmit_tx_on(void *context)
969
988
at86rf230_write_frame , false);
970
989
}
971
990
972
- static int
973
- at86rf230_xmit ( struct ieee802154_hw * hw , struct sk_buff * skb )
991
+ static void
992
+ at86rf230_xmit_start ( void * context )
974
993
{
975
- struct at86rf230_local * lp = hw -> priv ;
976
- struct at86rf230_state_change * ctx = & lp -> tx ;
977
-
978
- void (* tx_complete )(void * context ) = at86rf230_write_frame ;
979
-
980
- lp -> tx_skb = skb ;
994
+ struct at86rf230_state_change * ctx = context ;
995
+ struct at86rf230_local * lp = ctx -> lp ;
981
996
982
997
/* In ARET mode we need to go into STATE_TX_ARET_ON after we
983
998
* are in STATE_TX_ON. The pfad differs here, so we change
984
999
* the complete handler.
985
1000
*/
986
1001
if (lp -> tx_aret )
987
- tx_complete = at86rf230_xmit_tx_on ;
1002
+ at86rf230_async_state_change (lp , ctx , STATE_TX_ON ,
1003
+ at86rf230_xmit_tx_on , false);
1004
+ else
1005
+ at86rf230_async_state_change (lp , ctx , STATE_TX_ON ,
1006
+ at86rf230_write_frame , false);
1007
+ }
1008
+
1009
+ static int
1010
+ at86rf230_xmit (struct ieee802154_hw * hw , struct sk_buff * skb )
1011
+ {
1012
+ struct at86rf230_local * lp = hw -> priv ;
1013
+ struct at86rf230_state_change * ctx = & lp -> tx ;
988
1014
1015
+ lp -> tx_skb = skb ;
989
1016
lp -> tx_retry = 0 ;
990
- at86rf230_async_state_change (lp , ctx , STATE_TX_ON , tx_complete , false);
1017
+
1018
+ /* After 5 minutes in PLL and the same frequency we run again the
1019
+ * calibration loops which is recommended by at86rf2xx datasheets.
1020
+ *
1021
+ * The calibration is initiate by a state change from TRX_OFF
1022
+ * to TX_ON, the lp->cal_timeout should be reinit by state_delay
1023
+ * function then to start in the next 5 minutes.
1024
+ */
1025
+ if (time_is_before_jiffies (lp -> cal_timeout ))
1026
+ at86rf230_async_state_change (lp , ctx , STATE_TRX_OFF ,
1027
+ at86rf230_xmit_start , false);
1028
+ else
1029
+ at86rf230_xmit_start (ctx );
991
1030
992
1031
return 0 ;
993
1032
}
@@ -1003,6 +1042,9 @@ at86rf230_ed(struct ieee802154_hw *hw, u8 *level)
1003
1042
static int
1004
1043
at86rf230_start (struct ieee802154_hw * hw )
1005
1044
{
1045
+ struct at86rf230_local * lp = hw -> priv ;
1046
+
1047
+ lp -> cal_timeout = jiffies + AT86RF2XX_CAL_LOOP_TIMEOUT ;
1006
1048
return at86rf230_sync_state_change (hw -> priv , STATE_RX_AACK_ON );
1007
1049
}
1008
1050
@@ -1083,6 +1125,8 @@ at86rf230_channel(struct ieee802154_hw *hw, u8 page, u8 channel)
1083
1125
/* Wait for PLL */
1084
1126
usleep_range (lp -> data -> t_channel_switch ,
1085
1127
lp -> data -> t_channel_switch + 10 );
1128
+
1129
+ lp -> cal_timeout = jiffies + AT86RF2XX_CAL_LOOP_TIMEOUT ;
1086
1130
return rc ;
1087
1131
}
1088
1132
0 commit comments