diff options
author | Daniel Drake <dsd@gentoo.org> | 2008-07-03 23:30:49 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-07-08 14:16:03 -0400 |
commit | f2cae6c5e41a979f85463aff60877b31fa3a383d (patch) | |
tree | 5cc72cc6a6bd4a424b093589dbcaad2843994dbf /drivers/net/wireless/zd1211rw | |
parent | 6ef307bc561911c8cdda98ef3896b5982b602a43 (diff) |
zd1211rw: beacon config error checking
Add some error checking to the new beacon configuration code.
Signed-off-by: Daniel Drake <dsd@gentoo.org>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/zd1211rw')
-rw-r--r-- | drivers/net/wireless/zd1211rw/zd_mac.c | 62 |
1 files changed, 45 insertions, 17 deletions
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c index 317c5e24f80c..665f76af2fec 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.c +++ b/drivers/net/wireless/zd1211rw/zd_mac.c | |||
@@ -405,43 +405,66 @@ static void cs_set_control(struct zd_mac *mac, struct zd_ctrlset *cs, | |||
405 | /* FIXME: Management frame? */ | 405 | /* FIXME: Management frame? */ |
406 | } | 406 | } |
407 | 407 | ||
408 | void zd_mac_config_beacon(struct ieee80211_hw *hw, struct sk_buff *beacon) | 408 | static int zd_mac_config_beacon(struct ieee80211_hw *hw, struct sk_buff *beacon) |
409 | { | 409 | { |
410 | struct zd_mac *mac = zd_hw_mac(hw); | 410 | struct zd_mac *mac = zd_hw_mac(hw); |
411 | int r; | ||
411 | u32 tmp, j = 0; | 412 | u32 tmp, j = 0; |
412 | /* 4 more bytes for tail CRC */ | 413 | /* 4 more bytes for tail CRC */ |
413 | u32 full_len = beacon->len + 4; | 414 | u32 full_len = beacon->len + 4; |
414 | zd_iowrite32(&mac->chip, CR_BCN_FIFO_SEMAPHORE, 0); | 415 | |
415 | zd_ioread32(&mac->chip, CR_BCN_FIFO_SEMAPHORE, &tmp); | 416 | r = zd_iowrite32(&mac->chip, CR_BCN_FIFO_SEMAPHORE, 0); |
417 | if (r < 0) | ||
418 | return r; | ||
419 | r = zd_ioread32(&mac->chip, CR_BCN_FIFO_SEMAPHORE, &tmp); | ||
420 | if (r < 0) | ||
421 | return r; | ||
422 | |||
416 | while (tmp & 0x2) { | 423 | while (tmp & 0x2) { |
417 | zd_ioread32(&mac->chip, CR_BCN_FIFO_SEMAPHORE, &tmp); | 424 | r = zd_ioread32(&mac->chip, CR_BCN_FIFO_SEMAPHORE, &tmp); |
425 | if (r < 0) | ||
426 | return r; | ||
418 | if ((++j % 100) == 0) { | 427 | if ((++j % 100) == 0) { |
419 | printk(KERN_ERR "CR_BCN_FIFO_SEMAPHORE not ready\n"); | 428 | printk(KERN_ERR "CR_BCN_FIFO_SEMAPHORE not ready\n"); |
420 | if (j >= 500) { | 429 | if (j >= 500) { |
421 | printk(KERN_ERR "Giving up beacon config.\n"); | 430 | printk(KERN_ERR "Giving up beacon config.\n"); |
422 | return; | 431 | return -ETIMEDOUT; |
423 | } | 432 | } |
424 | } | 433 | } |
425 | msleep(1); | 434 | msleep(1); |
426 | } | 435 | } |
427 | 436 | ||
428 | zd_iowrite32(&mac->chip, CR_BCN_FIFO, full_len - 1); | 437 | r = zd_iowrite32(&mac->chip, CR_BCN_FIFO, full_len - 1); |
429 | if (zd_chip_is_zd1211b(&mac->chip)) | 438 | if (r < 0) |
430 | zd_iowrite32(&mac->chip, CR_BCN_LENGTH, full_len - 1); | 439 | return r; |
440 | if (zd_chip_is_zd1211b(&mac->chip)) { | ||
441 | r = zd_iowrite32(&mac->chip, CR_BCN_LENGTH, full_len - 1); | ||
442 | if (r < 0) | ||
443 | return r; | ||
444 | } | ||
431 | 445 | ||
432 | for (j = 0 ; j < beacon->len; j++) | 446 | for (j = 0 ; j < beacon->len; j++) { |
433 | zd_iowrite32(&mac->chip, CR_BCN_FIFO, | 447 | r = zd_iowrite32(&mac->chip, CR_BCN_FIFO, |
434 | *((u8 *)(beacon->data + j))); | 448 | *((u8 *)(beacon->data + j))); |
449 | if (r < 0) | ||
450 | return r; | ||
451 | } | ||
435 | 452 | ||
436 | for (j = 0; j < 4; j++) | 453 | for (j = 0; j < 4; j++) { |
437 | zd_iowrite32(&mac->chip, CR_BCN_FIFO, 0x0); | 454 | r = zd_iowrite32(&mac->chip, CR_BCN_FIFO, 0x0); |
455 | if (r < 0) | ||
456 | return r; | ||
457 | } | ||
458 | |||
459 | r = zd_iowrite32(&mac->chip, CR_BCN_FIFO_SEMAPHORE, 1); | ||
460 | if (r < 0) | ||
461 | return r; | ||
438 | 462 | ||
439 | zd_iowrite32(&mac->chip, CR_BCN_FIFO_SEMAPHORE, 1); | ||
440 | /* 802.11b/g 2.4G CCK 1Mb | 463 | /* 802.11b/g 2.4G CCK 1Mb |
441 | * 802.11a, not yet implemented, uses different values (see GPL vendor | 464 | * 802.11a, not yet implemented, uses different values (see GPL vendor |
442 | * driver) | 465 | * driver) |
443 | */ | 466 | */ |
444 | zd_iowrite32(&mac->chip, CR_BCN_PLCP_CFG, 0x00000400 | | 467 | return zd_iowrite32(&mac->chip, CR_BCN_PLCP_CFG, 0x00000400 | |
445 | (full_len << 19)); | 468 | (full_len << 19)); |
446 | } | 469 | } |
447 | 470 | ||
@@ -699,15 +722,20 @@ static int zd_op_config_interface(struct ieee80211_hw *hw, | |||
699 | { | 722 | { |
700 | struct zd_mac *mac = zd_hw_mac(hw); | 723 | struct zd_mac *mac = zd_hw_mac(hw); |
701 | int associated; | 724 | int associated; |
725 | int r; | ||
702 | 726 | ||
703 | if (mac->type == IEEE80211_IF_TYPE_MESH_POINT || | 727 | if (mac->type == IEEE80211_IF_TYPE_MESH_POINT || |
704 | mac->type == IEEE80211_IF_TYPE_IBSS) { | 728 | mac->type == IEEE80211_IF_TYPE_IBSS) { |
705 | associated = true; | 729 | associated = true; |
706 | if (conf->beacon) { | 730 | if (conf->beacon) { |
707 | zd_mac_config_beacon(hw, conf->beacon); | 731 | r = zd_mac_config_beacon(hw, conf->beacon); |
708 | kfree_skb(conf->beacon); | 732 | if (r < 0) |
709 | zd_set_beacon_interval(&mac->chip, BCN_MODE_IBSS | | 733 | return r; |
734 | r = zd_set_beacon_interval(&mac->chip, BCN_MODE_IBSS | | ||
710 | hw->conf.beacon_int); | 735 | hw->conf.beacon_int); |
736 | if (r < 0) | ||
737 | return r; | ||
738 | kfree_skb(conf->beacon); | ||
711 | } | 739 | } |
712 | } else | 740 | } else |
713 | associated = is_valid_ether_addr(conf->bssid); | 741 | associated = is_valid_ether_addr(conf->bssid); |