Commit f5a22550 authored by Stephen Hemminger's avatar Stephen Hemminger Committed by David S. Miller

hv_netvsc: optimize initialization of RNDIS header

The memset of the whole maximum possible RNDIS header is unnecessary.
For the main part of the header use a structure assignment.

No need to memset the whole per packet info. Instead rely on caller to
set what it wants. Also get rid of cast to void and signed/unsigned
conversion. Now return pointer to per packet data (rather than the
header) which simplifies use by code setting up the packet data.
Signed-off-by: default avatarStephen Hemminger <sthemmin@microsoft.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent a7f99d0f
...@@ -177,17 +177,15 @@ static int netvsc_close(struct net_device *net) ...@@ -177,17 +177,15 @@ static int netvsc_close(struct net_device *net)
return ret; return ret;
} }
static void *init_ppi_data(struct rndis_message *msg, u32 ppi_size, static inline void *init_ppi_data(struct rndis_message *msg,
int pkt_type) u32 ppi_size, u32 pkt_type)
{ {
struct rndis_packet *rndis_pkt; struct rndis_packet *rndis_pkt = &msg->msg.pkt;
struct rndis_per_packet_info *ppi; struct rndis_per_packet_info *ppi;
rndis_pkt = &msg->msg.pkt;
rndis_pkt->data_offset += ppi_size; rndis_pkt->data_offset += ppi_size;
ppi = (void *)rndis_pkt + rndis_pkt->per_pkt_info_offset
ppi = (struct rndis_per_packet_info *)((void *)rndis_pkt + + rndis_pkt->per_pkt_info_len;
rndis_pkt->per_pkt_info_offset + rndis_pkt->per_pkt_info_len);
ppi->size = ppi_size; ppi->size = ppi_size;
ppi->type = pkt_type; ppi->type = pkt_type;
...@@ -195,7 +193,7 @@ static void *init_ppi_data(struct rndis_message *msg, u32 ppi_size, ...@@ -195,7 +193,7 @@ static void *init_ppi_data(struct rndis_message *msg, u32 ppi_size,
rndis_pkt->per_pkt_info_len += ppi_size; rndis_pkt->per_pkt_info_len += ppi_size;
return ppi; return ppi + 1;
} }
/* Azure hosts don't support non-TCP port numbers in hashing for fragmented /* Azure hosts don't support non-TCP port numbers in hashing for fragmented
...@@ -472,10 +470,8 @@ static int netvsc_start_xmit(struct sk_buff *skb, struct net_device *net) ...@@ -472,10 +470,8 @@ static int netvsc_start_xmit(struct sk_buff *skb, struct net_device *net)
int ret; int ret;
unsigned int num_data_pgs; unsigned int num_data_pgs;
struct rndis_message *rndis_msg; struct rndis_message *rndis_msg;
struct rndis_packet *rndis_pkt;
struct net_device *vf_netdev; struct net_device *vf_netdev;
u32 rndis_msg_size; u32 rndis_msg_size;
struct rndis_per_packet_info *ppi;
u32 hash; u32 hash;
struct hv_page_buffer pb[MAX_PAGE_BUFFER_COUNT]; struct hv_page_buffer pb[MAX_PAGE_BUFFER_COUNT];
...@@ -530,34 +526,36 @@ static int netvsc_start_xmit(struct sk_buff *skb, struct net_device *net) ...@@ -530,34 +526,36 @@ static int netvsc_start_xmit(struct sk_buff *skb, struct net_device *net)
rndis_msg = (struct rndis_message *)skb->head; rndis_msg = (struct rndis_message *)skb->head;
memset(rndis_msg, 0, RNDIS_AND_PPI_SIZE);
/* Add the rndis header */ /* Add the rndis header */
rndis_msg->ndis_msg_type = RNDIS_MSG_PACKET; rndis_msg->ndis_msg_type = RNDIS_MSG_PACKET;
rndis_msg->msg_len = packet->total_data_buflen; rndis_msg->msg_len = packet->total_data_buflen;
rndis_pkt = &rndis_msg->msg.pkt;
rndis_pkt->data_offset = sizeof(struct rndis_packet); rndis_msg->msg.pkt = (struct rndis_packet) {
rndis_pkt->data_len = packet->total_data_buflen; .data_offset = sizeof(struct rndis_packet),
rndis_pkt->per_pkt_info_offset = sizeof(struct rndis_packet); .data_len = packet->total_data_buflen,
.per_pkt_info_offset = sizeof(struct rndis_packet),
};
rndis_msg_size = RNDIS_MESSAGE_SIZE(struct rndis_packet); rndis_msg_size = RNDIS_MESSAGE_SIZE(struct rndis_packet);
hash = skb_get_hash_raw(skb); hash = skb_get_hash_raw(skb);
if (hash != 0 && net->real_num_tx_queues > 1) { if (hash != 0 && net->real_num_tx_queues > 1) {
u32 *hash_info;
rndis_msg_size += NDIS_HASH_PPI_SIZE; rndis_msg_size += NDIS_HASH_PPI_SIZE;
ppi = init_ppi_data(rndis_msg, NDIS_HASH_PPI_SIZE, hash_info = init_ppi_data(rndis_msg, NDIS_HASH_PPI_SIZE,
NBL_HASH_VALUE); NBL_HASH_VALUE);
*(u32 *)((void *)ppi + ppi->ppi_offset) = hash; *hash_info = hash;
} }
if (skb_vlan_tag_present(skb)) { if (skb_vlan_tag_present(skb)) {
struct ndis_pkt_8021q_info *vlan; struct ndis_pkt_8021q_info *vlan;
rndis_msg_size += NDIS_VLAN_PPI_SIZE; rndis_msg_size += NDIS_VLAN_PPI_SIZE;
ppi = init_ppi_data(rndis_msg, NDIS_VLAN_PPI_SIZE, vlan = init_ppi_data(rndis_msg, NDIS_VLAN_PPI_SIZE,
IEEE_8021Q_INFO); IEEE_8021Q_INFO);
vlan = (void *)ppi + ppi->ppi_offset; vlan->value = 0;
vlan->vlanid = skb->vlan_tci & VLAN_VID_MASK; vlan->vlanid = skb->vlan_tci & VLAN_VID_MASK;
vlan->pri = (skb->vlan_tci & VLAN_PRIO_MASK) >> vlan->pri = (skb->vlan_tci & VLAN_PRIO_MASK) >>
VLAN_PRIO_SHIFT; VLAN_PRIO_SHIFT;
...@@ -567,11 +565,10 @@ static int netvsc_start_xmit(struct sk_buff *skb, struct net_device *net) ...@@ -567,11 +565,10 @@ static int netvsc_start_xmit(struct sk_buff *skb, struct net_device *net)
struct ndis_tcp_lso_info *lso_info; struct ndis_tcp_lso_info *lso_info;
rndis_msg_size += NDIS_LSO_PPI_SIZE; rndis_msg_size += NDIS_LSO_PPI_SIZE;
ppi = init_ppi_data(rndis_msg, NDIS_LSO_PPI_SIZE, lso_info = init_ppi_data(rndis_msg, NDIS_LSO_PPI_SIZE,
TCP_LARGESEND_PKTINFO); TCP_LARGESEND_PKTINFO);
lso_info = (void *)ppi + ppi->ppi_offset; lso_info->value = 0;
lso_info->lso_v2_transmit.type = NDIS_TCP_LARGE_SEND_OFFLOAD_V2_TYPE; lso_info->lso_v2_transmit.type = NDIS_TCP_LARGE_SEND_OFFLOAD_V2_TYPE;
if (skb->protocol == htons(ETH_P_IP)) { if (skb->protocol == htons(ETH_P_IP)) {
lso_info->lso_v2_transmit.ip_version = lso_info->lso_v2_transmit.ip_version =
...@@ -596,12 +593,10 @@ static int netvsc_start_xmit(struct sk_buff *skb, struct net_device *net) ...@@ -596,12 +593,10 @@ static int netvsc_start_xmit(struct sk_buff *skb, struct net_device *net)
struct ndis_tcp_ip_checksum_info *csum_info; struct ndis_tcp_ip_checksum_info *csum_info;
rndis_msg_size += NDIS_CSUM_PPI_SIZE; rndis_msg_size += NDIS_CSUM_PPI_SIZE;
ppi = init_ppi_data(rndis_msg, NDIS_CSUM_PPI_SIZE, csum_info = init_ppi_data(rndis_msg, NDIS_CSUM_PPI_SIZE,
TCPIP_CHKSUM_PKTINFO); TCPIP_CHKSUM_PKTINFO);
csum_info = (struct ndis_tcp_ip_checksum_info *)((void *)ppi + csum_info->value = 0;
ppi->ppi_offset);
csum_info->transmit.tcp_header_offset = skb_transport_offset(skb); csum_info->transmit.tcp_header_offset = skb_transport_offset(skb);
if (skb->protocol == htons(ETH_P_IP)) { if (skb->protocol == htons(ETH_P_IP)) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment