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

📄 iwl4965-base.c

📁 linux内核源码
💻 C
📖 第 1 页 / 共 5 页
字号:
static struct iwl_frame *iwl_get_free_frame(struct iwl_priv *priv){	struct iwl_frame *frame;	struct list_head *element;	if (list_empty(&priv->free_frames)) {		frame = kzalloc(sizeof(*frame), GFP_KERNEL);		if (!frame) {			IWL_ERROR("Could not allocate frame!\n");			return NULL;		}		priv->frames_count++;		return frame;	}	element = priv->free_frames.next;	list_del(element);	return list_entry(element, struct iwl_frame, list);}static void iwl_free_frame(struct iwl_priv *priv, struct iwl_frame *frame){	memset(frame, 0, sizeof(*frame));	list_add(&frame->list, &priv->free_frames);}unsigned int iwl_fill_beacon_frame(struct iwl_priv *priv,				struct ieee80211_hdr *hdr,				const u8 *dest, int left){	if (!iwl_is_associated(priv) || !priv->ibss_beacon ||	    ((priv->iw_mode != IEEE80211_IF_TYPE_IBSS) &&	     (priv->iw_mode != IEEE80211_IF_TYPE_AP)))		return 0;	if (priv->ibss_beacon->len > left)		return 0;	memcpy(hdr, priv->ibss_beacon->data, priv->ibss_beacon->len);	return priv->ibss_beacon->len;}int iwl_rate_index_from_plcp(int plcp){	int i = 0;	if (plcp & RATE_MCS_HT_MSK) {		i = (plcp & 0xff);		if (i >= IWL_RATE_MIMO_6M_PLCP)			i = i - IWL_RATE_MIMO_6M_PLCP;		i += IWL_FIRST_OFDM_RATE;		/* skip 9M not supported in ht*/		if (i >= IWL_RATE_9M_INDEX)			i += 1;		if ((i >= IWL_FIRST_OFDM_RATE) &&		    (i <= IWL_LAST_OFDM_RATE))			return i;	} else {		for (i = 0; i < ARRAY_SIZE(iwl_rates); i++)			if (iwl_rates[i].plcp == (plcp &0xFF))				return i;	}	return -1;}static u8 iwl_rate_get_lowest_plcp(int rate_mask){	u8 i;	for (i = IWL_RATE_1M_INDEX; i != IWL_RATE_INVALID;	     i = iwl_rates[i].next_ieee) {		if (rate_mask & (1 << i))			return iwl_rates[i].plcp;	}	return IWL_RATE_INVALID;}static int iwl_send_beacon_cmd(struct iwl_priv *priv){	struct iwl_frame *frame;	unsigned int frame_size;	int rc;	u8 rate;	frame = iwl_get_free_frame(priv);	if (!frame) {		IWL_ERROR("Could not obtain free frame buffer for beacon "			  "command.\n");		return -ENOMEM;	}	if (!(priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK)) {		rate = iwl_rate_get_lowest_plcp(priv->active_rate_basic &						0xFF0);		if (rate == IWL_INVALID_RATE)			rate = IWL_RATE_6M_PLCP;	} else {		rate = iwl_rate_get_lowest_plcp(priv->active_rate_basic & 0xF);		if (rate == IWL_INVALID_RATE)			rate = IWL_RATE_1M_PLCP;	}	frame_size = iwl_hw_get_beacon_cmd(priv, frame, rate);	rc = iwl_send_cmd_pdu(priv, REPLY_TX_BEACON, frame_size,			      &frame->u.cmd[0]);	iwl_free_frame(priv, frame);	return rc;}/****************************************************************************** * * EEPROM related functions * ******************************************************************************/static void get_eeprom_mac(struct iwl_priv *priv, u8 *mac){	memcpy(mac, priv->eeprom.mac_address, 6);}/** * iwl_eeprom_init - read EEPROM contents * * Load the EEPROM from adapter into priv->eeprom * * NOTE:  This routine uses the non-debug IO access functions. */int iwl_eeprom_init(struct iwl_priv *priv){	u16 *e = (u16 *)&priv->eeprom;	u32 gp = iwl_read32(priv, CSR_EEPROM_GP);	u32 r;	int sz = sizeof(priv->eeprom);	int rc;	int i;	u16 addr;	/* The EEPROM structure has several padding buffers within it	 * and when adding new EEPROM maps is subject to programmer errors	 * which may be very difficult to identify without explicitly	 * checking the resulting size of the eeprom map. */	BUILD_BUG_ON(sizeof(priv->eeprom) != IWL_EEPROM_IMAGE_SIZE);	if ((gp & CSR_EEPROM_GP_VALID_MSK) == CSR_EEPROM_GP_BAD_SIGNATURE) {		IWL_ERROR("EEPROM not found, EEPROM_GP=0x%08x", gp);		return -ENOENT;	}	rc = iwl_eeprom_aqcuire_semaphore(priv);	if (rc < 0) {		IWL_ERROR("Failed to aqcuire EEPROM semaphore.\n");		return -ENOENT;	}	/* eeprom is an array of 16bit values */	for (addr = 0; addr < sz; addr += sizeof(u16)) {		_iwl_write32(priv, CSR_EEPROM_REG, addr << 1);		_iwl_clear_bit(priv, CSR_EEPROM_REG, CSR_EEPROM_REG_BIT_CMD);		for (i = 0; i < IWL_EEPROM_ACCESS_TIMEOUT;					i += IWL_EEPROM_ACCESS_DELAY) {			r = _iwl_read_restricted(priv, CSR_EEPROM_REG);			if (r & CSR_EEPROM_REG_READ_VALID_MSK)				break;			udelay(IWL_EEPROM_ACCESS_DELAY);		}		if (!(r & CSR_EEPROM_REG_READ_VALID_MSK)) {			IWL_ERROR("Time out reading EEPROM[%d]", addr);			rc = -ETIMEDOUT;			goto done;		}		e[addr / 2] = le16_to_cpu(r >> 16);	}	rc = 0;done:	iwl_eeprom_release_semaphore(priv);	return rc;}/****************************************************************************** * * Misc. internal state and helper functions * ******************************************************************************/#ifdef CONFIG_IWLWIFI_DEBUG/** * iwl_report_frame - dump frame to syslog during debug sessions * * hack this function to show different aspects of received frames, * including selective frame dumps. * group100 parameter selects whether to show 1 out of 100 good frames. * * TODO:  ieee80211_hdr stuff is common to 3945 and 4965, so frame type *        info output is okay, but some of this stuff (e.g. iwl_rx_frame_stats) *        is 3945-specific and gives bad output for 4965.  Need to split the *        functionality, keep common stuff here. */void iwl_report_frame(struct iwl_priv *priv,		      struct iwl_rx_packet *pkt,		      struct ieee80211_hdr *header, int group100){	u32 to_us;	u32 print_summary = 0;	u32 print_dump = 0;	/* set to 1 to dump all frames' contents */	u32 hundred = 0;	u32 dataframe = 0;	u16 fc;	u16 seq_ctl;	u16 channel;	u16 phy_flags;	int rate_sym;	u16 length;	u16 status;	u16 bcn_tmr;	u32 tsf_low;	u64 tsf;	u8 rssi;	u8 agc;	u16 sig_avg;	u16 noise_diff;	struct iwl_rx_frame_stats *rx_stats = IWL_RX_STATS(pkt);	struct iwl_rx_frame_hdr *rx_hdr = IWL_RX_HDR(pkt);	struct iwl_rx_frame_end *rx_end = IWL_RX_END(pkt);	u8 *data = IWL_RX_DATA(pkt);	/* MAC header */	fc = le16_to_cpu(header->frame_control);	seq_ctl = le16_to_cpu(header->seq_ctrl);	/* metadata */	channel = le16_to_cpu(rx_hdr->channel);	phy_flags = le16_to_cpu(rx_hdr->phy_flags);	rate_sym = rx_hdr->rate;	length = le16_to_cpu(rx_hdr->len);	/* end-of-frame status and timestamp */	status = le32_to_cpu(rx_end->status);	bcn_tmr = le32_to_cpu(rx_end->beacon_timestamp);	tsf_low = le64_to_cpu(rx_end->timestamp) & 0x0ffffffff;	tsf = le64_to_cpu(rx_end->timestamp);	/* signal statistics */	rssi = rx_stats->rssi;	agc = rx_stats->agc;	sig_avg = le16_to_cpu(rx_stats->sig_avg);	noise_diff = le16_to_cpu(rx_stats->noise_diff);	to_us = !compare_ether_addr(header->addr1, priv->mac_addr);	/* if data frame is to us and all is good,	 *   (optionally) print summary for only 1 out of every 100 */	if (to_us && (fc & ~IEEE80211_FCTL_PROTECTED) ==	    (IEEE80211_FCTL_FROMDS | IEEE80211_FTYPE_DATA)) {		dataframe = 1;		if (!group100)			print_summary = 1;	/* print each frame */		else if (priv->framecnt_to_us < 100) {			priv->framecnt_to_us++;			print_summary = 0;		} else {			priv->framecnt_to_us = 0;			print_summary = 1;			hundred = 1;		}	} else {		/* print summary for all other frames */		print_summary = 1;	}	if (print_summary) {		char *title;		u32 rate;		if (hundred)			title = "100Frames";		else if (fc & IEEE80211_FCTL_RETRY)			title = "Retry";		else if (ieee80211_is_assoc_response(fc))			title = "AscRsp";		else if (ieee80211_is_reassoc_response(fc))			title = "RasRsp";		else if (ieee80211_is_probe_response(fc)) {			title = "PrbRsp";			print_dump = 1;	/* dump frame contents */		} else if (ieee80211_is_beacon(fc)) {			title = "Beacon";			print_dump = 1;	/* dump frame contents */		} else if (ieee80211_is_atim(fc))			title = "ATIM";		else if (ieee80211_is_auth(fc))			title = "Auth";		else if (ieee80211_is_deauth(fc))			title = "DeAuth";		else if (ieee80211_is_disassoc(fc))			title = "DisAssoc";		else			title = "Frame";		rate = iwl_rate_index_from_plcp(rate_sym);		if (rate == -1)			rate = 0;		else			rate = iwl_rates[rate].ieee / 2;		/* print frame summary.		 * MAC addresses show just the last byte (for brevity),		 *    but you can hack it to show more, if you'd like to. */		if (dataframe)			IWL_DEBUG_RX("%s: mhd=0x%04x, dst=0x%02x, "				     "len=%u, rssi=%d, chnl=%d, rate=%u, \n",				     title, fc, header->addr1[5],				     length, rssi, channel, rate);		else {			/* src/dst addresses assume managed mode */			IWL_DEBUG_RX("%s: 0x%04x, dst=0x%02x, "				     "src=0x%02x, rssi=%u, tim=%lu usec, "				     "phy=0x%02x, chnl=%d\n",				     title, fc, header->addr1[5],				     header->addr3[5], rssi,				     tsf_low - priv->scan_start_tsf,				     phy_flags, channel);		}	}	if (print_dump)		iwl_print_hex_dump(IWL_DL_RX, data, length);}#endifstatic void iwl_unset_hw_setting(struct iwl_priv *priv){	if (priv->hw_setting.shared_virt)		pci_free_consistent(priv->pci_dev,				    sizeof(struct iwl_shared),				    priv->hw_setting.shared_virt,				    priv->hw_setting.shared_phys);}/** * iwl_supported_rate_to_ie - fill in the supported rate in IE field * * return : set the bit for each supported rate insert in ie */static u16 iwl_supported_rate_to_ie(u8 *ie, u16 supported_rate,				    u16 basic_rate, int *left){	u16 ret_rates = 0, bit;	int i;	u8 *cnt = ie;	u8 *rates = ie + 1;	for (bit = 1, i = 0; i < IWL_RATE_COUNT; i++, bit <<= 1) {		if (bit & supported_rate) {			ret_rates |= bit;			rates[*cnt] = iwl_rates[i].ieee |				((bit & basic_rate) ? 0x80 : 0x00);			(*cnt)++;			(*left)--;			if ((*left <= 0) ||			    (*cnt >= IWL_SUPPORTED_RATES_IE_LEN))				break;		}	}	return ret_rates;}#ifdef CONFIG_IWLWIFI_HTvoid static iwl_set_ht_capab(struct ieee80211_hw *hw,			     struct ieee80211_ht_capability *ht_cap,			     u8 use_wide_chan);#endif/** * iwl_fill_probe_req - fill in all required fields and IE for probe request */static u16 iwl_fill_probe_req(struct iwl_priv *priv,			      struct ieee80211_mgmt *frame,			      int left, int is_direct){	int len = 0;	u8 *pos = NULL;	u16 active_rates, ret_rates, cck_rates;	/* Make sure there is enough space for the probe request,	 * two mandatory IEs and the data */	left -= 24;	if (left < 0)		return 0;	len += 24;	frame->frame_control = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ);	memcpy(frame->da, BROADCAST_ADDR, ETH_ALEN);	memcpy(frame->sa, priv->mac_addr, ETH_ALEN);	memcpy(frame->bssid, BROADCAST_ADDR, ETH_ALEN);	frame->seq_ctrl = 0;	/* fill in our indirect SSID IE */	/* ...next IE... */	left -= 2;	if (left < 0)		return 0;	len += 2;	pos = &(frame->u.probe_req.variable[0]);	*pos++ = WLAN_EID_SSID;	*pos++ = 0;	/* fill in our direct SSID IE... */	if (is_direct) {		/* ...next IE... */		left -= 2 + priv->essid_len;		if (left < 0)			return 0;		/* ... fill it in... */		*pos++ = WLAN_EID_SSID;		*pos++ = priv->essid_len;		memcpy(pos, priv->essid, priv->essid_len);		pos += priv->essid_len;		len += 2 + priv->essid_len;	}	/* fill in supported rate */	/* ...next IE... */	left -= 2;	if (left < 0)		return 0;	/* ... fill it in... */	*pos++ = WLAN_EID_SUPP_RATES;	*pos = 0;	priv->active_rate = priv->rates_mask;	active_rates = priv->active_rate;	priv->active_rate_basic = priv->rates_mask & IWL_BASIC_RATES_MASK;	cck_rates = IWL_CCK_RATES_MASK & active_rates;	ret_rates = iwl_supported_rate_to_ie(pos, cck_rates,			priv->active_rate_basic, &left);	active_rates &= ~ret_rates;	ret_rates = iwl_supported_rate_to_ie(pos, active_rates,				 priv->active_rate_basic, &left);	active_rates &= ~ret_rates;	len += 2 + *pos;	pos += (*pos) + 1;	if (active_rates == 0)		goto fill_end;	/* fill in supported extended rate */	/* ...next IE... */	left -= 2;	if (left < 0)		return 0;	/* ... fill it in... */	*pos++ = WLAN_EID_EXT_SUPP_RATES;	*pos = 0;	iwl_supported_rate_to_ie(pos, active_rates,				 priv->active_rate_basic, &left);	if (*pos > 0)		len += 2 + *pos;#ifdef CONFIG_IWLWIFI_HT	if (is_direct && priv->is_ht_enabled) {		u8 use_wide_chan = 1;		if (priv->channel_width != IWL_CHANNEL_WIDTH_40MHZ)			use_wide_chan = 0;		pos += (*pos) + 1;

⌨️ 快捷键说明

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