Re: [Intel-wired-lan] [PATCH net-next] bridge: Make the FDB consider inner tag for Q-in-Q
> Here the same thing. The 802.1ad bridge has the same PVID on all ports. > Why does the FDB lookup have to be as complex as to take 2 VIDs into > consideration, instead of just the inner one? In all my examples I'm using the same PVID, because that's a required condition for the issue to happen. I omit that the other .1ad ports in could have different .1ad VIDs configured for them, to focus on the concept I'm trying to describe. But other VIDs can be configured on other ports. So, there could be collisions of .1q VIDs across different .1ad VIDs. As such, I don't want to ignore the outer VID during FDB lookup. In my use case (topology-sim) the test fabric consists of .1ad bridges that are connected to networking equipment under test. The topology-sim user configures virtual ethernet cables (point to point) and/or L2 IVL ethernet segments between multiple devices under test. They do this to construct an arbitrary ethernet topology that they want to test. topology-sim assigns / maps each one of these L2 segments to a unique .1ad VID. This is how it keeps the "virtual wires" from interfering with each other. So if one virtual wire (ie .1ad vid 3) is connecting to a switch under test that is emitting frames with .1q vid 7, I want this virtual wire to be independent from another virtual wire (ie .1ad vid 4) that is also emitting frame with .lq7 vid 7. I acknowledge that we shouldn't make this upstream change just for topology-sim, considering that I'm the only user of it. But these same problems can affect, for example, metro ethernet carriers that use .1ad vlan stacking to differentiate between their different customer's sites. I'm not trying to claim that metro ethernet carriers would be inclined to use this feature -- I'm just providing another example to point out that this same concept applies to use cases outside of topology-sim, because toplogy-sim uses VLAN stacking in a typical, conventional way. I'll now proceed to go over my hairpin example, https://docs.google.com/drawings/d/1FybJP3UyCPxVQRGxAqGztO4Qc5mgXclV4m-QEyfUFQ8 in more detail. I think that it will help demonstrate why I want to consider the inner tags. It's an example about a circuitous network path where the same packet can enter the same .1ad bridge multiple times, with the same .1ad VID, but different inner .1q VIDs. Like I mentioned before, this network is contrived. I've never seen this done, and don't expect that it is a common topology. But my goal is to prevent connectivity issues that only arise due to how topology-sim constructs the virtual L2 ethernet segments. The network under test has a bridge mode firewall that is used to inspect traffic as it passes from some subset of a L2 segment to another subset of the same L2 segment. The way that the network operator achieve this goal is by creating separate VLANs for each subset of the L2 segment that need firewall interjection. This way, communicate between these different subsets are forced though the firewall. The firewall bridges the two VLANs to merge them into one L2 segment, one broadcast domain. Say the topology-sim user wants to interconnect two .q1 bridges via a virtual Ethernet connection. topology-sim accomplishes this by setting the same PVID for both ports that that face these .q1 switches under test. Let's follow what happens when a packets it transmitted from A towards B. When the frame is emitted from ".lq #1", heading toward the .1ad switch, it is .1q tagged as 7. When the .1ad bridge receives the frame, it will associate it with .1ad vid 3 and .1q vid 7 can be seen in the packet, if desired. At this point, the .1ad bridge can either learn that A is behind it's left port, for .1ad vid 3 (current implementation), or it can learn that A is behind the left port only for .1ad vid 3 + inner .1a vid 7 (proposed functionality). When the frame leaves the .1ad switch heading toward ".1q #2", it will just have .1q vid 7 tag. ".1q #2" sends the packet to the firewall, via its left port, untagged. The firewall bridges the frame, and therefore transmits out its right port to ".1q #2", untagged. ".1q #2" transmits toward .1ad with .1q tag 8. When the .1ad bridge receives the frame, it will associate it with .1ad vid 3 and the inner .1q vid 8 can be seen in the packet if desired. At this point, the .1ad bridge can either learn that A is behind its right port, for .1ad vid 3 or it can learn that A is behind it's right port, for .1ad vid 3 + .1q inner vid 8. Without my change, the .1ad switch's fdb entry for A's mac, .1ad vid 3, would flip continuously between the left and right port. With my change, for .1ad vid 3, the .1ad bridge will always forward packets destined to host A's MAC to the right if the inner vid is 8 and will always forward host A's MAC to the left when the inner vid is 7. I hope this example explains why I want to look at the inner VID. The fact that we can have inner VID collisions for different outer vids, drives the need to examine the outer VI
Re: [Intel-wired-lan] [PATCH iwl-next 1/1] igc: Improve XDP_SETUP_PROG process
Song Yoong Siang writes: > Improve XDP_SETUP_PROG process by avoiding unnecessary link down/up event > and hardware device reset. > Some examples of problems that these hardware resets are causing would be good. > Signed-off-by: Song Yoong Siang > --- The duplication of code doesn't look that good. Initialization is tricky, it seems to make it easy to update one place and forget to update the other. A couple of ideas: - separate the code into functions that can be used from the "usual" igc_open()/igc_close() flow; - it seems that igc_close()/igc_open() are too big a hammer for installing a new XDP program: what do we really need? (my mental model is: 1. stop new traffic from going into any queue; 2. wait for any packets "in progress"; 3. install the program; 4. resume operations; what else?) > drivers/net/ethernet/intel/igc/igc.h | 2 + > drivers/net/ethernet/intel/igc/igc_main.c | 138 ++ > drivers/net/ethernet/intel/igc/igc_xdp.c | 4 +- > 3 files changed, 142 insertions(+), 2 deletions(-) > > diff --git a/drivers/net/ethernet/intel/igc/igc.h > b/drivers/net/ethernet/intel/igc/igc.h > index eac0f966e0e4..b1e46fcaae1a 100644 > --- a/drivers/net/ethernet/intel/igc/igc.h > +++ b/drivers/net/ethernet/intel/igc/igc.h > @@ -341,6 +341,8 @@ void igc_up(struct igc_adapter *adapter); > void igc_down(struct igc_adapter *adapter); > int igc_open(struct net_device *netdev); > int igc_close(struct net_device *netdev); > +void igc_xdp_open(struct net_device *netdev); > +void igc_xdp_close(struct net_device *netdev); > int igc_setup_tx_resources(struct igc_ring *ring); > int igc_setup_rx_resources(struct igc_ring *ring); > void igc_free_tx_resources(struct igc_ring *ring); > diff --git a/drivers/net/ethernet/intel/igc/igc_main.c > b/drivers/net/ethernet/intel/igc/igc_main.c > index 27872bdea9bd..098529a80b88 100644 > --- a/drivers/net/ethernet/intel/igc/igc_main.c > +++ b/drivers/net/ethernet/intel/igc/igc_main.c > @@ -6145,6 +6145,144 @@ int igc_close(struct net_device *netdev) > return 0; > } > > +void igc_xdp_open(struct net_device *netdev) > +{ > + struct igc_adapter *adapter = netdev_priv(netdev); > + struct pci_dev *pdev = adapter->pdev; > + struct igc_hw *hw = &adapter->hw; > + int err = 0; > + int i = 0; > + > + /* disallow open during test */ > + if (test_bit(__IGC_TESTING, &adapter->state)) > + return; > + > + pm_runtime_get_sync(&pdev->dev); > + > + igc_ptp_reset(adapter); > + > + /* allocate transmit descriptors */ > + err = igc_setup_all_tx_resources(adapter); > + if (err) > + goto err_setup_tx; > + > + /* allocate receive descriptors */ > + err = igc_setup_all_rx_resources(adapter); > + if (err) > + goto err_setup_rx; > + > + igc_setup_tctl(adapter); > + igc_setup_rctl(adapter); > + igc_configure_tx(adapter); > + igc_configure_rx(adapter); > + igc_rx_fifo_flush_base(&adapter->hw); > + > + /* call igc_desc_unused which always leaves > + * at least 1 descriptor unused to make sure > + * next_to_use != next_to_clean > + */ > + for (i = 0; i < adapter->num_rx_queues; i++) { > + struct igc_ring *ring = adapter->rx_ring[i]; > + > + if (ring->xsk_pool) > + igc_alloc_rx_buffers_zc(ring, igc_desc_unused(ring)); > + else > + igc_alloc_rx_buffers(ring, igc_desc_unused(ring)); > + } > + > + err = igc_request_irq(adapter); > + if (err) > + goto err_req_irq; > + > + clear_bit(__IGC_DOWN, &adapter->state); > + > + for (i = 0; i < adapter->num_q_vectors; i++) > + napi_enable(&adapter->q_vector[i]->napi); > + > + /* Clear any pending interrupts. */ > + rd32(IGC_ICR); > + igc_irq_enable(adapter); > + > + pm_runtime_put(&pdev->dev); > + > + netif_tx_start_all_queues(netdev); > + netif_carrier_on(netdev); > + > + return; > + > +err_req_irq: > + igc_release_hw_control(adapter); > + igc_power_down_phy_copper_base(&adapter->hw); > + igc_free_all_rx_resources(adapter); > +err_setup_rx: > + igc_free_all_tx_resources(adapter); > +err_setup_tx: > + igc_reset(adapter); > + pm_runtime_put(&pdev->dev); > +} > + > +void igc_xdp_close(struct net_device *netdev) > +{ > + struct igc_adapter *adapter = netdev_priv(netdev); > + struct pci_dev *pdev = adapter->pdev; > + struct igc_hw *hw = &adapter->hw; > + u32 tctl, rctl; > + int i = 0; > + > + WARN_ON(test_bit(__IGC_RESETTING, &adapter->state)); > + > + pm_runtime_get_sync(&pdev->dev); > + > + set_bit(__IGC_DOWN, &adapter->state); > + > + igc_ptp_suspend(adapter); > + > + if (pci_device_is_present(pdev)) { > + /* disable receives in the hardware */ > + rctl = rd32(IGC_RCTL); > + wr32(IGC_RCTL, rctl & ~IGC_RCTL_EN); > + /* flush and slee
Re: [Intel-wired-lan] [PATCH iwl-next 1/1] igc: Improve XDP_SETUP_PROG process
On Thursday, December 5, 2024 8:38 AM, Gomes, Vinicius wrote: >Song Yoong Siang writes: > >> Improve XDP_SETUP_PROG process by avoiding unnecessary link down/up event >> and hardware device reset. >> > >Some examples of problems that these hardware resets are causing would >be good. > Sure, maybe I can give an example of "before" and "after" behavior on ptp4l clock sync log in commit msg in next submission. >> Signed-off-by: Song Yoong Siang >> --- > >The duplication of code doesn't look that good. Initialization is >tricky, it seems to make it easy to update one place and forget to >update the other. > The original idea of this patch is to avoid huge changes on igc_open/igc_close functions. But I agree with you that duplication of code is challenging to maintain. I will create common function whenever necessary in next submission. >A couple of ideas: > - separate the code into functions that can be used from the "usual" > igc_open()/igc_close() flow; > - it seems that igc_close()/igc_open() are too big a hammer for > installing a new XDP program: what do we really need? (my mental model > is: 1. stop new traffic from going into any queue; 2. wait for any > packets "in progress"; 3. install the program; 4. resume operations; > what else?) I think will need to reallocate DMA resource, if user enable XDP pool first, then only setup XDP prog. Maybe I can reuse the reset sequence in igc_xdp_enable_pool(). I will study further. [...] > >Cheers, >-- >Vinicius Thanks & Regards Siang
Re: [Intel-wired-lan] [PATCH net-next] bridge: Make the FDB consider inner tag for Q-in-Q
> What stops you from changing the 802.1ad bridge port pvids to unique > values, like 3, 4, 5... instead of 3, 3, 3, and making each other > j != i bridge port be a non-pvid member of port i's pvid? I'm not sure if I understand this suggestion. I tried to draw out what you described here: https://docs.google.com/drawings/d/1UcOpENFgr-s6p8Ypwo-l4yTvtUZFM6vSLxLiX2FOMLU I'm not sure how host A can communicate with B with this configuration. Consider host A transmitting towards host B. When the frame leaves ".1q bridge 3", it will be tagged with .1q tag vid 7. When the frame leaves the .1ad bridge heading toward ".1q bridge 2", it will be tagged again with an outer .1ad tag vid 3. So ".1q bridge 2" will see the frame as having an outer tag of .1ad vid 3 and inner tag of .1q vid 7. Is that what you are thinking, or something else?
Re: [Intel-wired-lan] [PATCH net-next] bridge: Make the FDB consider inner tag for Q-in-Q
On Wed, Dec 04, 2024 at 12:37:24AM -0800, Andrew Strohman wrote: > > What stops you from changing the 802.1ad bridge port pvids to unique > > values, like 3, 4, 5... instead of 3, 3, 3, and making each other > > j != i bridge port be a non-pvid member of port i's pvid? > > I'm not sure if I understand this suggestion. > > I tried to draw out what you described here: > https://docs.google.com/drawings/d/1UcOpENFgr-s6p8Ypwo-l4yTvtUZFM6vSLxLiX2FOMLU > > I'm not sure how host A can communicate with B with this configuration. > > Consider host A transmitting towards host B. When the frame leaves > ".1q bridge 3", > it will be tagged with .1q tag vid 7. When the frame leaves the .1ad bridge > heading toward ".1q bridge 2", it will be tagged again with an outer > .1ad tag vid 3. > > So ".1q bridge 2" will see the frame as having an outer tag of .1ad vid 3 and > inner tag of .1q vid 7. > > Is that what you are thinking, or something else? I didn't say "tagged". I just said "not PVID". There are 2 independent bridge VLAN attributes: "pvid" and [egress-]"untagged". I am suggesting that packets in VID 3, 4, 5 all exit the 802.1ad bridge untagged, but every bridge port has a unique PVID from this range. bridge vlan add dev port1 vid 3 pvid untagged bridge vlan add dev port1 vid 4 untagged bridge vlan add dev port1 vid 5 untagged bridge vlan add dev port1 vid 3 untagged bridge vlan add dev port1 vid 4 pvid untagged bridge vlan add dev port1 vid 5 untagged bridge vlan add dev port1 vid 3 untagged bridge vlan add dev port1 vid 4 untagged bridge vlan add dev port1 vid 5 pvid untagged
Re: [Intel-wired-lan] [PATCHv3 net-next iwl-next] net: intel: use ethtool string helpers
On 11/5/24 06:47, Przemek Kitszel wrote: On 10/31/24 22:14, Rosen Penev wrote: The latter is the preferred way to copy ethtool strings. Avoids manually incrementing the pointer. Cleans up the code quite well. Signed-off-by: Rosen Penev --- v3: change custom get_strings to u8** to make sure pointer increments get propagated. I'm sorry for misleading you here, or perhaps not being clear enough. Let me restate: I'm fine with double pointer, but single pointer is also fine, no need to change if not used. And my biggest corncern is that you change big chunks of the code for no reason, please either drop those changes/those drivers, or adjust to have only minimal changes. please fine this complain embedded in the code inline for ice, igb, igc, and ixgbe I would be happy to accept your changes trimmed to the drivers I didn't complained about, I find that part a valuable contribution from you PS. No need to CC XDP/BFP list/people for such changes [removed those] v2: add iwl-next tag. use inline int in for loops. .../net/ethernet/intel/e1000/e1000_ethtool.c | 10 ++--- drivers/net/ethernet/intel/e1000e/ethtool.c | 14 +++--- .../net/ethernet/intel/fm10k/fm10k_ethtool.c | 10 ++--- .../net/ethernet/intel/i40e/i40e_ethtool.c | 6 +-- drivers/net/ethernet/intel/ice/ice_ethtool.c | 43 +++ drivers/net/ethernet/intel/igb/igb_ethtool.c | 35 --- drivers/net/ethernet/intel/igbvf/ethtool.c | 10 ++--- drivers/net/ethernet/intel/igc/igc_ethtool.c | 36 .../net/ethernet/intel/ixgbe/ixgbe_ethtool.c | 32 +++--- drivers/net/ethernet/intel/ixgbevf/ethtool.c | 36 ++-- 10 files changed, 118 insertions(+), 114 deletions(-)
[Intel-wired-lan] [PATCH v3 iwl-next] ice: Add in/out PTP pin delays
HW can have different input/output delays for each of the pins. Currently, only E82X adapters have delay compensation based on TSPLL config and E810 adapters have constant 1 ms compensation, both cases only for output delays and the same one for all pins. E825 adapters have different delays for SDP and other pins. Those delays are also based on direction and input delays are different than output ones. This is the main reason for moving delays to pin description structure. Add a field in ice_ptp_pin_desc structure to reflect that. Delay values are based on approximate calculations of HW delays based on HW spec. Implement external timestamp (input) delay compensation. Remove existing definitions and wrappers for periodic output propagation delays. Reviewed-by: Przemek Kitszel Signed-off-by: Karol Kolacinski --- V2 -> V3: rebased, renamed prop_delay to prop_delay_ns, reworded commit message to be more descriptive V1 -> V2: removed duplicate gpio_pin variable and restored missing ICE_E810_E830_SYNC_DELAY drivers/net/ethernet/intel/ice/ice_ptp.c | 82 +++ drivers/net/ethernet/intel/ice/ice_ptp.h | 2 + .../net/ethernet/intel/ice/ice_ptp_consts.h | 12 --- drivers/net/ethernet/intel/ice/ice_ptp_hw.h | 23 -- 4 files changed, 49 insertions(+), 70 deletions(-) diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c index d8ed4240f225..b2dba54e6457 100644 --- a/drivers/net/ethernet/intel/ice/ice_ptp.c +++ b/drivers/net/ethernet/intel/ice/ice_ptp.c @@ -16,28 +16,28 @@ static const char ice_pin_names[][64] = { }; static const struct ice_ptp_pin_desc ice_pin_desc_e82x[] = { - /* name,gpio */ - { TIME_SYNC, { 4, -1 }}, - { ONE_PPS, { -1, 5 }}, + /* name,gpio, delay */ + { TIME_SYNC, { 4, -1 }, { 0, 0 }}, + { ONE_PPS, { -1, 5 }, { 0, 11 }}, }; static const struct ice_ptp_pin_desc ice_pin_desc_e825c[] = { - /* name,gpio */ - { SDP0, { 0, 0 }}, - { SDP1, { 1, 1 }}, - { SDP2, { 2, 2 }}, - { SDP3, { 3, 3 }}, - { TIME_SYNC, { 4, -1 }}, - { ONE_PPS, { -1, 5 }}, + /* name,gpio, delay */ + { SDP0, { 0, 0 }, { 15, 14 }}, + { SDP1, { 1, 1 }, { 15, 14 }}, + { SDP2, { 2, 2 }, { 15, 14 }}, + { SDP3, { 3, 3 }, { 15, 14 }}, + { TIME_SYNC, { 4, -1 }, { 11, 0 }}, + { ONE_PPS, { -1, 5 }, { 0, 9 }}, }; static const struct ice_ptp_pin_desc ice_pin_desc_e810[] = { - /* name, gpio */ - { SDP0,{ 0, 0 }}, - { SDP1,{ 1, 1 }}, - { SDP2,{ 2, 2 }}, - { SDP3,{ 3, 3 }}, - { ONE_PPS, { -1, 5 }}, + /* name,gpio, delay */ + { SDP0, { 0, 0 }, { 0, 1 }}, + { SDP1, { 1, 1 }, { 0, 1 }}, + { SDP2, { 2, 2 }, { 0, 1 }}, + { SDP3, { 3, 3 }, { 0, 1 }}, + { ONE_PPS, { -1, 5 }, { 0, 1 }}, }; static const char ice_pin_names_nvm[][64] = { @@ -49,12 +49,12 @@ static const char ice_pin_names_nvm[][64] = { }; static const struct ice_ptp_pin_desc ice_pin_desc_e810_sma[] = { - /* name, gpio */ - { GNSS, { 1, -1 }}, - { SMA1, { 1, 0 }}, - { UFL1, { -1, 0 }}, - { SMA2, { 3, 2 }}, - { UFL2, { 3, -1 }}, + /* name, gpio, delay */ + { GNSS, { 1, -1 }, { 0, 0 }}, + { SMA1, { 1, 0 }, { 0, 1 }}, + { UFL1, { -1, 0 }, { 0, 1 }}, + { SMA2, { 3, 2 }, { 0, 1 }}, + { UFL2, { 3, -1 }, { 0, 0 }}, }; static struct ice_pf *ice_get_ctrl_pf(struct ice_pf *pf) @@ -1561,18 +1561,29 @@ void ice_ptp_extts_event(struct ice_pf *pf) * Event is defined in GLTSYN_EVNT_0 register */ for (chan = 0; chan < GLTSYN_EVNT_H_IDX_MAX; chan++) { + int pin_desc_idx; + /* Check if channel is enabled */ - if (pf->ptp.ext_ts_irq & (1 << chan)) { - lo = rd32(hw, GLTSYN_EVNT_L(chan, tmr_idx)); - hi = rd32(hw, GLTSYN_EVNT_H(chan, tmr_idx)); - event.timestamp = (((u64)hi) << 32) | lo; - event.type = PTP_CLOCK_EXTTS; - event.index = chan; - - /* Fire event */ - ptp_clock_event(pf->ptp.clock, &event); - pf->ptp.ext_ts_irq &= ~(1 << chan); + if (!(pf->ptp.ext_ts_irq & (1 << chan))) + continue; + + lo = rd32(hw, GLTSYN_EVNT_L(chan, tmr_idx)); + hi = rd32(hw, GLTSYN_EVNT_H(chan, tmr_idx)); + event.timestamp = (u64)hi << 32 | lo; + + /* Add delay compensation */ + pin_desc_idx = ice_ptp_find_pin_idx(pf, PTP_PF_EXTTS, chan); + if
Re: [Intel-wired-lan] [PATCH net-next] bridge: Make the FDB consider inner tag for Q-in-Q
> I didn't say "tagged". I just said "not PVID". There are 2 independent > bridge VLAN attributes: "pvid" and [egress-]"untagged". I am suggesting > that packets in VID 3, 4, 5 all exit the 802.1ad bridge untagged, but > every bridge port has a unique PVID from this range. > > bridge vlan add dev port1 vid 3 pvid untagged > bridge vlan add dev port1 vid 4 untagged > bridge vlan add dev port1 vid 5 untagged > > bridge vlan add dev port1 vid 3 untagged > bridge vlan add dev port1 vid 4 pvid untagged > bridge vlan add dev port1 vid 5 untagged > > bridge vlan add dev port1 vid 3 untagged > bridge vlan add dev port1 vid 4 untagged > bridge vlan add dev port1 vid 5 pvid untagged Thanks for the clarification. I think you meant to have the second set of three commands affect port2 and the third set of three commands affect port3. Please let me know if I'm wrong about this. I gave this a try: root@OpenWrt:~# bridge vlan show port vlan-id lan1 3 PVID Egress Untagged 4 Egress Untagged 5 Egress Untagged lan2 3 Egress Untagged 4 PVID Egress Untagged 5 Egress Untagged lan3 3 Egress Untagged 4 Egress Untagged 5 PVID Egress Untagged root@OpenWrt:~# bridge fdb show dynamic f4:a4:54:80:93:2f dev lan1 vlan 3 master br-lan e0:3f:49:47:9a:38 dev lan2 vlan 4 master br-lan f4:a4:54:81:7a:90 dev lan3 vlan 5 master br-lan Like you said, this has a FDB per port. But I think I need to have a FDB per inner/outer VLAN combination. Connectiving works as expected in the above example, but only because of unknown-unicast flood, which of course, is suboptimal. The switch is acting like a hub. For example, ever time the host behind lan1 sends a frame to the host behind lan2, the bridge is not able to find an FDB entry for the VID corresponding to PVID of lan1 and the MAC of the host behind lan2. The only FDB entry for the MAC corresponding to the host behind lan2 is associated with the VID corresponding to the PVID of lan2 (which is a different VID than what the packet arrived on). Hence, there is constant unicast flood. I also don't think that this solves the issue for https://docs.google.com/drawings/d/1FybJP3UyCPxVQRGxAqGztO4Qc5mgXclV4m-QEyfUFQ8 . If you like, I'm happy to explain why. But before I do, I want to make sure we are on the same page before going further. Thanks, Andy
Re: [Intel-wired-lan] [PATCH net-next] e1000e: Fix real-time violations on link up
On 12/3/24 21:28, Gerhard Engleder wrote: From: Gerhard Engleder From: Gerhard Engleder duplicated From: line Link down and up triggers update of MTA table. This update executes many PCIe writes and a final flush. Thus, PCIe will be blocked until all writes are flushed. As a result, DMA transfers of other targets suffer from delay in the range of 50us. This results in timing violations on real-time systems during link down and up of e1000e. A flush after a low enough number of PCIe writes eliminates the delay but also increases the time needed for MTA table update. The following measurements were done on i3-2310E with e1000e for 128 MTA table entries: Single flush after all writes: 106us Flush after every write: 429us Flush after every 2nd write: 266us Flush after every 4th write: 180us Flush after every 8th write: 141us Flush after every 16th write: 121us A flush after every 8th write delays the link up by 35us and the negative impact to DMA transfers of other targets is still tolerable. Execute a flush after every 8th write. This prevents overloading the interconnect with posted writes. As this also increases the time spent for MTA table update considerable this change is limited to PREEMPT_RT. hmm, why to limit this to PREEMPT_RT, the change sounds resonable also for the standard kernel, at last for me (perhaps with every 16th write instead) with that said, I'm fine with this patch as is too Signed-off-by: Gerhard Engleder would be good to add link to your RFC https://lore.kernel.org/netdev/f8fe665a-5e6c-4f95-b47a-2f3281aa0...@lunn.ch/T/ and also CC Vitaly who participated there (done), same for IWL mailing list (also CCd), and use iwl-next tag for your future contributions to intel ethernet --- drivers/net/ethernet/intel/e1000e/mac.c | 8 +++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/intel/e1000e/mac.c b/drivers/net/ethernet/intel/e1000e/mac.c index d7df2a0ed629..7a2c10a4ecc5 100644 --- a/drivers/net/ethernet/intel/e1000e/mac.c +++ b/drivers/net/ethernet/intel/e1000e/mac.c @@ -331,8 +331,14 @@ void e1000e_update_mc_addr_list_generic(struct e1000_hw *hw, } /* replace the entire MTA table */ - for (i = hw->mac.mta_reg_count - 1; i >= 0; i--) + for (i = hw->mac.mta_reg_count - 1; i >= 0; i--) { E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i, hw->mac.mta_shadow[i]); + if (IS_ENABLED(CONFIG_PREEMPT_RT)) { + /* do not queue up too many writes */ + if ((i % 8) == 0 && i != 0) + e1e_flush(); + } + } e1e_flush(); }
Re: [Intel-wired-lan] [PATCH net-next] bridge: Make the FDB consider inner tag for Q-in-Q
On Wed, Dec 04, 2024 at 02:12:18AM -0800, Andrew Strohman wrote: > > I didn't say "tagged". I just said "not PVID". There are 2 independent > > bridge VLAN attributes: "pvid" and [egress-]"untagged". I am suggesting > > that packets in VID 3, 4, 5 all exit the 802.1ad bridge untagged, but > > every bridge port has a unique PVID from this range. > > > > bridge vlan add dev port1 vid 3 pvid untagged > > bridge vlan add dev port1 vid 4 untagged > > bridge vlan add dev port1 vid 5 untagged > > > > bridge vlan add dev port1 vid 3 untagged > > bridge vlan add dev port1 vid 4 pvid untagged > > bridge vlan add dev port1 vid 5 untagged > > > > bridge vlan add dev port1 vid 3 untagged > > bridge vlan add dev port1 vid 4 untagged > > bridge vlan add dev port1 vid 5 pvid untagged > > Thanks for the clarification. I think you meant to have the second > set of three commands affect port2 and the third set of three > commands affect port3. Please let me know if I'm wrong > about this. Yes, it should have been port1, port2, port3. > I gave this a try: > > root@OpenWrt:~# bridge vlan show > port vlan-id > lan1 3 PVID Egress Untagged > 4 Egress Untagged > 5 Egress Untagged > lan2 3 Egress Untagged > 4 PVID Egress Untagged > 5 Egress Untagged > lan3 3 Egress Untagged > 4 Egress Untagged > 5 PVID Egress Untagged > root@OpenWrt:~# bridge fdb show dynamic > f4:a4:54:80:93:2f dev lan1 vlan 3 master br-lan > e0:3f:49:47:9a:38 dev lan2 vlan 4 master br-lan > f4:a4:54:81:7a:90 dev lan3 vlan 5 master br-lan > > Like you said, this has a FDB per port. But I think > I need to have a FDB per inner/outer VLAN combination. > > Connectiving works as expected in the above example, > but only because of unknown-unicast flood, which of course, > is suboptimal. The switch is acting like a hub. > > For example, ever time the host behind lan1 sends a frame > to the host behind lan2, the bridge is not able to find an FDB > entry for the VID corresponding to PVID of lan1 and the MAC > of the host behind lan2. The only FDB entry for the MAC > corresponding to the host behind lan2 is associated with > the VID corresponding to the PVID of lan2 (which is a > different VID than what the packet arrived on). > Hence, there is constant unicast flood. Yes, I understand this is the implication of my proposal. I just was under the impression that the behavior (complete segregation of stations in the 802.1ad bridge into multiple FDBs) would be equivalent with what you wish to achieve with the Outer+Inner VLAN lookup. To be more precise, I thought that you want to keep the outer VLAN into the mix for FDB lookups for exactly that reason, thus the suggestion to make the isolation at the 802.1ad bridge level directly. I didn't look with enough attention into the FDB dump, to see that in your example, only the inner VID gives the namespacing that you desire. But to be honest, looking again, I don't understand why just modifying the bridge to perform FDB lookups based on Inner VID + MAC DA wouldn't be sufficient? Why does it have to be Outer VID + Inner VID + MAC DA? I guess adding a bridge option to classify on the inner VLAN protocol could be easier to swallow, both for the software bridge and for switchdev. > I also don't think that this solves the issue for > https://docs.google.com/drawings/d/1FybJP3UyCPxVQRGxAqGztO4Qc5mgXclV4m-QEyfUFQ8 > . If you like, I'm happy to explain why. But before I do, I want to > make sure we are on the same page before going further. Here the same thing. The 802.1ad bridge has the same PVID on all ports. Why does the FDB lookup have to be as complex as to take 2 VIDs into consideration, instead of just the inner one?
[Intel-wired-lan] [PATCH iwl-net 0/4] igb: fix igb_msix_other() handling for PREEMPT_RT
This is the second attempt at fixing the behavior of igb_msix_other() for PREEMPT_RT. The previous attempt [1] was reverted [2] following concerns raised by Sebastian [3]. The initial approach proposed converting vfs_lock to a raw_spinlock, a minor change intended to make it safe. However, it became evident that igb_rcv_msg_from_vf() invokes kcalloc with GFP_ATOMIC, which is unsafe in interrupt context on PREEMPT_RT systems. To address this, the solution involves splitting igb_msg_task() into two parts: * One part invoked from the IRQ context. * Another part called from the threaded interrupt handler. To accommodate this, vfs_lock has been restructured into a double lock: a spinlock_t and a raw_spinlock_t. In the revised design: * igb_disable_sriov() locks both spinlocks. * Each part of igb_msg_task() locks the appropriate spinlock for its execution context. It is worth noting that the double lock mechanism is only active under PREEMPT_RT. For non-PREEMPT_RT builds, the additional raw_spinlock_t field is ommited. If the extra raw_spinlock_t field can be tolerated under !PREEMPT_RT (even though it remains unused), we can eliminate the need for #ifdefs and simplify the code structure. I will be on vacation from December 7th to Christmas and will address review comments upon my return. If possible, I kindly request the Intel team to perform smoke tests on both stock and realtime kernels to catch any potential issues with this patch series. Cheers, Wander [1] https://lore.kernel.org/all/20240920185918.616302-2-wan...@redhat.com/ [2] https://lore.kernel.org/all/20241104124050.22290-1-wan...@redhat.com/ [3] https://lore.kernel.org/all/20241104110708.gfyxr...@linutronix.de/ Wander Lairson Costa (4): igb: narrow scope of vfs_lock in SR-IOV cleanup igb: introduce raw vfs_lock to igb_adapter igb: split igb_msg_task() igb: fix igb_msix_other() handling for PREEMPT_RT drivers/net/ethernet/intel/igb/igb.h | 4 + drivers/net/ethernet/intel/igb/igb_main.c | 160 +++--- 2 files changed, 148 insertions(+), 16 deletions(-) -- 2.47.0
[Intel-wired-lan] [PATCH iwl-net 3/4] igb: split igb_msg_task()
>From the perspective of PREEMPT_RT, igb_msg_task() invokes functions that are a mix of IRQ-safe and non-IRQ-safe operations. To address this, we separate igb_msg_task() into distinct IRQ-safe and preemptible-safe components. This is a preparatory step for upcoming commits, where the igb_msix_other interrupt handler will be split into IRQ and threaded handlers, each invoking the appropriate part of the newly divided igb_msg_task(). Signed-off-by: Wander Lairson Costa --- drivers/net/ethernet/intel/igb/igb_main.c | 88 +-- 1 file changed, 81 insertions(+), 7 deletions(-) diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c index 9b4235ec226df..5828831fd29c2 100644 --- a/drivers/net/ethernet/intel/igb/igb_main.c +++ b/drivers/net/ethernet/intel/igb/igb_main.c @@ -149,6 +149,8 @@ static int igb_vlan_rx_kill_vid(struct net_device *, __be16, u16); static void igb_restore_vlan(struct igb_adapter *); static void igb_rar_set_index(struct igb_adapter *, u32); static void igb_ping_all_vfs(struct igb_adapter *); +static void igb_msg_task_irq_safe(struct igb_adapter *adapter); +static void igb_msg_task_preemptible_safe(struct igb_adapter *adapter); static void igb_msg_task(struct igb_adapter *); static void igb_vmm_control(struct igb_adapter *); static int igb_set_vf_mac(struct igb_adapter *, int, unsigned char *); @@ -3681,6 +3683,30 @@ static __always_inline void vfs_unlock_irqrestore(struct igb_adapter *adapter, raw_spin_unlock_irqrestore(&adapter->raw_vfs_lock, flags); spin_unlock_irqrestore(&adapter->vfs_lock, flags); } + +static __always_inline void vfs_spin_lock_irqsave(struct igb_adapter *adapter, + unsigned long *flags) +{ + spin_lock_irqsave(&adapter->vfs_lock, *flags); +} + +static __always_inline void vfs_spin_unlock_irqrestore(struct igb_adapter *adapter, + unsigned long flags) +{ + spin_unlock_irqrestore(&adapter->vfs_lock, flags); +} + +static __always_inline void vfs_raw_spin_lock_irqsave(struct igb_adapter *adapter, + unsigned long *flags) +{ + raw_spin_lock_irqsave(&adapter->raw_vfs_lock, *flags); +} + +static __always_inline void vfs_raw_spin_unlock_irqrestore(struct igb_adapter *adapter, + unsigned long flags) +{ + raw_spin_unlock_irqrestore(&adapter->raw_vfs_lock, flags); +} #else static __always_inline void vfs_lock_init(struct igb_adapter *adapter) { @@ -3696,6 +3722,30 @@ static __always_inline void vfs_unlock_irqrestore(struct igb_adapter *adapter, u { spin_unlock_irqrestore(&adapter->vfs_lock, flags); } + +static __always_inline void vfs_spin_lock_irqsave(struct igb_adapter *adapter, + unsigned long *flags) +{ + spin_lock_irqsave(&adapter->vfs_lock, *flags); +} + +static __always_inline void vfs_spin_unlock_irqrestore(struct igb_adapter *adapter, + unsigned long flags) +{ + spin_unlock_irqrestore(&adapter->vfs_lock, flags); +} + +static __always_inline void vfs_raw_spin_lock_irqsave(struct igb_adapter *adapter, + unsigned long *flags) +{ + spin_lock_irqsave(&adapter->vfs_lock, *flags); +} + +static __always_inline void vfs_raw_spin_unlock_irqrestore(struct igb_adapter *adapter, + unsigned long flags) +{ + spin_unlock_irqrestore(&adapter->vfs_lock, flags); +} #endif #ifdef CONFIG_PCI_IOV @@ -8070,27 +8120,51 @@ static void igb_rcv_msg_from_vf(struct igb_adapter *adapter, u32 vf) igb_unlock_mbx(hw, vf); } -static void igb_msg_task(struct igb_adapter *adapter) +/* + * Note: the split of irq and preempible safe parts of igb_msg_task() + * only makes sense under PREEMPT_RT. + * The root cause of igb_rcv_msg_from_vf() is not IRQ safe is because + * it calls kcalloc with GFP_ATOMIC, but GFP_ATOMIC is not IRQ safe + * in PREEMPT_RT. + */ +static void igb_msg_task_irq_safe(struct igb_adapter *adapter) { struct e1000_hw *hw = &adapter->hw; unsigned long flags; u32 vf; - vfs_lock_irqsave(adapter, &flags); + vfs_raw_spin_lock_irqsave(adapter, &flags); for (vf = 0; vf < adapter->vfs_allocated_count; vf++) { /* process any reset requests */ if (!igb_check_for_rst(hw, vf)) igb_vf_reset_event(adapter, vf); - /* process any messages pending */ - if (!igb_check_for_msg(hw, vf)) - igb_rcv_msg_from_vf(adapter, vf); - /* process any acks */ if (!igb_check_for_ack(hw, vf)) igb_rcv_ack_from_vf(adapter, vf); } -
[Intel-wired-lan] [PATCH iwl-net 4/4] igb: fix igb_msix_other() handling for PREEMPT_RT
During testing of SR-IOV, Red Hat QE encountered an issue where the ip link up command intermittently fails for the igbvf interfaces when using the PREEMPT_RT variant. Investigation revealed that e1000_write_posted_mbx returns an error due to the lack of an ACK from e1000_poll_for_ack. The underlying issue arises from the fact that IRQs are threaded by default under PREEMPT_RT. While the exact hardware details are not available, it appears that the IRQ handled by igb_msix_other must be processed before e1000_poll_for_ack times out. However, e1000_write_posted_mbx is called with preemption disabled, leading to a scenario where the IRQ is serviced only after the failure of e1000_write_posted_mbx. Commit 338c4d3902fe ("igb: Disable threaded IRQ for igb_msix_other") forced the ISR to run in a non-threaded context. However, Sebastian observed that some functions called within the ISR acquire locks that may sleep. In the previous two patches, we managed to make igb_msg_mask() safe to call from an interrupt context. In this commit, we move most of the ISR handling to an interrupt context, leaving non IRQ safe code to be called from the thread context under PREEMPT_RT. Reproducer: ipaddr_vlan=3 nic_test=ens14f0 vf=${nic_test}v0 # The main testing steps: while true; do ip link set ${nic_test} mtu 1500 ip link set ${vf} mtu 1500 ip link set $vf up # 3. set vlan and ip for VF ip link set ${nic_test} vf 0 vlan ${ipaddr_vlan} ip addr add 172.30.${ipaddr_vlan}.1/24 dev ${vf} ip addr add 2021:db8:${ipaddr_vlan}::1/64 dev ${vf} # 4. check the link state for VF and PF ip link show ${nic_test} if ! ip link show $vf | grep 'state UP'; then echo 'Error found' break fi ip link set $vf down done You can also reproduce it more reliably by setting nr_cpus=1 in the kernel command line. Fixes: 9d5c824399de ("igb: PCI-Express 82575 Gigabit Ethernet driver") Signed-off-by: Wander Lairson Costa Reported-by: Yuying Ma --- drivers/net/ethernet/intel/igb/igb_main.c | 35 --- 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c index 5828831fd29c2..b2894cebe2c9e 100644 --- a/drivers/net/ethernet/intel/igb/igb_main.c +++ b/drivers/net/ethernet/intel/igb/igb_main.c @@ -131,6 +131,7 @@ static void igb_set_uta(struct igb_adapter *adapter, bool set); static irqreturn_t igb_intr(int irq, void *); static irqreturn_t igb_intr_msi(int irq, void *); static irqreturn_t igb_msix_other(int irq, void *); +static irqreturn_t igb_msix_other_threaded(int irq, void *); static irqreturn_t igb_msix_ring(int irq, void *); #ifdef CONFIG_IGB_DCA static void igb_update_dca(struct igb_q_vector *); @@ -151,7 +152,6 @@ static void igb_rar_set_index(struct igb_adapter *, u32); static void igb_ping_all_vfs(struct igb_adapter *); static void igb_msg_task_irq_safe(struct igb_adapter *adapter); static void igb_msg_task_preemptible_safe(struct igb_adapter *adapter); -static void igb_msg_task(struct igb_adapter *); static void igb_vmm_control(struct igb_adapter *); static int igb_set_vf_mac(struct igb_adapter *, int, unsigned char *); static void igb_flush_mac_table(struct igb_adapter *); @@ -908,8 +908,9 @@ static int igb_request_msix(struct igb_adapter *adapter) struct net_device *netdev = adapter->netdev; int i, err = 0, vector = 0, free_vector = 0; - err = request_irq(adapter->msix_entries[vector].vector, - igb_msix_other, 0, netdev->name, adapter); + err = request_threaded_irq(adapter->msix_entries[vector].vector, + igb_msix_other, igb_msix_other_threaded, + IRQF_NO_THREAD, netdev->name, adapter); if (err) goto err_out; @@ -7113,9 +7114,27 @@ static irqreturn_t igb_msix_other(int irq, void *data) igb_check_wvbr(adapter); } - /* Check for a mailbox event */ + /* Check for a mailbox event (interrupt safe part) */ if (icr & E1000_ICR_VMMB) - igb_msg_task(adapter); + igb_msg_task_irq_safe(adapter); + + adapter->test_icr = icr; + + if (!IS_ENABLED(CONFIG_PREEMPT_RT)) + return igb_msix_other_threaded(irq, data); + + return IRQ_WAKE_THREAD; +} + +static irqreturn_t igb_msix_other_threaded(int irq, void *data) +{ + struct igb_adapter *adapter = data; + struct e1000_hw *hw = &adapter->hw; + u32 icr = adapter->test_icr; + + /* Check for a mailbox event (preempible safe part) */ + if (icr & E1000_ICR_VMMB) + igb_msg_task_preemptible_safe(adapter); if (icr & E1000_ICR_LSC) { hw->mac.get_link_status = 1; @@ -8161,12 +8180,6 @@ static void igb_msg_task_preemptible_safe(struct igb_adapter *adapter) vfs_spin_unlock_irqrestore(adapter, flags); } -static
[Intel-wired-lan] [PATCH iwl-net 2/4] igb: introduce raw vfs_lock to igb_adapter
This change adds a raw_spinlock for the vfs_lock to the igb_adapter structure, enabling its use in both interrupt and preemptible contexts. This is essential for upcoming modifications to split igb_msg_task() into interrupt-safe and preemptible-safe parts. The motivation for this change stems from the need to modify igb_msix_other() to run in interrupt context under PREEMPT_RT. Currently, igb_msg_task() contains a code path that invokes kcalloc() with the GFP_ATOMIC flag. However, on PREEMPT_RT, GFP_ATOMIC is not honored, making it unsafe to call allocation functions in interrupt context. By introducing this raw spinlock, we can safely acquire the lock in both contexts, paving the way for the necessary restructuring of igb_msg_task(). Signed-off-by: Wander Lairson Costa Suggested-by: Clark Williams --- drivers/net/ethernet/intel/igb/igb.h | 4 ++ drivers/net/ethernet/intel/igb/igb_main.c | 51 --- 2 files changed, 50 insertions(+), 5 deletions(-) diff --git a/drivers/net/ethernet/intel/igb/igb.h b/drivers/net/ethernet/intel/igb/igb.h index 3c2dc7bdebb50..d50c22f09d0f8 100644 --- a/drivers/net/ethernet/intel/igb/igb.h +++ b/drivers/net/ethernet/intel/igb/igb.h @@ -666,6 +666,10 @@ struct igb_adapter { struct vf_mac_filter *vf_mac_list; /* lock for VF resources */ spinlock_t vfs_lock; +#ifdef CONFIG_PREEMPT_RT + /* Used to lock VFS in interrupt context under PREEMPT_RT */ + raw_spinlock_t raw_vfs_lock; +#endif }; /* flags controlling PTP/1588 function */ diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c index 4ca25660e876e..9b4235ec226df 100644 --- a/drivers/net/ethernet/intel/igb/igb_main.c +++ b/drivers/net/ethernet/intel/igb/igb_main.c @@ -3657,6 +3657,47 @@ static int igb_probe(struct pci_dev *pdev, const struct pci_device_id *ent) return err; } +#ifdef CONFIG_PREEMPT_RT +static __always_inline void vfs_lock_init(struct igb_adapter *adapter) +{ + spin_lock_init(&adapter->vfs_lock); + raw_spin_lock_init(&adapter->raw_vfs_lock); +} + +static __always_inline void vfs_lock_irqsave(struct igb_adapter *adapter, +unsigned long *flags) +{ + /* +* Remember that under PREEMPT_RT spin_lock_irqsave +* ignores the flags parameter +*/ + spin_lock_irqsave(&adapter->vfs_lock, *flags); + raw_spin_lock_irqsave(&adapter->raw_vfs_lock, *flags); +} + +static __always_inline void vfs_unlock_irqrestore(struct igb_adapter *adapter, + unsigned long flags) +{ + raw_spin_unlock_irqrestore(&adapter->raw_vfs_lock, flags); + spin_unlock_irqrestore(&adapter->vfs_lock, flags); +} +#else +static __always_inline void vfs_lock_init(struct igb_adapter *adapter) +{ + spin_lock_init(&adapter->vfs_lock); +} + +static __always_inline void vfs_lock_irqsave(struct igb_adapter *adapter, unsigned long *flags) +{ + spin_lock_irqsave(&adapter->vfs_lock, *flags); +} + +static __always_inline void vfs_unlock_irqrestore(struct igb_adapter *adapter, unsigned long flags) +{ + spin_unlock_irqrestore(&adapter->vfs_lock, flags); +} +#endif + #ifdef CONFIG_PCI_IOV static int igb_sriov_reinit(struct pci_dev *dev) { @@ -3707,9 +3748,9 @@ static int igb_disable_sriov(struct pci_dev *pdev, bool reinit) pci_disable_sriov(pdev); msleep(500); } - spin_lock_irqsave(&adapter->vfs_lock, flags); + vfs_lock_irqsave(adapter, &flags); adapter->vfs_allocated_count = 0; - spin_unlock_irqrestore(&adapter->vfs_lock, flags); + vfs_unlock_irqrestore(adapter, flags); kfree(adapter->vf_mac_list); adapter->vf_mac_list = NULL; kfree(adapter->vf_data); @@ -4042,7 +4083,7 @@ static int igb_sw_init(struct igb_adapter *adapter) spin_lock_init(&adapter->stats64_lock); /* init spinlock to avoid concurrency of VF resources */ - spin_lock_init(&adapter->vfs_lock); + vfs_lock_init(adapter); #ifdef CONFIG_PCI_IOV switch (hw->mac.type) { case e1000_82576: @@ -8035,7 +8076,7 @@ static void igb_msg_task(struct igb_adapter *adapter) unsigned long flags; u32 vf; - spin_lock_irqsave(&adapter->vfs_lock, flags); + vfs_lock_irqsave(adapter, &flags); for (vf = 0; vf < adapter->vfs_allocated_count; vf++) { /* process any reset requests */ if (!igb_check_for_rst(hw, vf)) @@ -8049,7 +8090,7 @@ static void igb_msg_task(struct igb_adapter *adapter) if (!igb_check_for_ack(hw, vf)) igb_rcv_ack_from_vf(adapter, vf); } - spin_unlock_irqrestore(&adapter->vfs_lock, flags); + vfs_unlock_irqrestore(adapter, flags); } /** -- 2.47.0
[Intel-wired-lan] [PATCH iwl-net 1/4] igb: narrow scope of vfs_lock in SR-IOV cleanup
The adapter->vfs_lock currently protects critical sections shared between igb_disable_sriov() and igb_msg_task(). Since igb_msg_task() — which is invoked solely by the igb_msix_other() ISR—only proceeds when adapter->vfs_allocated_count > 0, we can reduce the lock scope further. By moving the assignment adapter->vfs_allocated_count = 0 to the start of the cleanup code in igb_disable_sriov(), we can restrict the spinlock protection solely to this assignment. This change removes kfree() calls from within the locked section, simplifying lock management. Once kfree() is outside the vfs_lock scope, it becomes possible to safely convert vfs_lock to a raw_spin_lock. Signed-off-by: Wander Lairson Costa --- drivers/net/ethernet/intel/igb/igb_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c index 08578980b6518..4ca25660e876e 100644 --- a/drivers/net/ethernet/intel/igb/igb_main.c +++ b/drivers/net/ethernet/intel/igb/igb_main.c @@ -3708,12 +3708,12 @@ static int igb_disable_sriov(struct pci_dev *pdev, bool reinit) msleep(500); } spin_lock_irqsave(&adapter->vfs_lock, flags); + adapter->vfs_allocated_count = 0; + spin_unlock_irqrestore(&adapter->vfs_lock, flags); kfree(adapter->vf_mac_list); adapter->vf_mac_list = NULL; kfree(adapter->vf_data); adapter->vf_data = NULL; - adapter->vfs_allocated_count = 0; - spin_unlock_irqrestore(&adapter->vfs_lock, flags); wr32(E1000_IOVCTL, E1000_IOVCTL_REUSE_VFQ); wrfl(); msleep(100); -- 2.47.0
[Intel-wired-lan] [PATCH iwl-next 1/1] igc: Improve XDP_SETUP_PROG process
Improve XDP_SETUP_PROG process by avoiding unnecessary link down/up event and hardware device reset. Signed-off-by: Song Yoong Siang --- drivers/net/ethernet/intel/igc/igc.h | 2 + drivers/net/ethernet/intel/igc/igc_main.c | 138 ++ drivers/net/ethernet/intel/igc/igc_xdp.c | 4 +- 3 files changed, 142 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/intel/igc/igc.h b/drivers/net/ethernet/intel/igc/igc.h index eac0f966e0e4..b1e46fcaae1a 100644 --- a/drivers/net/ethernet/intel/igc/igc.h +++ b/drivers/net/ethernet/intel/igc/igc.h @@ -341,6 +341,8 @@ void igc_up(struct igc_adapter *adapter); void igc_down(struct igc_adapter *adapter); int igc_open(struct net_device *netdev); int igc_close(struct net_device *netdev); +void igc_xdp_open(struct net_device *netdev); +void igc_xdp_close(struct net_device *netdev); int igc_setup_tx_resources(struct igc_ring *ring); int igc_setup_rx_resources(struct igc_ring *ring); void igc_free_tx_resources(struct igc_ring *ring); diff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c index 27872bdea9bd..098529a80b88 100644 --- a/drivers/net/ethernet/intel/igc/igc_main.c +++ b/drivers/net/ethernet/intel/igc/igc_main.c @@ -6145,6 +6145,144 @@ int igc_close(struct net_device *netdev) return 0; } +void igc_xdp_open(struct net_device *netdev) +{ + struct igc_adapter *adapter = netdev_priv(netdev); + struct pci_dev *pdev = adapter->pdev; + struct igc_hw *hw = &adapter->hw; + int err = 0; + int i = 0; + + /* disallow open during test */ + if (test_bit(__IGC_TESTING, &adapter->state)) + return; + + pm_runtime_get_sync(&pdev->dev); + + igc_ptp_reset(adapter); + + /* allocate transmit descriptors */ + err = igc_setup_all_tx_resources(adapter); + if (err) + goto err_setup_tx; + + /* allocate receive descriptors */ + err = igc_setup_all_rx_resources(adapter); + if (err) + goto err_setup_rx; + + igc_setup_tctl(adapter); + igc_setup_rctl(adapter); + igc_configure_tx(adapter); + igc_configure_rx(adapter); + igc_rx_fifo_flush_base(&adapter->hw); + + /* call igc_desc_unused which always leaves +* at least 1 descriptor unused to make sure +* next_to_use != next_to_clean +*/ + for (i = 0; i < adapter->num_rx_queues; i++) { + struct igc_ring *ring = adapter->rx_ring[i]; + + if (ring->xsk_pool) + igc_alloc_rx_buffers_zc(ring, igc_desc_unused(ring)); + else + igc_alloc_rx_buffers(ring, igc_desc_unused(ring)); + } + + err = igc_request_irq(adapter); + if (err) + goto err_req_irq; + + clear_bit(__IGC_DOWN, &adapter->state); + + for (i = 0; i < adapter->num_q_vectors; i++) + napi_enable(&adapter->q_vector[i]->napi); + + /* Clear any pending interrupts. */ + rd32(IGC_ICR); + igc_irq_enable(adapter); + + pm_runtime_put(&pdev->dev); + + netif_tx_start_all_queues(netdev); + netif_carrier_on(netdev); + + return; + +err_req_irq: + igc_release_hw_control(adapter); + igc_power_down_phy_copper_base(&adapter->hw); + igc_free_all_rx_resources(adapter); +err_setup_rx: + igc_free_all_tx_resources(adapter); +err_setup_tx: + igc_reset(adapter); + pm_runtime_put(&pdev->dev); +} + +void igc_xdp_close(struct net_device *netdev) +{ + struct igc_adapter *adapter = netdev_priv(netdev); + struct pci_dev *pdev = adapter->pdev; + struct igc_hw *hw = &adapter->hw; + u32 tctl, rctl; + int i = 0; + + WARN_ON(test_bit(__IGC_RESETTING, &adapter->state)); + + pm_runtime_get_sync(&pdev->dev); + + set_bit(__IGC_DOWN, &adapter->state); + + igc_ptp_suspend(adapter); + + if (pci_device_is_present(pdev)) { + /* disable receives in the hardware */ + rctl = rd32(IGC_RCTL); + wr32(IGC_RCTL, rctl & ~IGC_RCTL_EN); + /* flush and sleep below */ + } + /* set trans_start so we don't get spurious watchdogs during reset */ + netif_trans_update(netdev); + + netif_carrier_off(netdev); + netif_tx_stop_all_queues(netdev); + + if (pci_device_is_present(pdev)) { + /* disable transmits in the hardware */ + tctl = rd32(IGC_TCTL); + tctl &= ~IGC_TCTL_EN; + wr32(IGC_TCTL, tctl); + /* flush both disables and wait for them to finish */ + wrfl(); + usleep_range(1, 2); + + igc_irq_disable(adapter); + } + + for (i = 0; i < adapter->num_q_vectors; i++) { + if (adapter->q_vector[i]) { + napi_synchronize(&adapter->q_vector[i]->napi)
[Intel-wired-lan] [PATCH iwl-next v2] ice: fw and port health status
Firmware generates events for global events or port specific events. Driver shall subscribe for health status events from firmware on supported FW versions >= 1.7.6. Driver shall expose those under specific health reporter, two new reporters are introduced: - FW health reporter shall represent global events (problems with the image, recovery mode); - Port health reporter shall represent port-specific events (module failure). Firmware only reports problems when those are detected, it does not store active fault list. Driver will hold only last global and last port-specific event. Driver will report all events via devlink health report, so in case of multiple events of the same source they can be reviewed using devlink autodump feature. $ devlink health pci/:b1:00.3: reporter fw state healthy error 0 recover 0 auto_dump true reporter port state error error 1 recover 0 last_dump_date 2024-03-17 last_dump_time 09:29:29 auto_dump true $ devlink health diagnose pci/:b1:00.3 reporter port Syndrome: 262 Description: Module is not present. Possible Solution: Check that the module is inserted correctly. Port Number: 0 Tested on Intel Corporation Ethernet Controller E810-C for SFP Co-developed-by: Sharon Haroni Signed-off-by: Sharon Haroni Co-developed-by: Nicholas Nunley Signed-off-by: Nicholas Nunley Co-developed-by: Brett Creeley Signed-off-by: Brett Creeley Signed-off-by: Konrad Knitter --- v2: - Removal of __VA_OPS__ usage. Style fixes. Depends-on: https://lore.kernel.org/netdev/20240930133724.610512-1-przemyslaw.kits...@intel.com/T/ --- .../net/ethernet/intel/ice/devlink/health.c | 253 +- .../net/ethernet/intel/ice/devlink/health.h | 14 +- .../net/ethernet/intel/ice/ice_adminq_cmd.h | 87 ++ drivers/net/ethernet/intel/ice/ice_common.c | 38 +++ drivers/net/ethernet/intel/ice/ice_common.h | 2 + drivers/net/ethernet/intel/ice/ice_main.c | 3 + drivers/net/ethernet/intel/ice/ice_type.h | 5 + 7 files changed, 400 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/intel/ice/devlink/health.c b/drivers/net/ethernet/intel/ice/devlink/health.c index c7a8b8c9e1ca..c5a16879c916 100644 --- a/drivers/net/ethernet/intel/ice/devlink/health.c +++ b/drivers/net/ethernet/intel/ice/devlink/health.c @@ -1,13 +1,251 @@ // SPDX-License-Identifier: GPL-2.0 /* Copyright (c) 2024, Intel Corporation. */ -#include "health.h" #include "ice.h" +#include "ice_adminq_cmd.h" /* for enum ice_aqc_health_status_elem */ +#include "health.h" #include "ice_ethtool_common.h" #define ICE_DEVLINK_FMSG_PUT_FIELD(fmsg, obj, name) \ devlink_fmsg_put(fmsg, #name, (obj)->name) +#define ICE_HEALTH_STATUS_DATA_SIZE 2 + +struct ice_health_status { + enum ice_aqc_health_status code; + const char *description; + const char *solution; + const char *data_label[ICE_HEALTH_STATUS_DATA_SIZE]; +}; + +/* + * In addition to the health status codes provided below, the firmware might + * generate Health Status Codes that are not pertinent to the end-user. + * For instance, Health Code 0x1002 is triggered when the command fails. + * Such codes should be disregarded by the end-user. + * The below lookup requires to be sorted by code. + */ + +static const char *const ice_common_port_solutions = + "Check your cable connection. Change or replace the module or cable. Manually set speed and duplex."; +static const char *const ice_port_number_label = "Port Number"; +static const char *const ice_update_nvm_solution = "Update to the latest NVM image."; + +static const struct ice_health_status ice_health_status_lookup[] = { + {ICE_AQC_HEALTH_STATUS_ERR_UNKNOWN_MOD_STRICT, "An unsupported module was detected", + ice_common_port_solutions, {ice_port_number_label}}, + {ICE_AQC_HEALTH_STATUS_ERR_MOD_TYPE, "Module type is not supported.", + "Change or replace the module or cable.", {ice_port_number_label}}, + {ICE_AQC_HEALTH_STATUS_ERR_MOD_QUAL, "Module is not qualified.", + ice_common_port_solutions, {ice_port_number_label}}, + {ICE_AQC_HEALTH_STATUS_ERR_MOD_COMM, + "Device cannot communicate with the module.", + "Check your cable connection. Change or replace the module or cable. Manually set speed and duplex.", + {ice_port_number_label}}, + {ICE_AQC_HEALTH_STATUS_ERR_MOD_CONFLICT, "Unresolved module conflict.", + "Manually set speed/duplex or change the port option. If the problem persists, use a cable/module that is found in the supported modules and cables list for this device.", + {ice_port_number_label}}, + {ICE_AQC_HEALTH_STATUS_ERR_MOD_NOT_PRESENT, "Module is not present.", + "Check that the module is inserted correctly. If the problem persists, use a cable/module that is found in the supported modules and cables list for this device.", +
Re: [Intel-wired-lan] [PATCH iwl-next v2] ice: fw and port health status
Dear Konrad, Thank you for your patch. It’d be great if you made the commit message summary/title a statement by adding a verb (in imperative mood). Maybe: ice: Support for fw and port health status Am 04.12.24 um 13:27 schrieb Konrad Knitter: Firmware generates events for global events or port specific events. Driver shall subscribe for health status events from firmware on supported FW versions >= 1.7.6. Please add a blank line between paragraphs, or do not break the line just because a new sentence starts. Driver shall expose those under specific health reporter, two new reporters are introduced: - FW health reporter shall represent global events (problems with the image, recovery mode); - Port health reporter shall represent port-specific events (module failure). Firmware only reports problems when those are detected, it does not store active fault list. Driver will hold only last global and last port-specific event. Driver will report all events via devlink health report, so in case of multiple events of the same source they can be reviewed using devlink autodump feature. $ devlink health pci/:b1:00.3: reporter fw state healthy error 0 recover 0 auto_dump true reporter port state error error 1 recover 0 last_dump_date 2024-03-17 last_dump_time 09:29:29 auto_dump true $ devlink health diagnose pci/:b1:00.3 reporter port Syndrome: 262 Description: Module is not present. Possible Solution: Check that the module is inserted correctly. Port Number: 0 Tested on Intel Corporation Ethernet Controller E810-C for SFP Thank you for adding the above information. Co-developed-by: Sharon Haroni Signed-off-by: Sharon Haroni Co-developed-by: Nicholas Nunley Signed-off-by: Nicholas Nunley Co-developed-by: Brett Creeley Signed-off-by: Brett Creeley Signed-off-by: Konrad Knitter --- v2: - Removal of __VA_OPS__ usage. Style fixes. Depends-on: https://lore.kernel.org/netdev/20240930133724.610512-1-przemyslaw.kits...@intel.com/T/ --- .../net/ethernet/intel/ice/devlink/health.c | 253 +- .../net/ethernet/intel/ice/devlink/health.h | 14 +- .../net/ethernet/intel/ice/ice_adminq_cmd.h | 87 ++ drivers/net/ethernet/intel/ice/ice_common.c | 38 +++ drivers/net/ethernet/intel/ice/ice_common.h | 2 + drivers/net/ethernet/intel/ice/ice_main.c | 3 + drivers/net/ethernet/intel/ice/ice_type.h | 5 + 7 files changed, 400 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/intel/ice/devlink/health.c b/drivers/net/ethernet/intel/ice/devlink/health.c index c7a8b8c9e1ca..c5a16879c916 100644 --- a/drivers/net/ethernet/intel/ice/devlink/health.c +++ b/drivers/net/ethernet/intel/ice/devlink/health.c @@ -1,13 +1,251 @@ // SPDX-License-Identifier: GPL-2.0 /* Copyright (c) 2024, Intel Corporation. */ -#include "health.h" #include "ice.h" +#include "ice_adminq_cmd.h" /* for enum ice_aqc_health_status_elem */ +#include "health.h" #include "ice_ethtool_common.h" #define ICE_DEVLINK_FMSG_PUT_FIELD(fmsg, obj, name) \ devlink_fmsg_put(fmsg, #name, (obj)->name) +#define ICE_HEALTH_STATUS_DATA_SIZE 2 + +struct ice_health_status { + enum ice_aqc_health_status code; + const char *description; + const char *solution; + const char *data_label[ICE_HEALTH_STATUS_DATA_SIZE]; +}; + +/* + * In addition to the health status codes provided below, the firmware might + * generate Health Status Codes that are not pertinent to the end-user. + * For instance, Health Code 0x1002 is triggered when the command fails. + * Such codes should be disregarded by the end-user. + * The below lookup requires to be sorted by code. + */ + +static const char *const ice_common_port_solutions = + "Check your cable connection. Change or replace the module or cable. Manually set speed and duplex."; +static const char *const ice_port_number_label = "Port Number"; +static const char *const ice_update_nvm_solution = "Update to the latest NVM image."; + +static const struct ice_health_status ice_health_status_lookup[] = { + {ICE_AQC_HEALTH_STATUS_ERR_UNKNOWN_MOD_STRICT, "An unsupported module was detected", + ice_common_port_solutions, {ice_port_number_label}}, + {ICE_AQC_HEALTH_STATUS_ERR_MOD_TYPE, "Module type is not supported.", + "Change or replace the module or cable.", {ice_port_number_label}}, + {ICE_AQC_HEALTH_STATUS_ERR_MOD_QUAL, "Module is not qualified.", + ice_common_port_solutions, {ice_port_number_label}}, + {ICE_AQC_HEALTH_STATUS_ERR_MOD_COMM, + "Device cannot communicate with the module.", + "Check your cable connection. Change or replace the module or cable. Manually set speed and duplex.", + {ice_port_number_label}}, + {ICE_AQC_HEALTH_STATUS_ERR_MOD_CONFLICT, "Unresolved module conflict.", + "Manually set speed/duplex or change the port
Re: [Intel-wired-lan] [PATCH iwl-next v2] ice: fw and port health status
[Cc: -Brett, -Nicholas (550 #5.1.0 Address rejected.)] Am 04.12.24 um 13:34 schrieb Paul Menzel: Dear Konrad, Thank you for your patch. It’d be great if you made the commit message summary/title a statement by adding a verb (in imperative mood). Maybe: ice: Support for fw and port health status Am 04.12.24 um 13:27 schrieb Konrad Knitter: Firmware generates events for global events or port specific events. Driver shall subscribe for health status events from firmware on supported FW versions >= 1.7.6. Please add a blank line between paragraphs, or do not break the line just because a new sentence starts. Driver shall expose those under specific health reporter, two new reporters are introduced: - FW health reporter shall represent global events (problems with the image, recovery mode); - Port health reporter shall represent port-specific events (module failure). Firmware only reports problems when those are detected, it does not store active fault list. Driver will hold only last global and last port-specific event. Driver will report all events via devlink health report, so in case of multiple events of the same source they can be reviewed using devlink autodump feature. $ devlink health pci/:b1:00.3: reporter fw state healthy error 0 recover 0 auto_dump true reporter port state error error 1 recover 0 last_dump_date 2024-03-17 last_dump_time 09:29:29 auto_dump true $ devlink health diagnose pci/:b1:00.3 reporter port Syndrome: 262 Description: Module is not present. Possible Solution: Check that the module is inserted correctly. Port Number: 0 Tested on Intel Corporation Ethernet Controller E810-C for SFP Thank you for adding the above information. Co-developed-by: Sharon Haroni Signed-off-by: Sharon Haroni Co-developed-by: Nicholas Nunley Signed-off-by: Nicholas Nunley Co-developed-by: Brett Creeley Signed-off-by: Brett Creeley Signed-off-by: Konrad Knitter --- v2: - Removal of __VA_OPS__ usage. Style fixes. Depends-on: https://lore.kernel.org/netdev/20240930133724.610512-1- przemyslaw.kits...@intel.com/T/ --- .../net/ethernet/intel/ice/devlink/health.c | 253 +- .../net/ethernet/intel/ice/devlink/health.h | 14 +- .../net/ethernet/intel/ice/ice_adminq_cmd.h | 87 ++ drivers/net/ethernet/intel/ice/ice_common.c | 38 +++ drivers/net/ethernet/intel/ice/ice_common.h | 2 + drivers/net/ethernet/intel/ice/ice_main.c | 3 + drivers/net/ethernet/intel/ice/ice_type.h | 5 + 7 files changed, 400 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/intel/ice/devlink/health.c b/drivers/net/ethernet/intel/ice/devlink/health.c index c7a8b8c9e1ca..c5a16879c916 100644 --- a/drivers/net/ethernet/intel/ice/devlink/health.c +++ b/drivers/net/ethernet/intel/ice/devlink/health.c @@ -1,13 +1,251 @@ // SPDX-License-Identifier: GPL-2.0 /* Copyright (c) 2024, Intel Corporation. */ -#include "health.h" #include "ice.h" +#include "ice_adminq_cmd.h" /* for enum ice_aqc_health_status_elem */ +#include "health.h" #include "ice_ethtool_common.h" #define ICE_DEVLINK_FMSG_PUT_FIELD(fmsg, obj, name) \ devlink_fmsg_put(fmsg, #name, (obj)->name) +#define ICE_HEALTH_STATUS_DATA_SIZE 2 + +struct ice_health_status { + enum ice_aqc_health_status code; + const char *description; + const char *solution; + const char *data_label[ICE_HEALTH_STATUS_DATA_SIZE]; +}; + +/* + * In addition to the health status codes provided below, the firmware might + * generate Health Status Codes that are not pertinent to the end-user. + * For instance, Health Code 0x1002 is triggered when the command fails. + * Such codes should be disregarded by the end-user. + * The below lookup requires to be sorted by code. + */ + +static const char *const ice_common_port_solutions = + "Check your cable connection. Change or replace the module or cable. Manually set speed and duplex."; +static const char *const ice_port_number_label = "Port Number"; +static const char *const ice_update_nvm_solution = "Update to the latest NVM image."; + +static const struct ice_health_status ice_health_status_lookup[] = { + {ICE_AQC_HEALTH_STATUS_ERR_UNKNOWN_MOD_STRICT, "An unsupported module was detected", + ice_common_port_solutions, {ice_port_number_label}}, + {ICE_AQC_HEALTH_STATUS_ERR_MOD_TYPE, "Module type is not supported.", + "Change or replace the module or cable.", {ice_port_number_label}}, + {ICE_AQC_HEALTH_STATUS_ERR_MOD_QUAL, "Module is not qualified.", + ice_common_port_solutions, {ice_port_number_label}}, + {ICE_AQC_HEALTH_STATUS_ERR_MOD_COMM, + "Device cannot communicate with the module.", + "Check your cable connection. Change or replace the module or cable. Manually set speed and duplex.", + {ice_port_number_label}}, + {ICE_AQC_HEALTH_STATUS_ERR_MOD_CONFLICT, "Unresolved module conflict.", + "Manually set speed/duplex or change the po
[Intel-wired-lan] [PATCH iwl-net v2] ice: fix incorrect PHY settings for 100 GB/s
ptp4l application reports too high offset when ran on E823 device with a 100GB/s link. Those values cannot go under 100ns, like in a working case when using 100 GB/s cable. This is due to incorrect frequency settings on the PHY clocks for 100 GB/s speed. Changes are introduced to align with the internal hardware documentation, and correctly initialize frequency in PHY clocks with the frequency values that are in our HW spec. To reproduce the issue run ptp4l as a Time Receiver on E823 device, and observe the offset, which will never approach values seen in the PTP working case. Reproduction output: ptp4l -i enp137s0f3 -m -2 -s -f /etc/ptp4l_8275.conf ptp4l[5278.775]: master offset 12470 s2 freq +41288 path delay -3002 ptp4l[5278.837]: master offset 10525 s2 freq +39202 path delay -3002 ptp4l[5278.900]: master offset -24840 s2 freq -20130 path delay -3002 ptp4l[5278.963]: master offset 10597 s2 freq +37908 path delay -3002 ptp4l[5279.025]: master offset 8883 s2 freq +36031 path delay -3002 ptp4l[5279.088]: master offset 7267 s2 freq +34151 path delay -3002 ptp4l[5279.150]: master offset 5771 s2 freq +32316 path delay -3002 ptp4l[5279.213]: master offset 4388 s2 freq +30526 path delay -3002 ptp4l[5279.275]: master offset -30434 s2 freq -28485 path delay -3002 ptp4l[5279.338]: master offset -28041 s2 freq -27412 path delay -3002 ptp4l[5279.400]: master offset 7870 s2 freq +31118 path delay -3002 Fixes: 3a7496234d17 ("ice: implement basic E822 PTP support") Reviewed-by: Milena Olech Signed-off-by: Przemyslaw Korba --- Changelog: v2: change commit message v1: https://lore.kernel.org/intel-wired-lan/20241126102311.344972-1-przemyslaw.ko...@intel.com/ --- drivers/net/ethernet/intel/ice/ice_ptp_consts.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/intel/ice/ice_ptp_consts.h b/drivers/net/ethernet/intel/ice/ice_ptp_consts.h index 6620642077bb..bdb1020147d1 100644 --- a/drivers/net/ethernet/intel/ice/ice_ptp_consts.h +++ b/drivers/net/ethernet/intel/ice/ice_ptp_consts.h @@ -761,9 +761,9 @@ const struct ice_vernier_info_e82x e822_vernier[NUM_ICE_PTP_LNK_SPD] = { /* rx_desk_rsgb_par */ 644531250, /* 644.53125 MHz Reed Solomon gearbox */ /* tx_desk_rsgb_pcs */ - 644531250, /* 644.53125 MHz Reed Solomon gearbox */ + 390625000, /* 390.625 MHz Reed Solomon gearbox */ /* rx_desk_rsgb_pcs */ - 644531250, /* 644.53125 MHz Reed Solomon gearbox */ + 390625000, /* 390.625 MHz Reed Solomon gearbox */ /* tx_fixed_delay */ 1620, /* pmd_adj_divisor */ base-commit: 6ef5f61a4aa7d4df94a855a44f996bff08b0be83 -- 2.31.1
[Intel-wired-lan] [PATCH iwl-next v11 0/8] ixgbe: Add support for Intel(R) E610 device
Add initial support for Intel(R) E610 Series of network devices. The E610 is based on X550 but adds firmware managed link, enhanced security capabilities and support for updated server manageability. This patch series adds low level support for the following features and enables link management. Piotr Kwapulinski (8): ixgbe: Add support for E610 FW Admin Command Interface ixgbe: Add support for E610 device capabilities detection ixgbe: Add link management support for E610 device ixgbe: Add support for NVM handling in E610 device ixgbe: Add support for EEPROM dump in E610 device ixgbe: Add ixgbe_x540 multiple header inclusion protection ixgbe: Clean up the E610 link management related code ixgbe: Enable link management in E610 device drivers/net/ethernet/intel/ixgbe/Makefile |4 +- drivers/net/ethernet/intel/ixgbe/ixgbe.h | 13 +- .../net/ethernet/intel/ixgbe/ixgbe_82599.c|3 +- .../net/ethernet/intel/ixgbe/ixgbe_common.c | 25 +- .../net/ethernet/intel/ixgbe/ixgbe_dcb_nl.c |3 +- drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c | 2653 + drivers/net/ethernet/intel/ixgbe/ixgbe_e610.h | 81 + .../net/ethernet/intel/ixgbe/ixgbe_ethtool.c |6 +- drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c |3 +- drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 436 ++- drivers/net/ethernet/intel/ixgbe/ixgbe_mbx.c |4 +- drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c |5 +- drivers/net/ethernet/intel/ixgbe/ixgbe_type.h | 72 +- .../ethernet/intel/ixgbe/ixgbe_type_e610.h| 1075 +++ drivers/net/ethernet/intel/ixgbe/ixgbe_x540.c | 12 +- drivers/net/ethernet/intel/ixgbe/ixgbe_x540.h |7 +- drivers/net/ethernet/intel/ixgbe/ixgbe_x550.c | 29 +- drivers/net/ethernet/intel/ixgbe/ixgbe_x550.h | 20 + 18 files changed, 4404 insertions(+), 47 deletions(-) create mode 100644 drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c create mode 100644 drivers/net/ethernet/intel/ixgbe/ixgbe_e610.h create mode 100644 drivers/net/ethernet/intel/ixgbe/ixgbe_type_e610.h create mode 100644 drivers/net/ethernet/intel/ixgbe/ixgbe_x550.h -- Add dedicated patch for EEPROM dump. v1 -> v2: - fix for no previous prototypes for ixgbe_set_fw_drv_ver_x550, ixgbe_set_ethertype_anti_spoofing_x550 and ixgbe_set_source_address_pruning_x550 - fix variable type mismatch: u16, u32, u64 - fix inaccurate doc for ixgbe_aci_desc - remove extra buffer allocation in ixgbe_aci_send_cmd_execute - replace custom loops with generic fls64 in ixgbe_get_media_type_e610 - add buffer caching and optimization in ixgbe_aci_send_cmd v2 -> v3: - revert ixgbe_set_eee_capable inlining - update copyright date v3 -> v4: - cleanup local variables in ixgbe_get_num_per_func - remove redundant casting in ixgbe_aci_disable_rxen v4 -> v5: - remove unnecessary structure members initialization - remove unnecessary casting - fix comments v5 -> v6: - create dedicated patch for ixgbe_x540 multiple header inclusion protection - extend debug messages - add descriptive constant for Receive Address Registers - remove unrelated changes - create dedicated patch for code cleanup - remove and cleanup of some conditions - spelling fixes v6 -> v7: - rebase to adopt recent Makefile "ixgbe-y" changes v7 -> v8: - implement more clear execution flow in ixgbe_aci_list_caps(), ixgbe_discover_func_caps(), ixgbe_get_link_status(), ixgbe_fc_autoneg_e610(), ixgbe_disable_rx_e610() and ixgbe_setup_phy_link_e610() - make use of FIELD_PREP macro in ixgbe_is_media_cage_present() v8 -> v9: - tune-up auto-negotiation advertised link speeds at driver load - update the method of pending events detection - update the way of discovering device and function capabilities - update the parameter set-up for the firmware-controlled PHYs - fix port down after driver reload v9 -> v10: - clean-up redundant automatic variables - optimize return statements v10 -> v11: - add support for EEPROM dump - use little endian type in admin commands - fix link status message based on FW link events 2.43.0
[Intel-wired-lan] [PATCH iwl-next v11 1/8] ixgbe: Add support for E610 FW Admin Command Interface
Add low level support for Admin Command Interface (ACI). ACI is the Firmware interface used by a driver to communicate with E610 adapter. Add the following ACI features: - data structures, macros, register definitions - commands handling - events handling Co-developed-by: Stefan Wegrzyn Signed-off-by: Stefan Wegrzyn Co-developed-by: Jedrzej Jagielski Signed-off-by: Jedrzej Jagielski Reviewed-by: Michal Swiatkowski Reviewed-by: Simon Horman Signed-off-by: Piotr Kwapulinski --- drivers/net/ethernet/intel/ixgbe/Makefile |4 +- .../net/ethernet/intel/ixgbe/ixgbe_common.c |6 +- drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c | 496 drivers/net/ethernet/intel/ixgbe/ixgbe_e610.h | 19 + drivers/net/ethernet/intel/ixgbe/ixgbe_type.h | 72 +- .../ethernet/intel/ixgbe/ixgbe_type_e610.h| 1066 + 6 files changed, 1656 insertions(+), 7 deletions(-) create mode 100644 drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c create mode 100644 drivers/net/ethernet/intel/ixgbe/ixgbe_e610.h create mode 100644 drivers/net/ethernet/intel/ixgbe/ixgbe_type_e610.h diff --git a/drivers/net/ethernet/intel/ixgbe/Makefile b/drivers/net/ethernet/intel/ixgbe/Makefile index 965e5ce..b456d10 100644 --- a/drivers/net/ethernet/intel/ixgbe/Makefile +++ b/drivers/net/ethernet/intel/ixgbe/Makefile @@ -1,5 +1,5 @@ # SPDX-License-Identifier: GPL-2.0 -# Copyright(c) 1999 - 2018 Intel Corporation. +# Copyright(c) 1999 - 2024 Intel Corporation. # # Makefile for the Intel(R) 10GbE PCI Express ethernet driver # @@ -9,7 +9,7 @@ obj-$(CONFIG_IXGBE) += ixgbe.o ixgbe-y := ixgbe_main.o ixgbe_common.o ixgbe_ethtool.o \ ixgbe_82599.o ixgbe_82598.o ixgbe_phy.o ixgbe_sriov.o \ ixgbe_mbx.o ixgbe_x540.o ixgbe_x550.o ixgbe_lib.o ixgbe_ptp.o \ - ixgbe_xsk.o + ixgbe_xsk.o ixgbe_e610.o ixgbe-$(CONFIG_IXGBE_DCB) += ixgbe_dcb.o ixgbe_dcb_82598.o \ ixgbe_dcb_82599.o ixgbe_dcb_nl.o diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c index 3be1bfb..bfab2c0 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c @@ -660,7 +660,11 @@ int ixgbe_get_bus_info_generic(struct ixgbe_hw *hw) hw->bus.type = ixgbe_bus_type_pci_express; /* Get the negotiated link width and speed from PCI config space */ - link_status = ixgbe_read_pci_cfg_word(hw, IXGBE_PCI_LINK_STATUS); + if (hw->mac.type == ixgbe_mac_e610) + link_status = ixgbe_read_pci_cfg_word(hw, IXGBE_PCI_LINK_STATUS_E610); + else + link_status = ixgbe_read_pci_cfg_word(hw, + IXGBE_PCI_LINK_STATUS); hw->bus.width = ixgbe_convert_bus_width(link_status); hw->bus.speed = ixgbe_convert_bus_speed(link_status); diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c new file mode 100644 index 000..e1bab11 --- /dev/null +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c @@ -0,0 +1,496 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2024 Intel Corporation. */ + +#include "ixgbe_common.h" +#include "ixgbe_e610.h" +#include "ixgbe_type.h" +#include "ixgbe_x540.h" +#include "ixgbe_phy.h" + +/** + * ixgbe_should_retry_aci_send_cmd_execute - decide if ACI command should + * be resent + * @opcode: ACI opcode + * + * Check if ACI command should be sent again depending on the provided opcode. + * It may happen when CSR is busy during link state changes. + * + * Return: true if the sending command routine should be repeated, + * otherwise false. + */ +static bool ixgbe_should_retry_aci_send_cmd_execute(u16 opcode) +{ + switch (opcode) { + case ixgbe_aci_opc_disable_rxen: + case ixgbe_aci_opc_get_phy_caps: + case ixgbe_aci_opc_get_link_status: + case ixgbe_aci_opc_get_link_topo: + return true; + } + + return false; +} + +/** + * ixgbe_aci_send_cmd_execute - execute sending FW Admin Command to FW Admin + * Command Interface + * @hw: pointer to the HW struct + * @desc: descriptor describing the command + * @buf: buffer to use for indirect commands (NULL for direct commands) + * @buf_size: size of buffer for indirect commands (0 for direct commands) + * + * Admin Command is sent using CSR by setting descriptor and buffer in specific + * registers. + * + * Return: the exit code of the operation. + * * - 0 - success. + * * - -EIO - CSR mechanism is not enabled. + * * - -EBUSY - CSR mechanism is busy. + * * - -EINVAL - buf_size is too big or + * invalid argument buf or buf_size. + * * - -ETIME - Admin Command X command timeout. + * * - -EIO - Admin Command X invalid state of HICR register or + * Admin Command failed because of bad opcode was returned or + * Admin Command failed with error Y. + */ +static int ixgbe_aci_send_cmd_execute(struct ixgbe
[Intel-wired-lan] [PATCH iwl-next v11 2/8] ixgbe: Add support for E610 device capabilities detection
Add low level support for E610 device capabilities detection. The capabilities are discovered via the Admin Command Interface. Discover the following capabilities: - function caps: vmdq, dcb, rss, rx/tx qs, msix, nvm, orom, reset - device caps: vsi, fdir, 1588 - phy caps Co-developed-by: Stefan Wegrzyn Signed-off-by: Stefan Wegrzyn Co-developed-by: Jedrzej Jagielski Signed-off-by: Jedrzej Jagielski Reviewed-by: Jan Sokolowski Reviewed-by: Simon Horman Signed-off-by: Piotr Kwapulinski --- drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c | 529 ++ drivers/net/ethernet/intel/ixgbe/ixgbe_e610.h | 12 + drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 7 + 3 files changed, 548 insertions(+) diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c index e1bab11..1e4e8d2 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c @@ -494,3 +494,532 @@ void ixgbe_release_res(struct ixgbe_hw *hw, enum ixgbe_aci_res_ids res) total_delay++; } } + +/** + * ixgbe_parse_e610_caps - Parse common device/function capabilities + * @hw: pointer to the HW struct + * @caps: pointer to common capabilities structure + * @elem: the capability element to parse + * @prefix: message prefix for tracing capabilities + * + * Given a capability element, extract relevant details into the common + * capability structure. + * + * Return: true if the capability matches one of the common capability ids, + * false otherwise. + */ +static bool ixgbe_parse_e610_caps(struct ixgbe_hw *hw, + struct ixgbe_hw_caps *caps, + struct ixgbe_aci_cmd_list_caps_elem *elem, + const char *prefix) +{ + u32 logical_id = le32_to_cpu(elem->logical_id); + u32 phys_id = le32_to_cpu(elem->phys_id); + u32 number = le32_to_cpu(elem->number); + u16 cap = le16_to_cpu(elem->cap); + + switch (cap) { + case IXGBE_ACI_CAPS_VALID_FUNCTIONS: + caps->valid_functions = number; + break; + case IXGBE_ACI_CAPS_SRIOV: + caps->sr_iov_1_1 = (number == 1); + break; + case IXGBE_ACI_CAPS_VMDQ: + caps->vmdq = (number == 1); + break; + case IXGBE_ACI_CAPS_DCB: + caps->dcb = (number == 1); + caps->active_tc_bitmap = logical_id; + caps->maxtc = phys_id; + break; + case IXGBE_ACI_CAPS_RSS: + caps->rss_table_size = number; + caps->rss_table_entry_width = logical_id; + break; + case IXGBE_ACI_CAPS_RXQS: + caps->num_rxq = number; + caps->rxq_first_id = phys_id; + break; + case IXGBE_ACI_CAPS_TXQS: + caps->num_txq = number; + caps->txq_first_id = phys_id; + break; + case IXGBE_ACI_CAPS_MSIX: + caps->num_msix_vectors = number; + caps->msix_vector_first_id = phys_id; + break; + case IXGBE_ACI_CAPS_NVM_VER: + break; + case IXGBE_ACI_CAPS_MAX_MTU: + caps->max_mtu = number; + break; + case IXGBE_ACI_CAPS_PCIE_RESET_AVOIDANCE: + caps->pcie_reset_avoidance = (number > 0); + break; + case IXGBE_ACI_CAPS_POST_UPDATE_RESET_RESTRICT: + caps->reset_restrict_support = (number == 1); + break; + case IXGBE_ACI_CAPS_EXT_TOPO_DEV_IMG0: + case IXGBE_ACI_CAPS_EXT_TOPO_DEV_IMG1: + case IXGBE_ACI_CAPS_EXT_TOPO_DEV_IMG2: + case IXGBE_ACI_CAPS_EXT_TOPO_DEV_IMG3: + { + u8 index = cap - IXGBE_ACI_CAPS_EXT_TOPO_DEV_IMG0; + + caps->ext_topo_dev_img_ver_high[index] = number; + caps->ext_topo_dev_img_ver_low[index] = logical_id; + caps->ext_topo_dev_img_part_num[index] = + FIELD_GET(IXGBE_EXT_TOPO_DEV_IMG_PART_NUM_M, phys_id); + caps->ext_topo_dev_img_load_en[index] = + (phys_id & IXGBE_EXT_TOPO_DEV_IMG_LOAD_EN) != 0; + caps->ext_topo_dev_img_prog_en[index] = + (phys_id & IXGBE_EXT_TOPO_DEV_IMG_PROG_EN) != 0; + break; + } + default: + /* Not one of the recognized common capabilities */ + return false; + } + + return true; +} + +/** + * ixgbe_parse_valid_functions_cap - Parse IXGBE_ACI_CAPS_VALID_FUNCTIONS caps + * @hw: pointer to the HW struct + * @dev_p: pointer to device capabilities structure + * @cap: capability element to parse + * + * Parse IXGBE_ACI_CAPS_VALID_FUNCTIONS for device capabilities. + */ +static void +ixgbe_parse_valid_functions_cap(struct ixgbe_hw *hw, + struct ixgbe_hw_dev_caps *dev_p, +
[Intel-wired-lan] [PATCH iwl-next v11 4/8] ixgbe: Add support for NVM handling in E610 device
Add low level support for accessing NVM in E610 device. NVM operations are handled via the Admin Command Interface. Add the following NVM specific operations: - acquire, release, read - validate checksum - read shadow ram Co-developed-by: Stefan Wegrzyn Signed-off-by: Stefan Wegrzyn Co-developed-by: Jedrzej Jagielski Signed-off-by: Jedrzej Jagielski Reviewed-by: Michal Swiatkowski Reviewed-by: Simon Horman Signed-off-by: Piotr Kwapulinski --- drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c | 291 ++ drivers/net/ethernet/intel/ixgbe/ixgbe_e610.h | 12 + 2 files changed, 303 insertions(+) diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c index 1c50005..0542b4b 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c @@ -2102,3 +2102,294 @@ int ixgbe_aci_get_netlist_node(struct ixgbe_hw *hw, return 0; } + +/** + * ixgbe_acquire_nvm - Generic request for acquiring the NVM ownership + * @hw: pointer to the HW structure + * @access: NVM access type (read or write) + * + * Request NVM ownership. + * + * Return: the exit code of the operation. + */ +int ixgbe_acquire_nvm(struct ixgbe_hw *hw, + enum ixgbe_aci_res_access_type access) +{ + u32 fla; + + /* Skip if we are in blank NVM programming mode */ + fla = IXGBE_READ_REG(hw, IXGBE_GLNVM_FLA); + if ((fla & IXGBE_GLNVM_FLA_LOCKED_M) == 0) + return 0; + + return ixgbe_acquire_res(hw, IXGBE_NVM_RES_ID, access, +IXGBE_NVM_TIMEOUT); +} + +/** + * ixgbe_release_nvm - Generic request for releasing the NVM ownership + * @hw: pointer to the HW structure + * + * Release NVM ownership. + */ +void ixgbe_release_nvm(struct ixgbe_hw *hw) +{ + u32 fla; + + /* Skip if we are in blank NVM programming mode */ + fla = IXGBE_READ_REG(hw, IXGBE_GLNVM_FLA); + if ((fla & IXGBE_GLNVM_FLA_LOCKED_M) == 0) + return; + + ixgbe_release_res(hw, IXGBE_NVM_RES_ID); +} + +/** + * ixgbe_aci_read_nvm - read NVM + * @hw: pointer to the HW struct + * @module_typeid: module pointer location in words from the NVM beginning + * @offset: byte offset from the module beginning + * @length: length of the section to be read (in bytes from the offset) + * @data: command buffer (size [bytes] = length) + * @last_command: tells if this is the last command in a series + * @read_shadow_ram: tell if this is a shadow RAM read + * + * Read the NVM using ACI command (0x0701). + * + * Return: the exit code of the operation. + */ +int ixgbe_aci_read_nvm(struct ixgbe_hw *hw, u16 module_typeid, u32 offset, + u16 length, void *data, bool last_command, + bool read_shadow_ram) +{ + struct ixgbe_aci_cmd_nvm *cmd; + struct ixgbe_aci_desc desc; + + if (offset > IXGBE_ACI_NVM_MAX_OFFSET) + return -EINVAL; + + cmd = &desc.params.nvm; + + ixgbe_fill_dflt_direct_cmd_desc(&desc, ixgbe_aci_opc_nvm_read); + + if (!read_shadow_ram && module_typeid == IXGBE_ACI_NVM_START_POINT) + cmd->cmd_flags |= IXGBE_ACI_NVM_FLASH_ONLY; + + /* If this is the last command in a series, set the proper flag. */ + if (last_command) + cmd->cmd_flags |= IXGBE_ACI_NVM_LAST_CMD; + cmd->module_typeid = cpu_to_le16(module_typeid); + cmd->offset_low = cpu_to_le16(offset & 0x); + cmd->offset_high = (offset >> 16) & 0xFF; + cmd->length = cpu_to_le16(length); + + return ixgbe_aci_send_cmd(hw, &desc, data, length); +} + +/** + * ixgbe_nvm_validate_checksum - validate checksum + * @hw: pointer to the HW struct + * + * Verify NVM PFA checksum validity using ACI command (0x0706). + * If the checksum verification failed, IXGBE_ERR_NVM_CHECKSUM is returned. + * The function acquires and then releases the NVM ownership. + * + * Return: the exit code of the operation. + */ +int ixgbe_nvm_validate_checksum(struct ixgbe_hw *hw) +{ + struct ixgbe_aci_cmd_nvm_checksum *cmd; + struct ixgbe_aci_desc desc; + int err; + + err = ixgbe_acquire_nvm(hw, IXGBE_RES_READ); + if (err) + return err; + + cmd = &desc.params.nvm_checksum; + + ixgbe_fill_dflt_direct_cmd_desc(&desc, ixgbe_aci_opc_nvm_checksum); + cmd->flags = IXGBE_ACI_NVM_CHECKSUM_VERIFY; + + err = ixgbe_aci_send_cmd(hw, &desc, NULL, 0); + + ixgbe_release_nvm(hw); + + if (!err && cmd->checksum != + cpu_to_le16(IXGBE_ACI_NVM_CHECKSUM_CORRECT)) { + struct ixgbe_adapter *adapter = container_of(hw, struct ixgbe_adapter, +hw); + + err = -EIO; + netdev_err(adapter->netdev, "Invalid Shadow Ram checksum"); + } + + return err; +} + +/** + * ixgbe_read_sr_word_aci - Reads Shadow RAM via
[Intel-wired-lan] [PATCH iwl-next v11 3/8] ixgbe: Add link management support for E610 device
Add low level link management support for E610 device. Link management operations are handled via the Admin Command Interface. Add the following link management operations: - get link capabilities - set up link - get media type - get link status, link status events - link power management Co-developed-by: Stefan Wegrzyn Signed-off-by: Stefan Wegrzyn Co-developed-by: Jedrzej Jagielski Signed-off-by: Jedrzej Jagielski Reviewed-by: Jan Glaza Signed-off-by: Piotr Kwapulinski --- drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c | 1079 + drivers/net/ethernet/intel/ixgbe/ixgbe_e610.h | 32 + .../ethernet/intel/ixgbe/ixgbe_type_e610.h|1 + 3 files changed, 1112 insertions(+) diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c index 1e4e8d2..1c50005 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c @@ -1023,3 +1023,1082 @@ void ixgbe_copy_phy_caps_to_cfg(struct ixgbe_aci_cmd_get_phy_caps_data *caps, cfg->module_compliance_enforcement = caps->module_compliance_enforcement; } + +/** + * ixgbe_aci_set_phy_cfg - set PHY configuration + * @hw: pointer to the HW struct + * @cfg: structure with PHY configuration data to be set + * + * Set the various PHY configuration parameters supported on the Port + * using ACI command (0x0601). + * One or more of the Set PHY config parameters may be ignored in an MFP + * mode as the PF may not have the privilege to set some of the PHY Config + * parameters. + * + * Return: the exit code of the operation. + */ +int ixgbe_aci_set_phy_cfg(struct ixgbe_hw *hw, + struct ixgbe_aci_cmd_set_phy_cfg_data *cfg) +{ + struct ixgbe_aci_desc desc; + int err; + + if (!cfg) + return -EINVAL; + + /* Ensure that only valid bits of cfg->caps can be turned on. */ + cfg->caps &= IXGBE_ACI_PHY_ENA_VALID_MASK; + + ixgbe_fill_dflt_direct_cmd_desc(&desc, ixgbe_aci_opc_set_phy_cfg); + desc.params.set_phy.lport_num = hw->bus.func; + desc.flags |= cpu_to_le16(IXGBE_ACI_FLAG_RD); + + err = ixgbe_aci_send_cmd(hw, &desc, cfg, sizeof(*cfg)); + if (!err) + hw->phy.curr_user_phy_cfg = *cfg; + + return err; +} + +/** + * ixgbe_aci_set_link_restart_an - set up link and restart AN + * @hw: pointer to the HW struct + * @ena_link: if true: enable link, if false: disable link + * + * Function sets up the link and restarts the Auto-Negotiation over the link. + * + * Return: the exit code of the operation. + */ +int ixgbe_aci_set_link_restart_an(struct ixgbe_hw *hw, bool ena_link) +{ + struct ixgbe_aci_cmd_restart_an *cmd; + struct ixgbe_aci_desc desc; + + cmd = &desc.params.restart_an; + + ixgbe_fill_dflt_direct_cmd_desc(&desc, ixgbe_aci_opc_restart_an); + + cmd->cmd_flags = IXGBE_ACI_RESTART_AN_LINK_RESTART; + cmd->lport_num = hw->bus.func; + if (ena_link) + cmd->cmd_flags |= IXGBE_ACI_RESTART_AN_LINK_ENABLE; + else + cmd->cmd_flags &= ~IXGBE_ACI_RESTART_AN_LINK_ENABLE; + + return ixgbe_aci_send_cmd(hw, &desc, NULL, 0); +} + +/** + * ixgbe_is_media_cage_present - check if media cage is present + * @hw: pointer to the HW struct + * + * Identify presence of media cage using the ACI command (0x06E0). + * + * Return: true if media cage is present, else false. If no cage, then + * media type is backplane or BASE-T. + */ +static bool ixgbe_is_media_cage_present(struct ixgbe_hw *hw) +{ + struct ixgbe_aci_cmd_get_link_topo *cmd; + struct ixgbe_aci_desc desc; + + cmd = &desc.params.get_link_topo; + + ixgbe_fill_dflt_direct_cmd_desc(&desc, ixgbe_aci_opc_get_link_topo); + + cmd->addr.topo_params.node_type_ctx = + FIELD_PREP(IXGBE_ACI_LINK_TOPO_NODE_CTX_M, + IXGBE_ACI_LINK_TOPO_NODE_CTX_PORT); + + /* Set node type. */ + cmd->addr.topo_params.node_type_ctx |= + FIELD_PREP(IXGBE_ACI_LINK_TOPO_NODE_TYPE_M, + IXGBE_ACI_LINK_TOPO_NODE_TYPE_CAGE); + + /* Node type cage can be used to determine if cage is present. If AQC +* returns error (ENOENT), then no cage present. If no cage present then +* connection type is backplane or BASE-T. +*/ + return ixgbe_aci_get_netlist_node(hw, cmd, NULL, NULL); +} + +/** + * ixgbe_get_media_type_from_phy_type - Gets media type based on phy type + * @hw: pointer to the HW struct + * + * Try to identify the media type based on the phy type. + * If more than one media type, the ixgbe_media_type_unknown is returned. + * First, phy_type_low is checked, then phy_type_high. + * If none are identified, the ixgbe_media_type_unknown is returned + * + * Return: type of a media based on phy type in form of enum. + */ +static enum ixgbe_media_type +ixgbe_get_media_type_from_phy_type(struct ixgbe_hw
[Intel-wired-lan] [PATCH iwl-next v11 5/8] ixgbe: Add support for EEPROM dump in E610 device
Add low level support for EEPROM dump for the specified network device. Co-developed-by: Stefan Wegrzyn Signed-off-by: Stefan Wegrzyn Signed-off-by: Piotr Kwapulinski --- drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c | 93 +++ drivers/net/ethernet/intel/ixgbe/ixgbe_e610.h | 5 + .../ethernet/intel/ixgbe/ixgbe_type_e610.h| 8 ++ 3 files changed, 106 insertions(+) diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c index 0542b4b..503a047 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c @@ -2070,6 +2070,38 @@ int ixgbe_enter_lplu_e610(struct ixgbe_hw *hw) return ixgbe_aci_set_phy_cfg(hw, &phy_cfg); } +/** + * ixgbe_init_eeprom_params_E610 - Initialize EEPROM params + * @hw: pointer to hardware structure + * + * Initialize the EEPROM parameters ixgbe_eeprom_info within the ixgbe_hw + * struct in order to set up EEPROM access. + * + * Return: the operation exit code + */ +int ixgbe_init_eeprom_params_e610(struct ixgbe_hw *hw) +{ + struct ixgbe_eeprom_info *eeprom = &hw->eeprom; + u32 gens_stat; + u8 sr_size; + + if (eeprom->type != ixgbe_eeprom_uninitialized) + return 0; + + eeprom->type = ixgbe_flash; + + gens_stat = IXGBE_READ_REG(hw, GLNVM_GENS); + sr_size = FIELD_GET(GLNVM_GENS_SR_SIZE_M, gens_stat); + + /* Switching to words (sr_size contains power of 2). */ + eeprom->word_size = BIT(sr_size) * IXGBE_SR_WORDS_IN_1KB; + + hw_dbg(hw, "Eeprom params: type = %d, size = %d\n", eeprom->type, + eeprom->word_size); + + return 0; +} + /** * ixgbe_aci_get_netlist_node - get a node handle * @hw: pointer to the hw struct @@ -2316,6 +2348,34 @@ int ixgbe_read_flat_nvm(struct ixgbe_hw *hw, u32 offset, u32 *length, return err; } +/** + * ixgbe_read_sr_buf_aci - Read Shadow RAM buffer via ACI + * @hw: pointer to the HW structure + * @offset: offset of the Shadow RAM words to read (0x00 - 0x001FFF) + * @words: (in) number of words to read; (out) number of words actually read + * @data: words read from the Shadow RAM + * + * Read 16 bit words (data buf) from the Shadow RAM. Acquire/release the NVM + * ownership. + * + * Return: the operation exit code + */ +int ixgbe_read_sr_buf_aci(struct ixgbe_hw *hw, u16 offset, u16 *words, + u16 *data) +{ + u32 bytes = *words * 2, i; + int err; + + err = ixgbe_read_flat_nvm(hw, offset * 2, &bytes, (u8 *)data, true); + + *words = bytes / 2; + + for (i = 0; i < *words; i++) + data[i] = le16_to_cpu(((__le16 *)data)[i]); + + return err; +} + /** * ixgbe_read_ee_aci_e610 - Read EEPROM word using the admin command. * @hw: pointer to hardware structure @@ -2349,6 +2409,39 @@ int ixgbe_read_ee_aci_e610(struct ixgbe_hw *hw, u16 offset, u16 *data) return err; } +/** + * ixgbe_read_ee_aci_buffer_e610 - Read EEPROM words via ACI + * @hw: pointer to hardware structure + * @offset: offset of words in the EEPROM to read + * @words: number of words to read + * @data: words to read from the EEPROM + * + * Read 16 bit words from the EEPROM via the ACI. Initialize the EEPROM params + * prior to the read. Acquire/release the NVM ownership. + * + * Return: the operation exit code + */ +int ixgbe_read_ee_aci_buffer_e610(struct ixgbe_hw *hw, u16 offset, + u16 words, u16 *data) +{ + int err; + + if (hw->eeprom.type == ixgbe_eeprom_uninitialized) { + err = hw->eeprom.ops.init_params(hw); + if (err) + return err; + } + + err = ixgbe_acquire_nvm(hw, IXGBE_RES_READ); + if (err) + return err; + + err = ixgbe_read_sr_buf_aci(hw, offset, &words, data); + ixgbe_release_nvm(hw); + + return err; +} + /** * ixgbe_validate_eeprom_checksum_e610 - Validate EEPROM checksum * @hw: pointer to hardware structure diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_e610.h b/drivers/net/ethernet/intel/ixgbe/ixgbe_e610.h index 412ddd1..9cfcfee 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_e610.h +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_e610.h @@ -56,6 +56,7 @@ int ixgbe_identify_module_e610(struct ixgbe_hw *hw); int ixgbe_setup_phy_link_e610(struct ixgbe_hw *hw); int ixgbe_set_phy_power_e610(struct ixgbe_hw *hw, bool on); int ixgbe_enter_lplu_e610(struct ixgbe_hw *hw); +int ixgbe_init_eeprom_params_e610(struct ixgbe_hw *hw); int ixgbe_aci_get_netlist_node(struct ixgbe_hw *hw, struct ixgbe_aci_cmd_get_link_topo *cmd, u8 *node_part_number, u16 *node_handle); @@ -69,7 +70,11 @@ int ixgbe_nvm_validate_checksum(struct ixgbe_hw *hw); int ixgbe_read_sr_word_aci(struct ixgbe_hw *hw, u16 offset, u16 *data); int ixgbe_read_flat_nvm(struct ixgbe_hw *hw, u32 off
[Intel-wired-lan] [PATCH iwl-next v11 6/8] ixgbe: Add ixgbe_x540 multiple header inclusion protection
Required to adopt x540 specific functions by E610 device. Signed-off-by: Piotr Kwapulinski Reviewed-by: Simon Horman --- drivers/net/ethernet/intel/ixgbe/ixgbe_x540.h | 7 ++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_x540.h b/drivers/net/ethernet/intel/ixgbe/ixgbe_x540.h index b69a680..6ed360c 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_x540.h +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_x540.h @@ -1,5 +1,8 @@ /* SPDX-License-Identifier: GPL-2.0 */ -/* Copyright(c) 1999 - 2018 Intel Corporation. */ +/* Copyright(c) 1999 - 2024 Intel Corporation. */ + +#ifndef _IXGBE_X540_H_ +#define _IXGBE_X540_H_ #include "ixgbe_type.h" @@ -17,3 +20,5 @@ int ixgbe_acquire_swfw_sync_X540(struct ixgbe_hw *hw, u32 mask); void ixgbe_release_swfw_sync_X540(struct ixgbe_hw *hw, u32 mask); void ixgbe_init_swfw_sync_X540(struct ixgbe_hw *hw); int ixgbe_init_eeprom_params_X540(struct ixgbe_hw *hw); + +#endif /* _IXGBE_X540_H_ */ -- 2.43.0
[Intel-wired-lan] [PATCH iwl-next v11 7/8] ixgbe: Clean up the E610 link management related code
Required for enabling the link management in E610 device. Reviewed-by: Simon Horman Signed-off-by: Piotr Kwapulinski --- drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 17 +++-- drivers/net/ethernet/intel/ixgbe/ixgbe_x550.c | 12 ++-- 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index 0992775..1542859 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c @@ -237,6 +237,9 @@ static int ixgbe_get_parent_bus_info(struct ixgbe_adapter *adapter) * bandwidth details should be gathered from the parent bus instead of from the * device. Used to ensure that various locations all have the correct device ID * checks. + * + * Return: true if information should be collected from the parent bus, false + * otherwise */ static inline bool ixgbe_pcie_from_parent(struct ixgbe_hw *hw) { @@ -5528,7 +5531,9 @@ static void ixgbe_sfp_link_config(struct ixgbe_adapter *adapter) * ixgbe_non_sfp_link_config - set up non-SFP+ link * @hw: pointer to private hardware struct * - * Returns 0 on success, negative on failure + * Configure non-SFP link. + * + * Return: 0 on success, negative on failure **/ static int ixgbe_non_sfp_link_config(struct ixgbe_hw *hw) { @@ -7217,11 +7222,11 @@ void ixgbe_update_stats(struct ixgbe_adapter *adapter) for (i = 0; i < 16; i++) { hwstats->qptc[i] += IXGBE_READ_REG(hw, IXGBE_QPTC(i)); hwstats->qprc[i] += IXGBE_READ_REG(hw, IXGBE_QPRC(i)); - if ((hw->mac.type == ixgbe_mac_82599EB) || - (hw->mac.type == ixgbe_mac_X540) || - (hw->mac.type == ixgbe_mac_X550) || - (hw->mac.type == ixgbe_mac_X550EM_x) || - (hw->mac.type == ixgbe_mac_x550em_a)) { + if (hw->mac.type == ixgbe_mac_82599EB || + hw->mac.type == ixgbe_mac_X540 || + hw->mac.type == ixgbe_mac_X550 || + hw->mac.type == ixgbe_mac_X550EM_x || + hw->mac.type == ixgbe_mac_x550em_a) { hwstats->qbtc[i] += IXGBE_READ_REG(hw, IXGBE_QBTC_L(i)); IXGBE_READ_REG(hw, IXGBE_QBTC_H(i)); /* to clear */ hwstats->qbrc[i] += IXGBE_READ_REG(hw, IXGBE_QBRC_L(i)); diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_x550.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_x550.c index d9a8cf0..1de0544 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_x550.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_x550.c @@ -3505,13 +3505,13 @@ static int ixgbe_reset_hw_X550em(struct ixgbe_hw *hw) return status; } -/** ixgbe_set_ethertype_anti_spoofing_X550 - Enable/Disable Ethertype +/** ixgbe_set_ethertype_anti_spoofing_x550 - Enable/Disable Ethertype * anti-spoofing * @hw: pointer to hardware structure * @enable: enable or disable switch for Ethertype anti-spoofing * @vf: Virtual Function pool - VF Pool to set for Ethertype anti-spoofing **/ -static void ixgbe_set_ethertype_anti_spoofing_X550(struct ixgbe_hw *hw, +static void ixgbe_set_ethertype_anti_spoofing_x550(struct ixgbe_hw *hw, bool enable, int vf) { int vf_target_reg = vf >> 3; @@ -3527,12 +3527,12 @@ static void ixgbe_set_ethertype_anti_spoofing_X550(struct ixgbe_hw *hw, IXGBE_WRITE_REG(hw, IXGBE_PFVFSPOOF(vf_target_reg), pfvfspoof); } -/** ixgbe_set_source_address_pruning_X550 - Enable/Disbale src address pruning +/** ixgbe_set_source_address_pruning_x550 - Enable/Disable src address pruning * @hw: pointer to hardware structure * @enable: enable or disable source address pruning * @pool: Rx pool to set source address pruning for **/ -static void ixgbe_set_source_address_pruning_X550(struct ixgbe_hw *hw, +static void ixgbe_set_source_address_pruning_x550(struct ixgbe_hw *hw, bool enable, unsigned int pool) { @@ -3831,9 +3831,9 @@ static int ixgbe_write_phy_reg_x550a(struct ixgbe_hw *hw, u32 reg_addr, .set_mac_anti_spoofing = &ixgbe_set_mac_anti_spoofing, \ .set_vlan_anti_spoofing = &ixgbe_set_vlan_anti_spoofing, \ .set_source_address_pruning = \ - &ixgbe_set_source_address_pruning_X550, \ + &ixgbe_set_source_address_pruning_x550, \ .set_ethertype_anti_spoofing= \ - &ixgbe_set_ethertype_anti_spoofing_X550, \ + &ixgbe_set_ethertype_anti_spoofing_x550, \ .disable_rx_buff= &ixgbe_disable_rx_buff_generic, \ .enable_rx_buff = &ixgbe_enable_rx_buff_generic, \ .get_thermal_sensor_data= NULL,
[Intel-wired-lan] [PATCH iwl-next v11 8/8] ixgbe: Enable link management in E610 device
Add high level link management support for E610 device. Enable the following features: - driver load - bring up network interface - IP address assignment - pass traffic - show statistics (e.g. via ethtool) - disable network interface - driver unload Co-developed-by: Carolyn Wyborny Signed-off-by: Carolyn Wyborny Co-developed-by: Jedrzej Jagielski Signed-off-by: Jedrzej Jagielski Reviewed-by: Jan Glaza Reviewed-by: Simon Horman Signed-off-by: Piotr Kwapulinski --- drivers/net/ethernet/intel/ixgbe/ixgbe.h | 13 +- .../net/ethernet/intel/ixgbe/ixgbe_82599.c| 3 +- .../net/ethernet/intel/ixgbe/ixgbe_common.c | 19 +- .../net/ethernet/intel/ixgbe/ixgbe_dcb_nl.c | 3 +- drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c | 165 +++ drivers/net/ethernet/intel/ixgbe/ixgbe_e610.h | 1 + .../net/ethernet/intel/ixgbe/ixgbe_ethtool.c | 6 +- drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c | 3 +- drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 414 +- drivers/net/ethernet/intel/ixgbe/ixgbe_mbx.c | 4 +- drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c | 5 +- drivers/net/ethernet/intel/ixgbe/ixgbe_x540.c | 12 +- drivers/net/ethernet/intel/ixgbe/ixgbe_x550.c | 21 +- drivers/net/ethernet/intel/ixgbe/ixgbe_x550.h | 20 + 14 files changed, 659 insertions(+), 30 deletions(-) create mode 100644 drivers/net/ethernet/intel/ixgbe/ixgbe_x550.h diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe.h b/drivers/net/ethernet/intel/ixgbe/ixgbe.h index 559b443..e6a380d 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe.h +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe.h @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: GPL-2.0 */ -/* Copyright(c) 1999 - 2018 Intel Corporation. */ +/* Copyright(c) 1999 - 2024 Intel Corporation. */ #ifndef _IXGBE_H_ #define _IXGBE_H_ @@ -20,6 +20,7 @@ #include "ixgbe_type.h" #include "ixgbe_common.h" #include "ixgbe_dcb.h" +#include "ixgbe_e610.h" #if IS_ENABLED(CONFIG_FCOE) #define IXGBE_FCOE #include "ixgbe_fcoe.h" @@ -173,6 +174,7 @@ enum ixgbe_tx_flags { #define VMDQ_P(p) ((p) + adapter->ring_feature[RING_F_VMDQ].offset) #define IXGBE_82599_VF_DEVICE_ID0x10ED #define IXGBE_X540_VF_DEVICE_ID 0x1515 +#define IXGBE_E610_VF_DEVICE_ID0x57AD #define UPDATE_VF_COUNTER_32bit(reg, last_counter, counter)\ { \ @@ -654,6 +656,7 @@ struct ixgbe_adapter { #define IXGBE_FLAG2_RSS_FIELD_IPV6_UDP BIT(9) #define IXGBE_FLAG2_PTP_PPS_ENABLEDBIT(10) #define IXGBE_FLAG2_PHY_INTERRUPT BIT(11) +#define IXGBE_FLAG2_FW_ASYNC_EVENT BIT(12) #define IXGBE_FLAG2_VLAN_PROMISC BIT(13) #define IXGBE_FLAG2_EEE_CAPABLEBIT(14) #define IXGBE_FLAG2_EEE_ENABLEDBIT(15) @@ -661,6 +664,9 @@ struct ixgbe_adapter { #define IXGBE_FLAG2_IPSEC_ENABLED BIT(17) #define IXGBE_FLAG2_VF_IPSEC_ENABLED BIT(18) #define IXGBE_FLAG2_AUTO_DISABLE_VFBIT(19) +#define IXGBE_FLAG2_PHY_FW_LOAD_FAILED BIT(20) +#define IXGBE_FLAG2_NO_MEDIA BIT(21) +#define IXGBE_FLAG2_MOD_POWER_UNSUPPORTED BIT(22) /* Tx fast path data */ int num_tx_queues; @@ -793,6 +799,7 @@ struct ixgbe_adapter { u32 vferr_refcount; struct ixgbe_mac_addr *mac_table; struct kobject *info_kobj; + u16 lse_mask; #ifdef CONFIG_IXGBE_HWMON struct hwmon_buff *ixgbe_hwmon_buff; #endif /* CONFIG_IXGBE_HWMON */ @@ -849,6 +856,7 @@ static inline u8 ixgbe_max_rss_indices(struct ixgbe_adapter *adapter) case ixgbe_mac_X550: case ixgbe_mac_X550EM_x: case ixgbe_mac_x550em_a: + case ixgbe_mac_e610: return IXGBE_MAX_RSS_INDICES_X550; default: return 0; @@ -874,6 +882,7 @@ enum ixgbe_state_t { __IXGBE_PTP_RUNNING, __IXGBE_PTP_TX_IN_PROGRESS, __IXGBE_RESET_REQUESTED, + __IXGBE_PHY_INIT_COMPLETE, }; struct ixgbe_cb { @@ -896,6 +905,7 @@ enum ixgbe_boards { board_x550em_x_fw, board_x550em_a, board_x550em_a_fw, + board_e610, }; extern const struct ixgbe_info ixgbe_82598_info; @@ -906,6 +916,7 @@ extern const struct ixgbe_info ixgbe_X550EM_x_info; extern const struct ixgbe_info ixgbe_x550em_x_fw_info; extern const struct ixgbe_info ixgbe_x550em_a_info; extern const struct ixgbe_info ixgbe_x550em_a_fw_info; +extern const struct ixgbe_info ixgbe_e610_info; #ifdef CONFIG_IXGBE_DCB extern const struct dcbnl_rtnl_ops ixgbe_dcbnl_ops; #endif diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c index cdaf087..964988b 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0 -/* Copyright(c) 1999 - 2018 Intel Corporation. */
[Intel-wired-lan] [tnguy-net-queue:200GbE] BUILD SUCCESS af8edaeddbc52e53207d859c912b017fd9a77629
tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/tnguy/net-queue.git 200GbE branch HEAD: af8edaeddbc52e53207d859c912b017fd9a77629 net: hsr: must allocate more bytes for RedBox support elapsed time: 1593m configs tested: 234 configs skipped: 9 The following configs have been built successfully. More configs may be tested in the coming days. tested configs: alphaalldefconfiggcc-14.2.0 alpha allnoconfiggcc-14.2.0 alphaallyesconfigclang-20 arc allmodconfigclang-20 arc allnoconfiggcc-14.2.0 arc allyesconfigclang-20 arc axs103_smp_defconfiggcc-14.2.0 arc haps_hs_smp_defconfiggcc-14.2.0 arc nsimosci_hs_smp_defconfigclang-20 arcrandconfig-001gcc-13.2.0 arc randconfig-001-20241204clang-14 arc randconfig-001-20241204gcc-13.2.0 arcrandconfig-002gcc-13.2.0 arc randconfig-002-20241204clang-14 arc randconfig-002-20241204gcc-13.2.0 arcvdk_hs38_smp_defconfiggcc-14.2.0 arm allmodconfigclang-20 arm allnoconfiggcc-14.2.0 arm allyesconfigclang-20 arm aspeed_g4_defconfigclang-20 arm aspeed_g5_defconfiggcc-14.2.0 arm assabet_defconfigclang-20 arm at91_dt_defconfigclang-20 arm davinci_all_defconfigclang-20 arm davinci_all_defconfiggcc-14.2.0 armdove_defconfiggcc-14.2.0 arm ep93xx_defconfiggcc-14.2.0 arm h3600_defconfigclang-20 arm imx_v4_v5_defconfigclang-16 arm imx_v6_v7_defconfigclang-20 arm ixp4xx_defconfiggcc-14.2.0 armkeystone_defconfiggcc-14.2.0 arm lpc18xx_defconfigclang-20 arm moxart_defconfiggcc-14.2.0 armmvebu_v5_defconfiggcc-14.2.0 arm pxa3xx_defconfigclang-15 arm pxa3xx_defconfiggcc-14.2.0 arm pxa910_defconfigclang-20 armqcom_defconfigclang-15 armqcom_defconfigclang-20 armrandconfig-001gcc-14.2.0 arm randconfig-001-20241204clang-14 arm randconfig-001-20241204clang-20 armrandconfig-002gcc-14.2.0 arm randconfig-002-20241204clang-14 arm randconfig-002-20241204clang-20 armrandconfig-003clang-20 arm randconfig-003-20241204clang-14 armrandconfig-004gcc-14.2.0 arm randconfig-004-20241204clang-14 arm randconfig-004-20241204gcc-14.2.0 arm rpc_defconfiggcc-14.2.0 arm s5pv210_defconfiggcc-14.2.0 armshmobile_defconfigclang-18 armshmobile_defconfiggcc-14.2.0 arm socfpga_defconfiggcc-14.2.0 arm sp7021_defconfigclang-20 armspear3xx_defconfigclang-20 arm spitz_defconfiggcc-14.2.0 arm stm32_defconfigclang-20 armvexpress_defconfiggcc-14.2.0 arm wpcm450_defconfigclang-20 arm64allmodconfigclang-20 arm64 allnoconfiggcc-14.2.0 arm64 randconfig-001gcc-14.2.0 arm64 randconfig-001-20241204clang-14 arm64 randconfig-001-20241204gcc-14.2.0 arm64 randconfig-002gcc-14.2.0 arm64 randconfig-002-20241204clang-14 arm64 randconfig-002-20241204gcc-14.2.0 arm64 randconfig-003clang-15 arm64 randconfig-003-20241204clang-14 arm64 randconfig-003-20241204gcc-14.2.0 arm64 randconfig-004clang-20 arm64 randconfig-004-20241204clang-14 arm64 randconfig-004-20241204gcc-14.2.0 csky alldefconfigclang-20 csky alldefconfiggcc-14.2.0 csky
[Intel-wired-lan] [tnguy-next-queue:10GbE] BUILD SUCCESS e8e7be7d212dc2bc83b8151e51088666a6c42092
tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/tnguy/next-queue.git 10GbE branch HEAD: e8e7be7d212dc2bc83b8151e51088666a6c42092 mctp i2c: drop check because i2c_unregister_device() is NULL safe elapsed time: 1594m configs tested: 205 configs skipped: 7 The following configs have been built successfully. More configs may be tested in the coming days. tested configs: alphaalldefconfiggcc-14.2.0 alpha allnoconfiggcc-14.2.0 alphaallyesconfigclang-20 arc allmodconfigclang-20 arc allnoconfiggcc-14.2.0 arc allyesconfigclang-20 arc axs103_smp_defconfiggcc-14.2.0 arc nsimosci_hs_smp_defconfigclang-20 arcrandconfig-001clang-20 arc randconfig-001-20241204clang-14 arc randconfig-001-20241204gcc-13.2.0 arcrandconfig-002clang-20 arc randconfig-002-20241204clang-14 arc randconfig-002-20241204gcc-13.2.0 arm allmodconfigclang-20 arm allnoconfiggcc-14.2.0 arm allyesconfigclang-20 arm aspeed_g4_defconfigclang-20 arm at91_dt_defconfigclang-20 arm davinci_all_defconfigclang-20 arm ep93xx_defconfiggcc-14.2.0 arm imx_v4_v5_defconfigclang-16 arm imx_v6_v7_defconfigclang-20 arm ixp4xx_defconfiggcc-14.2.0 armkeystone_defconfiggcc-14.2.0 arm lpc18xx_defconfigclang-20 armmmp2_defconfiggcc-14.2.0 arm moxart_defconfiggcc-14.2.0 armmvebu_v5_defconfiggcc-14.2.0 arm pxa3xx_defconfigclang-15 arm pxa3xx_defconfiggcc-14.2.0 armqcom_defconfigclang-15 armqcom_defconfigclang-20 armrandconfig-001clang-20 arm randconfig-001-20241204clang-14 arm randconfig-001-20241204clang-20 armrandconfig-002clang-20 arm randconfig-002-20241204clang-14 arm randconfig-002-20241204clang-20 armrandconfig-003clang-20 arm randconfig-003-20241204clang-14 armrandconfig-004clang-20 arm randconfig-004-20241204clang-14 arm randconfig-004-20241204gcc-14.2.0 arm rpc_defconfiggcc-14.2.0 armshmobile_defconfigclang-18 armshmobile_defconfiggcc-14.2.0 arm sp7021_defconfigclang-20 arm spitz_defconfiggcc-14.2.0 arm wpcm450_defconfigclang-20 arm64allmodconfigclang-20 arm64 allnoconfiggcc-14.2.0 arm64 randconfig-001clang-20 arm64 randconfig-001-20241204clang-14 arm64 randconfig-001-20241204gcc-14.2.0 arm64 randconfig-002clang-20 arm64 randconfig-002-20241204clang-14 arm64 randconfig-002-20241204gcc-14.2.0 arm64 randconfig-003clang-20 arm64 randconfig-003-20241204clang-14 arm64 randconfig-003-20241204gcc-14.2.0 arm64 randconfig-004clang-20 arm64 randconfig-004-20241204clang-14 arm64 randconfig-004-20241204gcc-14.2.0 csky alldefconfigclang-20 csky allnoconfiggcc-14.2.0 hexagon allmodconfigclang-20 hexagon allnoconfiggcc-14.2.0 hexagon allyesconfigclang-20 i386 buildonly-randconfig-001gcc-12 i386buildonly-randconfig-001-20241204clang-19 i386buildonly-randconfig-001-20241204gcc-12 i386 buildonly-randconfig-002gcc-12 i386buildonly-randconfig-002-20241204clang-19 i386buildonly-randconfig-002-20241204gcc-12 i386 buildonly-randconfig-003gcc-12 i386buildonly-randconfig-003-20241204clang-19 i386buildonly-randconfig-003-20241204gcc-12 i386 buildonly-randconfig-004
[Intel-wired-lan] [tnguy-net-queue:100GbE] BUILD SUCCESS 0566f83d206c7a864abcd741fe39d6e0ae5eef29
tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/tnguy/net-queue.git 100GbE branch HEAD: 0566f83d206c7a864abcd741fe39d6e0ae5eef29 igb: Fix potential invalid memory access in igb_init_module() elapsed time: 729m configs tested: 144 configs skipped: 4 The following configs have been built successfully. More configs may be tested in the coming days. tested configs: alpha allnoconfiggcc-14.2.0 alphaallyesconfigclang-20 arc allmodconfigclang-20 arc allnoconfiggcc-14.2.0 arc allyesconfigclang-20 arc axs103_smp_defconfiggcc-14.2.0 arc nsimosci_hs_smp_defconfigclang-20 arcrandconfig-001clang-20 arc randconfig-001-20241204clang-14 arcrandconfig-002clang-20 arc randconfig-002-20241204clang-14 arm allmodconfigclang-20 arm allnoconfiggcc-14.2.0 arm allyesconfigclang-20 arm aspeed_g4_defconfigclang-20 arm at91_dt_defconfigclang-20 arm imx_v6_v7_defconfigclang-20 armkeystone_defconfiggcc-14.2.0 arm lpc18xx_defconfigclang-20 armmvebu_v5_defconfiggcc-14.2.0 arm pxa3xx_defconfigclang-15 arm pxa3xx_defconfiggcc-14.2.0 armqcom_defconfigclang-15 armrandconfig-001clang-20 arm randconfig-001-20241204clang-14 armrandconfig-002clang-20 arm randconfig-002-20241204clang-14 armrandconfig-003clang-20 arm randconfig-003-20241204clang-14 armrandconfig-004clang-20 arm randconfig-004-20241204clang-14 arm rpc_defconfiggcc-14.2.0 armshmobile_defconfigclang-18 armshmobile_defconfiggcc-14.2.0 arm sp7021_defconfigclang-20 arm wpcm450_defconfigclang-20 arm64allmodconfigclang-20 arm64 allnoconfiggcc-14.2.0 arm64 randconfig-001clang-20 arm64 randconfig-001-20241204clang-14 arm64 randconfig-002clang-20 arm64 randconfig-002-20241204clang-14 arm64 randconfig-003clang-20 arm64 randconfig-003-20241204clang-14 arm64 randconfig-004clang-20 arm64 randconfig-004-20241204clang-14 csky alldefconfigclang-20 csky allnoconfiggcc-14.2.0 hexagon allmodconfigclang-20 hexagon allnoconfiggcc-14.2.0 hexagon allyesconfigclang-20 i386 buildonly-randconfig-001gcc-12 i386 buildonly-randconfig-002gcc-12 i386 buildonly-randconfig-003gcc-12 i386 buildonly-randconfig-004gcc-12 i386 buildonly-randconfig-005gcc-12 i386 buildonly-randconfig-006gcc-12 loongarchallmodconfiggcc-14.2.0 loongarch allnoconfiggcc-14.2.0 loongarch loongson3_defconfigclang-18 m68k allmodconfiggcc-14.2.0 m68k allnoconfiggcc-14.2.0 m68k allyesconfiggcc-14.2.0 m68k atari_defconfigclang-18 m68k atari_defconfiggcc-14.2.0 m68k bvme6000_defconfiggcc-14.2.0 m68km5407c3_defconfiggcc-14.2.0 m68kq40_defconfigclang-15 microblaze alldefconfiggcc-14.2.0 microblaze allmodconfiggcc-14.2.0 microblazeallnoconfiggcc-14.2.0 microblaze allyesconfiggcc-14.2.0 mips allnoconfiggcc-14.2.0 mips ath25_defconfigclang-20 mips ath79_defconfiggcc-14.2.0 mips bmips_stb_defconfigclang-18 mips ci20_defconfigclang-18 mips ip22_defconfigclang-15 mips ip22_defconfig
[Intel-wired-lan] [tnguy-net-queue:dev-queue] BUILD SUCCESS 160315a280a7536ddb7ca480bdbc00e49df14a5b
tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/tnguy/net-queue.git dev-queue branch HEAD: 160315a280a7536ddb7ca480bdbc00e49df14a5b idpf: add read memory barrier when checking descriptor done bit elapsed time: 728m configs tested: 142 configs skipped: 4 The following configs have been built successfully. More configs may be tested in the coming days. tested configs: alpha allnoconfiggcc-14.2.0 alphaallyesconfigclang-20 arc allmodconfigclang-20 arc allnoconfiggcc-14.2.0 arc allyesconfigclang-20 arc axs103_smp_defconfiggcc-14.2.0 arc nsimosci_hs_smp_defconfigclang-20 arcrandconfig-001clang-20 arc randconfig-001-20241204clang-14 arcrandconfig-002clang-20 arc randconfig-002-20241204clang-14 arm allmodconfigclang-20 arm allnoconfiggcc-14.2.0 arm allyesconfigclang-20 arm aspeed_g4_defconfigclang-20 arm at91_dt_defconfigclang-20 arm imx_v6_v7_defconfigclang-20 armkeystone_defconfiggcc-14.2.0 arm lpc18xx_defconfigclang-20 armmvebu_v5_defconfiggcc-14.2.0 arm pxa3xx_defconfigclang-15 arm pxa3xx_defconfiggcc-14.2.0 armqcom_defconfigclang-15 armrandconfig-001clang-20 arm randconfig-001-20241204clang-14 armrandconfig-002clang-20 arm randconfig-002-20241204clang-14 armrandconfig-003clang-20 arm randconfig-003-20241204clang-14 armrandconfig-004clang-20 arm randconfig-004-20241204clang-14 arm rpc_defconfiggcc-14.2.0 armshmobile_defconfigclang-18 armshmobile_defconfiggcc-14.2.0 arm sp7021_defconfigclang-20 arm wpcm450_defconfigclang-20 arm64allmodconfigclang-20 arm64 allnoconfiggcc-14.2.0 arm64 randconfig-001clang-20 arm64 randconfig-001-20241204clang-14 arm64 randconfig-002clang-20 arm64 randconfig-002-20241204clang-14 arm64 randconfig-003clang-20 arm64 randconfig-003-20241204clang-14 arm64 randconfig-004clang-20 arm64 randconfig-004-20241204clang-14 csky alldefconfigclang-20 csky allnoconfiggcc-14.2.0 hexagon allmodconfigclang-20 hexagon allnoconfiggcc-14.2.0 hexagon allyesconfigclang-20 i386 buildonly-randconfig-001gcc-12 i386 buildonly-randconfig-002gcc-12 i386 buildonly-randconfig-003gcc-12 i386 buildonly-randconfig-004gcc-12 i386 buildonly-randconfig-005gcc-12 i386 buildonly-randconfig-006gcc-12 loongarchallmodconfiggcc-14.2.0 loongarch allnoconfiggcc-14.2.0 loongarch loongson3_defconfigclang-18 m68k allmodconfiggcc-14.2.0 m68k allnoconfiggcc-14.2.0 m68k allyesconfiggcc-14.2.0 m68k atari_defconfigclang-18 m68k atari_defconfiggcc-14.2.0 m68k bvme6000_defconfiggcc-14.2.0 m68km5407c3_defconfiggcc-14.2.0 m68kq40_defconfigclang-15 microblaze alldefconfiggcc-14.2.0 microblaze allmodconfiggcc-14.2.0 microblazeallnoconfiggcc-14.2.0 microblaze allyesconfiggcc-14.2.0 mips allnoconfiggcc-14.2.0 mips ath25_defconfigclang-20 mips ath79_defconfiggcc-14.2.0 mips bmips_stb_defconfigclang-18 mips ci20_defconfigclang-18 mips ip22_defconfigclang-15 mips ip22_defconfig
[Intel-wired-lan] [PATCH iwl-net v1] ice: move static_assert to declaration section
static_assert() needs to be placed in the declaration section, so move it there in ice_cfg_tx_topo() function. Current code causes following warnings on some gcc versions: error: ISO C90 forbids mixed declarations and code [-Werror=declaration-after-statement] Fixes: c188afdc3611 ("ice: fix memleak in ice_init_tx_topology()") Reviewed-by: Marcin Szycik Signed-off-by: Mateusz Polchlopek --- drivers/net/ethernet/intel/ice/ice_ddp.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/intel/ice/ice_ddp.c b/drivers/net/ethernet/intel/ice/ice_ddp.c index 69d5b1a28491..e885f84520ba 100644 --- a/drivers/net/ethernet/intel/ice/ice_ddp.c +++ b/drivers/net/ethernet/intel/ice/ice_ddp.c @@ -2388,6 +2388,8 @@ int ice_cfg_tx_topo(struct ice_hw *hw, const void *buf, u32 len) int status; u8 flags; + static_assert(ICE_PKG_BUF_SIZE == ICE_AQ_MAX_BUF_LEN); + if (!buf || !len) return -EINVAL; @@ -2482,7 +2484,6 @@ int ice_cfg_tx_topo(struct ice_hw *hw, const void *buf, u32 len) } /* Get the new topology buffer, reuse current topo copy mem */ - static_assert(ICE_PKG_BUF_SIZE == ICE_AQ_MAX_BUF_LEN); new_topo = topo; memcpy(new_topo, (u8 *)section + offset, size); -- 2.38.1
Re: [Intel-wired-lan] [PATCH iwl-net v1] ice: move static_assert to declaration section
Dear Mateusz, Thank you for the patch. Am 04.12.24 um 16:02 schrieb Mateusz Polchlopek: static_assert() needs to be placed in the declaration section, so move it there in ice_cfg_tx_topo() function. Current code causes following warnings on some gcc versions: Please list the versions you know of. error: ISO C90 forbids mixed declarations and code [-Werror=declaration-after-statement] The above could be in one line, as it’s pasted. Fixes: c188afdc3611 ("ice: fix memleak in ice_init_tx_topology()") Reviewed-by: Marcin Szycik Signed-off-by: Mateusz Polchlopek --- drivers/net/ethernet/intel/ice/ice_ddp.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/intel/ice/ice_ddp.c b/drivers/net/ethernet/intel/ice/ice_ddp.c index 69d5b1a28491..e885f84520ba 100644 --- a/drivers/net/ethernet/intel/ice/ice_ddp.c +++ b/drivers/net/ethernet/intel/ice/ice_ddp.c @@ -2388,6 +2388,8 @@ int ice_cfg_tx_topo(struct ice_hw *hw, const void *buf, u32 len) int status; u8 flags; + static_assert(ICE_PKG_BUF_SIZE == ICE_AQ_MAX_BUF_LEN); + if (!buf || !len) return -EINVAL; @@ -2482,7 +2484,6 @@ int ice_cfg_tx_topo(struct ice_hw *hw, const void *buf, u32 len) } /* Get the new topology buffer, reuse current topo copy mem */ - static_assert(ICE_PKG_BUF_SIZE == ICE_AQ_MAX_BUF_LEN); new_topo = topo; memcpy(new_topo, (u8 *)section + offset, size); The diff looks good. Kind regards, Paul
[Intel-wired-lan] [PATCH iwl-next 0/5] ice: implement low latency PHY timer updates
Programming the PHY registers in preparation for an increment value change or a timer adjustment on E810 requires issuing Admin Queue commands for each PHY register. It has been found that the firmware Admin Queue processing occasionally has delays of tens or rarely up to hundreds of milliseconds. This delay cascades to failures in the PTP applications which depend on these updates being low latency. Consider a standard PTP profile with a sync rate of 16 times per second. This means there is ~62 milliseconds between sync messages. A complete cycle of the PTP algorithm 1) Sync message (with Tx timestamp) from source 2) Follow-up message from source 3) Delay request (with Tx timestamp) from sink 4) Delay response (with Rx timestamp of request) from source 5) measure instantaneous clock offset 6) request time adjustment via CLOCK_ADJTIME systemcall The Tx timestamps have a default maximum timeout of 10 milliseconds. If we assume that the maximum possible time is used, this leaves us with ~42 milliseconds of processing time for a complete cycle. The CLOCK_ADJTIME system call is synchronous and will block until the driver completes its timer adjustment or frequency change. If the writes to prepare the PHY timers get hit by a latency spike of 50 milliseconds, then the PTP application will be delayed past the point where the next cycle should start. Packets from the next cycle may have already arrived and are waiting on the socket. In particular, LinuxPTP ptp4l may start complaining about missing an announce message from the source, triggering a fault. In addition, the clockcheck logic it uses may trigger. This clockcheck failure occurs because the timestamp captured by hardware is compared against a reading of CLOCK_MONOTONIC. It is assumed that the time when the Rx timestamp is captured and the read from CLOCK_MONOTONIC are relatively close together. This is not the case if there is a significant delay to processing the Rx packet. Newer firmware supports programming the PHY registers over a low latency interface which bypasses the Admin Queue. Instead, software writes to the REG_LL_PROXY_H and REG_LL_PROXY_L registers. Firmware reads these registers and then programs the PHY timers. Implement functions to use this interface when available to program the PHY timers instead of using the Admin Queue. This avoids the Admin Queue latency and ensures that adjustments happen within acceptable latency bounds. Jacob Keller (5): ice: use rd32_poll_timeout_atomic in ice_read_phy_tstamp_ll_e810 ice: rename TS_LL_READ* macros to REG_LL_PROXY_H_* ice: add lock to protect low latency interface ice: check low latency PHY timer update firmware capability ice: implement low latency PHY timer updates drivers/net/ethernet/intel/ice/ice_common.c | 3 + drivers/net/ethernet/intel/ice/ice_osdep.h | 3 + drivers/net/ethernet/intel/ice/ice_ptp.c| 48 -- drivers/net/ethernet/intel/ice/ice_ptp_hw.c | 155 +--- drivers/net/ethernet/intel/ice/ice_ptp_hw.h | 17 ++- drivers/net/ethernet/intel/ice/ice_type.h | 12 ++ 6 files changed, 204 insertions(+), 34 deletions(-) base-commit: 4376b34cf49c2f38e761beacd173d1dc15a255fd -- 2.42.0
[Intel-wired-lan] [PATCH iwl-next 3/5] ice: add lock to protect low latency interface
From: Jacob Keller Newer firmware for the E810 devices support a 'low latency' interface to interact with the PHY without using the Admin Queue. This is interacted with via the REG_LL_PROXY_L and REG_LL_PROXY_H registers. Currently, this interface is only used for Tx timestamps. There are two different mechanisms, including one which uses an interrupt for firmware to signal completion. However, these two methods are mutually exclusive, so no synchronization between them was necessary. This low latency interface is being extended in future firmware to support also programming the PHY timers. Use of the interface for PHY timers will need synchronization to ensure there is no overlap with a Tx timestamp. The interrupt-based response complicates the locking somewhat. We can't use a simple spinlock. This would require being acquired in ice_ptp_req_tx_single_tstamp, and released in ice_ptp_complete_tx_single_tstamp. The ice_ptp_req_tx_single_tstamp function is called from the threaded IRQ, and the ice_ptp_complete_tx_single_stamp is called from the low latency IRQ, so we would need to acquire the lock with IRQs disabled. To handle this, we'll use a wait queue along with wait_event_interruptible_locked_irq in the update flows which don't use the interrupt. The interrupt flow will acquire the wait queue lock, set the ATQBAL_FLAGS_INTR_IN_PROGRESS, and then initiate the firmware low latency request, and unlock the wait queue lock. Upon receipt of the low latency interrupt, the lock will be acquired, the ATQBAL_FLAGS_INTR_IN_PROGRESS bit will be cleared, and the firmware response will be captured, and wake_up_locked() will be called on the wait queue. The other flows will use wait_event_interruptible_locked_irq() to wait until the ATQBAL_FLAGS_INTR_IN_PROGRESS is clear. This function checks the condition under lock, but does not hold the lock while waiting. On return, the lock is held, and a return of zero indicates we hold the lock and the in-progress flag is not set. This will ensure that threads which need to use the low latency interface will sleep until they can acquire the lock without any pending low latency interrupt flow interfering. Signed-off-by: Jacob Keller Reviewed-by: Milena Olech Signed-off-by: Anton Nadezhdin --- drivers/net/ethernet/intel/ice/ice_ptp.c| 42 + drivers/net/ethernet/intel/ice/ice_ptp_hw.c | 18 + drivers/net/ethernet/intel/ice/ice_type.h | 10 + 3 files changed, 62 insertions(+), 8 deletions(-) diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c index 3c81d98883c0..75d4e77b1167 100644 --- a/drivers/net/ethernet/intel/ice/ice_ptp.c +++ b/drivers/net/ethernet/intel/ice/ice_ptp.c @@ -473,7 +473,9 @@ ice_ptp_is_tx_tracker_up(struct ice_ptp_tx *tx) */ void ice_ptp_req_tx_single_tstamp(struct ice_ptp_tx *tx, u8 idx) { + struct ice_e810_params *params; struct ice_ptp_port *ptp_port; + unsigned long flags; struct sk_buff *skb; struct ice_pf *pf; @@ -482,6 +484,7 @@ void ice_ptp_req_tx_single_tstamp(struct ice_ptp_tx *tx, u8 idx) ptp_port = container_of(tx, struct ice_ptp_port, tx); pf = ptp_port_to_pf(ptp_port); + params = &pf->hw.ptp.phy.e810; /* Drop packets which have waited for more than 2 seconds */ if (time_is_before_jiffies(tx->tstamps[idx].start + 2 * HZ)) { @@ -498,11 +501,17 @@ void ice_ptp_req_tx_single_tstamp(struct ice_ptp_tx *tx, u8 idx) ice_trace(tx_tstamp_fw_req, tx->tstamps[idx].skb, idx); + spin_lock_irqsave(¶ms->atqbal_wq.lock, flags); + + params->atqbal_flags |= ATQBAL_FLAGS_INTR_IN_PROGRESS; + /* Write TS index to read to the PF register so the FW can read it */ wr32(&pf->hw, REG_LL_PROXY_H, REG_LL_PROXY_H_TS_INTR_ENA | FIELD_PREP(REG_LL_PROXY_H_TS_IDX, idx) | REG_LL_PROXY_H_EXEC); tx->last_ll_ts_idx_read = idx; + + spin_unlock_irqrestore(¶ms->atqbal_wq.lock, flags); } /** @@ -513,35 +522,52 @@ void ice_ptp_complete_tx_single_tstamp(struct ice_ptp_tx *tx) { struct skb_shared_hwtstamps shhwtstamps = {}; u8 idx = tx->last_ll_ts_idx_read; + struct ice_e810_params *params; struct ice_ptp_port *ptp_port; u64 raw_tstamp, tstamp; bool drop_ts = false; struct sk_buff *skb; + unsigned long flags; + struct device *dev; struct ice_pf *pf; - u32 val; + u32 reg_ll_high; if (!tx->init || tx->last_ll_ts_idx_read < 0) return; ptp_port = container_of(tx, struct ice_ptp_port, tx); pf = ptp_port_to_pf(ptp_port); + dev = ice_pf_to_dev(pf); + params = &pf->hw.ptp.phy.e810; ice_trace(tx_tstamp_fw_done, tx->tstamps[idx].skb, idx); - val = rd32(&pf->hw, REG_LL_PROXY_H); + spin_lock_irqsave(¶ms->atqbal_wq.lock, flags); + + if (!(params->atqbal_flags & ATQBAL_F
[Intel-wired-lan] [PATCH iwl-next 5/5] ice: implement low latency PHY timer updates
From: Jacob Keller Programming the PHY registers in preparation for an increment value change or a timer adjustment on E810 requires issuing Admin Queue commands for each PHY register. It has been found that the firmware Admin Queue processing occasionally has delays of tens or rarely up to hundreds of milliseconds. This delay cascades to failures in the PTP applications which depend on these updates being low latency. Consider a standard PTP profile with a sync rate of 16 times per second. This means there is ~62 milliseconds between sync messages. A complete cycle of the PTP algorithm 1) Sync message (with Tx timestamp) from source 2) Follow-up message from source 3) Delay request (with Tx timestamp) from sink 4) Delay response (with Rx timestamp of request) from source 5) measure instantaneous clock offset 6) request time adjustment via CLOCK_ADJTIME systemcall The Tx timestamps have a default maximum timeout of 10 milliseconds. If we assume that the maximum possible time is used, this leaves us with ~42 milliseconds of processing time for a complete cycle. The CLOCK_ADJTIME system call is synchronous and will block until the driver completes its timer adjustment or frequency change. If the writes to prepare the PHY timers get hit by a latency spike of 50 milliseconds, then the PTP application will be delayed past the point where the next cycle should start. Packets from the next cycle may have already arrived and are waiting on the socket. In particular, LinuxPTP ptp4l may start complaining about missing an announce message from the source, triggering a fault. In addition, the clockcheck logic it uses may trigger. This clockcheck failure occurs because the timestamp captured by hardware is compared against a reading of CLOCK_MONOTONIC. It is assumed that the time when the Rx timestamp is captured and the read from CLOCK_MONOTONIC are relatively close together. This is not the case if there is a significant delay to processing the Rx packet. Newer firmware supports programming the PHY registers over a low latency interface which bypasses the Admin Queue. Instead, software writes to the REG_LL_PROXY_L and REG_LL_PROXY_H registers. Firmware reads these registers and then programs the PHY timers. Implement functions to use this interface when available to program the PHY timers instead of using the Admin Queue. This avoids the Admin Queue latency and ensures that adjustments happen within acceptable latency bounds. Co-developed-by: Karol Kolacinski Signed-off-by: Karol Kolacinski Signed-off-by: Jacob Keller Reviewed-by: Milena Olech Signed-off-by: Anton Nadezhdin --- drivers/net/ethernet/intel/ice/ice_ptp_hw.c | 105 drivers/net/ethernet/intel/ice/ice_ptp_hw.h | 4 + 2 files changed, 109 insertions(+) diff --git a/drivers/net/ethernet/intel/ice/ice_ptp_hw.c b/drivers/net/ethernet/intel/ice/ice_ptp_hw.c index d4c831b6eb6d..d1d7b96ee39a 100644 --- a/drivers/net/ethernet/intel/ice/ice_ptp_hw.c +++ b/drivers/net/ethernet/intel/ice/ice_ptp_hw.c @@ -5087,6 +5087,55 @@ static int ice_ptp_prep_phy_time_e810(struct ice_hw *hw, u32 time) return 0; } +/** + * ice_ptp_prep_phy_adj_ll_e810 - Prep PHY ports for a time adjustment + * @hw: pointer to HW struct + * @adj: adjustment value to program + * + * Use the low latency firmware interface to program PHY time adjustment to + * all PHY ports. + * + * Return: 0 on success, -EBUSY on timeout + */ +static int ice_ptp_prep_phy_adj_ll_e810(struct ice_hw *hw, s32 adj) +{ + const u8 tmr_idx = hw->func_caps.ts_func_info.tmr_index_owned; + struct ice_e810_params *params = &hw->ptp.phy.e810; + unsigned long flags; + u32 val; + int err; + + spin_lock_irqsave(¶ms->atqbal_wq.lock, flags); + + /* Wait for any pending in-progress low latency interrupt */ + err = wait_event_interruptible_locked_irq(params->atqbal_wq, + !(params->atqbal_flags & + ATQBAL_FLAGS_INTR_IN_PROGRESS)); + if (err) { + spin_unlock_irqrestore(¶ms->atqbal_wq.lock, flags); + return err; + } + + wr32(hw, PF_SB_ATQBAH, adj); + val = FIELD_PREP(REG_LL_PROXY_H_PHY_TMR_CMD_M, REG_LL_PROXY_H_PHY_TMR_CMD_ADJ) | + FIELD_PREP(REG_LL_PROXY_H_PHY_TMR_IDX_M, tmr_idx) | REG_LL_PROXY_H_EXEC; + wr32(hw, PF_SB_ATQBAL, val); + + /* Read the register repeatedly until the FW indicates completion */ + err = rd32_poll_timeout_atomic(hw, PF_SB_ATQBAL, val, + !FIELD_GET(REG_LL_PROXY_H_EXEC, val), + 10, REG_LL_PROXY_H_TIMEOUT_US); + if (err) { + ice_debug(hw, ICE_DBG_PTP, "Failed to prepare PHY timer adjustment using low latency interface\n"); + spin_unlock_irqrestore(¶ms->atqbal_wq.lock, flags); + return err; + } + + spin_un
[Intel-wired-lan] [PATCH iwl-next 2/5] ice: rename TS_LL_READ* macros to REG_LL_PROXY_H_*
From: Jacob Keller The TS_LL_READ macros are used as part of the low latency Tx timestamp interface. A future firmware extension will add support for performing PHY timer updates over this interface. Using TS_LL_READ as the prefix for these macros will be confusing once the interface is used for other purposes. Rename the macros, using the prefix REG_LL_PROXY_H, to better clarify that this is for the low latency interface. Additionally add macroses for PF_SB_ATQBAH and PF_SB_ATQBAL registers to better clarify content of this registers as PF_SB_ATQBAH contain low part of Tx timestamp Co-developed-by: Karol Kolacinski Signed-off-by: Karol Kolacinski Signed-off-by: Jacob Keller Reviewed-by: Milena Olech Signed-off-by: Anton Nadezhdin --- drivers/net/ethernet/intel/ice/ice_ptp.c| 14 +++--- drivers/net/ethernet/intel/ice/ice_ptp_hw.c | 14 +++--- drivers/net/ethernet/intel/ice/ice_ptp_hw.h | 13 - 3 files changed, 22 insertions(+), 19 deletions(-) diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c index d8ed4240f225..3c81d98883c0 100644 --- a/drivers/net/ethernet/intel/ice/ice_ptp.c +++ b/drivers/net/ethernet/intel/ice/ice_ptp.c @@ -499,9 +499,9 @@ void ice_ptp_req_tx_single_tstamp(struct ice_ptp_tx *tx, u8 idx) ice_trace(tx_tstamp_fw_req, tx->tstamps[idx].skb, idx); /* Write TS index to read to the PF register so the FW can read it */ - wr32(&pf->hw, PF_SB_ATQBAL, -TS_LL_READ_TS_INTR | FIELD_PREP(TS_LL_READ_TS_IDX, idx) | -TS_LL_READ_TS); + wr32(&pf->hw, REG_LL_PROXY_H, +REG_LL_PROXY_H_TS_INTR_ENA | FIELD_PREP(REG_LL_PROXY_H_TS_IDX, idx) | +REG_LL_PROXY_H_EXEC); tx->last_ll_ts_idx_read = idx; } @@ -528,20 +528,20 @@ void ice_ptp_complete_tx_single_tstamp(struct ice_ptp_tx *tx) ice_trace(tx_tstamp_fw_done, tx->tstamps[idx].skb, idx); - val = rd32(&pf->hw, PF_SB_ATQBAL); + val = rd32(&pf->hw, REG_LL_PROXY_H); /* When the bit is cleared, the TS is ready in the register */ - if (val & TS_LL_READ_TS) { + if (val & REG_LL_PROXY_H_EXEC) { dev_err(ice_pf_to_dev(pf), "Failed to get the Tx tstamp - FW not ready"); return; } /* High 8 bit value of the TS is on the bits 16:23 */ - raw_tstamp = FIELD_GET(TS_LL_READ_TS_HIGH, val); + raw_tstamp = FIELD_GET(REG_LL_PROXY_H_TS_HIGH, val); raw_tstamp <<= 32; /* Read the low 32 bit value */ - raw_tstamp |= (u64)rd32(&pf->hw, PF_SB_ATQBAH); + raw_tstamp |= (u64)rd32(&pf->hw, REG_LL_PROXY_L); /* Devices using this interface always verify the timestamp differs * relative to the last cached timestamp value. diff --git a/drivers/net/ethernet/intel/ice/ice_ptp_hw.c b/drivers/net/ethernet/intel/ice/ice_ptp_hw.c index b9cf8ce9644a..06a0c78cd491 100644 --- a/drivers/net/ethernet/intel/ice/ice_ptp_hw.c +++ b/drivers/net/ethernet/intel/ice/ice_ptp_hw.c @@ -4871,23 +4871,23 @@ ice_read_phy_tstamp_ll_e810(struct ice_hw *hw, u8 idx, u8 *hi, u32 *lo) u8 err; /* Write TS index to read to the PF register so the FW can read it */ - val = FIELD_PREP(TS_LL_READ_TS_IDX, idx) | TS_LL_READ_TS; - wr32(hw, PF_SB_ATQBAL, val); + val = FIELD_PREP(REG_LL_PROXY_H_TS_IDX, idx) | REG_LL_PROXY_H_EXEC; + wr32(hw, REG_LL_PROXY_H, val); /* Read the register repeatedly until the FW provides us the TS */ - err = rd32_poll_timeout_atomic(hw, PF_SB_ATQBAL, val, - !FIELD_GET(TS_LL_READ_TS, val), - 10, TS_LL_READ_TIMEOUT); + err = rd32_poll_timeout_atomic(hw, REG_LL_PROXY_H, val, + !FIELD_GET(REG_LL_PROXY_H_EXEC, val), + 10, REG_LL_PROXY_H_TIMEOUT_US); if (err) { ice_debug(hw, ICE_DBG_PTP, "Failed to read PTP timestamp using low latency read\n"); return err; } /* High 8 bit value of the TS is on the bits 16:23 */ - *hi = FIELD_GET(TS_LL_READ_TS_HIGH, val); + *hi = FIELD_GET(REG_LL_PROXY_H_TS_HIGH, val); /* Read the low 32 bit value and set the TS valid bit */ - *lo = rd32(hw, PF_SB_ATQBAH) | TS_VALID; + *lo = rd32(hw, REG_LL_PROXY_L) | TS_VALID; return 0; } diff --git a/drivers/net/ethernet/intel/ice/ice_ptp_hw.h b/drivers/net/ethernet/intel/ice/ice_ptp_hw.h index 4c059e2f4d96..71097eb67d54 100644 --- a/drivers/net/ethernet/intel/ice/ice_ptp_hw.h +++ b/drivers/net/ethernet/intel/ice/ice_ptp_hw.h @@ -694,11 +694,14 @@ static inline bool ice_is_dual(struct ice_hw *hw) #define BYTES_PER_IDX_ADDR_L 4 /* Tx timestamp low latency read definitions */ -#define TS_LL_READ_TIMEOUT 2000 -#define TS_LL_READ_TS_HIGH GENMASK(23, 16) -#define TS_LL_R
[Intel-wired-lan] [PATCH iwl-next 4/5] ice: check low latency PHY timer update firmware capability
From: Jacob Keller Newer versions of firmware support programming the PHY timer via the low latency interface exposed over REG_LL_PROXY_L and REG_LL_PROXY_H. Add support for checking the device capabilities for this feature. Co-developed-by: Karol Kolacinski Signed-off-by: Karol Kolacinski Signed-off-by: Jacob Keller Reviewed-by: Milena Olech Signed-off-by: Anton Nadezhdin --- drivers/net/ethernet/intel/ice/ice_common.c | 3 +++ drivers/net/ethernet/intel/ice/ice_type.h | 2 ++ 2 files changed, 5 insertions(+) diff --git a/drivers/net/ethernet/intel/ice/ice_common.c b/drivers/net/ethernet/intel/ice/ice_common.c index faba09b9d880..d23f413740c4 100644 --- a/drivers/net/ethernet/intel/ice/ice_common.c +++ b/drivers/net/ethernet/intel/ice/ice_common.c @@ -2507,6 +2507,7 @@ ice_parse_1588_dev_caps(struct ice_hw *hw, struct ice_hw_dev_caps *dev_p, info->ts_ll_read = ((number & ICE_TS_LL_TX_TS_READ_M) != 0); info->ts_ll_int_read = ((number & ICE_TS_LL_TX_TS_INT_READ_M) != 0); + info->ll_phy_tmr_update = ((number & ICE_TS_LL_PHY_TMR_UPDATE_M) != 0); info->ena_ports = logical_id; info->tmr_own_map = phys_id; @@ -2529,6 +2530,8 @@ ice_parse_1588_dev_caps(struct ice_hw *hw, struct ice_hw_dev_caps *dev_p, info->ts_ll_read); ice_debug(hw, ICE_DBG_INIT, "dev caps: ts_ll_int_read = %u\n", info->ts_ll_int_read); + ice_debug(hw, ICE_DBG_INIT, "dev caps: ll_phy_tmr_update = %u\n", + info->ll_phy_tmr_update); ice_debug(hw, ICE_DBG_INIT, "dev caps: ieee_1588 ena_ports = %u\n", info->ena_ports); ice_debug(hw, ICE_DBG_INIT, "dev caps: tmr_own_map = %u\n", diff --git a/drivers/net/ethernet/intel/ice/ice_type.h b/drivers/net/ethernet/intel/ice/ice_type.h index 5f3af5f3d2cb..25d6dad1852b 100644 --- a/drivers/net/ethernet/intel/ice/ice_type.h +++ b/drivers/net/ethernet/intel/ice/ice_type.h @@ -369,6 +369,7 @@ struct ice_ts_func_info { #define ICE_TS_TMR1_ENA_M BIT(26) #define ICE_TS_LL_TX_TS_READ_M BIT(28) #define ICE_TS_LL_TX_TS_INT_READ_M BIT(29) +#define ICE_TS_LL_PHY_TMR_UPDATE_M BIT(30) struct ice_ts_dev_info { /* Device specific info */ @@ -383,6 +384,7 @@ struct ice_ts_dev_info { u8 tmr1_ena; u8 ts_ll_read; u8 ts_ll_int_read; + u8 ll_phy_tmr_update; }; #define ICE_NAC_TOPO_PRIMARY_M BIT(0) -- 2.42.0
[Intel-wired-lan] [PATCH iwl-next 1/5] ice: use rd32_poll_timeout_atomic in ice_read_phy_tstamp_ll_e810
From: Jacob Keller The ice_read_phy_tstamp_ll_e810 function repeatedly reads the PF_SB_ATQBAL register until the TS_LL_READ_TS bit is cleared. This is a perfect candidate for using rd32_poll_timeout. However, the default implementation uses a sleep-based wait. Add a new rd32_poll_timeout_atomic macro which is based on the non-sleeping read_poll_timeout_atomic implementation. Use this to replace the loop reading in the ice_read_phy_tstamp_ll_e810 function. This will also be used in the future when low latency PHY timer updates are supported. Co-developed-by: Karol Kolacinski Signed-off-by: Karol Kolacinski Signed-off-by: Jacob Keller Reviewed-by: Milena Olech Signed-off-by: Anton Nadezhdin --- drivers/net/ethernet/intel/ice/ice_osdep.h | 3 +++ drivers/net/ethernet/intel/ice/ice_ptp_hw.c | 30 + drivers/net/ethernet/intel/ice/ice_ptp_hw.h | 2 +- 3 files changed, 17 insertions(+), 18 deletions(-) diff --git a/drivers/net/ethernet/intel/ice/ice_osdep.h b/drivers/net/ethernet/intel/ice/ice_osdep.h index b9f383494b3f..9bb343de80a9 100644 --- a/drivers/net/ethernet/intel/ice/ice_osdep.h +++ b/drivers/net/ethernet/intel/ice/ice_osdep.h @@ -26,6 +26,9 @@ #define rd32_poll_timeout(a, addr, val, cond, delay_us, timeout_us) \ read_poll_timeout(rd32, val, cond, delay_us, timeout_us, false, a, addr) +#define rd32_poll_timeout_atomic(a, addr, val, cond, delay_us, timeout_us) \ + read_poll_timeout_atomic(rd32, val, cond, delay_us, timeout_us, false, \ +a, addr) #define ice_flush(a) rd32((a), GLGEN_STAT) #define ICE_M(m, s)((m ## U) << (s)) diff --git a/drivers/net/ethernet/intel/ice/ice_ptp_hw.c b/drivers/net/ethernet/intel/ice/ice_ptp_hw.c index e55aeab0975c..b9cf8ce9644a 100644 --- a/drivers/net/ethernet/intel/ice/ice_ptp_hw.c +++ b/drivers/net/ethernet/intel/ice/ice_ptp_hw.c @@ -4868,32 +4868,28 @@ static int ice_read_phy_tstamp_ll_e810(struct ice_hw *hw, u8 idx, u8 *hi, u32 *lo) { u32 val; - u8 i; + u8 err; /* Write TS index to read to the PF register so the FW can read it */ val = FIELD_PREP(TS_LL_READ_TS_IDX, idx) | TS_LL_READ_TS; wr32(hw, PF_SB_ATQBAL, val); /* Read the register repeatedly until the FW provides us the TS */ - for (i = TS_LL_READ_RETRIES; i > 0; i--) { - val = rd32(hw, PF_SB_ATQBAL); - - /* When the bit is cleared, the TS is ready in the register */ - if (!(FIELD_GET(TS_LL_READ_TS, val))) { - /* High 8 bit value of the TS is on the bits 16:23 */ - *hi = FIELD_GET(TS_LL_READ_TS_HIGH, val); + err = rd32_poll_timeout_atomic(hw, PF_SB_ATQBAL, val, + !FIELD_GET(TS_LL_READ_TS, val), + 10, TS_LL_READ_TIMEOUT); + if (err) { + ice_debug(hw, ICE_DBG_PTP, "Failed to read PTP timestamp using low latency read\n"); + return err; + } - /* Read the low 32 bit value and set the TS valid bit */ - *lo = rd32(hw, PF_SB_ATQBAH) | TS_VALID; - return 0; - } + /* High 8 bit value of the TS is on the bits 16:23 */ + *hi = FIELD_GET(TS_LL_READ_TS_HIGH, val); - udelay(10); - } + /* Read the low 32 bit value and set the TS valid bit */ + *lo = rd32(hw, PF_SB_ATQBAH) | TS_VALID; - /* FW failed to provide the TS in time */ - ice_debug(hw, ICE_DBG_PTP, "Failed to read PTP timestamp using low latency read\n"); - return -EINVAL; + return 0; } /** diff --git a/drivers/net/ethernet/intel/ice/ice_ptp_hw.h b/drivers/net/ethernet/intel/ice/ice_ptp_hw.h index 5c11d8a69fd3..4c059e2f4d96 100644 --- a/drivers/net/ethernet/intel/ice/ice_ptp_hw.h +++ b/drivers/net/ethernet/intel/ice/ice_ptp_hw.h @@ -694,7 +694,7 @@ static inline bool ice_is_dual(struct ice_hw *hw) #define BYTES_PER_IDX_ADDR_L 4 /* Tx timestamp low latency read definitions */ -#define TS_LL_READ_RETRIES 200 +#define TS_LL_READ_TIMEOUT 2000 #define TS_LL_READ_TS_HIGH GENMASK(23, 16) #define TS_LL_READ_TS_IDX GENMASK(29, 24) #define TS_LL_READ_TS_INTR BIT(30) -- 2.42.0
Re: [Intel-wired-lan] [PATCH iwl-next v11 5/8] ixgbe: Add support for EEPROM dump in E610 device
Hi Piotr, kernel test robot noticed the following build warnings: [auto build test WARNING on tnguy-next-queue/dev-queue] url: https://github.com/intel-lab-lkp/linux/commits/Piotr-Kwapulinski/ixgbe-Add-support-for-E610-FW-Admin-Command-Interface/20241204-223603 base: https://git.kernel.org/pub/scm/linux/kernel/git/tnguy/next-queue.git dev-queue patch link: https://lore.kernel.org/r/20241204143112.29411-6-piotr.kwapulinski%40intel.com patch subject: [Intel-wired-lan] [PATCH iwl-next v11 5/8] ixgbe: Add support for EEPROM dump in E610 device config: i386-buildonly-randconfig-003 (https://download.01.org/0day-ci/archive/20241205/202412050450.s26zxk1u-...@intel.com/config) compiler: clang version 19.1.3 (https://github.com/llvm/llvm-project ab51eccf88f5321e7c60591c5546b254b6afab99) reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241205/202412050450.s26zxk1u-...@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot | Closes: https://lore.kernel.org/oe-kbuild-all/202412050450.s26zxk1u-...@intel.com/ All warnings (new ones prefixed by >>): >> drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c:2083: warning: expecting >> prototype for ixgbe_init_eeprom_params_E610(). Prototype was for >> ixgbe_init_eeprom_params_e610() instead vim +2083 drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c 2072 2073 /** 2074 * ixgbe_init_eeprom_params_E610 - Initialize EEPROM params 2075 * @hw: pointer to hardware structure 2076 * 2077 * Initialize the EEPROM parameters ixgbe_eeprom_info within the ixgbe_hw 2078 * struct in order to set up EEPROM access. 2079 * 2080 * Return: the operation exit code 2081 */ 2082 int ixgbe_init_eeprom_params_e610(struct ixgbe_hw *hw) > 2083 { 2084 struct ixgbe_eeprom_info *eeprom = &hw->eeprom; 2085 u32 gens_stat; 2086 u8 sr_size; 2087 2088 if (eeprom->type != ixgbe_eeprom_uninitialized) 2089 return 0; 2090 2091 eeprom->type = ixgbe_flash; 2092 2093 gens_stat = IXGBE_READ_REG(hw, GLNVM_GENS); 2094 sr_size = FIELD_GET(GLNVM_GENS_SR_SIZE_M, gens_stat); 2095 2096 /* Switching to words (sr_size contains power of 2). */ 2097 eeprom->word_size = BIT(sr_size) * IXGBE_SR_WORDS_IN_1KB; 2098 2099 hw_dbg(hw, "Eeprom params: type = %d, size = %d\n", eeprom->type, 2100 eeprom->word_size); 2101 2102 return 0; 2103 } 2104 -- 0-DAY CI Kernel Test Service https://github.com/intel/lkp-tests/wiki
Re: [Intel-wired-lan] [PATCH iwl-next v11 5/8] ixgbe: Add support for EEPROM dump in E610 device
On 12/4/24 15:31, Piotr Kwapulinski wrote: Add low level support for EEPROM dump for the specified network device. Co-developed-by: Stefan Wegrzyn Signed-off-by: Stefan Wegrzyn Signed-off-by: Piotr Kwapulinski --- drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c | 93 +++ drivers/net/ethernet/intel/ixgbe/ixgbe_e610.h | 5 + .../ethernet/intel/ixgbe/ixgbe_type_e610.h| 8 ++ 3 files changed, 106 insertions(+) just nitpicks, so: Reviewed-by: Przemek Kitszel diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c index 0542b4b..503a047 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c @@ -2070,6 +2070,38 @@ int ixgbe_enter_lplu_e610(struct ixgbe_hw *hw) return ixgbe_aci_set_phy_cfg(hw, &phy_cfg); } +/** + * ixgbe_init_eeprom_params_E610 - Initialize EEPROM params as bot set (also for our internal version of the patch), this should be "e610" + * @hw: pointer to hardware structure + * + * Initialize the EEPROM parameters ixgbe_eeprom_info within the ixgbe_hw + * struct in order to set up EEPROM access. + * + * Return: the operation exit code missing dot (.) at the end + */ +int ixgbe_init_eeprom_params_e610(struct ixgbe_hw *hw) +{ + struct ixgbe_eeprom_info *eeprom = &hw->eeprom; + u32 gens_stat; + u8 sr_size; + + if (eeprom->type != ixgbe_eeprom_uninitialized) + return 0; + + eeprom->type = ixgbe_flash; + + gens_stat = IXGBE_READ_REG(hw, GLNVM_GENS); + sr_size = FIELD_GET(GLNVM_GENS_SR_SIZE_M, gens_stat); + + /* Switching to words (sr_size contains power of 2). */ + eeprom->word_size = BIT(sr_size) * IXGBE_SR_WORDS_IN_1KB; + + hw_dbg(hw, "Eeprom params: type = %d, size = %d\n", eeprom->type, + eeprom->word_size); + + return 0; +} + /** * ixgbe_aci_get_netlist_node - get a node handle * @hw: pointer to the hw struct @@ -2316,6 +2348,34 @@ int ixgbe_read_flat_nvm(struct ixgbe_hw *hw, u32 offset, u32 *length, return err; } +/** + * ixgbe_read_sr_buf_aci - Read Shadow RAM buffer via ACI + * @hw: pointer to the HW structure + * @offset: offset of the Shadow RAM words to read (0x00 - 0x001FFF) + * @words: (in) number of words to read; (out) number of words actually read + * @data: words read from the Shadow RAM + * + * Read 16 bit words (data buf) from the Shadow RAM. Acquire/release the NVM + * ownership. + * + * Return: the operation exit code ditto dot + */ +int ixgbe_read_sr_buf_aci(struct ixgbe_hw *hw, u16 offset, u16 *words, + u16 *data) +{ + u32 bytes = *words * 2, i; I would declare @i in the for loop below + int err; + + err = ixgbe_read_flat_nvm(hw, offset * 2, &bytes, (u8 *)data, true); shouldn't we exit early here? + + *words = bytes / 2; + + for (i = 0; i < *words; i++) + data[i] = le16_to_cpu(((__le16 *)data)[i]); + + return err; +} + /** * ixgbe_read_ee_aci_e610 - Read EEPROM word using the admin command. * @hw: pointer to hardware structure @@ -2349,6 +2409,39 @@ int ixgbe_read_ee_aci_e610(struct ixgbe_hw *hw, u16 offset, u16 *data) return err; } +/** + * ixgbe_read_ee_aci_buffer_e610 - Read EEPROM words via ACI + * @hw: pointer to hardware structure + * @offset: offset of words in the EEPROM to read + * @words: number of words to read + * @data: words to read from the EEPROM + * + * Read 16 bit words from the EEPROM via the ACI. Initialize the EEPROM params + * prior to the read. Acquire/release the NVM ownership. + * + * Return: the operation exit code ditto dot + */ +int ixgbe_read_ee_aci_buffer_e610(struct ixgbe_hw *hw, u16 offset, + u16 words, u16 *data) +{ + int err; + + if (hw->eeprom.type == ixgbe_eeprom_uninitialized) { + err = hw->eeprom.ops.init_params(hw); + if (err) + return err; + } + + err = ixgbe_acquire_nvm(hw, IXGBE_RES_READ); + if (err) + return err; + + err = ixgbe_read_sr_buf_aci(hw, offset, &words, data); + ixgbe_release_nvm(hw); + + return err; +} + /** * ixgbe_validate_eeprom_checksum_e610 - Validate EEPROM checksum * @hw: pointer to hardware structure diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_e610.h b/drivers/net/ethernet/intel/ixgbe/ixgbe_e610.h index 412ddd1..9cfcfee 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_e610.h +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_e610.h @@ -56,6 +56,7 @@ int ixgbe_identify_module_e610(struct ixgbe_hw *hw); int ixgbe_setup_phy_link_e610(struct ixgbe_hw *hw); int ixgbe_set_phy_power_e610(struct ixgbe_hw *hw, bool on); int ixgbe_enter_lplu_e610(struct ixgbe_hw *hw); +int ixgbe_init_eeprom_params_e610(struct ixgbe_hw *hw); int ixgbe_aci_get_netlist_node(struct ixgbe_hw *hw,
Re: [Intel-wired-lan] [PATCH net-next] e1000e: Fix real-time violations on link up
On 04.12.24 11:10, Przemek Kitszel wrote: On 12/3/24 21:28, Gerhard Engleder wrote: From: Gerhard Engleder From: Gerhard Engleder duplicated From: line Nervous fingers, sorry, will be fixed. Link down and up triggers update of MTA table. This update executes many PCIe writes and a final flush. Thus, PCIe will be blocked until all writes are flushed. As a result, DMA transfers of other targets suffer from delay in the range of 50us. This results in timing violations on real-time systems during link down and up of e1000e. A flush after a low enough number of PCIe writes eliminates the delay but also increases the time needed for MTA table update. The following measurements were done on i3-2310E with e1000e for 128 MTA table entries: Single flush after all writes: 106us Flush after every write: 429us Flush after every 2nd write: 266us Flush after every 4th write: 180us Flush after every 8th write: 141us Flush after every 16th write: 121us A flush after every 8th write delays the link up by 35us and the negative impact to DMA transfers of other targets is still tolerable. Execute a flush after every 8th write. This prevents overloading the interconnect with posted writes. As this also increases the time spent for MTA table update considerable this change is limited to PREEMPT_RT. hmm, why to limit this to PREEMPT_RT, the change sounds resonable also for the standard kernel, at last for me (perhaps with every 16th write instead) As Andrew argumented similar, I will remove the PREEMPT_RT dependency with the next version. This is not the hot path, so the additional delay of <<1ms for boot and interface up is negligible. with that said, I'm fine with this patch as is too Signed-off-by: Gerhard Engleder would be good to add link to your RFC https://lore.kernel.org/netdev/f8fe665a-5e6c-4f95-b47a-2f3281aa0...@lunn.ch/T/ and also CC Vitaly who participated there (done), same for IWL mailing list (also CCd), and use iwl-next tag for your future contributions to intel ethernet Will be done. Thank you for the review! Gerhard
[Intel-wired-lan] [tnguy-next-queue:main] BUILD SUCCESS bb18265c3aba92b91a1355609769f3e967b65dee
tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/tnguy/next-queue.git main branch HEAD: bb18265c3aba92b91a1355609769f3e967b65dee r8169: remove support for chip version 11 elapsed time: 1619m configs tested: 209 configs skipped: 8 The following configs have been built successfully. More configs may be tested in the coming days. tested configs: alpha allnoconfiggcc-14.2.0 alphaallyesconfigclang-20 arc alldefconfigclang-20 arc allmodconfigclang-20 arc allnoconfiggcc-14.2.0 arc allyesconfigclang-20 arc axs101_defconfigclang-18 arc axs101_defconfigclang-20 arc axs103_defconfigclang-20 arcnsimosci_defconfigclang-20 arcrandconfig-001clang-20 arcrandconfig-001gcc-13.2.0 arc randconfig-001-20241205clang-20 arcrandconfig-002clang-20 arcrandconfig-002gcc-13.2.0 arc randconfig-002-20241205clang-20 arc tb10x_defconfigclang-20 arcvdk_hs38_defconfiggcc-14.2.0 arm allmodconfigclang-20 arm allnoconfiggcc-14.2.0 arm allyesconfigclang-20 arm aspeed_g4_defconfiggcc-14.2.0 arm assabet_defconfiggcc-14.2.0 arm at91_dt_defconfigclang-20 armdove_defconfiggcc-14.2.0 arm exynos_defconfiggcc-14.2.0 armhisi_defconfiggcc-14.2.0 arm imx_v4_v5_defconfigclang-18 arm imxrt_defconfigclang-20 arm integrator_defconfigclang-20 armkeystone_defconfigclang-20 arm lpc18xx_defconfigclang-20 armmps2_defconfigclang-20 arm multi_v4t_defconfigclang-20 armmulti_v7_defconfiggcc-14.2.0 arm mv78xx0_defconfigclang-17 arm omap1_defconfigclang-20 arm orion5x_defconfigclang-20 arm pxa910_defconfigclang-20 arm pxa910_defconfiggcc-14.2.0 armrandconfig-001clang-20 armrandconfig-001gcc-14.2.0 arm randconfig-001-20241205clang-20 armrandconfig-002clang-20 armrandconfig-002gcc-14.2.0 arm randconfig-002-20241205clang-20 armrandconfig-003clang-20 arm randconfig-003-20241205clang-20 armrandconfig-004clang-20 armrandconfig-004gcc-14.2.0 arm randconfig-004-20241205clang-20 armrealview_defconfigclang-20 arm sama7_defconfigclang-20 arm sp7021_defconfigclang-20 armspear3xx_defconfigclang-20 arm spitz_defconfiggcc-14.2.0 arm versatile_defconfigclang-20 armvt8500_v6_v7_defconfigclang-20 arm wpcm450_defconfiggcc-14.2.0 arm64alldefconfiggcc-14.2.0 arm64allmodconfigclang-20 arm64 allnoconfiggcc-14.2.0 arm64 randconfig-001clang-20 arm64 randconfig-001gcc-14.2.0 arm64 randconfig-001-20241205clang-20 arm64 randconfig-002clang-20 arm64 randconfig-002gcc-14.2.0 arm64 randconfig-002-20241205clang-20 arm64 randconfig-003clang-15 arm64 randconfig-003clang-20 arm64 randconfig-003-20241205clang-20 arm64 randconfig-004clang-20 arm64 randconfig-004-20241205clang-20 csky allnoconfiggcc-14.2.0 hexagon alldefconfigclang-20 hexagon allmodconfigclang-20 hexagon allnoconfiggcc-14.2.0 hexagon allyesconfigclang-20 i386 buildonly-randconfig-001gcc-12 i386