Commit ae757ccf authored by Martin Jeřábek's avatar Martin Jeřábek

driver: fix priority rotation, frame defs endianity, data endianity (tmp sw fix)

parent e07f794c
...@@ -271,11 +271,11 @@ static int ctucan_start_xmit(struct sk_buff *skb, struct net_device *ndev) ...@@ -271,11 +271,11 @@ static int ctucan_start_xmit(struct sk_buff *skb, struct net_device *ndev)
struct canfd_frame *cf = (struct canfd_frame *)skb->data; struct canfd_frame *cf = (struct canfd_frame *)skb->data;
u32 txb_id; u32 txb_id;
bool ok; bool ok;
netdev_info(ndev, "ctucan_start_xmit");
if (can_dropped_invalid_skb(ndev, skb)) if (can_dropped_invalid_skb(ndev, skb))
return NETDEV_TX_OK; return NETDEV_TX_OK;
/* Check if the TX buffer is full */ /* Check if the TX buffer is full */
if (unlikely(!CTU_CAN_FD_TXTNF(ctu_can_get_status(&priv->p)))) { if (unlikely(!CTU_CAN_FD_TXTNF(ctu_can_get_status(&priv->p)))) {
netif_stop_queue(ndev); netif_stop_queue(ndev);
...@@ -284,6 +284,7 @@ static int ctucan_start_xmit(struct sk_buff *skb, struct net_device *ndev) ...@@ -284,6 +284,7 @@ static int ctucan_start_xmit(struct sk_buff *skb, struct net_device *ndev)
} }
txb_id = priv->txb_head & priv->txb_mask; txb_id = priv->txb_head & priv->txb_mask;
netdev_info(ndev, "ctucan_start_xmit: using TXB#%u", txb_id);
priv->txb_head++; priv->txb_head++;
ok = ctu_can_fd_insert_frame(&priv->p, cf, 0, txb_id, can_is_canfd_skb(skb)); ok = ctu_can_fd_insert_frame(&priv->p, cf, 0, txb_id, can_is_canfd_skb(skb));
if (!ok) { if (!ok) {
...@@ -322,7 +323,7 @@ static int ctucan_rx(struct net_device *ndev) ...@@ -322,7 +323,7 @@ static int ctucan_rx(struct net_device *ndev)
struct sk_buff *skb; struct sk_buff *skb;
u64 ts; u64 ts;
union ctu_can_fd_frame_form_w ffw; union ctu_can_fd_frame_form_w ffw;
netdev_info(ndev, "ctucan_rx"); //netdev_info(ndev, "ctucan_rx");
ffw.u32 = priv->p.read_reg(&priv->p, CTU_CAN_FD_RX_DATA); ffw.u32 = priv->p.read_reg(&priv->p, CTU_CAN_FD_RX_DATA);
...@@ -509,7 +510,7 @@ static int ctucan_rx_poll(struct napi_struct *napi, int quota) ...@@ -509,7 +510,7 @@ static int ctucan_rx_poll(struct napi_struct *napi, int quota)
struct ctucan_priv *priv = netdev_priv(ndev); struct ctucan_priv *priv = netdev_priv(ndev);
int work_done = 0; int work_done = 0;
union ctu_can_fd_int_stat isr, iec; union ctu_can_fd_int_stat isr, iec;
netdev_info(ndev, "ctucan_rx_poll"); //netdev_info(ndev, "ctucan_rx_poll");
iec.u32 = 0; iec.u32 = 0;
iec.s.rbnei = 1; iec.s.rbnei = 1;
...@@ -536,12 +537,12 @@ static int ctucan_rx_poll(struct napi_struct *napi, int quota) ...@@ -536,12 +537,12 @@ static int ctucan_rx_poll(struct napi_struct *napi, int quota)
static void ctucan_rotate_txb_prio(struct net_device *ndev) static void ctucan_rotate_txb_prio(struct net_device *ndev)
{ {
netdev_info(ndev, "ctucan_rotate_txb_prio");
struct ctucan_priv *priv = netdev_priv(ndev); struct ctucan_priv *priv = netdev_priv(ndev);
u32 prio = priv->txb_prio; u32 prio = priv->txb_prio;
u32 nbuffers = priv->txb_mask+1; u32 nbuffersm1 = priv->txb_mask; /* nbuffers - 1 */
prio = (prio << 4) | (prio >> (nbuffers*4)); prio = (prio << 4) | ((prio >> (nbuffersm1*4)) & 0xF);
netdev_info(ndev, "ctucan_rotate_txb_prio: from 0x%08x to 0x%08x", priv->txb_prio, prio);
priv->txb_prio = prio; priv->txb_prio = prio;
priv->p.write_reg(&priv->p, CTU_CAN_FD_TX_PRIORITY, prio); priv->p.write_reg(&priv->p, CTU_CAN_FD_TX_PRIORITY, prio);
} }
...@@ -570,6 +571,7 @@ static void ctucan_tx_interrupt(struct net_device *ndev) ...@@ -570,6 +571,7 @@ static void ctucan_tx_interrupt(struct net_device *ndev)
u32 txb_idx = priv->txb_tail & priv->txb_mask; u32 txb_idx = priv->txb_tail & priv->txb_mask;
u32 status = ctu_can_fd_get_tx_status(&priv->p, txb_idx); u32 status = ctu_can_fd_get_tx_status(&priv->p, txb_idx);
netdev_info(ndev, "TXI: TXB#%u: status 0x%x", txb_idx, status);
switch (status) { switch (status) {
case TXT_TOK: case TXT_TOK:
netdev_info(ndev, "TXT_OK"); netdev_info(ndev, "TXT_OK");
...@@ -882,7 +884,7 @@ static int ctucan_probe(struct platform_device *pdev) ...@@ -882,7 +884,7 @@ static int ctucan_probe(struct platform_device *pdev)
if (ret < 0) if (ret < 0)
goto err; goto err;
*/ */
ntxbufs = 8; ntxbufs = 4;
/* Create a CAN device instance */ /* Create a CAN device instance */
ndev = alloc_candev(sizeof(struct ctucan_priv), ntxbufs); ndev = alloc_candev(sizeof(struct ctucan_priv), ntxbufs);
......
...@@ -597,8 +597,11 @@ void ctu_can_fd_read_rx_frame_ffw(struct ctucanfd_priv *priv, struct canfd_frame ...@@ -597,8 +597,11 @@ void ctu_can_fd_read_rx_frame_ffw(struct ctucanfd_priv *priv, struct canfd_frame
*ts |= ((u64)priv->read_reg(priv, CTU_CAN_FD_RX_DATA) << 32); *ts |= ((u64)priv->read_reg(priv, CTU_CAN_FD_RX_DATA) << 32);
// Data // Data
for (i = 0; i < cf->len; i += 4) for (i = 0; i < cf->len; i += 4) {
*(u32 *)(cf->data + i) = priv->read_reg(priv, CTU_CAN_FD_RX_DATA); u32 data = priv->read_reg(priv, CTU_CAN_FD_RX_DATA);
data = be32_to_cpu(data); // TODO: remove when the core is fixed
*(u32 *)(cf->data + i) = data;
}
} }
enum ctu_can_fd_tx_status_tx1s ctu_can_fd_get_tx_status(struct ctucanfd_priv *priv, u8 buf) enum ctu_can_fd_tx_status_tx1s ctu_can_fd_get_tx_status(struct ctucanfd_priv *priv, u8 buf)
...@@ -742,9 +745,12 @@ bool ctu_can_fd_insert_frame(struct ctucanfd_priv *priv, const struct canfd_fram ...@@ -742,9 +745,12 @@ bool ctu_can_fd_insert_frame(struct ctucanfd_priv *priv, const struct canfd_fram
if (!(cf->can_id & CAN_RTR_FLAG)) { if (!(cf->can_id & CAN_RTR_FLAG)) {
// be32_to_cpup? // be32_to_cpup?
for (i = 0; i < cf->len; i += 4) for (i = 0; i < cf->len; i += 4) {
u32 data = *(u32 *)(cf->data + i);
data = cpu_to_be32(data); // TODO: remove when the core is fixed
ctu_can_fd_write_txt_buf(priv, buf_base, CTU_CAN_FD_DATA_1_4_W + i, ctu_can_fd_write_txt_buf(priv, buf_base, CTU_CAN_FD_DATA_1_4_W + i,
*(u32 *)(cf->data + i)); data);
}
} }
return true; return true;
......
...@@ -40,7 +40,7 @@ ...@@ -40,7 +40,7 @@
#include <stddef.h> #include <stddef.h>
//#include <linux/types.h> //#include <linux/types.h>
#include <linux/socket.h> #include <linux/socket.h>
#include <arpa/inet.h>
#define likely(x) __builtin_expect(!!(x), 1) #define likely(x) __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect(!!(x), 0) #define unlikely(x) __builtin_expect(!!(x), 0)
#define __iomem volatile #define __iomem volatile
...@@ -112,12 +112,13 @@ static inline u16 ioread16(const void *addr) {return *(const volatile u16*)addr; ...@@ -112,12 +112,13 @@ static inline u16 ioread16(const void *addr) {return *(const volatile u16*)addr;
__attribute__((noinline)) __attribute__((noinline))
static inline u8 ioread8(const void *addr) {return *(const volatile u8*)addr;} static inline u8 ioread8(const void *addr) {return *(const volatile u8*)addr;}
static inline u32 cpu_to_be32(u32 v) {return htonl(v);}
static inline u32 be32_to_cpu(u32 v) {return ntohl(v);}
// TODO: perform actual conversions
__attribute__((noinline)) __attribute__((noinline))
static inline void iowrite32be(u32 value, void *addr) {*(volatile u32*)addr = value;} static inline void iowrite32be(u32 value, void *addr) {*(volatile u32*)addr = cpu_to_be32(value);}
__attribute__((noinline)) __attribute__((noinline))
static inline u32 ioread32be(const void *addr) {return *(const volatile u32*)addr;} static inline u32 ioread32be(const void *addr) {return be32_to_cpu(*(const volatile u32*)addr);}
/* CAN DLC to real data length conversion helpers */ /* CAN DLC to real data length conversion helpers */
u8 can_dlc2len(u8 can_dlc); u8 can_dlc2len(u8 can_dlc);
......
...@@ -59,12 +59,13 @@ unsigned ctu_can_fd_read8(struct ctucanfd_priv *priv, enum ctu_can_fd_regs reg) ...@@ -59,12 +59,13 @@ unsigned ctu_can_fd_read8(struct ctucanfd_priv *priv, enum ctu_can_fd_regs reg)
unsigned ctu_can_fd_read16(struct ctucanfd_priv *priv, enum ctu_can_fd_regs reg) { unsigned ctu_can_fd_read16(struct ctucanfd_priv *priv, enum ctu_can_fd_regs reg) {
return priv->read_reg(priv, (enum ctu_can_fd_regs)(reg & ~1)) >> (8 * (reg & 1)); return priv->read_reg(priv, (enum ctu_can_fd_regs)(reg & ~1)) >> (8 * (reg & 1));
} }
/*
void ctu_can_fd_write8(struct ctucanfd_priv *priv, enum ctu_can_fd_regs reg, uint8_t val) { void ctu_can_fd_write8(struct ctucanfd_priv *priv, enum ctu_can_fd_regs reg, uint8_t val) {
iowrite8(val, (uint8_t*)priv->mem_base + reg); iowrite8(val, (uint8_t*)priv->mem_base + reg);
} }
void ctu_can_fd_write16(struct ctucanfd_priv *priv, enum ctu_can_fd_regs reg, uint16_t val) { void ctu_can_fd_write16(struct ctucanfd_priv *priv, enum ctu_can_fd_regs reg, uint16_t val) {
iowrite16(val, (uint8_t*)priv->mem_base + reg); iowrite16(val, (uint8_t*)priv->mem_base + reg);
} }*/
int main(int argc, char *argv[]) int main(int argc, char *argv[])
...@@ -135,7 +136,7 @@ int main(int argc, char *argv[]) ...@@ -135,7 +136,7 @@ int main(int argc, char *argv[])
priv->write_reg = ctu_can_fd_write32; priv->write_reg = ctu_can_fd_write32;
union ctu_can_fd_device_id_version reg; union ctu_can_fd_device_id_version reg;
reg.u32 = ctu_can_fd_read32(priv, CTU_CAN_FD_DEVICE_ID); reg.u32 = priv->read_reg(priv, CTU_CAN_FD_DEVICE_ID);
printf("DevID: 0x%08x, should be 0x%08x\n", reg.s.device_id, CTU_CAN_FD_ID); printf("DevID: 0x%08x, should be 0x%08x\n", reg.s.device_id, CTU_CAN_FD_ID);
...@@ -150,8 +151,8 @@ int main(int argc, char *argv[]) ...@@ -150,8 +151,8 @@ int main(int argc, char *argv[])
printf("NOT RESETTING!\n"); //printf("NOT RESETTING!\n");
//ctu_can_fd_reset(priv); ctu_can_fd_reset(priv);
{ {
union ctu_can_fd_mode_command_status_settings mode; union ctu_can_fd_mode_command_status_settings mode;
...@@ -166,7 +167,7 @@ int main(int argc, char *argv[]) ...@@ -166,7 +167,7 @@ int main(int argc, char *argv[])
nd.can.clock.freq = 100000000; nd.can.clock.freq = 100000000;
struct can_bittiming nom_timing = { struct can_bittiming nom_timing = {
.bitrate = 500000, .bitrate = 1000000,
}; };
res = can_get_bittiming(&nd, &nom_timing, res = can_get_bittiming(&nd, &nom_timing,
&ctu_can_fd_bit_timing_max, &ctu_can_fd_bit_timing_max,
...@@ -200,9 +201,10 @@ int main(int argc, char *argv[]) ...@@ -200,9 +201,10 @@ int main(int argc, char *argv[])
if (do_transmit) { if (do_transmit) {
struct canfd_frame txf; struct canfd_frame txf;
txf.can_id = 0x123; txf.can_id = 0x1FF;
txf.flags = 0; txf.flags = 0;
u8 d[] = {0xde, 0xad, 0xbe, 0xef}; //u8 d[] = {0xde, 0xad, 0xbe, 0xef};
u8 d[] = {0xDE, 0xAD, 0xBE, 0xEF};
memcpy(txf.data, d, sizeof(d)); memcpy(txf.data, d, sizeof(d));
txf.len = sizeof(d); txf.len = sizeof(d);
...@@ -210,6 +212,7 @@ int main(int argc, char *argv[]) ...@@ -210,6 +212,7 @@ int main(int argc, char *argv[])
if (!res) if (!res)
printf("TX failed\n"); printf("TX failed\n");
ctu_can_fd_txt_set_rdy(priv, CTU_CAN_FD_TXT_BUFFER_1); ctu_can_fd_txt_set_rdy(priv, CTU_CAN_FD_TXT_BUFFER_1);
return 0;
} }
while (1) { while (1) {
...@@ -229,16 +232,22 @@ int main(int argc, char *argv[]) ...@@ -229,16 +232,22 @@ int main(int argc, char *argv[])
printf("\n"); printf("\n");
/*
while (rxsz--) {
u32 data = priv->read_reg(priv, CTU_CAN_FD_RX_DATA);
printf(" 0x%08x\n", data);
}
*/
if (nrxf || rxsz) { if (nrxf || rxsz) {
struct canfd_frame cf; struct canfd_frame cf;
u64 ts; u64 ts;
ctu_can_fd_read_rx_frame(priv, &cf, &ts); ctu_can_fd_read_rx_frame(priv, &cf, &ts);
printf("#%x [%u]", cf.can_id, cf.len); printf("%llu: #%x [%u]", ts, cf.can_id, cf.len);
for (int i=0; i<cf.len; ++i) for (int i=0; i<cf.len; ++i)
printf(" %02x", cf.data[i]); printf(" %02x", cf.data[i]);
printf("\n"); printf("\n");
} }
usleep(1000000); usleep(1000000);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment