1 /* 2 * 3 * Author Karsten Keil <kkeil@novell.com> 4 * 5 * Copyright 2008 by Karsten Keil <kkeil@novell.com> 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License version 2 as 9 * published by the Free Software Foundation. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 */ 17 18 #include <linux/gfp.h> 19 #include <linux/module.h> 20 #include <linux/mISDNhw.h> 21 22 static void 23 dchannel_bh(struct work_struct *ws) 24 { 25 struct dchannel *dch = container_of(ws, struct dchannel, workq); 26 struct sk_buff *skb; 27 int err; 28 29 if (test_and_clear_bit(FLG_RECVQUEUE, &dch->Flags)) { 30 while ((skb = skb_dequeue(&dch->rqueue))) { 31 if (likely(dch->dev.D.peer)) { 32 err = dch->dev.D.recv(dch->dev.D.peer, skb); 33 if (err) 34 dev_kfree_skb(skb); 35 } else 36 dev_kfree_skb(skb); 37 } 38 } 39 if (test_and_clear_bit(FLG_PHCHANGE, &dch->Flags)) { 40 if (dch->phfunc) 41 dch->phfunc(dch); 42 } 43 } 44 45 static void 46 bchannel_bh(struct work_struct *ws) 47 { 48 struct bchannel *bch = container_of(ws, struct bchannel, workq); 49 struct sk_buff *skb; 50 int err; 51 52 if (test_and_clear_bit(FLG_RECVQUEUE, &bch->Flags)) { 53 while ((skb = skb_dequeue(&bch->rqueue))) { 54 bch->rcount--; 55 if (likely(bch->ch.peer)) { 56 err = bch->ch.recv(bch->ch.peer, skb); 57 if (err) 58 dev_kfree_skb(skb); 59 } else 60 dev_kfree_skb(skb); 61 } 62 } 63 } 64 65 int 66 mISDN_initdchannel(struct dchannel *ch, int maxlen, void *phf) 67 { 68 test_and_set_bit(FLG_HDLC, &ch->Flags); 69 ch->maxlen = maxlen; 70 ch->hw = NULL; 71 ch->rx_skb = NULL; 72 ch->tx_skb = NULL; 73 ch->tx_idx = 0; 74 ch->phfunc = phf; 75 skb_queue_head_init(&ch->squeue); 76 skb_queue_head_init(&ch->rqueue); 77 INIT_LIST_HEAD(&ch->dev.bchannels); 78 INIT_WORK(&ch->workq, dchannel_bh); 79 return 0; 80 } 81 EXPORT_SYMBOL(mISDN_initdchannel); 82 83 int 84 mISDN_initbchannel(struct bchannel *ch, unsigned short maxlen, 85 unsigned short minlen) 86 { 87 ch->Flags = 0; 88 ch->minlen = minlen; 89 ch->next_minlen = minlen; 90 ch->init_minlen = minlen; 91 ch->maxlen = maxlen; 92 ch->next_maxlen = maxlen; 93 ch->init_maxlen = maxlen; 94 ch->hw = NULL; 95 ch->rx_skb = NULL; 96 ch->tx_skb = NULL; 97 ch->tx_idx = 0; 98 skb_queue_head_init(&ch->rqueue); 99 ch->rcount = 0; 100 ch->next_skb = NULL; 101 INIT_WORK(&ch->workq, bchannel_bh); 102 return 0; 103 } 104 EXPORT_SYMBOL(mISDN_initbchannel); 105 106 int 107 mISDN_freedchannel(struct dchannel *ch) 108 { 109 if (ch->tx_skb) { 110 dev_kfree_skb(ch->tx_skb); 111 ch->tx_skb = NULL; 112 } 113 if (ch->rx_skb) { 114 dev_kfree_skb(ch->rx_skb); 115 ch->rx_skb = NULL; 116 } 117 skb_queue_purge(&ch->squeue); 118 skb_queue_purge(&ch->rqueue); 119 flush_work_sync(&ch->workq); 120 return 0; 121 } 122 EXPORT_SYMBOL(mISDN_freedchannel); 123 124 void 125 mISDN_clear_bchannel(struct bchannel *ch) 126 { 127 if (ch->tx_skb) { 128 dev_kfree_skb(ch->tx_skb); 129 ch->tx_skb = NULL; 130 } 131 ch->tx_idx = 0; 132 if (ch->rx_skb) { 133 dev_kfree_skb(ch->rx_skb); 134 ch->rx_skb = NULL; 135 } 136 if (ch->next_skb) { 137 dev_kfree_skb(ch->next_skb); 138 ch->next_skb = NULL; 139 } 140 test_and_clear_bit(FLG_TX_BUSY, &ch->Flags); 141 test_and_clear_bit(FLG_TX_NEXT, &ch->Flags); 142 test_and_clear_bit(FLG_ACTIVE, &ch->Flags); 143 test_and_clear_bit(FLG_FILLEMPTY, &ch->Flags); 144 test_and_clear_bit(FLG_TX_EMPTY, &ch->Flags); 145 test_and_clear_bit(FLG_RX_OFF, &ch->Flags); 146 ch->dropcnt = 0; 147 ch->minlen = ch->init_minlen; 148 ch->next_minlen = ch->init_minlen; 149 ch->maxlen = ch->init_maxlen; 150 ch->next_maxlen = ch->init_maxlen; 151 } 152 EXPORT_SYMBOL(mISDN_clear_bchannel); 153 154 int 155 mISDN_freebchannel(struct bchannel *ch) 156 { 157 mISDN_clear_bchannel(ch); 158 skb_queue_purge(&ch->rqueue); 159 ch->rcount = 0; 160 flush_work_sync(&ch->workq); 161 return 0; 162 } 163 EXPORT_SYMBOL(mISDN_freebchannel); 164 165 int 166 mISDN_ctrl_bchannel(struct bchannel *bch, struct mISDN_ctrl_req *cq) 167 { 168 int ret = 0; 169 170 switch (cq->op) { 171 case MISDN_CTRL_GETOP: 172 cq->op = MISDN_CTRL_RX_BUFFER | MISDN_CTRL_FILL_EMPTY | 173 MISDN_CTRL_RX_OFF; 174 break; 175 case MISDN_CTRL_FILL_EMPTY: 176 if (cq->p1) { 177 memset(bch->fill, cq->p2 & 0xff, MISDN_BCH_FILL_SIZE); 178 test_and_set_bit(FLG_FILLEMPTY, &bch->Flags); 179 } else { 180 test_and_clear_bit(FLG_FILLEMPTY, &bch->Flags); 181 } 182 break; 183 case MISDN_CTRL_RX_OFF: 184 /* read back dropped byte count */ 185 cq->p2 = bch->dropcnt; 186 if (cq->p1) 187 test_and_set_bit(FLG_RX_OFF, &bch->Flags); 188 else 189 test_and_clear_bit(FLG_RX_OFF, &bch->Flags); 190 bch->dropcnt = 0; 191 break; 192 case MISDN_CTRL_RX_BUFFER: 193 if (cq->p2 > MISDN_CTRL_RX_SIZE_IGNORE) 194 bch->next_maxlen = cq->p2; 195 if (cq->p1 > MISDN_CTRL_RX_SIZE_IGNORE) 196 bch->next_minlen = cq->p1; 197 /* we return the old values */ 198 cq->p1 = bch->minlen; 199 cq->p2 = bch->maxlen; 200 break; 201 default: 202 pr_info("mISDN unhandled control %x operation\n", cq->op); 203 ret = -EINVAL; 204 break; 205 } 206 return ret; 207 } 208 EXPORT_SYMBOL(mISDN_ctrl_bchannel); 209 210 static inline u_int 211 get_sapi_tei(u_char *p) 212 { 213 u_int sapi, tei; 214 215 sapi = *p >> 2; 216 tei = p[1] >> 1; 217 return sapi | (tei << 8); 218 } 219 220 void 221 recv_Dchannel(struct dchannel *dch) 222 { 223 struct mISDNhead *hh; 224 225 if (dch->rx_skb->len < 2) { /* at least 2 for sapi / tei */ 226 dev_kfree_skb(dch->rx_skb); 227 dch->rx_skb = NULL; 228 return; 229 } 230 hh = mISDN_HEAD_P(dch->rx_skb); 231 hh->prim = PH_DATA_IND; 232 hh->id = get_sapi_tei(dch->rx_skb->data); 233 skb_queue_tail(&dch->rqueue, dch->rx_skb); 234 dch->rx_skb = NULL; 235 schedule_event(dch, FLG_RECVQUEUE); 236 } 237 EXPORT_SYMBOL(recv_Dchannel); 238 239 void 240 recv_Echannel(struct dchannel *ech, struct dchannel *dch) 241 { 242 struct mISDNhead *hh; 243 244 if (ech->rx_skb->len < 2) { /* at least 2 for sapi / tei */ 245 dev_kfree_skb(ech->rx_skb); 246 ech->rx_skb = NULL; 247 return; 248 } 249 hh = mISDN_HEAD_P(ech->rx_skb); 250 hh->prim = PH_DATA_E_IND; 251 hh->id = get_sapi_tei(ech->rx_skb->data); 252 skb_queue_tail(&dch->rqueue, ech->rx_skb); 253 ech->rx_skb = NULL; 254 schedule_event(dch, FLG_RECVQUEUE); 255 } 256 EXPORT_SYMBOL(recv_Echannel); 257 258 void 259 recv_Bchannel(struct bchannel *bch, unsigned int id, bool force) 260 { 261 struct mISDNhead *hh; 262 263 /* if allocation did fail upper functions still may call us */ 264 if (unlikely(!bch->rx_skb)) 265 return; 266 if (unlikely(!bch->rx_skb->len)) { 267 /* we have no data to send - this may happen after recovery 268 * from overflow or too small allocation. 269 * We need to free the buffer here */ 270 dev_kfree_skb(bch->rx_skb); 271 bch->rx_skb = NULL; 272 } else { 273 if (test_bit(FLG_TRANSPARENT, &bch->Flags) && 274 (bch->rx_skb->len < bch->minlen) && !force) 275 return; 276 hh = mISDN_HEAD_P(bch->rx_skb); 277 hh->prim = PH_DATA_IND; 278 hh->id = id; 279 if (bch->rcount >= 64) { 280 printk(KERN_WARNING 281 "B%d receive queue overflow - flushing!\n", 282 bch->nr); 283 skb_queue_purge(&bch->rqueue); 284 } 285 bch->rcount++; 286 skb_queue_tail(&bch->rqueue, bch->rx_skb); 287 bch->rx_skb = NULL; 288 schedule_event(bch, FLG_RECVQUEUE); 289 } 290 } 291 EXPORT_SYMBOL(recv_Bchannel); 292 293 void 294 recv_Dchannel_skb(struct dchannel *dch, struct sk_buff *skb) 295 { 296 skb_queue_tail(&dch->rqueue, skb); 297 schedule_event(dch, FLG_RECVQUEUE); 298 } 299 EXPORT_SYMBOL(recv_Dchannel_skb); 300 301 void 302 recv_Bchannel_skb(struct bchannel *bch, struct sk_buff *skb) 303 { 304 if (bch->rcount >= 64) { 305 printk(KERN_WARNING "B-channel %p receive queue overflow, " 306 "flushing!\n", bch); 307 skb_queue_purge(&bch->rqueue); 308 bch->rcount = 0; 309 } 310 bch->rcount++; 311 skb_queue_tail(&bch->rqueue, skb); 312 schedule_event(bch, FLG_RECVQUEUE); 313 } 314 EXPORT_SYMBOL(recv_Bchannel_skb); 315 316 static void 317 confirm_Dsend(struct dchannel *dch) 318 { 319 struct sk_buff *skb; 320 321 skb = _alloc_mISDN_skb(PH_DATA_CNF, mISDN_HEAD_ID(dch->tx_skb), 322 0, NULL, GFP_ATOMIC); 323 if (!skb) { 324 printk(KERN_ERR "%s: no skb id %x\n", __func__, 325 mISDN_HEAD_ID(dch->tx_skb)); 326 return; 327 } 328 skb_queue_tail(&dch->rqueue, skb); 329 schedule_event(dch, FLG_RECVQUEUE); 330 } 331 332 int 333 get_next_dframe(struct dchannel *dch) 334 { 335 dch->tx_idx = 0; 336 dch->tx_skb = skb_dequeue(&dch->squeue); 337 if (dch->tx_skb) { 338 confirm_Dsend(dch); 339 return 1; 340 } 341 dch->tx_skb = NULL; 342 test_and_clear_bit(FLG_TX_BUSY, &dch->Flags); 343 return 0; 344 } 345 EXPORT_SYMBOL(get_next_dframe); 346 347 static void 348 confirm_Bsend(struct bchannel *bch) 349 { 350 struct sk_buff *skb; 351 352 if (bch->rcount >= 64) { 353 printk(KERN_WARNING "B-channel %p receive queue overflow, " 354 "flushing!\n", bch); 355 skb_queue_purge(&bch->rqueue); 356 bch->rcount = 0; 357 } 358 skb = _alloc_mISDN_skb(PH_DATA_CNF, mISDN_HEAD_ID(bch->tx_skb), 359 0, NULL, GFP_ATOMIC); 360 if (!skb) { 361 printk(KERN_ERR "%s: no skb id %x\n", __func__, 362 mISDN_HEAD_ID(bch->tx_skb)); 363 return; 364 } 365 bch->rcount++; 366 skb_queue_tail(&bch->rqueue, skb); 367 schedule_event(bch, FLG_RECVQUEUE); 368 } 369 370 int 371 get_next_bframe(struct bchannel *bch) 372 { 373 bch->tx_idx = 0; 374 if (test_bit(FLG_TX_NEXT, &bch->Flags)) { 375 bch->tx_skb = bch->next_skb; 376 if (bch->tx_skb) { 377 bch->next_skb = NULL; 378 test_and_clear_bit(FLG_TX_NEXT, &bch->Flags); 379 /* confirm imediately to allow next data */ 380 confirm_Bsend(bch); 381 return 1; 382 } else { 383 test_and_clear_bit(FLG_TX_NEXT, &bch->Flags); 384 printk(KERN_WARNING "B TX_NEXT without skb\n"); 385 } 386 } 387 bch->tx_skb = NULL; 388 test_and_clear_bit(FLG_TX_BUSY, &bch->Flags); 389 return 0; 390 } 391 EXPORT_SYMBOL(get_next_bframe); 392 393 void 394 queue_ch_frame(struct mISDNchannel *ch, u_int pr, int id, struct sk_buff *skb) 395 { 396 struct mISDNhead *hh; 397 398 if (!skb) { 399 _queue_data(ch, pr, id, 0, NULL, GFP_ATOMIC); 400 } else { 401 if (ch->peer) { 402 hh = mISDN_HEAD_P(skb); 403 hh->prim = pr; 404 hh->id = id; 405 if (!ch->recv(ch->peer, skb)) 406 return; 407 } 408 dev_kfree_skb(skb); 409 } 410 } 411 EXPORT_SYMBOL(queue_ch_frame); 412 413 int 414 dchannel_senddata(struct dchannel *ch, struct sk_buff *skb) 415 { 416 /* check oversize */ 417 if (skb->len <= 0) { 418 printk(KERN_WARNING "%s: skb too small\n", __func__); 419 return -EINVAL; 420 } 421 if (skb->len > ch->maxlen) { 422 printk(KERN_WARNING "%s: skb too large(%d/%d)\n", 423 __func__, skb->len, ch->maxlen); 424 return -EINVAL; 425 } 426 /* HW lock must be obtained */ 427 if (test_and_set_bit(FLG_TX_BUSY, &ch->Flags)) { 428 skb_queue_tail(&ch->squeue, skb); 429 return 0; 430 } else { 431 /* write to fifo */ 432 ch->tx_skb = skb; 433 ch->tx_idx = 0; 434 return 1; 435 } 436 } 437 EXPORT_SYMBOL(dchannel_senddata); 438 439 int 440 bchannel_senddata(struct bchannel *ch, struct sk_buff *skb) 441 { 442 443 /* check oversize */ 444 if (skb->len <= 0) { 445 printk(KERN_WARNING "%s: skb too small\n", __func__); 446 return -EINVAL; 447 } 448 if (skb->len > ch->maxlen) { 449 printk(KERN_WARNING "%s: skb too large(%d/%d)\n", 450 __func__, skb->len, ch->maxlen); 451 return -EINVAL; 452 } 453 /* HW lock must be obtained */ 454 /* check for pending next_skb */ 455 if (ch->next_skb) { 456 printk(KERN_WARNING 457 "%s: next_skb exist ERROR (skb->len=%d next_skb->len=%d)\n", 458 __func__, skb->len, ch->next_skb->len); 459 return -EBUSY; 460 } 461 if (test_and_set_bit(FLG_TX_BUSY, &ch->Flags)) { 462 test_and_set_bit(FLG_TX_NEXT, &ch->Flags); 463 ch->next_skb = skb; 464 return 0; 465 } else { 466 /* write to fifo */ 467 ch->tx_skb = skb; 468 ch->tx_idx = 0; 469 confirm_Bsend(ch); 470 return 1; 471 } 472 } 473 EXPORT_SYMBOL(bchannel_senddata); 474 475 /* The function allocates a new receive skb on demand with a size for the 476 * requirements of the current protocol. It returns the tailroom of the 477 * receive skb or an error. 478 */ 479 int 480 bchannel_get_rxbuf(struct bchannel *bch, int reqlen) 481 { 482 int len; 483 484 if (bch->rx_skb) { 485 len = skb_tailroom(bch->rx_skb); 486 if (len < reqlen) { 487 pr_warning("B%d no space for %d (only %d) bytes\n", 488 bch->nr, reqlen, len); 489 if (test_bit(FLG_TRANSPARENT, &bch->Flags)) { 490 /* send what we have now and try a new buffer */ 491 recv_Bchannel(bch, 0, true); 492 } else { 493 /* on HDLC we have to drop too big frames */ 494 return -EMSGSIZE; 495 } 496 } else { 497 return len; 498 } 499 } 500 /* update current min/max length first */ 501 if (unlikely(bch->maxlen != bch->next_maxlen)) 502 bch->maxlen = bch->next_maxlen; 503 if (unlikely(bch->minlen != bch->next_minlen)) 504 bch->minlen = bch->next_minlen; 505 if (unlikely(reqlen > bch->maxlen)) 506 return -EMSGSIZE; 507 if (test_bit(FLG_TRANSPARENT, &bch->Flags)) { 508 if (reqlen >= bch->minlen) { 509 len = reqlen; 510 } else { 511 len = 2 * bch->minlen; 512 if (len > bch->maxlen) 513 len = bch->maxlen; 514 } 515 } else { 516 /* with HDLC we do not know the length yet */ 517 len = bch->maxlen; 518 } 519 bch->rx_skb = mI_alloc_skb(len, GFP_ATOMIC); 520 if (!bch->rx_skb) { 521 pr_warning("B%d receive no memory for %d bytes\n", 522 bch->nr, len); 523 len = -ENOMEM; 524 } 525 return len; 526 } 527 EXPORT_SYMBOL(bchannel_get_rxbuf); 528