Commit 8714652f authored by David S. Miller's avatar David S. Miller

Merge tag 'linux-can-next-for-5.4-20190814' of...

Merge tag 'linux-can-next-for-5.4-20190814' of git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can-next

Marc Kleine-Budde says:

====================
pull-request: can-next 2019-08-14

this is a pull request for net-next/master consisting of 41 patches.

The first two patches are for the kvaser_pciefd driver: Christer Beskow
removes unnecessary code in the kvaser_pciefd_pwm_stop() function,
YueHaibing removes the unused including of <linux/version.h>.

In the next patch YueHaibing also removes the unused including of
<linux/version.h> in the f81601 driver.

In the ti_hecc driver the next 6 patches are by me and fix checkpatch
warnings. YueHaibing's patch removes an unused variable in the
ti_hecc_mailbox_read() function.

The next 6 patches all target the xilinx_can driver. Anssi Hannula's
patch fixes a chip start failure with an invalid bus. The patch by
Venkatesh Yadav Abbarapu skips an error message in case of a deferred
probe. The 3 patches by Appana Durga Kedareswara rao fix the RX and TX
path for CAN-FD frames. Srinivas Neeli's patch fixes the bit timing
calculations for CAN-FD.

The next 12 patches are by me and several checkpatch warnings in the
af_can, raw and bcm components.

Thomas Gleixner provides a patch for the bcm, which switches the timer
to HRTIMER_MODE_SOFT and removes the hrtimer_tasklet.

Then 6 more patches by me for the gw component, which fix checkpatch
warnings, followed by 2 patches by Oliver Hartkopp to add CAN-FD
support.

The vcan driver gets 3 patches by me, fixing checkpatch warnings.

