diff options
Diffstat (limited to 'drivers/net/wireless')
-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 317c5e2..665f76a 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, /* FIXME: Management frame? */ } -void zd_mac_config_beacon(struct ieee80211_hw *hw, struct sk_buff *beacon) +static int zd_mac_config_beacon(struct ieee80211_hw *hw, struct sk_buff *beacon) { struct zd_mac *mac = zd_hw_mac(hw); + int r; u32 tmp, j = 0; /* 4 more bytes for tail CRC */ u32 full_len = beacon->len + 4; - zd_iowrite32(&mac->chip, CR_BCN_FIFO_SEMAPHORE, 0); - zd_ioread32(&mac->chip, CR_BCN_FIFO_SEMAPHORE, &tmp); + + r = zd_iowrite32(&mac->chip, CR_BCN_FIFO_SEMAPHORE, 0); + if (r < 0) + return r; + r = zd_ioread32(&mac->chip, CR_BCN_FIFO_SEMAPHORE, &tmp); + if (r < 0) + return r; + while (tmp & 0x2) { - zd_ioread32(&mac->chip, CR_BCN_FIFO_SEMAPHORE, &tmp); + r = zd_ioread32(&mac->chip, CR_BCN_FIFO_SEMAPHORE, &tmp); + if (r < 0) + return r; if ((++j % 100) == 0) { printk(KERN_ERR "CR_BCN_FIFO_SEMAPHORE not ready\n"); if (j >= 500) { printk(KERN_ERR "Giving up beacon config.\n"); - return; + return -ETIMEDOUT; } } msleep(1); } - zd_iowrite32(&mac->chip, CR_BCN_FIFO, full_len - 1); - if (zd_chip_is_zd1211b(&mac->chip)) - zd_iowrite32(&mac->chip, CR_BCN_LENGTH, full_len - 1); + r = zd_iowrite32(&mac->chip, CR_BCN_FIFO, full_len - 1); + if (r < 0) + return r; + if (zd_chip_is_zd1211b(&mac->chip)) { + r = zd_iowrite32(&mac->chip, CR_BCN_LENGTH, full_len - 1); + if (r < 0) + return r; + } - for (j = 0 ; j < beacon->len; j++) - zd_iowrite32(&mac->chip, CR_BCN_FIFO, + for (j = 0 ; j < beacon->len; j++) { + r = zd_iowrite32(&mac->chip, CR_BCN_FIFO, *((u8 *)(beacon->data + j))); + if (r < 0) + return r; + } - for (j = 0; j < 4; j++) - zd_iowrite32(&mac->chip, CR_BCN_FIFO, 0x0); + for (j = 0; j < 4; j++) { + r = zd_iowrite32(&mac->chip, CR_BCN_FIFO, 0x0); + if (r < 0) + return r; + } + + r = zd_iowrite32(&mac->chip, CR_BCN_FIFO_SEMAPHORE, 1); + if (r < 0) + return r; - zd_iowrite32(&mac->chip, CR_BCN_FIFO_SEMAPHORE, 1); /* 802.11b/g 2.4G CCK 1Mb * 802.11a, not yet implemented, uses different values (see GPL vendor * driver) */ - zd_iowrite32(&mac->chip, CR_BCN_PLCP_CFG, 0x00000400 | + return zd_iowrite32(&mac->chip, CR_BCN_PLCP_CFG, 0x00000400 | (full_len << 19)); } @@ -699,15 +722,20 @@ static int zd_op_config_interface(struct ieee80211_hw *hw, { struct zd_mac *mac = zd_hw_mac(hw); int associated; + int r; if (mac->type == IEEE80211_IF_TYPE_MESH_POINT || mac->type == IEEE80211_IF_TYPE_IBSS) { associated = true; if (conf->beacon) { - zd_mac_config_beacon(hw, conf->beacon); - kfree_skb(conf->beacon); - zd_set_beacon_interval(&mac->chip, BCN_MODE_IBSS | + r = zd_mac_config_beacon(hw, conf->beacon); + if (r < 0) + return r; + r = zd_set_beacon_interval(&mac->chip, BCN_MODE_IBSS | hw->conf.beacon_int); + if (r < 0) + return r; + kfree_skb(conf->beacon); } } else associated = is_valid_ether_addr(conf->bssid); |