From 6142c526347c72950a1dcc794dec1da5bd531a2b Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Thu, 7 Jan 2010 21:59:57 +0000 Subject: [PATCH] add the carl9170 wifi driver for ar9170 devices SVN-Revision: 19066 --- package/carl9170/Makefile | 62 +++++++++++++ .../patches/100-request_firmware_compat.patch | 31 +++++++ .../carl9170/patches/110-endian_fixes.patch | 93 +++++++++++++++++++ 3 files changed, 186 insertions(+) create mode 100644 package/carl9170/Makefile create mode 100644 package/carl9170/patches/100-request_firmware_compat.patch create mode 100644 package/carl9170/patches/110-endian_fixes.patch diff --git a/package/carl9170/Makefile b/package/carl9170/Makefile new file mode 100644 index 000000000000..17f3376d2872 --- /dev/null +++ b/package/carl9170/Makefile @@ -0,0 +1,62 @@ +# +# Copyright (C) 2006 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk +include $(INCLUDE_DIR)/kernel.mk + +PKG_NAME:=carl9170 +PKG_VERSION:=0.9.2.1 +PKG_RELEASE:=1 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2 +PKG_SOURCE_URL:=http://www.kernel.org/pub/linux/kernel/people/chr/carl9170/$(PKG_VERSION) +PKG_MD5SUM:=5f0057ea651343460ea4f1fb093a4bdf + +include $(INCLUDE_DIR)/package.mk + +DRV_PATH:=$(PKG_BUILD_DIR)/drivers/net/wireless/ath/carl9170 + +define KernelPackage/carl9170 + SUBMENU:=Wireless Drivers + TITLE:=Driver for Atheros AR9170 USB sticks + DEPENDS:=+kmod-mac80211 +kmod-ath + URL:=http://www.kernel.org/pub/linux/kernel/people/chr/carl9170 + FILES:=$(DRV_PATH)/carl9170usb.$(LINUX_KMOD_SUFFIX) + AUTOLOAD:=$(call AutoLoad,60,carl9170usb) +endef + +define KernelPackage/carl9170/description + This package contains a driver for Atheros AR9170 USB sticks using the free firmware +endef + +define Build/Prepare + rm -rf $(PKG_BUILD_DIR) + mkdir -p $(PKG_BUILD_DIR) + $(HOST_TAR) -C $(PKG_BUILD_DIR) -xjf $(DL_DIR)/$(PKG_SOURCE) + $(HOST_TAR) -C $(PKG_BUILD_DIR) -xf $(PKG_BUILD_DIR)/$(PKG_VERSION)/driver/carl9170-driver-$(PKG_VERSION).tar + ln -s Makefile.standalone $(DRV_PATH)/Makefile + ln -s $(STAGING_DIR)/usr/include/mac80211/ath/*.h $(PKG_BUILD_DIR)/drivers/net/wireless/ath/ + $(Build/Patch) +endef + +BUILDFLAGS= \ + $(if $(CONFIG_ATH_USER_REGD),-DATH_USER_REGD) + +define Build/Compile + $(MAKE) -C $(LINUX_DIR) \ + SUBDIRS="$(DRV_PATH)" \ + ARCH="$(LINUX_KARCH)" \ + CROSS_COMPILE="$(KERNEL_CROSS)" \ + CC="$(TARGET_CC) -I$(STAGING_DIR)/usr/include/mac80211 $(BUILDFLAGS)" +endef + +define KernelPackage/carl9170/install + $(INSTALL_DIR) $(1)/lib/firmware + $(INSTALL_DATA) $(PKG_BUILD_DIR)/$(PKG_VERSION)/firmware_build/carl9170.fw $(1)/lib/firmware/ +endef + +$(eval $(call KernelPackage,carl9170)) diff --git a/package/carl9170/patches/100-request_firmware_compat.patch b/package/carl9170/patches/100-request_firmware_compat.patch new file mode 100644 index 000000000000..93fdc6f08446 --- /dev/null +++ b/package/carl9170/patches/100-request_firmware_compat.patch @@ -0,0 +1,31 @@ +--- a/drivers/net/wireless/ath/carl9170/usb.c ++++ b/drivers/net/wireless/ath/carl9170/usb.c +@@ -983,11 +983,28 @@ err_failed: + ar9170_usb_firmware_failed(aru); + } + ++ ++ + static int ar9170_usb_request_firmware(struct ar9170_usb *aru) + { ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33)) ++ const struct firmware *fw; ++ int ret; ++ ++ ret = request_firmware(&fw, ++ ar9170_fws[aru->fw_load].files[aru->fw_files].name, ++ &aru->udev->dev); ++ ++ if (ret < 0) ++ return ret; ++ ++ ar9170_usb_firmware_step2(fw, aru); ++ return 0; ++#else + return request_firmware_nowait(THIS_MODULE, 1, + ar9170_fws[aru->fw_load].files[aru->fw_files].name, + &aru->udev->dev, GFP_KERNEL, aru, ar9170_usb_firmware_step2); ++#endif + } + + static void ar9170_usb_disconnect(struct usb_interface *intf) diff --git a/package/carl9170/patches/110-endian_fixes.patch b/package/carl9170/patches/110-endian_fixes.patch new file mode 100644 index 000000000000..fa2eb1a55f42 --- /dev/null +++ b/package/carl9170/patches/110-endian_fixes.patch @@ -0,0 +1,93 @@ +--- a/drivers/net/wireless/ath/carl9170/fw.c ++++ b/drivers/net/wireless/ath/carl9170/fw.c +@@ -39,7 +39,7 @@ const void *ar9170_fw_find_desc(struct a + for_each_hdr(iter, ar->fw_desc) { + if (!memcmp(iter->magic, descid, sizeof(*descid)) && + !CHECK_HDR_VERSION(iter, compatible_revision) && +- (iter->length >= len)) { ++ (le16_to_cpu(iter->length) >= len)) { + ret = (void *)iter; + break; + } +@@ -63,20 +63,22 @@ static int ar9170_fw_verify_descs(struct + end = (void *) head + max_len; + + while (pos < end) { +- if (((unsigned long)pos + pos->length) > (unsigned long)end) ++ int pos_length = le16_to_cpu(pos->length); ++ ++ if (((unsigned long)pos + pos_length) > (unsigned long)end) + return -EMSGSIZE; + +- if (pos->length > max_len) ++ if (pos_length > max_len) + return -EMSGSIZE; + +- if (pos->length < sizeof(struct carl9170_fw_desc_head)) ++ if (pos_length < sizeof(struct carl9170_fw_desc_head)) + return -EINVAL; + + if (!memcmp(pos->magic, last_magic, sizeof(last_magic))) + return 0; + +- pos = (void *)((unsigned long)pos + pos->length); +- max_len -= pos->length; ++ pos = (void *)((unsigned long)pos + pos_length); ++ max_len -= le16_to_cpu(pos->length); + } + + return -EINVAL; +@@ -139,7 +141,7 @@ static int ar9170_fw_check(struct ar9170 + if (SUPP(CARL9170_FW_CRC32_CHECKSUM_TAIL)) { + __le32 crc32; + +- crc32 = crc32_le(~0, data, len - 4); ++ crc32 = cpu_to_le32(crc32_le(~0, data, len - 4)); + if (!memcmp(&crc32, &data[len - 4], 4) == 0) { + dev_err(ar->pdev, "CRC32 checksum mismatch!\n"); + return -EINVAL; +--- a/drivers/net/wireless/ath/carl9170/fwhdr.h ++++ b/drivers/net/wireless/ath/carl9170/fwhdr.h +@@ -196,7 +196,7 @@ struct carl9170_fw_last_desc_v1 { + #define for_each_hdr(desc, fw_desc) \ + for (desc = fw_desc; \ + (memcmp(desc->magic, LAST_MAGIC, 4) && desc->length); \ +- desc = (void *)((unsigned long)desc + desc->length)) ++ desc = (void *)((unsigned long)desc + le16_to_cpu(desc->length))) + + #define CHECK_HDR_VERSION(head, _min_ver) \ + (((head)->cur_ver < _min_ver) || ((head)->min_ver > _min_ver)) \ +--- a/drivers/net/wireless/ath/carl9170/usb.c ++++ b/drivers/net/wireless/ath/carl9170/usb.c +@@ -640,9 +640,10 @@ static int ar9170_usb_check_firmware(str + } + + if ((usb_desc->tx_descs < 16) || +- (usb_desc->tx_frag_len < 64) || (usb_desc->tx_frag_len > 512) || +- (usb_desc->rx_max_frame_len < 1024) || +- (usb_desc->rx_max_frame_len > AR9170_MAX_RX_BUFFER_SIZE)) { ++ (le16_to_cpu(usb_desc->tx_frag_len) < 64) || ++ (le16_to_cpu(usb_desc->tx_frag_len) > 512) || ++ (le16_to_cpu(usb_desc->rx_max_frame_len) < 1024) || ++ (le16_to_cpu(usb_desc->rx_max_frame_len) > AR9170_MAX_RX_BUFFER_SIZE)) { + dev_err(&aru->udev->dev, "usb firmware has obvious signs of " + "malicious tampering.\n"); + err = -EINVAL; +@@ -650,14 +651,14 @@ static int ar9170_usb_check_firmware(str + } + + if (SUPP(CARL9170_FW_USB_MINIBOOT)) +- aru->fw_offset = usb_desc->miniboot_size; ++ aru->fw_offset = le16_to_cpu(usb_desc->miniboot_size); + else + aru->fw_offset = 0; + +- aru->rx_size = usb_desc->rx_max_frame_len; ++ aru->rx_size = le16_to_cpu(usb_desc->rx_max_frame_len); + aru->common.mem_blocks = usb_desc->tx_descs; + atomic_set(&aru->common.mem_free_blocks, usb_desc->tx_descs); +- aru->common.mem_block_size = usb_desc->tx_frag_len; ++ aru->common.mem_block_size = le16_to_cpu(usb_desc->tx_frag_len); + return 0; + + fail: -- 2.30.2