NTB: MFV 113fc505: Handle 64bit BAR sizes
64bit BAR sizes are permissible with an NTB device. To support them various modifications and clean-ups were required, most significantly using 2 32bit scratch pad registers for each BAR. Also, modify the driver to allow more than 2 Memory Windows. Authored by: Jon Mason Obtained from: Linux Sponsored by: EMC / Isilon Storage Division
This commit is contained in:
parent
78020bdbae
commit
393effa336
@ -194,11 +194,22 @@ struct ntb_payload_header {
|
||||
};
|
||||
|
||||
enum {
|
||||
/*
|
||||
* The order of this enum is part of the if_ntb remote protocol. Do
|
||||
* not reorder without bumping protocol version (and it's probably best
|
||||
* to keep the protocol in lock-step with the Linux NTB driver.
|
||||
*/
|
||||
IF_NTB_VERSION = 0,
|
||||
IF_NTB_MW0_SZ,
|
||||
IF_NTB_MW1_SZ,
|
||||
IF_NTB_NUM_QPS,
|
||||
IF_NTB_QP_LINKS,
|
||||
IF_NTB_NUM_QPS,
|
||||
IF_NTB_NUM_MWS,
|
||||
/*
|
||||
* N.B.: transport_link_work assumes MW1 enums = MW0 + 2.
|
||||
*/
|
||||
IF_NTB_MW0_SZ_HIGH,
|
||||
IF_NTB_MW0_SZ_LOW,
|
||||
IF_NTB_MW1_SZ_HIGH,
|
||||
IF_NTB_MW1_SZ_LOW,
|
||||
IF_NTB_MAX_SPAD,
|
||||
};
|
||||
|
||||
@ -242,6 +253,7 @@ static void ntb_rx_completion_task(void *arg, int pending);
|
||||
static void ntb_transport_event_callback(void *data, enum ntb_hw_event event);
|
||||
static void ntb_transport_link_work(void *arg);
|
||||
static int ntb_set_mw(struct ntb_netdev *nt, int num_mw, unsigned int size);
|
||||
static void ntb_free_mw(struct ntb_netdev *nt, int num_mw);
|
||||
static void ntb_transport_setup_qp_mw(struct ntb_netdev *nt,
|
||||
unsigned int qp_num);
|
||||
static void ntb_qp_link_work(void *arg);
|
||||
@ -514,9 +526,7 @@ ntb_transport_free(void *transport)
|
||||
ntb_unregister_event_callback(ntb);
|
||||
|
||||
for (i = 0; i < NTB_NUM_MW; i++)
|
||||
if (nt->mw[i].virt_addr != NULL)
|
||||
contigfree(nt->mw[i].virt_addr, nt->mw[i].size,
|
||||
M_NTB_IF);
|
||||
ntb_free_mw(nt, i);
|
||||
|
||||
free(nt->qps, M_NTB_IF);
|
||||
ntb_unregister_transport(ntb);
|
||||
@ -1019,19 +1029,24 @@ ntb_transport_link_work(void *arg)
|
||||
struct ntb_netdev *nt = arg;
|
||||
struct ntb_softc *ntb = nt->ntb;
|
||||
struct ntb_transport_qp *qp;
|
||||
uint64_t val64;
|
||||
uint32_t val;
|
||||
int rc, i;
|
||||
|
||||
/* send the local info */
|
||||
rc = ntb_write_remote_spad(ntb, IF_NTB_VERSION, NTB_TRANSPORT_VERSION);
|
||||
if (rc != 0)
|
||||
goto out;
|
||||
/* send the local info, in the opposite order of the way we read it */
|
||||
for (i = 0; i < NTB_NUM_MW; i++) {
|
||||
rc = ntb_write_remote_spad(ntb, IF_NTB_MW0_SZ_HIGH + (i * 2),
|
||||
ntb_get_mw_size(ntb, i) >> 32);
|
||||
if (rc != 0)
|
||||
goto out;
|
||||
|
||||
rc = ntb_write_remote_spad(ntb, IF_NTB_MW0_SZ, ntb_get_mw_size(ntb, 0));
|
||||
if (rc != 0)
|
||||
goto out;
|
||||
rc = ntb_write_remote_spad(ntb, IF_NTB_MW0_SZ_LOW + (i * 2),
|
||||
(uint32_t)ntb_get_mw_size(ntb, i));
|
||||
if (rc != 0)
|
||||
goto out;
|
||||
}
|
||||
|
||||
rc = ntb_write_remote_spad(ntb, IF_NTB_MW1_SZ, ntb_get_mw_size(ntb, 1));
|
||||
rc = ntb_write_remote_spad(ntb, IF_NTB_NUM_MWS, NTB_NUM_MW);
|
||||
if (rc != 0)
|
||||
goto out;
|
||||
|
||||
@ -1039,11 +1054,7 @@ ntb_transport_link_work(void *arg)
|
||||
if (rc != 0)
|
||||
goto out;
|
||||
|
||||
rc = ntb_read_remote_spad(ntb, IF_NTB_QP_LINKS, &val);
|
||||
if (rc != 0)
|
||||
goto out;
|
||||
|
||||
rc = ntb_write_remote_spad(ntb, IF_NTB_QP_LINKS, val);
|
||||
rc = ntb_write_remote_spad(ntb, IF_NTB_VERSION, NTB_TRANSPORT_VERSION);
|
||||
if (rc != 0)
|
||||
goto out;
|
||||
|
||||
@ -1062,27 +1073,32 @@ ntb_transport_link_work(void *arg)
|
||||
if (val != nt->max_qps)
|
||||
goto out;
|
||||
|
||||
rc = ntb_read_local_spad(ntb, IF_NTB_MW0_SZ, &val);
|
||||
rc = ntb_read_local_spad(ntb, IF_NTB_NUM_MWS, &val);
|
||||
if (rc != 0)
|
||||
goto out;
|
||||
|
||||
if (val == 0)
|
||||
if (val != NTB_NUM_MW)
|
||||
goto out;
|
||||
|
||||
rc = ntb_set_mw(nt, 0, val);
|
||||
if (rc != 0)
|
||||
return;
|
||||
for (i = 0; i < NTB_NUM_MW; i++) {
|
||||
rc = ntb_read_local_spad(ntb, IF_NTB_MW0_SZ_HIGH + (i * 2),
|
||||
&val);
|
||||
if (rc != 0)
|
||||
goto free_mws;
|
||||
|
||||
rc = ntb_read_local_spad(ntb, IF_NTB_MW1_SZ, &val);
|
||||
if (rc != 0)
|
||||
goto out;
|
||||
val64 = (uint64_t)val << 32;
|
||||
|
||||
if (val == 0)
|
||||
goto out;
|
||||
rc = ntb_read_local_spad(ntb, IF_NTB_MW0_SZ_LOW + (i * 2),
|
||||
&val);
|
||||
if (rc != 0)
|
||||
goto free_mws;
|
||||
|
||||
rc = ntb_set_mw(nt, 1, val);
|
||||
if (rc != 0)
|
||||
return;
|
||||
val64 |= val;
|
||||
|
||||
rc = ntb_set_mw(nt, i, val64);
|
||||
if (rc != 0)
|
||||
goto free_mws;
|
||||
}
|
||||
|
||||
nt->transport_link = NTB_LINK_UP;
|
||||
if (bootverbose)
|
||||
@ -1099,10 +1115,13 @@ ntb_transport_link_work(void *arg)
|
||||
|
||||
return;
|
||||
|
||||
free_mws:
|
||||
for (i = 0; i < NTB_NUM_MW; i++)
|
||||
ntb_free_mw(nt, i);
|
||||
out:
|
||||
if (ntb_query_link_status(ntb))
|
||||
callout_reset(&nt->link_work,
|
||||
NTB_LINK_DOWN_TIMEOUT * hz / 1000, ntb_transport_link_work, nt);
|
||||
NTB_LINK_DOWN_TIMEOUT * hz / 1000, ntb_transport_link_work, nt);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -1129,6 +1148,18 @@ ntb_set_mw(struct ntb_netdev *nt, int num_mw, unsigned int size)
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
ntb_free_mw(struct ntb_netdev *nt, int num_mw)
|
||||
{
|
||||
struct ntb_transport_mw *mw = &nt->mw[num_mw];
|
||||
|
||||
if (mw->virt_addr == NULL)
|
||||
return;
|
||||
|
||||
contigfree(mw->virt_addr, mw->size, M_NTB_IF);
|
||||
mw->virt_addr = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
ntb_transport_setup_qp_mw(struct ntb_netdev *nt, unsigned int qp_num)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user