diff options
author | Bruno Randolf <bruno@thinktube.com> | 2008-02-17 21:21:15 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-02-29 15:37:12 -0500 |
commit | a607268a0d5532d6ae3777ddd0339ff7d8b037a0 (patch) | |
tree | 1645aae649f2bf4736f5cbfde185cd1b60eb3f09 | |
parent | c132bec33c2eb5e46d8e4b80cfa5a9656d8e57e7 (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>
-rw-r--r-- | net/mac80211/ieee80211_sta.c | 317 |
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 | ||
2030 | static 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 | |||
2030 | static void ieee80211_rx_bss_info(struct net_device *dev, | 2189 | static 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 | ||
2894 | static 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 | ||
3053 | static int ieee80211_sta_create_ibss(struct net_device *dev, | 3054 | static int ieee80211_sta_create_ibss(struct net_device *dev, |
3054 | struct ieee80211_if_sta *ifsta) | 3055 | struct ieee80211_if_sta *ifsta) |