Skip to content

Commit fcb39f6

Browse files
mkalderondavem330
authored andcommitted
qed: Add mpa buffer descriptors for storing and processing mpa fpdus
The mpa buff is a descriptor for iwarp ll2 buffers that contains additional information required for aligining fpdu's. In some cases, an additional packet will arrive which will complete the alignment of a fpdu, but we won't be able to post the fpdu due to insufficient place on the tx ring. In this case we can't loose the data and require storing it for later. Processing is therefore done in two places, during rx completion, where we initialize a mpa buffer descriptor and add it to the pending list, and during tx-completion, since we free up an entry in the tx chain we can process any pending mpa packets. The mpa buff descriptors are pre-allocated since we have to ensure that we won't reach a state where we can't store an incoming unaligned packet. All packets received on the ll2 MUST be processed by the driver at some stage. Since they are preallocated, we hold a free list. Signed-off-by: Michal Kalderon <Michal.Kalderon@cavium.com> Signed-off-by: Ariel Elior <Ariel.Elior@cavium.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent ae3488f commit fcb39f6

File tree

2 files changed

+127
-0
lines changed

2 files changed

+127
-0
lines changed

drivers/net/ethernet/qlogic/qed/qed_iwarp.c

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1415,7 +1415,10 @@ int qed_iwarp_alloc(struct qed_hwfn *p_hwfn)
14151415

14161416
void qed_iwarp_resc_free(struct qed_hwfn *p_hwfn)
14171417
{
1418+
struct qed_iwarp_info *iwarp_info = &p_hwfn->p_rdma_info->iwarp;
1419+
14181420
qed_rdma_bmap_free(p_hwfn, &p_hwfn->p_rdma_info->tcp_cid_map, 1);
1421+
kfree(iwarp_info->mpa_bufs);
14191422
}
14201423

