1 /********************************************************************* 2 * 3 * Filename: irlap.h 4 * Version: 0.8 5 * Description: An IrDA LAP driver for Linux 6 * Status: Experimental. 7 * Author: Dag Brattli <dagb@cs.uit.no> 8 * Created at: Mon Aug 4 20:40:53 1997 9 * Modified at: Fri Dec 10 13:21:17 1999 10 * Modified by: Dag Brattli <dagb@cs.uit.no> 11 * 12 * Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no>, 13 * All Rights Reserved. 14 * Copyright (c) 2000-2002 Jean Tourrilhes <jt@hpl.hp.com> 15 * 16 * This program is free software; you can redistribute it and/or 17 * modify it under the terms of the GNU General Public License as 18 * published by the Free Software Foundation; either version 2 of 19 * the License, or (at your option) any later version. 20 * 21 * Neither Dag Brattli nor University of Tromsø admit liability nor 22 * provide warranty for any of this software. This material is 23 * provided "AS-IS" and at no charge. 24 * 25 ********************************************************************/ 26 27 #ifndef IRLAP_H 28 #define IRLAP_H 29 30 #include <linux/types.h> 31 #include <linux/skbuff.h> 32 #include <linux/netdevice.h> 33 #include <linux/timer.h> 34 35 #include <net/irda/irqueue.h> /* irda_queue_t */ 36 #include <net/irda/qos.h> /* struct qos_info */ 37 #include <net/irda/discovery.h> /* discovery_t */ 38 #include <net/irda/irlap_event.h> /* IRLAP_STATE, ... */ 39 #include <net/irda/irmod.h> /* struct notify_t */ 40 41 #define CONFIG_IRDA_DYNAMIC_WINDOW 1 42 43 #define LAP_RELIABLE 1 44 #define LAP_UNRELIABLE 0 45 46 #define LAP_ADDR_HEADER 1 /* IrLAP Address Header */ 47 #define LAP_CTRL_HEADER 1 /* IrLAP Control Header */ 48 49 /* May be different when we get VFIR */ 50 #define LAP_MAX_HEADER (LAP_ADDR_HEADER + LAP_CTRL_HEADER) 51 52 /* Each IrDA device gets a random 32 bits IRLAP device address */ 53 #define LAP_ALEN 4 54 55 #define BROADCAST 0xffffffff /* Broadcast device address */ 56 #define CBROADCAST 0xfe /* Connection broadcast address */ 57 #define XID_FORMAT 0x01 /* Discovery XID format */ 58 59 /* Nobody seems to use this constant. */ 60 #define LAP_WINDOW_SIZE 8 61 /* We keep the LAP queue very small to minimise the amount of buffering. 62 * this improve latency and reduce resource consumption. 63 * This work only because we have synchronous refilling of IrLAP through 64 * the flow control mechanism (via scheduler and IrTTP). 65 * 2 buffers is the minimum we can work with, one that we send while polling 66 * IrTTP, and another to know that we should not send the pf bit. 67 * Jean II */ 68 #define LAP_HIGH_THRESHOLD 2 69 /* Some rare non TTP clients don't implement flow control, and 70 * so don't comply with the above limit (and neither with this one). 71 * For IAP and management, it doesn't matter, because they never transmit much. 72 *.For IrLPT, this should be fixed. 73 * - Jean II */ 74 #define LAP_MAX_QUEUE 10 75 /* Please note that all IrDA management frames (LMP/TTP conn req/disc and 76 * IAS queries) fall in the second category and are sent to LAP even if TTP 77 * is stopped. This means that those frames will wait only a maximum of 78 * two (2) data frames before beeing sent on the "wire", which speed up 79 * new socket setup when the link is saturated. 80 * Same story for two sockets competing for the medium : if one saturates 81 * the LAP, when the other want to transmit it only has to wait for 82 * maximum three (3) packets (2 + one scheduling), which improve performance 83 * of delay sensitive applications. 84 * Jean II */ 85 86 #define NR_EXPECTED 1 87 #define NR_UNEXPECTED 0 88 #define NR_INVALID -1 89 90 #define NS_EXPECTED 1 91 #define NS_UNEXPECTED 0 92 #define NS_INVALID -1 93 94 /* 95 * Meta information passed within the IrLAP state machine 96 */ 97 struct irlap_info { 98 __u8 caddr; /* Connection address */ 99 __u8 control; /* Frame type */ 100 __u8 cmd; 101 102 __u32 saddr; 103 __u32 daddr; 104 105 int pf; /* Poll/final bit set */ 106 107 __u8 nr; /* Sequence number of next frame expected */ 108 __u8 ns; /* Sequence number of frame sent */ 109 110 int S; /* Number of slots */ 111 int slot; /* Random chosen slot */ 112 int s; /* Current slot */ 113 114 discovery_t *discovery; /* Discovery information */ 115 }; 116 117 /* Main structure of IrLAP */ 118 struct irlap_cb { 119 irda_queue_t q; /* Must be first */ 120 magic_t magic; 121 122 /* Device we are attached to */ 123 struct net_device *netdev; 124 char hw_name[2*IFNAMSIZ + 1]; 125 126 /* Connection state */ 127 volatile IRLAP_STATE state; /* Current state */ 128 129 /* Timers used by IrLAP */ 130 struct timer_list query_timer; 131 struct timer_list slot_timer; 132 struct timer_list discovery_timer; 133 struct timer_list final_timer; 134 struct timer_list poll_timer; 135 struct timer_list wd_timer; 136 struct timer_list backoff_timer; 137 138 /* Media busy stuff */ 139 struct timer_list media_busy_timer; 140 int media_busy; 141 142 /* Timeouts which will be different with different turn time */ 143 int slot_timeout; 144 int poll_timeout; 145 int final_timeout; 146 int wd_timeout; 147 148 struct sk_buff_head txq; /* Frames to be transmitted */ 149 struct sk_buff_head txq_ultra; 150 151 __u8 caddr; /* Connection address */ 152 __u32 saddr; /* Source device address */ 153 __u32 daddr; /* Destination device address */ 154 155 int retry_count; /* Times tried to establish connection */ 156 int add_wait; /* True if we are waiting for frame */ 157 158 __u8 connect_pending; 159 __u8 disconnect_pending; 160 161 /* To send a faster RR if tx queue empty */ 162 #ifdef CONFIG_IRDA_FAST_RR 163 int fast_RR_timeout; 164 int fast_RR; 165 #endif /* CONFIG_IRDA_FAST_RR */ 166 167 int N1; /* N1 * F-timer = Negitiated link disconnect warning threshold */ 168 int N2; /* N2 * F-timer = Negitiated link disconnect time */ 169 int N3; /* Connection retry count */ 170 171 int local_busy; 172 int remote_busy; 173 int xmitflag; 174 175 __u8 vs; /* Next frame to be sent */ 176 __u8 vr; /* Next frame to be received */ 177 __u8 va; /* Last frame acked */ 178 int window; /* Nr of I-frames allowed to send */ 179 int window_size; /* Current negotiated window size */ 180 181 #ifdef CONFIG_IRDA_DYNAMIC_WINDOW 182 __u32 line_capacity; /* Number of bytes allowed to send */ 183 __u32 bytes_left; /* Number of bytes still allowed to transmit */ 184 #endif /* CONFIG_IRDA_DYNAMIC_WINDOW */ 185 186 struct sk_buff_head wx_list; 187 188 __u8 ack_required; 189 190 /* XID parameters */ 191 __u8 S; /* Number of slots */ 192 __u8 slot; /* Random chosen slot */ 193 __u8 s; /* Current slot */ 194 int frame_sent; /* Have we sent reply? */ 195 196 hashbin_t *discovery_log; 197 discovery_t *discovery_cmd; 198 199 __u32 speed; /* Link speed */ 200 201 struct qos_info qos_tx; /* QoS requested by peer */ 202 struct qos_info qos_rx; /* QoS requested by self */ 203 struct qos_info *qos_dev; /* QoS supported by device */ 204 205 notify_t notify; /* Callbacks to IrLMP */ 206 207 int mtt_required; /* Minimum turnaround time required */ 208 int xbofs_delay; /* Nr of XBOF's used to MTT */ 209 int bofs_count; /* Negotiated extra BOFs */ 210 int next_bofs; /* Negotiated extra BOFs after next frame */ 211 212 int mode; /* IrLAP mode (primary, secondary or monitor) */ 213 }; 214 215 /* 216 * Function prototypes 217 */ 218 int irlap_init(void); 219 void irlap_cleanup(void); 220 221 struct irlap_cb *irlap_open(struct net_device *dev, struct qos_info *qos, 222 const char *hw_name); 223 void irlap_close(struct irlap_cb *self); 224 225 void irlap_connect_request(struct irlap_cb *self, __u32 daddr, 226 struct qos_info *qos, int sniff); 227 void irlap_connect_response(struct irlap_cb *self, struct sk_buff *skb); 228 void irlap_connect_indication(struct irlap_cb *self, struct sk_buff *skb); 229 void irlap_connect_confirm(struct irlap_cb *, struct sk_buff *skb); 230 231 void irlap_data_indication(struct irlap_cb *, struct sk_buff *, int unreliable); 232 void irlap_data_request(struct irlap_cb *, struct sk_buff *, int unreliable); 233 234 #ifdef CONFIG_IRDA_ULTRA 235 void irlap_unitdata_request(struct irlap_cb *, struct sk_buff *); 236 void irlap_unitdata_indication(struct irlap_cb *, struct sk_buff *); 237 #endif /* CONFIG_IRDA_ULTRA */ 238 239 void irlap_disconnect_request(struct irlap_cb *); 240 void irlap_disconnect_indication(struct irlap_cb *, LAP_REASON reason); 241 242 void irlap_status_indication(struct irlap_cb *, int quality_of_link); 243 244 void irlap_test_request(__u8 *info, int len); 245 246 void irlap_discovery_request(struct irlap_cb *, discovery_t *discovery); 247 void irlap_discovery_confirm(struct irlap_cb *, hashbin_t *discovery_log); 248 void irlap_discovery_indication(struct irlap_cb *, discovery_t *discovery); 249 250 void irlap_reset_indication(struct irlap_cb *self); 251 void irlap_reset_confirm(void); 252 253 void irlap_update_nr_received(struct irlap_cb *, int nr); 254 int irlap_validate_nr_received(struct irlap_cb *, int nr); 255 int irlap_validate_ns_received(struct irlap_cb *, int ns); 256 257 int irlap_generate_rand_time_slot(int S, int s); 258 void irlap_initiate_connection_state(struct irlap_cb *); 259 void irlap_flush_all_queues(struct irlap_cb *); 260 void irlap_wait_min_turn_around(struct irlap_cb *, struct qos_info *); 261 262 void irlap_apply_default_connection_parameters(struct irlap_cb *self); 263 void irlap_apply_connection_parameters(struct irlap_cb *self, int now); 264 265 #define IRLAP_GET_HEADER_SIZE(self) (LAP_MAX_HEADER) 266 #define IRLAP_GET_TX_QUEUE_LEN(self) skb_queue_len(&self->txq) 267 268 /* Return TRUE if the node is in primary mode (i.e. master) 269 * - Jean II */ 270 static inline int irlap_is_primary(struct irlap_cb *self) 271 { 272 int ret; 273 switch(self->state) { 274 case LAP_XMIT_P: 275 case LAP_NRM_P: 276 ret = 1; 277 break; 278 case LAP_XMIT_S: 279 case LAP_NRM_S: 280 ret = 0; 281 break; 282 default: 283 ret = -1; 284 } 285 return ret; 286 } 287 288 /* Clear a pending IrLAP disconnect. - Jean II */ 289 static inline void irlap_clear_disconnect(struct irlap_cb *self) 290 { 291 self->disconnect_pending = FALSE; 292 } 293 294 /* 295 * Function irlap_next_state (self, state) 296 * 297 * Switches state and provides debug information 298 * 299 */ 300 static inline void irlap_next_state(struct irlap_cb *self, IRLAP_STATE state) 301 { 302 /* 303 if (!self || self->magic != LAP_MAGIC) 304 return; 305 306 pr_debug("next LAP state = %s\n", irlap_state[state]); 307 */ 308 self->state = state; 309 } 310 311 #endif 312
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.