* [PATCH net-next 0/3] sfc: Clean up Siena SR-IOV support in preparation for EF10 SR-IOV support
From: Shradha Shah @ 2014-11-05 12:15 UTC (permalink / raw)
To: David Miller; +Cc: netdev, linux-net-drivers
This patch series provides a base and clean up for the upcoming
EF10 SRIOV patches.
Shradha Shah (3):
sfc: Move the current VF state from efx_nic into siena_nic_data
sfc: Rename implementations in siena_sriov.c to have a 'siena' prefix
sfc: Add NIC type operations to replace direct calls from efx.c into
siena_sriov.c
drivers/net/ethernet/sfc/ef10.c | 5 +
drivers/net/ethernet/sfc/efx.c | 22 +--
drivers/net/ethernet/sfc/falcon.c | 10 ++
drivers/net/ethernet/sfc/farch.c | 27 ++--
drivers/net/ethernet/sfc/mcdi.c | 2 +-
drivers/net/ethernet/sfc/net_driver.h | 19 +--
drivers/net/ethernet/sfc/nic.h | 112 +++++++++-----
drivers/net/ethernet/sfc/siena.c | 8 +-
drivers/net/ethernet/sfc/siena_sriov.c | 269 ++++++++++++++++++---------------
9 files changed, 281 insertions(+), 193 deletions(-)
^ permalink raw reply
* [PATCH net-next 1/3] sfc: Move the current VF state from efx_nic into siena_nic_data
From: Shradha Shah @ 2014-11-05 12:16 UTC (permalink / raw)
To: David Miller; +Cc: netdev, linux-net-drivers
In-Reply-To: <545A14CD.6040809@solarflare.com>
This patch series provides a base and cleanup for the
upcoming EF10 SRIOV support.
This patch moves the VF state into siena_nic_data as a basis to
save the VF state based on nic type.
Signed-off-by: Shradha Shah <sshah@solarflare.com>
---
drivers/net/ethernet/sfc/farch.c | 11 +++-
drivers/net/ethernet/sfc/net_driver.h | 14 ------
drivers/net/ethernet/sfc/nic.h | 18 +++++++
drivers/net/ethernet/sfc/siena.c | 1 +
drivers/net/ethernet/sfc/siena_sriov.c | 92 +++++++++++++++++++++-------------
5 files changed, 84 insertions(+), 52 deletions(-)
diff --git a/drivers/net/ethernet/sfc/farch.c b/drivers/net/ethernet/sfc/farch.c
index 6859437..0274401 100644
--- a/drivers/net/ethernet/sfc/farch.c
+++ b/drivers/net/ethernet/sfc/farch.c
@@ -226,6 +226,9 @@ static int efx_alloc_special_buffer(struct efx_nic *efx,
struct efx_special_buffer *buffer,
unsigned int len)
{
+#ifdef CONFIG_SFC_SRIOV
+ struct siena_nic_data *nic_data = efx->nic_data;
+#endif
len = ALIGN(len, EFX_BUF_SIZE);
if (efx_nic_alloc_buffer(efx, &buffer->buf, len, GFP_KERNEL))
@@ -238,7 +241,7 @@ static int efx_alloc_special_buffer(struct efx_nic *efx,
efx->next_buffer_table += buffer->entries;
#ifdef CONFIG_SFC_SRIOV
BUG_ON(efx_sriov_enabled(efx) &&
- efx->vf_buftbl_base < efx->next_buffer_table);
+ nic_data->vf_buftbl_base < efx->next_buffer_table);
#endif
netif_dbg(efx, probe, efx->net_dev,
@@ -1668,6 +1671,10 @@ void efx_farch_dimension_resources(struct efx_nic *efx, unsigned sram_lim_qw)
{
unsigned vi_count, buftbl_min;
+#ifdef CONFIG_SFC_SRIOV
+ struct siena_nic_data *nic_data = efx->nic_data;
+#endif
+
/* Account for the buffer table entries backing the datapath channels
* and the descriptor caches for those channels.
*/
@@ -1681,7 +1688,7 @@ void efx_farch_dimension_resources(struct efx_nic *efx, unsigned sram_lim_qw)
if (efx_sriov_wanted(efx)) {
unsigned vi_dc_entries, buftbl_free, entries_per_vf, vf_limit;
- efx->vf_buftbl_base = buftbl_min;
+ nic_data->vf_buftbl_base = buftbl_min;
vi_dc_entries = RX_DC_ENTRIES + TX_DC_ENTRIES;
vi_count = max(vi_count, EFX_VI_BASE);
diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h
index 9ede320..779a1f5 100644
--- a/drivers/net/ethernet/sfc/net_driver.h
+++ b/drivers/net/ethernet/sfc/net_driver.h
@@ -913,13 +913,6 @@ struct vfdi_status;
* @vf_count: Number of VFs intended to be enabled.
* @vf_init_count: Number of VFs that have been fully initialised.
* @vi_scale: log2 number of vnics per VF.
- * @vf_buftbl_base: The zeroth buffer table index used to back VF queues.
- * @vfdi_status: Common VFDI status page to be dmad to VF address space.
- * @local_addr_list: List of local addresses. Protected by %local_lock.
- * @local_page_list: List of DMA addressable pages used to broadcast
- * %local_addr_list. Protected by %local_lock.
- * @local_lock: Mutex protecting %local_addr_list and %local_page_list.
- * @peer_work: Work item to broadcast peer addresses to VMs.
* @ptp_data: PTP state data
* @vpd_sn: Serial number read from VPD
* @monitor_work: Hardware monitor workitem
@@ -1060,17 +1053,10 @@ struct efx_nic {
wait_queue_head_t flush_wq;
#ifdef CONFIG_SFC_SRIOV
- struct efx_channel *vfdi_channel;
struct efx_vf *vf;
unsigned vf_count;
unsigned vf_init_count;
unsigned vi_scale;
- unsigned vf_buftbl_base;
- struct efx_buffer vfdi_status;
- struct list_head local_addr_list;
- struct list_head local_page_list;
- struct mutex local_lock;
- struct work_struct peer_work;
#endif
struct efx_ptp_data *ptp_data;
diff --git a/drivers/net/ethernet/sfc/nic.h b/drivers/net/ethernet/sfc/nic.h
index f77cce0..b5fe1f2 100644
--- a/drivers/net/ethernet/sfc/nic.h
+++ b/drivers/net/ethernet/sfc/nic.h
@@ -378,12 +378,30 @@ enum {
/**
* struct siena_nic_data - Siena NIC state
+ * @efx: Pointer back to main interface structure
* @wol_filter_id: Wake-on-LAN packet filter id
* @stats: Hardware statistics
+ * @vf_buftbl_base: The zeroth buffer table index used to back VF queues.
+ * @vfdi_status: Common VFDI status page to be dmad to VF address space.
+ * @local_addr_list: List of local addresses. Protected by %local_lock.
+ * @local_page_list: List of DMA addressable pages used to broadcast
+ * %local_addr_list. Protected by %local_lock.
+ * @local_lock: Mutex protecting %local_addr_list and %local_page_list.
+ * @peer_work: Work item to broadcast peer addresses to VMs.
*/
struct siena_nic_data {
+ struct efx_nic *efx;
int wol_filter_id;
u64 stats[SIENA_STAT_COUNT];
+#ifdef CONFIG_SFC_SRIOV
+ struct efx_channel *vfdi_channel;
+ unsigned vf_buftbl_base;
+ struct efx_buffer vfdi_status;
+ struct list_head local_addr_list;
+ struct list_head local_page_list;
+ struct mutex local_lock;
+ struct work_struct peer_work;
+#endif
};
enum {
diff --git a/drivers/net/ethernet/sfc/siena.c b/drivers/net/ethernet/sfc/siena.c
index ae69685..ffce06d 100644
--- a/drivers/net/ethernet/sfc/siena.c
+++ b/drivers/net/ethernet/sfc/siena.c
@@ -251,6 +251,7 @@ static int siena_probe_nic(struct efx_nic *efx)
nic_data = kzalloc(sizeof(struct siena_nic_data), GFP_KERNEL);
if (!nic_data)
return -ENOMEM;
+ nic_data->efx = efx;
efx->nic_data = nic_data;
if (efx_farch_fpga_ver(efx) != 0) {
diff --git a/drivers/net/ethernet/sfc/siena_sriov.c b/drivers/net/ethernet/sfc/siena_sriov.c
index 43d2e64..2b75eee 100644
--- a/drivers/net/ethernet/sfc/siena_sriov.c
+++ b/drivers/net/ethernet/sfc/siena_sriov.c
@@ -229,11 +229,12 @@ static int efx_sriov_cmd(struct efx_nic *efx, bool enable,
static void efx_sriov_usrev(struct efx_nic *efx, bool enabled)
{
+ struct siena_nic_data *nic_data = efx->nic_data;
efx_oword_t reg;
EFX_POPULATE_OWORD_2(reg,
FRF_CZ_USREV_DIS, enabled ? 0 : 1,
- FRF_CZ_DFLT_EVQ, efx->vfdi_channel->channel);
+ FRF_CZ_DFLT_EVQ, nic_data->vfdi_channel->channel);
efx_writeo(efx, ®, FR_CZ_USR_EV_CFG);
}
@@ -382,9 +383,12 @@ static void efx_sriov_reset_rx_filter(struct efx_vf *vf)
static void __efx_sriov_update_vf_addr(struct efx_vf *vf)
{
+ struct efx_nic *efx = vf->efx;
+ struct siena_nic_data *nic_data = efx->nic_data;
+
efx_sriov_reset_tx_filter(vf);
efx_sriov_reset_rx_filter(vf);
- queue_work(vfdi_workqueue, &vf->efx->peer_work);
+ queue_work(vfdi_workqueue, &nic_data->peer_work);
}
/* Push the peer list to this VF. The caller must hold status_lock to interlock
@@ -395,7 +399,8 @@ static void __efx_sriov_update_vf_addr(struct efx_vf *vf)
static void __efx_sriov_push_vf_status(struct efx_vf *vf)
{
struct efx_nic *efx = vf->efx;
- struct vfdi_status *status = efx->vfdi_status.addr;
+ struct siena_nic_data *nic_data = efx->nic_data;
+ struct vfdi_status *status = nic_data->vfdi_status.addr;
struct efx_memcpy_req copy[4];
struct efx_endpoint_page *epp;
unsigned int pos, count;
@@ -421,7 +426,7 @@ static void __efx_sriov_push_vf_status(struct efx_vf *vf)
*/
data_offset = offsetof(struct vfdi_status, version);
copy[1].from_rid = efx->pci_dev->devfn;
- copy[1].from_addr = efx->vfdi_status.dma_addr + data_offset;
+ copy[1].from_addr = nic_data->vfdi_status.dma_addr + data_offset;
copy[1].to_rid = vf->pci_rid;
copy[1].to_addr = vf->status_addr + data_offset;
copy[1].length = status->length - data_offset;
@@ -429,7 +434,7 @@ static void __efx_sriov_push_vf_status(struct efx_vf *vf)
/* Copy the peer pages */
pos = 2;
count = 0;
- list_for_each_entry(epp, &efx->local_page_list, link) {
+ list_for_each_entry(epp, &nic_data->local_page_list, link) {
if (count == vf->peer_page_count) {
/* The VF driver will know they need to provide more
* pages because peer_addr_count is too large.
@@ -754,6 +759,7 @@ static int efx_vfdi_fini_all_queues(struct efx_vf *vf)
static int efx_vfdi_insert_filter(struct efx_vf *vf)
{
struct efx_nic *efx = vf->efx;
+ struct siena_nic_data *nic_data = efx->nic_data;
struct vfdi_req *req = vf->buf.addr;
unsigned vf_rxq = req->u.mac_filter.rxq;
unsigned flags;
@@ -777,16 +783,19 @@ static int efx_vfdi_insert_filter(struct efx_vf *vf)
vf->rx_filtering = true;
efx_sriov_reset_rx_filter(vf);
- queue_work(vfdi_workqueue, &efx->peer_work);
+ queue_work(vfdi_workqueue, &nic_data->peer_work);
return VFDI_RC_SUCCESS;
}
static int efx_vfdi_remove_all_filters(struct efx_vf *vf)
{
+ struct efx_nic *efx = vf->efx;
+ struct siena_nic_data *nic_data = efx->nic_data;
+
vf->rx_filtering = false;
efx_sriov_reset_rx_filter(vf);
- queue_work(vfdi_workqueue, &vf->efx->peer_work);
+ queue_work(vfdi_workqueue, &nic_data->peer_work);
return VFDI_RC_SUCCESS;
}
@@ -794,6 +803,7 @@ static int efx_vfdi_remove_all_filters(struct efx_vf *vf)
static int efx_vfdi_set_status_page(struct efx_vf *vf)
{
struct efx_nic *efx = vf->efx;
+ struct siena_nic_data *nic_data = efx->nic_data;
struct vfdi_req *req = vf->buf.addr;
u64 page_count = req->u.set_status_page.peer_page_count;
u64 max_page_count =
@@ -809,7 +819,7 @@ static int efx_vfdi_set_status_page(struct efx_vf *vf)
return VFDI_RC_EINVAL;
}
- mutex_lock(&efx->local_lock);
+ mutex_lock(&nic_data->local_lock);
mutex_lock(&vf->status_lock);
vf->status_addr = req->u.set_status_page.dma_addr;
@@ -830,7 +840,7 @@ static int efx_vfdi_set_status_page(struct efx_vf *vf)
__efx_sriov_push_vf_status(vf);
mutex_unlock(&vf->status_lock);
- mutex_unlock(&efx->local_lock);
+ mutex_unlock(&nic_data->local_lock);
return VFDI_RC_SUCCESS;
}
@@ -1014,7 +1024,9 @@ static void efx_sriov_handle_no_channel(struct efx_nic *efx)
static int efx_sriov_probe_channel(struct efx_channel *channel)
{
- channel->efx->vfdi_channel = channel;
+ struct siena_nic_data *nic_data = channel->efx->nic_data;
+ nic_data->vfdi_channel = channel;
+
return 0;
}
@@ -1057,8 +1069,11 @@ void efx_sriov_probe(struct efx_nic *efx)
*/
static void efx_sriov_peer_work(struct work_struct *data)
{
- struct efx_nic *efx = container_of(data, struct efx_nic, peer_work);
- struct vfdi_status *vfdi_status = efx->vfdi_status.addr;
+ struct siena_nic_data *nic_data = container_of(data,
+ struct siena_nic_data,
+ peer_work);
+ struct efx_nic *efx = nic_data->efx;
+ struct vfdi_status *vfdi_status = nic_data->vfdi_status.addr;
struct efx_vf *vf;
struct efx_local_addr *local_addr;
struct vfdi_endpoint *peer;
@@ -1068,11 +1083,11 @@ static void efx_sriov_peer_work(struct work_struct *data)
unsigned int peer_count;
unsigned int pos;
- mutex_lock(&efx->local_lock);
+ mutex_lock(&nic_data->local_lock);
/* Move the existing peer pages off %local_page_list */
INIT_LIST_HEAD(&pages);
- list_splice_tail_init(&efx->local_page_list, &pages);
+ list_splice_tail_init(&nic_data->local_page_list, &pages);
/* Populate the VF addresses starting from entry 1 (entry 0 is
* the PF address)
@@ -1094,7 +1109,7 @@ static void efx_sriov_peer_work(struct work_struct *data)
}
/* Fill the remaining addresses */
- list_for_each_entry(local_addr, &efx->local_addr_list, link) {
+ list_for_each_entry(local_addr, &nic_data->local_addr_list, link) {
ether_addr_copy(peer->mac_addr, local_addr->addr);
peer->tci = 0;
++peer;
@@ -1117,13 +1132,13 @@ static void efx_sriov_peer_work(struct work_struct *data)
list_del(&epp->link);
}
- list_add_tail(&epp->link, &efx->local_page_list);
+ list_add_tail(&epp->link, &nic_data->local_page_list);
peer = (struct vfdi_endpoint *)epp->ptr;
peer_space = EFX_PAGE_SIZE / sizeof(struct vfdi_endpoint);
}
}
vfdi_status->peer_count = peer_count;
- mutex_unlock(&efx->local_lock);
+ mutex_unlock(&nic_data->local_lock);
/* Free any now unused endpoint pages */
while (!list_empty(&pages)) {
@@ -1148,18 +1163,19 @@ static void efx_sriov_peer_work(struct work_struct *data)
static void efx_sriov_free_local(struct efx_nic *efx)
{
+ struct siena_nic_data *nic_data = efx->nic_data;
struct efx_local_addr *local_addr;
struct efx_endpoint_page *epp;
- while (!list_empty(&efx->local_addr_list)) {
- local_addr = list_first_entry(&efx->local_addr_list,
+ while (!list_empty(&nic_data->local_addr_list)) {
+ local_addr = list_first_entry(&nic_data->local_addr_list,
struct efx_local_addr, link);
list_del(&local_addr->link);
kfree(local_addr);
}
- while (!list_empty(&efx->local_page_list)) {
- epp = list_first_entry(&efx->local_page_list,
+ while (!list_empty(&nic_data->local_page_list)) {
+ epp = list_first_entry(&nic_data->local_page_list,
struct efx_endpoint_page, link);
list_del(&epp->link);
dma_free_coherent(&efx->pci_dev->dev, EFX_PAGE_SIZE,
@@ -1215,6 +1231,7 @@ static void efx_sriov_vfs_fini(struct efx_nic *efx)
static int efx_sriov_vfs_init(struct efx_nic *efx)
{
struct pci_dev *pci_dev = efx->pci_dev;
+ struct siena_nic_data *nic_data = efx->nic_data;
unsigned index, devfn, sriov, buftbl_base;
u16 offset, stride;
struct efx_vf *vf;
@@ -1227,7 +1244,7 @@ static int efx_sriov_vfs_init(struct efx_nic *efx)
pci_read_config_word(pci_dev, sriov + PCI_SRIOV_VF_OFFSET, &offset);
pci_read_config_word(pci_dev, sriov + PCI_SRIOV_VF_STRIDE, &stride);
- buftbl_base = efx->vf_buftbl_base;
+ buftbl_base = nic_data->vf_buftbl_base;
devfn = pci_dev->devfn + offset;
for (index = 0; index < efx->vf_count; ++index) {
vf = efx->vf + index;
@@ -1260,6 +1277,7 @@ fail:
int efx_sriov_init(struct efx_nic *efx)
{
struct net_device *net_dev = efx->net_dev;
+ struct siena_nic_data *nic_data = efx->nic_data;
struct vfdi_status *vfdi_status;
int rc;
@@ -1275,11 +1293,11 @@ int efx_sriov_init(struct efx_nic *efx)
if (rc)
goto fail_cmd;
- rc = efx_nic_alloc_buffer(efx, &efx->vfdi_status, sizeof(*vfdi_status),
- GFP_KERNEL);
+ rc = efx_nic_alloc_buffer(efx, &nic_data->vfdi_status,
+ sizeof(*vfdi_status), GFP_KERNEL);
if (rc)
goto fail_status;
- vfdi_status = efx->vfdi_status.addr;
+ vfdi_status = nic_data->vfdi_status.addr;
memset(vfdi_status, 0, sizeof(*vfdi_status));
vfdi_status->version = 1;
vfdi_status->length = sizeof(*vfdi_status);
@@ -1293,10 +1311,10 @@ int efx_sriov_init(struct efx_nic *efx)
if (rc)
goto fail_alloc;
- mutex_init(&efx->local_lock);
- INIT_WORK(&efx->peer_work, efx_sriov_peer_work);
- INIT_LIST_HEAD(&efx->local_addr_list);
- INIT_LIST_HEAD(&efx->local_page_list);
+ mutex_init(&nic_data->local_lock);
+ INIT_WORK(&nic_data->peer_work, efx_sriov_peer_work);
+ INIT_LIST_HEAD(&nic_data->local_addr_list);
+ INIT_LIST_HEAD(&nic_data->local_page_list);
rc = efx_sriov_vfs_init(efx);
if (rc)
@@ -1327,11 +1345,11 @@ fail_pci:
rtnl_unlock();
efx_sriov_vfs_fini(efx);
fail_vfs:
- cancel_work_sync(&efx->peer_work);
+ cancel_work_sync(&nic_data->peer_work);
efx_sriov_free_local(efx);
kfree(efx->vf);
fail_alloc:
- efx_nic_free_buffer(efx, &efx->vfdi_status);
+ efx_nic_free_buffer(efx, &nic_data->vfdi_status);
fail_status:
efx_sriov_cmd(efx, false, NULL, NULL);
fail_cmd:
@@ -1342,12 +1360,13 @@ void efx_sriov_fini(struct efx_nic *efx)
{
struct efx_vf *vf;
unsigned int pos;
+ struct siena_nic_data *nic_data = efx->nic_data;
if (efx->vf_init_count == 0)
return;
/* Disable all interfaces to reconfiguration */
- BUG_ON(efx->vfdi_channel->enabled);
+ BUG_ON(nic_data->vfdi_channel->enabled);
efx_sriov_usrev(efx, false);
rtnl_lock();
efx->vf_init_count = 0;
@@ -1359,7 +1378,7 @@ void efx_sriov_fini(struct efx_nic *efx)
cancel_work_sync(&vf->req);
cancel_work_sync(&vf->reset_work);
}
- cancel_work_sync(&efx->peer_work);
+ cancel_work_sync(&nic_data->peer_work);
pci_disable_sriov(efx->pci_dev);
@@ -1367,7 +1386,7 @@ void efx_sriov_fini(struct efx_nic *efx)
efx_sriov_vfs_fini(efx);
efx_sriov_free_local(efx);
kfree(efx->vf);
- efx_nic_free_buffer(efx, &efx->vfdi_status);
+ efx_nic_free_buffer(efx, &nic_data->vfdi_status);
efx_sriov_cmd(efx, false, NULL, NULL);
}
@@ -1447,13 +1466,14 @@ void efx_sriov_flr(struct efx_nic *efx, unsigned vf_i)
void efx_sriov_mac_address_changed(struct efx_nic *efx)
{
- struct vfdi_status *vfdi_status = efx->vfdi_status.addr;
+ struct siena_nic_data *nic_data = efx->nic_data;
+ struct vfdi_status *vfdi_status = nic_data->vfdi_status.addr;
if (!efx->vf_init_count)
return;
ether_addr_copy(vfdi_status->peers[0].mac_addr,
efx->net_dev->dev_addr);
- queue_work(vfdi_workqueue, &efx->peer_work);
+ queue_work(vfdi_workqueue, &nic_data->peer_work);
}
void efx_sriov_tx_flush_done(struct efx_nic *efx, efx_qword_t *event)
^ permalink raw reply related
* [PATCH net-next 2/3] sfc: Rename implementations in siena_sriov.c to have a 'siena' prefix
From: Shradha Shah @ 2014-11-05 12:16 UTC (permalink / raw)
To: David Miller; +Cc: netdev, linux-net-drivers
In-Reply-To: <545A14CD.6040809@solarflare.com>
Patch in preparation for the upcoming EF10 sriov support.
Signed-off-by: Shradha Shah <sshah@solarflare.com>
---
drivers/net/ethernet/sfc/efx.c | 21 ++--
drivers/net/ethernet/sfc/farch.c | 16 +--
drivers/net/ethernet/sfc/mcdi.c | 2 +-
drivers/net/ethernet/sfc/nic.h | 70 +++++++------
drivers/net/ethernet/sfc/siena.c | 2 +-
drivers/net/ethernet/sfc/siena_sriov.c | 179 +++++++++++++++++----------------
6 files changed, 149 insertions(+), 141 deletions(-)
diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c
index b2cc590..2236ffc 100644
--- a/drivers/net/ethernet/sfc/efx.c
+++ b/drivers/net/ethernet/sfc/efx.c
@@ -1314,7 +1314,7 @@ static unsigned int efx_wanted_parallelism(struct efx_nic *efx)
/* If RSS is requested for the PF *and* VFs then we can't write RSS
* table entries that are inaccessible to VFs
*/
- if (efx_sriov_wanted(efx) && efx_vf_size(efx) > 1 &&
+ if (efx_siena_sriov_wanted(efx) && efx_vf_size(efx) > 1 &&
count > efx_vf_size(efx)) {
netif_warn(efx, probe, efx->net_dev,
"Reducing number of RSS channels from %u to %u for "
@@ -1426,7 +1426,8 @@ static int efx_probe_interrupts(struct efx_nic *efx)
}
/* RSS might be usable on VFs even if it is disabled on the PF */
- efx->rss_spread = ((efx->n_rx_channels > 1 || !efx_sriov_wanted(efx)) ?
+ efx->rss_spread = ((efx->n_rx_channels > 1 ||
+ !efx_siena_sriov_wanted(efx)) ?
efx->n_rx_channels : efx_vf_size(efx));
return 0;
@@ -2166,7 +2167,7 @@ static int efx_set_mac_address(struct net_device *net_dev, void *data)
}
ether_addr_copy(net_dev->dev_addr, new_addr);
- efx_sriov_mac_address_changed(efx);
+ efx_siena_sriov_mac_address_changed(efx);
/* Reconfigure the MAC */
mutex_lock(&efx->mac_lock);
@@ -2210,10 +2211,10 @@ static const struct net_device_ops efx_farch_netdev_ops = {
.ndo_set_rx_mode = efx_set_rx_mode,
.ndo_set_features = efx_set_features,
#ifdef CONFIG_SFC_SRIOV
- .ndo_set_vf_mac = efx_sriov_set_vf_mac,
- .ndo_set_vf_vlan = efx_sriov_set_vf_vlan,
- .ndo_set_vf_spoofchk = efx_sriov_set_vf_spoofchk,
- .ndo_get_vf_config = efx_sriov_get_vf_config,
+ .ndo_set_vf_mac = efx_siena_sriov_set_vf_mac,
+ .ndo_set_vf_vlan = efx_siena_sriov_set_vf_vlan,
+ .ndo_set_vf_spoofchk = efx_siena_sriov_set_vf_spoofchk,
+ .ndo_get_vf_config = efx_siena_sriov_get_vf_config,
#endif
#ifdef CONFIG_NET_POLL_CONTROLLER
.ndo_poll_controller = efx_netpoll,
@@ -2433,7 +2434,7 @@ int efx_reset_up(struct efx_nic *efx, enum reset_type method, bool ok)
if (rc)
goto fail;
efx_restore_filters(efx);
- efx_sriov_reset(efx);
+ efx_siena_sriov_reset(efx);
mutex_unlock(&efx->mac_lock);
@@ -2826,7 +2827,7 @@ static void efx_pci_remove(struct pci_dev *pci_dev)
efx_disable_interrupts(efx);
rtnl_unlock();
- efx_sriov_fini(efx);
+ efx_siena_sriov_fini(efx);
efx_unregister_netdev(efx);
efx_mtd_remove(efx);
@@ -3023,7 +3024,7 @@ static int efx_pci_probe(struct pci_dev *pci_dev,
if (rc)
goto fail4;
- rc = efx_sriov_init(efx);
+ rc = efx_siena_sriov_init(efx);
if (rc)
netif_err(efx, probe, efx->net_dev,
"SR-IOV can't be enabled rc %d\n", rc);
diff --git a/drivers/net/ethernet/sfc/farch.c b/drivers/net/ethernet/sfc/farch.c
index 0274401..f5549a9 100644
--- a/drivers/net/ethernet/sfc/farch.c
+++ b/drivers/net/ethernet/sfc/farch.c
@@ -240,7 +240,7 @@ static int efx_alloc_special_buffer(struct efx_nic *efx,
buffer->index = efx->next_buffer_table;
efx->next_buffer_table += buffer->entries;
#ifdef CONFIG_SFC_SRIOV
- BUG_ON(efx_sriov_enabled(efx) &&
+ BUG_ON(efx_siena_sriov_enabled(efx) &&
nic_data->vf_buftbl_base < efx->next_buffer_table);
#endif
@@ -670,7 +670,7 @@ static int efx_farch_do_flush(struct efx_nic *efx)
* the firmware (though we will still have to poll for
* completion). If that fails, fall back to the old scheme.
*/
- if (efx_sriov_enabled(efx)) {
+ if (efx_siena_sriov_enabled(efx)) {
rc = efx_mcdi_flush_rxqs(efx);
if (!rc)
goto wait;
@@ -1198,13 +1198,13 @@ efx_farch_handle_driver_event(struct efx_channel *channel, efx_qword_t *event)
netif_vdbg(efx, hw, efx->net_dev, "channel %d TXQ %d flushed\n",
channel->channel, ev_sub_data);
efx_farch_handle_tx_flush_done(efx, event);
- efx_sriov_tx_flush_done(efx, event);
+ efx_siena_sriov_tx_flush_done(efx, event);
break;
case FSE_AZ_RX_DESCQ_FLS_DONE_EV:
netif_vdbg(efx, hw, efx->net_dev, "channel %d RXQ %d flushed\n",
channel->channel, ev_sub_data);
efx_farch_handle_rx_flush_done(efx, event);
- efx_sriov_rx_flush_done(efx, event);
+ efx_siena_sriov_rx_flush_done(efx, event);
break;
case FSE_AZ_EVQ_INIT_DONE_EV:
netif_dbg(efx, hw, efx->net_dev,
@@ -1243,7 +1243,7 @@ efx_farch_handle_driver_event(struct efx_channel *channel, efx_qword_t *event)
ev_sub_data);
efx_schedule_reset(efx, RESET_TYPE_DMA_ERROR);
} else
- efx_sriov_desc_fetch_err(efx, ev_sub_data);
+ efx_siena_sriov_desc_fetch_err(efx, ev_sub_data);
break;
case FSE_BZ_TX_DSC_ERROR_EV:
if (ev_sub_data < EFX_VI_BASE) {
@@ -1253,7 +1253,7 @@ efx_farch_handle_driver_event(struct efx_channel *channel, efx_qword_t *event)
ev_sub_data);
efx_schedule_reset(efx, RESET_TYPE_DMA_ERROR);
} else
- efx_sriov_desc_fetch_err(efx, ev_sub_data);
+ efx_siena_sriov_desc_fetch_err(efx, ev_sub_data);
break;
default:
netif_vdbg(efx, hw, efx->net_dev,
@@ -1318,7 +1318,7 @@ int efx_farch_ev_process(struct efx_channel *channel, int budget)
efx_farch_handle_driver_event(channel, &event);
break;
case FSE_CZ_EV_CODE_USER_EV:
- efx_sriov_event(channel, &event);
+ efx_siena_sriov_event(channel, &event);
break;
case FSE_CZ_EV_CODE_MCDI_EV:
efx_mcdi_process_event(channel, &event);
@@ -1685,7 +1685,7 @@ void efx_farch_dimension_resources(struct efx_nic *efx, unsigned sram_lim_qw)
vi_count = max(efx->n_channels, efx->n_tx_channels * EFX_TXQ_TYPES);
#ifdef CONFIG_SFC_SRIOV
- if (efx_sriov_wanted(efx)) {
+ if (efx_siena_sriov_wanted(efx)) {
unsigned vi_dc_entries, buftbl_free, entries_per_vf, vf_limit;
nic_data->vf_buftbl_base = buftbl_min;
diff --git a/drivers/net/ethernet/sfc/mcdi.c b/drivers/net/ethernet/sfc/mcdi.c
index 5239cf9..d37928f 100644
--- a/drivers/net/ethernet/sfc/mcdi.c
+++ b/drivers/net/ethernet/sfc/mcdi.c
@@ -1035,7 +1035,7 @@ void efx_mcdi_process_event(struct efx_channel *channel,
/* MAC stats are gather lazily. We can ignore this. */
break;
case MCDI_EVENT_CODE_FLR:
- efx_sriov_flr(efx, MCDI_EVENT_FIELD(*event, FLR_VF));
+ efx_siena_sriov_flr(efx, MCDI_EVENT_FIELD(*event, FLR_VF));
break;
case MCDI_EVENT_CODE_PTP_RX:
case MCDI_EVENT_CODE_PTP_FAULT:
diff --git a/drivers/net/ethernet/sfc/nic.h b/drivers/net/ethernet/sfc/nic.h
index b5fe1f2..1ab3eda 100644
--- a/drivers/net/ethernet/sfc/nic.h
+++ b/drivers/net/ethernet/sfc/nic.h
@@ -540,62 +540,66 @@ struct efx_ef10_nic_data {
#ifdef CONFIG_SFC_SRIOV
-static inline bool efx_sriov_wanted(struct efx_nic *efx)
+static inline bool efx_siena_sriov_wanted(struct efx_nic *efx)
{
return efx->vf_count != 0;
}
-static inline bool efx_sriov_enabled(struct efx_nic *efx)
+
+static inline bool efx_siena_sriov_enabled(struct efx_nic *efx)
{
return efx->vf_init_count != 0;
}
+
static inline unsigned int efx_vf_size(struct efx_nic *efx)
{
return 1 << efx->vi_scale;
}
int efx_init_sriov(void);
-void efx_sriov_probe(struct efx_nic *efx);
-int efx_sriov_init(struct efx_nic *efx);
-void efx_sriov_mac_address_changed(struct efx_nic *efx);
-void efx_sriov_tx_flush_done(struct efx_nic *efx, efx_qword_t *event);
-void efx_sriov_rx_flush_done(struct efx_nic *efx, efx_qword_t *event);
-void efx_sriov_event(struct efx_channel *channel, efx_qword_t *event);
-void efx_sriov_desc_fetch_err(struct efx_nic *efx, unsigned dmaq);
-void efx_sriov_flr(struct efx_nic *efx, unsigned flr);
-void efx_sriov_reset(struct efx_nic *efx);
-void efx_sriov_fini(struct efx_nic *efx);
+void efx_siena_sriov_probe(struct efx_nic *efx);
+int efx_siena_sriov_init(struct efx_nic *efx);
+void efx_siena_sriov_mac_address_changed(struct efx_nic *efx);
+void efx_siena_sriov_tx_flush_done(struct efx_nic *efx, efx_qword_t *event);
+void efx_siena_sriov_rx_flush_done(struct efx_nic *efx, efx_qword_t *event);
+void efx_siena_sriov_event(struct efx_channel *channel, efx_qword_t *event);
+void efx_siena_sriov_desc_fetch_err(struct efx_nic *efx, unsigned dmaq);
+void efx_siena_sriov_flr(struct efx_nic *efx, unsigned flr);
+void efx_siena_sriov_reset(struct efx_nic *efx);
+void efx_siena_sriov_fini(struct efx_nic *efx);
void efx_fini_sriov(void);
#else
-static inline bool efx_sriov_wanted(struct efx_nic *efx) { return false; }
-static inline bool efx_sriov_enabled(struct efx_nic *efx) { return false; }
+static inline bool efx_siena_sriov_wanted(struct efx_nic *efx) { return false; }
+static inline bool efx_siena_sriov_enabled(struct efx_nic *efx) { return false; }
static inline unsigned int efx_vf_size(struct efx_nic *efx) { return 0; }
static inline int efx_init_sriov(void) { return 0; }
-static inline void efx_sriov_probe(struct efx_nic *efx) {}
-static inline int efx_sriov_init(struct efx_nic *efx) { return -EOPNOTSUPP; }
-static inline void efx_sriov_mac_address_changed(struct efx_nic *efx) {}
-static inline void efx_sriov_tx_flush_done(struct efx_nic *efx,
- efx_qword_t *event) {}
-static inline void efx_sriov_rx_flush_done(struct efx_nic *efx,
- efx_qword_t *event) {}
-static inline void efx_sriov_event(struct efx_channel *channel,
- efx_qword_t *event) {}
-static inline void efx_sriov_desc_fetch_err(struct efx_nic *efx, unsigned dmaq) {}
-static inline void efx_sriov_flr(struct efx_nic *efx, unsigned flr) {}
-static inline void efx_sriov_reset(struct efx_nic *efx) {}
-static inline void efx_sriov_fini(struct efx_nic *efx) {}
+static inline void efx_siena_sriov_probe(struct efx_nic *efx) {}
+static inline int efx_siena_sriov_init(struct efx_nic *efx) { return -EOPNOTSUPP; }
+static inline void efx_siena_sriov_mac_address_changed(struct efx_nic *efx) {}
+static inline void efx_siena_sriov_tx_flush_done(struct efx_nic *efx,
+ efx_qword_t *event) {}
+static inline void efx_siena_sriov_rx_flush_done(struct efx_nic *efx,
+ efx_qword_t *event) {}
+static inline void efx_siena_sriov_event(struct efx_channel *channel,
+ efx_qword_t *event) {}
+static inline void efx_siena_sriov_desc_fetch_err(struct efx_nic *efx,
+ unsigned dmaq) {}
+static inline void efx_siena_sriov_flr(struct efx_nic *efx, unsigned flr) {}
+static inline void efx_siena_sriov_reset(struct efx_nic *efx) {}
+static inline void efx_siena_sriov_fini(struct efx_nic *efx) {}
static inline void efx_fini_sriov(void) {}
#endif
-int efx_sriov_set_vf_mac(struct net_device *dev, int vf, u8 *mac);
-int efx_sriov_set_vf_vlan(struct net_device *dev, int vf, u16 vlan, u8 qos);
-int efx_sriov_get_vf_config(struct net_device *dev, int vf,
- struct ifla_vf_info *ivf);
-int efx_sriov_set_vf_spoofchk(struct net_device *net_dev, int vf,
- bool spoofchk);
+int efx_siena_sriov_set_vf_mac(struct net_device *dev, int vf, u8 *mac);
+int efx_siena_sriov_set_vf_vlan(struct net_device *dev, int vf,
+ u16 vlan, u8 qos);
+int efx_siena_sriov_get_vf_config(struct net_device *dev, int vf,
+ struct ifla_vf_info *ivf);
+int efx_siena_sriov_set_vf_spoofchk(struct net_device *net_dev, int vf,
+ bool spoofchk);
struct ethtool_ts_info;
int efx_ptp_probe(struct efx_nic *efx, struct efx_channel *channel);
diff --git a/drivers/net/ethernet/sfc/siena.c b/drivers/net/ethernet/sfc/siena.c
index ffce06d..cf40d60 100644
--- a/drivers/net/ethernet/sfc/siena.c
+++ b/drivers/net/ethernet/sfc/siena.c
@@ -307,7 +307,7 @@ static int siena_probe_nic(struct efx_nic *efx)
if (rc)
goto fail5;
- efx_sriov_probe(efx);
+ efx_siena_sriov_probe(efx);
efx_ptp_defer_probe_with_channel(efx);
return 0;
diff --git a/drivers/net/ethernet/sfc/siena_sriov.c b/drivers/net/ethernet/sfc/siena_sriov.c
index 2b75eee..a8bbbad 100644
--- a/drivers/net/ethernet/sfc/siena_sriov.c
+++ b/drivers/net/ethernet/sfc/siena_sriov.c
@@ -66,7 +66,7 @@ enum efx_vf_tx_filter_mode {
* @status_lock: Mutex protecting @msg_seqno, @status_addr, @addr,
* @peer_page_addrs and @peer_page_count from simultaneous
* updates by the VM and consumption by
- * efx_sriov_update_vf_addr()
+ * efx_siena_sriov_update_vf_addr()
* @peer_page_addrs: Pointer to an array of guest pages for local addresses.
* @peer_page_count: Number of entries in @peer_page_count.
* @evq0_addrs: Array of guest pages backing evq0.
@@ -194,8 +194,8 @@ static unsigned abs_index(struct efx_vf *vf, unsigned index)
return EFX_VI_BASE + vf->index * efx_vf_size(vf->efx) + index;
}
-static int efx_sriov_cmd(struct efx_nic *efx, bool enable,
- unsigned *vi_scale_out, unsigned *vf_total_out)
+static int efx_siena_sriov_cmd(struct efx_nic *efx, bool enable,
+ unsigned *vi_scale_out, unsigned *vf_total_out)
{
MCDI_DECLARE_BUF(inbuf, MC_CMD_SRIOV_IN_LEN);
MCDI_DECLARE_BUF(outbuf, MC_CMD_SRIOV_OUT_LEN);
@@ -227,7 +227,7 @@ static int efx_sriov_cmd(struct efx_nic *efx, bool enable,
return 0;
}
-static void efx_sriov_usrev(struct efx_nic *efx, bool enabled)
+static void efx_siena_sriov_usrev(struct efx_nic *efx, bool enabled)
{
struct siena_nic_data *nic_data = efx->nic_data;
efx_oword_t reg;
@@ -238,8 +238,9 @@ static void efx_sriov_usrev(struct efx_nic *efx, bool enabled)
efx_writeo(efx, ®, FR_CZ_USR_EV_CFG);
}
-static int efx_sriov_memcpy(struct efx_nic *efx, struct efx_memcpy_req *req,
- unsigned int count)
+static int efx_siena_sriov_memcpy(struct efx_nic *efx,
+ struct efx_memcpy_req *req,
+ unsigned int count)
{
MCDI_DECLARE_BUF(inbuf, MCDI_CTL_SDU_LEN_MAX_V1);
MCDI_DECLARE_STRUCT_PTR(record);
@@ -298,7 +299,7 @@ out:
/* The TX filter is entirely controlled by this driver, and is modified
* underneath the feet of the VF
*/
-static void efx_sriov_reset_tx_filter(struct efx_vf *vf)
+static void efx_siena_sriov_reset_tx_filter(struct efx_vf *vf)
{
struct efx_nic *efx = vf->efx;
struct efx_filter_spec filter;
@@ -342,7 +343,7 @@ static void efx_sriov_reset_tx_filter(struct efx_vf *vf)
}
/* The RX filter is managed here on behalf of the VF driver */
-static void efx_sriov_reset_rx_filter(struct efx_vf *vf)
+static void efx_siena_sriov_reset_rx_filter(struct efx_vf *vf)
{
struct efx_nic *efx = vf->efx;
struct efx_filter_spec filter;
@@ -381,22 +382,22 @@ static void efx_sriov_reset_rx_filter(struct efx_vf *vf)
}
}
-static void __efx_sriov_update_vf_addr(struct efx_vf *vf)
+static void __efx_siena_sriov_update_vf_addr(struct efx_vf *vf)
{
struct efx_nic *efx = vf->efx;
struct siena_nic_data *nic_data = efx->nic_data;
- efx_sriov_reset_tx_filter(vf);
- efx_sriov_reset_rx_filter(vf);
+ efx_siena_sriov_reset_tx_filter(vf);
+ efx_siena_sriov_reset_rx_filter(vf);
queue_work(vfdi_workqueue, &nic_data->peer_work);
}
/* Push the peer list to this VF. The caller must hold status_lock to interlock
* with VFDI requests, and they must be serialised against manipulation of
* local_page_list, either by acquiring local_lock or by running from
- * efx_sriov_peer_work()
+ * efx_siena_sriov_peer_work()
*/
-static void __efx_sriov_push_vf_status(struct efx_vf *vf)
+static void __efx_siena_sriov_push_vf_status(struct efx_vf *vf)
{
struct efx_nic *efx = vf->efx;
struct siena_nic_data *nic_data = efx->nic_data;
@@ -449,7 +450,7 @@ static void __efx_sriov_push_vf_status(struct efx_vf *vf)
copy[pos].length = EFX_PAGE_SIZE;
if (++pos == ARRAY_SIZE(copy)) {
- efx_sriov_memcpy(efx, copy, ARRAY_SIZE(copy));
+ efx_siena_sriov_memcpy(efx, copy, ARRAY_SIZE(copy));
pos = 0;
}
++count;
@@ -461,7 +462,7 @@ static void __efx_sriov_push_vf_status(struct efx_vf *vf)
copy[pos].to_addr = vf->status_addr + offsetof(struct vfdi_status,
generation_end);
copy[pos].length = sizeof(status->generation_end);
- efx_sriov_memcpy(efx, copy, pos + 1);
+ efx_siena_sriov_memcpy(efx, copy, pos + 1);
/* Notify the guest */
EFX_POPULATE_QWORD_3(event,
@@ -474,8 +475,8 @@ static void __efx_sriov_push_vf_status(struct efx_vf *vf)
&event);
}
-static void efx_sriov_bufs(struct efx_nic *efx, unsigned offset,
- u64 *addr, unsigned count)
+static void efx_siena_sriov_bufs(struct efx_nic *efx, unsigned offset,
+ u64 *addr, unsigned count)
{
efx_qword_t buf;
unsigned pos;
@@ -544,7 +545,7 @@ static int efx_vfdi_init_evq(struct efx_vf *vf)
return VFDI_RC_EINVAL;
}
- efx_sriov_bufs(efx, buftbl, req->u.init_evq.addr, buf_count);
+ efx_siena_sriov_bufs(efx, buftbl, req->u.init_evq.addr, buf_count);
EFX_POPULATE_OWORD_3(reg,
FRF_CZ_TIMER_Q_EN, 1,
@@ -589,7 +590,7 @@ static int efx_vfdi_init_rxq(struct efx_vf *vf)
}
if (__test_and_set_bit(req->u.init_rxq.index, vf->rxq_mask))
++vf->rxq_count;
- efx_sriov_bufs(efx, buftbl, req->u.init_rxq.addr, buf_count);
+ efx_siena_sriov_bufs(efx, buftbl, req->u.init_rxq.addr, buf_count);
label = req->u.init_rxq.label & EFX_FIELD_MASK(FRF_AZ_RX_DESCQ_LABEL);
EFX_POPULATE_OWORD_6(reg,
@@ -633,7 +634,7 @@ static int efx_vfdi_init_txq(struct efx_vf *vf)
if (__test_and_set_bit(req->u.init_txq.index, vf->txq_mask))
++vf->txq_count;
mutex_unlock(&vf->txq_lock);
- efx_sriov_bufs(efx, buftbl, req->u.init_txq.addr, buf_count);
+ efx_siena_sriov_bufs(efx, buftbl, req->u.init_txq.addr, buf_count);
eth_filt_en = vf->tx_filter_mode == VF_TX_FILTER_ON;
@@ -747,8 +748,8 @@ static int efx_vfdi_fini_all_queues(struct efx_vf *vf)
efx_writeo_table(efx, ®, FR_BZ_TIMER_TBL,
vf_offset + index);
}
- efx_sriov_bufs(efx, vf->buftbl_base, NULL,
- EFX_VF_BUFTBL_PER_VI * efx_vf_size(efx));
+ efx_siena_sriov_bufs(efx, vf->buftbl_base, NULL,
+ EFX_VF_BUFTBL_PER_VI * efx_vf_size(efx));
efx_vfdi_flush_clear(vf);
vf->evq0_count = 0;
@@ -782,7 +783,7 @@ static int efx_vfdi_insert_filter(struct efx_vf *vf)
vf->rx_filter_qid = vf_rxq;
vf->rx_filtering = true;
- efx_sriov_reset_rx_filter(vf);
+ efx_siena_sriov_reset_rx_filter(vf);
queue_work(vfdi_workqueue, &nic_data->peer_work);
return VFDI_RC_SUCCESS;
@@ -794,7 +795,7 @@ static int efx_vfdi_remove_all_filters(struct efx_vf *vf)
struct siena_nic_data *nic_data = efx->nic_data;
vf->rx_filtering = false;
- efx_sriov_reset_rx_filter(vf);
+ efx_siena_sriov_reset_rx_filter(vf);
queue_work(vfdi_workqueue, &nic_data->peer_work);
return VFDI_RC_SUCCESS;
@@ -838,7 +839,7 @@ static int efx_vfdi_set_status_page(struct efx_vf *vf)
}
}
- __efx_sriov_push_vf_status(vf);
+ __efx_siena_sriov_push_vf_status(vf);
mutex_unlock(&vf->status_lock);
mutex_unlock(&nic_data->local_lock);
@@ -867,7 +868,7 @@ static const efx_vfdi_op_t vfdi_ops[VFDI_OP_LIMIT] = {
[VFDI_OP_CLEAR_STATUS_PAGE] = efx_vfdi_clear_status_page,
};
-static void efx_sriov_vfdi(struct work_struct *work)
+static void efx_siena_sriov_vfdi(struct work_struct *work)
{
struct efx_vf *vf = container_of(work, struct efx_vf, req);
struct efx_nic *efx = vf->efx;
@@ -882,7 +883,7 @@ static void efx_sriov_vfdi(struct work_struct *work)
copy[0].to_rid = efx->pci_dev->devfn;
copy[0].to_addr = vf->buf.dma_addr;
copy[0].length = EFX_PAGE_SIZE;
- rc = efx_sriov_memcpy(efx, copy, 1);
+ rc = efx_siena_sriov_memcpy(efx, copy, 1);
if (rc) {
/* If we can't get the request, we can't reply to the caller */
if (net_ratelimit())
@@ -926,7 +927,7 @@ static void efx_sriov_vfdi(struct work_struct *work)
copy[1].to_addr = vf->req_addr + offsetof(struct vfdi_req, op);
copy[1].length = sizeof(req->op);
- (void) efx_sriov_memcpy(efx, copy, ARRAY_SIZE(copy));
+ (void)efx_siena_sriov_memcpy(efx, copy, ARRAY_SIZE(copy));
}
@@ -935,7 +936,8 @@ static void efx_sriov_vfdi(struct work_struct *work)
* event ring in guest memory with VFDI reset events, then (re-initialise) the
* event queue to raise an interrupt. The guest driver will then recover.
*/
-static void efx_sriov_reset_vf(struct efx_vf *vf, struct efx_buffer *buffer)
+static void efx_siena_sriov_reset_vf(struct efx_vf *vf,
+ struct efx_buffer *buffer)
{
struct efx_nic *efx = vf->efx;
struct efx_memcpy_req copy_req[4];
@@ -971,7 +973,7 @@ static void efx_sriov_reset_vf(struct efx_vf *vf, struct efx_buffer *buffer)
copy_req[k].to_addr = vf->evq0_addrs[pos + k];
copy_req[k].length = EFX_PAGE_SIZE;
}
- rc = efx_sriov_memcpy(efx, copy_req, count);
+ rc = efx_siena_sriov_memcpy(efx, copy_req, count);
if (rc) {
if (net_ratelimit())
netif_err(efx, hw, efx->net_dev,
@@ -984,7 +986,7 @@ static void efx_sriov_reset_vf(struct efx_vf *vf, struct efx_buffer *buffer)
/* Reinitialise, arm and trigger evq0 */
abs_evq = abs_index(vf, 0);
buftbl = EFX_BUFTBL_EVQ_BASE(vf, 0);
- efx_sriov_bufs(efx, buftbl, vf->evq0_addrs, vf->evq0_count);
+ efx_siena_sriov_bufs(efx, buftbl, vf->evq0_addrs, vf->evq0_count);
EFX_POPULATE_OWORD_3(reg,
FRF_CZ_TIMER_Q_EN, 1,
@@ -1002,19 +1004,19 @@ static void efx_sriov_reset_vf(struct efx_vf *vf, struct efx_buffer *buffer)
mutex_unlock(&vf->status_lock);
}
-static void efx_sriov_reset_vf_work(struct work_struct *work)
+static void efx_siena_sriov_reset_vf_work(struct work_struct *work)
{
struct efx_vf *vf = container_of(work, struct efx_vf, req);
struct efx_nic *efx = vf->efx;
struct efx_buffer buf;
if (!efx_nic_alloc_buffer(efx, &buf, EFX_PAGE_SIZE, GFP_NOIO)) {
- efx_sriov_reset_vf(vf, &buf);
+ efx_siena_sriov_reset_vf(vf, &buf);
efx_nic_free_buffer(efx, &buf);
}
}
-static void efx_sriov_handle_no_channel(struct efx_nic *efx)
+static void efx_siena_sriov_handle_no_channel(struct efx_nic *efx)
{
netif_err(efx, drv, efx->net_dev,
"ERROR: IOV requires MSI-X and 1 additional interrupt"
@@ -1022,7 +1024,7 @@ static void efx_sriov_handle_no_channel(struct efx_nic *efx)
efx->vf_count = 0;
}
-static int efx_sriov_probe_channel(struct efx_channel *channel)
+static int efx_siena_sriov_probe_channel(struct efx_channel *channel)
{
struct siena_nic_data *nic_data = channel->efx->nic_data;
nic_data->vfdi_channel = channel;
@@ -1031,28 +1033,29 @@ static int efx_sriov_probe_channel(struct efx_channel *channel)
}
static void
-efx_sriov_get_channel_name(struct efx_channel *channel, char *buf, size_t len)
+efx_siena_sriov_get_channel_name(struct efx_channel *channel,
+ char *buf, size_t len)
{
snprintf(buf, len, "%s-iov", channel->efx->name);
}
-static const struct efx_channel_type efx_sriov_channel_type = {
- .handle_no_channel = efx_sriov_handle_no_channel,
- .pre_probe = efx_sriov_probe_channel,
+static const struct efx_channel_type efx_siena_sriov_channel_type = {
+ .handle_no_channel = efx_siena_sriov_handle_no_channel,
+ .pre_probe = efx_siena_sriov_probe_channel,
.post_remove = efx_channel_dummy_op_void,
- .get_name = efx_sriov_get_channel_name,
+ .get_name = efx_siena_sriov_get_channel_name,
/* no copy operation; channel must not be reallocated */
.keep_eventq = true,
};
-void efx_sriov_probe(struct efx_nic *efx)
+void efx_siena_sriov_probe(struct efx_nic *efx)
{
unsigned count;
if (!max_vfs)
return;
- if (efx_sriov_cmd(efx, false, &efx->vi_scale, &count))
+ if (efx_siena_sriov_cmd(efx, false, &efx->vi_scale, &count))
return;
if (count > 0 && count > max_vfs)
count = max_vfs;
@@ -1060,14 +1063,14 @@ void efx_sriov_probe(struct efx_nic *efx)
/* efx_nic_dimension_resources() will reduce vf_count as appopriate */
efx->vf_count = count;
- efx->extra_channel_type[EFX_EXTRA_CHANNEL_IOV] = &efx_sriov_channel_type;
+ efx->extra_channel_type[EFX_EXTRA_CHANNEL_IOV] = &efx_siena_sriov_channel_type;
}
/* Copy the list of individual addresses into the vfdi_status.peers
* array and auxillary pages, protected by %local_lock. Drop that lock
* and then broadcast the address list to every VF.
*/
-static void efx_sriov_peer_work(struct work_struct *data)
+static void efx_siena_sriov_peer_work(struct work_struct *data)
{
struct siena_nic_data *nic_data = container_of(data,
struct siena_nic_data,
@@ -1156,12 +1159,12 @@ static void efx_sriov_peer_work(struct work_struct *data)
mutex_lock(&vf->status_lock);
if (vf->status_addr)
- __efx_sriov_push_vf_status(vf);
+ __efx_siena_sriov_push_vf_status(vf);
mutex_unlock(&vf->status_lock);
}
}
-static void efx_sriov_free_local(struct efx_nic *efx)
+static void efx_siena_sriov_free_local(struct efx_nic *efx)
{
struct siena_nic_data *nic_data = efx->nic_data;
struct efx_local_addr *local_addr;
@@ -1184,7 +1187,7 @@ static void efx_sriov_free_local(struct efx_nic *efx)
}
}
-static int efx_sriov_vf_alloc(struct efx_nic *efx)
+static int efx_siena_sriov_vf_alloc(struct efx_nic *efx)
{
unsigned index;
struct efx_vf *vf;
@@ -1201,8 +1204,8 @@ static int efx_sriov_vf_alloc(struct efx_nic *efx)
vf->rx_filter_id = -1;
vf->tx_filter_mode = VF_TX_FILTER_AUTO;
vf->tx_filter_id = -1;
- INIT_WORK(&vf->req, efx_sriov_vfdi);
- INIT_WORK(&vf->reset_work, efx_sriov_reset_vf_work);
+ INIT_WORK(&vf->req, efx_siena_sriov_vfdi);
+ INIT_WORK(&vf->reset_work, efx_siena_sriov_reset_vf_work);
init_waitqueue_head(&vf->flush_waitq);
mutex_init(&vf->status_lock);
mutex_init(&vf->txq_lock);
@@ -1211,7 +1214,7 @@ static int efx_sriov_vf_alloc(struct efx_nic *efx)
return 0;
}
-static void efx_sriov_vfs_fini(struct efx_nic *efx)
+static void efx_siena_sriov_vfs_fini(struct efx_nic *efx)
{
struct efx_vf *vf;
unsigned int pos;
@@ -1228,7 +1231,7 @@ static void efx_sriov_vfs_fini(struct efx_nic *efx)
}
}
-static int efx_sriov_vfs_init(struct efx_nic *efx)
+static int efx_siena_sriov_vfs_init(struct efx_nic *efx)
{
struct pci_dev *pci_dev = efx->pci_dev;
struct siena_nic_data *nic_data = efx->nic_data;
@@ -1270,11 +1273,11 @@ static int efx_sriov_vfs_init(struct efx_nic *efx)
return 0;
fail:
- efx_sriov_vfs_fini(efx);
+ efx_siena_sriov_vfs_fini(efx);
return rc;
}
-int efx_sriov_init(struct efx_nic *efx)
+int efx_siena_sriov_init(struct efx_nic *efx)
{
struct net_device *net_dev = efx->net_dev;
struct siena_nic_data *nic_data = efx->nic_data;
@@ -1289,7 +1292,7 @@ int efx_sriov_init(struct efx_nic *efx)
if (efx->vf_count == 0)
return 0;
- rc = efx_sriov_cmd(efx, true, NULL, NULL);
+ rc = efx_siena_sriov_cmd(efx, true, NULL, NULL);
if (rc)
goto fail_cmd;
@@ -1307,16 +1310,16 @@ int efx_sriov_init(struct efx_nic *efx)
vfdi_status->peer_count = 1 + efx->vf_count;
vfdi_status->timer_quantum_ns = efx->timer_quantum_ns;
- rc = efx_sriov_vf_alloc(efx);
+ rc = efx_siena_sriov_vf_alloc(efx);
if (rc)
goto fail_alloc;
mutex_init(&nic_data->local_lock);
- INIT_WORK(&nic_data->peer_work, efx_sriov_peer_work);
+ INIT_WORK(&nic_data->peer_work, efx_siena_sriov_peer_work);
INIT_LIST_HEAD(&nic_data->local_addr_list);
INIT_LIST_HEAD(&nic_data->local_page_list);
- rc = efx_sriov_vfs_init(efx);
+ rc = efx_siena_sriov_vfs_init(efx);
if (rc)
goto fail_vfs;
@@ -1325,7 +1328,7 @@ int efx_sriov_init(struct efx_nic *efx)
efx->vf_init_count = efx->vf_count;
rtnl_unlock();
- efx_sriov_usrev(efx, true);
+ efx_siena_sriov_usrev(efx, true);
/* At this point we must be ready to accept VFDI requests */
@@ -1339,24 +1342,24 @@ int efx_sriov_init(struct efx_nic *efx)
return 0;
fail_pci:
- efx_sriov_usrev(efx, false);
+ efx_siena_sriov_usrev(efx, false);
rtnl_lock();
efx->vf_init_count = 0;
rtnl_unlock();
- efx_sriov_vfs_fini(efx);
+ efx_siena_sriov_vfs_fini(efx);
fail_vfs:
cancel_work_sync(&nic_data->peer_work);
- efx_sriov_free_local(efx);
+ efx_siena_sriov_free_local(efx);
kfree(efx->vf);
fail_alloc:
efx_nic_free_buffer(efx, &nic_data->vfdi_status);
fail_status:
- efx_sriov_cmd(efx, false, NULL, NULL);
+ efx_siena_sriov_cmd(efx, false, NULL, NULL);
fail_cmd:
return rc;
}
-void efx_sriov_fini(struct efx_nic *efx)
+void efx_siena_sriov_fini(struct efx_nic *efx)
{
struct efx_vf *vf;
unsigned int pos;
@@ -1367,7 +1370,7 @@ void efx_sriov_fini(struct efx_nic *efx)
/* Disable all interfaces to reconfiguration */
BUG_ON(nic_data->vfdi_channel->enabled);
- efx_sriov_usrev(efx, false);
+ efx_siena_sriov_usrev(efx, false);
rtnl_lock();
efx->vf_init_count = 0;
rtnl_unlock();
@@ -1383,14 +1386,14 @@ void efx_sriov_fini(struct efx_nic *efx)
pci_disable_sriov(efx->pci_dev);
/* Tear down back-end state */
- efx_sriov_vfs_fini(efx);
- efx_sriov_free_local(efx);
+ efx_siena_sriov_vfs_fini(efx);
+ efx_siena_sriov_free_local(efx);
kfree(efx->vf);
efx_nic_free_buffer(efx, &nic_data->vfdi_status);
- efx_sriov_cmd(efx, false, NULL, NULL);
+ efx_siena_sriov_cmd(efx, false, NULL, NULL);
}
-void efx_sriov_event(struct efx_channel *channel, efx_qword_t *event)
+void efx_siena_sriov_event(struct efx_channel *channel, efx_qword_t *event)
{
struct efx_nic *efx = channel->efx;
struct efx_vf *vf;
@@ -1447,7 +1450,7 @@ error:
vf->req_seqno = seq + 1;
}
-void efx_sriov_flr(struct efx_nic *efx, unsigned vf_i)
+void efx_siena_sriov_flr(struct efx_nic *efx, unsigned vf_i)
{
struct efx_vf *vf;
@@ -1464,7 +1467,7 @@ void efx_sriov_flr(struct efx_nic *efx, unsigned vf_i)
vf->evq0_count = 0;
}
-void efx_sriov_mac_address_changed(struct efx_nic *efx)
+void efx_siena_sriov_mac_address_changed(struct efx_nic *efx)
{
struct siena_nic_data *nic_data = efx->nic_data;
struct vfdi_status *vfdi_status = nic_data->vfdi_status.addr;
@@ -1476,7 +1479,7 @@ void efx_sriov_mac_address_changed(struct efx_nic *efx)
queue_work(vfdi_workqueue, &nic_data->peer_work);
}
-void efx_sriov_tx_flush_done(struct efx_nic *efx, efx_qword_t *event)
+void efx_siena_sriov_tx_flush_done(struct efx_nic *efx, efx_qword_t *event)
{
struct efx_vf *vf;
unsigned queue, qid;
@@ -1495,7 +1498,7 @@ void efx_sriov_tx_flush_done(struct efx_nic *efx, efx_qword_t *event)
wake_up(&vf->flush_waitq);
}
-void efx_sriov_rx_flush_done(struct efx_nic *efx, efx_qword_t *event)
+void efx_siena_sriov_rx_flush_done(struct efx_nic *efx, efx_qword_t *event)
{
struct efx_vf *vf;
unsigned ev_failed, queue, qid;
@@ -1520,7 +1523,7 @@ void efx_sriov_rx_flush_done(struct efx_nic *efx, efx_qword_t *event)
}
/* Called from napi. Schedule the reset work item */
-void efx_sriov_desc_fetch_err(struct efx_nic *efx, unsigned dmaq)
+void efx_siena_sriov_desc_fetch_err(struct efx_nic *efx, unsigned dmaq)
{
struct efx_vf *vf;
unsigned int rel;
@@ -1536,7 +1539,7 @@ void efx_sriov_desc_fetch_err(struct efx_nic *efx, unsigned dmaq)
}
/* Reset all VFs */
-void efx_sriov_reset(struct efx_nic *efx)
+void efx_siena_sriov_reset(struct efx_nic *efx)
{
unsigned int vf_i;
struct efx_buffer buf;
@@ -1547,15 +1550,15 @@ void efx_sriov_reset(struct efx_nic *efx)
if (efx->vf_init_count == 0)
return;
- efx_sriov_usrev(efx, true);
- (void)efx_sriov_cmd(efx, true, NULL, NULL);
+ efx_siena_sriov_usrev(efx, true);
+ (void)efx_siena_sriov_cmd(efx, true, NULL, NULL);
if (efx_nic_alloc_buffer(efx, &buf, EFX_PAGE_SIZE, GFP_NOIO))
return;
for (vf_i = 0; vf_i < efx->vf_init_count; ++vf_i) {
vf = efx->vf + vf_i;
- efx_sriov_reset_vf(vf, &buf);
+ efx_siena_sriov_reset_vf(vf, &buf);
}
efx_nic_free_buffer(efx, &buf);
@@ -1563,8 +1566,8 @@ void efx_sriov_reset(struct efx_nic *efx)
int efx_init_sriov(void)
{
- /* A single threaded workqueue is sufficient. efx_sriov_vfdi() and
- * efx_sriov_peer_work() spend almost all their time sleeping for
+ /* A single threaded workqueue is sufficient. efx_siena_sriov_vfdi() and
+ * efx_siena_sriov_peer_work() spend almost all their time sleeping for
* MCDI to complete anyway
*/
vfdi_workqueue = create_singlethread_workqueue("sfc_vfdi");
@@ -1579,7 +1582,7 @@ void efx_fini_sriov(void)
destroy_workqueue(vfdi_workqueue);
}
-int efx_sriov_set_vf_mac(struct net_device *net_dev, int vf_i, u8 *mac)
+int efx_siena_sriov_set_vf_mac(struct net_device *net_dev, int vf_i, u8 *mac)
{
struct efx_nic *efx = netdev_priv(net_dev);
struct efx_vf *vf;
@@ -1590,14 +1593,14 @@ int efx_sriov_set_vf_mac(struct net_device *net_dev, int vf_i, u8 *mac)
mutex_lock(&vf->status_lock);
ether_addr_copy(vf->addr.mac_addr, mac);
- __efx_sriov_update_vf_addr(vf);
+ __efx_siena_sriov_update_vf_addr(vf);
mutex_unlock(&vf->status_lock);
return 0;
}
-int efx_sriov_set_vf_vlan(struct net_device *net_dev, int vf_i,
- u16 vlan, u8 qos)
+int efx_siena_sriov_set_vf_vlan(struct net_device *net_dev, int vf_i,
+ u16 vlan, u8 qos)
{
struct efx_nic *efx = netdev_priv(net_dev);
struct efx_vf *vf;
@@ -1610,14 +1613,14 @@ int efx_sriov_set_vf_vlan(struct net_device *net_dev, int vf_i,
mutex_lock(&vf->status_lock);
tci = (vlan & VLAN_VID_MASK) | ((qos & 0x7) << VLAN_PRIO_SHIFT);
vf->addr.tci = htons(tci);
- __efx_sriov_update_vf_addr(vf);
+ __efx_siena_sriov_update_vf_addr(vf);
mutex_unlock(&vf->status_lock);
return 0;
}
-int efx_sriov_set_vf_spoofchk(struct net_device *net_dev, int vf_i,
- bool spoofchk)
+int efx_siena_sriov_set_vf_spoofchk(struct net_device *net_dev, int vf_i,
+ bool spoofchk)
{
struct efx_nic *efx = netdev_priv(net_dev);
struct efx_vf *vf;
@@ -1640,8 +1643,8 @@ int efx_sriov_set_vf_spoofchk(struct net_device *net_dev, int vf_i,
return rc;
}
-int efx_sriov_get_vf_config(struct net_device *net_dev, int vf_i,
- struct ifla_vf_info *ivi)
+int efx_siena_sriov_get_vf_config(struct net_device *net_dev, int vf_i,
+ struct ifla_vf_info *ivi)
{
struct efx_nic *efx = netdev_priv(net_dev);
struct efx_vf *vf;
^ permalink raw reply related
* Re: [PATCH net-next 2/2] net/mlx4_en: Support for configurable RSS hash function
From: Or Gerlitz @ 2014-11-05 12:27 UTC (permalink / raw)
To: Eyal Perry
Cc: Amir Vadai, David S. Miller, Ben Hutchings, netdev,
Yevgeny Petrilin
In-Reply-To: <1415188769-19593-3-git-send-email-amirv@mellanox.com>
On 11/5/2014 1:59 PM, Amir Vadai wrote:
> From: Eyal Perry <eyalpe@mellanox.com>
>
> The ConnectX HW is capable of using one of the following hash functions:
> Toeplitz and an XOR hash function.
> This patch implements ethtool_ops {get,set}_rxfh_func callbacks for the
> mlx4_en driver in order to query and configure the RSS hash function to
> be used by the device.
>
> Signed-off-by: Eyal Perry <eyalpe@mellanox.com>
> Signed-off-by: Amir Vadai <amirv@mellanox.com>
> ---
> drivers/net/ethernet/mellanox/mlx4/en_ethtool.c | 40 +++++++++++++++++++++++++
> drivers/net/ethernet/mellanox/mlx4/en_netdev.c | 9 ++++++
> drivers/net/ethernet/mellanox/mlx4/en_rx.c | 11 ++++---
> drivers/net/ethernet/mellanox/mlx4/mlx4_en.h | 3 +-
> 4 files changed, 58 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c
> index 8ea4d5b..f33785a 100644
> --- a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c
> +++ b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c
> @@ -973,6 +973,44 @@ static u32 mlx4_en_get_rxfh_indir_size(struct net_device *dev)
> return priv->rx_ring_num;
> }
>
> +static u32 mlx4_en_get_rxfh_func(struct net_device *dev)
> +{
> + struct mlx4_en_priv *priv = netdev_priv(dev);
> +
> + return priv->rss_hash_fn;
> +}
> +
> +static int mlx4_en_set_rxfh_func(struct net_device *dev, u32 hfunc)
> +{
> + struct mlx4_en_priv *priv = netdev_priv(dev);
> + struct mlx4_en_dev *mdev = priv->mdev;
> + u32 prev_rss_hash_fn = priv->rss_hash_fn;
> + int err = 0;
> +
> + if (!(hfunc & priv->rss_hash_fn_caps))
> + return -EINVAL;
> +
> + priv->rss_hash_fn = hfunc;
Seems that you are blindly setting here priv->rss_hash_fn to the
function (xor or top) requested
by the user w.o prior checking if the firmware actually supports that
(e.g test it against priv->rss_hash_fn_caps, right?
> + if (hfunc == RSS_HASH_TOP && !(dev->features & NETIF_F_RXHASH))
> + en_warn(priv,
> + "Toeplitz hash function should be used in conjunction with RX hashing for optimal performance\n");
> + if (hfunc == RSS_HASH_XOR && (dev->features & NETIF_F_RXHASH))
> + en_warn(priv,
> + "Enabling both XOR Hash function and RX Hashing can limit RPS functionality\n");
> +
> + mutex_lock(&mdev->state_lock);
> + if (priv->port_up && priv->rss_hash_fn != prev_rss_hash_fn) {
> + mlx4_en_stop_port(dev, 1);
> + err = mlx4_en_start_port(dev);
> + }
> + mutex_unlock(&mdev->state_lock);
> +
> + if (err)
> + en_err(priv, "Failed to restart port %d\n", priv->port);
> +
> + return err;
> +}
> +
> static int mlx4_en_get_rxfh(struct net_device *dev, u32 *ring_index, u8 *key)
> {
> struct mlx4_en_priv *priv = netdev_priv(dev);
> @@ -1799,6 +1837,8 @@ const struct ethtool_ops mlx4_en_ethtool_ops = {
> .get_rxnfc = mlx4_en_get_rxnfc,
> .set_rxnfc = mlx4_en_set_rxnfc,
> .get_rxfh_indir_size = mlx4_en_get_rxfh_indir_size,
> + .get_rxfh_func = mlx4_en_get_rxfh_func,
> + .set_rxfh_func = mlx4_en_set_rxfh_func,
> .get_rxfh = mlx4_en_get_rxfh,
> .set_rxfh = mlx4_en_set_rxfh,
> .get_channels = mlx4_en_get_channels,
> diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
> index 0efbae9..a9e96a6 100644
> --- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
> +++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
> @@ -2585,6 +2585,15 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
> dev->features |= NETIF_F_GSO_UDP_TUNNEL;
> }
>
> + if (mdev->dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_RSS_XOR) {
> + priv->rss_hash_fn_caps |= RSS_HASH_XOR;
> + priv->rss_hash_fn = RSS_HASH_XOR;
> + }
> + if (mdev->dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_RSS_TOP) {
> + priv->rss_hash_fn_caps |= RSS_HASH_TOP;
> + priv->rss_hash_fn = RSS_HASH_TOP;
> + }
> +
> mdev->pndev[port] = dev;
>
> netif_carrier_off(dev);
> diff --git a/drivers/net/ethernet/mellanox/mlx4/en_rx.c b/drivers/net/ethernet/mellanox/mlx4/en_rx.c
> index b173a0c..41c1ff9 100644
> --- a/drivers/net/ethernet/mellanox/mlx4/en_rx.c
> +++ b/drivers/net/ethernet/mellanox/mlx4/en_rx.c
> @@ -1113,10 +1113,13 @@ int mlx4_en_config_rss_steer(struct mlx4_en_priv *priv)
> }
>
> rss_context->flags = rss_mask;
> - rss_context->hash_fn = MLX4_RSS_HASH_TOP;
> - for (i = 0; i < 10; i++)
> - rss_context->rss_key[i] = cpu_to_be32(rsskey[i]);
> -
> + if (priv->rss_hash_fn & MLX4_RSS_HASH_XOR) {
> + rss_context->hash_fn = MLX4_RSS_HASH_XOR;
> + } else {
> + rss_context->hash_fn = MLX4_RSS_HASH_TOP;
> + for (i = 0; i < 10; i++)
> + rss_context->rss_key[i] = cpu_to_be32(rsskey[i]);
> + }
So this patch effectively changes the default from top to xor, right? is
that intentional? if yes, spare few words on the change log.
> err = mlx4_qp_to_ready(mdev->dev, &priv->res.mtt, &context,
> &rss_map->indir_qp, &rss_map->indir_state);
> if (err)
> diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
> index ef83d12..e1c3364 100644
> --- a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
> +++ b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
> @@ -375,7 +375,6 @@ struct mlx4_en_port_profile {
> };
>
> struct mlx4_en_profile {
> - int rss_xor;
> int udp_rss;
> u8 rss_mask;
> u32 active_ports;
> @@ -615,6 +614,8 @@ struct mlx4_en_priv {
> __be16 vxlan_port;
>
> u32 pflags;
> + u8 rss_hash_fn;
> + u8 rss_hash_fn_caps;
> };
>
> enum mlx4_en_wol {
^ permalink raw reply
* Re: [linux-nics] [PATCH net 3/5] fm10k: Implement ndo_gso_check()
From: Jeff Kirsher @ 2014-11-05 12:34 UTC (permalink / raw)
To: Joe Stringer
Cc: netdev, linux.nics, shahed.shaikh, sathya.perla, amirv,
linux-kernel, Dept-GELinuxNICDev, therbert
In-Reply-To: <1415138202-1197-4-git-send-email-joestringer@nicira.com>
[-- Attachment #1: Type: text/plain, Size: 756 bytes --]
On Tue, 2014-11-04 at 13:56 -0800, Joe Stringer wrote:
> ndo_gso_check() was recently introduced to allow NICs to report the
> offloading support that they have on a per-skb basis. Add an
> implementation for this driver which checks for something that looks
> like VXLAN.
>
> Implementation shamelessly stolen from Tom Herbert:
> http://thread.gmane.org/gmane.linux.network/332428/focus=333111
>
> Signed-off-by: Joe Stringer <joestringer@nicira.com>
> ---
> Should this driver report support for GSO on packets with tunnel
> headers
> up to 64B like the i40e driver does?
> ---
> drivers/net/ethernet/intel/fm10k/fm10k_netdev.c | 12 ++++++++++++
> 1 file changed, 12 insertions(+)
Thanks Joe, I will add your patch to my queue.
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 819 bytes --]
^ permalink raw reply
* Re: [PATCH net 2/5] i40e: Implement ndo_gso_check()
From: Jeff Kirsher @ 2014-11-05 12:35 UTC (permalink / raw)
To: Joe Stringer
Cc: netdev, sathya.perla, linux.nics, amirv, shahed.shaikh,
Dept-GELinuxNICDev, therbert, linux-kernel
In-Reply-To: <1415138202-1197-3-git-send-email-joestringer@nicira.com>
[-- Attachment #1: Type: text/plain, Size: 673 bytes --]
On Tue, 2014-11-04 at 13:56 -0800, Joe Stringer wrote:
> ndo_gso_check() was recently introduced to allow NICs to report the
> offloading support that they have on a per-skb basis. Add an
> implementation for this driver which checks for tunnel headers over
> UDP
> of up to 64 octets in length.
>
> Implementation shamelessly stolen from Tom Herbert:
> http://thread.gmane.org/gmane.linux.network/332428/focus=333111
>
> Signed-off-by: Joe Stringer <joestringer@nicira.com>
> ---
> drivers/net/ethernet/intel/i40e/i40e_main.c | 14 +++++++++++++-
> 1 file changed, 13 insertions(+), 1 deletion(-)
Thanks again Joe, I will add your patch to my queue.
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 819 bytes --]
^ permalink raw reply
* Re: [PATCH net 2/5] i40e: Implement ndo_gso_check()
From: Jeff Kirsher @ 2014-11-05 12:37 UTC (permalink / raw)
To: Jesse Gross, Shannon Nelson, Jesse Brandeburg
Cc: Joe Stringer, netdev, Sathya Perla, linux.nics, amirv,
shahed.shaikh, Dept-GELinuxNICDev, Tom Herbert,
Linux Kernel Mailing List
In-Reply-To: <CAEP_g=8rbJF5z92LV_c14KooU=i3x=9WpikocctcEUOdw5-oLA@mail.gmail.com>
[-- Attachment #1: Type: text/plain, Size: 1408 bytes --]
On Tue, 2014-11-04 at 15:45 -0800, Jesse Gross wrote:
> On Tue, Nov 4, 2014 at 1:56 PM, Joe Stringer <joestringer@nicira.com> wrote:
> > diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c
> > index c3a7f4a..21829b5 100644
> > --- a/drivers/net/ethernet/intel/i40e/i40e_main.c
> > +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
> > +static bool i40e_gso_check(struct sk_buff *skb, struct net_device *dev)
> > +{
> > + if ((skb_shinfo(skb)->gso_type & SKB_GSO_UDP_TUNNEL) &&
> > + (skb->inner_protocol_type != ENCAP_TYPE_ETHER ||
> > + skb->inner_protocol != htons(ETH_P_TEB) ||
> > + skb_inner_mac_header(skb) - skb_transport_header(skb) > 64))
> > + return false;
>
> I think it may be possible to even support a few more things here.
> According to the datasheet here:
> http://www.intel.com/content/dam/www/public/us/en/documents/datasheets/xl710-10-40-controller-datasheet.pdf
>
> This can actually support 64 bytes beyond the tunnel header, which
> would make for a total of 80 bytes. It looks like it can also support
> IPv4 or IPv6 beyond just Ethernet as the encapsulated protocol.
>
> Intel guys, can you confirm that this is correct?
I believe you are correct Jesse, but I will let Shannon Nelson or Jesse
Brandeburg respond since they are the i40e maintainers.
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 819 bytes --]
^ permalink raw reply
* Re: [PATCH net 0/5] Implement ndo_gso_check() for vxlan nics
From: Or Gerlitz @ 2014-11-05 12:38 UTC (permalink / raw)
To: Joe Stringer
Cc: Linux Netdev List, sathya.perla, Jeff Kirsher, linux.nics,
Amir Vadai, shahed.shaikh, Dept-GELinuxNICDev, Tom Herbert,
Linux Kernel
In-Reply-To: <1415138202-1197-1-git-send-email-joestringer@nicira.com>
On Tue, Nov 4, 2014 at 11:56 PM, Joe Stringer <joestringer@nicira.com> wrote:
> Most NICs that report NETIF_F_GSO_UDP_TUNNEL support VXLAN, and not other
> UDP-based encapsulation protocols where the format and size of the header may
> differ. This patch series implements ndo_gso_check() for these NICs,
> restricting the GSO handling to something that looks and smells like VXLAN.
>
> Implementation shamelessly stolen from Tom Herbert (with minor fixups):
> http://thread.gmane.org/gmane.linux.network/332428/focus=333111
Hi Joe,
1st, thanks for picking this task...2nd, for drivers that currently
support only pure VXLAN, I don't see the point
to replicate the helper suggested by Tom (good catch on the size check
to be 16 and not 12) four times and who know how more in the future.
Let's just have one generic helper and make the mlx4/be/fm10k/benet
drivers to have it as their ndo, OK?
Or.
>
> If there are particular differences for your driver on actual support, I'd like
> to hear about it. I adjusted the i40e driver to report support with tunnel
> headers of up to 64 octets, perhaps there are other specifics that I've missed.
>
> Joe Stringer (5):
> be2net: Implement ndo_gso_check()
> i40e: Implement ndo_gso_check()
> fm10k: Implement ndo_gso_check()
> net/mlx4_en: Implement ndo_gso_check()
> qlcnic: Implement ndo_gso_check()
>
> drivers/net/ethernet/emulex/benet/be_main.c | 12 ++++++++++++
> drivers/net/ethernet/intel/fm10k/fm10k_netdev.c | 12 ++++++++++++
> drivers/net/ethernet/intel/i40e/i40e_main.c | 14 +++++++++++++-
> drivers/net/ethernet/mellanox/mlx4/en_netdev.c | 12 ++++++++++++
> drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | 12 ++++++++++++
> 5 files changed, 61 insertions(+), 1 deletion(-)
>
> --
> 1.7.10.4
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" 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: "asix: Don't reset PHY on if_up for ASIX 88772" breaks net onarndale platform
From: Riku Voipio @ 2014-11-05 12:39 UTC (permalink / raw)
To: Stam, Michel [FINT]
Cc: Charles Keepax, davem, linux-usb, netdev, linux-kernel,
linux-samsung-soc
In-Reply-To: <C89EFD3CD56F64468D3D206D683A8D22039FFC5F@ldam-msx2.fugro-nl.local>
Hi Michel,
On Wed, Nov 05, 2014 at 01:04:37PM +0100, Stam, Michel [FINT] wrote:
> After looking around I found the reset value for the 8772 chip, which
> seems to be 0x1E1 (ANAR register).
>
> This equates to (according to include/uapi/linux/mii.h)
> ADVERTISE_ALL | ADVERTISE_CSMA.
>
> The register only seems to become 0 if the software reset fails.
>
> Unfortunately, this is exactly what I get when the patch is applied;
> asix 1-2:1.0 eth1: Failed to send software reset: ffffffb5
> asix 1-2:1.0 eth1: link reset failed (-75) usbnet usb-0000:00:1d.0-2,
> ASIX AX88772 USB 2.0 Ethernet
> asix 1-2:1.0 eth1: Failed to send software reset: ffffffb5
> asix 1-2:1.0 eth1: link reset failed (-75) usbnet usb-0000:00:1d.0-2,
> ASIX AX88772 USB 2.0 Ethernet
>
> A little while after this its 'Failed to enable software MII access'.
> The ethernet device fails to see any link or accept any ethtool -s
> command.
> My device has vid:devid 0b95:772a (ASIX Elec. Corp.).
> Can you tell me what device is on the Andale platform, Charles? Same
> vendor/device id?
Bus 003 Device 004: ID 0b95:772a ASIX Electronics Corp. AX88772A Fast Ethernet
> Another thing that bothers me is that dev->mii.advertising seems to
> contain the same value, so maybe that can be used instead of a call to
> asix_mdio_read(). Can anyone comment on its purpose? Should it be a
> shadow copy of the real register or something?
> Riku, can you test Charles' patch as well?
With that patch + revert to ax88772_reset network works. I'm unable to get
ethtool to work with that patch or with the original 3.17 state of asix.
Once i disable autoneg network doesn't just work.
> > >I think it would better to revert the change now and with less hurry
> > introduce a ethtool fix that doesn't break arndale.
> > I don't fully agree here;
> > I would like to point out that this commit is a revert itself. Fixing
> > the armdale will then cause breakage in other implementations, such as
> > ours. Blankly reverting breaks other peoples' implementations.
My concern is, that none of us with this problem is a linux network
drivers expert. And no such expert joined the thread to help us. Thus if
we hurry to have proper fix for 3.18, our fix might easily be really
wrong.
Hence, it would seem safer to revert to 3.17 state before 3.18, so we
can propose a proper fix for 3.19. At least from our myopic view, having
no functioning net on arndale is worse than having non-functioning
ethtool (which doesn't seem to have bothered people for years).
Riku
> > The PHY reset is the thing that breaks ethtool support, so any fix
> > that appeases all would have to take existing PHY state into account.
> >
> > I'm not an expert on the ASIX driver, nor the MII, but I think this is
>
> > the cause;
> > drivers/net/usb/asix_devices.c:
> > 361 asix_mdio_write(dev->net, dev->mii.phy_id, MII_BMCR,
> > BMCR_RESET);
> > 362 asix_mdio_write(dev->net, dev->mii.phy_id, MII_ADVERTISE,
> > 363 ADVERTISE_ALL | ADVERTISE_CSMA);
> > 364 mii_nway_restart(&dev->mii);
> >
> > I would think that the ADVERTISE_ALL is the cause here, as it will
> > reset the MII back to default, thus overriding ethtool settings.
> > Would an:
> > Int reg;
> > reg = asix_mdio_read(dev->net,dev->mii.phy_id,MII_ADVERTISE);
> >
> > prior to the offending lines, and then;
> >
> > 362 asix_mdio_write(dev->net, dev->mii.phy_id, MII_ADVERTISE,
> > 363 reg);
> >
> > solve the problem for you guys?
>
> If I revert the patch in question and add this in:
>
> --- a/drivers/net/usb/asix_devices.c
> +++ b/drivers/net/usb/asix_devices.c
> @@ -299,6 +299,7 @@ static int ax88772_reset(struct usbnet *dev) {
> struct asix_data *data = (struct asix_data *)&dev->data;
> int ret, embd_phy;
> + int reg;
> u16 rx_ctl;
>
> ret = asix_write_gpio(dev,
> @@ -359,8 +360,10 @@ static int ax88772_reset(struct usbnet *dev)
> msleep(150);
>
> asix_mdio_write(dev->net, dev->mii.phy_id, MII_BMCR,
> BMCR_RESET);
> - asix_mdio_write(dev->net, dev->mii.phy_id, MII_ADVERTISE,
> - ADVERTISE_ALL | ADVERTISE_CSMA);
> + reg = asix_mdio_read(dev->net, dev->mii.phy_id, MII_ADVERTISE);
> + if (!reg)
> + reg = ADVERTISE_ALL | ADVERTISE_CSMA;
> + asix_mdio_write(dev->net, dev->mii.phy_id, MII_ADVERTISE, reg);
> mii_nway_restart(&dev->mii);
>
> ret = asix_write_medium_mode(dev, AX88772_MEDIUM_DEFAULT);
>
> Then things work on Arndale for me. Does that work for you?
> Whether that is a sensible fix I don't know however.
>
> >
> > Mind, maybe the read function should take into account the reset value
>
> > of the MII, and set it to ADVERTISE_ALL | ADVERTISE_CSMA. I don't have
>
> > any documention here at the moment.
>
> Yeah I also have no documentation.
>
> Thanks,
> Charles
>
> >
> > Is anyone able to confirm my suspicions?
> >
> > Kind regards,
> >
> > Michel Stam
> > -----Original Message-----
> > From: Riku Voipio [mailto:riku.voipio@iki.fi]
> > Sent: Tuesday, November 04, 2014 10:44 AM
> > To: Stam, Michel [FINT]
> > Cc: Riku Voipio; davem@davemloft.net; linux-usb@vger.kernel.org;
> > netdev@vger.kernel.org; linux-kernel@vger.kernel.org;
> > linux-samsung-soc@vger.kernel.org; ckeepax@opensource.wolfsonmicro.com
> > Subject: Re: "asix: Don't reset PHY on if_up for ASIX 88772" breaks
> > net on arndale platform
> >
> > On Tue, Nov 04, 2014 at 09:19:26AM +0100, Stam, Michel [FINT] wrote:
> > > Interesting, as the commit itself is a revert from a kernel back to
> > > 2.6 somewhere. The problem I had is related to the PHY being reset
> > > on interface-up, can you confirm that you require this?
> >
> > I can't confirm what exactly is needed on arndale. I'm neither expert
> > in USB or ethernet. However, I can confirm that without the PHY reset,
>
> > networking doesn't work on arndale.
> >
> > I now see someone else has the same problem, adding Charles to CC.
> >
> > http://www.spinics.net/lists/linux-usb/msg116656.html
> >
> > > Reverting this
> > > breaks ethtool support in turn.
> >
> > Fixing a bug (ethtool support) must not cause breakage elsewhere (in
> > this case on arndale). This is now a regression of functionality from
> > 3.17.
> >
> > I think it would better to revert the change now and with less hurry
> > introduce a ethtool fix that doesn't break arndale.
> >
> > > Kind regards,
> > >
> > > Michel Stam
> > >
> > > -----Original Message-----
> > > From: Riku Voipio [mailto:riku.voipio@iki.fi]
> > > Sent: Tuesday, November 04, 2014 8:23 AM
> > > To: davem@davemloft.net; Stam, Michel [FINT]
> > > Cc: linux-usb@vger.kernel.org; netdev@vger.kernel.org;
> > > linux-kernel@vger.kernel.org; linux-samsung-soc@vger.kernel.org
> > > Subject: "asix: Don't reset PHY on if_up for ASIX 88772" breaks net
> > > on
> >
> > > arndale platform
> > >
> > > Hi,
> > >
> > > With 3.18-rc3, asix on arndale (samsung exynos 5250 based board),
> > > fails to work. Interface is initialized but network traffic seem not
>
> > > to pass through. With kernel IP config the result looks like:
> > >
> > > [ 3.323275] usb 3-3.2.4: new high-speed USB device number 4 using
> > > exynos-ehci
> > > [ 3.419151] usb 3-3.2.4: New USB device found, idVendor=0b95,
> > > idProduct=772a
> > > [ 3.424735] usb 3-3.2.4: New USB device strings: Mfr=1,
> Product=2,
> > > SerialNumber=3
> > > [ 3.432196] usb 3-3.2.4: Product: AX88772
> > > [ 3.436279] usb 3-3.2.4: Manufacturer: ASIX Elec. Corp.
> > > [ 3.441486] usb 3-3.2.4: SerialNumber: 000001
> > > [ 3.447530] asix 3-3.2.4:1.0 (unnamed net_device)
> (uninitialized):
> > > invalid hw address, using random
> > > [ 3.764352] asix 3-3.2.4:1.0 eth0: register 'asix' at
> > > usb-12110000.usb-3.2.4, ASIX AX88772 USB 2.0 Ethernet,
> > de:a2:66:bf:ca:4f
> > > [ 4.488773] asix 3-3.2.4:1.0 eth0: link down
> > > [ 5.690025] asix 3-3.2.4:1.0 eth0: link up, 100Mbps, full-duplex,
> > lpa
> > > 0xC5E1
> > > [ 5.712947] Sending DHCP requests ...... timed out!
> > > [ 83.165303] IP-Config: Retrying forever (NFS root)...
> > > [ 83.170397] asix 3-3.2.4:1.0 eth0: link up, 100Mbps, full-duplex,
> > lpa
> > > 0xC5E1
> > > [ 83.192944] Sending DHCP requests .....
> > >
> > > Similar results also with dhclient. Git bisect identified the
> > > breaking
> >
> > > commit as:
> > >
> > > commit 3cc81d85ee01e5a0b7ea2f4190e2ed1165f53c31
> > > Author: Michel Stam <m.stam@fugro.nl>
> > > Date: Thu Oct 2 10:22:02 2014 +0200
> > >
> > > asix: Don't reset PHY on if_up for ASIX 88772
> > >
> > > Taking 3.18-rc3 and that commit reverted, network works again:
> > >
> > > [ 3.303500] usb 3-3.2.4: new high-speed USB device number 4 using
> > > exynos-ehci
> > > [ 3.399375] usb 3-3.2.4: New USB device found, idVendor=0b95,
> > > idProduct=772a
> > > [ 3.404963] usb 3-3.2.4: New USB device strings: Mfr=1,
> Product=2,
> > > SerialNumber=3
> > > [ 3.412424] usb 3-3.2.4: Product: AX88772
> > > [ 3.416508] usb 3-3.2.4: Manufacturer: ASIX Elec. Corp.
> > > [ 3.421715] usb 3-3.2.4: SerialNumber: 000001
> > > [ 3.427755] asix 3-3.2.4:1.0 (unnamed net_device)
> (uninitialized):
> > > invalid hw address, using random
> > > [ 3.744837] asix 3-3.2.4:1.0 eth0: register 'asix' at
> > > usb-12110000.usb-3.2.4, ASIX AX88772 USB 2.0 Ethernet,
> > 12:59:f1:a8:43:90
> > > [ 7.098998] asix 3-3.2.4:1.0 eth0: link up, 100Mbps, full-duplex,
> > lpa
> > > 0xC5E1
> > > [ 7.118258] Sending DHCP requests ., OK
> > > [ 9.753259] IP-Config: Got DHCP answer from 192.168.1.1, my
> address
> > > is 192.168.1.111
> > >
> > > There might something wrong on the samsung platform code (I
> > > understand
> >
> > > the USB on arndale is "funny"), but this is still an regression from
>
> > > 3.17.
> > >
> > > Riku
^ permalink raw reply
* Re: [PATCH net 4/5] net/mlx4_en: Implement ndo_gso_check()
From: Or Gerlitz @ 2014-11-05 12:41 UTC (permalink / raw)
To: Joe Stringer
Cc: Linux Netdev List, sathya.perla, Jeff Kirsher, linux.nics,
Amir Vadai, shahed.shaikh, Dept-GELinuxNICDev, Tom Herbert,
Linux Kernel
In-Reply-To: <1415138202-1197-5-git-send-email-joestringer@nicira.com>
On Tue, Nov 4, 2014 at 11:56 PM, Joe Stringer <joestringer@nicira.com> wrote:
> ndo_gso_check() was recently introduced to allow NICs to report the
> offloading support that they have on a per-skb basis. Add an
> implementation for this driver which checks for something that looks
> like VXLAN.
>
> Implementation shamelessly stolen from Tom Herbert:
> http://thread.gmane.org/gmane.linux.network/332428/focus=333111
>
> Signed-off-by: Joe Stringer <joestringer@nicira.com>
> ---
> drivers/net/ethernet/mellanox/mlx4/en_netdev.c | 12 ++++++++++++
> 1 file changed, 12 insertions(+)
>
> diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
> index f3032fe..aca9908 100644
> --- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
> +++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
> @@ -2344,6 +2344,17 @@ static void mlx4_en_del_vxlan_port(struct net_device *dev,
> }
> #endif
>
> +static bool mlx4_en_gso_check(struct sk_buff *skb, struct net_device *dev)
> +{
> + if ((skb_shinfo(skb)->gso_type & SKB_GSO_UDP_TUNNEL) &&
> + (skb->inner_protocol_type != ENCAP_TYPE_ETHER ||
> + skb->inner_protocol != htons(ETH_P_TEB) ||
> + skb_inner_mac_header(skb) - skb_transport_header(skb) != 16))
> + return false;
Let's have this 16 constant to be more clear... e.g make it the sum of
sizeof struct udphdr and struct vxlanhdr - you would need to move the
latter from vxlan.c into a public header. All for the general patch I
suggested
Or.
> +
> + return true;
> +}
> +
> static const struct net_device_ops mlx4_netdev_ops = {
> .ndo_open = mlx4_en_open,
> .ndo_stop = mlx4_en_close,
> @@ -2374,6 +2385,7 @@ static const struct net_device_ops mlx4_netdev_ops = {
> .ndo_add_vxlan_port = mlx4_en_add_vxlan_port,
> .ndo_del_vxlan_port = mlx4_en_del_vxlan_port,
> #endif
> + .ndo_gso_check = mlx4_en_gso_check,
> };
>
> static const struct net_device_ops mlx4_netdev_ops_master = {
> --
> 1.7.10.4
>
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" 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: [linux-nics] [PATCH net 3/5] fm10k: Implement ndo_gso_check()
From: Or Gerlitz @ 2014-11-05 12:44 UTC (permalink / raw)
To: Jeff Kirsher
Cc: Joe Stringer, Linux Netdev List, linux.nics, shahed.shaikh,
sathya.perla, Amir Vadai, Linux Kernel, Dept-GELinuxNICDev,
Tom Herbert
In-Reply-To: <1415190872.2420.55.camel@jtkirshe-mobl>
On Wed, Nov 5, 2014 at 2:34 PM, Jeff Kirsher
<jeffrey.t.kirsher@intel.com> wrote:
> On Tue, 2014-11-04 at 13:56 -0800, Joe Stringer wrote:
>> ndo_gso_check() was recently introduced to allow NICs to report the
>> offloading support that they have on a per-skb basis. Add an
>> implementation for this driver which checks for something that looks
>> like VXLAN.
>>
>> Implementation shamelessly stolen from Tom Herbert:
>> http://thread.gmane.org/gmane.linux.network/332428/focus=333111
>>
>> Signed-off-by: Joe Stringer <joestringer@nicira.com>
>> ---
>> Should this driver report support for GSO on packets with tunnel
>> headers
>> up to 64B like the i40e driver does?
>> ---
>> drivers/net/ethernet/intel/fm10k/fm10k_netdev.c | 12 ++++++++++++
>> 1 file changed, 12 insertions(+)
>
> Thanks Joe, I will add your patch to my queue.
Hi Jeff, please see my comment on patch 0/5, we're essentially
replicating the same helper four different times (fm10k, mlx4, benet,
qlgc) - I don't see the point in doing so. I asked Joe to come up with
one generic helper and then to pick it up by the four drivers, makes
sense?
^ permalink raw reply
* Re: [linux-nics] [PATCH net 3/5] fm10k: Implement ndo_gso_check()
From: Jeff Kirsher @ 2014-11-05 12:47 UTC (permalink / raw)
To: Or Gerlitz
Cc: Joe Stringer, Linux Netdev List, linux.nics, shahed.shaikh,
sathya.perla, Amir Vadai, Linux Kernel, Dept-GELinuxNICDev,
Tom Herbert
In-Reply-To: <CAJ3xEMjaQ54yEUQGL-8VHoPm=4G5bhPaGBa55jypzfKviR4KyQ@mail.gmail.com>
[-- Attachment #1: Type: text/plain, Size: 1343 bytes --]
On Wed, 2014-11-05 at 14:44 +0200, Or Gerlitz wrote:
> On Wed, Nov 5, 2014 at 2:34 PM, Jeff Kirsher
> <jeffrey.t.kirsher@intel.com> wrote:
> > On Tue, 2014-11-04 at 13:56 -0800, Joe Stringer wrote:
> >> ndo_gso_check() was recently introduced to allow NICs to report the
> >> offloading support that they have on a per-skb basis. Add an
> >> implementation for this driver which checks for something that looks
> >> like VXLAN.
> >>
> >> Implementation shamelessly stolen from Tom Herbert:
> >> http://thread.gmane.org/gmane.linux.network/332428/focus=333111
> >>
> >> Signed-off-by: Joe Stringer <joestringer@nicira.com>
> >> ---
> >> Should this driver report support for GSO on packets with tunnel
> >> headers
> >> up to 64B like the i40e driver does?
> >> ---
> >> drivers/net/ethernet/intel/fm10k/fm10k_netdev.c | 12 ++++++++++++
> >> 1 file changed, 12 insertions(+)
> >
> > Thanks Joe, I will add your patch to my queue.
>
> Hi Jeff, please see my comment on patch 0/5, we're essentially
> replicating the same helper four different times (fm10k, mlx4, benet,
> qlgc) - I don't see the point in doing so. I asked Joe to come up with
> one generic helper and then to pick it up by the four drivers, makes
> sense?
Yeah, I just saw your reply Or. Ok, I will await an update to Joe's
series, thanks!
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 819 bytes --]
^ permalink raw reply
* Re: [PATCH V2 1/4] can: m_can: update to support CAN FD features
From: Dong Aisheng @ 2014-11-05 12:47 UTC (permalink / raw)
To: Oliver Hartkopp
Cc: linux-can, mkl, wg, varkabhadram, netdev, linux-arm-kernel
In-Reply-To: <545A21AD.5040608@hartkopp.net>
On Wed, Nov 05, 2014 at 02:10:05PM +0100, Oliver Hartkopp wrote:
> On 05.11.2014 12:26, Dong Aisheng wrote:
> >On Wed, Nov 05, 2014 at 11:12:24AM +0100, Oliver Hartkopp wrote:
> >>On 05.11.2014 08:58, Dong Aisheng wrote:
>
>
> >>Unfortunately No. Here it becomes complicated due to the fact that
> >>the revision 3.0.x does not support per-frame switching for FD/BRS
> >>...
> >
> >I'm not sure i got your point.
> > From m_can spec, it allows switch CAN mode by setting CMR bit.
> >
> >Bits 11:10 CMR[1:0]: CAN Mode Request
> >A change of the CAN operation mode is requested by writing to this bit field. After change to the
> >requested operation mode the bit field is reset to “00” and the status flags FDBS and FDO are set
> >accordingly. In case the requested CAN operation mode is not enabled, the value written to CMR is
> >retained until it is overwritten by the next mode change request. In case CME = “01”/”10”/”11” a
> >change to CAN operation according to ISO 11898-1 is always possible. Default is CAN operation
> >according to ISO11898-1.
> >00 unchanged
> >01 Request CAN FD operation
> >10 Request CAN FD operation with bit rate switching
> >11 Request CAN operation according ISO11898-1
> >
> >So what's the difference between this function and the per-frame switching
> >you mentioned?
> >
> >>
> >>When (priv->can.ctrlmode & CAN_CTRLMODE_FD) is true this *only*
> >>tells us, that the controller is _capable_ to send either CAN or CAN
> >>FD frames.
> >>
> >>It does not configure the controller into one of these specific settings!
> >>
> >>Additionally: AFAIK when writing to the CCCR you have to make sure
> >>that there's currently no ongoing transfer.
> >>
> >
> >I don't know about it before.
> >By searching m_can user manual v302 again, i still did not find this
> >limitation. Can you point me if you know where it is?
> >
> >BTW, since we only use one Tx Buffer for transmission currently, so we
> >should not meet that case that CAN mode is switched during transfer.
> >So the issue you concern may not happen.
>
> Yes. You are right. Having a FIFO with a size of 1 will help here :-)
>
> >
> >Additionally it looks to me like m_can does allow set CMR bit at runtime
> >since the mode change will take affect when controller becomes idle.
> >See below:
> >
> >"A mode change requested by writing to CCCR.CMR will be executed next
> >time the CAN protocol controller FSM reaches idle phase between CAN frames.
> >Upon this event CCCR.CMR is reset to “00” and the status flags CCCR.FDBS
> >and CCCR.FDO are set accordingly. In case the requested
> >CAN operation mode is not enabled, the value written to CCCR.CMR is
> >retained until it is overwritten by the next mode change request.
> >Default is CAN operation according to ISO11898-1."
>
> Ah. I assumed we have to take care to set these bits in the idle state.
>
> So when thinking about the one and only tx buffer your current
> approach should work indeed. Sorry for my confusion.
>
> >
> >>I would suggest the following approach to make the revision 3.0.x
> >>act like a correct CAN FD capable controller:
> >>
> >>- create a helper function to switch FD and BRS while taking care of
> >>ongoing transmissions
> >>
> >>- create a variable that knows the current tx_mode for FD and BRS
> >>
> >>When we need to send a CAN frame which doesn't fit the settings in
> >>the tx_mode we need to switch the CCCR and update the tx_mode
> >>variable.
> >>
> >>This at least reduces the needed CCCR operations.
> >>
> >
> >Yes, i can do like that.
> >But what i see by doing that is only reduces the needed CCCR operations?
> >Any other benefits i missed?
>
> No. I just thought about a function that also takes care of the idle
> phase to switch the bits. But now you made it clear that this is not
> needed - so you can stay on your current implementation: Setting the
> CCCR each time before sending the frame.
>
Okay
> With the 3.1.x or 3.2.x this code will become obsolete then as the
> EDL and BRS seeting will get extra bits in the Tx Buffer.
> But that's a future point.
>
Got it.
Will update it in the future when the new IP doc is available.
> >And the test for current code showed it seemed work well on the Mode
> >switch among std frame/fd frame/brs frame.
>
> Fine.
>
> Btw. I would suggest to integrate patch [4/4] into [3/4].
>
Yes, will do it.
Thanks
Regards
Dong Aisheng
> Best regards,
> Oliver
>
^ permalink raw reply
* Re: [PATCH V2 1/4] can: m_can: update to support CAN FD features
From: Dong Aisheng @ 2014-11-05 12:47 UTC (permalink / raw)
To: Oliver Hartkopp
Cc: linux-can, mkl, wg, varkabhadram, netdev, linux-arm-kernel
In-Reply-To: <545A22EF.3070509@hartkopp.net>
On Wed, Nov 05, 2014 at 02:15:27PM +0100, Oliver Hartkopp wrote:
> Typo
>
> On 05.11.2014 14:10, Oliver Hartkopp wrote:
>
> >Btw. I would suggest to integrate patch [4/4] into [3/4].
>
> into [1/4] of course
Understand! :-)
Regards
Dong Aisheng
^ permalink raw reply
* [net PATCH 1/1] drivers: net: cpsw: remove cpsw_ale_stop from cpsw_ale_destroy
From: Mugunthan V N @ 2014-11-05 13:03 UTC (permalink / raw)
To: netdev; +Cc: davem, Mugunthan V N
when cpsw is build as modulea and simple insert and removal of module
creates a deadlock, due to delete timer. the timer is created and destroyed
in cpsw_ale_start and cpsw_ale_stop which are from device open and close.
root@am437x-evm:~# modprobe -r ti_cpsw
[ 158.505333] INFO: trying to register non-static key.
[ 158.510623] the code is fine but needs lockdep annotation.
[ 158.516448] turning off the locking correctness validator.
[ 158.522282] CPU: 0 PID: 1339 Comm: modprobe Not tainted 3.14.23-00445-gd41c88f #44
[ 158.530359] [<c0015380>] (unwind_backtrace) from [<c0012088>] (show_stack+0x10/0x14)
[ 158.538603] [<c0012088>] (show_stack) from [<c054ad70>] (dump_stack+0x78/0x94)
[ 158.546295] [<c054ad70>] (dump_stack) from [<c0088008>] (__lock_acquire+0x176c/0x1b74)
[ 158.554711] [<c0088008>] (__lock_acquire) from [<c0088944>] (lock_acquire+0x9c/0x104)
[ 158.563043] [<c0088944>] (lock_acquire) from [<c004e520>] (del_timer_sync+0x44/0xd8)
[ 158.571289] [<c004e520>] (del_timer_sync) from [<bf2eac1c>] (cpsw_ale_destroy+0x10/0x3c [ti_cpsw])
[ 158.580821] [<bf2eac1c>] (cpsw_ale_destroy [ti_cpsw]) from [<bf2eb268>] (cpsw_remove+0x30/0xa0 [ti_cpsw])
[ 158.591000] [<bf2eb268>] (cpsw_remove [ti_cpsw]) from [<c035ef44>] (platform_drv_remove+0x18/0x1c)
[ 158.600527] [<c035ef44>] (platform_drv_remove) from [<c035d8bc>] (__device_release_driver+0x70/0xc8)
[ 158.610236] [<c035d8bc>] (__device_release_driver) from [<c035e0d4>] (driver_detach+0xb4/0xb8)
[ 158.619386] [<c035e0d4>] (driver_detach) from [<c035d6e4>] (bus_remove_driver+0x4c/0x90)
[ 158.627988] [<c035d6e4>] (bus_remove_driver) from [<c00af2a8>] (SyS_delete_module+0x10c/0x198)
[ 158.637144] [<c00af2a8>] (SyS_delete_module) from [<c000e580>] (ret_fast_syscall+0x0/0x48)
[ 179.524727] INFO: rcu_sched detected stalls on CPUs/tasks: {} (detected by 0, t=2102 jiffies, g=1487, c=1486, q=6)
[ 179.535741] INFO: Stall ended before state dump start
Signed-off-by: Mugunthan V N <mugunthanvnm@ti.com>
---
drivers/net/ethernet/ti/cpsw_ale.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/drivers/net/ethernet/ti/cpsw_ale.c b/drivers/net/ethernet/ti/cpsw_ale.c
index 3ae8387..097ebe7 100644
--- a/drivers/net/ethernet/ti/cpsw_ale.c
+++ b/drivers/net/ethernet/ti/cpsw_ale.c
@@ -785,7 +785,6 @@ int cpsw_ale_destroy(struct cpsw_ale *ale)
{
if (!ale)
return -EINVAL;
- cpsw_ale_stop(ale);
cpsw_ale_control_set(ale, 0, ALE_ENABLE, 0);
kfree(ale);
return 0;
--
2.1.2.484.g13da0fc
^ permalink raw reply related
* Re: [PATCH net-next 2/2] net/mlx4_en: Support for configurable RSS hash function
From: Eyal perry @ 2014-11-05 13:05 UTC (permalink / raw)
To: Or Gerlitz, Eyal Perry
Cc: Amir Vadai, David S. Miller, Ben Hutchings, netdev,
Yevgeny Petrilin
In-Reply-To: <545A17C2.9070609@mellanox.com>
On 11/5/2014 2:27 PM, Or Gerlitz wrote:
> On 11/5/2014 1:59 PM, Amir Vadai wrote:
>> From: Eyal Perry <eyalpe@mellanox.com>
>>
>> The ConnectX HW is capable of using one of the following hash functions:
>> Toeplitz and an XOR hash function.
>> This patch implements ethtool_ops {get,set}_rxfh_func callbacks for the
>> mlx4_en driver in order to query and configure the RSS hash function to
>> be used by the device.
>>
>> Signed-off-by: Eyal Perry <eyalpe@mellanox.com>
>> Signed-off-by: Amir Vadai <amirv@mellanox.com>
>> ---
>> drivers/net/ethernet/mellanox/mlx4/en_ethtool.c | 40
>> +++++++++++++++++++++++++
>> drivers/net/ethernet/mellanox/mlx4/en_netdev.c | 9 ++++++
>> drivers/net/ethernet/mellanox/mlx4/en_rx.c | 11 ++++---
>> drivers/net/ethernet/mellanox/mlx4/mlx4_en.h | 3 +-
>> 4 files changed, 58 insertions(+), 5 deletions(-)
>>
[...]
>> +
>> +static int mlx4_en_set_rxfh_func(struct net_device *dev, u32 hfunc)
>> +{
>> + struct mlx4_en_priv *priv = netdev_priv(dev);
>> + struct mlx4_en_dev *mdev = priv->mdev;
>> + u32 prev_rss_hash_fn = priv->rss_hash_fn;
>> + int err = 0;
>> +
>> + if (!(hfunc & priv->rss_hash_fn_caps))
>> + return -EINVAL;
>> +
>> + priv->rss_hash_fn = hfunc;
>
> Seems that you are blindly setting here priv->rss_hash_fn to the
> function (xor or top) requested
> by the user w.o prior checking if the firmware actually supports that
> (e.g test it against priv->rss_hash_fn_caps, right?
>
That exactly what I do 3 lines above, priv->rss_hash_fn_caps is derived
from firmware capabilities.
[...]
>> --- a/drivers/net/ethernet/mellanox/mlx4/en_rx.c
>> +++ b/drivers/net/ethernet/mellanox/mlx4/en_rx.c
>> @@ -1113,10 +1113,13 @@ int mlx4_en_config_rss_steer(struct
>> mlx4_en_priv *priv)
>> }
>> rss_context->flags = rss_mask;
>> - rss_context->hash_fn = MLX4_RSS_HASH_TOP;
>> - for (i = 0; i < 10; i++)
>> - rss_context->rss_key[i] = cpu_to_be32(rsskey[i]);
>> -
>> + if (priv->rss_hash_fn & MLX4_RSS_HASH_XOR) {
>> + rss_context->hash_fn = MLX4_RSS_HASH_XOR;
>> + } else {
>> + rss_context->hash_fn = MLX4_RSS_HASH_TOP;
>> + for (i = 0; i < 10; i++)
>> + rss_context->rss_key[i] = cpu_to_be32(rsskey[i]);
>> + }
>
> So this patch effectively changes the default from top to xor, right? is
> that intentional? if yes, spare few words on the change log.
>
No, in general the default shouldn't be affected by the patch (unless
there's a bug). The default value is set in mlx4_en_init_netdev() and it
will remain Toeplitz unless firmware is supports only XOR hash function.
[...]
^ permalink raw reply
* Re: [PATCH V2 1/4] can: m_can: update to support CAN FD features
From: Oliver Hartkopp @ 2014-11-05 13:10 UTC (permalink / raw)
To: Dong Aisheng; +Cc: linux-can, mkl, wg, varkabhadram, netdev, linux-arm-kernel
In-Reply-To: <20141105112639.GB4007@shlinux1.ap.freescale.net>
On 05.11.2014 12:26, Dong Aisheng wrote:
> On Wed, Nov 05, 2014 at 11:12:24AM +0100, Oliver Hartkopp wrote:
>> On 05.11.2014 08:58, Dong Aisheng wrote:
>> Unfortunately No. Here it becomes complicated due to the fact that
>> the revision 3.0.x does not support per-frame switching for FD/BRS
>> ...
>
> I'm not sure i got your point.
> From m_can spec, it allows switch CAN mode by setting CMR bit.
>
> Bits 11:10 CMR[1:0]: CAN Mode Request
> A change of the CAN operation mode is requested by writing to this bit field. After change to the
> requested operation mode the bit field is reset to “00” and the status flags FDBS and FDO are set
> accordingly. In case the requested CAN operation mode is not enabled, the value written to CMR is
> retained until it is overwritten by the next mode change request. In case CME = “01”/”10”/”11” a
> change to CAN operation according to ISO 11898-1 is always possible. Default is CAN operation
> according to ISO11898-1.
> 00 unchanged
> 01 Request CAN FD operation
> 10 Request CAN FD operation with bit rate switching
> 11 Request CAN operation according ISO11898-1
>
> So what's the difference between this function and the per-frame switching
> you mentioned?
>
>>
>> When (priv->can.ctrlmode & CAN_CTRLMODE_FD) is true this *only*
>> tells us, that the controller is _capable_ to send either CAN or CAN
>> FD frames.
>>
>> It does not configure the controller into one of these specific settings!
>>
>> Additionally: AFAIK when writing to the CCCR you have to make sure
>> that there's currently no ongoing transfer.
>>
>
> I don't know about it before.
> By searching m_can user manual v302 again, i still did not find this
> limitation. Can you point me if you know where it is?
>
> BTW, since we only use one Tx Buffer for transmission currently, so we
> should not meet that case that CAN mode is switched during transfer.
> So the issue you concern may not happen.
Yes. You are right. Having a FIFO with a size of 1 will help here :-)
>
> Additionally it looks to me like m_can does allow set CMR bit at runtime
> since the mode change will take affect when controller becomes idle.
> See below:
>
> "A mode change requested by writing to CCCR.CMR will be executed next
> time the CAN protocol controller FSM reaches idle phase between CAN frames.
> Upon this event CCCR.CMR is reset to “00” and the status flags CCCR.FDBS
> and CCCR.FDO are set accordingly. In case the requested
> CAN operation mode is not enabled, the value written to CCCR.CMR is
> retained until it is overwritten by the next mode change request.
> Default is CAN operation according to ISO11898-1."
Ah. I assumed we have to take care to set these bits in the idle state.
So when thinking about the one and only tx buffer your current approach should
work indeed. Sorry for my confusion.
>
>> I would suggest the following approach to make the revision 3.0.x
>> act like a correct CAN FD capable controller:
>>
>> - create a helper function to switch FD and BRS while taking care of
>> ongoing transmissions
>>
>> - create a variable that knows the current tx_mode for FD and BRS
>>
>> When we need to send a CAN frame which doesn't fit the settings in
>> the tx_mode we need to switch the CCCR and update the tx_mode
>> variable.
>>
>> This at least reduces the needed CCCR operations.
>>
>
> Yes, i can do like that.
> But what i see by doing that is only reduces the needed CCCR operations?
> Any other benefits i missed?
No. I just thought about a function that also takes care of the idle phase to
switch the bits. But now you made it clear that this is not needed - so you
can stay on your current implementation: Setting the CCCR each time before
sending the frame.
With the 3.1.x or 3.2.x this code will become obsolete then as the EDL and BRS
seeting will get extra bits in the Tx Buffer.
But that's a future point.
> And the test for current code showed it seemed work well on the Mode
> switch among std frame/fd frame/brs frame.
Fine.
Btw. I would suggest to integrate patch [4/4] into [3/4].
Best regards,
Oliver
^ permalink raw reply
* Re: [PATCH V2 1/4] can: m_can: update to support CAN FD features
From: Oliver Hartkopp @ 2014-11-05 13:15 UTC (permalink / raw)
To: Dong Aisheng; +Cc: linux-can, mkl, wg, varkabhadram, netdev, linux-arm-kernel
In-Reply-To: <545A21AD.5040608@hartkopp.net>
Typo
On 05.11.2014 14:10, Oliver Hartkopp wrote:
> Btw. I would suggest to integrate patch [4/4] into [3/4].
into [1/4] of course
^ permalink raw reply
* [PATCH V3 1/3] can: add can_is_canfd_skb() API
From: Dong Aisheng @ 2014-11-05 13:16 UTC (permalink / raw)
To: linux-can
Cc: mkl, wg, varkabhadram, netdev, socketcan, b29396,
linux-arm-kernel
The CAN device drivers can use it to check if the frame to send is on
CAN FD mode or normal CAN mode.
Acked-by: Oliver Hartkopp <socketcan@hartkopp.net>
Signed-off-by: Dong Aisheng <b29396@freescale.com>
---
ChangesLog:
* v1->v2: change to skb->len == CANFD_MTU;
---
include/linux/can/dev.h | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/include/linux/can/dev.h b/include/linux/can/dev.h
index 6992afc..4c3919c 100644
--- a/include/linux/can/dev.h
+++ b/include/linux/can/dev.h
@@ -99,6 +99,11 @@ inval_skb:
return 1;
}
+static inline int can_is_canfd_skb(struct sk_buff *skb)
+{
+ return skb->len == CANFD_MTU;
+}
+
/* get data length from can_dlc with sanitized can_dlc */
u8 can_dlc2len(u8 can_dlc);
--
1.9.1
^ permalink raw reply related
* Re: [PATCH V2 1/4] can: m_can: update to support CAN FD features
From: Marc Kleine-Budde @ 2014-11-05 13:19 UTC (permalink / raw)
To: Oliver Hartkopp, Dong Aisheng
Cc: linux-can, wg, varkabhadram, netdev, linux-arm-kernel
In-Reply-To: <545A21AD.5040608@hartkopp.net>
[-- Attachment #1: Type: text/plain, Size: 2614 bytes --]
On 11/05/2014 02:10 PM, Oliver Hartkopp wrote:
> On 05.11.2014 12:26, Dong Aisheng wrote:
>> On Wed, Nov 05, 2014 at 11:12:24AM +0100, Oliver Hartkopp wrote:
>>> On 05.11.2014 08:58, Dong Aisheng wrote:
>
>
>>> Unfortunately No. Here it becomes complicated due to the fact that
>>> the revision 3.0.x does not support per-frame switching for FD/BRS
>>> ...
>>
>> I'm not sure i got your point.
>> From m_can spec, it allows switch CAN mode by setting CMR bit.
>>
>> Bits 11:10 CMR[1:0]: CAN Mode Request
>> A change of the CAN operation mode is requested by writing to this bit
>> field. After change to the
>> requested operation mode the bit field is reset to “00” and the status
>> flags FDBS and FDO are set
>> accordingly. In case the requested CAN operation mode is not enabled,
>> the value written to CMR is
>> retained until it is overwritten by the next mode change request. In
>> case CME = “01”/”10”/”11” a
>> change to CAN operation according to ISO 11898-1 is always possible.
>> Default is CAN operation
>> according to ISO11898-1.
>> 00 unchanged
>> 01 Request CAN FD operation
>> 10 Request CAN FD operation with bit rate switching
>> 11 Request CAN operation according ISO11898-1
>>
>> So what's the difference between this function and the per-frame
>> switching
>> you mentioned?
>>
>>>
>>> When (priv->can.ctrlmode & CAN_CTRLMODE_FD) is true this *only*
>>> tells us, that the controller is _capable_ to send either CAN or CAN
>>> FD frames.
>>>
>>> It does not configure the controller into one of these specific
>>> settings!
>>>
>>> Additionally: AFAIK when writing to the CCCR you have to make sure
>>> that there's currently no ongoing transfer.
>>>
>>
>> I don't know about it before.
>> By searching m_can user manual v302 again, i still did not find this
>> limitation. Can you point me if you know where it is?
>>
>> BTW, since we only use one Tx Buffer for transmission currently, so we
>> should not meet that case that CAN mode is switched during transfer.
>> So the issue you concern may not happen.
>
> Yes. You are right. Having a FIFO with a size of 1 will help here :-)
Errrr....sorry...no.
Taking an easy route here but making it x times harder to extend the
driver to make use of the FIFO is not an option.
Marc
--
Pengutronix e.K. | Marc Kleine-Budde |
Industrial Linux Solutions | Phone: +49-231-2826-924 |
Vertretung West/Dortmund | Fax: +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686 | http://www.pengutronix.de |
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]
^ permalink raw reply
* Re: [PATCH v3 6/8] net: can: c_can: Disable pins when CAN interface is down
From: Marc Kleine-Budde @ 2014-11-05 13:24 UTC (permalink / raw)
To: Roger Quadros, wg
Cc: wsa, tony, tglx, mugunthanvnm, george.cherian, balbi, nsekhar, nm,
sergei.shtylyov, linux-omap, linux-can, netdev
In-Reply-To: <1415096461-25576-7-git-send-email-rogerq@ti.com>
[-- Attachment #1: Type: text/plain, Size: 1917 bytes --]
On 11/04/2014 11:20 AM, Roger Quadros wrote:
> DRA7 CAN IP suffers from a problem which causes it to be prevented
> from fully turning OFF (i.e. stuck in transition) if the module was
> disabled while there was traffic on the CAN_RX line.
>
> To work around this issue we select the SLEEP pin state by default
> on probe and use the DEFAULT pin state on CAN up and back to the
> SLEEP pin state on CAN down.
>
> Signed-off-by: Roger Quadros <rogerq@ti.com>
> ---
> drivers/net/can/c_can/c_can.c | 20 ++++++++++++++++++++
> drivers/net/can/c_can/c_can.h | 1 +
> drivers/net/can/c_can/c_can_platform.c | 20 ++++++++++++++++++++
> 3 files changed, 41 insertions(+)
>
> diff --git a/drivers/net/can/c_can/c_can.c b/drivers/net/can/c_can/c_can.c
> index 8e78bb4..4dfc3ce 100644
> --- a/drivers/net/can/c_can/c_can.c
> +++ b/drivers/net/can/c_can/c_can.c
> @@ -35,6 +35,7 @@
> #include <linux/list.h>
> #include <linux/io.h>
> #include <linux/pm_runtime.h>
> +#include <linux/pinctrl/consumer.h>
>
> #include <linux/can.h>
> #include <linux/can/dev.h>
> @@ -603,6 +604,15 @@ static int c_can_start(struct net_device *dev)
>
> priv->can.state = CAN_STATE_ERROR_ACTIVE;
>
> + /* activate pins */
> + if (!IS_ERR(priv->pinctrl)) {
> + struct pinctrl_state *s;
> +
> + s = pinctrl_lookup_state(priv->pinctrl, PINCTRL_STATE_DEFAULT);
> + if (!IS_ERR(s))
> + pinctrl_select_state(priv->pinctrl, s);
> + }
Can you factor this into a common function? Which is used like this:
c_can_pinctrl_select_state(priv, PINCTRL_STATE_DEFAULT)
Otherwise looks god.
Marc
--
Pengutronix e.K. | Marc Kleine-Budde |
Industrial Linux Solutions | Phone: +49-231-2826-924 |
Vertretung West/Dortmund | Fax: +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686 | http://www.pengutronix.de |
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]
^ permalink raw reply
* Re: [PATCH net-next 2/2] net/mlx4_en: Support for configurable RSS hash function
From: Or Gerlitz @ 2014-11-05 13:30 UTC (permalink / raw)
To: Eyal perry, Eyal Perry
Cc: Amir Vadai, David S. Miller, Ben Hutchings, netdev,
Yevgeny Petrilin
In-Reply-To: <545A20B0.4080807@dev.mellanox.co.il>
On 11/5/2014 3:05 PM, Eyal perry wrote:
> On 11/5/2014 2:27 PM, Or Gerlitz wrote:
>>> +
>>> +static int mlx4_en_set_rxfh_func(struct net_device *dev, u32 hfunc)
>>> +{
>>> + struct mlx4_en_priv *priv = netdev_priv(dev);
>>> + struct mlx4_en_dev *mdev = priv->mdev;
>>> + u32 prev_rss_hash_fn = priv->rss_hash_fn;
>>> + int err = 0;
>>> +
>>> + if (!(hfunc & priv->rss_hash_fn_caps))
>>> + return -EINVAL;
>>> +
>>> + priv->rss_hash_fn = hfunc;
>> Seems that you are blindly setting here priv->rss_hash_fn to the function (xor or top) requested by the user w.o prior checking if the firmware actually supports that
>> (e.g test it against priv->rss_hash_fn_caps, right?
>>
> That exactly what I do 3 lines above, priv->rss_hash_fn_caps is derived from firmware capabilities.
got it, thanks.
>
> [...]
>
>>> --- a/drivers/net/ethernet/mellanox/mlx4/en_rx.c
>>> +++ b/drivers/net/ethernet/mellanox/mlx4/en_rx.c
>>> @@ -1113,10 +1113,13 @@ int mlx4_en_config_rss_steer(struct
>>> mlx4_en_priv *priv)
>>> }
>>> rss_context->flags = rss_mask;
>>> - rss_context->hash_fn = MLX4_RSS_HASH_TOP;
>>> - for (i = 0; i < 10; i++)
>>> - rss_context->rss_key[i] = cpu_to_be32(rsskey[i]);
>>> -
>>> + if (priv->rss_hash_fn & MLX4_RSS_HASH_XOR) {
>>> + rss_context->hash_fn = MLX4_RSS_HASH_XOR;
>>> + } else {
>>> + rss_context->hash_fn = MLX4_RSS_HASH_TOP;
>>> + for (i = 0; i < 10; i++)
>>> + rss_context->rss_key[i] = cpu_to_be32(rsskey[i]);
>>> + }
>> So this patch effectively changes the default from top to xor, right? is
>> that intentional? if yes, spare few words on the change log.
>>
> No, in general the default shouldn't be affected by the patch (unless
> there's a bug). The default value is set in mlx4_en_init_netdev() and it
> will remain Toeplitz unless firmware is supports only XOR hash function.
>
Oh, I see why I was confused and what I think need to be fixed. You are
using both MLX4_RSS_HASH_TOP/XOR and RSS_HASH_TOP/XOR, any reason for that?
Also, priv->rss_hash_fn should equal one value, right? so this code "if
(priv->rss_hash_fn & something)" is confusing, should be "if
(priv->rss_hash_fn == something)"
Or.
^ permalink raw reply
* Re: [PATCH v3 7/8] net: can: c_can: Add support for TI DRA7 DCAN
From: Marc Kleine-Budde @ 2014-11-05 13:30 UTC (permalink / raw)
To: Roger Quadros, wg
Cc: wsa, tony, tglx, mugunthanvnm, george.cherian, balbi, nsekhar, nm,
sergei.shtylyov, linux-omap, linux-can, netdev
In-Reply-To: <1415096461-25576-8-git-send-email-rogerq@ti.com>
[-- Attachment #1: Type: text/plain, Size: 3090 bytes --]
On 11/04/2014 11:21 AM, Roger Quadros wrote:
> DRA7 SoC has 2 CAN IPs. Provide compatible IDs and RAMINIT
> register data for both.
My understanding of the discussion with Wolfram was:
- We should put the number of the Interface into to DT as a regmap
parameter.
- We put the method how to find the correct bits into the DT, via the
compatible.
So for both CAN instances on the DRA7 we have a single compatible
"ti,dra7-d_can" and in the driver a mechanism that translates the number
of the instance into the needed bit offsets, e.g. via two arrays.
Same comments for patch 8/8.
Marc
>
> Signed-off-by: Roger Quadros <rogerq@ti.com>
> ---
> Documentation/devicetree/bindings/net/can/c_can.txt | 1 +
> drivers/net/can/c_can/c_can_platform.c | 16 ++++++++++++++++
> 2 files changed, 17 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/net/can/c_can.txt b/Documentation/devicetree/bindings/net/can/c_can.txt
> index 917ac0e..746cc07 100644
> --- a/Documentation/devicetree/bindings/net/can/c_can.txt
> +++ b/Documentation/devicetree/bindings/net/can/c_can.txt
> @@ -4,6 +4,7 @@ Bosch C_CAN/D_CAN controller Device Tree Bindings
> Required properties:
> - compatible : Should be "bosch,c_can" for C_CAN controllers and
> "bosch,d_can" for D_CAN controllers.
> + Can be "ti,dra7-d_can1" or "ti,dra7-d_can2".
> - reg : physical base address and size of the C_CAN/D_CAN
> registers map
> - interrupts : property with a value describing the interrupt
> diff --git a/drivers/net/can/c_can/c_can_platform.c b/drivers/net/can/c_can/c_can_platform.c
> index d058820..dc618ce 100644
> --- a/drivers/net/can/c_can/c_can_platform.c
> +++ b/drivers/net/can/c_can/c_can_platform.c
> @@ -195,6 +195,20 @@ static struct c_can_driver_data d_can_drvdata = {
> .id = BOSCH_D_CAN,
> };
>
> +static struct c_can_driver_data dra7_dcan1_drvdata = {
> + .id = BOSCH_D_CAN,
> + .raminit_start_bit = 3,
> + .raminit_done_bit = 1,
> + .raminit_pulse = true,
> +};
> +
> +static struct c_can_driver_data dra7_dcan2_drvdata = {
> + .id = BOSCH_D_CAN,
> + .raminit_start_bit = 5,
> + .raminit_done_bit = 2,
> + .raminit_pulse = true,
> +};
> +
> static struct platform_device_id c_can_id_table[] = {
> {
> .name = KBUILD_MODNAME,
> @@ -215,6 +229,8 @@ MODULE_DEVICE_TABLE(platform, c_can_id_table);
> static const struct of_device_id c_can_of_table[] = {
> { .compatible = "bosch,c_can", .data = &c_can_drvdata },
> { .compatible = "bosch,d_can", .data = &d_can_drvdata },
> + { .compatible = "ti,dra7-d_can1", .data = &dra7_dcan1_drvdata },
> + { .compatible = "ti,dra7-d_can2", .data = &dra7_dcan2_drvdata },
> { /* sentinel */ },
> };
> MODULE_DEVICE_TABLE(of, c_can_of_table);
>
--
Pengutronix e.K. | Marc Kleine-Budde |
Industrial Linux Solutions | Phone: +49-231-2826-924 |
Vertretung West/Dortmund | Fax: +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686 | http://www.pengutronix.de |
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]
^ permalink raw reply
* Re: [PATCH v3 6/8] net: can: c_can: Disable pins when CAN interface is down
From: Roger Quadros @ 2014-11-05 13:33 UTC (permalink / raw)
To: Marc Kleine-Budde, wg
Cc: wsa, tony, tglx, mugunthanvnm, george.cherian, balbi, nsekhar, nm,
sergei.shtylyov, linux-omap, linux-can, netdev
In-Reply-To: <545A2511.2090205@pengutronix.de>
On 11/05/2014 03:24 PM, Marc Kleine-Budde wrote:
> On 11/04/2014 11:20 AM, Roger Quadros wrote:
>> DRA7 CAN IP suffers from a problem which causes it to be prevented
>> from fully turning OFF (i.e. stuck in transition) if the module was
>> disabled while there was traffic on the CAN_RX line.
>>
>> To work around this issue we select the SLEEP pin state by default
>> on probe and use the DEFAULT pin state on CAN up and back to the
>> SLEEP pin state on CAN down.
>>
>> Signed-off-by: Roger Quadros <rogerq@ti.com>
>> ---
>> drivers/net/can/c_can/c_can.c | 20 ++++++++++++++++++++
>> drivers/net/can/c_can/c_can.h | 1 +
>> drivers/net/can/c_can/c_can_platform.c | 20 ++++++++++++++++++++
>> 3 files changed, 41 insertions(+)
>>
>> diff --git a/drivers/net/can/c_can/c_can.c b/drivers/net/can/c_can/c_can.c
>> index 8e78bb4..4dfc3ce 100644
>> --- a/drivers/net/can/c_can/c_can.c
>> +++ b/drivers/net/can/c_can/c_can.c
>> @@ -35,6 +35,7 @@
>> #include <linux/list.h>
>> #include <linux/io.h>
>> #include <linux/pm_runtime.h>
>> +#include <linux/pinctrl/consumer.h>
>>
>> #include <linux/can.h>
>> #include <linux/can/dev.h>
>> @@ -603,6 +604,15 @@ static int c_can_start(struct net_device *dev)
>>
>> priv->can.state = CAN_STATE_ERROR_ACTIVE;
>>
>> + /* activate pins */
>> + if (!IS_ERR(priv->pinctrl)) {
>> + struct pinctrl_state *s;
>> +
>> + s = pinctrl_lookup_state(priv->pinctrl, PINCTRL_STATE_DEFAULT);
>> + if (!IS_ERR(s))
>> + pinctrl_select_state(priv->pinctrl, s);
>> + }
>
> Can you factor this into a common function? Which is used like this:
>
> c_can_pinctrl_select_state(priv, PINCTRL_STATE_DEFAULT)
>
> Otherwise looks god.
OK.
cheers,
-roger
^ permalink raw reply
* Re: [PATCH v3 7/8] net: can: c_can: Add support for TI DRA7 DCAN
From: Roger Quadros @ 2014-11-05 13:36 UTC (permalink / raw)
To: Marc Kleine-Budde, wg
Cc: wsa, tony, tglx, mugunthanvnm, george.cherian, balbi, nsekhar, nm,
sergei.shtylyov, linux-omap, linux-can, netdev
In-Reply-To: <545A2679.2000905@pengutronix.de>
On 11/05/2014 03:30 PM, Marc Kleine-Budde wrote:
> On 11/04/2014 11:21 AM, Roger Quadros wrote:
>> DRA7 SoC has 2 CAN IPs. Provide compatible IDs and RAMINIT
>> register data for both.
>
> My understanding of the discussion with Wolfram was:
> - We should put the number of the Interface into to DT as a regmap
> parameter.
> - We put the method how to find the correct bits into the DT, via the
> compatible.
>
> So for both CAN instances on the DRA7 we have a single compatible
> "ti,dra7-d_can" and in the driver a mechanism that translates the number
> of the instance into the needed bit offsets, e.g. via two arrays.
>
OK. I'll revise this series.
The new syscon-raminit property will be like
syscon-raminit = <syscon_phandle raminit-reg-offset dcan-interface-number>;
cheers,
-roger
> Same comments for patch 8/8.
>
> Marc
>
>>
>> Signed-off-by: Roger Quadros <rogerq@ti.com>
>> ---
>> Documentation/devicetree/bindings/net/can/c_can.txt | 1 +
>> drivers/net/can/c_can/c_can_platform.c | 16 ++++++++++++++++
>> 2 files changed, 17 insertions(+)
>>
>> diff --git a/Documentation/devicetree/bindings/net/can/c_can.txt b/Documentation/devicetree/bindings/net/can/c_can.txt
>> index 917ac0e..746cc07 100644
>> --- a/Documentation/devicetree/bindings/net/can/c_can.txt
>> +++ b/Documentation/devicetree/bindings/net/can/c_can.txt
>> @@ -4,6 +4,7 @@ Bosch C_CAN/D_CAN controller Device Tree Bindings
>> Required properties:
>> - compatible : Should be "bosch,c_can" for C_CAN controllers and
>> "bosch,d_can" for D_CAN controllers.
>> + Can be "ti,dra7-d_can1" or "ti,dra7-d_can2".
>> - reg : physical base address and size of the C_CAN/D_CAN
>> registers map
>> - interrupts : property with a value describing the interrupt
>> diff --git a/drivers/net/can/c_can/c_can_platform.c b/drivers/net/can/c_can/c_can_platform.c
>> index d058820..dc618ce 100644
>> --- a/drivers/net/can/c_can/c_can_platform.c
>> +++ b/drivers/net/can/c_can/c_can_platform.c
>> @@ -195,6 +195,20 @@ static struct c_can_driver_data d_can_drvdata = {
>> .id = BOSCH_D_CAN,
>> };
>>
>> +static struct c_can_driver_data dra7_dcan1_drvdata = {
>> + .id = BOSCH_D_CAN,
>> + .raminit_start_bit = 3,
>> + .raminit_done_bit = 1,
>> + .raminit_pulse = true,
>> +};
>> +
>> +static struct c_can_driver_data dra7_dcan2_drvdata = {
>> + .id = BOSCH_D_CAN,
>> + .raminit_start_bit = 5,
>> + .raminit_done_bit = 2,
>> + .raminit_pulse = true,
>> +};
>> +
>> static struct platform_device_id c_can_id_table[] = {
>> {
>> .name = KBUILD_MODNAME,
>> @@ -215,6 +229,8 @@ MODULE_DEVICE_TABLE(platform, c_can_id_table);
>> static const struct of_device_id c_can_of_table[] = {
>> { .compatible = "bosch,c_can", .data = &c_can_drvdata },
>> { .compatible = "bosch,d_can", .data = &d_can_drvdata },
>> + { .compatible = "ti,dra7-d_can1", .data = &dra7_dcan1_drvdata },
>> + { .compatible = "ti,dra7-d_can2", .data = &dra7_dcan2_drvdata },
>> { /* sentinel */ },
>> };
>> MODULE_DEVICE_TABLE(of, c_can_of_table);
>>
>
>
^ 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