[PATCH v2 net-next] cxgb4/cxgb4vf: Fix mac_hlist initialization and free

2018-11-19 Thread Arjun Vynipadath
Null pointer dereference seen when cxgb4vf driver is unloaded
without bringing up any interfaces, moving mac_hlist initialization
to driver probe and free the mac_hlist in remove to fix the issue.

Fixes: 24357e06ba51 ("cxgb4vf: fix memleak in mac_hlist initialization")
Signed-off-by: Arjun Vynipadath 
Signed-off-by: Casey Leedom 
Signed-off-by: Ganesh Goudar 
---
v2:
- Updated commit description as per Leon's feedback
---
 drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 19 ++-
 drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c |  6 +++---
 2 files changed, 13 insertions(+), 12 deletions(-)

diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c 
b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
index 956e708..cdd6f48 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
@@ -2280,8 +2280,6 @@ static int cxgb_up(struct adapter *adap)
 #if IS_ENABLED(CONFIG_IPV6)
update_clip(adap);
 #endif
-   /* Initialize hash mac addr list*/
-   INIT_LIST_HEAD(>mac_hlist);
return err;
 
  irq_err:
@@ -2295,8 +2293,6 @@ static int cxgb_up(struct adapter *adap)
 
 static void cxgb_down(struct adapter *adapter)
 {
-   struct hash_mac_addr *entry, *tmp;
-
cancel_work_sync(>tid_release_task);
cancel_work_sync(>db_full_task);
cancel_work_sync(>db_drop_task);
@@ -2306,11 +2302,6 @@ static void cxgb_down(struct adapter *adapter)
t4_sge_stop(adapter);
t4_free_sge_resources(adapter);
 
-   list_for_each_entry_safe(entry, tmp, >mac_hlist, list) {
-   list_del(>list);
-   kfree(entry);
-   }
-
adapter->flags &= ~FULL_INIT_DONE;
 }
 
@@ -5629,6 +5620,9 @@ static int init_one(struct pci_dev *pdev, const struct 
pci_device_id *ent)
 (is_t5(adapter->params.chip) ? STATMODE_V(0) :
  T6_STATMODE_V(0)));
 
