Ejemplo n.º 1
0
static void rtl_get_rate( void *ppriv, struct ieee80211_sta *sta,
			 void *priv_sta, struct ieee80211_tx_rate_control *txrc )
{
	struct rtl_priv *rtlpriv = ppriv;
	struct sk_buff *skb = txrc->skb;
	struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB( skb );
	struct ieee80211_tx_rate *rates = tx_info->control.rates;
	__le16 fc = rtl_get_fc( skb );
	u8 try_per_rate, i, rix;
	bool not_data = !ieee80211_is_data( fc );

	if ( rate_control_send_low( sta, priv_sta, txrc ) )
		return;

	rix = _rtl_rc_get_highest_rix( rtlpriv, sta, skb, not_data );
	try_per_rate = 1;
	_rtl_rc_rate_set_series( rtlpriv, sta, &rates[0], txrc,
				try_per_rate, rix, 1, not_data );

	if ( !not_data ) {
		for ( i = 1; i < 4; i++ )
			_rtl_rc_rate_set_series( rtlpriv, sta, &rates[i],
						txrc, i, ( rix - i ), 1,
						not_data );
	}
}
Ejemplo n.º 2
0
static u8 _rtl92ce_map_hwqueue_to_fwqueue(struct sk_buff *skb, u8 hw_queue)
{
	__le16 fc = rtl_get_fc(skb);

	if (unlikely(ieee80211_is_beacon(fc)))
		return QSLT_BEACON;
	if (ieee80211_is_mgmt(fc) || ieee80211_is_ctl(fc))
		return QSLT_MGNT;

	return skb->priority;
}
Ejemplo n.º 3
0
Archivo: rc.c Proyecto: IDM350/linux
/*mac80211 Rate Control callbacks*/
static void rtl_tx_status(void *ppriv,
			  struct ieee80211_supported_band *sband,
			  struct ieee80211_sta *sta, void *priv_sta,
			  struct sk_buff *skb)
{
	struct rtl_priv *rtlpriv = ppriv;
	struct rtl_mac *mac = rtl_mac(rtlpriv);
	struct ieee80211_hdr *hdr = rtl_get_hdr(skb);
	__le16 fc = rtl_get_fc(skb);
	struct rtl_sta_info *sta_entry;

	if (!priv_sta || !ieee80211_is_data(fc))
		return;

	if (rtl_is_special_data(mac->hw, skb, true))
		return;

	if (is_multicast_ether_addr(ieee80211_get_DA(hdr)) ||
	    is_broadcast_ether_addr(ieee80211_get_DA(hdr)))
		return;

