|
@@ -60,7 +60,7 @@
|
|
|
|
|
|
#define NTB_TRANSPORT_VERSION 1
|
|
|
|
|
|
-static int transport_mtu = 0x401E;
|
|
|
+static unsigned int transport_mtu = 0x401E;
|
|
|
module_param(transport_mtu, uint, 0644);
|
|
|
MODULE_PARM_DESC(transport_mtu, "Maximum size of NTB transport packets");
|
|
|
|
|
@@ -94,6 +94,7 @@ struct ntb_transport_qp {
|
|
|
void *tx_mw_begin;
|
|
|
void *tx_mw_end;
|
|
|
void *tx_offset;
|
|
|
+ unsigned int tx_max_frame;
|
|
|
|
|
|
void (*rx_handler) (struct ntb_transport_qp *qp, void *qp_data,
|
|
|
void *data, int len);
|
|
@@ -105,6 +106,7 @@ struct ntb_transport_qp {
|
|
|
void *rx_buff_begin;
|
|
|
void *rx_buff_end;
|
|
|
void *rx_offset;
|
|
|
+ unsigned int rx_max_frame;
|
|
|
|
|
|
void (*event_handler) (void *data, int status);
|
|
|
struct delayed_work link_work;
|
|
@@ -458,28 +460,29 @@ static void ntb_transport_setup_qp_mw(struct ntb_transport *nt,
|
|
|
unsigned int qp_num)
|
|
|
{
|
|
|
struct ntb_transport_qp *qp = &nt->qps[qp_num];
|
|
|
- unsigned int size, num_qps_mw;
|
|
|
+ unsigned int rx_size, num_qps_mw;
|
|
|
u8 mw_num = QP_TO_MW(qp_num);
|
|
|
+ void *offset;
|
|
|
|
|
|
WARN_ON(nt->mw[mw_num].virt_addr == 0);
|
|
|
|
|
|
- if (nt->max_qps % NTB_NUM_MW && !mw_num)
|
|
|
- num_qps_mw = nt->max_qps / NTB_NUM_MW +
|
|
|
- (nt->max_qps % NTB_NUM_MW - mw_num);
|
|
|
+ if (nt->max_qps % NTB_NUM_MW && mw_num < nt->max_qps % NTB_NUM_MW)
|
|
|
+ num_qps_mw = nt->max_qps / NTB_NUM_MW + 1;
|
|
|
else
|
|
|
num_qps_mw = nt->max_qps / NTB_NUM_MW;
|
|
|
|
|
|
- size = nt->mw[mw_num].size / num_qps_mw;
|
|
|
-
|
|
|
+ rx_size = nt->mw[mw_num].size / num_qps_mw;
|
|
|
qp->rx_buff_begin = nt->mw[mw_num].virt_addr +
|
|
|
- (qp_num / NTB_NUM_MW * size);
|
|
|
- qp->rx_buff_end = qp->rx_buff_begin + size;
|
|
|
+ (qp_num / NTB_NUM_MW * rx_size);
|
|
|
+ qp->rx_buff_end = qp->rx_buff_begin + rx_size;
|
|
|
qp->rx_offset = qp->rx_buff_begin;
|
|
|
+ qp->rx_max_frame = min(transport_mtu, rx_size);
|
|
|
|
|
|
- qp->tx_mw_begin = ntb_get_mw_vbase(nt->ndev, mw_num) +
|
|
|
- (qp_num / NTB_NUM_MW * size);
|
|
|
- qp->tx_mw_end = qp->tx_mw_begin + size;
|
|
|
- qp->tx_offset = qp->tx_mw_begin;
|
|
|
+ /* setup the hdr offsets with 0's */
|
|
|
+ for (offset = qp->rx_buff_begin + qp->rx_max_frame -
|
|
|
+ sizeof(struct ntb_payload_header);
|
|
|
+ offset < qp->rx_buff_end; offset += qp->rx_max_frame)
|
|
|
+ memset(offset, 0, sizeof(struct ntb_payload_header));
|
|
|
|
|
|
qp->rx_pkts = 0;
|
|
|
qp->tx_pkts = 0;
|
|
@@ -489,7 +492,6 @@ static int ntb_set_mw(struct ntb_transport *nt, int num_mw, unsigned int size)
|
|
|
{
|
|
|
struct ntb_transport_mw *mw = &nt->mw[num_mw];
|
|
|
struct pci_dev *pdev = ntb_query_pdev(nt->ndev);
|
|
|
- void *offset;
|
|
|
|
|
|
/* Alloc memory for receiving data. Must be 4k aligned */
|
|
|
mw->size = ALIGN(size, 4096);
|
|
@@ -502,12 +504,6 @@ static int ntb_set_mw(struct ntb_transport *nt, int num_mw, unsigned int size)
|
|
|
return -ENOMEM;
|
|
|
}
|
|
|
|
|
|
- /* setup the hdr offsets with 0's */
|
|
|
- for (offset = mw->virt_addr + transport_mtu -
|
|
|
- sizeof(struct ntb_payload_header);
|
|
|
- offset < mw->virt_addr + size; offset += transport_mtu)
|
|
|
- memset(offset, 0, sizeof(struct ntb_payload_header));
|
|
|
-
|
|
|
/* Notify HW the memory location of the receive buffer */
|
|
|
ntb_set_mw_addr(nt->ndev, num_mw, mw->dma_addr);
|
|
|
|
|
@@ -737,6 +733,8 @@ static void ntb_transport_init_queue(struct ntb_transport *nt,
|
|
|
unsigned int qp_num)
|
|
|
{
|
|
|
struct ntb_transport_qp *qp;
|
|
|
+ unsigned int num_qps_mw, tx_size;
|
|
|
+ u8 mw_num = QP_TO_MW(qp_num);
|
|
|
|
|
|
qp = &nt->qps[qp_num];
|
|
|
qp->qp_num = qp_num;
|
|
@@ -746,6 +744,18 @@ static void ntb_transport_init_queue(struct ntb_transport *nt,
|
|
|
qp->client_ready = NTB_LINK_DOWN;
|
|
|
qp->event_handler = NULL;
|
|
|
|
|
|
+ if (nt->max_qps % NTB_NUM_MW && mw_num < nt->max_qps % NTB_NUM_MW)
|
|
|
+ num_qps_mw = nt->max_qps / NTB_NUM_MW + 1;
|
|
|
+ else
|
|
|
+ num_qps_mw = nt->max_qps / NTB_NUM_MW;
|
|
|
+
|
|
|
+ tx_size = ntb_get_mw_size(qp->ndev, mw_num) / num_qps_mw;
|
|
|
+ qp->tx_mw_begin = ntb_get_mw_vbase(nt->ndev, mw_num) +
|
|
|
+ (qp_num / NTB_NUM_MW * tx_size);
|
|
|
+ qp->tx_mw_end = qp->tx_mw_begin + tx_size;
|
|
|
+ qp->tx_offset = qp->tx_mw_begin;
|
|
|
+ qp->tx_max_frame = min(transport_mtu, tx_size);
|
|
|
+
|
|
|
if (nt->debugfs_dir) {
|
|
|
char debugfs_name[4];
|
|
|
|
|
@@ -873,9 +883,9 @@ static void ntb_rx_copy_task(struct ntb_transport_qp *qp,
|
|
|
struct ntb_payload_header *hdr;
|
|
|
|
|
|
BUG_ON(offset < qp->rx_buff_begin ||
|
|
|
- offset + transport_mtu >= qp->rx_buff_end);
|
|
|
+ offset + qp->rx_max_frame >= qp->rx_buff_end);
|
|
|
|
|
|
- hdr = offset + transport_mtu - sizeof(struct ntb_payload_header);
|
|
|
+ hdr = offset + qp->rx_max_frame - sizeof(struct ntb_payload_header);
|
|
|
entry->len = hdr->len;
|
|
|
|
|
|
memcpy(entry->buf, offset, entry->len);
|
|
@@ -898,7 +908,7 @@ static int ntb_process_rxc(struct ntb_transport_qp *qp)
|
|
|
|
|
|
entry = ntb_list_rm(&qp->ntb_rx_pend_q_lock, &qp->rx_pend_q);
|
|
|
if (!entry) {
|
|
|
- hdr = offset + transport_mtu -
|
|
|
+ hdr = offset + qp->rx_max_frame -
|
|
|
sizeof(struct ntb_payload_header);
|
|
|
dev_dbg(&ntb_query_pdev(qp->ndev)->dev,
|
|
|
"no buffer - HDR ver %llu, len %d, flags %x\n",
|
|
@@ -908,7 +918,7 @@ static int ntb_process_rxc(struct ntb_transport_qp *qp)
|
|
|
}
|
|
|
|
|
|
offset = qp->rx_offset;
|
|
|
- hdr = offset + transport_mtu - sizeof(struct ntb_payload_header);
|
|
|
+ hdr = offset + qp->rx_max_frame - sizeof(struct ntb_payload_header);
|
|
|
|
|
|
if (!(hdr->flags & DESC_DONE_FLAG)) {
|
|
|
ntb_list_add(&qp->ntb_rx_pend_q_lock, &entry->entry,
|
|
@@ -966,8 +976,8 @@ static int ntb_process_rxc(struct ntb_transport_qp *qp)
|
|
|
qp->rx_pkts++;
|
|
|
|
|
|
out:
|
|
|
- qp->rx_offset += transport_mtu;
|
|
|
- if (qp->rx_offset + transport_mtu >= qp->rx_buff_end)
|
|
|
+ qp->rx_offset += qp->rx_max_frame;
|
|
|
+ if (qp->rx_offset + qp->rx_max_frame >= qp->rx_buff_end)
|
|
|
qp->rx_offset = qp->rx_buff_begin;
|
|
|
|
|
|
return 0;
|
|
@@ -1000,11 +1010,11 @@ static void ntb_tx_copy_task(struct ntb_transport_qp *qp,
|
|
|
struct ntb_payload_header *hdr;
|
|
|
|
|
|
BUG_ON(offset < qp->tx_mw_begin ||
|
|
|
- offset + transport_mtu >= qp->tx_mw_end);
|
|
|
+ offset + qp->tx_max_frame >= qp->tx_mw_end);
|
|
|
|
|
|
memcpy_toio(offset, entry->buf, entry->len);
|
|
|
|
|
|
- hdr = offset + transport_mtu - sizeof(struct ntb_payload_header);
|
|
|
+ hdr = offset + qp->tx_max_frame - sizeof(struct ntb_payload_header);
|
|
|
hdr->len = entry->len;
|
|
|
hdr->ver = qp->tx_pkts;
|
|
|
|
|
@@ -1036,7 +1046,7 @@ static int ntb_process_tx(struct ntb_transport_qp *qp,
|
|
|
void *offset;
|
|
|
|
|
|
offset = qp->tx_offset;
|
|
|
- hdr = offset + transport_mtu - sizeof(struct ntb_payload_header);
|
|
|
+ hdr = offset + qp->tx_max_frame - sizeof(struct ntb_payload_header);
|
|
|
|
|
|
dev_dbg(&ntb_query_pdev(qp->ndev)->dev, "%lld - offset %p, tx %p, entry len %d flags %x buff %p\n",
|
|
|
qp->tx_pkts, offset, qp->tx_offset, entry->len, entry->flags,
|
|
@@ -1046,7 +1056,7 @@ static int ntb_process_tx(struct ntb_transport_qp *qp,
|
|
|
return -EAGAIN;
|
|
|
}
|
|
|
|
|
|
- if (entry->len > transport_mtu - sizeof(struct ntb_payload_header)) {
|
|
|
+ if (entry->len > qp->tx_max_frame - sizeof(struct ntb_payload_header)) {
|
|
|
if (qp->tx_handler)
|
|
|
qp->tx_handler(qp->cb_data, qp, NULL, -EIO);
|
|
|
|
|
@@ -1057,8 +1067,8 @@ static int ntb_process_tx(struct ntb_transport_qp *qp,
|
|
|
|
|
|
ntb_tx_copy_task(qp, entry, offset);
|
|
|
|
|
|
- qp->tx_offset += transport_mtu;
|
|
|
- if (qp->tx_offset + transport_mtu >= qp->tx_mw_end)
|
|
|
+ qp->tx_offset += qp->tx_max_frame;
|
|
|
+ if (qp->tx_offset + qp->tx_max_frame >= qp->tx_mw_end)
|
|
|
qp->tx_offset = qp->tx_mw_begin;
|
|
|
|
|
|
qp->tx_pkts++;
|
|
@@ -1425,9 +1435,8 @@ EXPORT_SYMBOL_GPL(ntb_transport_qp_num);
|
|
|
*
|
|
|
* RETURNS: the max payload size of a qp
|
|
|
*/
|
|
|
-unsigned int
|
|
|
-ntb_transport_max_size(__attribute__((unused)) struct ntb_transport_qp *qp)
|
|
|
+unsigned int ntb_transport_max_size(struct ntb_transport_qp *qp)
|
|
|
{
|
|
|
- return transport_mtu - sizeof(struct ntb_payload_header);
|
|
|
+ return qp->tx_max_frame - sizeof(struct ntb_payload_header);
|
|
|
}
|
|
|
EXPORT_SYMBOL_GPL(ntb_transport_max_size);
|