aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/isdn/gigaset/asyncdata.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/isdn/gigaset/asyncdata.c')
-rw-r--r--drivers/isdn/gigaset/asyncdata.c124
1 files changed, 58 insertions, 66 deletions
diff --git a/drivers/isdn/gigaset/asyncdata.c b/drivers/isdn/gigaset/asyncdata.c
index 44a58e6f8f65..a25216bf475e 100644
--- a/drivers/isdn/gigaset/asyncdata.c
+++ b/drivers/isdn/gigaset/asyncdata.c
@@ -119,10 +119,7 @@ static inline int hdlc_loop(unsigned char c, unsigned char *src, int numbytes,
119 int inputstate = bcs->inputstate; 119 int inputstate = bcs->inputstate;
120 __u16 fcs = bcs->fcs; 120 __u16 fcs = bcs->fcs;
121 struct sk_buff *skb = bcs->skb; 121 struct sk_buff *skb = bcs->skb;
122 unsigned char error;
123 struct sk_buff *compskb;
124 int startbytes = numbytes; 122 int startbytes = numbytes;
125 int l;
126 123
127 if (unlikely(inputstate & INS_byte_stuff)) { 124 if (unlikely(inputstate & INS_byte_stuff)) {
128 inputstate &= ~INS_byte_stuff; 125 inputstate &= ~INS_byte_stuff;
@@ -158,8 +155,8 @@ byte_stuff:
158#endif 155#endif
159 156
160 /* end of frame */ 157 /* end of frame */
161 error = 1; 158 gigaset_isdn_rcv_err(bcs);
162 gigaset_rcv_error(NULL, cs, bcs); 159 dev_kfree_skb(skb);
163 } else if (!(inputstate & INS_have_data)) { /* 7E 7E */ 160 } else if (!(inputstate & INS_have_data)) { /* 7E 7E */
164#ifdef CONFIG_GIGASET_DEBUG 161#ifdef CONFIG_GIGASET_DEBUG
165 ++bcs->emptycount; 162 ++bcs->emptycount;
@@ -170,54 +167,39 @@ byte_stuff:
170 "7e----------------------------"); 167 "7e----------------------------");
171 168
172 /* end of frame */ 169 /* end of frame */
173 error = 0;
174
175 if (unlikely(fcs != PPP_GOODFCS)) { 170 if (unlikely(fcs != PPP_GOODFCS)) {
176 dev_err(cs->dev, 171 dev_err(cs->dev,
177 "Checksum failed, %u bytes corrupted!\n", 172 "Checksum failed, %u bytes corrupted!\n",
178 skb->len); 173 skb->len);
179 compskb = NULL; 174 gigaset_isdn_rcv_err(bcs);
180 gigaset_rcv_error(compskb, cs, bcs); 175 dev_kfree_skb(skb);
181 error = 1; 176 } else if (likely(skb->len > 2)) {
177 __skb_trim(skb, skb->len - 2);
178 gigaset_skb_rcvd(bcs, skb);
182 } else { 179 } else {
183 if (likely((l = skb->len) > 2)) { 180 if (skb->len) {
184 skb->tail -= 2; 181 dev_err(cs->dev,
185 skb->len -= 2; 182 "invalid packet size (%d)\n", skb->len);
186 } else { 183 gigaset_isdn_rcv_err(bcs);
187 dev_kfree_skb(skb);
188 skb = NULL;
189 inputstate |= INS_skip_frame;
190 if (l == 1) {
191 dev_err(cs->dev,
192 "invalid packet size (1)!\n");
193 error = 1;
194 gigaset_rcv_error(NULL,
195 cs, bcs);
196 }
197 }
198 if (likely(!(error ||
199 (inputstate &
200 INS_skip_frame)))) {
201 gigaset_rcv_skb(skb, cs, bcs);
202 } 184 }
185 dev_kfree_skb(skb);
203 } 186 }
204 } 187 }
205 188
206 if (unlikely(error))
207 if (skb)
208 dev_kfree_skb(skb);
209
210 fcs = PPP_INITFCS; 189 fcs = PPP_INITFCS;
211 inputstate &= ~(INS_have_data | INS_skip_frame); 190 inputstate &= ~(INS_have_data | INS_skip_frame);
212 if (unlikely(bcs->ignore)) { 191 if (unlikely(bcs->ignore)) {
213 inputstate |= INS_skip_frame; 192 inputstate |= INS_skip_frame;
214 skb = NULL; 193 skb = NULL;
215 } else if (likely((skb = dev_alloc_skb(SBUFSIZE + HW_HDR_LEN)) != NULL)) {
216 skb_reserve(skb, HW_HDR_LEN);
217 } else { 194 } else {
218 dev_warn(cs->dev, 195 skb = dev_alloc_skb(SBUFSIZE + cs->hw_hdr_len);
219 "could not allocate new skb\n"); 196 if (skb != NULL) {
220 inputstate |= INS_skip_frame; 197 skb_reserve(skb, cs->hw_hdr_len);
198 } else {
199 dev_warn(cs->dev,
200 "could not allocate new skb\n");
201 inputstate |= INS_skip_frame;
202 }
221 } 203 }
222 204
223 break; 205 break;
@@ -314,18 +296,21 @@ static inline int iraw_loop(unsigned char c, unsigned char *src, int numbytes,
314 /* pass data up */ 296 /* pass data up */
315 if (likely(inputstate & INS_have_data)) { 297 if (likely(inputstate & INS_have_data)) {
316 if (likely(!(inputstate & INS_skip_frame))) { 298 if (likely(!(inputstate & INS_skip_frame))) {
317 gigaset_rcv_skb(skb, cs, bcs); 299 gigaset_skb_rcvd(bcs, skb);
318 } 300 }
319 inputstate &= ~(INS_have_data | INS_skip_frame); 301 inputstate &= ~(INS_have_data | INS_skip_frame);
320 if (unlikely(bcs->ignore)) { 302 if (unlikely(bcs->ignore)) {
321 inputstate |= INS_skip_frame; 303 inputstate |= INS_skip_frame;
322 skb = NULL; 304 skb = NULL;
323 } else if (likely((skb = dev_alloc_skb(SBUFSIZE + HW_HDR_LEN))
324 != NULL)) {
325 skb_reserve(skb, HW_HDR_LEN);
326 } else { 305 } else {
327 dev_warn(cs->dev, "could not allocate new skb\n"); 306 skb = dev_alloc_skb(SBUFSIZE + cs->hw_hdr_len);
328 inputstate |= INS_skip_frame; 307 if (skb != NULL) {
308 skb_reserve(skb, cs->hw_hdr_len);
309 } else {
310 dev_warn(cs->dev,
311 "could not allocate new skb\n");
312 inputstate |= INS_skip_frame;
313 }
329 } 314 }
330 } 315 }
331 316
@@ -383,7 +368,7 @@ void gigaset_m10x_input(struct inbuf_t *inbuf)
383 /* FIXME use function pointers? */ 368 /* FIXME use function pointers? */
384 if (inbuf->inputstate & INS_command) 369 if (inbuf->inputstate & INS_command)
385 procbytes = cmd_loop(c, src, numbytes, inbuf); 370 procbytes = cmd_loop(c, src, numbytes, inbuf);
386 else if (inbuf->bcs->proto2 == ISDN_PROTO_L2_HDLC) 371 else if (inbuf->bcs->proto2 == L2_HDLC)
387 procbytes = hdlc_loop(c, src, numbytes, inbuf); 372 procbytes = hdlc_loop(c, src, numbytes, inbuf);
388 else 373 else
389 procbytes = iraw_loop(c, src, numbytes, inbuf); 374 procbytes = iraw_loop(c, src, numbytes, inbuf);
@@ -440,16 +425,16 @@ EXPORT_SYMBOL_GPL(gigaset_m10x_input);
440 425
441/* == data output ========================================================== */ 426/* == data output ========================================================== */
442 427
443/* Encoding of a PPP packet into an octet stuffed HDLC frame 428/*
444 * with FCS, opening and closing flags. 429 * Encode a data packet into an octet stuffed HDLC frame with FCS,
430 * opening and closing flags, preserving headroom data.
445 * parameters: 431 * parameters:
446 * skb skb containing original packet (freed upon return) 432 * skb skb containing original packet (freed upon return)
447 * head number of headroom bytes to allocate in result skb 433 * headroom number of headroom bytes to preserve
448 * tail number of tailroom bytes to allocate in result skb
449 * Return value: 434 * Return value:
450 * pointer to newly allocated skb containing the result frame 435 * pointer to newly allocated skb containing the result frame
451 */ 436 */
452static struct sk_buff *HDLC_Encode(struct sk_buff *skb, int head, int tail) 437static struct sk_buff *HDLC_Encode(struct sk_buff *skb, int headroom)
453{ 438{
454 struct sk_buff *hdlc_skb; 439 struct sk_buff *hdlc_skb;
455 __u16 fcs; 440 __u16 fcs;
@@ -471,16 +456,17 @@ static struct sk_buff *HDLC_Encode(struct sk_buff *skb, int head, int tail)
471 456
472 /* size of new buffer: original size + number of stuffing bytes 457 /* size of new buffer: original size + number of stuffing bytes
473 * + 2 bytes FCS + 2 stuffing bytes for FCS (if needed) + 2 flag bytes 458 * + 2 bytes FCS + 2 stuffing bytes for FCS (if needed) + 2 flag bytes
459 * + room for acknowledgement header
474 */ 460 */
475 hdlc_skb = dev_alloc_skb(skb->len + stuf_cnt + 6 + tail + head); 461 hdlc_skb = dev_alloc_skb(skb->len + stuf_cnt + 6 + headroom);
476 if (!hdlc_skb) { 462 if (!hdlc_skb) {
477 dev_kfree_skb(skb); 463 dev_kfree_skb(skb);
478 return NULL; 464 return NULL;
479 } 465 }
480 skb_reserve(hdlc_skb, head);
481 466
482 /* Copy acknowledge request into new skb */ 467 /* Copy acknowledgement header into new skb */
483 memcpy(hdlc_skb->head, skb->head, 2); 468 skb_reserve(hdlc_skb, headroom);
469 memcpy(hdlc_skb->head, skb->head, headroom);
484 470
485 /* Add flag sequence in front of everything.. */ 471 /* Add flag sequence in front of everything.. */
486 *(skb_put(hdlc_skb, 1)) = PPP_FLAG; 472 *(skb_put(hdlc_skb, 1)) = PPP_FLAG;
@@ -515,15 +501,16 @@ static struct sk_buff *HDLC_Encode(struct sk_buff *skb, int head, int tail)
515 return hdlc_skb; 501 return hdlc_skb;
516} 502}
517 503
518/* Encoding of a raw packet into an octet stuffed bit inverted frame 504/*
505 * Encode a data packet into an octet stuffed raw bit inverted frame,
506 * preserving headroom data.
519 * parameters: 507 * parameters:
520 * skb skb containing original packet (freed upon return) 508 * skb skb containing original packet (freed upon return)
521 * head number of headroom bytes to allocate in result skb 509 * headroom number of headroom bytes to preserve
522 * tail number of tailroom bytes to allocate in result skb
523 * Return value: 510 * Return value:
524 * pointer to newly allocated skb containing the result frame 511 * pointer to newly allocated skb containing the result frame
525 */ 512 */
526static struct sk_buff *iraw_encode(struct sk_buff *skb, int head, int tail) 513static struct sk_buff *iraw_encode(struct sk_buff *skb, int headroom)
527{ 514{
528 struct sk_buff *iraw_skb; 515 struct sk_buff *iraw_skb;
529 unsigned char c; 516 unsigned char c;
@@ -531,12 +518,15 @@ static struct sk_buff *iraw_encode(struct sk_buff *skb, int head, int tail)
531 int len; 518 int len;
532 519
533 /* worst case: every byte must be stuffed */ 520 /* worst case: every byte must be stuffed */
534 iraw_skb = dev_alloc_skb(2*skb->len + tail + head); 521 iraw_skb = dev_alloc_skb(2*skb->len + headroom);
535 if (!iraw_skb) { 522 if (!iraw_skb) {
536 dev_kfree_skb(skb); 523 dev_kfree_skb(skb);
537 return NULL; 524 return NULL;
538 } 525 }
539 skb_reserve(iraw_skb, head); 526
527 /* Copy acknowledgement header into new skb */
528 skb_reserve(iraw_skb, headroom);
529 memcpy(iraw_skb->head, skb->head, headroom);
540 530
541 cp = skb->data; 531 cp = skb->data;
542 len = skb->len; 532 len = skb->len;
@@ -555,8 +545,10 @@ static struct sk_buff *iraw_encode(struct sk_buff *skb, int head, int tail)
555 * @bcs: B channel descriptor structure. 545 * @bcs: B channel descriptor structure.
556 * @skb: data to send. 546 * @skb: data to send.
557 * 547 *
558 * Called by i4l.c to encode and queue an skb for sending, and start 548 * Called by LL to encode and queue an skb for sending, and start
559 * transmission if necessary. 549 * transmission if necessary.
550 * Once the payload data has been transmitted completely, gigaset_skb_sent()
551 * will be called with the first cs->hw_hdr_len bytes of skb->head preserved.
560 * 552 *
561 * Return value: 553 * Return value:
562 * number of bytes accepted for sending (skb->len) if ok, 554 * number of bytes accepted for sending (skb->len) if ok,
@@ -567,10 +559,10 @@ int gigaset_m10x_send_skb(struct bc_state *bcs, struct sk_buff *skb)
567 unsigned len = skb->len; 559 unsigned len = skb->len;
568 unsigned long flags; 560 unsigned long flags;
569 561
570 if (bcs->proto2 == ISDN_PROTO_L2_HDLC) 562 if (bcs->proto2 == L2_HDLC)
571 skb = HDLC_Encode(skb, HW_HDR_LEN, 0); 563 skb = HDLC_Encode(skb, bcs->cs->hw_hdr_len);
572 else 564 else
573 skb = iraw_encode(skb, HW_HDR_LEN, 0); 565 skb = iraw_encode(skb, bcs->cs->hw_hdr_len);
574 if (!skb) { 566 if (!skb) {
575 dev_err(bcs->cs->dev, 567 dev_err(bcs->cs->dev,
576 "unable to allocate memory for encoding!\n"); 568 "unable to allocate memory for encoding!\n");