diff options
Diffstat (limited to 'drivers/net/wireless/rtlwifi')
73 files changed, 14642 insertions, 1708 deletions
diff --git a/drivers/net/wireless/rtlwifi/Kconfig b/drivers/net/wireless/rtlwifi/Kconfig index ce49e0ce7ca..5aee8b22d74 100644 --- a/drivers/net/wireless/rtlwifi/Kconfig +++ b/drivers/net/wireless/rtlwifi/Kconfig @@ -10,6 +10,17 @@ config RTL8192CE If you choose to build it as a module, it will be called rtl8192ce +config RTL8192SE + tristate "Realtek RTL8192SE/RTL8191SE PCIe Wireless Network Adapter" + depends on MAC80211 && EXPERIMENTAL + select FW_LOADER + select RTLWIFI + ---help--- + This is the driver for Realtek RTL8192SE/RTL8191SE 802.11n PCIe + wireless network adapters. + + If you choose to build it as a module, it will be called rtl8192se + config RTL8192CU tristate "Realtek RTL8192CU/RTL8188CU USB Wireless Network Adapter" depends on MAC80211 && USB && EXPERIMENTAL @@ -24,10 +35,10 @@ config RTL8192CU config RTLWIFI tristate - depends on RTL8192CE || RTL8192CU + depends on RTL8192CE || RTL8192CU || RTL8192SE default m config RTL8192C_COMMON tristate - depends on RTL8192CE || RTL8192CU + depends on RTL8192CE || RTL8192CU || RTL8192SE default m diff --git a/drivers/net/wireless/rtlwifi/Makefile b/drivers/net/wireless/rtlwifi/Makefile index ec9393f2479..7acce83c378 100644 --- a/drivers/net/wireless/rtlwifi/Makefile +++ b/drivers/net/wireless/rtlwifi/Makefile @@ -22,5 +22,6 @@ endif obj-$(CONFIG_RTL8192C_COMMON) += rtl8192c/ obj-$(CONFIG_RTL8192CE) += rtl8192ce/ obj-$(CONFIG_RTL8192CU) += rtl8192cu/ +obj-$(CONFIG_RTL8192SE) += rtl8192se/ ccflags-y += -D__CHECK_ENDIAN__ diff --git a/drivers/net/wireless/rtlwifi/base.c b/drivers/net/wireless/rtlwifi/base.c index 0d7d93e1d39..ccb6da38fe2 100644 --- a/drivers/net/wireless/rtlwifi/base.c +++ b/drivers/net/wireless/rtlwifi/base.c @@ -50,8 +50,9 @@ *3) functions called by core.c *4) wq & timer callback functions *5) frame process functions - *6) sysfs functions - *7) ... + *6) IOT functions + *7) sysfs functions + *8) ... */ /********************************************************* @@ -59,7 +60,7 @@ * mac80211 init functions * *********************************************************/ -static struct ieee80211_channel rtl_channeltable[] = { +static struct ieee80211_channel rtl_channeltable_2g[] = { {.center_freq = 2412, .hw_value = 1,}, {.center_freq = 2417, .hw_value = 2,}, {.center_freq = 2422, .hw_value = 3,}, @@ -76,7 +77,34 @@ static struct ieee80211_channel rtl_channeltable[] = { {.center_freq = 2484, .hw_value = 14,}, }; -static struct ieee80211_rate rtl_ratetable[] = { +static struct ieee80211_channel rtl_channeltable_5g[] = { + {.center_freq = 5180, .hw_value = 36,}, + {.center_freq = 5200, .hw_value = 40,}, + {.center_freq = 5220, .hw_value = 44,}, + {.center_freq = 5240, .hw_value = 48,}, + {.center_freq = 5260, .hw_value = 52,}, + {.center_freq = 5280, .hw_value = 56,}, + {.center_freq = 5300, .hw_value = 60,}, + {.center_freq = 5320, .hw_value = 64,}, + {.center_freq = 5500, .hw_value = 100,}, + {.center_freq = 5520, .hw_value = 104,}, + {.center_freq = 5540, .hw_value = 108,}, + {.center_freq = 5560, .hw_value = 112,}, + {.center_freq = 5580, .hw_value = 116,}, + {.center_freq = 5600, .hw_value = 120,}, + {.center_freq = 5620, .hw_value = 124,}, + {.center_freq = 5640, .hw_value = 128,}, + {.center_freq = 5660, .hw_value = 132,}, + {.center_freq = 5680, .hw_value = 136,}, + {.center_freq = 5700, .hw_value = 140,}, + {.center_freq = 5745, .hw_value = 149,}, + {.center_freq = 5765, .hw_value = 153,}, + {.center_freq = 5785, .hw_value = 157,}, + {.center_freq = 5805, .hw_value = 161,}, + {.center_freq = 5825, .hw_value = 165,}, +}; + +static struct ieee80211_rate rtl_ratetable_2g[] = { {.bitrate = 10, .hw_value = 0x00,}, {.bitrate = 20, .hw_value = 0x01,}, {.bitrate = 55, .hw_value = 0x02,}, @@ -91,18 +119,57 @@ static struct ieee80211_rate rtl_ratetable[] = { {.bitrate = 540, .hw_value = 0x0b,}, }; +static struct ieee80211_rate rtl_ratetable_5g[] = { + {.bitrate = 60, .hw_value = 0x04,}, + {.bitrate = 90, .hw_value = 0x05,}, + {.bitrate = 120, .hw_value = 0x06,}, + {.bitrate = 180, .hw_value = 0x07,}, + {.bitrate = 240, .hw_value = 0x08,}, + {.bitrate = 360, .hw_value = 0x09,}, + {.bitrate = 480, .hw_value = 0x0a,}, + {.bitrate = 540, .hw_value = 0x0b,}, +}; + static const struct ieee80211_supported_band rtl_band_2ghz = { .band = IEEE80211_BAND_2GHZ, - .channels = rtl_channeltable, - .n_channels = ARRAY_SIZE(rtl_channeltable), + .channels = rtl_channeltable_2g, + .n_channels = ARRAY_SIZE(rtl_channeltable_2g), - .bitrates = rtl_ratetable, - .n_bitrates = ARRAY_SIZE(rtl_ratetable), + .bitrates = rtl_ratetable_2g, + .n_bitrates = ARRAY_SIZE(rtl_ratetable_2g), .ht_cap = {0}, }; +static struct ieee80211_supported_band rtl_band_5ghz = { + .band = IEEE80211_BAND_5GHZ, + + .channels = rtl_channeltable_5g, + .n_channels = ARRAY_SIZE(rtl_channeltable_5g), + + .bitrates = rtl_ratetable_5g, + .n_bitrates = ARRAY_SIZE(rtl_ratetable_5g), + + .ht_cap = {0}, +}; + +static const u8 tid_to_ac[] = { + 2, /* IEEE80211_AC_BE */ + 3, /* IEEE80211_AC_BK */ + 3, /* IEEE80211_AC_BK */ + 2, /* IEEE80211_AC_BE */ + 1, /* IEEE80211_AC_VI */ + 1, /* IEEE80211_AC_VI */ + 0, /* IEEE80211_AC_VO */ + 0, /* IEEE80211_AC_VO */ +}; + +u8 rtl_tid_to_ac(struct ieee80211_hw *hw, u8 tid) +{ + return tid_to_ac[tid]; +} + static void _rtl_init_hw_ht_capab(struct ieee80211_hw *hw, struct ieee80211_sta_ht_cap *ht_cap) { @@ -115,6 +182,9 @@ static void _rtl_init_hw_ht_capab(struct ieee80211_hw *hw, IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_DSSSCCK40 | IEEE80211_HT_CAP_MAX_AMSDU; + if (rtlpriv->rtlhal.disable_amsdu_8k) + ht_cap->cap &= ~IEEE80211_HT_CAP_MAX_AMSDU; + /* *Maximum length of AMPDU that the STA can receive. *Length = 2 ^ (13 + max_ampdu_length_exp) - 1 (octets) @@ -159,37 +229,99 @@ static void _rtl_init_hw_ht_capab(struct ieee80211_hw *hw, static void _rtl_init_mac80211(struct ieee80211_hw *hw) { + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtlpriv); struct rtl_mac *rtlmac = rtl_mac(rtl_priv(hw)); struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); struct ieee80211_supported_band *sband; - /* <1> use mac->bands as mem for hw->wiphy->bands */ - sband = &(rtlmac->bands[IEEE80211_BAND_2GHZ]); - /* - * <2> set hw->wiphy->bands[IEEE80211_BAND_2GHZ] - * to default value(1T1R) - */ - memcpy(&(rtlmac->bands[IEEE80211_BAND_2GHZ]), &rtl_band_2ghz, - sizeof(struct ieee80211_supported_band)); + if (rtlhal->macphymode == SINGLEMAC_SINGLEPHY && rtlhal->bandset == + BAND_ON_BOTH) { + /* 1: 2.4 G bands */ + /* <1> use mac->bands as mem for hw->wiphy->bands */ + sband = &(rtlmac->bands[IEEE80211_BAND_2GHZ]); + + /* <2> set hw->wiphy->bands[IEEE80211_BAND_2GHZ] + * to default value(1T1R) */ + memcpy(&(rtlmac->bands[IEEE80211_BAND_2GHZ]), &rtl_band_2ghz, + sizeof(struct ieee80211_supported_band)); - /* <3> init ht cap base on ant_num */ - _rtl_init_hw_ht_capab(hw, &sband->ht_cap); + /* <3> init ht cap base on ant_num */ + _rtl_init_hw_ht_capab(hw, &sband->ht_cap); - /* <4> set mac->sband to wiphy->sband */ - hw->wiphy->bands[IEEE80211_BAND_2GHZ] = sband; + /* <4> set mac->sband to wiphy->sband */ + hw->wiphy->bands[IEEE80211_BAND_2GHZ] = sband; + /* 2: 5 G bands */ + /* <1> use mac->bands as mem for hw->wiphy->bands */ + sband = &(rtlmac->bands[IEEE80211_BAND_5GHZ]); + + /* <2> set hw->wiphy->bands[IEEE80211_BAND_5GHZ] + * to default value(1T1R) */ + memcpy(&(rtlmac->bands[IEEE80211_BAND_5GHZ]), &rtl_band_5ghz, + sizeof(struct ieee80211_supported_band)); + + /* <3> init ht cap base on ant_num */ + _rtl_init_hw_ht_capab(hw, &sband->ht_cap); + + /* <4> set mac->sband to wiphy->sband */ + hw->wiphy->bands[IEEE80211_BAND_5GHZ] = sband; + } else { + if (rtlhal->current_bandtype == BAND_ON_2_4G) { + /* <1> use mac->bands as mem for hw->wiphy->bands */ + sband = &(rtlmac->bands[IEEE80211_BAND_2GHZ]); + + /* <2> set hw->wiphy->bands[IEEE80211_BAND_2GHZ] + * to default value(1T1R) */ + memcpy(&(rtlmac->bands[IEEE80211_BAND_2GHZ]), + &rtl_band_2ghz, + sizeof(struct ieee80211_supported_band)); + + /* <3> init ht cap base on ant_num */ + _rtl_init_hw_ht_capab(hw, &sband->ht_cap); + + /* <4> set mac->sband to wiphy->sband */ + hw->wiphy->bands[IEEE80211_BAND_2GHZ] = sband; + } else if (rtlhal->current_bandtype == BAND_ON_5G) { + /* <1> use mac->bands as mem for hw->wiphy->bands */ + sband = &(rtlmac->bands[IEEE80211_BAND_5GHZ]); + + /* <2> set hw->wiphy->bands[IEEE80211_BAND_5GHZ] + * to default value(1T1R) */ + memcpy(&(rtlmac->bands[IEEE80211_BAND_5GHZ]), + &rtl_band_5ghz, + sizeof(struct ieee80211_supported_band)); + + /* <3> init ht cap base on ant_num */ + _rtl_init_hw_ht_capab(hw, &sband->ht_cap); + + /* <4> set mac->sband to wiphy->sband */ + hw->wiphy->bands[IEEE80211_BAND_5GHZ] = sband; + } else { + RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, + ("Err BAND %d\n", + rtlhal->current_bandtype)); + } + } /* <5> set hw caps */ hw->flags = IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_RX_INCLUDES_FCS | - IEEE80211_HW_BEACON_FILTER | IEEE80211_HW_AMPDU_AGGREGATION | /*PS*/ - /*IEEE80211_HW_SUPPORTS_PS | */ - /*IEEE80211_HW_PS_NULLFUNC_STACK | */ - /*IEEE80211_HW_SUPPORTS_DYNAMIC_PS | */ + IEEE80211_HW_BEACON_FILTER | + IEEE80211_HW_AMPDU_AGGREGATION | IEEE80211_HW_REPORTS_TX_ACK_STATUS | 0; + /* swlps or hwlps has been set in diff chip in init_sw_vars */ + if (rtlpriv->psc.swctrl_lps) + hw->flags |= IEEE80211_HW_SUPPORTS_PS | + IEEE80211_HW_PS_NULLFUNC_STACK | + /* IEEE80211_HW_SUPPORTS_DYNAMIC_PS | */ + 0; + hw->wiphy->interface_modes = - BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC); + BIT(NL80211_IFTYPE_AP) | + BIT(NL80211_IFTYPE_STATION) | + BIT(NL80211_IFTYPE_ADHOC); hw->wiphy->rts_threshold = 2347; @@ -199,9 +331,10 @@ static void _rtl_init_mac80211(struct ieee80211_hw *hw) /* TODO: Correct this value for our hw */ /* TODO: define these hard code value */ hw->channel_change_time = 100; - hw->max_listen_interval = 5; + hw->max_listen_interval = 10; hw->max_rate_tries = 4; /* hw->max_rates = 1; */ + hw->sta_data_size = sizeof(struct rtl_sta_info); /* <6> mac address */ if (is_valid_ether_addr(rtlefuse->dev_addr)) { @@ -230,6 +363,10 @@ static void _rtl_init_deferred_work(struct ieee80211_hw *hw) (void *)rtl_watchdog_wq_callback); INIT_DELAYED_WORK(&rtlpriv->works.ips_nic_off_wq, (void *)rtl_ips_nic_off_wq_callback); + INIT_DELAYED_WORK(&rtlpriv->works.ps_work, + (void *)rtl_swlps_wq_callback); + INIT_DELAYED_WORK(&rtlpriv->works.ps_rfon_wq, + (void *)rtl_swlps_rfon_wq_callback); } @@ -241,6 +378,8 @@ void rtl_deinit_deferred_work(struct ieee80211_hw *hw) cancel_delayed_work(&rtlpriv->works.watchdog_wq); cancel_delayed_work(&rtlpriv->works.ips_nic_off_wq); + cancel_delayed_work(&rtlpriv->works.ps_work); + cancel_delayed_work(&rtlpriv->works.ps_rfon_wq); } void rtl_init_rfkill(struct ieee80211_hw *hw) @@ -251,14 +390,16 @@ void rtl_init_rfkill(struct ieee80211_hw *hw) bool blocked; u8 valid = 0; - radio_state = rtlpriv->cfg->ops->radio_onoff_checking(hw, &valid); + /*set init state to on */ + rtlpriv->rfkill.rfkill_state = 1; + wiphy_rfkill_set_hw_state(hw->wiphy, 0); - /*set init state to that of switch */ - rtlpriv->rfkill.rfkill_state = radio_state; - printk(KERN_INFO "rtlwifi: wireless switch is %s\n", - rtlpriv->rfkill.rfkill_state ? "on" : "off"); + radio_state = rtlpriv->cfg->ops->radio_onoff_checking(hw, &valid); if (valid) { + printk(KERN_INFO "rtlwifi: wireless switch is %s\n", + rtlpriv->rfkill.rfkill_state ? "on" : "off"); + rtlpriv->rfkill.rfkill_state = radio_state; blocked = (rtlpriv->rfkill.rfkill_state == 1) ? 0 : 1; @@ -308,6 +449,8 @@ int rtl_init_core(struct ieee80211_hw *hw) spin_lock_init(&rtlpriv->locks.rf_ps_lock); spin_lock_init(&rtlpriv->locks.rf_lock); spin_lock_init(&rtlpriv->locks.lps_lock); + spin_lock_init(&rtlpriv->locks.waitq_lock); + spin_lock_init(&rtlpriv->locks.cck_and_rw_pagea_lock); rtlmac->link_state = MAC80211_NOLINK; @@ -327,12 +470,6 @@ void rtl_init_rx_config(struct ieee80211_hw *hw) struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_RCR, (u8 *) (&mac->rx_conf)); - rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_MGT_FILTER, - (u8 *) (&mac->rx_mgt_filter)); - rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_CTRL_FILTER, - (u8 *) (&mac->rx_ctrl_filter)); - rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_DATA_FILTER, - (u8 *) (&mac->rx_data_filter)); } /********************************************************* @@ -359,28 +496,40 @@ static void _rtl_qurey_shortpreamble_mode(struct ieee80211_hw *hw, } static void _rtl_query_shortgi(struct ieee80211_hw *hw, + struct ieee80211_sta *sta, struct rtl_tcb_desc *tcb_desc, struct ieee80211_tx_info *info) { struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); u8 rate_flag = info->control.rates[0].flags; - + u8 sgi_40 = 0, sgi_20 = 0, bw_40 = 0; tcb_desc->use_shortgi = false; - if (!mac->ht_enable) + if (sta == NULL) + return; + + sgi_40 = sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40; + sgi_20 = sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20; + + if (!(sta->ht_cap.ht_supported)) return; - if (!mac->sgi_40 && !mac->sgi_20) + if (!sgi_40 && !sgi_20) return; - if ((mac->bw_40 == true) && mac->sgi_40) + if (mac->opmode == NL80211_IFTYPE_STATION) + bw_40 = mac->bw_40; + else if (mac->opmode == NL80211_IFTYPE_AP || + mac->opmode == NL80211_IFTYPE_ADHOC) + bw_40 = sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40; + + if ((bw_40 == true) && sgi_40) tcb_desc->use_shortgi = true; - else if ((mac->bw_40 == false) && mac->sgi_20) + else if ((bw_40 == false) && sgi_20) tcb_desc->use_shortgi = true; if (!(rate_flag & IEEE80211_TX_RC_SHORT_GI)) tcb_desc->use_shortgi = false; - } static void _rtl_query_protection_mode(struct ieee80211_hw *hw, @@ -408,19 +557,25 @@ static void _rtl_query_protection_mode(struct ieee80211_hw *hw, tcb_desc->rts_enable = true; tcb_desc->rts_rate = rtlpriv->cfg->maps[RTL_RC_OFDM_RATE24M]; } - } static void _rtl_txrate_selectmode(struct ieee80211_hw *hw, + struct ieee80211_sta *sta, struct rtl_tcb_desc *tcb_desc) { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_sta_info *sta_entry = NULL; + u8 ratr_index = 7; + if (sta) { + sta_entry = (struct rtl_sta_info *) sta->drv_priv; + ratr_index = sta_entry->ratr_index; + } if (!tcb_desc->disable_ratefallback || !tcb_desc->use_driver_rate) { - if (mac->opmode == NL80211_IFTYPE_STATION) + if (mac->opmode == NL80211_IFTYPE_STATION) { tcb_desc->ratr_index = 0; - else if (mac->opmode == NL80211_IFTYPE_ADHOC) { + } else if (mac->opmode == NL80211_IFTYPE_ADHOC) { if (tcb_desc->multicast || tcb_desc->broadcast) { tcb_desc->hw_rate = rtlpriv->cfg->maps[RTL_RC_CCK_RATE2M]; @@ -428,36 +583,61 @@ static void _rtl_txrate_selectmode(struct ieee80211_hw *hw, } else { /* TODO */ } + tcb_desc->ratr_index = ratr_index; + } else if (mac->opmode == NL80211_IFTYPE_AP) { + tcb_desc->ratr_index = ratr_index; } } if (rtlpriv->dm.useramask) { /* TODO we will differentiate adhoc and station futrue */ - tcb_desc->mac_id = 0; - - if ((mac->mode == WIRELESS_MODE_N_24G) || - (mac->mode == WIRELESS_MOD |