Skip to content

Commit

Permalink
ath9k: get EEPROM contents from platform data on AHB bus
Browse files Browse the repository at this point in the history
On the AR913x SOCs we have to provide EEPROM contents via platform_data,
because accessing the flash via MMIO is not safe. Additionally different
boards may store the radio calibration data at different locations.

Changes-licensed-under: ISC

Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
Signed-off-by: Imre Kaloz <kaloz@openwrt.org>
Tested-by: Pavel Roskin <proski@gnu.org>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
  • Loading branch information
Gabor Juhos authored and John W. Linville committed Jan 29, 2009
1 parent 09329d3 commit 9dbeb91
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 48 deletions.
27 changes: 27 additions & 0 deletions drivers/net/wireless/ath9k/ahb.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

#include <linux/nl80211.h>
#include <linux/platform_device.h>
#include <linux/ath9k_platform.h>
#include "core.h"
#include "reg.h"
#include "hw.h"
Expand All @@ -33,9 +34,29 @@ static void ath_ahb_cleanup(struct ath_softc *sc)
iounmap(sc->mem);
}

static bool ath_ahb_eeprom_read(struct ath_hal *ah, u32 off, u16 *data)
{
struct ath_softc *sc = ah->ah_sc;
struct platform_device *pdev = to_platform_device(sc->dev);
struct ath9k_platform_data *pdata;

pdata = (struct ath9k_platform_data *) pdev->dev.platform_data;
if (off >= (ARRAY_SIZE(pdata->eeprom_data))) {
DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
"%s: flash read failed, offset %08x is out of range\n",
__func__, off);
return false;
}

*data = pdata->eeprom_data[off];
return true;
}

static struct ath_bus_ops ath_ahb_bus_ops = {
.read_cachesize = ath_ahb_read_cachesize,
.cleanup = ath_ahb_cleanup,

.eeprom_read = ath_ahb_eeprom_read,
};

static int ath_ahb_probe(struct platform_device *pdev)
Expand All @@ -48,6 +69,12 @@ static int ath_ahb_probe(struct platform_device *pdev)
int ret = 0;
struct ath_hal *ah;

if (!pdev->dev.platform_data) {
dev_err(&pdev->dev, "no platform data specified\n");
ret = -EINVAL;
goto err_out;
}

res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (res == NULL) {
dev_err(&pdev->dev, "no memory resource found\n");
Expand Down
1 change: 1 addition & 0 deletions drivers/net/wireless/ath9k/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -696,6 +696,7 @@ enum PROT_MODE {
struct ath_bus_ops {
void (*read_cachesize)(struct ath_softc *sc, int *csz);
void (*cleanup)(struct ath_softc *sc);
bool (*eeprom_read)(struct ath_hal *ah, u32 off, u16 *data);
};

struct ath_softc {
Expand Down
51 changes: 3 additions & 48 deletions drivers/net/wireless/ath9k/eeprom.c
Original file line number Diff line number Diff line change
Expand Up @@ -91,53 +91,11 @@ static inline bool ath9k_hw_get_lower_upper_index(u8 target, u8 *pList,
return false;
}

static bool ath9k_hw_eeprom_read(struct ath_hal *ah, u32 off, u16 *data)
{
(void)REG_READ(ah, AR5416_EEPROM_OFFSET + (off << AR5416_EEPROM_S));

if (!ath9k_hw_wait(ah,
AR_EEPROM_STATUS_DATA,
AR_EEPROM_STATUS_DATA_BUSY |
AR_EEPROM_STATUS_DATA_PROT_ACCESS, 0)) {
return false;
}

*data = MS(REG_READ(ah, AR_EEPROM_STATUS_DATA),
AR_EEPROM_STATUS_DATA_VAL);

return true;
}

static int ath9k_hw_flash_map(struct ath_hal *ah)
{
struct ath_hal_5416 *ahp = AH5416(ah);

ahp->ah_cal_mem = ioremap(AR5416_EEPROM_START_ADDR, AR5416_EEPROM_MAX);

if (!ahp->ah_cal_mem) {
DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
"cannot remap eeprom region \n");
return -EIO;
}

return 0;
}

static bool ath9k_hw_flash_read(struct ath_hal *ah, u32 off, u16 *data)
{
struct ath_hal_5416 *ahp = AH5416(ah);

*data = ioread16(ahp->ah_cal_mem + off);

return true;
}

static inline bool ath9k_hw_nvram_read(struct ath_hal *ah, u32 off, u16 *data)
{
if (ath9k_hw_use_flash(ah))
return ath9k_hw_flash_read(ah, off, data);
else
return ath9k_hw_eeprom_read(ah, off, data);
struct ath_softc *sc = ah->ah_sc;

return sc->bus_ops->eeprom_read(ah, off, data);
}

static bool ath9k_hw_fill_4k_eeprom(struct ath_hal *ah)
Expand Down Expand Up @@ -2825,9 +2783,6 @@ int ath9k_hw_eeprom_attach(struct ath_hal *ah)
int status;
struct ath_hal_5416 *ahp = AH5416(ah);

if (ath9k_hw_use_flash(ah))
ath9k_hw_flash_map(ah);

if (AR_SREV_9285(ah))
ahp->ah_eep_map = EEP_MAP_4KBITS;
else
Expand Down
18 changes: 18 additions & 0 deletions drivers/net/wireless/ath9k/pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,27 @@ static void ath_pci_cleanup(struct ath_softc *sc)
pci_disable_device(pdev);
}

static bool ath_pci_eeprom_read(struct ath_hal *ah, u32 off, u16 *data)
{
(void)REG_READ(ah, AR5416_EEPROM_OFFSET + (off << AR5416_EEPROM_S));

if (!ath9k_hw_wait(ah,
AR_EEPROM_STATUS_DATA,
AR_EEPROM_STATUS_DATA_BUSY |
AR_EEPROM_STATUS_DATA_PROT_ACCESS, 0)) {
return false;
}

*data = MS(REG_READ(ah, AR_EEPROM_STATUS_DATA),
AR_EEPROM_STATUS_DATA_VAL);

return true;
}

static struct ath_bus_ops ath_pci_bus_ops = {
.read_cachesize = ath_pci_read_cachesize,
.cleanup = ath_pci_cleanup,
.eeprom_read = ath_pci_eeprom_read,
};

static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
Expand Down
28 changes: 28 additions & 0 deletions include/linux/ath9k_platform.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* Copyright (c) 2008 Atheros Communications Inc.
* Copyright (c) 2009 Gabor Juhos <juhosg@openwrt.org>
* Copyright (c) 2009 Imre Kaloz <kaloz@openwrt.org>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/

#ifndef _LINUX_ATH9K_PLATFORM_H
#define _LINUX_ATH9K_PLATFORM_H

#define ATH9K_PLAT_EEP_MAX_WORDS 2048

struct ath9k_platform_data {
u16 eeprom_data[ATH9K_PLAT_EEP_MAX_WORDS];
};

#endif /* _LINUX_ATH9K_PLATFORM_H */

0 comments on commit 9dbeb91

Please sign in to comment.