software/drivers/sd8887/src/wlan/mlan/mlan_wmm.c
/**
 *  @brief Process the GET_WMM_STATUS command response from firmware
 *
 *  The GET_WMM_STATUS response may contain multiple TLVs for:
 *      - AC Queue status TLVs
 *      - Current WMM Parameter IE TLV
 *      - Admission Control action frame TLVs
 *
 *  This function parses the TLVs and then calls further functions
 *   to process any changes in the queue prioritize or state.
 *
 *  @param priv      Pointer to the mlan_private driver data struct
 *  @param ptlv      Pointer to the tlv block returned in the response.
 *  @param resp_len  Length of TLV block
 *
 *  @return MLAN_STATUS_SUCCESS
 */
@brief Process the GET_WMM_STATUS command response from firmware
The GET_WMM_STATUS response may contain multiple TLVs for:
- AC Queue status TLVs
- Current WMM Parameter IE TLV
- Admission Control action frame TLVs

This function parses the TLVs and then calls further functions
to process any changes in the queue prioritize or state.

@param priv      Pointer to the mlan_private driver data struct
@param ptlv      Pointer to the tlv block returned in the response.
@param resp_len  Length of TLV block


@brief Process the GET_WMM_STATUS command response from firmware The GET_WMM_STATUS response may contain multiple TLVs for : - AC Queue status TLVs - Current WMM Parameter IE TLV - Admission Control action frame TLVs This function parses the TLVs and then calls further functions to process any changes in the queue prioritize or state . @param priv Pointer to the mlan_private driver data struct @param ptlv Pointer to the tlv block returned in the response . @param resp_len Length of TLV block
mlan_status
wlan_ret_wmm_get_status(pmlan_private priv, t_u8 *ptlv, int resp_len)
{
	t_u8 *pcurrent = ptlv;
	t_u32 tlv_len;
	t_u8 send_wmm_event;
	MrvlIEtypes_Data_t *ptlv_hdr;
	MrvlIEtypes_WmmQueueStatus_t *ptlv_wmm_q_status;
	IEEEtypes_WmmParameter_t *pwmm_param_ie = MNULL;
	WmmAcStatus_t *pac_status;
	MrvlIETypes_ActionFrame_t *ptlv_action;
	IEEEtypes_Action_WMM_AddTsRsp_t *padd_ts_rsp;
	IEEEtypes_Action_WMM_DelTs_t *pdel_ts;
	ENTER();
	send_wmm_event = MFALSE;
	PRINTM(MINFO, "WMM: WMM_GET_STATUS cmdresp received: %d\n", resp_len);
	HEXDUMP("CMD_RESP: WMM_GET_STATUS", pcurrent, resp_len);
	while (resp_len >= sizeof(ptlv_hdr->header)) {
		ptlv_hdr = (MrvlIEtypes_Data_t *)pcurrent;
		tlv_len = wlan_le16_to_cpu(ptlv_hdr->header.len);
		if ((tlv_len + sizeof(ptlv_hdr->header)) > resp_len) {
			PRINTM(MERROR,
			       "WMM get status: Error in processing  TLV buffer\n");
			resp_len = 0;
			continue;
		}
		switch (wlan_le16_to_cpu(ptlv_hdr->header.type)) {
		case TLV_TYPE_WMMQSTATUS:
			ptlv_wmm_q_status =
				(MrvlIEtypes_WmmQueueStatus_t *)ptlv_hdr;
			PRINTM(MEVENT, "WMM_STATUS: QSTATUS TLV: %d\n",
			       ptlv_wmm_q_status->queue_index);
			PRINTM(MINFO,
			       "CMD_RESP: WMM_GET_STATUS: QSTATUS TLV: %d, %d, %d\n",
			       ptlv_wmm_q_status->queue_index,
			       ptlv_wmm_q_status->flow_required,
			       ptlv_wmm_q_status->disabled);
			pac_status =
				&priv->wmm.ac_status[ptlv_wmm_q_status->
						     queue_index];
			pac_status->disabled = ptlv_wmm_q_status->disabled;
			pac_status->flow_required =
				ptlv_wmm_q_status->flow_required;
			pac_status->flow_created =
				ptlv_wmm_q_status->flow_created;
			break;
		case TLV_TYPE_VENDOR_SPECIFIC_IE:	
			PRINTM(MEVENT, "WMM STATUS: WMM IE\n");
			HEXDUMP("WMM: WMM TLV:", (t_u8 *)ptlv_hdr, tlv_len + 4);
			pwmm_param_ie =
				(IEEEtypes_WmmParameter_t *)(pcurrent + 2);
			pwmm_param_ie->vend_hdr.len = (t_u8)tlv_len;
			pwmm_param_ie->vend_hdr.element_id = WMM_IE;
			PRINTM(MINFO,
			       "CMD_RESP: WMM_GET_STATUS: WMM Parameter Set: %d\n",
			       pwmm_param_ie->qos_info.para_set_count);
			memcpy(priv->adapter,
			       (t_u8 *)&priv->curr_bss_params.bss_descriptor.
			       wmm_ie, pwmm_param_ie,
			       MIN(sizeof(IEEEtypes_WmmParameter_t),
				   (pwmm_param_ie->vend_hdr.len + 2)));
			send_wmm_event = MTRUE;
			break;
		case TLV_TYPE_IEEE_ACTION_FRAME:
			PRINTM(MEVENT, "WMM_STATUS: IEEE Action Frame\n");
			ptlv_action = (MrvlIETypes_ActionFrame_t *)pcurrent;
			ptlv_action->actionFrame.wmmAc.tspecAct.category =
				wlan_le32_to_cpu(ptlv_action->actionFrame.wmmAc.
						 tspecAct.category);
			if (ptlv_action->actionFrame.wmmAc.tspecAct.category ==
			    IEEE_MGMT_ACTION_CATEGORY_WMM_TSPEC) {
				ptlv_action->actionFrame.wmmAc.tspecAct.action =
					wlan_le32_to_cpu(ptlv_action->
							 actionFrame.wmmAc.
							 tspecAct.action);
				switch (ptlv_action->actionFrame.wmmAc.tspecAct.
					action) {
				case TSPEC_ACTION_CODE_ADDTS_RSP:
					padd_ts_rsp =
						&ptlv_action->actionFrame.wmmAc.
						addTsRsp;
					wlan_send_wmmac_host_event(priv,
								   "ADDTS_RSP",
								   ptlv_action->
								   srcAddr,
								   padd_ts_rsp->
								   tspecIE.
								   TspecBody.
								   TSInfo.TID,
								   padd_ts_rsp->
								   tspecIE.
								   TspecBody.
								   TSInfo.
								   UserPri,
								   padd_ts_rsp->
								   statusCode);
					break;
				case TSPEC_ACTION_CODE_DELTS:
					pdel_ts =
						&ptlv_action->actionFrame.wmmAc.
						delTs;
					wlan_send_wmmac_host_event(priv,
								   "DELTS_RX",
								   ptlv_action->
								   srcAddr,
								   pdel_ts->
								   tspecIE.
								   TspecBody.
								   TSInfo.TID,
								   pdel_ts->
								   tspecIE.
								   TspecBody.
								   TSInfo.
								   UserPri,
								   pdel_ts->
								   reasonCode);
					break;
				case TSPEC_ACTION_CODE_ADDTS_REQ:
				default:
					break;
				}
			}
			break;
		default:
			break;
		}
		pcurrent += (tlv_len + sizeof(ptlv_hdr->header));
		resp_len -= (tlv_len + sizeof(ptlv_hdr->header));
	}
	wlan_wmm_setup_queue_priorities(priv, pwmm_param_ie);
	wlan_wmm_setup_ac_downgrade(priv);
	if (send_wmm_event) {
		wlan_recv_event(priv, MLAN_EVENT_ID_FW_WMM_CONFIG_CHANGE,
				MNULL);
	}
	LEAVE();
	return MLAN_STATUS_SUCCESS;
}
mlan_status wlan_ret_wmm_get_status ( pmlan_private priv , t_u8 * ptlv , int resp_len ) { t_u8 * pcurrent = ptlv ; t_u32 tlv_len ; t_u8 send_wmm_event ; MrvlIEtypes_Data_t * ptlv_hdr ; MrvlIEtypes_WmmQueueStatus_t * ptlv_wmm_q_status ; IEEEtypes_WmmParameter_t * pwmm_param_ie = MNULL ; WmmAcStatus_t * pac_status ; MrvlIETypes_ActionFrame_t * ptlv_action ; IEEEtypes_Action_WMM_AddTsRsp_t * padd_ts_rsp ; IEEEtypes_Action_WMM_DelTs_t * pdel_ts ; ENTER ( ) ; send_wmm_event = MFALSE ; PRINTM ( MINFO , " \n " , resp_len ) ; HEXDUMP ( " " , pcurrent , resp_len ) ; while ( resp_len >= sizeof ( ptlv_hdr -> header ) ) { ptlv_hdr = ( MrvlIEtypes_Data_t * ) pcurrent ; tlv_len = wlan_le16_to_cpu ( ptlv_hdr -> header . len ) ; if ( ( tlv_len + sizeof ( ptlv_hdr -> header ) ) > resp_len ) { PRINTM ( MERROR , " \n " ) ; resp_len = 0 ; continue ; } switch ( wlan_le16_to_cpu ( ptlv_hdr -> header . type ) ) { case TLV_TYPE_WMMQSTATUS : ptlv_wmm_q_status = ( MrvlIEtypes_WmmQueueStatus_t * ) ptlv_hdr ; PRINTM ( MEVENT , " \n " , ptlv_wmm_q_status -> queue_index ) ; PRINTM ( MINFO , " \n " , ptlv_wmm_q_status -> queue_index , ptlv_wmm_q_status -> flow_required , ptlv_wmm_q_status -> disabled ) ; pac_status = & priv -> wmm . ac_status [ ptlv_wmm_q_status -> queue_index ] ; pac_status -> disabled = ptlv_wmm_q_status -> disabled ; pac_status -> flow_required = ptlv_wmm_q_status -> flow_required ; pac_status -> flow_created = ptlv_wmm_q_status -> flow_created ; break ; case TLV_TYPE_VENDOR_SPECIFIC_IE : PRINTM ( MEVENT , " \n " ) ; HEXDUMP ( " " , ( t_u8 * ) ptlv_hdr , tlv_len + 4 ) ; pwmm_param_ie = ( IEEEtypes_WmmParameter_t * ) ( pcurrent + 2 ) ; pwmm_param_ie -> vend_hdr . len = ( t_u8 ) tlv_len ; pwmm_param_ie -> vend_hdr . element_id = WMM_IE ; PRINTM ( MINFO , " \n " , pwmm_param_ie -> qos_info . para_set_count ) ; memcpy ( priv -> adapter , ( t_u8 * ) & priv -> curr_bss_params . bss_descriptor . wmm_ie , pwmm_param_ie , MIN ( sizeof ( IEEEtypes_WmmParameter_t ) , ( pwmm_param_ie -> vend_hdr . len + 2 ) ) ) ; send_wmm_event = MTRUE ; break ; case TLV_TYPE_IEEE_ACTION_FRAME : PRINTM ( MEVENT , " \n " ) ; ptlv_action = ( MrvlIETypes_ActionFrame_t * ) pcurrent ; ptlv_action -> actionFrame . wmmAc . tspecAct . category = wlan_le32_to_cpu ( ptlv_action -> actionFrame . wmmAc . tspecAct . category ) ; if ( ptlv_action -> actionFrame . wmmAc . tspecAct . category == IEEE_MGMT_ACTION_CATEGORY_WMM_TSPEC ) { ptlv_action -> actionFrame . wmmAc . tspecAct . action = wlan_le32_to_cpu ( ptlv_action -> actionFrame . wmmAc . tspecAct . action ) ; switch ( ptlv_action -> actionFrame . wmmAc . tspecAct . action ) { case TSPEC_ACTION_CODE_ADDTS_RSP : padd_ts_rsp = & ptlv_action -> actionFrame . wmmAc . addTsRsp ; wlan_send_wmmac_host_event ( priv , " " , ptlv_action -> srcAddr , padd_ts_rsp -> tspecIE . TspecBody . TSInfo . TID , padd_ts_rsp -> tspecIE . TspecBody . TSInfo . UserPri , padd_ts_rsp -> statusCode ) ; break ; case TSPEC_ACTION_CODE_DELTS : pdel_ts = & ptlv_action -> actionFrame . wmmAc . delTs ; wlan_send_wmmac_host_event ( priv , " " , ptlv_action -> srcAddr , pdel_ts -> tspecIE . TspecBody . TSInfo . TID , pdel_ts -> tspecIE . TspecBody . TSInfo . UserPri , pdel_ts -> reasonCode ) ; break ; case TSPEC_ACTION_CODE_ADDTS_REQ : default : break ; } } break ; default : break ; } pcurrent += ( tlv_len + sizeof ( ptlv_hdr -> header ) ) ; resp_len -= ( tlv_len + sizeof ( ptlv_hdr -> header ) ) ; } wlan_wmm_setup_queue_priorities ( priv , pwmm_param_ie ) ; wlan_wmm_setup_ac_downgrade ( priv ) ; if ( send_wmm_event ) { wlan_recv_event ( priv , MLAN_EVENT_ID_FW_WMM_CONFIG_CHANGE , MNULL ) ; } LEAVE ( ) ; return MLAN_STATUS_SUCCESS ; }
@brief Process the GET_WMM_STATUS command response from firmware
  The GET_WMM_STATUS response may contain multiple TLVs for:
      - AC Queue status TLVs
      - Current WMM Parameter IE TLV
      - Admission Control action frame TLVs
@brief Process the GET_WMM_STATUS command response from firmware The GET_WMM_STATUS response may contain multiple TLVs for : - AC Queue status TLVs - Current WMM Parameter IE TLV - Admission Control action frame TLVs
/* WMM_IE */ /*
			 * Point the regular IEEE IE 2 bytes into the NXP IE
			 *   and setup the IEEE IE type and length byte fields
			 */