* [PATCH net-next 0/3] bnx2x: Support new Multi-function modes
From: Yuval Mintz @ 2014-09-17 13:24 UTC (permalink / raw)
To: davem, netdev; +Cc: Ariel.Elior, Yuval Mintz
This patch series adds support for 2 new Multi-function modes -
Unified Fabric Port [UFP] as well as nic partitioning 1.5 [NPAR1.5].
With the addition of the new multi-function modes, the series also
revises some of the storage-related multi-function macros.
[Do notice this series has several small issues with checkpatch]
Dave,
Please consider applying this series to `net-next'.
Thanks,
Yuval
Dmitry Kravkov (1):
bnx2x: Changes with storage & MAC macros
Yuval Mintz (2):
bnx2x: New multi-function mode: UFP
bnx2x: Add a fallback multi-function mode NPAR1.5
drivers/net/ethernet/broadcom/bnx2x/bnx2x.h | 53 +++++-
drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | 12 +-
drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h | 14 +-
.../net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c | 2 +-
drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h | 28 +--
drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 204 ++++++++++++++++-----
drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c | 41 ++++-
drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h | 23 +++
8 files changed, 296 insertions(+), 81 deletions(-)
--
1.8.3.1
^ permalink raw reply
* [PATCH net-next 1/3] bnx2x: Changes with storage & MAC macros
From: Yuval Mintz @ 2014-09-17 13:24 UTC (permalink / raw)
To: davem, netdev; +Cc: Ariel.Elior, Dmitry Kravkov, Yuval Mintz
In-Reply-To: <1410960278-32064-1-git-send-email-Yuval.Mintz@qlogic.com>
From: Dmitry Kravkov <Dmitry.Kravkov@qlogic.com>
Rearrange macros to query for storage-only modes in different MF environment.
Improves the readibility and maintainability of the code. E.g.:
- if (IS_MF_STORAGE_SD(bp) || IS_MF_FCOE_AFEX(bp))
+ if (IS_MF_STORAGE_ONLY(bp))
In addition, this removes the need for bnx2x_is_valid_ether_addr().
Signed-off-by: Dmitry Kravkov <Dmitry.Kravkov@qlogic.com>
Signed-off-by: Yuval Mintz <Yuval.Mintz@qlogic.com>
Signed-off-by: Ariel Elior <Ariel.Elior@qlogic.com>
---
drivers/net/ethernet/broadcom/bnx2x/bnx2x.h | 44 ++++++++++++++++++----
drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | 12 +++---
drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h | 8 ----
.../net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c | 2 +-
drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 30 ++++++---------
5 files changed, 54 insertions(+), 42 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
index 86e9451..7ecb61f 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
@@ -2361,7 +2361,7 @@ void bnx2x_igu_clear_sb_gen(struct bnx2x *bp, u8 func, u8 idu_sb_id,
#define ATTN_HARD_WIRED_MASK 0xff00
#define ATTENTION_ID 4
-#define IS_MF_STORAGE_ONLY(bp) (IS_MF_STORAGE_SD(bp) || \
+#define IS_MF_STORAGE_ONLY(bp) (IS_MF_STORAGE_PERSONALITY_ONLY(bp) || \
IS_MF_FCOE_AFEX(bp))
/* stuff added to make the code fit 80Col */
@@ -2537,14 +2537,44 @@ void bnx2x_notify_link_changed(struct bnx2x *bp);
#define IS_MF_ISCSI_SD(bp) (IS_MF_SD(bp) && BNX2X_IS_MF_SD_PROTOCOL_ISCSI(bp))
#define IS_MF_FCOE_SD(bp) (IS_MF_SD(bp) && BNX2X_IS_MF_SD_PROTOCOL_FCOE(bp))
+#define IS_MF_ISCSI_SI(bp) (IS_MF_SI(bp) && BNX2X_IS_MF_EXT_PROTOCOL_ISCSI(bp))
-#define BNX2X_MF_EXT_PROTOCOL_FCOE(bp) ((bp)->mf_ext_config & \
- MACP_FUNC_CFG_FLAGS_FCOE_OFFLOAD)
+#define IS_MF_ISCSI_ONLY(bp) (IS_MF_ISCSI_SD(bp) || IS_MF_ISCSI_SI(bp))
+
+#define BNX2X_MF_EXT_PROTOCOL_MASK \
+ (MACP_FUNC_CFG_FLAGS_ETHERNET | \
+ MACP_FUNC_CFG_FLAGS_ISCSI_OFFLOAD | \
+ MACP_FUNC_CFG_FLAGS_FCOE_OFFLOAD)
+
+#define BNX2X_MF_EXT_PROT(bp) ((bp)->mf_ext_config & \
+ BNX2X_MF_EXT_PROTOCOL_MASK)
+
+#define BNX2X_HAS_MF_EXT_PROTOCOL_FCOE(bp) \
+ (BNX2X_MF_EXT_PROT(bp) & MACP_FUNC_CFG_FLAGS_FCOE_OFFLOAD)
+
+#define BNX2X_IS_MF_EXT_PROTOCOL_FCOE(bp) \
+ (BNX2X_MF_EXT_PROT(bp) == MACP_FUNC_CFG_FLAGS_FCOE_OFFLOAD)
+
+#define BNX2X_IS_MF_EXT_PROTOCOL_ISCSI(bp) \
+ (BNX2X_MF_EXT_PROT(bp) == MACP_FUNC_CFG_FLAGS_ISCSI_OFFLOAD)
+
+#define IS_MF_FCOE_AFEX(bp) \
+ (IS_MF_AFEX(bp) && BNX2X_IS_MF_EXT_PROTOCOL_FCOE(bp))
+
+#define IS_MF_SD_STORAGE_PERSONALITY_ONLY(bp) \
+ (IS_MF_SD(bp) && \
+ (BNX2X_IS_MF_SD_PROTOCOL_ISCSI(bp) || \
+ BNX2X_IS_MF_SD_PROTOCOL_FCOE(bp)))
+
+#define IS_MF_SI_STORAGE_PERSONALITY_ONLY(bp) \
+ (IS_MF_SI(bp) && \
+ (BNX2X_IS_MF_EXT_PROTOCOL_ISCSI(bp) || \
+ BNX2X_IS_MF_EXT_PROTOCOL_FCOE(bp)))
+
+#define IS_MF_STORAGE_PERSONALITY_ONLY(bp) \
+ (IS_MF_SD_STORAGE_PERSONALITY_ONLY(bp) || \
+ IS_MF_SI_STORAGE_PERSONALITY_ONLY(bp))
-#define IS_MF_FCOE_AFEX(bp) (IS_MF_AFEX(bp) && BNX2X_MF_EXT_PROTOCOL_FCOE(bp))
-#define IS_MF_STORAGE_SD(bp) (IS_MF_SD(bp) && \
- (BNX2X_IS_MF_SD_PROTOCOL_ISCSI(bp) || \
- BNX2X_IS_MF_SD_PROTOCOL_FCOE(bp)))
#define SET_FLAG(value, mask, flag) \
do {\
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
index 6dc32ae..40beef5 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
@@ -1938,7 +1938,7 @@ void bnx2x_set_num_queues(struct bnx2x *bp)
bp->num_ethernet_queues = bnx2x_calc_num_queues(bp);
/* override in STORAGE SD modes */
- if (IS_MF_STORAGE_SD(bp) || IS_MF_FCOE_AFEX(bp))
+ if (IS_MF_STORAGE_ONLY(bp))
bp->num_ethernet_queues = 1;
/* Add special queues */
@@ -4231,14 +4231,13 @@ int bnx2x_change_mac_addr(struct net_device *dev, void *p)
struct bnx2x *bp = netdev_priv(dev);
int rc = 0;
- if (!bnx2x_is_valid_ether_addr(bp, addr->sa_data)) {
+ if (!is_valid_ether_addr(addr->sa_data)) {
BNX2X_ERR("Requested MAC address is not valid\n");
return -EINVAL;
}
- if ((IS_MF_STORAGE_SD(bp) || IS_MF_FCOE_AFEX(bp)) &&
- !is_zero_ether_addr(addr->sa_data)) {
- BNX2X_ERR("Can't configure non-zero address on iSCSI or FCoE functions in MF-SD mode\n");
+ if (IS_MF_STORAGE_ONLY(bp)) {
+ BNX2X_ERR("Can't change address on STORAGE ONLY function\n");
return -EINVAL;
}
@@ -4417,8 +4416,7 @@ static int bnx2x_alloc_fp_mem_at(struct bnx2x *bp, int index)
u8 cos;
int rx_ring_size = 0;
- if (!bp->rx_ring_size &&
- (IS_MF_STORAGE_SD(bp) || IS_MF_FCOE_AFEX(bp))) {
+ if (!bp->rx_ring_size && IS_MF_STORAGE_ONLY(bp)) {
rx_ring_size = MIN_RX_SIZE_NONTPA;
bp->rx_ring_size = rx_ring_size;
} else if (!bp->rx_ring_size) {
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h
index ac63e16..0102775 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h
@@ -1298,15 +1298,7 @@ static inline void bnx2x_update_drv_flags(struct bnx2x *bp, u32 flags, u32 set)
}
}
-static inline bool bnx2x_is_valid_ether_addr(struct bnx2x *bp, u8 *addr)
-{
- if (is_valid_ether_addr(addr) ||
- (is_zero_ether_addr(addr) &&
- (IS_MF_STORAGE_SD(bp) || IS_MF_FCOE_AFEX(bp))))
- return true;
- return false;
-}
/**
* bnx2x_fill_fw_str - Fill buffer with FW version string
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c
index 0b173ed..1edc931 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c
@@ -1852,7 +1852,7 @@ static int bnx2x_set_ringparam(struct net_device *dev,
if ((ering->rx_pending > MAX_RX_AVAIL) ||
(ering->rx_pending < (bp->disable_tpa ? MIN_RX_SIZE_NONTPA :
MIN_RX_SIZE_TPA)) ||
- (ering->tx_pending > (IS_MF_FCOE_AFEX(bp) ? 0 : MAX_TX_AVAIL)) ||
+ (ering->tx_pending > (IS_MF_STORAGE_ONLY(bp) ? 0 : MAX_TX_AVAIL)) ||
(ering->tx_pending <= MAX_SKB_FRAGS + 4)) {
DP(BNX2X_MSG_ETHTOOL, "Command parameters not supported\n");
return -EINVAL;
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
index 32e2444..82ea6b6 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
@@ -8323,13 +8323,6 @@ int bnx2x_del_all_macs(struct bnx2x *bp,
int bnx2x_set_eth_mac(struct bnx2x *bp, bool set)
{
- if (is_zero_ether_addr(bp->dev->dev_addr) &&
- (IS_MF_STORAGE_SD(bp) || IS_MF_FCOE_AFEX(bp))) {
- DP(NETIF_MSG_IFUP | NETIF_MSG_IFDOWN,
- "Ignoring Zero MAC for STORAGE SD mode\n");
- return 0;
- }
-
if (IS_PF(bp)) {
unsigned long ramrod_flags = 0;
@@ -11355,15 +11348,14 @@ static void bnx2x_get_fcoe_info(struct bnx2x *bp)
dev_info.port_hw_config[port].
fcoe_wwn_node_name_lower);
} else if (!IS_MF_SD(bp)) {
- /*
- * Read the WWN info only if the FCoE feature is enabled for
+ /* Read the WWN info only if the FCoE feature is enabled for
* this function.
*/
- if (BNX2X_MF_EXT_PROTOCOL_FCOE(bp) && !CHIP_IS_E1x(bp))
+ if (BNX2X_HAS_MF_EXT_PROTOCOL_FCOE(bp))
+ bnx2x_get_ext_wwn_info(bp, func);
+ } else {
+ if (BNX2X_IS_MF_SD_PROTOCOL_FCOE(bp) && !CHIP_IS_E1x(bp))
bnx2x_get_ext_wwn_info(bp, func);
-
- } else if (IS_MF_FCOE_SD(bp) && !CHIP_IS_E1x(bp)) {
- bnx2x_get_ext_wwn_info(bp, func);
}
BNX2X_DEV_INFO("max_fcoe_conn 0x%x\n", bp->cnic_eth_dev.max_fcoe_conn);
@@ -11401,7 +11393,7 @@ static void bnx2x_get_cnic_mac_hwinfo(struct bnx2x *bp)
* In non SD mode features configuration comes from struct
* func_ext_config.
*/
- if (!IS_MF_SD(bp) && !CHIP_IS_E1x(bp)) {
+ if (!IS_MF_SD(bp)) {
u32 cfg = MF_CFG_RD(bp, func_ext_config[func].func_cfg);
if (cfg & MACP_FUNC_CFG_FLAGS_ISCSI_OFFLOAD) {
val2 = MF_CFG_RD(bp, func_ext_config[func].
@@ -11520,7 +11512,7 @@ static void bnx2x_get_mac_hwinfo(struct bnx2x *bp)
memcpy(bp->link_params.mac_addr, bp->dev->dev_addr, ETH_ALEN);
- if (!bnx2x_is_valid_ether_addr(bp, bp->dev->dev_addr))
+ if (!is_valid_ether_addr(bp->dev->dev_addr))
dev_err(&bp->pdev->dev,
"bad Ethernet MAC address configuration: %pM\n"
"change it manually before bringing up the appropriate network interface\n",
@@ -11970,7 +11962,7 @@ static int bnx2x_init_bp(struct bnx2x *bp)
dev_err(&bp->pdev->dev, "MCP disabled, must load devices in order!\n");
bp->disable_tpa = disable_tpa;
- bp->disable_tpa |= IS_MF_STORAGE_SD(bp) || IS_MF_FCOE_AFEX(bp);
+ bp->disable_tpa |= !!IS_MF_STORAGE_ONLY(bp);
/* Reduce memory usage in kdump environment by disabling TPA */
bp->disable_tpa |= is_kdump_kernel();
@@ -11990,7 +11982,7 @@ static int bnx2x_init_bp(struct bnx2x *bp)
bp->mrrs = mrrs;
- bp->tx_ring_size = IS_MF_FCOE_AFEX(bp) ? 0 : MAX_TX_AVAIL;
+ bp->tx_ring_size = IS_MF_STORAGE_ONLY(bp) ? 0 : MAX_TX_AVAIL;
if (IS_VF(bp))
bp->rx_ring_size = MAX_RX_AVAIL;
@@ -12310,7 +12302,7 @@ void bnx2x_set_rx_mode_inner(struct bnx2x *bp)
bp->rx_mode = rx_mode;
/* handle ISCSI SD mode */
- if (IS_MF_ISCSI_SD(bp))
+ if (IS_MF_ISCSI_ONLY(bp))
bp->rx_mode = BNX2X_RX_MODE_NONE;
/* Schedule the rx_mode command */
@@ -12417,7 +12409,7 @@ static int bnx2x_validate_addr(struct net_device *dev)
if (IS_VF(bp))
bnx2x_sample_bulletin(bp);
- if (!bnx2x_is_valid_ether_addr(bp, dev->dev_addr)) {
+ if (!is_valid_ether_addr(dev->dev_addr)) {
BNX2X_ERR("Non-valid Ethernet address\n");
return -EADDRNOTAVAIL;
}
--
1.8.3.1
^ permalink raw reply related
* [PATCH net-next 2/3] bnx2x: New multi-function mode: UFP
From: Yuval Mintz @ 2014-09-17 13:24 UTC (permalink / raw)
To: davem, netdev; +Cc: Ariel.Elior, Yuval Mintz, Dmitry Kravkov
In-Reply-To: <1410960278-32064-1-git-send-email-Yuval.Mintz@qlogic.com>
Add support for a new multi-function mode based on the Unified Fabric Port
system specifications.
Support includes configuration of:
1. Outer vlan tags.
2. Bandwidth settings.
3. Virtual link enable/disable.
Signed-off-by: Yuval Mintz <Yuval.Mintz@qlogic.com>
Signed-off-by: Dmitry Kravkov <Dmitry.Kravkov@qlogic.com>
Signed-off-by: Ariel Elior <Ariel.Elior@qlogic.com>
---
drivers/net/ethernet/broadcom/bnx2x/bnx2x.h | 8 ++
drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h | 6 ++
drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h | 11 ++
drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 129 ++++++++++++++++++++---
drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c | 41 ++++++-
drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h | 23 ++++
6 files changed, 200 insertions(+), 18 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
index 7ecb61f..10291df 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
@@ -1448,6 +1448,11 @@ struct bnx2x_fp_stats {
struct bnx2x_eth_q_stats_old eth_q_stats_old;
};
+enum {
+ SUB_MF_MODE_UNKNOWN = 0,
+ SUB_MF_MODE_UFP,
+};
+
struct bnx2x {
/* Fields used in the tx and intr/napi performance paths
* are grouped together in the beginning of the structure
@@ -1659,6 +1664,9 @@ struct bnx2x {
#define IS_MF_SI(bp) (bp->mf_mode == MULTI_FUNCTION_SI)
#define IS_MF_SD(bp) (bp->mf_mode == MULTI_FUNCTION_SD)
#define IS_MF_AFEX(bp) (bp->mf_mode == MULTI_FUNCTION_AFEX)
+ u8 mf_sub_mode;
+#define IS_MF_UFP(bp) (IS_MF_SD(bp) && \
+ bp->mf_sub_mode == SUB_MF_MODE_UFP)
u8 wol;
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h
index 0102775..adcacda 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h
@@ -936,6 +936,12 @@ static inline int bnx2x_func_start(struct bnx2x *bp)
start_params->gre_tunnel_type = IPGRE_TUNNEL;
start_params->inner_gre_rss_en = 1;
+ if (IS_MF_UFP(bp) && BNX2X_IS_MF_SD_PROTOCOL_FCOE(bp)) {
+ start_params->class_fail_ethtype = ETH_P_FIP;
+ start_params->class_fail = 1;
+ start_params->no_added_tags = 1;
+ }
+
return bnx2x_func_state_change(bp, &func_params);
}
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h
index 3e0621a..3295863 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h
@@ -859,6 +859,7 @@ struct shared_feat_cfg { /* NVRAM Offset */
#define SHARED_FEAT_CFG_FORCE_SF_MODE_SPIO4 0x00000200
#define SHARED_FEAT_CFG_FORCE_SF_MODE_SWITCH_INDEPT 0x00000300
#define SHARED_FEAT_CFG_FORCE_SF_MODE_AFEX_MODE 0x00000400
+ #define SHARED_FEAT_CFG_FORCE_SF_MODE_UFP_MODE 0x00000600
/* The interval in seconds between sending LLDP packets. Set to zero
to disable the feature */
@@ -1268,6 +1269,10 @@ struct drv_func_mb {
#define DRV_MSG_CODE_GET_UPGRADE_KEY 0x81000000
#define DRV_MSG_CODE_GET_MANUF_KEY 0x82000000
#define DRV_MSG_CODE_LOAD_L2B_PRAM 0x90000000
+ #define DRV_MSG_CODE_OEM_OK 0x00010000
+ #define DRV_MSG_CODE_OEM_FAILURE 0x00020000
+ #define DRV_MSG_CODE_OEM_UPDATE_SVID_OK 0x00030000
+ #define DRV_MSG_CODE_OEM_UPDATE_SVID_FAILURE 0x00040000
/*
* The optic module verification command requires bootcode
* v5.0.6 or later, te specific optic module verification command
@@ -1423,6 +1428,12 @@ struct drv_func_mb {
#define DRV_STATUS_SET_MF_BW 0x00000004
#define DRV_STATUS_LINK_EVENT 0x00000008
+ #define DRV_STATUS_OEM_EVENT_MASK 0x00000070
+ #define DRV_STATUS_OEM_DISABLE_ENABLE_PF 0x00000010
+ #define DRV_STATUS_OEM_BANDWIDTH_ALLOCATION 0x00000020
+
+ #define DRV_STATUS_OEM_UPDATE_SVID 0x00000080
+
#define DRV_STATUS_DCC_EVENT_MASK 0x0000ff00
#define DRV_STATUS_DCC_DISABLE_ENABLE_PF 0x00000100
#define DRV_STATUS_DCC_BANDWIDTH_ALLOCATION 0x00000200
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
index 82ea6b6..da6c5bb 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
@@ -2905,6 +2905,57 @@ static void bnx2x_handle_afex_cmd(struct bnx2x *bp, u32 cmd)
}
}
+static void bnx2x_handle_update_svid_cmd(struct bnx2x *bp)
+{
+ struct bnx2x_func_switch_update_params *switch_update_params;
+ struct bnx2x_func_state_params func_params;
+
+ memset(&func_params, 0, sizeof(struct bnx2x_func_state_params));
+ switch_update_params = &func_params.params.switch_update;
+ func_params.f_obj = &bp->func_obj;
+ func_params.cmd = BNX2X_F_CMD_SWITCH_UPDATE;
+
+ if (IS_MF_UFP(bp)) {
+ int func = BP_ABS_FUNC(bp);
+ u32 val;
+
+ /* Re-learn the S-tag from shmem */
+ val = MF_CFG_RD(bp, func_mf_config[func].e1hov_tag) &
+ FUNC_MF_CFG_E1HOV_TAG_MASK;
+ if (val != FUNC_MF_CFG_E1HOV_TAG_DEFAULT) {
+ bp->mf_ov = val;
+ } else {
+ BNX2X_ERR("Got an SVID event, but no tag is configured in shmem\n");
+ goto fail;
+ }
+
+ /* Configure new S-tag in LLH */
+ REG_WR(bp, NIG_REG_LLH0_FUNC_VLAN_ID + BP_PORT(bp) * 8,
+ bp->mf_ov);
+
+ /* Send Ramrod to update FW of change */
+ __set_bit(BNX2X_F_UPDATE_SD_VLAN_TAG_CHNG,
+ &switch_update_params->changes);
+ switch_update_params->vlan = bp->mf_ov;
+
+ if (bnx2x_func_state_change(bp, &func_params) < 0) {
+ BNX2X_ERR("Failed to configure FW of S-tag Change to %02x\n",
+ bp->mf_ov);
+ goto fail;
+ }
+
+ DP(BNX2X_MSG_MCP, "Configured S-tag %02x\n", bp->mf_ov);
+
+ bnx2x_fw_command(bp, DRV_MSG_CODE_OEM_UPDATE_SVID_OK, 0);
+
+ return;
+ }
+
+ /* not supported by SW yet */
+fail:
+ bnx2x_fw_command(bp, DRV_MSG_CODE_OEM_UPDATE_SVID_FAILURE, 0);
+}
+
static void bnx2x_pmf_update(struct bnx2x *bp)
{
int port = BP_PORT(bp);
@@ -3297,7 +3348,8 @@ static void bnx2x_e1h_enable(struct bnx2x *bp)
{
int port = BP_PORT(bp);
- REG_WR(bp, NIG_REG_LLH0_FUNC_EN + port*8, 1);
+ if (!(IS_MF_UFP(bp) && BNX2X_IS_MF_SD_PROTOCOL_FCOE(bp)))
+ REG_WR(bp, NIG_REG_LLH0_FUNC_EN + port * 8, 1);
/* Tx queue should be only re-enabled */
netif_tx_wake_all_queues(bp->dev);
@@ -3652,14 +3704,30 @@ out:
ethver, iscsiver, fcoever);
}
-static void bnx2x_dcc_event(struct bnx2x *bp, u32 dcc_event)
+static void bnx2x_oem_event(struct bnx2x *bp, u32 event)
{
- DP(BNX2X_MSG_MCP, "dcc_event 0x%x\n", dcc_event);
+ u32 cmd_ok, cmd_fail;
+
+ /* sanity */
+ if (event & DRV_STATUS_DCC_EVENT_MASK &&
+ event & DRV_STATUS_OEM_EVENT_MASK) {
+ BNX2X_ERR("Received simultaneous events %08x\n", event);
+ return;
+ }
- if (dcc_event & DRV_STATUS_DCC_DISABLE_ENABLE_PF) {
+ if (event & DRV_STATUS_DCC_EVENT_MASK) {
+ cmd_fail = DRV_MSG_CODE_DCC_FAILURE;
+ cmd_ok = DRV_MSG_CODE_DCC_OK;
+ } else /* if (event & DRV_STATUS_OEM_EVENT_MASK) */ {
+ cmd_fail = DRV_MSG_CODE_OEM_FAILURE;
+ cmd_ok = DRV_MSG_CODE_OEM_OK;
+ }
- /*
- * This is the only place besides the function initialization
+ DP(BNX2X_MSG_MCP, "oem_event 0x%x\n", event);
+
+ if (event & (DRV_STATUS_DCC_DISABLE_ENABLE_PF |
+ DRV_STATUS_OEM_DISABLE_ENABLE_PF)) {
+ /* This is the only place besides the function initialization
* where the bp->flags can change so it is done without any
* locks
*/
@@ -3674,18 +3742,22 @@ static void bnx2x_dcc_event(struct bnx2x *bp, u32 dcc_event)
bnx2x_e1h_enable(bp);
}
- dcc_event &= ~DRV_STATUS_DCC_DISABLE_ENABLE_PF;
+ event &= ~(DRV_STATUS_DCC_DISABLE_ENABLE_PF |
+ DRV_STATUS_OEM_DISABLE_ENABLE_PF);
}
- if (dcc_event & DRV_STATUS_DCC_BANDWIDTH_ALLOCATION) {
+
+ if (event & (DRV_STATUS_DCC_BANDWIDTH_ALLOCATION |
+ DRV_STATUS_OEM_BANDWIDTH_ALLOCATION)) {
bnx2x_config_mf_bw(bp);
- dcc_event &= ~DRV_STATUS_DCC_BANDWIDTH_ALLOCATION;
+ event &= ~(DRV_STATUS_DCC_BANDWIDTH_ALLOCATION |
+ DRV_STATUS_OEM_BANDWIDTH_ALLOCATION);
}
/* Report results to MCP */
- if (dcc_event)
- bnx2x_fw_command(bp, DRV_MSG_CODE_DCC_FAILURE, 0);
+ if (event)
+ bnx2x_fw_command(bp, cmd_fail, 0);
else
- bnx2x_fw_command(bp, DRV_MSG_CODE_DCC_OK, 0);
+ bnx2x_fw_command(bp, cmd_ok, 0);
}
/* must be called under the spq lock */
@@ -4167,9 +4239,12 @@ static void bnx2x_attn_int_deasserted3(struct bnx2x *bp, u32 attn)
func_mf_config[BP_ABS_FUNC(bp)].config);
val = SHMEM_RD(bp,
func_mb[BP_FW_MB_IDX(bp)].drv_status);
- if (val & DRV_STATUS_DCC_EVENT_MASK)
- bnx2x_dcc_event(bp,
- (val & DRV_STATUS_DCC_EVENT_MASK));
+
+ if (val & (DRV_STATUS_DCC_EVENT_MASK |
+ DRV_STATUS_OEM_EVENT_MASK))
+ bnx2x_oem_event(bp,
+ (val & (DRV_STATUS_DCC_EVENT_MASK |
+ DRV_STATUS_OEM_EVENT_MASK)));
if (val & DRV_STATUS_SET_MF_BW)
bnx2x_set_mf_bw(bp);
@@ -4195,6 +4270,10 @@ static void bnx2x_attn_int_deasserted3(struct bnx2x *bp, u32 attn)
val & DRV_STATUS_AFEX_EVENT_MASK);
if (val & DRV_STATUS_EEE_NEGOTIATION_RESULTS)
bnx2x_handle_eee_event(bp);
+
+ if (val & DRV_STATUS_OEM_UPDATE_SVID)
+ bnx2x_handle_update_svid_cmd(bp);
+
if (bp->link_vars.periodic_flags &
PERIODIC_FLAGS_LINK_EVENT) {
/* sync with link */
@@ -7930,8 +8009,11 @@ static int bnx2x_init_hw_func(struct bnx2x *bp)
REG_WR(bp, CFC_REG_WEAK_ENABLE_PF, 1);
if (IS_MF(bp)) {
- REG_WR(bp, NIG_REG_LLH0_FUNC_EN + port*8, 1);
- REG_WR(bp, NIG_REG_LLH0_FUNC_VLAN_ID + port*8, bp->mf_ov);
+ if (!(IS_MF_UFP(bp) && BNX2X_IS_MF_SD_PROTOCOL_FCOE(bp))) {
+ REG_WR(bp, NIG_REG_LLH0_FUNC_EN + port * 8, 1);
+ REG_WR(bp, NIG_REG_LLH0_FUNC_VLAN_ID + port * 8,
+ bp->mf_ov);
+ }
}
bnx2x_init_block(bp, BLOCK_MISC_AEU, init_phase);
@@ -11626,6 +11708,7 @@ static int bnx2x_get_hwinfo(struct bnx2x *bp)
bp->mf_ov = 0;
bp->mf_mode = 0;
+ bp->mf_sub_mode = 0;
vn = BP_VN(bp);
if (!CHIP_IS_E1(bp) && !BP_NOMCP(bp)) {
@@ -11691,6 +11774,13 @@ static int bnx2x_get_hwinfo(struct bnx2x *bp)
} else
BNX2X_DEV_INFO("illegal OV for SD\n");
break;
+ case SHARED_FEAT_CFG_FORCE_SF_MODE_UFP_MODE:
+ bp->mf_mode = MULTI_FUNCTION_SD;
+ bp->mf_sub_mode = SUB_MF_MODE_UFP;
+ bp->mf_config[vn] =
+ MF_CFG_RD(bp,
+ func_mf_config[func].config);
+ break;
case SHARED_FEAT_CFG_FORCE_SF_MODE_FORCED_SF:
bp->mf_config[vn] = 0;
break;
@@ -11714,6 +11804,11 @@ static int bnx2x_get_hwinfo(struct bnx2x *bp)
BNX2X_DEV_INFO("MF OV for func %d is %d (0x%04x)\n",
func, bp->mf_ov, bp->mf_ov);
+ } else if (bp->mf_sub_mode == SUB_MF_MODE_UFP) {
+ dev_err(&bp->pdev->dev,
+ "Unexpected - no valid MF OV for func %d in UFP mode\n",
+ func);
+ bp->path_has_ovlan = true;
} else {
dev_err(&bp->pdev->dev,
"No valid MF OV for func %d, aborting\n",
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c
index 19d0c11..7bc2924 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c
@@ -5673,8 +5673,23 @@ static inline int bnx2x_func_send_start(struct bnx2x *bp,
rdata->gre_tunnel_type = start_params->gre_tunnel_type;
rdata->inner_gre_rss_en = start_params->inner_gre_rss_en;
rdata->vxlan_dst_port = cpu_to_le16(4789);
- rdata->sd_vlan_eth_type = cpu_to_le16(0x8100);
+ rdata->sd_accept_mf_clss_fail = start_params->class_fail;
+ if (start_params->class_fail_ethtype) {
+ rdata->sd_accept_mf_clss_fail_match_ethtype = 1;
+ rdata->sd_accept_mf_clss_fail_ethtype =
+ cpu_to_le16(start_params->class_fail_ethtype);
+ }
+
+ rdata->sd_vlan_force_pri_flg = start_params->sd_vlan_force_pri;
+ rdata->sd_vlan_force_pri_val = start_params->sd_vlan_force_pri_val;
+ if (start_params->sd_vlan_eth_type)
+ rdata->sd_vlan_eth_type =
+ cpu_to_le16(start_params->sd_vlan_eth_type);
+ else
+ rdata->sd_vlan_eth_type =
+ cpu_to_le16(0x8100);
+ rdata->no_added_tags = start_params->no_added_tags;
/* No need for an explicit memory barrier here as long we would
* need to ensure the ordering of writing to the SPQ element
* and updating of the SPQ producer which involves a memory
@@ -5708,6 +5723,30 @@ static inline int bnx2x_func_send_switch_update(struct bnx2x *bp,
&switch_update_params->changes);
}
+ if (test_bit(BNX2X_F_UPDATE_SD_VLAN_TAG_CHNG,
+ &switch_update_params->changes)) {
+ rdata->sd_vlan_tag_change_flg = 1;
+ rdata->sd_vlan_tag =
+ cpu_to_le16(switch_update_params->vlan);
+ }
+
+ if (test_bit(BNX2X_F_UPDATE_SD_VLAN_ETH_TYPE_CHNG,
+ &switch_update_params->changes)) {
+ rdata->sd_vlan_eth_type_change_flg = 1;
+ rdata->sd_vlan_eth_type =
+ cpu_to_le16(switch_update_params->vlan_eth_type);
+ }
+
+ if (test_bit(BNX2X_F_UPDATE_VLAN_FORCE_PRIO_CHNG,
+ &switch_update_params->changes)) {
+ rdata->sd_vlan_force_pri_change_flg = 1;
+ if (test_bit(BNX2X_F_UPDATE_VLAN_FORCE_PRIO_FLAG,
+ &switch_update_params->changes))
+ rdata->sd_vlan_force_pri_flg = 1;
+ rdata->sd_vlan_force_pri_flg =
+ switch_update_params->vlan_force_prio;
+ }
+
if (test_bit(BNX2X_F_UPDATE_TUNNEL_CFG_CHNG,
&switch_update_params->changes)) {
rdata->update_tunn_cfg_flg = 1;
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h
index 21c8f6f..e97275f 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h
@@ -1098,6 +1098,10 @@ struct bnx2x_queue_sp_obj {
enum {
BNX2X_F_UPDATE_TX_SWITCH_SUSPEND_CHNG,
BNX2X_F_UPDATE_TX_SWITCH_SUSPEND,
+ BNX2X_F_UPDATE_SD_VLAN_TAG_CHNG,
+ BNX2X_F_UPDATE_SD_VLAN_ETH_TYPE_CHNG,
+ BNX2X_F_UPDATE_VLAN_FORCE_PRIO_CHNG,
+ BNX2X_F_UPDATE_VLAN_FORCE_PRIO_FLAG,
BNX2X_F_UPDATE_TUNNEL_CFG_CHNG,
BNX2X_F_UPDATE_TUNNEL_CLSS_EN,
BNX2X_F_UPDATE_TUNNEL_INNER_GRE_RSS_EN,
@@ -1178,10 +1182,29 @@ struct bnx2x_func_start_params {
* capailities
*/
u8 inner_gre_rss_en;
+
+ /* Allows accepting of packets failing MF classification, possibly
+ * only matching a given ethertype
+ */
+ u8 class_fail;
+ u16 class_fail_ethtype;
+
+ /* Override priority of output packets */
+ u8 sd_vlan_force_pri;
+ u8 sd_vlan_force_pri_val;
+
+ /* Replace vlan's ethertype */
+ u16 sd_vlan_eth_type;
+
+ /* Prevent inner vlans from being added by FW */
+ u8 no_added_tags;
};
struct bnx2x_func_switch_update_params {
unsigned long changes; /* BNX2X_F_UPDATE_XX bits */
+ u16 vlan;
+ u16 vlan_eth_type;
+ u8 vlan_force_prio;
u8 tunnel_mode;
u8 gre_tunnel_type;
};
--
1.8.3.1
^ permalink raw reply related
* [PATCH net-next 3/3] bnx2x: Add a fallback multi-function mode NPAR1.5
From: Yuval Mintz @ 2014-09-17 13:24 UTC (permalink / raw)
To: davem, netdev; +Cc: Ariel.Elior, Yuval Mintz, Dmitry Kravkov
In-Reply-To: <1410960278-32064-1-git-send-email-Yuval.Mintz@qlogic.com>
When using new Multi-function modes it's possible that due to incompatible
configuration management FW will fallback into an existing mode.
Notice that at the moment this fallback is exactly the same as the already
existing switch-independent multi-function mode, but we still use existing
infrastructure to hold this information [in case some small differences will
arise in the future].
Signed-off-by: Yuval Mintz <Yuval.Mintz@qlogic.com>
Signed-off-by: Dmitry Kravkov <Dmitry.Kravkov@qlogic.com>
Signed-off-by: Ariel Elior <Ariel.Elior@qlogic.com>
---
drivers/net/ethernet/broadcom/bnx2x/bnx2x.h | 1 +
drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h | 17 ++++-----
drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 45 ++++++++++++++++++------
3 files changed, 42 insertions(+), 21 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
index 10291df..c3a6072 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
@@ -1451,6 +1451,7 @@ struct bnx2x_fp_stats {
enum {
SUB_MF_MODE_UNKNOWN = 0,
SUB_MF_MODE_UFP,
+ SUB_MF_MODE_NPAR1_DOT_5,
};
struct bnx2x {
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h
index 3295863..583591d 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h
@@ -280,17 +280,11 @@ struct shared_hw_cfg { /* NVRAM Offset */
#define SHARED_HW_CFG_MDC_MDIO_ACCESS2_BOTH 0x60000000
#define SHARED_HW_CFG_MDC_MDIO_ACCESS2_SWAPPED 0x80000000
-
- u32 power_dissipated; /* 0x11c */
- #define SHARED_HW_CFG_POWER_MGNT_SCALE_MASK 0x00ff0000
- #define SHARED_HW_CFG_POWER_MGNT_SCALE_SHIFT 16
- #define SHARED_HW_CFG_POWER_MGNT_UNKNOWN_SCALE 0x00000000
- #define SHARED_HW_CFG_POWER_MGNT_DOT_1_WATT 0x00010000
- #define SHARED_HW_CFG_POWER_MGNT_DOT_01_WATT 0x00020000
- #define SHARED_HW_CFG_POWER_MGNT_DOT_001_WATT 0x00030000
-
- #define SHARED_HW_CFG_POWER_DIS_CMN_MASK 0xff000000
- #define SHARED_HW_CFG_POWER_DIS_CMN_SHIFT 24
+ u32 config_3; /* 0x11C */
+ #define SHARED_HW_CFG_EXTENDED_MF_MODE_MASK 0x00000F00
+ #define SHARED_HW_CFG_EXTENDED_MF_MODE_SHIFT 8
+ #define SHARED_HW_CFG_EXTENDED_MF_MODE_NPAR1_DOT_5 0x00000000
+ #define SHARED_HW_CFG_EXTENDED_MF_MODE_NPAR2_DOT_0 0x00000100
u32 ump_nc_si_config; /* 0x120 */
#define SHARED_HW_CFG_UMP_NC_SI_MII_MODE_MASK 0x00000003
@@ -860,6 +854,7 @@ struct shared_feat_cfg { /* NVRAM Offset */
#define SHARED_FEAT_CFG_FORCE_SF_MODE_SWITCH_INDEPT 0x00000300
#define SHARED_FEAT_CFG_FORCE_SF_MODE_AFEX_MODE 0x00000400
#define SHARED_FEAT_CFG_FORCE_SF_MODE_UFP_MODE 0x00000600
+ #define SHARED_FEAT_CFG_FORCE_SF_MODE_EXTENDED_MODE 0x00000700
/* The interval in seconds between sending LLDP packets. Set to zero
to disable the feature */
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
index da6c5bb..74fbf9e 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
@@ -11624,11 +11624,27 @@ static bool bnx2x_get_dropless_info(struct bnx2x *bp)
return cfg;
}
+static void validate_set_si_mode(struct bnx2x *bp)
+{
+ u8 func = BP_ABS_FUNC(bp);
+ u32 val;
+
+ val = MF_CFG_RD(bp, func_mf_config[func].mac_upper);
+
+ /* check for legal mac (upper bytes) */
+ if (val != 0xffff) {
+ bp->mf_mode = MULTI_FUNCTION_SI;
+ bp->mf_config[BP_VN(bp)] =
+ MF_CFG_RD(bp, func_mf_config[func].config);
+ } else
+ BNX2X_DEV_INFO("illegal MAC address for SI\n");
+}
+
static int bnx2x_get_hwinfo(struct bnx2x *bp)
{
int /*abs*/func = BP_ABS_FUNC(bp);
int vn;
- u32 val = 0;
+ u32 val = 0, val2 = 0;
int rc = 0;
bnx2x_get_common_hwinfo(bp);
@@ -11738,15 +11754,7 @@ static int bnx2x_get_hwinfo(struct bnx2x *bp)
switch (val) {
case SHARED_FEAT_CFG_FORCE_SF_MODE_SWITCH_INDEPT:
- val = MF_CFG_RD(bp, func_mf_config[func].
- mac_upper);
- /* check for legal mac (upper bytes)*/
- if (val != 0xffff) {
- bp->mf_mode = MULTI_FUNCTION_SI;
- bp->mf_config[vn] = MF_CFG_RD(bp,
- func_mf_config[func].config);
- } else
- BNX2X_DEV_INFO("illegal MAC address for SI\n");
+ validate_set_si_mode(bp);
break;
case SHARED_FEAT_CFG_FORCE_SF_MODE_AFEX_MODE:
if ((!CHIP_IS_E1x(bp)) &&
@@ -11784,6 +11792,23 @@ static int bnx2x_get_hwinfo(struct bnx2x *bp)
case SHARED_FEAT_CFG_FORCE_SF_MODE_FORCED_SF:
bp->mf_config[vn] = 0;
break;
+ case SHARED_FEAT_CFG_FORCE_SF_MODE_EXTENDED_MODE:
+ val2 = SHMEM_RD(bp,
+ dev_info.shared_hw_config.config_3);
+ val2 &= SHARED_HW_CFG_EXTENDED_MF_MODE_MASK;
+ switch (val2) {
+ case SHARED_HW_CFG_EXTENDED_MF_MODE_NPAR1_DOT_5:
+ validate_set_si_mode(bp);
+ bp->mf_sub_mode =
+ SUB_MF_MODE_NPAR1_DOT_5;
+ break;
+ default:
+ /* Unknown configuration */
+ bp->mf_config[vn] = 0;
+ BNX2X_DEV_INFO("unknown extended MF mode 0x%x\n",
+ val);
+ }
+ break;
default:
/* Unknown configuration: reset mf_config */
bp->mf_config[vn] = 0;
--
1.8.3.1
^ permalink raw reply related
* CPU scheduler to TXQ binding? (ixgbe vs. igb)
From: Jesper Dangaard Brouer @ 2014-09-17 13:26 UTC (permalink / raw)
To: netdev@vger.kernel.org; +Cc: Tom Herbert, Eric Dumazet
The CPU to TXQ binding behavior of ixgbe vs. igb NIC driver are
somehow different. Normally I setup NIC IRQ-to-CPU bindings 1-to-1,
with script set_irq_affinity [1].
For forcing use of a specific HW TXQ, I normally force the CPU binding
of the process, either with "taskset" or with "netperf -T lcpu,rcpu".
This works fine with driver ixgbe, but not with driver igb. That is
with igb, the program forced to specific CPU, can still use another
TXQ. What am I missing?
I'm monitoring this with both:
1) watch -d sudo tc -s -d q ls dev ethXX
2) https://github.com/ffainelli/bqlmon
[1] https://github.com/netoptimizer/network-testing/blob/master/bin/set_irq_affinity
--
Best regards,
Jesper Dangaard Brouer
MSc.CS, Sr. Network Kernel Developer at Red Hat
Author of http://www.iptv-analyzer.org
LinkedIn: http://www.linkedin.com/in/brouer
^ permalink raw reply
* Re: [PATCH 1/1] bluetooth: Check for SCO type before setting retransmission effort
From: Marcel Holtmann @ 2014-09-17 13:55 UTC (permalink / raw)
To: Bernhard Thaler
Cc: Gustavo F. Padovan, Johan Hedberg, David S. Miller,
BlueZ development, Network Development, linux-kernel
In-Reply-To: <1410938010-6181-1-git-send-email-bernhard.thaler@r-it.at>
Hi Bernhard,
> SCO connection cannot be setup to devices that do not support retransmission.
> Patch based on http://permalink.gmane.org/gmane.linux.bluez.kernel/7779 and
> adapted for this kernel version.
> Code changed to check SCO/eSCO type before setting retransmission effort
> and max. latency. The purpose of the patch is to support older devices not
> capable of eSCO.
>
> Tested on Blackberry 655+ headset which does not support retransmission.
> Credits go to Alexander Sommerhuber.
>
> Signed-off-by: Bernhard Thaler <bernhard.thaler@r-it.at>
> ---
> net/bluetooth/hci_conn.c | 39 ++++++++++++++++++++++-----------------
> 1 file changed, 22 insertions(+), 17 deletions(-)
>
> diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
> index faff624..093abcc 100644
> --- a/net/bluetooth/hci_conn.c
> +++ b/net/bluetooth/hci_conn.c
> @@ -186,26 +186,31 @@ bool hci_setup_sync(struct hci_conn *conn, __u16 handle)
> cp.rx_bandwidth = cpu_to_le32(0x00001f40);
> cp.voice_setting = cpu_to_le16(conn->setting);
>
> - switch (conn->setting & SCO_AIRMODE_MASK) {
> - case SCO_AIRMODE_TRANSP:
> - if (conn->attempt > ARRAY_SIZE(sco_param_wideband))
> - return false;
> - cp.retrans_effort = 0x02;
> - param = &sco_param_wideband[conn->attempt - 1];
> - break;
> - case SCO_AIRMODE_CVSD:
> - if (conn->attempt > ARRAY_SIZE(sco_param_cvsd))
> + if (!(conn->link->features[0][3] & LMP_ESCO)) {
so we have something that is called lmp_esco_capable.
> + cp.retrans_effort = 0xff;
> + cp.pkt_type = __cpu_to_le16(conn->pkt_type);
> + cp.max_latency = __cpu_to_le16(0xffff);
Anyway, I do not thing this is the right approach. I think what we should do is just reject a connection attempt for transparent eSCO connections (since we only use them for wideband speech anyway) when connecting to a device that has no eSCO support.
> + } else {
> + switch (conn->setting & SCO_AIRMODE_MASK) {
> + case SCO_AIRMODE_TRANSP:
> + if (conn->attempt > ARRAY_SIZE(sco_param_wideband))
> + return false;
> + cp.retrans_effort = 0x02;
> + param = &sco_param_wideband[conn->attempt - 1];
> + break;
> + case SCO_AIRMODE_CVSD:
> + if (conn->attempt > ARRAY_SIZE(sco_param_cvsd))
> + return false;
> + cp.retrans_effort = 0x01;
> + param = &sco_param_cvsd[conn->attempt - 1];
> + break;
For CVSD based attempts, we should start with non eSCO parameter settings if we know that the remote side can not support eSCO.
The reason is that you still need to follow through with defined parameter sets from the HFP profile.
Regards
Marcel
^ permalink raw reply
* Re: [PATCH 3/3] bridge; Automatically filter vlans configured on top of bridge
From: Vlad Yasevich @ 2014-09-17 14:14 UTC (permalink / raw)
To: Toshiaki Makita, Toshiaki Makita, Vladislav Yasevich, netdev
Cc: shemminger, bridge
In-Reply-To: <5418D4F3.5070701@lab.ntt.co.jp>
On 09/16/2014 08:25 PM, Toshiaki Makita wrote:
> On 2014/09/17 0:00, Vlad Yasevich wrote:
>> On 09/16/2014 10:39 AM, Toshiaki Makita wrote:
>>> (14/09/16 (火) 22:31), Vlad Yasevich wrote:
>>>> On 09/16/2014 07:28 AM, Toshiaki Makita wrote:
>>>>> On 2014/09/16 0:19, Vlad Yasevich wrote:
>>>>>> On 09/14/2014 11:39 AM, Toshiaki Makita wrote:
>>>>>>> (14/09/13 (土) 5:44), Vladislav Yasevich wrote:
>>>>>>>> If the user configures vlan devices on top of the bridge,
>>>>>>>> automatically set up filter entries for it as long as
>>>>>>>> bridge vlan protocol matches that of the vlan.
>>>>>>>> This allows the user to atomatically receive vlan traffic
>>>>>>>> for the vlans that are convifgured.
>>>>>>>
>>>>>>> Changing br->vlan_proto seems to cause inconsistency between vlan
>>>>>>> interfaces and filter settings.
>>>>>>> Can we automatically change filters when setting vlan_proto?
>>>>>>>
>>>>>>
>>>>>> I thought we already do that in br_vlan_set_proto()? Nothing
>>>>>> here introduces any new kinds of issue with that code.
>>>>>
>>>>> I'm referring to a case like this:
>>>>> 1. create br0.10 (802.1ad)
>>>>> 2. change br->vlan_proto into 88a8
>>>>>
>>>>> When creating br0.10 (1), br->vlan_proto is 8100 and different from
>>>>> protocol of br0.10, so it is ignored by br_vlan_rx_add_vid().
>>>>> After changing br->vlan_proto (2), we might expect vlan 10 is not
>>>>> filtered on br0, but it will be filtered.
>>>>
>>>> Ok, I see what you mean. This one is a bit tough. Our options are:
>>>> 1) Return an error when configuring br0.10. This might break user-space. Not good.
>>>> 2) Ignore protocol when crating the filter. This is not good either as the user
>>>> may not switch the bridge vlan_proto value and we'd end up with a wrong filter.
>>>> 3) Re-implement .1ad support per-vlan instead of per-bridge.
>>>>
>>>> You see another other alternatives?
>>>
>>> We might be able to configure filterings on changing vlan_proto.
>>> 4) Memorize different protocol's filtering requests in
>>> br_vlan_rx_add_vid() and use them when switching vlan_proto.
>>
>> If we do this, we might as well take it one small step further and make per-vlan protocol
>> support.
>>
>>> 5) Scan vlan devices on bridge device when changing vlan_proto.
>>>
>>
>> The scan could work... walk the upper devices looking for vlans and add/delete filters
>> based on the protocol of the vlan devices.
>>
>> Seems kind of hacky, but let me give this one a try...
>
> dev->vlan_info->vid_list might be a more appropriate list since
> vlan_vid_add() can be called not only by vlan devices.
That's private to vlan implementation and I don't think this is a good reason
to expose it.
-vlad
>
> Thanks,
> Toshiaki Makita
>
^ permalink raw reply
* Re: Question about synchronize_net() in AF_PACKET close()
From: Martin Kelly @ 2014-09-17 14:29 UTC (permalink / raw)
To: David Miller; +Cc: netdev, Paul McKenney, Stephen Hemminger
In-Reply-To: <CAN8CM3xEnQXVgrLpV0rfAJoZ75v6Xv64pAGJ-9SAPACAT8WJ_w@mail.gmail.com>
On 09/10/2014 02:37 PM, Martin Kelly wrote:
>> The synchronize_net() is also there to protect against the prot hook
>> which can run asynchronously from the core packet input path on any
>> cpu.
>>
>
> Yes, understood. What I'm not clear about is whether it is safe to do
> the following:
>
> unregister_prot_hook(sk, false);
> sock_orphan(sk);
> sock->sk = NULL;
> call_rcu(...);
> close socket, return to userspace
>
> instead of
>
> unregister_prot_hook(sk, false);
> synchronize_net();
> sock_orphan(sk);
> sock->sk = NULL;
> close socket, return to userspace
>
> If you don't call synchronize_net() immediately, then other readers
> could see the protocol hook in the protocol list and try to use it.
> They could call into prot_hook.func. However, it appears that such
> functions ( e.g. packet_rcv() ) touch the socket buffer but not the
> socket itself, so orphaning the socket before all RCUs have been
> processed is safe. In addition, no new packets will come in after
> packet_release() and touch the socket because the socket fd will be
> removed from the process fd list.
>
> From my testing, I'm not seeing any obvious issues, but I could be
> missing something. Is orphaning the socket before all RCUs have
> finished unsafe?
>
(friendly ping)
^ permalink raw reply
* Re: CPU scheduler to TXQ binding? (ixgbe vs. igb)
From: Eric Dumazet @ 2014-09-17 14:32 UTC (permalink / raw)
To: Jesper Dangaard Brouer; +Cc: netdev@vger.kernel.org, Tom Herbert
In-Reply-To: <20140917152653.1c824a22@redhat.com>
On Wed, 2014-09-17 at 15:26 +0200, Jesper Dangaard Brouer wrote:
> The CPU to TXQ binding behavior of ixgbe vs. igb NIC driver are
> somehow different. Normally I setup NIC IRQ-to-CPU bindings 1-to-1,
> with script set_irq_affinity [1].
>
> For forcing use of a specific HW TXQ, I normally force the CPU binding
> of the process, either with "taskset" or with "netperf -T lcpu,rcpu".
>
> This works fine with driver ixgbe, but not with driver igb. That is
> with igb, the program forced to specific CPU, can still use another
> TXQ. What am I missing?
>
>
> I'm monitoring this with both:
> 1) watch -d sudo tc -s -d q ls dev ethXX
> 2) https://github.com/ffainelli/bqlmon
>
> [1] https://github.com/netoptimizer/network-testing/blob/master/bin/set_irq_affinity
Have you setup XPS ?
echo 0001 >/sys/class/net/ethX/queues/tx-0/xps_cpus
echo 0002 >/sys/class/net/ethX/queues/tx-1/xps_cpus
echo 0004 >/sys/class/net/ethX/queues/tx-2/xps_cpus
echo 0008 >/sys/class/net/ethX/queues/tx-3/xps_cpus
echo 0010 >/sys/class/net/ethX/queues/tx-4/xps_cpus
echo 0020 >/sys/class/net/ethX/queues/tx-5/xps_cpus
echo 0040 >/sys/class/net/ethX/queues/tx-6/xps_cpus
echo 0080 >/sys/class/net/ethX/queues/tx-7/xps_cpus
Or something like that, depending on number of cpus and TX queues.
^ permalink raw reply
* Re: Question about synchronize_net() in AF_PACKET close()
From: Eric Dumazet @ 2014-09-17 14:54 UTC (permalink / raw)
To: Martin Kelly; +Cc: David Miller, netdev, Paul McKenney, Stephen Hemminger
In-Reply-To: <54199AC7.1040502@martingkelly.com>
On Wed, 2014-09-17 at 07:29 -0700, Martin Kelly wrote:
> On 09/10/2014 02:37 PM, Martin Kelly wrote:
> >> The synchronize_net() is also there to protect against the prot hook
> >> which can run asynchronously from the core packet input path on any
> >> cpu.
> >>
> >
> > Yes, understood. What I'm not clear about is whether it is safe to do
> > the following:
> >
> > unregister_prot_hook(sk, false);
> > sock_orphan(sk);
> > sock->sk = NULL;
> > call_rcu(...);
Can you describe the ... ?
> > close socket, return to userspace
> >
> > instead of
> >
> > unregister_prot_hook(sk, false);
> > synchronize_net();
> > sock_orphan(sk);
> > sock->sk = NULL;
> > close socket, return to userspace
> >
> > If you don't call synchronize_net() immediately, then other readers
> > could see the protocol hook in the protocol list and try to use it.
> > They could call into prot_hook.func. However, it appears that such
> > functions ( e.g. packet_rcv() ) touch the socket buffer but not the
> > socket itself, so orphaning the socket before all RCUs have been
> > processed is safe. In addition, no new packets will come in after
> > packet_release() and touch the socket because the socket fd will be
> > removed from the process fd list.
> >
> > From my testing, I'm not seeing any obvious issues, but I could be
> > missing something. Is orphaning the socket before all RCUs have
> > finished unsafe?
> >
>
> (friendly ping)
What problem do you want to solve exactly ?
I believe its not safe, you missed sk_data_ready() call
(sock_def_readable())
^ permalink raw reply
* Re: CPU scheduler to TXQ binding? (ixgbe vs. igb)
From: Jesper Dangaard Brouer @ 2014-09-17 14:55 UTC (permalink / raw)
To: Eric Dumazet; +Cc: netdev@vger.kernel.org, Tom Herbert
In-Reply-To: <1410964359.7106.229.camel@edumazet-glaptop2.roam.corp.google.com>
On Wed, 17 Sep 2014 07:32:39 -0700
Eric Dumazet <eric.dumazet@gmail.com> wrote:
> On Wed, 2014-09-17 at 15:26 +0200, Jesper Dangaard Brouer wrote:
> > The CPU to TXQ binding behavior of ixgbe vs. igb NIC driver are
> > somehow different. Normally I setup NIC IRQ-to-CPU bindings 1-to-1,
> > with script set_irq_affinity [1].
> >
> > For forcing use of a specific HW TXQ, I normally force the CPU binding
> > of the process, either with "taskset" or with "netperf -T lcpu,rcpu".
> >
> > This works fine with driver ixgbe, but not with driver igb. That is
> > with igb, the program forced to specific CPU, can still use another
> > TXQ. What am I missing?
> >
> >
> > I'm monitoring this with both:
> > 1) watch -d sudo tc -s -d q ls dev ethXX
> > 2) https://github.com/ffainelli/bqlmon
> >
> > [1] https://github.com/netoptimizer/network-testing/blob/master/bin/set_irq_affinity
>
> Have you setup XPS ?
>
> echo 0001 >/sys/class/net/ethX/queues/tx-0/xps_cpus
> echo 0002 >/sys/class/net/ethX/queues/tx-1/xps_cpus
> echo 0004 >/sys/class/net/ethX/queues/tx-2/xps_cpus
> echo 0008 >/sys/class/net/ethX/queues/tx-3/xps_cpus
> echo 0010 >/sys/class/net/ethX/queues/tx-4/xps_cpus
> echo 0020 >/sys/class/net/ethX/queues/tx-5/xps_cpus
> echo 0040 >/sys/class/net/ethX/queues/tx-6/xps_cpus
> echo 0080 >/sys/class/net/ethX/queues/tx-7/xps_cpus
>
> Or something like that, depending on number of cpus and TX queues.
Thanks, that worked! They were all default set to "000" for igb, but
set correctly/like-above for ixgbe (strange).
Did:
$ export DEV=eth1 ; export NR_CPUS=11 ; \
for txq in `seq 0 $NR_CPUS` ; do \
file=/sys/class/net/${DEV}/queues/tx-${txq}/xps_cpus \
mask=`printf %X $((1<<$txq))`
test -e $file && sudo sh -c "echo $mask > $file" && \
grep . -H $file ;\
done
/sys/class/net/eth1/queues/tx-0/xps_cpus:001
/sys/class/net/eth1/queues/tx-1/xps_cpus:002
/sys/class/net/eth1/queues/tx-2/xps_cpus:004
/sys/class/net/eth1/queues/tx-3/xps_cpus:008
/sys/class/net/eth1/queues/tx-4/xps_cpus:010
/sys/class/net/eth1/queues/tx-5/xps_cpus:020
/sys/class/net/eth1/queues/tx-6/xps_cpus:040
/sys/class/net/eth1/queues/tx-7/xps_cpus:080
--
Best regards,
Jesper Dangaard Brouer
MSc.CS, Sr. Network Kernel Developer at Red Hat
Author of http://www.iptv-analyzer.org
LinkedIn: http://www.linkedin.com/in/brouer
^ permalink raw reply
* Re: CPU scheduler to TXQ binding? (ixgbe vs. igb)
From: Alexander Duyck @ 2014-09-17 14:59 UTC (permalink / raw)
To: Eric Dumazet, Jesper Dangaard Brouer; +Cc: netdev@vger.kernel.org, Tom Herbert
In-Reply-To: <1410964359.7106.229.camel@edumazet-glaptop2.roam.corp.google.com>
On 09/17/2014 07:32 AM, Eric Dumazet wrote:
> On Wed, 2014-09-17 at 15:26 +0200, Jesper Dangaard Brouer wrote:
>> The CPU to TXQ binding behavior of ixgbe vs. igb NIC driver are
>> somehow different. Normally I setup NIC IRQ-to-CPU bindings 1-to-1,
>> with script set_irq_affinity [1].
>>
>> For forcing use of a specific HW TXQ, I normally force the CPU binding
>> of the process, either with "taskset" or with "netperf -T lcpu,rcpu".
>>
>> This works fine with driver ixgbe, but not with driver igb. That is
>> with igb, the program forced to specific CPU, can still use another
>> TXQ. What am I missing?
>>
>>
>> I'm monitoring this with both:
>> 1) watch -d sudo tc -s -d q ls dev ethXX
>> 2) https://github.com/ffainelli/bqlmon
>>
>> [1] https://github.com/netoptimizer/network-testing/blob/master/bin/set_irq_affinity
>
> Have you setup XPS ?
>
> echo 0001 >/sys/class/net/ethX/queues/tx-0/xps_cpus
> echo 0002 >/sys/class/net/ethX/queues/tx-1/xps_cpus
> echo 0004 >/sys/class/net/ethX/queues/tx-2/xps_cpus
> echo 0008 >/sys/class/net/ethX/queues/tx-3/xps_cpus
> echo 0010 >/sys/class/net/ethX/queues/tx-4/xps_cpus
> echo 0020 >/sys/class/net/ethX/queues/tx-5/xps_cpus
> echo 0040 >/sys/class/net/ethX/queues/tx-6/xps_cpus
> echo 0080 >/sys/class/net/ethX/queues/tx-7/xps_cpus
>
> Or something like that, depending on number of cpus and TX queues.
>
That was what I was thinking as well.
ixgbe has ATR which makes use of XPS to setup the transmit queues for a
1:1 mapping. The receive side of the flow is routed back to the same Rx
queue through flow director mappings.
In the case of igb it only has RSS and doesn't set a default XPS
configuration. So you should probably setup XPS and you might also want
to try and make use of RPS to try and steer receive packets since the Rx
queues won't match the Tx queues.
Thanks,
Alex
^ permalink raw reply
* [PATCH net-next] net: sched: use __skb_queue_head_init() where applicable
From: Eric Dumazet @ 2014-09-17 15:05 UTC (permalink / raw)
To: David Miller; +Cc: netdev
From: Eric Dumazet <edumazet@google.com>
pfifo_fast and htb use skb lists, without needing their spinlocks.
(They instead use the standard qdisc lock)
We can use __skb_queue_head_init() instead of skb_queue_head_init()
to be consistent.
Signed-off-by: Eric Dumazet <edumazet@google.com>
---
net/sched/sch_generic.c | 2 +-
net/sched/sch_htb.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c
index 346ef85617d3..11b28f651ad1 100644
--- a/net/sched/sch_generic.c
+++ b/net/sched/sch_generic.c
@@ -523,7 +523,7 @@ static int pfifo_fast_init(struct Qdisc *qdisc, struct nlattr *opt)
struct pfifo_fast_priv *priv = qdisc_priv(qdisc);
for (prio = 0; prio < PFIFO_FAST_BANDS; prio++)
- skb_queue_head_init(band2list(priv, prio));
+ __skb_queue_head_init(band2list(priv, prio));
/* Can by-pass the queue discipline */
qdisc->flags |= TCQ_F_CAN_BYPASS;
diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c
index 6d16b9b81c28..14408f262143 100644
--- a/net/sched/sch_htb.c
+++ b/net/sched/sch_htb.c
@@ -1044,7 +1044,7 @@ static int htb_init(struct Qdisc *sch, struct nlattr *opt)
qdisc_watchdog_init(&q->watchdog, sch);
INIT_WORK(&q->work, htb_work_func);
- skb_queue_head_init(&q->direct_queue);
+ __skb_queue_head_init(&q->direct_queue);
if (tb[TCA_HTB_DIRECT_QLEN])
q->direct_qlen = nla_get_u32(tb[TCA_HTB_DIRECT_QLEN]);
^ permalink raw reply related
* Re: [PATCH v2 net-next 0/7] net: foo-over-udp (fou)
From: Or Gerlitz @ 2014-09-17 15:22 UTC (permalink / raw)
To: David Miller; +Cc: Tom Herbert, Linux Netdev List
In-Reply-To: <20140916.161634.1557106189352739238.davem@davemloft.net>
On Tue, Sep 16, 2014 at 11:16 PM, David Miller <davem@davemloft.net> wrote:
> From: Or Gerlitz <gerlitz.or@gmail.com>
> Date: Tue, 16 Sep 2014 23:04:30 +0300
>
>> And I wasn't sure what do you mean by remote checksum offload, can you clarify?
> http://vger.kernel.org/encapsulation_offloads.pdf
> Page 14.
Oh, thanks for the pointer, will take a look.
Or.
^ permalink raw reply
* pull request: wireless 2014-09-17
From: John W. Linville @ 2014-09-17 15:23 UTC (permalink / raw)
To: davem; +Cc: linux-wireless, netdev, linux-kernel
[-- Attachment #1: Type: text/plain, Size: 10327 bytes --]
Dave,
Please pull this batch of fixes intended for the 3.17 stream...
Arend van Spriel sends a trio of minor brcmfmac fixes, including a
fix for a Kconfig/build issue, a fix for a crash (null reference),
and a regression fix related to event handling on a P2P interface.
Hante Meuleman follows-up with a brcmfmac fix for a memory leak.
Johannes Stezenbach brings an ath9k_htc fix for a regression related
to hardware decryption offload.
Marcel Holtmann delivers a one-liner to properly mark a device ID
table in rfkill-gpio.
Please let me know if there are problems!
Thanks,
John
---
The following changes since commit ae0fd6354134e63aa3e62456e2080c430287144d:
Revert "ath9k: Calculate sleep duration" (2014-09-11 14:17:20 -0400)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless.git tags/master-2014-09-16
for you to fetch changes up to dda3b191eb6c5a56d443723dcb71ade60d97c04f:
net: rfkill: gpio: Enable module auto-loading for ACPI based switches (2014-09-16 16:09:01 -0400)
----------------------------------------------------------------
Arend van Spriel (3):
brcmfmac: conditionally compile firmware protocol source code
brcmfmac: obtain ifp through wdev structure
brcmfmac: handle IF event for P2P_DEVICE interface
Hante Meuleman (1):
brcmfmac: Fix memory leak and missing assignment.
Johannes Stezenbach (1):
ath9k_htc: fix random decryption failure
Marcel Holtmann (1):
net: rfkill: gpio: Enable module auto-loading for ACPI based switches
drivers/net/wireless/ath/ath9k/htc_drv_txrx.c | 2 +-
drivers/net/wireless/brcm80211/Kconfig | 10 ++++++++++
drivers/net/wireless/brcm80211/brcmfmac/Makefile | 10 ++++++----
drivers/net/wireless/brcm80211/brcmfmac/bcdc.h | 7 +++++--
drivers/net/wireless/brcm80211/brcmfmac/fweh.c | 12 +++++++++---
drivers/net/wireless/brcm80211/brcmfmac/fweh.h | 2 ++
drivers/net/wireless/brcm80211/brcmfmac/msgbuf.h | 11 +++++++++--
drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c | 9 +++++++--
net/rfkill/rfkill-gpio.c | 1 +
9 files changed, 50 insertions(+), 14 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
index bb86eb2ffc95..f0484b1b617e 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
@@ -978,7 +978,7 @@ static bool ath9k_rx_prepare(struct ath9k_htc_priv *priv,
struct ath_hw *ah = common->ah;
struct ath_htc_rx_status *rxstatus;
struct ath_rx_status rx_stats;
- bool decrypt_error;
+ bool decrypt_error = false;
if (skb->len < HTC_RX_FRAME_HEADER_SIZE) {
ath_err(common, "Corrupted RX frame, dropping (len: %d)\n",
diff --git a/drivers/net/wireless/brcm80211/Kconfig b/drivers/net/wireless/brcm80211/Kconfig
index b8e2561ea645..fe3dc126b149 100644
--- a/drivers/net/wireless/brcm80211/Kconfig
+++ b/drivers/net/wireless/brcm80211/Kconfig
@@ -27,10 +27,17 @@ config BRCMFMAC
one of the bus interface support. If you choose to build a module,
it'll be called brcmfmac.ko.
+config BRCMFMAC_PROTO_BCDC
+ bool
+
+config BRCMFMAC_PROTO_MSGBUF
+ bool
+
config BRCMFMAC_SDIO
bool "SDIO bus interface support for FullMAC driver"
depends on (MMC = y || MMC = BRCMFMAC)
depends on BRCMFMAC
+ select BRCMFMAC_PROTO_BCDC
select FW_LOADER
default y
---help---
@@ -42,6 +49,7 @@ config BRCMFMAC_USB
bool "USB bus interface support for FullMAC driver"
depends on (USB = y || USB = BRCMFMAC)
depends on BRCMFMAC
+ select BRCMFMAC_PROTO_BCDC
select FW_LOADER
---help---
This option enables the USB bus interface support for Broadcom
@@ -52,6 +60,8 @@ config BRCMFMAC_PCIE
bool "PCIE bus interface support for FullMAC driver"
depends on BRCMFMAC
depends on PCI
+ depends on HAS_DMA
+ select BRCMFMAC_PROTO_MSGBUF
select FW_LOADER
---help---
This option enables the PCIE bus interface support for Broadcom
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/Makefile b/drivers/net/wireless/brcm80211/brcmfmac/Makefile
index c35adf4bc70b..90a977fe9a64 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/Makefile
+++ b/drivers/net/wireless/brcm80211/brcmfmac/Makefile
@@ -30,16 +30,18 @@ brcmfmac-objs += \
fwsignal.o \
p2p.o \
proto.o \
- bcdc.o \
- commonring.o \
- flowring.o \
- msgbuf.o \
dhd_common.o \
dhd_linux.o \
firmware.o \
feature.o \
btcoex.o \
vendor.o
+brcmfmac-$(CONFIG_BRCMFMAC_PROTO_BCDC) += \
+ bcdc.o
+brcmfmac-$(CONFIG_BRCMFMAC_PROTO_MSGBUF) += \
+ commonring.o \
+ flowring.o \
+ msgbuf.o
brcmfmac-$(CONFIG_BRCMFMAC_SDIO) += \
dhd_sdio.o \
bcmsdh.o
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcdc.h b/drivers/net/wireless/brcm80211/brcmfmac/bcdc.h
index 17e8c039ff32..6003179c0ceb 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/bcdc.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/bcdc.h
@@ -16,9 +16,12 @@
#ifndef BRCMFMAC_BCDC_H
#define BRCMFMAC_BCDC_H
-
+#ifdef CONFIG_BRCMFMAC_PROTO_BCDC
int brcmf_proto_bcdc_attach(struct brcmf_pub *drvr);
void brcmf_proto_bcdc_detach(struct brcmf_pub *drvr);
-
+#else
+static inline int brcmf_proto_bcdc_attach(struct brcmf_pub *drvr) { return 0; }
+static inline void brcmf_proto_bcdc_detach(struct brcmf_pub *drvr) {}
+#endif
#endif /* BRCMFMAC_BCDC_H */
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fweh.c b/drivers/net/wireless/brcm80211/brcmfmac/fweh.c
index 4f1daabc551b..44fc85f68f7a 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/fweh.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fweh.c
@@ -185,7 +185,13 @@ static void brcmf_fweh_handle_if_event(struct brcmf_pub *drvr,
ifevent->action, ifevent->ifidx, ifevent->bssidx,
ifevent->flags, ifevent->role);
- if (ifevent->flags & BRCMF_E_IF_FLAG_NOIF) {
+ /* The P2P Device interface event must not be ignored
+ * contrary to what firmware tells us. The only way to
+ * distinguish the P2P Device is by looking at the ifidx
+ * and bssidx received.
+ */
+ if (!(ifevent->ifidx == 0 && ifevent->bssidx == 1) &&
+ (ifevent->flags & BRCMF_E_IF_FLAG_NOIF)) {
brcmf_dbg(EVENT, "event can be ignored\n");
return;
}
@@ -210,12 +216,12 @@ static void brcmf_fweh_handle_if_event(struct brcmf_pub *drvr,
return;
}
- if (ifevent->action == BRCMF_E_IF_CHANGE)
+ if (ifp && ifevent->action == BRCMF_E_IF_CHANGE)
brcmf_fws_reset_interface(ifp);
err = brcmf_fweh_call_event_handler(ifp, emsg->event_code, emsg, data);
- if (ifevent->action == BRCMF_E_IF_DEL) {
+ if (ifp && ifevent->action == BRCMF_E_IF_DEL) {
brcmf_fws_del_interface(ifp);
brcmf_del_if(drvr, ifevent->bssidx);
}
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fweh.h b/drivers/net/wireless/brcm80211/brcmfmac/fweh.h
index dd20b1862d44..cbf033f59109 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/fweh.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fweh.h
@@ -172,6 +172,8 @@ enum brcmf_fweh_event_code {
#define BRCMF_E_IF_ROLE_STA 0
#define BRCMF_E_IF_ROLE_AP 1
#define BRCMF_E_IF_ROLE_WDS 2
+#define BRCMF_E_IF_ROLE_P2P_GO 3
+#define BRCMF_E_IF_ROLE_P2P_CLIENT 4
/**
* definitions for event packet validation.
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.h b/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.h
index f901ae52bf2b..77a51b8c1e12 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.h
@@ -15,6 +15,7 @@
#ifndef BRCMFMAC_MSGBUF_H
#define BRCMFMAC_MSGBUF_H
+#ifdef CONFIG_BRCMFMAC_PROTO_MSGBUF
#define BRCMF_H2D_MSGRING_CONTROL_SUBMIT_MAX_ITEM 20
#define BRCMF_H2D_MSGRING_RXPOST_SUBMIT_MAX_ITEM 256
@@ -32,9 +33,15 @@
int brcmf_proto_msgbuf_rx_trigger(struct device *dev);
+void brcmf_msgbuf_delete_flowring(struct brcmf_pub *drvr, u8 flowid);
int brcmf_proto_msgbuf_attach(struct brcmf_pub *drvr);
void brcmf_proto_msgbuf_detach(struct brcmf_pub *drvr);
-void brcmf_msgbuf_delete_flowring(struct brcmf_pub *drvr, u8 flowid);
-
+#else
+static inline int brcmf_proto_msgbuf_attach(struct brcmf_pub *drvr)
+{
+ return 0;
+}
+static inline void brcmf_proto_msgbuf_detach(struct brcmf_pub *drvr) {}
+#endif
#endif /* BRCMFMAC_MSGBUF_H */
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
index 02fe706fc9ec..f3a9804988a6 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
@@ -497,8 +497,11 @@ brcmf_configure_arp_offload(struct brcmf_if *ifp, bool enable)
static void
brcmf_cfg80211_update_proto_addr_mode(struct wireless_dev *wdev)
{
- struct net_device *ndev = wdev->netdev;
- struct brcmf_if *ifp = netdev_priv(ndev);
+ struct brcmf_cfg80211_vif *vif;
+ struct brcmf_if *ifp;
+
+ vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
+ ifp = vif->ifp;
if ((wdev->iftype == NL80211_IFTYPE_ADHOC) ||
(wdev->iftype == NL80211_IFTYPE_AP) ||
@@ -5143,6 +5146,7 @@ static int brcmf_enable_bw40_2g(struct brcmf_cfg80211_info *cfg)
ch.band = BRCMU_CHAN_BAND_2G;
ch.bw = BRCMU_CHAN_BW_40;
+ ch.sb = BRCMU_CHAN_SB_NONE;
ch.chnum = 0;
cfg->d11inf.encchspec(&ch);
@@ -5176,6 +5180,7 @@ static int brcmf_enable_bw40_2g(struct brcmf_cfg80211_info *cfg)
brcmf_update_bw40_channel_flag(&band->channels[j], &ch);
}
+ kfree(pbuf);
}
return err;
}
diff --git a/net/rfkill/rfkill-gpio.c b/net/rfkill/rfkill-gpio.c
index 02a86a27fd84..5fa54dd78e25 100644
--- a/net/rfkill/rfkill-gpio.c
+++ b/net/rfkill/rfkill-gpio.c
@@ -163,6 +163,7 @@ static const struct acpi_device_id rfkill_acpi_match[] = {
{ "LNV4752", RFKILL_TYPE_GPS },
{ },
};
+MODULE_DEVICE_TABLE(acpi, rfkill_acpi_match);
#endif
static struct platform_driver rfkill_gpio_driver = {
--
John W. Linville Someday the world will need a hero, and you
linville@tuxdriver.com might be all we have. Be ready.
[-- Attachment #2: Type: application/pgp-signature, Size: 819 bytes --]
^ permalink raw reply related
* [PATCH 1/2 v2 nf-next] net: bridge: don't register netfilter call_iptables hooks by default
From: Florian Westphal @ 2014-09-17 15:52 UTC (permalink / raw)
To: netfilter-devel; +Cc: netdev, Florian Westphal
Jesper reports that kernels with CONFIG_BRIDGE_NETFILTER=n show significantly
better performance vs. CONFIG_BRIDGE_NETFILTER=y, even with
bridge-nf-call-iptables=0.
This is because bridge registers some bridge netfilter hooks at
module load time, so the static key to bypass nf rule evaluation
via NF_HOOK() is false.
The hooks serve no purpose, unless iptables filtering for bridges is
desired (i.e., bridge-nf-call-*=1 and active iptables rules present).
The proper solution would be to just change the bridge-nf-call-iptables sysctl
default value to 0 and then register the hooks when user enables call-iptables
sysctl. We cannot do that though since it breaks existing setups.
The next best solution is to delay registering of the hooks until
we know that
a) call-iptables sysctl is enabled (this is the default)
AND
b) ip(6)tables rules are loaded.
This adds br_nf_check_calliptables() helper in bridge input before
bridge 'prerouting' (sic) hooks to perform this check.
IOW, if user does not turn off call-iptables sysctl on the bridge, hook
registering is only done if NFPROTO_IPV4/IPV6 hooks are registered as
well once the first packet arrives on a bridge port.
Doing this check for every packet is still faster than registering
the hooks unconditionally. To not add overhead for setups where
the call-iptables hooks are required, a static key shortcut is provided.
As its not possible to register hooks from bh context (grabs mutex)
its scheduled via workqueue.
Note that, to not make this overly complicated, the hooks are not
unregistered again when the sysctl is disabled later on.
If user toggles call-iptables sysctl to 0 before adding any ports
to the bridge, those hooks are not registered even if iptables rules
are loaded.
Daniel reports following results for super_netperf/200/TCP_RR:
CONFIG_BRIDGE_NETFILTER=n: ~988k TPS
CONFIG_BRIDGE_NETFILTER=y: ~971k TPS
CONFIG_BRIDGE_NETFILTER=y /w patch: ~988k TPS
This change can be removed once the default sysctl values
are changed to 0.
Reported-by: Jesper Dangaard Brouer <brouer@redhat.com>
Tested-by: Daniel Borkmann <dborkman@redhat.com>
Signed-off-by: Florian Westphal <fw@strlen.de>
---
Changes since v1:
- don't use mutex for synchronizing vs. work queue (Nik Alexandrov),
instead use cmpxchg() to ensure only once cpu can register hook.
- use bool return type since the -ERR values were not used
net/bridge/br_input.c | 39 +++++++++++++++++++++++++++++
net/bridge/br_netfilter.c | 62 +++++++++++++++++++++++++++++++++++++----------
net/bridge/br_private.h | 15 ++++++++++++
3 files changed, 103 insertions(+), 13 deletions(-)
diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c
index 366c436..874d023 100644
--- a/net/bridge/br_input.c
+++ b/net/bridge/br_input.c
@@ -18,6 +18,11 @@
#include <linux/netfilter_bridge.h>
#include <linux/export.h>
#include <linux/rculist.h>
+
+#ifdef CONFIG_BRIDGE_NETFILTER
+#include <linux/jump_label.h>
+#endif
+
#include "br_private.h"
/* Hook for brouter */
@@ -153,6 +158,37 @@ static int br_handle_local_finish(struct sk_buff *skb)
return 0; /* process further */
}
+static inline bool br_nf_check_calliptables(const struct net_bridge *br)
+{
+#ifdef CONFIG_BRIDGE_NETFILTER
+ bool ip, ip6, arp;
+ int i;
+
+ if (static_key_true(&brnf_hooks_active))
+ return true; /* ok, hooks registered */
+
+ ip = brnf_call_iptables || br->nf_call_iptables;
+ ip6 = brnf_call_ip6tables || br->nf_call_ip6tables;
+ arp = brnf_call_arptables || br->nf_call_arptables;
+
+ for (i=0; i < NF_MAX_HOOKS; i++) {
+ if (nf_hooks_active(NFPROTO_IPV4, i) && ip)
+ break;
+ if (nf_hooks_active(NFPROTO_IPV6, i) && ip6)
+ break;
+ if (nf_hooks_active(NFPROTO_ARP, i) && arp)
+ break;
+ }
+
+ /* rules active and nf_call_iptables is set, need to register
+ * the required hooks.
+ */
+ if (i < NF_MAX_HOOKS)
+ return br_netfiler_hooks_init();
+#endif
+ return true; /* also ok: hooks are not needed */
+}
+
/*
* Return NULL if skb is handled
* note: already called with rcu_read_lock
@@ -176,6 +212,9 @@ rx_handler_result_t br_handle_frame(struct sk_buff **pskb)
p = br_port_get_rcu(skb->dev);
+ if (!br_nf_check_calliptables(p->br))
+ goto drop;
+
if (unlikely(is_link_local_ether_addr(dest))) {
u16 fwd_mask = p->br->group_fwd_mask_required;
diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c
index a615264..52c410f 100644
--- a/net/bridge/br_netfilter.c
+++ b/net/bridge/br_netfilter.c
@@ -31,6 +31,8 @@
#include <linux/netfilter_arp.h>
#include <linux/in_route.h>
#include <linux/inetdevice.h>
+#include <linux/workqueue.h>
+#include <linux/jump_label.h>
#include <net/ip.h>
#include <net/ipv6.h>
@@ -47,18 +49,19 @@
#define store_orig_dstaddr(skb) (skb_origaddr(skb) = ip_hdr(skb)->daddr)
#define dnat_took_place(skb) (skb_origaddr(skb) != ip_hdr(skb)->daddr)
+struct static_key brnf_hooks_active __read_mostly;
+static u32 brnf_hooks_loading __read_mostly;
+
#ifdef CONFIG_SYSCTL
static struct ctl_table_header *brnf_sysctl_header;
-static int brnf_call_iptables __read_mostly = 1;
-static int brnf_call_ip6tables __read_mostly = 1;
-static int brnf_call_arptables __read_mostly = 1;
static int brnf_filter_vlan_tagged __read_mostly = 0;
static int brnf_filter_pppoe_tagged __read_mostly = 0;
static int brnf_pass_vlan_indev __read_mostly = 0;
+
+int brnf_call_iptables __read_mostly = 1;
+int brnf_call_ip6tables __read_mostly = 1;
+int brnf_call_arptables __read_mostly = 1;
#else
-#define brnf_call_iptables 1
-#define brnf_call_ip6tables 1
-#define brnf_call_arptables 1
#define brnf_filter_vlan_tagged 0
#define brnf_filter_pppoe_tagged 0
#define brnf_pass_vlan_indev 0
@@ -1059,6 +1062,39 @@ static struct ctl_table brnf_table[] = {
};
#endif
+static void __br_register_hooks_init(struct work_struct *w)
+{
+ int ret = nf_register_hooks(br_nf_ops, ARRAY_SIZE(br_nf_ops));
+
+ kfree(w);
+
+ if (ret) {
+ WARN_ONCE(ret, "could not register bridge netfilter hook (error %d)",
+ ret);
+ brnf_hooks_loading = 0;
+ return;
+ }
+ static_key_slow_inc(&brnf_hooks_active);
+}
+
+bool br_netfiler_hooks_init(void)
+{
+ struct work_struct *w;
+
+ if (cmpxchg(&brnf_hooks_loading, 0, 1) != 0)
+ return false; /* wq not finished */
+
+ w = kzalloc(sizeof(*w), GFP_ATOMIC);
+ if (!w) {
+ brnf_hooks_loading = 0;
+ return false;
+ }
+
+ INIT_WORK(w, __br_register_hooks_init);
+ schedule_work(w);
+ return false;
+}
+
int __init br_netfilter_init(void)
{
int ret;
@@ -1067,17 +1103,11 @@ int __init br_netfilter_init(void)
if (ret < 0)
return ret;
- ret = nf_register_hooks(br_nf_ops, ARRAY_SIZE(br_nf_ops));
- if (ret < 0) {
- dst_entries_destroy(&fake_dst_ops);
- return ret;
- }
#ifdef CONFIG_SYSCTL
brnf_sysctl_header = register_net_sysctl(&init_net, "net/bridge", brnf_table);
if (brnf_sysctl_header == NULL) {
printk(KERN_WARNING
"br_netfilter: can't register to sysctl.\n");
- nf_unregister_hooks(br_nf_ops, ARRAY_SIZE(br_nf_ops));
dst_entries_destroy(&fake_dst_ops);
return -ENOMEM;
}
@@ -1088,7 +1118,13 @@ int __init br_netfilter_init(void)
void br_netfilter_fini(void)
{
- nf_unregister_hooks(br_nf_ops, ARRAY_SIZE(br_nf_ops));
+ while (brnf_hooks_loading && static_key_false(&brnf_hooks_active)) {
+ pr_info("waiting for hook register wq to finish");
+ schedule();
+ }
+ if (brnf_hooks_loading)
+ nf_unregister_hooks(br_nf_ops, ARRAY_SIZE(br_nf_ops));
+
#ifdef CONFIG_SYSCTL
unregister_net_sysctl_table(brnf_sysctl_header);
#endif
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
index 62a7fa2..7b39f0d 100644
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -426,6 +426,10 @@ void br_port_flags_change(struct net_bridge_port *port, unsigned long mask);
void br_manage_promisc(struct net_bridge *br);
/* br_input.c */
+#ifdef CONFIG_BRIDGE_NETFILTER
+extern struct static_key brnf_hooks_active __read_mostly;
+#endif
+
int br_handle_frame_finish(struct sk_buff *skb);
rx_handler_result_t br_handle_frame(struct sk_buff **pskb);
@@ -755,6 +759,17 @@ static inline int br_vlan_enabled(struct net_bridge *br)
int br_netfilter_init(void);
void br_netfilter_fini(void);
void br_netfilter_rtable_init(struct net_bridge *);
+bool br_netfiler_hooks_init(void);
+
+#ifdef CONFIG_SYSCTL
+extern int brnf_call_iptables;
+extern int brnf_call_ip6tables;
+extern int brnf_call_arptables;
+#else
+#define brnf_call_iptables 1
+#define brnf_call_ip6tables 1
+#define brnf_call_arptables 1
+#endif
#else
#define br_netfilter_init() (0)
#define br_netfilter_fini() do { } while (0)
--
1.8.1.5
^ permalink raw reply related
* [PATCH 2/2 nf-next] net: bridge: deprecate call_iptables=1 default value
From: Florian Westphal @ 2014-09-17 15:52 UTC (permalink / raw)
To: netfilter-devel; +Cc: netdev, Florian Westphal
In-Reply-To: <1410969137-11885-1-git-send-email-fw@strlen.de>
add a warning and tell users to set call_iptables to 0 or 1
depending on desired behaviour before adding ports to the bridge.
In distant future, this might allow to disable call_iptables by default.
Signed-off-by: Florian Westphal <fw@strlen.de>
---
no changes since v1.
net/bridge/br_netfilter.c | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c
index 52c410f..e0b581d 100644
--- a/net/bridge/br_netfilter.c
+++ b/net/bridge/br_netfilter.c
@@ -58,9 +58,9 @@ static int brnf_filter_vlan_tagged __read_mostly = 0;
static int brnf_filter_pppoe_tagged __read_mostly = 0;
static int brnf_pass_vlan_indev __read_mostly = 0;
-int brnf_call_iptables __read_mostly = 1;
-int brnf_call_ip6tables __read_mostly = 1;
-int brnf_call_arptables __read_mostly = 1;
+int brnf_call_iptables __read_mostly = 2;
+int brnf_call_ip6tables __read_mostly = 2;
+int brnf_call_arptables __read_mostly = 2;
#else
#define brnf_filter_vlan_tagged 0
#define brnf_filter_pppoe_tagged 0
@@ -1075,6 +1075,12 @@ static void __br_register_hooks_init(struct work_struct *w)
return;
}
static_key_slow_inc(&brnf_hooks_active);
+
+ if ((brnf_call_iptables|brnf_call_ip6tables|brnf_call_arptables) == 2)
+ pr_info("bridge: automatic filtering via arp/ip/ip6tables "
+ "is deprecated and it will be disabled soon. Set "
+ "bridge-nf-call-{ip,ip6,arp}tables sysctls to 1 or 0 "
+ "before adding bridge ports if you need this.\n");
}
bool br_netfiler_hooks_init(void)
--
1.8.1.5
^ permalink raw reply related
* Cannot move macvlan interface on top of bonding device
From: Francesco Ruggeri @ 2014-09-17 15:56 UTC (permalink / raw)
To: netdev; +Cc: David S. Miller, Weilong Chen, Florian Westphal,
Francesco Ruggeri
I cannot move a macvlan interface created on top of a bonding interface
to a different namespace:
# ip netns add dummy0
# ip link add link bond0 mac0 type macvlan
# ip link set mac0 netns dummy0
RTNETLINK answers: Invalid argument
#
This used to work in older releases.
The problem seems to be that commit f939981492 sets NETIF_F_NETNS_LOCAL
on bonding interfaces, and commit 797f87f83 causes macvlan interfaces
to inherit its features from the lower device.
Is there a reason why NETIF_F_NETNS_LOCAL should be inherited from the
lower device
by macvlan interfaces?
Thanks,
Francesco Ruggeri
^ permalink raw reply
* Re: [PATCH v2 3/4] net: stmmac: add support for Intel Quark X1000
From: David Miller @ 2014-09-17 15:57 UTC (permalink / raw)
To: hock.leong.kweh
Cc: peppe.cavallaro, rayagond, vbridgers2013, srinivas.kandagatla,
wens, netdev, linux-kernel, boon.leong.ong
In-Reply-To: <F54AEECA5E2B9541821D670476DAE19C2B7E9F5F@PGSMSX102.gar.corp.intel.com>
I'm not discussing things in private email, keep the discussion on-list so
that any developer, not just me, can answer you.
^ permalink raw reply
* Re: [PATCH v13 net-next 07/11] bpf: verifier (add ability to receive verification log)
From: Alexei Starovoitov @ 2014-09-17 16:08 UTC (permalink / raw)
To: Daniel Borkmann
Cc: David S. Miller, Ingo Molnar, Linus Torvalds, Andy Lutomirski,
Hannes Frederic Sowa, Chema Gonzalez, Eric Dumazet,
Peter Zijlstra, Pablo Neira Ayuso, H. Peter Anvin, Andrew Morton,
Kees Cook, Linux API, Network Development, LKML
In-Reply-To: <54192F66.8020200@redhat.com>
On Tue, Sep 16, 2014 at 11:51 PM, Daniel Borkmann <dborkman@redhat.com> wrote:
>>
>> /* last field in 'union bpf_attr' used by this command */
>> -#define BPF_PROG_LOAD_LAST_FIELD license
>> +#define BPF_PROG_LOAD_LAST_FIELD log_buf
>
>
> I was looking to find a use case for this item, but couldn't find anything,
> so
> this seems to be dead code?
See CHECK_ATTR() macro and comment next to it in patch #1
> Was it, so that each time you extend an uapi structure like above that you
> would
> only access the structure up to BPF_PROG_LOAD_LAST_FIELD? That might not
> work for
> old binaries using this ABI running on newer kernels where there are
> different
> expectations of what BPF_PROG_LOAD_LAST_FIELD has been at the time of
> compilation.
exactly the opposite.
CHECK_ATTR() is checking that all fields beyond last for given
command are zero, so we can extend bpf_attr with new fields
added after last.
Transition from patch 4 to patch 7 and the hunk you quoted are
demonstrating exactly that. Say, userspace was compiled
with bpf_attr as defined in patch 4 and it populated fields all the way
till 'license', and kernel is compiled with patch 7. Kernel does:
union bpf_attr attr = {};
/* copy attributes from user space, may be less than sizeof(bpf_attr) */
copy_from_user(&attr, uattr, size)
so newer fields (all the way till log_buf) stay zero and kernel
behavior is the same as it was in patch 4.
So older user space works as-is with newer kernel.
Another example:
say, we want to add another flag to lookup() method added in patch 3,
we just add another 'flags' field after 'value' field and adjust:
-#define BPF_MAP_LOOKUP_ELEM_LAST_FIELD value
+#define BPF_MAP_LOOKUP_ELEM_LAST_FIELD flags
Older user apps stay binary compatible with newer kernel.
Does this explain things?
>> +
>> + /* grab the mutex to protect few globals used by verifier */
>> + mutex_lock(&bpf_verifier_lock);
>
>
> So only because of the verifier error log (which are global vars here) we
> now have to hold a eBPF-related mutex lock each time when attaching a
> program?
correct.
it's done on purpose to simplify verifier code.
User app is blocked in bpf syscall until verifier checks the program.
Not a big deal. I don't expect a lot of concurrent program loading.
If it somehow becomes an issue, when can fix it, but for now I think
less lines of verifier code is definitely a better trade off.
> Also, if you really have to do the verifier error log, can't we spare
> ourself
> most part of the textifying parts if you would encode the verifier log into
> a
> normal structure array with eBPF specific error codes and then do all this
> pretty printing in user space? Why is that impossible? I really think it's
> odd.
I thought I explained this already...
verifier log is not at all "an array of specific error codes".
verifier is printing the trace and state of what it's seeing
while analyzing the program. Very branchy program may
generate a trace log several times larger than program size.
pretty text is the most convenient way to pass it to user.
Theoretically we can come with some obscure log format for
this internal verifier state, but what do we get ? only additional
complexity. This obscure format will change just as text will
change, because verifier will evolve. If you're looking for a way
to fix this output into ABI, it's not possible. Verifier will
become more advanced in the future and it's trace whether
in text or in obscure encoded structs will change.
Therefore text is much simpler option.
Also consider the learning curve for somebody planning
to add new features to verifier. This trace log is a perfect way
to understand how verifier is working. Try simple program
with multiple branches and see what kind of log is dumped.
Another example:
To make verifier easier to review, in this patch set I didn't
include 'state pruning optimization' patch. That patch
will change the trace log, because it changes the way
verifier is working. If we had to introduce struct
encoding of trace log, it would need to be changed already.
So pretty text is the simplest and most convenient way.
^ permalink raw reply
* [PATCH net] openvswitch: restore OVS_FLOW_CMD_NEW notifications
From: Nicolas Dichtel @ 2014-09-17 16:13 UTC (permalink / raw)
To: pshelar; +Cc: davem, dev, netdev, Samuel Gauthier, Nicolas Dichtel
From: Samuel Gauthier <samuel.gauthier@6wind.com>
Since commit fb5d1e9e127a ("openvswitch: Build flow cmd netlink reply only if needed."),
the new flows are not notified to the listeners of OVS_FLOW_MCGROUP.
This commit fixes the problem by checking that there are listeners in
the actual OVS_FLOW_MCGROUP group, instead of 0.
Signed-off-by: Samuel Gauthier <samuel.gauthier@6wind.com>
Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
---
net/openvswitch/datapath.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c
index 91d66b7e64ac..8396f6063343 100644
--- a/net/openvswitch/datapath.c
+++ b/net/openvswitch/datapath.c
@@ -79,10 +79,10 @@ static const struct genl_multicast_group ovs_dp_vport_multicast_group = {
/* Check if need to build a reply message.
* OVS userspace sets the NLM_F_ECHO flag if it needs the reply. */
static bool ovs_must_notify(struct genl_info *info,
- const struct genl_multicast_group *grp)
+ unsigned int group)
{
return info->nlhdr->nlmsg_flags & NLM_F_ECHO ||
- netlink_has_listeners(genl_info_net(info)->genl_sock, 0);
+ netlink_has_listeners(genl_info_net(info)->genl_sock, group);
}
static void ovs_notify(struct genl_family *family,
@@ -763,7 +763,7 @@ static struct sk_buff *ovs_flow_cmd_alloc_info(const struct sw_flow_actions *act
{
struct sk_buff *skb;
- if (!always && !ovs_must_notify(info, &ovs_dp_flow_multicast_group))
+ if (!always && !ovs_must_notify(info, dp_flow_genl_family.mcgrp_offset))
return NULL;
skb = genlmsg_new_unicast(ovs_flow_cmd_msg_size(acts), info, GFP_KERNEL);
--
2.1.0
^ permalink raw reply related
* Re: [PATCH v11 net-next 12/12] bpf: mini eBPF library, test stubs and verifier testsuite
From: Alexei Starovoitov @ 2014-09-17 16:17 UTC (permalink / raw)
To: Daniel Borkmann
Cc: David S. Miller, Ingo Molnar, Linus Torvalds, Andy Lutomirski,
Steven Rostedt, Hannes Frederic Sowa, Chema Gonzalez,
Eric Dumazet, Peter Zijlstra, Pablo Neira Ayuso, H. Peter Anvin,
Andrew Morton, Kees Cook, Linux API, Network Development, LKML
In-Reply-To: <54193542.6080101@redhat.com>
On Wed, Sep 17, 2014 at 12:16 AM, Daniel Borkmann <dborkman@redhat.com> wrote:
>
>
> That actually still doesn't answer my question why the test stub
> cannot live in lib/test_bpf where we have our actual testing
> framework for eBPF/BPF, also since you exactly only build test_stub.c
> when TEST_BPF is enabled which is the Kconfig for lib/test_bpf.
multiple reasons:
1.
lib/test_bpf.c is a module, whereas test_stub.c is kernel builtin.
2.
I wasn't sure that reusing CONFIG_TEST_BPF for this
purpose was a good idea. May be it's better to introduce
CONFIG_BPF_VERIFIER_TEST_STUBS or something.
3.
kernel/bpf/test_stubs.c can be removed once real tracing
or socket use case is in.
^ permalink raw reply
* Re: [net-next PATCH] net: sched: cls_u32: rcu can not be last node
From: Cong Wang @ 2014-09-17 16:40 UTC (permalink / raw)
To: Oliver Hartkopp
Cc: John Fastabend, David Miller, Eric Dumazet,
Linux Kernel Network Developers, Jamal Hadi Salim
In-Reply-To: <541921FD.1090203@hartkopp.net>
On Tue, Sep 16, 2014 at 10:54 PM, Oliver Hartkopp
<socketcan@hartkopp.net> wrote:
> Please add an appropriate comment to the *code* to prevent this knowledge to
> disappear. No one will search/find this in git commit messages next time.
>
+1
Even though I dig git log, I agree adding a one-line comment is better.
^ permalink raw reply
* Re: Cannot move macvlan interface on top of bonding device
From: Cong Wang @ 2014-09-17 16:46 UTC (permalink / raw)
To: Francesco Ruggeri; +Cc: netdev, David S. Miller, Weilong Chen, Florian Westphal
In-Reply-To: <CA+HUmGi74nx0zELqXX63nJCNXshTC9AkWoRG5bo6AMHyr_3+fg@mail.gmail.com>
On Wed, Sep 17, 2014 at 8:56 AM, Francesco Ruggeri <fruggeri@arista.com> wrote:
> This used to work in older releases.
> The problem seems to be that commit f939981492 sets NETIF_F_NETNS_LOCAL
> on bonding interfaces, and commit 797f87f83 causes macvlan interfaces
> to inherit its features from the lower device.
>
> Is there a reason why NETIF_F_NETNS_LOCAL should be inherited from the
> lower device
> by macvlan interfaces?
commit 797f87f83 looks wrong, it should not inherit NETIF_F_NETNS_LOCAL,
so just clear this flag. Please submit a patch.
^ permalink raw reply
* Re: [PATCH v13 net-next 07/11] bpf: verifier (add ability to receive verification log)
From: Daniel Borkmann @ 2014-09-17 17:03 UTC (permalink / raw)
To: Alexei Starovoitov
Cc: David S. Miller, Ingo Molnar, Linus Torvalds, Andy Lutomirski,
Hannes Frederic Sowa, Chema Gonzalez, Eric Dumazet,
Peter Zijlstra, Pablo Neira Ayuso, H. Peter Anvin, Andrew Morton,
Kees Cook, Linux API, Network Development, LKML
In-Reply-To: <CAMEtUuxK68ZoJ-izjLoygv0f+rLtPmMLUUq1=BJ+_ZBGfynkdA@mail.gmail.com>
On 09/17/2014 06:08 PM, Alexei Starovoitov wrote:
> On Tue, Sep 16, 2014 at 11:51 PM, Daniel Borkmann <dborkman@redhat.com> wrote:
>>>
>>> /* last field in 'union bpf_attr' used by this command */
>>> -#define BPF_PROG_LOAD_LAST_FIELD license
>>> +#define BPF_PROG_LOAD_LAST_FIELD log_buf
>>
>> I was looking to find a use case for this item, but couldn't find anything,
>> so
>> this seems to be dead code?
>
> See CHECK_ATTR() macro and comment next to it in patch #1
>
>> Was it, so that each time you extend an uapi structure like above that you
>> would
>> only access the structure up to BPF_PROG_LOAD_LAST_FIELD? That might not
>> work for
>> old binaries using this ABI running on newer kernels where there are
>> different
>> expectations of what BPF_PROG_LOAD_LAST_FIELD has been at the time of
>> compilation.
>
> exactly the opposite.
> CHECK_ATTR() is checking that all fields beyond last for given
> command are zero, so we can extend bpf_attr with new fields
> added after last.
> Transition from patch 4 to patch 7 and the hunk you quoted are
> demonstrating exactly that. Say, userspace was compiled
> with bpf_attr as defined in patch 4 and it populated fields all the way
> till 'license', and kernel is compiled with patch 7. Kernel does:
> union bpf_attr attr = {};
> /* copy attributes from user space, may be less than sizeof(bpf_attr) */
> copy_from_user(&attr, uattr, size)
> so newer fields (all the way till log_buf) stay zero and kernel
> behavior is the same as it was in patch 4.
> So older user space works as-is with newer kernel.
Ok, I see. Lets say, since the introduction of this syscall you have
added a couple of features and thus extended union bpf_attr where it
grew in size over time.
You built your shiny new binary on that uapi setting, and later on
decide to run it on an older kernel. What will happen is that in your
bpf syscall handler you will return with -EINVAL on that kernel right
away since the size of union bpf_attr is greater.
That would mean over time when new features will get added, applications
that want to make sure to run on _all_ kernels where the bpf syscall is
available have to make sure to either use the _initial_ version of
union bpf_attr in order to not get an -EINVAL, or worse they have
to probe though a syscall different versions of union bpf_attr if they
wish to make use of a particular feature until they do not get an -EINVAL
anymore.
I guess that might be problematic for an application developer that
wants to ship its application across different distributions usually
running different kernels. At least those people might then consider
holding a private copy of the _initial_ version of union bpf_attr in
their own source code, but it's not pleasant I guess.
I know you seem to have the constraint to run on NET-less systems, but
netlink could partially resolve that in the sense that it would allow
to at least load an eBPF program with initial feature set. Couldn't
there be some mechanism to make this interaction more pleasant? E.g.
in BPF extensions we can ask the kernel up to what extension it
supports and accordingly adapt to it up front. I know it's just a
/trivial/ example but have you thought about something on that kind for
the syscall?
^ permalink raw reply
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