diff options
Diffstat (limited to 'drivers/net/can/c_can/c_can.c')
-rw-r--r-- | drivers/net/can/c_can/c_can.c | 49 |
1 files changed, 24 insertions, 25 deletions
diff --git a/drivers/net/can/c_can/c_can.c b/drivers/net/can/c_can/c_can.c index c654efbcc527..7c60e6affe7a 100644 --- a/drivers/net/can/c_can/c_can.c +++ b/drivers/net/can/c_can/c_can.c | |||
@@ -113,9 +113,11 @@ | |||
113 | #define IF_COMM_CLR_NEWDAT IF_COMM_TXRQST | 113 | #define IF_COMM_CLR_NEWDAT IF_COMM_TXRQST |
114 | #define IF_COMM_DATAA BIT(1) | 114 | #define IF_COMM_DATAA BIT(1) |
115 | #define IF_COMM_DATAB BIT(0) | 115 | #define IF_COMM_DATAB BIT(0) |
116 | #define IF_COMM_ALL (IF_COMM_MASK | IF_COMM_ARB | \ | 116 | |
117 | IF_COMM_CONTROL | IF_COMM_TXRQST | \ | 117 | /* TX buffer setup */ |
118 | IF_COMM_DATAA | IF_COMM_DATAB) | 118 | #define IF_COMM_TX (IF_COMM_ARB | IF_COMM_CONTROL | \ |
119 | IF_COMM_TXRQST | \ | ||
120 | IF_COMM_DATAA | IF_COMM_DATAB) | ||
119 | 121 | ||
120 | /* For the low buffers we clear the interrupt bit, but keep newdat */ | 122 | /* For the low buffers we clear the interrupt bit, but keep newdat */ |
121 | #define IF_COMM_RCV_LOW (IF_COMM_MASK | IF_COMM_ARB | \ | 123 | #define IF_COMM_RCV_LOW (IF_COMM_MASK | IF_COMM_ARB | \ |
@@ -152,6 +154,8 @@ | |||
152 | #define IF_MCONT_RCV (IF_MCONT_RXIE | IF_MCONT_UMASK) | 154 | #define IF_MCONT_RCV (IF_MCONT_RXIE | IF_MCONT_UMASK) |
153 | #define IF_MCONT_RCV_EOB (IF_MCONT_RCV | IF_MCONT_EOB) | 155 | #define IF_MCONT_RCV_EOB (IF_MCONT_RCV | IF_MCONT_EOB) |
154 | 156 | ||
157 | #define IF_MCONT_TX (IF_MCONT_TXIE | IF_MCONT_EOB) | ||
158 | |||
155 | /* | 159 | /* |
156 | * Use IF1 for RX and IF2 for TX | 160 | * Use IF1 for RX and IF2 for TX |
157 | */ | 161 | */ |
@@ -290,40 +294,35 @@ static inline void c_can_object_put(struct net_device *dev, int iface, | |||
290 | c_can_obj_update(dev, iface, cmd | IF_COMM_WR, obj); | 294 | c_can_obj_update(dev, iface, cmd | IF_COMM_WR, obj); |
291 | } | 295 | } |
292 | 296 | ||
293 | static void c_can_write_msg_object(struct net_device *dev, | 297 | static void c_can_write_msg_object(struct net_device *dev, int iface, |
294 | int iface, struct can_frame *frame, int objno) | 298 | struct can_frame *frame, int obj) |
295 | { | 299 | { |
296 | int i; | ||
297 | u16 flags = 0; | ||
298 | unsigned int id; | ||
299 | struct c_can_priv *priv = netdev_priv(dev); | 300 | struct c_can_priv *priv = netdev_priv(dev); |
300 | 301 | u16 ctrl = IF_MCONT_TX | frame->can_dlc; | |
301 | if (!(frame->can_id & CAN_RTR_FLAG)) | 302 | u32 arb = IF_ARB_MSGVAL << 16; |
302 | flags |= IF_ARB_TRANSMIT; | 303 | int i; |
303 | 304 | ||
304 | if (frame->can_id & CAN_EFF_FLAG) { | 305 | if (frame->can_id & CAN_EFF_FLAG) { |
305 | id = frame->can_id & CAN_EFF_MASK; | 306 | arb |= frame->can_id & CAN_EFF_MASK; |
306 | flags |= IF_ARB_MSGXTD; | 307 | arb |= IF_ARB_MSGXTD << 16; |
307 | } else | 308 | } else { |
308 | id = ((frame->can_id & CAN_SFF_MASK) << 18); | 309 | arb |= (frame->can_id & CAN_SFF_MASK) << 18; |
310 | } | ||
309 | 311 | ||
310 | flags |= IF_ARB_MSGVAL; | 312 | if (!(frame->can_id & CAN_RTR_FLAG)) |
313 | arb |= IF_ARB_TRANSMIT << 16; | ||
314 | |||
315 | priv->write_reg(priv, C_CAN_IFACE(ARB1_REG, iface), arb); | ||
316 | priv->write_reg(priv, C_CAN_IFACE(ARB2_REG, iface), arb >> 16); | ||
311 | 317 | ||
312 | priv->write_reg(priv, C_CAN_IFACE(ARB1_REG, iface), | 318 | priv->write_reg(priv, C_CAN_IFACE(MSGCTRL_REG, iface), ctrl); |
313 | IFX_WRITE_LOW_16BIT(id)); | ||
314 | priv->write_reg(priv, C_CAN_IFACE(ARB2_REG, iface), flags | | ||
315 | IFX_WRITE_HIGH_16BIT(id)); | ||
316 | 319 | ||
317 | for (i = 0; i < frame->can_dlc; i += 2) { | 320 | for (i = 0; i < frame->can_dlc; i += 2) { |
318 | priv->write_reg(priv, C_CAN_IFACE(DATA1_REG, iface) + i / 2, | 321 | priv->write_reg(priv, C_CAN_IFACE(DATA1_REG, iface) + i / 2, |
319 | frame->data[i] | (frame->data[i + 1] << 8)); | 322 | frame->data[i] | (frame->data[i + 1] << 8)); |
320 | } | 323 | } |
321 | 324 | ||
322 | /* enable interrupt for this message object */ | 325 | c_can_object_put(dev, iface, obj, IF_COMM_TX); |
323 | priv->write_reg(priv, C_CAN_IFACE(MSGCTRL_REG, iface), | ||
324 | IF_MCONT_TXIE | IF_MCONT_TXRQST | IF_MCONT_EOB | | ||
325 | frame->can_dlc); | ||
326 | c_can_object_put(dev, iface, objno, IF_COMM_ALL); | ||
327 | } | 326 | } |
328 | 327 | ||
329 | static inline void c_can_activate_all_lower_rx_msg_obj(struct net_device *dev, | 328 | static inline void c_can_activate_all_lower_rx_msg_obj(struct net_device *dev, |