* [PATCH net-next v4 21/22] bnx2x: Support PF <-> VF Bulletin Board
From: Ariel Elior @ 2012-12-30 19:57 UTC (permalink / raw)
To: David Miller; +Cc: netdev, Ariel Elior, Eilon Greenstein
In-Reply-To: <1356897442-3063-1-git-send-email-ariele@broadcom.com>
The PF <-> VF Bulletin Board is a simple interface between the
PF and the VF. The main reason for the Bulletin Board is to allow
the PF to be the initiator. The VF publishes at 'acquire' stage
the GPA of a Bulletin Board structure it has allocated. The PF notes
this GPA in the VF database. The VF samples the Bulletin Board
periodically for new messages. The latest version of the BB is always
used.
Signed-off-by: Ariel Elior <ariele@broadcom.com>
Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
---
drivers/net/ethernet/broadcom/bnx2x/bnx2x.h | 6 ++
drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | 87 +++++++++++++++++++
drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h | 2 +
drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 94 ++++++++++++++++++++-
drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c | 13 +++
drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h | 18 ++++
drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c | 65 ++++++++++++++
drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.h | 37 ++++++++
8 files changed, 320 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
index 2431ffd..335b536 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
@@ -1259,6 +1259,12 @@ struct bnx2x {
/* we set aside a copy of the acquire response */
struct pfvf_acquire_resp_tlv acquire_resp;
+ /* bulletin board for messages from pf to vf */
+ union pf_vf_bulletin *pf2vf_bulletin;
+ dma_addr_t pf2vf_bulletin_mapping;
+
+ struct pf_vf_bulletin_content old_bulletin;
+
struct net_device *dev;
struct pci_dev *pdev;
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
index cdb073a..f9a15cb 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
@@ -3793,6 +3793,93 @@ int bnx2x_setup_tc(struct net_device *dev, u8 num_tc)
return 0;
}
+/* New mac for VF. Consider these cases:
+ * 1. VF hasn't been acquired yet - save the mac in local bulletin board and
+ * supply at acquire.
+ * 2. VF has already been acquired but has not yet initialized - store in local
+ * bulletin board. mac will be posted on VF bulletin board after VF init. VF
+ * will configure this mac when it is ready.
+ * 3. VF has already initialized but has not yet setup a queue - post the new
+ * mac on VF's bulletin board right now. VF will configure this mac when it
+ * is ready.
+ * 4. VF has already set a queue - delete any macs already configured for this
+ * queue and manually config the new mac.
+ * In any event, once this function has been called refuse any attempts by the
+ * VF to configure any mac for itself except for this mac. In case of a race
+ * where the VF fails to see the new post on its bulletin board before sending a
+ * mac configuration request, the PF will simply fail the request and VF can try
+ * again after consulting its bulletin board
+ */
+int bnx2x_set_vf_mac(struct net_device *dev, int queue, u8 *mac)
+{
+ struct bnx2x *bp = netdev_priv(dev);
+ int rc, q_logical_state, vfidx = queue;
+ struct bnx2x_virtf *vf = BP_VF(bp, vfidx);
+ struct pf_vf_bulletin_content *bulletin = BP_VF_BULLETIN(bp, vfidx);
+
+ /* if SRIOV is disabled there is nothing to do (and somewhere, someone
+ * has erred).
+ */
+ if (!IS_SRIOV(bp)) {
+ BNX2X_ERR("bnx2x_set_vf_mac called though sriov is disabled\n");
+ return -EINVAL;
+ }
+
+ if (!is_valid_ether_addr(mac)) {
+ BNX2X_ERR("mac address invalid\n");
+ return -EINVAL;
+ }
+
+ /* update PF's copy of the VF's bulletin. will no longer accept mac
+ * configuration requests from vf unless match this mac
+ */
+ bulletin->valid_bitmap |= 1 << MAC_ADDR_VALID;
+ memcpy(bulletin->mac, mac, ETH_ALEN);
+
+ /* Post update on VF's bulletin board */
+ rc = bnx2x_post_vf_bulletin(bp, vfidx);
+ if (rc) {
+ BNX2X_ERR("failed to update VF[%d] bulletin\n", vfidx);
+ return rc;
+ }
+
+ /* is vf initialized and queue set up? */
+ q_logical_state =
+ bnx2x_get_q_logical_state(bp, &bnx2x_vfq(vf, 0, sp_obj));
+ if (vf->state == VF_ENABLED &&
+ q_logical_state == BNX2X_Q_LOGICAL_STATE_ACTIVE) {
+ /* configure the mac in device on this vf's queue */
+ unsigned long flags = 0;
+ struct bnx2x_vlan_mac_obj *mac_obj = &bnx2x_vfq(vf, 0, mac_obj);
+
+ /* must lock vfpf channel to protect against vf flows */
+ bnx2x_lock_vf_pf_channel(bp, vf, CHANNEL_TLV_PF_SET_MAC);
+
+ /* remove existing eth macs */
+ rc = bnx2x_del_all_macs(bp, mac_obj, BNX2X_ETH_MAC, true);
+ if (rc) {
+ BNX2X_ERR("failed to delete eth macs\n");
+ return -EINVAL;
+ }
+
+ /* remove existing uc list macs */
+ rc = bnx2x_del_all_macs(bp, mac_obj, BNX2X_UC_LIST_MAC, true);
+ if (rc) {
+ BNX2X_ERR("failed to delete uc_list macs\n");
+ return -EINVAL;
+ }
+
+ /* configure the new mac to device */
+ __set_bit(RAMROD_COMP_WAIT, &flags);
+ bnx2x_set_mac_one(bp, (u8 *)&bulletin->mac, mac_obj, true,
+ BNX2X_ETH_MAC, &flags);
+
+ bnx2x_unlock_vf_pf_channel(bp, vf, CHANNEL_TLV_PF_SET_MAC);
+ }
+
+ return rc;
+}
+
/* called with rtnl_lock */
int bnx2x_change_mac_addr(struct net_device *dev, void *p)
{
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h
index cd1eaff..23a1fa9 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h
@@ -496,6 +496,8 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev);
/* setup_tc callback */
int bnx2x_setup_tc(struct net_device *dev, u8 num_tc);
+int bnx2x_set_vf_mac(struct net_device *dev, int queue, u8 *mac);
+
/* select_queue callback */
u16 bnx2x_select_queue(struct net_device *dev, struct sk_buff *skb);
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
index 98299cb..b836d0a 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
@@ -5248,6 +5248,61 @@ void bnx2x_drv_pulse(struct bnx2x *bp)
bp->fw_drv_pulse_wr_seq);
}
+/* crc is the first field in the bulletin board. compute the crc over the
+ * entire bulletin board excluding the crc field itself
+ */
+u32 bnx2x_crc_vf_bulletin(struct bnx2x *bp,
+ struct pf_vf_bulletin_content *bulletin)
+{
+ return crc32(BULLETIN_CRC_SEED,
+ ((u8 *)bulletin) + sizeof(bulletin->crc),
+ BULLETIN_CONTENT_SIZE - sizeof(bulletin->crc));
+}
+
+/* Check for new posts on the bulletin board */
+enum sample_bulletin_result bnx2x_sample_bulletin(struct bnx2x *bp)
+{
+ struct pf_vf_bulletin_content bulletin = bp->pf2vf_bulletin->content;
+ int attempts;
+
+ /* bulletin board hasn't changed since last sample */
+ if (bp->old_bulletin.version == bulletin.version)
+ return PFVF_BULLETIN_UNCHANGED;
+
+ /* validate crc of new bulletin board */
+ if (bp->old_bulletin.version != bp->pf2vf_bulletin->content.version) {
+ /* sampling structure in mid post may result with corrupted data
+ * validate crc to ensure coherency.
+ */
+ for (attempts = 0; attempts < BULLETIN_ATTEMPTS; attempts++) {
+ bulletin = bp->pf2vf_bulletin->content;
+ if (bulletin.crc == bnx2x_crc_vf_bulletin(bp,
+ &bulletin))
+ break;
+
+ BNX2X_ERR("bad crc on bulletin board. contained %x computed %x\n",
+ bulletin.crc,
+ bnx2x_crc_vf_bulletin(bp, &bulletin));
+ }
+ if (attempts >= BULLETIN_ATTEMPTS) {
+ BNX2X_ERR("pf to vf bulletin board crc was wrong %d consecutive times. Aborting\n",
+ attempts);
+ return PFVF_BULLETIN_CRC_ERR;
+ }
+ }
+
+ /* the mac address in bulletin board is valid and is new */
+ if (bulletin.valid_bitmap & 1 << MAC_ADDR_VALID &&
+ memcmp(bulletin.mac, bp->old_bulletin.mac, ETH_ALEN)) {
+ /* update new mac to net device */
+ memcpy(bp->dev->dev_addr, bulletin.mac, ETH_ALEN);
+ }
+
+ /* copy new bulletin board to bp */
+ bp->old_bulletin = bulletin;
+
+ return PFVF_BULLETIN_UPDATED;
+}
static void bnx2x_timer(unsigned long data)
{
@@ -5284,6 +5339,10 @@ static void bnx2x_timer(unsigned long data)
if (bp->state == BNX2X_STATE_OPEN)
bnx2x_stats_handle(bp, STATS_EVENT_UPDATE);
+ /* sample pf vf bulletin board for new posts from pf */
+ if (IS_VF(bp))
+ bnx2x_sample_bulletin(bp);
+
mod_timer(&bp->timer, jiffies + bp->current_interval);
}
@@ -11663,7 +11722,7 @@ static const struct net_device_ops bnx2x_netdev_ops = {
.ndo_poll_controller = poll_bnx2x,
#endif
.ndo_setup_tc = bnx2x_setup_tc,
-
+ .ndo_set_vf_mac = bnx2x_set_vf_mac,
#ifdef NETDEV_FCOE_WWNN
.ndo_fcoe_get_wwn = bnx2x_fcoe_get_wwn,
#endif
@@ -12324,6 +12383,11 @@ static int bnx2x_init_one(struct pci_dev *pdev,
/* allocate vf2pf mailbox for vf to pf channel */
BNX2X_PCI_ALLOC(bp->vf2pf_mbox, &bp->vf2pf_mbox_mapping,
sizeof(struct bnx2x_vf_mbx_msg));
+
+ /* allocate pf 2 vf bulletin board */
+ BNX2X_PCI_ALLOC(bp->pf2vf_bulletin, &bp->pf2vf_bulletin_mapping,
+ sizeof(union pf_vf_bulletin));
+
} else {
doorbell_size = BNX2X_L2_MAX_CID(bp) * (1 << BNX2X_DB_SHIFT);
if (doorbell_size > pci_resource_len(pdev, 2)) {
@@ -13382,6 +13446,9 @@ int bnx2x_vfpf_acquire(struct bnx2x *bp, u8 tx_count, u8 rx_count)
req->resc_request.num_mac_filters = VF_ACQUIRE_MAC_FILTERS;
req->resc_request.num_mc_filters = VF_ACQUIRE_MC_FILTERS;
+ /* pf 2 vf bulletin board address */
+ req->bulletin_addr = bp->pf2vf_bulletin_mapping;
+
/* add list termination tlv */
bnx2x_add_tlv(bp, req, req->first_tlv.tl.length, CHANNEL_TLV_LIST_END,
sizeof(struct channel_list_end_tlv));
@@ -13704,6 +13771,7 @@ int bnx2x_vfpf_teardown_queue(struct bnx2x *bp, int qidx)
return rc;
}
+ /* PF failed the transaction */
if (resp->hdr.status != PFVF_STATUS_SUCCESS) {
BNX2X_ERR("TEARDOWN for queue %d failed: %d\n", qidx,
resp->hdr.status);
@@ -13730,6 +13798,9 @@ int bnx2x_vfpf_set_mac(struct bnx2x *bp)
req->filters[0].flags =
VFPF_Q_FILTER_DEST_MAC_VALID | VFPF_Q_FILTER_SET_MAC;
+ /* sample bulletin board for new mac */
+ bnx2x_sample_bulletin(bp);
+
/* copy mac from device to request */
memcpy(req->filters[0].mac, bp->dev->dev_addr, ETH_ALEN);
@@ -13747,7 +13818,26 @@ int bnx2x_vfpf_set_mac(struct bnx2x *bp)
return rc;
}
- /* PF failed the transaction */
+ /* failure may mean PF was configured with a new mac for us */
+ while (resp->hdr.status == PFVF_STATUS_FAILURE) {
+ DP(BNX2X_MSG_IOV,
+ "vfpf SET MAC failed. Check bulletin board for new posts\n");
+
+ /* check if bulletin board was updated */
+ if (bnx2x_sample_bulletin(bp) == PFVF_BULLETIN_UPDATED) {
+ /* copy mac from device to request */
+ memcpy(req->filters[0].mac, bp->dev->dev_addr,
+ ETH_ALEN);
+
+ /* send message to pf */
+ rc = bnx2x_send_msg2pf(bp, &resp->hdr.status,
+ bp->vf2pf_mbox_mapping);
+ } else {
+ /* no new info in bulletin */
+ break;
+ }
+ }
+
if (resp->hdr.status != PFVF_STATUS_SUCCESS) {
BNX2X_ERR("vfpf SET MAC failed: %d\n", resp->hdr.status);
return -EINVAL;
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c
index c96ce5b..1f1e823 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c
@@ -2058,6 +2058,10 @@ void bnx2x_iov_free_mem(struct bnx2x *bp)
BNX2X_PCI_FREE(BP_VF_MBX_DMA(bp)->addr,
BP_VF_MBX_DMA(bp)->mapping,
BP_VF_MBX_DMA(bp)->size);
+
+ BNX2X_PCI_FREE(BP_VF_BULLETIN_DMA(bp)->addr,
+ BP_VF_BULLETIN_DMA(bp)->mapping,
+ BP_VF_BULLETIN_DMA(bp)->size);
}
int bnx2x_iov_alloc_mem(struct bnx2x *bp)
@@ -2097,6 +2101,12 @@ int bnx2x_iov_alloc_mem(struct bnx2x *bp)
tot_size);
BP_VF_MBX_DMA(bp)->size = tot_size;
+ /* allocate local bulletin boards */
+ tot_size = BNX2X_NR_VIRTFN(bp) * BULLETIN_CONTENT_SIZE;
+ BNX2X_PCI_ALLOC(BP_VF_BULLETIN_DMA(bp)->addr,
+ &BP_VF_BULLETIN_DMA(bp)->mapping, tot_size);
+ BP_VF_BULLETIN_DMA(bp)->size = tot_size;
+
return 0;
alloc_mem_err:
@@ -2810,6 +2820,9 @@ int bnx2x_vf_init(struct bnx2x *bp, struct bnx2x_virtf *vf, dma_addr_t *sb_map)
vf->state = VF_ENABLED;
+ /* update vf bulletin board */
+ bnx2x_post_vf_bulletin(bp, vf->index);
+
return 0;
}
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h
index 25396fa..aab2a05 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h
@@ -378,6 +378,12 @@ struct bnx2x_vfdb {
struct bnx2x_vf_mbx mbxs[BNX2X_MAX_NUM_OF_VFS];
#define BP_VF_MBX(bp, vfid) (&((bp)->vfdb->mbxs[(vfid)]))
+ struct hw_dma bulletin_dma;
+#define BP_VF_BULLETIN_DMA(bp) (&((bp)->vfdb->bulletin_dma))
+#define BP_VF_BULLETIN(bp, vf) \
+ (((struct pf_vf_bulletin_content *)(BP_VF_BULLETIN_DMA(bp)->addr)) \
+ + (vf))
+
struct hw_dma sp_dma;
#define bnx2x_vf_sp(bp, vf, field) ((bp)->vfdb->sp_dma.addr + \
(vf)->index * sizeof(struct bnx2x_vf_sp) + \
@@ -702,4 +708,16 @@ void bnx2x_dp_tlv_list(struct bnx2x *bp, void *tlvs_list);
bool bnx2x_tlv_supported(u16 tlvtype);
+u32 bnx2x_crc_vf_bulletin(struct bnx2x *bp,
+ struct pf_vf_bulletin_content *bulletin);
+int bnx2x_post_vf_bulletin(struct bnx2x *bp, int vf);
+
+enum sample_bulletin_result {
+ PFVF_BULLETIN_UNCHANGED,
+ PFVF_BULLETIN_UPDATED,
+ PFVF_BULLETIN_CRC_ERR
+};
+
+enum sample_bulletin_result bnx2x_sample_bulletin(struct bnx2x *bp);
+
#endif /* bnx2x_sriov.h */
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c
index b7c2456..55a45e5 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c
@@ -297,6 +297,10 @@ static void bnx2x_vf_mbx_acquire_resp(struct bnx2x *bp, struct bnx2x_virtf *vf,
resc->num_mc_filters = 0;
if (status == PFVF_STATUS_SUCCESS) {
+ /* fill in the allocated resources */
+ struct pf_vf_bulletin_content *bulletin =
+ BP_VF_BULLETIN(bp, vf->index);
+
for_each_vfq(vf, i)
resc->hw_qid[i] =
vfq_qzone_id(vf, vfq_get(vf, i));
@@ -305,6 +309,12 @@ static void bnx2x_vf_mbx_acquire_resp(struct bnx2x *bp, struct bnx2x_virtf *vf,
resc->hw_sbs[i].hw_sb_id = vf_igu_sb(vf, i);
resc->hw_sbs[i].sb_qid = vf_hc_qzone(vf, i);
}
+
+ /* if a mac has been set for this vf, supply it */
+ if (bulletin->valid_bitmap & 1 << MAC_ADDR_VALID) {
+ memcpy(resc->current_mac_addr, bulletin->mac,
+ ETH_ALEN);
+ }
}
}
@@ -356,6 +366,9 @@ static void bnx2x_vf_mbx_acquire(struct bnx2x *bp, struct bnx2x_virtf *vf,
/* acquire the resources */
rc = bnx2x_vf_acquire(bp, vf, &acquire->resc_request);
+ /* store address of vf's bulletin board */
+ vf->bulletin_map = acquire->bulletin_addr;
+
/* response */
bnx2x_vf_mbx_acquire_resp(bp, vf, mbx, rc);
}
@@ -766,11 +779,37 @@ static void bnx2x_vf_mbx_set_q_filters(struct bnx2x *bp,
struct bnx2x_vf_mbx *mbx)
{
struct vfpf_set_q_filters_tlv *filters = &mbx->msg->req.set_q_filters;
+ struct pf_vf_bulletin_content *bulletin = BP_VF_BULLETIN(bp, vf->index);
struct bnx2x_vfop_cmd cmd = {
.done = bnx2x_vf_mbx_resp,
.block = false,
};
+ /* if a mac was already set for this VF via the set vf mac ndo, we only
+ * accept mac configurations of that mac. Why accept them at all?
+ * because PF may have been unable to configure the mac at the time
+ * since queue was not set up.
+ */
+ if (bulletin->valid_bitmap & 1 << MAC_ADDR_VALID) {
+ /* once a mac was set by ndo can only accept a single mac... */
+ if (filters->n_mac_vlan_filters > 1) {
+ BNX2X_ERR("VF[%d] requested the addition of multiple macs after set_vf_mac ndo was called\n",
+ vf->abs_vfid);
+ vf->op_rc = -EPERM;
+ goto response;
+ }
+
+ /* ...and only the mac set by the ndo */
+ if (filters->n_mac_vlan_filters == 1 &&
+ memcmp(filters->filters->mac, bulletin->mac, ETH_ALEN)) {
+ BNX2X_ERR("VF[%d] requested the addition of a mac address not matching the one configured by set_vf_mac ndo\n",
+ vf->abs_vfid);
+
+ vf->op_rc = -EPERM;
+ goto response;
+ }
+ }
+
/* verify vf_qid */
if (filters->vf_qid > vf_rxq_count(vf))
goto response;
@@ -977,3 +1016,29 @@ mbx_error:
mbx_done:
return;
}
+
+/* propagate local bulletin board to vf */
+int bnx2x_post_vf_bulletin(struct bnx2x *bp, int vf)
+{
+ struct pf_vf_bulletin_content *bulletin = BP_VF_BULLETIN(bp, vf);
+ dma_addr_t pf_addr = BP_VF_BULLETIN_DMA(bp)->mapping +
+ vf * BULLETIN_CONTENT_SIZE;
+ dma_addr_t vf_addr = bnx2x_vf(bp, vf, bulletin_map);
+ u32 len = BULLETIN_CONTENT_SIZE;
+ int rc;
+
+ /* can only update vf after init took place */
+ if (bnx2x_vf(bp, vf, state) != VF_ENABLED &&
+ bnx2x_vf(bp, vf, state) != VF_ACQUIRED)
+ return 0;
+
+ /* increment bulletin board version and compute crc */
+ bulletin->version++;
+ bulletin->crc = bnx2x_crc_vf_bulletin(bp, bulletin);
+
+ /* propagate bulletin board via dmae to vm memory */
+ rc = bnx2x_copy32_vf_dmae(bp, false, pf_addr,
+ bnx2x_vf(bp, vf, abs_vfid), U64_HI(vf_addr),
+ U64_LO(vf_addr), len/4);
+ return rc;
+}
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.h
index 554c119..9f07ada 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.h
@@ -37,6 +37,7 @@ struct hw_sb_info {
* A.K.A VF-PF mailbox
*/
#define TLV_BUFFER_SIZE 1024
+#define PF_VF_BULLETIN_SIZE 512
#define VFPF_QUEUE_FLG_TPA 0x0001
#define VFPF_QUEUE_FLG_TPA_IPV6 0x0002
@@ -60,6 +61,9 @@ struct hw_sb_info {
#define VFPF_RX_MASK_ACCEPT_ALL_UNICAST 0x00000004
#define VFPF_RX_MASK_ACCEPT_ALL_MULTICAST 0x00000008
#define VFPF_RX_MASK_ACCEPT_BROADCAST 0x00000010
+#define BULLETIN_CONTENT_SIZE (sizeof(struct pf_vf_bulletin_content))
+#define BULLETIN_ATTEMPTS 5 /* crc failures before throwing towel */
+#define BULLETIN_CRC_SEED 0
enum {
PFVF_STATUS_WAITING = 0,
@@ -299,6 +303,38 @@ union pfvf_tlvs {
struct tlv_buffer_size tlv_buf_size;
};
+/* This is a structure which is allocated in the VF, which the PF may update
+ * when it deems it necessary to do so. The bulletin board is sampled
+ * periodically by the VF. A copy per VF is maintained in the PF (to prevent
+ * loss of data upon multiple updates (or the need for read modify write)).
+ */
+struct pf_vf_bulletin_size {
+ u8 size[PF_VF_BULLETIN_SIZE];
+};
+
+struct pf_vf_bulletin_content {
+ u32 crc; /* crc of structure to ensure is not in
+ * mid-update
+ */
+ u32 version;
+
+ aligned_u64 valid_bitmap; /* bitmap indicating which fields
+ * hold valid values
+ */
+
+#define MAC_ADDR_VALID 0 /* alert the vf that a new mac address
+ * is available for it
+ */
+
+ u8 mac[ETH_ALEN];
+ u8 padding[2];
+};
+
+union pf_vf_bulletin {
+ struct pf_vf_bulletin_content content;
+ struct pf_vf_bulletin_size size;
+};
+
#define MAX_TLVS_IN_LIST 50
enum channel_tlvs {
@@ -313,6 +349,7 @@ enum channel_tlvs {
CHANNEL_TLV_PF_RELEASE_VF,
CHANNEL_TLV_LIST_END,
CHANNEL_TLV_FLR,
+ CHANNEL_TLV_PF_SET_MAC,
CHANNEL_TLV_MAX
};
--
1.7.9.GIT
^ permalink raw reply related
* Re: Is keepalive behaving as expected in 3.7.0+/net-next?
From: Rick Jones @ 2012-12-30 20:51 UTC (permalink / raw)
To: Jamie Gloudon; +Cc: Eric Dumazet, netdev
In-Reply-To: <50df48f4.0e5b650a.36fa.1452@mx.google.com>
> Make a lot of sense. However, I got the impression from Rick that
> having tcp_keepalive_intvl > tcp_keepalive_time behaved correctly in
> older versions of the kernel.
I seek to make no assertions about the behaviour of older kernels. I
was just going off the ip-sysctl.txt wording I was looking to clean-up.
rick
^ permalink raw reply
* Re: [PATCH net-next] team: update master carrier state
From: Jiri Pirko @ 2012-12-30 21:47 UTC (permalink / raw)
To: Flavio Leitner; +Cc: netdev
In-Reply-To: <1356892049-14667-1-git-send-email-fbl@redhat.com>
Sun, Dec 30, 2012 at 07:27:29PM CET, fbl@redhat.com wrote:
>Update master's carrier state when there is any
>change with its ports.
This patch looks good to me. Just one nitpick I spotted....
>+ bool team_linkup;
>+
>+ team_linkup = false;
This can be squashed together.
^ permalink raw reply
* Re: [PATCH net-next] team: update master carrier state
From: Flavio Leitner @ 2012-12-30 22:06 UTC (permalink / raw)
To: Jiri Pirko; +Cc: netdev
In-Reply-To: <20121230214723.GD1575@minipsycho.orion>
On Sun, Dec 30, 2012 at 10:47:23PM +0100, Jiri Pirko wrote:
> Sun, Dec 30, 2012 at 07:27:29PM CET, fbl@redhat.com wrote:
> >Update master's carrier state when there is any
> >change with its ports.
>
>
> This patch looks good to me. Just one nitpick I spotted....
>
> >+ bool team_linkup;
> >+
> >+ team_linkup = false;
>
>
> This can be squashed together.
Ok, but that increases the static size of the module because it
moves the variable out of bss.
I have no strong opinion on either case, so it's up to you.
Thanks,
--
fbl
^ permalink raw reply
* Re: [patch net-next 01/15] net: introduce upper device lists
From: Jiri Pirko @ 2012-12-30 22:08 UTC (permalink / raw)
To: Ben Greear
Cc: netdev, davem, edumazet, bhutchings, faisal.latif, shemminger,
fbl, roland, sean.hefty, hal.rosenstock, fubar, andy, divy,
jitendra.kalsaria, sony.chacko, linux-driver, kaber, ursula.braun,
blaschka, schwidefsky, heiko.carstens, ebiederm, joe, amwang,
nhorman, john.r.fastabend, pablo
In-Reply-To: <50E0814A.3090100@candelatech.com>
Sun, Dec 30, 2012 at 07:00:42PM CET, greearb@candelatech.com wrote:
>On 12/30/2012 03:58 AM, Jiri Pirko wrote:
>>This lists are supposed to serve for storing pointers to all upper devices.
>>Eventually it will replace dev->master pointer which is used for
>>bonding, bridge, team but it cannot be used for vlan, macvlan where
>>there might be multiple upper present. In case the upper link is
>>replacement for dev->master, it is marked with "master" flag.
>
>This is confusing and full of grammatical errors. For instance, the 'it'
>in "team but it cannot be used"...you are talking about the list this
>patch introduces, or the old dev->master?
Sorry for my grammar, it stinks...
dev->master cannot be used for for vlan, macvlan. More upper devices
might be present for this type of devices and dev->master would not cover it.
So, In case there is only *one* upper device, "master" flag is used.
I Hope I cleared this one for you.
>
>>
>>New upper device list resolves this limitation. Also, the information
>>stored in lists is used for preventing looping setups like
>>"bond->somethingelse->samebond"
>>
>>Signed-off-by: Jiri Pirko <jiri@resnulli.us>
>>---
>> include/linux/netdevice.h | 14 +++
>> net/core/dev.c | 237 +++++++++++++++++++++++++++++++++++++++++++++-
>> 2 files changed, 247 insertions(+), 4 deletions(-)
>>
>>diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
>>index 6835b58..52d1146 100644
>>--- a/include/linux/netdevice.h
>>+++ b/include/linux/netdevice.h
>>@@ -1172,6 +1172,8 @@ struct net_device {
>> * which this device is member of.
>> */
>>
>>+ struct list_head upper_dev_list; /* List of upper devices */
>>+
>
>Unless I mis-understand, this is often contains 'lower' devices instead,
>and could contain a mixture.
>Maybe this could use a rename, or at least a lot more comments?
I'm terribly sorry, but I believe this is the case when I do not
understand your grammar. For example "this is often contains 'lower'
devices instead".
But in any case, no, list of upper devices contains only "upper" devices.
Meaning the set of devices which are using the original one as "lower".
Never the other way.
And to reply to your comment to patch "[patch net-next 04/15] rtnetlink:
remove usage of dev->master" as well:
upper dev is the device that is somehow using the lower dev for its
work. For bonding, you may call that lower device "slave", for bridge,
"port". And macvlan is also linked to it's lower device, the one on what
it is hooked on by rx_handler.
I hope this clears this for you a bit.
Thanks
Jiri.
>
>Thanks,
>Ben
>
>--
>Ben Greear <greearb@candelatech.com>
>Candela Technologies Inc http://www.candelatech.com
>
>
^ permalink raw reply
* Re: [PATCH net-next] team: update master carrier state
From: Jiri Pirko @ 2012-12-30 22:10 UTC (permalink / raw)
To: netdev
In-Reply-To: <20121230220616.GA2065@obelix.rh>
Sun, Dec 30, 2012 at 11:06:16PM CET, fbl@redhat.com wrote:
>On Sun, Dec 30, 2012 at 10:47:23PM +0100, Jiri Pirko wrote:
>> Sun, Dec 30, 2012 at 07:27:29PM CET, fbl@redhat.com wrote:
>> >Update master's carrier state when there is any
>> >change with its ports.
>>
>>
>> This patch looks good to me. Just one nitpick I spotted....
>>
>> >+ bool team_linkup;
>> >+
>> >+ team_linkup = false;
>>
>>
>> This can be squashed together.
>
>Ok, but that increases the static size of the module because it
>moves the variable out of bss.
>
>I have no strong opinion on either case, so it's up to you.
Ok :)
Acked-by: Jiri Pirko <jiri@resnulli.us>
^ permalink raw reply
* Re: [PATCH net-next v4 04/22] bnx2x: Separate VF and PF logic
From: David Miller @ 2012-12-31 1:35 UTC (permalink / raw)
To: ariele; +Cc: netdev, eilong
In-Reply-To: <1356897442-3063-5-git-send-email-ariele@broadcom.com>
From: "Ariel Elior" <ariele@broadcom.com>
Date: Sun, 30 Dec 2012 21:57:04 +0200
> Generally, the VF driver cannot access the chip, except by the
> narrow window its BAR allows. Care had to be taken so the VF driver
> will not reach code which accesses the chip elsewhere.
> Refactor the nic_load flow into parts so it would be
> easier to separate the VF-only logic from the PF-only logic.
>
> Signed-off-by: Ariel Elior <ariele@broadcom.com>
> Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
This introduces warnings:
drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c: In function ‘bnx2x_open’:
drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c:11311:7: warning: ‘load_status’ may be used uninitialized in this function [-Wmaybe-uninitialized]
drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c:11312:18: warning: ‘other_load_status’ may be used uninitialized in this function [-Wmaybe-uninitialized]
This is with gcc-4.7.2 on Fedora 17
^ permalink raw reply
* Re: [PATCH net-next v4 18/22] bnx2x: Support of PF driver of a VF close request
From: David Miller @ 2012-12-31 1:42 UTC (permalink / raw)
To: ariele; +Cc: netdev, eilong
In-Reply-To: <1356897442-3063-19-git-send-email-ariele@broadcom.com>
From: "Ariel Elior" <ariele@broadcom.com>
Date: Sun, 30 Dec 2012 21:57:18 +0200
> The 'close' command is the opposite of an init request. Here the
> queues of the VF are closed (if any are opened) and released.
> This flow applies the 'q_teardown' flow on all the queues.
> The VF state is changed by this request.
> Interrupts are disabled for the VF when closed.
>
> Signed-off-by: Ariel Elior <ariele@broadcom.com>
> Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
This introduces a warning:
drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c:816:13: warning: ‘bnx2x_vf_mbx_close_vf’ defined but not used [-Wunused-function]
^ permalink raw reply
* Re: Is keepalive behaving as expected in 3.7.0+/net-next?
From: Jamie Gloudon @ 2012-12-31 1:50 UTC (permalink / raw)
To: Rick Jones; +Cc: Eric Dumazet, netdev
In-Reply-To: <50E0A963.6080900@hp.com>
On Sun, Dec 30, 2012 at 12:51:47PM -0800, Rick Jones wrote:
> >Make a lot of sense. However, I got the impression from Rick that
> >having tcp_keepalive_intvl > tcp_keepalive_time behaved correctly in
> >older versions of the kernel.
>
> I seek to make no assertions about the behaviour of older kernels. I was
> just going off the ip-sysctl.txt wording I was looking to clean-up.
>
> rick
Ok, should ip-sysctl.txt documentation be updated to warn not to set tcp_keepalive_intvl > tcp_keepalive_time?
Regards,
Jamie Gloudon
^ permalink raw reply
* Re: [patch net-next 01/15] net: introduce upper device lists
From: Stephen Hemminger @ 2012-12-31 4:56 UTC (permalink / raw)
To: Jiri Pirko
Cc: netdev, davem, edumazet, bhutchings, faisal.latif, fbl, roland,
sean.hefty, hal.rosenstock, fubar, andy, divy, jitendra.kalsaria,
sony.chacko, linux-driver, kaber, ursula.braun, blaschka,
schwidefsky, heiko.carstens, ebiederm, joe, amwang, nhorman,
john.r.fastabend, pablo
In-Reply-To: <1356868702-8144-2-git-send-email-jiri@resnulli.us>
On Sun, 30 Dec 2012 12:58:08 +0100
Jiri Pirko <jiri@resnulli.us> wrote:
> This lists are supposed to serve for storing pointers to all upper devices.
> Eventually it will replace dev->master pointer which is used for
> bonding, bridge, team but it cannot be used for vlan, macvlan where
> there might be multiple upper present. In case the upper link is
> replacement for dev->master, it is marked with "master" flag.
>
> New upper device list resolves this limitation. Also, the information
> stored in lists is used for preventing looping setups like
> "bond->somethingelse->samebond"
>
> Signed-off-by: Jiri Pirko <jiri@resnulli.us>
What is the use case for this?
Could you describe a topology that the new upper device list supports,
that the old scheme does not?
I am concerned that it may open up many new possibilities for user
error that were not possible before. For example how does it prevent
an ethernet from being assigned to both a bonding and bridge at the
same time?
^ permalink raw reply
* Re: batman-adv: Unable to add interface in LXC
From: Marek Lindner @ 2012-12-31 7:11 UTC (permalink / raw)
To: b.a.t.m.a.n-ZwoEplunGu2X36UT3dwllkB+6BGkLq7r
Cc: netdev-u79uwXL29TY76Z2rM5mHXA, Pau Koning
In-Reply-To: <CANiGF9-dq-HrvWrgu9EMC94rP=1YdrmaFbCF2g1SZ9ocu77ysw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
On Monday, December 31, 2012 03:34:38 Pau Koning wrote:
> I am running LXC (SID) under Debian SID and the current git version of
> batman-adv (v3.7-rc7-1325-gaf5d4f7) +batctl (v2012.4.0-30-ga395164).
> But it fails to add any of my interfaces and non-batman-adv interfaces
> can be created without problems
>
> # ip link
> 13: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast
> state UP mode DEFAULT qlen 1000
> link/ether 00:ff:aa:00:00:01 brd ff:ff:ff:ff:ff:ff
> 15: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN
> mode DEFAULT
> link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
> # batctl if add eth0
> Error - can't open file '/sys/class/net/eth0/batman_adv/mesh_iface':
> Read-only file system
Did you check your kernel log messages ? I'd expect batman-adv to print
something there in case of an error.
Cheers,
Marek
^ permalink raw reply
* Re: [patch net-next 01/15] net: introduce upper device lists
From: Jiri Pirko @ 2012-12-31 9:55 UTC (permalink / raw)
To: Stephen Hemminger
Cc: netdev, davem, edumazet, bhutchings, faisal.latif, fbl, roland,
sean.hefty, hal.rosenstock, fubar, andy, divy, jitendra.kalsaria,
sony.chacko, linux-driver, kaber, ursula.braun, blaschka,
schwidefsky, heiko.carstens, ebiederm, joe, amwang, nhorman,
john.r.fastabend, pablo
In-Reply-To: <20121230205633.5e5614ac@nehalam.linuxnetplumber.net>
Mon, Dec 31, 2012 at 05:56:33AM CET, shemminger@vyatta.com wrote:
>On Sun, 30 Dec 2012 12:58:08 +0100
>Jiri Pirko <jiri@resnulli.us> wrote:
>
>> This lists are supposed to serve for storing pointers to all upper devices.
>> Eventually it will replace dev->master pointer which is used for
>> bonding, bridge, team but it cannot be used for vlan, macvlan where
>> there might be multiple upper present. In case the upper link is
>> replacement for dev->master, it is marked with "master" flag.
>>
>> New upper device list resolves this limitation. Also, the information
>> stored in lists is used for preventing looping setups like
>> "bond->somethingelse->samebond"
>>
>> Signed-off-by: Jiri Pirko <jiri@resnulli.us>
>
>What is the use case for this?
>Could you describe a topology that the new upper device list supports,
>that the old scheme does not?
The old scheme is not possible to track the upper-lower dependencies for
all types of devices. (dev->master is used by bonding,bridge,team only).
My new scheme using upper lists allows to track all dependencies. That
provides ability to prevent loops in the dependency trees.
>
>I am concerned that it may open up many new possibilities for user
>error that were not possible before. For example how does it prevent
>an ethernet from being assigned to both a bonding and bridge at the
>same time?
No. netdev_master_upper_dev_link() is used in bond,bridge,team etc.
This function ensures that only one upper device marked as "master" is
present at a time.
This patchset does not introduce any possibility for user error. Only
prevents one group of them - loops.
^ permalink raw reply
* Re: [PATCH] net: fix checking boundary of valid vlan id
From: Glen Turner @ 2012-12-31 11:36 UTC (permalink / raw)
To: Florian Westphal; +Cc: akong, netdev, davem
In-Reply-To: <20121230122542.GC11727@breakpoint.cc>
On 30/12/2012, at 10:55 PM, Florian Westphal wrote:
> akong@redhat.com <akong@redhat.com> wrote:
>> From: Amos Kong <akong@redhat.com>
>>
>> 4096 is not a valid vlan id.
>
> True.
>
> But why shouldn't users be allowed to check for frames
> with reserved value
It may be a valid VLAN ID, or it may not. The meaning of FFF is reserved for vendor use, which doesn't preclude a vendor using it as a (non-interoperable) VLAN identifier. Many vendor's products treat 4096 as they do any other VID.
It's up to Linux if it cares to treat 4096 as a VLAN or as something else.
In any case, Florian's point is good: an ethernet-layer firewall should be able to trigger on any value of VID, and particularly one which should not be seen from some vendor's gear.
-glen
^ permalink raw reply
* [PATCH] poll: prevent missed events if _qproc is NULL
From: Eric Wong @ 2012-12-31 13:21 UTC (permalink / raw)
To: linux-kernel
Cc: Eric Wong, Hans Verkuil, Jiri Olsa, Jonathan Corbet, Al Viro,
Davide Libenzi, Hans de Goede, Mauro Carvalho Chehab,
David Miller, Eric Dumazet, Andrew Morton, Linus Torvalds,
Andreas Voellmy, Junchang(Jason) Wang, netdev, linux-fsdevel
In-Reply-To: <20121228014503.GA5017@dcvr.yhbt.net>
This patch seems to fix my issue with ppoll() being stuck on my
SMP machine: http://article.gmane.org/gmane.linux.file-systems/70414
The change to sock_poll_wait() in
commit 626cf236608505d376e4799adb4f7eb00a8594af
(poll: add poll_requested_events() and poll_does_not_wait() functions)
seems to have allowed additional cases where the SMP memory barrier
is not issued before checking for readiness.
In my case, this affects the select()-family of functions
which register descriptors once and set _qproc to NULL before
checking events again (after poll_schedule_timeout() returns).
The set_mb() barrier in poll_schedule_timeout() appears to be
insufficient on my SMP x86-64 machine (as it's only an xchg()).
This may also be related to the epoll issue described by
Andreas Voellmy in http://thread.gmane.org/gmane.linux.kernel/1408782/
Signed-off-by: Eric Wong <normalperson@yhbt.net>
Cc: Hans Verkuil <hans.verkuil@cisco.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Jonathan Corbet <corbet@lwn.net>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: Davide Libenzi <davidel@xmailserver.org>
Cc: Hans de Goede <hdegoede@redhat.com>
Cc: Mauro Carvalho Chehab <mchehab@infradead.org>
Cc: David Miller <davem@davemloft.net>
Cc: Eric Dumazet <eric.dumazet@gmail.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Andreas Voellmy <andreas.voellmy@yale.edu>
Cc: "Junchang(Jason) Wang" <junchang.wang@yale.edu>
Cc: netdev@vger.kernel.org
Cc: linux-fsdevel@vger.kernel.org
---
If this patch is correct, I think we can just drop the
poll_does_not_wait() function entirely since poll_wait()
does the same check anyways...
include/net/sock.h | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/include/net/sock.h b/include/net/sock.h
index c945fba..1923e48 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -1925,8 +1925,9 @@ static inline bool wq_has_sleeper(struct socket_wq *wq)
static inline void sock_poll_wait(struct file *filp,
wait_queue_head_t *wait_address, poll_table *p)
{
- if (!poll_does_not_wait(p) && wait_address) {
- poll_wait(filp, wait_address, p);
+ if (wait_address) {
+ if (!poll_does_not_wait(p))
+ poll_wait(filp, wait_address, p);
/* We need to be sure we are in sync with the
* socket flags modification.
*
--
Eric Wong
^ permalink raw reply related
* [PATCH net-next 0/8] Add complementary BPF conditional jump instructions
From: Daniel Borkmann @ 2012-12-31 13:59 UTC (permalink / raw)
To: davem; +Cc: netdev
This set adds adds jump operations for lt (<), le (<=), ne (!=) that
compare A with K resp. X in order to facilitate filter programming
with conditional jumps, as also available in McCanne et. al's BPF+
paper (``BPF+: Exploiting Global Data-flow Optimization in a Generalized
Packet Filter Architecture'').
Also, follow-up BPF JIT implementations for x86, Sparc and PowerPC
are added in this set.
Daniel Borkmann (8):
net: bpf: add lt,le jump operations to bpf machine
x86: bpf_jit_comp: add JMP instructions for BPF JIT
sparc: bpf_jit_comp: add JMP instructions for BPF JIT
PPC: bpf_jit_comp: add JMP instructions for BPF JIT
net: bpf: add neq jump operations to bpf machine
x86: bpf_jit_comp: add JMP_NEQ instructions for BPF JIT
sparc: bpf_jit_comp: add JMP_NEQ instructions for BPF JIT
PPC: bpf_jit_comp: add JMP_NEQ instructions for BPF JIT
arch/powerpc/net/bpf_jit.h | 1 +
arch/powerpc/net/bpf_jit_comp.c | 16 ++++++++++++++++
arch/sparc/net/bpf_jit_comp.c | 12 ++++++++++++
arch/x86/net/bpf_jit_comp.c | 12 ++++++++++++
include/linux/filter.h | 6 ++++++
include/uapi/linux/filter.h | 4 ++++
net/core/filter.c | 42 +++++++++++++++++++++++++++++++++++++++++
7 files changed, 93 insertions(+)
--
1.7.11.7
^ permalink raw reply
* [PATCH net-next 1/8] net: bpf: add lt,le jump operations to bpf machine
From: Daniel Borkmann @ 2012-12-31 13:59 UTC (permalink / raw)
To: davem; +Cc: netdev
In-Reply-To: <cover.1356960070.git.dborkman@redhat.com>
This patch adds jump operations for lt (<) and le (<=) that
compare A with K resp. X in order to facilitate filter
programming with conditional jumps, since currently only
gt (>) and ge (>=) are present in the BPF machine. For
user-space filter programming / compilers, it might be good
to also have those complementary operations. They don't need
to be as ancillary, since they fit into the instruction
encoding directly. Follow-up BPF JIT patches are welcomed.
Signed-off-by: Daniel Borkmann <dborkman@redhat.com>
---
include/linux/filter.h | 4 ++++
include/uapi/linux/filter.h | 3 +++
net/core/filter.c | 28 ++++++++++++++++++++++++++++
3 files changed, 35 insertions(+)
diff --git a/include/linux/filter.h b/include/linux/filter.h
index c45eabc..36630bc 100644
--- a/include/linux/filter.h
+++ b/include/linux/filter.h
@@ -109,6 +109,10 @@ enum {
BPF_S_JMP_JGE_X,
BPF_S_JMP_JGT_K,
BPF_S_JMP_JGT_X,
+ BPF_S_JMP_JLE_K,
+ BPF_S_JMP_JLE_X,
+ BPF_S_JMP_JLT_K,
+ BPF_S_JMP_JLT_X,
BPF_S_JMP_JSET_K,
BPF_S_JMP_JSET_X,
/* Ancillary data */
diff --git a/include/uapi/linux/filter.h b/include/uapi/linux/filter.h
index 9cfde69..3ebcc2e 100644
--- a/include/uapi/linux/filter.h
+++ b/include/uapi/linux/filter.h
@@ -78,6 +78,9 @@ struct sock_fprog { /* Required for SO_ATTACH_FILTER. */
#define BPF_JGT 0x20
#define BPF_JGE 0x30
#define BPF_JSET 0x40
+#define BPF_JLT 0x50
+#define BPF_JLE 0x60
+
#define BPF_SRC(code) ((code) & 0x08)
#define BPF_K 0x00
#define BPF_X 0x08
diff --git a/net/core/filter.c b/net/core/filter.c
index 2ead2a9..2122eba 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -219,6 +219,12 @@ unsigned int sk_run_filter(const struct sk_buff *skb,
case BPF_S_JMP_JGE_K:
fentry += (A >= K) ? fentry->jt : fentry->jf;
continue;
+ case BPF_S_JMP_JLT_K:
+ fentry += (A < K) ? fentry->jt : fentry->jf;
+ continue;
+ case BPF_S_JMP_JLE_K:
+ fentry += (A <= K) ? fentry->jt : fentry->jf;
+ continue;
case BPF_S_JMP_JEQ_K:
fentry += (A == K) ? fentry->jt : fentry->jf;
continue;
@@ -231,6 +237,12 @@ unsigned int sk_run_filter(const struct sk_buff *skb,
case BPF_S_JMP_JGE_X:
fentry += (A >= X) ? fentry->jt : fentry->jf;
continue;
+ case BPF_S_JMP_JLT_X:
+ fentry += (A < X) ? fentry->jt : fentry->jf;
+ continue;
+ case BPF_S_JMP_JLE_X:
+ fentry += (A <= X) ? fentry->jt : fentry->jf;
+ continue;
case BPF_S_JMP_JEQ_X:
fentry += (A == X) ? fentry->jt : fentry->jf;
continue;
@@ -446,6 +458,10 @@ static int check_load_and_stores(struct sock_filter *filter, int flen)
case BPF_S_JMP_JGE_X:
case BPF_S_JMP_JGT_K:
case BPF_S_JMP_JGT_X:
+ case BPF_S_JMP_JLE_K:
+ case BPF_S_JMP_JLE_X:
+ case BPF_S_JMP_JLT_K:
+ case BPF_S_JMP_JLT_X:
case BPF_S_JMP_JSET_X:
case BPF_S_JMP_JSET_K:
/* a jump must set masks on targets */
@@ -528,6 +544,10 @@ int sk_chk_filter(struct sock_filter *filter, unsigned int flen)
[BPF_JMP|BPF_JGE|BPF_X] = BPF_S_JMP_JGE_X,
[BPF_JMP|BPF_JGT|BPF_K] = BPF_S_JMP_JGT_K,
[BPF_JMP|BPF_JGT|BPF_X] = BPF_S_JMP_JGT_X,
+ [BPF_JMP|BPF_JLE|BPF_K] = BPF_S_JMP_JLE_K,
+ [BPF_JMP|BPF_JLE|BPF_X] = BPF_S_JMP_JLE_X,
+ [BPF_JMP|BPF_JLT|BPF_K] = BPF_S_JMP_JLT_K,
+ [BPF_JMP|BPF_JLT|BPF_X] = BPF_S_JMP_JLT_X,
[BPF_JMP|BPF_JSET|BPF_K] = BPF_S_JMP_JSET_K,
[BPF_JMP|BPF_JSET|BPF_X] = BPF_S_JMP_JSET_X,
};
@@ -583,6 +603,10 @@ int sk_chk_filter(struct sock_filter *filter, unsigned int flen)
case BPF_S_JMP_JGE_X:
case BPF_S_JMP_JGT_K:
case BPF_S_JMP_JGT_X:
+ case BPF_S_JMP_JLE_K:
+ case BPF_S_JMP_JLE_X:
+ case BPF_S_JMP_JLT_K:
+ case BPF_S_JMP_JLT_X:
case BPF_S_JMP_JSET_X:
case BPF_S_JMP_JSET_K:
/* for conditionals both must be safe */
@@ -832,6 +856,10 @@ static void sk_decode_filter(struct sock_filter *filt, struct sock_filter *to)
[BPF_S_JMP_JGE_X] = BPF_JMP|BPF_JGE|BPF_X,
[BPF_S_JMP_JGT_K] = BPF_JMP|BPF_JGT|BPF_K,
[BPF_S_JMP_JGT_X] = BPF_JMP|BPF_JGT|BPF_X,
+ [BPF_S_JMP_JLE_K] = BPF_JMP|BPF_JLE|BPF_K,
+ [BPF_S_JMP_JLE_X] = BPF_JMP|BPF_JLE|BPF_X,
+ [BPF_S_JMP_JLT_K] = BPF_JMP|BPF_JLT|BPF_K,
+ [BPF_S_JMP_JLT_X] = BPF_JMP|BPF_JLT|BPF_X,
[BPF_S_JMP_JSET_K] = BPF_JMP|BPF_JSET|BPF_K,
[BPF_S_JMP_JSET_X] = BPF_JMP|BPF_JSET|BPF_X,
};
--
1.7.11.7
^ permalink raw reply related
* [PATCH net-next 2/8] x86: bpf_jit_comp: add JMP instructions for BPF JIT
From: Daniel Borkmann @ 2012-12-31 13:59 UTC (permalink / raw)
To: davem; +Cc: netdev, Eric Dumazet
In-Reply-To: <cover.1356960070.git.dborkman@redhat.com>
This patch is a follow-up for patch "net: bpf: add lt,le jump
operations to bpf machine" that implements BPF x86 JIT parts
for BPF JMP_LT/JMP_LE operations.
Cc: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: Daniel Borkmann <dborkman@redhat.com>
---
arch/x86/net/bpf_jit_comp.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c
index d11a470..6d6a4ce 100644
--- a/arch/x86/net/bpf_jit_comp.c
+++ b/arch/x86/net/bpf_jit_comp.c
@@ -584,10 +584,14 @@ common_load_ind: seen |= SEEN_DATAREF | SEEN_XREG;
break;
COND_SEL(BPF_S_JMP_JGT_K, X86_JA, X86_JBE);
COND_SEL(BPF_S_JMP_JGE_K, X86_JAE, X86_JB);
+ COND_SEL(BPF_S_JMP_JLT_K, X86_JB, X86_JAE);
+ COND_SEL(BPF_S_JMP_JLE_K, X86_JBE, X86_JA);
COND_SEL(BPF_S_JMP_JEQ_K, X86_JE, X86_JNE);
COND_SEL(BPF_S_JMP_JSET_K,X86_JNE, X86_JE);
COND_SEL(BPF_S_JMP_JGT_X, X86_JA, X86_JBE);
COND_SEL(BPF_S_JMP_JGE_X, X86_JAE, X86_JB);
+ COND_SEL(BPF_S_JMP_JLT_X, X86_JB, X86_JAE);
+ COND_SEL(BPF_S_JMP_JLE_X, X86_JBE, X86_JA);
COND_SEL(BPF_S_JMP_JEQ_X, X86_JE, X86_JNE);
COND_SEL(BPF_S_JMP_JSET_X,X86_JNE, X86_JE);
@@ -603,6 +607,8 @@ cond_branch: f_offset = addrs[i + filter[i].jf] - addrs[i];
switch (filter[i].code) {
case BPF_S_JMP_JGT_X:
case BPF_S_JMP_JGE_X:
+ case BPF_S_JMP_JLT_X:
+ case BPF_S_JMP_JLE_X:
case BPF_S_JMP_JEQ_X:
seen |= SEEN_XREG;
EMIT2(0x39, 0xd8); /* cmp %ebx,%eax */
@@ -618,6 +624,8 @@ cond_branch: f_offset = addrs[i + filter[i].jf] - addrs[i];
}
case BPF_S_JMP_JGT_K:
case BPF_S_JMP_JGE_K:
+ case BPF_S_JMP_JLT_K:
+ case BPF_S_JMP_JLE_K:
if (K <= 127)
EMIT3(0x83, 0xf8, K); /* cmp imm8,%eax */
else
--
1.7.11.7
^ permalink raw reply related
* [PATCH net-next 3/8] sparc: bpf_jit_comp: add JMP instructions for BPF JIT
From: Daniel Borkmann @ 2012-12-31 13:59 UTC (permalink / raw)
To: davem; +Cc: netdev
In-Reply-To: <cover.1356960070.git.dborkman@redhat.com>
This patch is a follow-up for patch "net: bpf: add lt,le jump
operations to bpf machine" that implements BPF SPARC JIT parts
for BPF JMP_LT/JMP_LE operations.
Signed-off-by: Daniel Borkmann <dborkman@redhat.com>
---
arch/sparc/net/bpf_jit_comp.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/arch/sparc/net/bpf_jit_comp.c b/arch/sparc/net/bpf_jit_comp.c
index 3109ca6..f5b4fc9 100644
--- a/arch/sparc/net/bpf_jit_comp.c
+++ b/arch/sparc/net/bpf_jit_comp.c
@@ -691,10 +691,14 @@ common_load_ind: seen |= SEEN_DATAREF | SEEN_XREG;
COND_SEL(BPF_S_JMP_JGT_K, BGU, BLEU);
COND_SEL(BPF_S_JMP_JGE_K, BGEU, BLU);
+ COND_SEL(BPF_S_JMP_JLT_K, BLU, BGEU);
+ COND_SEL(BPF_S_JMP_JLE_K, BLEU, BGU);
COND_SEL(BPF_S_JMP_JEQ_K, BE, BNE);
COND_SEL(BPF_S_JMP_JSET_K, BNE, BE);
COND_SEL(BPF_S_JMP_JGT_X, BGU, BLEU);
COND_SEL(BPF_S_JMP_JGE_X, BGEU, BLU);
+ COND_SEL(BPF_S_JMP_JLT_X, BLU, BGEU);
+ COND_SEL(BPF_S_JMP_JLE_X, BLEU, BGU);
COND_SEL(BPF_S_JMP_JEQ_X, BE, BNE);
COND_SEL(BPF_S_JMP_JSET_X, BNE, BE);
@@ -711,6 +715,8 @@ cond_branch: f_offset = addrs[i + filter[i].jf];
switch (filter[i].code) {
case BPF_S_JMP_JGT_X:
case BPF_S_JMP_JGE_X:
+ case BPF_S_JMP_JLT_X:
+ case BPF_S_JMP_JLE_X:
case BPF_S_JMP_JEQ_X:
seen |= SEEN_XREG;
emit_cmp(r_A, r_X);
@@ -722,6 +728,8 @@ cond_branch: f_offset = addrs[i + filter[i].jf];
case BPF_S_JMP_JEQ_K:
case BPF_S_JMP_JGT_K:
case BPF_S_JMP_JGE_K:
+ case BPF_S_JMP_JLT_K:
+ case BPF_S_JMP_JLE_K:
if (is_simm13(K)) {
emit_cmpi(r_A, K);
} else {
--
1.7.11.7
^ permalink raw reply related
* [PATCH net-next 5/8] net: bpf: add neq jump operations to bpf machine
From: Daniel Borkmann @ 2012-12-31 13:59 UTC (permalink / raw)
To: davem; +Cc: netdev
In-Reply-To: <cover.1356960070.git.dborkman@redhat.com>
This patch adds jump operations for neq (!=) that compare A
with K resp. X in order to facilitate filter programming with
conditional jumps, since currently only eq (==) is present in
the BPF machine. For user-space filter programming / compilers,
it might be good to also have this complementary operation.
They don't need to be as ancillary, since they fit into the
instruction encoding directly. Follow-up BPF JIT patches are
welcomed.
Signed-off-by: Daniel Borkmann <dborkman@redhat.com>
---
include/linux/filter.h | 2 ++
include/uapi/linux/filter.h | 1 +
net/core/filter.c | 14 ++++++++++++++
3 files changed, 17 insertions(+)
diff --git a/include/linux/filter.h b/include/linux/filter.h
index 36630bc..256c01f 100644
--- a/include/linux/filter.h
+++ b/include/linux/filter.h
@@ -105,6 +105,8 @@ enum {
BPF_S_JMP_JA,
BPF_S_JMP_JEQ_K,
BPF_S_JMP_JEQ_X,
+ BPF_S_JMP_JNEQ_K,
+ BPF_S_JMP_JNEQ_X,
BPF_S_JMP_JGE_K,
BPF_S_JMP_JGE_X,
BPF_S_JMP_JGT_K,
diff --git a/include/uapi/linux/filter.h b/include/uapi/linux/filter.h
index 3ebcc2e..d909a6f 100644
--- a/include/uapi/linux/filter.h
+++ b/include/uapi/linux/filter.h
@@ -80,6 +80,7 @@ struct sock_fprog { /* Required for SO_ATTACH_FILTER. */
#define BPF_JSET 0x40
#define BPF_JLT 0x50
#define BPF_JLE 0x60
+#define BPF_JNEQ 0x70
#define BPF_SRC(code) ((code) & 0x08)
#define BPF_K 0x00
diff --git a/net/core/filter.c b/net/core/filter.c
index 2122eba..b360fb3 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -228,6 +228,9 @@ unsigned int sk_run_filter(const struct sk_buff *skb,
case BPF_S_JMP_JEQ_K:
fentry += (A == K) ? fentry->jt : fentry->jf;
continue;
+ case BPF_S_JMP_JNEQ_K:
+ fentry += (A != K) ? fentry->jt : fentry->jf;
+ continue;
case BPF_S_JMP_JSET_K:
fentry += (A & K) ? fentry->jt : fentry->jf;
continue;
@@ -246,6 +249,9 @@ unsigned int sk_run_filter(const struct sk_buff *skb,
case BPF_S_JMP_JEQ_X:
fentry += (A == X) ? fentry->jt : fentry->jf;
continue;
+ case BPF_S_JMP_JNEQ_X:
+ fentry += (A != X) ? fentry->jt : fentry->jf;
+ continue;
case BPF_S_JMP_JSET_X:
fentry += (A & X) ? fentry->jt : fentry->jf;
continue;
@@ -454,6 +460,8 @@ static int check_load_and_stores(struct sock_filter *filter, int flen)
break;
case BPF_S_JMP_JEQ_K:
case BPF_S_JMP_JEQ_X:
+ case BPF_S_JMP_JNEQ_K:
+ case BPF_S_JMP_JNEQ_X:
case BPF_S_JMP_JGE_K:
case BPF_S_JMP_JGE_X:
case BPF_S_JMP_JGT_K:
@@ -540,6 +548,8 @@ int sk_chk_filter(struct sock_filter *filter, unsigned int flen)
[BPF_JMP|BPF_JA] = BPF_S_JMP_JA,
[BPF_JMP|BPF_JEQ|BPF_K] = BPF_S_JMP_JEQ_K,
[BPF_JMP|BPF_JEQ|BPF_X] = BPF_S_JMP_JEQ_X,
+ [BPF_JMP|BPF_JNEQ|BPF_K] = BPF_S_JMP_JNEQ_K,
+ [BPF_JMP|BPF_JNEQ|BPF_X] = BPF_S_JMP_JNEQ_X,
[BPF_JMP|BPF_JGE|BPF_K] = BPF_S_JMP_JGE_K,
[BPF_JMP|BPF_JGE|BPF_X] = BPF_S_JMP_JGE_X,
[BPF_JMP|BPF_JGT|BPF_K] = BPF_S_JMP_JGT_K,
@@ -599,6 +609,8 @@ int sk_chk_filter(struct sock_filter *filter, unsigned int flen)
break;
case BPF_S_JMP_JEQ_K:
case BPF_S_JMP_JEQ_X:
+ case BPF_S_JMP_JNEQ_K:
+ case BPF_S_JMP_JNEQ_X:
case BPF_S_JMP_JGE_K:
case BPF_S_JMP_JGE_X:
case BPF_S_JMP_JGT_K:
@@ -852,6 +864,8 @@ static void sk_decode_filter(struct sock_filter *filt, struct sock_filter *to)
[BPF_S_JMP_JA] = BPF_JMP|BPF_JA,
[BPF_S_JMP_JEQ_K] = BPF_JMP|BPF_JEQ|BPF_K,
[BPF_S_JMP_JEQ_X] = BPF_JMP|BPF_JEQ|BPF_X,
+ [BPF_S_JMP_JNEQ_K] = BPF_JMP|BPF_JNEQ|BPF_K,
+ [BPF_S_JMP_JNEQ_X] = BPF_JMP|BPF_JNEQ|BPF_X,
[BPF_S_JMP_JGE_K] = BPF_JMP|BPF_JGE|BPF_K,
[BPF_S_JMP_JGE_X] = BPF_JMP|BPF_JGE|BPF_X,
[BPF_S_JMP_JGT_K] = BPF_JMP|BPF_JGT|BPF_K,
--
1.7.11.7
^ permalink raw reply related
* [PATCH net-next 4/8] PPC: bpf_jit_comp: add JMP instructions for BPF JIT
From: Daniel Borkmann @ 2012-12-31 13:59 UTC (permalink / raw)
To: davem; +Cc: netdev, Matt Evans
In-Reply-To: <cover.1356960070.git.dborkman@redhat.com>
This patch is a follow-up for patch "net: bpf: add lt,le jump
operations to bpf machine" that implements BPF PowerPC JIT parts
for BPF JMP_LT/JMP_LE operations.
Cc: Matt Evans <matt@ozlabs.org>
Signed-off-by: Daniel Borkmann <dborkman@redhat.com>
---
arch/powerpc/net/bpf_jit.h | 1 +
arch/powerpc/net/bpf_jit_comp.c | 12 ++++++++++++
2 files changed, 13 insertions(+)
diff --git a/arch/powerpc/net/bpf_jit.h b/arch/powerpc/net/bpf_jit.h
index 8a5dfaf..f105b3b 100644
--- a/arch/powerpc/net/bpf_jit.h
+++ b/arch/powerpc/net/bpf_jit.h
@@ -221,6 +221,7 @@ static inline bool is_nearbranch(int offset)
#define COND_EQ (CR0_EQ | COND_CMP_TRUE)
#define COND_NE (CR0_EQ | COND_CMP_FALSE)
#define COND_LT (CR0_LT | COND_CMP_TRUE)
+#define COND_LE (CR0_GT | COND_CMP_FALSE)
#define SEEN_DATAREF 0x10000 /* might call external helpers */
#define SEEN_XREG 0x20000 /* X reg is used */
diff --git a/arch/powerpc/net/bpf_jit_comp.c b/arch/powerpc/net/bpf_jit_comp.c
index e834f1e..46b4d21 100644
--- a/arch/powerpc/net/bpf_jit_comp.c
+++ b/arch/powerpc/net/bpf_jit_comp.c
@@ -484,6 +484,14 @@ static int bpf_jit_build_body(struct sk_filter *fp, u32 *image,
case BPF_S_JMP_JGE_X:
true_cond = COND_GE;
goto cond_branch;
+ case BPF_S_JMP_JLT_K:
+ case BPF_S_JMP_JLT_X:
+ true_cond = COND_LT;
+ goto cond_branch;
+ case BPF_S_JMP_JLE_K:
+ case BPF_S_JMP_JLE_X:
+ true_cond = COND_LE;
+ goto cond_branch;
case BPF_S_JMP_JEQ_K:
case BPF_S_JMP_JEQ_X:
true_cond = COND_EQ;
@@ -503,6 +511,8 @@ static int bpf_jit_build_body(struct sk_filter *fp, u32 *image,
switch (filter[i].code) {
case BPF_S_JMP_JGT_X:
case BPF_S_JMP_JGE_X:
+ case BPF_S_JMP_JLT_X:
+ case BPF_S_JMP_JLE_X:
case BPF_S_JMP_JEQ_X:
ctx->seen |= SEEN_XREG;
PPC_CMPLW(r_A, r_X);
@@ -514,6 +524,8 @@ static int bpf_jit_build_body(struct sk_filter *fp, u32 *image,
case BPF_S_JMP_JEQ_K:
case BPF_S_JMP_JGT_K:
case BPF_S_JMP_JGE_K:
+ case BPF_S_JMP_JLT_K:
+ case BPF_S_JMP_JLE_K:
if (K < 32768)
PPC_CMPLWI(r_A, K);
else {
--
1.7.11.7
^ permalink raw reply related
* [PATCH net-next 8/8] PPC: bpf_jit_comp: add JMP_NEQ instructions for BPF JIT
From: Daniel Borkmann @ 2012-12-31 13:59 UTC (permalink / raw)
To: davem; +Cc: netdev, Matt Evans
In-Reply-To: <cover.1356960070.git.dborkman@redhat.com>
This patch is a follow-up for patch "net: bpf: add neq jump
operations to bpf machine" that implements BPF PowerPC JIT
parts for the BPF JMP_NEQ operation.
Cc: Matt Evans <matt@ozlabs.org>
Signed-off-by: Daniel Borkmann <dborkman@redhat.com>
---
arch/powerpc/net/bpf_jit_comp.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/arch/powerpc/net/bpf_jit_comp.c b/arch/powerpc/net/bpf_jit_comp.c
index 46b4d21..4b9ee59 100644
--- a/arch/powerpc/net/bpf_jit_comp.c
+++ b/arch/powerpc/net/bpf_jit_comp.c
@@ -496,6 +496,8 @@ static int bpf_jit_build_body(struct sk_filter *fp, u32 *image,
case BPF_S_JMP_JEQ_X:
true_cond = COND_EQ;
goto cond_branch;
+ case BPF_S_JMP_JNEQ_K:
+ case BPF_S_JMP_JNEQ_X:
case BPF_S_JMP_JSET_K:
case BPF_S_JMP_JSET_X:
true_cond = COND_NE;
@@ -514,6 +516,7 @@ static int bpf_jit_build_body(struct sk_filter *fp, u32 *image,
case BPF_S_JMP_JLT_X:
case BPF_S_JMP_JLE_X:
case BPF_S_JMP_JEQ_X:
+ case BPF_S_JMP_JNEQ_X:
ctx->seen |= SEEN_XREG;
PPC_CMPLW(r_A, r_X);
break;
@@ -522,6 +525,7 @@ static int bpf_jit_build_body(struct sk_filter *fp, u32 *image,
PPC_AND_DOT(r_scratch1, r_A, r_X);
break;
case BPF_S_JMP_JEQ_K:
+ case BPF_S_JMP_JNEQ_K:
case BPF_S_JMP_JGT_K:
case BPF_S_JMP_JGE_K:
case BPF_S_JMP_JLT_K:
--
1.7.11.7
^ permalink raw reply related
* [PATCH net-next 7/8] sparc: bpf_jit_comp: add JMP_NEQ instructions for BPF JIT
From: Daniel Borkmann @ 2012-12-31 13:59 UTC (permalink / raw)
To: davem; +Cc: netdev
In-Reply-To: <cover.1356960070.git.dborkman@redhat.com>
This patch is a follow-up for patch "net: bpf: add neq jump
operations to bpf machine" that implements BPF Sparc JIT parts
for the BPF JMP_NEQ operation.
Signed-off-by: Daniel Borkmann <dborkman@redhat.com>
---
arch/sparc/net/bpf_jit_comp.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/arch/sparc/net/bpf_jit_comp.c b/arch/sparc/net/bpf_jit_comp.c
index f5b4fc9..5da318c 100644
--- a/arch/sparc/net/bpf_jit_comp.c
+++ b/arch/sparc/net/bpf_jit_comp.c
@@ -694,12 +694,14 @@ common_load_ind: seen |= SEEN_DATAREF | SEEN_XREG;
COND_SEL(BPF_S_JMP_JLT_K, BLU, BGEU);
COND_SEL(BPF_S_JMP_JLE_K, BLEU, BGU);
COND_SEL(BPF_S_JMP_JEQ_K, BE, BNE);
+ COND_SEL(BPF_S_JMP_JNEQ_K, BNE, BE);
COND_SEL(BPF_S_JMP_JSET_K, BNE, BE);
COND_SEL(BPF_S_JMP_JGT_X, BGU, BLEU);
COND_SEL(BPF_S_JMP_JGE_X, BGEU, BLU);
COND_SEL(BPF_S_JMP_JLT_X, BLU, BGEU);
COND_SEL(BPF_S_JMP_JLE_X, BLEU, BGU);
COND_SEL(BPF_S_JMP_JEQ_X, BE, BNE);
+ COND_SEL(BPF_S_JMP_JNEQ_X, BNE, BE);
COND_SEL(BPF_S_JMP_JSET_X, BNE, BE);
cond_branch: f_offset = addrs[i + filter[i].jf];
@@ -718,6 +720,7 @@ cond_branch: f_offset = addrs[i + filter[i].jf];
case BPF_S_JMP_JLT_X:
case BPF_S_JMP_JLE_X:
case BPF_S_JMP_JEQ_X:
+ case BPF_S_JMP_JNEQ_X:
seen |= SEEN_XREG;
emit_cmp(r_A, r_X);
break;
@@ -726,6 +729,7 @@ cond_branch: f_offset = addrs[i + filter[i].jf];
emit_btst(r_A, r_X);
break;
case BPF_S_JMP_JEQ_K:
+ case BPF_S_JMP_JNEQ_K:
case BPF_S_JMP_JGT_K:
case BPF_S_JMP_JGE_K:
case BPF_S_JMP_JLT_K:
--
1.7.11.7
^ permalink raw reply related
* Re: [PATCH 10/14] atm: Removed redundant check on unsigned variable
From: chas williams - CONTRACTOR @ 2012-12-31 15:18 UTC (permalink / raw)
To: Tushar Behera; +Cc: linux-kernel, patches, linux-atm-general, netdev
In-Reply-To: <50DD2B34.9070905@linaro.org>
Acked-by: chas williams - CONTRACTOR <chas@cmf.nrl.navy.mil>
On Fri, 28 Dec 2012 10:46:36 +0530
Tushar Behera <tushar.behera@linaro.org> wrote:
> Ping.
>
> On 11/16/2012 12:20 PM, Tushar Behera wrote:
> > No need to check whether unsigned variable is less than 0.
> >
> > CC: Chas Williams <chas@cmf.nrl.navy.mil>
> > CC: linux-atm-general@lists.sourceforge.net
> > CC: netdev@vger.kernel.org
> > Signed-off-by: Tushar Behera <tushar.behera@linaro.org>
> > ---
> > drivers/atm/fore200e.c | 2 +-
> > 1 files changed, 1 insertions(+), 1 deletions(-)
> >
> > diff --git a/drivers/atm/fore200e.c b/drivers/atm/fore200e.c
> > index 361f5ae..fdd3fe7 100644
> > --- a/drivers/atm/fore200e.c
> > +++ b/drivers/atm/fore200e.c
> > @@ -972,7 +972,7 @@ int bsq_audit(int where, struct host_bsq* bsq, int scheme, int magn)
> > where, scheme, magn, buffer->index, buffer->scheme);
> > }
> >
> > - if ((buffer->index < 0) || (buffer->index >= fore200e_rx_buf_nbr[ scheme ][ magn ])) {
> > + if (buffer->index >= fore200e_rx_buf_nbr[ scheme ][ magn ]) {
> > printk(FORE200E "bsq_audit(%d): queue %d.%d, out of range buffer index = %ld !\n",
> > where, scheme, magn, buffer->index);
> > }
> >
>
>
^ permalink raw reply
* [PATCH RFC 15/15] via-rhine: add helper (reduce type-unsafe void * assignments).
From: Andreas Mohr @ 2012-12-31 15:25 UTC (permalink / raw)
To: andim2; +Cc: Roger Luethi, netdev, Francois Romieu
In-Reply-To: <1356967549-5056-1-git-send-email-andi@lisas.de>
From: Andreas Mohr <andim2@users.sf.net>
Signed-off-by: Andreas Mohr <andim2@users.sf.net>
---
drivers/net/ethernet/via/via-rhine.c | 15 +++++++++++----
1 files changed, 11 insertions(+), 4 deletions(-)
diff --git a/drivers/net/ethernet/via/via-rhine.c b/drivers/net/ethernet/via/via-rhine.c
index 051bb95..dd4fd04 100644
--- a/drivers/net/ethernet/via/via-rhine.c
+++ b/drivers/net/ethernet/via/via-rhine.c
@@ -2411,10 +2411,17 @@ static int rhine_close(struct net_device *dev)
return 0;
}
+/* Cast-only helper (try to minimize type-unsafe void * assignments). */
+/* TODO: could be doing the same thing for netdev_priv() use. */
+static inline struct net_device *
+rhine_to_net_device(struct pci_dev *pdev)
+{
+ return pci_get_drvdata(pdev);
+}
static void rhine_remove_one(struct pci_dev *pdev)
{
- struct net_device *dev = pci_get_drvdata(pdev);
+ struct net_device *dev = rhine_to_net_device(pdev);
struct rhine_private *rp = netdev_priv(dev);
unregister_netdev(dev);
@@ -2430,7 +2437,7 @@ static void rhine_remove_one(struct pci_dev *pdev)
static void
rhine_shutdown_and_keep_wol(struct pci_dev *pdev)
{
- struct net_device *dev = pci_get_drvdata(pdev);
+ struct net_device *dev = rhine_to_net_device(pdev);
struct rhine_private *rp = netdev_priv(dev);
void __iomem *ioaddr = rp->base;
@@ -2489,7 +2496,7 @@ rhine_shutdown_and_keep_wol(struct pci_dev *pdev)
static int rhine_suspend(struct device *device)
{
struct pci_dev *pdev = to_pci_dev(device);
- struct net_device *dev = pci_get_drvdata(pdev);
+ struct net_device *dev = rhine_to_net_device(pdev);
struct rhine_private *rp = netdev_priv(dev);
if (!netif_running(dev))
@@ -2509,7 +2516,7 @@ static int rhine_suspend(struct device *device)
static int rhine_resume(struct device *device)
{
struct pci_dev *pdev = to_pci_dev(device);
- struct net_device *dev = pci_get_drvdata(pdev);
+ struct net_device *dev = rhine_to_net_device(pdev);
struct rhine_private *rp = netdev_priv(dev);
/*
--
1.7.2.5
^ permalink raw reply related
* [PATCH RFC 01/15] via-rhine: YARB: fix broken resume of ifdown case (NetworkManager).
From: Andreas Mohr @ 2012-12-31 15:25 UTC (permalink / raw)
To: andim2; +Cc: Roger Luethi, netdev, Francois Romieu
In-Reply-To: <1356967549-5056-1-git-send-email-andi@lisas.de>
From: Andreas Mohr <andim2@users.sf.net>
Well, it's probably not a *breakage* this time after all
(handling probably was never fully correct before).
resume() in the case of an ifdown iface
(as e.g. usually done by NetworkManager)
did not restore the card to proper full post-probe() card state
(see resume()s !netif_running() check),
thereby causing the subsequent iface open() as done by NM to fail,
since that one requires full post-probe() card state
(e.g. PHY available) yet the PHY was not available
(at least in the case of full-shutdown S2R).
Some related NetworkManager links are
https://bugs.mageia.org/show_bug.cgi?id=7498
http://crunchbang.org/forums/viewtopic.php?id=15169
https://bugzilla.redhat.com/show_bug.cgi?id=477964
https://bugzilla.redhat.com/show_bug.cgi?id=549089
Suspend/resume behaviour verified with both NM running and not running,
and with both mem (S2R) and standby.
Tested on Neoware CA10 (VIA C3), will also test on EPoX 8K5A2+.
Signed-off-by: Andreas Mohr <andim2@users.sf.net>
---
drivers/net/ethernet/via/via-rhine.c | 13 ++++++++++---
1 files changed, 10 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/via/via-rhine.c b/drivers/net/ethernet/via/via-rhine.c
index 7992b3e..5facb0b 100644
--- a/drivers/net/ethernet/via/via-rhine.c
+++ b/drivers/net/ethernet/via/via-rhine.c
@@ -2324,13 +2324,20 @@ static int rhine_resume(struct device *device)
struct net_device *dev = pci_get_drvdata(pdev);
struct rhine_private *rp = netdev_priv(dev);
- if (!netif_running(dev))
- return 0;
-
#ifdef USE_MMIO
enable_mmio(rp->pioaddr, rp->quirks);
#endif
+ /*
+ * FIXME: some power calls here are being done
+ * internally in netdev setup parts below, too -
+ * should be corrected eventually.
+ */
rhine_power_init(dev);
+ rhine_hw_init(dev, rp->pioaddr);
+
+ if (!netif_running(dev))
+ return 0;
+
free_tbufs(dev);
free_rbufs(dev);
alloc_tbufs(dev);
--
1.7.2.5
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox