diff options
author | Kalle Valo <kvalo@codeaurora.org> | 2015-06-15 10:25:32 (GMT) |
---|---|---|
committer | Kalle Valo <kvalo@codeaurora.org> | 2015-06-15 10:25:32 (GMT) |
commit | d9378080a12ba314476fcccf4ce1328794e4e230 (patch) | |
tree | 78640c772386f691e927a1ec86694a3292e0adcc /drivers/net/wireless/ath/wil6210 | |
parent | ed8e0ed53b317f72df907298fb653a976b083dc4 (diff) | |
parent | 3e2d8e1b82af3e67c8d369f3c006b8f882399742 (diff) | |
download | linux-d9378080a12ba314476fcccf4ce1328794e4e230.tar.xz |
Merge ath-next from ath.git
Major changes:
wil6210:
* add modparam for bcast ring size
* support hidden SSID
* add per-MCS Rx stats
Diffstat (limited to 'drivers/net/wireless/ath/wil6210')
-rw-r--r-- | drivers/net/wireless/ath/wil6210/cfg80211.c | 46 | ||||
-rw-r--r-- | drivers/net/wireless/ath/wil6210/debugfs.c | 8 | ||||
-rw-r--r-- | drivers/net/wireless/ath/wil6210/main.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/ath/wil6210/netdev.c | 3 | ||||
-rw-r--r-- | drivers/net/wireless/ath/wil6210/pcie_bus.c | 99 | ||||
-rw-r--r-- | drivers/net/wireless/ath/wil6210/txrx.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/ath/wil6210/wil6210.h | 9 | ||||
-rw-r--r-- | drivers/net/wireless/ath/wil6210/wil_platform.c | 14 | ||||
-rw-r--r-- | drivers/net/wireless/ath/wil6210/wil_platform.h | 3 | ||||
-rw-r--r-- | drivers/net/wireless/ath/wil6210/wmi.c | 5 | ||||
-rw-r--r-- | drivers/net/wireless/ath/wil6210/wmi.h | 10 |
11 files changed, 153 insertions, 48 deletions
diff --git a/drivers/net/wireless/ath/wil6210/cfg80211.c b/drivers/net/wireless/ath/wil6210/cfg80211.c index dbfcdd1..c79cfe0 100644 --- a/drivers/net/wireless/ath/wil6210/cfg80211.c +++ b/drivers/net/wireless/ath/wil6210/cfg80211.c @@ -289,6 +289,26 @@ static int wil_cfg80211_scan(struct wiphy *wiphy, } wil_dbg_misc(wil, "Start scan_request 0x%p\n", request); + wil_dbg_misc(wil, "SSID count: %d", request->n_ssids); + + for (i = 0; i < request->n_ssids; i++) { + wil_dbg_misc(wil, "SSID[%d]", i); + print_hex_dump_bytes("SSID ", DUMP_PREFIX_OFFSET, + request->ssids[i].ssid, + request->ssids[i].ssid_len); + } + + if (request->n_ssids) + rc = wmi_set_ssid(wil, request->ssids[0].ssid_len, + request->ssids[0].ssid); + else + rc = wmi_set_ssid(wil, 0, NULL); + + if (rc) { + wil_err(wil, "set SSID for scan request failed: %d\n", rc); + return rc; + } + wil->scan_request = request; mod_timer(&wil->scan_timer, jiffies + WIL6210_SCAN_TO); @@ -778,6 +798,7 @@ static int wil_cfg80211_start_ap(struct wiphy *wiphy, size_t hlen = offsetof(struct ieee80211_mgmt, u.probe_resp.variable); const u8 *pr_ies = NULL; size_t pr_ies_len = 0; + u8 hidden_ssid; wil_dbg_misc(wil, "%s()\n", __func__); @@ -790,6 +811,8 @@ static int wil_cfg80211_start_ap(struct wiphy *wiphy, channel->center_freq, info->privacy ? "secure" : "open"); wil_dbg_misc(wil, "Privacy: %d auth_type %d\n", info->privacy, info->auth_type); + wil_dbg_misc(wil, "Hidden SSID mode: %d\n", + info->hidden_ssid); wil_dbg_misc(wil, "BI %d DTIM %d\n", info->beacon_interval, info->dtim_period); print_hex_dump_bytes("SSID ", DUMP_PREFIX_OFFSET, @@ -835,10 +858,28 @@ static int wil_cfg80211_start_ap(struct wiphy *wiphy, wil->privacy = info->privacy; + switch (info->hidden_ssid) { + case NL80211_HIDDEN_SSID_NOT_IN_USE: + hidden_ssid = WMI_HIDDEN_SSID_DISABLED; + break; + + case NL80211_HIDDEN_SSID_ZERO_LEN: + hidden_ssid = WMI_HIDDEN_SSID_SEND_EMPTY; + break; + + case NL80211_HIDDEN_SSID_ZERO_CONTENTS: + hidden_ssid = WMI_HIDDEN_SSID_CLEAR; + break; + + default: + rc = -EOPNOTSUPP; + goto out; + } + netif_carrier_on(ndev); rc = wmi_pcp_start(wil, info->beacon_interval, wmi_nettype, - channel->hw_value); + channel->hw_value, hidden_ssid); if (rc) goto err_pcp_start; @@ -1023,8 +1064,7 @@ static struct cfg80211_ops wil_cfg80211_ops = { static void wil_wiphy_init(struct wiphy *wiphy) { - /* TODO: set real value */ - wiphy->max_scan_ssids = 10; + wiphy->max_scan_ssids = 1; wiphy->max_scan_ie_len = WMI_MAX_IE_LEN; wiphy->max_num_pmkids = 0 /* TODO: */; wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | diff --git a/drivers/net/wireless/ath/wil6210/debugfs.c b/drivers/net/wireless/ath/wil6210/debugfs.c index 8f9c072..75219a1 100644 --- a/drivers/net/wireless/ath/wil6210/debugfs.c +++ b/drivers/net/wireless/ath/wil6210/debugfs.c @@ -1360,7 +1360,7 @@ static int wil_sta_debugfs_show(struct seq_file *s, void *data) __acquires(&p->tid_rx_lock) __releases(&p->tid_rx_lock) { struct wil6210_priv *wil = s->private; - int i, tid; + int i, tid, mcs; for (i = 0; i < ARRAY_SIZE(wil->sta); i++) { struct wil_sta_info *p = &wil->sta[i]; @@ -1390,6 +1390,12 @@ __acquires(&p->tid_rx_lock) __releases(&p->tid_rx_lock) } } spin_unlock_bh(&p->tid_rx_lock); + seq_puts(s, "Rx/MCS:"); + for (mcs = 0; mcs < ARRAY_SIZE(p->stats.rx_per_mcs); + mcs++) + seq_printf(s, " %lld", + p->stats.rx_per_mcs[mcs]); + seq_puts(s, "\n"); } } diff --git a/drivers/net/wireless/ath/wil6210/main.c b/drivers/net/wireless/ath/wil6210/main.c index 6d704ae..b9febab 100644 --- a/drivers/net/wireless/ath/wil6210/main.c +++ b/drivers/net/wireless/ath/wil6210/main.c @@ -100,6 +100,8 @@ module_param_cb(rx_ring_order, &ring_order_ops, &rx_ring_order, S_IRUGO); MODULE_PARM_DESC(rx_ring_order, " Rx ring order; size = 1 << order"); module_param_cb(tx_ring_order, &ring_order_ops, &tx_ring_order, S_IRUGO); MODULE_PARM_DESC(tx_ring_order, " Tx ring order; size = 1 << order"); +module_param_cb(bcast_ring_order, &ring_order_ops, &bcast_ring_order, S_IRUGO); +MODULE_PARM_DESC(bcast_ring_order, " Bcast ring order; size = 1 << order"); #define RST_DELAY (20) /* msec, for loop in @wil_target_reset */ #define RST_COUNT (1 + 1000/RST_DELAY) /* round up to be above 1 sec total */ diff --git a/drivers/net/wireless/ath/wil6210/netdev.c b/drivers/net/wireless/ath/wil6210/netdev.c index 6042f61..8ef18ac 100644 --- a/drivers/net/wireless/ath/wil6210/netdev.c +++ b/drivers/net/wireless/ath/wil6210/netdev.c @@ -132,7 +132,7 @@ static void wil_dev_setup(struct net_device *dev) dev->tx_queue_len = WIL_TX_Q_LEN_DEFAULT; } -void *wil_if_alloc(struct device *dev, void __iomem *csr) +void *wil_if_alloc(struct device *dev) { struct net_device *ndev; struct wireless_dev *wdev; @@ -147,7 +147,6 @@ void *wil_if_alloc(struct device *dev, void __iomem *csr) } wil = wdev_to_wil(wdev); - wil->csr = csr; wil->wdev = wdev; wil_dbg_misc(wil, "%s()\n", __func__); diff --git a/drivers/net/wireless/ath/wil6210/pcie_bus.c b/drivers/net/wireless/ath/wil6210/pcie_bus.c index 58c7916..aa3ecc6 100644 --- a/drivers/net/wireless/ath/wil6210/pcie_bus.c +++ b/drivers/net/wireless/ath/wil6210/pcie_bus.c @@ -163,7 +163,6 @@ static int wil_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id) { struct wil6210_priv *wil; struct device *dev = &pdev->dev; - void __iomem *csr; int rc; /* check HW */ @@ -178,9 +177,28 @@ static int wil_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id) return -ENODEV; } + wil = wil_if_alloc(dev); + if (IS_ERR(wil)) { + rc = (int)PTR_ERR(wil); + dev_err(dev, "wil_if_alloc failed: %d\n", rc); + return rc; + } + wil->pdev = pdev; + pci_set_drvdata(pdev, wil); + /* rollback to if_free */ + + wil->platform_handle = + wil_platform_init(&pdev->dev, &wil->platform_ops); + if (!wil->platform_handle) { + rc = -ENODEV; + wil_err(wil, "wil_platform_init failed\n"); + goto if_free; + } + /* rollback to err_plat */ + rc = pci_enable_device(pdev); if (rc) { - dev_err(&pdev->dev, + wil_err(wil, "pci_enable_device failed, retry with MSI only\n"); /* Work around for platforms that can't allocate IRQ: * retry with MSI only @@ -188,47 +206,37 @@ static int wil_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id) pdev->msi_enabled = 1; rc = pci_enable_device(pdev); } - if (rc) - return -ENODEV; + if (rc) { + wil_err(wil, + "pci_enable_device failed, even with MSI only\n"); + goto err_plat; + } /* rollback to err_disable_pdev */ rc = pci_request_region(pdev, 0, WIL_NAME); if (rc) { - dev_err(&pdev->dev, "pci_request_region failed\n"); + wil_err(wil, "pci_request_region failed\n"); goto err_disable_pdev; } /* rollback to err_release_reg */ - csr = pci_ioremap_bar(pdev, 0); - if (!csr) { - dev_err(&pdev->dev, "pci_ioremap_bar failed\n"); + wil->csr = pci_ioremap_bar(pdev, 0); + if (!wil->csr) { + wil_err(wil, "pci_ioremap_bar failed\n"); rc = -ENODEV; goto err_release_reg; } /* rollback to err_iounmap */ - dev_info(&pdev->dev, "CSR at %pR -> 0x%p\n", &pdev->resource[0], csr); + wil_info(wil, "CSR at %pR -> 0x%p\n", &pdev->resource[0], wil->csr); - wil = wil_if_alloc(dev, csr); - if (IS_ERR(wil)) { - rc = (int)PTR_ERR(wil); - dev_err(dev, "wil_if_alloc failed: %d\n", rc); - goto err_iounmap; - } - /* rollback to if_free */ - - pci_set_drvdata(pdev, wil); - wil->pdev = pdev; wil_set_capabilities(wil); wil6210_clear_irq(wil); - wil->platform_handle = - wil_platform_init(&pdev->dev, &wil->platform_ops); - /* FW should raise IRQ when ready */ rc = wil_if_pcie_enable(wil); if (rc) { wil_err(wil, "Enable device failed\n"); - goto if_free; + goto err_iounmap; } /* rollback to bus_disable */ @@ -243,18 +251,19 @@ static int wil_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id) return 0; - bus_disable: +bus_disable: wil_if_pcie_disable(wil); - if_free: +err_iounmap: + pci_iounmap(pdev, wil->csr); +err_release_reg: + pci_release_region(pdev, 0); +err_disable_pdev: + pci_disable_device(pdev); +err_plat: if (wil->platform_ops.uninit) wil->platform_ops.uninit(wil->platform_handle); +if_free: wil_if_free(wil); - err_iounmap: - pci_iounmap(pdev, csr); - err_release_reg: - pci_release_region(pdev, 0); - err_disable_pdev: - pci_disable_device(pdev); return rc; } @@ -269,12 +278,12 @@ static void wil_pcie_remove(struct pci_dev *pdev) wil6210_debugfs_remove(wil); wil_if_remove(wil); wil_if_pcie_disable(wil); - if (wil->platform_ops.uninit) - wil->platform_ops.uninit(wil->platform_handle); - wil_if_free(wil); pci_iounmap(pdev, csr); pci_release_region(pdev, 0); pci_disable_device(pdev); + if (wil->platform_ops.uninit) + wil->platform_ops.uninit(wil->platform_handle); + wil_if_free(wil); } static const struct pci_device_id wil6210_pcie_ids[] = { @@ -291,7 +300,27 @@ static struct pci_driver wil6210_driver = { .name = WIL_NAME, }; -module_pci_driver(wil6210_driver); +static int __init wil6210_driver_init(void) +{ + int rc; + + rc = wil_platform_modinit(); + if (rc) + return rc; + + rc = pci_register_driver(&wil6210_driver); + if (rc) + wil_platform_modexit(); + return rc; +} +module_init(wil6210_driver_init); + +static void __exit wil6210_driver_exit(void) +{ + pci_unregister_driver(&wil6210_driver); + wil_platform_modexit(); +} +module_exit(wil6210_driver_exit); MODULE_LICENSE("Dual BSD/GPL"); MODULE_AUTHOR("Qualcomm Atheros <wil6210@qca.qualcomm.com>"); diff --git a/drivers/net/wireless/ath/wil6210/txrx.c b/drivers/net/wireless/ath/wil6210/txrx.c index 0113dac..aa20af8 100644 --- a/drivers/net/wireless/ath/wil6210/txrx.c +++ b/drivers/net/wireless/ath/wil6210/txrx.c @@ -427,6 +427,8 @@ static struct sk_buff *wil_vring_reap_rx(struct wil6210_priv *wil, cid = wil_rxdesc_cid(d); stats = &wil->sta[cid].stats; stats->last_mcs_rx = wil_rxdesc_mcs(d); + if (stats->last_mcs_rx < ARRAY_SIZE(stats->rx_per_mcs)) + stats->rx_per_mcs[stats->last_mcs_rx]++; /* use radiotap header only if required */ if (ndev->type == ARPHRD_IEEE80211_RADIOTAP) diff --git a/drivers/net/wireless/ath/wil6210/wil6210.h b/drivers/net/wireless/ath/wil6210/wil6210.h index f3513a1..275355d 100644 --- a/drivers/net/wireless/ath/wil6210/wil6210.h +++ b/drivers/net/wireless/ath/wil6210/wil6210.h @@ -281,7 +281,7 @@ struct fw_map { }; /* array size should be in sync with actual definition in the wmi.c */ -extern const struct fw_map fw_mapping[7]; +extern const struct fw_map fw_mapping[8]; /** * mk_cidxtid - construct @cidxtid field @@ -464,6 +464,7 @@ enum wil_sta_status { }; #define WIL_STA_TID_NUM (16) +#define WIL_MCS_MAX (12) /* Maximum MCS supported */ struct wil_net_stats { unsigned long rx_packets; @@ -473,6 +474,7 @@ struct wil_net_stats { unsigned long tx_errors; unsigned long rx_dropped; u16 last_mcs_rx; + u64 rx_per_mcs[WIL_MCS_MAX + 1]; }; /** @@ -684,7 +686,7 @@ void wil_memcpy_fromio_32(void *dst, const volatile void __iomem *src, void wil_memcpy_toio_32(volatile void __iomem *dst, const void *src, size_t count); -void *wil_if_alloc(struct device *dev, void __iomem *csr); +void *wil_if_alloc(struct device *dev); void wil_if_free(struct wil6210_priv *wil); int wil_if_add(struct wil6210_priv *wil); void wil_if_remove(struct wil6210_priv *wil); @@ -762,7 +764,8 @@ struct wireless_dev *wil_cfg80211_init(struct device *dev); void wil_wdev_free(struct wil6210_priv *wil); int wmi_set_mac_address(struct wil6210_priv *wil, void *addr); -int wmi_pcp_start(struct wil6210_priv *wil, int bi, u8 wmi_nettype, u8 chan); +int wmi_pcp_start(struct wil6210_priv *wil, int bi, u8 wmi_nettype, + u8 chan, u8 hidden_ssid); int wmi_pcp_stop(struct wil6210_priv *wil); void wil6210_disconnect(struct wil6210_priv *wil, const u8 *bssid, u16 reason_code, bool from_event); diff --git a/drivers/net/wireless/ath/wil6210/wil_platform.c b/drivers/net/wireless/ath/wil6210/wil_platform.c index 976a071..de15f14 100644 --- a/drivers/net/wireless/ath/wil6210/wil_platform.c +++ b/drivers/net/wireless/ath/wil6210/wil_platform.c @@ -17,6 +17,15 @@ #include "linux/device.h" #include "wil_platform.h" +int __init wil_platform_modinit(void) +{ + return 0; +} + +void wil_platform_modexit(void) +{ +} + /** * wil_platform_init() - wil6210 platform module init * @@ -26,10 +35,11 @@ */ void *wil_platform_init(struct device *dev, struct wil_platform_ops *ops) { - void *handle = NULL; + void *handle = ops; /* to return some non-NULL for 'void' impl. */ if (!ops) { - dev_err(dev, "Invalid parameter. Cannot init platform module\n"); + dev_err(dev, + "Invalid parameter. Cannot init platform module\n"); return NULL; } diff --git a/drivers/net/wireless/ath/wil6210/wil_platform.h b/drivers/net/wireless/ath/wil6210/wil_platform.h index 158c73b..d7fa19b 100644 --- a/drivers/net/wireless/ath/wil6210/wil_platform.h +++ b/drivers/net/wireless/ath/wil6210/wil_platform.h @@ -31,4 +31,7 @@ struct wil_platform_ops { void *wil_platform_init(struct device *dev, struct wil_platform_ops *ops); +int __init wil_platform_modinit(void); +void wil_platform_modexit(void); + #endif /* __WIL_PLATFORM_H__ */ diff --git a/drivers/net/wireless/ath/wil6210/wmi.c b/drivers/net/wireless/ath/wil6210/wmi.c index 3dc8daf..c759759 100644 --- a/drivers/net/wireless/ath/wil6210/wmi.c +++ b/drivers/net/wireless/ath/wil6210/wmi.c @@ -85,6 +85,7 @@ const struct fw_map fw_mapping[] = { {0x880000, 0x88a000, 0x880000, "rgf"}, /* various RGF 40k */ {0x88a000, 0x88b000, 0x88a000, "AGC_tbl"}, /* AGC table 4k */ {0x88b000, 0x88c000, 0x88b000, "rgf_ext"}, /* Pcie_ext_rgf 4k */ + {0x88c000, 0x88c200, 0x88c000, "mac_rgf_ext"}, /* mac_ext_rgf 512b */ {0x8c0000, 0x949000, 0x8c0000, "upper"}, /* upper area 548k */ /* * 920000..930000 ucode code RAM @@ -824,7 +825,8 @@ int wmi_set_mac_address(struct wil6210_priv *wil, void *addr) return wmi_send(wil, WMI_SET_MAC_ADDRESS_CMDID, &cmd, sizeof(cmd)); } -int wmi_pcp_start(struct wil6210_priv *wil, int bi, u8 wmi_nettype, u8 chan) +int wmi_pcp_start(struct wil6210_priv *wil, int bi, u8 wmi_nettype, + u8 chan, u8 hidden_ssid) { int rc; @@ -834,6 +836,7 @@ int wmi_pcp_start(struct wil6210_priv *wil, int bi, u8 wmi_nettype, u8 chan) .disable_sec_offload = 1, .channel = chan - 1, .pcp_max_assoc_sta = max_assoc_sta, + .hidden_ssid = hidden_ssid, }; struct { struct wil6210_mbox_hdr_wmi wmi; diff --git a/drivers/net/wireless/ath/wil6210/wmi.h b/drivers/net/wireless/ath/wil6210/wmi.h index cc04ab7..6e90e78 100644 --- a/drivers/net/wireless/ath/wil6210/wmi.h +++ b/drivers/net/wireless/ath/wil6210/wmi.h @@ -495,10 +495,18 @@ struct wmi_power_mgmt_cfg_cmd { /* * WMI_PCP_START_CMDID */ + +enum wmi_hidden_ssid { + WMI_HIDDEN_SSID_DISABLED = 0, + WMI_HIDDEN_SSID_SEND_EMPTY = 1, + WMI_HIDDEN_SSID_CLEAR = 2, +}; + struct wmi_pcp_start_cmd { __le16 bcon_interval; u8 pcp_max_assoc_sta; - u8 reserved0[9]; + u8 hidden_ssid; + u8 reserved0[8]; u8 network_type; u8 channel; u8 disable_sec_offload; |