diff options
Diffstat (limited to 'drivers/net/ethernet')
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/cmd.c | 11 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/en_cq.c | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/en_netdev.c | 1 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/en_rx.c | 5 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/en_tx.c | 5 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/eq.c | 36 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/fw.c | 30 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/fw.h | 1 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/main.c | 38 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/mlx4_en.h | 1 |
10 files changed, 105 insertions, 25 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx4/cmd.c b/drivers/net/ethernet/mellanox/mlx4/cmd.c index 3d1899ff1076..fdc5f23d8e9f 100644 --- a/drivers/net/ethernet/mellanox/mlx4/cmd.c +++ b/drivers/net/ethernet/mellanox/mlx4/cmd.c | |||
@@ -1498,6 +1498,7 @@ static void mlx4_master_do_cmd(struct mlx4_dev *dev, int slave, u8 cmd, | |||
1498 | u32 reply; | 1498 | u32 reply; |
1499 | u8 is_going_down = 0; | 1499 | u8 is_going_down = 0; |
1500 | int i; | 1500 | int i; |
1501 | unsigned long flags; | ||
1501 | 1502 | ||
1502 | slave_state[slave].comm_toggle ^= 1; | 1503 | slave_state[slave].comm_toggle ^= 1; |
1503 | reply = (u32) slave_state[slave].comm_toggle << 31; | 1504 | reply = (u32) slave_state[slave].comm_toggle << 31; |
@@ -1576,12 +1577,12 @@ static void mlx4_master_do_cmd(struct mlx4_dev *dev, int slave, u8 cmd, | |||
1576 | mlx4_warn(dev, "Bad comm cmd:%d from slave:%d\n", cmd, slave); | 1577 | mlx4_warn(dev, "Bad comm cmd:%d from slave:%d\n", cmd, slave); |
1577 | goto reset_slave; | 1578 | goto reset_slave; |
1578 | } | 1579 | } |
1579 | spin_lock(&priv->mfunc.master.slave_state_lock); | 1580 | spin_lock_irqsave(&priv->mfunc.master.slave_state_lock, flags); |
1580 | if (!slave_state[slave].is_slave_going_down) | 1581 | if (!slave_state[slave].is_slave_going_down) |
1581 | slave_state[slave].last_cmd = cmd; | 1582 | slave_state[slave].last_cmd = cmd; |
1582 | else | 1583 | else |
1583 | is_going_down = 1; | 1584 | is_going_down = 1; |
1584 | spin_unlock(&priv->mfunc.master.slave_state_lock); | 1585 | spin_unlock_irqrestore(&priv->mfunc.master.slave_state_lock, flags); |
1585 | if (is_going_down) { | 1586 | if (is_going_down) { |
1586 | mlx4_warn(dev, "Slave is going down aborting command(%d)" | 1587 | mlx4_warn(dev, "Slave is going down aborting command(%d)" |
1587 | " executing from slave:%d\n", | 1588 | " executing from slave:%d\n", |
@@ -1597,10 +1598,10 @@ static void mlx4_master_do_cmd(struct mlx4_dev *dev, int slave, u8 cmd, | |||
1597 | reset_slave: | 1598 | reset_slave: |
1598 | /* cleanup any slave resources */ | 1599 | /* cleanup any slave resources */ |
1599 | mlx4_delete_all_resources_for_slave(dev, slave); | 1600 | mlx4_delete_all_resources_for_slave(dev, slave); |
1600 | spin_lock(&priv->mfunc.master.slave_state_lock); | 1601 | spin_lock_irqsave(&priv->mfunc.master.slave_state_lock, flags); |
1601 | if (!slave_state[slave].is_slave_going_down) | 1602 | if (!slave_state[slave].is_slave_going_down) |
1602 | slave_state[slave].last_cmd = MLX4_COMM_CMD_RESET; | 1603 | slave_state[slave].last_cmd = MLX4_COMM_CMD_RESET; |
1603 | spin_unlock(&priv->mfunc.master.slave_state_lock); | 1604 | spin_unlock_irqrestore(&priv->mfunc.master.slave_state_lock, flags); |
1604 | /*with slave in the middle of flr, no need to clean resources again.*/ | 1605 | /*with slave in the middle of flr, no need to clean resources again.*/ |
1605 | inform_slave_state: | 1606 | inform_slave_state: |
1606 | memset(&slave_state[slave].event_eq, 0, | 1607 | memset(&slave_state[slave].event_eq, 0, |
@@ -1755,7 +1756,7 @@ int mlx4_multi_func_init(struct mlx4_dev *dev) | |||
1755 | spin_lock_init(&s_state->lock); | 1756 | spin_lock_init(&s_state->lock); |
1756 | } | 1757 | } |
1757 | 1758 | ||
1758 | memset(&priv->mfunc.master.cmd_eqe, 0, sizeof(struct mlx4_eqe)); | 1759 | memset(&priv->mfunc.master.cmd_eqe, 0, dev->caps.eqe_size); |
1759 | priv->mfunc.master.cmd_eqe.type = MLX4_EVENT_TYPE_CMD; | 1760 | priv->mfunc.master.cmd_eqe.type = MLX4_EVENT_TYPE_CMD; |
1760 | INIT_WORK(&priv->mfunc.master.comm_work, | 1761 | INIT_WORK(&priv->mfunc.master.comm_work, |
1761 | mlx4_master_comm_channel); | 1762 | mlx4_master_comm_channel); |
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_cq.c b/drivers/net/ethernet/mellanox/mlx4/en_cq.c index aa9c2f6cf3c0..b8d0854a7ad1 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_cq.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_cq.c | |||
@@ -51,7 +51,7 @@ int mlx4_en_create_cq(struct mlx4_en_priv *priv, | |||
51 | int err; | 51 | int err; |
52 | 52 | ||
53 | cq->size = entries; | 53 | cq->size = entries; |
54 | cq->buf_size = cq->size * sizeof(struct mlx4_cqe); | 54 | cq->buf_size = cq->size * mdev->dev->caps.cqe_size; |
55 | 55 | ||
56 | cq->ring = ring; | 56 | cq->ring = ring; |
57 | cq->is_tx = mode; | 57 | cq->is_tx = mode; |
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c index 7d1287f81a31..75a3f467bb5b 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c | |||
@@ -1604,6 +1604,7 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port, | |||
1604 | goto out; | 1604 | goto out; |
1605 | } | 1605 | } |
1606 | priv->rx_ring_num = prof->rx_ring_num; | 1606 | priv->rx_ring_num = prof->rx_ring_num; |
1607 | priv->cqe_factor = (mdev->dev->caps.cqe_size == 64) ? 1 : 0; | ||
1607 | priv->mac_index = -1; | 1608 | priv->mac_index = -1; |
1608 | priv->msg_enable = MLX4_EN_MSG_LEVEL; | 1609 | priv->msg_enable = MLX4_EN_MSG_LEVEL; |
1609 | spin_lock_init(&priv->stats_lock); | 1610 | spin_lock_init(&priv->stats_lock); |
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_rx.c b/drivers/net/ethernet/mellanox/mlx4/en_rx.c index f76c9671f362..fed26d867f4e 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_rx.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_rx.c | |||
@@ -566,6 +566,7 @@ int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int bud | |||
566 | struct ethhdr *ethh; | 566 | struct ethhdr *ethh; |
567 | dma_addr_t dma; | 567 | dma_addr_t dma; |
568 | u64 s_mac; | 568 | u64 s_mac; |
569 | int factor = priv->cqe_factor; | ||
569 | 570 | ||
570 | if (!priv->port_up) | 571 | if (!priv->port_up) |
571 | return 0; | 572 | return 0; |
@@ -574,7 +575,7 @@ int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int bud | |||
574 | * descriptor offset can be deduced from the CQE index instead of | 575 | * descriptor offset can be deduced from the CQE index instead of |
575 | * reading 'cqe->index' */ | 576 | * reading 'cqe->index' */ |
576 | index = cq->mcq.cons_index & ring->size_mask; | 577 | index = cq->mcq.cons_index & ring->size_mask; |
577 | cqe = &cq->buf[index]; | 578 | cqe = &cq->buf[(index << factor) + factor]; |
578 | 579 | ||
579 | /* Process all completed CQEs */ | 580 | /* Process all completed CQEs */ |
580 | while (XNOR(cqe->owner_sr_opcode & MLX4_CQE_OWNER_MASK, | 581 | while (XNOR(cqe->owner_sr_opcode & MLX4_CQE_OWNER_MASK, |
@@ -709,7 +710,7 @@ next: | |||
709 | 710 | ||
710 | ++cq->mcq.cons_index; | 711 | ++cq->mcq.cons_index; |
711 | index = (cq->mcq.cons_index) & ring->size_mask; | 712 | index = (cq->mcq.cons_index) & ring->size_mask; |
712 | cqe = &cq->buf[index]; | 713 | cqe = &cq->buf[(index << factor) + factor]; |
713 | if (++polled == budget) | 714 | if (++polled == budget) |
714 | goto out; | 715 | goto out; |
715 | } | 716 | } |
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_tx.c b/drivers/net/ethernet/mellanox/mlx4/en_tx.c index 1f571d009155..2b799f4f1c37 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_tx.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_tx.c | |||
@@ -315,12 +315,13 @@ static void mlx4_en_process_tx_cq(struct net_device *dev, struct mlx4_en_cq *cq) | |||
315 | struct mlx4_cqe *buf = cq->buf; | 315 | struct mlx4_cqe *buf = cq->buf; |
316 | u32 packets = 0; | 316 | u32 packets = 0; |
317 | u32 bytes = 0; | 317 | u32 bytes = 0; |
318 | int factor = priv->cqe_factor; | ||
318 | 319 | ||
319 | if (!priv->port_up) | 320 | if (!priv->port_up) |
320 | return; | 321 | return; |
321 | 322 | ||
322 | index = cons_index & size_mask; | 323 | index = cons_index & size_mask; |
323 | cqe = &buf[index]; | 324 | cqe = &buf[(index << factor) + factor]; |
324 | ring_index = ring->cons & size_mask; | 325 | ring_index = ring->cons & size_mask; |
325 | 326 | ||
326 | /* Process all completed CQEs */ | 327 | /* Process all completed CQEs */ |
@@ -349,7 +350,7 @@ static void mlx4_en_process_tx_cq(struct net_device *dev, struct mlx4_en_cq *cq) | |||
349 | 350 | ||
350 | ++cons_index; | 351 | ++cons_index; |
351 | index = cons_index & size_mask; | 352 | index = cons_index & size_mask; |
352 | cqe = &buf[index]; | 353 | cqe = &buf[(index << factor) + factor]; |
353 | } | 354 | } |
354 | 355 | ||
355 | 356 | ||
diff --git a/drivers/net/ethernet/mellanox/mlx4/eq.c b/drivers/net/ethernet/mellanox/mlx4/eq.c index c48cf6f6529c..251ae2f93116 100644 --- a/drivers/net/ethernet/mellanox/mlx4/eq.c +++ b/drivers/net/ethernet/mellanox/mlx4/eq.c | |||
@@ -101,15 +101,21 @@ static void eq_set_ci(struct mlx4_eq *eq, int req_not) | |||
101 | mb(); | 101 | mb(); |
102 | } | 102 | } |
103 | 103 | ||
104 | static struct mlx4_eqe *get_eqe(struct mlx4_eq *eq, u32 entry) | 104 | static struct mlx4_eqe *get_eqe(struct mlx4_eq *eq, u32 entry, u8 eqe_factor) |
105 | { | 105 | { |
106 | unsigned long off = (entry & (eq->nent - 1)) * MLX4_EQ_ENTRY_SIZE; | 106 | /* (entry & (eq->nent - 1)) gives us a cyclic array */ |
107 | return eq->page_list[off / PAGE_SIZE].buf + off % PAGE_SIZE; | 107 | unsigned long offset = (entry & (eq->nent - 1)) * (MLX4_EQ_ENTRY_SIZE << eqe_factor); |
108 | /* CX3 is capable of extending the EQE from 32 to 64 bytes. | ||
109 | * When this feature is enabled, the first (in the lower addresses) | ||
110 | * 32 bytes in the 64 byte EQE are reserved and the next 32 bytes | ||
111 | * contain the legacy EQE information. | ||
112 | */ | ||
113 | return eq->page_list[offset / PAGE_SIZE].buf + (offset + (eqe_factor ? MLX4_EQ_ENTRY_SIZE : 0)) % PAGE_SIZE; | ||
108 | } | 114 | } |
109 | 115 | ||
110 | static struct mlx4_eqe *next_eqe_sw(struct mlx4_eq *eq) | 116 | static struct mlx4_eqe *next_eqe_sw(struct mlx4_eq *eq, u8 eqe_factor) |
111 | { | 117 | { |
112 | struct mlx4_eqe *eqe = get_eqe(eq, eq->cons_index); | 118 | struct mlx4_eqe *eqe = get_eqe(eq, eq->cons_index, eqe_factor); |
113 | return !!(eqe->owner & 0x80) ^ !!(eq->cons_index & eq->nent) ? NULL : eqe; | 119 | return !!(eqe->owner & 0x80) ^ !!(eq->cons_index & eq->nent) ? NULL : eqe; |
114 | } | 120 | } |
115 | 121 | ||
@@ -177,7 +183,7 @@ static void slave_event(struct mlx4_dev *dev, u8 slave, struct mlx4_eqe *eqe) | |||
177 | return; | 183 | return; |
178 | } | 184 | } |
179 | 185 | ||
180 | memcpy(s_eqe, eqe, sizeof(struct mlx4_eqe) - 1); | 186 | memcpy(s_eqe, eqe, dev->caps.eqe_size - 1); |
181 | s_eqe->slave_id = slave; | 187 | s_eqe->slave_id = slave; |
182 | /* ensure all information is written before setting the ownersip bit */ | 188 | /* ensure all information is written before setting the ownersip bit */ |
183 | wmb(); | 189 | wmb(); |
@@ -401,6 +407,7 @@ void mlx4_master_handle_slave_flr(struct work_struct *work) | |||
401 | struct mlx4_slave_state *slave_state = priv->mfunc.master.slave_state; | 407 | struct mlx4_slave_state *slave_state = priv->mfunc.master.slave_state; |
402 | int i; | 408 | int i; |
403 | int err; | 409 | int err; |
410 | unsigned long flags; | ||
404 | 411 | ||
405 | mlx4_dbg(dev, "mlx4_handle_slave_flr\n"); | 412 | mlx4_dbg(dev, "mlx4_handle_slave_flr\n"); |
406 | 413 | ||
@@ -412,10 +419,10 @@ void mlx4_master_handle_slave_flr(struct work_struct *work) | |||
412 | 419 | ||
413 | mlx4_delete_all_resources_for_slave(dev, i); | 420 | mlx4_delete_all_resources_for_slave(dev, i); |
414 | /*return the slave to running mode*/ | 421 | /*return the slave to running mode*/ |
415 | spin_lock(&priv->mfunc.master.slave_state_lock); | 422 | spin_lock_irqsave(&priv->mfunc.master.slave_state_lock, flags); |
416 | slave_state[i].last_cmd = MLX4_COMM_CMD_RESET; | 423 | slave_state[i].last_cmd = MLX4_COMM_CMD_RESET; |
417 | slave_state[i].is_slave_going_down = 0; | 424 | slave_state[i].is_slave_going_down = 0; |
418 | spin_unlock(&priv->mfunc.master.slave_state_lock); | 425 | spin_unlock_irqrestore(&priv->mfunc.master.slave_state_lock, flags); |
419 | /*notify the FW:*/ | 426 | /*notify the FW:*/ |
420 | err = mlx4_cmd(dev, 0, i, 0, MLX4_CMD_INFORM_FLR_DONE, | 427 | err = mlx4_cmd(dev, 0, i, 0, MLX4_CMD_INFORM_FLR_DONE, |
421 | MLX4_CMD_TIME_CLASS_A, MLX4_CMD_WRAPPED); | 428 | MLX4_CMD_TIME_CLASS_A, MLX4_CMD_WRAPPED); |
@@ -440,8 +447,9 @@ static int mlx4_eq_int(struct mlx4_dev *dev, struct mlx4_eq *eq) | |||
440 | u8 update_slave_state; | 447 | u8 update_slave_state; |
441 | int i; | 448 | int i; |
442 | enum slave_port_gen_event gen_event; | 449 | enum slave_port_gen_event gen_event; |
450 | unsigned long flags; | ||
443 | 451 | ||
444 | while ((eqe = next_eqe_sw(eq))) { | 452 | while ((eqe = next_eqe_sw(eq, dev->caps.eqe_factor))) { |
445 | /* | 453 | /* |
446 | * Make sure we read EQ entry contents after we've | 454 | * Make sure we read EQ entry contents after we've |
447 | * checked the ownership bit. | 455 | * checked the ownership bit. |
@@ -647,13 +655,13 @@ static int mlx4_eq_int(struct mlx4_dev *dev, struct mlx4_eq *eq) | |||
647 | } else | 655 | } else |
648 | update_slave_state = 1; | 656 | update_slave_state = 1; |
649 | 657 | ||
650 | spin_lock(&priv->mfunc.master.slave_state_lock); | 658 | spin_lock_irqsave(&priv->mfunc.master.slave_state_lock, flags); |
651 | if (update_slave_state) { | 659 | if (update_slave_state) { |
652 | priv->mfunc.master.slave_state[flr_slave].active = false; | 660 | priv->mfunc.master.slave_state[flr_slave].active = false; |
653 | priv->mfunc.master.slave_state[flr_slave].last_cmd = MLX4_COMM_CMD_FLR; | 661 | priv->mfunc.master.slave_state[flr_slave].last_cmd = MLX4_COMM_CMD_FLR; |
654 | priv->mfunc.master.slave_state[flr_slave].is_slave_going_down = 1; | 662 | priv->mfunc.master.slave_state[flr_slave].is_slave_going_down = 1; |
655 | } | 663 | } |
656 | spin_unlock(&priv->mfunc.master.slave_state_lock); | 664 | spin_unlock_irqrestore(&priv->mfunc.master.slave_state_lock, flags); |
657 | queue_work(priv->mfunc.master.comm_wq, | 665 | queue_work(priv->mfunc.master.comm_wq, |
658 | &priv->mfunc.master.slave_flr_event_work); | 666 | &priv->mfunc.master.slave_flr_event_work); |
659 | break; | 667 | break; |
@@ -864,7 +872,8 @@ static int mlx4_create_eq(struct mlx4_dev *dev, int nent, | |||
864 | 872 | ||
865 | eq->dev = dev; | 873 | eq->dev = dev; |
866 | eq->nent = roundup_pow_of_two(max(nent, 2)); | 874 | eq->nent = roundup_pow_of_two(max(nent, 2)); |
867 | npages = PAGE_ALIGN(eq->nent * MLX4_EQ_ENTRY_SIZE) / PAGE_SIZE; | 875 | /* CX3 is capable of extending the CQE/EQE from 32 to 64 bytes */ |
876 | npages = PAGE_ALIGN(eq->nent * (MLX4_EQ_ENTRY_SIZE << dev->caps.eqe_factor)) / PAGE_SIZE; | ||
868 | 877 | ||
869 | eq->page_list = kmalloc(npages * sizeof *eq->page_list, | 878 | eq->page_list = kmalloc(npages * sizeof *eq->page_list, |
870 | GFP_KERNEL); | 879 | GFP_KERNEL); |
@@ -966,8 +975,9 @@ static void mlx4_free_eq(struct mlx4_dev *dev, | |||
966 | struct mlx4_priv *priv = mlx4_priv(dev); | 975 | struct mlx4_priv *priv = mlx4_priv(dev); |
967 | struct mlx4_cmd_mailbox *mailbox; | 976 | struct mlx4_cmd_mailbox *mailbox; |
968 | int err; | 977 | int err; |
969 | int npages = PAGE_ALIGN(MLX4_EQ_ENTRY_SIZE * eq->nent) / PAGE_SIZE; | ||
970 | int i; | 978 | int i; |
979 | /* CX3 is capable of extending the CQE/EQE from 32 to 64 bytes */ | ||
980 | int npages = PAGE_ALIGN((MLX4_EQ_ENTRY_SIZE << dev->caps.eqe_factor) * eq->nent) / PAGE_SIZE; | ||
971 | 981 | ||
972 | mailbox = mlx4_alloc_cmd_mailbox(dev); | 982 | mailbox = mlx4_alloc_cmd_mailbox(dev); |
973 | if (IS_ERR(mailbox)) | 983 | if (IS_ERR(mailbox)) |
diff --git a/drivers/net/ethernet/mellanox/mlx4/fw.c b/drivers/net/ethernet/mellanox/mlx4/fw.c index 4f30b99324cf..9a9de51ecc91 100644 --- a/drivers/net/ethernet/mellanox/mlx4/fw.c +++ b/drivers/net/ethernet/mellanox/mlx4/fw.c | |||
@@ -110,6 +110,8 @@ static void dump_dev_cap_flags(struct mlx4_dev *dev, u64 flags) | |||
110 | [42] = "Multicast VEP steering support", | 110 | [42] = "Multicast VEP steering support", |
111 | [48] = "Counters support", | 111 | [48] = "Counters support", |
112 | [59] = "Port management change event support", | 112 | [59] = "Port management change event support", |
113 | [61] = "64 byte EQE support", | ||
114 | [62] = "64 byte CQE support", | ||
113 | }; | 115 | }; |
114 | int i; | 116 | int i; |
115 | 117 | ||
@@ -235,7 +237,7 @@ int mlx4_QUERY_FUNC_CAP_wrapper(struct mlx4_dev *dev, int slave, | |||
235 | field = dev->caps.num_ports; | 237 | field = dev->caps.num_ports; |
236 | MLX4_PUT(outbox->buf, field, QUERY_FUNC_CAP_NUM_PORTS_OFFSET); | 238 | MLX4_PUT(outbox->buf, field, QUERY_FUNC_CAP_NUM_PORTS_OFFSET); |
237 | 239 | ||
238 | size = 0; /* no PF behaviour is set for now */ | 240 | size = dev->caps.function_caps; /* set PF behaviours */ |
239 | MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_PF_BHVR_OFFSET); | 241 | MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_PF_BHVR_OFFSET); |
240 | 242 | ||
241 | field = 0; /* protected FMR support not available as yet */ | 243 | field = 0; /* protected FMR support not available as yet */ |
@@ -1237,6 +1239,24 @@ int mlx4_INIT_HCA(struct mlx4_dev *dev, struct mlx4_init_hca_param *param) | |||
1237 | if (dev->caps.flags & MLX4_DEV_CAP_FLAG_COUNTERS) | 1239 | if (dev->caps.flags & MLX4_DEV_CAP_FLAG_COUNTERS) |
1238 | *(inbox + INIT_HCA_FLAGS_OFFSET / 4) |= cpu_to_be32(1 << 4); | 1240 | *(inbox + INIT_HCA_FLAGS_OFFSET / 4) |= cpu_to_be32(1 << 4); |
1239 | 1241 | ||
1242 | /* CX3 is capable of extending CQEs/EQEs from 32 to 64 bytes */ | ||
1243 | if (dev->caps.flags & MLX4_DEV_CAP_FLAG_64B_EQE) { | ||
1244 | *(inbox + INIT_HCA_EQE_CQE_OFFSETS / 4) |= cpu_to_be32(1 << 29); | ||
1245 | dev->caps.eqe_size = 64; | ||
1246 | dev->caps.eqe_factor = 1; | ||
1247 | } else { | ||
1248 | dev->caps.eqe_size = 32; | ||
1249 | dev->caps.eqe_factor = 0; | ||
1250 | } | ||
1251 | |||
1252 | if (dev->caps.flags & MLX4_DEV_CAP_FLAG_64B_CQE) { | ||
1253 | *(inbox + INIT_HCA_EQE_CQE_OFFSETS / 4) |= cpu_to_be32(1 << 30); | ||
1254 | dev->caps.cqe_size = 64; | ||
1255 | dev->caps.userspace_caps |= MLX4_USER_DEV_CAP_64B_CQE; | ||
1256 | } else { | ||
1257 | dev->caps.cqe_size = 32; | ||
1258 | } | ||
1259 | |||
1240 | /* QPC/EEC/CQC/EQC/RDMARC attributes */ | 1260 | /* QPC/EEC/CQC/EQC/RDMARC attributes */ |
1241 | 1261 | ||
1242 | MLX4_PUT(inbox, param->qpc_base, INIT_HCA_QPC_BASE_OFFSET); | 1262 | MLX4_PUT(inbox, param->qpc_base, INIT_HCA_QPC_BASE_OFFSET); |
@@ -1319,6 +1339,7 @@ int mlx4_QUERY_HCA(struct mlx4_dev *dev, | |||
1319 | struct mlx4_cmd_mailbox *mailbox; | 1339 | struct mlx4_cmd_mailbox *mailbox; |
1320 | __be32 *outbox; | 1340 | __be32 *outbox; |
1321 | int err; | 1341 | int err; |
1342 | u8 byte_field; | ||
1322 | 1343 | ||
1323 | #define QUERY_HCA_GLOBAL_CAPS_OFFSET 0x04 | 1344 | #define QUERY_HCA_GLOBAL_CAPS_OFFSET 0x04 |
1324 | 1345 | ||
@@ -1370,6 +1391,13 @@ int mlx4_QUERY_HCA(struct mlx4_dev *dev, | |||
1370 | INIT_HCA_LOG_MC_TABLE_SZ_OFFSET); | 1391 | INIT_HCA_LOG_MC_TABLE_SZ_OFFSET); |
1371 | } | 1392 | } |
1372 | 1393 | ||
1394 | /* CX3 is capable of extending CQEs/EQEs from 32 to 64 bytes */ | ||
1395 | MLX4_GET(byte_field, outbox, INIT_HCA_EQE_CQE_OFFSETS); | ||
1396 | if (byte_field & 0x20) /* 64-bytes eqe enabled */ | ||
1397 | param->dev_cap_enabled |= MLX4_DEV_CAP_64B_EQE_ENABLED; | ||
1398 | if (byte_field & 0x40) /* 64-bytes cqe enabled */ | ||
1399 | param->dev_cap_enabled |= MLX4_DEV_CAP_64B_CQE_ENABLED; | ||
1400 | |||
1373 | /* TPT attributes */ | 1401 | /* TPT attributes */ |
1374 | 1402 | ||
1375 | MLX4_GET(param->dmpt_base, outbox, INIT_HCA_DMPT_BASE_OFFSET); | 1403 | MLX4_GET(param->dmpt_base, outbox, INIT_HCA_DMPT_BASE_OFFSET); |
diff --git a/drivers/net/ethernet/mellanox/mlx4/fw.h b/drivers/net/ethernet/mellanox/mlx4/fw.h index 85abe9c11a22..2c2e7ade2a34 100644 --- a/drivers/net/ethernet/mellanox/mlx4/fw.h +++ b/drivers/net/ethernet/mellanox/mlx4/fw.h | |||
@@ -172,6 +172,7 @@ struct mlx4_init_hca_param { | |||
172 | u8 log_uar_sz; | 172 | u8 log_uar_sz; |
173 | u8 uar_page_sz; /* log pg sz in 4k chunks */ | 173 | u8 uar_page_sz; /* log pg sz in 4k chunks */ |
174 | u8 fs_hash_enable_bits; | 174 | u8 fs_hash_enable_bits; |
175 | u64 dev_cap_enabled; | ||
175 | }; | 176 | }; |
176 | 177 | ||
177 | struct mlx4_init_ib_param { | 178 | struct mlx4_init_ib_param { |
diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c index 200cc0ec8052..b2acbe7706a3 100644 --- a/drivers/net/ethernet/mellanox/mlx4/main.c +++ b/drivers/net/ethernet/mellanox/mlx4/main.c | |||
@@ -95,8 +95,14 @@ MODULE_PARM_DESC(log_num_mgm_entry_size, "log mgm size, that defines the num" | |||
95 | " Not in use with device managed" | 95 | " Not in use with device managed" |
96 | " flow steering"); | 96 | " flow steering"); |
97 | 97 | ||
98 | static bool enable_64b_cqe_eqe; | ||
99 | module_param(enable_64b_cqe_eqe, bool, 0444); | ||
100 | MODULE_PARM_DESC(enable_64b_cqe_eqe, | ||
101 | "Enable 64 byte CQEs/EQEs when the the FW supports this"); | ||
102 | |||
98 | #define HCA_GLOBAL_CAP_MASK 0 | 103 | #define HCA_GLOBAL_CAP_MASK 0 |
99 | #define PF_CONTEXT_BEHAVIOUR_MASK 0 | 104 | |
105 | #define PF_CONTEXT_BEHAVIOUR_MASK MLX4_FUNC_CAP_64B_EQE_CQE | ||
100 | 106 | ||
101 | static char mlx4_version[] = | 107 | static char mlx4_version[] = |
102 | DRV_NAME ": Mellanox ConnectX core driver v" | 108 | DRV_NAME ": Mellanox ConnectX core driver v" |
@@ -386,6 +392,21 @@ static int mlx4_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) | |||
386 | dev->caps.reserved_qps_cnt[MLX4_QP_REGION_FC_EXCH]; | 392 | dev->caps.reserved_qps_cnt[MLX4_QP_REGION_FC_EXCH]; |
387 | 393 | ||
388 | dev->caps.sqp_demux = (mlx4_is_master(dev)) ? MLX4_MAX_NUM_SLAVES : 0; | 394 | dev->caps.sqp_demux = (mlx4_is_master(dev)) ? MLX4_MAX_NUM_SLAVES : 0; |
395 | |||
396 | if (!enable_64b_cqe_eqe) { | ||
397 | if (dev_cap->flags & | ||
398 | (MLX4_DEV_CAP_FLAG_64B_CQE | MLX4_DEV_CAP_FLAG_64B_EQE)) { | ||
399 | mlx4_warn(dev, "64B EQEs/CQEs supported by the device but not enabled\n"); | ||
400 | dev->caps.flags &= ~MLX4_DEV_CAP_FLAG_64B_CQE; | ||
401 | dev->caps.flags &= ~MLX4_DEV_CAP_FLAG_64B_EQE; | ||
402 | } | ||
403 | } | ||
404 | |||
405 | if ((dev_cap->flags & | ||
406 | (MLX4_DEV_CAP_FLAG_64B_CQE | MLX4_DEV_CAP_FLAG_64B_EQE)) && | ||
407 | mlx4_is_master(dev)) | ||
408 | dev->caps.function_caps |= MLX4_FUNC_CAP_64B_EQE_CQE; | ||
409 | |||
389 | return 0; | 410 | return 0; |
390 | } | 411 | } |
391 | /*The function checks if there are live vf, return the num of them*/ | 412 | /*The function checks if there are live vf, return the num of them*/ |
@@ -599,6 +620,21 @@ static int mlx4_slave_cap(struct mlx4_dev *dev) | |||
599 | goto err_mem; | 620 | goto err_mem; |
600 | } | 621 | } |
601 | 622 | ||
623 | if (hca_param.dev_cap_enabled & MLX4_DEV_CAP_64B_EQE_ENABLED) { | ||
624 | dev->caps.eqe_size = 64; | ||
625 | dev->caps.eqe_factor = 1; | ||
626 | } else { | ||
627 | dev->caps.eqe_size = 32; | ||
628 | dev->caps.eqe_factor = 0; | ||
629 | } | ||
630 | |||
631 | if (hca_param.dev_cap_enabled & MLX4_DEV_CAP_64B_CQE_ENABLED) { | ||
632 | dev->caps.cqe_size = 64; | ||
633 | dev->caps.userspace_caps |= MLX4_USER_DEV_CAP_64B_CQE; | ||
634 | } else { | ||
635 | dev->caps.cqe_size = 32; | ||
636 | } | ||
637 | |||
602 | return 0; | 638 | return 0; |
603 | 639 | ||
604 | err_mem: | 640 | err_mem: |
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h index 334ec483480b..8d54412ada63 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h +++ b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h | |||
@@ -473,6 +473,7 @@ struct mlx4_en_priv { | |||
473 | int mac_index; | 473 | int mac_index; |
474 | unsigned max_mtu; | 474 | unsigned max_mtu; |
475 | int base_qpn; | 475 | int base_qpn; |
476 | int cqe_factor; | ||
476 | 477 | ||
477 | struct mlx4_en_rss_map rss_map; | 478 | struct mlx4_en_rss_map rss_map; |
478 | __be32 ctrl_flags; | 479 | __be32 ctrl_flags; |