0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0013
0014 #include <linux/errno.h>
0015 #include <linux/types.h>
0016 #include <linux/socket.h>
0017 #include <linux/in.h>
0018 #include <linux/kernel.h>
0019 #include <linux/timer.h>
0020 #include <linux/string.h>
0021 #include <linux/sockios.h>
0022 #include <linux/net.h>
0023 #include <linux/inet.h>
0024 #include <linux/skbuff.h>
0025 #include <linux/slab.h>
0026 #include <net/sock.h>
0027 #include <linux/uaccess.h>
0028 #include <linux/fcntl.h>
0029 #include <linux/mm.h>
0030 #include <linux/interrupt.h>
0031 #include <net/lapb.h>
0032
0033
0034
0035
0036
0037 static void lapb_send_iframe(struct lapb_cb *lapb, struct sk_buff *skb, int poll_bit)
0038 {
0039 unsigned char *frame;
0040
0041 if (!skb)
0042 return;
0043
0044 if (lapb->mode & LAPB_EXTENDED) {
0045 frame = skb_push(skb, 2);
0046
0047 frame[0] = LAPB_I;
0048 frame[0] |= lapb->vs << 1;
0049 frame[1] = poll_bit ? LAPB_EPF : 0;
0050 frame[1] |= lapb->vr << 1;
0051 } else {
0052 frame = skb_push(skb, 1);
0053
0054 *frame = LAPB_I;
0055 *frame |= poll_bit ? LAPB_SPF : 0;
0056 *frame |= lapb->vr << 5;
0057 *frame |= lapb->vs << 1;
0058 }
0059
0060 lapb_dbg(1, "(%p) S%d TX I(%d) S%d R%d\n",
0061 lapb->dev, lapb->state, poll_bit, lapb->vs, lapb->vr);
0062
0063 lapb_transmit_buffer(lapb, skb, LAPB_COMMAND);
0064 }
0065
0066 void lapb_kick(struct lapb_cb *lapb)
0067 {
0068 struct sk_buff *skb, *skbn;
0069 unsigned short modulus, start, end;
0070
0071 modulus = (lapb->mode & LAPB_EXTENDED) ? LAPB_EMODULUS : LAPB_SMODULUS;
0072 start = !skb_peek(&lapb->ack_queue) ? lapb->va : lapb->vs;
0073 end = (lapb->va + lapb->window) % modulus;
0074
0075 if (!(lapb->condition & LAPB_PEER_RX_BUSY_CONDITION) &&
0076 start != end && skb_peek(&lapb->write_queue)) {
0077 lapb->vs = start;
0078
0079
0080
0081
0082 skb = skb_dequeue(&lapb->write_queue);
0083
0084 do {
0085 skbn = skb_copy(skb, GFP_ATOMIC);
0086 if (!skbn) {
0087 skb_queue_head(&lapb->write_queue, skb);
0088 break;
0089 }
0090
0091 if (skb->sk)
0092 skb_set_owner_w(skbn, skb->sk);
0093
0094
0095
0096
0097 lapb_send_iframe(lapb, skbn, LAPB_POLLOFF);
0098
0099 lapb->vs = (lapb->vs + 1) % modulus;
0100
0101
0102
0103
0104 skb_queue_tail(&lapb->ack_queue, skb);
0105
0106 } while (lapb->vs != end && (skb = skb_dequeue(&lapb->write_queue)) != NULL);
0107
0108 lapb->condition &= ~LAPB_ACK_PENDING_CONDITION;
0109
0110 if (!lapb_t1timer_running(lapb))
0111 lapb_start_t1timer(lapb);
0112 }
0113 }
0114
0115 void lapb_transmit_buffer(struct lapb_cb *lapb, struct sk_buff *skb, int type)
0116 {
0117 unsigned char *ptr;
0118
0119 ptr = skb_push(skb, 1);
0120
0121 if (lapb->mode & LAPB_MLP) {
0122 if (lapb->mode & LAPB_DCE) {
0123 if (type == LAPB_COMMAND)
0124 *ptr = LAPB_ADDR_C;
0125 if (type == LAPB_RESPONSE)
0126 *ptr = LAPB_ADDR_D;
0127 } else {
0128 if (type == LAPB_COMMAND)
0129 *ptr = LAPB_ADDR_D;
0130 if (type == LAPB_RESPONSE)
0131 *ptr = LAPB_ADDR_C;
0132 }
0133 } else {
0134 if (lapb->mode & LAPB_DCE) {
0135 if (type == LAPB_COMMAND)
0136 *ptr = LAPB_ADDR_A;
0137 if (type == LAPB_RESPONSE)
0138 *ptr = LAPB_ADDR_B;
0139 } else {
0140 if (type == LAPB_COMMAND)
0141 *ptr = LAPB_ADDR_B;
0142 if (type == LAPB_RESPONSE)
0143 *ptr = LAPB_ADDR_A;
0144 }
0145 }
0146
0147 lapb_dbg(2, "(%p) S%d TX %3ph\n", lapb->dev, lapb->state, skb->data);
0148
0149 if (!lapb_data_transmit(lapb, skb))
0150 kfree_skb(skb);
0151 }
0152
0153 void lapb_establish_data_link(struct lapb_cb *lapb)
0154 {
0155 lapb->condition = 0x00;
0156 lapb->n2count = 0;
0157
0158 if (lapb->mode & LAPB_EXTENDED) {
0159 lapb_dbg(1, "(%p) S%d TX SABME(1)\n", lapb->dev, lapb->state);
0160 lapb_send_control(lapb, LAPB_SABME, LAPB_POLLON, LAPB_COMMAND);
0161 } else {
0162 lapb_dbg(1, "(%p) S%d TX SABM(1)\n", lapb->dev, lapb->state);
0163 lapb_send_control(lapb, LAPB_SABM, LAPB_POLLON, LAPB_COMMAND);
0164 }
0165
0166 lapb_start_t1timer(lapb);
0167 lapb_stop_t2timer(lapb);
0168 }
0169
0170 void lapb_enquiry_response(struct lapb_cb *lapb)
0171 {
0172 lapb_dbg(1, "(%p) S%d TX RR(1) R%d\n",
0173 lapb->dev, lapb->state, lapb->vr);
0174
0175 lapb_send_control(lapb, LAPB_RR, LAPB_POLLON, LAPB_RESPONSE);
0176
0177 lapb->condition &= ~LAPB_ACK_PENDING_CONDITION;
0178 }
0179
0180 void lapb_timeout_response(struct lapb_cb *lapb)
0181 {
0182 lapb_dbg(1, "(%p) S%d TX RR(0) R%d\n",
0183 lapb->dev, lapb->state, lapb->vr);
0184 lapb_send_control(lapb, LAPB_RR, LAPB_POLLOFF, LAPB_RESPONSE);
0185
0186 lapb->condition &= ~LAPB_ACK_PENDING_CONDITION;
0187 }
0188
0189 void lapb_check_iframes_acked(struct lapb_cb *lapb, unsigned short nr)
0190 {
0191 if (lapb->vs == nr) {
0192 lapb_frames_acked(lapb, nr);
0193 lapb_stop_t1timer(lapb);
0194 lapb->n2count = 0;
0195 } else if (lapb->va != nr) {
0196 lapb_frames_acked(lapb, nr);
0197 lapb_start_t1timer(lapb);
0198 }
0199 }
0200
0201 void lapb_check_need_response(struct lapb_cb *lapb, int type, int pf)
0202 {
0203 if (type == LAPB_COMMAND && pf)
0204 lapb_enquiry_response(lapb);
0205 }