]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
wifi: ath12k: allocate dummy net_device dynamically
authorBreno Leitao <leitao@debian.org>
Wed, 8 May 2024 09:54:09 +0000 (02:54 -0700)
committerKalle Valo <quic_kvalo@quicinc.com>
Mon, 13 May 2024 14:19:13 +0000 (17:19 +0300)
Embedding net_device into structures prohibits the usage of flexible
arrays in the net_device structure. For more details, see the discussion
at [1].

Un-embed the net_device from struct ath12k_ext_irq_grp by converting it
into a pointer. Then use the leverage alloc_netdev_dummy() to allocate
the net_device object at ath12k_pci_ext_irq_config().

The free of the device occurs at ath12k_pci_free_ext_irq().

Link: https://lore.kernel.org/all/20240229225910.79e224cf@kernel.org/
Signed-off-by: Breno Leitao <leitao@debian.org>
Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
Link: https://msgid.link/20240508095410.1923198-1-leitao@debian.org
drivers/net/wireless/ath/ath12k/core.h
drivers/net/wireless/ath/ath12k/pci.c

index bb6c1b562baf6807d18780072bcf671659fd458d..c6b7524ce3a051bab59fedc83a95cf2735c002a3 100644 (file)
@@ -146,7 +146,7 @@ struct ath12k_ext_irq_grp {
        u32 grp_id;
        u64 timestamp;
        struct napi_struct napi;
-       struct net_device napi_ndev;
+       struct net_device *napi_ndev;
 };
 
 struct ath12k_smbios_bdf {
index 16af046c33d9eeed6ab9e1d1e89fa6e50cee0e54..ac75e8e3916bd92e7d4f1abd2b506061e810f306 100644 (file)
@@ -350,6 +350,7 @@ static void ath12k_pci_free_ext_irq(struct ath12k_base *ab)
                        free_irq(ab->irq_num[irq_grp->irqs[j]], irq_grp);
 
                netif_napi_del(&irq_grp->napi);
+               free_netdev(irq_grp->napi_ndev);
        }
 }
 
@@ -560,8 +561,9 @@ static irqreturn_t ath12k_pci_ext_interrupt_handler(int irq, void *arg)
 static int ath12k_pci_ext_irq_config(struct ath12k_base *ab)
 {
        struct ath12k_pci *ab_pci = ath12k_pci_priv(ab);
-       int i, j, ret, num_vectors = 0;
+       int i, j, n, ret, num_vectors = 0;
        u32 user_base_data = 0, base_vector = 0, base_idx;
+       struct ath12k_ext_irq_grp *irq_grp;
 
        base_idx = ATH12K_PCI_IRQ_CE0_OFFSET + CE_COUNT_MAX;
        ret = ath12k_pci_get_user_msi_assignment(ab, "DP",
@@ -572,13 +574,18 @@ static int ath12k_pci_ext_irq_config(struct ath12k_base *ab)
                return ret;
 
        for (i = 0; i < ATH12K_EXT_IRQ_GRP_NUM_MAX; i++) {
-               struct ath12k_ext_irq_grp *irq_grp = &ab->ext_irq_grp[i];
+               irq_grp = &ab->ext_irq_grp[i];
                u32 num_irq = 0;
 
                irq_grp->ab = ab;
                irq_grp->grp_id = i;
-               init_dummy_netdev(&irq_grp->napi_ndev);
-               netif_napi_add(&irq_grp->napi_ndev, &irq_grp->napi,
+               irq_grp->napi_ndev = alloc_netdev_dummy(0);
+               if (!irq_grp->napi_ndev) {
+                       ret = -ENOMEM;
+                       goto fail_allocate;
+               }
+
+               netif_napi_add(irq_grp->napi_ndev, &irq_grp->napi,
                               ath12k_pci_ext_grp_napi_poll);
 
                if (ab->hw_params->ring_mask->tx[i] ||
@@ -611,13 +618,23 @@ static int ath12k_pci_ext_irq_config(struct ath12k_base *ab)
                        if (ret) {
                                ath12k_err(ab, "failed request irq %d: %d\n",
                                           vector, ret);
-                               return ret;
+                               goto fail_request;
                        }
                }
                ath12k_pci_ext_grp_disable(irq_grp);
        }
 
        return 0;
+
+fail_request:
+       /* i ->napi_ndev was properly allocated. Free it also */
+       i += 1;
+fail_allocate:
+       for (n = 0; n < i; n++) {
+               irq_grp = &ab->ext_irq_grp[n];
+               free_netdev(irq_grp->napi_ndev);
+       }
+       return ret;
 }
 
 static int ath12k_pci_set_irq_affinity_hint(struct ath12k_pci *ab_pci,