diff options
author | Tomoya <tomoya-linux@dsn.okisemi.com> | 2010-12-12 15:24:09 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-12-13 15:24:19 -0500 |
commit | 8ac9702b9d5d81b819fc7d6b4f6abad22af01f3c (patch) | |
tree | 7301e2e3033cad0fcec89c17996c4adc9185212b /drivers/net | |
parent | e489ccebf14657774fd877dc841b458703730586 (diff) |
pch_can: Fix endianness issue
there is endianness issue both Tx and Rx.
Currently, data is set like below.
Register:
MSB--LSB
x x D0 D1
x x D2 D3
x x D4 D5
x x D6 D7
But Data to be sent must be set like below.
Register:
MSB--LSB
x x D1 D0
x x D3 D2
x x D5 D4
x x D7 D6 (x means reserved area.)
Signed-off-by: Tomoya MORINAGA <tomoya-linux@dsn.okisemi.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/can/pch_can.c | 47 |
1 files changed, 20 insertions, 27 deletions
diff --git a/drivers/net/can/pch_can.c b/drivers/net/can/pch_can.c index 0b6d4f490296..210957f093bb 100644 --- a/drivers/net/can/pch_can.c +++ b/drivers/net/can/pch_can.c | |||
@@ -138,10 +138,7 @@ struct pch_can_if_regs { | |||
138 | u32 id1; | 138 | u32 id1; |
139 | u32 id2; | 139 | u32 id2; |
140 | u32 mcont; | 140 | u32 mcont; |
141 | u32 dataa1; | 141 | u32 data[4]; |
142 | u32 dataa2; | ||
143 | u32 datab1; | ||
144 | u32 datab2; | ||
145 | u32 rsv[13]; | 142 | u32 rsv[13]; |
146 | }; | 143 | }; |
147 | 144 | ||
@@ -424,10 +421,10 @@ static void pch_can_clear_buffers(struct pch_can_priv *priv) | |||
424 | iowrite32(0x0, &priv->regs->ifregs[0].id1); | 421 | iowrite32(0x0, &priv->regs->ifregs[0].id1); |
425 | iowrite32(0x0, &priv->regs->ifregs[0].id2); | 422 | iowrite32(0x0, &priv->regs->ifregs[0].id2); |
426 | iowrite32(0x0, &priv->regs->ifregs[0].mcont); | 423 | iowrite32(0x0, &priv->regs->ifregs[0].mcont); |
427 | iowrite32(0x0, &priv->regs->ifregs[0].dataa1); | 424 | iowrite32(0x0, &priv->regs->ifregs[0].data[0]); |
428 | iowrite32(0x0, &priv->regs->ifregs[0].dataa2); | 425 | iowrite32(0x0, &priv->regs->ifregs[0].data[1]); |
429 | iowrite32(0x0, &priv->regs->ifregs[0].datab1); | 426 | iowrite32(0x0, &priv->regs->ifregs[0].data[2]); |
430 | iowrite32(0x0, &priv->regs->ifregs[0].datab2); | 427 | iowrite32(0x0, &priv->regs->ifregs[0].data[3]); |
431 | iowrite32(PCH_CMASK_RDWR | PCH_CMASK_MASK | | 428 | iowrite32(PCH_CMASK_RDWR | PCH_CMASK_MASK | |
432 | PCH_CMASK_ARB | PCH_CMASK_CTRL, | 429 | PCH_CMASK_ARB | PCH_CMASK_CTRL, |
433 | &priv->regs->ifregs[0].cmask); | 430 | &priv->regs->ifregs[0].cmask); |
@@ -441,10 +438,10 @@ static void pch_can_clear_buffers(struct pch_can_priv *priv) | |||
441 | iowrite32(0x0, &priv->regs->ifregs[1].id1); | 438 | iowrite32(0x0, &priv->regs->ifregs[1].id1); |
442 | iowrite32(0x0, &priv->regs->ifregs[1].id2); | 439 | iowrite32(0x0, &priv->regs->ifregs[1].id2); |
443 | iowrite32(0x0, &priv->regs->ifregs[1].mcont); | 440 | iowrite32(0x0, &priv->regs->ifregs[1].mcont); |
444 | iowrite32(0x0, &priv->regs->ifregs[1].dataa1); | 441 | iowrite32(0x0, &priv->regs->ifregs[1].data[0]); |
445 | iowrite32(0x0, &priv->regs->ifregs[1].dataa2); | 442 | iowrite32(0x0, &priv->regs->ifregs[1].data[1]); |
446 | iowrite32(0x0, &priv->regs->ifregs[1].datab1); | 443 | iowrite32(0x0, &priv->regs->ifregs[1].data[2]); |
447 | iowrite32(0x0, &priv->regs->ifregs[1].datab2); | 444 | iowrite32(0x0, &priv->regs->ifregs[1].data[3]); |
448 | iowrite32(PCH_CMASK_RDWR | PCH_CMASK_MASK | | 445 | iowrite32(PCH_CMASK_RDWR | PCH_CMASK_MASK | |
449 | PCH_CMASK_ARB | PCH_CMASK_CTRL, | 446 | PCH_CMASK_ARB | PCH_CMASK_CTRL, |
450 | &priv->regs->ifregs[1].cmask); | 447 | &priv->regs->ifregs[1].cmask); |
@@ -707,12 +704,13 @@ static int pch_can_rx_normal(struct net_device *ndev, u32 int_stat) | |||
707 | canid_t id; | 704 | canid_t id; |
708 | u32 ide; | 705 | u32 ide; |
709 | u32 rtr; | 706 | u32 rtr; |
710 | int i, j, k; | 707 | int i, k; |
711 | int rcv_pkts = 0; | 708 | int rcv_pkts = 0; |
712 | struct sk_buff *skb; | 709 | struct sk_buff *skb; |
713 | struct can_frame *cf; | 710 | struct can_frame *cf; |
714 | struct pch_can_priv *priv = netdev_priv(ndev); | 711 | struct pch_can_priv *priv = netdev_priv(ndev); |
715 | struct net_device_stats *stats = &(priv->ndev->stats); | 712 | struct net_device_stats *stats = &(priv->ndev->stats); |
713 | u16 data_reg; | ||
716 | 714 | ||
717 | /* Reading the messsage object from the Message RAM */ | 715 | /* Reading the messsage object from the Message RAM */ |
718 | iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->ifregs[0].cmask); | 716 | iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->ifregs[0].cmask); |
@@ -778,12 +776,10 @@ static int pch_can_rx_normal(struct net_device *ndev, u32 int_stat) | |||
778 | ((ioread32(&priv->regs->ifregs[0].mcont)) & 0x0f); | 776 | ((ioread32(&priv->regs->ifregs[0].mcont)) & 0x0f); |
779 | } | 777 | } |
780 | 778 | ||
781 | for (i = 0, j = 0; i < cf->can_dlc; j++) { | 779 | for (i = 0; i < cf->can_dlc; i += 2) { |
782 | reg = ioread32(&priv->regs->ifregs[0].dataa1 + j*4); | 780 | data_reg = ioread16(&priv->regs->ifregs[0].data[i / 2]); |
783 | cf->data[i++] = cpu_to_le32(reg & 0xff); | 781 | cf->data[i] = data_reg; |
784 | if (i == cf->can_dlc) | 782 | cf->data[i + 1] = data_reg >> 8; |
785 | break; | ||
786 | cf->data[i++] = cpu_to_le32((reg >> 8) & 0xff); | ||
787 | } | 783 | } |
788 | 784 | ||
789 | netif_receive_skb(skb); | 785 | netif_receive_skb(skb); |
@@ -1016,10 +1012,10 @@ static int pch_close(struct net_device *ndev) | |||
1016 | 1012 | ||
1017 | static netdev_tx_t pch_xmit(struct sk_buff *skb, struct net_device *ndev) | 1013 | static netdev_tx_t pch_xmit(struct sk_buff *skb, struct net_device *ndev) |
1018 | { | 1014 | { |
1019 | int i, j; | ||
1020 | struct pch_can_priv *priv = netdev_priv(ndev); | 1015 | struct pch_can_priv *priv = netdev_priv(ndev); |
1021 | struct can_frame *cf = (struct can_frame *)skb->data; | 1016 | struct can_frame *cf = (struct can_frame *)skb->data; |
1022 | int tx_buffer_avail = 0; | 1017 | int tx_buffer_avail = 0; |
1018 | int i; | ||
1023 | 1019 | ||
1024 | if (can_dropped_invalid_skb(ndev, skb)) | 1020 | if (can_dropped_invalid_skb(ndev, skb)) |
1025 | return NETDEV_TX_OK; | 1021 | return NETDEV_TX_OK; |
@@ -1060,13 +1056,10 @@ static netdev_tx_t pch_xmit(struct sk_buff *skb, struct net_device *ndev) | |||
1060 | if (cf->can_id & CAN_RTR_FLAG) | 1056 | if (cf->can_id & CAN_RTR_FLAG) |
1061 | pch_can_bit_clear(&priv->regs->ifregs[1].id2, PCH_ID2_DIR); | 1057 | pch_can_bit_clear(&priv->regs->ifregs[1].id2, PCH_ID2_DIR); |
1062 | 1058 | ||
1063 | for (i = 0, j = 0; i < cf->can_dlc; j++) { | 1059 | /* Copy data to register */ |
1064 | iowrite32(le32_to_cpu(cf->data[i++]), | 1060 | for (i = 0; i < cf->can_dlc; i += 2) { |
1065 | (&priv->regs->ifregs[1].dataa1) + j*4); | 1061 | iowrite16(cf->data[i] | (cf->data[i + 1] << 8), |
1066 | if (i == cf->can_dlc) | 1062 | &priv->regs->ifregs[1].data[i / 2]); |
1067 | break; | ||
1068 | iowrite32(le32_to_cpu(cf->data[i++] << 8), | ||
1069 | (&priv->regs->ifregs[1].dataa1) + j*4); | ||
1070 | } | 1063 | } |
1071 | 1064 | ||
1072 | can_put_echo_skb(skb, ndev, tx_buffer_avail - PCH_RX_OBJ_END - 1); | 1065 | can_put_echo_skb(skb, ndev, tx_buffer_avail - PCH_RX_OBJ_END - 1); |