aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/libertas/cfg.c
diff options
context:
space:
mode:
authorKiran Divekar <dkiran@marvell.com>2010-06-05 02:20:42 -0400
committerJohn W. Linville <linville@tuxdriver.com>2010-06-23 15:14:00 -0400
commit1047d5edd4838f27dc86f24676178f2249c446ea (patch)
tree2cf140cd7ae14590367b8dccda3c8adaee754e06 /drivers/net/wireless/libertas/cfg.c
parente4fe4eafa41cf951fb8fe2b9725ae84c599668d8 (diff)
Libertas: Added 11d support using cfg80211
Added 11d support for libertas driver using cfg80211. This is based on Holger Shurig's initial work to add cfg80211 support libertas. (https://patchwork.kernel.org/patch/64286/) Please let us know, if there are any improvements comments. Code is added to send 11d enable command to firmware while initialisation and pass 11d specific information to firmware when notifier handler is called by cfg80211. Signed-off-by: Amitkumar Karwar <akarwar@marvell.com> Signed-off-by: Kiran Divekar <dkiran@marvell.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/libertas/cfg.c')
-rw-r--r--drivers/net/wireless/libertas/cfg.c110
1 files changed, 110 insertions, 0 deletions
diff --git a/drivers/net/wireless/libertas/cfg.c b/drivers/net/wireless/libertas/cfg.c
index 089f0722fa2..f36cc970ad1 100644
--- a/drivers/net/wireless/libertas/cfg.c
+++ b/drivers/net/wireless/libertas/cfg.c
@@ -8,6 +8,7 @@
8 8
9#include <linux/slab.h> 9#include <linux/slab.h>
10#include <linux/if_arp.h> 10#include <linux/if_arp.h>
11#include <linux/ieee80211.h>
11#include <net/cfg80211.h> 12#include <net/cfg80211.h>
12#include <asm/unaligned.h> 13#include <asm/unaligned.h>
13 14
@@ -2042,6 +2043,7 @@ int lbs_cfg_register(struct lbs_private *priv)
2042 */ 2043 */
2043 wdev->wiphy->cipher_suites = cipher_suites; 2044 wdev->wiphy->cipher_suites = cipher_suites;
2044 wdev->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites); 2045 wdev->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
2046 wdev->wiphy->reg_notifier = lbs_reg_notifier;
2045 2047
2046 ret = wiphy_register(wdev->wiphy); 2048 ret = wiphy_register(wdev->wiphy);
2047 if (ret < 0) 2049 if (ret < 0)
@@ -2061,6 +2063,114 @@ int lbs_cfg_register(struct lbs_private *priv)
2061 return ret; 2063 return ret;
2062} 2064}
2063 2065
2066/**
2067 * @brief This function sets DOMAIN INFO to FW
2068 * @param priv pointer to struct lbs_private
2069 * @return 0; -1
2070*/
2071static int lbs_11d_set_domain_info(struct lbs_private *priv)
2072{
2073 int ret;
2074
2075 ret = lbs_prepare_and_send_command(priv, CMD_802_11D_DOMAIN_INFO,
2076 CMD_ACT_SET,
2077 CMD_OPTION_WAITFORRSP, 0, NULL);
2078 if (ret)
2079 lbs_deb_11d("fail to dnld domain info\n");
2080
2081 return ret;
2082}
2083
2084static void lbs_send_domain_info_cmd_fw(struct wiphy *wiphy,
2085 struct regulatory_request *request)
2086{
2087 u8 no_of_triplet = 0;
2088 u8 no_of_parsed_chan = 0;
2089 u8 first_channel = 0, next_chan = 0, max_pwr = 0;
2090 u8 i, flag = 0;
2091 enum ieee80211_band band;
2092 struct ieee80211_supported_band *sband;
2093 struct ieee80211_channel *ch;
2094 struct lbs_private *priv = wiphy_priv(wiphy);
2095 struct lbs_802_11d_domain_reg *domain_info = &priv->domain_reg;
2096 int ret = 0;
2097
2098 lbs_deb_enter(LBS_DEB_CFG80211);
2099
2100 /* Set country code */
2101 domain_info->country_code[0] = request->alpha2[0];
2102 domain_info->country_code[1] = request->alpha2[1];
2103 domain_info->country_code[2] = ' ';
2104
2105 for (band = 0; band < IEEE80211_NUM_BANDS ; band++) {
2106
2107 if (!wiphy->bands[band])
2108 continue;
2109
2110 sband = wiphy->bands[band];
2111
2112 for (i = 0; i < sband->n_channels ; i++) {
2113 ch = &sband->channels[i];
2114 if (ch->flags & IEEE80211_CHAN_DISABLED)
2115 continue;
2116
2117 if (!flag) {
2118 flag = 1;
2119 next_chan = first_channel = (u32) ch->hw_value;
2120 max_pwr = ch->max_power;
2121 no_of_parsed_chan = 1;
2122 continue;
2123 }
2124
2125 if (ch->hw_value == next_chan + 1 &&
2126 ch->max_power == max_pwr) {
2127 next_chan++;
2128 no_of_parsed_chan++;
2129 } else {
2130 domain_info->triplet[no_of_triplet]
2131 .chans.first_channel = first_channel;
2132 domain_info->triplet[no_of_triplet]
2133 .chans.num_channels = no_of_parsed_chan;
2134 domain_info->triplet[no_of_triplet]
2135 .chans.max_power = max_pwr;
2136 no_of_triplet++;
2137 flag = 0;
2138 }
2139 }
2140 if (flag) {
2141 domain_info->triplet[no_of_triplet]
2142 .chans.first_channel = first_channel;
2143 domain_info->triplet[no_of_triplet]
2144 .chans.num_channels = no_of_parsed_chan;
2145 domain_info->triplet[no_of_triplet]
2146 .chans.max_power = max_pwr;
2147 no_of_triplet++;
2148 }
2149 }
2150
2151 domain_info->no_triplet = no_of_triplet;
2152
2153 /* Set domain info */
2154 ret = lbs_11d_set_domain_info(priv);
2155 if (ret)
2156 lbs_pr_err("11D: error setting domain info in FW\n");
2157
2158 lbs_deb_leave(LBS_DEB_CFG80211);
2159}
2160
2161int lbs_reg_notifier(struct wiphy *wiphy,
2162 struct regulatory_request *request)
2163{
2164 lbs_deb_enter_args(LBS_DEB_CFG80211, "cfg80211 regulatory domain "
2165 "callback for domain %c%c\n", request->alpha2[0],
2166 request->alpha2[1]);
2167
2168 lbs_send_domain_info_cmd_fw(wiphy, request);
2169
2170 lbs_deb_leave(LBS_DEB_CFG80211);
2171
2172 return 0;
2173}
2064 2174
2065void lbs_scan_deinit(struct lbs_private *priv) 2175void lbs_scan_deinit(struct lbs_private *priv)
2066{ 2176{