aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless
diff options
context:
space:
mode:
authorBrian Cavagnolo <brian@cozybit.com>2010-11-12 20:23:51 -0500
committerJohn W. Linville <linville@tuxdriver.com>2010-11-16 16:37:03 -0500
commit952a0e963fb02e50f4afbf502f7d468a8fe2b0fa (patch)
treee3d170f1e6e251557d8b684ed1e93789336f1c1d /drivers/net/wireless
parent0863ade8d6bde1d151f75720d999ff27f9fe3533 (diff)
mwl8k: add API version checking for AP firmware
The AP firmware specifies an API version in the GET_HW_SPEC command response. Currently, the driver only supports AP firmware for the 8366, and only supports API v1. In the future, if higher API version firmwares emerge (possibly for different chips), different ops can be selected based on the reported API version. Signed-off-by: Brian Cavagnolo <brian@cozybit.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r--drivers/net/wireless/mwl8k.c23
1 files changed, 21 insertions, 2 deletions
diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c
index cbf72714e74d..e5b062c3bd56 100644
--- a/drivers/net/wireless/mwl8k.c
+++ b/drivers/net/wireless/mwl8k.c
@@ -101,6 +101,7 @@ struct mwl8k_device_info {
101 char *fw_image_sta; 101 char *fw_image_sta;
102 char *fw_image_ap; 102 char *fw_image_ap;
103 struct rxd_ops *ap_rxd_ops; 103 struct rxd_ops *ap_rxd_ops;
104 u32 fw_api_ap;
104}; 105};
105 106
106struct mwl8k_rx_queue { 107struct mwl8k_rx_queue {
@@ -1827,6 +1828,7 @@ struct mwl8k_cmd_get_hw_spec_ap {
1827 __le32 wcbbase1; 1828 __le32 wcbbase1;
1828 __le32 wcbbase2; 1829 __le32 wcbbase2;
1829 __le32 wcbbase3; 1830 __le32 wcbbase3;
1831 __le32 fw_api_version;
1830} __packed; 1832} __packed;
1831 1833
1832static int mwl8k_cmd_get_hw_spec_ap(struct ieee80211_hw *hw) 1834static int mwl8k_cmd_get_hw_spec_ap(struct ieee80211_hw *hw)
@@ -1834,6 +1836,7 @@ static int mwl8k_cmd_get_hw_spec_ap(struct ieee80211_hw *hw)
1834 struct mwl8k_priv *priv = hw->priv; 1836 struct mwl8k_priv *priv = hw->priv;
1835 struct mwl8k_cmd_get_hw_spec_ap *cmd; 1837 struct mwl8k_cmd_get_hw_spec_ap *cmd;
1836 int rc; 1838 int rc;
1839 u32 api_version;
1837 1840
1838 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 1841 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
1839 if (cmd == NULL) 1842 if (cmd == NULL)
@@ -1850,6 +1853,16 @@ static int mwl8k_cmd_get_hw_spec_ap(struct ieee80211_hw *hw)
1850 if (!rc) { 1853 if (!rc) {
1851 int off; 1854 int off;
1852 1855
1856 api_version = le32_to_cpu(cmd->fw_api_version);
1857 if (priv->device_info->fw_api_ap != api_version) {
1858 printk(KERN_ERR "%s: Unsupported fw API version for %s."
1859 " Expected %d got %d.\n", MWL8K_NAME,
1860 priv->device_info->part_name,
1861 priv->device_info->fw_api_ap,
1862 api_version);
1863 rc = -EINVAL;
1864 goto done;
1865 }
1853 SET_IEEE80211_PERM_ADDR(hw, cmd->perm_addr); 1866 SET_IEEE80211_PERM_ADDR(hw, cmd->perm_addr);
1854 priv->num_mcaddrs = le16_to_cpu(cmd->num_mcaddrs); 1867 priv->num_mcaddrs = le16_to_cpu(cmd->num_mcaddrs);
1855 priv->fw_rev = le32_to_cpu(cmd->fw_rev); 1868 priv->fw_rev = le32_to_cpu(cmd->fw_rev);
@@ -1877,6 +1890,7 @@ static int mwl8k_cmd_get_hw_spec_ap(struct ieee80211_hw *hw)
1877 iowrite32(priv->txq[3].txd_dma, priv->sram + off); 1890 iowrite32(priv->txq[3].txd_dma, priv->sram + off);
1878 } 1891 }
1879 1892
1893done:
1880 kfree(cmd); 1894 kfree(cmd);
1881 return rc; 1895 return rc;
1882} 1896}
@@ -3939,6 +3953,10 @@ enum {
3939 MWL8366, 3953 MWL8366,
3940}; 3954};
3941 3955
3956#define MWL8K_8366_AP_FW_API 1
3957#define _MWL8K_8366_AP_FW(api) "mwl8k/fmimage_8366_ap-" #api ".fw"
3958#define MWL8K_8366_AP_FW(api) _MWL8K_8366_AP_FW(api)
3959
3942static struct mwl8k_device_info mwl8k_info_tbl[] __devinitdata = { 3960static struct mwl8k_device_info mwl8k_info_tbl[] __devinitdata = {
3943 [MWL8363] = { 3961 [MWL8363] = {
3944 .part_name = "88w8363", 3962 .part_name = "88w8363",
@@ -3954,7 +3972,8 @@ static struct mwl8k_device_info mwl8k_info_tbl[] __devinitdata = {
3954 .part_name = "88w8366", 3972 .part_name = "88w8366",
3955 .helper_image = "mwl8k/helper_8366.fw", 3973 .helper_image = "mwl8k/helper_8366.fw",
3956 .fw_image_sta = "mwl8k/fmimage_8366.fw", 3974 .fw_image_sta = "mwl8k/fmimage_8366.fw",
3957 .fw_image_ap = "mwl8k/fmimage_8366_ap-1.fw", 3975 .fw_image_ap = MWL8K_8366_AP_FW(MWL8K_8366_AP_FW_API),
3976 .fw_api_ap = MWL8K_8366_AP_FW_API,
3958 .ap_rxd_ops = &rxd_8366_ap_ops, 3977 .ap_rxd_ops = &rxd_8366_ap_ops,
3959 }, 3978 },
3960}; 3979};
@@ -3965,7 +3984,7 @@ MODULE_FIRMWARE("mwl8k/helper_8687.fw");
3965MODULE_FIRMWARE("mwl8k/fmimage_8687.fw"); 3984MODULE_FIRMWARE("mwl8k/fmimage_8687.fw");
3966MODULE_FIRMWARE("mwl8k/helper_8366.fw"); 3985MODULE_FIRMWARE("mwl8k/helper_8366.fw");
3967MODULE_FIRMWARE("mwl8k/fmimage_8366.fw"); 3986MODULE_FIRMWARE("mwl8k/fmimage_8366.fw");
3968MODULE_FIRMWARE("mwl8k/fmimage_8366_ap-1.fw"); 3987MODULE_FIRMWARE(MWL8K_8366_AP_FW(MWL8K_8366_AP_FW_API));
3969 3988
3970static DEFINE_PCI_DEVICE_TABLE(mwl8k_pci_id_table) = { 3989static DEFINE_PCI_DEVICE_TABLE(mwl8k_pci_id_table) = {
3971 { PCI_VDEVICE(MARVELL, 0x2a0a), .driver_data = MWL8363, }, 3990 { PCI_VDEVICE(MARVELL, 0x2a0a), .driver_data = MWL8363, },