software/drivers/sd8887/src/wlan/mlan/mlan_sta_rx.c
/**
 *  @brief This function processes received packet and forwards it
 *          to kernel/upper layer
 *
 *  @param pmadapter A pointer to mlan_adapter
 *  @param pmbuf   A pointer to mlan_buffer which includes the received packet
 *
 *  @return        MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
 */
@brief This function processes received packet and forwards it
to kernel/upper layer

@param pmadapter A pointer to mlan_adapter
@param pmbuf   A pointer to mlan_buffer which includes the received packet


@brief This function processes received packet and forwards it to kernel / upper layer @param pmadapter A pointer to mlan_adapter @param pmbuf A pointer to mlan_buffer which includes the received packet
mlan_status
wlan_process_rx_packet(pmlan_adapter pmadapter, pmlan_buffer pmbuf)
{
	mlan_status ret = MLAN_STATUS_SUCCESS;
	pmlan_private priv = pmadapter->priv[pmbuf->bss_index];
	RxPacketHdr_t *prx_pkt;
	RxPD *prx_pd;
	int hdr_chop;
	EthII_Hdr_t *peth_hdr;
	t_u8 rfc1042_eth_hdr[MLAN_MAC_ADDR_LENGTH] = {
		0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00
	};
	t_u8 snap_oui_802_h[MLAN_MAC_ADDR_LENGTH] = {
		0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8
	};
	t_u8 appletalk_aarp_type[2] = { 0x80, 0xf3 };
	t_u8 ipx_snap_type[2] = { 0x81, 0x37 };
	t_u8 tdls_action_type[2] = { 0x89, 0x0d };
	ENTER();
	prx_pd = (RxPD *)(pmbuf->pbuf + pmbuf->data_offset);
	prx_pkt = (RxPacketHdr_t *)((t_u8 *)prx_pd + prx_pd->rx_pkt_offset);
#define DBG_TYPE_SMALL  2
#define SIZE_OF_DBG_STRUCT 4
	if (prx_pd->rx_pkt_type == PKT_TYPE_DEBUG) {
		t_u8 dbg_type;
		dbg_type = *(t_u8 *)&prx_pkt->eth803_hdr;
		if (dbg_type == DBG_TYPE_SMALL) {
			PRINTM(MFW_D, "\n");
			DBG_HEXDUMP(MFW_D, "FWDBG",
				    (char *)((t_u8 *)&prx_pkt->eth803_hdr +
					     SIZE_OF_DBG_STRUCT),
				    prx_pd->rx_pkt_length);
			PRINTM(MFW_D, "FWDBG::\n");
		}
		goto done;
	}
	PRINTM(MINFO,
	       "RX Data: data_len - prx_pd->rx_pkt_offset = %d - %d = %d\n",
	       pmbuf->data_len, prx_pd->rx_pkt_offset,
	       pmbuf->data_len - prx_pd->rx_pkt_offset);
	HEXDUMP("RX Data: Dest", prx_pkt->eth803_hdr.dest_addr,
		sizeof(prx_pkt->eth803_hdr.dest_addr));
	HEXDUMP("RX Data: Src", prx_pkt->eth803_hdr.src_addr,
		sizeof(prx_pkt->eth803_hdr.src_addr));
	if ((memcmp(pmadapter, &prx_pkt->rfc1042_hdr,
		    snap_oui_802_h, sizeof(snap_oui_802_h)) == 0) ||
	    ((memcmp(pmadapter, &prx_pkt->rfc1042_hdr,
		     rfc1042_eth_hdr, sizeof(rfc1042_eth_hdr)) == 0) &&
	     memcmp(pmadapter, &prx_pkt->rfc1042_hdr.snap_type,
		    appletalk_aarp_type, sizeof(appletalk_aarp_type)) &&
	     memcmp(pmadapter, &prx_pkt->rfc1042_hdr.snap_type,
		    ipx_snap_type, sizeof(ipx_snap_type)))) {
		peth_hdr = (EthII_Hdr_t *)
			((t_u8 *)&prx_pkt->eth803_hdr
			 + sizeof(prx_pkt->eth803_hdr) +
			 sizeof(prx_pkt->rfc1042_hdr)
			 - sizeof(prx_pkt->eth803_hdr.dest_addr)
			 - sizeof(prx_pkt->eth803_hdr.src_addr)
			 - sizeof(prx_pkt->rfc1042_hdr.snap_type));
		memcpy(pmadapter, peth_hdr->src_addr,
		       prx_pkt->eth803_hdr.src_addr,
		       sizeof(peth_hdr->src_addr));
		memcpy(pmadapter, peth_hdr->dest_addr,
		       prx_pkt->eth803_hdr.dest_addr,
		       sizeof(peth_hdr->dest_addr));
		hdr_chop = (t_u32)((t_ptr)peth_hdr - (t_ptr)prx_pd);
	} else {
		HEXDUMP("RX Data: LLC/SNAP",
			(t_u8 *)&prx_pkt->rfc1042_hdr,
			sizeof(prx_pkt->rfc1042_hdr));
		if (!memcmp
		    (pmadapter, &prx_pkt->eth803_hdr.h803_len, tdls_action_type,
		     sizeof(tdls_action_type))) {
			wlan_process_tdls_action_frame(priv,
						       ((t_u8 *)prx_pd +
							prx_pd->rx_pkt_offset),
						       prx_pd->rx_pkt_length);
		}
		hdr_chop = (t_u32)((t_ptr)&prx_pkt->eth803_hdr - (t_ptr)prx_pd);
	}
	pmbuf->data_len -= hdr_chop;
	pmbuf->data_offset += hdr_chop;
	pmbuf->pparent = MNULL;
	DBG_HEXDUMP(MDAT_D, "RxPD", (t_u8 *)prx_pd,
		    MIN(sizeof(RxPD), MAX_DATA_DUMP_LEN));
	DBG_HEXDUMP(MDAT_D, "Rx Payload",
		    ((t_u8 *)prx_pd + prx_pd->rx_pkt_offset),
		    MIN(prx_pd->rx_pkt_length, MAX_DATA_DUMP_LEN));
	priv->rxpd_rate = prx_pd->rx_rate;
	pmadapter->callbacks.moal_get_system_time(pmadapter->pmoal_handle,
						  &pmbuf->out_ts_sec,
						  &pmbuf->out_ts_usec);
	PRINTM_NETINTF(MDATA, priv);
	PRINTM(MDATA, "%lu.%06lu : Data => kernel seq_num=%d tid=%d\n",
	       pmbuf->out_ts_sec, pmbuf->out_ts_usec, prx_pd->seq_num,
	       prx_pd->priority);
	ret = pmadapter->callbacks.moal_recv_packet(pmadapter->pmoal_handle,
						    pmbuf);
	if (ret == MLAN_STATUS_FAILURE) {
		pmbuf->status_code = MLAN_ERROR_PKT_INVALID;
		PRINTM(MERROR,
		       "STA Rx Error: moal_recv_packet returned error\n");
	}
done:
	if (ret != MLAN_STATUS_PENDING)
		wlan_free_mlan_buffer(pmadapter, pmbuf);
	LEAVE();
	return ret;
}
mlan_status wlan_process_rx_packet ( pmlan_adapter pmadapter , pmlan_buffer pmbuf ) { mlan_status ret = MLAN_STATUS_SUCCESS ; pmlan_private priv = pmadapter -> priv [ pmbuf -> bss_index ] ; RxPacketHdr_t * prx_pkt ; RxPD * prx_pd ; int hdr_chop ; EthII_Hdr_t * peth_hdr ; t_u8 rfc1042_eth_hdr [ MLAN_MAC_ADDR_LENGTH ] = { 0xaa , 0xaa , 0x03 , 0x00 , 0x00 , 0x00 } ; t_u8 snap_oui_802_h [ MLAN_MAC_ADDR_LENGTH ] = { 0xaa , 0xaa , 0x03 , 0x00 , 0x00 , 0xf8 } ; t_u8 appletalk_aarp_type [ 2 ] = { 0x80 , 0xf3 } ; t_u8 ipx_snap_type [ 2 ] = { 0x81 , 0x37 } ; t_u8 tdls_action_type [ 2 ] = { 0x89 , 0x0d } ; ENTER ( ) ; prx_pd = ( RxPD * ) ( pmbuf -> pbuf + pmbuf -> data_offset ) ; prx_pkt = ( RxPacketHdr_t * ) ( ( t_u8 * ) prx_pd + prx_pd -> rx_pkt_offset ) ; #define DBG_TYPE_SMALL   2 #define SIZE_OF_DBG_STRUCT  4 if ( prx_pd -> rx_pkt_type == PKT_TYPE_DEBUG ) { t_u8 dbg_type ; dbg_type = * ( t_u8 * ) & prx_pkt -> eth803_hdr ; if ( dbg_type == DBG_TYPE_SMALL ) { PRINTM ( MFW_D , " \n " ) ; DBG_HEXDUMP ( MFW_D , " " , ( char * ) ( ( t_u8 * ) & prx_pkt -> eth803_hdr + SIZE_OF_DBG_STRUCT ) , prx_pd -> rx_pkt_length ) ; PRINTM ( MFW_D , " \n " ) ; } goto done ; } PRINTM ( MINFO , " \n " , pmbuf -> data_len , prx_pd -> rx_pkt_offset , pmbuf -> data_len - prx_pd -> rx_pkt_offset ) ; HEXDUMP ( " " , prx_pkt -> eth803_hdr . dest_addr , sizeof ( prx_pkt -> eth803_hdr . dest_addr ) ) ; HEXDUMP ( " " , prx_pkt -> eth803_hdr . src_addr , sizeof ( prx_pkt -> eth803_hdr . src_addr ) ) ; if ( ( memcmp ( pmadapter , & prx_pkt -> rfc1042_hdr , snap_oui_802_h , sizeof ( snap_oui_802_h ) ) == 0 ) || ( ( memcmp ( pmadapter , & prx_pkt -> rfc1042_hdr , rfc1042_eth_hdr , sizeof ( rfc1042_eth_hdr ) ) == 0 ) && memcmp ( pmadapter , & prx_pkt -> rfc1042_hdr . snap_type , appletalk_aarp_type , sizeof ( appletalk_aarp_type ) ) && memcmp ( pmadapter , & prx_pkt -> rfc1042_hdr . snap_type , ipx_snap_type , sizeof ( ipx_snap_type ) ) ) ) { peth_hdr = ( EthII_Hdr_t * ) ( ( t_u8 * ) & prx_pkt -> eth803_hdr + sizeof ( prx_pkt -> eth803_hdr ) + sizeof ( prx_pkt -> rfc1042_hdr ) - sizeof ( prx_pkt -> eth803_hdr . dest_addr ) - sizeof ( prx_pkt -> eth803_hdr . src_addr ) - sizeof ( prx_pkt -> rfc1042_hdr . snap_type ) ) ; memcpy ( pmadapter , peth_hdr -> src_addr , prx_pkt -> eth803_hdr . src_addr , sizeof ( peth_hdr -> src_addr ) ) ; memcpy ( pmadapter , peth_hdr -> dest_addr , prx_pkt -> eth803_hdr . dest_addr , sizeof ( peth_hdr -> dest_addr ) ) ; hdr_chop = ( t_u32 ) ( ( t_ptr ) peth_hdr - ( t_ptr ) prx_pd ) ; } else { HEXDUMP ( " " , ( t_u8 * ) & prx_pkt -> rfc1042_hdr , sizeof ( prx_pkt -> rfc1042_hdr ) ) ; if ( ! memcmp ( pmadapter , & prx_pkt -> eth803_hdr . h803_len , tdls_action_type , sizeof ( tdls_action_type ) ) ) { wlan_process_tdls_action_frame ( priv , ( ( t_u8 * ) prx_pd + prx_pd -> rx_pkt_offset ) , prx_pd -> rx_pkt_length ) ; } hdr_chop = ( t_u32 ) ( ( t_ptr ) & prx_pkt -> eth803_hdr - ( t_ptr ) prx_pd ) ; } pmbuf -> data_len -= hdr_chop ; pmbuf -> data_offset += hdr_chop ; pmbuf -> pparent = MNULL ; DBG_HEXDUMP ( MDAT_D , " " , ( t_u8 * ) prx_pd , MIN ( sizeof ( RxPD ) , MAX_DATA_DUMP_LEN ) ) ; DBG_HEXDUMP ( MDAT_D , " " , ( ( t_u8 * ) prx_pd + prx_pd -> rx_pkt_offset ) , MIN ( prx_pd -> rx_pkt_length , MAX_DATA_DUMP_LEN ) ) ; priv -> rxpd_rate = prx_pd -> rx_rate ; pmadapter -> callbacks . moal_get_system_time ( pmadapter -> pmoal_handle , & pmbuf -> out_ts_sec , & pmbuf -> out_ts_usec ) ; PRINTM_NETINTF ( MDATA , priv ) ; PRINTM ( MDATA , " \n " , pmbuf -> out_ts_sec , pmbuf -> out_ts_usec , prx_pd -> seq_num , prx_pd -> priority ) ; ret = pmadapter -> callbacks . moal_recv_packet ( pmadapter -> pmoal_handle , pmbuf ) ; if ( ret == MLAN_STATUS_FAILURE ) { pmbuf -> status_code = MLAN_ERROR_PKT_INVALID ; PRINTM ( MERROR , " \n " ) ; } done : if ( ret != MLAN_STATUS_PENDING ) wlan_free_mlan_buffer ( pmadapter , pmbuf ) ; LEAVE ( ) ; return ret ; }
@brief This function processes received packet and forwards it
          to kernel/upper layer
@brief This function processes received packet and forwards it to kernel / upper layer
/** Small debug type */ /** Size of debugging structure */ /*
		 * Replace the 803 header and rfc1042 header (llc/snap) with an
		 * EthernetII header, keep the src/dst and snap_type (ethertype).
		 * The firmware only passes up SNAP frames converting
		 * all RX Data from 802.11 to 802.2/LLC/SNAP frames.
		 * To create the Ethernet II, just move the src, dst address
		 * right before the snap_type.
		 */ /* Chop off the RxPD + the excess memory from the 802.2/llc/snap
		 *  header that was removed.
		 */ /* Chop off the RxPD */ /* Chop off the leading header bytes so the it points to the start of
	 *   either the reconstructed EthII frame or the 802.2/llc/snap frame
	 */