• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*
3  * i1480 Device Firmware Upload
4  *
5  * Copyright (C) 2005-2006 Intel Corporation
6  * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
7  *
8  * This driver is the firmware uploader for the Intel Wireless UWB
9  * Link 1480 device (both in the USB and PCI incarnations).
10  *
11  * The process is quite simple: we stop the device, write the firmware
12  * to its memory and then restart it. Wait for the device to let us
13  * know it is done booting firmware. Ready.
14  *
15  * We might have to upload before or after a phy firmware (which might
16  * be done in two methods, using a normal firmware image or through
17  * the MPI port).
18  *
19  * Because USB and PCI use common methods, we just make ops out of the
20  * common operations (read, write, wait_init_done and cmd) and
21  * implement them in usb.c and pci.c.
22  *
23  * The flow is (some parts omitted):
24  *
25  * i1480_{usb,pci}_probe()	  On enumerate/discovery
26  *   i1480_fw_upload()
27  *     i1480_pre_fw_upload()
28  *       __mac_fw_upload()
29  *         fw_hdrs_load()
30  *         mac_fw_hdrs_push()
31  *           i1480->write()       [i1480_{usb,pci}_write()]
32  *           i1480_fw_cmp()
33  *             i1480->read()      [i1480_{usb,pci}_read()]
34  *     i1480_mac_fw_upload()
35  *       __mac_fw_upload()
36  *       i1480->setup(()
37  *       i1480->wait_init_done()
38  *       i1480_cmd_reset()
39  *         i1480->cmd()           [i1480_{usb,pci}_cmd()]
40  *         ...
41  *     i1480_phy_fw_upload()
42  *       request_firmware()
43  *       i1480_mpi_write()
44  *         i1480->cmd()           [i1480_{usb,pci}_cmd()]
45  *
46  * Once the probe function enumerates the device and uploads the
47  * firmware, we just exit with -ENODEV, as we don't really want to
48  * attach to the device.
49  */
50 #ifndef __i1480_DFU_H__
51 #define __i1480_DFU_H__
52 
53 #include <linux/types.h>
54 #include <linux/completion.h>
55 #include "../../include/spec.h"
56 
57 #define i1480_FW_UPLOAD_MODE_MASK (cpu_to_le32(0x00000018))
58 
59 #if i1480_FW > 0x00000302
60 #define i1480_RCEB_EXTENDED
61 #endif
62 
63 struct uwb_rccb;
64 struct uwb_rceb;
65 
66 /*
67  * Common firmware upload handlers
68  *
69  * Normally you embed this struct in another one specific to your hw.
70  *
71  * @write	Write to device's memory from buffer.
72  * @read	Read from device's memory to i1480->evt_buf.
73  * @setup	Setup device after basic firmware is uploaded
74  * @wait_init_done
75  *              Wait for the device to send a notification saying init
76  *              is done.
77  * @cmd         FOP for issuing the command to the hardware. The
78  *              command data is contained in i1480->cmd_buf and the size
79  *              is supplied as an argument. The command replied is put
80  *              in i1480->evt_buf and the size in i1480->evt_result (or if
81  *              an error, a < 0 errno code).
82  *
83  * @cmd_buf	Memory buffer used to send commands to the device.
84  *              Allocated by the upper layers i1480_fw_upload().
85  *              Size has to be @buf_size.
86  * @evt_buf	Memory buffer used to place the async notifications
87  *              received by the hw. Allocated by the upper layers
88  *              i1480_fw_upload().
89  *              Size has to be @buf_size.
90  * @cmd_complete
91  *              Low level driver uses this to notify code waiting afor
92  *              an event that the event has arrived and data is in
93  *              i1480->evt_buf (and size/result in i1480->evt_result).
94  * @hw_rev
95  *              Use this value to activate dfu code to support new revisions
96  *              of hardware.  i1480_init() sets this to a default value.
97  *              It should be updated by the USB and PCI code.
98  */
99 struct i1480 {
100 	struct device *dev;
101 
102 	int (*write)(struct i1480 *, u32 addr, const void *, size_t);
103 	int (*read)(struct i1480 *, u32 addr, size_t);
104 	int (*rc_setup)(struct i1480 *);
105 	void (*rc_release)(struct i1480 *);
106 	int (*wait_init_done)(struct i1480 *);
107 	int (*cmd)(struct i1480 *, const char *cmd_name, size_t cmd_size);
108 	const char *pre_fw_name;
109 	const char *mac_fw_name;
110 	const char *mac_fw_name_deprecate;	/* FIXME: Will go away */
111 	const char *phy_fw_name;
112 	u8 hw_rev;
113 
114 	size_t buf_size;	/* size of both evt_buf and cmd_buf */
115 	void *evt_buf, *cmd_buf;
116 	ssize_t evt_result;
117 	struct completion evt_complete;
118 };
119 
120 static inline
i1480_init(struct i1480 * i1480)121 void i1480_init(struct i1480 *i1480)
122 {
123 	i1480->hw_rev = 1;
124 	init_completion(&i1480->evt_complete);
125 }
126 
127 extern int i1480_fw_upload(struct i1480 *);
128 extern int i1480_pre_fw_upload(struct i1480 *);
129 extern int i1480_mac_fw_upload(struct i1480 *);
130 extern int i1480_phy_fw_upload(struct i1480 *);
131 extern ssize_t i1480_cmd(struct i1480 *, const char *, size_t, size_t);
132 extern int i1480_rceb_check(const struct i1480 *,
133 			    const struct uwb_rceb *, const char *, u8,
134 			    u8, unsigned);
135 
136 enum {
137 	/* Vendor specific command type */
138 	i1480_CET_VS1 = 		0xfd,
139 	/* i1480 commands */
140 	i1480_CMD_SET_IP_MAS = 		0x000e,
141 	i1480_CMD_GET_MAC_PHY_INFO = 	0x0003,
142 	i1480_CMD_MPI_WRITE =		0x000f,
143 	i1480_CMD_MPI_READ = 		0x0010,
144 	/* i1480 events */
145 #if i1480_FW > 0x00000302
146 	i1480_EVT_CONFIRM = 		0x0002,
147 	i1480_EVT_RM_INIT_DONE = 	0x0101,
148 	i1480_EVT_DEV_ADD = 		0x0103,
149 	i1480_EVT_DEV_RM = 		0x0104,
150 	i1480_EVT_DEV_ID_CHANGE = 	0x0105,
151 	i1480_EVT_GET_MAC_PHY_INFO =	i1480_CMD_GET_MAC_PHY_INFO,
152 #else
153 	i1480_EVT_CONFIRM = 		0x0002,
154 	i1480_EVT_RM_INIT_DONE = 	0x0101,
155 	i1480_EVT_DEV_ADD = 		0x0103,
156 	i1480_EVT_DEV_RM = 		0x0104,
157 	i1480_EVT_DEV_ID_CHANGE = 	0x0105,
158 	i1480_EVT_GET_MAC_PHY_INFO =	i1480_EVT_CONFIRM,
159 #endif
160 };
161 
162 
163 struct i1480_evt_confirm {
164 	struct uwb_rceb rceb;
165 #ifdef i1480_RCEB_EXTENDED
166 	__le16 wParamLength;
167 #endif
168 	u8 bResultCode;
169 } __attribute__((packed));
170 
171 
172 struct i1480_rceb {
173 	struct uwb_rceb rceb;
174 #ifdef i1480_RCEB_EXTENDED
175 	__le16 wParamLength;
176 #endif
177 } __attribute__((packed));
178 
179 
180 /**
181  * Get MAC & PHY Information confirm event structure
182  *
183  * Confirm event returned by the command.
184  */
185 struct i1480_evt_confirm_GMPI {
186 #if i1480_FW > 0x00000302
187 	struct uwb_rceb rceb;
188 	__le16 wParamLength;
189 	__le16 status;
190 	u8 mac_addr[6];		/* EUI-64 bit IEEE address [still 8 bytes?] */
191 	u8 dev_addr[2];
192 	__le16 mac_fw_rev;	/* major = v >> 8; minor = v & 0xff */
193 	u8 hw_rev;
194 	u8 phy_vendor;
195 	u8 phy_rev;		/* major v = >> 8; minor = v & 0xff */
196 	__le16 mac_caps;
197 	u8 phy_caps[3];
198 	u8 key_stores;
199 	__le16 mcast_addr_stores;
200 	u8 sec_mode_supported;
201 #else
202 	struct uwb_rceb rceb;
203 	u8 status;
204 	u8 mac_addr[8];         /* EUI-64 bit IEEE address [still 8 bytes?] */
205 	u8 dev_addr[2];
206 	__le16 mac_fw_rev;      /* major = v >> 8; minor = v & 0xff */
207 	__le16 phy_fw_rev;      /* major v = >> 8; minor = v & 0xff */
208 	__le16 mac_caps;
209 	u8 phy_caps;
210 	u8 key_stores;
211 	__le16 mcast_addr_stores;
212 	u8 sec_mode_supported;
213 #endif
214 } __attribute__((packed));
215 
216 
217 struct i1480_cmd_mpi_write {
218 	struct uwb_rccb rccb;
219 	__le16 size;
220 	u8 data[];
221 };
222 
223 
224 struct i1480_cmd_mpi_read {
225 	struct uwb_rccb rccb;
226 	__le16 size;
227 	struct {
228 		u8 page, offset;
229 	} __attribute__((packed)) data[];
230 } __attribute__((packed));
231 
232 
233 struct i1480_evt_mpi_read {
234 	struct uwb_rceb rceb;
235 #ifdef i1480_RCEB_EXTENDED
236 	__le16 wParamLength;
237 #endif
238 	u8 bResultCode;
239 	__le16 size;
240 	struct {
241 		u8 page, offset, value;
242 	} __attribute__((packed)) data[];
243 } __attribute__((packed));
244 
245 
246 #endif /* #ifndef __i1480_DFU_H__ */
247