From: Palani <palaniappan.ramanat...@lsi.com>

Added support for variable segment size during the mailbox
transmission, depending on the message length.

The spinlock is acquired only when multiple
mailboxes are opened on a single OBDME, to reduce the effect
of spinlocks during single mailbox operation. Further
optimised the mailbox handling.

Signed-off-by: Palani <palaniappan.ramanat...@lsi.com>
---
 drivers/rapidio/devices/lsi/axxia-rio-irq.c | 118 ++++++++++------------------
 1 file changed, 42 insertions(+), 76 deletions(-)

diff --git a/drivers/rapidio/devices/lsi/axxia-rio-irq.c 
b/drivers/rapidio/devices/lsi/axxia-rio-irq.c
index 7f3f56c..0b0d278 100644
--- a/drivers/rapidio/devices/lsi/axxia-rio-irq.c
+++ b/drivers/rapidio/devices/lsi/axxia-rio-irq.c
@@ -900,7 +900,7 @@ static int alloc_msg_descriptors(struct rio_mport *mport,
        }
 
        idesc--;
-       idesc->last = 1;
+       idesc->last = DME_DESC_DW0_NXT_DESC_VALID;
 
        (*desc) = rdesc;
        (*descriptors) = rdescriptors;
@@ -930,7 +930,7 @@ static struct rio_msg_dme *alloc_message_engine(struct 
rio_mport *mport,
        kref_init(&me->kref);
        spin_lock_init(&me->lock);
        me->priv = priv;
-       me->sz = buf_sz;
+       me->sz = 0;/*buf_sz;*/
 
        rc = alloc_msg_descriptors(mport, &me->dres, buf_sz, entries,
                                entries, &me->desc, &me->descriptors);
@@ -991,31 +991,21 @@ ob_dme_restart:
                        dw0 = *((u32 *)DESC_TABLE_W0_MEM(dme, dme->read_idx));
                } else {
                        __rio_local_read_config_32(mport,
-                               DESC_TABLE_W0(dme->dres.start + dme->read_idx),
-                                                                       &dw0);
+                       DESC_TABLE_W0(dme->dres.start + dme->read_idx), &dw0);
                }
                if ((dw0 & DME_DESC_DW0_VALID) &&
                        (dw0 & DME_DESC_DW0_READY_MASK)) {
-                       if (!priv->intern_msg_desc) {
-                               *((u32 *)DESC_TABLE_W0_MEM(dme, dme->read_idx))
+                       *((u32 *)DESC_TABLE_W0_MEM(dme, dme->read_idx))
                                        = dw0 & DME_DESC_DW0_NXT_DESC_VALID;
-                               dw1 = *((u32 *)DESC_TABLE_W1_MEM(dme,
+                       dw1 = *((u32 *)DESC_TABLE_W1_MEM(dme,
                                                dme->read_idx));
-                       } else {
-                               __rio_local_write_config_32(mport,
-                               DESC_TABLE_W0(dme->dres.start + dme->read_idx),
-                                       dw0 & DME_DESC_DW0_NXT_DESC_VALID);
-                               __rio_local_read_config_32(mport,
-                               DESC_TABLE_W1(dme->dres.start + dme->read_idx),
-                                                                       &dw1);
-                       }
                        __dme_dw_dbg(dme, dw0);
+                       dme->read_idx = (dme->read_idx + 1) &
+                                               (dme->entries - 1);
                        mbox = (dw1 >> 2) & 0x3;
                        mb = priv->ob_mbox[mbox];
                        if (mb) {
                                mb->tx_slot = (mb->tx_slot + 1)%(mb->ring_size);
-                               dme->read_idx = (dme->read_idx + 1) &
-                                               (dme->entries - 1);
                                if (mport->outb_msg[mbox].mcback)
                                        mport->outb_msg[mbox].mcback(mport,
                                                        mb->dev_id,
@@ -1062,7 +1052,7 @@ static void ob_dme_irq_handler(struct rio_irq_handler *h)
 /*             if (dme_stat & (OB_DME_STAT_DESC_XFER_CPLT |
                                OB_DME_STAT_DESC_CHAIN_XFER_CPLT))
                        ob_dme_msg_handler(h, dme_no);*/
-               if (dme_stat & OB_DME_STAT_ERROR_MASK) {
+               if (unlikely(dme_stat & OB_DME_STAT_ERROR_MASK)) {
                        if (dme_stat & (OB_DME_STAT_DESC_FETCH_ERR |
                                        OB_DME_STAT_DESC_ERR |
                                        OB_DME_STAT_DESC_UPD_ERR))
@@ -1287,6 +1277,9 @@ static int open_outb_mbox_static(struct rio_mport *mport,
        mb->ring_size = entries;
        mb->tx_slot = 0;
        mb->dev_id = dev_id;
+       me->sz++;
+       mdelay(500); /* Delay added to ensure completion of any pending TX
+                       before Transmission on this Mailbox */
        test_and_set_bit(RIO_MB_MAPPED, &mb->state);
 
        priv->ob_dme_shared[dme_no].ring_size += entries;
@@ -1968,6 +1961,7 @@ void axxia_close_outb_mbox(struct rio_mport *mport, int 
mbox_id)
        mb->dev_id = NULL;
        clear_bit(RIO_MB_MAPPED, &mb->state);
        kfree(mb);
+       me->sz--;
        mutex_unlock(&priv->api_lock);
 
        return;
@@ -1982,12 +1976,7 @@ static inline struct rio_msg_desc *get_ob_desc(struct 
rio_mport *mport,
        int nxt_write_idx = (mb->write_idx + 1) & (mb->entries - 1);
        u32 dw0;
        if (nxt_write_idx != mb->read_idx) {
-               if (!priv->intern_msg_desc)
-                       dw0 = *((u32 *)DESC_TABLE_W0_MEM(mb, desc_num));
-               else
-                       __rio_local_read_config_32(mport,
-                                       DESC_TABLE_W0(mb->dres.start+desc_num),
-                                       &dw0);
+               dw0 = *((u32 *)DESC_TABLE_W0_MEM(mb, desc_num));
                if (!(dw0 & DME_DESC_DW0_VALID))
                        return desc;
                else
@@ -2036,16 +2025,20 @@ int axxia_add_outb_message(struct rio_mport *mport, 
struct rio_dev *rdev,
        struct rio_msg_desc *desc;
        u32 dw2_r, dw2;
        u32 idx;
+       u32 seg;
+       u32 lock = 0;
 
        if (!mb)
                return -EINVAL;
        me = mb->me;
+       if (me->sz > 1)
+               lock = 1;
 
        /* Choose a free descriptor in a critical section */
-       spin_lock(&me->lock);
+       if (lock)
+               spin_lock(&me->lock);
        desc = get_ob_desc(mport, me);
        if (!desc) {
-               spin_unlock(&me->lock);
                rc = -EBUSY;
                goto done;
        }
@@ -2053,8 +2046,7 @@ int axxia_add_outb_message(struct rio_mport *mport, 
struct rio_dev *rdev,
 
        /* Copy and clear rest of buffer */
        if ((u32)buffer & 0xFF) {
-               if (desc->msg_virt == NULL) {
-                       spin_unlock(&me->lock);
+               if (unlikely(desc->msg_virt == NULL)) {
                        rc = -ENXIO;
                        goto done;
                }
@@ -2065,15 +2057,17 @@ int axxia_add_outb_message(struct rio_mport *mport, 
struct rio_dev *rdev,
                DME_DESC_DW0_EN_INT|
                DME_DESC_DW0_VALID;
 #if 0
-       if (desc->desc_no % 2)
+       if (!(me->write_idx % 4))
                dw0 |=  DME_DESC_DW0_EN_INT;
 #endif
-       if (desc->last) /* (Re-)Make ring of descriptors */
-               dw0 |= DME_DESC_DW0_NXT_DESC_VALID;
-
+       dw0 |= desc->last;/*DME_DESC_DW0_NXT_DESC_VALID;*/
+       seg = len;
+       if (seg < 256)
+               seg = 256;
+       seg = roundup_pow_of_two(seg) >> 7;
        dw1 = DME_DESC_DW1_PRIO(flags) |
                DME_DESC_DW1_CRF(flags) |
-               DME_DESC_DW1_SEG_SIZE_256 |
+               (fls(seg)<<18) |
                DME_DESC_DW1_MSGLEN(len) |
                DME_DESC_DW1_XMBOX(mbox_dest) |
                DME_DESC_DW1_MBOX(mbox_dest) |
@@ -2086,31 +2080,26 @@ int axxia_add_outb_message(struct rio_mport *mport, 
struct rio_dev *rdev,
                dw2 = (u32)(virt_to_phys(buffer) >> 8) & 0x3fffffff;
        dw2 = (dw2_r & 0xc0000000) | dw2;
        me->write_idx = (me->write_idx+1) & (me->entries - 1);
-       if (!priv->intern_msg_desc) {
-               *((u32 *)DESC_TABLE_W2_MEM(me, idx)) = dw2;
-               *((u32 *)DESC_TABLE_W1_MEM(me, idx)) = dw1;
+       *((u32 *)DESC_TABLE_W2_MEM(me, idx)) = dw2;
+       *((u32 *)DESC_TABLE_W1_MEM(me, idx)) = dw1;
        AXXIA_RIO_SYSMEM_BARRIER();
-               *((u32 *)DESC_TABLE_W0_MEM(me, idx)) = dw0;
-       } else {
-               __rio_local_write_config_32(mport,
-                               DESC_TABLE_W2(me->dres.start+idx), dw2);
-               __rio_local_write_config_32(mport,
-                               DESC_TABLE_W1(me->dres.start+idx), dw1);
-               __rio_local_write_config_32(mport,
-                               DESC_TABLE_W0(me->dres.start+idx), dw0);
-       }
+       *((u32 *)DESC_TABLE_W0_MEM(me, idx)) = dw0;
 
-       spin_unlock(&me->lock);
-       /* Start / Wake up */
-/*     axxia_local_config_read(priv, RAB_OB_DME_CTRL(me->dme_no), &dme_ctrl);
-       dme_ctrl |= DME_WAKEUP | DME_ENABLE;*/
+       if (lock)
+               spin_unlock(&me->lock);
+       else
+               AXXIA_RIO_SYSMEM_BARRIER();
+       /* Start / Wake up - the stored state is used to avoid a Read */
        axxia_local_config_write(priv, RAB_OB_DME_CTRL(me->dme_no),
                                                        me->dme_ctrl);
 
 #ifdef CONFIG_AXXIA_RIO_STAT
        priv->ob_mbox[mbox_dest]->sent_msg_count++;
 #endif
+       return rc;
 done:
+       if (lock)
+               spin_unlock(&me->lock);
        return rc;
 }
 
@@ -2308,31 +2297,15 @@ void *axxia_get_inb_message(struct rio_mport *mport, 
int mbox, int letter,
                idx = me->read_idx;
                buf = NULL;
                *sz = 0;
-               if (!priv->intern_msg_desc) {
-                       dw0 = *((u32 *)DESC_TABLE_W0_MEM(me, idx));
-                       dw1 = *((u32 *)DESC_TABLE_W1_MEM(me, idx));
-               } else {
-                       __rio_local_read_config_32(mport,
-                                          DESC_TABLE_W0(me->dres.start+idx),
-                                          &dw0);
-                       __rio_local_read_config_32(mport,
-                                          DESC_TABLE_W1(me->dres.start+idx),
-                                          &dw1);
-               }
+               dw0 = *((u32 *)DESC_TABLE_W0_MEM(me, idx));
+               dw1 = *((u32 *)DESC_TABLE_W1_MEM(me, idx));
                __dme_dw_dbg(me, dw0);
                if ((dw0 & DME_DESC_DW0_ERROR_MASK) &&
                    (dw0 & DME_DESC_DW0_VALID)) {
-                       if (!priv->intern_msg_desc) {
-                               *((u32 *)DESC_TABLE_W0_MEM(me,
-                                       idx)) =
+                       *((u32 *)DESC_TABLE_W0_MEM(me, idx)) =
                                        (dw0 & 0xff) | DME_DESC_DW0_VALID;
 /*TODO Need to check here: May need to keep it valid for nocopy case
  *Proper Error Handling and add_inb_buffer Required */
-                       } else {
-                               __rio_local_write_config_32(mport,
-                                       DESC_TABLE_W0(me->dres.start+idx),
-                                       (dw0 & 0xff) | DME_DESC_DW0_VALID);
-                       }
                        pr_err("Desc error %d\n", dw0);
                        me->read_idx = (me->read_idx + 1) & (me->entries - 1);
                        num_proc++;
@@ -2353,15 +2326,8 @@ void *axxia_get_inb_message(struct rio_mport *mport, int 
mbox, int letter,
                                memcpy(buf, desc->msg_virt, buf_sz);
                        }
                        mb->virt_buffer[letter][me->read_idx] = NULL;
-                       if (!priv->intern_msg_desc) {
-                               *((u32 *)DESC_TABLE_W0_MEM(me,
-                                       idx)) =
+                       *((u32 *)DESC_TABLE_W0_MEM(me, idx)) =
                                        (dw0 & 0xfe);/*DME_DESC_INVALIDATE*/
-                       } else {
-                               __rio_local_write_config_32(mport,
-                                       DESC_TABLE_W0(me->dres.start+idx),
-                                       (dw0 & 0xfe));/*DME_DESC_INVALIDATE*/
-                       }
                        *sz = buf_sz;
 
                        me->read_idx = (me->read_idx + 1) & (me->entries - 1);
-- 
1.8.1.4

-- 
_______________________________________________
linux-yocto mailing list
linux-yocto@yoctoproject.org
https://lists.yoctoproject.org/listinfo/linux-yocto

Reply via email to