* [PATCH iproute2] ss: add more tcp socket diagnostics
From: Eric Dumazet @ 2014-10-01 11:17 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: netdev
From: Eric Dumazet <edumazet@google.com>
Display 4 additional tcp socket info fields :
backoff : exponential backoff
lastsnd : time in milli second since last send
lastrcv : time in milli second since last receive
lastack : time in milli second since last acknowledgement
$ ss -ti dst :22
State Recv-Q Send-Q Local Address:Port
Peer Address:Port
ESTAB 0 0 172.16.5.1:58470
172.17.131.143:ssh
cubic wscale:7,7 rto:228 rtt:30/20 ato:40 mss:1256 cwnd:6 ssthresh:4
send 2.0Mbps lastsnd:3480 lastrcv:3464 lastack:3464 rcv_rtt:81.5
rcv_space:87812
Signed-off-by: Eric Dumazet <edumazet@google.com>
---
misc/ss.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/misc/ss.c b/misc/ss.c
index c847954..2420b51 100644
--- a/misc/ss.c
+++ b/misc/ss.c
@@ -1554,6 +1554,8 @@ static void tcp_show_info(const struct nlmsghdr *nlh, struct inet_diag_msg *r,
info->tcpi_rcv_wscale);
if (info->tcpi_rto && info->tcpi_rto != 3000000)
printf(" rto:%g", (double)info->tcpi_rto/1000);
+ if (info->tcpi_backoff)
+ printf(" backoff:%u", info->tcpi_backoff);
if (info->tcpi_rtt)
printf(" rtt:%g/%g", (double)info->tcpi_rtt/1000,
(double)info->tcpi_rttvar/1000);
@@ -1583,6 +1585,15 @@ static void tcp_show_info(const struct nlmsghdr *nlh, struct inet_diag_msg *r,
/ rtt));
}
+ if (info->tcpi_last_data_sent)
+ printf(" lastsnd:%u", info->tcpi_last_data_sent);
+
+ if (info->tcpi_last_data_recv)
+ printf(" lastrcv:%u", info->tcpi_last_data_recv);
+
+ if (info->tcpi_last_ack_recv)
+ printf(" lastack:%u", info->tcpi_last_ack_recv);
+
if (info->tcpi_pacing_rate &&
info->tcpi_pacing_rate != ~0ULL) {
printf(" pacing_rate %sbps",
^ permalink raw reply related
* Re: [PATCH v2 net-next] net: cleanup and document skb fclone layout
From: Eric Dumazet @ 2014-10-01 11:22 UTC (permalink / raw)
To: Vijay Subramanian; +Cc: David Miller, netdev
In-Reply-To: <CAGK4HS8QNDmDguFtaqEoU7BGjKm46vw+2Lrmhb363gzBvYgE_g@mail.gmail.com>
On Wed, 2014-10-01 at 00:38 -0700, Vijay Subramanian wrote:
> > case SKB_FCLONE_CLONE:
> > - fclone_ref = (atomic_t *) (skb + 1);
> > - other = skb - 1;
> > + fclones = container_of(skb, struct sk_buff_fclones, skb2);
> >
> > /* The clone portion is available for
> > * fast-cloning again.
> > */
> > skb->fclone = SKB_FCLONE_UNAVAILABLE;
> >
>
> It looks like SKB_FCLONE_UNAVAILABLE has overloaded use depending on
> whether we are referring to skb allocated from head_cache or from
> fclone_cache. In the former case, it means this skb cannot be cloned
> i.e.(clone is unavailable) but in latter case, it means clone is free
> to be used.
> This overleading is confusing as seen in the comment in snippet above.
>
> Should we add something like SKB_CLONE_FREE for the second case that
> indicates that clone is free for use.? I can send a patch if it makes
> sense..
FCLONE_UNAVAILABLE always had two meanings, one for a normal skb telling
there is no fclone companion, one for the companion telling he is free.
It would be indeed clear to have SKB_CLONE_FREE for the companion.
^ permalink raw reply
* Re: [PATCH 4/4] net: stmmac: add MSI support for Intel Quark X1000
From: Bryan O'Donoghue @ 2014-10-01 11:29 UTC (permalink / raw)
To: Kweh, Hock Leong, 'David Miller'
Cc: 'peppe.cavallaro@st.com',
'rayagond@vayavyalabs.com',
'vbridgers2013@gmail.com',
'srinivas.kandagatla@st.com', 'wens@csie.org',
'netdev@vger.kernel.org',
'linux-kernel@vger.kernel.org', Ong, Boon Leong
In-Reply-To: <F54AEECA5E2B9541821D670476DAE19C2B7F65A6@PGSMSX102.gar.corp.intel.com>
> Hi Guys,
>
> Just gently ping for the discussion to carry on before forgetting the context.
> Anyone have any better idea or comments or concern to this topic?
> Hope the above explanation clear out your doubt.
>
>
> Regards,
> Wilson
Hi Wilson.
Seeing you post now on the PCI emumeration suggestion from Dave Miller I see
I wasn't copied on this https://lkml.org/lkml/2014/8/27/190 thread so
can only respond now....
What's missing from your MSI enabling code is the PVM mask/unmask
required on the Quark X1000 bridge - for *all* downstream devices using MSI.
I realise it's not an upstreaming friendly piece of code - however -
without the PVM mask operation all MSIs on Quark should be considered
unreliable.
Maybe you guys have submitted patches to the PCI layer on this already ?
If so feel free to ignore.
If not then please re-evaluate all MSI enabling code.
From the original
http://downloadmirror.intel.com/23171/eng/Board_Support_Package_Sources_for_Intel_Quark_v1.0.0.7z
+#if defined(CONFIG_INTEL_QUARK_X1000_SOC)
+ #define mask_pvm(x) qrk_pci_pvm_mask(x)
+ #define unmask_pvm(x) qrk_pci_pvm_unmask(x)
+#else
+ #define mask_pvm(x)
+ #define unmask_pvm(x)
+#endif
+
static irqreturn_t stmmac_interrupt(int irq, void *dev_id)
{
struct net_device *dev = (struct net_device *)dev_id;
@@ -1601,10 +1686,12 @@ static irqreturn_t stmmac_interrupt(int irq,
void *dev_id)
return IRQ_NONE;
}
+ mask_pvm(priv->pdev);
+
/* To handle GMAC own interrupts */
if (priv->plat->has_gmac) {
- int status = priv->hw->mac->host_irq_status((void __iomem *)
- dev->base_addr);
+ int status = priv->hw->mac->host_irq_status(priv);
+
if (unlikely(status)) {
if (status & core_mmc_tx_irq)
priv->xstats.mmc_tx_irq_n++;
@@ -1634,6 +1721,8 @@ static irqreturn_t stmmac_interrupt(int irq, void
*dev_id)
/* To handle DMA interrupts */
stmmac_dma_interrupt(priv);
+ unmask_pvm(priv->pdev);
+
return IRQ_HANDLED;
}
^ permalink raw reply
* [PATCH V3 next] r8169: add support for Byte Queue Limits
From: Florian Westphal @ 2014-10-01 11:38 UTC (permalink / raw)
To: netdev; +Cc: Florian Westphal, Francois Romieu, Hayes Wang
tested on RTL8168d/8111d model using 'super_netperf 40' with TCP/UDP_STREAM.
Output of
while true; do
for n in inflight limit; do
echo -n $n\ ; cat $n;
done;
sleep 1;
done
during netperf run, 100mbit peer:
inflight 0
limit 3028
inflight 6056
limit 4542
[ trimmed output for brevity, no limit/inflight changes during
test steady-state ]
limit 4542
inflight 3028
limit 6122
inflight 0
limit 6122
[ changed cable to 1gbit peer, restart netperf ]
inflight 37850
limit 36336
inflight 33308
limit 31794
inflight 33308
limit 31794
inflight 27252
limit 25738
[ again, no changes during test ]
inflight 27252
limit 25738
inflight 0
limit 28766
[ change cable to 100mbit peer, restart netperf ]
limit 28766
inflight 27370
limit 28766
inflight 4542
limit 5990
inflight 6056
limit 4542
[ .. ]
inflight 6056
limit 4542
inflight 0
[end of test]
Cc: Francois Romieu <romieu@fr.zoreil.com>
Cc: Hayes Wang <hayeswang@realtek.com>
Signed-off-by: Florian Westphal <fw@strlen.de>
Acked-by: Eric Dumazet <edumazet@google.com>
Acked-by: Tom Herbert <therbert@google.com>
---
Change since v2: updated commit message.
drivers/net/ethernet/realtek/r8169.c | 18 ++++++++++++++----
1 file changed, 14 insertions(+), 4 deletions(-)
diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c
index 1d81238..51b6dc2 100644
--- a/drivers/net/ethernet/realtek/r8169.c
+++ b/drivers/net/ethernet/realtek/r8169.c
@@ -4712,6 +4712,8 @@ static void rtl_hw_reset(struct rtl8169_private *tp)
RTL_W8(ChipCmd, CmdReset);
rtl_udelay_loop_wait_low(tp, &rtl_chipcmd_cond, 100, 100);
+
+ netdev_reset_queue(tp->dev);
}
static void rtl_request_uncached_firmware(struct rtl8169_private *tp)
@@ -6592,6 +6594,8 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb,
txd->opts2 = cpu_to_le32(opts[1]);
+ netdev_sent_queue(dev, skb->len);
+
skb_tx_timestamp(skb);
wmb();
@@ -6691,6 +6695,7 @@ static void rtl8169_pcierr_interrupt(struct net_device *dev)
static void rtl_tx(struct net_device *dev, struct rtl8169_private *tp)
{
unsigned int dirty_tx, tx_left;
+ unsigned int bytes_compl = 0, pkts_compl = 0;
dirty_tx = tp->dirty_tx;
smp_rmb();
@@ -6709,10 +6714,8 @@ static void rtl_tx(struct net_device *dev, struct rtl8169_private *tp)
rtl8169_unmap_tx_skb(&tp->pci_dev->dev, tx_skb,
tp->TxDescArray + entry);
if (status & LastFrag) {
- u64_stats_update_begin(&tp->tx_stats.syncp);
- tp->tx_stats.packets++;
- tp->tx_stats.bytes += tx_skb->skb->len;
- u64_stats_update_end(&tp->tx_stats.syncp);
+ pkts_compl++;
+ bytes_compl += tx_skb->skb->len;
dev_kfree_skb_any(tx_skb->skb);
tx_skb->skb = NULL;
}
@@ -6721,6 +6724,13 @@ static void rtl_tx(struct net_device *dev, struct rtl8169_private *tp)
}
if (tp->dirty_tx != dirty_tx) {
+ netdev_completed_queue(tp->dev, pkts_compl, bytes_compl);
+
+ u64_stats_update_begin(&tp->tx_stats.syncp);
+ tp->tx_stats.packets += pkts_compl;
+ tp->tx_stats.bytes += bytes_compl;
+ u64_stats_update_end(&tp->tx_stats.syncp);
+
tp->dirty_tx = dirty_tx;
/* Sync with rtl8169_start_xmit:
* - publish dirty_tx ring index (write barrier)
--
1.8.1.5
^ permalink raw reply related
* RE: [PATCH 4/4] net: stmmac: add MSI support for Intel Quark X1000
From: Kweh, Hock Leong @ 2014-10-01 11:55 UTC (permalink / raw)
To: Bryan O'Donoghue, 'David Miller'
Cc: 'peppe.cavallaro@st.com',
'rayagond@vayavyalabs.com',
'vbridgers2013@gmail.com',
'srinivas.kandagatla@st.com', 'wens@csie.org',
'netdev@vger.kernel.org',
'linux-kernel@vger.kernel.org', Ong, Boon Leong
In-Reply-To: <542BE580.2000807@nexus-software.ie>
> -----Original Message-----
> From: Bryan O'Donoghue [mailto:pure.logic@nexus-software.ie]
> Sent: Wednesday, October 01, 2014 7:29 PM
> Hi Wilson.
>
> Seeing you post now on the PCI emumeration suggestion from Dave Miller I
> see
>
> I wasn't copied on this https://lkml.org/lkml/2014/8/27/190 thread so can
> only respond now....
>
> What's missing from your MSI enabling code is the PVM mask/unmask
> required on the Quark X1000 bridge - for *all* downstream devices using MSI.
>
> I realise it's not an upstreaming friendly piece of code - however - without
> the PVM mask operation all MSIs on Quark should be considered unreliable.
>
> Maybe you guys have submitted patches to the PCI layer on this already ?
> If so feel free to ignore.
>
> If not then please re-evaluate all MSI enabling code.
>
> From the original
>
> http://downloadmirror.intel.com/23171/eng/Board_Support_Package_Sour
> ces_for_Intel_Quark_v1.0.0.7z
>
> +#if defined(CONFIG_INTEL_QUARK_X1000_SOC)
> + #define mask_pvm(x) qrk_pci_pvm_mask(x)
> + #define unmask_pvm(x) qrk_pci_pvm_unmask(x) #else
> + #define mask_pvm(x)
> + #define unmask_pvm(x)
> +#endif
> +
> static irqreturn_t stmmac_interrupt(int irq, void *dev_id)
> {
> struct net_device *dev = (struct net_device *)dev_id; @@ -1601,10
> +1686,12 @@ static irqreturn_t stmmac_interrupt(int irq, void *dev_id)
> return IRQ_NONE;
> }
>
> + mask_pvm(priv->pdev);
> +
> /* To handle GMAC own interrupts */
> if (priv->plat->has_gmac) {
> - int status = priv->hw->mac->host_irq_status((void __iomem
> *)
> - dev->base_addr);
> + int status = priv->hw->mac->host_irq_status(priv);
> +
> if (unlikely(status)) {
> if (status & core_mmc_tx_irq)
> priv->xstats.mmc_tx_irq_n++;
> @@ -1634,6 +1721,8 @@ static irqreturn_t stmmac_interrupt(int irq, void
> *dev_id)
> /* To handle DMA interrupts */
> stmmac_dma_interrupt(priv);
>
> + unmask_pvm(priv->pdev);
> +
> return IRQ_HANDLED;
> }
Hi Bryan,
The MSI masking is already implemented in the MSI framework: http://lxr.free-electrons.com/source/drivers/pci/msi.c#L181.
I don't see a reason to upstream a local set implementation to Ethernet subsystem.
Thanks.
Regards,
Wilson
^ permalink raw reply
* [PATCH] net: dsa: Fix build warning for !PM_SLEEP
From: Thierry Reding @ 2014-10-01 11:59 UTC (permalink / raw)
To: David S. Miller; +Cc: Florian Fainelli, netdev, linux-kernel
From: Thierry Reding <treding@nvidia.com>
The dsa_switch_suspend() and dsa_switch_resume() functions are only used
when PM_SLEEP is enabled, so they need #ifdef CONFIG_PM_SLEEP protection
to avoid a compiler warning.
Signed-off-by: Thierry Reding <treding@nvidia.com>
---
net/dsa/dsa.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/net/dsa/dsa.c b/net/dsa/dsa.c
index 6905f2d84c44..22f34cf4cb27 100644
--- a/net/dsa/dsa.c
+++ b/net/dsa/dsa.c
@@ -238,6 +238,7 @@ static void dsa_switch_destroy(struct dsa_switch *ds)
{
}
+#ifdef CONFIG_PM_SLEEP
static int dsa_switch_suspend(struct dsa_switch *ds)
{
int i, ret = 0;
@@ -280,6 +281,7 @@ static int dsa_switch_resume(struct dsa_switch *ds)
return 0;
}
+#endif
/* link polling *************************************************************/
--
2.1.0
^ permalink raw reply related
* Re: [net-next v3 20/29] fm10k: Add support for netdev offloads
From: Alexander Duyck @ 2014-10-01 12:02 UTC (permalink / raw)
To: Or Gerlitz, Jeff Kirsher
Cc: David Miller, Linux Netdev List, nhorman, sassmann, jogreene,
Tom Herbert
In-Reply-To: <CAJ3xEMhv-cS+vShPjTvOuWP182wf=zubNU=_p08DSkNv9W2C-w@mail.gmail.com>
On 10/01/2014 01:31 AM, Or Gerlitz wrote:
> On Tue, Sep 23, 2014 at 2:16 PM, Jeff Kirsher
> <jeffrey.t.kirsher@intel.com> wrote:
>> From: Alexander Duyck <alexander.h.duyck@intel.com>
>> This patch adds support for basic offloads including TSO, Tx checksum, Rx
>> checksum, Rx hash, and the same features applied to VXLAN/NVGRE tunnels.
>
>> --- a/drivers/net/ethernet/intel/fm10k/fm10k_main.c
>> +++ b/drivers/net/ethernet/intel/fm10k/fm10k_main.c
> [...]
>> +#define VXLAN_HLEN (sizeof(struct udphdr) + 8)
>> +static struct ethhdr *fm10k_port_is_vxlan(struct sk_buff *skb)
>> +{
>> + struct fm10k_intfc *interface = netdev_priv(skb->dev);
>> + struct fm10k_vxlan_port *vxlan_port;
>> +
>> + /* we can only offload a vxlan if we recognize it as such */
>> + vxlan_port = list_first_entry_or_null(&interface->vxlan_port,
>> + struct fm10k_vxlan_port, list);
>> +
>> + if (!vxlan_port)
>> + return NULL;
>> + if (vxlan_port->port != udp_hdr(skb)->dest)
>> + return NULL;
>> +
>> + /* return offset of udp_hdr plus 8 bytes for VXLAN header */
>> + return (struct ethhdr *)(skb_transport_header(skb) + VXLAN_HLEN);
>> +}
>> +
>> +#define FM10K_NVGRE_RESERVED0_FLAGS htons(0x9FFF)
>> +#define NVGRE_TNI htons(0x2000)
>> +struct fm10k_nvgre_hdr {
>> + __be16 flags;
>> + __be16 proto;
>> + __be32 tni;
>> +};
>> +
>> +static struct ethhdr *fm10k_gre_is_nvgre(struct sk_buff *skb)
>> +{
>> + struct fm10k_nvgre_hdr *nvgre_hdr;
>> + int hlen = ip_hdrlen(skb);
>> +
>> + /* currently only IPv4 is supported due to hlen above */
>> + if (vlan_get_protocol(skb) != htons(ETH_P_IP))
>> + return NULL;
>> +
>> + /* our transport header should be NVGRE */
>> + nvgre_hdr = (struct fm10k_nvgre_hdr *)(skb_network_header(skb) + hlen);
>> +
>> + /* verify all reserved flags are 0 */
>> + if (nvgre_hdr->flags & FM10K_NVGRE_RESERVED0_FLAGS)
>> + return NULL;
>> +
>> + /* verify protocol is transparent Ethernet bridging */
>> + if (nvgre_hdr->proto != htons(ETH_P_TEB))
>> + return NULL;
>> +
>> + /* report start of ethernet header */
>> + if (nvgre_hdr->flags & NVGRE_TNI)
>> + return (struct ethhdr *)(nvgre_hdr + 1);
>> +
>> + return (struct ethhdr *)(&nvgre_hdr->tni);
>> +}
>
> this helper is fully generic, should reside elsewhere in the stack
I will look into that and submit a follow-up patch to pull it out.
>> +static int fm10k_tso(struct fm10k_ring *tx_ring,
>> + struct fm10k_tx_buffer *first)
>> +{
>> + struct sk_buff *skb = first->skb;
>> + struct fm10k_tx_desc *tx_desc;
>> + unsigned char *th;
>> + u8 hdrlen;
>> +
>> + if (skb->ip_summed != CHECKSUM_PARTIAL)
>> + return 0;
>> +
>> + if (!skb_is_gso(skb))
>> + return 0;
>> +
>> + /* compute header lengths */
>> + if (skb->encapsulation) {
>> + if (!fm10k_tx_encap_offload(skb))
>> + goto err_vxlan;
>> + th = skb_inner_transport_header(skb);
>> + } else {
>> + th = skb_transport_header(skb);
>> + }
>> +
>> + /* compute offset from SOF to transport header and add header len */
>> + hdrlen = (th - skb->data) + (((struct tcphdr *)th)->doff << 2);
>> +
>> + first->tx_flags |= FM10K_TX_FLAGS_CSUM;
>> +
>> + /* update gso size and bytecount with header size */
>> + first->gso_segs = skb_shinfo(skb)->gso_segs;
>> + first->bytecount += (first->gso_segs - 1) * hdrlen;
>> +
>> + /* populate Tx descriptor header size and mss */
>> + tx_desc = FM10K_TX_DESC(tx_ring, tx_ring->next_to_use);
>> + tx_desc->hdrlen = hdrlen;
>> + tx_desc->mss = cpu_to_le16(skb_shinfo(skb)->gso_size);
>> +
>> + return 1;
>> +err_vxlan:
>> + tx_ring->netdev->features &= ~NETIF_F_GSO_UDP_TUNNEL;
>> + if (!net_ratelimit())
>> + netdev_err(tx_ring->netdev,
>> + "TSO requested for unsupported tunnel, disabling offload\n");
>> + return -1;
>> +}
>
> why? if TSO was requested for some packet the driver can't do, you disable GSO
> for udp tunnels for any future packets too? maybe just disable it
> permanently till you
> feel safer to run under the current stack?
That is essentially what I am doing. If the user wants they can turn
the feature back on via ethtool, but there is no point in having it on
if the device itself cannot support the packets that are coming through.
Thanks,
Alex
^ permalink raw reply
* Re: [PATCH 4/4] net: stmmac: add MSI support for Intel Quark X1000
From: Bryan O'Donoghue @ 2014-10-01 12:05 UTC (permalink / raw)
To: Kweh, Hock Leong, 'David Miller'
Cc: 'peppe.cavallaro@st.com',
'rayagond@vayavyalabs.com',
'vbridgers2013@gmail.com',
'srinivas.kandagatla@st.com', 'wens@csie.org',
'netdev@vger.kernel.org',
'linux-kernel@vger.kernel.org', Ong, Boon Leong
In-Reply-To: <F54AEECA5E2B9541821D670476DAE19C2B7F6612@PGSMSX102.gar.corp.intel.com>
On 01/10/14 12:55, Kweh, Hock Leong wrote:
>> -----Original Message-----
>> From: Bryan O'Donoghue [mailto:pure.logic@nexus-software.ie]
>> Sent: Wednesday, October 01, 2014 7:29 PM
>> Hi Wilson.
>>
>> Seeing you post now on the PCI emumeration suggestion from Dave Miller I
>> see
>>
>> I wasn't copied on this https://lkml.org/lkml/2014/8/27/190 thread so can
>> only respond now....
>>
>> What's missing from your MSI enabling code is the PVM mask/unmask
>> required on the Quark X1000 bridge - for *all* downstream devices using MSI.
>>
>> I realise it's not an upstreaming friendly piece of code - however - without
>> the PVM mask operation all MSIs on Quark should be considered unreliable.
>>
>> Maybe you guys have submitted patches to the PCI layer on this already ?
>> If so feel free to ignore.
>>
>> If not then please re-evaluate all MSI enabling code.
>>
>> From the original
>>
>> http://downloadmirror.intel.com/23171/eng/Board_Support_Package_Sour
>> ces_for_Intel_Quark_v1.0.0.7z
>>
>> +#if defined(CONFIG_INTEL_QUARK_X1000_SOC)
>> + #define mask_pvm(x) qrk_pci_pvm_mask(x)
>> + #define unmask_pvm(x) qrk_pci_pvm_unmask(x) #else
>> + #define mask_pvm(x)
>> + #define unmask_pvm(x)
>> +#endif
>> +
>> static irqreturn_t stmmac_interrupt(int irq, void *dev_id)
>> {
>> struct net_device *dev = (struct net_device *)dev_id; @@ -1601,10
>> +1686,12 @@ static irqreturn_t stmmac_interrupt(int irq, void *dev_id)
>> return IRQ_NONE;
>> }
>>
>> + mask_pvm(priv->pdev);
>> +
>> /* To handle GMAC own interrupts */
>> if (priv->plat->has_gmac) {
>> - int status = priv->hw->mac->host_irq_status((void __iomem
>> *)
>> - dev->base_addr);
>> + int status = priv->hw->mac->host_irq_status(priv);
>> +
>> if (unlikely(status)) {
>> if (status & core_mmc_tx_irq)
>> priv->xstats.mmc_tx_irq_n++;
>> @@ -1634,6 +1721,8 @@ static irqreturn_t stmmac_interrupt(int irq, void
>> *dev_id)
>> /* To handle DMA interrupts */
>> stmmac_dma_interrupt(priv);
>>
>> + unmask_pvm(priv->pdev);
> Hi Bryan,
>
> The MSI masking is already implemented in the MSI framework: http://lxr.free-electrons.com/source/drivers/pci/msi.c#L181.
> I don't see a reason to upstream a local set implementation to Ethernet subsystem.
> Thanks.
Hi Wilson.
Understand where you are getting your MSI enabling code from.
What I'm saying to you is that on Quark SoC X1000 there's an
*additional* requirement with respect to MSIs
That's why the reference code for the Quark BSP does PVM masking for
*all* MSI enabled code - not just ethernet.....
I'll have a review of the patches for the SoC thus far with a view to
ensuring the MSI pvm issue is adequately addressed - but just to be
clear it's emphatically *not* ethernet specific.
In essence the following additional requirement is place on the Quark
SoC when using MSIs
pvm_mask();
/* handle your interrupt */
pvm_unmask();
It's the same behaviour in the USB gadget driver...
@@ -2779,55 +2788,70 @@ static irqreturn_t pch_udc_isr(int irq, void *pdev)
{
struct pch_udc_dev *dev = (struct pch_udc_dev *) pdev;
u32 dev_intr, ep_intr;
- int i;
-
- dev_intr = pch_udc_read_device_interrupts(dev);
- ep_intr = pch_udc_read_ep_interrupts(dev);
-
- /* For a hot plug, this find that the controller is hung up. */
- if (dev_intr == ep_intr)
- if (dev_intr == pch_udc_readl(dev, UDC_DEVCFG_ADDR)) {
- dev_dbg(&dev->pdev->dev, "UDC: Hung up\n");
- /* The controller is reset */
- pch_udc_writel(dev, UDC_SRST, UDC_SRST_ADDR);
- return IRQ_HANDLED;
+ int i, events = 0;
+
+ mask_pvm(dev->pdev);
// do stuff
+ unmask_pvm(dev->pdev);
+
return IRQ_HANDLED;
}
And again in the GIP block
+static irqreturn_t intel_qrk_gip_handler(int irq, void *dev_id)
+{
+ irqreturn_t ret_i2c = IRQ_NONE;
+ irqreturn_t ret_gpio = IRQ_NONE;
+ struct intel_qrk_gip_data *data = (struct intel_qrk_gip_data *)dev_id;
+
+ mask_pvm(data->pci_device);
+
+ if (likely(i2c)) {
+ /* Only I2C gets platform data */
+ ret_i2c = i2c_dw_isr(irq, data->i2c_drvdata);
+ }
+
+ if (likely(gpio)) {
+ ret_gpio = intel_qrk_gpio_isr(irq, NULL);
+ }
+
+ unmask_pvm(data->pci_device);
+
+ if (likely(IRQ_HANDLED == ret_i2c || IRQ_HANDLED == ret_gpio))
+ return IRQ_HANDLED;
+
+ /* Each sub-ISR routine returns either IRQ_HANDLED or IRQ_NONE. */
+ return IRQ_NONE;
+}
Best,
BOD
^ permalink raw reply
* Re: [PATCH] net: dsa: Fix build warning for !PM_SLEEP
From: Fabio Estevam @ 2014-10-01 12:19 UTC (permalink / raw)
To: Thierry Reding
Cc: David S. Miller, Florian Fainelli, netdev@vger.kernel.org,
linux-kernel
In-Reply-To: <1412164740-32452-1-git-send-email-thierry.reding@gmail.com>
On Wed, Oct 1, 2014 at 8:59 AM, Thierry Reding <thierry.reding@gmail.com> wrote:
> From: Thierry Reding <treding@nvidia.com>
>
> The dsa_switch_suspend() and dsa_switch_resume() functions are only used
> when PM_SLEEP is enabled, so they need #ifdef CONFIG_PM_SLEEP protection
> to avoid a compiler warning.
>
> Signed-off-by: Thierry Reding <treding@nvidia.com>
> ---
> net/dsa/dsa.c | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/net/dsa/dsa.c b/net/dsa/dsa.c
> index 6905f2d84c44..22f34cf4cb27 100644
> --- a/net/dsa/dsa.c
> +++ b/net/dsa/dsa.c
> @@ -238,6 +238,7 @@ static void dsa_switch_destroy(struct dsa_switch *ds)
> {
> }
>
> +#ifdef CONFIG_PM_SLEEP
> static int dsa_switch_suspend(struct dsa_switch *ds)
> {
> int i, ret = 0;
> @@ -280,6 +281,7 @@ static int dsa_switch_resume(struct dsa_switch *ds)
>
> return 0;
> }
> +#endif
You could also mark them as __maybe_unused and avoid the ifdef.
^ permalink raw reply
* RE: [net-next v3 20/29] fm10k: Add support for netdev offloads
From: Sathya Perla @ 2014-10-01 12:22 UTC (permalink / raw)
To: Alexander Duyck, Or Gerlitz, Jeff Kirsher
Cc: David Miller, Linux Netdev List, nhorman@redhat.com,
sassmann@redhat.com, jogreene@redhat.com, Tom Herbert
In-Reply-To: <542BED4F.9070900@intel.com>
> -----Original Message-----
> From: netdev-owner@vger.kernel.org [mailto:netdev-
>
> On 10/01/2014 01:31 AM, Or Gerlitz wrote:
> > On Tue, Sep 23, 2014 at 2:16 PM, Jeff Kirsher
> > <jeffrey.t.kirsher@intel.com> wrote:
> >> From: Alexander Duyck <alexander.h.duyck@intel.com>
> >> This patch adds support for basic offloads including TSO, Tx checksum, Rx
> >> checksum, Rx hash, and the same features applied to VXLAN/NVGRE
> tunnels.
> >
> >> --- a/drivers/net/ethernet/intel/fm10k/fm10k_main.c
> >> +++ b/drivers/net/ethernet/intel/fm10k/fm10k_main.c
> > [...]
> >> +#define VXLAN_HLEN (sizeof(struct udphdr) + 8)
> >> +static struct ethhdr *fm10k_port_is_vxlan(struct sk_buff *skb)
> >> +{
> >> + struct fm10k_intfc *interface = netdev_priv(skb->dev);
> >> + struct fm10k_vxlan_port *vxlan_port;
> >> +
> >> + /* we can only offload a vxlan if we recognize it as such */
> >> + vxlan_port = list_first_entry_or_null(&interface->vxlan_port,
> >> + struct fm10k_vxlan_port, list);
> >> +
> >> + if (!vxlan_port)
> >> + return NULL;
> >> + if (vxlan_port->port != udp_hdr(skb)->dest)
> >> + return NULL;
> >> +
> >> + /* return offset of udp_hdr plus 8 bytes for VXLAN header */
> >> + return (struct ethhdr *)(skb_transport_header(skb) + VXLAN_HLEN);
> >> +}
> >> +
...
>
> >> +static int fm10k_tso(struct fm10k_ring *tx_ring,
> >> + struct fm10k_tx_buffer *first)
> >> +{
> >> + struct sk_buff *skb = first->skb;
> >> + struct fm10k_tx_desc *tx_desc;
> >> + unsigned char *th;
> >> + u8 hdrlen;
> >> +
> >> + if (skb->ip_summed != CHECKSUM_PARTIAL)
> >> + return 0;
> >> +
> >> + if (!skb_is_gso(skb))
> >> + return 0;
> >> +
> >> + /* compute header lengths */
> >> + if (skb->encapsulation) {
> >> + if (!fm10k_tx_encap_offload(skb))
> >> + goto err_vxlan;
> >> + th = skb_inner_transport_header(skb);
> >> + } else {
> >> + th = skb_transport_header(skb);
> >> + }
> >> +
> >> + /* compute offset from SOF to transport header and add header len
> */
> >> + hdrlen = (th - skb->data) + (((struct tcphdr *)th)->doff << 2);
> >> +
> >> + first->tx_flags |= FM10K_TX_FLAGS_CSUM;
> >> +
> >> + /* update gso size and bytecount with header size */
> >> + first->gso_segs = skb_shinfo(skb)->gso_segs;
> >> + first->bytecount += (first->gso_segs - 1) * hdrlen;
> >> +
> >> + /* populate Tx descriptor header size and mss */
> >> + tx_desc = FM10K_TX_DESC(tx_ring, tx_ring->next_to_use);
> >> + tx_desc->hdrlen = hdrlen;
> >> + tx_desc->mss = cpu_to_le16(skb_shinfo(skb)->gso_size);
> >> +
> >> + return 1;
> >> +err_vxlan:
> >> + tx_ring->netdev->features &= ~NETIF_F_GSO_UDP_TUNNEL;
> >> + if (!net_ratelimit())
> >> + netdev_err(tx_ring->netdev,
> >> + "TSO requested for unsupported tunnel, disabling
> offload\n");
> >> + return -1;
> >> +}
> >
> > why? if TSO was requested for some packet the driver can't do, you disable
> GSO
> > for udp tunnels for any future packets too? maybe just disable it
> > permanently till you
> > feel safer to run under the current stack?
>
> That is essentially what I am doing. If the user wants they can turn
> the feature back on via ethtool, but there is no point in having it on
> if the device itself cannot support the packets that are coming through.
>
To turn off the offload, shouldn't you be using netdev_update_features()
(->ndo_fix_features()) instead of directly flipping bits in netdev->features?
^ permalink raw reply
* Re: [PATCH net-next] et131x: Add PCIe gigabit ethernet driver et131x to drivers/net
From: Tobias Klauser @ 2014-10-01 12:45 UTC (permalink / raw)
To: Mark Einon; +Cc: davem, gregkh, linux-kernel, netdev
In-Reply-To: <1412112586-2194-1-git-send-email-mark.einon@gmail.com>
On 2014-09-30 at 23:29:46 +0200, Mark Einon <mark.einon@gmail.com> wrote:
> This adds the ethernet driver for Agere et131x devices to
> drivers/net/ethernet.
>
> The driver being added has been in the staging tree for some time, and will be
> removed from there in a seperate patch. This one merely disables the staging
> version to prevent two instances being built.
>
> Signed-off-by: Mark Einon <mark.einon@gmail.com>
> ---
> MAINTAINERS | 10 +-
> drivers/net/ethernet/Kconfig | 1 +
> drivers/net/ethernet/Makefile | 1 +
> drivers/net/ethernet/agere/Kconfig | 31 +
> drivers/net/ethernet/agere/Makefile | 5 +
> drivers/net/ethernet/agere/et131x.c | 4121 +++++++++++++++++++++++++++++++++++
> drivers/net/ethernet/agere/et131x.h | 1433 ++++++++++++
> drivers/staging/Kconfig | 2 -
> drivers/staging/Makefile | 1 -
> 9 files changed, 5597 insertions(+), 8 deletions(-)
> create mode 100644 drivers/net/ethernet/agere/Kconfig
> create mode 100644 drivers/net/ethernet/agere/Makefile
> create mode 100644 drivers/net/ethernet/agere/et131x.c
> create mode 100644 drivers/net/ethernet/agere/et131x.h
[...]
> diff --git a/drivers/net/ethernet/agere/et131x.c b/drivers/net/ethernet/agere/et131x.c
> new file mode 100644
> index 0000000..384dc16
> --- /dev/null
> +++ b/drivers/net/ethernet/agere/et131x.c
[...]
> +static int et131x_pci_setup(struct pci_dev *pdev,
> + const struct pci_device_id *ent)
> +{
> + struct net_device *netdev;
> + struct et131x_adapter *adapter;
> + int rc;
> + int ii;
> +
> + rc = pci_enable_device(pdev);
> + if (rc < 0) {
> + dev_err(&pdev->dev, "pci_enable_device() failed\n");
> + goto out;
Nit: Just return rc here.
> + }
> +
> + /* Perform some basic PCI checks */
> + if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) {
> + dev_err(&pdev->dev, "Can't find PCI device's base address\n");
> + rc = -ENODEV;
> + goto err_disable;
> + }
> +
> + rc = pci_request_regions(pdev, DRIVER_NAME);
> + if (rc < 0) {
> + dev_err(&pdev->dev, "Can't get PCI resources\n");
> + goto err_disable;
> + }
> +
> + pci_set_master(pdev);
> +
> + /* Check the DMA addressing support of this device */
> + if (dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64)) &&
> + dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32))) {
> + dev_err(&pdev->dev, "No usable DMA addressing method\n");
> + rc = -EIO;
> + goto err_release_res;
> + }
> +
> + netdev = alloc_etherdev(sizeof(struct et131x_adapter));
> + if (!netdev) {
> + dev_err(&pdev->dev, "Couldn't alloc netdev struct\n");
> + rc = -ENOMEM;
> + goto err_release_res;
> + }
> +
> + netdev->watchdog_timeo = ET131X_TX_TIMEOUT;
> + netdev->netdev_ops = &et131x_netdev_ops;
> +
> + SET_NETDEV_DEV(netdev, &pdev->dev);
> + netdev->ethtool_ops = &et131x_ethtool_ops;
> +
> + adapter = et131x_adapter_init(netdev, pdev);
> +
> + rc = et131x_pci_init(adapter, pdev);
> + if (rc < 0)
> + goto err_free_dev;
> +
> + /* Map the bus-relative registers to system virtual memory */
> + adapter->regs = pci_ioremap_bar(pdev, 0);
> + if (!adapter->regs) {
> + dev_err(&pdev->dev, "Cannot map device registers\n");
> + rc = -ENOMEM;
> + goto err_free_dev;
> + }
> +
> + /* If Phy COMA mode was enabled when we went down, disable it here. */
> + writel(ET_PMCSR_INIT, &adapter->regs->global.pm_csr);
> +
> + et131x_soft_reset(adapter);
> + et131x_disable_interrupts(adapter);
> +
> + rc = et131x_adapter_memory_alloc(adapter);
> + if (rc < 0) {
> + dev_err(&pdev->dev, "Could not alloc adapter memory (DMA)\n");
> + goto err_iounmap;
> + }
> +
> + et131x_init_send(adapter);
> +
> + netif_napi_add(netdev, &adapter->napi, et131x_poll, 64);
> +
> + ether_addr_copy(netdev->dev_addr, adapter->addr);
> +
> + rc = -ENOMEM;
> +
> + adapter->mii_bus = mdiobus_alloc();
> + if (!adapter->mii_bus) {
> + dev_err(&pdev->dev, "Alloc of mii_bus struct failed\n");
> + goto err_mem_free;
> + }
> +
> + adapter->mii_bus->name = "et131x_eth_mii";
> + snprintf(adapter->mii_bus->id, MII_BUS_ID_SIZE, "%x",
> + (adapter->pdev->bus->number << 8) | adapter->pdev->devfn);
> + adapter->mii_bus->priv = netdev;
> + adapter->mii_bus->read = et131x_mdio_read;
> + adapter->mii_bus->write = et131x_mdio_write;
> + adapter->mii_bus->irq = kmalloc_array(PHY_MAX_ADDR, sizeof(int),
> + GFP_KERNEL);
> + if (!adapter->mii_bus->irq)
> + goto err_mdio_free;
> +
> + for (ii = 0; ii < PHY_MAX_ADDR; ii++)
> + adapter->mii_bus->irq[ii] = PHY_POLL;
> +
> + rc = mdiobus_register(adapter->mii_bus);
> + if (rc < 0) {
> + dev_err(&pdev->dev, "failed to register MII bus\n");
> + goto err_mdio_free_irq;
> + }
> +
> + rc = et131x_mii_probe(netdev);
> + if (rc < 0) {
> + dev_err(&pdev->dev, "failed to probe MII bus\n");
> + goto err_mdio_unregister;
> + }
> +
> + et131x_adapter_setup(adapter);
> +
> + /* Init variable for counting how long we do not have link status */
> + adapter->boot_coma = 0;
> + et1310_disable_phy_coma(adapter);
> +
> + /* We can enable interrupts now
> + *
> + * NOTE - Because registration of interrupt handler is done in the
> + * device's open(), defer enabling device interrupts to that
> + * point
> + */
> +
> + rc = register_netdev(netdev);
> + if (rc < 0) {
> + dev_err(&pdev->dev, "register_netdev() failed\n");
> + goto err_phy_disconnect;
> + }
> +
> + /* Register the net_device struct with the PCI subsystem. Save a copy
> + * of the PCI config space for this device now that the device has
> + * been initialized, just in case it needs to be quickly restored.
> + */
> + pci_set_drvdata(pdev, netdev);
> +out:
> + return rc;
> +
> +err_phy_disconnect:
> + phy_disconnect(adapter->phydev);
> +err_mdio_unregister:
> + mdiobus_unregister(adapter->mii_bus);
> +err_mdio_free_irq:
> + kfree(adapter->mii_bus->irq);
> +err_mdio_free:
> + mdiobus_free(adapter->mii_bus);
> +err_mem_free:
> + et131x_adapter_memory_free(adapter);
> +err_iounmap:
> + iounmap(adapter->regs);
> +err_free_dev:
> + pci_dev_put(pdev);
> + free_netdev(netdev);
> +err_release_res:
> + pci_release_regions(pdev);
> +err_disable:
> + pci_disable_device(pdev);
> + goto out;
Same here, directly return rc. Then you can also get rid of the `out' label.
> +}
> +
> +static const struct pci_device_id et131x_pci_table[] = {
> + { PCI_VDEVICE(ATT, ET131X_PCI_DEVICE_ID_GIG), 0UL},
> + { PCI_VDEVICE(ATT, ET131X_PCI_DEVICE_ID_FAST), 0UL},
> + { 0,}
> +};
> +MODULE_DEVICE_TABLE(pci, et131x_pci_table);
> +
> +static struct pci_driver et131x_driver = {
> + .name = DRIVER_NAME,
> + .id_table = et131x_pci_table,
> + .probe = et131x_pci_setup,
> + .remove = et131x_pci_remove,
> + .driver.pm = &et131x_pm_ops,
> +};
> +
> +module_pci_driver(et131x_driver);
^ permalink raw reply
* Re: [PATCH] net: dsa: Fix build warning for !PM_SLEEP
From: Thierry Reding @ 2014-10-01 12:50 UTC (permalink / raw)
To: Fabio Estevam
Cc: David S. Miller, Florian Fainelli, netdev@vger.kernel.org,
linux-kernel
In-Reply-To: <CAOMZO5DJrvO=mpUEqk+GWFGGU_eNEfn=+XkoL6cqYv+c4GSyZw@mail.gmail.com>
[-- Attachment #1: Type: text/plain, Size: 1245 bytes --]
On Wed, Oct 01, 2014 at 09:19:24AM -0300, Fabio Estevam wrote:
> On Wed, Oct 1, 2014 at 8:59 AM, Thierry Reding <thierry.reding@gmail.com> wrote:
> > From: Thierry Reding <treding@nvidia.com>
> >
> > The dsa_switch_suspend() and dsa_switch_resume() functions are only used
> > when PM_SLEEP is enabled, so they need #ifdef CONFIG_PM_SLEEP protection
> > to avoid a compiler warning.
> >
> > Signed-off-by: Thierry Reding <treding@nvidia.com>
> > ---
> > net/dsa/dsa.c | 2 ++
> > 1 file changed, 2 insertions(+)
> >
> > diff --git a/net/dsa/dsa.c b/net/dsa/dsa.c
> > index 6905f2d84c44..22f34cf4cb27 100644
> > --- a/net/dsa/dsa.c
> > +++ b/net/dsa/dsa.c
> > @@ -238,6 +238,7 @@ static void dsa_switch_destroy(struct dsa_switch *ds)
> > {
> > }
> >
> > +#ifdef CONFIG_PM_SLEEP
> > static int dsa_switch_suspend(struct dsa_switch *ds)
> > {
> > int i, ret = 0;
> > @@ -280,6 +281,7 @@ static int dsa_switch_resume(struct dsa_switch *ds)
> >
> > return 0;
> > }
> > +#endif
>
> You could also mark them as __maybe_unused and avoid the ifdef.
The users of these functions, dsa_suspend() and dsa_resume(), also use
the CONFIG_PM_SLEEP protection, so this way is more consistent.
Thierry
[-- Attachment #2: Type: application/pgp-signature, Size: 819 bytes --]
^ permalink raw reply
* Re: [net-next PATCH V5] qdisc: bulk dequeue support for qdiscs with TCQ_F_ONETXQUEUE
From: Jamal Hadi Salim @ 2014-10-01 13:17 UTC (permalink / raw)
To: David Miller
Cc: brouer, netdev, therbert, eric.dumazet, hannes, fw, dborkman,
alexander.duyck, john.r.fastabend, dave.taht, toke
In-Reply-To: <20140930.142038.235338672810639160.davem@davemloft.net>
On 09/30/14 14:20, David Miller wrote:
> From: Jamal Hadi Salim <jhs@mojatatu.com>
> Date: Tue, 30 Sep 2014 07:07:37 -0400
>
>> Note, there are benefits as you have shown - but i would not
>> consider those to be standard use cases (actully one which would
>> have shown clear win is the VM thing Rusty was after).
>
> I completely disagree, you will see at least decreased cpu utilization
> for a very common case, bulk single stream transfers.
>
So lets say the common use case is:
= modern day cpu (pick some random cpu)
= 1-10 Gbps ethernet (not 100mbps)
= 1-24 tcp or udp bulk (you said one, Jesper had 24 which sounds better)
Run with test cases:
a) unchanged (no bulking code added at all)
vs
b) bulking code added and used
vs
c) bulking code added and *not* used
Jesper's results are comparing #b and #c.
And if #b + #c are slightly worse or equal then we have a win;->
Again, I do believe things like traffic generators or the VM io
or something like tuntap that crosses user space will have a clear
benefit (but are those common use cases?).
cheers,
jamal
^ permalink raw reply
* [PATCH V1 net-next 0/4] mlx5 update for 3.18
From: Eli Cohen @ 2014-10-01 13:18 UTC (permalink / raw)
To: davem; +Cc: netdev, ogerlitz, yevgenyp, Eli Cohen
Hi Dave,
This series integrates a new mechanism for populating and extracting field values
used in the driver/firmware interaction around command mailboxes.
Changes from V0:
- trimmed the auto-generated file to a minimum, as required by the reviewers.
Eli
Eli Cohen (4):
net/mlx5_core: Update device capabilities handling
net/mlx5_core: Use hardware registers description header file
net/mlx5_core: use set/get macros in device caps
net/mlx5_core: Identify resources by their type
drivers/infiniband/hw/mlx5/cq.c | 8 +-
drivers/infiniband/hw/mlx5/mad.c | 2 +-
drivers/infiniband/hw/mlx5/main.c | 83 +++---
drivers/infiniband/hw/mlx5/qp.c | 72 +++--
drivers/infiniband/hw/mlx5/srq.c | 6 +-
drivers/net/ethernet/mellanox/mlx5/core/cmd.c | 77 +++---
drivers/net/ethernet/mellanox/mlx5/core/eq.c | 14 +-
drivers/net/ethernet/mellanox/mlx5/core/fw.c | 81 +-----
drivers/net/ethernet/mellanox/mlx5/core/main.c | 229 ++++++++++++----
drivers/net/ethernet/mellanox/mlx5/core/qp.c | 60 +++--
drivers/net/ethernet/mellanox/mlx5/core/uar.c | 4 +-
include/linux/mlx5/device.h | 182 ++++++-------
include/linux/mlx5/driver.h | 118 +++------
include/linux/mlx5/mlx5_ifc.h | 349 +++++++++++++++++++++++++
include/linux/mlx5/qp.h | 3 +-
15 files changed, 833 insertions(+), 455 deletions(-)
create mode 100644 include/linux/mlx5/mlx5_ifc.h
--
2.1.1
^ permalink raw reply
* [PATCH V1 net-next 1/4] net/mlx5_core: Update device capabilities handling
From: Eli Cohen @ 2014-10-01 13:18 UTC (permalink / raw)
To: davem; +Cc: netdev, ogerlitz, yevgenyp, Eli Cohen
In-Reply-To: <1412169488-17500-1-git-send-email-eli@mellanox.com>
Rearrange struct mlx5_caps so it has a "gen" field to represent the current
capabilities configured for the device. Max capabilities can also be queried
from the device. Also update capabilities struct to contain more fields as per
the latest revision if firmware specification.
Change-Id: Ia0f9ad11779dfa76f51309abe676fd2e243bf20c
Signed-off-by: Eli Cohen <eli@mellanox.com>
---
drivers/infiniband/hw/mlx5/cq.c | 8 +-
drivers/infiniband/hw/mlx5/mad.c | 2 +-
drivers/infiniband/hw/mlx5/main.c | 83 ++++++----
drivers/infiniband/hw/mlx5/qp.c | 72 +++++---
drivers/infiniband/hw/mlx5/srq.c | 6 +-
drivers/net/ethernet/mellanox/mlx5/core/cmd.c | 24 ++-
drivers/net/ethernet/mellanox/mlx5/core/eq.c | 2 +-
drivers/net/ethernet/mellanox/mlx5/core/fw.c | 81 +--------
drivers/net/ethernet/mellanox/mlx5/core/main.c | 219 +++++++++++++++++++------
drivers/net/ethernet/mellanox/mlx5/core/uar.c | 4 +-
include/linux/mlx5/device.h | 24 ++-
include/linux/mlx5/driver.h | 28 +++-
12 files changed, 331 insertions(+), 222 deletions(-)
diff --git a/drivers/infiniband/hw/mlx5/cq.c b/drivers/infiniband/hw/mlx5/cq.c
index e4056279166d..10cfce5119a9 100644
--- a/drivers/infiniband/hw/mlx5/cq.c
+++ b/drivers/infiniband/hw/mlx5/cq.c
@@ -752,7 +752,7 @@ struct ib_cq *mlx5_ib_create_cq(struct ib_device *ibdev, int entries,
return ERR_PTR(-EINVAL);
entries = roundup_pow_of_two(entries + 1);
- if (entries > dev->mdev->caps.max_cqes)
+ if (entries > dev->mdev->caps.gen.max_cqes)
return ERR_PTR(-EINVAL);
cq = kzalloc(sizeof(*cq), GFP_KERNEL);
@@ -919,7 +919,7 @@ int mlx5_ib_modify_cq(struct ib_cq *cq, u16 cq_count, u16 cq_period)
int err;
u32 fsel;
- if (!(dev->mdev->caps.flags & MLX5_DEV_CAP_FLAG_CQ_MODER))
+ if (!(dev->mdev->caps.gen.flags & MLX5_DEV_CAP_FLAG_CQ_MODER))
return -ENOSYS;
in = kzalloc(sizeof(*in), GFP_KERNEL);
@@ -1074,7 +1074,7 @@ int mlx5_ib_resize_cq(struct ib_cq *ibcq, int entries, struct ib_udata *udata)
int uninitialized_var(cqe_size);
unsigned long flags;
- if (!(dev->mdev->caps.flags & MLX5_DEV_CAP_FLAG_RESIZE_CQ)) {
+ if (!(dev->mdev->caps.gen.flags & MLX5_DEV_CAP_FLAG_RESIZE_CQ)) {
pr_info("Firmware does not support resize CQ\n");
return -ENOSYS;
}
@@ -1083,7 +1083,7 @@ int mlx5_ib_resize_cq(struct ib_cq *ibcq, int entries, struct ib_udata *udata)
return -EINVAL;
entries = roundup_pow_of_two(entries + 1);
- if (entries > dev->mdev->caps.max_cqes + 1)
+ if (entries > dev->mdev->caps.gen.max_cqes + 1)
return -EINVAL;
if (entries == ibcq->cqe + 1)
diff --git a/drivers/infiniband/hw/mlx5/mad.c b/drivers/infiniband/hw/mlx5/mad.c
index b514bbb5610f..657af9a1167c 100644
--- a/drivers/infiniband/hw/mlx5/mad.c
+++ b/drivers/infiniband/hw/mlx5/mad.c
@@ -129,7 +129,7 @@ int mlx5_query_ext_port_caps(struct mlx5_ib_dev *dev, u8 port)
packet_error = be16_to_cpu(out_mad->status);
- dev->mdev->caps.ext_port_cap[port - 1] = (!err && !packet_error) ?
+ dev->mdev->caps.gen.ext_port_cap[port - 1] = (!err && !packet_error) ?
MLX_EXT_PORT_CAP_FLAG_EXTENDED_PORT_INFO : 0;
out:
diff --git a/drivers/infiniband/hw/mlx5/main.c b/drivers/infiniband/hw/mlx5/main.c
index d8907b20522a..f3114d1132fb 100644
--- a/drivers/infiniband/hw/mlx5/main.c
+++ b/drivers/infiniband/hw/mlx5/main.c
@@ -157,11 +157,13 @@ static int mlx5_ib_query_device(struct ib_device *ibdev,
struct mlx5_ib_dev *dev = to_mdev(ibdev);
struct ib_smp *in_mad = NULL;
struct ib_smp *out_mad = NULL;
+ struct mlx5_general_caps *gen;
int err = -ENOMEM;
int max_rq_sg;
int max_sq_sg;
u64 flags;
+ gen = &dev->mdev->caps.gen;
in_mad = kzalloc(sizeof(*in_mad), GFP_KERNEL);
out_mad = kmalloc(sizeof(*out_mad), GFP_KERNEL);
if (!in_mad || !out_mad)
@@ -183,7 +185,7 @@ static int mlx5_ib_query_device(struct ib_device *ibdev,
IB_DEVICE_PORT_ACTIVE_EVENT |
IB_DEVICE_SYS_IMAGE_GUID |
IB_DEVICE_RC_RNR_NAK_GEN;
- flags = dev->mdev->caps.flags;
+ flags = gen->flags;
if (flags & MLX5_DEV_CAP_FLAG_BAD_PKEY_CNTR)
props->device_cap_flags |= IB_DEVICE_BAD_PKEY_CNTR;
if (flags & MLX5_DEV_CAP_FLAG_BAD_QKEY_CNTR)
@@ -213,30 +215,31 @@ static int mlx5_ib_query_device(struct ib_device *ibdev,
memcpy(&props->sys_image_guid, out_mad->data + 4, 8);
props->max_mr_size = ~0ull;
- props->page_size_cap = dev->mdev->caps.min_page_sz;
- props->max_qp = 1 << dev->mdev->caps.log_max_qp;
- props->max_qp_wr = dev->mdev->caps.max_wqes;
- max_rq_sg = dev->mdev->caps.max_rq_desc_sz / sizeof(struct mlx5_wqe_data_seg);
- max_sq_sg = (dev->mdev->caps.max_sq_desc_sz - sizeof(struct mlx5_wqe_ctrl_seg)) /
+ props->page_size_cap = gen->min_page_sz;
+ props->max_qp = 1 << gen->log_max_qp;
+ props->max_qp_wr = gen->max_wqes;
+ max_rq_sg = gen->max_rq_desc_sz / sizeof(struct mlx5_wqe_data_seg);
+ max_sq_sg = (gen->max_sq_desc_sz - sizeof(struct mlx5_wqe_ctrl_seg)) /
sizeof(struct mlx5_wqe_data_seg);
props->max_sge = min(max_rq_sg, max_sq_sg);
- props->max_cq = 1 << dev->mdev->caps.log_max_cq;
- props->max_cqe = dev->mdev->caps.max_cqes - 1;
- props->max_mr = 1 << dev->mdev->caps.log_max_mkey;
- props->max_pd = 1 << dev->mdev->caps.log_max_pd;
- props->max_qp_rd_atom = dev->mdev->caps.max_ra_req_qp;
- props->max_qp_init_rd_atom = dev->mdev->caps.max_ra_res_qp;
+ props->max_cq = 1 << gen->log_max_cq;
+ props->max_cqe = gen->max_cqes - 1;
+ props->max_mr = 1 << gen->log_max_mkey;
+ props->max_pd = 1 << gen->log_max_pd;
+ props->max_qp_rd_atom = 1 << gen->log_max_ra_req_qp;
+ props->max_qp_init_rd_atom = 1 << gen->log_max_ra_res_qp;
+ props->max_srq = 1 << gen->log_max_srq;
+ props->max_srq_wr = gen->max_srq_wqes - 1;
+ props->local_ca_ack_delay = gen->local_ca_ack_delay;
props->max_res_rd_atom = props->max_qp_rd_atom * props->max_qp;
- props->max_srq = 1 << dev->mdev->caps.log_max_srq;
- props->max_srq_wr = dev->mdev->caps.max_srq_wqes - 1;
props->max_srq_sge = max_rq_sg - 1;
props->max_fast_reg_page_list_len = (unsigned int)-1;
- props->local_ca_ack_delay = dev->mdev->caps.local_ca_ack_delay;
+ props->local_ca_ack_delay = gen->local_ca_ack_delay;
props->atomic_cap = IB_ATOMIC_NONE;
props->masked_atomic_cap = IB_ATOMIC_NONE;
props->max_pkeys = be16_to_cpup((__be16 *)(out_mad->data + 28));
- props->max_mcast_grp = 1 << dev->mdev->caps.log_max_mcg;
- props->max_mcast_qp_attach = dev->mdev->caps.max_qp_mcg;
+ props->max_mcast_grp = 1 << gen->log_max_mcg;
+ props->max_mcast_qp_attach = gen->max_qp_mcg;
props->max_total_mcast_qp_attach = props->max_mcast_qp_attach *
props->max_mcast_grp;
props->max_map_per_fmr = INT_MAX; /* no limit in ConnectIB */
@@ -254,10 +257,12 @@ int mlx5_ib_query_port(struct ib_device *ibdev, u8 port,
struct mlx5_ib_dev *dev = to_mdev(ibdev);
struct ib_smp *in_mad = NULL;
struct ib_smp *out_mad = NULL;
+ struct mlx5_general_caps *gen;
int ext_active_speed;
int err = -ENOMEM;
- if (port < 1 || port > dev->mdev->caps.num_ports) {
+ gen = &dev->mdev->caps.gen;
+ if (port < 1 || port > gen->num_ports) {
mlx5_ib_warn(dev, "invalid port number %d\n", port);
return -EINVAL;
}
@@ -288,8 +293,8 @@ int mlx5_ib_query_port(struct ib_device *ibdev, u8 port,
props->phys_state = out_mad->data[33] >> 4;
props->port_cap_flags = be32_to_cpup((__be32 *)(out_mad->data + 20));
props->gid_tbl_len = out_mad->data[50];
- props->max_msg_sz = 1 << to_mdev(ibdev)->mdev->caps.log_max_msg;
- props->pkey_tbl_len = to_mdev(ibdev)->mdev->caps.port[port - 1].pkey_table_len;
+ props->max_msg_sz = 1 << gen->log_max_msg;
+ props->pkey_tbl_len = gen->port[port - 1].pkey_table_len;
props->bad_pkey_cntr = be16_to_cpup((__be16 *)(out_mad->data + 46));
props->qkey_viol_cntr = be16_to_cpup((__be16 *)(out_mad->data + 48));
props->active_width = out_mad->data[31] & 0xf;
@@ -316,7 +321,7 @@ int mlx5_ib_query_port(struct ib_device *ibdev, u8 port,
/* If reported active speed is QDR, check if is FDR-10 */
if (props->active_speed == 4) {
- if (dev->mdev->caps.ext_port_cap[port - 1] &
+ if (gen->ext_port_cap[port - 1] &
MLX_EXT_PORT_CAP_FLAG_EXTENDED_PORT_INFO) {
init_query_mad(in_mad);
in_mad->attr_id = MLX5_ATTR_EXTENDED_PORT_INFO;
@@ -470,6 +475,7 @@ static struct ib_ucontext *mlx5_ib_alloc_ucontext(struct ib_device *ibdev,
struct mlx5_ib_alloc_ucontext_req_v2 req;
struct mlx5_ib_alloc_ucontext_resp resp;
struct mlx5_ib_ucontext *context;
+ struct mlx5_general_caps *gen;
struct mlx5_uuar_info *uuari;
struct mlx5_uar *uars;
int gross_uuars;
@@ -480,6 +486,7 @@ static struct ib_ucontext *mlx5_ib_alloc_ucontext(struct ib_device *ibdev,
int i;
size_t reqlen;
+ gen = &dev->mdev->caps.gen;
if (!dev->ib_active)
return ERR_PTR(-EAGAIN);
@@ -512,14 +519,14 @@ static struct ib_ucontext *mlx5_ib_alloc_ucontext(struct ib_device *ibdev,
num_uars = req.total_num_uuars / MLX5_NON_FP_BF_REGS_PER_PAGE;
gross_uuars = num_uars * MLX5_BF_REGS_PER_PAGE;
- resp.qp_tab_size = 1 << dev->mdev->caps.log_max_qp;
- resp.bf_reg_size = dev->mdev->caps.bf_reg_size;
+ resp.qp_tab_size = 1 << gen->log_max_qp;
+ resp.bf_reg_size = gen->bf_reg_size;
resp.cache_line_size = L1_CACHE_BYTES;
- resp.max_sq_desc_sz = dev->mdev->caps.max_sq_desc_sz;
- resp.max_rq_desc_sz = dev->mdev->caps.max_rq_desc_sz;
- resp.max_send_wqebb = dev->mdev->caps.max_wqes;
- resp.max_recv_wr = dev->mdev->caps.max_wqes;
- resp.max_srq_recv_wr = dev->mdev->caps.max_srq_wqes;
+ resp.max_sq_desc_sz = gen->max_sq_desc_sz;
+ resp.max_rq_desc_sz = gen->max_rq_desc_sz;
+ resp.max_send_wqebb = gen->max_wqes;
+ resp.max_recv_wr = gen->max_wqes;
+ resp.max_srq_recv_wr = gen->max_srq_wqes;
context = kzalloc(sizeof(*context), GFP_KERNEL);
if (!context)
@@ -565,7 +572,7 @@ static struct ib_ucontext *mlx5_ib_alloc_ucontext(struct ib_device *ibdev,
mutex_init(&context->db_page_mutex);
resp.tot_uuars = req.total_num_uuars;
- resp.num_ports = dev->mdev->caps.num_ports;
+ resp.num_ports = gen->num_ports;
err = ib_copy_to_udata(udata, &resp,
sizeof(resp) - sizeof(resp.reserved));
if (err)
@@ -967,9 +974,11 @@ static void mlx5_ib_event(struct mlx5_core_dev *dev, void *context,
static void get_ext_port_caps(struct mlx5_ib_dev *dev)
{
+ struct mlx5_general_caps *gen;
int port;
- for (port = 1; port <= dev->mdev->caps.num_ports; port++)
+ gen = &dev->mdev->caps.gen;
+ for (port = 1; port <= gen->num_ports; port++)
mlx5_query_ext_port_caps(dev, port);
}
@@ -977,9 +986,11 @@ static int get_port_caps(struct mlx5_ib_dev *dev)
{
struct ib_device_attr *dprops = NULL;
struct ib_port_attr *pprops = NULL;
+ struct mlx5_general_caps *gen;
int err = 0;
int port;
+ gen = &dev->mdev->caps.gen;
pprops = kmalloc(sizeof(*pprops), GFP_KERNEL);
if (!pprops)
goto out;
@@ -994,14 +1005,14 @@ static int get_port_caps(struct mlx5_ib_dev *dev)
goto out;
}
- for (port = 1; port <= dev->mdev->caps.num_ports; port++) {
+ for (port = 1; port <= gen->num_ports; port++) {
err = mlx5_ib_query_port(&dev->ib_dev, port, pprops);
if (err) {
mlx5_ib_warn(dev, "query_port %d failed %d\n", port, err);
break;
}
- dev->mdev->caps.port[port - 1].pkey_table_len = dprops->max_pkeys;
- dev->mdev->caps.port[port - 1].gid_table_len = pprops->gid_tbl_len;
+ gen->port[port - 1].pkey_table_len = dprops->max_pkeys;
+ gen->port[port - 1].gid_table_len = pprops->gid_tbl_len;
mlx5_ib_dbg(dev, "pkey_table_len %d, gid_table_len %d\n",
dprops->max_pkeys, pprops->gid_tbl_len);
}
@@ -1279,8 +1290,8 @@ static void *mlx5_ib_add(struct mlx5_core_dev *mdev)
strlcpy(dev->ib_dev.name, "mlx5_%d", IB_DEVICE_NAME_MAX);
dev->ib_dev.owner = THIS_MODULE;
dev->ib_dev.node_type = RDMA_NODE_IB_CA;
- dev->ib_dev.local_dma_lkey = mdev->caps.reserved_lkey;
- dev->num_ports = mdev->caps.num_ports;
+ dev->ib_dev.local_dma_lkey = mdev->caps.gen.reserved_lkey;
+ dev->num_ports = mdev->caps.gen.num_ports;
dev->ib_dev.phys_port_cnt = dev->num_ports;
dev->ib_dev.num_comp_vectors = dev->num_comp_vectors;
dev->ib_dev.dma_device = &mdev->pdev->dev;
@@ -1355,7 +1366,7 @@ static void *mlx5_ib_add(struct mlx5_core_dev *mdev)
dev->ib_dev.free_fast_reg_page_list = mlx5_ib_free_fast_reg_page_list;
dev->ib_dev.check_mr_status = mlx5_ib_check_mr_status;
- if (mdev->caps.flags & MLX5_DEV_CAP_FLAG_XRC) {
+ if (mdev->caps.gen.flags & MLX5_DEV_CAP_FLAG_XRC) {
dev->ib_dev.alloc_xrcd = mlx5_ib_alloc_xrcd;
dev->ib_dev.dealloc_xrcd = mlx5_ib_dealloc_xrcd;
dev->ib_dev.uverbs_cmd_mask |=
diff --git a/drivers/infiniband/hw/mlx5/qp.c b/drivers/infiniband/hw/mlx5/qp.c
index 8c574b63d77b..dbfe498870c1 100644
--- a/drivers/infiniband/hw/mlx5/qp.c
+++ b/drivers/infiniband/hw/mlx5/qp.c
@@ -158,11 +158,13 @@ static void mlx5_ib_qp_event(struct mlx5_core_qp *qp, int type)
static int set_rq_size(struct mlx5_ib_dev *dev, struct ib_qp_cap *cap,
int has_rq, struct mlx5_ib_qp *qp, struct mlx5_ib_create_qp *ucmd)
{
+ struct mlx5_general_caps *gen;
int wqe_size;
int wq_size;
+ gen = &dev->mdev->caps.gen;
/* Sanity check RQ size before proceeding */
- if (cap->max_recv_wr > dev->mdev->caps.max_wqes)
+ if (cap->max_recv_wr > gen->max_wqes)
return -EINVAL;
if (!has_rq) {
@@ -182,10 +184,10 @@ static int set_rq_size(struct mlx5_ib_dev *dev, struct ib_qp_cap *cap,
wq_size = roundup_pow_of_two(cap->max_recv_wr) * wqe_size;
wq_size = max_t(int, wq_size, MLX5_SEND_WQE_BB);
qp->rq.wqe_cnt = wq_size / wqe_size;
- if (wqe_size > dev->mdev->caps.max_rq_desc_sz) {
+ if (wqe_size > gen->max_rq_desc_sz) {
mlx5_ib_dbg(dev, "wqe_size %d, max %d\n",
wqe_size,
- dev->mdev->caps.max_rq_desc_sz);
+ gen->max_rq_desc_sz);
return -EINVAL;
}
qp->rq.wqe_shift = ilog2(wqe_size);
@@ -266,9 +268,11 @@ static int calc_send_wqe(struct ib_qp_init_attr *attr)
static int calc_sq_size(struct mlx5_ib_dev *dev, struct ib_qp_init_attr *attr,
struct mlx5_ib_qp *qp)
{
+ struct mlx5_general_caps *gen;
int wqe_size;
int wq_size;
+ gen = &dev->mdev->caps.gen;
if (!attr->cap.max_send_wr)
return 0;
@@ -277,9 +281,9 @@ static int calc_sq_size(struct mlx5_ib_dev *dev, struct ib_qp_init_attr *attr,
if (wqe_size < 0)
return wqe_size;
- if (wqe_size > dev->mdev->caps.max_sq_desc_sz) {
+ if (wqe_size > gen->max_sq_desc_sz) {
mlx5_ib_dbg(dev, "wqe_size(%d) > max_sq_desc_sz(%d)\n",
- wqe_size, dev->mdev->caps.max_sq_desc_sz);
+ wqe_size, gen->max_sq_desc_sz);
return -EINVAL;
}
@@ -292,9 +296,9 @@ static int calc_sq_size(struct mlx5_ib_dev *dev, struct ib_qp_init_attr *attr,
wq_size = roundup_pow_of_two(attr->cap.max_send_wr * wqe_size);
qp->sq.wqe_cnt = wq_size / MLX5_SEND_WQE_BB;
- if (qp->sq.wqe_cnt > dev->mdev->caps.max_wqes) {
+ if (qp->sq.wqe_cnt > gen->max_wqes) {
mlx5_ib_dbg(dev, "wqe count(%d) exceeds limits(%d)\n",
- qp->sq.wqe_cnt, dev->mdev->caps.max_wqes);
+ qp->sq.wqe_cnt, gen->max_wqes);
return -ENOMEM;
}
qp->sq.wqe_shift = ilog2(MLX5_SEND_WQE_BB);
@@ -309,11 +313,13 @@ static int set_user_buf_size(struct mlx5_ib_dev *dev,
struct mlx5_ib_qp *qp,
struct mlx5_ib_create_qp *ucmd)
{
+ struct mlx5_general_caps *gen;
int desc_sz = 1 << qp->sq.wqe_shift;
- if (desc_sz > dev->mdev->caps.max_sq_desc_sz) {
+ gen = &dev->mdev->caps.gen;
+ if (desc_sz > gen->max_sq_desc_sz) {
mlx5_ib_warn(dev, "desc_sz %d, max_sq_desc_sz %d\n",
- desc_sz, dev->mdev->caps.max_sq_desc_sz);
+ desc_sz, gen->max_sq_desc_sz);
return -EINVAL;
}
@@ -325,9 +331,9 @@ static int set_user_buf_size(struct mlx5_ib_dev *dev,
qp->sq.wqe_cnt = ucmd->sq_wqe_count;
- if (qp->sq.wqe_cnt > dev->mdev->caps.max_wqes) {
+ if (qp->sq.wqe_cnt > gen->max_wqes) {
mlx5_ib_warn(dev, "wqe_cnt %d, max_wqes %d\n",
- qp->sq.wqe_cnt, dev->mdev->caps.max_wqes);
+ qp->sq.wqe_cnt, gen->max_wqes);
return -EINVAL;
}
@@ -803,16 +809,18 @@ static int create_qp_common(struct mlx5_ib_dev *dev, struct ib_pd *pd,
struct mlx5_ib_resources *devr = &dev->devr;
struct mlx5_ib_create_qp_resp resp;
struct mlx5_create_qp_mbox_in *in;
+ struct mlx5_general_caps *gen;
struct mlx5_ib_create_qp ucmd;
int inlen = sizeof(*in);
int err;
+ gen = &dev->mdev->caps.gen;
mutex_init(&qp->mutex);
spin_lock_init(&qp->sq.lock);
spin_lock_init(&qp->rq.lock);
if (init_attr->create_flags & IB_QP_CREATE_BLOCK_MULTICAST_LOOPBACK) {
- if (!(dev->mdev->caps.flags & MLX5_DEV_CAP_FLAG_BLOCK_MCAST)) {
+ if (!(gen->flags & MLX5_DEV_CAP_FLAG_BLOCK_MCAST)) {
mlx5_ib_dbg(dev, "block multicast loopback isn't supported\n");
return -EINVAL;
} else {
@@ -851,9 +859,9 @@ static int create_qp_common(struct mlx5_ib_dev *dev, struct ib_pd *pd,
mlx5_ib_dbg(dev, "invalid rq params\n");
return -EINVAL;
}
- if (ucmd.sq_wqe_count > dev->mdev->caps.max_wqes) {
+ if (ucmd.sq_wqe_count > gen->max_wqes) {
mlx5_ib_dbg(dev, "requested sq_wqe_count (%d) > max allowed (%d)\n",
- ucmd.sq_wqe_count, dev->mdev->caps.max_wqes);
+ ucmd.sq_wqe_count, gen->max_wqes);
return -EINVAL;
}
err = create_user_qp(dev, pd, qp, udata, &in, &resp, &inlen);
@@ -1144,6 +1152,7 @@ struct ib_qp *mlx5_ib_create_qp(struct ib_pd *pd,
struct ib_qp_init_attr *init_attr,
struct ib_udata *udata)
{
+ struct mlx5_general_caps *gen;
struct mlx5_ib_dev *dev;
struct mlx5_ib_qp *qp;
u16 xrcdn = 0;
@@ -1161,11 +1170,12 @@ struct ib_qp *mlx5_ib_create_qp(struct ib_pd *pd,
}
dev = to_mdev(to_mxrcd(init_attr->xrcd)->ibxrcd.device);
}
+ gen = &dev->mdev->caps.gen;
switch (init_attr->qp_type) {
case IB_QPT_XRC_TGT:
case IB_QPT_XRC_INI:
- if (!(dev->mdev->caps.flags & MLX5_DEV_CAP_FLAG_XRC)) {
+ if (!(gen->flags & MLX5_DEV_CAP_FLAG_XRC)) {
mlx5_ib_dbg(dev, "XRC not supported\n");
return ERR_PTR(-ENOSYS);
}
@@ -1272,6 +1282,9 @@ enum {
static int ib_rate_to_mlx5(struct mlx5_ib_dev *dev, u8 rate)
{
+ struct mlx5_general_caps *gen;
+
+ gen = &dev->mdev->caps.gen;
if (rate == IB_RATE_PORT_CURRENT) {
return 0;
} else if (rate < IB_RATE_2_5_GBPS || rate > IB_RATE_300_GBPS) {
@@ -1279,7 +1292,7 @@ static int ib_rate_to_mlx5(struct mlx5_ib_dev *dev, u8 rate)
} else {
while (rate != IB_RATE_2_5_GBPS &&
!(1 << (rate + MLX5_STAT_RATE_OFFSET) &
- dev->mdev->caps.stat_rate_support))
+ gen->stat_rate_support))
--rate;
}
@@ -1290,8 +1303,10 @@ static int mlx5_set_path(struct mlx5_ib_dev *dev, const struct ib_ah_attr *ah,
struct mlx5_qp_path *path, u8 port, int attr_mask,
u32 path_flags, const struct ib_qp_attr *attr)
{
+ struct mlx5_general_caps *gen;
int err;
+ gen = &dev->mdev->caps.gen;
path->fl = (path_flags & MLX5_PATH_FLAG_FL) ? 0x80 : 0;
path->free_ar = (path_flags & MLX5_PATH_FLAG_FREE_AR) ? 0x80 : 0;
@@ -1318,9 +1333,9 @@ static int mlx5_set_path(struct mlx5_ib_dev *dev, const struct ib_ah_attr *ah,
path->port = port;
if (ah->ah_flags & IB_AH_GRH) {
- if (ah->grh.sgid_index >= dev->mdev->caps.port[port - 1].gid_table_len) {
+ if (ah->grh.sgid_index >= gen->port[port - 1].gid_table_len) {
pr_err(KERN_ERR "sgid_index (%u) too large. max is %d\n",
- ah->grh.sgid_index, dev->mdev->caps.port[port - 1].gid_table_len);
+ ah->grh.sgid_index, gen->port[port - 1].gid_table_len);
return -EINVAL;
}
@@ -1492,6 +1507,7 @@ static int __mlx5_ib_modify_qp(struct ib_qp *ibqp,
struct mlx5_ib_qp *qp = to_mqp(ibqp);
struct mlx5_ib_cq *send_cq, *recv_cq;
struct mlx5_qp_context *context;
+ struct mlx5_general_caps *gen;
struct mlx5_modify_qp_mbox_in *in;
struct mlx5_ib_pd *pd;
enum mlx5_qp_state mlx5_cur, mlx5_new;
@@ -1500,6 +1516,7 @@ static int __mlx5_ib_modify_qp(struct ib_qp *ibqp,
int mlx5_st;
int err;
+ gen = &dev->mdev->caps.gen;
in = kzalloc(sizeof(*in), GFP_KERNEL);
if (!in)
return -ENOMEM;
@@ -1539,7 +1556,7 @@ static int __mlx5_ib_modify_qp(struct ib_qp *ibqp,
err = -EINVAL;
goto out;
}
- context->mtu_msgmax = (attr->path_mtu << 5) | dev->mdev->caps.log_max_msg;
+ context->mtu_msgmax = (attr->path_mtu << 5) | gen->log_max_msg;
}
if (attr_mask & IB_QP_DEST_QPN)
@@ -1685,9 +1702,11 @@ int mlx5_ib_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
struct mlx5_ib_dev *dev = to_mdev(ibqp->device);
struct mlx5_ib_qp *qp = to_mqp(ibqp);
enum ib_qp_state cur_state, new_state;
+ struct mlx5_general_caps *gen;
int err = -EINVAL;
int port;
+ gen = &dev->mdev->caps.gen;
mutex_lock(&qp->mutex);
cur_state = attr_mask & IB_QP_CUR_STATE ? attr->cur_qp_state : qp->state;
@@ -1699,21 +1718,21 @@ int mlx5_ib_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
goto out;
if ((attr_mask & IB_QP_PORT) &&
- (attr->port_num == 0 || attr->port_num > dev->mdev->caps.num_ports))
+ (attr->port_num == 0 || attr->port_num > gen->num_ports))
goto out;
if (attr_mask & IB_QP_PKEY_INDEX) {
port = attr_mask & IB_QP_PORT ? attr->port_num : qp->port;
- if (attr->pkey_index >= dev->mdev->caps.port[port - 1].pkey_table_len)
+ if (attr->pkey_index >= gen->port[port - 1].pkey_table_len)
goto out;
}
if (attr_mask & IB_QP_MAX_QP_RD_ATOMIC &&
- attr->max_rd_atomic > dev->mdev->caps.max_ra_res_qp)
+ attr->max_rd_atomic > (1 << gen->log_max_ra_res_qp))
goto out;
if (attr_mask & IB_QP_MAX_DEST_RD_ATOMIC &&
- attr->max_dest_rd_atomic > dev->mdev->caps.max_ra_req_qp)
+ attr->max_dest_rd_atomic > (1 << gen->log_max_ra_req_qp))
goto out;
if (cur_state == new_state && cur_state == IB_QPS_RESET) {
@@ -2893,7 +2912,8 @@ static void to_ib_ah_attr(struct mlx5_ib_dev *ibdev, struct ib_ah_attr *ib_ah_at
memset(ib_ah_attr, 0, sizeof(*ib_ah_attr));
ib_ah_attr->port_num = path->port;
- if (ib_ah_attr->port_num == 0 || ib_ah_attr->port_num > dev->caps.num_ports)
+ if (ib_ah_attr->port_num == 0 ||
+ ib_ah_attr->port_num > dev->caps.gen.num_ports)
return;
ib_ah_attr->sl = path->sl & 0xf;
@@ -3011,10 +3031,12 @@ struct ib_xrcd *mlx5_ib_alloc_xrcd(struct ib_device *ibdev,
struct ib_udata *udata)
{
struct mlx5_ib_dev *dev = to_mdev(ibdev);
+ struct mlx5_general_caps *gen;
struct mlx5_ib_xrcd *xrcd;
int err;
- if (!(dev->mdev->caps.flags & MLX5_DEV_CAP_FLAG_XRC))
+ gen = &dev->mdev->caps.gen;
+ if (!(gen->flags & MLX5_DEV_CAP_FLAG_XRC))
return ERR_PTR(-ENOSYS);
xrcd = kmalloc(sizeof(*xrcd), GFP_KERNEL);
diff --git a/drivers/infiniband/hw/mlx5/srq.c b/drivers/infiniband/hw/mlx5/srq.c
index 70bd131ba646..97cc1baaa8e3 100644
--- a/drivers/infiniband/hw/mlx5/srq.c
+++ b/drivers/infiniband/hw/mlx5/srq.c
@@ -238,6 +238,7 @@ struct ib_srq *mlx5_ib_create_srq(struct ib_pd *pd,
struct ib_udata *udata)
{
struct mlx5_ib_dev *dev = to_mdev(pd->device);
+ struct mlx5_general_caps *gen;
struct mlx5_ib_srq *srq;
int desc_size;
int buf_size;
@@ -247,11 +248,12 @@ struct ib_srq *mlx5_ib_create_srq(struct ib_pd *pd,
int is_xrc;
u32 flgs, xrcdn;
+ gen = &dev->mdev->caps.gen;
/* Sanity check SRQ size before proceeding */
- if (init_attr->attr.max_wr >= dev->mdev->caps.max_srq_wqes) {
+ if (init_attr->attr.max_wr >= gen->max_srq_wqes) {
mlx5_ib_dbg(dev, "max_wr %d, cap %d\n",
init_attr->attr.max_wr,
- dev->mdev->caps.max_srq_wqes);
+ gen->max_srq_wqes);
return ERR_PTR(-EINVAL);
}
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/cmd.c b/drivers/net/ethernet/mellanox/mlx5/core/cmd.c
index 65a7da69e2ac..6eb0f85cf872 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/cmd.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/cmd.c
@@ -1538,16 +1538,9 @@ static const char *cmd_status_str(u8 status)
}
}
-int mlx5_cmd_status_to_err(struct mlx5_outbox_hdr *hdr)
+static int cmd_status_to_err(u8 status)
{
- if (!hdr->status)
- return 0;
-
- pr_warn("command failed, status %s(0x%x), syndrome 0x%x\n",
- cmd_status_str(hdr->status), hdr->status,
- be32_to_cpu(hdr->syndrome));
-
- switch (hdr->status) {
+ switch (status) {
case MLX5_CMD_STAT_OK: return 0;
case MLX5_CMD_STAT_INT_ERR: return -EIO;
case MLX5_CMD_STAT_BAD_OP_ERR: return -EINVAL;
@@ -1567,3 +1560,16 @@ int mlx5_cmd_status_to_err(struct mlx5_outbox_hdr *hdr)
default: return -EIO;
}
}
+
+/* this will be available till all the commands use set/get macros */
+int mlx5_cmd_status_to_err(struct mlx5_outbox_hdr *hdr)
+{
+ if (!hdr->status)
+ return 0;
+
+ pr_warn("command failed, status %s(0x%x), syndrome 0x%x\n",
+ cmd_status_str(hdr->status), hdr->status,
+ be32_to_cpu(hdr->syndrome));
+
+ return cmd_status_to_err(hdr->status);
+}
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eq.c b/drivers/net/ethernet/mellanox/mlx5/core/eq.c
index 4e8bd0b34bb0..11b9b840ad4d 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/eq.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/eq.c
@@ -468,7 +468,7 @@ int mlx5_start_eqs(struct mlx5_core_dev *dev)
err = mlx5_create_map_eq(dev, &table->pages_eq,
MLX5_EQ_VEC_PAGES,
- dev->caps.max_vf + 1,
+ dev->caps.gen.max_vf + 1,
1 << MLX5_EVENT_TYPE_PAGE_REQUEST, "mlx5_pages_eq",
&dev->priv.uuari.uars[0]);
if (err) {
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fw.c b/drivers/net/ethernet/mellanox/mlx5/core/fw.c
index f012658b6a92..087c4c797deb 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/fw.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/fw.c
@@ -64,86 +64,9 @@ out_out:
return err;
}
-int mlx5_cmd_query_hca_cap(struct mlx5_core_dev *dev,
- struct mlx5_caps *caps)
+int mlx5_cmd_query_hca_cap(struct mlx5_core_dev *dev, struct mlx5_caps *caps)
{
- struct mlx5_cmd_query_hca_cap_mbox_out *out;
- struct mlx5_cmd_query_hca_cap_mbox_in in;
- struct mlx5_query_special_ctxs_mbox_out ctx_out;
- struct mlx5_query_special_ctxs_mbox_in ctx_in;
- int err;
- u16 t16;
-
- out = kzalloc(sizeof(*out), GFP_KERNEL);
- if (!out)
- return -ENOMEM;
-
- memset(&in, 0, sizeof(in));
- in.hdr.opcode = cpu_to_be16(MLX5_CMD_OP_QUERY_HCA_CAP);
- in.hdr.opmod = cpu_to_be16(0x1);
- err = mlx5_cmd_exec(dev, &in, sizeof(in), out, sizeof(*out));
- if (err)
- goto out_out;
-
- if (out->hdr.status) {
- err = mlx5_cmd_status_to_err(&out->hdr);
- goto out_out;
- }
-
-
- caps->log_max_eq = out->hca_cap.log_max_eq & 0xf;
- caps->max_cqes = 1 << out->hca_cap.log_max_cq_sz;
- caps->max_wqes = 1 << out->hca_cap.log_max_qp_sz;
- caps->max_sq_desc_sz = be16_to_cpu(out->hca_cap.max_desc_sz_sq);
- caps->max_rq_desc_sz = be16_to_cpu(out->hca_cap.max_desc_sz_rq);
- caps->flags = be64_to_cpu(out->hca_cap.flags);
- caps->stat_rate_support = be16_to_cpu(out->hca_cap.stat_rate_support);
- caps->log_max_msg = out->hca_cap.log_max_msg & 0x1f;
- caps->num_ports = out->hca_cap.num_ports & 0xf;
- caps->log_max_cq = out->hca_cap.log_max_cq & 0x1f;
- if (caps->num_ports > MLX5_MAX_PORTS) {
- mlx5_core_err(dev, "device has %d ports while the driver supports max %d ports\n",
- caps->num_ports, MLX5_MAX_PORTS);
- err = -EINVAL;
- goto out_out;
- }
- caps->log_max_qp = out->hca_cap.log_max_qp & 0x1f;
- caps->log_max_mkey = out->hca_cap.log_max_mkey & 0x3f;
- caps->log_max_pd = out->hca_cap.log_max_pd & 0x1f;
- caps->log_max_srq = out->hca_cap.log_max_srqs & 0x1f;
- caps->local_ca_ack_delay = out->hca_cap.local_ca_ack_delay & 0x1f;
- caps->log_max_mcg = out->hca_cap.log_max_mcg;
- caps->max_qp_mcg = be32_to_cpu(out->hca_cap.max_qp_mcg) & 0xffffff;
- caps->max_ra_res_qp = 1 << (out->hca_cap.log_max_ra_res_qp & 0x3f);
- caps->max_ra_req_qp = 1 << (out->hca_cap.log_max_ra_req_qp & 0x3f);
- caps->max_srq_wqes = 1 << out->hca_cap.log_max_srq_sz;
- t16 = be16_to_cpu(out->hca_cap.bf_log_bf_reg_size);
- if (t16 & 0x8000) {
- caps->bf_reg_size = 1 << (t16 & 0x1f);
- caps->bf_regs_per_page = MLX5_BF_REGS_PER_PAGE;
- } else {
- caps->bf_reg_size = 0;
- caps->bf_regs_per_page = 0;
- }
- caps->min_page_sz = ~(u32)((1 << out->hca_cap.log_pg_sz) - 1);
-
- memset(&ctx_in, 0, sizeof(ctx_in));
- memset(&ctx_out, 0, sizeof(ctx_out));
- ctx_in.hdr.opcode = cpu_to_be16(MLX5_CMD_OP_QUERY_SPECIAL_CONTEXTS);
- err = mlx5_cmd_exec(dev, &ctx_in, sizeof(ctx_in),
- &ctx_out, sizeof(ctx_out));
- if (err)
- goto out_out;
-
- if (ctx_out.hdr.status)
- err = mlx5_cmd_status_to_err(&ctx_out.hdr);
-
- caps->reserved_lkey = be32_to_cpu(ctx_out.reserved_lkey);
-
-out_out:
- kfree(out);
-
- return err;
+ return mlx5_core_get_caps(dev, caps, HCA_CAP_OPMOD_GET_CUR);
}
int mlx5_cmd_init_hca(struct mlx5_core_dev *dev)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c
index f2716cc1f51d..d9f74618befa 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/main.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c
@@ -207,11 +207,11 @@ static void release_bar(struct pci_dev *pdev)
static int mlx5_enable_msix(struct mlx5_core_dev *dev)
{
struct mlx5_eq_table *table = &dev->priv.eq_table;
- int num_eqs = 1 << dev->caps.log_max_eq;
+ int num_eqs = 1 << dev->caps.gen.log_max_eq;
int nvec;
int i;
- nvec = dev->caps.num_ports * num_online_cpus() + MLX5_EQ_VEC_COMP_BASE;
+ nvec = dev->caps.gen.num_ports * num_online_cpus() + MLX5_EQ_VEC_COMP_BASE;
nvec = min_t(int, nvec, num_eqs);
if (nvec <= MLX5_EQ_VEC_COMP_BASE)
return -ENOMEM;
@@ -250,13 +250,34 @@ struct mlx5_reg_host_endianess {
#define CAP_MASK(pos, size) ((u64)((1 << (size)) - 1) << (pos))
enum {
- MLX5_CAP_BITS_RW_MASK = CAP_MASK(MLX5_CAP_OFF_CMDIF_CSUM, 2) |
- CAP_MASK(MLX5_CAP_OFF_DCT, 1),
+ MLX5_CAP_BITS_RW_MASK = CAP_MASK(MLX5_CAP_OFF_CMDIF_CSUM, 2) |
+ MLX5_DEV_CAP_FLAG_DCT,
};
+static u16 to_fw_pkey_sz(u32 size)
+{
+ switch (size) {
+ case 128:
+ return 0;
+ case 256:
+ return 1;
+ case 512:
+ return 2;
+ case 1024:
+ return 3;
+ case 2048:
+ return 4;
+ case 4096:
+ return 5;
+ default:
+ pr_warn("invalid pkey table size %d\n", size);
+ return 0;
+ }
+}
+
/* selectively copy writable fields clearing any reserved area
*/
-static void copy_rw_fields(struct mlx5_hca_cap *to, struct mlx5_hca_cap *from)
+static void copy_rw_fields(struct mlx5_hca_cap *to, struct mlx5_general_caps *from)
{
u64 v64;
@@ -265,76 +286,172 @@ static void copy_rw_fields(struct mlx5_hca_cap *to, struct mlx5_hca_cap *from)
to->log_max_ra_res_dc = from->log_max_ra_res_dc & 0x3f;
to->log_max_ra_req_qp = from->log_max_ra_req_qp & 0x3f;
to->log_max_ra_res_qp = from->log_max_ra_res_qp & 0x3f;
- to->log_max_atomic_size_qp = from->log_max_atomic_size_qp;
- to->log_max_atomic_size_dc = from->log_max_atomic_size_dc;
- v64 = be64_to_cpu(from->flags) & MLX5_CAP_BITS_RW_MASK;
+ to->pkey_table_size = cpu_to_be16(to_fw_pkey_sz(from->pkey_table_size));
+ v64 = from->flags & MLX5_CAP_BITS_RW_MASK;
to->flags = cpu_to_be64(v64);
}
-enum {
- HCA_CAP_OPMOD_GET_MAX = 0,
- HCA_CAP_OPMOD_GET_CUR = 1,
-};
+static u16 get_pkey_table_size(int pkey)
+{
+ if (pkey > MLX5_MAX_LOG_PKEY_TABLE)
+ return 0;
-static int handle_hca_cap(struct mlx5_core_dev *dev)
+ return MLX5_MIN_PKEY_TABLE_SIZE << pkey;
+}
+
+static void fw2drv_caps(struct mlx5_caps *caps,
+ struct mlx5_cmd_query_hca_cap_mbox_out *out)
{
- struct mlx5_cmd_query_hca_cap_mbox_out *query_out = NULL;
- struct mlx5_cmd_set_hca_cap_mbox_in *set_ctx = NULL;
- struct mlx5_cmd_query_hca_cap_mbox_in query_ctx;
- struct mlx5_cmd_set_hca_cap_mbox_out set_out;
- u64 flags;
+ struct mlx5_general_caps *gen = &caps->gen;
+ u16 t16;
+
+ gen->max_srq_wqes = 1 << out->hca_cap.log_max_srq_sz;
+ gen->max_wqes = 1 << out->hca_cap.log_max_qp_sz;
+ gen->log_max_qp = out->hca_cap.log_max_qp & 0x1f;
+ gen->log_max_strq = out->hca_cap.log_max_strq_sz;
+ gen->log_max_srq = out->hca_cap.log_max_srqs & 0x1f;
+ gen->max_cqes = 1 << out->hca_cap.log_max_cq_sz;
+ gen->log_max_cq = out->hca_cap.log_max_cq & 0x1f;
+ gen->max_eqes = out->hca_cap.log_max_eq_sz;
+ gen->log_max_mkey = out->hca_cap.log_max_mkey & 0x3f;
+ gen->log_max_eq = out->hca_cap.log_max_eq & 0xf;
+ gen->max_indirection = out->hca_cap.max_indirection;
+ gen->log_max_mrw_sz = out->hca_cap.log_max_mrw_sz;
+ gen->log_max_bsf_list_size = 0;
+ gen->log_max_klm_list_size = 0;
+ gen->log_max_ra_req_dc = out->hca_cap.log_max_ra_req_dc;
+ gen->log_max_ra_res_dc = out->hca_cap.log_max_ra_res_dc;
+ gen->log_max_ra_req_qp = out->hca_cap.log_max_ra_req_qp;
+ gen->log_max_ra_res_qp = out->hca_cap.log_max_ra_res_qp;
+ gen->max_qp_counters = be16_to_cpu(out->hca_cap.max_qp_count);
+ gen->pkey_table_size = get_pkey_table_size(be16_to_cpu(out->hca_cap.pkey_table_size));
+ gen->local_ca_ack_delay = out->hca_cap.local_ca_ack_delay & 0x1f;
+ gen->num_ports = out->hca_cap.num_ports & 0xf;
+ gen->log_max_msg = out->hca_cap.log_max_msg & 0x1f;
+ gen->stat_rate_support = be16_to_cpu(out->hca_cap.stat_rate_support);
+ gen->flags = be64_to_cpu(out->hca_cap.flags);
+ pr_debug("flags = 0x%llx\n", gen->flags);
+ gen->uar_sz = out->hca_cap.uar_sz;
+ gen->min_log_pg_sz = out->hca_cap.log_pg_sz;
+
+ t16 = be16_to_cpu(out->hca_cap.bf_log_bf_reg_size);
+ if (t16 & 0x8000) {
+ gen->bf_reg_size = 1 << (t16 & 0x1f);
+ gen->bf_regs_per_page = MLX5_BF_REGS_PER_PAGE;
+ } else {
+ gen->bf_reg_size = 0;
+ gen->bf_regs_per_page = 0;
+ }
+ gen->max_sq_desc_sz = be16_to_cpu(out->hca_cap.max_desc_sz_sq);
+ gen->max_rq_desc_sz = be16_to_cpu(out->hca_cap.max_desc_sz_rq);
+ gen->max_qp_mcg = be32_to_cpu(out->hca_cap.max_qp_mcg) & 0xffffff;
+ gen->log_max_pd = out->hca_cap.log_max_pd & 0x1f;
+ gen->log_max_xrcd = out->hca_cap.log_max_xrcd;
+ gen->log_uar_page_sz = be16_to_cpu(out->hca_cap.log_uar_page_sz);
+}
+
+static const char *caps_opmod_str(u16 opmod)
+{
+ switch (opmod) {
+ case HCA_CAP_OPMOD_GET_MAX:
+ return "GET_MAX";
+ case HCA_CAP_OPMOD_GET_CUR:
+ return "GET_CUR";
+ default:
+ return "Invalid";
+ }
+}
+
+int mlx5_core_get_caps(struct mlx5_core_dev *dev, struct mlx5_caps *caps,
+ u16 opmod)
+{
+ struct mlx5_cmd_query_hca_cap_mbox_out *out;
+ struct mlx5_cmd_query_hca_cap_mbox_in in;
int err;
- memset(&query_ctx, 0, sizeof(query_ctx));
- query_out = kzalloc(sizeof(*query_out), GFP_KERNEL);
- if (!query_out)
+ memset(&in, 0, sizeof(in));
+ out = kzalloc(sizeof(*out), GFP_KERNEL);
+ if (!out)
return -ENOMEM;
- set_ctx = kzalloc(sizeof(*set_ctx), GFP_KERNEL);
- if (!set_ctx) {
- err = -ENOMEM;
+ in.hdr.opcode = cpu_to_be16(MLX5_CMD_OP_QUERY_HCA_CAP);
+ in.hdr.opmod = cpu_to_be16(opmod);
+ err = mlx5_cmd_exec(dev, &in, sizeof(in), out, sizeof(*out));
+
+ err = mlx5_cmd_status_to_err(&out->hdr);
+ if (err) {
+ mlx5_core_warn(dev, "query max hca cap failed, %d\n", err);
goto query_ex;
}
+ mlx5_core_dbg(dev, "%s\n", caps_opmod_str(opmod));
+ fw2drv_caps(caps, out);
- query_ctx.hdr.opcode = cpu_to_be16(MLX5_CMD_OP_QUERY_HCA_CAP);
- query_ctx.hdr.opmod = cpu_to_be16(HCA_CAP_OPMOD_GET_CUR);
- err = mlx5_cmd_exec(dev, &query_ctx, sizeof(query_ctx),
- query_out, sizeof(*query_out));
+query_ex:
+ kfree(out);
+ return err;
+}
+
+static int set_caps(struct mlx5_core_dev *dev,
+ struct mlx5_cmd_set_hca_cap_mbox_in *in)
+{
+ struct mlx5_cmd_set_hca_cap_mbox_out out;
+ int err;
+
+ memset(&out, 0, sizeof(out));
+
+ in->hdr.opcode = cpu_to_be16(MLX5_CMD_OP_SET_HCA_CAP);
+ err = mlx5_cmd_exec(dev, in, sizeof(*in), &out, sizeof(out));
if (err)
- goto query_ex;
+ return err;
- err = mlx5_cmd_status_to_err(&query_out->hdr);
- if (err) {
- mlx5_core_warn(dev, "query hca cap failed, %d\n", err);
+ err = mlx5_cmd_status_to_err(&out.hdr);
+
+ return err;
+}
+
+static int handle_hca_cap(struct mlx5_core_dev *dev)
+{
+ struct mlx5_cmd_set_hca_cap_mbox_in *set_ctx = NULL;
+ struct mlx5_profile *prof = dev->profile;
+ struct mlx5_caps *cur_caps = NULL;
+ struct mlx5_caps *max_caps = NULL;
+ int err = -ENOMEM;
+
+ set_ctx = kzalloc(sizeof(*set_ctx), GFP_KERNEL);
+ if (!set_ctx)
goto query_ex;
- }
- copy_rw_fields(&set_ctx->hca_cap, &query_out->hca_cap);
+ max_caps = kzalloc(sizeof(*max_caps), GFP_KERNEL);
+ if (!max_caps)
+ goto query_ex;
- if (dev->profile && dev->profile->mask & MLX5_PROF_MASK_QP_SIZE)
- set_ctx->hca_cap.log_max_qp = dev->profile->log_max_qp;
+ cur_caps = kzalloc(sizeof(*cur_caps), GFP_KERNEL);
+ if (!cur_caps)
+ goto query_ex;
- flags = be64_to_cpu(query_out->hca_cap.flags);
- /* disable checksum */
- flags &= ~MLX5_DEV_CAP_FLAG_CMDIF_CSUM;
-
- set_ctx->hca_cap.flags = cpu_to_be64(flags);
- memset(&set_out, 0, sizeof(set_out));
- set_ctx->hca_cap.log_uar_page_sz = cpu_to_be16(PAGE_SHIFT - 12);
- set_ctx->hdr.opcode = cpu_to_be16(MLX5_CMD_OP_SET_HCA_CAP);
- err = mlx5_cmd_exec(dev, set_ctx, sizeof(*set_ctx),
- &set_out, sizeof(set_out));
- if (err) {
- mlx5_core_warn(dev, "set hca cap failed, %d\n", err);
+ err = mlx5_core_get_caps(dev, max_caps, HCA_CAP_OPMOD_GET_MAX);
+ if (err)
goto query_ex;
- }
- err = mlx5_cmd_status_to_err(&set_out.hdr);
+ err = mlx5_core_get_caps(dev, cur_caps, HCA_CAP_OPMOD_GET_CUR);
if (err)
goto query_ex;
+ /* we limit the size of the pkey table to 128 entries for now */
+ cur_caps->gen.pkey_table_size = 128;
+
+ if (prof->mask & MLX5_PROF_MASK_QP_SIZE)
+ cur_caps->gen.log_max_qp = prof->log_max_qp;
+
+ /* disable checksum */
+ cur_caps->gen.flags &= ~MLX5_DEV_CAP_FLAG_CMDIF_CSUM;
+
+ copy_rw_fields(&set_ctx->hca_cap, &cur_caps->gen);
+ err = set_caps(dev, set_ctx);
+
query_ex:
- kfree(query_out);
+ kfree(cur_caps);
+ kfree(max_caps);
kfree(set_ctx);
return err;
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/uar.c b/drivers/net/ethernet/mellanox/mlx5/core/uar.c
index 68f5d9c77c7b..0a6348cefc01 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/uar.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/uar.c
@@ -174,11 +174,11 @@ int mlx5_alloc_uuars(struct mlx5_core_dev *dev, struct mlx5_uuar_info *uuari)
for (i = 0; i < tot_uuars; i++) {
bf = &uuari->bfs[i];
- bf->buf_size = dev->caps.bf_reg_size / 2;
+ bf->buf_size = dev->caps.gen.bf_reg_size / 2;
bf->uar = &uuari->uars[i / MLX5_BF_REGS_PER_PAGE];
bf->regreg = uuari->uars[i / MLX5_BF_REGS_PER_PAGE].map;
bf->reg = NULL; /* Add WC support */
- bf->offset = (i % MLX5_BF_REGS_PER_PAGE) * dev->caps.bf_reg_size +
+ bf->offset = (i % MLX5_BF_REGS_PER_PAGE) * dev->caps.gen.bf_reg_size +
MLX5_BF_OFFSET;
bf->need_lock = need_uuar_lock(i);
spin_lock_init(&bf->lock);
diff --git a/include/linux/mlx5/device.h b/include/linux/mlx5/device.h
index 334947151dfc..dce01fd854a8 100644
--- a/include/linux/mlx5/device.h
+++ b/include/linux/mlx5/device.h
@@ -71,6 +71,11 @@ enum {
};
enum {
+ MLX5_MIN_PKEY_TABLE_SIZE = 128,
+ MLX5_MAX_LOG_PKEY_TABLE = 5,
+};
+
+enum {
MLX5_PERM_LOCAL_READ = 1 << 2,
MLX5_PERM_LOCAL_WRITE = 1 << 3,
MLX5_PERM_REMOTE_READ = 1 << 4,
@@ -184,10 +189,10 @@ enum {
MLX5_DEV_CAP_FLAG_CQ_MODER = 1LL << 29,
MLX5_DEV_CAP_FLAG_RESIZE_CQ = 1LL << 30,
MLX5_DEV_CAP_FLAG_RESIZE_SRQ = 1LL << 32,
+ MLX5_DEV_CAP_FLAG_DCT = 1LL << 37,
MLX5_DEV_CAP_FLAG_REMOTE_FENCE = 1LL << 38,
MLX5_DEV_CAP_FLAG_TLP_HINTS = 1LL << 39,
MLX5_DEV_CAP_FLAG_SIG_HAND_OVER = 1LL << 40,
- MLX5_DEV_CAP_FLAG_DCT = 1LL << 41,
MLX5_DEV_CAP_FLAG_CMDIF_CSUM = 3LL << 46,
};
@@ -243,10 +248,14 @@ enum {
};
enum {
- MLX5_CAP_OFF_DCT = 41,
MLX5_CAP_OFF_CMDIF_CSUM = 46,
};
+enum {
+ HCA_CAP_OPMOD_GET_MAX = 0,
+ HCA_CAP_OPMOD_GET_CUR = 1,
+};
+
struct mlx5_inbox_hdr {
__be16 opcode;
u8 rsvd[4];
@@ -303,9 +312,10 @@ struct mlx5_hca_cap {
u8 log_max_ra_req_qp;
u8 rsvd10;
u8 log_max_ra_res_qp;
- u8 rsvd11[4];
+ u8 pad_cap;
+ u8 rsvd11[3];
__be16 max_qp_count;
- __be16 rsvd12;
+ __be16 pkey_table_size;
u8 rsvd13;
u8 local_ca_ack_delay;
u8 rsvd14;
@@ -335,11 +345,7 @@ struct mlx5_hca_cap {
u8 log_max_xrcd;
u8 rsvd25[42];
__be16 log_uar_page_sz;
- u8 rsvd26[28];
- u8 log_max_atomic_size_qp;
- u8 rsvd27[2];
- u8 log_max_atomic_size_dc;
- u8 rsvd28[76];
+ u8 rsvd26[108];
};
diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h
index b88e9b46d957..45a2add747e0 100644
--- a/include/linux/mlx5/driver.h
+++ b/include/linux/mlx5/driver.h
@@ -335,23 +335,30 @@ struct mlx5_port_caps {
int pkey_table_len;
};
-struct mlx5_caps {
+struct mlx5_general_caps {
u8 log_max_eq;
u8 log_max_cq;
u8 log_max_qp;
u8 log_max_mkey;
u8 log_max_pd;
u8 log_max_srq;
+ u8 log_max_strq;
+ u8 log_max_mrw_sz;
+ u8 log_max_bsf_list_size;
+ u8 log_max_klm_list_size;
u32 max_cqes;
int max_wqes;
+ u32 max_eqes;
+ u32 max_indirection;
int max_sq_desc_sz;
int max_rq_desc_sz;
+ int max_dc_sq_desc_sz;
u64 flags;
u16 stat_rate_support;
int log_max_msg;
int num_ports;
- int max_ra_res_qp;
- int max_ra_req_qp;
+ u8 log_max_ra_res_qp;
+ u8 log_max_ra_req_qp;
int max_srq_wqes;
int bf_reg_size;
int bf_regs_per_page;
@@ -363,6 +370,19 @@ struct mlx5_caps {
u8 log_max_mcg;
u32 max_qp_mcg;
int min_page_sz;
+ int pd_cap;
+ u32 max_qp_counters;
+ u32 pkey_table_size;
+ u8 log_max_ra_req_dc;
+ u8 log_max_ra_res_dc;
+ u32 uar_sz;
+ u8 min_log_pg_sz;
+ u8 log_max_xrcd;
+ u16 log_uar_page_sz;
+};
+
+struct mlx5_caps {
+ struct mlx5_general_caps gen;
};
struct mlx5_cmd_mailbox {
@@ -695,6 +715,8 @@ void mlx5_cmd_cleanup(struct mlx5_core_dev *dev);
void mlx5_cmd_use_events(struct mlx5_core_dev *dev);
void mlx5_cmd_use_polling(struct mlx5_core_dev *dev);
int mlx5_cmd_status_to_err(struct mlx5_outbox_hdr *hdr);
+int mlx5_core_get_caps(struct mlx5_core_dev *dev, struct mlx5_caps *caps,
+ u16 opmod);
int mlx5_cmd_exec(struct mlx5_core_dev *dev, void *in, int in_size, void *out,
int out_size);
int mlx5_cmd_exec_cb(struct mlx5_core_dev *dev, void *in, int in_size,
--
2.1.1
^ permalink raw reply related
* [PATCH V1 net-next 3/4] net/mlx5_core: use set/get macros in device caps
From: Eli Cohen @ 2014-10-01 13:18 UTC (permalink / raw)
To: davem; +Cc: netdev, ogerlitz, yevgenyp, Eli Cohen
In-Reply-To: <1412169488-17500-1-git-send-email-eli@mellanox.com>
Transform device capabilities related commands to use set/get macros to
manipulate command mailboxes.
Change-Id: Ia643ad33c9ec4df648dd9eeb0130764fca45b164
Signed-off-by: Eli Cohen <eli@mellanox.com>
---
drivers/net/ethernet/mellanox/mlx5/core/cmd.c | 17 ++
drivers/net/ethernet/mellanox/mlx5/core/main.c | 150 +++++++++---------
include/linux/mlx5/device.h | 92 -----------
include/linux/mlx5/driver.h | 1 +
include/linux/mlx5/mlx5_ifc.h | 206 +++++++++++++++++++++++++
5 files changed, 298 insertions(+), 168 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/cmd.c b/drivers/net/ethernet/mellanox/mlx5/core/cmd.c
index 3ecef1310bae..368c6c5ea014 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/cmd.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/cmd.c
@@ -1537,3 +1537,20 @@ int mlx5_cmd_status_to_err(struct mlx5_outbox_hdr *hdr)
return cmd_status_to_err(hdr->status);
}
+
+int mlx5_cmd_status_to_err_v2(void *ptr)
+{
+ u32 syndrome;
+ u8 status;
+
+ status = be32_to_cpu(*(__be32 *)ptr) >> 24;
+ if (!status)
+ return 0;
+
+ syndrome = be32_to_cpu(*(__be32 *)(ptr + 4));
+
+ pr_warn("command failed, status %s(0x%x), syndrome 0x%x\n",
+ cmd_status_str(status), status, syndrome);
+
+ return cmd_status_to_err(status);
+}
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c
index d9f74618befa..b9e3259e415f 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/main.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c
@@ -43,6 +43,7 @@
#include <linux/mlx5/qp.h>
#include <linux/mlx5/srq.h>
#include <linux/debugfs.h>
+#include <linux/mlx5/mlx5_ifc.h>
#include "mlx5_core.h"
#define DRIVER_NAME "mlx5_core"
@@ -277,18 +278,20 @@ static u16 to_fw_pkey_sz(u32 size)
/* selectively copy writable fields clearing any reserved area
*/
-static void copy_rw_fields(struct mlx5_hca_cap *to, struct mlx5_general_caps *from)
+static void copy_rw_fields(void *to, struct mlx5_caps *from)
{
+ __be64 *flags_off = (__be64 *)MLX5_ADDR_OF(cmd_hca_cap, to, reserved_22);
u64 v64;
- to->log_max_qp = from->log_max_qp & 0x1f;
- to->log_max_ra_req_dc = from->log_max_ra_req_dc & 0x3f;
- to->log_max_ra_res_dc = from->log_max_ra_res_dc & 0x3f;
- to->log_max_ra_req_qp = from->log_max_ra_req_qp & 0x3f;
- to->log_max_ra_res_qp = from->log_max_ra_res_qp & 0x3f;
- to->pkey_table_size = cpu_to_be16(to_fw_pkey_sz(from->pkey_table_size));
- v64 = from->flags & MLX5_CAP_BITS_RW_MASK;
- to->flags = cpu_to_be64(v64);
+ MLX5_SET(cmd_hca_cap, to, log_max_qp, from->gen.log_max_qp);
+ MLX5_SET(cmd_hca_cap, to, log_max_ra_req_qp, from->gen.log_max_ra_req_qp);
+ MLX5_SET(cmd_hca_cap, to, log_max_ra_res_qp, from->gen.log_max_ra_res_qp);
+ MLX5_SET(cmd_hca_cap, to, pkey_table_size, from->gen.pkey_table_size);
+ MLX5_SET(cmd_hca_cap, to, log_max_ra_req_dc, from->gen.log_max_ra_req_dc);
+ MLX5_SET(cmd_hca_cap, to, log_max_ra_res_dc, from->gen.log_max_ra_res_dc);
+ MLX5_SET(cmd_hca_cap, to, pkey_table_size, to_fw_pkey_sz(from->gen.pkey_table_size));
+ v64 = from->gen.flags & MLX5_CAP_BITS_RW_MASK;
+ *flags_off = cpu_to_be64(v64);
}
static u16 get_pkey_table_size(int pkey)
@@ -299,55 +302,47 @@ static u16 get_pkey_table_size(int pkey)
return MLX5_MIN_PKEY_TABLE_SIZE << pkey;
}
-static void fw2drv_caps(struct mlx5_caps *caps,
- struct mlx5_cmd_query_hca_cap_mbox_out *out)
+static void fw2drv_caps(struct mlx5_caps *caps, void *out)
{
struct mlx5_general_caps *gen = &caps->gen;
- u16 t16;
-
- gen->max_srq_wqes = 1 << out->hca_cap.log_max_srq_sz;
- gen->max_wqes = 1 << out->hca_cap.log_max_qp_sz;
- gen->log_max_qp = out->hca_cap.log_max_qp & 0x1f;
- gen->log_max_strq = out->hca_cap.log_max_strq_sz;
- gen->log_max_srq = out->hca_cap.log_max_srqs & 0x1f;
- gen->max_cqes = 1 << out->hca_cap.log_max_cq_sz;
- gen->log_max_cq = out->hca_cap.log_max_cq & 0x1f;
- gen->max_eqes = out->hca_cap.log_max_eq_sz;
- gen->log_max_mkey = out->hca_cap.log_max_mkey & 0x3f;
- gen->log_max_eq = out->hca_cap.log_max_eq & 0xf;
- gen->max_indirection = out->hca_cap.max_indirection;
- gen->log_max_mrw_sz = out->hca_cap.log_max_mrw_sz;
- gen->log_max_bsf_list_size = 0;
- gen->log_max_klm_list_size = 0;
- gen->log_max_ra_req_dc = out->hca_cap.log_max_ra_req_dc;
- gen->log_max_ra_res_dc = out->hca_cap.log_max_ra_res_dc;
- gen->log_max_ra_req_qp = out->hca_cap.log_max_ra_req_qp;
- gen->log_max_ra_res_qp = out->hca_cap.log_max_ra_res_qp;
- gen->max_qp_counters = be16_to_cpu(out->hca_cap.max_qp_count);
- gen->pkey_table_size = get_pkey_table_size(be16_to_cpu(out->hca_cap.pkey_table_size));
- gen->local_ca_ack_delay = out->hca_cap.local_ca_ack_delay & 0x1f;
- gen->num_ports = out->hca_cap.num_ports & 0xf;
- gen->log_max_msg = out->hca_cap.log_max_msg & 0x1f;
- gen->stat_rate_support = be16_to_cpu(out->hca_cap.stat_rate_support);
- gen->flags = be64_to_cpu(out->hca_cap.flags);
- pr_debug("flags = 0x%llx\n", gen->flags);
- gen->uar_sz = out->hca_cap.uar_sz;
- gen->min_log_pg_sz = out->hca_cap.log_pg_sz;
- t16 = be16_to_cpu(out->hca_cap.bf_log_bf_reg_size);
- if (t16 & 0x8000) {
- gen->bf_reg_size = 1 << (t16 & 0x1f);
- gen->bf_regs_per_page = MLX5_BF_REGS_PER_PAGE;
- } else {
- gen->bf_reg_size = 0;
- gen->bf_regs_per_page = 0;
- }
- gen->max_sq_desc_sz = be16_to_cpu(out->hca_cap.max_desc_sz_sq);
- gen->max_rq_desc_sz = be16_to_cpu(out->hca_cap.max_desc_sz_rq);
- gen->max_qp_mcg = be32_to_cpu(out->hca_cap.max_qp_mcg) & 0xffffff;
- gen->log_max_pd = out->hca_cap.log_max_pd & 0x1f;
- gen->log_max_xrcd = out->hca_cap.log_max_xrcd;
- gen->log_uar_page_sz = be16_to_cpu(out->hca_cap.log_uar_page_sz);
+ gen->max_srq_wqes = 1 << MLX5_GET_PR(cmd_hca_cap, out, log_max_srq_sz);
+ gen->max_wqes = 1 << MLX5_GET_PR(cmd_hca_cap, out, log_max_qp_sz);
+ gen->log_max_qp = MLX5_GET_PR(cmd_hca_cap, out, log_max_qp);
+ gen->log_max_strq = MLX5_GET_PR(cmd_hca_cap, out, log_max_strq_sz);
+ gen->log_max_srq = MLX5_GET_PR(cmd_hca_cap, out, log_max_srqs);
+ gen->max_cqes = 1 << MLX5_GET_PR(cmd_hca_cap, out, log_max_cq_sz);
+ gen->log_max_cq = MLX5_GET_PR(cmd_hca_cap, out, log_max_cq);
+ gen->max_eqes = 1 << MLX5_GET_PR(cmd_hca_cap, out, log_max_eq_sz);
+ gen->log_max_mkey = MLX5_GET_PR(cmd_hca_cap, out, log_max_mkey);
+ gen->log_max_eq = MLX5_GET_PR(cmd_hca_cap, out, log_max_eq);
+ gen->max_indirection = MLX5_GET_PR(cmd_hca_cap, out, max_indirection);
+ gen->log_max_mrw_sz = MLX5_GET_PR(cmd_hca_cap, out, log_max_mrw_sz);
+ gen->log_max_bsf_list_size = MLX5_GET_PR(cmd_hca_cap, out, log_max_bsf_list_size);
+ gen->log_max_klm_list_size = MLX5_GET_PR(cmd_hca_cap, out, log_max_klm_list_size);
+ gen->log_max_ra_req_dc = MLX5_GET_PR(cmd_hca_cap, out, log_max_ra_req_dc);
+ gen->log_max_ra_res_dc = MLX5_GET_PR(cmd_hca_cap, out, log_max_ra_res_dc);
+ gen->log_max_ra_req_qp = MLX5_GET_PR(cmd_hca_cap, out, log_max_ra_req_qp);
+ gen->log_max_ra_res_qp = MLX5_GET_PR(cmd_hca_cap, out, log_max_ra_res_qp);
+ gen->max_qp_counters = MLX5_GET_PR(cmd_hca_cap, out, max_qp_cnt);
+ gen->pkey_table_size = get_pkey_table_size(MLX5_GET_PR(cmd_hca_cap, out, pkey_table_size));
+ gen->local_ca_ack_delay = MLX5_GET_PR(cmd_hca_cap, out, local_ca_ack_delay);
+ gen->num_ports = MLX5_GET_PR(cmd_hca_cap, out, num_ports);
+ gen->log_max_msg = MLX5_GET_PR(cmd_hca_cap, out, log_max_msg);
+ gen->stat_rate_support = MLX5_GET_PR(cmd_hca_cap, out, stat_rate_support);
+ gen->flags = be64_to_cpu(*(__be64 *)MLX5_ADDR_OF(cmd_hca_cap, out, reserved_22));
+ pr_debug("flags = 0x%llx\n", gen->flags);
+ gen->uar_sz = MLX5_GET_PR(cmd_hca_cap, out, uar_sz);
+ gen->min_log_pg_sz = MLX5_GET_PR(cmd_hca_cap, out, log_pg_sz);
+ gen->bf_reg_size = MLX5_GET_PR(cmd_hca_cap, out, bf);
+ gen->bf_reg_size = 1 << MLX5_GET_PR(cmd_hca_cap, out, log_bf_reg_size);
+ gen->max_sq_desc_sz = MLX5_GET_PR(cmd_hca_cap, out, max_wqe_sz_sq);
+ gen->max_rq_desc_sz = MLX5_GET_PR(cmd_hca_cap, out, max_wqe_sz_rq);
+ gen->max_dc_sq_desc_sz = MLX5_GET_PR(cmd_hca_cap, out, max_wqe_sz_sq_dc);
+ gen->max_qp_mcg = MLX5_GET_PR(cmd_hca_cap, out, max_qp_mcg);
+ gen->log_max_pd = MLX5_GET_PR(cmd_hca_cap, out, log_max_pd);
+ gen->log_max_xrcd = MLX5_GET_PR(cmd_hca_cap, out, log_max_xrcd);
+ gen->log_uar_page_sz = MLX5_GET_PR(cmd_hca_cap, out, log_uar_page_sz);
}
static const char *caps_opmod_str(u16 opmod)
@@ -365,59 +360,61 @@ static const char *caps_opmod_str(u16 opmod)
int mlx5_core_get_caps(struct mlx5_core_dev *dev, struct mlx5_caps *caps,
u16 opmod)
{
- struct mlx5_cmd_query_hca_cap_mbox_out *out;
- struct mlx5_cmd_query_hca_cap_mbox_in in;
+ u8 in[MLX5_ST_SZ_BYTES(query_hca_cap_in)];
+ int out_sz = MLX5_ST_SZ_BYTES(query_hca_cap_out);
+ void *out;
int err;
- memset(&in, 0, sizeof(in));
- out = kzalloc(sizeof(*out), GFP_KERNEL);
+ memset(in, 0, sizeof(in));
+ out = kzalloc(out_sz, GFP_KERNEL);
if (!out)
return -ENOMEM;
+ MLX5_SET(query_hca_cap_in, in, opcode, MLX5_CMD_OP_QUERY_HCA_CAP);
+ MLX5_SET(query_hca_cap_in, in, op_mod, opmod);
+ err = mlx5_cmd_exec(dev, in, sizeof(in), out, out_sz);
+ if (err)
+ goto query_ex;
- in.hdr.opcode = cpu_to_be16(MLX5_CMD_OP_QUERY_HCA_CAP);
- in.hdr.opmod = cpu_to_be16(opmod);
- err = mlx5_cmd_exec(dev, &in, sizeof(in), out, sizeof(*out));
-
- err = mlx5_cmd_status_to_err(&out->hdr);
+ err = mlx5_cmd_status_to_err_v2(out);
if (err) {
mlx5_core_warn(dev, "query max hca cap failed, %d\n", err);
goto query_ex;
}
mlx5_core_dbg(dev, "%s\n", caps_opmod_str(opmod));
- fw2drv_caps(caps, out);
+ fw2drv_caps(caps, MLX5_ADDR_OF(query_hca_cap_out, out, capability_struct));
query_ex:
kfree(out);
return err;
}
-static int set_caps(struct mlx5_core_dev *dev,
- struct mlx5_cmd_set_hca_cap_mbox_in *in)
+static int set_caps(struct mlx5_core_dev *dev, void *in, int in_sz)
{
- struct mlx5_cmd_set_hca_cap_mbox_out out;
+ u32 out[MLX5_ST_SZ_DW(set_hca_cap_out)];
int err;
- memset(&out, 0, sizeof(out));
+ memset(out, 0, sizeof(out));
- in->hdr.opcode = cpu_to_be16(MLX5_CMD_OP_SET_HCA_CAP);
- err = mlx5_cmd_exec(dev, in, sizeof(*in), &out, sizeof(out));
+ MLX5_SET(set_hca_cap_in, in, opcode, MLX5_CMD_OP_SET_HCA_CAP);
+ err = mlx5_cmd_exec(dev, in, in_sz, out, sizeof(out));
if (err)
return err;
- err = mlx5_cmd_status_to_err(&out.hdr);
+ err = mlx5_cmd_status_to_err_v2(out);
return err;
}
static int handle_hca_cap(struct mlx5_core_dev *dev)
{
- struct mlx5_cmd_set_hca_cap_mbox_in *set_ctx = NULL;
+ void *set_ctx = NULL;
struct mlx5_profile *prof = dev->profile;
struct mlx5_caps *cur_caps = NULL;
struct mlx5_caps *max_caps = NULL;
int err = -ENOMEM;
+ int set_sz = MLX5_ST_SZ_BYTES(set_hca_cap_in);
- set_ctx = kzalloc(sizeof(*set_ctx), GFP_KERNEL);
+ set_ctx = kzalloc(set_sz, GFP_KERNEL);
if (!set_ctx)
goto query_ex;
@@ -446,8 +443,9 @@ static int handle_hca_cap(struct mlx5_core_dev *dev)
/* disable checksum */
cur_caps->gen.flags &= ~MLX5_DEV_CAP_FLAG_CMDIF_CSUM;
- copy_rw_fields(&set_ctx->hca_cap, &cur_caps->gen);
- err = set_caps(dev, set_ctx);
+ copy_rw_fields(MLX5_ADDR_OF(set_hca_cap_in, set_ctx, hca_capability_struct),
+ cur_caps);
+ err = set_caps(dev, set_ctx, set_sz);
query_ex:
kfree(cur_caps);
diff --git a/include/linux/mlx5/device.h b/include/linux/mlx5/device.h
index 3db2d4d82ad3..08a963c894dc 100644
--- a/include/linux/mlx5/device.h
+++ b/include/linux/mlx5/device.h
@@ -357,98 +357,6 @@ struct mlx5_cmd_query_adapter_mbox_out {
u8 vsd_psid[16];
};
-struct mlx5_hca_cap {
- u8 rsvd1[16];
- u8 log_max_srq_sz;
- u8 log_max_qp_sz;
- u8 rsvd2;
- u8 log_max_qp;
- u8 log_max_strq_sz;
- u8 log_max_srqs;
- u8 rsvd4[2];
- u8 rsvd5;
- u8 log_max_cq_sz;
- u8 rsvd6;
- u8 log_max_cq;
- u8 log_max_eq_sz;
- u8 log_max_mkey;
- u8 rsvd7;
- u8 log_max_eq;
- u8 max_indirection;
- u8 log_max_mrw_sz;
- u8 log_max_bsf_list_sz;
- u8 log_max_klm_list_sz;
- u8 rsvd_8_0;
- u8 log_max_ra_req_dc;
- u8 rsvd_8_1;
- u8 log_max_ra_res_dc;
- u8 rsvd9;
- u8 log_max_ra_req_qp;
- u8 rsvd10;
- u8 log_max_ra_res_qp;
- u8 pad_cap;
- u8 rsvd11[3];
- __be16 max_qp_count;
- __be16 pkey_table_size;
- u8 rsvd13;
- u8 local_ca_ack_delay;
- u8 rsvd14;
- u8 num_ports;
- u8 log_max_msg;
- u8 rsvd15[3];
- __be16 stat_rate_support;
- u8 rsvd16[2];
- __be64 flags;
- u8 rsvd17;
- u8 uar_sz;
- u8 rsvd18;
- u8 log_pg_sz;
- __be16 bf_log_bf_reg_size;
- u8 rsvd19[4];
- __be16 max_desc_sz_sq;
- u8 rsvd20[2];
- __be16 max_desc_sz_rq;
- u8 rsvd21[2];
- __be16 max_desc_sz_sq_dc;
- __be32 max_qp_mcg;
- u8 rsvd22[3];
- u8 log_max_mcg;
- u8 rsvd23;
- u8 log_max_pd;
- u8 rsvd24;
- u8 log_max_xrcd;
- u8 rsvd25[42];
- __be16 log_uar_page_sz;
- u8 rsvd26[108];
-};
-
-
-struct mlx5_cmd_query_hca_cap_mbox_in {
- struct mlx5_inbox_hdr hdr;
- u8 rsvd[8];
-};
-
-
-struct mlx5_cmd_query_hca_cap_mbox_out {
- struct mlx5_outbox_hdr hdr;
- u8 rsvd0[8];
- struct mlx5_hca_cap hca_cap;
-};
-
-
-struct mlx5_cmd_set_hca_cap_mbox_in {
- struct mlx5_inbox_hdr hdr;
- u8 rsvd[8];
- struct mlx5_hca_cap hca_cap;
-};
-
-
-struct mlx5_cmd_set_hca_cap_mbox_out {
- struct mlx5_outbox_hdr hdr;
- u8 rsvd0[8];
-};
-
-
struct mlx5_cmd_init_hca_mbox_in {
struct mlx5_inbox_hdr hdr;
u8 rsvd0[2];
diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h
index 6f48dc793b9f..c439f9c59b93 100644
--- a/include/linux/mlx5/driver.h
+++ b/include/linux/mlx5/driver.h
@@ -641,6 +641,7 @@ void mlx5_cmd_cleanup(struct mlx5_core_dev *dev);
void mlx5_cmd_use_events(struct mlx5_core_dev *dev);
void mlx5_cmd_use_polling(struct mlx5_core_dev *dev);
int mlx5_cmd_status_to_err(struct mlx5_outbox_hdr *hdr);
+int mlx5_cmd_status_to_err_v2(void *ptr);
int mlx5_core_get_caps(struct mlx5_core_dev *dev, struct mlx5_caps *caps,
u16 opmod);
int mlx5_cmd_exec(struct mlx5_core_dev *dev, void *in, int in_size, void *out,
diff --git a/include/linux/mlx5/mlx5_ifc.h b/include/linux/mlx5/mlx5_ifc.h
index df3bd9b5fbcf..5f48b8f592c5 100644
--- a/include/linux/mlx5/mlx5_ifc.h
+++ b/include/linux/mlx5/mlx5_ifc.h
@@ -140,4 +140,210 @@ enum {
MLX5_CMD_OP_MAX = 0x911
};
+struct mlx5_ifc_cmd_hca_cap_bits {
+ u8 reserved_0[0x80];
+
+ u8 log_max_srq_sz[0x8];
+ u8 log_max_qp_sz[0x8];
+ u8 reserved_1[0xb];
+ u8 log_max_qp[0x5];
+
+ u8 log_max_strq_sz[0x8];
+ u8 reserved_2[0x3];
+ u8 log_max_srqs[0x5];
+ u8 reserved_3[0x10];
+
+ u8 reserved_4[0x8];
+ u8 log_max_cq_sz[0x8];
+ u8 reserved_5[0xb];
+ u8 log_max_cq[0x5];
+
+ u8 log_max_eq_sz[0x8];
+ u8 reserved_6[0x2];
+ u8 log_max_mkey[0x6];
+ u8 reserved_7[0xc];
+ u8 log_max_eq[0x4];
+
+ u8 max_indirection[0x8];
+ u8 reserved_8[0x1];
+ u8 log_max_mrw_sz[0x7];
+ u8 reserved_9[0x2];
+ u8 log_max_bsf_list_size[0x6];
+ u8 reserved_10[0x2];
+ u8 log_max_klm_list_size[0x6];
+
+ u8 reserved_11[0xa];
+ u8 log_max_ra_req_dc[0x6];
+ u8 reserved_12[0xa];
+ u8 log_max_ra_res_dc[0x6];
+
+ u8 reserved_13[0xa];
+ u8 log_max_ra_req_qp[0x6];
+ u8 reserved_14[0xa];
+ u8 log_max_ra_res_qp[0x6];
+
+ u8 pad_cap[0x1];
+ u8 cc_query_allowed[0x1];
+ u8 cc_modify_allowed[0x1];
+ u8 reserved_15[0x1d];
+
+ u8 reserved_16[0x6];
+ u8 max_qp_cnt[0xa];
+ u8 pkey_table_size[0x10];
+
+ u8 eswitch_owner[0x1];
+ u8 reserved_17[0xa];
+ u8 local_ca_ack_delay[0x5];
+ u8 reserved_18[0x8];
+ u8 num_ports[0x8];
+
+ u8 reserved_19[0x3];
+ u8 log_max_msg[0x5];
+ u8 reserved_20[0x18];
+
+ u8 stat_rate_support[0x10];
+ u8 reserved_21[0x10];
+
+ u8 reserved_22[0x10];
+ u8 cmdif_checksum[0x2];
+ u8 sigerr_cqe[0x1];
+ u8 reserved_23[0x1];
+ u8 wq_signature[0x1];
+ u8 sctr_data_cqe[0x1];
+ u8 reserved_24[0x1];
+ u8 sho[0x1];
+ u8 tph[0x1];
+ u8 rf[0x1];
+ u8 dc[0x1];
+ u8 reserved_25[0x2];
+ u8 roce[0x1];
+ u8 atomic[0x1];
+ u8 rsz_srq[0x1];
+
+ u8 cq_oi[0x1];
+ u8 cq_resize[0x1];
+ u8 cq_moderation[0x1];
+ u8 sniffer_rule_flow[0x1];
+ u8 sniffer_rule_vport[0x1];
+ u8 sniffer_rule_phy[0x1];
+ u8 reserved_26[0x1];
+ u8 pg[0x1];
+ u8 block_lb_mc[0x1];
+ u8 reserved_27[0x3];
+ u8 cd[0x1];
+ u8 reserved_28[0x1];
+ u8 apm[0x1];
+ u8 reserved_29[0x7];
+ u8 qkv[0x1];
+ u8 pkv[0x1];
+ u8 reserved_30[0x4];
+ u8 xrc[0x1];
+ u8 ud[0x1];
+ u8 uc[0x1];
+ u8 rc[0x1];
+
+ u8 reserved_31[0xa];
+ u8 uar_sz[0x6];
+ u8 reserved_32[0x8];
+ u8 log_pg_sz[0x8];
+
+ u8 bf[0x1];
+ u8 reserved_33[0xa];
+ u8 log_bf_reg_size[0x5];
+ u8 reserved_34[0x10];
+
+ u8 reserved_35[0x10];
+ u8 max_wqe_sz_sq[0x10];
+
+ u8 reserved_36[0x10];
+ u8 max_wqe_sz_rq[0x10];
+
+ u8 reserved_37[0x10];
+ u8 max_wqe_sz_sq_dc[0x10];
+
+ u8 reserved_38[0x7];
+ u8 max_qp_mcg[0x19];
+
+ u8 reserved_39[0x18];
+ u8 log_max_mcg[0x8];
+
+ u8 reserved_40[0xb];
+ u8 log_max_pd[0x5];
+ u8 reserved_41[0xb];
+ u8 log_max_xrcd[0x5];
+
+ u8 reserved_42[0x20];
+
+ u8 reserved_43[0x3];
+ u8 log_max_rq[0x5];
+ u8 reserved_44[0x3];
+ u8 log_max_sq[0x5];
+ u8 reserved_45[0x3];
+ u8 log_max_tir[0x5];
+ u8 reserved_46[0x3];
+ u8 log_max_tis[0x5];
+
+ u8 reserved_47[0x13];
+ u8 log_max_rq_per_tir[0x5];
+ u8 reserved_48[0x3];
+ u8 log_max_tis_per_sq[0x5];
+
+ u8 reserved_49[0xe0];
+
+ u8 reserved_50[0x10];
+ u8 log_uar_page_sz[0x10];
+
+ u8 reserved_51[0x100];
+
+ u8 reserved_52[0x1f];
+ u8 cqe_zip[0x1];
+
+ u8 cqe_zip_timeout[0x10];
+ u8 cqe_zip_max_num[0x10];
+
+ u8 reserved_53[0x220];
+};
+
+struct mlx5_ifc_set_hca_cap_in_bits {
+ u8 opcode[0x10];
+ u8 reserved_0[0x10];
+
+ u8 reserved_1[0x10];
+ u8 op_mod[0x10];
+
+ u8 reserved_2[0x40];
+
+ struct mlx5_ifc_cmd_hca_cap_bits hca_capability_struct;
+};
+
+struct mlx5_ifc_query_hca_cap_in_bits {
+ u8 opcode[0x10];
+ u8 reserved_0[0x10];
+
+ u8 reserved_1[0x10];
+ u8 op_mod[0x10];
+
+ u8 reserved_2[0x40];
+};
+
+struct mlx5_ifc_query_hca_cap_out_bits {
+ u8 status[0x8];
+ u8 reserved_0[0x18];
+
+ u8 syndrome[0x20];
+
+ u8 reserved_1[0x40];
+
+ u8 capability_struct[256][0x8];
+};
+
+struct mlx5_ifc_set_hca_cap_out_bits {
+ u8 status[0x8];
+ u8 reserved_0[0x18];
+
+ u8 syndrome[0x20];
+
+ u8 reserved_1[0x40];
+};
+
#endif /* MLX5_IFC_H */
--
2.1.1
^ permalink raw reply related
* [PATCH V1 net-next 4/4] net/mlx5_core: Identify resources by their type
From: Eli Cohen @ 2014-10-01 13:18 UTC (permalink / raw)
To: davem; +Cc: netdev, ogerlitz, yevgenyp, Eli Cohen
In-Reply-To: <1412169488-17500-1-git-send-email-eli@mellanox.com>
This patch puts a common part as the first field of mlx5_core_qp. This field is
used to identify which resource generated an event. This is required since upcoming
new resource types such as DC targets are allocated for the same numerical space
as regular QPs and may generate the same events. By searching the resource in the
same table we can then look at the common field to identify the resource.
Change-Id: I5b9d0d563f22ba28f284ed6227c4cda36fd7dad3
Signed-off-by: Eli Cohen <eli@mellanox.com>
---
drivers/net/ethernet/mellanox/mlx5/core/eq.c | 12 +++---
drivers/net/ethernet/mellanox/mlx5/core/qp.c | 57 ++++++++++++++++++++--------
include/linux/mlx5/driver.h | 13 ++++++-
include/linux/mlx5/qp.h | 3 +-
4 files changed, 60 insertions(+), 25 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eq.c b/drivers/net/ethernet/mellanox/mlx5/core/eq.c
index 11b9b840ad4d..ed53291468f3 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/eq.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/eq.c
@@ -198,7 +198,7 @@ static int mlx5_eq_int(struct mlx5_core_dev *dev, struct mlx5_eq *eq)
int eqes_found = 0;
int set_ci = 0;
u32 cqn;
- u32 srqn;
+ u32 rsn;
u8 port;
while ((eqe = next_eqe_sw(eq))) {
@@ -224,18 +224,18 @@ static int mlx5_eq_int(struct mlx5_core_dev *dev, struct mlx5_eq *eq)
case MLX5_EVENT_TYPE_PATH_MIG_FAILED:
case MLX5_EVENT_TYPE_WQ_INVAL_REQ_ERROR:
case MLX5_EVENT_TYPE_WQ_ACCESS_ERROR:
+ rsn = be32_to_cpu(eqe->data.qp_srq.qp_srq_n) & 0xffffff;
mlx5_core_dbg(dev, "event %s(%d) arrived\n",
eqe_type_str(eqe->type), eqe->type);
- mlx5_qp_event(dev, be32_to_cpu(eqe->data.qp_srq.qp_srq_n) & 0xffffff,
- eqe->type);
+ mlx5_rsc_event(dev, rsn, eqe->type);
break;
case MLX5_EVENT_TYPE_SRQ_RQ_LIMIT:
case MLX5_EVENT_TYPE_SRQ_CATAS_ERROR:
- srqn = be32_to_cpu(eqe->data.qp_srq.qp_srq_n) & 0xffffff;
+ rsn = be32_to_cpu(eqe->data.qp_srq.qp_srq_n) & 0xffffff;
mlx5_core_dbg(dev, "SRQ event %s(%d): srqn 0x%x\n",
- eqe_type_str(eqe->type), eqe->type, srqn);
- mlx5_srq_event(dev, srqn, eqe->type);
+ eqe_type_str(eqe->type), eqe->type, rsn);
+ mlx5_srq_event(dev, rsn, eqe->type);
break;
case MLX5_EVENT_TYPE_CMD:
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/qp.c b/drivers/net/ethernet/mellanox/mlx5/core/qp.c
index 415b67ce379e..5261a2b0da43 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/qp.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/qp.c
@@ -39,28 +39,53 @@
#include "mlx5_core.h"
-void mlx5_qp_event(struct mlx5_core_dev *dev, u32 qpn, int event_type)
+static struct mlx5_core_rsc_common *mlx5_get_rsc(struct mlx5_core_dev *dev,
+ u32 rsn)
{
struct mlx5_qp_table *table = &dev->priv.qp_table;
- struct mlx5_core_qp *qp;
+ struct mlx5_core_rsc_common *common;
spin_lock(&table->lock);
- qp = radix_tree_lookup(&table->tree, qpn);
- if (qp)
- atomic_inc(&qp->refcount);
+ common = radix_tree_lookup(&table->tree, rsn);
+ if (common)
+ atomic_inc(&common->refcount);
spin_unlock(&table->lock);
- if (!qp) {
- mlx5_core_warn(dev, "Async event for bogus QP 0x%x\n", qpn);
- return;
+ if (!common) {
+ mlx5_core_warn(dev, "Async event for bogus resource 0x%x\n",
+ rsn);
+ return NULL;
}
+ return common;
+}
- qp->event(qp, event_type);
+void mlx5_core_put_rsc(struct mlx5_core_rsc_common *common)
+{
+ if (atomic_dec_and_test(&common->refcount))
+ complete(&common->free);
+}
+
+void mlx5_rsc_event(struct mlx5_core_dev *dev, u32 rsn, int event_type)
+{
+ struct mlx5_core_rsc_common *common = mlx5_get_rsc(dev, rsn);
+ struct mlx5_core_qp *qp;
+
+ if (!common)
+ return;
+
+ switch (common->res) {
+ case MLX5_RES_QP:
+ qp = (struct mlx5_core_qp *)common;
+ qp->event(qp, event_type);
+ break;
+
+ default:
+ mlx5_core_warn(dev, "invalid resource type for 0x%x\n", rsn);
+ }
- if (atomic_dec_and_test(&qp->refcount))
- complete(&qp->free);
+ mlx5_core_put_rsc(common);
}
int mlx5_core_create_qp(struct mlx5_core_dev *dev,
@@ -92,6 +117,7 @@ int mlx5_core_create_qp(struct mlx5_core_dev *dev,
qp->qpn = be32_to_cpu(out.qpn) & 0xffffff;
mlx5_core_dbg(dev, "qpn = 0x%x\n", qp->qpn);
+ qp->common.res = MLX5_RES_QP;
spin_lock_irq(&table->lock);
err = radix_tree_insert(&table->tree, qp->qpn, qp);
spin_unlock_irq(&table->lock);
@@ -106,9 +132,9 @@ int mlx5_core_create_qp(struct mlx5_core_dev *dev,
qp->qpn);
qp->pid = current->pid;
- atomic_set(&qp->refcount, 1);
+ atomic_set(&qp->common.refcount, 1);
atomic_inc(&dev->num_qps);
- init_completion(&qp->free);
+ init_completion(&qp->common.free);
return 0;
@@ -138,9 +164,8 @@ int mlx5_core_destroy_qp(struct mlx5_core_dev *dev,
radix_tree_delete(&table->tree, qp->qpn);
spin_unlock_irqrestore(&table->lock, flags);
- if (atomic_dec_and_test(&qp->refcount))
- complete(&qp->free);
- wait_for_completion(&qp->free);
+ mlx5_core_put_rsc((struct mlx5_core_rsc_common *)qp);
+ wait_for_completion(&qp->common.free);
memset(&in, 0, sizeof(in));
memset(&out, 0, sizeof(out));
diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h
index c439f9c59b93..246310dc8bef 100644
--- a/include/linux/mlx5/driver.h
+++ b/include/linux/mlx5/driver.h
@@ -375,6 +375,16 @@ struct mlx5_core_mr {
u32 pd;
};
+enum mlx5_res_type {
+ MLX5_RES_QP,
+};
+
+struct mlx5_core_rsc_common {
+ enum mlx5_res_type res;
+ atomic_t refcount;
+ struct completion free;
+};
+
struct mlx5_core_srq {
u32 srqn;
int max;
@@ -700,7 +710,7 @@ int mlx5_eq_init(struct mlx5_core_dev *dev);
void mlx5_eq_cleanup(struct mlx5_core_dev *dev);
void mlx5_fill_page_array(struct mlx5_buf *buf, __be64 *pas);
void mlx5_cq_completion(struct mlx5_core_dev *dev, u32 cqn);
-void mlx5_qp_event(struct mlx5_core_dev *dev, u32 qpn, int event_type);
+void mlx5_rsc_event(struct mlx5_core_dev *dev, u32 rsn, int event_type);
void mlx5_srq_event(struct mlx5_core_dev *dev, u32 srqn, int event_type);
struct mlx5_core_srq *mlx5_core_get_srq(struct mlx5_core_dev *dev, u32 srqn);
void mlx5_cmd_comp_handler(struct mlx5_core_dev *dev, unsigned long vector);
@@ -737,6 +747,7 @@ void mlx5_cmdif_debugfs_cleanup(struct mlx5_core_dev *dev);
int mlx5_core_create_psv(struct mlx5_core_dev *dev, u32 pdn,
int npsvs, u32 *sig_index);
int mlx5_core_destroy_psv(struct mlx5_core_dev *dev, int psv_num);
+void mlx5_core_put_rsc(struct mlx5_core_rsc_common *common);
static inline u32 mlx5_mkey_to_idx(u32 mkey)
{
diff --git a/include/linux/mlx5/qp.h b/include/linux/mlx5/qp.h
index 9709b30e2d69..7c4c0f1f5805 100644
--- a/include/linux/mlx5/qp.h
+++ b/include/linux/mlx5/qp.h
@@ -342,10 +342,9 @@ struct mlx5_stride_block_ctrl_seg {
};
struct mlx5_core_qp {
+ struct mlx5_core_rsc_common common; /* must be first */
void (*event) (struct mlx5_core_qp *, int);
int qpn;
- atomic_t refcount;
- struct completion free;
struct mlx5_rsc_debug *dbg;
int pid;
};
--
2.1.1
^ permalink raw reply related
* [PATCH V1 net-next 2/4] net/mlx5_core: Use hardware registers description header file
From: Eli Cohen @ 2014-10-01 13:18 UTC (permalink / raw)
To: davem; +Cc: netdev, ogerlitz, yevgenyp, Eli Cohen
In-Reply-To: <1412169488-17500-1-git-send-email-eli@mellanox.com>
Add an auto generated header file that describes hardware registers along with
set of macros that set/get values. The macros do static checks to avoid
overflow, handle endianess, and overall provide a clean way to code commands.
Currently the header file is small and we will add structs as we make use of
the macros.
A few commands were removed from the commands enum since they are not supported
currently and will be added when support is available.
Change-Id: Ieea94e4b329ec46902b1634cf66b0c3a04445a04
Signed-off-by: Eli Cohen <eli@mellanox.com>
---
drivers/net/ethernet/mellanox/mlx5/core/cmd.c | 36 -------
drivers/net/ethernet/mellanox/mlx5/core/qp.c | 3 -
include/linux/mlx5/device.h | 74 +++++++++++++
include/linux/mlx5/driver.h | 76 +-------------
include/linux/mlx5/mlx5_ifc.h | 143 ++++++++++++++++++++++++++
5 files changed, 218 insertions(+), 114 deletions(-)
create mode 100644 include/linux/mlx5/mlx5_ifc.h
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/cmd.c b/drivers/net/ethernet/mellanox/mlx5/core/cmd.c
index 6eb0f85cf872..3ecef1310bae 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/cmd.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/cmd.c
@@ -357,60 +357,24 @@ const char *mlx5_command_str(int command)
case MLX5_CMD_OP_2ERR_QP:
return "2ERR_QP";
- case MLX5_CMD_OP_RTS2SQD_QP:
- return "RTS2SQD_QP";
-
- case MLX5_CMD_OP_SQD2RTS_QP:
- return "SQD2RTS_QP";
-
case MLX5_CMD_OP_2RST_QP:
return "2RST_QP";
case MLX5_CMD_OP_QUERY_QP:
return "QUERY_QP";
- case MLX5_CMD_OP_CONF_SQP:
- return "CONF_SQP";
-
case MLX5_CMD_OP_MAD_IFC:
return "MAD_IFC";
case MLX5_CMD_OP_INIT2INIT_QP:
return "INIT2INIT_QP";
- case MLX5_CMD_OP_SUSPEND_QP:
- return "SUSPEND_QP";
-
- case MLX5_CMD_OP_UNSUSPEND_QP:
- return "UNSUSPEND_QP";
-
- case MLX5_CMD_OP_SQD2SQD_QP:
- return "SQD2SQD_QP";
-
- case MLX5_CMD_OP_ALLOC_QP_COUNTER_SET:
- return "ALLOC_QP_COUNTER_SET";
-
- case MLX5_CMD_OP_DEALLOC_QP_COUNTER_SET:
- return "DEALLOC_QP_COUNTER_SET";
-
- case MLX5_CMD_OP_QUERY_QP_COUNTER_SET:
- return "QUERY_QP_COUNTER_SET";
-
case MLX5_CMD_OP_CREATE_PSV:
return "CREATE_PSV";
case MLX5_CMD_OP_DESTROY_PSV:
return "DESTROY_PSV";
- case MLX5_CMD_OP_QUERY_PSV:
- return "QUERY_PSV";
-
- case MLX5_CMD_OP_QUERY_SIG_RULE_TABLE:
- return "QUERY_SIG_RULE_TABLE";
-
- case MLX5_CMD_OP_QUERY_BLOCK_SIZE_TABLE:
- return "QUERY_BLOCK_SIZE_TABLE";
-
case MLX5_CMD_OP_CREATE_SRQ:
return "CREATE_SRQ";
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/qp.c b/drivers/net/ethernet/mellanox/mlx5/core/qp.c
index 8145b4668229..415b67ce379e 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/qp.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/qp.c
@@ -184,13 +184,10 @@ int mlx5_core_qp_modify(struct mlx5_core_dev *dev, enum mlx5_qp_state cur_state,
[MLX5_QP_STATE_RST] = MLX5_CMD_OP_2RST_QP,
[MLX5_QP_STATE_ERR] = MLX5_CMD_OP_2ERR_QP,
[MLX5_QP_STATE_RTS] = MLX5_CMD_OP_RTS2RTS_QP,
- [MLX5_QP_STATE_SQD] = MLX5_CMD_OP_RTS2SQD_QP,
},
[MLX5_QP_STATE_SQD] = {
[MLX5_QP_STATE_RST] = MLX5_CMD_OP_2RST_QP,
[MLX5_QP_STATE_ERR] = MLX5_CMD_OP_2ERR_QP,
- [MLX5_QP_STATE_RTS] = MLX5_CMD_OP_SQD2RTS_QP,
- [MLX5_QP_STATE_SQD] = MLX5_CMD_OP_SQD2SQD_QP,
},
[MLX5_QP_STATE_SQER] = {
[MLX5_QP_STATE_RST] = MLX5_CMD_OP_2RST_QP,
diff --git a/include/linux/mlx5/device.h b/include/linux/mlx5/device.h
index dce01fd854a8..3db2d4d82ad3 100644
--- a/include/linux/mlx5/device.h
+++ b/include/linux/mlx5/device.h
@@ -44,6 +44,80 @@
#error Host endianness not defined
#endif
+/* helper macros */
+#define __mlx5_nullp(typ) ((struct mlx5_ifc_##typ##_bits *)0)
+#define __mlx5_bit_sz(typ, fld) sizeof(__mlx5_nullp(typ)->fld)
+#define __mlx5_bit_off(typ, fld) ((unsigned)(unsigned long)(&(__mlx5_nullp(typ)->fld)))
+#define __mlx5_dw_off(typ, fld) (__mlx5_bit_off(typ, fld) / 32)
+#define __mlx5_64_off(typ, fld) (__mlx5_bit_off(typ, fld) / 64)
+#define __mlx5_dw_bit_off(typ, fld) (32 - __mlx5_bit_sz(typ, fld) - (__mlx5_bit_off(typ, fld) & 0x1f))
+#define __mlx5_mask(typ, fld) ((u32)((1ull << __mlx5_bit_sz(typ, fld)) - 1))
+#define __mlx5_dw_mask(typ, fld) (__mlx5_mask(typ, fld) << __mlx5_dw_bit_off(typ, fld))
+#define __mlx5_st_sz_bits(typ) sizeof(struct mlx5_ifc_##typ##_bits)
+
+#define MLX5_FLD_SZ_BYTES(typ, fld) (__mlx5_bit_sz(typ, fld) / 8)
+#define MLX5_ST_SZ_BYTES(typ) (sizeof(struct mlx5_ifc_##typ##_bits) / 8)
+#define MLX5_ST_SZ_DW(typ) (sizeof(struct mlx5_ifc_##typ##_bits) / 32)
+#define MLX5_BYTE_OFF(typ, fld) (__mlx5_bit_off(typ, fld) / 8)
+#define MLX5_ADDR_OF(typ, p, fld) ((char *)(p) + MLX5_BYTE_OFF(typ, fld))
+
+static inline void non_existent_function(void)
+{
+ pr_info("%s\n", __func__);
+}
+
+static inline void non_existent_function_sz_align32(void)
+{
+ pr_info("%s\n", __func__);
+}
+
+static inline void non_existent_function_const_overflow(void)
+{
+ pr_info("%s\n", __func__);
+}
+
+static inline void memcpy_cpu_to_be32(void *dst, void *src, int len)
+{
+ u32 *dst_u32 = (u32 *)dst;
+ int i;
+
+ memcpy(dst, src, len);
+
+ for (i = 0; i < (len >> 2); i++)
+ dst_u32[i] = cpu_to_be32(dst_u32[i]);
+}
+
+/* insert a value to a struct */
+#define MLX5_SET(typ, p, fld, v) do { \
+ if (__mlx5_st_sz_bits(typ) % 32) \
+ non_existent_function_sz_align32(); \
+ *((__be32 *)(p) + __mlx5_dw_off(typ, fld)) = \
+ cpu_to_be32((be32_to_cpu(*((__be32 *)(p) + __mlx5_dw_off(typ, fld))) & \
+ (~__mlx5_dw_mask(typ, fld))) | (((v) & __mlx5_mask(typ, fld)) \
+ << __mlx5_dw_bit_off(typ, fld))); \
+} while (0)
+
+#define MLX5_GET(typ, p, fld) ((be32_to_cpu(*((__be32 *)(p) +\
+__mlx5_dw_off(typ, fld))) >> __mlx5_dw_bit_off(typ, fld)) & \
+__mlx5_mask(typ, fld))
+
+#define MLX5_GET_PR(typ, p, fld) ({ \
+ u32 ___t = MLX5_GET(typ, p, fld); \
+ pr_debug(#fld " = 0x%x\n", ___t); \
+ ___t; \
+})
+
+#define MLX5_SET64(typ, p, fld, v) do { \
+ if (__mlx5_bit_sz(typ, fld) != 64) \
+ non_existent_function(); \
+ else if (__mlx5_bit_off(typ, fld) % 64) \
+ non_existent_function(); \
+ else \
+ *((__be64 *)(p) + __mlx5_64_off(typ, fld)) = cpu_to_be64(v); \
+} while (0)
+
+#define MLX5_GET64(typ, p, fld) be64_to_cpu(*((__be64 *)(p) + __mlx5_64_off(typ, fld)))
+
enum {
MLX5_MAX_COMMANDS = 32,
MLX5_CMD_DATA_BLOCK_SIZE = 512,
diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h
index 45a2add747e0..6f48dc793b9f 100644
--- a/include/linux/mlx5/driver.h
+++ b/include/linux/mlx5/driver.h
@@ -44,6 +44,7 @@
#include <linux/mlx5/device.h>
#include <linux/mlx5/doorbell.h>
+#include <linux/mlx5/mlx5_ifc.h>
enum {
MLX5_BOARD_ID_LEN = 64,
@@ -99,81 +100,6 @@ enum {
};
enum {
- MLX5_CMD_OP_QUERY_HCA_CAP = 0x100,
- MLX5_CMD_OP_QUERY_ADAPTER = 0x101,
- MLX5_CMD_OP_INIT_HCA = 0x102,
- MLX5_CMD_OP_TEARDOWN_HCA = 0x103,
- MLX5_CMD_OP_ENABLE_HCA = 0x104,
- MLX5_CMD_OP_DISABLE_HCA = 0x105,
- MLX5_CMD_OP_QUERY_PAGES = 0x107,
- MLX5_CMD_OP_MANAGE_PAGES = 0x108,
- MLX5_CMD_OP_SET_HCA_CAP = 0x109,
-
- MLX5_CMD_OP_CREATE_MKEY = 0x200,
- MLX5_CMD_OP_QUERY_MKEY = 0x201,
- MLX5_CMD_OP_DESTROY_MKEY = 0x202,
- MLX5_CMD_OP_QUERY_SPECIAL_CONTEXTS = 0x203,
-
- MLX5_CMD_OP_CREATE_EQ = 0x301,
- MLX5_CMD_OP_DESTROY_EQ = 0x302,
- MLX5_CMD_OP_QUERY_EQ = 0x303,
-
- MLX5_CMD_OP_CREATE_CQ = 0x400,
- MLX5_CMD_OP_DESTROY_CQ = 0x401,
- MLX5_CMD_OP_QUERY_CQ = 0x402,
- MLX5_CMD_OP_MODIFY_CQ = 0x403,
-
- MLX5_CMD_OP_CREATE_QP = 0x500,
- MLX5_CMD_OP_DESTROY_QP = 0x501,
- MLX5_CMD_OP_RST2INIT_QP = 0x502,
- MLX5_CMD_OP_INIT2RTR_QP = 0x503,
- MLX5_CMD_OP_RTR2RTS_QP = 0x504,
- MLX5_CMD_OP_RTS2RTS_QP = 0x505,
- MLX5_CMD_OP_SQERR2RTS_QP = 0x506,
- MLX5_CMD_OP_2ERR_QP = 0x507,
- MLX5_CMD_OP_RTS2SQD_QP = 0x508,
- MLX5_CMD_OP_SQD2RTS_QP = 0x509,
- MLX5_CMD_OP_2RST_QP = 0x50a,
- MLX5_CMD_OP_QUERY_QP = 0x50b,
- MLX5_CMD_OP_CONF_SQP = 0x50c,
- MLX5_CMD_OP_MAD_IFC = 0x50d,
- MLX5_CMD_OP_INIT2INIT_QP = 0x50e,
- MLX5_CMD_OP_SUSPEND_QP = 0x50f,
- MLX5_CMD_OP_UNSUSPEND_QP = 0x510,
- MLX5_CMD_OP_SQD2SQD_QP = 0x511,
- MLX5_CMD_OP_ALLOC_QP_COUNTER_SET = 0x512,
- MLX5_CMD_OP_DEALLOC_QP_COUNTER_SET = 0x513,
- MLX5_CMD_OP_QUERY_QP_COUNTER_SET = 0x514,
-
- MLX5_CMD_OP_CREATE_PSV = 0x600,
- MLX5_CMD_OP_DESTROY_PSV = 0x601,
- MLX5_CMD_OP_QUERY_PSV = 0x602,
- MLX5_CMD_OP_QUERY_SIG_RULE_TABLE = 0x603,
- MLX5_CMD_OP_QUERY_BLOCK_SIZE_TABLE = 0x604,
-
- MLX5_CMD_OP_CREATE_SRQ = 0x700,
- MLX5_CMD_OP_DESTROY_SRQ = 0x701,
- MLX5_CMD_OP_QUERY_SRQ = 0x702,
- MLX5_CMD_OP_ARM_RQ = 0x703,
- MLX5_CMD_OP_RESIZE_SRQ = 0x704,
-
- MLX5_CMD_OP_ALLOC_PD = 0x800,
- MLX5_CMD_OP_DEALLOC_PD = 0x801,
- MLX5_CMD_OP_ALLOC_UAR = 0x802,
- MLX5_CMD_OP_DEALLOC_UAR = 0x803,
-
- MLX5_CMD_OP_ATTACH_TO_MCG = 0x806,
- MLX5_CMD_OP_DETACH_FROM_MCG = 0x807,
-
-
- MLX5_CMD_OP_ALLOC_XRCD = 0x80e,
- MLX5_CMD_OP_DEALLOC_XRCD = 0x80f,
-
- MLX5_CMD_OP_ACCESS_REG = 0x805,
- MLX5_CMD_OP_MAX = 0x810,
-};
-
-enum {
MLX5_REG_PCAP = 0x5001,
MLX5_REG_PMTU = 0x5003,
MLX5_REG_PTYS = 0x5004,
diff --git a/include/linux/mlx5/mlx5_ifc.h b/include/linux/mlx5/mlx5_ifc.h
new file mode 100644
index 000000000000..df3bd9b5fbcf
--- /dev/null
+++ b/include/linux/mlx5/mlx5_ifc.h
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 2014, Mellanox Technologies inc. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * - Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef MLX5_IFC_H
+#define MLX5_IFC_H
+
+enum {
+ MLX5_CMD_OP_QUERY_HCA_CAP = 0x100,
+ MLX5_CMD_OP_QUERY_ADAPTER = 0x101,
+ MLX5_CMD_OP_INIT_HCA = 0x102,
+ MLX5_CMD_OP_TEARDOWN_HCA = 0x103,
+ MLX5_CMD_OP_ENABLE_HCA = 0x104,
+ MLX5_CMD_OP_DISABLE_HCA = 0x105,
+ MLX5_CMD_OP_QUERY_PAGES = 0x107,
+ MLX5_CMD_OP_MANAGE_PAGES = 0x108,
+ MLX5_CMD_OP_SET_HCA_CAP = 0x109,
+ MLX5_CMD_OP_CREATE_MKEY = 0x200,
+ MLX5_CMD_OP_QUERY_MKEY = 0x201,
+ MLX5_CMD_OP_DESTROY_MKEY = 0x202,
+ MLX5_CMD_OP_QUERY_SPECIAL_CONTEXTS = 0x203,
+ MLX5_CMD_OP_PAGE_FAULT_RESUME = 0x204,
+ MLX5_CMD_OP_CREATE_EQ = 0x301,
+ MLX5_CMD_OP_DESTROY_EQ = 0x302,
+ MLX5_CMD_OP_QUERY_EQ = 0x303,
+ MLX5_CMD_OP_GEN_EQE = 0x304,
+ MLX5_CMD_OP_CREATE_CQ = 0x400,
+ MLX5_CMD_OP_DESTROY_CQ = 0x401,
+ MLX5_CMD_OP_QUERY_CQ = 0x402,
+ MLX5_CMD_OP_MODIFY_CQ = 0x403,
+ MLX5_CMD_OP_CREATE_QP = 0x500,
+ MLX5_CMD_OP_DESTROY_QP = 0x501,
+ MLX5_CMD_OP_RST2INIT_QP = 0x502,
+ MLX5_CMD_OP_INIT2RTR_QP = 0x503,
+ MLX5_CMD_OP_RTR2RTS_QP = 0x504,
+ MLX5_CMD_OP_RTS2RTS_QP = 0x505,
+ MLX5_CMD_OP_SQERR2RTS_QP = 0x506,
+ MLX5_CMD_OP_2ERR_QP = 0x507,
+ MLX5_CMD_OP_2RST_QP = 0x50a,
+ MLX5_CMD_OP_QUERY_QP = 0x50b,
+ MLX5_CMD_OP_INIT2INIT_QP = 0x50e,
+ MLX5_CMD_OP_CREATE_PSV = 0x600,
+ MLX5_CMD_OP_DESTROY_PSV = 0x601,
+ MLX5_CMD_OP_CREATE_SRQ = 0x700,
+ MLX5_CMD_OP_DESTROY_SRQ = 0x701,
+ MLX5_CMD_OP_QUERY_SRQ = 0x702,
+ MLX5_CMD_OP_ARM_RQ = 0x703,
+ MLX5_CMD_OP_RESIZE_SRQ = 0x704,
+ MLX5_CMD_OP_CREATE_DCT = 0x710,
+ MLX5_CMD_OP_DESTROY_DCT = 0x711,
+ MLX5_CMD_OP_DRAIN_DCT = 0x712,
+ MLX5_CMD_OP_QUERY_DCT = 0x713,
+ MLX5_CMD_OP_ARM_DCT_FOR_KEY_VIOLATION = 0x714,
+ MLX5_CMD_OP_QUERY_VPORT_STATE = 0x750,
+ MLX5_CMD_OP_MODIFY_VPORT_STATE = 0x751,
+ MLX5_CMD_OP_QUERY_ESW_VPORT_CONTEXT = 0x752,
+ MLX5_CMD_OP_MODIFY_ESW_VPORT_CONTEXT = 0x753,
+ MLX5_CMD_OP_QUERY_NIC_VPORT_CONTEXT = 0x754,
+ MLX5_CMD_OP_MODIFY_NIC_VPORT_CONTEXT = 0x755,
+ MLX5_CMD_OP_QUERY_RCOE_ADDRESS = 0x760,
+ MLX5_CMD_OP_SET_ROCE_ADDRESS = 0x761,
+ MLX5_CMD_OP_QUERY_VPORT_COUNTER = 0x770,
+ MLX5_CMD_OP_ALLOC_Q_COUNTER = 0x771,
+ MLX5_CMD_OP_DEALLOC_Q_COUNTER = 0x772,
+ MLX5_CMD_OP_QUERY_Q_COUNTER = 0x773,
+ MLX5_CMD_OP_ALLOC_PD = 0x800,
+ MLX5_CMD_OP_DEALLOC_PD = 0x801,
+ MLX5_CMD_OP_ALLOC_UAR = 0x802,
+ MLX5_CMD_OP_DEALLOC_UAR = 0x803,
+ MLX5_CMD_OP_CONFIG_INT_MODERATION = 0x804,
+ MLX5_CMD_OP_ACCESS_REG = 0x805,
+ MLX5_CMD_OP_ATTACH_TO_MCG = 0x806,
+ MLX5_CMD_OP_DETACH_FROM_MCG = 0x807,
+ MLX5_CMD_OP_GET_DROPPED_PACKET_LOG = 0x80a,
+ MLX5_CMD_OP_MAD_IFC = 0x50d,
+ MLX5_CMD_OP_QUERY_MAD_DEMUX = 0x80b,
+ MLX5_CMD_OP_SET_MAD_DEMUX = 0x80c,
+ MLX5_CMD_OP_NOP = 0x80d,
+ MLX5_CMD_OP_ALLOC_XRCD = 0x80e,
+ MLX5_CMD_OP_DEALLOC_XRCD = 0x80f,
+ MLX5_CMD_OP_SET_BURST_SIZE = 0x812,
+ MLX5_CMD_OP_QUERY_BURST_SZIE = 0x813,
+ MLX5_CMD_OP_ACTIVATE_TRACER = 0x814,
+ MLX5_CMD_OP_DEACTIVATE_TRACER = 0x815,
+ MLX5_CMD_OP_CREATE_SNIFFER_RULE = 0x820,
+ MLX5_CMD_OP_DESTROY_SNIFFER_RULE = 0x821,
+ MLX5_CMD_OP_QUERY_CONG_PARAMS = 0x822,
+ MLX5_CMD_OP_MODIFY_CONG_PARAMS = 0x823,
+ MLX5_CMD_OP_QUERY_CONG_STATISTICS = 0x824,
+ MLX5_CMD_OP_CREATE_TIR = 0x900,
+ MLX5_CMD_OP_MODIFY_TIR = 0x901,
+ MLX5_CMD_OP_DESTROY_TIR = 0x902,
+ MLX5_CMD_OP_QUERY_TIR = 0x903,
+ MLX5_CMD_OP_CREATE_TIS = 0x912,
+ MLX5_CMD_OP_MODIFY_TIS = 0x913,
+ MLX5_CMD_OP_DESTROY_TIS = 0x914,
+ MLX5_CMD_OP_QUERY_TIS = 0x915,
+ MLX5_CMD_OP_CREATE_SQ = 0x904,
+ MLX5_CMD_OP_MODIFY_SQ = 0x905,
+ MLX5_CMD_OP_DESTROY_SQ = 0x906,
+ MLX5_CMD_OP_QUERY_SQ = 0x907,
+ MLX5_CMD_OP_CREATE_RQ = 0x908,
+ MLX5_CMD_OP_MODIFY_RQ = 0x909,
+ MLX5_CMD_OP_DESTROY_RQ = 0x90a,
+ MLX5_CMD_OP_QUERY_RQ = 0x90b,
+ MLX5_CMD_OP_CREATE_RMP = 0x90c,
+ MLX5_CMD_OP_MODIFY_RMP = 0x90d,
+ MLX5_CMD_OP_DESTROY_RMP = 0x90e,
+ MLX5_CMD_OP_QUERY_RMP = 0x90f,
+ MLX5_CMD_OP_SET_FLOW_TABLE_ENTRY = 0x910,
+ MLX5_CMD_OP_QUERY_FLOW_TABLE_ENTRY = 0x911,
+ MLX5_CMD_OP_MAX = 0x911
+};
+
+#endif /* MLX5_IFC_H */
--
2.1.1
^ permalink raw reply related
* Re: [PATCH] ssb: Fix Sparse error in main
From: Michael Büsch @ 2014-10-01 13:27 UTC (permalink / raw)
To: Pramod Gurav; +Cc: Paul Bolle, linux-kernel, netdev
In-Reply-To: <542BAFB3.6030207@smartplayin.com>
[-- Attachment #1: Type: text/plain, Size: 1845 bytes --]
On Wed, 01 Oct 2014 13:09:31 +0530
Pramod Gurav <pramod.gurav@smartplayin.com> wrote:
> On Wednesday 01 October 2014 12:59 PM, Paul Bolle wrote:
> > On Wed, 2014-10-01 at 12:36 +0530, Pramod Gurav wrote:
> >> This change fixes below sparse error:
> >>
> >> drivers/ssb/main.c:94:16: warning: symbol 'ssb_sdio_func_to_bus'
> >> was not declared. Should it be static?
> >>
> >> Cc: Michael Buesch <m@bues.ch>
> >> Cc: netdev@vger.kernel.org
> >> Signed-off-by: Pramod Gurav <pramod.gurav@smartplayin.com>
> >> ---
> >> drivers/ssb/ssb_private.h | 1 +
> >> 1 file changed, 1 insertion(+)
> >>
> >> diff --git a/drivers/ssb/ssb_private.h b/drivers/ssb/ssb_private.h
> >> index eb507a5..86bbbe3 100644
> >> --- a/drivers/ssb/ssb_private.h
> >> +++ b/drivers/ssb/ssb_private.h
> >> @@ -193,6 +193,7 @@ extern struct ssb_bus *ssb_pci_dev_to_bus(struct pci_dev *pdev);
> >> int ssb_for_each_bus_call(unsigned long data,
> >> int (*func)(struct ssb_bus *bus, unsigned long data));
> >> extern struct ssb_bus *ssb_pcmcia_dev_to_bus(struct pcmcia_device *pdev);
> >> +struct ssb_bus *ssb_sdio_func_to_bus(struct sdio_func *func);
> >>
> >> struct ssb_freeze_context {
> >> /* Pointer to the bus */
> >
> > To me this looked like an odd way to silence that warning. So I dug a
> > bit further.
> >
> > ssb_sdio_func_to_bus() was added in commit 24ea602e183c ("ssb: Implement
> > SDIO host bus support"). So it was added in release v2.6.32. I found no
> > evidence this function was ever used. Can't it be removed?
> >
> Thanks Paul for review. Initially I too had greped for this function in
> kernel and found noone using it. But I thought this function might be
> useful in future. About removing it, may be original author can tell.
If it's unused, please remove it.
--
Michael
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]
^ permalink raw reply
* Re: [PATCH net-next] et131x: Add PCIe gigabit ethernet driver et131x to drivers/net
From: Joe Perches @ 2014-10-01 13:43 UTC (permalink / raw)
To: Tobias Klauser; +Cc: Mark Einon, davem, gregkh, linux-kernel, netdev
In-Reply-To: <20141001124500.GH3279@distanz.ch>
On Wed, 2014-10-01 at 14:45 +0200, Tobias Klauser wrote:
> On 2014-09-30 at 23:29:46 +0200, Mark Einon <mark.einon@gmail.com> wrote:
> > This adds the ethernet driver for Agere et131x devices to
> > drivers/net/ethernet.
[]
> > diff --git a/drivers/net/ethernet/agere/et131x.c b/drivers/net/ethernet/agere/et131x.c
[]
> > + rc = pci_enable_device(pdev);
> > + if (rc < 0) {
> > + dev_err(&pdev->dev, "pci_enable_device() failed\n");
> > + goto out;
>
> Nit: Just return rc here.
I don't think it matters at all.
It's a predictable style to use common exit blocks.
It's a maintainer's right to do it in whatever
fashion is desired.
^ permalink raw reply
* Re: [PATCH 33/34] netfilter: nf_tables: store and dump set policy
From: Arturo Borrero Gonzalez @ 2014-10-01 13:47 UTC (permalink / raw)
To: Sergei Shtylyov
Cc: Pablo Neira Ayuso, Netfilter Development Mailing list, davem,
netdev@vger.kernel.org
In-Reply-To: <54298583.3020100@cogentembedded.com>
On 29 September 2014 18:14, Sergei Shtylyov
<sergei.shtylyov@cogentembedded.com> wrote:
>>
>> index a476b99..19e79f0 100644
>> --- a/net/netfilter/nf_tables_api.c
>> +++ b/net/netfilter/nf_tables_api.c
>> @@ -2344,6 +2344,11 @@ static int nf_tables_fill_set(struct sk_buff *skb,
>> const struct nft_ctx *ctx,
>> goto nla_put_failure;
>> }
>>
>> + if (set->policy != NFT_SET_POL_PERFORMANCE) {
>> + if (nla_put_be32(skb, NFTA_SET_POLICY,
>> htonl(set->policy)))
>> + goto nla_put_failure;
>
>
> Why not fold these two *if* stetement into a single one?
>
I don't have any preference.
Should I send a patch to change it?
regards.
--
Arturo Borrero González
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* RE: [PATCH net-next 2/4] net/mlx5_core: Use hardware registers description header file
From: Eli Cohen @ 2014-10-01 13:47 UTC (permalink / raw)
To: David Miller
Cc: alexei.starovoitov@gmail.com, eli@dev.mellanox.co.il,
netdev@vger.kernel.org, Or Gerlitz, Yevgeny Petrilin
In-Reply-To: <20140930.161357.778280234084349300.davem@davemloft.net>
>People will try to review it only to discover that it's completely unused.
>
>I've been through this before with other device driver teams telling us that it's part of some automated framework etc. and that >doesn't make it acceptable.
>
>Please trim these things down to exactly what the driver uses.
OK, I have sent a few minutes ago V1 series that fixes that.
^ permalink raw reply
* RE: [net-next v3 20/29] fm10k: Add support for netdev offloads
From: Duyck, Alexander H @ 2014-10-01 13:52 UTC (permalink / raw)
To: Sathya Perla, Or Gerlitz, Kirsher, Jeffrey T
Cc: David Miller, Linux Netdev List, nhorman@redhat.com,
sassmann@redhat.com, jogreene@redhat.com, Tom Herbert
In-Reply-To: <CF9D1877D81D214CB0CA0669EFAE020C57B6EE4D@CMEXMB1.ad.emulex.com>
> -----Original Message-----
> From: Sathya Perla [mailto:Sathya.Perla@Emulex.Com]
> Sent: Wednesday, October 01, 2014 5:22 AM
> To: Duyck, Alexander H; Or Gerlitz; Kirsher, Jeffrey T
> Cc: David Miller; Linux Netdev List; nhorman@redhat.com;
> sassmann@redhat.com; jogreene@redhat.com; Tom Herbert
> Subject: RE: [net-next v3 20/29] fm10k: Add support for netdev offloads
>
>
> > -----Original Message-----
> > From: netdev-owner@vger.kernel.org [mailto:netdev-
> >
> > On 10/01/2014 01:31 AM, Or Gerlitz wrote:
> > > On Tue, Sep 23, 2014 at 2:16 PM, Jeff Kirsher
> > > <jeffrey.t.kirsher@intel.com> wrote:
> > >> From: Alexander Duyck <alexander.h.duyck@intel.com> This patch adds
> > >> support for basic offloads including TSO, Tx checksum, Rx checksum,
> > >> Rx hash, and the same features applied to VXLAN/NVGRE
> > tunnels.
> > >
> > >> --- a/drivers/net/ethernet/intel/fm10k/fm10k_main.c
> > >> +++ b/drivers/net/ethernet/intel/fm10k/fm10k_main.c
> > > [...]
> > >> +#define VXLAN_HLEN (sizeof(struct udphdr) + 8) static struct
> > >> +ethhdr *fm10k_port_is_vxlan(struct sk_buff *skb) {
> > >> + struct fm10k_intfc *interface = netdev_priv(skb->dev);
> > >> + struct fm10k_vxlan_port *vxlan_port;
> > >> +
> > >> + /* we can only offload a vxlan if we recognize it as such */
> > >> + vxlan_port = list_first_entry_or_null(&interface->vxlan_port,
> > >> + struct
> > >> + fm10k_vxlan_port, list);
> > >> +
> > >> + if (!vxlan_port)
> > >> + return NULL;
> > >> + if (vxlan_port->port != udp_hdr(skb)->dest)
> > >> + return NULL;
> > >> +
> > >> + /* return offset of udp_hdr plus 8 bytes for VXLAN header */
> > >> + return (struct ethhdr *)(skb_transport_header(skb) +
> > >> +VXLAN_HLEN); }
> > >> +
> ...
> >
> > >> +static int fm10k_tso(struct fm10k_ring *tx_ring,
> > >> + struct fm10k_tx_buffer *first) {
> > >> + struct sk_buff *skb = first->skb;
> > >> + struct fm10k_tx_desc *tx_desc;
> > >> + unsigned char *th;
> > >> + u8 hdrlen;
> > >> +
> > >> + if (skb->ip_summed != CHECKSUM_PARTIAL)
> > >> + return 0;
> > >> +
> > >> + if (!skb_is_gso(skb))
> > >> + return 0;
> > >> +
> > >> + /* compute header lengths */
> > >> + if (skb->encapsulation) {
> > >> + if (!fm10k_tx_encap_offload(skb))
> > >> + goto err_vxlan;
> > >> + th = skb_inner_transport_header(skb);
> > >> + } else {
> > >> + th = skb_transport_header(skb);
> > >> + }
> > >> +
> > >> + /* compute offset from SOF to transport header and add
> > >> + header len
> > */
> > >> + hdrlen = (th - skb->data) + (((struct tcphdr *)th)->doff <<
> > >> + 2);
> > >> +
> > >> + first->tx_flags |= FM10K_TX_FLAGS_CSUM;
> > >> +
> > >> + /* update gso size and bytecount with header size */
> > >> + first->gso_segs = skb_shinfo(skb)->gso_segs;
> > >> + first->bytecount += (first->gso_segs - 1) * hdrlen;
> > >> +
> > >> + /* populate Tx descriptor header size and mss */
> > >> + tx_desc = FM10K_TX_DESC(tx_ring, tx_ring->next_to_use);
> > >> + tx_desc->hdrlen = hdrlen;
> > >> + tx_desc->mss = cpu_to_le16(skb_shinfo(skb)->gso_size);
> > >> +
> > >> + return 1;
> > >> +err_vxlan:
> > >> + tx_ring->netdev->features &= ~NETIF_F_GSO_UDP_TUNNEL;
> > >> + if (!net_ratelimit())
> > >> + netdev_err(tx_ring->netdev,
> > >> + "TSO requested for unsupported tunnel,
> > >> +disabling
> > offload\n");
> > >> + return -1;
> > >> +}
> > >
> > > why? if TSO was requested for some packet the driver can't do, you
> > > disable
> > GSO
> > > for udp tunnels for any future packets too? maybe just disable it
> > > permanently till you feel safer to run under the current stack?
> >
> > That is essentially what I am doing. If the user wants they can turn
> > the feature back on via ethtool, but there is no point in having it on
> > if the device itself cannot support the packets that are coming through.
> >
>
> To turn off the offload, shouldn't you be using netdev_update_features()
> (->ndo_fix_features()) instead of directly flipping bits in netdev->features?
Why? That would just be me calling my own ndo operation wouldn't it, since I am changing the features of the device covered by this driver.
Thanks,
Alex
^ permalink raw reply
* Re: [PATCH net-next] et131x: Add PCIe gigabit ethernet driver et131x to drivers/net
From: Tobias Klauser @ 2014-10-01 14:14 UTC (permalink / raw)
To: Joe Perches; +Cc: Mark Einon, davem, gregkh, linux-kernel, netdev
In-Reply-To: <1412171027.3247.6.camel@joe-AO725>
On 2014-10-01 at 15:43:47 +0200, Joe Perches <joe@perches.com> wrote:
> On Wed, 2014-10-01 at 14:45 +0200, Tobias Klauser wrote:
> > On 2014-09-30 at 23:29:46 +0200, Mark Einon <mark.einon@gmail.com> wrote:
> > > This adds the ethernet driver for Agere et131x devices to
> > > drivers/net/ethernet.
> []
> > > diff --git a/drivers/net/ethernet/agere/et131x.c b/drivers/net/ethernet/agere/et131x.c
> []
> > > + rc = pci_enable_device(pdev);
> > > + if (rc < 0) {
> > > + dev_err(&pdev->dev, "pci_enable_device() failed\n");
> > > + goto out;
> >
> > Nit: Just return rc here.
>
> I don't think it matters at all.
Combined with my second remark this change makes the `out' label
unnecessary. If Mark decides to keep the goto here, at least the
position of the label should be changed to the end of the function, to
remain predictable and avoid jumping back.
^ permalink raw reply
* [PATCH net-next 0/2] Add pgtable API to query if write combining is available
From: Or Gerlitz @ 2014-10-01 14:54 UTC (permalink / raw)
To: David S. Miller
Cc: netdev, Amir Vadai, Jack Morgenstein, Moshe Lazer, Tal Alon,
Yevgeny Petrilin, Or Gerlitz
Currently the kernel write-combining interface provides a best effort
mechanism in which the caller simply invokes pgprot_writecombine().
If write combining is available, the region is mapped for it, otherwise
the region is (silently) mapped as non-cached. In some cases, however,
the calling driver must know if write combining is available, so a silent
best effort mechanism is not sufficient. Add writecombine_available(), which
returns 1 if the system supports write combining and 0 if it doesn't.
In mlx4 for better latency, we write send descriptors to a write-combining
(WC) mapped buffer instead of ringing a doorbell and having the HW fetch
the descriptor from system memory.
However, if write-combining is not supported on the host, then we
obtain better latency by using the doorbell-ring/HW fetch mechanism.
This series from Moshe and Jack adds the API and uses in in mlx4.
We are sending through netdev to get feedback from the networking
community and extend the reviewer audience if required.
Or
Moshe Lazer (2):
pgtable: Add API to query if write combining is available
net/mlx4_core: Disable BF when write combining is not available
arch/arm/include/asm/pgtable.h | 6 ++++++
arch/arm64/include/asm/pgtable.h | 5 +++++
arch/ia64/include/asm/pgtable.h | 6 ++++++
arch/powerpc/include/asm/pgtable.h | 6 ++++++
arch/x86/include/asm/pgtable_types.h | 2 ++
arch/x86/mm/pat.c | 9 +++++++++
drivers/net/ethernet/mellanox/mlx4/fw.c | 2 +-
include/asm-generic/pgtable.h | 8 ++++++++
8 files changed, 43 insertions(+), 1 deletions(-)
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox