📄 iwl3945-base.c
字号:
if (priv->ibss_beacon->len > left) return 0; memcpy(hdr, priv->ibss_beacon->data, priv->ibss_beacon->len); return priv->ibss_beacon->len;}static int iwl_rate_index_from_plcp(int plcp){ int i = 0; for (i = 0; i < IWL_RATE_COUNT; i++) if (iwl_rates[i].plcp == plcp) 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); return -ETIMEDOUT; } e[addr / 2] = le16_to_cpu(r >> 16); } return 0;}/****************************************************************************** * * 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;}/** * 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; 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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -