Lines Matching +full:rx +full:- +full:tx +full:- +full:swap

1 // SPDX-License-Identifier: GPL-2.0
2 // Copyright (c) 2010-2011 EIA Electronics,
6 // Copyright (c) 2017-2019 Pengutronix,
7 // Marc Kleine-Budde <kernel@pengutronix.de>
8 // Copyright (c) 2017-2019 Pengutronix,
13 #include "j1939-priv.h"
229 netdev_warn(priv->ndev, "Unknown abort code %i", abort); in j1939_xtp_abort_to_errno()
238 spin_lock_bh(&priv->active_session_list_lock); in j1939_session_list_lock()
243 spin_unlock_bh(&priv->active_session_list_lock); in j1939_session_list_unlock()
248 kref_get(&session->kref); in j1939_session_get()
254 if (!session->transmission) in __j1939_session_drop()
257 j1939_sock_pending_del(session->sk); in __j1939_session_drop()
258 sock_put(session->sk); in __j1939_session_drop()
265 if (session->transmission) { in j1939_session_destroy()
266 if (session->err) in j1939_session_destroy()
270 } else if (session->err) { in j1939_session_destroy()
274 netdev_dbg(session->priv->ndev, "%s: 0x%p\n", __func__, session); in j1939_session_destroy()
276 WARN_ON_ONCE(!list_empty(&session->sk_session_queue_entry)); in j1939_session_destroy()
277 WARN_ON_ONCE(!list_empty(&session->active_session_list_entry)); in j1939_session_destroy()
279 while ((skb = skb_dequeue(&session->skb_queue)) != NULL) { in j1939_session_destroy()
285 j1939_priv_put(session->priv); in j1939_session_destroy()
299 kref_put(&session->kref, __j1939_session_release); in j1939_session_put()
304 if (hrtimer_cancel(&session->txtimer)) in j1939_session_txtimer_cancel()
310 if (hrtimer_cancel(&session->rxtimer)) in j1939_session_rxtimer_cancel()
322 return (!skcb->addr.dst_name && (skcb->addr.da == 0xff)); in j1939_cb_is_broadcast()
332 if (skb_queue_len(&session->skb_queue) < 2) in j1939_session_skb_drop_old()
335 offset_start = session->pkt.tx_acked * 7; in j1939_session_skb_drop_old()
337 spin_lock_irqsave(&session->skb_queue.lock, flags); in j1939_session_skb_drop_old()
338 do_skb = skb_peek(&session->skb_queue); in j1939_session_skb_drop_old()
341 if ((do_skcb->offset + do_skb->len) < offset_start) { in j1939_session_skb_drop_old()
342 __skb_unlink(do_skb, &session->skb_queue); in j1939_session_skb_drop_old()
345 spin_unlock_irqrestore(&session->skb_queue.lock, flags); in j1939_session_skb_drop_old()
349 spin_unlock_irqrestore(&session->skb_queue.lock, flags); in j1939_session_skb_drop_old()
357 struct j1939_priv *priv = session->priv; in j1939_session_skb_queue()
361 if (j1939_address_is_unicast(skcb->addr.da) && in j1939_session_skb_queue()
362 priv->ents[skcb->addr.da].nusers) in j1939_session_skb_queue()
363 skcb->flags |= J1939_ECU_LOCAL_DST; in j1939_session_skb_queue()
365 skcb->flags |= J1939_ECU_LOCAL_SRC; in j1939_session_skb_queue()
368 skb_queue_tail(&session->skb_queue, skb); in j1939_session_skb_queue()
375 struct j1939_priv *priv = session->priv; in j1939_session_skb_get_by_offset()
381 spin_lock_irqsave(&session->skb_queue.lock, flags); in j1939_session_skb_get_by_offset()
382 skb_queue_walk(&session->skb_queue, do_skb) { in j1939_session_skb_get_by_offset()
385 if (offset_start >= do_skcb->offset && in j1939_session_skb_get_by_offset()
386 offset_start < (do_skcb->offset + do_skb->len)) { in j1939_session_skb_get_by_offset()
394 spin_unlock_irqrestore(&session->skb_queue.lock, flags); in j1939_session_skb_get_by_offset()
397 netdev_dbg(priv->ndev, "%s: 0x%p: no skb found for start: %i, queue size: %i\n", in j1939_session_skb_get_by_offset()
399 skb_queue_len(&session->skb_queue)); in j1939_session_skb_get_by_offset()
408 offset_start = session->pkt.dpo * 7; in j1939_session_skb_get()
417 return skcb->flags & J1939_ECU_LOCAL_DST; in j1939_tp_im_receiver()
423 return skcb->flags & J1939_ECU_LOCAL_SRC; in j1939_tp_im_transmitter()
427 static int j1939_tp_im_involved(const struct j1939_sk_buff_cb *skcb, bool swap) in j1939_tp_im_involved() argument
429 if (swap) in j1939_tp_im_involved()
437 return skcb->flags & (J1939_ECU_LOCAL_SRC | J1939_ECU_LOCAL_DST); in j1939_tp_im_involved_anydir()
440 /* extract pgn from flow-ctl message */
468 * reverse: swap cb's src & dst
476 if (se_addr->type != sk_addr->type) in j1939_session_match()
480 if (se_addr->src_name) { in j1939_session_match()
481 if (se_addr->src_name != sk_addr->dst_name) in j1939_session_match()
483 } else if (se_addr->sa != sk_addr->da) { in j1939_session_match()
487 if (se_addr->dst_name) { in j1939_session_match()
488 if (se_addr->dst_name != sk_addr->src_name) in j1939_session_match()
490 } else if (se_addr->da != sk_addr->sa) { in j1939_session_match()
494 if (se_addr->src_name) { in j1939_session_match()
495 if (se_addr->src_name != sk_addr->src_name) in j1939_session_match()
497 } else if (se_addr->sa != sk_addr->sa) { in j1939_session_match()
501 if (se_addr->dst_name) { in j1939_session_match()
502 if (se_addr->dst_name != sk_addr->dst_name) in j1939_session_match()
504 } else if (se_addr->da != sk_addr->da) { in j1939_session_match()
520 lockdep_assert_held(&priv->active_session_list_lock); in j1939_session_get_by_addr_locked()
524 if (j1939_session_match(&session->skcb.addr, addr, reverse) && in j1939_session_get_by_addr_locked()
525 session->transmission == transmitter) in j1939_session_get_by_addr_locked()
540 lockdep_assert_held(&priv->active_session_list_lock); in j1939_session_get_simple()
542 list_for_each_entry(session, &priv->active_session_list, in j1939_session_get_simple()
545 if (session->skcb.addr.type == J1939_SIMPLE && in j1939_session_get_simple()
546 session->tskey == skcb->tskey && session->sk == skb->sk) in j1939_session_get_simple()
563 &priv->active_session_list, in j1939_session_get_by_addr()
574 swap(skcb->addr.dst_name, skcb->addr.src_name); in j1939_skbcb_swap()
575 swap(skcb->addr.da, skcb->addr.sa); in j1939_skbcb_swap()
577 /* swap SRC and DST flags, leave other untouched */ in j1939_skbcb_swap()
578 if (skcb->flags & J1939_ECU_LOCAL_SRC) in j1939_skbcb_swap()
580 if (skcb->flags & J1939_ECU_LOCAL_DST) in j1939_skbcb_swap()
582 skcb->flags &= ~(J1939_ECU_LOCAL_SRC | J1939_ECU_LOCAL_DST); in j1939_skbcb_swap()
583 skcb->flags |= tmp; in j1939_skbcb_swap()
598 return ERR_PTR(-ENOMEM); in j1939_tp_tx_dat_new()
600 skb->dev = priv->ndev; in j1939_tp_tx_dat_new()
602 can_skb_prv(skb)->ifindex = priv->ndev->ifindex; in j1939_tp_tx_dat_new()
603 can_skb_prv(skb)->skbcnt = 0; in j1939_tp_tx_dat_new()
607 memcpy(skb->cb, re_skcb, sizeof(skb->cb)); in j1939_tp_tx_dat_new()
613 if (skcb->addr.type == J1939_ETP) in j1939_tp_tx_dat_new()
614 skcb->addr.pgn = J1939_ETP_PGN_CTL; in j1939_tp_tx_dat_new()
616 skcb->addr.pgn = J1939_TP_PGN_CTL; in j1939_tp_tx_dat_new()
618 if (skcb->addr.type == J1939_ETP) in j1939_tp_tx_dat_new()
619 skcb->addr.pgn = J1939_ETP_PGN_DAT; in j1939_tp_tx_dat_new()
621 skcb->addr.pgn = J1939_TP_PGN_DAT; in j1939_tp_tx_dat_new()
631 struct j1939_priv *priv = session->priv; in j1939_tp_tx_dat()
634 skb = j1939_tp_tx_dat_new(priv, &session->skcb, in j1939_tp_tx_dat()
641 memset(skb_put(skb, 8 - len), 0xff, 8 - len); in j1939_tp_tx_dat()
672 struct j1939_priv *priv = session->priv; in j1939_tp_tx_ctl()
674 return j1939_xtp_do_tx_ctl(priv, &session->skcb, in j1939_tp_tx_ctl()
676 session->skcb.addr.pgn, dat); in j1939_tp_tx_ctl()
699 hrtimer_start(&session->txtimer, ms_to_ktime(msec), in j1939_tp_schedule_txtimer()
708 hrtimer_start(&session->rxtimer, ms_to_ktime(msec), in j1939_tp_set_rxtimeout()
719 dat[1] = (session->total_message_size >> 0); in j1939_session_tx_rts()
720 dat[2] = (session->total_message_size >> 8); in j1939_session_tx_rts()
721 dat[3] = session->pkt.total; in j1939_session_tx_rts()
723 if (session->skcb.addr.type == J1939_ETP) { in j1939_session_tx_rts()
725 dat[1] = (session->total_message_size >> 0); in j1939_session_tx_rts()
726 dat[2] = (session->total_message_size >> 8); in j1939_session_tx_rts()
727 dat[3] = (session->total_message_size >> 16); in j1939_session_tx_rts()
728 dat[4] = (session->total_message_size >> 24); in j1939_session_tx_rts()
729 } else if (j1939_cb_is_broadcast(&session->skcb)) { in j1939_session_tx_rts()
732 session->pkt.tx = 0; in j1939_session_tx_rts()
738 if (dat[0] == session->last_txcmd) in j1939_session_tx_rts()
746 session->last_txcmd = dat[0]; in j1939_session_tx_rts()
754 netdev_dbg(session->priv->ndev, "%s: 0x%p\n", __func__, session); in j1939_session_tx_rts()
768 session->pkt.dpo = session->pkt.tx_acked; in j1939_session_tx_dpo()
769 pkt = session->pkt.dpo; in j1939_session_tx_dpo()
770 dat[1] = session->pkt.last - session->pkt.tx_acked; in j1939_session_tx_dpo()
779 session->last_txcmd = dat[0]; in j1939_session_tx_dpo()
781 session->pkt.tx = session->pkt.tx_acked; in j1939_session_tx_dpo()
783 netdev_dbg(session->priv->ndev, "%s: 0x%p\n", __func__, session); in j1939_session_tx_dpo()
790 struct j1939_priv *priv = session->priv; in j1939_session_tx_dat()
799 se_skb = j1939_session_skb_get_by_offset(session, session->pkt.tx * 7); in j1939_session_tx_dat()
801 return -ENOBUFS; in j1939_session_tx_dat()
804 tpdat = se_skb->data; in j1939_session_tx_dat()
807 if (session->skcb.addr.type != J1939_ETP && in j1939_session_tx_dat()
808 j1939_cb_is_broadcast(&session->skcb)) in j1939_session_tx_dat()
809 pkt_end = session->pkt.total; in j1939_session_tx_dat()
811 pkt_end = session->pkt.last; in j1939_session_tx_dat()
813 while (session->pkt.tx < pkt_end) { in j1939_session_tx_dat()
814 dat[0] = session->pkt.tx - session->pkt.dpo + 1; in j1939_session_tx_dat()
815 offset = (session->pkt.tx * 7) - se_skcb->offset; in j1939_session_tx_dat()
816 len = se_skb->len - offset; in j1939_session_tx_dat()
820 if (offset + len > se_skb->len) { in j1939_session_tx_dat()
821 netdev_err_once(priv->ndev, in j1939_session_tx_dat()
822 "%s: 0x%p: requested data outside of queued buffer: offset %i, len %i, pkt.tx: %i\n", in j1939_session_tx_dat()
823 __func__, session, se_skcb->offset, in j1939_session_tx_dat()
824 se_skb->len , session->pkt.tx); in j1939_session_tx_dat()
825 ret = -EOVERFLOW; in j1939_session_tx_dat()
830 ret = -ENOBUFS; in j1939_session_tx_dat()
837 /* ENOBUFS == CAN interface TX queue is full */ in j1939_session_tx_dat()
838 if (ret != -ENOBUFS) in j1939_session_tx_dat()
839 netdev_alert(priv->ndev, in j1939_session_tx_dat()
845 session->last_txcmd = 0xff; in j1939_session_tx_dat()
847 session->pkt.tx++; in j1939_session_tx_dat()
848 pdelay = j1939_cb_is_broadcast(&session->skcb) ? 50 : in j1939_session_tx_dat()
851 if (session->pkt.tx < session->pkt.total && pdelay) { in j1939_session_tx_dat()
871 struct j1939_priv *priv = session->priv; in j1939_xtp_txnext_transmiter()
874 if (!j1939_tp_im_transmitter(&session->skcb)) { in j1939_xtp_txnext_transmiter()
875 netdev_alert(priv->ndev, "%s: 0x%p: called by not transmitter!\n", in j1939_xtp_txnext_transmiter()
877 return -EINVAL; in j1939_xtp_txnext_transmiter()
880 switch (session->last_cmd) { in j1939_xtp_txnext_transmiter()
886 if (session->last_txcmd != J1939_ETP_CMD_DPO) { in j1939_xtp_txnext_transmiter()
901 netdev_alert(priv->ndev, "%s: 0x%p: unexpected last_cmd: %x\n", in j1939_xtp_txnext_transmiter()
902 __func__, session, session->last_cmd); in j1939_xtp_txnext_transmiter()
910 struct j1939_priv *priv = session->priv; in j1939_session_tx_cts()
915 if (!j1939_sk_recv_match(priv, &session->skcb)) in j1939_session_tx_cts()
916 return -ENOENT; in j1939_session_tx_cts()
918 len = session->pkt.total - session->pkt.rx; in j1939_session_tx_cts()
919 len = min3(len, session->pkt.block, j1939_tp_block ?: 255); in j1939_session_tx_cts()
922 if (session->skcb.addr.type == J1939_ETP) { in j1939_session_tx_cts()
923 pkt = session->pkt.rx + 1; in j1939_session_tx_cts()
932 dat[2] = session->pkt.rx + 1; in j1939_session_tx_cts()
935 if (dat[0] == session->last_txcmd) in j1939_session_tx_cts()
945 session->last_txcmd = dat[0]; in j1939_session_tx_cts()
948 netdev_dbg(session->priv->ndev, "%s: 0x%p\n", __func__, session); in j1939_session_tx_cts()
955 struct j1939_priv *priv = session->priv; in j1939_session_tx_eoma()
959 if (!j1939_sk_recv_match(priv, &session->skcb)) in j1939_session_tx_eoma()
960 return -ENOENT; in j1939_session_tx_eoma()
964 if (session->skcb.addr.type == J1939_ETP) { in j1939_session_tx_eoma()
966 dat[1] = session->total_message_size >> 0; in j1939_session_tx_eoma()
967 dat[2] = session->total_message_size >> 8; in j1939_session_tx_eoma()
968 dat[3] = session->total_message_size >> 16; in j1939_session_tx_eoma()
969 dat[4] = session->total_message_size >> 24; in j1939_session_tx_eoma()
972 dat[1] = session->total_message_size; in j1939_session_tx_eoma()
973 dat[2] = session->total_message_size >> 8; in j1939_session_tx_eoma()
974 dat[3] = session->pkt.total; in j1939_session_tx_eoma()
977 if (dat[0] == session->last_txcmd) in j1939_session_tx_eoma()
985 session->last_txcmd = dat[0]; in j1939_session_tx_eoma()
990 netdev_dbg(session->priv->ndev, "%p: 0x%p\n", __func__, session); in j1939_session_tx_eoma()
997 struct j1939_priv *priv = session->priv; in j1939_xtp_txnext_receiver()
1000 if (!j1939_tp_im_receiver(&session->skcb)) { in j1939_xtp_txnext_receiver()
1001 netdev_alert(priv->ndev, "%s: 0x%p: called by not receiver!\n", in j1939_xtp_txnext_receiver()
1003 return -EINVAL; in j1939_xtp_txnext_receiver()
1006 switch (session->last_cmd) { in j1939_xtp_txnext_receiver()
1016 if ((session->skcb.addr.type == J1939_TP && in j1939_xtp_txnext_receiver()
1017 j1939_cb_is_broadcast(&session->skcb))) in j1939_xtp_txnext_receiver()
1020 if (session->pkt.rx >= session->pkt.total) { in j1939_xtp_txnext_receiver()
1022 } else if (session->pkt.rx >= session->pkt.last) { in j1939_xtp_txnext_receiver()
1023 session->last_txcmd = 0; in j1939_xtp_txnext_receiver()
1028 netdev_alert(priv->ndev, "%s: 0x%p: unexpected last_cmd: %x\n", in j1939_xtp_txnext_receiver()
1029 __func__, session, session->last_cmd); in j1939_xtp_txnext_receiver()
1037 struct j1939_priv *priv = session->priv; in j1939_simple_txnext()
1047 ret = -ENOMEM; in j1939_simple_txnext()
1051 can_skb_set_owner(skb, se_skb->sk); in j1939_simple_txnext()
1075 lockdep_assert_held(&session->priv->active_session_list_lock); in j1939_session_deactivate_locked()
1077 if (session->state >= J1939_SESSION_ACTIVE && in j1939_session_deactivate_locked()
1078 session->state < J1939_SESSION_ACTIVE_MAX) { in j1939_session_deactivate_locked()
1081 list_del_init(&session->active_session_list_entry); in j1939_session_deactivate_locked()
1082 session->state = J1939_SESSION_DONE; in j1939_session_deactivate_locked()
1091 struct j1939_priv *priv = session->priv; in j1939_session_deactivate()
1095 /* This function should be called with a session ref-count of at in j1939_session_deactivate()
1098 WARN_ON_ONCE(kref_read(&session->kref) < 2); in j1939_session_deactivate()
1115 struct j1939_priv *priv = session->priv; in __j1939_session_cancel()
1118 lockdep_assert_held(&session->priv->active_session_list_lock); in __j1939_session_cancel()
1120 session->err = j1939_xtp_abort_to_errno(priv, err); in __j1939_session_cancel()
1121 session->state = J1939_SESSION_WAITING_ABORT; in __j1939_session_cancel()
1123 if (!j1939_cb_is_broadcast(&session->skcb)) { in __j1939_session_cancel()
1124 j1939_xtp_tx_abort(priv, &session->skcb, in __j1939_session_cancel()
1125 !session->transmission, in __j1939_session_cancel()
1126 err, session->skcb.addr.pgn); in __j1939_session_cancel()
1129 if (session->sk) in __j1939_session_cancel()
1130 j1939_sk_send_loop_abort(session->sk, session->err); in __j1939_session_cancel()
1138 j1939_session_list_lock(session->priv); in j1939_session_cancel()
1140 if (session->state >= J1939_SESSION_ACTIVE && in j1939_session_cancel()
1141 session->state < J1939_SESSION_WAITING_ABORT) { in j1939_session_cancel()
1146 j1939_session_list_unlock(session->priv); in j1939_session_cancel()
1153 struct j1939_priv *priv = session->priv; in j1939_tp_txtimer()
1156 if (session->skcb.addr.type == J1939_SIMPLE) { in j1939_tp_txtimer()
1159 if (session->transmission) in j1939_tp_txtimer()
1166 case -ENOBUFS: in j1939_tp_txtimer()
1168 if (session->tx_retry < J1939_XTP_TX_RETRY_LIMIT) { in j1939_tp_txtimer()
1169 session->tx_retry++; in j1939_tp_txtimer()
1173 netdev_alert(priv->ndev, "%s: 0x%p: tx retry count reached\n", in j1939_tp_txtimer()
1175 session->err = -ENETUNREACH; in j1939_tp_txtimer()
1180 case -ENETDOWN: in j1939_tp_txtimer()
1188 case -EOVERFLOW: in j1939_tp_txtimer()
1192 session->tx_retry = 0; in j1939_tp_txtimer()
1195 netdev_alert(priv->ndev, "%s: 0x%p: tx aborted with unknown reason: %i\n", in j1939_tp_txtimer()
1197 if (session->skcb.addr.type != J1939_SIMPLE) { in j1939_tp_txtimer()
1200 session->err = ret; in j1939_tp_txtimer()
1215 if (!session->transmission) { in j1939_session_completed()
1218 j1939_sk_recv(session->priv, se_skb); in j1939_session_completed()
1230 struct j1939_priv *priv = session->priv; in j1939_tp_rxtimer()
1232 if (session->state == J1939_SESSION_WAITING_ABORT) { in j1939_tp_rxtimer()
1233 netdev_alert(priv->ndev, "%s: 0x%p: abort rx timeout. Force session deactivation\n", in j1939_tp_rxtimer()
1238 } else if (session->skcb.addr.type == J1939_SIMPLE) { in j1939_tp_rxtimer()
1239 netdev_alert(priv->ndev, "%s: 0x%p: Timeout. Failed to send simple message.\n", in j1939_tp_rxtimer()
1245 session->err = -ETIME; in j1939_tp_rxtimer()
1248 j1939_session_list_lock(session->priv); in j1939_tp_rxtimer()
1249 if (session->state >= J1939_SESSION_ACTIVE && in j1939_tp_rxtimer()
1250 session->state < J1939_SESSION_ACTIVE_MAX) { in j1939_tp_rxtimer()
1251 netdev_alert(priv->ndev, "%s: 0x%p: rx timeout, send abort\n", in j1939_tp_rxtimer()
1254 hrtimer_start(&session->rxtimer, in j1939_tp_rxtimer()
1259 j1939_session_list_unlock(session->priv); in j1939_tp_rxtimer()
1271 pgn_t pgn = j1939_xtp_ctl_to_pgn(skb->data); in j1939_xtp_rx_cmd_bad_pgn()
1272 struct j1939_priv *priv = session->priv; in j1939_xtp_rx_cmd_bad_pgn()
1274 u8 cmd = skb->data[0]; in j1939_xtp_rx_cmd_bad_pgn()
1276 if (session->skcb.addr.pgn == pgn) in j1939_xtp_rx_cmd_bad_pgn()
1315 …netdev_warn(priv->ndev, "%s: 0x%p: CMD 0x%02x with PGN 0x%05x for running session with different P… in j1939_xtp_rx_cmd_bad_pgn()
1316 __func__, session, cmd, pgn, session->skcb.addr.pgn); in j1939_xtp_rx_cmd_bad_pgn()
1328 u8 abort = skb->data[1]; in j1939_xtp_rx_abort_one()
1330 session = j1939_session_get_by_addr(priv, &skcb->addr, reverse, in j1939_xtp_rx_abort_one()
1338 netdev_info(priv->ndev, "%s: 0x%p: 0x%05x: (%u) %s\n", __func__, in j1939_xtp_rx_abort_one()
1339 session, j1939_xtp_ctl_to_pgn(skb->data), abort, in j1939_xtp_rx_abort_one()
1343 session->err = j1939_xtp_abort_to_errno(priv, abort); in j1939_xtp_rx_abort_one()
1344 if (session->sk) in j1939_xtp_rx_abort_one()
1345 j1939_sk_send_loop_abort(session->sk, session->err); in j1939_xtp_rx_abort_one()
1373 dat = skb->data; in j1939_xtp_rx_eoma_one()
1375 if (skcb->addr.type == J1939_ETP) in j1939_xtp_rx_eoma_one()
1380 if (session->total_message_size != len) { in j1939_xtp_rx_eoma_one()
1381 netdev_warn_once(session->priv->ndev, in j1939_xtp_rx_eoma_one()
1383 __func__, session, session->total_message_size, in j1939_xtp_rx_eoma_one()
1387 netdev_dbg(session->priv->ndev, "%s: 0x%p\n", __func__, session); in j1939_xtp_rx_eoma_one()
1389 session->pkt.tx_acked = session->pkt.total; in j1939_xtp_rx_eoma_one()
1402 session = j1939_session_get_by_addr(priv, &skcb->addr, true, in j1939_xtp_rx_eoma()
1418 dat = skb->data; in j1939_xtp_rx_cts_one()
1423 netdev_dbg(session->priv->ndev, "%s: 0x%p\n", __func__, session); in j1939_xtp_rx_cts_one()
1425 if (session->last_cmd == dat[0]) { in j1939_xtp_rx_cts_one()
1430 if (session->skcb.addr.type == J1939_ETP) in j1939_xtp_rx_cts_one()
1437 else if (dat[1] > session->pkt.block /* 0xff for etp */) in j1939_xtp_rx_cts_one()
1441 session->pkt.tx_acked = pkt - 1; in j1939_xtp_rx_cts_one()
1443 session->pkt.last = session->pkt.tx_acked + dat[1]; in j1939_xtp_rx_cts_one()
1444 if (session->pkt.last > session->pkt.total) in j1939_xtp_rx_cts_one()
1446 session->pkt.last = session->pkt.total; in j1939_xtp_rx_cts_one()
1447 /* TODO: do not set tx here, do it in txtimer */ in j1939_xtp_rx_cts_one()
1448 session->pkt.tx = session->pkt.tx_acked; in j1939_xtp_rx_cts_one()
1450 session->last_cmd = dat[0]; in j1939_xtp_rx_cts_one()
1453 if (session->transmission) { in j1939_xtp_rx_cts_one()
1454 if (session->pkt.tx_acked) in j1939_xtp_rx_cts_one()
1477 session = j1939_session_get_by_addr(priv, &skcb->addr, true, in j1939_xtp_rx_cts()
1495 INIT_LIST_HEAD(&session->active_session_list_entry); in j1939_session_new()
1496 INIT_LIST_HEAD(&session->sk_session_queue_entry); in j1939_session_new()
1497 kref_init(&session->kref); in j1939_session_new()
1500 session->priv = priv; in j1939_session_new()
1501 session->total_message_size = size; in j1939_session_new()
1502 session->state = J1939_SESSION_NEW; in j1939_session_new()
1504 skb_queue_head_init(&session->skb_queue); in j1939_session_new()
1505 skb_queue_tail(&session->skb_queue, skb); in j1939_session_new()
1508 memcpy(&session->skcb, skcb, sizeof(session->skcb)); in j1939_session_new()
1510 hrtimer_init(&session->txtimer, CLOCK_MONOTONIC, in j1939_session_new()
1512 session->txtimer.function = j1939_tp_txtimer; in j1939_session_new()
1513 hrtimer_init(&session->rxtimer, CLOCK_MONOTONIC, in j1939_session_new()
1515 session->rxtimer.function = j1939_tp_rxtimer; in j1939_session_new()
1517 netdev_dbg(priv->ndev, "%s: 0x%p: sa: %02x, da: %02x\n", in j1939_session_new()
1518 __func__, session, skcb->addr.sa, skcb->addr.da); in j1939_session_new()
1536 skb->dev = priv->ndev; in j1939_session_fresh_new()
1538 can_skb_prv(skb)->ifindex = priv->ndev->ifindex; in j1939_session_fresh_new()
1539 can_skb_prv(skb)->skbcnt = 0; in j1939_session_fresh_new()
1557 struct j1939_priv *priv = session->priv; in j1939_session_activate()
1562 if (session->skcb.addr.type != J1939_SIMPLE) in j1939_session_activate()
1564 &priv->active_session_list, in j1939_session_activate()
1565 &session->skcb.addr, false, in j1939_session_activate()
1566 session->transmission); in j1939_session_activate()
1569 ret = -EAGAIN; in j1939_session_activate()
1571 WARN_ON_ONCE(session->state != J1939_SESSION_NEW); in j1939_session_activate()
1572 list_add_tail(&session->active_session_list_entry, in j1939_session_activate()
1573 &priv->active_session_list); in j1939_session_activate()
1575 session->state = J1939_SESSION_ACTIVE; in j1939_session_activate()
1577 netdev_dbg(session->priv->ndev, "%s: 0x%p\n", in j1939_session_activate()
1596 netdev_dbg(priv->ndev, "%s\n", __func__); in j1939_xtp_rx_rts_session_new()
1598 dat = skb->data; in j1939_xtp_rx_rts_session_new()
1609 else if (len > priv->tp_max_packet_size) in j1939_xtp_rx_rts_session_new()
1617 else if (len > priv->tp_max_packet_size) in j1939_xtp_rx_rts_session_new()
1636 session->pkt.total = (len + 6) / 7; in j1939_xtp_rx_rts_session_new()
1637 session->pkt.block = 0xff; in j1939_xtp_rx_rts_session_new()
1639 if (dat[3] != session->pkt.total) in j1939_xtp_rx_rts_session_new()
1640 netdev_alert(priv->ndev, "%s: 0x%p: strange total, %u != %u\n", in j1939_xtp_rx_rts_session_new()
1641 __func__, session, session->pkt.total, in j1939_xtp_rx_rts_session_new()
1643 session->pkt.total = dat[3]; in j1939_xtp_rx_rts_session_new()
1644 session->pkt.block = min(dat[3], dat[4]); in j1939_xtp_rx_rts_session_new()
1647 session->pkt.rx = 0; in j1939_xtp_rx_rts_session_new()
1648 session->pkt.tx = 0; in j1939_xtp_rx_rts_session_new()
1650 session->tskey = priv->rx_tskey++; in j1939_xtp_rx_rts_session_new()
1662 struct j1939_priv *priv = session->priv; in j1939_xtp_rx_rts_session_active()
1664 if (!session->transmission) { in j1939_xtp_rx_rts_session_active()
1666 return -EBUSY; in j1939_xtp_rx_rts_session_active()
1673 if (session->last_cmd != 0) { in j1939_xtp_rx_rts_session_active()
1675 netdev_alert(priv->ndev, "%s: 0x%p: connection exists (%02x %02x). last cmd: %x\n", in j1939_xtp_rx_rts_session_active()
1676 __func__, session, skcb->addr.sa, skcb->addr.da, in j1939_xtp_rx_rts_session_active()
1677 session->last_cmd); in j1939_xtp_rx_rts_session_active()
1682 return -EBUSY; in j1939_xtp_rx_rts_session_active()
1685 if (session->skcb.addr.sa != skcb->addr.sa || in j1939_xtp_rx_rts_session_active()
1686 session->skcb.addr.da != skcb->addr.da) in j1939_xtp_rx_rts_session_active()
1687 …netdev_warn(priv->ndev, "%s: 0x%p: session->skcb.addr.sa=0x%02x skcb->addr.sa=0x%02x session->skcb… in j1939_xtp_rx_rts_session_active()
1689 session->skcb.addr.sa, skcb->addr.sa, in j1939_xtp_rx_rts_session_active()
1690 session->skcb.addr.da, skcb->addr.da); in j1939_xtp_rx_rts_session_active()
1695 session->skcb.addr.sa = skcb->addr.sa; in j1939_xtp_rx_rts_session_active()
1696 session->skcb.addr.da = skcb->addr.da; in j1939_xtp_rx_rts_session_active()
1698 netdev_dbg(session->priv->ndev, "%s: 0x%p\n", __func__, session); in j1939_xtp_rx_rts_session_active()
1708 u8 cmd = skb->data[0]; in j1939_xtp_rx_rts()
1710 session = j1939_session_get_by_addr(priv, &skcb->addr, false, in j1939_xtp_rx_rts()
1726 * - user space closed socket was and the session was in j1939_xtp_rx_rts()
1728 * - session was aborted due to external abort message in j1939_xtp_rx_rts()
1735 netdev_info(priv->ndev, "%s: failed to create TP BAM session\n", in j1939_xtp_rx_rts()
1745 session->last_cmd = cmd; in j1939_xtp_rx_rts()
1748 if (!session->transmission) in j1939_xtp_rx_rts()
1751 if (!session->transmission) { in j1939_xtp_rx_rts()
1764 const u8 *dat = skb->data; in j1939_xtp_rx_dpo_one()
1769 netdev_dbg(session->priv->ndev, "%s: 0x%p\n", __func__, session); in j1939_xtp_rx_dpo_one()
1772 session->pkt.dpo = j1939_etp_ctl_to_packet(skb->data); in j1939_xtp_rx_dpo_one()
1773 session->last_cmd = dat[0]; in j1939_xtp_rx_dpo_one()
1776 if (!session->transmission) in j1939_xtp_rx_dpo_one()
1786 session = j1939_session_get_by_addr(priv, &skcb->addr, false, in j1939_xtp_rx_dpo()
1789 netdev_info(priv->ndev, in j1939_xtp_rx_dpo()
1802 struct j1939_priv *priv = session->priv; in j1939_xtp_rx_dat_one()
1815 dat = skb->data; in j1939_xtp_rx_dat_one()
1816 if (skb->len != 8) { in j1939_xtp_rx_dat_one()
1822 switch (session->last_cmd) { in j1939_xtp_rx_dat_one()
1826 if (skcb->addr.type == J1939_ETP) in j1939_xtp_rx_dat_one()
1832 if (skcb->addr.type != J1939_ETP) in j1939_xtp_rx_dat_one()
1836 netdev_info(priv->ndev, "%s: 0x%p: last %02x\n", __func__, in j1939_xtp_rx_dat_one()
1837 session, session->last_cmd); in j1939_xtp_rx_dat_one()
1841 packet = (dat[0] - 1 + session->pkt.dpo); in j1939_xtp_rx_dat_one()
1842 if (packet > session->pkt.total || in j1939_xtp_rx_dat_one()
1843 (session->pkt.rx + 1) > session->pkt.total) { in j1939_xtp_rx_dat_one()
1844 netdev_info(priv->ndev, "%s: 0x%p: should have been completed\n", in j1939_xtp_rx_dat_one()
1851 netdev_warn(priv->ndev, "%s: 0x%p: no skb found\n", __func__, in j1939_xtp_rx_dat_one()
1857 offset = packet * 7 - se_skcb->offset; in j1939_xtp_rx_dat_one()
1858 nbytes = se_skb->len - offset; in j1939_xtp_rx_dat_one()
1861 if (nbytes <= 0 || (nbytes + 1) > skb->len) { in j1939_xtp_rx_dat_one()
1862 netdev_info(priv->ndev, "%s: 0x%p: nbytes %i, len %i\n", in j1939_xtp_rx_dat_one()
1863 __func__, session, nbytes, skb->len); in j1939_xtp_rx_dat_one()
1867 tpdat = se_skb->data; in j1939_xtp_rx_dat_one()
1868 if (!session->transmission) { in j1939_xtp_rx_dat_one()
1875 netdev_err_once(priv->ndev, in j1939_xtp_rx_dat_one()
1876 "%s: 0x%p: Data of RX-looped back packet (%*ph) doesn't match TX data (%*ph)!\n", in j1939_xtp_rx_dat_one()
1882 if (packet == session->pkt.rx) in j1939_xtp_rx_dat_one()
1883 session->pkt.rx++; in j1939_xtp_rx_dat_one()
1885 if (se_skcb->addr.type != J1939_ETP && in j1939_xtp_rx_dat_one()
1886 j1939_cb_is_broadcast(&session->skcb)) { in j1939_xtp_rx_dat_one()
1887 if (session->pkt.rx >= session->pkt.total) in j1939_xtp_rx_dat_one()
1893 if (session->pkt.rx >= session->pkt.last) in j1939_xtp_rx_dat_one()
1901 if (!session->transmission) in j1939_xtp_rx_dat_one()
1905 if (!session->transmission) in j1939_xtp_rx_dat_one()
1910 session->last_cmd = 0xff; in j1939_xtp_rx_dat_one()
1931 session = j1939_session_get_by_addr(priv, &skcb->addr, false, in j1939_xtp_rx_dat()
1934 netdev_info(priv->ndev, "%s: no tx connection found\n", in j1939_xtp_rx_dat()
1941 session = j1939_session_get_by_addr(priv, &skcb->addr, false, in j1939_xtp_rx_dat()
1944 netdev_info(priv->ndev, "%s: no rx connection found\n", in j1939_xtp_rx_dat()
1951 session = j1939_session_get_by_addr(priv, &skcb->addr, false, in j1939_xtp_rx_dat()
1966 if (skcb->addr.pgn == J1939_TP_PGN_DAT || in j1939_tp_send()
1967 skcb->addr.pgn == J1939_TP_PGN_CTL || in j1939_tp_send()
1968 skcb->addr.pgn == J1939_ETP_PGN_DAT || in j1939_tp_send()
1969 skcb->addr.pgn == J1939_ETP_PGN_CTL) in j1939_tp_send()
1971 return ERR_PTR(-EDOM); in j1939_tp_send()
1973 if (size > priv->tp_max_packet_size) in j1939_tp_send()
1974 return ERR_PTR(-EMSGSIZE); in j1939_tp_send()
1977 skcb->addr.type = J1939_SIMPLE; in j1939_tp_send()
1979 skcb->addr.type = J1939_ETP; in j1939_tp_send()
1981 skcb->addr.type = J1939_TP; in j1939_tp_send()
1983 if (skcb->addr.type == J1939_ETP && in j1939_tp_send()
1985 return ERR_PTR(-EDESTADDRREQ); in j1939_tp_send()
1993 if (j1939_address_is_unicast(skcb->addr.da) && in j1939_tp_send()
1994 priv->ents[skcb->addr.da].nusers) in j1939_tp_send()
1995 skcb->flags |= J1939_ECU_LOCAL_DST; in j1939_tp_send()
1998 skcb->flags |= J1939_ECU_LOCAL_SRC; in j1939_tp_send()
2003 return ERR_PTR(-ENOMEM); in j1939_tp_send()
2006 sock_hold(skb->sk); in j1939_tp_send()
2007 session->sk = skb->sk; in j1939_tp_send()
2008 session->transmission = true; in j1939_tp_send()
2009 session->pkt.total = (size + 6) / 7; in j1939_tp_send()
2010 session->pkt.block = skcb->addr.type == J1939_ETP ? 255 : in j1939_tp_send()
2011 min(j1939_tp_block ?: 255, session->pkt.total); in j1939_tp_send()
2013 if (j1939_cb_is_broadcast(&session->skcb)) in j1939_tp_send()
2014 /* set the end-packet for broadcast */ in j1939_tp_send()
2015 session->pkt.last = session->pkt.total; in j1939_tp_send()
2017 skcb->tskey = atomic_inc_return(&session->sk->sk_tskey) - 1; in j1939_tp_send()
2018 session->tskey = skcb->tskey; in j1939_tp_send()
2027 u8 cmd = skb->data[0]; in j1939_tp_cmd_recv()
2035 netdev_err_once(priv->ndev, "%s: BAM to unicast (%02x), ignoring!\n", in j1939_tp_cmd_recv()
2036 __func__, skcb->addr.sa); in j1939_tp_cmd_recv()
2041 if (skcb->addr.type != extd) in j1939_tp_cmd_recv()
2045 netdev_alert(priv->ndev, "%s: rts without destination (%02x)\n", in j1939_tp_cmd_recv()
2046 __func__, skcb->addr.sa); in j1939_tp_cmd_recv()
2062 if (skcb->addr.type != extd) in j1939_tp_cmd_recv()
2074 if (skcb->addr.type != J1939_ETP) in j1939_tp_cmd_recv()
2089 if (skcb->addr.type != extd) in j1939_tp_cmd_recv()
2102 netdev_err_once(priv->ndev, "%s: abort to broadcast (%02x), ignoring!\n", in j1939_tp_cmd_recv()
2103 __func__, skcb->addr.sa); in j1939_tp_cmd_recv()
2126 switch (skcb->addr.pgn) { in j1939_tp_recv()
2128 skcb->addr.type = J1939_ETP; in j1939_tp_recv()
2135 skcb->addr.type = J1939_ETP; in j1939_tp_recv()
2138 if (skb->len < 8) in j1939_tp_recv()
2153 if (!skb->sk) in j1939_simple_recv()
2156 if (skb->sk->sk_family != AF_CAN || in j1939_simple_recv()
2157 skb->sk->sk_protocol != CAN_J1939) in j1939_simple_recv()
2164 netdev_warn(priv->ndev, in j1939_simple_recv()
2179 netdev_dbg(priv->ndev, "%s, sk: %p\n", __func__, sk); in j1939_cancel_active_session()
2182 &priv->active_session_list, in j1939_cancel_active_session()
2184 if (!sk || sk == session->sk) { in j1939_cancel_active_session()
2185 if (hrtimer_try_to_cancel(&session->txtimer) == 1) in j1939_cancel_active_session()
2187 if (hrtimer_try_to_cancel(&session->rxtimer) == 1) in j1939_cancel_active_session()
2190 session->err = ESHUTDOWN; in j1939_cancel_active_session()
2200 spin_lock_init(&priv->active_session_list_lock); in j1939_tp_init()
2201 INIT_LIST_HEAD(&priv->active_session_list); in j1939_tp_init()
2202 priv->tp_max_packet_size = J1939_MAX_ETP_PACKET_SIZE; in j1939_tp_init()