14211424
int qed_iwarp_accept(void *rdma_cxt, struct qed_iwarp_accept_in *iparams)
@@ -1715,13 +1718,104 @@ qed_iwarp_parse_rx_pkt(struct qed_hwfn *p_hwfn,
17151718

17161719
/* fpdu can be fragmented over maximum 3 bds: header, partial mpa, unaligned */
17171720
#define QED_IWARP_MAX_BDS_PER_FPDU 3
1721+
static void
1722+
qed_iwarp_mpa_get_data(struct qed_hwfn *p_hwfn,
1723+
struct unaligned_opaque_data *curr_pkt,
1724+
u32 opaque_data0, u32 opaque_data1)
1725+
{
1726+
u64 opaque_data;
1727+
1728+
opaque_data = HILO_64(opaque_data1, opaque_data0);
1729+
*curr_pkt = *((struct unaligned_opaque_data *)&opaque_data);
1730+
1731+
curr_pkt->first_mpa_offset = curr_pkt->tcp_payload_offset +
1732+
le16_to_cpu(curr_pkt->first_mpa_offset);
1733+
curr_pkt->cid = le32_to_cpu(curr_pkt->cid);
1734+
}
1735+
1736+
/* This function is called when an unaligned or incomplete MPA packet arrives
1737+
* driver needs to align the packet, perhaps using previous data and send
1738+
* it down to FW once it is aligned.
1739+
*/
1740+
static int
1741+
qed_iwarp_process_mpa_pkt(struct qed_hwfn *p_hwfn,
1742+
struct qed_iwarp_ll2_mpa_buf *mpa_buf)
1743+
{
1744+
struct qed_iwarp_ll2_buff *buf = mpa_buf->ll2_buf;
1745+
int rc = -EINVAL;
1746+
1747+
qed_iwarp_ll2_post_rx(p_hwfn,
1748+
buf,
1749+
p_hwfn->p_rdma_info->iwarp.ll2_mpa_handle);
1750+
return rc;
1751+
}
1752+
1753+
static void qed_iwarp_process_pending_pkts(struct qed_hwfn *p_hwfn)
1754+
{
1755+
struct qed_iwarp_info *iwarp_info = &p_hwfn->p_rdma_info->iwarp;
1756+
struct qed_iwarp_ll2_mpa_buf *mpa_buf = NULL;
1757+
int rc;
1758+
1759+
while (!list_empty(&iwarp_info->mpa_buf_pending_list)) {
1760+
mpa_buf = list_first_entry(&iwarp_info->mpa_buf_pending_list,
1761+
struct qed_iwarp_ll2_mpa_buf,
1762+
list_entry);
1763+
1764+
rc = qed_iwarp_process_mpa_pkt(p_hwfn, mpa_buf);
1765+
1766+
/* busy means break and continue processing later, don't
1767+
* remove the buf from the pending list.
1768+
*/
1769+
if (rc == -EBUSY)
1770+
break;
1771+
1772+
list_del(&mpa_buf->list_entry);
1773+
list_add_tail(&mpa_buf->list_entry, &iwarp_info->mpa_buf_list);
1774+
1775+
if (rc) { /* different error, don't continue */
1776+
DP_NOTICE(p_hwfn, "process pkts failed rc=%d\n", rc);
1777+
break;
1778+
}
1779+
}
1780+
}
1781+
17181782
static void
17191783
qed_iwarp_ll2_comp_mpa_pkt(void *cxt, struct qed_ll2_comp_rx_data *data)
17201784
{
1785+
struct qed_iwarp_ll2_mpa_buf *mpa_buf;
17211786
struct qed_iwarp_info *iwarp_info;
17221787
struct qed_hwfn *p_hwfn = cxt;
17231788

17241789
iwarp_info = &p_hwfn->p_rdma_info->iwarp;
1790+
mpa_buf = list_first_entry(&iwarp_info->mpa_buf_list,
1791+
struct qed_iwarp_ll2_mpa_buf, list_entry);
1792+
if (!mpa_buf) {
1793+
DP_ERR(p_hwfn, "No free mpa buf\n");
1794+
goto err;
1795+
}
1796+
1797+
list_del(&mpa_buf->list_entry);
1798+
qed_iwarp_mpa_get_data(p_hwfn, &mpa_buf->data,
1799+
data->opaque_data_0, data->opaque_data_1);
1800+
1801+
DP_VERBOSE(p_hwfn,
1802+
QED_MSG_RDMA,
1803+
"LL2 MPA CompRx payload_len:0x%x\tfirst_mpa_offset:0x%x\ttcp_payload_offset:0x%x\tflags:0x%x\tcid:0x%x\n",
1804+
data->length.packet_length, mpa_buf->data.first_mpa_offset,
1805+
mpa_buf->data.tcp_payload_offset, mpa_buf->data.flags,
1806+
mpa_buf->data.cid);
1807+
1808+
mpa_buf->ll2_buf = data->cookie;
1809+
mpa_buf->tcp_payload_len = data->length.packet_length -
1810+
mpa_buf->data.first_mpa_offset;
1811+
mpa_buf->data.first_mpa_offset += data->u.placement_offset;
1812+
mpa_buf->placement_offset = data->u.placement_offset;
1813+
1814+
list_add_tail(&mpa_buf->list_entry, &iwarp_info->mpa_buf_pending_list);
1815+
1816+
qed_iwarp_process_pending_pkts(p_hwfn);
1817+
return;
1818+
err:
17251819
qed_iwarp_ll2_post_rx(p_hwfn, data->cookie,
17261820
iwarp_info->ll2_mpa_handle);
17271821
}
@@ -1872,6 +1966,11 @@ static void qed_iwarp_ll2_comp_tx_pkt(void *cxt, u8 connection_handle,
18721966

18731967
/* this was originally an rx packet, post it back */
18741968
qed_iwarp_ll2_post_rx(p_hwfn, buffer, connection_handle);
1969+
1970+
if (connection_handle == p_hwfn->p_rdma_info->iwarp.ll2_mpa_handle)
1971+
qed_iwarp_process_pending_pkts(p_hwfn);
1972+
1973+
return;
18751974
}
18761975

18771976
static void qed_iwarp_ll2_rel_tx_pkt(void *cxt, u8 connection_handle,
@@ -1986,6 +2085,7 @@ qed_iwarp_ll2_start(struct qed_hwfn *p_hwfn,
19862085
u32 mpa_buff_size;
19872086
u16 n_ooo_bufs;
19882087
int rc = 0;
2088+
int i;
19892089

19902090
iwarp_info = &p_hwfn->p_rdma_info->iwarp;
19912091
iwarp_info->ll2_syn_handle = QED_IWARP_HANDLE_INVAL;
@@ -2094,6 +2194,22 @@ qed_iwarp_ll2_start(struct qed_hwfn *p_hwfn,
20942194
iwarp_info->ll2_mpa_handle);
20952195
if (rc)
20962196
goto err;
2197+
/* The mpa_bufs array serves for pending RX packets received on the
2198+
* mpa ll2 that don't have place on the tx ring and require later
2199+
* processing. We can't fail on allocation of such a struct therefore
2200+
* we allocate enough to take care of all rx packets
2201+
*/
2202+
iwarp_info->mpa_bufs = kcalloc(data.input.rx_num_desc,
2203+
sizeof(*iwarp_info->mpa_bufs),
2204+
GFP_KERNEL);
2205+
if (!iwarp_info->mpa_bufs)
2206+
goto err;
2207+
2208+
INIT_LIST_HEAD(&iwarp_info->mpa_buf_pending_list);
2209+
INIT_LIST_HEAD(&iwarp_info->mpa_buf_list);
2210+
for (i = 0; i < data.input.rx_num_desc; i++)
2211+
list_add_tail(&iwarp_info->mpa_bufs[i].list_entry,
2212+
&iwarp_info->mpa_buf_list);
20972213
return rc;
20982214
err:
20992215
qed_iwarp_ll2_stop(p_hwfn, p_ptt);

drivers/net/ethernet/qlogic/qed/qed_iwarp.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,10 +60,20 @@ struct qed_iwarp_ll2_buff {
6060
u32 buff_size;
6161
};
6262

63+
struct qed_iwarp_ll2_mpa_buf {
64+
struct list_head list_entry;
65+
struct qed_iwarp_ll2_buff *ll2_buf;
66+
struct unaligned_opaque_data data;
67+
u16 tcp_payload_len;
68+
u8 placement_offset;
69+
};
70+
6371
struct qed_iwarp_info {
6472
struct list_head listen_list; /* qed_iwarp_listener */
6573
struct list_head ep_list; /* qed_iwarp_ep */
6674
struct list_head ep_free_list; /* pre-allocated ep's */
75+
struct list_head mpa_buf_list; /* list of mpa_bufs */
76+
struct list_head mpa_buf_pending_list;
6777
spinlock_t iw_lock; /* for iwarp resources */
6878
spinlock_t qp_lock; /* for teardown races */
6979
u32 rcv_wnd_scale;
@@ -77,6 +87,7 @@ struct qed_iwarp_info {
7787
u8 peer2peer;
7888
enum mpa_negotiation_mode mpa_rev;
7989
enum mpa_rtr_type rtr_type;
90+
struct qed_iwarp_ll2_mpa_buf *mpa_bufs;
8091
};
8192

8293
enum qed_iwarp_ep_state {

0 commit comments

Comments
 (0)