-
Notifications
You must be signed in to change notification settings - Fork 21
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Drivers/FPGA/DFL - Intel PAC N3000 missing modules select #22
Open
hwspeedy
wants to merge
3
commits into
OFS:master
Choose a base branch
from
hwspeedy:master
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,230 @@ | ||
// SPDX-License-Identifier: GPL-2.0 | ||
/* Intel Max10 BMC Retimer Interface Driver | ||
* | ||
* Copyright (C) 2018-2020 Intel Corporation. All rights reserved. | ||
* | ||
*/ | ||
#include <linux/device.h> | ||
#include <linux/mfd/intel-m10-bmc.h> | ||
#include <linux/module.h> | ||
#include <linux/phy.h> | ||
#include <linux/platform_device.h> | ||
|
||
#define NUM_CHIP 2 | ||
#define MAX_LINK 4 | ||
|
||
#define BITS_MASK(nbits) ((1 << (nbits)) - 1) | ||
|
||
#define N3000BMC_RETIMER_DEV_NAME "n3000bmc-retimer" | ||
#define M10BMC_RETIMER_MII_NAME "m10bmc retimer mii" | ||
|
||
struct m10bmc_retimer { | ||
struct device *dev; | ||
struct intel_m10bmc *m10bmc; | ||
int num_devs; | ||
struct device *base_dev; | ||
struct mii_bus *retimer_mii_bus; | ||
}; | ||
|
||
#define RETIMER_LINK_STAT_BIT(retimer_id, link_id) \ | ||
BIT(((retimer_id) << 2) + (link_id)) | ||
|
||
static u32 retimer_get_link(struct m10bmc_retimer *retimer, int index) | ||
{ | ||
unsigned int val; | ||
|
||
if (m10bmc_sys_read(retimer->m10bmc, PKVL_LINK_STATUS, &val)) { | ||
dev_err(retimer->dev, "fail to read PKVL_LINK_STATUS\n"); | ||
return 0; | ||
} | ||
|
||
if (val & BIT(index)) | ||
return 1; | ||
|
||
return 0; | ||
} | ||
|
||
static int m10bmc_retimer_phy_match(struct phy_device *phydev) | ||
{ | ||
if (phydev->mdio.bus->name && | ||
!strcmp(phydev->mdio.bus->name, M10BMC_RETIMER_MII_NAME)) { | ||
return 1; | ||
} | ||
|
||
return 0; | ||
} | ||
|
||
static int m10bmc_retimer_phy_probe(struct phy_device *phydev) | ||
{ | ||
struct m10bmc_retimer *retimer = phydev->mdio.bus->priv; | ||
|
||
phydev->priv = retimer; | ||
|
||
return 0; | ||
} | ||
|
||
static void m10bmc_retimer_phy_remove(struct phy_device *phydev) | ||
{ | ||
if (phydev->attached_dev) | ||
phy_disconnect(phydev); | ||
} | ||
|
||
static int m10bmc_retimer_read_status(struct phy_device *phydev) | ||
{ | ||
struct m10bmc_retimer *retimer = phydev->priv; | ||
|
||
phydev->link = retimer_get_link(retimer, phydev->mdio.addr); | ||
|
||
phydev->duplex = DUPLEX_FULL; | ||
|
||
return 0; | ||
} | ||
|
||
static int m10bmc_retimer_get_features(struct phy_device *phydev) | ||
{ | ||
linkmode_set_bit(ETHTOOL_LINK_MODE_10000baseT_Full_BIT, | ||
phydev->supported); | ||
linkmode_set_bit(ETHTOOL_LINK_MODE_10000baseSR_Full_BIT, | ||
phydev->supported); | ||
linkmode_set_bit(ETHTOOL_LINK_MODE_10000baseLR_Full_BIT, | ||
phydev->supported); | ||
|
||
linkmode_set_bit(ETHTOOL_LINK_MODE_25000baseCR_Full_BIT, | ||
phydev->supported); | ||
linkmode_set_bit(ETHTOOL_LINK_MODE_25000baseSR_Full_BIT, | ||
phydev->supported); | ||
|
||
linkmode_set_bit(ETHTOOL_LINK_MODE_40000baseCR4_Full_BIT, | ||
phydev->supported); | ||
linkmode_set_bit(ETHTOOL_LINK_MODE_40000baseSR4_Full_BIT, | ||
phydev->supported); | ||
linkmode_set_bit(ETHTOOL_LINK_MODE_40000baseLR4_Full_BIT, | ||
phydev->supported); | ||
|
||
linkmode_set_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, phydev->supported); | ||
|
||
return 0; | ||
} | ||
|
||
static struct phy_driver m10bmc_retimer_phy_driver = { | ||
.phy_id = 0xffffffff, | ||
.phy_id_mask = 0xffffffff, | ||
.name = "m10bmc retimer PHY", | ||
.match_phy_device = m10bmc_retimer_phy_match, | ||
.probe = m10bmc_retimer_phy_probe, | ||
.remove = m10bmc_retimer_phy_remove, | ||
.read_status = m10bmc_retimer_read_status, | ||
.get_features = m10bmc_retimer_get_features, | ||
.read_mmd = genphy_read_mmd_unsupported, | ||
.write_mmd = genphy_write_mmd_unsupported, | ||
}; | ||
|
||
static int m10bmc_retimer_read(struct mii_bus *bus, int addr, int regnum) | ||
{ | ||
struct m10bmc_retimer *retimer = bus->priv; | ||
|
||
if (addr < retimer->num_devs && | ||
(regnum == MII_PHYSID1 || regnum == MII_PHYSID2)) | ||
return 0; | ||
|
||
return 0xffff; | ||
} | ||
|
||
static int m10bmc_retimer_write(struct mii_bus *bus, int addr, int regnum, u16 val) | ||
{ | ||
return 0; | ||
} | ||
|
||
static int m10bmc_retimer_mii_bus_init(struct m10bmc_retimer *retimer) | ||
{ | ||
struct mii_bus *bus; | ||
int ret; | ||
|
||
bus = devm_mdiobus_alloc(retimer->dev); | ||
if (!bus) | ||
return -ENOMEM; | ||
|
||
bus->priv = (void *)retimer; | ||
bus->name = M10BMC_RETIMER_MII_NAME; | ||
bus->read = m10bmc_retimer_read; | ||
bus->write = m10bmc_retimer_write; | ||
snprintf(bus->id, MII_BUS_ID_SIZE, "%s-mii", | ||
dev_name(retimer->base_dev)); | ||
bus->parent = retimer->dev; | ||
bus->phy_mask = ~(BITS_MASK(retimer->num_devs)); | ||
|
||
ret = mdiobus_register(bus); | ||
if (ret) | ||
return ret; | ||
|
||
retimer->retimer_mii_bus = bus; | ||
|
||
return 0; | ||
} | ||
|
||
static void m10bmc_retimer_mii_bus_uinit(struct m10bmc_retimer *retimer) | ||
{ | ||
mdiobus_unregister(retimer->retimer_mii_bus); | ||
} | ||
|
||
static int intel_m10bmc_retimer_probe(struct platform_device *pdev) | ||
{ | ||
struct intel_m10bmc_retimer_pdata *pdata = dev_get_platdata(&pdev->dev); | ||
struct intel_m10bmc *m10bmc = dev_get_drvdata(pdev->dev.parent); | ||
struct m10bmc_retimer *retimer; | ||
|
||
retimer = devm_kzalloc(&pdev->dev, sizeof(*retimer), GFP_KERNEL); | ||
if (!retimer) | ||
return -ENOMEM; | ||
|
||
dev_set_drvdata(&pdev->dev, retimer); | ||
|
||
retimer->dev = &pdev->dev; | ||
retimer->m10bmc = m10bmc; | ||
retimer->base_dev = pdata->retimer_master; | ||
retimer->num_devs = NUM_CHIP * MAX_LINK; | ||
|
||
return m10bmc_retimer_mii_bus_init(retimer); | ||
} | ||
|
||
static int intel_m10bmc_retimer_remove(struct platform_device *pdev) | ||
{ | ||
struct m10bmc_retimer *retimer = dev_get_drvdata(&pdev->dev); | ||
|
||
m10bmc_retimer_mii_bus_uinit(retimer); | ||
|
||
return 0; | ||
} | ||
|
||
static struct platform_driver intel_m10bmc_retimer_driver = { | ||
.probe = intel_m10bmc_retimer_probe, | ||
.remove = intel_m10bmc_retimer_remove, | ||
.driver = { | ||
.name = N3000BMC_RETIMER_DEV_NAME, | ||
}, | ||
}; | ||
|
||
static int __init intel_m10bmc_retimer_init(void) | ||
{ | ||
int ret; | ||
|
||
ret = phy_driver_register(&m10bmc_retimer_phy_driver, THIS_MODULE); | ||
if (ret) | ||
return ret; | ||
|
||
return platform_driver_register(&intel_m10bmc_retimer_driver); | ||
} | ||
module_init(intel_m10bmc_retimer_init); | ||
|
||
static void __exit intel_m10bmc_retimer_exit(void) | ||
{ | ||
platform_driver_unregister(&intel_m10bmc_retimer_driver); | ||
phy_driver_unregister(&m10bmc_retimer_phy_driver); | ||
} | ||
module_exit(intel_m10bmc_retimer_exit); | ||
|
||
MODULE_ALIAS("platform:" N3000BMC_RETIMER_DEV_NAME); | ||
MODULE_AUTHOR("Intel Corporation"); | ||
MODULE_DESCRIPTION("Intel MAX 10 BMC retimer driver"); | ||
MODULE_LICENSE("GPL"); | ||
MODULE_IMPORT_NS(INTEL_M10_BMC_CORE); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
select
should not be used to express dependencies in general sinceSo then one might ask why not add these dependencies using
depends on
? If you take a look atdfl-n3000-nios.c
, note how its minimal dependencies,FPGA_DFL
andREGMAP
, provide symbols used by the module, e.g.,__dfl_driver_register()
(throughmodule_dfl_driver()
) andregmap_read()
, respectively. With only these dependencies selected, thedfl-n3000-nios
module should load successfully since its symbols are satisfied. The dependencies you specified above may be useful to exploit the full functionality of the driver, but they are not needed to load the driver.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you very much for your feedback.
Here are my 5 cents to DFL/OPAE and what I think need to happen for OFS success.
State of OFS - DFL/OPAE.
DFL contains a bunch of modules and almost no-one understands it.
Partial reconfiguration (PR) is a messy business – keeping part of the FPGA running while stalling another part and changing that. Isolation bridges for freezing the registers towards the running part, ensuring that the running part do not use the part that is being changed and the other way around, when loading the new part.
Why do you have to partition in special way – that is known only by the FPGA manufacture – but it has to do with chains used to configure the FPGA. For Arria 10 FPGA it is keep it slim and wide. The schemes are different for Xilinx chips – more like Stratix. The PR needs to be compiled for exactly what is running – loading something else is a crash?
So that is why the FPGA loading is validating - that could be Kernel or BMC. When a FPGA part is running it would be nice to could verify who made this part and if it is valid.
A simple way – upload known good image, another way is to check public/private keys. Security is important both for data centers, companies and consumers and the implementations need maturity - open source is quite good at that.
But all of this does not make entirely sense to most kernel maintainers/users – its ugly hardware solutions mostly used because the PCIe interface, embedded CPU or memory in FPGA needs to continue running while we update or replace a function.
So DFL and OPAE is trying to address this situation – but it is also seams messy.
Looking at the linux-fpga patchworks board - it seams Redhat as maintainer mostly gave up and I see why.
What is this? How does it benefit Linux? Where is going? Is it really open source?
My experience
I have a couple of Intel FPGA cards and installs them in a machine. Nothing works – no drivers.
Hacking the kernel and adding the Intel PAC n3000 card and finding the OPAE in the OFS gives a little life but no flashing LED yet.
Now you need to debug the entire DFL and Intel PAC n3000 private to discover lots of missing modules. Then add these – more life and mostly running as root – only a retimer module is missing.
Trying to get it to work as an user on the PC – Trouble again – PHY are accessed trough the kernel debug interface on the regmaps – Nice new feature by the way. But this leaves the driver incomplete and probably why the PAC n3000V is not working at 10G instead of the 25G, when the FPGA is made for 10G but the retimers are still 25G.
When we look at the FPGA and OFS to setup the retimers you end up needing a missing BMC source and FPGA source. But as OFS says on the webpage - you can get this package by contacting Intel.
FAE manager at Arrow was not able to get this package.
I need it to change the messy retimer thing with SPI bridge in both directions along with removing, what I believe is a CVE security problem – The fast Core Cache IP, but still have the BMC with Powerup seq, temp, overheating protection, FPGA loading, etc.
Can you get the package consisting of BMC controller RTL+FW+qsf and FPGA RTL bridge part for me?
Back to the open source idea, which has bought the world the Linux we know.
So Intel wants to be in the kernel that runs all data centers and seams to be contributing to open source – but where are the Xilinx PAC/NAC cards?
My 5 cents:
If the above succeeds so does Intel and AMD FPGA and we get more FPGA developers in the world.
Please share you comments and also let me know if I can get the above package, thanx.