IB/ipath: Misc changes to prepare for IB7220 introduction
authorArthur Jones <arthur.jones@qlogic.com>
Thu, 17 Apr 2008 04:09:31 +0000 (21:09 -0700)
committerRoland Dreier <rolandd@cisco.com>
Thu, 17 Apr 2008 04:09:31 +0000 (21:09 -0700)
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: Ralph Campbell <ralph.campbell@qlogic.com>
Signed-off-by: Roland Dreier <rolandd@cisco.com>
drivers/infiniband/hw/ipath/ipath_driver.c
drivers/infiniband/hw/ipath/ipath_file_ops.c
drivers/infiniband/hw/ipath/ipath_init_chip.c
drivers/infiniband/hw/ipath/ipath_intr.c
drivers/infiniband/hw/ipath/ipath_kernel.h
drivers/infiniband/hw/ipath/ipath_sysfs.c

index a3141bbc177a41762afad3b7600796fefd9e355a..c94bc4730b2b80b0d0dec2364451d47022b3cdc7 100644 (file)
@@ -89,6 +89,10 @@ MODULE_LICENSE("GPL");
 MODULE_AUTHOR("QLogic <support@qlogic.com>");
 MODULE_DESCRIPTION("QLogic InfiniPath driver");
 
+/*
+ * Table to translate the LINKTRAININGSTATE portion of
+ * IBCStatus to a human-readable form.
+ */
 const char *ipath_ibcstatus_str[] = {
        "Disabled",
        "LinkUp",
@@ -103,9 +107,20 @@ const char *ipath_ibcstatus_str[] = {
        "CfgWaitRmt",
        "CfgIdle",
        "RecovRetrain",
-       "LState0xD",            /* unused */
+       "CfgTxRevLane",         /* unused before IBA7220 */
        "RecovWaitRmt",
        "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 *);
@@ -333,7 +348,14 @@ static void ipath_verify_pioperf(struct ipath_devdata *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();
 
        /*
@@ -374,6 +396,7 @@ static int __devinit ipath_init_one(struct pci_dev *pdev,
        struct ipath_devdata *dd;
        unsigned long long addr;
        u32 bar0 = 0, bar1 = 0;
+       u8 rev;
 
        dd = ipath_alloc_devdata(pdev);
        if (IS_ERR(dd)) {
@@ -405,7 +428,7 @@ static int __devinit ipath_init_one(struct pci_dev *pdev,
        }
        addr = pci_resource_start(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,
                   ent->device, ent->driver_data);
 
@@ -530,7 +553,13 @@ static int __devinit ipath_init_one(struct pci_dev *pdev,
                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__)
        /* 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",
                   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))
                ipath_dev_err(dd, "Failed to setup config space; "
                              "continuing anyway\n");
@@ -649,6 +670,10 @@ static void __devexit cleanup_device(struct ipath_devdata *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) {
                dma_free_coherent(&dd->pcidev->dev, PAGE_SIZE,
                                  (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(
                                   dd, dd->ipath_kregs->kr_ibcctrl),
                           (unsigned long long) val,
-                          ipath_ibcstatus_str[val & 0xf]);
+                          ipath_ibcstatus_str[val & dd->ibcs_lts_mask]);
        }
        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);
        if (err & INFINIPATH_E_RHDR)
                strlcat(buf, "rhdr ", blen);
+       if (err & INFINIPATH_E_SENDSPECIALTRIGGER)
+               strlcat(buf, "sendspecialtrigger ", blen);
        if (err & INFINIPATH_E_RLONGPKTLEN)
                strlcat(buf, "rlongpktlen ", blen);
        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);
        if (err & INFINIPATH_E_RESET)
                strlcat(buf, "reset ", blen);
+       if (err & INFINIPATH_E_INVALIDEEPCMD)
+               strlcat(buf, "invalideepromcmd ", blen);
 done:
        return iserr;
 }
@@ -1701,6 +1730,10 @@ bail:
  */
 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");
 
        /* 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 */
        ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch);
+bail:;
 }
 
 /*
@@ -2282,6 +2316,7 @@ static int __init infinipath_init(void)
         */
        idr_init(&unit_table);
        if (!idr_pre_get(&unit_table, GFP_KERNEL)) {
+               printk(KERN_ERR IPATH_DRV_NAME ": idr_pre_get() failed\n");
                ret = -ENOMEM;
                goto bail;
        }
index eab69dfdc28e17c3f72d5af3722d4afc4f59c8f5..b87d3126e4dc36aab63e26095adc2d22fc6e2843 100644 (file)
@@ -2074,7 +2074,7 @@ static int ipath_close(struct inode *in, struct file *fp)
                        pd->port_rcvnowait = pd->port_pionowait = 0;
        }
        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_flag = 0;
        }
