Skip to content

Commit

Permalink
wifi: Add support for specific WiFi 6E/7 USB and PCI devices
Browse files Browse the repository at this point in the history
This commit adds support for various WiFi 6E and WiFi 7 devices from major
manufacturers. The implementation includes:

1. Device Support:
   - MediaTek: MT7921, MT7922 (PCI), MT7925 (USB)
   - Realtek: RTL8852BE, RTL8852AE (PCI), RTL8852BU (USB)
   - Intel: AX211, AX411, BE200 (PCI)
   - Qualcomm: QCA6490, QCA6750, QCN9074 (PCI)
   - Broadcom: BCM4389, BCM4398 (PCI)
  • Loading branch information
rexinscfu committed Jan 27, 2025
1 parent 78e6cc3 commit 207799c
Show file tree
Hide file tree
Showing 4 changed files with 618 additions and 0 deletions.
8 changes: 8 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
obj-m += wifi67.o
obj-m += managh_wifi_usb.o
obj-m += managh_wifi_pci.o

wifi67-objs := \
src/core/main.o \
Expand All @@ -18,6 +20,12 @@ wifi67-objs := \
src/diag/hw_diag.o \
src/power/power_mgmt.o

managh_wifi_usb-objs := \
managh_usb&cards_suprtd/usb/usb_driver.o

managh_wifi_pci-objs := \
managh_usb&cards_suprtd/pci/pci_driver.o

# Test modules
obj-m += wifi67_test.o
obj-m += dma_test.o
Expand Down
232 changes: 232 additions & 0 deletions managh_usb&cards_suprtd/pci/pci_driver.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,232 @@
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/firmware.h>
#include "../supported_devices.h"
#include "../../include/core/wifi67.h"

/* PCI device private structure */
struct managh_pci_dev {
struct pci_dev *pdev;
struct wifi67_priv *wifi_priv;
void __iomem *mmio;

bool initialized;
bool suspended;

spinlock_t lock;

/* Device-specific information */
const struct managh_device_info *dev_info;
};

static int managh_pci_probe(struct pci_dev *pdev,
const struct pci_device_id *id)
{
struct managh_pci_dev *pci_dev;
struct wifi67_priv *wifi_priv;
const struct managh_device_info *dev_info = NULL;
int i, ret;

/* Find device info */
for (i = 0; i < ARRAY_SIZE(supported_devices); i++) {
if (supported_devices[i].vendor_id == pdev->vendor &&
supported_devices[i].device_id == pdev->device &&
!supported_devices[i].is_usb) {
dev_info = &supported_devices[i];
break;
}
}

if (!dev_info) {
pr_err("Unsupported PCI device %04x:%04x\n",
pdev->vendor, pdev->device);
return -ENODEV;
}

/* Allocate PCI device structure */
pci_dev = kzalloc(sizeof(*pci_dev), GFP_KERNEL);
if (!pci_dev)
return -ENOMEM;

/* Initialize PCI device */
pci_dev->pdev = pdev;
pci_dev->dev_info = dev_info;
spin_lock_init(&pci_dev->lock);

/* Enable PCI device */
ret = pci_enable_device(pdev);
if (ret)
goto err_free_dev;

/* Request PCI regions */
ret = pci_request_regions(pdev, "managh_wifi");
if (ret)
goto err_disable_device;

/* Set DMA mask */
ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
if (ret) {
ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
if (ret)
goto err_release_regions;
}

/* Map BAR0 */
pci_dev->mmio = pci_iomap(pdev, 0, 0);
if (!pci_dev->mmio) {
ret = -EIO;
goto err_release_regions;
}

/* Enable bus mastering */
pci_set_master(pdev);

/* Initialize WiFi core */
wifi_priv = wifi67_core_alloc();
if (!wifi_priv) {
ret = -ENOMEM;
goto err_iounmap;
}

pci_dev->wifi_priv = wifi_priv;
wifi_priv->dev = &pdev->dev;
wifi_priv->mmio = pci_dev->mmio;

/* Set device capabilities */
wifi_priv->features.has_6ghz = !!(dev_info->capabilities & DEVICE_CAP_WIFI_6E);
wifi_priv->features.has_7ghz = !!(dev_info->capabilities & DEVICE_CAP_WIFI_7);
wifi_priv->features.max_spatial_streams = dev_info->max_spatial_streams;
wifi_priv->features.max_bandwidth = dev_info->max_bandwidth_mhz;

/* Initialize WiFi core */
ret = wifi67_core_init(wifi_priv);
if (ret)
goto err_free_wifi;

/* Set driver data */
pci_set_drvdata(pdev, pci_dev);
pci_dev->initialized = true;

pr_info("Initialized %s PCI WiFi device\n", dev_info->name);
return 0;

err_free_wifi:
wifi67_core_free(wifi_priv);
err_iounmap:
pci_iounmap(pdev, pci_dev->mmio);
err_release_regions:
pci_release_regions(pdev);
err_disable_device:
pci_disable_device(pdev);
err_free_dev:
kfree(pci_dev);
return ret;
}

