diff options
| -rw-r--r-- | drivers/ntb/ntb_hw.c | 126 | 
1 files changed, 98 insertions, 28 deletions
| diff --git a/drivers/ntb/ntb_hw.c b/drivers/ntb/ntb_hw.c index 7567452250df..6f1c92182f35 100644 --- a/drivers/ntb/ntb_hw.c +++ b/drivers/ntb/ntb_hw.c @@ -702,24 +702,8 @@ static void bwd_link_poll(struct work_struct *work)  static int ntb_xeon_setup(struct ntb_device *ndev)  { -	int rc; -	u8 val; - -	ndev->hw_type = SNB_HW; - -	rc = pci_read_config_byte(ndev->pdev, NTB_PPD_OFFSET, &val); -	if (rc) -		return rc; - -	if (val & SNB_PPD_DEV_TYPE) -		ndev->dev_type = NTB_DEV_USD; -	else -		ndev->dev_type = NTB_DEV_DSD; - -	switch (val & SNB_PPD_CONN_TYPE) { +	switch (ndev->conn_type) {  	case NTB_CONN_B2B: -		dev_info(&ndev->pdev->dev, "Conn Type = B2B\n"); -		ndev->conn_type = NTB_CONN_B2B;  		ndev->reg_ofs.ldb = ndev->reg_base + SNB_PDOORBELL_OFFSET;  		ndev->reg_ofs.ldb_mask = ndev->reg_base + SNB_PDBMSK_OFFSET;  		ndev->reg_ofs.spad_read = ndev->reg_base + SNB_SPAD_OFFSET; @@ -835,9 +819,6 @@ static int ntb_xeon_setup(struct ntb_device *ndev)  		}  		break;  	case NTB_CONN_RP: -		dev_info(&ndev->pdev->dev, "Conn Type = RP\n"); -		ndev->conn_type = NTB_CONN_RP; -  		if (xeon_errata_workaround) {  			dev_err(&ndev->pdev->dev,  				"NTB-RP disabled due to hardware errata.  To disregard this warning and potentially lock-up the system, add the parameter 'xeon_errata_workaround=0'.\n"); @@ -867,8 +848,6 @@ static int ntb_xeon_setup(struct ntb_device *ndev)  		ndev->limits.max_mw = SNB_MAX_MW;  		break;  	case NTB_CONN_TRANSPARENT: -		dev_info(&ndev->pdev->dev, "Conn Type = TRANSPARENT\n"); -		ndev->conn_type = NTB_CONN_TRANSPARENT;  		/* Scratch pads need to have exclusive access from the primary  		 * or secondary side.  Halve the num spads so that each side can  		 * have an equal amount. @@ -890,10 +869,10 @@ static int ntb_xeon_setup(struct ntb_device *ndev)  		ndev->limits.max_mw = SNB_MAX_MW;  		break;  	default: -		/* Most likely caused by the remote NTB-RP device not being -		 * configured +		/* +		 * we should never hit this. the detect function should've +		 * take cared of everything.  		 */ -		dev_err(&ndev->pdev->dev, "Unknown PPD %x\n", val);  		return -EINVAL;  	} @@ -977,9 +956,6 @@ static int ntb_device_setup(struct ntb_device *ndev)  	if (rc)  		return rc; -	dev_info(&ndev->pdev->dev, "Device Type = %s\n", -		 ndev->dev_type == NTB_DEV_USD ? "USD/DSP" : "DSD/USP"); -  	if (ndev->conn_type == NTB_CONN_B2B)  		/* Enable Bus Master and Memory Space on the secondary side */  		writew(PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER, @@ -1519,6 +1495,96 @@ static void ntb_hw_link_down(struct ntb_device *ndev)  	writel(ntb_cntl, ndev->reg_ofs.lnk_cntl);  } +static int ntb_xeon_detect(struct ntb_device *ndev) +{ +	int rc; +	u8 ppd; + +	ndev->hw_type = SNB_HW; + +	rc = pci_read_config_byte(ndev->pdev, NTB_PPD_OFFSET, &ppd); +	if (rc) +		return -EIO; + +	if (ppd & SNB_PPD_DEV_TYPE) +		ndev->dev_type = NTB_DEV_USD; +	else +		ndev->dev_type = NTB_DEV_DSD; + +	switch (ppd & SNB_PPD_CONN_TYPE) { +	case NTB_CONN_B2B: +		dev_info(&ndev->pdev->dev, "Conn Type = B2B\n"); +		ndev->conn_type = NTB_CONN_B2B; +		break; +	case NTB_CONN_RP: +		dev_info(&ndev->pdev->dev, "Conn Type = RP\n"); +		ndev->conn_type = NTB_CONN_RP; +		break; +	case NTB_CONN_TRANSPARENT: +		dev_info(&ndev->pdev->dev, "Conn Type = TRANSPARENT\n"); +		ndev->conn_type = NTB_CONN_TRANSPARENT; +		/* +		 * This mode is default to USD/DSP. HW does not report +		 * properly in transparent mode as it has no knowledge of +		 * NTB. We will just force correct here. +		 */ +		ndev->dev_type = NTB_DEV_USD; +		break; +	default: +		dev_err(&ndev->pdev->dev, "Unknown PPD %x\n", ppd); +		return -ENODEV; +	} + +	return 0; +} + +static int ntb_atom_detect(struct ntb_device *ndev) +{ +	int rc; +	u32 ppd; + +	ndev->hw_type = BWD_HW; + +	rc = pci_read_config_dword(ndev->pdev, NTB_PPD_OFFSET, &ppd); +	if (rc) +		return rc; + +	switch ((ppd & BWD_PPD_CONN_TYPE) >> 8) { +	case NTB_CONN_B2B: +		dev_info(&ndev->pdev->dev, "Conn Type = B2B\n"); +		ndev->conn_type = NTB_CONN_B2B; +		break; +	case NTB_CONN_RP: +	default: +		dev_err(&ndev->pdev->dev, "Unsupported NTB configuration\n"); +		return -EINVAL; +	} + +	if (ppd & BWD_PPD_DEV_TYPE) +		ndev->dev_type = NTB_DEV_DSD; +	else +		ndev->dev_type = NTB_DEV_USD; + +	return 0; +} + +static int ntb_device_detect(struct ntb_device *ndev) +{ +	int rc; + +	if (is_ntb_xeon(ndev)) +		rc = ntb_xeon_detect(ndev); +	else if (is_ntb_atom(ndev)) +		rc = ntb_atom_detect(ndev); +	else +		rc = -ENODEV; + +	dev_info(&ndev->pdev->dev, "Device Type = %s\n", +		 ndev->dev_type == NTB_DEV_USD ? "USD/DSP" : "DSD/USP"); + +	return 0; +} +  static int ntb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)  {  	struct ntb_device *ndev; @@ -1539,6 +1605,10 @@ static int ntb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)  	pci_set_master(ndev->pdev); +	rc = ntb_device_detect(ndev); +	if (rc) +		goto err; +  	rc = pci_request_selected_regions(pdev, NTB_BAR_MASK, KBUILD_MODNAME);  	if (rc)  		goto err1; | 
