Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1 | /********************************************************************* |
| 2 | * |
| 3 | * Filename: irttp.h |
| 4 | * Version: 1.0 |
| 5 | * Description: Tiny Transport Protocol (TTP) definitions |
| 6 | * Status: Experimental. |
| 7 | * Author: Dag Brattli <dagb@cs.uit.no> |
| 8 | * Created at: Sun Aug 31 20:14:31 1997 |
| 9 | * Modified at: Sun Dec 12 13:09:07 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 IRTTP_H |
| 28 | #define IRTTP_H |
| 29 | |
| 30 | #include <linux/types.h> |
| 31 | #include <linux/skbuff.h> |
| 32 | #include <linux/spinlock.h> |
| 33 | |
| 34 | #include <net/irda/irda.h> |
| 35 | #include <net/irda/irlmp.h> /* struct lsap_cb */ |
| 36 | #include <net/irda/qos.h> /* struct qos_info */ |
| 37 | #include <net/irda/irqueue.h> |
| 38 | |
| 39 | #define TTP_MAX_CONNECTIONS LM_MAX_CONNECTIONS |
| 40 | #define TTP_HEADER 1 |
| 41 | #define TTP_MAX_HEADER (TTP_HEADER + LMP_MAX_HEADER) |
| 42 | #define TTP_SAR_HEADER 5 |
| 43 | #define TTP_PARAMETERS 0x80 |
| 44 | #define TTP_MORE 0x80 |
| 45 | |
| 46 | /* Transmission queue sizes */ |
| 47 | /* Worst case scenario, two window of data - Jean II */ |
| 48 | #define TTP_TX_MAX_QUEUE 14 |
| 49 | /* We need to keep at least 5 frames to make sure that we can refill |
| 50 | * appropriately the LAP layer. LAP keeps only two buffers, and we need |
| 51 | * to have 7 to make a full window - Jean II */ |
| 52 | #define TTP_TX_LOW_THRESHOLD 5 |
| 53 | /* Most clients are synchronous with respect to flow control, so we can |
| 54 | * keep a low number of Tx buffers in TTP - Jean II */ |
| 55 | #define TTP_TX_HIGH_THRESHOLD 7 |
| 56 | |
| 57 | /* Receive queue sizes */ |
| 58 | /* Minimum of credit that the peer should hold. |
| 59 | * If the peer has less credits than 9 frames, we will explicitely send |
| 60 | * him some credits (through irttp_give_credit() and a specific frame). |
| 61 | * Note that when we give credits it's likely that it won't be sent in |
| 62 | * this LAP window, but in the next one. So, we make sure that the peer |
| 63 | * has something to send while waiting for credits (one LAP window == 7 |
| 64 | * + 1 frames while he process the credits). - Jean II */ |
| 65 | #define TTP_RX_MIN_CREDIT 8 |
| 66 | /* This is the default maximum number of credits held by the peer, so the |
| 67 | * default maximum number of frames he can send us before needing flow |
| 68 | * control answer from us (this may be negociated differently at TSAP setup). |
| 69 | * We want to minimise the number of times we have to explicitely send some |
| 70 | * credit to the peer, hoping we can piggyback it on the return data. In |
| 71 | * particular, it doesn't make sense for us to send credit more than once |
| 72 | * per LAP window. |
| 73 | * Moreover, giving credits has some latency, so we need strictly more than |
| 74 | * a LAP window, otherwise we may already have credits in our Tx queue. |
| 75 | * But on the other hand, we don't want to keep too many Rx buffer here |
| 76 | * before starting to flow control the other end, so make it exactly one |
| 77 | * LAP window + 1 + MIN_CREDITS. - Jean II */ |
| 78 | #define TTP_RX_DEFAULT_CREDIT 16 |
| 79 | /* Maximum number of credits we can allow the peer to have, and therefore |
| 80 | * maximum Rx queue size. |
| 81 | * Note that we try to deliver packets to the higher layer every time we |
| 82 | * receive something, so in normal mode the Rx queue will never contains |
| 83 | * more than one or two packets. - Jean II */ |
| 84 | #define TTP_RX_MAX_CREDIT 21 |
| 85 | |
| 86 | /* What clients should use when calling ttp_open_tsap() */ |
| 87 | #define DEFAULT_INITIAL_CREDIT TTP_RX_DEFAULT_CREDIT |
| 88 | |
| 89 | /* Some priorities for disconnect requests */ |
| 90 | #define P_NORMAL 0 |
| 91 | #define P_HIGH 1 |
| 92 | |
| 93 | #define TTP_SAR_DISABLE 0 |
| 94 | #define TTP_SAR_UNBOUND 0xffffffff |
| 95 | |
| 96 | /* Parameters */ |
| 97 | #define TTP_MAX_SDU_SIZE 0x01 |
| 98 | |
| 99 | /* |
| 100 | * This structure contains all data assosiated with one instance of a TTP |
| 101 | * connection. |
| 102 | */ |
| 103 | struct tsap_cb { |
| 104 | irda_queue_t q; /* Must be first */ |
| 105 | magic_t magic; /* Just in case */ |
| 106 | |
| 107 | __u8 stsap_sel; /* Source TSAP */ |
| 108 | __u8 dtsap_sel; /* Destination TSAP */ |
| 109 | |
| 110 | struct lsap_cb *lsap; /* Corresponding LSAP to this TSAP */ |
| 111 | |
| 112 | __u8 connected; /* TSAP connected */ |
| 113 | |
| 114 | __u8 initial_credit; /* Initial credit to give peer */ |
| 115 | |
| 116 | int avail_credit; /* Available credit to return to peer */ |
| 117 | int remote_credit; /* Credit held by peer TTP entity */ |
| 118 | int send_credit; /* Credit held by local TTP entity */ |
| 119 | |
| 120 | struct sk_buff_head tx_queue; /* Frames to be transmitted */ |
| 121 | struct sk_buff_head rx_queue; /* Received frames */ |
| 122 | struct sk_buff_head rx_fragments; |
| 123 | int tx_queue_lock; |
| 124 | int rx_queue_lock; |
| 125 | spinlock_t lock; |
| 126 | |
| 127 | notify_t notify; /* Callbacks to client layer */ |
| 128 | |
| 129 | struct net_device_stats stats; |
| 130 | struct timer_list todo_timer; |
| 131 | |
| 132 | __u32 max_seg_size; /* Max data that fit into an IrLAP frame */ |
| 133 | __u8 max_header_size; |
| 134 | |
| 135 | int rx_sdu_busy; /* RxSdu.busy */ |
| 136 | __u32 rx_sdu_size; /* Current size of a partially received frame */ |
| 137 | __u32 rx_max_sdu_size; /* Max receive user data size */ |
| 138 | |
| 139 | int tx_sdu_busy; /* TxSdu.busy */ |
| 140 | __u32 tx_max_sdu_size; /* Max transmit user data size */ |
| 141 | |
| 142 | int close_pend; /* Close, but disconnect_pend */ |
| 143 | unsigned long disconnect_pend; /* Disconnect, but still data to send */ |
| 144 | struct sk_buff *disconnect_skb; |
| 145 | }; |
| 146 | |
| 147 | struct irttp_cb { |
| 148 | magic_t magic; |
| 149 | hashbin_t *tsaps; |
| 150 | }; |
| 151 | |
| 152 | int irttp_init(void); |
| 153 | void irttp_cleanup(void); |
| 154 | |
| 155 | struct tsap_cb *irttp_open_tsap(__u8 stsap_sel, int credit, notify_t *notify); |
| 156 | int irttp_close_tsap(struct tsap_cb *self); |
| 157 | |
| 158 | int irttp_data_request(struct tsap_cb *self, struct sk_buff *skb); |
| 159 | int irttp_udata_request(struct tsap_cb *self, struct sk_buff *skb); |
| 160 | |
| 161 | int irttp_connect_request(struct tsap_cb *self, __u8 dtsap_sel, |
| 162 | __u32 saddr, __u32 daddr, |
| 163 | struct qos_info *qos, __u32 max_sdu_size, |
| 164 | struct sk_buff *userdata); |
| 165 | int irttp_connect_response(struct tsap_cb *self, __u32 max_sdu_size, |
| 166 | struct sk_buff *userdata); |
| 167 | int irttp_disconnect_request(struct tsap_cb *self, struct sk_buff *skb, |
| 168 | int priority); |
| 169 | void irttp_flow_request(struct tsap_cb *self, LOCAL_FLOW flow); |
| 170 | struct tsap_cb *irttp_dup(struct tsap_cb *self, void *instance); |
| 171 | |
| 172 | static __inline __u32 irttp_get_saddr(struct tsap_cb *self) |
| 173 | { |
| 174 | return irlmp_get_saddr(self->lsap); |
| 175 | } |
| 176 | |
| 177 | static __inline __u32 irttp_get_daddr(struct tsap_cb *self) |
| 178 | { |
| 179 | return irlmp_get_daddr(self->lsap); |
| 180 | } |
| 181 | |
| 182 | static __inline __u32 irttp_get_max_seg_size(struct tsap_cb *self) |
| 183 | { |
| 184 | return self->max_seg_size; |
| 185 | } |
| 186 | |
| 187 | /* After doing a irttp_dup(), this get one of the two socket back into |
| 188 | * a state where it's waiting incomming connections. |
| 189 | * Note : this can be used *only* if the socket is not yet connected |
| 190 | * (i.e. NO irttp_connect_response() done on this socket). |
| 191 | * - Jean II */ |
| 192 | static inline void irttp_listen(struct tsap_cb *self) |
| 193 | { |
| 194 | irlmp_listen(self->lsap); |
| 195 | self->dtsap_sel = LSAP_ANY; |
| 196 | } |
| 197 | |
| 198 | /* Return TRUE if the node is in primary mode (i.e. master) |
| 199 | * - Jean II */ |
| 200 | static inline int irttp_is_primary(struct tsap_cb *self) |
| 201 | { |
| 202 | if ((self == NULL) || |
| 203 | (self->lsap == NULL) || |
| 204 | (self->lsap->lap == NULL) || |
| 205 | (self->lsap->lap->irlap == NULL)) |
| 206 | return -2; |
| 207 | return(irlap_is_primary(self->lsap->lap->irlap)); |
| 208 | } |
| 209 | |
| 210 | #endif /* IRTTP_H */ |