index 8d8e572baf6ef25159bd2ead48a5ba1ce38befe7..c012e05649b3cecfe6f366a637da3b9800859ab6 100644 (file)
@@ -230,6 +230,15 @@ static int init_chip_first(struct ipath_devdata *dd)
        int ret = 0;
        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,
         * 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",
                       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:
        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)
 {
-       char boardn[32];
+       char boardn[40];
        int ret = 0;
 
        /*
@@ -800,7 +803,12 @@ int ipath_init_chip(struct ipath_devdata *dd, int reinit)
                        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.
         * Follows early_init because some chips have to initialize
index 3bad601fcc9038b925e8c0c61480348134d72949..90b972f6a8401b1df97c56e9fd6d6b9fba00792f 100644 (file)
@@ -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,
  * 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;
        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);
        sbuf[1] = ipath_read_kreg64(
                dd, dd->ipath_kregs->kr_sendbuffererror + 1);
-       if (piobcnt > 128) {
+       if (piobcnt > 128)
                sbuf[2] = ipath_read_kreg64(
                        dd, dd->ipath_kregs->kr_sendbuffererror + 2);
+       if (piobcnt > 192)
                sbuf[3] = ipath_read_kreg64(
                        dd, dd->ipath_kregs->kr_sendbuffererror + 3);
-       }
+       else
+               sbuf[3] = 0;
 
        if (sbuf[0] || sbuf[1] || (piobcnt > 128 && (sbuf[2] || sbuf[3]))) {
                int i;
@@ -365,7 +367,8 @@ static void handle_e_ibstatuschanged(struct ipath_devdata *dd,
                 */
                if (lastlts == INFINIPATH_IBCS_LT_STATE_POLLACTIVE ||
                    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_statusp |=
                                        IPATH_STATUS_IB_NOCABLE;
index feb4f9dbac7777a623c31898982f281d417eea6d..550d46c1aefb5fb32aae01f90325e72fab644fc1 100644 (file)
@@ -1010,6 +1010,7 @@ void ipath_get_eeprom_info(struct ipath_devdata *);
 int ipath_update_eeprom_log(struct ipath_devdata *dd);
 void ipath_inc_eeprom_err(struct ipath_devdata *dd, u32 eidx, u32 incr);
 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 signal_ib_event(struct ipath_devdata *dd, enum ib_event_type ev);
 
index 7961d26404f15eb02295c6c293386735ecbae665..2e6d2aab2600171c75f831339124ec512bd61f50 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/ctype.h>
 
 #include "ipath_kernel.h"
+#include "ipath_verbs.h"
 #include "ipath_common.h"
 
 /**
@@ -320,6 +321,8 @@ static ssize_t store_guid(struct device *dev,
 
        dd->ipath_guid = new_guid;
        dd->ipath_nguid = 1;
+       if (dd->verbs_dev)
+               dd->verbs_dev->ibdev.node_guid = new_guid;
 
        ret = strlen(buf);
        goto bail;
@@ -928,18 +931,17 @@ static ssize_t store_rx_polinv_enb(struct device *dev,
        u16 val;
 
        ret = ipath_parse_ushort(buf, &val);
-       if (ret < 0 || val > 1)
-               goto invalid;
+       if (ret >= 0 && val > 1) {
+               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);
-       if (r < 0) {
+       if (r < 0)
                ret = r;
-               goto bail;
-       }
 
-       goto bail;
-invalid:
-       ipath_dev_err(dd, "attempt to set invalid Rx Polarity (enable)\n");
 bail:
        return ret;
 }