1/* 2 * Common data handling layer for ser_gigaset and usb_gigaset 3 * 4 * Copyright (c) 2005 by Tilman Schmidt <tilman@imap.cc>, 5 * Hansjoerg Lipp <hjlipp@web.de>, 6 * Stefan Eilers. 7 * 8 * ===================================================================== 9 * This program is free software; you can redistribute it and/or 10 * modify it under the terms of the GNU General Public License as 11 * published by the Free Software Foundation; either version 2 of 12 * the License, or (at your option) any later version. 13 * ===================================================================== 14 */ 15 16#include "gigaset.h" 17#include <linux/crc-ccitt.h> 18#include <linux/bitrev.h> 19#include <linux/export.h> 20 21/* check if byte must be stuffed/escaped 22 * I'm not sure which data should be encoded. 23 * Therefore I will go the hard way and encode every value 24 * less than 0x20, the flag sequence and the control escape char. 25 */ 26static inline int muststuff(unsigned char c) 27{ 28 if (c < PPP_TRANS) return 1; 29 if (c == PPP_FLAG) return 1; 30 if (c == PPP_ESCAPE) return 1; 31 /* other possible candidates: */ 32 /* 0x91: XON with parity set */ 33 /* 0x93: XOFF with parity set */ 34 return 0; 35} 36 37/* == data input =========================================================== */ 38 39/* process a block of received bytes in command mode 40 * (mstate != MS_LOCKED && (inputstate & INS_command)) 41 * Append received bytes to the command response buffer and forward them 42 * line by line to the response handler. Exit whenever a mode/state change 43 * might have occurred. 44 * Note: Received lines may be terminated by CR, LF, or CR LF, which will be 45 * removed before passing the line to the response handler. 46 * Return value: 47 * number of processed bytes 48 */ 49static unsigned cmd_loop(unsigned numbytes, struct inbuf_t *inbuf) 50{ 51 unsigned char *src = inbuf->data + inbuf->head; 52 struct cardstate *cs = inbuf->cs; 53 unsigned cbytes = cs->cbytes; 54 unsigned procbytes = 0; 55 unsigned char c; 56 57 while (procbytes < numbytes) { 58 c = *src++; 59 procbytes++; 60 61 switch (c) { 62 case '\n': 63 if (cbytes == 0 && cs->respdata[0] == '\r') { 64 /* collapse LF with preceding CR */ 65 cs->respdata[0] = 0; 66 break; 67 } 68 /* --v-- fall through --v-- */ 69 case '\r': 70 /* end of message line, pass to response handler */ 71 if (cbytes >= MAX_RESP_SIZE) { 72 dev_warn(cs->dev, "response too large (%d)\n", 73 cbytes); 74 cbytes = MAX_RESP_SIZE; 75 } 76 cs->cbytes = cbytes; 77 gigaset_dbg_buffer(DEBUG_TRANSCMD, "received response", 78 cbytes, cs->respdata); 79 gigaset_handle_modem_response(cs); 80 cbytes = 0; 81 82 /* store EOL byte for CRLF collapsing */ 83 cs->respdata[0] = c; 84 85 /* cs->dle may have changed */ 86 if (cs->dle && !(inbuf->inputstate & INS_DLE_command)) 87 inbuf->inputstate &= ~INS_command; 88 89 /* return for reevaluating state */ 90 goto exit; 91 92 case DLE_FLAG: 93 if (inbuf->inputstate & INS_DLE_char) { 94 /* quoted DLE: clear quote flag */ 95 inbuf->inputstate &= ~INS_DLE_char; 96 } else if (cs->dle || 97 (inbuf->inputstate & INS_DLE_command)) { 98 /* DLE escape, pass up for handling */ 99 inbuf->inputstate |= INS_DLE_char; 100 goto exit; 101 } 102 /* quoted or not in DLE mode: treat as regular data */ 103 /* --v-- fall through --v-- */ 104 default: 105 /* append to line buffer if possible */ 106 if (cbytes < MAX_RESP_SIZE) 107 cs->respdata[cbytes] = c; 108 cbytes++; 109 } 110 } 111exit: 112 cs->cbytes = cbytes; 113 return procbytes; 114} 115 116/* process a block of received bytes in lock mode 117 * All received bytes are passed unmodified to the tty i/f. 118 * Return value: 119 * number of processed bytes 120 */ 121static unsigned lock_loop(unsigned numbytes, struct inbuf_t *inbuf) 122{ 123 unsigned char *src = inbuf->data + inbuf->head; 124 125 gigaset_dbg_buffer(DEBUG_LOCKCMD, "received response", numbytes, src); 126 gigaset_if_receive(inbuf->cs, src, numbytes); 127 return numbytes; 128} 129 130/* process a block of received bytes in HDLC data mode 131 * (mstate != MS_LOCKED && !(inputstate & INS_command) && proto2 == L2_HDLC) 132 * Collect HDLC frames, undoing byte stuffing and watching for DLE escapes. 133 * When a frame is complete, check the FCS and pass valid frames to the LL. 134 * If DLE is encountered, return immediately to let the caller handle it. 135 * Return value: 136 * number of processed bytes 137 */ 138static unsigned hdlc_loop(unsigned numbytes, struct inbuf_t *inbuf) 139{ 140 struct cardstate *cs = inbuf->cs; 141 struct bc_state *bcs = cs->bcs; 142 int inputstate = bcs->inputstate; 143 __u16 fcs = bcs->rx_fcs; 144 struct sk_buff *skb = bcs->rx_skb; 145 unsigned char *src = inbuf->data + inbuf->head; 146 unsigned procbytes = 0; 147 unsigned char c; 148 149 if (inputstate & INS_byte_stuff) { 150 if (!numbytes) 151 return 0; 152 inputstate &= ~INS_byte_stuff; 153 goto byte_stuff; 154 } 155 156 while (procbytes < numbytes) { 157 c = *src++; 158 procbytes++; 159 if (c == DLE_FLAG) { 160 if (inputstate & INS_DLE_char) { 161 /* quoted DLE: clear quote flag */ 162 inputstate &= ~INS_DLE_char; 163 } else if (cs->dle || (inputstate & INS_DLE_command)) { 164 /* DLE escape, pass up for handling */ 165 inputstate |= INS_DLE_char; 166 break; 167 } 168 } 169 170 if (c == PPP_ESCAPE) { 171 /* byte stuffing indicator: pull in next byte */ 172 if (procbytes >= numbytes) { 173 /* end of buffer, save for later processing */ 174 inputstate |= INS_byte_stuff; 175 break; 176 } 177byte_stuff: 178 c = *src++; 179 procbytes++; 180 if (c == DLE_FLAG) { 181 if (inputstate & INS_DLE_char) { 182 /* quoted DLE: clear quote flag */ 183 inputstate &= ~INS_DLE_char; 184 } else if (cs->dle || 185 (inputstate & INS_DLE_command)) { 186 /* DLE escape, pass up for handling */ 187 inputstate |= 188 INS_DLE_char | INS_byte_stuff; 189 break; 190 } 191 } 192 c ^= PPP_TRANS; 193#ifdef CONFIG_GIGASET_DEBUG 194 if (!muststuff(c)) 195 gig_dbg(DEBUG_HDLC, "byte stuffed: 0x%02x", c); 196#endif 197 } else if (c == PPP_FLAG) { 198 /* end of frame: process content if any */ 199 if (inputstate & INS_have_data) { 200 gig_dbg(DEBUG_HDLC, 201 "7e----------------------------"); 202 203 /* check and pass received frame */ 204 if (!skb) { 205 /* skipped frame */ 206 gigaset_isdn_rcv_err(bcs); 207 } else if (skb->len < 2) { 208 /* frame too short for FCS */ 209 dev_warn(cs->dev, 210 "short frame (%d)\n", 211 skb->len); 212 gigaset_isdn_rcv_err(bcs); 213 dev_kfree_skb_any(skb); 214 } else if (fcs != PPP_GOODFCS) { 215 /* frame check error */ 216 dev_err(cs->dev, 217 "Checksum failed, %u bytes corrupted!\n", 218 skb->len); 219 gigaset_isdn_rcv_err(bcs); 220 dev_kfree_skb_any(skb); 221 } else { 222 /* good frame */ 223 __skb_trim(skb, skb->len - 2); 224 gigaset_skb_rcvd(bcs, skb); 225 } 226 227 /* prepare reception of next frame */ 228 inputstate &= ~INS_have_data; 229 skb = gigaset_new_rx_skb(bcs); 230 } else { 231 /* empty frame (7E 7E) */ 232#ifdef CONFIG_GIGASET_DEBUG 233 ++bcs->emptycount; 234#endif 235 if (!skb) { 236 /* skipped (?) */ 237 gigaset_isdn_rcv_err(bcs); 238 skb = gigaset_new_rx_skb(bcs); 239 } 240 } 241 242 fcs = PPP_INITFCS; 243 continue; 244#ifdef CONFIG_GIGASET_DEBUG 245 } else if (muststuff(c)) { 246 /* Should not happen. Possible after ZDLE=1<CR><LF>. */ 247 gig_dbg(DEBUG_HDLC, "not byte stuffed: 0x%02x", c); 248#endif 249 } 250 251 /* regular data byte, append to skb */ 252#ifdef CONFIG_GIGASET_DEBUG 253 if (!(inputstate & INS_have_data)) { 254 gig_dbg(DEBUG_HDLC, "7e (%d x) ================", 255 bcs->emptycount); 256 bcs->emptycount = 0; 257 } 258#endif 259 inputstate |= INS_have_data; 260 if (skb) { 261 if (skb->len >= bcs->rx_bufsize) { 262 dev_warn(cs->dev, "received packet too long\n"); 263 dev_kfree_skb_any(skb); 264 /* skip remainder of packet */ 265 bcs->rx_skb = skb = NULL; 266 } else { 267 *__skb_put(skb, 1) = c; 268 fcs = crc_ccitt_byte(fcs, c); 269 } 270 } 271 } 272 273 bcs->inputstate = inputstate; 274 bcs->rx_fcs = fcs; 275 return procbytes; 276} 277 278/* process a block of received bytes in transparent data mode 279 * (mstate != MS_LOCKED && !(inputstate & INS_command) && proto2 != L2_HDLC) 280 * Invert bytes, undoing byte stuffing and watching for DLE escapes. 281 * If DLE is encountered, return immediately to let the caller handle it. 282 * Return value: 283 * number of processed bytes 284 */ 285static unsigned iraw_loop(unsigned numbytes, struct inbuf_t *inbuf) 286{ 287 struct cardstate *cs = inbuf->cs; 288 struct bc_state *bcs = cs->bcs; 289 int inputstate = bcs->inputstate; 290 struct sk_buff *skb = bcs->rx_skb; 291 unsigned char *src = inbuf->data + inbuf->head; 292 unsigned procbytes = 0; 293 unsigned char c; 294 295 if (!skb) { 296 /* skip this block */ 297 gigaset_new_rx_skb(bcs); 298 return numbytes; 299 } 300 301 while (procbytes < numbytes && skb->len < bcs->rx_bufsize) { 302 c = *src++; 303 procbytes++; 304 305 if (c == DLE_FLAG) { 306 if (inputstate & INS_DLE_char) { 307 /* quoted DLE: clear quote flag */ 308 inputstate &= ~INS_DLE_char; 309 } else if (cs->dle || (inputstate & INS_DLE_command)) { 310 /* DLE escape, pass up for handling */ 311 inputstate |= INS_DLE_char; 312 break; 313 } 314 } 315 316 /* regular data byte: append to current skb */ 317 inputstate |= INS_have_data; 318 *__skb_put(skb, 1) = bitrev8(c); 319 } 320 321 /* pass data up */ 322 if (inputstate & INS_have_data) { 323 gigaset_skb_rcvd(bcs, skb); 324 inputstate &= ~INS_have_data; 325 gigaset_new_rx_skb(bcs); 326 } 327 328 bcs->inputstate = inputstate; 329 return procbytes; 330} 331 332/* process DLE escapes 333 * Called whenever a DLE sequence might be encountered in the input stream. 334 * Either processes the entire DLE sequence or, if that isn't possible, 335 * notes the fact that an initial DLE has been received in the INS_DLE_char 336 * inputstate flag and resumes processing of the sequence on the next call. 337 */ 338static void handle_dle(struct inbuf_t *inbuf) 339{ 340 struct cardstate *cs = inbuf->cs; 341 342 if (cs->mstate == MS_LOCKED) 343 return; /* no DLE processing in lock mode */ 344 345 if (!(inbuf->inputstate & INS_DLE_char)) { 346 /* no DLE pending */ 347 if (inbuf->data[inbuf->head] == DLE_FLAG && 348 (cs->dle || inbuf->inputstate & INS_DLE_command)) { 349 /* start of DLE sequence */ 350 inbuf->head++; 351 if (inbuf->head == inbuf->tail || 352 inbuf->head == RBUFSIZE) { 353 /* end of buffer, save for later processing */ 354 inbuf->inputstate |= INS_DLE_char; 355 return; 356 } 357 } else { 358 /* regular data byte */ 359 return; 360 } 361 } 362 363 /* consume pending DLE */ 364 inbuf->inputstate &= ~INS_DLE_char; 365 366 switch (inbuf->data[inbuf->head]) { 367 case 'X': /* begin of event message */ 368 if (inbuf->inputstate & INS_command) 369 dev_notice(cs->dev, 370 "received <DLE>X in command mode\n"); 371 inbuf->inputstate |= INS_command | INS_DLE_command; 372 inbuf->head++; /* byte consumed */ 373 break; 374 case '.': /* end of event message */ 375 if (!(inbuf->inputstate & INS_DLE_command)) 376 dev_notice(cs->dev, 377 "received <DLE>. without <DLE>X\n"); 378 inbuf->inputstate &= ~INS_DLE_command; 379 /* return to data mode if in DLE mode */ 380 if (cs->dle) 381 inbuf->inputstate &= ~INS_command; 382 inbuf->head++; /* byte consumed */ 383 break; 384 case DLE_FLAG: /* DLE in data stream */ 385 /* mark as quoted */ 386 inbuf->inputstate |= INS_DLE_char; 387 if (!(cs->dle || inbuf->inputstate & INS_DLE_command)) 388 dev_notice(cs->dev, 389 "received <DLE><DLE> not in DLE mode\n"); 390 break; /* quoted byte left in buffer */ 391 default: 392 dev_notice(cs->dev, "received <DLE><%02x>\n", 393 inbuf->data[inbuf->head]); 394 /* quoted byte left in buffer */ 395 } 396} 397 398/** 399 * gigaset_m10x_input() - process a block of data received from the device 400 * @inbuf: received data and device descriptor structure. 401 * 402 * Called by hardware module {ser,usb}_gigaset with a block of received 403 * bytes. Separates the bytes received over the serial data channel into 404 * user data and command replies (locked/unlocked) according to the 405 * current state of the interface. 406 */ 407void gigaset_m10x_input(struct inbuf_t *inbuf) 408{ 409 struct cardstate *cs = inbuf->cs; 410 unsigned numbytes, procbytes; 411 412 gig_dbg(DEBUG_INTR, "buffer state: %u -> %u", inbuf->head, inbuf->tail); 413 414 while (inbuf->head != inbuf->tail) { 415 /* check for DLE escape */ 416 handle_dle(inbuf); 417 418 /* process a contiguous block of bytes */ 419 numbytes = (inbuf->head > inbuf->tail ? 420 RBUFSIZE : inbuf->tail) - inbuf->head; 421 gig_dbg(DEBUG_INTR, "processing %u bytes", numbytes); 422 /* 423 * numbytes may be 0 if handle_dle() ate the last byte. 424 * This does no harm, *_loop() will just return 0 immediately. 425 */ 426 427 if (cs->mstate == MS_LOCKED) 428 procbytes = lock_loop(numbytes, inbuf); 429 else if (inbuf->inputstate & INS_command) 430 procbytes = cmd_loop(numbytes, inbuf); 431 else if (cs->bcs->proto2 == L2_HDLC) 432 procbytes = hdlc_loop(numbytes, inbuf); 433 else 434 procbytes = iraw_loop(numbytes, inbuf); 435 inbuf->head += procbytes; 436 437 /* check for buffer wraparound */ 438 if (inbuf->head >= RBUFSIZE) 439 inbuf->head = 0; 440 441 gig_dbg(DEBUG_INTR, "head set to %u", inbuf->head); 442 } 443} 444EXPORT_SYMBOL_GPL(gigaset_m10x_input); 445 446 447/* == data output ========================================================== */ 448 449/* 450 * Encode a data packet into an octet stuffed HDLC frame with FCS, 451 * opening and closing flags, preserving headroom data. 452 * parameters: 453 * skb skb containing original packet (freed upon return) 454 * Return value: 455 * pointer to newly allocated skb containing the result frame 456 * and the original link layer header, NULL on error 457 */ 458static struct sk_buff *HDLC_Encode(struct sk_buff *skb) 459{ 460 struct sk_buff *hdlc_skb; 461 __u16 fcs; 462 unsigned char c; 463 unsigned char *cp; 464 int len; 465 unsigned int stuf_cnt; 466 467 stuf_cnt = 0; 468 fcs = PPP_INITFCS; 469 cp = skb->data; 470 len = skb->len; 471 while (len--) { 472 if (muststuff(*cp)) 473 stuf_cnt++; 474 fcs = crc_ccitt_byte(fcs, *cp++); 475 } 476 fcs ^= 0xffff; /* complement */ 477 478 /* size of new buffer: original size + number of stuffing bytes 479 * + 2 bytes FCS + 2 stuffing bytes for FCS (if needed) + 2 flag bytes 480 * + room for link layer header 481 */ 482 hdlc_skb = dev_alloc_skb(skb->len + stuf_cnt + 6 + skb->mac_len); 483 if (!hdlc_skb) { 484 dev_kfree_skb_any(skb); 485 return NULL; 486 } 487 488 /* Copy link layer header into new skb */ 489 skb_reset_mac_header(hdlc_skb); 490 skb_reserve(hdlc_skb, skb->mac_len); 491 memcpy(skb_mac_header(hdlc_skb), skb_mac_header(skb), skb->mac_len); 492 hdlc_skb->mac_len = skb->mac_len; 493 494 /* Add flag sequence in front of everything.. */ 495 *(skb_put(hdlc_skb, 1)) = PPP_FLAG; 496 497 /* Perform byte stuffing while copying data. */ 498 while (skb->len--) { 499 if (muststuff(*skb->data)) { 500 *(skb_put(hdlc_skb, 1)) = PPP_ESCAPE; 501 *(skb_put(hdlc_skb, 1)) = (*skb->data++) ^ PPP_TRANS; 502 } else 503 *(skb_put(hdlc_skb, 1)) = *skb->data++; 504 } 505 506 /* Finally add FCS (byte stuffed) and flag sequence */ 507 c = (fcs & 0x00ff); /* least significant byte first */ 508 if (muststuff(c)) { 509 *(skb_put(hdlc_skb, 1)) = PPP_ESCAPE; 510 c ^= PPP_TRANS; 511 } 512 *(skb_put(hdlc_skb, 1)) = c; 513 514 c = ((fcs >> 8) & 0x00ff); 515 if (muststuff(c)) { 516 *(skb_put(hdlc_skb, 1)) = PPP_ESCAPE; 517 c ^= PPP_TRANS; 518 } 519 *(skb_put(hdlc_skb, 1)) = c; 520 521 *(skb_put(hdlc_skb, 1)) = PPP_FLAG; 522 523 dev_kfree_skb_any(skb); 524 return hdlc_skb; 525} 526 527/* 528 * Encode a data packet into an octet stuffed raw bit inverted frame, 529 * preserving headroom data. 530 * parameters: 531 * skb skb containing original packet (freed upon return) 532 * Return value: 533 * pointer to newly allocated skb containing the result frame 534 * and the original link layer header, NULL on error 535 */ 536static struct sk_buff *iraw_encode(struct sk_buff *skb) 537{ 538 struct sk_buff *iraw_skb; 539 unsigned char c; 540 unsigned char *cp; 541 int len; 542 543 /* size of new buffer (worst case = every byte must be stuffed): 544 * 2 * original size + room for link layer header 545 */ 546 iraw_skb = dev_alloc_skb(2 * skb->len + skb->mac_len); 547 if (!iraw_skb) { 548 dev_kfree_skb_any(skb); 549 return NULL; 550 } 551 552 /* copy link layer header into new skb */ 553 skb_reset_mac_header(iraw_skb); 554 skb_reserve(iraw_skb, skb->mac_len); 555 memcpy(skb_mac_header(iraw_skb), skb_mac_header(skb), skb->mac_len); 556 iraw_skb->mac_len = skb->mac_len; 557 558 /* copy and stuff data */ 559 cp = skb->data; 560 len = skb->len; 561 while (len--) { 562 c = bitrev8(*cp++); 563 if (c == DLE_FLAG) 564 *(skb_put(iraw_skb, 1)) = c; 565 *(skb_put(iraw_skb, 1)) = c; 566 } 567 dev_kfree_skb_any(skb); 568 return iraw_skb; 569} 570 571/** 572 * gigaset_m10x_send_skb() - queue an skb for sending 573 * @bcs: B channel descriptor structure. 574 * @skb: data to send. 575 * 576 * Called by LL to encode and queue an skb for sending, and start 577 * transmission if necessary. 578 * Once the payload data has been transmitted completely, gigaset_skb_sent() 579 * will be called with the skb's link layer header preserved. 580 * 581 * Return value: 582 * number of bytes accepted for sending (skb->len) if ok, 583 * error code < 0 (eg. -ENOMEM) on error 584 */ 585int gigaset_m10x_send_skb(struct bc_state *bcs, struct sk_buff *skb) 586{ 587 struct cardstate *cs = bcs->cs; 588 unsigned len = skb->len; 589 unsigned long flags; 590 591 if (bcs->proto2 == L2_HDLC) 592 skb = HDLC_Encode(skb); 593 else 594 skb = iraw_encode(skb); 595 if (!skb) { 596 dev_err(cs->dev, 597 "unable to allocate memory for encoding!\n"); 598 return -ENOMEM; 599 } 600 601 skb_queue_tail(&bcs->squeue, skb); 602 spin_lock_irqsave(&cs->lock, flags); 603 if (cs->connected) 604 tasklet_schedule(&cs->write_tasklet); 605 spin_unlock_irqrestore(&cs->lock, flags); 606 607 return len; /* ok so far */ 608} 609EXPORT_SYMBOL_GPL(gigaset_m10x_send_skb); 610