Skip to content

Commit b2e556d

Browse files
aentingerMaxPayne86
authored andcommitted
Fixing numerous issues - now we have again a single transmit buffer CAN pipeline.
1 parent a02d938 commit b2e556d

File tree

3 files changed

+86
-63
lines changed

3 files changed

+86
-63
lines changed

x8h7_can.c

Lines changed: 48 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ static void x8h7_can_status(struct x8h7_can_priv *priv, u8 intf, u8 eflag)
9797
int can_id = 0;
9898
int data1 = 0;
9999

100-
DBG_PRINT("\n");
100+
//DBG_PRINT("\n");
101101

102102
if (intf & X8H7_CAN_STS_INT_ERR)
103103
{
@@ -120,12 +120,25 @@ static void x8h7_can_status(struct x8h7_can_priv *priv, u8 intf, u8 eflag)
120120
}
121121
}
122122

123-
if (intf & X8H7_CAN_STS_INT_TX) {
123+
if (intf & X8H7_CAN_STS_INT_TX_COMPLETE) {
124+
DBG_PRINT("TX COMPLETE");
124125
net->stats.tx_packets++;
125126
net->stats.tx_bytes += priv->tx_len;
126127
priv->tx_len = 0;
127128
can_led_event(net, CAN_LED_EVENT_TX);
128-
//can_get_echo_skb(net, 0);
129+
can_get_echo_skb(net, 0);
130+
netif_wake_queue(net);
131+
}
132+
133+
if (intf & X8H7_CAN_STS_INT_TX_ABORT_COMPLETE)
134+
{
135+
DBG_PRINT("TX ABORT COMPLETE");
136+
netif_wake_queue(net);
137+
}
138+
139+
if (intf & X8H7_CAN_STS_INT_TX_FIFO_EMPTY)
140+
{
141+
DBG_PRINT("TX FIFO EMPTY");
129142
netif_wake_queue(net);
130143
}
131144
}
@@ -348,56 +361,65 @@ static int x8h7_can_stop(struct net_device *net)
348361
return 0;
349362
}
350363

351-
/**
352-
*/
353-
static int x8h7_can_frame_message_tx_obj_num_elems(struct x8h7_can_frame_message_tx_obj_buf * tx_obj_buf)
364+
static void tx_obj_buf_push(struct x8h7_can_frame_message_tx_obj_buf * tx_obj_buf, union x8h7_can_frame_message const * x8h7_can_msg)
354365
{
355-
uint8_t num_elems = 0;
356-
357366
spin_lock(&tx_obj_buf->lock);
358-
num_elems = tx_obj_buf->num_elems;
367+
memcpy(tx_obj_buf->data + tx_obj_buf->head, x8h7_can_msg, sizeof(x8h7_can_msg->buf));
368+
tx_obj_buf->head = (tx_obj_buf->head + 1) % X8H7_TX_FIFO_SIZE;
369+
tx_obj_buf->num_elems++;
359370
spin_unlock(&tx_obj_buf->lock);
371+
}
360372

361-
return num_elems;
373+
static uint8_t tx_obj_buf_num_elems(struct x8h7_can_frame_message_tx_obj_buf * tx_obj_buf)
374+
{
375+
uint8_t ret;
376+
spin_lock(&tx_obj_buf->lock);
377+
ret = tx_obj_buf->num_elems;
378+
spin_unlock(&tx_obj_buf->lock);
379+
return ret;
362380
}
363381

