diff options
Diffstat (limited to 'drivers/net/wireless/rtl818x/rtl8187_dev.c')
-rw-r--r-- | drivers/net/wireless/rtl818x/rtl8187_dev.c | 73 |
1 files changed, 67 insertions, 6 deletions
diff --git a/drivers/net/wireless/rtl818x/rtl8187_dev.c b/drivers/net/wireless/rtl818x/rtl8187_dev.c index 5fe7473124e8..cb5bcefd1c3e 100644 --- a/drivers/net/wireless/rtl818x/rtl8187_dev.c +++ b/drivers/net/wireless/rtl818x/rtl8187_dev.c | |||
@@ -712,6 +712,13 @@ static int rtl8187b_init_hw(struct ieee80211_hw *dev) | |||
712 | 712 | ||
713 | rtl818x_iowrite16_idx(priv, (__le16 *)0xFFEC, 0x0800, 1); | 713 | rtl818x_iowrite16_idx(priv, (__le16 *)0xFFEC, 0x0800, 1); |
714 | 714 | ||
715 | priv->slot_time = 0x9; | ||
716 | priv->aifsn[0] = 2; /* AIFSN[AC_VO] */ | ||
717 | priv->aifsn[1] = 2; /* AIFSN[AC_VI] */ | ||
718 | priv->aifsn[2] = 7; /* AIFSN[AC_BK] */ | ||
719 | priv->aifsn[3] = 3; /* AIFSN[AC_BE] */ | ||
720 | rtl818x_iowrite8(priv, &priv->map->ACM_CONTROL, 0); | ||
721 | |||
715 | return 0; | 722 | return 0; |
716 | } | 723 | } |
717 | 724 | ||
@@ -919,24 +926,38 @@ static int rtl8187_config_interface(struct ieee80211_hw *dev, | |||
919 | return 0; | 926 | return 0; |
920 | } | 927 | } |
921 | 928 | ||
929 | /* | ||
930 | * With 8187B, AC_*_PARAM clashes with FEMR definition in struct rtl818x_csr for | ||
931 | * example. Thus we have to use raw values for AC_*_PARAM register addresses. | ||
932 | */ | ||
933 | static __le32 *rtl8187b_ac_addr[4] = { | ||
934 | (__le32 *) 0xFFF0, /* AC_VO */ | ||
935 | (__le32 *) 0xFFF4, /* AC_VI */ | ||
936 | (__le32 *) 0xFFFC, /* AC_BK */ | ||
937 | (__le32 *) 0xFFF8, /* AC_BE */ | ||
938 | }; | ||
939 | |||
940 | #define SIFS_TIME 0xa | ||
941 | |||
922 | static void rtl8187_conf_erp(struct rtl8187_priv *priv, bool use_short_slot, | 942 | static void rtl8187_conf_erp(struct rtl8187_priv *priv, bool use_short_slot, |
923 | bool use_short_preamble) | 943 | bool use_short_preamble) |
924 | { | 944 | { |
925 | if (priv->is_rtl8187b) { | 945 | if (priv->is_rtl8187b) { |
926 | u8 difs, eifs, slot_time; | 946 | u8 difs, eifs; |
927 | u16 ack_timeout; | 947 | u16 ack_timeout; |
948 | int queue; | ||
928 | 949 | ||
929 | if (use_short_slot) { | 950 | if (use_short_slot) { |
930 | slot_time = 0x9; | 951 | priv->slot_time = 0x9; |
931 | difs = 0x1c; | 952 | difs = 0x1c; |
932 | eifs = 0x53; | 953 | eifs = 0x53; |
933 | } else { | 954 | } else { |
934 | slot_time = 0x14; | 955 | priv->slot_time = 0x14; |
935 | difs = 0x32; | 956 | difs = 0x32; |
936 | eifs = 0x5b; | 957 | eifs = 0x5b; |
937 | } | 958 | } |
938 | rtl818x_iowrite8(priv, &priv->map->SIFS, 0x22); | 959 | rtl818x_iowrite8(priv, &priv->map->SIFS, 0x22); |
939 | rtl818x_iowrite8(priv, &priv->map->SLOT, slot_time); | 960 | rtl818x_iowrite8(priv, &priv->map->SLOT, priv->slot_time); |
940 | rtl818x_iowrite8(priv, &priv->map->DIFS, difs); | 961 | rtl818x_iowrite8(priv, &priv->map->DIFS, difs); |
941 | 962 | ||
942 | /* | 963 | /* |
@@ -957,18 +978,21 @@ static void rtl8187_conf_erp(struct rtl8187_priv *priv, bool use_short_slot, | |||
957 | ack_timeout += 144; | 978 | ack_timeout += 144; |
958 | rtl818x_iowrite8(priv, &priv->map->CARRIER_SENSE_COUNTER, | 979 | rtl818x_iowrite8(priv, &priv->map->CARRIER_SENSE_COUNTER, |
959 | DIV_ROUND_UP(ack_timeout, 4)); | 980 | DIV_ROUND_UP(ack_timeout, 4)); |
981 | |||
982 | for (queue = 0; queue < 4; queue++) | ||
983 | rtl818x_iowrite8(priv, (u8 *) rtl8187b_ac_addr[queue], | ||
984 | priv->aifsn[queue] * priv->slot_time + | ||
985 | SIFS_TIME); | ||
960 | } else { | 986 | } else { |
961 | rtl818x_iowrite8(priv, &priv->map->SIFS, 0x22); | 987 | rtl818x_iowrite8(priv, &priv->map->SIFS, 0x22); |
962 | if (use_short_slot) { | 988 | if (use_short_slot) { |
963 | rtl818x_iowrite8(priv, &priv->map->SLOT, 0x9); | 989 | rtl818x_iowrite8(priv, &priv->map->SLOT, 0x9); |
964 | rtl818x_iowrite8(priv, &priv->map->DIFS, 0x14); | 990 | rtl818x_iowrite8(priv, &priv->map->DIFS, 0x14); |
965 | rtl818x_iowrite8(priv, &priv->map->EIFS, 91 - 0x14); | 991 | rtl818x_iowrite8(priv, &priv->map->EIFS, 91 - 0x14); |
966 | rtl818x_iowrite8(priv, &priv->map->CW_VAL, 0x73); | ||
967 | } else { | 992 | } else { |
968 | rtl818x_iowrite8(priv, &priv->map->SLOT, 0x14); | 993 | rtl818x_iowrite8(priv, &priv->map->SLOT, 0x14); |
969 | rtl818x_iowrite8(priv, &priv->map->DIFS, 0x24); | 994 | rtl818x_iowrite8(priv, &priv->map->DIFS, 0x24); |
970 | rtl818x_iowrite8(priv, &priv->map->EIFS, 91 - 0x24); | 995 | rtl818x_iowrite8(priv, &priv->map->EIFS, 91 - 0x24); |
971 | rtl818x_iowrite8(priv, &priv->map->CW_VAL, 0xa5); | ||
972 | } | 996 | } |
973 | } | 997 | } |
974 | } | 998 | } |
@@ -1017,6 +1041,42 @@ static void rtl8187_configure_filter(struct ieee80211_hw *dev, | |||
1017 | rtl818x_iowrite32_async(priv, &priv->map->RX_CONF, priv->rx_conf); | 1041 | rtl818x_iowrite32_async(priv, &priv->map->RX_CONF, priv->rx_conf); |
1018 | } | 1042 | } |
1019 | 1043 | ||
1044 | static int rtl8187_conf_tx(struct ieee80211_hw *dev, u16 queue, | ||
1045 | const struct ieee80211_tx_queue_params *params) | ||
1046 | { | ||
1047 | struct rtl8187_priv *priv = dev->priv; | ||
1048 | u8 cw_min, cw_max; | ||
1049 | |||
1050 | if (queue > 3) | ||
1051 | return -EINVAL; | ||
1052 | |||
1053 | cw_min = fls(params->cw_min); | ||
1054 | cw_max = fls(params->cw_max); | ||
1055 | |||
1056 | if (priv->is_rtl8187b) { | ||
1057 | priv->aifsn[queue] = params->aifs; | ||
1058 | |||
1059 | /* | ||
1060 | * This is the structure of AC_*_PARAM registers in 8187B: | ||
1061 | * - TXOP limit field, bit offset = 16 | ||
1062 | * - ECWmax, bit offset = 12 | ||
1063 | * - ECWmin, bit offset = 8 | ||
1064 | * - AIFS, bit offset = 0 | ||
1065 | */ | ||
1066 | rtl818x_iowrite32(priv, rtl8187b_ac_addr[queue], | ||
1067 | (params->txop << 16) | (cw_max << 12) | | ||
1068 | (cw_min << 8) | (params->aifs * | ||
1069 | priv->slot_time + SIFS_TIME)); | ||
1070 | } else { | ||
1071 | if (queue != 0) | ||
1072 | return -EINVAL; | ||
1073 | |||
1074 | rtl818x_iowrite8(priv, &priv->map->CW_VAL, | ||
1075 | cw_min | (cw_max << 4)); | ||
1076 | } | ||
1077 | return 0; | ||
1078 | } | ||
1079 | |||
1020 | static const struct ieee80211_ops rtl8187_ops = { | 1080 | static const struct ieee80211_ops rtl8187_ops = { |
1021 | .tx = rtl8187_tx, | 1081 | .tx = rtl8187_tx, |
1022 | .start = rtl8187_start, | 1082 | .start = rtl8187_start, |
@@ -1027,6 +1087,7 @@ static const struct ieee80211_ops rtl8187_ops = { | |||
1027 | .config_interface = rtl8187_config_interface, | 1087 | .config_interface = rtl8187_config_interface, |
1028 | .bss_info_changed = rtl8187_bss_info_changed, | 1088 | .bss_info_changed = rtl8187_bss_info_changed, |
1029 | .configure_filter = rtl8187_configure_filter, | 1089 | .configure_filter = rtl8187_configure_filter, |
1090 | .conf_tx = rtl8187_conf_tx | ||
1030 | }; | 1091 | }; |
1031 | 1092 | ||
1032 | static void rtl8187_eeprom_register_read(struct eeprom_93cx6 *eeprom) | 1093 | static void rtl8187_eeprom_register_read(struct eeprom_93cx6 *eeprom) |