Ejemplo n.º 1
0
/**
 *  @brief Function to send packet
 *
 *  @param pmlan_adapter	A pointer to mlan_adapter structure
 *  @param pmbuf		A pointer to mlan_buffer structure
 *
 *  @return			MLAN_STATUS_PENDING
 */
mlan_status
mlan_send_packet(IN t_void * pmlan_adapter, IN pmlan_buffer pmbuf)
{
    mlan_status ret = MLAN_STATUS_PENDING;
    mlan_adapter *pmadapter = (mlan_adapter *) pmlan_adapter;

    ENTER();
    MASSERT(pmlan_adapter && pmbuf);

    MASSERT(pmbuf->bss_index < pmadapter->priv_num);
    pmbuf->flags = MLAN_BUF_FLAG_MOAL_TX_BUF;

    if (((pmadapter->priv[pmbuf->bss_index]->port_ctrl_mode == MTRUE) &&
         ((mlan_ntohs(*(t_u16 *) & pmbuf->pbuf[pmbuf->data_offset +
                                               MLAN_ETHER_PKT_TYPE_OFFSET]) ==
           MLAN_ETHER_PKT_TYPE_EAPOL)
          ||
          (mlan_ntohs
           (*(t_u16 *) & pmbuf->
            pbuf[pmbuf->data_offset + MLAN_ETHER_PKT_TYPE_OFFSET]) ==
           MLAN_ETHER_PKT_TYPE_WAPI)
         ))
        || (pmbuf->buf_type == MLAN_BUF_TYPE_RAW_DATA)

        ) {
        PRINTM(MINFO, "mlan_send_pkt(): enq(bybass_txq)\n");
        wlan_add_buf_bypass_txqueue(pmadapter, pmbuf);
    } else {
        /* Transmit the packet */
        wlan_wmm_add_buf_txqueue(pmadapter, pmbuf);
    }

    LEAVE();
    return ret;
}
/**
 *  @brief Function to send packet
 *
 *  @param pmlan_adapter	A pointer to mlan_adapter structure
 *  @param pmbuf		A pointer to mlan_buffer structure
 *
 *  @return			MLAN_STATUS_PENDING
 */
mlan_status
mlan_send_packet(IN t_void * pmlan_adapter, IN pmlan_buffer pmbuf)
{
	mlan_status ret = MLAN_STATUS_PENDING;
	mlan_adapter *pmadapter = (mlan_adapter *) pmlan_adapter;
	mlan_private *pmpriv;
	t_u16 eth_type = 0;
	t_u8 ra[MLAN_MAC_ADDR_LENGTH];
	tdlsStatus_e tdls_status;

	ENTER();
	MASSERT(pmlan_adapter && pmbuf);

	MASSERT(pmbuf->bss_index < pmadapter->priv_num);
	pmbuf->flags |= MLAN_BUF_FLAG_MOAL_TX_BUF;
	pmpriv = pmadapter->priv[pmbuf->bss_index];

	eth_type =
		mlan_ntohs(*(t_u16 *) & pmbuf->
			   pbuf[pmbuf->data_offset +
				MLAN_ETHER_PKT_TYPE_OFFSET]);
	if (((pmadapter->priv[pmbuf->bss_index]->port_ctrl_mode == MTRUE) &&
	     ((eth_type == MLAN_ETHER_PKT_TYPE_EAPOL)
	      || (eth_type == MLAN_ETHER_PKT_TYPE_WAPI)
	     ))
	    || (eth_type == MLAN_ETHER_PKT_TYPE_TDLS_ACTION)
	    || (pmbuf->buf_type == MLAN_BUF_TYPE_RAW_DATA)

		) {
		if (eth_type == MLAN_ETHER_PKT_TYPE_TDLS_ACTION) {
			memcpy(pmadapter, ra, pmbuf->pbuf + pmbuf->data_offset,
			       MLAN_MAC_ADDR_LENGTH);
			tdls_status = wlan_get_tdls_link_status(pmpriv, ra);
			if (MTRUE == wlan_is_tdls_link_setup(tdls_status) ||
			    !pmpriv->media_connected)
				pmbuf->flags |= MLAN_BUF_FLAG_TDLS;
		}
		PRINTM(MINFO, "mlan_send_pkt(): enq(bybass_txq)\n");
		wlan_add_buf_bypass_txqueue(pmadapter, pmbuf);
	} else {
		/* Transmit the packet */
		wlan_wmm_add_buf_txqueue(pmadapter, pmbuf);
	}

	LEAVE();
	return ret;
}
Ejemplo n.º 3
0
/**
 *  @brief This function processes received packet and forwards it
 *          to kernel/upper layer or send back to firmware
 *
 *  @param priv      A pointer to mlan_private
 *  @param pmbuf     A pointer to mlan_buffer which includes the received packet
 *
 *  @return          MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
 */
