This patch adds implementation of handling IRQ
of other receiver's receive cancellation request.

Signed-off-by: Taku Izumi <izumi.t...@jp.fujitsu.com>
---
 drivers/net/fjes/fjes_main.c | 79 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 79 insertions(+)

diff --git a/drivers/net/fjes/fjes_main.c b/drivers/net/fjes/fjes_main.c
index faaf2ed..b21ad68 100644
--- a/drivers/net/fjes/fjes_main.c
+++ b/drivers/net/fjes/fjes_main.c
@@ -822,6 +822,75 @@ static int fjes_vlan_rx_kill_vid(struct net_device *netdev,
        return 0;
 }
 
+static void fjes_txrx_stop_req_irq(struct fjes_adapter *adapter,
+                                  int src_epid)
+{
+       struct fjes_hw *hw = &adapter->hw;
+       enum ep_partner_status status;
+
+       status = fjes_hw_get_partner_ep_status(hw, src_epid);
+       switch (status) {
+       case EP_PARTNER_UNSHARE:
+       default:
+               break;
+       case EP_PARTNER_COMPLETE:
+               break;
+       case EP_PARTNER_WAITING:
+               if (src_epid < hw->my_epid) {
+                       hw->ep_shm_info[src_epid].tx.info->v1i.rx_status |=
+                               FJES_RX_STOP_REQ_DONE;
+
+                       clear_bit(src_epid, &hw->txrx_stop_req_bit);
+                       set_bit(src_epid, &adapter->unshare_watch_bitmask);
+
+                       if (!work_pending(&adapter->unshare_watch_task))
+                               queue_work(adapter->control_wq,
+                                          &adapter->unshare_watch_task);
+               }
+               break;
+       case EP_PARTNER_SHARED:
+               if (hw->ep_shm_info[src_epid].rx.info->v1i.rx_status
+                               & FJES_RX_STOP_REQ_REQUEST) {
+                       set_bit(src_epid, &hw->epstop_req_bit);
+                       if (!work_pending(&hw->epstop_task))
+                               queue_work(adapter->control_wq,
+                                          &hw->epstop_task);
+               }
+               break;
+       }
+}
+
+static void fjes_stop_req_irq(struct fjes_adapter *adapter, int src_epid)
+{
+       struct fjes_hw *hw = &adapter->hw;
+       enum ep_partner_status status;
+
+       set_bit(src_epid, &hw->hw_info.buffer_unshare_reserve_bit);
+
+       status = fjes_hw_get_partner_ep_status(hw, src_epid);
+       switch (status) {
+       case EP_PARTNER_WAITING:
+               hw->ep_shm_info[src_epid].tx.info->v1i.rx_status |=
+                               FJES_RX_STOP_REQ_DONE;
+               clear_bit(src_epid, &hw->txrx_stop_req_bit);
+               /* fall through */
+       case EP_PARTNER_UNSHARE:
+       case EP_PARTNER_COMPLETE:
+       default:
+               set_bit(src_epid, &adapter->unshare_watch_bitmask);
+               if (!work_pending(&adapter->unshare_watch_task))
+                       queue_work(adapter->control_wq,
+                                  &adapter->unshare_watch_task);
+               break;
+       case EP_PARTNER_SHARED:
+               set_bit(src_epid, &hw->epstop_req_bit);
+
+               if (!work_pending(&hw->epstop_task))
+                       queue_work(adapter->control_wq, &hw->epstop_task);
+               break;
+       }
+}
+
 static void fjes_update_zone_irq(struct fjes_adapter *adapter,
                                 int src_epid)
 {
@@ -844,6 +913,16 @@ static irqreturn_t fjes_intr(int irq, void *data)
                if (icr & REG_ICTL_MASK_RX_DATA)
                        fjes_rx_irq(adapter, icr & REG_IS_MASK_EPID);
 
+               if (icr & REG_ICTL_MASK_DEV_STOP_REQ)
+                       fjes_stop_req_irq(adapter, icr & REG_IS_MASK_EPID);
+
+               if (icr & REG_ICTL_MASK_TXRX_STOP_REQ)
+                       fjes_txrx_stop_req_irq(adapter, icr & REG_IS_MASK_EPID);
+
+               if (icr & REG_ICTL_MASK_TXRX_STOP_DONE)
+                       fjes_hw_set_irqmask(hw,
+                                           REG_ICTL_MASK_TXRX_STOP_DONE, true);
+
                if (icr & REG_ICTL_MASK_INFO_UPDATE)
                        fjes_update_zone_irq(adapter, icr & REG_IS_MASK_EPID);
 
-- 
1.8.3.1

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to