32 #include <linux/slab.h>
33 #include <linux/string.h>
38 #include <linux/random.h>
39 #include <linux/module.h>
61 static void __irlap_close(
struct irlap_cb *
self);
62 static void irlap_init_qos_capabilities(
struct irlap_cb *
self,
65 #ifdef CONFIG_IRDA_DEBUG
66 static const char *
const lap_reasons[] = {
68 "LAP_DISC_INDICATION",
70 "LAP_RESET_INDICATION",
73 "LAP_PRIMARY_CONFLICT",
90 IRDA_ERROR(
"%s: can't allocate irlap hashbin!\n",
129 if(hw_name !=
NULL) {
130 strlcpy(self->hw_name, hw_name,
sizeof(self->hw_name));
132 self->hw_name[0] =
'\0';
141 skb_queue_head_init(&self->txq);
142 skb_queue_head_init(&self->txq_ultra);
143 skb_queue_head_init(&self->wx_list);
152 }
while ((self->saddr == 0x0) || (self->saddr ==
BROADCAST) ||
186 static void __irlap_close(
struct irlap_cb *
self)
229 self->notify.instance =
NULL;
234 IRDA_DEBUG(1,
"%s(), Didn't find myself!\n", __func__);
254 irlap_init_qos_capabilities(
self,
NULL);
257 self->daddr, &self->qos_tx, skb);
281 struct qos_info *qos_user,
int sniff)
283 IRDA_DEBUG(3,
"%s(), daddr=0x%08x\n", __func__, daddr);
294 irlap_init_qos_capabilities(
self, qos_user);
296 if ((self->state ==
LAP_NDM) && !self->media_busy)
299 self->connect_pending =
TRUE;
375 if((skb_queue_len(&self->txq) <= 1) && (!self->local_busy))
388 #ifdef CONFIG_IRDA_ULTRA
417 #ifdef CONFIG_IRDA_ULTRA
418 void irlap_unitdata_indication(
struct irlap_cb *
self,
struct sk_buff *skb)
429 irlmp_link_unitdata_indication(self->notify.instance, skb);
446 if (!skb_queue_empty(&self->txq)) {
447 self->disconnect_pending =
TRUE;
452 switch (self->state) {
461 IRDA_DEBUG(2,
"%s(), disconnect pending!\n", __func__);
462 self->disconnect_pending =
TRUE;
475 IRDA_DEBUG(1,
"%s(), reason=%s\n", __func__, lap_reasons[reason]);
485 IRDA_DEBUG(1,
"%s(), Sending reset request!\n", __func__);
496 IRDA_ERROR(
"%s: Unknown reason %d\n", __func__, reason);
522 IRDA_DEBUG(4,
"%s(), discovery only possible in NDM mode\n",
536 if (self->discovery_log !=
NULL) {
538 self->discovery_log =
NULL;
544 if (self->discovery_log ==
NULL) {
545 IRDA_WARNING(
"%s(), Unable to allocate discovery log!\n",
628 switch (quality_of_link) {
681 rand ^= (rand << 12);
682 rand ^= (rand >> 20);
684 slot = s + rand % (S-
s);
712 if (nr == self->vs) {
720 while ((skb_peek(&self->wx_list) !=
NULL) &&
721 (((self->va+1) % 8) != nr))
726 self->va = (
self->va + 1) % 8;
732 self->window =
self->window_size - skb_queue_len(&self->wx_list);
762 if (nr == self->vs) {
771 if (self->va < self->vs) {
772 if ((nr >= self->va) && (nr <= self->vs))
775 if ((nr >= self->va) || (nr <= self->vs))
797 self->vs =
self->vr = 0;
804 self->remote_busy =
FALSE;
805 self->retry_count = 0;
826 if (speed > 115200) {
827 self->mtt_required = min_turn_time;
870 static void irlap_change_speed(
struct irlap_cb *
self,
__u32 speed,
int now)
874 IRDA_DEBUG(0,
"%s(), setting speed to %d\n", __func__, speed);
898 static void irlap_init_qos_capabilities(
struct irlap_cb *
self,
917 IRDA_DEBUG(1,
"%s(), Found user specified QoS!\n", __func__);
932 self->qos_rx.max_turn_time.bits &= 0x01;
953 self->next_bofs = 12;
954 self->bofs_count = 12;
957 irlap_change_speed(
self, 9600,
TRUE);
966 while ((self->caddr == 0x00) || (self->caddr == 0xfe)) {
978 self->qos_tx.baud_rate.value = 9600;
979 self->qos_rx.baud_rate.value = 9600;
980 self->qos_tx.max_turn_time.value = 0;
981 self->qos_rx.max_turn_time.value = 0;
982 self->qos_tx.min_turn_time.value = 0;
983 self->qos_rx.min_turn_time.value = 0;
984 self->qos_tx.data_size.value = 64;
985 self->qos_rx.data_size.value = 64;
986 self->qos_tx.window_size.value = 1;
987 self->qos_rx.window_size.value = 1;
988 self->qos_tx.additional_bofs.value = 12;
989 self->qos_rx.additional_bofs.value = 12;
990 self->qos_tx.link_disc_time.value = 0;
991 self->qos_rx.link_disc_time.value = 0;
995 self->disconnect_pending =
FALSE;
996 self->connect_pending =
FALSE;
1016 self->next_bofs =
self->qos_tx.additional_bofs.value;
1018 self->bofs_count =
self->next_bofs;
1021 irlap_change_speed(
self, self->qos_tx.baud_rate.value, now);
1023 self->window_size =
self->qos_tx.window_size.value;
1024 self->window =
self->qos_tx.window_size.value;
1026 #ifdef CONFIG_IRDA_DYNAMIC_WINDOW
1031 self->line_capacity =
1033 self->qos_tx.max_turn_time.value);
1034 self->bytes_left =
self->line_capacity;
1042 IRDA_ASSERT(self->qos_tx.max_turn_time.value != 0,
return;);
1043 IRDA_ASSERT(self->qos_rx.max_turn_time.value != 0,
return;);
1050 self->poll_timeout =
self->qos_tx.max_turn_time.value *
HZ / 1000;
1056 self->final_timeout =
self->qos_rx.max_turn_time.value *
HZ / 1000;
1062 self->wd_timeout =
self->final_timeout * 2;
1088 self->qos_rx.max_turn_time.value;
1090 IRDA_DEBUG(4,
"Setting N1 = %d\n", self->N1);
1093 self->N2 =
self->qos_tx.link_disc_time.value * 1000 /
1094 self->qos_rx.max_turn_time.value;
1095 IRDA_DEBUG(4,
"Setting N2 = %d\n", self->N2);
1098 #ifdef CONFIG_PROC_FS
1099 struct irlap_iter_state {
1103 static void *irlap_seq_start(
struct seq_file *seq, loff_t *
pos)
1105 struct irlap_iter_state *iter = seq->
private;
1114 if (iter->id == *pos)
1122 static void *irlap_seq_next(
struct seq_file *seq,
void *
v, loff_t *pos)
1124 struct irlap_iter_state *iter = seq->
private;
1131 static void irlap_seq_stop(
struct seq_file *seq,
void *v)
1136 static int irlap_seq_show(
struct seq_file *seq,
void *v)
1138 const struct irlap_iter_state *iter = seq->
private;
1148 (self->netdev) ? self->netdev->name :
"bug");
1149 seq_printf(seq,
"hardware name: %s\n", self->hw_name);
1151 seq_printf(seq,
" caddr: %#02x, ", self->caddr);
1152 seq_printf(seq,
"saddr: %#08x, ", self->saddr);
1153 seq_printf(seq,
"daddr: %#08x\n", self->daddr);
1158 #ifdef CONFIG_IRDA_DYNAMIC_WINDOW
1160 self->line_capacity);
1161 seq_printf(seq,
"bytes left: %d\n", self->bytes_left);
1164 skb_queue_len(&self->txq));
1166 skb_queue_len(&self->wx_list));
1167 seq_printf(seq,
"rbusy: %s", self->remote_busy ?
1169 seq_printf(seq,
" mbusy: %s\n", self->media_busy ?
1172 seq_printf(seq,
" retrans: %d ", self->retry_count);
1177 seq_printf(seq,
" qos\tbps\tmaxtt\tdsize\twinsize\taddbofs\tmintt\tldisc\tcomp\n");
1180 self->qos_tx.baud_rate.value);
1182 self->qos_tx.max_turn_time.value);
1184 self->qos_tx.data_size.value);
1186 self->qos_tx.window_size.value);
1188 self->qos_tx.additional_bofs.value);
1190 self->qos_tx.min_turn_time.value);
1192 self->qos_tx.link_disc_time.value);
1196 self->qos_rx.baud_rate.value);
1198 self->qos_rx.max_turn_time.value);
1200 self->qos_rx.data_size.value);
1202 self->qos_rx.window_size.value);
1204 self->qos_rx.additional_bofs.value);
1206 self->qos_rx.min_turn_time.value);
1208 self->qos_rx.link_disc_time.value);
1214 .
start = irlap_seq_start,
1215 .next = irlap_seq_next,
1216 .stop = irlap_seq_stop,
1217 .show = irlap_seq_show,
1226 sizeof(
struct irlap_iter_state));
1231 .open = irlap_seq_open,