From patchwork Wed Apr 14 10:05:48 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Grazvydas Ignotas X-Patchwork-Id: 92371 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter.kernel.org (8.14.3/8.14.3) with ESMTP id o3EA6KsJ015337 for ; Wed, 14 Apr 2010 10:06:20 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754999Ab0DNKF5 (ORCPT ); Wed, 14 Apr 2010 06:05:57 -0400 Received: from mail-wy0-f174.google.com ([74.125.82.174]:62563 "EHLO mail-wy0-f174.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754901Ab0DNKFz (ORCPT ); Wed, 14 Apr 2010 06:05:55 -0400 Received: by wyf19 with SMTP id 19so650515wyf.19 for ; Wed, 14 Apr 2010 03:05:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:from:to:cc:subject:date :message-id:x-mailer; bh=D9uEh3ZZZkFpY9UN5tJ6lIn8CSfH3Wiw0s7HBCuu+rQ=; b=T4i5aJUG5I8tP2/l63vS0whHrhNVXwJjmRpKLnHwAdJ71p5xc+PJ0cU+bwc8qfPWwy /lobvEG6Ggps7pgVf6GatAHYkoIqhha8zhlRgJKMgtsJSMmbSBJs9DXcmquNViU8CJDo 81g8TFI2/a2FKUq5KzM7OoTbwwJumA0evghe8= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=from:to:cc:subject:date:message-id:x-mailer; b=oJ1fOMgn9vekwHBLsa6ZCZdDCh6u8MAkb1pWdQepDU6Je6q7S6ap9IGXJVETCFs3Ga 8sfMH8MNIq8e5wqZ7kch8Op4+8kB2+5dMOWOUWcn/+E6mu0J6d72sDO2EyG5/+468PGv i2AI7RK6LYSn97cq/770cwt0Uzj5PGJGkz2gw= Received: by 10.216.86.196 with SMTP id w46mr5033574wee.201.1271239553897; Wed, 14 Apr 2010 03:05:53 -0700 (PDT) Received: from localhost.localdomain (ip-88-119-226-136.static.b4net.lt [88.119.226.136]) by mx.google.com with ESMTPS id z3sm1426127wbs.4.2010.04.14.03.05.52 (version=TLSv1/SSLv3 cipher=RC4-MD5); Wed, 14 Apr 2010 03:05:53 -0700 (PDT) From: Grazvydas Ignotas To: "John W. Linville" Cc: linux-wireless@vger.kernel.org, Kalle Valo , Grazvydas Ignotas Subject: [PATCH v2] wl1251: read default MAC address from EEPROM when available Date: Wed, 14 Apr 2010 13:05:48 +0300 Message-Id: <1271239548-15326-1-git-send-email-notasas@gmail.com> X-Mailer: git-send-email 1.6.3.3 Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter.kernel.org [140.211.167.41]); Wed, 14 Apr 2010 10:06:21 +0000 (UTC) diff --git a/drivers/net/wireless/wl12xx/wl1251_main.c b/drivers/net/wireless/wl12xx/wl1251_main.c index 56b78e4..5dc04df 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 = { .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; @@ -1242,6 +1302,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; diff --git a/drivers/net/wireless/wl12xx/wl1251_reg.h b/drivers/net/wireless/wl12xx/wl1251_reg.h index 0ca3b43..d16edd9 100644 --- a/drivers/net/wireless/wl12xx/wl1251_reg.h +++ b/drivers/net/wireless/wl12xx/wl1251_reg.h @@ -46,7 +46,14 @@ #define SOR_CFG (REGISTERS_BASE + 0x0800) #define ECPU_CTRL (REGISTERS_BASE + 0x0804) #define HI_CFG (REGISTERS_BASE + 0x0808) + +/* EEPROM registers */ #define EE_START (REGISTERS_BASE + 0x080C) +#define EE_CTL (REGISTERS_BASE + 0x2000) +#define EE_DATA (REGISTERS_BASE + 0x2004) +#define EE_ADDR (REGISTERS_BASE + 0x2008) + +#define EE_CTL_READ 2 #define CHIP_ID_B (REGISTERS_BASE + 0x5674)