Beispiel #1
0
/*************************************************************************
* FUNCTION
*  void ccci_boottrc_send_log
*
* DESCRIPTION
*  This function is exported API to write bootup trace log in shared buffer.
*
* PARAMETERS
*  index - bootup trace log key.
*  value - bootup trace log value.
*
* RETURNS
*  NA
*
*************************************************************************/
void ccci_boottrc_send_log(kal_uint32 index, kal_uint32 value)
{
#if defined(__MTK_TARGET__)
#ifdef __boottrc_performance_measurement__
	kal_uint32 ccci_boottrc_start_time =0;
	kal_uint32 ccci_boottrc_end_time =0;
	kal_uint32 ccci_boottrc_dur_time =0;
	ccci_boottrc_start_time = ccci_get_current_time();
#endif

	qbm_gpd    	*p_gpd;
    void       	*p_cache_aligned;
	CCCI_BUFF_T	*ccci_buff;
	kal_bool    hif_ret;

	p_cache_aligned = ccci_boottrc_gpd;
	if((kal_uint32)p_cache_aligned&CPU_CACHE_LINE_SIZE_MASK) { 
		p_cache_aligned = (void *)((kal_uint32)(ccci_boottrc_gpd)&~CPU_CACHE_LINE_SIZE_MASK);
		p_cache_aligned += CPU_CACHE_LINE_SIZE;
	}
	p_gpd = (qbm_gpd *)p_cache_aligned;
	
	//kal_mem_set(ccci_hs_buff, 0, CCCI_POLLING_MODE_BUF_SZ);
	/* CCCI polling mode, QMU_BM is not ready yet*/ 
	/* format ccci_hs_buff as GPD->BUFF format */
	CCCI_INIT_RESET_DATALEN_EXTLEN((kal_uint32 *)p_gpd);
	CCCI_INIT_RESET_COMMON_DATA((kal_uint32 *)p_gpd);
	ccci_buff = QBM_DES_GET_DATAPTR(p_gpd);
	ccci_buff->data[0] = 0x43525442; // pattern : "BTRC"
	ccci_buff->data[1] = index;
	ccci_buff->channel = CCCI_CONTROL_CHANNEL;
	ccci_buff->reserved = value;
    ccci_debug_add_seq(ccci_buff, CCCI_DEBUG_ASSERT_BIT); // add ccci seq
	QBM_DES_SET_DATALEN(p_gpd, sizeof(CCCI_BUFF_T));
	QBM_CACHE_FLUSH(ccci_buff, sizeof(CCCI_BUFF_T));
    
#if defined(__HIF_SDIO_SUPPORT__)
    hif_ret = hifsdio_simple_send_gpd(0, p_gpd, CCCI_HS_POLLING_TIMEOUT);
#elif defined(__HIF_CLDMA_SUPPORT__)
    hif_ret = hifcldma_simple_send_gpd(0, p_gpd, CCCI_HS_POLLING_TIMEOUT);
#elif defined(__CCIFCORE_SUPPORT__)
    hif_ret = ccifc_simple_send_gpd(0, p_gpd, CCCI_HS_POLLING_TIMEOUT);
#endif

	if(!hif_ret){
		EXT_ASSERT(KAL_FALSE, hif_ret,0,0);
	}

#ifdef __boottrc_performance_measurement__
	ccci_boottrc_end_time = ccci_get_current_time();
	ccci_boottrc_dur_time = ccci_get_duration(ccci_boottrc_start_time,ccci_boottrc_end_time);
	ccci_boottrc_max_transmit_time = (ccci_boottrc_dur_time > ccci_boottrc_max_transmit_time)? ccci_boottrc_dur_time : ccci_boottrc_max_transmit_time;
	ccci_boottrc_min_transmit_time = (ccci_boottrc_dur_time < ccci_boottrc_min_transmit_time)? ccci_boottrc_dur_time : ccci_boottrc_min_transmit_time;
	ccci_boottrc_total_transmit_time += ccci_boottrc_dur_time;
	ccci_boottrc_transmit_count++;
	ccci_boottrc_avg_transmit_time = ccci_boottrc_total_transmit_time / ccci_boottrc_transmit_count; 
	// write to share memory
	ccci_excep_dbg_logging_InHS2(CCCI_EXCEP_DBG_HS_BOOTTRC_WAIT_TIME, (void *)&ccci_boottrc_total_transmit_time);
#endif
#endif
}
/*!
 * Callback function with packet information to process the IP datagram filtered.
 * Reply TCP RST packet to the sender of the garbage TCP SYN packet.
 *
 * @param   info_p [IN] Related information of filtered out GPDs.
 * @param   context [IN] A context specified while registering the filter.
 * @param   filter_id [IN] Corresponding registered filter ID.
 * @param   head_gpd [IN] Pointer head of the GPD list for the IP datagram filtered.
 * @param   tail_gpd [IN] Pointer tail of the GPD list for the IP datagram filtered.
 * @param   length [IN] Bytes of buffers used in the GPD list.
 */
