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()
263 if (session->err) in j1939_session_destroy()
268 netdev_dbg(session->priv->ndev, "%s: 0x%p\n", __func__, session); in j1939_session_destroy()
270 WARN_ON_ONCE(!list_empty(&session->sk_session_queue_entry)); in j1939_session_destroy()
271 WARN_ON_ONCE(!list_empty(&session->active_session_list_entry)); in j1939_session_destroy()
273 skb_queue_purge(&session->skb_queue); in j1939_session_destroy()
275 j1939_priv_put(session->priv); in j1939_session_destroy()
289 kref_put(&session->kref, __j1939_session_release); in j1939_session_put()
294 if (hrtimer_cancel(&session->txtimer)) in j1939_session_txtimer_cancel()
300 if (hrtimer_cancel(&session->rxtimer)) in j1939_session_rxtimer_cancel()
312 return (!skcb->addr.dst_name && (skcb->addr.da == 0xff)); in j1939_cb_is_broadcast()
322 if (skb_queue_len(&session->skb_queue) < 2) in j1939_session_skb_drop_old()
325 offset_start = session->pkt.tx_acked * 7; in j1939_session_skb_drop_old()
327 spin_lock_irqsave(&session->skb_queue.lock, flags); in j1939_session_skb_drop_old()
328 do_skb = skb_peek(&session->skb_queue); in j1939_session_skb_drop_old()
331 if ((do_skcb->offset + do_skb->len) < offset_start) { in j1939_session_skb_drop_old()
332 __skb_unlink(do_skb, &session->skb_queue); in j1939_session_skb_drop_old()
335 spin_unlock_irqrestore(&session->skb_queue.lock, flags); in j1939_session_skb_drop_old()
342 struct j1939_priv *priv = session->priv; in j1939_session_skb_queue()
346 if (j1939_address_is_unicast(skcb->addr.da) && in j1939_session_skb_queue()
347 priv->ents[skcb->addr.da].nusers) in j1939_session_skb_queue()
348 skcb->flags |= J1939_ECU_LOCAL_DST; in j1939_session_skb_queue()
350 skcb->flags |= J1939_ECU_LOCAL_SRC; in j1939_session_skb_queue()
352 skb_queue_tail(&session->skb_queue, skb); in j1939_session_skb_queue()
359 struct j1939_priv *priv = session->priv; in j1939_session_skb_find_by_offset()
365 spin_lock_irqsave(&session->skb_queue.lock, flags); in j1939_session_skb_find_by_offset()
366 skb_queue_walk(&session->skb_queue, do_skb) { in j1939_session_skb_find_by_offset()
369 if (offset_start >= do_skcb->offset && in j1939_session_skb_find_by_offset()
370 offset_start < (do_skcb->offset + do_skb->len)) { in j1939_session_skb_find_by_offset()
374 spin_unlock_irqrestore(&session->skb_queue.lock, flags); in j1939_session_skb_find_by_offset()
377 netdev_dbg(priv->ndev, "%s: 0x%p: no skb found for start: %i, queue size: %i\n", in j1939_session_skb_find_by_offset()
379 skb_queue_len(&session->skb_queue)); in j1939_session_skb_find_by_offset()
388 offset_start = session->pkt.dpo * 7; in j1939_session_skb_find()
397 return skcb->flags & J1939_ECU_LOCAL_DST; in j1939_tp_im_receiver()
403 return skcb->flags & J1939_ECU_LOCAL_SRC; in j1939_tp_im_transmitter()
407 static int j1939_tp_im_involved(const struct j1939_sk_buff_cb *skcb, bool swap) in j1939_tp_im_involved() argument
409 if (swap) in j1939_tp_im_involved()
417 return skcb->flags & (J1939_ECU_LOCAL_SRC | J1939_ECU_LOCAL_DST); in j1939_tp_im_involved_anydir()
420 /* extract pgn from flow-ctl message */
448 * reverse: swap cb's src & dst
456 if (se_addr->type != sk_addr->type) in j1939_session_match()
460 if (se_addr->src_name) { in j1939_session_match()
461 if (se_addr->src_name != sk_addr->dst_name) in j1939_session_match()
463 } else if (se_addr->sa != sk_addr->da) { in j1939_session_match()
467 if (se_addr->dst_name) { in j1939_session_match()
468 if (se_addr->dst_name != sk_addr->src_name) in j1939_session_match()
470 } else if (se_addr->da != sk_addr->sa) { in j1939_session_match()
474 if (se_addr->src_name) { in j1939_session_match()
475 if (se_addr->src_name != sk_addr->src_name) in j1939_session_match()
477 } else if (se_addr->sa != sk_addr->sa) { in j1939_session_match()
481 if (se_addr->dst_name) { in j1939_session_match()
482 if (se_addr->dst_name != sk_addr->dst_name) in j1939_session_match()
484 } else if (se_addr->da != sk_addr->da) { in j1939_session_match()
500 lockdep_assert_held(&priv->active_session_list_lock); in j1939_session_get_by_addr_locked()
504 if (j1939_session_match(&session->skcb.addr, addr, reverse) && in j1939_session_get_by_addr_locked()
505 session->transmission == transmitter) in j1939_session_get_by_addr_locked()
520 lockdep_assert_held(&priv->active_session_list_lock); in j1939_session_get_simple()
522 list_for_each_entry(session, &priv->active_session_list, in j1939_session_get_simple()
525 if (session->skcb.addr.type == J1939_SIMPLE && in j1939_session_get_simple()
526 session->tskey == skcb->tskey && session->sk == skb->sk) in j1939_session_get_simple()
543 &priv->active_session_list, in j1939_session_get_by_addr()
554 swap(skcb->addr.dst_name, skcb->addr.src_name); in j1939_skbcb_swap()
555 swap(skcb->addr.da, skcb->addr.sa); in j1939_skbcb_swap()
557 /* swap SRC and DST flags, leave other untouched */ in j1939_skbcb_swap()
558 if (skcb->flags & J1939_ECU_LOCAL_SRC) in j1939_skbcb_swap()
560 if (skcb->flags & J1939_ECU_LOCAL_DST) in j1939_skbcb_swap()
562 skcb->flags &= ~(J1939_ECU_LOCAL_SRC | J1939_ECU_LOCAL_DST); in j1939_skbcb_swap()
563 skcb->flags |= tmp; in j1939_skbcb_swap()
578 return ERR_PTR(-ENOMEM); in j1939_tp_tx_dat_new()
580 skb->dev = priv->ndev; in j1939_tp_tx_dat_new()
582 can_skb_prv(skb)->ifindex = priv->ndev->ifindex; in j1939_tp_tx_dat_new()
583 can_skb_prv(skb)->skbcnt = 0; in j1939_tp_tx_dat_new()
587 memcpy(skb->cb, re_skcb, sizeof(skb->cb)); in j1939_tp_tx_dat_new()
593 if (skcb->addr.type == J1939_ETP) in j1939_tp_tx_dat_new()
594 skcb->addr.pgn = J1939_ETP_PGN_CTL; in j1939_tp_tx_dat_new()
596 skcb->addr.pgn = J1939_TP_PGN_CTL; in j1939_tp_tx_dat_new()
598 if (skcb->addr.type == J1939_ETP) in j1939_tp_tx_dat_new()
599 skcb->addr.pgn = J1939_ETP_PGN_DAT; in j1939_tp_tx_dat_new()
601 skcb->addr.pgn = J1939_TP_PGN_DAT; in j1939_tp_tx_dat_new()
611 struct j1939_priv *priv = session->priv; in j1939_tp_tx_dat()
614 skb = j1939_tp_tx_dat_new(priv, &session->skcb, in j1939_tp_tx_dat()
621 memset(skb_put(skb, 8 - len), 0xff, 8 - len); in j1939_tp_tx_dat()
652 struct j1939_priv *priv = session->priv; in j1939_tp_tx_ctl()
654 return j1939_xtp_do_tx_ctl(priv, &session->skcb, in j1939_tp_tx_ctl()
656 session->skcb.addr.pgn, dat); in j1939_tp_tx_ctl()
679 hrtimer_start(&session->txtimer, ms_to_ktime(msec), in j1939_tp_schedule_txtimer()
688 hrtimer_start(&session->rxtimer, ms_to_ktime(msec), in j1939_tp_set_rxtimeout()
699 dat[1] = (session->total_message_size >> 0); in j1939_session_tx_rts()
700 dat[2] = (session->total_message_size >> 8); in j1939_session_tx_rts()
701 dat[3] = session->pkt.total; in j1939_session_tx_rts()
703 if (session->skcb.addr.type == J1939_ETP) { in j1939_session_tx_rts()
705 dat[1] = (session->total_message_size >> 0); in j1939_session_tx_rts()
706 dat[2] = (session->total_message_size >> 8); in j1939_session_tx_rts()
707 dat[3] = (session->total_message_size >> 16); in j1939_session_tx_rts()
708 dat[4] = (session->total_message_size >> 24); in j1939_session_tx_rts()
709 } else if (j1939_cb_is_broadcast(&session->skcb)) { in j1939_session_tx_rts()
712 session->pkt.tx = 0; in j1939_session_tx_rts()
718 if (dat[0] == session->last_txcmd) in j1939_session_tx_rts()
726 session->last_txcmd = dat[0]; in j1939_session_tx_rts()
734 netdev_dbg(session->priv->ndev, "%s: 0x%p\n", __func__, session); in j1939_session_tx_rts()
748 session->pkt.dpo = session->pkt.tx_acked; in j1939_session_tx_dpo()
749 pkt = session->pkt.dpo; in j1939_session_tx_dpo()
750 dat[1] = session->pkt.last - session->pkt.tx_acked; in j1939_session_tx_dpo()
759 session->last_txcmd = dat[0]; in j1939_session_tx_dpo()
761 session->pkt.tx = session->pkt.tx_acked; in j1939_session_tx_dpo()
763 netdev_dbg(session->priv->ndev, "%s: 0x%p\n", __func__, session); in j1939_session_tx_dpo()
770 struct j1939_priv *priv = session->priv; in j1939_session_tx_dat()
779 se_skb = j1939_session_skb_find_by_offset(session, session->pkt.tx * 7); in j1939_session_tx_dat()
781 return -ENOBUFS; in j1939_session_tx_dat()
784 tpdat = se_skb->data; in j1939_session_tx_dat()
787 if (session->skcb.addr.type != J1939_ETP && in j1939_session_tx_dat()
788 j1939_cb_is_broadcast(&session->skcb)) in j1939_session_tx_dat()
789 pkt_end = session->pkt.total; in j1939_session_tx_dat()
791 pkt_end = session->pkt.last; in j1939_session_tx_dat()
793 while (session->pkt.tx < pkt_end) { in j1939_session_tx_dat()
794 dat[0] = session->pkt.tx - session->pkt.dpo + 1; in j1939_session_tx_dat()
795 offset = (session->pkt.tx * 7) - skcb->offset; in j1939_session_tx_dat()
796 len = se_skb->len - offset; in j1939_session_tx_dat()
800 if (offset + len > se_skb->len) { in j1939_session_tx_dat()
801 netdev_err_once(priv->ndev, in j1939_session_tx_dat()
802 "%s: 0x%p: requested data outside of queued buffer: offset %i, len %i, pkt.tx: %i\n", in j1939_session_tx_dat()
803 __func__, session, skcb->offset, se_skb->len , session->pkt.tx); in j1939_session_tx_dat()
804 return -EOVERFLOW; in j1939_session_tx_dat()
808 ret = -ENOBUFS; in j1939_session_tx_dat()
815 /* ENOBUS == CAN interface TX queue is full */ in j1939_session_tx_dat()
816 if (ret != -ENOBUFS) in j1939_session_tx_dat()
817 netdev_alert(priv->ndev, in j1939_session_tx_dat()
823 session->last_txcmd = 0xff; in j1939_session_tx_dat()
825 session->pkt.tx++; in j1939_session_tx_dat()
826 pdelay = j1939_cb_is_broadcast(&session->skcb) ? 50 : in j1939_session_tx_dat()
829 if (session->pkt.tx < session->pkt.total && pdelay) { in j1939_session_tx_dat()
843 struct j1939_priv *priv = session->priv; in j1939_xtp_txnext_transmiter()
846 if (!j1939_tp_im_transmitter(&session->skcb)) { in j1939_xtp_txnext_transmiter()
847 netdev_alert(priv->ndev, "%s: 0x%p: called by not transmitter!\n", in j1939_xtp_txnext_transmiter()
849 return -EINVAL; in j1939_xtp_txnext_transmiter()
852 switch (session->last_cmd) { in j1939_xtp_txnext_transmiter()
858 if (session->last_txcmd != J1939_ETP_CMD_DPO) { in j1939_xtp_txnext_transmiter()
873 netdev_alert(priv->ndev, "%s: 0x%p: unexpected last_cmd: %x\n", in j1939_xtp_txnext_transmiter()
874 __func__, session, session->last_cmd); in j1939_xtp_txnext_transmiter()
882 struct j1939_priv *priv = session->priv; in j1939_session_tx_cts()
887 if (!j1939_sk_recv_match(priv, &session->skcb)) in j1939_session_tx_cts()
888 return -ENOENT; in j1939_session_tx_cts()
890 len = session->pkt.total - session->pkt.rx; in j1939_session_tx_cts()
891 len = min3(len, session->pkt.block, j1939_tp_block ?: 255); in j1939_session_tx_cts()
894 if (session->skcb.addr.type == J1939_ETP) { in j1939_session_tx_cts()
895 pkt = session->pkt.rx + 1; in j1939_session_tx_cts()
904 dat[2] = session->pkt.rx + 1; in j1939_session_tx_cts()
907 if (dat[0] == session->last_txcmd) in j1939_session_tx_cts()
917 session->last_txcmd = dat[0]; in j1939_session_tx_cts()
920 netdev_dbg(session->priv->ndev, "%s: 0x%p\n", __func__, session); in j1939_session_tx_cts()
927 struct j1939_priv *priv = session->priv; in j1939_session_tx_eoma()
931 if (!j1939_sk_recv_match(priv, &session->skcb)) in j1939_session_tx_eoma()
932 return -ENOENT; in j1939_session_tx_eoma()
936 if (session->skcb.addr.type == J1939_ETP) { in j1939_session_tx_eoma()
938 dat[1] = session->total_message_size >> 0; in j1939_session_tx_eoma()
939 dat[2] = session->total_message_size >> 8; in j1939_session_tx_eoma()
940 dat[3] = session->total_message_size >> 16; in j1939_session_tx_eoma()
941 dat[4] = session->total_message_size >> 24; in j1939_session_tx_eoma()
944 dat[1] = session->total_message_size; in j1939_session_tx_eoma()
945 dat[2] = session->total_message_size >> 8; in j1939_session_tx_eoma()
946 dat[3] = session->pkt.total; in j1939_session_tx_eoma()
949 if (dat[0] == session->last_txcmd) in j1939_session_tx_eoma()
957 session->last_txcmd = dat[0]; in j1939_session_tx_eoma()
962 netdev_dbg(session->priv->ndev, "%p: 0x%p\n", __func__, session); in j1939_session_tx_eoma()
969 struct j1939_priv *priv = session->priv; in j1939_xtp_txnext_receiver()
972 if (!j1939_tp_im_receiver(&session->skcb)) { in j1939_xtp_txnext_receiver()
973 netdev_alert(priv->ndev, "%s: 0x%p: called by not receiver!\n", in j1939_xtp_txnext_receiver()
975 return -EINVAL; in j1939_xtp_txnext_receiver()
978 switch (session->last_cmd) { in j1939_xtp_txnext_receiver()
988 if ((session->skcb.addr.type == J1939_TP && in j1939_xtp_txnext_receiver()
989 j1939_cb_is_broadcast(&session->skcb))) in j1939_xtp_txnext_receiver()
992 if (session->pkt.rx >= session->pkt.total) { in j1939_xtp_txnext_receiver()
994 } else if (session->pkt.rx >= session->pkt.last) { in j1939_xtp_txnext_receiver()
995 session->last_txcmd = 0; in j1939_xtp_txnext_receiver()
1000 netdev_alert(priv->ndev, "%s: 0x%p: unexpected last_cmd: %x\n", in j1939_xtp_txnext_receiver()
1001 __func__, session, session->last_cmd); in j1939_xtp_txnext_receiver()
1009 struct j1939_priv *priv = session->priv; in j1939_simple_txnext()
1019 return -ENOMEM; in j1939_simple_txnext()
1021 can_skb_set_owner(skb, se_skb->sk); in j1939_simple_txnext()
1039 lockdep_assert_held(&session->priv->active_session_list_lock); in j1939_session_deactivate_locked()
1041 if (session->state >= J1939_SESSION_ACTIVE && in j1939_session_deactivate_locked()
1042 session->state < J1939_SESSION_ACTIVE_MAX) { in j1939_session_deactivate_locked()
1045 list_del_init(&session->active_session_list_entry); in j1939_session_deactivate_locked()
1046 session->state = J1939_SESSION_DONE; in j1939_session_deactivate_locked()
1057 j1939_session_list_lock(session->priv); in j1939_session_deactivate()
1059 j1939_session_list_unlock(session->priv); in j1939_session_deactivate()
1074 struct j1939_priv *priv = session->priv; in __j1939_session_cancel()
1077 lockdep_assert_held(&session->priv->active_session_list_lock); in __j1939_session_cancel()
1079 session->err = j1939_xtp_abort_to_errno(priv, err); in __j1939_session_cancel()
1080 session->state = J1939_SESSION_WAITING_ABORT; in __j1939_session_cancel()
1082 if (!j1939_cb_is_broadcast(&session->skcb)) { in __j1939_session_cancel()
1083 j1939_xtp_tx_abort(priv, &session->skcb, in __j1939_session_cancel()
1084 !session->transmission, in __j1939_session_cancel()
1085 err, session->skcb.addr.pgn); in __j1939_session_cancel()
1088 if (session->sk) in __j1939_session_cancel()
1089 j1939_sk_send_loop_abort(session->sk, session->err); in __j1939_session_cancel()
1095 j1939_session_list_lock(session->priv); in j1939_session_cancel()
1097 if (session->state >= J1939_SESSION_ACTIVE && in j1939_session_cancel()
1098 session->state < J1939_SESSION_WAITING_ABORT) { in j1939_session_cancel()
1103 j1939_session_list_unlock(session->priv); in j1939_session_cancel()
1110 struct j1939_priv *priv = session->priv; in j1939_tp_txtimer()
1113 if (session->skcb.addr.type == J1939_SIMPLE) { in j1939_tp_txtimer()
1116 if (session->transmission) in j1939_tp_txtimer()
1123 case -ENOBUFS: in j1939_tp_txtimer()
1125 if (session->tx_retry < J1939_XTP_TX_RETRY_LIMIT) { in j1939_tp_txtimer()
1126 session->tx_retry++; in j1939_tp_txtimer()
1130 netdev_alert(priv->ndev, "%s: 0x%p: tx retry count reached\n", in j1939_tp_txtimer()
1132 session->err = -ENETUNREACH; in j1939_tp_txtimer()
1137 case -ENETDOWN: in j1939_tp_txtimer()
1145 case -EOVERFLOW: in j1939_tp_txtimer()
1149 session->tx_retry = 0; in j1939_tp_txtimer()
1152 netdev_alert(priv->ndev, "%s: 0x%p: tx aborted with unknown reason: %i\n", in j1939_tp_txtimer()
1154 if (session->skcb.addr.type != J1939_SIMPLE) { in j1939_tp_txtimer()
1157 session->err = ret; in j1939_tp_txtimer()
1172 if (!session->transmission) { in j1939_session_completed()
1175 j1939_sk_recv(session->priv, skb); in j1939_session_completed()
1186 struct j1939_priv *priv = session->priv; in j1939_tp_rxtimer()
1188 if (session->state == J1939_SESSION_WAITING_ABORT) { in j1939_tp_rxtimer()
1189 netdev_alert(priv->ndev, "%s: 0x%p: abort rx timeout. Force session deactivation\n", in j1939_tp_rxtimer()
1194 } else if (session->skcb.addr.type == J1939_SIMPLE) { in j1939_tp_rxtimer()
1195 netdev_alert(priv->ndev, "%s: 0x%p: Timeout. Failed to send simple message.\n", in j1939_tp_rxtimer()
1201 session->err = -ETIME; in j1939_tp_rxtimer()
1204 netdev_alert(priv->ndev, "%s: 0x%p: rx timeout, send abort\n", in j1939_tp_rxtimer()
1207 j1939_session_list_lock(session->priv); in j1939_tp_rxtimer()
1208 if (session->state >= J1939_SESSION_ACTIVE && in j1939_tp_rxtimer()
1209 session->state < J1939_SESSION_ACTIVE_MAX) { in j1939_tp_rxtimer()
1211 hrtimer_start(&session->rxtimer, in j1939_tp_rxtimer()
1216 j1939_session_list_unlock(session->priv); in j1939_tp_rxtimer()
1228 pgn_t pgn = j1939_xtp_ctl_to_pgn(skb->data); in j1939_xtp_rx_cmd_bad_pgn()
1229 struct j1939_priv *priv = session->priv; in j1939_xtp_rx_cmd_bad_pgn()
1231 u8 cmd = skb->data[0]; in j1939_xtp_rx_cmd_bad_pgn()
1233 if (session->skcb.addr.pgn == pgn) in j1939_xtp_rx_cmd_bad_pgn()
1269 …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()
1270 __func__, session, cmd, pgn, session->skcb.addr.pgn); in j1939_xtp_rx_cmd_bad_pgn()
1282 u8 abort = skb->data[1]; in j1939_xtp_rx_abort_one()
1284 session = j1939_session_get_by_addr(priv, &skcb->addr, reverse, in j1939_xtp_rx_abort_one()
1292 netdev_info(priv->ndev, "%s: 0x%p: 0x%05x: (%u) %s\n", __func__, in j1939_xtp_rx_abort_one()
1293 session, j1939_xtp_ctl_to_pgn(skb->data), abort, in j1939_xtp_rx_abort_one()
1297 session->err = j1939_xtp_abort_to_errno(priv, abort); in j1939_xtp_rx_abort_one()
1298 if (session->sk) in j1939_xtp_rx_abort_one()
1299 j1939_sk_send_loop_abort(session->sk, session->err); in j1939_xtp_rx_abort_one()
1325 dat = skb->data; in j1939_xtp_rx_eoma_one()
1327 if (skcb->addr.type == J1939_ETP) in j1939_xtp_rx_eoma_one()
1332 if (session->total_message_size != len) { in j1939_xtp_rx_eoma_one()
1333 netdev_warn_once(session->priv->ndev, in j1939_xtp_rx_eoma_one()
1335 __func__, session, session->total_message_size, in j1939_xtp_rx_eoma_one()
1339 netdev_dbg(session->priv->ndev, "%s: 0x%p\n", __func__, session); in j1939_xtp_rx_eoma_one()
1341 session->pkt.tx_acked = session->pkt.total; in j1939_xtp_rx_eoma_one()
1354 session = j1939_session_get_by_addr(priv, &skcb->addr, true, in j1939_xtp_rx_eoma()
1370 dat = skb->data; in j1939_xtp_rx_cts_one()
1375 netdev_dbg(session->priv->ndev, "%s: 0x%p\n", __func__, session); in j1939_xtp_rx_cts_one()
1377 if (session->last_cmd == dat[0]) { in j1939_xtp_rx_cts_one()
1382 if (session->skcb.addr.type == J1939_ETP) in j1939_xtp_rx_cts_one()
1389 else if (dat[1] > session->pkt.block /* 0xff for etp */) in j1939_xtp_rx_cts_one()
1393 session->pkt.tx_acked = pkt - 1; in j1939_xtp_rx_cts_one()
1395 session->pkt.last = session->pkt.tx_acked + dat[1]; in j1939_xtp_rx_cts_one()
1396 if (session->pkt.last > session->pkt.total) in j1939_xtp_rx_cts_one()
1398 session->pkt.last = session->pkt.total; in j1939_xtp_rx_cts_one()
1399 /* TODO: do not set tx here, do it in txtimer */ in j1939_xtp_rx_cts_one()
1400 session->pkt.tx = session->pkt.tx_acked; in j1939_xtp_rx_cts_one()
1402 session->last_cmd = dat[0]; in j1939_xtp_rx_cts_one()
1405 if (session->transmission) { in j1939_xtp_rx_cts_one()
1406 if (session->pkt.tx_acked) in j1939_xtp_rx_cts_one()
1429 session = j1939_session_get_by_addr(priv, &skcb->addr, true, in j1939_xtp_rx_cts()
1447 INIT_LIST_HEAD(&session->active_session_list_entry); in j1939_session_new()
1448 INIT_LIST_HEAD(&session->sk_session_queue_entry); in j1939_session_new()
1449 kref_init(&session->kref); in j1939_session_new()
1452 session->priv = priv; in j1939_session_new()
1453 session->total_message_size = size; in j1939_session_new()
1454 session->state = J1939_SESSION_NEW; in j1939_session_new()
1456 skb_queue_head_init(&session->skb_queue); in j1939_session_new()
1457 skb_queue_tail(&session->skb_queue, skb); in j1939_session_new()
1460 memcpy(&session->skcb, skcb, sizeof(session->skcb)); in j1939_session_new()
1462 hrtimer_init(&session->txtimer, CLOCK_MONOTONIC, in j1939_session_new()
1464 session->txtimer.function = j1939_tp_txtimer; in j1939_session_new()
1465 hrtimer_init(&session->rxtimer, CLOCK_MONOTONIC, in j1939_session_new()
1467 session->rxtimer.function = j1939_tp_rxtimer; in j1939_session_new()
1469 netdev_dbg(priv->ndev, "%s: 0x%p: sa: %02x, da: %02x\n", in j1939_session_new()
1470 __func__, session, skcb->addr.sa, skcb->addr.da); in j1939_session_new()
1488 skb->dev = priv->ndev; in j1939_session_fresh_new()
1490 can_skb_prv(skb)->ifindex = priv->ndev->ifindex; in j1939_session_fresh_new()
1491 can_skb_prv(skb)->skbcnt = 0; in j1939_session_fresh_new()
1509 struct j1939_priv *priv = session->priv; in j1939_session_activate()
1514 if (session->skcb.addr.type != J1939_SIMPLE) in j1939_session_activate()
1516 &priv->active_session_list, in j1939_session_activate()
1517 &session->skcb.addr, false, in j1939_session_activate()
1518 session->transmission); in j1939_session_activate()
1521 ret = -EAGAIN; in j1939_session_activate()
1523 WARN_ON_ONCE(session->state != J1939_SESSION_NEW); in j1939_session_activate()
1524 list_add_tail(&session->active_session_list_entry, in j1939_session_activate()
1525 &priv->active_session_list); in j1939_session_activate()
1527 session->state = J1939_SESSION_ACTIVE; in j1939_session_activate()
1529 netdev_dbg(session->priv->ndev, "%s: 0x%p\n", in j1939_session_activate()
1548 netdev_dbg(priv->ndev, "%s\n", __func__); in j1939_xtp_rx_rts_session_new()
1550 dat = skb->data; in j1939_xtp_rx_rts_session_new()
1561 else if (len > priv->tp_max_packet_size) in j1939_xtp_rx_rts_session_new()
1569 else if (len > priv->tp_max_packet_size) in j1939_xtp_rx_rts_session_new()
1586 session->pkt.total = (len + 6) / 7; in j1939_xtp_rx_rts_session_new()
1587 session->pkt.block = 0xff; in j1939_xtp_rx_rts_session_new()
1589 if (dat[3] != session->pkt.total) in j1939_xtp_rx_rts_session_new()
1590 netdev_alert(priv->ndev, "%s: 0x%p: strange total, %u != %u\n", in j1939_xtp_rx_rts_session_new()
1591 __func__, session, session->pkt.total, in j1939_xtp_rx_rts_session_new()
1593 session->pkt.total = dat[3]; in j1939_xtp_rx_rts_session_new()
1594 session->pkt.block = min(dat[3], dat[4]); in j1939_xtp_rx_rts_session_new()
1597 session->pkt.rx = 0; in j1939_xtp_rx_rts_session_new()
1598 session->pkt.tx = 0; in j1939_xtp_rx_rts_session_new()
1609 struct j1939_priv *priv = session->priv; in j1939_xtp_rx_rts_session_active()
1611 if (!session->transmission) { in j1939_xtp_rx_rts_session_active()
1613 return -EBUSY; in j1939_xtp_rx_rts_session_active()
1620 if (session->last_cmd != 0) { in j1939_xtp_rx_rts_session_active()
1622 netdev_alert(priv->ndev, "%s: 0x%p: connection exists (%02x %02x). last cmd: %x\n", in j1939_xtp_rx_rts_session_active()
1623 __func__, session, skcb->addr.sa, skcb->addr.da, in j1939_xtp_rx_rts_session_active()
1624 session->last_cmd); in j1939_xtp_rx_rts_session_active()
1629 return -EBUSY; in j1939_xtp_rx_rts_session_active()
1632 if (session->skcb.addr.sa != skcb->addr.sa || in j1939_xtp_rx_rts_session_active()
1633 session->skcb.addr.da != skcb->addr.da) in j1939_xtp_rx_rts_session_active()
1634 …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()
1636 session->skcb.addr.sa, skcb->addr.sa, in j1939_xtp_rx_rts_session_active()
1637 session->skcb.addr.da, skcb->addr.da); in j1939_xtp_rx_rts_session_active()
1642 session->skcb.addr.sa = skcb->addr.sa; in j1939_xtp_rx_rts_session_active()
1643 session->skcb.addr.da = skcb->addr.da; in j1939_xtp_rx_rts_session_active()
1645 netdev_dbg(session->priv->ndev, "%s: 0x%p\n", __func__, session); in j1939_xtp_rx_rts_session_active()
1655 u8 cmd = skb->data[0]; in j1939_xtp_rx_rts()
1657 session = j1939_session_get_by_addr(priv, &skcb->addr, false, in j1939_xtp_rx_rts()
1673 * - user space closed socket was and the session was in j1939_xtp_rx_rts()
1675 * - session was aborted due to external abort message in j1939_xtp_rx_rts()
1682 netdev_info(priv->ndev, "%s: failed to create TP BAM session\n", in j1939_xtp_rx_rts()
1692 session->last_cmd = cmd; in j1939_xtp_rx_rts()
1695 if (!session->transmission) in j1939_xtp_rx_rts()
1698 if (!session->transmission) { in j1939_xtp_rx_rts()
1711 const u8 *dat = skb->data; in j1939_xtp_rx_dpo_one()
1716 netdev_dbg(session->priv->ndev, "%s: 0x%p\n", __func__, session); in j1939_xtp_rx_dpo_one()
1719 session->pkt.dpo = j1939_etp_ctl_to_packet(skb->data); in j1939_xtp_rx_dpo_one()
1720 session->last_cmd = dat[0]; in j1939_xtp_rx_dpo_one()
1730 session = j1939_session_get_by_addr(priv, &skcb->addr, false, in j1939_xtp_rx_dpo()
1733 netdev_info(priv->ndev, in j1939_xtp_rx_dpo()
1745 struct j1939_priv *priv = session->priv; in j1939_xtp_rx_dat_one()
1758 dat = skb->data; in j1939_xtp_rx_dat_one()
1759 if (skb->len <= 1) in j1939_xtp_rx_dat_one()
1763 switch (session->last_cmd) { in j1939_xtp_rx_dat_one()
1767 if (skcb->addr.type == J1939_ETP) in j1939_xtp_rx_dat_one()
1772 if (skcb->addr.type != J1939_ETP) in j1939_xtp_rx_dat_one()
1776 netdev_info(priv->ndev, "%s: 0x%p: last %02x\n", __func__, in j1939_xtp_rx_dat_one()
1777 session, session->last_cmd); in j1939_xtp_rx_dat_one()
1781 packet = (dat[0] - 1 + session->pkt.dpo); in j1939_xtp_rx_dat_one()
1782 if (packet > session->pkt.total || in j1939_xtp_rx_dat_one()
1783 (session->pkt.rx + 1) > session->pkt.total) { in j1939_xtp_rx_dat_one()
1784 netdev_info(priv->ndev, "%s: 0x%p: should have been completed\n", in j1939_xtp_rx_dat_one()
1791 netdev_warn(priv->ndev, "%s: 0x%p: no skb found\n", __func__, in j1939_xtp_rx_dat_one()
1797 offset = packet * 7 - skcb->offset; in j1939_xtp_rx_dat_one()
1798 nbytes = se_skb->len - offset; in j1939_xtp_rx_dat_one()
1801 if (nbytes <= 0 || (nbytes + 1) > skb->len) { in j1939_xtp_rx_dat_one()
1802 netdev_info(priv->ndev, "%s: 0x%p: nbytes %i, len %i\n", in j1939_xtp_rx_dat_one()
1803 __func__, session, nbytes, skb->len); in j1939_xtp_rx_dat_one()
1807 tpdat = se_skb->data; in j1939_xtp_rx_dat_one()
1808 if (!session->transmission) { in j1939_xtp_rx_dat_one()
1815 netdev_err_once(priv->ndev, in j1939_xtp_rx_dat_one()
1816 "%s: 0x%p: Data of RX-looped back packet (%*ph) doesn't match TX data (%*ph)!\n", in j1939_xtp_rx_dat_one()
1822 if (packet == session->pkt.rx) in j1939_xtp_rx_dat_one()
1823 session->pkt.rx++; in j1939_xtp_rx_dat_one()
1825 if (skcb->addr.type != J1939_ETP && in j1939_xtp_rx_dat_one()
1826 j1939_cb_is_broadcast(&session->skcb)) { in j1939_xtp_rx_dat_one()
1827 if (session->pkt.rx >= session->pkt.total) in j1939_xtp_rx_dat_one()
1833 if (session->pkt.rx >= session->pkt.last) in j1939_xtp_rx_dat_one()
1841 if (!session->transmission) in j1939_xtp_rx_dat_one()
1845 if (!session->transmission) in j1939_xtp_rx_dat_one()
1850 session->last_cmd = 0xff; in j1939_xtp_rx_dat_one()
1869 session = j1939_session_get_by_addr(priv, &skcb->addr, false, in j1939_xtp_rx_dat()
1872 netdev_info(priv->ndev, "%s: no tx connection found\n", in j1939_xtp_rx_dat()
1879 session = j1939_session_get_by_addr(priv, &skcb->addr, false, in j1939_xtp_rx_dat()
1882 netdev_info(priv->ndev, "%s: no rx connection found\n", in j1939_xtp_rx_dat()
1889 session = j1939_session_get_by_addr(priv, &skcb->addr, false, in j1939_xtp_rx_dat()
1904 if (skcb->addr.pgn == J1939_TP_PGN_DAT || in j1939_tp_send()
1905 skcb->addr.pgn == J1939_TP_PGN_CTL || in j1939_tp_send()
1906 skcb->addr.pgn == J1939_ETP_PGN_DAT || in j1939_tp_send()
1907 skcb->addr.pgn == J1939_ETP_PGN_CTL) in j1939_tp_send()
1909 return ERR_PTR(-EDOM); in j1939_tp_send()
1911 if (size > priv->tp_max_packet_size) in j1939_tp_send()
1912 return ERR_PTR(-EMSGSIZE); in j1939_tp_send()
1915 skcb->addr.type = J1939_SIMPLE; in j1939_tp_send()
1917 skcb->addr.type = J1939_ETP; in j1939_tp_send()
1919 skcb->addr.type = J1939_TP; in j1939_tp_send()
1921 if (skcb->addr.type == J1939_ETP && in j1939_tp_send()
1923 return ERR_PTR(-EDESTADDRREQ); in j1939_tp_send()
1931 if (j1939_address_is_unicast(skcb->addr.da) && in j1939_tp_send()
1932 priv->ents[skcb->addr.da].nusers) in j1939_tp_send()
1933 skcb->flags |= J1939_ECU_LOCAL_DST; in j1939_tp_send()
1936 skcb->flags |= J1939_ECU_LOCAL_SRC; in j1939_tp_send()
1941 return ERR_PTR(-ENOMEM); in j1939_tp_send()
1944 sock_hold(skb->sk); in j1939_tp_send()
1945 session->sk = skb->sk; in j1939_tp_send()
1946 session->transmission = true; in j1939_tp_send()
1947 session->pkt.total = (size + 6) / 7; in j1939_tp_send()
1948 session->pkt.block = skcb->addr.type == J1939_ETP ? 255 : in j1939_tp_send()
1949 min(j1939_tp_block ?: 255, session->pkt.total); in j1939_tp_send()
1951 if (j1939_cb_is_broadcast(&session->skcb)) in j1939_tp_send()
1952 /* set the end-packet for broadcast */ in j1939_tp_send()
1953 session->pkt.last = session->pkt.total; in j1939_tp_send()
1955 skcb->tskey = session->sk->sk_tskey++; in j1939_tp_send()
1956 session->tskey = skcb->tskey; in j1939_tp_send()
1965 u8 cmd = skb->data[0]; in j1939_tp_cmd_recv()
1973 if (skcb->addr.type != extd) in j1939_tp_cmd_recv()
1977 netdev_alert(priv->ndev, "%s: rts without destination (%02x)\n", in j1939_tp_cmd_recv()
1978 __func__, skcb->addr.sa); in j1939_tp_cmd_recv()
1994 if (skcb->addr.type != extd) in j1939_tp_cmd_recv()
2006 if (skcb->addr.type != J1939_ETP) in j1939_tp_cmd_recv()
2021 if (skcb->addr.type != extd) in j1939_tp_cmd_recv()
2052 switch (skcb->addr.pgn) { in j1939_tp_recv()
2054 skcb->addr.type = J1939_ETP; in j1939_tp_recv()
2061 skcb->addr.type = J1939_ETP; in j1939_tp_recv()
2064 if (skb->len < 8) in j1939_tp_recv()
2079 if (!skb->sk) in j1939_simple_recv()
2082 if (skb->sk->sk_family != AF_CAN || in j1939_simple_recv()
2083 skb->sk->sk_protocol != CAN_J1939) in j1939_simple_recv()
2090 netdev_warn(priv->ndev, in j1939_simple_recv()
2105 netdev_dbg(priv->ndev, "%s, sk: %p\n", __func__, sk); in j1939_cancel_active_session()
2108 &priv->active_session_list, in j1939_cancel_active_session()
2110 if (!sk || sk == session->sk) { in j1939_cancel_active_session()
2111 if (hrtimer_try_to_cancel(&session->txtimer) == 1) in j1939_cancel_active_session()
2113 if (hrtimer_try_to_cancel(&session->rxtimer) == 1) in j1939_cancel_active_session()
2116 session->err = ESHUTDOWN; in j1939_cancel_active_session()
2126 spin_lock_init(&priv->active_session_list_lock); in j1939_tp_init()
2127 INIT_LIST_HEAD(&priv->active_session_list); in j1939_tp_init()
2128 priv->tp_max_packet_size = J1939_MAX_ETP_PACKET_SIZE; in j1939_tp_init()