+static u8 ltq_ethaddr[6] = { 0 };
+
+static int __init setup_ethaddr(char *str)
+{
+ if (!mac_pton(str, ltq_ethaddr))
+ memset(ltq_ethaddr, 0, 6);
+ return 0;
+}
+__setup("ethaddr=", setup_ethaddr);
+
+static u16 dgn3500_eeprom_data[ATH9K_PLAT_EEP_MAX_WORDS] = {0};
+
+static ssize_t ath_eeprom_read(struct file *filp, struct kobject *kobj,
+ struct bin_attribute *attr, char *buf,
+ loff_t offset, size_t count)
+{
+ if (unlikely(offset >= sizeof(dgn3500_eeprom_data)))
+ return 0;
+ if ((offset + count) > sizeof(dgn3500_eeprom_data))
+ count = sizeof(dgn3500_eeprom_data) - offset;
+ if (unlikely(!count))
+ return count;
+
+ memcpy(buf, (char *)(dgn3500_eeprom_data) + offset, count);
+
+ return count;
+}
+
+extern struct ath9k_platform_data ath9k_pdata;
+
+static ssize_t ath_eeprom_write(struct file *filp, struct kobject *kobj,
+ struct bin_attribute *attr, char *buf,
+ loff_t offset, size_t count)
+{
+ int i;
+ char *eeprom_bytes = (char *)dgn3500_eeprom_data;
+
+ if (unlikely(offset >= sizeof(dgn3500_eeprom_data)))
+ return -EFBIG;
+ if ((offset + count) > sizeof(dgn3500_eeprom_data))
+ count = sizeof(dgn3500_eeprom_data) - offset;
+ if (unlikely(!count))
+ return count;
+ if (count % 2)
+ return 0;
+
+ /* The PCI fixup routine requires an endian swap of the calibartion data
+ * stored in flash */
+ for (i = 0; i < count; i += 2) {
+ eeprom_bytes[offset + i + 1] = buf[i];
+ eeprom_bytes[offset + i] = buf[i+1];
+ }
+
+ /* The original data does not contain a checksum. Set the country and
+ * calculate new checksum when all data is received */
+ if ((count + offset) == sizeof(dgn3500_eeprom_data))
+ memcpy(ath9k_pdata.eeprom_data, dgn3500_eeprom_data,
+ sizeof(ath9k_pdata.eeprom_data));
+
+ return count;
+}
+
+static struct bin_attribute dev_attr_ath_eeprom = {
+ .attr = {
+ .name = "ath_eeprom",
+ .mode = S_IRUGO|S_IWUSR,
+ },
+ .read = ath_eeprom_read,
+ .write = ath_eeprom_write,