blob: ba4691f4bf0ff101a15e9eaff44ed68a8677a911 [file] [log] [blame]
#include "core.h"
#include "debug.h"
#define MAC_FILE "ath6k/AR6003/hw2.1.1/softmac"
/* Bleh, same offsets. */
#define AR6003_MAC_ADDRESS_OFFSET 0x16
#define AR6004_MAC_ADDRESS_OFFSET 0x16
/* Global variables, sane coding be damned. */
u8 *ath6kl_softmac;
size_t ath6kl_softmac_len;
static void ath6kl_calculate_crc(u32 target_type, u8 *data, size_t len)
{
u16 *crc, *data_idx;
u16 checksum;
int i;
if (target_type == TARGET_TYPE_AR6003) {
crc = (u16 *)(data + 0x04);
} else if (target_type == TARGET_TYPE_AR6004) {
len = 1024;
crc = (u16 *)(data + 0x04);
} else {
ath6kl_err("Invalid target type\n");
return;
}
ath6kl_dbg(ATH6KL_DBG_BOOT, "Old Checksum: %u\n", *crc);
*crc = 0;
checksum = 0;
data_idx = (u16 *)data;
for (i = 0; i < len; i += 2) {
checksum = checksum ^ (*data_idx);
data_idx++;
}
*crc = cpu_to_le16(checksum);
ath6kl_dbg(ATH6KL_DBG_BOOT, "New Checksum: %u\n", checksum);
}
static int ath6kl_fetch_mac_file(struct ath6kl *ar)
{
const struct firmware *fw_entry;
int ret = 0;
ret = request_firmware(&fw_entry, MAC_FILE, ar->dev);
if (ret)
return ret;
ath6kl_softmac_len = fw_entry->size;
ath6kl_softmac = kmemdup(fw_entry->data, fw_entry->size, GFP_KERNEL);
if (ath6kl_softmac == NULL)
ret = -ENOMEM;
release_firmware(fw_entry);
return ret;
}
void ath6kl_mangle_mac_address(struct ath6kl *ar)
{
u8 *ptr_mac;
int i, ret;
char mac_buf[128];
unsigned int softmac[6];
switch (ar->target_type) {
case TARGET_TYPE_AR6003:
ptr_mac = ar->fw_board + AR6003_MAC_ADDRESS_OFFSET;
break;
case TARGET_TYPE_AR6004:
ptr_mac = ar->fw_board + AR6004_MAC_ADDRESS_OFFSET;
break;
default:
ath6kl_err("Invalid Target Type\n");
return;
}
printk(
"MAC from EEPROM %02X:%02X:%02X:%02X:%02X:%02X\n",
ptr_mac[0], ptr_mac[1], ptr_mac[2],
ptr_mac[3], ptr_mac[4], ptr_mac[5]);
ret = ath6kl_fetch_mac_file(ar);
if (ret) {
ath6kl_err("MAC address file not found\n");
return;
}
if (ath6kl_softmac_len > sizeof(mac_buf)) {
ath6kl_err("Invalid softmac file\n");
return;
}
memcpy(mac_buf, ath6kl_softmac, ath6kl_softmac_len);
mac_buf[ath6kl_softmac_len] = '\0';
if (sscanf(mac_buf, "%02x:%02x:%02x:%02x:%02x:%02x",
&softmac[0], &softmac[1], &softmac[2],
&softmac[3], &softmac[4], &softmac[5]) == 6) {
for (i = 0; i < ETH_ALEN; ++i) {
ptr_mac[i] = softmac[i] & 0xff;
}
}
printk(
"Soft MAC %02X:%02X:%02X:%02X:%02X:%02X\n",
ptr_mac[0], ptr_mac[1], ptr_mac[2],
ptr_mac[3], ptr_mac[4], ptr_mac[5]);
kfree(ath6kl_softmac);
ath6kl_calculate_crc(ar->target_type, ar->fw_board, ar->fw_board_len);
}