sfc: commonise MCDI MAC stats handling
Most of it was already declared in mcdi_port_common.h, so just move the implementations to mcdi_port_common.c. Signed-off-by: Edward Cree <ecree@solarflare.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
83d00531cb
commit
272e53aa5c
@ -692,80 +692,6 @@ bool efx_mcdi_mac_check_fault(struct efx_nic *efx)
|
||||
return MCDI_DWORD(outbuf, GET_LINK_OUT_MAC_FAULT) != 0;
|
||||
}
|
||||
|
||||
enum efx_stats_action {
|
||||
EFX_STATS_ENABLE,
|
||||
EFX_STATS_DISABLE,
|
||||
EFX_STATS_PULL,
|
||||
};
|
||||
|
||||
static int efx_mcdi_mac_stats(struct efx_nic *efx,
|
||||
enum efx_stats_action action, int clear)
|
||||
{
|
||||
MCDI_DECLARE_BUF(inbuf, MC_CMD_MAC_STATS_IN_LEN);
|
||||
int rc;
|
||||
int change = action == EFX_STATS_PULL ? 0 : 1;
|
||||
int enable = action == EFX_STATS_ENABLE ? 1 : 0;
|
||||
int period = action == EFX_STATS_ENABLE ? 1000 : 0;
|
||||
dma_addr_t dma_addr = efx->stats_buffer.dma_addr;
|
||||
u32 dma_len = action != EFX_STATS_DISABLE ?
|
||||
efx->num_mac_stats * sizeof(u64) : 0;
|
||||
|
||||
BUILD_BUG_ON(MC_CMD_MAC_STATS_OUT_DMA_LEN != 0);
|
||||
|
||||
MCDI_SET_QWORD(inbuf, MAC_STATS_IN_DMA_ADDR, dma_addr);
|
||||
MCDI_POPULATE_DWORD_7(inbuf, MAC_STATS_IN_CMD,
|
||||
MAC_STATS_IN_DMA, !!enable,
|
||||
MAC_STATS_IN_CLEAR, clear,
|
||||
MAC_STATS_IN_PERIODIC_CHANGE, change,
|
||||
MAC_STATS_IN_PERIODIC_ENABLE, enable,
|
||||
MAC_STATS_IN_PERIODIC_CLEAR, 0,
|
||||
MAC_STATS_IN_PERIODIC_NOEVENT, 1,
|
||||
MAC_STATS_IN_PERIOD_MS, period);
|
||||
MCDI_SET_DWORD(inbuf, MAC_STATS_IN_DMA_LEN, dma_len);
|
||||
|
||||
if (efx_nic_rev(efx) >= EFX_REV_HUNT_A0)
|
||||
MCDI_SET_DWORD(inbuf, MAC_STATS_IN_PORT_ID, efx->vport_id);
|
||||
|
||||
rc = efx_mcdi_rpc_quiet(efx, MC_CMD_MAC_STATS, inbuf, sizeof(inbuf),
|
||||
NULL, 0, NULL);
|
||||
/* Expect ENOENT if DMA queues have not been set up */
|
||||
if (rc && (rc != -ENOENT || atomic_read(&efx->active_queues)))
|
||||
efx_mcdi_display_error(efx, MC_CMD_MAC_STATS, sizeof(inbuf),
|
||||
NULL, 0, rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
void efx_mcdi_mac_start_stats(struct efx_nic *efx)
|
||||
{
|
||||
__le64 *dma_stats = efx->stats_buffer.addr;
|
||||
|
||||
dma_stats[efx->num_mac_stats - 1] = EFX_MC_STATS_GENERATION_INVALID;
|
||||
|
||||
efx_mcdi_mac_stats(efx, EFX_STATS_ENABLE, 0);
|
||||
}
|
||||
|
||||
void efx_mcdi_mac_stop_stats(struct efx_nic *efx)
|
||||
{
|
||||
efx_mcdi_mac_stats(efx, EFX_STATS_DISABLE, 0);
|
||||
}
|
||||
|
||||
#define EFX_MAC_STATS_WAIT_US 100
|
||||
#define EFX_MAC_STATS_WAIT_ATTEMPTS 10
|
||||
|
||||
void efx_mcdi_mac_pull_stats(struct efx_nic *efx)
|
||||
{
|
||||
__le64 *dma_stats = efx->stats_buffer.addr;
|
||||
int attempts = EFX_MAC_STATS_WAIT_ATTEMPTS;
|
||||
|
||||
dma_stats[efx->num_mac_stats - 1] = EFX_MC_STATS_GENERATION_INVALID;
|
||||
efx_mcdi_mac_stats(efx, EFX_STATS_PULL, 0);
|
||||
|
||||
while (dma_stats[efx->num_mac_stats - 1] ==
|
||||
EFX_MC_STATS_GENERATION_INVALID &&
|
||||
attempts-- != 0)
|
||||
udelay(EFX_MAC_STATS_WAIT_US);
|
||||
}
|
||||
|
||||
int efx_mcdi_port_probe(struct efx_nic *efx)
|
||||
{
|
||||
int rc;
|
||||
@ -783,24 +709,11 @@ int efx_mcdi_port_probe(struct efx_nic *efx)
|
||||
if (rc != 0)
|
||||
return rc;
|
||||
|
||||
/* Allocate buffer for stats */
|
||||
rc = efx_nic_alloc_buffer(efx, &efx->stats_buffer,
|
||||
efx->num_mac_stats * sizeof(u64), GFP_KERNEL);
|
||||
if (rc)
|
||||
return rc;
|
||||
netif_dbg(efx, probe, efx->net_dev,
|
||||
"stats buffer at %llx (virt %p phys %llx)\n",
|
||||
(u64)efx->stats_buffer.dma_addr,
|
||||
efx->stats_buffer.addr,
|
||||
(u64)virt_to_phys(efx->stats_buffer.addr));
|
||||
|
||||
efx_mcdi_mac_stats(efx, EFX_STATS_DISABLE, 1);
|
||||
|
||||
return 0;
|
||||
return efx_mcdi_mac_init_stats(efx);
|
||||
}
|
||||
|
||||
void efx_mcdi_port_remove(struct efx_nic *efx)
|
||||
{
|
||||
efx->phy_op->remove(efx);
|
||||
efx_nic_free_buffer(efx, &efx->stats_buffer);
|
||||
efx_mcdi_mac_fini_stats(efx);
|
||||
}
|
||||
|
@ -10,6 +10,7 @@
|
||||
|
||||
#include "mcdi_port_common.h"
|
||||
#include "efx_common.h"
|
||||
#include "nic.h"
|
||||
|
||||
int efx_mcdi_get_phy_cfg(struct efx_nic *efx, struct efx_mcdi_phy_data *cfg)
|
||||
{
|
||||
@ -520,6 +521,110 @@ int efx_mcdi_set_mac(struct efx_nic *efx)
|
||||
NULL, 0, NULL);
|
||||
}
|
||||
|
||||
enum efx_stats_action {
|
||||
EFX_STATS_ENABLE,
|
||||
EFX_STATS_DISABLE,
|
||||
EFX_STATS_PULL,
|
||||
};
|
||||
|
||||
static int efx_mcdi_mac_stats(struct efx_nic *efx,
|
||||
enum efx_stats_action action, int clear)
|
||||
{
|
||||
MCDI_DECLARE_BUF(inbuf, MC_CMD_MAC_STATS_IN_LEN);
|
||||
int rc;
|
||||
int change = action == EFX_STATS_PULL ? 0 : 1;
|
||||
int enable = action == EFX_STATS_ENABLE ? 1 : 0;
|
||||
int period = action == EFX_STATS_ENABLE ? 1000 : 0;
|
||||
dma_addr_t dma_addr = efx->stats_buffer.dma_addr;
|
||||
u32 dma_len = action != EFX_STATS_DISABLE ?
|
||||
efx->num_mac_stats * sizeof(u64) : 0;
|
||||
|
||||
BUILD_BUG_ON(MC_CMD_MAC_STATS_OUT_DMA_LEN != 0);
|
||||
|
||||
MCDI_SET_QWORD(inbuf, MAC_STATS_IN_DMA_ADDR, dma_addr);
|
||||
MCDI_POPULATE_DWORD_7(inbuf, MAC_STATS_IN_CMD,
|
||||
MAC_STATS_IN_DMA, !!enable,
|
||||
MAC_STATS_IN_CLEAR, clear,
|
||||
MAC_STATS_IN_PERIODIC_CHANGE, change,
|
||||
MAC_STATS_IN_PERIODIC_ENABLE, enable,
|
||||
MAC_STATS_IN_PERIODIC_CLEAR, 0,
|
||||
MAC_STATS_IN_PERIODIC_NOEVENT, 1,
|
||||
MAC_STATS_IN_PERIOD_MS, period);
|
||||
MCDI_SET_DWORD(inbuf, MAC_STATS_IN_DMA_LEN, dma_len);
|
||||
|
||||
if (efx_nic_rev(efx) >= EFX_REV_HUNT_A0)
|
||||
MCDI_SET_DWORD(inbuf, MAC_STATS_IN_PORT_ID, efx->vport_id);
|
||||
|
||||
rc = efx_mcdi_rpc_quiet(efx, MC_CMD_MAC_STATS, inbuf, sizeof(inbuf),
|
||||
NULL, 0, NULL);
|
||||
/* Expect ENOENT if DMA queues have not been set up */
|
||||
if (rc && (rc != -ENOENT || atomic_read(&efx->active_queues)))
|
||||
efx_mcdi_display_error(efx, MC_CMD_MAC_STATS, sizeof(inbuf),
|
||||
NULL, 0, rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
void efx_mcdi_mac_start_stats(struct efx_nic *efx)
|
||||
{
|
||||
__le64 *dma_stats = efx->stats_buffer.addr;
|
||||
|
||||
dma_stats[efx->num_mac_stats - 1] = EFX_MC_STATS_GENERATION_INVALID;
|
||||
|
||||
efx_mcdi_mac_stats(efx, EFX_STATS_ENABLE, 0);
|
||||
}
|
||||
|
||||
void efx_mcdi_mac_stop_stats(struct efx_nic *efx)
|
||||
{
|
||||
efx_mcdi_mac_stats(efx, EFX_STATS_DISABLE, 0);
|
||||
}
|
||||
|
||||
#define EFX_MAC_STATS_WAIT_US 100
|
||||
#define EFX_MAC_STATS_WAIT_ATTEMPTS 10
|
||||
|
||||
void efx_mcdi_mac_pull_stats(struct efx_nic *efx)
|
||||
{
|
||||
__le64 *dma_stats = efx->stats_buffer.addr;
|
||||
int attempts = EFX_MAC_STATS_WAIT_ATTEMPTS;
|
||||
|
||||
dma_stats[efx->num_mac_stats - 1] = EFX_MC_STATS_GENERATION_INVALID;
|
||||
efx_mcdi_mac_stats(efx, EFX_STATS_PULL, 0);
|
||||
|
||||
while (dma_stats[efx->num_mac_stats - 1] ==
|
||||
EFX_MC_STATS_GENERATION_INVALID &&
|
||||
attempts-- != 0)
|
||||
udelay(EFX_MAC_STATS_WAIT_US);
|
||||
}
|
||||
|
||||
int efx_mcdi_mac_init_stats(struct efx_nic *efx)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if (!efx->num_mac_stats)
|
||||
return 0;
|
||||
|
||||
/* Allocate buffer for stats */
|
||||
rc = efx_nic_alloc_buffer(efx, &efx->stats_buffer,
|
||||
efx->num_mac_stats * sizeof(u64), GFP_KERNEL);
|
||||
if (rc) {
|
||||
netif_warn(efx, probe, efx->net_dev,
|
||||
"failed to allocate DMA buffer: %d\n", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
netif_dbg(efx, probe, efx->net_dev,
|
||||
"stats buffer at %llx (virt %p phys %llx)\n",
|
||||
(u64) efx->stats_buffer.dma_addr,
|
||||
efx->stats_buffer.addr,
|
||||
(u64) virt_to_phys(efx->stats_buffer.addr));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void efx_mcdi_mac_fini_stats(struct efx_nic *efx)
|
||||
{
|
||||
efx_nic_free_buffer(efx, &efx->stats_buffer);
|
||||
}
|
||||
|
||||
/* Get physical port number (EF10 only; on Siena it is same as PF number) */
|
||||
int efx_mcdi_port_get_number(struct efx_nic *efx)
|
||||
{
|
||||
|
@ -51,6 +51,8 @@ int efx_mcdi_phy_get_fecparam(struct efx_nic *efx,
|
||||
struct ethtool_fecparam *fec);
|
||||
int efx_mcdi_phy_test_alive(struct efx_nic *efx);
|
||||
int efx_mcdi_set_mac(struct efx_nic *efx);
|
||||
int efx_mcdi_mac_init_stats(struct efx_nic *efx);
|
||||
void efx_mcdi_mac_fini_stats(struct efx_nic *efx);
|
||||
int efx_mcdi_port_get_number(struct efx_nic *efx);
|
||||
void efx_mcdi_process_link_change(struct efx_nic *efx, efx_qword_t *ev);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user