mirror of https://github.com/Qortal/Brooklyn
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
198 lines
5.1 KiB
198 lines
5.1 KiB
/* SPDX-License-Identifier: GPL-2.0-only */ |
|
/* |
|
* Copyright (c) 2021 pureLiFi |
|
*/ |
|
|
|
#ifndef PLFXLC_USB_H |
|
#define PLFXLC_USB_H |
|
|
|
#include <linux/completion.h> |
|
#include <linux/netdevice.h> |
|
#include <linux/spinlock.h> |
|
#include <linux/skbuff.h> |
|
#include <linux/usb.h> |
|
|
|
#include "intf.h" |
|
|
|
#define USB_BULK_MSG_TIMEOUT_MS 2000 |
|
|
|
#define PURELIFI_X_VENDOR_ID_0 0x16C1 |
|
#define PURELIFI_X_PRODUCT_ID_0 0x1CDE |
|
#define PURELIFI_XC_VENDOR_ID_0 0x2EF5 |
|
#define PURELIFI_XC_PRODUCT_ID_0 0x0008 |
|
#define PURELIFI_XL_VENDOR_ID_0 0x2EF5 |
|
#define PURELIFI_XL_PRODUCT_ID_0 0x000A /* Station */ |
|
|
|
#define PLF_FPGA_STATUS_LEN 2 |
|
#define PLF_FPGA_STATE_LEN 9 |
|
#define PLF_BULK_TLEN 16384 |
|
#define PLF_FPGA_MG 6 /* Magic check */ |
|
#define PLF_XL_BUF_LEN 64 |
|
#define PLF_MSG_STATUS_OFFSET 7 |
|
|
|
#define PLF_USB_TIMEOUT 1000 |
|
#define PLF_MSLEEP_TIME 200 |
|
|
|
#define PURELIFI_URB_RETRY_MAX 5 |
|
|
|
#define plfxlc_usb_dev(usb) (&(usb)->intf->dev) |
|
|
|
/* Tx retry backoff timer (in milliseconds) */ |
|
#define TX_RETRY_BACKOFF_MS 10 |
|
#define STA_QUEUE_CLEANUP_MS 5000 |
|
|
|
/* Tx retry backoff timer (in jiffies) */ |
|
#define TX_RETRY_BACKOFF_JIFF ((TX_RETRY_BACKOFF_MS * HZ) / 1000) |
|
#define STA_QUEUE_CLEANUP_JIFF ((STA_QUEUE_CLEANUP_MS * HZ) / 1000) |
|
|
|
/* Ensures that MAX_TRANSFER_SIZE is even. */ |
|
#define MAX_TRANSFER_SIZE (USB_MAX_TRANSFER_SIZE & ~1) |
|
#define plfxlc_urb_dev(urb) (&(urb)->dev->dev) |
|
|
|
#define STATION_FIFO_ALMOST_FULL_MESSAGE 0 |
|
#define STATION_FIFO_ALMOST_FULL_NOT_MESSAGE 1 |
|
#define STATION_CONNECT_MESSAGE 2 |
|
#define STATION_DISCONNECT_MESSAGE 3 |
|
|
|
int plfxlc_usb_wreq(struct usb_interface *ez_usb, void *buffer, int buffer_len, |
|
enum plf_usb_req_enum usb_req_id); |
|
void plfxlc_tx_urb_complete(struct urb *urb); |
|
|
|
enum { |
|
USB_MAX_RX_SIZE = 4800, |
|
USB_MAX_EP_INT_BUFFER = 64, |
|
}; |
|
|
|
struct plfxlc_usb_interrupt { |
|
spinlock_t lock; /* spin lock for usb interrupt buffer */ |
|
struct urb *urb; |
|
void *buffer; |
|
int interval; |
|
}; |
|
|
|
#define RX_URBS_COUNT 5 |
|
|
|
struct plfxlc_usb_rx { |
|
spinlock_t lock; /* spin lock for rx urb */ |
|
struct mutex setup_mutex; /* mutex lockt for rx urb */ |
|
u8 fragment[2 * USB_MAX_RX_SIZE]; |
|
unsigned int fragment_length; |
|
unsigned int usb_packet_size; |
|
struct urb **urbs; |
|
int urbs_count; |
|
}; |
|
|
|
struct plf_station { |
|
/* 7...3 | 2 | 1 | 0 | |
|
* Reserved | Heartbeat | FIFO full | Connected | |
|
*/ |
|
unsigned char flag; |
|
unsigned char mac[ETH_ALEN]; |
|
struct sk_buff_head data_list; |
|
}; |
|
|
|
struct plfxlc_firmware_file { |
|
u32 total_files; |
|
u32 total_size; |
|
u32 size; |
|
u32 start_addr; |
|
u32 control_packets; |
|
} __packed; |
|
|
|
#define STATION_CONNECTED_FLAG 0x1 |
|
#define STATION_FIFO_FULL_FLAG 0x2 |
|
#define STATION_HEARTBEAT_FLAG 0x4 |
|
#define STATION_ACTIVE_FLAG 0xFD |
|
|
|
#define PURELIFI_SERIAL_LEN 256 |
|
#define STA_BROADCAST_INDEX (AP_USER_LIMIT) |
|
#define MAX_STA_NUM (AP_USER_LIMIT + 1) |
|
|
|
struct plfxlc_usb_tx { |
|
unsigned long enabled; |
|
spinlock_t lock; /* spinlock for USB tx */ |
|
u8 mac_fifo_full; |
|
struct sk_buff_head submitted_skbs; |
|
struct usb_anchor submitted; |
|
int submitted_urbs; |
|
bool stopped; |
|
struct timer_list tx_retry_timer; |
|
struct plf_station station[MAX_STA_NUM]; |
|
}; |
|
|
|
/* Contains the usb parts. The structure doesn't require a lock because intf |
|
* will not be changed after initialization. |
|
*/ |
|
struct plfxlc_usb { |
|
struct timer_list sta_queue_cleanup; |
|
struct plfxlc_usb_rx rx; |
|
struct plfxlc_usb_tx tx; |
|
struct usb_interface *intf; |
|
struct usb_interface *ez_usb; |
|
u8 req_buf[64]; /* plfxlc_usb_iowrite16v needs 62 bytes */ |
|
u8 sidx; /* store last served */ |
|
bool rx_usb_enabled; |
|
bool initialized; |
|
bool was_running; |
|
bool link_up; |
|
}; |
|
|
|
enum endpoints { |
|
EP_DATA_IN = 2, |
|
EP_DATA_OUT = 8, |
|
}; |
|
|
|
enum devicetype { |
|
DEVICE_LIFI_X = 0, |
|
DEVICE_LIFI_XC = 1, |
|
DEVICE_LIFI_XL = 1, |
|
}; |
|
|
|
enum { |
|
PLF_BIT_ENABLED = 1, |
|
PLF_BIT_MAX = 2, |
|
}; |
|
|
|
int plfxlc_usb_wreq_async(struct plfxlc_usb *usb, const u8 *buffer, |
|
int buffer_len, enum plf_usb_req_enum usb_req_id, |
|
usb_complete_t complete_fn, void *context); |
|
|
|
static inline struct usb_device * |
|
plfxlc_usb_to_usbdev(struct plfxlc_usb *usb) |
|
{ |
|
return interface_to_usbdev(usb->intf); |
|
} |
|
|
|
static inline struct ieee80211_hw * |
|
plfxlc_intf_to_hw(struct usb_interface *intf) |
|
{ |
|
return usb_get_intfdata(intf); |
|
} |
|
|
|
static inline struct ieee80211_hw * |
|
plfxlc_usb_to_hw(struct plfxlc_usb *usb) |
|
{ |
|
return plfxlc_intf_to_hw(usb->intf); |
|
} |
|
|
|
void plfxlc_usb_init(struct plfxlc_usb *usb, struct ieee80211_hw *hw, |
|
struct usb_interface *intf); |
|
void plfxlc_send_packet_from_data_queue(struct plfxlc_usb *usb); |
|
void plfxlc_usb_release(struct plfxlc_usb *usb); |
|
void plfxlc_usb_disable_rx(struct plfxlc_usb *usb); |
|
void plfxlc_usb_enable_tx(struct plfxlc_usb *usb); |
|
void plfxlc_usb_disable_tx(struct plfxlc_usb *usb); |
|
int plfxlc_usb_tx(struct plfxlc_usb *usb, struct sk_buff *skb); |
|
int plfxlc_usb_enable_rx(struct plfxlc_usb *usb); |
|
int plfxlc_usb_init_hw(struct plfxlc_usb *usb); |
|
const char *plfxlc_speed(enum usb_device_speed speed); |
|
|
|
/* Firmware declarations */ |
|
int plfxlc_download_xl_firmware(struct usb_interface *intf); |
|
int plfxlc_download_fpga(struct usb_interface *intf); |
|
|
|
int plfxlc_upload_mac_and_serial(struct usb_interface *intf, |
|
unsigned char *hw_address, |
|
unsigned char *serial_number); |
|
|
|
#endif /* PLFXLC_USB_H */
|
|
|