1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198
|
/* 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 */
|