diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/wireless/rtl8187.h | 4 | ||||
-rw-r--r-- | drivers/net/wireless/rtl8187_dev.c | 15 |
2 files changed, 18 insertions, 1 deletions
diff --git a/drivers/net/wireless/rtl8187.h b/drivers/net/wireless/rtl8187.h index 1b0d750f6623..5a9515c99960 100644 --- a/drivers/net/wireless/rtl8187.h +++ b/drivers/net/wireless/rtl8187.h | |||
@@ -94,6 +94,10 @@ struct rtl8187_priv { | |||
94 | const struct rtl818x_rf_ops *rf; | 94 | const struct rtl818x_rf_ops *rf; |
95 | struct ieee80211_vif *vif; | 95 | struct ieee80211_vif *vif; |
96 | int mode; | 96 | int mode; |
97 | /* The mutex protects the TX loopback state. | ||
98 | * Any attempt to set channels concurrently locks the device. | ||
99 | */ | ||
100 | struct mutex conf_mutex; | ||
97 | 101 | ||
98 | /* rtl8187 specific */ | 102 | /* rtl8187 specific */ |
99 | struct ieee80211_channel channels[14]; | 103 | struct ieee80211_channel channels[14]; |
diff --git a/drivers/net/wireless/rtl8187_dev.c b/drivers/net/wireless/rtl8187_dev.c index 461aa26164c2..57376fb993ed 100644 --- a/drivers/net/wireless/rtl8187_dev.c +++ b/drivers/net/wireless/rtl8187_dev.c | |||
@@ -728,6 +728,7 @@ static int rtl8187_start(struct ieee80211_hw *dev) | |||
728 | if (ret) | 728 | if (ret) |
729 | return ret; | 729 | return ret; |
730 | 730 | ||
731 | mutex_lock(&priv->conf_mutex); | ||
731 | if (priv->is_rtl8187b) { | 732 | if (priv->is_rtl8187b) { |
732 | reg = RTL818X_RX_CONF_MGMT | | 733 | reg = RTL818X_RX_CONF_MGMT | |
733 | RTL818X_RX_CONF_DATA | | 734 | RTL818X_RX_CONF_DATA | |
@@ -749,6 +750,7 @@ static int rtl8187_start(struct ieee80211_hw *dev) | |||
749 | (7 << 0 /* long retry limit */) | | 750 | (7 << 0 /* long retry limit */) | |
750 | (7 << 21 /* MAX TX DMA */)); | 751 | (7 << 21 /* MAX TX DMA */)); |
751 | rtl8187_init_urbs(dev); | 752 | rtl8187_init_urbs(dev); |
753 | mutex_unlock(&priv->conf_mutex); | ||
752 | return 0; | 754 | return 0; |
753 | } | 755 | } |
754 | 756 | ||
@@ -792,6 +794,7 @@ static int rtl8187_start(struct ieee80211_hw *dev) | |||
792 | reg |= RTL818X_CMD_TX_ENABLE; | 794 | reg |= RTL818X_CMD_TX_ENABLE; |
793 | reg |= RTL818X_CMD_RX_ENABLE; | 795 | reg |= RTL818X_CMD_RX_ENABLE; |
794 | rtl818x_iowrite8(priv, &priv->map->CMD, reg); | 796 | rtl818x_iowrite8(priv, &priv->map->CMD, reg); |
797 | mutex_unlock(&priv->conf_mutex); | ||
795 | 798 | ||
796 | return 0; | 799 | return 0; |
797 | } | 800 | } |
@@ -803,6 +806,7 @@ static void rtl8187_stop(struct ieee80211_hw *dev) | |||
803 | struct sk_buff *skb; | 806 | struct sk_buff *skb; |
804 | u32 reg; | 807 | u32 reg; |
805 | 808 | ||
809 | mutex_lock(&priv->conf_mutex); | ||
806 | rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0); | 810 | rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0); |
807 | 811 | ||
808 | reg = rtl818x_ioread8(priv, &priv->map->CMD); | 812 | reg = rtl818x_ioread8(priv, &priv->map->CMD); |
@@ -822,7 +826,7 @@ static void rtl8187_stop(struct ieee80211_hw *dev) | |||
822 | usb_kill_urb(info->urb); | 826 | usb_kill_urb(info->urb); |
823 | kfree_skb(skb); | 827 | kfree_skb(skb); |
824 | } | 828 | } |
825 | return; | 829 | mutex_unlock(&priv->conf_mutex); |
826 | } | 830 | } |
827 | 831 | ||
828 | static int rtl8187_add_interface(struct ieee80211_hw *dev, | 832 | static int rtl8187_add_interface(struct ieee80211_hw *dev, |
@@ -842,6 +846,7 @@ static int rtl8187_add_interface(struct ieee80211_hw *dev, | |||
842 | return -EOPNOTSUPP; | 846 | return -EOPNOTSUPP; |
843 | } | 847 | } |
844 | 848 | ||
849 | mutex_lock(&priv->conf_mutex); | ||
845 | priv->vif = conf->vif; | 850 | priv->vif = conf->vif; |
846 | 851 | ||
847 | rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); | 852 | rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); |
@@ -850,6 +855,7 @@ static int rtl8187_add_interface(struct ieee80211_hw *dev, | |||
850 | ((u8 *)conf->mac_addr)[i]); | 855 | ((u8 *)conf->mac_addr)[i]); |
851 | rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); | 856 | rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); |
852 | 857 | ||
858 | mutex_unlock(&priv->conf_mutex); | ||
853 | return 0; | 859 | return 0; |
854 | } | 860 | } |
855 | 861 | ||
@@ -857,8 +863,10 @@ static void rtl8187_remove_interface(struct ieee80211_hw *dev, | |||
857 | struct ieee80211_if_init_conf *conf) | 863 | struct ieee80211_if_init_conf *conf) |
858 | { | 864 | { |
859 | struct rtl8187_priv *priv = dev->priv; | 865 | struct rtl8187_priv *priv = dev->priv; |
866 | mutex_lock(&priv->conf_mutex); | ||
860 | priv->mode = IEEE80211_IF_TYPE_MNTR; | 867 | priv->mode = IEEE80211_IF_TYPE_MNTR; |
861 | priv->vif = NULL; | 868 | priv->vif = NULL; |
869 | mutex_unlock(&priv->conf_mutex); | ||
862 | } | 870 | } |
863 | 871 | ||
864 | static int rtl8187_config(struct ieee80211_hw *dev, struct ieee80211_conf *conf) | 872 | static int rtl8187_config(struct ieee80211_hw *dev, struct ieee80211_conf *conf) |
@@ -866,6 +874,7 @@ static int rtl8187_config(struct ieee80211_hw *dev, struct ieee80211_conf *conf) | |||
866 | struct rtl8187_priv *priv = dev->priv; | 874 | struct rtl8187_priv *priv = dev->priv; |
867 | u32 reg; | 875 | u32 reg; |
868 | 876 | ||
877 | mutex_lock(&priv->conf_mutex); | ||
869 | reg = rtl818x_ioread32(priv, &priv->map->TX_CONF); | 878 | reg = rtl818x_ioread32(priv, &priv->map->TX_CONF); |
870 | /* Enable TX loopback on MAC level to avoid TX during channel | 879 | /* Enable TX loopback on MAC level to avoid TX during channel |
871 | * changes, as this has be seen to causes problems and the | 880 | * changes, as this has be seen to causes problems and the |
@@ -898,6 +907,7 @@ static int rtl8187_config(struct ieee80211_hw *dev, struct ieee80211_conf *conf) | |||
898 | rtl818x_iowrite16(priv, &priv->map->ATIMTR_INTERVAL, 100); | 907 | rtl818x_iowrite16(priv, &priv->map->ATIMTR_INTERVAL, 100); |
899 | rtl818x_iowrite16(priv, &priv->map->BEACON_INTERVAL, 100); | 908 | rtl818x_iowrite16(priv, &priv->map->BEACON_INTERVAL, 100); |
900 | rtl818x_iowrite16(priv, &priv->map->BEACON_INTERVAL_TIME, 100); | 909 | rtl818x_iowrite16(priv, &priv->map->BEACON_INTERVAL_TIME, 100); |
910 | mutex_unlock(&priv->conf_mutex); | ||
901 | return 0; | 911 | return 0; |
902 | } | 912 | } |
903 | 913 | ||
@@ -909,6 +919,7 @@ static int rtl8187_config_interface(struct ieee80211_hw *dev, | |||
909 | int i; | 919 | int i; |
910 | u8 reg; | 920 | u8 reg; |
911 | 921 | ||
922 | mutex_lock(&priv->conf_mutex); | ||
912 | for (i = 0; i < ETH_ALEN; i++) | 923 | for (i = 0; i < ETH_ALEN; i++) |
913 | rtl818x_iowrite8(priv, &priv->map->BSSID[i], conf->bssid[i]); | 924 | rtl818x_iowrite8(priv, &priv->map->BSSID[i], conf->bssid[i]); |
914 | 925 | ||
@@ -922,6 +933,7 @@ static int rtl8187_config_interface(struct ieee80211_hw *dev, | |||
922 | rtl818x_iowrite8(priv, &priv->map->MSR, reg); | 933 | rtl818x_iowrite8(priv, &priv->map->MSR, reg); |
923 | } | 934 | } |
924 | 935 | ||
936 | mutex_unlock(&priv->conf_mutex); | ||
925 | return 0; | 937 | return 0; |
926 | } | 938 | } |
927 | 939 | ||
@@ -1189,6 +1201,7 @@ static int __devinit rtl8187_probe(struct usb_interface *intf, | |||
1189 | printk(KERN_ERR "rtl8187: Cannot register device\n"); | 1201 | printk(KERN_ERR "rtl8187: Cannot register device\n"); |
1190 | goto err_free_dev; | 1202 | goto err_free_dev; |
1191 | } | 1203 | } |
1204 | mutex_init(&priv->conf_mutex); | ||
1192 | 1205 | ||
1193 | printk(KERN_INFO "%s: hwaddr %s, %s V%d + %s\n", | 1206 | printk(KERN_INFO "%s: hwaddr %s, %s V%d + %s\n", |
1194 | wiphy_name(dev->wiphy), print_mac(mac, dev->wiphy->perm_addr), | 1207 | wiphy_name(dev->wiphy), print_mac(mac, dev->wiphy->perm_addr), |