Merge tag 'icc-6.7-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/djakov/icc...
[linux-2.6-microblaze.git] / drivers / net / ethernet / marvell / octeontx2 / af / mcs.c
index 492baa0..c1775bd 100644 (file)
@@ -117,7 +117,7 @@ void mcs_get_rx_secy_stats(struct mcs *mcs, struct mcs_secy_stats *stats, int id
        reg = MCSX_CSE_RX_MEM_SLAVE_INPKTSSECYTAGGEDCTLX(id);
        stats->pkt_tagged_ctl_cnt = mcs_reg_read(mcs, reg);
 
-       reg = MCSX_CSE_RX_MEM_SLAVE_INPKTSSECYUNTAGGEDORNOTAGX(id);
+       reg = MCSX_CSE_RX_MEM_SLAVE_INPKTSSECYUNTAGGEDX(id);
        stats->pkt_untaged_cnt = mcs_reg_read(mcs, reg);
 
        reg = MCSX_CSE_RX_MEM_SLAVE_INPKTSSECYCTLX(id);
@@ -215,7 +215,7 @@ void mcs_get_sc_stats(struct mcs *mcs, struct mcs_sc_stats *stats,
                reg = MCSX_CSE_RX_MEM_SLAVE_INPKTSSCNOTVALIDX(id);
                stats->pkt_notvalid_cnt = mcs_reg_read(mcs, reg);
 
-               reg = MCSX_CSE_RX_MEM_SLAVE_INPKTSSCUNCHECKEDOROKX(id);
+               reg = MCSX_CSE_RX_MEM_SLAVE_INPKTSSCUNCHECKEDX(id);
                stats->pkt_unchecked_cnt = mcs_reg_read(mcs, reg);
 
                if (mcs->hw->mcs_blks > 1) {
@@ -473,6 +473,8 @@ void mcs_flowid_entry_write(struct mcs *mcs, u64 *data, u64 *mask, int flow_id,
                for (reg_id = 0; reg_id < 4; reg_id++) {
                        reg = MCSX_CPM_RX_SLAVE_FLOWID_TCAM_DATAX(reg_id, flow_id);
                        mcs_reg_write(mcs, reg, data[reg_id]);
+               }
+               for (reg_id = 0; reg_id < 4; reg_id++) {
                        reg = MCSX_CPM_RX_SLAVE_FLOWID_TCAM_MASKX(reg_id, flow_id);
                        mcs_reg_write(mcs, reg, mask[reg_id]);
                }
@@ -480,6 +482,8 @@ void mcs_flowid_entry_write(struct mcs *mcs, u64 *data, u64 *mask, int flow_id,
                for (reg_id = 0; reg_id < 4; reg_id++) {
                        reg = MCSX_CPM_TX_SLAVE_FLOWID_TCAM_DATAX(reg_id, flow_id);
                        mcs_reg_write(mcs, reg, data[reg_id]);
+               }
+               for (reg_id = 0; reg_id < 4; reg_id++) {
                        reg = MCSX_CPM_TX_SLAVE_FLOWID_TCAM_MASKX(reg_id, flow_id);
                        mcs_reg_write(mcs, reg, mask[reg_id]);
                }
@@ -932,60 +936,42 @@ static void mcs_tx_misc_intr_handler(struct mcs *mcs, u64 intr)
        mcs_add_intr_wq_entry(mcs, &event);
 }
 
-static void mcs_bbe_intr_handler(struct mcs *mcs, u64 intr, enum mcs_direction dir)
+void cn10kb_mcs_bbe_intr_handler(struct mcs *mcs, u64 intr,
+                                enum mcs_direction dir)
 {
-       struct mcs_intr_event event = { 0 };
-       int i;
+       u64 val, reg;
+       int lmac;
 
-       if (!(intr & MCS_BBE_INT_MASK))
+       if (!(intr & 0x6ULL))
                return;
 
-       event.mcs_id = mcs->mcs_id;
-       event.pcifunc = mcs->pf_map[0];
+       if (intr & BIT_ULL(1))
+               reg = (dir == MCS_RX) ? MCSX_BBE_RX_SLAVE_DFIFO_OVERFLOW_0 :
+                                       MCSX_BBE_TX_SLAVE_DFIFO_OVERFLOW_0;
+       else
+               reg = (dir == MCS_RX) ? MCSX_BBE_RX_SLAVE_PLFIFO_OVERFLOW_0 :
+                                       MCSX_BBE_TX_SLAVE_PLFIFO_OVERFLOW_0;
+       val = mcs_reg_read(mcs, reg);
 
-       for (i = 0; i < MCS_MAX_BBE_INT; i++) {
-               if (!(intr & BIT_ULL(i)))
+       /* policy/data over flow occurred */
+       for (lmac = 0; lmac < mcs->hw->lmac_cnt; lmac++) {
+               if (!(val & BIT_ULL(lmac)))
                        continue;
-
-               /* Lower nibble denotes data fifo overflow interrupts and
-                * upper nibble indicates policy fifo overflow interrupts.
-                */
-               if (intr & 0xFULL)
-                       event.intr_mask = (dir == MCS_RX) ?
-                                         MCS_BBE_RX_DFIFO_OVERFLOW_INT :
-                                         MCS_BBE_TX_DFIFO_OVERFLOW_INT;
-               else
-                       event.intr_mask = (dir == MCS_RX) ?
-                                         MCS_BBE_RX_PLFIFO_OVERFLOW_INT :
-                                         MCS_BBE_TX_PLFIFO_OVERFLOW_INT;
-
-               /* Notify the lmac_id info which ran into BBE fatal error */
-               event.lmac_id = i & 0x3ULL;
-               mcs_add_intr_wq_entry(mcs, &event);
+               dev_warn(mcs->dev, "BEE:Policy or data overflow occurred on lmac:%d\n", lmac);
        }
 }
 
-static void mcs_pab_intr_handler(struct mcs *mcs, u64 intr, enum mcs_direction dir)
+void cn10kb_mcs_pab_intr_handler(struct mcs *mcs, u64 intr,
+                                enum mcs_direction dir)
 {
-       struct mcs_intr_event event = { 0 };
-       int i;
+       int lmac;
 
-       if (!(intr & MCS_PAB_INT_MASK))
+       if (!(intr & 0xFFFFFULL))
                return;
 
-       event.mcs_id = mcs->mcs_id;
-       event.pcifunc = mcs->pf_map[0];
-
-       for (i = 0; i < MCS_MAX_PAB_INT; i++) {
-               if (!(intr & BIT_ULL(i)))
-                       continue;
-
-               event.intr_mask = (dir == MCS_RX) ? MCS_PAB_RX_CHAN_OVERFLOW_INT :
-                                 MCS_PAB_TX_CHAN_OVERFLOW_INT;
-
-               /* Notify the lmac_id info which ran into PAB fatal error */
-               event.lmac_id = i;
-               mcs_add_intr_wq_entry(mcs, &event);
+       for (lmac = 0; lmac < mcs->hw->lmac_cnt; lmac++) {
+               if (intr & BIT_ULL(lmac))
+                       dev_warn(mcs->dev, "PAB: overflow occurred on lmac:%d\n", lmac);
        }
 }
 
@@ -994,9 +980,8 @@ static irqreturn_t mcs_ip_intr_handler(int irq, void *mcs_irq)
        struct mcs *mcs = (struct mcs *)mcs_irq;
        u64 intr, cpm_intr, bbe_intr, pab_intr;
 
-       /* Disable and clear the interrupt */
+       /* Disable  the interrupt */
        mcs_reg_write(mcs, MCSX_IP_INT_ENA_W1C, BIT_ULL(0));
-       mcs_reg_write(mcs, MCSX_IP_INT, BIT_ULL(0));
 
        /* Check which block has interrupt*/
        intr = mcs_reg_read(mcs, MCSX_TOP_SLAVE_INT_SUM);
@@ -1043,7 +1028,7 @@ static irqreturn_t mcs_ip_intr_handler(int irq, void *mcs_irq)
        /* BBE RX */
        if (intr & MCS_BBE_RX_INT_ENA) {
                bbe_intr = mcs_reg_read(mcs, MCSX_BBE_RX_SLAVE_BBE_INT);
-               mcs_bbe_intr_handler(mcs, bbe_intr, MCS_RX);
+               mcs->mcs_ops->mcs_bbe_intr_handler(mcs, bbe_intr, MCS_RX);
 
                /* Clear the interrupt */
                mcs_reg_write(mcs, MCSX_BBE_RX_SLAVE_BBE_INT_INTR_RW, 0);
@@ -1053,7 +1038,7 @@ static irqreturn_t mcs_ip_intr_handler(int irq, void *mcs_irq)
        /* BBE TX */
        if (intr & MCS_BBE_TX_INT_ENA) {
                bbe_intr = mcs_reg_read(mcs, MCSX_BBE_TX_SLAVE_BBE_INT);
-               mcs_bbe_intr_handler(mcs, bbe_intr, MCS_TX);
+               mcs->mcs_ops->mcs_bbe_intr_handler(mcs, bbe_intr, MCS_TX);
 
                /* Clear the interrupt */
                mcs_reg_write(mcs, MCSX_BBE_TX_SLAVE_BBE_INT_INTR_RW, 0);
@@ -1063,7 +1048,7 @@ static irqreturn_t mcs_ip_intr_handler(int irq, void *mcs_irq)
        /* PAB RX */
        if (intr & MCS_PAB_RX_INT_ENA) {
                pab_intr = mcs_reg_read(mcs, MCSX_PAB_RX_SLAVE_PAB_INT);
-               mcs_pab_intr_handler(mcs, pab_intr, MCS_RX);
+               mcs->mcs_ops->mcs_pab_intr_handler(mcs, pab_intr, MCS_RX);
 
                /* Clear the interrupt */
                mcs_reg_write(mcs, MCSX_PAB_RX_SLAVE_PAB_INT_INTR_RW, 0);
@@ -1073,14 +1058,15 @@ static irqreturn_t mcs_ip_intr_handler(int irq, void *mcs_irq)
        /* PAB TX */
        if (intr & MCS_PAB_TX_INT_ENA) {
                pab_intr = mcs_reg_read(mcs, MCSX_PAB_TX_SLAVE_PAB_INT);
-               mcs_pab_intr_handler(mcs, pab_intr, MCS_TX);
+               mcs->mcs_ops->mcs_pab_intr_handler(mcs, pab_intr, MCS_TX);
 
                /* Clear the interrupt */
                mcs_reg_write(mcs, MCSX_PAB_TX_SLAVE_PAB_INT_INTR_RW, 0);
                mcs_reg_write(mcs, MCSX_PAB_TX_SLAVE_PAB_INT, pab_intr);
        }
 
-       /* Enable the interrupt */
+       /* Clear and enable the interrupt */
+       mcs_reg_write(mcs, MCSX_IP_INT, BIT_ULL(0));
        mcs_reg_write(mcs, MCSX_IP_INT_ENA_W1S, BIT_ULL(0));
 
        return IRQ_HANDLED;
@@ -1162,7 +1148,7 @@ static int mcs_register_interrupts(struct mcs *mcs)
                return ret;
        }
 
-       ret = request_irq(pci_irq_vector(mcs->pdev, MCS_INT_VEC_IP),
+       ret = request_irq(pci_irq_vector(mcs->pdev, mcs->hw->ip_vec),
                          mcs_ip_intr_handler, 0, "MCS_IP", mcs);
        if (ret) {
                dev_err(mcs->dev, "MCS IP irq registration failed\n");
@@ -1181,11 +1167,11 @@ static int mcs_register_interrupts(struct mcs *mcs)
        mcs_reg_write(mcs, MCSX_CPM_TX_SLAVE_TX_INT_ENB, 0x7ULL);
        mcs_reg_write(mcs, MCSX_CPM_RX_SLAVE_RX_INT_ENB, 0x7FULL);
 
-       mcs_reg_write(mcs, MCSX_BBE_RX_SLAVE_BBE_INT_ENB, 0xff);
-       mcs_reg_write(mcs, MCSX_BBE_TX_SLAVE_BBE_INT_ENB, 0xff);
+       mcs_reg_write(mcs, MCSX_BBE_RX_SLAVE_BBE_INT_ENB, 0xFFULL);
+       mcs_reg_write(mcs, MCSX_BBE_TX_SLAVE_BBE_INT_ENB, 0xFFULL);
 
-       mcs_reg_write(mcs, MCSX_PAB_RX_SLAVE_PAB_INT_ENB, 0xff);
-       mcs_reg_write(mcs, MCSX_PAB_TX_SLAVE_PAB_INT_ENB, 0xff);
+       mcs_reg_write(mcs, MCSX_PAB_RX_SLAVE_PAB_INT_ENB, 0xFFFFFULL);
+       mcs_reg_write(mcs, MCSX_PAB_TX_SLAVE_PAB_INT_ENB, 0xFFFFFULL);
 
        mcs->tx_sa_active = alloc_mem(mcs, mcs->hw->sc_entries);
        if (!mcs->tx_sa_active) {
@@ -1196,7 +1182,7 @@ static int mcs_register_interrupts(struct mcs *mcs)
        return ret;
 
 free_irq:
-       free_irq(pci_irq_vector(mcs->pdev, MCS_INT_VEC_IP), mcs);
+       free_irq(pci_irq_vector(mcs->pdev, mcs->hw->ip_vec), mcs);
 exit:
        pci_free_irq_vectors(mcs->pdev);
        mcs->num_vec = 0;
@@ -1233,6 +1219,17 @@ struct mcs *mcs_get_pdata(int mcs_id)
        return NULL;
 }
 
+bool is_mcs_bypass(int mcs_id)
+{
+       struct mcs *mcs_dev;
+
+       list_for_each_entry(mcs_dev, &mcs_list, mcs_list) {
+               if (mcs_dev->mcs_id == mcs_id)
+                       return mcs_dev->bypass;
+       }
+       return true;
+}
+
 void mcs_set_port_cfg(struct mcs *mcs, struct mcs_port_cfg_set_req *req)
 {
        u64 val = 0;
@@ -1450,7 +1447,7 @@ static int mcs_x2p_calibration(struct mcs *mcs)
        return err;
 }
 
-static void mcs_set_external_bypass(struct mcs *mcs, u8 bypass)
+static void mcs_set_external_bypass(struct mcs *mcs, bool bypass)
 {
        u64 val;
 
@@ -1461,6 +1458,7 @@ static void mcs_set_external_bypass(struct mcs *mcs, u8 bypass)
        else
                val &= ~BIT_ULL(6);
        mcs_reg_write(mcs, MCSX_MIL_GLOBAL, val);
+       mcs->bypass = bypass;
 }
 
 static void mcs_global_cfg(struct mcs *mcs)
@@ -1493,6 +1491,7 @@ void cn10kb_mcs_set_hw_capabilities(struct mcs *mcs)
        hw->lmac_cnt = 20;              /* lmacs/ports per mcs block */
        hw->mcs_x2p_intf = 5;           /* x2p clabration intf */
        hw->mcs_blks = 1;               /* MCS blocks */
+       hw->ip_vec = MCS_CN10KB_INT_VEC_IP; /* IP vector */
 }
 
 static struct mcs_ops cn10kb_mcs_ops = {
@@ -1501,6 +1500,8 @@ static struct mcs_ops cn10kb_mcs_ops = {
        .mcs_tx_sa_mem_map_write        = cn10kb_mcs_tx_sa_mem_map_write,
        .mcs_rx_sa_mem_map_write        = cn10kb_mcs_rx_sa_mem_map_write,
        .mcs_flowid_secy_map            = cn10kb_mcs_flowid_secy_map,
+       .mcs_bbe_intr_handler           = cn10kb_mcs_bbe_intr_handler,
+       .mcs_pab_intr_handler           = cn10kb_mcs_pab_intr_handler,
 };
 
 static int mcs_probe(struct pci_dev *pdev, const struct pci_device_id *id)
@@ -1601,7 +1602,7 @@ static void mcs_remove(struct pci_dev *pdev)
 
        /* Set MCS to external bypass */
        mcs_set_external_bypass(mcs, true);
-       free_irq(pci_irq_vector(pdev, MCS_INT_VEC_IP), mcs);
+       free_irq(pci_irq_vector(pdev, mcs->hw->ip_vec), mcs);
        pci_free_irq_vectors(pdev);
        pci_release_regions(pdev);
        pci_disable_device(pdev);