Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bb917144 authored by Arthur Jones's avatar Arthur Jones Committed by Roland Dreier
Browse files

IB/ipath: Misc changes to prepare for IB7220 introduction



The patch adds a number of minor changes to support newer HCAs:
 - New send buffer control bits
 - New error condition bits
 - Locking and initialization changes
 - More send buffers

Signed-off-by: default avatarRalph Campbell <ralph.campbell@qlogic.com>
Signed-off-by: default avatarRoland Dreier <rolandd@cisco.com>
parent 8babfa4f
Loading
Loading
Loading
Loading
+48 −13
Original line number Original line Diff line number Diff line
@@ -89,6 +89,10 @@ MODULE_LICENSE("GPL");
MODULE_AUTHOR("QLogic <support@qlogic.com>");
MODULE_AUTHOR("QLogic <support@qlogic.com>");
MODULE_DESCRIPTION("QLogic InfiniPath driver");
MODULE_DESCRIPTION("QLogic InfiniPath driver");


/*
 * Table to translate the LINKTRAININGSTATE portion of
 * IBCStatus to a human-readable form.
 */
const char *ipath_ibcstatus_str[] = {
const char *ipath_ibcstatus_str[] = {
	"Disabled",
	"Disabled",
	"LinkUp",
	"LinkUp",
@@ -103,9 +107,20 @@ const char *ipath_ibcstatus_str[] = {
	"CfgWaitRmt",
	"CfgWaitRmt",
	"CfgIdle",
	"CfgIdle",
	"RecovRetrain",
	"RecovRetrain",
	"LState0xD",		/* unused */
	"CfgTxRevLane",		/* unused before IBA7220 */
	"RecovWaitRmt",
	"RecovWaitRmt",
	"RecovIdle",
	"RecovIdle",
	/* below were added for IBA7220 */
	"CfgEnhanced",
	"CfgTest",
	"CfgWaitRmtTest",
	"CfgWaitCfgEnhanced",
	"SendTS_T",
	"SendTstIdles",
	"RcvTS_T",
	"SendTst_TS1s",
	"LTState18", "LTState19", "LTState1A", "LTState1B",
	"LTState1C", "LTState1D", "LTState1E", "LTState1F"
};
};


static void __devexit ipath_remove_one(struct pci_dev *);
static void __devexit ipath_remove_one(struct pci_dev *);
@@ -333,7 +348,14 @@ static void ipath_verify_pioperf(struct ipath_devdata *dd)


	ipath_disable_armlaunch(dd);
	ipath_disable_armlaunch(dd);


	writeq(0, piobuf); /* length 0, no dwords actually sent */
	/*
	 * length 0, no dwords actually sent, and mark as VL15
	 * on chips where that may matter (due to IB flowcontrol)
	 */
	if ((dd->ipath_flags & IPATH_HAS_PBC_CNT))
		writeq(1UL << 63, piobuf);
	else
		writeq(0, piobuf);
	ipath_flush_wc();
	ipath_flush_wc();


	/*
	/*
@@ -374,6 +396,7 @@ static int __devinit ipath_init_one(struct pci_dev *pdev,
	struct ipath_devdata *dd;
	struct ipath_devdata *dd;
	unsigned long long addr;
	unsigned long long addr;
	u32 bar0 = 0, bar1 = 0;
	u32 bar0 = 0, bar1 = 0;
	u8 rev;


	dd = ipath_alloc_devdata(pdev);
	dd = ipath_alloc_devdata(pdev);
	if (IS_ERR(dd)) {
	if (IS_ERR(dd)) {
@@ -405,7 +428,7 @@ static int __devinit ipath_init_one(struct pci_dev *pdev,
	}
	}
	addr = pci_resource_start(pdev, 0);
	addr = pci_resource_start(pdev, 0);
	len = pci_resource_len(pdev, 0);
	len = pci_resource_len(pdev, 0);
	ipath_cdbg(VERBOSE, "regbase (0) %llx len %d pdev->irq %d, vend %x/%x "
	ipath_cdbg(VERBOSE, "regbase (0) %llx len %d irq %d, vend %x/%x "
		   "driver_data %lx\n", addr, len, pdev->irq, ent->vendor,
		   "driver_data %lx\n", addr, len, pdev->irq, ent->vendor,
		   ent->device, ent->driver_data);
		   ent->device, ent->driver_data);


@@ -530,7 +553,13 @@ static int __devinit ipath_init_one(struct pci_dev *pdev,
		goto bail_regions;
		goto bail_regions;
	}
	}


	dd->ipath_pcirev = pdev->revision;
	ret = pci_read_config_byte(pdev, PCI_REVISION_ID, &rev);
	if (ret) {
		ipath_dev_err(dd, "Failed to read PCI revision ID unit "
			      "%u: err %d\n", dd->ipath_unit, -ret);
		goto bail_regions;	/* shouldn't ever happen */
	}
	dd->ipath_pcirev = rev;


