hyperv/hn: Simplify RNDIS NVS message sending.

MFC after:	1 week
Sponsored by:	Microsoft
Differential Revision:	https://reviews.freebsd.org/D7501
This commit is contained in:
sephe 2016-08-16 07:37:02 +00:00
parent b2c45dd531
commit 86f8b8d983
6 changed files with 58 additions and 41 deletions

View File

@ -118,7 +118,7 @@ hv_nv_get_next_send_section(netvsc_dev *net_dev)
unsigned long bitsmap_words = net_dev->bitsmap_words;
unsigned long *bitsmap = net_dev->send_section_bitsmap;
unsigned long idx;
int ret = NVSP_1_CHIMNEY_SEND_INVALID_SECTION_INDEX;
int ret = HN_NVS_CHIM_IDX_INVALID;
int i;
for (i = 0; i < bitsmap_words; i++) {
@ -814,32 +814,23 @@ hv_nv_on_send_completion(netvsc_dev *net_dev, struct vmbus_channel *chan,
* Returns 0 on success, non-zero on failure.
*/
int
hv_nv_on_send(struct vmbus_channel *chan, bool is_data_pkt,
hv_nv_on_send(struct vmbus_channel *chan, uint32_t rndis_mtype,
struct hn_send_ctx *sndc, struct vmbus_gpa *gpa, int gpa_cnt)
{
nvsp_msg send_msg;
struct hn_nvs_rndis rndis;
int ret;
send_msg.hdr.msg_type = nvsp_msg_1_type_send_rndis_pkt;
if (is_data_pkt) {
/* 0 is RMC_DATA */
send_msg.msgs.vers_1_msgs.send_rndis_pkt.chan_type = 0;
} else {
/* 1 is RMC_CONTROL */
send_msg.msgs.vers_1_msgs.send_rndis_pkt.chan_type = 1;
}
send_msg.msgs.vers_1_msgs.send_rndis_pkt.send_buf_section_idx =
sndc->hn_chim_idx;
send_msg.msgs.vers_1_msgs.send_rndis_pkt.send_buf_section_size =
sndc->hn_chim_sz;
rndis.nvs_type = HN_NVS_TYPE_RNDIS;
rndis.nvs_rndis_mtype = rndis_mtype;
rndis.nvs_chim_idx = sndc->hn_chim_idx;
rndis.nvs_chim_sz = sndc->hn_chim_sz;
if (gpa_cnt) {
ret = hn_nvs_send_sglist(chan, gpa, gpa_cnt,
&send_msg, sizeof(nvsp_msg), sndc);
&rndis, sizeof(rndis), sndc);
} else {
ret = hn_nvs_send(chan, VMBUS_CHANPKT_FLAG_RC,
&send_msg, sizeof(nvsp_msg), sndc);
&rndis, sizeof(rndis), sndc);
}
return (ret);

View File

@ -1256,7 +1256,7 @@ netvsc_dev *hv_nv_on_device_add(struct hn_softc *sc,
void *additional_info, struct hn_rx_ring *rxr);
int hv_nv_on_device_remove(struct hn_softc *sc,
boolean_t destroy_channel);
int hv_nv_on_send(struct vmbus_channel *chan, bool is_data_pkt,
int hv_nv_on_send(struct vmbus_channel *chan, uint32_t rndis_mtype,
struct hn_send_ctx *sndc, struct vmbus_gpa *gpa, int gpa_cnt);
int hv_nv_get_next_send_section(netvsc_dev *net_dev);
void hv_nv_subchan_attach(struct vmbus_channel *chan,

View File

@ -798,7 +798,7 @@ hn_tx_done(struct hn_send_ctx *sndc, struct netvsc_dev_ *net_dev,
struct hn_txdesc *txd = sndc->hn_cbarg;
struct hn_tx_ring *txr;
if (sndc->hn_chim_idx != NVSP_1_CHIMNEY_SEND_INVALID_SECTION_INDEX)
if (sndc->hn_chim_idx != HN_NVS_CHIM_IDX_INVALID)
hn_chim_free(net_dev, sndc->hn_chim_idx);
txr = txd->txr;
@ -988,8 +988,7 @@ hn_encap(struct hn_tx_ring *txr, struct hn_txdesc *txd, struct mbuf **m_head0)
txr->hn_tx_chimney_tried++;
send_buf_section_idx =
hv_nv_get_next_send_section(net_dev);
if (send_buf_section_idx !=
NVSP_1_CHIMNEY_SEND_INVALID_SECTION_INDEX) {
if (send_buf_section_idx != HN_NVS_CHIM_IDX_INVALID) {
uint8_t *dest = ((uint8_t *)net_dev->send_buf +
(send_buf_section_idx *
net_dev->send_section_size));
@ -1045,7 +1044,7 @@ hn_encap(struct hn_tx_ring *txr, struct hn_txdesc *txd, struct mbuf **m_head0)
gpa->gpa_len = segs[i].ds_len;
}
send_buf_section_idx = NVSP_1_CHIMNEY_SEND_INVALID_SECTION_INDEX;
send_buf_section_idx = HN_NVS_CHIM_IDX_INVALID;
send_buf_section_size = 0;
done:
txd->m = m_head;
@ -1072,8 +1071,8 @@ hn_send_pkt(struct ifnet *ifp, struct hn_tx_ring *txr, struct hn_txdesc *txd)
* Make sure that txd is not freed before ETHER_BPF_MTAP.
*/
hn_txdesc_hold(txd);
error = hv_nv_on_send(txr->hn_chan, true, &txd->send_ctx,
txr->hn_gpa, txr->hn_gpa_cnt);
error = hv_nv_on_send(txr->hn_chan, HN_NVS_RNDIS_MTYPE_DATA,
&txd->send_ctx, txr->hn_gpa, txr->hn_gpa_cnt);
if (!error) {
ETHER_BPF_MTAP(ifp, txd->m);
if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);

View File

@ -277,8 +277,7 @@ hv_rf_send_request(rndis_device *device, rndis_request *request,
if (tot_data_buf_len < net_dev->send_section_size) {
send_buf_section_idx = hv_nv_get_next_send_section(net_dev);
if (send_buf_section_idx !=
NVSP_1_CHIMNEY_SEND_INVALID_SECTION_INDEX) {
if (send_buf_section_idx != HN_NVS_CHIM_IDX_INVALID) {
char *dest = ((char *)net_dev->send_buf +
send_buf_section_idx * net_dev->send_section_size);
@ -289,14 +288,14 @@ hv_rf_send_request(rndis_device *device, rndis_request *request,
}
/* Failed to allocate chimney send buffer; move on */
}
send_buf_section_idx = NVSP_1_CHIMNEY_SEND_INVALID_SECTION_INDEX;
send_buf_section_idx = HN_NVS_CHIM_IDX_INVALID;
send_buf_section_size = 0;
sendit:
hn_send_ctx_init(&request->send_ctx, cb, request,
send_buf_section_idx, send_buf_section_size);
return hv_nv_on_send(device->net_dev->sc->hn_prichan, false,
&request->send_ctx, gpa, gpa_cnt);
return hv_nv_on_send(device->net_dev->sc->hn_prichan,
HN_NVS_RNDIS_MTYPE_CTRL, &request->send_ctx, gpa, gpa_cnt);
}
/*
@ -1276,7 +1275,7 @@ hn_rndis_sent_cb(struct hn_send_ctx *sndc, struct netvsc_dev_ *net_dev,
struct vmbus_channel *chan __unused, const struct nvsp_msg_ *msg __unused,
int dlen __unused)
{
if (sndc->hn_chim_idx != NVSP_1_CHIMNEY_SEND_INVALID_SECTION_INDEX)
if (sndc->hn_chim_idx != HN_NVS_CHIM_IDX_INVALID)
hn_chim_free(net_dev, sndc->hn_chim_idx);
}
@ -1287,7 +1286,7 @@ hn_rndis_sent_halt(struct hn_send_ctx *sndc, struct netvsc_dev_ *net_dev,
{
rndis_request *request = sndc->hn_cbarg;
if (sndc->hn_chim_idx != NVSP_1_CHIMNEY_SEND_INVALID_SECTION_INDEX)
if (sndc->hn_chim_idx != HN_NVS_CHIM_IDX_INVALID)
hn_chim_free(net_dev, sndc->hn_chim_idx);
/*

View File

@ -35,8 +35,19 @@
#define HN_NVS_RXBUF_SIG 0xcafe
#define HN_NVS_CHIM_SIG 0xface
#define HN_NVS_CHIM_IDX_INVALID 0xffffffff
#define HN_NVS_RNDIS_MTYPE_DATA 0
#define HN_NVS_RNDIS_MTYPE_CTRL 1
/*
* NVS message transacion status codes.
*/
#define HN_NVS_STATUS_OK 1
/*
* NVS request/response message types.
*/
#define HN_NVS_TYPE_INIT 1
#define HN_NVS_TYPE_INIT_RESP 2
#define HN_NVS_TYPE_NDIS_INIT 100
@ -46,6 +57,7 @@
#define HN_NVS_TYPE_CHIM_CONN 104
#define HN_NVS_TYPE_CHIM_CONNRESP 105
#define HN_NVS_TYPE_CHIM_DISCONN 106
#define HN_NVS_TYPE_RNDIS 107
#define HN_NVS_TYPE_NDIS_CONF 125
#define HN_NVS_TYPE_SUBCH_REQ 133
#define HN_NVS_TYPE_SUBCH_RESP 133 /* same as SUBCH_REQ */
@ -162,4 +174,21 @@ struct hn_nvs_subch_resp {
uint32_t nvs_nsubch;
} __packed;
struct hn_nvs_rndis {
uint32_t nvs_type; /* HN_NVS_TYPE_RNDIS */
uint32_t nvs_rndis_mtype;/* HN_NVS_RNDIS_MTYPE_ */
/*
* Chimney sending buffer index and size.
*
* NOTE:
* If nvs_chim_idx is set to HN_NVS_CHIM_IDX_INVALID
* and nvs_chim_sz is set to 0, then chimney sending
* buffer is _not_ used by this RNDIS message.
*/
uint32_t nvs_chim_idx;
uint32_t nvs_chim_sz;
uint8_t nvs_rsvd[16];
} __packed;
CTASSERT(sizeof(struct hn_nvs_rndis) >= HN_NVS_REQSIZE_MIN);
#endif /* !_IF_HNREG_H_ */

View File

@ -32,7 +32,7 @@
#include <sys/param.h>
#include <dev/hyperv/include/vmbus.h>
#include <dev/hyperv/netvsc/hv_net_vsc.h>
#include <dev/hyperv/netvsc/if_hnreg.h>
struct netvsc_dev_;
struct nvsp_msg_;
@ -51,12 +51,12 @@ struct hn_send_ctx {
int hn_chim_sz;
};
#define HN_SEND_CTX_INITIALIZER(cb, cbarg) \
{ \
.hn_cb = cb, \
.hn_cbarg = cbarg, \
.hn_chim_idx = NVSP_1_CHIMNEY_SEND_INVALID_SECTION_INDEX, \
.hn_chim_sz = 0 \
#define HN_SEND_CTX_INITIALIZER(cb, cbarg) \
{ \
.hn_cb = cb, \
.hn_cbarg = cbarg, \
.hn_chim_idx = HN_NVS_CHIM_IDX_INVALID, \
.hn_chim_sz = 0 \
}
static __inline void
@ -75,8 +75,7 @@ hn_send_ctx_init_simple(struct hn_send_ctx *sndc, hn_sent_callback_t cb,
void *cbarg)
{
hn_send_ctx_init(sndc, cb, cbarg,
NVSP_1_CHIMNEY_SEND_INVALID_SECTION_INDEX, 0);
hn_send_ctx_init(sndc, cb, cbarg, HN_NVS_CHIM_IDX_INVALID, 0);
}
static __inline int