mlan_status
wlan_process_uap_rx_packet(IN mlan_private *priv, IN pmlan_buffer pmbuf)
{
	pmlan_adapter pmadapter = priv->adapter;
	mlan_status ret = MLAN_STATUS_SUCCESS;
	UapRxPD *prx_pd;
	RxPacketHdr_t *prx_pkt;
	pmlan_buffer newbuf = MNULL;

	ENTER();

	prx_pd = (UapRxPD *)(pmbuf->pbuf + pmbuf->data_offset);
	prx_pkt = (RxPacketHdr_t *)((t_u8 *)prx_pd + prx_pd->rx_pkt_offset);

	DBG_HEXDUMP(MDAT_D, "uAP RxPD", prx_pd,
		    MIN(sizeof(UapRxPD), MAX_DATA_DUMP_LEN));
	DBG_HEXDUMP(MDAT_D, "uAP Rx Payload",
		    ((t_u8 *)prx_pd + prx_pd->rx_pkt_offset),
		    MIN(prx_pd->rx_pkt_length, MAX_DATA_DUMP_LEN));

	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);
	PRINTM(MDATA, "Rx dest " MACSTR "\n",
	       MAC2STR(prx_pkt->eth803_hdr.dest_addr));

	/* don't do packet forwarding in disconnected state */
	/* don't do packet forwarding when packet > 1514 */
	if ((priv->media_connected == MFALSE) ||
	    ((pmbuf->data_len - prx_pd->rx_pkt_offset) > MV_ETH_FRAME_LEN))
		goto upload;

	if (prx_pkt->eth803_hdr.dest_addr[0] & 0x01) {
		if (!(priv->pkt_fwd & PKT_FWD_INTRA_BCAST)) {
			/* Multicast pkt */
			newbuf = wlan_alloc_mlan_buffer(pmadapter,
							MLAN_TX_DATA_BUF_SIZE_2K,
							0, MOAL_MALLOC_BUFFER);
			if (newbuf) {
				newbuf->bss_index = pmbuf->bss_index;
				newbuf->buf_type = pmbuf->buf_type;
				newbuf->priority = pmbuf->priority;
				newbuf->in_ts_sec = pmbuf->in_ts_sec;
				newbuf->in_ts_usec = pmbuf->in_ts_usec;
				newbuf->data_offset =
					(sizeof(UapTxPD) + INTF_HEADER_LEN +
					 DMA_ALIGNMENT);
				util_scalar_increment(pmadapter->pmoal_handle,
						      &pmadapter->
						      pending_bridge_pkts,
						      pmadapter->callbacks.
						      moal_spin_lock,
						      pmadapter->callbacks.
						      moal_spin_unlock);
				newbuf->flags |= MLAN_BUF_FLAG_BRIDGE_BUF;

				/* copy the data, skip rxpd */
				memcpy(pmadapter,
				       (t_u8 *)newbuf->pbuf +
				       newbuf->data_offset,
				       pmbuf->pbuf + pmbuf->data_offset +
				       prx_pd->rx_pkt_offset,
				       pmbuf->data_len - prx_pd->rx_pkt_offset);
				newbuf->data_len =
					pmbuf->data_len - prx_pd->rx_pkt_offset;
				wlan_wmm_add_buf_txqueue(pmadapter, newbuf);
				if (util_scalar_read(pmadapter->pmoal_handle,
						     &pmadapter->
						     pending_bridge_pkts,
						     pmadapter->callbacks.
						     moal_spin_lock,
						     pmadapter->callbacks.
						     moal_spin_unlock) >
				    RX_HIGH_THRESHOLD)
					wlan_drop_tx_pkts(priv);
				wlan_recv_event(priv,
						MLAN_EVENT_ID_DRV_DEFER_HANDLING,
						MNULL);
			}
		}
	} else {
		if ((!(priv->pkt_fwd & PKT_FWD_INTRA_UCAST)) &&
		    (wlan_get_station_entry
		     (priv, prx_pkt->eth803_hdr.dest_addr))) {
			/* Forwarding Intra-BSS packet */
			pmbuf->data_len -= prx_pd->rx_pkt_offset;
			pmbuf->data_offset += prx_pd->rx_pkt_offset;
			pmbuf->flags |= MLAN_BUF_FLAG_BRIDGE_BUF;
			util_scalar_increment(pmadapter->pmoal_handle,
					      &pmadapter->pending_bridge_pkts,
					      pmadapter->callbacks.
					      moal_spin_lock,
					      pmadapter->callbacks.
					      moal_spin_unlock);
			wlan_wmm_add_buf_txqueue(pmadapter, pmbuf);
			if (util_scalar_read(pmadapter->pmoal_handle,
					     &pmadapter->pending_bridge_pkts,
					     pmadapter->callbacks.
					     moal_spin_lock,
					     pmadapter->callbacks.
					     moal_spin_unlock) >
			    RX_HIGH_THRESHOLD)
				wlan_drop_tx_pkts(priv);
			wlan_recv_event(priv, MLAN_EVENT_ID_DRV_DEFER_HANDLING,
					MNULL);
			goto done;
		} else if (MLAN_STATUS_FAILURE ==
			   wlan_check_unicast_packet(priv,
						     prx_pkt->eth803_hdr.
						     dest_addr)) {
			PRINTM(MDATA, "Drop Pkts: Rx dest " MACSTR "\n",
			       MAC2STR(prx_pkt->eth803_hdr.dest_addr));
			pmbuf->status_code = MLAN_ERROR_PKT_INVALID;
			wlan_free_mlan_buffer(pmadapter, pmbuf);
			goto done;
		}
	}