#if defined(__powerpc__)
#if defined(__powerpc__)
	/* There isn't a generic way to specify writethrough mappings */
	/* There isn't a generic way to specify writethrough mappings */
@@ -553,14 +582,6 @@ static int __devinit ipath_init_one(struct pci_dev *pdev,
	ipath_cdbg(VERBOSE, "mapped io addr %llx to kregbase %p\n",
	ipath_cdbg(VERBOSE, "mapped io addr %llx to kregbase %p\n",
		   addr, dd->ipath_kregbase);
		   addr, dd->ipath_kregbase);


	/*
	 * clear ipath_flags here instead of in ipath_init_chip as it is set
	 * by ipath_setup_htconfig.
	 */
	dd->ipath_flags = 0;
	dd->ipath_lli_counter = 0;
	dd->ipath_lli_errors = 0;

	if (dd->ipath_f_bus(dd, pdev))
	if (dd->ipath_f_bus(dd, pdev))
		ipath_dev_err(dd, "Failed to setup config space; "
		ipath_dev_err(dd, "Failed to setup config space; "
			      "continuing anyway\n");
			      "continuing anyway\n");
@@ -649,6 +670,10 @@ static void __devexit cleanup_device(struct ipath_devdata *dd)
		ipath_disable_wc(dd);
		ipath_disable_wc(dd);
	}
	}


	if (dd->ipath_spectriggerhit)
		dev_info(&dd->pcidev->dev, "%lu special trigger hits\n",
			 dd->ipath_spectriggerhit);

	if (dd->ipath_pioavailregs_dma) {
	if (dd->ipath_pioavailregs_dma) {
		dma_free_coherent(&dd->pcidev->dev, PAGE_SIZE,
		dma_free_coherent(&dd->pcidev->dev, PAGE_SIZE,
				  (void *) dd->ipath_pioavailregs_dma,
				  (void *) dd->ipath_pioavailregs_dma,
@@ -857,7 +882,7 @@ int ipath_wait_linkstate(struct ipath_devdata *dd, u32 state, int msecs)
			   (unsigned long long) ipath_read_kreg64(
			   (unsigned long long) ipath_read_kreg64(
				   dd, dd->ipath_kregs->kr_ibcctrl),
				   dd, dd->ipath_kregs->kr_ibcctrl),
			   (unsigned long long) val,
			   (unsigned long long) val,
			   ipath_ibcstatus_str[val & 0xf]);
			   ipath_ibcstatus_str[val & dd->ibcs_lts_mask]);
	}
	}
	return (dd->ipath_flags & state) ? 0 : -ETIMEDOUT;
	return (dd->ipath_flags & state) ? 0 : -ETIMEDOUT;
}
}
@@ -906,6 +931,8 @@ int ipath_decode_err(char *buf, size_t blen, ipath_err_t err)
		strlcat(buf, "rbadversion ", blen);
		strlcat(buf, "rbadversion ", blen);
	if (err & INFINIPATH_E_RHDR)
	if (err & INFINIPATH_E_RHDR)
		strlcat(buf, "rhdr ", blen);
		strlcat(buf, "rhdr ", blen);
	if (err & INFINIPATH_E_SENDSPECIALTRIGGER)
		strlcat(buf, "sendspecialtrigger ", blen);
	if (err & INFINIPATH_E_RLONGPKTLEN)
	if (err & INFINIPATH_E_RLONGPKTLEN)
		strlcat(buf, "rlongpktlen ", blen);
		strlcat(buf, "rlongpktlen ", blen);
	if (err & INFINIPATH_E_RMAXPKTLEN)
	if (err & INFINIPATH_E_RMAXPKTLEN)
@@ -948,6 +975,8 @@ int ipath_decode_err(char *buf, size_t blen, ipath_err_t err)
		strlcat(buf, "hardware ", blen);
		strlcat(buf, "hardware ", blen);
	if (err & INFINIPATH_E_RESET)
	if (err & INFINIPATH_E_RESET)
		strlcat(buf, "reset ", blen);
		strlcat(buf, "reset ", blen);
	if (err & INFINIPATH_E_INVALIDEEPCMD)
		strlcat(buf, "invalideepromcmd ", blen);
