Skip to content

Commit 9c0532f

Browse files
committed
Merge tag 'linux-can-next-for-5.15-20210804' of git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can-next
Marc Kleine-Budde says: ==================== pull-request: can-next 2021-08-04 this is a pull request of 5 patches for net-next/master. The first patch is by me and fixes a typo in a comment in the CAN J1939 protocol. The next 2 patches are by Oleksij Rempel and update the CAN J1939 protocol to send RX status updates via the error queue mechanism. The next patch is by me and adds a missing variable initialization to the flexcan driver (the problem was introduced in the current net-next cycle). The last patch is by Aswath Govindraju and adds power-domains to the Bosch m_can DT binding documentation. ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents 51b8f81 + d85165b commit 9c0532f

File tree

6 files changed

+152
-44
lines changed

6 files changed

+152
-44
lines changed

Documentation/devicetree/bindings/net/can/bosch,m_can.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,12 @@ properties:
104104
maximum: 32
105105
maxItems: 1
106106

107+
power-domains:
108+
description:
109+
Power domain provider node and an args specifier containing
110+
the can device id value.
111+
maxItems: 1
112+
107113
can-transceiver:
108114
$ref: can-transceiver.yaml#
109115

drivers/net/can/flexcan.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -649,7 +649,7 @@ static inline void flexcan_error_irq_disable(const struct flexcan_priv *priv)
649649

