aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/wl12xx
diff options
context:
space:
mode:
authorJuuso Oikarinen <juuso.oikarinen@nokia.com>2010-07-08 10:49:58 -0400
committerJohn W. Linville <linville@tuxdriver.com>2010-07-08 16:35:50 -0400
commiteb887dfd8837bf0a2538418c02b3992fb9ff1f28 (patch)
treee683ec601f59e6c739c04fe447bd59e3c9444176 /drivers/net/wireless/wl12xx
parentbbbb538e337a3eb2166d5a20307b93822bdacc4f (diff)
wl1271: Use the ARP configuration function from mac80211
This patch updates the driver to use the ARP configuration function from the mac80211. Also, clean up IPv6 support from the ACX function as ARP is not used with that protocol version. Signed-off-by: Juuso Oikarinen <juuso.oikarinen@nokia.com> Reviewed-by: Luciano Coelho <luciano.coelho@nokia.com> Signed-off-by: Luciano Coelho <luciano.coelho@nokia.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/wl12xx')
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_acx.c19
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_acx.h3
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_main.c142
3 files changed, 56 insertions, 108 deletions
diff --git a/drivers/net/wireless/wl12xx/wl1271_acx.c b/drivers/net/wireless/wl12xx/wl1271_acx.c
index 5cadb9d06c76..b45ebbcf6c4a 100644
--- a/drivers/net/wireless/wl12xx/wl1271_acx.c
+++ b/drivers/net/wireless/wl12xx/wl1271_acx.c
@@ -1075,13 +1075,12 @@ out:
1075 return ret; 1075 return ret;
1076} 1076}
1077 1077
1078int wl1271_acx_arp_ip_filter(struct wl1271 *wl, bool enable, u8 *address, 1078int wl1271_acx_arp_ip_filter(struct wl1271 *wl, u8 mode, u8 *address)
1079 u8 version)
1080{ 1079{
1081 struct wl1271_acx_arp_filter *acx; 1080 struct wl1271_acx_arp_filter *acx;
1082 int ret; 1081 int ret;
1083 1082
1084 wl1271_debug(DEBUG_ACX, "acx arp ip filter, enable: %d", enable); 1083 wl1271_debug(DEBUG_ACX, "acx arp ip filter, mode: %d", mode);
1085 1084
1086 acx = kzalloc(sizeof(*acx), GFP_KERNEL); 1085 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
1087 if (!acx) { 1086 if (!acx) {
@@ -1089,17 +1088,11 @@ int wl1271_acx_arp_ip_filter(struct wl1271 *wl, bool enable, u8 *address,
1089 goto out; 1088 goto out;
1090 } 1089 }
1091 1090
1092 acx->version = version; 1091 acx->version = ACX_IPV4_VERSION;
1093 acx->enable = enable; 1092 acx->enable = mode;
1094 1093
1095 if (enable == true) { 1094 if (mode != ACX_ARP_DISABLE)
1096 if (version == ACX_IPV4_VERSION) 1095 memcpy(acx->address, address, ACX_IPV4_ADDR_SIZE);
1097 memcpy(acx->address, address, ACX_IPV4_ADDR_SIZE);
1098 else if (version == ACX_IPV6_VERSION)
1099 memcpy(acx->address, address, sizeof(acx->address));
1100 else
1101 wl1271_error("Invalid IP version");
1102 }
1103 1096
1104 ret = wl1271_cmd_configure(wl, ACX_ARP_IP_FILTER, 1097 ret = wl1271_cmd_configure(wl, ACX_ARP_IP_FILTER,
1105 acx, sizeof(*acx)); 1098 acx, sizeof(*acx));
diff --git a/drivers/net/wireless/wl12xx/wl1271_acx.h b/drivers/net/wireless/wl12xx/wl1271_acx.h
index 914b29b92999..6a6f3e3ebf34 100644
--- a/drivers/net/wireless/wl12xx/wl1271_acx.h
+++ b/drivers/net/wireless/wl12xx/wl1271_acx.h
@@ -1117,8 +1117,7 @@ int wl1271_acx_init_mem_config(struct wl1271 *wl);
1117int wl1271_acx_init_rx_interrupt(struct wl1271 *wl); 1117int wl1271_acx_init_rx_interrupt(struct wl1271 *wl);
1118int wl1271_acx_smart_reflex(struct wl1271 *wl); 1118int wl1271_acx_smart_reflex(struct wl1271 *wl);
1119int wl1271_acx_bet_enable(struct wl1271 *wl, bool enable); 1119int wl1271_acx_bet_enable(struct wl1271 *wl, bool enable);
1120int wl1271_acx_arp_ip_filter(struct wl1271 *wl, bool enable, u8 *address, 1120int wl1271_acx_arp_ip_filter(struct wl1271 *wl, u8 mode, u8 *address);
1121 u8 version);
1122int wl1271_acx_pm_config(struct wl1271 *wl); 1121int wl1271_acx_pm_config(struct wl1271 *wl);
1123int wl1271_acx_keep_alive_mode(struct wl1271 *wl, bool enable); 1122int wl1271_acx_keep_alive_mode(struct wl1271 *wl, bool enable);
1124int wl1271_acx_keep_alive_config(struct wl1271 *wl, u8 index, u8 tpl_valid); 1123int wl1271_acx_keep_alive_config(struct wl1271 *wl, u8 index, u8 tpl_valid);
diff --git a/drivers/net/wireless/wl12xx/wl1271_main.c b/drivers/net/wireless/wl12xx/wl1271_main.c
index 5970fde49d40..a37244c88fee 100644
--- a/drivers/net/wireless/wl12xx/wl1271_main.c
+++ b/drivers/net/wireless/wl12xx/wl1271_main.c
@@ -28,7 +28,6 @@
28#include <linux/crc32.h> 28#include <linux/crc32.h>
29#include <linux/etherdevice.h> 29#include <linux/etherdevice.h>
30#include <linux/vmalloc.h> 30#include <linux/vmalloc.h>
31#include <linux/inetdevice.h>
32#include <linux/platform_device.h> 31#include <linux/platform_device.h>
33#include <linux/slab.h> 32#include <linux/slab.h>
34 33
@@ -818,93 +817,6 @@ static int wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
818 return NETDEV_TX_OK; 817 return NETDEV_TX_OK;
819} 818}
820 819
821static int wl1271_dev_notify(struct notifier_block *me, unsigned long what,
822 void *arg)
823{
824 struct net_device *dev;
825 struct wireless_dev *wdev;
826 struct wiphy *wiphy;
827 struct ieee80211_hw *hw;
828 struct wl1271 *wl;
829 struct wl1271 *wl_temp;
830 struct in_device *idev;
831 struct in_ifaddr *ifa = arg;
832 int ret = 0;
833
834 /* FIXME: this ugly function should probably be implemented in the
835 * mac80211, and here should only be a simple callback handling actual
836 * setting of the filters. Now we need to dig up references to
837 * various structures to gain access to what we need.
838 * Also, because of this, there is no "initial" setting of the filter
839 * in "op_start", because we don't want to dig up struct net_device
840 * there - the filter will be set upon first change of the interface
841 * IP address. */
842
843 dev = ifa->ifa_dev->dev;
844
845 wdev = dev->ieee80211_ptr;
846 if (wdev == NULL)
847 return NOTIFY_DONE;
848
849 wiphy = wdev->wiphy;
850 if (wiphy == NULL)
851 return NOTIFY_DONE;
852
853 hw = wiphy_priv(wiphy);
854 if (hw == NULL)
855 return NOTIFY_DONE;
856
857 /* Check that the interface is one supported by this driver. */
858 wl_temp = hw->priv;
859 list_for_each_entry(wl, &wl_list, list) {
860 if (wl == wl_temp)
861 break;
862 }
863 if (wl != wl_temp)
864 return NOTIFY_DONE;
865
866 /* Get the interface IP address for the device. "ifa" will become
867 NULL if:
868 - there is no IPV4 protocol address configured
869 - there are multiple (virtual) IPV4 addresses configured
870 When "ifa" is NULL, filtering will be disabled.
871 */
872 ifa = NULL;
873 idev = dev->ip_ptr;
874 if (idev)
875 ifa = idev->ifa_list;
876
877 if (ifa && ifa->ifa_next)
878 ifa = NULL;
879
880 mutex_lock(&wl->mutex);
881
882 if (wl->state == WL1271_STATE_OFF)
883 goto out;
884
885 ret = wl1271_ps_elp_wakeup(wl, false);
886 if (ret < 0)
887 goto out;
888 if (ifa)
889 ret = wl1271_acx_arp_ip_filter(wl, true,
890 (u8 *)&ifa->ifa_address,
891 ACX_IPV4_VERSION);
892 else
893 ret = wl1271_acx_arp_ip_filter(wl, false, NULL,
894 ACX_IPV4_VERSION);
895 wl1271_ps_elp_sleep(wl);
896
897out:
898 mutex_unlock(&wl->mutex);
899
900 return NOTIFY_OK;
901}
902
903static struct notifier_block wl1271_dev_notifier = {
904 .notifier_call = wl1271_dev_notify,
905};
906
907
908static int wl1271_op_start(struct ieee80211_hw *hw) 820static int wl1271_op_start(struct ieee80211_hw *hw)
909{ 821{
910 wl1271_debug(DEBUG_MAC80211, "mac80211 start"); 822 wl1271_debug(DEBUG_MAC80211, "mac80211 start");
@@ -1008,10 +920,8 @@ power_off:
1008out: 920out:
1009 mutex_unlock(&wl->mutex); 921 mutex_unlock(&wl->mutex);
1010 922
1011 if (!ret) { 923 if (!ret)
1012 list_add(&wl->list, &wl_list); 924 list_add(&wl->list, &wl_list);
1013 register_inetaddr_notifier(&wl1271_dev_notifier);
1014 }
1015 925
1016 return ret; 926 return ret;
1017} 927}
@@ -1022,8 +932,6 @@ static void wl1271_op_remove_interface(struct ieee80211_hw *hw,
1022 struct wl1271 *wl = hw->priv; 932 struct wl1271 *wl = hw->priv;
1023 int i; 933 int i;
1024 934
1025 unregister_inetaddr_notifier(&wl1271_dev_notifier);
1026
1027 mutex_lock(&wl->mutex); 935 mutex_lock(&wl->mutex);
1028 wl1271_debug(DEBUG_MAC80211, "mac80211 remove interface"); 936 wl1271_debug(DEBUG_MAC80211, "mac80211 remove interface");
1029 937
@@ -1400,6 +1308,53 @@ struct wl1271_filter_params {
1400 u8 mc_list[ACX_MC_ADDRESS_GROUP_MAX][ETH_ALEN]; 1308 u8 mc_list[ACX_MC_ADDRESS_GROUP_MAX][ETH_ALEN];
1401}; 1309};
1402 1310
1311static int wl1271_op_configure_arp_filter(struct ieee80211_hw *hw,
1312 struct ieee80211_vif *vif,
1313 struct in_ifaddr *ifa_list)
1314{
1315 struct wl1271 *wl = hw->priv;
1316 int ret = 0;
1317
1318 WARN_ON(vif != wl->vif);
1319
1320 /* disable filtering if there are multiple addresses */
1321 if (ifa_list && ifa_list->ifa_next)
1322 ifa_list = NULL;
1323
1324 mutex_lock(&wl->mutex);
1325
1326 if (wl->state == WL1271_STATE_OFF)
1327 goto out;
1328
1329 WARN_ON(wl->bss_type != BSS_TYPE_STA_BSS);
1330
1331 ret = wl1271_ps_elp_wakeup(wl, false);
1332 if (ret < 0)
1333 goto out;
1334
1335 if (ifa_list) {
1336 ret = wl1271_cmd_build_arp_reply(wl, &ifa_list->ifa_address);
1337 if (ret < 0)
1338 goto out_sleep;
1339 ret = wl1271_acx_arp_ip_filter(wl, ACX_ARP_FILTER_AND_REPLY,
1340 (u8 *)&ifa_list->ifa_address);
1341 if (ret < 0)
1342 goto out_sleep;
1343 } else {
1344 ret = wl1271_acx_arp_ip_filter(wl, ACX_ARP_DISABLE, NULL);
1345 if (ret < 0)
1346 goto out_sleep;
1347 }
1348
1349out_sleep:
1350 wl1271_ps_elp_sleep(wl);
1351
1352out:
1353 mutex_unlock(&wl->mutex);
1354
1355 return ret;
1356}
1357
1403static u64 wl1271_op_prepare_multicast(struct ieee80211_hw *hw, 1358static u64 wl1271_op_prepare_multicast(struct ieee80211_hw *hw,
1404 struct netdev_hw_addr_list *mc_list) 1359 struct netdev_hw_addr_list *mc_list)
1405{ 1360{
@@ -2213,6 +2168,7 @@ static const struct ieee80211_ops wl1271_ops = {
2213 .add_interface = wl1271_op_add_interface, 2168 .add_interface = wl1271_op_add_interface,
2214 .remove_interface = wl1271_op_remove_interface, 2169 .remove_interface = wl1271_op_remove_interface,
2215 .config = wl1271_op_config, 2170 .config = wl1271_op_config,
2171 .configure_arp_filter = wl1271_op_configure_arp_filter,
2216 .prepare_multicast = wl1271_op_prepare_multicast, 2172 .prepare_multicast = wl1271_op_prepare_multicast,
2217 .configure_filter = wl1271_op_configure_filter, 2173 .configure_filter = wl1271_op_configure_filter,
2218 .tx = wl1271_op_tx, 2174 .tx = wl1271_op_tx,