aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTaku Izumi <izumi.taku@jp.fujitsu.com>2015-08-21 04:29:34 -0400
committerDavid S. Miller <davem@davemloft.net>2015-08-24 17:06:36 -0400
commit8fc4cadb98c6a0f1eecde678271fcc957258af3e (patch)
tree82661522033d14ea560cc85dc5b0df368ad76537
parentff5b42103227c01c4082f27b06a43758efbf5ab8 (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.h3
-rw-r--r--drivers/net/fjes/fjes_main.c126
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 *);
73static int fjes_sw_init(struct fjes_adapter *); 73static int fjes_sw_init(struct fjes_adapter *);
74static void fjes_netdev_setup(struct net_device *); 74static void fjes_netdev_setup(struct net_device *);
75static void fjes_irq_watch_task(struct work_struct *); 75static void fjes_irq_watch_task(struct work_struct *);
76static void fjes_watch_unshare_task(struct work_struct *);
76static void fjes_rx_irq(struct fjes_adapter *, int); 77static void fjes_rx_irq(struct fjes_adapter *, int);
77static int fjes_poll(struct napi_struct *, int); 78static 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
1137static 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 */
1132static int __init fjes_init_module(void) 1258static int __init fjes_init_module(void)
1133{ 1259{