diff options
Diffstat (limited to 'drivers/net/wireless/wl12xx/wl1251_main.c')
-rw-r--r-- | drivers/net/wireless/wl12xx/wl1251_main.c | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/drivers/net/wireless/wl12xx/wl1251_main.c b/drivers/net/wireless/wl12xx/wl1251_main.c index 4d479708158d..51614d181ccb 100644 --- a/drivers/net/wireless/wl12xx/wl1251_main.c +++ b/drivers/net/wireless/wl12xx/wl1251_main.c | |||
@@ -1196,6 +1196,66 @@ static const struct ieee80211_ops wl1251_ops = { | |||
1196 | .conf_tx = wl1251_op_conf_tx, | 1196 | .conf_tx = wl1251_op_conf_tx, |
1197 | }; | 1197 | }; |
1198 | 1198 | ||
1199 | static int wl1251_read_eeprom_byte(struct wl1251 *wl, off_t offset, u8 *data) | ||
1200 | { | ||
1201 | unsigned long timeout; | ||
1202 | |||
1203 | wl1251_reg_write32(wl, EE_ADDR, offset); | ||
1204 | wl1251_reg_write32(wl, EE_CTL, EE_CTL_READ); | ||
1205 | |||
1206 | /* EE_CTL_READ clears when data is ready */ | ||
1207 | timeout = jiffies + msecs_to_jiffies(100); | ||
1208 | while (1) { | ||
1209 | if (!(wl1251_reg_read32(wl, EE_CTL) & EE_CTL_READ)) | ||
1210 | break; | ||
1211 | |||
1212 | if (time_after(jiffies, timeout)) | ||
1213 | return -ETIMEDOUT; | ||
1214 | |||
1215 | msleep(1); | ||
1216 | } | ||
1217 | |||
1218 | *data = wl1251_reg_read32(wl, EE_DATA); | ||
1219 | return 0; | ||
1220 | } | ||
1221 | |||
1222 | static int wl1251_read_eeprom(struct wl1251 *wl, off_t offset, | ||
1223 | u8 *data, size_t len) | ||
1224 | { | ||
1225 | size_t i; | ||
1226 | int ret; | ||
1227 | |||
1228 | wl1251_reg_write32(wl, EE_START, 0); | ||
1229 | |||
1230 | for (i = 0; i < len; i++) { | ||
1231 | ret = wl1251_read_eeprom_byte(wl, offset + i, &data[i]); | ||
1232 | if (ret < 0) | ||
1233 | return ret; | ||
1234 | } | ||
1235 | |||
1236 | return 0; | ||
1237 | } | ||
1238 | |||
1239 | static int wl1251_read_eeprom_mac(struct wl1251 *wl) | ||
1240 | { | ||
1241 | u8 mac[ETH_ALEN]; | ||
1242 | int i, ret; | ||
1243 | |||
1244 | wl1251_set_partition(wl, 0, 0, REGISTERS_BASE, REGISTERS_DOWN_SIZE); | ||
1245 | |||
1246 | ret = wl1251_read_eeprom(wl, 0x1c, mac, sizeof(mac)); | ||
1247 | if (ret < 0) { | ||
1248 | wl1251_warning("failed to read MAC address from EEPROM"); | ||
1249 | return ret; | ||
1250 | } | ||
1251 | |||
1252 | /* MAC is stored in reverse order */ | ||
1253 | for (i = 0; i < ETH_ALEN; i++) | ||
1254 | wl->mac_addr[i] = mac[ETH_ALEN - i - 1]; | ||
1255 | |||
1256 | return 0; | ||
1257 | } | ||
1258 | |||
1199 | static int wl1251_register_hw(struct wl1251 *wl) | 1259 | static int wl1251_register_hw(struct wl1251 *wl) |
1200 | { | 1260 | { |
1201 | int ret; | 1261 | int ret; |
@@ -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; |