650650
static int flexcan_clks_enable(const struct flexcan_priv *priv)
651651
{
652-
int err;
652+
int err = 0;
653653

654654
if (priv->clk_ipg) {
655655
err = clk_prepare_enable(priv->clk_ipg);

include/uapi/linux/can/j1939.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,11 +78,20 @@ enum {
7878
enum {
7979
J1939_NLA_PAD,
8080
J1939_NLA_BYTES_ACKED,
81+
J1939_NLA_TOTAL_SIZE,
82+
J1939_NLA_PGN,
83+
J1939_NLA_SRC_NAME,
84+
J1939_NLA_DEST_NAME,
85+
J1939_NLA_SRC_ADDR,
86+
J1939_NLA_DEST_ADDR,
8187
};
8288

8389
enum {
8490
J1939_EE_INFO_NONE,
8591
J1939_EE_INFO_TX_ABORT,
92+
J1939_EE_INFO_RX_RTS,
93+
J1939_EE_INFO_RX_DPO,
94+
J1939_EE_INFO_RX_ABORT,
8695
};
8796

8897
struct j1939_filter {

net/can/j1939/j1939-priv.h

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,12 @@
2020

2121
struct j1939_session;
2222
enum j1939_sk_errqueue_type {
23-
J1939_ERRQUEUE_ACK,
24-
J1939_ERRQUEUE_SCHED,
25-
J1939_ERRQUEUE_ABORT,
23+
J1939_ERRQUEUE_TX_ACK,
24+
J1939_ERRQUEUE_TX_SCHED,
25+
J1939_ERRQUEUE_TX_ABORT,
26+
J1939_ERRQUEUE_RX_RTS,
27+
J1939_ERRQUEUE_RX_DPO,
28+
J1939_ERRQUEUE_RX_ABORT,
2629
};
2730

2831
/* j1939 devices */
@@ -87,6 +90,7 @@ struct j1939_priv {
8790
struct list_head j1939_socks;
8891

8992
struct kref rx_kref;
93+
u32 rx_tskey;
9094
};
9195

9296
void j1939_ecu_put(struct j1939_ecu *ecu);

net/can/j1939/socket.c

Lines changed: 108 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -905,20 +905,33 @@ static struct sk_buff *j1939_sk_alloc_skb(struct net_device *ndev,
905905
return NULL;
906906
}
907907

908-
static size_t j1939_sk_opt_stats_get_size(void)
908+
static size_t j1939_sk_opt_stats_get_size(enum j1939_sk_errqueue_type type)
909909
{
910-
return
911-
nla_total_size(sizeof(u32)) + /* J1939_NLA_BYTES_ACKED */
912-
0;
910+
switch (type) {
911+
case J1939_ERRQUEUE_RX_RTS:
912+
return
913+
nla_total_size(sizeof(u32)) + /* J1939_NLA_TOTAL_SIZE */
914+
nla_total_size(sizeof(u32)) + /* J1939_NLA_PGN */
915+
nla_total_size(sizeof(u64)) + /* J1939_NLA_SRC_NAME */
916+
nla_total_size(sizeof(u64)) + /* J1939_NLA_DEST_NAME */
917+
nla_total_size(sizeof(u8)) + /* J1939_NLA_SRC_ADDR */
918+
nla_total_size(sizeof(u8)) + /* J1939_NLA_DEST_ADDR */
919+
0;
920+
default:
921+
return
922+
nla_total_size(sizeof(u32)) + /* J1939_NLA_BYTES_ACKED */
923+
0;
924+
}
913925
}
914926

915927
static struct sk_buff *
916-
j1939_sk_get_timestamping_opt_stats(struct j1939_session *session)
928+
j1939_sk_get_timestamping_opt_stats(struct j1939_session *session,
929+
enum j1939_sk_errqueue_type type)
917930
{
918931
struct sk_buff *stats;
919932
u32 size;
920933

921-
stats = alloc_skb(j1939_sk_opt_stats_get_size(), GFP_ATOMIC);
934+
stats = alloc_skb(j1939_sk_opt_stats_get_size(type), GFP_ATOMIC);
922935
if (!stats)
923936
return NULL;
924937

@@ -928,32 +941,67 @@ j1939_sk_get_timestamping_opt_stats(struct j1939_session *session)
928941
size = min(session->pkt.tx_acked * 7,
929942
session->total_message_size);
930943

931-
nla_put_u32(stats, J1939_NLA_BYTES_ACKED, size);
944+
switch (type) {
945+
case J1939_ERRQUEUE_RX_RTS:
946+
nla_put_u32(stats, J1939_NLA_TOTAL_SIZE,
947+
session->total_message_size);
948+
nla_put_u32(stats, J1939_NLA_PGN,
949+
session->skcb.addr.pgn);
950+
nla_put_u64_64bit(stats, J1939_NLA_SRC_NAME,
951+
session->skcb.addr.src_name, J1939_NLA_PAD);
952+
nla_put_u64_64bit(stats, J1939_NLA_DEST_NAME,
953+
session->skcb.addr.dst_name, J1939_NLA_PAD);
954+
nla_put_u8(stats, J1939_NLA_SRC_ADDR,
955+
session->skcb.addr.sa);
956+
nla_put_u8(stats, J1939_NLA_DEST_ADDR,
957+
session->skcb.addr.da);
958+
break;
959+
default:
960+
nla_put_u32(stats, J1939_NLA_BYTES_ACKED, size);
961+
}
932962

933963
return stats;
934964
}
935965

936-
void j1939_sk_errqueue(struct j1939_session *session,
937-
enum j1939_sk_errqueue_type type)
966+
static void __j1939_sk_errqueue(struct j1939_session *session, struct sock *sk,
967+
enum j1939_sk_errqueue_type type)
938968
{
939969
struct j1939_priv *priv = session->priv;
940-
struct sock *sk = session->sk;
941970
struct j1939_sock *jsk;
942971
struct sock_exterr_skb *serr;
943972
struct sk_buff *skb;
944973
char *state = "UNK";
945974
int err;
946975

947-
/* currently we have no sk for the RX session */
948-
if (!sk)
949-
return;
950-
951976
jsk = j1939_sk(sk);
952977

953978
if (!(jsk->state & J1939_SOCK_ERRQUEUE))
954979
return;
955980

956-
skb = j1939_sk_get_timestamping_opt_stats(session);
981+
switch (type) {
982+
case J1939_ERRQUEUE_TX_ACK:
983+
if (!(sk->sk_tsflags & SOF_TIMESTAMPING_TX_ACK))
984+
return;
985+
break;
986+
case J1939_ERRQUEUE_TX_SCHED:
987+
if (!(sk->sk_tsflags & SOF_TIMESTAMPING_TX_SCHED))
988+
return;
989+
break;
990+
case J1939_ERRQUEUE_TX_ABORT:
991+
break;
992+
case J1939_ERRQUEUE_RX_RTS:
993+
fallthrough;
994+
case J1939_ERRQUEUE_RX_DPO:
995+
fallthrough;
996+
case J1939_ERRQUEUE_RX_ABORT:
997+
if (!(sk->sk_tsflags & SOF_TIMESTAMPING_RX_SOFTWARE))
998+
return;
999+
break;
1000+
default:
1001+
netdev_err(priv->ndev, "Unknown errqueue type %i\n", type);
1002+
}
1003+
1004+
skb = j1939_sk_get_timestamping_opt_stats(session, type);
9571005
if (!skb)
9581006
return;
9591007

@@ -964,36 +1012,42 @@ void j1939_sk_errqueue(struct j1939_session *session,
9641012
serr = SKB_EXT_ERR(skb);
9651013
memset(serr, 0, sizeof(*serr));
9661014
switch (type) {
967-
case J1939_ERRQUEUE_ACK:
968-
if (!(sk->sk_tsflags & SOF_TIMESTAMPING_TX_ACK)) {
969-
kfree_skb(skb);
970-
return;
971-
}
972-
1015+
case J1939_ERRQUEUE_TX_ACK:
9731016
serr->ee.ee_errno = ENOMSG;
9741017
serr->ee.ee_origin = SO_EE_ORIGIN_TIMESTAMPING;
9751018
serr->ee.ee_info = SCM_TSTAMP_ACK;
976-
state = "ACK";
1019+
state = "TX ACK";
9771020
break;
978-
case J1939_ERRQUEUE_SCHED:
979-
if (!(sk->sk_tsflags & SOF_TIMESTAMPING_TX_SCHED)) {
980-
kfree_skb(skb);
981-
return;
982-
}
983-
1021+
case J1939_ERRQUEUE_TX_SCHED:
9841022
serr->ee.ee_errno = ENOMSG;
9851023
serr->ee.ee_origin = SO_EE_ORIGIN_TIMESTAMPING;
9861024
serr->ee.ee_info = SCM_TSTAMP_SCHED;
987-
state = "SCH";
1025+
state = "TX SCH";
9881026
break;
989-
case J1939_ERRQUEUE_ABORT:
1027+
case J1939_ERRQUEUE_TX_ABORT:
9901028
serr->ee.ee_errno = session->err;
9911029
serr->ee.ee_origin = SO_EE_ORIGIN_LOCAL;
9921030
serr->ee.ee_info = J1939_EE_INFO_TX_ABORT;
993-
state = "ABT";
1031+
state = "TX ABT";
1032+
break;
1033+
case J1939_ERRQUEUE_RX_RTS:
1034+
serr->ee.ee_errno = ENOMSG;
1035+
serr->ee.ee_origin = SO_EE_ORIGIN_LOCAL;
1036+
serr->ee.ee_info = J1939_EE_INFO_RX_RTS;
1037+
state = "RX RTS";
1038+
break;
1039+
case J1939_ERRQUEUE_RX_DPO:
1040+
serr->ee.ee_errno = ENOMSG;
1041+
serr->ee.ee_origin = SO_EE_ORIGIN_LOCAL;
1042+
serr->ee.ee_info = J1939_EE_INFO_RX_DPO;
1043+
state = "RX DPO";
1044+
break;
1045+
case J1939_ERRQUEUE_RX_ABORT:
1046+
serr->ee.ee_errno = session->err;
1047+
serr->ee.ee_origin = SO_EE_ORIGIN_LOCAL;
1048+
serr->ee.ee_info = J1939_EE_INFO_RX_ABORT;
1049+
state = "RX ABT";
9941050
break;
995-
default:
996-
netdev_err(priv->ndev, "Unknown errqueue type %i\n", type);
9971051
}
9981052

9991053
serr->opt_stats = true;
@@ -1008,6 +1062,27 @@ void j1939_sk_errqueue(struct j1939_session *session,
10081062
kfree_skb(skb);
10091063
};
10101064

1065+
void j1939_sk_errqueue(struct j1939_session *session,
1066+
enum j1939_sk_errqueue_type type)
1067+
{
1068+
struct j1939_priv *priv = session->priv;
1069+
struct j1939_sock *jsk;
1070+
1071+
if (session->sk) {
1072+
/* send TX notifications to the socket of origin */
1073+
__j1939_sk_errqueue(session, session->sk, type);
1074+
return;
1075+
}
1076+
1077+
/* spread RX notifications to all sockets subscribed to this session */
1078+
spin_lock_bh(&priv->j1939_socks_lock);
1079+
list_for_each_entry(jsk, &priv->j1939_socks, list) {
1080+
if (j1939_sk_recv_match_one(jsk, &session->skcb))
1081+
__j1939_sk_errqueue(session, &jsk->sk, type);
1082+
}
1083+
spin_unlock_bh(&priv->j1939_socks_lock);
1084+
};
1085+
10111086
void j1939_sk_send_loop_abort(struct sock *sk, int err)
10121087
{
10131088
sk->sk_err = err;

net/can/j1939/transport.c

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -260,10 +260,14 @@ static void __j1939_session_drop(struct j1939_session *session)
260260

261261
static void j1939_session_destroy(struct j1939_session *session)
262262
{
263-
if (session->err)
264-
j1939_sk_errqueue(session, J1939_ERRQUEUE_ABORT);
265-
else
266-
j1939_sk_errqueue(session, J1939_ERRQUEUE_ACK);
263+
if (session->transmission) {
264+
if (session->err)
265+
j1939_sk_errqueue(session, J1939_ERRQUEUE_TX_ABORT);
266+
else
267+
j1939_sk_errqueue(session, J1939_ERRQUEUE_TX_ACK);
268+
} else if (session->err) {
269+
j1939_sk_errqueue(session, J1939_ERRQUEUE_RX_ABORT);
270+
}
267271

268272
netdev_dbg(session->priv->ndev, "%s: 0x%p\n", __func__, session);
269273

@@ -822,7 +826,7 @@ static int j1939_session_tx_dat(struct j1939_session *session)
822826
memcpy(&dat[1], &tpdat[offset], len);
823827
ret = j1939_tp_tx_dat(session, dat, len + 1);
824828
if (ret < 0) {
825-
/* ENOBUS == CAN interface TX queue is full */
829+
/* ENOBUFS == CAN interface TX queue is full */
826830
if (ret != -ENOBUFS)
827831
netdev_alert(priv->ndev,
828832
"%s: 0x%p: queue data error: %i\n",
@@ -1044,7 +1048,7 @@ static int j1939_simple_txnext(struct j1939_session *session)
10441048
if (ret)
10451049
goto out_free;
10461050

1047-
j1939_sk_errqueue(session, J1939_ERRQUEUE_SCHED);
1051+
j1939_sk_errqueue(session, J1939_ERRQUEUE_TX_SCHED);
10481052
j1939_sk_queue_activate_next(session);
10491053

10501054
out_free:
@@ -1116,6 +1120,8 @@ static void __j1939_session_cancel(struct j1939_session *session,
11161120

11171121
if (session->sk)
11181122
j1939_sk_send_loop_abort(session->sk, session->err);
1123+
else
1124+
j1939_sk_errqueue(session, J1939_ERRQUEUE_RX_ABORT);
11191125
}
11201126

11211127
static void j1939_session_cancel(struct j1939_session *session,
@@ -1330,6 +1336,8 @@ static void j1939_xtp_rx_abort_one(struct j1939_priv *priv, struct sk_buff *skb,
13301336
session->err = j1939_xtp_abort_to_errno(priv, abort);
13311337
if (session->sk)
13321338
j1939_sk_send_loop_abort(session->sk, session->err);
1339+
else
1340+
j1939_sk_errqueue(session, J1939_ERRQUEUE_RX_ABORT);
13331341
j1939_session_deactivate_activate_next(session);
13341342

13351343
abort_put:
@@ -1438,7 +1446,7 @@ j1939_xtp_rx_cts_one(struct j1939_session *session, struct sk_buff *skb)
14381446
if (session->transmission) {
14391447
if (session->pkt.tx_acked)
14401448
j1939_sk_errqueue(session,
1441-
J1939_ERRQUEUE_SCHED);
1449+
J1939_ERRQUEUE_TX_SCHED);
14421450
j1939_session_txtimer_cancel(session);
14431451
j1939_tp_schedule_txtimer(session, 0);
14441452
}
@@ -1630,6 +1638,9 @@ j1939_session *j1939_xtp_rx_rts_session_new(struct j1939_priv *priv,
16301638
session->pkt.rx = 0;
16311639
session->pkt.tx = 0;
16321640

1641+
session->tskey = priv->rx_tskey++;
1642+
j1939_sk_errqueue(session, J1939_ERRQUEUE_RX_RTS);
1643+
16331644
WARN_ON_ONCE(j1939_session_activate(session));
16341645

16351646
return session;
@@ -1752,6 +1763,9 @@ static void j1939_xtp_rx_dpo_one(struct j1939_session *session,
17521763
session->pkt.dpo = j1939_etp_ctl_to_packet(skb->data);
17531764
session->last_cmd = dat[0];
17541765
j1939_tp_set_rxtimeout(session, 750);
1766+
1767+
if (!session->transmission)
1768+
j1939_sk_errqueue(session, J1939_ERRQUEUE_RX_DPO);
17551769
}
17561770

17571771
static void j1939_xtp_rx_dpo(struct j1939_priv *priv, struct sk_buff *skb,

0 commit comments

Comments
 (0)