forked from torvalds/linux
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
wireless: Initial driver submission for pureLiFi STA devices
This introduces the pureLiFi LiFi driver for LiFi-X, LiFi-XC and LiFi-XL USB devices. This driver implementation has been based on the zd1211rw driver. Driver is based on 802.11 softMAC Architecture and uses native 802.11 for configuration and management. The driver is compiled and tested in ARM, x86 architectures and compiled in powerpc architecture. Signed-off-by: Srinivasan Raju <srini.raju@purelifi.com>
- Loading branch information
1 parent
16ad7b4
commit 5d8fb5c
Showing
15 changed files
with
2,807 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
# SPDX-License-Identifier: GPL-2.0-only | ||
config WLAN_VENDOR_PURELIFI | ||
bool "pureLiFi devices" | ||
default y | ||
help | ||
If you have a pureLiFi device, say Y. | ||
|
||
Note that the answer to this question doesn't directly affect the | ||
kernel: saying N will just cause the configurator to skip all the | ||
questions about these cards. If you say Y, you will be asked for | ||
your specific card in the following questions. | ||
|
||
if WLAN_VENDOR_PURELIFI | ||
|
||
source "drivers/net/wireless/purelifi/plfxlc/Kconfig" | ||
|
||
endif # WLAN_VENDOR_PURELIFI |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
# SPDX-License-Identifier: GPL-2.0-only | ||
obj-$(CONFIG_WLAN_VENDOR_PURELIFI) := plfxlc/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
# SPDX-License-Identifier: GPL-2.0-only | ||
config PLFXLC | ||
|
||
tristate "pureLiFi X, XL, XC device support" | ||
depends on CFG80211 && MAC80211 && USB | ||
help | ||
This driver makes the adapter appear as a normal WLAN interface. | ||
|
||
The pureLiFi device requires external STA firmware to be loaded. | ||
|
||
To compile this driver as a module, choose M here: the module will | ||
be called purelifi. | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# SPDX-License-Identifier: GPL-2.0-only | ||
obj-$(CONFIG_PLFXLC) := plfxlc.o | ||
plfxlc-objs += chip.o firmware.o usb.o mac.o |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
// SPDX-License-Identifier: GPL-2.0-only | ||
/* | ||
* Copyright (c) 2021 pureLiFi | ||
*/ | ||
|
||
#include <linux/kernel.h> | ||
#include <linux/errno.h> | ||
|
||
#include "chip.h" | ||
#include "mac.h" | ||
#include "usb.h" | ||
|
||
void purelifi_chip_init(struct purelifi_chip *chip, | ||
struct ieee80211_hw *hw, | ||
struct usb_interface *intf) | ||
{ | ||
memset(chip, 0, sizeof(*chip)); | ||
mutex_init(&chip->mutex); | ||
purelifi_usb_init(&chip->usb, hw, intf); | ||
} | ||
|
||
void purelifi_chip_release(struct purelifi_chip *chip) | ||
{ | ||
purelifi_usb_release(&chip->usb); | ||
mutex_destroy(&chip->mutex); | ||
} | ||
|
||
int purelifi_set_beacon_interval(struct purelifi_chip *chip, u16 interval, | ||
u8 dtim_period, int type) | ||
{ | ||
if (!interval || | ||
(chip->beacon_set && chip->beacon_interval == interval)) { | ||
return 0; | ||
} | ||
|
||
chip->beacon_interval = interval; | ||
chip->beacon_set = true; | ||
return usb_write_req((const u8 *)&chip->beacon_interval, | ||
sizeof(chip->beacon_interval), | ||
USB_REQ_BEACON_INTERVAL_WR); | ||
} | ||
|
||
int purelifi_chip_init_hw(struct purelifi_chip *chip) | ||
{ | ||
u8 *addr = purelifi_mac_get_perm_addr(purelifi_chip_to_mac(chip)); | ||
struct usb_device *udev = interface_to_usbdev(chip->usb.intf); | ||
|
||
pr_info("purelifi chip %02x:%02x v%02x %02x-%02x-%02x %s\n", | ||
le16_to_cpu(udev->descriptor.idVendor), | ||
le16_to_cpu(udev->descriptor.idProduct), | ||
le16_to_cpu(udev->descriptor.bcdDevice), | ||
addr[0], addr[1], addr[2], | ||
purelifi_speed(udev->speed)); | ||
|
||
return purelifi_set_beacon_interval(chip, 100, 0, 0); | ||
} | ||
|
||
int purelifi_chip_switch_radio(struct purelifi_chip *chip, u32 value) | ||
{ | ||
int r; | ||
|
||
r = usb_write_req((const u8 *)&value, sizeof(value), USB_REQ_POWER_WR); | ||
if (r) | ||
dev_err(purelifi_chip_dev(chip), "POWER_WR failed (%d)\n", r); | ||
return r; | ||
} | ||
|
||
int purelifi_chip_enable_rxtx(struct purelifi_chip *chip) | ||
{ | ||
purelifi_usb_enable_tx(&chip->usb); | ||
return purelifi_usb_enable_rx(&chip->usb); | ||
} | ||
|
||
void purelifi_chip_disable_rxtx(struct purelifi_chip *chip) | ||
{ | ||
static const u8 value; | ||
|
||
usb_write_req(&value, sizeof(value), USB_REQ_RXTX_WR); | ||
purelifi_usb_disable_rx(&chip->usb); | ||
purelifi_usb_disable_tx(&chip->usb); | ||
} | ||
|
||
int purelifi_chip_set_rate(struct purelifi_chip *chip, u8 rate) | ||
{ | ||
int r; | ||
|
||
if (!chip) | ||
return -EINVAL; | ||
|
||
r = usb_write_req(&rate, sizeof(rate), USB_REQ_RATE_WR); | ||
if (r) | ||
dev_err(purelifi_chip_dev(chip), "RATE_WR failed (%d)\n", r); | ||
return r; | ||
} | ||
|
||
MODULE_LICENSE("GPL"); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
/* SPDX-License-Identifier: GPL-2.0-only */ | ||
/* | ||
* Copyright (c) 2021 pureLiFi | ||
*/ | ||
|
||
#ifndef _LF_X_CHIP_H | ||
#define _LF_X_CHIP_H | ||
|
||
#include <net/mac80211.h> | ||
|
||
#include "usb.h" | ||
|
||
enum unit_type_t { | ||
STA = 0, | ||
AP = 1, | ||
}; | ||
|
||
struct purelifi_chip { | ||
struct purelifi_usb usb; | ||
struct mutex mutex; /* lock to protect chip data */ | ||
enum unit_type_t unit_type; | ||
u16 link_led; | ||
u8 beacon_set; | ||
u16 beacon_interval; | ||
}; | ||
|
||
struct purelifi_mc_hash { | ||
u32 low; | ||
u32 high; | ||
}; | ||
|
||
#define purelifi_chip_dev(chip) (&(chip)->usb.intf->dev) | ||
|
||
void purelifi_chip_init(struct purelifi_chip *chip, | ||
struct ieee80211_hw *hw, | ||
struct usb_interface *intf); | ||
|
||
void purelifi_chip_release(struct purelifi_chip *chip); | ||
|
||
void purelifi_chip_disable_rxtx(struct purelifi_chip *chip); | ||
|
||
int purelifi_chip_init_hw(struct purelifi_chip *chip); | ||
|
||
int purelifi_chip_enable_rxtx(struct purelifi_chip *chip); | ||
|
||
int purelifi_chip_set_rate(struct purelifi_chip *chip, u8 rate); | ||
|
||
int purelifi_set_beacon_interval(struct purelifi_chip *chip, u16 interval, | ||
u8 dtim_period, int type); | ||
|
||
int purelifi_chip_switch_radio(struct purelifi_chip *chip, u32 value); | ||
|
||
static inline struct purelifi_chip *purelifi_usb_to_chip(struct purelifi_usb | ||
*usb) | ||
{ | ||
return container_of(usb, struct purelifi_chip, usb); | ||
} | ||
|
||
static inline void purelifi_mc_clear(struct purelifi_mc_hash *hash) | ||
{ | ||
hash->low = 0; | ||
/* The interfaces must always received broadcasts. | ||
* The hash of the broadcast address ff:ff:ff:ff:ff:ff is 63. | ||
*/ | ||
hash->high = 0x80000000; | ||
} | ||
|
||
static inline void purelifi_mc_add_all(struct purelifi_mc_hash *hash) | ||
{ | ||
hash->low = 0xffffffff; | ||
hash->high = 0xffffffff; | ||
} | ||
|
||
static inline void purelifi_mc_add_addr(struct purelifi_mc_hash *hash, | ||
u8 *addr) | ||
{ | ||
unsigned int i = addr[5] >> 2; | ||
|
||
if (i < 32) | ||
hash->low |= 1 << i; | ||
else | ||
hash->high |= 1 << (i - 32); | ||
} | ||
#endif /* _LF_X_CHIP_H */ |
Oops, something went wrong.