diff options
author | Taku Izumi <izumi.taku@jp.fujitsu.com> | 2015-08-21 04:29:34 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-08-24 17:06:36 -0400 |
commit | 8fc4cadb98c6a0f1eecde678271fcc957258af3e (patch) | |
tree | 82661522033d14ea560cc85dc5b0df368ad76537 | |
parent | ff5b42103227c01c4082f27b06a43758efbf5ab8 (diff) |
fjes: unshare_watch_task
This patch adds unshare_watch_task.
Shared buffer's status can be changed into unshared.
This task is used to monitor shared buffer's status.
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.h | 3 | ||||
-rw-r--r-- | drivers/net/fjes/fjes_main.c | 126 |
2 files changed, 129 insertions, 0 deletions
diff --git a/drivers/net/fjes/fjes.h b/drivers/net/fjes/fjes.h index d31d4c3be45f..57feee84332d 100644 --- a/drivers/net/fjes/fjes.h +++ b/drivers/net/fjes/fjes.h | |||
@@ -59,6 +59,9 @@ struct fjes_adapter { | |||
59 | struct work_struct tx_stall_task; | 59 | struct work_struct tx_stall_task; |
60 | struct work_struct raise_intr_rxdata_task; | 60 | struct work_struct raise_intr_rxdata_task; |
61 | 61 | ||
62 | struct work_struct unshare_watch_task; | ||
63 | unsigned long unshare_watch_bitmask; | ||
64 | |||
62 | struct delayed_work interrupt_watch_task; | 65 | struct delayed_work interrupt_watch_task; |
63 | bool interrupt_watch_enable; | 66 | bool interrupt_watch_enable; |
64 | 67 | ||
diff --git a/drivers/net/fjes/fjes_main.c b/drivers/net/fjes/fjes_main.c index caecfb39ecf9..c47ecf35d005 100644 --- a/drivers/net/fjes/fjes_main.c +++ b/drivers/net/fjes/fjes_main.c | |||
@@ -73,6 +73,7 @@ static int fjes_remove(struct platform_device *); | |||
73 | static int fjes_sw_init(struct fjes_adapter *); | 73 | static int fjes_sw_init(struct fjes_adapter *); |
74 | static void fjes_netdev_setup(struct net_device *); | 74 | static void fjes_netdev_setup(struct net_device *); |
75 | static void fjes_irq_watch_task(struct work_struct *); | 75 | static void fjes_irq_watch_task(struct work_struct *); |
76 | static void fjes_watch_unshare_task(struct work_struct *); | ||
76 | static void fjes_rx_irq(struct fjes_adapter *, int); | 77 | static void fjes_rx_irq(struct fjes_adapter *, int); |
77 | static int fjes_poll(struct napi_struct *, int); | 78 | static int fjes_poll(struct napi_struct *, int); |
78 | 79 | ||
@@ -309,6 +310,8 @@ static int fjes_close(struct net_device *netdev) | |||
309 | fjes_free_irq(adapter); | 310 | fjes_free_irq(adapter); |
310 | 311 | ||
311 | cancel_delayed_work_sync(&adapter->interrupt_watch_task); | 312 | cancel_delayed_work_sync(&adapter->interrupt_watch_task); |
313 | cancel_work_sync(&adapter->unshare_watch_task); | ||
314 | adapter->unshare_watch_bitmask = 0; | ||
312 | cancel_work_sync(&adapter->raise_intr_rxdata_task); | 315 | cancel_work_sync(&adapter->raise_intr_rxdata_task); |
313 | cancel_work_sync(&adapter->tx_stall_task); | 316 | cancel_work_sync(&adapter->tx_stall_task); |
314 | 317 | ||
@@ -1025,6 +1028,8 @@ static int fjes_probe(struct platform_device *plat_dev) | |||
1025 | INIT_WORK(&adapter->tx_stall_task, fjes_tx_stall_task); | 1028 | INIT_WORK(&adapter->tx_stall_task, fjes_tx_stall_task); |
1026 | INIT_WORK(&adapter->raise_intr_rxdata_task, | 1029 | INIT_WORK(&adapter->raise_intr_rxdata_task, |
1027 | fjes_raise_intr_rxdata_task); | 1030 | fjes_raise_intr_rxdata_task); |
1031 | INIT_WORK(&adapter->unshare_watch_task, fjes_watch_unshare_task); | ||
1032 | adapter->unshare_watch_bitmask = 0; | ||
1028 | 1033 | ||
1029 | INIT_DELAYED_WORK(&adapter->interrupt_watch_task, fjes_irq_watch_task); | 1034 | INIT_DELAYED_WORK(&adapter->interrupt_watch_task, fjes_irq_watch_task); |
1030 | adapter->interrupt_watch_enable = false; | 1035 | adapter->interrupt_watch_enable = false; |
@@ -1069,6 +1074,7 @@ static int fjes_remove(struct platform_device *plat_dev) | |||
1069 | struct fjes_hw *hw = &adapter->hw; | 1074 | struct fjes_hw *hw = &adapter->hw; |
1070 | 1075 | ||
1071 | cancel_delayed_work_sync(&adapter->interrupt_watch_task); | 1076 | cancel_delayed_work_sync(&adapter->interrupt_watch_task); |
1077 | cancel_work_sync(&adapter->unshare_watch_task); | ||
1072 | cancel_work_sync(&adapter->raise_intr_rxdata_task); | 1078 | cancel_work_sync(&adapter->raise_intr_rxdata_task); |
1073 | cancel_work_sync(&adapter->tx_stall_task); | 1079 | cancel_work_sync(&adapter->tx_stall_task); |
1074 | if (adapter->control_wq) | 1080 | if (adapter->control_wq) |
@@ -1128,6 +1134,126 @@ static void fjes_irq_watch_task(struct work_struct *work) | |||
1128 | } | 1134 | } |
1129 | } | 1135 | } |
1130 | 1136 | ||
1137 | static void fjes_watch_unshare_task(struct work_struct *work) | ||
1138 | { | ||
1139 | struct fjes_adapter *adapter = | ||
1140 | container_of(work, struct fjes_adapter, unshare_watch_task); | ||
1141 | |||
1142 | struct net_device *netdev = adapter->netdev; | ||
1143 | struct fjes_hw *hw = &adapter->hw; | ||
1144 | |||
1145 | int unshare_watch, unshare_reserve; | ||
1146 | int max_epid, my_epid, epidx; | ||
1147 | int stop_req, stop_req_done; | ||
1148 | ulong unshare_watch_bitmask; | ||
1149 | int wait_time = 0; | ||
1150 | int is_shared; | ||
1151 | int ret; | ||
1152 | |||
1153 | my_epid = hw->my_epid; | ||
1154 | max_epid = hw->max_epid; | ||
1155 | |||
1156 | unshare_watch_bitmask = adapter->unshare_watch_bitmask; | ||
1157 | adapter->unshare_watch_bitmask = 0; | ||
1158 | |||
1159 | while ((unshare_watch_bitmask || hw->txrx_stop_req_bit) && | ||
1160 | (wait_time < 3000)) { | ||
1161 | for (epidx = 0; epidx < hw->max_epid; epidx++) { | ||
1162 | if (epidx == hw->my_epid) | ||
1163 | continue; | ||
1164 | |||
1165 | is_shared = fjes_hw_epid_is_shared(hw->hw_info.share, | ||
1166 | epidx); | ||
1167 | |||
1168 | stop_req = test_bit(epidx, &hw->txrx_stop_req_bit); | ||
1169 | |||
1170 | stop_req_done = hw->ep_shm_info[epidx].rx.info->v1i.rx_status & | ||
1171 | FJES_RX_STOP_REQ_DONE; | ||
1172 | |||
1173 | unshare_watch = test_bit(epidx, &unshare_watch_bitmask); | ||
1174 | |||
1175 | unshare_reserve = test_bit(epidx, | ||
1176 | &hw->hw_info.buffer_unshare_reserve_bit); | ||
1177 | |||
1178 | if ((!stop_req || | ||
1179 | (is_shared && (!is_shared || !stop_req_done))) && | ||
1180 | (is_shared || !unshare_watch || !unshare_reserve)) | ||
1181 | continue; | ||
1182 | |||
1183 | mutex_lock(&hw->hw_info.lock); | ||
1184 | ret = fjes_hw_unregister_buff_addr(hw, epidx); | ||
1185 | switch (ret) { | ||
1186 | case 0: | ||
1187 | break; | ||
1188 | case -ENOMSG: | ||
1189 | case -EBUSY: | ||
1190 | default: | ||
1191 | if (!work_pending( | ||
1192 | &adapter->force_close_task)) { | ||
1193 | adapter->force_reset = true; | ||
1194 | schedule_work( | ||
1195 | &adapter->force_close_task); | ||
1196 | } | ||
1197 | break; | ||
1198 | } | ||
1199 | mutex_unlock(&hw->hw_info.lock); | ||
1200 | |||
1201 | fjes_hw_setup_epbuf(&hw->ep_shm_info[epidx].tx, | ||
1202 | netdev->dev_addr, netdev->mtu); | ||
1203 | |||
1204 | clear_bit(epidx, &hw->txrx_stop_req_bit); | ||
1205 | clear_bit(epidx, &unshare_watch_bitmask); | ||
1206 | clear_bit(epidx, | ||
1207 | &hw->hw_info.buffer_unshare_reserve_bit); | ||
1208 | } | ||
1209 | |||
1210 | msleep(100); | ||
1211 | wait_time += 100; | ||
1212 | } | ||
1213 | |||
1214 | if (hw->hw_info.buffer_unshare_reserve_bit) { | ||
1215 | for (epidx = 0; epidx < hw->max_epid; epidx++) { | ||
1216 | if (epidx == hw->my_epid) | ||
1217 | continue; | ||
1218 | |||
1219 | if (test_bit(epidx, | ||
1220 | &hw->hw_info.buffer_unshare_reserve_bit)) { | ||
1221 | mutex_lock(&hw->hw_info.lock); | ||
1222 | |||
1223 | ret = fjes_hw_unregister_buff_addr(hw, epidx); | ||
1224 | switch (ret) { | ||
1225 | case 0: | ||
1226 | break; | ||
1227 | case -ENOMSG: | ||
1228 | case -EBUSY: | ||
1229 | default: | ||
1230 | if (!work_pending( | ||
1231 | &adapter->force_close_task)) { | ||
1232 | adapter->force_reset = true; | ||
1233 | schedule_work( | ||
1234 | &adapter->force_close_task); | ||
1235 | } | ||
1236 | break; | ||
1237 | } | ||
1238 | mutex_unlock(&hw->hw_info.lock); | ||
1239 | |||
1240 | fjes_hw_setup_epbuf( | ||
1241 | &hw->ep_shm_info[epidx].tx, | ||
1242 | netdev->dev_addr, netdev->mtu); | ||
1243 | |||
1244 | clear_bit(epidx, &hw->txrx_stop_req_bit); | ||
1245 | clear_bit(epidx, &unshare_watch_bitmask); | ||
1246 | clear_bit(epidx, &hw->hw_info.buffer_unshare_reserve_bit); | ||
1247 | } | ||
1248 | |||
1249 | if (test_bit(epidx, &unshare_watch_bitmask)) { | ||
1250 | hw->ep_shm_info[epidx].tx.info->v1i.rx_status &= | ||
1251 | ~FJES_RX_STOP_REQ_DONE; | ||
1252 | } | ||
1253 | } | ||
1254 | } | ||
1255 | } | ||
1256 | |||
1131 | /* fjes_init_module - Driver Registration Routine */ | 1257 | /* fjes_init_module - Driver Registration Routine */ |
1132 | static int __init fjes_init_module(void) | 1258 | static int __init fjes_init_module(void) |
1133 | { | 1259 | { |