Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/net/can/j1939/j1939-priv.h
26288 views
1
/* SPDX-License-Identifier: GPL-2.0 */
2
// Copyright (c) 2010-2011 EIA Electronics,
3
// Kurt Van Dijck <[email protected]>
4
// Copyright (c) 2017-2019 Pengutronix,
5
// Marc Kleine-Budde <[email protected]>
6
// Copyright (c) 2017-2019 Pengutronix,
7
// Oleksij Rempel <[email protected]>
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
21
struct j1939_session;
22
enum 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 */
32
struct 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
46
struct 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
rwlock_t j1939_socks_lock;
90
struct list_head j1939_socks;
91
92
struct kref rx_kref;
93
u32 rx_tskey;
94
};
95
96
void j1939_ecu_put(struct j1939_ecu *ecu);
97
98
/* keep the cache of what is local */
99
int j1939_local_ecu_get(struct j1939_priv *priv, name_t name, u8 sa);
100
void j1939_local_ecu_put(struct j1939_priv *priv, name_t name, u8 sa);
101
102
static inline bool j1939_address_is_unicast(u8 addr)
103
{
104
return addr <= J1939_MAX_UNICAST_ADDR;
105
}
106
107
static inline bool j1939_address_is_idle(u8 addr)
108
{
109
return addr == J1939_IDLE_ADDR;
110
}
111
112
static inline bool j1939_address_is_valid(u8 addr)
113
{
114
return addr != J1939_NO_ADDR;
115
}
116
117
static 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 */
124
void j1939_ecu_unmap_locked(struct j1939_ecu *ecu);
125
void j1939_ecu_unmap(struct j1939_ecu *ecu);
126
127
u8 j1939_name_to_addr(struct j1939_priv *priv, name_t name);
128
struct j1939_ecu *j1939_ecu_find_by_addr_locked(struct j1939_priv *priv,
129
u8 addr);
130
struct j1939_ecu *j1939_ecu_get_by_addr(struct j1939_priv *priv, u8 addr);
131
struct j1939_ecu *j1939_ecu_get_by_addr_locked(struct j1939_priv *priv,
132
u8 addr);
133
struct j1939_ecu *j1939_ecu_get_by_name(struct j1939_priv *priv, name_t name);
134
struct j1939_ecu *j1939_ecu_get_by_name_locked(struct j1939_priv *priv,
135
name_t name);
136
137
enum j1939_transfer_type {
138
J1939_TP,
139
J1939_ETP,
140
J1939_SIMPLE,
141
};
142
143
struct 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 */
155
struct 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
175
static inline
176
struct 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
183
int j1939_send_one(struct j1939_priv *priv, struct sk_buff *skb);
184
void j1939_sk_recv(struct j1939_priv *priv, struct sk_buff *skb);
185
bool j1939_sk_recv_match(struct j1939_priv *priv,
186
struct j1939_sk_buff_cb *skcb);
187
void j1939_sk_send_loop_abort(struct sock *sk, int err);
188
void j1939_sk_errqueue(struct j1939_session *session,
189
enum j1939_sk_errqueue_type type);
190
void j1939_sk_queue_activate_next(struct j1939_session *session);
191
192
/* stack entries */
193
struct j1939_session *j1939_tp_send(struct j1939_priv *priv,
194
struct sk_buff *skb, size_t size);
195
int j1939_tp_recv(struct j1939_priv *priv, struct sk_buff *skb);
196
int j1939_ac_fixup(struct j1939_priv *priv, struct sk_buff *skb);
197
void j1939_ac_recv(struct j1939_priv *priv, struct sk_buff *skb);
198
void j1939_simple_recv(struct j1939_priv *priv, struct sk_buff *skb);
199
200
/* network management */
201
struct j1939_ecu *j1939_ecu_create_locked(struct j1939_priv *priv, name_t name);
202
203
void j1939_ecu_timer_start(struct j1939_ecu *ecu);
204
void j1939_ecu_timer_cancel(struct j1939_ecu *ecu);
205
void j1939_ecu_unmap_all(struct j1939_priv *priv);
206
207
struct j1939_priv *j1939_netdev_start(struct net_device *ndev);
208
void j1939_netdev_stop(struct j1939_priv *priv);
209
210
void j1939_priv_put(struct j1939_priv *priv);
211
void j1939_priv_get(struct j1939_priv *priv);
212
213
/* notify/alert all j1939 sockets bound to ifindex */
214
void j1939_sk_netdev_event_netdown(struct j1939_priv *priv);
215
int j1939_cancel_active_session(struct j1939_priv *priv, struct sock *sk);
216
void j1939_tp_init(struct j1939_priv *priv);
217
218
/* decrement pending skb for a j1939 socket */
219
void j1939_sock_pending_del(struct sock *sk);
220
221
enum 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
230
struct 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
291
struct 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
spinlock_t filters_lock;
305
struct j1939_filter *filters;
306
int nfilters;
307
pgn_t pgn_rx_filter;
308
309
/* j1939 may emit equal PGN (!= equal CAN-id's) out of order
310
* when transport protocol comes in.
311
* To allow emitting in order, keep a 'pending' nr. of packets
312
*/
313
atomic_t skb_pending;
314
wait_queue_head_t waitq;
315
316
/* lock for the sk_session_queue list */
317
spinlock_t sk_session_queue_lock;
318
struct list_head sk_session_queue;
319
};
320
321
static inline struct j1939_sock *j1939_sk(const struct sock *sk)
322
{
323
return container_of(sk, struct j1939_sock, sk);
324
}
325
326
void j1939_session_get(struct j1939_session *session);
327
void j1939_session_put(struct j1939_session *session);
328
void j1939_session_skb_queue(struct j1939_session *session,
329
struct sk_buff *skb);
330
int j1939_session_activate(struct j1939_session *session);
331
void j1939_tp_schedule_txtimer(struct j1939_session *session, int msec);
332
void j1939_session_timers_cancel(struct j1939_session *session);
333
334
#define J1939_MIN_TP_PACKET_SIZE 9
335
#define J1939_MAX_TP_PACKET_SIZE (7 * 0xff)
336
#define J1939_MAX_ETP_PACKET_SIZE (7 * 0x00ffffff)
337
338
#define J1939_REGULAR 0
339
#define J1939_EXTENDED 1
340
341
/* CAN protocol */
342
extern const struct can_proto j1939_can_proto;
343
344
#endif /* _J1939_PRIV_H_ */
345
346