aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/hyperv/netvsc_drv.c153
1 files changed, 114 insertions, 39 deletions
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
index 9ef6be90a81c..1f7b12f9e6fb 100644
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -140,21 +140,123 @@ static void netvsc_xmit_completion(void *context)
140 dev_kfree_skb_any(skb); 140 dev_kfree_skb_any(skb);
141} 141}
142 142
143static u32 fill_pg_buf(struct page *page, u32 offset, u32 len,
144 struct hv_page_buffer *pb)
145{
146 int j = 0;
147
148 /* Deal with compund pages by ignoring unused part
149 * of the page.
150 */
151 page += (offset >> PAGE_SHIFT);
152 offset &= ~PAGE_MASK;
153
154 while (len > 0) {
155 unsigned long bytes;
156
157 bytes = PAGE_SIZE - offset;
158 if (bytes > len)
159 bytes = len;
160 pb[j].pfn = page_to_pfn(page);
161 pb[j].offset = offset;
162 pb[j].len = bytes;
163
164 offset += bytes;
165 len -= bytes;
166
167 if (offset == PAGE_SIZE && len) {
168 page++;
169 offset = 0;
170 j++;
171 }
172 }
173
174 return j + 1;
175}
176
177static void init_page_array(void *hdr, u32 len, struct sk_buff *skb,
178 struct hv_page_buffer *pb)
179{
180 u32 slots_used = 0;
181 char *data = skb->data;
182 int frags = skb_shinfo(skb)->nr_frags;
183 int i;
184
185 /* The packet is laid out thus:
186 * 1. hdr
187 * 2. skb linear data
188 * 3. skb fragment data
189 */
190 if (hdr != NULL)
191 slots_used += fill_pg_buf(virt_to_page(hdr),
192 offset_in_page(hdr),
193 len, &pb[slots_used]);
194
195 slots_used += fill_pg_buf(virt_to_page(data),
196 offset_in_page(data),
197 skb_headlen(skb), &pb[slots_used]);
198
199 for (i = 0; i < frags; i++) {
200 skb_frag_t *frag = skb_shinfo(skb)->frags + i;
201
202 slots_used += fill_pg_buf(skb_frag_page(frag),
203 frag->page_offset,
204 skb_frag_size(frag), &pb[slots_used]);
205 }
206}
207
208static int count_skb_frag_slots(struct sk_buff *skb)
209{
210 int i, frags = skb_shinfo(skb)->nr_frags;
211 int pages = 0;
212
213 for (i = 0; i < frags; i++) {
214 skb_frag_t *frag = skb_shinfo(skb)->frags + i;
215 unsigned long size = skb_frag_size(frag);
216 unsigned long offset = frag->page_offset;
217
218 /* Skip unused frames from start of page */
219 offset &= ~PAGE_MASK;
220 pages += PFN_UP(offset + size);
221 }
222 return pages;
223}
224
225static int netvsc_get_slots(struct sk_buff *skb)
226{
227 char *data = skb->data;
228 unsigned int offset = offset_in_page(data);
229 unsigned int len = skb_headlen(skb);
230 int slots;
231 int frag_slots;
232
233 slots = DIV_ROUND_UP(offset + len, PAGE_SIZE);
234 frag_slots = count_skb_frag_slots(skb);
235 return slots + frag_slots;
236}
237
143static int netvsc_start_xmit(struct sk_buff *skb, struct net_device *net) 238static int netvsc_start_xmit(struct sk_buff *skb, struct net_device *net)
144{ 239{
145 struct net_device_context *net_device_ctx = netdev_priv(net); 240 struct net_device_context *net_device_ctx = netdev_priv(net);
146 struct hv_netvsc_packet *packet; 241 struct hv_netvsc_packet *packet;
147 int ret; 242 int ret;
148 unsigned int i, num_pages, npg_data; 243 unsigned int num_data_pages;
149 244
150 /* Add multipages for skb->data and additional 2 for RNDIS */ 245 /* We will atmost need two pages to describe the rndis
151 npg_data = (((unsigned long)skb->data + skb_headlen(skb) - 1) 246 * header. We can only transmit MAX_PAGE_BUFFER_COUNT number
152 >> PAGE_SHIFT) - ((unsigned long)skb->data >> PAGE_SHIFT) + 1; 247 * of pages in a single packet.
153 num_pages = skb_shinfo(skb)->nr_frags + npg_data + 2; 248 */
249 num_data_pages = netvsc_get_slots(skb) + 2;
250 if (num_data_pages > MAX_PAGE_BUFFER_COUNT) {
251 netdev_err(net, "Packet too big: %u\n", skb->len);
252 dev_kfree_skb(skb);
253 net->stats.tx_dropped++;
254 return NETDEV_TX_OK;
255 }
154 256
155 /* Allocate a netvsc packet based on # of frags. */ 257 /* Allocate a netvsc packet based on # of frags. */
156 packet = kzalloc(sizeof(struct hv_netvsc_packet) + 258 packet = kzalloc(sizeof(struct hv_netvsc_packet) +
157 (num_pages * sizeof(struct hv_page_buffer)) + 259 (num_data_pages * sizeof(struct hv_page_buffer)) +
158 sizeof(struct rndis_message) + 260 sizeof(struct rndis_message) +
159 NDIS_VLAN_PPI_SIZE, GFP_ATOMIC); 261 NDIS_VLAN_PPI_SIZE, GFP_ATOMIC);
160 if (!packet) { 262 if (!packet) {
@@ -169,44 +271,17 @@ static int netvsc_start_xmit(struct sk_buff *skb, struct net_device *net)
169 packet->vlan_tci = skb->vlan_tci; 271 packet->vlan_tci = skb->vlan_tci;
170 272
171 packet->extension = (void *)(unsigned long)packet + 273 packet->extension = (void *)(unsigned long)packet +
172 sizeof(struct hv_netvsc_packet) + 274 sizeof(struct hv_netvsc_packet) +
173 (num_pages * sizeof(struct hv_page_buffer)); 275 (num_data_pages * sizeof(struct hv_page_buffer));
174 276
175 /* If the rndis msg goes beyond 1 page, we will add 1 later */ 277 /* If the rndis msg goes beyond 1 page, we will add 1 later */
176 packet->page_buf_cnt = num_pages - 1; 278 packet->page_buf_cnt = num_data_pages - 1;
177 279
178 /* Initialize it from the skb */ 280 /* Initialize it from the skb */
179 packet->total_data_buflen = skb->len; 281 packet->total_data_buflen = skb->len;
180 282
181 /* Start filling in the page buffers starting after RNDIS buffer. */ 283 /* Start filling in the page buffers starting after RNDIS buffer. */
182 packet->page_buf[1].pfn = virt_to_phys(skb->data) >> PAGE_SHIFT; 284 init_page_array(NULL, 0, skb, &packet->page_buf[1]);
183 packet->page_buf[1].offset
184 = (unsigned long)skb->data & (PAGE_SIZE - 1);
185 if (npg_data == 1)
186 packet->page_buf[1].len = skb_headlen(skb);
187 else
188 packet->page_buf[1].len = PAGE_SIZE
189 - packet->page_buf[1].offset;
190
191 for (i = 2; i <= npg_data; i++) {
192 packet->page_buf[i].pfn = virt_to_phys(skb->data
193 + PAGE_SIZE * (i-1)) >> PAGE_SHIFT;
194 packet->page_buf[i].offset = 0;
195 packet->page_buf[i].len = PAGE_SIZE;
196 }
197 if (npg_data > 1)
198 packet->page_buf[npg_data].len = (((unsigned long)skb->data
199 + skb_headlen(skb) - 1) & (PAGE_SIZE - 1)) + 1;
200
201 /* Additional fragments are after SKB data */
202 for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
203 const skb_frag_t *f = &skb_shinfo(skb)->frags[i];
204
205 packet->page_buf[i+npg_data+1].pfn =
206 page_to_pfn(skb_frag_page(f));
207 packet->page_buf[i+npg_data+1].offset = f->page_offset;
208 packet->page_buf[i+npg_data+1].len = skb_frag_size(f);
209 }
210 285
211 /* Set the completion routine */ 286 /* Set the completion routine */
212 packet->completion.send.send_completion = netvsc_xmit_completion; 287 packet->completion.send.send_completion = netvsc_xmit_completion;
@@ -451,8 +526,8 @@ static int netvsc_probe(struct hv_device *dev,
451 net->netdev_ops = &device_ops; 526 net->netdev_ops = &device_ops;
452 527
453 /* TODO: Add GSO and Checksum offload */ 528 /* TODO: Add GSO and Checksum offload */
454 net->hw_features = 0; 529 net->hw_features = NETIF_F_SG;
455 net->features = NETIF_F_HW_VLAN_CTAG_TX; 530 net->features = NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_SG;
456 531
457 SET_ETHTOOL_OPS(net, &ethtool_ops); 532 SET_ETHTOOL_OPS(net, &ethtool_ops);
458 SET_NETDEV_DEV(net, &dev->device); 533 SET_NETDEV_DEV(net, &dev->device);