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->transmission) { in j1939_session_destroy()
264 if (session->err) in j1939_session_destroy()
268 } else if (session->err) { in j1939_session_destroy()
272 netdev_dbg(session->priv->ndev, "%s: 0x%p\n", __func__, session); in j1939_session_destroy()
274 WARN_ON_ONCE(!list_empty(&session->sk_session_queue_entry)); in j1939_session_destroy()
275 WARN_ON_ONCE(!list_empty(&session->active_session_list_entry)); in j1939_session_destroy()
277 skb_queue_purge(&session->skb_queue); in j1939_session_destroy()
279 j1939_priv_put(session->priv); in j1939_session_destroy()
293 kref_put(&session->kref, __j1939_session_release); in j1939_session_put()
298 if (hrtimer_cancel(&session->txtimer)) in j1939_session_txtimer_cancel()
304 if (hrtimer_cancel(&session->rxtimer)) in j1939_session_rxtimer_cancel()
316 return (!skcb->addr.dst_name && (skcb->addr.da == 0xff)); in j1939_cb_is_broadcast()
326 if (skb_queue_len(&session->skb_queue) < 2) in j1939_session_skb_drop_old()
329 offset_start = session->pkt.tx_acked * 7; in j1939_session_skb_drop_old()
331 spin_lock_irqsave(&session->skb_queue.lock, flags); in j1939_session_skb_drop_old()
332 do_skb = skb_peek(&session->skb_queue); in j1939_session_skb_drop_old()
335 if ((do_skcb->offset + do_skb->len) < offset_start) { in j1939_session_skb_drop_old()
336 __skb_unlink(do_skb, &session->skb_queue); in j1939_session_skb_drop_old()
342 spin_unlock_irqrestore(&session->skb_queue.lock, flags); in j1939_session_skb_drop_old()
349 struct j1939_priv *priv = session->priv; in j1939_session_skb_queue()
353 if (j1939_address_is_unicast(skcb->addr.da) && in j1939_session_skb_queue()
354 priv->ents[skcb->addr.da].nusers) in j1939_session_skb_queue()
355 skcb->flags |= J1939_ECU_LOCAL_DST; in j1939_session_skb_queue()
357 skcb->flags |= J1939_ECU_LOCAL_SRC; in j1939_session_skb_queue()
360 skb_queue_tail(&session->skb_queue, skb); in j1939_session_skb_queue()
367 struct j1939_priv *priv = session->priv; in j1939_session_skb_get_by_offset()
373 spin_lock_irqsave(&session->skb_queue.lock, flags); in j1939_session_skb_get_by_offset()
374 skb_queue_walk(&session->skb_queue, do_skb) { in j1939_session_skb_get_by_offset()
377 if (offset_start >= do_skcb->offset && in j1939_session_skb_get_by_offset()
378 offset_start < (do_skcb->offset + do_skb->len)) { in j1939_session_skb_get_by_offset()
386 spin_unlock_irqrestore(&session->skb_queue.lock, flags); in j1939_session_skb_get_by_offset()
389 netdev_dbg(priv->ndev, "%s: 0x%p: no skb found for start: %i, queue size: %i\n", in j1939_session_skb_get_by_offset()
391 skb_queue_len(&session->skb_queue)); in j1939_session_skb_get_by_offset()
400 offset_start = session->pkt.dpo * 7; in j1939_session_skb_get()
409 return skcb->flags & J1939_ECU_LOCAL_DST; in j1939_tp_im_receiver()
415 return skcb->flags & J1939_ECU_LOCAL_SRC; in j1939_tp_im_transmitter()
419 static int j1939_tp_im_involved(const struct j1939_sk_buff_cb *skcb, bool swap) in j1939_tp_im_involved() argument
421 if (swap) in j1939_tp_im_involved()
429 return skcb->flags & (J1939_ECU_LOCAL_SRC | J1939_ECU_LOCAL_DST); in j1939_tp_im_involved_anydir()
432 /* extract pgn from flow-ctl message */
460 * reverse: swap cb's src & dst
468 if (se_addr->type != sk_addr->type) in j1939_session_match()
472 if (se_addr->src_name) { in j1939_session_match()
473 if (se_addr->src_name != sk_addr->dst_name) in j1939_session_match()
475 } else if (se_addr->sa != sk_addr->da) { in j1939_session_match()
479 if (se_addr->dst_name) { in j1939_session_match()
480 if (se_addr->dst_name != sk_addr->src_name) in j1939_session_match()
482 } else if (se_addr->da != sk_addr->sa) { in j1939_session_match()
486 if (se_addr->src_name) { in j1939_session_match()
487 if (se_addr->src_name != sk_addr->src_name) in j1939_session_match()
489 } else if (se_addr->sa != sk_addr->sa) { in j1939_session_match()
493 if (se_addr->dst_name) { in j1939_session_match()
494 if (se_addr->dst_name != sk_addr->dst_name) in j1939_session_match()
496 } else if (se_addr->da != sk_addr->da) { in j1939_session_match()
512 lockdep_assert_held(&priv->active_session_list_lock); in j1939_session_get_by_addr_locked()
516 if (j1939_session_match(&session->skcb.addr, addr, reverse) && in j1939_session_get_by_addr_locked()
517 session->transmission == transmitter) in j1939_session_get_by_addr_locked()
532 lockdep_assert_held(&priv->active_session_list_lock); in j1939_session_get_simple()
534 list_for_each_entry(session, &priv->active_session_list, in j1939_session_get_simple()
537 if (session->skcb.addr.type == J1939_SIMPLE && in j1939_session_get_simple()
538 session->tskey == skcb->tskey && session->sk == skb->sk) in j1939_session_get_simple()
555 &priv->active_session_list, in j1939_session_get_by_addr()
566 swap(skcb->addr.dst_name, skcb->addr.src_name); in j1939_skbcb_swap()
567 swap(skcb->addr.da, skcb->addr.sa); in j1939_skbcb_swap()
569 /* swap SRC and DST flags, leave other untouched */ in j1939_skbcb_swap()
570 if (skcb->flags & J1939_ECU_LOCAL_SRC) in j1939_skbcb_swap()
572 if (skcb->flags & J1939_ECU_LOCAL_DST) in j1939_skbcb_swap()
574 skcb->flags &= ~(J1939_ECU_LOCAL_SRC | J1939_ECU_LOCAL_DST); in j1939_skbcb_swap()
575 skcb->flags |= tmp; in j1939_skbcb_swap()
590 return ERR_PTR(-ENOMEM); in j1939_tp_tx_dat_new()
592 skb->dev = priv->ndev; in j1939_tp_tx_dat_new()
594 can_skb_prv(skb)->ifindex = priv->ndev->ifindex; in j1939_tp_tx_dat_new()
595 can_skb_prv(skb)->skbcnt = 0; in j1939_tp_tx_dat_new()
599 memcpy(skb->cb, re_skcb, sizeof(skb->cb)); in j1939_tp_tx_dat_new()
605 if (skcb->addr.type == J1939_ETP) in j1939_tp_tx_dat_new()
606 skcb->addr.pgn = J1939_ETP_PGN_CTL; in j1939_tp_tx_dat_new()
608 skcb->addr.pgn = J1939_TP_PGN_CTL; in j1939_tp_tx_dat_new()
610 if (skcb->addr.type == J1939_ETP) in j1939_tp_tx_dat_new()
611 skcb->addr.pgn = J1939_ETP_PGN_DAT; in j1939_tp_tx_dat_new()
613 skcb->addr.pgn = J1939_TP_PGN_DAT; in j1939_tp_tx_dat_new()
623 struct j1939_priv *priv = session->priv; in j1939_tp_tx_dat()
626 skb = j1939_tp_tx_dat_new(priv, &session->skcb, in j1939_tp_tx_dat()
633 memset(skb_put(skb, 8 - len), 0xff, 8 - len); in j1939_tp_tx_dat()
664 struct j1939_priv *priv = session->priv; in j1939_tp_tx_ctl()
666 return j1939_xtp_do_tx_ctl(priv, &session->skcb, in j1939_tp_tx_ctl()
668 session->skcb.addr.pgn, dat); in j1939_tp_tx_ctl()
691 hrtimer_start(&session->txtimer, ms_to_ktime(msec), in j1939_tp_schedule_txtimer()
700 hrtimer_start(&session->rxtimer, ms_to_ktime(msec), in j1939_tp_set_rxtimeout()
711 dat[1] = (session->total_message_size >> 0); in j1939_session_tx_rts()
712 dat[2] = (session->total_message_size >> 8); in j1939_session_tx_rts()
713 dat[3] = session->pkt.total; in j1939_session_tx_rts()
715 if (session->skcb.addr.type == J1939_ETP) { in j1939_session_tx_rts()
717 dat[1] = (session->total_message_size >> 0); in j1939_session_tx_rts()
718 dat[2] = (session->total_message_size >> 8); in j1939_session_tx_rts()
719 dat[3] = (session->total_message_size >> 16); in j1939_session_tx_rts()
720 dat[4] = (session->total_message_size >> 24); in j1939_session_tx_rts()
721 } else if (j1939_cb_is_broadcast(&session->skcb)) { in j1939_session_tx_rts()
724 session->pkt.tx = 0; in j1939_session_tx_rts()
730 if (dat[0] == session->last_txcmd) in j1939_session_tx_rts()
738 session->last_txcmd = dat[0]; in j1939_session_tx_rts()
746 netdev_dbg(session->priv->ndev, "%s: 0x%p\n", __func__, session); in j1939_session_tx_rts()
760 session->pkt.dpo = session->pkt.tx_acked; in j1939_session_tx_dpo()
761 pkt = session->pkt.dpo; in j1939_session_tx_dpo()
762 dat[1] = session->pkt.last - session->pkt.tx_acked; in j1939_session_tx_dpo()
771 session->last_txcmd = dat[0]; in j1939_session_tx_dpo()
773 session->pkt.tx = session->pkt.tx_acked; in j1939_session_tx_dpo()
775 netdev_dbg(session->priv->ndev, "%s: 0x%p\n", __func__, session); in j1939_session_tx_dpo()
782 struct j1939_priv *priv = session->priv; in j1939_session_tx_dat()
791 se_skb = j1939_session_skb_get_by_offset(session, session->pkt.tx * 7); in j1939_session_tx_dat()
793 return -ENOBUFS; in j1939_session_tx_dat()
796 tpdat = se_skb->data; in j1939_session_tx_dat()
799 if (session->skcb.addr.type != J1939_ETP && in j1939_session_tx_dat()
800 j1939_cb_is_broadcast(&session->skcb)) in j1939_session_tx_dat()
801 pkt_end = session->pkt.total; in j1939_session_tx_dat()
803 pkt_end = session->pkt.last; in j1939_session_tx_dat()
805 while (session->pkt.tx < pkt_end) { in j1939_session_tx_dat()
806 dat[0] = session->pkt.tx - session->pkt.dpo + 1; in j1939_session_tx_dat()
807 offset = (session->pkt.tx * 7) - se_skcb->offset; in j1939_session_tx_dat()
808 len = se_skb->len - offset; in j1939_session_tx_dat()
812 if (offset + len > se_skb->len) { in j1939_session_tx_dat()
813 netdev_err_once(priv->ndev, in j1939_session_tx_dat()
814 "%s: 0x%p: requested data outside of queued buffer: offset %i, len %i, pkt.tx: %i\n", in j1939_session_tx_dat()
815 __func__, session, se_skcb->offset, in j1939_session_tx_dat()
816 se_skb->len , session->pkt.tx); in j1939_session_tx_dat()
817 ret = -EOVERFLOW; in j1939_session_tx_dat()
822 ret = -ENOBUFS; in j1939_session_tx_dat()
829 /* ENOBUFS == CAN interface TX queue is full */ in j1939_session_tx_dat()
830 if (ret != -ENOBUFS) in j1939_session_tx_dat()
831 netdev_alert(priv->ndev, in j1939_session_tx_dat()
837 session->last_txcmd = 0xff; in j1939_session_tx_dat()
839 session->pkt.tx++; in j1939_session_tx_dat()
840 pdelay = j1939_cb_is_broadcast(&session->skcb) ? 50 : in j1939_session_tx_dat()
843 if (session->pkt.tx < session->pkt.total && pdelay) { in j1939_session_tx_dat()
863 struct j1939_priv *priv = session->priv; in j1939_xtp_txnext_transmiter()
866 if (!j1939_tp_im_transmitter(&session->skcb)) { in j1939_xtp_txnext_transmiter()
867 netdev_alert(priv->ndev, "%s: 0x%p: called by not transmitter!\n", in j1939_xtp_txnext_transmiter()
869 return -EINVAL; in j1939_xtp_txnext_transmiter()
872 switch (session->last_cmd) { in j1939_xtp_txnext_transmiter()
878 if (session->last_txcmd != J1939_ETP_CMD_DPO) { in j1939_xtp_txnext_transmiter()
893 netdev_alert(priv->ndev, "%s: 0x%p: unexpected last_cmd: %x\n", in j1939_xtp_txnext_transmiter()
894 __func__, session, session->last_cmd); in j1939_xtp_txnext_transmiter()
902 struct j1939_priv *priv = session->priv; in j1939_session_tx_cts()
907 if (!j1939_sk_recv_match(priv, &session->skcb)) in j1939_session_tx_cts()
908 return -ENOENT; in j1939_session_tx_cts()
910 len = session->pkt.total - session->pkt.rx; in j1939_session_tx_cts()
911 len = min3(len, session->pkt.block, j1939_tp_block ?: 255); in j1939_session_tx_cts()
914 if (session->skcb.addr.type == J1939_ETP) { in j1939_session_tx_cts()
915 pkt = session->pkt.rx + 1; in j1939_session_tx_cts()
924 dat[2] = session->pkt.rx + 1; in j1939_session_tx_cts()
927 if (dat[0] == session->last_txcmd) in j1939_session_tx_cts()
937 session->last_txcmd = dat[0]; in j1939_session_tx_cts()
940 netdev_dbg(session->priv->ndev, "%s: 0x%p\n", __func__, session); in j1939_session_tx_cts()
947 struct j1939_priv *priv = session->priv; in j1939_session_tx_eoma()
951 if (!j1939_sk_recv_match(priv, &session->skcb)) in j1939_session_tx_eoma()
952 return -ENOENT; in j1939_session_tx_eoma()
956 if (session->skcb.addr.type == J1939_ETP) { in j1939_session_tx_eoma()
958 dat[1] = session->total_message_size >> 0; in j1939_session_tx_eoma()
959 dat[2] = session->total_message_size >> 8; in j1939_session_tx_eoma()
960 dat[3] = session->total_message_size >> 16; in j1939_session_tx_eoma()
961 dat[4] = session->total_message_size >> 24; in j1939_session_tx_eoma()
964 dat[1] = session->total_message_size; in j1939_session_tx_eoma()
965 dat[2] = session->total_message_size >> 8; in j1939_session_tx_eoma()
966 dat[3] = session->pkt.total; in j1939_session_tx_eoma()
969 if (dat[0] == session->last_txcmd) in j1939_session_tx_eoma()
977 session->last_txcmd = dat[0]; in j1939_session_tx_eoma()
982 netdev_dbg(session->priv->ndev, "%p: 0x%p\n", __func__, session); in j1939_session_tx_eoma()
989 struct j1939_priv *priv = session->priv; in j1939_xtp_txnext_receiver()
992 if (!j1939_tp_im_receiver(&session->skcb)) { in j1939_xtp_txnext_receiver()
993 netdev_alert(priv->ndev, "%s: 0x%p: called by not receiver!\n", in j1939_xtp_txnext_receiver()
995 return -EINVAL; in j1939_xtp_txnext_receiver()
998 switch (session->last_cmd) { in j1939_xtp_txnext_receiver()
1008 if ((session->skcb.addr.type == J1939_TP && in j1939_xtp_txnext_receiver()
1009 j1939_cb_is_broadcast(&session->skcb))) in j1939_xtp_txnext_receiver()
1012 if (session->pkt.rx >= session->pkt.total) { in j1939_xtp_txnext_receiver()
1014 } else if (session->pkt.rx >= session->pkt.last) { in j1939_xtp_txnext_receiver()
1015 session->last_txcmd = 0; in j1939_xtp_txnext_receiver()
1020 netdev_alert(priv->ndev, "%s: 0x%p: unexpected last_cmd: %x\n", in j1939_xtp_txnext_receiver()
1021 __func__, session, session->last_cmd); in j1939_xtp_txnext_receiver()
1029 struct j1939_priv *priv = session->priv; in j1939_simple_txnext()
1039 ret = -ENOMEM; in j1939_simple_txnext()
1043 can_skb_set_owner(skb, se_skb->sk); in j1939_simple_txnext()
1067 lockdep_assert_held(&session->priv->active_session_list_lock); in j1939_session_deactivate_locked()
1069 if (session->state >= J1939_SESSION_ACTIVE && in j1939_session_deactivate_locked()
1070 session->state < J1939_SESSION_ACTIVE_MAX) { in j1939_session_deactivate_locked()
1073 list_del_init(&session->active_session_list_entry); in j1939_session_deactivate_locked()
1074 session->state = J1939_SESSION_DONE; in j1939_session_deactivate_locked()
1083 struct j1939_priv *priv = session->priv; in j1939_session_deactivate()
1087 /* This function should be called with a session ref-count of at in j1939_session_deactivate()
1090 WARN_ON_ONCE(kref_read(&session->kref) < 2); in j1939_session_deactivate()
1107 struct j1939_priv *priv = session->priv; in __j1939_session_cancel()
1110 lockdep_assert_held(&session->priv->active_session_list_lock); in __j1939_session_cancel()
1112 session->err = j1939_xtp_abort_to_errno(priv, err); in __j1939_session_cancel()
1113 session->state = J1939_SESSION_WAITING_ABORT; in __j1939_session_cancel()
1115 if (!j1939_cb_is_broadcast(&session->skcb)) { in __j1939_session_cancel()
1116 j1939_xtp_tx_abort(priv, &session->skcb, in __j1939_session_cancel()
1117 !session->transmission, in __j1939_session_cancel()
1118 err, session->skcb.addr.pgn); in __j1939_session_cancel()
1121 if (session->sk) in __j1939_session_cancel()
1122 j1939_sk_send_loop_abort(session->sk, session->err); in __j1939_session_cancel()
1130 j1939_session_list_lock(session->priv); in j1939_session_cancel()
1132 if (session->state >= J1939_SESSION_ACTIVE && in j1939_session_cancel()
1133 session->state < J1939_SESSION_WAITING_ABORT) { in j1939_session_cancel()
1138 j1939_session_list_unlock(session->priv); in j1939_session_cancel()
1145 struct j1939_priv *priv = session->priv; in j1939_tp_txtimer()
1148 if (session->skcb.addr.type == J1939_SIMPLE) { in j1939_tp_txtimer()
1151 if (session->transmission) in j1939_tp_txtimer()
1158 case -ENOBUFS: in j1939_tp_txtimer()
1160 if (session->tx_retry < J1939_XTP_TX_RETRY_LIMIT) { in j1939_tp_txtimer()
1161 session->tx_retry++; in j1939_tp_txtimer()
1165 netdev_alert(priv->ndev, "%s: 0x%p: tx retry count reached\n", in j1939_tp_txtimer()
1167 session->err = -ENETUNREACH; in j1939_tp_txtimer()
1172 case -ENETDOWN: in j1939_tp_txtimer()
1180 case -EOVERFLOW: in j1939_tp_txtimer()
1184 session->tx_retry = 0; in j1939_tp_txtimer()
1187 netdev_alert(priv->ndev, "%s: 0x%p: tx aborted with unknown reason: %i\n", in j1939_tp_txtimer()
1189 if (session->skcb.addr.type != J1939_SIMPLE) { in j1939_tp_txtimer()
1192 session->err = ret; in j1939_tp_txtimer()
1207 if (!session->transmission) { in j1939_session_completed()
1210 j1939_sk_recv(session->priv, se_skb); in j1939_session_completed()
1222 struct j1939_priv *priv = session->priv; in j1939_tp_rxtimer()
1224 if (session->state == J1939_SESSION_WAITING_ABORT) { in j1939_tp_rxtimer()
1225 netdev_alert(priv->ndev, "%s: 0x%p: abort rx timeout. Force session deactivation\n", in j1939_tp_rxtimer()
1230 } else if (session->skcb.addr.type == J1939_SIMPLE) { in j1939_tp_rxtimer()
1231 netdev_alert(priv->ndev, "%s: 0x%p: Timeout. Failed to send simple message.\n", in j1939_tp_rxtimer()
1237 session->err = -ETIME; in j1939_tp_rxtimer()
1240 j1939_session_list_lock(session->priv); in j1939_tp_rxtimer()
1241 if (session->state >= J1939_SESSION_ACTIVE && in j1939_tp_rxtimer()
1242 session->state < J1939_SESSION_ACTIVE_MAX) { in j1939_tp_rxtimer()
1243 netdev_alert(priv->ndev, "%s: 0x%p: rx timeout, send abort\n", in j1939_tp_rxtimer()
1246 hrtimer_start(&session->rxtimer, in j1939_tp_rxtimer()
1251 j1939_session_list_unlock(session->priv); in j1939_tp_rxtimer()
1263 pgn_t pgn = j1939_xtp_ctl_to_pgn(skb->data); in j1939_xtp_rx_cmd_bad_pgn()
1264 struct j1939_priv *priv = session->priv; in j1939_xtp_rx_cmd_bad_pgn()
1266 u8 cmd = skb->data[0]; in j1939_xtp_rx_cmd_bad_pgn()
1268 if (session->skcb.addr.pgn == pgn) in j1939_xtp_rx_cmd_bad_pgn()
1307 …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()
1308 __func__, session, cmd, pgn, session->skcb.addr.pgn); in j1939_xtp_rx_cmd_bad_pgn()
1320 u8 abort = skb->data[1]; in j1939_xtp_rx_abort_one()
1322 session = j1939_session_get_by_addr(priv, &skcb->addr, reverse, in j1939_xtp_rx_abort_one()
1330 netdev_info(priv->ndev, "%s: 0x%p: 0x%05x: (%u) %s\n", __func__, in j1939_xtp_rx_abort_one()
1331 session, j1939_xtp_ctl_to_pgn(skb->data), abort, in j1939_xtp_rx_abort_one()
1335 session->err = j1939_xtp_abort_to_errno(priv, abort); in j1939_xtp_rx_abort_one()
1336 if (session->sk) in j1939_xtp_rx_abort_one()
1337 j1939_sk_send_loop_abort(session->sk, session->err); in j1939_xtp_rx_abort_one()
1365 dat = skb->data; in j1939_xtp_rx_eoma_one()
1367 if (skcb->addr.type == J1939_ETP) in j1939_xtp_rx_eoma_one()
1372 if (session->total_message_size != len) { in j1939_xtp_rx_eoma_one()
1373 netdev_warn_once(session->priv->ndev, in j1939_xtp_rx_eoma_one()
1375 __func__, session, session->total_message_size, in j1939_xtp_rx_eoma_one()
1379 netdev_dbg(session->priv->ndev, "%s: 0x%p\n", __func__, session); in j1939_xtp_rx_eoma_one()
1381 session->pkt.tx_acked = session->pkt.total; in j1939_xtp_rx_eoma_one()
1394 session = j1939_session_get_by_addr(priv, &skcb->addr, true, in j1939_xtp_rx_eoma()
1410 dat = skb->data; in j1939_xtp_rx_cts_one()
1415 netdev_dbg(session->priv->ndev, "%s: 0x%p\n", __func__, session); in j1939_xtp_rx_cts_one()
1417 if (session->last_cmd == dat[0]) { in j1939_xtp_rx_cts_one()
1422 if (session->skcb.addr.type == J1939_ETP) in j1939_xtp_rx_cts_one()
1429 else if (dat[1] > session->pkt.block /* 0xff for etp */) in j1939_xtp_rx_cts_one()
1433 session->pkt.tx_acked = pkt - 1; in j1939_xtp_rx_cts_one()
1435 session->pkt.last = session->pkt.tx_acked + dat[1]; in j1939_xtp_rx_cts_one()
1436 if (session->pkt.last > session->pkt.total) in j1939_xtp_rx_cts_one()
1438 session->pkt.last = session->pkt.total; in j1939_xtp_rx_cts_one()
1439 /* TODO: do not set tx here, do it in txtimer */ in j1939_xtp_rx_cts_one()
1440 session->pkt.tx = session->pkt.tx_acked; in j1939_xtp_rx_cts_one()
1442 session->last_cmd = dat[0]; in j1939_xtp_rx_cts_one()
1445 if (session->transmission) { in j1939_xtp_rx_cts_one()
1446 if (session->pkt.tx_acked) in j1939_xtp_rx_cts_one()
1469 session = j1939_session_get_by_addr(priv, &skcb->addr, true, in j1939_xtp_rx_cts()
1487 INIT_LIST_HEAD(&session->active_session_list_entry); in j1939_session_new()
1488 INIT_LIST_HEAD(&session->sk_session_queue_entry); in j1939_session_new()
1489 kref_init(&session->kref); in j1939_session_new()
1492 session->priv = priv; in j1939_session_new()
1493 session->total_message_size = size; in j1939_session_new()
1494 session->state = J1939_SESSION_NEW; in j1939_session_new()
1496 skb_queue_head_init(&session->skb_queue); in j1939_session_new()
1497 skb_queue_tail(&session->skb_queue, skb); in j1939_session_new()
1500 memcpy(&session->skcb, skcb, sizeof(session->skcb)); in j1939_session_new()
1502 hrtimer_init(&session->txtimer, CLOCK_MONOTONIC, in j1939_session_new()
1504 session->txtimer.function = j1939_tp_txtimer; in j1939_session_new()
1505 hrtimer_init(&session->rxtimer, CLOCK_MONOTONIC, in j1939_session_new()
1507 session->rxtimer.function = j1939_tp_rxtimer; in j1939_session_new()
1509 netdev_dbg(priv->ndev, "%s: 0x%p: sa: %02x, da: %02x\n", in j1939_session_new()
1510 __func__, session, skcb->addr.sa, skcb->addr.da); in j1939_session_new()
1528 skb->dev = priv->ndev; in j1939_session_fresh_new()
1530 can_skb_prv(skb)->ifindex = priv->ndev->ifindex; in j1939_session_fresh_new()
1531 can_skb_prv(skb)->skbcnt = 0; in j1939_session_fresh_new()
1549 struct j1939_priv *priv = session->priv; in j1939_session_activate()
1554 if (session->skcb.addr.type != J1939_SIMPLE) in j1939_session_activate()
1556 &priv->active_session_list, in j1939_session_activate()
1557 &session->skcb.addr, false, in j1939_session_activate()
1558 session->transmission); in j1939_session_activate()
1561 ret = -EAGAIN; in j1939_session_activate()
1563 WARN_ON_ONCE(session->state != J1939_SESSION_NEW); in j1939_session_activate()
1564 list_add_tail(&session->active_session_list_entry, in j1939_session_activate()
1565 &priv->active_session_list); in j1939_session_activate()
1567 session->state = J1939_SESSION_ACTIVE; in j1939_session_activate()
1569 netdev_dbg(session->priv->ndev, "%s: 0x%p\n", in j1939_session_activate()
1588 netdev_dbg(priv->ndev, "%s\n", __func__); in j1939_xtp_rx_rts_session_new()
1590 dat = skb->data; in j1939_xtp_rx_rts_session_new()
1601 else if (len > priv->tp_max_packet_size) in j1939_xtp_rx_rts_session_new()
1609 else if (len > priv->tp_max_packet_size) in j1939_xtp_rx_rts_session_new()
1628 session->pkt.total = (len + 6) / 7; in j1939_xtp_rx_rts_session_new()
1629 session->pkt.block = 0xff; in j1939_xtp_rx_rts_session_new()
1631 if (dat[3] != session->pkt.total) in j1939_xtp_rx_rts_session_new()
1632 netdev_alert(priv->ndev, "%s: 0x%p: strange total, %u != %u\n", in j1939_xtp_rx_rts_session_new()
1633 __func__, session, session->pkt.total, in j1939_xtp_rx_rts_session_new()
1635 session->pkt.total = dat[3]; in j1939_xtp_rx_rts_session_new()
1636 session->pkt.block = min(dat[3], dat[4]); in j1939_xtp_rx_rts_session_new()
1639 session->pkt.rx = 0; in j1939_xtp_rx_rts_session_new()
1640 session->pkt.tx = 0; in j1939_xtp_rx_rts_session_new()
1642 session->tskey = priv->rx_tskey++; in j1939_xtp_rx_rts_session_new()
1654 struct j1939_priv *priv = session->priv; in j1939_xtp_rx_rts_session_active()
1656 if (!session->transmission) { in j1939_xtp_rx_rts_session_active()
1658 return -EBUSY; in j1939_xtp_rx_rts_session_active()
1665 if (session->last_cmd != 0) { in j1939_xtp_rx_rts_session_active()
1667 netdev_alert(priv->ndev, "%s: 0x%p: connection exists (%02x %02x). last cmd: %x\n", in j1939_xtp_rx_rts_session_active()
1668 __func__, session, skcb->addr.sa, skcb->addr.da, in j1939_xtp_rx_rts_session_active()
1669 session->last_cmd); in j1939_xtp_rx_rts_session_active()
1674 return -EBUSY; in j1939_xtp_rx_rts_session_active()
1677 if (session->skcb.addr.sa != skcb->addr.sa || in j1939_xtp_rx_rts_session_active()
1678 session->skcb.addr.da != skcb->addr.da) in j1939_xtp_rx_rts_session_active()
1679 …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()
1681 session->skcb.addr.sa, skcb->addr.sa, in j1939_xtp_rx_rts_session_active()
1682 session->skcb.addr.da, skcb->addr.da); in j1939_xtp_rx_rts_session_active()
1687 session->skcb.addr.sa = skcb->addr.sa; in j1939_xtp_rx_rts_session_active()
1688 session->skcb.addr.da = skcb->addr.da; in j1939_xtp_rx_rts_session_active()
1690 netdev_dbg(session->priv->ndev, "%s: 0x%p\n", __func__, session); in j1939_xtp_rx_rts_session_active()
1700 u8 cmd = skb->data[0]; in j1939_xtp_rx_rts()
1702 session = j1939_session_get_by_addr(priv, &skcb->addr, false, in j1939_xtp_rx_rts()
1718 * - user space closed socket was and the session was in j1939_xtp_rx_rts()
1720 * - session was aborted due to external abort message in j1939_xtp_rx_rts()
1727 netdev_info(priv->ndev, "%s: failed to create TP BAM session\n", in j1939_xtp_rx_rts()
1737 session->last_cmd = cmd; in j1939_xtp_rx_rts()
1740 if (!session->transmission) in j1939_xtp_rx_rts()
1743 if (!session->transmission) { in j1939_xtp_rx_rts()
1756 const u8 *dat = skb->data; in j1939_xtp_rx_dpo_one()
1761 netdev_dbg(session->priv->ndev, "%s: 0x%p\n", __func__, session); in j1939_xtp_rx_dpo_one()
1764 session->pkt.dpo = j1939_etp_ctl_to_packet(skb->data); in j1939_xtp_rx_dpo_one()
1765 session->last_cmd = dat[0]; in j1939_xtp_rx_dpo_one()
1768 if (!session->transmission) in j1939_xtp_rx_dpo_one()
1778 session = j1939_session_get_by_addr(priv, &skcb->addr, false, in j1939_xtp_rx_dpo()
1781 netdev_info(priv->ndev, in j1939_xtp_rx_dpo()
1794 struct j1939_priv *priv = session->priv; in j1939_xtp_rx_dat_one()
1807 dat = skb->data; in j1939_xtp_rx_dat_one()
1808 if (skb->len != 8) { in j1939_xtp_rx_dat_one()
1814 switch (session->last_cmd) { in j1939_xtp_rx_dat_one()
1818 if (skcb->addr.type == J1939_ETP) in j1939_xtp_rx_dat_one()
1824 if (skcb->addr.type != J1939_ETP) in j1939_xtp_rx_dat_one()
1828 netdev_info(priv->ndev, "%s: 0x%p: last %02x\n", __func__, in j1939_xtp_rx_dat_one()
1829 session, session->last_cmd); in j1939_xtp_rx_dat_one()
1833 packet = (dat[0] - 1 + session->pkt.dpo); in j1939_xtp_rx_dat_one()
1834 if (packet > session->pkt.total || in j1939_xtp_rx_dat_one()
1835 (session->pkt.rx + 1) > session->pkt.total) { in j1939_xtp_rx_dat_one()
1836 netdev_info(priv->ndev, "%s: 0x%p: should have been completed\n", in j1939_xtp_rx_dat_one()
1843 netdev_warn(priv->ndev, "%s: 0x%p: no skb found\n", __func__, in j1939_xtp_rx_dat_one()
1849 offset = packet * 7 - se_skcb->offset; in j1939_xtp_rx_dat_one()
1850 nbytes = se_skb->len - offset; in j1939_xtp_rx_dat_one()
1853 if (nbytes <= 0 || (nbytes + 1) > skb->len) { in j1939_xtp_rx_dat_one()
1854 netdev_info(priv->ndev, "%s: 0x%p: nbytes %i, len %i\n", in j1939_xtp_rx_dat_one()
1855 __func__, session, nbytes, skb->len); in j1939_xtp_rx_dat_one()
1859 tpdat = se_skb->data; in j1939_xtp_rx_dat_one()
1860 if (!session->transmission) { in j1939_xtp_rx_dat_one()
1867 netdev_err_once(priv->ndev, in j1939_xtp_rx_dat_one()
1868 "%s: 0x%p: Data of RX-looped back packet (%*ph) doesn't match TX data (%*ph)!\n", in j1939_xtp_rx_dat_one()
1874 if (packet == session->pkt.rx) in j1939_xtp_rx_dat_one()
1875 session->pkt.rx++; in j1939_xtp_rx_dat_one()
1877 if (se_skcb->addr.type != J1939_ETP && in j1939_xtp_rx_dat_one()
1878 j1939_cb_is_broadcast(&session->skcb)) { in j1939_xtp_rx_dat_one()
1879 if (session->pkt.rx >= session->pkt.total) in j1939_xtp_rx_dat_one()
1885 if (session->pkt.rx >= session->pkt.last) in j1939_xtp_rx_dat_one()
1893 if (!session->transmission) in j1939_xtp_rx_dat_one()
1897 if (!session->transmission) in j1939_xtp_rx_dat_one()
1902 session->last_cmd = 0xff; in j1939_xtp_rx_dat_one()
1923 session = j1939_session_get_by_addr(priv, &skcb->addr, false, in j1939_xtp_rx_dat()
1926 netdev_info(priv->ndev, "%s: no tx connection found\n", in j1939_xtp_rx_dat()
1933 session = j1939_session_get_by_addr(priv, &skcb->addr, false, in j1939_xtp_rx_dat()
1936 netdev_info(priv->ndev, "%s: no rx connection found\n", in j1939_xtp_rx_dat()
1943 session = j1939_session_get_by_addr(priv, &skcb->addr, false, in j1939_xtp_rx_dat()
1958 if (skcb->addr.pgn == J1939_TP_PGN_DAT || in j1939_tp_send()
1959 skcb->addr.pgn == J1939_TP_PGN_CTL || in j1939_tp_send()
1960 skcb->addr.pgn == J1939_ETP_PGN_DAT || in j1939_tp_send()
1961 skcb->addr.pgn == J1939_ETP_PGN_CTL) in j1939_tp_send()
1963 return ERR_PTR(-EDOM); in j1939_tp_send()
1965 if (size > priv->tp_max_packet_size) in j1939_tp_send()
1966 return ERR_PTR(-EMSGSIZE); in j1939_tp_send()
1969 skcb->addr.type = J1939_SIMPLE; in j1939_tp_send()
1971 skcb->addr.type = J1939_ETP; in j1939_tp_send()
1973 skcb->addr.type = J1939_TP; in j1939_tp_send()
1975 if (skcb->addr.type == J1939_ETP && in j1939_tp_send()
1977 return ERR_PTR(-EDESTADDRREQ); in j1939_tp_send()
1985 if (j1939_address_is_unicast(skcb->addr.da) && in j1939_tp_send()
1986 priv->ents[skcb->addr.da].nusers) in j1939_tp_send()
1987 skcb->flags |= J1939_ECU_LOCAL_DST; in j1939_tp_send()
1990 skcb->flags |= J1939_ECU_LOCAL_SRC; in j1939_tp_send()
1995 return ERR_PTR(-ENOMEM); in j1939_tp_send()
1998 sock_hold(skb->sk); in j1939_tp_send()
1999 session->sk = skb->sk; in j1939_tp_send()
2000 session->transmission = true; in j1939_tp_send()
2001 session->pkt.total = (size + 6) / 7; in j1939_tp_send()
2002 session->pkt.block = skcb->addr.type == J1939_ETP ? 255 : in j1939_tp_send()
2003 min(j1939_tp_block ?: 255, session->pkt.total); in j1939_tp_send()
2005 if (j1939_cb_is_broadcast(&session->skcb)) in j1939_tp_send()
2006 /* set the end-packet for broadcast */ in j1939_tp_send()
2007 session->pkt.last = session->pkt.total; in j1939_tp_send()
2009 skcb->tskey = session->sk->sk_tskey++; in j1939_tp_send()
2010 session->tskey = skcb->tskey; in j1939_tp_send()
2019 u8 cmd = skb->data[0]; in j1939_tp_cmd_recv()
2028 if (skcb->addr.type != extd) in j1939_tp_cmd_recv()
2032 netdev_alert(priv->ndev, "%s: rts without destination (%02x)\n", in j1939_tp_cmd_recv()
2033 __func__, skcb->addr.sa); in j1939_tp_cmd_recv()
2049 if (skcb->addr.type != extd) in j1939_tp_cmd_recv()
2061 if (skcb->addr.type != J1939_ETP) in j1939_tp_cmd_recv()
2076 if (skcb->addr.type != extd) in j1939_tp_cmd_recv()
2107 switch (skcb->addr.pgn) { in j1939_tp_recv()
2109 skcb->addr.type = J1939_ETP; in j1939_tp_recv()
2116 skcb->addr.type = J1939_ETP; in j1939_tp_recv()
2119 if (skb->len < 8) in j1939_tp_recv()
2134 if (!skb->sk) in j1939_simple_recv()
2137 if (skb->sk->sk_family != AF_CAN || in j1939_simple_recv()
2138 skb->sk->sk_protocol != CAN_J1939) in j1939_simple_recv()
2145 netdev_warn(priv->ndev, in j1939_simple_recv()
2160 netdev_dbg(priv->ndev, "%s, sk: %p\n", __func__, sk); in j1939_cancel_active_session()
2163 &priv->active_session_list, in j1939_cancel_active_session()
2165 if (!sk || sk == session->sk) { in j1939_cancel_active_session()
2166 if (hrtimer_try_to_cancel(&session->txtimer) == 1) in j1939_cancel_active_session()
2168 if (hrtimer_try_to_cancel(&session->rxtimer) == 1) in j1939_cancel_active_session()
2171 session->err = ESHUTDOWN; in j1939_cancel_active_session()
2181 spin_lock_init(&priv->active_session_list_lock); in j1939_tp_init()
2182 INIT_LIST_HEAD(&priv->active_session_list); in j1939_tp_init()
2183 priv->tp_max_packet_size = J1939_MAX_ETP_PACKET_SIZE; in j1939_tp_init()