linux/net/can/j1939/j1939-priv.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0 */
   2// Copyright (c) 2010-2011 EIA Electronics,
   3//                         Kurt Van Dijck <kurt.van.dijck@eia.be>
   4// Copyright (c) 2017-2019 Pengutronix,
   5//                         Marc Kleine-Budde <kernel@pengutronix.de>
   6// Copyright (c) 2017-2019 Pengutronix,
   7//                         Oleksij Rempel <kernel@pengutronix.de>
   8
   9#ifndef _J1939_PRIV_H_
  10#define _J1939_PRIV_H_
  11
  12#include <linux/can/j1939.h>
  13#include <net/sock.h>
  14
  15/* Timeout to receive the abort signal over loop back. In case CAN
  16 * bus is open, the timeout should be triggered.
  17 */
  18#define J1939_XTP_ABORT_TIMEOUT_MS 500
  19#define J1939_SIMPLE_ECHO_TIMEOUT_MS (10 * 1000)
  20
  21struct j1939_session;
  22enum j1939_sk_errqueue_type {
  23        J1939_ERRQUEUE_TX_ACK,
  24        J1939_ERRQUEUE_TX_SCHED,
  25        J1939_ERRQUEUE_TX_ABORT,
  26        J1939_ERRQUEUE_RX_RTS,
  27        J1939_ERRQUEUE_RX_DPO,
  28        J1939_ERRQUEUE_RX_ABORT,
  29};
  30
  31/* j1939 devices */
  32struct j1939_ecu {
  33        struct list_head list;
  34        name_t name;
  35        u8 addr;
  36
  37        /* indicates that this ecu successfully claimed @sa as its address */
  38        struct hrtimer ac_timer;
  39        struct kref kref;
  40        struct j1939_priv *priv;
  41
  42        /* count users, to help transport protocol decide for interaction */
  43        int nusers;
  44};
  45
  46struct j1939_priv {
  47        struct list_head ecus;
  48        /* local list entry in priv
  49         * These allow irq (& softirq) context lookups on j1939 devices
  50         * This approach (separate lists) is done as the other 2 alternatives
  51         * are not easier or even wrong
  52         * 1) using the pure kobject methods involves mutexes, which are not
  53         *    allowed in irq context.
  54         * 2) duplicating data structures would require a lot of synchronization
  55         *    code
  56         * usage:
  57         */
  58
  59        /* segments need a lock to protect the above list */
  60        rwlock_t lock;
  61
  62        struct net_device *ndev;
  63
  64        /* list of 256 ecu ptrs, that cache the claimed addresses.
  65         * also protected by the above lock
  66         */
  67        struct j1939_addr_ent {
  68                struct j1939_ecu *ecu;
  69                /* count users, to help transport protocol */
  70                int nusers;
  71        } ents[256];
  72
  73        struct kref kref;
  74
  75        /* List of active sessions to prevent start of conflicting
  76         * one.
  77         *
  78         * Do not start two sessions of same type, addresses and
  79         * direction.
  80         */
  81        struct list_head active_session_list;
  82
  83        /* protects active_session_list */
  84        spinlock_t active_session_list_lock;
  85
  86        unsigned int tp_max_packet_size;
  87
  88        /* lock for j1939_socks list */
  89        spinlock_t j1939_socks_lock;
  90        struct list_head j1939_socks;
  91
  92        struct kref rx_kref;
  93        u32 rx_tskey;
  94};
  95
  96void j1939_ecu_put(struct j1939_ecu *ecu);
  97
  98/* keep the cache of what is local */
  99int j1939_local_ecu_get(struct j1939_priv *priv, name_t name, u8 sa);
 100void j1939_local_ecu_put(struct j1939_priv *priv, name_t name, u8 sa);
 101
 102static inline bool j1939_address_is_unicast(u8 addr)
 103{
 104        return addr <= J1939_MAX_UNICAST_ADDR;
 105}
 106
 107static inline bool j1939_address_is_idle(u8 addr)
 108{
 109        return addr == J1939_IDLE_ADDR;
 110}
 111
 112static inline bool j1939_address_is_valid(u8 addr)
 113{
 114        return addr != J1939_NO_ADDR;
 115}
 116
 117static inline bool j1939_pgn_is_pdu1(pgn_t pgn)
 118{
 119        /* ignore dp & res bits for this */
 120        return (pgn & 0xff00) < 0xf000;
 121}
 122
 123/* utility to correctly unmap an ECU */
 124void j1939_ecu_unmap_locked(struct j1939_ecu *ecu);
 125void j1939_ecu_unmap(struct j1939_ecu *ecu);
 126
 127u8 j1939_name_to_addr(struct j1939_priv *priv, name_t name);
 128struct j1939_ecu *j1939_ecu_find_by_addr_locked(struct j1939_priv *priv,
 129                                                u8 addr);
 130struct j1939_ecu *j1939_ecu_get_by_addr(struct j1939_priv *priv, u8 addr);
 131struct j1939_ecu *j1939_ecu_get_by_addr_locked(struct j1939_priv *priv,
 132                                               u8 addr);
 133struct j1939_ecu *j1939_ecu_get_by_name(struct j1939_priv *priv, name_t name);
 134struct j1939_ecu *j1939_ecu_get_by_name_locked(struct j1939_priv *priv,
 135                                               name_t name);
 136
 137enum j1939_transfer_type {
 138        J1939_TP,
 139        J1939_ETP,
 140        J1939_SIMPLE,
 141};
 142
 143struct j1939_addr {
 144        name_t src_name;
 145        name_t dst_name;
 146        pgn_t pgn;
 147
 148        u8 sa;
 149        u8 da;
 150
 151        u8 type;
 152};
 153
 154/* control buffer of the sk_buff */
 155struct j1939_sk_buff_cb {
 156        /* Offset in bytes within one ETP session */
 157        u32 offset;
 158
 159        /* for tx, MSG_SYN will be used to sync on sockets */
 160        u32 msg_flags;
 161        u32 tskey;
 162
 163        struct j1939_addr addr;
 164
 165        /* Flags for quick lookups during skb processing.
 166         * These are set in the receive path only.
 167         */
 168#define J1939_ECU_LOCAL_SRC BIT(0)
 169#define J1939_ECU_LOCAL_DST BIT(1)
 170        u8 flags;
 171
 172        priority_t priority;
 173};
 174
 175static inline
 176struct j1939_sk_buff_cb *j1939_skb_to_cb(const struct sk_buff *skb)
 177{
 178        BUILD_BUG_ON(sizeof(struct j1939_sk_buff_cb) > sizeof(skb->cb));
 179
 180        return (struct j1939_sk_buff_cb *)skb->cb;
 181}
 182
 183int j1939_send_one(struct j1939_priv *priv, struct sk_buff *skb);
 184void j1939_sk_recv(struct j1939_priv *priv, struct sk_buff *skb);
 185bool j1939_sk_recv_match(struct j1939_priv *priv,
 186                         struct j1939_sk_buff_cb *skcb);
 187void j1939_sk_send_loop_abort(struct sock *sk, int err);
 188void j1939_sk_errqueue(struct j1939_session *session,
 189                       enum j1939_sk_errqueue_type type);
 190void j1939_sk_queue_activate_next(struct j1939_session *session);
 191
 192/* stack entries */
 193struct j1939_session *j1939_tp_send(struct j1939_priv *priv,
 194                                    struct sk_buff *skb, size_t size);
 195int j1939_tp_recv(struct j1939_priv *priv, struct sk_buff *skb);
 196int j1939_ac_fixup(struct j1939_priv *priv, struct sk_buff *skb);
 197void j1939_ac_recv(struct j1939_priv *priv, struct sk_buff *skb);
 198void j1939_simple_recv(struct j1939_priv *priv, struct sk_buff *skb);
 199
 200/* network management */
 201struct j1939_ecu *j1939_ecu_create_locked(struct j1939_priv *priv, name_t name);
 202
 203void j1939_ecu_timer_start(struct j1939_ecu *ecu);
 204void j1939_ecu_timer_cancel(struct j1939_ecu *ecu);
 205void j1939_ecu_unmap_all(struct j1939_priv *priv);
 206
 207struct j1939_priv *j1939_netdev_start(struct net_device *ndev);
 208void j1939_netdev_stop(struct j1939_priv *priv);
 209
 210void j1939_priv_put(struct j1939_priv *priv);
 211void j1939_priv_get(struct j1939_priv *priv);
 212
 213/* notify/alert all j1939 sockets bound to ifindex */
 214void j1939_sk_netdev_event_netdown(struct j1939_priv *priv);
 215int j1939_cancel_active_session(struct j1939_priv *priv, struct sock *sk);
 216void j1939_tp_init(struct j1939_priv *priv);
 217
 218/* decrement pending skb for a j1939 socket */
 219void j1939_sock_pending_del(struct sock *sk);
 220
 221enum j1939_session_state {
 222        J1939_SESSION_NEW,
 223        J1939_SESSION_ACTIVE,
 224        /* waiting for abort signal on the bus */
 225        J1939_SESSION_WAITING_ABORT,
 226        J1939_SESSION_ACTIVE_MAX,
 227        J1939_SESSION_DONE,
 228};
 229
 230struct j1939_session {
 231        struct j1939_priv *priv;
 232        struct list_head active_session_list_entry;
 233        struct list_head sk_session_queue_entry;
 234        struct kref kref;
 235        struct sock *sk;
 236
 237        /* ifindex, src, dst, pgn define the session block
 238         * the are _never_ modified after insertion in the list
 239         * this decreases locking problems a _lot_
 240         */
 241        struct j1939_sk_buff_cb skcb;
 242        struct sk_buff_head skb_queue;
 243
 244        /* all tx related stuff (last_txcmd, pkt.tx)
 245         * is protected (modified only) with the txtimer hrtimer
 246         * 'total' & 'block' are never changed,
 247         * last_cmd, last & block are protected by ->lock
 248         * this means that the tx may run after cts is received that should
 249         * have stopped tx, but this time discrepancy is never avoided anyhow
 250         */
 251        u8 last_cmd, last_txcmd;
 252        bool transmission;
 253        bool extd;
 254        /* Total message size, number of bytes */
 255        unsigned int total_message_size;
 256        /* Total number of bytes queue from socket to the session */
 257        unsigned int total_queued_size;
 258        unsigned int tx_retry;
 259
 260        int err;
 261        u32 tskey;
 262        enum j1939_session_state state;
 263
 264        /* Packets counters for a (extended) transfer session. The packet is
 265         * maximal of 7 bytes.
 266         */
 267        struct {
 268                /* total - total number of packets for this session */
 269                unsigned int total;
 270                /* last - last packet of a transfer block after which
 271                 * responder should send ETP.CM_CTS and originator
 272                 * ETP.CM_DPO
 273                 */
 274                unsigned int last;
 275                /* tx - number of packets send by originator node.
 276                 * this counter can be set back if responder node
 277                 * didn't received all packets send by originator.
 278                 */
 279                unsigned int tx;
 280                unsigned int tx_acked;
 281                /* rx - number of packets received */
 282                unsigned int rx;
 283                /* block - amount of packets expected in one block */
 284                unsigned int block;
 285                /* dpo - ETP.CM_DPO, Data Packet Offset */
 286                unsigned int dpo;
 287        } pkt;
 288        struct hrtimer txtimer, rxtimer;
 289};
 290
 291struct j1939_sock {
 292        struct sock sk; /* must be first to skip with memset */
 293        struct j1939_priv *priv;
 294        struct list_head list;
 295
 296#define J1939_SOCK_BOUND BIT(0)
 297#define J1939_SOCK_CONNECTED BIT(1)
 298#define J1939_SOCK_PROMISC BIT(2)
 299#define J1939_SOCK_ERRQUEUE BIT(3)
 300        int state;
 301
 302        int ifindex;
 303        struct j1939_addr addr;
 304        struct j1939_filter *filters;
 305        int nfilters;
 306        pgn_t pgn_rx_filter;
 307
 308        /* j1939 may emit equal PGN (!= equal CAN-id's) out of order
 309         * when transport protocol comes in.
 310         * To allow emitting in order, keep a 'pending' nr. of packets
 311         */
 312        atomic_t skb_pending;
 313        wait_queue_head_t waitq;
 314
 315        /* lock for the sk_session_queue list */
 316        spinlock_t sk_session_queue_lock;
 317        struct list_head sk_session_queue;
 318};
 319
 320static inline struct j1939_sock *j1939_sk(const struct sock *sk)
 321{
 322        return container_of(sk, struct j1939_sock, sk);
 323}
 324
 325void j1939_session_get(struct j1939_session *session);
 326void j1939_session_put(struct j1939_session *session);
 327void j1939_session_skb_queue(struct j1939_session *session,
 328                             struct sk_buff *skb);
 329int j1939_session_activate(struct j1939_session *session);
 330void j1939_tp_schedule_txtimer(struct j1939_session *session, int msec);
 331void j1939_session_timers_cancel(struct j1939_session *session);
 332
 333#define J1939_MIN_TP_PACKET_SIZE 9
 334#define J1939_MAX_TP_PACKET_SIZE (7 * 0xff)
 335#define J1939_MAX_ETP_PACKET_SIZE (7 * 0x00ffffff)
 336
 337#define J1939_REGULAR 0
 338#define J1939_EXTENDED 1
 339
 340/* CAN protocol */
 341extern const struct can_proto j1939_can_proto;
 342
 343#endif /* _J1939_PRIV_H_ */
 344