⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bcm43xx_xmit.c

📁 linux内核源码
💻 C
📖 第 1 页 / 共 2 页
字号:
			    const int is_first_fragment,			    const u16 cookie){	const struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);	const struct ieee80211_hdr_4addr *wireless_header = (const struct ieee80211_hdr_4addr *)fragment_data;	const struct ieee80211_security *secinfo = &bcm->ieee->sec;	u8 bitrate;	u8 fallback_bitrate;	int ofdm_modulation;	int fallback_ofdm_modulation;	u16 plcp_fragment_len = fragment_len;	u16 flags = 0;	u16 control = 0;	u16 wsec_rate = 0;	u16 encrypt_frame;	const u16 ftype = WLAN_FC_GET_TYPE(le16_to_cpu(wireless_header->frame_ctl));	const int is_mgt = (ftype == IEEE80211_FTYPE_MGMT);	/* Now construct the TX header. */	memset(txhdr, 0, sizeof(*txhdr));	bitrate = ieee80211softmac_suggest_txrate(bcm->softmac,		is_multicast_ether_addr(wireless_header->addr1), is_mgt);	ofdm_modulation = !(ieee80211_is_cck_rate(bitrate));	fallback_bitrate = bcm43xx_calc_fallback_rate(bitrate);	fallback_ofdm_modulation = !(ieee80211_is_cck_rate(fallback_bitrate));	/* Set Frame Control from 80211 header. */	txhdr->frame_control = wireless_header->frame_ctl;	/* Copy address1 from 80211 header. */	memcpy(txhdr->mac1, wireless_header->addr1, 6);	/* Set the fallback duration ID. */	txhdr->fallback_dur_id = bcm43xx_calc_duration_id((const struct ieee80211_hdr *)wireless_header,							  fallback_bitrate);	/* Set the cookie (used as driver internal ID for the frame) */	txhdr->cookie = cpu_to_le16(cookie);	/* Hardware appends FCS. */	plcp_fragment_len += IEEE80211_FCS_LEN;	/* Hardware encryption. */	encrypt_frame = le16_to_cpup(&wireless_header->frame_ctl) & IEEE80211_FCTL_PROTECTED;	if (encrypt_frame && !bcm->ieee->host_encrypt) {		const struct ieee80211_hdr_3addr *hdr = (struct ieee80211_hdr_3addr *)wireless_header;		memcpy(txhdr->wep_iv, hdr->payload, 4);		/* Hardware appends ICV. */		plcp_fragment_len += 4;		wsec_rate |= (bcm->key[secinfo->active_key].algorithm << BCM43xx_TXHDR_WSEC_ALGO_SHIFT)			     & BCM43xx_TXHDR_WSEC_ALGO_MASK;		wsec_rate |= (secinfo->active_key << BCM43xx_TXHDR_WSEC_KEYINDEX_SHIFT)			     & BCM43xx_TXHDR_WSEC_KEYINDEX_MASK;	}	/* Generate the PLCP header and the fallback PLCP header. */	bcm43xx_generate_plcp_hdr((struct bcm43xx_plcp_hdr4 *)(&txhdr->plcp),				  plcp_fragment_len,				  bitrate, ofdm_modulation);	bcm43xx_generate_plcp_hdr(&txhdr->fallback_plcp, plcp_fragment_len,				  fallback_bitrate, fallback_ofdm_modulation);	/* Set the CONTROL field */	if (ofdm_modulation)		control |= BCM43xx_TXHDRCTL_OFDM;	if (bcm->short_preamble) //FIXME: could be the other way around, please test		control |= BCM43xx_TXHDRCTL_SHORT_PREAMBLE;	control |= (phy->antenna_diversity << BCM43xx_TXHDRCTL_ANTENNADIV_SHIFT)		   & BCM43xx_TXHDRCTL_ANTENNADIV_MASK;	/* Set the FLAGS field */	if (!is_multicast_ether_addr(wireless_header->addr1) &&	    !is_broadcast_ether_addr(wireless_header->addr1))		flags |= BCM43xx_TXHDRFLAG_EXPECTACK;	if (1 /* FIXME: PS poll?? */)		flags |= 0x10; // FIXME: unknown meaning.	if (fallback_ofdm_modulation)		flags |= BCM43xx_TXHDRFLAG_FALLBACKOFDM;	if (is_first_fragment)		flags |= BCM43xx_TXHDRFLAG_FIRSTFRAGMENT;	/* Set WSEC/RATE field */	wsec_rate |= (txhdr->plcp.raw[0] << BCM43xx_TXHDR_RATE_SHIFT)		     & BCM43xx_TXHDR_RATE_MASK;	/* Generate the RTS/CTS packet, if required. */	/* FIXME: We should first try with CTS-to-self,	 *        if we are on 80211g. If we get too many	 *        failures (hidden nodes), we should switch back to RTS/CTS.	 */	if (0/*FIXME txctl->use_rts_cts*/) {		bcm43xx_generate_rts(phy, txhdr, &flags,				     0/*FIXME txctl->rts_cts_rate*/,				     wireless_header);	}	txhdr->flags = cpu_to_le16(flags);	txhdr->control = cpu_to_le16(control);	txhdr->wsec_rate = cpu_to_le16(wsec_rate);}static s8 bcm43xx_rssi_postprocess(struct bcm43xx_private *bcm,				   u8 in_rssi, int ofdm,				   int adjust_2053, int adjust_2050){	struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);	struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);	s32 tmp;	switch (radio->version) {	case 0x2050:		if (ofdm) {			tmp = in_rssi;			if (tmp > 127)				tmp -= 256;			tmp *= 73;			tmp /= 64;			if (adjust_2050)				tmp += 25;			else				tmp -= 3;		} else {			if (bcm->sprom.boardflags & BCM43xx_BFL_RSSI) {				if (in_rssi > 63)					in_rssi = 63;				tmp = radio->nrssi_lt[in_rssi];				tmp = 31 - tmp;				tmp *= -131;				tmp /= 128;				tmp -= 57;			} else {				tmp = in_rssi;				tmp = 31 - tmp;				tmp *= -149;				tmp /= 128;				tmp -= 68;			}			if (phy->type == BCM43xx_PHYTYPE_G &&			    adjust_2050)				tmp += 25;		}		break;	case 0x2060:		if (in_rssi > 127)			tmp = in_rssi - 256;		else			tmp = in_rssi;		break;	default:		tmp = in_rssi;		tmp -= 11;		tmp *= 103;		tmp /= 64;		if (adjust_2053)			tmp -= 109;		else			tmp -= 83;	}	return (s8)tmp;}//TODO#if 0static s8 bcm43xx_rssinoise_postprocess(struct bcm43xx_private *bcm,					u8 in_rssi){	struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);	s8 ret;	if (phy->type == BCM43xx_PHYTYPE_A) {		//TODO: Incomplete specs.		ret = 0;	} else		ret = bcm43xx_rssi_postprocess(bcm, in_rssi, 0, 1, 1);	return ret;}#endifint bcm43xx_rx(struct bcm43xx_private *bcm,	       struct sk_buff *skb,	       struct bcm43xx_rxhdr *rxhdr){	struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);	struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);	struct bcm43xx_plcp_hdr4 *plcp;	struct ieee80211_rx_stats stats;	struct ieee80211_hdr_4addr *wlhdr;	u16 frame_ctl;	int is_packet_for_us = 0;	int err = -EINVAL;	const u16 rxflags1 = le16_to_cpu(rxhdr->flags1);	const u16 rxflags2 = le16_to_cpu(rxhdr->flags2);	const u16 rxflags3 = le16_to_cpu(rxhdr->flags3);	const int is_ofdm = !!(rxflags1 & BCM43xx_RXHDR_FLAGS1_OFDM);	if (rxflags2 & BCM43xx_RXHDR_FLAGS2_TYPE2FRAME) {		plcp = (struct bcm43xx_plcp_hdr4 *)(skb->data + 2);		/* Skip two unknown bytes and the PLCP header. */		skb_pull(skb, 2 + sizeof(struct bcm43xx_plcp_hdr6));	} else {		plcp = (struct bcm43xx_plcp_hdr4 *)(skb->data);		/* Skip the PLCP header. */		skb_pull(skb, sizeof(struct bcm43xx_plcp_hdr6));	}	/* The SKB contains the PAYLOAD (wireless header + data)	 * at this point. The FCS at the end is stripped.	 */	memset(&stats, 0, sizeof(stats));	stats.mac_time = le16_to_cpu(rxhdr->mactime);	stats.rssi = rxhdr->rssi;	stats.signal = bcm43xx_rssi_postprocess(bcm, rxhdr->rssi, is_ofdm,					      !!(rxflags1 & BCM43xx_RXHDR_FLAGS1_2053RSSIADJ),					      !!(rxflags3 & BCM43xx_RXHDR_FLAGS3_2050RSSIADJ));	stats.noise = bcm->stats.noise;	if (is_ofdm)		stats.rate = bcm43xx_plcp_get_bitrate_ofdm(plcp);	else		stats.rate = bcm43xx_plcp_get_bitrate_cck(plcp);	stats.received_channel = radio->channel;	stats.mask = IEEE80211_STATMASK_SIGNAL |		     IEEE80211_STATMASK_NOISE |		     IEEE80211_STATMASK_RATE |		     IEEE80211_STATMASK_RSSI;	if (phy->type == BCM43xx_PHYTYPE_A)		stats.freq = IEEE80211_52GHZ_BAND;	else		stats.freq = IEEE80211_24GHZ_BAND;	stats.len = skb->len;	bcm->stats.last_rx = jiffies;	if (bcm->ieee->iw_mode == IW_MODE_MONITOR) {		err = ieee80211_rx(bcm->ieee, skb, &stats);		return (err == 0) ? -EINVAL : 0;	}	wlhdr = (struct ieee80211_hdr_4addr *)(skb->data);	switch (bcm->ieee->iw_mode) {	case IW_MODE_ADHOC:		if (memcmp(wlhdr->addr1, bcm->net_dev->dev_addr, ETH_ALEN) == 0 ||		    memcmp(wlhdr->addr3, bcm->ieee->bssid, ETH_ALEN) == 0 ||		    is_broadcast_ether_addr(wlhdr->addr1) ||		    is_multicast_ether_addr(wlhdr->addr1) ||		    bcm->net_dev->flags & IFF_PROMISC)			is_packet_for_us = 1;		break;	case IW_MODE_INFRA:	default:		/* When receiving multicast or broadcast packets, filter out		   the packets we send ourself; we shouldn't see those */		if (memcmp(wlhdr->addr3, bcm->ieee->bssid, ETH_ALEN) == 0 ||		    memcmp(wlhdr->addr1, bcm->net_dev->dev_addr, ETH_ALEN) == 0 ||		    (memcmp(wlhdr->addr3, bcm->net_dev->dev_addr, ETH_ALEN) &&		     (is_broadcast_ether_addr(wlhdr->addr1) ||		      is_multicast_ether_addr(wlhdr->addr1) ||		      bcm->net_dev->flags & IFF_PROMISC)))			is_packet_for_us = 1;		break;	}	frame_ctl = le16_to_cpu(wlhdr->frame_ctl);	switch (WLAN_FC_GET_TYPE(frame_ctl)) {	case IEEE80211_FTYPE_MGMT:		ieee80211_rx_mgt(bcm->ieee, wlhdr, &stats);		break;	case IEEE80211_FTYPE_DATA:		if (is_packet_for_us) {			err = ieee80211_rx(bcm->ieee, skb, &stats);			err = (err == 0) ? -EINVAL : 0;		}		break;	case IEEE80211_FTYPE_CTL:		break;	default:		assert(0);		return -EINVAL;	}	return err;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -