@@ -185,10 +185,11 @@ int rtw89_chanctx_ops_add(struct rtw89_dev *rtwdev,
{
struct rtw89_hal *hal = &rtwdev->hal;
struct rtw89_chanctx_cfg *cfg = (struct rtw89_chanctx_cfg *)ctx->drv_priv;
+ const struct rtw89_chip_info *chip = rtwdev->chip;
u8 idx;
idx = find_first_zero_bit(hal->entity_map, NUM_OF_RTW89_SUB_ENTITY);
- if (idx > RTW89_SUB_ENTITY_0)
+ if (idx >= chip->support_chanctx_num)
return -ENOENT;
rtw89_config_entity_chandef(rtwdev, idx, &ctx->def);
@@ -3208,6 +3208,53 @@ void rtw89_core_unregister(struct rtw89_dev *rtwdev)
}
EXPORT_SYMBOL(rtw89_core_unregister);
+struct rtw89_dev *rtw89_alloc_ieee80211_hw(struct device *device,
+ u32 bus_data_size,
+ const struct rtw89_chip_info *chip)
+{
+ struct ieee80211_hw *hw;
+ struct rtw89_dev *rtwdev;
+ struct ieee80211_ops *ops;
+ u32 driver_data_size;
+
+ ops = kmemdup(&rtw89_ops, sizeof(rtw89_ops), GFP_KERNEL);
+ if (!ops)
+ goto err;
+
+ if (chip->support_chanctx_num == 0) {
+ ops->add_chanctx = NULL;
+ ops->remove_chanctx = NULL;
+ ops->change_chanctx = NULL;
+ ops->assign_vif_chanctx = NULL;
+ ops->unassign_vif_chanctx = NULL;
+ }
+
+ driver_data_size = sizeof(struct rtw89_dev) + bus_data_size;
+ hw = ieee80211_alloc_hw(driver_data_size, ops);
+ if (!hw)
+ goto err;
+
+ rtwdev = hw->priv;
+ rtwdev->hw = hw;
+ rtwdev->dev = device;
+ rtwdev->ops = ops;
+ rtwdev->chip = chip;
+
+ return rtwdev;
+
+err:
+ kfree(ops);
+ return NULL;
+}
+EXPORT_SYMBOL(rtw89_alloc_ieee80211_hw);
+
+void rtw89_free_ieee80211_hw(struct rtw89_dev *rtwdev)
+{
+ kfree(rtwdev->ops);
+ ieee80211_free_hw(rtwdev->hw);
+}
+EXPORT_SYMBOL(rtw89_free_ieee80211_hw);
+
MODULE_AUTHOR("Realtek Corporation");
MODULE_DESCRIPTION("Realtek 802.11ax wireless core module");
MODULE_LICENSE("Dual BSD/GPL");
@@ -2408,6 +2408,7 @@ struct rtw89_chip_info {
const struct rtw89_hfc_param_ini *hfc_param_ini;
const struct rtw89_dle_mem *dle_mem;
u32 rf_base_addr[2];
+ u8 support_chanctx_num;
u8 support_bands;
bool support_bw160;
bool hw_sec_hdr;
@@ -3152,6 +3153,7 @@ struct rtw89_phy_efuse_gain {
struct rtw89_dev {
struct ieee80211_hw *hw;
struct device *dev;
+ const struct ieee80211_ops *ops;
bool dbcc_en;
struct rtw89_hw_scan_info scan_info;
@@ -3963,6 +3965,10 @@ int rtw89_core_init(struct rtw89_dev *rtwdev);
void rtw89_core_deinit(struct rtw89_dev *rtwdev);
int rtw89_core_register(struct rtw89_dev *rtwdev);
void rtw89_core_unregister(struct rtw89_dev *rtwdev);
+struct rtw89_dev *rtw89_alloc_ieee80211_hw(struct device *device,
+ u32 bus_data_size,
+ const struct rtw89_chip_info *chip);
+void rtw89_free_ieee80211_hw(struct rtw89_dev *rtwdev);
void rtw89_core_set_chip_txpwr(struct rtw89_dev *rtwdev);
void rtw89_get_default_chandef(struct cfg80211_chan_def *chandef);
void rtw89_set_channel(struct rtw89_dev *rtwdev);
@@ -3614,27 +3614,23 @@ static const struct rtw89_hci_ops rtw89_pci_ops = {
int rtw89_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{
- struct ieee80211_hw *hw;
struct rtw89_dev *rtwdev;
const struct rtw89_driver_info *info;
const struct rtw89_pci_info *pci_info;
- int driver_data_size;
int ret;
- driver_data_size = sizeof(struct rtw89_dev) + sizeof(struct rtw89_pci);
- hw = ieee80211_alloc_hw(driver_data_size, &rtw89_ops);
- if (!hw) {
+ info = (const struct rtw89_driver_info *)id->driver_data;
+
+ rtwdev = rtw89_alloc_ieee80211_hw(&pdev->dev,
+ sizeof(struct rtw89_pci),
+ info->chip);
+ if (!rtwdev) {
dev_err(&pdev->dev, "failed to allocate hw\n");
return -ENOMEM;
}
- info = (const struct rtw89_driver_info *)id->driver_data;
pci_info = info->bus.pci;
- rtwdev = hw->priv;
- rtwdev->hw = hw;
- rtwdev->dev = &pdev->dev;
- rtwdev->chip = info->chip;
rtwdev->pci_info = info->bus.pci;
rtwdev->hci.ops = &rtw89_pci_ops;
rtwdev->hci.type = RTW89_HCI_TYPE_PCIE;
@@ -3696,7 +3692,7 @@ int rtw89_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
err_core_deinit:
rtw89_core_deinit(rtwdev);
err_release_hw:
- ieee80211_free_hw(hw);
+ rtw89_free_ieee80211_hw(rtwdev);
return ret;
}
@@ -3715,7 +3711,7 @@ void rtw89_pci_remove(struct pci_dev *pdev)
rtw89_pci_clear_resource(rtwdev, pdev);
rtw89_pci_declaim_device(rtwdev, pdev);
rtw89_core_deinit(rtwdev);
- ieee80211_free_hw(hw);
+ rtw89_free_ieee80211_hw(rtwdev);
}
EXPORT_SYMBOL(rtw89_pci_remove);
@@ -2133,6 +2133,7 @@ const struct rtw89_chip_info rtw8852a_chip_info = {
.txpwr_factor_mac = 1,
.dig_table = &rtw89_8852a_phy_dig_table,
.tssi_dbw_table = NULL,
+ .support_chanctx_num = 0,
.support_bands = BIT(NL80211_BAND_2GHZ) |
BIT(NL80211_BAND_5GHZ),
.support_bw160 = false,
@@ -2981,6 +2981,7 @@ const struct rtw89_chip_info rtw8852c_chip_info = {
.txpwr_factor_mac = 1,
.dig_table = NULL,
.tssi_dbw_table = &rtw89_8852c_tssi_dbw_table,
+ .support_chanctx_num = 0,
.support_bands = BIT(NL80211_BAND_2GHZ) |
BIT(NL80211_BAND_5GHZ) |
BIT(NL80211_BAND_6GHZ),