static void managh_pci_remove(struct pci_dev *pdev)
{
struct managh_pci_dev *pci_dev = pci_get_drvdata(pdev);

if (!pci_dev)
return;

/* Cleanup WiFi core */
if (pci_dev->wifi_priv) {
wifi67_core_deinit(pci_dev->wifi_priv);
wifi67_core_free(pci_dev->wifi_priv);
}

/* Cleanup PCI device */
pci_iounmap(pdev, pci_dev->mmio);
pci_release_regions(pdev);
pci_disable_device(pdev);
pci_set_drvdata(pdev, NULL);
kfree(pci_dev);

pr_info("PCI WiFi device removed\n");
}

static int managh_pci_suspend(struct pci_dev *pdev, pm_message_t state)
{
struct managh_pci_dev *pci_dev = pci_get_drvdata(pdev);

if (!pci_dev)
return 0;

wifi67_core_suspend(pci_dev->wifi_priv);
pci_save_state(pdev);
pci_disable_device(pdev);
pci_set_power_state(pdev, pci_choose_state(pdev, state));
pci_dev->suspended = true;

return 0;
}

static int managh_pci_resume(struct pci_dev *pdev)
{
struct managh_pci_dev *pci_dev = pci_get_drvdata(pdev);
int ret;

if (!pci_dev)
return 0;

pci_set_power_state(pdev, PCI_D0);
pci_restore_state(pdev);

ret = pci_enable_device(pdev);
if (ret)
return ret;

pci_set_master(pdev);

ret = wifi67_core_resume(pci_dev->wifi_priv);
if (ret)
return ret;

pci_dev->suspended = false;
return 0;
}

/* PCI device ID table */
static const struct pci_device_id managh_pci_ids[] = {
/* MediaTek */
{ PCI_DEVICE(MT_VENDOR_ID, MT7921_PCI_DEVICE_ID) },
{ PCI_DEVICE(MT_VENDOR_ID, MT7922_PCI_DEVICE_ID) },

/* Realtek */
{ PCI_DEVICE(RTK_VENDOR_ID, RTL8852BE_DEVICE_ID) },
{ PCI_DEVICE(RTK_VENDOR_ID, RTL8852AE_DEVICE_ID) },

/* Intel */
{ PCI_DEVICE(INTEL_VENDOR_ID, AX211_DEVICE_ID) },
{ PCI_DEVICE(INTEL_VENDOR_ID, AX411_DEVICE_ID) },
{ PCI_DEVICE(INTEL_VENDOR_ID, BE200_DEVICE_ID) },

/* Qualcomm */
{ PCI_DEVICE(QCA_VENDOR_ID, QCA6490_DEVICE_ID) },
{ PCI_DEVICE(QCA_VENDOR_ID, QCA6750_DEVICE_ID) },
{ PCI_DEVICE(QCA_VENDOR_ID, QCN9074_DEVICE_ID) },

/* Broadcom */
{ PCI_DEVICE(BCM_VENDOR_ID, BCM4389_DEVICE_ID) },
{ PCI_DEVICE(BCM_VENDOR_ID, BCM4398_DEVICE_ID) },

{ }
};
MODULE_DEVICE_TABLE(pci, managh_pci_ids);

/* PCI driver structure */
static struct pci_driver managh_pci_driver = {
.name = "managh_wifi_pci",
.id_table = managh_pci_ids,
.probe = managh_pci_probe,
.remove = managh_pci_remove,
.suspend = managh_pci_suspend,
.resume = managh_pci_resume,
};

module_pci_driver(managh_pci_driver);

MODULE_AUTHOR("Your Name");
MODULE_DESCRIPTION("Managh WiFi PCI Driver");
MODULE_LICENSE("GPL");
Loading

0 comments on commit 207799c

Please sign in to comment.