提交 04cf53f4 编写于 作者: S Sujith Manoharan 提交者: John W. Linville

ath9k_hw: Offload USB eeprom reading to target

For USB devices, reading the EEPROM data can be offloaded
to the target. Use multiple register reads to take advantage
of this feature to reduce initialization time.
Signed-off-by: NSujith Manoharan <Sujith.Manoharan@atheros.com>
Signed-off-by: NJohn W. Linville <linville@tuxdriver.com>
上级 09a525d3
...@@ -89,6 +89,38 @@ bool ath9k_hw_get_lower_upper_index(u8 target, u8 *pList, u16 listSize, ...@@ -89,6 +89,38 @@ bool ath9k_hw_get_lower_upper_index(u8 target, u8 *pList, u16 listSize,
return false; return false;
} }
void ath9k_hw_usb_gen_fill_eeprom(struct ath_hw *ah, u16 *eep_data,
int eep_start_loc, int size)
{
int i = 0, j, addr;
u32 addrdata[8];
u32 data[8];
for (addr = 0; addr < size; addr++) {
addrdata[i] = AR5416_EEPROM_OFFSET +
((addr + eep_start_loc) << AR5416_EEPROM_S);
i++;
if (i == 8) {
REG_READ_MULTI(ah, addrdata, data, i);
for (j = 0; j < i; j++) {
*eep_data = data[j];
eep_data++;
}
i = 0;
}
}
if (i != 0) {
REG_READ_MULTI(ah, addrdata, data, i);
for (j = 0; j < i; j++) {
*eep_data = data[j];
eep_data++;
}
}
}
bool ath9k_hw_nvram_read(struct ath_common *common, u32 off, u16 *data) bool ath9k_hw_nvram_read(struct ath_common *common, u32 off, u16 *data)
{ {
return common->bus_ops->eeprom_read(common, off, data); return common->bus_ops->eeprom_read(common, off, data);
......
...@@ -665,6 +665,8 @@ int16_t ath9k_hw_interpolate(u16 target, u16 srcLeft, u16 srcRight, ...@@ -665,6 +665,8 @@ int16_t ath9k_hw_interpolate(u16 target, u16 srcLeft, u16 srcRight,
bool ath9k_hw_get_lower_upper_index(u8 target, u8 *pList, u16 listSize, bool ath9k_hw_get_lower_upper_index(u8 target, u8 *pList, u16 listSize,
u16 *indexL, u16 *indexR); u16 *indexL, u16 *indexR);
bool ath9k_hw_nvram_read(struct ath_common *common, u32 off, u16 *data); bool ath9k_hw_nvram_read(struct ath_common *common, u32 off, u16 *data);
void ath9k_hw_usb_gen_fill_eeprom(struct ath_hw *ah, u16 *eep_data,
int eep_start_loc, int size);
void ath9k_hw_fill_vpd_table(u8 pwrMin, u8 pwrMax, u8 *pPwrList, void ath9k_hw_fill_vpd_table(u8 pwrMin, u8 pwrMax, u8 *pPwrList,
u8 *pVpdList, u16 numIntercepts, u8 *pVpdList, u16 numIntercepts,
u8 *pRetVpdList); u8 *pRetVpdList);
......
...@@ -27,19 +27,13 @@ static int ath9k_hw_4k_get_eeprom_rev(struct ath_hw *ah) ...@@ -27,19 +27,13 @@ static int ath9k_hw_4k_get_eeprom_rev(struct ath_hw *ah)
return ((ah->eeprom.map4k.baseEepHeader.version) & 0xFFF); return ((ah->eeprom.map4k.baseEepHeader.version) & 0xFFF);
} }
static bool ath9k_hw_4k_fill_eeprom(struct ath_hw *ah)
{
#define SIZE_EEPROM_4K (sizeof(struct ar5416_eeprom_4k) / sizeof(u16)) #define SIZE_EEPROM_4K (sizeof(struct ar5416_eeprom_4k) / sizeof(u16))
static bool __ath9k_hw_4k_fill_eeprom(struct ath_hw *ah)
{
struct ath_common *common = ath9k_hw_common(ah); struct ath_common *common = ath9k_hw_common(ah);
u16 *eep_data = (u16 *)&ah->eeprom.map4k; u16 *eep_data = (u16 *)&ah->eeprom.map4k;
int addr, eep_start_loc = 0; int addr, eep_start_loc = 64;
eep_start_loc = 64;
if (!ath9k_hw_use_flash(ah)) {
ath_dbg(common, ATH_DBG_EEPROM,
"Reading from EEPROM, not flash\n");
}
for (addr = 0; addr < SIZE_EEPROM_4K; addr++) { for (addr = 0; addr < SIZE_EEPROM_4K; addr++) {
if (!ath9k_hw_nvram_read(common, addr + eep_start_loc, eep_data)) { if (!ath9k_hw_nvram_read(common, addr + eep_start_loc, eep_data)) {
...@@ -51,9 +45,34 @@ static bool ath9k_hw_4k_fill_eeprom(struct ath_hw *ah) ...@@ -51,9 +45,34 @@ static bool ath9k_hw_4k_fill_eeprom(struct ath_hw *ah)
} }
return true; return true;
#undef SIZE_EEPROM_4K
} }
static bool __ath9k_hw_usb_4k_fill_eeprom(struct ath_hw *ah)
{
u16 *eep_data = (u16 *)&ah->eeprom.map4k;
ath9k_hw_usb_gen_fill_eeprom(ah, eep_data, 64, SIZE_EEPROM_4K);
return true;
}
static bool ath9k_hw_4k_fill_eeprom(struct ath_hw *ah)
{
struct ath_common *common = ath9k_hw_common(ah);
if (!ath9k_hw_use_flash(ah)) {
ath_dbg(common, ATH_DBG_EEPROM,
"Reading from EEPROM, not flash\n");
}
if (common->bus_ops->ath_bus_type == ATH_USB)
return __ath9k_hw_usb_4k_fill_eeprom(ah);
else
return __ath9k_hw_4k_fill_eeprom(ah);
}
#undef SIZE_EEPROM_4K
static int ath9k_hw_4k_check_eeprom(struct ath_hw *ah) static int ath9k_hw_4k_check_eeprom(struct ath_hw *ah)
{ {
#define EEPROM_4K_SIZE (sizeof(struct ar5416_eeprom_4k) / sizeof(u16)) #define EEPROM_4K_SIZE (sizeof(struct ar5416_eeprom_4k) / sizeof(u16))
......
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
#include "hw.h" #include "hw.h"
#include "ar9002_phy.h" #include "ar9002_phy.h"
#define NUM_EEP_WORDS (sizeof(struct ar9287_eeprom) / sizeof(u16)) #define SIZE_EEPROM_AR9287 (sizeof(struct ar9287_eeprom) / sizeof(u16))
static int ath9k_hw_ar9287_get_eeprom_ver(struct ath_hw *ah) static int ath9k_hw_ar9287_get_eeprom_ver(struct ath_hw *ah)
{ {
...@@ -29,25 +29,15 @@ static int ath9k_hw_ar9287_get_eeprom_rev(struct ath_hw *ah) ...@@ -29,25 +29,15 @@ static int ath9k_hw_ar9287_get_eeprom_rev(struct ath_hw *ah)
return (ah->eeprom.map9287.baseEepHeader.version) & 0xFFF; return (ah->eeprom.map9287.baseEepHeader.version) & 0xFFF;
} }
static bool ath9k_hw_ar9287_fill_eeprom(struct ath_hw *ah) static bool __ath9k_hw_ar9287_fill_eeprom(struct ath_hw *ah)
{ {
struct ar9287_eeprom *eep = &ah->eeprom.map9287; struct ar9287_eeprom *eep = &ah->eeprom.map9287;
struct ath_common *common = ath9k_hw_common(ah); struct ath_common *common = ath9k_hw_common(ah);
u16 *eep_data; u16 *eep_data;
int addr, eep_start_loc; int addr, eep_start_loc = AR9287_EEP_START_LOC;
eep_data = (u16 *)eep; eep_data = (u16 *)eep;
if (common->bus_ops->ath_bus_type == ATH_USB) for (addr = 0; addr < SIZE_EEPROM_AR9287; addr++) {
eep_start_loc = AR9287_HTC_EEP_START_LOC;
else
eep_start_loc = AR9287_EEP_START_LOC;
if (!ath9k_hw_use_flash(ah)) {
ath_dbg(common, ATH_DBG_EEPROM,
"Reading from EEPROM, not flash\n");
}
for (addr = 0; addr < NUM_EEP_WORDS; addr++) {
if (!ath9k_hw_nvram_read(common, addr + eep_start_loc, if (!ath9k_hw_nvram_read(common, addr + eep_start_loc,
eep_data)) { eep_data)) {
ath_dbg(common, ATH_DBG_EEPROM, ath_dbg(common, ATH_DBG_EEPROM,
...@@ -60,6 +50,31 @@ static bool ath9k_hw_ar9287_fill_eeprom(struct ath_hw *ah) ...@@ -60,6 +50,31 @@ static bool ath9k_hw_ar9287_fill_eeprom(struct ath_hw *ah)
return true; return true;
} }
static bool __ath9k_hw_usb_ar9287_fill_eeprom(struct ath_hw *ah)
{
u16 *eep_data = (u16 *)&ah->eeprom.map9287;
ath9k_hw_usb_gen_fill_eeprom(ah, eep_data,
AR9287_HTC_EEP_START_LOC,
SIZE_EEPROM_AR9287);
return true;
}
static bool ath9k_hw_ar9287_fill_eeprom(struct ath_hw *ah)
{
struct ath_common *common = ath9k_hw_common(ah);
if (!ath9k_hw_use_flash(ah)) {
ath_dbg(common, ATH_DBG_EEPROM,
"Reading from EEPROM, not flash\n");
}
if (common->bus_ops->ath_bus_type == ATH_USB)
return __ath9k_hw_usb_ar9287_fill_eeprom(ah);
else
return __ath9k_hw_ar9287_fill_eeprom(ah);
}
static int ath9k_hw_ar9287_check_eeprom(struct ath_hw *ah) static int ath9k_hw_ar9287_check_eeprom(struct ath_hw *ah)
{ {
u32 sum = 0, el, integer; u32 sum = 0, el, integer;
...@@ -86,7 +101,7 @@ static int ath9k_hw_ar9287_check_eeprom(struct ath_hw *ah) ...@@ -86,7 +101,7 @@ static int ath9k_hw_ar9287_check_eeprom(struct ath_hw *ah)
need_swap = true; need_swap = true;
eepdata = (u16 *)(&ah->eeprom); eepdata = (u16 *)(&ah->eeprom);
for (addr = 0; addr < NUM_EEP_WORDS; addr++) { for (addr = 0; addr < SIZE_EEPROM_AR9287; addr++) {
temp = swab16(*eepdata); temp = swab16(*eepdata);
*eepdata = temp; *eepdata = temp;
eepdata++; eepdata++;
......
...@@ -86,9 +86,10 @@ static int ath9k_hw_def_get_eeprom_rev(struct ath_hw *ah) ...@@ -86,9 +86,10 @@ static int ath9k_hw_def_get_eeprom_rev(struct ath_hw *ah)
return ((ah->eeprom.def.baseEepHeader.version) & 0xFFF); return ((ah->eeprom.def.baseEepHeader.version) & 0xFFF);
} }
static bool ath9k_hw_def_fill_eeprom(struct ath_hw *ah)
{
#define SIZE_EEPROM_DEF (sizeof(struct ar5416_eeprom_def) / sizeof(u16)) #define SIZE_EEPROM_DEF (sizeof(struct ar5416_eeprom_def) / sizeof(u16))
static bool __ath9k_hw_def_fill_eeprom(struct ath_hw *ah)
{
struct ath_common *common = ath9k_hw_common(ah); struct ath_common *common = ath9k_hw_common(ah);
u16 *eep_data = (u16 *)&ah->eeprom.def; u16 *eep_data = (u16 *)&ah->eeprom.def;
int addr, ar5416_eep_start_loc = 0x100; int addr, ar5416_eep_start_loc = 0x100;
...@@ -103,9 +104,34 @@ static bool ath9k_hw_def_fill_eeprom(struct ath_hw *ah) ...@@ -103,9 +104,34 @@ static bool ath9k_hw_def_fill_eeprom(struct ath_hw *ah)
eep_data++; eep_data++;
} }
return true; return true;
#undef SIZE_EEPROM_DEF
} }
static bool __ath9k_hw_usb_def_fill_eeprom(struct ath_hw *ah)
{
u16 *eep_data = (u16 *)&ah->eeprom.def;
ath9k_hw_usb_gen_fill_eeprom(ah, eep_data,
0x100, SIZE_EEPROM_DEF);
return true;
}
static bool ath9k_hw_def_fill_eeprom(struct ath_hw *ah)
{
struct ath_common *common = ath9k_hw_common(ah);
if (!ath9k_hw_use_flash(ah)) {
ath_dbg(common, ATH_DBG_EEPROM,
"Reading from EEPROM, not flash\n");
}
if (common->bus_ops->ath_bus_type == ATH_USB)
return __ath9k_hw_usb_def_fill_eeprom(ah);
else
return __ath9k_hw_def_fill_eeprom(ah);
}
#undef SIZE_EEPROM_DEF
static int ath9k_hw_def_check_eeprom(struct ath_hw *ah) static int ath9k_hw_def_check_eeprom(struct ath_hw *ah)
{ {
struct ar5416_eeprom_def *eep = struct ar5416_eeprom_def *eep =
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册