done:
done:
	return iserr;
	return iserr;
}
}
@@ -1701,6 +1730,10 @@ int ipath_create_rcvhdrq(struct ipath_devdata *dd,
 */
 */
void ipath_cancel_sends(struct ipath_devdata *dd, int restore_sendctrl)
void ipath_cancel_sends(struct ipath_devdata *dd, int restore_sendctrl)
{
{
	if (dd->ipath_flags & IPATH_IB_AUTONEG_INPROG) {
		ipath_cdbg(VERBOSE, "Ignore while in autonegotiation\n");
		goto bail;
	}
	ipath_dbg("Cancelling all in-progress send buffers\n");
	ipath_dbg("Cancelling all in-progress send buffers\n");


	/* skip armlaunch errs for a while */
	/* skip armlaunch errs for a while */
@@ -1721,6 +1754,7 @@ void ipath_cancel_sends(struct ipath_devdata *dd, int restore_sendctrl)


	/* and again, be sure all have hit the chip */
	/* and again, be sure all have hit the chip */
	ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch);
	ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch);
bail:;
}
}


/*
/*
@@ -2282,6 +2316,7 @@ static int __init infinipath_init(void)
	 */
	 */
	idr_init(&unit_table);
	idr_init(&unit_table);
	if (!idr_pre_get(&unit_table, GFP_KERNEL)) {
	if (!idr_pre_get(&unit_table, GFP_KERNEL)) {
		printk(KERN_ERR IPATH_DRV_NAME ": idr_pre_get() failed\n");
		ret = -ENOMEM;
		ret = -ENOMEM;
		goto bail;
		goto bail;
	}
	}
+1 −1
Original line number Original line Diff line number Diff line
@@ -2074,7 +2074,7 @@ static int ipath_close(struct inode *in, struct file *fp)
			pd->port_rcvnowait = pd->port_pionowait = 0;
			pd->port_rcvnowait = pd->port_pionowait = 0;
	}
	}
	if (pd->port_flag) {
	if (pd->port_flag) {
		ipath_dbg("port %u port_flag still set to 0x%lx\n",
		ipath_cdbg(PROC, "port %u port_flag set: 0x%lx\n",
			  pd->port_port, pd->port_flag);
			  pd->port_port, pd->port_flag);
		pd->port_flag = 0;
		pd->port_flag = 0;
	}
	}
+16 −8
Original line number Original line Diff line number Diff line
@@ -230,6 +230,15 @@ static int init_chip_first(struct ipath_devdata *dd)
	int ret = 0;
	int ret = 0;
	u64 val;
	u64 val;


	spin_lock_init(&dd->ipath_kernel_tid_lock);
	spin_lock_init(&dd->ipath_user_tid_lock);
	spin_lock_init(&dd->ipath_sendctrl_lock);
	spin_lock_init(&dd->ipath_sdma_lock);
	spin_lock_init(&dd->ipath_gpio_lock);
	spin_lock_init(&dd->ipath_eep_st_lock);
	spin_lock_init(&dd->ipath_sdepb_lock);
	mutex_init(&dd->ipath_eep_lock);

	/*
	/*
	 * skip cfgports stuff because we are not allocating memory,
	 * skip cfgports stuff because we are not allocating memory,
	 * and we don't want problems if the portcnt changed due to
	 * and we don't want problems if the portcnt changed due to
@@ -319,12 +328,6 @@ static int init_chip_first(struct ipath_devdata *dd)
	else ipath_dbg("%u 2k piobufs @ %p\n",
	else ipath_dbg("%u 2k piobufs @ %p\n",
		       dd->ipath_piobcnt2k, dd->ipath_pio2kbase);
		       dd->ipath_piobcnt2k, dd->ipath_pio2kbase);


	spin_lock_init(&dd->ipath_user_tid_lock);
	spin_lock_init(&dd->ipath_sendctrl_lock);
	spin_lock_init(&dd->ipath_gpio_lock);
	spin_lock_init(&dd->ipath_eep_st_lock);
	mutex_init(&dd->ipath_eep_lock);

done:
done:
	return ret;
	return ret;
}
}
@@ -553,7 +556,7 @@ static void enable_chip(struct ipath_devdata *dd, int reinit)


static int init_housekeeping(struct ipath_devdata *dd, int reinit)
static int init_housekeeping(struct ipath_devdata *dd, int reinit)
{
{
	char boardn[32];
	char boardn[40];
	int ret = 0;
	int ret = 0;


	/*
	/*
@@ -800,7 +803,12 @@ int ipath_init_chip(struct ipath_devdata *dd, int reinit)
			dd->ipath_pioupd_thresh = kpiobufs;
			dd->ipath_pioupd_thresh = kpiobufs;
	}
	}


	dd->ipath_f_early_init(dd);
	ret = dd->ipath_f_early_init(dd);
	if (ret) {
		ipath_dev_err(dd, "Early initialization failure\n");
		goto done;
	}

	/*
	/*
	 * Cancel any possible active sends from early driver load.
	 * Cancel any possible active sends from early driver load.
	 * Follows early_init because some chips have to initialize
	 * Follows early_init because some chips have to initialize
+7 −4
Original line number Original line Diff line number Diff line
@@ -73,7 +73,7 @@ static void ipath_clrpiobuf(struct ipath_devdata *dd, u32 pnum)
 * If rewrite is true, and bits are set in the sendbufferror registers,
 * If rewrite is true, and bits are set in the sendbufferror registers,
 * we'll write to the buffer, for error recovery on parity errors.
 * we'll write to the buffer, for error recovery on parity errors.
 */
 */
