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 */ 97struct 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 */ 118struct 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 */ 218int irlap_init(void); 219void irlap_cleanup(void); 220 221struct irlap_cb *irlap_open(struct net_device *dev, struct qos_info *qos, 222 const char *hw_name); 223void irlap_close(struct irlap_cb *self); 224 225void irlap_connect_request(struct irlap_cb *self, __u32 daddr, 226 struct qos_info *qos, int sniff); 227void irlap_connect_response(struct irlap_cb *self, struct sk_buff *skb); 228void irlap_connect_indication(struct irlap_cb *self, struct sk_buff *skb); 229void irlap_connect_confirm(struct irlap_cb *, struct sk_buff *skb); 230 231void irlap_data_indication(struct irlap_cb *, struct sk_buff *, int unreliable); 232void irlap_data_request(struct irlap_cb *, struct sk_buff *, int unreliable); 233 234#ifdef CONFIG_IRDA_ULTRA 235void irlap_unitdata_request(struct irlap_cb *, struct sk_buff *); 236void irlap_unitdata_indication(struct irlap_cb *, struct sk_buff *); 237#endif /* CONFIG_IRDA_ULTRA */ 238 239void irlap_disconnect_request(struct irlap_cb *); 240void irlap_disconnect_indication(struct irlap_cb *, LAP_REASON reason); 241 242void irlap_status_indication(struct irlap_cb *, int quality_of_link); 243 244void irlap_test_request(__u8 *info, int len); 245 246void irlap_discovery_request(struct irlap_cb *, discovery_t *discovery); 247void irlap_discovery_confirm(struct irlap_cb *, hashbin_t *discovery_log); 248void irlap_discovery_indication(struct irlap_cb *, discovery_t *discovery); 249 250void irlap_reset_indication(struct irlap_cb *self); 251void irlap_reset_confirm(void); 252 253void irlap_update_nr_received(struct irlap_cb *, int nr); 254int irlap_validate_nr_received(struct irlap_cb *, int nr); 255int irlap_validate_ns_received(struct irlap_cb *, int ns); 256 257int irlap_generate_rand_time_slot(int S, int s); 258void irlap_initiate_connection_state(struct irlap_cb *); 259void irlap_flush_all_queues(struct irlap_cb *); 260void irlap_wait_min_turn_around(struct irlap_cb *, struct qos_info *); 261 262void irlap_apply_default_connection_parameters(struct irlap_cb *self); 263void 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 */ 270static 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 */ 289static 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 */ 300static 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