wl1251: read default MAC address from EEPROM when available
[pandora-wifi.git] / drivers / net / wireless / wl12xx / wl1251_main.c
index 929e6de..de59d8d 100644 (file)
@@ -1198,6 +1198,66 @@ static const struct ieee80211_ops wl1251_ops = {
        .conf_tx = wl1251_op_conf_tx,
 };
 
+static int wl1251_read_eeprom_byte(struct wl1251 *wl, off_t offset, u8 *data)
+{
+       unsigned long timeout;
+
+       wl1251_reg_write32(wl, EE_ADDR, offset);
+       wl1251_reg_write32(wl, EE_CTL, EE_CTL_READ);
+
+       /* EE_CTL_READ clears when data is ready */
+       timeout = jiffies + msecs_to_jiffies(100);
+       while (1) {
+               if (!(wl1251_reg_read32(wl, EE_CTL) & EE_CTL_READ))
+                       break;
+
+               if (time_after(jiffies, timeout))
+                       return -ETIMEDOUT;
+
+               msleep(1);
+       }
+
+       *data = wl1251_reg_read32(wl, EE_DATA);
+       return 0;
+}
+
+static int wl1251_read_eeprom(struct wl1251 *wl, off_t offset,
+                             u8 *data, size_t len)
+{
+       size_t i;
+       int ret;
+
+       wl1251_reg_write32(wl, EE_START, 0);
+
+       for (i = 0; i < len; i++) {
+               ret = wl1251_read_eeprom_byte(wl, offset + i, &data[i]);
+               if (ret < 0)
+                       return ret;
+       }
+
+       return 0;
+}
+
+static int wl1251_read_eeprom_mac(struct wl1251 *wl)
+{
+       u8 mac[ETH_ALEN];
+       int i, ret;
+
+       wl1251_set_partition(wl, 0, 0, REGISTERS_BASE, REGISTERS_DOWN_SIZE);
+
+       ret = wl1251_read_eeprom(wl, 0x1c, mac, sizeof(mac));
+       if (ret < 0) {
+               wl1251_warning("failed to read MAC address from EEPROM");
+               return ret;
+       }
+
+       /* MAC is stored in reverse order */
+       for (i = 0; i < ETH_ALEN; i++)
+               wl->mac_addr[i] = mac[ETH_ALEN - i - 1];
+
+       return 0;
+}
+
 static int wl1251_register_hw(struct wl1251 *wl)
 {
        int ret;
@@ -1244,6 +1304,9 @@ int wl1251_init_ieee80211(struct wl1251 *wl)
 
        wl->hw->queues = 4;
 
+       if (wl->use_eeprom)
+               wl1251_read_eeprom_mac(wl);
+
        ret = wl1251_register_hw(wl);
        if (ret)
                goto out;