move mac80211 device registration to common code

Signed-off-by: Felix Fietkau <[email protected]>
This commit is contained in:
Felix Fietkau
2015-12-08 10:21:52 +01:00
parent 79c6074d7e
commit 89c32b4b58
6 changed files with 248 additions and 210 deletions
+1 -1
View File
@@ -3,7 +3,7 @@ EXTRA_CFLAGS += -Werror
obj-m := mt76.o mt76x2e.o mt7603e.o
mt76-y := \
mmio.o util.o trace.o dma.o
mmio.o util.o trace.o dma.o mac80211.o
mt76x2e-y := \
mt76x2_pci.o mt76x2_dma.o \
+222
View File
@@ -0,0 +1,222 @@
/*
* Copyright (C) 2015 Felix Fietkau <[email protected]>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include "mt76.h"
#define CHAN2G(_idx, _freq) { \
.band = IEEE80211_BAND_2GHZ, \
.center_freq = (_freq), \
.hw_value = (_idx), \
.max_power = 30, \
}
#define CHAN5G(_idx, _freq) { \
.band = IEEE80211_BAND_5GHZ, \
.center_freq = (_freq), \
.hw_value = (_idx), \
.max_power = 30, \
}
static const struct ieee80211_channel mt76_channels_2ghz[] = {
CHAN2G(1, 2412),
CHAN2G(2, 2417),
CHAN2G(3, 2422),
CHAN2G(4, 2427),
CHAN2G(5, 2432),
CHAN2G(6, 2437),
CHAN2G(7, 2442),
CHAN2G(8, 2447),
CHAN2G(9, 2452),
CHAN2G(10, 2457),
CHAN2G(11, 2462),
CHAN2G(12, 2467),
CHAN2G(13, 2472),
CHAN2G(14, 2484),
};
static const struct ieee80211_channel mt76_channels_5ghz[] = {
CHAN5G(36, 5180),
CHAN5G(40, 5200),
CHAN5G(44, 5220),
CHAN5G(48, 5240),
CHAN5G(52, 5260),
CHAN5G(56, 5280),
CHAN5G(60, 5300),
CHAN5G(64, 5320),
CHAN5G(100, 5500),
CHAN5G(104, 5520),
CHAN5G(108, 5540),
CHAN5G(112, 5560),
CHAN5G(116, 5580),
CHAN5G(120, 5600),
CHAN5G(124, 5620),
CHAN5G(128, 5640),
CHAN5G(132, 5660),
CHAN5G(136, 5680),
CHAN5G(140, 5700),
CHAN5G(149, 5745),
CHAN5G(153, 5765),
CHAN5G(157, 5785),
CHAN5G(161, 5805),
CHAN5G(165, 5825),
};
static int
mt76_init_sband(struct mt76_dev *dev, struct ieee80211_supported_band *sband,
const struct ieee80211_channel *chan, int n_chan,
struct ieee80211_rate *rates, int n_rates, bool vht)
{
struct ieee80211_sta_ht_cap *ht_cap;
struct ieee80211_sta_vht_cap *vht_cap;
void *chanlist;
u16 mcs_map;
int size;
size = n_chan * sizeof(*chan);
chanlist = devm_kmemdup(dev->dev, chan, size, GFP_KERNEL);
if (!chanlist)
return -ENOMEM;
sband->channels = chanlist;
sband->n_channels = n_chan;
sband->bitrates = rates;
sband->n_bitrates = n_rates;
ht_cap = &sband->ht_cap;
ht_cap->ht_supported = true;
ht_cap->cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
IEEE80211_HT_CAP_GRN_FLD |
IEEE80211_HT_CAP_SGI_20 |
IEEE80211_HT_CAP_SGI_40 |
IEEE80211_HT_CAP_LDPC_CODING |
IEEE80211_HT_CAP_TX_STBC |
(1 << IEEE80211_HT_CAP_RX_STBC_SHIFT);
ht_cap->mcs.rx_mask[0] = 0xff;
ht_cap->mcs.rx_mask[1] = 0xff;
ht_cap->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
ht_cap->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
ht_cap->ampdu_density = IEEE80211_HT_MPDU_DENSITY_4;
if (!vht)
return 0;
vht_cap = &sband->vht_cap;
vht_cap->vht_supported = true;
mcs_map = (IEEE80211_VHT_MCS_SUPPORT_0_9 << (0 * 2)) |
(IEEE80211_VHT_MCS_SUPPORT_0_9 << (1 * 2)) |
(IEEE80211_VHT_MCS_NOT_SUPPORTED << (2 * 2)) |
(IEEE80211_VHT_MCS_NOT_SUPPORTED << (3 * 2)) |
(IEEE80211_VHT_MCS_NOT_SUPPORTED << (4 * 2)) |
(IEEE80211_VHT_MCS_NOT_SUPPORTED << (5 * 2)) |
(IEEE80211_VHT_MCS_NOT_SUPPORTED << (6 * 2)) |
(IEEE80211_VHT_MCS_NOT_SUPPORTED << (7 * 2));
vht_cap->vht_mcs.rx_mcs_map = cpu_to_le16(mcs_map);
vht_cap->vht_mcs.tx_mcs_map = cpu_to_le16(mcs_map);
vht_cap->cap = IEEE80211_VHT_CAP_RXLDPC |
IEEE80211_VHT_CAP_TXSTBC |
IEEE80211_VHT_CAP_RXSTBC_1 |
IEEE80211_VHT_CAP_SHORT_GI_80;
return 0;
}
static int
mt76_init_sband_2g(struct mt76_dev *dev, struct ieee80211_rate *rates,
int n_rates)
{
dev->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &dev->sband_2g;
return mt76_init_sband(dev, &dev->sband_2g,
mt76_channels_2ghz,
ARRAY_SIZE(mt76_channels_2ghz),
rates, n_rates, false);
}
static int
mt76_init_sband_5g(struct mt76_dev *dev, struct ieee80211_rate *rates,
int n_rates, bool vht)
{
dev->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &dev->sband_5g;
return mt76_init_sband(dev, &dev->sband_5g,
mt76_channels_5ghz,
ARRAY_SIZE(mt76_channels_5ghz),
rates, n_rates, vht);
}
static const struct ieee80211_iface_limit if_limits[] = {
{
.max = 1,
.types = BIT(NL80211_IFTYPE_ADHOC)
}, {
.max = 8,
.types = BIT(NL80211_IFTYPE_STATION) |
#ifdef CONFIG_MAC80211_MESH
BIT(NL80211_IFTYPE_MESH_POINT) |
#endif
BIT(NL80211_IFTYPE_AP)
},
};
static const struct ieee80211_iface_combination if_comb[] = {
{
.limits = if_limits,
.n_limits = ARRAY_SIZE(if_limits),
.max_interfaces = 8,
.num_different_channels = 1,
.beacon_int_infra_match = true,
}
};
int mt76_register_device(struct mt76_dev *dev, int bands, bool vht,
struct ieee80211_rate *rates, int n_rates)
{
struct ieee80211_hw *hw = dev->hw;
struct wiphy *wiphy = hw->wiphy;
int ret;
SET_IEEE80211_DEV(hw, dev->dev);
wiphy->interface_modes =
BIT(NL80211_IFTYPE_STATION) |
BIT(NL80211_IFTYPE_AP) |
#ifdef CONFIG_MAC80211_MESH
BIT(NL80211_IFTYPE_MESH_POINT) |
#endif
BIT(NL80211_IFTYPE_ADHOC);
wiphy->iface_combinations = if_comb;
wiphy->n_iface_combinations = ARRAY_SIZE(if_comb);
wiphy->features |= NL80211_FEATURE_ACTIVE_MONITOR;
if (bands & BIT(IEEE80211_BAND_2GHZ)) {
ret = mt76_init_sband_2g(dev, rates, n_rates);
if (ret)
return ret;
}
if (bands & BIT(IEEE80211_BAND_5GHZ)) {
ret = mt76_init_sband_5g(dev, rates + 4, n_rates - 4, vht);
if (ret)
return ret;
}
return ieee80211_register_hw(hw);
}
EXPORT_SYMBOL_GPL(mt76_register_device);
+14
View File
@@ -103,6 +103,17 @@ struct mt76_dev {
u32 rev;
unsigned long state;
struct ieee80211_supported_band sband_2g;
struct ieee80211_supported_band sband_5g;
};
enum mt76_phy_type {
MT_PHY_TYPE_CCK,
MT_PHY_TYPE_OFDM,
MT_PHY_TYPE_HT,
MT_PHY_TYPE_HT_GF,
MT_PHY_TYPE_VHT,
};
#define mt76_rr(dev, ...) (dev)->mt76.bus->rr(&((dev)->mt76), __VA_ARGS__)
@@ -146,4 +157,7 @@ static inline u16 mt76_rev(struct mt76_dev *dev)
#define mt76_queue_cleanup(dev, ...) (dev)->mt76.queue_ops->cleanup(&((dev)->mt76), __VA_ARGS__)
#define mt76_queue_kick(dev, ...) (dev)->mt76.queue_ops->kick(&((dev)->mt76), __VA_ARGS__)
int mt76_register_device(struct mt76_dev *dev, int bands, bool vht,
struct ieee80211_rate *rates, int n_rates);
#endif
-2
View File
@@ -122,8 +122,6 @@ struct mt76x2_dev {
unsigned long wcid_mask[256 / BITS_PER_LONG];
struct cfg80211_chan_def chandef;
struct ieee80211_supported_band sband_2g;
struct ieee80211_supported_band sband_5g;
int txpower_conf;
int txpower_cur;
+11 -199
View File
@@ -577,67 +577,6 @@ struct mt76x2_dev *mt76x2_alloc_device(struct device *pdev)
return dev;
}
#define CHAN2G(_idx, _freq) { \
.band = IEEE80211_BAND_2GHZ, \
.center_freq = (_freq), \
.hw_value = (_idx), \
.max_power = 30, \
}
#define CHAN5G(_idx, _freq) { \
.band = IEEE80211_BAND_5GHZ, \
.center_freq = (_freq), \
.hw_value = (_idx), \
.max_power = 30, \
}
static const struct ieee80211_channel mt76x2_channels_2ghz[] = {
CHAN2G(1, 2412),
CHAN2G(2, 2417),
CHAN2G(3, 2422),
CHAN2G(4, 2427),
CHAN2G(5, 2432),
CHAN2G(6, 2437),
CHAN2G(7, 2442),
CHAN2G(8, 2447),
CHAN2G(9, 2452),
CHAN2G(10, 2457),
CHAN2G(11, 2462),
CHAN2G(12, 2467),
CHAN2G(13, 2472),
CHAN2G(14, 2484),
};
static const struct ieee80211_channel mt76x2_channels_5ghz[] = {
CHAN5G(36, 5180),
CHAN5G(40, 5200),
CHAN5G(44, 5220),
CHAN5G(48, 5240),
CHAN5G(52, 5260),
CHAN5G(56, 5280),
CHAN5G(60, 5300),
CHAN5G(64, 5320),
CHAN5G(100, 5500),
CHAN5G(104, 5520),
CHAN5G(108, 5540),
CHAN5G(112, 5560),
CHAN5G(116, 5580),
CHAN5G(120, 5600),
CHAN5G(124, 5620),
CHAN5G(128, 5640),
CHAN5G(132, 5660),
CHAN5G(136, 5680),
CHAN5G(140, 5700),
CHAN5G(149, 5745),
CHAN5G(153, 5765),
CHAN5G(157, 5785),
CHAN5G(161, 5805),
CHAN5G(165, 5825),
};
#define CCK_RATE(_idx, _rate) { \
.bitrate = _rate, \
.flags = IEEE80211_RATE_SHORT_PREAMBLE, \
@@ -666,127 +605,15 @@ static struct ieee80211_rate mt76x2_rates[] = {
OFDM_RATE(7, 540),
};
static int
mt76x2_init_sband(struct mt76x2_dev *dev, struct ieee80211_supported_band *sband,
const struct ieee80211_channel *chan, int n_chan,
struct ieee80211_rate *rates, int n_rates)
{
struct ieee80211_sta_ht_cap *ht_cap;
struct ieee80211_sta_vht_cap *vht_cap;
void *chanlist;
u16 mcs_map;
int size;
size = n_chan * sizeof(*chan);
chanlist = devm_kmemdup(dev->mt76.dev, chan, size, GFP_KERNEL);
if (!chanlist)
return -ENOMEM;
sband->channels = chanlist;
sband->n_channels = n_chan;
sband->bitrates = rates;
sband->n_bitrates = n_rates;
ht_cap = &sband->ht_cap;
ht_cap->ht_supported = true;
ht_cap->cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
IEEE80211_HT_CAP_GRN_FLD |
IEEE80211_HT_CAP_SGI_20 |
IEEE80211_HT_CAP_SGI_40 |
IEEE80211_HT_CAP_LDPC_CODING |
IEEE80211_HT_CAP_TX_STBC |
(1 << IEEE80211_HT_CAP_RX_STBC_SHIFT);
ht_cap->mcs.rx_mask[0] = 0xff;
ht_cap->mcs.rx_mask[1] = 0xff;
ht_cap->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
ht_cap->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
ht_cap->ampdu_density = IEEE80211_HT_MPDU_DENSITY_4;
if (dev->cap.has_5ghz)
{
vht_cap = &sband->vht_cap;
vht_cap->vht_supported = true;
mcs_map = (IEEE80211_VHT_MCS_SUPPORT_0_9 << (0 * 2)) |
(IEEE80211_VHT_MCS_SUPPORT_0_9 << (1 * 2)) |
(IEEE80211_VHT_MCS_NOT_SUPPORTED << (2 * 2)) |
(IEEE80211_VHT_MCS_NOT_SUPPORTED << (3 * 2)) |
(IEEE80211_VHT_MCS_NOT_SUPPORTED << (4 * 2)) |
(IEEE80211_VHT_MCS_NOT_SUPPORTED << (5 * 2)) |
(IEEE80211_VHT_MCS_NOT_SUPPORTED << (6 * 2)) |
(IEEE80211_VHT_MCS_NOT_SUPPORTED << (7 * 2));
vht_cap->vht_mcs.rx_mcs_map = cpu_to_le16(mcs_map);
vht_cap->vht_mcs.tx_mcs_map = cpu_to_le16(mcs_map);
vht_cap->cap = IEEE80211_VHT_CAP_RXLDPC |
IEEE80211_VHT_CAP_TXSTBC |
IEEE80211_VHT_CAP_RXSTBC_1 |
IEEE80211_VHT_CAP_SHORT_GI_80;
}
dev->chandef.chan = &sband->channels[0];
return 0;
}
static int
mt76x2_init_sband_2g(struct mt76x2_dev *dev)
{
if (!dev->cap.has_2ghz)
return 0;
mt76_hw(dev)->wiphy->bands[IEEE80211_BAND_2GHZ] = &dev->sband_2g;
return mt76x2_init_sband(dev, &dev->sband_2g,
mt76x2_channels_2ghz,
ARRAY_SIZE(mt76x2_channels_2ghz),
mt76x2_rates, ARRAY_SIZE(mt76x2_rates));
}
static int
mt76x2_init_sband_5g(struct mt76x2_dev *dev)
{
if (!dev->cap.has_5ghz)
return 0;
mt76_hw(dev)->wiphy->bands[IEEE80211_BAND_5GHZ] = &dev->sband_5g;
return mt76x2_init_sband(dev, &dev->sband_5g,
mt76x2_channels_5ghz,
ARRAY_SIZE(mt76x2_channels_5ghz),
mt76x2_rates + 4, ARRAY_SIZE(mt76x2_rates) - 4);
}
static const struct ieee80211_iface_limit if_limits[] = {
{
.max = 1,
.types = BIT(NL80211_IFTYPE_ADHOC)
}, {
.max = 8,
.types = BIT(NL80211_IFTYPE_STATION) |
#ifdef CONFIG_MAC80211_MESH
BIT(NL80211_IFTYPE_MESH_POINT) |
#endif
BIT(NL80211_IFTYPE_AP)
},
};
static const struct ieee80211_iface_combination if_comb[] = {
{
.limits = if_limits,
.n_limits = ARRAY_SIZE(if_limits),
.max_interfaces = 8,
.num_different_channels = 1,
.beacon_int_infra_match = true,
}
};
int mt76x2_register_device(struct mt76x2_dev *dev)
{
struct ieee80211_hw *hw = mt76_hw(dev);
struct ieee80211_supported_band *sband;
struct wiphy *wiphy = hw->wiphy;
void *status_fifo;
int fifo_size;
int i, ret;
int bands;
fifo_size = roundup_pow_of_two(32 * sizeof(struct mt76x2_tx_status));
status_fifo = devm_kzalloc(dev->mt76.dev, fifo_size, GFP_KERNEL);
@@ -799,8 +626,6 @@ int mt76x2_register_device(struct mt76x2_dev *dev)
if (ret)
return ret;
SET_IEEE80211_DEV(hw, dev->mt76.dev);
hw->queues = 4;
hw->max_rates = 1;
hw->max_report_rates = 7;
@@ -835,35 +660,22 @@ int mt76x2_register_device(struct mt76x2_dev *dev)
wiphy->addresses = dev->macaddr_list;
wiphy->n_addresses = ARRAY_SIZE(dev->macaddr_list);
wiphy->features |= NL80211_FEATURE_ACTIVE_MONITOR;
wiphy->interface_modes =
BIT(NL80211_IFTYPE_STATION) |
BIT(NL80211_IFTYPE_AP) |
#ifdef CONFIG_MAC80211_MESH
BIT(NL80211_IFTYPE_MESH_POINT) |
#endif
BIT(NL80211_IFTYPE_ADHOC);
wiphy->iface_combinations = if_comb;
wiphy->n_iface_combinations = ARRAY_SIZE(if_comb);
ret = mt76x2_init_sband_2g(dev);
if (ret)
goto fail;
ret = mt76x2_init_sband_5g(dev);
if (ret)
goto fail;
INIT_LIST_HEAD(&dev->txwi_cache);
INIT_DELAYED_WORK(&dev->cal_work, mt76x2_phy_calibrate);
INIT_DELAYED_WORK(&dev->mac_work, mt76x2_mac_work);
ret = ieee80211_register_hw(hw);
bands = (!!dev->cap.has_2ghz * BIT(IEEE80211_BAND_2GHZ)) |
(!!dev->cap.has_5ghz * BIT(IEEE80211_BAND_5GHZ));
ret = mt76_register_device(&dev->mt76, bands, true,
mt76x2_rates, ARRAY_SIZE(mt76x2_rates));
if (ret)
goto fail;
sband = wiphy->bands[dev->cap.has_5ghz ? IEEE80211_BAND_5GHZ :
IEEE80211_BAND_2GHZ];
dev->chandef.chan = &sband->channels[0];
mt76x2_init_debugfs(dev);
return 0;
-8
View File
@@ -107,14 +107,6 @@ struct mt76x2_rxwi {
#define MT_RATE_INDEX_VHT_IDX GENMASK(3, 0)
#define MT_RATE_INDEX_VHT_NSS GENMASK(5, 4)
enum mt76x2_phy_type {
MT_PHY_TYPE_CCK,
MT_PHY_TYPE_OFDM,
MT_PHY_TYPE_HT,
MT_PHY_TYPE_HT_GF,
MT_PHY_TYPE_VHT,
};
enum mt76x2_phy_bandwith {
MT_PHY_BW_20,
MT_PHY_BW_40,