network.c (12919B)
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/interrupt.h> 20#include <linux/kernel.h> 21#include <linux/mutex.h> 22#include <linux/netdevice.h> 23#include <linux/ppp_channel.h> 24#include <linux/ppp_defs.h> 25#include <linux/slab.h> 26#include <linux/ppp-ioctl.h> 27#include <linux/skbuff.h> 28 29#include "network.h" 30#include "hardware.h" 31#include "main.h" 32#include "tty.h" 33 34#define MAX_ASSOCIATED_TTYS 2 35 36#define SC_RCV_BITS (SC_RCV_B7_1|SC_RCV_B7_0|SC_RCV_ODDP|SC_RCV_EVNP) 37 38struct ipw_network { 39 /* Hardware context, used for calls to hardware layer. */ 40 struct ipw_hardware *hardware; 41 /* Context for kernel 'generic_ppp' functionality */ 42 struct ppp_channel *ppp_channel; 43 /* tty context connected with IPW console */ 44 struct ipw_tty *associated_ttys[NO_OF_IPW_CHANNELS][MAX_ASSOCIATED_TTYS]; 45 /* True if ppp needs waking up once we're ready to xmit */ 46 int ppp_blocked; 47 /* Number of packets queued up in hardware module. */ 48 int outgoing_packets_queued; 49 /* Spinlock to avoid interrupts during shutdown */ 50 spinlock_t lock; 51 struct mutex close_lock; 52 53 /* PPP ioctl data, not actually used anywere */ 54 unsigned int flags; 55 unsigned int rbits; 56 u32 xaccm[8]; 57 u32 raccm; 58 int mru; 59 60 int shutting_down; 61 unsigned int ras_control_lines; 62 63 struct work_struct work_go_online; 64 struct work_struct work_go_offline; 65}; 66 67static void notify_packet_sent(void *callback_data, unsigned int packet_length) 68{ 69 struct ipw_network *network = callback_data; 70 unsigned long flags; 71 72 spin_lock_irqsave(&network->lock, flags); 73 network->outgoing_packets_queued--; 74 if (network->ppp_channel != NULL) { 75 if (network->ppp_blocked) { 76 network->ppp_blocked = 0; 77 spin_unlock_irqrestore(&network->lock, flags); 78 ppp_output_wakeup(network->ppp_channel); 79 if (ipwireless_debug) 80 printk(KERN_DEBUG IPWIRELESS_PCCARD_NAME 81 ": ppp unblocked\n"); 82 } else 83 spin_unlock_irqrestore(&network->lock, flags); 84 } else 85 spin_unlock_irqrestore(&network->lock, flags); 86} 87 88/* 89 * Called by the ppp system when it has a packet to send to the hardware. 90 */ 91static int ipwireless_ppp_start_xmit(struct ppp_channel *ppp_channel, 92 struct sk_buff *skb) 93{ 94 struct ipw_network *network = ppp_channel->private; 95 unsigned long flags; 96 97 spin_lock_irqsave(&network->lock, flags); 98 if (network->outgoing_packets_queued < ipwireless_out_queue) { 99 unsigned char *buf; 100 static unsigned char header[] = { 101 PPP_ALLSTATIONS, /* 0xff */ 102 PPP_UI, /* 0x03 */ 103 }; 104 int ret; 105 106 network->outgoing_packets_queued++; 107 spin_unlock_irqrestore(&network->lock, flags); 108 109 /* 110 * If we have the requested amount of headroom in the skb we 111 * were handed, then we can add the header efficiently. 112 */ 113 if (skb_headroom(skb) >= 2) { 114 memcpy(skb_push(skb, 2), header, 2); 115 ret = ipwireless_send_packet(network->hardware, 116 IPW_CHANNEL_RAS, skb->data, 117 skb->len, 118 notify_packet_sent, 119 network); 120 if (ret < 0) { 121 skb_pull(skb, 2); 122 return 0; 123 } 124 } else { 125 /* Otherwise (rarely) we do it inefficiently. */ 126 buf = kmalloc(skb->len + 2, GFP_ATOMIC); 127 if (!buf) 128 return 0; 129 memcpy(buf + 2, skb->data, skb->len); 130 memcpy(buf, header, 2); 131 ret = ipwireless_send_packet(network->hardware, 132 IPW_CHANNEL_RAS, buf, 133 skb->len + 2, 134 notify_packet_sent, 135 network); 136 kfree(buf); 137 if (ret < 0) 138 return 0; 139 } 140 kfree_skb(skb); 141 return 1; 142 } else { 143 /* 144 * Otherwise reject the packet, and flag that the ppp system 145 * needs to be unblocked once we are ready to send. 146 */ 147 network->ppp_blocked = 1; 148 spin_unlock_irqrestore(&network->lock, flags); 149 if (ipwireless_debug) 150 printk(KERN_DEBUG IPWIRELESS_PCCARD_NAME ": ppp blocked\n"); 151 return 0; 152 } 153} 154 155/* Handle an ioctl call that has come in via ppp. (copy of ppp_async_ioctl() */ 156static int ipwireless_ppp_ioctl(struct ppp_channel *ppp_channel, 157 unsigned int cmd, unsigned long arg) 158{ 159 struct ipw_network *network = ppp_channel->private; 160 int err, val; 161 u32 accm[8]; 162 int __user *user_arg = (int __user *) arg; 163 164 err = -EFAULT; 165 switch (cmd) { 166 case PPPIOCGFLAGS: 167 val = network->flags | network->rbits; 168 if (put_user(val, user_arg)) 169 break; 170 err = 0; 171 break; 172 173 case PPPIOCSFLAGS: 174 if (get_user(val, user_arg)) 175 break; 176 network->flags = val & ~SC_RCV_BITS; 177 network->rbits = val & SC_RCV_BITS; 178 err = 0; 179 break; 180 181 case PPPIOCGASYNCMAP: 182 if (put_user(network->xaccm[0], user_arg)) 183 break; 184 err = 0; 185 break; 186 187 case PPPIOCSASYNCMAP: 188 if (get_user(network->xaccm[0], user_arg)) 189 break; 190 err = 0; 191 break; 192 193 case PPPIOCGRASYNCMAP: 194 if (put_user(network->raccm, user_arg)) 195 break; 196 err = 0; 197 break; 198 199 case PPPIOCSRASYNCMAP: 200 if (get_user(network->raccm, user_arg)) 201 break; 202 err = 0; 203 break; 204 205 case PPPIOCGXASYNCMAP: 206 if (copy_to_user((void __user *) arg, network->xaccm, 207 sizeof(network->xaccm))) 208 break; 209 err = 0; 210 break; 211 212 case PPPIOCSXASYNCMAP: 213 if (copy_from_user(accm, (void __user *) arg, sizeof(accm))) 214 break; 215 accm[2] &= ~0x40000000U; /* can't escape 0x5e */ 216 accm[3] |= 0x60000000U; /* must escape 0x7d, 0x7e */ 217 memcpy(network->xaccm, accm, sizeof(network->xaccm)); 218 err = 0; 219 break; 220 221 case PPPIOCGMRU: 222 if (put_user(network->mru, user_arg)) 223 break; 224 err = 0; 225 break; 226 227 case PPPIOCSMRU: 228 if (get_user(val, user_arg)) 229 break; 230 if (val < PPP_MRU) 231 val = PPP_MRU; 232 network->mru = val; 233 err = 0; 234 break; 235 236 default: 237 err = -ENOTTY; 238 } 239 240 return err; 241} 242 243static const struct ppp_channel_ops ipwireless_ppp_channel_ops = { 244 .start_xmit = ipwireless_ppp_start_xmit, 245 .ioctl = ipwireless_ppp_ioctl 246}; 247 248static void do_go_online(struct work_struct *work_go_online) 249{ 250 struct ipw_network *network = 251 container_of(work_go_online, struct ipw_network, 252 work_go_online); 253 unsigned long flags; 254 255 spin_lock_irqsave(&network->lock, flags); 256 if (!network->ppp_channel) { 257 struct ppp_channel *channel; 258 259 spin_unlock_irqrestore(&network->lock, flags); 260 channel = kzalloc(sizeof(struct ppp_channel), GFP_KERNEL); 261 if (!channel) { 262 printk(KERN_ERR IPWIRELESS_PCCARD_NAME 263 ": unable to allocate PPP channel\n"); 264 return; 265 } 266 channel->private = network; 267 channel->mtu = 16384; /* Wild guess */ 268 channel->hdrlen = 2; 269 channel->ops = &ipwireless_ppp_channel_ops; 270 271 network->flags = 0; 272 network->rbits = 0; 273 network->mru = PPP_MRU; 274 memset(network->xaccm, 0, sizeof(network->xaccm)); 275 network->xaccm[0] = ~0U; 276 network->xaccm[3] = 0x60000000U; 277 network->raccm = ~0U; 278 if (ppp_register_channel(channel) < 0) { 279 printk(KERN_ERR IPWIRELESS_PCCARD_NAME 280 ": unable to register PPP channel\n"); 281 kfree(channel); 282 return; 283 } 284 spin_lock_irqsave(&network->lock, flags); 285 network->ppp_channel = channel; 286 } 287 spin_unlock_irqrestore(&network->lock, flags); 288} 289 290static void do_go_offline(struct work_struct *work_go_offline) 291{ 292 struct ipw_network *network = 293 container_of(work_go_offline, struct ipw_network, 294 work_go_offline); 295 unsigned long flags; 296 297 mutex_lock(&network->close_lock); 298 spin_lock_irqsave(&network->lock, flags); 299 if (network->ppp_channel != NULL) { 300 struct ppp_channel *channel = network->ppp_channel; 301 302 network->ppp_channel = NULL; 303 spin_unlock_irqrestore(&network->lock, flags); 304 mutex_unlock(&network->close_lock); 305 ppp_unregister_channel(channel); 306 } else { 307 spin_unlock_irqrestore(&network->lock, flags); 308 mutex_unlock(&network->close_lock); 309 } 310} 311 312void ipwireless_network_notify_control_line_change(struct ipw_network *network, 313 unsigned int channel_idx, 314 unsigned int control_lines, 315 unsigned int changed_mask) 316{ 317 int i; 318 319 if (channel_idx == IPW_CHANNEL_RAS) 320 network->ras_control_lines = control_lines; 321 322 for (i = 0; i < MAX_ASSOCIATED_TTYS; i++) { 323 struct ipw_tty *tty = 324 network->associated_ttys[channel_idx][i]; 325 326 /* 327 * If it's associated with a tty (other than the RAS channel 328 * when we're online), then send the data to that tty. The RAS 329 * channel's data is handled above - it always goes through 330 * ppp_generic. 331 */ 332 if (tty) 333 ipwireless_tty_notify_control_line_change(tty, 334 channel_idx, 335 control_lines, 336 changed_mask); 337 } 338} 339 340/* 341 * Some versions of firmware stuff packets with 0xff 0x03 (PPP: ALLSTATIONS, UI) 342 * bytes, which are required on sent packet, but not always present on received 343 * packets 344 */ 345static struct sk_buff *ipw_packet_received_skb(unsigned char *data, 346 unsigned int length) 347{ 348 struct sk_buff *skb; 349 350 if (length > 2 && data[0] == PPP_ALLSTATIONS && data[1] == PPP_UI) { 351 length -= 2; 352 data += 2; 353 } 354 355 skb = dev_alloc_skb(length + 4); 356 if (skb == NULL) 357 return NULL; 358 skb_reserve(skb, 2); 359 skb_put_data(skb, data, length); 360 361 return skb; 362} 363 364void ipwireless_network_packet_received(struct ipw_network *network, 365 unsigned int channel_idx, 366 unsigned char *data, 367 unsigned int length) 368{ 369 int i; 370 unsigned long flags; 371 372 for (i = 0; i < MAX_ASSOCIATED_TTYS; i++) { 373 struct ipw_tty *tty = network->associated_ttys[channel_idx][i]; 374 375 if (!tty) 376 continue; 377 378 /* 379 * If it's associated with a tty (other than the RAS channel 380 * when we're online), then send the data to that tty. The RAS 381 * channel's data is handled above - it always goes through 382 * ppp_generic. 383 */ 384 if (channel_idx == IPW_CHANNEL_RAS 385 && (network->ras_control_lines & 386 IPW_CONTROL_LINE_DCD) != 0 387 && ipwireless_tty_is_modem(tty)) { 388 /* 389 * If data came in on the RAS channel and this tty is 390 * the modem tty, and we are online, then we send it to 391 * the PPP layer. 392 */ 393 mutex_lock(&network->close_lock); 394 spin_lock_irqsave(&network->lock, flags); 395 if (network->ppp_channel != NULL) { 396 struct sk_buff *skb; 397 398 spin_unlock_irqrestore(&network->lock, 399 flags); 400 401 /* Send the data to the ppp_generic module. */ 402 skb = ipw_packet_received_skb(data, length); 403 if (skb) 404 ppp_input(network->ppp_channel, skb); 405 } else 406 spin_unlock_irqrestore(&network->lock, 407 flags); 408 mutex_unlock(&network->close_lock); 409 } 410 /* Otherwise we send it out the tty. */ 411 else 412 ipwireless_tty_received(tty, data, length); 413 } 414} 415 416struct ipw_network *ipwireless_network_create(struct ipw_hardware *hw) 417{ 418 struct ipw_network *network = 419 kzalloc(sizeof(struct ipw_network), GFP_KERNEL); 420 421 if (!network) 422 return NULL; 423 424 spin_lock_init(&network->lock); 425 mutex_init(&network->close_lock); 426 427 network->hardware = hw; 428 429 INIT_WORK(&network->work_go_online, do_go_online); 430 INIT_WORK(&network->work_go_offline, do_go_offline); 431 432 ipwireless_associate_network(hw, network); 433 434 return network; 435} 436 437void ipwireless_network_free(struct ipw_network *network) 438{ 439 network->shutting_down = 1; 440 441 ipwireless_ppp_close(network); 442 flush_work(&network->work_go_online); 443 flush_work(&network->work_go_offline); 444 445 ipwireless_stop_interrupts(network->hardware); 446 ipwireless_associate_network(network->hardware, NULL); 447 448 kfree(network); 449} 450 451void ipwireless_associate_network_tty(struct ipw_network *network, 452 unsigned int channel_idx, 453 struct ipw_tty *tty) 454{ 455 int i; 456 457 for (i = 0; i < MAX_ASSOCIATED_TTYS; i++) 458 if (network->associated_ttys[channel_idx][i] == NULL) { 459 network->associated_ttys[channel_idx][i] = tty; 460 break; 461 } 462} 463 464void ipwireless_disassociate_network_ttys(struct ipw_network *network, 465 unsigned int channel_idx) 466{ 467 int i; 468 469 for (i = 0; i < MAX_ASSOCIATED_TTYS; i++) 470 network->associated_ttys[channel_idx][i] = NULL; 471} 472 473void ipwireless_ppp_open(struct ipw_network *network) 474{ 475 if (ipwireless_debug) 476 printk(KERN_DEBUG IPWIRELESS_PCCARD_NAME ": online\n"); 477 schedule_work(&network->work_go_online); 478} 479 480void ipwireless_ppp_close(struct ipw_network *network) 481{ 482 /* Disconnect from the wireless network. */ 483 if (ipwireless_debug) 484 printk(KERN_DEBUG IPWIRELESS_PCCARD_NAME ": offline\n"); 485 schedule_work(&network->work_go_offline); 486} 487 488int ipwireless_ppp_channel_index(struct ipw_network *network) 489{ 490 int ret = -1; 491 unsigned long flags; 492 493 spin_lock_irqsave(&network->lock, flags); 494 if (network->ppp_channel != NULL) 495 ret = ppp_channel_index(network->ppp_channel); 496 spin_unlock_irqrestore(&network->lock, flags); 497 498 return ret; 499} 500 501int ipwireless_ppp_unit_number(struct ipw_network *network) 502{ 503 int ret = -1; 504 unsigned long flags; 505 506 spin_lock_irqsave(&network->lock, flags); 507 if (network->ppp_channel != NULL) 508 ret = ppp_unit_number(network->ppp_channel); 509 spin_unlock_irqrestore(&network->lock, flags); 510 511 return ret; 512} 513 514int ipwireless_ppp_mru(const struct ipw_network *network) 515{ 516 return network->mru; 517}