📄 qos.c
字号:
#ifdef CONFIG_IRDA_DYNAMIC_WINDOW while ((qos->data_size.value > line_capacity) && (index > 0)) { qos->data_size.value = data_sizes[index--]; IRDA_DEBUG(1, "%s(), reducing data size to %d\n", __FUNCTION__, qos->data_size.value); }#else /* Use method described in section 6.6.11 of IrLAP */ while (irlap_requested_line_capacity(qos) > line_capacity) { IRDA_ASSERT(index != 0, return;); /* Must be able to send at least one frame */ if (qos->window_size.value > 1) { qos->window_size.value--; IRDA_DEBUG(4, "%s(), reducing window size to %d\n", __FUNCTION__, qos->window_size.value); } else if (index > 1) { qos->data_size.value = data_sizes[index--]; IRDA_DEBUG(4, "%s(), reducing data size to %d\n", __FUNCTION__, qos->data_size.value); } else { IRDA_WARNING("%s(), nothing more we can do!\n", __FUNCTION__); } }#endif /* CONFIG_IRDA_DYNAMIC_WINDOW */ /* * Fix tx data size according to user limits - Jean II */ if (qos->data_size.value > sysctl_max_tx_data_size) /* Allow non discrete adjustement to avoid loosing capacity */ qos->data_size.value = sysctl_max_tx_data_size; /* * Override Tx window if user request it. - Jean II */ if (qos->window_size.value > sysctl_max_tx_window) qos->window_size.value = sysctl_max_tx_window;}/** Function irlap_negotiate (qos_device, qos_session, skb)** Negotiate QoS values, not really that much negotiation :-)* We just set the QoS capabilities for the peer station**/int irlap_qos_negotiate(struct irlap_cb *self, struct sk_buff *skb){ int ret; ret = irda_param_extract_all(self, skb->data, skb->len, &irlap_param_info); /* Convert the negotiated bits to values */ irda_qos_bits_to_value(&self->qos_tx); irda_qos_bits_to_value(&self->qos_rx); irlap_adjust_qos_settings(&self->qos_tx); IRDA_DEBUG(1, "Setting BAUD_RATE to %d bps.\n", self->qos_tx.baud_rate.value); IRDA_DEBUG(1, "Setting DATA_SIZE to %d bytes\n", self->qos_tx.data_size.value); IRDA_DEBUG(1, "Setting WINDOW_SIZE to %d\n", self->qos_tx.window_size.value); IRDA_DEBUG(1, "Setting XBOFS to %d\n", self->qos_tx.additional_bofs.value); IRDA_DEBUG(1, "Setting MAX_TURN_TIME to %d ms.\n", self->qos_tx.max_turn_time.value); IRDA_DEBUG(1, "Setting MIN_TURN_TIME to %d usecs.\n", self->qos_tx.min_turn_time.value); IRDA_DEBUG(1, "Setting LINK_DISC to %d secs.\n", self->qos_tx.link_disc_time.value); return ret;}/** Function irlap_insert_negotiation_params (qos, fp)** Insert QoS negotiaion pararameters into frame**/int irlap_insert_qos_negotiation_params(struct irlap_cb *self, struct sk_buff *skb){ int ret; /* Insert data rate */ ret = irda_param_insert(self, PI_BAUD_RATE, skb_tail_pointer(skb), skb_tailroom(skb), &irlap_param_info); if (ret < 0) return ret; skb_put(skb, ret); /* Insert max turnaround time */ ret = irda_param_insert(self, PI_MAX_TURN_TIME, skb_tail_pointer(skb), skb_tailroom(skb), &irlap_param_info); if (ret < 0) return ret; skb_put(skb, ret); /* Insert data size */ ret = irda_param_insert(self, PI_DATA_SIZE, skb_tail_pointer(skb), skb_tailroom(skb), &irlap_param_info); if (ret < 0) return ret; skb_put(skb, ret); /* Insert window size */ ret = irda_param_insert(self, PI_WINDOW_SIZE, skb_tail_pointer(skb), skb_tailroom(skb), &irlap_param_info); if (ret < 0) return ret; skb_put(skb, ret); /* Insert additional BOFs */ ret = irda_param_insert(self, PI_ADD_BOFS, skb_tail_pointer(skb), skb_tailroom(skb), &irlap_param_info); if (ret < 0) return ret; skb_put(skb, ret); /* Insert minimum turnaround time */ ret = irda_param_insert(self, PI_MIN_TURN_TIME, skb_tail_pointer(skb), skb_tailroom(skb), &irlap_param_info); if (ret < 0) return ret; skb_put(skb, ret); /* Insert link disconnect/threshold time */ ret = irda_param_insert(self, PI_LINK_DISC, skb_tail_pointer(skb), skb_tailroom(skb), &irlap_param_info); if (ret < 0) return ret; skb_put(skb, ret); return 0;}/** Function irlap_param_baud_rate (instance, param, get)** Negotiate data-rate**/static int irlap_param_baud_rate(void *instance, irda_param_t *param, int get){ __u16 final; struct irlap_cb *self = (struct irlap_cb *) instance; IRDA_ASSERT(self != NULL, return -1;); IRDA_ASSERT(self->magic == LAP_MAGIC, return -1;); if (get) { param->pv.i = self->qos_rx.baud_rate.bits; IRDA_DEBUG(2, "%s(), baud rate = 0x%02x\n", __FUNCTION__, param->pv.i); } else { /* * Stations must agree on baud rate, so calculate * intersection */ IRDA_DEBUG(2, "Requested BAUD_RATE: 0x%04x\n", (__u16) param->pv.i); final = (__u16) param->pv.i & self->qos_rx.baud_rate.bits; IRDA_DEBUG(2, "Final BAUD_RATE: 0x%04x\n", final); self->qos_tx.baud_rate.bits = final; self->qos_rx.baud_rate.bits = final; } return 0;}/** Function irlap_param_link_disconnect (instance, param, get)** Negotiate link disconnect/threshold time.**/static int irlap_param_link_disconnect(void *instance, irda_param_t *param, int get){ __u16 final; struct irlap_cb *self = (struct irlap_cb *) instance; IRDA_ASSERT(self != NULL, return -1;); IRDA_ASSERT(self->magic == LAP_MAGIC, return -1;); if (get) param->pv.i = self->qos_rx.link_disc_time.bits; else { /* * Stations must agree on link disconnect/threshold * time. */ IRDA_DEBUG(2, "LINK_DISC: %02x\n", (__u8) param->pv.i); final = (__u8) param->pv.i & self->qos_rx.link_disc_time.bits; IRDA_DEBUG(2, "Final LINK_DISC: %02x\n", final); self->qos_tx.link_disc_time.bits = final; self->qos_rx.link_disc_time.bits = final; } return 0;}/** Function irlap_param_max_turn_time (instance, param, get)** Negotiate the maximum turnaround time. This is a type 1 parameter and* will be negotiated independently for each station**/static int irlap_param_max_turn_time(void *instance, irda_param_t *param, int get){ struct irlap_cb *self = (struct irlap_cb *) instance; IRDA_ASSERT(self != NULL, return -1;); IRDA_ASSERT(self->magic == LAP_MAGIC, return -1;); if (get) param->pv.i = self->qos_rx.max_turn_time.bits; else self->qos_tx.max_turn_time.bits = (__u8) param->pv.i; return 0;}/** Function irlap_param_data_size (instance, param, get)** Negotiate the data size. This is a type 1 parameter and* will be negotiated independently for each station**/static int irlap_param_data_size(void *instance, irda_param_t *param, int get){ struct irlap_cb *self = (struct irlap_cb *) instance; IRDA_ASSERT(self != NULL, return -1;); IRDA_ASSERT(self->magic == LAP_MAGIC, return -1;); if (get) param->pv.i = self->qos_rx.data_size.bits; else self->qos_tx.data_size.bits = (__u8) param->pv.i; return 0;}/** Function irlap_param_window_size (instance, param, get)** Negotiate the window size. This is a type 1 parameter and* will be negotiated independently for each station**/static int irlap_param_window_size(void *instance, irda_param_t *param, int get){ struct irlap_cb *self = (struct irlap_cb *) instance; IRDA_ASSERT(self != NULL, return -1;); IRDA_ASSERT(self->magic == LAP_MAGIC, return -1;); if (get) param->pv.i = self->qos_rx.window_size.bits; else self->qos_tx.window_size.bits = (__u8) param->pv.i; return 0;}/** Function irlap_param_additional_bofs (instance, param, get)** Negotiate additional BOF characters. This is a type 1 parameter and* will be negotiated independently for each station.*/static int irlap_param_additional_bofs(void *instance, irda_param_t *param, int get){ struct irlap_cb *self = (struct irlap_cb *) instance; IRDA_ASSERT(self != NULL, return -1;); IRDA_ASSERT(self->magic == LAP_MAGIC, return -1;); if (get) param->pv.i = self->qos_rx.additional_bofs.bits; else self->qos_tx.additional_bofs.bits = (__u8) param->pv.i; return 0;}/** Function irlap_param_min_turn_time (instance, param, get)** Negotiate the minimum turn around time. This is a type 1 parameter and* will be negotiated independently for each station*/static int irlap_param_min_turn_time(void *instance, irda_param_t *param, int get){ struct irlap_cb *self = (struct irlap_cb *) instance; IRDA_ASSERT(self != NULL, return -1;); IRDA_ASSERT(self->magic == LAP_MAGIC, return -1;); if (get) param->pv.i = self->qos_rx.min_turn_time.bits; else self->qos_tx.min_turn_time.bits = (__u8) param->pv.i; return 0;}/** Function irlap_max_line_capacity (speed, max_turn_time, min_turn_time)** Calculate the maximum line capacity**/__u32 irlap_max_line_capacity(__u32 speed, __u32 max_turn_time){ __u32 line_capacity; int i,j; IRDA_DEBUG(2, "%s(), speed=%d, max_turn_time=%d\n", __FUNCTION__, speed, max_turn_time); i = value_index(speed, baud_rates, 10); j = value_index(max_turn_time, max_turn_times, 4); IRDA_ASSERT(((i >=0) && (i <10)), return 0;); IRDA_ASSERT(((j >=0) && (j <4)), return 0;); line_capacity = max_line_capacities[i][j]; IRDA_DEBUG(2, "%s(), line capacity=%d bytes\n", __FUNCTION__, line_capacity); return line_capacity;}#ifndef CONFIG_IRDA_DYNAMIC_WINDOWstatic __u32 irlap_requested_line_capacity(struct qos_info *qos){ __u32 line_capacity; line_capacity = qos->window_size.value * (qos->data_size.value + 6 + qos->additional_bofs.value) + irlap_min_turn_time_in_bytes(qos->baud_rate.value, qos->min_turn_time.value); IRDA_DEBUG(2, "%s(), requested line capacity=%d\n", __FUNCTION__, line_capacity); return line_capacity;}#endifvoid irda_qos_bits_to_value(struct qos_info *qos){ int index; IRDA_ASSERT(qos != NULL, return;); index = msb_index(qos->baud_rate.bits); qos->baud_rate.value = baud_rates[index]; index = msb_index(qos->data_size.bits); qos->data_size.value = data_sizes[index]; index = msb_index(qos->window_size.bits); qos->window_size.value = index+1; index = msb_index(qos->min_turn_time.bits); qos->min_turn_time.value = min_turn_times[index]; index = msb_index(qos->max_turn_time.bits); qos->max_turn_time.value = max_turn_times[index]; index = msb_index(qos->link_disc_time.bits); qos->link_disc_time.value = link_disc_times[index]; index = msb_index(qos->additional_bofs.bits); qos->additional_bofs.value = add_bofs[index];}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -