16
16
#include <linux/netdevice.h>
17
17
#include <linux/pci.h>
18
18
#include <linux/timer.h>
19
+ #include <net/netdev_queues.h>
19
20
20
21
MODULE_LICENSE ("Dual BSD/GPL" );
21
22
MODULE_AUTHOR (
"Kvaser AB <[email protected] >" );
@@ -410,10 +411,13 @@ struct kvaser_pciefd_can {
410
411
void __iomem * reg_base ;
411
412
struct can_berr_counter bec ;
412
413
u8 cmd_seq ;
414
+ u8 tx_max_count ;
415
+ u8 tx_idx ;
416
+ u8 ack_idx ;
413
417
int err_rep_cnt ;
414
- int echo_idx ;
418
+ unsigned int completed_tx_pkts ;
419
+ unsigned int completed_tx_bytes ;
415
420
spinlock_t lock ; /* Locks sensitive registers (e.g. MODE) */
416
- spinlock_t echo_lock ; /* Locks the message echo buffer */
417
421
struct timer_list bec_poll_timer ;
418
422
struct completion start_comp , flush_comp ;
419
423
};
@@ -714,6 +718,9 @@ static int kvaser_pciefd_open(struct net_device *netdev)
714
718
int ret ;
715
719
struct kvaser_pciefd_can * can = netdev_priv (netdev );
716
720
721
+ can -> tx_idx = 0 ;
722
+ can -> ack_idx = 0 ;
723
+
717
724
ret = open_candev (netdev );
718
725
if (ret )
719
726
return ret ;
@@ -745,21 +752,26 @@ static int kvaser_pciefd_stop(struct net_device *netdev)
745
752
timer_delete (& can -> bec_poll_timer );
746
753
}
747
754
can -> can .state = CAN_STATE_STOPPED ;
755
+ netdev_reset_queue (netdev );
748
756
close_candev (netdev );
749
757
750
758
return ret ;
751
759
}
752
760
761
+ static unsigned int kvaser_pciefd_tx_avail (const struct kvaser_pciefd_can * can )
762
+ {
763
+ return can -> tx_max_count - (READ_ONCE (can -> tx_idx ) - READ_ONCE (can -> ack_idx ));
764
+ }
765
+
753
766
static int kvaser_pciefd_prepare_tx_packet (struct kvaser_pciefd_tx_packet * p ,
754
- struct kvaser_pciefd_can * can ,
767
+ struct can_priv * can , u8 seq ,
755
768
struct sk_buff * skb )
756
769
{
757
770
struct canfd_frame * cf = (struct canfd_frame * )skb -> data ;
758
771
int packet_size ;
759
- int seq = can -> echo_idx ;
760
772
761
773
memset (p , 0 , sizeof (* p ));
762
- if (can -> can . ctrlmode & CAN_CTRLMODE_ONE_SHOT )
774
+ if (can -> ctrlmode & CAN_CTRLMODE_ONE_SHOT )
763
775
p -> header [1 ] |= KVASER_PCIEFD_TPACKET_SMS ;
764
776
765
777
if (cf -> can_id & CAN_RTR_FLAG )
@@ -782,7 +794,7 @@ static int kvaser_pciefd_prepare_tx_packet(struct kvaser_pciefd_tx_packet *p,
782
794
} else {
783
795
p -> header [1 ] |=
784
796
FIELD_PREP (KVASER_PCIEFD_RPACKET_DLC_MASK ,
785
- can_get_cc_dlc ((struct can_frame * )cf , can -> can . ctrlmode ));
797
+ can_get_cc_dlc ((struct can_frame * )cf , can -> ctrlmode ));
786
798
}
787
799
788
800
p -> header [1 ] |= FIELD_PREP (KVASER_PCIEFD_PACKET_SEQ_MASK , seq );
@@ -797,22 +809,24 @@ static netdev_tx_t kvaser_pciefd_start_xmit(struct sk_buff *skb,
797
809
struct net_device * netdev )
798
810
{
799
811
struct kvaser_pciefd_can * can = netdev_priv (netdev );
800
- unsigned long irq_flags ;
801
812
struct kvaser_pciefd_tx_packet packet ;
813
+ unsigned int seq = can -> tx_idx & (can -> can .echo_skb_max - 1 );
814
+ unsigned int frame_len ;
802
815
int nr_words ;
803
- u8 count ;
804
816
805
817
if (can_dev_dropped_skb (netdev , skb ))
806
818
return NETDEV_TX_OK ;
819
+ if (!netif_subqueue_maybe_stop (netdev , 0 , kvaser_pciefd_tx_avail (can ), 1 , 1 ))
820
+ return NETDEV_TX_BUSY ;
807
821
808
- nr_words = kvaser_pciefd_prepare_tx_packet (& packet , can , skb );
822
+ nr_words = kvaser_pciefd_prepare_tx_packet (& packet , & can -> can , seq , skb );
809
823
810
- spin_lock_irqsave (& can -> echo_lock , irq_flags );
811
824
/* Prepare and save echo skb in internal slot */
812
- can_put_echo_skb (skb , netdev , can -> echo_idx , 0 );
813
-
814
- /* Move echo index to the next slot */
815
- can -> echo_idx = (can -> echo_idx + 1 ) % can -> can .echo_skb_max ;
825
+ WRITE_ONCE (can -> can .echo_skb [seq ], NULL );
826
+ frame_len = can_skb_get_frame_len (skb );
827
+ can_put_echo_skb (skb , netdev , seq , frame_len );
828
+ netdev_sent_queue (netdev , frame_len );
829
+ WRITE_ONCE (can -> tx_idx , can -> tx_idx + 1 );
816
830
817
831
/* Write header to fifo */
818
832
iowrite32 (packet .header [0 ],
@@ -836,14 +850,7 @@ static netdev_tx_t kvaser_pciefd_start_xmit(struct sk_buff *skb,
836
850
KVASER_PCIEFD_KCAN_FIFO_LAST_REG );
837
851
}
838
852
839
- count = FIELD_GET (KVASER_PCIEFD_KCAN_TX_NR_PACKETS_CURRENT_MASK ,
840
- ioread32 (can -> reg_base + KVASER_PCIEFD_KCAN_TX_NR_PACKETS_REG ));
841
- /* No room for a new message, stop the queue until at least one
842
- * successful transmit
843
- */
844
- if (count >= can -> can .echo_skb_max || can -> can .echo_skb [can -> echo_idx ])
845
- netif_stop_queue (netdev );
846
- spin_unlock_irqrestore (& can -> echo_lock , irq_flags );
853
+ netif_subqueue_maybe_stop (netdev , 0 , kvaser_pciefd_tx_avail (can ), 1 , 1 );
847
854
848
855
return NETDEV_TX_OK ;
849
856
}
@@ -970,6 +977,8 @@ static int kvaser_pciefd_setup_can_ctrls(struct kvaser_pciefd *pcie)
970
977
can -> kv_pcie = pcie ;
971
978
can -> cmd_seq = 0 ;
972
979
can -> err_rep_cnt = 0 ;
980
+ can -> completed_tx_pkts = 0 ;
981
+ can -> completed_tx_bytes = 0 ;
973
982
can -> bec .txerr = 0 ;
974
983
can -> bec .rxerr = 0 ;
975
984
@@ -983,11 +992,10 @@ static int kvaser_pciefd_setup_can_ctrls(struct kvaser_pciefd *pcie)
983
992
tx_nr_packets_max =
984
993
FIELD_GET (KVASER_PCIEFD_KCAN_TX_NR_PACKETS_MAX_MASK ,
985
994
ioread32 (can -> reg_base + KVASER_PCIEFD_KCAN_TX_NR_PACKETS_REG ));
995
+ can -> tx_max_count = min (KVASER_PCIEFD_CAN_TX_MAX_COUNT , tx_nr_packets_max - 1 );
986
996
987
997
can -> can .clock .freq = pcie -> freq ;
988
- can -> can .echo_skb_max = min (KVASER_PCIEFD_CAN_TX_MAX_COUNT , tx_nr_packets_max - 1 );
989
- can -> echo_idx = 0 ;
990
- spin_lock_init (& can -> echo_lock );
998
+ can -> can .echo_skb_max = roundup_pow_of_two (can -> tx_max_count );
991
999
spin_lock_init (& can -> lock );
992
1000
993
1001
can -> can .bittiming_const = & kvaser_pciefd_bittiming_const ;
@@ -1510,19 +1518,21 @@ static int kvaser_pciefd_handle_ack_packet(struct kvaser_pciefd *pcie,
1510
1518
netdev_dbg (can -> can .dev , "Packet was flushed\n" );
1511
1519
} else {
1512
1520
int echo_idx = FIELD_GET (KVASER_PCIEFD_PACKET_SEQ_MASK , p -> header [0 ]);
1513
- int len ;
1514
- u8 count ;
1521
+ unsigned int len , frame_len = 0 ;
1515
1522
struct sk_buff * skb ;
1516
1523
1524
+ if (echo_idx != (can -> ack_idx & (can -> can .echo_skb_max - 1 )))
1525
+ return 0 ;
1517
1526
skb = can -> can .echo_skb [echo_idx ];
1518
- if (skb )
1519
- kvaser_pciefd_set_skb_timestamp (pcie , skb , p -> timestamp );
1520
- len = can_get_echo_skb (can -> can .dev , echo_idx , NULL );
1521
- count = FIELD_GET (KVASER_PCIEFD_KCAN_TX_NR_PACKETS_CURRENT_MASK ,
1522
- ioread32 (can -> reg_base + KVASER_PCIEFD_KCAN_TX_NR_PACKETS_REG ));
1527
+ if (!skb )
1528
+ return 0 ;
1529
+ kvaser_pciefd_set_skb_timestamp (pcie , skb , p -> timestamp );
1530
+ len = can_get_echo_skb (can -> can .dev , echo_idx , & frame_len );
1523
1531
1524
- if (count < can -> can .echo_skb_max && netif_queue_stopped (can -> can .dev ))
1525
- netif_wake_queue (can -> can .dev );
1532
+ /* Pairs with barrier in kvaser_pciefd_start_xmit() */
1533
+ smp_store_release (& can -> ack_idx , can -> ack_idx + 1 );
1534
+ can -> completed_tx_pkts ++ ;
1535
+ can -> completed_tx_bytes += frame_len ;
1526
1536
1527
1537
if (!one_shot_fail ) {
1528
1538
can -> can .dev -> stats .tx_bytes += len ;
@@ -1638,11 +1648,26 @@ static int kvaser_pciefd_read_buffer(struct kvaser_pciefd *pcie, int dma_buf)
1638
1648
{
1639
1649
int pos = 0 ;
1640
1650
int res = 0 ;
1651
+ unsigned int i ;
1641
1652
1642
1653
do {
1643
1654
res = kvaser_pciefd_read_packet (pcie , & pos , dma_buf );
1644
1655
} while (!res && pos > 0 && pos < KVASER_PCIEFD_DMA_SIZE );
1645
1656
1657
+ /* Report ACKs in this buffer to BQL en masse for correct periods */
1658
+ for (i = 0 ; i < pcie -> nr_channels ; ++ i ) {
1659
+ struct kvaser_pciefd_can * can = pcie -> can [i ];
1660
+
1661
+ if (!can -> completed_tx_pkts )
1662
+ continue ;
1663
+ netif_subqueue_completed_wake (can -> can .dev , 0 ,
1664
+ can -> completed_tx_pkts ,
1665
+ can -> completed_tx_bytes ,
1666
+ kvaser_pciefd_tx_avail (can ), 1 );
1667
+ can -> completed_tx_pkts = 0 ;
1668
+ can -> completed_tx_bytes = 0 ;
1669
+ }
1670
+
1646
1671
return res ;
1647
1672
}
1648
1673
0 commit comments