fjes: raise_intr_rxdata_task
This patch add raise_intr_rxdata_task. Extended Socket Network Device is shared memory based, so someone's transmission denotes other's reception. In order to notify receivers, sender has to raise interruption of receivers. raise_intr_rxdata_task does this work. Signed-off-by: Taku Izumi <izumi.taku@jp.fujitsu.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
9acf51cbf7
commit
b772b9dc63
|
@ -50,6 +50,10 @@ struct fjes_adapter {
|
|||
|
||||
bool irq_registered;
|
||||
|
||||
struct workqueue_struct *txrx_wq;
|
||||
|
||||
struct work_struct raise_intr_rxdata_task;
|
||||
|
||||
struct fjes_hw hw;
|
||||
};
|
||||
|
||||
|
|
|
@ -52,6 +52,7 @@ static int fjes_close(struct net_device *);
|
|||
static int fjes_setup_resources(struct fjes_adapter *);
|
||||
static void fjes_free_resources(struct fjes_adapter *);
|
||||
static netdev_tx_t fjes_xmit_frame(struct sk_buff *, struct net_device *);
|
||||
static void fjes_raise_intr_rxdata_task(struct work_struct *);
|
||||
static irqreturn_t fjes_intr(int, void*);
|
||||
|
||||
static int fjes_acpi_add(struct acpi_device *);
|
||||
|
@ -276,6 +277,8 @@ static int fjes_close(struct net_device *netdev)
|
|||
|
||||
fjes_free_irq(adapter);
|
||||
|
||||
cancel_work_sync(&adapter->raise_intr_rxdata_task);
|
||||
|
||||
fjes_hw_wait_epstop(hw);
|
||||
|
||||
fjes_free_resources(adapter);
|
||||
|
@ -404,6 +407,54 @@ static void fjes_free_resources(struct fjes_adapter *adapter)
|
|||
}
|
||||
}
|
||||
|
||||
static void fjes_raise_intr_rxdata_task(struct work_struct *work)
|
||||
{
|
||||
struct fjes_adapter *adapter = container_of(work,
|
||||
struct fjes_adapter, raise_intr_rxdata_task);
|
||||
struct fjes_hw *hw = &adapter->hw;
|
||||
enum ep_partner_status pstatus;
|
||||
int max_epid, my_epid, epid;
|
||||
|
||||
my_epid = hw->my_epid;
|
||||
max_epid = hw->max_epid;
|
||||
|
||||
for (epid = 0; epid < max_epid; epid++)
|
||||
hw->ep_shm_info[epid].tx_status_work = 0;
|
||||
|
||||
for (epid = 0; epid < max_epid; epid++) {
|
||||
if (epid == my_epid)
|
||||
continue;
|
||||
|
||||
pstatus = fjes_hw_get_partner_ep_status(hw, epid);
|
||||
if (pstatus == EP_PARTNER_SHARED) {
|
||||
hw->ep_shm_info[epid].tx_status_work =
|
||||
hw->ep_shm_info[epid].tx.info->v1i.tx_status;
|
||||
|
||||
if (hw->ep_shm_info[epid].tx_status_work ==
|
||||
FJES_TX_DELAY_SEND_PENDING) {
|
||||
hw->ep_shm_info[epid].tx.info->v1i.tx_status =
|
||||
FJES_TX_DELAY_SEND_NONE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (epid = 0; epid < max_epid; epid++) {
|
||||
if (epid == my_epid)
|
||||
continue;
|
||||
|
||||
pstatus = fjes_hw_get_partner_ep_status(hw, epid);
|
||||
if ((hw->ep_shm_info[epid].tx_status_work ==
|
||||
FJES_TX_DELAY_SEND_PENDING) &&
|
||||
(pstatus == EP_PARTNER_SHARED) &&
|
||||
!(hw->ep_shm_info[epid].rx.info->v1i.rx_status)) {
|
||||
fjes_hw_raise_interrupt(hw, epid,
|
||||
REG_ICTL_MASK_RX_DATA);
|
||||
}
|
||||
}
|
||||
|
||||
usleep_range(500, 1000);
|
||||
}
|
||||
|
||||
static int fjes_tx_send(struct fjes_adapter *adapter, int dest,
|
||||
void *data, size_t len)
|
||||
{
|
||||
|
@ -416,6 +467,9 @@ static int fjes_tx_send(struct fjes_adapter *adapter, int dest,
|
|||
|
||||
adapter->hw.ep_shm_info[dest].tx.info->v1i.tx_status =
|
||||
FJES_TX_DELAY_SEND_PENDING;
|
||||
if (!work_pending(&adapter->raise_intr_rxdata_task))
|
||||
queue_work(adapter->txrx_wq,
|
||||
&adapter->raise_intr_rxdata_task);
|
||||
|
||||
retval = 0;
|
||||
return retval;
|
||||
|
@ -630,6 +684,11 @@ static int fjes_probe(struct platform_device *plat_dev)
|
|||
adapter->force_reset = false;
|
||||
adapter->open_guard = false;
|
||||
|
||||
adapter->txrx_wq = create_workqueue(DRV_NAME "/txrx");
|
||||
|
||||
INIT_WORK(&adapter->raise_intr_rxdata_task,
|
||||
fjes_raise_intr_rxdata_task);
|
||||
|
||||
res = platform_get_resource(plat_dev, IORESOURCE_MEM, 0);
|
||||
hw->hw_res.start = res->start;
|
||||
hw->hw_res.size = res->end - res->start + 1;
|
||||
|
@ -669,6 +728,10 @@ static int fjes_remove(struct platform_device *plat_dev)
|
|||
struct fjes_adapter *adapter = netdev_priv(netdev);
|
||||
struct fjes_hw *hw = &adapter->hw;
|
||||
|
||||
cancel_work_sync(&adapter->raise_intr_rxdata_task);
|
||||
if (adapter->txrx_wq)
|
||||
destroy_workqueue(adapter->txrx_wq);
|
||||
|
||||
unregister_netdev(netdev);
|
||||
|
||||
fjes_hw_exit(hw);
|
||||
|
|
Loading…
Reference in New Issue