Commit b6fd8b7f authored by David S. Miller's avatar David S. Miller

Merge branch 'bnx2x-next'

Yuval Mintz says:

====================
bnx2x: Enhancement patch series

This patch series introduces the ability to propagate link parameters
to VFs as well as control the VF link via hypervisor.

In addition, it contains 2 small improvements [one IOV-related and the
other improves performance on machines with short cache lines].

Please consider applying these patches to `net-next'.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents edd79ca8 ebf457f9
...@@ -1482,6 +1482,7 @@ struct bnx2x { ...@@ -1482,6 +1482,7 @@ struct bnx2x {
union pf_vf_bulletin *pf2vf_bulletin; union pf_vf_bulletin *pf2vf_bulletin;
dma_addr_t pf2vf_bulletin_mapping; dma_addr_t pf2vf_bulletin_mapping;
union pf_vf_bulletin shadow_bulletin;
struct pf_vf_bulletin_content old_bulletin; struct pf_vf_bulletin_content old_bulletin;
u16 requested_nr_virtfn; u16 requested_nr_virtfn;
...@@ -1507,8 +1508,10 @@ struct bnx2x { ...@@ -1507,8 +1508,10 @@ struct bnx2x {
/* TCP with Timestamp Option (32) + IPv6 (40) */ /* TCP with Timestamp Option (32) + IPv6 (40) */
#define ETH_MAX_TPA_HEADER_SIZE 72 #define ETH_MAX_TPA_HEADER_SIZE 72
/* Max supported alignment is 256 (8 shift) */ /* Max supported alignment is 256 (8 shift)
#define BNX2X_RX_ALIGN_SHIFT min(8, L1_CACHE_SHIFT) * minimal alignment shift 6 is optimal for 57xxx HW performance
*/
#define BNX2X_RX_ALIGN_SHIFT max(6, min(8, L1_CACHE_SHIFT))
/* FW uses 2 Cache lines Alignment for start packet and size /* FW uses 2 Cache lines Alignment for start packet and size
* *
...@@ -1928,6 +1931,8 @@ struct bnx2x { ...@@ -1928,6 +1931,8 @@ struct bnx2x {
struct semaphore stats_sema; struct semaphore stats_sema;
u8 phys_port_id[ETH_ALEN]; u8 phys_port_id[ETH_ALEN];
struct bnx2x_link_report_data vf_link_vars;
}; };
/* Tx queues may be less or equal to Rx queues */ /* Tx queues may be less or equal to Rx queues */
......
...@@ -1185,29 +1185,38 @@ u16 bnx2x_get_mf_speed(struct bnx2x *bp) ...@@ -1185,29 +1185,38 @@ u16 bnx2x_get_mf_speed(struct bnx2x *bp)
static void bnx2x_fill_report_data(struct bnx2x *bp, static void bnx2x_fill_report_data(struct bnx2x *bp,
struct bnx2x_link_report_data *data) struct bnx2x_link_report_data *data)
{ {
u16 line_speed = bnx2x_get_mf_speed(bp);
memset(data, 0, sizeof(*data)); memset(data, 0, sizeof(*data));
/* Fill the report data: effective line speed */ if (IS_PF(bp)) {
data->line_speed = line_speed; /* Fill the report data: effective line speed */
data->line_speed = bnx2x_get_mf_speed(bp);
/* Link is down */
if (!bp->link_vars.link_up || (bp->flags & MF_FUNC_DIS)) /* Link is down */
__set_bit(BNX2X_LINK_REPORT_LINK_DOWN, if (!bp->link_vars.link_up || (bp->flags & MF_FUNC_DIS))
&data->link_report_flags); __set_bit(BNX2X_LINK_REPORT_LINK_DOWN,
&data->link_report_flags);
/* Full DUPLEX */
if (bp->link_vars.duplex == DUPLEX_FULL) if (!BNX2X_NUM_ETH_QUEUES(bp))
__set_bit(BNX2X_LINK_REPORT_FD, &data->link_report_flags); __set_bit(BNX2X_LINK_REPORT_LINK_DOWN,
&data->link_report_flags);
/* Rx Flow Control is ON */
if (bp->link_vars.flow_ctrl & BNX2X_FLOW_CTRL_RX) /* Full DUPLEX */
__set_bit(BNX2X_LINK_REPORT_RX_FC_ON, &data->link_report_flags); if (bp->link_vars.duplex == DUPLEX_FULL)
__set_bit(BNX2X_LINK_REPORT_FD,
/* Tx Flow Control is ON */ &data->link_report_flags);
if (bp->link_vars.flow_ctrl & BNX2X_FLOW_CTRL_TX)
__set_bit(BNX2X_LINK_REPORT_TX_FC_ON, &data->link_report_flags); /* Rx Flow Control is ON */
if (bp->link_vars.flow_ctrl & BNX2X_FLOW_CTRL_RX)
__set_bit(BNX2X_LINK_REPORT_RX_FC_ON,
&data->link_report_flags);
/* Tx Flow Control is ON */
if (bp->link_vars.flow_ctrl & BNX2X_FLOW_CTRL_TX)
__set_bit(BNX2X_LINK_REPORT_TX_FC_ON,
&data->link_report_flags);
} else { /* VF */
*data = bp->vf_link_vars;
}
} }
/** /**
...@@ -1261,6 +1270,10 @@ void __bnx2x_link_report(struct bnx2x *bp) ...@@ -1261,6 +1270,10 @@ void __bnx2x_link_report(struct bnx2x *bp)
*/ */
memcpy(&bp->last_reported_link, &cur_data, sizeof(cur_data)); memcpy(&bp->last_reported_link, &cur_data, sizeof(cur_data));
/* propagate status to VFs */
if (IS_PF(bp))
bnx2x_iov_link_update(bp);
if (test_bit(BNX2X_LINK_REPORT_LINK_DOWN, if (test_bit(BNX2X_LINK_REPORT_LINK_DOWN,
&cur_data.link_report_flags)) { &cur_data.link_report_flags)) {
netif_carrier_off(bp->dev); netif_carrier_off(bp->dev);
......
...@@ -216,6 +216,43 @@ static int bnx2x_get_port_type(struct bnx2x *bp) ...@@ -216,6 +216,43 @@ static int bnx2x_get_port_type(struct bnx2x *bp)
return port_type; return port_type;
} }
static int bnx2x_get_vf_settings(struct net_device *dev,
struct ethtool_cmd *cmd)
{
struct bnx2x *bp = netdev_priv(dev);
if (bp->state == BNX2X_STATE_OPEN) {
if (test_bit(BNX2X_LINK_REPORT_FD,
&bp->vf_link_vars.link_report_flags))
cmd->duplex = DUPLEX_FULL;
else
cmd->duplex = DUPLEX_HALF;
ethtool_cmd_speed_set(cmd, bp->vf_link_vars.line_speed);
} else {
cmd->duplex = DUPLEX_UNKNOWN;
ethtool_cmd_speed_set(cmd, SPEED_UNKNOWN);
}
cmd->port = PORT_OTHER;
cmd->phy_address = 0;
cmd->transceiver = XCVR_INTERNAL;
cmd->autoneg = AUTONEG_DISABLE;
cmd->maxtxpkt = 0;
cmd->maxrxpkt = 0;
DP(BNX2X_MSG_ETHTOOL, "ethtool_cmd: cmd %d\n"
" supported 0x%x advertising 0x%x speed %u\n"
" duplex %d port %d phy_address %d transceiver %d\n"
" autoneg %d maxtxpkt %d maxrxpkt %d\n",
cmd->cmd, cmd->supported, cmd->advertising,
ethtool_cmd_speed(cmd),
cmd->duplex, cmd->port, cmd->phy_address, cmd->transceiver,
cmd->autoneg, cmd->maxtxpkt, cmd->maxrxpkt);
return 0;
}
static int bnx2x_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) static int bnx2x_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{ {
struct bnx2x *bp = netdev_priv(dev); struct bnx2x *bp = netdev_priv(dev);
...@@ -1110,6 +1147,10 @@ static u32 bnx2x_get_link(struct net_device *dev) ...@@ -1110,6 +1147,10 @@ static u32 bnx2x_get_link(struct net_device *dev)
if (bp->flags & MF_FUNC_DIS || (bp->state != BNX2X_STATE_OPEN)) if (bp->flags & MF_FUNC_DIS || (bp->state != BNX2X_STATE_OPEN))
return 0; return 0;
if (IS_VF(bp))
return !test_bit(BNX2X_LINK_REPORT_LINK_DOWN,
&bp->vf_link_vars.link_report_flags);
return bp->link_vars.link_up; return bp->link_vars.link_up;
} }
...@@ -3484,8 +3525,7 @@ static const struct ethtool_ops bnx2x_ethtool_ops = { ...@@ -3484,8 +3525,7 @@ static const struct ethtool_ops bnx2x_ethtool_ops = {
}; };
static const struct ethtool_ops bnx2x_vf_ethtool_ops = { static const struct ethtool_ops bnx2x_vf_ethtool_ops = {
.get_settings = bnx2x_get_settings, .get_settings = bnx2x_get_vf_settings,
.set_settings = bnx2x_set_settings,
.get_drvinfo = bnx2x_get_drvinfo, .get_drvinfo = bnx2x_get_drvinfo,
.get_msglevel = bnx2x_get_msglevel, .get_msglevel = bnx2x_get_msglevel,
.set_msglevel = bnx2x_set_msglevel, .set_msglevel = bnx2x_set_msglevel,
......
...@@ -2698,6 +2698,14 @@ void bnx2x__link_status_update(struct bnx2x *bp) ...@@ -2698,6 +2698,14 @@ void bnx2x__link_status_update(struct bnx2x *bp)
bp->link_vars.duplex = DUPLEX_FULL; bp->link_vars.duplex = DUPLEX_FULL;
bp->link_vars.flow_ctrl = BNX2X_FLOW_CTRL_NONE; bp->link_vars.flow_ctrl = BNX2X_FLOW_CTRL_NONE;
__bnx2x_link_report(bp); __bnx2x_link_report(bp);
bnx2x_sample_bulletin(bp);
/* if bulletin board did not have an update for link status
* __bnx2x_link_report will report current status
* but it will NOT duplicate report in case of already reported
* during sampling bulletin board.
*/
bnx2x_stats_handle(bp, STATS_EVENT_LINK_UP); bnx2x_stats_handle(bp, STATS_EVENT_LINK_UP);
} }
} }
...@@ -12424,6 +12432,7 @@ static const struct net_device_ops bnx2x_netdev_ops = { ...@@ -12424,6 +12432,7 @@ static const struct net_device_ops bnx2x_netdev_ops = {
.ndo_busy_poll = bnx2x_low_latency_recv, .ndo_busy_poll = bnx2x_low_latency_recv,
#endif #endif
.ndo_get_phys_port_id = bnx2x_get_phys_port_id, .ndo_get_phys_port_id = bnx2x_get_phys_port_id,
.ndo_set_vf_link_state = bnx2x_set_vf_link_state,
}; };
static int bnx2x_set_coherency_mask(struct bnx2x *bp) static int bnx2x_set_coherency_mask(struct bnx2x *bp)
......
...@@ -126,7 +126,11 @@ struct bnx2x_virtf { ...@@ -126,7 +126,11 @@ struct bnx2x_virtf {
#define VF_CACHE_LINE 0x0010 #define VF_CACHE_LINE 0x0010
#define VF_CFG_VLAN 0x0020 #define VF_CFG_VLAN 0x0020
#define VF_CFG_STATS_COALESCE 0x0040 #define VF_CFG_STATS_COALESCE 0x0040
#define VF_CFG_EXT_BULLETIN 0x0080
u8 link_cfg; /* IFLA_VF_LINK_STATE_AUTO
* IFLA_VF_LINK_STATE_ENABLE
* IFLA_VF_LINK_STATE_DISABLE
*/
u8 state; u8 state;
#define VF_FREE 0 /* VF ready to be acquired holds no resc */ #define VF_FREE 0 /* VF ready to be acquired holds no resc */
#define VF_ACQUIRED 1 /* VF acquired, but not initialized */ #define VF_ACQUIRED 1 /* VF acquired, but not initialized */
...@@ -295,22 +299,22 @@ struct bnx2x_vfdb { ...@@ -295,22 +299,22 @@ struct bnx2x_vfdb {
#define BP_VFDB(bp) ((bp)->vfdb) #define BP_VFDB(bp) ((bp)->vfdb)
/* vf array */ /* vf array */
struct bnx2x_virtf *vfs; struct bnx2x_virtf *vfs;
#define BP_VF(bp, idx) (&((bp)->vfdb->vfs[(idx)])) #define BP_VF(bp, idx) (&((bp)->vfdb->vfs[idx]))
#define bnx2x_vf(bp, idx, var) ((bp)->vfdb->vfs[(idx)].var) #define bnx2x_vf(bp, idx, var) ((bp)->vfdb->vfs[idx].var)
/* queue array - for all vfs */ /* queue array - for all vfs */
struct bnx2x_vf_queue *vfqs; struct bnx2x_vf_queue *vfqs;
/* vf HW contexts */ /* vf HW contexts */
struct hw_dma context[BNX2X_VF_CIDS/ILT_PAGE_CIDS]; struct hw_dma context[BNX2X_VF_CIDS/ILT_PAGE_CIDS];
#define BP_VF_CXT_PAGE(bp, i) (&(bp)->vfdb->context[(i)]) #define BP_VF_CXT_PAGE(bp, i) (&(bp)->vfdb->context[i])
/* SR-IOV information */ /* SR-IOV information */
struct bnx2x_sriov sriov; struct bnx2x_sriov sriov;
struct hw_dma mbx_dma; struct hw_dma mbx_dma;
#define BP_VF_MBX_DMA(bp) (&((bp)->vfdb->mbx_dma)) #define BP_VF_MBX_DMA(bp) (&((bp)->vfdb->mbx_dma))
struct bnx2x_vf_mbx mbxs[BNX2X_MAX_NUM_OF_VFS]; struct bnx2x_vf_mbx mbxs[BNX2X_MAX_NUM_OF_VFS];
#define BP_VF_MBX(bp, vfid) (&((bp)->vfdb->mbxs[(vfid)])) #define BP_VF_MBX(bp, vfid) (&((bp)->vfdb->mbxs[vfid]))
struct hw_dma bulletin_dma; struct hw_dma bulletin_dma;
#define BP_VF_BULLETIN_DMA(bp) (&((bp)->vfdb->bulletin_dma)) #define BP_VF_BULLETIN_DMA(bp) (&((bp)->vfdb->bulletin_dma))
...@@ -336,6 +340,9 @@ struct bnx2x_vfdb { ...@@ -336,6 +340,9 @@ struct bnx2x_vfdb {
/* sp_rtnl synchronization */ /* sp_rtnl synchronization */
struct mutex event_mutex; struct mutex event_mutex;
u64 event_occur; u64 event_occur;
/* bulletin board update synchronization */
struct mutex bulletin_mutex;
}; };
/* queue access */ /* queue access */
...@@ -467,9 +474,10 @@ void bnx2x_vf_handle_flr_event(struct bnx2x *bp); ...@@ -467,9 +474,10 @@ void bnx2x_vf_handle_flr_event(struct bnx2x *bp);
bool bnx2x_tlv_supported(u16 tlvtype); bool bnx2x_tlv_supported(u16 tlvtype);
u32 bnx2x_crc_vf_bulletin(struct bnx2x *bp, u32 bnx2x_crc_vf_bulletin(struct pf_vf_bulletin_content *bulletin);
struct pf_vf_bulletin_content *bulletin);
int bnx2x_post_vf_bulletin(struct bnx2x *bp, int vf); int bnx2x_post_vf_bulletin(struct bnx2x *bp, int vf);
void bnx2x_vf_bulletin_finalize(struct pf_vf_bulletin_content *bulletin,
bool support_long);
enum sample_bulletin_result bnx2x_sample_bulletin(struct bnx2x *bp); enum sample_bulletin_result bnx2x_sample_bulletin(struct bnx2x *bp);
...@@ -520,6 +528,11 @@ void bnx2x_iov_task(struct work_struct *work); ...@@ -520,6 +528,11 @@ void bnx2x_iov_task(struct work_struct *work);
void bnx2x_schedule_iov_task(struct bnx2x *bp, enum bnx2x_iov_flag flag); void bnx2x_schedule_iov_task(struct bnx2x *bp, enum bnx2x_iov_flag flag);
void bnx2x_iov_link_update(struct bnx2x *bp);
int bnx2x_iov_link_update_vf(struct bnx2x *bp, int idx);
int bnx2x_set_vf_link_state(struct net_device *dev, int vf, int link_state);
#else /* CONFIG_BNX2X_SRIOV */ #else /* CONFIG_BNX2X_SRIOV */
static inline void bnx2x_iov_set_queue_sp_obj(struct bnx2x *bp, int vf_cid, static inline void bnx2x_iov_set_queue_sp_obj(struct bnx2x *bp, int vf_cid,
...@@ -579,6 +592,14 @@ static inline void bnx2x_iov_channel_down(struct bnx2x *bp) {} ...@@ -579,6 +592,14 @@ static inline void bnx2x_iov_channel_down(struct bnx2x *bp) {}
static inline void bnx2x_iov_task(struct work_struct *work) {} static inline void bnx2x_iov_task(struct work_struct *work) {}
static inline void bnx2x_schedule_iov_task(struct bnx2x *bp, enum bnx2x_iov_flag flag) {} static inline void bnx2x_schedule_iov_task(struct bnx2x *bp, enum bnx2x_iov_flag flag) {}
static inline void bnx2x_iov_link_update(struct bnx2x *bp) {}
static inline int bnx2x_iov_link_update_vf(struct bnx2x *bp, int idx) {return 0; }
static inline int bnx2x_set_vf_link_state(struct net_device *dev, int vf,
int link_state) {return 0; }
struct pf_vf_bulletin_content;
static inline void bnx2x_vf_bulletin_finalize(struct pf_vf_bulletin_content *bulletin,
bool support_long) {}
#endif /* CONFIG_BNX2X_SRIOV */ #endif /* CONFIG_BNX2X_SRIOV */
#endif /* bnx2x_sriov.h */ #endif /* bnx2x_sriov.h */
...@@ -251,6 +251,9 @@ int bnx2x_vfpf_acquire(struct bnx2x *bp, u8 tx_count, u8 rx_count) ...@@ -251,6 +251,9 @@ int bnx2x_vfpf_acquire(struct bnx2x *bp, u8 tx_count, u8 rx_count)
bnx2x_add_tlv(bp, req, req->first_tlv.tl.length, bnx2x_add_tlv(bp, req, req->first_tlv.tl.length,
CHANNEL_TLV_PHYS_PORT_ID, sizeof(struct channel_tlv)); CHANNEL_TLV_PHYS_PORT_ID, sizeof(struct channel_tlv));
/* Bulletin support for bulletin board with length > legacy length */
req->vfdev_info.caps |= VF_CAP_SUPPORT_EXT_BULLETIN;
/* add list termination tlv */ /* add list termination tlv */
bnx2x_add_tlv(bp, req, bnx2x_add_tlv(bp, req,
req->first_tlv.tl.length + sizeof(struct channel_tlv), req->first_tlv.tl.length + sizeof(struct channel_tlv),
...@@ -1232,6 +1235,41 @@ static void bnx2x_vf_mbx_acquire_resp(struct bnx2x *bp, struct bnx2x_virtf *vf, ...@@ -1232,6 +1235,41 @@ static void bnx2x_vf_mbx_acquire_resp(struct bnx2x *bp, struct bnx2x_virtf *vf,
bnx2x_vf_mbx_resp_send_msg(bp, vf, vfop_status); bnx2x_vf_mbx_resp_send_msg(bp, vf, vfop_status);
} }
static bool bnx2x_vf_mbx_is_windows_vm(struct bnx2x *bp,
struct vfpf_acquire_tlv *acquire)
{
/* Windows driver does one of three things:
* 1. Old driver doesn't have bulletin board address set.
* 2. 'Middle' driver sends mc_num == 32.
* 3. New driver sets the OS field.
*/
if (!acquire->bulletin_addr ||
acquire->resc_request.num_mc_filters == 32 ||
((acquire->vfdev_info.vf_os & VF_OS_MASK) ==
VF_OS_WINDOWS))
return true;
return false;
}
static int bnx2x_vf_mbx_acquire_chk_dorq(struct bnx2x *bp,
struct bnx2x_virtf *vf,
struct bnx2x_vf_mbx *mbx)
{
/* Linux drivers which correctly set the doorbell size also
* send a physical port request
*/
if (bnx2x_search_tlv_list(bp, &mbx->msg->req,
CHANNEL_TLV_PHYS_PORT_ID))
return 0;
/* Issue does not exist in windows VMs */
if (bnx2x_vf_mbx_is_windows_vm(bp, &mbx->msg->req.acquire))
return 0;
return -EOPNOTSUPP;
}
static void bnx2x_vf_mbx_acquire(struct bnx2x *bp, struct bnx2x_virtf *vf, static void bnx2x_vf_mbx_acquire(struct bnx2x *bp, struct bnx2x_virtf *vf,
struct bnx2x_vf_mbx *mbx) struct bnx2x_vf_mbx *mbx)
{ {
...@@ -1247,12 +1285,32 @@ static void bnx2x_vf_mbx_acquire(struct bnx2x *bp, struct bnx2x_virtf *vf, ...@@ -1247,12 +1285,32 @@ static void bnx2x_vf_mbx_acquire(struct bnx2x *bp, struct bnx2x_virtf *vf,
acquire->resc_request.num_vlan_filters, acquire->resc_request.num_vlan_filters,
acquire->resc_request.num_mc_filters); acquire->resc_request.num_mc_filters);
/* Prevent VFs with old drivers from loading, since they calculate
* CIDs incorrectly requiring a VF-flr [VM reboot] in order to recover
* while being upgraded.
*/
rc = bnx2x_vf_mbx_acquire_chk_dorq(bp, vf, mbx);
if (rc) {
DP(BNX2X_MSG_IOV,
"VF [%d] - Can't support acquire request due to doorbell mismatch. Please update VM driver\n",
vf->abs_vfid);
goto out;
}
/* acquire the resources */ /* acquire the resources */
rc = bnx2x_vf_acquire(bp, vf, &acquire->resc_request); rc = bnx2x_vf_acquire(bp, vf, &acquire->resc_request);
/* store address of vf's bulletin board */ /* store address of vf's bulletin board */
vf->bulletin_map = acquire->bulletin_addr; vf->bulletin_map = acquire->bulletin_addr;
if (acquire->vfdev_info.caps & VF_CAP_SUPPORT_EXT_BULLETIN) {
DP(BNX2X_MSG_IOV, "VF[%d] supports long bulletin boards\n",
vf->abs_vfid);
vf->cfg_flags |= VF_CFG_EXT_BULLETIN;
} else {
vf->cfg_flags &= ~VF_CFG_EXT_BULLETIN;
}
out:
/* response */ /* response */
bnx2x_vf_mbx_acquire_resp(bp, vf, mbx, rc); bnx2x_vf_mbx_acquire_resp(bp, vf, mbx, rc);
} }
...@@ -1273,6 +1331,10 @@ static void bnx2x_vf_mbx_init_vf(struct bnx2x *bp, struct bnx2x_virtf *vf, ...@@ -1273,6 +1331,10 @@ static void bnx2x_vf_mbx_init_vf(struct bnx2x *bp, struct bnx2x_virtf *vf,
if (init->flags & VFPF_INIT_FLG_STATS_COALESCE) if (init->flags & VFPF_INIT_FLG_STATS_COALESCE)
vf->cfg_flags |= VF_CFG_STATS_COALESCE; vf->cfg_flags |= VF_CFG_STATS_COALESCE;
/* Update VF's view of link state */
if (vf->cfg_flags & VF_CFG_EXT_BULLETIN)
bnx2x_iov_link_update_vf(bp, vf->index);
/* response */ /* response */
bnx2x_vf_mbx_resp(bp, vf, rc); bnx2x_vf_mbx_resp(bp, vf, rc);
} }
...@@ -2007,6 +2069,17 @@ void bnx2x_vf_mbx(struct bnx2x *bp) ...@@ -2007,6 +2069,17 @@ void bnx2x_vf_mbx(struct bnx2x *bp)
} }
} }
void bnx2x_vf_bulletin_finalize(struct pf_vf_bulletin_content *bulletin,
bool support_long)
{
/* Older VFs contain a bug where they can't check CRC for bulletin
* boards of length greater than legacy size.
*/
bulletin->length = support_long ? BULLETIN_CONTENT_SIZE :
BULLETIN_CONTENT_LEGACY_SIZE;
bulletin->crc = bnx2x_crc_vf_bulletin(bulletin);
}
/* propagate local bulletin board to vf */ /* propagate local bulletin board to vf */
int bnx2x_post_vf_bulletin(struct bnx2x *bp, int vf) int bnx2x_post_vf_bulletin(struct bnx2x *bp, int vf)
{ {
...@@ -2023,8 +2096,9 @@ int bnx2x_post_vf_bulletin(struct bnx2x *bp, int vf) ...@@ -2023,8 +2096,9 @@ int bnx2x_post_vf_bulletin(struct bnx2x *bp, int vf)
/* increment bulletin board version and compute crc */ /* increment bulletin board version and compute crc */
bulletin->version++; bulletin->version++;
bulletin->length = BULLETIN_CONTENT_SIZE; bnx2x_vf_bulletin_finalize(bulletin,
bulletin->crc = bnx2x_crc_vf_bulletin(bp, bulletin); (bnx2x_vf(bp, vf, cfg_flags) &
VF_CFG_EXT_BULLETIN) ? true : false);
/* propagate bulletin board via dmae to vm memory */ /* propagate bulletin board via dmae to vm memory */
rc = bnx2x_copy32_vf_dmae(bp, false, pf_addr, rc = bnx2x_copy32_vf_dmae(bp, false, pf_addr,
......
...@@ -65,6 +65,7 @@ struct hw_sb_info { ...@@ -65,6 +65,7 @@ struct hw_sb_info {
#define VFPF_RX_MASK_ACCEPT_ALL_MULTICAST 0x00000008 #define VFPF_RX_MASK_ACCEPT_ALL_MULTICAST 0x00000008
#define VFPF_RX_MASK_ACCEPT_BROADCAST 0x00000010 #define VFPF_RX_MASK_ACCEPT_BROADCAST 0x00000010
#define BULLETIN_CONTENT_SIZE (sizeof(struct pf_vf_bulletin_content)) #define BULLETIN_CONTENT_SIZE (sizeof(struct pf_vf_bulletin_content))
#define BULLETIN_CONTENT_LEGACY_SIZE (32)
#define BULLETIN_ATTEMPTS 5 /* crc failures before throwing towel */ #define BULLETIN_ATTEMPTS 5 /* crc failures before throwing towel */
#define BULLETIN_CRC_SEED 0 #define BULLETIN_CRC_SEED 0
...@@ -117,7 +118,15 @@ struct vfpf_acquire_tlv { ...@@ -117,7 +118,15 @@ struct vfpf_acquire_tlv {
/* the following fields are for debug purposes */ /* the following fields are for debug purposes */
u8 vf_id; /* ME register value */ u8 vf_id; /* ME register value */
u8 vf_os; /* e.g. Linux, W2K8 */ u8 vf_os; /* e.g. Linux, W2K8 */
u8 padding[2]; #define VF_OS_SUBVERSION_MASK (0x1f)
#define VF_OS_MASK (0xe0)
#define VF_OS_SHIFT (5)
#define VF_OS_UNDEFINED (0 << VF_OS_SHIFT)
#define VF_OS_WINDOWS (1 << VF_OS_SHIFT)
u8 padding;
u8 caps;
#define VF_CAP_SUPPORT_EXT_BULLETIN (1 << 0)
} vfdev_info; } vfdev_info;
struct vf_pf_resc_request resc_request; struct vf_pf_resc_request resc_request;
...@@ -393,11 +402,23 @@ struct pf_vf_bulletin_content { ...@@ -393,11 +402,23 @@ struct pf_vf_bulletin_content {
* to attempt to send messages on the * to attempt to send messages on the
* channel after this bit is set * channel after this bit is set
*/ */
#define LINK_VALID 3 /* alert the VF thet a new link status
* update is available for it
*/
u8 mac[ETH_ALEN]; u8 mac[ETH_ALEN];
u8 mac_padding[2]; u8 mac_padding[2];
u16 vlan; u16 vlan;
u8 vlan_padding[6]; u8 vlan_padding[6];
u16 link_speed; /* Effective line speed */
u8 link_speed_padding[6];
u32 link_flags; /* VFPF_LINK_REPORT_XXX flags */
#define VFPF_LINK_REPORT_LINK_DOWN (1 << 0)
#define VFPF_LINK_REPORT_FULL_DUPLEX (1 << 1)
#define VFPF_LINK_REPORT_RX_FC_ON (1 << 2)
#define VFPF_LINK_REPORT_TX_FC_ON (1 << 3)
u8 link_flags_padding[4];
}; };
union pf_vf_bulletin { union pf_vf_bulletin {
......
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