* [PATCH v2 net-next 7/8] qed: Call rx_release_cb() when flushing LL2
From: Yuval Mintz @ 2017-06-09 14:13 UTC (permalink / raw)
To: netdev, davem; +Cc: linux-rdma, Michal.Kalderon, Yuval Mintz
In-Reply-To: <20170609141325.20547-1-Yuval.Mintz@cavium.com>
Driver to inform the connection owner that the its buffers are being
released as part of a flush.
Signed-off-by: Yuval Mintz <Yuval.Mintz@cavium.com>
---
drivers/net/ethernet/qlogic/qed/qed_ll2.c | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/drivers/net/ethernet/qlogic/qed/qed_ll2.c b/drivers/net/ethernet/qlogic/qed/qed_ll2.c
index 2a68fb9..c6172a77e 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_ll2.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_ll2.c
@@ -525,10 +525,6 @@ static void qed_ll2_rxq_flush(struct qed_hwfn *p_hwfn, u8 connection_handle)
p_rx = &p_ll2_conn->rx_queue;
while (!list_empty(&p_rx->active_descq)) {
- dma_addr_t rx_buf_addr;
- void *cookie;
- bool b_last;
-
p_pkt = list_first_entry(&p_rx->active_descq,
struct qed_ll2_rx_packet, list_entry);
if (!p_pkt)
@@ -543,10 +539,15 @@ static void qed_ll2_rxq_flush(struct qed_hwfn *p_hwfn, u8 connection_handle)
qed_ooo_put_free_buffer(p_hwfn, p_hwfn->p_ooo_info,
p_buffer);
} else {
- rx_buf_addr = p_pkt->rx_buf_addr;
- cookie = p_pkt->cookie;
+ dma_addr_t rx_buf_addr = p_pkt->rx_buf_addr;
+ void *cookie = p_pkt->cookie;
+ bool b_last;
b_last = list_empty(&p_rx->active_descq);
+ p_ll2_conn->cbs.rx_release_cb(p_ll2_conn->cbs.cookie,
+ p_ll2_conn->my_id,
+ cookie,
+ rx_buf_addr, b_last);
}
}
}
--
2.9.4
^ permalink raw reply related
* [PATCH v2 net-next 6/8] qed: No need for LL2 frags indication
From: Yuval Mintz @ 2017-06-09 14:13 UTC (permalink / raw)
To: netdev, davem; +Cc: linux-rdma, Michal.Kalderon, Yuval Mintz
In-Reply-To: <20170609141325.20547-1-Yuval.Mintz@cavium.com>
This is a legacy leftover; There's no current flow where 'frags_mapped'
would be set.
Signed-off-by: Yuval Mintz <Yuval.Mintz@cavium.com>
---
drivers/net/ethernet/qlogic/qed/qed_ll2.c | 31 ++++++++-----------------------
1 file changed, 8 insertions(+), 23 deletions(-)
diff --git a/drivers/net/ethernet/qlogic/qed/qed_ll2.c b/drivers/net/ethernet/qlogic/qed/qed_ll2.c
index b222b2b..2a68fb9 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_ll2.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_ll2.c
@@ -73,7 +73,6 @@ struct qed_cb_ll2_info {
int rx_cnt;
u32 rx_size;
u8 handle;
- bool frags_mapped;
/* Lock protecting LL2 buffer lists in sleepless context */
spinlock_t lock;
@@ -108,12 +107,6 @@ static void qed_ll2b_complete_tx_packet(void *cxt,
cdev->ll2->cbs->tx_cb(cdev->ll2->cb_cookie, skb,
b_last_fragment);
- if (cdev->ll2->frags_mapped)
- /* Case where mapped frags were received, need to
- * free skb with nr_frags marked as 0
- */
- skb_shinfo(skb)->nr_frags = 0;
-
dev_kfree_skb_any(skb);
}
@@ -2100,7 +2093,6 @@ static int qed_ll2_start(struct qed_dev *cdev, struct qed_ll2_params *params)
spin_lock_init(&cdev->ll2->lock);
cdev->ll2->rx_size = NET_SKB_PAD + ETH_HLEN +
L1_CACHE_BYTES + params->mtu;
- cdev->ll2->frags_mapped = params->frags_mapped;
/*Allocate memory for LL2 */
DP_INFO(cdev, "Allocating LL2 buffers of size %08x bytes\n",
@@ -2313,21 +2305,14 @@ static int qed_ll2_start_xmit(struct qed_dev *cdev, struct sk_buff *skb)
for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
frag = &skb_shinfo(skb)->frags[i];
- if (!cdev->ll2->frags_mapped) {
- mapping = skb_frag_dma_map(&cdev->pdev->dev, frag, 0,
- skb_frag_size(frag),
- DMA_TO_DEVICE);
-
- if (unlikely(dma_mapping_error(&cdev->pdev->dev,
- mapping))) {
- DP_NOTICE(cdev,
- "Unable to map frag - dropping packet\n");
- rc = -ENOMEM;
- goto err;
- }
- } else {
- mapping = page_to_phys(skb_frag_page(frag)) |
- frag->page_offset;
+
+ mapping = skb_frag_dma_map(&cdev->pdev->dev, frag, 0,
+ skb_frag_size(frag), DMA_TO_DEVICE);
+
+ if (unlikely(dma_mapping_error(&cdev->pdev->dev, mapping))) {
+ DP_NOTICE(cdev,
+ "Unable to map frag - dropping packet\n");
+ goto err;
}
rc = qed_ll2_set_fragment_of_tx_packet(QED_LEADING_HWFN(cdev),
--
2.9.4
^ permalink raw reply related
* [PATCH v2 net-next 3/8] qed: Cleaner seperation of LL2 inputs
From: Yuval Mintz @ 2017-06-09 14:13 UTC (permalink / raw)
To: netdev, davem; +Cc: linux-rdma, Michal.Kalderon, Yuval Mintz
In-Reply-To: <20170609141325.20547-1-Yuval.Mintz@cavium.com>
A LL2 connection [qed_ll2_info] has a sub-structure of type qed_ll2_conn
that contain various inputs for ll2 acquisition, but the connection also
utilizes a couple of other inputs.
Restructure the input structure to include all the inputs and refactor
the code necessary to populate those.
Signed-off-by: Yuval Mintz <Yuval.Mintz@cavium.com>
---
drivers/net/ethernet/qlogic/qed/qed_ll2.c | 379 +++++++++++++++--------------
drivers/net/ethernet/qlogic/qed/qed_ll2.h | 42 +---
drivers/net/ethernet/qlogic/qed/qed_roce.c | 31 +--
include/linux/qed/qed_ll2_if.h | 39 +++
4 files changed, 262 insertions(+), 229 deletions(-)
diff --git a/drivers/net/ethernet/qlogic/qed/qed_ll2.c b/drivers/net/ethernet/qlogic/qed/qed_ll2.c
index 46b71a6..fcf4ea9 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_ll2.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_ll2.c
@@ -315,7 +315,7 @@ static void qed_ll2_txq_flush(struct qed_hwfn *p_hwfn, u8 connection_handle)
list_del(&p_pkt->list_entry);
b_last_packet = list_empty(&p_tx->active_descq);
list_add_tail(&p_pkt->list_entry, &p_tx->free_descq);
- if (p_ll2_conn->conn.conn_type == QED_LL2_TYPE_ISCSI_OOO) {
+ if (p_ll2_conn->input.conn_type == QED_LL2_TYPE_ISCSI_OOO) {
struct qed_ooo_buffer *p_buffer;
p_buffer = (struct qed_ooo_buffer *)p_pkt->cookie;
@@ -327,7 +327,7 @@ static void qed_ll2_txq_flush(struct qed_hwfn *p_hwfn, u8 connection_handle)
b_last_frag =
p_tx->cur_completing_bd_idx == p_pkt->bd_used;
tx_frag = p_pkt->bds_set[0].tx_frag;
- if (p_ll2_conn->conn.gsi_enable)
+ if (p_ll2_conn->input.gsi_enable)
qed_ll2b_release_tx_gsi_packet(p_hwfn,
p_ll2_conn->
my_id,
@@ -396,7 +396,7 @@ static int qed_ll2_txq_completion(struct qed_hwfn *p_hwfn, void *p_cookie)
spin_unlock_irqrestore(&p_tx->lock, flags);
tx_frag = p_pkt->bds_set[0].tx_frag;
- if (p_ll2_conn->conn.gsi_enable)
+ if (p_ll2_conn->input.gsi_enable)
qed_ll2b_complete_tx_gsi_packet(p_hwfn,
p_ll2_conn->my_id,
p_pkt->cookie,
@@ -495,7 +495,7 @@ qed_ll2_rxq_handle_completion(struct qed_hwfn *p_hwfn,
if (!p_pkt) {
DP_NOTICE(p_hwfn,
"[%d] LL2 Rx completion but active_descq is empty\n",
- p_ll2_conn->conn.conn_type);
+ p_ll2_conn->input.conn_type);
return -EIO;
}
@@ -522,7 +522,7 @@ qed_ll2_rxq_handle_completion(struct qed_hwfn *p_hwfn,
static int qed_ll2_rxq_completion(struct qed_hwfn *p_hwfn, void *cookie)
{
- struct qed_ll2_info *p_ll2_conn = cookie;
+ struct qed_ll2_info *p_ll2_conn = (struct qed_ll2_info *)cookie;
struct qed_ll2_rx_queue *p_rx = &p_ll2_conn->rx_queue;
union core_rx_cqe_union *cqe = NULL;
u16 cq_new_idx = 0, cq_old_idx = 0;
@@ -536,7 +536,9 @@ static int qed_ll2_rxq_completion(struct qed_hwfn *p_hwfn, void *cookie)
while (cq_new_idx != cq_old_idx) {
bool b_last_cqe = (cq_new_idx == cq_old_idx);
- cqe = qed_chain_consume(&p_rx->rcq_chain);
+ cqe =
+ (union core_rx_cqe_union *)
+ qed_chain_consume(&p_rx->rcq_chain);
cq_old_idx = qed_chain_get_cons_idx(&p_rx->rcq_chain);
DP_VERBOSE(p_hwfn,
@@ -591,7 +593,7 @@ static void qed_ll2_rxq_flush(struct qed_hwfn *p_hwfn, u8 connection_handle)
list_move_tail(&p_pkt->list_entry, &p_rx->free_descq);
- if (p_ll2_conn->conn.conn_type == QED_LL2_TYPE_ISCSI_OOO) {
+ if (p_ll2_conn->input.conn_type == QED_LL2_TYPE_ISCSI_OOO) {
struct qed_ooo_buffer *p_buffer;
p_buffer = (struct qed_ooo_buffer *)p_pkt->cookie;
@@ -606,7 +608,6 @@ static void qed_ll2_rxq_flush(struct qed_hwfn *p_hwfn, u8 connection_handle)
}
}
-#if IS_ENABLED(CONFIG_QED_ISCSI)
static u8 qed_ll2_convert_rx_parse_to_tx_flags(u16 parse_flags)
{
u8 bd_flags = 0;
@@ -782,7 +783,7 @@ qed_ooo_submit_tx_buffers(struct qed_hwfn *p_hwfn,
tx_pkt.vlan = p_buffer->vlan;
tx_pkt.bd_flags = bd_flags;
tx_pkt.l4_hdr_offset_w = l4_hdr_offset_w;
- tx_pkt.tx_dest = p_ll2_conn->conn.tx_dest;
+ tx_pkt.tx_dest = p_ll2_conn->tx_dest;
tx_pkt.first_frag = first_frag;
tx_pkt.first_frag_len = p_buffer->packet_length;
tx_pkt.cookie = p_buffer;
@@ -895,60 +896,11 @@ static int qed_ll2_lb_txq_completion(struct qed_hwfn *p_hwfn, void *p_cookie)
return 0;
}
-static int
-qed_ll2_acquire_connection_ooo(struct qed_hwfn *p_hwfn,
- struct qed_ll2_info *p_ll2_info,
- u16 rx_num_ooo_buffers, u16 mtu)
-{
- struct qed_ooo_buffer *p_buf = NULL;
- void *p_virt;
- u16 buf_idx;
- int rc = 0;
-
- if (p_ll2_info->conn.conn_type != QED_LL2_TYPE_ISCSI_OOO)
- return rc;
-
- if (!rx_num_ooo_buffers)
- return -EINVAL;
-
- for (buf_idx = 0; buf_idx < rx_num_ooo_buffers; buf_idx++) {
- p_buf = kzalloc(sizeof(*p_buf), GFP_KERNEL);
- if (!p_buf) {
- rc = -ENOMEM;
- goto out;
- }
-
- p_buf->rx_buffer_size = mtu + 26 + ETH_CACHE_LINE_SIZE;
- p_buf->rx_buffer_size = (p_buf->rx_buffer_size +
- ETH_CACHE_LINE_SIZE - 1) &
- ~(ETH_CACHE_LINE_SIZE - 1);
- p_virt = dma_alloc_coherent(&p_hwfn->cdev->pdev->dev,
- p_buf->rx_buffer_size,
- &p_buf->rx_buffer_phys_addr,
- GFP_KERNEL);
- if (!p_virt) {
- kfree(p_buf);
- rc = -ENOMEM;
- goto out;
- }
-
- p_buf->rx_buffer_virt_addr = p_virt;
- qed_ooo_put_free_buffer(p_hwfn, p_hwfn->p_ooo_info, p_buf);
- }
-
- DP_VERBOSE(p_hwfn, QED_MSG_LL2,
- "Allocated [%04x] LL2 OOO buffers [each of size 0x%08x]\n",
- rx_num_ooo_buffers, p_buf->rx_buffer_size);
-
-out:
- return rc;
-}
-
static void
qed_ll2_establish_connection_ooo(struct qed_hwfn *p_hwfn,
struct qed_ll2_info *p_ll2_conn)
{
- if (p_ll2_conn->conn.conn_type != QED_LL2_TYPE_ISCSI_OOO)
+ if (p_ll2_conn->input.conn_type != QED_LL2_TYPE_ISCSI_OOO)
return;
qed_ooo_release_all_isles(p_hwfn, p_hwfn->p_ooo_info);
@@ -960,7 +912,7 @@ static void qed_ll2_release_connection_ooo(struct qed_hwfn *p_hwfn,
{
struct qed_ooo_buffer *p_buffer;
- if (p_ll2_conn->conn.conn_type != QED_LL2_TYPE_ISCSI_OOO)
+ if (p_ll2_conn->input.conn_type != QED_LL2_TYPE_ISCSI_OOO)
return;
qed_ooo_release_all_isles(p_hwfn, p_hwfn->p_ooo_info);
@@ -987,69 +939,11 @@ static void qed_ll2_stop_ooo(struct qed_dev *cdev)
*handle = QED_LL2_UNUSED_HANDLE;
}
-static int qed_ll2_start_ooo(struct qed_dev *cdev,
- struct qed_ll2_params *params)
-{
- struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev);
- u8 *handle = &hwfn->pf_params.iscsi_pf_params.ll2_ooo_queue_id;
- struct qed_ll2_conn ll2_info = { 0 };
- int rc;
-
- ll2_info.conn_type = QED_LL2_TYPE_ISCSI_OOO;
- ll2_info.mtu = params->mtu;
- ll2_info.rx_drop_ttl0_flg = params->drop_ttl0_packets;
- ll2_info.rx_vlan_removal_en = params->rx_vlan_stripping;
- ll2_info.tx_tc = OOO_LB_TC;
- ll2_info.tx_dest = CORE_TX_DEST_LB;
-
- rc = qed_ll2_acquire_connection(hwfn, &ll2_info,
- QED_LL2_RX_SIZE, QED_LL2_TX_SIZE,
- handle);
- if (rc) {
- DP_INFO(cdev, "Failed to acquire LL2 OOO connection\n");
- goto out;
- }
-
- rc = qed_ll2_establish_connection(hwfn, *handle);
- if (rc) {
- DP_INFO(cdev, "Failed to establist LL2 OOO connection\n");
- goto fail;
- }
-
- return 0;
-
-fail:
- qed_ll2_release_connection(hwfn, *handle);
-out:
- *handle = QED_LL2_UNUSED_HANDLE;
- return rc;
-}
-#else /* IS_ENABLED(CONFIG_QED_ISCSI) */
-static int qed_ll2_lb_rxq_completion(struct qed_hwfn *p_hwfn,
- void *p_cookie) { return -EINVAL; }
-static int qed_ll2_lb_txq_completion(struct qed_hwfn *p_hwfn,
- void *p_cookie) { return -EINVAL; }
-static inline int
-qed_ll2_acquire_connection_ooo(struct qed_hwfn *p_hwfn,
- struct qed_ll2_info *p_ll2_info,
- u16 rx_num_ooo_buffers, u16 mtu) { return 0; }
-static inline void
-qed_ll2_establish_connection_ooo(struct qed_hwfn *p_hwfn,
- struct qed_ll2_info *p_ll2_conn) { return; }
-static inline void
-qed_ll2_release_connection_ooo(struct qed_hwfn *p_hwfn,
- struct qed_ll2_info *p_ll2_conn) { return; }
-static inline void qed_ll2_stop_ooo(struct qed_dev *cdev) { return; }
-static inline int qed_ll2_start_ooo(struct qed_dev *cdev,
- struct qed_ll2_params *params)
- { return -EINVAL; }
-#endif /* IS_ENABLED(CONFIG_QED_ISCSI) */
-
static int qed_sp_ll2_rx_queue_start(struct qed_hwfn *p_hwfn,
struct qed_ll2_info *p_ll2_conn,
u8 action_on_error)
{
- enum qed_ll2_conn_type conn_type = p_ll2_conn->conn.conn_type;
+ enum qed_ll2_conn_type conn_type = p_ll2_conn->input.conn_type;
struct qed_ll2_rx_queue *p_rx = &p_ll2_conn->rx_queue;
struct core_rx_start_ramrod_data *p_ramrod = NULL;
struct qed_spq_entry *p_ent = NULL;
@@ -1075,16 +969,15 @@ static int qed_sp_ll2_rx_queue_start(struct qed_hwfn *p_hwfn,
p_ramrod->sb_index = p_rx->rx_sb_index;
p_ramrod->complete_event_flg = 1;
- p_ramrod->mtu = cpu_to_le16(p_ll2_conn->conn.mtu);
- DMA_REGPAIR_LE(p_ramrod->bd_base,
- p_rx->rxq_chain.p_phys_addr);
+ p_ramrod->mtu = cpu_to_le16(p_ll2_conn->input.mtu);
+ DMA_REGPAIR_LE(p_ramrod->bd_base, p_rx->rxq_chain.p_phys_addr);
cqe_pbl_size = (u16)qed_chain_get_page_cnt(&p_rx->rcq_chain);
p_ramrod->num_of_pbl_pages = cpu_to_le16(cqe_pbl_size);
DMA_REGPAIR_LE(p_ramrod->cqe_pbl_addr,
qed_chain_get_pbl_phys(&p_rx->rcq_chain));
- p_ramrod->drop_ttl0_flg = p_ll2_conn->conn.rx_drop_ttl0_flg;
- p_ramrod->inner_vlan_removal_en = p_ll2_conn->conn.rx_vlan_removal_en;
+ p_ramrod->drop_ttl0_flg = p_ll2_conn->input.rx_drop_ttl0_flg;
+ p_ramrod->inner_vlan_removal_en = p_ll2_conn->input.rx_vlan_removal_en;
p_ramrod->queue_id = p_ll2_conn->queue_id;
p_ramrod->main_func_queue = (conn_type == QED_LL2_TYPE_ISCSI_OOO) ? 0
: 1;
@@ -1099,14 +992,14 @@ static int qed_sp_ll2_rx_queue_start(struct qed_hwfn *p_hwfn,
}
p_ramrod->action_on_error.error_type = action_on_error;
- p_ramrod->gsi_offload_flag = p_ll2_conn->conn.gsi_enable;
+ p_ramrod->gsi_offload_flag = p_ll2_conn->input.gsi_enable;
return qed_spq_post(p_hwfn, p_ent, NULL);
}
static int qed_sp_ll2_tx_queue_start(struct qed_hwfn *p_hwfn,
struct qed_ll2_info *p_ll2_conn)
{
- enum qed_ll2_conn_type conn_type = p_ll2_conn->conn.conn_type;
+ enum qed_ll2_conn_type conn_type = p_ll2_conn->input.conn_type;
struct qed_ll2_tx_queue *p_tx = &p_ll2_conn->tx_queue;
struct core_tx_start_ramrod_data *p_ramrod = NULL;
struct qed_spq_entry *p_ent = NULL;
@@ -1117,7 +1010,7 @@ static int qed_sp_ll2_tx_queue_start(struct qed_hwfn *p_hwfn,
if (!QED_LL2_TX_REGISTERED(p_ll2_conn))
return 0;
- if (p_ll2_conn->conn.conn_type == QED_LL2_TYPE_ISCSI_OOO)
+ if (p_ll2_conn->input.conn_type == QED_LL2_TYPE_ISCSI_OOO)
p_ll2_conn->tx_stats_en = 0;
else
p_ll2_conn->tx_stats_en = 1;
@@ -1138,7 +1031,7 @@ static int qed_sp_ll2_tx_queue_start(struct qed_hwfn *p_hwfn,
p_ramrod->sb_id = cpu_to_le16(qed_int_get_sp_sb_id(p_hwfn));
p_ramrod->sb_index = p_tx->tx_sb_index;
- p_ramrod->mtu = cpu_to_le16(p_ll2_conn->conn.mtu);
+ p_ramrod->mtu = cpu_to_le16(p_ll2_conn->input.mtu);
p_ramrod->stats_en = p_ll2_conn->tx_stats_en;
p_ramrod->stats_id = p_ll2_conn->tx_stats_id;
@@ -1147,7 +1040,7 @@ static int qed_sp_ll2_tx_queue_start(struct qed_hwfn *p_hwfn,
pbl_size = qed_chain_get_page_cnt(&p_tx->txq_chain);
p_ramrod->pbl_size = cpu_to_le16(pbl_size);
- switch (p_ll2_conn->conn.tx_tc) {
+ switch (p_ll2_conn->input.tx_tc) {
case LB_TC:
pq_id = qed_get_cm_pq_idx(p_hwfn, PQ_FLAGS_LB);
break;
@@ -1177,7 +1070,8 @@ static int qed_sp_ll2_tx_queue_start(struct qed_hwfn *p_hwfn,
DP_NOTICE(p_hwfn, "Unknown connection type: %d\n", conn_type);
}
- p_ramrod->gsi_offload_flag = p_ll2_conn->conn.gsi_enable;
+ p_ramrod->gsi_offload_flag = p_ll2_conn->input.gsi_enable;
+
return qed_spq_post(p_hwfn, p_ent, NULL);
}
@@ -1233,20 +1127,20 @@ static int qed_sp_ll2_tx_queue_stop(struct qed_hwfn *p_hwfn,
static int
qed_ll2_acquire_connection_rx(struct qed_hwfn *p_hwfn,
- struct qed_ll2_info *p_ll2_info, u16 rx_num_desc)
+ struct qed_ll2_info *p_ll2_info)
{
struct qed_ll2_rx_packet *p_descq;
u32 capacity;
int rc = 0;
- if (!rx_num_desc)
+ if (!p_ll2_info->input.rx_num_desc)
goto out;
rc = qed_chain_alloc(p_hwfn->cdev,
QED_CHAIN_USE_TO_CONSUME_PRODUCE,
QED_CHAIN_MODE_NEXT_PTR,
QED_CHAIN_CNT_TYPE_U16,
- rx_num_desc,
+ p_ll2_info->input.rx_num_desc,
sizeof(struct core_rx_bd),
&p_ll2_info->rx_queue.rxq_chain);
if (rc) {
@@ -1268,7 +1162,7 @@ qed_ll2_acquire_connection_rx(struct qed_hwfn *p_hwfn,
QED_CHAIN_USE_TO_CONSUME_PRODUCE,
QED_CHAIN_MODE_PBL,
QED_CHAIN_CNT_TYPE_U16,
- rx_num_desc,
+ p_ll2_info->input.rx_num_desc,
sizeof(struct core_rx_fast_path_cqe),
&p_ll2_info->rx_queue.rcq_chain);
if (rc) {
@@ -1278,28 +1172,27 @@ qed_ll2_acquire_connection_rx(struct qed_hwfn *p_hwfn,
DP_VERBOSE(p_hwfn, QED_MSG_LL2,
"Allocated LL2 Rxq [Type %08x] with 0x%08x buffers\n",
- p_ll2_info->conn.conn_type, rx_num_desc);
+ p_ll2_info->input.conn_type, p_ll2_info->input.rx_num_desc);
out:
return rc;
}
static int qed_ll2_acquire_connection_tx(struct qed_hwfn *p_hwfn,
- struct qed_ll2_info *p_ll2_info,
- u16 tx_num_desc)
+ struct qed_ll2_info *p_ll2_info)
{
struct qed_ll2_tx_packet *p_descq;
u32 capacity;
int rc = 0;
- if (!tx_num_desc)
+ if (!p_ll2_info->input.tx_num_desc)
goto out;
rc = qed_chain_alloc(p_hwfn->cdev,
QED_CHAIN_USE_TO_CONSUME_PRODUCE,
QED_CHAIN_MODE_PBL,
QED_CHAIN_CNT_TYPE_U16,
- tx_num_desc,
+ p_ll2_info->input.tx_num_desc,
sizeof(struct core_tx_bd),
&p_ll2_info->tx_queue.txq_chain);
if (rc)
@@ -1316,28 +1209,95 @@ static int qed_ll2_acquire_connection_tx(struct qed_hwfn *p_hwfn,
DP_VERBOSE(p_hwfn, QED_MSG_LL2,
"Allocated LL2 Txq [Type %08x] with 0x%08x buffers\n",
- p_ll2_info->conn.conn_type, tx_num_desc);
+ p_ll2_info->input.conn_type, p_ll2_info->input.tx_num_desc);
out:
if (rc)
DP_NOTICE(p_hwfn,
"Can't allocate memory for Tx LL2 with 0x%08x buffers\n",
- tx_num_desc);
+ p_ll2_info->input.tx_num_desc);
+ return rc;
+}
+
+static int
+qed_ll2_acquire_connection_ooo(struct qed_hwfn *p_hwfn,
+ struct qed_ll2_info *p_ll2_info, u16 mtu)
+{
+ struct qed_ooo_buffer *p_buf = NULL;
+ void *p_virt;
+ u16 buf_idx;
+ int rc = 0;
+
+ if (p_ll2_info->input.conn_type != QED_LL2_TYPE_ISCSI_OOO)
+ return rc;
+
+ /* Correct number of requested OOO buffers if needed */
+ if (!p_ll2_info->input.rx_num_ooo_buffers) {
+ u16 num_desc = p_ll2_info->input.rx_num_desc;
+
+ if (!num_desc)
+ return -EINVAL;
+ p_ll2_info->input.rx_num_ooo_buffers = num_desc * 2;
+ }
+
+ for (buf_idx = 0; buf_idx < p_ll2_info->input.rx_num_ooo_buffers;
+ buf_idx++) {
+ p_buf = kzalloc(sizeof(*p_buf), GFP_KERNEL);
+ if (!p_buf) {
+ rc = -ENOMEM;
+ goto out;
+ }
+
+ p_buf->rx_buffer_size = mtu + 26 + ETH_CACHE_LINE_SIZE;
+ p_buf->rx_buffer_size = (p_buf->rx_buffer_size +
+ ETH_CACHE_LINE_SIZE - 1) &
+ ~(ETH_CACHE_LINE_SIZE - 1);
+ p_virt = dma_alloc_coherent(&p_hwfn->cdev->pdev->dev,
+ p_buf->rx_buffer_size,
+ &p_buf->rx_buffer_phys_addr,
+ GFP_KERNEL);
+ if (!p_virt) {
+ kfree(p_buf);
+ rc = -ENOMEM;
+ goto out;
+ }
+
+ p_buf->rx_buffer_virt_addr = p_virt;
+ qed_ooo_put_free_buffer(p_hwfn, p_hwfn->p_ooo_info, p_buf);
+ }
+
+ DP_VERBOSE(p_hwfn, QED_MSG_LL2,
+ "Allocated [%04x] LL2 OOO buffers [each of size 0x%08x]\n",
+ p_ll2_info->input.rx_num_ooo_buffers, p_buf->rx_buffer_size);
+
+out:
return rc;
}
+static enum core_error_handle
+qed_ll2_get_error_choice(enum qed_ll2_error_handle err)
+{
+ switch (err) {
+ case QED_LL2_DROP_PACKET:
+ return LL2_DROP_PACKET;
+ case QED_LL2_DO_NOTHING:
+ return LL2_DO_NOTHING;
+ case QED_LL2_ASSERT:
+ return LL2_ASSERT;
+ default:
+ return LL2_DO_NOTHING;
+ }
+}
+
int qed_ll2_acquire_connection(struct qed_hwfn *p_hwfn,
- struct qed_ll2_conn *p_params,
- u16 rx_num_desc,
- u16 tx_num_desc,
- u8 *p_connection_handle)
+ struct qed_ll2_acquire_data *data)
{
qed_int_comp_cb_t comp_rx_cb, comp_tx_cb;
struct qed_ll2_info *p_ll2_info = NULL;
+ u8 i, *p_tx_max;
int rc;
- u8 i;
- if (!p_connection_handle || !p_hwfn->p_ll2_info)
+ if (!data->p_connection_handle || !p_hwfn->p_ll2_info)
return -EINVAL;
/* Find a free connection to be used */
@@ -1356,23 +1316,33 @@ int qed_ll2_acquire_connection(struct qed_hwfn *p_hwfn,
if (!p_ll2_info)
return -EBUSY;
- p_ll2_info->conn = *p_params;
+ memcpy(&p_ll2_info->input, &data->input, sizeof(p_ll2_info->input));
- rc = qed_ll2_acquire_connection_rx(p_hwfn, p_ll2_info, rx_num_desc);
+ p_ll2_info->tx_dest = (data->input.tx_dest == QED_LL2_TX_DEST_NW) ?
+ CORE_TX_DEST_NW : CORE_TX_DEST_LB;
+
+ /* Correct maximum number of Tx BDs */
+ p_tx_max = &p_ll2_info->input.tx_max_bds_per_packet;
+ if (*p_tx_max == 0)
+ *p_tx_max = CORE_LL2_TX_MAX_BDS_PER_PACKET;
+ else
+ *p_tx_max = min_t(u8, *p_tx_max,
+ CORE_LL2_TX_MAX_BDS_PER_PACKET);
+ rc = qed_ll2_acquire_connection_rx(p_hwfn, p_ll2_info);
if (rc)
goto q_allocate_fail;
- rc = qed_ll2_acquire_connection_tx(p_hwfn, p_ll2_info, tx_num_desc);
+ rc = qed_ll2_acquire_connection_tx(p_hwfn, p_ll2_info);
if (rc)
goto q_allocate_fail;
rc = qed_ll2_acquire_connection_ooo(p_hwfn, p_ll2_info,
- rx_num_desc * 2, p_params->mtu);
+ data->input.mtu);
if (rc)
goto q_allocate_fail;
/* Register callbacks for the Rx/Tx queues */
- if (p_params->conn_type == QED_LL2_TYPE_ISCSI_OOO) {
+ if (data->input.conn_type == QED_LL2_TYPE_ISCSI_OOO) {
comp_rx_cb = qed_ll2_lb_rxq_completion;
comp_tx_cb = qed_ll2_lb_txq_completion;
} else {
@@ -1380,7 +1350,7 @@ int qed_ll2_acquire_connection(struct qed_hwfn *p_hwfn,
comp_tx_cb = qed_ll2_txq_completion;
}
- if (rx_num_desc) {
+ if (data->input.rx_num_desc) {
qed_int_register_cb(p_hwfn, comp_rx_cb,
&p_hwfn->p_ll2_info[i],
&p_ll2_info->rx_queue.rx_sb_index,
@@ -1388,7 +1358,7 @@ int qed_ll2_acquire_connection(struct qed_hwfn *p_hwfn,
p_ll2_info->rx_queue.b_cb_registred = true;
}
- if (tx_num_desc) {
+ if (data->input.tx_num_desc) {
qed_int_register_cb(p_hwfn,
comp_tx_cb,
&p_hwfn->p_ll2_info[i],
@@ -1397,7 +1367,7 @@ int qed_ll2_acquire_connection(struct qed_hwfn *p_hwfn,
p_ll2_info->tx_queue.b_cb_registred = true;
}
- *p_connection_handle = i;
+ *data->p_connection_handle = i;
return rc;
q_allocate_fail:
@@ -1408,18 +1378,21 @@ int qed_ll2_acquire_connection(struct qed_hwfn *p_hwfn,
static int qed_ll2_establish_connection_rx(struct qed_hwfn *p_hwfn,
struct qed_ll2_info *p_ll2_conn)
{
+ enum qed_ll2_error_handle error_input;
+ enum core_error_handle error_mode;
u8 action_on_error = 0;
if (!QED_LL2_RX_REGISTERED(p_ll2_conn))
return 0;
DIRECT_REG_WR(p_ll2_conn->rx_queue.set_prod_addr, 0x0);
-
+ error_input = p_ll2_conn->input.ai_err_packet_too_big;
+ error_mode = qed_ll2_get_error_choice(error_input);
SET_FIELD(action_on_error,
- CORE_RX_ACTION_ON_ERROR_PACKET_TOO_BIG,
- p_ll2_conn->conn.ai_err_packet_too_big);
- SET_FIELD(action_on_error,
- CORE_RX_ACTION_ON_ERROR_NO_BUFF, p_ll2_conn->conn.ai_err_no_buf);
+ CORE_RX_ACTION_ON_ERROR_PACKET_TOO_BIG, error_mode);
+ error_input = p_ll2_conn->input.ai_err_no_buf;
+ error_mode = qed_ll2_get_error_choice(error_input);
+ SET_FIELD(action_on_error, CORE_RX_ACTION_ON_ERROR_NO_BUFF, error_mode);
return qed_sp_ll2_rx_queue_start(p_hwfn, p_ll2_conn, action_on_error);
}
@@ -1503,7 +1476,7 @@ int qed_ll2_establish_connection(struct qed_hwfn *p_hwfn, u8 connection_handle)
qed_ll2_establish_connection_ooo(p_hwfn, p_ll2_conn);
- if (p_ll2_conn->conn.conn_type == QED_LL2_TYPE_FCOE) {
+ if (p_ll2_conn->input.conn_type == QED_LL2_TYPE_FCOE) {
qed_llh_add_protocol_filter(p_hwfn, p_ptt,
0x8906, 0,
QED_LLH_FILTER_ETHERTYPE);
@@ -1667,7 +1640,7 @@ qed_ll2_prepare_tx_packet_set_bd(struct qed_hwfn *p_hwfn,
"LL2 [q 0x%02x cid 0x%08x type 0x%08x] Tx Producer at [0x%04x] - set with a %04x bytes %02x BDs buffer at %08x:%08x\n",
p_ll2->queue_id,
p_ll2->cid,
- p_ll2->conn.conn_type,
+ p_ll2->input.conn_type,
prod_idx,
pkt->first_frag_len,
pkt->num_of_bds,
@@ -1742,7 +1715,8 @@ static void qed_ll2_tx_packet_notify(struct qed_hwfn *p_hwfn,
(NETIF_MSG_TX_QUEUED | QED_MSG_LL2),
"LL2 [q 0x%02x cid 0x%08x type 0x%08x] Doorbelled [producer 0x%04x]\n",
p_ll2_conn->queue_id,
- p_ll2_conn->cid, p_ll2_conn->conn.conn_type, db_msg.spq_prod);
+ p_ll2_conn->cid,
+ p_ll2_conn->input.conn_type, db_msg.spq_prod);
}
int qed_ll2_prepare_tx_packet(struct qed_hwfn *p_hwfn,
@@ -1866,10 +1840,10 @@ int qed_ll2_terminate_connection(struct qed_hwfn *p_hwfn, u8 connection_handle)
qed_ll2_rxq_flush(p_hwfn, connection_handle);
}
- if (p_ll2_conn->conn.conn_type == QED_LL2_TYPE_ISCSI_OOO)
+ if (p_ll2_conn->input.conn_type == QED_LL2_TYPE_ISCSI_OOO)
qed_ooo_release_all_isles(p_hwfn, p_hwfn->p_ooo_info);
- if (p_ll2_conn->conn.conn_type == QED_LL2_TYPE_FCOE) {
+ if (p_ll2_conn->input.conn_type == QED_LL2_TYPE_FCOE) {
qed_llh_remove_protocol_filter(p_hwfn, p_ptt,
0x8906, 0,
QED_LLH_FILTER_ETHERTYPE);
@@ -2054,11 +2028,68 @@ static void qed_ll2_register_cb_ops(struct qed_dev *cdev,
cdev->ll2->cb_cookie = cookie;
}
+static void qed_ll2_set_conn_data(struct qed_dev *cdev,
+ struct qed_ll2_acquire_data *data,
+ struct qed_ll2_params *params,
+ enum qed_ll2_conn_type conn_type,
+ u8 *handle, bool lb, u8 gsi_enable)
+{
+ memset(data, 0, sizeof(*data));
+
+ data->input.conn_type = conn_type;
+ data->input.mtu = params->mtu;
+ data->input.rx_num_desc = QED_LL2_RX_SIZE;
+ data->input.rx_drop_ttl0_flg = params->drop_ttl0_packets;
+ data->input.rx_vlan_removal_en = params->rx_vlan_stripping;
+ data->input.tx_num_desc = QED_LL2_TX_SIZE;
+ data->input.gsi_enable = gsi_enable;
+ data->p_connection_handle = handle;
+ if (lb) {
+ data->input.tx_tc = OOO_LB_TC;
+ data->input.tx_dest = QED_LL2_TX_DEST_LB;
+ } else {
+ data->input.tx_tc = 0;
+ data->input.tx_dest = QED_LL2_TX_DEST_NW;
+ }
+}
+
+static int qed_ll2_start_ooo(struct qed_dev *cdev,
+ struct qed_ll2_params *params)
+{
+ struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev);
+ u8 *handle = &hwfn->pf_params.iscsi_pf_params.ll2_ooo_queue_id;
+ struct qed_ll2_acquire_data data;
+ int rc;
+
+ qed_ll2_set_conn_data(cdev, &data, params,
+ QED_LL2_TYPE_ISCSI_OOO, handle, true, 0);
+
+ rc = qed_ll2_acquire_connection(hwfn, &data);
+ if (rc) {
+ DP_INFO(cdev, "Failed to acquire LL2 OOO connection\n");
+ goto out;
+ }
+
+ rc = qed_ll2_establish_connection(hwfn, *handle);
+ if (rc) {
+ DP_INFO(cdev, "Failed to establist LL2 OOO connection\n");
+ goto fail;
+ }
+
+ return 0;
+
+fail:
+ qed_ll2_release_connection(hwfn, *handle);
+out:
+ *handle = QED_LL2_UNUSED_HANDLE;
+ return rc;
+}
+
static int qed_ll2_start(struct qed_dev *cdev, struct qed_ll2_params *params)
{
- struct qed_ll2_conn ll2_info;
struct qed_ll2_buffer *buffer, *tmp_buffer;
enum qed_ll2_conn_type conn_type;
+ struct qed_ll2_acquire_data data;
struct qed_ptt *p_ptt;
int rc, i;
u8 gsi_enable = 1;
@@ -2106,20 +2137,10 @@ static int qed_ll2_start(struct qed_dev *cdev, struct qed_ll2_params *params)
conn_type = QED_LL2_TYPE_TEST;
}
- /* Prepare the temporary ll2 information */
- memset(&ll2_info, 0, sizeof(ll2_info));
-
- ll2_info.conn_type = conn_type;
- ll2_info.mtu = params->mtu;
- ll2_info.rx_drop_ttl0_flg = params->drop_ttl0_packets;
- ll2_info.rx_vlan_removal_en = params->rx_vlan_stripping;
- ll2_info.tx_tc = 0;
- ll2_info.tx_dest = CORE_TX_DEST_NW;
- ll2_info.gsi_enable = gsi_enable;
+ qed_ll2_set_conn_data(cdev, &data, params, conn_type,
+ &cdev->ll2->handle, false, gsi_enable);
- rc = qed_ll2_acquire_connection(QED_LEADING_HWFN(cdev), &ll2_info,
- QED_LL2_RX_SIZE, QED_LL2_TX_SIZE,
- &cdev->ll2->handle);
+ rc = qed_ll2_acquire_connection(QED_LEADING_HWFN(cdev), &data);
if (rc) {
DP_INFO(cdev, "Failed to acquire LL2 connection\n");
goto fail;
diff --git a/drivers/net/ethernet/qlogic/qed/qed_ll2.h b/drivers/net/ethernet/qlogic/qed/qed_ll2.h
index 96af50b..3caaad5 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_ll2.h
+++ b/drivers/net/ethernet/qlogic/qed/qed_ll2.h
@@ -47,17 +47,6 @@
#define QED_MAX_NUM_OF_LL2_CONNECTIONS (4)
-enum qed_ll2_conn_type {
- QED_LL2_TYPE_FCOE,
- QED_LL2_TYPE_ISCSI,
- QED_LL2_TYPE_TEST,
- QED_LL2_TYPE_ISCSI_OOO,
- QED_LL2_TYPE_RESERVED2,
- QED_LL2_TYPE_ROCE,
- QED_LL2_TYPE_RESERVED3,
- MAX_QED_LL2_RX_CONN_TYPE
-};
-
struct qed_ll2_rx_packet {
struct list_head list_entry;
struct core_rx_bd_with_buff_len *rxq_bd;
@@ -123,27 +112,17 @@ struct qed_ll2_tx_queue {
bool b_completing_packet;
};
-struct qed_ll2_conn {
- enum qed_ll2_conn_type conn_type;
- u16 mtu;
- u8 rx_drop_ttl0_flg;
- u8 rx_vlan_removal_en;
- u8 tx_tc;
- enum core_tx_dest tx_dest;
- enum core_error_handle ai_err_packet_too_big;
- enum core_error_handle ai_err_no_buf;
- u8 gsi_enable;
-};
-
struct qed_ll2_info {
/* Lock protecting the state of LL2 */
struct mutex mutex;
- struct qed_ll2_conn conn;
+
+ struct qed_ll2_acquire_data_inputs input;
u32 cid;
u8 my_id;
u8 queue_id;
u8 tx_stats_id;
bool b_active;
+ enum core_tx_dest tx_dest;
u8 tx_stats_en;
struct qed_ll2_rx_queue rx_queue;
struct qed_ll2_tx_queue tx_queue;
@@ -154,20 +133,13 @@ struct qed_ll2_info {
* starts rx & tx (if relevant) queues pair. Provides
* connecion handler as output parameter.
*
- * @param p_hwfn
- * @param p_params Contain various configuration properties
- * @param rx_num_desc
- * @param tx_num_desc
- *
- * @param p_connection_handle Output container for LL2 connection's handle
*
- * @return 0 on success, failure otherwise
+ * @param p_hwfn
+ * @param data - describes connection parameters
+ * @return int
*/
int qed_ll2_acquire_connection(struct qed_hwfn *p_hwfn,
- struct qed_ll2_conn *p_params,
- u16 rx_num_desc,
- u16 tx_num_desc,
- u8 *p_connection_handle);
+ struct qed_ll2_acquire_data *data);
/**
* @brief qed_ll2_establish_connection - start previously
diff --git a/drivers/net/ethernet/qlogic/qed/qed_roce.c b/drivers/net/ethernet/qlogic/qed/qed_roce.c
index afc63c0..33abcf1 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_roce.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_roce.c
@@ -2818,7 +2818,7 @@ static int qed_roce_ll2_start(struct qed_dev *cdev,
{
struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev);
struct qed_roce_ll2_info *roce_ll2;
- struct qed_ll2_conn ll2_params;
+ struct qed_ll2_acquire_data data;
int rc;
if (!params) {
@@ -2844,25 +2844,26 @@ static int qed_roce_ll2_start(struct qed_dev *cdev,
DP_ERR(cdev, "qed roce ll2 start: failed memory allocation\n");
return -ENOMEM;
}
+
roce_ll2->handle = QED_LL2_UNUSED_HANDLE;
roce_ll2->cbs = params->cbs;
roce_ll2->cb_cookie = params->cb_cookie;
mutex_init(&roce_ll2->lock);
- memset(&ll2_params, 0, sizeof(ll2_params));
- ll2_params.conn_type = QED_LL2_TYPE_ROCE;
- ll2_params.mtu = params->mtu;
- ll2_params.rx_drop_ttl0_flg = true;
- ll2_params.rx_vlan_removal_en = false;
- ll2_params.tx_dest = CORE_TX_DEST_NW;
- ll2_params.ai_err_packet_too_big = LL2_DROP_PACKET;
- ll2_params.ai_err_no_buf = LL2_DROP_PACKET;
- ll2_params.gsi_enable = true;
-
- rc = qed_ll2_acquire_connection(QED_LEADING_HWFN(cdev), &ll2_params,
- params->max_rx_buffers,
- params->max_tx_buffers,
- &roce_ll2->handle);
+ memset(&data, 0, sizeof(data));
+ data.input.conn_type = QED_LL2_TYPE_ROCE;
+ data.input.mtu = params->mtu;
+ data.input.rx_num_desc = params->max_rx_buffers;
+ data.input.tx_num_desc = params->max_tx_buffers;
+ data.input.rx_drop_ttl0_flg = true;
+ data.input.rx_vlan_removal_en = false;
+ data.input.tx_dest = QED_LL2_TX_DEST_NW;
+ data.input.ai_err_packet_too_big = LL2_DROP_PACKET;
+ data.input.ai_err_no_buf = LL2_DROP_PACKET;
+ data.p_connection_handle = &roce_ll2->handle;
+ data.input.gsi_enable = true;
+
+ rc = qed_ll2_acquire_connection(QED_LEADING_HWFN(cdev), &data);
if (rc) {
DP_ERR(cdev,
"qed roce ll2 start: failed to acquire LL2 connection (rc=%d)\n",
diff --git a/include/linux/qed/qed_ll2_if.h b/include/linux/qed/qed_ll2_if.h
index 056ac00..a1f63ec 100644
--- a/include/linux/qed/qed_ll2_if.h
+++ b/include/linux/qed/qed_ll2_if.h
@@ -43,6 +43,17 @@
#include <linux/slab.h>
#include <linux/qed/qed_if.h>
+enum qed_ll2_conn_type {
+ QED_LL2_TYPE_FCOE,
+ QED_LL2_TYPE_ISCSI,
+ QED_LL2_TYPE_TEST,
+ QED_LL2_TYPE_ISCSI_OOO,
+ QED_LL2_TYPE_RESERVED2,
+ QED_LL2_TYPE_ROCE,
+ QED_LL2_TYPE_RESERVED3,
+ MAX_QED_LL2_RX_CONN_TYPE
+};
+
enum qed_ll2_roce_flavor_type {
QED_LL2_ROCE,
QED_LL2_RROCE,
@@ -55,6 +66,12 @@ enum qed_ll2_tx_dest {
QED_LL2_TX_DEST_MAX
};
+enum qed_ll2_error_handle {
+ QED_LL2_DROP_PACKET,
+ QED_LL2_DO_NOTHING,
+ QED_LL2_ASSERT,
+};
+
struct qed_ll2_stats {
u64 gsi_invalid_hdr;
u64 gsi_invalid_pkt_length;
@@ -105,6 +122,28 @@ struct qed_ll2_comp_rx_data {
} u;
};
+struct qed_ll2_acquire_data_inputs {
+ enum qed_ll2_conn_type conn_type;
+ u16 mtu;
+ u16 rx_num_desc;
+ u16 rx_num_ooo_buffers;
+ u8 rx_drop_ttl0_flg;
+ u8 rx_vlan_removal_en;
+ u16 tx_num_desc;
+ u8 tx_max_bds_per_packet;
+ u8 tx_tc;
+ enum qed_ll2_tx_dest tx_dest;
+ enum qed_ll2_error_handle ai_err_packet_too_big;
+ enum qed_ll2_error_handle ai_err_no_buf;
+ u8 gsi_enable;
+};
+
+struct qed_ll2_acquire_data {
+ struct qed_ll2_acquire_data_inputs input;
+ /* Output container for LL2 connection's handle */
+ u8 *p_connection_handle;
+};
+
struct qed_ll2_tx_pkt_info {
void *cookie;
dma_addr_t first_frag;
--
2.9.4
^ permalink raw reply related
* [PATCH v2 net-next 8/8] qed: collect GSI port statistics
From: Yuval Mintz @ 2017-06-09 14:13 UTC (permalink / raw)
To: netdev-u79uwXL29TY76Z2rM5mHXA, davem-fT/PcQaiUtIeIZ0/mPfg9Q
Cc: linux-rdma-u79uwXL29TY76Z2rM5mHXA,
Michal.Kalderon-YGCgFSpz5w/QT0dZR+AlfA, Yuval Mintz
In-Reply-To: <20170609141325.20547-1-Yuval.Mintz-YGCgFSpz5w/QT0dZR+AlfA@public.gmane.org>
The LL2 statistics already have place holders for these, but haven't
populated them so far.
Signed-off-by: Yuval Mintz <Yuval.Mintz-YGCgFSpz5w/QT0dZR+AlfA@public.gmane.org>
---
drivers/net/ethernet/qlogic/qed/qed_ll2.c | 23 +++++++++++++++++++++++
1 file changed, 23 insertions(+)
diff --git a/drivers/net/ethernet/qlogic/qed/qed_ll2.c b/drivers/net/ethernet/qlogic/qed/qed_ll2.c
index c6172a77e..0e26193 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_ll2.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_ll2.c
@@ -1902,6 +1902,27 @@ void qed_ll2_free(struct qed_hwfn *p_hwfn)
p_hwfn->p_ll2_info = NULL;
}
+static void _qed_ll2_get_port_stats(struct qed_hwfn *p_hwfn,
+ struct qed_ptt *p_ptt,
+ struct qed_ll2_stats *p_stats)
+{
+ struct core_ll2_port_stats port_stats;
+
+ memset(&port_stats, 0, sizeof(port_stats));
+ qed_memcpy_from(p_hwfn, p_ptt, &port_stats,
+ BAR0_MAP_REG_TSDM_RAM +
+ TSTORM_LL2_PORT_STAT_OFFSET(MFW_PORT(p_hwfn)),
+ sizeof(port_stats));
+
+ p_stats->gsi_invalid_hdr = HILO_64_REGPAIR(port_stats.gsi_invalid_hdr);
+ p_stats->gsi_invalid_pkt_length =
+ HILO_64_REGPAIR(port_stats.gsi_invalid_pkt_length);
+ p_stats->gsi_unsupported_pkt_typ =
+ HILO_64_REGPAIR(port_stats.gsi_unsupported_pkt_typ);
+ p_stats->gsi_crcchksm_error =
+ HILO_64_REGPAIR(port_stats.gsi_crcchksm_error);
+}
+
static void _qed_ll2_get_tstats(struct qed_hwfn *p_hwfn,
struct qed_ptt *p_ptt,
struct qed_ll2_info *p_ll2_conn,
@@ -1986,6 +2007,8 @@ int qed_ll2_get_stats(void *cxt,
return -EINVAL;
}
+ if (p_ll2_conn->input.gsi_enable)
+ _qed_ll2_get_port_stats(p_hwfn, p_ptt, p_stats);
_qed_ll2_get_tstats(p_hwfn, p_ptt, p_ll2_conn, p_stats);
_qed_ll2_get_ustats(p_hwfn, p_ptt, p_ll2_conn, p_stats);
if (p_ll2_conn->tx_stats_en)
--
2.9.4
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH v2 net-next 5/8] qed*: LL2 callback operations
From: Yuval Mintz @ 2017-06-09 14:13 UTC (permalink / raw)
To: netdev-u79uwXL29TY76Z2rM5mHXA, davem-fT/PcQaiUtIeIZ0/mPfg9Q
Cc: linux-rdma-u79uwXL29TY76Z2rM5mHXA,
Michal.Kalderon-YGCgFSpz5w/QT0dZR+AlfA, Yuval Mintz
In-Reply-To: <20170609141325.20547-1-Yuval.Mintz-YGCgFSpz5w/QT0dZR+AlfA@public.gmane.org>
From: Michal Kalderon <Michal.Kalderon-YGCgFSpz5w/QT0dZR+AlfA@public.gmane.org>
LL2 today is interrupt driven - when tx/rx completion arrives [or any
other indication], qed needs to operate on the connection and pass
the information to the protocol-driver [or internal qed consumer].
Since we have several flavors of ll2 employeed by the driver,
each handler needs to do an if-else to determine the right functionality
to use based on the connection type.
In order to make things more scalable [given that we're going to add
additional types of ll2 flavors] move the infrastrucutre into using
a callback-based approach - the callbacks would be provided as part
of the connection's initialization parameters.
Signed-off-by: Michal Kalderon <Michal.Kalderon-YGCgFSpz5w/QT0dZR+AlfA@public.gmane.org>
Signed-off-by: Yuval Mintz <Yuval.Mintz-YGCgFSpz5w/QT0dZR+AlfA@public.gmane.org>
---
drivers/infiniband/hw/qedr/main.c | 6 +-
drivers/infiniband/hw/qedr/qedr.h | 2 +
drivers/infiniband/hw/qedr/qedr_cm.c | 238 ++++++++++++++++------
drivers/net/ethernet/qlogic/qed/qed.h | 1 -
drivers/net/ethernet/qlogic/qed/qed_ll2.c | 197 +++++++++----------
drivers/net/ethernet/qlogic/qed/qed_ll2.h | 34 ++--
drivers/net/ethernet/qlogic/qed/qed_roce.c | 304 ++---------------------------
drivers/net/ethernet/qlogic/qed/qed_roce.h | 43 ----
include/linux/qed/qed_ll2_if.h | 36 ++++
include/linux/qed/qed_roce_if.h | 80 +++-----
10 files changed, 384 insertions(+), 557 deletions(-)
diff --git a/drivers/infiniband/hw/qedr/main.c b/drivers/infiniband/hw/qedr/main.c
index 6a72095..485c1fe 100644
--- a/drivers/infiniband/hw/qedr/main.c
+++ b/drivers/infiniband/hw/qedr/main.c
@@ -886,9 +886,9 @@ static void qedr_mac_address_change(struct qedr_dev *dev)
memcpy(&sgid->raw[8], guid, sizeof(guid));
/* Update LL2 */
- rc = dev->ops->roce_ll2_set_mac_filter(dev->cdev,
- dev->gsi_ll2_mac_address,
- dev->ndev->dev_addr);
+ rc = dev->ops->ll2_set_mac_filter(dev->cdev,
+ dev->gsi_ll2_mac_address,
+ dev->ndev->dev_addr);
ether_addr_copy(dev->gsi_ll2_mac_address, dev->ndev->dev_addr);
diff --git a/drivers/infiniband/hw/qedr/qedr.h b/drivers/infiniband/hw/qedr/qedr.h
index aa08c76..80333ec 100644
--- a/drivers/infiniband/hw/qedr/qedr.h
+++ b/drivers/infiniband/hw/qedr/qedr.h
@@ -150,6 +150,8 @@ struct qedr_dev {
u32 dp_module;
u8 dp_level;
u8 num_hwfns;
+ u8 gsi_ll2_handle;
+
uint wq_multiplier;
u8 gsi_ll2_mac_address[ETH_ALEN];
int gsi_qp_created;
diff --git a/drivers/infiniband/hw/qedr/qedr_cm.c b/drivers/infiniband/hw/qedr/qedr_cm.c
index d86dbe8..eb3dce7 100644
--- a/drivers/infiniband/hw/qedr/qedr_cm.c
+++ b/drivers/infiniband/hw/qedr/qedr_cm.c
@@ -64,9 +64,14 @@ void qedr_store_gsi_qp_cq(struct qedr_dev *dev, struct qedr_qp *qp,
dev->gsi_qp = qp;
}
-void qedr_ll2_tx_cb(void *_qdev, struct qed_roce_ll2_packet *pkt)
+void qedr_ll2_complete_tx_packet(void *cxt,
+ u8 connection_handle,
+ void *cookie,
+ dma_addr_t first_frag_addr,
+ bool b_last_fragment, bool b_last_packet)
{
- struct qedr_dev *dev = (struct qedr_dev *)_qdev;
+ struct qedr_dev *dev = (struct qedr_dev *)cxt;
+ struct qed_roce_ll2_packet *pkt = cookie;
struct qedr_cq *cq = dev->gsi_sqcq;
struct qedr_qp *qp = dev->gsi_qp;
unsigned long flags;
@@ -88,20 +93,26 @@ void qedr_ll2_tx_cb(void *_qdev, struct qed_roce_ll2_packet *pkt)
(*cq->ibcq.comp_handler) (&cq->ibcq, cq->ibcq.cq_context);
}
-void qedr_ll2_rx_cb(void *_dev, struct qed_roce_ll2_packet *pkt,
- struct qed_roce_ll2_rx_params *params)
+void qedr_ll2_complete_rx_packet(void *cxt,
+ struct qed_ll2_comp_rx_data *data)
{
- struct qedr_dev *dev = (struct qedr_dev *)_dev;
+ struct qedr_dev *dev = (struct qedr_dev *)cxt;
struct qedr_cq *cq = dev->gsi_rqcq;
struct qedr_qp *qp = dev->gsi_qp;
unsigned long flags;
spin_lock_irqsave(&qp->q_lock, flags);
- qp->rqe_wr_id[qp->rq.gsi_cons].rc = params->rc;
- qp->rqe_wr_id[qp->rq.gsi_cons].vlan_id = params->vlan_id;
- qp->rqe_wr_id[qp->rq.gsi_cons].sg_list[0].length = pkt->payload[0].len;
- ether_addr_copy(qp->rqe_wr_id[qp->rq.gsi_cons].smac, params->smac);
+ qp->rqe_wr_id[qp->rq.gsi_cons].rc = data->u.data_length_error ?
+ -EINVAL : 0;
+ qp->rqe_wr_id[qp->rq.gsi_cons].vlan_id = data->vlan;
+ /* note: length stands for data length i.e. GRH is excluded */
+ qp->rqe_wr_id[qp->rq.gsi_cons].sg_list[0].length =
+ data->length.data_length;
+ *((u32 *)&qp->rqe_wr_id[qp->rq.gsi_cons].smac[0]) =
+ ntohl(data->opaque_data_0);
+ *((u16 *)&qp->rqe_wr_id[qp->rq.gsi_cons].smac[4]) =
+ ntohs((u16)data->opaque_data_1);
qedr_inc_sw_gsi_cons(&qp->rq);
@@ -111,6 +122,14 @@ void qedr_ll2_rx_cb(void *_dev, struct qed_roce_ll2_packet *pkt,
(*cq->ibcq.comp_handler) (&cq->ibcq, cq->ibcq.cq_context);
}
+void qedr_ll2_release_rx_packet(void *cxt,
+ u8 connection_handle,
+ void *cookie,
+ dma_addr_t rx_buf_addr, bool b_last_packet)
+{
+ /* Do nothing... */
+}
+
static void qedr_destroy_gsi_cq(struct qedr_dev *dev,
struct ib_qp_init_attr *attrs)
{
@@ -159,27 +178,159 @@ static inline int qedr_check_gsi_qp_attrs(struct qedr_dev *dev,
return 0;
}
+static int qedr_ll2_post_tx(struct qedr_dev *dev,
+ struct qed_roce_ll2_packet *pkt)
+{
+ enum qed_ll2_roce_flavor_type roce_flavor;
+ struct qed_ll2_tx_pkt_info ll2_tx_pkt;
+ int rc;
+ int i;
+
+ memset(&ll2_tx_pkt, 0, sizeof(ll2_tx_pkt));
+
+ roce_flavor = (pkt->roce_mode == ROCE_V1) ?
+ QED_LL2_ROCE : QED_LL2_RROCE;
+
+ if (pkt->roce_mode == ROCE_V2_IPV4)
+ ll2_tx_pkt.enable_ip_cksum = 1;
+
+ ll2_tx_pkt.num_of_bds = 1 /* hdr */ + pkt->n_seg;
+ ll2_tx_pkt.vlan = 0;
+ ll2_tx_pkt.tx_dest = pkt->tx_dest;
+ ll2_tx_pkt.qed_roce_flavor = roce_flavor;
+ ll2_tx_pkt.first_frag = pkt->header.baddr;
+ ll2_tx_pkt.first_frag_len = pkt->header.len;
+ ll2_tx_pkt.cookie = pkt;
+
+ /* tx header */
+ rc = dev->ops->ll2_prepare_tx_packet(dev->rdma_ctx,
+ dev->gsi_ll2_handle,
+ &ll2_tx_pkt, 1);
+ if (rc) {
+ /* TX failed while posting header - release resources */
+ dma_free_coherent(&dev->pdev->dev, pkt->header.len,
+ pkt->header.vaddr, pkt->header.baddr);
+ kfree(pkt);
+
+ DP_ERR(dev, "roce ll2 tx: header failed (rc=%d)\n", rc);
+ return rc;
+ }
+
+ /* tx payload */
+ for (i = 0; i < pkt->n_seg; i++) {
+ rc = dev->ops->ll2_set_fragment_of_tx_packet(
+ dev->rdma_ctx,
+ dev->gsi_ll2_handle,
+ pkt->payload[i].baddr,
+ pkt->payload[i].len);
+
+ if (rc) {
+ /* if failed not much to do here, partial packet has
+ * been posted we can't free memory, will need to wait
+ * for completion
+ */
+ DP_ERR(dev, "ll2 tx: payload failed (rc=%d)\n", rc);
+ return rc;
+ }
+ }
+
+ return 0;
+}
+
+int qedr_ll2_stop(struct qedr_dev *dev)
+{
+ int rc;
+
+ if (dev->gsi_ll2_handle == QED_LL2_UNUSED_HANDLE)
+ return 0;
+
+ /* remove LL2 MAC address filter */
+ rc = dev->ops->ll2_set_mac_filter(dev->cdev,
+ dev->gsi_ll2_mac_address, NULL);
+
+ rc = dev->ops->ll2_terminate_connection(dev->rdma_ctx,
+ dev->gsi_ll2_handle);
+ if (rc)
+ DP_ERR(dev, "Failed to terminate LL2 connection (rc=%d)\n", rc);
+
+ dev->ops->ll2_release_connection(dev->rdma_ctx, dev->gsi_ll2_handle);
+
+ dev->gsi_ll2_handle = QED_LL2_UNUSED_HANDLE;
+
+ return rc;
+}
+
+int qedr_ll2_start(struct qedr_dev *dev,
+ struct ib_qp_init_attr *attrs, struct qedr_qp *qp)
+{
+ struct qed_ll2_acquire_data data;
+ struct qed_ll2_cbs cbs;
+ int rc;
+
+ /* configure and start LL2 */
+ cbs.rx_comp_cb = qedr_ll2_complete_rx_packet;
+ cbs.tx_comp_cb = qedr_ll2_complete_tx_packet;
+ cbs.rx_release_cb = qedr_ll2_release_rx_packet;
+ cbs.tx_release_cb = qedr_ll2_complete_tx_packet;
+ cbs.cookie = dev;
+
+ memset(&data, 0, sizeof(data));
+ data.input.conn_type = QED_LL2_TYPE_ROCE;
+ data.input.mtu = dev->ndev->mtu;
+ data.input.rx_num_desc = attrs->cap.max_recv_wr;
+ data.input.rx_drop_ttl0_flg = true;
+ data.input.rx_vlan_removal_en = false;
+ data.input.tx_num_desc = attrs->cap.max_send_wr;
+ data.input.tx_tc = 0;
+ data.input.tx_dest = QED_LL2_TX_DEST_NW;
+ data.input.ai_err_packet_too_big = QED_LL2_DROP_PACKET;
+ data.input.ai_err_no_buf = QED_LL2_DROP_PACKET;
+ data.input.gsi_enable = 1;
+ data.p_connection_handle = &dev->gsi_ll2_handle;
+ data.cbs = &cbs;
+
+ rc = dev->ops->ll2_acquire_connection(dev->rdma_ctx, &data);
+ if (rc) {
+ DP_ERR(dev,
+ "ll2 start: failed to acquire LL2 connection (rc=%d)\n",
+ rc);
+ return rc;
+ }
+
+ rc = dev->ops->ll2_establish_connection(dev->rdma_ctx,
+ dev->gsi_ll2_handle);
+ if (rc) {
+ DP_ERR(dev,
+ "ll2 start: failed to establish LL2 connection (rc=%d)\n",
+ rc);
+ goto err1;
+ }
+
+ rc = dev->ops->ll2_set_mac_filter(dev->cdev, NULL, dev->ndev->dev_addr);
+ if (rc)
+ goto err2;
+
+ return 0;
+
+err2:
+ dev->ops->ll2_terminate_connection(dev->rdma_ctx, dev->gsi_ll2_handle);
+err1:
+ dev->ops->ll2_release_connection(dev->rdma_ctx, dev->gsi_ll2_handle);
+
+ return rc;
+}
+
struct ib_qp *qedr_create_gsi_qp(struct qedr_dev *dev,
struct ib_qp_init_attr *attrs,
struct qedr_qp *qp)
{
- struct qed_roce_ll2_params ll2_params;
int rc;
rc = qedr_check_gsi_qp_attrs(dev, attrs);
if (rc)
return ERR_PTR(rc);
- /* configure and start LL2 */
- memset(&ll2_params, 0, sizeof(ll2_params));
- ll2_params.max_tx_buffers = attrs->cap.max_send_wr;
- ll2_params.max_rx_buffers = attrs->cap.max_recv_wr;
- ll2_params.cbs.tx_cb = qedr_ll2_tx_cb;
- ll2_params.cbs.rx_cb = qedr_ll2_rx_cb;
- ll2_params.cb_cookie = (void *)dev;
- ll2_params.mtu = dev->ndev->mtu;
- ether_addr_copy(ll2_params.mac_address, dev->ndev->dev_addr);
- rc = dev->ops->roce_ll2_start(dev->cdev, &ll2_params);
+ rc = qedr_ll2_start(dev, attrs, qp);
if (rc) {
DP_ERR(dev, "create gsi qp: failed on ll2 start. rc=%d\n", rc);
return ERR_PTR(rc);
@@ -214,7 +365,7 @@ struct ib_qp *qedr_create_gsi_qp(struct qedr_dev *dev,
err:
kfree(qp->rqe_wr_id);
- rc = dev->ops->roce_ll2_stop(dev->cdev);
+ rc = qedr_ll2_stop(dev);
if (rc)
DP_ERR(dev, "create gsi qp: failed destroy on create\n");
@@ -223,15 +374,7 @@ struct ib_qp *qedr_create_gsi_qp(struct qedr_dev *dev,
int qedr_destroy_gsi_qp(struct qedr_dev *dev)
{
- int rc;
-
- rc = dev->ops->roce_ll2_stop(dev->cdev);
- if (rc)
- DP_ERR(dev, "destroy gsi qp: failed (rc=%d)\n", rc);
- else
- DP_DEBUG(dev, QEDR_MSG_GSI, "destroy gsi qp: success\n");
-
- return rc;
+ return qedr_ll2_stop(dev);
}
#define QEDR_MAX_UD_HEADER_SIZE (100)
@@ -421,7 +564,6 @@ int qedr_gsi_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
{
struct qed_roce_ll2_packet *pkt = NULL;
struct qedr_qp *qp = get_qedr_qp(ibqp);
- struct qed_roce_ll2_tx_params params;
struct qedr_dev *dev = qp->dev;
unsigned long flags;
int rc;
@@ -449,8 +591,6 @@ int qedr_gsi_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
goto err;
}
- memset(¶ms, 0, sizeof(params));
-
spin_lock_irqsave(&qp->q_lock, flags);
rc = qedr_gsi_build_packet(dev, qp, wr, &pkt);
@@ -459,7 +599,8 @@ int qedr_gsi_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
goto err;
}
- rc = dev->ops->roce_ll2_tx(dev->cdev, pkt, ¶ms);
+ rc = qedr_ll2_post_tx(dev, pkt);
+
if (!rc) {
qp->wqe_wr_id[qp->sq.prod].wr_id = wr->wr_id;
qedr_inc_sw_prod(&qp->sq);
@@ -467,17 +608,6 @@ int qedr_gsi_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
"gsi post send: opcode=%d, in_irq=%ld, irqs_disabled=%d, wr_id=%llx\n",
wr->opcode, in_irq(), irqs_disabled(), wr->wr_id);
} else {
- if (rc == QED_ROCE_TX_HEAD_FAILURE) {
- /* TX failed while posting header - release resources */
- dma_free_coherent(&dev->pdev->dev, pkt->header.len,
- pkt->header.vaddr, pkt->header.baddr);
- kfree(pkt);
- } else if (rc == QED_ROCE_TX_FRAG_FAILURE) {
- /* NTD since TX failed while posting a fragment. We will
- * release the resources on TX callback
- */
- }
-
DP_ERR(dev, "gsi post send: failed to transmit (rc=%d)\n", rc);
rc = -EAGAIN;
*bad_wr = wr;
@@ -504,10 +634,8 @@ int qedr_gsi_post_recv(struct ib_qp *ibqp, struct ib_recv_wr *wr,
{
struct qedr_dev *dev = get_qedr_dev(ibqp->device);
struct qedr_qp *qp = get_qedr_qp(ibqp);
- struct qed_roce_ll2_buffer buf;
unsigned long flags;
- int status = 0;
- int rc;
+ int rc = 0;
if ((qp->state != QED_ROCE_QP_STATE_RTR) &&
(qp->state != QED_ROCE_QP_STATE_RTS)) {
@@ -518,8 +646,6 @@ int qedr_gsi_post_recv(struct ib_qp *ibqp, struct ib_recv_wr *wr,
return -EINVAL;
}
- memset(&buf, 0, sizeof(buf));
-
spin_lock_irqsave(&qp->q_lock, flags);
while (wr) {
@@ -530,10 +656,12 @@ int qedr_gsi_post_recv(struct ib_qp *ibqp, struct ib_recv_wr *wr,
goto err;
}
- buf.baddr = wr->sg_list[0].addr;
- buf.len = wr->sg_list[0].length;
-
- rc = dev->ops->roce_ll2_post_rx_buffer(dev->cdev, &buf, 0, 1);
+ rc = dev->ops->ll2_post_rx_buffer(dev->rdma_ctx,
+ dev->gsi_ll2_handle,
+ wr->sg_list[0].addr,
+ wr->sg_list[0].length,
+ 0 /* cookie */,
+ 1 /* notify_fw */);
if (rc) {
DP_ERR(dev,
"gsi post recv: failed to post rx buffer (rc=%d)\n",
@@ -553,7 +681,7 @@ int qedr_gsi_post_recv(struct ib_qp *ibqp, struct ib_recv_wr *wr,
spin_unlock_irqrestore(&qp->q_lock, flags);
- return status;
+ return rc;
err:
spin_unlock_irqrestore(&qp->q_lock, flags);
*bad_wr = wr;
diff --git a/drivers/net/ethernet/qlogic/qed/qed.h b/drivers/net/ethernet/qlogic/qed/qed.h
index d7afc42..14b08ee 100644
--- a/drivers/net/ethernet/qlogic/qed/qed.h
+++ b/drivers/net/ethernet/qlogic/qed/qed.h
@@ -552,7 +552,6 @@ struct qed_hwfn {
#endif
struct z_stream_s *stream;
- struct qed_roce_ll2_info *ll2;
};
struct pci_params {
diff --git a/drivers/net/ethernet/qlogic/qed/qed_ll2.c b/drivers/net/ethernet/qlogic/qed/qed_ll2.c
index f3aad61..b222b2b 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_ll2.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_ll2.c
@@ -89,13 +89,14 @@ struct qed_ll2_buffer {
dma_addr_t phys_addr;
};
-static void qed_ll2b_complete_tx_packet(struct qed_hwfn *p_hwfn,
+static void qed_ll2b_complete_tx_packet(void *cxt,
u8 connection_handle,
void *cookie,
dma_addr_t first_frag_addr,
bool b_last_fragment,
bool b_last_packet)
{
+ struct qed_hwfn *p_hwfn = cxt;
struct qed_dev *cdev = p_hwfn->cdev;
struct sk_buff *skb = cookie;
@@ -164,9 +165,9 @@ static void qed_ll2_kill_buffers(struct qed_dev *cdev)
qed_ll2_dealloc_buffer(cdev, buffer);
}
-static void qed_ll2b_complete_rx_packet(struct qed_hwfn *p_hwfn,
- struct qed_ll2_comp_rx_data *data)
+void qed_ll2b_complete_rx_packet(void *cxt, struct qed_ll2_comp_rx_data *data)
{
+ struct qed_hwfn *p_hwfn = cxt;
struct qed_ll2_buffer *buffer = data->cookie;
struct qed_dev *cdev = p_hwfn->cdev;
dma_addr_t new_phys_addr;
@@ -327,21 +328,12 @@ static void qed_ll2_txq_flush(struct qed_hwfn *p_hwfn, u8 connection_handle)
b_last_frag =
p_tx->cur_completing_bd_idx == p_pkt->bd_used;
tx_frag = p_pkt->bds_set[0].tx_frag;
- if (p_ll2_conn->input.gsi_enable)
- qed_ll2b_release_tx_gsi_packet(p_hwfn,
- p_ll2_conn->
- my_id,
- p_pkt->cookie,
- tx_frag,
- b_last_frag,
- b_last_packet);
- else
- qed_ll2b_complete_tx_packet(p_hwfn,
- p_ll2_conn->my_id,
- p_pkt->cookie,
- tx_frag,
- b_last_frag,
- b_last_packet);
+ p_ll2_conn->cbs.tx_release_cb(p_ll2_conn->cbs.cookie,
+ p_ll2_conn->my_id,
+ p_pkt->cookie,
+ tx_frag,
+ b_last_frag,
+ b_last_packet);
}
}
}
@@ -354,7 +346,6 @@ static int qed_ll2_txq_completion(struct qed_hwfn *p_hwfn, void *p_cookie)
struct qed_ll2_tx_packet *p_pkt;
bool b_last_frag = false;
unsigned long flags;
- dma_addr_t tx_frag;
int rc = -EINVAL;
spin_lock_irqsave(&p_tx->lock, flags);
@@ -395,19 +386,13 @@ static int qed_ll2_txq_completion(struct qed_hwfn *p_hwfn, void *p_cookie)
list_add_tail(&p_pkt->list_entry, &p_tx->free_descq);
spin_unlock_irqrestore(&p_tx->lock, flags);
- tx_frag = p_pkt->bds_set[0].tx_frag;
- if (p_ll2_conn->input.gsi_enable)
- qed_ll2b_complete_tx_gsi_packet(p_hwfn,
- p_ll2_conn->my_id,
- p_pkt->cookie,
- tx_frag,
- b_last_frag, !num_bds);
- else
- qed_ll2b_complete_tx_packet(p_hwfn,
- p_ll2_conn->my_id,
- p_pkt->cookie,
- tx_frag,
- b_last_frag, !num_bds);
+
+ p_ll2_conn->cbs.tx_comp_cb(p_ll2_conn->cbs.cookie,
+ p_ll2_conn->my_id,
+ p_pkt->cookie,
+ p_pkt->bds_set[0].tx_frag,
+ b_last_frag, !num_bds);
+
spin_lock_irqsave(&p_tx->lock, flags);
}
@@ -418,52 +403,16 @@ static int qed_ll2_txq_completion(struct qed_hwfn *p_hwfn, void *p_cookie)
return rc;
}
-static int
-qed_ll2_rxq_completion_gsi(struct qed_hwfn *p_hwfn,
- struct qed_ll2_info *p_ll2_info,
- union core_rx_cqe_union *p_cqe,
- unsigned long lock_flags, bool b_last_cqe)
+static void qed_ll2_rxq_parse_gsi(struct qed_hwfn *p_hwfn,
+ union core_rx_cqe_union *p_cqe,
+ struct qed_ll2_comp_rx_data *data)
{
- struct qed_ll2_rx_queue *p_rx = &p_ll2_info->rx_queue;
- struct qed_ll2_rx_packet *p_pkt = NULL;
- u16 packet_length, parse_flags, vlan;
- u32 src_mac_addrhi;
- u16 src_mac_addrlo;
-
- if (!list_empty(&p_rx->active_descq))
- p_pkt = list_first_entry(&p_rx->active_descq,
- struct qed_ll2_rx_packet, list_entry);
- if (!p_pkt) {
- DP_NOTICE(p_hwfn,
- "GSI Rx completion but active_descq is empty\n");
- return -EIO;
- }
-
- list_del(&p_pkt->list_entry);
- parse_flags = le16_to_cpu(p_cqe->rx_cqe_gsi.parse_flags.flags);
- packet_length = le16_to_cpu(p_cqe->rx_cqe_gsi.data_length);
- vlan = le16_to_cpu(p_cqe->rx_cqe_gsi.vlan);
- src_mac_addrhi = le32_to_cpu(p_cqe->rx_cqe_gsi.src_mac_addrhi);
- src_mac_addrlo = le16_to_cpu(p_cqe->rx_cqe_gsi.src_mac_addrlo);
- if (qed_chain_consume(&p_rx->rxq_chain) != p_pkt->rxq_bd)
- DP_NOTICE(p_hwfn,
- "Mismatch between active_descq and the LL2 Rx chain\n");
- list_add_tail(&p_pkt->list_entry, &p_rx->free_descq);
-
- spin_unlock_irqrestore(&p_rx->lock, lock_flags);
- qed_ll2b_complete_rx_gsi_packet(p_hwfn,
- p_ll2_info->my_id,
- p_pkt->cookie,
- p_pkt->rx_buf_addr,
- packet_length,
- p_cqe->rx_cqe_gsi.data_length_error,
- parse_flags,
- vlan,
- src_mac_addrhi,
- src_mac_addrlo, b_last_cqe);
- spin_lock_irqsave(&p_rx->lock, lock_flags);
-
- return 0;
+ data->parse_flags = le16_to_cpu(p_cqe->rx_cqe_gsi.parse_flags.flags);
+ data->length.data_length = le16_to_cpu(p_cqe->rx_cqe_gsi.data_length);
+ data->vlan = le16_to_cpu(p_cqe->rx_cqe_gsi.vlan);
+ data->opaque_data_0 = le32_to_cpu(p_cqe->rx_cqe_gsi.src_mac_addrhi);
+ data->opaque_data_1 = le16_to_cpu(p_cqe->rx_cqe_gsi.src_mac_addrlo);
+ data->u.data_length_error = p_cqe->rx_cqe_gsi.data_length_error;
}
static void qed_ll2_rxq_parse_reg(struct qed_hwfn *p_hwfn,
@@ -501,7 +450,10 @@ qed_ll2_rxq_handle_completion(struct qed_hwfn *p_hwfn,
}
list_del(&p_pkt->list_entry);
- qed_ll2_rxq_parse_reg(p_hwfn, p_cqe, &data);
+ if (p_cqe->rx_cqe_sp.type == CORE_RX_CQE_TYPE_REGULAR)
+ qed_ll2_rxq_parse_reg(p_hwfn, p_cqe, &data);
+ else
+ qed_ll2_rxq_parse_gsi(p_hwfn, p_cqe, &data);
if (qed_chain_consume(&p_rx->rxq_chain) != p_pkt->rxq_bd)
DP_NOTICE(p_hwfn,
"Mismatch between active_descq and the LL2 Rx chain\n");
@@ -514,7 +466,8 @@ qed_ll2_rxq_handle_completion(struct qed_hwfn *p_hwfn,
data.b_last_packet = b_last_cqe;
spin_unlock_irqrestore(&p_rx->lock, *p_lock_flags);
- qed_ll2b_complete_rx_packet(p_hwfn, &data);
+ p_ll2_conn->cbs.rx_comp_cb(p_ll2_conn->cbs.cookie, &data);
+
spin_lock_irqsave(&p_rx->lock, *p_lock_flags);
return 0;
@@ -552,9 +505,6 @@ static int qed_ll2_rxq_completion(struct qed_hwfn *p_hwfn, void *cookie)
rc = -EINVAL;
break;
case CORE_RX_CQE_TYPE_GSI_OFFLOAD:
- rc = qed_ll2_rxq_completion_gsi(p_hwfn, p_ll2_conn,
- cqe, flags, b_last_cqe);
- break;
case CORE_RX_CQE_TYPE_REGULAR:
rc = qed_ll2_rxq_handle_completion(p_hwfn, p_ll2_conn,
cqe, &flags,
@@ -1244,6 +1194,23 @@ qed_ll2_acquire_connection_ooo(struct qed_hwfn *p_hwfn,
return rc;
}
+static int
+qed_ll2_set_cbs(struct qed_ll2_info *p_ll2_info, const struct qed_ll2_cbs *cbs)
+{
+ if (!cbs || (!cbs->rx_comp_cb ||
+ !cbs->rx_release_cb ||
+ !cbs->tx_comp_cb || !cbs->tx_release_cb || !cbs->cookie))
+ return -EINVAL;
+
+ p_ll2_info->cbs.rx_comp_cb = cbs->rx_comp_cb;
+ p_ll2_info->cbs.rx_release_cb = cbs->rx_release_cb;
+ p_ll2_info->cbs.tx_comp_cb = cbs->tx_comp_cb;
+ p_ll2_info->cbs.tx_release_cb = cbs->tx_release_cb;
+ p_ll2_info->cbs.cookie = cbs->cookie;
+
+ return 0;
+}
+
static enum core_error_handle
qed_ll2_get_error_choice(enum qed_ll2_error_handle err)
{
@@ -1259,9 +1226,9 @@ qed_ll2_get_error_choice(enum qed_ll2_error_handle err)
}
}
-int qed_ll2_acquire_connection(struct qed_hwfn *p_hwfn,
- struct qed_ll2_acquire_data *data)
+int qed_ll2_acquire_connection(void *cxt, struct qed_ll2_acquire_data *data)
{
+ struct qed_hwfn *p_hwfn = cxt;
qed_int_comp_cb_t comp_rx_cb, comp_tx_cb;
struct qed_ll2_info *p_ll2_info = NULL;
u8 i, *p_tx_max;
@@ -1298,6 +1265,13 @@ int qed_ll2_acquire_connection(struct qed_hwfn *p_hwfn,
else
*p_tx_max = min_t(u8, *p_tx_max,
CORE_LL2_TX_MAX_BDS_PER_PACKET);
+
+ rc = qed_ll2_set_cbs(p_ll2_info, data->cbs);
+ if (rc) {
+ DP_NOTICE(p_hwfn, "Invalid callback functions\n");
+ goto q_allocate_fail;
+ }
+
rc = qed_ll2_acquire_connection_rx(p_hwfn, p_ll2_info);
if (rc)
goto q_allocate_fail;
@@ -1377,8 +1351,10 @@ qed_ll2_establish_connection_ooo(struct qed_hwfn *p_hwfn,
qed_ooo_release_all_isles(p_hwfn, p_hwfn->p_ooo_info);
qed_ooo_submit_rx_buffers(p_hwfn, p_ll2_conn);
}
-int qed_ll2_establish_connection(struct qed_hwfn *p_hwfn, u8 connection_handle)
+
+int qed_ll2_establish_connection(void *cxt, u8 connection_handle)
{
+ struct qed_hwfn *p_hwfn = cxt;
struct qed_ll2_info *p_ll2_conn;
struct qed_ll2_rx_queue *p_rx;
struct qed_ll2_tx_queue *p_tx;
@@ -1505,11 +1481,12 @@ static void qed_ll2_post_rx_buffer_notify_fw(struct qed_hwfn *p_hwfn,
DIRECT_REG_WR(p_rx->set_prod_addr, *((u32 *)&rx_prod));
}
-int qed_ll2_post_rx_buffer(struct qed_hwfn *p_hwfn,
+int qed_ll2_post_rx_buffer(void *cxt,
u8 connection_handle,
dma_addr_t addr,
u16 buf_len, void *cookie, u8 notify_fw)
{
+ struct qed_hwfn *p_hwfn = cxt;
struct core_rx_bd_with_buff_len *p_curb = NULL;
struct qed_ll2_rx_packet *p_curp = NULL;
struct qed_ll2_info *p_ll2_conn;
@@ -1699,11 +1676,12 @@ static void qed_ll2_tx_packet_notify(struct qed_hwfn *p_hwfn,
p_ll2_conn->input.conn_type, db_msg.spq_prod);
}
-int qed_ll2_prepare_tx_packet(struct qed_hwfn *p_hwfn,
+int qed_ll2_prepare_tx_packet(void *cxt,
u8 connection_handle,
struct qed_ll2_tx_pkt_info *pkt,
bool notify_fw)
{
+ struct qed_hwfn *p_hwfn = cxt;
struct qed_ll2_tx_packet *p_curp = NULL;
struct qed_ll2_info *p_ll2_conn = NULL;
struct qed_ll2_tx_queue *p_tx;
@@ -1750,11 +1728,12 @@ int qed_ll2_prepare_tx_packet(struct qed_hwfn *p_hwfn,
return rc;
}
-int qed_ll2_set_fragment_of_tx_packet(struct qed_hwfn *p_hwfn,
+int qed_ll2_set_fragment_of_tx_packet(void *cxt,
u8 connection_handle,
dma_addr_t addr, u16 nbytes)
{
struct qed_ll2_tx_packet *p_cur_send_packet = NULL;
+ struct qed_hwfn *p_hwfn = cxt;
struct qed_ll2_info *p_ll2_conn = NULL;
u16 cur_send_frag_num = 0;
struct core_tx_bd *p_bd;
@@ -1789,8 +1768,9 @@ int qed_ll2_set_fragment_of_tx_packet(struct qed_hwfn *p_hwfn,
return 0;
}
-int qed_ll2_terminate_connection(struct qed_hwfn *p_hwfn, u8 connection_handle)
+int qed_ll2_terminate_connection(void *cxt, u8 connection_handle)
{
+ struct qed_hwfn *p_hwfn = cxt;
struct qed_ll2_info *p_ll2_conn = NULL;
int rc = -EINVAL;
struct qed_ptt *p_ptt;
@@ -1855,8 +1835,10 @@ static void qed_ll2_release_connection_ooo(struct qed_hwfn *p_hwfn,
kfree(p_buffer);
}
}
-void qed_ll2_release_connection(struct qed_hwfn *p_hwfn, u8 connection_handle)
+
+void qed_ll2_release_connection(void *cxt, u8 connection_handle)
{
+ struct qed_hwfn *p_hwfn = cxt;
struct qed_ll2_info *p_ll2_conn = NULL;
p_ll2_conn = qed_ll2_handle_sanity(p_hwfn, connection_handle);
@@ -1989,9 +1971,10 @@ static void _qed_ll2_get_pstats(struct qed_hwfn *p_hwfn,
p_stats->sent_bcast_pkts = HILO_64_REGPAIR(pstats.sent_bcast_pkts);
}
-int qed_ll2_get_stats(struct qed_hwfn *p_hwfn,
+int qed_ll2_get_stats(void *cxt,
u8 connection_handle, struct qed_ll2_stats *p_stats)
{
+ struct qed_hwfn *p_hwfn = cxt;
struct qed_ll2_info *p_ll2_conn = NULL;
struct qed_ptt *p_ptt;
@@ -2018,6 +2001,17 @@ int qed_ll2_get_stats(struct qed_hwfn *p_hwfn,
return 0;
}
+static void qed_ll2b_release_rx_packet(void *cxt,
+ u8 connection_handle,
+ void *cookie,
+ dma_addr_t rx_buf_addr,
+ bool b_last_packet)
+{
+ struct qed_hwfn *p_hwfn = cxt;
+
+ qed_ll2_dealloc_buffer(p_hwfn->cdev, cookie);
+}
+
static void qed_ll2_register_cb_ops(struct qed_dev *cdev,
const struct qed_ll2_cb_ops *ops,
void *cookie)
@@ -2026,11 +2020,18 @@ static void qed_ll2_register_cb_ops(struct qed_dev *cdev,
cdev->ll2->cb_cookie = cookie;
}
+struct qed_ll2_cbs ll2_cbs = {
+ .rx_comp_cb = &qed_ll2b_complete_rx_packet,
+ .rx_release_cb = &qed_ll2b_release_rx_packet,
+ .tx_comp_cb = &qed_ll2b_complete_tx_packet,
+ .tx_release_cb = &qed_ll2b_complete_tx_packet,
+};
+
static void qed_ll2_set_conn_data(struct qed_dev *cdev,
struct qed_ll2_acquire_data *data,
struct qed_ll2_params *params,
enum qed_ll2_conn_type conn_type,
- u8 *handle, bool lb, u8 gsi_enable)
+ u8 *handle, bool lb)
{
memset(data, 0, sizeof(*data));
@@ -2040,8 +2041,10 @@ static void qed_ll2_set_conn_data(struct qed_dev *cdev,
data->input.rx_drop_ttl0_flg = params->drop_ttl0_packets;
data->input.rx_vlan_removal_en = params->rx_vlan_stripping;
data->input.tx_num_desc = QED_LL2_TX_SIZE;
- data->input.gsi_enable = gsi_enable;
data->p_connection_handle = handle;
+ data->cbs = &ll2_cbs;
+ ll2_cbs.cookie = QED_LEADING_HWFN(cdev);
+
if (lb) {
data->input.tx_tc = OOO_LB_TC;
data->input.tx_dest = QED_LL2_TX_DEST_LB;
@@ -2060,7 +2063,7 @@ static int qed_ll2_start_ooo(struct qed_dev *cdev,
int rc;
qed_ll2_set_conn_data(cdev, &data, params,
- QED_LL2_TYPE_ISCSI_OOO, handle, true, 0);
+ QED_LL2_TYPE_ISCSI_OOO, handle, true);
rc = qed_ll2_acquire_connection(hwfn, &data);
if (rc) {
@@ -2090,7 +2093,7 @@ static int qed_ll2_start(struct qed_dev *cdev, struct qed_ll2_params *params)
struct qed_ll2_acquire_data data;
struct qed_ptt *p_ptt;
int rc, i;
- u8 gsi_enable = 1;
+
/* Initialize LL2 locks & lists */
INIT_LIST_HEAD(&cdev->ll2->list);
@@ -2122,11 +2125,9 @@ static int qed_ll2_start(struct qed_dev *cdev, struct qed_ll2_params *params)
switch (QED_LEADING_HWFN(cdev)->hw_info.personality) {
case QED_PCI_FCOE:
conn_type = QED_LL2_TYPE_FCOE;
- gsi_enable = 0;
break;
case QED_PCI_ISCSI:
conn_type = QED_LL2_TYPE_ISCSI;
- gsi_enable = 0;
break;
case QED_PCI_ETH_ROCE:
conn_type = QED_LL2_TYPE_ROCE;
@@ -2136,7 +2137,7 @@ static int qed_ll2_start(struct qed_dev *cdev, struct qed_ll2_params *params)
}
qed_ll2_set_conn_data(cdev, &data, params, conn_type,
- &cdev->ll2->handle, false, gsi_enable);
+ &cdev->ll2->handle, false);
rc = qed_ll2_acquire_connection(QED_LEADING_HWFN(cdev), &data);
if (rc) {
diff --git a/drivers/net/ethernet/qlogic/qed/qed_ll2.h b/drivers/net/ethernet/qlogic/qed/qed_ll2.h
index 3caaad5..a822528 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_ll2.h
+++ b/drivers/net/ethernet/qlogic/qed/qed_ll2.h
@@ -126,6 +126,7 @@ struct qed_ll2_info {
u8 tx_stats_en;
struct qed_ll2_rx_queue rx_queue;
struct qed_ll2_tx_queue tx_queue;
+ struct qed_ll2_cbs cbs;
};
/**
@@ -134,30 +135,29 @@ struct qed_ll2_info {
* connecion handler as output parameter.
*
*
- * @param p_hwfn
+ * @param cxt - pointer to the hw-function [opaque to some]
* @param data - describes connection parameters
* @return int
*/
-int qed_ll2_acquire_connection(struct qed_hwfn *p_hwfn,
- struct qed_ll2_acquire_data *data);
+int qed_ll2_acquire_connection(void *cxt, struct qed_ll2_acquire_data *data);
/**
* @brief qed_ll2_establish_connection - start previously
* allocated LL2 queues pair
*
- * @param p_hwfn
+ * @param cxt - pointer to the hw-function [opaque to some]
* @param p_ptt
* @param connection_handle LL2 connection's handle obtained from
* qed_ll2_require_connection
*
* @return 0 on success, failure otherwise
*/
-int qed_ll2_establish_connection(struct qed_hwfn *p_hwfn, u8 connection_handle);
+int qed_ll2_establish_connection(void *cxt, u8 connection_handle);
/**
* @brief qed_ll2_post_rx_buffers - submit buffers to LL2 Rx queue.
*
- * @param p_hwfn
+ * @param cxt - pointer to the hw-function [opaque to some]
* @param connection_handle LL2 connection's handle obtained from
* qed_ll2_require_connection
* @param addr rx (physical address) buffers to submit
@@ -166,7 +166,7 @@ int qed_ll2_establish_connection(struct qed_hwfn *p_hwfn, u8 connection_handle);
*
* @return 0 on success, failure otherwise
*/
-int qed_ll2_post_rx_buffer(struct qed_hwfn *p_hwfn,
+int qed_ll2_post_rx_buffer(void *cxt,
u8 connection_handle,
dma_addr_t addr,
u16 buf_len, void *cookie, u8 notify_fw);
@@ -175,14 +175,14 @@ int qed_ll2_post_rx_buffer(struct qed_hwfn *p_hwfn,
* @brief qed_ll2_prepare_tx_packet - request for start Tx BD
* to prepare Tx packet submission to FW.
*
- * @param p_hwfn
+ * @param cxt - pointer to the hw-function [opaque to some]
* @param connection_handle
* @param pkt - info regarding the tx packet
* @param notify_fw - issue doorbell to fw for this packet
*
* @return 0 on success, failure otherwise
*/
-int qed_ll2_prepare_tx_packet(struct qed_hwfn *p_hwfn,
+int qed_ll2_prepare_tx_packet(void *cxt,
u8 connection_handle,
struct qed_ll2_tx_pkt_info *pkt,
bool notify_fw);
@@ -191,18 +191,18 @@ int qed_ll2_prepare_tx_packet(struct qed_hwfn *p_hwfn,
* @brief qed_ll2_release_connection - releases resources
* allocated for LL2 connection
*
- * @param p_hwfn
+ * @param cxt - pointer to the hw-function [opaque to some]
* @param connection_handle LL2 connection's handle obtained from
* qed_ll2_require_connection
*/
-void qed_ll2_release_connection(struct qed_hwfn *p_hwfn, u8 connection_handle);
+void qed_ll2_release_connection(void *cxt, u8 connection_handle);
/**
* @brief qed_ll2_set_fragment_of_tx_packet - provides fragments to fill
* Tx BD of BDs requested by
* qed_ll2_prepare_tx_packet
*
- * @param p_hwfn
+ * @param cxt - pointer to the hw-function [opaque to some]
* @param connection_handle LL2 connection's handle
* obtained from
* qed_ll2_require_connection
@@ -211,7 +211,7 @@ void qed_ll2_release_connection(struct qed_hwfn *p_hwfn, u8 connection_handle);
*
* @return 0 on success, failure otherwise
*/
-int qed_ll2_set_fragment_of_tx_packet(struct qed_hwfn *p_hwfn,
+int qed_ll2_set_fragment_of_tx_packet(void *cxt,
u8 connection_handle,
dma_addr_t addr, u16 nbytes);
@@ -219,27 +219,27 @@ int qed_ll2_set_fragment_of_tx_packet(struct qed_hwfn *p_hwfn,
* @brief qed_ll2_terminate_connection - stops Tx/Rx queues
*
*
- * @param p_hwfn
+ * @param cxt - pointer to the hw-function [opaque to some]
* @param connection_handle LL2 connection's handle
* obtained from
* qed_ll2_require_connection
*
* @return 0 on success, failure otherwise
*/
-int qed_ll2_terminate_connection(struct qed_hwfn *p_hwfn, u8 connection_handle);
+int qed_ll2_terminate_connection(void *cxt, u8 connection_handle);
/**
* @brief qed_ll2_get_stats - get LL2 queue's statistics
*
*
- * @param p_hwfn
+ * @param cxt - pointer to the hw-function [opaque to some]
* @param connection_handle LL2 connection's handle obtained from
* qed_ll2_require_connection
* @param p_stats
*
* @return 0 on success, failure otherwise
*/
-int qed_ll2_get_stats(struct qed_hwfn *p_hwfn,
+int qed_ll2_get_stats(void *cxt,
u8 connection_handle, struct qed_ll2_stats *p_stats);
/**
diff --git a/drivers/net/ethernet/qlogic/qed/qed_roce.c b/drivers/net/ethernet/qlogic/qed/qed_roce.c
index 33abcf1..4bc2f6c 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_roce.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_roce.c
@@ -35,7 +35,6 @@
#include <linux/delay.h>
#include <linux/dma-mapping.h>
#include <linux/errno.h>
-#include <linux/etherdevice.h>
#include <linux/if_ether.h>
#include <linux/if_vlan.h>
#include <linux/io.h>
@@ -65,6 +64,7 @@
#include "qed_sp.h"
#include "qed_roce.h"
#include "qed_ll2.h"
+#include <linux/qed/qed_ll2_if.h>
static void qed_roce_free_real_icid(struct qed_hwfn *p_hwfn, u16 icid);
@@ -2709,310 +2709,35 @@ static void qed_rdma_remove_user(void *rdma_cxt, u16 dpi)
spin_unlock_bh(&p_hwfn->p_rdma_info->lock);
}
-void qed_ll2b_complete_tx_gsi_packet(struct qed_hwfn *p_hwfn,
- u8 connection_handle,
- void *cookie,
- dma_addr_t first_frag_addr,
- bool b_last_fragment, bool b_last_packet)
-{
- struct qed_roce_ll2_packet *packet = cookie;
- struct qed_roce_ll2_info *roce_ll2 = p_hwfn->ll2;
-
- roce_ll2->cbs.tx_cb(roce_ll2->cb_cookie, packet);
-}
-
-void qed_ll2b_release_tx_gsi_packet(struct qed_hwfn *p_hwfn,
- u8 connection_handle,
- void *cookie,
- dma_addr_t first_frag_addr,
- bool b_last_fragment, bool b_last_packet)
-{
- qed_ll2b_complete_tx_gsi_packet(p_hwfn, connection_handle,
- cookie, first_frag_addr,
- b_last_fragment, b_last_packet);
-}
-
-void qed_ll2b_complete_rx_gsi_packet(struct qed_hwfn *p_hwfn,
- u8 connection_handle,
- void *cookie,
- dma_addr_t rx_buf_addr,
- u16 data_length,
- u8 data_length_error,
- u16 parse_flags,
- u16 vlan,
- u32 src_mac_addr_hi,
- u16 src_mac_addr_lo, bool b_last_packet)
-{
- struct qed_roce_ll2_info *roce_ll2 = p_hwfn->ll2;
- struct qed_roce_ll2_rx_params params;
- struct qed_dev *cdev = p_hwfn->cdev;
- struct qed_roce_ll2_packet pkt;
-
- DP_VERBOSE(cdev,
- QED_MSG_LL2,
- "roce ll2 rx complete: bus_addr=%p, len=%d, data_len_err=%d\n",
- (void *)(uintptr_t)rx_buf_addr,
- data_length, data_length_error);
-
- memset(&pkt, 0, sizeof(pkt));
- pkt.n_seg = 1;
- pkt.payload[0].baddr = rx_buf_addr;
- pkt.payload[0].len = data_length;
-
- memset(¶ms, 0, sizeof(params));
- params.vlan_id = vlan;
- *((u32 *)¶ms.smac[0]) = ntohl(src_mac_addr_hi);
- *((u16 *)¶ms.smac[4]) = ntohs(src_mac_addr_lo);
-
- if (data_length_error) {
- DP_ERR(cdev,
- "roce ll2 rx complete: data length error %d, length=%d\n",
- data_length_error, data_length);
- params.rc = -EINVAL;
- }
-
- roce_ll2->cbs.rx_cb(roce_ll2->cb_cookie, &pkt, ¶ms);
-}
-
static int qed_roce_ll2_set_mac_filter(struct qed_dev *cdev,
u8 *old_mac_address,
u8 *new_mac_address)
{
- struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev);
+ struct qed_hwfn *p_hwfn = QED_LEADING_HWFN(cdev);
struct qed_ptt *p_ptt;
int rc = 0;
- if (!hwfn->ll2 || hwfn->ll2->handle == QED_LL2_UNUSED_HANDLE) {
- DP_ERR(cdev,
- "qed roce mac filter failed - roce_info/ll2 NULL\n");
- return -EINVAL;
- }
-
- p_ptt = qed_ptt_acquire(QED_LEADING_HWFN(cdev));
+ p_ptt = qed_ptt_acquire(p_hwfn);
if (!p_ptt) {
DP_ERR(cdev,
"qed roce ll2 mac filter set: failed to acquire PTT\n");
return -EINVAL;
}
- mutex_lock(&hwfn->ll2->lock);
if (old_mac_address)
- qed_llh_remove_mac_filter(QED_LEADING_HWFN(cdev), p_ptt,
- old_mac_address);
+ qed_llh_remove_mac_filter(p_hwfn, p_ptt, old_mac_address);
if (new_mac_address)
- rc = qed_llh_add_mac_filter(QED_LEADING_HWFN(cdev), p_ptt,
- new_mac_address);
- mutex_unlock(&hwfn->ll2->lock);
-
- qed_ptt_release(QED_LEADING_HWFN(cdev), p_ptt);
-
- if (rc)
- DP_ERR(cdev,
- "qed roce ll2 mac filter set: failed to add mac filter\n");
-
- return rc;
-}
-
-static int qed_roce_ll2_start(struct qed_dev *cdev,
- struct qed_roce_ll2_params *params)
-{
- struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev);
- struct qed_roce_ll2_info *roce_ll2;
- struct qed_ll2_acquire_data data;
- int rc;
-
- if (!params) {
- DP_ERR(cdev, "qed roce ll2 start: failed due to NULL params\n");
- return -EINVAL;
- }
- if (!params->cbs.tx_cb || !params->cbs.rx_cb) {
- DP_ERR(cdev,
- "qed roce ll2 start: failed due to NULL tx/rx. tx_cb=%p, rx_cb=%p\n",
- params->cbs.tx_cb, params->cbs.rx_cb);
- return -EINVAL;
- }
- if (!is_valid_ether_addr(params->mac_address)) {
- DP_ERR(cdev,
- "qed roce ll2 start: failed due to invalid Ethernet address %pM\n",
- params->mac_address);
- return -EINVAL;
- }
-
- /* Initialize */
- roce_ll2 = kzalloc(sizeof(*roce_ll2), GFP_ATOMIC);
- if (!roce_ll2) {
- DP_ERR(cdev, "qed roce ll2 start: failed memory allocation\n");
- return -ENOMEM;
- }
+ rc = qed_llh_add_mac_filter(p_hwfn, p_ptt, new_mac_address);
- roce_ll2->handle = QED_LL2_UNUSED_HANDLE;
- roce_ll2->cbs = params->cbs;
- roce_ll2->cb_cookie = params->cb_cookie;
- mutex_init(&roce_ll2->lock);
-
- memset(&data, 0, sizeof(data));
- data.input.conn_type = QED_LL2_TYPE_ROCE;
- data.input.mtu = params->mtu;
- data.input.rx_num_desc = params->max_rx_buffers;
- data.input.tx_num_desc = params->max_tx_buffers;
- data.input.rx_drop_ttl0_flg = true;
- data.input.rx_vlan_removal_en = false;
- data.input.tx_dest = QED_LL2_TX_DEST_NW;
- data.input.ai_err_packet_too_big = LL2_DROP_PACKET;
- data.input.ai_err_no_buf = LL2_DROP_PACKET;
- data.p_connection_handle = &roce_ll2->handle;
- data.input.gsi_enable = true;
-
- rc = qed_ll2_acquire_connection(QED_LEADING_HWFN(cdev), &data);
- if (rc) {
- DP_ERR(cdev,
- "qed roce ll2 start: failed to acquire LL2 connection (rc=%d)\n",
- rc);
- goto err;
- }
-
- rc = qed_ll2_establish_connection(QED_LEADING_HWFN(cdev),
- roce_ll2->handle);
- if (rc) {
- DP_ERR(cdev,
- "qed roce ll2 start: failed to establish LL2 connection (rc=%d)\n",
- rc);
- goto err1;
- }
-
- hwfn->ll2 = roce_ll2;
-
- rc = qed_roce_ll2_set_mac_filter(cdev, NULL, params->mac_address);
- if (rc) {
- hwfn->ll2 = NULL;
- goto err2;
- }
- ether_addr_copy(roce_ll2->mac_address, params->mac_address);
-
- return 0;
-
-err2:
- qed_ll2_terminate_connection(QED_LEADING_HWFN(cdev), roce_ll2->handle);
-err1:
- qed_ll2_release_connection(QED_LEADING_HWFN(cdev), roce_ll2->handle);
-err:
- kfree(roce_ll2);
- return rc;
-}
-
-static int qed_roce_ll2_stop(struct qed_dev *cdev)
-{
- struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev);
- struct qed_roce_ll2_info *roce_ll2 = hwfn->ll2;
- int rc;
-
- if (roce_ll2->handle == QED_LL2_UNUSED_HANDLE) {
- DP_ERR(cdev, "qed roce ll2 stop: cannot stop an unused LL2\n");
- return -EINVAL;
- }
-
- /* remove LL2 MAC address filter */
- rc = qed_roce_ll2_set_mac_filter(cdev, roce_ll2->mac_address, NULL);
- eth_zero_addr(roce_ll2->mac_address);
+ qed_ptt_release(p_hwfn, p_ptt);
- rc = qed_ll2_terminate_connection(QED_LEADING_HWFN(cdev),
- roce_ll2->handle);
if (rc)
DP_ERR(cdev,
- "qed roce ll2 stop: failed to terminate LL2 connection (rc=%d)\n",
- rc);
-
- qed_ll2_release_connection(QED_LEADING_HWFN(cdev), roce_ll2->handle);
-
- roce_ll2->handle = QED_LL2_UNUSED_HANDLE;
-
- kfree(roce_ll2);
+ "qed roce ll2 mac filter set: failed to add MAC filter\n");
return rc;
}
-static int qed_roce_ll2_tx(struct qed_dev *cdev,
- struct qed_roce_ll2_packet *pkt,
- struct qed_roce_ll2_tx_params *params)
-{
- struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev);
- struct qed_roce_ll2_info *roce_ll2 = hwfn->ll2;
- enum qed_ll2_roce_flavor_type qed_roce_flavor;
- struct qed_ll2_tx_pkt_info ll2_pkt;
- u8 flags = 0;
- int rc;
- int i;
-
- if (!pkt || !params) {
- DP_ERR(cdev,
- "roce ll2 tx: failed tx because one of the following is NULL - drv=%p, pkt=%p, params=%p\n",
- cdev, pkt, params);
- return -EINVAL;
- }
-
- qed_roce_flavor = (pkt->roce_mode == ROCE_V1) ? QED_LL2_ROCE
- : QED_LL2_RROCE;
-
- if (pkt->roce_mode == ROCE_V2_IPV4)
- flags |= BIT(CORE_TX_BD_DATA_IP_CSUM_SHIFT);
-
- /* Tx header */
- memset(&ll2_pkt, 0, sizeof(ll2_pkt));
- ll2_pkt.num_of_bds = 1 + pkt->n_seg;
- ll2_pkt.bd_flags = flags;
- ll2_pkt.tx_dest = QED_LL2_TX_DEST_NW;
- ll2_pkt.qed_roce_flavor = qed_roce_flavor;
- ll2_pkt.first_frag = pkt->header.baddr;
- ll2_pkt.first_frag_len = pkt->header.len;
- ll2_pkt.cookie = pkt;
-
- rc = qed_ll2_prepare_tx_packet(QED_LEADING_HWFN(cdev),
- roce_ll2->handle,
- &ll2_pkt, 1);
- if (rc) {
- DP_ERR(cdev, "roce ll2 tx: header failed (rc=%d)\n", rc);
- return QED_ROCE_TX_HEAD_FAILURE;
- }
-
- /* Tx payload */
- for (i = 0; i < pkt->n_seg; i++) {
- rc = qed_ll2_set_fragment_of_tx_packet(QED_LEADING_HWFN(cdev),
- roce_ll2->handle,
- pkt->payload[i].baddr,
- pkt->payload[i].len);
- if (rc) {
- /* If failed not much to do here, partial packet has
- * been posted * we can't free memory, will need to wait
- * for completion
- */
- DP_ERR(cdev,
- "roce ll2 tx: payload failed (rc=%d)\n", rc);
- return QED_ROCE_TX_FRAG_FAILURE;
- }
- }
-
- return 0;
-}
-
-static int qed_roce_ll2_post_rx_buffer(struct qed_dev *cdev,
- struct qed_roce_ll2_buffer *buf,
- u64 cookie, u8 notify_fw)
-{
- return qed_ll2_post_rx_buffer(QED_LEADING_HWFN(cdev),
- QED_LEADING_HWFN(cdev)->ll2->handle,
- buf->baddr, buf->len,
- (void *)(uintptr_t)cookie, notify_fw);
-}
-
-static int qed_roce_ll2_stats(struct qed_dev *cdev, struct qed_ll2_stats *stats)
-{
- struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev);
- struct qed_roce_ll2_info *roce_ll2 = hwfn->ll2;
-
- return qed_ll2_get_stats(QED_LEADING_HWFN(cdev),
- roce_ll2->handle, stats);
-}
-
static const struct qed_rdma_ops qed_rdma_ops_pass = {
.common = &qed_common_ops_pass,
.fill_dev_info = &qed_fill_rdma_dev_info,
@@ -3040,12 +2765,15 @@ static const struct qed_rdma_ops qed_rdma_ops_pass = {
.rdma_free_tid = &qed_rdma_free_tid,
.rdma_register_tid = &qed_rdma_register_tid,
.rdma_deregister_tid = &qed_rdma_deregister_tid,
- .roce_ll2_start = &qed_roce_ll2_start,
- .roce_ll2_stop = &qed_roce_ll2_stop,
- .roce_ll2_tx = &qed_roce_ll2_tx,
- .roce_ll2_post_rx_buffer = &qed_roce_ll2_post_rx_buffer,
- .roce_ll2_set_mac_filter = &qed_roce_ll2_set_mac_filter,
- .roce_ll2_stats = &qed_roce_ll2_stats,
+ .ll2_acquire_connection = &qed_ll2_acquire_connection,
+ .ll2_establish_connection = &qed_ll2_establish_connection,
+ .ll2_terminate_connection = &qed_ll2_terminate_connection,
+ .ll2_release_connection = &qed_ll2_release_connection,
+ .ll2_post_rx_buffer = &qed_ll2_post_rx_buffer,
+ .ll2_prepare_tx_packet = &qed_ll2_prepare_tx_packet,
+ .ll2_set_fragment_of_tx_packet = &qed_ll2_set_fragment_of_tx_packet,
+ .ll2_set_mac_filter = &qed_roce_ll2_set_mac_filter,
+ .ll2_get_stats = &qed_ll2_get_stats,
};
const struct qed_rdma_ops *qed_get_rdma_ops(void)
diff --git a/drivers/net/ethernet/qlogic/qed/qed_roce.h b/drivers/net/ethernet/qlogic/qed/qed_roce.h
index 9742af5..94be3b5 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_roce.h
+++ b/drivers/net/ethernet/qlogic/qed/qed_roce.h
@@ -170,53 +170,10 @@ struct qed_rdma_qp {
void qed_rdma_dpm_bar(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt);
void qed_roce_async_event(struct qed_hwfn *p_hwfn,
u8 fw_event_code, union rdma_eqe_data *rdma_data);
-void qed_ll2b_complete_tx_gsi_packet(struct qed_hwfn *p_hwfn,
- u8 connection_handle,
- void *cookie,
- dma_addr_t first_frag_addr,
- bool b_last_fragment, bool b_last_packet);
-void qed_ll2b_release_tx_gsi_packet(struct qed_hwfn *p_hwfn,
- u8 connection_handle,
- void *cookie,
- dma_addr_t first_frag_addr,
- bool b_last_fragment, bool b_last_packet);
-void qed_ll2b_complete_rx_gsi_packet(struct qed_hwfn *p_hwfn,
- u8 connection_handle,
- void *cookie,
- dma_addr_t rx_buf_addr,
- u16 data_length,
- u8 data_length_error,
- u16 parse_flags,
- u16 vlan,
- u32 src_mac_addr_hi,
- u16 src_mac_addr_lo, bool b_last_packet);
#else
static inline void qed_rdma_dpm_bar(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt) {}
static inline void qed_roce_async_event(struct qed_hwfn *p_hwfn,
u8 fw_event_code,
union rdma_eqe_data *rdma_data) {}
-static inline void qed_ll2b_complete_tx_gsi_packet(struct qed_hwfn *p_hwfn,
- u8 connection_handle,
- void *cookie,
- dma_addr_t first_frag_addr,
- bool b_last_fragment,
- bool b_last_packet) {}
-static inline void qed_ll2b_release_tx_gsi_packet(struct qed_hwfn *p_hwfn,
- u8 connection_handle,
- void *cookie,
- dma_addr_t first_frag_addr,
- bool b_last_fragment,
- bool b_last_packet) {}
-static inline void qed_ll2b_complete_rx_gsi_packet(struct qed_hwfn *p_hwfn,
- u8 connection_handle,
- void *cookie,
- dma_addr_t rx_buf_addr,
- u16 data_length,
- u8 data_length_error,
- u16 parse_flags,
- u16 vlan,
- u32 src_mac_addr_hi,
- u16 src_mac_addr_lo,
- bool b_last_packet) {}
#endif
#endif
diff --git a/include/linux/qed/qed_ll2_if.h b/include/linux/qed/qed_ll2_if.h
index a1f63ec..5958b45e 100644
--- a/include/linux/qed/qed_ll2_if.h
+++ b/include/linux/qed/qed_ll2_if.h
@@ -122,6 +122,40 @@ struct qed_ll2_comp_rx_data {
} u;
};
+typedef
+void (*qed_ll2_complete_rx_packet_cb)(void *cxt,
+ struct qed_ll2_comp_rx_data *data);
+
+typedef
+void (*qed_ll2_release_rx_packet_cb)(void *cxt,
+ u8 connection_handle,
+ void *cookie,
+ dma_addr_t rx_buf_addr,
+ bool b_last_packet);
+
+typedef
+void (*qed_ll2_complete_tx_packet_cb)(void *cxt,
+ u8 connection_handle,
+ void *cookie,
+ dma_addr_t first_frag_addr,
+ bool b_last_fragment,
+ bool b_last_packet);
+
+typedef
+void (*qed_ll2_release_tx_packet_cb)(void *cxt,
+ u8 connection_handle,
+ void *cookie,
+ dma_addr_t first_frag_addr,
+ bool b_last_fragment, bool b_last_packet);
+
+struct qed_ll2_cbs {
+ qed_ll2_complete_rx_packet_cb rx_comp_cb;
+ qed_ll2_release_rx_packet_cb rx_release_cb;
+ qed_ll2_complete_tx_packet_cb tx_comp_cb;
+ qed_ll2_release_tx_packet_cb tx_release_cb;
+ void *cookie;
+};
+
struct qed_ll2_acquire_data_inputs {
enum qed_ll2_conn_type conn_type;
u16 mtu;
@@ -140,6 +174,8 @@ struct qed_ll2_acquire_data_inputs {
struct qed_ll2_acquire_data {
struct qed_ll2_acquire_data_inputs input;
+ const struct qed_ll2_cbs *cbs;
+
/* Output container for LL2 connection's handle */
u8 *p_connection_handle;
};
diff --git a/include/linux/qed/qed_roce_if.h b/include/linux/qed/qed_roce_if.h
index cbb2ff0..8e70f5e 100644
--- a/include/linux/qed/qed_roce_if.h
+++ b/include/linux/qed/qed_roce_if.h
@@ -34,8 +34,6 @@
#include <linux/types.h>
#include <linux/delay.h>
#include <linux/list.h>
-#include <linux/mutex.h>
-#include <linux/pci.h>
#include <linux/slab.h>
#include <linux/qed/qed_if.h>
#include <linux/qed/qed_ll2_if.h>
@@ -491,42 +489,6 @@ struct qed_roce_ll2_packet {
enum qed_roce_ll2_tx_dest tx_dest;
};
-struct qed_roce_ll2_tx_params {
- int reserved;
-};
-
-struct qed_roce_ll2_rx_params {
- u16 vlan_id;
- u8 smac[ETH_ALEN];
- int rc;
-};
-
-struct qed_roce_ll2_cbs {
- void (*tx_cb)(void *pdev, struct qed_roce_ll2_packet *pkt);
-
- void (*rx_cb)(void *pdev, struct qed_roce_ll2_packet *pkt,
- struct qed_roce_ll2_rx_params *params);
-};
-
-struct qed_roce_ll2_params {
- u16 max_rx_buffers;
- u16 max_tx_buffers;
- u16 mtu;
- u8 mac_address[ETH_ALEN];
- struct qed_roce_ll2_cbs cbs;
- void *cb_cookie;
-};
-
-struct qed_roce_ll2_info {
- u8 handle;
- struct qed_roce_ll2_cbs cbs;
- u8 mac_address[ETH_ALEN];
- void *cb_cookie;
-
- /* Lock to protect ll2 */
- struct mutex lock;
-};
-
enum qed_rdma_type {
QED_RDMA_TYPE_ROCE,
};
@@ -579,26 +541,40 @@ struct qed_rdma_ops {
int (*rdma_query_qp)(void *rdma_cxt, struct qed_rdma_qp *qp,
struct qed_rdma_query_qp_out_params *oparams);
int (*rdma_destroy_qp)(void *rdma_cxt, struct qed_rdma_qp *qp);
+
int
(*rdma_register_tid)(void *rdma_cxt,
struct qed_rdma_register_tid_in_params *iparams);
+
int (*rdma_deregister_tid)(void *rdma_cxt, u32 itid);
int (*rdma_alloc_tid)(void *rdma_cxt, u32 *itid);
void (*rdma_free_tid)(void *rdma_cxt, u32 itid);
- int (*roce_ll2_start)(struct qed_dev *cdev,
- struct qed_roce_ll2_params *params);
- int (*roce_ll2_stop)(struct qed_dev *cdev);
- int (*roce_ll2_tx)(struct qed_dev *cdev,
- struct qed_roce_ll2_packet *packet,
- struct qed_roce_ll2_tx_params *params);
- int (*roce_ll2_post_rx_buffer)(struct qed_dev *cdev,
- struct qed_roce_ll2_buffer *buf,
- u64 cookie, u8 notify_fw);
- int (*roce_ll2_set_mac_filter)(struct qed_dev *cdev,
- u8 *old_mac_address,
- u8 *new_mac_address);
- int (*roce_ll2_stats)(struct qed_dev *cdev,
- struct qed_ll2_stats *stats);
+
+ int (*ll2_acquire_connection)(void *rdma_cxt,
+ struct qed_ll2_acquire_data *data);
+
+ int (*ll2_establish_connection)(void *rdma_cxt, u8 connection_handle);
+ int (*ll2_terminate_connection)(void *rdma_cxt, u8 connection_handle);
+ void (*ll2_release_connection)(void *rdma_cxt, u8 connection_handle);
+
+ int (*ll2_prepare_tx_packet)(void *rdma_cxt,
+ u8 connection_handle,
+ struct qed_ll2_tx_pkt_info *pkt,
+ bool notify_fw);
+
+ int (*ll2_set_fragment_of_tx_packet)(void *rdma_cxt,
+ u8 connection_handle,
+ dma_addr_t addr,
+ u16 nbytes);
+ int (*ll2_post_rx_buffer)(void *rdma_cxt, u8 connection_handle,
+ dma_addr_t addr, u16 buf_len, void *cookie,
+ u8 notify_fw);
+ int (*ll2_get_stats)(void *rdma_cxt,
+ u8 connection_handle,
+ struct qed_ll2_stats *p_stats);
+ int (*ll2_set_mac_filter)(struct qed_dev *cdev,
+ u8 *old_mac_address, u8 *new_mac_address);
+
};
const struct qed_rdma_ops *qed_get_rdma_ops(void);
--
2.9.4
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH v2 net-next 4/8] qed: LL2 code relocations
From: Yuval Mintz @ 2017-06-09 14:13 UTC (permalink / raw)
To: netdev-u79uwXL29TY76Z2rM5mHXA, davem-fT/PcQaiUtIeIZ0/mPfg9Q
Cc: linux-rdma-u79uwXL29TY76Z2rM5mHXA,
Michal.Kalderon-YGCgFSpz5w/QT0dZR+AlfA, Yuval Mintz
In-Reply-To: <20170609141325.20547-1-Yuval.Mintz-YGCgFSpz5w/QT0dZR+AlfA@public.gmane.org>
Instead of having the OOO logic packetd, divide it with rest of code
according to establish/release flows.
Signed-off-by: Yuval Mintz <Yuval.Mintz-YGCgFSpz5w/QT0dZR+AlfA@public.gmane.org>
---
drivers/net/ethernet/qlogic/qed/qed_ll2.c | 58 +++++++++++++++----------------
1 file changed, 28 insertions(+), 30 deletions(-)
diff --git a/drivers/net/ethernet/qlogic/qed/qed_ll2.c b/drivers/net/ethernet/qlogic/qed/qed_ll2.c
index fcf4ea9..f3aad61 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_ll2.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_ll2.c
@@ -896,36 +896,6 @@ static int qed_ll2_lb_txq_completion(struct qed_hwfn *p_hwfn, void *p_cookie)
return 0;
}
-static void
-qed_ll2_establish_connection_ooo(struct qed_hwfn *p_hwfn,
- struct qed_ll2_info *p_ll2_conn)
-{
- if (p_ll2_conn->input.conn_type != QED_LL2_TYPE_ISCSI_OOO)
- return;
-
- qed_ooo_release_all_isles(p_hwfn, p_hwfn->p_ooo_info);
- qed_ooo_submit_rx_buffers(p_hwfn, p_ll2_conn);
-}
-
-static void qed_ll2_release_connection_ooo(struct qed_hwfn *p_hwfn,
- struct qed_ll2_info *p_ll2_conn)
-{
- struct qed_ooo_buffer *p_buffer;
-
- if (p_ll2_conn->input.conn_type != QED_LL2_TYPE_ISCSI_OOO)
- return;
-
- qed_ooo_release_all_isles(p_hwfn, p_hwfn->p_ooo_info);
- while ((p_buffer = qed_ooo_get_free_buffer(p_hwfn,
- p_hwfn->p_ooo_info))) {
- dma_free_coherent(&p_hwfn->cdev->pdev->dev,
- p_buffer->rx_buffer_size,
- p_buffer->rx_buffer_virt_addr,
- p_buffer->rx_buffer_phys_addr);
- kfree(p_buffer);
- }
-}
-
static void qed_ll2_stop_ooo(struct qed_dev *cdev)
{
struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev);
@@ -1397,6 +1367,16 @@ static int qed_ll2_establish_connection_rx(struct qed_hwfn *p_hwfn,
return qed_sp_ll2_rx_queue_start(p_hwfn, p_ll2_conn, action_on_error);
}
+static void
+qed_ll2_establish_connection_ooo(struct qed_hwfn *p_hwfn,
+ struct qed_ll2_info *p_ll2_conn)
+{
+ if (p_ll2_conn->input.conn_type != QED_LL2_TYPE_ISCSI_OOO)
+ return;
+
+ qed_ooo_release_all_isles(p_hwfn, p_hwfn->p_ooo_info);
+ qed_ooo_submit_rx_buffers(p_hwfn, p_ll2_conn);
+}
int qed_ll2_establish_connection(struct qed_hwfn *p_hwfn, u8 connection_handle)
{
struct qed_ll2_info *p_ll2_conn;
@@ -1857,6 +1837,24 @@ int qed_ll2_terminate_connection(struct qed_hwfn *p_hwfn, u8 connection_handle)
return rc;
}
+static void qed_ll2_release_connection_ooo(struct qed_hwfn *p_hwfn,
+ struct qed_ll2_info *p_ll2_conn)
+{
+ struct qed_ooo_buffer *p_buffer;
+
+ if (p_ll2_conn->input.conn_type != QED_LL2_TYPE_ISCSI_OOO)
+ return;
+
+ qed_ooo_release_all_isles(p_hwfn, p_hwfn->p_ooo_info);
+ while ((p_buffer = qed_ooo_get_free_buffer(p_hwfn,
+ p_hwfn->p_ooo_info))) {
+ dma_free_coherent(&p_hwfn->cdev->pdev->dev,
+ p_buffer->rx_buffer_size,
+ p_buffer->rx_buffer_virt_addr,
+ p_buffer->rx_buffer_phys_addr);
+ kfree(p_buffer);
+ }
+}
void qed_ll2_release_connection(struct qed_hwfn *p_hwfn, u8 connection_handle)
{
struct qed_ll2_info *p_ll2_conn = NULL;
--
2.9.4
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH v2 net-next 2/8] qed: Revise ll2 Rx completion
From: Yuval Mintz @ 2017-06-09 14:13 UTC (permalink / raw)
To: netdev-u79uwXL29TY76Z2rM5mHXA, davem-fT/PcQaiUtIeIZ0/mPfg9Q
Cc: linux-rdma-u79uwXL29TY76Z2rM5mHXA,
Michal.Kalderon-YGCgFSpz5w/QT0dZR+AlfA, Yuval Mintz
In-Reply-To: <20170609141325.20547-1-Yuval.Mintz-YGCgFSpz5w/QT0dZR+AlfA@public.gmane.org>
This introduces qed_ll2_comp_rx_data as a public struct
and moves handling of Rx packets in LL2 into using it.
Signed-off-by: Yuval Mintz <Yuval.Mintz-YGCgFSpz5w/QT0dZR+AlfA@public.gmane.org>
---
drivers/net/ethernet/qlogic/qed/qed_ll2.c | 84 ++++++++++++++++++-------------
include/linux/qed/qed_ll2_if.h | 26 ++++++++++
2 files changed, 76 insertions(+), 34 deletions(-)
diff --git a/drivers/net/ethernet/qlogic/qed/qed_ll2.c b/drivers/net/ethernet/qlogic/qed/qed_ll2.c
index 0b75f5d..46b71a6 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_ll2.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_ll2.c
@@ -165,41 +165,33 @@ static void qed_ll2_kill_buffers(struct qed_dev *cdev)
}
static void qed_ll2b_complete_rx_packet(struct qed_hwfn *p_hwfn,
- u8 connection_handle,
- struct qed_ll2_rx_packet *p_pkt,
- struct core_rx_fast_path_cqe *p_cqe,
- bool b_last_packet)
+ struct qed_ll2_comp_rx_data *data)
{
- u16 packet_length = le16_to_cpu(p_cqe->packet_length);
- struct qed_ll2_buffer *buffer = p_pkt->cookie;
+ struct qed_ll2_buffer *buffer = data->cookie;
struct qed_dev *cdev = p_hwfn->cdev;
- u16 vlan = le16_to_cpu(p_cqe->vlan);
- u32 opaque_data_0, opaque_data_1;
- u8 pad = p_cqe->placement_offset;
dma_addr_t new_phys_addr;
struct sk_buff *skb;
bool reuse = false;
int rc = -EINVAL;
u8 *new_data;
- opaque_data_0 = le32_to_cpu(p_cqe->opaque_data.data[0]);
- opaque_data_1 = le32_to_cpu(p_cqe->opaque_data.data[1]);
-
DP_VERBOSE(p_hwfn,
(NETIF_MSG_RX_STATUS | QED_MSG_STORAGE | NETIF_MSG_PKTDATA),
"Got an LL2 Rx completion: [Buffer at phys 0x%llx, offset 0x%02x] Length 0x%04x Parse_flags 0x%04x vlan 0x%04x Opaque data [0x%08x:0x%08x]\n",
- (u64)p_pkt->rx_buf_addr, pad, packet_length,
- le16_to_cpu(p_cqe->parse_flags.flags), vlan,
- opaque_data_0, opaque_data_1);
+ (u64)data->rx_buf_addr,
+ data->u.placement_offset,
+ data->length.packet_length,
+ data->parse_flags,
+ data->vlan, data->opaque_data_0, data->opaque_data_1);
if ((cdev->dp_module & NETIF_MSG_PKTDATA) && buffer->data) {
print_hex_dump(KERN_INFO, "",
DUMP_PREFIX_OFFSET, 16, 1,
- buffer->data, packet_length, false);
+ buffer->data, data->length.packet_length, false);
}
/* Determine if data is valid */
- if (packet_length < ETH_HLEN)
+ if (data->length.packet_length < ETH_HLEN)
reuse = true;
/* Allocate a replacement for buffer; Reuse upon failure */
@@ -219,9 +211,9 @@ static void qed_ll2b_complete_rx_packet(struct qed_hwfn *p_hwfn,
goto out_post;
}
- pad += NET_SKB_PAD;
- skb_reserve(skb, pad);
- skb_put(skb, packet_length);
+ data->u.placement_offset += NET_SKB_PAD;
+ skb_reserve(skb, data->u.placement_offset);
+ skb_put(skb, data->length.packet_length);
skb_checksum_none_assert(skb);
/* Get parital ethernet information instead of eth_type_trans(),
@@ -232,10 +224,12 @@ static void qed_ll2b_complete_rx_packet(struct qed_hwfn *p_hwfn,
/* Pass SKB onward */
if (cdev->ll2->cbs && cdev->ll2->cbs->rx_cb) {
- if (vlan)
- __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), vlan);
+ if (data->vlan)
+ __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q),
+ data->vlan);
cdev->ll2->cbs->rx_cb(cdev->ll2->cb_cookie, skb,
- opaque_data_0, opaque_data_1);
+ data->opaque_data_0,
+ data->opaque_data_1);
}
/* Update Buffer information and update FW producer */
@@ -472,33 +466,55 @@ qed_ll2_rxq_completion_gsi(struct qed_hwfn *p_hwfn,
return 0;
}
-static int qed_ll2_rxq_completion_reg(struct qed_hwfn *p_hwfn,
- struct qed_ll2_info *p_ll2_conn,
- union core_rx_cqe_union *p_cqe,
- unsigned long *p_lock_flags,
- bool b_last_cqe)
+static void qed_ll2_rxq_parse_reg(struct qed_hwfn *p_hwfn,
+ union core_rx_cqe_union *p_cqe,
+ struct qed_ll2_comp_rx_data *data)
+{
+ data->parse_flags = le16_to_cpu(p_cqe->rx_cqe_fp.parse_flags.flags);
+ data->length.packet_length =
+ le16_to_cpu(p_cqe->rx_cqe_fp.packet_length);
+ data->vlan = le16_to_cpu(p_cqe->rx_cqe_fp.vlan);
+ data->opaque_data_0 = le32_to_cpu(p_cqe->rx_cqe_fp.opaque_data.data[0]);
+ data->opaque_data_1 = le32_to_cpu(p_cqe->rx_cqe_fp.opaque_data.data[1]);
+ data->u.placement_offset = p_cqe->rx_cqe_fp.placement_offset;
+}
+
+static int
+qed_ll2_rxq_handle_completion(struct qed_hwfn *p_hwfn,
+ struct qed_ll2_info *p_ll2_conn,
+ union core_rx_cqe_union *p_cqe,
+ unsigned long *p_lock_flags, bool b_last_cqe)
{
struct qed_ll2_rx_queue *p_rx = &p_ll2_conn->rx_queue;
struct qed_ll2_rx_packet *p_pkt = NULL;
+ struct qed_ll2_comp_rx_data data;
if (!list_empty(&p_rx->active_descq))
p_pkt = list_first_entry(&p_rx->active_descq,
struct qed_ll2_rx_packet, list_entry);
if (!p_pkt) {
DP_NOTICE(p_hwfn,
- "LL2 Rx completion but active_descq is empty\n");
+ "[%d] LL2 Rx completion but active_descq is empty\n",
+ p_ll2_conn->conn.conn_type);
+
return -EIO;
}
list_del(&p_pkt->list_entry);
+ qed_ll2_rxq_parse_reg(p_hwfn, p_cqe, &data);
if (qed_chain_consume(&p_rx->rxq_chain) != p_pkt->rxq_bd)
DP_NOTICE(p_hwfn,
"Mismatch between active_descq and the LL2 Rx chain\n");
+
list_add_tail(&p_pkt->list_entry, &p_rx->free_descq);
+ data.connection_handle = p_ll2_conn->my_id;
+ data.cookie = p_pkt->cookie;
+ data.rx_buf_addr = p_pkt->rx_buf_addr;
+ data.b_last_packet = b_last_cqe;
+
spin_unlock_irqrestore(&p_rx->lock, *p_lock_flags);
- qed_ll2b_complete_rx_packet(p_hwfn, p_ll2_conn->my_id,
- p_pkt, &p_cqe->rx_cqe_fp, b_last_cqe);
+ qed_ll2b_complete_rx_packet(p_hwfn, &data);
spin_lock_irqsave(&p_rx->lock, *p_lock_flags);
return 0;
@@ -538,9 +554,9 @@ static int qed_ll2_rxq_completion(struct qed_hwfn *p_hwfn, void *cookie)
cqe, flags, b_last_cqe);
break;
case CORE_RX_CQE_TYPE_REGULAR:
- rc = qed_ll2_rxq_completion_reg(p_hwfn, p_ll2_conn,
- cqe, &flags,
- b_last_cqe);
+ rc = qed_ll2_rxq_handle_completion(p_hwfn, p_ll2_conn,
+ cqe, &flags,
+ b_last_cqe);
break;
default:
rc = -EIO;
diff --git a/include/linux/qed/qed_ll2_if.h b/include/linux/qed/qed_ll2_if.h
index 78d9ed6..056ac00 100644
--- a/include/linux/qed/qed_ll2_if.h
+++ b/include/linux/qed/qed_ll2_if.h
@@ -79,6 +79,32 @@ struct qed_ll2_stats {
u64 sent_bcast_pkts;
};
+struct qed_ll2_comp_rx_data {
+ void *cookie;
+ dma_addr_t rx_buf_addr;
+ u16 parse_flags;
+ u16 vlan;
+ bool b_last_packet;
+ u8 connection_handle;
+
+ union {
+ u16 packet_length;
+ u16 data_length;
+ } length;
+
+ u32 opaque_data_0;
+ u32 opaque_data_1;
+
+ /* GSI only */
+ u32 gid_dst[4];
+ u16 qp_id;
+
+ union {
+ u8 placement_offset;
+ u8 data_length_error;
+ } u;
+};
+
struct qed_ll2_tx_pkt_info {
void *cookie;
dma_addr_t first_frag;
--
2.9.4
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH v2 net-next 1/8] qed: LL2 to use packed information for tx
From: Yuval Mintz @ 2017-06-09 14:13 UTC (permalink / raw)
To: netdev-u79uwXL29TY76Z2rM5mHXA, davem-fT/PcQaiUtIeIZ0/mPfg9Q
Cc: linux-rdma-u79uwXL29TY76Z2rM5mHXA,
Michal.Kalderon-YGCgFSpz5w/QT0dZR+AlfA, Yuval Mintz
In-Reply-To: <20170609141325.20547-1-Yuval.Mintz-YGCgFSpz5w/QT0dZR+AlfA@public.gmane.org>
First step in revising the LL2 interface, this declares
qed_ll2_tx_pkt_info as part of the ll2 interface, and uses it for
transmission instead of receiving lots of parameters.
Signed-off-by: Yuval Mintz <Yuval.Mintz-YGCgFSpz5w/QT0dZR+AlfA@public.gmane.org>
---
drivers/net/ethernet/qlogic/qed/qed_ll2.c | 127 +++++++++++++----------------
drivers/net/ethernet/qlogic/qed/qed_ll2.h | 41 ++--------
drivers/net/ethernet/qlogic/qed/qed_roce.c | 18 ++--
include/linux/qed/qed_ll2_if.h | 27 ++++++
4 files changed, 102 insertions(+), 111 deletions(-)
diff --git a/drivers/net/ethernet/qlogic/qed/qed_ll2.c b/drivers/net/ethernet/qlogic/qed/qed_ll2.c
index f67ed6d..0b75f5d 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_ll2.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_ll2.c
@@ -740,12 +740,13 @@ static void
qed_ooo_submit_tx_buffers(struct qed_hwfn *p_hwfn,
struct qed_ll2_info *p_ll2_conn)
{
+ struct qed_ll2_tx_pkt_info tx_pkt;
struct qed_ooo_buffer *p_buffer;
- int rc;
u16 l4_hdr_offset_w;
dma_addr_t first_frag;
u16 parse_flags;
u8 bd_flags;
+ int rc;
/* Submit Tx buffers here */
while ((p_buffer = qed_ooo_get_ready_buffer(p_hwfn,
@@ -760,13 +761,18 @@ qed_ooo_submit_tx_buffers(struct qed_hwfn *p_hwfn,
SET_FIELD(bd_flags, CORE_TX_BD_DATA_FORCE_VLAN_MODE, 1);
SET_FIELD(bd_flags, CORE_TX_BD_DATA_L4_PROTOCOL, 1);
- rc = qed_ll2_prepare_tx_packet(p_hwfn, p_ll2_conn->my_id, 1,
- p_buffer->vlan, bd_flags,
- l4_hdr_offset_w,
- p_ll2_conn->conn.tx_dest, 0,
- first_frag,
- p_buffer->packet_length,
- p_buffer, true);
+ memset(&tx_pkt, 0, sizeof(tx_pkt));
+ tx_pkt.num_of_bds = 1;
+ tx_pkt.vlan = p_buffer->vlan;
+ tx_pkt.bd_flags = bd_flags;
+ tx_pkt.l4_hdr_offset_w = l4_hdr_offset_w;
+ tx_pkt.tx_dest = p_ll2_conn->conn.tx_dest;
+ tx_pkt.first_frag = first_frag;
+ tx_pkt.first_frag_len = p_buffer->packet_length;
+ tx_pkt.cookie = p_buffer;
+
+ rc = qed_ll2_prepare_tx_packet(p_hwfn, p_ll2_conn->my_id,
+ &tx_pkt, true);
if (rc) {
qed_ooo_put_ready_buffer(p_hwfn, p_hwfn->p_ooo_info,
p_buffer, false);
@@ -1593,20 +1599,18 @@ int qed_ll2_post_rx_buffer(struct qed_hwfn *p_hwfn,
static void qed_ll2_prepare_tx_packet_set(struct qed_hwfn *p_hwfn,
struct qed_ll2_tx_queue *p_tx,
struct qed_ll2_tx_packet *p_curp,
- u8 num_of_bds,
- dma_addr_t first_frag,
- u16 first_frag_len, void *p_cookie,
+ struct qed_ll2_tx_pkt_info *pkt,
u8 notify_fw)
{
list_del(&p_curp->list_entry);
- p_curp->cookie = p_cookie;
- p_curp->bd_used = num_of_bds;
+ p_curp->cookie = pkt->cookie;
+ p_curp->bd_used = pkt->num_of_bds;
p_curp->notify_fw = notify_fw;
p_tx->cur_send_packet = p_curp;
p_tx->cur_send_frag_num = 0;
- p_curp->bds_set[p_tx->cur_send_frag_num].tx_frag = first_frag;
- p_curp->bds_set[p_tx->cur_send_frag_num].frag_len = first_frag_len;
+ p_curp->bds_set[p_tx->cur_send_frag_num].tx_frag = pkt->first_frag;
+ p_curp->bds_set[p_tx->cur_send_frag_num].frag_len = pkt->first_frag_len;
p_tx->cur_send_frag_num++;
}
@@ -1614,32 +1618,33 @@ static void
qed_ll2_prepare_tx_packet_set_bd(struct qed_hwfn *p_hwfn,
struct qed_ll2_info *p_ll2,
struct qed_ll2_tx_packet *p_curp,
- u8 num_of_bds,
- enum core_tx_dest tx_dest,
- u16 vlan,
- u8 bd_flags,
- u16 l4_hdr_offset_w,
- enum core_roce_flavor_type roce_flavor,
- dma_addr_t first_frag,
- u16 first_frag_len)
+ struct qed_ll2_tx_pkt_info *pkt)
{
struct qed_chain *p_tx_chain = &p_ll2->tx_queue.txq_chain;
u16 prod_idx = qed_chain_get_prod_idx(p_tx_chain);
struct core_tx_bd *start_bd = NULL;
+ enum core_roce_flavor_type roce_flavor;
+ enum core_tx_dest tx_dest;
u16 bd_data = 0, frag_idx;
+ roce_flavor = (pkt->qed_roce_flavor == QED_LL2_ROCE) ? CORE_ROCE
+ : CORE_RROCE;
+
+ tx_dest = (pkt->tx_dest == QED_LL2_TX_DEST_NW) ? CORE_TX_DEST_NW
+ : CORE_TX_DEST_LB;
+
start_bd = (struct core_tx_bd *)qed_chain_produce(p_tx_chain);
- start_bd->nw_vlan_or_lb_echo = cpu_to_le16(vlan);
+ start_bd->nw_vlan_or_lb_echo = cpu_to_le16(pkt->vlan);
SET_FIELD(start_bd->bitfield1, CORE_TX_BD_L4_HDR_OFFSET_W,
- cpu_to_le16(l4_hdr_offset_w));
+ cpu_to_le16(pkt->l4_hdr_offset_w));
SET_FIELD(start_bd->bitfield1, CORE_TX_BD_TX_DST, tx_dest);
- bd_data |= bd_flags;
+ bd_data |= pkt->bd_flags;
SET_FIELD(bd_data, CORE_TX_BD_DATA_START_BD, 0x1);
- SET_FIELD(bd_data, CORE_TX_BD_DATA_NBDS, num_of_bds);
+ SET_FIELD(bd_data, CORE_TX_BD_DATA_NBDS, pkt->num_of_bds);
SET_FIELD(bd_data, CORE_TX_BD_DATA_ROCE_FLAV, roce_flavor);
start_bd->bd_data.as_bitfield = cpu_to_le16(bd_data);
- DMA_REGPAIR_LE(start_bd->addr, first_frag);
- start_bd->nbytes = cpu_to_le16(first_frag_len);
+ DMA_REGPAIR_LE(start_bd->addr, pkt->first_frag);
+ start_bd->nbytes = cpu_to_le16(pkt->first_frag_len);
DP_VERBOSE(p_hwfn,
(NETIF_MSG_TX_QUEUED | QED_MSG_LL2),
@@ -1648,17 +1653,17 @@ qed_ll2_prepare_tx_packet_set_bd(struct qed_hwfn *p_hwfn,
p_ll2->cid,
p_ll2->conn.conn_type,
prod_idx,
- first_frag_len,
- num_of_bds,
+ pkt->first_frag_len,
+ pkt->num_of_bds,
le32_to_cpu(start_bd->addr.hi),
le32_to_cpu(start_bd->addr.lo));
- if (p_ll2->tx_queue.cur_send_frag_num == num_of_bds)
+ if (p_ll2->tx_queue.cur_send_frag_num == pkt->num_of_bds)
return;
/* Need to provide the packet with additional BDs for frags */
for (frag_idx = p_ll2->tx_queue.cur_send_frag_num;
- frag_idx < num_of_bds; frag_idx++) {
+ frag_idx < pkt->num_of_bds; frag_idx++) {
struct core_tx_bd **p_bd = &p_curp->bds_set[frag_idx].txq_bd;
*p_bd = (struct core_tx_bd *)qed_chain_produce(p_tx_chain);
@@ -1726,21 +1731,13 @@ static void qed_ll2_tx_packet_notify(struct qed_hwfn *p_hwfn,
int qed_ll2_prepare_tx_packet(struct qed_hwfn *p_hwfn,
u8 connection_handle,
- u8 num_of_bds,
- u16 vlan,
- u8 bd_flags,
- u16 l4_hdr_offset_w,
- enum qed_ll2_tx_dest e_tx_dest,
- enum qed_ll2_roce_flavor_type qed_roce_flavor,
- dma_addr_t first_frag,
- u16 first_frag_len, void *cookie, u8 notify_fw)
+ struct qed_ll2_tx_pkt_info *pkt,
+ bool notify_fw)
{
struct qed_ll2_tx_packet *p_curp = NULL;
struct qed_ll2_info *p_ll2_conn = NULL;
- enum core_roce_flavor_type roce_flavor;
struct qed_ll2_tx_queue *p_tx;
struct qed_chain *p_tx_chain;
- enum core_tx_dest tx_dest;
unsigned long flags;
int rc = 0;
@@ -1750,7 +1747,7 @@ int qed_ll2_prepare_tx_packet(struct qed_hwfn *p_hwfn,
p_tx = &p_ll2_conn->tx_queue;
p_tx_chain = &p_tx->txq_chain;
- if (num_of_bds > CORE_LL2_TX_MAX_BDS_PER_PACKET)
+ if (pkt->num_of_bds > CORE_LL2_TX_MAX_BDS_PER_PACKET)
return -EIO;
spin_lock_irqsave(&p_tx->lock, flags);
@@ -1763,7 +1760,7 @@ int qed_ll2_prepare_tx_packet(struct qed_hwfn *p_hwfn,
if (!list_empty(&p_tx->free_descq))
p_curp = list_first_entry(&p_tx->free_descq,
struct qed_ll2_tx_packet, list_entry);
- if (p_curp && qed_chain_get_elem_left(p_tx_chain) < num_of_bds)
+ if (p_curp && qed_chain_get_elem_left(p_tx_chain) < pkt->num_of_bds)
p_curp = NULL;
if (!p_curp) {
@@ -1771,26 +1768,10 @@ int qed_ll2_prepare_tx_packet(struct qed_hwfn *p_hwfn,
goto out;
}
- tx_dest = e_tx_dest == QED_LL2_TX_DEST_NW ? CORE_TX_DEST_NW :
- CORE_TX_DEST_LB;
- if (qed_roce_flavor == QED_LL2_ROCE) {
- roce_flavor = CORE_ROCE;
- } else if (qed_roce_flavor == QED_LL2_RROCE) {
- roce_flavor = CORE_RROCE;
- } else {
- rc = -EINVAL;
- goto out;
- }
-
/* Prepare packet and BD, and perhaps send a doorbell to FW */
- qed_ll2_prepare_tx_packet_set(p_hwfn, p_tx, p_curp,
- num_of_bds, first_frag,
- first_frag_len, cookie, notify_fw);
- qed_ll2_prepare_tx_packet_set_bd(p_hwfn, p_ll2_conn, p_curp,
- num_of_bds, tx_dest,
- vlan, bd_flags, l4_hdr_offset_w,
- roce_flavor,
- first_frag, first_frag_len);
+ qed_ll2_prepare_tx_packet_set(p_hwfn, p_tx, p_curp, pkt, notify_fw);
+
+ qed_ll2_prepare_tx_packet_set_bd(p_hwfn, p_ll2_conn, p_curp, pkt);
qed_ll2_tx_packet_notify(p_hwfn, p_ll2_conn);
@@ -2245,6 +2226,7 @@ static int qed_ll2_stop(struct qed_dev *cdev)
static int qed_ll2_start_xmit(struct qed_dev *cdev, struct sk_buff *skb)
{
+ struct qed_ll2_tx_pkt_info pkt;
const skb_frag_t *frag;
int rc = -EINVAL, i;
dma_addr_t mapping;
@@ -2279,12 +2261,17 @@ static int qed_ll2_start_xmit(struct qed_dev *cdev, struct sk_buff *skb)
flags |= BIT(CORE_TX_BD_DATA_VLAN_INSERTION_SHIFT);
}
- rc = qed_ll2_prepare_tx_packet(QED_LEADING_HWFN(cdev),
- cdev->ll2->handle,
- 1 + skb_shinfo(skb)->nr_frags,
- vlan, flags, 0, QED_LL2_TX_DEST_NW,
- 0 /* RoCE FLAVOR */,
- mapping, skb->len, skb, 1);
+ memset(&pkt, 0, sizeof(pkt));
+ pkt.num_of_bds = 1 + skb_shinfo(skb)->nr_frags;
+ pkt.vlan = vlan;
+ pkt.bd_flags = flags;
+ pkt.tx_dest = QED_LL2_TX_DEST_NW;
+ pkt.first_frag = mapping;
+ pkt.first_frag_len = skb->len;
+ pkt.cookie = skb;
+
+ rc = qed_ll2_prepare_tx_packet(&cdev->hwfns[0], cdev->ll2->handle,
+ &pkt, 1);
if (rc)
goto err;
diff --git a/drivers/net/ethernet/qlogic/qed/qed_ll2.h b/drivers/net/ethernet/qlogic/qed/qed_ll2.h
index 2c07d0e..96af50b 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_ll2.h
+++ b/drivers/net/ethernet/qlogic/qed/qed_ll2.h
@@ -47,12 +47,6 @@
#define QED_MAX_NUM_OF_LL2_CONNECTIONS (4)
-enum qed_ll2_roce_flavor_type {
- QED_LL2_ROCE,
- QED_LL2_RROCE,
- MAX_QED_LL2_ROCE_FLAVOR_TYPE
-};
-
enum qed_ll2_conn_type {
QED_LL2_TYPE_FCOE,
QED_LL2_TYPE_ISCSI,
@@ -64,12 +58,6 @@ enum qed_ll2_conn_type {
MAX_QED_LL2_RX_CONN_TYPE
};
-enum qed_ll2_tx_dest {
- QED_LL2_TX_DEST_NW, /* Light L2 TX Destination to the Network */
- QED_LL2_TX_DEST_LB, /* Light L2 TX Destination to the Loopback */
- QED_LL2_TX_DEST_MAX
-};
-
struct qed_ll2_rx_packet {
struct list_head list_entry;
struct core_rx_bd_with_buff_len *rxq_bd;
@@ -216,35 +204,16 @@ int qed_ll2_post_rx_buffer(struct qed_hwfn *p_hwfn,
* to prepare Tx packet submission to FW.
*
* @param p_hwfn
- * @param connection_handle LL2 connection's handle obtained from
- * qed_ll2_require_connection
- * @param num_of_bds a number of requested BD equals a number of
- * fragments in Tx packet
- * @param vlan VLAN to insert to packet (if insertion set)
- * @param bd_flags
- * @param l4_hdr_offset_w L4 Header Offset from start of packet
- * (in words). This is needed if both l4_csum
- * and ipv6_ext are set
- * @param e_tx_dest indicates if the packet is to be transmitted via
- * loopback or to the network
- * @param first_frag
- * @param first_frag_len
- * @param cookie
- *
- * @param notify_fw
+ * @param connection_handle
+ * @param pkt - info regarding the tx packet
+ * @param notify_fw - issue doorbell to fw for this packet
*
* @return 0 on success, failure otherwise
*/
int qed_ll2_prepare_tx_packet(struct qed_hwfn *p_hwfn,
u8 connection_handle,
- u8 num_of_bds,
- u16 vlan,
- u8 bd_flags,
- u16 l4_hdr_offset_w,
- enum qed_ll2_tx_dest e_tx_dest,
- enum qed_ll2_roce_flavor_type qed_roce_flavor,
- dma_addr_t first_frag,
- u16 first_frag_len, void *cookie, u8 notify_fw);
+ struct qed_ll2_tx_pkt_info *pkt,
+ bool notify_fw);
/**
* @brief qed_ll2_release_connection - releases resources
diff --git a/drivers/net/ethernet/qlogic/qed/qed_roce.c b/drivers/net/ethernet/qlogic/qed/qed_roce.c
index b9434b7..afc63c0 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_roce.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_roce.c
@@ -2937,6 +2937,7 @@ static int qed_roce_ll2_tx(struct qed_dev *cdev,
struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev);
struct qed_roce_ll2_info *roce_ll2 = hwfn->ll2;
enum qed_ll2_roce_flavor_type qed_roce_flavor;
+ struct qed_ll2_tx_pkt_info ll2_pkt;
u8 flags = 0;
int rc;
int i;
@@ -2955,11 +2956,18 @@ static int qed_roce_ll2_tx(struct qed_dev *cdev,
flags |= BIT(CORE_TX_BD_DATA_IP_CSUM_SHIFT);
/* Tx header */
- rc = qed_ll2_prepare_tx_packet(QED_LEADING_HWFN(cdev), roce_ll2->handle,
- 1 + pkt->n_seg, 0, flags, 0,
- QED_LL2_TX_DEST_NW,
- qed_roce_flavor, pkt->header.baddr,
- pkt->header.len, pkt, 1);
+ memset(&ll2_pkt, 0, sizeof(ll2_pkt));
+ ll2_pkt.num_of_bds = 1 + pkt->n_seg;
+ ll2_pkt.bd_flags = flags;
+ ll2_pkt.tx_dest = QED_LL2_TX_DEST_NW;
+ ll2_pkt.qed_roce_flavor = qed_roce_flavor;
+ ll2_pkt.first_frag = pkt->header.baddr;
+ ll2_pkt.first_frag_len = pkt->header.len;
+ ll2_pkt.cookie = pkt;
+
+ rc = qed_ll2_prepare_tx_packet(QED_LEADING_HWFN(cdev),
+ roce_ll2->handle,
+ &ll2_pkt, 1);
if (rc) {
DP_ERR(cdev, "roce ll2 tx: header failed (rc=%d)\n", rc);
return QED_ROCE_TX_HEAD_FAILURE;
diff --git a/include/linux/qed/qed_ll2_if.h b/include/linux/qed/qed_ll2_if.h
index 4fb4666..78d9ed6 100644
--- a/include/linux/qed/qed_ll2_if.h
+++ b/include/linux/qed/qed_ll2_if.h
@@ -43,6 +43,18 @@
#include <linux/slab.h>
#include <linux/qed/qed_if.h>
+enum qed_ll2_roce_flavor_type {
+ QED_LL2_ROCE,
+ QED_LL2_RROCE,
+ MAX_QED_LL2_ROCE_FLAVOR_TYPE
+};
+
+enum qed_ll2_tx_dest {
+ QED_LL2_TX_DEST_NW, /* Light L2 TX Destination to the Network */
+ QED_LL2_TX_DEST_LB, /* Light L2 TX Destination to the Loopback */
+ QED_LL2_TX_DEST_MAX
+};
+
struct qed_ll2_stats {
u64 gsi_invalid_hdr;
u64 gsi_invalid_pkt_length;
@@ -67,6 +79,21 @@ struct qed_ll2_stats {
u64 sent_bcast_pkts;
};
+struct qed_ll2_tx_pkt_info {
+ void *cookie;
+ dma_addr_t first_frag;
+ enum qed_ll2_tx_dest tx_dest;
+ enum qed_ll2_roce_flavor_type qed_roce_flavor;
+ u16 vlan;
+ u16 l4_hdr_offset_w; /* from start of packet */
+ u16 first_frag_len;
+ u8 num_of_bds;
+ u8 bd_flags;
+ bool enable_ip_cksum;
+ bool enable_l4_cksum;
+ bool calc_ip_len;
+};
+
#define QED_LL2_UNUSED_HANDLE (0xff)
struct qed_ll2_cb_ops {
--
2.9.4
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH v2 net-next 0/8] qed*: Light L2 updates
From: Yuval Mintz @ 2017-06-09 14:13 UTC (permalink / raw)
To: netdev-u79uwXL29TY76Z2rM5mHXA, davem-fT/PcQaiUtIeIZ0/mPfg9Q
Cc: linux-rdma-u79uwXL29TY76Z2rM5mHXA,
Michal.Kalderon-YGCgFSpz5w/QT0dZR+AlfA, Yuval Mintz
This series does a major overhaul of the LL2 logic in qed.
The single biggest change done here is in #5 where we're changing
the API qed provides for LL2 [both internally in case of storage and
externally in case of RoCE] to become callback-based to allow cleaner
scalability in preperation to the future iWARP submission which would
aadd additional flavors of LL2. It's also the only patch in series
to modify !qed logic [qedr].
Patches prior to that mostly deal with refactoring LL2 code,
encapsulating varaious parameters into structure and re-ordering
of LL2 code. The latter patches add some small missing bits of LL2
ffunctionality.
Dave,
Please consider applying this series to `net-next'.
Thanks,
Yuval
Changes from previous versions
------------------------------
- V2 - Change layout of strucutres introduced in #1, #2
to mend gaps due to alignment.
Michal Kalderon (1):
qed*: LL2 callback operations
Yuval Mintz (7):
qed: LL2 to use packed information for tx
qed: Revise ll2 Rx completion
qed: Cleaner seperation of LL2 inputs
qed: LL2 code relocations
qed: No need for LL2 frags indication
qed: Call rx_release_cb() when flushing LL2
qed: collect GSI port statistics
drivers/infiniband/hw/qedr/main.c | 6 +-
drivers/infiniband/hw/qedr/qedr.h | 2 +
drivers/infiniband/hw/qedr/qedr_cm.c | 238 ++++++--
drivers/net/ethernet/qlogic/qed/qed.h | 1 -
drivers/net/ethernet/qlogic/qed/qed_ll2.c | 882 +++++++++++++++--------------
drivers/net/ethernet/qlogic/qed/qed_ll2.h | 113 +---
drivers/net/ethernet/qlogic/qed/qed_roce.c | 295 +---------
drivers/net/ethernet/qlogic/qed/qed_roce.h | 43 --
include/linux/qed/qed_ll2_if.h | 128 +++++
include/linux/qed/qed_roce_if.h | 80 +--
10 files changed, 844 insertions(+), 944 deletions(-)
--
2.9.4
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [PATCH] Fix some mroute forwarding issues in vrf's
From: Donald Sharp @ 2017-06-09 14:10 UTC (permalink / raw)
To: netdev, dsahern, Thomas.Winter, nikolay, yotamg, idosch, roopa
This patch fixes two issues:
1) When forwarding on *,G mroutes that are in a vrf, the
kernel was dropping information about the actual incoming
interface when calling ip_mr_forward from ip_mr_input.
This caused ip_mr_forward to send the multicast packet
back out the incoming interface. Fix this by
modifying ip_mr_forward to be handed the correctly
resolved dev.
2) When a unresolved cache entry is created we store
the incoming skb on the unresolved cache entry and
upon mroute resolution from the user space daemon,
we attempt to forward the packet. Again we were
not resolving to the correct incoming device for
a vrf scenario, before calling ip_mr_forward.
Fix this by resolving to the correct interface
and calling ip_mr_forward with the result.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
---
net/ipv4/ipmr.c | 27 ++++++++++++++++++---------
1 file changed, 18 insertions(+), 9 deletions(-)
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c
index 551de4d..559009e 100644
--- a/net/ipv4/ipmr.c
+++ b/net/ipv4/ipmr.c
@@ -101,8 +101,8 @@ static struct mr_table *ipmr_new_table(struct net *net, u32 id);
static void ipmr_free_table(struct mr_table *mrt);
static void ip_mr_forward(struct net *net, struct mr_table *mrt,
- struct sk_buff *skb, struct mfc_cache *cache,
- int local);
+ struct net_device *dev, struct sk_buff *skb,
+ struct mfc_cache *cache, int local);
static int ipmr_cache_report(struct mr_table *mrt,
struct sk_buff *pkt, vifi_t vifi, int assert);
static int __ipmr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb,
@@ -988,7 +988,16 @@ static void ipmr_cache_resolve(struct net *net, struct mr_table *mrt,
rtnl_unicast(skb, net, NETLINK_CB(skb).portid);
} else {
- ip_mr_forward(net, mrt, skb, c, 0);
+ struct net_device *dev = skb->dev;
+
+ if (netif_is_l3_master(dev)) {
+ dev = __dev_get_by_index(net, IPCB(skb)->iif);
+ if (!dev) {
+ kfree_skb(skb);
+ continue;
+ }
+ }
+ ip_mr_forward(net, mrt, dev, skb, c, 0);
}
}
}
@@ -1828,10 +1837,10 @@ static int ipmr_find_vif(struct mr_table *mrt, struct net_device *dev)
/* "local" means that we should preserve one skb (for local delivery) */
static void ip_mr_forward(struct net *net, struct mr_table *mrt,
- struct sk_buff *skb, struct mfc_cache *cache,
- int local)
+ struct net_device *dev, struct sk_buff *skb,
+ struct mfc_cache *cache, int local)
{
- int true_vifi = ipmr_find_vif(mrt, skb->dev);
+ int true_vifi = ipmr_find_vif(mrt, dev);
int psend = -1;
int vif, ct;
@@ -1853,11 +1862,11 @@ static void ip_mr_forward(struct net *net, struct mr_table *mrt,
}
/* Wrong interface: drop packet and (maybe) send PIM assert. */
- if (mrt->vif_table[vif].dev != skb->dev) {
+ if (mrt->vif_table[vif].dev != dev) {
struct net_device *mdev;
mdev = l3mdev_master_dev_rcu(mrt->vif_table[vif].dev);
- if (mdev == skb->dev)
+ if (mdev == dev)
goto forward;
if (rt_is_output_route(skb_rtable(skb))) {
@@ -2064,7 +2073,7 @@ int ip_mr_input(struct sk_buff *skb)
}
read_lock(&mrt_lock);
- ip_mr_forward(net, mrt, skb, cache, local);
+ ip_mr_forward(net, mrt, dev, skb, cache, local);
read_unlock(&mrt_lock);
if (local)
--
2.9.4
^ permalink raw reply related
* Re: [PATCH] af_unix: Add sockaddr length checks before accessing sa_family in bind and connect handlers
From: David Miller @ 2017-06-09 14:09 UTC (permalink / raw)
To: mjurczyk
Cc: xiyou.wangcong, hannes, viro, keescook, mszeredi, iboukris,
avagin, netdev, linux-kernel
In-Reply-To: <CAPr8fOTtiUwBiVP2_740WZmmbbN=6oYJoyBCK31qOFbq5UCtSw@mail.gmail.com>
From: Mateusz Jurczyk <mjurczyk@google.com>
Date: Fri, 9 Jun 2017 13:15:40 +0200
> On Thu, Jun 8, 2017 at 10:04 PM, David Miller <davem@davemloft.net> wrote:
>> From: Mateusz Jurczyk <mjurczyk@google.com>
>> Date: Thu, 8 Jun 2017 11:13:36 +0200
>>
>>> Verify that the caller-provided sockaddr structure is large enough to
>>> contain the sa_family field, before accessing it in bind() and connect()
>>> handlers of the AF_UNIX socket. Since neither syscall enforces a minimum
>>> size of the corresponding memory region, very short sockaddrs (zero or
>>> one byte long) result in operating on uninitialized memory while
>>> referencing .sa_family.
>>>
>>> Signed-off-by: Mateusz Jurczyk <mjurczyk@google.com>
>>
>> The sockaddr comes from a structure on the caller's kernel stack, even
>> if the user gives a smaller length, it is legal to access that memory.
>
> It is legal to access it, but since it's uninitialized kernel stack
> memory, the results of comparisons against AF_UNIX or AF_UNSPEC are
> indeterminate. In practice a user-mode program could likely use timing
> measurement to infer the evaluation of these comparisons, and hence
> determine if a garbage 16-bit variable on the kernel stack is equal to
> 0x0000 or 0x0001, or a garbage byte is equal to 0x00 (if the first
> byte is provided).
>
> This is of course not very bad. However, my project for finding use of
> uninitialized memory flagged it, and I thought it was worth fixing, at
> least to avoid having this construct detected in the future (e.g. by
> KMSAN).
>
> There are a few more instances of this behavior in other socket types,
> which I was going to report with separate patches. If you decide this
> kind of issues indeed deserves a fix, please let me know if further
> separate patches are the right approach.
Oh that's right, we don't zero initialize the on-stack object before
copying from userspace.
I'm going to apply this patch and please submit further changes fixing
bugs like this one.
Thanks.
^ permalink raw reply
* Re: [PATCH v2 7/8] net: mvmdio: add xmdio support
From: Antoine Tenart @ 2017-06-09 14:09 UTC (permalink / raw)
To: Andrew Lunn
Cc: Antoine Tenart, Florian Fainelli, davem, jason, gregory.clement,
sebastian.hesselbarth, thomas.petazzoni, mw, linux, netdev,
linux-arm-kernel
In-Reply-To: <20170609132624.GC20756@lunn.ch>
[-- Attachment #1: Type: text/plain, Size: 2233 bytes --]
Hi Andrew,
On Fri, Jun 09, 2017 at 03:26:24PM +0200, Andrew Lunn wrote:
> On Fri, Jun 09, 2017 at 10:25:41AM +0200, Antoine Tenart wrote:
> > On Thu, Jun 08, 2017 at 09:42:21AM -0700, Florian Fainelli wrote:
> > >
> > > If I get this right, the xMDIO controller is actually a superset of the
> > > MDIO controller and has an extra MVMDIO_XSMI_ADDR_REG register to
> > > preform C45 accesses?
> >
> > This is also a mistake. It's not a superset as the register offsets are
> > different. So we can't use the same smi operations in both cases. We
> > would need dedicated xmdio smi operations, but I don't think there is a
> > board where a c22 PHY is connected to the xMDIO interface.
>
> Is it described as one device, which can do c22 via one set of
> registers, and c45 by another set of registers?
>
> Or are there two separate devices. In particular, does each device
> have there own MDC and MDIO pins? Do we have an C22 only device/bus,
> and a C45 only device/bus?
The MDIO/xMDIO registers are embedded into the network controller. The
mvmdio driver was created at first to abstract this functionality
outside the network controller driver because it is shared between all
ports and used in different IPs. So it's not really devices per say.
Looking at the datasheet/schematics there are two hardware buses, one
for c22 and one for c45. So we should keep two separate nodes to
describe the two interfaces. From what I read c45 is backward
compatible with c22 so the xSMI interface should be capable to speak to
c22 PHYs as well. And by looking at the datasheet this seems possible,
although it's not completely clear. But anyway this wouldn't impact the
dt bindings.
What I'll propose in v3 is two separate nodes, with their own
compatibles. The driver will have smi ops for the marvell,orion-mdio and
xsmi ops for the marvell,xmdio. I won't implement for now the smi ops
for marvell,xmdio as I can't test them and can't be 100% sure it would
work. (But again this won't impact the dt and can be updated in the
driver later).
Does that sound right?
Thanks!
Antoine
--
Antoine Ténart, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]
^ permalink raw reply
* Re: [PATCH net-next 1/8] qed: LL2 to use packed information for tx
From: David Miller @ 2017-06-09 13:59 UTC (permalink / raw)
To: Yuval.Mintz-YGCgFSpz5w/QT0dZR+AlfA
Cc: netdev-u79uwXL29TY76Z2rM5mHXA, linux-rdma-u79uwXL29TY76Z2rM5mHXA,
Michal.Kalderon-YGCgFSpz5w/QT0dZR+AlfA
In-Reply-To: <BLUPR0701MB200415C3D80FB06774CF2C7B8DCE0-v5ruerSQ/oj1oiTf6dR/AE5OhdzP3rhOnBOFsp37pqbUKgpGm//BTAC/G2K4zDHf@public.gmane.org>
From: "Mintz, Yuval" <Yuval.Mintz-YGCgFSpz5w/QT0dZR+AlfA@public.gmane.org>
Date: Fri, 9 Jun 2017 07:08:54 +0000
> But one thing I thought of asking - do we consider layouts of relatively
> insignificant structures to be some golden coding standard?
It just shows lack of thought when writing things.
I want to see code that shows the author put some care into it
and didn't just slap things together.
Thank you.
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [PATCH net-next 2/2] netns: fix error code when the nsid is already used
From: Nicolas Dichtel @ 2017-06-09 12:41 UTC (permalink / raw)
To: davem; +Cc: netdev, Nicolas Dichtel, Jamal Hadi Salim
In-Reply-To: <1497012117-1344-1-git-send-email-nicolas.dichtel@6wind.com>
When the user tries to assign a specific nsid, idr_alloc() is called with
the range [nsid, nsid+1]. If this nsid is already used, idr_alloc() returns
ENOSPC (No space left on device). In our case, it's better to return
EEXIST to make it clear that the nsid is not available.
CC: Jamal Hadi Salim <jhs@mojatatu.com>
Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
---
net/core/net_namespace.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c
index 1f60c180e2de..2178db8e47cd 100644
--- a/net/core/net_namespace.c
+++ b/net/core/net_namespace.c
@@ -642,6 +642,7 @@ static int rtnl_net_newid(struct sk_buff *skb, struct nlmsghdr *nlh,
rtnl_net_notifyid(net, RTM_NEWNSID, err);
err = 0;
} else if (err == -ENOSPC && nsid >= 0) {
+ err = -EEXIST;
NL_SET_BAD_ATTR(extack, tb[NETNSA_NSID]);
NL_SET_ERR_MSG(extack, "The specified nsid is already used");
}
--
2.8.1
^ permalink raw reply related
* [PATCH net-next 1/2] netns: define extack error msg for nsis cmds
From: Nicolas Dichtel @ 2017-06-09 12:41 UTC (permalink / raw)
To: davem; +Cc: netdev, Nicolas Dichtel, Jamal Hadi Salim
It helps the user to identify errors.
CC: Jamal Hadi Salim <jhs@mojatatu.com>
Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
---
net/core/net_namespace.c | 42 +++++++++++++++++++++++++++++++++---------
1 file changed, 33 insertions(+), 9 deletions(-)
diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c
index 26bbfababff2..1f60c180e2de 100644
--- a/net/core/net_namespace.c
+++ b/net/core/net_namespace.c
@@ -596,6 +596,7 @@ static int rtnl_net_newid(struct sk_buff *skb, struct nlmsghdr *nlh,
{
struct net *net = sock_net(skb->sk);
struct nlattr *tb[NETNSA_MAX + 1];
+ struct nlattr *nla;
struct net *peer;
int nsid, err;
@@ -603,23 +604,35 @@ static int rtnl_net_newid(struct sk_buff *skb, struct nlmsghdr *nlh,
rtnl_net_policy, extack);
if (err < 0)
return err;
- if (!tb[NETNSA_NSID])
+ if (!tb[NETNSA_NSID]) {
+ NL_SET_ERR_MSG(extack, "nsid is missing");
return -EINVAL;
+ }
nsid = nla_get_s32(tb[NETNSA_NSID]);
- if (tb[NETNSA_PID])
+ if (tb[NETNSA_PID]) {
peer = get_net_ns_by_pid(nla_get_u32(tb[NETNSA_PID]));
- else if (tb[NETNSA_FD])
+ nla = tb[NETNSA_PID];
+ } else if (tb[NETNSA_FD]) {
peer = get_net_ns_by_fd(nla_get_u32(tb[NETNSA_FD]));
- else
+ nla = tb[NETNSA_FD];
+ } else {
+ NL_SET_ERR_MSG(extack, "Peer netns reference is missing");
return -EINVAL;
- if (IS_ERR(peer))
+ }
+ if (IS_ERR(peer)) {
+ NL_SET_BAD_ATTR(extack, nla);
+ NL_SET_ERR_MSG(extack, "Peer netns reference is invalid");
return PTR_ERR(peer);
+ }
spin_lock_bh(&net->nsid_lock);
if (__peernet2id(net, peer) >= 0) {
spin_unlock_bh(&net->nsid_lock);
err = -EEXIST;
+ NL_SET_BAD_ATTR(extack, nla);
+ NL_SET_ERR_MSG(extack,
+ "Peer netns already has a nsid assigned");
goto out;
}
@@ -628,6 +641,9 @@ static int rtnl_net_newid(struct sk_buff *skb, struct nlmsghdr *nlh,
if (err >= 0) {
rtnl_net_notifyid(net, RTM_NEWNSID, err);
err = 0;
+ } else if (err == -ENOSPC && nsid >= 0) {
+ NL_SET_BAD_ATTR(extack, tb[NETNSA_NSID]);
+ NL_SET_ERR_MSG(extack, "The specified nsid is already used");
}
out:
put_net(peer);
@@ -670,6 +686,7 @@ static int rtnl_net_getid(struct sk_buff *skb, struct nlmsghdr *nlh,
{
struct net *net = sock_net(skb->sk);
struct nlattr *tb[NETNSA_MAX + 1];
+ struct nlattr *nla;
struct sk_buff *msg;
struct net *peer;
int err, id;
@@ -678,15 +695,22 @@ static int rtnl_net_getid(struct sk_buff *skb, struct nlmsghdr *nlh,
rtnl_net_policy, extack);
if (err < 0)
return err;
- if (tb[NETNSA_PID])
+ if (tb[NETNSA_PID]) {
peer = get_net_ns_by_pid(nla_get_u32(tb[NETNSA_PID]));
- else if (tb[NETNSA_FD])
+ nla = tb[NETNSA_PID];
+ } else if (tb[NETNSA_FD]) {
peer = get_net_ns_by_fd(nla_get_u32(tb[NETNSA_FD]));
- else
+ nla = tb[NETNSA_FD];
+ } else {
+ NL_SET_ERR_MSG(extack, "Peer netns reference is missing");
return -EINVAL;
+ }
- if (IS_ERR(peer))
+ if (IS_ERR(peer)) {
+ NL_SET_BAD_ATTR(extack, nla);
+ NL_SET_ERR_MSG(extack, "Peer netns reference is invalid");
return PTR_ERR(peer);
+ }
msg = nlmsg_new(rtnl_net_get_size(), GFP_KERNEL);
if (!msg) {
--
2.8.1
^ permalink raw reply related
* [PATCH net-next] cxgb4: fix memory leak in init_one()
From: Ganesh Goudar @ 2017-06-09 13:56 UTC (permalink / raw)
To: netdev, davem; +Cc: nirranjan, indranil, venkatesh, Ganesh Goudar
Free up mbox_log allocated for PF0 to PF3.
Fixes: 7829451c695e ("cxgb4: Add control net_device for configuring PCIe VF")
Signed-off-by: Ganesh Goudar <ganeshgr@chelsio.com>
---
drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
index ff8bcf5..01c9710 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
@@ -5169,13 +5169,15 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
&v, &port_vec);
if (err < 0) {
dev_err(adapter->pdev_dev, "Could not fetch port params\n");
- goto free_adapter;
+ goto free_mbox_log;
}
adapter->params.nports = hweight32(port_vec);
pci_set_drvdata(pdev, adapter);
return 0;
+free_mbox_log:
+ kfree(adapter->mbox_log);
free_adapter:
kfree(adapter);
free_pci_region:
@@ -5275,6 +5277,7 @@ static void remove_one(struct pci_dev *pdev)
unregister_netdev(adapter->port[0]);
iounmap(adapter->regs);
kfree(adapter->vfinfo);
+ kfree(adapter->mbox_log);
kfree(adapter);
pci_disable_sriov(pdev);
pci_release_regions(pdev);
@@ -5321,6 +5324,7 @@ static void shutdown_one(struct pci_dev *pdev)
unregister_netdev(adapter->port[0]);
iounmap(adapter->regs);
kfree(adapter->vfinfo);
+ kfree(adapter->mbox_log);
kfree(adapter);
pci_disable_sriov(pdev);
pci_release_regions(pdev);
--
2.1.0
^ permalink raw reply related
* [PATCH net] net: phy: add missing SPEED_14000
From: Nicolas Dichtel @ 2017-06-09 13:45 UTC (permalink / raw)
To: davem, joe
Cc: netdev, j.vosburgh, vfalico, andy, thibaut.collet, linville,
Nicolas Dichtel
In-Reply-To: <1496966712.1929.25.camel@perches.com>
From: Joe Perches <joe@perches.com>
Fixes: 0d7e2d2166f6 ("IB/ipoib: add get_link_ksettings in ethtool")
Signed-off-by: Joe Perches <joe@perches.com>
Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
---
drivers/net/phy/phy.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index 7524caa0f29d..eebb0e1c70ff 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -54,6 +54,8 @@ static const char *phy_speed_to_str(int speed)
return "5Gbps";
case SPEED_10000:
return "10Gbps";
+ case SPEED_14000:
+ return "14Gbps";
case SPEED_20000:
return "20Gbps";
case SPEED_25000:
--
2.8.1
^ permalink raw reply related
* (unknown),
From: Mrs Alice Walton @ 2017-06-09 12:45 UTC (permalink / raw)
To: Recipients
I have a charity proposal for you
^ permalink raw reply
* RE: [PATCH net-next] qed: add qed_int_sb_init() stub function
From: Mintz, Yuval @ 2017-06-09 13:44 UTC (permalink / raw)
To: Arnd Bergmann
Cc: David S. Miller, Chopra, Manish, netdev@vger.kernel.org,
linux-kernel@vger.kernel.org
In-Reply-To: <20170609103744.3239316-1-arnd@arndb.de>
> When CONFIG_QED_SRIOV is disabled, we get a build error:
>
> drivers/net/ethernet/qlogic/qed/qed_int.c: In function 'qed_int_sb_init':
> drivers/net/ethernet/qlogic/qed/qed_int.c:1499:4: error: implicit declaration
> of function 'qed_vf_set_sb_info'; did you mean 'qed_mcp_get_resc_info'? [-
> Werror=implicit-function-declaration]
>
> All the other declarations have a 'static inline' stub as an alternative here, so
> this adds one more for qed_int_sb_init.
>
> Fixes: 50a207147fce ("qed: Hold a single array for SBs")
> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Missed it. Thanks.
Acked-by: Yuval Mintz <Yuval.Mintz@cavium.com>
^ permalink raw reply
* [PATCH net-next] bonding: warn user when 802.3ad speed is unknown
From: Nicolas Dichtel @ 2017-06-09 13:34 UTC (permalink / raw)
To: davem
Cc: netdev, j.vosburgh, vfalico, andy, thibaut.collet, linville,
Nicolas Dichtel
In-Reply-To: <20170608164811.GB20216@lunn.ch>
Make it explicit in the log.
Suggested-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
---
drivers/net/bonding/bond_3ad.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c
index b44a6aeb346d..b15b177662b0 100644
--- a/drivers/net/bonding/bond_3ad.c
+++ b/drivers/net/bonding/bond_3ad.c
@@ -322,6 +322,9 @@ static u16 __get_link_speed(struct port *port)
default:
/* unknown speed value from ethtool. shouldn't happen */
+ pr_warn("%s: unknown speed (%d) for port %d (set it to 0)\n",
+ slave->bond->dev->name, slave->speed,
+ port->actor_port_number);
speed = 0;
break;
}
--
2.8.1
^ permalink raw reply related
* Re: Repeatable inet6_dump_fib crash in stock 4.12.0-rc4+
From: David Ahern @ 2017-06-09 13:27 UTC (permalink / raw)
To: Cong Wang, Ben Greear; +Cc: Eric Dumazet, netdev
In-Reply-To: <CAM_iQpXM3G=J0tw=n1_mKno=i41Kmoxb00+nDyBWofWskj5P_A@mail.gmail.com>
On 6/8/17 11:55 PM, Cong Wang wrote:
> On Thu, Jun 8, 2017 at 2:27 PM, Ben Greear <greearb@candelatech.com> wrote:
>>
>> As far as I can tell, the patch did not help, or at least we still reproduce
>> the
>> crash easily.
>
> netlink dump is serialized by nlk->cb_mutex so I don't think that
> patch makes any sense w.r.t race condition.
>From what I can see fn_sernum should be accessed under table lock, so
when saving and checking it during a walk make sure it the lock is held.
That has nothing to do with the netlink dump, but the table changing
during a walk.
>> (gdb) l *(fib6_walk_continue+0x76)
>> 0x188c6 is in fib6_walk_continue
>> (/home/greearb/git/linux-2.6/net/ipv6/ip6_fib.c:1593).
>> 1588 if (fn == w->root)
>> 1589 return 0;
>> 1590 pn = fn->parent;
>> 1591 w->node = pn;
>> 1592 #ifdef CONFIG_IPV6_SUBTREES
>> 1593 if (FIB6_SUBTREE(pn) == fn) {
>
> Apparently fn->parent is NULL here for some reason, but
> I don't know if that is expected or not. If a simple NULL check
> is not enough here, we have to trace why it is NULL.
>From my understanding, parent should not be null hence the attempts to
fix access to table nodes under a lock. ie., figuring out why it is null
here.
^ permalink raw reply
* Re: [PATCH v2 7/8] net: mvmdio: add xmdio support
From: Andrew Lunn @ 2017-06-09 13:26 UTC (permalink / raw)
To: Antoine Tenart
Cc: Florian Fainelli, davem, jason, gregory.clement,
sebastian.hesselbarth, thomas.petazzoni, mw, linux, netdev,
linux-arm-kernel
In-Reply-To: <20170609082541.GC31464@kwain>
On Fri, Jun 09, 2017 at 10:25:41AM +0200, Antoine Tenart wrote:
> On Thu, Jun 08, 2017 at 09:42:21AM -0700, Florian Fainelli wrote:
> > On 06/08/2017 02:26 AM, Antoine Tenart wrote:
> > > This patch adds the xMDIO interface support in the mvmdio driver. This
> > > interface is used in Ethernet controllers on Marvell 370, 7k and 8k (as
> > > of now). The xSMI interface supported by this driver complies with the
> > > IEEE 802.3 clause 45 (while the SMI interface complies with the clause
> > > 22). The xSMI interface is used by 10GbE devices.
> >
> > In the previous version you were properly defining a new compatibles
> > strings for xmdio, but now you don't and instead you runtime select the
> > operations based on whether MII_ADDR_C45 is set in the register which is
> > fine from a functional perspective.
> >
> > If I get this right, the xMDIO controller is actually a superset of the
> > MDIO controller and has an extra MVMDIO_XSMI_ADDR_REG register to
> > preform C45 accesses?
>
> This is also a mistake. It's not a superset as the register offsets are
> different. So we can't use the same smi operations in both cases. We
> would need dedicated xmdio smi operations, but I don't think there is a
> board where a c22 PHY is connected to the xMDIO interface.
Hi Antoine
I don't have the datasheet...
Is it described as one device, which can do c22 via one set of
registers, and c45 by another set of registers?
Or are there two separate devices. In particular, does each device
have there own MDC and MDIO pins? Do we have an C22 only device/bus,
and a C45 only device/bus?
Andrew
^ permalink raw reply
* Re: [RFC PATCH net-next 2/5] bpf/verifier: rework value tracking
From: Daniel Borkmann @ 2017-06-09 13:25 UTC (permalink / raw)
To: Alexei Starovoitov, Edward Cree
Cc: davem, Alexei Starovoitov, netdev, iovisor-dev, LKML
In-Reply-To: <20170608164553.y2jvdbmsqqdc7cqt@ast-mbp.dhcp.thefacebook.com>
On 06/08/2017 06:45 PM, Alexei Starovoitov wrote:
[...]
> I think Daniel will be happy to test your next rev of the patches.
> I'll test them as well.
> At least 'insn_processed' from C code in tools/testing/selftests/bpf/
> is a good estimate of how these changes affect pruning.
Without having looked more deeply (yet), I ran couple of tests with
the cilium test suite to track complexity. Overall programs load
with the set applied, worst case increase I've seen for some of the
current progs was by ~80% from ~33k to ~60k insns. Will still go over
the code for an initial review either today or tomorrow.
> btw, I'm working on bpf_call support and also refactoring verifier
> quite a bit, but my stuff is far from ready and I'll wait for
> your rewrite to land first.
> One of the things I'm working on is trying to get rid of state pruning
> heuristics and use register+stack liveness information instead.
> It's all experimental so far.
Thanks,
Daniel
^ permalink raw reply
* Re: [PATCH v4 3/7] dt-bindings: net: Document Intel pch_gbe binding
From: Rob Herring @ 2017-06-09 13:21 UTC (permalink / raw)
To: Paul Burton
Cc: netdev-u79uwXL29TY76Z2rM5mHXA, David S . Miller,
linux-mips-6z/3iImG2C8G8FEW9MqTrA, Eric Dumazet, Jarod Wilson,
Tobias Klauser, Mark Rutland, devicetree-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20170605173136.10795-4-paul.burton-1AXoQHu6uovQT0dZR+AlfA@public.gmane.org>
On Mon, Jun 05, 2017 at 10:31:32AM -0700, Paul Burton wrote:
> Introduce documentation for a device tree binding for the Intel Platform
> Controller Hub (PCH) GigaBit Ethernet (GBE) device. Although this is a
> PCIe device & thus largely auto-detectable, this binding will be used to
> provide the driver with the PHY reset GPIO.
>
> Signed-off-by: Paul Burton <paul.burton-1AXoQHu6uovQT0dZR+AlfA@public.gmane.org>
> Cc: David S. Miller <davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org>
> Cc: Eric Dumazet <edumazet-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org>
> Cc: Jarod Wilson <jarod-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
> Cc: Mark Rutland <mark.rutland-5wv7dgnIgG8@public.gmane.org>
> Cc: Rob Herring <robh+dt-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
> Cc: Tobias Klauser <tklauser-93Khv+1bN0NyDzI6CaY1VQ@public.gmane.org>
> Cc: devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> Cc: linux-mips-6z/3iImG2C8G8FEW9MqTrA@public.gmane.org
> Cc: netdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
>
> ---
>
> Changes in v4: None
>
> Changes in v3:
> - New patch.
>
> Changes in v2: None
>
> Documentation/devicetree/bindings/net/pch_gbe.txt | 25 +++++++++++++++++++++++
> 1 file changed, 25 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/net/pch_gbe.txt
>
> diff --git a/Documentation/devicetree/bindings/net/pch_gbe.txt b/Documentation/devicetree/bindings/net/pch_gbe.txt
> new file mode 100644
> index 000000000000..5de479c26b04
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/net/pch_gbe.txt
> @@ -0,0 +1,25 @@
> +Intel Platform Controller Hub (PCH) GigaBit Ethernet (GBE)
> +
> +Required properties:
> +- compatible: Should be the PCI vendor & device ID, eg. "pci8086,8802".
> +- reg: Should be a PCI device number as specified by the PCI bus
> + binding to IEEE Std 1275-1994.
> +- phy-reset-gpios: Should be a GPIO list containing a single GPIO that
> + resets the attached PHY when active.
> +
> +Example:
> +
> + eg20t_mac@2,0,1 {
ethernet@...
Your unit address is not valid for PCI[1]. You should not have the bus
number (2) as there should be a bridge node that defines the bus number.
Rob
[1] http://www.o3one.org/hwdocs/openfirmware/pci_supplement_2_1.pdf
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [PATCH 04/13] net: dsa: lan9303: Added adjust_link() method
From: Egil Hjelmeland @ 2017-06-09 13:18 UTC (permalink / raw)
To: corbet, andrew, vivien.didelot, f.fainelli, davem, kernel,
linux-doc, linux-kernel, netdev
Cc: egil.hjelmeland
This makes the driver react to device tree "fixed-link" declaration
on CPU port.
- turn off autonegotiation
- force speed 10 or 100 mb/s
- force duplex mode
Signed-off-by: Egil Hjelmeland <egil.hjelmeland@zenitel.com>
---
drivers/net/dsa/lan9303-core.c | 33 +++++++++++++++++++++++++++++++++
1 file changed, 33 insertions(+)
diff --git a/drivers/net/dsa/lan9303-core.c b/drivers/net/dsa/lan9303-core.c
index 0806a0684d55..be6d78f45a5f 100644
--- a/drivers/net/dsa/lan9303-core.c
+++ b/drivers/net/dsa/lan9303-core.c
@@ -17,6 +17,7 @@
#include <linux/regmap.h>
#include <linux/mutex.h>
#include <linux/mii.h>
+#include <linux/phy.h>
#include "lan9303.h"
@@ -746,6 +747,37 @@ static int lan9303_phy_write(struct dsa_switch *ds, int phy, int regnum,
return chip->ops->phy_write(chip, phy, regnum, val);
}
+static void lan9303_adjust_link(struct dsa_switch *ds, int port,
+ struct phy_device *phydev)
+{
+ struct lan9303 *chip = ds->priv;
+
+ int ctl, res;
+
+ ctl = lan9303_phy_read(ds, port, MII_BMCR);
+
+ if (!phy_is_pseudo_fixed_link(phydev))
+ return;
+
+ ctl &= ~BMCR_ANENABLE;
+ if (phydev->speed == SPEED_100)
+ ctl |= BMCR_SPEED100;
+
+ if (phydev->duplex == DUPLEX_FULL)
+ ctl |= BMCR_FULLDPLX;
+
+ res = lan9303_phy_write(ds, port, MII_BMCR, ctl);
+
+ if (port == chip->phy_addr_sel_strap) {
+ /* Virtual Phy: Remove Turbo 200Mbit mode */
+ lan9303_read(chip->regmap, LAN9303_VIRT_SPECIAL_CTRL, &ctl);
+
+ ctl &= ~(1 << 10); // TURBO BIT
+ res = regmap_write(chip->regmap,
+ LAN9303_VIRT_SPECIAL_CTRL, ctl);
+ }
+}
+
static int lan9303_port_enable(struct dsa_switch *ds, int port,
struct phy_device *phy)
{
@@ -789,6 +821,7 @@ static struct dsa_switch_ops lan9303_switch_ops = {
.get_strings = lan9303_get_strings,
.phy_read = lan9303_phy_read,
.phy_write = lan9303_phy_write,
+ .adjust_link = lan9303_adjust_link,
.get_ethtool_stats = lan9303_get_ethtool_stats,
.get_sset_count = lan9303_get_sset_count,
.port_enable = lan9303_port_enable,
--
2.11.0
DISCLAIMER:
This e-mail may contain confidential and privileged material for the sole use of the intended recipient. Any review, use, distribution or disclosure by others is strictly prohibited. If you are not the intended recipient (or authorized to receive for the recipient), please contact the sender by reply e-mail and delete all copies of this message.
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox