aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/libertas/scan.c
diff options
context:
space:
mode:
authorDavid Woodhouse <dwmw2@infradead.org>2008-03-03 06:18:03 -0500
committerJohn W. Linville <linville@tuxdriver.com>2008-03-06 17:09:49 -0500
commitfa62f99cf80af9c65bfc0f731d780e03e3ce6ede (patch)
treea5f5130a54f1daf500247c529a4e059511e5a4b6 /drivers/net/wireless/libertas/scan.c
parentc5562e98332511c3e4d7f807ae4dd85f6db2a7e6 (diff)
libertas: convert 802_11_SCAN to a direct command
Signed-off-by: David Woodhouse <dwmw2@infradead.org> Acked-by: Dan Williams <dcbw@redhat.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/libertas/scan.c')
-rw-r--r--drivers/net/wireless/libertas/scan.c122
1 files changed, 41 insertions, 81 deletions
diff --git a/drivers/net/wireless/libertas/scan.c b/drivers/net/wireless/libertas/scan.c
index 7d4f3afa8cc5..9f9c7d9c8bd2 100644
--- a/drivers/net/wireless/libertas/scan.c
+++ b/drivers/net/wireless/libertas/scan.c
@@ -20,6 +20,7 @@
20#include "dev.h" 20#include "dev.h"
21#include "scan.h" 21#include "scan.h"
22#include "join.h" 22#include "join.h"
23#include "cmd.h"
23 24
24//! 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
25#define MAX_SCAN_CELL_SIZE (IW_EV_ADDR_LEN \ 26#define MAX_SCAN_CELL_SIZE (IW_EV_ADDR_LEN \
@@ -39,10 +40,9 @@
39//! Memory needed to store a max number/size SSID TLV for a firmware scan 40//! Memory needed to store a max number/size SSID TLV for a firmware scan
40#define SSID_TLV_MAX_SIZE (1 * sizeof(struct mrvlietypes_ssidparamset)) 41#define SSID_TLV_MAX_SIZE (1 * sizeof(struct mrvlietypes_ssidparamset))
41 42
42//! Maximum memory needed for a lbs_scan_cmd_config with all TLVs at max 43//! Maximum memory needed for a cmd_ds_802_11_scan with all TLVs at max
43#define MAX_SCAN_CFG_ALLOC (sizeof(struct lbs_scan_cmd_config) \ 44#define MAX_SCAN_CFG_ALLOC (sizeof(struct cmd_ds_802_11_scan) \
44 + CHAN_TLV_MAX_SIZE \ 45 + CHAN_TLV_MAX_SIZE + SSID_TLV_MAX_SIZE)
45 + SSID_TLV_MAX_SIZE)
46 46
47//! The maximum number of channels the firmware can scan per command 47//! The maximum number of channels the firmware can scan per command
48#define MRVDRV_MAX_CHANNELS_PER_SCAN 14 48#define MRVDRV_MAX_CHANNELS_PER_SCAN 14
@@ -64,8 +64,8 @@
64static const u8 zeromac[ETH_ALEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 64static const u8 zeromac[ETH_ALEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
65static const u8 bcastmac[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; 65static const u8 bcastmac[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
66 66
67 67static int lbs_ret_80211_scan(struct lbs_private *priv, unsigned long dummy,
68 68 struct cmd_header *resp);
69 69
70/*********************************************************************/ 70/*********************************************************************/
71/* */ 71/* */
@@ -492,24 +492,22 @@ static int lbs_scan_add_rates_tlv(u8 *tlv)
492 * Generate the CMD_802_11_SCAN command with the proper tlv 492 * Generate the CMD_802_11_SCAN command with the proper tlv
493 * for a bunch of channels. 493 * for a bunch of channels.
494 */ 494 */
495static int lbs_do_scan(struct lbs_private *priv, 495static int lbs_do_scan(struct lbs_private *priv, uint8_t bsstype,
496 u8 bsstype, 496 struct chanscanparamset *chan_list, int chan_count,
497 struct chanscanparamset *chan_list, 497 const struct lbs_ioctl_user_scan_cfg *user_cfg)
498 int chan_count,
499 const struct lbs_ioctl_user_scan_cfg *user_cfg)
500{ 498{
501 int ret = -ENOMEM; 499 int ret = -ENOMEM;
502 struct lbs_scan_cmd_config *scan_cmd; 500 struct cmd_ds_802_11_scan *scan_cmd;
503 u8 *tlv; /* pointer into our current, growing TLV storage area */ 501 uint8_t *tlv; /* pointer into our current, growing TLV storage area */
504 502
505 lbs_deb_enter_args(LBS_DEB_SCAN, "bsstype %d, chanlist[].chan %d, " 503 lbs_deb_enter_args(LBS_DEB_SCAN, "bsstype %d, chanlist[].chan %d, chan_count %d",
506 "chan_count %d", 504 bsstype, chan_list[0].channumber, chan_count);
507 bsstype, chan_list[0].channumber, chan_count);
508 505
509 /* create the fixed part for scan command */ 506 /* create the fixed part for scan command */
510 scan_cmd = kzalloc(MAX_SCAN_CFG_ALLOC, GFP_KERNEL); 507 scan_cmd = kzalloc(MAX_SCAN_CFG_ALLOC, GFP_KERNEL);
511 if (scan_cmd == NULL) 508 if (scan_cmd == NULL)
512 goto out; 509 goto out;
510
513 tlv = scan_cmd->tlvbuffer; 511 tlv = scan_cmd->tlvbuffer;
514 if (user_cfg) 512 if (user_cfg)
515 memcpy(scan_cmd->bssid, user_cfg->bssid, ETH_ALEN); 513 memcpy(scan_cmd->bssid, user_cfg->bssid, ETH_ALEN);
@@ -523,13 +521,16 @@ static int lbs_do_scan(struct lbs_private *priv,
523 tlv += lbs_scan_add_rates_tlv(tlv); 521 tlv += lbs_scan_add_rates_tlv(tlv);
524 522
525 /* This is the final data we are about to send */ 523 /* This is the final data we are about to send */
526 scan_cmd->tlvbufferlen = tlv - scan_cmd->tlvbuffer; 524 scan_cmd->hdr.size = cpu_to_le16(tlv - (uint8_t *)scan_cmd);
527 lbs_deb_hex(LBS_DEB_SCAN, "SCAN_CMD", (void *)scan_cmd, 1+6); 525 lbs_deb_hex(LBS_DEB_SCAN, "SCAN_CMD", (void *)scan_cmd,
526 sizeof(*scan_cmd));
528 lbs_deb_hex(LBS_DEB_SCAN, "SCAN_TLV", scan_cmd->tlvbuffer, 527 lbs_deb_hex(LBS_DEB_SCAN, "SCAN_TLV", scan_cmd->tlvbuffer,
529 scan_cmd->tlvbufferlen); 528 tlv - scan_cmd->tlvbuffer);
529
530 ret = __lbs_cmd(priv, CMD_802_11_SCAN, &scan_cmd->hdr,
531 le16_to_cpu(scan_cmd->hdr.size),
532 lbs_ret_80211_scan, 0);
530 533
531 ret = lbs_prepare_and_send_command(priv, CMD_802_11_SCAN, 0,
532 CMD_OPTION_WAITFORRSP, 0, scan_cmd);
533out: 534out:
534 kfree(scan_cmd); 535 kfree(scan_cmd);
535 lbs_deb_leave_args(LBS_DEB_SCAN, "ret %d", ret); 536 lbs_deb_leave_args(LBS_DEB_SCAN, "ret %d", ret);
@@ -1485,44 +1486,6 @@ int lbs_get_scan(struct net_device *dev, struct iw_request_info *info,
1485 1486
1486 1487
1487/** 1488/**
1488 * @brief Prepare a scan command to be sent to the firmware
1489 *
1490 * Called via lbs_prepare_and_send_command(priv, CMD_802_11_SCAN, ...)
1491 * from cmd.c
1492 *
1493 * Sends a fixed length data part (specifying the BSS type and BSSID filters)
1494 * as well as a variable number/length of TLVs to the firmware.
1495 *
1496 * @param priv A pointer to struct lbs_private structure
1497 * @param cmd A pointer to cmd_ds_command structure to be sent to
1498 * firmware with the cmd_DS_801_11_SCAN structure
1499 * @param pdata_buf Void pointer cast of a lbs_scan_cmd_config struct used
1500 * to set the fields/TLVs for the command sent to firmware
1501 *
1502 * @return 0 or -1
1503 */
1504int lbs_cmd_80211_scan(struct lbs_private *priv,
1505 struct cmd_ds_command *cmd, void *pdata_buf)
1506{
1507 struct cmd_ds_802_11_scan *pscan = &cmd->params.scan;
1508 struct lbs_scan_cmd_config *pscancfg = pdata_buf;
1509
1510 lbs_deb_enter(LBS_DEB_SCAN);
1511
1512 /* Set fixed field variables in scan command */
1513 pscan->bsstype = pscancfg->bsstype;
1514 memcpy(pscan->bssid, pscancfg->bssid, ETH_ALEN);
1515 memcpy(pscan->tlvbuffer, pscancfg->tlvbuffer, pscancfg->tlvbufferlen);
1516
1517 /* size is equal to the sizeof(fixed portions) + the TLV len + header */
1518 cmd->size = cpu_to_le16(sizeof(pscan->bsstype) + ETH_ALEN
1519 + pscancfg->tlvbufferlen + S_DS_GEN);
1520
1521 lbs_deb_leave(LBS_DEB_SCAN);
1522 return 0;
1523}
1524
1525/**
1526 * @brief This function handles the command response of scan 1489 * @brief This function handles the command response of scan
1527 * 1490 *
1528 * Called from handle_cmd_response() in cmdrespc. 1491 * Called from handle_cmd_response() in cmdrespc.
@@ -1548,13 +1511,14 @@ int lbs_cmd_80211_scan(struct lbs_private *priv,
1548 * 1511 *
1549 * @return 0 or -1 1512 * @return 0 or -1
1550 */ 1513 */
1551int lbs_ret_80211_scan(struct lbs_private *priv, struct cmd_ds_command *resp) 1514static int lbs_ret_80211_scan(struct lbs_private *priv, unsigned long dummy,
1515 struct cmd_header *resp)
1552{ 1516{
1553 struct cmd_ds_802_11_scan_rsp *pscan; 1517 struct cmd_ds_802_11_scan_rsp *scanresp = (void *)resp;
1554 struct bss_descriptor * iter_bss; 1518 struct bss_descriptor * iter_bss;
1555 struct bss_descriptor * safe; 1519 struct bss_descriptor * safe;
1556 u8 *pbssinfo; 1520 uint8_t *bssinfo;
1557 u16 scanrespsize; 1521 uint16_t scanrespsize;
1558 int bytesleft; 1522 int bytesleft;
1559 int idx; 1523 int idx;
1560 int tlvbufsize; 1524 int tlvbufsize;
@@ -1571,48 +1535,45 @@ int lbs_ret_80211_scan(struct lbs_private *priv, struct cmd_ds_command *resp)
1571 clear_bss_descriptor(iter_bss); 1535 clear_bss_descriptor(iter_bss);
1572 } 1536 }
1573 1537
1574 pscan = &resp->params.scanresp; 1538 if (scanresp->nr_sets > MAX_NETWORK_COUNT) {
1575 1539 lbs_deb_scan("SCAN_RESP: too many scan results (%d, max %d)\n",
1576 if (pscan->nr_sets > MAX_NETWORK_COUNT) { 1540 scanresp->nr_sets, MAX_NETWORK_COUNT);
1577 lbs_deb_scan(
1578 "SCAN_RESP: too many scan results (%d, max %d)!!\n",
1579 pscan->nr_sets, MAX_NETWORK_COUNT);
1580 ret = -1; 1541 ret = -1;
1581 goto done; 1542 goto done;
1582 } 1543 }
1583 1544
1584 bytesleft = le16_to_cpu(pscan->bssdescriptsize); 1545 bytesleft = le16_to_cpu(scanresp->bssdescriptsize);
1585 lbs_deb_scan("SCAN_RESP: bssdescriptsize %d\n", bytesleft); 1546 lbs_deb_scan("SCAN_RESP: bssdescriptsize %d\n", bytesleft);
1586 1547
1587 scanrespsize = le16_to_cpu(resp->size); 1548 scanrespsize = le16_to_cpu(resp->size);
1588 lbs_deb_scan("SCAN_RESP: scan results %d\n", pscan->nr_sets); 1549 lbs_deb_scan("SCAN_RESP: scan results %d\n", scanresp->nr_sets);
1589 1550
1590 pbssinfo = pscan->bssdesc_and_tlvbuffer; 1551 bssinfo = scanresp->bssdesc_and_tlvbuffer;
1591 1552
1592 /* The size of the TLV buffer is equal to the entire command response 1553 /* The size of the TLV buffer is equal to the entire command response
1593 * size (scanrespsize) minus the fixed fields (sizeof()'s), the 1554 * size (scanrespsize) minus the fixed fields (sizeof()'s), the
1594 * BSS Descriptions (bssdescriptsize as bytesLef) and the command 1555 * BSS Descriptions (bssdescriptsize as bytesLef) and the command
1595 * response header (S_DS_GEN) 1556 * response header (S_DS_GEN)
1596 */ 1557 */
1597 tlvbufsize = scanrespsize - (bytesleft + sizeof(pscan->bssdescriptsize) 1558 tlvbufsize = scanrespsize - (bytesleft + sizeof(scanresp->bssdescriptsize)
1598 + sizeof(pscan->nr_sets) 1559 + sizeof(scanresp->nr_sets)
1599 + S_DS_GEN); 1560 + S_DS_GEN);
1600 1561
1601 /* 1562 /*
1602 * Process each scan response returned (pscan->nr_sets). Save 1563 * Process each scan response returned (scanresp->nr_sets). Save
1603 * the information in the newbssentry and then insert into the 1564 * the information in the newbssentry and then insert into the
1604 * driver scan table either as an update to an existing entry 1565 * driver scan table either as an update to an existing entry
1605 * or as an addition at the end of the table 1566 * or as an addition at the end of the table
1606 */ 1567 */
1607 for (idx = 0; idx < pscan->nr_sets && bytesleft; idx++) { 1568 for (idx = 0; idx < scanresp->nr_sets && bytesleft; idx++) {
1608 struct bss_descriptor new; 1569 struct bss_descriptor new;
1609 struct bss_descriptor * found = NULL; 1570 struct bss_descriptor *found = NULL;
1610 struct bss_descriptor * oldest = NULL; 1571 struct bss_descriptor *oldest = NULL;
1611 DECLARE_MAC_BUF(mac); 1572 DECLARE_MAC_BUF(mac);
1612 1573
1613 /* Process the data fields and IEs returned for this BSS */ 1574 /* Process the data fields and IEs returned for this BSS */
1614 memset(&new, 0, sizeof (struct bss_descriptor)); 1575 memset(&new, 0, sizeof (struct bss_descriptor));
1615 if (lbs_process_bss(&new, &pbssinfo, &bytesleft) != 0) { 1576 if (lbs_process_bss(&new, &bssinfo, &bytesleft) != 0) {
1616 /* error parsing the scan response, skipped */ 1577 /* error parsing the scan response, skipped */
1617 lbs_deb_scan("SCAN_RESP: process_bss returned ERROR\n"); 1578 lbs_deb_scan("SCAN_RESP: process_bss returned ERROR\n");
1618 continue; 1579 continue;
@@ -1647,8 +1608,7 @@ int lbs_ret_80211_scan(struct lbs_private *priv, struct cmd_ds_command *resp)
1647 continue; 1608 continue;
1648 } 1609 }
1649 1610
1650 lbs_deb_scan("SCAN_RESP: BSSID %s\n", 1611 lbs_deb_scan("SCAN_RESP: BSSID %s\n", print_mac(mac, new.bssid));
1651 print_mac(mac, new.bssid));
1652 1612
1653 /* Copy the locally created newbssentry to the scan table */ 1613 /* Copy the locally created newbssentry to the scan table */
1654 memcpy(found, &new, offsetof(struct bss_descriptor, list)); 1614 memcpy(found, &new, offsetof(struct bss_descriptor, list));