]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - drivers/infiniband/hw/cxgb4/device.c
Merge branch 'master' into tk71
[mv-sheeva.git] / drivers / infiniband / hw / cxgb4 / device.c
index 9bbf491d5d9ee087e2081ef024e7ebdd0d2c23aa..54fbc1118abe0eb2e2e4592ab0724e1e72ca0f5a 100644 (file)
@@ -49,29 +49,33 @@ static DEFINE_MUTEX(dev_mutex);
 
 static struct dentry *c4iw_debugfs_root;
 
-struct debugfs_qp_data {
+struct c4iw_debugfs_data {
        struct c4iw_dev *devp;
        char *buf;
        int bufsize;
        int pos;
 };
 
-static int count_qps(int id, void *p, void *data)
+static int count_idrs(int id, void *p, void *data)
 {
-       struct c4iw_qp *qp = p;
        int *countp = data;
 
-       if (id != qp->wq.sq.qid)
-               return 0;
-
        *countp = *countp + 1;
        return 0;
 }
 
-static int dump_qps(int id, void *p, void *data)
+static ssize_t debugfs_read(struct file *file, char __user *buf, size_t count,
+                           loff_t *ppos)
+{
+       struct c4iw_debugfs_data *d = file->private_data;
+
+       return simple_read_from_buffer(buf, count, ppos, d->buf, d->pos);
+}
+
+static int dump_qp(int id, void *p, void *data)
 {
        struct c4iw_qp *qp = p;
-       struct debugfs_qp_data *qpd = data;
+       struct c4iw_debugfs_data *qpd = data;
        int space;
        int cc;
 
@@ -101,7 +105,7 @@ static int dump_qps(int id, void *p, void *data)
 
 static int qp_release(struct inode *inode, struct file *file)
 {
-       struct debugfs_qp_data *qpd = file->private_data;
+       struct c4iw_debugfs_data *qpd = file->private_data;
        if (!qpd) {
                printk(KERN_INFO "%s null qpd?\n", __func__);
                return 0;
@@ -113,7 +117,7 @@ static int qp_release(struct inode *inode, struct file *file)
 
 static int qp_open(struct inode *inode, struct file *file)
 {
-       struct debugfs_qp_data *qpd;
+       struct c4iw_debugfs_data *qpd;
        int ret = 0;
        int count = 1;
 
@@ -126,7 +130,7 @@ static int qp_open(struct inode *inode, struct file *file)
        qpd->pos = 0;
 
        spin_lock_irq(&qpd->devp->lock);
-       idr_for_each(&qpd->devp->qpidr, count_qps, &count);
+       idr_for_each(&qpd->devp->qpidr, count_idrs, &count);
        spin_unlock_irq(&qpd->devp->lock);
 
        qpd->bufsize = count * 128;
@@ -137,7 +141,7 @@ static int qp_open(struct inode *inode, struct file *file)
        }
 
        spin_lock_irq(&qpd->devp->lock);
-       idr_for_each(&qpd->devp->qpidr, dump_qps, qpd);
+       idr_for_each(&qpd->devp->qpidr, dump_qp, qpd);
        spin_unlock_irq(&qpd->devp->lock);
 
        qpd->buf[qpd->pos++] = 0;
@@ -149,43 +153,86 @@ out:
        return ret;
 }
 
-static ssize_t qp_read(struct file *file, char __user *buf, size_t count,
-                       loff_t *ppos)
+static const struct file_operations qp_debugfs_fops = {
+       .owner   = THIS_MODULE,
+       .open    = qp_open,
+       .release = qp_release,
+       .read    = debugfs_read,
+       .llseek  = default_llseek,
+};
+
+static int dump_stag(int id, void *p, void *data)
 {
-       struct debugfs_qp_data *qpd = file->private_data;
-       loff_t pos = *ppos;
-       loff_t avail = qpd->pos;
+       struct c4iw_debugfs_data *stagd = data;
+       int space;
+       int cc;
 
-       if (pos < 0)
-               return -EINVAL;
-       if (pos >= avail)
+       space = stagd->bufsize - stagd->pos - 1;
+       if (space == 0)
+               return 1;
+
+       cc = snprintf(stagd->buf + stagd->pos, space, "0x%x\n", id<<8);
+       if (cc < space)
+               stagd->pos += cc;
+       return 0;
+}
+
+static int stag_release(struct inode *inode, struct file *file)
+{
+       struct c4iw_debugfs_data *stagd = file->private_data;
+       if (!stagd) {
+               printk(KERN_INFO "%s null stagd?\n", __func__);
                return 0;
-       if (count > avail - pos)
-               count = avail - pos;
+       }
+       kfree(stagd->buf);
+       kfree(stagd);
+       return 0;
+}
 
-       while (count) {
-               size_t len = 0;
+static int stag_open(struct inode *inode, struct file *file)
+{
+       struct c4iw_debugfs_data *stagd;
+       int ret = 0;
+       int count = 1;
 
-               len = min((int)count, (int)qpd->pos - (int)pos);
-               if (copy_to_user(buf, qpd->buf + pos, len))
-                       return -EFAULT;
-               if (len == 0)
-                       return -EINVAL;
+       stagd = kmalloc(sizeof *stagd, GFP_KERNEL);
+       if (!stagd) {
+               ret = -ENOMEM;
+               goto out;
+       }
+       stagd->devp = inode->i_private;
+       stagd->pos = 0;
+
+       spin_lock_irq(&stagd->devp->lock);
+       idr_for_each(&stagd->devp->mmidr, count_idrs, &count);
+       spin_unlock_irq(&stagd->devp->lock);
 
-               buf += len;
-               pos += len;
-               count -= len;
+       stagd->bufsize = count * sizeof("0x12345678\n");
+       stagd->buf = kmalloc(stagd->bufsize, GFP_KERNEL);
+       if (!stagd->buf) {
+               ret = -ENOMEM;
+               goto err1;
        }
-       count = pos - *ppos;
-       *ppos = pos;
-       return count;
+
+       spin_lock_irq(&stagd->devp->lock);
+       idr_for_each(&stagd->devp->mmidr, dump_stag, stagd);
+       spin_unlock_irq(&stagd->devp->lock);
+
+       stagd->buf[stagd->pos++] = 0;
+       file->private_data = stagd;
+       goto out;
+err1:
+       kfree(stagd);
+out:
+       return ret;
 }
 
-static const struct file_operations qp_debugfs_fops = {
+static const struct file_operations stag_debugfs_fops = {
        .owner   = THIS_MODULE,
-       .open    = qp_open,
-       .release = qp_release,
-       .read    = qp_read,
+       .open    = stag_open,
+       .release = stag_release,
+       .read    = debugfs_read,
+       .llseek  = default_llseek,
 };
 
 static int setup_debugfs(struct c4iw_dev *devp)
@@ -199,6 +246,11 @@ static int setup_debugfs(struct c4iw_dev *devp)
                                 (void *)devp, &qp_debugfs_fops);
        if (de && de->d_inode)
                de->d_inode->i_size = 4096;
+
+       de = debugfs_create_file("stags", S_IWUSR, devp->debugfs_root,
+                                (void *)devp, &stag_debugfs_fops);
+       if (de && de->d_inode)
+               de->d_inode->i_size = 4096;
        return 0;
 }
 
@@ -290,7 +342,14 @@ static int c4iw_rdev_open(struct c4iw_rdev *rdev)
                printk(KERN_ERR MOD "error %d initializing rqt pool\n", err);
                goto err3;
        }
+       err = c4iw_ocqp_pool_create(rdev);
+       if (err) {
+               printk(KERN_ERR MOD "error %d initializing ocqp pool\n", err);
+               goto err4;
+       }
        return 0;
+err4:
+       c4iw_rqtpool_destroy(rdev);
 err3:
        c4iw_pblpool_destroy(rdev);
 err2:
@@ -317,6 +376,7 @@ static void c4iw_remove(struct c4iw_dev *dev)
        idr_destroy(&dev->cqidr);
        idr_destroy(&dev->qpidr);
        idr_destroy(&dev->mmidr);
+       iounmap(dev->rdev.oc_mw_kva);
        ib_dealloc_device(&dev->ibdev);
 }
 
@@ -332,6 +392,17 @@ static struct c4iw_dev *c4iw_alloc(const struct cxgb4_lld_info *infop)
        }
        devp->rdev.lldi = *infop;
 
