mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-09-04 20:19:47 +08:00
Merge branch 'for-davem' of git://git.kernel.org/pub/scm/linux/kernel/git/bwh/sfc-next
Ben Hutchings says: ==================== 1. Extension to PPS/PTP to allow for PHC devices where pulses are subject to a variable but measurable delay. 2. PPS/PTP/PHC support for Solarflare boards with a timestamping peripheral. 3. MTD support for updating the timestamping peripheral on those boards. 4. Fix for potential over-length requests to firmware. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
b85c715c2e
@ -34,3 +34,10 @@ config SFC_SRIOV
|
|||||||
This enables support for the SFC9000 I/O Virtualization
|
This enables support for the SFC9000 I/O Virtualization
|
||||||
features, allowing accelerated network performance in
|
features, allowing accelerated network performance in
|
||||||
virtualized environments.
|
virtualized environments.
|
||||||
|
config SFC_PTP
|
||||||
|
bool "Solarflare SFC9000-family PTP support"
|
||||||
|
depends on SFC && PTP_1588_CLOCK && !(SFC=y && PTP_1588_CLOCK=m)
|
||||||
|
default y
|
||||||
|
---help---
|
||||||
|
This enables support for the Precision Time Protocol (PTP)
|
||||||
|
on SFC9000-family NICs
|
||||||
|
@ -5,5 +5,6 @@ sfc-y += efx.o nic.o falcon.o siena.o tx.o rx.o filter.o \
|
|||||||
mcdi.o mcdi_phy.o mcdi_mon.o
|
mcdi.o mcdi_phy.o mcdi_mon.o
|
||||||
sfc-$(CONFIG_SFC_MTD) += mtd.o
|
sfc-$(CONFIG_SFC_MTD) += mtd.o
|
||||||
sfc-$(CONFIG_SFC_SRIOV) += siena_sriov.o
|
sfc-$(CONFIG_SFC_SRIOV) += siena_sriov.o
|
||||||
|
sfc-$(CONFIG_SFC_PTP) += ptp.o
|
||||||
|
|
||||||
obj-$(CONFIG_SFC) += sfc.o
|
obj-$(CONFIG_SFC) += sfc.o
|
||||||
|
@ -734,6 +734,7 @@ static void efx_remove_channel(struct efx_channel *channel)
|
|||||||
efx_for_each_possible_channel_tx_queue(tx_queue, channel)
|
efx_for_each_possible_channel_tx_queue(tx_queue, channel)
|
||||||
efx_remove_tx_queue(tx_queue);
|
efx_remove_tx_queue(tx_queue);
|
||||||
efx_remove_eventq(channel);
|
efx_remove_eventq(channel);
|
||||||
|
channel->type->post_remove(channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void efx_remove_channels(struct efx_nic *efx)
|
static void efx_remove_channels(struct efx_nic *efx)
|
||||||
@ -852,6 +853,7 @@ void efx_schedule_slow_fill(struct efx_rx_queue *rx_queue)
|
|||||||
|
|
||||||
static const struct efx_channel_type efx_default_channel_type = {
|
static const struct efx_channel_type efx_default_channel_type = {
|
||||||
.pre_probe = efx_channel_dummy_op_int,
|
.pre_probe = efx_channel_dummy_op_int,
|
||||||
|
.post_remove = efx_channel_dummy_op_void,
|
||||||
.get_name = efx_get_channel_name,
|
.get_name = efx_get_channel_name,
|
||||||
.copy = efx_copy_channel,
|
.copy = efx_copy_channel,
|
||||||
.keep_eventq = false,
|
.keep_eventq = false,
|
||||||
@ -862,6 +864,10 @@ int efx_channel_dummy_op_int(struct efx_channel *channel)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void efx_channel_dummy_op_void(struct efx_channel *channel)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
*
|
*
|
||||||
* Port handling
|
* Port handling
|
||||||
@ -1451,10 +1457,16 @@ static void efx_set_channels(struct efx_nic *efx)
|
|||||||
efx->tx_channel_offset =
|
efx->tx_channel_offset =
|
||||||
separate_tx_channels ? efx->n_channels - efx->n_tx_channels : 0;
|
separate_tx_channels ? efx->n_channels - efx->n_tx_channels : 0;
|
||||||
|
|
||||||
/* We need to adjust the TX queue numbers if we have separate
|
/* We need to mark which channels really have RX and TX
|
||||||
|
* queues, and adjust the TX queue numbers if we have separate
|
||||||
* RX-only and TX-only channels.
|
* RX-only and TX-only channels.
|
||||||
*/
|
*/
|
||||||
efx_for_each_channel(channel, efx) {
|
efx_for_each_channel(channel, efx) {
|
||||||
|
if (channel->channel < efx->n_rx_channels)
|
||||||
|
channel->rx_queue.core_index = channel->channel;
|
||||||
|
else
|
||||||
|
channel->rx_queue.core_index = -1;
|
||||||
|
|
||||||
efx_for_each_channel_tx_queue(tx_queue, channel)
|
efx_for_each_channel_tx_queue(tx_queue, channel)
|
||||||
tx_queue->queue -= (efx->tx_channel_offset *
|
tx_queue->queue -= (efx->tx_channel_offset *
|
||||||
EFX_TXQ_TYPES);
|
EFX_TXQ_TYPES);
|
||||||
@ -1767,6 +1779,9 @@ static int efx_ioctl(struct net_device *net_dev, struct ifreq *ifr, int cmd)
|
|||||||
struct efx_nic *efx = netdev_priv(net_dev);
|
struct efx_nic *efx = netdev_priv(net_dev);
|
||||||
struct mii_ioctl_data *data = if_mii(ifr);
|
struct mii_ioctl_data *data = if_mii(ifr);
|
||||||
|
|
||||||
|
if (cmd == SIOCSHWTSTAMP)
|
||||||
|
return efx_ptp_ioctl(efx, ifr, cmd);
|
||||||
|
|
||||||
/* Convert phy_id from older PRTAD/DEVAD format */
|
/* Convert phy_id from older PRTAD/DEVAD format */
|
||||||
if ((cmd == SIOCGMIIREG || cmd == SIOCSMIIREG) &&
|
if ((cmd == SIOCGMIIREG || cmd == SIOCSMIIREG) &&
|
||||||
(data->phy_id & 0xfc00) == 0x0400)
|
(data->phy_id & 0xfc00) == 0x0400)
|
||||||
|
@ -102,6 +102,7 @@ static inline void efx_filter_rfs_expire(struct efx_channel *channel) {}
|
|||||||
|
|
||||||
/* Channels */
|
/* Channels */
|
||||||
extern int efx_channel_dummy_op_int(struct efx_channel *channel);
|
extern int efx_channel_dummy_op_int(struct efx_channel *channel);
|
||||||
|
extern void efx_channel_dummy_op_void(struct efx_channel *channel);
|
||||||
extern void efx_process_channel_now(struct efx_channel *channel);
|
extern void efx_process_channel_now(struct efx_channel *channel);
|
||||||
extern int
|
extern int
|
||||||
efx_realloc_channels(struct efx_nic *efx, u32 rxq_entries, u32 txq_entries);
|
efx_realloc_channels(struct efx_nic *efx, u32 rxq_entries, u32 txq_entries);
|
||||||
|
@ -1174,6 +1174,7 @@ const struct ethtool_ops efx_ethtool_ops = {
|
|||||||
.get_rxfh_indir_size = efx_ethtool_get_rxfh_indir_size,
|
.get_rxfh_indir_size = efx_ethtool_get_rxfh_indir_size,
|
||||||
.get_rxfh_indir = efx_ethtool_get_rxfh_indir,
|
.get_rxfh_indir = efx_ethtool_get_rxfh_indir,
|
||||||
.set_rxfh_indir = efx_ethtool_set_rxfh_indir,
|
.set_rxfh_indir = efx_ethtool_set_rxfh_indir,
|
||||||
|
.get_ts_info = efx_ptp_get_ts_info,
|
||||||
.get_module_info = efx_ethtool_get_module_info,
|
.get_module_info = efx_ethtool_get_module_info,
|
||||||
.get_module_eeprom = efx_ethtool_get_module_eeprom,
|
.get_module_eeprom = efx_ethtool_get_module_eeprom,
|
||||||
};
|
};
|
||||||
|
@ -320,14 +320,20 @@ static void efx_mcdi_ev_cpl(struct efx_nic *efx, unsigned int seqno,
|
|||||||
efx_mcdi_complete(mcdi);
|
efx_mcdi_complete(mcdi);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Issue the given command by writing the data into the shared memory PDU,
|
|
||||||
* ring the doorbell and wait for completion. Copyout the result. */
|
|
||||||
int efx_mcdi_rpc(struct efx_nic *efx, unsigned cmd,
|
int efx_mcdi_rpc(struct efx_nic *efx, unsigned cmd,
|
||||||
const u8 *inbuf, size_t inlen, u8 *outbuf, size_t outlen,
|
const u8 *inbuf, size_t inlen, u8 *outbuf, size_t outlen,
|
||||||
size_t *outlen_actual)
|
size_t *outlen_actual)
|
||||||
|
{
|
||||||
|
efx_mcdi_rpc_start(efx, cmd, inbuf, inlen);
|
||||||
|
return efx_mcdi_rpc_finish(efx, cmd, inlen,
|
||||||
|
outbuf, outlen, outlen_actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
void efx_mcdi_rpc_start(struct efx_nic *efx, unsigned cmd, const u8 *inbuf,
|
||||||
|
size_t inlen)
|
||||||
{
|
{
|
||||||
struct efx_mcdi_iface *mcdi = efx_mcdi(efx);
|
struct efx_mcdi_iface *mcdi = efx_mcdi(efx);
|
||||||
int rc;
|
|
||||||
BUG_ON(efx_nic_rev(efx) < EFX_REV_SIENA_A0);
|
BUG_ON(efx_nic_rev(efx) < EFX_REV_SIENA_A0);
|
||||||
|
|
||||||
efx_mcdi_acquire(mcdi);
|
efx_mcdi_acquire(mcdi);
|
||||||
@ -338,6 +344,15 @@ int efx_mcdi_rpc(struct efx_nic *efx, unsigned cmd,
|
|||||||
spin_unlock_bh(&mcdi->iface_lock);
|
spin_unlock_bh(&mcdi->iface_lock);
|
||||||
|
|
||||||
efx_mcdi_copyin(efx, cmd, inbuf, inlen);
|
efx_mcdi_copyin(efx, cmd, inbuf, inlen);
|
||||||
|
}
|
||||||
|
|
||||||
|
int efx_mcdi_rpc_finish(struct efx_nic *efx, unsigned cmd, size_t inlen,
|
||||||
|
u8 *outbuf, size_t outlen, size_t *outlen_actual)
|
||||||
|
{
|
||||||
|
struct efx_mcdi_iface *mcdi = efx_mcdi(efx);
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
BUG_ON(efx_nic_rev(efx) < EFX_REV_SIENA_A0);
|
||||||
|
|
||||||
if (mcdi->mode == MCDI_MODE_POLL)
|
if (mcdi->mode == MCDI_MODE_POLL)
|
||||||
rc = efx_mcdi_poll(efx);
|
rc = efx_mcdi_poll(efx);
|
||||||
@ -563,6 +578,11 @@ void efx_mcdi_process_event(struct efx_channel *channel,
|
|||||||
case MCDI_EVENT_CODE_FLR:
|
case MCDI_EVENT_CODE_FLR:
|
||||||
efx_sriov_flr(efx, MCDI_EVENT_FIELD(*event, FLR_VF));
|
efx_sriov_flr(efx, MCDI_EVENT_FIELD(*event, FLR_VF));
|
||||||
break;
|
break;
|
||||||
|
case MCDI_EVENT_CODE_PTP_RX:
|
||||||
|
case MCDI_EVENT_CODE_PTP_FAULT:
|
||||||
|
case MCDI_EVENT_CODE_PTP_PPS:
|
||||||
|
efx_ptp_event(efx, event);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
netif_err(efx, hw, efx->net_dev, "Unknown MCDI event 0x%x\n",
|
netif_err(efx, hw, efx->net_dev, "Unknown MCDI event 0x%x\n",
|
||||||
@ -641,9 +661,8 @@ int efx_mcdi_get_board_cfg(struct efx_nic *efx, u8 *mac_address,
|
|||||||
u16 *fw_subtype_list, u32 *capabilities)
|
u16 *fw_subtype_list, u32 *capabilities)
|
||||||
{
|
{
|
||||||
uint8_t outbuf[MC_CMD_GET_BOARD_CFG_OUT_LENMIN];
|
uint8_t outbuf[MC_CMD_GET_BOARD_CFG_OUT_LENMIN];
|
||||||
size_t outlen;
|
size_t outlen, offset, i;
|
||||||
int port_num = efx_port_num(efx);
|
int port_num = efx_port_num(efx);
|
||||||
int offset;
|
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
BUILD_BUG_ON(MC_CMD_GET_BOARD_CFG_IN_LEN != 0);
|
BUILD_BUG_ON(MC_CMD_GET_BOARD_CFG_IN_LEN != 0);
|
||||||
@ -663,11 +682,18 @@ int efx_mcdi_get_board_cfg(struct efx_nic *efx, u8 *mac_address,
|
|||||||
: MC_CMD_GET_BOARD_CFG_OUT_MAC_ADDR_BASE_PORT0_OFST;
|
: MC_CMD_GET_BOARD_CFG_OUT_MAC_ADDR_BASE_PORT0_OFST;
|
||||||
if (mac_address)
|
if (mac_address)
|
||||||
memcpy(mac_address, outbuf + offset, ETH_ALEN);
|
memcpy(mac_address, outbuf + offset, ETH_ALEN);
|
||||||
if (fw_subtype_list)
|
if (fw_subtype_list) {
|
||||||
memcpy(fw_subtype_list,
|
/* Byte-swap and truncate or zero-pad as necessary */
|
||||||
outbuf + MC_CMD_GET_BOARD_CFG_OUT_FW_SUBTYPE_LIST_OFST,
|
offset = MC_CMD_GET_BOARD_CFG_OUT_FW_SUBTYPE_LIST_OFST;
|
||||||
MC_CMD_GET_BOARD_CFG_OUT_FW_SUBTYPE_LIST_MINNUM *
|
for (i = 0;
|
||||||
sizeof(fw_subtype_list[0]));
|
i < MC_CMD_GET_BOARD_CFG_OUT_FW_SUBTYPE_LIST_MAXNUM;
|
||||||
|
i++) {
|
||||||
|
fw_subtype_list[i] =
|
||||||
|
(offset + 2 <= outlen) ?
|
||||||
|
le16_to_cpup((__le16 *)(outbuf + offset)) : 0;
|
||||||
|
offset += 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (capabilities) {
|
if (capabilities) {
|
||||||
if (port_num)
|
if (port_num)
|
||||||
*capabilities = MCDI_DWORD(outbuf,
|
*capabilities = MCDI_DWORD(outbuf,
|
||||||
@ -1169,6 +1195,9 @@ int efx_mcdi_flush_rxqs(struct efx_nic *efx)
|
|||||||
__le32 *qid;
|
__le32 *qid;
|
||||||
int rc, count;
|
int rc, count;
|
||||||
|
|
||||||
|
BUILD_BUG_ON(EFX_MAX_CHANNELS >
|
||||||
|
MC_CMD_FLUSH_RX_QUEUES_IN_QID_OFST_MAXNUM);
|
||||||
|
|
||||||
qid = kmalloc(EFX_MAX_CHANNELS * sizeof(*qid), GFP_KERNEL);
|
qid = kmalloc(EFX_MAX_CHANNELS * sizeof(*qid), GFP_KERNEL);
|
||||||
if (qid == NULL)
|
if (qid == NULL)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
@ -71,6 +71,12 @@ extern int efx_mcdi_rpc(struct efx_nic *efx, unsigned cmd, const u8 *inbuf,
|
|||||||
size_t inlen, u8 *outbuf, size_t outlen,
|
size_t inlen, u8 *outbuf, size_t outlen,
|
||||||
size_t *outlen_actual);
|
size_t *outlen_actual);
|
||||||
|
|
||||||
|
extern void efx_mcdi_rpc_start(struct efx_nic *efx, unsigned cmd,
|
||||||
|
const u8 *inbuf, size_t inlen);
|
||||||
|
extern int efx_mcdi_rpc_finish(struct efx_nic *efx, unsigned cmd, size_t inlen,
|
||||||
|
u8 *outbuf, size_t outlen,
|
||||||
|
size_t *outlen_actual);
|
||||||
|
|
||||||
extern int efx_mcdi_poll_reboot(struct efx_nic *efx);
|
extern int efx_mcdi_poll_reboot(struct efx_nic *efx);
|
||||||
extern void efx_mcdi_mode_poll(struct efx_nic *efx);
|
extern void efx_mcdi_mode_poll(struct efx_nic *efx);
|
||||||
extern void efx_mcdi_mode_event(struct efx_nic *efx);
|
extern void efx_mcdi_mode_event(struct efx_nic *efx);
|
||||||
|
@ -289,6 +289,7 @@
|
|||||||
#define MCDI_EVENT_CODE_TX_FLUSH 0xc /* enum */
|
#define MCDI_EVENT_CODE_TX_FLUSH 0xc /* enum */
|
||||||
#define MCDI_EVENT_CODE_PTP_RX 0xd /* enum */
|
#define MCDI_EVENT_CODE_PTP_RX 0xd /* enum */
|
||||||
#define MCDI_EVENT_CODE_PTP_FAULT 0xe /* enum */
|
#define MCDI_EVENT_CODE_PTP_FAULT 0xe /* enum */
|
||||||
|
#define MCDI_EVENT_CODE_PTP_PPS 0xf /* enum */
|
||||||
#define MCDI_EVENT_CMDDONE_DATA_OFST 0
|
#define MCDI_EVENT_CMDDONE_DATA_OFST 0
|
||||||
#define MCDI_EVENT_CMDDONE_DATA_LBN 0
|
#define MCDI_EVENT_CMDDONE_DATA_LBN 0
|
||||||
#define MCDI_EVENT_CMDDONE_DATA_WIDTH 32
|
#define MCDI_EVENT_CMDDONE_DATA_WIDTH 32
|
||||||
@ -491,12 +492,12 @@
|
|||||||
|
|
||||||
/* MC_CMD_GET_FPGAREG_OUT msgresponse */
|
/* MC_CMD_GET_FPGAREG_OUT msgresponse */
|
||||||
#define MC_CMD_GET_FPGAREG_OUT_LENMIN 1
|
#define MC_CMD_GET_FPGAREG_OUT_LENMIN 1
|
||||||
#define MC_CMD_GET_FPGAREG_OUT_LENMAX 255
|
#define MC_CMD_GET_FPGAREG_OUT_LENMAX 252
|
||||||
#define MC_CMD_GET_FPGAREG_OUT_LEN(num) (0+1*(num))
|
#define MC_CMD_GET_FPGAREG_OUT_LEN(num) (0+1*(num))
|
||||||
#define MC_CMD_GET_FPGAREG_OUT_BUFFER_OFST 0
|
#define MC_CMD_GET_FPGAREG_OUT_BUFFER_OFST 0
|
||||||
#define MC_CMD_GET_FPGAREG_OUT_BUFFER_LEN 1
|
#define MC_CMD_GET_FPGAREG_OUT_BUFFER_LEN 1
|
||||||
#define MC_CMD_GET_FPGAREG_OUT_BUFFER_MINNUM 1
|
#define MC_CMD_GET_FPGAREG_OUT_BUFFER_MINNUM 1
|
||||||
#define MC_CMD_GET_FPGAREG_OUT_BUFFER_MAXNUM 255
|
#define MC_CMD_GET_FPGAREG_OUT_BUFFER_MAXNUM 252
|
||||||
|
|
||||||
|
|
||||||
/***********************************/
|
/***********************************/
|
||||||
@ -507,13 +508,13 @@
|
|||||||
|
|
||||||
/* MC_CMD_PUT_FPGAREG_IN msgrequest */
|
/* MC_CMD_PUT_FPGAREG_IN msgrequest */
|
||||||
#define MC_CMD_PUT_FPGAREG_IN_LENMIN 5
|
#define MC_CMD_PUT_FPGAREG_IN_LENMIN 5
|
||||||
#define MC_CMD_PUT_FPGAREG_IN_LENMAX 255
|
#define MC_CMD_PUT_FPGAREG_IN_LENMAX 252
|
||||||
#define MC_CMD_PUT_FPGAREG_IN_LEN(num) (4+1*(num))
|
#define MC_CMD_PUT_FPGAREG_IN_LEN(num) (4+1*(num))
|
||||||
#define MC_CMD_PUT_FPGAREG_IN_ADDR_OFST 0
|
#define MC_CMD_PUT_FPGAREG_IN_ADDR_OFST 0
|
||||||
#define MC_CMD_PUT_FPGAREG_IN_BUFFER_OFST 4
|
#define MC_CMD_PUT_FPGAREG_IN_BUFFER_OFST 4
|
||||||
#define MC_CMD_PUT_FPGAREG_IN_BUFFER_LEN 1
|
#define MC_CMD_PUT_FPGAREG_IN_BUFFER_LEN 1
|
||||||
#define MC_CMD_PUT_FPGAREG_IN_BUFFER_MINNUM 1
|
#define MC_CMD_PUT_FPGAREG_IN_BUFFER_MINNUM 1
|
||||||
#define MC_CMD_PUT_FPGAREG_IN_BUFFER_MAXNUM 251
|
#define MC_CMD_PUT_FPGAREG_IN_BUFFER_MAXNUM 248
|
||||||
|
|
||||||
/* MC_CMD_PUT_FPGAREG_OUT msgresponse */
|
/* MC_CMD_PUT_FPGAREG_OUT msgresponse */
|
||||||
#define MC_CMD_PUT_FPGAREG_OUT_LEN 0
|
#define MC_CMD_PUT_FPGAREG_OUT_LEN 0
|
||||||
@ -560,7 +561,7 @@
|
|||||||
|
|
||||||
/* MC_CMD_PTP_IN_TRANSMIT msgrequest */
|
/* MC_CMD_PTP_IN_TRANSMIT msgrequest */
|
||||||
#define MC_CMD_PTP_IN_TRANSMIT_LENMIN 13
|
#define MC_CMD_PTP_IN_TRANSMIT_LENMIN 13
|
||||||
#define MC_CMD_PTP_IN_TRANSMIT_LENMAX 255
|
#define MC_CMD_PTP_IN_TRANSMIT_LENMAX 252
|
||||||
#define MC_CMD_PTP_IN_TRANSMIT_LEN(num) (12+1*(num))
|
#define MC_CMD_PTP_IN_TRANSMIT_LEN(num) (12+1*(num))
|
||||||
/* MC_CMD_PTP_IN_CMD_OFST 0 */
|
/* MC_CMD_PTP_IN_CMD_OFST 0 */
|
||||||
/* MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */
|
/* MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */
|
||||||
@ -568,7 +569,7 @@
|
|||||||
#define MC_CMD_PTP_IN_TRANSMIT_PACKET_OFST 12
|
#define MC_CMD_PTP_IN_TRANSMIT_PACKET_OFST 12
|
||||||
#define MC_CMD_PTP_IN_TRANSMIT_PACKET_LEN 1
|
#define MC_CMD_PTP_IN_TRANSMIT_PACKET_LEN 1
|
||||||
#define MC_CMD_PTP_IN_TRANSMIT_PACKET_MINNUM 1
|
#define MC_CMD_PTP_IN_TRANSMIT_PACKET_MINNUM 1
|
||||||
#define MC_CMD_PTP_IN_TRANSMIT_PACKET_MAXNUM 243
|
#define MC_CMD_PTP_IN_TRANSMIT_PACKET_MAXNUM 240
|
||||||
|
|
||||||
/* MC_CMD_PTP_IN_READ_NIC_TIME msgrequest */
|
/* MC_CMD_PTP_IN_READ_NIC_TIME msgrequest */
|
||||||
#define MC_CMD_PTP_IN_READ_NIC_TIME_LEN 8
|
#define MC_CMD_PTP_IN_READ_NIC_TIME_LEN 8
|
||||||
@ -1145,7 +1146,7 @@
|
|||||||
|
|
||||||
/* MC_CMD_PUTS_IN msgrequest */
|
/* MC_CMD_PUTS_IN msgrequest */
|
||||||
#define MC_CMD_PUTS_IN_LENMIN 13
|
#define MC_CMD_PUTS_IN_LENMIN 13
|
||||||
#define MC_CMD_PUTS_IN_LENMAX 255
|
#define MC_CMD_PUTS_IN_LENMAX 252
|
||||||
#define MC_CMD_PUTS_IN_LEN(num) (12+1*(num))
|
#define MC_CMD_PUTS_IN_LEN(num) (12+1*(num))
|
||||||
#define MC_CMD_PUTS_IN_DEST_OFST 0
|
#define MC_CMD_PUTS_IN_DEST_OFST 0
|
||||||
#define MC_CMD_PUTS_IN_UART_LBN 0
|
#define MC_CMD_PUTS_IN_UART_LBN 0
|
||||||
@ -1157,7 +1158,7 @@
|
|||||||
#define MC_CMD_PUTS_IN_STRING_OFST 12
|
#define MC_CMD_PUTS_IN_STRING_OFST 12
|
||||||
#define MC_CMD_PUTS_IN_STRING_LEN 1
|
#define MC_CMD_PUTS_IN_STRING_LEN 1
|
||||||
#define MC_CMD_PUTS_IN_STRING_MINNUM 1
|
#define MC_CMD_PUTS_IN_STRING_MINNUM 1
|
||||||
#define MC_CMD_PUTS_IN_STRING_MAXNUM 243
|
#define MC_CMD_PUTS_IN_STRING_MAXNUM 240
|
||||||
|
|
||||||
/* MC_CMD_PUTS_OUT msgresponse */
|
/* MC_CMD_PUTS_OUT msgresponse */
|
||||||
#define MC_CMD_PUTS_OUT_LEN 0
|
#define MC_CMD_PUTS_OUT_LEN 0
|
||||||
@ -1947,12 +1948,12 @@
|
|||||||
|
|
||||||
/* MC_CMD_NVRAM_READ_OUT msgresponse */
|
/* MC_CMD_NVRAM_READ_OUT msgresponse */
|
||||||
#define MC_CMD_NVRAM_READ_OUT_LENMIN 1
|
#define MC_CMD_NVRAM_READ_OUT_LENMIN 1
|
||||||
#define MC_CMD_NVRAM_READ_OUT_LENMAX 255
|
#define MC_CMD_NVRAM_READ_OUT_LENMAX 252
|
||||||
#define MC_CMD_NVRAM_READ_OUT_LEN(num) (0+1*(num))
|
#define MC_CMD_NVRAM_READ_OUT_LEN(num) (0+1*(num))
|
||||||
#define MC_CMD_NVRAM_READ_OUT_READ_BUFFER_OFST 0
|
#define MC_CMD_NVRAM_READ_OUT_READ_BUFFER_OFST 0
|
||||||
#define MC_CMD_NVRAM_READ_OUT_READ_BUFFER_LEN 1
|
#define MC_CMD_NVRAM_READ_OUT_READ_BUFFER_LEN 1
|
||||||
#define MC_CMD_NVRAM_READ_OUT_READ_BUFFER_MINNUM 1
|
#define MC_CMD_NVRAM_READ_OUT_READ_BUFFER_MINNUM 1
|
||||||
#define MC_CMD_NVRAM_READ_OUT_READ_BUFFER_MAXNUM 255
|
#define MC_CMD_NVRAM_READ_OUT_READ_BUFFER_MAXNUM 252
|
||||||
|
|
||||||
|
|
||||||
/***********************************/
|
/***********************************/
|
||||||
@ -1963,7 +1964,7 @@
|
|||||||
|
|
||||||
/* MC_CMD_NVRAM_WRITE_IN msgrequest */
|
/* MC_CMD_NVRAM_WRITE_IN msgrequest */
|
||||||
#define MC_CMD_NVRAM_WRITE_IN_LENMIN 13
|
#define MC_CMD_NVRAM_WRITE_IN_LENMIN 13
|
||||||
#define MC_CMD_NVRAM_WRITE_IN_LENMAX 255
|
#define MC_CMD_NVRAM_WRITE_IN_LENMAX 252
|
||||||
#define MC_CMD_NVRAM_WRITE_IN_LEN(num) (12+1*(num))
|
#define MC_CMD_NVRAM_WRITE_IN_LEN(num) (12+1*(num))
|
||||||
#define MC_CMD_NVRAM_WRITE_IN_TYPE_OFST 0
|
#define MC_CMD_NVRAM_WRITE_IN_TYPE_OFST 0
|
||||||
/* Enum values, see field(s): */
|
/* Enum values, see field(s): */
|
||||||
@ -1973,7 +1974,7 @@
|
|||||||
#define MC_CMD_NVRAM_WRITE_IN_WRITE_BUFFER_OFST 12
|
#define MC_CMD_NVRAM_WRITE_IN_WRITE_BUFFER_OFST 12
|
||||||
#define MC_CMD_NVRAM_WRITE_IN_WRITE_BUFFER_LEN 1
|
#define MC_CMD_NVRAM_WRITE_IN_WRITE_BUFFER_LEN 1
|
||||||
#define MC_CMD_NVRAM_WRITE_IN_WRITE_BUFFER_MINNUM 1
|
#define MC_CMD_NVRAM_WRITE_IN_WRITE_BUFFER_MINNUM 1
|
||||||
#define MC_CMD_NVRAM_WRITE_IN_WRITE_BUFFER_MAXNUM 243
|
#define MC_CMD_NVRAM_WRITE_IN_WRITE_BUFFER_MAXNUM 240
|
||||||
|
|
||||||
/* MC_CMD_NVRAM_WRITE_OUT msgresponse */
|
/* MC_CMD_NVRAM_WRITE_OUT msgresponse */
|
||||||
#define MC_CMD_NVRAM_WRITE_OUT_LEN 0
|
#define MC_CMD_NVRAM_WRITE_OUT_LEN 0
|
||||||
@ -2305,13 +2306,13 @@
|
|||||||
|
|
||||||
/* MC_CMD_GET_PHY_MEDIA_INFO_OUT msgresponse */
|
/* MC_CMD_GET_PHY_MEDIA_INFO_OUT msgresponse */
|
||||||
#define MC_CMD_GET_PHY_MEDIA_INFO_OUT_LENMIN 5
|
#define MC_CMD_GET_PHY_MEDIA_INFO_OUT_LENMIN 5
|
||||||
#define MC_CMD_GET_PHY_MEDIA_INFO_OUT_LENMAX 255
|
#define MC_CMD_GET_PHY_MEDIA_INFO_OUT_LENMAX 252
|
||||||
#define MC_CMD_GET_PHY_MEDIA_INFO_OUT_LEN(num) (4+1*(num))
|
#define MC_CMD_GET_PHY_MEDIA_INFO_OUT_LEN(num) (4+1*(num))
|
||||||
#define MC_CMD_GET_PHY_MEDIA_INFO_OUT_DATALEN_OFST 0
|
#define MC_CMD_GET_PHY_MEDIA_INFO_OUT_DATALEN_OFST 0
|
||||||
#define MC_CMD_GET_PHY_MEDIA_INFO_OUT_DATA_OFST 4
|
#define MC_CMD_GET_PHY_MEDIA_INFO_OUT_DATA_OFST 4
|
||||||
#define MC_CMD_GET_PHY_MEDIA_INFO_OUT_DATA_LEN 1
|
#define MC_CMD_GET_PHY_MEDIA_INFO_OUT_DATA_LEN 1
|
||||||
#define MC_CMD_GET_PHY_MEDIA_INFO_OUT_DATA_MINNUM 1
|
#define MC_CMD_GET_PHY_MEDIA_INFO_OUT_DATA_MINNUM 1
|
||||||
#define MC_CMD_GET_PHY_MEDIA_INFO_OUT_DATA_MAXNUM 251
|
#define MC_CMD_GET_PHY_MEDIA_INFO_OUT_DATA_MAXNUM 248
|
||||||
|
|
||||||
|
|
||||||
/***********************************/
|
/***********************************/
|
||||||
|
@ -585,6 +585,7 @@ static const struct siena_nvram_type_info siena_nvram_types[] = {
|
|||||||
[MC_CMD_NVRAM_TYPE_EXP_ROM_CFG_PORT1] = { 1, "sfc_exp_rom_cfg" },
|
[MC_CMD_NVRAM_TYPE_EXP_ROM_CFG_PORT1] = { 1, "sfc_exp_rom_cfg" },
|
||||||
[MC_CMD_NVRAM_TYPE_PHY_PORT0] = { 0, "sfc_phy_fw" },
|
[MC_CMD_NVRAM_TYPE_PHY_PORT0] = { 0, "sfc_phy_fw" },
|
||||||
[MC_CMD_NVRAM_TYPE_PHY_PORT1] = { 1, "sfc_phy_fw" },
|
[MC_CMD_NVRAM_TYPE_PHY_PORT1] = { 1, "sfc_phy_fw" },
|
||||||
|
[MC_CMD_NVRAM_TYPE_FPGA] = { 0, "sfc_fpga" },
|
||||||
};
|
};
|
||||||
|
|
||||||
static int siena_mtd_probe_partition(struct efx_nic *efx,
|
static int siena_mtd_probe_partition(struct efx_nic *efx,
|
||||||
@ -598,7 +599,8 @@ static int siena_mtd_probe_partition(struct efx_nic *efx,
|
|||||||
bool protected;
|
bool protected;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
if (type >= ARRAY_SIZE(siena_nvram_types))
|
if (type >= ARRAY_SIZE(siena_nvram_types) ||
|
||||||
|
siena_nvram_types[type].name == NULL)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
info = &siena_nvram_types[type];
|
info = &siena_nvram_types[type];
|
||||||
@ -627,7 +629,8 @@ static int siena_mtd_get_fw_subtypes(struct efx_nic *efx,
|
|||||||
struct efx_mtd *efx_mtd)
|
struct efx_mtd *efx_mtd)
|
||||||
{
|
{
|
||||||
struct efx_mtd_partition *part;
|
struct efx_mtd_partition *part;
|
||||||
uint16_t fw_subtype_list[MC_CMD_GET_BOARD_CFG_OUT_FW_SUBTYPE_LIST_MINNUM];
|
uint16_t fw_subtype_list[
|
||||||
|
MC_CMD_GET_BOARD_CFG_OUT_FW_SUBTYPE_LIST_MAXNUM];
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
rc = efx_mcdi_get_board_cfg(efx, NULL, fw_subtype_list, NULL);
|
rc = efx_mcdi_get_board_cfg(efx, NULL, fw_subtype_list, NULL);
|
||||||
|
@ -37,7 +37,7 @@
|
|||||||
*
|
*
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
#define EFX_DRIVER_VERSION "3.1"
|
#define EFX_DRIVER_VERSION "3.2"
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
#define EFX_BUG_ON_PARANOID(x) BUG_ON(x)
|
#define EFX_BUG_ON_PARANOID(x) BUG_ON(x)
|
||||||
@ -56,7 +56,8 @@
|
|||||||
#define EFX_MAX_CHANNELS 32U
|
#define EFX_MAX_CHANNELS 32U
|
||||||
#define EFX_MAX_RX_QUEUES EFX_MAX_CHANNELS
|
#define EFX_MAX_RX_QUEUES EFX_MAX_CHANNELS
|
||||||
#define EFX_EXTRA_CHANNEL_IOV 0
|
#define EFX_EXTRA_CHANNEL_IOV 0
|
||||||
#define EFX_MAX_EXTRA_CHANNELS 1U
|
#define EFX_EXTRA_CHANNEL_PTP 1
|
||||||
|
#define EFX_MAX_EXTRA_CHANNELS 2U
|
||||||
|
|
||||||
/* Checksum generation is a per-queue option in hardware, so each
|
/* Checksum generation is a per-queue option in hardware, so each
|
||||||
* queue visible to the networking core is backed by two hardware TX
|
* queue visible to the networking core is backed by two hardware TX
|
||||||
@ -68,6 +69,9 @@
|
|||||||
#define EFX_TXQ_TYPES 4
|
#define EFX_TXQ_TYPES 4
|
||||||
#define EFX_MAX_TX_QUEUES (EFX_TXQ_TYPES * EFX_MAX_CHANNELS)
|
#define EFX_MAX_TX_QUEUES (EFX_TXQ_TYPES * EFX_MAX_CHANNELS)
|
||||||
|
|
||||||
|
/* Forward declare Precision Time Protocol (PTP) support structure. */
|
||||||
|
struct efx_ptp_data;
|
||||||
|
|
||||||
struct efx_self_tests;
|
struct efx_self_tests;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -242,6 +246,8 @@ struct efx_rx_page_state {
|
|||||||
/**
|
/**
|
||||||
* struct efx_rx_queue - An Efx RX queue
|
* struct efx_rx_queue - An Efx RX queue
|
||||||
* @efx: The associated Efx NIC
|
* @efx: The associated Efx NIC
|
||||||
|
* @core_index: Index of network core RX queue. Will be >= 0 iff this
|
||||||
|
* is associated with a real RX queue.
|
||||||
* @buffer: The software buffer ring
|
* @buffer: The software buffer ring
|
||||||
* @rxd: The hardware descriptor ring
|
* @rxd: The hardware descriptor ring
|
||||||
* @ptr_mask: The size of the ring minus 1.
|
* @ptr_mask: The size of the ring minus 1.
|
||||||
@ -263,6 +269,7 @@ struct efx_rx_page_state {
|
|||||||
*/
|
*/
|
||||||
struct efx_rx_queue {
|
struct efx_rx_queue {
|
||||||
struct efx_nic *efx;
|
struct efx_nic *efx;
|
||||||
|
int core_index;
|
||||||
struct efx_rx_buffer *buffer;
|
struct efx_rx_buffer *buffer;
|
||||||
struct efx_special_buffer rxd;
|
struct efx_special_buffer rxd;
|
||||||
unsigned int ptr_mask;
|
unsigned int ptr_mask;
|
||||||
@ -390,14 +397,17 @@ struct efx_channel {
|
|||||||
* @get_name: Generate the channel's name (used for its IRQ handler)
|
* @get_name: Generate the channel's name (used for its IRQ handler)
|
||||||
* @copy: Copy the channel state prior to reallocation. May be %NULL if
|
* @copy: Copy the channel state prior to reallocation. May be %NULL if
|
||||||
* reallocation is not supported.
|
* reallocation is not supported.
|
||||||
|
* @receive_skb: Handle an skb ready to be passed to netif_receive_skb()
|
||||||
* @keep_eventq: Flag for whether event queue should be kept initialised
|
* @keep_eventq: Flag for whether event queue should be kept initialised
|
||||||
* while the device is stopped
|
* while the device is stopped
|
||||||
*/
|
*/
|
||||||
struct efx_channel_type {
|
struct efx_channel_type {
|
||||||
void (*handle_no_channel)(struct efx_nic *);
|
void (*handle_no_channel)(struct efx_nic *);
|
||||||
int (*pre_probe)(struct efx_channel *);
|
int (*pre_probe)(struct efx_channel *);
|
||||||
|
void (*post_remove)(struct efx_channel *);
|
||||||
void (*get_name)(struct efx_channel *, char *buf, size_t len);
|
void (*get_name)(struct efx_channel *, char *buf, size_t len);
|
||||||
struct efx_channel *(*copy)(const struct efx_channel *);
|
struct efx_channel *(*copy)(const struct efx_channel *);
|
||||||
|
void (*receive_skb)(struct efx_channel *, struct sk_buff *);
|
||||||
bool keep_eventq;
|
bool keep_eventq;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -730,6 +740,7 @@ struct vfdi_status;
|
|||||||
* %local_addr_list. Protected by %local_lock.
|
* %local_addr_list. Protected by %local_lock.
|
||||||
* @local_lock: Mutex protecting %local_addr_list and %local_page_list.
|
* @local_lock: Mutex protecting %local_addr_list and %local_page_list.
|
||||||
* @peer_work: Work item to broadcast peer addresses to VMs.
|
* @peer_work: Work item to broadcast peer addresses to VMs.
|
||||||
|
* @ptp_data: PTP state data
|
||||||
* @monitor_work: Hardware monitor workitem
|
* @monitor_work: Hardware monitor workitem
|
||||||
* @biu_lock: BIU (bus interface unit) lock
|
* @biu_lock: BIU (bus interface unit) lock
|
||||||
* @last_irq_cpu: Last CPU to handle a possible test interrupt. This
|
* @last_irq_cpu: Last CPU to handle a possible test interrupt. This
|
||||||
@ -857,6 +868,10 @@ struct efx_nic {
|
|||||||
struct work_struct peer_work;
|
struct work_struct peer_work;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_SFC_PTP
|
||||||
|
struct efx_ptp_data *ptp_data;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* The following fields may be written more often */
|
/* The following fields may be written more often */
|
||||||
|
|
||||||
struct delayed_work monitor_work ____cacheline_aligned_in_smp;
|
struct delayed_work monitor_work ____cacheline_aligned_in_smp;
|
||||||
@ -1047,7 +1062,7 @@ static inline bool efx_tx_queue_used(struct efx_tx_queue *tx_queue)
|
|||||||
|
|
||||||
static inline bool efx_channel_has_rx_queue(struct efx_channel *channel)
|
static inline bool efx_channel_has_rx_queue(struct efx_channel *channel)
|
||||||
{
|
{
|
||||||
return channel->channel < channel->efx->n_rx_channels;
|
return channel->rx_queue.core_index >= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline struct efx_rx_queue *
|
static inline struct efx_rx_queue *
|
||||||
@ -1119,5 +1134,13 @@ static inline void clear_bit_le(unsigned nr, unsigned char *addr)
|
|||||||
#define EFX_MAX_FRAME_LEN(mtu) \
|
#define EFX_MAX_FRAME_LEN(mtu) \
|
||||||
((((mtu) + ETH_HLEN + VLAN_HLEN + 4/* FCS */ + 7) & ~7) + 16)
|
((((mtu) + ETH_HLEN + VLAN_HLEN + 4/* FCS */ + 7) & ~7) + 16)
|
||||||
|
|
||||||
|
static inline bool efx_xmit_with_hwtstamp(struct sk_buff *skb)
|
||||||
|
{
|
||||||
|
return skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP;
|
||||||
|
}
|
||||||
|
static inline void efx_xmit_hwtstamp_pending(struct sk_buff *skb)
|
||||||
|
{
|
||||||
|
skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* EFX_NET_DRIVER_H */
|
#endif /* EFX_NET_DRIVER_H */
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
#ifndef EFX_NIC_H
|
#ifndef EFX_NIC_H
|
||||||
#define EFX_NIC_H
|
#define EFX_NIC_H
|
||||||
|
|
||||||
|
#include <linux/net_tstamp.h>
|
||||||
#include <linux/i2c-algo-bit.h>
|
#include <linux/i2c-algo-bit.h>
|
||||||
#include "net_driver.h"
|
#include "net_driver.h"
|
||||||
#include "efx.h"
|
#include "efx.h"
|
||||||
@ -250,6 +251,41 @@ extern int efx_sriov_get_vf_config(struct net_device *dev, int vf,
|
|||||||
extern int efx_sriov_set_vf_spoofchk(struct net_device *net_dev, int vf,
|
extern int efx_sriov_set_vf_spoofchk(struct net_device *net_dev, int vf,
|
||||||
bool spoofchk);
|
bool spoofchk);
|
||||||
|
|
||||||
|
struct ethtool_ts_info;
|
||||||
|
#ifdef CONFIG_SFC_PTP
|
||||||
|
extern void efx_ptp_probe(struct efx_nic *efx);
|
||||||
|
extern int efx_ptp_ioctl(struct efx_nic *efx, struct ifreq *ifr, int cmd);
|
||||||
|
extern int efx_ptp_get_ts_info(struct net_device *net_dev,
|
||||||
|
struct ethtool_ts_info *ts_info);
|
||||||
|
extern bool efx_ptp_is_ptp_tx(struct efx_nic *efx, struct sk_buff *skb);
|
||||||
|
extern int efx_ptp_tx(struct efx_nic *efx, struct sk_buff *skb);
|
||||||
|
extern void efx_ptp_event(struct efx_nic *efx, efx_qword_t *ev);
|
||||||
|
#else
|
||||||
|
static inline void efx_ptp_probe(struct efx_nic *efx) {}
|
||||||
|
static inline int efx_ptp_ioctl(struct efx_nic *efx, struct ifreq *ifr, int cmd)
|
||||||
|
{
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
}
|
||||||
|
static inline int efx_ptp_get_ts_info(struct net_device *net_dev,
|
||||||
|
struct ethtool_ts_info *ts_info)
|
||||||
|
{
|
||||||
|
ts_info->so_timestamping = (SOF_TIMESTAMPING_SOFTWARE |
|
||||||
|
SOF_TIMESTAMPING_RX_SOFTWARE);
|
||||||
|
ts_info->phc_index = -1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
static inline bool efx_ptp_is_ptp_tx(struct efx_nic *efx, struct sk_buff *skb)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
static inline int efx_ptp_tx(struct efx_nic *efx, struct sk_buff *skb)
|
||||||
|
{
|
||||||
|
return NETDEV_TX_OK;
|
||||||
|
}
|
||||||
|
static inline void efx_ptp_event(struct efx_nic *efx, efx_qword_t *ev) {}
|
||||||
|
#endif
|
||||||
|
|
||||||
extern const struct efx_nic_type falcon_a1_nic_type;
|
extern const struct efx_nic_type falcon_a1_nic_type;
|
||||||
extern const struct efx_nic_type falcon_b0_nic_type;
|
extern const struct efx_nic_type falcon_b0_nic_type;
|
||||||
extern const struct efx_nic_type siena_a0_nic_type;
|
extern const struct efx_nic_type siena_a0_nic_type;
|
||||||
|
1483
drivers/net/ethernet/sfc/ptp.c
Normal file
1483
drivers/net/ethernet/sfc/ptp.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -479,7 +479,7 @@ static void efx_rx_packet_gro(struct efx_channel *channel,
|
|||||||
skb->ip_summed = ((rx_buf->flags & EFX_RX_PKT_CSUMMED) ?
|
skb->ip_summed = ((rx_buf->flags & EFX_RX_PKT_CSUMMED) ?
|
||||||
CHECKSUM_UNNECESSARY : CHECKSUM_NONE);
|
CHECKSUM_UNNECESSARY : CHECKSUM_NONE);
|
||||||
|
|
||||||
skb_record_rx_queue(skb, channel->channel);
|
skb_record_rx_queue(skb, channel->rx_queue.core_index);
|
||||||
|
|
||||||
gro_result = napi_gro_frags(napi);
|
gro_result = napi_gro_frags(napi);
|
||||||
} else {
|
} else {
|
||||||
@ -571,7 +571,13 @@ static void efx_rx_deliver(struct efx_channel *channel,
|
|||||||
/* Set the SKB flags */
|
/* Set the SKB flags */
|
||||||
skb_checksum_none_assert(skb);
|
skb_checksum_none_assert(skb);
|
||||||
|
|
||||||
|
/* Record the rx_queue */
|
||||||
|
skb_record_rx_queue(skb, channel->rx_queue.core_index);
|
||||||
|
|
||||||
/* Pass the packet up */
|
/* Pass the packet up */
|
||||||
|
if (channel->type->receive_skb)
|
||||||
|
channel->type->receive_skb(channel, skb);
|
||||||
|
else
|
||||||
netif_receive_skb(skb);
|
netif_receive_skb(skb);
|
||||||
|
|
||||||
/* Update allocation strategy method */
|
/* Update allocation strategy method */
|
||||||
@ -608,13 +614,14 @@ void __efx_rx_packet(struct efx_channel *channel, struct efx_rx_buffer *rx_buf)
|
|||||||
* at the ethernet header */
|
* at the ethernet header */
|
||||||
skb->protocol = eth_type_trans(skb, efx->net_dev);
|
skb->protocol = eth_type_trans(skb, efx->net_dev);
|
||||||
|
|
||||||
skb_record_rx_queue(skb, channel->channel);
|
skb_record_rx_queue(skb, channel->rx_queue.core_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (unlikely(!(efx->net_dev->features & NETIF_F_RXCSUM)))
|
if (unlikely(!(efx->net_dev->features & NETIF_F_RXCSUM)))
|
||||||
rx_buf->flags &= ~EFX_RX_PKT_CSUMMED;
|
rx_buf->flags &= ~EFX_RX_PKT_CSUMMED;
|
||||||
|
|
||||||
if (likely(rx_buf->flags & (EFX_RX_BUF_PAGE | EFX_RX_PKT_CSUMMED)))
|
if (likely(rx_buf->flags & (EFX_RX_BUF_PAGE | EFX_RX_PKT_CSUMMED)) &&
|
||||||
|
!channel->type->receive_skb)
|
||||||
efx_rx_packet_gro(channel, rx_buf, eh);
|
efx_rx_packet_gro(channel, rx_buf, eh);
|
||||||
else
|
else
|
||||||
efx_rx_deliver(channel, rx_buf);
|
efx_rx_deliver(channel, rx_buf);
|
||||||
@ -624,6 +631,11 @@ void efx_rx_strategy(struct efx_channel *channel)
|
|||||||
{
|
{
|
||||||
enum efx_rx_alloc_method method = rx_alloc_method;
|
enum efx_rx_alloc_method method = rx_alloc_method;
|
||||||
|
|
||||||
|
if (channel->type->receive_skb) {
|
||||||
|
channel->rx_alloc_push_pages = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* Only makes sense to use page based allocation if GRO is enabled */
|
/* Only makes sense to use page based allocation if GRO is enabled */
|
||||||
if (!(channel->efx->net_dev->features & NETIF_F_GRO)) {
|
if (!(channel->efx->net_dev->features & NETIF_F_GRO)) {
|
||||||
method = RX_ALLOC_METHOD_SKB;
|
method = RX_ALLOC_METHOD_SKB;
|
||||||
|
@ -335,6 +335,7 @@ static int siena_probe_nic(struct efx_nic *efx)
|
|||||||
goto fail5;
|
goto fail5;
|
||||||
|
|
||||||
efx_sriov_probe(efx);
|
efx_sriov_probe(efx);
|
||||||
|
efx_ptp_probe(efx);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -21,6 +21,9 @@
|
|||||||
/* Number of longs required to track all the VIs in a VF */
|
/* Number of longs required to track all the VIs in a VF */
|
||||||
#define VI_MASK_LENGTH BITS_TO_LONGS(1 << EFX_VI_SCALE_MAX)
|
#define VI_MASK_LENGTH BITS_TO_LONGS(1 << EFX_VI_SCALE_MAX)
|
||||||
|
|
||||||
|
/* Maximum number of RX queues supported */
|
||||||
|
#define VF_MAX_RX_QUEUES 63
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* enum efx_vf_tx_filter_mode - TX MAC filtering behaviour
|
* enum efx_vf_tx_filter_mode - TX MAC filtering behaviour
|
||||||
* @VF_TX_FILTER_OFF: Disabled
|
* @VF_TX_FILTER_OFF: Disabled
|
||||||
@ -578,6 +581,7 @@ static int efx_vfdi_init_rxq(struct efx_vf *vf)
|
|||||||
efx_oword_t reg;
|
efx_oword_t reg;
|
||||||
|
|
||||||
if (bad_vf_index(efx, vf_evq) || bad_vf_index(efx, vf_rxq) ||
|
if (bad_vf_index(efx, vf_evq) || bad_vf_index(efx, vf_rxq) ||
|
||||||
|
vf_rxq >= VF_MAX_RX_QUEUES ||
|
||||||
bad_buf_count(buf_count, EFX_MAX_DMAQ_SIZE)) {
|
bad_buf_count(buf_count, EFX_MAX_DMAQ_SIZE)) {
|
||||||
if (net_ratelimit())
|
if (net_ratelimit())
|
||||||
netif_err(efx, hw, efx->net_dev,
|
netif_err(efx, hw, efx->net_dev,
|
||||||
@ -683,6 +687,9 @@ static int efx_vfdi_fini_all_queues(struct efx_vf *vf)
|
|||||||
__le32 *rxqs;
|
__le32 *rxqs;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
|
BUILD_BUG_ON(VF_MAX_RX_QUEUES >
|
||||||
|
MC_CMD_FLUSH_RX_QUEUES_IN_QID_OFST_MAXNUM);
|
||||||
|
|
||||||
rxqs = kmalloc(count * sizeof(*rxqs), GFP_KERNEL);
|
rxqs = kmalloc(count * sizeof(*rxqs), GFP_KERNEL);
|
||||||
if (rxqs == NULL)
|
if (rxqs == NULL)
|
||||||
return VFDI_RC_ENOMEM;
|
return VFDI_RC_ENOMEM;
|
||||||
|
@ -339,6 +339,12 @@ netdev_tx_t efx_hard_start_xmit(struct sk_buff *skb,
|
|||||||
|
|
||||||
EFX_WARN_ON_PARANOID(!netif_device_present(net_dev));
|
EFX_WARN_ON_PARANOID(!netif_device_present(net_dev));
|
||||||
|
|
||||||
|
/* PTP "event" packet */
|
||||||
|
if (unlikely(efx_xmit_with_hwtstamp(skb)) &&
|
||||||
|
unlikely(efx_ptp_is_ptp_tx(efx, skb))) {
|
||||||
|
return efx_ptp_tx(efx, skb);
|
||||||
|
}
|
||||||
|
|
||||||
index = skb_get_queue_mapping(skb);
|
index = skb_get_queue_mapping(skb);
|
||||||
type = skb->ip_summed == CHECKSUM_PARTIAL ? EFX_TXQ_TYPE_OFFLOAD : 0;
|
type = skb->ip_summed == CHECKSUM_PARTIAL ? EFX_TXQ_TYPE_OFFLOAD : 0;
|
||||||
if (index >= efx->n_tx_channels) {
|
if (index >= efx->n_tx_channels) {
|
||||||
|
@ -300,6 +300,11 @@ void ptp_clock_event(struct ptp_clock *ptp, struct ptp_clock_event *event)
|
|||||||
pps_get_ts(&evt);
|
pps_get_ts(&evt);
|
||||||
pps_event(ptp->pps_source, &evt, PTP_PPS_EVENT, NULL);
|
pps_event(ptp->pps_source, &evt, PTP_PPS_EVENT, NULL);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case PTP_CLOCK_PPSUSR:
|
||||||
|
pps_event(ptp->pps_source, &event->pps_times,
|
||||||
|
PTP_PPS_EVENT, NULL);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(ptp_clock_event);
|
EXPORT_SYMBOL(ptp_clock_event);
|
||||||
|
@ -116,5 +116,14 @@ static inline void pps_get_ts(struct pps_event_time *ts)
|
|||||||
|
|
||||||
#endif /* CONFIG_NTP_PPS */
|
#endif /* CONFIG_NTP_PPS */
|
||||||
|
|
||||||
|
/* Subtract known time delay from PPS event time(s) */
|
||||||
|
static inline void pps_sub_ts(struct pps_event_time *ts, struct timespec delta)
|
||||||
|
{
|
||||||
|
ts->ts_real = timespec_sub(ts->ts_real, delta);
|
||||||
|
#ifdef CONFIG_NTP_PPS
|
||||||
|
ts->ts_raw = timespec_sub(ts->ts_raw, delta);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* LINUX_PPS_KERNEL_H */
|
#endif /* LINUX_PPS_KERNEL_H */
|
||||||
|
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
#ifndef _PTP_CLOCK_KERNEL_H_
|
#ifndef _PTP_CLOCK_KERNEL_H_
|
||||||
#define _PTP_CLOCK_KERNEL_H_
|
#define _PTP_CLOCK_KERNEL_H_
|
||||||
|
|
||||||
|
#include <linux/pps_kernel.h>
|
||||||
#include <linux/ptp_clock.h>
|
#include <linux/ptp_clock.h>
|
||||||
|
|
||||||
|
|
||||||
@ -110,6 +111,7 @@ enum ptp_clock_events {
|
|||||||
PTP_CLOCK_ALARM,
|
PTP_CLOCK_ALARM,
|
||||||
PTP_CLOCK_EXTTS,
|
PTP_CLOCK_EXTTS,
|
||||||
PTP_CLOCK_PPS,
|
PTP_CLOCK_PPS,
|
||||||
|
PTP_CLOCK_PPSUSR,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -117,13 +119,17 @@ enum ptp_clock_events {
|
|||||||
*
|
*
|
||||||
* @type: One of the ptp_clock_events enumeration values.
|
* @type: One of the ptp_clock_events enumeration values.
|
||||||
* @index: Identifies the source of the event.
|
* @index: Identifies the source of the event.
|
||||||
* @timestamp: When the event occured.
|
* @timestamp: When the event occurred (%PTP_CLOCK_EXTTS only).
|
||||||
|
* @pps_times: When the event occurred (%PTP_CLOCK_PPSUSR only).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
struct ptp_clock_event {
|
struct ptp_clock_event {
|
||||||
int type;
|
int type;
|
||||||
int index;
|
int index;
|
||||||
|
union {
|
||||||
u64 timestamp;
|
u64 timestamp;
|
||||||
|
struct pps_event_time pps_times;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user