Commit 2c0133a4 authored by Arik Nemtsov's avatar Arik Nemtsov Committed by Luciano Coelho

wlcore/wl12xx/wl18xx: introduce quirk to remove TKIP header space

18xx chips do not require extra space in the TKIP header. Introduce a
new HW quirk to allow us to make this feature arch-specific. 12xx chip
will now have this quirk.
Signed-off-by: default avatarArik Nemtsov <arik@wizery.com>
Signed-off-by: default avatarLuciano Coelho <coelho@ti.com>
parent a4203c64
...@@ -625,7 +625,8 @@ static int wl12xx_identify_chip(struct wl1271 *wl) ...@@ -625,7 +625,8 @@ static int wl12xx_identify_chip(struct wl1271 *wl)
wl1271_warning("chip id 0x%x (1271 PG10) support is obsolete", wl1271_warning("chip id 0x%x (1271 PG10) support is obsolete",
wl->chip.id); wl->chip.id);
wl->quirks |= WLCORE_QUIRK_LEGACY_NVS; wl->quirks |= WLCORE_QUIRK_LEGACY_NVS |
WLCORE_QUIRK_TKIP_HEADER_SPACE;
wl->sr_fw_name = WL127X_FW_NAME_SINGLE; wl->sr_fw_name = WL127X_FW_NAME_SINGLE;
wl->mr_fw_name = WL127X_FW_NAME_MULTI; wl->mr_fw_name = WL127X_FW_NAME_MULTI;
memcpy(&wl->conf.mem, &wl12xx_default_priv_conf.mem_wl127x, memcpy(&wl->conf.mem, &wl12xx_default_priv_conf.mem_wl127x,
...@@ -640,7 +641,8 @@ static int wl12xx_identify_chip(struct wl1271 *wl) ...@@ -640,7 +641,8 @@ static int wl12xx_identify_chip(struct wl1271 *wl)
wl1271_debug(DEBUG_BOOT, "chip id 0x%x (1271 PG20)", wl1271_debug(DEBUG_BOOT, "chip id 0x%x (1271 PG20)",
wl->chip.id); wl->chip.id);
wl->quirks |= WLCORE_QUIRK_LEGACY_NVS; wl->quirks |= WLCORE_QUIRK_LEGACY_NVS |
WLCORE_QUIRK_TKIP_HEADER_SPACE;
wl->plt_fw_name = WL127X_PLT_FW_NAME; wl->plt_fw_name = WL127X_PLT_FW_NAME;
wl->sr_fw_name = WL127X_FW_NAME_SINGLE; wl->sr_fw_name = WL127X_FW_NAME_SINGLE;
wl->mr_fw_name = WL127X_FW_NAME_MULTI; wl->mr_fw_name = WL127X_FW_NAME_MULTI;
...@@ -660,7 +662,8 @@ static int wl12xx_identify_chip(struct wl1271 *wl) ...@@ -660,7 +662,8 @@ static int wl12xx_identify_chip(struct wl1271 *wl)
wl->mr_fw_name = WL128X_FW_NAME_MULTI; wl->mr_fw_name = WL128X_FW_NAME_MULTI;
/* wl128x requires TX blocksize alignment */ /* wl128x requires TX blocksize alignment */
wl->quirks |= WLCORE_QUIRK_TX_BLOCKSIZE_ALIGN; wl->quirks |= WLCORE_QUIRK_TX_BLOCKSIZE_ALIGN |
WLCORE_QUIRK_TKIP_HEADER_SPACE;
break; break;
case CHIP_ID_1283_PG10: case CHIP_ID_1283_PG10:
......
...@@ -75,7 +75,8 @@ static void wl18xx_tx_complete_packet(struct wl1271 *wl, u8 tx_stat_byte) ...@@ -75,7 +75,8 @@ static void wl18xx_tx_complete_packet(struct wl1271 *wl, u8 tx_stat_byte)
skb_pull(skb, sizeof(struct wl1271_tx_hw_descr)); skb_pull(skb, sizeof(struct wl1271_tx_hw_descr));
/* remove TKIP header space if present */ /* remove TKIP header space if present */
if (info->control.hw_key && if ((wl->quirks & WLCORE_QUIRK_TKIP_HEADER_SPACE) &&
info->control.hw_key &&
info->control.hw_key->cipher == WLAN_CIPHER_SUITE_TKIP) { info->control.hw_key->cipher == WLAN_CIPHER_SUITE_TKIP) {
int hdrlen = ieee80211_get_hdrlen_from_skb(skb); int hdrlen = ieee80211_get_hdrlen_from_skb(skb);
memmove(skb->data + WL1271_EXTRA_SPACE_TKIP, skb->data, hdrlen); memmove(skb->data + WL1271_EXTRA_SPACE_TKIP, skb->data, hdrlen);
......
...@@ -1046,7 +1046,7 @@ struct sk_buff *wl1271_cmd_build_ap_probe_req(struct wl1271 *wl, ...@@ -1046,7 +1046,7 @@ struct sk_buff *wl1271_cmd_build_ap_probe_req(struct wl1271 *wl,
int wl1271_cmd_build_arp_rsp(struct wl1271 *wl, struct wl12xx_vif *wlvif) int wl1271_cmd_build_arp_rsp(struct wl1271 *wl, struct wl12xx_vif *wlvif)
{ {
int ret, extra; int ret, extra = 0;
u16 fc; u16 fc;
struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif); struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif);
struct sk_buff *skb; struct sk_buff *skb;
...@@ -1085,7 +1085,8 @@ int wl1271_cmd_build_arp_rsp(struct wl1271 *wl, struct wl12xx_vif *wlvif) ...@@ -1085,7 +1085,8 @@ int wl1271_cmd_build_arp_rsp(struct wl1271 *wl, struct wl12xx_vif *wlvif)
/* encryption space */ /* encryption space */
switch (wlvif->encryption_type) { switch (wlvif->encryption_type) {
case KEY_TKIP: case KEY_TKIP:
extra = WL1271_EXTRA_SPACE_TKIP; if (wl->quirks & WLCORE_QUIRK_TKIP_HEADER_SPACE)
extra = WL1271_EXTRA_SPACE_TKIP;
break; break;
case KEY_AES: case KEY_AES:
extra = WL1271_EXTRA_SPACE_AES; extra = WL1271_EXTRA_SPACE_AES;
......
...@@ -4975,9 +4975,11 @@ static int wl1271_init_ieee80211(struct wl1271 *wl) ...@@ -4975,9 +4975,11 @@ static int wl1271_init_ieee80211(struct wl1271 *wl)
WL1271_CIPHER_SUITE_GEM, WL1271_CIPHER_SUITE_GEM,
}; };
/* The tx descriptor buffer and the TKIP space. */ /* The tx descriptor buffer */
wl->hw->extra_tx_headroom = WL1271_EXTRA_SPACE_TKIP + wl->hw->extra_tx_headroom = sizeof(struct wl1271_tx_hw_descr);
sizeof(struct wl1271_tx_hw_descr);
if (wl->quirks & WLCORE_QUIRK_TKIP_HEADER_SPACE)
wl->hw->extra_tx_headroom += WL1271_EXTRA_SPACE_TKIP;
/* unit us */ /* unit us */
/* FIXME: find a proper value */ /* FIXME: find a proper value */
......
...@@ -358,7 +358,8 @@ static int wl1271_prepare_tx_frame(struct wl1271 *wl, struct wl12xx_vif *wlvif, ...@@ -358,7 +358,8 @@ static int wl1271_prepare_tx_frame(struct wl1271 *wl, struct wl12xx_vif *wlvif,
/* TODO: handle dummy packets on multi-vifs */ /* TODO: handle dummy packets on multi-vifs */
is_dummy = wl12xx_is_dummy_packet(wl, skb); is_dummy = wl12xx_is_dummy_packet(wl, skb);
if (info->control.hw_key && if ((wl->quirks & WLCORE_QUIRK_TKIP_HEADER_SPACE) &&
info->control.hw_key &&
info->control.hw_key->cipher == WLAN_CIPHER_SUITE_TKIP) info->control.hw_key->cipher == WLAN_CIPHER_SUITE_TKIP)
extra = WL1271_EXTRA_SPACE_TKIP; extra = WL1271_EXTRA_SPACE_TKIP;
...@@ -852,7 +853,8 @@ static void wl1271_tx_complete_packet(struct wl1271 *wl, ...@@ -852,7 +853,8 @@ static void wl1271_tx_complete_packet(struct wl1271 *wl,
skb_pull(skb, sizeof(struct wl1271_tx_hw_descr)); skb_pull(skb, sizeof(struct wl1271_tx_hw_descr));
/* remove TKIP header space if present */ /* remove TKIP header space if present */
if (info->control.hw_key && if ((wl->quirks & WLCORE_QUIRK_TKIP_HEADER_SPACE) &&
info->control.hw_key &&
info->control.hw_key->cipher == WLAN_CIPHER_SUITE_TKIP) { info->control.hw_key->cipher == WLAN_CIPHER_SUITE_TKIP) {
int hdrlen = ieee80211_get_hdrlen_from_skb(skb); int hdrlen = ieee80211_get_hdrlen_from_skb(skb);
memmove(skb->data + WL1271_EXTRA_SPACE_TKIP, skb->data, memmove(skb->data + WL1271_EXTRA_SPACE_TKIP, skb->data,
...@@ -1001,7 +1003,8 @@ void wl12xx_tx_reset(struct wl1271 *wl, bool reset_tx_queues) ...@@ -1001,7 +1003,8 @@ void wl12xx_tx_reset(struct wl1271 *wl, bool reset_tx_queues)
*/ */
info = IEEE80211_SKB_CB(skb); info = IEEE80211_SKB_CB(skb);
skb_pull(skb, sizeof(struct wl1271_tx_hw_descr)); skb_pull(skb, sizeof(struct wl1271_tx_hw_descr));
if (info->control.hw_key && if ((wl->quirks & WLCORE_QUIRK_TKIP_HEADER_SPACE) &&
info->control.hw_key &&
info->control.hw_key->cipher == info->control.hw_key->cipher ==
WLAN_CIPHER_SUITE_TKIP) { WLAN_CIPHER_SUITE_TKIP) {
int hdrlen = ieee80211_get_hdrlen_from_skb(skb); int hdrlen = ieee80211_get_hdrlen_from_skb(skb);
......
...@@ -411,6 +411,9 @@ int wlcore_free_hw(struct wl1271 *wl); ...@@ -411,6 +411,9 @@ int wlcore_free_hw(struct wl1271 *wl);
/* Some firmwares may not support ELP */ /* Some firmwares may not support ELP */
#define WLCORE_QUIRK_NO_ELP BIT(6) #define WLCORE_QUIRK_NO_ELP BIT(6)
/* extra header space is required for TKIP */
#define WLCORE_QUIRK_TKIP_HEADER_SPACE BIT(8)
/* TODO: move to the lower drivers when all usages are abstracted */ /* TODO: move to the lower drivers when all usages are abstracted */
#define CHIP_ID_1271_PG10 (0x4030101) #define CHIP_ID_1271_PG10 (0x4030101)
#define CHIP_ID_1271_PG20 (0x4030111) #define CHIP_ID_1271_PG20 (0x4030111)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment