diff options
| -rw-r--r-- | drivers/net/benet/be_cmds.c | 26 | ||||
| -rw-r--r-- | drivers/net/benet/be_cmds.h | 2 | ||||
| -rw-r--r-- | drivers/net/benet/be_main.c | 47 |
3 files changed, 37 insertions, 38 deletions
diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c index c8a2bacb1d13..4b1f80519ca4 100644 --- a/drivers/net/benet/be_cmds.c +++ b/drivers/net/benet/be_cmds.c | |||
| @@ -119,10 +119,10 @@ void be_async_mcc_disable(struct be_adapter *adapter) | |||
| 119 | adapter->mcc_obj.rearm_cq = false; | 119 | adapter->mcc_obj.rearm_cq = false; |
| 120 | } | 120 | } |
| 121 | 121 | ||
| 122 | int be_process_mcc(struct be_adapter *adapter) | 122 | int be_process_mcc(struct be_adapter *adapter, int *status) |
| 123 | { | 123 | { |
| 124 | struct be_mcc_compl *compl; | 124 | struct be_mcc_compl *compl; |
| 125 | int num = 0, status = 0; | 125 | int num = 0; |
| 126 | struct be_mcc_obj *mcc_obj = &adapter->mcc_obj; | 126 | struct be_mcc_obj *mcc_obj = &adapter->mcc_obj; |
| 127 | 127 | ||
| 128 | spin_lock_bh(&adapter->mcc_cq_lock); | 128 | spin_lock_bh(&adapter->mcc_cq_lock); |
| @@ -135,31 +135,31 @@ int be_process_mcc(struct be_adapter *adapter) | |||
| 135 | be_async_link_state_process(adapter, | 135 | be_async_link_state_process(adapter, |
| 136 | (struct be_async_event_link_state *) compl); | 136 | (struct be_async_event_link_state *) compl); |
| 137 | } else if (compl->flags & CQE_FLAGS_COMPLETED_MASK) { | 137 | } else if (compl->flags & CQE_FLAGS_COMPLETED_MASK) { |
| 138 | status = be_mcc_compl_process(adapter, compl); | 138 | *status = be_mcc_compl_process(adapter, compl); |
| 139 | atomic_dec(&mcc_obj->q.used); | 139 | atomic_dec(&mcc_obj->q.used); |
| 140 | } | 140 | } |
| 141 | be_mcc_compl_use(compl); | 141 | be_mcc_compl_use(compl); |
| 142 | num++; | 142 | num++; |
| 143 | } | 143 | } |
| 144 | 144 | ||
| 145 | if (num) | ||
| 146 | be_cq_notify(adapter, mcc_obj->cq.id, mcc_obj->rearm_cq, num); | ||
| 147 | |||
| 148 | spin_unlock_bh(&adapter->mcc_cq_lock); | 145 | spin_unlock_bh(&adapter->mcc_cq_lock); |
| 149 | return status; | 146 | return num; |
| 150 | } | 147 | } |
| 151 | 148 | ||
| 152 | /* Wait till no more pending mcc requests are present */ | 149 | /* Wait till no more pending mcc requests are present */ |
| 153 | static int be_mcc_wait_compl(struct be_adapter *adapter) | 150 | static int be_mcc_wait_compl(struct be_adapter *adapter) |
| 154 | { | 151 | { |
| 155 | #define mcc_timeout 120000 /* 12s timeout */ | 152 | #define mcc_timeout 120000 /* 12s timeout */ |
| 156 | int i, status; | 153 | int i, num, status = 0; |
| 154 | struct be_mcc_obj *mcc_obj = &adapter->mcc_obj; | ||
| 155 | |||
| 157 | for (i = 0; i < mcc_timeout; i++) { | 156 | for (i = 0; i < mcc_timeout; i++) { |
| 158 | status = be_process_mcc(adapter); | 157 | num = be_process_mcc(adapter, &status); |
| 159 | if (status) | 158 | if (num) |
| 160 | return status; | 159 | be_cq_notify(adapter, mcc_obj->cq.id, |
| 160 | mcc_obj->rearm_cq, num); | ||
| 161 | 161 | ||
| 162 | if (atomic_read(&adapter->mcc_obj.q.used) == 0) | 162 | if (atomic_read(&mcc_obj->q.used) == 0) |
| 163 | break; | 163 | break; |
| 164 | udelay(100); | 164 | udelay(100); |
| 165 | } | 165 | } |
| @@ -167,7 +167,7 @@ static int be_mcc_wait_compl(struct be_adapter *adapter) | |||
| 167 | dev_err(&adapter->pdev->dev, "mccq poll timed out\n"); | 167 | dev_err(&adapter->pdev->dev, "mccq poll timed out\n"); |
| 168 | return -1; | 168 | return -1; |
| 169 | } | 169 | } |
| 170 | return 0; | 170 | return status; |
| 171 | } | 171 | } |
| 172 | 172 | ||
| 173 | /* Notify MCC requests and wait for completion */ | 173 | /* Notify MCC requests and wait for completion */ |
diff --git a/drivers/net/benet/be_cmds.h b/drivers/net/benet/be_cmds.h index 728b0d736929..cce61f9a3714 100644 --- a/drivers/net/benet/be_cmds.h +++ b/drivers/net/benet/be_cmds.h | |||
| @@ -920,7 +920,7 @@ extern int be_cmd_get_flow_control(struct be_adapter *adapter, | |||
| 920 | extern int be_cmd_query_fw_cfg(struct be_adapter *adapter, | 920 | extern int be_cmd_query_fw_cfg(struct be_adapter *adapter, |
| 921 | u32 *port_num, u32 *cap); | 921 | u32 *port_num, u32 *cap); |
| 922 | extern int be_cmd_reset_function(struct be_adapter *adapter); | 922 | extern int be_cmd_reset_function(struct be_adapter *adapter); |
| 923 | extern int be_process_mcc(struct be_adapter *adapter); | 923 | extern int be_process_mcc(struct be_adapter *adapter, int *status); |
| 924 | extern int be_cmd_set_beacon_state(struct be_adapter *adapter, | 924 | extern int be_cmd_set_beacon_state(struct be_adapter *adapter, |
| 925 | u8 port_num, u8 beacon, u8 status, u8 state); | 925 | u8 port_num, u8 beacon, u8 status, u8 state); |
| 926 | extern int be_cmd_get_beacon_state(struct be_adapter *adapter, | 926 | extern int be_cmd_get_beacon_state(struct be_adapter *adapter, |
diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index 27ccdd80257b..a703ed8e24fe 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c | |||
| @@ -583,7 +583,7 @@ static void be_set_multicast_list(struct net_device *netdev) | |||
| 583 | } | 583 | } |
| 584 | 584 | ||
| 585 | be_cmd_multicast_set(adapter, adapter->if_handle, netdev, | 585 | be_cmd_multicast_set(adapter, adapter->if_handle, netdev, |
| 586 | &adapter->mc_cmd_mem); | 586 | &adapter->mc_cmd_mem); |
| 587 | done: | 587 | done: |
| 588 | return; | 588 | return; |
| 589 | } | 589 | } |
| @@ -1469,23 +1469,38 @@ int be_poll_rx(struct napi_struct *napi, int budget) | |||
| 1469 | return work_done; | 1469 | return work_done; |
| 1470 | } | 1470 | } |
| 1471 | 1471 | ||
| 1472 | void be_process_tx(struct be_adapter *adapter) | 1472 | /* As TX and MCC share the same EQ check for both TX and MCC completions. |
| 1473 | * For TX/MCC we don't honour budget; consume everything | ||
| 1474 | */ | ||
| 1475 | static int be_poll_tx_mcc(struct napi_struct *napi, int budget) | ||
| 1473 | { | 1476 | { |
| 1477 | struct be_eq_obj *tx_eq = container_of(napi, struct be_eq_obj, napi); | ||
| 1478 | struct be_adapter *adapter = | ||
| 1479 | container_of(tx_eq, struct be_adapter, tx_eq); | ||
| 1474 | struct be_queue_info *txq = &adapter->tx_obj.q; | 1480 | struct be_queue_info *txq = &adapter->tx_obj.q; |
| 1475 | struct be_queue_info *tx_cq = &adapter->tx_obj.cq; | 1481 | struct be_queue_info *tx_cq = &adapter->tx_obj.cq; |
| 1476 | struct be_eth_tx_compl *txcp; | 1482 | struct be_eth_tx_compl *txcp; |
| 1477 | u32 num_cmpl = 0; | 1483 | int tx_compl = 0, mcc_compl, status = 0; |
| 1478 | u16 end_idx; | 1484 | u16 end_idx; |
| 1479 | 1485 | ||
| 1480 | while ((txcp = be_tx_compl_get(tx_cq))) { | 1486 | while ((txcp = be_tx_compl_get(tx_cq))) { |
| 1481 | end_idx = AMAP_GET_BITS(struct amap_eth_tx_compl, | 1487 | end_idx = AMAP_GET_BITS(struct amap_eth_tx_compl, |
| 1482 | wrb_index, txcp); | 1488 | wrb_index, txcp); |
| 1483 | be_tx_compl_process(adapter, end_idx); | 1489 | be_tx_compl_process(adapter, end_idx); |
| 1484 | num_cmpl++; | 1490 | tx_compl++; |
| 1485 | } | 1491 | } |
| 1486 | 1492 | ||
| 1487 | if (num_cmpl) { | 1493 | mcc_compl = be_process_mcc(adapter, &status); |
| 1488 | be_cq_notify(adapter, tx_cq->id, true, num_cmpl); | 1494 | |
| 1495 | napi_complete(napi); | ||
| 1496 | |||
| 1497 | if (mcc_compl) { | ||
| 1498 | struct be_mcc_obj *mcc_obj = &adapter->mcc_obj; | ||
| 1499 | be_cq_notify(adapter, mcc_obj->cq.id, true, mcc_compl); | ||
| 1500 | } | ||
| 1501 | |||
| 1502 | if (tx_compl) { | ||
| 1503 | be_cq_notify(adapter, adapter->tx_obj.cq.id, true, tx_compl); | ||
| 1489 | 1504 | ||
| 1490 | /* As Tx wrbs have been freed up, wake up netdev queue if | 1505 | /* As Tx wrbs have been freed up, wake up netdev queue if |
| 1491 | * it was stopped due to lack of tx wrbs. | 1506 | * it was stopped due to lack of tx wrbs. |
| @@ -1496,24 +1511,8 @@ void be_process_tx(struct be_adapter *adapter) | |||
| 1496 | } | 1511 | } |
| 1497 | 1512 | ||
| 1498 | drvr_stats(adapter)->be_tx_events++; | 1513 | drvr_stats(adapter)->be_tx_events++; |
| 1499 | drvr_stats(adapter)->be_tx_compl += num_cmpl; | 1514 | drvr_stats(adapter)->be_tx_compl += tx_compl; |
| 1500 | } | 1515 | } |
| 1501 | } | ||
| 1502 | |||
| 1503 | /* As TX and MCC share the same EQ check for both TX and MCC completions. | ||
| 1504 | * For TX/MCC we don't honour budget; consume everything | ||
| 1505 | */ | ||
| 1506 | static int be_poll_tx_mcc(struct napi_struct *napi, int budget) | ||
| 1507 | { | ||
| 1508 | struct be_eq_obj *tx_eq = container_of(napi, struct be_eq_obj, napi); | ||
| 1509 | struct be_adapter *adapter = | ||
| 1510 | container_of(tx_eq, struct be_adapter, tx_eq); | ||
| 1511 | |||
| 1512 | napi_complete(napi); | ||
| 1513 | |||
| 1514 | be_process_tx(adapter); | ||
| 1515 | |||
| 1516 | be_process_mcc(adapter); | ||
| 1517 | 1516 | ||
| 1518 | return 1; | 1517 | return 1; |
| 1519 | } | 1518 | } |
