Skip to content

Commit 1fa80e2

Browse files
scosumarckleinebudde
authored andcommitted
can: m_can: Introduce a tx_fifo_in_flight counter
Keep track of the number of transmits in flight. This patch prepares the driver to control the network interface queue based on this counter. By itself this counter be implemented with an atomic, but as we need to do other things in the critical sections later I am using a spinlock instead. Signed-off-by: Markus Schneider-Pargmann <[email protected]> Link: https://lore.kernel.org/all/[email protected] Signed-off-by: Marc Kleine-Budde <[email protected]>
1 parent e668673 commit 1fa80e2

File tree

2 files changed

+34
-0
lines changed

2 files changed

+34
-0
lines changed

drivers/net/can/m_can/m_can.c

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -484,6 +484,7 @@ static u32 m_can_get_timestamp(struct m_can_classdev *cdev)
484484
static void m_can_clean(struct net_device *net)
485485
{
486486
struct m_can_classdev *cdev = netdev_priv(net);
487+
unsigned long irqflags;
487488

488489
if (cdev->tx_ops) {
489490
for (int i = 0; i != cdev->tx_fifo_size; ++i) {
@@ -497,6 +498,10 @@ static void m_can_clean(struct net_device *net)
497498

498499
for (int i = 0; i != cdev->can.echo_skb_max; ++i)
499500
can_free_echo_skb(cdev->net, i, NULL);
501+
502+
spin_lock_irqsave(&cdev->tx_handling_spinlock, irqflags);
503+
cdev->tx_fifo_in_flight = 0;
504+
spin_unlock_irqrestore(&cdev->tx_handling_spinlock, irqflags);
500505
}
501506

502507
/* For peripherals, pass skb to rx-offload, which will push skb from
@@ -1067,6 +1072,24 @@ static void m_can_tx_update_stats(struct m_can_classdev *cdev,
10671072
stats->tx_packets++;
10681073
}
10691074

1075+
static void m_can_finish_tx(struct m_can_classdev *cdev, int transmitted)
1076+
{
1077+
unsigned long irqflags;
1078+
1079+
spin_lock_irqsave(&cdev->tx_handling_spinlock, irqflags);
1080+
cdev->tx_fifo_in_flight -= transmitted;
1081+
spin_unlock_irqrestore(&cdev->tx_handling_spinlock, irqflags);
1082+
}
1083+
1084+
static void m_can_start_tx(struct m_can_classdev *cdev)
1085+
{
1086+
unsigned long irqflags;
1087+
1088+
spin_lock_irqsave(&cdev->tx_handling_spinlock, irqflags);
1089+
++cdev->tx_fifo_in_flight;
1090+
spin_unlock_irqrestore(&cdev->tx_handling_spinlock, irqflags);
1091+
}
1092+
10701093
static int m_can_echo_tx_event(struct net_device *dev)
10711094
{
10721095
u32 txe_count = 0;
@@ -1076,6 +1099,7 @@ static int m_can_echo_tx_event(struct net_device *dev)
10761099
int i = 0;
10771100
int err = 0;
10781101
unsigned int msg_mark;
1102+
int processed = 0;
10791103

10801104
struct m_can_classdev *cdev = netdev_priv(dev);
10811105

@@ -1105,12 +1129,15 @@ static int m_can_echo_tx_event(struct net_device *dev)
11051129

11061130
/* update stats */
11071131
m_can_tx_update_stats(cdev, msg_mark, timestamp);
1132+
++processed;
11081133
}
11091134

11101135
if (ack_fgi != -1)
11111136
m_can_write(cdev, M_CAN_TXEFA, FIELD_PREP(TXEFA_EFAI_MASK,
11121137
ack_fgi));
11131138

1139+
m_can_finish_tx(cdev, processed);
1140+
11141141
return err;
11151142
}
11161143

@@ -1192,6 +1219,7 @@ static irqreturn_t m_can_isr(int irq, void *dev_id)
11921219
timestamp = m_can_get_timestamp(cdev);
11931220
m_can_tx_update_stats(cdev, 0, timestamp);
11941221
netif_wake_queue(dev);
1222+
m_can_finish_tx(cdev, 1);
11951223
}
11961224
} else {
11971225
if (ir & (IR_TEFN | IR_TEFW)) {
@@ -1890,6 +1918,8 @@ static netdev_tx_t m_can_start_xmit(struct sk_buff *skb,
18901918
return NETDEV_TX_OK;
18911919
}
18921920

1921+
m_can_start_tx(cdev);
1922+
18931923
if (cdev->is_peripheral)
18941924
return m_can_start_peripheral_xmit(cdev, skb);
18951925
else

drivers/net/can/m_can/m_can.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,10 @@ struct m_can_classdev {
108108
// Store this internally to avoid fetch delays on peripheral chips
109109
u32 tx_fifo_putidx;
110110

111+
/* Protects shared state between start_xmit and m_can_isr */
112+
spinlock_t tx_handling_spinlock;
113+
int tx_fifo_in_flight;
114+
111115
struct m_can_tx_op *tx_ops;
112116
int tx_fifo_size;
113117
int next_tx_op;

0 commit comments

Comments
 (0)