	if (sta) {
		/* Check if aggregation has to be enabled for this tid */
		sta_entry = (struct rtl_sta_info *) sta->drv_priv;
		if ((sta->ht_cap.ht_supported == true) &&
				!(skb->protocol == cpu_to_be16(ETH_P_PAE))) {
			if (ieee80211_is_data_qos(fc)) {
				u8 tid = rtl_get_tid(skb);
				if (_rtl_tx_aggr_check(rtlpriv, sta_entry,
						       tid)) {
					sta_entry->tids[tid].agg.agg_state =
						RTL_AGG_PROGRESS;
					/*<delete in kernel start>*/
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
					/*<delete in kernel end>*/
					ieee80211_start_tx_ba_session(sta, tid,
								      5000);
					/*<delete in kernel start>*/
#else
					ieee80211_start_tx_ba_session(sta, tid);
#endif
					/*<delete in kernel end>*/
				}
			}
		}
	}
}
Ejemplo n.º 4
0
static u8 _rtl92se_map_hwqueue_to_fwqueue( struct sk_buff *skb,	u8 skb_queue )
{
	__le16 fc = rtl_get_fc( skb );

	if ( unlikely( ieee80211_is_beacon( fc ) ) )
		return QSLT_BEACON;
	if ( ieee80211_is_mgmt( fc ) || ieee80211_is_ctl( fc ) )
		return QSLT_MGNT;
	if ( ieee80211_is_nullfunc( fc ) )
		return QSLT_HIGH;

	/* Kernel commit 1bf4bbb4024dcdab changed EAPOL packets to use
	 * queue V0 at priority 7; however, the RTL8192SE appears to have
	 * that queue at priority 6
	 */
	if ( skb->priority == 7 )
		return QSLT_VO;
	return skb->priority;
}
Ejemplo n.º 5
0
bool rtl_tx_mgmt_proc(struct ieee80211_hw *hw, struct sk_buff *skb)
{
	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
	struct rtl_priv *rtlpriv = rtl_priv(hw);
	__le16 fc = rtl_get_fc(skb);

	if (rtlpriv->dm.supp_phymode_switch &&
	    mac->link_state < MAC80211_LINKED &&
	    (ieee80211_is_auth(fc) || ieee80211_is_probe_req(fc))) {
		if (rtlpriv->cfg->ops->check_switch_to_dmdp)
			rtlpriv->cfg->ops->check_switch_to_dmdp(hw);
	}
	if (ieee80211_is_auth(fc)) {
		RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, "MAC80211_LINKING\n");
		rtl_ips_nic_on(hw);

		mac->link_state = MAC80211_LINKING;
		/* Dual mac */
		rtlpriv->phy.need_iqk = true;
	}

	return true;
}
Ejemplo n.º 6
0
/*should call before software enc*/
u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx)
{
	struct rtl_priv *rtlpriv = rtl_priv(hw);
	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
	__le16 fc = rtl_get_fc(skb);
	u16 ether_type;
	u8 mac_hdr_len = ieee80211_get_hdrlen_from_skb(skb);
	const struct iphdr *ip;

	if (!ieee80211_is_data(fc))
		return false;


	ip = (struct iphdr *)((u8 *) skb->data + mac_hdr_len +
			      SNAP_SIZE + PROTOC_TYPE_SIZE);
	ether_type = *(u16 *) ((u8 *) skb->data + mac_hdr_len + SNAP_SIZE);
	/*	ether_type = ntohs(ether_type); */

	if (ETH_P_IP == ether_type) {
		if (IPPROTO_UDP == ip->protocol) {
			struct udphdr *udp = (struct udphdr *)((u8 *) ip +
							       (ip->ihl << 2));
			if (((((u8 *) udp)[1] == 68) &&
			     (((u8 *) udp)[3] == 67)) ||
			    ((((u8 *) udp)[1] == 67) &&
			     (((u8 *) udp)[3] == 68))) {
				/*
				 * 68 : UDP BOOTP client
				 * 67 : UDP BOOTP server
				 */
				RT_TRACE(rtlpriv, (COMP_SEND | COMP_RECV),
					 DBG_DMESG, "dhcp %s !!\n",
					 is_tx ? "Tx" : "Rx");

				if (is_tx) {
					schedule_work(&rtlpriv->
						      works.lps_leave_work);
					ppsc->last_delaylps_stamp_jiffies =
					    jiffies;
				}

				return true;
			}
		}
	} else if (ETH_P_ARP == ether_type) {
		if (is_tx) {
			schedule_work(&rtlpriv->works.lps_leave_work);
			ppsc->last_delaylps_stamp_jiffies = jiffies;
		}

		return true;
	} else if (ETH_P_PAE == ether_type) {
		RT_TRACE(rtlpriv, (COMP_SEND | COMP_RECV), DBG_DMESG,
			 "802.1X %s EAPOL pkt!!\n", is_tx ? "Tx" : "Rx");

		if (is_tx) {
			schedule_work(&rtlpriv->works.lps_leave_work);
			ppsc->last_delaylps_stamp_jiffies = jiffies;
		}

		return true;
	} else if (ETH_P_IPV6 == ether_type) {
		/* IPv6 */
		return true;
	}

	return false;
}