upload:
	/* Chop off RxPD */
	pmbuf->data_len -= prx_pd->rx_pkt_offset;
	pmbuf->data_offset += prx_pd->rx_pkt_offset;
	pmbuf->pparent = MNULL;

	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) {
		PRINTM(MERROR,
		       "uAP Rx Error: moal_recv_packet returned error\n");
		pmbuf->status_code = MLAN_ERROR_PKT_INVALID;
	}

	if (ret != MLAN_STATUS_PENDING)
		wlan_free_mlan_buffer(pmadapter, pmbuf);
done:
	LEAVE();
	return ret;
}
Ejemplo n.º 4
0
/**
 *  @brief This function processes received packet and forwards it
 *          to kernel/upper layer or send back to firmware
 *
 *  @param priv      A pointer to mlan_private
 *  @param pmbuf     A pointer to mlan_buffer which includes the received packet
 *
 *  @return          MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
 */
mlan_status
wlan_uap_recv_packet(IN mlan_private *priv, IN pmlan_buffer pmbuf)
{
	pmlan_adapter pmadapter = priv->adapter;
	mlan_status ret = MLAN_STATUS_SUCCESS;
	RxPacketHdr_t *prx_pkt;
	pmlan_buffer newbuf = MNULL;

	ENTER();

	prx_pkt = (RxPacketHdr_t *)((t_u8 *)pmbuf->pbuf + pmbuf->data_offset);

	DBG_HEXDUMP(MDAT_D, "uap_recv_packet", pmbuf->pbuf + pmbuf->data_offset,
		    MIN(pmbuf->data_len, MAX_DATA_DUMP_LEN));

	PRINTM(MDATA, "AMSDU dest " MACSTR "\n",
	       MAC2STR(prx_pkt->eth803_hdr.dest_addr));

	/* don't do packet forwarding in disconnected state */
	if ((priv->media_connected == MFALSE) ||
	    (pmbuf->data_len > MV_ETH_FRAME_LEN))
		goto upload;

	if (prx_pkt->eth803_hdr.dest_addr[0] & 0x01) {
		if (!(priv->pkt_fwd & PKT_FWD_INTRA_BCAST)) {
			/* Multicast pkt */
			newbuf = wlan_alloc_mlan_buffer(pmadapter,
							MLAN_TX_DATA_BUF_SIZE_2K,
							0, MOAL_MALLOC_BUFFER);
			if (newbuf) {
				newbuf->bss_index = pmbuf->bss_index;
				newbuf->buf_type = pmbuf->buf_type;
				newbuf->priority = pmbuf->priority;
				newbuf->in_ts_sec = pmbuf->in_ts_sec;
				newbuf->in_ts_usec = pmbuf->in_ts_usec;
				newbuf->data_offset =
					(sizeof(UapTxPD) + INTF_HEADER_LEN +
					 DMA_ALIGNMENT);
				util_scalar_increment(pmadapter->pmoal_handle,
						      &pmadapter->
						      pending_bridge_pkts,
						      pmadapter->callbacks.
						      moal_spin_lock,
						      pmadapter->callbacks.
						      moal_spin_unlock);

				newbuf->flags |= MLAN_BUF_FLAG_BRIDGE_BUF;

				/* copy the data */
				memcpy(pmadapter,
				       (t_u8 *)newbuf->pbuf +
				       newbuf->data_offset,
				       pmbuf->pbuf + pmbuf->data_offset,
				       pmbuf->data_len);
				newbuf->data_len = pmbuf->data_len;
				wlan_wmm_add_buf_txqueue(pmadapter, newbuf);
				if (util_scalar_read(pmadapter->pmoal_handle,
						     &pmadapter->
						     pending_bridge_pkts,
						     pmadapter->callbacks.
						     moal_spin_lock,
						     pmadapter->callbacks.
						     moal_spin_unlock) >
				    RX_HIGH_THRESHOLD)
					wlan_drop_tx_pkts(priv);
				wlan_recv_event(priv,
						MLAN_EVENT_ID_DRV_DEFER_HANDLING,
						MNULL);
			}
		}
	} else {
		if ((!(priv->pkt_fwd & PKT_FWD_INTRA_UCAST)) &&
		    (wlan_get_station_entry
		     (priv, prx_pkt->eth803_hdr.dest_addr))) {
			/* Intra BSS packet */
			newbuf = wlan_alloc_mlan_buffer(pmadapter,
							MLAN_TX_DATA_BUF_SIZE_2K,
							0, MOAL_MALLOC_BUFFER);
			if (newbuf) {
				newbuf->bss_index = pmbuf->bss_index;
				newbuf->buf_type = pmbuf->buf_type;
				newbuf->priority = pmbuf->priority;
				newbuf->in_ts_sec = pmbuf->in_ts_sec;
				newbuf->in_ts_usec = pmbuf->in_ts_usec;
				newbuf->data_offset =
					(sizeof(UapTxPD) + INTF_HEADER_LEN +
					 DMA_ALIGNMENT);
				util_scalar_increment(pmadapter->pmoal_handle,
						      &pmadapter->
						      pending_bridge_pkts,
						      pmadapter->callbacks.
						      moal_spin_lock,
						      pmadapter->callbacks.
						      moal_spin_unlock);
				newbuf->flags |= MLAN_BUF_FLAG_BRIDGE_BUF;

				/* copy the data */
				memcpy(pmadapter,
				       (t_u8 *)newbuf->pbuf +
				       newbuf->data_offset,
				       pmbuf->pbuf + pmbuf->data_offset,
				       pmbuf->data_len);
				newbuf->data_len = pmbuf->data_len;
				wlan_wmm_add_buf_txqueue(pmadapter, newbuf);
				if (util_scalar_read(pmadapter->pmoal_handle,
						     &pmadapter->
						     pending_bridge_pkts,
						     pmadapter->callbacks.
						     moal_spin_lock,
						     pmadapter->callbacks.
						     moal_spin_unlock) >
				    RX_HIGH_THRESHOLD)
					wlan_drop_tx_pkts(priv);
				wlan_recv_event(priv,
						MLAN_EVENT_ID_DRV_DEFER_HANDLING,
						MNULL);
			}
			goto done;
		} else if (MLAN_STATUS_FAILURE ==
			   wlan_check_unicast_packet(priv,
						     prx_pkt->eth803_hdr.
						     dest_addr)) {
			/* drop packet */
			PRINTM(MDATA, "Drop AMSDU dest " MACSTR "\n",
			       MAC2STR(prx_pkt->eth803_hdr.dest_addr));
			goto done;
		}
	}
upload:
    /** send packet to moal */
	ret = pmadapter->callbacks.moal_recv_packet(pmadapter->pmoal_handle,
						    pmbuf);
done:
	LEAVE();
	return ret;
}
Ejemplo n.º 5
0
/**
 *  @brief This function processes received packet and forwards it
 *  		to kernel/upper layer or send back to firmware 
 *  
 *  @param priv      A pointer to mlan_private
 *  @param pmbuf     A pointer to mlan_buffer which includes the received packet
 *
 *  @return 	   MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
 */
