Skip to content

Commit

Permalink
rtlwifi: rtl8192cu: Fix endianian issues
Browse files Browse the repository at this point in the history
Driver rtlwifi fails on a big-endian host.

These changes have been tested on a Mac PowerBook G4, which has
a PPC processor.

Although this patch touches some of the code that will affect endian
issues on PCI hardware through drivers rtl8192ce, rtl8192se, and
rtl8192de, these have not been tested due to lack of suitable hardware.

Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
  • Loading branch information
Larry Finger authored and John W. Linville committed Nov 21, 2011
1 parent ff6ff96 commit abfabc9
Show file tree
Hide file tree
Showing 7 changed files with 43 additions and 36 deletions.
6 changes: 3 additions & 3 deletions drivers/net/wireless/rtlwifi/base.c
Original file line number Diff line number Diff line change
Expand Up @@ -344,9 +344,9 @@ static void _rtl_init_mac80211(struct ieee80211_hw *hw)
if (is_valid_ether_addr(rtlefuse->dev_addr)) {
SET_IEEE80211_PERM_ADDR(hw, rtlefuse->dev_addr);
} else {
u8 rtlmac[] = { 0x00, 0xe0, 0x4c, 0x81, 0x92, 0x00 };
get_random_bytes((rtlmac + (ETH_ALEN - 1)), 1);
SET_IEEE80211_PERM_ADDR(hw, rtlmac);
u8 rtlmac1[] = { 0x00, 0xe0, 0x4c, 0x81, 0x92, 0x00 };
get_random_bytes((rtlmac1 + (ETH_ALEN - 1)), 1);
SET_IEEE80211_PERM_ADDR(hw, rtlmac1);
}

}
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/wireless/rtlwifi/base.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ enum ap_peer {
SET_BITS_TO_LE_2BYTE(_hdr, 8, 1, _val)

#define SET_80211_PS_POLL_AID(_hdr, _val) \
(*(u16 *)((u8 *)(_hdr) + 2) = le16_to_cpu(_val))
(*(u16 *)((u8 *)(_hdr) + 2) = _val)
#define SET_80211_PS_POLL_BSSID(_hdr, _val) \
memcpy(((u8 *)(_hdr)) + 4, (u8 *)(_val), ETH_ALEN)
#define SET_80211_PS_POLL_TA(_hdr, _val) \
Expand Down
28 changes: 16 additions & 12 deletions drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -108,27 +108,30 @@ static void _rtl92c_fw_block_write(struct ieee80211_hw *hw,
u8 *bufferPtr = (u8 *) buffer;
u32 *pu4BytePtr = (u32 *) buffer;
u32 i, offset, blockCount, remainSize;
u32 data;

if (rtlpriv->io.writeN_sync) {
rtl_block_fw_writeN(hw, buffer, size);
return;
}
blockCount = size / blockSize;
remainSize = size % blockSize;
if (remainSize) {
/* the last word is < 4 bytes - pad it with zeros */
for (i = 0; i < 4 - remainSize; i++)
*(bufferPtr + size + i) = 0;
blockCount++;
}

for (i = 0; i < blockCount; i++) {
offset = i * blockSize;
/* for big-endian platforms, the firmware data need to be byte
* swapped as it was read as a byte string and will be written
* as 32-bit dwords and byte swapped when written
*/
data = le32_to_cpu(*(__le32 *)(pu4BytePtr + i));
rtl_write_dword(rtlpriv, (FW_8192C_START_ADDRESS + offset),
*(pu4BytePtr + i));
}

if (remainSize) {
offset = blockCount * blockSize;
bufferPtr += offset;
for (i = 0; i < remainSize; i++) {
rtl_write_byte(rtlpriv, (FW_8192C_START_ADDRESS +
offset + i), *(bufferPtr + i));
}
data);
}
}

Expand Down Expand Up @@ -269,8 +272,9 @@ int rtl92c_download_fw(struct ieee80211_hw *hw)
if (IS_FW_HEADER_EXIST(pfwheader)) {
RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG,
("Firmware Version(%d), Signature(%#x),Size(%d)\n",
pfwheader->version, pfwheader->signature,
(uint)sizeof(struct rtl92c_firmware_header)));
le16_to_cpu(pfwheader->version),
le16_to_cpu(pfwheader->signature),
(uint)sizeof(struct rtl92c_firmware_header)));

pfwdata = pfwdata + sizeof(struct rtl92c_firmware_header);
fwsize = fwsize - sizeof(struct rtl92c_firmware_header);
Expand Down
20 changes: 10 additions & 10 deletions drivers/net/wireless/rtlwifi/rtl8192c/fw_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,26 +38,26 @@
#define FW_8192C_POLLING_TIMEOUT_COUNT 100

#define IS_FW_HEADER_EXIST(_pfwhdr) \
((_pfwhdr->signature&0xFFF0) == 0x92C0 ||\
(_pfwhdr->signature&0xFFF0) == 0x88C0)
((le16_to_cpu(_pfwhdr->signature)&0xFFF0) == 0x92C0 ||\
(le16_to_cpu(_pfwhdr->signature)&0xFFF0) == 0x88C0)

struct rtl92c_firmware_header {
u16 signature;
__le16 signature;
u8 category;
u8 function;
u16 version;
__le16 version;
u8 subversion;
u8 rsvd1;
u8 month;
u8 date;
u8 hour;
u8 minute;
u16 ramcodeSize;
u16 rsvd2;
u32 svnindex;
u32 rsvd3;
u32 rsvd4;
u32 rsvd5;
__le16 ramcodeSize;
__le16 rsvd2;
__le32 svnindex;
__le32 rsvd3;
__le32 rsvd4;
__le32 rsvd5;
};

enum rtl8192c_h2c_cmd {
Expand Down
9 changes: 5 additions & 4 deletions drivers/net/wireless/rtlwifi/rtl8192cu/hw.c
Original file line number Diff line number Diff line change
Expand Up @@ -498,7 +498,7 @@ static void _rtl92cu_read_adapter_info(struct ieee80211_hw *hw)
}
RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_LOUD, ("MAP\n"),
hwinfo, HWSET_MAX_SIZE);
eeprom_id = *((u16 *)&hwinfo[0]);
eeprom_id = le16_to_cpu(*((__le16 *)&hwinfo[0]));
if (eeprom_id != RTL8190_EEPROM_ID) {
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
("EEPROM ID(%#x) is invalid!!\n", eeprom_id));
Expand All @@ -516,13 +516,14 @@ static void _rtl92cu_read_adapter_info(struct ieee80211_hw *hw)
pr_info("MAC address: %pM\n", rtlefuse->dev_addr);
_rtl92cu_read_txpower_info_from_hwpg(hw,
rtlefuse->autoload_failflag, hwinfo);
rtlefuse->eeprom_vid = *(u16 *)&hwinfo[EEPROM_VID];
rtlefuse->eeprom_did = *(u16 *)&hwinfo[EEPROM_DID];
rtlefuse->eeprom_vid = le16_to_cpu(*(__le16 *)&hwinfo[EEPROM_VID]);
rtlefuse->eeprom_did = le16_to_cpu(*(__le16 *)&hwinfo[EEPROM_DID]);
RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
(" VID = 0x%02x PID = 0x%02x\n",
rtlefuse->eeprom_vid, rtlefuse->eeprom_did));
rtlefuse->eeprom_channelplan = *(u8 *)&hwinfo[EEPROM_CHANNELPLAN];
rtlefuse->eeprom_version = *(u16 *)&hwinfo[EEPROM_VERSION];
rtlefuse->eeprom_version =
le16_to_cpu(*(__le16 *)&hwinfo[EEPROM_VERSION]);
rtlefuse->txpwr_fromeprom = true;
rtlefuse->eeprom_oemid = *(u8 *)&hwinfo[EEPROM_CUSTOMER_ID];
RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/wireless/rtlwifi/rtl8192cu/trx.c
Original file line number Diff line number Diff line change
Expand Up @@ -491,7 +491,7 @@ static void _rtl_tx_desc_checksum(u8 *txdesc)
SET_TX_DESC_TX_DESC_CHECKSUM(txdesc, 0);
for (index = 0; index < 16; index++)
checksum = checksum ^ (*(ptr + index));
SET_TX_DESC_TX_DESC_CHECKSUM(txdesc, checksum);
SET_TX_DESC_TX_DESC_CHECKSUM(txdesc, cpu_to_le16(checksum));
}

void rtl92cu_tx_fill_desc(struct ieee80211_hw *hw,
Expand Down
12 changes: 7 additions & 5 deletions drivers/net/wireless/rtlwifi/usb.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ static int _usbctrl_vendorreq_async_write(struct usb_device *udev, u8 request,
dr->wValue = cpu_to_le16(value);
dr->wIndex = cpu_to_le16(index);
dr->wLength = cpu_to_le16(len);
/* data are already in little-endian order */
memcpy(buf, pdata, len);
usb_fill_control_urb(urb, udev, pipe,
(unsigned char *)dr, buf, len,
Expand All @@ -101,6 +102,7 @@ static int _usbctrl_vendorreq_sync_read(struct usb_device *udev, u8 request,
int status;
u8 reqtype;
int vendorreq_times = 0;
static int count;

pipe = usb_rcvctrlpipe(udev, 0); /* read_in */
reqtype = REALTEK_USB_VENQT_READ;
Expand All @@ -117,9 +119,9 @@ static int _usbctrl_vendorreq_sync_read(struct usb_device *udev, u8 request,
break;
}
}
if (status < 0)
if (status < 0 && count++ < 4)
pr_err("reg 0x%x, usbctrl_vendorreq TimeOut! status:0x%x value=0x%x\n",
value, status, *(u32 *)pdata);
value, status, le32_to_cpu(*(u32 *)pdata));
return status;
}

Expand All @@ -139,7 +141,7 @@ static u32 _usb_read_sync(struct usb_device *udev, u32 addr, u16 len)

wvalue = (u16)addr;
_usbctrl_vendorreq_sync_read(udev, request, wvalue, index, data, len);
ret = *data;
ret = le32_to_cpu(*data);
kfree(data);
return ret;
}
Expand Down Expand Up @@ -171,12 +173,12 @@ static void _usb_write_async(struct usb_device *udev, u32 addr, u32 val,
u8 request;
u16 wvalue;
u16 index;
u32 data;
__le32 data;

request = REALTEK_USB_VENQT_CMD_REQ;
index = REALTEK_USB_VENQT_CMD_IDX; /* n/a */
wvalue = (u16)(addr&0x0000ffff);
data = val;
data = cpu_to_le32(val);
_usbctrl_vendorreq_async_write(udev, request, wvalue, index, &data,
len);
}
Expand Down

0 comments on commit abfabc9

Please sign in to comment.