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