diff options
Diffstat (limited to 'drivers/net/can')
35 files changed, 915 insertions, 902 deletions
diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c index 6efe2745811..f07fa89b5fd 100644 --- a/drivers/net/can/at91_can.c +++ b/drivers/net/can/at91_can.c @@ -420,7 +420,11 @@ static void at91_chip_start(struct net_device *dev) at91_transceiver_switch(priv, 1); /* enable chip */ - at91_write(priv, AT91_MR, AT91_MR_CANEN); + if (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY) + reg_mr = AT91_MR_CANEN | AT91_MR_ABM; + else + reg_mr = AT91_MR_CANEN; + at91_write(priv, AT91_MR, reg_mr); priv->can.state = CAN_STATE_ERROR_ACTIVE; @@ -1190,6 +1194,7 @@ static const struct net_device_ops at91_netdev_ops = { .ndo_open = at91_open, .ndo_stop = at91_close, .ndo_start_xmit = at91_start_xmit, + .ndo_change_mtu = can_change_mtu, }; static ssize_t at91_sysfs_show_mb0_id(struct device *dev, @@ -1341,7 +1346,8 @@ static int at91_can_probe(struct platform_device *pdev) priv->can.bittiming_const = &at91_bittiming_const; priv->can.do_set_mode = at91_set_mode; priv->can.do_get_berr_counter = at91_get_berr_counter; - priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES; + priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES | + CAN_CTRLMODE_LISTENONLY; priv->dev = dev; priv->reg_base = addr; priv->devtype_data = *devtype_data; diff --git a/drivers/net/can/bfin_can.c b/drivers/net/can/bfin_can.c index 8d2b89a12e0..543ecceb33e 100644 --- a/drivers/net/can/bfin_can.c +++ b/drivers/net/can/bfin_can.c @@ -528,6 +528,7 @@ static const struct net_device_ops bfin_can_netdev_ops = { .ndo_open = bfin_can_open, .ndo_stop = bfin_can_close, .ndo_start_xmit = bfin_can_start_xmit, + .ndo_change_mtu = can_change_mtu, }; static int bfin_can_probe(struct platform_device *pdev) diff --git a/drivers/net/can/c_can/c_can.c b/drivers/net/can/c_can/c_can.c index 951bfede8f3..95e04e2002d 100644 --- a/drivers/net/can/c_can/c_can.c +++ b/drivers/net/can/c_can/c_can.c @@ -60,6 +60,8 @@ #define CONTROL_IE BIT(1) #define CONTROL_INIT BIT(0) +#define CONTROL_IRQMSK (CONTROL_EIE | CONTROL_IE | CONTROL_SIE) + /* test register */ #define TEST_RX BIT(7) #define TEST_TX1 BIT(6) @@ -108,21 +110,38 @@ #define IF_COMM_CONTROL BIT(4) #define IF_COMM_CLR_INT_PND BIT(3) #define IF_COMM_TXRQST BIT(2) +#define IF_COMM_CLR_NEWDAT IF_COMM_TXRQST #define IF_COMM_DATAA BIT(1) #define IF_COMM_DATAB BIT(0) -#define IF_COMM_ALL (IF_COMM_MASK | IF_COMM_ARB | \ - IF_COMM_CONTROL | IF_COMM_TXRQST | \ - IF_COMM_DATAA | IF_COMM_DATAB) + +/* TX buffer setup */ +#define IF_COMM_TX (IF_COMM_ARB | IF_COMM_CONTROL | \ + IF_COMM_TXRQST | \ + IF_COMM_DATAA | IF_COMM_DATAB) + +/* For the low buffers we clear the interrupt bit, but keep newdat */ +#define IF_COMM_RCV_LOW (IF_COMM_MASK | IF_COMM_ARB | \ + IF_COMM_CONTROL | IF_COMM_CLR_INT_PND | \ + IF_COMM_DATAA | IF_COMM_DATAB) + +/* For the high buffers we clear the interrupt bit and newdat */ +#define IF_COMM_RCV_HIGH (IF_COMM_RCV_LOW | IF_COMM_CLR_NEWDAT) + + +/* Receive setup of message objects */ +#define IF_COMM_RCV_SETUP (IF_COMM_MASK | IF_COMM_ARB | IF_COMM_CONTROL) + +/* Invalidation of message objects */ +#define IF_COMM_INVAL (IF_COMM_ARB | IF_COMM_CONTROL) /* IFx arbitration */ -#define IF_ARB_MSGVAL BIT(15) -#define IF_ARB_MSGXTD BIT(14) -#define IF_ARB_TRANSMIT BIT(13) +#define IF_ARB_MSGVAL BIT(31) +#define IF_ARB_MSGXTD BIT(30) +#define IF_ARB_TRANSMIT BIT(29) /* IFx message control */ #define IF_MCONT_NEWDAT BIT(15) #define IF_MCONT_MSGLST BIT(14) -#define IF_MCONT_CLR_MSGLST (0 << 14) #define IF_MCONT_INTPND BIT(13) #define IF_MCONT_UMASK BIT(12) #define IF_MCONT_TXIE BIT(11) @@ -132,39 +151,16 @@ #define IF_MCONT_EOB BIT(7) #define IF_MCONT_DLC_MASK 0xf -/* - * IFx register masks: - * allow easy operation on 16-bit registers when the - * argument is 32-bit instead - */ -#define IFX_WRITE_LOW_16BIT(x) ((x) & 0xFFFF) -#define IFX_WRITE_HIGH_16BIT(x) (((x) & 0xFFFF0000) >> 16) +#define IF_MCONT_RCV (IF_MCONT_RXIE | IF_MCONT_UMASK) +#define IF_MCONT_RCV_EOB (IF_MCONT_RCV | IF_MCONT_EOB) -/* message object split */ -#define C_CAN_NO_OF_OBJECTS 32 -#define C_CAN_MSG_OBJ_RX_NUM 16 -#define C_CAN_MSG_OBJ_TX_NUM 16 +#define IF_MCONT_TX (IF_MCONT_TXIE | IF_MCONT_EOB) -#define C_CAN_MSG_OBJ_RX_FIRST 1 -#define C_CAN_MSG_OBJ_RX_LAST (C_CAN_MSG_OBJ_RX_FIRST + \ - C_CAN_MSG_OBJ_RX_NUM - 1) - -#define C_CAN_MSG_OBJ_TX_FIRST (C_CAN_MSG_OBJ_RX_LAST + 1) -#define C_CAN_MSG_OBJ_TX_LAST (C_CAN_MSG_OBJ_TX_FIRST + \ - C_CAN_MSG_OBJ_TX_NUM - 1) - -#define C_CAN_MSG_OBJ_RX_SPLIT 9 -#define C_CAN_MSG_RX_LOW_LAST (C_CAN_MSG_OBJ_RX_SPLIT - 1) - -#define C_CAN_NEXT_MSG_OBJ_MASK (C_CAN_MSG_OBJ_TX_NUM - 1) -#define RECEIVE_OBJECT_BITS 0x0000ffff - -/* status interrupt */ -#define STATUS_INTERRUPT 0x8000 - -/* global interrupt masks */ -#define ENABLE_ALL_INTERRUPTS 1 -#define DISABLE_ALL_INTERRUPTS 0 +/* + * Use IF1 for RX and IF2 for TX + */ +#define IF_RX 0 +#define IF_TX 1 /* minimum timeout for checking BUSY status */ #define MIN_TIMEOUT_VALUE 6 @@ -185,6 +181,7 @@ enum c_can_lec_type { LEC_BIT0_ERROR, LEC_CRC_ERROR, LEC_UNUSED, + LEC_MASK = LEC_UNUSED, }; /* @@ -240,210 +237,151 @@ static inline void c_can_reset_ram(const struct c_can_priv *priv, bool enable) priv->raminit(priv, enable); } -static inline int get_tx_next_msg_obj(const struct c_can_priv *priv) -{ - return (priv->tx_next & C_CAN_NEXT_MSG_OBJ_MASK) + - C_CAN_MSG_OBJ_TX_FIRST; -} - -static inline int get_tx_echo_msg_obj(const struct c_can_priv *priv) +static void c_can_irq_control(struct c_can_priv *priv, bool enable) { - return (priv->tx_echo & C_CAN_NEXT_MSG_OBJ_MASK) + - C_CAN_MSG_OBJ_TX_FIRST; -} - -static u32 c_can_read_reg32(struct c_can_priv *priv, enum reg index) -{ - u32 val = priv->read_reg(priv, index); - val |= ((u32) priv->read_reg(priv, index + 1)) << 16; - return val; -} - -static void c_can_enable_all_interrupts(struct c_can_priv *priv, - int enable) -{ - unsigned int cntrl_save = priv->read_reg(priv, - C_CAN_CTRL_REG); + u32 ctrl = priv->read_reg(priv, C_CAN_CTRL_REG) & ~CONTROL_IRQMSK; if (enable) - cntrl_save |= (CONTROL_SIE | CONTROL_EIE | CONTROL_IE); - else - cntrl_save &= ~(CONTROL_EIE | CONTROL_IE | CONTROL_SIE); + ctrl |= CONTROL_IRQMSK; - priv->write_reg(priv, C_CAN_CTRL_REG, cntrl_save); + priv->write_reg(priv, C_CAN_CTRL_REG, ctrl); } -static inline int c_can_msg_obj_is_busy(struct c_can_priv *priv, int iface) +static void c_can_obj_update(struct net_device *dev, int iface, u32 cmd, u32 obj) { - int count = MIN_TIMEOUT_VALUE; + struct c_can_priv *priv = netdev_priv(dev); + int cnt, reg = C_CAN_IFACE(COMREQ_REG, iface); + + priv->write_reg(priv, reg + 1, cmd); + priv->write_reg(priv, reg, obj); - while (count && priv->read_reg(priv, - C_CAN_IFACE(COMREQ_REG, iface)) & - IF_COMR_BUSY) { - count--; + for (cnt = MIN_TIMEOUT_VALUE; cnt; cnt--) { + if (!(priv->read_reg(priv, reg) & IF_COMR_BUSY)) + return; udelay(1); } + netdev_err(dev, "Updating object timed out\n"); - if (!count) - return 1; +} - return 0; +static inline void c_can_object_get(struct net_device *dev, int iface, + u32 obj, u32 cmd) +{ + c_can_obj_update(dev, iface, cmd, obj); } -static inline void c_can_object_get(struct net_device *dev, - int iface, int objno, int mask) +static inline void c_can_object_put(struct net_device *dev, int iface, + u32 obj, u32 cmd) { - struct c_can_priv *priv = netdev_priv(dev); + c_can_obj_update(dev, iface, cmd | IF_COMM_WR, obj); +} - /* - * As per specs, after writting the message object number in the - * IF command request register the transfer b/w interface - * register and message RAM must be complete in 6 CAN-CLK - * period. - */ - priv->write_reg(priv, C_CAN_IFACE(COMMSK_REG, iface), - IFX_WRITE_LOW_16BIT(mask)); - priv->write_reg(priv, C_CAN_IFACE(COMREQ_REG, iface), - IFX_WRITE_LOW_16BIT(objno)); +/* + * Note: According to documentation clearing TXIE while MSGVAL is set + * is not allowed, but works nicely on C/DCAN. And that lowers the I/O + * load significantly. + */ +static void c_can_inval_tx_object(struct net_device *dev, int iface, int obj) +{ + struct c_can_priv *priv = netdev_priv(dev); - if (c_can_msg_obj_is_busy(priv, iface)) - netdev_err(dev, "timed out in object get\n"); + priv->write_reg(priv, C_CAN_IFACE(MSGCTRL_REG, iface), 0); + c_can_object_put(dev, iface, obj, IF_COMM_INVAL); } -static inline void c_can_object_put(struct net_device *dev, - int iface, int objno, int mask) +static void c_can_inval_msg_object(struct net_device *dev, int iface, int obj) { struct c_can_priv *priv = netdev_priv(dev); - /* - * As per specs, after writting the message object number in the - * IF command request register the transfer b/w interface - * register and message RAM must be complete in 6 CAN-CLK - * period. - */ - priv->write_reg(priv, C_CAN_IFACE(COMMSK_REG, iface), - (IF_COMM_WR | IFX_WRITE_LOW_16BIT(mask))); - priv->write_reg(priv, C_CAN_IFACE(COMREQ_REG, iface), - IFX_WRITE_LOW_16BIT(objno)); - - if (c_can_msg_obj_is_busy(priv, iface)) - netdev_err(dev, "timed out in object put\n"); + priv->write_reg(priv, C_CAN_IFACE(ARB1_REG, iface), 0); + priv->write_reg(priv, C_CAN_IFACE(ARB2_REG, iface), 0); + c_can_inval_tx_object(dev, iface, obj); } -static void c_can_write_msg_object(struct net_device *dev, - int iface, struct can_frame *frame, int objno) +static void c_can_setup_tx_object(struct net_device *dev, int iface, + struct can_frame *frame, int idx) { - int i; - u16 flags = 0; - unsigned int id; struct c_can_priv *priv = netdev_priv(dev); - - if (!(frame->can_id & CAN_RTR_FLAG)) - flags |= IF_ARB_TRANSMIT; + u16 ctrl = IF_MCONT_TX | frame->can_dlc; + bool rtr = frame->can_id & CAN_RTR_FLAG; + u32 arb = IF_ARB_MSGVAL; + int i; if (frame->can_id & CAN_EFF_FLAG) { - id = frame->can_id & CAN_EFF_MASK; - flags |= IF_ARB_MSGXTD; - } else - id = ((frame->can_id & CAN_SFF_MASK) << 18); + arb |= frame->can_id & CAN_EFF_MASK; + arb |= IF_ARB_MSGXTD; + } else { + arb |= (frame->can_id & CAN_SFF_MASK) << 18; + } - flags |= IF_ARB_MSGVAL; + if (!rtr) + arb |= IF_ARB_TRANSMIT; - priv->write_reg(priv, C_CAN_IFACE(ARB1_REG, iface), - IFX_WRITE_LOW_16BIT(id)); - priv->write_reg(priv, C_CAN_IFACE(ARB2_REG, iface), flags | - IFX_WRITE_HIGH_16BIT(id)); + /* + * If we change the DIR bit, we need to invalidate the buffer + * first, i.e. clear the MSGVAL flag in the arbiter. + */ + if (rtr != (bool)test_bit(idx, &priv->tx_dir)) { + u32 obj = idx + C_CAN_MSG_OBJ_TX_FIRST; - for (i = 0; i < frame->can_dlc; i += 2) { - priv->write_reg(priv, C_CAN_IFACE(DATA1_REG, iface) + i / 2, - frame->data[i] | (frame->data[i + 1] << 8)); + c_can_inval_msg_object(dev, iface, obj); + change_bit(idx, &priv->tx_dir); } - /* enable interrupt for this message object */ - priv->write_reg(priv, C_CAN_IFACE(MSGCTRL_REG, iface), - IF_MCONT_TXIE | IF_MCONT_TXRQST | IF_MCONT_EOB | - frame->can_dlc); - c_can_object_put(dev, iface, objno, IF_COMM_ALL); -} - -static inline void c_can_mark_rx_msg_obj(struct net_device *dev, - int iface, int ctrl_mask, - int obj) -{ - struct c_can_priv *priv = netdev_priv(dev); + priv->write_reg(priv, C_CAN_IFACE(ARB1_REG, iface), arb); + priv->write_reg(priv, C_CAN_IFACE(ARB2_REG, iface), arb >> 16); - priv->write_reg(priv, C_CAN_IFACE(MSGCTRL_REG, iface), - ctrl_mask & ~(IF_MCONT_MSGLST | IF_MCONT_INTPND)); - c_can_object_put(dev, iface, obj, IF_COMM_CONTROL); + priv->write_reg(priv, C_CAN_IFACE(MSGCTRL_REG, iface), ctrl); + for (i = 0; i < frame->can_dlc; i += 2) { + priv->write_reg(priv, C_CAN_IFACE(DATA1_REG, iface) + i / 2, + frame->data[i] | (frame->data[i + 1] << 8)); + } } static inline void c_can_activate_all_lower_rx_msg_obj(struct net_device *dev, - int iface, - int ctrl_mask) + int iface) { int i; - struct c_can_priv *priv = netdev_priv(dev); - - for (i = C_CAN_MSG_OBJ_RX_FIRST; i <= C_CAN_MSG_RX_LOW_LAST; i++) { - priv->write_reg(priv, C_CAN_IFACE(MSGCTRL_REG, iface), - ctrl_mask & ~(IF_MCONT_MSGLST | - IF_MCONT_INTPND | IF_MCONT_NEWDAT)); - c_can_object_put(dev, iface, i, IF_COMM_CONTROL); - } -} - -static inline void c_can_activate_rx_msg_obj(struct net_device *dev, - int iface, int ctrl_mask, - int obj) -{ - struct c_can_priv *priv = netdev_priv(dev); - priv->write_reg(priv, C_CAN_IFACE(MSGCTRL_REG, iface), - ctrl_mask & ~(IF_MCONT_MSGLST | - IF_MCONT_INTPND | IF_MCONT_NEWDAT)); - c_can_object_put(dev, iface, obj, IF_COMM_CONTROL); + for (i = C_CAN_MSG_OBJ_RX_FIRST; i <= C_CAN_MSG_RX_LOW_LAST; i++) + c_can_object_get(dev, iface, i, IF_COMM_CLR_NEWDAT); } -static void c_can_handle_lost_msg_obj(struct net_device *dev, - int iface, int objno) +static int c_can_handle_lost_msg_obj(struct net_device *dev, + int iface, int objno, u32 ctrl) { - struct c_can_priv *priv = netdev_priv(dev); struct net_device_stats *stats = &dev->stats; - struct sk_buff *skb; + struct c_can_priv *priv = netdev_priv(dev); struct can_frame *frame; + struct sk_buff *skb; - netdev_err(dev, "msg lost in buffer %d\n", objno); - - c_can_object_get(dev, iface, objno, IF_COMM_ALL & ~IF_COMM_TXRQST); - - priv->write_reg(priv, C_CAN_IFACE(MSGCTRL_REG, iface), - IF_MCONT_CLR_MSGLST); + ctrl &= ~(IF_MCONT_MSGLST | IF_MCONT_INTPND | IF_MCONT_NEWDAT); + priv->write_reg(priv, C_CAN_IFACE(MSGCTRL_REG, iface), ctrl); + c_can_object_put(dev, iface, objno, IF_COMM_CONTROL); - c_can_object_put(dev, 0, objno, IF_COMM_CONTROL); + stats->rx_errors++; + stats->rx_over_errors++; /* create an error msg */ skb = alloc_can_err_skb(dev, &frame); if (unlikely(!skb)) - return; + return 0; frame->can_id |= CAN_ERR_CRTL; frame->data[1] = CAN_ERR_CRTL_RX_OVERFLOW; - stats->rx_errors++; - stats->rx_over_errors++; netif_receive_skb(skb); + return 1; } -static int c_can_read_msg_object(struct net_device *dev, int iface, int ctrl) +static int c_can_read_msg_object(struct net_device *dev, int iface, u32 ctrl) { - u16 flags, data; - int i; - unsigned int val; - struct c_can_priv *priv = netdev_priv(dev); struct net_device_stats *stats = &dev->stats; - struct sk_buff *skb; + struct c_can_priv *priv = netdev_priv(dev); struct can_frame *frame; + struct sk_buff *skb; + u32 arb, data; skb = alloc_can_skb(dev, &frame); if (!skb) { @@ -453,119 +391,101 @@ static int c_can_read_msg_object(struct net_device *dev, int iface, int ctrl) frame->can_dlc = get_can_dlc(ctrl & 0x0F); - flags = priv->read_reg(priv, C_CAN_IFACE(ARB2_REG, iface)); - val = priv->read_reg(priv, C_CAN_IFACE(ARB1_REG, iface)) | - (flags << 16); + arb = priv->read_reg(priv, C_CAN_IFACE(ARB1_REG, iface)); + arb |= priv->read_reg(priv, C_CAN_IFACE(ARB2_REG, iface)) << 16; - if (flags & IF_ARB_MSGXTD) - frame->can_id = (val & CAN_EFF_MASK) | CAN_EFF_FLAG; + if (arb & IF_ARB_MSGXTD) + frame->can_id = (arb & CAN_EFF_MASK) | CAN_EFF_FLAG; else - frame->can_id = (val >> 18) & CAN_SFF_MASK; + frame->can_id = (arb >> 18) & CAN_SFF_MASK; - if (flags & IF_ARB_TRANSMIT) + if (arb & IF_ARB_TRANSMIT) { frame->can_id |= CAN_RTR_FLAG; - else { - for (i = 0; i < frame->can_dlc; i += 2) { - data = priv->read_reg(priv, - C_CAN_IFACE(DATA1_REG, iface) + i / 2); + } else { + int i, dreg = C_CAN_IFACE(DATA1_REG, iface); + + for (i = 0; i < frame->can_dlc; i += 2, dreg ++) { + data = priv->read_reg(priv, dreg); frame->data[i] = data; frame->data[i + 1] = data >> 8; } } - netif_receive_skb(skb); - stats->rx_packets++; stats->rx_bytes += frame->can_dlc; - can_led_event(dev, CAN_LED_EVENT_RX); - + netif_receive_skb(skb); return 0; } static void c_can_setup_receive_object(struct net_device *dev, int iface, - int objno, unsigned int mask, - unsigned int id, unsigned int mcont) + u32 obj, u32 mask, u32 id, u32 mcont) { struct c_can_priv *priv = netdev_priv(dev); - priv->write_reg(priv, C_CAN_IFACE(MASK1_REG, iface), - IFX_WRITE_LOW_16BIT(mask)); - - /* According to C_CAN documentation, the reserved bit - * in IFx_MASK2 register is fixed 1 - */ - priv->write_reg(priv, C_CAN_IFACE(MASK2_REG, iface), - IFX_WRITE_HIGH_16BIT(mask) | BIT(13)); + mask |= BIT(29); + priv->write_reg(priv, C_CAN_IFACE(MASK1_REG, iface), mask); + priv->write_reg(priv, C_CAN_IFACE(MASK2_REG, iface), mask >> 16); - priv->write_reg(priv, C_CAN_IFACE(ARB1_REG, iface), - IFX_WRITE_LOW_16BIT(id)); - priv->write_reg(priv, C_CAN_IFACE(ARB2_REG, iface), - (IF_ARB_MSGVAL | IFX_WRITE_HIGH_16BIT(id))); + id |= IF_ARB_MSGVAL; + priv->write_reg(priv, C_CAN_IFACE(ARB1_REG, iface), id); + priv->write_reg(priv, C_CAN_IFACE(ARB2_REG, iface), id >> 16); priv->write_reg(priv, C_CAN_IFACE(MSGCTRL_REG, iface), mcont); - c_can_object_put(dev, iface, objno, IF_COMM_ALL & ~IF_COMM_TXRQST); - - netdev_dbg(dev, "obj no:%d, msgval:0x%08x\n", objno, - c_can_read_reg32(priv, C_CAN_MSGVAL1_REG)); -} - -static void c_can_inval_msg_object(struct net_device *dev, int iface, int objno) -{ - struct c_can_priv *priv = netdev_priv(dev); - - priv->write_reg(priv, C_CAN_IFACE(ARB1_REG, iface), 0); - priv->write_reg(priv, C_CAN_IFACE(ARB2_REG, iface), 0); - priv->write_reg(priv, C_CAN_IFACE(MSGCTRL_REG, iface), 0); - - c_can_object_put(dev, iface, objno, IF_COMM_ARB | IF_COMM_CONTROL); - - netdev_dbg(dev, "obj no:%d, msgval:0x%08x\n", objno, - c_can_read_reg32(priv, C_CAN_MSGVAL1_REG)); -} - -static inline int c_can_is_next_tx_obj_busy(struct c_can_priv *priv, int objno) -{ - int val = c_can_read_reg32(priv, C_CAN_TXRQST1_REG); - - /* - * as transmission request register's bit n-1 corresponds to - * message object n, we need to handle the same properly. - */ - if (val & (1 << (objno - 1))) - return 1; - - return 0; + c_can_object_put(dev, iface, obj, IF_COMM_RCV_SETUP); } static netdev_tx_t c_can_start_xmit(struct sk_buff *skb, - struct net_device *dev) + struct net_device *dev) { - u32 msg_obj_no; - struct c_can_priv *priv = netdev_priv(dev); struct can_frame *frame = (struct can_frame *)skb->data; + struct c_can_priv *priv = netdev_priv(dev); + u32 idx, obj; if (can_dropped_invalid_skb(dev, skb)) return NETDEV_TX_OK; - - msg_obj_no = get_tx_next_msg_obj(priv); - - /* prepare message object for transmission */ - c_can_write_msg_object(dev, 0, frame, msg_obj_no); - can_put_echo_skb(skb, dev, msg_obj_no - C_CAN_MSG_OBJ_TX_FIRST); - /* - * we have to stop the queue in case of a wrap around or - * if the next TX message object is still in use + * This is not a FIFO. C/D_CAN sends out the buffers + * prioritized. The lowest buffer number wins. */ - priv->tx_next++; - if (c_can_is_next_tx_obj_busy(priv, get_tx_next_msg_obj(priv)) || - (priv->tx_next & C_CAN_NEXT_MSG_OBJ_MASK) == 0) + idx = fls(atomic_read(&priv->tx_active)); + obj = idx + C_CAN_MSG_OBJ_TX_FIRST; + + /* If this is the last buffer, stop the xmit queue */ + if (idx == C_CAN_MSG_OBJ_TX_NUM - 1) netif_stop_queue(dev); + /* + * Store the message in the interface so we can call + * can_put_echo_skb(). We must do this before we enable + * transmit as we might race against do_tx(). + */ + c_can_setup_tx_object(dev, IF_TX, frame, idx); + priv->dlc[idx] = frame->can_dlc; + can_put_echo_skb(skb, dev, idx); + + /* Update the active bits */ + atomic_add((1 << idx), &priv->tx_active); + /* Start transmission */ + c_can_object_put(dev, IF_TX, obj, IF_COMM_TX); return NETDEV_TX_OK; } +static int c_can_wait_for_ctrl_init(struct net_device *dev, + struct c_can_priv *priv, u32 init) +{ + int retry = 0; + + while (init != (priv->read_reg(priv, C_CAN_CTRL_REG) & CONTROL_INIT)) { + udelay(10); + if (retry++ > 1000) { + netdev_err(dev, "CCTRL: set CONTROL_INIT failed\n"); + return -EIO; + } + } + return 0; +} + static int c_can_set_bittiming(struct net_device *dev) { unsigned int reg_btr, reg_brpe, ctrl_save; @@ -573,6 +493,7 @@ static int c_can_set_bittiming(struct net_device *dev) u32 ten_bit_brp; struct c_can_priv *priv = netdev_priv(dev); const struct can_bittiming *bt = &priv->can.bittiming; + int res; /* c_can provides a 6-bit brp and 4-bit brpe fields */ ten_bit_brp = bt->brp - 1; @@ -590,13 +511,17 @@ static int c_can_set_bittiming(struct net_device *dev) "setting BTR=%04x BRPE=%04x\n", reg_btr, reg_brpe); ctrl_save = priv->read_reg(priv, C_CAN_CTRL_REG); - priv->write_reg(priv, C_CAN_CTRL_REG, - ctrl_save | CONTROL_CCE | CONTROL_INIT); + ctrl_save &= ~CONTROL_INIT; + priv->write_reg(priv, C_CAN_CTRL_REG, CONTROL_CCE | CONTROL_INIT); + res = c_can_wait_for_ctrl_init(dev, priv, CONTROL_INIT); + if (res) + return res; + priv->write_reg(priv, C_CAN_BTR_REG, reg_btr); priv->write_reg(priv, C_CAN_BRPEXT_REG, reg_brpe); priv->write_reg(priv, C_CAN_CTRL_REG, ctrl_save); - return 0; + return c_can_wait_for_ctrl_init(dev, priv, 0); } /* @@ -614,15 +539,14 @@ static void c_can_configure_msg_objects(struct net_device *dev) /* first invalidate all message objects */ for (i = C_CAN_MSG_OBJ_RX_FIRST; i <= C_CAN_NO_OF_OBJECTS; i++) - c_can_inval_msg_object(dev, 0, i); + c_can_inval_msg_object(dev, IF_RX, i); /* setup receive message objects */ for (i = C_CAN_MSG_OBJ_RX_FIRST; i < C_CAN_MSG_OBJ_RX_LAST; i++) - c_can_setup_receive_object(dev, 0, i, 0, 0, - (IF_MCONT_RXIE | IF_MCONT_UMASK) & ~IF_MCONT_EOB); + c_can_setup_receive_object(dev, IF_RX, i, 0, 0, IF_MCONT_RCV); - c_can_setup_receive_object(dev, 0, C_CAN_MSG_OBJ_RX_LAST, 0, 0, - IF_MCONT_EOB | IF_MCONT_RXIE | IF_MCONT_UMASK); + c_can_setup_receive_object(dev, IF_RX, C_CAN_MSG_OBJ_RX_LAST, 0, 0, + IF_MCONT_RCV_EOB); } /* @@ -631,35 +555,27 @@ static void c_can_configure_msg_objects(struct net_device *dev) * - set operating mode * - configure message objects */ -static void c_can_chip_config(struct net_device *dev) +static int c_can_chip_config(struct net_device *dev) { struct c_can_priv *priv = netdev_priv(dev); /* enable automatic retransmission */ - priv->write_reg(priv, C_CAN_CTRL_REG, - CONTROL_ENABLE_AR); + priv->write_reg(priv, C_CAN_CTRL_REG, CONTROL_ENABLE_AR); if ((priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY) && (priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK)) { /* loopback + silent mode : useful for hot self-test */ - priv->write_reg(priv, C_CAN_CTRL_REG, CONTROL_EIE | - CONTROL_SIE | CONTROL_IE | CONTROL_TEST); - priv->write_reg(priv, C_CAN_TEST_REG, - TEST_LBACK | TEST_SILENT); + priv->write_reg(priv, C_CAN_CTRL_REG, CONTROL_TEST); + priv->write_reg(priv, C_CAN_TEST_REG, TEST_LBACK | TEST_SILENT); } else if (priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK) { /* loopback mode : useful for self-test function */ - priv->write_reg(priv, C_CAN_CTRL_REG, CONTROL_EIE | - CONTROL_SIE | CONTROL_IE | CONTROL_TEST); + priv->write_reg(priv, C_CAN_CTRL_REG, CONTROL_TEST); priv->write_reg(priv, C_CAN_TEST_REG, TEST_LBACK); } else if (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY) { /* silent mode : bus-monitoring mode */ - priv->write_reg(priv, C_CAN_CTRL_REG, CONTROL_EIE | - CONTROL_SIE | CONTROL_IE | CONTROL_TEST); + priv->write_reg(priv, C_CAN_CTRL_REG, CONTROL_TEST); priv->write_reg(priv, C_CAN_TEST_REG, TEST_SILENT); - } else - /* normal mode*/ - priv->write_reg(priv, C_CAN_CTRL_REG, - CONTROL_EIE | CONTROL_SIE | CONTROL_IE); + } /* configure message objects */ c_can_configure_msg_objects(dev); @@ -667,43 +583,54 @@ static void c_can_chip_config(struct net_device *dev) /* set a `lec` value so that we can check for updates later */ priv->write_reg(priv, C_CAN_STS_REG, LEC_UNUSED); + /* Clear all internal status */ + atomic_set(&priv->tx_active, 0); + priv->rxmasked = 0; + priv->tx_dir = 0; + /* set bittiming params */ - c_can_set_bittiming(dev); + return c_can_set_bittiming(dev); } -static void c_can_start(struct net_device *dev) +static int c_can_start(struct net_device *dev) { struct c_can_priv *priv = netdev_priv(dev); + int err; /* basic c_can configuration */ - c_can_chip_config(dev); + err = c_can_chip_config(dev); + if (err) + return err; - priv->can.state = CAN_STATE_ERROR_ACTIVE; + /* Setup the command for new messages */ + priv->comm_rcv_high = priv->type != BOSCH_D_CAN ? + IF_COMM_RCV_LOW : IF_COMM_RCV_HIGH; - /* reset tx helper pointers */ - priv->tx_next = priv->tx_echo = 0; + priv->can.state = CAN_STATE_ERROR_ACTIVE; - /* enable status change, error and module interrupts */ - c_can_enable_all_interrupts(priv, ENABLE_ALL_INTERRUPTS); + return 0; } static void c_can_stop(struct net_device *dev) { struct c_can_priv *priv = netdev_priv(dev); - /* disable all interrupts */ - c_can_enable_all_interrupts(priv, DISABLE_ALL_INTERRUPTS); - - /* set the state as STOPPED */ + c_can_irq_control(priv, false); priv->can.state = CAN_STATE_STOPPED; } static int c_can_set_mode(struct net_device *dev, enum can_mode mode) { + struct c_can_priv *priv = netdev_priv(dev); + int err; + switch (mode) { case CAN_MODE_START: - c_can_start(dev); + err = c_can_start(dev); + if (err) + return err; netif_wake_queue(dev); + c_can_irq_control(priv, true); break; default: return -EOPNOTSUPP; @@ -739,46 +666,126 @@ static int c_can_get_berr_counter(const struct net_device *dev, return err; } -/* - * theory of operation: - * - * priv->tx_echo holds the number of the oldest can_frame put for - * transmission into the hardware, but not yet ACKed by the CAN tx - * complete IRQ. - * - * We iterate from priv->tx_echo to priv->tx_next and check if the - * packet has been transmitted, echo it back to the CAN framework. - * If we discover a not yet transmitted packet, stop looking for more. - */ static void c_can_do_tx(struct net_device *dev) { - u32 val; - u32 msg_obj_no; struct c_can_priv *priv = netdev_priv(dev); struct net_device_stats *stats = &dev->stats; + u32 idx, obj, pkts = 0, bytes = 0, pend, clr; + + clr = pend = priv->read_reg(priv, C_CAN_INTPND2_REG); + + while ((idx = ffs(pend))) { + idx--; + pend &= ~(1 << idx); + obj = idx + C_CAN_MSG_OBJ_TX_FIRST; + c_can_inval_tx_object(dev, IF_RX, obj); + can_get_echo_skb(dev, idx); + bytes += priv->dlc[idx]; + pkts++; + } - for (/* nix */; (priv->tx_next - priv->tx_echo) > 0; priv->tx_echo++) { - msg_obj_no = get_tx_echo_msg_obj(priv); - val = c_can_read_reg32(priv, C_CAN_TXRQST1_REG); - if (!(val & (1 << (msg_obj_no - 1)))) { - can_get_echo_skb(dev, - msg_obj_no - C_CAN_MSG_OBJ_TX_FIRST); - c_can_object_get(dev, 0, msg_obj_no, IF_COMM_ALL); - stats->tx_bytes += priv->read_reg(priv, - C_CAN_IFACE(MSGCTRL_REG, 0)) - & IF_MCONT_DLC_MASK; - stats->tx_packets++; - can_led_event(dev, CAN_LED_EVENT_TX); - c_can_inval_msg_object(dev, 0, msg_obj_no); - } else { - break; + /* Clear the bits in the tx_active mask */ + atomic_sub(clr, &priv->tx_active); + + if (clr & (1 << (C_CAN_MSG_OBJ_TX_NUM - 1))) + netif_wake_queue(dev); + + if (pkts) { + stats->tx_bytes += bytes; + stats->tx_packets += pkts; + can_led_event(dev, CAN_LED_EVENT_TX); + } +} + +/* + * If we have a gap in the pending bits, that means we either + * raced with the hardware or failed to readout all upper + * objects in the last run due to quota limit. + */ +static u32 c_can_adjust_pending(u32 pend) +{ + u32 weight, lasts; + + if (pend == RECEIVE_OBJECT_BITS) + return pend; + + /* + * If the last set bit is larger than the number of pending + * bits we have a gap. + */ + weight = hweight32(pend); + lasts = fls(pend); + + /* If the bits are linear, nothing to do */ + if (lasts == weight) + return pend; + + /* + * Find the first set bit after the gap. We walk backwards + * from the last set bit. + */ + for (lasts--; pend & (1 << (lasts - 1)); lasts--); + + return pend & ~((1 << lasts) - 1); +} + +static inline void c_can_rx_object_get(struct net_device *dev, + struct c_can_priv *priv, u32 obj) +{ + c_can_object_get(dev, IF_RX, obj, priv->comm_rcv_high); +} + +static inline void c_can_rx_finalize(struct net_device *dev, + struct c_can_priv *priv, u32 obj) +{ + if (priv->type != BOSCH_D_CAN) + c_can_object_get(dev, IF_RX, obj, IF_COMM_CLR_NEWDAT); +} + +static int c_can_read_objects(struct net_device *dev, struct c_can_priv *priv, + u32 pend, int quota) +{ + u32 pkts = 0, ctrl, obj; + + while ((obj = ffs(pend)) && quota > 0) { + pend &= ~BIT(obj - 1); + + c_can_rx_object_get(dev, priv, obj); + ctrl = priv->read_reg(priv, C_CAN_IFACE(MSGCTRL_REG, IF_RX)); + + if (ctrl & IF_MCONT_MSGLST) { + int n = c_can_handle_lost_msg_obj(dev, IF_RX, obj, ctrl); + + pkts += n; + quota -= n; + continue; } + + /* + * This really should not happen, but this covers some + * odd HW behaviour. Do not remove that unless you + * want to brick your machine. + */ + if (!(ctrl & IF_MCONT_NEWDAT)) + continue; + + /* read the data from the message object */ + c_can_read_msg_object(dev, IF_RX, ctrl); + + c_can_rx_finalize(dev, priv, obj); + + pkts++; + quota--; } - /* restart queue if wrap-up or if queue stalled on last pkt */ - if (((priv->tx_next & C_CAN_NEXT_MSG_OBJ_MASK) != 0) || - ((priv->tx_echo & C_CAN_NEXT_MSG_OBJ_MASK) == 0)) - netif_wake_queue(dev); + return pkts; +} + +static inline u32 c_can_get_pending(struct c_can_priv *priv) +{ + u32 pend = priv->read_reg(priv, C_CAN_NEWDAT1_REG); + + return pend; } /* @@ -790,25 +797,14 @@ static void c_can_do_tx(struct net_device *dev) * has arrived. To work-around this issue, we keep two groups of message * objects whose partitioning is defined by C_CAN_MSG_OBJ_RX_SPLIT. * - * To ensure in-order frame reception we use the following - * approach while re-activating a message object to receive further - * frames: - * - if the current message object number is lower than - * C_CAN_MSG_RX_LOW_LAST, do not clear the NEWDAT bit while clearing - * the INTPND bit. - * - if the current message object number is equal to - * C_CAN_MSG_RX_LOW_LAST then clear the NEWDAT bit of all lower - * receive message objects. - * - if the current message object number is greater than - * C_CAN_MSG_RX_LOW_LAST then clear the NEWDAT bit of - * only this message object. + * We clear the newdat bit right away. + * + * This can result in packet reordering when the readout is slow. */ static int c_can_do_rx_poll(struct net_device *dev, int quota) { - u32 num_rx_pkts = 0; - unsigned int msg_obj, msg_ctrl_save; struct c_can_priv *priv = netdev_priv(dev); - u16 val; + u32 pkts = 0, pend = 0, toread, n; /* * It is faster to read only one 16bit register. This is only possible @@ -817,55 +813,31 @@ static int c_can_do_rx_poll(struct net_device *dev, int quota) BUILD_BUG_ON_MSG(C_CAN_MSG_OBJ_RX_LAST > 16, "Implementation does not support more message objects than 16"); - while (quota > 0 && (val = priv->read_reg(priv, C_CAN_INTPND1_REG))) { - while ((msg_obj = ffs(val)) && quota > 0) { - val &= ~BIT(msg_obj - 1); - - c_can_object_get(dev, 0, msg_obj, IF_COMM_ALL & - ~IF_COMM_TXRQST); - msg_ctrl_save = priv->read_reg(priv, - C_CAN_IFACE(MSGCTRL_REG, 0)); - - if (msg_ctrl_save & IF_MCONT_MSGLST) { - c_can_handle_lost_msg_obj(dev, 0, msg_obj); - num_rx_pkts++; - quota--; - continue; - } - - if (msg_ctrl_save & IF_MCONT_EOB) - return num_rx_pkts; - - if (!(msg_ctrl_save & IF_MCONT_NEWDAT)) - continue; - - /* read the data from the message object */ - c_can_read_msg_object(dev, 0, msg_ctrl_save); - - if (msg_obj < C_CAN_MSG_RX_LOW_LAST) - c_can_mark_rx_msg_obj(dev, 0, - msg_ctrl_save, msg_obj); - else if (msg_obj > C_CAN_MSG_RX_LOW_LAST) - /* activate this msg obj */ - c_can_activate_rx_msg_obj(dev, 0, - msg_ctrl_save, msg_obj); - else if (msg_obj == C_CAN_MSG_RX_LOW_LAST) - /* activate all lower message objects */ - c_can_activate_all_lower_rx_msg_obj(dev, - 0, msg_ctrl_save); - - num_rx_pkts++; - quota--; + while (quota > 0) { + if (!pend) { + pend = c_can_get_pending(priv); + if (!pend) + break; + /* + * If the pending field has a gap, handle the + * bits above the gap first. + */ + toread = c_can_adjust_pending(pend); + } else { + toread = pend; } + /* Remove the bits from pend */ + pend &= ~toread; + /* Read the objects */ + n = c_can_read_objects(dev, priv, toread, quota); + pkts += n; + quota -= n; } - return num_rx_pkts; -} + if (pkts) + can_led_event(dev, CAN_LED_EVENT_RX); -static inline int c_can_has_and_handle_berr(struct c_can_priv *priv) -{ - return (priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING) && - (priv->current_status & LEC_UNUSED); + return pkts; } static int c_can_handle_state_change(struct net_device *dev, @@ -879,6 +851,26 @@ static int c_can_handle_state_change(struct net_device *dev, struct sk_buff *skb; struct can_berr_counter bec; + switch (error_type) { + case C_CAN_ERROR_WARNING: + /* error warning state */ + priv->can.can_stats.error_warning++; + priv->can.state = CAN_STATE_ERROR_WARNING; + break; + case C_CAN_ERROR_PASSIVE: + /* error passive state */ + priv->can.can_stats.error_passive++; + priv->can.state = CAN_STATE_ERROR_PASSIVE; + break; + case C_CAN_BUS_OFF: + /* bus-off state */ + priv->can.state = CAN_STATE_BUS_OFF; + can_bus_off(dev); + break; + default: + break; + } + /* propagate the error condition to the CAN stack */ skb = alloc_can_err_skb(dev, &cf); if (unlikely(!skb)) @@ -892,8 +884,6 @@ static int c_can_handle_state_change(struct net_device *dev, switch (error_type) { case C_CAN_ERROR_WARNING: /* error warning state */ - priv->can.can_stats.error_warning++; - priv->can.state = CAN_STATE_ERROR_WARNING; cf->can_id |= CAN_ERR_CRTL; cf->data[1] = (bec.txerr > bec.rxerr) ? CAN_ERR_CRTL_TX_WARNING : @@ -904,8 +894,6 @@ static int c_can_handle_state_change(struct net_device *dev, break; case C_CAN_ERROR_PASSIVE: /* error passive state */ - priv->can.can_stats.error_passive++; - priv->can.state = CAN_STATE_ERROR_PASSIVE; cf->can_id |= CAN_ERR_CRTL; if (rx_err_passive) cf->data[1] |= CAN_ERR_CRTL_RX_PASSIVE; @@ -917,22 +905,16 @@ static int c_can_handle_state_change(struct net_device *dev, break; case C_CAN_BUS_OFF: /* bus-off state */ - priv->can.state = CAN_STATE_BUS_OFF; cf->can_id |= CAN_ERR_BUSOFF; - /* - * disable all interrupts in bus-off mode to ensure that - * the CPU is not hogged down - */ - c_can_enable_all_interrupts(priv, DISABLE_ALL_INTERRUPTS); can_bus_off(dev); break; default: break; } - netif_receive_skb(skb); stats->rx_packets++; stats->rx_bytes += cf->can_dlc; + netif_receive_skb(skb); return 1; } @@ -953,6 +935,13 @@ static int c_can_handle_bus_err(struct net_device *dev, if (lec_type == LEC_UNUSED || lec_type == LEC_NO_ERROR) return 0; + if (!(priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING)) + return 0; + + /* common for all type of bus errors */ + priv->can.can_stats.bus_error++; + stats->rx_errors++; + /* propagate the error condition to the CAN stack */ skb = alloc_can_err_skb(dev, &cf); if (unlikely(!skb)) @@ -962,10 +951,6 @@ static int c_can_handle_bus_err(struct net_device *dev, * check for 'last error code' which tells us the * type of the last error to occur on the CAN bus */ - - /* common for all type of bus errors */ - priv->can.can_stats.bus_error++; - stats->rx_errors++; cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR; cf->data[2] |= CAN_ERR_PROT_UNSPEC; @@ -1000,95 +985,64 @@ static int c_can_handle_bus_err(struct net_device *dev, break; } - /* set a `lec` value so that we can check for updates later */ - priv->write_reg(priv, C_CAN_STS_REG, LEC_UNUSED); - - netif_receive_skb(skb); stats->rx_packets++; stats->rx_bytes += cf->can_dlc; - + netif_receive_skb(skb); return 1; } static int c_can_poll(struct napi_struct *napi, int quota) { - u16 irqstatus; - int lec_type = 0; - int work_done = 0; struct net_device *dev = napi->dev; struct c_can_priv *priv = netdev_priv(dev); + u16 curr, last = priv->last_status; + int work_done = 0; - irqstatus = priv->irqstatus; - if (!irqstatus) - goto end; + priv->last_status = curr = priv->read_reg(priv, C_CAN_STS_REG); + /* Ack status on C_CAN. D_CAN is self clearing */ + if (priv->type != BOSCH_D_CAN) + priv->write_reg(priv, C_CAN_STS_REG, LEC_UNUSED); - /* status events have the highest priority */ - if (irqstatus == STATUS_INTERRUPT) { - priv->current_status = priv->read_reg(priv, - C_CAN_STS_REG); - - /* handle Tx/Rx events */ - if (priv->current_status & STATUS_TXOK) - priv->write_reg(priv, C_CAN_STS_REG, - priv->current_status & ~STATUS_TXOK); - - if (priv->current_status & STATUS_RXOK) - priv->write_reg(priv, C_CAN_STS_REG, - priv->current_status & ~STATUS_RXOK); - - /* handle state changes */ - if ((priv->current_status & STATUS_EWARN) && - (!(priv->last_status & STATUS_EWARN))) { - netdev_dbg(dev, "entered error warning state\n"); - work_done += c_can_handle_state_change(dev, - C_CAN_ERROR_WARNING); - } - if ((priv->current_status & STATUS_EPASS) && - (!(priv->last_status & STATUS_EPASS))) { - netdev_dbg(dev, "entered error passive state\n"); - work_done += c_can_handle_state_change(dev, - C_CAN_ERROR_PASSIVE); - } - if ((priv->current_status & STATUS_BOFF) && - (!(priv->last_status & STATUS_BOFF))) { - netdev_dbg(dev, "entered bus off state\n"); - work_done += c_can_handle_state_change(dev, - C_CAN_BUS_OFF); - } + /* handle state changes */ + if ((curr & STATUS_EWARN) && (!(last & STATUS_EWARN))) { + netdev_dbg(dev, "entered error warning state\n"); + work_done += c_can_handle_state_change(dev, C_CAN_ERROR_WARNING); + } - /* handle bus recovery events */ - if ((!(priv->current_status & STATUS_BOFF)) && - (priv->last_status & STATUS_BOFF)) { - netdev_dbg(dev, "left bus off state\n"); - priv->can.state = CAN_STATE_ERROR_ACTIVE; - } - if ((!(priv->current_status & STATUS_EPASS)) && - (priv->last_status & STATUS_EPASS)) { - netdev_dbg(dev, "left error passive state\n"); - priv->can.state = CAN_STATE_ERROR_ACTIVE; - } + if ((curr & STATUS_EPASS) && (!(last & STATUS_EPASS))) { + netdev_dbg(dev, "entered error passive state\n"); + work_done += c_can_handle_state_change(dev, C_CAN_ERROR_PASSIVE); + } - priv->last_status = priv->current_status; - - /* handle lec errors on the bus */ - lec_type = c_can_has_and_handle_berr(priv); - if (lec_type) - work_done += c_can_handle_bus_err(dev, lec_type); - } else if ((irqstatus >= C_CAN_MSG_OBJ_RX_FIRST) && - (irqstatus <= C_CAN_MSG_OBJ_RX_LAST)) { - /* handle events corresponding to receive message objects */ - work_done += c_can_do_rx_poll(dev, (quota - work_done)); - } else if ((irqstatus >= C_CAN_MSG_OBJ_TX_FIRST) && - (irqstatus <= C_CAN_MSG_OBJ_TX_LAST)) { - /* handle events corresponding to transmit message objects */ - c_can_do_tx(dev); + if ((curr & STATUS_BOFF) && (!(last & STATUS_BOFF))) { + netdev_dbg(dev, "entered bus off state\n"); + work_done += c_can_handle_state_change(dev, C_CAN_BUS_OFF); + goto end; } + /* handle bus recovery events */ + if ((!(curr & STATUS_BOFF)) && (last & STATUS_BOFF)) { + netdev_dbg(dev, "left bus off state\n"); + priv->can.state = CAN_STATE_ERROR_ACTIVE; + } + if ((!(curr & STATUS_EPASS)) && (last & STATUS_EPASS)) { + netdev_dbg(dev, "left error passive state\n"); + priv->can.state = CAN_STATE_ERROR_ACTIVE; + } + + /* handle lec errors on the bus */ + work_done += c_can_handle_bus_err(dev, curr & LEC_MASK); + + /* Handle Tx/Rx events. We do this unconditionally */ + work_done += c_can_do_rx_poll(dev, (quota - work_done)); + c_can_do_tx(dev); + end: if (work_done < quota) { napi_complete(napi); - /* enable all IRQs */ - c_can_enable_all_interrupts(priv, ENABLE_ALL_INTERRUPTS); + /* enable all IRQs if we are not in bus off state */ + if (priv->can.state != CAN_STATE_BUS_OFF) + c_can_irq_control(priv, true); } return work_done; @@ -1099,12 +1053,11 @@ static irqreturn_t c_can_isr(int irq, void *dev_id) struct net_device *dev = (struct net_device *)dev_id; struct c_can_priv *priv = netdev_priv(dev); - priv->irqstatus = priv->read_reg(priv, C_CAN_INT_REG); - if (!priv->irqstatus) + if (!priv->read_reg(priv, C_CAN_INT_REG)) return IRQ_NONE; /* disable all interrupts and schedule the NAPI */ - c_can_enable_all_interrupts(priv, DISABLE_ALL_INTERRUPTS); + c_can_irq_control(priv, false); napi_schedule(&priv->napi); return IRQ_HANDLED; @@ -1133,17 +1086,22 @@ static int c_can_open(struct net_device *dev) goto exit_irq_fail; } - napi_enable(&priv->napi); + /* start the c_can controller */ + err = c_can_start(dev); + if (err) + goto exit_start_fail; can_led_event(dev, CAN_LED_EVENT_OPEN); - /* start the c_can controller */ - c_can_start(dev); - + napi_enable(&priv->napi); + /* enable status change, error and module interrupts */ + c_can_irq_control(priv, true); netif_start_queue(dev); return 0; +exit_start_fail: + free_irq(dev->irq, dev); exit_irq_fail: close_candev(dev); exit_open_fail: @@ -1234,6 +1192,7 @@ int c_can_power_up(struct net_device *dev) u32 val; unsigned long time_out; struct c_can_priv *priv = netdev_priv(dev); + int ret; if (!(dev->flags & IFF_UP)) return 0; @@ -1260,15 +1219,20 @@ int c_can_power_up(struct net_device *dev) if (time_after(jiffies, time_out)) return -ETIMEDOUT; - c_can_start(dev); + ret = c_can_start(dev); + if (!ret) + c_can_irq_control(priv, true); - return 0; + return ret; } EXPORT_SYMBOL_GPL(c_can_power_up); #endif void free_c_can_dev(struct net_device *dev) { + struct c_can_priv *priv = netdev_priv(dev); + + netif_napi_del(&priv->napi); free_candev(dev); } EXPORT_SYMBOL_GPL(free_c_can_dev); @@ -1277,6 +1241,7 @@ static const struct net_device_ops c_can_netdev_ops = { .ndo_open = c_can_open, .ndo_stop = c_can_close, .ndo_start_xmit = c_can_start_xmit, + .ndo_change_mtu = can_change_mtu, }; int register_c_can_dev(struct net_device *dev) diff --git a/drivers/net/can/c_can/c_can.h b/drivers/net/can/c_can/c_can.h index d2e1c21b143..c56f1b1c11c 100644 --- a/drivers/net/can/c_can/c_can.h +++ b/drivers/net/can/c_can/c_can.h @@ -22,6 +22,23 @@ #ifndef C_CAN_H #define C_CAN_H +/* message object split */ +#define C_CAN_NO_OF_OBJECTS 32 +#define C_CAN_MSG_OBJ_RX_NUM 16 +#define C_CAN_MSG_OBJ_TX_NUM 16 + +#define C_CAN_MSG_OBJ_RX_FIRST 1 +#define C_CAN_MSG_OBJ_RX_LAST (C_CAN_MSG_OBJ_RX_FIRST + \ + C_CAN_MSG_OBJ_RX_NUM - 1) + +#define C_CAN_MSG_OBJ_TX_FIRST (C_CAN_MSG_OBJ_RX_LAST + 1) +#define C_CAN_MSG_OBJ_TX_LAST (C_CAN_MSG_OBJ_TX_FIRST + \ + C_CAN_MSG_OBJ_TX_NUM - 1) + +#define C_CAN_MSG_OBJ_RX_SPLIT 9 +#define C_CAN_MSG_RX_LOW_LAST (C_CAN_MSG_OBJ_RX_SPLIT - 1) +#define RECEIVE_OBJECT_BITS 0x0000ffff + enum reg { C_CAN_CTRL_REG = 0, C_CAN_CTRL_EX_REG, @@ -156,22 +173,21 @@ struct c_can_priv { struct napi_struct napi; struct net_device *dev; struct device *device; - int tx_object; - int current_status; + atomic_t tx_active; + unsigned long tx_dir; int last_status; u16 (*read_reg) (struct c_can_priv *priv, enum reg index); void (*write_reg) (struct c_can_priv *priv, enum reg index, u16 val); void __iomem *base; const u16 *regs; - unsigned long irq_flags; /* for request_irq() */ - unsigned int tx_next; - unsigned int tx_echo; void *priv; /* for board-specific data */ - u16 irqstatus; enum c_can_dev_id type; u32 __iomem *raminit_ctrlreg; - unsigned int instance; + int instance; void (*raminit) (const struct c_can_priv *priv, bool enable); + u32 comm_rcv_high; + u32 rxmasked; + u32 dlc[C_CAN_MSG_OBJ_TX_NUM]; }; struct net_device *alloc_c_can_dev(void); diff --git a/drivers/net/can/c_can/c_can_pci.c b/drivers/net/can/c_can/c_can_pci.c index bce0be54c2f..fe5f6303b58 100644 --- a/drivers/net/can/c_can/c_can_pci.c +++ b/drivers/net/can/c_can/c_can_pci.c @@ -84,8 +84,11 @@ static int c_can_pci_probe(struct pci_dev *pdev, goto out_disable_device; } - pci_set_master(pdev); - pci_enable_msi(pdev); + ret = pci_enable_msi(pdev); + if (!ret) { + dev_info(&pdev->dev, "MSI enabled\n"); + pci_set_master(pdev); + } addr = pci_iomap(pdev, 0, pci_resource_len(pdev, 0)); if (!addr) { @@ -132,6 +135,8 @@ static int c_can_pci_probe(struct pci_dev *pdev, goto out_free_c_can; } + priv->type = c_can_pci_data->type; + /* Configure access to registers */ switch (c_can_pci_data->reg_align) { case C_CAN_REG_ALIGN_32: diff --git a/drivers/net/can/c_can/c_can_platform.c b/drivers/net/can/c_can/c_can_platform.c index d66ac265269..1df0b322d1e 100644 --- a/drivers/net/can/c_can/c_can_platform.c +++ b/drivers/net/can/c_can/c_can_platform.c @@ -37,8 +37,10 @@ #include "c_can.h" -#define CAN_RAMINIT_START_MASK(i) (1 << (i)) - +#define CAN_RAMINIT_START_MASK(i) (0x001 << (i)) +#define CAN_RAMINIT_DONE_MASK(i) (0x100 << (i)) +#define CAN_RAMINIT_ALL_MASK(i) (0x101 << (i)) +static DEFINE_SPINLOCK(raminit_lock); /* * 16-bit c_can registers can be arranged differently in the memory * architecture of different implementations. For example: 16-bit @@ -69,16 +71,41 @@ static void c_can_plat_write_reg_aligned_to_32bit(struct c_can_priv *priv, writew(val, priv->base + 2 * priv->regs[index]); } +static void c_can_hw_raminit_wait(const struct c_can_priv *priv, u32 mask, + u32 val) +{ + /* We look only at the bits of our instance. */ + val &= mask; + while ((readl(priv->raminit_ctrlreg) & mask) != val) + udelay(1); +} + static void c_can_hw_raminit(const struct c_can_priv *priv, bool enable) { - u32 val; - - val = readl(priv->raminit_ctrlreg); - if (enable) - val |= CAN_RAMINIT_START_MASK(priv->instance); - else - val &= ~CAN_RAMINIT_START_MASK(priv->instance); - writel(val, priv->raminit_ctrlreg); + u32 mask = CAN_RAMINIT_ALL_MASK(priv->instance); + u32 ctrl; + + spin_lock(&raminit_lock); + + ctrl = readl(priv->raminit_ctrlreg); + /* We clear the done and start bit first. The start bit is + * looking at the 0 -> transition, but is not self clearing; + * And we clear the init done bit as well. + */ + ctrl &= ~CAN_RAMINIT_START_MASK(priv->instance); + ctrl |= CAN_RAMINIT_DONE_MASK(priv->instance); + writel(ctrl, priv->raminit_ctrlreg); + ctrl &= ~CAN_RAMINIT_DONE_MASK(priv->instance); + c_can_hw_raminit_wait(priv, ctrl, mask); + + if (enable) { + /* Set start bit and wait for the done bit. */ + ctrl |= CAN_RAMINIT_START_MASK(priv->instance); + writel(ctrl, priv->raminit_ctrlreg); + ctrl |= CAN_RAMINIT_DONE_MASK(priv->instance); + c_can_hw_raminit_wait(priv, ctrl, mask); + } + spin_unlock(&raminit_lock); } static struct platform_device_id c_can_id_table[] = { @@ -195,7 +222,7 @@ static int c_can_plat_probe(struct platform_device *pdev) res = platform_get_resource(pdev, IORESOURCE_MEM, 1); priv->raminit_ctrlreg = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(priv->raminit_ctrlreg) || (int)priv->instance < 0) + if (IS_ERR(priv->raminit_ctrlreg) || priv->instance < 0) dev_info(&pdev->dev, "control memory is not used for raminit\n"); else priv->raminit = c_can_hw_raminit; diff --git a/drivers/net/can/cc770/cc770.c b/drivers/net/can/cc770/cc770.c index 0f12abf6591..d8379278d64 100644 --- a/drivers/net/can/cc770/cc770.c +++ b/drivers/net/can/cc770/cc770.c @@ -823,6 +823,7 @@ static const struct net_device_ops cc770_netdev_ops = { .ndo_open = cc770_open, .ndo_stop = cc770_close, .ndo_start_xmit = cc770_start_xmit, + .ndo_change_mtu = can_change_mtu, }; int register_cc770dev(struct net_device *dev) diff --git a/drivers/net/can/dev.c b/drivers/net/can/dev.c index fc59bc6f040..e318e87e2bf 100644 --- a/drivers/net/can/dev.c +++ b/drivers/net/can/dev.c @@ -99,10 +99,10 @@ static int can_update_spt(const struct can_bittiming_const *btc, return 1000 * (tseg + 1 - *tseg2) / (tseg + 1); } -static int can_calc_bittiming(struct net_device *dev, struct can_bittiming *bt) +static int can_calc_bittiming(struct net_device *dev, struct can_bittiming *bt, + const struct can_bittiming_const *btc) { struct can_priv *priv = netdev_priv(dev); - const struct can_bittiming_const *btc = priv->bittiming_const; long rate, best_rate = 0; long best_error = 1000000000, error = 0; int best_tseg = 0, best_brp = 0, brp = 0; @@ -110,9 +110,6 @@ static int can_calc_bittiming(struct net_device *dev, struct can_bittiming *bt) int spt_error = 1000, spt = 0, sampl_pt; u64 v64; - if (!priv->bittiming_const) - return -ENOTSUPP; - /* Use CIA recommended sample points */ if (bt->sample_point) { sampl_pt = bt->sample_point; @@ -204,7 +201,8 @@ static int can_calc_bittiming(struct net_device *dev, struct can_bittiming *bt) return 0; } #else /* !CONFIG_CAN_CALC_BITTIMING */ -static int can_calc_bittiming(struct net_device *dev, struct can_bittiming *bt) +static int can_calc_bittiming(struct net_device *dev, struct can_bittiming *bt, + const struct can_bittiming_const *btc) { netdev_err(dev, "bit-timing calculation not available\n"); return -EINVAL; @@ -217,16 +215,13 @@ static int can_calc_bittiming(struct net_device *dev, struct can_bittiming *bt) * prescaler value brp. You can find more information in the header * file linux/can/netlink.h. */ -static int can_fixup_bittiming(struct net_device *dev, struct can_bittiming *bt) +static int can_fixup_bittiming(struct net_device *dev, struct can_bittiming *bt, + const struct can_bittiming_const *btc) { struct can_priv *priv = netdev_priv(dev); - const struct can_bittiming_const *btc = priv->bittiming_const; int tseg1, alltseg; u64 brp64; - if (!priv->bittiming_const) - return -ENOTSUPP; - tseg1 = bt->prop_seg + bt->phase_seg1; if (!bt->sjw) bt->sjw = 1; @@ -254,26 +249,29 @@ static int can_fixup_bittiming(struct net_device *dev, struct can_bittiming *bt) return 0; } -static int can_get_bittiming(struct net_device *dev, struct can_bittiming *bt) +static int can_get_bittiming(struct net_device *dev, struct can_bittiming *bt, + const struct can_bittiming_const *btc) { - struct can_priv *priv = netdev_priv(dev); int err; /* Check if the CAN device has bit-timing parameters */ - if (priv->bittiming_const) { + if (!btc) + return -EOPNOTSUPP; - /* Non-expert mode? Check if the bitrate has been pre-defined */ - if (!bt->tq) - /* Determine bit-timing parameters */ - err = can_calc_bittiming(dev, bt); - else - /* Check bit-timing params and calculate proper brp */ - err = can_fixup_bittiming(dev, bt); - if (err) - return err; - } + /* + * Depending on the given can_bittiming parameter structure the CAN + * timing parameters are calculated based on the provided bitrate OR + * alternatively the CAN timing parameters (tq, prop_seg, etc.) are + * provided directly which are then checked and fixed up. + */ + if (!bt->tq && bt->bitrate) + err = can_calc_bittiming(dev, bt, btc); + else if (bt->tq && !bt->bitrate) + err = can_fixup_bittiming(dev, bt, btc); + else + err = -EINVAL; - return 0; + return err; } /* @@ -317,7 +315,9 @@ void can_put_echo_skb(struct sk_buff *skb, struct net_device *dev, BUG_ON(idx >= priv->echo_skb_max); /* check flag whether this packet has to be looped back */ - if (!(dev->flags & IFF_ECHO) || skb->pkt_type != PACKET_LOOPBACK) { + if (!(dev->flags & IFF_ECHO) || skb->pkt_type != PACKET_LOOPBACK || + (skb->protocol != htons(ETH_P_CAN) && + skb->protocol != htons(ETH_P_CANFD))) { kfree_skb(skb); return; } @@ -329,7 +329,6 @@ void can_put_echo_skb(struct sk_buff *skb, struct net_device *dev, return; /* make settings for echo to reduce code in irq context */ - skb->protocol = htons(ETH_P_CAN); skb->pkt_type = PACKET_BROADCAST; skb->ip_summed = CHECKSUM_UNNECESSARY; skb->dev = dev; @@ -512,6 +511,30 @@ struct sk_buff *alloc_can_skb(struct net_device *dev, struct can_frame **cf) } EXPORT_SYMBOL_GPL(alloc_can_skb); +struct sk_buff *alloc_canfd_skb(struct net_device *dev, + struct canfd_frame **cfd) +{ + struct sk_buff *skb; + + skb = netdev_alloc_skb(dev, sizeof(struct can_skb_priv) + + sizeof(struct canfd_frame)); + if (unlikely(!skb)) + return NULL; + + skb->protocol = htons(ETH_P_CANFD); + skb->pkt_type = PACKET_BROADCAST; + skb->ip_summed = CHECKSUM_UNNECESSARY; + + can_skb_reserve(skb); + can_skb_prv(skb)->ifindex = dev->ifindex; + + *cfd = (struct canfd_frame *)skb_put(skb, sizeof(struct canfd_frame)); + memset(*cfd, 0, sizeof(struct canfd_frame)); + + return skb; +} +EXPORT_SYMBOL_GPL(alloc_canfd_skb); + struct sk_buff *alloc_can_err_skb(struct net_device *dev, struct can_frame **cf) { struct sk_buff *skb; @@ -572,6 +595,39 @@ void free_candev(struct net_device *dev) EXPORT_SYMBOL_GPL(free_candev); /* + * changing MTU and control mode for CAN/CANFD devices + */ +int can_change_mtu(struct net_device *dev, int new_mtu) +{ + struct can_priv *priv = netdev_priv(dev); + + /* Do not allow changing the MTU while running */ + if (dev->flags & IFF_UP) + return -EBUSY; + + /* allow change of MTU according to the CANFD ability of the device */ + switch (new_mtu) { + case CAN_MTU: + priv->ctrlmode &= ~CAN_CTRLMODE_FD; + break; + + case CANFD_MTU: + if (!(priv->ctrlmode_supported & CAN_CTRLMODE_FD)) + return -EINVAL; + + priv->ctrlmode |= CAN_CTRLMODE_FD; + break; + + default: + return -EINVAL; + } + + dev->mtu = new_mtu; + return 0; +} +EXPORT_SYMBOL_GPL(can_change_mtu); + +/* * Common open function when the device gets opened. * * This function should be called in the open function of the device @@ -581,11 +637,19 @@ int open_candev(struct net_device *dev) { struct can_priv *priv = netdev_priv(dev); - if (!priv->bittiming.tq && !priv->bittiming.bitrate) { + if (!priv->bittiming.bitrate) { netdev_err(dev, "bit-timing not yet defined\n"); return -EINVAL; } + /* For CAN FD the data bitrate has to be >= the arbitration bitrate */ + if ((priv->ctrlmode & CAN_CTRLMODE_FD) && + (!priv->data_bittiming.bitrate || + (priv->data_bittiming.bitrate < priv->bittiming.bitrate))) { + netdev_err(dev, "incorrect/missing data bit-timing\n"); + return -EINVAL; + } + /* Switch carrier on if device was stopped while in bus-off state */ if (!netif_carrier_ok(dev)) netif_carrier_on(dev); @@ -624,6 +688,10 @@ static const struct nla_policy can_policy[IFLA_CAN_MAX + 1] = { = { .len = sizeof(struct can_bittiming_const) }, [IFLA_CAN_CLOCK] = { .len = sizeof(struct can_clock) }, [IFLA_CAN_BERR_COUNTER] = { .len = sizeof(struct can_berr_counter) }, + [IFLA_CAN_DATA_BITTIMING] + = { .len = sizeof(struct can_bittiming) }, + [IFLA_CAN_DATA_BITTIMING_CONST] + = { .len = sizeof(struct can_bittiming_const) }, }; static int can_changelink(struct net_device *dev, @@ -642,9 +710,7 @@ static int can_changelink(struct net_device *dev, if (dev->flags & IFF_UP) return -EBUSY; memcpy(&bt, nla_data(data[IFLA_CAN_BITTIMING]), sizeof(bt)); - if ((!bt.bitrate && !bt.tq) || (bt.bitrate && bt.tq)) - return -EINVAL; - err = can_get_bittiming(dev, &bt); + err = can_get_bittiming(dev, &bt, priv->bittiming_const); if (err) return err; memcpy(&priv->bittiming, &bt, sizeof(bt)); @@ -668,6 +734,12 @@ static int can_changelink(struct net_device *dev, return -EOPNOTSUPP; priv->ctrlmode &= ~cm->mask; priv->ctrlmode |= cm->flags; + + /* CAN_CTRLMODE_FD can only be set when driver supports FD */ + if (priv->ctrlmode & CAN_CTRLMODE_FD) + dev->mtu = CANFD_MTU; + else + dev->mtu = CAN_MTU; } if (data[IFLA_CAN_RESTART_MS]) { @@ -686,6 +758,27 @@ static int can_changelink(struct net_device *dev, return err; } + if (data[IFLA_CAN_DATA_BITTIMING]) { + struct can_bittiming dbt; + + /* Do not allow changing bittiming while running */ + if (dev->flags & IFF_UP) + return -EBUSY; + memcpy(&dbt, nla_data(data[IFLA_CAN_DATA_BITTIMING]), + sizeof(dbt)); + err = can_get_bittiming(dev, &dbt, priv->data_bittiming_const); + if (err) + return err; + memcpy(&priv->data_bittiming, &dbt, sizeof(dbt)); + + if (priv->do_set_data_bittiming) { + /* Finally, set the bit-timing registers */ + err = priv->do_set_data_bittiming(dev); + if (err) + return err; + } + } + return 0; } @@ -694,7 +787,8 @@ static size_t can_get_size(const struct net_device *dev) struct can_priv *priv = netdev_priv(dev); size_t size = 0; - size += nla_total_size(sizeof(struct can_bittiming)); /* IFLA_CAN_BITTIMING */ + if (priv->bittiming.bitrate) /* IFLA_CAN_BITTIMING */ + size += nla_total_size(sizeof(struct can_bittiming)); if (priv->bittiming_const) /* IFLA_CAN_BITTIMING_CONST */ size += nla_total_size(sizeof(struct can_bittiming_const)); size += nla_total_size(sizeof(struct can_clock)); /* IFLA_CAN_CLOCK */ @@ -703,6 +797,10 @@ static size_t can_get_size(const struct net_device *dev) size += nla_total_size(sizeof(u32)); /* IFLA_CAN_RESTART_MS */ if (priv->do_get_berr_counter) /* IFLA_CAN_BERR_COUNTER */ size += nla_total_size(sizeof(struct can_berr_counter)); + if (priv->data_bittiming.bitrate) /* IFLA_CAN_DATA_BITTIMING */ + size += nla_total_size(sizeof(struct can_bittiming)); + if (priv->data_bittiming_const) /* IFLA_CAN_DATA_BITTIMING_CONST */ + size += nla_total_size(sizeof(struct can_bittiming_const)); return size; } @@ -716,19 +814,34 @@ static int can_fill_info(struct sk_buff *skb, const struct net_device *dev) if (priv->do_get_state) priv->do_get_state(dev, &state); - if (nla_put(skb, IFLA_CAN_BITTIMING, - sizeof(priv->bittiming), &priv->bittiming) || + + if ((priv->bittiming.bitrate && + nla_put(skb, IFLA_CAN_BITTIMING, + sizeof(priv->bittiming), &priv->bittiming)) || + (priv->bittiming_const && nla_put(skb, IFLA_CAN_BITTIMING_CONST, sizeof(*priv->bittiming_const), priv->bittiming_const)) || + nla_put(skb, IFLA_CAN_CLOCK, sizeof(cm), &priv->clock) || nla_put_u32(skb, IFLA_CAN_STATE, state) || nla_put(skb, IFLA_CAN_CTRLMODE, sizeof(cm), &cm) || nla_put_u32(skb, IFLA_CAN_RESTART_MS, priv->restart_ms) || + (priv->do_get_berr_counter && !priv->do_get_berr_counter(dev, &bec) && - nla_put(skb, IFLA_CAN_BERR_COUNTER, sizeof(bec), &bec))) + nla_put(skb, IFLA_CAN_BERR_COUNTER, sizeof(bec), &bec)) || + + (priv->data_bittiming.bitrate && + nla_put(skb, IFLA_CAN_DATA_BITTIMING, + sizeof(priv->data_bittiming), &priv->data_bittiming)) || + + (priv->data_bittiming_const && + nla_put(skb, IFLA_CAN_DATA_BITTIMING_CONST, + sizeof(*priv->data_bittiming_const), + priv->data_bittiming_const))) return -EMSGSIZE; + return 0; } diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c index 61376abdab3..f425ec2c783 100644 --- a/drivers/net/can/flexcan.c +++ b/drivers/net/can/flexcan.c @@ -1011,6 +1011,7 @@ static const struct net_device_ops flexcan_netdev_ops = { .ndo_open = flexcan_open, .ndo_stop = flexcan_close, .ndo_start_xmit = flexcan_start_xmit, + .ndo_change_mtu = can_change_mtu, }; static int register_flexcandev(struct net_device *dev) @@ -1132,9 +1133,9 @@ static int flexcan_probe(struct platform_device *pdev) of_id = of_match_device(flexcan_of_match, &pdev->dev); if (of_id) { devtype_data = of_id->data; - } else if (pdev->id_entry->driver_data) { + } else if (platform_get_device_id(pdev)->driver_data) { devtype_data = (struct flexcan_devtype_data *) - pdev->id_entry->driver_data; + platform_get_device_id(pdev)->driver_data; } else { return -ENODEV; } @@ -1201,8 +1202,7 @@ static int flexcan_remove(struct platform_device *pdev) return 0; } -#ifdef CONFIG_PM_SLEEP -static int flexcan_suspend(struct device *device) +static int __maybe_unused flexcan_suspend(struct device *device) { struct net_device *dev = dev_get_drvdata(device); struct flexcan_priv *priv = netdev_priv(dev); @@ -1221,7 +1221,7 @@ static int flexcan_suspend(struct device *device) return 0; } -static int flexcan_resume(struct device *device) +static int __maybe_unused flexcan_resume(struct device *device) { struct net_device *dev = dev_get_drvdata(device); struct flexcan_priv *priv = netdev_priv(dev); @@ -1233,7 +1233,6 @@ static int flexcan_resume(struct device *device) } return flexcan_chip_enable(priv); } -#endif /* CONFIG_PM_SLEEP */ static SIMPLE_DEV_PM_OPS(flexcan_pm_ops, flexcan_suspend, flexcan_resume); diff --git a/drivers/net/can/grcan.c b/drivers/net/can/grcan.c index ab506d6cab3..3fd9fd942c6 100644 --- a/drivers/net/can/grcan.c +++ b/drivers/net/can/grcan.c @@ -1578,6 +1578,7 @@ static const struct net_device_ops grcan_netdev_ops = { .ndo_open = grcan_open, .ndo_stop = grcan_close, .ndo_start_xmit = grcan_start_xmit, + .ndo_change_mtu = can_change_mtu, }; static int grcan_setup_netdev(struct platform_device *ofdev, diff --git a/drivers/net/can/janz-ican3.c b/drivers/net/can/janz-ican3.c index 71594e5676f..2382c04dc78 100644 --- a/drivers/net/can/janz-ican3.c +++ b/drivers/net/can/janz-ican3.c @@ -198,9 +198,6 @@ struct ican3_dev { struct net_device *ndev; struct napi_struct napi; - /* Device for printing */ - struct device *dev; - /* module number */ unsigned int num; @@ -295,7 +292,7 @@ static int ican3_old_recv_msg(struct ican3_dev *mod, struct ican3_msg *msg) xord = locl ^ peer; if ((xord & MSYNC_RB_MASK) == 0x00) { - dev_dbg(mod->dev, "no mbox for reading\n"); + netdev_dbg(mod->ndev, "no mbox for reading\n"); return -ENOMEM; } @@ -340,7 +337,7 @@ static int ican3_old_send_msg(struct ican3_dev *mod, struct ican3_msg *msg) xord = locl ^ peer; if ((xord & MSYNC_WB_MASK) == MSYNC_WB_MASK) { - dev_err(mod->dev, "no mbox for writing\n"); + netdev_err(mod->ndev, "no mbox for writing\n"); return -ENOMEM; } @@ -542,7 +539,7 @@ static int ican3_new_send_msg(struct ican3_dev *mod, struct ican3_msg *msg) memcpy_fromio(&desc, desc_addr, sizeof(desc)); if (!(desc.control & DESC_VALID)) { - dev_dbg(mod->dev, "%s: no free buffers\n", __func__); + netdev_dbg(mod->ndev, "%s: no free buffers\n", __func__); return -ENOMEM; } @@ -573,7 +570,7 @@ static int ican3_new_recv_msg(struct ican3_dev *mod, struct ican3_msg *msg) memcpy_fromio(&desc, desc_addr, sizeof(desc)); if (!(desc.control & DESC_VALID)) { - dev_dbg(mod->dev, "%s: no buffers to recv\n", __func__); + netdev_dbg(mod->ndev, "%s: no buffers to recv\n", __func__); return -ENOMEM; } @@ -883,7 +880,7 @@ static void can_frame_to_ican3(struct ican3_dev *mod, */ static void ican3_handle_idvers(struct ican3_dev *mod, struct ican3_msg *msg) { - dev_dbg(mod->dev, "IDVERS response: %s\n", msg->data); + netdev_dbg(mod->ndev, "IDVERS response: %s\n", msg->data); } static void ican3_handle_msglost(struct ican3_dev *mod, struct ican3_msg *msg) @@ -899,7 +896,7 @@ static void ican3_handle_msglost(struct ican3_dev *mod, struct ican3_msg *msg) * error frame for userspace */ if (msg->spec == MSG_MSGLOST) { - dev_err(mod->dev, "lost %d control messages\n", msg->data[0]); + netdev_err(mod->ndev, "lost %d control messages\n", msg->data[0]); return; } @@ -939,13 +936,13 @@ static int ican3_handle_cevtind(struct ican3_dev *mod, struct ican3_msg *msg) /* we can only handle the SJA1000 part */ if (msg->data[1] != CEVTIND_CHIP_SJA1000) { - dev_err(mod->dev, "unable to handle errors on non-SJA1000\n"); + netdev_err(mod->ndev, "unable to handle errors on non-SJA1000\n"); return -ENODEV; } /* check the message length for sanity */ if (le16_to_cpu(msg->len) < 6) { - dev_err(mod->dev, "error message too short\n"); + netdev_err(mod->ndev, "error message too short\n"); return -EINVAL; } @@ -967,7 +964,7 @@ static int ican3_handle_cevtind(struct ican3_dev *mod, struct ican3_msg *msg) */ if (isrc == CEVTIND_BEI) { int ret; - dev_dbg(mod->dev, "bus error interrupt\n"); + netdev_dbg(mod->ndev, "bus error interrupt\n"); /* TX error */ if (!(ecc & ECC_DIR)) { @@ -983,7 +980,7 @@ static int ican3_handle_cevtind(struct ican3_dev *mod, struct ican3_msg *msg) */ ret = ican3_set_buserror(mod, 1); if (ret) { - dev_err(mod->dev, "unable to re-enable bus-error\n"); + netdev_err(mod->ndev, "unable to re-enable bus-error\n"); return ret; } @@ -998,7 +995,7 @@ static int ican3_handle_cevtind(struct ican3_dev *mod, struct ican3_msg *msg) /* data overrun interrupt */ if (isrc == CEVTIND_DOI || isrc == CEVTIND_LOST) { - dev_dbg(mod->dev, "data overrun interrupt\n"); + netdev_dbg(mod->ndev, "data overrun interrupt\n"); cf->can_id |= CAN_ERR_CRTL; cf->data[1] = CAN_ERR_CRTL_RX_OVERFLOW; stats->rx_over_errors++; @@ -1007,7 +1004,7 @@ static int ican3_handle_cevtind(struct ican3_dev *mod, struct ican3_msg *msg) /* error warning + passive interrupt */ if (isrc == CEVTIND_EI) { - dev_dbg(mod->dev, "error warning + passive interrupt\n"); + netdev_dbg(mod->ndev, "error warning + passive interrupt\n"); if (status & SR_BS) { state = CAN_STATE_BUS_OFF; cf->can_id |= CAN_ERR_BUSOFF; @@ -1088,7 +1085,7 @@ static void ican3_handle_inquiry(struct ican3_dev *mod, struct ican3_msg *msg) complete(&mod->termination_comp); break; default: - dev_err(mod->dev, "received an unknown inquiry response\n"); + netdev_err(mod->ndev, "received an unknown inquiry response\n"); break; } } @@ -1096,7 +1093,7 @@ static void ican3_handle_inquiry(struct ican3_dev *mod, struct ican3_msg *msg) static void ican3_handle_unknown_message(struct ican3_dev *mod, struct ican3_msg *msg) { - dev_warn(mod->dev, "received unknown message: spec 0x%.2x length %d\n", + netdev_warn(mod->ndev, "received unknown message: spec 0x%.2x length %d\n", msg->spec, le16_to_cpu(msg->len)); } @@ -1105,7 +1102,7 @@ static void ican3_handle_unknown_message(struct ican3_dev *mod, */ static void ican3_handle_message(struct ican3_dev *mod, struct ican3_msg *msg) { - dev_dbg(mod->dev, "%s: modno %d spec 0x%.2x len %d bytes\n", __func__, + netdev_dbg(mod->ndev, "%s: modno %d spec 0x%.2x len %d bytes\n", __func__, mod->num, msg->spec, le16_to_cpu(msg->len)); switch (msg->spec) { @@ -1406,7 +1403,7 @@ static int ican3_reset_module(struct ican3_dev *mod) msleep(10); } while (time_before(jiffies, start + HZ / 4)); - dev_err(mod->dev, "failed to reset CAN module\n"); + netdev_err(mod->ndev, "failed to reset CAN module\n"); return -ETIMEDOUT; } @@ -1425,7 +1422,7 @@ static int ican3_startup_module(struct ican3_dev *mod) ret = ican3_reset_module(mod); if (ret) { - dev_err(mod->dev, "unable to reset module\n"); + netdev_err(mod->ndev, "unable to reset module\n"); return ret; } @@ -1434,41 +1431,41 @@ static int ican3_startup_module(struct ican3_dev *mod) ret = ican3_msg_connect(mod); if (ret) { - dev_err(mod->dev, "unable to connect to module\n"); + netdev_err(mod->ndev, "unable to connect to module\n"); return ret; } ican3_init_new_host_interface(mod); ret = ican3_msg_newhostif(mod); if (ret) { - dev_err(mod->dev, "unable to switch to new-style interface\n"); + netdev_err(mod->ndev, "unable to switch to new-style interface\n"); return ret; } /* default to "termination on" */ ret = ican3_set_termination(mod, true); if (ret) { - dev_err(mod->dev, "unable to enable termination\n"); + netdev_err(mod->ndev, "unable to enable termination\n"); return ret; } /* default to "bus errors enabled" */ ret = ican3_set_buserror(mod, 1); if (ret) { - dev_err(mod->dev, "unable to set bus-error\n"); + netdev_err(mod->ndev, "unable to set bus-error\n"); return ret; } ican3_init_fast_host_interface(mod); ret = ican3_msg_fasthostif(mod); if (ret) { - dev_err(mod->dev, "unable to switch to fast host interface\n"); + netdev_err(mod->ndev, "unable to switch to fast host interface\n"); return ret; } ret = ican3_set_id_filter(mod, true); if (ret) { - dev_err(mod->dev, "unable to set acceptance filter\n"); + netdev_err(mod->ndev, "unable to set acceptance filter\n"); return ret; } @@ -1487,14 +1484,14 @@ static int ican3_open(struct net_device *ndev) /* open the CAN layer */ ret = open_candev(ndev); if (ret) { - dev_err(mod->dev, "unable to start CAN layer\n"); + netdev_err(mod->ndev, "unable to start CAN layer\n"); return ret; } /* bring the bus online */ ret = ican3_set_bus_state(mod, true); if (ret) { - dev_err(mod->dev, "unable to set bus-on\n"); + netdev_err(mod->ndev, "unable to set bus-on\n"); close_candev(ndev); return ret; } @@ -1518,7 +1515,7 @@ static int ican3_stop(struct net_device *ndev) /* bring the bus offline, stop receiving packets */ ret = ican3_set_bus_state(mod, false); if (ret) { - dev_err(mod->dev, "unable to set bus-off\n"); + netdev_err(mod->ndev, "unable to set bus-off\n"); return ret; } @@ -1545,7 +1542,7 @@ static int ican3_xmit(struct sk_buff *skb, struct net_device *ndev) /* check that we can actually transmit */ if (!ican3_txok(mod)) { - dev_err(mod->dev, "BUG: no free descriptors\n"); + netdev_err(mod->ndev, "BUG: no free descriptors\n"); spin_unlock_irqrestore(&mod->lock, flags); return NETDEV_TX_BUSY; } @@ -1597,6 +1594,7 @@ static const struct net_device_ops ican3_netdev_ops = { .ndo_open = ican3_open, .ndo_stop = ican3_stop, .ndo_start_xmit = ican3_xmit, + .ndo_change_mtu = can_change_mtu, }; /* @@ -1657,7 +1655,7 @@ static int ican3_set_mode(struct net_device *ndev, enum can_mode mode) /* bring the bus online */ ret = ican3_set_bus_state(mod, true); if (ret) { - dev_err(mod->dev, "unable to set bus-on\n"); + netdev_err(ndev, "unable to set bus-on\n"); return ret; } @@ -1682,7 +1680,7 @@ static int ican3_get_berr_counter(const struct net_device *ndev, ret = wait_for_completion_timeout(&mod->buserror_comp, HZ); if (ret == 0) { - dev_info(mod->dev, "%s timed out\n", __func__); + netdev_info(mod->ndev, "%s timed out\n", __func__); return -ETIMEDOUT; } @@ -1708,7 +1706,7 @@ static ssize_t ican3_sysfs_show_term(struct device *dev, ret = wait_for_completion_timeout(&mod->termination_comp, HZ); if (ret == 0) { - dev_info(mod->dev, "%s timed out\n", __func__); + netdev_info(mod->ndev, "%s timed out\n", __func__); return -ETIMEDOUT; } @@ -1778,7 +1776,6 @@ static int ican3_probe(struct platform_device *pdev) platform_set_drvdata(pdev, ndev); mod = netdev_priv(ndev); mod->ndev = ndev; - mod->dev = &pdev->dev; mod->num = pdata->modno; netif_napi_add(ndev, &mod->napi, ican3_napi, ICAN3_RX_BUFFERS); skb_queue_head_init(&mod->echoq); diff --git a/drivers/net/can/led.c b/drivers/net/can/led.c index a3d99a8fd2d..ab7f1b01be4 100644 --- a/drivers/net/can/led.c +++ b/drivers/net/can/led.c @@ -97,6 +97,9 @@ static int can_led_notifier(struct notifier_block *nb, unsigned long msg, if (!priv) return NOTIFY_DONE; + if (!priv->tx_led_trig || !priv->rx_led_trig) + return NOTIFY_DONE; + if (msg == NETDEV_CHANGENAME) { snprintf(name, sizeof(name), "%s-tx", netdev->name); led_trigger_rename_static(name, priv->tx_led_trig); diff --git a/drivers/net/can/mcp251x.c b/drivers/net/can/mcp251x.c index cdb9808d12d..28c11f81524 100644 --- a/drivers/net/can/mcp251x.c +++ b/drivers/net/can/mcp251x.c @@ -601,10 +601,10 @@ static int mcp251x_do_set_bittiming(struct net_device *net) (bt->prop_seg - 1)); mcp251x_write_bits(spi, CNF3, CNF3_PHSEG2_MASK, (bt->phase_seg2 - 1)); - dev_info(&spi->dev, "CNF: 0x%02x 0x%02x 0x%02x\n", - mcp251x_read_reg(spi, CNF1), - mcp251x_read_reg(spi, CNF2), - mcp251x_read_reg(spi, CNF3)); + dev_dbg(&spi->dev, "CNF: 0x%02x 0x%02x 0x%02x\n", + mcp251x_read_reg(spi, CNF1), + mcp251x_read_reg(spi, CNF2), + mcp251x_read_reg(spi, CNF3)); return 0; } @@ -672,7 +672,7 @@ static int mcp251x_hw_probe(struct spi_device *spi) static int mcp251x_power_enable(struct regulator *reg, int enable) { - if (IS_ERR(reg)) + if (IS_ERR_OR_NULL(reg)) return 0; if (enable) @@ -996,6 +996,7 @@ static const struct net_device_ops mcp251x_netdev_ops = { .ndo_open = mcp251x_open, .ndo_stop = mcp251x_stop, .ndo_start_xmit = mcp251x_hard_start_xmit, + .ndo_change_mtu = can_change_mtu, }; static const struct of_device_id mcp251x_of_match[] = { @@ -1155,8 +1156,6 @@ static int mcp251x_can_probe(struct spi_device *spi) devm_can_led_init(net); - dev_info(&spi->dev, "probed\n"); - return ret; error_probe: @@ -1197,9 +1196,7 @@ static int mcp251x_can_remove(struct spi_device *spi) return 0; } -#ifdef CONFIG_PM_SLEEP - -static int mcp251x_can_suspend(struct device *dev) +static int __maybe_unused mcp251x_can_suspend(struct device *dev) { struct spi_device *spi = to_spi_device(dev); struct mcp251x_priv *priv = spi_get_drvdata(spi); @@ -1221,7 +1218,7 @@ static int mcp251x_can_suspend(struct device *dev) priv->after_suspend = AFTER_SUSPEND_DOWN; } - if (!IS_ERR(priv->power)) { + if (!IS_ERR_OR_NULL(priv->power)) { regulator_disable(priv->power); priv->after_suspend |= AFTER_SUSPEND_POWER; } @@ -1229,7 +1226,7 @@ static int mcp251x_can_suspend(struct device *dev) return 0; } -static int mcp251x_can_resume(struct device *dev) +static int __maybe_unused mcp251x_can_resume(struct device *dev) { struct spi_device *spi = to_spi_device(dev); struct mcp251x_priv *priv = spi_get_drvdata(spi); @@ -1249,7 +1246,6 @@ static int mcp251x_can_resume(struct device *dev) enable_irq(spi->irq); return 0; } -#endif static SIMPLE_DEV_PM_OPS(mcp251x_can_pm_ops, mcp251x_can_suspend, mcp251x_can_resume); diff --git a/drivers/net/can/mscan/mscan.c b/drivers/net/can/mscan/mscan.c index b9f3faabb0f..e0c9be5e2ab 100644 --- a/drivers/net/can/mscan/mscan.c +++ b/drivers/net/can/mscan/mscan.c @@ -647,9 +647,10 @@ static int mscan_close(struct net_device *dev) } static const struct net_device_ops mscan_netdev_ops = { - .ndo_open = mscan_open, - .ndo_stop = mscan_close, - .ndo_start_xmit = mscan_start_xmit, + .ndo_open = mscan_open, + .ndo_stop = mscan_close, + .ndo_start_xmit = mscan_start_xmit, + .ndo_change_mtu = can_change_mtu, }; int register_mscandev(struct net_device *dev, int mscan_clksrc) diff --git a/drivers/net/can/pch_can.c b/drivers/net/can/pch_can.c index 6c077eb87b5..6472562efed 100644 --- a/drivers/net/can/pch_can.c +++ b/drivers/net/can/pch_can.c @@ -950,6 +950,7 @@ static const struct net_device_ops pch_can_netdev_ops = { .ndo_open = pch_can_open, .ndo_stop = pch_close, .ndo_start_xmit = pch_xmit, + .ndo_change_mtu = can_change_mtu, }; static void pch_can_remove(struct pci_dev *pdev) diff --git a/drivers/net/can/sja1000/Kconfig b/drivers/net/can/sja1000/Kconfig index ff2ba86cd4a..1e65cb6c259 100644 --- a/drivers/net/can/sja1000/Kconfig +++ b/drivers/net/can/sja1000/Kconfig @@ -17,16 +17,9 @@ config CAN_SJA1000_PLATFORM the "platform bus" (Linux abstraction for directly to the processor attached devices). Which can be found on various boards from Phytec (http://www.phytec.de) like the PCM027, - PCM038. - -config CAN_SJA1000_OF_PLATFORM - tristate "Generic OF Platform Bus based SJA1000 driver" - depends on OF - ---help--- - This driver adds support for the SJA1000 chips connected to - the OpenFirmware "platform bus" found on embedded systems with - OpenFirmware bindings, e.g. if you have a PowerPC based system - you may want to enable this option. + PCM038. It also provides the OpenFirmware "platform bus" found + on embedded systems with OpenFirmware bindings, e.g. if you + have a PowerPC based system you may want to enable this option. config CAN_EMS_PCMCIA tristate "EMS CPC-CARD Card" @@ -46,7 +39,7 @@ config CAN_EMS_PCI config CAN_PEAK_PCMCIA tristate "PEAK PCAN-PC Card" depends on PCMCIA - depends on HAS_IOPORT + depends on HAS_IOPORT_MAP ---help--- This driver is for the PCAN-PC Card PCMCIA adapter (1 or 2 channels) from PEAK-System (http://www.peak-system.com). To compile this diff --git a/drivers/net/can/sja1000/Makefile b/drivers/net/can/sja1000/Makefile index b3d05cbfec3..531d5fcc97e 100644 --- a/drivers/net/can/sja1000/Makefile +++ b/drivers/net/can/sja1000/Makefile @@ -5,7 +5,6 @@ obj-$(CONFIG_CAN_SJA1000) += sja1000.o obj-$(CONFIG_CAN_SJA1000_ISA) += sja1000_isa.o obj-$(CONFIG_CAN_SJA1000_PLATFORM) += sja1000_platform.o -obj-$(CONFIG_CAN_SJA1000_OF_PLATFORM) += sja1000_of_platform.o obj-$(CONFIG_CAN_EMS_PCMCIA) += ems_pcmcia.o obj-$(CONFIG_CAN_EMS_PCI) += ems_pci.o obj-$(CONFIG_CAN_KVASER_PCI) += kvaser_pci.o diff --git a/drivers/net/can/sja1000/ems_pci.c b/drivers/net/can/sja1000/ems_pci.c index d790b874ca7..fd13dbf07d9 100644 --- a/drivers/net/can/sja1000/ems_pci.c +++ b/drivers/net/can/sja1000/ems_pci.c @@ -323,6 +323,7 @@ static int ems_pci_add_card(struct pci_dev *pdev, priv->cdr = EMS_PCI_CDR; SET_NETDEV_DEV(dev, &pdev->dev); + dev->dev_id = i; if (card->version == 1) /* reset int flag of pita */ diff --git a/drivers/net/can/sja1000/ems_pcmcia.c b/drivers/net/can/sja1000/ems_pcmcia.c index 9e535f2ef52..381de998d2f 100644 --- a/drivers/net/can/sja1000/ems_pcmcia.c +++ b/drivers/net/can/sja1000/ems_pcmcia.c @@ -211,6 +211,7 @@ static int ems_pcmcia_add_card(struct pcmcia_device *pdev, unsigned long base) priv = netdev_priv(dev); priv->priv = card; SET_NETDEV_DEV(dev, &pdev->dev); + dev->dev_id = i; priv->irq_flags = IRQF_SHARED; dev->irq = pdev->irq; diff --git a/drivers/net/can/sja1000/kvaser_pci.c b/drivers/net/can/sja1000/kvaser_pci.c index c96eb14699d..23b8e1324e2 100644 --- a/drivers/net/can/sja1000/kvaser_pci.c +++ b/drivers/net/can/sja1000/kvaser_pci.c @@ -270,6 +270,7 @@ static int kvaser_pci_add_chan(struct pci_dev *pdev, int channel, priv->reg_base, board->conf_addr, dev->irq); SET_NETDEV_DEV(dev, &pdev->dev); + dev->dev_id = channel; /* Register SJA1000 device */ err = register_sja1000dev(dev); diff --git a/drivers/net/can/sja1000/peak_pci.c b/drivers/net/can/sja1000/peak_pci.c index 065ca49eb45..564933ae218 100644 --- a/drivers/net/can/sja1000/peak_pci.c +++ b/drivers/net/can/sja1000/peak_pci.c @@ -551,7 +551,7 @@ static int peak_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { struct sja1000_priv *priv; struct peak_pci_chan *chan; - struct net_device *dev; + struct net_device *dev, *prev_dev; void __iomem *cfg_base, *reg_base; u16 sub_sys_id, icr; int i, err, channels; @@ -642,6 +642,7 @@ static int peak_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) icr |= chan->icr_mask; SET_NETDEV_DEV(dev, &pdev->dev); + dev->dev_id = i; /* Create chain of SJA1000 devices */ chan->prev_dev = pci_get_drvdata(pdev); @@ -687,11 +688,13 @@ failure_remove_channels: writew(0x0, cfg_base + PITA_ICR + 2); chan = NULL; - for (dev = pci_get_drvdata(pdev); dev; dev = chan->prev_dev) { - unregister_sja1000dev(dev); - free_sja1000dev(dev); + for (dev = pci_get_drvdata(pdev); dev; dev = prev_dev) { priv = netdev_priv(dev); chan = priv->priv; + prev_dev = chan->prev_dev; + + unregister_sja1000dev(dev); + free_sja1000dev(dev); } /* free any PCIeC resources too */ @@ -725,10 +728,12 @@ static void peak_pci_remove(struct pci_dev *pdev) /* Loop over all registered devices */ while (1) { + struct net_device *prev_dev = chan->prev_dev; + dev_info(&pdev->dev, "removing device %s\n", dev->name); unregister_sja1000dev(dev); free_sja1000dev(dev); - dev = chan->prev_dev; + dev = prev_dev; if (!dev) { /* do that only for first channel */ diff --git a/drivers/net/can/sja1000/peak_pcmcia.c b/drivers/net/can/sja1000/peak_pcmcia.c index f7ad754dd2a..dd56133cc46 100644 --- a/drivers/net/can/sja1000/peak_pcmcia.c +++ b/drivers/net/can/sja1000/peak_pcmcia.c @@ -550,6 +550,7 @@ static int pcan_add_channels(struct pcan_pccard *card) priv = netdev_priv(netdev); priv->priv = card; SET_NETDEV_DEV(netdev, &pdev->dev); + netdev->dev_id = i; priv->irq_flags = IRQF_SHARED; netdev->irq = pdev->irq; diff --git a/drivers/net/can/sja1000/plx_pci.c b/drivers/net/can/sja1000/plx_pci.c index fbb61a0d901..ec39b7cb228 100644 --- a/drivers/net/can/sja1000/plx_pci.c +++ b/drivers/net/can/sja1000/plx_pci.c @@ -587,6 +587,7 @@ static int plx_pci_add_card(struct pci_dev *pdev, priv->cdr = ci->cdr; SET_NETDEV_DEV(dev, &pdev->dev); + dev->dev_id = i; /* Register SJA1000 device */ err = register_sja1000dev(dev); diff --git a/drivers/net/can/sja1000/sja1000.c b/drivers/net/can/sja1000/sja1000.c index f17c3018b7c..f31499a32d7 100644 --- a/drivers/net/can/sja1000/sja1000.c +++ b/drivers/net/can/sja1000/sja1000.c @@ -106,8 +106,7 @@ static int sja1000_probe_chip(struct net_device *dev) struct sja1000_priv *priv = netdev_priv(dev); if (priv->reg_base && sja1000_is_absent(priv)) { - printk(KERN_INFO "%s: probing @0x%lX failed\n", - DRV_NAME, dev->base_addr); + netdev_err(dev, "probing failed\n"); return 0; } return -1; @@ -643,9 +642,10 @@ void free_sja1000dev(struct net_device *dev) EXPORT_SYMBOL_GPL(free_sja1000dev); static const struct net_device_ops sja1000_netdev_ops = { - .ndo_open = sja1000_open, - .ndo_stop = sja1000_close, - .ndo_start_xmit = sja1000_start_xmit, + .ndo_open = sja1000_open, + .ndo_stop = sja1000_close, + .ndo_start_xmit = sja1000_start_xmit, + .ndo_change_mtu = can_change_mtu, }; int register_sja1000dev(struct net_device *dev) diff --git a/drivers/net/can/sja1000/sja1000_isa.c b/drivers/net/can/sja1000/sja1000_isa.c index df136a2516c..014695d7e6a 100644 --- a/drivers/net/can/sja1000/sja1000_isa.c +++ b/drivers/net/can/sja1000/sja1000_isa.c @@ -46,6 +46,7 @@ static int clk[MAXDEV]; static unsigned char cdr[MAXDEV] = {[0 ... (MAXDEV - 1)] = 0xff}; static unsigned char ocr[MAXDEV] = {[0 ... (MAXDEV - 1)] = 0xff}; static int indirect[MAXDEV] = {[0 ... (MAXDEV - 1)] = -1}; +static spinlock_t indirect_lock[MAXDEV]; /* lock for indirect access mode */ module_param_array(port, ulong, NULL, S_IRUGO); MODULE_PARM_DESC(port, "I/O port number"); @@ -101,19 +102,26 @@ static void sja1000_isa_port_write_reg(const struct sja1000_priv *priv, static u8 sja1000_isa_port_read_reg_indirect(const struct sja1000_priv *priv, int reg) { - unsigned long base = (unsigned long)priv->reg_base; + unsigned long flags, base = (unsigned long)priv->reg_base; + u8 readval; + spin_lock_irqsave(&indirect_lock[priv->dev->dev_id], flags); outb(reg, base); - return inb(base + 1); + readval = inb(base + 1); + spin_unlock_irqrestore(&indirect_lock[priv->dev->dev_id], flags); + + return readval; } static void sja1000_isa_port_write_reg_indirect(const struct sja1000_priv *priv, int reg, u8 val) { - unsigned long base = (unsigned long)priv->reg_base; + unsigned long flags, base = (unsigned long)priv->reg_base; + spin_lock_irqsave(&indirect_lock[priv->dev->dev_id], flags); outb(reg, base); outb(val, base + 1); + spin_unlock_irqrestore(&indirect_lock[priv->dev->dev_id], flags); } static int sja1000_isa_probe(struct platform_device *pdev) @@ -169,6 +177,7 @@ static int sja1000_isa_probe(struct platform_device *pdev) if (iosize == SJA1000_IOSIZE_INDIRECT) { priv->read_reg = sja1000_isa_port_read_reg_indirect; priv->write_reg = sja1000_isa_port_write_reg_indirect; + spin_lock_init(&indirect_lock[idx]); } else { priv->read_reg = sja1000_isa_port_read_reg; priv->write_reg = sja1000_isa_port_write_reg; @@ -198,6 +207,7 @@ static int sja1000_isa_probe(struct platform_device *pdev) platform_set_drvdata(pdev, dev); SET_NETDEV_DEV(dev, &pdev->dev); + dev->dev_id = idx; err = register_sja1000dev(dev); if (err) { diff --git a/drivers/net/can/sja1000/sja1000_of_platform.c b/drivers/net/can/sja1000/sja1000_of_platform.c deleted file mode 100644 index 2f6e2453423..00000000000 --- a/drivers/net/can/sja1000/sja1000_of_platform.c +++ /dev/null @@ -1,220 +0,0 @@ -/* - * Driver for SJA1000 CAN controllers on the OpenFirmware platform bus - * - * Copyright (C) 2008-2009 Wolfgang Grandegger <wg@grandegger.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the version 2 of the GNU General Public License - * as published by the Free Software Foundation - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see <http://www.gnu.org/licenses/>. - */ - -/* This is a generic driver for SJA1000 chips on the OpenFirmware platform - * bus found on embedded PowerPC systems. You need a SJA1000 CAN node - * definition in your flattened device tree source (DTS) file similar to: - * - * can@3,100 { - * compatible = "nxp,sja1000"; - * reg = <3 0x100 0x80>; - * interrupts = <2 0>; - * interrupt-parent = <&mpic>; - * nxp,external-clock-frequency = <16000000>; - * }; - * - * See "Documentation/devicetree/bindings/net/can/sja1000.txt" for further - * information. - */ - -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/interrupt.h> -#include <linux/netdevice.h> -#include <linux/delay.h> -#include <linux/io.h> -#include <linux/can/dev.h> - -#include <linux/of_platform.h> -#include <linux/of_address.h> -#include <linux/of_irq.h> - -#include "sja1000.h" - -#define DRV_NAME "sja1000_of_platform" - -MODULE_AUTHOR("Wolfgang Grandegger <wg@grandegger.com>"); -MODULE_DESCRIPTION("Socket-CAN driver for SJA1000 on the OF platform bus"); -MODULE_LICENSE("GPL v2"); - -#define SJA1000_OFP_CAN_CLOCK (16000000 / 2) - -#define SJA1000_OFP_OCR OCR_TX0_PULLDOWN -#define SJA1000_OFP_CDR (CDR_CBP | CDR_CLK_OFF) - -static u8 sja1000_ofp_read_reg(const struct sja1000_priv *priv, int reg) -{ - return ioread8(priv->reg_base + reg); -} - -static void sja1000_ofp_write_reg(const struct sja1000_priv *priv, - int reg, u8 val) -{ - iowrite8(val, priv->reg_base + reg); -} - -static int sja1000_ofp_remove(struct platform_device *ofdev) -{ - struct net_device *dev = platform_get_drvdata(ofdev); - struct sja1000_priv *priv = netdev_priv(dev); - struct device_node *np = ofdev->dev.of_node; - struct resource res; - - unregister_sja1000dev(dev); - free_sja1000dev(dev); - iounmap(priv->reg_base); - irq_dispose_mapping(dev->irq); - - of_address_to_resource(np, 0, &res); - release_mem_region(res.start, resource_size(&res)); - - return 0; -} - -static int sja1000_ofp_probe(struct platform_device *ofdev) -{ - struct device_node *np = ofdev->dev.of_node; - struct net_device *dev; - struct sja1000_priv *priv; - struct resource res; - u32 prop; - int err, irq, res_size; - void __iomem *base; - - err = of_address_to_resource(np, 0, &res); - if (err) { - dev_err(&ofdev->dev, "invalid address\n"); - return err; - } - - res_size = resource_size(&res); - - if (!request_mem_region(res.start, res_size, DRV_NAME)) { - dev_err(&ofdev->dev, "couldn't request %pR\n", &res); - return -EBUSY; - } - - base = ioremap_nocache(res.start, res_size); - if (!base) { - dev_err(&ofdev->dev, "couldn't ioremap %pR\n", &res); - err = -ENOMEM; - goto exit_release_mem; - } - - irq = irq_of_parse_and_map(np, 0); - if (irq == 0) { - dev_err(&ofdev->dev, "no irq found\n"); - err = -ENODEV; - goto exit_unmap_mem; - } - - dev = alloc_sja1000dev(0); - if (!dev) { - err = -ENOMEM; - goto exit_dispose_irq; - } - - priv = netdev_priv(dev); - - priv->read_reg = sja1000_ofp_read_reg; - priv->write_reg = sja1000_ofp_write_reg; - - err = of_property_read_u32(np, "nxp,external-clock-frequency", &prop); - if (!err) - priv->can.clock.freq = prop / 2; - else - priv->can.clock.freq = SJA1000_OFP_CAN_CLOCK; /* default */ - - err = of_property_read_u32(np, "nxp,tx-output-mode", &prop); - if (!err) - priv->ocr |= prop & OCR_MODE_MASK; - else - priv->ocr |= OCR_MODE_NORMAL; /* default */ - - err = of_property_read_u32(np, "nxp,tx-output-config", &prop); - if (!err) - priv->ocr |= (prop << OCR_TX_SHIFT) & OCR_TX_MASK; - else - priv->ocr |= OCR_TX0_PULLDOWN; /* default */ - - err = of_property_read_u32(np, "nxp,clock-out-frequency", &prop); - if (!err && prop) { - u32 divider = priv->can.clock.freq * 2 / prop; - - if (divider > 1) - priv->cdr |= divider / 2 - 1; - else - priv->cdr |= CDR_CLKOUT_MASK; - } else { - priv->cdr |= CDR_CLK_OFF; /* default */ - } - - if (!of_property_read_bool(np, "nxp,no-comparator-bypass")) - priv->cdr |= CDR_CBP; /* default */ - - priv->irq_flags = IRQF_SHARED; - priv->reg_base = base; - - dev->irq = irq; - - dev_info(&ofdev->dev, - "reg_base=0x%p irq=%d clock=%d ocr=0x%02x cdr=0x%02x\n", - priv->reg_base, dev->irq, priv->can.clock.freq, - priv->ocr, priv->cdr); - - platform_set_drvdata(ofdev, dev); - SET_NETDEV_DEV(dev, &ofdev->dev); - - err = register_sja1000dev(dev); - if (err) { - dev_err(&ofdev->dev, "registering %s failed (err=%d)\n", - DRV_NAME, err); - goto exit_free_sja1000; - } - - return 0; - -exit_free_sja1000: - free_sja1000dev(dev); -exit_dispose_irq: - irq_dispose_mapping(irq); -exit_unmap_mem: - iounmap(base); -exit_release_mem: - release_mem_region(res.start, res_size); - - return err; -} - -static struct of_device_id sja1000_ofp_table[] = { - {.compatible = "nxp,sja1000"}, - {}, -}; -MODULE_DEVICE_TABLE(of, sja1000_ofp_table); - -static struct platform_driver sja1000_ofp_driver = { - .driver = { - .owner = THIS_MODULE, - .name = DRV_NAME, - .of_match_table = sja1000_ofp_table, - }, - .probe = sja1000_ofp_probe, - .remove = sja1000_ofp_remove, -}; - -module_platform_driver(sja1000_ofp_driver); diff --git a/drivers/net/can/sja1000/sja1000_platform.c b/drivers/net/can/sja1000/sja1000_platform.c index 943df645b45..95a844a7ee7 100644 --- a/drivers/net/can/sja1000/sja1000_platform.c +++ b/drivers/net/can/sja1000/sja1000_platform.c @@ -26,12 +26,16 @@ #include <linux/can/dev.h> #include <linux/can/platform/sja1000.h> #include <linux/io.h> +#include <linux/of.h> +#include <linux/of_irq.h> #include "sja1000.h" #define DRV_NAME "sja1000_platform" +#define SP_CAN_CLOCK (16000000 / 2) MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>"); +MODULE_AUTHOR("Wolfgang Grandegger <wg@grandegger.com>"); MODULE_DESCRIPTION("Socket-CAN driver for SJA1000 on the platform bus"); MODULE_ALIAS("platform:" DRV_NAME); MODULE_LICENSE("GPL v2"); @@ -66,59 +70,16 @@ static void sp_write_reg32(const struct sja1000_priv *priv, int reg, u8 val) iowrite8(val, priv->reg_base + reg * 4); } -static int sp_probe(struct platform_device *pdev) +static void sp_populate(struct sja1000_priv *priv, + struct sja1000_platform_data *pdata, + unsigned long resource_mem_flags) { - int err; - void __iomem *addr; - struct net_device *dev; - struct sja1000_priv *priv; - struct resource *res_mem, *res_irq; - struct sja1000_platform_data *pdata; - - pdata = dev_get_platdata(&pdev->dev); - if (!pdata) { - dev_err(&pdev->dev, "No platform data provided!\n"); - err = -ENODEV; - goto exit; - } - - res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); - res_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); - if (!res_mem || !res_irq) { - err = -ENODEV; - goto exit; - } - - if (!request_mem_region(res_mem->start, resource_size(res_mem), - DRV_NAME)) { - err = -EBUSY; - goto exit; - } - - addr = ioremap_nocache(res_mem->start, resource_size(res_mem)); - if (!addr) { - err = -ENOMEM; - goto exit_release; - } - - dev = alloc_sja1000dev(0); - if (!dev) { - err = -ENOMEM; - goto exit_iounmap; - } - priv = netdev_priv(dev); - - dev->irq = res_irq->start; - priv->irq_flags = res_irq->flags & IRQF_TRIGGER_MASK; - if (res_irq->flags & IORESOURCE_IRQ_SHAREABLE) - priv->irq_flags |= IRQF_SHARED; - priv->reg_base = addr; /* The CAN clock frequency is half the oscillator clock frequency */ priv->can.clock.freq = pdata->osc_freq / 2; priv->ocr = pdata->ocr; priv->cdr = pdata->cdr; - switch (res_mem->flags & IORESOURCE_MEM_TYPE_MASK) { + switch (resource_mem_flags & IORESOURCE_MEM_TYPE_MASK) { case IORESOURCE_MEM_32BIT: priv->read_reg = sp_read_reg32; priv->write_reg = sp_write_reg32; @@ -133,6 +94,124 @@ static int sp_probe(struct platform_device *pdev) priv->write_reg = sp_write_reg8; break; } +} + +static void sp_populate_of(struct sja1000_priv *priv, struct device_node *of) +{ + int err; + u32 prop; + + err = of_property_read_u32(of, "reg-io-width", &prop); + if (err) + prop = 1; /* 8 bit is default */ + + switch (prop) { + case 4: + priv->read_reg = sp_read_reg32; + priv->write_reg = sp_write_reg32; + break; + case 2: + priv->read_reg = sp_read_reg16; + priv->write_reg = sp_write_reg16; + break; + case 1: /* fallthrough */ + default: + priv->read_reg = sp_read_reg8; + priv->write_reg = sp_write_reg8; + } + + err = of_property_read_u32(of, "nxp,external-clock-frequency", &prop); + if (!err) + priv->can.clock.freq = prop / 2; + else + priv->can.clock.freq = SP_CAN_CLOCK; /* default */ + + err = of_property_read_u32(of, "nxp,tx-output-mode", &prop); + if (!err) + priv->ocr |= prop & OCR_MODE_MASK; + else + priv->ocr |= OCR_MODE_NORMAL; /* default */ + + err = of_property_read_u32(of, "nxp,tx-output-config", &prop); + if (!err) + priv->ocr |= (prop << OCR_TX_SHIFT) & OCR_TX_MASK; + else + priv->ocr |= OCR_TX0_PULLDOWN; /* default */ + + err = of_property_read_u32(of, "nxp,clock-out-frequency", &prop); + if (!err && prop) { + u32 divider = priv->can.clock.freq * 2 / prop; + + if (divider > 1) + priv->cdr |= divider / 2 - 1; + else + priv->cdr |= CDR_CLKOUT_MASK; + } else { + priv->cdr |= CDR_CLK_OFF; /* default */ + } + + if (!of_property_read_bool(of, "nxp,no-comparator-bypass")) + priv->cdr |= CDR_CBP; /* default */ +} + +static int sp_probe(struct platform_device *pdev) +{ + int err, irq = 0; + void __iomem *addr; + struct net_device *dev; + struct sja1000_priv *priv; + struct resource *res_mem, *res_irq = NULL; + struct sja1000_platform_data *pdata; + struct device_node *of = pdev->dev.of_node; + + pdata = dev_get_platdata(&pdev->dev); + if (!pdata && !of) { + dev_err(&pdev->dev, "No platform data provided!\n"); + return -ENODEV; + } + + res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res_mem) + return -ENODEV; + + if (!devm_request_mem_region(&pdev->dev, res_mem->start, + resource_size(res_mem), DRV_NAME)) + return -EBUSY; + + addr = devm_ioremap_nocache(&pdev->dev, res_mem->start, + resource_size(res_mem)); + if (!addr) + return -ENOMEM; + + if (of) + irq = irq_of_parse_and_map(of, 0); + else + res_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); + + if (!irq && !res_irq) + return -ENODEV; + + dev = alloc_sja1000dev(0); + if (!dev) + return -ENOMEM; + priv = netdev_priv(dev); + + if (res_irq) { + irq = res_irq->start; + priv->irq_flags = res_irq->flags & IRQF_TRIGGER_MASK; + if (res_irq->flags & IORESOURCE_IRQ_SHAREABLE) + priv->irq_flags |= IRQF_SHARED; + } else { + priv->irq_flags = IRQF_SHARED; + } + + dev->irq = irq; + priv->reg_base = addr; + + if (of) + sp_populate_of(priv, of); + else + sp_populate(priv, pdata, res_mem->flags); platform_set_drvdata(pdev, dev); SET_NETDEV_DEV(dev, &pdev->dev); @@ -150,39 +229,32 @@ static int sp_probe(struct platform_device *pdev) exit_free: free_sja1000dev(dev); - exit_iounmap: - iounmap(addr); - exit_release: - release_mem_region(res_mem->start, resource_size(res_mem)); - exit: return err; } static int sp_remove(struct platform_device *pdev) { struct net_device *dev = platform_get_drvdata(pdev); - struct sja1000_priv *priv = netdev_priv(dev); - struct resource *res; unregister_sja1000dev(dev); - - if (priv->reg_base) - iounmap(priv->reg_base); - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - release_mem_region(res->start, resource_size(res)); - free_sja1000dev(dev); return 0; } +static struct of_device_id sp_of_table[] = { + {.compatible = "nxp,sja1000"}, + {}, +}; +MODULE_DEVICE_TABLE(of, sp_of_table); + static struct platform_driver sp_driver = { .probe = sp_probe, .remove = sp_remove, .driver = { .name = DRV_NAME, .owner = THIS_MODULE, + .of_match_table = sp_of_table, }, }; diff --git a/drivers/net/can/slcan.c b/drivers/net/can/slcan.c index 3fcdae26637..dcf9196f631 100644 --- a/drivers/net/can/slcan.c +++ b/drivers/net/can/slcan.c @@ -322,13 +322,13 @@ static void slcan_write_wakeup(struct tty_struct *tty) if (!sl || sl->magic != SLCAN_MAGIC || !netif_running(sl->dev)) return; - spin_lock(&sl->lock); + spin_lock_bh(&sl->lock); if (sl->xleft <= 0) { /* Now serial buffer is almost free & we can start * transmission of another packet */ sl->dev->stats.tx_packets++; clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags); - spin_unlock(&sl->lock); + spin_unlock_bh(&sl->lock); netif_wake_queue(sl->dev); return; } @@ -336,7 +336,7 @@ static void slcan_write_wakeup(struct tty_struct *tty) actual = tty->ops->write(tty, sl->xhead, sl->xleft); sl->xleft -= actual; sl->xhead += actual; - spin_unlock(&sl->lock); + spin_unlock_bh(&sl->lock); } /* Send a can_frame to a TTY queue. */ @@ -411,10 +411,16 @@ static void slc_free_netdev(struct net_device *dev) slcan_devs[i] = NULL; } +static int slcan_change_mtu(struct net_device *dev, int new_mtu) +{ + return -EINVAL; +} + static const struct net_device_ops slc_netdev_ops = { .ndo_open = slc_open, .ndo_stop = slc_close, .ndo_start_xmit = slc_xmit, + .ndo_change_mtu = slcan_change_mtu, }; static void slc_setup(struct net_device *dev) diff --git a/drivers/net/can/softing/softing_main.c b/drivers/net/can/softing/softing_main.c index 9ea0dcde94c..7d8c8f3672d 100644 --- a/drivers/net/can/softing/softing_main.c +++ b/drivers/net/can/softing/softing_main.c @@ -628,6 +628,7 @@ static const struct net_device_ops softing_netdev_ops = { .ndo_open = softing_netdev_open, .ndo_stop = softing_netdev_stop, .ndo_start_xmit = softing_netdev_start_xmit, + .ndo_change_mtu = can_change_mtu, }; static const struct can_bittiming_const softing_btr_const = { @@ -832,6 +833,7 @@ static int softing_pdev_probe(struct platform_device *pdev) ret = -ENOMEM; goto netdev_failed; } + netdev->dev_id = j; priv = netdev_priv(card->net[j]); priv->index = j; ret = softing_netdev_register(netdev); diff --git a/drivers/net/can/ti_hecc.c b/drivers/net/can/ti_hecc.c index 2c62fe6c8fa..258b9c4856e 100644 --- a/drivers/net/can/ti_hecc.c +++ b/drivers/net/can/ti_hecc.c @@ -871,6 +871,7 @@ static const struct net_device_ops ti_hecc_netdev_ops = { .ndo_open = ti_hecc_open, .ndo_stop = ti_hecc_close, .ndo_start_xmit = ti_hecc_xmit, + .ndo_change_mtu = can_change_mtu, }; static int ti_hecc_probe(struct platform_device *pdev) diff --git a/drivers/net/can/usb/ems_usb.c b/drivers/net/can/usb/ems_usb.c index 52c42fd4951..00f2534dde7 100644 --- a/drivers/net/can/usb/ems_usb.c +++ b/drivers/net/can/usb/ems_usb.c @@ -883,6 +883,7 @@ static const struct net_device_ops ems_usb_netdev_ops = { .ndo_open = ems_usb_open, .ndo_stop = ems_usb_close, .ndo_start_xmit = ems_usb_start_xmit, + .ndo_change_mtu = can_change_mtu, }; static const struct can_bittiming_const ems_usb_bittiming_const = { diff --git a/drivers/net/can/usb/esd_usb2.c b/drivers/net/can/usb/esd_usb2.c index 7fbe85935f1..b7c9e8b1146 100644 --- a/drivers/net/can/usb/esd_usb2.c +++ b/drivers/net/can/usb/esd_usb2.c @@ -888,6 +888,7 @@ static const struct net_device_ops esd_usb2_netdev_ops = { .ndo_open = esd_usb2_open, .ndo_stop = esd_usb2_close, .ndo_start_xmit = esd_usb2_start_xmit, + .ndo_change_mtu = can_change_mtu, }; static const struct can_bittiming_const esd_usb2_bittiming_const = { @@ -1024,6 +1025,7 @@ static int esd_usb2_probe_one_net(struct usb_interface *intf, int index) netdev->netdev_ops = &esd_usb2_netdev_ops; SET_NETDEV_DEV(netdev, &intf->dev); + netdev->dev_id = index; err = register_candev(netdev); if (err) { diff --git a/drivers/net/can/usb/kvaser_usb.c b/drivers/net/can/usb/kvaser_usb.c index e77d1104974..4ca46edc061 100644 --- a/drivers/net/can/usb/kvaser_usb.c +++ b/drivers/net/can/usb/kvaser_usb.c @@ -1388,6 +1388,7 @@ static const struct net_device_ops kvaser_usb_netdev_ops = { .ndo_open = kvaser_usb_open, .ndo_stop = kvaser_usb_close, .ndo_start_xmit = kvaser_usb_start_xmit, + .ndo_change_mtu = can_change_mtu, }; static const struct can_bittiming_const kvaser_usb_bittiming_const = { @@ -1529,6 +1530,7 @@ static int kvaser_usb_init_one(struct usb_interface *intf, netdev->netdev_ops = &kvaser_usb_netdev_ops; SET_NETDEV_DEV(netdev, &intf->dev); + netdev->dev_id = channel; dev->nets[channel] = priv; diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_core.c b/drivers/net/can/usb/peak_usb/pcan_usb_core.c index 0b7a4c3b01a..644e6ab8a48 100644 --- a/drivers/net/can/usb/peak_usb/pcan_usb_core.c +++ b/drivers/net/can/usb/peak_usb/pcan_usb_core.c @@ -702,6 +702,7 @@ static const struct net_device_ops peak_usb_netdev_ops = { .ndo_open = peak_usb_ndo_open, .ndo_stop = peak_usb_ndo_stop, .ndo_start_xmit = peak_usb_ndo_start_xmit, + .ndo_change_mtu = can_change_mtu, }; /* @@ -769,6 +770,7 @@ static int peak_usb_create_dev(struct peak_usb_adapter *peak_usb_adapter, usb_set_intfdata(intf, dev); SET_NETDEV_DEV(netdev, &intf->dev); + netdev->dev_id = ctrl_idx; err = register_candev(netdev); if (err) { diff --git a/drivers/net/can/usb/usb_8dev.c b/drivers/net/can/usb/usb_8dev.c index a0fa1fd5092..ef674ecb82f 100644 --- a/drivers/net/can/usb/usb_8dev.c +++ b/drivers/net/can/usb/usb_8dev.c @@ -697,8 +697,8 @@ static netdev_tx_t usb_8dev_start_xmit(struct sk_buff *skb, return NETDEV_TX_OK; nofreecontext: - usb_unanchor_urb(urb); usb_free_coherent(priv->udev, size, buf, urb->transfer_dma); + usb_free_urb(urb); netdev_warn(netdev, "couldn't find free context"); @@ -887,6 +887,7 @@ static const struct net_device_ops usb_8dev_netdev_ops = { .ndo_open = usb_8dev_open, .ndo_stop = usb_8dev_close, .ndo_start_xmit = usb_8dev_start_xmit, + .ndo_change_mtu = can_change_mtu, }; static const struct can_bittiming_const usb_8dev_bittiming_const = { |