mlan_status
wlan_process_uap_rx_packet(IN mlan_private * priv, IN pmlan_buffer pmbuf)
{
    pmlan_adapter pmadapter = priv->adapter;
    mlan_status ret = MLAN_STATUS_SUCCESS;
    UapRxPD *prx_pd;
    RxPacketHdr_t *prx_pkt;
    pmlan_buffer newbuf = MNULL;

    ENTER();

    prx_pd = (UapRxPD *) (pmbuf->pbuf + pmbuf->data_offset);
    prx_pkt = (RxPacketHdr_t *) ((t_u8 *) prx_pd + prx_pd->rx_pkt_offset);

    DBG_HEXDUMP(MDAT_D, "uAP RxPD", prx_pd,
                MIN(sizeof(UapRxPD), MAX_DATA_DUMP_LEN));
    DBG_HEXDUMP(MDAT_D, "uAP Rx Payload",
                ((t_u8 *) prx_pd + prx_pd->rx_pkt_offset),
                MIN(prx_pd->rx_pkt_length, MAX_DATA_DUMP_LEN));

    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);
    PRINTM(MDATA, "Rx dest %02x:%02x:%02x:%02x:%02x:%02x\n",
           prx_pkt->eth803_hdr.dest_addr[0], prx_pkt->eth803_hdr.dest_addr[1],
           prx_pkt->eth803_hdr.dest_addr[2], prx_pkt->eth803_hdr.dest_addr[3],
           prx_pkt->eth803_hdr.dest_addr[4], prx_pkt->eth803_hdr.dest_addr[5]);

    /* don't do packet forwarding in disconnected state */
    /* don't do packet forwarding when packet > 1514 */
    if ((priv->media_connected == MFALSE) ||
        ((pmbuf->data_len - prx_pd->rx_pkt_offset) > MV_ETH_FRAME_LEN))
        goto upload;

    if (prx_pkt->eth803_hdr.dest_addr[0] & 0x01) {
        /* Multicast pkt */
        if ((newbuf =
             wlan_alloc_mlan_buffer(pmadapter, MLAN_TX_DATA_BUF_SIZE_2K, 0,
                                    MTRUE))) {
            newbuf->bss_index = pmbuf->bss_index;
            newbuf->buf_type = pmbuf->buf_type;
            newbuf->priority = pmbuf->priority;
            newbuf->in_ts_sec = pmbuf->in_ts_sec;
            newbuf->in_ts_usec = pmbuf->in_ts_usec;
            newbuf->data_offset =
                (sizeof(UapTxPD) + INTF_HEADER_LEN + DMA_ALIGNMENT);
            pmadapter->pending_bridge_pkts++;
            newbuf->flags |= MLAN_BUF_FLAG_BRIDGE_BUF;

            /* copy the data, skip rxpd */
            memcpy(pmadapter, (t_u8 *) newbuf->pbuf + newbuf->data_offset,
                   pmbuf->pbuf + pmbuf->data_offset + prx_pd->rx_pkt_offset,
                   pmbuf->data_len - prx_pd->rx_pkt_offset);
            newbuf->data_len = pmbuf->data_len - prx_pd->rx_pkt_offset;
            wlan_wmm_add_buf_txqueue(pmadapter, newbuf);
            if (pmadapter->pending_bridge_pkts > RX_HIGH_THRESHOLD)
                wlan_drop_tx_pkts(priv);
        }
    } else {
        if (wlan_get_station_entry(priv, prx_pkt->eth803_hdr.dest_addr)) {
            /* Forwarding Intra-BSS packet */
            pmbuf->data_len -= prx_pd->rx_pkt_offset;
            pmbuf->data_offset += prx_pd->rx_pkt_offset;
            pmbuf->flags |= MLAN_BUF_FLAG_BRIDGE_BUF;
            pmadapter->pending_bridge_pkts++;
            wlan_wmm_add_buf_txqueue(pmadapter, pmbuf);
            if (pmadapter->pending_bridge_pkts > RX_HIGH_THRESHOLD)
                wlan_drop_tx_pkts(priv);
            pmadapter->callbacks.moal_recv_complete(pmadapter->pmoal_handle,
                                                    MNULL,
                                                    MLAN_USB_EP_DATA, ret);
            goto done;
        }
    }
  upload:
    /* Chop off RxPD */
    pmbuf->data_len -= prx_pd->rx_pkt_offset;
    pmbuf->data_offset += prx_pd->rx_pkt_offset;
    pmbuf->pparent = MNULL;

    pmadapter->callbacks.moal_get_system_time(pmadapter->pmoal_handle,
                                              &pmbuf->out_ts_sec,
                                              &pmbuf->out_ts_usec);
    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) {
        PRINTM(MERROR, "uAP Rx Error: moal_recv_packet returned error\n");
        pmbuf->status_code = MLAN_ERROR_PKT_INVALID;
    }

    if (ret != MLAN_STATUS_PENDING) {
        pmadapter->callbacks.moal_recv_complete(pmadapter->pmoal_handle, pmbuf,
                                                MLAN_USB_EP_DATA, ret);
    }
  done:
    LEAVE();
    return ret;
}
Ejemplo n.º 6
0
/**
 *  @brief This function processes received packet and forwards it
 *  		to kernel/upper layer or send back to firmware 
 *  
 *  @param priv      A pointer to mlan_private
 *  @param pmbuf     A pointer to mlan_buffer which includes the received packet
 *
 *  @return 	   MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
 */
