1/*********************************************************************
2 *
3 *	sir.h:	include file for irda-sir device abstraction layer
4 *
5 *	Copyright (c) 2002 Martin Diehl
6 *
7 *	This program is free software; you can redistribute it and/or
8 *	modify it under the terms of the GNU General Public License as
9 *	published by the Free Software Foundation; either version 2 of
10 *	the License, or (at your option) any later version.
11 *
12 ********************************************************************/
13
14#ifndef IRDA_SIR_H
15#define IRDA_SIR_H
16
17#include <linux/netdevice.h>
18#include <linux/workqueue.h>
19
20#include <net/irda/irda.h>
21#include <net/irda/irda_device.h>		// iobuff_t
22
23struct sir_fsm {
24	struct semaphore	sem;
25	struct delayed_work	work;
26	unsigned		state, substate;
27	int			param;
28	int			result;
29};
30
31#define SIRDEV_STATE_WAIT_TX_COMPLETE	0x0100
32
33/* substates for wait_tx_complete */
34#define SIRDEV_STATE_WAIT_XMIT		0x0101
35#define SIRDEV_STATE_WAIT_UNTIL_SENT	0x0102
36#define SIRDEV_STATE_TX_DONE		0x0103
37
38#define SIRDEV_STATE_DONGLE_OPEN		0x0300
39
40/* 0x0301-0x03ff reserved for individual dongle substates */
41
42#define SIRDEV_STATE_DONGLE_CLOSE	0x0400
43
44/* 0x0401-0x04ff reserved for individual dongle substates */
45
46#define SIRDEV_STATE_SET_DTR_RTS		0x0500
47
48#define SIRDEV_STATE_SET_SPEED		0x0700
49#define SIRDEV_STATE_DONGLE_CHECK	0x0800
50#define SIRDEV_STATE_DONGLE_RESET	0x0900
51
52/* 0x0901-0x09ff reserved for individual dongle substates */
53
54#define SIRDEV_STATE_DONGLE_SPEED	0x0a00
55/* 0x0a01-0x0aff reserved for individual dongle substates */
56
57#define SIRDEV_STATE_PORT_SPEED		0x0b00
58#define SIRDEV_STATE_DONE		0x0c00
59#define SIRDEV_STATE_ERROR		0x0d00
60#define SIRDEV_STATE_COMPLETE		0x0e00
61
62#define SIRDEV_STATE_DEAD		0xffff
63
64
65struct sir_dev;
66
67struct dongle_driver {
68
69	struct module *owner;
70
71	const char *driver_name;
72
73	IRDA_DONGLE type;
74
75	int	(*open)(struct sir_dev *dev);
76	int	(*close)(struct sir_dev *dev);
77	int	(*reset)(struct sir_dev *dev);
78	int	(*set_speed)(struct sir_dev *dev, unsigned speed);
79
80	struct list_head dongle_list;
81};
82
83struct sir_driver {
84
85	struct module *owner;
86
87	const char *driver_name;
88
89	int qos_mtt_bits;
90
91	int (*chars_in_buffer)(struct sir_dev *dev);
92	void (*wait_until_sent)(struct sir_dev *dev);
93	int (*set_speed)(struct sir_dev *dev, unsigned speed);
94	int (*set_dtr_rts)(struct sir_dev *dev, int dtr, int rts);
95
96	int (*do_write)(struct sir_dev *dev, const unsigned char *ptr, size_t len);
97
98	int (*start_dev)(struct sir_dev *dev);
99	int (*stop_dev)(struct sir_dev *dev);
100};
101
102
103/* exported */
104
105int irda_register_dongle(struct dongle_driver *new);
106int irda_unregister_dongle(struct dongle_driver *drv);
107
108struct sir_dev *sirdev_get_instance(const struct sir_driver *drv,
109				    const char *name);
110int sirdev_put_instance(struct sir_dev *self);
111
112int sirdev_set_dongle(struct sir_dev *dev, IRDA_DONGLE type);
113void sirdev_write_complete(struct sir_dev *dev);
114int sirdev_receive(struct sir_dev *dev, const unsigned char *cp, size_t count);
115
116/* low level helpers for SIR device/dongle setup */
117int sirdev_raw_write(struct sir_dev *dev, const char *buf, int len);
118int sirdev_raw_read(struct sir_dev *dev, char *buf, int len);
119int sirdev_set_dtr_rts(struct sir_dev *dev, int dtr, int rts);
120
121/* not exported */
122
123int sirdev_get_dongle(struct sir_dev *self, IRDA_DONGLE type);
124int sirdev_put_dongle(struct sir_dev *self);
125
126void sirdev_enable_rx(struct sir_dev *dev);
127int sirdev_schedule_request(struct sir_dev *dev, int state, unsigned param);
128
129/* inline helpers */
130
131static inline int sirdev_schedule_speed(struct sir_dev *dev, unsigned speed)
132{
133	return sirdev_schedule_request(dev, SIRDEV_STATE_SET_SPEED, speed);
134}
135
136static inline int sirdev_schedule_dongle_open(struct sir_dev *dev, int dongle_id)
137{
138	return sirdev_schedule_request(dev, SIRDEV_STATE_DONGLE_OPEN, dongle_id);
139}
140
141static inline int sirdev_schedule_dongle_close(struct sir_dev *dev)
142{
143	return sirdev_schedule_request(dev, SIRDEV_STATE_DONGLE_CLOSE, 0);
144}
145
146static inline int sirdev_schedule_dtr_rts(struct sir_dev *dev, int dtr, int rts)
147{
148	int	dtrrts;
149
150	dtrrts = ((dtr) ? 0x02 : 0x00) | ((rts) ? 0x01 : 0x00);
151	return sirdev_schedule_request(dev, SIRDEV_STATE_SET_DTR_RTS, dtrrts);
152}
153
154#if 0
155static inline int sirdev_schedule_mode(struct sir_dev *dev, int mode)
156{
157	return sirdev_schedule_request(dev, SIRDEV_STATE_SET_MODE, mode);
158}
159#endif
160
161
162struct sir_dev {
163	struct net_device *netdev;
164
165	struct irlap_cb    *irlap;
166
167	struct qos_info qos;
168
169	char hwname[32];
170
171	struct sir_fsm fsm;
172	atomic_t enable_rx;
173	int raw_tx;
174	spinlock_t tx_lock;
175
176	u32 new_speed;
177 	u32 flags;
178
179	unsigned	speed;
180
181	iobuff_t tx_buff;          /* Transmit buffer */
182	iobuff_t rx_buff;          /* Receive buffer */
183	struct sk_buff *tx_skb;
184
185	const struct dongle_driver * dongle_drv;
186	const struct sir_driver * drv;
187	void *priv;
188
189};
190
191#endif	/* IRDA_SIR_H */
192