Commit 38e00438 authored by Vasu Dev's avatar Vasu Dev Committed by David S. Miller

i40e: Adds FCoE related code to i40e core driver

Adds FCoE specific code to existing i40e core driver to:-

1. have separate FCoE VSI with additional FCoE queues pairs.
2. have FCoE related hash defines.
3. have additional FCoE related stats code.
4. export and then re-use existing functions required by FCoE build.
Signed-off-by: default avatarVasu Dev <vasu.dev@intel.com>
Tested-by: Jack Morgan<jack.morgan@intel.com>
Signed-off-by: default avatarAaron Brown <aaron.f.brown@intel.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent a1a69369
...@@ -54,6 +54,9 @@ ...@@ -54,6 +54,9 @@
#include <linux/ptp_clock_kernel.h> #include <linux/ptp_clock_kernel.h>
#include "i40e_type.h" #include "i40e_type.h"
#include "i40e_prototype.h" #include "i40e_prototype.h"
#ifdef I40E_FCOE
#include "i40e_fcoe.h"
#endif
#include "i40e_virtchnl.h" #include "i40e_virtchnl.h"
#include "i40e_virtchnl_pf.h" #include "i40e_virtchnl_pf.h"
#include "i40e_txrx.h" #include "i40e_txrx.h"
...@@ -79,6 +82,10 @@ ...@@ -79,6 +82,10 @@
#define I40E_MAX_QUEUES_PER_TC 64 /* should be a power of 2 */ #define I40E_MAX_QUEUES_PER_TC 64 /* should be a power of 2 */
#define I40E_FDIR_RING 0 #define I40E_FDIR_RING 0
#define I40E_FDIR_RING_COUNT 32 #define I40E_FDIR_RING_COUNT 32
#ifdef I40E_FCOE
#define I40E_DEFAULT_FCOE 8 /* default number of QPs for FCoE */
#define I40E_MINIMUM_FCOE 1 /* minimum number of QPs for FCoE */
#endif /* I40E_FCOE */
#define I40E_MAX_AQ_BUF_SIZE 4096 #define I40E_MAX_AQ_BUF_SIZE 4096
#define I40E_AQ_LEN 32 #define I40E_AQ_LEN 32
#define I40E_AQ_WORK_LIMIT 16 #define I40E_AQ_WORK_LIMIT 16
...@@ -225,6 +232,10 @@ struct i40e_pf { ...@@ -225,6 +232,10 @@ struct i40e_pf {
u16 num_vmdq_msix; /* num queue vectors per vmdq pool */ u16 num_vmdq_msix; /* num queue vectors per vmdq pool */
u16 num_req_vfs; /* num vfs requested for this vf */ u16 num_req_vfs; /* num vfs requested for this vf */
u16 num_vf_qps; /* num queue pairs per vf */ u16 num_vf_qps; /* num queue pairs per vf */
#ifdef I40E_FCOE
u16 num_fcoe_qps; /* num fcoe queues this pf has set up */
u16 num_fcoe_msix; /* num queue vectors per fcoe pool */
#endif /* I40E_FCOE */
u16 num_lan_qps; /* num lan queues this pf has set up */ u16 num_lan_qps; /* num lan queues this pf has set up */
u16 num_lan_msix; /* num queue vectors for the base pf vsi */ u16 num_lan_msix; /* num queue vectors for the base pf vsi */
int queues_left; /* queues left unclaimed */ int queues_left; /* queues left unclaimed */
...@@ -265,6 +276,9 @@ struct i40e_pf { ...@@ -265,6 +276,9 @@ struct i40e_pf {
#define I40E_FLAG_VMDQ_ENABLED (u64)(1 << 7) #define I40E_FLAG_VMDQ_ENABLED (u64)(1 << 7)
#define I40E_FLAG_FDIR_REQUIRES_REINIT (u64)(1 << 8) #define I40E_FLAG_FDIR_REQUIRES_REINIT (u64)(1 << 8)
#define I40E_FLAG_NEED_LINK_UPDATE (u64)(1 << 9) #define I40E_FLAG_NEED_LINK_UPDATE (u64)(1 << 9)
#ifdef I40E_FCOE
#define I40E_FLAG_FCOE_ENABLED (u64)(1 << 11)
#endif /* I40E_FCOE */
#define I40E_FLAG_IN_NETPOLL (u64)(1 << 12) #define I40E_FLAG_IN_NETPOLL (u64)(1 << 12)
#define I40E_FLAG_16BYTE_RX_DESC_ENABLED (u64)(1 << 13) #define I40E_FLAG_16BYTE_RX_DESC_ENABLED (u64)(1 << 13)
#define I40E_FLAG_CLEAN_ADMINQ (u64)(1 << 14) #define I40E_FLAG_CLEAN_ADMINQ (u64)(1 << 14)
...@@ -286,6 +300,10 @@ struct i40e_pf { ...@@ -286,6 +300,10 @@ struct i40e_pf {
/* tracks features that get auto disabled by errors */ /* tracks features that get auto disabled by errors */
u64 auto_disable_flags; u64 auto_disable_flags;
#ifdef I40E_FCOE
struct i40e_fcoe fcoe;
#endif /* I40E_FCOE */
bool stat_offsets_loaded; bool stat_offsets_loaded;
struct i40e_hw_port_stats stats; struct i40e_hw_port_stats stats;
struct i40e_hw_port_stats stats_offsets; struct i40e_hw_port_stats stats_offsets;
...@@ -408,6 +426,11 @@ struct i40e_vsi { ...@@ -408,6 +426,11 @@ struct i40e_vsi {
struct rtnl_link_stats64 net_stats_offsets; struct rtnl_link_stats64 net_stats_offsets;
struct i40e_eth_stats eth_stats; struct i40e_eth_stats eth_stats;
struct i40e_eth_stats eth_stats_offsets; struct i40e_eth_stats eth_stats_offsets;
#ifdef I40E_FCOE
struct i40e_fcoe_stats fcoe_stats;
struct i40e_fcoe_stats fcoe_stats_offsets;
bool fcoe_stat_offsets_loaded;
#endif
u32 tx_restart; u32 tx_restart;
u32 tx_busy; u32 tx_busy;
u32 rx_buf_failed; u32 rx_buf_failed;
...@@ -598,6 +621,11 @@ struct i40e_vsi *i40e_vsi_setup(struct i40e_pf *pf, u8 type, ...@@ -598,6 +621,11 @@ struct i40e_vsi *i40e_vsi_setup(struct i40e_pf *pf, u8 type,
int i40e_vsi_release(struct i40e_vsi *vsi); int i40e_vsi_release(struct i40e_vsi *vsi);
struct i40e_vsi *i40e_vsi_lookup(struct i40e_pf *pf, enum i40e_vsi_type type, struct i40e_vsi *i40e_vsi_lookup(struct i40e_pf *pf, enum i40e_vsi_type type,
struct i40e_vsi *start_vsi); struct i40e_vsi *start_vsi);
#ifdef I40E_FCOE
void i40e_vsi_setup_queue_map(struct i40e_vsi *vsi,
struct i40e_vsi_context *ctxt,
u8 enabled_tc, bool is_add);
#endif
int i40e_vsi_control_rings(struct i40e_vsi *vsi, bool enable); int i40e_vsi_control_rings(struct i40e_vsi *vsi, bool enable);
int i40e_reconfig_rss_queues(struct i40e_pf *pf, int queue_count); int i40e_reconfig_rss_queues(struct i40e_pf *pf, int queue_count);
struct i40e_veb *i40e_veb_setup(struct i40e_pf *pf, u16 flags, u16 uplink_seid, struct i40e_veb *i40e_veb_setup(struct i40e_pf *pf, u16 flags, u16 uplink_seid,
...@@ -624,7 +652,21 @@ void i40e_irq_dynamic_enable(struct i40e_vsi *vsi, int vector); ...@@ -624,7 +652,21 @@ void i40e_irq_dynamic_enable(struct i40e_vsi *vsi, int vector);
void i40e_irq_dynamic_disable(struct i40e_vsi *vsi, int vector); void i40e_irq_dynamic_disable(struct i40e_vsi *vsi, int vector);
void i40e_irq_dynamic_disable_icr0(struct i40e_pf *pf); void i40e_irq_dynamic_disable_icr0(struct i40e_pf *pf);
void i40e_irq_dynamic_enable_icr0(struct i40e_pf *pf); void i40e_irq_dynamic_enable_icr0(struct i40e_pf *pf);
#ifdef I40E_FCOE
struct rtnl_link_stats64 *i40e_get_netdev_stats_struct(
struct net_device *netdev,
struct rtnl_link_stats64 *storage);
int i40e_set_mac(struct net_device *netdev, void *p);
void i40e_set_rx_mode(struct net_device *netdev);
#endif
int i40e_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd); int i40e_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd);
#ifdef I40E_FCOE
void i40e_tx_timeout(struct net_device *netdev);
int i40e_vlan_rx_add_vid(struct net_device *netdev,
__always_unused __be16 proto, u16 vid);
int i40e_vlan_rx_kill_vid(struct net_device *netdev,
__always_unused __be16 proto, u16 vid);
#endif
int i40e_vsi_open(struct i40e_vsi *vsi); int i40e_vsi_open(struct i40e_vsi *vsi);
void i40e_vlan_stripping_disable(struct i40e_vsi *vsi); void i40e_vlan_stripping_disable(struct i40e_vsi *vsi);
int i40e_vsi_add_vlan(struct i40e_vsi *vsi, s16 vid); int i40e_vsi_add_vlan(struct i40e_vsi *vsi, s16 vid);
...@@ -634,6 +676,26 @@ struct i40e_mac_filter *i40e_put_mac_in_vlan(struct i40e_vsi *vsi, u8 *macaddr, ...@@ -634,6 +676,26 @@ struct i40e_mac_filter *i40e_put_mac_in_vlan(struct i40e_vsi *vsi, u8 *macaddr,
bool i40e_is_vsi_in_vlan(struct i40e_vsi *vsi); bool i40e_is_vsi_in_vlan(struct i40e_vsi *vsi);
struct i40e_mac_filter *i40e_find_mac(struct i40e_vsi *vsi, u8 *macaddr, struct i40e_mac_filter *i40e_find_mac(struct i40e_vsi *vsi, u8 *macaddr,
bool is_vf, bool is_netdev); bool is_vf, bool is_netdev);
#ifdef I40E_FCOE
int i40e_open(struct net_device *netdev);
int i40e_close(struct net_device *netdev);
int i40e_setup_tc(struct net_device *netdev, u8 tc);
void i40e_netpoll(struct net_device *netdev);
int i40e_fcoe_enable(struct net_device *netdev);
int i40e_fcoe_disable(struct net_device *netdev);
int i40e_fcoe_vsi_init(struct i40e_vsi *vsi, struct i40e_vsi_context *ctxt);
u8 i40e_get_fcoe_tc_map(struct i40e_pf *pf);
void i40e_fcoe_config_netdev(struct net_device *netdev, struct i40e_vsi *vsi);
void i40e_fcoe_vsi_setup(struct i40e_pf *pf);
int i40e_init_pf_fcoe(struct i40e_pf *pf);
int i40e_fcoe_setup_ddp_resources(struct i40e_vsi *vsi);
void i40e_fcoe_free_ddp_resources(struct i40e_vsi *vsi);
int i40e_fcoe_handle_offload(struct i40e_ring *rx_ring,
union i40e_rx_desc *rx_desc,
struct sk_buff *skb);
void i40e_fcoe_handle_status(struct i40e_ring *rx_ring,
union i40e_rx_desc *rx_desc, u8 prog_id);
#endif /* I40E_FCOE */
void i40e_vlan_stripping_enable(struct i40e_vsi *vsi); void i40e_vlan_stripping_enable(struct i40e_vsi *vsi);
#ifdef CONFIG_I40E_DCB #ifdef CONFIG_I40E_DCB
void i40e_dcbnl_flush_apps(struct i40e_pf *pf, void i40e_dcbnl_flush_apps(struct i40e_pf *pf,
......
...@@ -709,6 +709,33 @@ void i40e_pre_tx_queue_cfg(struct i40e_hw *hw, u32 queue, bool enable) ...@@ -709,6 +709,33 @@ void i40e_pre_tx_queue_cfg(struct i40e_hw *hw, u32 queue, bool enable)
wr32(hw, I40E_GLLAN_TXPRE_QDIS(reg_block), reg_val); wr32(hw, I40E_GLLAN_TXPRE_QDIS(reg_block), reg_val);
} }
#ifdef I40E_FCOE
/**
* i40e_get_san_mac_addr - get SAN MAC address
* @hw: pointer to the HW structure
* @mac_addr: pointer to SAN MAC address
*
* Reads the adapter's SAN MAC address from NVM
**/
i40e_status i40e_get_san_mac_addr(struct i40e_hw *hw, u8 *mac_addr)
{
struct i40e_aqc_mac_address_read_data addrs;
i40e_status status;
u16 flags = 0;
status = i40e_aq_mac_address_read(hw, &flags, &addrs, NULL);
if (status)
return status;
if (flags & I40E_AQC_SAN_ADDR_VALID)
memcpy(mac_addr, &addrs.pf_san_mac, sizeof(addrs.pf_san_mac));
else
status = I40E_ERR_INVALID_MAC_ADDR;
return status;
}
#endif
/** /**
* i40e_get_media_type - Gets media type * i40e_get_media_type - Gets media type
......
...@@ -697,6 +697,25 @@ static void i40e_dbg_dump_vsi_seid(struct i40e_pf *pf, int seid) ...@@ -697,6 +697,25 @@ static void i40e_dbg_dump_vsi_seid(struct i40e_pf *pf, int seid)
vsi->bw_ets_limit_credits[i], vsi->bw_ets_limit_credits[i],
vsi->bw_ets_max_quanta[i]); vsi->bw_ets_max_quanta[i]);
} }
#ifdef I40E_FCOE
if (vsi->type == I40E_VSI_FCOE) {
dev_info(&pf->pdev->dev,
" fcoe_stats: rx_packets = %llu, rx_dwords = %llu, rx_dropped = %llu\n",
vsi->fcoe_stats.rx_fcoe_packets,
vsi->fcoe_stats.rx_fcoe_dwords,
vsi->fcoe_stats.rx_fcoe_dropped);
dev_info(&pf->pdev->dev,
" fcoe_stats: tx_packets = %llu, tx_dwords = %llu\n",
vsi->fcoe_stats.tx_fcoe_packets,
vsi->fcoe_stats.tx_fcoe_dwords);
dev_info(&pf->pdev->dev,
" fcoe_stats: bad_crc = %llu, last_error = %llu\n",
vsi->fcoe_stats.fcoe_bad_fccrc,
vsi->fcoe_stats.fcoe_last_error);
dev_info(&pf->pdev->dev, " fcoe_stats: ddp_count = %llu\n",
vsi->fcoe_stats.fcoe_ddp_count);
}
#endif
} }
/** /**
......
...@@ -155,6 +155,19 @@ static struct i40e_stats i40e_gstrings_stats[] = { ...@@ -155,6 +155,19 @@ static struct i40e_stats i40e_gstrings_stats[] = {
I40E_PF_STAT("rx_lpi_count", stats.rx_lpi_count), I40E_PF_STAT("rx_lpi_count", stats.rx_lpi_count),
}; };
#ifdef I40E_FCOE
static const struct i40e_stats i40e_gstrings_fcoe_stats[] = {
I40E_VSI_STAT("fcoe_bad_fccrc", fcoe_stats.fcoe_bad_fccrc),
I40E_VSI_STAT("rx_fcoe_dropped", fcoe_stats.rx_fcoe_dropped),
I40E_VSI_STAT("rx_fcoe_packets", fcoe_stats.rx_fcoe_packets),
I40E_VSI_STAT("rx_fcoe_dwords", fcoe_stats.rx_fcoe_dwords),
I40E_VSI_STAT("fcoe_ddp_count", fcoe_stats.fcoe_ddp_count),
I40E_VSI_STAT("fcoe_last_error", fcoe_stats.fcoe_last_error),
I40E_VSI_STAT("tx_fcoe_packets", fcoe_stats.tx_fcoe_packets),
I40E_VSI_STAT("tx_fcoe_dwords", fcoe_stats.tx_fcoe_dwords),
};
#endif /* I40E_FCOE */
#define I40E_QUEUE_STATS_LEN(n) \ #define I40E_QUEUE_STATS_LEN(n) \
(((struct i40e_netdev_priv *)netdev_priv((n)))->vsi->num_queue_pairs \ (((struct i40e_netdev_priv *)netdev_priv((n)))->vsi->num_queue_pairs \
* 2 /* Tx and Rx together */ \ * 2 /* Tx and Rx together */ \
...@@ -162,9 +175,17 @@ static struct i40e_stats i40e_gstrings_stats[] = { ...@@ -162,9 +175,17 @@ static struct i40e_stats i40e_gstrings_stats[] = {
#define I40E_GLOBAL_STATS_LEN ARRAY_SIZE(i40e_gstrings_stats) #define I40E_GLOBAL_STATS_LEN ARRAY_SIZE(i40e_gstrings_stats)
#define I40E_NETDEV_STATS_LEN ARRAY_SIZE(i40e_gstrings_net_stats) #define I40E_NETDEV_STATS_LEN ARRAY_SIZE(i40e_gstrings_net_stats)
#define I40E_MISC_STATS_LEN ARRAY_SIZE(i40e_gstrings_misc_stats) #define I40E_MISC_STATS_LEN ARRAY_SIZE(i40e_gstrings_misc_stats)
#ifdef I40E_FCOE
#define I40E_FCOE_STATS_LEN ARRAY_SIZE(i40e_gstrings_fcoe_stats)
#define I40E_VSI_STATS_LEN(n) (I40E_NETDEV_STATS_LEN + \
I40E_FCOE_STATS_LEN + \
I40E_MISC_STATS_LEN + \
I40E_QUEUE_STATS_LEN((n)))
#else
#define I40E_VSI_STATS_LEN(n) (I40E_NETDEV_STATS_LEN + \ #define I40E_VSI_STATS_LEN(n) (I40E_NETDEV_STATS_LEN + \
I40E_MISC_STATS_LEN + \ I40E_MISC_STATS_LEN + \
I40E_QUEUE_STATS_LEN((n))) I40E_QUEUE_STATS_LEN((n)))
#endif /* I40E_FCOE */
#define I40E_PFC_STATS_LEN ( \ #define I40E_PFC_STATS_LEN ( \
(FIELD_SIZEOF(struct i40e_pf, stats.priority_xoff_rx) + \ (FIELD_SIZEOF(struct i40e_pf, stats.priority_xoff_rx) + \
FIELD_SIZEOF(struct i40e_pf, stats.priority_xon_rx) + \ FIELD_SIZEOF(struct i40e_pf, stats.priority_xon_rx) + \
...@@ -1112,6 +1133,13 @@ static void i40e_get_ethtool_stats(struct net_device *netdev, ...@@ -1112,6 +1133,13 @@ static void i40e_get_ethtool_stats(struct net_device *netdev,
data[i++] = (i40e_gstrings_misc_stats[j].sizeof_stat == data[i++] = (i40e_gstrings_misc_stats[j].sizeof_stat ==
sizeof(u64)) ? *(u64 *)p : *(u32 *)p; sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
} }
#ifdef I40E_FCOE
for (j = 0; j < I40E_FCOE_STATS_LEN; j++) {
p = (char *)vsi + i40e_gstrings_fcoe_stats[j].stat_offset;
data[i++] = (i40e_gstrings_fcoe_stats[j].sizeof_stat ==
sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
}
#endif
rcu_read_lock(); rcu_read_lock();
for (j = 0; j < vsi->num_queue_pairs; j++) { for (j = 0; j < vsi->num_queue_pairs; j++) {
tx_ring = ACCESS_ONCE(vsi->tx_rings[j]); tx_ring = ACCESS_ONCE(vsi->tx_rings[j]);
...@@ -1193,6 +1221,13 @@ static void i40e_get_strings(struct net_device *netdev, u32 stringset, ...@@ -1193,6 +1221,13 @@ static void i40e_get_strings(struct net_device *netdev, u32 stringset,
i40e_gstrings_misc_stats[i].stat_string); i40e_gstrings_misc_stats[i].stat_string);
p += ETH_GSTRING_LEN; p += ETH_GSTRING_LEN;
} }
#ifdef I40E_FCOE
for (i = 0; i < I40E_FCOE_STATS_LEN; i++) {
snprintf(p, ETH_GSTRING_LEN, "%s",
i40e_gstrings_fcoe_stats[i].stat_string);
p += ETH_GSTRING_LEN;
}
#endif
for (i = 0; i < vsi->num_queue_pairs; i++) { for (i = 0; i < vsi->num_queue_pairs; i++) {
snprintf(p, ETH_GSTRING_LEN, "tx-%u.tx_packets", i); snprintf(p, ETH_GSTRING_LEN, "tx-%u.tx_packets", i);
p += ETH_GSTRING_LEN; p += ETH_GSTRING_LEN;
......
...@@ -1363,8 +1363,6 @@ static netdev_tx_t i40e_fcoe_xmit_frame(struct sk_buff *skb, ...@@ -1363,8 +1363,6 @@ static netdev_tx_t i40e_fcoe_xmit_frame(struct sk_buff *skb,
struct i40e_vsi *vsi = np->vsi; struct i40e_vsi *vsi = np->vsi;
struct i40e_ring *tx_ring = vsi->tx_rings[skb->queue_mapping]; struct i40e_ring *tx_ring = vsi->tx_rings[skb->queue_mapping];
struct i40e_tx_buffer *first; struct i40e_tx_buffer *first;
__be16 protocol = skb->protocol;
u32 tx_flags = 0; u32 tx_flags = 0;
u8 hdr_len = 0; u8 hdr_len = 0;
u8 sof = 0; u8 sof = 0;
...@@ -1384,13 +1382,8 @@ static netdev_tx_t i40e_fcoe_xmit_frame(struct sk_buff *skb, ...@@ -1384,13 +1382,8 @@ static netdev_tx_t i40e_fcoe_xmit_frame(struct sk_buff *skb,
/* record the location of the first descriptor for this packet */ /* record the location of the first descriptor for this packet */
first = &tx_ring->tx_bi[tx_ring->next_to_use]; first = &tx_ring->tx_bi[tx_ring->next_to_use];
if (protocol == htons(ETH_P_8021Q)) {
struct vlan_ethhdr *veth = (struct vlan_ethhdr *)eth_hdr(skb);
protocol = veth->h_vlan_encapsulated_proto;
}
/* FIP is a regular L2 traffic w/o offload */ /* FIP is a regular L2 traffic w/o offload */
if (protocol == htons(ETH_P_FIP)) if (skb->protocol == htons(ETH_P_FIP))
goto out_send; goto out_send;
/* check sof and eof, only supports FC Class 2 or 3 */ /* check sof and eof, only supports FC Class 2 or 3 */
......
This diff is collapsed.
...@@ -78,4 +78,7 @@ do { \ ...@@ -78,4 +78,7 @@ do { \
} while (0) } while (0)
typedef enum i40e_status_code i40e_status; typedef enum i40e_status_code i40e_status;
#if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE)
#define I40E_FCOE
#endif /* CONFIG_FCOE or CONFIG_FCOE_MODULE */
#endif /* _I40E_OSDEP_H_ */ #endif /* _I40E_OSDEP_H_ */
...@@ -237,6 +237,9 @@ i40e_status i40e_get_mac_addr(struct i40e_hw *hw, u8 *mac_addr); ...@@ -237,6 +237,9 @@ i40e_status i40e_get_mac_addr(struct i40e_hw *hw, u8 *mac_addr);
i40e_status i40e_get_port_mac_addr(struct i40e_hw *hw, u8 *mac_addr); i40e_status i40e_get_port_mac_addr(struct i40e_hw *hw, u8 *mac_addr);
i40e_status i40e_validate_mac_addr(u8 *mac_addr); i40e_status i40e_validate_mac_addr(u8 *mac_addr);
void i40e_pre_tx_queue_cfg(struct i40e_hw *hw, u32 queue, bool enable); void i40e_pre_tx_queue_cfg(struct i40e_hw *hw, u32 queue, bool enable);
#ifdef I40E_FCOE
i40e_status i40e_get_san_mac_addr(struct i40e_hw *hw, u8 *mac_addr);
#endif
/* prototype for functions used for NVM access */ /* prototype for functions used for NVM access */
i40e_status i40e_init_nvm(struct i40e_hw *hw); i40e_status i40e_init_nvm(struct i40e_hw *hw);
i40e_status i40e_acquire_nvm(struct i40e_hw *hw, i40e_status i40e_acquire_nvm(struct i40e_hw *hw,
......
...@@ -896,6 +896,11 @@ static void i40e_clean_programming_status(struct i40e_ring *rx_ring, ...@@ -896,6 +896,11 @@ static void i40e_clean_programming_status(struct i40e_ring *rx_ring,
if (id == I40E_RX_PROG_STATUS_DESC_FD_FILTER_STATUS) if (id == I40E_RX_PROG_STATUS_DESC_FD_FILTER_STATUS)
i40e_fd_handle_status(rx_ring, rx_desc, id); i40e_fd_handle_status(rx_ring, rx_desc, id);
#ifdef I40E_FCOE
else if ((id == I40E_RX_PROG_STATUS_DESC_FCOE_CTXT_PROG_STATUS) ||
(id == I40E_RX_PROG_STATUS_DESC_FCOE_CTXT_INVL_STATUS))
i40e_fcoe_handle_status(rx_ring, rx_desc, id);
#endif
} }
/** /**
...@@ -1489,6 +1494,12 @@ static int i40e_clean_rx_irq(struct i40e_ring *rx_ring, int budget) ...@@ -1489,6 +1494,12 @@ static int i40e_clean_rx_irq(struct i40e_ring *rx_ring, int budget)
vlan_tag = rx_status & (1 << I40E_RX_DESC_STATUS_L2TAG1P_SHIFT) vlan_tag = rx_status & (1 << I40E_RX_DESC_STATUS_L2TAG1P_SHIFT)
? le16_to_cpu(rx_desc->wb.qword0.lo_dword.l2tag1) ? le16_to_cpu(rx_desc->wb.qword0.lo_dword.l2tag1)
: 0; : 0;
#ifdef I40E_FCOE
if (!i40e_fcoe_handle_offload(rx_ring, rx_desc, skb)) {
dev_kfree_skb_any(skb);
goto next_desc;
}
#endif
i40e_receive_skb(rx_ring, skb, vlan_tag); i40e_receive_skb(rx_ring, skb, vlan_tag);
rx_ring->netdev->last_rx = jiffies; rx_ring->netdev->last_rx = jiffies;
...@@ -1719,9 +1730,15 @@ static void i40e_atr(struct i40e_ring *tx_ring, struct sk_buff *skb, ...@@ -1719,9 +1730,15 @@ static void i40e_atr(struct i40e_ring *tx_ring, struct sk_buff *skb,
* Returns error code indicate the frame should be dropped upon error and the * Returns error code indicate the frame should be dropped upon error and the
* otherwise returns 0 to indicate the flags has been set properly. * otherwise returns 0 to indicate the flags has been set properly.
**/ **/
#ifdef I40E_FCOE
int i40e_tx_prepare_vlan_flags(struct sk_buff *skb,
struct i40e_ring *tx_ring,
u32 *flags)
#else
static int i40e_tx_prepare_vlan_flags(struct sk_buff *skb, static int i40e_tx_prepare_vlan_flags(struct sk_buff *skb,
struct i40e_ring *tx_ring, struct i40e_ring *tx_ring,
u32 *flags) u32 *flags)
#endif
{ {
__be16 protocol = skb->protocol; __be16 protocol = skb->protocol;
u32 tx_flags = 0; u32 tx_flags = 0;
...@@ -1743,9 +1760,8 @@ static int i40e_tx_prepare_vlan_flags(struct sk_buff *skb, ...@@ -1743,9 +1760,8 @@ static int i40e_tx_prepare_vlan_flags(struct sk_buff *skb,
} }
/* Insert 802.1p priority into VLAN header */ /* Insert 802.1p priority into VLAN header */
if ((tx_ring->vsi->back->flags & I40E_FLAG_DCB_ENABLED) && if ((tx_flags & (I40E_TX_FLAGS_HW_VLAN | I40E_TX_FLAGS_SW_VLAN)) ||
((tx_flags & (I40E_TX_FLAGS_HW_VLAN | I40E_TX_FLAGS_SW_VLAN)) || (skb->priority != TC_PRIO_CONTROL)) {
(skb->priority != TC_PRIO_CONTROL))) {
tx_flags &= ~I40E_TX_FLAGS_VLAN_PRIO_MASK; tx_flags &= ~I40E_TX_FLAGS_VLAN_PRIO_MASK;
tx_flags |= (skb->priority & 0x7) << tx_flags |= (skb->priority & 0x7) <<
I40E_TX_FLAGS_VLAN_PRIO_SHIFT; I40E_TX_FLAGS_VLAN_PRIO_SHIFT;
...@@ -2018,9 +2034,15 @@ static void i40e_create_tx_ctx(struct i40e_ring *tx_ring, ...@@ -2018,9 +2034,15 @@ static void i40e_create_tx_ctx(struct i40e_ring *tx_ring,
* @td_cmd: the command field in the descriptor * @td_cmd: the command field in the descriptor
* @td_offset: offset for checksum or crc * @td_offset: offset for checksum or crc
**/ **/
#ifdef I40E_FCOE
void i40e_tx_map(struct i40e_ring *tx_ring, struct sk_buff *skb,
struct i40e_tx_buffer *first, u32 tx_flags,
const u8 hdr_len, u32 td_cmd, u32 td_offset)
#else
static void i40e_tx_map(struct i40e_ring *tx_ring, struct sk_buff *skb, static void i40e_tx_map(struct i40e_ring *tx_ring, struct sk_buff *skb,
struct i40e_tx_buffer *first, u32 tx_flags, struct i40e_tx_buffer *first, u32 tx_flags,
const u8 hdr_len, u32 td_cmd, u32 td_offset) const u8 hdr_len, u32 td_cmd, u32 td_offset)
#endif
{ {
unsigned int data_len = skb->data_len; unsigned int data_len = skb->data_len;
unsigned int size = skb_headlen(skb); unsigned int size = skb_headlen(skb);
...@@ -2197,7 +2219,11 @@ static inline int __i40e_maybe_stop_tx(struct i40e_ring *tx_ring, int size) ...@@ -2197,7 +2219,11 @@ static inline int __i40e_maybe_stop_tx(struct i40e_ring *tx_ring, int size)
* *
* Returns 0 if stop is not needed * Returns 0 if stop is not needed
**/ **/
#ifdef I40E_FCOE
int i40e_maybe_stop_tx(struct i40e_ring *tx_ring, int size)
#else
static int i40e_maybe_stop_tx(struct i40e_ring *tx_ring, int size) static int i40e_maybe_stop_tx(struct i40e_ring *tx_ring, int size)
#endif
{ {
if (likely(I40E_DESC_UNUSED(tx_ring) >= size)) if (likely(I40E_DESC_UNUSED(tx_ring) >= size))
return 0; return 0;
...@@ -2213,8 +2239,13 @@ static int i40e_maybe_stop_tx(struct i40e_ring *tx_ring, int size) ...@@ -2213,8 +2239,13 @@ static int i40e_maybe_stop_tx(struct i40e_ring *tx_ring, int size)
* there is not enough descriptors available in this ring since we need at least * there is not enough descriptors available in this ring since we need at least
* one descriptor. * one descriptor.
**/ **/
#ifdef I40E_FCOE
int i40e_xmit_descriptor_count(struct sk_buff *skb,
struct i40e_ring *tx_ring)
#else
static int i40e_xmit_descriptor_count(struct sk_buff *skb, static int i40e_xmit_descriptor_count(struct sk_buff *skb,
struct i40e_ring *tx_ring) struct i40e_ring *tx_ring)
#endif
{ {
unsigned int f; unsigned int f;
int count = 0; int count = 0;
......
...@@ -290,4 +290,13 @@ int i40e_setup_rx_descriptors(struct i40e_ring *rx_ring); ...@@ -290,4 +290,13 @@ int i40e_setup_rx_descriptors(struct i40e_ring *rx_ring);
void i40e_free_tx_resources(struct i40e_ring *tx_ring); void i40e_free_tx_resources(struct i40e_ring *tx_ring);
void i40e_free_rx_resources(struct i40e_ring *rx_ring); void i40e_free_rx_resources(struct i40e_ring *rx_ring);
int i40e_napi_poll(struct napi_struct *napi, int budget); int i40e_napi_poll(struct napi_struct *napi, int budget);
#ifdef I40E_FCOE
void i40e_tx_map(struct i40e_ring *tx_ring, struct sk_buff *skb,
struct i40e_tx_buffer *first, u32 tx_flags,
const u8 hdr_len, u32 td_cmd, u32 td_offset);
int i40e_maybe_stop_tx(struct i40e_ring *tx_ring, int size);
int i40e_xmit_descriptor_count(struct sk_buff *skb, struct i40e_ring *tx_ring);
int i40e_tx_prepare_vlan_flags(struct sk_buff *skb,
struct i40e_ring *tx_ring, u32 *flags);
#endif
#endif /* _I40E_TXRX_H_ */ #endif /* _I40E_TXRX_H_ */
...@@ -1051,6 +1051,25 @@ struct i40e_eth_stats { ...@@ -1051,6 +1051,25 @@ struct i40e_eth_stats {
u64 tx_errors; /* tepc */ u64 tx_errors; /* tepc */
}; };
#ifdef I40E_FCOE
/* Statistics collected per function for FCoE */
struct i40e_fcoe_stats {
u64 rx_fcoe_packets; /* fcoeprc */
u64 rx_fcoe_dwords; /* focedwrc */
u64 rx_fcoe_dropped; /* fcoerpdc */
u64 tx_fcoe_packets; /* fcoeptc */
u64 tx_fcoe_dwords; /* focedwtc */
u64 fcoe_bad_fccrc; /* fcoecrc */
u64 fcoe_last_error; /* fcoelast */
u64 fcoe_ddp_count; /* fcoeddpc */
};
/* offset to per function FCoE statistics block */
#define I40E_FCOE_VF_STAT_OFFSET 0
#define I40E_FCOE_PF_STAT_OFFSET 128
#define I40E_FCOE_STAT_MAX (I40E_FCOE_PF_STAT_OFFSET + I40E_MAX_PF)
#endif
/* Statistics collected by the MAC */ /* Statistics collected by the MAC */
struct i40e_hw_port_stats { struct i40e_hw_port_stats {
/* eth stats collected by the port */ /* eth stats collected by the port */
...@@ -1131,6 +1150,125 @@ struct i40e_hw_port_stats { ...@@ -1131,6 +1150,125 @@ struct i40e_hw_port_stats {
#define I40E_SRRD_SRCTL_ATTEMPTS 100000 #define I40E_SRRD_SRCTL_ATTEMPTS 100000
#ifdef I40E_FCOE
/* FCoE Tx context descriptor - Use the i40e_tx_context_desc struct */
enum i40E_fcoe_tx_ctx_desc_cmd_bits {
I40E_FCOE_TX_CTX_DESC_OPCODE_SINGLE_SEND = 0x00, /* 4 BITS */
I40E_FCOE_TX_CTX_DESC_OPCODE_TSO_FC_CLASS2 = 0x01, /* 4 BITS */
I40E_FCOE_TX_CTX_DESC_OPCODE_TSO_FC_CLASS3 = 0x05, /* 4 BITS */
I40E_FCOE_TX_CTX_DESC_OPCODE_ETSO_FC_CLASS2 = 0x02, /* 4 BITS */
I40E_FCOE_TX_CTX_DESC_OPCODE_ETSO_FC_CLASS3 = 0x06, /* 4 BITS */
I40E_FCOE_TX_CTX_DESC_OPCODE_DWO_FC_CLASS2 = 0x03, /* 4 BITS */
I40E_FCOE_TX_CTX_DESC_OPCODE_DWO_FC_CLASS3 = 0x07, /* 4 BITS */
I40E_FCOE_TX_CTX_DESC_OPCODE_DDP_CTX_INVL = 0x08, /* 4 BITS */
I40E_FCOE_TX_CTX_DESC_OPCODE_DWO_CTX_INVL = 0x09, /* 4 BITS */
I40E_FCOE_TX_CTX_DESC_RELOFF = 0x10,
I40E_FCOE_TX_CTX_DESC_CLRSEQ = 0x20,
I40E_FCOE_TX_CTX_DESC_DIFENA = 0x40,
I40E_FCOE_TX_CTX_DESC_IL2TAG2 = 0x80
};
/* FCoE DDP Context descriptor */
struct i40e_fcoe_ddp_context_desc {
__le64 rsvd;
__le64 type_cmd_foff_lsize;
};
#define I40E_FCOE_DDP_CTX_QW1_DTYPE_SHIFT 0
#define I40E_FCOE_DDP_CTX_QW1_DTYPE_MASK (0xFULL << \
I40E_FCOE_DDP_CTX_QW1_DTYPE_SHIFT)
#define I40E_FCOE_DDP_CTX_QW1_CMD_SHIFT 4
#define I40E_FCOE_DDP_CTX_QW1_CMD_MASK (0xFULL << \
I40E_FCOE_DDP_CTX_QW1_CMD_SHIFT)
enum i40e_fcoe_ddp_ctx_desc_cmd_bits {
I40E_FCOE_DDP_CTX_DESC_BSIZE_512B = 0x00, /* 2 BITS */
I40E_FCOE_DDP_CTX_DESC_BSIZE_4K = 0x01, /* 2 BITS */
I40E_FCOE_DDP_CTX_DESC_BSIZE_8K = 0x02, /* 2 BITS */
I40E_FCOE_DDP_CTX_DESC_BSIZE_16K = 0x03, /* 2 BITS */
I40E_FCOE_DDP_CTX_DESC_DIFENA = 0x04, /* 1 BIT */
I40E_FCOE_DDP_CTX_DESC_LASTSEQH = 0x08, /* 1 BIT */
};
#define I40E_FCOE_DDP_CTX_QW1_FOFF_SHIFT 16
#define I40E_FCOE_DDP_CTX_QW1_FOFF_MASK (0x3FFFULL << \
I40E_FCOE_DDP_CTX_QW1_FOFF_SHIFT)
#define I40E_FCOE_DDP_CTX_QW1_LSIZE_SHIFT 32
#define I40E_FCOE_DDP_CTX_QW1_LSIZE_MASK (0x3FFFULL << \
I40E_FCOE_DDP_CTX_QW1_LSIZE_SHIFT)
/* FCoE DDP/DWO Queue Context descriptor */
struct i40e_fcoe_queue_context_desc {
__le64 dmaindx_fbase; /* 0:11 DMAINDX, 12:63 FBASE */
__le64 flen_tph; /* 0:12 FLEN, 13:15 TPH */
};
#define I40E_FCOE_QUEUE_CTX_QW0_DMAINDX_SHIFT 0
#define I40E_FCOE_QUEUE_CTX_QW0_DMAINDX_MASK (0xFFFULL << \
I40E_FCOE_QUEUE_CTX_QW0_DMAINDX_SHIFT)
#define I40E_FCOE_QUEUE_CTX_QW0_FBASE_SHIFT 12
#define I40E_FCOE_QUEUE_CTX_QW0_FBASE_MASK (0xFFFFFFFFFFFFFULL << \
I40E_FCOE_QUEUE_CTX_QW0_FBASE_SHIFT)
#define I40E_FCOE_QUEUE_CTX_QW1_FLEN_SHIFT 0
#define I40E_FCOE_QUEUE_CTX_QW1_FLEN_MASK (0x1FFFULL << \
I40E_FCOE_QUEUE_CTX_QW1_FLEN_SHIFT)
#define I40E_FCOE_QUEUE_CTX_QW1_TPH_SHIFT 13
#define I40E_FCOE_QUEUE_CTX_QW1_TPH_MASK (0x7ULL << \
I40E_FCOE_QUEUE_CTX_QW1_FLEN_SHIFT)
enum i40e_fcoe_queue_ctx_desc_tph_bits {
I40E_FCOE_QUEUE_CTX_DESC_TPHRDESC = 0x1,
I40E_FCOE_QUEUE_CTX_DESC_TPHDATA = 0x2
};
#define I40E_FCOE_QUEUE_CTX_QW1_RECIPE_SHIFT 30
#define I40E_FCOE_QUEUE_CTX_QW1_RECIPE_MASK (0x3ULL << \
I40E_FCOE_QUEUE_CTX_QW1_RECIPE_SHIFT)
/* FCoE DDP/DWO Filter Context descriptor */
struct i40e_fcoe_filter_context_desc {
__le32 param;
__le16 seqn;
/* 48:51(0:3) RSVD, 52:63(4:15) DMAINDX */
__le16 rsvd_dmaindx;
/* 0:7 FLAGS, 8:52 RSVD, 53:63 LANQ */
__le64 flags_rsvd_lanq;
};
#define I40E_FCOE_FILTER_CTX_QW0_DMAINDX_SHIFT 4
#define I40E_FCOE_FILTER_CTX_QW0_DMAINDX_MASK (0xFFF << \
I40E_FCOE_FILTER_CTX_QW0_DMAINDX_SHIFT)
enum i40e_fcoe_filter_ctx_desc_flags_bits {
I40E_FCOE_FILTER_CTX_DESC_CTYP_DDP = 0x00,
I40E_FCOE_FILTER_CTX_DESC_CTYP_DWO = 0x01,
I40E_FCOE_FILTER_CTX_DESC_ENODE_INIT = 0x00,
I40E_FCOE_FILTER_CTX_DESC_ENODE_RSP = 0x02,
I40E_FCOE_FILTER_CTX_DESC_FC_CLASS2 = 0x00,
I40E_FCOE_FILTER_CTX_DESC_FC_CLASS3 = 0x04
};
#define I40E_FCOE_FILTER_CTX_QW1_FLAGS_SHIFT 0
#define I40E_FCOE_FILTER_CTX_QW1_FLAGS_MASK (0xFFULL << \
I40E_FCOE_FILTER_CTX_QW1_FLAGS_SHIFT)
#define I40E_FCOE_FILTER_CTX_QW1_PCTYPE_SHIFT 8
#define I40E_FCOE_FILTER_CTX_QW1_PCTYPE_MASK (0x3FULL << \
I40E_FCOE_FILTER_CTX_QW1_PCTYPE_SHIFT)
#define I40E_FCOE_FILTER_CTX_QW1_LANQINDX_SHIFT 53
#define I40E_FCOE_FILTER_CTX_QW1_LANQINDX_MASK (0x7FFULL << \
I40E_FCOE_FILTER_CTX_QW1_LANQINDX_SHIFT)
#endif /* I40E_FCOE */
enum i40e_switch_element_types { enum i40e_switch_element_types {
I40E_SWITCH_ELEMENT_TYPE_MAC = 1, I40E_SWITCH_ELEMENT_TYPE_MAC = 1,
I40E_SWITCH_ELEMENT_TYPE_PF = 2, I40E_SWITCH_ELEMENT_TYPE_PF = 2,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment