software/drivers/sd8887/src/wlan/mapp/mlanutl/mlanoffload.c
/**
 *  @brief Issue a measurement timing command
 *
 *  @param argc     number of arguments
 *  @param argv     A pointer to arguments array
 *
 *  @return         MLAN_STATUS_SUCCESS--success, otherwise--fail
 */
@brief Issue a measurement timing command
@param argc     number of arguments
@param argv     A pointer to arguments array


@brief Issue a measurement timing command @param argc number of arguments @param argv A pointer to arguments array
int
process_measurement(int argc, char *argv[])
{
	int ret = 0;
	struct ifreq ifr;
	t_u8 *buffer = NULL, *pos = NULL;
	t_u32 cmd_len = 0, cmd_header_len;
	struct eth_priv_cmd *cmd = NULL;
	HostCmd_DS_GEN *hostcmd = NULL;
	HostCmd_DS_MEASUREMENT_Timing *timing_cmd = NULL;
	MrvlIETypes_MeasTiming_t *timing_tlv = NULL;
	int idx, rsp_len;
	t_u8 sel = 0;
	t_u16 tlv_len = 0;
	timing_sel_t sel_str[] = { {"disconnected", 1},
	{"adhoc", 1},
	{"fullpower", 1},
	{"ieeeps", 1},
	{"periodic", 1}
	};
	if ((argc < 4) || strncmp(argv[3], "timing",
				  MAX(strlen("timing"), strlen(argv[3])))) {
		printf("\nUnknown %s command. Valid subcmd: timing \n",
		       argv[2]);
		return MLAN_STATUS_FAILURE;
	}
	cmd_header_len = strlen(CMD_NXP) + strlen(HOSTCMD);
	cmd_len = S_DS_GEN + sizeof(t_u16);
	buffer = (t_u8 *)malloc(BUFFER_LENGTH);
	if (buffer == NULL) {
		fprintf(stderr, "Cannot alloc memory\n");
		return -ENOMEM;
	}
	memset(buffer, 0, BUFFER_LENGTH);
	cmd = (struct eth_priv_cmd *)malloc(sizeof(struct eth_priv_cmd));
	if (!cmd) {
		printf("ERR:Cannot allocate buffer for command!\n");
		free(buffer);
		return -ENOMEM;
	}
#ifdef USERSPACE_32BIT_OVER_KERNEL_64BIT
	memset(cmd, 0, sizeof(struct eth_priv_cmd));
	memcpy(&cmd->buf, &buffer, sizeof(buffer));
#else
	cmd->buf = buffer;
#endif
	cmd->used_len = 0;
	cmd->total_len = BUFFER_LENGTH;
	strncpy((char *)buffer, CMD_NXP, strlen(CMD_NXP));
	strncpy((char *)buffer + strlen(CMD_NXP), HOSTCMD, strlen(HOSTCMD));
	hostcmd = (HostCmd_DS_GEN *)(buffer + cmd_header_len + sizeof(t_u32));
	hostcmd->command = cpu_to_le16(HostCmd_CMD_MEASUREMENT_TIMING_CONFIG);
	hostcmd->size = cmd_len;
	hostcmd->seq_num = 0;
	hostcmd->result = 0;
	pos = (t_u8 *)hostcmd + S_DS_GEN;
	timing_cmd = (HostCmd_DS_MEASUREMENT_Timing *)pos;
	timing_cmd->action = cpu_to_le16(HostCmd_ACT_GEN_GET);
	timing_tlv = (MrvlIETypes_MeasTiming_t *)timing_cmd->tlv_buffer;
	if (argc == 7) {
		timing_cmd->action = cpu_to_le16(HostCmd_ACT_GEN_SET);
		timing_tlv->header.type =
			cpu_to_le16(TLV_TYPE_MEASUREMENT_TIMING);
		timing_tlv->header.len =
			cpu_to_le16(sizeof(MrvlIETypes_MeasTiming_t)
				    - sizeof(timing_tlv->header));
		for (idx = 1; (unsigned int)idx < NELEMENTS(sel_str); idx++) {
			if (strncmp
			    (argv[4], sel_str[idx].str,
			     sel_str[idx].match_len) == 0) {
				sel = idx + 1;
				break;
			}
		}
		if (idx == NELEMENTS(sel_str)) {
			printf("Wrong argument for mode selected \"%s\"\n",
			       argv[4]);
			ret = -EINVAL;
			goto done;
		}
		timing_tlv->mode = cpu_to_le32(sel);
		timing_tlv->max_off_channel = cpu_to_le32(atoi(argv[5]));
		timing_tlv->max_on_channel = cpu_to_le32(atoi(argv[6]));
		cmd_len += sizeof(MrvlIETypes_MeasTiming_t);
	}
	memcpy(buffer + cmd_header_len, &cmd_len, sizeof(t_u32));
	hostcmd->size = cpu_to_le16(cmd_len);
	memset(&ifr, 0, sizeof(ifr));
	strncpy(ifr.ifr_ifrn.ifrn_name, dev_name, strlen(dev_name));
	ifr.ifr_ifru.ifru_data = (void *)cmd;
	if (ioctl(sockfd, MLAN_ETH_PRIV, &ifr)) {
		perror("ioctl[measurement timing ioctl]");
		printf("ERR:Command sending failed!\n");
		ret = -EFAULT;
		goto done;
	}
	printf("--------------------------------------------------\n");
	printf("%44s\n", "Measurement Timing Profiles (in ms)");
	printf("--------------------------------------------------\n");
	printf("     Profile    |  MaxOffChannel |  MaxOnChannel\n");
	printf("--------------------------------------------------\n");
	rsp_len = le16_to_cpu(hostcmd->size);
	rsp_len -= (S_DS_GEN + sizeof(t_u16));
	pos = (t_u8 *)hostcmd + S_DS_GEN + sizeof(t_u16);
	while ((unsigned int)rsp_len > sizeof(MrvlIEtypesHeader_t)) {
		switch (le16_to_cpu(*(t_u16 *)(pos))) {
		case TLV_TYPE_MEASUREMENT_TIMING:
			timing_tlv = (MrvlIETypes_MeasTiming_t *)pos;
			tlv_len = le16_to_cpu(timing_tlv->header.len);
			printf("%15s | %14d | %13d\n",
			       sel_str[le32_to_cpu(timing_tlv->mode) - 1].str,
			       (int)le32_to_cpu(timing_tlv->max_off_channel),
			       (int)le32_to_cpu(timing_tlv->max_on_channel));
			break;
		}
		pos += tlv_len + sizeof(MrvlIEtypesHeader_t);
		rsp_len -= tlv_len + sizeof(MrvlIEtypesHeader_t);
		rsp_len = (rsp_len > 0) ? rsp_len : 0;
	}
	printf("\n");
done:
	if (buffer)
		free(buffer);
	if (cmd)
		free(cmd);
	return ret;
}
int process_measurement ( int argc , char * argv [ ] ) { int ret = 0 ; struct ifreq ifr ; t_u8 * buffer = NULL , * pos = NULL ; t_u32 cmd_len = 0 , cmd_header_len ; struct eth_priv_cmd * cmd = NULL ; HostCmd_DS_GEN * hostcmd = NULL ; HostCmd_DS_MEASUREMENT_Timing * timing_cmd = NULL ; MrvlIETypes_MeasTiming_t * timing_tlv = NULL ; int idx , rsp_len ; t_u8 sel = 0 ; t_u16 tlv_len = 0 ; timing_sel_t sel_str [ ] = { { " " , 1 } , { " " , 1 } , { " " , 1 } , { " " , 1 } , { " " , 1 } } ; if ( ( argc < 4 ) || strncmp ( argv [ 3 ] , " " , MAX ( strlen ( " " ) , strlen ( argv [ 3 ] ) ) ) ) { printf ( " \n \n " , argv [ 2 ] ) ; return MLAN_STATUS_FAILURE ; } cmd_header_len = strlen ( CMD_NXP ) + strlen ( HOSTCMD ) ; cmd_len = S_DS_GEN + sizeof ( t_u16 ) ; buffer = ( t_u8 * ) malloc ( BUFFER_LENGTH ) ; if ( buffer == NULL ) { fprintf ( stderr , " \n " ) ; return - ENOMEM ; } memset ( buffer , 0 , BUFFER_LENGTH ) ; cmd = ( struct eth_priv_cmd * ) malloc ( sizeof ( struct eth_priv_cmd ) ) ; if ( ! cmd ) { printf ( " \n " ) ; free ( buffer ) ; return - ENOMEM ; } #ifdef USERSPACE_32BIT_OVER_KERNEL_64BIT memset ( cmd , 0 , sizeof ( struct eth_priv_cmd ) ) ; memcpy ( & cmd -> buf , & buffer , sizeof ( buffer ) ) ; #else cmd -> buf = buffer ; #endif cmd -> used_len = 0 ; cmd -> total_len = BUFFER_LENGTH ; strncpy ( ( char * ) buffer , CMD_NXP , strlen ( CMD_NXP ) ) ; strncpy ( ( char * ) buffer + strlen ( CMD_NXP ) , HOSTCMD , strlen ( HOSTCMD ) ) ; hostcmd = ( HostCmd_DS_GEN * ) ( buffer + cmd_header_len + sizeof ( t_u32 ) ) ; hostcmd -> command = cpu_to_le16 ( HostCmd_CMD_MEASUREMENT_TIMING_CONFIG ) ; hostcmd -> size = cmd_len ; hostcmd -> seq_num = 0 ; hostcmd -> result = 0 ; pos = ( t_u8 * ) hostcmd + S_DS_GEN ; timing_cmd = ( HostCmd_DS_MEASUREMENT_Timing * ) pos ; timing_cmd -> action = cpu_to_le16 ( HostCmd_ACT_GEN_GET ) ; timing_tlv = ( MrvlIETypes_MeasTiming_t * ) timing_cmd -> tlv_buffer ; if ( argc == 7 ) { timing_cmd -> action = cpu_to_le16 ( HostCmd_ACT_GEN_SET ) ; timing_tlv -> header . type = cpu_to_le16 ( TLV_TYPE_MEASUREMENT_TIMING ) ; timing_tlv -> header . len = cpu_to_le16 ( sizeof ( MrvlIETypes_MeasTiming_t ) - sizeof ( timing_tlv -> header ) ) ; for ( idx = 1 ; ( unsigned int ) idx < NELEMENTS ( sel_str ) ; idx ++ ) { if ( strncmp ( argv [ 4 ] , sel_str [ idx ] . str , sel_str [ idx ] . match_len ) == 0 ) { sel = idx + 1 ; break ; } } if ( idx == NELEMENTS ( sel_str ) ) { printf ( " \" \" \n " , argv [ 4 ] ) ; ret = - EINVAL ; goto done ; } timing_tlv -> mode = cpu_to_le32 ( sel ) ; timing_tlv -> max_off_channel = cpu_to_le32 ( atoi ( argv [ 5 ] ) ) ; timing_tlv -> max_on_channel = cpu_to_le32 ( atoi ( argv [ 6 ] ) ) ; cmd_len += sizeof ( MrvlIETypes_MeasTiming_t ) ; } memcpy ( buffer + cmd_header_len , & cmd_len , sizeof ( t_u32 ) ) ; hostcmd -> size = cpu_to_le16 ( cmd_len ) ; memset ( & ifr , 0 , sizeof ( ifr ) ) ; strncpy ( ifr . ifr_ifrn . ifrn_name , dev_name , strlen ( dev_name ) ) ; ifr . ifr_ifru . ifru_data = ( void * ) cmd ; if ( ioctl ( sockfd , MLAN_ETH_PRIV , & ifr ) ) { perror ( " " ) ; printf ( " \n " ) ; ret = - EFAULT ; goto done ; } printf ( " \n " ) ; printf ( " \n " , " " ) ; printf ( " \n " ) ; printf ( " \n " ) ; printf ( " \n " ) ; rsp_len = le16_to_cpu ( hostcmd -> size ) ; rsp_len -= ( S_DS_GEN + sizeof ( t_u16 ) ) ; pos = ( t_u8 * ) hostcmd + S_DS_GEN + sizeof ( t_u16 ) ; while ( ( unsigned int ) rsp_len > sizeof ( MrvlIEtypesHeader_t ) ) { switch ( le16_to_cpu ( * ( t_u16 * ) ( pos ) ) ) { case TLV_TYPE_MEASUREMENT_TIMING : timing_tlv = ( MrvlIETypes_MeasTiming_t * ) pos ; tlv_len = le16_to_cpu ( timing_tlv -> header . len ) ; printf ( " \n " , sel_str [ le32_to_cpu ( timing_tlv -> mode ) - 1 ] . str , ( int ) le32_to_cpu ( timing_tlv -> max_off_channel ) , ( int ) le32_to_cpu ( timing_tlv -> max_on_channel ) ) ; break ; } pos += tlv_len + sizeof ( MrvlIEtypesHeader_t ) ; rsp_len -= tlv_len + sizeof ( MrvlIEtypesHeader_t ) ; rsp_len = ( rsp_len > 0 ) ? rsp_len : 0 ; } printf ( " \n " ) ; done : if ( buffer ) free ( buffer ) ; if ( cmd ) free ( cmd ) ; return ret ; }
@brief Issue a measurement timing command
  @param argc     number of arguments
  @param argv     A pointer to arguments array
@brief Issue a measurement timing command @param argc number of arguments @param argv A pointer to arguments array
/* Fill up buffer */ /* buffer = MRVL_CMD<cmd> */ /* buffer = MRVL_CMD<cmd><hostcmd_size><HostCmd_DS_GEN><CMD_DS> */ /* Point after host command header */ /* Put buffer length */ /* Initialize the ifr structure */ /* Perform ioctl */ /* Changed to TLV parsing */