add the carl9170 wifi driver for ar9170 devices
authorFelix Fietkau <nbd@openwrt.org>
Thu, 7 Jan 2010 21:59:57 +0000 (21:59 +0000)
committerFelix Fietkau <nbd@openwrt.org>
Thu, 7 Jan 2010 21:59:57 +0000 (21:59 +0000)
SVN-Revision: 19066

package/carl9170/Makefile [new file with mode: 0644]
package/carl9170/patches/100-request_firmware_compat.patch [new file with mode: 0644]
package/carl9170/patches/110-endian_fixes.patch [new file with mode: 0644]

diff --git a/package/carl9170/Makefile b/package/carl9170/Makefile
new file mode 100644 (file)
index 0000000..17f3376
--- /dev/null
@@ -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 (file)
index 0000000..93fdc6f
--- /dev/null
@@ -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 (file)
index 0000000..fa2eb1a
--- /dev/null
@@ -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: