Browse Source

qcacmn: Support one MSI vector dynamically

MSI vector number is defined in platform driver, so use platform
driver API to check whether it is in one MSI mode or not.

In case of one MSI vector, interrupt migration needs to be disabled.
This is because when interrupt migration happens, the MSI data may
change. However, MSI data is already programmed to rings during initial
phase and there is no way to know that MSI data is changed during run
time and reprogram again.

If it is in one MSI mode, disable interrupt migration by adding IRQ
flag IRQF_NOBALANCING.

Change-Id: I54579dfe1e658c1a2c395be93875d013d6e6affd
CRs-Fixed: 3290829
Bing Sun 2 năm trước cách đây
mục cha
commit
186e8421e0
2 tập tin đã thay đổi với 27 bổ sung17 xóa
  1. 11 11
      dp/wifi3.0/dp_main.c
  2. 16 6
      hif/src/pcie/if_pci.c

+ 11 - 11
dp/wifi3.0/dp_main.c

@@ -1225,24 +1225,22 @@ static int dp_srng_find_ring_in_mask(int ring_num, uint8_t *grp_mask)
 
 /**
  * dp_is_msi_group_number_invalid() - check msi_group_number valid or not
+ * @soc: dp_soc
  * @msi_group_number: MSI group number.
  * @msi_data_count: MSI data count.
  *
  * Return: true if msi_group_number is invalid.
  */
-#ifdef WLAN_ONE_MSI_VECTOR
-static bool dp_is_msi_group_number_invalid(int msi_group_number,
-					   int msi_data_count)
-{
-	return false;
-}
-#else
-static bool dp_is_msi_group_number_invalid(int msi_group_number,
+static bool dp_is_msi_group_number_invalid(struct dp_soc *soc,
+					   int msi_group_number,
 					   int msi_data_count)
 {
+	if (soc && soc->osdev && soc->osdev->dev &&
+	    pld_is_one_msi(soc->osdev->dev))
+		return false;
+
 	return msi_group_number > msi_data_count;
 }
-#endif
 
 #ifdef WLAN_FEATURE_NEAR_FULL_IRQ
 /**
@@ -1370,7 +1368,8 @@ dp_srng_msi2_setup(struct dp_soc *soc,
 		return;
 	}
 
-	if (dp_is_msi_group_number_invalid(nf_msi_grp_num, msi_data_count)) {
+	if (dp_is_msi_group_number_invalid(soc, nf_msi_grp_num,
+					   msi_data_count)) {
 		dp_init_warn("%pK: 2 msi_groups will share an msi for near full IRQ; msi_group_num %d",
 			     soc, nf_msi_grp_num);
 		QDF_ASSERT(0);
@@ -1681,7 +1680,8 @@ static void dp_srng_msi_setup(struct dp_soc *soc, struct hal_srng_params
 		goto configure_msi2;
 	}
 
-	if (dp_is_msi_group_number_invalid(reg_msi_grp_num, msi_data_count)) {
+	if (dp_is_msi_group_number_invalid(soc, reg_msi_grp_num,
+					   msi_data_count)) {
 		dp_init_warn("%pK: 2 msi_groups will share an msi; msi_group_num %d",
 			     soc, reg_msi_grp_num);
 		QDF_ASSERT(0);

+ 16 - 6
hif/src/pcie/if_pci.c

@@ -3020,6 +3020,7 @@ int hif_ce_msi_configure_irq_by_ceid(struct hif_softc *scn, int ce_id)
 	struct HIF_CE_state *ce_sc = HIF_GET_CE_STATE(scn);
 	struct hif_pci_softc *pci_sc = HIF_GET_PCI_SOFTC(scn);
 	int pci_slot;
+	unsigned long irq_flags;
 
 	if (ce_id >= CE_COUNT_MAX)
 		return -EINVAL;
@@ -3041,8 +3042,12 @@ int hif_ce_msi_configure_irq_by_ceid(struct hif_softc *scn, int ce_id)
 	pci_slot = hif_get_pci_slot(scn);
 	msi_data = irq_id + msi_irq_start;
 	irq = pld_get_msi_irq(scn->qdf_dev->dev, msi_data);
-	hif_debug("%s: (ce_id %d, irq_id %d, msi_data %d, irq %d tasklet %pK)",
-		  __func__, ce_id, irq_id, msi_data, irq,
+	if (pld_is_one_msi(scn->qdf_dev->dev))
+		irq_flags = IRQF_SHARED | IRQF_NOBALANCING;
+	else
+		irq_flags = IRQF_SHARED;
+	hif_debug("%s: (ce_id %d, irq_id %d, msi_data %d, irq %d flag 0x%lx tasklet %pK)",
+		  __func__, ce_id, irq_id, msi_data, irq, irq_flags,
 		  &ce_sc->tasklets[ce_id]);
 
 	/* implies the ce is also initialized */
@@ -3056,7 +3061,7 @@ int hif_ce_msi_configure_irq_by_ceid(struct hif_softc *scn, int ce_id)
 		      pci_slot, ce_id);
 
 	ret = pfrm_request_irq(scn->qdf_dev->dev,
-			       irq, hif_ce_interrupt_handler, IRQF_SHARED,
+			       irq, hif_ce_interrupt_handler, irq_flags,
 			       ce_irqname[pci_slot][ce_id],
 			       &ce_sc->tasklets[ce_id]);
 	if (ret)
@@ -3430,6 +3435,7 @@ int hif_pci_configure_grp_irq(struct hif_softc *scn,
 	int irq = 0;
 	int j;
 	int pci_slot;
+	unsigned long irq_flags;
 
 	if (pld_get_enable_intx(scn->qdf_dev->dev))
 		return hif_grp_configure_legacyirq(scn, hif_ext_group);
@@ -3446,8 +3452,12 @@ int hif_pci_configure_grp_irq(struct hif_softc *scn,
 			qdf_dev_set_irq_status_flags(irq,
 						     QDF_IRQ_DISABLE_UNLAZY);
 
-		hif_debug("request_irq = %d for grp %d",
-			  irq, hif_ext_group->grp_id);
+		if (pld_is_one_msi(scn->qdf_dev->dev))
+			irq_flags = IRQF_SHARED | IRQF_NOBALANCING;
+		else
+			irq_flags = IRQF_SHARED | IRQF_NO_SUSPEND;
+		hif_debug("request_irq = %d for grp %d irq_flags 0x%lx",
+			  irq, hif_ext_group->grp_id, irq_flags);
 
 		qdf_scnprintf(dp_irqname[pci_slot][hif_ext_group->grp_id],
 			      DP_IRQ_NAME_LEN, "pci%u_wlan_grp_dp_%u",
@@ -3455,7 +3465,7 @@ int hif_pci_configure_grp_irq(struct hif_softc *scn,
 		ret = pfrm_request_irq(
 				scn->qdf_dev->dev, irq,
 				hif_ext_group_interrupt_handler,
-				IRQF_SHARED | IRQF_NO_SUSPEND,
+				irq_flags,
 				dp_irqname[pci_slot][hif_ext_group->grp_id],
 				hif_ext_group);
 		if (ret) {