Commit 13c54771 authored by Mintz, Yuval's avatar Mintz, Yuval Committed by David S. Miller

qed: Cleaner seperation of LL2 inputs

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: default avatarYuval Mintz <Yuval.Mintz@cavium.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 68be910c
...@@ -315,7 +315,7 @@ static void qed_ll2_txq_flush(struct qed_hwfn *p_hwfn, u8 connection_handle) ...@@ -315,7 +315,7 @@ static void qed_ll2_txq_flush(struct qed_hwfn *p_hwfn, u8 connection_handle)
list_del(&p_pkt->list_entry); list_del(&p_pkt->list_entry);
b_last_packet = list_empty(&p_tx->active_descq); b_last_packet = list_empty(&p_tx->active_descq);
list_add_tail(&p_pkt->list_entry, &p_tx->free_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; struct qed_ooo_buffer *p_buffer;
p_buffer = (struct qed_ooo_buffer *)p_pkt->cookie; 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) ...@@ -327,7 +327,7 @@ static void qed_ll2_txq_flush(struct qed_hwfn *p_hwfn, u8 connection_handle)
b_last_frag = b_last_frag =
p_tx->cur_completing_bd_idx == p_pkt->bd_used; p_tx->cur_completing_bd_idx == p_pkt->bd_used;
tx_frag = p_pkt->bds_set[0].tx_frag; 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, qed_ll2b_release_tx_gsi_packet(p_hwfn,
p_ll2_conn-> p_ll2_conn->
my_id, my_id,
...@@ -396,7 +396,7 @@ static int qed_ll2_txq_completion(struct qed_hwfn *p_hwfn, void *p_cookie) ...@@ -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); spin_unlock_irqrestore(&p_tx->lock, flags);
tx_frag = p_pkt->bds_set[0].tx_frag; 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, qed_ll2b_complete_tx_gsi_packet(p_hwfn,
p_ll2_conn->my_id, p_ll2_conn->my_id,
p_pkt->cookie, p_pkt->cookie,
...@@ -495,7 +495,7 @@ qed_ll2_rxq_handle_completion(struct qed_hwfn *p_hwfn, ...@@ -495,7 +495,7 @@ qed_ll2_rxq_handle_completion(struct qed_hwfn *p_hwfn,
if (!p_pkt) { if (!p_pkt) {
DP_NOTICE(p_hwfn, DP_NOTICE(p_hwfn,
"[%d] 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); p_ll2_conn->input.conn_type);
return -EIO; return -EIO;
} }
...@@ -522,7 +522,7 @@ qed_ll2_rxq_handle_completion(struct qed_hwfn *p_hwfn, ...@@ -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) 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; struct qed_ll2_rx_queue *p_rx = &p_ll2_conn->rx_queue;
union core_rx_cqe_union *cqe = NULL; union core_rx_cqe_union *cqe = NULL;
u16 cq_new_idx = 0, cq_old_idx = 0; 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) ...@@ -536,7 +536,9 @@ static int qed_ll2_rxq_completion(struct qed_hwfn *p_hwfn, void *cookie)
while (cq_new_idx != cq_old_idx) { while (cq_new_idx != cq_old_idx) {
bool b_last_cqe = (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); cq_old_idx = qed_chain_get_cons_idx(&p_rx->rcq_chain);
DP_VERBOSE(p_hwfn, DP_VERBOSE(p_hwfn,
...@@ -591,7 +593,7 @@ static void qed_ll2_rxq_flush(struct qed_hwfn *p_hwfn, u8 connection_handle) ...@@ -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); 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; struct qed_ooo_buffer *p_buffer;
p_buffer = (struct qed_ooo_buffer *)p_pkt->cookie; 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) ...@@ -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) static u8 qed_ll2_convert_rx_parse_to_tx_flags(u16 parse_flags)
{ {
u8 bd_flags = 0; u8 bd_flags = 0;
...@@ -782,7 +783,7 @@ qed_ooo_submit_tx_buffers(struct qed_hwfn *p_hwfn, ...@@ -782,7 +783,7 @@ qed_ooo_submit_tx_buffers(struct qed_hwfn *p_hwfn,
tx_pkt.vlan = p_buffer->vlan; tx_pkt.vlan = p_buffer->vlan;
tx_pkt.bd_flags = bd_flags; tx_pkt.bd_flags = bd_flags;
tx_pkt.l4_hdr_offset_w = l4_hdr_offset_w; 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 = first_frag;
tx_pkt.first_frag_len = p_buffer->packet_length; tx_pkt.first_frag_len = p_buffer->packet_length;
tx_pkt.cookie = p_buffer; tx_pkt.cookie = p_buffer;
...@@ -895,60 +896,11 @@ static int qed_ll2_lb_txq_completion(struct qed_hwfn *p_hwfn, void *p_cookie) ...@@ -895,60 +896,11 @@ static int qed_ll2_lb_txq_completion(struct qed_hwfn *p_hwfn, void *p_cookie)
return 0; 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 static void
qed_ll2_establish_connection_ooo(struct qed_hwfn *p_hwfn, qed_ll2_establish_connection_ooo(struct qed_hwfn *p_hwfn,
struct qed_ll2_info *p_ll2_conn) 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; return;
qed_ooo_release_all_isles(p_hwfn, p_hwfn->p_ooo_info); 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, ...@@ -960,7 +912,7 @@ static void qed_ll2_release_connection_ooo(struct qed_hwfn *p_hwfn,
{ {
struct qed_ooo_buffer *p_buffer; 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; return;
qed_ooo_release_all_isles(p_hwfn, p_hwfn->p_ooo_info); 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) ...@@ -987,69 +939,11 @@ static void qed_ll2_stop_ooo(struct qed_dev *cdev)
*handle = QED_LL2_UNUSED_HANDLE; *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, static int qed_sp_ll2_rx_queue_start(struct qed_hwfn *p_hwfn,
struct qed_ll2_info *p_ll2_conn, struct qed_ll2_info *p_ll2_conn,
u8 action_on_error) 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 qed_ll2_rx_queue *p_rx = &p_ll2_conn->rx_queue;
struct core_rx_start_ramrod_data *p_ramrod = NULL; struct core_rx_start_ramrod_data *p_ramrod = NULL;
struct qed_spq_entry *p_ent = 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, ...@@ -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->sb_index = p_rx->rx_sb_index;
p_ramrod->complete_event_flg = 1; p_ramrod->complete_event_flg = 1;
p_ramrod->mtu = cpu_to_le16(p_ll2_conn->conn.mtu); p_ramrod->mtu = cpu_to_le16(p_ll2_conn->input.mtu);
DMA_REGPAIR_LE(p_ramrod->bd_base, DMA_REGPAIR_LE(p_ramrod->bd_base, p_rx->rxq_chain.p_phys_addr);
p_rx->rxq_chain.p_phys_addr);
cqe_pbl_size = (u16)qed_chain_get_page_cnt(&p_rx->rcq_chain); 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); p_ramrod->num_of_pbl_pages = cpu_to_le16(cqe_pbl_size);
DMA_REGPAIR_LE(p_ramrod->cqe_pbl_addr, DMA_REGPAIR_LE(p_ramrod->cqe_pbl_addr,
qed_chain_get_pbl_phys(&p_rx->rcq_chain)); qed_chain_get_pbl_phys(&p_rx->rcq_chain));
p_ramrod->drop_ttl0_flg = p_ll2_conn->conn.rx_drop_ttl0_flg; p_ramrod->drop_ttl0_flg = p_ll2_conn->input.rx_drop_ttl0_flg;
p_ramrod->inner_vlan_removal_en = p_ll2_conn->conn.rx_vlan_removal_en; 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->queue_id = p_ll2_conn->queue_id;
p_ramrod->main_func_queue = (conn_type == QED_LL2_TYPE_ISCSI_OOO) ? 0 p_ramrod->main_func_queue = (conn_type == QED_LL2_TYPE_ISCSI_OOO) ? 0
: 1; : 1;
...@@ -1099,14 +992,14 @@ static int qed_sp_ll2_rx_queue_start(struct qed_hwfn *p_hwfn, ...@@ -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->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); return qed_spq_post(p_hwfn, p_ent, NULL);
} }
static int qed_sp_ll2_tx_queue_start(struct qed_hwfn *p_hwfn, static int qed_sp_ll2_tx_queue_start(struct qed_hwfn *p_hwfn,
struct qed_ll2_info *p_ll2_conn) 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 qed_ll2_tx_queue *p_tx = &p_ll2_conn->tx_queue;
struct core_tx_start_ramrod_data *p_ramrod = NULL; struct core_tx_start_ramrod_data *p_ramrod = NULL;
struct qed_spq_entry *p_ent = 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, ...@@ -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)) if (!QED_LL2_TX_REGISTERED(p_ll2_conn))
return 0; 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; p_ll2_conn->tx_stats_en = 0;
else else
p_ll2_conn->tx_stats_en = 1; p_ll2_conn->tx_stats_en = 1;
...@@ -1138,7 +1031,7 @@ static int qed_sp_ll2_tx_queue_start(struct qed_hwfn *p_hwfn, ...@@ -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_id = cpu_to_le16(qed_int_get_sp_sb_id(p_hwfn));
p_ramrod->sb_index = p_tx->tx_sb_index; 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_en = p_ll2_conn->tx_stats_en;
p_ramrod->stats_id = p_ll2_conn->tx_stats_id; 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, ...@@ -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); pbl_size = qed_chain_get_page_cnt(&p_tx->txq_chain);
p_ramrod->pbl_size = cpu_to_le16(pbl_size); 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: case LB_TC:
pq_id = qed_get_cm_pq_idx(p_hwfn, PQ_FLAGS_LB); pq_id = qed_get_cm_pq_idx(p_hwfn, PQ_FLAGS_LB);
break; break;
...@@ -1177,7 +1070,8 @@ static int qed_sp_ll2_tx_queue_start(struct qed_hwfn *p_hwfn, ...@@ -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); 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); 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, ...@@ -1233,20 +1127,20 @@ static int qed_sp_ll2_tx_queue_stop(struct qed_hwfn *p_hwfn,
static int static int
qed_ll2_acquire_connection_rx(struct qed_hwfn *p_hwfn, 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; struct qed_ll2_rx_packet *p_descq;
u32 capacity; u32 capacity;
int rc = 0; int rc = 0;
if (!rx_num_desc) if (!p_ll2_info->input.rx_num_desc)
goto out; goto out;
rc = qed_chain_alloc(p_hwfn->cdev, rc = qed_chain_alloc(p_hwfn->cdev,
QED_CHAIN_USE_TO_CONSUME_PRODUCE, QED_CHAIN_USE_TO_CONSUME_PRODUCE,
QED_CHAIN_MODE_NEXT_PTR, QED_CHAIN_MODE_NEXT_PTR,
QED_CHAIN_CNT_TYPE_U16, QED_CHAIN_CNT_TYPE_U16,
rx_num_desc, p_ll2_info->input.rx_num_desc,
sizeof(struct core_rx_bd), sizeof(struct core_rx_bd),
&p_ll2_info->rx_queue.rxq_chain); &p_ll2_info->rx_queue.rxq_chain);
if (rc) { if (rc) {
...@@ -1268,7 +1162,7 @@ qed_ll2_acquire_connection_rx(struct qed_hwfn *p_hwfn, ...@@ -1268,7 +1162,7 @@ qed_ll2_acquire_connection_rx(struct qed_hwfn *p_hwfn,
QED_CHAIN_USE_TO_CONSUME_PRODUCE, QED_CHAIN_USE_TO_CONSUME_PRODUCE,
QED_CHAIN_MODE_PBL, QED_CHAIN_MODE_PBL,
QED_CHAIN_CNT_TYPE_U16, QED_CHAIN_CNT_TYPE_U16,
rx_num_desc, p_ll2_info->input.rx_num_desc,
sizeof(struct core_rx_fast_path_cqe), sizeof(struct core_rx_fast_path_cqe),
&p_ll2_info->rx_queue.rcq_chain); &p_ll2_info->rx_queue.rcq_chain);
if (rc) { if (rc) {
...@@ -1278,28 +1172,27 @@ qed_ll2_acquire_connection_rx(struct qed_hwfn *p_hwfn, ...@@ -1278,28 +1172,27 @@ qed_ll2_acquire_connection_rx(struct qed_hwfn *p_hwfn,
DP_VERBOSE(p_hwfn, QED_MSG_LL2, DP_VERBOSE(p_hwfn, QED_MSG_LL2,
"Allocated LL2 Rxq [Type %08x] with 0x%08x buffers\n", "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: out:
return rc; return rc;
} }
static int qed_ll2_acquire_connection_tx(struct qed_hwfn *p_hwfn, static int qed_ll2_acquire_connection_tx(struct qed_hwfn *p_hwfn,
struct qed_ll2_info *p_ll2_info, struct qed_ll2_info *p_ll2_info)
u16 tx_num_desc)
{ {
struct qed_ll2_tx_packet *p_descq; struct qed_ll2_tx_packet *p_descq;
u32 capacity; u32 capacity;
int rc = 0; int rc = 0;
if (!tx_num_desc) if (!p_ll2_info->input.tx_num_desc)
goto out; goto out;
rc = qed_chain_alloc(p_hwfn->cdev, rc = qed_chain_alloc(p_hwfn->cdev,
QED_CHAIN_USE_TO_CONSUME_PRODUCE, QED_CHAIN_USE_TO_CONSUME_PRODUCE,
QED_CHAIN_MODE_PBL, QED_CHAIN_MODE_PBL,
QED_CHAIN_CNT_TYPE_U16, QED_CHAIN_CNT_TYPE_U16,
tx_num_desc, p_ll2_info->input.tx_num_desc,
sizeof(struct core_tx_bd), sizeof(struct core_tx_bd),
&p_ll2_info->tx_queue.txq_chain); &p_ll2_info->tx_queue.txq_chain);
if (rc) if (rc)
...@@ -1316,28 +1209,95 @@ static int qed_ll2_acquire_connection_tx(struct qed_hwfn *p_hwfn, ...@@ -1316,28 +1209,95 @@ static int qed_ll2_acquire_connection_tx(struct qed_hwfn *p_hwfn,
DP_VERBOSE(p_hwfn, QED_MSG_LL2, DP_VERBOSE(p_hwfn, QED_MSG_LL2,
"Allocated LL2 Txq [Type %08x] with 0x%08x buffers\n", "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: out:
if (rc) if (rc)
DP_NOTICE(p_hwfn, DP_NOTICE(p_hwfn,
"Can't allocate memory for Tx LL2 with 0x%08x buffers\n", "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; 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, int qed_ll2_acquire_connection(struct qed_hwfn *p_hwfn,
struct qed_ll2_conn *p_params, struct qed_ll2_acquire_data *data)
u16 rx_num_desc,
u16 tx_num_desc,
u8 *p_connection_handle)
{ {
qed_int_comp_cb_t comp_rx_cb, comp_tx_cb; qed_int_comp_cb_t comp_rx_cb, comp_tx_cb;
struct qed_ll2_info *p_ll2_info = NULL; struct qed_ll2_info *p_ll2_info = NULL;
u8 i, *p_tx_max;
int rc; 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; return -EINVAL;
/* Find a free connection to be used */ /* Find a free connection to be used */
...@@ -1356,23 +1316,33 @@ int qed_ll2_acquire_connection(struct qed_hwfn *p_hwfn, ...@@ -1356,23 +1316,33 @@ int qed_ll2_acquire_connection(struct qed_hwfn *p_hwfn,
if (!p_ll2_info) if (!p_ll2_info)
return -EBUSY; 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) if (rc)
goto q_allocate_fail; 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) if (rc)
goto q_allocate_fail; goto q_allocate_fail;
rc = qed_ll2_acquire_connection_ooo(p_hwfn, p_ll2_info, rc = qed_ll2_acquire_connection_ooo(p_hwfn, p_ll2_info,
rx_num_desc * 2, p_params->mtu); data->input.mtu);
if (rc) if (rc)
goto q_allocate_fail; goto q_allocate_fail;
/* Register callbacks for the Rx/Tx queues */ /* 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_rx_cb = qed_ll2_lb_rxq_completion;
comp_tx_cb = qed_ll2_lb_txq_completion; comp_tx_cb = qed_ll2_lb_txq_completion;
} else { } else {
...@@ -1380,7 +1350,7 @@ int qed_ll2_acquire_connection(struct qed_hwfn *p_hwfn, ...@@ -1380,7 +1350,7 @@ int qed_ll2_acquire_connection(struct qed_hwfn *p_hwfn,
comp_tx_cb = qed_ll2_txq_completion; 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, qed_int_register_cb(p_hwfn, comp_rx_cb,
&p_hwfn->p_ll2_info[i], &p_hwfn->p_ll2_info[i],
&p_ll2_info->rx_queue.rx_sb_index, &p_ll2_info->rx_queue.rx_sb_index,
...@@ -1388,7 +1358,7 @@ int qed_ll2_acquire_connection(struct qed_hwfn *p_hwfn, ...@@ -1388,7 +1358,7 @@ int qed_ll2_acquire_connection(struct qed_hwfn *p_hwfn,
p_ll2_info->rx_queue.b_cb_registred = true; 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, qed_int_register_cb(p_hwfn,
comp_tx_cb, comp_tx_cb,
&p_hwfn->p_ll2_info[i], &p_hwfn->p_ll2_info[i],
...@@ -1397,7 +1367,7 @@ int qed_ll2_acquire_connection(struct qed_hwfn *p_hwfn, ...@@ -1397,7 +1367,7 @@ int qed_ll2_acquire_connection(struct qed_hwfn *p_hwfn,
p_ll2_info->tx_queue.b_cb_registred = true; p_ll2_info->tx_queue.b_cb_registred = true;
} }
*p_connection_handle = i; *data->p_connection_handle = i;
return rc; return rc;
q_allocate_fail: q_allocate_fail:
...@@ -1408,18 +1378,21 @@ int qed_ll2_acquire_connection(struct qed_hwfn *p_hwfn, ...@@ -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, static int qed_ll2_establish_connection_rx(struct qed_hwfn *p_hwfn,
struct qed_ll2_info *p_ll2_conn) 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; u8 action_on_error = 0;
if (!QED_LL2_RX_REGISTERED(p_ll2_conn)) if (!QED_LL2_RX_REGISTERED(p_ll2_conn))
return 0; return 0;
DIRECT_REG_WR(p_ll2_conn->rx_queue.set_prod_addr, 0x0); 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, SET_FIELD(action_on_error,
CORE_RX_ACTION_ON_ERROR_PACKET_TOO_BIG, CORE_RX_ACTION_ON_ERROR_PACKET_TOO_BIG, error_mode);
p_ll2_conn->conn.ai_err_packet_too_big); error_input = p_ll2_conn->input.ai_err_no_buf;
SET_FIELD(action_on_error, error_mode = qed_ll2_get_error_choice(error_input);
CORE_RX_ACTION_ON_ERROR_NO_BUFF, p_ll2_conn->conn.ai_err_no_buf); 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); 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) ...@@ -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); 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, qed_llh_add_protocol_filter(p_hwfn, p_ptt,
0x8906, 0, 0x8906, 0,
QED_LLH_FILTER_ETHERTYPE); QED_LLH_FILTER_ETHERTYPE);
...@@ -1667,7 +1640,7 @@ qed_ll2_prepare_tx_packet_set_bd(struct qed_hwfn *p_hwfn, ...@@ -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", "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->queue_id,
p_ll2->cid, p_ll2->cid,
p_ll2->conn.conn_type, p_ll2->input.conn_type,
prod_idx, prod_idx,
pkt->first_frag_len, pkt->first_frag_len,
pkt->num_of_bds, pkt->num_of_bds,
...@@ -1742,7 +1715,8 @@ static void qed_ll2_tx_packet_notify(struct qed_hwfn *p_hwfn, ...@@ -1742,7 +1715,8 @@ static void qed_ll2_tx_packet_notify(struct qed_hwfn *p_hwfn,
(NETIF_MSG_TX_QUEUED | QED_MSG_LL2), (NETIF_MSG_TX_QUEUED | QED_MSG_LL2),
"LL2 [q 0x%02x cid 0x%08x type 0x%08x] Doorbelled [producer 0x%04x]\n", "LL2 [q 0x%02x cid 0x%08x type 0x%08x] Doorbelled [producer 0x%04x]\n",
p_ll2_conn->queue_id, 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, 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) ...@@ -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); 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); 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, qed_llh_remove_protocol_filter(p_hwfn, p_ptt,
0x8906, 0, 0x8906, 0,
QED_LLH_FILTER_ETHERTYPE); QED_LLH_FILTER_ETHERTYPE);
...@@ -2054,11 +2028,68 @@ static void qed_ll2_register_cb_ops(struct qed_dev *cdev, ...@@ -2054,11 +2028,68 @@ static void qed_ll2_register_cb_ops(struct qed_dev *cdev,
cdev->ll2->cb_cookie = cookie; 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) 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; struct qed_ll2_buffer *buffer, *tmp_buffer;
enum qed_ll2_conn_type conn_type; enum qed_ll2_conn_type conn_type;
struct qed_ll2_acquire_data data;
struct qed_ptt *p_ptt; struct qed_ptt *p_ptt;
int rc, i; int rc, i;
u8 gsi_enable = 1; u8 gsi_enable = 1;
...@@ -2106,20 +2137,10 @@ static int qed_ll2_start(struct qed_dev *cdev, struct qed_ll2_params *params) ...@@ -2106,20 +2137,10 @@ static int qed_ll2_start(struct qed_dev *cdev, struct qed_ll2_params *params)
conn_type = QED_LL2_TYPE_TEST; conn_type = QED_LL2_TYPE_TEST;
} }
/* Prepare the temporary ll2 information */ qed_ll2_set_conn_data(cdev, &data, params, conn_type,
memset(&ll2_info, 0, sizeof(ll2_info)); &cdev->ll2->handle, false, gsi_enable);
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;
rc = qed_ll2_acquire_connection(QED_LEADING_HWFN(cdev), &ll2_info, rc = qed_ll2_acquire_connection(QED_LEADING_HWFN(cdev), &data);
QED_LL2_RX_SIZE, QED_LL2_TX_SIZE,
&cdev->ll2->handle);
if (rc) { if (rc) {
DP_INFO(cdev, "Failed to acquire LL2 connection\n"); DP_INFO(cdev, "Failed to acquire LL2 connection\n");
goto fail; goto fail;
......
...@@ -47,17 +47,6 @@ ...@@ -47,17 +47,6 @@
#define QED_MAX_NUM_OF_LL2_CONNECTIONS (4) #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 qed_ll2_rx_packet {
struct list_head list_entry; struct list_head list_entry;
struct core_rx_bd_with_buff_len *rxq_bd; struct core_rx_bd_with_buff_len *rxq_bd;
...@@ -123,27 +112,17 @@ struct qed_ll2_tx_queue { ...@@ -123,27 +112,17 @@ struct qed_ll2_tx_queue {
bool b_completing_packet; 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 { struct qed_ll2_info {
/* Lock protecting the state of LL2 */ /* Lock protecting the state of LL2 */
struct mutex mutex; struct mutex mutex;
struct qed_ll2_conn conn;
struct qed_ll2_acquire_data_inputs input;
u32 cid; u32 cid;
u8 my_id; u8 my_id;
u8 queue_id; u8 queue_id;
u8 tx_stats_id; u8 tx_stats_id;
bool b_active; bool b_active;
enum core_tx_dest tx_dest;
u8 tx_stats_en; u8 tx_stats_en;
struct qed_ll2_rx_queue rx_queue; struct qed_ll2_rx_queue rx_queue;
struct qed_ll2_tx_queue tx_queue; struct qed_ll2_tx_queue tx_queue;
...@@ -154,20 +133,13 @@ struct qed_ll2_info { ...@@ -154,20 +133,13 @@ struct qed_ll2_info {
* starts rx & tx (if relevant) queues pair. Provides * starts rx & tx (if relevant) queues pair. Provides
* connecion handler as output parameter. * 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, int qed_ll2_acquire_connection(struct qed_hwfn *p_hwfn,
struct qed_ll2_conn *p_params, struct qed_ll2_acquire_data *data);
u16 rx_num_desc,
u16 tx_num_desc,
u8 *p_connection_handle);
/** /**
* @brief qed_ll2_establish_connection - start previously * @brief qed_ll2_establish_connection - start previously
......
...@@ -2818,7 +2818,7 @@ static int qed_roce_ll2_start(struct qed_dev *cdev, ...@@ -2818,7 +2818,7 @@ static int qed_roce_ll2_start(struct qed_dev *cdev,
{ {
struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev); struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev);
struct qed_roce_ll2_info *roce_ll2; struct qed_roce_ll2_info *roce_ll2;
struct qed_ll2_conn ll2_params; struct qed_ll2_acquire_data data;
int rc; int rc;
if (!params) { if (!params) {
...@@ -2844,25 +2844,26 @@ static int qed_roce_ll2_start(struct qed_dev *cdev, ...@@ -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"); DP_ERR(cdev, "qed roce ll2 start: failed memory allocation\n");
return -ENOMEM; return -ENOMEM;
} }
roce_ll2->handle = QED_LL2_UNUSED_HANDLE; roce_ll2->handle = QED_LL2_UNUSED_HANDLE;
roce_ll2->cbs = params->cbs; roce_ll2->cbs = params->cbs;
roce_ll2->cb_cookie = params->cb_cookie; roce_ll2->cb_cookie = params->cb_cookie;
mutex_init(&roce_ll2->lock); mutex_init(&roce_ll2->lock);
memset(&ll2_params, 0, sizeof(ll2_params)); memset(&data, 0, sizeof(data));
ll2_params.conn_type = QED_LL2_TYPE_ROCE; data.input.conn_type = QED_LL2_TYPE_ROCE;
ll2_params.mtu = params->mtu; data.input.mtu = params->mtu;
ll2_params.rx_drop_ttl0_flg = true; data.input.rx_num_desc = params->max_rx_buffers;
ll2_params.rx_vlan_removal_en = false; data.input.tx_num_desc = params->max_tx_buffers;
ll2_params.tx_dest = CORE_TX_DEST_NW; data.input.rx_drop_ttl0_flg = true;
ll2_params.ai_err_packet_too_big = LL2_DROP_PACKET; data.input.rx_vlan_removal_en = false;
ll2_params.ai_err_no_buf = LL2_DROP_PACKET; data.input.tx_dest = QED_LL2_TX_DEST_NW;
ll2_params.gsi_enable = true; data.input.ai_err_packet_too_big = LL2_DROP_PACKET;
data.input.ai_err_no_buf = LL2_DROP_PACKET;
rc = qed_ll2_acquire_connection(QED_LEADING_HWFN(cdev), &ll2_params, data.p_connection_handle = &roce_ll2->handle;
params->max_rx_buffers, data.input.gsi_enable = true;
params->max_tx_buffers,
&roce_ll2->handle); rc = qed_ll2_acquire_connection(QED_LEADING_HWFN(cdev), &data);
if (rc) { if (rc) {
DP_ERR(cdev, DP_ERR(cdev,
"qed roce ll2 start: failed to acquire LL2 connection (rc=%d)\n", "qed roce ll2 start: failed to acquire LL2 connection (rc=%d)\n",
......
...@@ -43,6 +43,17 @@ ...@@ -43,6 +43,17 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/qed/qed_if.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 { enum qed_ll2_roce_flavor_type {
QED_LL2_ROCE, QED_LL2_ROCE,
QED_LL2_RROCE, QED_LL2_RROCE,
...@@ -55,6 +66,12 @@ enum qed_ll2_tx_dest { ...@@ -55,6 +66,12 @@ enum qed_ll2_tx_dest {
QED_LL2_TX_DEST_MAX 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 { struct qed_ll2_stats {
u64 gsi_invalid_hdr; u64 gsi_invalid_hdr;
u64 gsi_invalid_pkt_length; u64 gsi_invalid_pkt_length;
...@@ -105,6 +122,28 @@ struct qed_ll2_comp_rx_data { ...@@ -105,6 +122,28 @@ struct qed_ll2_comp_rx_data {
} u; } 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 { struct qed_ll2_tx_pkt_info {
void *cookie; void *cookie;
dma_addr_t first_frag; dma_addr_t first_frag;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment