Skip to content

Commit 68d57a0

Browse files
srini-purelifiKalle Valo
authored andcommitted
wireless: add plfxlc driver for pureLiFi X, XL, XC devices
This is a driver for pureLiFi X, XL, XC devices which use light to transmit data, so they are not compatible with normal Wi-Fi devices. The driver uses separate NL80211_BAND_LC band to distinguish from Wi-Fi. The driver is based on 802.11 softMAC Architecture and uses native 802.11 for configuration and management. Station and Ad-Hoc modes are supported. The driver is compiled and tested in ARM, x86 architectures and compiled in powerpc architecture. This driver implementation has been based on the zd1211rw driver. Signed-off-by: Srinivasan Raju <[email protected]> Signed-off-by: Kalle Valo <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent 2fb822f commit 68d57a0

File tree

15 files changed

+2569
-0
lines changed

15 files changed

+2569
-0
lines changed

MAINTAINERS

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15970,6 +15970,12 @@ T: git git://linuxtv.org/media_tree.git
1597015970
F: Documentation/admin-guide/media/pulse8-cec.rst
1597115971
F: drivers/media/cec/usb/pulse8/
1597215972

15973+
PURELIFI PLFXLC DRIVER
15974+
M: Srinivasan Raju <[email protected]>
15975+
15976+
S: Supported
15977+
F: drivers/net/wireless/purelifi/plfxlc/
15978+
1597315979
PVRUSB2 VIDEO4LINUX DRIVER
1597415980
M: Mike Isely <[email protected]>
1597515981
L: [email protected] (subscribers-only)

drivers/net/wireless/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ source "drivers/net/wireless/intersil/Kconfig"
2828
source "drivers/net/wireless/marvell/Kconfig"
2929
source "drivers/net/wireless/mediatek/Kconfig"
3030
source "drivers/net/wireless/microchip/Kconfig"
31+
source "drivers/net/wireless/purelifi/Kconfig"
3132
source "drivers/net/wireless/ralink/Kconfig"
3233
source "drivers/net/wireless/realtek/Kconfig"
3334
source "drivers/net/wireless/rsi/Kconfig"

drivers/net/wireless/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ obj-$(CONFIG_WLAN_VENDOR_INTERSIL) += intersil/
1313
obj-$(CONFIG_WLAN_VENDOR_MARVELL) += marvell/
1414
obj-$(CONFIG_WLAN_VENDOR_MEDIATEK) += mediatek/
1515
obj-$(CONFIG_WLAN_VENDOR_MICROCHIP) += microchip/
16+
obj-$(CONFIG_WLAN_VENDOR_PURELIFI) += purelifi/
1617
obj-$(CONFIG_WLAN_VENDOR_RALINK) += ralink/
1718
obj-$(CONFIG_WLAN_VENDOR_REALTEK) += realtek/
1819
obj-$(CONFIG_WLAN_VENDOR_RSI) += rsi/
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# SPDX-License-Identifier: GPL-2.0-only
2+
config WLAN_VENDOR_PURELIFI
3+
bool "pureLiFi devices"
4+
default y
5+
help
6+
If you have a pureLiFi device, say Y.
7+
8+
Note that the answer to this question doesn't directly affect the
9+
kernel: saying N will just cause the configurator to skip all the
10+
questions about these cards. If you say Y, you will be asked for
11+
your specific card in the following questions.
12+
13+
if WLAN_VENDOR_PURELIFI
14+
15+
source "drivers/net/wireless/purelifi/plfxlc/Kconfig"
16+
17+
endif # WLAN_VENDOR_PURELIFI
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# SPDX-License-Identifier: GPL-2.0-only
2+
obj-$(CONFIG_PLFXLC) := plfxlc/
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# SPDX-License-Identifier: GPL-2.0-only
2+
config PLFXLC
3+
tristate "pureLiFi X, XL, XC device support"
4+
depends on CFG80211 && MAC80211 && USB
5+
help
6+
This option adds support for pureLiFi LiFi wireless USB
7+
adapters. The pureLiFi X, XL, XC USB devices are based on
8+
802.11 OFDM PHY but uses light as the transmission medium.
9+
The driver supports common 802.11 encryption/authentication
10+
methods including Open, WPA, WPA2-Personal and
11+
WPA2-Enterprise (802.1X).
12+
13+
To compile this driver as a module, choose m here. The module will
14+
be called plfxlc.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# SPDX-License-Identifier: GPL-2.0-only
2+
obj-$(CONFIG_PLFXLC) := plfxlc.o
3+
plfxlc-objs += chip.o firmware.o usb.o mac.o
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
// SPDX-License-Identifier: GPL-2.0-only
2+
/*
3+
* Copyright (c) 2021 pureLiFi
4+
*/
5+
6+
#include <linux/kernel.h>
7+
#include <linux/errno.h>
8+
9+
#include "chip.h"
10+
#include "mac.h"
11+
#include "usb.h"
12+
13+
void plfxlc_chip_init(struct plfxlc_chip *chip,
14+
struct ieee80211_hw *hw,
15+
struct usb_interface *intf)
16+
{
17+
memset(chip, 0, sizeof(*chip));
18+
mutex_init(&chip->mutex);
19+
plfxlc_usb_init(&chip->usb, hw, intf);
20+
}
21+
22+
void plfxlc_chip_release(struct plfxlc_chip *chip)
23+
{
24+
plfxlc_usb_release(&chip->usb);
25+
mutex_destroy(&chip->mutex);
26+
}
27+
28+
int plfxlc_set_beacon_interval(struct plfxlc_chip *chip, u16 interval,
29+
u8 dtim_period, int type)
30+
{
31+
if (!interval ||
32+
(chip->beacon_set &&
33+
le16_to_cpu(chip->beacon_interval) == interval))
34+
return 0;
35+
36+
chip->beacon_interval = cpu_to_le16(interval);
37+
chip->beacon_set = true;
38+
return plfxlc_usb_wreq(chip->usb.ez_usb,
39+
&chip->beacon_interval,
40+
sizeof(chip->beacon_interval),
41+
USB_REQ_BEACON_INTERVAL_WR);
42+
}
43+
44+
int plfxlc_chip_init_hw(struct plfxlc_chip *chip)
45+
{
46+
unsigned char *addr = plfxlc_mac_get_perm_addr(plfxlc_chip_to_mac(chip));
47+
struct usb_device *udev = interface_to_usbdev(chip->usb.intf);
48+
49+
pr_info("plfxlc chip %04x:%04x v%02x %pM %s\n",
50+
le16_to_cpu(udev->descriptor.idVendor),
51+
le16_to_cpu(udev->descriptor.idProduct),
52+
le16_to_cpu(udev->descriptor.bcdDevice),
53+
addr,
54+
plfxlc_speed(udev->speed));
55+
56+
return plfxlc_set_beacon_interval(chip, 100, 0, 0);
57+
}
58+
59+
int plfxlc_chip_switch_radio(struct plfxlc_chip *chip, u16 value)
60+
{
61+
int r;
62+
__le16 radio_on = cpu_to_le16(value);
63+
64+
r = plfxlc_usb_wreq(chip->usb.ez_usb, &radio_on,
65+
sizeof(value), USB_REQ_POWER_WR);
66+
if (r)
67+
dev_err(plfxlc_chip_dev(chip), "POWER_WR failed (%d)\n", r);
68+
return r;
69+
}
70+
71+
int plfxlc_chip_enable_rxtx(struct plfxlc_chip *chip)
72+
{
73+
plfxlc_usb_enable_tx(&chip->usb);
74+
return plfxlc_usb_enable_rx(&chip->usb);
75+
}
76+
77+
void plfxlc_chip_disable_rxtx(struct plfxlc_chip *chip)
78+
{
79+
u8 value = 0;
80+
81+
plfxlc_usb_wreq(chip->usb.ez_usb,
82+
&value, sizeof(value), USB_REQ_RXTX_WR);
83+
plfxlc_usb_disable_rx(&chip->usb);
84+
plfxlc_usb_disable_tx(&chip->usb);
85+
}
86+
87+
int plfxlc_chip_set_rate(struct plfxlc_chip *chip, u8 rate)
88+
{
89+
int r;
90+
91+
if (!chip)
92+
return -EINVAL;
93+
94+
r = plfxlc_usb_wreq(chip->usb.ez_usb,
95+
&rate, sizeof(rate), USB_REQ_RATE_WR);
96+
if (r)
97+
dev_err(plfxlc_chip_dev(chip), "RATE_WR failed (%d)\n", r);
98+
return r;
99+
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
/* SPDX-License-Identifier: GPL-2.0-only */
2+
/*
3+
* Copyright (c) 2021 pureLiFi
4+
*/
5+
6+
#ifndef PLFXLC_CHIP_H
7+
#define PLFXLC_CHIP_H
8+
9+
#include <net/mac80211.h>
10+
11+
#include "usb.h"
12+
13+
enum unit_type {
14+
STA = 0,
15+
AP = 1,
16+
};
17+
18+
enum {
19+
PLFXLC_RADIO_OFF = 0,
20+
PLFXLC_RADIO_ON = 1,
21+
};
22+
23+
struct plfxlc_chip {
24+
struct plfxlc_usb usb;
25+
struct mutex mutex; /* lock to protect chip data */
26+
enum unit_type unit_type;
27+
u16 link_led;
28+
u8 beacon_set;
29+
u16 beacon_interval;
30+
};
31+
32+
struct plfxlc_mc_hash {
33+
u32 low;
34+
u32 high;
35+
};
36+
37+
#define plfxlc_chip_dev(chip) (&(chip)->usb.intf->dev)
38+
39+
void plfxlc_chip_init(struct plfxlc_chip *chip,
40+
struct ieee80211_hw *hw,
41+
struct usb_interface *intf);
42+
43+
void plfxlc_chip_release(struct plfxlc_chip *chip);
44+
45+
void plfxlc_chip_disable_rxtx(struct plfxlc_chip *chip);
46+
47+
int plfxlc_chip_init_hw(struct plfxlc_chip *chip);
48+
49+
int plfxlc_chip_enable_rxtx(struct plfxlc_chip *chip);
50+
51+
int plfxlc_chip_set_rate(struct plfxlc_chip *chip, u8 rate);
52+
53+
int plfxlc_set_beacon_interval(struct plfxlc_chip *chip, u16 interval,
54+
u8 dtim_period, int type);
55+
56+
int plfxlc_chip_switch_radio(struct plfxlc_chip *chip, u16 value);
57+
58+
static inline struct plfxlc_chip *plfxlc_usb_to_chip(struct plfxlc_usb
59+
*usb)
60+
{
61+
return container_of(usb, struct plfxlc_chip, usb);
62+
}
63+
64+
static inline void plfxlc_mc_add_all(struct plfxlc_mc_hash *hash)
65+
{
66+
hash->low = 0xffffffff;
67+
hash->high = 0xffffffff;
68+
}
69+
70+
#endif /* PLFXLC_CHIP_H */

0 commit comments

Comments
 (0)