Commit f7b88d9a authored by Jakub Kicinski's avatar Jakub Kicinski

Merge tag 'linux-can-next-for-5.19-20220516' of...

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

Marc Kleine-Budde says:

====================
pull-request: can-next 2022-05-16

the first 2 patches are by me and target the CAN raw protocol. The 1st
removes an unneeded assignment, the other one adds support for
SO_TXTIME/SCM_TXTIME.

Oliver Hartkopp contributes 2 patches for the ISOTP protocol. The 1st
adds support for transmission without flow control, the other let's
bind() return an error on incorrect CAN ID formatting.

Geert Uytterhoeven contributes a patch to clean up ctucanfd's Kconfig
file.

Vincent Mailhol's patch for the slcan driver uses the proper function
to check for invalid CAN frames in the xmit callback.

The next patch is by Geert Uytterhoeven and makes the interrupt-names
of the renesas,rcar-canfd dt bindings mandatory.

A patch by my update the ctucanfd dt bindings to include the common
CAN controller bindings.

The last patch is by Akira Yokosawa and fixes a breakage the
ctucanfd's documentation.

* tag 'linux-can-next-for-5.19-20220516' of git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can-next:
  docs: ctucanfd: Use 'kernel-figure' directive instead of 'figure'
  dt-bindings: can: ctucanfd: include common CAN controller bindings
  dt-bindings: can: renesas,rcar-canfd: Make interrupt-names required
  can: slcan: slc_xmit(): use can_dropped_invalid_skb() instead of manual check
  can: ctucanfd: Let users select instead of depend on CAN_CTUCANFD
  can: isotp: isotp_bind(): return -EINVAL on incorrect CAN ID formatting
  can: isotp: add support for transmission without flow control
  can: raw: add support for SO_TXTIME/SCM_TXTIME
  can: raw: raw_sendmsg(): remove not needed setting of skb->sk
====================

