]> git.ipfire.org Git - thirdparty/open-vm-tools.git/commitdiff
vmxnet(3) fix building with Linux kernel 3.2
authorVMware, Inc <>
Thu, 22 Dec 2011 00:22:35 +0000 (16:22 -0800)
committerMarcelo Vanzin <mvanzin@vmware.com>
Thu, 22 Dec 2011 00:22:35 +0000 (16:22 -0800)
API changes for skb->frag and multicast list
Also, downstreaming change to prohibit vlan tag adding/removing
when interace is in promiscuous mode.

Also incorporated more changes from upstream to the driver.
Some linux systems expose versions as 2.6.40 and 2.6.41 instead of
3.0.0 and 3.1.0 and so on. To make the version checking easier, this
patch introduces a macro COMPAT_LINUX_VERSION_CHECK_LT(). This macro
must be used to compare versions 3.0 and beyond only.

Signed-off-by: Marcelo Vanzin <mvanzin@vmware.com>
open-vm-tools/modules/linux/shared/compat_version.h
open-vm-tools/modules/linux/vmxnet/vmxnet.c
open-vm-tools/modules/linux/vmxnet/vmxnet_version.h

index 5eea894014b024a63c8ceab9af22476ebdce72ac..56d021cff6beb778e64cf707c34bbf4a58ea17e6 100644 (file)
 #   define KERNEL_2_5_5
 #endif
 
+/* Linux kernel 3.0 can be called 2.6.40, and 3.1 can be 2.6.41...
+ * Use COMPAT_LINUX_VERSION_CHECK_LT iff you need to compare running kernel to
+ * versions 3.0 and above.
+ *
+ */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0)
+   /* Straight forward comparison if kernel version is 3.0.0 and beyond */
+#   define COMPAT_LINUX_VERSION_CHECK_LT(a, b, c) LINUX_VERSION_CODE < KERNEL_VERSION (a, b, c)
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 40)
+   /* Use b of the check to calculate corresponding c of kernel
+    *  version to compare */
+#   define COMPAT_LINUX_VERSION_CHECK_LT(a, b, c) LINUX_VERSION_CODE < KERNEL_VERSION (2, 6, (b + 40))
+#else
+    /* This is anyways lesser than any 3.x versions */
+#   define COMPAT_LINUX_VERSION_CHECK_LT(a, b, c) 1
+#endif
 
 #endif /* __COMPAT_VERSION_H__ */
