| 1 | |
| 2 |
|
| 3 | use core::num::NonZero;
|
| 4 |
|
| 5 | use kernel::{
|
| 6 | device,
|
| 7 | pci,
|
| 8 | prelude::*, |
| 9 | };
|
| 10 |
|
| 11 | use crate::{
|
| 12 | fsp::{
|
| 13 | Fsp,
|
| 14 | VgpuMode, |
| 15 | },
|
| 16 | gpu::Chipset, |
| 17 | };
|
| 18 |
|
| 19 | mod hal;
|
| 20 |
|
| 21 | |
| 22 | #[derive(Debug, Clone, Copy)]
|
| 23 | pub(crate) enum VgpuState {
|
| 24 | |
| 25 | Disabled,
|
| 26 | |
| 27 | Enabled {
|
| 28 | |
| 29 | total_vfs: NonZero<u16>,
|
| 30 | },
|
| 31 | }
|
| 32 |
|
| 33 | |
| 34 | pub(crate) struct VgpuManager {
|
| 35 | state: VgpuState,
|
| 36 | }
|
| 37 |
|
| 38 | impl VgpuManager {
|
| 39 | |
| 40 | pub(crate) fn new(
|
| 41 | pdev: &pci::Device<device::Core<'_>>,
|
| 42 | chipset: Chipset,
|
| 43 | fsp: Option<&mut Fsp<'_>>,
|
| 44 | ) -> Self {
|
| 45 | let state = Self::detect_state(pdev, chipset, fsp).unwrap_or_else(|e| {
|
| 46 | dev_warn!(
|
| 47 | pdev,
|
| 48 | "vGPU state detection failed: {:?}; disabling vGPU\n",
|
| 49 | e
|
| 50 | );
|
| 51 | VgpuState::Disabled
|
| 52 | });
|
| 53 | dev_dbg!(pdev, "vGPU state: {:?}\n", state);
|
| 54 |
|
| 55 | Self { state }
|
| 56 | }
|
| 57 |
|
| 58 | |
| 59 | fn detect_state(
|
| 60 | pdev: &pci::Device<device::Core<'_>>,
|
| 61 | chipset: Chipset,
|
| 62 | fsp: Option<&mut Fsp<'_>>,
|
| 63 | ) -> Result<VgpuState> {
|
| 64 | if !hal::vgpu_hal(chipset).supports_vgpu() {
|
| 65 | return Ok(VgpuState::Disabled);
|
| 66 | }
|
| 67 |
|
| 68 | let Some(total_vfs) = pdev.sriov_get_totalvfs() else {
|
| 69 | return Ok(VgpuState::Disabled);
|
| 70 | };
|
| 71 |
|
| 72 | if total_vfs.get() < 2 {
|
| 73 | |
| 74 | |
| 75 | |
| 76 | return Ok(VgpuState::Disabled);
|
| 77 | }
|
| 78 |
|
| 79 | let fsp = fsp.ok_or(ENODEV)?;
|
| 80 |
|
| 81 | match fsp.read_vgpu_mode(pdev.as_ref())? {
|
| 82 | VgpuMode::Enabled => Ok(VgpuState::Enabled { total_vfs }),
|
| 83 | VgpuMode::Disabled => Ok(VgpuState::Disabled),
|
| 84 | }
|
| 85 | }
|
| 86 |
|
| 87 | |
| 88 | pub(crate) fn state(&self) -> VgpuState {
|
| 89 | self.state
|
| 90 | }
|
| 91 | }
|