X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fnetvsc%2Fhn_nvs.c;h=477202b2a0b7003a5e488abf05edd41cac5b2dcd;hb=d789705873d47d70a3ba0a6a4dfb83fb629d3464;hp=d58770e0455ed6fca8c619a95d3ada753c834d79;hpb=825ab257b5ce8235ab0cdc260e5b7b757e102875;p=dpdk.git diff --git a/drivers/net/netvsc/hn_nvs.c b/drivers/net/netvsc/hn_nvs.c index d58770e045..477202b2a0 100644 --- a/drivers/net/netvsc/hn_nvs.c +++ b/drivers/net/netvsc/hn_nvs.c @@ -54,7 +54,7 @@ static int hn_nvs_req_send(struct hn_data *hv, } static int -hn_nvs_execute(struct hn_data *hv, +__hn_nvs_execute(struct hn_data *hv, void *req, uint32_t reqlen, void *resp, uint32_t resplen, uint32_t type) @@ -62,6 +62,7 @@ hn_nvs_execute(struct hn_data *hv, struct vmbus_channel *chan = hn_primary_chan(hv); char buffer[NVS_RESPSIZE_MAX]; const struct hn_nvs_hdr *hdr; + uint64_t xactid; uint32_t len; int ret; @@ -77,7 +78,7 @@ hn_nvs_execute(struct hn_data *hv, retry: len = sizeof(buffer); - ret = rte_vmbus_chan_recv(chan, buffer, &len, NULL); + ret = rte_vmbus_chan_recv(chan, buffer, &len, &xactid); if (ret == -EAGAIN) { rte_delay_us(HN_CHAN_INTERVAL_US); goto retry; @@ -88,7 +89,20 @@ hn_nvs_execute(struct hn_data *hv, return ret; } + if (len < sizeof(*hdr)) { + PMD_DRV_LOG(ERR, "response missing NVS header"); + return -EINVAL; + } + hdr = (struct hn_nvs_hdr *)buffer; + + /* Silently drop received packets while waiting for response */ + if (hdr->type == NVS_TYPE_RNDIS) { + hn_nvs_ack_rxbuf(chan, xactid); + --hv->rxbuf_outstanding; + goto retry; + } + if (hdr->type != type) { PMD_DRV_LOG(ERR, "unexpected NVS resp %#x, expect %#x", hdr->type, type); @@ -108,6 +122,29 @@ hn_nvs_execute(struct hn_data *hv, return 0; } + +/* + * Execute one control command and get the response. + * Only one command can be active on a channel at once + * Unlike BSD, DPDK does not have an interrupt context + * so the polling is required to wait for response. + */ +static int +hn_nvs_execute(struct hn_data *hv, + void *req, uint32_t reqlen, + void *resp, uint32_t resplen, + uint32_t type) +{ + struct hn_rx_queue *rxq = hv->primary; + int ret; + + rte_spinlock_lock(&rxq->ring_lock); + ret = __hn_nvs_execute(hv, req, reqlen, resp, resplen, type); + rte_spinlock_unlock(&rxq->ring_lock); + + return ret; +} + static int hn_nvs_doinit(struct hn_data *hv, uint32_t nvs_ver) { @@ -323,7 +360,7 @@ hn_nvs_conf_ndis(struct hn_data *hv, unsigned int mtu) memset(&conf, 0, sizeof(conf)); conf.type = NVS_TYPE_NDIS_CONF; - conf.mtu = mtu + ETHER_HDR_LEN; + conf.mtu = mtu + RTE_ETHER_HDR_LEN; conf.caps = NVS_NDIS_CONF_VLAN; /* enable SRIOV */