aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/benet/be_main.c85
1 files changed, 56 insertions, 29 deletions
diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c
index 9bbf447ee28f..2db879c03c6d 100644
--- a/drivers/net/benet/be_main.c
+++ b/drivers/net/benet/be_main.c
@@ -993,6 +993,56 @@ static void be_tx_compl_process(struct be_adapter *adapter, u16 last_index)
993 kfree_skb(sent_skb); 993 kfree_skb(sent_skb);
994} 994}
995 995
996static inline struct be_eq_entry *event_get(struct be_eq_obj *eq_obj)
997{
998 struct be_eq_entry *eqe = queue_tail_node(&eq_obj->q);
999
1000 if (!eqe->evt)
1001 return NULL;
1002
1003 eqe->evt = le32_to_cpu(eqe->evt);
1004 queue_tail_inc(&eq_obj->q);
1005 return eqe;
1006}
1007
1008static int event_handle(struct be_adapter *adapter,
1009 struct be_eq_obj *eq_obj)
1010{
1011 struct be_eq_entry *eqe;
1012 u16 num = 0;
1013
1014 while ((eqe = event_get(eq_obj)) != NULL) {
1015 eqe->evt = 0;
1016 num++;
1017 }
1018
1019 /* Deal with any spurious interrupts that come
1020 * without events
1021 */
1022 be_eq_notify(adapter, eq_obj->q.id, true, true, num);
1023 if (num)
1024 napi_schedule(&eq_obj->napi);
1025
1026 return num;
1027}
1028
1029/* Just read and notify events without processing them.
1030 * Used at the time of destroying event queues */
1031static void be_eq_clean(struct be_adapter *adapter,
1032 struct be_eq_obj *eq_obj)
1033{
1034 struct be_eq_entry *eqe;
1035 u16 num = 0;
1036
1037 while ((eqe = event_get(eq_obj)) != NULL) {
1038 eqe->evt = 0;
1039 num++;
1040 }
1041
1042 if (num)
1043 be_eq_notify(adapter, eq_obj->q.id, false, true, num);
1044}
1045
996static void be_rx_q_clean(struct be_adapter *adapter) 1046static void be_rx_q_clean(struct be_adapter *adapter)
997{ 1047{
998 struct be_rx_page_info *page_info; 1048 struct be_rx_page_info *page_info;
@@ -1114,6 +1164,9 @@ static void be_tx_queues_destroy(struct be_adapter *adapter)
1114 be_cmd_q_destroy(adapter, q, QTYPE_CQ); 1164 be_cmd_q_destroy(adapter, q, QTYPE_CQ);
1115 be_queue_free(adapter, q); 1165 be_queue_free(adapter, q);
1116 1166
1167 /* Clear any residual events */
1168 be_eq_clean(adapter, &adapter->tx_eq);
1169
1117 q = &adapter->tx_eq.q; 1170 q = &adapter->tx_eq.q;
1118 if (q->created) 1171 if (q->created)
1119 be_cmd_q_destroy(adapter, q, QTYPE_EQ); 1172 be_cmd_q_destroy(adapter, q, QTYPE_EQ);
@@ -1185,6 +1238,9 @@ static void be_rx_queues_destroy(struct be_adapter *adapter)
1185 be_cmd_q_destroy(adapter, q, QTYPE_CQ); 1238 be_cmd_q_destroy(adapter, q, QTYPE_CQ);
1186 be_queue_free(adapter, q); 1239 be_queue_free(adapter, q);
1187 1240
1241 /* Clear any residual events */
1242 be_eq_clean(adapter, &adapter->rx_eq);
1243
1188 q = &adapter->rx_eq.q; 1244 q = &adapter->rx_eq.q;
1189 if (q->created) 1245 if (q->created)
1190 be_cmd_q_destroy(adapter, q, QTYPE_EQ); 1246 be_cmd_q_destroy(adapter, q, QTYPE_EQ);
@@ -1251,35 +1307,6 @@ rx_eq_free:
1251 be_queue_free(adapter, eq); 1307 be_queue_free(adapter, eq);
1252 return rc; 1308 return rc;
1253} 1309}
1254static bool event_get(struct be_eq_obj *eq_obj, u16 *rid)
1255{
1256 struct be_eq_entry *entry = queue_tail_node(&eq_obj->q);
1257 u32 evt = entry->evt;
1258
1259 if (!evt)
1260 return false;
1261
1262 evt = le32_to_cpu(evt);
1263 *rid = (evt >> EQ_ENTRY_RES_ID_SHIFT) & EQ_ENTRY_RES_ID_MASK;
1264 entry->evt = 0;
1265 queue_tail_inc(&eq_obj->q);
1266 return true;
1267}
1268
1269static int event_handle(struct be_adapter *adapter, struct be_eq_obj *eq_obj)
1270{
1271 u16 rid = 0, num = 0;
1272
1273 while (event_get(eq_obj, &rid))
1274 num++;
1275
1276 /* We can see an interrupt and no event */
1277 be_eq_notify(adapter, eq_obj->q.id, true, true, num);
1278 if (num)
1279 napi_schedule(&eq_obj->napi);
1280
1281 return num;
1282}
1283 1310
1284static irqreturn_t be_intx(int irq, void *dev) 1311static irqreturn_t be_intx(int irq, void *dev)
1285{ 1312{