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

📄 iwl4965-base.c

📁 linux内核源码
💻 C
📖 第 1 页 / 共 5 页
字号:
		*pos++ = WLAN_EID_HT_CAPABILITY;		*pos++ = sizeof(struct ieee80211_ht_capability);		iwl_set_ht_capab(NULL, (struct ieee80211_ht_capability *)pos,				 use_wide_chan);		len += 2 + sizeof(struct ieee80211_ht_capability);	}#endif  /*CONFIG_IWLWIFI_HT */ fill_end:	return (u16)len;}/* * QoS  support*/#ifdef CONFIG_IWLWIFI_QOSstatic int iwl_send_qos_params_command(struct iwl_priv *priv,				       struct iwl_qosparam_cmd *qos){	return iwl_send_cmd_pdu(priv, REPLY_QOS_PARAM,				sizeof(struct iwl_qosparam_cmd), qos);}static void iwl_reset_qos(struct iwl_priv *priv){	u16 cw_min = 15;	u16 cw_max = 1023;	u8 aifs = 2;	u8 is_legacy = 0;	unsigned long flags;	int i;	spin_lock_irqsave(&priv->lock, flags);	priv->qos_data.qos_active = 0;	if (priv->iw_mode == IEEE80211_IF_TYPE_IBSS) {		if (priv->qos_data.qos_enable)			priv->qos_data.qos_active = 1;		if (!(priv->active_rate & 0xfff0)) {			cw_min = 31;			is_legacy = 1;		}	} else if (priv->iw_mode == IEEE80211_IF_TYPE_AP) {		if (priv->qos_data.qos_enable)			priv->qos_data.qos_active = 1;	} else if (!(priv->staging_rxon.flags & RXON_FLG_SHORT_SLOT_MSK)) {		cw_min = 31;		is_legacy = 1;	}	if (priv->qos_data.qos_active)		aifs = 3;	priv->qos_data.def_qos_parm.ac[0].cw_min = cpu_to_le16(cw_min);	priv->qos_data.def_qos_parm.ac[0].cw_max = cpu_to_le16(cw_max);	priv->qos_data.def_qos_parm.ac[0].aifsn = aifs;	priv->qos_data.def_qos_parm.ac[0].edca_txop = 0;	priv->qos_data.def_qos_parm.ac[0].reserved1 = 0;	if (priv->qos_data.qos_active) {		i = 1;		priv->qos_data.def_qos_parm.ac[i].cw_min = cpu_to_le16(cw_min);		priv->qos_data.def_qos_parm.ac[i].cw_max = cpu_to_le16(cw_max);		priv->qos_data.def_qos_parm.ac[i].aifsn = 7;		priv->qos_data.def_qos_parm.ac[i].edca_txop = 0;		priv->qos_data.def_qos_parm.ac[i].reserved1 = 0;		i = 2;		priv->qos_data.def_qos_parm.ac[i].cw_min =			cpu_to_le16((cw_min + 1) / 2 - 1);		priv->qos_data.def_qos_parm.ac[i].cw_max =			cpu_to_le16(cw_max);		priv->qos_data.def_qos_parm.ac[i].aifsn = 2;		if (is_legacy)			priv->qos_data.def_qos_parm.ac[i].edca_txop =				cpu_to_le16(6016);		else			priv->qos_data.def_qos_parm.ac[i].edca_txop =				cpu_to_le16(3008);		priv->qos_data.def_qos_parm.ac[i].reserved1 = 0;		i = 3;		priv->qos_data.def_qos_parm.ac[i].cw_min =			cpu_to_le16((cw_min + 1) / 4 - 1);		priv->qos_data.def_qos_parm.ac[i].cw_max =			cpu_to_le16((cw_max + 1) / 2 - 1);		priv->qos_data.def_qos_parm.ac[i].aifsn = 2;		priv->qos_data.def_qos_parm.ac[i].reserved1 = 0;		if (is_legacy)			priv->qos_data.def_qos_parm.ac[i].edca_txop =				cpu_to_le16(3264);		else			priv->qos_data.def_qos_parm.ac[i].edca_txop =				cpu_to_le16(1504);	} else {		for (i = 1; i < 4; i++) {			priv->qos_data.def_qos_parm.ac[i].cw_min =				cpu_to_le16(cw_min);			priv->qos_data.def_qos_parm.ac[i].cw_max =				cpu_to_le16(cw_max);			priv->qos_data.def_qos_parm.ac[i].aifsn = aifs;			priv->qos_data.def_qos_parm.ac[i].edca_txop = 0;			priv->qos_data.def_qos_parm.ac[i].reserved1 = 0;		}	}	IWL_DEBUG_QOS("set QoS to default \n");	spin_unlock_irqrestore(&priv->lock, flags);}static void iwl_activate_qos(struct iwl_priv *priv, u8 force){	unsigned long flags;	if (priv == NULL)		return;	if (test_bit(STATUS_EXIT_PENDING, &priv->status))		return;	if (!priv->qos_data.qos_enable)		return;	spin_lock_irqsave(&priv->lock, flags);	priv->qos_data.def_qos_parm.qos_flags = 0;	if (priv->qos_data.qos_cap.q_AP.queue_request &&	    !priv->qos_data.qos_cap.q_AP.txop_request)		priv->qos_data.def_qos_parm.qos_flags |=			QOS_PARAM_FLG_TXOP_TYPE_MSK;	if (priv->qos_data.qos_active)		priv->qos_data.def_qos_parm.qos_flags |=			QOS_PARAM_FLG_UPDATE_EDCA_MSK;	spin_unlock_irqrestore(&priv->lock, flags);	if (force || iwl_is_associated(priv)) {		IWL_DEBUG_QOS("send QoS cmd with Qos active %d \n",			      priv->qos_data.qos_active);		iwl_send_qos_params_command(priv,				&(priv->qos_data.def_qos_parm));	}}#endif /* CONFIG_IWLWIFI_QOS *//* * Power management (not Tx power!) functions */#define MSEC_TO_USEC 1024#define NOSLP __constant_cpu_to_le16(0), 0, 0#define SLP IWL_POWER_DRIVER_ALLOW_SLEEP_MSK, 0, 0#define SLP_TIMEOUT(T) __constant_cpu_to_le32((T) * MSEC_TO_USEC)#define SLP_VEC(X0, X1, X2, X3, X4) {__constant_cpu_to_le32(X0), \				     __constant_cpu_to_le32(X1), \				     __constant_cpu_to_le32(X2), \				     __constant_cpu_to_le32(X3), \				     __constant_cpu_to_le32(X4)}/* default power management (not Tx power) table values *//* for tim  0-10 */static struct iwl_power_vec_entry range_0[IWL_POWER_AC] = {	{{NOSLP, SLP_TIMEOUT(0), SLP_TIMEOUT(0), SLP_VEC(0, 0, 0, 0, 0)}, 0},	{{SLP, SLP_TIMEOUT(200), SLP_TIMEOUT(500), SLP_VEC(1, 2, 3, 4, 4)}, 0},	{{SLP, SLP_TIMEOUT(200), SLP_TIMEOUT(300), SLP_VEC(2, 4, 6, 7, 7)}, 0},	{{SLP, SLP_TIMEOUT(50), SLP_TIMEOUT(100), SLP_VEC(2, 6, 9, 9, 10)}, 0},	{{SLP, SLP_TIMEOUT(50), SLP_TIMEOUT(25), SLP_VEC(2, 7, 9, 9, 10)}, 1},	{{SLP, SLP_TIMEOUT(25), SLP_TIMEOUT(25), SLP_VEC(4, 7, 10, 10, 10)}, 1}};/* for tim > 10 */static struct iwl_power_vec_entry range_1[IWL_POWER_AC] = {	{{NOSLP, SLP_TIMEOUT(0), SLP_TIMEOUT(0), SLP_VEC(0, 0, 0, 0, 0)}, 0},	{{SLP, SLP_TIMEOUT(200), SLP_TIMEOUT(500),		 SLP_VEC(1, 2, 3, 4, 0xFF)}, 0},	{{SLP, SLP_TIMEOUT(200), SLP_TIMEOUT(300),		 SLP_VEC(2, 4, 6, 7, 0xFF)}, 0},	{{SLP, SLP_TIMEOUT(50), SLP_TIMEOUT(100),		 SLP_VEC(2, 6, 9, 9, 0xFF)}, 0},	{{SLP, SLP_TIMEOUT(50), SLP_TIMEOUT(25), SLP_VEC(2, 7, 9, 9, 0xFF)}, 0},	{{SLP, SLP_TIMEOUT(25), SLP_TIMEOUT(25),		 SLP_VEC(4, 7, 10, 10, 0xFF)}, 0}};int iwl_power_init_handle(struct iwl_priv *priv){	int rc = 0, i;	struct iwl_power_mgr *pow_data;	int size = sizeof(struct iwl_power_vec_entry) * IWL_POWER_AC;	u16 pci_pm;	IWL_DEBUG_POWER("Initialize power \n");	pow_data = &(priv->power_data);	memset(pow_data, 0, sizeof(*pow_data));	pow_data->active_index = IWL_POWER_RANGE_0;	pow_data->dtim_val = 0xffff;	memcpy(&pow_data->pwr_range_0[0], &range_0[0], size);	memcpy(&pow_data->pwr_range_1[0], &range_1[0], size);	rc = pci_read_config_word(priv->pci_dev, PCI_LINK_CTRL, &pci_pm);	if (rc != 0)		return 0;	else {		struct iwl_powertable_cmd *cmd;		IWL_DEBUG_POWER("adjust power command flags\n");		for (i = 0; i < IWL_POWER_AC; i++) {			cmd = &pow_data->pwr_range_0[i].cmd;			if (pci_pm & 0x1)				cmd->flags &= ~IWL_POWER_PCI_PM_MSK;			else				cmd->flags |= IWL_POWER_PCI_PM_MSK;		}	}	return rc;}static int iwl_update_power_cmd(struct iwl_priv *priv,				struct iwl_powertable_cmd *cmd, u32 mode){	int rc = 0, i;	u8 skip;	u32 max_sleep = 0;	struct iwl_power_vec_entry *range;	u8 period = 0;	struct iwl_power_mgr *pow_data;	if (mode > IWL_POWER_INDEX_5) {		IWL_DEBUG_POWER("Error invalid power mode \n");		return -1;	}	pow_data = &(priv->power_data);	if (pow_data->active_index == IWL_POWER_RANGE_0)		range = &pow_data->pwr_range_0[0];	else		range = &pow_data->pwr_range_1[1];	memcpy(cmd, &range[mode].cmd, sizeof(struct iwl_powertable_cmd));#ifdef IWL_MAC80211_DISABLE	if (priv->assoc_network != NULL) {		unsigned long flags;		period = priv->assoc_network->tim.tim_period;	}#endif	/*IWL_MAC80211_DISABLE */	skip = range[mode].no_dtim;	if (period == 0) {		period = 1;		skip = 0;	}	if (skip == 0) {		max_sleep = period;		cmd->flags &= ~IWL_POWER_SLEEP_OVER_DTIM_MSK;	} else {		__le32 slp_itrvl = cmd->sleep_interval[IWL_POWER_VEC_SIZE - 1];		max_sleep = (le32_to_cpu(slp_itrvl) / period) * period;		cmd->flags |= IWL_POWER_SLEEP_OVER_DTIM_MSK;	}	for (i = 0; i < IWL_POWER_VEC_SIZE; i++) {		if (le32_to_cpu(cmd->sleep_interval[i]) > max_sleep)			cmd->sleep_interval[i] = cpu_to_le32(max_sleep);	}	IWL_DEBUG_POWER("Flags value = 0x%08X\n", cmd->flags);	IWL_DEBUG_POWER("Tx timeout = %u\n", le32_to_cpu(cmd->tx_data_timeout));	IWL_DEBUG_POWER("Rx timeout = %u\n", le32_to_cpu(cmd->rx_data_timeout));	IWL_DEBUG_POWER("Sleep interval vector = { %d , %d , %d , %d , %d }\n",			le32_to_cpu(cmd->sleep_interval[0]),			le32_to_cpu(cmd->sleep_interval[1]),			le32_to_cpu(cmd->sleep_interval[2]),			le32_to_cpu(cmd->sleep_interval[3]),			le32_to_cpu(cmd->sleep_interval[4]));	return rc;}static int iwl_send_power_mode(struct iwl_priv *priv, u32 mode){	u32 final_mode = mode;	int rc;	struct iwl_powertable_cmd cmd;	/* If on battery, set to 3,	 * if plugged into AC power, set to CAM ("continuosly aware mode"),	 * else user level */	switch (mode) {	case IWL_POWER_BATTERY:		final_mode = IWL_POWER_INDEX_3;		break;	case IWL_POWER_AC:		final_mode = IWL_POWER_MODE_CAM;		break;	default:		final_mode = mode;		break;	}	cmd.keep_alive_beacons = 0;	iwl_update_power_cmd(priv, &cmd, final_mode);	rc = iwl_send_cmd_pdu(priv, POWER_TABLE_CMD, sizeof(cmd), &cmd);	if (final_mode == IWL_POWER_MODE_CAM)		clear_bit(STATUS_POWER_PMI, &priv->status);	else		set_bit(STATUS_POWER_PMI, &priv->status);	return rc;}int iwl_is_network_packet(struct iwl_priv *priv, struct ieee80211_hdr *header){	/* Filter incoming packets to determine if they are targeted toward	 * this network, discarding packets coming from ourselves */	switch (priv->iw_mode) {	case IEEE80211_IF_TYPE_IBSS: /* Header: Dest. | Source    | BSSID */		/* packets from our adapter are dropped (echo) */		if (!compare_ether_addr(header->addr2, priv->mac_addr))			return 0;		/* {broad,multi}cast packets to our IBSS go through */		if (is_multicast_ether_addr(header->addr1))			return !compare_ether_addr(header->addr3, priv->bssid);		/* packets to our adapter go through */		return !compare_ether_addr(header->addr1, priv->mac_addr);	case IEEE80211_IF_TYPE_STA: /* Header: Dest. | AP{BSSID} | Source */		/* packets from our adapter are dropped (echo) */		if (!compare_ether_addr(header->addr3, priv->mac_addr))			return 0;		/* {broad,multi}cast packets to our BSS go through */		if (is_multicast_ether_addr(header->addr1))			return !compare_ether_addr(header->addr2, priv->bssid);		/* packets to our adapter go through */		return !compare_ether_addr(header->addr1, priv->mac_addr);	}	return 1;}#define TX_STATUS_ENTRY(x) case TX_STATUS_FAIL_ ## x: return #xconst char *iwl_get_tx_fail_reason(u32 status){	switch (status & TX_STATUS_MSK) {	case TX_STATUS_SUCCESS:		return "SUCCESS";		TX_STATUS_ENTRY(SHORT_LIMIT);		TX_STATUS_ENTRY(LONG_LIMIT);		TX_STATUS_ENTRY(FIFO_UNDERRUN);		TX_STATUS_ENTRY(MGMNT_ABORT);		TX_STATUS_ENTRY(NEXT_FRAG);		TX_STATUS_ENTRY(LIFE_EXPIRE);		TX_STATUS_ENTRY(DEST_PS);		TX_STATUS_ENTRY(ABORTED);		TX_STATUS_ENTRY(BT_RETRY);		TX_STATUS_ENTRY(STA_INVALID);		TX_STATUS_ENTRY(FRAG_DROPPED);		TX_STATUS_ENTRY(TID_DISABLE);		TX_STATUS_ENTRY(FRAME_FLUSHED);		TX_STATUS_ENTRY(INSUFFICIENT_CF_POLL);		TX_STATUS_ENTRY(TX_LOCKED);		TX_STATUS_ENTRY(NO_BEACON_ON_RADAR);	}	return "UNKNOWN";}/** * iwl_scan_cancel - Cancel any currently executing HW scan * * NOTE: priv->mutex is not required before calling this function */static int iwl_scan_cancel(struct iwl_priv *priv){	if (!test_bit(STATUS_SCAN_HW, &priv->status)) {		clear_bit(STATUS_SCANNING, &priv->status);		return 0;	}	if (test_bit(STATUS_SCANNING, &priv->status)) {		if (!test_bit(STATUS_SCAN_ABORTING, &priv->status)) {			IWL_DEBUG_SCAN("Queuing scan abort.\n");			set_bit(STATUS_SCAN_ABORTING, &priv->status);			queue_work(priv->workqueue, &priv->abort_scan);		} else			IWL_DEBUG_SCAN("Scan abort already in progress.\n");		return test_bit(STATUS_SCANNING, &priv->status);	}	return 0;}/** * iwl_scan_cancel_timeout - Cancel any currently executing HW scan * @ms: amount of time to wait (in milliseconds) for scan to abort * * NOTE: priv->mutex must be held before calling this function */static int iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms){	unsigned long now = jiffies;	int ret;	ret = iwl_scan_cancel(priv);	if (ret && ms) {		mutex_unlock(&priv->mutex);		while (!time_after(jiffies, now + msecs_to_jiffies(ms)) &&				test_bit(STATUS_SCANNING, &priv->status))			msleep(1);		mutex_lock(&priv->mutex);		return test_bit(STATUS_SCANNING, &priv->status);	}	return ret;}static void iwl_sequence_reset(struct iwl_priv *priv){	/* Reset ieee stats */	/* We don't reset the net_device_stats (ieee->stats) on	 * re-association */	priv->last_seq_num = -1;	priv->last_frag_num = -1;	priv->last_packet_time = 0;	iwl_scan_cancel(priv);}#define MAX_UCODE_BEACON_INTERVAL	4096#define INTEL_CONN_LISTEN_INTERVAL	__constant_cpu_to_le16(0xA)static __le16 iwl_adjust_beacon_interval(u16 beacon_val){	u16 new_val = 0;	u16 beacon_factor = 0;	beacon_factor =	    (beacon_val + MAX_UCODE_BEACON_INTERVAL)		/ MAX_UCODE_BEACON_INTERVAL;	new_val = beacon_val / beacon_factor;	return cpu_to_le16(new_val);}static void iwl_setup_rxon_timing(struct iwl_priv *priv){	u64 interval_tm_unit;	u64 tsf, result;	unsigned long flags;	struct ieee80211_conf *conf = NULL;	u16 beacon_int = 0;	conf = ieee80211_get_hw_conf(priv->hw);	spin_lock_irqsave(&priv->lock, flags);	priv->rxon_timing.timestamp.dw[1] = cpu_to_le32(priv->timestamp1);	priv->rxon_timing.timestamp.dw[0] = cpu_to_le32(priv->timestamp0);	priv->rxon_timing.listen_interval = INTEL_CONN_LISTEN_INTER

⌨️ 快捷键说明

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