Esempio n. 1
0
void r8712_set_qos(struct pkt_file *ppktfile, struct pkt_attrib *pattrib)
{
	struct ethhdr etherhdr;
	struct iphdr ip_hdr;
	u16 UserPriority = 0;

	_r8712_open_pktfile(ppktfile->pkt, ppktfile);
	_r8712_pktfile_read(ppktfile, (unsigned char *)&etherhdr, ETH_HLEN);

	/* get UserPriority from IP hdr*/
	if (pattrib->ether_type == 0x0800) {
		_r8712_pktfile_read(ppktfile, (u8 *)&ip_hdr, sizeof(ip_hdr));
		/*UserPriority = (ntohs(ip_hdr.tos) >> 5) & 0x3 ;*/
		UserPriority = ip_hdr.tos >> 5;
	} else {
Esempio n. 2
0
sint r8712_update_attrib(struct _adapter *padapter, _pkt *pkt,
		   struct pkt_attrib *pattrib)
{
	uint i;
	struct pkt_file pktfile;
	struct sta_info *psta = NULL;
	struct ethhdr etherhdr;

	struct tx_cmd txdesc;

	sint bmcast;
	struct sta_priv		*pstapriv = &padapter->stapriv;
	struct security_priv	*psecuritypriv = &padapter->securitypriv;
	struct mlme_priv	*pmlmepriv = &padapter->mlmepriv;
	struct qos_priv		*pqospriv = &pmlmepriv->qospriv;

	_r8712_open_pktfile(pkt, &pktfile);

	i = _r8712_pktfile_read(&pktfile, (unsigned char *)&etherhdr, ETH_HLEN);

	pattrib->ether_type = ntohs(etherhdr.h_proto);

{
	u8 bool;
	/*If driver xmit ARP packet, driver can set ps mode to initial
	 * setting. It stands for getting DHCP or fix IP.*/
	if (pattrib->ether_type == 0x0806) {
		if (padapter->pwrctrlpriv.pwr_mode !=
		    padapter->registrypriv.power_mgnt) {
			_cancel_timer(&(pmlmepriv->dhcp_timer), &bool);
			r8712_set_ps_mode(padapter, padapter->registrypriv.
				power_mgnt, padapter->registrypriv.smart_ps);
		}
	}
}
void r8712_set_qos(struct pkt_file *ppktfile, struct pkt_attrib *pattrib)
{
	int i;
	struct ethhdr etherhdr;
	struct iphdr ip_hdr;
	u16 UserPriority = 0;

	_r8712_open_pktfile(ppktfile->pkt, ppktfile);
	_r8712_pktfile_read(ppktfile, (unsigned char *)&etherhdr, ETH_HLEN);

	
	if (pattrib->ether_type == 0x0800) {
		i = _r8712_pktfile_read(ppktfile, (u8 *)&ip_hdr,
					sizeof(ip_hdr));
		
		UserPriority = ip_hdr.tos >> 5;
	} else {
Esempio n. 4
0
/*
 * This sub-routine will perform all the following:
 * 1. remove 802.3 header.
 * 2. create wlan_header, based on the info in pxmitframe
 * 3. append sta's iv/ext-iv
 * 4. append LLC
 * 5. move frag chunk from pframe to pxmitframe->mem
 * 6. apply sw-encrypt, if necessary.
 */
sint r8712_xmitframe_coalesce(struct _adapter *padapter, _pkt *pkt,
			struct xmit_frame *pxmitframe)
{
	struct pkt_file pktfile;

	sint	frg_len, mpdu_len, llc_sz;
	u32	mem_sz;
	u8	frg_inx;
	addr_t addr;
	u8 *pframe, *mem_start, *ptxdesc;
	struct sta_info		*psta;
	struct security_priv	*psecuritypriv = &padapter->securitypriv;
	struct mlme_priv	*pmlmepriv = &padapter->mlmepriv;
	struct xmit_priv	*pxmitpriv = &padapter->xmitpriv;
	struct pkt_attrib	*pattrib = &pxmitframe->attrib;
	u8 *pbuf_start;
	sint bmcst = IS_MCAST(pattrib->ra);

	if (pattrib->psta == NULL)
		return _FAIL;
	psta = pattrib->psta;
	if (pxmitframe->buf_addr == NULL)
		return _FAIL;
	pbuf_start = pxmitframe->buf_addr;
	ptxdesc = pbuf_start;
	mem_start = pbuf_start + TXDESC_OFFSET;
	if (make_wlanhdr(padapter, mem_start, pattrib) == _FAIL)
		return _FAIL;
	_r8712_open_pktfile(pkt, &pktfile);
	_r8712_pktfile_read(&pktfile, NULL, (uint) pattrib->pkt_hdrlen);
	if (check_fwstate(pmlmepriv, WIFI_MP_STATE)) {
		/* truncate TXDESC_SIZE bytes txcmd if at mp mode for 871x */
		if (pattrib->ether_type == 0x8712) {
			/* take care -  update_txdesc overwrite this */
			_r8712_pktfile_read(&pktfile, ptxdesc, TXDESC_SIZE);
		}
	}
	pattrib->pktlen = pktfile.pkt_len;
	frg_inx = 0;
	frg_len = pxmitpriv->frag_len - 4;
	while (1) {
		llc_sz = 0;
		mpdu_len = frg_len;
		pframe = mem_start;
		SetMFrag(mem_start);
		pframe += pattrib->hdrlen;
		mpdu_len -= pattrib->hdrlen;
		/* adding icv, if necessary...*/
		if (pattrib->iv_len) {
			if (psta != NULL) {
				switch (pattrib->encrypt) {
				case _WEP40_:
				case _WEP104_:
					WEP_IV(pattrib->iv, psta->txpn,
					       (u8)psecuritypriv->
					       PrivacyKeyIndex);
					break;
				case _TKIP_:
					if (bmcst)
						TKIP_IV(pattrib->iv,
						    psta->txpn,
						    (u8)psecuritypriv->
						    XGrpKeyid);
					else
						TKIP_IV(pattrib->iv, psta->txpn,
							0);
					break;
				case _AES_:
					if (bmcst)
						AES_IV(pattrib->iv, psta->txpn,
						    (u8)psecuritypriv->
						    XGrpKeyid);
					else
						AES_IV(pattrib->iv, psta->txpn,
						       0);
					break;
				}
			}
			memcpy(pframe, pattrib->iv, pattrib->iv_len);
			pframe += pattrib->iv_len;
			mpdu_len -= pattrib->iv_len;
		}
		if (frg_inx == 0) {
			llc_sz = r8712_put_snap(pframe, pattrib->ether_type);
			pframe += llc_sz;
			mpdu_len -= llc_sz;
		}
		if ((pattrib->icv_len > 0) && (pattrib->bswenc))
			mpdu_len -= pattrib->icv_len;
		if (bmcst)
			mem_sz = _r8712_pktfile_read(&pktfile, pframe,
				 pattrib->pktlen);
		else
			mem_sz = _r8712_pktfile_read(&pktfile, pframe,
				 mpdu_len);
		pframe += mem_sz;
		if ((pattrib->icv_len > 0) && (pattrib->bswenc)) {
			memcpy(pframe, pattrib->icv, pattrib->icv_len);
			pframe += pattrib->icv_len;
		}
		frg_inx++;
		if (bmcst || r8712_endofpktfile(&pktfile)) {
			pattrib->nr_frags = frg_inx;
			pattrib->last_txcmdsz = pattrib->hdrlen +
						pattrib->iv_len +
						((pattrib->nr_frags == 1) ?
						llc_sz : 0) +
						((pattrib->bswenc) ?
						pattrib->icv_len : 0) + mem_sz;
			ClearMFrag(mem_start);
			break;
		}
		addr = (addr_t)(pframe);
		mem_start = (unsigned char *)RND4(addr) + TXDESC_OFFSET;
		memcpy(mem_start, pbuf_start + TXDESC_OFFSET, pattrib->hdrlen);
	}

	if (xmitframe_addmic(padapter, pxmitframe) == _FAIL)
		return _FAIL;
	xmitframe_swencrypt(padapter, pxmitframe);
	return _SUCCESS;
}
Esempio n. 5
0
sint r8712_update_attrib(struct _adapter *padapter, _pkt *pkt,
		   struct pkt_attrib *pattrib)
{
	struct pkt_file pktfile;
	struct sta_info *psta = NULL;
	struct ethhdr etherhdr;

	struct tx_cmd txdesc;

	sint bmcast;
	struct sta_priv		*pstapriv = &padapter->stapriv;
	struct security_priv	*psecuritypriv = &padapter->securitypriv;
	struct mlme_priv	*pmlmepriv = &padapter->mlmepriv;
	struct qos_priv		*pqospriv = &pmlmepriv->qospriv;

	_r8712_open_pktfile(pkt, &pktfile);

	_r8712_pktfile_read(&pktfile, (unsigned char *)&etherhdr, ETH_HLEN);

	pattrib->ether_type = ntohs(etherhdr.h_proto);

	/*
	 * If driver xmit ARP packet, driver can set ps mode to initial
	 * setting. It stands for getting DHCP or fix IP.
	 */
	if (pattrib->ether_type == 0x0806) {
		if (padapter->pwrctrlpriv.pwr_mode !=
		    padapter->registrypriv.power_mgnt) {
			del_timer_sync(&pmlmepriv->dhcp_timer);
			r8712_set_ps_mode(padapter,
					  padapter->registrypriv.power_mgnt,
					  padapter->registrypriv.smart_ps);
		}
	}

	memcpy(pattrib->dst, &etherhdr.h_dest, ETH_ALEN);
	memcpy(pattrib->src, &etherhdr.h_source, ETH_ALEN);
	pattrib->pctrl = 0;
	if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) ||
	    check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) {
		memcpy(pattrib->ra, pattrib->dst, ETH_ALEN);
		memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
	} else if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
		memcpy(pattrib->ra, get_bssid(pmlmepriv), ETH_ALEN);
		memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
	} else if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
		memcpy(pattrib->ra, pattrib->dst, ETH_ALEN);
		memcpy(pattrib->ta, get_bssid(pmlmepriv), ETH_ALEN);
	} else if (check_fwstate(pmlmepriv, WIFI_MP_STATE)) {
		/*firstly, filter packet not belongs to mp*/
		if (pattrib->ether_type != 0x8712)
			return _FAIL;
		/* for mp storing the txcmd per packet,
		 * according to the info of txcmd to update pattrib
		 */
		/*get MP_TXDESC_SIZE bytes txcmd per packet*/
		_r8712_pktfile_read(&pktfile, (u8 *)&txdesc, TXDESC_SIZE);
		memcpy(pattrib->ra, pattrib->dst, ETH_ALEN);
		memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
		pattrib->pctrl = 1;
	}
	/* r8712_xmitframe_coalesce() overwrite this!*/
	pattrib->pktlen = pktfile.pkt_len;
	if (pattrib->ether_type == ETH_P_IP) {
		/* The following is for DHCP and ARP packet, we use cck1M to
		 * tx these packets and let LPS awake some time
		 * to prevent DHCP protocol fail
		 */
		u8 tmp[24];

		_r8712_pktfile_read(&pktfile, &tmp[0], 24);
		pattrib->dhcp_pkt = 0;
		if (pktfile.pkt_len > 282) {/*MINIMUM_DHCP_PACKET_SIZE)*/
			if (pattrib->ether_type == ETH_P_IP) {/* IP header*/
				if (((tmp[21] == 68) && (tmp[23] == 67)) ||
					((tmp[21] == 67) && (tmp[23] == 68))) {
					/* 68 : UDP BOOTP client
					 * 67 : UDP BOOTP server
					 * Use low rate to send DHCP packet.
					 */
					pattrib->dhcp_pkt = 1;
				}
			}
		}
	}
	bmcast = IS_MCAST(pattrib->ra);
	/* get sta_info*/
	if (bmcast) {
		psta = r8712_get_bcmc_stainfo(padapter);
		pattrib->mac_id = 4;
	} else {
		if (check_fwstate(pmlmepriv, WIFI_MP_STATE)) {
			psta = r8712_get_stainfo(pstapriv,
						 get_bssid(pmlmepriv));
			pattrib->mac_id = 5;
		} else {
			psta = r8712_get_stainfo(pstapriv, pattrib->ra);
			if (psta == NULL)  /* drop the pkt */
				return _FAIL;
			if (check_fwstate(pmlmepriv, WIFI_STATION_STATE))
				pattrib->mac_id = 5;
			else
				pattrib->mac_id = psta->mac_id;
		}
	}

	if (psta) {
		pattrib->psta = psta;
	} else {
		/* if we cannot get psta => drrp the pkt */
		return _FAIL;
	}

	pattrib->ack_policy = 0;
	/* get ether_hdr_len */
	pattrib->pkt_hdrlen = ETH_HLEN;

	if (pqospriv->qos_option) {
		r8712_set_qos(&pktfile, pattrib);
	} else {
		pattrib->hdrlen = WLAN_HDR_A3_LEN;
		pattrib->subtype = WIFI_DATA_TYPE;
		pattrib->priority = 0;
	}
	if (psta->ieee8021x_blocked) {
		pattrib->encrypt = 0;
		if ((pattrib->ether_type != 0x888e) &&
		    !check_fwstate(pmlmepriv, WIFI_MP_STATE))
			return _FAIL;
	} else {
		GET_ENCRY_ALGO(psecuritypriv, psta, pattrib->encrypt, bmcast);
	}
	switch (pattrib->encrypt) {
	case _WEP40_:
	case _WEP104_:
		pattrib->iv_len = 4;
		pattrib->icv_len = 4;
		break;
	case _TKIP_:
		pattrib->iv_len = 8;
		pattrib->icv_len = 4;
		if (padapter->securitypriv.busetkipkey == _FAIL)
			return _FAIL;
		break;
	case _AES_:
		pattrib->iv_len = 8;
		pattrib->icv_len = 8;
		break;
	default:
		pattrib->iv_len = 0;
		pattrib->icv_len = 0;
		break;
	}

	if (pattrib->encrypt &&
	    (padapter->securitypriv.sw_encrypt ||
	    !psecuritypriv->hw_decrypted))
		pattrib->bswenc = true;
	else
		pattrib->bswenc = false;
	/* if in MP_STATE, update pkt_attrib from mp_txcmd, and overwrite
	 * some settings above.
	 */
	if (check_fwstate(pmlmepriv, WIFI_MP_STATE))
		pattrib->priority =
		    (le32_to_cpu(txdesc.txdw1) >> QSEL_SHT) & 0x1f;
	return _SUCCESS;
}