qcacld-3.0: Fix handling of QOS action frame

QOS action frame is not handled and thus HDD's dscp mapping
are not updated.

Update the HDD's dscp mapping properly once hdd receive
QOS action frame.

Change-Id: I04ba9882767918cfb0c551791783f2b7eac998d5
CRs-Fixed: 2325729
This commit is contained in:
Abhishek Singh
2018-10-01 16:44:32 +05:30
committed by nshrivas
parent 9b13327cfb
commit ee5c9a3851

View File

@@ -903,9 +903,30 @@ int wlan_hdd_del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev)
return ret; return ret;
} }
/**
* hdd_is_qos_action_frame() - check if frame is QOS action frame
* @pb_frames: frame pointer
* @frame_len: frame length
*
* Return: true if it is QOS action frame else false.
*/
static inline bool
hdd_is_qos_action_frame(uint8_t *pb_frames, uint32_t frame_len)
{
if (frame_len <= WLAN_HDD_PUBLIC_ACTION_FRAME_OFFSET + 1) {
hdd_debug("Not a QOS frame len: %d", frame_len);
return false;
}
return ((pb_frames[WLAN_HDD_PUBLIC_ACTION_FRAME_OFFSET] ==
WLAN_HDD_QOS_ACTION_FRAME) &&
(pb_frames[WLAN_HDD_PUBLIC_ACTION_FRAME_OFFSET + 1] ==
WLAN_HDD_QOS_MAP_CONFIGURE));
}
void __hdd_indicate_mgmt_frame(struct hdd_adapter *adapter, void __hdd_indicate_mgmt_frame(struct hdd_adapter *adapter,
uint32_t nFrameLength, uint32_t frm_len,
uint8_t *pbFrames, uint8_t *pb_frames,
uint8_t frameType, uint32_t rxChan, int8_t rxRssi) uint8_t frameType, uint32_t rxChan, int8_t rxRssi)
{ {
uint16_t freq; uint16_t freq;
@@ -914,7 +935,7 @@ void __hdd_indicate_mgmt_frame(struct hdd_adapter *adapter,
struct hdd_context *hdd_ctx; struct hdd_context *hdd_ctx;
hdd_debug("Frame Type = %d Frame Length = %d", hdd_debug("Frame Type = %d Frame Length = %d",
frameType, nFrameLength); frameType, frm_len);
if (NULL == adapter) { if (NULL == adapter) {
hdd_err("adapter is NULL"); hdd_err("adapter is NULL");
@@ -922,27 +943,27 @@ void __hdd_indicate_mgmt_frame(struct hdd_adapter *adapter,
} }
hdd_ctx = WLAN_HDD_GET_CTX(adapter); hdd_ctx = WLAN_HDD_GET_CTX(adapter);
if (0 == nFrameLength) { if (!frm_len) {
hdd_err("Frame Length is Invalid ZERO"); hdd_err("Frame Length is Invalid ZERO");
return; return;
} }
if (NULL == pbFrames) { if (!pb_frames) {
hdd_err("pbFrames is NULL"); hdd_err("pbFrames is NULL");
return; return;
} }
type = WLAN_HDD_GET_TYPE_FRM_FC(pbFrames[0]); type = WLAN_HDD_GET_TYPE_FRM_FC(pb_frames[0]);
subType = WLAN_HDD_GET_SUBTYPE_FRM_FC(pbFrames[0]); subType = WLAN_HDD_GET_SUBTYPE_FRM_FC(pb_frames[0]);
/* Get adapter from Destination mac address of the frame */ /* Get adapter from Destination mac address of the frame */
if ((type == SIR_MAC_MGMT_FRAME) && if ((type == SIR_MAC_MGMT_FRAME) &&
(subType != SIR_MAC_MGMT_PROBE_REQ) && (subType != SIR_MAC_MGMT_PROBE_REQ) &&
!qdf_is_macaddr_broadcast( !qdf_is_macaddr_broadcast(
(struct qdf_mac_addr *)&pbFrames[WLAN_HDD_80211_FRM_DA_OFFSET])) { (struct qdf_mac_addr *)&pb_frames[WLAN_HDD_80211_FRM_DA_OFFSET])) {
adapter = adapter =
hdd_get_adapter_by_macaddr(hdd_ctx, hdd_get_adapter_by_macaddr(hdd_ctx,
&pbFrames &pb_frames
[WLAN_HDD_80211_FRM_DA_OFFSET]); [WLAN_HDD_80211_FRM_DA_OFFSET]);
if (NULL == adapter) { if (NULL == adapter) {
/* /*
@@ -952,17 +973,17 @@ void __hdd_indicate_mgmt_frame(struct hdd_adapter *adapter,
*/ */
hdd_err("adapter for action frame is NULL Macaddr = " hdd_err("adapter for action frame is NULL Macaddr = "
MAC_ADDRESS_STR, MAC_ADDRESS_STR,
MAC_ADDR_ARRAY(&pbFrames MAC_ADDR_ARRAY(&pb_frames
[WLAN_HDD_80211_FRM_DA_OFFSET])); [WLAN_HDD_80211_FRM_DA_OFFSET]));
hdd_debug("Frame Type = %d Frame Length = %d subType = %d", hdd_debug("Frame Type = %d Frame Length = %d subType = %d",
frameType, nFrameLength, subType); frameType, frm_len, subType);
/* /*
* We will receive broadcast management frames * We will receive broadcast management frames
* in OCB mode * in OCB mode
*/ */
adapter = hdd_get_adapter(hdd_ctx, QDF_OCB_MODE); adapter = hdd_get_adapter(hdd_ctx, QDF_OCB_MODE);
if (NULL == adapter || !qdf_is_macaddr_broadcast( if (NULL == adapter || !qdf_is_macaddr_broadcast(
(struct qdf_mac_addr *)&pbFrames (struct qdf_mac_addr *)&pb_frames
[WLAN_HDD_80211_FRM_DA_OFFSET])) { [WLAN_HDD_80211_FRM_DA_OFFSET])) {
/* /*
* Under assumtion that we don't * Under assumtion that we don't
@@ -994,23 +1015,28 @@ void __hdd_indicate_mgmt_frame(struct hdd_adapter *adapter,
freq = ieee80211_channel_to_frequency(rxChan, freq = ieee80211_channel_to_frequency(rxChan,
NL80211_BAND_5GHZ); NL80211_BAND_5GHZ);
if (hdd_is_qos_action_frame(pb_frames, frm_len))
sme_update_dsc_pto_up_mapping(hdd_ctx->mac_handle,
adapter->dscp_to_up_map,
adapter->session_id);
/* Indicate Frame Over Normal Interface */ /* Indicate Frame Over Normal Interface */
hdd_debug("Indicate Frame over NL80211 sessionid : %d, idx :%d", hdd_debug("Indicate Frame over NL80211 sessionid : %d, idx :%d",
adapter->session_id, adapter->dev->ifindex); adapter->session_id, adapter->dev->ifindex);
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0)) #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
cfg80211_rx_mgmt(adapter->dev->ieee80211_ptr, cfg80211_rx_mgmt(adapter->dev->ieee80211_ptr,
freq, rxRssi * 100, pbFrames, freq, rxRssi * 100, pb_frames,
nFrameLength, NL80211_RXMGMT_FLAG_ANSWERED); frm_len, NL80211_RXMGMT_FLAG_ANSWERED);
#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 12, 0)) #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 12, 0))
cfg80211_rx_mgmt(adapter->dev->ieee80211_ptr, cfg80211_rx_mgmt(adapter->dev->ieee80211_ptr,
freq, rxRssi * 100, pbFrames, freq, rxRssi * 100, pb_frames,
nFrameLength, NL80211_RXMGMT_FLAG_ANSWERED, frm_len, NL80211_RXMGMT_FLAG_ANSWERED,
GFP_ATOMIC); GFP_ATOMIC);
#else #else
cfg80211_rx_mgmt(adapter->dev->ieee80211_ptr, freq, cfg80211_rx_mgmt(adapter->dev->ieee80211_ptr, freq,
rxRssi * 100, rxRssi * 100,
pbFrames, nFrameLength, GFP_ATOMIC); pb_frames, frm_len, GFP_ATOMIC);
#endif /* LINUX_VERSION_CODE */ #endif /* LINUX_VERSION_CODE */
} }