1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright(c) 2023 Advanced Micro Devices, Inc */
4 #include <linux/errno.h>
6 #include <linux/utsname.h>
10 int pdsc_err_to_errno(enum pds_core_status_code code
)
58 bool pdsc_is_fw_running(struct pdsc
*pdsc
)
63 pdsc
->fw_status
= ioread8(&pdsc
->info_regs
->fw_status
);
64 pdsc
->last_fw_time
= jiffies
;
65 pdsc
->last_hb
= ioread32(&pdsc
->info_regs
->fw_heartbeat
);
67 /* Firmware is useful only if the running bit is set and
68 * fw_status != 0xff (bad PCI read)
70 return (pdsc
->fw_status
!= PDS_RC_BAD_PCI
) &&
71 (pdsc
->fw_status
& PDS_CORE_FW_STS_F_RUNNING
);
74 bool pdsc_is_fw_good(struct pdsc
*pdsc
)
76 bool fw_running
= pdsc_is_fw_running(pdsc
);
79 /* Make sure to update the cached fw_status by calling
80 * pdsc_is_fw_running() before getting the generation
82 gen
= pdsc
->fw_status
& PDS_CORE_FW_STS_F_GENERATION
;
84 return fw_running
&& gen
== pdsc
->fw_generation
;
87 static u8
pdsc_devcmd_status(struct pdsc
*pdsc
)
89 return ioread8(&pdsc
->cmd_regs
->comp
.status
);
92 static bool pdsc_devcmd_done(struct pdsc
*pdsc
)
94 return ioread32(&pdsc
->cmd_regs
->done
) & PDS_CORE_DEV_CMD_DONE
;
97 static void pdsc_devcmd_dbell(struct pdsc
*pdsc
)
99 iowrite32(0, &pdsc
->cmd_regs
->done
);
100 iowrite32(1, &pdsc
->cmd_regs
->doorbell
);
103 static void pdsc_devcmd_clean(struct pdsc
*pdsc
)
105 iowrite32(0, &pdsc
->cmd_regs
->doorbell
);
106 memset_io(&pdsc
->cmd_regs
->cmd
, 0, sizeof(pdsc
->cmd_regs
->cmd
));
109 static const char *pdsc_devcmd_str(int opcode
)
112 case PDS_CORE_CMD_NOP
:
113 return "PDS_CORE_CMD_NOP";
114 case PDS_CORE_CMD_IDENTIFY
:
115 return "PDS_CORE_CMD_IDENTIFY";
116 case PDS_CORE_CMD_RESET
:
117 return "PDS_CORE_CMD_RESET";
118 case PDS_CORE_CMD_INIT
:
119 return "PDS_CORE_CMD_INIT";
120 case PDS_CORE_CMD_FW_DOWNLOAD
:
121 return "PDS_CORE_CMD_FW_DOWNLOAD";
122 case PDS_CORE_CMD_FW_CONTROL
:
123 return "PDS_CORE_CMD_FW_CONTROL";
125 return "PDS_CORE_CMD_UNKNOWN";
129 static int pdsc_devcmd_wait(struct pdsc
*pdsc
, u8 opcode
, int max_seconds
)
131 struct device
*dev
= pdsc
->dev
;
132 unsigned long start_time
;
133 unsigned long max_wait
;
134 unsigned long duration
;
141 start_time
= jiffies
;
142 max_wait
= start_time
+ (max_seconds
* HZ
);
144 while (!done
&& !timeout
) {
145 running
= pdsc_is_fw_running(pdsc
);
149 done
= pdsc_devcmd_done(pdsc
);
153 timeout
= time_after(jiffies
, max_wait
);
157 usleep_range(100, 200);
159 duration
= jiffies
- start_time
;
161 if (done
&& duration
> HZ
)
162 dev_dbg(dev
, "DEVCMD %d %s after %ld secs\n",
163 opcode
, pdsc_devcmd_str(opcode
), duration
/ HZ
);
165 if ((!done
|| timeout
) && running
) {
166 dev_err(dev
, "DEVCMD %d %s timeout, done %d timeout %d max_seconds=%d\n",
167 opcode
, pdsc_devcmd_str(opcode
), done
, timeout
,
170 pdsc_devcmd_clean(pdsc
);
173 status
= pdsc_devcmd_status(pdsc
);
174 err
= pdsc_err_to_errno(status
);
175 if (err
&& err
!= -EAGAIN
)
176 dev_err(dev
, "DEVCMD %d %s failed, status=%d err %d %pe\n",
177 opcode
, pdsc_devcmd_str(opcode
), status
, err
,
183 int pdsc_devcmd_locked(struct pdsc
*pdsc
, union pds_core_dev_cmd
*cmd
,
184 union pds_core_dev_comp
*comp
, int max_seconds
)
191 memcpy_toio(&pdsc
->cmd_regs
->cmd
, cmd
, sizeof(*cmd
));
192 pdsc_devcmd_dbell(pdsc
);
193 err
= pdsc_devcmd_wait(pdsc
, cmd
->opcode
, max_seconds
);
195 if ((err
== -ENXIO
|| err
== -ETIMEDOUT
) && pdsc
->wq
)
196 queue_work(pdsc
->wq
, &pdsc
->health_work
);
198 memcpy_fromio(comp
, &pdsc
->cmd_regs
->comp
, sizeof(*comp
));
203 int pdsc_devcmd(struct pdsc
*pdsc
, union pds_core_dev_cmd
*cmd
,
204 union pds_core_dev_comp
*comp
, int max_seconds
)
208 mutex_lock(&pdsc
->devcmd_lock
);
209 err
= pdsc_devcmd_locked(pdsc
, cmd
, comp
, max_seconds
);
210 mutex_unlock(&pdsc
->devcmd_lock
);
215 int pdsc_devcmd_init(struct pdsc
*pdsc
)
217 union pds_core_dev_comp comp
= {};
218 union pds_core_dev_cmd cmd
= {
219 .opcode
= PDS_CORE_CMD_INIT
,
222 return pdsc_devcmd(pdsc
, &cmd
, &comp
, pdsc
->devcmd_timeout
);
225 int pdsc_devcmd_reset(struct pdsc
*pdsc
)
227 union pds_core_dev_comp comp
= {};
228 union pds_core_dev_cmd cmd
= {
229 .reset
.opcode
= PDS_CORE_CMD_RESET
,
232 if (!pdsc_is_fw_running(pdsc
))
235 return pdsc_devcmd(pdsc
, &cmd
, &comp
, pdsc
->devcmd_timeout
);
238 static int pdsc_devcmd_identify_locked(struct pdsc
*pdsc
)
240 union pds_core_dev_comp comp
= {};
241 union pds_core_dev_cmd cmd
= {
242 .identify
.opcode
= PDS_CORE_CMD_IDENTIFY
,
243 .identify
.ver
= PDS_CORE_IDENTITY_VERSION_1
,
246 return pdsc_devcmd_locked(pdsc
, &cmd
, &comp
, pdsc
->devcmd_timeout
);
249 static void pdsc_init_devinfo(struct pdsc
*pdsc
)
251 pdsc
->dev_info
.asic_type
= ioread8(&pdsc
->info_regs
->asic_type
);
252 pdsc
->dev_info
.asic_rev
= ioread8(&pdsc
->info_regs
->asic_rev
);
253 pdsc
->fw_generation
= PDS_CORE_FW_STS_F_GENERATION
&
254 ioread8(&pdsc
->info_regs
->fw_status
);
256 memcpy_fromio(pdsc
->dev_info
.fw_version
,
257 pdsc
->info_regs
->fw_version
,
258 PDS_CORE_DEVINFO_FWVERS_BUFLEN
);
259 pdsc
->dev_info
.fw_version
[PDS_CORE_DEVINFO_FWVERS_BUFLEN
] = 0;
261 memcpy_fromio(pdsc
->dev_info
.serial_num
,
262 pdsc
->info_regs
->serial_num
,
263 PDS_CORE_DEVINFO_SERIAL_BUFLEN
);
264 pdsc
->dev_info
.serial_num
[PDS_CORE_DEVINFO_SERIAL_BUFLEN
] = 0;
266 dev_dbg(pdsc
->dev
, "fw_version %s\n", pdsc
->dev_info
.fw_version
);
269 static int pdsc_identify(struct pdsc
*pdsc
)
271 struct pds_core_drv_identity drv
= {};
276 drv
.drv_type
= cpu_to_le32(PDS_DRIVER_LINUX
);
277 /* Catching the return quiets a Wformat-truncation complaint */
278 n
= snprintf(drv
.driver_ver_str
, sizeof(drv
.driver_ver_str
),
279 "%s %s", PDS_CORE_DRV_NAME
, utsname()->release
);
280 if (n
> sizeof(drv
.driver_ver_str
))
281 dev_dbg(pdsc
->dev
, "release name truncated, don't care\n");
283 /* Next let's get some info about the device
284 * We use the devcmd_lock at this level in order to
285 * get safe access to the cmd_regs->data before anyone
286 * else can mess it up
288 mutex_lock(&pdsc
->devcmd_lock
);
290 sz
= min_t(size_t, sizeof(drv
), sizeof(pdsc
->cmd_regs
->data
));
291 memcpy_toio(&pdsc
->cmd_regs
->data
, &drv
, sz
);
293 err
= pdsc_devcmd_identify_locked(pdsc
);
295 sz
= min_t(size_t, sizeof(pdsc
->dev_ident
),
296 sizeof(pdsc
->cmd_regs
->data
));
297 memcpy_fromio(&pdsc
->dev_ident
, &pdsc
->cmd_regs
->data
, sz
);
299 mutex_unlock(&pdsc
->devcmd_lock
);
302 dev_err(pdsc
->dev
, "Cannot identify device: %pe\n",
307 if (isprint(pdsc
->dev_info
.fw_version
[0]) &&
308 isascii(pdsc
->dev_info
.fw_version
[0]))
309 dev_info(pdsc
->dev
, "FW: %.*s\n",
310 (int)(sizeof(pdsc
->dev_info
.fw_version
) - 1),
311 pdsc
->dev_info
.fw_version
);
313 dev_info(pdsc
->dev
, "FW: (invalid string) 0x%02x 0x%02x 0x%02x 0x%02x ...\n",
314 (u8
)pdsc
->dev_info
.fw_version
[0],
315 (u8
)pdsc
->dev_info
.fw_version
[1],
316 (u8
)pdsc
->dev_info
.fw_version
[2],
317 (u8
)pdsc
->dev_info
.fw_version
[3]);
322 void pdsc_dev_uninit(struct pdsc
*pdsc
)
324 if (pdsc
->intr_info
) {
327 for (i
= 0; i
< pdsc
->nintrs
; i
++)
328 pdsc_intr_free(pdsc
, i
);
330 kfree(pdsc
->intr_info
);
331 pdsc
->intr_info
= NULL
;
335 pci_free_irq_vectors(pdsc
->pdev
);
338 int pdsc_dev_init(struct pdsc
*pdsc
)
343 /* Initial init and reset of device */
344 pdsc_init_devinfo(pdsc
);
345 pdsc
->devcmd_timeout
= PDS_CORE_DEVCMD_TIMEOUT
;
347 err
= pdsc_devcmd_reset(pdsc
);
351 err
= pdsc_identify(pdsc
);
355 pdsc_debugfs_add_ident(pdsc
);
357 /* Now we can reserve interrupts */
358 nintrs
= le32_to_cpu(pdsc
->dev_ident
.nintrs
);
359 nintrs
= min_t(unsigned int, num_online_cpus(), nintrs
);
361 /* Get intr_info struct array for tracking */
362 pdsc
->intr_info
= kcalloc(nintrs
, sizeof(*pdsc
->intr_info
), GFP_KERNEL
);
363 if (!pdsc
->intr_info
)
366 err
= pci_alloc_irq_vectors(pdsc
->pdev
, nintrs
, nintrs
, PCI_IRQ_MSIX
);
368 dev_err(pdsc
->dev
, "Can't get %d intrs from OS: %pe\n",
369 nintrs
, ERR_PTR(err
));
373 pdsc
->nintrs
= nintrs
;
378 kfree(pdsc
->intr_info
);
379 pdsc
->intr_info
= NULL
;