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 == -1) { 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 ipw_tty *tty, 252 struct serial_struct __user *retinfo) 253 { 254 struct serial_struct tmp; 255 256 memset(&tmp, 0, sizeof(tmp)); 257 tmp.type = PORT_UNKNOWN; 258 tmp.line = tty->index; 259 tmp.baud_base = 115200; 260 261 if (copy_to_user(retinfo, &tmp, sizeof(*retinfo))) 262 return -EFAULT; 263 264 return 0; 265 } 266 267 static int ipw_chars_in_buffer(struct tty_struct *linux_tty) 268 { 269 struct ipw_tty *tty = linux_tty->driver_data; 270 271 if (!tty) 272 return 0; 273 274 if (!tty->port.count) 275 return 0; 276 277 return tty->tx_bytes_queued; 278 } 279 280 static int get_control_lines(struct ipw_tty *tty) 281 { 282 unsigned int my = tty->control_lines; 283 unsigned int out = 0; 284 285 if (my & IPW_CONTROL_LINE_RTS) 286 out |= TIOCM_RTS; 287 if (my & IPW_CONTROL_LINE_DTR) 288 out |= TIOCM_DTR; 289 if (my & IPW_CONTROL_LINE_CTS) 290 out |= TIOCM_CTS; 291 if (my & IPW_CONTROL_LINE_DSR) 292 out |= TIOCM_DSR; 293 if (my & IPW_CONTROL_LINE_DCD) 294 out |= TIOCM_CD; 295 296 return out; 297 } 298 299 static int set_control_lines(struct ipw_tty *tty, unsigned int set, 300 unsigned int clear) 301 { 302 int ret; 303 304 if (set & TIOCM_RTS) { 305 ret = ipwireless_set_RTS(tty->hardware, tty->channel_idx, 1); 306 if (ret) 307 return ret; 308 if (tty->secondary_channel_idx != -1) { 309 ret = ipwireless_set_RTS(tty->hardware, 310 tty->secondary_channel_idx, 1); 311 if (ret) 312 return ret; 313 } 314 } 315 if (set & TIOCM_DTR) { 316 ret = ipwireless_set_DTR(tty->hardware, tty->channel_idx, 1); 317 if (ret) 318 return ret; 319 if (tty->secondary_channel_idx != -1) { 320 ret = ipwireless_set_DTR(tty->hardware, 321 tty->secondary_channel_idx, 1); 322 if (ret) 323 return ret; 324 } 325 } 326 if (clear & TIOCM_RTS) { 327 ret = ipwireless_set_RTS(tty->hardware, tty->channel_idx, 0); 328 if (tty->secondary_channel_idx != -1) { 329 ret = ipwireless_set_RTS(tty->hardware, 330 tty->secondary_channel_idx, 0); 331 if (ret) 332 return ret; 333 } 334 } 335 if (clear & TIOCM_DTR) { 336 ret = ipwireless_set_DTR(tty->hardware, tty->channel_idx, 0); 337 if (tty->secondary_channel_idx != -1) { 338 ret = ipwireless_set_DTR(tty->hardware, 339 tty->secondary_channel_idx, 0); 340 if (ret) 341 return ret; 342 } 343 } 344 return 0; 345 } 346 347 static int ipw_tiocmget(struct tty_struct *linux_tty) 348 { 349 struct ipw_tty *tty = linux_tty->driver_data; 350 /* FIXME: Exactly how is the tty object locked here .. */ 351 352 if (!tty) 353 return -ENODEV; 354 355 if (!tty->port.count) 356 return -EINVAL; 357 358 return get_control_lines(tty); 359 } 360 361 static int 362 ipw_tiocmset(struct tty_struct *linux_tty, 363 unsigned int set, unsigned int clear) 364 { 365 struct ipw_tty *tty = linux_tty->driver_data; 366 /* FIXME: Exactly how is the tty object locked here .. */ 367 368 if (!tty) 369 return -ENODEV; 370 371 if (!tty->port.count) 372 return -EINVAL; 373 374 return set_control_lines(tty, set, clear); 375 } 376 377 static int ipw_ioctl(struct tty_struct *linux_tty, 378 unsigned int cmd, unsigned long arg) 379 { 380 struct ipw_tty *tty = linux_tty->driver_data; 381 382 if (!tty) 383 return -ENODEV; 384 385 if (!tty->port.count) 386 return -EINVAL; 387 388 /* FIXME: Exactly how is the tty object locked here .. */ 389 390 switch (cmd) { 391 case TIOCGSERIAL: 392 return ipwireless_get_serial_info(tty, (void __user *) arg); 393 394 case TIOCSSERIAL: 395 return 0; /* Keeps the PCMCIA scripts happy. */ 396 } 397 398 if (tty->tty_type == TTYTYPE_MODEM) { 399 switch (cmd) { 400 case PPPIOCGCHAN: 401 { 402 int chan = ipwireless_ppp_channel_index( 403 tty->network); 404 405 if (chan < 0) 406 return -ENODEV; 407 if (put_user(chan, (int __user *) arg)) 408 return -EFAULT; 409 } 410 return 0; 411 412 case PPPIOCGUNIT: 413 { 414 int unit = ipwireless_ppp_unit_number( 415 tty->network); 416 417 if (unit < 0) 418 return -ENODEV; 419 if (put_user(unit, (int __user *) arg)) 420 return -EFAULT; 421 } 422 return 0; 423 424 case FIONREAD: 425 { 426 int val = 0; 427 428 if (put_user(val, (int __user *) arg)) 429 return -EFAULT; 430 } 431 return 0; 432 case TCFLSH: 433 return tty_perform_flush(linux_tty, arg); 434 } 435 } 436 return -ENOIOCTLCMD; 437 } 438 439 static int add_tty(int j, 440 struct ipw_hardware *hardware, 441 struct ipw_network *network, int channel_idx, 442 int secondary_channel_idx, int tty_type) 443 { 444 ttys[j] = kzalloc(sizeof(struct ipw_tty), GFP_KERNEL); 445 if (!ttys[j]) 446 return -ENOMEM; 447 ttys[j]->index = j; 448 ttys[j]->hardware = hardware; 449 ttys[j]->channel_idx = channel_idx; 450 ttys[j]->secondary_channel_idx = secondary_channel_idx; 451 ttys[j]->network = network; 452 ttys[j]->tty_type = tty_type; 453 mutex_init(&ttys[j]->ipw_tty_mutex); 454 tty_port_init(&ttys[j]->port); 455 456 tty_port_register_device(&ttys[j]->port, ipw_tty_driver, j, NULL); 457 ipwireless_associate_network_tty(network, channel_idx, ttys[j]); 458 459 if (secondary_channel_idx != -1) 460 ipwireless_associate_network_tty(network, 461 secondary_channel_idx, 462 ttys[j]); 463 /* check if we provide raw device (if loopback is enabled) */ 464 if (get_tty(j)) 465 printk(KERN_INFO IPWIRELESS_PCCARD_NAME 466 ": registering %s device ttyIPWp%d\n", 467 tty_type_name(tty_type), j); 468 469 return 0; 470 } 471 472 struct ipw_tty *ipwireless_tty_create(struct ipw_hardware *hardware, 473 struct ipw_network *network) 474 { 475 int i, j; 476 477 for (i = 0; i < IPWIRELESS_PCMCIA_MINOR_RANGE; i++) { 478 int allfree = 1; 479 480 for (j = i; j < IPWIRELESS_PCMCIA_MINORS; 481 j += IPWIRELESS_PCMCIA_MINOR_RANGE) 482 if (ttys[j] != NULL) { 483 allfree = 0; 484 break; 485 } 486 487 if (allfree) { 488 j = i; 489 490 if (add_tty(j, hardware, network, 491 IPW_CHANNEL_DIALLER, IPW_CHANNEL_RAS, 492 TTYTYPE_MODEM)) 493 return NULL; 494 495 j += IPWIRELESS_PCMCIA_MINOR_RANGE; 496 if (add_tty(j, hardware, network, 497 IPW_CHANNEL_DIALLER, -1, 498 TTYTYPE_MONITOR)) 499 return NULL; 500 501 j += IPWIRELESS_PCMCIA_MINOR_RANGE; 502 if (add_tty(j, hardware, network, 503 IPW_CHANNEL_RAS, -1, 504 TTYTYPE_RAS_RAW)) 505 return NULL; 506 507 return ttys[i]; 508 } 509 } 510 return NULL; 511 } 512 513 /* 514 * Must be called before ipwireless_network_free(). 515 */ 516 void ipwireless_tty_free(struct ipw_tty *tty) 517 { 518 int j; 519 struct ipw_network *network = ttys[tty->index]->network; 520 521 for (j = tty->index; j < IPWIRELESS_PCMCIA_MINORS; 522 j += IPWIRELESS_PCMCIA_MINOR_RANGE) { 523 struct ipw_tty *ttyj = ttys[j]; 524 525 if (ttyj) { 526 mutex_lock(&ttyj->ipw_tty_mutex); 527 if (get_tty(j)) 528 printk(KERN_INFO IPWIRELESS_PCCARD_NAME 529 ": deregistering %s device ttyIPWp%d\n", 530 tty_type_name(ttyj->tty_type), j); 531 ttyj->closing = 1; 532 if (ttyj->port.tty != NULL) { 533 mutex_unlock(&ttyj->ipw_tty_mutex); 534 tty_vhangup(ttyj->port.tty); 535 /* FIXME: Exactly how is the tty object locked here 536 against a parallel ioctl etc */ 537 /* FIXME2: hangup does not mean all processes 538 * are gone */ 539 mutex_lock(&ttyj->ipw_tty_mutex); 540 } 541 while (ttyj->port.count) 542 do_ipw_close(ttyj); 543 ipwireless_disassociate_network_ttys(network, 544 ttyj->channel_idx); 545 tty_unregister_device(ipw_tty_driver, j); 546 tty_port_destroy(&ttyj->port); 547 ttys[j] = NULL; 548 mutex_unlock(&ttyj->ipw_tty_mutex); 549 kfree(ttyj); 550 } 551 } 552 } 553 554 static const struct tty_operations tty_ops = { 555 .open = ipw_open, 556 .close = ipw_close, 557 .hangup = ipw_hangup, 558 .write = ipw_write, 559 .write_room = ipw_write_room, 560 .ioctl = ipw_ioctl, 561 .chars_in_buffer = ipw_chars_in_buffer, 562 .tiocmget = ipw_tiocmget, 563 .tiocmset = ipw_tiocmset, 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