1 // SPDX-License-Identifier: ISC
2 /* Initialize Owl Emulation Devices
4 * Copyright (C) 2016 Christian Lamparter <chunkeey@gmail.com>
5 * Copyright (C) 2016 Martin Blumenstingl <martin.blumenstingl@googlemail.com>
7 * Some devices (like the Cisco Meraki Z1 Cloud Managed Teleworker Gateway)
8 * need to be able to initialize the PCIe wifi device. Normally, this is done
9 * during the early stages as a pci quirk.
10 * However, this isn't possible for devices which have the init code for the
11 * Atheros chip stored on UBI Volume on NAND. Hence, this module can be used to
12 * initialize the chip when the user-space is ready to extract the init code.
14 #include <linux/module.h>
15 #include <linux/completion.h>
16 #include <linux/etherdevice.h>
17 #include <linux/firmware.h>
18 #include <linux/pci.h>
19 #include <linux/delay.h>
20 #include <linux/platform_device.h>
21 #include <linux/ath9k_platform.h>
24 struct completion eeprom_load
;
27 #define EEPROM_FILENAME_LEN 100
29 #define AR5416_EEPROM_MAGIC 0xa55a
31 static int ath9k_pci_fixup(struct pci_dev
*pdev
, const u16
*cal_data
,
35 const void *cal_end
= (void *)cal_data
+ cal_len
;
43 bool swap_needed
= false;
45 if (*cal_data
!= AR5416_EEPROM_MAGIC
) {
46 if (*cal_data
!= swab16(AR5416_EEPROM_MAGIC
)) {
47 dev_err(&pdev
->dev
, "invalid calibration data\n");
51 dev_dbg(&pdev
->dev
, "calibration data needs swapping\n");
55 dev_info(&pdev
->dev
, "fixup device configuration\n");
57 mem
= pcim_iomap(pdev
, 0, 0);
59 dev_err(&pdev
->dev
, "ioremap error\n");
63 pci_read_config_dword(pdev
, PCI_BASE_ADDRESS_0
, &bar0
);
64 pci_write_config_dword(pdev
, PCI_BASE_ADDRESS_0
,
65 pci_resource_start(pdev
, 0));
66 pci_read_config_word(pdev
, PCI_COMMAND
, &cmd
);
67 cmd
|= PCI_COMMAND_MASTER
| PCI_COMMAND_MEMORY
;
68 pci_write_config_word(pdev
, PCI_COMMAND
, cmd
);
70 /* set pointer to first reg address */
71 for (data
= (const void *)(cal_data
+ 3);
72 (const void *)data
<= cal_end
&& data
->reg
!= (u16
)~0;
79 val
|= ((u32
)data
->high_val
) << 16;
86 iowrite32(val
, mem
+ reg
);
87 usleep_range(100, 120);
90 pci_read_config_word(pdev
, PCI_COMMAND
, &cmd
);
91 cmd
&= ~(PCI_COMMAND_MASTER
| PCI_COMMAND_MEMORY
);
92 pci_write_config_word(pdev
, PCI_COMMAND
, cmd
);
94 pci_write_config_dword(pdev
, PCI_BASE_ADDRESS_0
, bar0
);
95 pcim_iounmap(pdev
, mem
);
97 pci_disable_device(pdev
);
102 static void owl_fw_cb(const struct firmware
*fw
, void *context
)
104 struct pci_dev
*pdev
= (struct pci_dev
*)context
;
105 struct owl_ctx
*ctx
= (struct owl_ctx
*)pci_get_drvdata(pdev
);
108 complete(&ctx
->eeprom_load
);
111 dev_err(&pdev
->dev
, "no eeprom data received.\n");
115 /* also note that we are doing *u16 operations on the file */
116 if (fw
->size
> 4096 || fw
->size
< 0x200 || (fw
->size
& 1) == 1) {
117 dev_err(&pdev
->dev
, "eeprom file has an invalid size.\n");
121 if (ath9k_pci_fixup(pdev
, (const u16
*)fw
->data
, fw
->size
))
124 pci_lock_rescan_remove();
126 pci_stop_and_remove_bus_device(pdev
);
127 /* the device should come back with the proper
128 * ProductId. But we have to initiate a rescan.
131 pci_unlock_rescan_remove();
134 release_firmware(fw
);
137 static const char *owl_get_eeprom_name(struct pci_dev
*pdev
)
139 struct device
*dev
= &pdev
->dev
;
142 dev_dbg(dev
, "using auto-generated eeprom filename\n");
144 eeprom_name
= devm_kzalloc(dev
, EEPROM_FILENAME_LEN
, GFP_KERNEL
);
148 /* this should match the pattern used in ath9k/init.c */
149 scnprintf(eeprom_name
, EEPROM_FILENAME_LEN
, "ath9k-eeprom-pci-%s.bin",
155 static int owl_probe(struct pci_dev
*pdev
,
156 const struct pci_device_id
*id
)
159 const char *eeprom_name
;
162 if (pcim_enable_device(pdev
))
165 pcim_pin_device(pdev
);
167 eeprom_name
= owl_get_eeprom_name(pdev
);
169 dev_err(&pdev
->dev
, "no eeprom filename found.\n");
173 ctx
= devm_kzalloc(&pdev
->dev
, sizeof(*ctx
), GFP_KERNEL
);
177 init_completion(&ctx
->eeprom_load
);
179 pci_set_drvdata(pdev
, ctx
);
180 err
= request_firmware_nowait(THIS_MODULE
, true, eeprom_name
,
181 &pdev
->dev
, GFP_KERNEL
, pdev
, owl_fw_cb
);
183 dev_err(&pdev
->dev
, "failed to request caldata (%d).\n", err
);
188 static void owl_remove(struct pci_dev
*pdev
)
190 struct owl_ctx
*ctx
= pci_get_drvdata(pdev
);
193 wait_for_completion(&ctx
->eeprom_load
);
194 pci_set_drvdata(pdev
, NULL
);
198 static const struct pci_device_id owl_pci_table
[] = {
199 { PCI_VDEVICE(ATHEROS
, 0xff1c) }, /* PCIe */
200 { PCI_VDEVICE(ATHEROS
, 0xff1d) }, /* PCI */
203 MODULE_DEVICE_TABLE(pci
, owl_pci_table
);
205 static struct pci_driver owl_driver
= {
206 .name
= KBUILD_MODNAME
,
207 .id_table
= owl_pci_table
,
209 .remove
= owl_remove
,
211 module_pci_driver(owl_driver
);
212 MODULE_AUTHOR("Christian Lamparter <chunkeey@gmail.com>");
213 MODULE_DESCRIPTION("External EEPROM data loader for Atheros AR500X to AR92XX");
214 MODULE_LICENSE("Dual BSD/GPL");