aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/ieee80211_sta.c
diff options
context:
space:
mode:
authorBruno Randolf <bruno@thinktube.com>2008-02-17 21:21:15 -0500
committerJohn W. Linville <linville@tuxdriver.com>2008-02-29 15:37:12 -0500
commita607268a0d5532d6ae3777ddd0339ff7d8b037a0 (patch)
tree1645aae649f2bf4736f5cbfde185cd1b60eb3f09 /net/mac80211/ieee80211_sta.c
parentc132bec33c2eb5e46d8e4b80cfa5a9656d8e57e7 (diff)
mac80211: move function ieee80211_sta_join_ibss()
this moves ieee80211_sta_join_ibss() up for the next patch (ibss merge). Signed-off-by: Bruno Randolf <bruno@thinktube.com> Acked-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/ieee80211_sta.c')
-rw-r--r--net/mac80211/ieee80211_sta.c317
1 files changed, 159 insertions, 158 deletions
diff --git a/net/mac80211/ieee80211_sta.c b/net/mac80211/ieee80211_sta.c
index a465e38c7252..a84ead49b1e6 100644
--- a/net/mac80211/ieee80211_sta.c
+++ b/net/mac80211/ieee80211_sta.c
@@ -2027,6 +2027,165 @@ void ieee80211_rx_bss_list_deinit(struct net_device *dev)
2027} 2027}
2028 2028
2029 2029
2030static int ieee80211_sta_join_ibss(struct net_device *dev,
2031 struct ieee80211_if_sta *ifsta,
2032 struct ieee80211_sta_bss *bss)
2033{
2034 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
2035 int res, rates, i, j;
2036 struct sk_buff *skb;
2037 struct ieee80211_mgmt *mgmt;
2038 struct ieee80211_tx_control control;
2039 struct rate_selection ratesel;
2040 u8 *pos;
2041 struct ieee80211_sub_if_data *sdata;
2042 struct ieee80211_supported_band *sband;
2043
2044 sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
2045
2046 /* Remove possible STA entries from other IBSS networks. */
2047 sta_info_flush(local, NULL);
2048
2049 if (local->ops->reset_tsf) {
2050 /* Reset own TSF to allow time synchronization work. */
2051 local->ops->reset_tsf(local_to_hw(local));
2052 }
2053 memcpy(ifsta->bssid, bss->bssid, ETH_ALEN);
2054 res = ieee80211_if_config(dev);
2055 if (res)
2056 return res;
2057
2058 local->hw.conf.beacon_int = bss->beacon_int >= 10 ? bss->beacon_int : 10;
2059
2060 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
2061 sdata->drop_unencrypted = bss->capability &
2062 WLAN_CAPABILITY_PRIVACY ? 1 : 0;
2063
2064 res = ieee80211_set_freq(local, bss->freq);
2065
2066 if (local->oper_channel->flags & IEEE80211_CHAN_NO_IBSS) {
2067 printk(KERN_DEBUG "%s: IBSS not allowed on frequency "
2068 "%d MHz\n", dev->name, local->oper_channel->center_freq);
2069 return -1;
2070 }
2071
2072 /* Set beacon template */
2073 skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400);
2074 do {
2075 if (!skb)
2076 break;
2077
2078 skb_reserve(skb, local->hw.extra_tx_headroom);
2079
2080 mgmt = (struct ieee80211_mgmt *)
2081 skb_put(skb, 24 + sizeof(mgmt->u.beacon));
2082 memset(mgmt, 0, 24 + sizeof(mgmt->u.beacon));
2083 mgmt->frame_control = IEEE80211_FC(IEEE80211_FTYPE_MGMT,
2084 IEEE80211_STYPE_BEACON);
2085 memset(mgmt->da, 0xff, ETH_ALEN);
2086 memcpy(mgmt->sa, dev->dev_addr, ETH_ALEN);
2087 memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN);
2088 mgmt->u.beacon.beacon_int =
2089 cpu_to_le16(local->hw.conf.beacon_int);
2090 mgmt->u.beacon.capab_info = cpu_to_le16(bss->capability);
2091
2092 pos = skb_put(skb, 2 + ifsta->ssid_len);
2093 *pos++ = WLAN_EID_SSID;
2094 *pos++ = ifsta->ssid_len;
2095 memcpy(pos, ifsta->ssid, ifsta->ssid_len);
2096
2097 rates = bss->supp_rates_len;
2098 if (rates > 8)
2099 rates = 8;
2100 pos = skb_put(skb, 2 + rates);
2101 *pos++ = WLAN_EID_SUPP_RATES;
2102 *pos++ = rates;
2103 memcpy(pos, bss->supp_rates, rates);
2104
2105 if (bss->band == IEEE80211_BAND_2GHZ) {
2106 pos = skb_put(skb, 2 + 1);
2107 *pos++ = WLAN_EID_DS_PARAMS;
2108 *pos++ = 1;
2109 *pos++ = ieee80211_frequency_to_channel(bss->freq);
2110 }
2111
2112 pos = skb_put(skb, 2 + 2);
2113 *pos++ = WLAN_EID_IBSS_PARAMS;
2114 *pos++ = 2;
2115 /* FIX: set ATIM window based on scan results */
2116 *pos++ = 0;
2117 *pos++ = 0;
2118
2119 if (bss->supp_rates_len > 8) {
2120 rates = bss->supp_rates_len - 8;
2121 pos = skb_put(skb, 2 + rates);
2122 *pos++ = WLAN_EID_EXT_SUPP_RATES;
2123 *pos++ = rates;
2124 memcpy(pos, &bss->supp_rates[8], rates);
2125 }
2126
2127 memset(&control, 0, sizeof(control));
2128 rate_control_get_rate(dev, sband, skb, &ratesel);
2129 if (!ratesel.rate) {
2130 printk(KERN_DEBUG "%s: Failed to determine TX rate "
2131 "for IBSS beacon\n", dev->name);
2132 break;
2133 }
2134 control.vif = &sdata->vif;
2135 control.tx_rate = ratesel.rate;
2136 if (sdata->bss_conf.use_short_preamble &&
2137 ratesel.rate->flags & IEEE80211_RATE_SHORT_PREAMBLE)
2138 control.flags |= IEEE80211_TXCTL_SHORT_PREAMBLE;
2139 control.antenna_sel_tx = local->hw.conf.antenna_sel_tx;
2140 control.flags |= IEEE80211_TXCTL_NO_ACK;
2141 control.retry_limit = 1;
2142
2143 ifsta->probe_resp = skb_copy(skb, GFP_ATOMIC);
2144 if (ifsta->probe_resp) {
2145 mgmt = (struct ieee80211_mgmt *)
2146 ifsta->probe_resp->data;
2147 mgmt->frame_control =
2148 IEEE80211_FC(IEEE80211_FTYPE_MGMT,
2149 IEEE80211_STYPE_PROBE_RESP);
2150 } else {
2151 printk(KERN_DEBUG "%s: Could not allocate ProbeResp "
2152 "template for IBSS\n", dev->name);
2153 }
2154
2155 if (local->ops->beacon_update &&
2156 local->ops->beacon_update(local_to_hw(local),
2157 skb, &control) == 0) {
2158 printk(KERN_DEBUG "%s: Configured IBSS beacon "
2159 "template\n", dev->name);
2160 skb = NULL;
2161 }
2162
2163 rates = 0;
2164 sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
2165 for (i = 0; i < bss->supp_rates_len; i++) {
2166 int bitrate = (bss->supp_rates[i] & 0x7f) * 5;
2167 for (j = 0; j < sband->n_bitrates; j++)
2168 if (sband->bitrates[j].bitrate == bitrate)
2169 rates |= BIT(j);
2170 }
2171 ifsta->supp_rates_bits[local->hw.conf.channel->band] = rates;
2172 } while (0);
2173
2174 if (skb) {
2175 printk(KERN_DEBUG "%s: Failed to configure IBSS beacon "
2176 "template\n", dev->name);
2177 dev_kfree_skb(skb);
2178 }
2179
2180 ifsta->state = IEEE80211_IBSS_JOINED;
2181 mod_timer(&ifsta->timer, jiffies + IEEE80211_IBSS_MERGE_INTERVAL);
2182
2183 ieee80211_rx_bss_put(dev, bss);
2184
2185 return res;
2186}
2187
2188
2030static void ieee80211_rx_bss_info(struct net_device *dev, 2189static void ieee80211_rx_bss_info(struct net_device *dev,
2031 struct ieee80211_mgmt *mgmt, 2190 struct ieee80211_mgmt *mgmt,
2032 size_t len, 2191 size_t len,
@@ -2891,164 +3050,6 @@ static int ieee80211_sta_config_auth(struct net_device *dev,
2891 return -1; 3050 return -1;
2892} 3051}
2893 3052
2894static int ieee80211_sta_join_ibss(struct net_device *dev,
2895 struct ieee80211_if_sta *ifsta,
2896 struct ieee80211_sta_bss *bss)
2897{
2898 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
2899 int res, rates, i, j;
2900 struct sk_buff *skb;
2901 struct ieee80211_mgmt *mgmt;
2902 struct ieee80211_tx_control control;
2903 struct rate_selection ratesel;
2904 u8 *pos;
2905 struct ieee80211_sub_if_data *sdata;
2906 struct ieee80211_supported_band *sband;
2907
2908 sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
2909
2910 /* Remove possible STA entries from other IBSS networks. */
2911 sta_info_flush(local, NULL);
2912
2913 if (local->ops->reset_tsf) {
2914 /* Reset own TSF to allow time synchronization work. */
2915 local->ops->reset_tsf(local_to_hw(local));
2916 }
2917 memcpy(ifsta->bssid, bss->bssid, ETH_ALEN);
2918 res = ieee80211_if_config(dev);
2919 if (res)
2920 return res;
2921
2922 local->hw.conf.beacon_int = bss->beacon_int >= 10 ? bss->beacon_int : 10;
2923
2924 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
2925 sdata->drop_unencrypted = bss->capability &
2926 WLAN_CAPABILITY_PRIVACY ? 1 : 0;
2927
2928 res = ieee80211_set_freq(local, bss->freq);
2929
2930 if (local->oper_channel->flags & IEEE80211_CHAN_NO_IBSS) {
2931 printk(KERN_DEBUG "%s: IBSS not allowed on frequency "
2932 "%d MHz\n", dev->name, local->oper_channel->center_freq);
2933 return -1;
2934 }
2935
2936 /* Set beacon template based on scan results */
2937 skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400);
2938 do {
2939 if (!skb)
2940 break;
2941
2942 skb_reserve(skb, local->hw.extra_tx_headroom);
2943
2944 mgmt = (struct ieee80211_mgmt *)
2945 skb_put(skb, 24 + sizeof(mgmt->u.beacon));
2946 memset(mgmt, 0, 24 + sizeof(mgmt->u.beacon));
2947 mgmt->frame_control = IEEE80211_FC(IEEE80211_FTYPE_MGMT,
2948 IEEE80211_STYPE_BEACON);
2949 memset(mgmt->da, 0xff, ETH_ALEN);
2950 memcpy(mgmt->sa, dev->dev_addr, ETH_ALEN);
2951 memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN);
2952 mgmt->u.beacon.beacon_int =
2953 cpu_to_le16(local->hw.conf.beacon_int);
2954 mgmt->u.beacon.capab_info = cpu_to_le16(bss->capability);
2955
2956 pos = skb_put(skb, 2 + ifsta->ssid_len);
2957 *pos++ = WLAN_EID_SSID;
2958 *pos++ = ifsta->ssid_len;
2959 memcpy(pos, ifsta->ssid, ifsta->ssid_len);
2960
2961 rates = bss->supp_rates_len;
2962 if (rates > 8)
2963 rates = 8;
2964 pos = skb_put(skb, 2 + rates);
2965 *pos++ = WLAN_EID_SUPP_RATES;
2966 *pos++ = rates;
2967 memcpy(pos, bss->supp_rates, rates);
2968
2969 if (bss->band == IEEE80211_BAND_2GHZ) {
2970 pos = skb_put(skb, 2 + 1);
2971 *pos++ = WLAN_EID_DS_PARAMS;
2972 *pos++ = 1;
2973 *pos++ = ieee80211_frequency_to_channel(bss->freq);
2974 }
2975
2976 pos = skb_put(skb, 2 + 2);
2977 *pos++ = WLAN_EID_IBSS_PARAMS;
2978 *pos++ = 2;
2979 /* FIX: set ATIM window based on scan results */
2980 *pos++ = 0;
2981 *pos++ = 0;
2982
2983 if (bss->supp_rates_len > 8) {
2984 rates = bss->supp_rates_len - 8;
2985 pos = skb_put(skb, 2 + rates);
2986 *pos++ = WLAN_EID_EXT_SUPP_RATES;
2987 *pos++ = rates;
2988 memcpy(pos, &bss->supp_rates[8], rates);
2989 }
2990
2991 memset(&control, 0, sizeof(control));
2992 rate_control_get_rate(dev, sband, skb, &ratesel);
2993 if (!ratesel.rate) {
2994 printk(KERN_DEBUG "%s: Failed to determine TX rate "
2995 "for IBSS beacon\n", dev->name);
2996 break;
2997 }
2998 control.vif = &sdata->vif;
2999 control.tx_rate = ratesel.rate;
3000 if (sdata->bss_conf.use_short_preamble &&
3001 ratesel.rate->flags & IEEE80211_RATE_SHORT_PREAMBLE)
3002 control.flags |= IEEE80211_TXCTL_SHORT_PREAMBLE;
3003 control.antenna_sel_tx = local->hw.conf.antenna_sel_tx;
3004 control.flags |= IEEE80211_TXCTL_NO_ACK;
3005 control.retry_limit = 1;
3006
3007 ifsta->probe_resp = skb_copy(skb, GFP_ATOMIC);
3008 if (ifsta->probe_resp) {
3009 mgmt = (struct ieee80211_mgmt *)
3010 ifsta->probe_resp->data;
3011 mgmt->frame_control =
3012 IEEE80211_FC(IEEE80211_FTYPE_MGMT,
3013 IEEE80211_STYPE_PROBE_RESP);
3014 } else {
3015 printk(KERN_DEBUG "%s: Could not allocate ProbeResp "
3016 "template for IBSS\n", dev->name);
3017 }
3018
3019 if (local->ops->beacon_update &&
3020 local->ops->beacon_update(local_to_hw(local),
3021 skb, &control) == 0) {
3022 printk(KERN_DEBUG "%s: Configured IBSS beacon "
3023 "template based on scan results\n", dev->name);
3024 skb = NULL;
3025 }
3026
3027 rates = 0;
3028 sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
3029 for (i = 0; i < bss->supp_rates_len; i++) {
3030 int bitrate = (bss->supp_rates[i] & 0x7f) * 5;
3031 for (j = 0; j < sband->n_bitrates; j++)
3032 if (sband->bitrates[j].bitrate == bitrate)
3033 rates |= BIT(j);
3034 }
3035 ifsta->supp_rates_bits[local->hw.conf.channel->band] = rates;
3036 } while (0);
3037
3038 if (skb) {
3039 printk(KERN_DEBUG "%s: Failed to configure IBSS beacon "
3040 "template\n", dev->name);
3041 dev_kfree_skb(skb);
3042 }
3043
3044 ifsta->state = IEEE80211_IBSS_JOINED;
3045 mod_timer(&ifsta->timer, jiffies + IEEE80211_IBSS_MERGE_INTERVAL);
3046
3047 ieee80211_rx_bss_put(dev, bss);
3048
3049 return res;
3050}
3051
3052 3053
3053static int ieee80211_sta_create_ibss(struct net_device *dev, 3054static int ieee80211_sta_create_ibss(struct net_device *dev,
3054 struct ieee80211_if_sta *ifsta) 3055 struct ieee80211_if_sta *ifsta)