mlan_status
wlan_uap_recv_packet(IN mlan_private * priv, IN pmlan_buffer pmbuf)
{
    pmlan_adapter pmadapter = priv->adapter;
    mlan_status ret = MLAN_STATUS_SUCCESS;
    RxPacketHdr_t *prx_pkt;
    pmlan_buffer newbuf = MNULL;

    ENTER();

    prx_pkt = (RxPacketHdr_t *) ((t_u8 *) pmbuf->pbuf + pmbuf->data_offset);

    DBG_HEXDUMP(MDAT_D, "uap_recv_packet", pmbuf->pbuf + pmbuf->data_offset,
                MIN(pmbuf->data_len, MAX_DATA_DUMP_LEN));

    PRINTM(MDATA, "AMSDU dest %02x:%02x:%02x:%02x:%02x:%02x\n",
           prx_pkt->eth803_hdr.dest_addr[0], prx_pkt->eth803_hdr.dest_addr[1],
           prx_pkt->eth803_hdr.dest_addr[2], prx_pkt->eth803_hdr.dest_addr[3],
           prx_pkt->eth803_hdr.dest_addr[4], prx_pkt->eth803_hdr.dest_addr[5]);

    /* don't do packet forwarding in disconnected state */
    if ((priv->media_connected == MFALSE) ||
        (pmbuf->data_len > MV_ETH_FRAME_LEN))
        goto upload;

    if (prx_pkt->eth803_hdr.dest_addr[0] & 0x01) {
        /* Multicast pkt */
        if ((newbuf =
             wlan_alloc_mlan_buffer(pmadapter, MLAN_TX_DATA_BUF_SIZE_2K, 0,
                                    MTRUE))) {
            newbuf->bss_index = pmbuf->bss_index;
            newbuf->buf_type = pmbuf->buf_type;
            newbuf->priority = pmbuf->priority;
            newbuf->in_ts_sec = pmbuf->in_ts_sec;
            newbuf->in_ts_usec = pmbuf->in_ts_usec;
            newbuf->data_offset =
                (sizeof(UapTxPD) + INTF_HEADER_LEN + DMA_ALIGNMENT);
            pmadapter->pending_bridge_pkts++;
            newbuf->flags |= MLAN_BUF_FLAG_BRIDGE_BUF;

            /* copy the data */
            memcpy(pmadapter, (t_u8 *) newbuf->pbuf + newbuf->data_offset,
                   pmbuf->pbuf + pmbuf->data_offset, pmbuf->data_len);
            newbuf->data_len = pmbuf->data_len;
            wlan_wmm_add_buf_txqueue(pmadapter, newbuf);
            if (pmadapter->pending_bridge_pkts > RX_HIGH_THRESHOLD)
                wlan_drop_tx_pkts(priv);
        }
    } else {
        if (wlan_get_station_entry(priv, prx_pkt->eth803_hdr.dest_addr)) {
            /* Intra BSS packet */
            if ((newbuf =
                 wlan_alloc_mlan_buffer(pmadapter, MLAN_TX_DATA_BUF_SIZE_2K, 0,
                                        MTRUE))) {
                newbuf->bss_index = pmbuf->bss_index;
                newbuf->buf_type = pmbuf->buf_type;
                newbuf->priority = pmbuf->priority;
                newbuf->in_ts_sec = pmbuf->in_ts_sec;
                newbuf->in_ts_usec = pmbuf->in_ts_usec;
                newbuf->data_offset =
                    (sizeof(UapTxPD) + INTF_HEADER_LEN + DMA_ALIGNMENT);
                pmadapter->pending_bridge_pkts++;
                newbuf->flags |= MLAN_BUF_FLAG_BRIDGE_BUF;

                /* copy the data */
                memcpy(pmadapter, (t_u8 *) newbuf->pbuf + newbuf->data_offset,
                       pmbuf->pbuf + pmbuf->data_offset, pmbuf->data_len);
                newbuf->data_len = pmbuf->data_len;
                wlan_wmm_add_buf_txqueue(pmadapter, newbuf);
                if (pmadapter->pending_bridge_pkts > RX_HIGH_THRESHOLD)
                    wlan_drop_tx_pkts(priv);
            }
            goto done;
        }
    }
  upload:
    /** send packet to moal */
    ret = pmadapter->callbacks.moal_recv_packet(pmadapter->pmoal_handle, pmbuf);
  done:
    LEAVE();
    return ret;
}