mwifiex: Use accessors routines for unaligned values
Synopsys' ARCompact architecture does not support loading from or
storing values to unaligned memory locations. We saw a series of
misaligned access exceptions on ARC. To work around this issue, we bulk
replaced le16_to_cpu and le32_to_cpu with get_unaligned_le16 and
get_unaligned_le32, respectively. We also added le16_unaligned_add_cpu
which is similar to le16_add_cpu but works with unaligned values.
Signed-off-by: Daniel Mentz <danielmentz@google.com>
Change-Id: Ia2f7fa4b4c1f255286ef44ca39f9367e890f3cfa
diff --git a/drivers/net/wireless/marvell/mwifiex/11h.c b/drivers/net/wireless/marvell/mwifiex/11h.c
index 81c60d0..66448933 100644
--- a/drivers/net/wireless/marvell/mwifiex/11h.c
+++ b/drivers/net/wireless/marvell/mwifiex/11h.c
@@ -153,7 +153,8 @@
cmd->command = cpu_to_le16(HostCmd_CMD_CHAN_REPORT_REQUEST);
cmd->size = cpu_to_le16(S_DS_GEN);
- le16_add_cpu(&cmd->size, sizeof(struct host_cmd_ds_chan_rpt_req));
+ le16_unaligned_add_cpu(&cmd->size,
+ sizeof(struct host_cmd_ds_chan_rpt_req));
cr_req->chan_desc.start_freq = cpu_to_le16(MWIFIEX_A_BAND_START_FREQ);
cr_req->chan_desc.chan_num = radar_params->chandef->chan->hw_value;
diff --git a/drivers/net/wireless/marvell/mwifiex/ie.c b/drivers/net/wireless/marvell/mwifiex/ie.c
index c488c30..922e3d6 100644
--- a/drivers/net/wireless/marvell/mwifiex/ie.c
+++ b/drivers/net/wireless/marvell/mwifiex/ie.c
@@ -131,9 +131,10 @@
sizeof(struct mwifiex_ie));
}
- le16_add_cpu(&ie_list->len,
- le16_to_cpu(priv->mgmt_ie[index].ie_length) +
- MWIFIEX_IE_HDR_SIZE);
+ le16_unaligned_add_cpu(&ie_list->len,
+ le16_to_cpu(
+ priv->mgmt_ie[index].ie_length) +
+ MWIFIEX_IE_HDR_SIZE);
input_len -= tlv_len + MWIFIEX_IE_HDR_SIZE;
}
@@ -172,21 +173,21 @@
le16_to_cpu(beacon_ie->ie_length);
memcpy(pos, beacon_ie, len);
pos += len;
- le16_add_cpu(&ap_custom_ie->len, len);
+ le16_unaligned_add_cpu(&ap_custom_ie->len, len);
}
if (pr_ie) {
len = sizeof(struct mwifiex_ie) - IEEE_MAX_IE_SIZE +
le16_to_cpu(pr_ie->ie_length);
memcpy(pos, pr_ie, len);
pos += len;
- le16_add_cpu(&ap_custom_ie->len, len);
+ le16_unaligned_add_cpu(&ap_custom_ie->len, len);
}
if (ar_ie) {
len = sizeof(struct mwifiex_ie) - IEEE_MAX_IE_SIZE +
le16_to_cpu(ar_ie->ie_length);
memcpy(pos, ar_ie, len);
pos += len;
- le16_add_cpu(&ap_custom_ie->len, len);
+ le16_unaligned_add_cpu(&ap_custom_ie->len, len);
}
ret = mwifiex_update_autoindex_ies(priv, ap_custom_ie);
@@ -242,7 +243,7 @@
vs_ie = (struct ieee_types_header *)vendor_ie;
memcpy(ie->ie_buffer + le16_to_cpu(ie->ie_length),
vs_ie, vs_ie->len + 2);
- le16_add_cpu(&ie->ie_length, vs_ie->len + 2);
+ le16_unaligned_add_cpu(&ie->ie_length, vs_ie->len + 2);
ie->mgmt_subtype_mask = cpu_to_le16(mask);
ie->ie_index = cpu_to_le16(MWIFIEX_AUTO_IDX_MASK);
}
diff --git a/drivers/net/wireless/marvell/mwifiex/main.h b/drivers/net/wireless/marvell/mwifiex/main.h
index 0207af0..4aced83 100644
--- a/drivers/net/wireless/marvell/mwifiex/main.h
+++ b/drivers/net/wireless/marvell/mwifiex/main.h
@@ -1344,7 +1344,7 @@
*/
static inline bool mwifiex_is_skb_mgmt_frame(struct sk_buff *skb)
{
- return (le32_to_cpu(*(__le32 *)skb->data) == PKT_TYPE_MGMT);
+ return (get_unaligned_le32(skb->data) == PKT_TYPE_MGMT);
}
/* This function retrieves channel closed for operation by Channel
diff --git a/drivers/net/wireless/marvell/mwifiex/scan.c b/drivers/net/wireless/marvell/mwifiex/scan.c
index bc5e52c..d919fe6 100644
--- a/drivers/net/wireless/marvell/mwifiex/scan.c
+++ b/drivers/net/wireless/marvell/mwifiex/scan.c
@@ -691,8 +691,9 @@
/* Increment the TLV header length by the size
appended */
- le16_add_cpu(&chan_tlv_out->header.len,
- sizeof(chan_tlv_out->chan_scan_param));
+ le16_unaligned_add_cpu(&chan_tlv_out->header.len,
+ sizeof(
+ chan_tlv_out->chan_scan_param));
/*
* The tlv buffer length is set to the number of bytes
@@ -1726,7 +1727,7 @@
if (*bytes_left >= sizeof(beacon_size)) {
/* Extract & convert beacon size from command buffer */
- beacon_size = le16_to_cpu(*(__le16 *)(*bss_info));
+ beacon_size = get_unaligned_le16((*bss_info));
*bytes_left -= sizeof(beacon_size);
*bss_info += sizeof(beacon_size);
}
@@ -2314,8 +2315,9 @@
temp_chan = chan_list_tlv->chan_scan_param + chan_idx;
/* Increment the TLV header length by size appended */
- le16_add_cpu(&chan_list_tlv->header.len,
- sizeof(chan_list_tlv->chan_scan_param));
+ le16_unaligned_add_cpu(&chan_list_tlv->header.len,
+ sizeof(
+ chan_list_tlv->chan_scan_param));
temp_chan->chan_number =
bgscan_cfg_in->chan_list[chan_idx].chan_number;
@@ -2352,8 +2354,8 @@
mwifiex_bgscan_create_channel_list(priv, bgscan_cfg_in,
chan_list_tlv->
chan_scan_param);
- le16_add_cpu(&chan_list_tlv->header.len,
- chan_num *
+ le16_unaligned_add_cpu(&chan_list_tlv->header.len,
+ chan_num *
sizeof(chan_list_tlv->chan_scan_param[0]));
}
@@ -2377,7 +2379,7 @@
/* Append vendor specific IE TLV */
mwifiex_cmd_append_vsie_tlv(priv, MWIFIEX_VSIE_MASK_BGSCAN, &tlv_pos);
- le16_add_cpu(&cmd->size, tlv_pos - bgscan_config->tlv);
+ le16_unaligned_add_cpu(&cmd->size, tlv_pos - bgscan_config->tlv);
return 0;
}
diff --git a/drivers/net/wireless/marvell/mwifiex/sta_cmd.c b/drivers/net/wireless/marvell/mwifiex/sta_cmd.c
index e436574..78e1061 100644
--- a/drivers/net/wireless/marvell/mwifiex/sta_cmd.c
+++ b/drivers/net/wireless/marvell/mwifiex/sta_cmd.c
@@ -126,12 +126,12 @@
if (cmd_action == HostCmd_ACT_GEN_GET) {
snmp_mib->query_type = cpu_to_le16(HostCmd_ACT_GEN_GET);
snmp_mib->buf_size = cpu_to_le16(MAX_SNMP_BUF_SIZE);
- le16_add_cpu(&cmd->size, MAX_SNMP_BUF_SIZE);
+ le16_unaligned_add_cpu(&cmd->size, MAX_SNMP_BUF_SIZE);
} else if (cmd_action == HostCmd_ACT_GEN_SET) {
snmp_mib->query_type = cpu_to_le16(HostCmd_ACT_GEN_SET);
snmp_mib->buf_size = cpu_to_le16(sizeof(u16));
*((__le16 *) (snmp_mib->value)) = cpu_to_le16(*ul_temp);
- le16_add_cpu(&cmd->size, sizeof(u16));
+ le16_unaligned_add_cpu(&cmd->size, sizeof(u16));
}
mwifiex_dbg(priv->adapter, CMD,
@@ -1323,8 +1323,9 @@
subsc_evt_cfg->bcn_l_rssi_cfg.evt_freq);
pos += sizeof(struct mwifiex_ie_types_rssi_threshold);
- le16_add_cpu(&cmd->size,
- sizeof(struct mwifiex_ie_types_rssi_threshold));
+ le16_unaligned_add_cpu(&cmd->size,
+ sizeof(
+ struct mwifiex_ie_types_rssi_threshold));
}
if (event_bitmap & BITMASK_BCN_RSSI_HIGH) {
@@ -1344,8 +1345,9 @@
subsc_evt_cfg->bcn_h_rssi_cfg.evt_freq);
pos += sizeof(struct mwifiex_ie_types_rssi_threshold);
- le16_add_cpu(&cmd->size,
- sizeof(struct mwifiex_ie_types_rssi_threshold));
+ le16_unaligned_add_cpu(&cmd->size,
+ sizeof(
+ struct mwifiex_ie_types_rssi_threshold));
}
return 0;
@@ -1634,14 +1636,15 @@
sizeof(u8) + sizeof(u8));
/* Add the rule length to the command size*/
- le16_add_cpu(&cmd->size, le16_to_cpu(rule->header.len) +
- sizeof(struct mwifiex_ie_types_header));
+ le16_unaligned_add_cpu(&cmd->size,
+ le16_to_cpu(rule->header.len) +
+ sizeof(struct mwifiex_ie_types_header));
rule = (void *)((u8 *)rule->params + length);
}
/* Add sizeof action, num_of_rules to total command length */
- le16_add_cpu(&cmd->size, sizeof(u16) + sizeof(u16));
+ le16_unaligned_add_cpu(&cmd->size, sizeof(u16) + sizeof(u16));
return 0;
}
@@ -1659,7 +1662,7 @@
cmd->command = cpu_to_le16(HostCmd_CMD_TDLS_CONFIG);
cmd->size = cpu_to_le16(S_DS_GEN);
tdls_config->tdls_action = cpu_to_le16(cmd_action);
- le16_add_cpu(&cmd->size, sizeof(tdls_config->tdls_action));
+ le16_unaligned_add_cpu(&cmd->size, sizeof(tdls_config->tdls_action));
switch (cmd_action) {
case ACT_TDLS_CS_ENABLE_CONFIG:
@@ -1686,7 +1689,7 @@
return -ENOTSUPP;
}
- le16_add_cpu(&cmd->size, len);
+ le16_unaligned_add_cpu(&cmd->size, len);
return 0;
}
@@ -1711,7 +1714,8 @@
cmd->command = cpu_to_le16(HostCmd_CMD_TDLS_OPER);
cmd->size = cpu_to_le16(S_DS_GEN);
- le16_add_cpu(&cmd->size, sizeof(struct host_cmd_ds_tdls_oper));
+ le16_unaligned_add_cpu(&cmd->size,
+ sizeof(struct host_cmd_ds_tdls_oper));
tdls_oper->reason = 0;
memcpy(tdls_oper->peer_mac, oper->peer_mac, ETH_ALEN);
@@ -1814,7 +1818,7 @@
return -ENOTSUPP;
}
- le16_add_cpu(&cmd->size, config_len);
+ le16_unaligned_add_cpu(&cmd->size, config_len);
return 0;
}
diff --git a/drivers/net/wireless/marvell/mwifiex/util.h b/drivers/net/wireless/marvell/mwifiex/util.h
index b541d66..c386992 100644
--- a/drivers/net/wireless/marvell/mwifiex/util.h
+++ b/drivers/net/wireless/marvell/mwifiex/util.h
@@ -93,4 +93,9 @@
int mwifiex_debug_info_to_buffer(struct mwifiex_private *priv, char *buf,
struct mwifiex_debug_info *info);
+static inline void le16_unaligned_add_cpu(__le16 *var, u16 val)
+{
+ put_unaligned_le16(get_unaligned_le16(var) + val, var);
+}
+
#endif /* !_MWIFIEX_UTIL_H_ */