162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Copyright (c) 2021 pureLiFi
462306a36Sopenharmony_ci */
562306a36Sopenharmony_ci
662306a36Sopenharmony_ci#ifndef PLFXLC_USB_H
762306a36Sopenharmony_ci#define PLFXLC_USB_H
862306a36Sopenharmony_ci
962306a36Sopenharmony_ci#include <linux/completion.h>
1062306a36Sopenharmony_ci#include <linux/netdevice.h>
1162306a36Sopenharmony_ci#include <linux/spinlock.h>
1262306a36Sopenharmony_ci#include <linux/skbuff.h>
1362306a36Sopenharmony_ci#include <linux/usb.h>
1462306a36Sopenharmony_ci
1562306a36Sopenharmony_ci#include "intf.h"
1662306a36Sopenharmony_ci
1762306a36Sopenharmony_ci#define USB_BULK_MSG_TIMEOUT_MS 2000
1862306a36Sopenharmony_ci
1962306a36Sopenharmony_ci#define PURELIFI_X_VENDOR_ID_0   0x16C1
2062306a36Sopenharmony_ci#define PURELIFI_X_PRODUCT_ID_0  0x1CDE
2162306a36Sopenharmony_ci#define PURELIFI_XC_VENDOR_ID_0  0x2EF5
2262306a36Sopenharmony_ci#define PURELIFI_XC_PRODUCT_ID_0 0x0008
2362306a36Sopenharmony_ci#define PURELIFI_XL_VENDOR_ID_0  0x2EF5
2462306a36Sopenharmony_ci#define PURELIFI_XL_PRODUCT_ID_0 0x000A /* Station */
2562306a36Sopenharmony_ci
2662306a36Sopenharmony_ci#define PLF_FPGA_STATUS_LEN 2
2762306a36Sopenharmony_ci#define PLF_FPGA_STATE_LEN 9
2862306a36Sopenharmony_ci#define PLF_BULK_TLEN 16384
2962306a36Sopenharmony_ci#define PLF_FPGA_MG 6 /* Magic check */
3062306a36Sopenharmony_ci#define PLF_XL_BUF_LEN 64
3162306a36Sopenharmony_ci#define PLF_MSG_STATUS_OFFSET 7
3262306a36Sopenharmony_ci
3362306a36Sopenharmony_ci#define PLF_USB_TIMEOUT 1000
3462306a36Sopenharmony_ci#define PLF_MSLEEP_TIME 200
3562306a36Sopenharmony_ci
3662306a36Sopenharmony_ci#define PURELIFI_URB_RETRY_MAX 5
3762306a36Sopenharmony_ci
3862306a36Sopenharmony_ci#define plfxlc_usb_dev(usb) (&(usb)->intf->dev)
3962306a36Sopenharmony_ci
4062306a36Sopenharmony_ci/* Tx retry backoff timer (in milliseconds) */
4162306a36Sopenharmony_ci#define TX_RETRY_BACKOFF_MS 10
4262306a36Sopenharmony_ci#define STA_QUEUE_CLEANUP_MS 5000
4362306a36Sopenharmony_ci
4462306a36Sopenharmony_ci/* Tx retry backoff timer (in jiffies) */
4562306a36Sopenharmony_ci#define TX_RETRY_BACKOFF_JIFF ((TX_RETRY_BACKOFF_MS * HZ) / 1000)
4662306a36Sopenharmony_ci#define STA_QUEUE_CLEANUP_JIFF ((STA_QUEUE_CLEANUP_MS * HZ) / 1000)
4762306a36Sopenharmony_ci
4862306a36Sopenharmony_ci/* Ensures that MAX_TRANSFER_SIZE is even. */
4962306a36Sopenharmony_ci#define MAX_TRANSFER_SIZE (USB_MAX_TRANSFER_SIZE & ~1)
5062306a36Sopenharmony_ci#define plfxlc_urb_dev(urb) (&(urb)->dev->dev)
5162306a36Sopenharmony_ci
5262306a36Sopenharmony_ci#define STATION_FIFO_ALMOST_FULL_MESSAGE     0
5362306a36Sopenharmony_ci#define STATION_FIFO_ALMOST_FULL_NOT_MESSAGE 1
5462306a36Sopenharmony_ci#define STATION_CONNECT_MESSAGE              2
5562306a36Sopenharmony_ci#define STATION_DISCONNECT_MESSAGE           3
5662306a36Sopenharmony_ci
5762306a36Sopenharmony_ciint plfxlc_usb_wreq(struct usb_interface *ez_usb, void *buffer, int buffer_len,
5862306a36Sopenharmony_ci		    enum plf_usb_req_enum usb_req_id);
5962306a36Sopenharmony_civoid plfxlc_tx_urb_complete(struct urb *urb);
6062306a36Sopenharmony_ci
6162306a36Sopenharmony_cienum {
6262306a36Sopenharmony_ci	USB_MAX_RX_SIZE       = 4800,
6362306a36Sopenharmony_ci	USB_MAX_EP_INT_BUFFER = 64,
6462306a36Sopenharmony_ci};
6562306a36Sopenharmony_ci
6662306a36Sopenharmony_cistruct plfxlc_usb_interrupt {
6762306a36Sopenharmony_ci	spinlock_t lock; /* spin lock for usb interrupt buffer */
6862306a36Sopenharmony_ci	struct urb *urb;
6962306a36Sopenharmony_ci	void *buffer;
7062306a36Sopenharmony_ci	int interval;
7162306a36Sopenharmony_ci};
7262306a36Sopenharmony_ci
7362306a36Sopenharmony_ci#define RX_URBS_COUNT 5
7462306a36Sopenharmony_ci
7562306a36Sopenharmony_cistruct plfxlc_usb_rx {
7662306a36Sopenharmony_ci	spinlock_t lock; /* spin lock for rx urb */
7762306a36Sopenharmony_ci	struct mutex setup_mutex; /* mutex lockt for rx urb */
7862306a36Sopenharmony_ci	u8 fragment[2 * USB_MAX_RX_SIZE];
7962306a36Sopenharmony_ci	unsigned int fragment_length;
8062306a36Sopenharmony_ci	unsigned int usb_packet_size;
8162306a36Sopenharmony_ci	struct urb **urbs;
8262306a36Sopenharmony_ci	int urbs_count;
8362306a36Sopenharmony_ci};
8462306a36Sopenharmony_ci
8562306a36Sopenharmony_cistruct plf_station {
8662306a36Sopenharmony_ci   /*  7...3    |    2      |     1     |     0	    |
8762306a36Sopenharmony_ci    * Reserved  | Heartbeat | FIFO full | Connected |
8862306a36Sopenharmony_ci    */
8962306a36Sopenharmony_ci	unsigned char flag;
9062306a36Sopenharmony_ci	unsigned char mac[ETH_ALEN];
9162306a36Sopenharmony_ci	struct sk_buff_head data_list;
9262306a36Sopenharmony_ci};
9362306a36Sopenharmony_ci
9462306a36Sopenharmony_cistruct plfxlc_firmware_file {
9562306a36Sopenharmony_ci	u32 total_files;
9662306a36Sopenharmony_ci	u32 total_size;
9762306a36Sopenharmony_ci	u32 size;
9862306a36Sopenharmony_ci	u32 start_addr;
9962306a36Sopenharmony_ci	u32 control_packets;
10062306a36Sopenharmony_ci} __packed;
10162306a36Sopenharmony_ci
10262306a36Sopenharmony_ci#define STATION_CONNECTED_FLAG 0x1
10362306a36Sopenharmony_ci#define STATION_FIFO_FULL_FLAG 0x2
10462306a36Sopenharmony_ci#define STATION_HEARTBEAT_FLAG 0x4
10562306a36Sopenharmony_ci#define STATION_ACTIVE_FLAG    0xFD
10662306a36Sopenharmony_ci
10762306a36Sopenharmony_ci#define PURELIFI_SERIAL_LEN 256
10862306a36Sopenharmony_ci#define STA_BROADCAST_INDEX (AP_USER_LIMIT)
10962306a36Sopenharmony_ci#define MAX_STA_NUM         (AP_USER_LIMIT + 1)
11062306a36Sopenharmony_ci
11162306a36Sopenharmony_cistruct plfxlc_usb_tx {
11262306a36Sopenharmony_ci	unsigned long enabled;
11362306a36Sopenharmony_ci	spinlock_t lock; /* spinlock for USB tx */
11462306a36Sopenharmony_ci	u8 mac_fifo_full;
11562306a36Sopenharmony_ci	struct sk_buff_head submitted_skbs;
11662306a36Sopenharmony_ci	struct usb_anchor submitted;
11762306a36Sopenharmony_ci	int submitted_urbs;
11862306a36Sopenharmony_ci	bool stopped;
11962306a36Sopenharmony_ci	struct timer_list tx_retry_timer;
12062306a36Sopenharmony_ci	struct plf_station station[MAX_STA_NUM];
12162306a36Sopenharmony_ci};
12262306a36Sopenharmony_ci
12362306a36Sopenharmony_ci/* Contains the usb parts. The structure doesn't require a lock because intf
12462306a36Sopenharmony_ci * will not be changed after initialization.
12562306a36Sopenharmony_ci */
12662306a36Sopenharmony_cistruct plfxlc_usb {
12762306a36Sopenharmony_ci	struct timer_list sta_queue_cleanup;
12862306a36Sopenharmony_ci	struct plfxlc_usb_rx rx;
12962306a36Sopenharmony_ci	struct plfxlc_usb_tx tx;
13062306a36Sopenharmony_ci	struct usb_interface *intf;
13162306a36Sopenharmony_ci	struct usb_interface *ez_usb;
13262306a36Sopenharmony_ci	u8 req_buf[64]; /* plfxlc_usb_iowrite16v needs 62 bytes */
13362306a36Sopenharmony_ci	u8 sidx; /* store last served */
13462306a36Sopenharmony_ci	bool rx_usb_enabled;
13562306a36Sopenharmony_ci	bool initialized;
13662306a36Sopenharmony_ci	bool was_running;
13762306a36Sopenharmony_ci	bool link_up;
13862306a36Sopenharmony_ci};
13962306a36Sopenharmony_ci
14062306a36Sopenharmony_cienum endpoints {
14162306a36Sopenharmony_ci	EP_DATA_IN  = 2,
14262306a36Sopenharmony_ci	EP_DATA_OUT = 8,
14362306a36Sopenharmony_ci};
14462306a36Sopenharmony_ci
14562306a36Sopenharmony_cienum devicetype {
14662306a36Sopenharmony_ci	DEVICE_LIFI_X  = 0,
14762306a36Sopenharmony_ci	DEVICE_LIFI_XC  = 1,
14862306a36Sopenharmony_ci	DEVICE_LIFI_XL  = 1,
14962306a36Sopenharmony_ci};
15062306a36Sopenharmony_ci
15162306a36Sopenharmony_cienum {
15262306a36Sopenharmony_ci	PLF_BIT_ENABLED = 1,
15362306a36Sopenharmony_ci	PLF_BIT_MAX = 2,
15462306a36Sopenharmony_ci};
15562306a36Sopenharmony_ci
15662306a36Sopenharmony_ciint plfxlc_usb_wreq_async(struct plfxlc_usb *usb, const u8 *buffer,
15762306a36Sopenharmony_ci			  int buffer_len, enum plf_usb_req_enum usb_req_id,
15862306a36Sopenharmony_ci			  usb_complete_t complete_fn, void *context);
15962306a36Sopenharmony_ci
16062306a36Sopenharmony_cistatic inline struct usb_device *
16162306a36Sopenharmony_ciplfxlc_usb_to_usbdev(struct plfxlc_usb *usb)
16262306a36Sopenharmony_ci{
16362306a36Sopenharmony_ci	return interface_to_usbdev(usb->intf);
16462306a36Sopenharmony_ci}
16562306a36Sopenharmony_ci
16662306a36Sopenharmony_cistatic inline struct ieee80211_hw *
16762306a36Sopenharmony_ciplfxlc_intf_to_hw(struct usb_interface *intf)
16862306a36Sopenharmony_ci{
16962306a36Sopenharmony_ci	return usb_get_intfdata(intf);
17062306a36Sopenharmony_ci}
17162306a36Sopenharmony_ci
17262306a36Sopenharmony_cistatic inline struct ieee80211_hw *
17362306a36Sopenharmony_ciplfxlc_usb_to_hw(struct plfxlc_usb *usb)
17462306a36Sopenharmony_ci{
17562306a36Sopenharmony_ci	return plfxlc_intf_to_hw(usb->intf);
17662306a36Sopenharmony_ci}
17762306a36Sopenharmony_ci
17862306a36Sopenharmony_civoid plfxlc_usb_init(struct plfxlc_usb *usb, struct ieee80211_hw *hw,
17962306a36Sopenharmony_ci		     struct usb_interface *intf);
18062306a36Sopenharmony_civoid plfxlc_send_packet_from_data_queue(struct plfxlc_usb *usb);
18162306a36Sopenharmony_civoid plfxlc_usb_release(struct plfxlc_usb *usb);
18262306a36Sopenharmony_civoid plfxlc_usb_disable_rx(struct plfxlc_usb *usb);
18362306a36Sopenharmony_civoid plfxlc_usb_enable_tx(struct plfxlc_usb *usb);
18462306a36Sopenharmony_civoid plfxlc_usb_disable_tx(struct plfxlc_usb *usb);
18562306a36Sopenharmony_ciint plfxlc_usb_tx(struct plfxlc_usb *usb, struct sk_buff *skb);
18662306a36Sopenharmony_ciint plfxlc_usb_enable_rx(struct plfxlc_usb *usb);
18762306a36Sopenharmony_ciint plfxlc_usb_init_hw(struct plfxlc_usb *usb);
18862306a36Sopenharmony_ciconst char *plfxlc_speed(enum usb_device_speed speed);
18962306a36Sopenharmony_ci
19062306a36Sopenharmony_ci/* Firmware declarations */
19162306a36Sopenharmony_ciint plfxlc_download_xl_firmware(struct usb_interface *intf);
19262306a36Sopenharmony_ciint plfxlc_download_fpga(struct usb_interface *intf);
19362306a36Sopenharmony_ci
19462306a36Sopenharmony_ciint plfxlc_upload_mac_and_serial(struct usb_interface *intf,
19562306a36Sopenharmony_ci				 unsigned char *hw_address,
19662306a36Sopenharmony_ci				 unsigned char *serial_number);
19762306a36Sopenharmony_ci
19862306a36Sopenharmony_ci#endif /* PLFXLC_USB_H */
199