@@ -152,8 +152,22 @@ struct mrf24j40 {
152
152
153
153
struct regmap * regmap_short ;
154
154
struct regmap * regmap_long ;
155
+
156
+ /* for writing txfifo */
157
+ struct spi_message tx_msg ;
158
+ u8 tx_hdr_buf [2 ];
159
+ struct spi_transfer tx_hdr_trx ;
160
+ u8 tx_len_buf [2 ];
161
+ struct spi_transfer tx_len_trx ;
162
+ struct spi_transfer tx_buf_trx ;
163
+ struct sk_buff * tx_skb ;
164
+
165
+ /* post transmit message to send frame out */
166
+ struct spi_message tx_post_msg ;
167
+ u8 tx_post_buf [2 ];
168
+ struct spi_transfer tx_post_trx ;
169
+
155
170
struct mutex buffer_mutex ; /* only used to protect buf */
156
- struct completion tx_complete ;
157
171
u8 * buf ; /* 3 bytes. Used for SPI single-register transfers. */
158
172
};
159
173
@@ -543,55 +557,65 @@ static int read_long_reg(struct mrf24j40 *devrec, u16 reg, u8 *value)
543
557
return ret ;
544
558
}
545
559
560
+ static void write_tx_buf_complete (void * context )
561
+ {
562
+ struct mrf24j40 * devrec = context ;
563
+ __le16 fc = ieee802154_get_fc_from_skb (devrec -> tx_skb );
564
+ u8 val = 0x01 ;
565
+ int ret ;
566
+
567
+ if (ieee802154_is_ackreq (fc ))
568
+ val |= 0x04 ;
569
+
570
+ devrec -> tx_post_msg .complete = NULL ;
571
+ devrec -> tx_post_buf [0 ] = MRF24J40_WRITESHORT (REG_TXNCON );
572
+ devrec -> tx_post_buf [1 ] = val ;
573
+
574
+ ret = spi_async (devrec -> spi , & devrec -> tx_post_msg );
575
+ if (ret )
576
+ dev_err (printdev (devrec ), "SPI write Failed for transmit buf\n" );
577
+ }
578
+
546
579
/* This function relies on an undocumented write method. Once a write command
547
580
and address is set, as many bytes of data as desired can be clocked into
548
581
the device. The datasheet only shows setting one byte at a time. */
549
582
static int write_tx_buf (struct mrf24j40 * devrec , u16 reg ,
550
583
const u8 * data , size_t length )
551
584
{
552
- int ret ;
553
585
u16 cmd ;
554
- u8 lengths [2 ];
555
- struct spi_message msg ;
556
- struct spi_transfer addr_xfer = {
557
- .len = 2 ,
558
- .tx_buf = devrec -> buf ,
559
- };
560
- struct spi_transfer lengths_xfer = {
561
- .len = 2 ,
562
- .tx_buf = & lengths , /* TODO: Is DMA really required for SPI? */
563
- };
564
- struct spi_transfer data_xfer = {
565
- .len = length ,
566
- .tx_buf = data ,
567
- };
586
+ int ret ;
568
587
569
588
/* Range check the length. 2 bytes are used for the length fields.*/
570
589
if (length > TX_FIFO_SIZE - 2 ) {
571
590
dev_err (printdev (devrec ), "write_tx_buf() was passed too large a buffer. Performing short write.\n" );
572
591
length = TX_FIFO_SIZE - 2 ;
573
592
}
574
593
575
- spi_message_init (& msg );
576
- spi_message_add_tail (& addr_xfer , & msg );
577
- spi_message_add_tail (& lengths_xfer , & msg );
578
- spi_message_add_tail (& data_xfer , & msg );
579
-
580
594
cmd = MRF24J40_WRITELONG (reg );
581
- mutex_lock (& devrec -> buffer_mutex );
582
- devrec -> buf [0 ] = cmd >> 8 & 0xff ;
583
- devrec -> buf [1 ] = cmd & 0xff ;
584
- lengths [0 ] = 0x0 ; /* Header Length. Set to 0 for now. TODO */
585
- lengths [1 ] = length ; /* Total length */
586
-
587
- ret = spi_sync (devrec -> spi , & msg );
595
+ devrec -> tx_hdr_buf [0 ] = cmd >> 8 & 0xff ;
596
+ devrec -> tx_hdr_buf [1 ] = cmd & 0xff ;
597
+ devrec -> tx_len_buf [0 ] = 0x0 ; /* Header Length. Set to 0 for now. TODO */
598
+ devrec -> tx_len_buf [1 ] = length ; /* Total length */
599
+ devrec -> tx_buf_trx .tx_buf = data ;
600
+ devrec -> tx_buf_trx .len = length ;
601
+
602
+ ret = spi_async (devrec -> spi , & devrec -> tx_msg );
588
603
if (ret )
589
604
dev_err (printdev (devrec ), "SPI write Failed for TX buf\n" );
590
605
591
- mutex_unlock (& devrec -> buffer_mutex );
592
606
return ret ;
593
607
}
594
608
609
+ static int mrf24j40_tx (struct ieee802154_hw * hw , struct sk_buff * skb )
610
+ {
611
+ struct mrf24j40 * devrec = hw -> priv ;
612
+
613
+ dev_dbg (printdev (devrec ), "tx packet of %d bytes\n" , skb -> len );
614
+ devrec -> tx_skb = skb ;
615
+
616
+ return write_tx_buf (devrec , 0x000 , skb -> data , skb -> len );
617
+ }
618
+
595
619
static int mrf24j40_read_rx_buf (struct mrf24j40 * devrec ,
596
620
u8 * data , u8 * len , u8 * lqi )
597
621
{
@@ -664,57 +688,6 @@ static int mrf24j40_read_rx_buf(struct mrf24j40 *devrec,
664
688
return ret ;
665
689
}
666
690
667
- static int mrf24j40_tx (struct ieee802154_hw * hw , struct sk_buff * skb )
668
- {
669
- struct mrf24j40 * devrec = hw -> priv ;
670
- u8 val ;
671
- int ret = 0 ;
672
-
673
- dev_dbg (printdev (devrec ), "tx packet of %d bytes\n" , skb -> len );
674
-
675
- ret = write_tx_buf (devrec , 0x000 , skb -> data , skb -> len );
676
- if (ret )
677
- goto err ;
678
-
679
- reinit_completion (& devrec -> tx_complete );
680
-
681
- /* Set TXNTRIG bit of TXNCON to send packet */
682
- ret = read_short_reg (devrec , REG_TXNCON , & val );
683
- if (ret )
684
- goto err ;
685
- val |= 0x1 ;
686
- /* Set TXNACKREQ if the ACK bit is set in the packet. */
687
- if (skb -> data [0 ] & IEEE802154_FC_ACK_REQ )
688
- val |= 0x4 ;
689
- write_short_reg (devrec , REG_TXNCON , val );
690
-
691
- /* Wait for the device to send the TX complete interrupt. */
692
- ret = wait_for_completion_interruptible_timeout (
693
- & devrec -> tx_complete ,
694
- 5 * HZ );
695
- if (ret == - ERESTARTSYS )
696
- goto err ;
697
- if (ret == 0 ) {
698
- dev_warn (printdev (devrec ), "Timeout waiting for TX interrupt\n" );
699
- ret = - ETIMEDOUT ;
700
- goto err ;
701
- }
702
-
703
- /* Check for send error from the device. */
704
- ret = read_short_reg (devrec , REG_TXSTAT , & val );
705
- if (ret )
706
- goto err ;
707
- if (val & 0x1 ) {
708
- dev_dbg (printdev (devrec ), "Error Sending. Retry count exceeded\n" );
709
- ret = - ECOMM ; /* TODO: Better error code ? */
710
- } else
711
- dev_dbg (printdev (devrec ), "Packet Sent\n" );
712
-
713
- err :
714
-
715
- return ret ;
716
- }
717
-
718
691
static int mrf24j40_ed (struct ieee802154_hw * hw , u8 * level )
719
692
{
720
693
/* TODO: */
@@ -901,7 +874,7 @@ static int mrf24j40_handle_rx(struct mrf24j40 *devrec)
901
874
902
875
static const struct ieee802154_ops mrf24j40_ops = {
903
876
.owner = THIS_MODULE ,
904
- .xmit_sync = mrf24j40_tx ,
877
+ .xmit_async = mrf24j40_tx ,
905
878
.ed = mrf24j40_ed ,
906
879
.start = mrf24j40_start ,
907
880
.stop = mrf24j40_stop ,
@@ -922,7 +895,7 @@ static irqreturn_t mrf24j40_isr(int irq, void *data)
922
895
923
896
/* Check for TX complete */
924
897
if (intstat & 0x1 )
925
- complete ( & devrec -> tx_complete );
898
+ ieee802154_xmit_complete ( devrec -> hw , devrec -> tx_skb , false );
926
899
927
900
/* Check for Rx */
928
901
if (intstat & 0x8 )
@@ -1031,6 +1004,27 @@ static int mrf24j40_hw_init(struct mrf24j40 *devrec)
1031
1004
return ret ;
1032
1005
}
1033
1006
1007
+ static void
1008
+ mrf24j40_setup_tx_spi_messages (struct mrf24j40 * devrec )
1009
+ {
1010
+ spi_message_init (& devrec -> tx_msg );
1011
+ devrec -> tx_msg .context = devrec ;
1012
+ devrec -> tx_msg .complete = write_tx_buf_complete ;
1013
+ devrec -> tx_hdr_trx .len = 2 ;
1014
+ devrec -> tx_hdr_trx .tx_buf = devrec -> tx_hdr_buf ;
1015
+ spi_message_add_tail (& devrec -> tx_hdr_trx , & devrec -> tx_msg );
1016
+ devrec -> tx_len_trx .len = 2 ;
1017
+ devrec -> tx_len_trx .tx_buf = devrec -> tx_len_buf ;
1018
+ spi_message_add_tail (& devrec -> tx_len_trx , & devrec -> tx_msg );
1019
+ spi_message_add_tail (& devrec -> tx_buf_trx , & devrec -> tx_msg );
1020
+
1021
+ spi_message_init (& devrec -> tx_post_msg );
1022
+ devrec -> tx_post_msg .context = devrec ;
1023
+ devrec -> tx_post_trx .len = 2 ;
1024
+ devrec -> tx_post_trx .tx_buf = devrec -> tx_post_buf ;
1025
+ spi_message_add_tail (& devrec -> tx_post_trx , & devrec -> tx_post_msg );
1026
+ }
1027
+
1034
1028
static void mrf24j40_phy_setup (struct mrf24j40 * devrec )
1035
1029
{
1036
1030
ieee802154_random_extended_addr (& devrec -> hw -> phy -> perm_extended_addr );
@@ -1059,6 +1053,8 @@ static int mrf24j40_probe(struct spi_device *spi)
1059
1053
devrec -> hw -> phy -> supported .channels [0 ] = CHANNEL_MASK ;
1060
1054
devrec -> hw -> flags = IEEE802154_HW_TX_OMIT_CKSUM | IEEE802154_HW_AFILT ;
1061
1055
1056
+ mrf24j40_setup_tx_spi_messages (devrec );
1057
+
1062
1058
devrec -> regmap_short = devm_regmap_init_spi (spi ,
1063
1059
& mrf24j40_short_regmap );
1064
1060
if (IS_ERR (devrec -> regmap_short )) {
@@ -1089,7 +1085,6 @@ static int mrf24j40_probe(struct spi_device *spi)
1089
1085
}
1090
1086
1091
1087
mutex_init (& devrec -> buffer_mutex );
1092
- init_completion (& devrec -> tx_complete );
1093
1088
1094
1089
ret = mrf24j40_hw_init (devrec );
1095
1090
if (ret )
0 commit comments