static void ipath_disarm_senderrbufs(struct ipath_devdata *dd, int rewrite)
void ipath_disarm_senderrbufs(struct ipath_devdata *dd, int rewrite)
{
{
	u32 piobcnt;
	u32 piobcnt;
	unsigned long sbuf[4];
	unsigned long sbuf[4];
@@ -87,12 +87,14 @@ static void ipath_disarm_senderrbufs(struct ipath_devdata *dd, int rewrite)
		dd, dd->ipath_kregs->kr_sendbuffererror);
		dd, dd->ipath_kregs->kr_sendbuffererror);
	sbuf[1] = ipath_read_kreg64(
	sbuf[1] = ipath_read_kreg64(
		dd, dd->ipath_kregs->kr_sendbuffererror + 1);
		dd, dd->ipath_kregs->kr_sendbuffererror + 1);
	if (piobcnt > 128) {
	if (piobcnt > 128)
		sbuf[2] = ipath_read_kreg64(
		sbuf[2] = ipath_read_kreg64(
			dd, dd->ipath_kregs->kr_sendbuffererror + 2);
			dd, dd->ipath_kregs->kr_sendbuffererror + 2);
	if (piobcnt > 192)
		sbuf[3] = ipath_read_kreg64(
		sbuf[3] = ipath_read_kreg64(
			dd, dd->ipath_kregs->kr_sendbuffererror + 3);
			dd, dd->ipath_kregs->kr_sendbuffererror + 3);
	}
	else
		sbuf[3] = 0;


	if (sbuf[0] || sbuf[1] || (piobcnt > 128 && (sbuf[2] || sbuf[3]))) {
	if (sbuf[0] || sbuf[1] || (piobcnt > 128 && (sbuf[2] || sbuf[3]))) {
		int i;
		int i;
@@ -365,7 +367,8 @@ static void handle_e_ibstatuschanged(struct ipath_devdata *dd,
		 */
		 */
		if (lastlts == INFINIPATH_IBCS_LT_STATE_POLLACTIVE ||
		if (lastlts == INFINIPATH_IBCS_LT_STATE_POLLACTIVE ||
		    lastlts == INFINIPATH_IBCS_LT_STATE_POLLQUIET) {
		    lastlts == INFINIPATH_IBCS_LT_STATE_POLLQUIET) {
			if (++dd->ipath_ibpollcnt == 40) {
			if (!(dd->ipath_flags & IPATH_IB_AUTONEG_INPROG) &&
			     (++dd->ipath_ibpollcnt == 40)) {
				dd->ipath_flags |= IPATH_NOCABLE;
				dd->ipath_flags |= IPATH_NOCABLE;
				*dd->ipath_statusp |=
				*dd->ipath_statusp |=
					IPATH_STATUS_IB_NOCABLE;
					IPATH_STATUS_IB_NOCABLE;
+1 −0
Original line number Original line Diff line number Diff line
@@ -1010,6 +1010,7 @@ void ipath_get_eeprom_info(struct ipath_devdata *);
int ipath_update_eeprom_log(struct ipath_devdata *dd);
int ipath_update_eeprom_log(struct ipath_devdata *dd);
void ipath_inc_eeprom_err(struct ipath_devdata *dd, u32 eidx, u32 incr);
void ipath_inc_eeprom_err(struct ipath_devdata *dd, u32 eidx, u32 incr);
u64 ipath_snap_cntr(struct ipath_devdata *, ipath_creg);
u64 ipath_snap_cntr(struct ipath_devdata *, ipath_creg);
void ipath_disarm_senderrbufs(struct ipath_devdata *, int);
void ipath_force_pio_avail_update(struct ipath_devdata *);
void ipath_force_pio_avail_update(struct ipath_devdata *);
void signal_ib_event(struct ipath_devdata *dd, enum ib_event_type ev);
void signal_ib_event(struct ipath_devdata *dd, enum ib_event_type ev);


Loading