Friday, January 09, 2009

Patch for Broadcom NetXtreme II 10GbE on kernel 2.6.22

While preparing some IBM x3950 M2 machines, I got several problems. Distro used is Debian Lenny AMD64 varian, which provides kernel 2.6.22 and 2.6.26. Machine couldn't boot kernel 2.6.26, but this problem needs proper IPMI setup or local access (which I don't have now). So back to kernel 2.6.22. Next problem is that 2.6.22 doesn't support Broadcom BCM57710 10GbE. Searching IBM's support, I find potential driver v1.45.20, but they are for SLES/RHEL. Time to get dirty!

First try, too many errors:

$ make KVER=2.6.22-bnx
make -C /lib/modules/2.6.22-bnx/build M=`pwd` modules
make[1]: Entering directory `/usr/src/linux-2.6-2.6.22'
CC [M] /home/andika/src/broadcom/bnx2x-1.45.20/bnx2x_main.o
/home/andika/src/broadcom/bnx2x-1.45.20/bnx2x_main.c: In function ‘bnx2x_xmit_type’:
/home/andika/src/broadcom/bnx2x-1.45.20/bnx2x_main.c:9759: error: ‘struct sk_buff’ has no member named ‘nh’
/home/andika/src/broadcom/bnx2x-1.45.20/bnx2x_main.c:9764: error: ‘struct sk_buff’ has no member named ‘nh’
/home/andika/src/broadcom/bnx2x-1.45.20/bnx2x_main.c: In function ‘bnx2x_pkt_req_lin’:
/home/andika/src/broadcom/bnx2x-1.45.20/bnx2x_main.c:9809: error: ‘struct sk_buff’ has no member named ‘h’
/home/andika/src/broadcom/bnx2x-1.45.20/bnx2x_main.c:9810: error: ‘struct sk_buff’ has no member named ‘h’
/home/andika/src/broadcom/bnx2x-1.45.20/bnx2x_main.c: In function ‘bnx2x_start_xmit’:
/home/andika/src/broadcom/bnx2x-1.45.20/bnx2x_main.c:9899: error: ‘struct sk_buff’ has no member named ‘nh’
/home/andika/src/broadcom/bnx2x-1.45.20/bnx2x_main.c:9899: error: ‘struct sk_buff’ has no member named ‘nh’
/home/andika/src/broadcom/bnx2x-1.45.20/bnx2x_main.c:9968: error: ‘struct sk_buff’ has no member named ‘nh’
/home/andika/src/broadcom/bnx2x-1.45.20/bnx2x_main.c:9975: error: ‘struct sk_buff’ has no member named ‘h’
/home/andika/src/broadcom/bnx2x-1.45.20/bnx2x_main.c:9976: error: ‘struct sk_buff’ has no member named ‘nh’
/home/andika/src/broadcom/bnx2x-1.45.20/bnx2x_main.c:9978: error: ‘struct sk_buff’ has no member named ‘h’
/home/andika/src/broadcom/bnx2x-1.45.20/bnx2x_main.c:9992: error: ‘struct sk_buff’ has no member named ‘h’
/home/andika/src/broadcom/bnx2x-1.45.20/bnx2x_main.c:9992: error: ‘struct sk_buff’ has no member named ‘h’
/home/andika/src/broadcom/bnx2x-1.45.20/bnx2x_main.c:9992: error: ‘struct sk_buff’ has no member named ‘h’
/home/andika/src/broadcom/bnx2x-1.45.20/bnx2x_main.c:9992: error: ‘struct sk_buff’ has no member named ‘h’
/home/andika/src/broadcom/bnx2x-1.45.20/bnx2x_main.c:10000: error: ‘struct sk_buff’ has no member named ‘h’
/home/andika/src/broadcom/bnx2x-1.45.20/bnx2x_main.c:10007: error: ‘struct sk_buff’ has no member named ‘h’
/home/andika/src/broadcom/bnx2x-1.45.20/bnx2x_main.c:10008: error: ‘struct sk_buff’ has no member named ‘h’
/home/andika/src/broadcom/bnx2x-1.45.20/bnx2x_main.c:10044: error: ‘struct sk_buff’ has no member named ‘h’
/home/andika/src/broadcom/bnx2x-1.45.20/bnx2x_main.c:10044: error: ‘struct sk_buff’ has no member named ‘h’
/home/andika/src/broadcom/bnx2x-1.45.20/bnx2x_main.c:10044: error: ‘struct sk_buff’ has no member named ‘h’
/home/andika/src/broadcom/bnx2x-1.45.20/bnx2x_main.c:10044: error: ‘struct sk_buff’ has no member named ‘h’
/home/andika/src/broadcom/bnx2x-1.45.20/bnx2x_main.c:10044: error: ‘struct sk_buff’ has no member named ‘h’
/home/andika/src/broadcom/bnx2x-1.45.20/bnx2x_main.c:10044: error: ‘struct sk_buff’ has no member named ‘h’
/home/andika/src/broadcom/bnx2x-1.45.20/bnx2x_main.c:10045: error: ‘struct sk_buff’ has no member named ‘h’
/home/andika/src/broadcom/bnx2x-1.45.20/bnx2x_main.c:10045: error: ‘struct sk_buff’ has no member named ‘h’
/home/andika/src/broadcom/bnx2x-1.45.20/bnx2x_main.c:10045: error: ‘struct sk_buff’ has no member named ‘h’
/home/andika/src/broadcom/bnx2x-1.45.20/bnx2x_main.c:10045: error: ‘struct sk_buff’ has no member named ‘h’
/home/andika/src/broadcom/bnx2x-1.45.20/bnx2x_main.c:10045: error: ‘struct sk_buff’ has no member named ‘h’
/home/andika/src/broadcom/bnx2x-1.45.20/bnx2x_main.c:10045: error: ‘struct sk_buff’ has no member named ‘h’
/home/andika/src/broadcom/bnx2x-1.45.20/bnx2x_main.c:10048: error: ‘struct sk_buff’ has no member named ‘nh’
/home/andika/src/broadcom/bnx2x-1.45.20/bnx2x_main.c:10048: error: ‘struct sk_buff’ has no member named ‘nh’
/home/andika/src/broadcom/bnx2x-1.45.20/bnx2x_main.c:10048: error: ‘struct sk_buff’ has no member named ‘nh’
/home/andika/src/broadcom/bnx2x-1.45.20/bnx2x_main.c:10048: error: ‘struct sk_buff’ has no member named ‘nh’
/home/andika/src/broadcom/bnx2x-1.45.20/bnx2x_main.c:10050: error: ‘struct sk_buff’ has no member named ‘nh’
/home/andika/src/broadcom/bnx2x-1.45.20/bnx2x_main.c:10050: error: ‘struct sk_buff’ has no member named ‘nh’
/home/andika/src/broadcom/bnx2x-1.45.20/bnx2x_main.c:10050: error: ‘struct sk_buff’ has no member named ‘nh’
/home/andika/src/broadcom/bnx2x-1.45.20/bnx2x_main.c:10050: error: ‘struct sk_buff’ has no member named ‘nh’
/home/andika/src/broadcom/bnx2x-1.45.20/bnx2x_main.c:10050: error: ‘struct sk_buff’ has no member named ‘nh’
/home/andika/src/broadcom/bnx2x-1.45.20/bnx2x_main.c:10050: error: ‘struct sk_buff’ has no member named ‘nh’
/home/andika/src/broadcom/bnx2x-1.45.20/bnx2x_main.c:10050: error: ‘struct sk_buff’ has no member named ‘nh’
/home/andika/src/broadcom/bnx2x-1.45.20/bnx2x_main.c:10050: error: ‘struct sk_buff’ has no member named ‘nh’
/home/andika/src/broadcom/bnx2x-1.45.20/bnx2x_main.c:10056: error: ‘struct sk_buff’ has no member named ‘nh’
/home/andika/src/broadcom/bnx2x-1.45.20/bnx2x_main.c:10056: error: ‘struct sk_buff’ has no member named ‘nh’
/home/andika/src/broadcom/bnx2x-1.45.20/bnx2x_main.c:10056: error: ‘struct sk_buff’ has no member named ‘nh’
/home/andika/src/broadcom/bnx2x-1.45.20/bnx2x_main.c:10056: error: ‘struct sk_buff’ has no member named ‘nh’
/home/andika/src/broadcom/bnx2x-1.45.20/bnx2x_main.c:10056: error: ‘struct sk_buff’ has no member named ‘nh’
/home/andika/src/broadcom/bnx2x-1.45.20/bnx2x_main.c:10056: error: ‘struct sk_buff’ has no member named ‘nh’
/home/andika/src/broadcom/bnx2x-1.45.20/bnx2x_main.c:10056: error: ‘struct sk_buff’ has no member named ‘nh’
/home/andika/src/broadcom/bnx2x-1.45.20/bnx2x_main.c:10056: error: ‘struct sk_buff’ has no member named ‘nh’
make[2]: *** [/home/andika/src/broadcom/bnx2x-1.45.20/bnx2x_main.o] Error 1
make[1]: *** [_module_/home/andika/src/broadcom/bnx2x-1.45.20] Error 2
make[1]: Leaving directory `/usr/src/linux-2.6-2.6.22'
make: *** [bnx2x.o] Error 2
After long warming up, last effort involving GNU global (gtags, htags), creating cross references for kernel 2.6.21, 2.6.22, and 2.6.28, path to solution started to appear. The culprit is file bnx2x-compat.h which is a compatibility header created to make this driver compatible to multiple kernel versions. Line #4 originally:
#if (LINUX_VERSION_CODE < 0x020617)
changing this to
#if (LINUX_VERSION_CODE < 0x020616)
made a big difference:
make -C /lib/modules/2.6.22-bnx/build M=`pwd` modules
make[1]: Entering directory `/usr/src/linux-2.6-2.6.22'
CC [M] /home/andika/src/broadcom/bnx2x-1.45.20/bnx2x_main.o
/home/andika/src/broadcom/bnx2x-1.45.20/bnx2x_main.c: In function ‘bnx2x_interrupt’:
/home/andika/src/broadcom/bnx2x-1.45.20/bnx2x_main.c:1746: error: ‘struct bnx2x_fastpath’ has no member named ‘napi’
/home/andika/src/broadcom/bnx2x-1.45.20/bnx2x_main.c:1746: error: too many arguments to function ‘netif_rx_schedule’
/home/andika/src/broadcom/bnx2x-1.45.20/bnx2x_main.c: In function ‘bnx2x_poll’:
/home/andika/src/broadcom/bnx2x-1.45.20/bnx2x_main.c:9660: error: ‘napi’ undeclared (first use in this function)
/home/andika/src/broadcom/bnx2x-1.45.20/bnx2x_main.c:9660: error: (Each undeclared identifier is reported only once
/home/andika/src/broadcom/bnx2x-1.45.20/bnx2x_main.c:9660: error: for each function it appears in.)
/home/andika/src/broadcom/bnx2x-1.45.20/bnx2x_main.c:9660: error: too many arguments to function ‘netif_rx_complete’
make[2]: *** [/home/andika/src/broadcom/bnx2x-1.45.20/bnx2x_main.o] Error 1
make[1]: *** [_module_/home/andika/src/broadcom/bnx2x-1.45.20] Error 2
make[1]: Leaving directory `/usr/src/linux-2.6-2.6.22'
make: *** [bnx2x.o] Error 2
All error disappeared after this complete patch:
--- bnx2x_compat.h.asli 2008-08-26 16:07:35.000000000 +0700
+++ bnx2x_compat.h 2009-01-08 22:51:52.000000000 +0700
@@ -1,14 +1,16 @@
#ifndef __BNX2X_COMPAT_H__
#define __BNX2X_COMPAT_H__

-#if (LINUX_VERSION_CODE < 0x020617)
+#if (LINUX_VERSION_CODE < 0x020618)

#define skb_copy_from_linear_data_offset(skb, pad, new_skb_data, len) \
memcpy(new_skb_data, skb->data + pad, len)

#define netif_rx_schedule(dev, X) netif_rx_schedule(dev)
#define netif_rx_complete(X, Y) netif_rx_complete(dev)
+#endif

+#if (LINUX_VERSION_CODE < 0x020616)
/* skb_buff accessors */
#define ip_hdr(skb) (skb)->nh.iph
#define ipv6_hdr(skb) (skb)->nh.ipv6h
Alternatively you can get the patch here: http://research.indocisc.com/~andika/ibm/bnx2x-compat-2.6.22.patch

NIC working now, next target is making 2.6.27+ kernel boots.

No comments: