1  /* SPDX-License-Identifier: GPL-2.0-only */
2  /*
3   * Copyright (c) 2021 pureLiFi
4   */
5  
6  #ifndef PLFXLC_USB_H
7  #define PLFXLC_USB_H
8  
9  #include <linux/completion.h>
10  #include <linux/netdevice.h>
11  #include <linux/spinlock.h>
12  #include <linux/skbuff.h>
13  #include <linux/usb.h>
14  
15  #include "intf.h"
16  
17  #define USB_BULK_MSG_TIMEOUT_MS 2000
18  
19  #define PURELIFI_X_VENDOR_ID_0   0x16C1
20  #define PURELIFI_X_PRODUCT_ID_0  0x1CDE
21  #define PURELIFI_XC_VENDOR_ID_0  0x2EF5
22  #define PURELIFI_XC_PRODUCT_ID_0 0x0008
23  #define PURELIFI_XL_VENDOR_ID_0  0x2EF5
24  #define PURELIFI_XL_PRODUCT_ID_0 0x000A /* Station */
25  
26  #define PLF_FPGA_STATUS_LEN 2
27  #define PLF_FPGA_STATE_LEN 9
28  #define PLF_BULK_TLEN 16384
29  #define PLF_FPGA_MG 6 /* Magic check */
30  #define PLF_XL_BUF_LEN 64
31  #define PLF_MSG_STATUS_OFFSET 7
32  
33  #define PLF_USB_TIMEOUT 1000
34  #define PLF_MSLEEP_TIME 200
35  
36  #define PURELIFI_URB_RETRY_MAX 5
37  
38  #define plfxlc_usb_dev(usb) (&(usb)->intf->dev)
39  
40  /* Tx retry backoff timer (in milliseconds) */
41  #define TX_RETRY_BACKOFF_MS 10
42  #define STA_QUEUE_CLEANUP_MS 5000
43  
44  /* Tx retry backoff timer (in jiffies) */
45  #define TX_RETRY_BACKOFF_JIFF ((TX_RETRY_BACKOFF_MS * HZ) / 1000)
46  #define STA_QUEUE_CLEANUP_JIFF ((STA_QUEUE_CLEANUP_MS * HZ) / 1000)
47  
48  /* Ensures that MAX_TRANSFER_SIZE is even. */
49  #define MAX_TRANSFER_SIZE (USB_MAX_TRANSFER_SIZE & ~1)
50  #define plfxlc_urb_dev(urb) (&(urb)->dev->dev)
51  
52  #define STATION_FIFO_ALMOST_FULL_MESSAGE     0
53  #define STATION_FIFO_ALMOST_FULL_NOT_MESSAGE 1
54  #define STATION_CONNECT_MESSAGE              2
55  #define STATION_DISCONNECT_MESSAGE           3
56  
57  int plfxlc_usb_wreq(struct usb_interface *ez_usb, void *buffer, int buffer_len,
58  		    enum plf_usb_req_enum usb_req_id);
59  void plfxlc_tx_urb_complete(struct urb *urb);
60  
61  enum {
62  	USB_MAX_RX_SIZE       = 4800,
63  	USB_MAX_EP_INT_BUFFER = 64,
64  };
65  
66  struct plfxlc_usb_interrupt {
67  	spinlock_t lock; /* spin lock for usb interrupt buffer */
68  	struct urb *urb;
69  	void *buffer;
70  	int interval;
71  };
72  
73  #define RX_URBS_COUNT 5
74  
75  struct plfxlc_usb_rx {
76  	spinlock_t lock; /* spin lock for rx urb */
77  	struct mutex setup_mutex; /* mutex lockt for rx urb */
78  	u8 fragment[2 * USB_MAX_RX_SIZE];
79  	unsigned int fragment_length;
80  	unsigned int usb_packet_size;
81  	struct urb **urbs;
82  	int urbs_count;
83  };
84  
85  struct plf_station {
86     /*  7...3    |    2      |     1     |     0	    |
87      * Reserved  | Heartbeat | FIFO full | Connected |
88      */
89  	unsigned char flag;
90  	unsigned char mac[ETH_ALEN];
91  	struct sk_buff_head data_list;
92  };
93  
94  struct plfxlc_firmware_file {
95  	u32 total_files;
96  	u32 total_size;
97  	u32 size;
98  	u32 start_addr;
99  	u32 control_packets;
100  } __packed;
101  
102  #define STATION_CONNECTED_FLAG 0x1
103  #define STATION_FIFO_FULL_FLAG 0x2
104  #define STATION_HEARTBEAT_FLAG 0x4
105  #define STATION_ACTIVE_FLAG    0xFD
106  
107  #define PURELIFI_SERIAL_LEN 256
108  #define STA_BROADCAST_INDEX (AP_USER_LIMIT)
109  #define MAX_STA_NUM         (AP_USER_LIMIT + 1)
110  
111  struct plfxlc_usb_tx {
112  	unsigned long enabled;
113  	spinlock_t lock; /* spinlock for USB tx */
114  	u8 mac_fifo_full;
115  	struct sk_buff_head submitted_skbs;
116  	struct usb_anchor submitted;
117  	int submitted_urbs;
118  	bool stopped;
119  	struct timer_list tx_retry_timer;
120  	struct plf_station station[MAX_STA_NUM];
121  };
122  
123  /* Contains the usb parts. The structure doesn't require a lock because intf
124   * will not be changed after initialization.
125   */
126  struct plfxlc_usb {
127  	struct timer_list sta_queue_cleanup;
128  	struct plfxlc_usb_rx rx;
129  	struct plfxlc_usb_tx tx;
130  	struct usb_interface *intf;
131  	struct usb_interface *ez_usb;
132  	u8 req_buf[64]; /* plfxlc_usb_iowrite16v needs 62 bytes */
133  	u8 sidx; /* store last served */
134  	bool rx_usb_enabled;
135  	bool initialized;
136  	bool was_running;
137  	bool link_up;
138  };
139  
140  enum endpoints {
141  	EP_DATA_IN  = 2,
142  	EP_DATA_OUT = 8,
143  };
144  
145  enum devicetype {
146  	DEVICE_LIFI_X  = 0,
147  	DEVICE_LIFI_XC  = 1,
148  	DEVICE_LIFI_XL  = 1,
149  };
150  
151  enum {
152  	PLF_BIT_ENABLED = 1,
153  	PLF_BIT_MAX = 2,
154  };
155  
156  int plfxlc_usb_wreq_async(struct plfxlc_usb *usb, const u8 *buffer,
157  			  int buffer_len, enum plf_usb_req_enum usb_req_id,
158  			  usb_complete_t complete_fn, void *context);
159  
160  static inline struct usb_device *
plfxlc_usb_to_usbdev(struct plfxlc_usb * usb)161  plfxlc_usb_to_usbdev(struct plfxlc_usb *usb)
162  {
163  	return interface_to_usbdev(usb->intf);
164  }
165  
166  static inline struct ieee80211_hw *
plfxlc_intf_to_hw(struct usb_interface * intf)167  plfxlc_intf_to_hw(struct usb_interface *intf)
168  {
169  	return usb_get_intfdata(intf);
170  }
171  
172  static inline struct ieee80211_hw *
plfxlc_usb_to_hw(struct plfxlc_usb * usb)173  plfxlc_usb_to_hw(struct plfxlc_usb *usb)
174  {
175  	return plfxlc_intf_to_hw(usb->intf);
176  }
177  
178  void plfxlc_usb_init(struct plfxlc_usb *usb, struct ieee80211_hw *hw,
179  		     struct usb_interface *intf);
180  void plfxlc_send_packet_from_data_queue(struct plfxlc_usb *usb);
181  void plfxlc_usb_release(struct plfxlc_usb *usb);
182  void plfxlc_usb_disable_rx(struct plfxlc_usb *usb);
183  void plfxlc_usb_enable_tx(struct plfxlc_usb *usb);
184  void plfxlc_usb_disable_tx(struct plfxlc_usb *usb);
185  int plfxlc_usb_tx(struct plfxlc_usb *usb, struct sk_buff *skb);
186  int plfxlc_usb_enable_rx(struct plfxlc_usb *usb);
187  int plfxlc_usb_init_hw(struct plfxlc_usb *usb);
188  const char *plfxlc_speed(enum usb_device_speed speed);
189  
190  /* Firmware declarations */
191  int plfxlc_download_xl_firmware(struct usb_interface *intf);
192  int plfxlc_download_fpga(struct usb_interface *intf);
193  
194  int plfxlc_upload_mac_and_serial(struct usb_interface *intf,
195  				 unsigned char *hw_address,
196  				 unsigned char *serial_number);
197  
198  #endif /* PLFXLC_USB_H */
199