ath10k: create a chip revision whitelist
authorMichal Kazior <michal.kazior@tieto.com>
Tue, 2 Dec 2014 08:55:54 +0000 (10:55 +0200)
committerKalle Valo <kvalo@qca.qualcomm.com>
Mon, 8 Dec 2014 15:34:13 +0000 (17:34 +0200)
This will make it easier to extend and maintain
list of supported hardware.

Signed-off-by: Michal Kazior <michal.kazior@tieto.com>
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
drivers/net/wireless/ath/ath10k/core.c
drivers/net/wireless/ath/ath10k/pci.c
drivers/net/wireless/ath/ath10k/pci.h

index 6165f2735b35c403e634c1e4ce44ddd357e14fa6..3a299fc8be88691599a8873a2615d0a7b61cc5a9 100644 (file)
@@ -1136,34 +1136,6 @@ static int ath10k_core_probe_fw(struct ath10k *ar)
        return 0;
 }
 
-static int ath10k_core_check_chip_id(struct ath10k *ar)
-{
-       u32 hw_revision = MS(ar->chip_id, SOC_CHIP_ID_REV);
-
-       ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot chip_id 0x%08x hw_revision 0x%x\n",
-                  ar->chip_id, hw_revision);
-
-       /* Check that we are not using hw1.0 (some of them have same pci id
-        * as hw2.0) before doing anything else as ath10k crashes horribly
-        * due to missing hw1.0 workarounds. */
-       switch (hw_revision) {
-       case QCA988X_HW_1_0_CHIP_ID_REV:
-               ath10k_err(ar, "ERROR: qca988x hw1.0 is not supported\n");
-               return -EOPNOTSUPP;
-
-       case QCA988X_HW_2_0_CHIP_ID_REV:
-               /* known hardware revision, continue normally */
-               return 0;
-
-       default:
-               ath10k_warn(ar, "Warning: hardware revision unknown (0x%x), expect problems\n",
-                           ar->chip_id);
-               return 0;
-       }
-
-       return 0;
-}
-
 static void ath10k_core_register_work(struct work_struct *work)
 {
        struct ath10k *ar = container_of(work, struct ath10k, register_work);
@@ -1211,16 +1183,7 @@ err:
 
 int ath10k_core_register(struct ath10k *ar, u32 chip_id)
 {
-       int status;
-
        ar->chip_id = chip_id;
-
-       status = ath10k_core_check_chip_id(ar);
-       if (status) {
-               ath10k_err(ar, "Unsupported chip id 0x%08x\n", ar->chip_id);
-               return status;
-       }
-
        queue_work(ar->workqueue, &ar->register_work);
 
        return 0;
index 7abb8367119a872f0de5063d9ff1f75025abcebd..5e50214246f8da317b669fdddea4dc952b60c8cf 100644 (file)
@@ -64,6 +64,14 @@ static const struct pci_device_id ath10k_pci_id_table[] = {
        {0}
 };
 
+static const struct ath10k_pci_supp_chip ath10k_pci_supp_chips[] = {
+       /* QCA988X pre 2.0 chips are not supported because they need some nasty
+        * hacks. ath10k doesn't have them and these devices crash horribly
+        * because of that.
+        */
+       { QCA988X_2_0_DEVICE_ID, QCA988X_HW_2_0_CHIP_ID_REV },
+};
+
 static void ath10k_pci_buffer_cleanup(struct ath10k *ar);
 static int ath10k_pci_cold_reset(struct ath10k *ar);
 static int ath10k_pci_warm_reset(struct ath10k *ar);
@@ -2476,6 +2484,23 @@ static void ath10k_pci_release(struct ath10k *ar)
        pci_disable_device(pdev);
 }
 
+static bool ath10k_pci_chip_is_supported(u32 dev_id, u32 chip_id)
+{
+       const struct ath10k_pci_supp_chip *supp_chip;
+       int i;
+       u32 rev_id = MS(chip_id, SOC_CHIP_ID_REV);
+
+       for (i = 0; i < ARRAY_SIZE(ath10k_pci_supp_chips); i++) {
+               supp_chip = &ath10k_pci_supp_chips[i];
+
+               if (supp_chip->dev_id == dev_id &&
+                   supp_chip->rev_id == rev_id)
+                       return true;
+       }
+
+       return false;
+}
+
 static int ath10k_pci_probe(struct pci_dev *pdev,
                            const struct pci_device_id *pci_dev)
 {
@@ -2521,6 +2546,12 @@ static int ath10k_pci_probe(struct pci_dev *pdev,
                goto err_sleep;
        }
 
+       if (!ath10k_pci_chip_is_supported(pdev->device, chip_id)) {
+               ath10k_err(ar, "device %04x with chip_id %08x isn't supported\n",
+                          pdev->device, chip_id);
+               goto err_sleep;
+       }
+
        ret = ath10k_pci_alloc_pipes(ar);
        if (ret) {
                ath10k_err(ar, "failed to allocate copy engine pipes: %d\n",
index cf36511c7f4dcf41db9610b5cd9487cefcfc59ad..ce4a1ef8996126f88c76e7876302dba2bdc2daac 100644 (file)
@@ -152,6 +152,11 @@ struct ath10k_pci_pipe {
        struct tasklet_struct intr;
 };
 
+struct ath10k_pci_supp_chip {
+       u32 dev_id;
+       u32 rev_id;
+};
+
 struct ath10k_pci {
        struct pci_dev *pdev;
        struct device *dev;