mirror of
https://github.com/torvalds/linux.git
synced 2024-11-24 05:02:12 +00:00
linux-can-next-for-5.19-20220516
-----BEGIN PGP SIGNATURE----- iQFHBAABCgAxFiEEBsvAIBsPu6mG7thcrX5LkNig010FAmKCr/0THG1rbEBwZW5n dXRyb25peC5kZQAKCRCtfkuQ2KDTXbVWCAClh9ywNEPiSxXsB2k9EdVoijz0hv6I y6YLFPfHxc8w0ewOnBxJOBeLhVjIE2K3n81NaEudheBBImWV8CGlFPHu5sI4S01b aFcAuLT6SOat52xzkh44WGGjW517+EZM1Of1xzPhKdnR0nLvva52SpJlYwgLrkCN O6r30cDuU558H4g2BNxavbbNFPzL7HhkBpHmgWQg4q2p7LvLuTE6sN2CvNEgUWYM nIyK6P/FIyy3l7M7E873WhIEGNGRnAXRBEPXivRmKTlw0wizcvPxlWKm4YxTA0WL 30fw58Hy4x6SZD+7+sP0QhdjiYOofgMtZFZn/LaJYE+rfaYLsFUH3A/2 =tUrE -----END PGP SIGNATURE----- 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.de Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
commit
f7b88d9ae9
@ -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
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
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 */
|
||||
|
||||
|
105
net/can/isotp.c
105
net/can/isotp.c
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user