Link: https://lore.kernel.org/r/20220516202625.1129281-1-mkl@pengutronix.deSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 7fb18c0a ba3e2eae
......@@ -25,6 +25,9 @@ maintainers:
- Ondrej Ille <ondrej.ille@gmail.com>
- Martin Jerabek <martin.jerabek01@gmail.com>
allOf:
- $ref: can-controller.yaml#
properties:
compatible:
oneOf:
......
......@@ -88,6 +88,7 @@ required:
- compatible
- reg
- interrupts
- interrupt-names
- clocks
- clock-names
- power-domains
......@@ -136,7 +137,6 @@ then:
- const: rstc_n
required:
- interrupt-names
- reset-names
else:
properties:
......@@ -167,6 +167,7 @@ examples:
reg = <0xe66c0000 0x8000>;
interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "ch_int", "g_int";
clocks = <&cpg CPG_MOD 914>,
<&cpg CPG_CORE R8A7795_CLK_CANFD>,
<&can_clk>;
......
......@@ -72,7 +72,7 @@ it is reachable (on which bus it resides) and its configuration –
registers address, interrupts and so on. An example of such a device
tree is given in .
.. code:: raw
::
/ {
/* ... */
......@@ -451,7 +451,7 @@ the FIFO is maintained, together with priority rotation, is depicted in
|
.. figure:: fsm_txt_buffer_user.svg
.. kernel-figure:: fsm_txt_buffer_user.svg
TX Buffer states with possible transitions
......
config CAN_CTUCANFD
tristate "CTU CAN-FD IP core"
tristate "CTU CAN-FD IP core" if COMPILE_TEST
help
This driver adds support for the CTU CAN FD open-source IP core.
More documentation and core sources at project page
......@@ -13,8 +13,8 @@ config CAN_CTUCANFD
config CAN_CTUCANFD_PCI
tristate "CTU CAN-FD IP core PCI/PCIe driver"
depends on CAN_CTUCANFD
depends on PCI
select CAN_CTUCANFD
help
This driver adds PCI/PCIe support for CTU CAN-FD IP core.
The project providing FPGA design for Intel EP4CGX15 based DB4CGX15
......@@ -23,8 +23,8 @@ config CAN_CTUCANFD_PCI
config CAN_CTUCANFD_PLATFORM
tristate "CTU CAN-FD IP core platform (FPGA, SoC) driver"
depends on CAN_CTUCANFD
depends on OF || COMPILE_TEST
select CAN_CTUCANFD
help
The core has been tested together with OpenCores SJA1000
modified to be CAN FD frames tolerant on MicroZed Zynq based
......
......@@ -359,8 +359,8 @@ static netdev_tx_t slc_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct slcan *sl = netdev_priv(dev);
if (skb->len != CAN_MTU)
goto out;
if (can_dropped_invalid_skb(dev, skb))
return NETDEV_TX_OK;
spin_lock(&sl->lock);
if (!netif_running(dev)) {
......
......@@ -124,18 +124,19 @@ struct can_isotp_ll_options {
/* flags for isotp behaviour */
#define CAN_ISOTP_LISTEN_MODE 0x001 /* listen only (do not send FC) */
#define CAN_ISOTP_EXTEND_ADDR 0x002 /* enable extended addressing */
#define CAN_ISOTP_TX_PADDING 0x004 /* enable CAN frame padding tx path */
#define CAN_ISOTP_RX_PADDING 0x008 /* enable CAN frame padding rx path */
#define CAN_ISOTP_CHK_PAD_LEN 0x010 /* check received CAN frame padding */
#define CAN_ISOTP_CHK_PAD_DATA 0x020 /* check received CAN frame padding */
#define CAN_ISOTP_HALF_DUPLEX 0x040 /* half duplex error state handling */
#define CAN_ISOTP_FORCE_TXSTMIN 0x080 /* ignore stmin from received FC */
#define CAN_ISOTP_FORCE_RXSTMIN 0x100 /* ignore CFs depending on rx stmin */
#define CAN_ISOTP_RX_EXT_ADDR 0x200 /* different rx extended addressing */
#define CAN_ISOTP_WAIT_TX_DONE 0x400 /* wait for tx completion */
#define CAN_ISOTP_SF_BROADCAST 0x800 /* 1-to-N functional addressing */
#define CAN_ISOTP_LISTEN_MODE 0x0001 /* listen only (do not send FC) */
#define CAN_ISOTP_EXTEND_ADDR 0x0002 /* enable extended addressing */
#define CAN_ISOTP_TX_PADDING 0x0004 /* enable CAN frame padding tx path */
#define CAN_ISOTP_RX_PADDING 0x0008 /* enable CAN frame padding rx path */
#define CAN_ISOTP_CHK_PAD_LEN 0x0010 /* check received CAN frame padding */
#define CAN_ISOTP_CHK_PAD_DATA 0x0020 /* check received CAN frame padding */
#define CAN_ISOTP_HALF_DUPLEX 0x0040 /* half duplex error state handling */
#define CAN_ISOTP_FORCE_TXSTMIN 0x0080 /* ignore stmin from received FC */
#define CAN_ISOTP_FORCE_RXSTMIN 0x0100 /* ignore CFs depending on rx stmin */
#define CAN_ISOTP_RX_EXT_ADDR 0x0200 /* different rx extended addressing */
#define CAN_ISOTP_WAIT_TX_DONE 0x0400 /* wait for tx completion */
#define CAN_ISOTP_SF_BROADCAST 0x0800 /* 1-to-N functional addressing */
#define CAN_ISOTP_CF_BROADCAST 0x1000 /* 1-to-N transmission w/o FC */
/* protocol machine default values */
......
......@@ -104,6 +104,7 @@ MODULE_ALIAS("can-proto-6");
#define FC_CONTENT_SZ 3 /* flow control content size in byte (FS/BS/STmin) */
#define ISOTP_CHECK_PADDING (CAN_ISOTP_CHK_PAD_LEN | CAN_ISOTP_CHK_PAD_DATA)
#define ISOTP_ALL_BC_FLAGS (CAN_ISOTP_SF_BROADCAST | CAN_ISOTP_CF_BROADCAST)
/* Flow Status given in FC frame */
#define ISOTP_FC_CTS 0 /* clear to send */
......@@ -159,6 +160,23 @@ static inline struct isotp_sock *isotp_sk(const struct sock *sk)
return (struct isotp_sock *)sk;
}
static u32 isotp_bc_flags(struct isotp_sock *so)
{
return so->opt.flags & ISOTP_ALL_BC_FLAGS;
}
static bool isotp_register_rxid(struct isotp_sock *so)
{
/* no broadcast modes => register rx_id for FC frame reception */
return (isotp_bc_flags(so) == 0);
}
static bool isotp_register_txecho(struct isotp_sock *so)
{
/* all modes but SF_BROADCAST register for tx echo skbs */
return (isotp_bc_flags(so) != CAN_ISOTP_SF_BROADCAST);
}
static enum hrtimer_restart isotp_rx_timer_handler(struct hrtimer *hrtimer)
{
struct isotp_sock *so = container_of(hrtimer, struct isotp_sock,
......@@ -803,7 +821,6 @@ static void isotp_create_fframe(struct canfd_frame *cf, struct isotp_sock *so,
cf->data[i] = so->tx.buf[so->tx.idx++];
so->tx.sn = 1;
so->tx.state = ISOTP_WAIT_FIRST_FC;
}
static void isotp_rcv_echo(struct sk_buff *skb, void *data)
......@@ -936,7 +953,7 @@ static int isotp_sendmsg(struct socket *sock, struct msghdr *msg, size_t size)
off = (so->tx.ll_dl > CAN_MAX_DLEN) ? 1 : 0;
/* does the given data fit into a single frame for SF_BROADCAST? */
if ((so->opt.flags & CAN_ISOTP_SF_BROADCAST) &&
if ((isotp_bc_flags(so) == CAN_ISOTP_SF_BROADCAST) &&
(size > so->tx.ll_dl - SF_PCI_SZ4 - ae - off)) {
err = -EINVAL;
goto err_out_drop;
......@@ -1000,12 +1017,41 @@ static int isotp_sendmsg(struct socket *sock, struct msghdr *msg, size_t size)
/* don't enable wait queue for a single frame transmission */
wait_tx_done = 0;
} else {
/* send first frame and wait for FC */
/* send first frame */
isotp_create_fframe(cf, so, ae);
/* start timeout for FC */
hrtimer_sec = 1;
if (isotp_bc_flags(so) == CAN_ISOTP_CF_BROADCAST) {
/* set timer for FC-less operation (STmin = 0) */
if (so->opt.flags & CAN_ISOTP_FORCE_TXSTMIN)
so->tx_gap = ktime_set(0, so->force_tx_stmin);
else
so->tx_gap = ktime_set(0, so->frame_txtime);
/* disable wait for FCs due to activated block size */
so->txfc.bs = 0;
/* cfecho should have been zero'ed by init */
if (so->cfecho)
pr_notice_once("can-isotp: no fc cfecho %08X\n",
so->cfecho);
/* set consecutive frame echo tag */
so->cfecho = *(u32 *)cf->data;
/* switch directly to ISOTP_SENDING state */
so->tx.state = ISOTP_SENDING;
/* start timeout for unlikely lost echo skb */
hrtimer_sec = 2;
} else {
/* standard flow control check */
so->tx.state = ISOTP_WAIT_FIRST_FC;
/* start timeout for FC */
hrtimer_sec = 1;
}
hrtimer_start(&so->txtimer, ktime_set(hrtimer_sec, 0),
HRTIMER_MODE_REL_SOFT);
}
......@@ -1025,6 +1071,9 @@ static int isotp_sendmsg(struct socket *sock, struct msghdr *msg, size_t size)
if (hrtimer_sec)
hrtimer_cancel(&so->txtimer);
/* reset consecutive frame echo tag */
so->cfecho = 0;
goto err_out_drop;
}
......@@ -1120,15 +1169,17 @@ static int isotp_release(struct socket *sock)
lock_sock(sk);
/* remove current filters & unregister */
if (so->bound && (!(so->opt.flags & CAN_ISOTP_SF_BROADCAST))) {
if (so->bound && isotp_register_txecho(so)) {
if (so->ifindex) {
struct net_device *dev;
dev = dev_get_by_index(net, so->ifindex);
if (dev) {
can_rx_unregister(net, dev, so->rxid,
SINGLE_MASK(so->rxid),
isotp_rcv, sk);
if (isotp_register_rxid(so))
can_rx_unregister(net, dev, so->rxid,
SINGLE_MASK(so->rxid),
isotp_rcv, sk);
can_rx_unregister(net, dev, so->txid,
SINGLE_MASK(so->txid),
isotp_rcv_echo, sk);
......@@ -1164,7 +1215,6 @@ static int isotp_bind(struct socket *sock, struct sockaddr *uaddr, int len)
canid_t tx_id, rx_id;
int err = 0;
int notify_enetdown = 0;
int do_rx_reg = 1;
if (len < ISOTP_MIN_NAMELEN)
return -EINVAL;
......@@ -1182,6 +1232,11 @@ static int isotp_bind(struct socket *sock, struct sockaddr *uaddr, int len)
else
rx_id &= CAN_SFF_MASK;
/* give feedback on wrong CAN-ID values */
if (tx_id != addr->can_addr.tp.tx_id ||
rx_id != addr->can_addr.tp.rx_id)
return -EINVAL;
if (!addr->can_ifindex)
return -ENODEV;
......@@ -1192,12 +1247,8 @@ static int isotp_bind(struct socket *sock, struct sockaddr *uaddr, int len)
goto out;
}
/* do not register frame reception for functional addressing */
if (so->opt.flags & CAN_ISOTP_SF_BROADCAST)
do_rx_reg = 0;
/* do not validate rx address for functional addressing */
if (do_rx_reg && rx_id == tx_id) {
/* ensure different CAN IDs when the rx_id is to be registered */
if (isotp_register_rxid(so) && rx_id == tx_id) {
err = -EADDRNOTAVAIL;
goto out;
}
......@@ -1222,10 +1273,11 @@ static int isotp_bind(struct socket *sock, struct sockaddr *uaddr, int len)
ifindex = dev->ifindex;
if (do_rx_reg) {
if (isotp_register_rxid(so))
can_rx_register(net, dev, rx_id, SINGLE_MASK(rx_id),
isotp_rcv, sk, "isotp", sk);
if (isotp_register_txecho(so)) {
/* no consecutive frame echo skb in flight */
so->cfecho = 0;
......@@ -1294,6 +1346,15 @@ static int isotp_setsockopt_locked(struct socket *sock, int level, int optname,
if (!(so->opt.flags & CAN_ISOTP_RX_EXT_ADDR))
so->opt.rx_ext_address = so->opt.ext_address;
/* these broadcast flags are not allowed together */
if (isotp_bc_flags(so) == ISOTP_ALL_BC_FLAGS) {
/* CAN_ISOTP_SF_BROADCAST is prioritized */
so->opt.flags &= ~CAN_ISOTP_CF_BROADCAST;
/* give user feedback on wrong config attempt */
ret = -EINVAL;
}
/* check for frame_txtime changes (0 => no changes) */
if (so->opt.frame_txtime) {
if (so->opt.frame_txtime == CAN_ISOTP_FRAME_TXTIME_ZERO)
......@@ -1444,10 +1505,12 @@ static void isotp_notify(struct isotp_sock *so, unsigned long msg,
case NETDEV_UNREGISTER:
lock_sock(sk);
/* remove current filters & unregister */
if (so->bound && (!(so->opt.flags & CAN_ISOTP_SF_BROADCAST))) {
can_rx_unregister(dev_net(dev), dev, so->rxid,
SINGLE_MASK(so->rxid),
isotp_rcv, sk);
if (so->bound && isotp_register_txecho(so)) {
if (isotp_register_rxid(so))
can_rx_unregister(dev_net(dev), dev, so->rxid,
SINGLE_MASK(so->rxid),
isotp_rcv, sk);
can_rx_unregister(dev_net(dev), dev, so->txid,
SINGLE_MASK(so->txid),
isotp_rcv_echo, sk);
......
......@@ -772,6 +772,7 @@ static int raw_sendmsg(struct socket *sock, struct msghdr *msg, size_t size)
{
struct sock *sk = sock->sk;
struct raw_sock *ro = raw_sk(sk);
struct sockcm_cookie sockc;
struct sk_buff *skb;
struct net_device *dev;
int ifindex;
......@@ -817,11 +818,18 @@ static int raw_sendmsg(struct socket *sock, struct msghdr *msg, size_t size)
if (err < 0)
goto free_skb;
skb_setup_tx_timestamp(skb, sk->sk_tsflags);
sockcm_init(&sockc, sk);
if (msg->msg_controllen) {
err = sock_cmsg_send(sk, msg, &sockc);
if (unlikely(err))
goto free_skb;
}
skb->dev = dev;
skb->sk = sk;
skb->priority = sk->sk_priority;
skb->tstamp = sockc.transmit_time;
skb_setup_tx_timestamp(skb, sockc.tsflags);
err = can_send(skb, ro->loopback);
......
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