And finally a patch by Andre Hartmann to fix typos in CAN's netlink
header.
====================
parents 8d73f8f2 3ca3c4aa
...@@ -7,7 +7,6 @@ ...@@ -7,7 +7,6 @@
*/ */
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/version.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/device.h> #include <linux/device.h>
#include <linux/pci.h> #include <linux/pci.h>
...@@ -643,7 +642,7 @@ static int kvaser_pciefd_bus_on(struct kvaser_pciefd_can *can) ...@@ -643,7 +642,7 @@ static int kvaser_pciefd_bus_on(struct kvaser_pciefd_can *can)
static void kvaser_pciefd_pwm_stop(struct kvaser_pciefd_can *can) static void kvaser_pciefd_pwm_stop(struct kvaser_pciefd_can *can)
{ {
int top, trigger; u8 top;
u32 pwm_ctrl; u32 pwm_ctrl;
unsigned long irq; unsigned long irq;
...@@ -651,12 +650,8 @@ static void kvaser_pciefd_pwm_stop(struct kvaser_pciefd_can *can) ...@@ -651,12 +650,8 @@ static void kvaser_pciefd_pwm_stop(struct kvaser_pciefd_can *can)
pwm_ctrl = ioread32(can->reg_base + KVASER_PCIEFD_KCAN_PWM_REG); pwm_ctrl = ioread32(can->reg_base + KVASER_PCIEFD_KCAN_PWM_REG);
top = (pwm_ctrl >> KVASER_PCIEFD_KCAN_PWM_TOP_SHIFT) & 0xff; top = (pwm_ctrl >> KVASER_PCIEFD_KCAN_PWM_TOP_SHIFT) & 0xff;
trigger = (100 * top + 50) / 100; /* Set duty cycle to zero */
if (trigger < 0) pwm_ctrl |= top;
trigger = 0;
pwm_ctrl = trigger & 0xff;
pwm_ctrl |= (top & 0xff) << KVASER_PCIEFD_KCAN_PWM_TOP_SHIFT;
iowrite32(pwm_ctrl, can->reg_base + KVASER_PCIEFD_KCAN_PWM_REG); iowrite32(pwm_ctrl, can->reg_base + KVASER_PCIEFD_KCAN_PWM_REG);
spin_unlock_irqrestore(&can->lock, irq); spin_unlock_irqrestore(&can->lock, irq);
} }
......
...@@ -14,7 +14,6 @@ ...@@ -14,7 +14,6 @@
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/can/dev.h> #include <linux/can/dev.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/version.h>
#include "sja1000.h" #include "sja1000.h"
......
...@@ -46,8 +46,7 @@ MODULE_VERSION(HECC_MODULE_VERSION); ...@@ -46,8 +46,7 @@ MODULE_VERSION(HECC_MODULE_VERSION);
#define HECC_MAX_MAILBOXES 32 /* hardware mailboxes - do not change */ #define HECC_MAX_MAILBOXES 32 /* hardware mailboxes - do not change */
#define MAX_TX_PRIO 0x3F /* hardware value - do not change */ #define MAX_TX_PRIO 0x3F /* hardware value - do not change */
/* /* Important Note: TX mailbox configuration
* Important Note: TX mailbox configuration
* TX mailboxes should be restricted to the number of SKB buffers to avoid * TX mailboxes should be restricted to the number of SKB buffers to avoid
* maintaining SKB buffers separately. TX mailboxes should be a power of 2 * maintaining SKB buffers separately. TX mailboxes should be a power of 2
* for the mailbox logic to work. Top mailbox numbers are reserved for RX * for the mailbox logic to work. Top mailbox numbers are reserved for RX
...@@ -272,8 +271,8 @@ static int ti_hecc_set_btc(struct ti_hecc_priv *priv) ...@@ -272,8 +271,8 @@ static int ti_hecc_set_btc(struct ti_hecc_priv *priv)
if (bit_timing->brp > 4) if (bit_timing->brp > 4)
can_btc |= HECC_CANBTC_SAM; can_btc |= HECC_CANBTC_SAM;
else else
netdev_warn(priv->ndev, "WARN: Triple" netdev_warn(priv->ndev,
"sampling not set due to h/w limitations"); "WARN: Triple sampling not set due to h/w limitations");
} }
can_btc |= ((bit_timing->sjw - 1) & 0x3) << 8; can_btc |= ((bit_timing->sjw - 1) & 0x3) << 8;
can_btc |= ((bit_timing->brp - 1) & 0xFF) << 16; can_btc |= ((bit_timing->brp - 1) & 0xFF) << 16;
...@@ -309,8 +308,7 @@ static void ti_hecc_reset(struct net_device *ndev) ...@@ -309,8 +308,7 @@ static void ti_hecc_reset(struct net_device *ndev)
/* Set change control request and wait till enabled */ /* Set change control request and wait till enabled */
hecc_set_bit(priv, HECC_CANMC, HECC_CANMC_CCR); hecc_set_bit(priv, HECC_CANMC, HECC_CANMC_CCR);
/* /* INFO: It has been observed that at times CCE bit may not be
* INFO: It has been observed that at times CCE bit may not be
* set and hw seems to be ok even if this bit is not set so * set and hw seems to be ok even if this bit is not set so
* timing out with a timing of 1ms to respect the specs * timing out with a timing of 1ms to respect the specs
*/ */
...@@ -320,8 +318,7 @@ static void ti_hecc_reset(struct net_device *ndev) ...@@ -320,8 +318,7 @@ static void ti_hecc_reset(struct net_device *ndev)
udelay(10); udelay(10);
} }
/* /* Note: On HECC, BTC can be programmed only in initialization mode, so
* Note: On HECC, BTC can be programmed only in initialization mode, so
* it is expected that the can bittiming parameters are set via ip * it is expected that the can bittiming parameters are set via ip
* utility before the device is opened * utility before the device is opened
*/ */
...@@ -330,13 +327,11 @@ static void ti_hecc_reset(struct net_device *ndev) ...@@ -330,13 +327,11 @@ static void ti_hecc_reset(struct net_device *ndev)
/* Clear CCR (and CANMC register) and wait for CCE = 0 enable */ /* Clear CCR (and CANMC register) and wait for CCE = 0 enable */
hecc_write(priv, HECC_CANMC, 0); hecc_write(priv, HECC_CANMC, 0);
/* /* INFO: CAN net stack handles bus off and hence disabling auto-bus-on
* INFO: CAN net stack handles bus off and hence disabling auto-bus-on
* hecc_set_bit(priv, HECC_CANMC, HECC_CANMC_ABO); * hecc_set_bit(priv, HECC_CANMC, HECC_CANMC_ABO);
*/ */
/* /* INFO: It has been observed that at times CCE bit may not be
* INFO: It has been observed that at times CCE bit may not be
* set and hw seems to be ok even if this bit is not set so * set and hw seems to be ok even if this bit is not set so
*/ */
cnt = HECC_CCE_WAIT_COUNT; cnt = HECC_CCE_WAIT_COUNT;
...@@ -369,7 +364,8 @@ static void ti_hecc_start(struct net_device *ndev) ...@@ -369,7 +364,8 @@ static void ti_hecc_start(struct net_device *ndev)
/* put HECC in initialization mode and set btc */ /* put HECC in initialization mode and set btc */
ti_hecc_reset(ndev); ti_hecc_reset(ndev);
priv->tx_head = priv->tx_tail = HECC_TX_MASK; priv->tx_head = HECC_TX_MASK;
priv->tx_tail = HECC_TX_MASK;
/* Enable local and global acceptance mask registers */ /* Enable local and global acceptance mask registers */
hecc_write(priv, HECC_CANGAM, HECC_SET_REG); hecc_write(priv, HECC_CANGAM, HECC_SET_REG);
...@@ -439,8 +435,7 @@ static int ti_hecc_get_berr_counter(const struct net_device *ndev, ...@@ -439,8 +435,7 @@ static int ti_hecc_get_berr_counter(const struct net_device *ndev,
return 0; return 0;
} }
/* /* ti_hecc_xmit: HECC Transmit
* ti_hecc_xmit: HECC Transmit
* *
* The transmit mailboxes start from 0 to HECC_MAX_TX_MBOX. In HECC the * The transmit mailboxes start from 0 to HECC_MAX_TX_MBOX. In HECC the
* priority of the mailbox for tranmission is dependent upon priority setting * priority of the mailbox for tranmission is dependent upon priority setting
...@@ -520,7 +515,8 @@ static netdev_tx_t ti_hecc_xmit(struct sk_buff *skb, struct net_device *ndev) ...@@ -520,7 +515,8 @@ static netdev_tx_t ti_hecc_xmit(struct sk_buff *skb, struct net_device *ndev)
return NETDEV_TX_OK; return NETDEV_TX_OK;
} }
static inline struct ti_hecc_priv *rx_offload_to_priv(struct can_rx_offload *offload) static inline
struct ti_hecc_priv *rx_offload_to_priv(struct can_rx_offload *offload)
{ {
return container_of(offload, struct ti_hecc_priv, offload); return container_of(offload, struct ti_hecc_priv, offload);
} }
...@@ -530,18 +526,19 @@ static unsigned int ti_hecc_mailbox_read(struct can_rx_offload *offload, ...@@ -530,18 +526,19 @@ static unsigned int ti_hecc_mailbox_read(struct can_rx_offload *offload,
u32 *timestamp, unsigned int mbxno) u32 *timestamp, unsigned int mbxno)
{ {
struct ti_hecc_priv *priv = rx_offload_to_priv(offload); struct ti_hecc_priv *priv = rx_offload_to_priv(offload);
u32 data, mbx_mask; u32 data;
mbx_mask = BIT(mbxno);
data = hecc_read_mbx(priv, mbxno, HECC_CANMID); data = hecc_read_mbx(priv, mbxno, HECC_CANMID);
if (data & HECC_CANMID_IDE) if (data & HECC_CANMID_IDE)
cf->can_id = (data & CAN_EFF_MASK) | CAN_EFF_FLAG; cf->can_id = (data & CAN_EFF_MASK) | CAN_EFF_FLAG;
else else
cf->can_id = (data >> 18) & CAN_SFF_MASK; cf->can_id = (data >> 18) & CAN_SFF_MASK;
data = hecc_read_mbx(priv, mbxno, HECC_CANMCF); data = hecc_read_mbx(priv, mbxno, HECC_CANMCF);
if (data & HECC_CANMCF_RTR) if (data & HECC_CANMCF_RTR)
cf->can_id |= CAN_RTR_FLAG; cf->can_id |= CAN_RTR_FLAG;
cf->can_dlc = get_can_dlc(data & 0xF); cf->can_dlc = get_can_dlc(data & 0xF);
data = hecc_read_mbx(priv, mbxno, HECC_CANMDL); data = hecc_read_mbx(priv, mbxno, HECC_CANMDL);
*(__be32 *)(cf->data) = cpu_to_be32(data); *(__be32 *)(cf->data) = cpu_to_be32(data);
if (cf->can_dlc > 4) { if (cf->can_dlc > 4) {
...@@ -567,7 +564,8 @@ static int ti_hecc_error(struct net_device *ndev, int int_status, ...@@ -567,7 +564,8 @@ static int ti_hecc_error(struct net_device *ndev, int int_status,
if (!skb) { if (!skb) {
if (printk_ratelimit()) if (printk_ratelimit())
netdev_err(priv->ndev, netdev_err(priv->ndev,
"ti_hecc_error: alloc_can_err_skb() failed\n"); "%s: alloc_can_err_skb() failed\n",
__func__);
return -ENOMEM; return -ENOMEM;
} }
...@@ -601,8 +599,7 @@ static int ti_hecc_error(struct net_device *ndev, int int_status, ...@@ -601,8 +599,7 @@ static int ti_hecc_error(struct net_device *ndev, int int_status,
hecc_clear_bit(priv, HECC_CANMC, HECC_CANMC_CCR); hecc_clear_bit(priv, HECC_CANMC, HECC_CANMC_CCR);
} }
/* /* Need to check busoff condition in error status register too to
* Need to check busoff condition in error status register too to
* ensure warning interrupts don't hog the system * ensure warning interrupts don't hog the system
*/ */
if ((int_status & HECC_CANGIF_BOIF) || (err_status & HECC_CANES_BO)) { if ((int_status & HECC_CANGIF_BOIF) || (err_status & HECC_CANES_BO)) {
...@@ -656,7 +653,8 @@ static irqreturn_t ti_hecc_interrupt(int irq, void *dev_id) ...@@ -656,7 +653,8 @@ static irqreturn_t ti_hecc_interrupt(int irq, void *dev_id)
unsigned long flags, rx_pending; unsigned long flags, rx_pending;
int_status = hecc_read(priv, int_status = hecc_read(priv,
(priv->use_hecc1int) ? HECC_CANGIF1 : HECC_CANGIF0); priv->use_hecc1int ?
HECC_CANGIF1 : HECC_CANGIF0);
if (!int_status) if (!int_status)
return IRQ_NONE; return IRQ_NONE;
...@@ -678,7 +676,8 @@ static irqreturn_t ti_hecc_interrupt(int irq, void *dev_id) ...@@ -678,7 +676,8 @@ static irqreturn_t ti_hecc_interrupt(int irq, void *dev_id)
hecc_clear_bit(priv, HECC_CANME, mbx_mask); hecc_clear_bit(priv, HECC_CANME, mbx_mask);
spin_unlock_irqrestore(&priv->mbx_lock, flags); spin_unlock_irqrestore(&priv->mbx_lock, flags);
stamp = hecc_read_stamp(priv, mbxno); stamp = hecc_read_stamp(priv, mbxno);
stats->tx_bytes += can_rx_offload_get_echo_skb(&priv->offload, stats->tx_bytes +=
can_rx_offload_get_echo_skb(&priv->offload,
mbxno, stamp); mbxno, stamp);
stats->tx_packets++; stats->tx_packets++;
can_led_event(ndev, CAN_LED_EVENT_TX); can_led_event(ndev, CAN_LED_EVENT_TX);
...@@ -686,7 +685,7 @@ static irqreturn_t ti_hecc_interrupt(int irq, void *dev_id) ...@@ -686,7 +685,7 @@ static irqreturn_t ti_hecc_interrupt(int irq, void *dev_id)
} }
/* restart queue if wrap-up or if queue stalled on last pkt */ /* restart queue if wrap-up or if queue stalled on last pkt */
if (((priv->tx_head == priv->tx_tail) && if ((priv->tx_head == priv->tx_tail &&
((priv->tx_head & HECC_TX_MASK) != HECC_TX_MASK)) || ((priv->tx_head & HECC_TX_MASK) != HECC_TX_MASK)) ||
(((priv->tx_tail & HECC_TX_MASK) == HECC_TX_MASK) && (((priv->tx_tail & HECC_TX_MASK) == HECC_TX_MASK) &&
((priv->tx_head & HECC_TX_MASK) == HECC_TX_MASK))) ((priv->tx_head & HECC_TX_MASK) == HECC_TX_MASK)))
...@@ -894,7 +893,7 @@ static int ti_hecc_probe(struct platform_device *pdev) ...@@ -894,7 +893,7 @@ static int ti_hecc_probe(struct platform_device *pdev)
devm_can_led_init(ndev); devm_can_led_init(ndev);
dev_info(&pdev->dev, "device registered (reg_base=%p, irq=%u)\n", dev_info(&pdev->dev, "device registered (reg_base=%p, irq=%u)\n",
priv->base, (u32) ndev->irq); priv->base, (u32)ndev->irq);
return 0; return 0;
......
/* /* vcan.c - Virtual CAN interface
* vcan.c - Virtual CAN interface
* *
* Copyright (c) 2002-2017 Volkswagen Group Electronic Research * Copyright (c) 2002-2017 Volkswagen Group Electronic Research
* All rights reserved. * All rights reserved.
...@@ -39,6 +38,8 @@ ...@@ -39,6 +38,8 @@
* *
*/ */
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/module.h> #include <linux/module.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/netdevice.h> #include <linux/netdevice.h>
...@@ -57,9 +58,7 @@ MODULE_LICENSE("Dual BSD/GPL"); ...@@ -57,9 +58,7 @@ MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("Urs Thuermann <urs.thuermann@volkswagen.de>"); MODULE_AUTHOR("Urs Thuermann <urs.thuermann@volkswagen.de>");
MODULE_ALIAS_RTNL_LINK(DRV_NAME); MODULE_ALIAS_RTNL_LINK(DRV_NAME);
/* CAN test feature:
/*
* CAN test feature:
* Enable the echo on driver level for testing the CAN core echo modes. * Enable the echo on driver level for testing the CAN core echo modes.
* See Documentation/networking/can.rst for details. * See Documentation/networking/can.rst for details.
*/ */
...@@ -68,7 +67,6 @@ static bool echo; /* echo testing. Default: 0 (Off) */ ...@@ -68,7 +67,6 @@ static bool echo; /* echo testing. Default: 0 (Off) */
module_param(echo, bool, 0444); module_param(echo, bool, 0444);
MODULE_PARM_DESC(echo, "Echo sent frames (for testing). Default: 0 (Off)"); MODULE_PARM_DESC(echo, "Echo sent frames (for testing). Default: 0 (Off)");
static void vcan_rx(struct sk_buff *skb, struct net_device *dev) static void vcan_rx(struct sk_buff *skb, struct net_device *dev)
{ {
struct canfd_frame *cfd = (struct canfd_frame *)skb->data; struct canfd_frame *cfd = (struct canfd_frame *)skb->data;
...@@ -101,10 +99,8 @@ static netdev_tx_t vcan_tx(struct sk_buff *skb, struct net_device *dev) ...@@ -101,10 +99,8 @@ static netdev_tx_t vcan_tx(struct sk_buff *skb, struct net_device *dev)
if (!echo) { if (!echo) {
/* no echo handling available inside this driver */ /* no echo handling available inside this driver */
if (loop) { if (loop) {
/* /* only count the packets here, because the
* only count the packets here, because the
* CAN core already did the echo for us * CAN core already did the echo for us
*/ */
stats->rx_packets++; stats->rx_packets++;
...@@ -117,7 +113,6 @@ static netdev_tx_t vcan_tx(struct sk_buff *skb, struct net_device *dev) ...@@ -117,7 +113,6 @@ static netdev_tx_t vcan_tx(struct sk_buff *skb, struct net_device *dev)
/* perform standard echo handling for CAN network interfaces */ /* perform standard echo handling for CAN network interfaces */
if (loop) { if (loop) {
skb = can_create_echo_skb(skb); skb = can_create_echo_skb(skb);
if (!skb) if (!skb)
return NETDEV_TX_OK; return NETDEV_TX_OK;
...@@ -173,10 +168,10 @@ static struct rtnl_link_ops vcan_link_ops __read_mostly = { ...@@ -173,10 +168,10 @@ static struct rtnl_link_ops vcan_link_ops __read_mostly = {
static __init int vcan_init_module(void) static __init int vcan_init_module(void)
{ {
pr_info("vcan: Virtual CAN interface driver\n"); pr_info("Virtual CAN interface driver\n");
if (echo) if (echo)
printk(KERN_INFO "vcan: enabled echo on driver level.\n"); pr_info("enabled echo on driver level.\n");
return rtnl_link_register(&vcan_link_ops); return rtnl_link_register(&vcan_link_ops);
} }
......
...@@ -66,8 +66,7 @@ enum xcan_reg { ...@@ -66,8 +66,7 @@ enum xcan_reg {
#define XCAN_FRAME_DLC_OFFSET(frame_base) ((frame_base) + 0x04) #define XCAN_FRAME_DLC_OFFSET(frame_base) ((frame_base) + 0x04)
#define XCAN_FRAME_DW1_OFFSET(frame_base) ((frame_base) + 0x08) #define XCAN_FRAME_DW1_OFFSET(frame_base) ((frame_base) + 0x08)
#define XCAN_FRAME_DW2_OFFSET(frame_base) ((frame_base) + 0x0C) #define XCAN_FRAME_DW2_OFFSET(frame_base) ((frame_base) + 0x0C)
#define XCANFD_FRAME_DW_OFFSET(frame_base, n) (((frame_base) + 0x08) + \ #define XCANFD_FRAME_DW_OFFSET(frame_base) ((frame_base) + 0x08)
((n) * XCAN_CANFD_FRAME_SIZE))
#define XCAN_CANFD_FRAME_SIZE 0x48 #define XCAN_CANFD_FRAME_SIZE 0x48
#define XCAN_TXMSG_FRAME_OFFSET(n) (XCAN_TXMSG_BASE_OFFSET + \ #define XCAN_TXMSG_FRAME_OFFSET(n) (XCAN_TXMSG_BASE_OFFSET + \
...@@ -124,8 +123,10 @@ enum xcan_reg { ...@@ -124,8 +123,10 @@ enum xcan_reg {
#define XCAN_IDR_RTR_MASK 0x00000001 /* Remote TX request */ #define XCAN_IDR_RTR_MASK 0x00000001 /* Remote TX request */
#define XCAN_DLCR_DLC_MASK 0xF0000000 /* Data length code */ #define XCAN_DLCR_DLC_MASK 0xF0000000 /* Data length code */
#define XCAN_FSR_FL_MASK 0x00003F00 /* RX Fill Level */ #define XCAN_FSR_FL_MASK 0x00003F00 /* RX Fill Level */
#define XCAN_2_FSR_FL_MASK 0x00007F00 /* RX Fill Level */
#define XCAN_FSR_IRI_MASK 0x00000080 /* RX Increment Read Index */ #define XCAN_FSR_IRI_MASK 0x00000080 /* RX Increment Read Index */
#define XCAN_FSR_RI_MASK 0x0000001F /* RX Read Index */ #define XCAN_FSR_RI_MASK 0x0000001F /* RX Read Index */
#define XCAN_2_FSR_RI_MASK 0x0000003F /* RX Read Index */
#define XCAN_DLCR_EDL_MASK 0x08000000 /* EDL Mask in DLC */ #define XCAN_DLCR_EDL_MASK 0x08000000 /* EDL Mask in DLC */
#define XCAN_DLCR_BRS_MASK 0x04000000 /* BRS Mask in DLC */ #define XCAN_DLCR_BRS_MASK 0x04000000 /* BRS Mask in DLC */
...@@ -424,7 +425,7 @@ static int xcan_set_bittiming(struct net_device *ndev) ...@@ -424,7 +425,7 @@ static int xcan_set_bittiming(struct net_device *ndev)
btr0 = dbt->brp - 1; btr0 = dbt->brp - 1;
/* Setting Time Segment 1 in BTR Register */ /* Setting Time Segment 1 in BTR Register */
btr1 = dbt->prop_seg + bt->phase_seg1 - 1; btr1 = dbt->prop_seg + dbt->phase_seg1 - 1;
/* Setting Time Segment 2 in BTR Register */ /* Setting Time Segment 2 in BTR Register */
btr1 |= (dbt->phase_seg2 - 1) << priv->devtype.btr_ts2_shift; btr1 |= (dbt->phase_seg2 - 1) << priv->devtype.btr_ts2_shift;
...@@ -456,9 +457,8 @@ static int xcan_set_bittiming(struct net_device *ndev) ...@@ -456,9 +457,8 @@ static int xcan_set_bittiming(struct net_device *ndev)
static int xcan_chip_start(struct net_device *ndev) static int xcan_chip_start(struct net_device *ndev)
{ {
struct xcan_priv *priv = netdev_priv(ndev); struct xcan_priv *priv = netdev_priv(ndev);
u32 reg_msr, reg_sr_mask; u32 reg_msr;
int err; int err;
unsigned long timeout;
u32 ier; u32 ier;
/* Check if it is in reset mode */ /* Check if it is in reset mode */
...@@ -484,10 +484,8 @@ static int xcan_chip_start(struct net_device *ndev) ...@@ -484,10 +484,8 @@ static int xcan_chip_start(struct net_device *ndev)
/* Check whether it is loopback mode or normal mode */ /* Check whether it is loopback mode or normal mode */
if (priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK) { if (priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK) {
reg_msr = XCAN_MSR_LBACK_MASK; reg_msr = XCAN_MSR_LBACK_MASK;
reg_sr_mask = XCAN_SR_LBACK_MASK;
} else { } else {
reg_msr = 0x0; reg_msr = 0x0;
reg_sr_mask = XCAN_SR_NORMAL_MASK;
} }
/* enable the first extended filter, if any, as cores with extended /* enable the first extended filter, if any, as cores with extended
...@@ -499,14 +497,6 @@ static int xcan_chip_start(struct net_device *ndev) ...@@ -499,14 +497,6 @@ static int xcan_chip_start(struct net_device *ndev)
priv->write_reg(priv, XCAN_MSR_OFFSET, reg_msr); priv->write_reg(priv, XCAN_MSR_OFFSET, reg_msr);
priv->write_reg(priv, XCAN_SRR_OFFSET, XCAN_SRR_CEN_MASK); priv->write_reg(priv, XCAN_SRR_OFFSET, XCAN_SRR_CEN_MASK);
timeout = jiffies + XCAN_TIMEOUT;
while (!(priv->read_reg(priv, XCAN_SR_OFFSET) & reg_sr_mask)) {
if (time_after(jiffies, timeout)) {
netdev_warn(ndev,
"timed out for correct mode\n");
return -ETIMEDOUT;
}
}
netdev_dbg(ndev, "status:#x%08x\n", netdev_dbg(ndev, "status:#x%08x\n",
priv->read_reg(priv, XCAN_SR_OFFSET)); priv->read_reg(priv, XCAN_SR_OFFSET));
...@@ -600,7 +590,7 @@ static void xcan_write_frame(struct xcan_priv *priv, struct sk_buff *skb, ...@@ -600,7 +590,7 @@ static void xcan_write_frame(struct xcan_priv *priv, struct sk_buff *skb,
if (priv->devtype.cantype == XAXI_CANFD || if (priv->devtype.cantype == XAXI_CANFD ||
priv->devtype.cantype == XAXI_CANFD_2_0) { priv->devtype.cantype == XAXI_CANFD_2_0) {
for (i = 0; i < cf->len; i += 4) { for (i = 0; i < cf->len; i += 4) {
ramoff = XCANFD_FRAME_DW_OFFSET(frame_offset, dwindex) + ramoff = XCANFD_FRAME_DW_OFFSET(frame_offset) +
(dwindex * XCANFD_DW_BYTES); (dwindex * XCANFD_DW_BYTES);
priv->write_reg(priv, ramoff, priv->write_reg(priv, ramoff,
be32_to_cpup((__be32 *)(cf->data + i))); be32_to_cpup((__be32 *)(cf->data + i)));
...@@ -816,13 +806,9 @@ static int xcanfd_rx(struct net_device *ndev, int frame_base) ...@@ -816,13 +806,9 @@ static int xcanfd_rx(struct net_device *ndev, int frame_base)
struct net_device_stats *stats = &ndev->stats; struct net_device_stats *stats = &ndev->stats;
struct canfd_frame *cf; struct canfd_frame *cf;
struct sk_buff *skb; struct sk_buff *skb;
u32 id_xcan, dlc, data[2] = {0, 0}, dwindex = 0, i, fsr, readindex; u32 id_xcan, dlc, data[2] = {0, 0}, dwindex = 0, i, dw_offset;
fsr = priv->read_reg(priv, XCAN_FSR_OFFSET); id_xcan = priv->read_reg(priv, XCAN_FRAME_ID_OFFSET(frame_base));
if (fsr & XCAN_FSR_FL_MASK) {
readindex = fsr & XCAN_FSR_RI_MASK;
id_xcan = priv->read_reg(priv,
XCAN_FRAME_ID_OFFSET(frame_base));
dlc = priv->read_reg(priv, XCAN_FRAME_DLC_OFFSET(frame_base)); dlc = priv->read_reg(priv, XCAN_FRAME_DLC_OFFSET(frame_base));
if (dlc & XCAN_DLCR_EDL_MASK) if (dlc & XCAN_DLCR_EDL_MASK)
skb = alloc_canfd_skb(ndev, &cf); skb = alloc_canfd_skb(ndev, &cf);
...@@ -865,45 +851,24 @@ static int xcanfd_rx(struct net_device *ndev, int frame_base) ...@@ -865,45 +851,24 @@ static int xcanfd_rx(struct net_device *ndev, int frame_base)
/* Check the frame received is FD or not*/ /* Check the frame received is FD or not*/
if (dlc & XCAN_DLCR_EDL_MASK) { if (dlc & XCAN_DLCR_EDL_MASK) {
for (i = 0; i < cf->len; i += 4) { for (i = 0; i < cf->len; i += 4) {
if (priv->devtype.flags & XCAN_FLAG_CANFD_2) dw_offset = XCANFD_FRAME_DW_OFFSET(frame_base) +
data[0] = priv->read_reg(priv, (dwindex * XCANFD_DW_BYTES);
(XCAN_RXMSG_2_FRAME_OFFSET(readindex) + data[0] = priv->read_reg(priv, dw_offset);
(dwindex * XCANFD_DW_BYTES))); *(__be32 *)(cf->data + i) = cpu_to_be32(data[0]);
else
data[0] = priv->read_reg(priv,
(XCAN_RXMSG_FRAME_OFFSET(readindex) +
(dwindex * XCANFD_DW_BYTES)));
*(__be32 *)(cf->data + i) =
cpu_to_be32(data[0]);
dwindex++; dwindex++;
} }
} else { } else {
for (i = 0; i < cf->len; i += 4) { for (i = 0; i < cf->len; i += 4) {
if (priv->devtype.flags & XCAN_FLAG_CANFD_2) dw_offset = XCANFD_FRAME_DW_OFFSET(frame_base);
data[0] = priv->read_reg(priv, data[0] = priv->read_reg(priv, dw_offset + i);
XCAN_RXMSG_2_FRAME_OFFSET(readindex) + i); *(__be32 *)(cf->data + i) = cpu_to_be32(data[0]);
else
data[0] = priv->read_reg(priv,
XCAN_RXMSG_FRAME_OFFSET(readindex) + i);
*(__be32 *)(cf->data + i) =
cpu_to_be32(data[0]);
} }
} }
/* Update FSR Register so that next packet will save to
* buffer
*/
fsr = priv->read_reg(priv, XCAN_FSR_OFFSET);
fsr |= XCAN_FSR_IRI_MASK;
priv->write_reg(priv, XCAN_FSR_OFFSET, fsr);
fsr = priv->read_reg(priv, XCAN_FSR_OFFSET);
stats->rx_bytes += cf->len; stats->rx_bytes += cf->len;
stats->rx_packets++; stats->rx_packets++;
netif_receive_skb(skb); netif_receive_skb(skb);
return 1; return 1;
}
/* If FSR Register is not updated with fill level */
return 0;
} }
/** /**
...@@ -1164,7 +1129,7 @@ static int xcan_rx_fifo_get_next_frame(struct xcan_priv *priv) ...@@ -1164,7 +1129,7 @@ static int xcan_rx_fifo_get_next_frame(struct xcan_priv *priv)
int offset; int offset;
if (priv->devtype.flags & XCAN_FLAG_RX_FIFO_MULTI) { if (priv->devtype.flags & XCAN_FLAG_RX_FIFO_MULTI) {
u32 fsr; u32 fsr, mask;
/* clear RXOK before the is-empty check so that any newly /* clear RXOK before the is-empty check so that any newly
* received frame will reassert it without a race * received frame will reassert it without a race
...@@ -1174,12 +1139,17 @@ static int xcan_rx_fifo_get_next_frame(struct xcan_priv *priv) ...@@ -1174,12 +1139,17 @@ static int xcan_rx_fifo_get_next_frame(struct xcan_priv *priv)
fsr = priv->read_reg(priv, XCAN_FSR_OFFSET); fsr = priv->read_reg(priv, XCAN_FSR_OFFSET);
/* check if RX FIFO is empty */ /* check if RX FIFO is empty */
if (!(fsr & XCAN_FSR_FL_MASK)) if (priv->devtype.flags & XCAN_FLAG_CANFD_2)
mask = XCAN_2_FSR_FL_MASK;
else
mask = XCAN_FSR_FL_MASK;
if (!(fsr & mask))
return -ENOENT; return -ENOENT;
if (priv->devtype.flags & XCAN_FLAG_CANFD_2) if (priv->devtype.flags & XCAN_FLAG_CANFD_2)
offset = offset =
XCAN_RXMSG_2_FRAME_OFFSET(fsr & XCAN_FSR_RI_MASK); XCAN_RXMSG_2_FRAME_OFFSET(fsr & XCAN_2_FSR_RI_MASK);
else else
offset = offset =
XCAN_RXMSG_FRAME_OFFSET(fsr & XCAN_FSR_RI_MASK); XCAN_RXMSG_FRAME_OFFSET(fsr & XCAN_FSR_RI_MASK);
...@@ -1791,6 +1761,7 @@ static int xcan_probe(struct platform_device *pdev) ...@@ -1791,6 +1761,7 @@ static int xcan_probe(struct platform_device *pdev)
/* Getting the CAN can_clk info */ /* Getting the CAN can_clk info */
priv->can_clk = devm_clk_get(&pdev->dev, "can_clk"); priv->can_clk = devm_clk_get(&pdev->dev, "can_clk");
if (IS_ERR(priv->can_clk)) { if (IS_ERR(priv->can_clk)) {
if (PTR_ERR(priv->can_clk) != -EPROBE_DEFER)
dev_err(&pdev->dev, "Device clock not found.\n"); dev_err(&pdev->dev, "Device clock not found.\n");
ret = PTR_ERR(priv->can_clk); ret = PTR_ERR(priv->can_clk);
goto err_free; goto err_free;
......
...@@ -80,6 +80,10 @@ enum { ...@@ -80,6 +80,10 @@ enum {
CGW_DELETED, /* number of deleted CAN frames (see max_hops param) */ CGW_DELETED, /* number of deleted CAN frames (see max_hops param) */
CGW_LIM_HOPS, /* limit the number of hops of this specific rule */ CGW_LIM_HOPS, /* limit the number of hops of this specific rule */
CGW_MOD_UID, /* user defined identifier for modification updates */ CGW_MOD_UID, /* user defined identifier for modification updates */
CGW_FDMOD_AND, /* CAN FD frame modification binary AND */
CGW_FDMOD_OR, /* CAN FD frame modification binary OR */
CGW_FDMOD_XOR, /* CAN FD frame modification binary XOR */
CGW_FDMOD_SET, /* CAN FD frame modification set alternate values */
__CGW_MAX __CGW_MAX
}; };
...@@ -88,15 +92,18 @@ enum { ...@@ -88,15 +92,18 @@ enum {
#define CGW_FLAGS_CAN_ECHO 0x01 #define CGW_FLAGS_CAN_ECHO 0x01
#define CGW_FLAGS_CAN_SRC_TSTAMP 0x02 #define CGW_FLAGS_CAN_SRC_TSTAMP 0x02
#define CGW_FLAGS_CAN_IIF_TX_OK 0x04 #define CGW_FLAGS_CAN_IIF_TX_OK 0x04
#define CGW_FLAGS_CAN_FD 0x08
#define CGW_MOD_FUNCS 4 /* AND OR XOR SET */ #define CGW_MOD_FUNCS 4 /* AND OR XOR SET */
/* CAN frame elements that are affected by curr. 3 CAN frame modifications */ /* CAN frame elements that are affected by curr. 3 CAN frame modifications */
#define CGW_MOD_ID 0x01 #define CGW_MOD_ID 0x01
#define CGW_MOD_DLC 0x02 #define CGW_MOD_DLC 0x02 /* contains the data length in bytes */
#define CGW_MOD_LEN CGW_MOD_DLC /* CAN FD length representation */
#define CGW_MOD_DATA 0x04 #define CGW_MOD_DATA 0x04
#define CGW_MOD_FLAGS 0x08 /* CAN FD flags */
#define CGW_FRAME_MODS 3 /* ID DLC DATA */ #define CGW_FRAME_MODS 4 /* ID DLC/LEN DATA FLAGS */
#define MAX_MODFUNCTIONS (CGW_MOD_FUNCS * CGW_FRAME_MODS) #define MAX_MODFUNCTIONS (CGW_MOD_FUNCS * CGW_FRAME_MODS)
...@@ -105,7 +112,13 @@ struct cgw_frame_mod { ...@@ -105,7 +112,13 @@ struct cgw_frame_mod {
__u8 modtype; __u8 modtype;
} __attribute__((packed)); } __attribute__((packed));
struct cgw_fdframe_mod {
struct canfd_frame cf;
__u8 modtype;
} __attribute__((packed));
#define CGW_MODATTR_LEN sizeof(struct cgw_frame_mod) #define CGW_MODATTR_LEN sizeof(struct cgw_frame_mod)
#define CGW_FDMODATTR_LEN sizeof(struct cgw_fdframe_mod)
struct cgw_csum_xor { struct cgw_csum_xor {
__s8 from_idx; __s8 from_idx;
......
...@@ -40,15 +40,15 @@ struct can_bittiming { ...@@ -40,15 +40,15 @@ struct can_bittiming {
}; };
/* /*
* CAN harware-dependent bit-timing constant * CAN hardware-dependent bit-timing constant
* *
* Used for calculating and checking bit-timing parameters * Used for calculating and checking bit-timing parameters
*/ */
struct can_bittiming_const { struct can_bittiming_const {
char name[16]; /* Name of the CAN controller hardware */ char name[16]; /* Name of the CAN controller hardware */
__u32 tseg1_min; /* Time segement 1 = prop_seg + phase_seg1 */ __u32 tseg1_min; /* Time segment 1 = prop_seg + phase_seg1 */
__u32 tseg1_max; __u32 tseg1_max;
__u32 tseg2_min; /* Time segement 2 = phase_seg2 */ __u32 tseg2_min; /* Time segment 2 = phase_seg2 */
__u32 tseg2_max; __u32 tseg2_max;
__u32 sjw_max; /* Synchronisation jump width */ __u32 sjw_max; /* Synchronisation jump width */
__u32 brp_min; /* Bit-rate prescaler */ __u32 brp_min; /* Bit-rate prescaler */
......
// SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) // SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
/* /* af_can.c - Protocol family CAN core module
* af_can.c - Protocol family CAN core module
* (used by different CAN protocol modules) * (used by different CAN protocol modules)
* *
* Copyright (c) 2002-2017 Volkswagen Group Electronic Research * Copyright (c) 2002-2017 Volkswagen Group Electronic Research
...@@ -84,9 +83,7 @@ static DEFINE_MUTEX(proto_tab_lock); ...@@ -84,9 +83,7 @@ static DEFINE_MUTEX(proto_tab_lock);
static atomic_t skbcounter = ATOMIC_INIT(0); static atomic_t skbcounter = ATOMIC_INIT(0);
/* /* af_can socket functions */
* af_can socket functions
*/
static void can_sock_destruct(struct sock *sk) static void can_sock_destruct(struct sock *sk)
{ {
...@@ -132,14 +129,13 @@ static int can_create(struct net *net, struct socket *sock, int protocol, ...@@ -132,14 +129,13 @@ static int can_create(struct net *net, struct socket *sock, int protocol,
err = request_module("can-proto-%d", protocol); err = request_module("can-proto-%d", protocol);
/* /* In case of error we only print a message but don't
* In case of error we only print a message but don't
* return the error code immediately. Below we will * return the error code immediately. Below we will
* return -EPROTONOSUPPORT * return -EPROTONOSUPPORT
*/ */
if (err) if (err)
printk_ratelimited(KERN_ERR "can: request_module " pr_err_ratelimited("can: request_module (can-proto-%d) failed.\n",
"(can-proto-%d) failed.\n", protocol); protocol);
cp = can_get_proto(protocol); cp = can_get_proto(protocol);
} }
...@@ -180,9 +176,7 @@ static int can_create(struct net *net, struct socket *sock, int protocol, ...@@ -180,9 +176,7 @@ static int can_create(struct net *net, struct socket *sock, int protocol,
return err; return err;
} }
/* /* af_can tx path */
* af_can tx path
*/
/** /**
* can_send - transmit a CAN frame (optional with local loopback) * can_send - transmit a CAN frame (optional with local loopback)
...@@ -215,11 +209,11 @@ int can_send(struct sk_buff *skb, int loop) ...@@ -215,11 +209,11 @@ int can_send(struct sk_buff *skb, int loop)
skb->protocol = htons(ETH_P_CANFD); skb->protocol = htons(ETH_P_CANFD);
if (unlikely(cfd->len > CANFD_MAX_DLEN)) if (unlikely(cfd->len > CANFD_MAX_DLEN))
goto inval_skb; goto inval_skb;
} else } else {
goto inval_skb; goto inval_skb;
}
/* /* Make sure the CAN frame can pass the selected CAN netdevice.
* Make sure the CAN frame can pass the selected CAN netdevice.
* As structs can_frame and canfd_frame are similar, we can provide * As structs can_frame and canfd_frame are similar, we can provide
* CAN FD frames to legacy CAN drivers as long as the length is <= 8 * CAN FD frames to legacy CAN drivers as long as the length is <= 8
*/ */
...@@ -250,8 +244,7 @@ int can_send(struct sk_buff *skb, int loop) ...@@ -250,8 +244,7 @@ int can_send(struct sk_buff *skb, int loop)
/* indication for the CAN driver: do loopback */ /* indication for the CAN driver: do loopback */
skb->pkt_type = PACKET_LOOPBACK; skb->pkt_type = PACKET_LOOPBACK;
/* /* The reference to the originating sock may be required
* The reference to the originating sock may be required
* by the receiving socket to check whether the frame is * by the receiving socket to check whether the frame is
* its own. Example: can_raw sockopt CAN_RAW_RECV_OWN_MSGS * its own. Example: can_raw sockopt CAN_RAW_RECV_OWN_MSGS
* Therefore we have to ensure that skb->sk remains the * Therefore we have to ensure that skb->sk remains the
...@@ -260,8 +253,7 @@ int can_send(struct sk_buff *skb, int loop) ...@@ -260,8 +253,7 @@ int can_send(struct sk_buff *skb, int loop)
*/ */
if (!(skb->dev->flags & IFF_ECHO)) { if (!(skb->dev->flags & IFF_ECHO)) {
/* /* If the interface is not capable to do loopback
* If the interface is not capable to do loopback
* itself, we do it here. * itself, we do it here.
*/ */
newskb = skb_clone(skb, GFP_ATOMIC); newskb = skb_clone(skb, GFP_ATOMIC);
...@@ -304,9 +296,7 @@ int can_send(struct sk_buff *skb, int loop) ...@@ -304,9 +296,7 @@ int can_send(struct sk_buff *skb, int loop)
} }
EXPORT_SYMBOL(can_send); EXPORT_SYMBOL(can_send);
/* /* af_can rx path */
* af_can rx path
*/
static struct can_dev_rcv_lists *find_dev_rcv_lists(struct net *net, static struct can_dev_rcv_lists *find_dev_rcv_lists(struct net *net,
struct net_device *dev) struct net_device *dev)
...@@ -401,7 +391,6 @@ static struct hlist_head *find_rcv_list(canid_t *can_id, canid_t *mask, ...@@ -401,7 +391,6 @@ static struct hlist_head *find_rcv_list(canid_t *can_id, canid_t *mask,
/* extra filterlists for the subscription of a single non-RTR can_id */ /* extra filterlists for the subscription of a single non-RTR can_id */
if (((*mask & CAN_EFF_RTR_FLAGS) == CAN_EFF_RTR_FLAGS) && if (((*mask & CAN_EFF_RTR_FLAGS) == CAN_EFF_RTR_FLAGS) &&
!(*can_id & CAN_RTR_FLAG)) { !(*can_id & CAN_RTR_FLAG)) {
if (*can_id & CAN_EFF_FLAG) { if (*can_id & CAN_EFF_FLAG) {
if (*mask == (CAN_EFF_MASK | CAN_EFF_RTR_FLAGS)) if (*mask == (CAN_EFF_MASK | CAN_EFF_RTR_FLAGS))
return &d->rx_eff[effhash(*can_id)]; return &d->rx_eff[effhash(*can_id)];
...@@ -498,9 +487,7 @@ int can_rx_register(struct net *net, struct net_device *dev, canid_t can_id, ...@@ -498,9 +487,7 @@ int can_rx_register(struct net *net, struct net_device *dev, canid_t can_id,
} }
EXPORT_SYMBOL(can_rx_register); EXPORT_SYMBOL(can_rx_register);
/* /* can_rx_delete_receiver - rcu callback for single receiver entry removal */
* can_rx_delete_receiver - rcu callback for single receiver entry removal
*/
static void can_rx_delete_receiver(struct rcu_head *rp) static void can_rx_delete_receiver(struct rcu_head *rp)
{ {
struct receiver *r = container_of(rp, struct receiver, rcu); struct receiver *r = container_of(rp, struct receiver, rcu);
...@@ -541,16 +528,14 @@ void can_rx_unregister(struct net *net, struct net_device *dev, canid_t can_id, ...@@ -541,16 +528,14 @@ void can_rx_unregister(struct net *net, struct net_device *dev, canid_t can_id,
d = find_dev_rcv_lists(net, dev); d = find_dev_rcv_lists(net, dev);
if (!d) { if (!d) {
pr_err("BUG: receive list not found for " pr_err("BUG: receive list not found for dev %s, id %03X, mask %03X\n",
"dev %s, id %03X, mask %03X\n",
DNAME(dev), can_id, mask); DNAME(dev), can_id, mask);
goto out; goto out;
} }
rl = find_rcv_list(&can_id, &mask, d); rl = find_rcv_list(&can_id, &mask, d);
/* /* Search the receiver list for the item to delete. This should
* Search the receiver list for the item to delete. This should
* exist, since no receiver may be unregistered that hasn't * exist, since no receiver may be unregistered that hasn't
* been registered before. * been registered before.
*/ */
...@@ -561,14 +546,13 @@ void can_rx_unregister(struct net *net, struct net_device *dev, canid_t can_id, ...@@ -561,14 +546,13 @@ void can_rx_unregister(struct net *net, struct net_device *dev, canid_t can_id,
break; break;
} }
/* /* Check for bugs in CAN protocol implementations using af_can.c:
* Check for bugs in CAN protocol implementations using af_can.c:
* 'r' will be NULL if no matching list item was found for removal. * 'r' will be NULL if no matching list item was found for removal.
*/ */
if (!r) { if (!r) {
WARN(1, "BUG: receive list entry not found for dev %s, " WARN(1, "BUG: receive list entry not found for dev %s, id %03X, mask %03X\n",
"id %03X, mask %03X\n", DNAME(dev), can_id, mask); DNAME(dev), can_id, mask);
goto out; goto out;
} }
...@@ -737,9 +721,7 @@ static int canfd_rcv(struct sk_buff *skb, struct net_device *dev, ...@@ -737,9 +721,7 @@ static int canfd_rcv(struct sk_buff *skb, struct net_device *dev,
return NET_RX_SUCCESS; return NET_RX_SUCCESS;
} }
/* /* af_can protocol functions */
* af_can protocol functions
*/
/** /**
* can_proto_register - register CAN transport protocol * can_proto_register - register CAN transport protocol
...@@ -770,8 +752,9 @@ int can_proto_register(const struct can_proto *cp) ...@@ -770,8 +752,9 @@ int can_proto_register(const struct can_proto *cp)
if (rcu_access_pointer(proto_tab[proto])) { if (rcu_access_pointer(proto_tab[proto])) {
pr_err("can: protocol %d already registered\n", proto); pr_err("can: protocol %d already registered\n", proto);
err = -EBUSY; err = -EBUSY;
} else } else {
RCU_INIT_POINTER(proto_tab[proto], cp); RCU_INIT_POINTER(proto_tab[proto], cp);
}
mutex_unlock(&proto_tab_lock); mutex_unlock(&proto_tab_lock);
...@@ -801,9 +784,7 @@ void can_proto_unregister(const struct can_proto *cp) ...@@ -801,9 +784,7 @@ void can_proto_unregister(const struct can_proto *cp)
} }
EXPORT_SYMBOL(can_proto_unregister); EXPORT_SYMBOL(can_proto_unregister);
/* /* af_can notifier to create/remove CAN netdevice specific structs */
* af_can notifier to create/remove CAN netdevice specific structs
*/
static int can_notifier(struct notifier_block *nb, unsigned long msg, static int can_notifier(struct notifier_block *nb, unsigned long msg,
void *ptr) void *ptr)
{ {
...@@ -814,7 +795,6 @@ static int can_notifier(struct notifier_block *nb, unsigned long msg, ...@@ -814,7 +795,6 @@ static int can_notifier(struct notifier_block *nb, unsigned long msg,
return NOTIFY_DONE; return NOTIFY_DONE;
switch (msg) { switch (msg) {
case NETDEV_REGISTER: case NETDEV_REGISTER:
/* create new dev_rcv_lists for this device */ /* create new dev_rcv_lists for this device */
...@@ -831,15 +811,16 @@ static int can_notifier(struct notifier_block *nb, unsigned long msg, ...@@ -831,15 +811,16 @@ static int can_notifier(struct notifier_block *nb, unsigned long msg,
d = dev->ml_priv; d = dev->ml_priv;
if (d) { if (d) {
if (d->entries) if (d->entries) {
d->remove_on_zero_entries = 1; d->remove_on_zero_entries = 1;
else { } else {
kfree(d); kfree(d);
dev->ml_priv = NULL; dev->ml_priv = NULL;
} }
} else } else {
pr_err("can: notifier: receive list not found for dev " pr_err("can: notifier: receive list not found for dev %s\n",
"%s\n", dev->name); dev->name);
}
spin_unlock(&dev_net(dev)->can.can_rcvlists_lock); spin_unlock(&dev_net(dev)->can.can_rcvlists_lock);
...@@ -853,13 +834,13 @@ static int can_pernet_init(struct net *net) ...@@ -853,13 +834,13 @@ static int can_pernet_init(struct net *net)
{ {
spin_lock_init(&net->can.can_rcvlists_lock); spin_lock_init(&net->can.can_rcvlists_lock);
net->can.can_rx_alldev_list = net->can.can_rx_alldev_list =
kzalloc(sizeof(struct can_dev_rcv_lists), GFP_KERNEL); kzalloc(sizeof(*net->can.can_rx_alldev_list), GFP_KERNEL);
if (!net->can.can_rx_alldev_list) if (!net->can.can_rx_alldev_list)
goto out; goto out;
net->can.can_stats = kzalloc(sizeof(struct s_stats), GFP_KERNEL); net->can.can_stats = kzalloc(sizeof(*net->can.can_stats), GFP_KERNEL);
if (!net->can.can_stats) if (!net->can.can_stats)
goto out_free_alldev_list; goto out_free_alldev_list;
net->can.can_pstats = kzalloc(sizeof(struct s_pstats), GFP_KERNEL); net->can.can_pstats = kzalloc(sizeof(*net->can.can_pstats), GFP_KERNEL);
if (!net->can.can_pstats) if (!net->can.can_pstats)
goto out_free_can_stats; goto out_free_can_stats;
...@@ -913,9 +894,7 @@ static void can_pernet_exit(struct net *net) ...@@ -913,9 +894,7 @@ static void can_pernet_exit(struct net *net)
kfree(net->can.can_pstats); kfree(net->can.can_pstats);
} }
/* /* af_can module init/exit functions */
* af_can module init/exit functions
*/
static struct packet_type can_packet __read_mostly = { static struct packet_type can_packet __read_mostly = {
.type = cpu_to_be16(ETH_P_CAN), .type = cpu_to_be16(ETH_P_CAN),
......
/* SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) */ /* SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) */
/* /* Copyright (c) 2002-2007 Volkswagen Group Electronic Research
* Copyright (c) 2002-2007 Volkswagen Group Electronic Research
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
...@@ -54,7 +53,7 @@ struct receiver { ...@@ -54,7 +53,7 @@ struct receiver {
canid_t can_id; canid_t can_id;
canid_t mask; canid_t mask;
unsigned long matches; unsigned long matches;
void (*func)(struct sk_buff *, void *); void (*func)(struct sk_buff *skb, void *data);
void *data; void *data;
char *ident; char *ident;
struct sock *sk; struct sock *sk;
......
...@@ -106,7 +106,6 @@ struct bcm_op { ...@@ -106,7 +106,6 @@ struct bcm_op {
unsigned long frames_abs, frames_filtered; unsigned long frames_abs, frames_filtered;
struct bcm_timeval ival1, ival2; struct bcm_timeval ival1, ival2;
struct hrtimer timer, thrtimer; struct hrtimer timer, thrtimer;
struct tasklet_struct tsklet, thrtsklet;
ktime_t rx_stamp, kt_ival1, kt_ival2, kt_lastmsg; ktime_t rx_stamp, kt_ival1, kt_ival2, kt_lastmsg;
int rx_ifindex; int rx_ifindex;
int cfsiz; int cfsiz;
...@@ -371,25 +370,34 @@ static void bcm_send_to_user(struct bcm_op *op, struct bcm_msg_head *head, ...@@ -371,25 +370,34 @@ static void bcm_send_to_user(struct bcm_op *op, struct bcm_msg_head *head,
} }
} }
static void bcm_tx_start_timer(struct bcm_op *op) static bool bcm_tx_set_expiry(struct bcm_op *op, struct hrtimer *hrt)
{ {
ktime_t ival;
if (op->kt_ival1 && op->count) if (op->kt_ival1 && op->count)
hrtimer_start(&op->timer, ival = op->kt_ival1;
ktime_add(ktime_get(), op->kt_ival1),
HRTIMER_MODE_ABS);
else if (op->kt_ival2) else if (op->kt_ival2)
hrtimer_start(&op->timer, ival = op->kt_ival2;
ktime_add(ktime_get(), op->kt_ival2), else
HRTIMER_MODE_ABS); return false;
hrtimer_set_expires(hrt, ktime_add(ktime_get(), ival));
return true;
} }
static void bcm_tx_timeout_tsklet(unsigned long data) static void bcm_tx_start_timer(struct bcm_op *op)
{ {
struct bcm_op *op = (struct bcm_op *)data; if (bcm_tx_set_expiry(op, &op->timer))
hrtimer_start_expires(&op->timer, HRTIMER_MODE_ABS_SOFT);
}
/* bcm_tx_timeout_handler - performs cyclic CAN frame transmissions */
static enum hrtimer_restart bcm_tx_timeout_handler(struct hrtimer *hrtimer)
{
struct bcm_op *op = container_of(hrtimer, struct bcm_op, timer);
struct bcm_msg_head msg_head; struct bcm_msg_head msg_head;
if (op->kt_ival1 && (op->count > 0)) { if (op->kt_ival1 && (op->count > 0)) {
op->count--; op->count--;
if (!op->count && (op->flags & TX_COUNTEVT)) { if (!op->count && (op->flags & TX_COUNTEVT)) {
...@@ -406,22 +414,12 @@ static void bcm_tx_timeout_tsklet(unsigned long data) ...@@ -406,22 +414,12 @@ static void bcm_tx_timeout_tsklet(unsigned long data)
} }
bcm_can_tx(op); bcm_can_tx(op);
} else if (op->kt_ival2) } else if (op->kt_ival2) {
bcm_can_tx(op); bcm_can_tx(op);
}
bcm_tx_start_timer(op); return bcm_tx_set_expiry(op, &op->timer) ?
} HRTIMER_RESTART : HRTIMER_NORESTART;
/*
* bcm_tx_timeout_handler - performs cyclic CAN frame transmissions
*/
static enum hrtimer_restart bcm_tx_timeout_handler(struct hrtimer *hrtimer)
{
struct bcm_op *op = container_of(hrtimer, struct bcm_op, timer);
tasklet_schedule(&op->tsklet);
return HRTIMER_NORESTART;
} }
/* /*
...@@ -487,7 +485,7 @@ static void bcm_rx_update_and_send(struct bcm_op *op, ...@@ -487,7 +485,7 @@ static void bcm_rx_update_and_send(struct bcm_op *op,
/* do not send the saved data - only start throttle timer */ /* do not send the saved data - only start throttle timer */
hrtimer_start(&op->thrtimer, hrtimer_start(&op->thrtimer,
ktime_add(op->kt_lastmsg, op->kt_ival2), ktime_add(op->kt_lastmsg, op->kt_ival2),
HRTIMER_MODE_ABS); HRTIMER_MODE_ABS_SOFT);
return; return;
} }
...@@ -546,14 +544,21 @@ static void bcm_rx_starttimer(struct bcm_op *op) ...@@ -546,14 +544,21 @@ static void bcm_rx_starttimer(struct bcm_op *op)
return; return;
if (op->kt_ival1) if (op->kt_ival1)
hrtimer_start(&op->timer, op->kt_ival1, HRTIMER_MODE_REL); hrtimer_start(&op->timer, op->kt_ival1, HRTIMER_MODE_REL_SOFT);
} }
static void bcm_rx_timeout_tsklet(unsigned long data) /* bcm_rx_timeout_handler - when the (cyclic) CAN frame reception timed out */
static enum hrtimer_restart bcm_rx_timeout_handler(struct hrtimer *hrtimer)
{ {
struct bcm_op *op = (struct bcm_op *)data; struct bcm_op *op = container_of(hrtimer, struct bcm_op, timer);
struct bcm_msg_head msg_head; struct bcm_msg_head msg_head;
/* if user wants to be informed, when cyclic CAN-Messages come back */
if ((op->flags & RX_ANNOUNCE_RESUME) && op->last_frames) {
/* clear received CAN frames to indicate 'nothing received' */
memset(op->last_frames, 0, op->nframes * op->cfsiz);
}
/* create notification to user */ /* create notification to user */
msg_head.opcode = RX_TIMEOUT; msg_head.opcode = RX_TIMEOUT;
msg_head.flags = op->flags; msg_head.flags = op->flags;
...@@ -564,25 +569,6 @@ static void bcm_rx_timeout_tsklet(unsigned long data) ...@@ -564,25 +569,6 @@ static void bcm_rx_timeout_tsklet(unsigned long data)
msg_head.nframes = 0; msg_head.nframes = 0;
bcm_send_to_user(op, &msg_head, NULL, 0); bcm_send_to_user(op, &msg_head, NULL, 0);
}
/*
* bcm_rx_timeout_handler - when the (cyclic) CAN frame reception timed out
*/
static enum hrtimer_restart bcm_rx_timeout_handler(struct hrtimer *hrtimer)
{
struct bcm_op *op = container_of(hrtimer, struct bcm_op, timer);
/* schedule before NET_RX_SOFTIRQ */
tasklet_hi_schedule(&op->tsklet);
/* no restart of the timer is done here! */
/* if user wants to be informed, when cyclic CAN-Messages come back */
if ((op->flags & RX_ANNOUNCE_RESUME) && op->last_frames) {
/* clear received CAN frames to indicate 'nothing received' */
memset(op->last_frames, 0, op->nframes * op->cfsiz);
}
return HRTIMER_NORESTART; return HRTIMER_NORESTART;
} }
...@@ -590,13 +576,11 @@ static enum hrtimer_restart bcm_rx_timeout_handler(struct hrtimer *hrtimer) ...@@ -590,13 +576,11 @@ static enum hrtimer_restart bcm_rx_timeout_handler(struct hrtimer *hrtimer)
/* /*
* bcm_rx_do_flush - helper for bcm_rx_thr_flush * bcm_rx_do_flush - helper for bcm_rx_thr_flush
*/ */
static inline int bcm_rx_do_flush(struct bcm_op *op, int update, static inline int bcm_rx_do_flush(struct bcm_op *op, unsigned int index)
unsigned int index)
{ {
struct canfd_frame *lcf = op->last_frames + op->cfsiz * index; struct canfd_frame *lcf = op->last_frames + op->cfsiz * index;
if ((op->last_frames) && (lcf->flags & RX_THR)) { if ((op->last_frames) && (lcf->flags & RX_THR)) {
if (update)
bcm_rx_changed(op, lcf); bcm_rx_changed(op, lcf);
return 1; return 1;
} }
...@@ -605,11 +589,8 @@ static inline int bcm_rx_do_flush(struct bcm_op *op, int update, ...@@ -605,11 +589,8 @@ static inline int bcm_rx_do_flush(struct bcm_op *op, int update,
/* /*
* bcm_rx_thr_flush - Check for throttled data and send it to the userspace * bcm_rx_thr_flush - Check for throttled data and send it to the userspace
*
* update == 0 : just check if throttled data is available (any irq context)
* update == 1 : check and send throttled data to userspace (soft_irq context)
*/ */
static int bcm_rx_thr_flush(struct bcm_op *op, int update) static int bcm_rx_thr_flush(struct bcm_op *op)
{ {
int updated = 0; int updated = 0;
...@@ -618,24 +599,16 @@ static int bcm_rx_thr_flush(struct bcm_op *op, int update) ...@@ -618,24 +599,16 @@ static int bcm_rx_thr_flush(struct bcm_op *op, int update)
/* for MUX filter we start at index 1 */ /* for MUX filter we start at index 1 */
for (i = 1; i < op->nframes; i++) for (i = 1; i < op->nframes; i++)
updated += bcm_rx_do_flush(op, update, i); updated += bcm_rx_do_flush(op, i);
} else { } else {
/* for RX_FILTER_ID and simple filter */ /* for RX_FILTER_ID and simple filter */
updated += bcm_rx_do_flush(op, update, 0); updated += bcm_rx_do_flush(op, 0);
} }
return updated; return updated;
} }
static void bcm_rx_thr_tsklet(unsigned long data)
{
struct bcm_op *op = (struct bcm_op *)data;
/* push the changed data to the userspace */
bcm_rx_thr_flush(op, 1);
}
/* /*
* bcm_rx_thr_handler - the time for blocked content updates is over now: * bcm_rx_thr_handler - the time for blocked content updates is over now:
* Check for throttled data and send it to the userspace * Check for throttled data and send it to the userspace
...@@ -644,9 +617,7 @@ static enum hrtimer_restart bcm_rx_thr_handler(struct hrtimer *hrtimer) ...@@ -644,9 +617,7 @@ static enum hrtimer_restart bcm_rx_thr_handler(struct hrtimer *hrtimer)
{ {
struct bcm_op *op = container_of(hrtimer, struct bcm_op, thrtimer); struct bcm_op *op = container_of(hrtimer, struct bcm_op, thrtimer);
tasklet_schedule(&op->thrtsklet); if (bcm_rx_thr_flush(op)) {
if (bcm_rx_thr_flush(op, 0)) {
hrtimer_forward(hrtimer, ktime_get(), op->kt_ival2); hrtimer_forward(hrtimer, ktime_get(), op->kt_ival2);
return HRTIMER_RESTART; return HRTIMER_RESTART;
} else { } else {
...@@ -742,23 +713,8 @@ static struct bcm_op *bcm_find_op(struct list_head *ops, ...@@ -742,23 +713,8 @@ static struct bcm_op *bcm_find_op(struct list_head *ops,
static void bcm_remove_op(struct bcm_op *op) static void bcm_remove_op(struct bcm_op *op)
{ {
if (op->tsklet.func) {
while (test_bit(TASKLET_STATE_SCHED, &op->tsklet.state) ||
test_bit(TASKLET_STATE_RUN, &op->tsklet.state) ||
hrtimer_active(&op->timer)) {
hrtimer_cancel(&op->timer); hrtimer_cancel(&op->timer);
tasklet_kill(&op->tsklet);
}
}
if (op->thrtsklet.func) {
while (test_bit(TASKLET_STATE_SCHED, &op->thrtsklet.state) ||
test_bit(TASKLET_STATE_RUN, &op->thrtsklet.state) ||
hrtimer_active(&op->thrtimer)) {
hrtimer_cancel(&op->thrtimer); hrtimer_cancel(&op->thrtimer);
tasklet_kill(&op->thrtsklet);
}
}
if ((op->frames) && (op->frames != &op->sframe)) if ((op->frames) && (op->frames != &op->sframe))
kfree(op->frames); kfree(op->frames);
...@@ -991,15 +947,13 @@ static int bcm_tx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg, ...@@ -991,15 +947,13 @@ static int bcm_tx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,
op->ifindex = ifindex; op->ifindex = ifindex;
/* initialize uninitialized (kzalloc) structure */ /* initialize uninitialized (kzalloc) structure */
hrtimer_init(&op->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); hrtimer_init(&op->timer, CLOCK_MONOTONIC,
HRTIMER_MODE_REL_SOFT);
op->timer.function = bcm_tx_timeout_handler; op->timer.function = bcm_tx_timeout_handler;
/* initialize tasklet for tx countevent notification */
tasklet_init(&op->tsklet, bcm_tx_timeout_tsklet,
(unsigned long) op);
/* currently unused in tx_ops */ /* currently unused in tx_ops */
hrtimer_init(&op->thrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); hrtimer_init(&op->thrtimer, CLOCK_MONOTONIC,
HRTIMER_MODE_REL_SOFT);
/* add this bcm_op to the list of the tx_ops */ /* add this bcm_op to the list of the tx_ops */
list_add(&op->list, &bo->tx_ops); list_add(&op->list, &bo->tx_ops);
...@@ -1168,20 +1122,14 @@ static int bcm_rx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg, ...@@ -1168,20 +1122,14 @@ static int bcm_rx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,
op->rx_ifindex = ifindex; op->rx_ifindex = ifindex;
/* initialize uninitialized (kzalloc) structure */ /* initialize uninitialized (kzalloc) structure */
hrtimer_init(&op->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); hrtimer_init(&op->timer, CLOCK_MONOTONIC,
HRTIMER_MODE_REL_SOFT);
op->timer.function = bcm_rx_timeout_handler; op->timer.function = bcm_rx_timeout_handler;
/* initialize tasklet for rx timeout notification */ hrtimer_init(&op->thrtimer, CLOCK_MONOTONIC,
tasklet_init(&op->tsklet, bcm_rx_timeout_tsklet, HRTIMER_MODE_REL_SOFT);
(unsigned long) op);
hrtimer_init(&op->thrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
op->thrtimer.function = bcm_rx_thr_handler; op->thrtimer.function = bcm_rx_thr_handler;
/* initialize tasklet for rx throttle handling */
tasklet_init(&op->thrtsklet, bcm_rx_thr_tsklet,
(unsigned long) op);
/* add this bcm_op to the list of the rx_ops */ /* add this bcm_op to the list of the rx_ops */
list_add(&op->list, &bo->rx_ops); list_add(&op->list, &bo->rx_ops);
...@@ -1227,12 +1175,12 @@ static int bcm_rx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg, ...@@ -1227,12 +1175,12 @@ static int bcm_rx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,
*/ */
op->kt_lastmsg = 0; op->kt_lastmsg = 0;
hrtimer_cancel(&op->thrtimer); hrtimer_cancel(&op->thrtimer);
bcm_rx_thr_flush(op, 1); bcm_rx_thr_flush(op);
} }
if ((op->flags & STARTTIMER) && op->kt_ival1) if ((op->flags & STARTTIMER) && op->kt_ival1)
hrtimer_start(&op->timer, op->kt_ival1, hrtimer_start(&op->timer, op->kt_ival1,
HRTIMER_MODE_REL); HRTIMER_MODE_REL_SOFT);
} }
/* now we can register for can_ids, if we added a new bcm_op */ /* now we can register for can_ids, if we added a new bcm_op */
...@@ -1680,7 +1628,7 @@ static int bcm_recvmsg(struct socket *sock, struct msghdr *msg, size_t size, ...@@ -1680,7 +1628,7 @@ static int bcm_recvmsg(struct socket *sock, struct msghdr *msg, size_t size,
return size; return size;
} }
int bcm_sock_no_ioctlcmd(struct socket *sock, unsigned int cmd, static int bcm_sock_no_ioctlcmd(struct socket *sock, unsigned int cmd,
unsigned long arg) unsigned long arg)
{ {
/* no ioctls for socket layer -> hand it down to NIC layer */ /* no ioctls for socket layer -> hand it down to NIC layer */
......
This diff is collapsed.
// SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) // SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause)
/* /* raw.c - Raw sockets for protocol family CAN
* raw.c - Raw sockets for protocol family CAN
* *
* Copyright (c) 2002-2007 Volkswagen Group Electronic Research * Copyright (c) 2002-2007 Volkswagen Group Electronic Research
* All rights reserved. * All rights reserved.
...@@ -65,8 +64,7 @@ MODULE_ALIAS("can-proto-1"); ...@@ -65,8 +64,7 @@ MODULE_ALIAS("can-proto-1");
#define MASK_ALL 0 #define MASK_ALL 0
/* /* A raw socket has a list of can_filters attached to it, each receiving
* A raw socket has a list of can_filters attached to it, each receiving
* the CAN frames matching that filter. If the filter list is empty, * the CAN frames matching that filter. If the filter list is empty,
* no CAN frames will be received by the socket. The default after * no CAN frames will be received by the socket. The default after
* opening the socket, is to have one filter which receives all frames. * opening the socket, is to have one filter which receives all frames.
...@@ -97,8 +95,7 @@ struct raw_sock { ...@@ -97,8 +95,7 @@ struct raw_sock {
struct uniqframe __percpu *uniq; struct uniqframe __percpu *uniq;
}; };
/* /* Return pointer to store the extra msg flags for raw_recvmsg().
* Return pointer to store the extra msg flags for raw_recvmsg().
* We use the space of one unsigned int beyond the 'struct sockaddr_can' * We use the space of one unsigned int beyond the 'struct sockaddr_can'
* in skb->cb. * in skb->cb.
*/ */
...@@ -157,8 +154,7 @@ static void raw_rcv(struct sk_buff *oskb, void *data) ...@@ -157,8 +154,7 @@ static void raw_rcv(struct sk_buff *oskb, void *data)
if (!skb) if (!skb)
return; return;
/* /* Put the datagram to the queue so that raw_recvmsg() can
* Put the datagram to the queue so that raw_recvmsg() can
* get it from there. We need to pass the interface index to * get it from there. We need to pass the interface index to
* raw_recvmsg(). We pass a whole struct sockaddr_can in skb->cb * raw_recvmsg(). We pass a whole struct sockaddr_can in skb->cb
* containing the interface index. * containing the interface index.
...@@ -284,7 +280,6 @@ static int raw_notifier(struct notifier_block *nb, ...@@ -284,7 +280,6 @@ static int raw_notifier(struct notifier_block *nb,
return NOTIFY_DONE; return NOTIFY_DONE;
switch (msg) { switch (msg) {
case NETDEV_UNREGISTER: case NETDEV_UNREGISTER:
lock_sock(sk); lock_sock(sk);
/* remove current filters & unregister */ /* remove current filters & unregister */
...@@ -370,9 +365,10 @@ static int raw_release(struct socket *sock) ...@@ -370,9 +365,10 @@ static int raw_release(struct socket *sock)
raw_disable_allfilters(dev_net(dev), dev, sk); raw_disable_allfilters(dev_net(dev), dev, sk);
dev_put(dev); dev_put(dev);
} }
} else } else {
raw_disable_allfilters(sock_net(sk), NULL, sk); raw_disable_allfilters(sock_net(sk), NULL, sk);
} }
}
if (ro->count > 1) if (ro->count > 1)
kfree(ro->filter); kfree(ro->filter);
...@@ -451,9 +447,10 @@ static int raw_bind(struct socket *sock, struct sockaddr *uaddr, int len) ...@@ -451,9 +447,10 @@ static int raw_bind(struct socket *sock, struct sockaddr *uaddr, int len)
dev, sk); dev, sk);
dev_put(dev); dev_put(dev);
} }
} else } else {
raw_disable_allfilters(sock_net(sk), NULL, sk); raw_disable_allfilters(sock_net(sk), NULL, sk);
} }
}
ro->ifindex = ifindex; ro->ifindex = ifindex;
ro->bound = 1; ro->bound = 1;
} }
...@@ -503,7 +500,6 @@ static int raw_setsockopt(struct socket *sock, int level, int optname, ...@@ -503,7 +500,6 @@ static int raw_setsockopt(struct socket *sock, int level, int optname,
return -EINVAL; return -EINVAL;
switch (optname) { switch (optname) {
case CAN_RAW_FILTER: case CAN_RAW_FILTER:
if (optlen % sizeof(struct can_filter) != 0) if (optlen % sizeof(struct can_filter) != 0)
return -EINVAL; return -EINVAL;
...@@ -666,17 +662,18 @@ static int raw_getsockopt(struct socket *sock, int level, int optname, ...@@ -666,17 +662,18 @@ static int raw_getsockopt(struct socket *sock, int level, int optname,
return -EINVAL; return -EINVAL;
switch (optname) { switch (optname) {
case CAN_RAW_FILTER: case CAN_RAW_FILTER:
lock_sock(sk); lock_sock(sk);
if (ro->count > 0) { if (ro->count > 0) {
int fsize = ro->count * sizeof(struct can_filter); int fsize = ro->count * sizeof(struct can_filter);
if (len > fsize) if (len > fsize)
len = fsize; len = fsize;
if (copy_to_user(optval, ro->filter, len)) if (copy_to_user(optval, ro->filter, len))
err = -EFAULT; err = -EFAULT;
} else } else {
len = 0; len = 0;
}
release_sock(sk); release_sock(sk);
if (!err) if (!err)
...@@ -743,8 +740,9 @@ static int raw_sendmsg(struct socket *sock, struct msghdr *msg, size_t size) ...@@ -743,8 +740,9 @@ static int raw_sendmsg(struct socket *sock, struct msghdr *msg, size_t size)
return -EINVAL; return -EINVAL;
ifindex = addr->can_ifindex; ifindex = addr->can_ifindex;
} else } else {
ifindex = ro->ifindex; ifindex = ro->ifindex;
}
dev = dev_get_by_index(sock_net(sk), ifindex); dev = dev_get_by_index(sock_net(sk), ifindex);
if (!dev) if (!dev)
...@@ -837,7 +835,7 @@ static int raw_recvmsg(struct socket *sock, struct msghdr *msg, size_t size, ...@@ -837,7 +835,7 @@ static int raw_recvmsg(struct socket *sock, struct msghdr *msg, size_t size,
return size; return size;
} }
int raw_sock_no_ioctlcmd(struct socket *sock, unsigned int cmd, static int raw_sock_no_ioctlcmd(struct socket *sock, unsigned int cmd,
unsigned long arg) unsigned long arg)
{ {
/* no ioctls for socket layer -> hand it down to NIC layer */ /* no ioctls for socket layer -> hand it down to NIC layer */
...@@ -887,7 +885,7 @@ static __init int raw_module_init(void) ...@@ -887,7 +885,7 @@ static __init int raw_module_init(void)
err = can_proto_register(&raw_can_proto); err = can_proto_register(&raw_can_proto);
if (err < 0) if (err < 0)
printk(KERN_ERR "can: registration of raw protocol failed\n"); pr_err("can: registration of raw protocol failed\n");
return err; return err;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment