fjes: handle receive cancellation request interrupt
This patch adds implementation of handling IRQ of other receiver's receive cancellation request. Signed-off-by: Taku Izumi <izumi.taku@jp.fujitsu.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
committed by
David S. Miller
parent
b5a9152d99
commit
cb79eaaec4
@ -820,6 +820,74 @@ static int fjes_vlan_rx_kill_vid(struct net_device *netdev,
|
|||||||
return 0;
|
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:
|
||||||
|
case EP_PARTNER_COMPLETE:
|
||||||
|
default:
|
||||||
|
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,
|
static void fjes_update_zone_irq(struct fjes_adapter *adapter,
|
||||||
int src_epid)
|
int src_epid)
|
||||||
{
|
{
|
||||||
@ -842,6 +910,16 @@ static irqreturn_t fjes_intr(int irq, void *data)
|
|||||||
if (icr & REG_ICTL_MASK_RX_DATA)
|
if (icr & REG_ICTL_MASK_RX_DATA)
|
||||||
fjes_rx_irq(adapter, icr & REG_IS_MASK_EPID);
|
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)
|
if (icr & REG_ICTL_MASK_INFO_UPDATE)
|
||||||
fjes_update_zone_irq(adapter, icr & REG_IS_MASK_EPID);
|
fjes_update_zone_irq(adapter, icr & REG_IS_MASK_EPID);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user