diff options
Diffstat (limited to 'drivers/net/wireless/wl12xx/wl1251_main.c')
-rw-r--r-- | drivers/net/wireless/wl12xx/wl1251_main.c | 73 |
1 files changed, 68 insertions, 5 deletions
diff --git a/drivers/net/wireless/wl12xx/wl1251_main.c b/drivers/net/wireless/wl12xx/wl1251_main.c index 1c8226eee409..00b24282fc73 100644 --- a/drivers/net/wireless/wl12xx/wl1251_main.c +++ b/drivers/net/wireless/wl12xx/wl1251_main.c | |||
@@ -147,8 +147,8 @@ static void wl1251_fw_wakeup(struct wl1251 *wl) | |||
147 | u32 elp_reg; | 147 | u32 elp_reg; |
148 | 148 | ||
149 | elp_reg = ELPCTRL_WAKE_UP; | 149 | elp_reg = ELPCTRL_WAKE_UP; |
150 | wl1251_write32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, elp_reg); | 150 | wl1251_write_elp(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, elp_reg); |
151 | elp_reg = wl1251_read32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR); | 151 | elp_reg = wl1251_read_elp(wl, HW_ACCESS_ELP_CTRL_REG_ADDR); |
152 | 152 | ||
153 | if (!(elp_reg & ELPCTRL_WLAN_READY)) | 153 | if (!(elp_reg & ELPCTRL_WLAN_READY)) |
154 | wl1251_warning("WLAN not ready"); | 154 | wl1251_warning("WLAN not ready"); |
@@ -202,8 +202,8 @@ static int wl1251_chip_wakeup(struct wl1251 *wl) | |||
202 | goto out; | 202 | goto out; |
203 | } | 203 | } |
204 | 204 | ||
205 | /* No NVS from netlink, try to get it from the filesystem */ | 205 | if (wl->nvs == NULL && !wl->use_eeprom) { |
206 | if (wl->nvs == NULL) { | 206 | /* No NVS from netlink, try to get it from the filesystem */ |
207 | ret = wl1251_fetch_nvs(wl); | 207 | ret = wl1251_fetch_nvs(wl); |
208 | if (ret < 0) | 208 | if (ret < 0) |
209 | goto out; | 209 | goto out; |
@@ -857,6 +857,7 @@ out: | |||
857 | } | 857 | } |
858 | 858 | ||
859 | static int wl1251_op_hw_scan(struct ieee80211_hw *hw, | 859 | static int wl1251_op_hw_scan(struct ieee80211_hw *hw, |
860 | struct ieee80211_vif *vif, | ||
860 | struct cfg80211_scan_request *req) | 861 | struct cfg80211_scan_request *req) |
861 | { | 862 | { |
862 | struct wl1251 *wl = hw->priv; | 863 | struct wl1251 *wl = hw->priv; |
@@ -1196,6 +1197,66 @@ static const struct ieee80211_ops wl1251_ops = { | |||
1196 | .conf_tx = wl1251_op_conf_tx, | 1197 | .conf_tx = wl1251_op_conf_tx, |
1197 | }; | 1198 | }; |
1198 | 1199 | ||
1200 | static int wl1251_read_eeprom_byte(struct wl1251 *wl, off_t offset, u8 *data) | ||
1201 | { | ||
1202 | unsigned long timeout; | ||
1203 | |||
1204 | wl1251_reg_write32(wl, EE_ADDR, offset); | ||
1205 | wl1251_reg_write32(wl, EE_CTL, EE_CTL_READ); | ||
1206 | |||
1207 | /* EE_CTL_READ clears when data is ready */ | ||
1208 | timeout = jiffies + msecs_to_jiffies(100); | ||
1209 | while (1) { | ||
1210 | if (!(wl1251_reg_read32(wl, EE_CTL) & EE_CTL_READ)) | ||
1211 | break; | ||
1212 | |||
1213 | if (time_after(jiffies, timeout)) | ||
1214 | return -ETIMEDOUT; | ||
1215 | |||
1216 | msleep(1); | ||
1217 | } | ||
1218 | |||
1219 | *data = wl1251_reg_read32(wl, EE_DATA); | ||
1220 | return 0; | ||
1221 | } | ||
1222 | |||
1223 | static int wl1251_read_eeprom(struct wl1251 *wl, off_t offset, | ||
1224 | u8 *data, size_t len) | ||
1225 | { | ||
1226 | size_t i; | ||
1227 | int ret; | ||
1228 | |||
1229 | wl1251_reg_write32(wl, EE_START, 0); | ||
1230 | |||
1231 | for (i = 0; i < len; i++) { | ||
1232 | ret = wl1251_read_eeprom_byte(wl, offset + i, &data[i]); | ||
1233 | if (ret < 0) | ||
1234 | return ret; | ||
1235 | } | ||
1236 | |||
1237 | return 0; | ||
1238 | } | ||
1239 | |||
1240 | static int wl1251_read_eeprom_mac(struct wl1251 *wl) | ||
1241 | { | ||
1242 | u8 mac[ETH_ALEN]; | ||
1243 | int i, ret; | ||
1244 | |||
1245 | wl1251_set_partition(wl, 0, 0, REGISTERS_BASE, REGISTERS_DOWN_SIZE); | ||
1246 | |||
1247 | ret = wl1251_read_eeprom(wl, 0x1c, mac, sizeof(mac)); | ||
1248 | if (ret < 0) { | ||
1249 | wl1251_warning("failed to read MAC address from EEPROM"); | ||
1250 | return ret; | ||
1251 | } | ||
1252 | |||
1253 | /* MAC is stored in reverse order */ | ||
1254 | for (i = 0; i < ETH_ALEN; i++) | ||
1255 | wl->mac_addr[i] = mac[ETH_ALEN - i - 1]; | ||
1256 | |||
1257 | return 0; | ||
1258 | } | ||
1259 | |||
1199 | static int wl1251_register_hw(struct wl1251 *wl) | 1260 | static int wl1251_register_hw(struct wl1251 *wl) |
1200 | { | 1261 | { |
1201 | int ret; | 1262 | int ret; |
@@ -1231,7 +1292,6 @@ int wl1251_init_ieee80211(struct wl1251 *wl) | |||
1231 | wl->hw->channel_change_time = 10000; | 1292 | wl->hw->channel_change_time = 10000; |
1232 | 1293 | ||
1233 | wl->hw->flags = IEEE80211_HW_SIGNAL_DBM | | 1294 | wl->hw->flags = IEEE80211_HW_SIGNAL_DBM | |
1234 | IEEE80211_HW_NOISE_DBM | | ||
1235 | IEEE80211_HW_SUPPORTS_PS | | 1295 | IEEE80211_HW_SUPPORTS_PS | |
1236 | IEEE80211_HW_BEACON_FILTER | | 1296 | IEEE80211_HW_BEACON_FILTER | |
1237 | IEEE80211_HW_SUPPORTS_UAPSD; | 1297 | IEEE80211_HW_SUPPORTS_UAPSD; |
@@ -1242,6 +1302,9 @@ int wl1251_init_ieee80211(struct wl1251 *wl) | |||
1242 | 1302 | ||
1243 | wl->hw->queues = 4; | 1303 | wl->hw->queues = 4; |
1244 | 1304 | ||
1305 | if (wl->use_eeprom) | ||
1306 | wl1251_read_eeprom_mac(wl); | ||
1307 | |||
1245 | ret = wl1251_register_hw(wl); | 1308 | ret = wl1251_register_hw(wl); |
1246 | if (ret) | 1309 | if (ret) |
1247 | goto out; | 1310 | goto out; |