mirror of
				git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
				synced 2025-10-31 16:54:21 +00:00 
			
		
		
		
	ath11k: refactor multiple MSI vector implementation
This is to prepare for one MSI vector support. IRQ enable and disable of CE and DP are done only in case of multiple MSI vectors. Tested-on: QCA6390 hw2.0 PCI WLAN.HST.1.0.1-01740-QCAHSTSWPLZ_V2_TO_X86-1 Signed-off-by: Carl Huang <cjhuang@codeaurora.org> Signed-off-by: Kalle Valo <kvalo@codeaurora.org> Signed-off-by: Baochen Qiang <bqiang@codeaurora.org> Link: https://lore.kernel.org/r/20211026041705.5167-1-bqiang@codeaurora.org
This commit is contained in:
		
							parent
							
								
									4ab4693f32
								
							
						
					
					
						commit
						c41a6700b2
					
				
					 2 changed files with 43 additions and 8 deletions
				
			
		|  | @ -486,11 +486,11 @@ int ath11k_pci_get_user_msi_assignment(struct ath11k_pci *ab_pci, char *user_nam | |||
| 	for (idx = 0; idx < msi_config->total_users; idx++) { | ||||
| 		if (strcmp(user_name, msi_config->users[idx].name) == 0) { | ||||
| 			*num_vectors = msi_config->users[idx].num_vectors; | ||||
| 			*user_base_data = msi_config->users[idx].base_vector | ||||
| 				+ ab_pci->msi_ep_base_data; | ||||
| 			*base_vector = msi_config->users[idx].base_vector; | ||||
| 			*base_vector =  msi_config->users[idx].base_vector; | ||||
| 			*user_base_data = *base_vector + ab_pci->msi_ep_base_data; | ||||
| 
 | ||||
| 			ath11k_dbg(ab, ATH11K_DBG_PCI, "Assign MSI to user: %s, num_vectors: %d, user_base_data: %u, base_vector: %u\n", | ||||
| 			ath11k_dbg(ab, ATH11K_DBG_PCI, | ||||
| 				   "Assign MSI to user: %s, num_vectors: %d, user_base_data: %u, base_vector: %u\n", | ||||
| 				   user_name, *num_vectors, *user_base_data, | ||||
| 				   *base_vector); | ||||
| 
 | ||||
|  | @ -561,16 +561,30 @@ static void ath11k_pci_free_irq(struct ath11k_base *ab) | |||
| 
 | ||||
| static void ath11k_pci_ce_irq_enable(struct ath11k_base *ab, u16 ce_id) | ||||
| { | ||||
| 	struct ath11k_pci *ab_pci = ath11k_pci_priv(ab); | ||||
| 	u32 irq_idx; | ||||
| 
 | ||||
| 	/* In case of one MSI vector, we handle irq enable/disable in a
 | ||||
| 	 * uniform way since we only have one irq | ||||
| 	 */ | ||||
| 	if (!test_bit(ATH11K_PCI_FLAG_MULTI_MSI_VECTORS, &ab_pci->flags)) | ||||
| 		return; | ||||
| 
 | ||||
| 	irq_idx = ATH11K_PCI_IRQ_CE0_OFFSET + ce_id; | ||||
| 	enable_irq(ab->irq_num[irq_idx]); | ||||
| } | ||||
| 
 | ||||
| static void ath11k_pci_ce_irq_disable(struct ath11k_base *ab, u16 ce_id) | ||||
| { | ||||
| 	struct ath11k_pci *ab_pci = ath11k_pci_priv(ab); | ||||
| 	u32 irq_idx; | ||||
| 
 | ||||
| 	/* In case of one MSI vector, we handle irq enable/disable in a
 | ||||
| 	 * uniform way since we only have one irq | ||||
| 	 */ | ||||
| 	if (!test_bit(ATH11K_PCI_FLAG_MULTI_MSI_VECTORS, &ab_pci->flags)) | ||||
| 		return; | ||||
| 
 | ||||
| 	irq_idx = ATH11K_PCI_IRQ_CE0_OFFSET + ce_id; | ||||
| 	disable_irq_nosync(ab->irq_num[irq_idx]); | ||||
| } | ||||
|  | @ -630,8 +644,15 @@ static irqreturn_t ath11k_pci_ce_interrupt_handler(int irq, void *arg) | |||
| 
 | ||||
| static void ath11k_pci_ext_grp_disable(struct ath11k_ext_irq_grp *irq_grp) | ||||
| { | ||||
| 	struct ath11k_pci *ab_pci = ath11k_pci_priv(irq_grp->ab); | ||||
| 	int i; | ||||
| 
 | ||||
| 	/* In case of one MSI vector, we handle irq enable/disable
 | ||||
| 	 * in a uniform way since we only have one irq | ||||
| 	 */ | ||||
| 	if (!test_bit(ATH11K_PCI_FLAG_MULTI_MSI_VECTORS, &ab_pci->flags)) | ||||
| 		return; | ||||
| 
 | ||||
| 	for (i = 0; i < irq_grp->num_irq; i++) | ||||
| 		disable_irq_nosync(irq_grp->ab->irq_num[irq_grp->irqs[i]]); | ||||
| } | ||||
|  | @ -654,8 +675,15 @@ static void __ath11k_pci_ext_irq_disable(struct ath11k_base *sc) | |||
| 
 | ||||
| static void ath11k_pci_ext_grp_enable(struct ath11k_ext_irq_grp *irq_grp) | ||||
| { | ||||
| 	struct ath11k_pci *ab_pci = ath11k_pci_priv(irq_grp->ab); | ||||
| 	int i; | ||||
| 
 | ||||
| 	/* In case of one MSI vector, we handle irq enable/disable in a
 | ||||
| 	 * uniform way since we only have one irq | ||||
| 	 */ | ||||
| 	if (!test_bit(ATH11K_PCI_FLAG_MULTI_MSI_VECTORS, &ab_pci->flags)) | ||||
| 		return; | ||||
| 
 | ||||
| 	for (i = 0; i < irq_grp->num_irq; i++) | ||||
| 		enable_irq(irq_grp->ab->irq_num[irq_grp->irqs[i]]); | ||||
| } | ||||
|  | @ -736,6 +764,7 @@ static irqreturn_t ath11k_pci_ext_interrupt_handler(int irq, void *arg) | |||
| 
 | ||||
| static int ath11k_pci_ext_irq_config(struct ath11k_base *ab) | ||||
| { | ||||
| 	struct ath11k_pci *ab_pci = ath11k_pci_priv(ab); | ||||
| 	int i, j, ret, num_vectors = 0; | ||||
| 	u32 user_base_data = 0, base_vector = 0; | ||||
| 
 | ||||
|  | @ -782,16 +811,15 @@ static int ath11k_pci_ext_irq_config(struct ath11k_base *ab) | |||
| 
 | ||||
| 			irq_set_status_flags(irq, IRQ_DISABLE_UNLAZY); | ||||
| 			ret = request_irq(irq, ath11k_pci_ext_interrupt_handler, | ||||
| 					  IRQF_SHARED, | ||||
| 					  ab_pci->irq_flags, | ||||
| 					  "DP_EXT_IRQ", irq_grp); | ||||
| 			if (ret) { | ||||
| 				ath11k_err(ab, "failed request irq %d: %d\n", | ||||
| 					   vector, ret); | ||||
| 				return ret; | ||||
| 			} | ||||
| 
 | ||||
| 			disable_irq_nosync(ab->irq_num[irq_idx]); | ||||
| 		} | ||||
| 		ath11k_pci_ext_grp_disable(irq_grp); | ||||
| 	} | ||||
| 
 | ||||
| 	return 0; | ||||
|  | @ -799,6 +827,7 @@ static int ath11k_pci_ext_irq_config(struct ath11k_base *ab) | |||
| 
 | ||||
| static int ath11k_pci_config_irq(struct ath11k_base *ab) | ||||
| { | ||||
| 	struct ath11k_pci *ab_pci = ath11k_pci_priv(ab); | ||||
| 	struct ath11k_ce_pipe *ce_pipe; | ||||
| 	u32 msi_data_start; | ||||
| 	u32 msi_data_count, msi_data_idx; | ||||
|  | @ -826,7 +855,7 @@ static int ath11k_pci_config_irq(struct ath11k_base *ab) | |||
| 		tasklet_setup(&ce_pipe->intr_tq, ath11k_pci_ce_tasklet); | ||||
| 
 | ||||
| 		ret = request_irq(irq, ath11k_pci_ce_interrupt_handler, | ||||
| 				  IRQF_SHARED, irq_name[irq_idx], | ||||
| 				  ab_pci->irq_flags, irq_name[irq_idx], | ||||
| 				  ce_pipe); | ||||
| 		if (ret) { | ||||
| 			ath11k_err(ab, "failed to request irq %d: %d\n", | ||||
|  | @ -920,6 +949,9 @@ static int ath11k_pci_alloc_msi(struct ath11k_pci *ab_pci) | |||
| 			return -EINVAL; | ||||
| 		else | ||||
| 			return num_vectors; | ||||
| 	} else { | ||||
| 		set_bit(ATH11K_PCI_FLAG_MULTI_MSI_VECTORS, &ab_pci->flags); | ||||
| 		ab_pci->irq_flags = IRQF_SHARED; | ||||
| 	} | ||||
| 	ath11k_pci_msi_disable(ab_pci); | ||||
| 
 | ||||
|  |  | |||
|  | @ -68,6 +68,7 @@ enum ath11k_pci_flags { | |||
| 	ATH11K_PCI_FLAG_INIT_DONE, | ||||
| 	ATH11K_PCI_FLAG_IS_MSI_64, | ||||
| 	ATH11K_PCI_ASPM_RESTORE, | ||||
| 	ATH11K_PCI_FLAG_MULTI_MSI_VECTORS, | ||||
| }; | ||||
| 
 | ||||
| struct ath11k_pci { | ||||
|  | @ -87,6 +88,8 @@ struct ath11k_pci { | |||
| 	/* enum ath11k_pci_flags */ | ||||
| 	unsigned long flags; | ||||
| 	u16 link_ctl; | ||||
| 
 | ||||
| 	unsigned long irq_flags; | ||||
| }; | ||||
| 
 | ||||
| static inline struct ath11k_pci *ath11k_pci_priv(struct ath11k_base *ab) | ||||
|  |  | |||
		Loading…
	
	Add table
		
		Reference in a new issue
	
	 Carl Huang
						Carl Huang