index a6f5740c5433ff7b62f219e26dd7d67125ad5a10..0f6f119cfaba4b344c25a8fc5a481dc2194f2734 100644 (file)
@@ -989,7 +989,11 @@ vmxnet_probe_device(struct pci_dev             *pdev, // IN: vmxnet PCI device
       .ndo_start_xmit = &vmxnet_start_tx,
       .ndo_stop = &vmxnet_close,
       .ndo_get_stats = &vmxnet_get_stats,
+#if COMPAT_LINUX_VERSION_CHECK_LT(3, 2, 0)
       .ndo_set_multicast_list = &vmxnet_set_multicast_list,
+#else
+      .ndo_set_rx_mode = &vmxnet_set_multicast_list,
+#endif
       .ndo_change_mtu = &vmxnet_change_mtu,
 #   ifdef VMW_HAVE_POLL_CONTROLLER
       .ndo_poll_controller = vmxnet_netpoll,
@@ -2033,21 +2037,31 @@ vmxnet_map_pkt(struct sk_buff *skb,
       offset -= skb_headlen(skb);
 
       for ( ; nextFrag < skb_shinfo(skb)->nr_frags; nextFrag++){
+         int fragSize;
          frag = &skb_shinfo(skb)->frags[nextFrag];
+#if COMPAT_LINUX_VERSION_CHECK_LT(3, 1, 0)
+        fragSize = frag->size;
+#else
+       fragSize = skb_frag_size(frag);
+#endif
 
          // skip those frags that are completely copied
-         if (offset >= frag->size){
-            offset -= frag->size;
+         if (offset >= fragSize){
+            offset -= fragSize;
          } else {
             // map the part of the frag that is not copied
             dma = pci_map_page(lp->pdev,
+#if COMPAT_LINUX_VERSION_CHECK_LT(3, 1, 0)
                                frag->page,
+#else
+                               frag->page.p,
+#endif
                                frag->page_offset + offset,
-                               frag->size - offset,
+                               fragSize - offset,
                                PCI_DMA_TODEVICE);
-            VMXNET_FILL_SG(xre->sg.sg[nextSg], dma, frag->size - offset);
+            VMXNET_FILL_SG(xre->sg.sg[nextSg], dma, fragSize - offset);
             VMXNET_LOG("vmxnet_map_tx: txRing[%u].sg[%d] -> frag[%d]+%u (%uB)\n",
-                       dd->txDriverNext, nextSg, nextFrag, offset, frag->size - offset);
+                       dd->txDriverNext, nextSg, nextFrag, offset, fragSize - offset);
             nextSg++;
             nextFrag++;
 
@@ -2058,11 +2072,22 @@ vmxnet_map_pkt(struct sk_buff *skb,
 
    // map the remaining frags, we might need to use additional tx entries
    for ( ; nextFrag < skb_shinfo(skb)->nr_frags; nextFrag++) {
+      int fragSize;
       frag = &skb_shinfo(skb)->frags[nextFrag];
+#if COMPAT_LINUX_VERSION_CHECK_LT(3, 1, 0)
+      fragSize = frag->size;
+#else
+      fragSize = skb_frag_size(frag);
+#endif
+     
       dma = pci_map_page(lp->pdev,
+#if COMPAT_LINUX_VERSION_CHECK_LT(3, 1, 0)
                          frag->page,
+#else
+                         frag->page.p,
+#endif
                          frag->page_offset,
-                         frag->size,
+                         fragSize,
                          PCI_DMA_TODEVICE);
 
       if (nextSg == VMXNET2_SG_DEFAULT_LENGTH) {
@@ -2091,9 +2116,9 @@ vmxnet_map_pkt(struct sk_buff *skb,
 
          nextSg = 0;
       }
-      VMXNET_FILL_SG(xre->sg.sg[nextSg], dma, frag->size);
+      VMXNET_FILL_SG(xre->sg.sg[nextSg], dma, fragSize);
       VMXNET_LOG("vmxnet_map_tx: txRing[%u].sg[%d] -> frag[%d] (%uB)\n",
-                 dd->txDriverNext, nextSg, nextFrag, frag->size);
+                 dd->txDriverNext, nextSg, nextFrag, fragSize);
       nextSg++;
    }
 
@@ -2548,7 +2573,7 @@ vmxnet_rx_frags(Vmxnet_Private *lp, struct sk_buff *skb)
          if (UNLIKELY(newPage == NULL)) {
             skb_shinfo(skb)->nr_frags = numFrags;
             skb->len += skb->data_len;
-            skb->truesize += skb->data_len;
+            skb->truesize += PAGE_SIZE;
 
             compat_dev_kfree_skb(skb, FREE_WRITE);
 
@@ -2558,10 +2583,16 @@ vmxnet_rx_frags(Vmxnet_Private *lp, struct sk_buff *skb)
          }
 
          pci_unmap_page(pdev, rre2->paddr, PAGE_SIZE, PCI_DMA_FROMDEVICE);
+#if COMPAT_LINUX_VERSION_CHECK_LT(3, 1, 0)
          skb_shinfo(skb)->frags[numFrags].page = lp->rxPages[dd->rxDriverNext2];
+#else
+         __skb_frag_set_page(&skb_shinfo(skb)->frags[numFrags],
+                             lp->rxPages[dd->rxDriverNext2]);
+#endif
          skb_shinfo(skb)->frags[numFrags].page_offset = 0;
          skb_shinfo(skb)->frags[numFrags].size = rre2->actualLength;
          skb->data_len += rre2->actualLength;
+         skb->truesize += PAGE_SIZE;
          numFrags++;
 
          /* refill the buffer */
@@ -2579,7 +2610,7 @@ vmxnet_rx_frags(Vmxnet_Private *lp, struct sk_buff *skb)
    VMXNET_ASSERT(numFrags > 0);
    skb_shinfo(skb)->nr_frags = numFrags;
    skb->len += skb->data_len;
-   skb->truesize += skb->data_len;
+   skb->truesize += PAGE_SIZE;
    VMXNET_LOG("vmxnet_rx: %dB from rxRing[%d](%dB)+rxRing2[%d, %d)(%dB)\n",
               skb->len, dd->rxDriverNext, skb_headlen(skb),
               firstFrag, dd->rxDriverNext2, skb->data_len);
index bb0163e2faa48579122ae3f5821855d02671ac2b..aaacd86c3caee898ac03d5f3d54e53f5122c7950 100644 (file)
@@ -25,8 +25,8 @@
 #ifndef _VMXNET_VERSION_H_
 #define _VMXNET_VERSION_H_
 
-#define VMXNET_DRIVER_VERSION          2.0.11.0
-#define VMXNET_DRIVER_VERSION_COMMAS   2,0,11,0
-#define VMXNET_DRIVER_VERSION_STRING   "2.0.11.0"
+#define VMXNET_DRIVER_VERSION          2.0.12.0
+#define VMXNET_DRIVER_VERSION_COMMAS   2,0,12,0
+#define VMXNET_DRIVER_VERSION_STRING   "2.0.12.0"
 
 #endif /* _VMXNET_VERSION_H_ */