void pfm_ipc_dl_filter_with_info_cb(
    ipc_filter_info_t      *info_p,
    void                   *context,
    kal_int32               filter_id,
    qbm_gpd                *head_gpd,
    qbm_gpd                *tail_gpd,
    kal_uint32              length)
{
    ipc_pkt_t       ipc_pkt;
    qbm_gpd        *ul_gpd;
    qbm_gpd        *bd;
    kal_uint8      *p_data;
    kal_uint8       next_header;
    kal_uint8      *p_packet;
    kal_uint8      *src_addr;
    kal_uint8      *dst_addr;
    kal_uint8      *p_tcp_header;
    kal_uint32      ip_header_len;
    kal_bool        is_ipv4;

    if (QBM_DES_GET_BDP(head_gpd)) {
        bd = QBM_DES_GET_DATAPTR(head_gpd);
        p_packet = QBM_DES_GET_DATAPTR(bd);
    } else {
        p_packet = QBM_DES_GET_DATAPTR(head_gpd);
    }

    if (IPC_HDR_IS_V4(p_packet)) {
        is_ipv4 = KAL_TRUE;

        if (IPC_HDR_PROT_TCP != IPC_HDR_V4_GET_PROTOCOL(p_packet)) {
            /* Only For TCP packet */
            goto free_gpd;
        }

        /* Send IPv4 TCP RST */
        ip_header_len = (kal_uint32)IPC_HDR_V4_GET_IHL(p_packet);
        p_tcp_header = p_packet + ip_header_len;

        src_addr = IPC_HDR_V4_GET_DST_ADDR(p_packet);
        dst_addr = IPC_HDR_V4_GET_SRC_ADDR(p_packet);
    } else if (IPC_HDR_IS_V6(p_packet)) {
        is_ipv4 = KAL_FALSE;

        /* Check if it's TCP or not */
        ip_header_len = IPC_HDR_V6_HEADER_SIZE; // fix
        next_header = IPC_HDR_V6_GET_NH_TYPE(p_packet);
        p_tcp_header = p_packet + ip_header_len;
        while (1) {
            if ((next_header == IPC_HDR_PROT_IPV6_HOP) ||
                (next_header == IPC_HDR_PROT_IPV6_ROUTE) ||
                (next_header == IPC_HDR_PROT_IPV6_DEST)) {

                // next header
                next_header = IPC_NE_GET_1B(p_tcp_header);
                // move pointer to next ext header
                p_tcp_header += (IPC_NE_GET_1B(p_tcp_header + 1) + 1)*8;
            } else if (next_header == IPC_HDR_PROT_AH) {

                // next header
                next_header = IPC_NE_GET_1B(p_tcp_header);
                // move pointer to next ext header
                p_tcp_header += (IPC_NE_GET_1B(p_tcp_header + 1) + 2)*4;
            } else if (next_header == IPC_HDR_PROT_TCP) {
                /* Found TCP header ! */
                break;
            } else {
                goto free_gpd;
            }
        }

        src_addr = IPC_HDR_V6_GET_DST_ADDR(p_packet);
        dst_addr = IPC_HDR_V6_GET_SRC_ADDR(p_packet);
    } else {
        goto free_gpd;
    }

    /* Allocate a UL GPD */
    ul_gpd = QBM_ALLOC_ONE(QBM_TYPE_HIF_UL_TYPE);
    if (!ul_gpd) {
        PFM_ASSERT(KAL_FALSE);
    }

    bd = QBM_DES_GET_DATAPTR(ul_gpd);
    p_data = QBM_DES_GET_DATAPTR(bd);

    /* Fill IP/TCP header */
    {
        kal_uint16          sum16;
        kal_uint32          tcp_header_len;
        kal_uint32          total_len;
        kal_uint8           *ip_header;     // ip_header for output packet
        kal_uint8           *tcp_header;    // tcp_header for output packet

        ip_header_len = ((is_ipv4) ? IPC_HDR_V4_HEADER_SIZE : IPC_HDR_V6_HEADER_SIZE);
        tcp_header_len = IPC_HDR_TCP_HEADER_SIZE;
        total_len = ip_header_len + tcp_header_len;

        ip_header = p_data;
        tcp_header = ip_header + ip_header_len;

        /* Fill TCP header */
        IPC_HDR_TCP_SET_SRC_PORT(tcp_header, IPC_HDR_TCP_GET_DST_PORT(p_tcp_header));
        IPC_HDR_TCP_SET_DST_PORT(tcp_header, IPC_HDR_TCP_GET_SRC_PORT(p_tcp_header));
        IPC_HDR_TCP_SET_SEQ_NUM(tcp_header, IPC_HDR_TCP_GET_ACK_NUM(p_tcp_header));
        IPC_HDR_TCP_SET_ACK_NUM(tcp_header, IPC_HDR_TCP_GET_SEQ_NUM(p_tcp_header) + 1);
        IPC_HDR_TCP_SET_OFFSET(tcp_header, IPC_HDR_TCP_HEADER_SIZE);
        IPC_HDR_TCP_SET_RESERVED(tcp_header, 0);
        IPC_HDR_TCP_SET_FLAGS(tcp_header, IPC_HDR_TCP_FLAG_RST | IPC_HDR_TCP_FLAG_ACK);
        IPC_HDR_TCP_SET_WINDOW(tcp_header, 0);
        IPC_HDR_TCP_SET_CHECKSUM(tcp_header, 0);
        IPC_HDR_TCP_SET_URGENT_PTR(tcp_header, 0);
        sum16 = ipc_calc_tcp_checksum(  is_ipv4,
                                        src_addr,
                                        dst_addr,
                                        tcp_header,
                                        tcp_header_len);
        IPC_HDR_TCP_SET_CHECKSUM(tcp_header, sum16);

        if (is_ipv4) {
            IPC_HDR_V4_RESET_VER_IHL_DSCP_ECN(ip_header);
            IPC_HDR_V4_SET_DSCP(ip_header, IPC_HDR_V4_GET_DSCP(p_packet));
            IPC_HDR_V4_SET_TOTAL_LENGTH(ip_header, total_len);
            IPC_HDR_V4_SET_IDENTITY(ip_header, 0);
            IPC_HDR_V4_SET_FLAGS(ip_header, 0);
            IPC_HDR_V4_SET_FRAG_OFFSET(ip_header, 0);
            IPC_HDR_V4_SET_TTL(ip_header, IPC_DEF_TTL);
            IPC_HDR_V4_SET_PROTOCOL(ip_header, IPC_HDR_PROT_TCP);
            IPC_HDR_V4_SET_HEADER_CHECKSUM(ip_header, 0);
            IPC_HDR_V4_SET_SRC_ADDR(ip_header, src_addr);
            IPC_HDR_V4_SET_DST_ADDR(ip_header, dst_addr);
            sum16 = ipc_calc_ipv4_checksum(ip_header);
            IPC_HDR_V4_SET_HEADER_CHECKSUM(ip_header, sum16);
        } else {
            IPC_HDR_V6_RESET_VER_TC_FL(ip_header);
            IPC_HDR_V6_SET_TC(ip_header, IPC_HDR_V6_GET_TC(p_packet));
            IPC_HDR_V6_SET_LENGTH(ip_header, total_len - ip_header_len/* TCP length */);
            IPC_HDR_V6_SET_NH_TYPE(ip_header, IPC_HDR_PROT_TCP);
            IPC_HDR_V6_SET_HOP_LIMIT(ip_header, IPC_DEF_TTL);
            IPC_HDR_V6_SET_SRC_ADDR(ip_header, src_addr);
            IPC_HDR_V6_SET_DST_ADDR(ip_header, dst_addr);
        }

        QBM_CACHE_FLUSH(ip_header, total_len);

        QBM_DES_SET_DATALEN(bd, total_len);
        qbm_cal_set_checksum(bd);

        QBM_DES_SET_DATALEN(ul_gpd, total_len);
        qbm_cal_set_checksum(ul_gpd);
    }

    kal_mem_set(&ipc_pkt, 0, sizeof(ipc_pkt));
    ipc_pkt.isGPD = KAL_TRUE;
    ipc_pkt.head = ul_gpd;
    ipc_pkt.tail = ul_gpd;
    ipc_send_ul_pkt(&ipc_pkt, NULL, info_p->ebi);

    hif_trace_info(PFM_TR_GARBAGE_FILTER_REPLY_RST, 0, IPC_HDR_TCP_GET_DST_PORT(p_tcp_header));

free_gpd:
    pfm_drop_packet_trace(info_p->ebi, p_packet, PFM_DROP_PACKET_DUMP_SIZE);
    qbmt_dest_q(head_gpd, tail_gpd);
}