aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/libertas
diff options
context:
space:
mode:
authorHolger Schurig <hs4233@mail.mn-solutions.de>2008-04-02 10:27:10 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-04-08 16:44:40 -0400
commit697900ac14528e985b66f471ecb81082fc00baa9 (patch)
treeafcfac67c1ce47c2005d35eb84249a4fb1a19736 /drivers/net/wireless/libertas
parent53f36d70f072403d9aef68b332b72eb8c559b4ae (diff)
libertas: move association code from join.c into scan.c
Besides code moving, I did the following changes: * made some functions static * removed some unneeded #include's * made patch checkpatch.pl clean Signed-off-by: Holger Schurig <hs4233@mail.mn-solutions.de> Acked-by: Dan Williams <dcbw@redhat.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/libertas')
-rw-r--r--drivers/net/wireless/libertas/Makefile2
-rw-r--r--drivers/net/wireless/libertas/assoc.c862
-rw-r--r--drivers/net/wireless/libertas/assoc.h28
-rw-r--r--drivers/net/wireless/libertas/cmd.c2
-rw-r--r--drivers/net/wireless/libertas/cmdresp.c2
-rw-r--r--drivers/net/wireless/libertas/ethtool.c1
-rw-r--r--drivers/net/wireless/libertas/join.c872
-rw-r--r--drivers/net/wireless/libertas/join.h48
-rw-r--r--drivers/net/wireless/libertas/main.c1
-rw-r--r--drivers/net/wireless/libertas/scan.c2
-rw-r--r--drivers/net/wireless/libertas/wext.c1
11 files changed, 890 insertions, 931 deletions
diff --git a/drivers/net/wireless/libertas/Makefile b/drivers/net/wireless/libertas/Makefile
index 0e2787691f96..f0724e31adfd 100644
--- a/drivers/net/wireless/libertas/Makefile
+++ b/drivers/net/wireless/libertas/Makefile
@@ -1,7 +1,7 @@
1libertas-objs := main.o wext.o \ 1libertas-objs := main.o wext.o \
2 rx.o tx.o cmd.o \ 2 rx.o tx.o cmd.o \
3 cmdresp.o scan.o \ 3 cmdresp.o scan.o \
4 join.o 11d.o \ 4 11d.o \
5 debugfs.o \ 5 debugfs.o \
6 ethtool.o assoc.o 6 ethtool.o assoc.o
7 7
diff --git a/drivers/net/wireless/libertas/assoc.c b/drivers/net/wireless/libertas/assoc.c
index 95d98203eb4e..e794e93a2297 100644
--- a/drivers/net/wireless/libertas/assoc.c
+++ b/drivers/net/wireless/libertas/assoc.c
@@ -1,13 +1,9 @@
1/* Copyright (C) 2006, Red Hat, Inc. */ 1/* Copyright (C) 2006, Red Hat, Inc. */
2 2
3#include <linux/bitops.h>
4#include <net/ieee80211.h>
5#include <linux/etherdevice.h> 3#include <linux/etherdevice.h>
6 4
7#include "assoc.h" 5#include "assoc.h"
8#include "join.h"
9#include "decl.h" 6#include "decl.h"
10#include "hostcmd.h"
11#include "host.h" 7#include "host.h"
12#include "cmd.h" 8#include "cmd.h"
13 9
@@ -17,6 +13,162 @@ static const u8 bssid_any[ETH_ALEN] __attribute__ ((aligned (2))) =
17static const u8 bssid_off[ETH_ALEN] __attribute__ ((aligned (2))) = 13static const u8 bssid_off[ETH_ALEN] __attribute__ ((aligned (2))) =
18 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 14 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
19 15
16/* The firmware needs certain bits masked out of the beacon-derviced capability
17 * field when associating/joining to BSSs.
18 */
19#define CAPINFO_MASK (~(0xda00))
20
21
22
23/**
24 * @brief Associate to a specific BSS discovered in a scan
25 *
26 * @param priv A pointer to struct lbs_private structure
27 * @param pbssdesc Pointer to the BSS descriptor to associate with.
28 *
29 * @return 0-success, otherwise fail
30 */
31static int lbs_associate(struct lbs_private *priv,
32 struct assoc_request *assoc_req)
33{
34 int ret;
35
36 lbs_deb_enter(LBS_DEB_ASSOC);
37
38 ret = lbs_prepare_and_send_command(priv, CMD_802_11_AUTHENTICATE,
39 0, CMD_OPTION_WAITFORRSP,
40 0, assoc_req->bss.bssid);
41
42 if (ret)
43 goto done;
44
45 /* set preamble to firmware */
46 if ((priv->capability & WLAN_CAPABILITY_SHORT_PREAMBLE) &&
47 (assoc_req->bss.capability & WLAN_CAPABILITY_SHORT_PREAMBLE))
48 priv->preamble = CMD_TYPE_SHORT_PREAMBLE;
49 else
50 priv->preamble = CMD_TYPE_LONG_PREAMBLE;
51
52 lbs_set_radio_control(priv);
53
54 ret = lbs_prepare_and_send_command(priv, CMD_802_11_ASSOCIATE,
55 0, CMD_OPTION_WAITFORRSP, 0, assoc_req);
56
57done:
58 lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
59 return ret;
60}
61
62/**
63 * @brief Join an adhoc network found in a previous scan
64 *
65 * @param priv A pointer to struct lbs_private structure
66 * @param pbssdesc Pointer to a BSS descriptor found in a previous scan
67 * to attempt to join
68 *
69 * @return 0--success, -1--fail
70 */
71static int lbs_join_adhoc_network(struct lbs_private *priv,
72 struct assoc_request *assoc_req)
73{
74 struct bss_descriptor *bss = &assoc_req->bss;
75 int ret = 0;
76
77 lbs_deb_join("current SSID '%s', ssid length %u\n",
78 escape_essid(priv->curbssparams.ssid,
79 priv->curbssparams.ssid_len),
80 priv->curbssparams.ssid_len);
81 lbs_deb_join("requested ssid '%s', ssid length %u\n",
82 escape_essid(bss->ssid, bss->ssid_len),
83 bss->ssid_len);
84
85 /* check if the requested SSID is already joined */
86 if (priv->curbssparams.ssid_len &&
87 !lbs_ssid_cmp(priv->curbssparams.ssid,
88 priv->curbssparams.ssid_len,
89 bss->ssid, bss->ssid_len) &&
90 (priv->mode == IW_MODE_ADHOC) &&
91 (priv->connect_status == LBS_CONNECTED)) {
92 union iwreq_data wrqu;
93
94 lbs_deb_join("ADHOC_J_CMD: New ad-hoc SSID is the same as "
95 "current, not attempting to re-join");
96
97 /* Send the re-association event though, because the association
98 * request really was successful, even if just a null-op.
99 */
100 memset(&wrqu, 0, sizeof(wrqu));
101 memcpy(wrqu.ap_addr.sa_data, priv->curbssparams.bssid,
102 ETH_ALEN);
103 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
104 wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL);
105 goto out;
106 }
107
108 /* Use shortpreamble only when both creator and card supports
109 short preamble */
110 if (!(bss->capability & WLAN_CAPABILITY_SHORT_PREAMBLE) ||
111 !(priv->capability & WLAN_CAPABILITY_SHORT_PREAMBLE)) {
112 lbs_deb_join("AdhocJoin: Long preamble\n");
113 priv->preamble = CMD_TYPE_LONG_PREAMBLE;
114 } else {
115 lbs_deb_join("AdhocJoin: Short preamble\n");
116 priv->preamble = CMD_TYPE_SHORT_PREAMBLE;
117 }
118
119 lbs_set_radio_control(priv);
120
121 lbs_deb_join("AdhocJoin: channel = %d\n", assoc_req->channel);
122 lbs_deb_join("AdhocJoin: band = %c\n", assoc_req->band);
123
124 priv->adhoccreate = 0;
125
126 ret = lbs_prepare_and_send_command(priv, CMD_802_11_AD_HOC_JOIN,
127 0, CMD_OPTION_WAITFORRSP,
128 OID_802_11_SSID, assoc_req);
129
130out:
131 return ret;
132}
133
134/**
135 * @brief Start an Adhoc Network
136 *
137 * @param priv A pointer to struct lbs_private structure
138 * @param adhocssid The ssid of the Adhoc Network
139 * @return 0--success, -1--fail
140 */
141static int lbs_start_adhoc_network(struct lbs_private *priv,
142 struct assoc_request *assoc_req)
143{
144 int ret = 0;
145
146 priv->adhoccreate = 1;
147
148 if (priv->capability & WLAN_CAPABILITY_SHORT_PREAMBLE) {
149 lbs_deb_join("AdhocStart: Short preamble\n");
150 priv->preamble = CMD_TYPE_SHORT_PREAMBLE;
151 } else {
152 lbs_deb_join("AdhocStart: Long preamble\n");
153 priv->preamble = CMD_TYPE_LONG_PREAMBLE;
154 }
155
156 lbs_set_radio_control(priv);
157
158 lbs_deb_join("AdhocStart: channel = %d\n", assoc_req->channel);
159 lbs_deb_join("AdhocStart: band = %d\n", assoc_req->band);
160
161 ret = lbs_prepare_and_send_command(priv, CMD_802_11_AD_HOC_START,
162 0, CMD_OPTION_WAITFORRSP, 0, assoc_req);
163
164 return ret;
165}
166
167int lbs_stop_adhoc_network(struct lbs_private *priv)
168{
169 return lbs_prepare_and_send_command(priv, CMD_802_11_AD_HOC_STOP,
170 0, CMD_OPTION_WAITFORRSP, 0, NULL);
171}
20 172
21static int assoc_helper_essid(struct lbs_private *priv, 173static int assoc_helper_essid(struct lbs_private *priv,
22 struct assoc_request * assoc_req) 174 struct assoc_request * assoc_req)
@@ -722,3 +874,705 @@ struct assoc_request *lbs_get_association_request(struct lbs_private *priv)
722 lbs_deb_leave(LBS_DEB_ASSOC); 874 lbs_deb_leave(LBS_DEB_ASSOC);
723 return assoc_req; 875 return assoc_req;
724} 876}
877
878
879/**
880 * @brief This function finds common rates between rate1 and card rates.
881 *
882 * It will fill common rates in rate1 as output if found.
883 *
884 * NOTE: Setting the MSB of the basic rates need to be taken
885 * care, either before or after calling this function
886 *
887 * @param priv A pointer to struct lbs_private structure
888 * @param rate1 the buffer which keeps input and output
889 * @param rate1_size the size of rate1 buffer; new size of buffer on return
890 *
891 * @return 0 or -1
892 */
893static int get_common_rates(struct lbs_private *priv,
894 u8 *rates,
895 u16 *rates_size)
896{
897 u8 *card_rates = lbs_bg_rates;
898 size_t num_card_rates = sizeof(lbs_bg_rates);
899 int ret = 0, i, j;
900 u8 tmp[30];
901 size_t tmp_size = 0;
902
903 /* For each rate in card_rates that exists in rate1, copy to tmp */
904 for (i = 0; card_rates[i] && (i < num_card_rates); i++) {
905 for (j = 0; rates[j] && (j < *rates_size); j++) {
906 if (rates[j] == card_rates[i])
907 tmp[tmp_size++] = card_rates[i];
908 }
909 }
910
911 lbs_deb_hex(LBS_DEB_JOIN, "AP rates ", rates, *rates_size);
912 lbs_deb_hex(LBS_DEB_JOIN, "card rates ", card_rates, num_card_rates);
913 lbs_deb_hex(LBS_DEB_JOIN, "common rates", tmp, tmp_size);
914 lbs_deb_join("TX data rate 0x%02x\n", priv->cur_rate);
915
916 if (!priv->auto_rate) {
917 for (i = 0; i < tmp_size; i++) {
918 if (tmp[i] == priv->cur_rate)
919 goto done;
920 }
921 lbs_pr_alert("Previously set fixed data rate %#x isn't "
922 "compatible with the network.\n", priv->cur_rate);
923 ret = -1;
924 goto done;
925 }
926 ret = 0;
927
928done:
929 memset(rates, 0, *rates_size);
930 *rates_size = min_t(int, tmp_size, *rates_size);
931 memcpy(rates, tmp, *rates_size);
932 return ret;
933}
934
935
936/**
937 * @brief Sets the MSB on basic rates as the firmware requires
938 *
939 * Scan through an array and set the MSB for basic data rates.
940 *
941 * @param rates buffer of data rates
942 * @param len size of buffer
943 */
944static void lbs_set_basic_rate_flags(u8 *rates, size_t len)
945{
946 int i;
947
948 for (i = 0; i < len; i++) {
949 if (rates[i] == 0x02 || rates[i] == 0x04 ||
950 rates[i] == 0x0b || rates[i] == 0x16)
951 rates[i] |= 0x80;
952 }
953}
954
955/**
956 * @brief Send Deauthentication Request
957 *
958 * @param priv A pointer to struct lbs_private structure
959 * @return 0--success, -1--fail
960 */
961int lbs_send_deauthentication(struct lbs_private *priv)
962{
963 return lbs_prepare_and_send_command(priv, CMD_802_11_DEAUTHENTICATE,
964 0, CMD_OPTION_WAITFORRSP, 0, NULL);
965}
966
967/**
968 * @brief This function prepares command of authenticate.
969 *
970 * @param priv A pointer to struct lbs_private structure
971 * @param cmd A pointer to cmd_ds_command structure
972 * @param pdata_buf Void cast of pointer to a BSSID to authenticate with
973 *
974 * @return 0 or -1
975 */
976int lbs_cmd_80211_authenticate(struct lbs_private *priv,
977 struct cmd_ds_command *cmd,
978 void *pdata_buf)
979{
980 struct cmd_ds_802_11_authenticate *pauthenticate = &cmd->params.auth;
981 int ret = -1;
982 u8 *bssid = pdata_buf;
983 DECLARE_MAC_BUF(mac);
984
985 lbs_deb_enter(LBS_DEB_JOIN);
986
987 cmd->command = cpu_to_le16(CMD_802_11_AUTHENTICATE);
988 cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_authenticate)
989 + S_DS_GEN);
990
991 /* translate auth mode to 802.11 defined wire value */
992 switch (priv->secinfo.auth_mode) {
993 case IW_AUTH_ALG_OPEN_SYSTEM:
994 pauthenticate->authtype = 0x00;
995 break;
996 case IW_AUTH_ALG_SHARED_KEY:
997 pauthenticate->authtype = 0x01;
998 break;
999 case IW_AUTH_ALG_LEAP:
1000 pauthenticate->authtype = 0x80;
1001 break;
1002 default:
1003 lbs_deb_join("AUTH_CMD: invalid auth alg 0x%X\n",
1004 priv->secinfo.auth_mode);
1005 goto out;
1006 }
1007
1008 memcpy(pauthenticate->macaddr, bssid, ETH_ALEN);
1009
1010 lbs_deb_join("AUTH_CMD: BSSID %s, auth 0x%x\n",
1011 print_mac(mac, bssid), pauthenticate->authtype);
1012 ret = 0;
1013
1014out:
1015 lbs_deb_leave_args(LBS_DEB_JOIN, "ret %d", ret);
1016 return ret;
1017}
1018
1019int lbs_cmd_80211_deauthenticate(struct lbs_private *priv,
1020 struct cmd_ds_command *cmd)
1021{
1022 struct cmd_ds_802_11_deauthenticate *dauth = &cmd->params.deauth;
1023
1024 lbs_deb_enter(LBS_DEB_JOIN);
1025
1026 cmd->command = cpu_to_le16(CMD_802_11_DEAUTHENTICATE);
1027 cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_deauthenticate) +
1028 S_DS_GEN);
1029
1030 /* set AP MAC address */
1031 memmove(dauth->macaddr, priv->curbssparams.bssid, ETH_ALEN);
1032
1033 /* Reason code 3 = Station is leaving */
1034#define REASON_CODE_STA_LEAVING 3
1035 dauth->reasoncode = cpu_to_le16(REASON_CODE_STA_LEAVING);
1036
1037 lbs_deb_leave(LBS_DEB_JOIN);
1038 return 0;
1039}
1040
1041int lbs_cmd_80211_associate(struct lbs_private *priv,
1042 struct cmd_ds_command *cmd, void *pdata_buf)
1043{
1044 struct cmd_ds_802_11_associate *passo = &cmd->params.associate;
1045 int ret = 0;
1046 struct assoc_request *assoc_req = pdata_buf;
1047 struct bss_descriptor *bss = &assoc_req->bss;
1048 u8 *pos;
1049 u16 tmpcap, tmplen;
1050 struct mrvlietypes_ssidparamset *ssid;
1051 struct mrvlietypes_phyparamset *phy;
1052 struct mrvlietypes_ssparamset *ss;
1053 struct mrvlietypes_ratesparamset *rates;
1054 struct mrvlietypes_rsnparamset *rsn;
1055
1056 lbs_deb_enter(LBS_DEB_ASSOC);
1057
1058 pos = (u8 *) passo;
1059
1060 if (!priv) {
1061 ret = -1;
1062 goto done;
1063 }
1064
1065 cmd->command = cpu_to_le16(CMD_802_11_ASSOCIATE);
1066
1067 memcpy(passo->peerstaaddr, bss->bssid, sizeof(passo->peerstaaddr));
1068 pos += sizeof(passo->peerstaaddr);
1069
1070 /* set the listen interval */
1071 passo->listeninterval = cpu_to_le16(MRVDRV_DEFAULT_LISTEN_INTERVAL);
1072
1073 pos += sizeof(passo->capability);
1074 pos += sizeof(passo->listeninterval);
1075 pos += sizeof(passo->bcnperiod);
1076 pos += sizeof(passo->dtimperiod);
1077
1078 ssid = (struct mrvlietypes_ssidparamset *) pos;
1079 ssid->header.type = cpu_to_le16(TLV_TYPE_SSID);
1080 tmplen = bss->ssid_len;
1081 ssid->header.len = cpu_to_le16(tmplen);
1082 memcpy(ssid->ssid, bss->ssid, tmplen);
1083 pos += sizeof(ssid->header) + tmplen;
1084
1085 phy = (struct mrvlietypes_phyparamset *) pos;
1086 phy->header.type = cpu_to_le16(TLV_TYPE_PHY_DS);
1087 tmplen = sizeof(phy->fh_ds.dsparamset);
1088 phy->header.len = cpu_to_le16(tmplen);
1089 memcpy(&phy->fh_ds.dsparamset,
1090 &bss->phyparamset.dsparamset.currentchan,
1091 tmplen);
1092 pos += sizeof(phy->header) + tmplen;
1093
1094 ss = (struct mrvlietypes_ssparamset *) pos;
1095 ss->header.type = cpu_to_le16(TLV_TYPE_CF);
1096 tmplen = sizeof(ss->cf_ibss.cfparamset);
1097 ss->header.len = cpu_to_le16(tmplen);
1098 pos += sizeof(ss->header) + tmplen;
1099
1100 rates = (struct mrvlietypes_ratesparamset *) pos;
1101 rates->header.type = cpu_to_le16(TLV_TYPE_RATES);
1102 memcpy(&rates->rates, &bss->rates, MAX_RATES);
1103 tmplen = MAX_RATES;
1104 if (get_common_rates(priv, rates->rates, &tmplen)) {
1105 ret = -1;
1106 goto done;
1107 }
1108 pos += sizeof(rates->header) + tmplen;
1109 rates->header.len = cpu_to_le16(tmplen);
1110 lbs_deb_assoc("ASSOC_CMD: num rates %u\n", tmplen);
1111
1112 /* Copy the infra. association rates into Current BSS state structure */
1113 memset(&priv->curbssparams.rates, 0, sizeof(priv->curbssparams.rates));
1114 memcpy(&priv->curbssparams.rates, &rates->rates, tmplen);
1115
1116 /* Set MSB on basic rates as the firmware requires, but _after_
1117 * copying to current bss rates.
1118 */
1119 lbs_set_basic_rate_flags(rates->rates, tmplen);
1120
1121 if (assoc_req->secinfo.WPAenabled || assoc_req->secinfo.WPA2enabled) {
1122 rsn = (struct mrvlietypes_rsnparamset *) pos;
1123 /* WPA_IE or WPA2_IE */
1124 rsn->header.type = cpu_to_le16((u16) assoc_req->wpa_ie[0]);
1125 tmplen = (u16) assoc_req->wpa_ie[1];
1126 rsn->header.len = cpu_to_le16(tmplen);
1127 memcpy(rsn->rsnie, &assoc_req->wpa_ie[2], tmplen);
1128 lbs_deb_hex(LBS_DEB_JOIN, "ASSOC_CMD: RSN IE", (u8 *) rsn,
1129 sizeof(rsn->header) + tmplen);
1130 pos += sizeof(rsn->header) + tmplen;
1131 }
1132
1133 /* update curbssparams */
1134 priv->curbssparams.channel = bss->phyparamset.dsparamset.currentchan;
1135
1136 if (lbs_parse_dnld_countryinfo_11d(priv, bss)) {
1137 ret = -1;
1138 goto done;
1139 }
1140
1141 cmd->size = cpu_to_le16((u16) (pos - (u8 *) passo) + S_DS_GEN);
1142
1143 /* set the capability info */
1144 tmpcap = (bss->capability & CAPINFO_MASK);
1145 if (bss->mode == IW_MODE_INFRA)
1146 tmpcap |= WLAN_CAPABILITY_ESS;
1147 passo->capability = cpu_to_le16(tmpcap);
1148 lbs_deb_assoc("ASSOC_CMD: capability 0x%04x\n", tmpcap);
1149
1150done:
1151 lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
1152 return ret;
1153}
1154
1155int lbs_cmd_80211_ad_hoc_start(struct lbs_private *priv,
1156 struct cmd_ds_command *cmd, void *pdata_buf)
1157{
1158 struct cmd_ds_802_11_ad_hoc_start *adhs = &cmd->params.ads;
1159 int ret = 0;
1160 int cmdappendsize = 0;
1161 struct assoc_request *assoc_req = pdata_buf;
1162 u16 tmpcap = 0;
1163 size_t ratesize = 0;
1164
1165 lbs_deb_enter(LBS_DEB_JOIN);
1166
1167 if (!priv) {
1168 ret = -1;
1169 goto done;
1170 }
1171
1172 cmd->command = cpu_to_le16(CMD_802_11_AD_HOC_START);
1173
1174 /*
1175 * Fill in the parameters for 2 data structures:
1176 * 1. cmd_ds_802_11_ad_hoc_start command
1177 * 2. priv->scantable[i]
1178 *
1179 * Driver will fill up SSID, bsstype,IBSS param, Physical Param,
1180 * probe delay, and cap info.
1181 *
1182 * Firmware will fill up beacon period, DTIM, Basic rates
1183 * and operational rates.
1184 */
1185
1186 memset(adhs->ssid, 0, IW_ESSID_MAX_SIZE);
1187 memcpy(adhs->ssid, assoc_req->ssid, assoc_req->ssid_len);
1188
1189 lbs_deb_join("ADHOC_S_CMD: SSID '%s', ssid length %u\n",
1190 escape_essid(assoc_req->ssid, assoc_req->ssid_len),
1191 assoc_req->ssid_len);
1192
1193 /* set the BSS type */
1194 adhs->bsstype = CMD_BSS_TYPE_IBSS;
1195 priv->mode = IW_MODE_ADHOC;
1196 if (priv->beacon_period == 0)
1197 priv->beacon_period = MRVDRV_BEACON_INTERVAL;
1198 adhs->beaconperiod = cpu_to_le16(priv->beacon_period);
1199
1200 /* set Physical param set */
1201#define DS_PARA_IE_ID 3
1202#define DS_PARA_IE_LEN 1
1203
1204 adhs->phyparamset.dsparamset.elementid = DS_PARA_IE_ID;
1205 adhs->phyparamset.dsparamset.len = DS_PARA_IE_LEN;
1206
1207 WARN_ON(!assoc_req->channel);
1208
1209 lbs_deb_join("ADHOC_S_CMD: Creating ADHOC on channel %d\n",
1210 assoc_req->channel);
1211
1212 adhs->phyparamset.dsparamset.currentchan = assoc_req->channel;
1213
1214 /* set IBSS param set */
1215#define IBSS_PARA_IE_ID 6
1216#define IBSS_PARA_IE_LEN 2
1217
1218 adhs->ssparamset.ibssparamset.elementid = IBSS_PARA_IE_ID;
1219 adhs->ssparamset.ibssparamset.len = IBSS_PARA_IE_LEN;
1220 adhs->ssparamset.ibssparamset.atimwindow = 0;
1221
1222 /* set capability info */
1223 tmpcap = WLAN_CAPABILITY_IBSS;
1224 if (assoc_req->secinfo.wep_enabled) {
1225 lbs_deb_join("ADHOC_S_CMD: WEP enabled, "
1226 "setting privacy on\n");
1227 tmpcap |= WLAN_CAPABILITY_PRIVACY;
1228 } else {
1229 lbs_deb_join("ADHOC_S_CMD: WEP disabled, "
1230 "setting privacy off\n");
1231 }
1232 adhs->capability = cpu_to_le16(tmpcap);
1233
1234 /* probedelay */
1235 adhs->probedelay = cpu_to_le16(CMD_SCAN_PROBE_DELAY_TIME);
1236
1237 memset(adhs->rates, 0, sizeof(adhs->rates));
1238 ratesize = min(sizeof(adhs->rates), sizeof(lbs_bg_rates));
1239 memcpy(adhs->rates, lbs_bg_rates, ratesize);
1240
1241 /* Copy the ad-hoc creating rates into Current BSS state structure */
1242 memset(&priv->curbssparams.rates, 0, sizeof(priv->curbssparams.rates));
1243 memcpy(&priv->curbssparams.rates, &adhs->rates, ratesize);
1244
1245 /* Set MSB on basic rates as the firmware requires, but _after_
1246 * copying to current bss rates.
1247 */
1248 lbs_set_basic_rate_flags(adhs->rates, ratesize);
1249
1250 lbs_deb_join("ADHOC_S_CMD: rates=%02x %02x %02x %02x \n",
1251 adhs->rates[0], adhs->rates[1], adhs->rates[2], adhs->rates[3]);
1252
1253 lbs_deb_join("ADHOC_S_CMD: AD HOC Start command is ready\n");
1254
1255 if (lbs_create_dnld_countryinfo_11d(priv)) {
1256 lbs_deb_join("ADHOC_S_CMD: dnld_countryinfo_11d failed\n");
1257 ret = -1;
1258 goto done;
1259 }
1260
1261 cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_ad_hoc_start) +
1262 S_DS_GEN + cmdappendsize);
1263
1264 ret = 0;
1265done:
1266 lbs_deb_leave_args(LBS_DEB_JOIN, "ret %d", ret);
1267 return ret;
1268}
1269
1270int lbs_cmd_80211_ad_hoc_stop(struct cmd_ds_command *cmd)
1271{
1272 cmd->command = cpu_to_le16(CMD_802_11_AD_HOC_STOP);
1273 cmd->size = cpu_to_le16(S_DS_GEN);
1274
1275 return 0;
1276}
1277
1278int lbs_cmd_80211_ad_hoc_join(struct lbs_private *priv,
1279 struct cmd_ds_command *cmd, void *pdata_buf)
1280{
1281 struct cmd_ds_802_11_ad_hoc_join *join_cmd = &cmd->params.adj;
1282 struct assoc_request *assoc_req = pdata_buf;
1283 struct bss_descriptor *bss = &assoc_req->bss;
1284 int cmdappendsize = 0;
1285 int ret = 0;
1286 u16 ratesize = 0;
1287 DECLARE_MAC_BUF(mac);
1288
1289 lbs_deb_enter(LBS_DEB_JOIN);
1290
1291 cmd->command = cpu_to_le16(CMD_802_11_AD_HOC_JOIN);
1292
1293 join_cmd->bss.type = CMD_BSS_TYPE_IBSS;
1294 join_cmd->bss.beaconperiod = cpu_to_le16(bss->beaconperiod);
1295
1296 memcpy(&join_cmd->bss.bssid, &bss->bssid, ETH_ALEN);
1297 memcpy(&join_cmd->bss.ssid, &bss->ssid, bss->ssid_len);
1298
1299 memcpy(&join_cmd->bss.phyparamset, &bss->phyparamset,
1300 sizeof(union ieeetypes_phyparamset));
1301
1302 memcpy(&join_cmd->bss.ssparamset, &bss->ssparamset,
1303 sizeof(union IEEEtypes_ssparamset));
1304
1305 join_cmd->bss.capability = cpu_to_le16(bss->capability & CAPINFO_MASK);
1306 lbs_deb_join("ADHOC_J_CMD: tmpcap=%4X CAPINFO_MASK=%4X\n",
1307 bss->capability, CAPINFO_MASK);
1308
1309 /* information on BSSID descriptor passed to FW */
1310 lbs_deb_join(
1311 "ADHOC_J_CMD: BSSID = %s, SSID = '%s'\n",
1312 print_mac(mac, join_cmd->bss.bssid),
1313 join_cmd->bss.ssid);
1314
1315 /* failtimeout */
1316 join_cmd->failtimeout = cpu_to_le16(MRVDRV_ASSOCIATION_TIME_OUT);
1317
1318 /* probedelay */
1319 join_cmd->probedelay = cpu_to_le16(CMD_SCAN_PROBE_DELAY_TIME);
1320
1321 priv->curbssparams.channel = bss->channel;
1322
1323 /* Copy Data rates from the rates recorded in scan response */
1324 memset(join_cmd->bss.rates, 0, sizeof(join_cmd->bss.rates));
1325 ratesize = min_t(u16, sizeof(join_cmd->bss.rates), MAX_RATES);
1326 memcpy(join_cmd->bss.rates, bss->rates, ratesize);
1327 if (get_common_rates(priv, join_cmd->bss.rates, &ratesize)) {
1328 lbs_deb_join("ADHOC_J_CMD: get_common_rates returns error.\n");
1329 ret = -1;
1330 goto done;
1331 }
1332
1333 /* Copy the ad-hoc creating rates into Current BSS state structure */
1334 memset(&priv->curbssparams.rates, 0, sizeof(priv->curbssparams.rates));
1335 memcpy(&priv->curbssparams.rates, join_cmd->bss.rates, ratesize);
1336
1337 /* Set MSB on basic rates as the firmware requires, but _after_
1338 * copying to current bss rates.
1339 */
1340 lbs_set_basic_rate_flags(join_cmd->bss.rates, ratesize);
1341
1342 join_cmd->bss.ssparamset.ibssparamset.atimwindow =
1343 cpu_to_le16(bss->atimwindow);
1344
1345 if (assoc_req->secinfo.wep_enabled) {
1346 u16 tmp = le16_to_cpu(join_cmd->bss.capability);
1347 tmp |= WLAN_CAPABILITY_PRIVACY;
1348 join_cmd->bss.capability = cpu_to_le16(tmp);
1349 }
1350
1351 if (priv->psmode == LBS802_11POWERMODEMAX_PSP) {
1352 /* wake up first */
1353 __le32 Localpsmode;
1354
1355 Localpsmode = cpu_to_le32(LBS802_11POWERMODECAM);
1356 ret = lbs_prepare_and_send_command(priv,
1357 CMD_802_11_PS_MODE,
1358 CMD_ACT_SET,
1359 0, 0, &Localpsmode);
1360
1361 if (ret) {
1362 ret = -1;
1363 goto done;
1364 }
1365 }
1366
1367 if (lbs_parse_dnld_countryinfo_11d(priv, bss)) {
1368 ret = -1;
1369 goto done;
1370 }
1371
1372 cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_ad_hoc_join) +
1373 S_DS_GEN + cmdappendsize);
1374
1375done:
1376 lbs_deb_leave_args(LBS_DEB_JOIN, "ret %d", ret);
1377 return ret;
1378}
1379
1380int lbs_ret_80211_associate(struct lbs_private *priv,
1381 struct cmd_ds_command *resp)
1382{
1383 int ret = 0;
1384 union iwreq_data wrqu;
1385 struct ieeetypes_assocrsp *passocrsp;
1386 struct bss_descriptor *bss;
1387 u16 status_code;
1388
1389 lbs_deb_enter(LBS_DEB_ASSOC);
1390
1391 if (!priv->in_progress_assoc_req) {
1392 lbs_deb_assoc("ASSOC_RESP: no in-progress assoc request\n");
1393 ret = -1;
1394 goto done;
1395 }
1396 bss = &priv->in_progress_assoc_req->bss;
1397
1398 passocrsp = (struct ieeetypes_assocrsp *) &resp->params;
1399
1400 /*
1401 * Older FW versions map the IEEE 802.11 Status Code in the association
1402 * response to the following values returned in passocrsp->statuscode:
1403 *
1404 * IEEE Status Code Marvell Status Code
1405 * 0 -> 0x0000 ASSOC_RESULT_SUCCESS
1406 * 13 -> 0x0004 ASSOC_RESULT_AUTH_REFUSED
1407 * 14 -> 0x0004 ASSOC_RESULT_AUTH_REFUSED
1408 * 15 -> 0x0004 ASSOC_RESULT_AUTH_REFUSED
1409 * 16 -> 0x0004 ASSOC_RESULT_AUTH_REFUSED
1410 * others -> 0x0003 ASSOC_RESULT_REFUSED
1411 *
1412 * Other response codes:
1413 * 0x0001 -> ASSOC_RESULT_INVALID_PARAMETERS (unused)
1414 * 0x0002 -> ASSOC_RESULT_TIMEOUT (internal timer expired waiting for
1415 * association response from the AP)
1416 */
1417
1418 status_code = le16_to_cpu(passocrsp->statuscode);
1419 switch (status_code) {
1420 case 0x00:
1421 break;
1422 case 0x01:
1423 lbs_deb_assoc("ASSOC_RESP: invalid parameters\n");
1424 break;
1425 case 0x02:
1426 lbs_deb_assoc("ASSOC_RESP: internal timer "
1427 "expired while waiting for the AP\n");
1428 break;
1429 case 0x03:
1430 lbs_deb_assoc("ASSOC_RESP: association "
1431 "refused by AP\n");
1432 break;
1433 case 0x04:
1434 lbs_deb_assoc("ASSOC_RESP: authentication "
1435 "refused by AP\n");
1436 break;
1437 default:
1438 lbs_deb_assoc("ASSOC_RESP: failure reason 0x%02x "
1439 " unknown\n", status_code);
1440 break;
1441 }
1442
1443 if (status_code) {
1444 lbs_mac_event_disconnected(priv);
1445 ret = -1;
1446 goto done;
1447 }
1448
1449 lbs_deb_hex(LBS_DEB_ASSOC, "ASSOC_RESP", (void *)&resp->params,
1450 le16_to_cpu(resp->size) - S_DS_GEN);
1451
1452 /* Send a Media Connected event, according to the Spec */
1453 priv->connect_status = LBS_CONNECTED;
1454
1455 /* Update current SSID and BSSID */
1456 memcpy(&priv->curbssparams.ssid, &bss->ssid, IW_ESSID_MAX_SIZE);
1457 priv->curbssparams.ssid_len = bss->ssid_len;
1458 memcpy(priv->curbssparams.bssid, bss->bssid, ETH_ALEN);
1459
1460 priv->SNR[TYPE_RXPD][TYPE_AVG] = 0;
1461 priv->NF[TYPE_RXPD][TYPE_AVG] = 0;
1462
1463 memset(priv->rawSNR, 0x00, sizeof(priv->rawSNR));
1464 memset(priv->rawNF, 0x00, sizeof(priv->rawNF));
1465 priv->nextSNRNF = 0;
1466 priv->numSNRNF = 0;
1467
1468 netif_carrier_on(priv->dev);
1469 if (!priv->tx_pending_len)
1470 netif_wake_queue(priv->dev);
1471
1472 memcpy(wrqu.ap_addr.sa_data, priv->curbssparams.bssid, ETH_ALEN);
1473 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
1474 wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL);
1475
1476done:
1477 lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
1478 return ret;
1479}
1480
1481int lbs_ret_80211_disassociate(struct lbs_private *priv)
1482{
1483 lbs_deb_enter(LBS_DEB_JOIN);
1484
1485 lbs_mac_event_disconnected(priv);
1486
1487 lbs_deb_leave(LBS_DEB_JOIN);
1488 return 0;
1489}
1490
1491int lbs_ret_80211_ad_hoc_start(struct lbs_private *priv,
1492 struct cmd_ds_command *resp)
1493{
1494 int ret = 0;
1495 u16 command = le16_to_cpu(resp->command);
1496 u16 result = le16_to_cpu(resp->result);
1497 struct cmd_ds_802_11_ad_hoc_result *padhocresult;
1498 union iwreq_data wrqu;
1499 struct bss_descriptor *bss;
1500 DECLARE_MAC_BUF(mac);
1501
1502 lbs_deb_enter(LBS_DEB_JOIN);
1503
1504 padhocresult = &resp->params.result;
1505
1506 lbs_deb_join("ADHOC_RESP: size = %d\n", le16_to_cpu(resp->size));
1507 lbs_deb_join("ADHOC_RESP: command = %x\n", command);
1508 lbs_deb_join("ADHOC_RESP: result = %x\n", result);
1509
1510 if (!priv->in_progress_assoc_req) {
1511 lbs_deb_join("ADHOC_RESP: no in-progress association "
1512 "request\n");
1513 ret = -1;
1514 goto done;
1515 }
1516 bss = &priv->in_progress_assoc_req->bss;
1517
1518 /*
1519 * Join result code 0 --> SUCCESS
1520 */
1521 if (result) {
1522 lbs_deb_join("ADHOC_RESP: failed\n");
1523 if (priv->connect_status == LBS_CONNECTED)
1524 lbs_mac_event_disconnected(priv);
1525 ret = -1;
1526 goto done;
1527 }
1528
1529 /*
1530 * Now the join cmd should be successful
1531 * If BSSID has changed use SSID to compare instead of BSSID
1532 */
1533 lbs_deb_join("ADHOC_RESP: associated to '%s'\n",
1534 escape_essid(bss->ssid, bss->ssid_len));
1535
1536 /* Send a Media Connected event, according to the Spec */
1537 priv->connect_status = LBS_CONNECTED;
1538
1539 if (command == CMD_RET(CMD_802_11_AD_HOC_START)) {
1540 /* Update the created network descriptor with the new BSSID */
1541 memcpy(bss->bssid, padhocresult->bssid, ETH_ALEN);
1542 }
1543
1544 /* Set the BSSID from the joined/started descriptor */
1545 memcpy(&priv->curbssparams.bssid, bss->bssid, ETH_ALEN);
1546
1547 /* Set the new SSID to current SSID */
1548 memcpy(&priv->curbssparams.ssid, &bss->ssid, IW_ESSID_MAX_SIZE);
1549 priv->curbssparams.ssid_len = bss->ssid_len;
1550
1551 netif_carrier_on(priv->dev);
1552 if (!priv->tx_pending_len)
1553 netif_wake_queue(priv->dev);
1554
1555 memset(&wrqu, 0, sizeof(wrqu));
1556 memcpy(wrqu.ap_addr.sa_data, priv->curbssparams.bssid, ETH_ALEN);
1557 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
1558 wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL);
1559
1560 lbs_deb_join("ADHOC_RESP: - Joined/Started Ad Hoc\n");
1561 lbs_deb_join("ADHOC_RESP: channel = %d\n", priv->curbssparams.channel);
1562 lbs_deb_join("ADHOC_RESP: BSSID = %s\n",
1563 print_mac(mac, padhocresult->bssid));
1564
1565done:
1566 lbs_deb_leave_args(LBS_DEB_JOIN, "ret %d", ret);
1567 return ret;
1568}
1569
1570int lbs_ret_80211_ad_hoc_stop(struct lbs_private *priv)
1571{
1572 lbs_deb_enter(LBS_DEB_JOIN);
1573
1574 lbs_mac_event_disconnected(priv);
1575
1576 lbs_deb_leave(LBS_DEB_JOIN);
1577 return 0;
1578}
diff --git a/drivers/net/wireless/libertas/assoc.h b/drivers/net/wireless/libertas/assoc.h
index d489cf4cc1e2..c516fbe518fd 100644
--- a/drivers/net/wireless/libertas/assoc.h
+++ b/drivers/net/wireless/libertas/assoc.h
@@ -8,4 +8,32 @@
8void lbs_association_worker(struct work_struct *work); 8void lbs_association_worker(struct work_struct *work);
9struct assoc_request *lbs_get_association_request(struct lbs_private *priv); 9struct assoc_request *lbs_get_association_request(struct lbs_private *priv);
10 10
11struct cmd_ds_command;
12int lbs_cmd_80211_authenticate(struct lbs_private *priv,
13 struct cmd_ds_command *cmd,
14 void *pdata_buf);
15int lbs_cmd_80211_ad_hoc_join(struct lbs_private *priv,
16 struct cmd_ds_command *cmd,
17 void *pdata_buf);
18int lbs_cmd_80211_ad_hoc_stop(struct cmd_ds_command *cmd);
19int lbs_cmd_80211_ad_hoc_start(struct lbs_private *priv,
20 struct cmd_ds_command *cmd,
21 void *pdata_buf);
22int lbs_cmd_80211_deauthenticate(struct lbs_private *priv,
23 struct cmd_ds_command *cmd);
24int lbs_cmd_80211_associate(struct lbs_private *priv,
25 struct cmd_ds_command *cmd,
26 void *pdata_buf);
27
28int lbs_ret_80211_ad_hoc_start(struct lbs_private *priv,
29 struct cmd_ds_command *resp);
30int lbs_ret_80211_ad_hoc_stop(struct lbs_private *priv);
31int lbs_ret_80211_disassociate(struct lbs_private *priv);
32int lbs_ret_80211_associate(struct lbs_private *priv,
33 struct cmd_ds_command *resp);
34
35int lbs_stop_adhoc_network(struct lbs_private *priv);
36
37int lbs_send_deauthentication(struct lbs_private *priv);
38
11#endif /* _LBS_ASSOC_H */ 39#endif /* _LBS_ASSOC_H */
diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c
index dbaf8b9e47d5..4e6d01948372 100644
--- a/drivers/net/wireless/libertas/cmd.c
+++ b/drivers/net/wireless/libertas/cmd.c
@@ -9,7 +9,7 @@
9#include "decl.h" 9#include "decl.h"
10#include "defs.h" 10#include "defs.h"
11#include "dev.h" 11#include "dev.h"
12#include "join.h" 12#include "assoc.h"
13#include "wext.h" 13#include "wext.h"
14#include "cmd.h" 14#include "cmd.h"
15 15
diff --git a/drivers/net/wireless/libertas/cmdresp.c b/drivers/net/wireless/libertas/cmdresp.c
index e60d03bf8d11..245d3c3a9274 100644
--- a/drivers/net/wireless/libertas/cmdresp.c
+++ b/drivers/net/wireless/libertas/cmdresp.c
@@ -12,7 +12,7 @@
12#include "decl.h" 12#include "decl.h"
13#include "defs.h" 13#include "defs.h"
14#include "dev.h" 14#include "dev.h"
15#include "join.h" 15#include "assoc.h"
16#include "wext.h" 16#include "wext.h"
17 17
18/** 18/**
diff --git a/drivers/net/wireless/libertas/ethtool.c b/drivers/net/wireless/libertas/ethtool.c
index 7c8ce7d0f23a..be226c1885a9 100644
--- a/drivers/net/wireless/libertas/ethtool.c
+++ b/drivers/net/wireless/libertas/ethtool.c
@@ -6,7 +6,6 @@
6#include "decl.h" 6#include "decl.h"
7#include "defs.h" 7#include "defs.h"
8#include "dev.h" 8#include "dev.h"
9#include "join.h"
10#include "wext.h" 9#include "wext.h"
11#include "cmd.h" 10#include "cmd.h"
12 11
diff --git a/drivers/net/wireless/libertas/join.c b/drivers/net/wireless/libertas/join.c
deleted file mode 100644
index 3e5026ff2ffa..000000000000
--- a/drivers/net/wireless/libertas/join.c
+++ /dev/null
@@ -1,872 +0,0 @@
1/**
2 * Functions implementing wlan infrastructure and adhoc join routines,
3 * IOCTL handlers as well as command preperation and response routines
4 * for sending adhoc start, adhoc join, and association commands
5 * to the firmware.
6 */
7#include <linux/netdevice.h>
8#include <linux/if_arp.h>
9#include <linux/wireless.h>
10#include <linux/etherdevice.h>
11
12#include <net/iw_handler.h>
13
14#include "host.h"
15#include "decl.h"
16#include "join.h"
17#include "dev.h"
18#include "assoc.h"
19
20/* The firmware needs certain bits masked out of the beacon-derviced capability
21 * field when associating/joining to BSSs.
22 */
23#define CAPINFO_MASK (~(0xda00))
24
25/**
26 * @brief This function finds common rates between rate1 and card rates.
27 *
28 * It will fill common rates in rate1 as output if found.
29 *
30 * NOTE: Setting the MSB of the basic rates need to be taken
31 * care, either before or after calling this function
32 *
33 * @param priv A pointer to struct lbs_private structure
34 * @param rate1 the buffer which keeps input and output
35 * @param rate1_size the size of rate1 buffer; new size of buffer on return
36 *
37 * @return 0 or -1
38 */
39static int get_common_rates(struct lbs_private *priv,
40 u8 *rates,
41 u16 *rates_size)
42{
43 u8 *card_rates = lbs_bg_rates;
44 size_t num_card_rates = sizeof(lbs_bg_rates);
45 int ret = 0, i, j;
46 u8 tmp[30];
47 size_t tmp_size = 0;
48
49 /* For each rate in card_rates that exists in rate1, copy to tmp */
50 for (i = 0; card_rates[i] && (i < num_card_rates); i++) {
51 for (j = 0; rates[j] && (j < *rates_size); j++) {
52 if (rates[j] == card_rates[i])
53 tmp[tmp_size++] = card_rates[i];
54 }
55 }
56
57 lbs_deb_hex(LBS_DEB_JOIN, "AP rates ", rates, *rates_size);
58 lbs_deb_hex(LBS_DEB_JOIN, "card rates ", card_rates, num_card_rates);
59 lbs_deb_hex(LBS_DEB_JOIN, "common rates", tmp, tmp_size);
60 lbs_deb_join("TX data rate 0x%02x\n", priv->cur_rate);
61
62 if (!priv->auto_rate) {
63 for (i = 0; i < tmp_size; i++) {
64 if (tmp[i] == priv->cur_rate)
65 goto done;
66 }
67 lbs_pr_alert("Previously set fixed data rate %#x isn't "
68 "compatible with the network.\n", priv->cur_rate);
69 ret = -1;
70 goto done;
71 }
72 ret = 0;
73
74done:
75 memset(rates, 0, *rates_size);
76 *rates_size = min_t(int, tmp_size, *rates_size);
77 memcpy(rates, tmp, *rates_size);
78 return ret;
79}
80
81
82/**
83 * @brief Sets the MSB on basic rates as the firmware requires
84 *
85 * Scan through an array and set the MSB for basic data rates.
86 *
87 * @param rates buffer of data rates
88 * @param len size of buffer
89 */
90static void lbs_set_basic_rate_flags(u8 *rates, size_t len)
91{
92 int i;
93
94 for (i = 0; i < len; i++) {
95 if (rates[i] == 0x02 || rates[i] == 0x04 ||
96 rates[i] == 0x0b || rates[i] == 0x16)
97 rates[i] |= 0x80;
98 }
99}
100
101/**
102 * @brief Associate to a specific BSS discovered in a scan
103 *
104 * @param priv A pointer to struct lbs_private structure
105 * @param pbssdesc Pointer to the BSS descriptor to associate with.
106 *
107 * @return 0-success, otherwise fail
108 */
109int lbs_associate(struct lbs_private *priv, struct assoc_request *assoc_req)
110{
111 int ret;
112
113 lbs_deb_enter(LBS_DEB_ASSOC);
114
115 ret = lbs_prepare_and_send_command(priv, CMD_802_11_AUTHENTICATE,
116 0, CMD_OPTION_WAITFORRSP,
117 0, assoc_req->bss.bssid);
118
119 if (ret)
120 goto done;
121
122 /* set preamble to firmware */
123 if ( (priv->capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
124 && (assoc_req->bss.capability & WLAN_CAPABILITY_SHORT_PREAMBLE))
125 priv->preamble = CMD_TYPE_SHORT_PREAMBLE;
126 else
127 priv->preamble = CMD_TYPE_LONG_PREAMBLE;
128
129 lbs_set_radio_control(priv);
130
131 ret = lbs_prepare_and_send_command(priv, CMD_802_11_ASSOCIATE,
132 0, CMD_OPTION_WAITFORRSP, 0, assoc_req);
133
134done:
135 lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
136 return ret;
137}
138
139/**
140 * @brief Start an Adhoc Network
141 *
142 * @param priv A pointer to struct lbs_private structure
143 * @param adhocssid The ssid of the Adhoc Network
144 * @return 0--success, -1--fail
145 */
146int lbs_start_adhoc_network(struct lbs_private *priv,
147 struct assoc_request *assoc_req)
148{
149 int ret = 0;
150
151 priv->adhoccreate = 1;
152
153 if (priv->capability & WLAN_CAPABILITY_SHORT_PREAMBLE) {
154 lbs_deb_join("AdhocStart: Short preamble\n");
155 priv->preamble = CMD_TYPE_SHORT_PREAMBLE;
156 } else {
157 lbs_deb_join("AdhocStart: Long preamble\n");
158 priv->preamble = CMD_TYPE_LONG_PREAMBLE;
159 }
160
161 lbs_set_radio_control(priv);
162
163 lbs_deb_join("AdhocStart: channel = %d\n", assoc_req->channel);
164 lbs_deb_join("AdhocStart: band = %d\n", assoc_req->band);
165
166 ret = lbs_prepare_and_send_command(priv, CMD_802_11_AD_HOC_START,
167 0, CMD_OPTION_WAITFORRSP, 0, assoc_req);
168
169 return ret;
170}
171
172/**
173 * @brief Join an adhoc network found in a previous scan
174 *
175 * @param priv A pointer to struct lbs_private structure
176 * @param pbssdesc Pointer to a BSS descriptor found in a previous scan
177 * to attempt to join
178 *
179 * @return 0--success, -1--fail
180 */
181int lbs_join_adhoc_network(struct lbs_private *priv,
182 struct assoc_request *assoc_req)
183{
184 struct bss_descriptor * bss = &assoc_req->bss;
185 int ret = 0;
186
187 lbs_deb_join("%s: Current SSID '%s', ssid length %u\n",
188 __func__,
189 escape_essid(priv->curbssparams.ssid,
190 priv->curbssparams.ssid_len),
191 priv->curbssparams.ssid_len);
192 lbs_deb_join("%s: requested ssid '%s', ssid length %u\n",
193 __func__, escape_essid(bss->ssid, bss->ssid_len),
194 bss->ssid_len);
195
196 /* check if the requested SSID is already joined */
197 if ( priv->curbssparams.ssid_len
198 && !lbs_ssid_cmp(priv->curbssparams.ssid,
199 priv->curbssparams.ssid_len,
200 bss->ssid, bss->ssid_len)
201 && (priv->mode == IW_MODE_ADHOC)
202 && (priv->connect_status == LBS_CONNECTED)) {
203 union iwreq_data wrqu;
204
205 lbs_deb_join("ADHOC_J_CMD: New ad-hoc SSID is the same as "
206 "current, not attempting to re-join");
207
208 /* Send the re-association event though, because the association
209 * request really was successful, even if just a null-op.
210 */
211 memset(&wrqu, 0, sizeof(wrqu));
212 memcpy(wrqu.ap_addr.sa_data, priv->curbssparams.bssid,
213 ETH_ALEN);
214 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
215 wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL);
216 goto out;
217 }
218
219 /* Use shortpreamble only when both creator and card supports
220 short preamble */
221 if ( !(bss->capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
222 || !(priv->capability & WLAN_CAPABILITY_SHORT_PREAMBLE)) {
223 lbs_deb_join("AdhocJoin: Long preamble\n");
224 priv->preamble = CMD_TYPE_LONG_PREAMBLE;
225 } else {
226 lbs_deb_join("AdhocJoin: Short preamble\n");
227 priv->preamble = CMD_TYPE_SHORT_PREAMBLE;
228 }
229
230 lbs_set_radio_control(priv);
231
232 lbs_deb_join("AdhocJoin: channel = %d\n", assoc_req->channel);
233 lbs_deb_join("AdhocJoin: band = %c\n", assoc_req->band);
234
235 priv->adhoccreate = 0;
236
237 ret = lbs_prepare_and_send_command(priv, CMD_802_11_AD_HOC_JOIN,
238 0, CMD_OPTION_WAITFORRSP,
239 OID_802_11_SSID, assoc_req);
240
241out:
242 return ret;
243}
244
245int lbs_stop_adhoc_network(struct lbs_private *priv)
246{
247 return lbs_prepare_and_send_command(priv, CMD_802_11_AD_HOC_STOP,
248 0, CMD_OPTION_WAITFORRSP, 0, NULL);
249}
250
251/**
252 * @brief Send Deauthentication Request
253 *
254 * @param priv A pointer to struct lbs_private structure
255 * @return 0--success, -1--fail
256 */
257int lbs_send_deauthentication(struct lbs_private *priv)
258{
259 return lbs_prepare_and_send_command(priv, CMD_802_11_DEAUTHENTICATE,
260 0, CMD_OPTION_WAITFORRSP, 0, NULL);
261}
262
263/**
264 * @brief This function prepares command of authenticate.
265 *
266 * @param priv A pointer to struct lbs_private structure
267 * @param cmd A pointer to cmd_ds_command structure
268 * @param pdata_buf Void cast of pointer to a BSSID to authenticate with
269 *
270 * @return 0 or -1
271 */
272int lbs_cmd_80211_authenticate(struct lbs_private *priv,
273 struct cmd_ds_command *cmd,
274 void *pdata_buf)
275{
276 struct cmd_ds_802_11_authenticate *pauthenticate = &cmd->params.auth;
277 int ret = -1;
278 u8 *bssid = pdata_buf;
279 DECLARE_MAC_BUF(mac);
280
281 lbs_deb_enter(LBS_DEB_JOIN);
282
283 cmd->command = cpu_to_le16(CMD_802_11_AUTHENTICATE);
284 cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_authenticate)
285 + S_DS_GEN);
286
287 /* translate auth mode to 802.11 defined wire value */
288 switch (priv->secinfo.auth_mode) {
289 case IW_AUTH_ALG_OPEN_SYSTEM:
290 pauthenticate->authtype = 0x00;
291 break;
292 case IW_AUTH_ALG_SHARED_KEY:
293 pauthenticate->authtype = 0x01;
294 break;
295 case IW_AUTH_ALG_LEAP:
296 pauthenticate->authtype = 0x80;
297 break;
298 default:
299 lbs_deb_join("AUTH_CMD: invalid auth alg 0x%X\n",
300 priv->secinfo.auth_mode);
301 goto out;
302 }
303
304 memcpy(pauthenticate->macaddr, bssid, ETH_ALEN);
305
306 lbs_deb_join("AUTH_CMD: BSSID %s, auth 0x%x\n",
307 print_mac(mac, bssid), pauthenticate->authtype);
308 ret = 0;
309
310out:
311 lbs_deb_leave_args(LBS_DEB_JOIN, "ret %d", ret);
312 return ret;
313}
314
315int lbs_cmd_80211_deauthenticate(struct lbs_private *priv,
316 struct cmd_ds_command *cmd)
317{
318 struct cmd_ds_802_11_deauthenticate *dauth = &cmd->params.deauth;
319
320 lbs_deb_enter(LBS_DEB_JOIN);
321
322 cmd->command = cpu_to_le16(CMD_802_11_DEAUTHENTICATE);
323 cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_deauthenticate) +
324 S_DS_GEN);
325
326 /* set AP MAC address */
327 memmove(dauth->macaddr, priv->curbssparams.bssid, ETH_ALEN);
328
329 /* Reason code 3 = Station is leaving */
330#define REASON_CODE_STA_LEAVING 3
331 dauth->reasoncode = cpu_to_le16(REASON_CODE_STA_LEAVING);
332
333 lbs_deb_leave(LBS_DEB_JOIN);
334 return 0;
335}
336
337int lbs_cmd_80211_associate(struct lbs_private *priv,
338 struct cmd_ds_command *cmd, void *pdata_buf)
339{
340 struct cmd_ds_802_11_associate *passo = &cmd->params.associate;
341 int ret = 0;
342 struct assoc_request * assoc_req = pdata_buf;
343 struct bss_descriptor * bss = &assoc_req->bss;
344 u8 *pos;
345 u16 tmpcap, tmplen;
346 struct mrvlietypes_ssidparamset *ssid;
347 struct mrvlietypes_phyparamset *phy;
348 struct mrvlietypes_ssparamset *ss;
349 struct mrvlietypes_ratesparamset *rates;
350 struct mrvlietypes_rsnparamset *rsn;
351
352 lbs_deb_enter(LBS_DEB_ASSOC);
353
354 pos = (u8 *) passo;
355
356 if (!priv) {
357 ret = -1;
358 goto done;
359 }
360
361 cmd->command = cpu_to_le16(CMD_802_11_ASSOCIATE);
362
363 memcpy(passo->peerstaaddr, bss->bssid, sizeof(passo->peerstaaddr));
364 pos += sizeof(passo->peerstaaddr);
365
366 /* set the listen interval */
367 passo->listeninterval = cpu_to_le16(MRVDRV_DEFAULT_LISTEN_INTERVAL);
368
369 pos += sizeof(passo->capability);
370 pos += sizeof(passo->listeninterval);
371 pos += sizeof(passo->bcnperiod);
372 pos += sizeof(passo->dtimperiod);
373
374 ssid = (struct mrvlietypes_ssidparamset *) pos;
375 ssid->header.type = cpu_to_le16(TLV_TYPE_SSID);
376 tmplen = bss->ssid_len;
377 ssid->header.len = cpu_to_le16(tmplen);
378 memcpy(ssid->ssid, bss->ssid, tmplen);
379 pos += sizeof(ssid->header) + tmplen;
380
381 phy = (struct mrvlietypes_phyparamset *) pos;
382 phy->header.type = cpu_to_le16(TLV_TYPE_PHY_DS);
383 tmplen = sizeof(phy->fh_ds.dsparamset);
384 phy->header.len = cpu_to_le16(tmplen);
385 memcpy(&phy->fh_ds.dsparamset,
386 &bss->phyparamset.dsparamset.currentchan,
387 tmplen);
388 pos += sizeof(phy->header) + tmplen;
389
390 ss = (struct mrvlietypes_ssparamset *) pos;
391 ss->header.type = cpu_to_le16(TLV_TYPE_CF);
392 tmplen = sizeof(ss->cf_ibss.cfparamset);
393 ss->header.len = cpu_to_le16(tmplen);
394 pos += sizeof(ss->header) + tmplen;
395
396 rates = (struct mrvlietypes_ratesparamset *) pos;
397 rates->header.type = cpu_to_le16(TLV_TYPE_RATES);
398 memcpy(&rates->rates, &bss->rates, MAX_RATES);
399 tmplen = MAX_RATES;
400 if (get_common_rates(priv, rates->rates, &tmplen)) {
401 ret = -1;
402 goto done;
403 }
404 pos += sizeof(rates->header) + tmplen;
405 rates->header.len = cpu_to_le16(tmplen);
406 lbs_deb_assoc("ASSOC_CMD: num rates %u\n", tmplen);
407
408 /* Copy the infra. association rates into Current BSS state structure */
409 memset(&priv->curbssparams.rates, 0, sizeof(priv->curbssparams.rates));
410 memcpy(&priv->curbssparams.rates, &rates->rates, tmplen);
411
412 /* Set MSB on basic rates as the firmware requires, but _after_
413 * copying to current bss rates.
414 */
415 lbs_set_basic_rate_flags(rates->rates, tmplen);
416
417 if (assoc_req->secinfo.WPAenabled || assoc_req->secinfo.WPA2enabled) {
418 rsn = (struct mrvlietypes_rsnparamset *) pos;
419 /* WPA_IE or WPA2_IE */
420 rsn->header.type = cpu_to_le16((u16) assoc_req->wpa_ie[0]);
421 tmplen = (u16) assoc_req->wpa_ie[1];
422 rsn->header.len = cpu_to_le16(tmplen);
423 memcpy(rsn->rsnie, &assoc_req->wpa_ie[2], tmplen);
424 lbs_deb_hex(LBS_DEB_JOIN, "ASSOC_CMD: RSN IE", (u8 *) rsn,
425 sizeof(rsn->header) + tmplen);
426 pos += sizeof(rsn->header) + tmplen;
427 }
428
429 /* update curbssparams */
430 priv->curbssparams.channel = bss->phyparamset.dsparamset.currentchan;
431
432 if (lbs_parse_dnld_countryinfo_11d(priv, bss)) {
433 ret = -1;
434 goto done;
435 }
436
437 cmd->size = cpu_to_le16((u16) (pos - (u8 *) passo) + S_DS_GEN);
438
439 /* set the capability info */
440 tmpcap = (bss->capability & CAPINFO_MASK);
441 if (bss->mode == IW_MODE_INFRA)
442 tmpcap |= WLAN_CAPABILITY_ESS;
443 passo->capability = cpu_to_le16(tmpcap);
444 lbs_deb_assoc("ASSOC_CMD: capability 0x%04x\n", tmpcap);
445
446done:
447 lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
448 return ret;
449}
450
451int lbs_cmd_80211_ad_hoc_start(struct lbs_private *priv,
452 struct cmd_ds_command *cmd, void *pdata_buf)
453{
454 struct cmd_ds_802_11_ad_hoc_start *adhs = &cmd->params.ads;
455 int ret = 0;
456 int cmdappendsize = 0;
457 struct assoc_request * assoc_req = pdata_buf;
458 u16 tmpcap = 0;
459 size_t ratesize = 0;
460
461 lbs_deb_enter(LBS_DEB_JOIN);
462
463 if (!priv) {
464 ret = -1;
465 goto done;
466 }
467
468 cmd->command = cpu_to_le16(CMD_802_11_AD_HOC_START);
469
470 /*
471 * Fill in the parameters for 2 data structures:
472 * 1. cmd_ds_802_11_ad_hoc_start command
473 * 2. priv->scantable[i]
474 *
475 * Driver will fill up SSID, bsstype,IBSS param, Physical Param,
476 * probe delay, and cap info.
477 *
478 * Firmware will fill up beacon period, DTIM, Basic rates
479 * and operational rates.
480 */
481
482 memset(adhs->ssid, 0, IW_ESSID_MAX_SIZE);
483 memcpy(adhs->ssid, assoc_req->ssid, assoc_req->ssid_len);
484
485 lbs_deb_join("ADHOC_S_CMD: SSID '%s', ssid length %u\n",
486 escape_essid(assoc_req->ssid, assoc_req->ssid_len),
487 assoc_req->ssid_len);
488
489 /* set the BSS type */
490 adhs->bsstype = CMD_BSS_TYPE_IBSS;
491 priv->mode = IW_MODE_ADHOC;
492 if (priv->beacon_period == 0)
493 priv->beacon_period = MRVDRV_BEACON_INTERVAL;
494 adhs->beaconperiod = cpu_to_le16(priv->beacon_period);
495
496 /* set Physical param set */
497#define DS_PARA_IE_ID 3
498#define DS_PARA_IE_LEN 1
499
500 adhs->phyparamset.dsparamset.elementid = DS_PARA_IE_ID;
501 adhs->phyparamset.dsparamset.len = DS_PARA_IE_LEN;
502
503 WARN_ON(!assoc_req->channel);
504
505 lbs_deb_join("ADHOC_S_CMD: Creating ADHOC on channel %d\n",
506 assoc_req->channel);
507
508 adhs->phyparamset.dsparamset.currentchan = assoc_req->channel;
509
510 /* set IBSS param set */
511#define IBSS_PARA_IE_ID 6
512#define IBSS_PARA_IE_LEN 2
513
514 adhs->ssparamset.ibssparamset.elementid = IBSS_PARA_IE_ID;
515 adhs->ssparamset.ibssparamset.len = IBSS_PARA_IE_LEN;
516 adhs->ssparamset.ibssparamset.atimwindow = 0;
517
518 /* set capability info */
519 tmpcap = WLAN_CAPABILITY_IBSS;
520 if (assoc_req->secinfo.wep_enabled) {
521 lbs_deb_join("ADHOC_S_CMD: WEP enabled, setting privacy on\n");
522 tmpcap |= WLAN_CAPABILITY_PRIVACY;
523 } else {
524 lbs_deb_join("ADHOC_S_CMD: WEP disabled, setting privacy off\n");
525 }
526 adhs->capability = cpu_to_le16(tmpcap);
527
528 /* probedelay */
529 adhs->probedelay = cpu_to_le16(CMD_SCAN_PROBE_DELAY_TIME);
530
531 memset(adhs->rates, 0, sizeof(adhs->rates));
532 ratesize = min(sizeof(adhs->rates), sizeof(lbs_bg_rates));
533 memcpy(adhs->rates, lbs_bg_rates, ratesize);
534
535 /* Copy the ad-hoc creating rates into Current BSS state structure */
536 memset(&priv->curbssparams.rates, 0, sizeof(priv->curbssparams.rates));
537 memcpy(&priv->curbssparams.rates, &adhs->rates, ratesize);
538
539 /* Set MSB on basic rates as the firmware requires, but _after_
540 * copying to current bss rates.
541 */
542 lbs_set_basic_rate_flags(adhs->rates, ratesize);
543
544 lbs_deb_join("ADHOC_S_CMD: rates=%02x %02x %02x %02x \n",
545 adhs->rates[0], adhs->rates[1], adhs->rates[2], adhs->rates[3]);
546
547 lbs_deb_join("ADHOC_S_CMD: AD HOC Start command is ready\n");
548
549 if (lbs_create_dnld_countryinfo_11d(priv)) {
550 lbs_deb_join("ADHOC_S_CMD: dnld_countryinfo_11d failed\n");
551 ret = -1;
552 goto done;
553 }
554
555 cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_ad_hoc_start) +
556 S_DS_GEN + cmdappendsize);
557
558 ret = 0;
559done:
560 lbs_deb_leave_args(LBS_DEB_JOIN, "ret %d", ret);
561 return ret;
562}
563
564int lbs_cmd_80211_ad_hoc_stop(struct cmd_ds_command *cmd)
565{
566 cmd->command = cpu_to_le16(CMD_802_11_AD_HOC_STOP);
567 cmd->size = cpu_to_le16(S_DS_GEN);
568
569 return 0;
570}
571
572int lbs_cmd_80211_ad_hoc_join(struct lbs_private *priv,
573 struct cmd_ds_command *cmd, void *pdata_buf)
574{
575 struct cmd_ds_802_11_ad_hoc_join *join_cmd = &cmd->params.adj;
576 struct assoc_request * assoc_req = pdata_buf;
577 struct bss_descriptor *bss = &assoc_req->bss;
578 int cmdappendsize = 0;
579 int ret = 0;
580 u16 ratesize = 0;
581 DECLARE_MAC_BUF(mac);
582
583 lbs_deb_enter(LBS_DEB_JOIN);
584
585 cmd->command = cpu_to_le16(CMD_802_11_AD_HOC_JOIN);
586
587 join_cmd->bss.type = CMD_BSS_TYPE_IBSS;
588 join_cmd->bss.beaconperiod = cpu_to_le16(bss->beaconperiod);
589
590 memcpy(&join_cmd->bss.bssid, &bss->bssid, ETH_ALEN);
591 memcpy(&join_cmd->bss.ssid, &bss->ssid, bss->ssid_len);
592
593 memcpy(&join_cmd->bss.phyparamset, &bss->phyparamset,
594 sizeof(union ieeetypes_phyparamset));
595
596 memcpy(&join_cmd->bss.ssparamset, &bss->ssparamset,
597 sizeof(union IEEEtypes_ssparamset));
598
599 join_cmd->bss.capability = cpu_to_le16(bss->capability & CAPINFO_MASK);
600 lbs_deb_join("ADHOC_J_CMD: tmpcap=%4X CAPINFO_MASK=%4X\n",
601 bss->capability, CAPINFO_MASK);
602
603 /* information on BSSID descriptor passed to FW */
604 lbs_deb_join(
605 "ADHOC_J_CMD: BSSID = %s, SSID = '%s'\n",
606 print_mac(mac, join_cmd->bss.bssid),
607 join_cmd->bss.ssid);
608
609 /* failtimeout */
610 join_cmd->failtimeout = cpu_to_le16(MRVDRV_ASSOCIATION_TIME_OUT);
611
612 /* probedelay */
613 join_cmd->probedelay = cpu_to_le16(CMD_SCAN_PROBE_DELAY_TIME);
614
615 priv->curbssparams.channel = bss->channel;
616
617 /* Copy Data rates from the rates recorded in scan response */
618 memset(join_cmd->bss.rates, 0, sizeof(join_cmd->bss.rates));
619 ratesize = min_t(u16, sizeof(join_cmd->bss.rates), MAX_RATES);
620 memcpy(join_cmd->bss.rates, bss->rates, ratesize);
621 if (get_common_rates(priv, join_cmd->bss.rates, &ratesize)) {
622 lbs_deb_join("ADHOC_J_CMD: get_common_rates returns error.\n");
623 ret = -1;
624 goto done;
625 }
626
627 /* Copy the ad-hoc creating rates into Current BSS state structure */
628 memset(&priv->curbssparams.rates, 0, sizeof(priv->curbssparams.rates));
629 memcpy(&priv->curbssparams.rates, join_cmd->bss.rates, ratesize);
630
631 /* Set MSB on basic rates as the firmware requires, but _after_
632 * copying to current bss rates.
633 */
634 lbs_set_basic_rate_flags(join_cmd->bss.rates, ratesize);
635
636 join_cmd->bss.ssparamset.ibssparamset.atimwindow =
637 cpu_to_le16(bss->atimwindow);
638
639 if (assoc_req->secinfo.wep_enabled) {
640 u16 tmp = le16_to_cpu(join_cmd->bss.capability);
641 tmp |= WLAN_CAPABILITY_PRIVACY;
642 join_cmd->bss.capability = cpu_to_le16(tmp);
643 }
644
645 if (priv->psmode == LBS802_11POWERMODEMAX_PSP) {
646 /* wake up first */
647 __le32 Localpsmode;
648
649 Localpsmode = cpu_to_le32(LBS802_11POWERMODECAM);
650 ret = lbs_prepare_and_send_command(priv,
651 CMD_802_11_PS_MODE,
652 CMD_ACT_SET,
653 0, 0, &Localpsmode);
654
655 if (ret) {
656 ret = -1;
657 goto done;
658 }
659 }
660
661 if (lbs_parse_dnld_countryinfo_11d(priv, bss)) {
662 ret = -1;
663 goto done;
664 }
665
666 cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_ad_hoc_join) +
667 S_DS_GEN + cmdappendsize);
668
669done:
670 lbs_deb_leave_args(LBS_DEB_JOIN, "ret %d", ret);
671 return ret;
672}
673
674int lbs_ret_80211_associate(struct lbs_private *priv,
675 struct cmd_ds_command *resp)
676{
677 int ret = 0;
678 union iwreq_data wrqu;
679 struct ieeetypes_assocrsp *passocrsp;
680 struct bss_descriptor * bss;
681 u16 status_code;
682
683 lbs_deb_enter(LBS_DEB_ASSOC);
684
685 if (!priv->in_progress_assoc_req) {
686 lbs_deb_assoc("ASSOC_RESP: no in-progress assoc request\n");
687 ret = -1;
688 goto done;
689 }
690 bss = &priv->in_progress_assoc_req->bss;
691
692 passocrsp = (struct ieeetypes_assocrsp *) & resp->params;
693
694 /*
695 * Older FW versions map the IEEE 802.11 Status Code in the association
696 * response to the following values returned in passocrsp->statuscode:
697 *
698 * IEEE Status Code Marvell Status Code
699 * 0 -> 0x0000 ASSOC_RESULT_SUCCESS
700 * 13 -> 0x0004 ASSOC_RESULT_AUTH_REFUSED
701 * 14 -> 0x0004 ASSOC_RESULT_AUTH_REFUSED
702 * 15 -> 0x0004 ASSOC_RESULT_AUTH_REFUSED
703 * 16 -> 0x0004 ASSOC_RESULT_AUTH_REFUSED
704 * others -> 0x0003 ASSOC_RESULT_REFUSED
705 *
706 * Other response codes:
707 * 0x0001 -> ASSOC_RESULT_INVALID_PARAMETERS (unused)
708 * 0x0002 -> ASSOC_RESULT_TIMEOUT (internal timer expired waiting for
709 * association response from the AP)
710 */
711
712 status_code = le16_to_cpu(passocrsp->statuscode);
713 switch (status_code) {
714 case 0x00:
715 break;
716 case 0x01:
717 lbs_deb_assoc("ASSOC_RESP: invalid parameters\n");
718 break;
719 case 0x02:
720 lbs_deb_assoc("ASSOC_RESP: internal timer "
721 "expired while waiting for the AP\n");
722 break;
723 case 0x03:
724 lbs_deb_assoc("ASSOC_RESP: association "
725 "refused by AP\n");
726 break;
727 case 0x04:
728 lbs_deb_assoc("ASSOC_RESP: authentication "
729 "refused by AP\n");
730 break;
731 default:
732 lbs_deb_assoc("ASSOC_RESP: failure reason 0x%02x "
733 " unknown\n", status_code);
734 break;
735 }
736
737 if (status_code) {
738 lbs_mac_event_disconnected(priv);
739 ret = -1;
740 goto done;
741 }
742
743 lbs_deb_hex(LBS_DEB_ASSOC, "ASSOC_RESP", (void *)&resp->params,
744 le16_to_cpu(resp->size) - S_DS_GEN);
745
746 /* Send a Media Connected event, according to the Spec */
747 priv->connect_status = LBS_CONNECTED;
748
749 /* Update current SSID and BSSID */
750 memcpy(&priv->curbssparams.ssid, &bss->ssid, IW_ESSID_MAX_SIZE);
751 priv->curbssparams.ssid_len = bss->ssid_len;
752 memcpy(priv->curbssparams.bssid, bss->bssid, ETH_ALEN);
753
754 priv->SNR[TYPE_RXPD][TYPE_AVG] = 0;
755 priv->NF[TYPE_RXPD][TYPE_AVG] = 0;
756
757 memset(priv->rawSNR, 0x00, sizeof(priv->rawSNR));
758 memset(priv->rawNF, 0x00, sizeof(priv->rawNF));
759 priv->nextSNRNF = 0;
760 priv->numSNRNF = 0;
761
762 netif_carrier_on(priv->dev);
763 if (!priv->tx_pending_len)
764 netif_wake_queue(priv->dev);
765
766 memcpy(wrqu.ap_addr.sa_data, priv->curbssparams.bssid, ETH_ALEN);
767 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
768 wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL);
769
770done:
771 lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
772 return ret;
773}
774
775int lbs_ret_80211_disassociate(struct lbs_private *priv)
776{
777 lbs_deb_enter(LBS_DEB_JOIN);
778
779 lbs_mac_event_disconnected(priv);
780
781 lbs_deb_leave(LBS_DEB_JOIN);
782 return 0;
783}
784
785int lbs_ret_80211_ad_hoc_start(struct lbs_private *priv,
786 struct cmd_ds_command *resp)
787{
788 int ret = 0;
789 u16 command = le16_to_cpu(resp->command);
790 u16 result = le16_to_cpu(resp->result);
791 struct cmd_ds_802_11_ad_hoc_result *padhocresult;
792 union iwreq_data wrqu;
793 struct bss_descriptor *bss;
794 DECLARE_MAC_BUF(mac);
795
796 lbs_deb_enter(LBS_DEB_JOIN);
797
798 padhocresult = &resp->params.result;
799
800 lbs_deb_join("ADHOC_RESP: size = %d\n", le16_to_cpu(resp->size));
801 lbs_deb_join("ADHOC_RESP: command = %x\n", command);
802 lbs_deb_join("ADHOC_RESP: result = %x\n", result);
803
804 if (!priv->in_progress_assoc_req) {
805 lbs_deb_join("ADHOC_RESP: no in-progress association request\n");
806 ret = -1;
807 goto done;
808 }
809 bss = &priv->in_progress_assoc_req->bss;
810
811 /*
812 * Join result code 0 --> SUCCESS
813 */
814 if (result) {
815 lbs_deb_join("ADHOC_RESP: failed\n");
816 if (priv->connect_status == LBS_CONNECTED) {
817 lbs_mac_event_disconnected(priv);
818 }
819 ret = -1;
820 goto done;
821 }
822
823 /*
824 * Now the join cmd should be successful
825 * If BSSID has changed use SSID to compare instead of BSSID
826 */
827 lbs_deb_join("ADHOC_RESP: associated to '%s'\n",
828 escape_essid(bss->ssid, bss->ssid_len));
829
830 /* Send a Media Connected event, according to the Spec */
831 priv->connect_status = LBS_CONNECTED;
832
833 if (command == CMD_RET(CMD_802_11_AD_HOC_START)) {
834 /* Update the created network descriptor with the new BSSID */
835 memcpy(bss->bssid, padhocresult->bssid, ETH_ALEN);
836 }
837
838 /* Set the BSSID from the joined/started descriptor */
839 memcpy(&priv->curbssparams.bssid, bss->bssid, ETH_ALEN);
840
841 /* Set the new SSID to current SSID */
842 memcpy(&priv->curbssparams.ssid, &bss->ssid, IW_ESSID_MAX_SIZE);
843 priv->curbssparams.ssid_len = bss->ssid_len;
844
845 netif_carrier_on(priv->dev);
846 if (!priv->tx_pending_len)
847 netif_wake_queue(priv->dev);
848
849 memset(&wrqu, 0, sizeof(wrqu));
850 memcpy(wrqu.ap_addr.sa_data, priv->curbssparams.bssid, ETH_ALEN);
851 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
852 wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL);
853
854 lbs_deb_join("ADHOC_RESP: - Joined/Started Ad Hoc\n");
855 lbs_deb_join("ADHOC_RESP: channel = %d\n", priv->curbssparams.channel);
856 lbs_deb_join("ADHOC_RESP: BSSID = %s\n",
857 print_mac(mac, padhocresult->bssid));
858
859done:
860 lbs_deb_leave_args(LBS_DEB_JOIN, "ret %d", ret);
861 return ret;
862}
863
864int lbs_ret_80211_ad_hoc_stop(struct lbs_private *priv)
865{
866 lbs_deb_enter(LBS_DEB_JOIN);
867
868 lbs_mac_event_disconnected(priv);
869
870 lbs_deb_leave(LBS_DEB_JOIN);
871 return 0;
872}
diff --git a/drivers/net/wireless/libertas/join.h b/drivers/net/wireless/libertas/join.h
deleted file mode 100644
index bfc3a10a2f39..000000000000
--- a/drivers/net/wireless/libertas/join.h
+++ /dev/null
@@ -1,48 +0,0 @@
1/**
2 * Interface for the wlan infrastructure and adhoc join routines
3 *
4 * Driver interface functions and type declarations for the join module
5 * implemented in join.c. Process all start/join requests for
6 * both adhoc and infrastructure networks
7 */
8#ifndef _LBS_JOIN_H
9#define _LBS_JOIN_H
10
11#include "defs.h"
12#include "dev.h"
13
14struct cmd_ds_command;
15int lbs_cmd_80211_authenticate(struct lbs_private *priv,
16 struct cmd_ds_command *cmd,
17 void *pdata_buf);
18int lbs_cmd_80211_ad_hoc_join(struct lbs_private *priv,
19 struct cmd_ds_command *cmd,
20 void *pdata_buf);
21int lbs_cmd_80211_ad_hoc_stop(struct cmd_ds_command *cmd);
22int lbs_cmd_80211_ad_hoc_start(struct lbs_private *priv,
23 struct cmd_ds_command *cmd,
24 void *pdata_buf);
25int lbs_cmd_80211_deauthenticate(struct lbs_private *priv,
26 struct cmd_ds_command *cmd);
27int lbs_cmd_80211_associate(struct lbs_private *priv,
28 struct cmd_ds_command *cmd,
29 void *pdata_buf);
30
31int lbs_ret_80211_ad_hoc_start(struct lbs_private *priv,
32 struct cmd_ds_command *resp);
33int lbs_ret_80211_ad_hoc_stop(struct lbs_private *priv);
34int lbs_ret_80211_disassociate(struct lbs_private *priv);
35int lbs_ret_80211_associate(struct lbs_private *priv,
36 struct cmd_ds_command *resp);
37
38int lbs_start_adhoc_network(struct lbs_private *priv,
39 struct assoc_request * assoc_req);
40int lbs_join_adhoc_network(struct lbs_private *priv,
41 struct assoc_request * assoc_req);
42int lbs_stop_adhoc_network(struct lbs_private *priv);
43
44int lbs_send_deauthentication(struct lbs_private *priv);
45
46int lbs_associate(struct lbs_private *priv, struct assoc_request *assoc_req);
47
48#endif
diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c
index 6c2af176da20..15c9cc8bab48 100644
--- a/drivers/net/wireless/libertas/main.c
+++ b/drivers/net/wireless/libertas/main.c
@@ -20,7 +20,6 @@
20#include "wext.h" 20#include "wext.h"
21#include "debugfs.h" 21#include "debugfs.h"
22#include "assoc.h" 22#include "assoc.h"
23#include "join.h"
24#include "cmd.h" 23#include "cmd.h"
25 24
26#define DRIVER_RELEASE_VERSION "323.p0" 25#define DRIVER_RELEASE_VERSION "323.p0"
diff --git a/drivers/net/wireless/libertas/scan.c b/drivers/net/wireless/libertas/scan.c
index 3825b7979fc4..1c7003d7de43 100644
--- a/drivers/net/wireless/libertas/scan.c
+++ b/drivers/net/wireless/libertas/scan.c
@@ -19,7 +19,7 @@
19#include "decl.h" 19#include "decl.h"
20#include "dev.h" 20#include "dev.h"
21#include "scan.h" 21#include "scan.h"
22#include "join.h" 22#include "assoc.h"
23#include "cmd.h" 23#include "cmd.h"
24 24
25//! Approximate amount of data needed to pass a scan result back to iwlist 25//! Approximate amount of data needed to pass a scan result back to iwlist
diff --git a/drivers/net/wireless/libertas/wext.c b/drivers/net/wireless/libertas/wext.c
index 738142e802d4..375072130221 100644
--- a/drivers/net/wireless/libertas/wext.c
+++ b/drivers/net/wireless/libertas/wext.c
@@ -16,7 +16,6 @@
16#include "decl.h" 16#include "decl.h"
17#include "defs.h" 17#include "defs.h"
18#include "dev.h" 18#include "dev.h"
19#include "join.h"
20#include "wext.h" 19#include "wext.h"
21#include "assoc.h" 20#include "assoc.h"
22#include "cmd.h" 21#include "cmd.h"