364382
/**
365383
*/
366384
static netdev_tx_t x8h7_can_start_xmit(struct sk_buff *skb,
367385
struct net_device *net)
368386
{
369-
struct x8h7_can_priv *priv = netdev_priv(net);
370-
const struct device *dev = priv->dev;
371-
struct can_frame *frame;
372-
387+
struct x8h7_can_priv *priv = netdev_priv(net);
388+
const struct device *dev = priv->dev;
389+
struct can_frame *frame;
390+
union x8h7_can_frame_message x8h7_can_msg;
373391

374392
DBG_PRINT("\n");
375393

376394
if (can_dropped_invalid_skb(net, skb))
377395
return NETDEV_TX_OK;
378396

379-
if (x8h7_can_frame_message_tx_obj_num_elems(&priv->tx_obj_buf) == X8H7_TX_FIFO_SIZE) {
397+
if (tx_obj_buf_num_elems(&priv->tx_obj_buf) > 0) {
380398
netif_stop_queue(net);
381-
dev_warn(dev, "hard_xmit called while tx fifo is full\n");
399+
dev_warn(dev, "xmit called while device busy");
382400
return NETDEV_TX_BUSY;
383401
}
384402

385-
spin_lock(&priv->tx_obj_buf.lock);
386-
387403
frame = (struct can_frame *)skb->data;
388-
x8h7_can_frame_to_tx_obj(frame, priv->tx_obj_buf.data + priv->tx_obj_buf.head);
389-
priv->tx_obj_buf.head = (priv->tx_obj_buf.head + 1) % X8H7_TX_FIFO_SIZE;
390-
priv->tx_obj_buf.num_elems++;
404+
x8h7_can_frame_to_tx_obj(frame, &x8h7_can_msg);
405+
tx_obj_buf_push(&priv->tx_obj_buf, &x8h7_can_msg);
391406

392-
spin_unlock(&priv->tx_obj_buf.lock);
393-
394-
//can_put_echo_skb(skb, net, 0);
407+
can_put_echo_skb(skb, net, 0);
395408

396409
queue_work(priv->wq, &priv->work);
397410

398411
return NETDEV_TX_OK;
399412
}
400413

414+
static void tx_obj_buf_pop(struct x8h7_can_frame_message_tx_obj_buf * tx_obj_buf, union x8h7_can_frame_message * x8h7_can_msg)
415+
{
416+
spin_lock(&tx_obj_buf->lock);
417+
memcpy(x8h7_can_msg, tx_obj_buf->data + tx_obj_buf->tail, sizeof(x8h7_can_msg->buf));
418+
tx_obj_buf->tail = (tx_obj_buf->tail + 1) % X8H7_TX_FIFO_SIZE;
419+
tx_obj_buf->num_elems--;
420+
spin_unlock(&tx_obj_buf->lock);
421+
}
422+
401423
/**
402424
*/
403425
static void x8h7_can_tx_work_handler(struct work_struct *ws)
@@ -412,33 +434,21 @@ static void x8h7_can_tx_work_handler(struct work_struct *ws)
412434

413435
DBG_PRINT("\n");
414436

415-
while (x8h7_can_frame_message_tx_obj_num_elems(&priv->tx_obj_buf) > 0)
437+
while (tx_obj_buf_num_elems(&priv->tx_obj_buf) > 0)
416438
{
417439
union x8h7_can_frame_message x8h7_can_msg;
418-
419-
spin_lock(&priv->tx_obj_buf.lock);
420-
421-
memcpy(&x8h7_can_msg,
422-
priv->tx_obj_buf.data + priv->tx_obj_buf.tail,
423-
sizeof(x8h7_can_msg));
424-
priv->tx_obj_buf.tail = (priv->tx_obj_buf.tail + 1) % X8H7_TX_FIFO_SIZE;
425-
priv->tx_obj_buf.num_elems--;
426-
427-
spin_unlock(&priv->tx_obj_buf.lock);
428-
440+
tx_obj_buf_pop(&priv->tx_obj_buf, &x8h7_can_msg);
429441
x8h7_pkt_enq(priv->periph,
430442
X8H7_CAN_OC_SEND,
431443
X8H7_CAN_HEADER_SIZE + x8h7_can_msg.field.len, /* Send 4-Byte ID, 1-Byte Length and the required number of data bytes. */
432444
x8h7_can_msg.buf);
433-
434445
#ifdef DEBUG
435446
i = 0; len = 0;
436447
for (i = 0; (i < x8h7_can_msg.field.len) && (len < sizeof(data_str)); i++)
437448
len += snprintf(data_str + len, sizeof(data_str) - len, " %02X", x8h7_can_msg.field.data[i]);
438449
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);
439450
#endif
440451
}
441-
442452
x8h7_pkt_send();
443453
}
444454

x8h7_can.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,11 @@
2727
#define X8H7_CAN_OC_STS 0x40
2828
#define X8H7_CAN_OC_FLT 0x50
2929

30-
#define X8H7_CAN_STS_INT_TX 0x01
31-
#define X8H7_CAN_STS_INT_RX 0x02
32-
#define X8H7_CAN_STS_INT_ERR 0x04
30+
#define X8H7_CAN_STS_INT_TX_COMPLETE 0x01
31+
#define X8H7_CAN_STS_INT_RX 0x02
32+
#define X8H7_CAN_STS_INT_ERR 0x04
33+
#define X8H7_CAN_STS_INT_TX_ABORT_COMPLETE 0x08
34+
#define X8H7_CAN_STS_INT_TX_FIFO_EMPTY 0x10
3335

3436
#define X8H7_CAN_STS_FLG_RX_OVR 0x01 // Receive Buffer Overflow
3537
#define X8H7_CAN_STS_FLG_TX_BO 0x02 // Bus-Off

x8h7_drv.c

Lines changed: 33 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,8 @@ struct spidev_data {
6060
u8 *x8h7_txb_2;
6161
u8 *x8h7_txb_active;
6262
u8 *x8h7_txb_transfer;
63-
u16 x8h7_txl;
63+
u16 x8h7_txl_active;
64+
u16 x8h7_txl_transfer;
6465
u8 *x8h7_rxb;
6566
};
6667

