aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorDavid Woodhouse <dwmw2@infradead.org>2007-12-12 23:29:13 -0500
committerDavid S. Miller <davem@davemloft.net>2008-01-28 18:07:06 -0500
commit020f3d0001cb249ceae623c1a7ae0c196326ef3f (patch)
tree7d0c7c534b3e42bf882d169b3758e100fd672f6d /drivers/net
parent9f4625776f96e26b15d98615337ea5916648b1e8 (diff)
libertas: cope with both old and new mesh TLV values
Signed-off-by: David Woodhouse <dwmw2@infradead.org> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/wireless/libertas/cmd.c6
-rw-r--r--drivers/net/wireless/libertas/dev.h2
-rw-r--r--drivers/net/wireless/libertas/main.c32
3 files changed, 34 insertions, 6 deletions
diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c
index ddf15271244f..c4299ae1774e 100644
--- a/drivers/net/wireless/libertas/cmd.c
+++ b/drivers/net/wireless/libertas/cmd.c
@@ -1121,14 +1121,14 @@ int lbs_mesh_config(struct lbs_private *priv, int enable)
1121 memset(&cmd, 0, sizeof(cmd)); 1121 memset(&cmd, 0, sizeof(cmd));
1122 cmd.action = cpu_to_le16(enable); 1122 cmd.action = cpu_to_le16(enable);
1123 cmd.channel = cpu_to_le16(priv->curbssparams.channel); 1123 cmd.channel = cpu_to_le16(priv->curbssparams.channel);
1124 cmd.type = cpu_to_le16(0x100 + 37); 1124 cmd.type = cpu_to_le16(priv->mesh_tlv);
1125 1125
1126 if (enable) { 1126 if (enable) {
1127 cmd.length = cpu_to_le16(priv->mesh_ssid_len); 1127 cmd.length = cpu_to_le16(priv->mesh_ssid_len);
1128 memcpy(cmd.data, priv->mesh_ssid, priv->mesh_ssid_len); 1128 memcpy(cmd.data, priv->mesh_ssid, priv->mesh_ssid_len);
1129 } 1129 }
1130 lbs_deb_cmd("mesh config channel %d SSID %s\n", 1130 lbs_deb_cmd("mesh config enable %d TLV %x channel %d SSID %s\n",
1131 priv->curbssparams.channel, 1131 enable, priv->mesh_tlv, priv->curbssparams.channel,
1132 escape_essid(priv->mesh_ssid, priv->mesh_ssid_len)); 1132 escape_essid(priv->mesh_ssid, priv->mesh_ssid_len));
1133 return lbs_cmd_with_response(priv, CMD_MESH_CONFIG, &cmd); 1133 return lbs_cmd_with_response(priv, CMD_MESH_CONFIG, &cmd);
1134} 1134}
diff --git a/drivers/net/wireless/libertas/dev.h b/drivers/net/wireless/libertas/dev.h
index 60a6a51d0dcb..e6f553d5d2cf 100644
--- a/drivers/net/wireless/libertas/dev.h
+++ b/drivers/net/wireless/libertas/dev.h
@@ -206,6 +206,8 @@ struct lbs_private {
206 206
207 /** current ssid/bssid related parameters*/ 207 /** current ssid/bssid related parameters*/
208 struct current_bss_params curbssparams; 208 struct current_bss_params curbssparams;
209
210 uint16_t mesh_tlv;
209 u8 mesh_ssid[IW_ESSID_MAX_SIZE + 1]; 211 u8 mesh_ssid[IW_ESSID_MAX_SIZE + 1];
210 u8 mesh_ssid_len; 212 u8 mesh_ssid_len;
211 213
diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c
index 5e2f3296be34..2409df85c2e0 100644
--- a/drivers/net/wireless/libertas/main.c
+++ b/drivers/net/wireless/libertas/main.c
@@ -1171,8 +1171,33 @@ int lbs_start_card(struct lbs_private *priv)
1171 } 1171 }
1172 if (device_create_file(&dev->dev, &dev_attr_lbs_rtap)) 1172 if (device_create_file(&dev->dev, &dev_attr_lbs_rtap))
1173 lbs_pr_err("cannot register lbs_rtap attribute\n"); 1173 lbs_pr_err("cannot register lbs_rtap attribute\n");
1174 if (device_create_file(&dev->dev, &dev_attr_lbs_mesh)) 1174
1175 lbs_pr_err("cannot register lbs_mesh attribute\n"); 1175 /* Enable mesh, if supported, and work out which TLV it uses.
1176 0x100 + 291 is an unofficial value used in 5.110.20.pXX
1177 0x100 + 37 is the official value used in 5.110.21.pXX
1178 but we check them in that order because 20.pXX doesn't
1179 give an error -- it just silently fails. */
1180
1181 /* 5.110.20.pXX firmware will fail the command if the channel
1182 doesn't match the existing channel. But only if the TLV
1183 is correct. If the channel is wrong, _BOTH_ versions will
1184 give an error to 0x100+291, and allow 0x100+37 to succeed.
1185 It's just that 5.110.20.pXX will not have done anything
1186 useful */
1187
1188 lbs_update_channel(priv);
1189 priv->mesh_tlv = 0x100 + 291;
1190 if (lbs_mesh_config(priv, 1)) {
1191 priv->mesh_tlv = 0x100 + 37;
1192 if (lbs_mesh_config(priv, 1))
1193 priv->mesh_tlv = 0;
1194 }
1195 if (priv->mesh_tlv) {
1196 lbs_add_mesh(priv);
1197
1198 if (device_create_file(&dev->dev, &dev_attr_lbs_mesh))
1199 lbs_pr_err("cannot register lbs_mesh attribute\n");
1200 }
1176 1201
1177 lbs_debugfs_init_one(priv, dev); 1202 lbs_debugfs_init_one(priv, dev);
1178 1203
@@ -1201,7 +1226,8 @@ int lbs_stop_card(struct lbs_private *priv)
1201 1226
1202 lbs_debugfs_remove_one(priv); 1227 lbs_debugfs_remove_one(priv);
1203 device_remove_file(&dev->dev, &dev_attr_lbs_rtap); 1228 device_remove_file(&dev->dev, &dev_attr_lbs_rtap);
1204 device_remove_file(&dev->dev, &dev_attr_lbs_mesh); 1229 if (priv->mesh_tlv)
1230 device_remove_file(&dev->dev, &dev_attr_lbs_mesh);
1205 1231
1206 /* Flush pending command nodes */ 1232 /* Flush pending command nodes */
1207 spin_lock_irqsave(&priv->driver_lock, flags); 1233 spin_lock_irqsave(&priv->driver_lock, flags);