|
@@ -51,6 +51,17 @@ const struct dp_rx_defrag_cipher dp_f_wep = {
|
|
0,
|
|
0,
|
|
};
|
|
};
|
|
|
|
|
|
|
|
+/*
|
|
|
|
+ * The header and mic length are same for both
|
|
|
|
+ * GCMP-128 and GCMP-256.
|
|
|
|
+ */
|
|
|
|
+const struct dp_rx_defrag_cipher dp_f_gcmp = {
|
|
|
|
+ "AES-GCMP",
|
|
|
|
+ WLAN_IEEE80211_GCMP_HEADERLEN,
|
|
|
|
+ WLAN_IEEE80211_GCMP_MICLEN,
|
|
|
|
+ WLAN_IEEE80211_GCMP_MICLEN,
|
|
|
|
+};
|
|
|
|
+
|
|
/*
|
|
/*
|
|
* dp_rx_defrag_frames_free(): Free fragment chain
|
|
* dp_rx_defrag_frames_free(): Free fragment chain
|
|
* @frames: Fragment chain
|
|
* @frames: Fragment chain
|
|
@@ -1414,6 +1425,36 @@ static QDF_STATUS dp_rx_defrag_reo_reinject(struct dp_peer *peer,
|
|
}
|
|
}
|
|
#endif
|
|
#endif
|
|
|
|
|
|
|
|
+/*
|
|
|
|
+ * dp_rx_defrag_gcmp_demic(): Remove MIC information from GCMP fragment
|
|
|
|
+ * @nbuf: Pointer to the fragment buffer
|
|
|
|
+ * @hdrlen: 802.11 header length
|
|
|
|
+ *
|
|
|
|
+ * Remove MIC information from GCMP fragment
|
|
|
|
+ *
|
|
|
|
+ * Returns: QDF_STATUS
|
|
|
|
+ */
|
|
|
|
+static QDF_STATUS dp_rx_defrag_gcmp_demic(qdf_nbuf_t nbuf, uint16_t hdrlen)
|
|
|
|
+{
|
|
|
|
+ uint8_t *ivp, *orig_hdr;
|
|
|
|
+ int rx_desc_len = SIZE_OF_DATA_RX_TLV;
|
|
|
|
+
|
|
|
|
+ /* start of the 802.11 header */
|
|
|
|
+ orig_hdr = (uint8_t *)(qdf_nbuf_data(nbuf) + rx_desc_len);
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * GCMP header is located after 802.11 header and EXTIV
|
|
|
|
+ * field should always be set to 1 for GCMP protocol.
|
|
|
|
+ */
|
|
|
|
+ ivp = orig_hdr + hdrlen;
|
|
|
|
+ if (!(ivp[IEEE80211_WEP_IVLEN] & IEEE80211_WEP_EXTIV))
|
|
|
|
+ return QDF_STATUS_E_DEFRAG_ERROR;
|
|
|
|
+
|
|
|
|
+ qdf_nbuf_trim_tail(nbuf, dp_f_gcmp.ic_trailer);
|
|
|
|
+
|
|
|
|
+ return QDF_STATUS_SUCCESS;
|
|
|
|
+}
|
|
|
|
+
|
|
/*
|
|
/*
|
|
* dp_rx_defrag(): Defragment the fragment chain
|
|
* dp_rx_defrag(): Defragment the fragment chain
|
|
* @peer: Pointer to the peer
|
|
* @peer: Pointer to the peer
|
|
@@ -1523,6 +1564,22 @@ static QDF_STATUS dp_rx_defrag(struct dp_peer *peer, unsigned tid,
|
|
/* If success, increment header to be stripped later */
|
|
/* If success, increment header to be stripped later */
|
|
hdr_space += dp_f_wep.ic_header;
|
|
hdr_space += dp_f_wep.ic_header;
|
|
break;
|
|
break;
|
|
|
|
+ case cdp_sec_type_aes_gcmp:
|
|
|
|
+ case cdp_sec_type_aes_gcmp_256:
|
|
|
|
+ while (cur) {
|
|
|
|
+ tmp_next = qdf_nbuf_next(cur);
|
|
|
|
+ if (dp_rx_defrag_gcmp_demic(cur, hdr_space)) {
|
|
|
|
+ QDF_TRACE(QDF_MODULE_ID_TXRX,
|
|
|
|
+ QDF_TRACE_LEVEL_ERROR,
|
|
|
|
+ "dp_rx_defrag: GCMP demic failed");
|
|
|
|
+
|
|
|
|
+ return QDF_STATUS_E_DEFRAG_ERROR;
|
|
|
|
+ }
|
|
|
|
+ cur = tmp_next;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ hdr_space += dp_f_gcmp.ic_header;
|
|
|
|
+ break;
|
|
default:
|
|
default:
|
|
break;
|
|
break;
|
|
}
|
|
}
|