qcacmn: [CRYPTO] Support word-aligned 802.11 headers

Some chipsets using Direct-attach architecture need the 802.11 header
padded to a 32-bit boundary for 4-address and QoS frames.

Change-Id: Id29c114b2246cbb1230c9b22f4d04c070069d569
CRs-Fixed: 2233228
This commit is contained in:
Padma Raghunathan
2018-04-27 15:01:25 +05:30
committato da nshrivas
parent 9492161c23
commit 6ac6143190
2 ha cambiato i file con 65 aggiunte e 9 eliminazioni

Vedi File

@@ -482,10 +482,10 @@ static inline bool wlan_crypto_is_data_protected(const void *data)
*
* Return: header size of the frame
*/
static inline int ieee80211_hdrsize(const void *data)
static inline uint8_t ieee80211_hdrsize(const void *data)
{
const struct ieee80211_hdr *hdr = (const struct ieee80211_hdr *)data;
int16_t size = sizeof(struct ieee80211_hdr);
uint8_t size = sizeof(struct ieee80211_hdr);
if ((hdr->frame_control[1] & WLAN_FC1_DIR_MASK)
== (WLAN_FC1_DSTODS)) {
@@ -502,6 +502,28 @@ static inline int ieee80211_hdrsize(const void *data)
return size;
}
/**
* ieee80211_hdrspace - calculate frame header size with padding
* @pdev: pdev
* @data: frame header
*
* This function returns the space occupied by the 802.11 header
* and any padding required by the driver. This works for a management
* or data frame.
*
* Return: header size of the frame with padding
*/
static inline uint8_t
ieee80211_hdrspace(struct wlan_objmgr_pdev *pdev, const void *data)
{
uint8_t size = ieee80211_hdrsize(data);
if (wlan_pdev_nif_feat_cap_get(pdev, WLAN_PDEV_F_DATAPAD))
size = roundup(size, sizeof(u_int32_t));
return size;
}
/**
* wlan_get_tid - get tid of the frame
* @data: frame

Vedi File

@@ -1051,7 +1051,10 @@ QDF_STATUS wlan_crypto_encap(struct wlan_objmgr_vdev *vdev,
struct wlan_objmgr_peer *peer;
uint8_t bssid_mac[WLAN_ALEN];
uint8_t pdev_id;
uint8_t hdrlen;
enum QDF_OPMODE opmode;
opmode = wlan_vdev_mlme_get_opmode(vdev);
wlan_vdev_obj_lock(vdev);
qdf_mem_copy(bssid_mac, wlan_vdev_mlme_get_macaddr(vdev), WLAN_ALEN);
psoc = wlan_vdev_get_psoc(vdev);
@@ -1117,10 +1120,16 @@ QDF_STATUS wlan_crypto_encap(struct wlan_objmgr_vdev *vdev,
if (!key)
return QDF_STATUS_E_INVAL;
}
if (opmode == QDF_MONITOR_MODE)
hdrlen = ieee80211_hdrsize((uint8_t *)qdf_nbuf_data(wbuf));
else
hdrlen = ieee80211_hdrspace(wlan_vdev_get_pdev(vdev),
(uint8_t *)qdf_nbuf_data(wbuf));
/* if tkip, is counter measures enabled, then drop the frame */
cipher_table = (struct wlan_crypto_cipher *)key->cipher_table;
status = cipher_table->encap(key, wbuf, encapdone,
ieee80211_hdrsize((uint8_t *)qdf_nbuf_data(wbuf)));
hdrlen);
return status;
}
@@ -1151,7 +1160,10 @@ QDF_STATUS wlan_crypto_decap(struct wlan_objmgr_vdev *vdev,
uint8_t bssid_mac[WLAN_ALEN];
uint8_t keyid;
uint8_t pdev_id;
uint8_t hdrlen;
enum QDF_OPMODE opmode;
opmode = wlan_vdev_mlme_get_opmode(vdev);
wlan_vdev_obj_lock(vdev);
qdf_mem_copy(bssid_mac, wlan_vdev_mlme_get_macaddr(vdev), WLAN_ALEN);
psoc = wlan_vdev_get_psoc(vdev);
@@ -1162,6 +1174,12 @@ QDF_STATUS wlan_crypto_decap(struct wlan_objmgr_vdev *vdev,
}
wlan_vdev_obj_unlock(vdev);
if (opmode == QDF_MONITOR_MODE)
hdrlen = ieee80211_hdrsize((uint8_t *)qdf_nbuf_data(wbuf));
else
hdrlen = ieee80211_hdrspace(wlan_vdev_get_pdev(vdev),
(uint8_t *)qdf_nbuf_data(wbuf));
keyid = wlan_crypto_get_keyid((uint8_t *)qdf_nbuf_data(wbuf));
if (keyid >= WLAN_CRYPTO_MAXKEYIDX)
@@ -1223,8 +1241,7 @@ QDF_STATUS wlan_crypto_decap(struct wlan_objmgr_vdev *vdev,
}
/* if tkip, is counter measures enabled, then drop the frame */
cipher_table = (struct wlan_crypto_cipher *)key->cipher_table;
status = cipher_table->decap(key, wbuf, tid,
ieee80211_hdrsize((uint8_t *)qdf_nbuf_data(wbuf)));
status = cipher_table->decap(key, wbuf, tid, hdrlen);
return status;
}
@@ -1251,6 +1268,10 @@ QDF_STATUS wlan_crypto_enmic(struct wlan_objmgr_vdev *vdev,
struct wlan_crypto_cipher *cipher_table;
struct wlan_objmgr_psoc *psoc;
uint8_t bssid_mac[WLAN_ALEN];
uint8_t hdrlen;
enum QDF_OPMODE opmode;
opmode = wlan_vdev_mlme_get_opmode(vdev);
wlan_vdev_obj_lock(vdev);
@@ -1305,10 +1326,15 @@ QDF_STATUS wlan_crypto_enmic(struct wlan_objmgr_vdev *vdev,
if (!key)
return QDF_STATUS_E_INVAL;
}
if (opmode == QDF_MONITOR_MODE)
hdrlen = ieee80211_hdrsize((uint8_t *)qdf_nbuf_data(wbuf));
else
hdrlen = ieee80211_hdrspace(wlan_vdev_get_pdev(vdev),
(uint8_t *)qdf_nbuf_data(wbuf));
/* if tkip, is counter measures enabled, then drop the frame */
cipher_table = (struct wlan_crypto_cipher *)key->cipher_table;
status = cipher_table->enmic(key, wbuf, encapdone,
ieee80211_hdrsize((uint8_t *)qdf_nbuf_data(wbuf)));
status = cipher_table->enmic(key, wbuf, encapdone, hdrlen);
return status;
}
@@ -1336,7 +1362,16 @@ QDF_STATUS wlan_crypto_demic(struct wlan_objmgr_vdev *vdev,
struct wlan_crypto_cipher *cipher_table;
struct wlan_objmgr_psoc *psoc;
uint8_t bssid_mac[WLAN_ALEN];
uint8_t hdrlen;
enum QDF_OPMODE opmode;
opmode = wlan_vdev_mlme_get_opmode(vdev);
if (opmode == QDF_MONITOR_MODE)
hdrlen = ieee80211_hdrsize((uint8_t *)qdf_nbuf_data(wbuf));
else
hdrlen = ieee80211_hdrspace(wlan_vdev_get_pdev(vdev),
(uint8_t *)qdf_nbuf_data(wbuf));
wlan_vdev_obj_lock(vdev);
qdf_mem_copy(bssid_mac, wlan_vdev_mlme_get_macaddr(vdev), WLAN_ALEN);
@@ -1391,8 +1426,7 @@ QDF_STATUS wlan_crypto_demic(struct wlan_objmgr_vdev *vdev,
}
/* if tkip, is counter measures enabled, then drop the frame */
cipher_table = (struct wlan_crypto_cipher *)key->cipher_table;
status = cipher_table->demic(key, wbuf, tid,
ieee80211_hdrsize((uint8_t *)qdf_nbuf_data(wbuf)));
status = cipher_table->demic(key, wbuf, tid, hdrlen);
return status;
}