aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLarry Finger <Larry.Finger@lwfinger.net>2011-11-17 13:14:44 -0500
committerJohn W. Linville <linville@tuxdriver.com>2011-11-21 16:20:46 -0500
commitabfabc9b48f6943dbb707fcfc2ef2a04c329e3e8 (patch)
tree608f73989a2fe7d5f5967cd6ab76701ed2f6d173
parentff6ff96b5ba5b39f7ab3d8ea0cf9ec414452ac92 (diff)
rtlwifi: rtl8192cu: Fix endianian issues
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>
-rw-r--r--drivers/net/wireless/rtlwifi/base.c6
-rw-r--r--drivers/net/wireless/rtlwifi/base.h2
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c28
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192c/fw_common.h20
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192cu/hw.c9
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192cu/trx.c2
-rw-r--r--drivers/net/wireless/rtlwifi/usb.c12
7 files changed, 43 insertions, 36 deletions
diff --git a/drivers/net/wireless/rtlwifi/base.c b/drivers/net/wireless/rtlwifi/base.c
index d4fdd2a5a739..c968458c6ecc 100644
--- a/drivers/net/wireless/rtlwifi/base.c
+++ b/drivers/net/wireless/rtlwifi/base.c
@@ -344,9 +344,9 @@ static void _rtl_init_mac80211(struct ieee80211_hw *hw)
344 if (is_valid_ether_addr(rtlefuse->dev_addr)) { 344 if (is_valid_ether_addr(rtlefuse->dev_addr)) {
345 SET_IEEE80211_PERM_ADDR(hw, rtlefuse->dev_addr); 345 SET_IEEE80211_PERM_ADDR(hw, rtlefuse->dev_addr);
346 } else { 346 } else {
347 u8 rtlmac[] = { 0x00, 0xe0, 0x4c, 0x81, 0x92, 0x00 }; 347 u8 rtlmac1[] = { 0x00, 0xe0, 0x4c, 0x81, 0x92, 0x00 };
348 get_random_bytes((rtlmac + (ETH_ALEN - 1)), 1); 348 get_random_bytes((rtlmac1 + (ETH_ALEN - 1)), 1);
349 SET_IEEE80211_PERM_ADDR(hw, rtlmac); 349 SET_IEEE80211_PERM_ADDR(hw, rtlmac1);
350 } 350 }
351 351
352} 352}
diff --git a/drivers/net/wireless/rtlwifi/base.h b/drivers/net/wireless/rtlwifi/base.h
index 4ae905983d0d..f66b5757f6b9 100644
--- a/drivers/net/wireless/rtlwifi/base.h
+++ b/drivers/net/wireless/rtlwifi/base.h
@@ -76,7 +76,7 @@ enum ap_peer {
76 SET_BITS_TO_LE_2BYTE(_hdr, 8, 1, _val) 76 SET_BITS_TO_LE_2BYTE(_hdr, 8, 1, _val)
77 77
78#define SET_80211_PS_POLL_AID(_hdr, _val) \ 78#define SET_80211_PS_POLL_AID(_hdr, _val) \
79 (*(u16 *)((u8 *)(_hdr) + 2) = le16_to_cpu(_val)) 79 (*(u16 *)((u8 *)(_hdr) + 2) = _val)
80#define SET_80211_PS_POLL_BSSID(_hdr, _val) \ 80#define SET_80211_PS_POLL_BSSID(_hdr, _val) \
81 memcpy(((u8 *)(_hdr)) + 4, (u8 *)(_val), ETH_ALEN) 81 memcpy(((u8 *)(_hdr)) + 4, (u8 *)(_val), ETH_ALEN)
82#define SET_80211_PS_POLL_TA(_hdr, _val) \ 82#define SET_80211_PS_POLL_TA(_hdr, _val) \
diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c
index ebb73a2fae91..1234e3b32fbf 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c
@@ -108,6 +108,7 @@ static void _rtl92c_fw_block_write(struct ieee80211_hw *hw,
108 u8 *bufferPtr = (u8 *) buffer; 108 u8 *bufferPtr = (u8 *) buffer;
109 u32 *pu4BytePtr = (u32 *) buffer; 109 u32 *pu4BytePtr = (u32 *) buffer;
110 u32 i, offset, blockCount, remainSize; 110 u32 i, offset, blockCount, remainSize;
111 u32 data;
111 112
112 if (rtlpriv->io.writeN_sync) { 113 if (rtlpriv->io.writeN_sync) {
113 rtl_block_fw_writeN(hw, buffer, size); 114 rtl_block_fw_writeN(hw, buffer, size);
@@ -115,20 +116,22 @@ static void _rtl92c_fw_block_write(struct ieee80211_hw *hw,
115 } 116 }
116 blockCount = size / blockSize; 117 blockCount = size / blockSize;
117 remainSize = size % blockSize; 118 remainSize = size % blockSize;
119 if (remainSize) {
120 /* the last word is < 4 bytes - pad it with zeros */
121 for (i = 0; i < 4 - remainSize; i++)
122 *(bufferPtr + size + i) = 0;
123 blockCount++;
124 }
118 125
119 for (i = 0; i < blockCount; i++) { 126 for (i = 0; i < blockCount; i++) {
120 offset = i * blockSize; 127 offset = i * blockSize;
128 /* for big-endian platforms, the firmware data need to be byte
129 * swapped as it was read as a byte string and will be written
130 * as 32-bit dwords and byte swapped when written
131 */
132 data = le32_to_cpu(*(__le32 *)(pu4BytePtr + i));
121 rtl_write_dword(rtlpriv, (FW_8192C_START_ADDRESS + offset), 133 rtl_write_dword(rtlpriv, (FW_8192C_START_ADDRESS + offset),
122 *(pu4BytePtr + i)); 134 data);
123 }
124
125 if (remainSize) {
126 offset = blockCount * blockSize;
127 bufferPtr += offset;
128 for (i = 0; i < remainSize; i++) {
129 rtl_write_byte(rtlpriv, (FW_8192C_START_ADDRESS +
130 offset + i), *(bufferPtr + i));
131 }
132 } 135 }
133} 136}
134 137
@@ -269,8 +272,9 @@ int rtl92c_download_fw(struct ieee80211_hw *hw)
269 if (IS_FW_HEADER_EXIST(pfwheader)) { 272 if (IS_FW_HEADER_EXIST(pfwheader)) {
270 RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG, 273 RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG,
271 ("Firmware Version(%d), Signature(%#x),Size(%d)\n", 274 ("Firmware Version(%d), Signature(%#x),Size(%d)\n",
272 pfwheader->version, pfwheader->signature, 275 le16_to_cpu(pfwheader->version),
273 (uint)sizeof(struct rtl92c_firmware_header))); 276 le16_to_cpu(pfwheader->signature),
277 (uint)sizeof(struct rtl92c_firmware_header)));
274 278
275 pfwdata = pfwdata + sizeof(struct rtl92c_firmware_header); 279 pfwdata = pfwdata + sizeof(struct rtl92c_firmware_header);
276 fwsize = fwsize - sizeof(struct rtl92c_firmware_header); 280 fwsize = fwsize - sizeof(struct rtl92c_firmware_header);
diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.h b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.h
index c55c0541ff15..cec5a3a1cc53 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.h
@@ -38,26 +38,26 @@
38#define FW_8192C_POLLING_TIMEOUT_COUNT 100 38#define FW_8192C_POLLING_TIMEOUT_COUNT 100
39 39
40#define IS_FW_HEADER_EXIST(_pfwhdr) \ 40#define IS_FW_HEADER_EXIST(_pfwhdr) \
41 ((_pfwhdr->signature&0xFFF0) == 0x92C0 ||\ 41 ((le16_to_cpu(_pfwhdr->signature)&0xFFF0) == 0x92C0 ||\
42 (_pfwhdr->signature&0xFFF0) == 0x88C0) 42 (le16_to_cpu(_pfwhdr->signature)&0xFFF0) == 0x88C0)
43 43
44struct rtl92c_firmware_header { 44struct rtl92c_firmware_header {
45 u16 signature; 45 __le16 signature;
46 u8 category; 46 u8 category;
47 u8 function; 47 u8 function;
48 u16 version; 48 __le16 version;
49 u8 subversion; 49 u8 subversion;
50 u8 rsvd1; 50 u8 rsvd1;
51 u8 month; 51 u8 month;
52 u8 date; 52 u8 date;
53 u8 hour; 53 u8 hour;
54 u8 minute; 54 u8 minute;
55 u16 ramcodeSize; 55 __le16 ramcodeSize;
56 u16 rsvd2; 56 __le16 rsvd2;
57 u32 svnindex; 57 __le32 svnindex;
58 u32 rsvd3; 58 __le32 rsvd3;
59 u32 rsvd4; 59 __le32 rsvd4;
60 u32 rsvd5; 60 __le32 rsvd5;
61}; 61};
62 62
63enum rtl8192c_h2c_cmd { 63enum rtl8192c_h2c_cmd {
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c
index 814c05df51e8..4ed973a3aa17 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c
@@ -498,7 +498,7 @@ static void _rtl92cu_read_adapter_info(struct ieee80211_hw *hw)
498 } 498 }
499 RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_LOUD, ("MAP\n"), 499 RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_LOUD, ("MAP\n"),
500 hwinfo, HWSET_MAX_SIZE); 500 hwinfo, HWSET_MAX_SIZE);
501 eeprom_id = *((u16 *)&hwinfo[0]); 501 eeprom_id = le16_to_cpu(*((__le16 *)&hwinfo[0]));
502 if (eeprom_id != RTL8190_EEPROM_ID) { 502 if (eeprom_id != RTL8190_EEPROM_ID) {
503 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, 503 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
504 ("EEPROM ID(%#x) is invalid!!\n", eeprom_id)); 504 ("EEPROM ID(%#x) is invalid!!\n", eeprom_id));
@@ -516,13 +516,14 @@ static void _rtl92cu_read_adapter_info(struct ieee80211_hw *hw)
516 pr_info("MAC address: %pM\n", rtlefuse->dev_addr); 516 pr_info("MAC address: %pM\n", rtlefuse->dev_addr);
517 _rtl92cu_read_txpower_info_from_hwpg(hw, 517 _rtl92cu_read_txpower_info_from_hwpg(hw,
518 rtlefuse->autoload_failflag, hwinfo); 518 rtlefuse->autoload_failflag, hwinfo);
519 rtlefuse->eeprom_vid = *(u16 *)&hwinfo[EEPROM_VID]; 519 rtlefuse->eeprom_vid = le16_to_cpu(*(__le16 *)&hwinfo[EEPROM_VID]);
520 rtlefuse->eeprom_did = *(u16 *)&hwinfo[EEPROM_DID]; 520 rtlefuse->eeprom_did = le16_to_cpu(*(__le16 *)&hwinfo[EEPROM_DID]);
521 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, 521 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
522 (" VID = 0x%02x PID = 0x%02x\n", 522 (" VID = 0x%02x PID = 0x%02x\n",
523 rtlefuse->eeprom_vid, rtlefuse->eeprom_did)); 523 rtlefuse->eeprom_vid, rtlefuse->eeprom_did));
524 rtlefuse->eeprom_channelplan = *(u8 *)&hwinfo[EEPROM_CHANNELPLAN]; 524 rtlefuse->eeprom_channelplan = *(u8 *)&hwinfo[EEPROM_CHANNELPLAN];
525 rtlefuse->eeprom_version = *(u16 *)&hwinfo[EEPROM_VERSION]; 525 rtlefuse->eeprom_version =
526 le16_to_cpu(*(__le16 *)&hwinfo[EEPROM_VERSION]);
526 rtlefuse->txpwr_fromeprom = true; 527 rtlefuse->txpwr_fromeprom = true;
527 rtlefuse->eeprom_oemid = *(u8 *)&hwinfo[EEPROM_CUSTOMER_ID]; 528 rtlefuse->eeprom_oemid = *(u8 *)&hwinfo[EEPROM_CUSTOMER_ID];
528 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, 529 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c
index bc33b147f44f..b3cc7b949992 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c
@@ -491,7 +491,7 @@ static void _rtl_tx_desc_checksum(u8 *txdesc)
491 SET_TX_DESC_TX_DESC_CHECKSUM(txdesc, 0); 491 SET_TX_DESC_TX_DESC_CHECKSUM(txdesc, 0);
492 for (index = 0; index < 16; index++) 492 for (index = 0; index < 16; index++)
493 checksum = checksum ^ (*(ptr + index)); 493 checksum = checksum ^ (*(ptr + index));
494 SET_TX_DESC_TX_DESC_CHECKSUM(txdesc, checksum); 494 SET_TX_DESC_TX_DESC_CHECKSUM(txdesc, cpu_to_le16(checksum));
495} 495}
496 496
497void rtl92cu_tx_fill_desc(struct ieee80211_hw *hw, 497void rtl92cu_tx_fill_desc(struct ieee80211_hw *hw,
diff --git a/drivers/net/wireless/rtlwifi/usb.c b/drivers/net/wireless/rtlwifi/usb.c
index a461822c05b3..79889b83287e 100644
--- a/drivers/net/wireless/rtlwifi/usb.c
+++ b/drivers/net/wireless/rtlwifi/usb.c
@@ -82,6 +82,7 @@ static int _usbctrl_vendorreq_async_write(struct usb_device *udev, u8 request,
82 dr->wValue = cpu_to_le16(value); 82 dr->wValue = cpu_to_le16(value);
83 dr->wIndex = cpu_to_le16(index); 83 dr->wIndex = cpu_to_le16(index);
84 dr->wLength = cpu_to_le16(len); 84 dr->wLength = cpu_to_le16(len);
85 /* data are already in little-endian order */
85 memcpy(buf, pdata, len); 86 memcpy(buf, pdata, len);
86 usb_fill_control_urb(urb, udev, pipe, 87 usb_fill_control_urb(urb, udev, pipe,
87 (unsigned char *)dr, buf, len, 88 (unsigned char *)dr, buf, len,
@@ -101,6 +102,7 @@ static int _usbctrl_vendorreq_sync_read(struct usb_device *udev, u8 request,
101 int status; 102 int status;
102 u8 reqtype; 103 u8 reqtype;
103 int vendorreq_times = 0; 104 int vendorreq_times = 0;
105 static int count;
104 106
105 pipe = usb_rcvctrlpipe(udev, 0); /* read_in */ 107 pipe = usb_rcvctrlpipe(udev, 0); /* read_in */
106 reqtype = REALTEK_USB_VENQT_READ; 108 reqtype = REALTEK_USB_VENQT_READ;
@@ -117,9 +119,9 @@ static int _usbctrl_vendorreq_sync_read(struct usb_device *udev, u8 request,
117 break; 119 break;
118 } 120 }
119 } 121 }
120 if (status < 0) 122 if (status < 0 && count++ < 4)
121 pr_err("reg 0x%x, usbctrl_vendorreq TimeOut! status:0x%x value=0x%x\n", 123 pr_err("reg 0x%x, usbctrl_vendorreq TimeOut! status:0x%x value=0x%x\n",
122 value, status, *(u32 *)pdata); 124 value, status, le32_to_cpu(*(u32 *)pdata));
123 return status; 125 return status;
124} 126}
125 127
@@ -139,7 +141,7 @@ static u32 _usb_read_sync(struct usb_device *udev, u32 addr, u16 len)
139 141
140 wvalue = (u16)addr; 142 wvalue = (u16)addr;
141 _usbctrl_vendorreq_sync_read(udev, request, wvalue, index, data, len); 143 _usbctrl_vendorreq_sync_read(udev, request, wvalue, index, data, len);
142 ret = *data; 144 ret = le32_to_cpu(*data);
143 kfree(data); 145 kfree(data);
144 return ret; 146 return ret;
145} 147}
@@ -171,12 +173,12 @@ static void _usb_write_async(struct usb_device *udev, u32 addr, u32 val,
171 u8 request; 173 u8 request;
172 u16 wvalue; 174 u16 wvalue;
173 u16 index; 175 u16 index;
174 u32 data; 176 __le32 data;
175 177
176 request = REALTEK_USB_VENQT_CMD_REQ; 178 request = REALTEK_USB_VENQT_CMD_REQ;
177 index = REALTEK_USB_VENQT_CMD_IDX; /* n/a */ 179 index = REALTEK_USB_VENQT_CMD_IDX; /* n/a */
178 wvalue = (u16)(addr&0x0000ffff); 180 wvalue = (u16)(addr&0x0000ffff);
179 data = val; 181 data = cpu_to_le32(val);
180 _usbctrl_vendorreq_async_write(udev, request, wvalue, index, &data, 182 _usbctrl_vendorreq_async_write(udev, request, wvalue, index, &data,
181 len); 183 len);
182} 184}