mirror of https://gitee.com/openkylin/linux.git
linux-can-fixes-for-3.18-20141118
-----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABAgAGBQJUa62AAAoJECte4hHFiupU4poP/ioEJ/FE0ODYBWzLkseu1SA3 l9+Y76SvXb1HJ9g0GMK2Dk71R6GsmxT7cUx2Gn9EwRyFF9hHDq5d3Oz+zGIJxLcj GJeVLKEarg74nxFixIb19H5mrfpSP18wvg68BBjLuAiM9zo++AYiJU1jb9hSIU/f dkFFaU3/HSBZVbrb152kTO7bMvxzi0fYnlhK8TisZbq6YWMla5oJOAugxT7Ew81L fAb3FnZdho/XLXecBLsOtSEnDVv9rD89H0IyYp89pBTmtpzDH6JUR77BBmdN9w/D 7hHtqjuC0vhBG9xrFq5z5vnbgR3SmxfkTgstsJUyYkAP/R9v3I/LznlHfUp80UrI IkJw66iYOZRFo5bORHoY8ID+/2h8b/AcBAwBRXj+RcwjndEZbWl4JOEP1bxYlQG3 53WIhYLwTcJP1djp2NPWt0Z6Hli/j2KlAYsbunbnNIGmZJovtirWe2+sob/Xvoi2 FO8kVlbeowT2hu6tMPenQ+qfR7nO9MqK2PMT4NWPcR7a42h7fIHS9JAa2SJVfANJ weGvh3RcVOKfiPvmDCZGSlytk+OgEmS5vna/xOoQZP8xIhQ3899MM/Lpz2gIExvU mHbxj6nV2DmgljFTCz2T9z5yfhZs+OHd5Nrl048UIt/XIaUIBa0lax9WjqDTY8sZ TCH/A/JHILxmpQLOq66N =OIH1 -----END PGP SIGNATURE----- Merge tag 'linux-can-fixes-for-3.18-20141118' of git://gitorious.org/linux-can/linux-can Marc Kleine-Budde says: ==================== pull-request: can 2014-11-18 this is a pull request of 17 patches for net/master for the v3.18 release cycle. The last patch of this pull request ("can: m_can: update to support CAN FD features") adds, as the description says, a new feature to the m_can driver. As the m_can driver has been added in v3.18 there is no risk of causing a regression. Give me a note if this is not okay and I'll create a new pull request without it. There is a patch for the CAN infrastructure by Thomas Körper which fixes calling kfree_skb() from interrupt context. Roman Fietze fixes a typo also in the infrastructure. A patch by Dong Aisheng adds a generic helper function to tell if a skb is normal CAN or CAN-FD frame. Alexey Khoroshilov of the Linux Driver Verification project fixes a memory leak in the esd_usb2 driver. Two patches by Sudip Mukherjee remove unused variables and fixe the signess of a variable. Three patches by me add the missing .ndo_change_mtu callback to the xilinx_can, rcar_can and gs_usb driver. The remaining patches improve the m_can driver: David Cohen adds the missing CONFIG_HAS_IOMEM dependency. Dong Aisheng provides 6 bugfix patches (most important: missing RAM init, sleep in NAPI poll, dlc in RTR). While the last of his patches adds CAN FD support to the driver. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
ddecab1abc
|
@ -110,7 +110,7 @@ static int can_calc_bittiming(struct net_device *dev, struct can_bittiming *bt,
|
|||
long rate;
|
||||
u64 v64;
|
||||
|
||||
/* Use CIA recommended sample points */
|
||||
/* Use CiA recommended sample points */
|
||||
if (bt->sample_point) {
|
||||
sampl_pt = bt->sample_point;
|
||||
} else {
|
||||
|
@ -382,7 +382,7 @@ void can_free_echo_skb(struct net_device *dev, unsigned int idx)
|
|||
BUG_ON(idx >= priv->echo_skb_max);
|
||||
|
||||
if (priv->echo_skb[idx]) {
|
||||
kfree_skb(priv->echo_skb[idx]);
|
||||
dev_kfree_skb_any(priv->echo_skb[idx]);
|
||||
priv->echo_skb[idx] = NULL;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
config CAN_M_CAN
|
||||
depends on HAS_IOMEM
|
||||
tristate "Bosch M_CAN devices"
|
||||
---help---
|
||||
Say Y here if you want to support for Bosch M_CAN controller.
|
||||
|
|
|
@ -105,14 +105,36 @@ enum m_can_mram_cfg {
|
|||
MRAM_CFG_NUM,
|
||||
};
|
||||
|
||||
/* Fast Bit Timing & Prescaler Register (FBTP) */
|
||||
#define FBTR_FBRP_MASK 0x1f
|
||||
#define FBTR_FBRP_SHIFT 16
|
||||
#define FBTR_FTSEG1_SHIFT 8
|
||||
#define FBTR_FTSEG1_MASK (0xf << FBTR_FTSEG1_SHIFT)
|
||||
#define FBTR_FTSEG2_SHIFT 4
|
||||
#define FBTR_FTSEG2_MASK (0x7 << FBTR_FTSEG2_SHIFT)
|
||||
#define FBTR_FSJW_SHIFT 0
|
||||
#define FBTR_FSJW_MASK 0x3
|
||||
|
||||
/* Test Register (TEST) */
|
||||
#define TEST_LBCK BIT(4)
|
||||
|
||||
/* CC Control Register(CCCR) */
|
||||
#define CCCR_TEST BIT(7)
|
||||
#define CCCR_MON BIT(5)
|
||||
#define CCCR_CCE BIT(1)
|
||||
#define CCCR_INIT BIT(0)
|
||||
#define CCCR_TEST BIT(7)
|
||||
#define CCCR_CMR_MASK 0x3
|
||||
#define CCCR_CMR_SHIFT 10
|
||||
#define CCCR_CMR_CANFD 0x1
|
||||
#define CCCR_CMR_CANFD_BRS 0x2
|
||||
#define CCCR_CMR_CAN 0x3
|
||||
#define CCCR_CME_MASK 0x3
|
||||
#define CCCR_CME_SHIFT 8
|
||||
#define CCCR_CME_CAN 0
|
||||
#define CCCR_CME_CANFD 0x1
|
||||
#define CCCR_CME_CANFD_BRS 0x2
|
||||
#define CCCR_TEST BIT(7)
|
||||
#define CCCR_MON BIT(5)
|
||||
#define CCCR_CCE BIT(1)
|
||||
#define CCCR_INIT BIT(0)
|
||||
#define CCCR_CANFD 0x10
|
||||
|
||||
/* Bit Timing & Prescaler Register (BTP) */
|
||||
#define BTR_BRP_MASK 0x3ff
|
||||
|
@ -204,6 +226,7 @@ enum m_can_mram_cfg {
|
|||
|
||||
/* Rx Buffer / FIFO Element Size Configuration (RXESC) */
|
||||
#define M_CAN_RXESC_8BYTES 0x0
|
||||
#define M_CAN_RXESC_64BYTES 0x777
|
||||
|
||||
/* Tx Buffer Configuration(TXBC) */
|
||||
#define TXBC_NDTB_OFF 16
|
||||
|
@ -211,6 +234,7 @@ enum m_can_mram_cfg {
|
|||
|
||||
/* Tx Buffer Element Size Configuration(TXESC) */
|
||||
#define TXESC_TBDS_8BYTES 0x0
|
||||
#define TXESC_TBDS_64BYTES 0x7
|
||||
|
||||
/* Tx Event FIFO Con.guration (TXEFC) */
|
||||
#define TXEFC_EFS_OFF 16
|
||||
|
@ -219,11 +243,11 @@ enum m_can_mram_cfg {
|
|||
/* Message RAM Configuration (in bytes) */
|
||||
#define SIDF_ELEMENT_SIZE 4
|
||||
#define XIDF_ELEMENT_SIZE 8
|
||||
#define RXF0_ELEMENT_SIZE 16
|
||||
#define RXF1_ELEMENT_SIZE 16
|
||||
#define RXF0_ELEMENT_SIZE 72
|
||||
#define RXF1_ELEMENT_SIZE 72
|
||||
#define RXB_ELEMENT_SIZE 16
|
||||
#define TXE_ELEMENT_SIZE 8
|
||||
#define TXB_ELEMENT_SIZE 16
|
||||
#define TXB_ELEMENT_SIZE 72
|
||||
|
||||
/* Message RAM Elements */
|
||||
#define M_CAN_FIFO_ID 0x0
|
||||
|
@ -231,11 +255,17 @@ enum m_can_mram_cfg {
|
|||
#define M_CAN_FIFO_DATA(n) (0x8 + ((n) << 2))
|
||||
|
||||
/* Rx Buffer Element */
|
||||
/* R0 */
|
||||
#define RX_BUF_ESI BIT(31)
|
||||
#define RX_BUF_XTD BIT(30)
|
||||
#define RX_BUF_RTR BIT(29)
|
||||
/* R1 */
|
||||
#define RX_BUF_ANMF BIT(31)
|
||||
#define RX_BUF_EDL BIT(21)
|
||||
#define RX_BUF_BRS BIT(20)
|
||||
|
||||
/* Tx Buffer Element */
|
||||
/* R0 */
|
||||
#define TX_BUF_XTD BIT(30)
|
||||
#define TX_BUF_RTR BIT(29)
|
||||
|
||||
|
@ -296,6 +326,7 @@ static inline void m_can_config_endisable(const struct m_can_priv *priv,
|
|||
if (enable) {
|
||||
/* enable m_can configuration */
|
||||
m_can_write(priv, M_CAN_CCCR, cccr | CCCR_INIT);
|
||||
udelay(5);
|
||||
/* CCCR.CCE can only be set/reset while CCCR.INIT = '1' */
|
||||
m_can_write(priv, M_CAN_CCCR, cccr | CCCR_INIT | CCCR_CCE);
|
||||
} else {
|
||||
|
@ -326,41 +357,67 @@ static inline void m_can_disable_all_interrupts(const struct m_can_priv *priv)
|
|||
m_can_write(priv, M_CAN_ILE, 0x0);
|
||||
}
|
||||
|
||||
static void m_can_read_fifo(const struct net_device *dev, struct can_frame *cf,
|
||||
u32 rxfs)
|
||||
static void m_can_read_fifo(struct net_device *dev, u32 rxfs)
|
||||
{
|
||||
struct net_device_stats *stats = &dev->stats;
|
||||
struct m_can_priv *priv = netdev_priv(dev);
|
||||
u32 id, fgi;
|
||||
struct canfd_frame *cf;
|
||||
struct sk_buff *skb;
|
||||
u32 id, fgi, dlc;
|
||||
int i;
|
||||
|
||||
/* calculate the fifo get index for where to read data */
|
||||
fgi = (rxfs & RXFS_FGI_MASK) >> RXFS_FGI_OFF;
|
||||
dlc = m_can_fifo_read(priv, fgi, M_CAN_FIFO_DLC);
|
||||
if (dlc & RX_BUF_EDL)
|
||||
skb = alloc_canfd_skb(dev, &cf);
|
||||
else
|
||||
skb = alloc_can_skb(dev, (struct can_frame **)&cf);
|
||||
if (!skb) {
|
||||
stats->rx_dropped++;
|
||||
return;
|
||||
}
|
||||
|
||||
if (dlc & RX_BUF_EDL)
|
||||
cf->len = can_dlc2len((dlc >> 16) & 0x0F);
|
||||
else
|
||||
cf->len = get_can_dlc((dlc >> 16) & 0x0F);
|
||||
|
||||
id = m_can_fifo_read(priv, fgi, M_CAN_FIFO_ID);
|
||||
if (id & RX_BUF_XTD)
|
||||
cf->can_id = (id & CAN_EFF_MASK) | CAN_EFF_FLAG;
|
||||
else
|
||||
cf->can_id = (id >> 18) & CAN_SFF_MASK;
|
||||
|
||||
if (id & RX_BUF_RTR) {
|
||||
if (id & RX_BUF_ESI) {
|
||||
cf->flags |= CANFD_ESI;
|
||||
netdev_dbg(dev, "ESI Error\n");
|
||||
}
|
||||
|
||||
if (!(dlc & RX_BUF_EDL) && (id & RX_BUF_RTR)) {
|
||||
cf->can_id |= CAN_RTR_FLAG;
|
||||
} else {
|
||||
id = m_can_fifo_read(priv, fgi, M_CAN_FIFO_DLC);
|
||||
cf->can_dlc = get_can_dlc((id >> 16) & 0x0F);
|
||||
*(u32 *)(cf->data + 0) = m_can_fifo_read(priv, fgi,
|
||||
M_CAN_FIFO_DATA(0));
|
||||
*(u32 *)(cf->data + 4) = m_can_fifo_read(priv, fgi,
|
||||
M_CAN_FIFO_DATA(1));
|
||||
if (dlc & RX_BUF_BRS)
|
||||
cf->flags |= CANFD_BRS;
|
||||
|
||||
for (i = 0; i < cf->len; i += 4)
|
||||
*(u32 *)(cf->data + i) =
|
||||
m_can_fifo_read(priv, fgi,
|
||||
M_CAN_FIFO_DATA(i / 4));
|
||||
}
|
||||
|
||||
/* acknowledge rx fifo 0 */
|
||||
m_can_write(priv, M_CAN_RXF0A, fgi);
|
||||
|
||||
stats->rx_packets++;
|
||||
stats->rx_bytes += cf->len;
|
||||
|
||||
netif_receive_skb(skb);
|
||||
}
|
||||
|
||||
static int m_can_do_rx_poll(struct net_device *dev, int quota)
|
||||
{
|
||||
struct m_can_priv *priv = netdev_priv(dev);
|
||||
struct net_device_stats *stats = &dev->stats;
|
||||
struct sk_buff *skb;
|
||||
struct can_frame *frame;
|
||||
u32 pkts = 0;
|
||||
u32 rxfs;
|
||||
|
||||
|
@ -374,18 +431,7 @@ static int m_can_do_rx_poll(struct net_device *dev, int quota)
|
|||
if (rxfs & RXFS_RFL)
|
||||
netdev_warn(dev, "Rx FIFO 0 Message Lost\n");
|
||||
|
||||
skb = alloc_can_skb(dev, &frame);
|
||||
if (!skb) {
|
||||
stats->rx_dropped++;
|
||||
return pkts;
|
||||
}
|
||||
|
||||
m_can_read_fifo(dev, frame, rxfs);
|
||||
|
||||
stats->rx_packets++;
|
||||
stats->rx_bytes += frame->can_dlc;
|
||||
|
||||
netif_receive_skb(skb);
|
||||
m_can_read_fifo(dev, rxfs);
|
||||
|
||||
quota--;
|
||||
pkts++;
|
||||
|
@ -481,11 +527,23 @@ static int m_can_handle_lec_err(struct net_device *dev,
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int __m_can_get_berr_counter(const struct net_device *dev,
|
||||
struct can_berr_counter *bec)
|
||||
{
|
||||
struct m_can_priv *priv = netdev_priv(dev);
|
||||
unsigned int ecr;
|
||||
|
||||
ecr = m_can_read(priv, M_CAN_ECR);
|
||||
bec->rxerr = (ecr & ECR_REC_MASK) >> ECR_REC_SHIFT;
|
||||
bec->txerr = ecr & ECR_TEC_MASK;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int m_can_get_berr_counter(const struct net_device *dev,
|
||||
struct can_berr_counter *bec)
|
||||
{
|
||||
struct m_can_priv *priv = netdev_priv(dev);
|
||||
unsigned int ecr;
|
||||
int err;
|
||||
|
||||
err = clk_prepare_enable(priv->hclk);
|
||||
|
@ -498,9 +556,7 @@ static int m_can_get_berr_counter(const struct net_device *dev,
|
|||
return err;
|
||||
}
|
||||
|
||||
ecr = m_can_read(priv, M_CAN_ECR);
|
||||
bec->rxerr = (ecr & ECR_REC_MASK) >> ECR_REC_SHIFT;
|
||||
bec->txerr = ecr & ECR_TEC_MASK;
|
||||
__m_can_get_berr_counter(dev, bec);
|
||||
|
||||
clk_disable_unprepare(priv->cclk);
|
||||
clk_disable_unprepare(priv->hclk);
|
||||
|
@ -544,7 +600,7 @@ static int m_can_handle_state_change(struct net_device *dev,
|
|||
if (unlikely(!skb))
|
||||
return 0;
|
||||
|
||||
m_can_get_berr_counter(dev, &bec);
|
||||
__m_can_get_berr_counter(dev, &bec);
|
||||
|
||||
switch (new_state) {
|
||||
case CAN_STATE_ERROR_ACTIVE:
|
||||
|
@ -596,14 +652,14 @@ static int m_can_handle_state_errors(struct net_device *dev, u32 psr)
|
|||
|
||||
if ((psr & PSR_EP) &&
|
||||
(priv->can.state != CAN_STATE_ERROR_PASSIVE)) {
|
||||
netdev_dbg(dev, "entered error warning state\n");
|
||||
netdev_dbg(dev, "entered error passive state\n");
|
||||
work_done += m_can_handle_state_change(dev,
|
||||
CAN_STATE_ERROR_PASSIVE);
|
||||
}
|
||||
|
||||
if ((psr & PSR_BO) &&
|
||||
(priv->can.state != CAN_STATE_BUS_OFF)) {
|
||||
netdev_dbg(dev, "entered error warning state\n");
|
||||
netdev_dbg(dev, "entered error bus off state\n");
|
||||
work_done += m_can_handle_state_change(dev,
|
||||
CAN_STATE_BUS_OFF);
|
||||
}
|
||||
|
@ -615,7 +671,7 @@ static void m_can_handle_other_err(struct net_device *dev, u32 irqstatus)
|
|||
{
|
||||
if (irqstatus & IR_WDI)
|
||||
netdev_err(dev, "Message RAM Watchdog event due to missing READY\n");
|
||||
if (irqstatus & IR_BEU)
|
||||
if (irqstatus & IR_ELO)
|
||||
netdev_err(dev, "Error Logging Overflow\n");
|
||||
if (irqstatus & IR_BEU)
|
||||
netdev_err(dev, "Bit Error Uncorrected\n");
|
||||
|
@ -733,10 +789,23 @@ static const struct can_bittiming_const m_can_bittiming_const = {
|
|||
.brp_inc = 1,
|
||||
};
|
||||
|
||||
static const struct can_bittiming_const m_can_data_bittiming_const = {
|
||||
.name = KBUILD_MODNAME,
|
||||
.tseg1_min = 2, /* Time segment 1 = prop_seg + phase_seg1 */
|
||||
.tseg1_max = 16,
|
||||
.tseg2_min = 1, /* Time segment 2 = phase_seg2 */
|
||||
.tseg2_max = 8,
|
||||
.sjw_max = 4,
|
||||
.brp_min = 1,
|
||||
.brp_max = 32,
|
||||
.brp_inc = 1,
|
||||
};
|
||||
|
||||
static int m_can_set_bittiming(struct net_device *dev)
|
||||
{
|
||||
struct m_can_priv *priv = netdev_priv(dev);
|
||||
const struct can_bittiming *bt = &priv->can.bittiming;
|
||||
const struct can_bittiming *dbt = &priv->can.data_bittiming;
|
||||
u16 brp, sjw, tseg1, tseg2;
|
||||
u32 reg_btp;
|
||||
|
||||
|
@ -747,7 +816,17 @@ static int m_can_set_bittiming(struct net_device *dev)
|
|||
reg_btp = (brp << BTR_BRP_SHIFT) | (sjw << BTR_SJW_SHIFT) |
|
||||
(tseg1 << BTR_TSEG1_SHIFT) | (tseg2 << BTR_TSEG2_SHIFT);
|
||||
m_can_write(priv, M_CAN_BTP, reg_btp);
|
||||
netdev_dbg(dev, "setting BTP 0x%x\n", reg_btp);
|
||||
|
||||
if (priv->can.ctrlmode & CAN_CTRLMODE_FD) {
|
||||
brp = dbt->brp - 1;
|
||||
sjw = dbt->sjw - 1;
|
||||
tseg1 = dbt->prop_seg + dbt->phase_seg1 - 1;
|
||||
tseg2 = dbt->phase_seg2 - 1;
|
||||
reg_btp = (brp << FBTR_FBRP_SHIFT) | (sjw << FBTR_FSJW_SHIFT) |
|
||||
(tseg1 << FBTR_FTSEG1_SHIFT) |
|
||||
(tseg2 << FBTR_FTSEG2_SHIFT);
|
||||
m_can_write(priv, M_CAN_FBTP, reg_btp);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -767,8 +846,8 @@ static void m_can_chip_config(struct net_device *dev)
|
|||
|
||||
m_can_config_endisable(priv, true);
|
||||
|
||||
/* RX Buffer/FIFO Element Size 8 bytes data field */
|
||||
m_can_write(priv, M_CAN_RXESC, M_CAN_RXESC_8BYTES);
|
||||
/* RX Buffer/FIFO Element Size 64 bytes data field */
|
||||
m_can_write(priv, M_CAN_RXESC, M_CAN_RXESC_64BYTES);
|
||||
|
||||
/* Accept Non-matching Frames Into FIFO 0 */
|
||||
m_can_write(priv, M_CAN_GFC, 0x0);
|
||||
|
@ -777,8 +856,8 @@ static void m_can_chip_config(struct net_device *dev)
|
|||
m_can_write(priv, M_CAN_TXBC, (1 << TXBC_NDTB_OFF) |
|
||||
priv->mcfg[MRAM_TXB].off);
|
||||
|
||||
/* only support 8 bytes firstly */
|
||||
m_can_write(priv, M_CAN_TXESC, TXESC_TBDS_8BYTES);
|
||||
/* support 64 bytes payload */
|
||||
m_can_write(priv, M_CAN_TXESC, TXESC_TBDS_64BYTES);
|
||||
|
||||
m_can_write(priv, M_CAN_TXEFC, (1 << TXEFC_EFS_OFF) |
|
||||
priv->mcfg[MRAM_TXE].off);
|
||||
|
@ -793,7 +872,8 @@ static void m_can_chip_config(struct net_device *dev)
|
|||
RXFC_FWM_1 | priv->mcfg[MRAM_RXF1].off);
|
||||
|
||||
cccr = m_can_read(priv, M_CAN_CCCR);
|
||||
cccr &= ~(CCCR_TEST | CCCR_MON);
|
||||
cccr &= ~(CCCR_TEST | CCCR_MON | (CCCR_CMR_MASK << CCCR_CMR_SHIFT) |
|
||||
(CCCR_CME_MASK << CCCR_CME_SHIFT));
|
||||
test = m_can_read(priv, M_CAN_TEST);
|
||||
test &= ~TEST_LBCK;
|
||||
|
||||
|
@ -805,6 +885,9 @@ static void m_can_chip_config(struct net_device *dev)
|
|||
test |= TEST_LBCK;
|
||||
}
|
||||
|
||||
if (priv->can.ctrlmode & CAN_CTRLMODE_FD)
|
||||
cccr |= CCCR_CME_CANFD_BRS << CCCR_CME_SHIFT;
|
||||
|
||||
m_can_write(priv, M_CAN_CCCR, cccr);
|
||||
m_can_write(priv, M_CAN_TEST, test);
|
||||
|
||||
|
@ -869,11 +952,13 @@ static struct net_device *alloc_m_can_dev(void)
|
|||
|
||||
priv->dev = dev;
|
||||
priv->can.bittiming_const = &m_can_bittiming_const;
|
||||
priv->can.data_bittiming_const = &m_can_data_bittiming_const;
|
||||
priv->can.do_set_mode = m_can_set_mode;
|
||||
priv->can.do_get_berr_counter = m_can_get_berr_counter;
|
||||
priv->can.ctrlmode_supported = CAN_CTRLMODE_LOOPBACK |
|
||||
CAN_CTRLMODE_LISTENONLY |
|
||||
CAN_CTRLMODE_BERR_REPORTING;
|
||||
CAN_CTRLMODE_BERR_REPORTING |
|
||||
CAN_CTRLMODE_FD;
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
@ -956,8 +1041,9 @@ static netdev_tx_t m_can_start_xmit(struct sk_buff *skb,
|
|||
struct net_device *dev)
|
||||
{
|
||||
struct m_can_priv *priv = netdev_priv(dev);
|
||||
struct can_frame *cf = (struct can_frame *)skb->data;
|
||||
u32 id;
|
||||
struct canfd_frame *cf = (struct canfd_frame *)skb->data;
|
||||
u32 id, cccr;
|
||||
int i;
|
||||
|
||||
if (can_dropped_invalid_skb(dev, skb))
|
||||
return NETDEV_TX_OK;
|
||||
|
@ -976,11 +1062,28 @@ static netdev_tx_t m_can_start_xmit(struct sk_buff *skb,
|
|||
|
||||
/* message ram configuration */
|
||||
m_can_fifo_write(priv, 0, M_CAN_FIFO_ID, id);
|
||||
m_can_fifo_write(priv, 0, M_CAN_FIFO_DLC, cf->can_dlc << 16);
|
||||
m_can_fifo_write(priv, 0, M_CAN_FIFO_DATA(0), *(u32 *)(cf->data + 0));
|
||||
m_can_fifo_write(priv, 0, M_CAN_FIFO_DATA(1), *(u32 *)(cf->data + 4));
|
||||
m_can_fifo_write(priv, 0, M_CAN_FIFO_DLC, can_len2dlc(cf->len) << 16);
|
||||
|
||||
for (i = 0; i < cf->len; i += 4)
|
||||
m_can_fifo_write(priv, 0, M_CAN_FIFO_DATA(i / 4),
|
||||
*(u32 *)(cf->data + i));
|
||||
|
||||
can_put_echo_skb(skb, dev, 0);
|
||||
|
||||
if (priv->can.ctrlmode & CAN_CTRLMODE_FD) {
|
||||
cccr = m_can_read(priv, M_CAN_CCCR);
|
||||
cccr &= ~(CCCR_CMR_MASK << CCCR_CMR_SHIFT);
|
||||
if (can_is_canfd_skb(skb)) {
|
||||
if (cf->flags & CANFD_BRS)
|
||||
cccr |= CCCR_CMR_CANFD_BRS << CCCR_CMR_SHIFT;
|
||||
else
|
||||
cccr |= CCCR_CMR_CANFD << CCCR_CMR_SHIFT;
|
||||
} else {
|
||||
cccr |= CCCR_CMR_CAN << CCCR_CMR_SHIFT;
|
||||
}
|
||||
m_can_write(priv, M_CAN_CCCR, cccr);
|
||||
}
|
||||
|
||||
/* enable first TX buffer to start transfer */
|
||||
m_can_write(priv, M_CAN_TXBTIE, 0x1);
|
||||
m_can_write(priv, M_CAN_TXBAR, 0x1);
|
||||
|
@ -992,6 +1095,7 @@ static const struct net_device_ops m_can_netdev_ops = {
|
|||
.ndo_open = m_can_open,
|
||||
.ndo_stop = m_can_close,
|
||||
.ndo_start_xmit = m_can_start_xmit,
|
||||
.ndo_change_mtu = can_change_mtu,
|
||||
};
|
||||
|
||||
static int register_m_can_dev(struct net_device *dev)
|
||||
|
@ -1009,7 +1113,7 @@ static int m_can_of_parse_mram(struct platform_device *pdev,
|
|||
struct resource *res;
|
||||
void __iomem *addr;
|
||||
u32 out_val[MRAM_CFG_LEN];
|
||||
int ret;
|
||||
int i, start, end, ret;
|
||||
|
||||
/* message ram could be shared */
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "message_ram");
|
||||
|
@ -1060,6 +1164,15 @@ static int m_can_of_parse_mram(struct platform_device *pdev,
|
|||
priv->mcfg[MRAM_TXE].off, priv->mcfg[MRAM_TXE].num,
|
||||
priv->mcfg[MRAM_TXB].off, priv->mcfg[MRAM_TXB].num);
|
||||
|
||||
/* initialize the entire Message RAM in use to avoid possible
|
||||
* ECC/parity checksum errors when reading an uninitialized buffer
|
||||
*/
|
||||
start = priv->mcfg[MRAM_SIDF].off;
|
||||
end = priv->mcfg[MRAM_TXB].off +
|
||||
priv->mcfg[MRAM_TXB].num * TXB_ELEMENT_SIZE;
|
||||
for (i = start; i < end; i += 4)
|
||||
writel(0x0, priv->mram_base + i);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -628,6 +628,7 @@ static const struct net_device_ops rcar_can_netdev_ops = {
|
|||
.ndo_open = rcar_can_open,
|
||||
.ndo_stop = rcar_can_close,
|
||||
.ndo_start_xmit = rcar_can_start_xmit,
|
||||
.ndo_change_mtu = can_change_mtu,
|
||||
};
|
||||
|
||||
static void rcar_can_rx_pkt(struct rcar_can_priv *priv)
|
||||
|
|
|
@ -214,7 +214,7 @@ static int kvaser_pci_add_chan(struct pci_dev *pdev, int channel,
|
|||
struct net_device *dev;
|
||||
struct sja1000_priv *priv;
|
||||
struct kvaser_pci *board;
|
||||
int err, init_step;
|
||||
int err;
|
||||
|
||||
dev = alloc_sja1000dev(sizeof(struct kvaser_pci));
|
||||
if (dev == NULL)
|
||||
|
@ -235,7 +235,6 @@ static int kvaser_pci_add_chan(struct pci_dev *pdev, int channel,
|
|||
if (channel == 0) {
|
||||
board->xilinx_ver =
|
||||
ioread8(board->res_addr + XILINX_VERINT) >> 4;
|
||||
init_step = 2;
|
||||
|
||||
/* Assert PTADR# - we're in passive mode so the other bits are
|
||||
not important */
|
||||
|
@ -264,8 +263,6 @@ static int kvaser_pci_add_chan(struct pci_dev *pdev, int channel,
|
|||
priv->irq_flags = IRQF_SHARED;
|
||||
dev->irq = pdev->irq;
|
||||
|
||||
init_step = 4;
|
||||
|
||||
dev_info(&pdev->dev, "reg_base=%p conf_addr=%p irq=%d\n",
|
||||
priv->reg_base, board->conf_addr, dev->irq);
|
||||
|
||||
|
|
|
@ -434,10 +434,9 @@ static void ems_usb_read_bulk_callback(struct urb *urb)
|
|||
if (urb->actual_length > CPC_HEADER_SIZE) {
|
||||
struct ems_cpc_msg *msg;
|
||||
u8 *ibuf = urb->transfer_buffer;
|
||||
u8 msg_count, again, start;
|
||||
u8 msg_count, start;
|
||||
|
||||
msg_count = ibuf[0] & ~0x80;
|
||||
again = ibuf[0] & 0x80;
|
||||
|
||||
start = CPC_HEADER_SIZE;
|
||||
|
||||
|
|
|
@ -464,7 +464,6 @@ static void esd_usb2_write_bulk_callback(struct urb *urb)
|
|||
{
|
||||
struct esd_tx_urb_context *context = urb->context;
|
||||
struct esd_usb2_net_priv *priv;
|
||||
struct esd_usb2 *dev;
|
||||
struct net_device *netdev;
|
||||
size_t size = sizeof(struct esd_usb2_msg);
|
||||
|
||||
|
@ -472,7 +471,6 @@ static void esd_usb2_write_bulk_callback(struct urb *urb)
|
|||
|
||||
priv = context->priv;
|
||||
netdev = priv->netdev;
|
||||
dev = priv->usb2;
|
||||
|
||||
/* free up our allocated buffer */
|
||||
usb_free_coherent(urb->dev, size,
|
||||
|
@ -1143,6 +1141,7 @@ static void esd_usb2_disconnect(struct usb_interface *intf)
|
|||
}
|
||||
}
|
||||
unlink_all_urbs(dev);
|
||||
kfree(dev);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -718,6 +718,7 @@ static const struct net_device_ops gs_usb_netdev_ops = {
|
|||
.ndo_open = gs_can_open,
|
||||
.ndo_stop = gs_can_close,
|
||||
.ndo_start_xmit = gs_can_start_xmit,
|
||||
.ndo_change_mtu = can_change_mtu,
|
||||
};
|
||||
|
||||
static struct gs_can *gs_make_candev(unsigned int channel, struct usb_interface *intf)
|
||||
|
|
|
@ -300,7 +300,8 @@ static int xcan_set_bittiming(struct net_device *ndev)
|
|||
static int xcan_chip_start(struct net_device *ndev)
|
||||
{
|
||||
struct xcan_priv *priv = netdev_priv(ndev);
|
||||
u32 err, reg_msr, reg_sr_mask;
|
||||
u32 reg_msr, reg_sr_mask;
|
||||
int err;
|
||||
unsigned long timeout;
|
||||
|
||||
/* Check if it is in reset mode */
|
||||
|
@ -961,6 +962,7 @@ static const struct net_device_ops xcan_netdev_ops = {
|
|||
.ndo_open = xcan_open,
|
||||
.ndo_stop = xcan_close,
|
||||
.ndo_start_xmit = xcan_start_xmit,
|
||||
.ndo_change_mtu = can_change_mtu,
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -99,6 +99,12 @@ static inline int can_dropped_invalid_skb(struct net_device *dev,
|
|||
return 1;
|
||||
}
|
||||
|
||||
static inline bool can_is_canfd_skb(const struct sk_buff *skb)
|
||||
{
|
||||
/* the CAN specific type of skb is identified by its data length */
|
||||
return skb->len == CANFD_MTU;
|
||||
}
|
||||
|
||||
/* get data length from can_dlc with sanitized can_dlc */
|
||||
u8 can_dlc2len(u8 can_dlc);
|
||||
|
||||
|
|
Loading…
Reference in New Issue