@@ -202,7 +203,7 @@ int x8h7_pkt_enq(uint8_t peripheral, uint8_t opcode, uint16_t size, void *data)
202203
}
203204
hdr->size += sizeof(x8h7_subpkt_t) + size;
204205
hdr->checksum = hdr->size ^ 0x5555;
205-
spidev->x8h7_txl = hdr->size;
206+
spidev->x8h7_txl_active = hdr->size;
206207
mutex_unlock(&spidev->txb_lock);
207208
return 0;
208209
}
@@ -325,6 +326,10 @@ static inline int x8h7_pkt_send_priv(int arg)
325326

326327
spidev->x8h7_txb_transfer = spidev->x8h7_txb_active;
327328
spidev->x8h7_txb_active = (spidev->x8h7_txb_active == spidev->x8h7_txb_1) ? spidev->x8h7_txb_2 : spidev->x8h7_txb_1;
329+
memset(spidev->x8h7_txb_active, 0, X8H7_BUF_SIZE);
330+
331+
spidev->x8h7_txl_transfer = spidev->x8h7_txl_active;
332+
spidev->x8h7_txl_active = 0;
328333

329334
mutex_unlock(&spidev->txb_lock);
330335

@@ -337,12 +342,12 @@ static inline int x8h7_pkt_send_priv(int arg)
337342

338343
hdr = (x8h7_pkthdr_t*)spidev->x8h7_rxb;
339344
if ((hdr->size != 0) && ((hdr->size ^ 0x5555) != hdr->checksum)) {
340-
DBG_ERROR("Out of sync %x %x\n", hdr->size, hdr->checksum);
345+
DBG_ERROR("Out of sync %04x %04x\n", hdr->size, hdr->checksum);
341346
mutex_unlock(&spidev->spi_lock);
342347
return -1;
343348
}
344349

345-
len = max(hdr->size, spidev->x8h7_txl);
350+
len = max(hdr->size, spidev->x8h7_txl_transfer);
346351
if (len == 0) {
347352
DBG_ERROR("Transaction length is zero\n");
348353
x8h7_spi_trx(spidev->spi,
@@ -368,9 +373,7 @@ static inline int x8h7_pkt_send_priv(int arg)
368373
}
369374
}
370375

371-
memset(spidev->x8h7_txb_transfer, 0, X8H7_BUF_SIZE);
372376
memset(spidev->x8h7_rxb, 0, X8H7_BUF_SIZE);
373-
spidev->x8h7_txl = 0;
374377

375378
mutex_unlock(&spidev->spi_lock);
376379
return 0;
@@ -440,20 +443,6 @@ static int x8h7_probe(struct spi_device *spi)
440443

441444
status = 0;
442445

443-
/* Interrupt request */
444-
if (spi->irq > 0) {
445-
int ret;
446-
ret = devm_request_threaded_irq(&spi->dev, spi->irq,
447-
NULL, x8h7_threaded_isr,
448-
IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
449-
"x8h7", spidev);
450-
if (ret) {
451-
DBG_ERROR("Failed request IRQ #%d\n", spi->irq);
452-
status = -ENODEV;
453-
}
454-
DBG_PRINT("IRQ request irq %d OK\n", spi->irq);
455-
}
456-
457446
mutex_init(&spidev->txb_lock);
458447

459448
if (status == 0) {
@@ -472,8 +461,16 @@ static int x8h7_probe(struct spi_device *spi)
472461
}
473462
}
474463

475-
spidev->x8h7_txb_active = spidev->x8h7_txb_1;
476-
spidev->x8h7_txb_transfer = 0;
464+
if (status == 0)
465+
{
466+
memset(spidev->x8h7_txb_1, 0, X8H7_BUF_SIZE);
467+
memset(spidev->x8h7_txb_2, 0, X8H7_BUF_SIZE);
468+
469+
spidev->x8h7_txb_active = spidev->x8h7_txb_1;
470+
spidev->x8h7_txb_transfer = 0;
471+
spidev->x8h7_txl_active = 0;
472+
spidev->x8h7_txl_transfer = 0;
473+
}
477474

478475
if (status == 0) {
479476
spidev->x8h7_rxb = devm_kzalloc(&spi->dev, X8H7_BUF_SIZE, GFP_KERNEL);
@@ -483,6 +480,20 @@ static int x8h7_probe(struct spi_device *spi)
483480
}
484481
}
485482

483+
/* Configure interrupt request */
484+
if (spi->irq > 0) {
485+
int ret;
486+
ret = devm_request_threaded_irq(&spi->dev, spi->irq,
487+
NULL, x8h7_threaded_isr,
488+
IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
489+
"x8h7", spidev);
490+
if (ret) {
491+
DBG_ERROR("Failed request IRQ #%d\n", spi->irq);
492+
status = -ENODEV;
493+
}
494+
DBG_PRINT("IRQ request irq %d OK\n", spi->irq);
495+
}
496+
486497
x8h7_spidev = spidev;
487498

488499
if (status == 0)

0 commit comments

Comments
 (0)