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

Commit 826d8010 authored by Dave Olson's avatar Dave Olson Committed by Roland Dreier
Browse files

IB/ipath: Enable 4KB MTU



Enable use of 4KB MTU.  Since the driver uses more pinned memory for
receive buffers when the 4KB MTU is enabled, whether or not the fabric
supports that MTU, add a "mtu4096" module parameter that can be used to
limit the MTU to 2KB when it is known that 4KB MTUs can't be used
anyway.

Signed-off-by: default avatarDave Olson <dave.olson@qlogic.com>
Signed-off-by: default avatarRoland Dreier <rolandd@cisco.com>
parent 5d1ce03d
Loading
Loading
Loading
Loading
+15 −16
Original line number Diff line number Diff line
@@ -73,6 +73,10 @@ module_param_named(debug, ipath_debug, uint, S_IWUSR | S_IRUGO);
MODULE_PARM_DESC(debug, "mask for debug prints");
EXPORT_SYMBOL_GPL(ipath_debug);

unsigned ipath_mtu4096 = 1; /* max 4KB IB mtu by default, if supported */
module_param_named(mtu4096, ipath_mtu4096, uint, S_IRUGO);
MODULE_PARM_DESC(mtu4096, "enable MTU of 4096 bytes, if supported");

MODULE_LICENSE("GPL");
MODULE_AUTHOR("QLogic <support@pathscale.com>");
MODULE_DESCRIPTION("QLogic InfiniPath driver");
@@ -1800,7 +1804,7 @@ int ipath_set_mtu(struct ipath_devdata *dd, u16 arg)
	 * piosize).  We check that it's one of the valid IB sizes.
	 */
	if (arg != 256 && arg != 512 && arg != 1024 && arg != 2048 &&
	    arg != 4096) {
	    (arg != 4096 || !ipath_mtu4096)) {
		ipath_dbg("Trying to set invalid mtu %u, failing\n", arg);
		ret = -EINVAL;
		goto bail;
@@ -1816,6 +1820,8 @@ int ipath_set_mtu(struct ipath_devdata *dd, u16 arg)
	if (arg >= (piosize - IPATH_PIO_MAXIBHDR)) {
		/* Only if it's not the initial value (or reset to it) */
		if (piosize != dd->ipath_init_ibmaxlen) {
			if (arg > piosize && arg <= dd->ipath_init_ibmaxlen)
				piosize = dd->ipath_init_ibmaxlen;
			dd->ipath_ibmaxlen = piosize;
			changed = 1;
		}
@@ -1829,24 +1835,17 @@ int ipath_set_mtu(struct ipath_devdata *dd, u16 arg)
	}

	if (changed) {
		u64 ibc = dd->ipath_ibcctrl, ibdw;
		/*
		 * set the IBC maxpktlength to the size of our pio
		 * buffers in words
		 * update our housekeeping variables, and set IBC max
		 * size, same as init code; max IBC is max we allow in
		 * buffer, less the qword pbc, plus 1 for ICRC, in dwords
		 */
		u64 ibc = dd->ipath_ibcctrl;
		dd->ipath_ibmaxlen = piosize - 2 * sizeof(u32);
		ibdw = (dd->ipath_ibmaxlen >> 2) + 1;
		ibc &= ~(INFINIPATH_IBCC_MAXPKTLEN_MASK <<
			 INFINIPATH_IBCC_MAXPKTLEN_SHIFT);

		piosize = piosize - 2 * sizeof(u32);    /* ignore pbc */
		dd->ipath_ibmaxlen = piosize;
		piosize /= sizeof(u32); /* in words */
		/*
		 * for ICRC, which we only send in diag test pkt mode, and
		 * we don't need to worry about that for mtu
		 */
		piosize += 1;

		ibc |= piosize << INFINIPATH_IBCC_MAXPKTLEN_SHIFT;
			 dd->ibcc_mpl_shift);
		ibc |= ibdw << dd->ibcc_mpl_shift;
		dd->ipath_ibcctrl = ibc;
		ipath_write_kreg(dd, dd->ipath_kregs->kr_ibcctrl,
				 dd->ipath_ibcctrl);
+6 −1
Original line number Diff line number Diff line
@@ -219,7 +219,12 @@ static int ipath_get_base_info(struct file *fp,
	kinfo->spi_pioalign = dd->ipath_palign;

	kinfo->spi_qpair = IPATH_KD_QP;
	kinfo->spi_piosize = dd->ipath_ibmaxlen;
	/*
	 * user mode PIO buffers are always 2KB, even when 4KB can
	 * be received, and sent via the kernel; this is ibmaxlen
	 * for 2K MTU.
	 */
	kinfo->spi_piosize = dd->ipath_piosize2k - 2 * sizeof(u32);
	kinfo->spi_mtu = dd->ipath_ibmaxlen;	/* maxlen, not ibmtu */
	kinfo->spi_port = pd->port_port;
	kinfo->spi_subport = subport_fp(fp);
+3 −7
Original line number Diff line number Diff line
@@ -1441,17 +1441,13 @@ static int ipath_pe_early_init(struct ipath_devdata *dd)
	dd->ipath_egrtidbase = (u64 __iomem *)
		((char __iomem *) dd->ipath_kregbase + dd->ipath_rcvegrbase);

	/*
	 * To truly support a 4KB MTU (for usermode), we need to
	 * bump this to a larger value.  For now, we use them for
	 * the kernel only.
	 */
	dd->ipath_rcvegrbufsize = 2048;
	dd->ipath_rcvegrbufsize = ipath_mtu4096 ? 4096 : 2048;
	/*
	 * the min() check here is currently a nop, but it may not always
	 * be, depending on just how we do ipath_rcvegrbufsize
	 */
	dd->ipath_ibmaxlen = min(dd->ipath_piosize2k,
	dd->ipath_ibmaxlen = min(ipath_mtu4096 ? dd->ipath_piosize4k :
				 dd->ipath_piosize2k,
				 dd->ipath_rcvegrbufsize +
				 (dd->ipath_rcvhdrentsize << 2));
	dd->ipath_init_ibmaxlen = dd->ipath_ibmaxlen;
+8 −22
Original line number Diff line number Diff line
@@ -155,24 +155,13 @@ static int bringup_link(struct ipath_devdata *dd)
			 dd->ipath_control);

	/*
	 * Note that prior to try 14 or 15 of IB, the credit scaling
	 * wasn't working, because it was swapped for writes with the
	 * 1 bit default linkstate field
	 * set initial max size pkt IBC will send, including ICRC; it's the
	 * PIO buffer size in dwords, less 1; also see ipath_set_mtu()
	 */
	val = (dd->ipath_ibmaxlen >> 2) + 1;
	ibc = val << dd->ibcc_mpl_shift;

	/* ignore pbc and align word */
	val = dd->ipath_piosize2k - 2 * sizeof(u32);
	/*
	 * for ICRC, which we only send in diag test pkt mode, and we
	 * don't need to worry about that for mtu
	 */
	val += 1;
	/*
	 * Set the IBC maxpktlength to the size of our pio buffers the
	 * maxpktlength is in words.  This is *not* the IB data MTU.
	 */
	ibc = (val / sizeof(u32)) << INFINIPATH_IBCC_MAXPKTLEN_SHIFT;
	/* in KB */
	/* flowcontrolwatermark is in units of KBytes */
	ibc |= 0x5ULL << INFINIPATH_IBCC_FLOWCTRLWATERMARK_SHIFT;
	/*
	 * How often flowctrl sent.  More or less in usecs; balance against
@@ -295,12 +284,9 @@ static int init_chip_first(struct ipath_devdata *dd,
	val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_sendpiosize);
	dd->ipath_piosize2k = val & ~0U;
	dd->ipath_piosize4k = val >> 32;
	/*
	 * Note: the chips support a maximum MTU of 4096, but the driver
	 * hasn't implemented this feature yet, so set the initial value
	 * to 2048.
	 */
	dd->ipath_ibmtu = 2048;
	if (dd->ipath_piosize4k == 0 && ipath_mtu4096)
		ipath_mtu4096 = 0; /* 4KB not supported by this chip */
	dd->ipath_ibmtu = ipath_mtu4096 ? 4096 : 2048;
	val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_sendpiobufcnt);
	dd->ipath_piobcnt2k = val & ~0U;
	dd->ipath_piobcnt4k = val >> 32;
+1 −0
Original line number Diff line number Diff line
@@ -1066,6 +1066,7 @@ dma_addr_t ipath_map_single(struct pci_dev *, void *, size_t, int);
#endif

extern unsigned ipath_debug; /* debugging bit mask */
extern unsigned ipath_mtu4096;

#define IPATH_MAX_PARITY_ATTEMPTS 10000 /* max times to try recovery */

Loading