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 "hardware.h" 20 #include "network.h" 21 #include "main.h" 22 #include "tty.h" 23 24 #include <linux/delay.h> 25 #include <linux/init.h> 26 #include <linux/io.h> 27 #include <linux/kernel.h> 28 #include <linux/module.h> 29 #include <linux/sched.h> 30 #include <linux/slab.h> 31 32 #include <pcmcia/cisreg.h> 33 #include <pcmcia/device_id.h> 34 #include <pcmcia/ss.h> 35 #include <pcmcia/ds.h> 36 37 static const struct pcmcia_device_id ipw_ids[] = { 38 PCMCIA_DEVICE_MANF_CARD(0x02f2, 0x0100), 39 PCMCIA_DEVICE_MANF_CARD(0x02f2, 0x0200), 40 PCMCIA_DEVICE_NULL 41 }; 42 MODULE_DEVICE_TABLE(pcmcia, ipw_ids); 43 44 static void ipwireless_detach(struct pcmcia_device *link); 45 46 /* 47 * Module params 48 */ 49 /* Debug mode: more verbose, print sent/recv bytes */ 50 int ipwireless_debug; 51 int ipwireless_loopback; 52 int ipwireless_out_queue = 10; 53 54 module_param_named(debug, ipwireless_debug, int, 0); 55 module_param_named(loopback, ipwireless_loopback, int, 0); 56 module_param_named(out_queue, ipwireless_out_queue, int, 0); 57 MODULE_PARM_DESC(debug, "switch on debug messages [0]"); 58 MODULE_PARM_DESC(loopback, 59 "debug: enable ras_raw channel [0]"); 60 MODULE_PARM_DESC(out_queue, "debug: set size of outgoing PPP queue [10]"); 61 62 /* Executes in process context. */ 63 static void signalled_reboot_work(struct work_struct *work_reboot) 64 { 65 struct ipw_dev *ipw = container_of(work_reboot, struct ipw_dev, 66 work_reboot); 67 struct pcmcia_device *link = ipw->link; 68 pcmcia_reset_card(link->socket); 69 } 70 71 static void signalled_reboot_callback(void *callback_data) 72 { 73 struct ipw_dev *ipw = (struct ipw_dev *) callback_data; 74 75 /* Delegate to process context. */ 76 schedule_work(&ipw->work_reboot); 77 } 78 79 static int ipwireless_probe(struct pcmcia_device *p_dev, void *priv_data) 80 { 81 struct ipw_dev *ipw = priv_data; 82 int ret; 83 84 p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH; 85 p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO; 86 87 /* 0x40 causes it to generate level mode interrupts. */ 88 /* 0x04 enables IREQ pin. */ 89 p_dev->config_index |= 0x44; 90 p_dev->io_lines = 16; 91 ret = pcmcia_request_io(p_dev); 92 if (ret) 93 return ret; 94 95 if (!request_region(p_dev->resource[0]->start, 96 resource_size(p_dev->resource[0]), 97 IPWIRELESS_PCCARD_NAME)) { 98 ret = -EBUSY; 99 goto exit; 100 } 101 102 p_dev->resource[2]->flags |= 103 WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_CM | WIN_ENABLE; 104 105 ret = pcmcia_request_window(p_dev, p_dev->resource[2], 0); 106 if (ret != 0) 107 goto exit1; 108 109 ret = pcmcia_map_mem_page(p_dev, p_dev->resource[2], p_dev->card_addr); 110 if (ret != 0) 111 goto exit1; 112 113 ipw->is_v2_card = resource_size(p_dev->resource[2]) == 0x100; 114 115 ipw->common_memory = ioremap(p_dev->resource[2]->start, 116 resource_size(p_dev->resource[2])); 117 if (!request_mem_region(p_dev->resource[2]->start, 118 resource_size(p_dev->resource[2]), 119 IPWIRELESS_PCCARD_NAME)) { 120 ret = -EBUSY; 121 goto exit2; 122 } 123 124 p_dev->resource[3]->flags |= WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_AM | 125 WIN_ENABLE; 126 p_dev->resource[3]->end = 0; /* this used to be 0x1000 */ 127 ret = pcmcia_request_window(p_dev, p_dev->resource[3], 0); 128 if (ret != 0) 129 goto exit3; 130 131 ret = pcmcia_map_mem_page(p_dev, p_dev->resource[3], 0); 132 if (ret != 0) 133 goto exit3; 134 135 ipw->attr_memory = ioremap(p_dev->resource[3]->start, 136 resource_size(p_dev->resource[3])); 137 if (!request_mem_region(p_dev->resource[3]->start, 138 resource_size(p_dev->resource[3]), 139 IPWIRELESS_PCCARD_NAME)) { 140 ret = -EBUSY; 141 goto exit4; 142 } 143 144 return 0; 145 146 exit4: 147 iounmap(ipw->attr_memory); 148 exit3: 149 release_mem_region(p_dev->resource[2]->start, 150 resource_size(p_dev->resource[2])); 151 exit2: 152 iounmap(ipw->common_memory); 153 exit1: 154 release_region(p_dev->resource[0]->start, 155 resource_size(p_dev->resource[0])); 156 exit: 157 pcmcia_disable_device(p_dev); 158 return ret; 159 } 160 161 static int config_ipwireless(struct ipw_dev *ipw) 162 { 163 struct pcmcia_device *link = ipw->link; 164 int ret = 0; 165 166 ipw->is_v2_card = 0; 167 link->config_flags |= CONF_AUTO_SET_IO | CONF_AUTO_SET_IOMEM | 168 CONF_ENABLE_IRQ; 169 170 ret = pcmcia_loop_config(link, ipwireless_probe, ipw); 171 if (ret != 0) 172 return ret; 173 174 INIT_WORK(&ipw->work_reboot, signalled_reboot_work); 175 176 ipwireless_init_hardware_v1(ipw->hardware, link->resource[0]->start, 177 ipw->attr_memory, ipw->common_memory, 178 ipw->is_v2_card, signalled_reboot_callback, 179 ipw); 180 181 ret = pcmcia_request_irq(link, ipwireless_interrupt); 182 if (ret != 0) 183 goto exit; 184 185 printk(KERN_INFO IPWIRELESS_PCCARD_NAME ": Card type %s\n", 186 ipw->is_v2_card ? "V2/V3" : "V1"); 187 printk(KERN_INFO IPWIRELESS_PCCARD_NAME 188 ": I/O ports %pR, irq %d\n", link->resource[0], 189 (unsigned int) link->irq); 190 if (ipw->attr_memory && ipw->common_memory) 191 printk(KERN_INFO IPWIRELESS_PCCARD_NAME 192 ": attr memory %pR, common memory %pR\n", 193 link->resource[3], 194 link->resource[2]); 195 196 ipw->network = ipwireless_network_create(ipw->hardware); 197 if (!ipw->network) 198 goto exit; 199 200 ipw->tty = ipwireless_tty_create(ipw->hardware, ipw->network); 201 if (!ipw->tty) 202 goto exit; 203 204 ipwireless_init_hardware_v2_v3(ipw->hardware); 205 206 /* 207 * Do the RequestConfiguration last, because it enables interrupts. 208 * Then we don't get any interrupts before we're ready for them. 209 */ 210 ret = pcmcia_enable_device(link); 211 if (ret != 0) 212 goto exit; 213 214 return 0; 215 216 exit: 217 if (ipw->common_memory) { 218 release_mem_region(link->resource[2]->start, 219 resource_size(link->resource[2])); 220 iounmap(ipw->common_memory); 221 } 222 if (ipw->attr_memory) { 223 release_mem_region(link->resource[3]->start, 224 resource_size(link->resource[3])); 225 iounmap(ipw->attr_memory); 226 } 227 pcmcia_disable_device(link); 228 return -1; 229 } 230 231 static void release_ipwireless(struct ipw_dev *ipw) 232 { 233 release_region(ipw->link->resource[0]->start, 234 resource_size(ipw->link->resource[0])); 235 if (ipw->common_memory) { 236 release_mem_region(ipw->link->resource[2]->start, 237 resource_size(ipw->link->resource[2])); 238 iounmap(ipw->common_memory); 239 } 240 if (ipw->attr_memory) { 241 release_mem_region(ipw->link->resource[3]->start, 242 resource_size(ipw->link->resource[3])); 243 iounmap(ipw->attr_memory); 244 } 245 pcmcia_disable_device(ipw->link); 246 } 247 248 /* 249 * ipwireless_attach() creates an "instance" of the driver, allocating 250 * local data structures for one device (one interface). The device 251 * is registered with Card Services. 252 * 253 * The pcmcia_device structure is initialized, but we don't actually 254 * configure the card at this point -- we wait until we receive a 255 * card insertion event. 256 */ 257 static int ipwireless_attach(struct pcmcia_device *link) 258 { 259 struct ipw_dev *ipw; 260 int ret; 261 262 ipw = kzalloc(sizeof(struct ipw_dev), GFP_KERNEL); 263 if (!ipw) 264 return -ENOMEM; 265 266 ipw->link = link; 267 link->priv = ipw; 268 269 ipw->hardware = ipwireless_hardware_create(); 270 if (!ipw->hardware) { 271 kfree(ipw); 272 return -ENOMEM; 273 } 274 /* RegisterClient will call config_ipwireless */ 275 276 ret = config_ipwireless(ipw); 277 278 if (ret != 0) { 279 ipwireless_detach(link); 280 return ret; 281 } 282 283 return 0; 284 } 285 286 /* 287 * This deletes a driver "instance". The device is de-registered with 288 * Card Services. If it has been released, all local data structures 289 * are freed. Otherwise, the structures will be freed when the device 290 * is released. 291 */ 292 static void ipwireless_detach(struct pcmcia_device *link) 293 { 294 struct ipw_dev *ipw = link->priv; 295 296 release_ipwireless(ipw); 297 298 if (ipw->tty != NULL) 299 ipwireless_tty_free(ipw->tty); 300 if (ipw->network != NULL) 301 ipwireless_network_free(ipw->network); 302 if (ipw->hardware != NULL) 303 ipwireless_hardware_free(ipw->hardware); 304 kfree(ipw); 305 } 306 307 static struct pcmcia_driver me = { 308 .owner = THIS_MODULE, 309 .probe = ipwireless_attach, 310 .remove = ipwireless_detach, 311 .name = IPWIRELESS_PCCARD_NAME, 312 .id_table = ipw_ids 313 }; 314 315 /* 316 * Module insertion : initialisation of the module. 317 * Register the card with cardmgr... 318 */ 319 static int __init init_ipwireless(void) 320 { 321 int ret; 322 323 ret = ipwireless_tty_init(); 324 if (ret != 0) 325 return ret; 326 327 ret = pcmcia_register_driver(&me); 328 if (ret != 0) 329 ipwireless_tty_release(); 330 331 return ret; 332 } 333 334 /* 335 * Module removal 336 */ 337 static void __exit exit_ipwireless(void) 338 { 339 pcmcia_unregister_driver(&me); 340 ipwireless_tty_release(); 341 } 342 343 module_init(init_ipwireless); 344 module_exit(exit_ipwireless); 345 346 MODULE_AUTHOR(IPWIRELESS_PCMCIA_AUTHOR); 347 MODULE_DESCRIPTION(IPWIRELESS_PCCARD_NAME " " IPWIRELESS_PCMCIA_VERSION); 348 MODULE_LICENSE("GPL"); 349