net: ethernet: ti: cpsw: fix buld break when NET_POLL_CONTROLLER
[firefly-linux-kernel-4.4.55.git] / drivers / net / ethernet / ti / cpsw.c
index c560f9aeb55d691f23c65dae362c18defa1e9e44..a1ba3a0c28da50a5cb922fa8d0cb4a81b85a1f7f 100644 (file)
@@ -610,7 +610,7 @@ static void cpsw_set_promiscious(struct net_device *ndev, bool enable)
 
                        /* Clear all mcast from ALE */
                        cpsw_ale_flush_multicast(ale, ALE_ALL_PORTS <<
-                                                priv->host_port);
+                                                priv->host_port, -1);
 
                        /* Flood All Unicast Packets to Host port */
                        cpsw_ale_control_set(ale, 0, ALE_P0_UNI_FLOOD, 1);
@@ -634,6 +634,12 @@ static void cpsw_set_promiscious(struct net_device *ndev, bool enable)
 static void cpsw_ndo_set_rx_mode(struct net_device *ndev)
 {
        struct cpsw_priv *priv = netdev_priv(ndev);
+       int vid;
+
+       if (priv->data.dual_emac)
+               vid = priv->slaves[priv->emac_port].port_vlan;
+       else
+               vid = priv->data.default_vlan;
 
        if (ndev->flags & IFF_PROMISC) {
                /* Enable promiscuous mode */
@@ -649,7 +655,8 @@ static void cpsw_ndo_set_rx_mode(struct net_device *ndev)
        cpsw_ale_set_allmulti(priv->ale, priv->ndev->flags & IFF_ALLMULTI);
 
        /* Clear all mcast from ALE */
-       cpsw_ale_flush_multicast(priv->ale, ALE_ALL_PORTS << priv->host_port);
+       cpsw_ale_flush_multicast(priv->ale, ALE_ALL_PORTS << priv->host_port,
+                                vid);
 
        if (!netdev_mc_empty(ndev)) {
                struct netdev_hw_addr *ha;
@@ -754,10 +761,26 @@ requeue:
                dev_kfree_skb_any(new_skb);
 }
 
-static irqreturn_t cpsw_interrupt(int irq, void *dev_id)
+static irqreturn_t cpsw_tx_interrupt(int irq, void *dev_id)
+{
+       struct cpsw_priv *priv = dev_id;
+
+       cpdma_ctlr_eoi(priv->dma, CPDMA_EOI_TX);
+       cpdma_chan_process(priv->txch, 128);
+
+       priv = cpsw_get_slave_priv(priv, 1);
+       if (priv)
+               cpdma_chan_process(priv->txch, 128);
+
+       return IRQ_HANDLED;
+}
+
+static irqreturn_t cpsw_rx_interrupt(int irq, void *dev_id)
 {
        struct cpsw_priv *priv = dev_id;
 
+       cpdma_ctlr_eoi(priv->dma, CPDMA_EOI_RX);
+
        cpsw_intr_disable(priv);
        if (priv->irq_enabled == true) {
                cpsw_disable_irq(priv);
@@ -786,8 +809,6 @@ static int cpsw_poll(struct napi_struct *napi, int budget)
        int                     num_tx, num_rx;
 
        num_tx = cpdma_chan_process(priv->txch, 128);
-       if (num_tx)
-               cpdma_ctlr_eoi(priv->dma, CPDMA_EOI_TX);
 
        num_rx = cpdma_chan_process(priv->rxch, budget);
        if (num_rx < budget) {
@@ -795,7 +816,6 @@ static int cpsw_poll(struct napi_struct *napi, int budget)
 
                napi_complete(napi);
                cpsw_intr_enable(priv);
-               cpdma_ctlr_eoi(priv->dma, CPDMA_EOI_RX);
                prim_cpsw = cpsw_get_slave_priv(priv, 0);
                if (prim_cpsw->irq_enabled == false) {
                        prim_cpsw->irq_enabled = true;
@@ -1310,8 +1330,6 @@ static int cpsw_ndo_open(struct net_device *ndev)
        napi_enable(&priv->napi);
        cpdma_ctlr_start(priv->dma);
        cpsw_intr_enable(priv);
-       cpdma_ctlr_eoi(priv->dma, CPDMA_EOI_RX);
-       cpdma_ctlr_eoi(priv->dma, CPDMA_EOI_TX);
 
        prim_cpsw = cpsw_get_slave_priv(priv, 0);
        if (prim_cpsw->irq_enabled == false) {
@@ -1578,9 +1596,6 @@ static void cpsw_ndo_tx_timeout(struct net_device *ndev)
        cpdma_chan_start(priv->txch);
        cpdma_ctlr_int_ctrl(priv->dma, true);
        cpsw_intr_enable(priv);
-       cpdma_ctlr_eoi(priv->dma, CPDMA_EOI_RX);
-       cpdma_ctlr_eoi(priv->dma, CPDMA_EOI_TX);
-
 }
 
 static int cpsw_ndo_set_mac_address(struct net_device *ndev, void *p)
@@ -1617,12 +1632,10 @@ static void cpsw_ndo_poll_controller(struct net_device *ndev)
 
        cpsw_intr_disable(priv);
        cpdma_ctlr_int_ctrl(priv->dma, false);
-       cpsw_interrupt(ndev->irq, priv);
+       cpsw_rx_interrupt(priv->irqs_table[0], priv);
+       cpsw_tx_interrupt(priv->irqs_table[1], priv);
        cpdma_ctlr_int_ctrl(priv->dma, true);
        cpsw_intr_enable(priv);
-       cpdma_ctlr_eoi(priv->dma, CPDMA_EOI_RX);
-       cpdma_ctlr_eoi(priv->dma, CPDMA_EOI_TX);
-
 }
 #endif
 
@@ -2159,7 +2172,8 @@ static int cpsw_probe(struct platform_device *pdev)
        void __iomem                    *ss_regs;
        struct resource                 *res, *ss_res;
        u32 slave_offset, sliver_offset, slave_size;
-       int ret = 0, i, k = 0;
+       int ret = 0, i;
+       int irq;
 
        ndev = alloc_etherdev(sizeof(struct cpsw_priv));
        if (!ndev) {
@@ -2341,31 +2355,47 @@ static int cpsw_probe(struct platform_device *pdev)
                goto clean_dma_ret;
        }
 
-       ndev->irq = platform_get_irq(pdev, 0);
+       ndev->irq = platform_get_irq(pdev, 1);
        if (ndev->irq < 0) {
                dev_err(priv->dev, "error getting irq resource\n");
                ret = -ENOENT;
                goto clean_ale_ret;
        }
 
-       while ((res = platform_get_resource(priv->pdev, IORESOURCE_IRQ, k))) {
-               if (k >= ARRAY_SIZE(priv->irqs_table)) {
-                       ret = -EINVAL;
-                       goto clean_ale_ret;
-               }
+       /* Grab RX and TX IRQs. Note that we also have RX_THRESHOLD and
+        * MISC IRQs which are always kept disabled with this driver so
+        * we will not request them.
+        *
+        * If anyone wants to implement support for those, make sure to
+        * first request and append them to irqs_table array.
+        */
 
-               ret = devm_request_irq(&pdev->dev, res->start, cpsw_interrupt,
-                                      0, dev_name(&pdev->dev), priv);
-               if (ret < 0) {
-                       dev_err(priv->dev, "error attaching irq (%d)\n", ret);
-                       goto clean_ale_ret;
-               }
+       /* RX IRQ */
+       irq = platform_get_irq(pdev, 1);
+       if (irq < 0)
+               goto clean_ale_ret;
 
-               priv->irqs_table[k] = res->start;
-               k++;
+       priv->irqs_table[0] = irq;
+       ret = devm_request_irq(&pdev->dev, irq, cpsw_rx_interrupt,
+                              0, dev_name(&pdev->dev), priv);
+       if (ret < 0) {
+               dev_err(priv->dev, "error attaching irq (%d)\n", ret);
+               goto clean_ale_ret;
        }
 
-       priv->num_irqs = k;
+       /* TX IRQ */
+       irq = platform_get_irq(pdev, 2);
+       if (irq < 0)
+               goto clean_ale_ret;
+
+       priv->irqs_table[1] = irq;
+       ret = devm_request_irq(&pdev->dev, irq, cpsw_tx_interrupt,
+                              0, dev_name(&pdev->dev), priv);
+       if (ret < 0) {
+               dev_err(priv->dev, "error attaching irq (%d)\n", ret);
+               goto clean_ale_ret;
+       }
+       priv->num_irqs = 2;
 
        ndev->features |= NETIF_F_HW_VLAN_CTAG_FILTER;