| 304 | } |
| 305 | |
| 306 | static int _vnic_dev_cmd(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd, |
| 307 | int wait) |
| 308 | { |
| 309 | struct vnic_devcmd __iomem *devcmd = vdev->devcmd; |
| 310 | unsigned int i; |
| 311 | int delay; |
| 312 | uint32_t status; |
| 313 | int err; |
| 314 | |
| 315 | status = ioread32(&devcmd->status); |
| 316 | if (status == 0xFFFFFFFF) { |
| 317 | /* PCI-e target device is gone */ |
| 318 | return -ENODEV; |
| 319 | } |
| 320 | if (status & STAT_BUSY) { |
| 321 | |
| 322 | pr_err("Busy devcmd %d\n", _CMD_N(cmd)); |
| 323 | return -EBUSY; |
| 324 | } |
| 325 | |
| 326 | if (_CMD_DIR(cmd) & _CMD_DIR_WRITE) { |
| 327 | for (i = 0; i < VNIC_DEVCMD_NARGS; i++) |
| 328 | writeq(vdev->args[i], &devcmd->args[i]); |
| 329 | rte_wmb(); /* complete all writes initiated till now */ |
| 330 | } |
| 331 | |
| 332 | iowrite32(cmd, &devcmd->cmd); |
| 333 | |
| 334 | if ((_CMD_FLAGS(cmd) & _CMD_FLAGS_NOWAIT)) |
| 335 | return 0; |
| 336 | |
| 337 | for (delay = 0; delay < wait; delay++) { |
| 338 | |
| 339 | usleep(100); |
| 340 | |
| 341 | status = ioread32(&devcmd->status); |
| 342 | if (status == 0xFFFFFFFF) { |
| 343 | /* PCI-e target device is gone */ |
| 344 | return -ENODEV; |
| 345 | } |
| 346 | |
| 347 | if (!(status & STAT_BUSY)) { |
| 348 | if (status & STAT_ERROR) { |
| 349 | err = -(int)readq(&devcmd->args[0]); |
| 350 | if (cmd != CMD_CAPABILITY && |
| 351 | cmd != CMD_OVERLAY_OFFLOAD_CTRL && |
| 352 | cmd != CMD_GET_SUPP_FEATURE_VER) |
| 353 | pr_err("Devcmd %d failed " \ |
| 354 | "with error code %d\n", |
| 355 | _CMD_N(cmd), err); |
| 356 | return err; |
| 357 | } |
| 358 | |
| 359 | if (_CMD_DIR(cmd) & _CMD_DIR_READ) { |
| 360 | rte_rmb();/* finish all reads */ |
| 361 | for (i = 0; i < VNIC_DEVCMD_NARGS; i++) |
| 362 | vdev->args[i] = readq(&devcmd->args[i]); |
| 363 | } |
no test coverage detected