diff options
Diffstat (limited to 'drivers/net/wireless/intel/iwlwifi/pcie/trans.c')
| -rw-r--r-- | drivers/net/wireless/intel/iwlwifi/pcie/trans.c | 92 | 
1 files changed, 58 insertions, 34 deletions
| diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c index fe8269d023de..803fcbac4152 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c @@ -896,6 +896,8 @@ void iwl_pcie_apply_destination(struct iwl_trans *trans)  		if (!trans->num_blocks)  			return; +		IWL_DEBUG_FW(trans, +			     "WRT: applying DRAM buffer[0] destination\n");  		iwl_write_umac_prph(trans, MON_BUFF_BASE_ADDR_VER2,  				    trans->fw_mon[0].physical >>  				    MON_BUFF_SHIFT_VER2); @@ -2067,7 +2069,6 @@ static void iwl_trans_pcie_release_nic_access(struct iwl_trans *trans,  	 * MAC_ACCESS_REQ bit to be performed before any other writes  	 * scheduled on different CPUs (after we drop reg_lock).  	 */ -	mmiowb();  out:  	spin_unlock_irqrestore(&trans_pcie->reg_lock, *flags);  } @@ -2442,9 +2443,8 @@ void iwl_pcie_dump_csr(struct iwl_trans *trans)  #ifdef CONFIG_IWLWIFI_DEBUGFS  /* create and remove of files */  #define DEBUGFS_ADD_FILE(name, parent, mode) do {			\ -	if (!debugfs_create_file(#name, mode, parent, trans,		\ -				 &iwl_dbgfs_##name##_ops))		\ -		goto err;						\ +	debugfs_create_file(#name, mode, parent, trans,			\ +			    &iwl_dbgfs_##name##_ops);			\  } while (0)  /* file operation */ @@ -2687,16 +2687,17 @@ static ssize_t iwl_dbgfs_rfkill_write(struct file *file,  {  	struct iwl_trans *trans = file->private_data;  	struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); -	bool old = trans_pcie->debug_rfkill; +	bool new_value;  	int ret; -	ret = kstrtobool_from_user(user_buf, count, &trans_pcie->debug_rfkill); +	ret = kstrtobool_from_user(user_buf, count, &new_value);  	if (ret)  		return ret; -	if (old == trans_pcie->debug_rfkill) +	if (new_value == trans_pcie->debug_rfkill)  		return count;  	IWL_WARN(trans, "changing debug rfkill %d->%d\n", -		 old, trans_pcie->debug_rfkill); +		 trans_pcie->debug_rfkill, new_value); +	trans_pcie->debug_rfkill = new_value;  	iwl_pcie_handle_rfkill_irq(trans);  	return count; @@ -2847,7 +2848,7 @@ static const struct file_operations iwl_dbgfs_monitor_data_ops = {  };  /* Create the debugfs files and directories */ -int iwl_trans_pcie_dbgfs_register(struct iwl_trans *trans) +void iwl_trans_pcie_dbgfs_register(struct iwl_trans *trans)  {  	struct dentry *dir = trans->dbgfs_dir; @@ -2858,11 +2859,6 @@ int iwl_trans_pcie_dbgfs_register(struct iwl_trans *trans)  	DEBUGFS_ADD_FILE(fh_reg, dir, 0400);  	DEBUGFS_ADD_FILE(rfkill, dir, 0600);  	DEBUGFS_ADD_FILE(monitor_data, dir, 0400); -	return 0; - -err: -	IWL_ERR(trans, "failed to create the trans debugfs entry\n"); -	return -ENOMEM;  }  static void iwl_trans_pcie_debugfs_cleanup(struct iwl_trans *trans) @@ -3012,10 +3008,14 @@ static void  iwl_trans_pcie_dump_pointers(struct iwl_trans *trans,  			     struct iwl_fw_error_dump_fw_mon *fw_mon_data)  { -	u32 base, write_ptr, wrap_cnt; +	u32 base, base_high, write_ptr, write_ptr_val, wrap_cnt; -	/* If there was a dest TLV - use the values from there */ -	if (trans->ini_valid) { +	if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_AX210) { +		base = DBGC_CUR_DBGBUF_BASE_ADDR_LSB; +		base_high = DBGC_CUR_DBGBUF_BASE_ADDR_MSB; +		write_ptr = DBGC_CUR_DBGBUF_STATUS; +		wrap_cnt = DBGC_DBGBUF_WRAP_AROUND; +	} else if (trans->ini_valid) {  		base = iwl_umac_prph(trans, MON_BUFF_BASE_ADDR_VER2);  		write_ptr = iwl_umac_prph(trans, MON_BUFF_WRPTR_VER2);  		wrap_cnt = iwl_umac_prph(trans, MON_BUFF_CYCLE_CNT_VER2); @@ -3028,12 +3028,18 @@ iwl_trans_pcie_dump_pointers(struct iwl_trans *trans,  		write_ptr = MON_BUFF_WRPTR;  		wrap_cnt = MON_BUFF_CYCLE_CNT;  	} -	fw_mon_data->fw_mon_wr_ptr = -		cpu_to_le32(iwl_read_prph(trans, write_ptr)); + +	write_ptr_val = iwl_read_prph(trans, write_ptr);  	fw_mon_data->fw_mon_cycle_cnt =  		cpu_to_le32(iwl_read_prph(trans, wrap_cnt));  	fw_mon_data->fw_mon_base_ptr =  		cpu_to_le32(iwl_read_prph(trans, base)); +	if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_AX210) { +		fw_mon_data->fw_mon_base_high_ptr = +			cpu_to_le32(iwl_read_prph(trans, base_high)); +		write_ptr_val &= DBGC_CUR_DBGBUF_STATUS_OFFSET_MSK; +	} +	fw_mon_data->fw_mon_wr_ptr = cpu_to_le32(write_ptr_val);  }  static u32 @@ -3044,9 +3050,10 @@ iwl_trans_pcie_dump_monitor(struct iwl_trans *trans,  	u32 len = 0;  	if ((trans->num_blocks && -	     trans->cfg->device_family == IWL_DEVICE_FAMILY_7000) || -	     (trans->dbg_dest_tlv && !trans->ini_valid) || -	     (trans->ini_valid && trans->num_blocks)) { +	     (trans->cfg->device_family == IWL_DEVICE_FAMILY_7000 || +	      trans->cfg->device_family >= IWL_DEVICE_FAMILY_AX210 || +	      trans->ini_valid)) || +	    (trans->dbg_dest_tlv && !trans->ini_valid)) {  		struct iwl_fw_error_dump_fw_mon *fw_mon_data;  		(*data)->type = cpu_to_le32(IWL_FW_ERROR_DUMP_FW_MONITOR); @@ -3165,8 +3172,10 @@ static struct iwl_trans_dump_data  	len = sizeof(*dump_data);  	/* host commands */ -	len += sizeof(*data) + -		cmdq->n_window * (sizeof(*txcmd) + TFD_MAX_PAYLOAD_SIZE); +	if (dump_mask & BIT(IWL_FW_ERROR_DUMP_TXCMD)) +		len += sizeof(*data) + +			cmdq->n_window * (sizeof(*txcmd) + +					  TFD_MAX_PAYLOAD_SIZE);  	/* FW monitor */  	if (dump_mask & BIT(IWL_FW_ERROR_DUMP_FW_MONITOR)) @@ -3318,7 +3327,8 @@ static void iwl_trans_pcie_resume(struct iwl_trans *trans)  	.unref = iwl_trans_pcie_unref,					\  	.dump_data = iwl_trans_pcie_dump_data,				\  	.d3_suspend = iwl_trans_pcie_d3_suspend,			\ -	.d3_resume = iwl_trans_pcie_d3_resume +	.d3_resume = iwl_trans_pcie_d3_resume,				\ +	.sync_nmi = iwl_trans_pcie_sync_nmi  #ifdef CONFIG_PM_SLEEP  #define IWL_TRANS_PM_OPS						\ @@ -3411,7 +3421,7 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,  		ret = -ENOMEM;  		goto out_no_pci;  	} - +	trans_pcie->debug_rfkill = -1;  	if (!cfg->base_params->pcie_l1_allowed) {  		/* @@ -3539,9 +3549,16 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,  		} else if (CSR_HW_RF_ID_TYPE_CHIP_ID(trans->hw_rf_id) ==  			   CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_GF)) {  			trans->cfg = &iwlax210_2ax_cfg_so_gf_a0; +		} else if (CSR_HW_RF_ID_TYPE_CHIP_ID(trans->hw_rf_id) == +			   CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_GF4)) { +			trans->cfg = &iwlax210_2ax_cfg_so_gf4_a0;  		}  	} else if (cfg == &iwl_ax101_cfg_qu_hr) {  		if (CSR_HW_RF_ID_TYPE_CHIP_ID(trans->hw_rf_id) == +		    CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_HR) && +		    trans->hw_rev == CSR_HW_REV_TYPE_QNJ_B0) { +			trans->cfg = &iwl22000_2ax_cfg_qnj_hr_b0; +		} else if (CSR_HW_RF_ID_TYPE_CHIP_ID(trans->hw_rf_id) ==  		    CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_HR)) {  			trans->cfg = &iwl_ax101_cfg_qu_hr;  		} else if (CSR_HW_RF_ID_TYPE_CHIP_ID(trans->hw_rf_id) == @@ -3560,7 +3577,7 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,  		}  	} else if (CSR_HW_RF_ID_TYPE_CHIP_ID(trans->hw_rf_id) ==  		   CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_HR) && -		   (trans->cfg != &iwl22260_2ax_cfg || +		   (trans->cfg != &iwl_ax200_cfg_cc ||  		    trans->hw_rev == CSR_HW_REV_TYPE_QNJ_B0)) {  		u32 hw_status; @@ -3637,22 +3654,29 @@ out_no_pci:  	return ERR_PTR(ret);  } -void iwl_trans_sync_nmi(struct iwl_trans *trans) +void iwl_trans_pcie_sync_nmi(struct iwl_trans *trans)  { +	struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);  	unsigned long timeout = jiffies + IWL_TRANS_NMI_TIMEOUT; +	u32 inta_addr, sw_err_bit; + +	if (trans_pcie->msix_enabled) { +		inta_addr = CSR_MSIX_HW_INT_CAUSES_AD; +		sw_err_bit = MSIX_HW_INT_CAUSES_REG_SW_ERR; +	} else { +		inta_addr = CSR_INT; +		sw_err_bit = CSR_INT_BIT_SW_ERR; +	}  	iwl_disable_interrupts(trans);  	iwl_force_nmi(trans);  	while (time_after(timeout, jiffies)) { -		u32 inta_hw = iwl_read32(trans, -					 CSR_MSIX_HW_INT_CAUSES_AD); +		u32 inta_hw = iwl_read32(trans, inta_addr);  		/* Error detected by uCode */ -		if (inta_hw & MSIX_HW_INT_CAUSES_REG_SW_ERR) { +		if (inta_hw & sw_err_bit) {  			/* Clear causes register */ -			iwl_write32(trans, CSR_MSIX_HW_INT_CAUSES_AD, -				    inta_hw & -				    MSIX_HW_INT_CAUSES_REG_SW_ERR); +			iwl_write32(trans, inta_addr, inta_hw & sw_err_bit);  			break;  		} |