aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTaku Izumi <izumi.taku@jp.fujitsu.com>2015-08-21 04:29:25 -0400
committerDavid S. Miller <davem@davemloft.net>2015-08-24 17:06:34 -0400
commitb772b9dc63df0ca8a750ceac9ab356376022f0b6 (patch)
treece11cedba5d6f092c964b875f81738875953edee
parent9acf51cbf73de8952e3df75200d7a7755c16d0f6 (diff)
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>
-rw-r--r--drivers/net/fjes/fjes.h4
-rw-r--r--drivers/net/fjes/fjes_main.c63
2 files changed, 67 insertions, 0 deletions
diff --git a/drivers/net/fjes/fjes.h b/drivers/net/fjes/fjes.h
index 7af4304f5425..8e9899ea1993 100644
--- a/drivers/net/fjes/fjes.h
+++ b/drivers/net/fjes/fjes.h
@@ -50,6 +50,10 @@ struct fjes_adapter {
50 50
51 bool irq_registered; 51 bool irq_registered;
52 52
53 struct workqueue_struct *txrx_wq;
54
55 struct work_struct raise_intr_rxdata_task;
56
53 struct fjes_hw hw; 57 struct fjes_hw hw;
54}; 58};
55 59
diff --git a/drivers/net/fjes/fjes_main.c b/drivers/net/fjes/fjes_main.c
index 220ff3da4521..80e180f163f5 100644
--- a/drivers/net/fjes/fjes_main.c
+++ b/drivers/net/fjes/fjes_main.c
@@ -52,6 +52,7 @@ static int fjes_close(struct net_device *);
52static int fjes_setup_resources(struct fjes_adapter *); 52static int fjes_setup_resources(struct fjes_adapter *);
53static void fjes_free_resources(struct fjes_adapter *); 53static void fjes_free_resources(struct fjes_adapter *);
54static netdev_tx_t fjes_xmit_frame(struct sk_buff *, struct net_device *); 54static netdev_tx_t fjes_xmit_frame(struct sk_buff *, struct net_device *);
55static void fjes_raise_intr_rxdata_task(struct work_struct *);
55static irqreturn_t fjes_intr(int, void*); 56static irqreturn_t fjes_intr(int, void*);
56 57
57static int fjes_acpi_add(struct acpi_device *); 58static int fjes_acpi_add(struct acpi_device *);
@@ -276,6 +277,8 @@ static int fjes_close(struct net_device *netdev)
276 277
277 fjes_free_irq(adapter); 278 fjes_free_irq(adapter);
278 279
280 cancel_work_sync(&adapter->raise_intr_rxdata_task);
281
279 fjes_hw_wait_epstop(hw); 282 fjes_hw_wait_epstop(hw);
280 283
281 fjes_free_resources(adapter); 284 fjes_free_resources(adapter);
@@ -404,6 +407,54 @@ static void fjes_free_resources(struct fjes_adapter *adapter)
404 } 407 }
405} 408}
406 409
410static void fjes_raise_intr_rxdata_task(struct work_struct *work)
411{
412 struct fjes_adapter *adapter = container_of(work,
413 struct fjes_adapter, raise_intr_rxdata_task);
414 struct fjes_hw *hw = &adapter->hw;
415 enum ep_partner_status pstatus;
416 int max_epid, my_epid, epid;
417
418 my_epid = hw->my_epid;
419 max_epid = hw->max_epid;
420
421 for (epid = 0; epid < max_epid; epid++)
422 hw->ep_shm_info[epid].tx_status_work = 0;
423
424 for (epid = 0; epid < max_epid; epid++) {
425 if (epid == my_epid)
426 continue;
427
428 pstatus = fjes_hw_get_partner_ep_status(hw, epid);
429 if (pstatus == EP_PARTNER_SHARED) {
430 hw->ep_shm_info[epid].tx_status_work =
431 hw->ep_shm_info[epid].tx.info->v1i.tx_status;
432
433 if (hw->ep_shm_info[epid].tx_status_work ==
434 FJES_TX_DELAY_SEND_PENDING) {
435 hw->ep_shm_info[epid].tx.info->v1i.tx_status =
436 FJES_TX_DELAY_SEND_NONE;
437 }
438 }
439 }
440
441 for (epid = 0; epid < max_epid; epid++) {
442 if (epid == my_epid)
443 continue;
444
445 pstatus = fjes_hw_get_partner_ep_status(hw, epid);
446 if ((hw->ep_shm_info[epid].tx_status_work ==
447 FJES_TX_DELAY_SEND_PENDING) &&
448 (pstatus == EP_PARTNER_SHARED) &&
449 !(hw->ep_shm_info[epid].rx.info->v1i.rx_status)) {
450 fjes_hw_raise_interrupt(hw, epid,
451 REG_ICTL_MASK_RX_DATA);
452 }
453 }
454
455 usleep_range(500, 1000);
456}
457
407static int fjes_tx_send(struct fjes_adapter *adapter, int dest, 458static int fjes_tx_send(struct fjes_adapter *adapter, int dest,
408 void *data, size_t len) 459 void *data, size_t len)
409{ 460{
@@ -416,6 +467,9 @@ static int fjes_tx_send(struct fjes_adapter *adapter, int dest,
416 467
417 adapter->hw.ep_shm_info[dest].tx.info->v1i.tx_status = 468 adapter->hw.ep_shm_info[dest].tx.info->v1i.tx_status =
418 FJES_TX_DELAY_SEND_PENDING; 469 FJES_TX_DELAY_SEND_PENDING;
470 if (!work_pending(&adapter->raise_intr_rxdata_task))
471 queue_work(adapter->txrx_wq,
472 &adapter->raise_intr_rxdata_task);
419 473
420 retval = 0; 474 retval = 0;
421 return retval; 475 return retval;
@@ -630,6 +684,11 @@ static int fjes_probe(struct platform_device *plat_dev)
630 adapter->force_reset = false; 684 adapter->force_reset = false;
631 adapter->open_guard = false; 685 adapter->open_guard = false;
632 686
687 adapter->txrx_wq = create_workqueue(DRV_NAME "/txrx");
688
689 INIT_WORK(&adapter->raise_intr_rxdata_task,
690 fjes_raise_intr_rxdata_task);
691
633 res = platform_get_resource(plat_dev, IORESOURCE_MEM, 0); 692 res = platform_get_resource(plat_dev, IORESOURCE_MEM, 0);
634 hw->hw_res.start = res->start; 693 hw->hw_res.start = res->start;
635 hw->hw_res.size = res->end - res->start + 1; 694 hw->hw_res.size = res->end - res->start + 1;
@@ -669,6 +728,10 @@ static int fjes_remove(struct platform_device *plat_dev)
669 struct fjes_adapter *adapter = netdev_priv(netdev); 728 struct fjes_adapter *adapter = netdev_priv(netdev);
670 struct fjes_hw *hw = &adapter->hw; 729 struct fjes_hw *hw = &adapter->hw;
671 730
731 cancel_work_sync(&adapter->raise_intr_rxdata_task);
732 if (adapter->txrx_wq)
733 destroy_workqueue(adapter->txrx_wq);
734
672 unregister_netdev(netdev); 735 unregister_netdev(netdev);
673 736
674 fjes_hw_exit(hw); 737 fjes_hw_exit(hw);