+       devp->rdev.oc_mw_pa = pci_resource_start(devp->rdev.lldi.pdev, 2) +
+               (pci_resource_len(devp->rdev.lldi.pdev, 2) -
+                roundup_pow_of_two(devp->rdev.lldi.vr->ocq.size));
+       devp->rdev.oc_mw_kva = ioremap_wc(devp->rdev.oc_mw_pa,
+                                              devp->rdev.lldi.vr->ocq.size);
+
+       printk(KERN_INFO MOD "ocq memory: "
+              "hw_start 0x%x size %u mw_pa 0x%lx mw_kva %p\n",
+              devp->rdev.lldi.vr->ocq.start, devp->rdev.lldi.vr->ocq.size,
+              devp->rdev.oc_mw_pa, devp->rdev.oc_mw_kva);
+
        mutex_lock(&dev_mutex);
 
        ret = c4iw_rdev_open(&devp->rdev);
@@ -383,46 +454,6 @@ out:
        return dev;
 }
 
-static struct sk_buff *t4_pktgl_to_skb(const struct pkt_gl *gl,
-                                      unsigned int skb_len,
-                                      unsigned int pull_len)
-{
-       struct sk_buff *skb;
-       struct skb_shared_info *ssi;
-
-       if (gl->tot_len <= 512) {
-               skb = alloc_skb(gl->tot_len, GFP_ATOMIC);
-               if (unlikely(!skb))
-                       goto out;
-               __skb_put(skb, gl->tot_len);
-               skb_copy_to_linear_data(skb, gl->va, gl->tot_len);
-       } else {
-               skb = alloc_skb(skb_len, GFP_ATOMIC);
-               if (unlikely(!skb))
-                       goto out;
-               __skb_put(skb, pull_len);
-               skb_copy_to_linear_data(skb, gl->va, pull_len);
-
-               ssi = skb_shinfo(skb);
-               ssi->frags[0].page = gl->frags[0].page;
-               ssi->frags[0].page_offset = gl->frags[0].page_offset + pull_len;
-               ssi->frags[0].size = gl->frags[0].size - pull_len;
-               if (gl->nfrags > 1)
-                       memcpy(&ssi->frags[1], &gl->frags[1],
-                              (gl->nfrags - 1) * sizeof(skb_frag_t));
-               ssi->nr_frags = gl->nfrags;
-
-               skb->len = gl->tot_len;
-               skb->data_len = skb->len - pull_len;
-               skb->truesize += skb->data_len;
-
-               /* Get a reference for the last page, we don't own it */
-               get_page(gl->frags[gl->nfrags - 1].page);
-       }
-out:
-       return skb;
-}
-
 static int c4iw_uld_rx_handler(void *handle, const __be64 *rsp,
                        const struct pkt_gl *gl)
 {
@@ -447,7 +478,7 @@ static int c4iw_uld_rx_handler(void *handle, const __be64 *rsp,
                c4iw_ev_handler(dev, qid);
                return 0;
        } else {
-               skb = t4_pktgl_to_skb(gl, 128, 128);
+               skb = cxgb4_pktgl_to_skb(gl, 128, 128);
                if (unlikely(!skb))
                        goto nomem;
        }