aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorDavid Woodhouse <dwmw2@infradead.org>2007-12-11 18:56:42 -0500
committerDavid S. Miller <davem@davemloft.net>2008-01-28 18:06:53 -0500
commit23a397ac821ab0aa263bda47131bb0628e49101a (patch)
treea631b5bb2b89885519791b46f712b04407692d6a /drivers
parente7240acae372727aa8eb3a67ca7b189dd261136a (diff)
libertas: add lbs_mesh sysfs attribute for enabling mesh
Signed-off-by: David Woodhouse <dwmw2@infradead.org> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/wireless/libertas/cmd.c17
-rw-r--r--drivers/net/wireless/libertas/cmd.h2
-rw-r--r--drivers/net/wireless/libertas/decl.h2
-rw-r--r--drivers/net/wireless/libertas/dev.h2
-rw-r--r--drivers/net/wireless/libertas/host.h1
-rw-r--r--drivers/net/wireless/libertas/hostcmd.h12
-rw-r--r--drivers/net/wireless/libertas/if_usb.c6
-rw-r--r--drivers/net/wireless/libertas/main.c74
8 files changed, 99 insertions, 17 deletions
diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c
index 2228feccb249..01d23493b4eb 100644
--- a/drivers/net/wireless/libertas/cmd.c
+++ b/drivers/net/wireless/libertas/cmd.c
@@ -1093,6 +1093,23 @@ int lbs_mesh_access(struct lbs_private *priv, uint16_t cmd_action,
1093} 1093}
1094EXPORT_SYMBOL_GPL(lbs_mesh_access); 1094EXPORT_SYMBOL_GPL(lbs_mesh_access);
1095 1095
1096int lbs_mesh_config(struct lbs_private *priv, int enable)
1097{
1098 struct cmd_ds_mesh_config cmd;
1099
1100 memset(&cmd, 0, sizeof(cmd));
1101 cmd.action = cpu_to_le16(enable);
1102 cmd.channel = cpu_to_le16(priv->curbssparams.channel);
1103 cmd.type = cpu_to_le16(0x100 + 37);
1104
1105 if (enable) {
1106 cmd.length = cpu_to_le16(priv->mesh_ssid_len);
1107 memcpy(cmd.data, priv->mesh_ssid, priv->mesh_ssid_len);
1108 }
1109
1110 return lbs_cmd_with_response(priv, CMD_MESH_CONFIG, cmd);
1111}
1112
1096static int lbs_cmd_bcn_ctrl(struct lbs_private * priv, 1113static int lbs_cmd_bcn_ctrl(struct lbs_private * priv,
1097 struct cmd_ds_command *cmd, 1114 struct cmd_ds_command *cmd,
1098 u16 cmd_action) 1115 u16 cmd_action)
diff --git a/drivers/net/wireless/libertas/cmd.h b/drivers/net/wireless/libertas/cmd.h
index 5b02d73c8a0e..80714b51285a 100644
--- a/drivers/net/wireless/libertas/cmd.h
+++ b/drivers/net/wireless/libertas/cmd.h
@@ -33,4 +33,6 @@ int lbs_set_data_rate(struct lbs_private *priv, u8 rate);
33int lbs_get_channel(struct lbs_private *priv); 33int lbs_get_channel(struct lbs_private *priv);
34int lbs_set_channel(struct lbs_private *priv, u8 channel); 34int lbs_set_channel(struct lbs_private *priv, u8 channel);
35 35
36int lbs_mesh_config(struct lbs_private *priv, int enable);
37
36#endif /* _LBS_CMD_H */ 38#endif /* _LBS_CMD_H */
diff --git a/drivers/net/wireless/libertas/decl.h b/drivers/net/wireless/libertas/decl.h
index 33c8305b5c0e..9b0ef166185d 100644
--- a/drivers/net/wireless/libertas/decl.h
+++ b/drivers/net/wireless/libertas/decl.h
@@ -74,8 +74,6 @@ struct lbs_private *lbs_add_card(void *card, struct device *dmdev);
74int lbs_remove_card(struct lbs_private *priv); 74int lbs_remove_card(struct lbs_private *priv);
75int lbs_start_card(struct lbs_private *priv); 75int lbs_start_card(struct lbs_private *priv);
76int lbs_stop_card(struct lbs_private *priv); 76int lbs_stop_card(struct lbs_private *priv);
77int lbs_add_mesh(struct lbs_private *priv, struct device *dev);
78void lbs_remove_mesh(struct lbs_private *priv);
79int lbs_reset_device(struct lbs_private *priv); 77int lbs_reset_device(struct lbs_private *priv);
80void lbs_host_to_card_done(struct lbs_private *priv); 78void lbs_host_to_card_done(struct lbs_private *priv);
81 79
diff --git a/drivers/net/wireless/libertas/dev.h b/drivers/net/wireless/libertas/dev.h
index 9921d0cd6f1d..86b45a471fc6 100644
--- a/drivers/net/wireless/libertas/dev.h
+++ b/drivers/net/wireless/libertas/dev.h
@@ -201,6 +201,8 @@ struct lbs_private {
201 201
202 /** current ssid/bssid related parameters*/ 202 /** current ssid/bssid related parameters*/
203 struct current_bss_params curbssparams; 203 struct current_bss_params curbssparams;
204 u8 mesh_ssid[IW_ESSID_MAX_SIZE + 1];
205 u8 mesh_ssid_len;
204 206
205 /* IW_MODE_* */ 207 /* IW_MODE_* */
206 u8 mode; 208 u8 mode;
diff --git a/drivers/net/wireless/libertas/host.h b/drivers/net/wireless/libertas/host.h
index cc5f9bf6cf2f..fcd223807ba6 100644
--- a/drivers/net/wireless/libertas/host.h
+++ b/drivers/net/wireless/libertas/host.h
@@ -113,6 +113,7 @@
113#define CMD_802_11_MONITOR_MODE 0x0098 113#define CMD_802_11_MONITOR_MODE 0x0098
114 114
115#define CMD_MESH_ACCESS 0x009b 115#define CMD_MESH_ACCESS 0x009b
116#define CMD_MESH_CONFIG 0x00a3
116 117
117#define CMD_SET_BOOT2_VER 0x00a5 118#define CMD_SET_BOOT2_VER 0x00a5
118 119
diff --git a/drivers/net/wireless/libertas/hostcmd.h b/drivers/net/wireless/libertas/hostcmd.h
index 7acb65116678..aab5d64f32d8 100644
--- a/drivers/net/wireless/libertas/hostcmd.h
+++ b/drivers/net/wireless/libertas/hostcmd.h
@@ -626,6 +626,18 @@ struct cmd_ds_fwt_access {
626 u8 prec[ETH_ALEN]; 626 u8 prec[ETH_ALEN];
627} __attribute__ ((packed)); 627} __attribute__ ((packed));
628 628
629
630struct cmd_ds_mesh_config {
631 struct cmd_header hdr;
632
633 __le16 action;
634 __le16 channel;
635 __le16 type;
636 __le16 length;
637 u8 data[128]; /* last position reserved */
638} __attribute__ ((packed));
639
640
629struct cmd_ds_mesh_access { 641struct cmd_ds_mesh_access {
630 struct cmd_header hdr; 642 struct cmd_header hdr;
631 643
diff --git a/drivers/net/wireless/libertas/if_usb.c b/drivers/net/wireless/libertas/if_usb.c
index 7c57ff44ad01..351c7ea43184 100644
--- a/drivers/net/wireless/libertas/if_usb.c
+++ b/drivers/net/wireless/libertas/if_usb.c
@@ -232,9 +232,6 @@ static int if_usb_probe(struct usb_interface *intf,
232 cardp->priv = priv; 232 cardp->priv = priv;
233 cardp->priv->fw_ready = 1; 233 cardp->priv->fw_ready = 1;
234 234
235 if (lbs_add_mesh(priv, &udev->dev))
236 goto err_add_mesh;
237
238 cardp->eth_dev = priv->dev; 235 cardp->eth_dev = priv->dev;
239 236
240 priv->hw_host_to_card = if_usb_host_to_card; 237 priv->hw_host_to_card = if_usb_host_to_card;
@@ -255,8 +252,6 @@ static int if_usb_probe(struct usb_interface *intf,
255 return 0; 252 return 0;
256 253
257err_start_card: 254err_start_card:
258 lbs_remove_mesh(priv);
259err_add_mesh:
260 lbs_remove_card(priv); 255 lbs_remove_card(priv);
261err_prog_firmware: 256err_prog_firmware:
262 if_usb_reset_device(cardp); 257 if_usb_reset_device(cardp);
@@ -286,7 +281,6 @@ static void if_usb_disconnect(struct usb_interface *intf)
286 281
287 priv->surpriseremoved = 1; 282 priv->surpriseremoved = 1;
288 lbs_stop_card(priv); 283 lbs_stop_card(priv);
289 lbs_remove_mesh(priv);
290 lbs_remove_card(priv); 284 lbs_remove_card(priv);
291 } 285 }
292 286
diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c
index c51d3af131fd..fd76c46225d1 100644
--- a/drivers/net/wireless/libertas/main.c
+++ b/drivers/net/wireless/libertas/main.c
@@ -254,6 +254,9 @@ static ssize_t lbs_anycast_set(struct device *dev,
254 254
255static int lbs_add_rtap(struct lbs_private *priv); 255static int lbs_add_rtap(struct lbs_private *priv);
256static void lbs_remove_rtap(struct lbs_private *priv); 256static void lbs_remove_rtap(struct lbs_private *priv);
257static int lbs_add_mesh(struct lbs_private *priv);
258static void lbs_remove_mesh(struct lbs_private *priv);
259
257 260
258/** 261/**
259 * Get function for sysfs attribute rtap 262 * Get function for sysfs attribute rtap
@@ -312,11 +315,53 @@ static ssize_t lbs_rtap_set(struct device *dev,
312} 315}
313 316
314/** 317/**
315 * lbs_rtap attribute to be exported per mshX interface 318 * lbs_rtap attribute to be exported per ethX interface
316 * through sysfs (/sys/class/net/mshX/libertas-rtap) 319 * through sysfs (/sys/class/net/ethX/lbs_rtap)
317 */ 320 */
318static DEVICE_ATTR(lbs_rtap, 0644, lbs_rtap_get, 321static DEVICE_ATTR(lbs_rtap, 0644, lbs_rtap_get, lbs_rtap_set );
319 lbs_rtap_set ); 322
323/**
324 * Get function for sysfs attribute mesh
325 */
326static ssize_t lbs_mesh_get(struct device *dev,
327 struct device_attribute *attr, char * buf)
328{
329 struct lbs_private *priv = to_net_dev(dev)->priv;
330 return snprintf(buf, 5, "0x%X\n", !!priv->mesh_dev);
331}
332
333/**
334 * Set function for sysfs attribute mesh
335 */
336static ssize_t lbs_mesh_set(struct device *dev,
337 struct device_attribute *attr, const char * buf, size_t count)
338{
339 struct lbs_private *priv = to_net_dev(dev)->priv;
340 int enable;
341 int ret;
342
343 sscanf(buf, "%x", &enable);
344 enable = !!enable;
345 if (enable == !!priv->mesh_dev)
346 return count;
347
348 ret = lbs_mesh_config(priv, enable);
349 if (ret)
350 return ret;
351
352 if (enable)
353 lbs_add_mesh(priv);
354 else
355 lbs_remove_mesh(priv);
356
357 return count;
358}
359
360/**
361 * lbs_mesh attribute to be exported per ethX interface
362 * through sysfs (/sys/class/net/ethX/lbs_mesh)
363 */
364static DEVICE_ATTR(lbs_mesh, 0644, lbs_mesh_get, lbs_mesh_set);
320 365
321/** 366/**
322 * anycast_mask attribute to be exported per mshX interface 367 * anycast_mask attribute to be exported per mshX interface
@@ -867,7 +912,9 @@ static int lbs_setup_firmware(struct lbs_private *priv)
867 ret = lbs_mesh_access(priv, CMD_ACT_MESH_SET_AUTOSTART_ENABLED, 912 ret = lbs_mesh_access(priv, CMD_ACT_MESH_SET_AUTOSTART_ENABLED,
868 &mesh_access); 913 &mesh_access);
869 if (ret) { 914 if (ret) {
870 ret = -1; 915 printk("Mesh autostart set failed\n");
916 ret = 0;
917 //ret = -1;
871 goto done; 918 goto done;
872 } 919 }
873 priv->mesh_autostart_enabled = 0; 920 priv->mesh_autostart_enabled = 0;
@@ -1059,6 +1106,9 @@ struct lbs_private *lbs_add_card(void *card, struct device *dmdev)
1059 INIT_DELAYED_WORK(&priv->scan_work, lbs_scan_worker); 1106 INIT_DELAYED_WORK(&priv->scan_work, lbs_scan_worker);
1060 INIT_WORK(&priv->sync_channel, lbs_sync_channel); 1107 INIT_WORK(&priv->sync_channel, lbs_sync_channel);
1061 1108
1109 sprintf(priv->mesh_ssid, "mesh");
1110 priv->mesh_ssid_len = 4;
1111
1062 goto done; 1112 goto done;
1063 1113
1064err_init_adapter: 1114err_init_adapter:
@@ -1080,6 +1130,7 @@ int lbs_remove_card(struct lbs_private *priv)
1080 1130
1081 lbs_deb_enter(LBS_DEB_MAIN); 1131 lbs_deb_enter(LBS_DEB_MAIN);
1082 1132
1133 lbs_remove_mesh(priv);
1083 lbs_remove_rtap(priv); 1134 lbs_remove_rtap(priv);
1084 1135
1085 dev = priv->dev; 1136 dev = priv->dev;
@@ -1133,6 +1184,8 @@ int lbs_start_card(struct lbs_private *priv)
1133 } 1184 }
1134 if (device_create_file(&dev->dev, &dev_attr_lbs_rtap)) 1185 if (device_create_file(&dev->dev, &dev_attr_lbs_rtap))
1135 lbs_pr_err("cannot register lbs_rtap attribute\n"); 1186 lbs_pr_err("cannot register lbs_rtap attribute\n");
1187 if (device_create_file(&dev->dev, &dev_attr_lbs_mesh))
1188 lbs_pr_err("cannot register lbs_mesh attribute\n");
1136 1189
1137 lbs_debugfs_init_one(priv, dev); 1190 lbs_debugfs_init_one(priv, dev);
1138 1191
@@ -1161,6 +1214,7 @@ int lbs_stop_card(struct lbs_private *priv)
1161 1214
1162 lbs_debugfs_remove_one(priv); 1215 lbs_debugfs_remove_one(priv);
1163 device_remove_file(&dev->dev, &dev_attr_lbs_rtap); 1216 device_remove_file(&dev->dev, &dev_attr_lbs_rtap);
1217 device_remove_file(&dev->dev, &dev_attr_lbs_mesh);
1164 1218
1165 /* Flush pending command nodes */ 1219 /* Flush pending command nodes */
1166 spin_lock_irqsave(&priv->driver_lock, flags); 1220 spin_lock_irqsave(&priv->driver_lock, flags);
@@ -1184,7 +1238,7 @@ EXPORT_SYMBOL_GPL(lbs_stop_card);
1184 * @param priv A pointer to the struct lbs_private structure 1238 * @param priv A pointer to the struct lbs_private structure
1185 * @return 0 if successful, -X otherwise 1239 * @return 0 if successful, -X otherwise
1186 */ 1240 */
1187int lbs_add_mesh(struct lbs_private *priv, struct device *dev) 1241static int lbs_add_mesh(struct lbs_private *priv)
1188{ 1242{
1189 struct net_device *mesh_dev = NULL; 1243 struct net_device *mesh_dev = NULL;
1190 int ret = 0; 1244 int ret = 0;
@@ -1209,7 +1263,7 @@ int lbs_add_mesh(struct lbs_private *priv, struct device *dev)
1209 memcpy(mesh_dev->dev_addr, priv->dev->dev_addr, 1263 memcpy(mesh_dev->dev_addr, priv->dev->dev_addr,
1210 sizeof(priv->dev->dev_addr)); 1264 sizeof(priv->dev->dev_addr));
1211 1265
1212 SET_NETDEV_DEV(priv->mesh_dev, dev); 1266 SET_NETDEV_DEV(priv->mesh_dev, priv->dev->dev.parent);
1213 1267
1214#ifdef WIRELESS_EXT 1268#ifdef WIRELESS_EXT
1215 mesh_dev->wireless_handlers = (struct iw_handler_def *)&mesh_handler_def; 1269 mesh_dev->wireless_handlers = (struct iw_handler_def *)&mesh_handler_def;
@@ -1242,7 +1296,7 @@ done:
1242EXPORT_SYMBOL_GPL(lbs_add_mesh); 1296EXPORT_SYMBOL_GPL(lbs_add_mesh);
1243 1297
1244 1298
1245void lbs_remove_mesh(struct lbs_private *priv) 1299static void lbs_remove_mesh(struct lbs_private *priv)
1246{ 1300{
1247 struct net_device *mesh_dev; 1301 struct net_device *mesh_dev;
1248 1302
@@ -1252,6 +1306,8 @@ void lbs_remove_mesh(struct lbs_private *priv)
1252 goto out; 1306 goto out;
1253 1307
1254 mesh_dev = priv->mesh_dev; 1308 mesh_dev = priv->mesh_dev;
1309 if (!mesh_dev)
1310 goto out;
1255 1311
1256 netif_stop_queue(mesh_dev); 1312 netif_stop_queue(mesh_dev);
1257 netif_carrier_off(priv->mesh_dev); 1313 netif_carrier_off(priv->mesh_dev);
@@ -1259,7 +1315,7 @@ void lbs_remove_mesh(struct lbs_private *priv)
1259 sysfs_remove_group(&(mesh_dev->dev.kobj), &lbs_mesh_attr_group); 1315 sysfs_remove_group(&(mesh_dev->dev.kobj), &lbs_mesh_attr_group);
1260 unregister_netdev(mesh_dev); 1316 unregister_netdev(mesh_dev);
1261 1317
1262 priv->mesh_dev = NULL ; 1318 priv->mesh_dev = NULL;
1263 free_netdev(mesh_dev); 1319 free_netdev(mesh_dev);
1264 1320
1265out: 1321out: