diff options
| -rw-r--r-- | drivers/net/ethernet/amazon/ena/ena_com.c | 35 | ||||
| -rw-r--r-- | drivers/net/ethernet/amazon/ena/ena_ethtool.c | 2 | ||||
| -rw-r--r-- | drivers/net/ethernet/amazon/ena/ena_netdev.c | 179 | ||||
| -rw-r--r-- | drivers/net/ethernet/amazon/ena/ena_netdev.h | 18 |
4 files changed, 169 insertions, 65 deletions
diff --git a/drivers/net/ethernet/amazon/ena/ena_com.c b/drivers/net/ethernet/amazon/ena/ena_com.c index 08d11cede9c9..f5b237e0bd60 100644 --- a/drivers/net/ethernet/amazon/ena/ena_com.c +++ b/drivers/net/ethernet/amazon/ena/ena_com.c | |||
| @@ -61,6 +61,8 @@ | |||
| 61 | 61 | ||
| 62 | #define ENA_MMIO_READ_TIMEOUT 0xFFFFFFFF | 62 | #define ENA_MMIO_READ_TIMEOUT 0xFFFFFFFF |
| 63 | 63 | ||
| 64 | #define ENA_REGS_ADMIN_INTR_MASK 1 | ||
| 65 | |||
| 64 | /*****************************************************************************/ | 66 | /*****************************************************************************/ |
| 65 | /*****************************************************************************/ | 67 | /*****************************************************************************/ |
| 66 | /*****************************************************************************/ | 68 | /*****************************************************************************/ |
| @@ -232,11 +234,9 @@ static struct ena_comp_ctx *__ena_com_submit_admin_cmd(struct ena_com_admin_queu | |||
| 232 | tail_masked = admin_queue->sq.tail & queue_size_mask; | 234 | tail_masked = admin_queue->sq.tail & queue_size_mask; |
| 233 | 235 | ||
| 234 | /* In case of queue FULL */ | 236 | /* In case of queue FULL */ |
| 235 | cnt = admin_queue->sq.tail - admin_queue->sq.head; | 237 | cnt = atomic_read(&admin_queue->outstanding_cmds); |
| 236 | if (cnt >= admin_queue->q_depth) { | 238 | if (cnt >= admin_queue->q_depth) { |
| 237 | pr_debug("admin queue is FULL (tail %d head %d depth: %d)\n", | 239 | pr_debug("admin queue is full.\n"); |
| 238 | admin_queue->sq.tail, admin_queue->sq.head, | ||
| 239 | admin_queue->q_depth); | ||
| 240 | admin_queue->stats.out_of_space++; | 240 | admin_queue->stats.out_of_space++; |
| 241 | return ERR_PTR(-ENOSPC); | 241 | return ERR_PTR(-ENOSPC); |
| 242 | } | 242 | } |
| @@ -508,15 +508,20 @@ static int ena_com_comp_status_to_errno(u8 comp_status) | |||
| 508 | static int ena_com_wait_and_process_admin_cq_polling(struct ena_comp_ctx *comp_ctx, | 508 | static int ena_com_wait_and_process_admin_cq_polling(struct ena_comp_ctx *comp_ctx, |
| 509 | struct ena_com_admin_queue *admin_queue) | 509 | struct ena_com_admin_queue *admin_queue) |
| 510 | { | 510 | { |
| 511 | unsigned long flags; | 511 | unsigned long flags, timeout; |
| 512 | u32 start_time; | ||
| 513 | int ret; | 512 | int ret; |
| 514 | 513 | ||
| 515 | start_time = ((u32)jiffies_to_usecs(jiffies)); | 514 | timeout = jiffies + ADMIN_CMD_TIMEOUT_US; |
| 515 | |||
| 516 | while (1) { | ||
| 517 | spin_lock_irqsave(&admin_queue->q_lock, flags); | ||
| 518 | ena_com_handle_admin_completion(admin_queue); | ||
| 519 | spin_unlock_irqrestore(&admin_queue->q_lock, flags); | ||
| 520 | |||
| 521 | if (comp_ctx->status != ENA_CMD_SUBMITTED) | ||
| 522 | break; | ||
| 516 | 523 | ||
| 517 | while (comp_ctx->status == ENA_CMD_SUBMITTED) { | 524 | if (time_is_before_jiffies(timeout)) { |
| 518 | if ((((u32)jiffies_to_usecs(jiffies)) - start_time) > | ||
| 519 | ADMIN_CMD_TIMEOUT_US) { | ||
| 520 | pr_err("Wait for completion (polling) timeout\n"); | 525 | pr_err("Wait for completion (polling) timeout\n"); |
| 521 | /* ENA didn't have any completion */ | 526 | /* ENA didn't have any completion */ |
| 522 | spin_lock_irqsave(&admin_queue->q_lock, flags); | 527 | spin_lock_irqsave(&admin_queue->q_lock, flags); |
| @@ -528,10 +533,6 @@ static int ena_com_wait_and_process_admin_cq_polling(struct ena_comp_ctx *comp_c | |||
| 528 | goto err; | 533 | goto err; |
| 529 | } | 534 | } |
| 530 | 535 | ||
| 531 | spin_lock_irqsave(&admin_queue->q_lock, flags); | ||
| 532 | ena_com_handle_admin_completion(admin_queue); | ||
| 533 | spin_unlock_irqrestore(&admin_queue->q_lock, flags); | ||
| 534 | |||
| 535 | msleep(100); | 536 | msleep(100); |
| 536 | } | 537 | } |
| 537 | 538 | ||
| @@ -1455,6 +1456,12 @@ void ena_com_admin_destroy(struct ena_com_dev *ena_dev) | |||
| 1455 | 1456 | ||
| 1456 | void ena_com_set_admin_polling_mode(struct ena_com_dev *ena_dev, bool polling) | 1457 | void ena_com_set_admin_polling_mode(struct ena_com_dev *ena_dev, bool polling) |
| 1457 | { | 1458 | { |
| 1459 | u32 mask_value = 0; | ||
| 1460 | |||
| 1461 | if (polling) | ||
| 1462 | mask_value = ENA_REGS_ADMIN_INTR_MASK; | ||
| 1463 | |||
| 1464 | writel(mask_value, ena_dev->reg_bar + ENA_REGS_INTR_MASK_OFF); | ||
| 1458 | ena_dev->admin_queue.polling = polling; | 1465 | ena_dev->admin_queue.polling = polling; |
| 1459 | } | 1466 | } |
| 1460 | 1467 | ||
diff --git a/drivers/net/ethernet/amazon/ena/ena_ethtool.c b/drivers/net/ethernet/amazon/ena/ena_ethtool.c index 67b2338f8fb3..3ee55e2fd694 100644 --- a/drivers/net/ethernet/amazon/ena/ena_ethtool.c +++ b/drivers/net/ethernet/amazon/ena/ena_ethtool.c | |||
| @@ -80,7 +80,6 @@ static const struct ena_stats ena_stats_tx_strings[] = { | |||
| 80 | ENA_STAT_TX_ENTRY(tx_poll), | 80 | ENA_STAT_TX_ENTRY(tx_poll), |
| 81 | ENA_STAT_TX_ENTRY(doorbells), | 81 | ENA_STAT_TX_ENTRY(doorbells), |
| 82 | ENA_STAT_TX_ENTRY(prepare_ctx_err), | 82 | ENA_STAT_TX_ENTRY(prepare_ctx_err), |
| 83 | ENA_STAT_TX_ENTRY(missing_tx_comp), | ||
| 84 | ENA_STAT_TX_ENTRY(bad_req_id), | 83 | ENA_STAT_TX_ENTRY(bad_req_id), |
| 85 | }; | 84 | }; |
| 86 | 85 | ||
| @@ -94,6 +93,7 @@ static const struct ena_stats ena_stats_rx_strings[] = { | |||
| 94 | ENA_STAT_RX_ENTRY(dma_mapping_err), | 93 | ENA_STAT_RX_ENTRY(dma_mapping_err), |
| 95 | ENA_STAT_RX_ENTRY(bad_desc_num), | 94 | ENA_STAT_RX_ENTRY(bad_desc_num), |
| 96 | ENA_STAT_RX_ENTRY(rx_copybreak_pkt), | 95 | ENA_STAT_RX_ENTRY(rx_copybreak_pkt), |
| 96 | ENA_STAT_RX_ENTRY(empty_rx_ring), | ||
| 97 | }; | 97 | }; |
| 98 | 98 | ||
| 99 | static const struct ena_stats ena_stats_ena_com_strings[] = { | 99 | static const struct ena_stats ena_stats_ena_com_strings[] = { |
diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c b/drivers/net/ethernet/amazon/ena/ena_netdev.c index 7c1214d78855..4f16ed38bcf3 100644 --- a/drivers/net/ethernet/amazon/ena/ena_netdev.c +++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c | |||
| @@ -190,6 +190,7 @@ static void ena_init_io_rings(struct ena_adapter *adapter) | |||
| 190 | rxr->sgl_size = adapter->max_rx_sgl_size; | 190 | rxr->sgl_size = adapter->max_rx_sgl_size; |
| 191 | rxr->smoothed_interval = | 191 | rxr->smoothed_interval = |
| 192 | ena_com_get_nonadaptive_moderation_interval_rx(ena_dev); | 192 | ena_com_get_nonadaptive_moderation_interval_rx(ena_dev); |
| 193 | rxr->empty_rx_queue = 0; | ||
| 193 | } | 194 | } |
| 194 | } | 195 | } |
| 195 | 196 | ||
| @@ -1078,6 +1079,26 @@ inline void ena_adjust_intr_moderation(struct ena_ring *rx_ring, | |||
| 1078 | rx_ring->per_napi_bytes = 0; | 1079 | rx_ring->per_napi_bytes = 0; |
| 1079 | } | 1080 | } |
| 1080 | 1081 | ||
| 1082 | static inline void ena_unmask_interrupt(struct ena_ring *tx_ring, | ||
| 1083 | struct ena_ring *rx_ring) | ||
| 1084 | { | ||
| 1085 | struct ena_eth_io_intr_reg intr_reg; | ||
| 1086 | |||
| 1087 | /* Update intr register: rx intr delay, | ||
| 1088 | * tx intr delay and interrupt unmask | ||
| 1089 | */ | ||
| 1090 | ena_com_update_intr_reg(&intr_reg, | ||
| 1091 | rx_ring->smoothed_interval, | ||
| 1092 | tx_ring->smoothed_interval, | ||
| 1093 | true); | ||
| 1094 | |||
| 1095 | /* It is a shared MSI-X. | ||
| 1096 | * Tx and Rx CQ have pointer to it. | ||
| 1097 | * So we use one of them to reach the intr reg | ||
| 1098 | */ | ||
| 1099 | ena_com_unmask_intr(rx_ring->ena_com_io_cq, &intr_reg); | ||
| 1100 | } | ||
| 1101 | |||
| 1081 | static inline void ena_update_ring_numa_node(struct ena_ring *tx_ring, | 1102 | static inline void ena_update_ring_numa_node(struct ena_ring *tx_ring, |
| 1082 | struct ena_ring *rx_ring) | 1103 | struct ena_ring *rx_ring) |
| 1083 | { | 1104 | { |
| @@ -1108,7 +1129,6 @@ static int ena_io_poll(struct napi_struct *napi, int budget) | |||
| 1108 | { | 1129 | { |
| 1109 | struct ena_napi *ena_napi = container_of(napi, struct ena_napi, napi); | 1130 | struct ena_napi *ena_napi = container_of(napi, struct ena_napi, napi); |
| 1110 | struct ena_ring *tx_ring, *rx_ring; | 1131 | struct ena_ring *tx_ring, *rx_ring; |
| 1111 | struct ena_eth_io_intr_reg intr_reg; | ||
| 1112 | 1132 | ||
| 1113 | u32 tx_work_done; | 1133 | u32 tx_work_done; |
| 1114 | u32 rx_work_done; | 1134 | u32 rx_work_done; |
| @@ -1149,22 +1169,9 @@ static int ena_io_poll(struct napi_struct *napi, int budget) | |||
| 1149 | if (ena_com_get_adaptive_moderation_enabled(rx_ring->ena_dev)) | 1169 | if (ena_com_get_adaptive_moderation_enabled(rx_ring->ena_dev)) |
| 1150 | ena_adjust_intr_moderation(rx_ring, tx_ring); | 1170 | ena_adjust_intr_moderation(rx_ring, tx_ring); |
| 1151 | 1171 | ||
| 1152 | /* Update intr register: rx intr delay, | 1172 | ena_unmask_interrupt(tx_ring, rx_ring); |
| 1153 | * tx intr delay and interrupt unmask | ||
| 1154 | */ | ||
| 1155 | ena_com_update_intr_reg(&intr_reg, | ||
| 1156 | rx_ring->smoothed_interval, | ||
| 1157 | tx_ring->smoothed_interval, | ||
| 1158 | true); | ||
| 1159 | |||
| 1160 | /* It is a shared MSI-X. | ||
| 1161 | * Tx and Rx CQ have pointer to it. | ||
| 1162 | * So we use one of them to reach the intr reg | ||
| 1163 | */ | ||
| 1164 | ena_com_unmask_intr(rx_ring->ena_com_io_cq, &intr_reg); | ||
| 1165 | } | 1173 | } |
| 1166 | 1174 | ||
| 1167 | |||
| 1168 | ena_update_ring_numa_node(tx_ring, rx_ring); | 1175 | ena_update_ring_numa_node(tx_ring, rx_ring); |