+   /* Initialize hash mac addr list */
+   INIT_LIST_HEAD(>mac_hlist);
+
for_each_port(adapter, i) {
netdev = alloc_etherdev_mq(sizeof(struct port_info),
   MAX_ETH_QSETS);
@@ -5907,6 +5901,7 @@ static int init_one(struct pci_dev *pdev, const struct 
pci_device_id *ent)
 static void remove_one(struct pci_dev *pdev)
 {
struct adapter *adapter = pci_get_drvdata(pdev);
+   struct hash_mac_addr *entry, *tmp;
 
if (!adapter) {
pci_release_regions(pdev);
@@ -5956,6 +5951,12 @@ static void remove_one(struct pci_dev *pdev)
if (adapter->num_uld || adapter->num_ofld_uld)
t4_uld_mem_free(adapter);
free_some_resources(adapter);
+   list_for_each_entry_safe(entry, tmp, >mac_hlist,
+list) {
+   list_del(>list);
+   kfree(entry);
+   }
+
 #if IS_ENABLED(CONFIG_IPV6)
t4_cleanup_clip_tbl(adapter);
 #endif
diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c 
b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c
index 8ec503c..8a2ad6b 100644
--- a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c
+++ b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c
@@ -723,9 +723,6 @@ static int adapter_up(struct adapter *adapter)
if (adapter->flags & USING_MSIX)
name_msix_vecs(adapter);
 
-   /* Initialize hash mac addr list*/
-   INIT_LIST_HEAD(>mac_hlist);
-
adapter->flags |= FULL_INIT_DONE;
}
 
@@ -3038,6 +3035,9 @@ static int cxgb4vf_pci_probe(struct pci_dev *pdev,
if (err)
goto err_unmap_bar;
 
+   /* Initialize hash mac addr list */
+   INIT_LIST_HEAD(>mac_hlist);
+
/*
 * Allocate our "adapter ports" and stitch everything together.
 */
-- 
2.9.5



[PATCH net-next] cxgb4/cxgb4vf: Fix mac_hlist initialization and free

2018-11-19 Thread Arjun Vynipadath
Null pointer dereference seen when cxgb4vf driver is unloaded
without bringing up any interfaces, moving mac_hlist initialization
to driver probe and free the mac_hlist in remove to fix this.

Fixes 'commit 24357e06ba51 ("cxgb4vf: fix memleak in mac_hlist
initialization")'

Signed-off-by: Arjun Vynipadath 
Signed-off-by: Casey Leedom 
Signed-off-by: Ganesh Goudar 
---
 drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 19 ++-
 drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c |  6 +++---
 2 files changed, 13 insertions(+), 12 deletions(-)

diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c 
b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
index 956e708..cdd6f48 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
@@ -2280,8 +2280,6 @@ static int cxgb_up(struct adapter *adap)
 #if IS_ENABLED(CONFIG_IPV6)
update_clip(adap);
 #endif
-   /* Initialize hash mac addr list*/
-   INIT_LIST_HEAD(>mac_hlist);
return err;
 
  irq_err:
@@ -2295,8 +2293,6 @@ static int cxgb_up(struct adapter *adap)
 
 static void cxgb_down(struct adapter *adapter)
 {
-   struct hash_mac_addr *entry, *tmp;
-
cancel_work_sync(>tid_release_task);
cancel_work_sync(>db_full_task);
cancel_work_sync(>db_drop_task);
@@ -2306,11 +2302,6 @@ static void cxgb_down(struct adapter *adapter)
t4_sge_stop(adapter);
t4_free_sge_resources(adapter);
 
-   list_for_each_entry_safe(entry, tmp, >mac_hlist, list) {
-   list_del(>list);
-   kfree(entry);
-   }
-
adapter->flags &= ~FULL_INIT_DONE;
 }
 
@@ -5629,6 +5620,9 @@ static int init_one(struct pci_dev *pdev, const struct 
pci_device_id *ent)
 (is_t5(adapter->params.chip) ? STATMODE_V(0) :
  T6_STATMODE_V(0)));
 
+   /* Initialize hash mac addr list */
+   INIT_LIST_HEAD(>mac_hlist);
+
for_each_port(adapter, i) {
netdev = alloc_etherdev_mq(sizeof(struct port_info),
   MAX_ETH_QSETS);
@@ -5907,6 +5901,7 @@ static int init_one(struct pci_dev *pdev, const struct 
pci_device_id *ent)
 static void remove_one(struct pci_dev *pdev)
 {
struct adapter *adapter = pci_get_drvdata(pdev);
+   struct hash_mac_addr *entry, *tmp;
 
if (!adapter) {
pci_release_regions(pdev);
@@ -5956,6 +5951,12 @@ static void remove_one(struct pci_dev *pdev)
if (adapter->num_uld || adapter->num_ofld_uld)
t4_uld_mem_free(adapter);
free_some_resources(adapter);
+   list_for_each_entry_safe(entry, tmp, >mac_hlist,
+list) {
+   list_del(>list);
+   kfree(entry);
+   }
+
 #if IS_ENABLED(CONFIG_IPV6)
t4_cleanup_clip_tbl(adapter);
 #endif
diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c 
b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c
index 8ec503c..8a2ad6b 100644
--- a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c
+++ b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c
@@ -723,9 +723,6 @@ static int adapter_up(struct adapter *adapter)
if (adapter->flags & USING_MSIX)
name_msix_vecs(adapter);
 
-   /* Initialize hash mac addr list*/
-   INIT_LIST_HEAD(>mac_hlist);
-
adapter->flags |= FULL_INIT_DONE;
}
 
@@ -3038,6 +3035,9 @@ static int cxgb4vf_pci_probe(struct pci_dev *pdev,
if (err)
goto err_unmap_bar;
 
+   /* Initialize hash mac addr list */
+   INIT_LIST_HEAD(>mac_hlist);
+
/*
 * Allocate our "adapter ports" and stitch everything together.
 */
-- 
2.9.5



[PATCH net-next] cxgb4: Remove SGE_HOST_PAGE_SIZE dependency on page size

2018-11-15 Thread Arjun Vynipadath
The SGE Host Page Size has nothing to do with the actual
Host Page Size. It's the SGE's BAR2 Doorbell/GTS Page Size
for interpreting the SGE Ingress/Egress Queue per Page values.
Firmware reads all of these things and makes all the
subsequent changes necessary. The Host Driver uses the SGE
Host Page Size in order to properly calculate BAR2 Offsets.

Signed-off-by: Casey Leedom 
Signed-off-by: Arjun Vynipadath 
Signed-off-by: Ganesh Goudar 
---
 drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | 11 ---
 1 file changed, 11 deletions(-)

diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c 
b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
index cb52394..fc6a087 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
@@ -7141,21 +7141,10 @@ int t4_fixup_host_params(struct adapter *adap, unsigned 
int page_size,
 unsigned int cache_line_size)
 {
unsigned int page_shift = fls(page_size) - 1;
-   unsigned int sge_hps = page_shift - 10;
unsigned int stat_len = cache_line_size > 64 ? 128 : 64;
unsigned int fl_align = cache_line_size < 32 ? 32 : cache_line_size;
unsigned int fl_align_log = fls(fl_align) - 1;
 
-   t4_write_reg(adap, SGE_HOST_PAGE_SIZE_A,
-HOSTPAGESIZEPF0_V(sge_hps) |
-HOSTPAGESIZEPF1_V(sge_hps) |
-HOSTPAGESIZEPF2_V(sge_hps) |
-HOSTPAGESIZEPF3_V(sge_hps) |
-HOSTPAGESIZEPF4_V(sge_hps) |
-HOSTPAGESIZEPF5_V(sge_hps) |
-HOSTPAGESIZEPF6_V(sge_hps) |
-HOSTPAGESIZEPF7_V(sge_hps));
-
if (is_t4(adap->params.chip)) {
t4_set_reg_field(adap, SGE_CONTROL_A,
 INGPADBOUNDARY_V(INGPADBOUNDARY_M) |
-- 
2.9.5



[PATCH net-next] cxgb4vf: free mac_hlist properly

2018-11-09 Thread Arjun Vynipadath
The locally maintained list for tracking hash mac table was
not freed during driver remove.

Signed-off-by: Arjun Vynipadath 
Signed-off-by: Ganesh Goudar 
---
 drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c 
b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c
index 972dc7b..8ec503c 100644
--- a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c
+++ b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c
@@ -3289,6 +3289,7 @@ static int cxgb4vf_pci_probe(struct pci_dev *pdev,
 static void cxgb4vf_pci_remove(struct pci_dev *pdev)
 {
struct adapter *adapter = pci_get_drvdata(pdev);
+   struct hash_mac_addr *entry, *tmp;
 
/*
 * Tear down driver state associated with device.
@@ -3339,6 +3340,11 @@ static void cxgb4vf_pci_remove(struct pci_dev *pdev)
if (!is_t4(adapter->params.chip))
iounmap(adapter->bar2);
kfree(adapter->mbox_log);
+   list_for_each_entry_safe(entry, tmp, >mac_hlist,
+list) {
+   list_del(>list);
+   kfree(entry);
+   }
kfree(adapter);
}
 
-- 
1.8.3.1



[PATCH net-next] cxgb4vf: fix memleak in mac_hlist initialization

2018-11-09 Thread Arjun Vynipadath
mac_hlist was initialized during adapter_up, which will be called
every time a vf device is first brought up, or every time when device
is brought up again after bringing all devices down. This means our
state of previous list is lost, causing a memleak if entries are
present in the list. To fix that, move list init to the condition
that performs initial one time adapter setup.

Signed-off-by: Arjun Vynipadath 
Signed-off-by: Ganesh Goudar 
---
 drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c 
b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c
index ff84791..972dc7b 100644
--- a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c
+++ b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c
@@ -722,6 +722,10 @@ static int adapter_up(struct adapter *adapter)
 
if (adapter->flags & USING_MSIX)
name_msix_vecs(adapter);
+
+   /* Initialize hash mac addr list*/
+   INIT_LIST_HEAD(>mac_hlist);
+
adapter->flags |= FULL_INIT_DONE;
}
 
@@ -747,8 +751,6 @@ static int adapter_up(struct adapter *adapter)
enable_rx(adapter);
t4vf_sge_start(adapter);
 
-   /* Initialize hash mac addr list*/
-   INIT_LIST_HEAD(>mac_hlist);
return 0;
 }
 
-- 
1.8.3.1



[PATCH net-next] cxgb4: free mac_hlist properly

2018-11-09 Thread Arjun Vynipadath
The locally maintained list for tracking hash mac table was
not freed during driver remove.

Signed-off-by: Arjun Vynipadath 
Signed-off-by: Ganesh Goudar 
---
 drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c 
b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
index 05a4692..956e708 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
@@ -2295,6 +2295,8 @@ static int cxgb_up(struct adapter *adap)
 
 static void cxgb_down(struct adapter *adapter)
 {
+   struct hash_mac_addr *entry, *tmp;
+
cancel_work_sync(>tid_release_task);
cancel_work_sync(>db_full_task);
cancel_work_sync(>db_drop_task);
@@ -2303,6 +2305,12 @@ static void cxgb_down(struct adapter *adapter)
 
t4_sge_stop(adapter);
t4_free_sge_resources(adapter);
+
+   list_for_each_entry_safe(entry, tmp, >mac_hlist, list) {
+   list_del(>list);
+   kfree(entry);
+   }
+
adapter->flags &= ~FULL_INIT_DONE;
 }
 
-- 
1.8.3.1



Re: [PATCH net-next] cxgb4vf: Add ethtool private flags for changing force_link_up

2018-09-21 Thread Arjun Vynipadath
On Tuesday, September 09/18/18, 2018 at 11:39:14 -0700, Jakub Kicinski wrote:
> On Tue, 18 Sep 2018 18:37:23 +0530, Arjun Vynipadath wrote:
> > Forcing link up of virtual interfaces even when physical link is down
> > causes packet drops and ping failures during bonding failover. Hence
> > adding a ethtool private flag to toggle force_link_up whenever required.
> > 
> > Signed-off-by: Arjun Vynipadath 
> > Signed-off-by: Casey Leedom 
> > Signed-off-by: Ganesh Goudar 
> 
> Could you describe how this mechanism relates to the existing
> ndo_set_vf_link_state, which you seem to not make use of:
> 
> $ git grep ndo_set_vf_link_state -- drivers/net/ethernet/chelsio/
> $ 
> 
> I understand you're configuring the setting from the VF side, but the
> question, as always, is: why ;)
Hi Jakub,
ndo_set_vf_link_state can't be presently used in our case.
We dont have firmware support to communicate the link flags set through
ndo_set_vf_link_state from pf (cxgb4) driver to vf (cxgb4vf) driver.

Thanks,
Arjun.


[PATCH net-next] cxgb4vf: Add ethtool private flags for changing force_link_up

2018-09-18 Thread Arjun Vynipadath
Forcing link up of virtual interfaces even when physical link is down
causes packet drops and ping failures during bonding failover. Hence
adding a ethtool private flag to toggle force_link_up whenever required.

Signed-off-by: Arjun Vynipadath 
Signed-off-by: Casey Leedom 
Signed-off-by: Ganesh Goudar 
---
 drivers/net/ethernet/chelsio/cxgb4vf/adapter.h | 16 +++
 .../net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c| 54 +-
 2 files changed, 68 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/adapter.h 
b/drivers/net/ethernet/chelsio/cxgb4vf/adapter.h
index 5883f09..444a5c8 100644
--- a/drivers/net/ethernet/chelsio/cxgb4vf/adapter.h
+++ b/drivers/net/ethernet/chelsio/cxgb4vf/adapter.h
@@ -78,6 +78,18 @@ enum {
MAX_EGRQ= MAX_ETH_QSETS*2,
 };
 
+enum {
+   PRIV_FLAG_PORT_FORCE_LINKUP_BIT,
+};
+
+#define PRIV_FLAG_PORT_FORCE_LINKUP\
+   BIT(PRIV_FLAG_PORT_FORCE_LINKUP_BIT)
+
+#define PRIV_FLAGS_ADAP0x0
+#define DEFAULT_PRIV_FLAGS_ADAP0x0
+#define PRIV_FLAGS_PORTPRIV_FLAG_PORT_FORCE_LINKUP
+#define DEFAULT_PRIV_FLAGS_PORTPRIV_FLAG_PORT_FORCE_LINKUP
+
 /*
  * Forward structure definition references.
  */
@@ -103,6 +115,7 @@ struct port_info {
u8 port_id; /* physical port ID */
u8 nqsets;  /* # of "Queue Sets" */
u8 first_qset;  /* index of first "Queue Set" */
+   u32 eth_flags;  /* ethtool private flags */
struct link_config link_cfg;/* physical port configuration */
 };
 
@@ -374,6 +387,9 @@ struct adapter {
unsigned long flags;
struct adapter_params params;
 
+   /* ethtool private flags */
+   u32 eth_flags;
+
/* queue and interrupt resources */
struct {
unsigned short vec;
diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c 
b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c
index ff84791..ac10b5b 100644
--- a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c
+++ b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c
@@ -138,6 +138,7 @@ static struct dentry *cxgb4vf_debugfs_root;
 void t4vf_os_link_changed(struct adapter *adapter, int pidx, int link_ok)
 {
struct net_device *dev = adapter->port[pidx];
+   const struct port_info *pi = netdev_priv(dev);
 
/*
 * If the port is disabled or the current recorded "link up"
@@ -153,7 +154,9 @@ void t4vf_os_link_changed(struct adapter *adapter, int 
pidx, int link_ok)
if (link_ok) {
const char *s;
const char *fc;
-   const struct port_info *pi = netdev_priv(dev);
+
+   if (!(pi->eth_flags & PRIV_FLAG_PORT_FORCE_LINKUP))
+   netif_carrier_on(dev);
 
switch (pi->link_cfg.speed) {
case 100:
@@ -200,6 +203,8 @@ void t4vf_os_link_changed(struct adapter *adapter, int 
pidx, int link_ok)
 
netdev_info(dev, "link up, %s, full-duplex, %s PAUSE\n", s, fc);
} else {
+   if (!(pi->eth_flags & PRIV_FLAG_PORT_FORCE_LINKUP))
+   netif_carrier_off(dev);
netdev_info(dev, "link down\n");
}
 }
@@ -283,7 +288,7 @@ static int link_start(struct net_device *dev)
 * no errors in enabling vi.
 */
 
-   if (ret == 0)
+   if (ret == 0 && (pi->eth_flags & PRIV_FLAG_PORT_FORCE_LINKUP))
netif_carrier_on(dev);
 
return ret;
@@ -1502,6 +1507,10 @@ static int cxgb4vf_get_fecparam(struct net_device *dev,
return 0;
 }
 
+static const char cxgb4vf_priv_flags_strings[][ETH_GSTRING_LEN] = {
+   [PRIV_FLAG_PORT_FORCE_LINKUP_BIT] = "port_force_linkup",
+};
+
 /*
  * Return our driver information.
  */
@@ -1524,6 +1533,7 @@ static void cxgb4vf_get_drvinfo(struct net_device *dev,
 FW_HDR_FW_VER_MINOR_G(adapter->params.dev.tprev),
 FW_HDR_FW_VER_MICRO_G(adapter->params.dev.tprev),
 FW_HDR_FW_VER_BUILD_G(adapter->params.dev.tprev));
+   drvinfo->n_priv_flags = ARRAY_SIZE(cxgb4vf_priv_flags_strings);
 }
 
 /*
@@ -1728,6 +1738,8 @@ static int cxgb4vf_get_sset_count(struct net_device *dev, 
int sset)
switch (sset) {
case ETH_SS_STATS:
return ARRAY_SIZE(stats_strings);
+   case ETH_SS_PRIV_FLAGS:
+   return ARRAY_SIZE(cxgb4vf_priv_flags_strings);
default:
return -EOPNOTSUPP;
}
@@ -1745,6 +1757,10 @@ static void cxgb4vf_get_strings(struct net_device *dev,
case ETH_SS_STATS:
memcpy(data, stats_strings, sizeof(stats_strings));
break;
+   case ETH_SS_PRIV_FLAGS:
+   memcpy(data, cxgb4vf_priv_flags_strings,
+

[PATCH net] cxgb4: Added missing break in ndo_udp_tunnel_{add/del}

2018-07-25 Thread Arjun Vynipadath
Break statements were missing for Geneve case in
ndo_udp_tunnel_{add/del}, thereby raw mac matchall
entries were not getting added.

Fixes: c746fc0e8b2d("cxgb4: add geneve offload support for T6")
Signed-off-by: Arjun Vynipadath 
Signed-off-by: Ganesh Goudar 
---
 drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c 
b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
index 40cf8dc..a46a010 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
@@ -3074,6 +3074,7 @@ static void cxgb_del_udp_tunnel(struct net_device *netdev,
 
adapter->geneve_port = 0;
t4_write_reg(adapter, MPS_RX_GENEVE_TYPE_A, 0);
+   break;
default:
return;
}
@@ -3159,6 +3160,7 @@ static void cxgb_add_udp_tunnel(struct net_device *netdev,
 
t4_write_reg(adapter, MPS_RX_GENEVE_TYPE_A,
 GENEVE_V(be16_to_cpu(ti->port)) | GENEVE_EN_F);
+   break;
default:
return;
}
-- 
2.3.5



[PATCH net-next] cxgb4: Add HMA support

2018-03-13 Thread Arjun Vynipadath
HMA(Host Memory Access) maps a part of host memory for T6-SO memfree cards.

This commit does the following:
- Query FW to check if we have HMA support. If yes, the params will
  return HMA size configured in FW. We will dma map memory based
  on this size.
- Also contains changes to get HMA memory information via debugfs.

Signed-off-by: Arjun Vynipadath <ar...@chelsio.com>
Signed-off-by: Santosh Rastapur <sant...@chelsio.com>
Signed-off-by: Michael Werner <wer...@chelsio.com>
Signed-off-by: Ganesh GR <ganes...@chelsio.com>
---
 drivers/net/ethernet/chelsio/cxgb4/cxgb4.h |  13 ++
 drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c |  10 +-
 drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c| 228 -
 drivers/net/ethernet/chelsio/cxgb4/t4_hw.c |   2 +-
 drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h  |  56 +
 5 files changed, 303 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h 
b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
index d3fa53d..b2df0ff 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
@@ -831,6 +831,16 @@ struct vf_info {
u16 vlan;
 };
 
+enum {
+   HMA_DMA_MAPPED_FLAG = 1
+};
+
+struct hma_data {
+   unsigned char flags;
+   struct sg_table *sgt;
+   dma_addr_t *phy_addr;   /* physical address of the page */
+};
+
 struct mbox_list {
struct list_head list;
 };
@@ -946,6 +956,9 @@ struct adapter {
 
/* Ethtool Dump */
struct ethtool_dump eth_dump;
+
+   /* HMA */
+   struct hma_data hma;
 };
 
 /* Support for "sched-class" command to allow a TX Scheduling Class to be
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c 
b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c
index 2822bbf..de2ba86 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c
@@ -2617,7 +2617,7 @@ int mem_open(struct inode *inode, struct file *file)
 
file->private_data = inode->i_private;
 
-   mem = (uintptr_t)file->private_data & 0x3;
+   mem = (uintptr_t)file->private_data & 0x7;
adap = file->private_data - mem;
 
(void)t4_fwcache(adap, FW_PARAM_DEV_FWCACHE_FLUSH);
@@ -2630,7 +2630,7 @@ static ssize_t mem_read(struct file *file, char __user 
*buf, size_t count,
 {
loff_t pos = *ppos;
loff_t avail = file_inode(file)->i_size;
-   unsigned int mem = (uintptr_t)file->private_data & 3;
+   unsigned int mem = (uintptr_t)file->private_data & 0x7;
struct adapter *adap = file->private_data - mem;
__be32 *data;
int ret;
@@ -3042,6 +3042,12 @@ int t4_setup_debugfs(struct adapter *adap)
add_debugfs_mem(adap, "mc", MEM_MC,
EXT_MEM_SIZE_G(size));
}
+
+   if (i & HMA_MUX_F) {
+   size = t4_read_reg(adap, MA_EXT_MEMORY1_BAR_A);
+   add_debugfs_mem(adap, "hma", MEM_HMA,
+   EXT_MEM1_SIZE_G(size));
+   }
}
 
de = debugfs_create_file_size("flash", S_IRUSR, adap->debugfs_root, 
adap,
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c 
b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
index 1b44652..d1e2786 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
@@ -1733,10 +1733,11 @@ EXPORT_SYMBOL(cxgb4_sync_txq_pidx);
 
 int cxgb4_read_tpte(struct net_device *dev, u32 stag, __be32 *tpte)
 {
-   struct adapter *adap;
-   u32 offset, memtype, memaddr;
u32 edc0_size, edc1_size, mc0_size, mc1_size, size;
u32 edc0_end, edc1_end, mc0_end, mc1_end;
+   u32 offset, memtype, memaddr;
+   struct adapter *adap;
+   u32 hma_size = 0;
int ret;
 
adap = netdev2adap(dev);
@@ -1756,6 +1757,10 @@ int cxgb4_read_tpte(struct net_device *dev, u32 stag, 
__be32 *tpte)
size = t4_read_reg(adap, MA_EXT_MEMORY0_BAR_A);
mc0_size = EXT_MEM0_SIZE_G(size) << 20;
 
+   if (t4_read_reg(adap, MA_TARGET_MEM_ENABLE_A) & HMA_MUX_F) {
+   size = t4_read_reg(adap, MA_EXT_MEMORY1_BAR_A);
+   hma_size = EXT_MEM1_SIZE_G(size) << 20;
+   }
edc0_end = edc0_size;
edc1_end = edc0_end + edc1_size;
mc0_end = edc1_end + mc0_size;
@@ -1767,7 +1772,10 @@ int cxgb4_read_tpte(struct net_device *dev, u32 stag, 
__be32 *tpte)
memtype = MEM_EDC1;
memaddr = offset - edc0_end;
} else {
-   if (offset < mc0_end) {
+   if (hma_size && (offset < (edc1_end + hma_size))) {
+   memtype = MEM_HMA;
+   memaddr = offset - edc1_en

[REGRESSION, bisect] pci: cxgb4 probe fails after commit 104daa71b3961434 ("PCI: Determine actual VPD size on first access")

2018-01-23 Thread Arjun Vynipadath
Sending on behalf of "Casey Leedom "

Way back on April 11, 2016 we reported a regression in Linux kernel 4.6-rc2 
brought on by kernel.org commit 104daa71b396. This commit calculates the 
size of a PCI Device's VPD area by parsing the VPD Structure at offset 0x000, 
and restricts accesses to the VPD to that computed size.

Our devices have a second VPD structure which is located starting at offset 
0x400 which is the "real" VPD[1].  The 104daa71b396 commit (plus a follow on 
commit 408641e93aa5) caused efforts to read past the end of that computed 
length of the VPD to return silently without error leaving stack junk in the 
VPD read buffers.

We introduced kernel.org commit cb92148b to allow a driver to tell the 
kernel how large the VPD area really is, introducing a new API 
pci_set_vpd_size() for this purpose.

Now we've discovered a new subtlety to the problem.

We have a KVM Hypervisor running a 4.9.70 kernel.  So it has all of the 
above commits.  When we attach our Physical Function 4 to a Virtual Machine 
and attempt to run cxgb4 in that VM, we see the problem again.  The issue is 
that all of the VM Guest OS's efforts to access the PCIe VPD Capability are 
trapped into the KVM 4.9.70 kernel and executed there, with the results 
routed back to the VM Guest OS.  The cxgb4 driver in the VM Guest OS uses 
the new pci_set_vpd_size() to notify the OS of the true size of the VPD, but 
that information of course is never sent to the KVM 4.9.70 Hypervisor. 
(And, truth be told, if the Guest OS were older than 4.6, it wouldn't even 
know that it needed to do this.)  The result is that again we get silent VPD 
read failures with random stack garbage in the VPD read buffers. (sigh) 

It strikes me that the only way to handle this issue is to have KVM 
circumvent the VPD-Size Restricted logic which was added in kernel.org 
commits 104daa71b396 and 408641e93aa5.  Maybe via a __pci_read_vpd() or 
similar API.  But we are open to other suggestions.

Thoughts?

Casey.

[1] Chelsio adapters actually have two VPD structures stored in the VPD.  An
abbreviated on at Offset 0x0 and the complete VPD at Offset 0x400.  The
abbreviated one only contains the PN, SN and EC Keywords, while the
complete VPD contains those plus various adapter constants contained in
V0, V1, etc.  And it also contains the Base Ethernet MAC Address in the
"NA" Keyword which the cxgb4 driver needs when it can't contact the
adapter firmware.  (We don't have the "NA" Keyword in the VPD Structure
at Offset 0x000 because that's not an allowed VPD Keyword in the PCI-E
3.0 specification.)

Note that two other drivers look like they may also do something
similar, the Broadcom bnx2x and tg3.