diff --git a/broadcom-wl_v5/PKGBUILD b/broadcom-wl_v5/PKGBUILD new file mode 100644 index 0000000..9025e66 --- /dev/null +++ b/broadcom-wl_v5/PKGBUILD @@ -0,0 +1,52 @@ +# Maintainer: Armin K. + +pkgname=broadcom-wl_v5 +pkgver=5.100.82.112 +pkgrel=1 +pkgdesc="Broadcom hybrid wireless device driver for Linux" +arch=(i686 x86_64) +url="http://www.broadcom.com/support/802.11/linux_sta.php" +license=('custom') +depends=('linux-headers') +source=("http://ftp.de.debian.org/debian/pool/non-free/b/broadcom-sta/broadcom-sta_${pkgver}.orig.tar.gz" + distro.patch + fixes.patch + modprobe.d) +install=${pkgname}.install +md5sums=('3842465cf117f97445a39cf13d0e3c2f' + '5ea63d8c69e891c8fff56a25a898c3ab' + '246b2a67a5592293104615f5e2bacbb7' + '3600df7db49c759c655bc6a7789b28d4') + +if [[ ${CARCH} = "i686" ]]; then + _arch=i386 +else + _arch=amd64 +fi + +_kernmajor="$(pacman -Q linux | awk '{print $2}' | cut -d - -f1 | cut -d . -f1,2)" +_extramodules="extramodules-${_kernmajor}-ARCH" +_kernver="$(cat /usr/lib/modules/${_extramodules}/version)" + +prepare(){ + cd broadcom-sta-${pkgver}/${_arch} + + patch -Np1 -i "${srcdir}/distro.patch" + patch -Np1 -i "${srcdir}/fixes.patch" +} + +build() { + cd broadcom-sta-${pkgver}/${_arch} + + make -C /usr/lib/modules/${_kernver}/build M=`pwd` +} + +package() { + cd broadcom-sta-${pkgver}/${_arch} + + install -D -m 644 wl.ko "${pkgdir}/usr/lib/modules/${_extramodules}/wl.ko" + gzip "${pkgdir}/usr/lib/modules/${_extramodules}/wl.ko" + + install -D -m 644 lib/LICENSE.txt "${pkgdir}/usr/share/licenses/${pkgname}/LICENSE" + install -D -m 644 ${srcdir}/modprobe.d "${pkgdir}/etc/modprobe.d/broadcom-wl.conf" +} diff --git a/broadcom-wl_v5/broadcom-wl_v5-5.100.82.112-1.src.tar.gz b/broadcom-wl_v5/broadcom-wl_v5-5.100.82.112-1.src.tar.gz new file mode 100644 index 0000000..c8c573c Binary files /dev/null and b/broadcom-wl_v5/broadcom-wl_v5-5.100.82.112-1.src.tar.gz differ diff --git a/broadcom-wl_v5/broadcom-wl_v5.install b/broadcom-wl_v5/broadcom-wl_v5.install new file mode 100644 index 0000000..43f3e31 --- /dev/null +++ b/broadcom-wl_v5/broadcom-wl_v5.install @@ -0,0 +1,9 @@ +post_upgrade() { + cd lib/modules + for i in extramodules-*; do depmod $(cat "$i/version"); done + cd ../.. +} + +post_install() { + post_upgrade +} diff --git a/broadcom-wl_v5/distro.patch b/broadcom-wl_v5/distro.patch new file mode 100644 index 0000000..8a51a55 --- /dev/null +++ b/broadcom-wl_v5/distro.patch @@ -0,0 +1,46 @@ +--- a/Makefile 2011-10-22 18:56:55.000000000 +0200 ++++ b/Makefile 2013-04-22 16:38:31.388576172 +0200 +@@ -120,13 +120,20 @@ + EXTRA_CFLAGS += -I$(src)/src/wl/sys -I$(src)/src/wl/phy + #EXTRA_CFLAGS += -DBCMDBG_ASSERT + ++ifeq ($(KVER),) ++ KVER = $(shell uname -r) ++endif ++ ++KDIR = /lib/modules/$(KVER)/build ++PWD = $(shell pwd) ++ + EXTRA_LDFLAGS := $(src)/lib/wlc_hybrid.o_shipped + + all: +- KBUILD_NOPEDANTIC=1 make -C /lib/modules/`uname -r`/build M=`pwd` ++ KBUILD_NOPEDANTIC=1 make -C $(KDIR) M=$(PWD) + + clean: +- KBUILD_NOPEDANTIC=1 make -C /lib/modules/`uname -r`/build M=`pwd` clean ++ KBUILD_NOPEDANTIC=1 make -C $(KDIR) M=$(PWD) clean + + install: +- install -D -m 755 wl.ko /lib/modules/`uname -r`/kernel/drivers/net/wireless/wl.ko ++ install -D -m 755 wl.ko /lib/modules/$(KVER)/kernel/drivers/net/wireless/wl.ko +--- a/src/wl/sys/wl_linux.c 2011-10-22 18:56:55.000000000 +0200 ++++ b/src/wl/sys/wl_linux.c 2013-04-22 16:38:24.891526375 +0200 +@@ -185,6 +185,8 @@ + static void wl_report_radio_state(wl_info_t *wl); + #endif + ++MODULE_LICENSE("MIXED/Proprietary"); ++ + static struct pci_device_id wl_id_table[] = { + { PCI_VENDOR_ID_BROADCOM, 0x4311, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, + { PCI_VENDOR_ID_BROADCOM, 0x4312, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, +@@ -256,7 +258,7 @@ + #define quote_str(s) to_str(s) + + #ifndef BRCM_WLAN_IFNAME +-#define BRCM_WLAN_IFNAME eth%d ++#define BRCM_WLAN_IFNAME wlan%d + #endif + + static char name[IFNAMSIZ] = quote_str(BRCM_WLAN_IFNAME); diff --git a/broadcom-wl_v5/fixes.patch b/broadcom-wl_v5/fixes.patch new file mode 100644 index 0000000..add47d2 --- /dev/null +++ b/broadcom-wl_v5/fixes.patch @@ -0,0 +1,400 @@ +--- a/Makefile 2013-07-04 13:06:00.717790365 +0200 ++++ b/Makefile 2013-07-04 13:15:20.607786877 +0200 +@@ -16,7 +16,7 @@ + ifneq ($(KERNELRELEASE),) + + LINUXVER_GOODFOR_CFG80211:=$(strip $(shell \ +- if [ "$(VERSION)" -ge "2" -a "$(PATCHLEVEL)" -ge "6" -a "$(SUBLEVEL)" -ge "32" ]; then \ ++ if [ "$(VERSION)" -ge "3" -o "$(VERSION)" -ge "2" -a "$(PATCHLEVEL)" -ge "6" -a "$(SUBLEVEL)" -ge "32" ]; then \ + echo TRUE; \ + else \ + echo FALSE; \ +@@ -24,7 +24,7 @@ + )) + + LINUXVER_WEXT_ONLY:=$(strip $(shell \ +- if [ "$(VERSION)" -ge "2" -a "$(PATCHLEVEL)" -ge "6" -a "$(SUBLEVEL)" -ge "17" ]; then \ ++ if [ "$(VERSION)" -ge "3" -o "$(VERSION)" -ge "2" -a "$(PATCHLEVEL)" -ge "6" -a "$(SUBLEVEL)" -ge "17" ]; then \ + echo FALSE; \ + else \ + echo TRUE; \ +--- a/src/include/bcmutils.h 2011-10-22 18:55:54.000000000 +0200 ++++ b/src/include/bcmutils.h 2013-07-04 13:15:20.607786877 +0200 +@@ -555,7 +555,11 @@ + extern void prhex(const char *msg, uchar *buf, uint len); + + extern bcm_tlv_t *BCMROMFN(bcm_next_tlv)(bcm_tlv_t *elt, int *buflen); ++#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0) + extern bcm_tlv_t *BCMROMFN(bcm_parse_tlvs)(void *buf, int buflen, uint key); ++#else ++extern bcm_tlv_t *BCMROMFN(bcm_parse_tlvs)(const void *buf, int buflen, uint key); ++#endif + extern bcm_tlv_t *BCMROMFN(bcm_parse_ordered_tlvs)(void *buf, int buflen, uint key); + + extern const char *bcmerrorstr(int bcmerror); +--- a/src/wl/sys/wl_cfg80211.c 2011-10-22 18:55:54.000000000 +0200 ++++ b/src/wl/sys/wl_cfg80211.c 2013-07-04 13:15:20.614453543 +0200 +@@ -42,8 +42,12 @@ + enum nl80211_iftype type, u32 *flags, struct vif_params *params); + static s32 __wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev, + struct cfg80211_scan_request *request, struct cfg80211_ssid *this_ssid); ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0) ++static s32 wl_cfg80211_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request); ++#else + static s32 wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev, + struct cfg80211_scan_request *request); ++#endif + static s32 wl_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed); + static s32 wl_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev, + struct cfg80211_ibss_params *params); +@@ -56,7 +60,11 @@ + struct cfg80211_connect_params *sme); + static s32 wl_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev, u16 reason_code); + +-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36) ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0) ++static int wl_cfg80211_set_tx_power(struct wiphy *wiphy, ++ struct wireless_dev *wdev, ++ enum nl80211_tx_power_setting type, int dbm); ++#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36) + static s32 wl_cfg80211_set_tx_power(struct wiphy *wiphy, + enum nl80211_tx_power_setting type, s32 dbm); + #else +@@ -64,7 +72,12 @@ + enum tx_power_setting type, s32 dbm); + #endif + ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0) ++static int wl_cfg80211_get_tx_power(struct wiphy *wiphy, ++ struct wireless_dev *wdev, int *dbm); ++#else + static s32 wl_cfg80211_get_tx_power(struct wiphy *wiphy, s32 *dbm); ++#endif + + #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38) + static s32 wl_cfg80211_config_default_key(struct wiphy *wiphy, +@@ -570,10 +583,18 @@ + } + + static s32 ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0) ++wl_cfg80211_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request) ++#else + wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev, + struct cfg80211_scan_request *request) ++#endif + { + s32 err = 0; ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0) ++ struct wl_priv *wl = wiphy_to_wl(wiphy); ++ struct net_device *ndev = wl_to_ndev(wl); ++#endif + + CHECK_SYS_UP(); + err = __wl_cfg80211_scan(wiphy, ndev, request, NULL); +@@ -742,7 +763,11 @@ + else + memset(&join_params.params.bssid, 0, ETHER_ADDR_LEN); + +- wl_ch_to_chanspec(params->channel, &join_params, &join_params_size); ++#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0) ++ wl_ch_to_chanspec(params->channel, &join_params, &join_params_size); ++#else ++ wl_ch_to_chanspec(params->chandef.chan, &join_params, &join_params_size); ++#endif + + err = wl_dev_ioctl(dev, WLC_SET_SSID, &join_params, join_params_size); + if (err) { +@@ -1099,7 +1124,12 @@ + return err; + } + +-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36) ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0) ++static int ++wl_cfg80211_set_tx_power(struct wiphy *wiphy, ++ struct wireless_dev *wdev, ++ enum nl80211_tx_power_setting type, int dbm) ++#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36) + static s32 + wl_cfg80211_set_tx_power(struct wiphy *wiphy, enum nl80211_tx_power_setting type, s32 dbm) + #else +@@ -1155,16 +1185,29 @@ + } + wl->conf->tx_power = dbm; + ++#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0) + return err; ++#else ++ return (int) err; ++#endif + } + ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0) ++static int wl_cfg80211_get_tx_power(struct wiphy *wiphy, ++ struct wireless_dev *wdev, int *dbm) ++#else + static s32 wl_cfg80211_get_tx_power(struct wiphy *wiphy, s32 *dbm) ++#endif + { + struct wl_priv *wl = wiphy_to_wl(wiphy); + struct net_device *ndev = wl_to_ndev(wl); + s32 txpwrdbm; + u8 result; ++#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0) + s32 err = 0; ++#else ++ int err = 0; ++#endif + + CHECK_SYS_UP(); + err = wl_dev_intvar_get(ndev, "qtxpower", &txpwrdbm); +@@ -1173,8 +1216,11 @@ + return err; + } + result = (u8) (txpwrdbm & ~WL_TXPWR_OVERRIDE); ++#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0) + *dbm = (s32) bcm_qdbm_to_mw(result); +- ++#else ++ *dbm = (int) bcm_qdbm_to_mw(result); ++#endif + return err; + } + +@@ -1466,7 +1512,10 @@ + scb_val.val = 0; + err = wl_dev_ioctl(dev, WLC_GET_RSSI, &scb_val, sizeof(scb_val_t)); + if (err) { +- WL_ERR(("Could not get rssi (%d)\n", err)); ++ if (err != -EINVAL) { ++ // Don't fill syslog with EINVAL error ++ WL_ERR(("Could not get rssi (%d)\n", err)); ++ } + return err; + } + rssi = dtoh32(scb_val.val); +@@ -1811,7 +1860,7 @@ + notif_bss_info->frame_len = offsetof(struct ieee80211_mgmt, u.beacon.variable) + + wl_get_ielen(wl); + freq = ieee80211_channel_to_frequency(notif_bss_info->channel +-#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39) ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39) + ,(notif_bss_info->channel <= CH_MAX_2G_CHANNEL) ? IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ + #endif + ); +@@ -2042,9 +2091,14 @@ + struct bcm_tlv *tim; + u16 beacon_interval; + s32 dtim_period; +- size_t ie_len; +- u8 *ie; + s32 err = 0; ++ size_t ie_len; ++#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0) ++ u8 *ie; ++#else ++ const u8 *ie; ++ const struct cfg80211_bss_ies *ies; ++#endif + + ssid = &wl->profile->ssid; + bss = cfg80211_get_bss(wl_to_wiphy(wl), NULL, (s8 *)&wl->bssid, +@@ -2074,10 +2128,25 @@ + beacon_interval = cpu_to_le16(bi->beacon_period); + } else { + WL_DBG(("Found the AP in the list - BSSID %pM\n", bss->bssid)); +- ie = bss->information_elements; +- ie_len = bss->len_information_elements; ++#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0) ++ ie = bss->information_elements; ++ ie_len = bss->len_information_elements; ++#else ++ ies = (const struct cfg80211_bss_ies*)rcu_dereference(bss->ies); ++ if (!ies) { ++ /* This should never happen */ ++ err = -EIO; ++ goto update_bss_info_out; ++ } ++ ie = ies->data; ++ ie_len = (size_t)(ies->len); ++#endif + beacon_interval = bss->beacon_interval; ++#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 9, 0) + cfg80211_put_bss(bss); ++#else ++ cfg80211_put_bss(wl_to_wiphy(wl), bss); ++#endif + } + + tim = bcm_parse_tlvs(ie, ie_len, WLAN_EID_TIM); +--- a/src/wl/sys/wl_iw.h 2011-10-22 18:55:54.000000000 +0200 ++++ b/src/wl/sys/wl_iw.h 2013-07-04 13:15:20.617786877 +0200 +@@ -16,6 +16,7 @@ + #define _wl_iw_h_ + + #include ++#include + + #include + #include +--- a/src/wl/sys/wl_linux.c 2013-07-04 13:06:00.721123699 +0200 ++++ b/src/wl/sys/wl_linux.c 2013-07-04 13:23:17.847783903 +0200 +@@ -40,7 +40,9 @@ + #include + #define WLC_MAXBSSCFG 1 + ++#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 4, 0) + #include ++#endif + #include + #include + #include +@@ -387,7 +389,11 @@ + #endif + .ndo_get_stats = wl_get_stats, + .ndo_set_mac_address = wl_set_mac_address, ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0) ++ .ndo_set_rx_mode = wl_set_multicast_list, ++#else + .ndo_set_multicast_list = wl_set_multicast_list, ++#endif + .ndo_do_ioctl = wl_ioctl + }; + +@@ -845,7 +851,11 @@ + pci_set_drvdata(pdev, NULL); + } + ++#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0) + static struct pci_driver wl_pci_driver = { ++#else ++static struct pci_driver wl_pci_driver __refdata = { ++#endif + name: "wl", + probe: wl_pci_probe, + suspend: wl_suspend, +@@ -1581,11 +1591,7 @@ + } + + WL_LOCK(wl); +- if (!capable(CAP_NET_ADMIN)) { +- bcmerror = BCME_EPERM; +- } else { +- bcmerror = wlc_ioctl(wl->wlc, ioc.cmd, buf, ioc.len, wlif->wlcif); +- } ++ bcmerror = wlc_ioctl(wl->wlc, ioc.cmd, buf, ioc.len, wlif->wlcif); + WL_UNLOCK(wl); + + done1: +@@ -2962,7 +2968,7 @@ + void + wl_tkip_printstats(wl_info_t *wl, bool group_key) + { +-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 14) ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 14) && LINUX_VERSION_CODE < KERNEL_VERSION(3, 10, 0) + char debug_buf[512]; + int idx; + if (wl->tkipmodops) { +@@ -3121,6 +3127,7 @@ + return 0; + } + ++#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 10, 0) + static int + wl_proc_read(char *buffer, char **start, off_t offset, int length, int *eof, void *data) + { +@@ -3175,18 +3182,89 @@ + return length; + } + ++#else ++ ++static int ++wl_proc_read(struct seq_file *seq, void *offset) ++{ ++ wl_info_t * wl = (wl_info_t *)seq->private; ++ int bcmerror, to_user; ++ ++ WL_LOCK(wl); ++ bcmerror = wlc_ioctl(wl->wlc, WLC_GET_MONITOR, &to_user, sizeof(int), NULL); ++ WL_UNLOCK(wl); ++ ++ seq_printf(seq, "%d\n", to_user); ++ return bcmerror; ++} ++ ++static ssize_t wl_proc_write(struct file *file, const char __user *buff, ++ size_t length, loff_t *ppos) ++{ ++ struct seq_file *seq = file->private_data; ++ wl_info_t * wl = (wl_info_t *)seq->private; ++ int bcmerror, from_user = 0; ++ ++ if (length != 1) { ++ WL_ERROR(("%s: Invalid data length\n", __FUNCTION__)); ++ return -EIO; ++ } ++ ++ if (copy_from_user(&from_user, buff, 1)) { ++ WL_ERROR(("%s: copy from user failed\n", __FUNCTION__)); ++ return -EFAULT; ++ } ++ ++ if (from_user >= 0x30) ++ from_user -= 0x30; ++ ++ WL_LOCK(wl); ++ bcmerror = wlc_ioctl(wl->wlc, WLC_SET_MONITOR, &from_user, sizeof(int), NULL); ++ WL_UNLOCK(wl); ++ ++ if (bcmerror < 0) { ++ WL_ERROR(("%s: SET_MONITOR failed with %d\n", __FUNCTION__, bcmerror)); ++ return -EIO; ++ } ++ *ppos += length; ++ return length; ++} ++ ++static int wl_proc_open(struct inode *inode, struct file *file) ++{ ++ return single_open(file, wl_proc_read, PDE_DATA(inode)); ++} ++ ++static const struct file_operations wl_proc_fops = { ++ .owner = THIS_MODULE, ++ .open = wl_proc_open, ++ .read = seq_read, ++ .write = wl_proc_write, ++ .llseek = seq_lseek, ++ .release = single_release, ++}; ++#endif ++ + static int + wl_reg_proc_entry(wl_info_t *wl) + { + char tmp[32]; + sprintf(tmp, "%s%d", HYBRID_PROC, wl->pub->unit); +- if ((wl->proc_entry = create_proc_entry(tmp, 0644, NULL)) == NULL) { ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 10, 0) ++ wl->proc_entry = create_proc_entry(tmp, 0644, NULL); ++ if (wl->proc_entry) { ++ wl->proc_entry->read_proc = wl_proc_read; ++ wl->proc_entry->write_proc = wl_proc_write; ++ wl->proc_entry->data = wl; ++ } ++#else ++ wl->proc_entry = proc_create_data(tmp, 0644, NULL, &wl_proc_fops, wl); ++#endif ++ if (!wl->proc_entry) { + WL_ERROR(("%s: create_proc_entry %s failed\n", __FUNCTION__, tmp)); + ASSERT(0); + return -1; + } +- wl->proc_entry->read_proc = wl_proc_read; +- wl->proc_entry->write_proc = wl_proc_write; +- wl->proc_entry->data = wl; + return 0; + } diff --git a/broadcom-wl_v5/modprobe.d b/broadcom-wl_v5/modprobe.d new file mode 100644 index 0000000..f09d4c1 --- /dev/null +++ b/broadcom-wl_v5/modprobe.d @@ -0,0 +1,5 @@ +blacklist b43 +blacklist ssb +blacklist bcma +blacklist brcmsmac +blacklist brcmfmac