diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-06-12 17:27:40 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-06-12 17:27:40 -0400 |
commit | f9da455b93f6ba076935b4ef4589f61e529ae046 (patch) | |
tree | 3c4e69ce1ba1d6bf65915b97a76ca2172105b278 /drivers/net/hyperv/netvsc_drv.c | |
parent | 0e04c641b199435f3779454055f6a7de258ecdfc (diff) | |
parent | e5eca6d41f53db48edd8cf88a3f59d2c30227f8e (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next
Pull networking updates from David Miller:
1) Seccomp BPF filters can now be JIT'd, from Alexei Starovoitov.
2) Multiqueue support in xen-netback and xen-netfront, from Andrew J
Benniston.
3) Allow tweaking of aggregation settings in cdc_ncm driver, from Bjørn
Mork.
4) BPF now has a "random" opcode, from Chema Gonzalez.
5) Add more BPF documentation and improve test framework, from Daniel
Borkmann.
6) Support TCP fastopen over ipv6, from Daniel Lee.
7) Add software TSO helper functions and use them to support software
TSO in mvneta and mv643xx_eth drivers. From Ezequiel Garcia.
8) Support software TSO in fec driver too, from Nimrod Andy.
9) Add Broadcom SYSTEMPORT driver, from Florian Fainelli.
10) Handle broadcasts more gracefully over macvlan when there are large
numbers of interfaces configured, from Herbert Xu.
11) Allow more control over fwmark used for non-socket based responses,
from Lorenzo Colitti.
12) Do TCP congestion window limiting based upon measurements, from Neal
Cardwell.
13) Support busy polling in SCTP, from Neal Horman.
14) Allow RSS key to be configured via ethtool, from Venkata Duvvuru.
15) Bridge promisc mode handling improvements from Vlad Yasevich.
16) Don't use inetpeer entries to implement ID generation any more, it
performs poorly, from Eric Dumazet.
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next: (1522 commits)
rtnetlink: fix userspace API breakage for iproute2 < v3.9.0
tcp: fixing TLP's FIN recovery
net: fec: Add software TSO support
net: fec: Add Scatter/gather support
net: fec: Increase buffer descriptor entry number
net: fec: Factorize feature setting
net: fec: Enable IP header hardware checksum
net: fec: Factorize the .xmit transmit function
bridge: fix compile error when compiling without IPv6 support
bridge: fix smatch warning / potential null pointer dereference
via-rhine: fix full-duplex with autoneg disable
bnx2x: Enlarge the dorq threshold for VFs
bnx2x: Check for UNDI in uncommon branch
bnx2x: Fix 1G-baseT link
bnx2x: Fix link for KR with swapped polarity lane
sctp: Fix sk_ack_backlog wrap-around problem
net/core: Add VF link state control policy
net/fsl: xgmac_mdio is dependent on OF_MDIO
net/fsl: Make xgmac_mdio read error message useful
net_sched: drr: warn when qdisc is not work conserving
...
Diffstat (limited to 'drivers/net/hyperv/netvsc_drv.c')
-rw-r--r-- | drivers/net/hyperv/netvsc_drv.c | 129 |
1 files changed, 117 insertions, 12 deletions
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c index 7918d5132c1f..4fd71b75e666 100644 --- a/drivers/net/hyperv/netvsc_drv.c +++ b/drivers/net/hyperv/netvsc_drv.c | |||
@@ -101,7 +101,7 @@ static int netvsc_open(struct net_device *net) | |||
101 | return ret; | 101 | return ret; |
102 | } | 102 | } |
103 | 103 | ||
104 | netif_start_queue(net); | 104 | netif_tx_start_all_queues(net); |
105 | 105 | ||
106 | nvdev = hv_get_drvdata(device_obj); | 106 | nvdev = hv_get_drvdata(device_obj); |
107 | rdev = nvdev->extension; | 107 | rdev = nvdev->extension; |
@@ -149,15 +149,100 @@ static void *init_ppi_data(struct rndis_message *msg, u32 ppi_size, | |||
149 | return ppi; | 149 | return ppi; |
150 | } | 150 | } |
151 | 151 | ||
152 | union sub_key { | ||
153 | u64 k; | ||
154 | struct { | ||
155 | u8 pad[3]; | ||
156 | u8 kb; | ||
157 | u32 ka; | ||
158 | }; | ||
159 | }; | ||
160 | |||
161 | /* Toeplitz hash function | ||
162 | * data: network byte order | ||
163 | * return: host byte order | ||
164 | */ | ||
165 | static u32 comp_hash(u8 *key, int klen, u8 *data, int dlen) | ||
166 | { | ||
167 | union sub_key subk; | ||
168 | int k_next = 4; | ||
169 | u8 dt; | ||
170 | int i, j; | ||
171 | u32 ret = 0; | ||
172 | |||
173 | subk.k = 0; | ||
174 | subk.ka = ntohl(*(u32 *)key); | ||
175 | |||
176 | for (i = 0; i < dlen; i++) { | ||
177 | subk.kb = key[k_next]; | ||
178 | k_next = (k_next + 1) % klen; | ||
179 | dt = data[i]; | ||
180 | for (j = 0; j < 8; j++) { | ||
181 | if (dt & 0x80) | ||
182 | ret ^= subk.ka; | ||
183 | dt <<= 1; | ||
184 | subk.k <<= 1; | ||
185 | } | ||
186 | } | ||
187 | |||
188 | return ret; | ||
189 | } | ||
190 | |||
191 | static bool netvsc_set_hash(u32 *hash, struct sk_buff *skb) | ||
192 | { | ||
193 | struct iphdr *iphdr; | ||
194 | int data_len; | ||
195 | bool ret = false; | ||
196 | |||
197 | if (eth_hdr(skb)->h_proto != htons(ETH_P_IP)) | ||
198 | return false; | ||
199 | |||
200 | iphdr = ip_hdr(skb); | ||
201 | |||
202 | if (iphdr->version == 4) { | ||
203 | if (iphdr->protocol == IPPROTO_TCP) | ||
204 | data_len = 12; | ||
205 | else | ||
206 | data_len = 8; | ||
207 | *hash = comp_hash(netvsc_hash_key, HASH_KEYLEN, | ||
208 | (u8 *)&iphdr->saddr, data_len); | ||
209 | ret = true; | ||
210 | } | ||
211 | |||
212 | return ret; | ||
213 | } | ||
214 | |||
215 | static u16 netvsc_select_queue(struct net_device *ndev, struct sk_buff *skb, | ||
216 | void *accel_priv, select_queue_fallback_t fallback) | ||
217 | { | ||
218 | struct net_device_context *net_device_ctx = netdev_priv(ndev); | ||
219 | struct hv_device *hdev = net_device_ctx->device_ctx; | ||
220 | struct netvsc_device *nvsc_dev = hv_get_drvdata(hdev); | ||
221 | u32 hash; | ||
222 | u16 q_idx = 0; | ||
223 | |||
224 | if (nvsc_dev == NULL || ndev->real_num_tx_queues <= 1) | ||
225 | return 0; | ||
226 | |||
227 | if (netvsc_set_hash(&hash, skb)) { | ||
228 | q_idx = nvsc_dev->send_table[hash % VRSS_SEND_TAB_SIZE] % | ||
229 | ndev->real_num_tx_queues; | ||
230 | skb_set_hash(skb, hash, PKT_HASH_TYPE_L3); | ||
231 | } | ||
232 | |||
233 | return q_idx; | ||
234 | } | ||
235 | |||
152 | static void netvsc_xmit_completion(void *context) | 236 | static void netvsc_xmit_completion(void *context) |
153 | { | 237 | { |
154 | struct hv_netvsc_packet *packet = (struct hv_netvsc_packet *)context; | 238 | struct hv_netvsc_packet *packet = (struct hv_netvsc_packet *)context; |
155 | struct sk_buff *skb = (struct sk_buff *) | 239 | struct sk_buff *skb = (struct sk_buff *) |
156 | (unsigned long)packet->completion.send.send_completion_tid; | 240 | (unsigned long)packet->send_completion_tid; |
241 | u32 index = packet->send_buf_index; | ||
157 | 242 | ||
158 | kfree(packet); | 243 | kfree(packet); |
159 | 244 | ||
160 | if (skb) | 245 | if (skb && (index == NETVSC_INVALID_INDEX)) |
161 | dev_kfree_skb_any(skb); | 246 | dev_kfree_skb_any(skb); |
162 | } | 247 | } |
163 | 248 | ||
@@ -301,6 +386,7 @@ static int netvsc_start_xmit(struct sk_buff *skb, struct net_device *net) | |||
301 | struct ndis_tcp_lso_info *lso_info; | 386 | struct ndis_tcp_lso_info *lso_info; |
302 | int hdr_offset; | 387 | int hdr_offset; |
303 | u32 net_trans_info; | 388 | u32 net_trans_info; |
389 | u32 hash; | ||
304 | 390 | ||
305 | 391 | ||
306 | /* We will atmost need two pages to describe the rndis | 392 | /* We will atmost need two pages to describe the rndis |
@@ -319,9 +405,8 @@ static int netvsc_start_xmit(struct sk_buff *skb, struct net_device *net) | |||
319 | packet = kzalloc(sizeof(struct hv_netvsc_packet) + | 405 | packet = kzalloc(sizeof(struct hv_netvsc_packet) + |
320 | (num_data_pgs * sizeof(struct hv_page_buffer)) + | 406 | (num_data_pgs * sizeof(struct hv_page_buffer)) + |
321 | sizeof(struct rndis_message) + | 407 | sizeof(struct rndis_message) + |
322 | NDIS_VLAN_PPI_SIZE + | 408 | NDIS_VLAN_PPI_SIZE + NDIS_CSUM_PPI_SIZE + |
323 | NDIS_CSUM_PPI_SIZE + | 409 | NDIS_LSO_PPI_SIZE + NDIS_HASH_PPI_SIZE, GFP_ATOMIC); |
324 | NDIS_LSO_PPI_SIZE, GFP_ATOMIC); | ||
325 | if (!packet) { | 410 | if (!packet) { |
326 | /* out of memory, drop packet */ | 411 | /* out of memory, drop packet */ |
327 | netdev_err(net, "unable to allocate hv_netvsc_packet\n"); | 412 | netdev_err(net, "unable to allocate hv_netvsc_packet\n"); |
@@ -333,6 +418,8 @@ static int netvsc_start_xmit(struct sk_buff *skb, struct net_device *net) | |||
333 | 418 | ||
334 | packet->vlan_tci = skb->vlan_tci; | 419 | packet->vlan_tci = skb->vlan_tci; |
335 | 420 | ||
421 | packet->q_idx = skb_get_queue_mapping(skb); | ||
422 | |||
336 | packet->is_data_pkt = true; | 423 | packet->is_data_pkt = true; |
337 | packet->total_data_buflen = skb->len; | 424 | packet->total_data_buflen = skb->len; |
338 | 425 | ||
@@ -341,9 +428,9 @@ static int netvsc_start_xmit(struct sk_buff *skb, struct net_device *net) | |||
341 | (num_data_pgs * sizeof(struct hv_page_buffer))); | 428 | (num_data_pgs * sizeof(struct hv_page_buffer))); |
342 | 429 | ||
343 | /* Set the completion routine */ | 430 | /* Set the completion routine */ |
344 | packet->completion.send.send_completion = netvsc_xmit_completion; | 431 | packet->send_completion = netvsc_xmit_completion; |
345 | packet->completion.send.send_completion_ctx = packet; | 432 | packet->send_completion_ctx = packet; |
346 | packet->completion.send.send_completion_tid = (unsigned long)skb; | 433 | packet->send_completion_tid = (unsigned long)skb; |
347 | 434 | ||
348 | isvlan = packet->vlan_tci & VLAN_TAG_PRESENT; | 435 | isvlan = packet->vlan_tci & VLAN_TAG_PRESENT; |
349 | 436 | ||
@@ -358,6 +445,14 @@ static int netvsc_start_xmit(struct sk_buff *skb, struct net_device *net) | |||
358 | 445 | ||
359 | rndis_msg_size = RNDIS_MESSAGE_SIZE(struct rndis_packet); | 446 | rndis_msg_size = RNDIS_MESSAGE_SIZE(struct rndis_packet); |
360 | 447 | ||
448 | hash = skb_get_hash_raw(skb); | ||
449 | if (hash != 0 && net->real_num_tx_queues > 1) { | ||
450 | rndis_msg_size += NDIS_HASH_PPI_SIZE; | ||
451 | ppi = init_ppi_data(rndis_msg, NDIS_HASH_PPI_SIZE, | ||
452 | NBL_HASH_VALUE); | ||
453 | *(u32 *)((void *)ppi + ppi->ppi_offset) = hash; | ||
454 | } | ||
455 | |||
361 | if (isvlan) { | 456 | if (isvlan) { |
362 | struct ndis_pkt_8021q_info *vlan; | 457 | struct ndis_pkt_8021q_info *vlan; |
363 | 458 | ||
@@ -558,6 +653,9 @@ int netvsc_recv_callback(struct hv_device *device_obj, | |||
558 | __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), | 653 | __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), |
559 | packet->vlan_tci); | 654 | packet->vlan_tci); |
560 | 655 | ||
656 | skb_record_rx_queue(skb, packet->channel-> | ||
657 | offermsg.offer.sub_channel_index); | ||
658 | |||
561 | net->stats.rx_packets++; | 659 | net->stats.rx_packets++; |
562 | net->stats.rx_bytes += packet->total_data_buflen; | 660 | net->stats.rx_bytes += packet->total_data_buflen; |
563 | 661 | ||
@@ -606,7 +704,7 @@ static int netvsc_change_mtu(struct net_device *ndev, int mtu) | |||
606 | hv_set_drvdata(hdev, ndev); | 704 | hv_set_drvdata(hdev, ndev); |
607 | device_info.ring_size = ring_size; | 705 | device_info.ring_size = ring_size; |
608 | rndis_filter_device_add(hdev, &device_info); | 706 | rndis_filter_device_add(hdev, &device_info); |
609 | netif_wake_queue(ndev); | 707 | netif_tx_wake_all_queues(ndev); |
610 | 708 | ||
611 | return 0; | 709 | return 0; |
612 | } | 710 | } |
@@ -652,6 +750,7 @@ static const struct net_device_ops device_ops = { | |||
652 | .ndo_change_mtu = netvsc_change_mtu, | 750 | .ndo_change_mtu = netvsc_change_mtu, |
653 | .ndo_validate_addr = eth_validate_addr, | 751 | .ndo_validate_addr = eth_validate_addr, |
654 | .ndo_set_mac_address = netvsc_set_mac_addr, | 752 | .ndo_set_mac_address = netvsc_set_mac_addr, |
753 | .ndo_select_queue = netvsc_select_queue, | ||
655 | }; | 754 | }; |
656 | 755 | ||
657 | /* | 756 | /* |
@@ -698,9 +797,11 @@ static int netvsc_probe(struct hv_device *dev, | |||
698 | struct net_device *net = NULL; | 797 | struct net_device *net = NULL; |
699 | struct net_device_context *net_device_ctx; | 798 | struct net_device_context *net_device_ctx; |
700 | struct netvsc_device_info device_info; | 799 | struct netvsc_device_info device_info; |
800 | struct netvsc_device *nvdev; | ||
701 | int ret; | 801 | int ret; |
702 | 802 | ||
703 | net = alloc_etherdev(sizeof(struct net_device_context)); | 803 | net = alloc_etherdev_mq(sizeof(struct net_device_context), |
804 | num_online_cpus()); | ||
704 | if (!net) | 805 | if (!net) |
705 | return -ENOMEM; | 806 | return -ENOMEM; |
706 | 807 | ||
@@ -719,7 +820,7 @@ static int netvsc_probe(struct hv_device *dev, | |||
719 | net->features = NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_SG | NETIF_F_RXCSUM | | 820 | net->features = NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_SG | NETIF_F_RXCSUM | |
720 | NETIF_F_IP_CSUM | NETIF_F_TSO; | 821 | NETIF_F_IP_CSUM | NETIF_F_TSO; |
721 | 822 | ||
722 | SET_ETHTOOL_OPS(net, ðtool_ops); | 823 | net->ethtool_ops = ðtool_ops; |
723 | SET_NETDEV_DEV(net, &dev->device); | 824 | SET_NETDEV_DEV(net, &dev->device); |
724 | 825 | ||
725 | /* Notify the netvsc driver of the new device */ | 826 | /* Notify the netvsc driver of the new device */ |
@@ -733,6 +834,10 @@ static int netvsc_probe(struct hv_device *dev, | |||
733 | } | 834 | } |
734 | memcpy(net->dev_addr, device_info.mac_adr, ETH_ALEN); | 835 | memcpy(net->dev_addr, device_info.mac_adr, ETH_ALEN); |
735 | 836 | ||
837 | nvdev = hv_get_drvdata(dev); | ||
838 | netif_set_real_num_tx_queues(net, nvdev->num_chn); | ||
839 | netif_set_real_num_rx_queues(net, nvdev->num_chn); | ||
840 | |||
736 | ret = register_netdev(net); | 841 | ret = register_netdev(net); |
737 | if (ret != 0) { | 842 | if (ret != 0) { |
738 | pr_err("Unable to register netdev.\n"); | 843 | pr_err("Unable to register netdev.\n"); |