]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/blobdiff - drivers/net/ethernet/amazon/ena/ena_com.c
UBUNTU: Ubuntu-4.10.0-37.41
[mirror_ubuntu-zesty-kernel.git] / drivers / net / ethernet / amazon / ena / ena_com.c
index 02752d5b5b601162e45d401fdb68095e3c8258e6..52beba8c7a39990d3a9d6fb5910c689905a3a6a9 100644 (file)
@@ -99,8 +99,8 @@ static inline int ena_com_mem_addr_set(struct ena_com_dev *ena_dev,
                return -EINVAL;
        }
 
-       ena_addr->mem_addr_low = (u32)addr;
-       ena_addr->mem_addr_high = (u64)addr >> 32;
+       ena_addr->mem_addr_low = lower_32_bits(addr);
+       ena_addr->mem_addr_high = (u16)upper_32_bits(addr);
 
        return 0;
 }
@@ -329,7 +329,7 @@ static int ena_com_init_io_sq(struct ena_com_dev *ena_dev,
        size_t size;
        int dev_node = 0;
 
-       memset(&io_sq->desc_addr, 0x0, sizeof(struct ena_com_io_desc_addr));
+       memset(&io_sq->desc_addr, 0x0, sizeof(io_sq->desc_addr));
 
        io_sq->desc_entry_size =
                (io_sq->direction == ENA_COM_IO_QUEUE_DIRECTION_TX) ?
@@ -383,7 +383,7 @@ static int ena_com_init_io_cq(struct ena_com_dev *ena_dev,
        size_t size;
        int prev_node = 0;
 
-       memset(&io_cq->cdesc_addr, 0x0, sizeof(struct ena_com_io_desc_addr));
+       memset(&io_cq->cdesc_addr, 0x0, sizeof(io_cq->cdesc_addr));
 
        /* Use the basic completion descriptor for Rx */
        io_cq->cdesc_entry_size_in_bytes =
@@ -511,7 +511,7 @@ static int ena_com_wait_and_process_admin_cq_polling(struct ena_comp_ctx *comp_c
        unsigned long flags, timeout;
        int ret;
 
-       timeout = jiffies + ADMIN_CMD_TIMEOUT_US;
+       timeout = jiffies + usecs_to_jiffies(admin_queue->completion_timeout);
 
        while (1) {
                spin_lock_irqsave(&admin_queue->q_lock, flags);
@@ -561,7 +561,8 @@ static int ena_com_wait_and_process_admin_cq_interrupts(struct ena_comp_ctx *com
        int ret;
 
        wait_for_completion_timeout(&comp_ctx->wait_event,
-                                   usecs_to_jiffies(ADMIN_CMD_TIMEOUT_US));
+                                   usecs_to_jiffies(
+                                           admin_queue->completion_timeout));
 
        /* In case the command wasn't completed find out the root cause.
         * There might be 2 kinds of errors
@@ -601,12 +602,15 @@ static u32 ena_com_reg_bar_read32(struct ena_com_dev *ena_dev, u16 offset)
        struct ena_com_mmio_read *mmio_read = &ena_dev->mmio_read;
        volatile struct ena_admin_ena_mmio_req_read_less_resp *read_resp =
                mmio_read->read_resp;
-       u32 mmio_read_reg, ret;
+       u32 mmio_read_reg, ret, i;
        unsigned long flags;
-       int i;
+       u32 timeout = mmio_read->reg_read_to;
 
        might_sleep();
 
+       if (timeout == 0)
+               timeout = ENA_REG_READ_TIMEOUT;
+
        /* If readless is disabled, perform regular read */
        if (!mmio_read->readless_supported)
                return readl(ena_dev->reg_bar + offset);
@@ -627,14 +631,14 @@ static u32 ena_com_reg_bar_read32(struct ena_com_dev *ena_dev, u16 offset)
 
        writel(mmio_read_reg, ena_dev->reg_bar + ENA_REGS_MMIO_REG_READ_OFF);
 
-       for (i = 0; i < ENA_REG_READ_TIMEOUT; i++) {
+       for (i = 0; i < timeout; i++) {
                if (read_resp->req_id == mmio_read->seq_num)
                        break;
 
                udelay(1);
        }
 
-       if (unlikely(i == ENA_REG_READ_TIMEOUT)) {
+       if (unlikely(i == timeout)) {
                pr_err("reading reg failed for timeout. expected: req id[%hu] offset[%hu] actual: req id[%hu] offset[%hu]\n",
                       mmio_read->seq_num, offset, read_resp->req_id,
                       read_resp->reg_off);
@@ -681,7 +685,7 @@ static int ena_com_destroy_io_sq(struct ena_com_dev *ena_dev,
        u8 direction;
        int ret;
 
-       memset(&destroy_cmd, 0x0, sizeof(struct ena_admin_aq_destroy_sq_cmd));
+       memset(&destroy_cmd, 0x0, sizeof(destroy_cmd));
 
        if (io_sq->direction == ENA_COM_IO_QUEUE_DIRECTION_TX)
                direction = ENA_ADMIN_SQ_DIRECTION_TX;
@@ -963,7 +967,7 @@ static int ena_com_create_io_sq(struct ena_com_dev *ena_dev,
        u8 direction;
        int ret;
 
-       memset(&create_cmd, 0x0, sizeof(struct ena_admin_aq_create_sq_cmd));
+       memset(&create_cmd, 0x0, sizeof(create_cmd));
 
        create_cmd.aq_common_descriptor.opcode = ENA_ADMIN_CREATE_SQ;
 
@@ -1155,7 +1159,7 @@ int ena_com_create_io_cq(struct ena_com_dev *ena_dev,
        struct ena_admin_acq_create_cq_resp_desc cmd_completion;
        int ret;
 
-       memset(&create_cmd, 0x0, sizeof(struct ena_admin_aq_create_cq_cmd));
+       memset(&create_cmd, 0x0, sizeof(create_cmd));
 
        create_cmd.aq_common_descriptor.opcode = ENA_ADMIN_CREATE_CQ;
 
@@ -1263,7 +1267,7 @@ int ena_com_destroy_io_cq(struct ena_com_dev *ena_dev,
        struct ena_admin_acq_destroy_cq_resp_desc destroy_resp;
        int ret;
 
-       memset(&destroy_cmd, 0x0, sizeof(struct ena_admin_aq_destroy_sq_cmd));
+       memset(&destroy_cmd, 0x0, sizeof(destroy_cmd));
 
        destroy_cmd.cq_idx = io_cq->idx;
        destroy_cmd.aq_common_descriptor.opcode = ENA_ADMIN_DESTROY_CQ;
@@ -1619,8 +1623,8 @@ int ena_com_create_io_queue(struct ena_com_dev *ena_dev,
        io_sq = &ena_dev->io_sq_queues[ctx->qid];
        io_cq = &ena_dev->io_cq_queues[ctx->qid];
 
-       memset(io_sq, 0x0, sizeof(struct ena_com_io_sq));
-       memset(io_cq, 0x0, sizeof(struct ena_com_io_cq));
+       memset(io_sq, 0x0, sizeof(*io_sq));
+       memset(io_cq, 0x0, sizeof(*io_cq));
 
        /* Init CQ */
        io_cq->q_depth = ctx->queue_size;
@@ -1730,6 +1734,20 @@ int ena_com_get_dev_attr_feat(struct ena_com_dev *ena_dev,
        memcpy(&get_feat_ctx->offload, &get_resp.u.offload,
               sizeof(get_resp.u.offload));
 
+       /* Driver hints isn't mandatory admin command. So in case the
+        * command isn't supported set driver hints to 0
+        */
+       rc = ena_com_get_feature(ena_dev, &get_resp, ENA_ADMIN_HW_HINTS);
+
+       if (!rc)
+               memcpy(&get_feat_ctx->hw_hints, &get_resp.u.hw_hints,
+                      sizeof(get_resp.u.hw_hints));
+       else if (rc == -EOPNOTSUPP)
+               memset(&get_feat_ctx->hw_hints, 0x0,
+                      sizeof(get_feat_ctx->hw_hints));
+       else
+               return rc;
+
        return 0;
 }
 
@@ -1807,7 +1825,8 @@ void ena_com_aenq_intr_handler(struct ena_com_dev *dev, void *data)
        writel((u32)aenq->head, dev->reg_bar + ENA_REGS_AENQ_HEAD_DB_OFF);
 }
 
-int ena_com_dev_reset(struct ena_com_dev *ena_dev)
+int ena_com_dev_reset(struct ena_com_dev *ena_dev,
+                     enum ena_regs_reset_reason_types reset_reason)
 {
        u32 stat, timeout, cap, reset_val;
        int rc;
@@ -1835,6 +1854,8 @@ int ena_com_dev_reset(struct ena_com_dev *ena_dev)
 
        /* start reset */
        reset_val = ENA_REGS_DEV_CTL_DEV_RESET_MASK;
+       reset_val |= (reset_reason << ENA_REGS_DEV_CTL_RESET_REASON_SHIFT) &
+                    ENA_REGS_DEV_CTL_RESET_REASON_MASK;
        writel(reset_val, ena_dev->reg_bar + ENA_REGS_DEV_CTL_OFF);
 
        /* Write again the MMIO read request address */
@@ -1855,6 +1876,14 @@ int ena_com_dev_reset(struct ena_com_dev *ena_dev)
                return rc;
        }
 
+       timeout = (cap & ENA_REGS_CAPS_ADMIN_CMD_TO_MASK) >>
+               ENA_REGS_CAPS_ADMIN_CMD_TO_SHIFT;
+       if (timeout)
+               /* the resolution of timeout reg is 100ms */
+               ena_dev->admin_queue.completion_timeout = timeout * 100000;
+       else
+               ena_dev->admin_queue.completion_timeout = ADMIN_CMD_TIMEOUT_US;
+
        return 0;
 }