* Re: [net-next PATCH 6/8] mlx4: Add support for inner IPv6 checksum offloads and TSO
From: Alex Duyck @ 2016-04-26 15:50 UTC (permalink / raw)
To: Saeed Mahameed
Cc: talal, Linux Kernel Network Developers, David Miller, galp,
ogerlitz, Eran Ben Elisha
In-Reply-To: <571F7D14.7090504@dev.mellanox.co.il>
On Tue, Apr 26, 2016 at 7:37 AM, Saeed Mahameed
<saeedm@dev.mellanox.co.il> wrote:
>
>
> On 4/25/2016 9:31 PM, Alexander Duyck wrote:
>>
>> >From what I can tell the ConnectX-3 will support an inner IPv6 checksum
>> and
>> segmentation offload, however it cannot support outer IPv6 headers. For
>> this reason I am adding the feature to the hw_enc_features and adding an
>> extra check to the features_check call that will disable GSO and checksum
>> offload in the case that the encapsulated frame has an outer IP version of
>> that is not 4.
>
>
> Hi Alex,
>
> Can you share the testing commands of running vxlan over IPv6 and what
> exactly didn't work for you ?
> we would like to test this in house and understand what went wrong,
> theoretically there shouldn't be a difference between IPv6/IPv4 outer
> checksum offloading in ConnectX-3.
The setup is pretty straight forward. Basically I left the first port
in the default namespace and moved the second int a secondary
namespace referred to below as $netns. I then assigned the IPv6
addresses fec0::10:1 and fec0::10:2. After that I ran the following:
VXLAN=vx$net
echo $VXLAN ${test_options[$i]}
ip link add $VXLAN type vxlan id $net \
local fec0::10:1 remote $addr6 dev $PF0 \
${test_options[$i]} dstport `expr 8800 + $net`
ip netns exec $netns ip link add $VXLAN type vxlan id $net \
local $addr6 remote fec0::10:1 dev $port \
${test_options[$i]} dstport `expr 8800 + $net`
ifconfig $VXLAN 192.168.${net}.1/24
ip netns exec $netns ifconfig $VXLAN 192.168.${net}.2/24
> Anyway, I suspect it might be related to a driver bug most likely in
> get_real_size function @en_tx.c
> specifically in : *lso_header_size = (skb_inner_transport_header(skb) -
> skb->data) + inner_tcp_hdrlen(skb);
>
> will check this and get back to you.
I'm not entirely convinced. What I was seeing is t hat the hardware
itself was performing Rx checksum offload only on tunnels with an
outer IPv4 header and ignoring tunnels with an outer IPv6 header.
> for the mlx5 patches I will also go through them later today.
Thanks.
>
>> Signed-off-by: Alexander Duyck <aduyck@mirantis.com>
>> ---
>> drivers/net/ethernet/mellanox/mlx4/en_netdev.c | 25
>> +++++++++++++++++++-----
>> drivers/net/ethernet/mellanox/mlx4/en_tx.c | 15 ++++++++++++--
>> 2 files changed, 33 insertions(+), 7 deletions(-)
>>
>> diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
>> b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
>> index bce37cbfde24..6f28ac58251c 100644
>> --- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
>> +++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
>> @@ -2357,8 +2357,10 @@ out:
>> }
>> /* set offloads */
>> - priv->dev->hw_enc_features |= NETIF_F_IP_CSUM | NETIF_F_RXCSUM |
>> - NETIF_F_TSO | NETIF_F_GSO_UDP_TUNNEL
>> |
>> + priv->dev->hw_enc_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM
>> |
>> + NETIF_F_RXCSUM |
>> + NETIF_F_TSO | NETIF_F_TSO6 |
>> + NETIF_F_GSO_UDP_TUNNEL |
>> NETIF_F_GSO_UDP_TUNNEL_CSUM |
>> NETIF_F_GSO_PARTIAL;
>> }
>> @@ -2369,8 +2371,10 @@ static void mlx4_en_del_vxlan_offloads(struct
>> work_struct *work)
>> struct mlx4_en_priv *priv = container_of(work, struct
>> mlx4_en_priv,
>> vxlan_del_task);
>> /* unset offloads */
>> - priv->dev->hw_enc_features &= ~(NETIF_F_IP_CSUM | NETIF_F_RXCSUM |
>> - NETIF_F_TSO |
>> NETIF_F_GSO_UDP_TUNNEL |
>> + priv->dev->hw_enc_features &= ~(NETIF_F_IP_CSUM |
>> NETIF_F_IPV6_CSUM |
>> + NETIF_F_RXCSUM |
>> + NETIF_F_TSO | NETIF_F_TSO6 |
>> + NETIF_F_GSO_UDP_TUNNEL |
>> NETIF_F_GSO_UDP_TUNNEL_CSUM |
>> NETIF_F_GSO_PARTIAL);
>> @@ -2431,7 +2435,18 @@ static netdev_features_t
>> mlx4_en_features_check(struct sk_buff *skb,
>> netdev_features_t
>> features)
>> {
>> features = vlan_features_check(skb, features);
>> - return vxlan_features_check(skb, features);
>> + features = vxlan_features_check(skb, features);
>> +
>> + /* The ConnectX-3 doesn't support outer IPv6 checksums but it does
>> + * support inner IPv6 checksums and segmentation so we need to
>> + * strip that feature if this is an IPv6 encapsulated frame.
>> + */
>> + if (skb->encapsulation &&
>> + (skb->ip_summed == CHECKSUM_PARTIAL) &&
>> + (ip_hdr(skb)->version != 4))
>> + features &= ~(NETIF_F_CSUM_MASK | NETIF_F_GSO_MASK);
>
> Dejavu, didn't you fix this already in harmonize_features, in
> i.e, it is enough to do here:
>
> if (skb->encapsulation && (skb->ip_summed == CHECKSUM_PARTIAL))
> features &= ~NETIF_F_IPV6_CSUM;
>
So what this patch is doing is enabling an inner IPv6 header offloads.
Up above we set the NETIF_F_IPV6_CSUM bit and we want it to stay set
unless we have an outer IPv6 header because the inner headers may
still need that bit set. If I did what you suggest it strips IPv6
checksum support for inner headers and if we have to use GSO partial I
ended up encountering some of the other bugs that I have fixed for GSO
partial where either sg or csum are not defined.
>
>> +
>> + return features;
>> }
>> #endif
>> diff --git a/drivers/net/ethernet/mellanox/mlx4/en_tx.c
>> b/drivers/net/ethernet/mellanox/mlx4/en_tx.c
>> index c0d7b7296236..c9f5388ea22a 100644
>> --- a/drivers/net/ethernet/mellanox/mlx4/en_tx.c
>> +++ b/drivers/net/ethernet/mellanox/mlx4/en_tx.c
>> @@ -41,6 +41,7 @@
>> #include <linux/vmalloc.h>
>> #include <linux/tcp.h>
>> #include <linux/ip.h>
>> +#include <linux/ipv6.h>
>> #include <linux/moduleparam.h>
>> #include "mlx4_en.h"
>> @@ -918,8 +919,18 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct
>> net_device *dev)
>> tx_ind, fragptr);
>> if (skb->encapsulation) {
>> - struct iphdr *ipv4 = (struct iphdr
>> *)skb_inner_network_header(skb);
>> - if (ipv4->protocol == IPPROTO_TCP || ipv4->protocol ==
>> IPPROTO_UDP)
>> + union {
>> + struct iphdr *v4;
>> + struct ipv6hdr *v6;
>> + unsigned char *hdr;
>> + } ip;
>> + u8 proto;
>> +
>> + ip.hdr = skb_inner_network_header(skb);
>> + proto = (ip.v4->version == 4) ? ip.v4->protocol :
>> + ip.v6->nexthdr;
>> +
>> + if (proto == IPPROTO_TCP || proto == IPPROTO_UDP)
>> op_own |= cpu_to_be32(MLX4_WQE_CTRL_IIP |
>> MLX4_WQE_CTRL_ILP);
>> else
>> op_own |= cpu_to_be32(MLX4_WQE_CTRL_IIP);
>
>
> basically this is a bug fix, I don't know why the original author assumed it
> will be ipv4 !
Because the feature flags didn't allow it any other way. I am adding
the NETIF_F_TSO6 and NETIF_F_IPV6_CSUM flags in hw_enc_features and so
situations such as this couldn't be encountered until you start adding
those flags.
- Alex
^ permalink raw reply
* Re: [PATCH] net/mlx5e: avoid stack overflow in mlx5e_open_channels
From: Arnd Bergmann @ 2016-04-26 15:49 UTC (permalink / raw)
To: Saeed Mahameed
Cc: Saeed Mahameed, Matan Barak, Leon Romanovsky, David S. Miller,
Achiad Shochat, Or Gerlitz, Amir Vadai, Tariq Toukan,
Linux Netdev List, linux-rdma, linux-kernel
In-Reply-To: <CALzJLG-d1mTs9SdubELzQtczsiVY0cgzBc3BC6wJoBgx4Wg_+Q@mail.gmail.com>
On Tuesday 26 April 2016 17:41:45 Saeed Mahameed wrote:
> On Tue, Apr 26, 2016 at 4:53 PM, Arnd Bergmann <arnd@arndb.de> wrote:
> >
> > Sure, do you want to just edit this when you forward the patch, or
> > do you need me to do it?
> >
>
> Well, I won't say no if you want to do it
>
All I want is to get rid of the patch in my queue. I guess it's
worth the 10 minute of work ;-)
v2 coming
Arnd
^ permalink raw reply
* [PATCH net-next 0/3] qed: Bandwidth configuration support
From: Manish Chopra @ 2016-04-26 14:56 UTC (permalink / raw)
To: davem; +Cc: netdev, Ariel.Elior, Yuval.Mintz
Hi David,
This series adds support in driver for min/max bandwidth configuration
for the PF on the link change notification or on explicit request of
bandwidth update from the MFW [management firmware].
The same infrastructure would later be used by user based flows
[for example, rate shaping for the VFs]
Please consider applying this series to "net-next"
Thanks,
Manish
Manish Chopra (3):
qed: Add vport WFQ configuration APIs
qed: Add PF max bandwidth configuration support
qed: Add PF min bandwidth configuration support
drivers/net/ethernet/qlogic/qed/qed.h | 11 +
drivers/net/ethernet/qlogic/qed/qed_dev.c | 327 ++++++++++++++++++++-
drivers/net/ethernet/qlogic/qed/qed_hsi.h | 6 +-
.../net/ethernet/qlogic/qed/qed_init_fw_funcs.c | 40 +++
drivers/net/ethernet/qlogic/qed/qed_mcp.c | 146 +++++----
drivers/net/ethernet/qlogic/qed/qed_mcp.h | 21 +-
drivers/net/ethernet/qlogic/qed/qed_reg_addr.h | 2 +
7 files changed, 491 insertions(+), 62 deletions(-)
--
2.7.2
^ permalink raw reply
* [PATCH net-next 1/3] qed: Add vport WFQ configuration APIs
From: Manish Chopra @ 2016-04-26 14:56 UTC (permalink / raw)
To: davem; +Cc: netdev, Ariel.Elior, Yuval.Mintz
In-Reply-To: <1461682570-745-1-git-send-email-manish.chopra@qlogic.com>
This patch adds relevant APIs needed to configure WFQ
(Weighted fair queueing) values for the vports. WFQ configuration
is used per vport basis when minimum bandwidth update/configuration
is notified to the PF by the management firmware.
Signed-off-by: Manish Chopra <manish.chopra@qlogic.com>
Signed-off-by: Yuval Mintz <Yuval.Mintz@qlogic.com>
---
drivers/net/ethernet/qlogic/qed/qed.h | 11 ++
drivers/net/ethernet/qlogic/qed/qed_dev.c | 188 ++++++++++++++++++++-
drivers/net/ethernet/qlogic/qed/qed_hsi.h | 2 +
.../net/ethernet/qlogic/qed/qed_init_fw_funcs.c | 25 +++
drivers/net/ethernet/qlogic/qed/qed_reg_addr.h | 1 +
5 files changed, 223 insertions(+), 4 deletions(-)
diff --git a/drivers/net/ethernet/qlogic/qed/qed.h b/drivers/net/ethernet/qlogic/qed/qed.h
index 33e2ed6..cceac32 100644
--- a/drivers/net/ethernet/qlogic/qed/qed.h
+++ b/drivers/net/ethernet/qlogic/qed/qed.h
@@ -32,6 +32,8 @@ extern const struct qed_common_ops qed_common_ops_pass;
#define NAME_SIZE 16
#define VER_SIZE 16
+#define QED_WFQ_UNIT 100
+
/* cau states */
enum qed_coalescing_mode {
QED_COAL_MODE_DISABLE,
@@ -237,6 +239,12 @@ struct qed_dmae_info {
struct dmae_cmd *p_dmae_cmd;
};
+struct qed_wfq_data {
+ /* when feature is configured for at least 1 vport */
+ u32 min_speed;
+ bool configured;
+};
+
struct qed_qm_info {
struct init_qm_pq_params *qm_pq_params;
struct init_qm_vport_params *qm_vport_params;
@@ -257,6 +265,7 @@ struct qed_qm_info {
bool vport_wfq_en;
u8 pf_wfq;
u32 pf_rl;
+ struct qed_wfq_data *wfq_data;
};
struct storm_stats {
@@ -526,6 +535,8 @@ static inline u8 qed_concrete_to_sw_fid(struct qed_dev *cdev,
#define PURE_LB_TC 8
+void qed_configure_vp_wfq_on_link_change(struct qed_dev *cdev, u32 min_pf_rate);
+
#define QED_LEADING_HWFN(dev) (&dev->hwfns[0])
/* Other Linux specific common definitions */
diff --git a/drivers/net/ethernet/qlogic/qed/qed_dev.c b/drivers/net/ethernet/qlogic/qed/qed_dev.c
index bdae5a5..28e0619 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_dev.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_dev.c
@@ -105,6 +105,8 @@ static void qed_qm_info_free(struct qed_hwfn *p_hwfn)
qm_info->qm_vport_params = NULL;
kfree(qm_info->qm_port_params);
qm_info->qm_port_params = NULL;
+ kfree(qm_info->wfq_data);
+ qm_info->wfq_data = NULL;
}
void qed_resc_free(struct qed_dev *cdev)
@@ -175,6 +177,11 @@ static int qed_init_qm_info(struct qed_hwfn *p_hwfn)
if (!qm_info->qm_port_params)
goto alloc_err;
+ qm_info->wfq_data = kcalloc(num_vports, sizeof(*qm_info->wfq_data),
+ GFP_KERNEL);
+ if (!qm_info->wfq_data)
+ goto alloc_err;
+
vport_id = (u8)RESC_START(p_hwfn, QED_VPORT);
/* First init per-TC PQs */
@@ -221,10 +228,7 @@ static int qed_init_qm_info(struct qed_hwfn *p_hwfn)
alloc_err:
DP_NOTICE(p_hwfn, "Failed to allocate memory for QM params\n");
- kfree(qm_info->qm_pq_params);
- kfree(qm_info->qm_vport_params);
- kfree(qm_info->qm_port_params);
-
+ qed_qm_info_free(p_hwfn);
return -ENOMEM;
}
@@ -1595,3 +1599,179 @@ int qed_fw_rss_eng(struct qed_hwfn *p_hwfn,
return 0;
}
+
+/* Calculate final WFQ values for all vports and configure them.
+ * After this configuration each vport will have
+ * approx min rate = min_pf_rate * (vport_wfq / QED_WFQ_UNIT)
+ */
+static void qed_configure_wfq_for_all_vports(struct qed_hwfn *p_hwfn,
+ struct qed_ptt *p_ptt,
+ u32 min_pf_rate)
+{
+ struct init_qm_vport_params *vport_params;
+ int i;
+
+ vport_params = p_hwfn->qm_info.qm_vport_params;
+
+ for (i = 0; i < p_hwfn->qm_info.num_vports; i++) {
+ u32 wfq_speed = p_hwfn->qm_info.wfq_data[i].min_speed;
+
+ vport_params[i].vport_wfq = (wfq_speed * QED_WFQ_UNIT) /
+ min_pf_rate;
+ qed_init_vport_wfq(p_hwfn, p_ptt,
+ vport_params[i].first_tx_pq_id,
+ vport_params[i].vport_wfq);
+ }
+}
+
+static void qed_init_wfq_default_param(struct qed_hwfn *p_hwfn,
+ u32 min_pf_rate)
+
+{
+ int i;
+
+ for (i = 0; i < p_hwfn->qm_info.num_vports; i++)
+ p_hwfn->qm_info.qm_vport_params[i].vport_wfq = 1;
+}
+
+static void qed_disable_wfq_for_all_vports(struct qed_hwfn *p_hwfn,
+ struct qed_ptt *p_ptt,
+ u32 min_pf_rate)
+{
+ struct init_qm_vport_params *vport_params;
+ int i;
+
+ vport_params = p_hwfn->qm_info.qm_vport_params;
+
+ for (i = 0; i < p_hwfn->qm_info.num_vports; i++) {
+ qed_init_wfq_default_param(p_hwfn, min_pf_rate);
+ qed_init_vport_wfq(p_hwfn, p_ptt,
+ vport_params[i].first_tx_pq_id,
+ vport_params[i].vport_wfq);
+ }
+}
+
+/* This function performs several validations for WFQ
+ * configuration and required min rate for a given vport
+ * 1. req_rate must be greater than one percent of min_pf_rate.
+ * 2. req_rate should not cause other vports [not configured for WFQ explicitly]
+ * rates to get less than one percent of min_pf_rate.
+ * 3. total_req_min_rate [all vports min rate sum] shouldn't exceed min_pf_rate.
+ */
+static int qed_init_wfq_param(struct qed_hwfn *p_hwfn,
+ u16 vport_id, u32 req_rate,
+ u32 min_pf_rate)
+{
+ u32 total_req_min_rate = 0, total_left_rate = 0, left_rate_per_vp = 0;
+ int non_requested_count = 0, req_count = 0, i, num_vports;
+
+ num_vports = p_hwfn->qm_info.num_vports;
+
+ /* Accounting for the vports which are configured for WFQ explicitly */
+ for (i = 0; i < num_vports; i++) {
+ u32 tmp_speed;
+
+ if ((i != vport_id) &&
+ p_hwfn->qm_info.wfq_data[i].configured) {
+ req_count++;
+ tmp_speed = p_hwfn->qm_info.wfq_data[i].min_speed;
+ total_req_min_rate += tmp_speed;
+ }
+ }
+
+ /* Include current vport data as well */
+ req_count++;
+ total_req_min_rate += req_rate;
+ non_requested_count = num_vports - req_count;
+
+ if (req_rate < min_pf_rate / QED_WFQ_UNIT) {
+ DP_VERBOSE(p_hwfn, NETIF_MSG_LINK,
+ "Vport [%d] - Requested rate[%d Mbps] is less than one percent of configured PF min rate[%d Mbps]\n",
+ vport_id, req_rate, min_pf_rate);
+ return -EINVAL;
+ }
+
+ if (num_vports > QED_WFQ_UNIT) {
+ DP_VERBOSE(p_hwfn, NETIF_MSG_LINK,
+ "Number of vports is greater than %d\n",
+ QED_WFQ_UNIT);
+ return -EINVAL;
+ }
+
+ if (total_req_min_rate > min_pf_rate) {
+ DP_VERBOSE(p_hwfn, NETIF_MSG_LINK,
+ "Total requested min rate for all vports[%d Mbps] is greater than configured PF min rate[%d Mbps]\n",
+ total_req_min_rate, min_pf_rate);
+ return -EINVAL;
+ }
+
+ total_left_rate = min_pf_rate - total_req_min_rate;
+
+ left_rate_per_vp = total_left_rate / non_requested_count;
+ if (left_rate_per_vp < min_pf_rate / QED_WFQ_UNIT) {
+ DP_VERBOSE(p_hwfn, NETIF_MSG_LINK,
+ "Non WFQ configured vports rate [%d Mbps] is less than one percent of configured PF min rate[%d Mbps]\n",
+ left_rate_per_vp, min_pf_rate);
+ return -EINVAL;
+ }
+
+ p_hwfn->qm_info.wfq_data[vport_id].min_speed = req_rate;
+ p_hwfn->qm_info.wfq_data[vport_id].configured = true;
+
+ for (i = 0; i < num_vports; i++) {
+ if (p_hwfn->qm_info.wfq_data[i].configured)
+ continue;
+
+ p_hwfn->qm_info.wfq_data[i].min_speed = left_rate_per_vp;
+ }
+
+ return 0;
+}
+
+static int __qed_configure_vp_wfq_on_link_change(struct qed_hwfn *p_hwfn,
+ struct qed_ptt *p_ptt,
+ u32 min_pf_rate)
+{
+ bool use_wfq = false;
+ int rc = 0;
+ u16 i;
+
+ /* Validate all pre configured vports for wfq */
+ for (i = 0; i < p_hwfn->qm_info.num_vports; i++) {
+ u32 rate;
+
+ if (!p_hwfn->qm_info.wfq_data[i].configured)
+ continue;
+
+ rate = p_hwfn->qm_info.wfq_data[i].min_speed;
+ use_wfq = true;
+
+ rc = qed_init_wfq_param(p_hwfn, i, rate, min_pf_rate);
+ if (rc) {
+ DP_NOTICE(p_hwfn,
+ "WFQ validation failed while configuring min rate\n");
+ break;
+ }
+ }
+
+ if (!rc && use_wfq)
+ qed_configure_wfq_for_all_vports(p_hwfn, p_ptt, min_pf_rate);
+ else
+ qed_disable_wfq_for_all_vports(p_hwfn, p_ptt, min_pf_rate);
+
+ return rc;
+}
+
+/* API to configure WFQ from mcp link change */
+void qed_configure_vp_wfq_on_link_change(struct qed_dev *cdev, u32 min_pf_rate)
+{
+ int i;
+
+ for_each_hwfn(cdev, i) {
+ struct qed_hwfn *p_hwfn = &cdev->hwfns[i];
+
+ __qed_configure_vp_wfq_on_link_change(p_hwfn,
+ p_hwfn->p_dpc_ptt,
+ min_pf_rate);
+ }
+}
diff --git a/drivers/net/ethernet/qlogic/qed/qed_hsi.h b/drivers/net/ethernet/qlogic/qed/qed_hsi.h
index 15e02ab..7d5ed0c 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_hsi.h
+++ b/drivers/net/ethernet/qlogic/qed/qed_hsi.h
@@ -5116,4 +5116,6 @@ struct hw_set_image {
struct hw_set_info hw_sets[1];
};
+int qed_init_vport_wfq(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt,
+ u16 first_tx_pq_id[NUM_OF_TCS], u16 vport_wfq);
#endif
diff --git a/drivers/net/ethernet/qlogic/qed/qed_init_fw_funcs.c b/drivers/net/ethernet/qlogic/qed/qed_init_fw_funcs.c
index 1dd5324..e646987 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_init_fw_funcs.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_init_fw_funcs.c
@@ -732,6 +732,31 @@ int qed_init_pf_rl(struct qed_hwfn *p_hwfn,
return 0;
}
+int qed_init_vport_wfq(struct qed_hwfn *p_hwfn,
+ struct qed_ptt *p_ptt,
+ u16 first_tx_pq_id[NUM_OF_TCS],
+ u16 vport_wfq)
+{
+ u32 inc_val = QM_WFQ_INC_VAL(vport_wfq);
+ u8 tc;
+
+ if (!inc_val || inc_val > QM_WFQ_MAX_INC_VAL) {
+ DP_NOTICE(p_hwfn, "Invalid VPORT WFQ weight configuration");
+ return -1;
+ }
+
+ for (tc = 0; tc < NUM_OF_TCS; tc++) {
+ u16 vport_pq_id = first_tx_pq_id[tc];
+
+ if (vport_pq_id != QM_INVALID_PQ_ID)
+ qed_wr(p_hwfn, p_ptt,
+ QM_REG_WFQVPWEIGHT + vport_pq_id * 4,
+ inc_val);
+ }
+
+ return 0;
+}
+
int qed_init_vport_rl(struct qed_hwfn *p_hwfn,
struct qed_ptt *p_ptt,
u8 vport_id,
diff --git a/drivers/net/ethernet/qlogic/qed/qed_reg_addr.h b/drivers/net/ethernet/qlogic/qed/qed_reg_addr.h
index 55451a4..d2f5730 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_reg_addr.h
+++ b/drivers/net/ethernet/qlogic/qed/qed_reg_addr.h
@@ -458,4 +458,5 @@
#define PBF_REG_NGE_COMP_VER 0xd80524UL
#define PRS_REG_NGE_COMP_VER 0x1f0878UL
+#define QM_REG_WFQVPWEIGHT 0x2fa000UL
#endif
--
2.7.2
^ permalink raw reply related
* [PATCH net-next 2/3] qed: Add PF max bandwidth configuration support
From: Manish Chopra @ 2016-04-26 14:56 UTC (permalink / raw)
To: davem; +Cc: netdev, Ariel.Elior, Yuval.Mintz
In-Reply-To: <1461682570-745-1-git-send-email-manish.chopra@qlogic.com>
This patch adds support for PF maximum bandwidth update
or configuration notified by management firmware.
Signed-off-by: Manish Chopra <manish.chopra@qlogic.com>
Signed-off-by: Yuval Mintz <Yuval.Mintz@qlogic.com>
---
drivers/net/ethernet/qlogic/qed/qed_dev.c | 68 ++++++++++++++-
drivers/net/ethernet/qlogic/qed/qed_hsi.h | 2 +-
drivers/net/ethernet/qlogic/qed/qed_mcp.c | 138 ++++++++++++++++++------------
drivers/net/ethernet/qlogic/qed/qed_mcp.h | 14 ++-
4 files changed, 165 insertions(+), 57 deletions(-)
diff --git a/drivers/net/ethernet/qlogic/qed/qed_dev.c b/drivers/net/ethernet/qlogic/qed/qed_dev.c
index 28e0619..4e99108 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_dev.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_dev.c
@@ -579,7 +579,7 @@ static int qed_hw_init_pf(struct qed_hwfn *p_hwfn,
p_hwfn->qm_info.pf_wfq = p_info->bandwidth_min;
/* Update rate limit once we'll actually have a link */
- p_hwfn->qm_info.pf_rl = 100;
+ p_hwfn->qm_info.pf_rl = 100000;
}
qed_cxt_hw_init_pf(p_hwfn);
@@ -1775,3 +1775,69 @@ void qed_configure_vp_wfq_on_link_change(struct qed_dev *cdev, u32 min_pf_rate)
min_pf_rate);
}
}
+
+int __qed_configure_pf_max_bandwidth(struct qed_hwfn *p_hwfn,
+ struct qed_ptt *p_ptt,
+ struct qed_mcp_link_state *p_link,
+ u8 max_bw)
+{
+ int rc = 0;
+
+ p_hwfn->mcp_info->func_info.bandwidth_max = max_bw;
+
+ if (!p_link->line_speed && (max_bw != 100))
+ return rc;
+
+ p_link->speed = (p_link->line_speed * max_bw) / 100;
+ p_hwfn->qm_info.pf_rl = p_link->speed;
+
+ /* Since the limiter also affects Tx-switched traffic, we don't want it
+ * to limit such traffic in case there's no actual limit.
+ * In that case, set limit to imaginary high boundary.
+ */
+ if (max_bw == 100)
+ p_hwfn->qm_info.pf_rl = 100000;
+
+ rc = qed_init_pf_rl(p_hwfn, p_ptt, p_hwfn->rel_pf_id,
+ p_hwfn->qm_info.pf_rl);
+
+ DP_VERBOSE(p_hwfn, NETIF_MSG_LINK,
+ "Configured MAX bandwidth to be %08x Mb/sec\n",
+ p_link->speed);
+
+ return rc;
+}
+
+/* Main API to configure PF max bandwidth where bw range is [1 - 100] */
+int qed_configure_pf_max_bandwidth(struct qed_dev *cdev, u8 max_bw)
+{
+ int i, rc = -EINVAL;
+
+ if (max_bw < 1 || max_bw > 100) {
+ DP_NOTICE(cdev, "PF max bw valid range is [1-100]\n");
+ return rc;
+ }
+
+ for_each_hwfn(cdev, i) {
+ struct qed_hwfn *p_hwfn = &cdev->hwfns[i];
+ struct qed_hwfn *p_lead = QED_LEADING_HWFN(cdev);
+ struct qed_mcp_link_state *p_link;
+ struct qed_ptt *p_ptt;
+
+ p_link = &p_lead->mcp_info->link_output;
+
+ p_ptt = qed_ptt_acquire(p_hwfn);
+ if (!p_ptt)
+ return -EBUSY;
+
+ rc = __qed_configure_pf_max_bandwidth(p_hwfn, p_ptt,
+ p_link, max_bw);
+
+ qed_ptt_release(p_hwfn, p_ptt);
+
+ if (rc)
+ break;
+ }
+
+ return rc;
+}
diff --git a/drivers/net/ethernet/qlogic/qed/qed_hsi.h b/drivers/net/ethernet/qlogic/qed/qed_hsi.h
index 7d5ed0c..81cf625 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_hsi.h
+++ b/drivers/net/ethernet/qlogic/qed/qed_hsi.h
@@ -3837,7 +3837,7 @@ struct public_drv_mb {
#define DRV_MSG_CODE_SET_LLDP 0x24000000
#define DRV_MSG_CODE_SET_DCBX 0x25000000
-
+#define DRV_MSG_CODE_BW_UPDATE_ACK 0x32000000
#define DRV_MSG_CODE_NIG_DRAIN 0x30000000
#define DRV_MSG_CODE_INITIATE_FLR 0x02000000
diff --git a/drivers/net/ethernet/qlogic/qed/qed_mcp.c b/drivers/net/ethernet/qlogic/qed/qed_mcp.c
index b89c9a8..578b09c 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_mcp.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_mcp.c
@@ -473,6 +473,7 @@ static void qed_mcp_handle_link_change(struct qed_hwfn *p_hwfn,
{
struct qed_mcp_link_state *p_link;
u32 status = 0;
+ u8 max_bw;
p_link = &p_hwfn->mcp_info->link_output;
memset(p_link, 0, sizeof(*p_link));
@@ -527,17 +528,15 @@ static void qed_mcp_handle_link_change(struct qed_hwfn *p_hwfn,
p_link->speed = 0;
}
+ if (p_link->link_up && p_link->speed)
+ p_link->line_speed = p_link->speed;
+ else
+ p_link->line_speed = 0;
+
+ max_bw = p_hwfn->mcp_info->func_info.bandwidth_max;
+
/* Correct speed according to bandwidth allocation */
- if (p_hwfn->mcp_info->func_info.bandwidth_max && p_link->speed) {
- p_link->speed = p_link->speed *
- p_hwfn->mcp_info->func_info.bandwidth_max /
- 100;
- qed_init_pf_rl(p_hwfn, p_ptt, p_hwfn->rel_pf_id,
- p_link->speed);
- DP_VERBOSE(p_hwfn, NETIF_MSG_LINK,
- "Configured MAX bandwidth to be %08x Mb/sec\n",
- p_link->speed);
- }
+ __qed_configure_pf_max_bandwidth(p_hwfn, p_ptt, p_link, max_bw);
p_link->an = !!(status & LINK_STATUS_AUTO_NEGOTIATE_ENABLED);
p_link->an_complete = !!(status &
@@ -648,6 +647,76 @@ int qed_mcp_set_link(struct qed_hwfn *p_hwfn,
return 0;
}
+static void qed_read_pf_bandwidth(struct qed_hwfn *p_hwfn,
+ struct public_func *p_shmem_info)
+{
+ struct qed_mcp_function_info *p_info;
+
+ p_info = &p_hwfn->mcp_info->func_info;
+
+ p_info->bandwidth_min = (p_shmem_info->config &
+ FUNC_MF_CFG_MIN_BW_MASK) >>
+ FUNC_MF_CFG_MIN_BW_SHIFT;
+ if (p_info->bandwidth_min < 1 || p_info->bandwidth_min > 100) {
+ DP_INFO(p_hwfn,
+ "bandwidth minimum out of bounds [%02x]. Set to 1\n",
+ p_info->bandwidth_min);
+ p_info->bandwidth_min = 1;
+ }
+
+ p_info->bandwidth_max = (p_shmem_info->config &
+ FUNC_MF_CFG_MAX_BW_MASK) >>
+ FUNC_MF_CFG_MAX_BW_SHIFT;
+ if (p_info->bandwidth_max < 1 || p_info->bandwidth_max > 100) {
+ DP_INFO(p_hwfn,
+ "bandwidth maximum out of bounds [%02x]. Set to 100\n",
+ p_info->bandwidth_max);
+ p_info->bandwidth_max = 100;
+ }
+}
+
+static u32 qed_mcp_get_shmem_func(struct qed_hwfn *p_hwfn,
+ struct qed_ptt *p_ptt,
+ struct public_func *p_data,
+ int pfid)
+{
+ u32 addr = SECTION_OFFSIZE_ADDR(p_hwfn->mcp_info->public_base,
+ PUBLIC_FUNC);
+ u32 mfw_path_offsize = qed_rd(p_hwfn, p_ptt, addr);
+ u32 func_addr = SECTION_ADDR(mfw_path_offsize, pfid);
+ u32 i, size;
+
+ memset(p_data, 0, sizeof(*p_data));
+
+ size = min_t(u32, sizeof(*p_data),
+ QED_SECTION_SIZE(mfw_path_offsize));
+ for (i = 0; i < size / sizeof(u32); i++)
+ ((u32 *)p_data)[i] = qed_rd(p_hwfn, p_ptt,
+ func_addr + (i << 2));
+ return size;
+}
+
+static void qed_mcp_update_bw(struct qed_hwfn *p_hwfn,
+ struct qed_ptt *p_ptt)
+{
+ struct qed_mcp_function_info *p_info;
+ struct public_func shmem_info;
+ u32 resp = 0, param = 0;
+
+ qed_mcp_get_shmem_func(p_hwfn, p_ptt, &shmem_info,
+ MCP_PF_ID(p_hwfn));
+
+ qed_read_pf_bandwidth(p_hwfn, &shmem_info);
+
+ p_info = &p_hwfn->mcp_info->func_info;
+
+ qed_configure_pf_max_bandwidth(p_hwfn->cdev, p_info->bandwidth_max);
+
+ /* Acknowledge the MFW */
+ qed_mcp_cmd(p_hwfn, p_ptt, DRV_MSG_CODE_BW_UPDATE_ACK, 0, &resp,
+ ¶m);
+}
+
int qed_mcp_handle_events(struct qed_hwfn *p_hwfn,
struct qed_ptt *p_ptt)
{
@@ -679,6 +748,9 @@ int qed_mcp_handle_events(struct qed_hwfn *p_hwfn,
case MFW_DRV_MSG_TRANSCEIVER_STATE_CHANGE:
qed_mcp_handle_transceiver_change(p_hwfn, p_ptt);
break;
+ case MFW_DRV_MSG_BW_UPDATE:
+ qed_mcp_update_bw(p_hwfn, p_ptt);
+ break;
default:
DP_NOTICE(p_hwfn, "Unimplemented MFW message %d\n", i);
rc = -EINVAL;
@@ -758,28 +830,6 @@ int qed_mcp_get_media_type(struct qed_dev *cdev,
return 0;
}
-static u32 qed_mcp_get_shmem_func(struct qed_hwfn *p_hwfn,
- struct qed_ptt *p_ptt,
- struct public_func *p_data,
- int pfid)
-{
- u32 addr = SECTION_OFFSIZE_ADDR(p_hwfn->mcp_info->public_base,
- PUBLIC_FUNC);
- u32 mfw_path_offsize = qed_rd(p_hwfn, p_ptt, addr);
- u32 func_addr = SECTION_ADDR(mfw_path_offsize, pfid);
- u32 i, size;
-
- memset(p_data, 0, sizeof(*p_data));
-
- size = min_t(u32, sizeof(*p_data),
- QED_SECTION_SIZE(mfw_path_offsize));
- for (i = 0; i < size / sizeof(u32); i++)
- ((u32 *)p_data)[i] = qed_rd(p_hwfn, p_ptt,
- func_addr + (i << 2));
-
- return size;
-}
-
static int
qed_mcp_get_shmem_proto(struct qed_hwfn *p_hwfn,
struct public_func *p_info,
@@ -818,26 +868,7 @@ int qed_mcp_fill_shmem_func_info(struct qed_hwfn *p_hwfn,
return -EINVAL;
}
-
- info->bandwidth_min = (shmem_info.config &
- FUNC_MF_CFG_MIN_BW_MASK) >>
- FUNC_MF_CFG_MIN_BW_SHIFT;
- if (info->bandwidth_min < 1 || info->bandwidth_min > 100) {
- DP_INFO(p_hwfn,
- "bandwidth minimum out of bounds [%02x]. Set to 1\n",
- info->bandwidth_min);
- info->bandwidth_min = 1;
- }
-
- info->bandwidth_max = (shmem_info.config &
- FUNC_MF_CFG_MAX_BW_MASK) >>
- FUNC_MF_CFG_MAX_BW_SHIFT;
- if (info->bandwidth_max < 1 || info->bandwidth_max > 100) {
- DP_INFO(p_hwfn,
- "bandwidth maximum out of bounds [%02x]. Set to 100\n",
- info->bandwidth_max);
- info->bandwidth_max = 100;
- }
+ qed_read_pf_bandwidth(p_hwfn, &shmem_info);
if (shmem_info.mac_upper || shmem_info.mac_lower) {
info->mac[0] = (u8)(shmem_info.mac_upper >> 8);
@@ -938,9 +969,10 @@ qed_mcp_send_drv_version(struct qed_hwfn *p_hwfn,
p_drv_version = &union_data.drv_version;
p_drv_version->version = p_ver->version;
+
for (i = 0; i < MCP_DRV_VER_STR_SIZE - 1; i += 4) {
val = cpu_to_be32(p_ver->name[i]);
- *(u32 *)&p_drv_version->name[i * sizeof(u32)] = val;
+ *(__be32 *)&p_drv_version->name[i * sizeof(u32)] = val;
}
memset(&mb_params, 0, sizeof(mb_params));
diff --git a/drivers/net/ethernet/qlogic/qed/qed_mcp.h b/drivers/net/ethernet/qlogic/qed/qed_mcp.h
index 50917a2..29a51ad 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_mcp.h
+++ b/drivers/net/ethernet/qlogic/qed/qed_mcp.h
@@ -40,7 +40,13 @@ struct qed_mcp_link_capabilities {
struct qed_mcp_link_state {
bool link_up;
- u32 speed; /* In Mb/s */
+ /* Actual link speed in Mb/s */
+ u32 line_speed;
+
+ /* PF max speed in Mb/s, deduced from line_speed
+ * according to PF max bandwidth configuration.
+ */
+ u32 speed;
bool full_duplex;
bool an;
@@ -388,5 +394,9 @@ int qed_mcp_reset(struct qed_hwfn *p_hwfn,
* @return true iff MFW is running and mcp_info is initialized
*/
bool qed_mcp_is_init(struct qed_hwfn *p_hwfn);
-
+int qed_configure_pf_max_bandwidth(struct qed_dev *cdev, u8 max_bw);
+int __qed_configure_pf_max_bandwidth(struct qed_hwfn *p_hwfn,
+ struct qed_ptt *p_ptt,
+ struct qed_mcp_link_state *p_link,
+ u8 max_bw);
#endif
--
2.7.2
^ permalink raw reply related
* [PATCH net-next 3/3] qed: Add PF min bandwidth configuration support
From: Manish Chopra @ 2016-04-26 14:56 UTC (permalink / raw)
To: davem; +Cc: netdev, Ariel.Elior, Yuval.Mintz
In-Reply-To: <1461682570-745-1-git-send-email-manish.chopra@qlogic.com>
This patch adds support for PF minimum bandwidth update
or configuration notified by management firmware.
Signed-off-by: Manish Chopra <manish.chopra@qlogic.com>
Signed-off-by: Yuval Mintz <Yuval.Mintz@qlogic.com>
---
drivers/net/ethernet/qlogic/qed/qed_dev.c | 71 ++++++++++++++++++++++
drivers/net/ethernet/qlogic/qed/qed_hsi.h | 2 +
.../net/ethernet/qlogic/qed/qed_init_fw_funcs.c | 15 +++++
drivers/net/ethernet/qlogic/qed/qed_mcp.c | 10 ++-
drivers/net/ethernet/qlogic/qed/qed_mcp.h | 7 +++
drivers/net/ethernet/qlogic/qed/qed_reg_addr.h | 1 +
6 files changed, 104 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/qlogic/qed/qed_dev.c b/drivers/net/ethernet/qlogic/qed/qed_dev.c
index 4e99108..b500c86 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_dev.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_dev.c
@@ -220,9 +220,13 @@ static int qed_init_qm_info(struct qed_hwfn *p_hwfn)
qm_info->start_vport = (u8)RESC_START(p_hwfn, QED_VPORT);
+ for (i = 0; i < qm_info->num_vports; i++)
+ qm_info->qm_vport_params[i].vport_wfq = 1;
+
qm_info->pf_wfq = 0;
qm_info->pf_rl = 0;
qm_info->vport_rl_en = 1;
+ qm_info->vport_wfq_en = 1;
return 0;
@@ -1841,3 +1845,70 @@ int qed_configure_pf_max_bandwidth(struct qed_dev *cdev, u8 max_bw)
return rc;
}
+
+int __qed_configure_pf_min_bandwidth(struct qed_hwfn *p_hwfn,
+ struct qed_ptt *p_ptt,
+ struct qed_mcp_link_state *p_link,
+ u8 min_bw)
+{
+ int rc = 0;
+
+ p_hwfn->mcp_info->func_info.bandwidth_min = min_bw;
+ p_hwfn->qm_info.pf_wfq = min_bw;
+
+ if (!p_link->line_speed)
+ return rc;
+
+ p_link->min_pf_rate = (p_link->line_speed * min_bw) / 100;
+
+ rc = qed_init_pf_wfq(p_hwfn, p_ptt, p_hwfn->rel_pf_id, min_bw);
+
+ DP_VERBOSE(p_hwfn, NETIF_MSG_LINK,
+ "Configured MIN bandwidth to be %d Mb/sec\n",
+ p_link->min_pf_rate);
+
+ return rc;
+}
+
+/* Main API to configure PF min bandwidth where bw range is [1-100] */
+int qed_configure_pf_min_bandwidth(struct qed_dev *cdev, u8 min_bw)
+{
+ int i, rc = -EINVAL;
+
+ if (min_bw < 1 || min_bw > 100) {
+ DP_NOTICE(cdev, "PF min bw valid range is [1-100]\n");
+ return rc;
+ }
+
+ for_each_hwfn(cdev, i) {
+ struct qed_hwfn *p_hwfn = &cdev->hwfns[i];
+ struct qed_hwfn *p_lead = QED_LEADING_HWFN(cdev);
+ struct qed_mcp_link_state *p_link;
+ struct qed_ptt *p_ptt;
+
+ p_link = &p_lead->mcp_info->link_output;
+
+ p_ptt = qed_ptt_acquire(p_hwfn);
+ if (!p_ptt)
+ return -EBUSY;
+
+ rc = __qed_configure_pf_min_bandwidth(p_hwfn, p_ptt,
+ p_link, min_bw);
+ if (rc) {
+ qed_ptt_release(p_hwfn, p_ptt);
+ return rc;
+ }
+
+ if (p_link->min_pf_rate) {
+ u32 min_rate = p_link->min_pf_rate;
+
+ rc = __qed_configure_vp_wfq_on_link_change(p_hwfn,
+ p_ptt,
+ min_rate);
+ }
+
+ qed_ptt_release(p_hwfn, p_ptt);
+ }
+
+ return rc;
+}
diff --git a/drivers/net/ethernet/qlogic/qed/qed_hsi.h b/drivers/net/ethernet/qlogic/qed/qed_hsi.h
index 81cf625..5aa78a9 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_hsi.h
+++ b/drivers/net/ethernet/qlogic/qed/qed_hsi.h
@@ -5116,6 +5116,8 @@ struct hw_set_image {
struct hw_set_info hw_sets[1];
};
+int qed_init_pf_wfq(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt,
+ u8 pf_id, u16 pf_wfq);
int qed_init_vport_wfq(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt,
u16 first_tx_pq_id[NUM_OF_TCS], u16 vport_wfq);
#endif
diff --git a/drivers/net/ethernet/qlogic/qed/qed_init_fw_funcs.c b/drivers/net/ethernet/qlogic/qed/qed_init_fw_funcs.c
index e646987..e8a3b9d 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_init_fw_funcs.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_init_fw_funcs.c
@@ -712,6 +712,21 @@ int qed_qm_pf_rt_init(struct qed_hwfn *p_hwfn,
return 0;
}
+int qed_init_pf_wfq(struct qed_hwfn *p_hwfn,
+ struct qed_ptt *p_ptt,
+ u8 pf_id, u16 pf_wfq)
+{
+ u32 inc_val = QM_WFQ_INC_VAL(pf_wfq);
+
+ if (!inc_val || inc_val > QM_WFQ_MAX_INC_VAL) {
+ DP_NOTICE(p_hwfn, "Invalid PF WFQ weight configuration");
+ return -1;
+ }
+
+ qed_wr(p_hwfn, p_ptt, QM_REG_WFQPFWEIGHT + pf_id * 4, inc_val);
+ return 0;
+}
+
int qed_init_pf_rl(struct qed_hwfn *p_hwfn,
struct qed_ptt *p_ptt,
u8 pf_id,
diff --git a/drivers/net/ethernet/qlogic/qed/qed_mcp.c b/drivers/net/ethernet/qlogic/qed/qed_mcp.c
index 578b09c..cb46dbd 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_mcp.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_mcp.c
@@ -472,8 +472,8 @@ static void qed_mcp_handle_link_change(struct qed_hwfn *p_hwfn,
bool b_reset)
{
struct qed_mcp_link_state *p_link;
+ u8 max_bw, min_bw;
u32 status = 0;
- u8 max_bw;
p_link = &p_hwfn->mcp_info->link_output;
memset(p_link, 0, sizeof(*p_link));
@@ -534,10 +534,15 @@ static void qed_mcp_handle_link_change(struct qed_hwfn *p_hwfn,
p_link->line_speed = 0;
max_bw = p_hwfn->mcp_info->func_info.bandwidth_max;
+ min_bw = p_hwfn->mcp_info->func_info.bandwidth_min;
- /* Correct speed according to bandwidth allocation */
+ /* Max bandwidth configuration */
__qed_configure_pf_max_bandwidth(p_hwfn, p_ptt, p_link, max_bw);
+ /* Min bandwidth configuration */
+ __qed_configure_pf_min_bandwidth(p_hwfn, p_ptt, p_link, min_bw);
+ qed_configure_vp_wfq_on_link_change(p_hwfn->cdev, p_link->min_pf_rate);
+
p_link->an = !!(status & LINK_STATUS_AUTO_NEGOTIATE_ENABLED);
p_link->an_complete = !!(status &
LINK_STATUS_AUTO_NEGOTIATE_COMPLETE);
@@ -710,6 +715,7 @@ static void qed_mcp_update_bw(struct qed_hwfn *p_hwfn,
p_info = &p_hwfn->mcp_info->func_info;
+ qed_configure_pf_min_bandwidth(p_hwfn->cdev, p_info->bandwidth_min);
qed_configure_pf_max_bandwidth(p_hwfn->cdev, p_info->bandwidth_max);
/* Acknowledge the MFW */
diff --git a/drivers/net/ethernet/qlogic/qed/qed_mcp.h b/drivers/net/ethernet/qlogic/qed/qed_mcp.h
index 29a51ad..608bcb2 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_mcp.h
+++ b/drivers/net/ethernet/qlogic/qed/qed_mcp.h
@@ -40,6 +40,8 @@ struct qed_mcp_link_capabilities {
struct qed_mcp_link_state {
bool link_up;
+ u32 min_pf_rate;
+
/* Actual link speed in Mb/s */
u32 line_speed;
@@ -394,9 +396,14 @@ int qed_mcp_reset(struct qed_hwfn *p_hwfn,
* @return true iff MFW is running and mcp_info is initialized
*/
bool qed_mcp_is_init(struct qed_hwfn *p_hwfn);
+int qed_configure_pf_min_bandwidth(struct qed_dev *cdev, u8 min_bw);
int qed_configure_pf_max_bandwidth(struct qed_dev *cdev, u8 max_bw);
int __qed_configure_pf_max_bandwidth(struct qed_hwfn *p_hwfn,
struct qed_ptt *p_ptt,
struct qed_mcp_link_state *p_link,
u8 max_bw);
+int __qed_configure_pf_min_bandwidth(struct qed_hwfn *p_hwfn,
+ struct qed_ptt *p_ptt,
+ struct qed_mcp_link_state *p_link,
+ u8 min_bw);
#endif
diff --git a/drivers/net/ethernet/qlogic/qed/qed_reg_addr.h b/drivers/net/ethernet/qlogic/qed/qed_reg_addr.h
index d2f5730..bf4d7cc 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_reg_addr.h
+++ b/drivers/net/ethernet/qlogic/qed/qed_reg_addr.h
@@ -458,5 +458,6 @@
#define PBF_REG_NGE_COMP_VER 0xd80524UL
#define PRS_REG_NGE_COMP_VER 0x1f0878UL
+#define QM_REG_WFQPFWEIGHT 0x2f4e80UL
#define QM_REG_WFQVPWEIGHT 0x2fa000UL
#endif
--
2.7.2
^ permalink raw reply related
* Re: [PATCH net v2 1/3] drivers: net: cpsw: fix parsing of phy-handle DT property in dual_emac config
From: David Rivshin (Allworx) @ 2016-04-26 15:27 UTC (permalink / raw)
To: Grygorii Strashko, David Miller; +Cc: netdev, linux-omap, Mugunthan V N
In-Reply-To: <571E6C7F.10704@ti.com>
On Mon, 25 Apr 2016 22:14:07 +0300
Grygorii Strashko <grygorii.strashko@ti.com> wrote:
> On 04/22/2016 04:03 PM, Grygorii Strashko wrote:
> > On 04/21/2016 09:19 PM, David Rivshin (Allworx) wrote:
> >> From: David Rivshin <drivshin@allworx.com>
> >>
> >> Commit 9e42f715264ff158478fa30eaed847f6e131366b ("drivers: net: cpsw: add
> >> phy-handle parsing") saved the "phy-handle" phandle into a new cpsw_priv
> >> field. However, phy connections are per-slave, so the phy_node field
> >> should
> >> be in cpsw_slave_data rather than cpsw_priv.
> >>
> >> This would go unnoticed in a single emac configuration. But in dual_emac
> >> mode, the last "phy-handle" property parsed for either slave would be
> >> used
> >> by both of them, causing them both to refer to the same phy_device.
> >>
> >> Fixes: 9e42f715264f ("drivers: net: cpsw: add phy-handle parsing")
> >> Signed-off-by: David Rivshin <drivshin@allworx.com>
> >> Tested-by: Nicolas Chauvet <kwizart@gmail.com>
> >> ---
> >> I would suggest this for -stable. It should apply cleanly as far back
> >> as 4.4.
> >>
> >> Changes since v1 [1]:
> >> - Rebased (no conflicts)
> >> - Added Tested-by from Nicolas Chauvet
> >>
> >> [1] https://patchwork.ozlabs.org/patch/560326/
> >
> > Reviewed-by: Grygorii Strashko <grygorii.strashko@ti.com>
>
> In my opinion, it will be good to have this patch merged as part of -rc cycle, since
> it will fix "NULL pointer dereference" issue with current LKML as reported by Andrew Goodbody.
Dave,
If you'd like to take just this first patch while enhancements for patch 2
are worked out, I'd have no problem with that. I would then just submit the
rest of the series separately. If I don't see that you've taken this by the
time I have a V3 ready I'll include it again, but it will be unchanged and
you can still take it separately if you wish. Or I can resubmit this patch
separately if you prefer.
(FYI, I tried to send this multiple times last night, but gmail has not
been my friend lately. I ended up having to trim the CC list substantially
just to get this out at all; apologies for that. Suggestions for other
email providers that are usable for patch submissions are welcome.)
^ permalink raw reply
* Re: [PATCH 4/5] batman-adv: Reduce refcnt of removed router when updating route
From: Sven Eckelmann @ 2016-04-26 15:00 UTC (permalink / raw)
To: Sergei Shtylyov
Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
b.a.t.m.a.n-ZwoEplunGu2X36UT3dwllkB+6BGkLq7r, Antonio Quartulli,
davem-fT/PcQaiUtIeIZ0/mPfg9Q, Marek Lindner
In-Reply-To: <83cedcb0-1090-2a0d-f3b8-c9c273c5f1d2-M4DtvfQ/ZS1MRgGoP+s0PdBPR1lH4CV8@public.gmane.org>
[-- Attachment #1: Type: text/plain, Size: 1009 bytes --]
On Tuesday 26 April 2016 17:42:54 Sergei Shtylyov wrote:
> > _batadv_update_route rcu_derefences orig_ifinfo->router outside of a
> > spinlock protected region to print some information messages to the debug
> > log. But this pointer is not checked again when the new pointer is assigned
> > in the spinlock protected region. Thus is can happen that the value of
>
> Thus is can? :-)
Yes, my fault. s/is/it/.
[...]
> > spin_lock_bh(&orig_node->neigh_list_lock);
> > + /* curr_router used earlier may not be the current orig_ifinfo->router
> > + * anymore because it was dereferenced outside of the neigh_list_lock
> > + * protected region. After the new best neighbor has replace the current
>
> Replaced.
>
> [...]
This one looks like one of Marek's modifications [1] to the patch. But I would
guess that he has nothing against adding a 'd'.
Should Antonio resent all the patches or is a different approach preferred?
Kind regards,
Sven
[1] https://patchwork.open-mesh.org/patch/15940/
[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 819 bytes --]
^ permalink raw reply
* Re: [PATCH 4/5] batman-adv: Reduce refcnt of removed router when updating route
From: Sergei Shtylyov @ 2016-04-26 14:42 UTC (permalink / raw)
To: Antonio Quartulli, davem-fT/PcQaiUtIeIZ0/mPfg9Q
Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
b.a.t.m.a.n-ZwoEplunGu2X36UT3dwllkB+6BGkLq7r, Marek Lindner
In-Reply-To: <1461641239-7097-5-git-send-email-a-2CpIooy/SPIKlTDg6p0iyA@public.gmane.org>
Hello.
On 4/26/2016 6:27 AM, Antonio Quartulli wrote:
> From: Sven Eckelmann <sven-KaDOiPu9UxWEi8DpZVb4nw@public.gmane.org>
>
> _batadv_update_route rcu_derefences orig_ifinfo->router outside of a
> spinlock protected region to print some information messages to the debug
> log. But this pointer is not checked again when the new pointer is assigned
> in the spinlock protected region. Thus is can happen that the value of
Thus is can? :-)
> orig_ifinfo->router changed in the meantime and thus the reference counter
> of the wrong router gets reduced after the spinlock protected region.
>
> Just rcu_dereferencing the value of orig_ifinfo->router inside the spinlock
> protected region (which also set the new pointer) is enough to get the
> correct old router object.
>
> Fixes: e1a5382f978b ("batman-adv: Make orig_node->router an rcu protected pointer")
> Signed-off-by: Sven Eckelmann <sven-KaDOiPu9UxWEi8DpZVb4nw@public.gmane.org>
> Signed-off-by: Marek Lindner <mareklindner-rVWd3aGhH2z5bpWLKbzFeg@public.gmane.org>
> Signed-off-by: Antonio Quartulli <a@unstable.cc>
> ---
> net/batman-adv/routing.c | 9 +++++++++
> 1 file changed, 9 insertions(+)
>
> diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c
> index 4dd646a52f1a..b781bf753250 100644
> --- a/net/batman-adv/routing.c
> +++ b/net/batman-adv/routing.c
> @@ -105,6 +105,15 @@ static void _batadv_update_route(struct batadv_priv *bat_priv,
> neigh_node = NULL;
>
> spin_lock_bh(&orig_node->neigh_list_lock);
> + /* curr_router used earlier may not be the current orig_ifinfo->router
> + * anymore because it was dereferenced outside of the neigh_list_lock
> + * protected region. After the new best neighbor has replace the current
Replaced.
[...]
MBR, Sergei
^ permalink raw reply
* Re: [PATCH] net/mlx5e: avoid stack overflow in mlx5e_open_channels
From: Saeed Mahameed @ 2016-04-26 14:41 UTC (permalink / raw)
To: Arnd Bergmann
Cc: Saeed Mahameed, Matan Barak, Leon Romanovsky, David S. Miller,
Achiad Shochat, Or Gerlitz, Amir Vadai, Tariq Toukan,
Linux Netdev List, linux-rdma-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <5940636.9Nic57IXcZ@wuerfel>
On Tue, Apr 26, 2016 at 4:53 PM, Arnd Bergmann <arnd-r2nGTMty4D4@public.gmane.org> wrote:
>
> Sure, do you want to just edit this when you forward the patch, or
> do you need me to do it?
>
Well, I won't say no if you want to do it :)
Saeed
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: codel: split into multiple files
From: Jens Axboe @ 2016-04-26 14:37 UTC (permalink / raw)
To: Michal Kazior, sedat.dilek; +Cc: David S. Miller, netdev@vger.kernel.org
In-Reply-To: <CA+BoTQmovjcYFA4JQBDNQwJHmu=MjZg_HnDn4+KbTi6vYcVV7A@mail.gmail.com>
On 04/26/2016 06:36 AM, Michal Kazior wrote:
> On 26 April 2016 at 08:43, Sedat Dilek <sedat.dilek@gmail.com> wrote:
>> On 4/26/16, Michal Kazior <michal.kazior@tieto.com> wrote:
>>> On 26 April 2016 at 08:09, Sedat Dilek <sedat.dilek@gmail.com> wrote:
>>>> Hi,
>>>>
>>>> I had a very quick view on net-next.git#master (up to commit
>>>> fab7b629a82da1b59620470d13152aff975239f6).
>>>>
>>>> Commit in [1] aka "codel: split into multiple files" removed codel.h
>>>> but [2] and [3] have relicts to it.
>>>> Forgot to remove?
>>>
>>> codel.h was not removed. diffstat for codel.h is all red which I
>>> presume is why you thought of it as removed, see:
>>>
>>> http://git.kernel.org/cgit/linux/kernel/git/davem/net-next.git/tree/include/net/codel.h?id=d068ca2ae2e614b9a418fb3b5f1fd4cf996ff032
>>>
>>
>> [ CC Jens ]
>>
>> OK.
>> So what are the plans in the future?
>> Keep a "generic" codel.h (compatibility reasons?) for net or is it your split?
>
> I'm interested in re-using codel in mac80211 for wireless. cfg80211
> drivers may want to do that as well later. Even vendor drivers could
> start to use it (I can dream :).
>
> I plan to re-spin my patches soonish re-based on the new codel.h/fq.h
> approach. There's quite a few spins already[1].
>
>
>> AFAICS I have seen a codel-implementation in block.git#wb-buf-throttle.
>> Does it make sense to have a more "super-generic" codel.h for re-use
>> (not only for net and block)?
>> Just a thought.
>
> Oh, I'm not really familiar with block and problems around it but it
> sounds reasonable and interesting. It doesn't look like it blatantly
> copies codel though (I did that in my initial mac80211 patches with
> some adjustments, you can check that in the link[1] which you can
> lookup via my patchset's cover letter[2]; I've based off of codel5[3]
> back then).
The block version is an adaptation, I guess you can say it pays homage
to CoDel. But there are a sufficient amount of differences between
networking and storage that I don't think a fully generic version is
really feasible. My favorite thing to bring up is the fact that we don't
have the luxury of dropping packets on the storage side...
--
Jens Axboe
^ permalink raw reply
* Re: [net-next PATCH 6/8] mlx4: Add support for inner IPv6 checksum offloads and TSO
From: Saeed Mahameed @ 2016-04-26 14:37 UTC (permalink / raw)
To: Alexander Duyck, talal, netdev, davem, galp, ogerlitz, eranbe
In-Reply-To: <20160425183133.11331.54774.stgit@ahduyck-xeon-server>
On 4/25/2016 9:31 PM, Alexander Duyck wrote:
> >From what I can tell the ConnectX-3 will support an inner IPv6 checksum and
> segmentation offload, however it cannot support outer IPv6 headers. For
> this reason I am adding the feature to the hw_enc_features and adding an
> extra check to the features_check call that will disable GSO and checksum
> offload in the case that the encapsulated frame has an outer IP version of
> that is not 4.
Hi Alex,
Can you share the testing commands of running vxlan over IPv6 and what
exactly didn't work for you ?
we would like to test this in house and understand what went wrong,
theoretically there shouldn't be a difference between IPv6/IPv4 outer
checksum offloading in ConnectX-3.
Anyway, I suspect it might be related to a driver bug most likely in
get_real_size function @en_tx.c
specifically in : *lso_header_size = (skb_inner_transport_header(skb) -
skb->data) + inner_tcp_hdrlen(skb);
will check this and get back to you.
for the mlx5 patches I will also go through them later today.
> Signed-off-by: Alexander Duyck <aduyck@mirantis.com>
> ---
> drivers/net/ethernet/mellanox/mlx4/en_netdev.c | 25 +++++++++++++++++++-----
> drivers/net/ethernet/mellanox/mlx4/en_tx.c | 15 ++++++++++++--
> 2 files changed, 33 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
> index bce37cbfde24..6f28ac58251c 100644
> --- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
> +++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
> @@ -2357,8 +2357,10 @@ out:
> }
>
> /* set offloads */
> - priv->dev->hw_enc_features |= NETIF_F_IP_CSUM | NETIF_F_RXCSUM |
> - NETIF_F_TSO | NETIF_F_GSO_UDP_TUNNEL |
> + priv->dev->hw_enc_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
> + NETIF_F_RXCSUM |
> + NETIF_F_TSO | NETIF_F_TSO6 |
> + NETIF_F_GSO_UDP_TUNNEL |
> NETIF_F_GSO_UDP_TUNNEL_CSUM |
> NETIF_F_GSO_PARTIAL;
> }
> @@ -2369,8 +2371,10 @@ static void mlx4_en_del_vxlan_offloads(struct work_struct *work)
> struct mlx4_en_priv *priv = container_of(work, struct mlx4_en_priv,
> vxlan_del_task);
> /* unset offloads */
> - priv->dev->hw_enc_features &= ~(NETIF_F_IP_CSUM | NETIF_F_RXCSUM |
> - NETIF_F_TSO | NETIF_F_GSO_UDP_TUNNEL |
> + priv->dev->hw_enc_features &= ~(NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
> + NETIF_F_RXCSUM |
> + NETIF_F_TSO | NETIF_F_TSO6 |
> + NETIF_F_GSO_UDP_TUNNEL |
> NETIF_F_GSO_UDP_TUNNEL_CSUM |
> NETIF_F_GSO_PARTIAL);
>
> @@ -2431,7 +2435,18 @@ static netdev_features_t mlx4_en_features_check(struct sk_buff *skb,
> netdev_features_t features)
> {
> features = vlan_features_check(skb, features);
> - return vxlan_features_check(skb, features);
> + features = vxlan_features_check(skb, features);
> +
> + /* The ConnectX-3 doesn't support outer IPv6 checksums but it does
> + * support inner IPv6 checksums and segmentation so we need to
> + * strip that feature if this is an IPv6 encapsulated frame.
> + */
> + if (skb->encapsulation &&
> + (skb->ip_summed == CHECKSUM_PARTIAL) &&
> + (ip_hdr(skb)->version != 4))
> + features &= ~(NETIF_F_CSUM_MASK | NETIF_F_GSO_MASK);
Dejavu, didn't you fix this already in harmonize_features, in
i.e, it is enough to do here:
if (skb->encapsulation && (skb->ip_summed == CHECKSUM_PARTIAL))
features &= ~NETIF_F_IPV6_CSUM;
> +
> + return features;
> }
> #endif
>
> diff --git a/drivers/net/ethernet/mellanox/mlx4/en_tx.c b/drivers/net/ethernet/mellanox/mlx4/en_tx.c
> index c0d7b7296236..c9f5388ea22a 100644
> --- a/drivers/net/ethernet/mellanox/mlx4/en_tx.c
> +++ b/drivers/net/ethernet/mellanox/mlx4/en_tx.c
> @@ -41,6 +41,7 @@
> #include <linux/vmalloc.h>
> #include <linux/tcp.h>
> #include <linux/ip.h>
> +#include <linux/ipv6.h>
> #include <linux/moduleparam.h>
>
> #include "mlx4_en.h"
> @@ -918,8 +919,18 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev)
> tx_ind, fragptr);
>
> if (skb->encapsulation) {
> - struct iphdr *ipv4 = (struct iphdr *)skb_inner_network_header(skb);
> - if (ipv4->protocol == IPPROTO_TCP || ipv4->protocol == IPPROTO_UDP)
> + union {
> + struct iphdr *v4;
> + struct ipv6hdr *v6;
> + unsigned char *hdr;
> + } ip;
> + u8 proto;
> +
> + ip.hdr = skb_inner_network_header(skb);
> + proto = (ip.v4->version == 4) ? ip.v4->protocol :
> + ip.v6->nexthdr;
> +
> + if (proto == IPPROTO_TCP || proto == IPPROTO_UDP)
> op_own |= cpu_to_be32(MLX4_WQE_CTRL_IIP | MLX4_WQE_CTRL_ILP);
> else
> op_own |= cpu_to_be32(MLX4_WQE_CTRL_IIP);
basically this is a bug fix, I don't know why the original author
assumed it will be ipv4 !
^ permalink raw reply
* [PATCH net-next 6/8] cxgb4: DCB message handler needs to use correct portid to netdev mapping
From: Hariprasad Shenai @ 2016-04-26 14:40 UTC (permalink / raw)
To: davem; +Cc: netdev, leedom, swise, nirranjan, santosh, Hariprasad Shenai
In-Reply-To: <1461681629-28275-1-git-send-email-hariprasad@chelsio.com>
Signed-off-by: Hariprasad Shenai <hariprasad@chelsio.com>
---
drivers/net/ethernet/chelsio/cxgb4/cxgb4_dcb.c | 2 +-
drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 5 +++--
2 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_dcb.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_dcb.c
index 052c660aca80..6ee2ed30626b 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_dcb.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_dcb.c
@@ -253,7 +253,7 @@ void cxgb4_dcb_handle_fw_update(struct adapter *adap,
{
const union fw_port_dcb *fwdcb = &pcmd->u.dcb;
int port = FW_PORT_CMD_PORTID_G(be32_to_cpu(pcmd->op_to_portid));
- struct net_device *dev = adap->port[port];
+ struct net_device *dev = adap->port[adap->chan_map[port]];
struct port_info *pi = netdev_priv(dev);
struct port_dcb_info *dcb = &pi->dcb;
int dcb_type = pcmd->u.dcb.pgid.type;
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
index abc425bfc744..4f627f3edb98 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
@@ -515,7 +515,7 @@ EXPORT_SYMBOL(cxgb4_dcb_enabled);
static void dcb_rpl(struct adapter *adap, const struct fw_port_cmd *pcmd)
{
int port = FW_PORT_CMD_PORTID_G(ntohl(pcmd->op_to_portid));
- struct net_device *dev = adap->port[port];
+ struct net_device *dev = adap->port[adap->chan_map[port]];
int old_dcb_enabled = cxgb4_dcb_enabled(dev);
int new_dcb_enabled;
@@ -645,7 +645,8 @@ static int fwevtq_handler(struct sge_rspq *q, const __be64 *rsp,
action == FW_PORT_ACTION_GET_PORT_INFO) {
int port = FW_PORT_CMD_PORTID_G(
be32_to_cpu(pcmd->op_to_portid));
- struct net_device *dev = q->adap->port[port];
+ struct net_device *dev =
+ q->adap->port[q->adap->chan_map[port]];
int state_input = ((pcmd->u.info.dcbxdis_pkd &
FW_PORT_CMD_DCBXDIS_F)
? CXGB4_DCB_INPUT_FW_DISABLED
--
2.3.4
^ permalink raw reply related
* [PATCH net-next 7/8] cxgb4: Don't assume FW_PORT_CMD reply is always port info msg
From: Hariprasad Shenai @ 2016-04-26 14:40 UTC (permalink / raw)
To: davem; +Cc: netdev, leedom, swise, nirranjan, santosh, Hariprasad Shenai
In-Reply-To: <1461681629-28275-1-git-send-email-hariprasad@chelsio.com>
The firmware can send a set of asynchronous replies through FW_PORT_CMD
with DCBX information when that's negotiated with the Link Peer. The old
code always assumed that a FW_PORT_CMD reply was always a Get Port
Information message. This change conditionalizes the code to only handle
the Get Port Information messages and throws a warning if we don't
understand what we've been given.
Also refactor t4_handle_fw_rpl() so that core functionality performed by
t4_handle_get_port_info() for a specified port.
Signed-off-by: Hariprasad Shenai <hariprasad@chelsio.com>
---
drivers/net/ethernet/chelsio/cxgb4/cxgb4.h | 1 +
drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | 110 +++++++++++++++++++----------
2 files changed, 74 insertions(+), 37 deletions(-)
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
index f69119bc5990..911fe11d32c6 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
@@ -1470,6 +1470,7 @@ int t4_ctrl_eq_free(struct adapter *adap, unsigned int mbox, unsigned int pf,
int t4_ofld_eq_free(struct adapter *adap, unsigned int mbox, unsigned int pf,
unsigned int vf, unsigned int eqid);
int t4_sge_ctxt_flush(struct adapter *adap, unsigned int mbox);
+void t4_handle_get_port_info(struct port_info *pi, const __be64 *rpl);
int t4_handle_fw_rpl(struct adapter *adap, const __be64 *rpl);
void t4_db_full(struct adapter *adapter);
void t4_db_dropped(struct adapter *adapter);
diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
index 1ebbbb9323e3..cf3efbf4a37a 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
@@ -7103,52 +7103,88 @@ int t4_ofld_eq_free(struct adapter *adap, unsigned int mbox, unsigned int pf,
}
/**
- * t4_handle_fw_rpl - process a FW reply message
- * @adap: the adapter
+ * t4_handle_get_port_info - process a FW reply message
+ * @pi: the port info
* @rpl: start of the FW message
*
- * Processes a FW message, such as link state change messages.
+ * Processes a GET_PORT_INFO FW reply message.
+ */
+void t4_handle_get_port_info(struct port_info *pi, const __be64 *rpl)
+{
+ const struct fw_port_cmd *p = (const void *)rpl;
+ struct adapter *adap = pi->adapter;
+
+ /* link/module state change message */
+ int speed = 0, fc = 0;
+ struct link_config *lc;
+ u32 stat = be32_to_cpu(p->u.info.lstatus_to_modtype);
+ int link_ok = (stat & FW_PORT_CMD_LSTATUS_F) != 0;
+ u32 mod = FW_PORT_CMD_MODTYPE_G(stat);
+
+ if (stat & FW_PORT_CMD_RXPAUSE_F)
+ fc |= PAUSE_RX;
+ if (stat & FW_PORT_CMD_TXPAUSE_F)
+ fc |= PAUSE_TX;
+ if (stat & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_100M))
+ speed = 100;
+ else if (stat & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_1G))
+ speed = 1000;
+ else if (stat & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_10G))
+ speed = 10000;
+ else if (stat & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_40G))
+ speed = 40000;
+
+ lc = &pi->link_cfg;
+
+ if (mod != pi->mod_type) {
+ pi->mod_type = mod;
+ t4_os_portmod_changed(adap, pi->port_id);
+ }
+ if (link_ok != lc->link_ok || speed != lc->speed ||
+ fc != lc->fc) { /* something changed */
+ lc->link_ok = link_ok;
+ lc->speed = speed;
+ lc->fc = fc;
+ lc->supported = be16_to_cpu(p->u.info.pcap);
+ t4_os_link_changed(adap, pi->port_id, link_ok);
+ }
+}
+
+/**
+ * t4_handle_fw_rpl - process a FW reply message
+ * @adap: the adapter
+ * @rpl: start of the FW message
+ *
+ * Processes a FW message, such as link state change messages.
*/
int t4_handle_fw_rpl(struct adapter *adap, const __be64 *rpl)
{
u8 opcode = *(const u8 *)rpl;
- if (opcode == FW_PORT_CMD) { /* link/module state change message */
- int speed = 0, fc = 0;
- const struct fw_port_cmd *p = (void *)rpl;
+ /* This might be a port command ... this simplifies the following
+ * conditionals ... We can get away with pre-dereferencing
+ * action_to_len16 because it's in the first 16 bytes and all messages
+ * will be at least that long.
+ */
+ const struct fw_port_cmd *p = (const void *)rpl;
+ unsigned int action =
+ FW_PORT_CMD_ACTION_G(be32_to_cpu(p->action_to_len16));
+
+ if (opcode == FW_PORT_CMD && action == FW_PORT_ACTION_GET_PORT_INFO) {
+ int i;
int chan = FW_PORT_CMD_PORTID_G(be32_to_cpu(p->op_to_portid));
- int port = adap->chan_map[chan];
- struct port_info *pi = adap2pinfo(adap, port);
- struct link_config *lc = &pi->link_cfg;
- u32 stat = be32_to_cpu(p->u.info.lstatus_to_modtype);
- int link_ok = (stat & FW_PORT_CMD_LSTATUS_F) != 0;
- u32 mod = FW_PORT_CMD_MODTYPE_G(stat);
-
- if (stat & FW_PORT_CMD_RXPAUSE_F)
- fc |= PAUSE_RX;
- if (stat & FW_PORT_CMD_TXPAUSE_F)
- fc |= PAUSE_TX;
- if (stat & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_100M))
- speed = 100;
- else if (stat & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_1G))
- speed = 1000;
- else if (stat & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_10G))
- speed = 10000;
- else if (stat & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_40G))
- speed = 40000;
-
- if (link_ok != lc->link_ok || speed != lc->speed ||
- fc != lc->fc) { /* something changed */
- lc->link_ok = link_ok;
- lc->speed = speed;
- lc->fc = fc;
- lc->supported = be16_to_cpu(p->u.info.pcap);
- t4_os_link_changed(adap, port, link_ok);
- }
- if (mod != pi->mod_type) {
- pi->mod_type = mod;
- t4_os_portmod_changed(adap, port);
+ struct port_info *pi = NULL;
+
+ for_each_port(adap, i) {
+ pi = adap2pinfo(adap, i);
+ if (pi->tx_chan == chan)
+ break;
}
+
+ t4_handle_get_port_info(pi, rpl);
+ } else {
+ dev_warn(adap->pdev_dev, "Unknown firmware reply %d\n", opcode);
+ return -EINVAL;
}
return 0;
}
--
2.3.4
^ permalink raw reply related
* [PATCH net-next 8/8] cxgb4: Decode link down reason code obtained from firmware
From: Hariprasad Shenai @ 2016-04-26 14:40 UTC (permalink / raw)
To: davem; +Cc: netdev, leedom, swise, nirranjan, santosh, Hariprasad Shenai
In-Reply-To: <1461681629-28275-1-git-send-email-hariprasad@chelsio.com>
Signed-off-by: Hariprasad Shenai <hariprasad@chelsio.com>
---
drivers/net/ethernet/chelsio/cxgb4/cxgb4.h | 1 +
drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | 34 +++++++++++++++++++++++++++
drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h | 5 ++++
3 files changed, 40 insertions(+)
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
index 911fe11d32c6..6af5242e6d21 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
@@ -396,6 +396,7 @@ struct link_config {
unsigned char fc; /* actual link flow control */
unsigned char autoneg; /* autonegotiating? */
unsigned char link_ok; /* link up? */
+ unsigned char link_down_rc; /* link down reason */
};
#define FW_LEN16(fw_struct) FW_CMD_LEN16_V(sizeof(fw_struct) / 16)
diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
index cf3efbf4a37a..7907d85efa4c 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
@@ -7103,6 +7103,32 @@ int t4_ofld_eq_free(struct adapter *adap, unsigned int mbox, unsigned int pf,
}
/**
+ * t4_link_down_rc_str - return a string for a Link Down Reason Code
+ * @adap: the adapter
+ * @link_down_rc: Link Down Reason Code
+ *
+ * Returns a string representation of the Link Down Reason Code.
+ */
+static const char *t4_link_down_rc_str(unsigned char link_down_rc)
+{
+ static const char * const reason[] = {
+ "Link Down",
+ "Remote Fault",
+ "Auto-negotiation Failure",
+ "Reserved",
+ "Insufficient Airflow",
+ "Unable To Determine Reason",
+ "No RX Signal Detected",
+ "Reserved",
+ };
+
+ if (link_down_rc >= ARRAY_SIZE(reason))
+ return "Bad Reason Code";
+
+ return reason[link_down_rc];
+}
+
+/**
* t4_handle_get_port_info - process a FW reply message
* @pi: the port info
* @rpl: start of the FW message
@@ -7142,6 +7168,14 @@ void t4_handle_get_port_info(struct port_info *pi, const __be64 *rpl)
}
if (link_ok != lc->link_ok || speed != lc->speed ||
fc != lc->fc) { /* something changed */
+ if (!link_ok && lc->link_ok) {
+ unsigned char rc = FW_PORT_CMD_LINKDNRC_G(stat);
+
+ lc->link_down_rc = rc;
+ dev_warn(adap->pdev_dev,
+ "Port %d link down, reason: %s\n",
+ pi->port_id, t4_link_down_rc_str(rc));
+ }
lc->link_ok = link_ok;
lc->speed = speed;
lc->fc = fc;
diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h b/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h
index 7ad6d4e75b2a..392d6644fdd8 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h
@@ -2510,6 +2510,11 @@ struct fw_port_cmd {
#define FW_PORT_CMD_PTYPE_G(x) \
(((x) >> FW_PORT_CMD_PTYPE_S) & FW_PORT_CMD_PTYPE_M)
+#define FW_PORT_CMD_LINKDNRC_S 5
+#define FW_PORT_CMD_LINKDNRC_M 0x7
+#define FW_PORT_CMD_LINKDNRC_G(x) \
+ (((x) >> FW_PORT_CMD_LINKDNRC_S) & FW_PORT_CMD_LINKDNRC_M)
+
#define FW_PORT_CMD_MODTYPE_S 0
#define FW_PORT_CMD_MODTYPE_M 0x1f
#define FW_PORT_CMD_MODTYPE_V(x) ((x) << FW_PORT_CMD_MODTYPE_S)
--
2.3.4
^ permalink raw reply related
* [PATCH net-next 5/8] cxgb4: Refactor t4_port_init function
From: Hariprasad Shenai @ 2016-04-26 14:40 UTC (permalink / raw)
To: davem; +Cc: netdev, leedom, swise, nirranjan, santosh, Hariprasad Shenai
In-Reply-To: <1461681629-28275-1-git-send-email-hariprasad@chelsio.com>
Refactor t4_port_init() so that the core functionality is done by
t4_init_portinfo() for a particular port. Also rename variables to
sensible ones.
Signed-off-by: Hariprasad Shenai <hariprasad@chelsio.com>
---
drivers/net/ethernet/chelsio/cxgb4/cxgb4.h | 2 +
drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | 93 +++++++++++++++++-------------
2 files changed, 55 insertions(+), 40 deletions(-)
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
index 459775884cad..f69119bc5990 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
@@ -1333,6 +1333,8 @@ int t4_init_sge_params(struct adapter *adapter);
int t4_init_tp_params(struct adapter *adap);
int t4_filter_field_shift(const struct adapter *adap, int filter_sel);
int t4_init_rss_mode(struct adapter *adap, int mbox);
+int t4_init_portinfo(struct port_info *pi, int mbox,
+ int port, int pf, int vf, u8 mac[]);
int t4_port_init(struct adapter *adap, int mbox, int pf, int vf);
void t4_fatal_err(struct adapter *adapter);
int t4_config_rss_range(struct adapter *adapter, int mbox, unsigned int viid,
diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
index 2ced24fc569d..1ebbbb9323e3 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
@@ -7668,61 +7668,74 @@ int t4_init_rss_mode(struct adapter *adap, int mbox)
return 0;
}
-int t4_port_init(struct adapter *adap, int mbox, int pf, int vf)
+/**
+ * t4_init_portinfo - allocate a virtual interface amd initialize port_info
+ * @pi: the port_info
+ * @mbox: mailbox to use for the FW command
+ * @port: physical port associated with the VI
+ * @pf: the PF owning the VI
+ * @vf: the VF owning the VI
+ * @mac: the MAC address of the VI
+ *
+ * Allocates a virtual interface for the given physical port. If @mac is
+ * not %NULL it contains the MAC address of the VI as assigned by FW.
+ * @mac should be large enough to hold an Ethernet address.
+ * Returns < 0 on error.
+ */
+int t4_init_portinfo(struct port_info *pi, int mbox,
+ int port, int pf, int vf, u8 mac[])
{
- u8 addr[6];
- int ret, i, j = 0;
+ int ret;
struct fw_port_cmd c;
- struct fw_rss_vi_config_cmd rvc;
+ unsigned int rss_size;
memset(&c, 0, sizeof(c));
- memset(&rvc, 0, sizeof(rvc));
+ c.op_to_portid = cpu_to_be32(FW_CMD_OP_V(FW_PORT_CMD) |
+ FW_CMD_REQUEST_F | FW_CMD_READ_F |
+ FW_PORT_CMD_PORTID_V(port));
+ c.action_to_len16 = cpu_to_be32(
+ FW_PORT_CMD_ACTION_V(FW_PORT_ACTION_GET_PORT_INFO) |
+ FW_LEN16(c));
+ ret = t4_wr_mbox(pi->adapter, mbox, &c, sizeof(c), &c);
+ if (ret)
+ return ret;
+
+ ret = t4_alloc_vi(pi->adapter, mbox, port, pf, vf, 1, mac, &rss_size);
+ if (ret < 0)
+ return ret;
+
+ pi->viid = ret;
+ pi->tx_chan = port;
+ pi->lport = port;
+ pi->rss_size = rss_size;
+
+ ret = be32_to_cpu(c.u.info.lstatus_to_modtype);
+ pi->mdio_addr = (ret & FW_PORT_CMD_MDIOCAP_F) ?
+ FW_PORT_CMD_MDIOADDR_G(ret) : -1;
+ pi->port_type = FW_PORT_CMD_PTYPE_G(ret);
+ pi->mod_type = FW_PORT_MOD_TYPE_NA;
+
+ init_link_config(&pi->link_cfg, be16_to_cpu(c.u.info.pcap));
+ return 0;
+}
+
+int t4_port_init(struct adapter *adap, int mbox, int pf, int vf)
+{
+ u8 addr[6];
+ int ret, i, j = 0;
for_each_port(adap, i) {
- unsigned int rss_size;
- struct port_info *p = adap2pinfo(adap, i);
+ struct port_info *pi = adap2pinfo(adap, i);
while ((adap->params.portvec & (1 << j)) == 0)
j++;
- c.op_to_portid = cpu_to_be32(FW_CMD_OP_V(FW_PORT_CMD) |
- FW_CMD_REQUEST_F | FW_CMD_READ_F |
- FW_PORT_CMD_PORTID_V(j));
- c.action_to_len16 = cpu_to_be32(
- FW_PORT_CMD_ACTION_V(FW_PORT_ACTION_GET_PORT_INFO) |
- FW_LEN16(c));
- ret = t4_wr_mbox(adap, mbox, &c, sizeof(c), &c);
+ ret = t4_init_portinfo(pi, mbox, j, pf, vf, addr);
if (ret)
return ret;
- ret = t4_alloc_vi(adap, mbox, j, pf, vf, 1, addr, &rss_size);
- if (ret < 0)
- return ret;
-
- p->viid = ret;
- p->tx_chan = j;
- p->lport = j;
- p->rss_size = rss_size;
memcpy(adap->port[i]->dev_addr, addr, ETH_ALEN);
adap->port[i]->dev_port = j;
-
- ret = be32_to_cpu(c.u.info.lstatus_to_modtype);
- p->mdio_addr = (ret & FW_PORT_CMD_MDIOCAP_F) ?
- FW_PORT_CMD_MDIOADDR_G(ret) : -1;
- p->port_type = FW_PORT_CMD_PTYPE_G(ret);
- p->mod_type = FW_PORT_MOD_TYPE_NA;
-
- rvc.op_to_viid =
- cpu_to_be32(FW_CMD_OP_V(FW_RSS_VI_CONFIG_CMD) |
- FW_CMD_REQUEST_F | FW_CMD_READ_F |
- FW_RSS_VI_CONFIG_CMD_VIID(p->viid));
- rvc.retval_len16 = cpu_to_be32(FW_LEN16(rvc));
- ret = t4_wr_mbox(adap, mbox, &rvc, sizeof(rvc), &rvc);
- if (ret)
- return ret;
- p->rss_mode = be32_to_cpu(rvc.u.basicvirtual.defaultq_to_udpen);
-
- init_link_config(&p->link_cfg, be16_to_cpu(c.u.info.pcap));
j++;
}
return 0;
--
2.3.4
^ permalink raw reply related
* [PATCH net-next 4/8] cxgb4: Properly decode port module type
From: Hariprasad Shenai @ 2016-04-26 14:40 UTC (permalink / raw)
To: davem; +Cc: netdev, leedom, swise, nirranjan, santosh, Hariprasad Shenai
In-Reply-To: <1461681629-28275-1-git-send-email-hariprasad@chelsio.com>
Decode and log port module error, unknown modules and unsupported
modules.
Signed-off-by: Hariprasad Shenai <hariprasad@chelsio.com>
---
drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
index b8dc7921b258..abc425bfc744 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
@@ -337,6 +337,17 @@ void t4_os_portmod_changed(const struct adapter *adap, int port_id)
netdev_info(dev, "port module unplugged\n");
else if (pi->mod_type < ARRAY_SIZE(mod_str))
netdev_info(dev, "%s module inserted\n", mod_str[pi->mod_type]);
+ else if (pi->mod_type == FW_PORT_MOD_TYPE_NOTSUPPORTED)
+ netdev_info(dev, "%s: unsupported port module inserted\n",
+ dev->name);
+ else if (pi->mod_type == FW_PORT_MOD_TYPE_UNKNOWN)
+ netdev_info(dev, "%s: unknown port module inserted\n",
+ dev->name);
+ else if (pi->mod_type == FW_PORT_MOD_TYPE_ERROR)
+ netdev_info(dev, "%s: transceiver module error\n", dev->name);
+ else
+ netdev_info(dev, "%s: unknown module type %d inserted\n",
+ dev->name, pi->mod_type);
}
int dbfifo_int_thresh = 10; /* 10 == 640 entry threshold */
--
2.3.4
^ permalink raw reply related
* [PATCH net-next 3/8] cxgb4: Avoids race and deadlock while freeing tx descriptor
From: Hariprasad Shenai @ 2016-04-26 14:40 UTC (permalink / raw)
To: davem; +Cc: netdev, leedom, swise, nirranjan, santosh, Hariprasad Shenai
In-Reply-To: <1461681629-28275-1-git-send-email-hariprasad@chelsio.com>
There could be race between t4_eth_xmit() and t4_free_sge_resources() while
freeing tx descriptors, take txq lock in t4_free_sge_resources(). We need
to stop the xmit frame path which runs in bottom half context while
unloading the driver using _bh variant of the lock. This is to prevent
the deadlock between xmit and driver unload.
Signed-off-by: Hariprasad Shenai <hariprasad@chelsio.com>
---
drivers/net/ethernet/chelsio/cxgb4/sge.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/net/ethernet/chelsio/cxgb4/sge.c b/drivers/net/ethernet/chelsio/cxgb4/sge.c
index 6278e5a74b74..bad253beb8c8 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/sge.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/sge.c
@@ -3006,7 +3006,9 @@ void t4_free_sge_resources(struct adapter *adap)
if (etq->q.desc) {
t4_eth_eq_free(adap, adap->mbox, adap->pf, 0,
etq->q.cntxt_id);
+ __netif_tx_lock_bh(etq->txq);
free_tx_desc(adap, &etq->q, etq->q.in_use, true);
+ __netif_tx_unlock_bh(etq->txq);
kfree(etq->q.sdesc);
free_txq(adap, &etq->q);
}
--
2.3.4
^ permalink raw reply related
* [PATCH net-next 2/8] cxgb4: Add llseek operation for flash debugfs entry
From: Hariprasad Shenai @ 2016-04-26 14:40 UTC (permalink / raw)
To: davem; +Cc: netdev, leedom, swise, nirranjan, santosh, Hariprasad Shenai
In-Reply-To: <1461681629-28275-1-git-send-email-hariprasad@chelsio.com>
Signed-off-by: Hariprasad Shenai <hariprasad@chelsio.com>
---
drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c
index 0bb41e9b9b1c..9506c5cd11b9 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c
@@ -1572,6 +1572,7 @@ static const struct file_operations flash_debugfs_fops = {
.owner = THIS_MODULE,
.open = mem_open,
.read = flash_read,
+ .llseek = default_llseek,
};
static inline void tcamxy2valmask(u64 x, u64 y, u8 *addr, u64 *mask)
--
2.3.4
^ permalink raw reply related
* [PATCH net-next 1/8] cxgb4: add new routine to get adapter info
From: Hariprasad Shenai @ 2016-04-26 14:40 UTC (permalink / raw)
To: davem; +Cc: netdev, leedom, swise, nirranjan, santosh, Hariprasad Shenai
In-Reply-To: <1461681629-28275-1-git-send-email-hariprasad@chelsio.com>
Add new routine to print out general adapter information (various version
numbers, adapter name, part number, serial number, etc.) and remove
redundant information dumped in the Port Information.
Signed-off-by: Hariprasad Shenai <hariprasad@chelsio.com>
---
drivers/net/ethernet/chelsio/cxgb4/cxgb4.h | 4 ++
drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 78 ++++++++++++++++++++++---
drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | 14 +++++
drivers/net/ethernet/chelsio/cxgb4/t4_hw.h | 7 +++
4 files changed, 95 insertions(+), 8 deletions(-)
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
index 326d4009525e..459775884cad 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
@@ -324,7 +324,9 @@ struct adapter_params {
unsigned int sf_fw_start; /* start of FW image in flash */
unsigned int fw_vers;
+ unsigned int bs_vers; /* bootstrap version */
unsigned int tp_vers;
+ unsigned int er_vers; /* expansion ROM version */
u8 api_vers[7];
unsigned short mtus[NMTUS];
@@ -731,6 +733,7 @@ struct adapter {
u32 t4_bar0;
struct pci_dev *pdev;
struct device *pdev_dev;
+ const char *name;
unsigned int mbox;
unsigned int pf;
unsigned int flags;
@@ -1306,6 +1309,7 @@ int t4_fl_pkt_align(struct adapter *adap);
unsigned int t4_flash_cfg_addr(struct adapter *adapter);
int t4_check_fw_version(struct adapter *adap);
int t4_get_fw_version(struct adapter *adapter, u32 *vers);
+int t4_get_bs_version(struct adapter *adapter, u32 *vers);
int t4_get_tp_version(struct adapter *adapter, u32 *vers);
int t4_get_exprom_version(struct adapter *adapter, u32 *vers);
int t4_prep_fw(struct adapter *adap, struct fw_info *fw_info,
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
index a1e329ec24cd..b8dc7921b258 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
@@ -3738,7 +3738,10 @@ static int adap_init0(struct adapter *adap)
* is excessively mismatched relative to the driver.)
*/
t4_get_fw_version(adap, &adap->params.fw_vers);
+ t4_get_bs_version(adap, &adap->params.bs_vers);
t4_get_tp_version(adap, &adap->params.tp_vers);
+ t4_get_exprom_version(adap, &adap->params.er_vers);
+
ret = t4_check_fw_version(adap);
/* If firmware is too old (not supported by driver) force an update. */
if (ret)
@@ -4652,6 +4655,68 @@ static void cxgb4_check_pcie_caps(struct adapter *adap)
"suggested for optimal performance.\n");
}
+/* Dump basic information about the adapter */
+static void print_adapter_info(struct adapter *adapter)
+{
+ /* Device information */
+ dev_info(adapter->pdev_dev, "Chelsio %s rev %d\n",
+ adapter->params.vpd.id,
+ CHELSIO_CHIP_RELEASE(adapter->params.chip));
+ dev_info(adapter->pdev_dev, "S/N: %s, P/N: %s\n",
+ adapter->params.vpd.sn, adapter->params.vpd.pn);
+
+ /* Firmware Version */
+ if (!adapter->params.fw_vers)
+ dev_warn(adapter->pdev_dev, "No firmware loaded\n");
+ else
+ dev_info(adapter->pdev_dev, "Firmware version: %u.%u.%u.%u\n",
+ FW_HDR_FW_VER_MAJOR_G(adapter->params.fw_vers),
+ FW_HDR_FW_VER_MINOR_G(adapter->params.fw_vers),
+ FW_HDR_FW_VER_MICRO_G(adapter->params.fw_vers),
+ FW_HDR_FW_VER_BUILD_G(adapter->params.fw_vers));
+
+ /* Bootstrap Firmware Version. (Some adapters don't have Bootstrap
+ * Firmware, so dev_info() is more appropriate here.)
+ */
+ if (!adapter->params.bs_vers)
+ dev_info(adapter->pdev_dev, "No bootstrap loaded\n");
+ else
+ dev_info(adapter->pdev_dev, "Bootstrap version: %u.%u.%u.%u\n",
+ FW_HDR_FW_VER_MAJOR_G(adapter->params.bs_vers),
+ FW_HDR_FW_VER_MINOR_G(adapter->params.bs_vers),
+ FW_HDR_FW_VER_MICRO_G(adapter->params.bs_vers),
+ FW_HDR_FW_VER_BUILD_G(adapter->params.bs_vers));
+
+ /* TP Microcode Version */
+ if (!adapter->params.tp_vers)
+ dev_warn(adapter->pdev_dev, "No TP Microcode loaded\n");
+ else
+ dev_info(adapter->pdev_dev,
+ "TP Microcode version: %u.%u.%u.%u\n",
+ FW_HDR_FW_VER_MAJOR_G(adapter->params.tp_vers),
+ FW_HDR_FW_VER_MINOR_G(adapter->params.tp_vers),
+ FW_HDR_FW_VER_MICRO_G(adapter->params.tp_vers),
+ FW_HDR_FW_VER_BUILD_G(adapter->params.tp_vers));
+
+ /* Expansion ROM version */
+ if (!adapter->params.er_vers)
+ dev_info(adapter->pdev_dev, "No Expansion ROM loaded\n");
+ else
+ dev_info(adapter->pdev_dev,
+ "Expansion ROM version: %u.%u.%u.%u\n",
+ FW_HDR_FW_VER_MAJOR_G(adapter->params.er_vers),
+ FW_HDR_FW_VER_MINOR_G(adapter->params.er_vers),
+ FW_HDR_FW_VER_MICRO_G(adapter->params.er_vers),
+ FW_HDR_FW_VER_BUILD_G(adapter->params.er_vers));
+
+ /* Software/Hardware configuration */
+ dev_info(adapter->pdev_dev, "Configuration: %sNIC %s, %s capable\n",
+ is_offload(adapter) ? "R" : "",
+ ((adapter->flags & USING_MSIX) ? "MSI-X" :
+ (adapter->flags & USING_MSI) ? "MSI" : ""),
+ is_offload(adapter) ? "Offload" : "non-Offload");
+}
+
static void print_port_info(const struct net_device *dev)
{
char buf[80];
@@ -4679,14 +4744,8 @@ static void print_port_info(const struct net_device *dev)
--bufp;
sprintf(bufp, "BASE-%s", t4_get_port_type_description(pi->port_type));
- netdev_info(dev, "Chelsio %s rev %d %s %sNIC %s\n",
- adap->params.vpd.id,
- CHELSIO_CHIP_RELEASE(adap->params.chip), buf,
- is_offload(adap) ? "R" : "",
- (adap->flags & USING_MSIX) ? " MSI-X" :
- (adap->flags & USING_MSI) ? " MSI" : "");
- netdev_info(dev, "S/N: %s, P/N: %s\n",
- adap->params.vpd.sn, adap->params.vpd.pn);
+ netdev_info(dev, "%s: Chelsio %s (%s) %s\n",
+ dev->name, adap->params.vpd.id, adap->name, buf);
}
static void enable_pcie_relaxed_ordering(struct pci_dev *dev)
@@ -4844,6 +4903,7 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
adapter->regs = regs;
adapter->pdev = pdev;
adapter->pdev_dev = &pdev->dev;
+ adapter->name = pci_name(pdev);
adapter->mbox = func;
adapter->pf = func;
adapter->msg_enable = dflt_msg_enable;
@@ -5074,6 +5134,8 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
if (is_offload(adapter))
attach_ulds(adapter);
+ print_adapter_info(adapter);
+
sriov:
#ifdef CONFIG_PCI_IOV
if (func < ARRAY_SIZE(num_vf) && num_vf[func] > 0)
diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
index 71586a3e0f61..2ced24fc569d 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
@@ -2937,6 +2937,20 @@ int t4_get_fw_version(struct adapter *adapter, u32 *vers)
}
/**
+ * t4_get_bs_version - read the firmware bootstrap version
+ * @adapter: the adapter
+ * @vers: where to place the version
+ *
+ * Reads the FW Bootstrap version from flash.
+ */
+int t4_get_bs_version(struct adapter *adapter, u32 *vers)
+{
+ return t4_read_flash(adapter, FLASH_FWBOOTSTRAP_START +
+ offsetof(struct fw_hdr, fw_ver), 1,
+ vers, 0);
+}
+
+/**
* t4_get_tp_version - read the TP microcode version
* @adapter: the adapter
* @vers: where to place the version
diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.h b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.h
index 2fc60e83a7a1..7f59ca458431 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.h
@@ -220,6 +220,13 @@ enum {
FLASH_FW_START = FLASH_START(FLASH_FW_START_SEC),
FLASH_FW_MAX_SIZE = FLASH_MAX_SIZE(FLASH_FW_NSECS),
+ /* Location of bootstrap firmware image in FLASH.
+ */
+ FLASH_FWBOOTSTRAP_START_SEC = 27,
+ FLASH_FWBOOTSTRAP_NSECS = 1,
+ FLASH_FWBOOTSTRAP_START = FLASH_START(FLASH_FWBOOTSTRAP_START_SEC),
+ FLASH_FWBOOTSTRAP_MAX_SIZE = FLASH_MAX_SIZE(FLASH_FWBOOTSTRAP_NSECS),
+
/*
* iSCSI persistent/crash information.
*/
--
2.3.4
^ permalink raw reply related
* [PATCH net-next 0/8] cxgb4: minor fixes, decode msgs and code refactor for few functions
From: Hariprasad Shenai @ 2016-04-26 14:40 UTC (permalink / raw)
To: davem; +Cc: netdev, leedom, swise, nirranjan, santosh, Hariprasad Shenai
Hi
This patch series adds new routine to get adapter information and removes
some redundant messages logged in dmesg. Fixes race while freeing tx
descriptors. Decodes module type and link down reason codes obtained from
firmware. Refactor port initialization and FW_PORT_CMD handling. Pass
correct port id in DCB message handler to obtain netdev associated.
This patch series has been created against net-next tree and includes
patches on cxgb4 driver.
We have included all the maintainers of respective drivers. Kindly review
the change and let us know in case of any review comments.
Thanks
Hariprasad Shenai (8):
cxgb4: add new routine to get adapter info
cxgb4: Add llseek operation for flash debugfs entry
cxgb4: Avoids race and deadlock while freeing tx descriptor
cxgb4: Properly decode port module type
cxgb4: Refactor t4_port_init function
cxgb4: DCB message handler needs to use correct portid to netdev
mapping
cxgb4: Don't assume FW_PORT_CMD reply is always port info msg
cxgb4: Decode link down reason code obtained from firmware
drivers/net/ethernet/chelsio/cxgb4/cxgb4.h | 8 +
drivers/net/ethernet/chelsio/cxgb4/cxgb4_dcb.c | 2 +-
drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c | 1 +
drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 94 +++++++-
drivers/net/ethernet/chelsio/cxgb4/sge.c | 2 +
drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | 249 ++++++++++++++-------
drivers/net/ethernet/chelsio/cxgb4/t4_hw.h | 7 +
drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h | 5 +
8 files changed, 281 insertions(+), 87 deletions(-)
--
2.3.4
^ permalink raw reply
* Re: [net-next PATCH 4/4] samples/bpf: allow make to be run from samples/bpf/ directory
From: Alexei Starovoitov @ 2016-04-26 14:35 UTC (permalink / raw)
To: Jesper Dangaard Brouer; +Cc: netdev, bblanco, borkmann, linux-kbuild
In-Reply-To: <20160426110932.20716.51360.stgit@firesoul>
On Tue, Apr 26, 2016 at 01:09:32PM +0200, Jesper Dangaard Brouer wrote:
> It is not intuitive that 'make' must be run from the top level
> directory with argument "samples/bpf/" to compile these eBPF samples.
>
> Introduce a kbuild make file trick that allow make to be run from the
> "samples/bpf/" directory itself. It basically change to the top level
> directory and call "make samples/bpf/" with the "/" slash after the
> directory name.
>
> Also add a clean target that only cleans this directory, by taking
> advantage of the kbuild external module setting M=$PWD.
>
> Signed-off-by: Jesper Dangaard Brouer <brouer@redhat.com>
> ---
> samples/bpf/Makefile | 8 ++++++++
> samples/bpf/README.rst | 3 +++
> 2 files changed, 11 insertions(+)
>
> diff --git a/samples/bpf/Makefile b/samples/bpf/Makefile
> index 7ac66f5bbbf5..7370dfee482f 100644
> --- a/samples/bpf/Makefile
> +++ b/samples/bpf/Makefile
> @@ -85,6 +85,14 @@ HOSTLOADLIBES_test_overhead += -lelf -lrt
> # make samples/bpf/ LLC=~/git/llvm/build/bin/llc
> LLC ?= llc
>
> +# Trick to allow make to be run from this directory
> +all:
> + $(MAKE) -C ../../ $$PWD/
> +
> +clean:
> + $(MAKE) -C ../../ M=$$PWD clean
> + @rm -f *~
> +
nice trick!
^ permalink raw reply
* Re: [net-next PATCH 3/4] samples/bpf: add a README file to get users started
From: Alexei Starovoitov @ 2016-04-26 14:34 UTC (permalink / raw)
To: Daniel Borkmann
Cc: Jesper Dangaard Brouer, netdev, bblanco, borkmann, linux-kbuild
In-Reply-To: <571F61D6.50101@iogearbox.net>
On Tue, Apr 26, 2016 at 02:40:54PM +0200, Daniel Borkmann wrote:
> On 04/26/2016 01:56 PM, Jesper Dangaard Brouer wrote:
> >>>+Compiling requires having installed:
> >>>+ * clang
> >>>+ * llvm >= version 3.7.0
please change it to 3.7.1, since 3.7.0 had several bugs.
They're rare, but better to avoid the issue.
> >>>+
> >>>+Note that LLVM's tool 'llc' must support target 'bpf', list with command::
> >>>+
> >>>+ $ llc --version
> >>>+ LLVM (http://llvm.org/):
> >>>+ LLVM version 3.x.y
> >>>+ [...]
> >>>+ Host CPU: xxx
> >>>+
> >>>+ Registered Targets:
> >>>+ [...]
> >>>+ bpf - BPF (host endian)
> >>>+ bpfeb - BPF (big endian)
> >>>+ bpfel - BPF (little endian)
there always be 3 targets for bpf, since some folks need to cross-compile.
> >>>+Manually compiling LLVM with 'bpf' support
> >>>+------------------------------------------
> >>>+
> >>>+In some LLVM versions the BPF target were marked experimental. To
> >>>+compile LLVM manually and enable BPF target run (build dependencies
> >>>+are cmake and gcc-c++)::
> >>>+
> >>>+ $ git clone http://llvm.org/git/llvm.git
> >>>+ $ cd llvm
> >>>+ $ mkdir build; cd build
> >>>+ $ cmake .. -DLLVM_EXPERIMENTAL_TARGETS_TO_BUILD=BPF
> >>>+ $ make
> >>
> >>That's perhaps a bit misleading in the sense that when you clone the
> >>tree from git, you'd nowadays invoke cmake normally with LLVM_TARGETS_TO_BUILD
> >>instead of LLVM_EXPERIMENTAL_TARGETS_TO_BUILD for BPF, as BPF is not an
> >>experimental target anymore. It's probably also recommended to clone
> >>clang into tools/ dir as well under your llvm/ repo when you compile
> >>from scratch anyways.
yes. LLVM_EXPERIMENTAL_TARGETS_TO_BUILD is the thing of the past
when bpf was just merged into llvm < 3.7
By default llvm will build all non-experimental backends including bpf.
If you need to make llc binary smaller you can use:
-DLLVM_TARGETS_TO_BUILD="BPF;X86"
Also fedora and ubuntu ship with llvm that has bpf support.
> >Can you come up with a formulation/desc I can use instead then?
>
> You mean how to build with clang? There are various docs/snippets out
> there, for example, see the 'Build LLVM and Clang development libs'
> part of [1], that you can tweak for your README with.
>
> [1] https://gist.github.com/brendangregg/cfa482acb71aa577789c
yep. +1 for the link.
^ permalink raw reply
* Re: [PATCH v5 09/21] IB/hns: Add hca support
From: Jiri Pirko @ 2016-04-26 14:25 UTC (permalink / raw)
To: Leon Romanovsky
Cc: oulijun, dledford, sean.hefty, hal.rosenstock, davem,
jeffrey.t.kirsher, jiri, ogerlitz, linuxarm, linux-rdma,
linux-kernel, netdev, gongyangming, xiaokun, tangchaofei,
haifeng.wei, yisen.zhuang, yankejian, lisheng011, charles.chenxin
In-Reply-To: <20160426141821.GJ7974@leon.nu>
Tue, Apr 26, 2016 at 04:18:21PM CEST, leon@kernel.org wrote:
>On Tue, Apr 26, 2016 at 02:34:44PM +0800, oulijun wrote:
>> On 2016/4/24 15:54, Leon Romanovsky wrote:
<snip>
>> >> +int hns_roce_bitmap_alloc(struct hns_roce_bitmap *bitmap, u32 *obj)
>> >> +{
>> >> + int ret = 0;
>> >> +
>> >> + spin_lock(&bitmap->lock);
>> >> + *obj = find_next_zero_bit(bitmap->table, bitmap->max, bitmap->last);
>> >> + if (*obj >= bitmap->max) {
>> >> + bitmap->top = (bitmap->top + bitmap->max + bitmap->reserved_top)
>> >> + & bitmap->mask;
>> >> + *obj = find_first_zero_bit(bitmap->table, bitmap->max);
>> >
>> > find_first_zero_bit function returns "unsigned long" which may or may
>> > not be equal to u32 on some architectures.
>> >
>> Hi Leon,
>> I appreciate your keen eye. this code is meant for ARM64bit therefore should run corretly for 64-bit AARCH64.
The driver should run correctly on any arch.
>> I will consider changing it as part of good partice and better portability "
>> I will give a primary plan to modified it.
>> for example:
>> *obj = (u32)find_next_zero_bit(bitmap->table, bitmap->max, bitmap->last);
>> Beause the max size of bitmap->table is u32 in current version.
>>
>> int hns_roce_bitmap_init(struct hns_roce_bitmap *bitmap, u32 num, u32 mask,
>> u32 reserved_bot, u32 reserved_top)
>> {
>> u32 i;
>>
>> if (num != roundup_pow_of_two(num))
>> return -EINVAL;
>>
>> bitmap->last = 0;
>> bitmap->top = 0;
>> bitmap->max = num - reserved_top;
>> bitmap->mask = mask;
>> bitmap->reserved_top = reserved_top;
>> spin_lock_init(&bitmap->lock);
>> bitmap->table = kcalloc(BITS_TO_LONGS(bitmap->max), sizeof(long),
>> GFP_KERNEL);
>>
>> Is this plan ok?
>
>No,
>You are submitting new driver, please do it properly (without casting)
>from the beginning.
>
>>
>> Thanks
>> Lijun Ou
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-rdma" 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 v5 09/21] IB/hns: Add hca support
From: Leon Romanovsky @ 2016-04-26 14:18 UTC (permalink / raw)
To: oulijun
Cc: dledford-H+wXaHxf7aLQT0dZR+AlfA,
sean.hefty-ral2JQCrhuEAvxtiuMwx3w,
hal.rosenstock-Re5JQEeQqe8AvxtiuMwx3w,
davem-fT/PcQaiUtIeIZ0/mPfg9Q,
jeffrey.t.kirsher-ral2JQCrhuEAvxtiuMwx3w,
jiri-VPRAkNaXOzVWk0Htik3J/w, ogerlitz-VPRAkNaXOzVWk0Htik3J/w,
linuxarm-hv44wF8Li93QT0dZR+AlfA,
linux-rdma-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
netdev-u79uwXL29TY76Z2rM5mHXA,
gongyangming-hv44wF8Li93QT0dZR+AlfA,
xiaokun-hv44wF8Li93QT0dZR+AlfA,
tangchaofei-hv44wF8Li93QT0dZR+AlfA,
haifeng.wei-hv44wF8Li93QT0dZR+AlfA,
yisen.zhuang-hv44wF8Li93QT0dZR+AlfA,
yankejian-hv44wF8Li93QT0dZR+AlfA,
lisheng011-hv44wF8Li93QT0dZR+AlfA,
charles.chenxin-hv44wF8Li93QT0dZR+AlfA
In-Reply-To: <571F0C04.2010005-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
[-- Attachment #1: Type: text/plain, Size: 4292 bytes --]
On Tue, Apr 26, 2016 at 02:34:44PM +0800, oulijun wrote:
> On 2016/4/24 15:54, Leon Romanovsky wrote:
> > On Sat, Apr 23, 2016 at 06:26:47PM +0800, Lijun Ou wrote:
> >> This patch mainly setup hca for RoCE. it will do a series of
> >> initial works as follows:
> >> 1. init uar table, allocate uar resource
> >> 2. init pd table
> >> 3. init cq table
> >> 4. init mr table
> >> 5. init qp table
> >>
> >> Signed-off-by: Lijun Ou <oulijun-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
> >> Signed-off-by: Wei Hu(Xavier) <xavier.huwei-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
> >> ---
> >> drivers/infiniband/hw/hns/hns_roce_alloc.c | 104 ++++++++++++++++
> >> drivers/infiniband/hw/hns/hns_roce_cq.c | 25 ++++
> >> drivers/infiniband/hw/hns/hns_roce_device.h | 69 ++++++++++
> >> drivers/infiniband/hw/hns/hns_roce_eq.c | 1 -
> >> drivers/infiniband/hw/hns/hns_roce_icm.c | 88 +++++++++++++
> >> drivers/infiniband/hw/hns/hns_roce_icm.h | 9 ++
> >> drivers/infiniband/hw/hns/hns_roce_main.c | 79 ++++++++++++
> >> drivers/infiniband/hw/hns/hns_roce_mr.c | 187 ++++++++++++++++++++++++++++
> >> drivers/infiniband/hw/hns/hns_roce_pd.c | 65 ++++++++++
> >> drivers/infiniband/hw/hns/hns_roce_qp.c | 30 +++++
> >> 10 files changed, 656 insertions(+), 1 deletion(-)
> >> create mode 100644 drivers/infiniband/hw/hns/hns_roce_alloc.c
> >> create mode 100644 drivers/infiniband/hw/hns/hns_roce_mr.c
> >> create mode 100644 drivers/infiniband/hw/hns/hns_roce_pd.c
> >>
> >> diff --git a/drivers/infiniband/hw/hns/hns_roce_alloc.c b/drivers/infiniband/hw/hns/hns_roce_alloc.c
> >> new file mode 100644
> >> index 0000000..0c76f1b
> >> --- /dev/null
> >> +++ b/drivers/infiniband/hw/hns/hns_roce_alloc.c
> >> @@ -0,0 +1,104 @@
> >> +/*
> >> + * Copyright (c) 2016 Hisilicon Limited.
> >> + *
> >> + * This program is free software; you can redistribute it and/or modify
> >> + * it under the terms of the GNU General Public License as published by
> >> + * the Free Software Foundation; either version 2 of the License, or
> >> + * (at your option) any later version.
> >> + */
> >> +
> >> +#include <linux/bitmap.h>
> >> +#include <linux/dma-mapping.h>
> >> +#include <linux/errno.h>
> >> +#include <linux/mm.h>
> >> +#include <linux/slab.h>
> >> +#include <linux/vmalloc.h>
> >> +#include "hns_roce_device.h"
> >> +
> >> +int hns_roce_bitmap_alloc(struct hns_roce_bitmap *bitmap, u32 *obj)
> >> +{
> >> + int ret = 0;
> >> +
> >> + spin_lock(&bitmap->lock);
> >> + *obj = find_next_zero_bit(bitmap->table, bitmap->max, bitmap->last);
> >> + if (*obj >= bitmap->max) {
> >> + bitmap->top = (bitmap->top + bitmap->max + bitmap->reserved_top)
> >> + & bitmap->mask;
> >> + *obj = find_first_zero_bit(bitmap->table, bitmap->max);
> >
> > find_first_zero_bit function returns "unsigned long" which may or may
> > not be equal to u32 on some architectures.
> >
> Hi Leon,
> I appreciate your keen eye. this code is meant for ARM64bit therefore should run corretly for 64-bit AARCH64.
> I will consider changing it as part of good partice and better portability "
> I will give a primary plan to modified it.
> for example:
> *obj = (u32)find_next_zero_bit(bitmap->table, bitmap->max, bitmap->last);
> Beause the max size of bitmap->table is u32 in current version.
>
> int hns_roce_bitmap_init(struct hns_roce_bitmap *bitmap, u32 num, u32 mask,
> u32 reserved_bot, u32 reserved_top)
> {
> u32 i;
>
> if (num != roundup_pow_of_two(num))
> return -EINVAL;
>
> bitmap->last = 0;
> bitmap->top = 0;
> bitmap->max = num - reserved_top;
> bitmap->mask = mask;
> bitmap->reserved_top = reserved_top;
> spin_lock_init(&bitmap->lock);
> bitmap->table = kcalloc(BITS_TO_LONGS(bitmap->max), sizeof(long),
> GFP_KERNEL);
>
> Is this plan ok?
No,
You are submitting new driver, please do it properly (without casting)
from the beginning.
>
> Thanks
> Lijun Ou
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
> the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]
^ 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