From 6995dcc3312b5f16b726fa88757b67604e26ef36 Mon Sep 17 00:00:00 2001
From: Felix Fietkau <nbd@openwrt.org>
Date: Fri, 17 Nov 2006 03:54:33 +0000
Subject: [PATCH] upgrade to broadcom wl driver version 4.80.53.0 (from wrt350n
 release)

SVN-Revision: 5546
---
 package/broadcom-wl/Makefile                  |  4 +-
 package/broadcom-wl/src/kmod/bcmutils.c       | 16 ++++
 package/broadcom-wl/src/kmod/linux_osl.c      |  7 +-
 package/broadcom-wl/src/kmod/linux_osl.h      | 12 +--
 .../linux/brcm-2.4/patches/001-bcm47xx.patch  | 82 ++++++++++++-------
 5 files changed, 82 insertions(+), 39 deletions(-)

diff --git a/package/broadcom-wl/Makefile b/package/broadcom-wl/Makefile
index 1b396428549..39bf944ae66 100644
--- a/package/broadcom-wl/Makefile
+++ b/package/broadcom-wl/Makefile
@@ -10,13 +10,13 @@ include $(TOPDIR)/rules.mk
 include $(INCLUDE_DIR)/kernel.mk
 
 PKG_NAME:=broadcom-wl
-PKG_VERSION:=4.80.17.0
+PKG_VERSION:=4.80.53.0
 PKG_RELEASE:=1
 WLC_VERSION:=0.1
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
 PKG_SOURCE_URL:=http://downloads.openwrt.org/sources
-PKG_MD5SUM:=3183ddb60e3e882b41df1776c89b614c
+PKG_MD5SUM:=62d6ca48678b8c48f90830466c1f1842
 PKG_CAT:=bzcat
 
 PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
diff --git a/package/broadcom-wl/src/kmod/bcmutils.c b/package/broadcom-wl/src/kmod/bcmutils.c
index c264ea500b7..7592f230ade 100644
--- a/package/broadcom-wl/src/kmod/bcmutils.c
+++ b/package/broadcom-wl/src/kmod/bcmutils.c
@@ -855,3 +855,19 @@ bcm_bprintf(struct bcmstrbuf *b, const char *fmt, ...)
 
 	return r;
 }
+
+uint
+bcm_bitcount(uint8 *bitmap, uint length)
+{   
+	uint bitcount = 0, i;
+	uint8 tmp;
+	for (i = 0; i < length; i++) {
+		tmp = bitmap[i];
+		while (tmp) {
+			bitcount++;
+			tmp &= (tmp - 1);
+		}
+	}
+	return bitcount;
+}
+
diff --git a/package/broadcom-wl/src/kmod/linux_osl.c b/package/broadcom-wl/src/kmod/linux_osl.c
index d702961032a..24fd77daea5 100644
--- a/package/broadcom-wl/src/kmod/linux_osl.c
+++ b/package/broadcom-wl/src/kmod/linux_osl.c
@@ -159,13 +159,18 @@ osl_pktget(osl_t *osh, uint len, bool send)
 	return ((void*) skb);
 }
 
+typedef void (*pktfree_cb_fn_t)(void *ctx, void *pkt, uint16 status);
 /* Free the driver packet. Free the tag if present */
 void
-osl_pktfree(osl_t *osh, void *p)
+osl_pktfree(osl_t *osh, void *p, bool send)
 {
 	struct sk_buff *skb, *nskb;
+	pktfree_cb_fn_t tx_fn = osh->pub.tx_fn;
 
 	skb = (struct sk_buff*) p;
+	
+	if (send && tx_fn)
+		tx_fn(osh->pub.tx_ctx, p, 0);
 
 	/* perversion: we use skb->next to chain multi-skb packets */
 	while (skb) {
diff --git a/package/broadcom-wl/src/kmod/linux_osl.h b/package/broadcom-wl/src/kmod/linux_osl.h
index f6af6124c6c..d9c5533b85e 100644
--- a/package/broadcom-wl/src/kmod/linux_osl.h
+++ b/package/broadcom-wl/src/kmod/linux_osl.h
@@ -92,7 +92,7 @@ osl_dma_free_consistent(osl_t *osh, void *va, uint size, ulong pa)
 
 /* packet primitives */
 #define	PKTGET(osh, len, send)		osl_pktget((osh), (len), (send))
-#define	PKTFREE(osh, skb, send)		osl_pktfree((osh), (skb))
+#define	PKTFREE(osh, skb, send)		osl_pktfree((osh), (skb), (send))
 #define	PKTDATA(osh, skb)		(((struct sk_buff*)(skb))->data)
 #define	PKTLEN(osh, skb)		(((struct sk_buff*)(skb))->len)
 #define PKTHEADROOM(osh, skb)		(PKTDATA(osh, skb)-(((struct sk_buff*)(skb))->head))
@@ -112,7 +112,7 @@ osl_dma_free_consistent(osl_t *osh, void *va, uint size, ulong pa)
  * Also, a packettag is zeroed out
  */
 static INLINE void *
-osl_pkt_frmnative(struct osl_pubinfo *osh, struct sk_buff *skb)
+osl_pkt_frmnative(osl_pubinfo_t*osh, struct sk_buff *skb)
 {
 	struct sk_buff *nskb;
 
@@ -126,7 +126,7 @@ osl_pkt_frmnative(struct osl_pubinfo *osh, struct sk_buff *skb)
 
 	return (void *)skb;
 }
-#define PKTFRMNATIVE(osh, skb)	osl_pkt_frmnative(((struct osl_pubinfo *)osh), \
+#define PKTFRMNATIVE(osh, skb)	osl_pkt_frmnative(((osl_pubinfo_t*)osh), \
 							(struct sk_buff*)(skb))
 
 /* Convert a driver packet to native(OS) packet
@@ -135,7 +135,7 @@ osl_pkt_frmnative(struct osl_pubinfo *osh, struct sk_buff *skb)
  * In our case, that means it should be 0
  */
 static INLINE struct sk_buff *
-osl_pkt_tonative(struct osl_pubinfo *osh, void *pkt)
+osl_pkt_tonative(osl_pubinfo_t*osh, void *pkt)
 {
 	struct sk_buff *nskb;
 
@@ -149,7 +149,7 @@ osl_pkt_tonative(struct osl_pubinfo *osh, void *pkt)
 
 	return (struct sk_buff *)pkt;
 }
-#define PKTTONATIVE(osh, pkt)		osl_pkt_tonative((struct osl_pubinfo *)(osh), (pkt))
+#define PKTTONATIVE(osh, pkt)		osl_pkt_tonative((osl_pubinfo_t*)(osh), (pkt))
 
 #define	PKTLINK(skb)			(((struct sk_buff*)(skb))->prev)
 #define	PKTSETLINK(skb, x)		(((struct sk_buff*)(skb))->prev = (struct sk_buff*)(x))
@@ -158,7 +158,7 @@ osl_pkt_tonative(struct osl_pubinfo *osh, void *pkt)
 #define PKTSHARED(skb)                  (((struct sk_buff*)(skb))->cloned)
 
 extern void *osl_pktget(osl_t *osh, uint len, bool send);
-extern void osl_pktfree(osl_t *osh, void *skb);
+extern void osl_pktfree(osl_t *osh, void *skb, bool send);
 extern void *osl_pktdup(osl_t *osh, void *skb);
 extern uint osl_pktalloced(osl_t *osh);
 
diff --git a/target/linux/brcm-2.4/patches/001-bcm47xx.patch b/target/linux/brcm-2.4/patches/001-bcm47xx.patch
index 98195f55dbd..fd3c65a8946 100644
--- a/target/linux/brcm-2.4/patches/001-bcm47xx.patch
+++ b/target/linux/brcm-2.4/patches/001-bcm47xx.patch
@@ -1,7 +1,7 @@
 diff -urN linux.old/arch/mips/bcm947xx/bcmsrom.c linux.dev/arch/mips/bcm947xx/bcmsrom.c
 --- linux.old/arch/mips/bcm947xx/bcmsrom.c	1970-01-01 01:00:00.000000000 +0100
 +++ linux.dev/arch/mips/bcm947xx/bcmsrom.c	2006-10-02 21:19:59.000000000 +0200
-@@ -0,0 +1,1212 @@
+@@ -0,0 +1,1213 @@
 +/*
 + *  Misc useful routines to access NIC SROM/OTP .
 + *
@@ -148,12 +148,12 @@ diff -urN linux.old/arch/mips/bcm947xx/bcmsrom.c linux.dev/arch/mips/bcm947xx/bc
 +
 +		nw = crc_range / 2;
 +		/* read first 64 words from srom */
-+		if (srom_read(bustype, curmap, osh, 0, nw * 2, image))
++		if (srom_read(bustype, curmap, osh, 0, crc_range, image))
 +			return 1;
 +		if (image[SROM4_SIGN] == SROM4_SIGNATURE) {
 +			crc_range = SROM4_WORDS;
 +			nw = crc_range / 2;
-+			if (srom_read(bustype, curmap, osh, 0, nw * 2, image))
++			if (srom_read(bustype, curmap, osh, 0, crc_range, image))
 +				return 1;
 +		}
 +		/* make changes */
@@ -696,18 +696,17 @@ diff -urN linux.old/arch/mips/bcm947xx/bcmsrom.c linux.dev/arch/mips/bcm947xx/bc
 +
 +	err = sprom_read_pci(osh, (void*)((int8*)curmap + PCI_BAR0_SPROM_OFFSET), 0, b,
 +	                     64, TRUE);
-+	if (err == 0) {
++	if (b[SROM4_SIGN] == SROM4_SIGNATURE) {
++		/* sromrev >= 4, read more */
++		err = sprom_read_pci(osh, (void*)((int8*)curmap + PCI_BAR0_SPROM_OFFSET), 0, b,	SROM4_WORDS, TRUE);
++		sromrev = b[SROM4_WORDS - 1] & 0xff;
++	} else if (err == 0) {
 +		/* srom is good and is rev < 4 */
 +		/* top word of sprom contains version and crc8 */
 +		sromrev = b[63] & 0xff;
 +		/* bcm4401 sroms misprogrammed */
 +		if (sromrev == 0x10)
 +			sromrev = 1;
-+	} else if (b[SROM4_SIGN] == SROM4_SIGNATURE) {
-+		/* If sromrev >= 4, read more */
-+		err = sprom_read_pci(osh, (void*)((int8*)curmap + PCI_BAR0_SPROM_OFFSET), 0, b,
-+		                     SROM4_WORDS, TRUE);
-+		sromrev = b[SROM4_WORDS - 1] & 0xff;
 +	}
 +
 +	if (err) {
@@ -817,11 +816,13 @@ diff -urN linux.old/arch/mips/bcm947xx/bcmsrom.c linux.dev/arch/mips/bcm947xx/bc
 +			vp++;
 +		}
 +		/* LED Powersave duty cycle (oncount >> 24) (offcount >> 8) */
-+		w = b[SROM4_LEDDC];
-+		w32 = ((uint32)((unsigned char)(w >> 8) & 0xff) << 24) |  /* oncount */
-+			((uint32)((unsigned char)(w & 0xff)) << 8); /* offcount */
-+		vp += sprintf(vp, "leddc=%d", w32);
-+		vp++;
++		if (w != 0xffff) {
++			w = b[SROM4_LEDDC];
++			w32 = ((uint32)((unsigned char)(w >> 8) & 0xff) << 24) |  /* oncount */
++				((uint32)((unsigned char)(w & 0xff)) << 8); /* offcount */
++			vp += sprintf(vp, "leddc=%d", w32);
++			vp++;
++		}
 +
 +		w = b[SROM4_AA];
 +		vp += sprintf(vp, "aa2g=%d", w & SROM4_AA2G_MASK);
@@ -1743,7 +1744,7 @@ diff -urN linux.old/arch/mips/bcm947xx/compressed/Makefile linux.dev/arch/mips/b
 diff -urN linux.old/arch/mips/bcm947xx/export.c linux.dev/arch/mips/bcm947xx/export.c
 --- linux.old/arch/mips/bcm947xx/export.c	1970-01-01 01:00:00.000000000 +0100
 +++ linux.dev/arch/mips/bcm947xx/export.c	2006-10-02 21:19:59.000000000 +0200
-@@ -0,0 +1,70 @@
+@@ -0,0 +1,66 @@
 +#include <linux/module.h>
 +
 +#define _export(n) \
@@ -1772,21 +1773,17 @@ diff -urN linux.old/arch/mips/bcm947xx/export.c linux.dev/arch/mips/bcm947xx/exp
 +_export(sb_coreflags)
 +_export(sb_coreflagshi)
 +_export(sb_coreidx)
-+_export(sb_coreregs)
 +_export(sb_corerev)
 +_export(sb_coreunit)
 +_export(sb_detach)
 +_export(sb_deviceremoved)
 +_export(sb_gpiosetcore)
 +_export(sb_gpiocontrol)
-+_export(sb_gpiointmask)
-+_export(sb_gpiointpolarity)
 +_export(sb_gpioled)
 +_export(sb_gpioin)
 +_export(sb_gpioout)
 +_export(sb_gpioouten)
 +_export(sb_gpiotimerval)
-+_export(sb_irq)
 +_export(sb_iscoreup)
 +_export(sb_pci_setup)
 +_export(sb_pcirev)
@@ -1794,8 +1791,8 @@ diff -urN linux.old/arch/mips/bcm947xx/export.c linux.dev/arch/mips/bcm947xx/exp
 +_export(sb_pcmciarev)
 +_export(sb_register_intr_callback)
 +_export(sb_setcore)
-+_export(sb_setcoreidx)
 +_export(sb_war16165)
++_export(sb_war32414_forceHT)
 +_export(sb_osh)
 +		
 +_export(getvar)
@@ -5315,7 +5312,7 @@ diff -urN linux.old/arch/mips/bcm947xx/include/mipsinc.h linux.dev/arch/mips/bcm
 diff -urN linux.old/arch/mips/bcm947xx/include/osl.h linux.dev/arch/mips/bcm947xx/include/osl.h
 --- linux.old/arch/mips/bcm947xx/include/osl.h	1970-01-01 01:00:00.000000000 +0100
 +++ linux.dev/arch/mips/bcm947xx/include/osl.h	2006-10-02 21:19:59.000000000 +0200
-@@ -0,0 +1,179 @@
+@@ -0,0 +1,181 @@
 +#ifndef __osl_h
 +#define __osl_h
 +
@@ -5328,13 +5325,15 @@ diff -urN linux.old/arch/mips/bcm947xx/include/osl.h linux.dev/arch/mips/bcm947x
 +#define ASSERT(n)
 +
 +/* Pkttag flag should be part of public information */
-+struct osl_pubinfo {
++typedef struct {
 +	bool pkttag;
 +	uint pktalloced; /* Number of allocated packet buffers */
-+};
++	void *tx_fn;
++	void *tx_ctx;
++} osl_pubinfo_t;
 +
 +struct osl_info {
-+	struct osl_pubinfo pub;
++	osl_pubinfo_t pub;
 +	uint magic;
 +	void *pdev;
 +	uint malloced;
@@ -7969,7 +7968,7 @@ diff -urN linux.old/arch/mips/bcm947xx/include/sbsocram.h linux.dev/arch/mips/bc
 diff -urN linux.old/arch/mips/bcm947xx/include/sbutils.h linux.dev/arch/mips/bcm947xx/include/sbutils.h
 --- linux.old/arch/mips/bcm947xx/include/sbutils.h	1970-01-01 01:00:00.000000000 +0100
 +++ linux.dev/arch/mips/bcm947xx/include/sbutils.h	2006-10-02 21:19:59.000000000 +0200
-@@ -0,0 +1,150 @@
+@@ -0,0 +1,151 @@
 +/*
 + * Misc utility routines for accessing chip-specific features
 + * of Broadcom HNBU SiliconBackplane-based chips.
@@ -8115,6 +8114,7 @@ diff -urN linux.old/arch/mips/bcm947xx/include/sbutils.h linux.dev/arch/mips/bcm
 +/* GPIO usage priorities */
 +#define GPIO_DRV_PRIORITY	0		/* Driver */
 +#define GPIO_APP_PRIORITY	1		/* Application */
++#define GPIO_HI_PRIORITY   2		/* Highest priority. Ignore GPIO reservation */
 +
 +/* device path */
 +#define SB_DEVPATH_BUFSZ	16		/* min buffer size in bytes */
@@ -11969,7 +11969,7 @@ diff -urN linux.old/arch/mips/bcm947xx/sbpci.c linux.dev/arch/mips/bcm947xx/sbpc
 diff -urN linux.old/arch/mips/bcm947xx/sbutils.c linux.dev/arch/mips/bcm947xx/sbutils.c
 --- linux.old/arch/mips/bcm947xx/sbutils.c	1970-01-01 01:00:00.000000000 +0100
 +++ linux.dev/arch/mips/bcm947xx/sbutils.c	2006-10-02 21:19:59.000000000 +0200
-@@ -0,0 +1,3081 @@
+@@ -0,0 +1,3103 @@
 +/*
 + * Misc utility routines for accessing chip-specific features
 + * of the SiliconBackplane-based Broadcom chips.
@@ -12114,6 +12114,11 @@ diff -urN linux.old/arch/mips/bcm947xx/sbutils.c linux.dev/arch/mips/bcm947xx/sb
 +#define PCIE_CONFIGREGS 	1		/* Access to config space */
 +#define PCIE_PCIEREGS 		2		/* Access to pcie registers */
 +
++/* force HT war check */
++#define FORCEHT_WAR32414(si)   \
++   ((PCIE(si)) && (((si->sb.chip == BCM4311_CHIP_ID) && (si->sb.chiprev == 1)) ||  \
++   ((si->sb.chip == BCM4321_CHIP_ID) && (si->sb.chiprev <= 3))))
++
 +/* GPIO Based LED powersave defines */
 +#define DEFAULT_GPIO_ONTIME	10		/* Default: 10% on */
 +#define DEFAULT_GPIO_OFFTIME	90		/* Default: 10% on */
@@ -12267,6 +12272,23 @@ diff -urN linux.old/arch/mips/bcm947xx/sbutils.c linux.dev/arch/mips/bcm947xx/sb
 +}
 +#endif	/* !BCMBUSTYPE || (BCMBUSTYPE == SB_BUS) */
 +
++void
++BCMINITFN(sb_war32414_forceHT)(sb_t *sbh, bool forceHT)
++{
++   sb_info_t *si;
++
++   si = SB_INFO(sbh);
++
++   
++   if (FORCEHT_WAR32414(si)) {
++       uint32 val = 0;
++       if (forceHT)
++           val = SYCC_HR;
++       sb_corereg((void*)si, SB_CC_IDX, OFFSETOF(chipcregs_t, system_clk_ctl),
++           SYCC_HR, val);
++   }
++}
++
 +static sb_info_t  *
 +BCMINITFN(sb_doattach)(sb_info_t *si, uint devid, osl_t *osh, void *regs,
 +                       uint bustype, void *sdh, char **vars, uint *varsz)
@@ -12449,17 +12471,17 @@ diff -urN linux.old/arch/mips/bcm947xx/sbutils.c linux.dev/arch/mips/bcm947xx/sb
 +			w = DEFAULT_GPIOTIMERVAL;
 +		sb_corereg(si, 0, OFFSETOF(chipcregs_t, gpiotimerval), ~0, w);
 +	}
-+	if ((si->sb.chip == BCM4311_CHIP_ID) && (si->sb.chiprev <= 1)) {
++	if (FORCEHT_WAR32414(si)) {
 +		/* set proper clk setup delays before forcing HT */
 +		sb_clkctl_init((void *)si);
-+		sb_corereg((void*)si, SB_CC_IDX, OFFSETOF(chipcregs_t, system_clk_ctl),
-+		           SYCC_HR, SYCC_HR);
++		sb_war32414_forceHT((void *)si, 1);
 +	}
 +
 +
 +	return (si);
 +}
 +
++
 +uint
 +sb_coreid(sb_t *sbh)
 +{
@@ -12768,7 +12790,7 @@ diff -urN linux.old/arch/mips/bcm947xx/sbutils.c linux.dev/arch/mips/bcm947xx/sb
 +#define read_pci_cfg_byte(a) \
 +	(BYTE_VAL(OSL_PCI_READ_CONFIG(si->osh, DWORD_ALIGN(a), 4), a) & 0xff)
 +
-+#define read_pci_cfg_write(a) \
++#define read_pci_cfg_word(a) \
 +	(WORD_VAL(OSL_PCI_READ_CONFIG(si->osh, DWORD_ALIGN(a), 4), a) & 0xffff)
 +
 +