patch-2.2.15 linux/net/irda/irlap.c
Next file: linux/net/irda/irlap_comp.c
Previous file: linux/net/irda/irlan/irlan_provider_event.c
Back to the patch index
Back to the overall index
- Lines: 1100
- Date:
Fri Apr 21 12:47:16 2000
- Orig file:
v2.2.14/net/irda/irlap.c
- Orig date:
Sat Aug 14 02:26:52 1999
diff -u --new-file --recursive --exclude-from ../../exclude v2.2.14/net/irda/irlap.c linux/net/irda/irlap.c
@@ -6,7 +6,7 @@
* Status: Stable
* Author: Dag Brattli <dagb@cs.uit.no>
* Created at: Mon Aug 4 20:40:53 1997
- * Modified at: Mon May 31 21:43:55 1999
+ * Modified at: Tue Dec 14 09:26:44 1999
* Modified by: Dag Brattli <dagb@cs.uit.no>
*
* Copyright (c) 1998-1999 Dag Brattli, All Rights Reserved.
@@ -69,19 +69,20 @@
#endif /* CONFIG_PROC_FS */
-__initfunc(int irlap_init(void))
+int __init irlap_init(void)
{
/* Allocate master array */
irlap = hashbin_new(HB_LOCAL);
if (irlap == NULL) {
- printk(KERN_WARNING "IrLAP: Can't allocate irlap hashbin!\n");
+ ERROR(__FUNCTION__ "(), can't allocate irlap hashbin!\n");
return -ENOMEM;
}
#ifdef CONFIG_IRDA_COMPRESSION
irlap_compressors = hashbin_new(HB_LOCAL);
if (irlap_compressors == NULL) {
- printk(KERN_WARNING "IrLAP: Can't allocate compressors hashbin!\n");
+ WARNING(__FUNCTION__
+ "(), can't allocate compressors hashbin!\n");
return -ENOMEM;
}
#endif
@@ -106,15 +107,12 @@
* Initialize IrLAP layer
*
*/
-struct irlap_cb *irlap_open(struct irda_device *irdev)
+struct irlap_cb *irlap_open(struct device *dev, struct qos_info *qos)
{
struct irlap_cb *self;
- DEBUG(4, __FUNCTION__ "()\n");
+ IRDA_DEBUG(4, __FUNCTION__ "()\n");
- ASSERT(irdev != NULL, return NULL;);
- ASSERT(irdev->magic == IRDA_DEVICE_MAGIC, return NULL;);
-
/* Initialize the irlap structure. */
self = kmalloc(sizeof(struct irlap_cb), GFP_KERNEL);
if (self == NULL)
@@ -124,26 +122,22 @@
self->magic = LAP_MAGIC;
/* Make a binding between the layers */
- self->irdev = irdev;
- self->netdev = &irdev->netdev;
+ self->netdev = dev;
+ self->qos_dev = qos;
+
+ /* FIXME: should we get our own field? */
+ dev->atalk_ptr = self;
irlap_next_state(self, LAP_OFFLINE);
- /* Initialize transmitt queue */
- skb_queue_head_init(&self->tx_list);
+ /* Initialize transmit queue */
+ skb_queue_head_init(&self->txq);
+ skb_queue_head_init(&self->txq_ultra);
skb_queue_head_init(&self->wx_list);
/* My unique IrLAP device address! */
get_random_bytes(&self->saddr, sizeof(self->saddr));
-
- /*
- * Generate random connection address for this session, which must
- * be 7 bits wide and different from 0x00 and 0xfe
- */
- while ((self->caddr == 0x00) || (self->caddr == 0xfe)) {
- get_random_bytes(&self->caddr, sizeof(self->caddr));
- self->caddr &= 0xfe;
- }
+ memcpy(dev->dev_addr, &self->saddr, 4);
init_timer(&self->slot_timer);
init_timer(&self->query_timer);
@@ -152,12 +146,15 @@
init_timer(&self->poll_timer);
init_timer(&self->wd_timer);
init_timer(&self->backoff_timer);
+ init_timer(&self->media_busy_timer);
irlap_apply_default_connection_parameters(self);
+
+ self->N3 = 3; /* # connections attemts to try before giving up */
irlap_next_state(self, LAP_NDM);
- hashbin_insert(irlap, (QUEUE *) self, self->saddr, NULL);
+ hashbin_insert(irlap, (queue_t *) self, self->saddr, NULL);
irlmp_register_link(self, self->saddr, &self->notify);
@@ -183,10 +180,10 @@
del_timer(&self->poll_timer);
del_timer(&self->wd_timer);
del_timer(&self->backoff_timer);
+ del_timer(&self->media_busy_timer);
irlap_flush_all_queues(self);
- self->irdev = NULL;
self->magic = 0;
kfree(self);
@@ -202,7 +199,7 @@
{
struct irlap_cb *lap;
- DEBUG(4, __FUNCTION__ "()\n");
+ IRDA_DEBUG(4, __FUNCTION__ "()\n");
ASSERT(self != NULL, return;);
ASSERT(self->magic == LAP_MAGIC, return;);
@@ -215,7 +212,7 @@
/* Be sure that we manage to remove ourself from the hash */
lap = hashbin_remove(irlap, self->saddr, NULL);
if (!lap) {
- DEBUG(1, __FUNCTION__ "(), Didn't find myself!\n");
+ IRDA_DEBUG(1, __FUNCTION__ "(), Didn't find myself!\n");
return;
}
__irlap_close(lap);
@@ -229,7 +226,7 @@
*/
void irlap_connect_indication(struct irlap_cb *self, struct sk_buff *skb)
{
- DEBUG(4, __FUNCTION__ "()\n");
+ IRDA_DEBUG(4, __FUNCTION__ "()\n");
ASSERT(self != NULL, return;);
ASSERT(self->magic == LAP_MAGIC, return;);
@@ -248,7 +245,7 @@
*/
void irlap_connect_response(struct irlap_cb *self, struct sk_buff *skb)
{
- DEBUG(4, __FUNCTION__ "()\n");
+ IRDA_DEBUG(4, __FUNCTION__ "()\n");
irlap_do_event(self, CONNECT_RESPONSE, skb, NULL);
}
@@ -263,7 +260,7 @@
void irlap_connect_request(struct irlap_cb *self, __u32 daddr,
struct qos_info *qos_user, int sniff)
{
- DEBUG(3, __FUNCTION__ "(), daddr=0x%08x\n", daddr);
+ IRDA_DEBUG(3, __FUNCTION__ "(), daddr=0x%08x\n", daddr);
ASSERT(self != NULL, return;);
ASSERT(self->magic == LAP_MAGIC, return;);
@@ -276,8 +273,7 @@
*/
irlap_init_qos_capabilities(self, qos_user);
- if ((self->state == LAP_NDM) &&
- !irda_device_is_media_busy(self->irdev))
+ if ((self->state == LAP_NDM) && !self->media_busy)
irlap_do_event(self, CONNECT_REQUEST, NULL, NULL);
else
self->connect_pending = TRUE;
@@ -291,7 +287,7 @@
*/
void irlap_connect_confirm(struct irlap_cb *self, struct sk_buff *skb)
{
- DEBUG(4, __FUNCTION__ "()\n");
+ IRDA_DEBUG(4, __FUNCTION__ "()\n");
ASSERT(self != NULL, return;);
ASSERT(self->magic == LAP_MAGIC, return;);
@@ -306,7 +302,8 @@
* IrLMP for further processing
*
*/
-inline void irlap_data_indication(struct irlap_cb *self, struct sk_buff *skb)
+void irlap_data_indication(struct irlap_cb *self, struct sk_buff *skb,
+ int unreliable)
{
/* Hide LAP header from IrLMP layer */
skb_pull(skb, LAP_ADDR_HEADER+LAP_CTRL_HEADER);
@@ -315,43 +312,14 @@
if (self->qos_tx.compression.value) {
skb = irlap_decompress_frame(self, skb);
if (!skb) {
- DEBUG(1, __FUNCTION__ "(), Decompress error!\n");
+ IRDA_DEBUG(1, __FUNCTION__ "(), Decompress error!\n");
return;
}
}
#endif
- irlmp_link_data_indication(self->notify.instance, LAP_RELIABLE, skb);
+ irlmp_link_data_indication(self->notify.instance, skb, unreliable);
}
-/*
- * Function irlap_unit_data_indication (self, skb)
- *
- * Received some data that was sent unreliable
- *
- */
-void irlap_unit_data_indication(struct irlap_cb *self, struct sk_buff *skb)
-{
- DEBUG(1, __FUNCTION__ "()\n");
-
- ASSERT(self != NULL, return;);
- ASSERT(self->magic == LAP_MAGIC, return;);
- ASSERT(skb != NULL, return;);
-
- /* Hide LAP header from IrLMP layer */
- skb_pull(skb, LAP_ADDR_HEADER+LAP_CTRL_HEADER);
-
-#ifdef CONFIG_IRDA_COMPRESSION
- if (self->qos_tx.compression.value) {
-
- skb = irlap_decompress_frame(self, skb);
- if (!skb) {
- DEBUG(1, __FUNCTION__ "(), Decompress error!\n");
- return;
- }
- }
-#endif
- irlmp_link_data_indication(self->notify.instance, LAP_UNRELIABLE, skb);
-}
/*
* Function irlap_data_request (self, skb)
@@ -359,23 +327,23 @@
* Queue data for transmission, must wait until XMIT state
*
*/
-inline void irlap_data_request(struct irlap_cb *self, struct sk_buff *skb,
- int reliable)
+void irlap_data_request(struct irlap_cb *self, struct sk_buff *skb,
+ int unreliable)
{
ASSERT(self != NULL, return;);
ASSERT(self->magic == LAP_MAGIC, return;);
- ASSERT(skb != NULL, return;);
+
+ IRDA_DEBUG(3, __FUNCTION__ "()\n");
#ifdef CONFIG_IRDA_COMPRESSION
if (self->qos_tx.compression.value) {
skb = irlap_compress_frame(self, skb);
if (!skb) {
- DEBUG(1, __FUNCTION__ "(), Compress error!\n");
+ IRDA_DEBUG(1, __FUNCTION__ "(), Compress error!\n");
return;
}
}
#endif
-
ASSERT(skb_headroom(skb) >= (LAP_ADDR_HEADER+LAP_CTRL_HEADER),
return;);
skb_push(skb, LAP_ADDR_HEADER+LAP_CTRL_HEADER);
@@ -384,12 +352,10 @@
* Must set frame format now so that the rest of the code knows
* if its dealing with an I or an UI frame
*/
- if (reliable)
- skb->data[1] = I_FRAME;
- else {
- DEBUG(4, __FUNCTION__ "(), queueing unreliable frame\n");
+ if (unreliable)
skb->data[1] = UI_FRAME;
- }
+ else
+ skb->data[1] = I_FRAME;
/*
* Send event if this frame only if we are in the right state
@@ -400,16 +366,65 @@
* Check if the transmit queue contains some unsent frames,
* and if so, make sure they are sent first
*/
- if (!skb_queue_empty(&self->tx_list)) {
- skb_queue_tail(&self->tx_list, skb);
- skb = skb_dequeue(&self->tx_list);
+ if (!skb_queue_empty(&self->txq)) {
+ skb_queue_tail(&self->txq, skb);
+ skb = skb_dequeue(&self->txq);
ASSERT(skb != NULL, return;);
}
irlap_do_event(self, SEND_I_CMD, skb, NULL);
} else
- skb_queue_tail(&self->tx_list, skb);
+ skb_queue_tail(&self->txq, skb);
+}
+
+/*
+ * Function irlap_unitdata_request (self, skb)
+ *
+ * Send Ultra data. This is data that must be sent outside any connection
+ *
+ */
+#ifdef CONFIG_IRDA_ULTRA
+void irlap_unitdata_request(struct irlap_cb *self, struct sk_buff *skb)
+{
+ ASSERT(self != NULL, return;);
+ ASSERT(self->magic == LAP_MAGIC, return;);
+
+ IRDA_DEBUG(3, __FUNCTION__ "()\n");
+
+ ASSERT(skb_headroom(skb) >= (LAP_ADDR_HEADER+LAP_CTRL_HEADER),
+ return;);
+ skb_push(skb, LAP_ADDR_HEADER+LAP_CTRL_HEADER);
+
+ skb->data[0] = CBROADCAST;
+ skb->data[1] = UI_FRAME;
+
+ skb_queue_tail(&self->txq_ultra, skb);
+
+ irlap_do_event(self, SEND_UI_FRAME, NULL, NULL);
}
+#endif /*CONFIG_IRDA_ULTRA */
+
+/*
+ * Function irlap_udata_indication (self, skb)
+ *
+ * Receive Ultra data. This is data that is received outside any connection
+ *
+ */
+#ifdef CONFIG_IRDA_ULTRA
+void irlap_unitdata_indication(struct irlap_cb *self, struct sk_buff *skb)
+{
+ IRDA_DEBUG(1, __FUNCTION__ "()\n");
+
+ ASSERT(self != NULL, return;);
+ ASSERT(self->magic == LAP_MAGIC, return;);
+ ASSERT(skb != NULL, return;);
+
+ /* Hide LAP header from IrLMP layer */
+ skb_pull(skb, LAP_ADDR_HEADER+LAP_CTRL_HEADER);
+
+ irlmp_link_unitdata_indication(self->notify.instance, skb);
+}
+#endif /* CONFIG_IRDA_ULTRA */
/*
* Function irlap_disconnect_request (void)
@@ -418,11 +433,19 @@
*/
void irlap_disconnect_request(struct irlap_cb *self)
{
- DEBUG(3, __FUNCTION__ "()\n");
+ IRDA_DEBUG(3, __FUNCTION__ "()\n");
ASSERT(self != NULL, return;);
ASSERT(self->magic == LAP_MAGIC, return;);
+ /* Don't disconnect until all data frames are successfully sent */
+ if (skb_queue_len(&self->txq) > 0) {
+ self->disconnect_pending = TRUE;
+
+ return;
+ }
+
+ /* Check if we are in the right state for disconnecting */
switch (self->state) {
case LAP_XMIT_P: /* FALLTROUGH */
case LAP_XMIT_S: /* FALLTROUGH */
@@ -432,7 +455,7 @@
irlap_do_event(self, DISCONNECT_REQUEST, NULL, NULL);
break;
default:
- DEBUG(0, __FUNCTION__ "(), disconnect pending!\n");
+ IRDA_DEBUG(2, __FUNCTION__ "(), disconnect pending!\n");
self->disconnect_pending = TRUE;
break;
}
@@ -446,7 +469,7 @@
*/
void irlap_disconnect_indication(struct irlap_cb *self, LAP_REASON reason)
{
- DEBUG(1, __FUNCTION__ "(), reason=%s\n", lap_reasons[reason]);
+ IRDA_DEBUG(1, __FUNCTION__ "(), reason=%s\n", lap_reasons[reason]);
ASSERT(self != NULL, return;);
ASSERT(self->magic == LAP_MAGIC, return;);
@@ -457,21 +480,20 @@
/* Flush queues */
irlap_flush_all_queues(self);
- switch(reason) {
+ switch (reason) {
case LAP_RESET_INDICATION:
- DEBUG(1, __FUNCTION__ "(), Sending reset request!\n");
+ IRDA_DEBUG(1, __FUNCTION__ "(), Sending reset request!\n");
irlap_do_event(self, RESET_REQUEST, NULL, NULL);
break;
case LAP_NO_RESPONSE: /* FALLTROUGH */
case LAP_DISC_INDICATION: /* FALLTROUGH */
case LAP_FOUND_NONE: /* FALLTROUGH */
case LAP_MEDIA_BUSY:
- irlmp_link_disconnect_indication(self->notify.instance,
- self, reason, NULL);
+ irlmp_link_disconnect_indication(self->notify.instance, self,
+ reason, NULL);
break;
default:
- DEBUG(1, __FUNCTION__ "(), Reason %d not implemented!\n",
- reason);
+ ERROR(__FUNCTION__ "(), Unknown reason %d\n", reason);
}
}
@@ -489,49 +511,53 @@
ASSERT(self->magic == LAP_MAGIC, return;);
ASSERT(discovery != NULL, return;);
- DEBUG(4, __FUNCTION__ "(), nslots = %d\n", discovery->nslots);
+ IRDA_DEBUG(4, __FUNCTION__ "(), nslots = %d\n", discovery->nslots);
ASSERT((discovery->nslots == 1) || (discovery->nslots == 6) ||
(discovery->nslots == 8) || (discovery->nslots == 16),
return;);
- /*
- * Discovery is only possible in NDM mode
- */
- if (self->state == LAP_NDM) {
- ASSERT(self->discovery_log == NULL, return;);
- self->discovery_log= hashbin_new(HB_LOCAL);
-
- info.S = discovery->nslots; /* Number of slots */
- info.s = 0; /* Current slot */
-
- self->discovery_cmd = discovery;
- info.discovery = discovery;
-
- /* Check if the slot timeout is within limits */
- if (sysctl_slot_timeout < 20) {
- ERROR(__FUNCTION__
- "(), to low value for slot timeout!\n");
- sysctl_slot_timeout = 20;
- }
- /*
- * Highest value is actually 8, but we allow higher since
- * some devices seems to require it.
- */
- if (sysctl_slot_timeout > 160) {
- ERROR(__FUNCTION__
- "(), to high value for slot timeout!\n");
- sysctl_slot_timeout = 160;
- }
-
- self->slot_timeout = sysctl_slot_timeout * HZ / 1000;
-
- irlap_do_event(self, DISCOVERY_REQUEST, NULL, &info);
- } else {
- DEBUG(4, __FUNCTION__
- "(), discovery only possible in NDM mode\n");
+ /* Discovery is only possible in NDM mode */
+ if (self->state != LAP_NDM) {
+ IRDA_DEBUG(4, __FUNCTION__
+ "(), discovery only possible in NDM mode\n");
irlap_discovery_confirm(self, NULL);
- }
+ return;
+ }
+
+ /* Check if last discovery request finished in time */
+ if (self->discovery_log != NULL) {
+ hashbin_delete(self->discovery_log, (FREE_FUNC) kfree);
+ self->discovery_log = NULL;
+ }
+
+ self->discovery_log= hashbin_new(HB_LOCAL);
+
+ info.S = discovery->nslots; /* Number of slots */
+ info.s = 0; /* Current slot */
+
+ self->discovery_cmd = discovery;
+ info.discovery = discovery;
+
+ /* Check if the slot timeout is within limits */
+ if (sysctl_slot_timeout < 20) {
+ ERROR(__FUNCTION__
+ "(), to low value for slot timeout!\n");
+ sysctl_slot_timeout = 20;
+ }
+ /*
+ * Highest value is actually 8, but we allow higher since
+ * some devices seems to require it.
+ */
+ if (sysctl_slot_timeout > 160) {
+ ERROR(__FUNCTION__
+ "(), to high value for slot timeout!\n");
+ sysctl_slot_timeout = 160;
+ }
+
+ self->slot_timeout = sysctl_slot_timeout * HZ / 1000;
+
+ irlap_do_event(self, DISCOVERY_REQUEST, NULL, &info);
}
/*
@@ -552,16 +578,11 @@
* the media busy condition (irlap p.94). This should allow us to make
* connection attempts much easier.
*/
- if (discovery_log && hashbin_get_size(discovery_log) > 0)
- irda_device_set_media_busy(self->irdev, FALSE);
+ if (discovery_log && HASHBIN_GET_SIZE(discovery_log) > 0)
+ irda_device_set_media_busy(self->netdev, FALSE);
/* Inform IrLMP */
irlmp_link_discovery_confirm(self->notify.instance, discovery_log);
-
- /*
- * IrLMP has now the responsibilities for the discovery_log
- */
- self->discovery_log = NULL;
}
/*
@@ -572,7 +593,7 @@
*/
void irlap_discovery_indication(struct irlap_cb *self, discovery_t *discovery)
{
- DEBUG(4, __FUNCTION__ "()\n");
+ IRDA_DEBUG(4, __FUNCTION__ "()\n");
ASSERT(self != NULL, return;);
ASSERT(self->magic == LAP_MAGIC, return;);
@@ -591,12 +612,12 @@
*/
void irlap_status_indication(int quality_of_link)
{
- switch(quality_of_link) {
+ switch (quality_of_link) {
case STATUS_NO_ACTIVITY:
- printk(KERN_INFO "IrLAP, no activity on link!\n");
+ MESSAGE("IrLAP, no activity on link!\n");
break;
case STATUS_NOISY:
- printk(KERN_INFO "IrLAP, noisy link!\n");
+ MESSAGE("IrLAP, noisy link!\n");
break;
default:
break;
@@ -612,7 +633,7 @@
*/
void irlap_reset_indication(struct irlap_cb *self)
{
- DEBUG(1, __FUNCTION__ "()\n");
+ IRDA_DEBUG(1, __FUNCTION__ "()\n");
ASSERT(self != NULL, return;);
ASSERT(self->magic == LAP_MAGIC, return;);
@@ -631,7 +652,7 @@
*/
void irlap_reset_confirm(void)
{
- DEBUG(1, __FUNCTION__ "()\n");
+ IRDA_DEBUG(1, __FUNCTION__ "()\n");
}
/*
@@ -666,16 +687,10 @@
struct sk_buff *skb = NULL;
int count = 0;
- ASSERT(self != NULL, return;);
- ASSERT(self->magic == LAP_MAGIC, return;);
-
/*
* Remove all the ack-ed frames from the window queue.
*/
- DEBUG(4, "--> wx_list=%d, va=%d, nr=%d\n",
- skb_queue_len(&self->wx_list), self->va, nr);
-
/*
* Optimize for the common case. It is most likely that the receiver
* will acknowledge all the frames we have sent! So in that case we
@@ -683,7 +698,7 @@
*/
if (nr == self->vs) {
while ((skb = skb_dequeue(&self->wx_list)) != NULL) {
- dev_kfree_skb(skb);
+ dev_kfree_skb(skb);
}
/* The last acked frame is the next to send minus one */
self->va = nr - 1;
@@ -698,10 +713,6 @@
self->va = (self->va + 1) % 8;
count++;
}
-
- DEBUG(4, "irlap_update_nr_received(), removed %d\n", count);
- DEBUG(4, "wx_list=%d, va=%d, nr=%d -->\n",
- skb_queue_len(&self->wx_list), self->va, nr);
}
/* Advance window */
@@ -715,20 +726,15 @@
*/
int irlap_validate_ns_received(struct irlap_cb *self, int ns)
{
- ASSERT(self != NULL, return -ENODEV;);
- ASSERT(self->magic == LAP_MAGIC, return -EBADR;);
-
/* ns as expected? */
- if (ns == self->vr) {
- DEBUG(4, __FUNCTION__ "(), expected!\n");
+ if (ns == self->vr)
return NS_EXPECTED;
- }
/*
* Stations are allowed to treat invalid NS as unexpected NS
* IrLAP, Recv ... with-invalid-Ns. p. 84
*/
return NS_UNEXPECTED;
-
+
/* return NR_INVALID; */
}
/*
@@ -739,12 +745,9 @@
*/
int irlap_validate_nr_received(struct irlap_cb *self, int nr)
{
- ASSERT(self != NULL, return -ENODEV;);
- ASSERT(self->magic == LAP_MAGIC, return -EBADR;);
-
/* nr as expected? */
if (nr == self->vs) {
- DEBUG(4, __FUNCTION__ "(), expected!\n");
+ IRDA_DEBUG(4, __FUNCTION__ "(), expected!\n");
return NR_EXPECTED;
}
@@ -772,7 +775,7 @@
*/
void irlap_initiate_connection_state(struct irlap_cb *self)
{
- DEBUG(4, __FUNCTION__ "()\n");
+ IRDA_DEBUG(4, __FUNCTION__ "()\n");
ASSERT(self != NULL, return;);
ASSERT(self->magic == LAP_MAGIC, return;);
@@ -799,17 +802,16 @@
*/
void irlap_wait_min_turn_around(struct irlap_cb *self, struct qos_info *qos)
{
- int usecs;
- int speed;
- int bytes ;
+ __u32 min_turn_time;
+ __u32 speed;
/* Get QoS values. */
speed = qos->baud_rate.value;
- usecs = qos->min_turn_time.value;
+ min_turn_time = qos->min_turn_time.value;
/* No need to calculate XBOFs for speeds over 115200 bps */
if (speed > 115200) {
- self->mtt_required = usecs;
+ self->mtt_required = min_turn_time;
return;
}
@@ -818,9 +820,7 @@
* min turn time, so now we must calculate how many chars (XBOF's) we
* must send for the requested time period (min turn time)
*/
- bytes = speed * usecs / 10000000;
-
- self->xbofs_delay = bytes;
+ self->xbofs_delay = irlap_min_turn_time_in_bytes(speed, min_turn_time);
}
/*
@@ -837,9 +837,12 @@
ASSERT(self->magic == LAP_MAGIC, return;);
/* Free transmission queue */
- while ((skb = skb_dequeue(&self->tx_list)) != NULL)
+ while ((skb = skb_dequeue(&self->txq)) != NULL)
dev_kfree_skb(skb);
+ while ((skb = skb_dequeue(&self->txq_ultra)) != NULL)
+ dev_kfree_skb(skb);
+
/* Free sliding window buffered packets */
while ((skb = skb_dequeue(&self->wx_list)) != NULL)
dev_kfree_skb(skb);
@@ -858,22 +861,18 @@
* Change the speed of the IrDA port
*
*/
-void irlap_change_speed(struct irlap_cb *self, int speed)
+void irlap_change_speed(struct irlap_cb *self, __u32 speed, int now)
{
- DEBUG(4, __FUNCTION__ "(), setting speed to %d\n", speed);
+ IRDA_DEBUG(0, __FUNCTION__ "(), setting speed to %d\n", speed);
ASSERT(self != NULL, return;);
ASSERT(self->magic == LAP_MAGIC, return;);
- if (!self->irdev) {
- DEBUG(1, __FUNCTION__ "(), driver missing!\n");
- return;
- }
-
- irda_device_change_speed(self->irdev, speed);
+ self->speed = speed;
- self->qos_rx.baud_rate.value = speed;
- self->qos_tx.baud_rate.value = speed;
+ /* Change speed now, or just piggyback speed on frames */
+ if (now)
+ irda_device_change_speed(self->netdev, speed);
}
#ifdef CONFIG_IRDA_COMPRESSION
@@ -885,33 +884,33 @@
ASSERT(self != NULL, return;);
ASSERT(self->magic == LAP_MAGIC, return;);
-
+
/*
* Find out which compressors we support. We do this be checking that
* the corresponding compressor for each bit set in the QoS bits has
* actually been loaded. Ths is sort of hairy code but that is what
* you get when you do a little bit flicking :-)
*/
- DEBUG(4, __FUNCTION__ "(), comp bits 0x%02x\n",
- self->qos_rx.compression.bits);
+ IRDA_DEBUG(4, __FUNCTION__ "(), comp bits 0x%02x\n",
+ self->qos_rx.compression.bits);
mask = 0x80; /* Start with testing MSB */
for (i=0;i<8;i++) {
- DEBUG(4, __FUNCTION__ "(), testing bit %d\n", 8-i);
+ IRDA_DEBUG(4, __FUNCTION__ "(), testing bit %d\n", 8-i);
if (self->qos_rx.compression.bits & mask) {
- DEBUG(4, __FUNCTION__ "(), bit %d is set by defalt\n",
- 8-i);
+ IRDA_DEBUG(4, __FUNCTION__
+ "(), bit %d is set by defalt\n", 8-i);
comp = hashbin_find(irlap_compressors,
- compression[ msb_index(mask)],
- NULL);
+ compressions[msb_index(mask)],
+ NULL);
if (!comp) {
/* Protocol not supported, so clear the bit */
- DEBUG(4, __FUNCTION__ "(), Compression "
- "protocol %d has not been loaded!\n",
- compression[msb_index(mask)]);
+ IRDA_DEBUG(4, __FUNCTION__ "(), Compression "
+ "protocol %d has not been loaded!\n",
+ compressions[msb_index(mask)]);
self->qos_rx.compression.bits &= ~mask;
- DEBUG(4, __FUNCTION__
- "(), comp bits 0x%02x\n",
- self->qos_rx.compression.bits);
+ IRDA_DEBUG(4, __FUNCTION__
+ "(), comp bits 0x%02x\n",
+ self->qos_rx.compression.bits);
}
}
/* Try the next bit */
@@ -933,7 +932,7 @@
{
ASSERT(self != NULL, return;);
ASSERT(self->magic == LAP_MAGIC, return;);
- ASSERT(self->irdev != NULL, return;);
+ ASSERT(self->netdev != NULL, return;);
/* Start out with the maximum QoS support possible */
irda_init_max_qos_capabilies(&self->qos_rx);
@@ -943,8 +942,7 @@
#endif
/* Apply drivers QoS capabilities */
- irda_qos_compute_intersection(&self->qos_rx,
- irda_device_get_qos(self->irdev));
+ irda_qos_compute_intersection(&self->qos_rx, self->qos_dev);
/*
* Check for user supplied QoS parameters. The service user is only
@@ -952,7 +950,7 @@
* user may not have set all of them.
*/
if (qos_user) {
- DEBUG(1, __FUNCTION__ "(), Found user specified QoS!\n");
+ IRDA_DEBUG(1, __FUNCTION__ "(), Found user specified QoS!\n");
if (qos_user->baud_rate.bits)
self->qos_rx.baud_rate.bits &= qos_user->baud_rate.bits;
@@ -969,17 +967,11 @@
#endif
}
- /*
- * Make the intersection between IrLAP and drivers QoS
- * capabilities
- */
-
/* Use 500ms in IrLAP for now */
- self->qos_rx.max_turn_time.bits &= 0x03;
self->qos_rx.max_turn_time.bits &= 0x01;
/* Set data size */
- /* self->qos_rx.data_size.bits &= 0x03; */
+ /*self->qos_rx.data_size.bits &= 0x03;*/
/* Set disconnect time */
self->qos_rx.link_disc_time.bits &= 0x07;
@@ -995,28 +987,54 @@
*/
void irlap_apply_default_connection_parameters(struct irlap_cb *self)
{
- DEBUG(4, __FUNCTION__ "()\n");
+ IRDA_DEBUG(4, __FUNCTION__ "()\n");
ASSERT(self != NULL, return;);
ASSERT(self->magic == LAP_MAGIC, return;);
- irlap_change_speed(self, 9600);
+ irlap_change_speed(self, 9600, TRUE);
+
+ /* Set mbusy when going to NDM state */
+ irda_device_set_media_busy(self->netdev, TRUE);
/* Default value in NDM */
self->bofs_count = 11;
- /* Use these until connection has been made */
+ /*
+ * Generate random connection address for this session, which must
+ * be 7 bits wide and different from 0x00 and 0xfe
+ */
+ while ((self->caddr == 0x00) || (self->caddr == 0xfe)) {
+ get_random_bytes(&self->caddr, sizeof(self->caddr));
+ self->caddr &= 0xfe;
+ }
+
+ /* Use default values until connection has been negitiated */
self->slot_timeout = sysctl_slot_timeout;
self->final_timeout = FINAL_TIMEOUT;
self->poll_timeout = POLL_TIMEOUT;
self->wd_timeout = WD_TIMEOUT;
+ /* Set some default values */
+ self->qos_tx.baud_rate.value = 9600;
+ self->qos_rx.baud_rate.value = 9600;
+ self->qos_tx.max_turn_time.value = 0;
+ self->qos_rx.max_turn_time.value = 0;
+ self->qos_tx.min_turn_time.value = 0;
+ self->qos_rx.min_turn_time.value = 0;
self->qos_tx.data_size.value = 64;
+ self->qos_rx.data_size.value = 64;
+ self->qos_tx.window_size.value = 1;
+ self->qos_rx.window_size.value = 1;
self->qos_tx.additional_bofs.value = 11;
+ self->qos_rx.additional_bofs.value = 11;
+ self->qos_tx.link_disc_time.value = 0;
+ self->qos_rx.link_disc_time.value = 0;
irlap_flush_all_queues(self);
self->disconnect_pending = FALSE;
+ self->connect_pending = FALSE;
}
/*
@@ -1025,62 +1043,86 @@
* Initialize IrLAP with the negotiated QoS values
*
*/
-void irlap_apply_connection_parameters(struct irlap_cb *self,
- struct qos_info *qos)
+void irlap_apply_connection_parameters(struct irlap_cb *self)
{
- DEBUG(4, __FUNCTION__ "()\n");
+ IRDA_DEBUG(4, __FUNCTION__ "()\n");
ASSERT(self != NULL, return;);
ASSERT(self->magic == LAP_MAGIC, return;);
- irlap_change_speed(self, qos->baud_rate.value);
+ irlap_change_speed(self, self->qos_tx.baud_rate.value, FALSE);
- self->window_size = qos->window_size.value;
- self->window = qos->window_size.value;
- self->bofs_count = qos->additional_bofs.value;
+ self->window_size = self->qos_tx.window_size.value;
+ self->window = self->qos_tx.window_size.value;
+ self->bofs_count = self->qos_tx.additional_bofs.value;
/*
* Calculate how many bytes it is possible to transmit before the
- * link must be turned around wb = baud * mtt/1000 * 1/2
+ * link must be turned around
*/
- self->window_bytes = qos->baud_rate.value
- * qos->max_turn_time.value / 10000;
- DEBUG(4, "Setting window_bytes = %d\n", self->window_bytes);
-
+ self->line_capacity =
+ irlap_max_line_capacity(self->qos_tx.baud_rate.value,
+ self->qos_tx.max_turn_time.value);
/*
* Set N1 to 0 if Link Disconnect/Threshold Time = 3 and set it to
* 3 seconds otherwise. See page 71 in IrLAP for more details.
* TODO: these values should be calculated from the final timer
* as well
*/
- if (qos->link_disc_time.value == 3)
+ ASSERT(self->qos_tx.max_turn_time.value != 0, return;);
+ if (self->qos_tx.link_disc_time.value == 3)
self->N1 = 0;
else
- self->N1 = 3000 / qos->max_turn_time.value;
+ self->N1 = 3000 / self->qos_tx.max_turn_time.value;
+
+ IRDA_DEBUG(4, "Setting N1 = %d\n", self->N1);
- DEBUG(4, "Setting N1 = %d\n", self->N1);
- self->N2 = qos->link_disc_time.value * 1000 / qos->max_turn_time.value;
- DEBUG(4, "Setting N2 = %d\n", self->N2);
+ self->N2 = self->qos_tx.link_disc_time.value * 1000 /
+ self->qos_tx.max_turn_time.value;
+ IRDA_DEBUG(4, "Setting N2 = %d\n", self->N2);
/*
* Initialize timeout values, some of the rules are listed on
* page 92 in IrLAP.
*/
- self->poll_timeout = qos->max_turn_time.value * HZ / 1000;
- self->final_timeout = qos->max_turn_time.value * HZ / 1000;
+ self->poll_timeout = self->qos_tx.max_turn_time.value * HZ / 1000;
self->wd_timeout = self->poll_timeout * 2;
+ /*
+ * Be careful to keep our promises to the peer device about how long
+ * time it can keep the pf bit. So here we must use the rx_qos value
+ */
+ self->final_timeout = self->qos_rx.max_turn_time.value * HZ / 1000;
+
#ifdef CONFIG_IRDA_COMPRESSION
- if (qos->compression.value) {
- DEBUG(1, __FUNCTION__ "(), Initializing compression\n");
- irda_set_compression(self, qos->compression.value);
+ if (self->qos_tx.compression.value) {
+ IRDA_DEBUG(1, __FUNCTION__ "(), Initializing compression\n");
+ irda_set_compression(self, self->qos_tx.compression.value);
irlap_compressor_init(self, 0);
}
#endif
}
+/*
+ * Function irlap_set_local_busy (self, status)
+ *
+ *
+ *
+ */
+void irlap_set_local_busy(struct irlap_cb *self, int status)
+{
+ IRDA_DEBUG(0, __FUNCTION__ "()\n");
+
+ self->local_busy = status;
+
+ if (status)
+ IRDA_DEBUG(0, __FUNCTION__ "(), local busy ON\n");
+ else
+ IRDA_DEBUG(0, __FUNCTION__ "(), local busy OFF\n");
+}
+
#ifdef CONFIG_PROC_FS
/*
* Function irlap_proc_read (buf, start, offset, len, unused)
@@ -1089,7 +1131,7 @@
*
*/
int irlap_proc_read(char *buf, char **start, off_t offset, int len,
- int unused)
+ int unused)
{
struct irlap_cb *self;
unsigned long flags;
@@ -1105,27 +1147,30 @@
ASSERT(self != NULL, return -ENODEV;);
ASSERT(self->magic == LAP_MAGIC, return -EBADR;);
- len += sprintf(buf+len, "irlap%d <-> %s ",
- i++, self->irdev->name);
+ len += sprintf(buf+len, "irlap%d ", i++);
len += sprintf(buf+len, "state: %s\n",
- irlap_state[ self->state]);
+ irlap_state[self->state]);
len += sprintf(buf+len, " caddr: %#02x, ", self->caddr);
len += sprintf(buf+len, "saddr: %#08x, ", self->saddr);
len += sprintf(buf+len, "daddr: %#08x\n", self->daddr);
len += sprintf(buf+len, " win size: %d, ",
- self->window_size);
+ self->window_size);
len += sprintf(buf+len, "win: %d, ", self->window);
- len += sprintf(buf+len, "win bytes: %d, ", self->window_bytes);
+#if CONFIG_IRDA_DYNAMIC_WINDOW
+ len += sprintf(buf+len, "line capacity: %d, ",
+ self->line_capacity);
len += sprintf(buf+len, "bytes left: %d\n", self->bytes_left);
-
+#endif /* CONFIG_IRDA_DYNAMIC_WINDOW */
len += sprintf(buf+len, " tx queue len: %d ",
- skb_queue_len(&self->tx_list));
+ skb_queue_len(&self->txq));
len += sprintf(buf+len, "win queue len: %d ",
- skb_queue_len(&self->wx_list));
- len += sprintf(buf+len, "rbusy: %s\n", self->remote_busy ?
- "TRUE" : "FALSE");
+ skb_queue_len(&self->wx_list));
+ len += sprintf(buf+len, "rbusy: %s", self->remote_busy ?
+ "TRUE" : "FALSE");
+ len += sprintf(buf+len, " mbusy: %s\n", self->media_busy ?
+ "TRUE" : "FALSE");
len += sprintf(buf+len, " retrans: %d ", self->retry_count);
len += sprintf(buf+len, "vs: %d ", self->vs);
@@ -1135,42 +1180,42 @@
len += sprintf(buf+len, " qos\tbps\tmaxtt\tdsize\twinsize\taddbofs\tmintt\tldisc\tcomp\n");
len += sprintf(buf+len, " tx\t%d\t",
- self->qos_tx.baud_rate.value);
+ self->qos_tx.baud_rate.value);
len += sprintf(buf+len, "%d\t",
- self->qos_tx.max_turn_time.value);
+ self->qos_tx.max_turn_time.value);
len += sprintf(buf+len, "%d\t",
- self->qos_tx.data_size.value);
+ self->qos_tx.data_size.value);
len += sprintf(buf+len, "%d\t",
- self->qos_tx.window_size.value);
+ self->qos_tx.window_size.value);
len += sprintf(buf+len, "%d\t",
- self->qos_tx.additional_bofs.value);
+ self->qos_tx.additional_bofs.value);
len += sprintf(buf+len, "%d\t",
- self->qos_tx.min_turn_time.value);
+ self->qos_tx.min_turn_time.value);
len += sprintf(buf+len, "%d\t",
- self->qos_tx.link_disc_time.value);
+ self->qos_tx.link_disc_time.value);
#ifdef CONFIG_IRDA_COMPRESSION
len += sprintf(buf+len, "%d",
- self->qos_tx.compression.value);
+ self->qos_tx.compression.value);
#endif
len += sprintf(buf+len, "\n");
len += sprintf(buf+len, " rx\t%d\t",
- self->qos_rx.baud_rate.value);
+ self->qos_rx.baud_rate.value);
len += sprintf(buf+len, "%d\t",
- self->qos_rx.max_turn_time.value);
+ self->qos_rx.max_turn_time.value);
len += sprintf(buf+len, "%d\t",
- self->qos_rx.data_size.value);
+ self->qos_rx.data_size.value);
len += sprintf(buf+len, "%d\t",
- self->qos_rx.window_size.value);
+ self->qos_rx.window_size.value);
len += sprintf(buf+len, "%d\t",
- self->qos_rx.additional_bofs.value);
+ self->qos_rx.additional_bofs.value);
len += sprintf(buf+len, "%d\t",
- self->qos_rx.min_turn_time.value);
+ self->qos_rx.min_turn_time.value);
len += sprintf(buf+len, "%d\t",
- self->qos_rx.link_disc_time.value);
+ self->qos_rx.link_disc_time.value);
#ifdef CONFIG_IRDA_COMPRESSION
len += sprintf(buf+len, "%d",
- self->qos_rx.compression.value);
+ self->qos_rx.compression.value);
#endif
len += sprintf(buf+len, "\n");
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)