| 976 | } |
| 977 | |
| 978 | static void |
| 979 | ntb_dev_stop(struct rte_rawdev *dev) |
| 980 | { |
| 981 | struct ntb_hw *hw = dev->dev_private; |
| 982 | uint32_t time_out; |
| 983 | int status, i; |
| 984 | |
| 985 | if (!hw->peer_dev_up) |
| 986 | goto clean; |
| 987 | |
| 988 | ntb_link_cleanup(dev); |
| 989 | |
| 990 | /* Notify the peer that device will be down. */ |
| 991 | if (hw->ntb_ops->peer_db_set == NULL) { |
| 992 | NTB_LOG(ERR, "Peer doorbell setting is not supported."); |
| 993 | return; |
| 994 | } |
| 995 | status = (*hw->ntb_ops->peer_db_set)(dev, 1); |
| 996 | if (status) { |
| 997 | NTB_LOG(ERR, "Failed to tell peer device is down."); |
| 998 | return; |
| 999 | } |
| 1000 | |
| 1001 | /* |
| 1002 | * Set time out as 1s in case that the peer is stopped accidently |
| 1003 | * without any notification. |
| 1004 | */ |
| 1005 | time_out = 1000000; |
| 1006 | |
| 1007 | /* Wait for cleanup work down before db mask clear. */ |
| 1008 | while (hw->peer_dev_up && time_out) { |
| 1009 | time_out -= 10; |
| 1010 | rte_delay_us(10); |
| 1011 | } |
| 1012 | |
| 1013 | clean: |
| 1014 | /* Clear doorbells mask. */ |
| 1015 | if (hw->ntb_ops->db_set_mask == NULL) { |
| 1016 | NTB_LOG(ERR, "Doorbell mask setting is not supported."); |
| 1017 | return; |
| 1018 | } |
| 1019 | status = (*hw->ntb_ops->db_set_mask)(dev, |
| 1020 | (((uint64_t)1 << hw->db_cnt) - 1)); |
| 1021 | if (status) |
| 1022 | NTB_LOG(ERR, "Failed to clear doorbells."); |
| 1023 | |
| 1024 | for (i = 0; i < hw->queue_pairs; i++) { |
| 1025 | ntb_rxq_release_mbufs(hw->rx_queues[i]); |
| 1026 | ntb_txq_release_mbufs(hw->tx_queues[i]); |
| 1027 | } |
| 1028 | |
| 1029 | dev->started = 0; |
| 1030 | } |
| 1031 | |
| 1032 | static int |
| 1033 | ntb_dev_close(struct rte_rawdev *dev) |
no test coverage detected