예제 #1
0
파일: fw.c 프로젝트: Yomi0/rtlwifi_new
static bool _rtl92s_firmware_downloadcode(struct ieee80211_hw *hw,
		u8 *code_virtual_address, u32 buffer_len)
{
	struct rtl_priv *rtlpriv = rtl_priv(hw);
	struct sk_buff *skb;
	struct rtl_tcb_desc *tcb_desc;
	unsigned char *seg_ptr;
	u16 frag_threshold = MAX_FIRMWARE_CODE_SIZE;
	u16 frag_length, frag_offset = 0;
	u16 extra_descoffset = 0;
	u8 blast_inipkt = 0;

	_rtl92s_fw_set_rqpn(hw);

	if (buffer_len >= MAX_FIRMWARE_CODE_SIZE) {
		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
			"Size over FIRMWARE_CODE_SIZE!\n");

		return false;
	}

	extra_descoffset = 0;

	do {
		if ((buffer_len - frag_offset) > frag_threshold) {
			frag_length = frag_threshold + extra_descoffset;
		} else {
			frag_length = (u16)(buffer_len -
				frag_offset + extra_descoffset);
			blast_inipkt = 1;
		}

		/* Allocate skb buffer to contain firmware */
		/* info and tx descriptor info. */
		skb = dev_alloc_skb(frag_length);
		skb_reserve(skb, extra_descoffset);
		seg_ptr = (u8 *)skb_put(skb,
			(u32)(frag_length - extra_descoffset));
		memcpy(seg_ptr,
			code_virtual_address + frag_offset,
			(u32)(frag_length - extra_descoffset));

		tcb_desc = (struct rtl_tcb_desc *)(skb->cb);
		tcb_desc->queue_index = TXCMD_QUEUE;
		tcb_desc->cmd_or_init = DESC_PACKET_TYPE_INIT;
		tcb_desc->last_inipkt = blast_inipkt;

		_rtl92s_cmd_send_packet(hw, skb, blast_inipkt);

		frag_offset += (frag_length - extra_descoffset);

	} while (frag_offset < buffer_len);

	rtl_write_byte(rtlpriv, TP_POLL, TPPOLL_CQ);

	return true;
}
예제 #2
0
파일: fw.c 프로젝트: kyalipay/rtl8192su
static int _rtl92s_firmware_downloadcode(struct ieee80211_hw *hw,
		u8 *code_virtual_address, u32 buffer_len)
{
	struct rtl_priv *rtlpriv = rtl_priv(hw);
	struct sk_buff *skb;
	struct rtl_tcb_desc *tcb_desc;
	unsigned char *seg_ptr;
	int err;
	u16 frag_threshold = 0xC000;
	u16 frag_length, frag_offset = 0;
	u16 extra_descoffset = 0;
	u8 last_inipkt = 0;

	if (buffer_len >= MAX_FIRMWARE_CODE_SIZE) {
		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
			 "Size over FIRMWARE_CODE_SIZE!\n");
		return -EINVAL;
	}

	extra_descoffset = 0;

	do {
		if ((buffer_len - frag_offset) > frag_threshold) {
			frag_length = frag_threshold + extra_descoffset;
		} else {
			frag_length = (u16)(buffer_len - frag_offset +
					    extra_descoffset);
			last_inipkt = 1;
		}

		/* Allocate skb buffer to contain firmware */
		/* info and tx descriptor info. */
		skb = dev_alloc_skb(frag_length);
		if (!skb)
			return -ENOMEM;
		skb_reserve(skb, extra_descoffset);
		seg_ptr = (u8 *)skb_put(skb, (u32)(frag_length -
					extra_descoffset));
		memcpy(seg_ptr, code_virtual_address + frag_offset,
		       (u32)(frag_length - extra_descoffset));

		tcb_desc = (struct rtl_tcb_desc *)(skb->cb);
		tcb_desc->queue_index = RTL_TXQ_VO;
		tcb_desc->cmd_or_init = DESC_PACKET_TYPE_INIT;
		tcb_desc->last_inipkt = last_inipkt;

		err = _rtl92s_cmd_send_packet(hw, skb, last_inipkt);
		if (err)
			return err;

		frag_offset += (frag_length - extra_descoffset);

	} while (frag_offset < buffer_len);

	return 0;
}
예제 #3
0
static bool _rtl92s_firmware_set_h2c_cmd( struct ieee80211_hw *hw, u8 h2c_cmd,
		u8 *pcmd_buffer )
{
	struct rtl_priv *rtlpriv = rtl_priv( hw );
	struct rtl_hal *rtlhal = rtl_hal( rtl_priv( hw ) );
	struct rtl_tcb_desc *cb_desc;
	struct sk_buff *skb;
	u32	element_id = 0;
	u32	cmd_len = 0;
	u32	len;

	switch ( h2c_cmd ) {
	case FW_H2C_SETPWRMODE:
		element_id = H2C_SETPWRMODE_CMD ;
		cmd_len = sizeof( struct h2c_set_pwrmode_parm );
		break;
	case FW_H2C_JOINBSSRPT:
		element_id = H2C_JOINBSSRPT_CMD;
		cmd_len = sizeof( struct h2c_joinbss_rpt_parm );
		break;
	case FW_H2C_WOWLAN_UPDATE_GTK:
		element_id = H2C_WOWLAN_UPDATE_GTK_CMD;
		cmd_len = sizeof( struct h2c_wpa_two_way_parm );
		break;
	case FW_H2C_WOWLAN_UPDATE_IV:
		element_id = H2C_WOWLAN_UPDATE_IV_CMD;
		cmd_len = sizeof( unsigned long long );
		break;
	case FW_H2C_WOWLAN_OFFLOAD:
		element_id = H2C_WOWLAN_FW_OFFLOAD;
		cmd_len = sizeof( u8 );
		break;
	default:
		break;
	}

	len = _rtl92s_get_h2c_cmdlen( MAX_TRANSMIT_BUFFER_SIZE, 1, &cmd_len );
	skb = dev_alloc_skb( len );
	cb_desc = ( struct rtl_tcb_desc* )( skb->cb );
	cb_desc->queue_index = TXCMD_QUEUE;
	cb_desc->b_cmd_or_init = DESC_PACKET_TYPE_NORMAL;
	cb_desc->b_last_inipkt = false;

	_rtl92s_fill_h2c_cmd( skb, MAX_TRANSMIT_BUFFER_SIZE, 1, &element_id,
			&cmd_len, &pcmd_buffer,	&rtlhal->h2c_txcmd_seq );
	_rtl92s_cmd_send_packet( hw, skb, false );
	rtlpriv->cfg->ops->tx_polling( hw, TXCMD_QUEUE );

	return true;
}
예제 #4
0
파일: fw.c 프로젝트: kyalipay/rtl8192su
static int _rtl92s_firmware_set_h2c_cmd(struct ieee80211_hw *hw, u32 h2c_cmd,
					 u32 cmd_len, u8 *pcmd_buffer)
{
	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
	struct rtl_tcb_desc *cb_desc;
	struct sk_buff *skb;
	u32 len;

	len = _rtl92s_get_h2c_cmdlen(MAX_TRANSMIT_BUFFER_SIZE, 1, &cmd_len);
	skb = dev_alloc_skb(len);
	if (!skb)
		return -ENOMEM;

	cb_desc = (struct rtl_tcb_desc *)(skb->cb);
	cb_desc->queue_index = TXCMD_QUEUE;
	cb_desc->cmd_or_init = DESC_PACKET_TYPE_NORMAL;
	cb_desc->last_inipkt = false;

	_rtl92s_fill_h2c_cmd(skb, MAX_TRANSMIT_BUFFER_SIZE, 1, &h2c_cmd,
			&cmd_len, &pcmd_buffer,	&rtlhal->h2c_txcmd_seq);
	return _rtl92s_cmd_send_packet(hw, skb, false);
}