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

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
...@@ -89,6 +89,10 @@ MODULE_LICENSE("GPL"); ...@@ -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[] = { ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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;
} }
......
...@@ -2074,7 +2074,7 @@ static int ipath_close(struct inode *in, struct file *fp) ...@@ -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;
} }
......
...@@ -230,6 +230,15 @@ static int init_chip_first(struct ipath_devdata *dd) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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
......
...@@ -73,7 +73,7 @@ static void ipath_clrpiobuf(struct ipath_devdata *dd, u32 pnum) ...@@ -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) ...@@ -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, ...@@ -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;
......
...@@ -1010,6 +1010,7 @@ void ipath_get_eeprom_info(struct ipath_devdata *); ...@@ -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);
......
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
#include <linux/ctype.h> #include <linux/ctype.h>
#include "ipath_kernel.h" #include "ipath_kernel.h"
#include "ipath_verbs.h"
#include "ipath_common.h" #include "ipath_common.h"
/** /**
...@@ -320,6 +321,8 @@ static ssize_t store_guid(struct device *dev, ...@@ -320,6 +321,8 @@ static ssize_t store_guid(struct device *dev,
dd->ipath_guid = new_guid; dd->ipath_guid = new_guid;
dd->ipath_nguid = 1; dd->ipath_nguid = 1;
if (dd->verbs_dev)
dd->verbs_dev->ibdev.node_guid = new_guid;
ret = strlen(buf); ret = strlen(buf);
goto bail; goto bail;
...@@ -928,18 +931,17 @@ static ssize_t store_rx_polinv_enb(struct device *dev, ...@@ -928,18 +931,17 @@ static ssize_t store_rx_polinv_enb(struct device *dev,
u16 val; u16 val;
ret = ipath_parse_ushort(buf, &val); ret = ipath_parse_ushort(buf, &val);
if (ret < 0 || val > 1) if (ret >= 0 && val > 1) {
goto invalid; ipath_dev_err(dd,
"attempt to set invalid Rx Polarity (enable)\n");
ret = -EINVAL;
goto bail;
}
r = dd->ipath_f_set_ib_cfg(dd, IPATH_IB_CFG_RXPOL_ENB, val); r = dd->ipath_f_set_ib_cfg(dd, IPATH_IB_CFG_RXPOL_ENB, val);
if (r < 0) { if (r < 0)
ret = r; ret = r;
goto bail;
}
goto bail;
invalid:
ipath_dev_err(dd, "attempt to set invalid Rx Polarity (enable)\n");
bail: bail:
return ret; return ret;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment