@@ -126,7 +126,12 @@ static void x8h7_can_status(struct x8h7_can_priv *priv, u8 intf, u8 eflag)
126
126
net -> stats .tx_bytes += priv -> tx_len ;
127
127
priv -> tx_len = 0 ;
128
128
can_led_event (net , CAN_LED_EVENT_TX );
129
- can_get_echo_skb (net , 0 );
129
+ //can_get_echo_skb(net, 0);
130
+
131
+ spin_lock (& priv -> tx_obj_buf .lock );
132
+ priv -> ack_cnt ++ ;
133
+ spin_unlock (& priv -> tx_obj_buf .lock );
134
+
130
135
netif_wake_queue (net );
131
136
}
132
137
@@ -139,6 +144,12 @@ static void x8h7_can_status(struct x8h7_can_priv *priv, u8 intf, u8 eflag)
139
144
if (intf & X8H7_CAN_STS_INT_TX_FIFO_EMPTY )
140
145
{
141
146
DBG_PRINT ("TX FIFO EMPTY" );
147
+
148
+ // spin_lock(&priv->tx_obj_buf.lock);
149
+ // priv->req_cnt = 0;
150
+ // priv->ack_cnt = 0;
151
+ // spin_unlock(&priv->tx_obj_buf.lock);
152
+
142
153
netif_wake_queue (net );
143
154
}
144
155
}
@@ -298,6 +309,9 @@ static int x8h7_can_open(struct net_device *net)
298
309
priv -> tx_obj_buf .tail = 0 ;
299
310
priv -> tx_obj_buf .num_elems = 0 ;
300
311
312
+ priv -> req_cnt = 0 ;
313
+ priv -> ack_cnt = 0 ;
314
+
301
315
priv -> tx_len = 0 ;
302
316
303
317
priv -> wq = alloc_workqueue ("x8h7_can_wq" , WQ_FREEZABLE | WQ_MEM_RECLAIM , 0 );
@@ -379,6 +393,15 @@ static uint8_t tx_obj_buf_num_elems(struct x8h7_can_frame_message_tx_obj_buf * t
379
393
return ret ;
380
394
}
381
395
396
+ static int h7_tx_fifo_fill_level (struct x8h7_can_priv * priv )
397
+ {
398
+ int diff ;
399
+ spin_lock (& priv -> tx_obj_buf .lock );
400
+ diff = (priv -> req_cnt - priv -> ack_cnt );
401
+ spin_unlock (& priv -> tx_obj_buf .lock );
402
+ return diff ;
403
+ }
404
+
382
405
/**
383
406
*/
384
407
static netdev_tx_t x8h7_can_start_xmit (struct sk_buff * skb ,
@@ -396,15 +419,21 @@ static netdev_tx_t x8h7_can_start_xmit(struct sk_buff *skb,
396
419
397
420
if (tx_obj_buf_num_elems (& priv -> tx_obj_buf ) > 0 ) {
398
421
netif_stop_queue (net );
399
- dev_warn (dev , "xmit called while device busy" );
422
+ dev_warn (dev , "xmit called while tx_obj_buf full" );
423
+ return NETDEV_TX_BUSY ;
424
+ }
425
+
426
+ if (h7_tx_fifo_fill_level (priv ) > 0 ) {
427
+ netif_stop_queue (net );
428
+ dev_warn (dev , "xmit called while H7 transmit FIFO full" );
400
429
return NETDEV_TX_BUSY ;
401
430
}
402
431
403
432
frame = (struct can_frame * )skb -> data ;
404
433
x8h7_can_frame_to_tx_obj (frame , & x8h7_can_msg );
405
434
tx_obj_buf_push (& priv -> tx_obj_buf , & x8h7_can_msg );
406
435
407
- can_put_echo_skb (skb , net , 0 );
436
+ // can_put_echo_skb(skb, net, 0);
408
437
409
438
queue_work (priv -> wq , & priv -> work );
410
439
@@ -434,7 +463,7 @@ static void x8h7_can_tx_work_handler(struct work_struct *ws)
434
463
435
464
DBG_PRINT ("\n" );
436
465
437
- while (tx_obj_buf_num_elems (& priv -> tx_obj_buf ) > 0 )
466
+ while (tx_obj_buf_num_elems (& priv -> tx_obj_buf ) > 0 && h7_tx_fifo_fill_level ( priv ) < 1 )
438
467
{
439
468
union x8h7_can_frame_message x8h7_can_msg ;
440
469
tx_obj_buf_pop (& priv -> tx_obj_buf , & x8h7_can_msg );
@@ -448,6 +477,10 @@ static void x8h7_can_tx_work_handler(struct work_struct *ws)
448
477
len += snprintf (data_str + len , sizeof (data_str ) - len , " %02X" , x8h7_can_msg .field .data [i ]);
449
478
DBG_PRINT ("Enqueue CAN frame to H7: id = %08X, len = %d, data = [%s ]\n" , x8h7_can_msg .field .id , x8h7_can_msg .field .len , data_str );
450
479
#endif
480
+
481
+ spin_lock (& priv -> tx_obj_buf .lock );
482
+ priv -> req_cnt ++ ;
483
+ spin_unlock (& priv -> tx_obj_buf .lock );
451
484
}
452
485
x8h7_pkt_send ();
453
486
}
0 commit comments