From patchwork Mon Aug 15 13:34:23 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Arend van Spriel X-Patchwork-Id: 1067352 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.4) with ESMTP id p7FDZ1wa021112 for ; Mon, 15 Aug 2011 13:35:02 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753467Ab1HONe7 (ORCPT ); Mon, 15 Aug 2011 09:34:59 -0400 Received: from mms2.broadcom.com ([216.31.210.18]:2733 "EHLO mms2.broadcom.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753465Ab1HONem (ORCPT ); Mon, 15 Aug 2011 09:34:42 -0400 Received: from [10.9.200.133] by mms2.broadcom.com with ESMTP (Broadcom SMTP Relay (Email Firewall v6.3.2)); Mon, 15 Aug 2011 06:40:03 -0700 X-Server-Uuid: D3C04415-6FA8-4F2C-93C1-920E106A2031 Received: from mail-irva-13.broadcom.com (10.11.16.103) by IRVEXCHHUB02.corp.ad.broadcom.com (10.9.200.133) with Microsoft SMTP Server id 8.2.247.2; Mon, 15 Aug 2011 06:34:14 -0700 Received: from mail-sj1-12.sj.broadcom.com (mail-sj1-12.sj.broadcom.com [10.17.16.106]) by mail-irva-13.broadcom.com (Postfix) with ESMTP id 417EB74D03; Mon, 15 Aug 2011 06:34:32 -0700 (PDT) Received: from arend-laptop (unknown [10.176.68.34]) by mail-sj1-12.sj.broadcom.com (Postfix) with ESMTP id EA0932050C; Mon, 15 Aug 2011 06:34:29 -0700 (PDT) Received: from arend by arend-laptop with local (Exim 4.74) ( envelope-from ) id 1QsxJE-0001OG-NN; Mon, 15 Aug 2011 15:34:28 +0200 From: "Arend van Spriel" To: gregkh@suse.de cc: devel@linuxdriverproject.org, linux-wireless@vger.kernel.org, "Henry Ptasinski" , "Arend van Spriel" Subject: [PATCH 11/15] staging: brcm80211: Fix handling of firmware and inits on big-endian platforms Date: Mon, 15 Aug 2011 15:34:23 +0200 Message-ID: <1313415267-5264-12-git-send-email-arend@broadcom.com> X-Mailer: git-send-email 1.7.4.1 In-Reply-To: <1313415267-5264-1-git-send-email-arend@broadcom.com> References: <1313415267-5264-1-git-send-email-arend@broadcom.com> MIME-Version: 1.0 X-WSS-ID: 6257FE393W44959236-02-01 Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter1.kernel.org [140.211.167.41]); Mon, 15 Aug 2011 13:35:02 +0000 (UTC) From: Henry Ptasinski The firmware files are encoded as little-endian. Do the appropriate swapping for big-endian platforms. Tested on Mac G5 PPC and BCM63281. Signed-off-by: Henry Ptasinski Reviewed-by: Arend van Spriel Reviewed-by: Roland Vossen Tested-by: Jonas Gorski Signed-off-by: Arend van Spriel --- drivers/staging/brcm80211/brcmsmac/mac80211_if.c | 24 ++++++++++++--------- drivers/staging/brcm80211/brcmsmac/main.c | 21 ++++++++++++------ 2 files changed, 28 insertions(+), 17 deletions(-) diff --git a/drivers/staging/brcm80211/brcmsmac/mac80211_if.c b/drivers/staging/brcm80211/brcmsmac/mac80211_if.c index e465749..7179edd 100644 --- a/drivers/staging/brcm80211/brcmsmac/mac80211_if.c +++ b/drivers/staging/brcm80211/brcmsmac/mac80211_if.c @@ -1722,15 +1722,17 @@ int brcms_ucode_init_buf(struct brcms_info *wl, void **pbuf, u32 idx) hdr = (struct firmware_hdr *)wl->fw.fw_hdr[i]->data; for (entry = 0; entry < wl->fw.hdr_num_entries[i]; entry++, hdr++) { - if (hdr->idx == idx) { - pdata = wl->fw.fw_bin[i]->data + hdr->offset; - *pbuf = kmalloc(hdr->len, GFP_ATOMIC); + u32 len = le32_to_cpu(hdr->len); + if (le32_to_cpu(hdr->idx) == idx) { + pdata = wl->fw.fw_bin[i]->data + + le32_to_cpu(hdr->offset); + *pbuf = kmalloc(len, GFP_ATOMIC); if (*pbuf == NULL) { wiphy_err(wl->wiphy, "fail to alloc %d" - " bytes\n", hdr->len); + " bytes\n", len); goto fail; } - memcpy(*pbuf, pdata, hdr->len); + memcpy(*pbuf, pdata, len); return 0; } } @@ -1755,14 +1757,15 @@ int brcms_ucode_init_uint(struct brcms_info *wl, u32 *data, u32 idx) hdr = (struct firmware_hdr *)wl->fw.fw_hdr[i]->data; for (entry = 0; entry < wl->fw.hdr_num_entries[i]; entry++, hdr++) { - if (hdr->idx == idx) { - pdata = wl->fw.fw_bin[i]->data + hdr->offset; - if (hdr->len != 4) { + if (le32_to_cpu(hdr->idx) == idx) { + pdata = wl->fw.fw_bin[i]->data + + le32_to_cpu(hdr->offset); + if (le32_to_cpu(hdr->len) != 4) { wiphy_err(wl->wiphy, "ERROR: fw hdr len\n"); return -ENOMSG; } - *data = *((u32 *) pdata); + *data = le32_to_cpu(*((u32 *) pdata)); return 0; } } @@ -1868,7 +1871,8 @@ int brcms_check_firmwares(struct brcms_info *wl) ucode_hdr = (struct firmware_hdr *)fw_hdr->data; for (entry = 0; entry < wl->fw.hdr_num_entries[i] && !rc; entry++, ucode_hdr++) { - if (ucode_hdr->offset + ucode_hdr->len > + if (le32_to_cpu(ucode_hdr->offset) + + le32_to_cpu(ucode_hdr->len) > fw->size) { wiphy_err(wl->wiphy, "%s: conflicting bin/hdr\n", diff --git a/drivers/staging/brcm80211/brcmsmac/main.c b/drivers/staging/brcm80211/brcmsmac/main.c index d6837d3..c625c25 100644 --- a/drivers/staging/brcm80211/brcmsmac/main.c +++ b/drivers/staging/brcm80211/brcmsmac/main.c @@ -2033,7 +2033,8 @@ static void brcms_ucode_write(struct brcms_hardware *wlc_hw, const u32 ucode[], W_REG(®s->objaddr, (OBJADDR_AUTO_INC | OBJADDR_UCM_SEL)); (void)R_REG(®s->objaddr); for (i = 0; i < count; i++) - W_REG(®s->objdata, ucode[i]); + W_REG(®s->objdata, le32_to_cpu(ucode[i])); + } static void brcms_c_write_inits(struct brcms_hardware *wlc_hw, @@ -2041,18 +2042,24 @@ static void brcms_c_write_inits(struct brcms_hardware *wlc_hw, { int i; u8 *base; + u8 *addr; + u16 size; + u32 value; BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); base = (u8 *)wlc_hw->regs; for (i = 0; inits[i].addr != 0xffff; i++) { - if (inits[i].size == 2) - W_REG((u16 *)(base + inits[i].addr), - inits[i].value); - else if (inits[i].size == 4) - W_REG((u32 *)(base + inits[i].addr), - inits[i].value); + size = le16_to_cpu(inits[i].size); + addr = base + le16_to_cpu(inits[i].addr); + value = le32_to_cpu(inits[i].value); + if (size == 2) + W_REG((u16 *)addr, value); + else if (size == 4) + W_REG((u32 *)addr, value); + else + break; } }