1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * IPWireless 3G PCMCIA Network Driver 4 * 5 * Original code 6 * by Stephen Blackheath <stephen@blacksapphire.com>, 7 * Ben Martel <benm@symmetric.co.nz> 8 * 9 * Copyrighted as follows: 10 * Copyright (C) 2004 by Symmetric Systems Ltd (NZ) 11 * 12 * Various driver changes and rewrites, port to new kernels 13 * Copyright (C) 2006-2007 Jiri Kosina 14 * 15 * Misc code cleanups and updates 16 * Copyright (C) 2007 David Sterba 17 */ 18 19 #include <linux/kernel.h> 20 #include <linux/module.h> 21 #include <linux/mutex.h> 22 #include <linux/ppp_defs.h> 23 #include <linux/if.h> 24 #include <linux/ppp-ioctl.h> 25 #include <linux/sched.h> 26 #include <linux/serial.h> 27 #include <linux/slab.h> 28 #include <linux/tty.h> 29 #include <linux/tty_driver.h> 30 #include <linux/tty_flip.h> 31 #include <linux/uaccess.h> 32 33 #include "tty.h" 34 #include "network.h" 35 #include "hardware.h" 36 #include "main.h" 37 38 #define IPWIRELESS_PCMCIA_START (0) 39 #define IPWIRELESS_PCMCIA_MINORS (24) 40 #define IPWIRELESS_PCMCIA_MINOR_RANGE (8) 41 42 #define TTYTYPE_MODEM (0) 43 #define TTYTYPE_MONITOR (1) 44 #define TTYTYPE_RAS_RAW (2) 45 46 struct ipw_tty { 47 struct tty_port port; 48 int index; 49 struct ipw_hardware *hardware; 50 unsigned int channel_idx; 51 unsigned int secondary_channel_idx; 52 int tty_type; 53 struct ipw_network *network; 54 unsigned int control_lines; 55 struct mutex ipw_tty_mutex; 56 int tx_bytes_queued; 57 int closing; 58 }; 59 60 static struct ipw_tty *ttys[IPWIRELESS_PCMCIA_MINORS]; 61 62 static struct tty_driver *ipw_tty_driver; 63 64 static char *tty_type_name(int tty_type) 65 { 66 static char *channel_names[] = { 67 "modem", 68 "monitor", 69 "RAS-raw" 70 }; 71 72 return channel_names[tty_type]; 73 } 74 75 static struct ipw_tty *get_tty(int index) 76 { 77 /* 78 * The 'ras_raw' channel is only available when 'loopback' mode 79 * is enabled. 80 * Number of minor starts with 16 (_RANGE * _RAS_RAW). 81 */ 82 if (!ipwireless_loopback && index >= 83 IPWIRELESS_PCMCIA_MINOR_RANGE * TTYTYPE_RAS_RAW) 84 return NULL; 85 86 return ttys[index]; 87 } 88 89 static int ipw_open(struct tty_struct *linux_tty, struct file *filp) 90 { 91 struct ipw_tty *tty = get_tty(linux_tty->index); 92 93 if (!tty) 94 return -ENODEV; 95 96 mutex_lock(&tty->ipw_tty_mutex); 97 if (tty->port.count == 0) 98 tty->tx_bytes_queued = 0; 99 100 tty->port.count++; 101 102 tty->port.tty = linux_tty; 103 linux_tty->driver_data = tty; 104 tty->port.low_latency = 1; 105 106 if (tty->tty_type == TTYTYPE_MODEM) 107 ipwireless_ppp_open(tty->network); 108 109 mutex_unlock(&tty->ipw_tty_mutex); 110 111 return 0; 112 } 113 114 static void do_ipw_close(struct ipw_tty *tty) 115 { 116 tty->port.count--; 117 118 if (tty->port.count == 0) { 119 struct tty_struct *linux_tty = tty->port.tty; 120 121 if (linux_tty != NULL) { 122 tty->port.tty = NULL; 123 linux_tty->driver_data = NULL; 124 125 if (tty->tty_type == TTYTYPE_MODEM) 126 ipwireless_ppp_close(tty->network); 127 } 128 } 129 } 130 131 static void ipw_hangup(struct tty_struct *linux_tty) 132 { 133 struct ipw_tty *tty = linux_tty->driver_data; 134 135 if (!tty) 136 return; 137 138 mutex_lock(&tty->ipw_tty_mutex); 139 if (tty->port.count == 0) { 140 mutex_unlock(&tty->ipw_tty_mutex); 141 return; 142 } 143 144 do_ipw_close(tty); 145 146 mutex_unlock(&tty->ipw_tty_mutex); 147 } 148 149 static void ipw_close(struct tty_struct *linux_tty, struct file *filp) 150 { 151 ipw_hangup(linux_tty); 152 } 153 154 /* Take data received from hardware, and send it out the tty */ 155 void ipwireless_tty_received(struct ipw_tty *tty, unsigned char *data, 156 unsigned int length) 157 { 158 int work = 0; 159 160 mutex_lock(&tty->ipw_tty_mutex); 161 162 if (!tty->port.count) { 163 mutex_unlock(&tty->ipw_tty_mutex); 164 return; 165 } 166 mutex_unlock(&tty->ipw_tty_mutex); 167 168 work = tty_insert_flip_string(&tty->port, data, length); 169 170 if (work != length) 171 printk(KERN_DEBUG IPWIRELESS_PCCARD_NAME 172 ": %d chars not inserted to flip buffer!\n", 173 length - work); 174 175 if (work) 176 tty_flip_buffer_push(&tty->port); 177 } 178 179 static void ipw_write_packet_sent_callback(void *callback_data, 180 unsigned int packet_length) 181 { 182 struct ipw_tty *tty = callback_data; 183 184 /* 185 * Packet has been sent, so we subtract the number of bytes from our 186 * tally of outstanding TX bytes. 187 */ 188 tty->tx_bytes_queued -= packet_length; 189 } 190 191 static int ipw_write(struct tty_struct *linux_tty, 192 const unsigned char *buf, int count) 193 { 194 struct ipw_tty *tty = linux_tty->driver_data; 195 int room, ret; 196 197 if (!tty) 198 return -ENODEV; 199 200 mutex_lock(&tty->ipw_tty_mutex); 201 if (!tty->port.count) { 202 mutex_unlock(&tty->ipw_tty_mutex); 203 return -EINVAL; 204 } 205 206 room = IPWIRELESS_TX_QUEUE_SIZE - tty->tx_bytes_queued; 207 if (room < 0) 208 room = 0; 209 /* Don't allow caller to write any more than we have room for */ 210 if (count > room) 211 count = room; 212 213 if (count == 0) { 214 mutex_unlock(&tty->ipw_tty_mutex); 215 return 0; 216 } 217 218 ret = ipwireless_send_packet(tty->hardware, IPW_CHANNEL_RAS, 219 buf, count, 220 ipw_write_packet_sent_callback, tty); 221 if (ret < 0) { 222 mutex_unlock(&tty->ipw_tty_mutex); 223 return 0; 224 } 225 226 tty->tx_bytes_queued += count; 227 mutex_unlock(&tty->ipw_tty_mutex); 228 229 return count; 230 } 231 232 static int ipw_write_room(struct tty_struct *linux_tty) 233 { 234 struct ipw_tty *tty = linux_tty->driver_data; 235 int room; 236 237 /* FIXME: Exactly how is the tty object locked here .. */ 238 if (!tty) 239 return -ENODEV; 240 241 if (!tty->port.count) 242 return -EINVAL; 243 244 room = IPWIRELESS_TX_QUEUE_SIZE - tty->tx_bytes_queued; 245 if (room < 0) 246 room = 0; 247 248 return room; 249 } 250 251 static int ipwireless_get_serial_info(struct tty_struct *linux_tty, 252 struct serial_struct *ss) 253 { 254 struct ipw_tty *tty = linux_tty->driver_data; 255 256 if (!tty) 257 return -ENODEV; 258 259 if (!tty->port.count) 260 return -EINVAL; 261 262 ss->type = PORT_UNKNOWN; 263 ss->line = tty->index; 264 ss->baud_base = 115200; 265 return 0; 266 } 267 268 static int ipwireless_set_serial_info(struct tty_struct *linux_tty, 269 struct serial_struct *ss) 270 { 271 return 0; /* Keeps the PCMCIA scripts happy. */ 272 } 273 274 static int ipw_chars_in_buffer(struct tty_struct *linux_tty) 275 { 276 struct ipw_tty *tty = linux_tty->driver_data; 277 278 if (!tty) 279 return 0; 280 281 if (!tty->port.count) 282 return 0; 283 284 return tty->tx_bytes_queued; 285 } 286 287 static int get_control_lines(struct ipw_tty *tty) 288 { 289 unsigned int my = tty->control_lines; 290 unsigned int out = 0; 291 292 if (my & IPW_CONTROL_LINE_RTS) 293 out |= TIOCM_RTS; 294 if (my & IPW_CONTROL_LINE_DTR) 295 out |= TIOCM_DTR; 296 if (my & IPW_CONTROL_LINE_CTS) 297 out |= TIOCM_CTS; 298 if (my & IPW_CONTROL_LINE_DSR) 299 out |= TIOCM_DSR; 300 if (my & IPW_CONTROL_LINE_DCD) 301 out |= TIOCM_CD; 302 303 return out; 304 } 305 306 static int set_control_lines(struct ipw_tty *tty, unsigned int set, 307 unsigned int clear) 308 { 309 int ret; 310 311 if (set & TIOCM_RTS) { 312 ret = ipwireless_set_RTS(tty->hardware, tty->channel_idx, 1); 313 if (ret) 314 return ret; 315 if (tty->secondary_channel_idx != -1) { 316 ret = ipwireless_set_RTS(tty->hardware, 317 tty->secondary_channel_idx, 1); 318 if (ret) 319 return ret; 320 } 321 } 322 if (set & TIOCM_DTR) { 323 ret = ipwireless_set_DTR(tty->hardware, tty->channel_idx, 1); 324 if (ret) 325 return ret; 326 if (tty->secondary_channel_idx != -1) { 327 ret = ipwireless_set_DTR(tty->hardware, 328 tty->secondary_channel_idx, 1); 329 if (ret) 330 return ret; 331 } 332 } 333 if (clear & TIOCM_RTS) { 334 ret = ipwireless_set_RTS(tty->hardware, tty->channel_idx, 0); 335 if (tty->secondary_channel_idx != -1) { 336 ret = ipwireless_set_RTS(tty->hardware, 337 tty->secondary_channel_idx, 0); 338 if (ret) 339 return ret; 340 } 341 } 342 if (clear & TIOCM_DTR) { 343 ret = ipwireless_set_DTR(tty->hardware, tty->channel_idx, 0); 344 if (tty->secondary_channel_idx != -1) { 345 ret = ipwireless_set_DTR(tty->hardware, 346 tty->secondary_channel_idx, 0); 347 if (ret) 348 return ret; 349 } 350 } 351 return 0; 352 } 353 354 static int ipw_tiocmget(struct tty_struct *linux_tty) 355 { 356 struct ipw_tty *tty = linux_tty->driver_data; 357 /* FIXME: Exactly how is the tty object locked here .. */ 358 359 if (!tty) 360 return -ENODEV; 361 362 if (!tty->port.count) 363 return -EINVAL; 364 365 return get_control_lines(tty); 366 } 367 368 static int 369 ipw_tiocmset(struct tty_struct *linux_tty, 370 unsigned int set, unsigned int clear) 371 { 372 struct ipw_tty *tty = linux_tty->driver_data; 373 /* FIXME: Exactly how is the tty object locked here .. */ 374 375 if (!tty) 376 return -ENODEV; 377 378 if (!tty->port.count) 379 return -EINVAL; 380 381 return set_control_lines(tty, set, clear); 382 } 383 384 static int ipw_ioctl(struct tty_struct *linux_tty, 385 unsigned int cmd, unsigned long arg) 386 { 387 struct ipw_tty *tty = linux_tty->driver_data; 388 389 if (!tty) 390 return -ENODEV; 391 392 if (!tty->port.count) 393 return -EINVAL; 394 395 /* FIXME: Exactly how is the tty object locked here .. */ 396 if (tty->tty_type == TTYTYPE_MODEM) { 397 switch (cmd) { 398 case PPPIOCGCHAN: 399 { 400 int chan = ipwireless_ppp_channel_index( 401 tty->network); 402 403 if (chan < 0) 404 return -ENODEV; 405 if (put_user(chan, (int __user *) arg)) 406 return -EFAULT; 407 } 408 return 0; 409 410 case PPPIOCGUNIT: 411 { 412 int unit = ipwireless_ppp_unit_number( 413 tty->network); 414 415 if (unit < 0) 416 return -ENODEV; 417 if (put_user(unit, (int __user *) arg)) 418 return -EFAULT; 419 } 420 return 0; 421 422 case FIONREAD: 423 { 424 int val = 0; 425 426 if (put_user(val, (int __user *) arg)) 427 return -EFAULT; 428 } 429 return 0; 430 case TCFLSH: 431 return tty_perform_flush(linux_tty, arg); 432 } 433 } 434 return -ENOIOCTLCMD; 435 } 436 437 static int add_tty(int j, 438 struct ipw_hardware *hardware, 439 struct ipw_network *network, int channel_idx, 440 int secondary_channel_idx, int tty_type) 441 { 442 ttys[j] = kzalloc(sizeof(struct ipw_tty), GFP_KERNEL); 443 if (!ttys[j]) 444 return -ENOMEM; 445 ttys[j]->index = j; 446 ttys[j]->hardware = hardware; 447 ttys[j]->channel_idx = channel_idx; 448 ttys[j]->secondary_channel_idx = secondary_channel_idx; 449 ttys[j]->network = network; 450 ttys[j]->tty_type = tty_type; 451 mutex_init(&ttys[j]->ipw_tty_mutex); 452 tty_port_init(&ttys[j]->port); 453 454 tty_port_register_device(&ttys[j]->port, ipw_tty_driver, j, NULL); 455 ipwireless_associate_network_tty(network, channel_idx, ttys[j]); 456 457 if (secondary_channel_idx != -1) 458 ipwireless_associate_network_tty(network, 459 secondary_channel_idx, 460 ttys[j]); 461 /* check if we provide raw device (if loopback is enabled) */ 462 if (get_tty(j)) 463 printk(KERN_INFO IPWIRELESS_PCCARD_NAME 464 ": registering %s device ttyIPWp%d\n", 465 tty_type_name(tty_type), j); 466 467 return 0; 468 } 469 470 struct ipw_tty *ipwireless_tty_create(struct ipw_hardware *hardware, 471 struct ipw_network *network) 472 { 473 int i, j; 474 475 for (i = 0; i < IPWIRELESS_PCMCIA_MINOR_RANGE; i++) { 476 int allfree = 1; 477 478 for (j = i; j < IPWIRELESS_PCMCIA_MINORS; 479 j += IPWIRELESS_PCMCIA_MINOR_RANGE) 480 if (ttys[j] != NULL) { 481 allfree = 0; 482 break; 483 } 484 485 if (allfree) { 486 j = i; 487 488 if (add_tty(j, hardware, network, 489 IPW_CHANNEL_DIALLER, IPW_CHANNEL_RAS, 490 TTYTYPE_MODEM)) 491 return NULL; 492 493 j += IPWIRELESS_PCMCIA_MINOR_RANGE; 494 if (add_tty(j, hardware, network, 495 IPW_CHANNEL_DIALLER, -1, 496 TTYTYPE_MONITOR)) 497 return NULL; 498 499 j += IPWIRELESS_PCMCIA_MINOR_RANGE; 500 if (add_tty(j, hardware, network, 501 IPW_CHANNEL_RAS, -1, 502 TTYTYPE_RAS_RAW)) 503 return NULL; 504 505 return ttys[i]; 506 } 507 } 508 return NULL; 509 } 510 511 /* 512 * Must be called before ipwireless_network_free(). 513 */ 514 void ipwireless_tty_free(struct ipw_tty *tty) 515 { 516 int j; 517 struct ipw_network *network = ttys[tty->index]->network; 518 519 for (j = tty->index; j < IPWIRELESS_PCMCIA_MINORS; 520 j += IPWIRELESS_PCMCIA_MINOR_RANGE) { 521 struct ipw_tty *ttyj = ttys[j]; 522 523 if (ttyj) { 524 mutex_lock(&ttyj->ipw_tty_mutex); 525 if (get_tty(j)) 526 printk(KERN_INFO IPWIRELESS_PCCARD_NAME 527 ": deregistering %s device ttyIPWp%d\n", 528 tty_type_name(ttyj->tty_type), j); 529 ttyj->closing = 1; 530 if (ttyj->port.tty != NULL) { 531 mutex_unlock(&ttyj->ipw_tty_mutex); 532 tty_vhangup(ttyj->port.tty); 533 /* FIXME: Exactly how is the tty object locked here 534 against a parallel ioctl etc */ 535 /* FIXME2: hangup does not mean all processes 536 * are gone */ 537 mutex_lock(&ttyj->ipw_tty_mutex); 538 } 539 while (ttyj->port.count) 540 do_ipw_close(ttyj); 541 ipwireless_disassociate_network_ttys(network, 542 ttyj->channel_idx); 543 tty_unregister_device(ipw_tty_driver, j); 544 tty_port_destroy(&ttyj->port); 545 ttys[j] = NULL; 546 mutex_unlock(&ttyj->ipw_tty_mutex); 547 kfree(ttyj); 548 } 549 } 550 } 551 552 static const struct tty_operations tty_ops = { 553 .open = ipw_open, 554 .close = ipw_close, 555 .hangup = ipw_hangup, 556 .write = ipw_write, 557 .write_room = ipw_write_room, 558 .ioctl = ipw_ioctl, 559 .chars_in_buffer = ipw_chars_in_buffer, 560 .tiocmget = ipw_tiocmget, 561 .tiocmset = ipw_tiocmset, 562 .set_serial = ipwireless_set_serial_info, 563 .get_serial = ipwireless_get_serial_info, 564 }; 565 566 int ipwireless_tty_init(void) 567 { 568 int result; 569 570 ipw_tty_driver = alloc_tty_driver(IPWIRELESS_PCMCIA_MINORS); 571 if (!ipw_tty_driver) 572 return -ENOMEM; 573 574 ipw_tty_driver->driver_name = IPWIRELESS_PCCARD_NAME; 575 ipw_tty_driver->name = "ttyIPWp"; 576 ipw_tty_driver->major = 0; 577 ipw_tty_driver->minor_start = IPWIRELESS_PCMCIA_START; 578 ipw_tty_driver->type = TTY_DRIVER_TYPE_SERIAL; 579 ipw_tty_driver->subtype = SERIAL_TYPE_NORMAL; 580 ipw_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; 581 ipw_tty_driver->init_termios = tty_std_termios; 582 ipw_tty_driver->init_termios.c_cflag = 583 B9600 | CS8 | CREAD | HUPCL | CLOCAL; 584 ipw_tty_driver->init_termios.c_ispeed = 9600; 585 ipw_tty_driver->init_termios.c_ospeed = 9600; 586 tty_set_operations(ipw_tty_driver, &tty_ops); 587 result = tty_register_driver(ipw_tty_driver); 588 if (result) { 589 printk(KERN_ERR IPWIRELESS_PCCARD_NAME 590 ": failed to register tty driver\n"); 591 put_tty_driver(ipw_tty_driver); 592 return result; 593 } 594 595 return 0; 596 } 597 598 void ipwireless_tty_release(void) 599 { 600 int ret; 601 602 ret = tty_unregister_driver(ipw_tty_driver); 603 put_tty_driver(ipw_tty_driver); 604 if (ret != 0) 605 printk(KERN_ERR IPWIRELESS_PCCARD_NAME 606 ": tty_unregister_driver failed with code %d\n", ret); 607 } 608 609 int ipwireless_tty_is_modem(struct ipw_tty *tty) 610 { 611 return tty->tty_type == TTYTYPE_MODEM; 612 } 613 614 void 615 ipwireless_tty_notify_control_line_change(struct ipw_tty *tty, 616 unsigned int channel_idx, 617 unsigned int control_lines, 618 unsigned int changed_mask) 619 { 620 unsigned int old_control_lines = tty->control_lines; 621 622 tty->control_lines = (tty->control_lines & ~changed_mask) 623 | (control_lines & changed_mask); 624 625 /* 626 * If DCD is de-asserted, we close the tty so pppd can tell that we 627 * have gone offline. 628 */ 629 if ((old_control_lines & IPW_CONTROL_LINE_DCD) 630 && !(tty->control_lines & IPW_CONTROL_LINE_DCD) 631 && tty->port.tty) { 632 tty_hangup(tty->port.tty); 633 } 634 } 635 636