aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/ieee802154/at86rf230.c157
1 files changed, 77 insertions, 80 deletions
diff --git a/drivers/net/ieee802154/at86rf230.c b/drivers/net/ieee802154/at86rf230.c
index 5dbec64eb786..7a1a8e39b130 100644
--- a/drivers/net/ieee802154/at86rf230.c
+++ b/drivers/net/ieee802154/at86rf230.c
@@ -74,6 +74,8 @@ struct at86rf230_state_change {
74 void (*complete)(void *context); 74 void (*complete)(void *context);
75 u8 from_state; 75 u8 from_state;
76 u8 to_state; 76 u8 to_state;
77
78 bool irq_enable;
77}; 79};
78 80
79struct at86rf230_local { 81struct at86rf230_local {
@@ -292,10 +294,11 @@ struct at86rf230_local {
292 294
293#define AT86RF2XX_NUMREGS 0x3F 295#define AT86RF2XX_NUMREGS 0x3F
294 296
295static int 297static void
296at86rf230_async_state_change(struct at86rf230_local *lp, 298at86rf230_async_state_change(struct at86rf230_local *lp,
297 struct at86rf230_state_change *ctx, 299 struct at86rf230_state_change *ctx,
298 const u8 state, void (*complete)(void *context)); 300 const u8 state, void (*complete)(void *context),
301 const bool irq_enable);
299 302
300static inline int 303static inline int
301__at86rf230_write(struct at86rf230_local *lp, 304__at86rf230_write(struct at86rf230_local *lp,
@@ -452,7 +455,7 @@ at86rf230_async_error_recover(void *context)
452 struct at86rf230_state_change *ctx = context; 455 struct at86rf230_state_change *ctx = context;
453 struct at86rf230_local *lp = ctx->lp; 456 struct at86rf230_local *lp = ctx->lp;
454 457
455 at86rf230_async_state_change(lp, ctx, STATE_RX_AACK_ON, NULL); 458 at86rf230_async_state_change(lp, ctx, STATE_RX_AACK_ON, NULL, false);
456} 459}
457 460
458static void 461static void
@@ -462,21 +465,31 @@ at86rf230_async_error(struct at86rf230_local *lp,
462 dev_err(&lp->spi->dev, "spi_async error %d\n", rc); 465 dev_err(&lp->spi->dev, "spi_async error %d\n", rc);
463 466
464 at86rf230_async_state_change(lp, ctx, STATE_FORCE_TRX_OFF, 467 at86rf230_async_state_change(lp, ctx, STATE_FORCE_TRX_OFF,
465 at86rf230_async_error_recover); 468 at86rf230_async_error_recover, false);
466} 469}
467 470
468/* Generic function to get some register value in async mode */ 471/* Generic function to get some register value in async mode */
469static int 472static void
470at86rf230_async_read_reg(struct at86rf230_local *lp, const u8 reg, 473at86rf230_async_read_reg(struct at86rf230_local *lp, const u8 reg,
471 struct at86rf230_state_change *ctx, 474 struct at86rf230_state_change *ctx,
472 void (*complete)(void *context)) 475 void (*complete)(void *context),
476 const bool irq_enable)
473{ 477{
478 int rc;
479
474 u8 *tx_buf = ctx->buf; 480 u8 *tx_buf = ctx->buf;
475 481
476 tx_buf[0] = (reg & CMD_REG_MASK) | CMD_REG; 482 tx_buf[0] = (reg & CMD_REG_MASK) | CMD_REG;
477 ctx->trx.len = 2; 483 ctx->trx.len = 2;
478 ctx->msg.complete = complete; 484 ctx->msg.complete = complete;
479 return spi_async(lp->spi, &ctx->msg); 485 ctx->irq_enable = irq_enable;
486 rc = spi_async(lp->spi, &ctx->msg);
487 if (rc) {
488 if (irq_enable)
489 enable_irq(lp->spi->irq);
490
491 at86rf230_async_error(lp, ctx, rc);
492 }
480} 493}
481 494
482static void 495static void
@@ -513,7 +526,8 @@ at86rf230_async_state_assert(void *context)
513 if (ctx->to_state == STATE_TX_ON) { 526 if (ctx->to_state == STATE_TX_ON) {
514 at86rf230_async_state_change(lp, ctx, 527 at86rf230_async_state_change(lp, ctx,
515 STATE_FORCE_TX_ON, 528 STATE_FORCE_TX_ON,
516 ctx->complete); 529 ctx->complete,
530 ctx->irq_enable);
517 return; 531 return;
518 } 532 }
519 } 533 }
@@ -536,7 +550,6 @@ at86rf230_async_state_delay(void *context)
536 struct at86rf230_local *lp = ctx->lp; 550 struct at86rf230_local *lp = ctx->lp;
537 struct at86rf2xx_chip_data *c = lp->data; 551 struct at86rf2xx_chip_data *c = lp->data;
538 bool force = false; 552 bool force = false;
539 int rc;
540 553
541 /* The force state changes are will show as normal states in the 554 /* The force state changes are will show as normal states in the
542 * state status subregister. We change the to_state to the 555 * state status subregister. We change the to_state to the
@@ -605,10 +618,9 @@ at86rf230_async_state_delay(void *context)
605 udelay(1); 618 udelay(1);
606 619
607change: 620change:
608 rc = at86rf230_async_read_reg(lp, RG_TRX_STATUS, ctx, 621 at86rf230_async_read_reg(lp, RG_TRX_STATUS, ctx,
609 at86rf230_async_state_assert); 622 at86rf230_async_state_assert,
610 if (rc) 623 ctx->irq_enable);
611 dev_err(&lp->spi->dev, "spi_async error %d\n", rc);
612} 624}
613 625
614static void 626static void
@@ -623,10 +635,9 @@ at86rf230_async_state_change_start(void *context)
623 /* Check for "possible" STATE_TRANSITION_IN_PROGRESS */ 635 /* Check for "possible" STATE_TRANSITION_IN_PROGRESS */
624 if (trx_state == STATE_TRANSITION_IN_PROGRESS) { 636 if (trx_state == STATE_TRANSITION_IN_PROGRESS) {
625 udelay(1); 637 udelay(1);
626 rc = at86rf230_async_read_reg(lp, RG_TRX_STATUS, ctx, 638 at86rf230_async_read_reg(lp, RG_TRX_STATUS, ctx,
627 at86rf230_async_state_change_start); 639 at86rf230_async_state_change_start,
628 if (rc) 640 ctx->irq_enable);
629 dev_err(&lp->spi->dev, "spi_async error %d\n", rc);
630 return; 641 return;
631 } 642 }
632 643
@@ -648,20 +659,28 @@ at86rf230_async_state_change_start(void *context)
648 ctx->trx.len = 2; 659 ctx->trx.len = 2;
649 ctx->msg.complete = at86rf230_async_state_delay; 660 ctx->msg.complete = at86rf230_async_state_delay;
650 rc = spi_async(lp->spi, &ctx->msg); 661 rc = spi_async(lp->spi, &ctx->msg);
651 if (rc) 662 if (rc) {
663 if (ctx->irq_enable)
664 enable_irq(lp->spi->irq);
665
666 at86rf230_async_error(lp, &lp->state, rc);
652 dev_err(&lp->spi->dev, "spi_async error %d\n", rc); 667 dev_err(&lp->spi->dev, "spi_async error %d\n", rc);
668 }
653} 669}
654 670
655static int 671static void
656at86rf230_async_state_change(struct at86rf230_local *lp, 672at86rf230_async_state_change(struct at86rf230_local *lp,
657 struct at86rf230_state_change *ctx, 673 struct at86rf230_state_change *ctx,
658 const u8 state, void (*complete)(void *context)) 674 const u8 state, void (*complete)(void *context),
675 const bool irq_enable)
659{ 676{
660 /* Initialization for the state change context */ 677 /* Initialization for the state change context */
661 ctx->to_state = state; 678 ctx->to_state = state;
662 ctx->complete = complete; 679 ctx->complete = complete;
663 return at86rf230_async_read_reg(lp, RG_TRX_STATUS, ctx, 680 ctx->irq_enable = irq_enable;
664 at86rf230_async_state_change_start); 681 at86rf230_async_read_reg(lp, RG_TRX_STATUS, ctx,
682 at86rf230_async_state_change_start,
683 irq_enable);
665} 684}
666 685
667static void 686static void
@@ -682,12 +701,9 @@ at86rf230_sync_state_change(struct at86rf230_local *lp, unsigned int state)
682{ 701{
683 int rc; 702 int rc;
684 703
685 rc = at86rf230_async_state_change(lp, &lp->state, state, 704 at86rf230_async_state_change(lp, &lp->state, state,
686 at86rf230_sync_state_change_complete); 705 at86rf230_sync_state_change_complete,
687 if (rc) { 706 false);
688 at86rf230_async_error(lp, &lp->state, rc);
689 return rc;
690 }
691 707
692 rc = wait_for_completion_timeout(&lp->state_complete, 708 rc = wait_for_completion_timeout(&lp->state_complete,
693 msecs_to_jiffies(100)); 709 msecs_to_jiffies(100));
@@ -714,12 +730,9 @@ at86rf230_tx_on(void *context)
714{ 730{
715 struct at86rf230_state_change *ctx = context; 731 struct at86rf230_state_change *ctx = context;
716 struct at86rf230_local *lp = ctx->lp; 732 struct at86rf230_local *lp = ctx->lp;
717 int rc;
718 733
719 rc = at86rf230_async_state_change(lp, &lp->irq, STATE_RX_AACK_ON, 734 at86rf230_async_state_change(lp, &lp->irq, STATE_RX_AACK_ON,
720 at86rf230_tx_complete); 735 at86rf230_tx_complete, true);
721 if (rc)
722 at86rf230_async_error(lp, ctx, rc);
723} 736}
724 737
725static void 738static void
@@ -727,12 +740,9 @@ at86rf230_tx_trac_error(void *context)
727{ 740{
728 struct at86rf230_state_change *ctx = context; 741 struct at86rf230_state_change *ctx = context;
729 struct at86rf230_local *lp = ctx->lp; 742 struct at86rf230_local *lp = ctx->lp;
730 int rc;
731 743
732 rc = at86rf230_async_state_change(lp, ctx, STATE_TX_ON, 744 at86rf230_async_state_change(lp, ctx, STATE_TX_ON,
733 at86rf230_tx_on); 745 at86rf230_tx_on, true);
734 if (rc)
735 at86rf230_async_error(lp, ctx, rc);
736} 746}
737 747
738static void 748static void
@@ -742,17 +752,14 @@ at86rf230_tx_trac_check(void *context)
742 struct at86rf230_local *lp = ctx->lp; 752 struct at86rf230_local *lp = ctx->lp;
743 const u8 *buf = ctx->buf; 753 const u8 *buf = ctx->buf;
744 const u8 trac = (buf[1] & 0xe0) >> 5; 754 const u8 trac = (buf[1] & 0xe0) >> 5;
745 int rc;
746 755
747 /* If trac status is different than zero we need to do a state change 756 /* If trac status is different than zero we need to do a state change
748 * to STATE_FORCE_TRX_OFF then STATE_TX_ON to recover the transceiver 757 * to STATE_FORCE_TRX_OFF then STATE_TX_ON to recover the transceiver
749 * state to TX_ON. 758 * state to TX_ON.
750 */ 759 */
751 if (trac) { 760 if (trac) {
752 rc = at86rf230_async_state_change(lp, ctx, STATE_FORCE_TRX_OFF, 761 at86rf230_async_state_change(lp, ctx, STATE_FORCE_TRX_OFF,
753 at86rf230_tx_trac_error); 762 at86rf230_tx_trac_error, true);
754 if (rc)
755 at86rf230_async_error(lp, ctx, rc);
756 return; 763 return;
757 } 764 }
758 765
@@ -765,12 +772,9 @@ at86rf230_tx_trac_status(void *context)
765{ 772{
766 struct at86rf230_state_change *ctx = context; 773 struct at86rf230_state_change *ctx = context;
767 struct at86rf230_local *lp = ctx->lp; 774 struct at86rf230_local *lp = ctx->lp;
768 int rc;
769 775
770 rc = at86rf230_async_read_reg(lp, RG_TRX_STATE, ctx, 776 at86rf230_async_read_reg(lp, RG_TRX_STATE, ctx,
771 at86rf230_tx_trac_check); 777 at86rf230_tx_trac_check, true);
772 if (rc)
773 at86rf230_async_error(lp, ctx, rc);
774} 778}
775 779
776static void 780static void
@@ -823,15 +827,21 @@ at86rf230_rx_read_frame_complete(void *context)
823 at86rf230_rx(lp, buf + 2, len); 827 at86rf230_rx(lp, buf + 2, len);
824} 828}
825 829
826static int 830static void
827at86rf230_rx_read_frame(struct at86rf230_local *lp) 831at86rf230_rx_read_frame(struct at86rf230_local *lp)
828{ 832{
833 int rc;
834
829 u8 *buf = lp->irq.buf; 835 u8 *buf = lp->irq.buf;
830 836
831 buf[0] = CMD_FB; 837 buf[0] = CMD_FB;
832 lp->irq.trx.len = AT86RF2XX_MAX_BUF; 838 lp->irq.trx.len = AT86RF2XX_MAX_BUF;
833 lp->irq.msg.complete = at86rf230_rx_read_frame_complete; 839 lp->irq.msg.complete = at86rf230_rx_read_frame_complete;
834 return spi_async(lp->spi, &lp->irq.msg); 840 rc = spi_async(lp->spi, &lp->irq.msg);
841 if (rc) {
842 enable_irq(lp->spi->irq);
843 at86rf230_async_error(lp, &lp->irq, rc);
844 }
835} 845}
836 846
837static void 847static void
@@ -839,7 +849,6 @@ at86rf230_rx_trac_check(void *context)
839{ 849{
840 struct at86rf230_state_change *ctx = context; 850 struct at86rf230_state_change *ctx = context;
841 struct at86rf230_local *lp = ctx->lp; 851 struct at86rf230_local *lp = ctx->lp;
842 int rc;
843 852
844 /* Possible check on trac status here. This could be useful to make 853 /* Possible check on trac status here. This could be useful to make
845 * some stats why receive is failed. Not used at the moment, but it's 854 * some stats why receive is failed. Not used at the moment, but it's
@@ -847,14 +856,10 @@ at86rf230_rx_trac_check(void *context)
847 * The programming guide say do it so. 856 * The programming guide say do it so.
848 */ 857 */
849 858
850 rc = at86rf230_rx_read_frame(lp); 859 at86rf230_rx_read_frame(lp);
851 if (rc) {
852 enable_irq(lp->spi->irq);
853 at86rf230_async_error(lp, ctx, rc);
854 }
855} 860}
856 861
857static int 862static void
858at86rf230_irq_trx_end(struct at86rf230_local *lp) 863at86rf230_irq_trx_end(struct at86rf230_local *lp)
859{ 864{
860 spin_lock(&lp->lock); 865 spin_lock(&lp->lock);
@@ -863,17 +868,19 @@ at86rf230_irq_trx_end(struct at86rf230_local *lp)
863 spin_unlock(&lp->lock); 868 spin_unlock(&lp->lock);
864 869
865 if (lp->tx_aret) 870 if (lp->tx_aret)
866 return at86rf230_async_state_change(lp, &lp->irq, 871 at86rf230_async_state_change(lp, &lp->irq,
867 STATE_FORCE_TX_ON, 872 STATE_FORCE_TX_ON,
868 at86rf230_tx_trac_status); 873 at86rf230_tx_trac_status,
874 true);
869 else 875 else
870 return at86rf230_async_state_change(lp, &lp->irq, 876 at86rf230_async_state_change(lp, &lp->irq,
871 STATE_RX_AACK_ON, 877 STATE_RX_AACK_ON,
872 at86rf230_tx_complete); 878 at86rf230_tx_complete,
879 true);
873 } else { 880 } else {
874 spin_unlock(&lp->lock); 881 spin_unlock(&lp->lock);
875 return at86rf230_async_read_reg(lp, RG_TRX_STATE, &lp->irq, 882 at86rf230_async_read_reg(lp, RG_TRX_STATE, &lp->irq,
876 at86rf230_rx_trac_check); 883 at86rf230_rx_trac_check, true);
877 } 884 }
878} 885}
879 886
@@ -884,12 +891,9 @@ at86rf230_irq_status(void *context)
884 struct at86rf230_local *lp = ctx->lp; 891 struct at86rf230_local *lp = ctx->lp;
885 const u8 *buf = lp->irq.buf; 892 const u8 *buf = lp->irq.buf;
886 const u8 irq = buf[1]; 893 const u8 irq = buf[1];
887 int rc;
888 894
889 if (irq & IRQ_TRX_END) { 895 if (irq & IRQ_TRX_END) {
890 rc = at86rf230_irq_trx_end(lp); 896 at86rf230_irq_trx_end(lp);
891 if (rc)
892 at86rf230_async_error(lp, ctx, rc);
893 } else { 897 } else {
894 enable_irq(lp->spi->irq); 898 enable_irq(lp->spi->irq);
895 dev_err(&lp->spi->dev, "not supported irq %02x received\n", 899 dev_err(&lp->spi->dev, "not supported irq %02x received\n",
@@ -964,12 +968,9 @@ at86rf230_xmit_tx_on(void *context)
964{ 968{
965 struct at86rf230_state_change *ctx = context; 969 struct at86rf230_state_change *ctx = context;
966 struct at86rf230_local *lp = ctx->lp; 970 struct at86rf230_local *lp = ctx->lp;
967 int rc;
968 971
969 rc = at86rf230_async_state_change(lp, ctx, STATE_TX_ARET_ON, 972 at86rf230_async_state_change(lp, ctx, STATE_TX_ARET_ON,
970 at86rf230_write_frame); 973 at86rf230_write_frame, false);
971 if (rc)
972 at86rf230_async_error(lp, ctx, rc);
973} 974}
974 975
975static int 976static int
@@ -990,12 +991,8 @@ at86rf230_xmit(struct ieee802154_dev *dev, struct sk_buff *skb)
990 if (lp->tx_aret) 991 if (lp->tx_aret)
991 tx_complete = at86rf230_xmit_tx_on; 992 tx_complete = at86rf230_xmit_tx_on;
992 993
993 rc = at86rf230_async_state_change(lp, ctx, STATE_TX_ON, 994 at86rf230_async_state_change(lp, ctx, STATE_TX_ON, tx_complete, false);
994 tx_complete); 995
995 if (rc) {
996 at86rf230_async_error(lp, ctx, rc);
997 return rc;
998 }
999 rc = wait_for_completion_interruptible_timeout(&lp->tx_complete, 996 rc = wait_for_completion_interruptible_timeout(&lp->tx_complete,
1000 msecs_to_jiffies(lp->data->t_tx_timeout)); 997 msecs_to_jiffies(lp->data->t_tx_timeout));
1001 if (!rc) { 998 if (!rc) {