aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/hostap/hostap_cs.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/hostap/hostap_cs.c')
-rw-r--r--drivers/net/wireless/hostap/hostap_cs.c120
1 files changed, 81 insertions, 39 deletions
diff --git a/drivers/net/wireless/hostap/hostap_cs.c b/drivers/net/wireless/hostap/hostap_cs.c
index 3210c99694e6..70242459d57a 100644
--- a/drivers/net/wireless/hostap/hostap_cs.c
+++ b/drivers/net/wireless/hostap/hostap_cs.c
@@ -40,6 +40,14 @@ module_param(ignore_cis_vcc, int, 0444);
40MODULE_PARM_DESC(ignore_cis_vcc, "Ignore broken CIS VCC entry"); 40MODULE_PARM_DESC(ignore_cis_vcc, "Ignore broken CIS VCC entry");
41 41
42 42
43/* struct local_info::hw_priv */
44struct hostap_cs_priv {
45 dev_node_t node;
46 dev_link_t *link;
47 int sandisk_connectplus;
48};
49
50
43#ifdef PRISM2_IO_DEBUG 51#ifdef PRISM2_IO_DEBUG
44 52
45static inline void hfa384x_outb_debug(struct net_device *dev, int a, u8 v) 53static inline void hfa384x_outb_debug(struct net_device *dev, int a, u8 v)
@@ -203,8 +211,9 @@ static int prism2_event(event_t event, int priority,
203 211
204static int prism2_pccard_card_present(local_info_t *local) 212static int prism2_pccard_card_present(local_info_t *local)
205{ 213{
206 if (local->link != NULL && 214 struct hostap_cs_priv *hw_priv = local->hw_priv;
207 ((local->link->state & (DEV_PRESENT | DEV_CONFIG)) == 215 if (hw_priv->link != NULL &&
216 ((hw_priv->link->state & (DEV_PRESENT | DEV_CONFIG)) ==
208 (DEV_PRESENT | DEV_CONFIG))) 217 (DEV_PRESENT | DEV_CONFIG)))
209 return 1; 218 return 1;
210 return 0; 219 return 0;
@@ -224,12 +233,14 @@ static void sandisk_set_iobase(local_info_t *local)
224{ 233{
225 int res; 234 int res;
226 conf_reg_t reg; 235 conf_reg_t reg;
236 struct hostap_cs_priv *hw_priv = local->hw_priv;
227 237
228 reg.Function = 0; 238 reg.Function = 0;
229 reg.Action = CS_WRITE; 239 reg.Action = CS_WRITE;
230 reg.Offset = 0x10; /* 0x3f0 IO base 1 */ 240 reg.Offset = 0x10; /* 0x3f0 IO base 1 */
231 reg.Value = local->link->io.BasePort1 & 0x00ff; 241 reg.Value = hw_priv->link->io.BasePort1 & 0x00ff;
232 res = pcmcia_access_configuration_register(local->link->handle, &reg); 242 res = pcmcia_access_configuration_register(hw_priv->link->handle,
243 &reg);
233 if (res != CS_SUCCESS) { 244 if (res != CS_SUCCESS) {
234 printk(KERN_DEBUG "Prism3 SanDisk - failed to set I/O base 0 -" 245 printk(KERN_DEBUG "Prism3 SanDisk - failed to set I/O base 0 -"
235 " res=%d\n", res); 246 " res=%d\n", res);
@@ -239,8 +250,9 @@ static void sandisk_set_iobase(local_info_t *local)
239 reg.Function = 0; 250 reg.Function = 0;
240 reg.Action = CS_WRITE; 251 reg.Action = CS_WRITE;
241 reg.Offset = 0x12; /* 0x3f2 IO base 2 */ 252 reg.Offset = 0x12; /* 0x3f2 IO base 2 */
242 reg.Value = (local->link->io.BasePort1 & 0xff00) >> 8; 253 reg.Value = (hw_priv->link->io.BasePort1 & 0xff00) >> 8;
243 res = pcmcia_access_configuration_register(local->link->handle, &reg); 254 res = pcmcia_access_configuration_register(hw_priv->link->handle,
255 &reg);
244 if (res != CS_SUCCESS) { 256 if (res != CS_SUCCESS) {
245 printk(KERN_DEBUG "Prism3 SanDisk - failed to set I/O base 1 -" 257 printk(KERN_DEBUG "Prism3 SanDisk - failed to set I/O base 1 -"
246 " res=%d\n", res); 258 " res=%d\n", res);
@@ -272,8 +284,9 @@ static int sandisk_enable_wireless(struct net_device *dev)
272 tuple_t tuple; 284 tuple_t tuple;
273 cisparse_t *parse = NULL; 285 cisparse_t *parse = NULL;
274 u_char buf[64]; 286 u_char buf[64];
287 struct hostap_cs_priv *hw_priv = local->hw_priv;
275 288
276 if (local->link->io.NumPorts1 < 0x42) { 289 if (hw_priv->link->io.NumPorts1 < 0x42) {
277 /* Not enough ports to be SanDisk multi-function card */ 290 /* Not enough ports to be SanDisk multi-function card */
278 ret = -ENODEV; 291 ret = -ENODEV;
279 goto done; 292 goto done;
@@ -290,9 +303,9 @@ static int sandisk_enable_wireless(struct net_device *dev)
290 tuple.TupleData = buf; 303 tuple.TupleData = buf;
291 tuple.TupleDataMax = sizeof(buf); 304 tuple.TupleDataMax = sizeof(buf);
292 tuple.TupleOffset = 0; 305 tuple.TupleOffset = 0;
293 if (pcmcia_get_first_tuple(local->link->handle, &tuple) || 306 if (pcmcia_get_first_tuple(hw_priv->link->handle, &tuple) ||
294 pcmcia_get_tuple_data(local->link->handle, &tuple) || 307 pcmcia_get_tuple_data(hw_priv->link->handle, &tuple) ||
295 pcmcia_parse_tuple(local->link->handle, &tuple, parse) || 308 pcmcia_parse_tuple(hw_priv->link->handle, &tuple, parse) ||
296 parse->manfid.manf != 0xd601 || parse->manfid.card != 0x0101) { 309 parse->manfid.manf != 0xd601 || parse->manfid.card != 0x0101) {
297 /* No SanDisk manfid found */ 310 /* No SanDisk manfid found */
298 ret = -ENODEV; 311 ret = -ENODEV;
@@ -300,9 +313,9 @@ static int sandisk_enable_wireless(struct net_device *dev)
300 } 313 }
301 314
302 tuple.DesiredTuple = CISTPL_LONGLINK_MFC; 315 tuple.DesiredTuple = CISTPL_LONGLINK_MFC;
303 if (pcmcia_get_first_tuple(local->link->handle, &tuple) || 316 if (pcmcia_get_first_tuple(hw_priv->link->handle, &tuple) ||
304 pcmcia_get_tuple_data(local->link->handle, &tuple) || 317 pcmcia_get_tuple_data(hw_priv->link->handle, &tuple) ||
305 pcmcia_parse_tuple(local->link->handle, &tuple, parse) || 318 pcmcia_parse_tuple(hw_priv->link->handle, &tuple, parse) ||
306 parse->longlink_mfc.nfn < 2) { 319 parse->longlink_mfc.nfn < 2) {
307 /* No multi-function links found */ 320 /* No multi-function links found */
308 ret = -ENODEV; 321 ret = -ENODEV;
@@ -311,13 +324,14 @@ static int sandisk_enable_wireless(struct net_device *dev)
311 324
312 printk(KERN_DEBUG "%s: Multi-function SanDisk ConnectPlus detected" 325 printk(KERN_DEBUG "%s: Multi-function SanDisk ConnectPlus detected"
313 " - using vendor-specific initialization\n", dev->name); 326 " - using vendor-specific initialization\n", dev->name);
314 local->sandisk_connectplus = 1; 327 hw_priv->sandisk_connectplus = 1;
315 328
316 reg.Function = 0; 329 reg.Function = 0;
317 reg.Action = CS_WRITE; 330 reg.Action = CS_WRITE;
318 reg.Offset = CISREG_COR; 331 reg.Offset = CISREG_COR;
319 reg.Value = COR_SOFT_RESET; 332 reg.Value = COR_SOFT_RESET;
320 res = pcmcia_access_configuration_register(local->link->handle, &reg); 333 res = pcmcia_access_configuration_register(hw_priv->link->handle,
334 &reg);
321 if (res != CS_SUCCESS) { 335 if (res != CS_SUCCESS) {
322 printk(KERN_DEBUG "%s: SanDisk - COR sreset failed (%d)\n", 336 printk(KERN_DEBUG "%s: SanDisk - COR sreset failed (%d)\n",
323 dev->name, res); 337 dev->name, res);
@@ -333,7 +347,8 @@ static int sandisk_enable_wireless(struct net_device *dev)
333 * will be enabled during the first cor_sreset call. 347 * will be enabled during the first cor_sreset call.
334 */ 348 */
335 reg.Value = COR_LEVEL_REQ | 0x8 | COR_ADDR_DECODE | COR_FUNC_ENA; 349 reg.Value = COR_LEVEL_REQ | 0x8 | COR_ADDR_DECODE | COR_FUNC_ENA;
336 res = pcmcia_access_configuration_register(local->link->handle, &reg); 350 res = pcmcia_access_configuration_register(hw_priv->link->handle,
351 &reg);
337 if (res != CS_SUCCESS) { 352 if (res != CS_SUCCESS) {
338 printk(KERN_DEBUG "%s: SanDisk - COR sreset failed (%d)\n", 353 printk(KERN_DEBUG "%s: SanDisk - COR sreset failed (%d)\n",
339 dev->name, res); 354 dev->name, res);
@@ -358,6 +373,7 @@ static void prism2_pccard_cor_sreset(local_info_t *local)
358{ 373{
359 int res; 374 int res;
360 conf_reg_t reg; 375 conf_reg_t reg;
376 struct hostap_cs_priv *hw_priv = local->hw_priv;
361 377
362 if (!prism2_pccard_card_present(local)) 378 if (!prism2_pccard_card_present(local))
363 return; 379 return;
@@ -366,7 +382,8 @@ static void prism2_pccard_cor_sreset(local_info_t *local)
366 reg.Action = CS_READ; 382 reg.Action = CS_READ;
367 reg.Offset = CISREG_COR; 383 reg.Offset = CISREG_COR;
368 reg.Value = 0; 384 reg.Value = 0;
369 res = pcmcia_access_configuration_register(local->link->handle, &reg); 385 res = pcmcia_access_configuration_register(hw_priv->link->handle,
386 &reg);
370 if (res != CS_SUCCESS) { 387 if (res != CS_SUCCESS) {
371 printk(KERN_DEBUG "prism2_pccard_cor_sreset failed 1 (%d)\n", 388 printk(KERN_DEBUG "prism2_pccard_cor_sreset failed 1 (%d)\n",
372 res); 389 res);
@@ -377,28 +394,30 @@ static void prism2_pccard_cor_sreset(local_info_t *local)
377 394
378 reg.Action = CS_WRITE; 395 reg.Action = CS_WRITE;
379 reg.Value |= COR_SOFT_RESET; 396 reg.Value |= COR_SOFT_RESET;
380 res = pcmcia_access_configuration_register(local->link->handle, &reg); 397 res = pcmcia_access_configuration_register(hw_priv->link->handle,
398 &reg);
381 if (res != CS_SUCCESS) { 399 if (res != CS_SUCCESS) {
382 printk(KERN_DEBUG "prism2_pccard_cor_sreset failed 2 (%d)\n", 400 printk(KERN_DEBUG "prism2_pccard_cor_sreset failed 2 (%d)\n",
383 res); 401 res);
384 return; 402 return;
385 } 403 }
386 404
387 mdelay(local->sandisk_connectplus ? 5 : 2); 405 mdelay(hw_priv->sandisk_connectplus ? 5 : 2);
388 406
389 reg.Value &= ~COR_SOFT_RESET; 407 reg.Value &= ~COR_SOFT_RESET;
390 if (local->sandisk_connectplus) 408 if (hw_priv->sandisk_connectplus)
391 reg.Value |= COR_IREQ_ENA; 409 reg.Value |= COR_IREQ_ENA;
392 res = pcmcia_access_configuration_register(local->link->handle, &reg); 410 res = pcmcia_access_configuration_register(hw_priv->link->handle,
411 &reg);
393 if (res != CS_SUCCESS) { 412 if (res != CS_SUCCESS) {
394 printk(KERN_DEBUG "prism2_pccard_cor_sreset failed 3 (%d)\n", 413 printk(KERN_DEBUG "prism2_pccard_cor_sreset failed 3 (%d)\n",
395 res); 414 res);
396 return; 415 return;
397 } 416 }
398 417
399 mdelay(local->sandisk_connectplus ? 5 : 2); 418 mdelay(hw_priv->sandisk_connectplus ? 5 : 2);
400 419
401 if (local->sandisk_connectplus) 420 if (hw_priv->sandisk_connectplus)
402 sandisk_set_iobase(local); 421 sandisk_set_iobase(local);
403} 422}
404 423
@@ -408,11 +427,12 @@ static void prism2_pccard_genesis_reset(local_info_t *local, int hcr)
408 int res; 427 int res;
409 conf_reg_t reg; 428 conf_reg_t reg;
410 int old_cor; 429 int old_cor;
430 struct hostap_cs_priv *hw_priv = local->hw_priv;
411 431
412 if (!prism2_pccard_card_present(local)) 432 if (!prism2_pccard_card_present(local))
413 return; 433 return;
414 434
415 if (local->sandisk_connectplus) { 435 if (hw_priv->sandisk_connectplus) {
416 sandisk_write_hcr(local, hcr); 436 sandisk_write_hcr(local, hcr);
417 return; 437 return;
418 } 438 }
@@ -421,7 +441,8 @@ static void prism2_pccard_genesis_reset(local_info_t *local, int hcr)
421 reg.Action = CS_READ; 441 reg.Action = CS_READ;
422 reg.Offset = CISREG_COR; 442 reg.Offset = CISREG_COR;
423 reg.Value = 0; 443 reg.Value = 0;
424 res = pcmcia_access_configuration_register(local->link->handle, &reg); 444 res = pcmcia_access_configuration_register(hw_priv->link->handle,
445 &reg);
425 if (res != CS_SUCCESS) { 446 if (res != CS_SUCCESS) {
426 printk(KERN_DEBUG "prism2_pccard_genesis_sreset failed 1 " 447 printk(KERN_DEBUG "prism2_pccard_genesis_sreset failed 1 "
427 "(%d)\n", res); 448 "(%d)\n", res);
@@ -433,7 +454,8 @@ static void prism2_pccard_genesis_reset(local_info_t *local, int hcr)
433 454
434 reg.Action = CS_WRITE; 455 reg.Action = CS_WRITE;
435 reg.Value |= COR_SOFT_RESET; 456 reg.Value |= COR_SOFT_RESET;
436 res = pcmcia_access_configuration_register(local->link->handle, &reg); 457 res = pcmcia_access_configuration_register(hw_priv->link->handle,
458 &reg);
437 if (res != CS_SUCCESS) { 459 if (res != CS_SUCCESS) {
438 printk(KERN_DEBUG "prism2_pccard_genesis_sreset failed 2 " 460 printk(KERN_DEBUG "prism2_pccard_genesis_sreset failed 2 "
439 "(%d)\n", res); 461 "(%d)\n", res);
@@ -446,7 +468,8 @@ static void prism2_pccard_genesis_reset(local_info_t *local, int hcr)
446 reg.Action = CS_WRITE; 468 reg.Action = CS_WRITE;
447 reg.Value = hcr; 469 reg.Value = hcr;
448 reg.Offset = CISREG_CCSR; 470 reg.Offset = CISREG_CCSR;
449 res = pcmcia_access_configuration_register(local->link->handle, &reg); 471 res = pcmcia_access_configuration_register(hw_priv->link->handle,
472 &reg);
450 if (res != CS_SUCCESS) { 473 if (res != CS_SUCCESS) {
451 printk(KERN_DEBUG "prism2_pccard_genesis_sreset failed 3 " 474 printk(KERN_DEBUG "prism2_pccard_genesis_sreset failed 3 "
452 "(%d)\n", res); 475 "(%d)\n", res);
@@ -457,7 +480,8 @@ static void prism2_pccard_genesis_reset(local_info_t *local, int hcr)
457 reg.Action = CS_WRITE; 480 reg.Action = CS_WRITE;
458 reg.Offset = CISREG_COR; 481 reg.Offset = CISREG_COR;
459 reg.Value = old_cor & ~COR_SOFT_RESET; 482 reg.Value = old_cor & ~COR_SOFT_RESET;
460 res = pcmcia_access_configuration_register(local->link->handle, &reg); 483 res = pcmcia_access_configuration_register(hw_priv->link->handle,
484 &reg);
461 if (res != CS_SUCCESS) { 485 if (res != CS_SUCCESS) {
462 printk(KERN_DEBUG "prism2_pccard_genesis_sreset failed 4 " 486 printk(KERN_DEBUG "prism2_pccard_genesis_sreset failed 4 "
463 "(%d)\n", res); 487 "(%d)\n", res);
@@ -470,23 +494,29 @@ static void prism2_pccard_genesis_reset(local_info_t *local, int hcr)
470 494
471static int prism2_pccard_dev_open(local_info_t *local) 495static int prism2_pccard_dev_open(local_info_t *local)
472{ 496{
473 local->link->open++; 497 struct hostap_cs_priv *hw_priv = local->hw_priv;
498 hw_priv->link->open++;
474 return 0; 499 return 0;
475} 500}
476 501
477 502
478static int prism2_pccard_dev_close(local_info_t *local) 503static int prism2_pccard_dev_close(local_info_t *local)
479{ 504{
480 if (local == NULL || local->link == NULL) 505 struct hostap_cs_priv *hw_priv;
506
507 if (local == NULL || local->hw_priv == NULL)
508 return 1;
509 hw_priv = local->hw_priv;
510 if (hw_priv->link == NULL)
481 return 1; 511 return 1;
482 512
483 if (!local->link->open) { 513 if (!hw_priv->link->open) {
484 printk(KERN_WARNING "%s: prism2_pccard_dev_close(): " 514 printk(KERN_WARNING "%s: prism2_pccard_dev_close(): "
485 "link not open?!\n", local->dev->name); 515 "link not open?!\n", local->dev->name);
486 return 1; 516 return 1;
487 } 517 }
488 518
489 local->link->open--; 519 hw_priv->link->open--;
490 520
491 return 0; 521 return 0;
492} 522}
@@ -567,8 +597,13 @@ static void prism2_detach(dev_link_t *link)
567 *linkp = link->next; 597 *linkp = link->next;
568 /* release net devices */ 598 /* release net devices */
569 if (link->priv) { 599 if (link->priv) {
570 prism2_free_local_data((struct net_device *) link->priv); 600 struct net_device *dev;
571 601 struct hostap_interface *iface;
602 dev = link->priv;
603 iface = netdev_priv(dev);
604 kfree(iface->local->hw_priv);
605 iface->local->hw_priv = NULL;
606 prism2_free_local_data(dev);
572 } 607 }
573 kfree(link); 608 kfree(link);
574} 609}
@@ -601,14 +636,19 @@ static int prism2_config(dev_link_t *link)
601 u_char buf[64]; 636 u_char buf[64];
602 config_info_t conf; 637 config_info_t conf;
603 cistpl_cftable_entry_t dflt = { 0 }; 638 cistpl_cftable_entry_t dflt = { 0 };
639 struct hostap_cs_priv *hw_priv;
604 640
605 PDEBUG(DEBUG_FLOW, "prism2_config()\n"); 641 PDEBUG(DEBUG_FLOW, "prism2_config()\n");
606 642
607 parse = kmalloc(sizeof(cisparse_t), GFP_KERNEL); 643 parse = kmalloc(sizeof(cisparse_t), GFP_KERNEL);
608 if (parse == NULL) { 644 hw_priv = kmalloc(sizeof(*hw_priv), GFP_KERNEL);
645 if (parse == NULL || hw_priv == NULL) {
646 kfree(parse);
647 kfree(hw_priv);
609 ret = -ENOMEM; 648 ret = -ENOMEM;
610 goto failed; 649 goto failed;
611 } 650 }
651 memset(hw_priv, 0, sizeof(*hw_priv));
612 652
613 tuple.DesiredTuple = CISTPL_CONFIG; 653 tuple.DesiredTuple = CISTPL_CONFIG;
614 tuple.Attributes = 0; 654 tuple.Attributes = 0;
@@ -779,9 +819,10 @@ static int prism2_config(dev_link_t *link)
779 819
780 iface = netdev_priv(dev); 820 iface = netdev_priv(dev);
781 local = iface->local; 821 local = iface->local;
782 local->link = link; 822 local->hw_priv = hw_priv;
783 strcpy(local->node.dev_name, dev->name); 823 hw_priv->link = link;
784 link->dev = &local->node; 824 strcpy(hw_priv->node.dev_name, dev->name);
825 link->dev = &hw_priv->node;
785 826
786 local->shutdown = 0; 827 local->shutdown = 0;
787 828
@@ -791,7 +832,7 @@ static int prism2_config(dev_link_t *link)
791 if (!ret) { 832 if (!ret) {
792 ret = hostap_hw_ready(dev); 833 ret = hostap_hw_ready(dev);
793 if (ret == 0 && local->ddev) 834 if (ret == 0 && local->ddev)
794 strcpy(local->node.dev_name, local->ddev->name); 835 strcpy(hw_priv->node.dev_name, local->ddev->name);
795 } 836 }
796 kfree(parse); 837 kfree(parse);
797 return ret; 838 return ret;
@@ -801,6 +842,7 @@ static int prism2_config(dev_link_t *link)
801 842
802 failed: 843 failed:
803 kfree(parse); 844 kfree(parse);
845 kfree(hw_priv);
804 prism2_release((u_long)link); 846 prism2_release((u_long)link);
805 return ret; 847 return ret;
806} 848}