Netdev List
 help / color / mirror / Atom feed
* [PATCH net-next] net: fujitsu: Remove ISA depdendency from Kconfig
From: Matthew Whitehead @ 2013-10-04 21:03 UTC (permalink / raw)
  To: netdev; +Cc: Matthew Whitehead

There no longer are ISA drivers in the fujitsu directory, so remove the
dependency from the Kconfig.

Signed-off-by: Matthew Whitehead <tedheadster@gmail.com>
---
 drivers/net/ethernet/fujitsu/Kconfig |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/net/ethernet/fujitsu/Kconfig b/drivers/net/ethernet/fujitsu/Kconfig
index 6231bc0..1085257 100644
--- a/drivers/net/ethernet/fujitsu/Kconfig
+++ b/drivers/net/ethernet/fujitsu/Kconfig
@@ -5,7 +5,7 @@
 config NET_VENDOR_FUJITSU
 	bool "Fujitsu devices"
 	default y
-	depends on ISA || PCMCIA
+	depends on PCMCIA
 	---help---
 	  If you have a network (Ethernet) card belonging to this class, say Y
 	  and read the Ethernet-HOWTO, available from
-- 
1.7.2.5

^ permalink raw reply related

* Re: [PATCH net-next 02/10] qlcnic: Enhance ethtool to display ring indices and interrupt mask
From: Ben Hutchings @ 2013-10-04 20:37 UTC (permalink / raw)
  To: Himanshu Madhani; +Cc: davem, netdev, Dept_NX_Linux_NIC_Driver, Pratik Pujar
In-Reply-To: <6802e3c08711090eada36dead165ab931c4e61db.1380937706.git.himanshu.madhani@qlogic.com>

On Fri, 2013-10-04 at 14:30 -0400, Himanshu Madhani wrote:
> From: Pratik Pujar <pratik.pujar@qlogic.com>
> 
> o Updated ethtool -d <ethX> option to display ring indices for Transmit(Tx),
>   Receive(Rx), and Status(St) rings.
> o Updated ethtool -d <ethX> option to display ring interrupt mask for Transmit(Tx),
>   and Status(St) rings.
> 
> Signed-off-by: Pratik Pujar <pratik.pujar@qlogic.com>
> Signed-off-by: Himanshu Madhani <himanshu.madhani@qlogic.com>
> ---
>  .../net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c    |  8 +--
>  .../net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c    | 61 +++++++++++++++++-----
>  2 files changed, 51 insertions(+), 18 deletions(-)
> 
> diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
> index 66e94dc..c2df4ce 100644
> --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
> +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
[...]
> @@ -512,21 +527,39 @@ qlcnic_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p)
>  	if (!test_bit(__QLCNIC_DEV_UP, &adapter->state))
>  		return;
>  
> -	regs_buff[i++] = 0xFFEFCDAB; /* Marker btw regs and ring count*/
> -
> -	regs_buff[i++] = 1; /* No. of tx ring */
> -	regs_buff[i++] = le32_to_cpu(*(adapter->tx_ring->hw_consumer));
> -	regs_buff[i++] = readl(adapter->tx_ring->crb_cmd_producer);
> -
> -	regs_buff[i++] = 2; /* No. of rx ring */
> -	regs_buff[i++] = readl(recv_ctx->rds_rings[0].crb_rcv_producer);
> -	regs_buff[i++] = readl(recv_ctx->rds_rings[1].crb_rcv_producer);
> -
> -	regs_buff[i++] = adapter->max_sds_rings;
> +	/* Marker btw regs and TX ring count */
> +	regs_buff[i++] = QLCNIC_TX_RING_MARKER;
[...]

This is really sad; why don't you write a proper dump parser for ethtool
rather than including markers that make it slightly easier to read hex
dumps?

And when changing the dump format in an incompatible way like this, you
should also bump the version number.

Ben.

-- 
Ben Hutchings, Staff Engineer, Solarflare
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.

^ permalink raw reply

* Re: Build failure after merge of the drm-intel tree
From: Mark Brown @ 2013-10-04 20:22 UTC (permalink / raw)
  To: Brett Rudley, Arend van Spriel, Franky Lin, Hante Meuleman,
	John W. Linville, Larry Finger, Chaoming Li, Joe Perches,
	David S. Miller
  Cc: linux-next, linux-kernel, Thierry Reding, netdev,
	brcm80211-dev-list, linux-wireless
In-Reply-To: <20131003171440.GD27287@sirena.org.uk>

[-- Attachment #1: Type: text/plain, Size: 16197 bytes --]

While merging the wireless-next tree into -next there were conflicts in
several headers due to conflicts between various commits from Joe
Perches removing extern from headers in the net-next tree and
development in the wireless tree.

I've resolved this as below (sorry, got some extra stuff that resolved
automatically).

diff --cc drivers/net/wireless/ath/ath10k/debug.h
index bb00633,fa58148..6576b82
--- a/drivers/net/wireless/ath/ath10k/debug.h
+++ b/drivers/net/wireless/ath/ath10k/debug.h
@@@ -37,11 -38,13 +38,13 @@@ enum ath10k_debug_mask 
  
  extern unsigned int ath10k_debug_mask;
  
 -extern __printf(1, 2) int ath10k_info(const char *fmt, ...);
 -extern __printf(1, 2) int ath10k_err(const char *fmt, ...);
 -extern __printf(1, 2) int ath10k_warn(const char *fmt, ...);
 +__printf(1, 2) int ath10k_info(const char *fmt, ...);
 +__printf(1, 2) int ath10k_err(const char *fmt, ...);
 +__printf(1, 2) int ath10k_warn(const char *fmt, ...);
  
  #ifdef CONFIG_ATH10K_DEBUGFS
+ int ath10k_debug_start(struct ath10k *ar);
+ void ath10k_debug_stop(struct ath10k *ar);
  int ath10k_debug_create(struct ath10k *ar);
  void ath10k_debug_read_service_map(struct ath10k *ar,
  				   void *service_map,
diff --cc drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c
index c3462b7,091c905..2a23bf2
--- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c
@@@ -464,9 -459,11 +459,9 @@@ static struct sdio_driver brcmf_sdmmc_d
  
  static int brcmf_sdio_pd_probe(struct platform_device *pdev)
  {
 -	int ret;
 -
  	brcmf_dbg(SDIO, "Enter\n");
  
- 	brcmfmac_sdio_pdata = pdev->dev.platform_data;
+ 	brcmfmac_sdio_pdata = dev_get_platdata(&pdev->dev);
  
  	if (brcmfmac_sdio_pdata->power_on)
  		brcmfmac_sdio_pdata->power_on();
diff --cc drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h
index 7f1340d,200ee9b..a6eb09e
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h
@@@ -132,34 -132,34 +132,34 @@@ struct pktq *brcmf_bus_gettxq(struct br
   * interface functions from common layer
   */
  
 -extern bool brcmf_c_prec_enq(struct device *dev, struct pktq *q,
 -			 struct sk_buff *pkt, int prec);
 +bool brcmf_c_prec_enq(struct device *dev, struct pktq *q, struct sk_buff *pkt,
 +		      int prec);
  
  /* Receive frame for delivery to OS.  Callee disposes of rxp. */
- void brcmf_rx_frames(struct device *dev, struct sk_buff_head *rxlist);
 -extern void brcmf_rx_frame(struct device *dev, struct sk_buff *rxp);
++void brcmf_rx_frame(struct device *dev, struct sk_buff *rxp);
  
  /* Indication from bus module regarding presence/insertion of dongle. */
 -extern int brcmf_attach(uint bus_hdrlen, struct device *dev);
 +int brcmf_attach(uint bus_hdrlen, struct device *dev);
  /* Indication from bus module regarding removal/absence of dongle */
 -extern void brcmf_detach(struct device *dev);
 +void brcmf_detach(struct device *dev);
  /* Indication from bus module that dongle should be reset */
 -extern void brcmf_dev_reset(struct device *dev);
 +void brcmf_dev_reset(struct device *dev);
  /* Indication from bus module to change flow-control state */
 -extern void brcmf_txflowblock(struct device *dev, bool state);
 +void brcmf_txflowblock(struct device *dev, bool state);
  
  /* Notify the bus has transferred the tx packet to firmware */
 -extern void brcmf_txcomplete(struct device *dev, struct sk_buff *txp,
 -			     bool success);
 +void brcmf_txcomplete(struct device *dev, struct sk_buff *txp, bool success);
  
 -extern int brcmf_bus_start(struct device *dev);
 +int brcmf_bus_start(struct device *dev);
  
  #ifdef CONFIG_BRCMFMAC_SDIO
 -extern void brcmf_sdio_exit(void);
 -extern void brcmf_sdio_init(void);
 +void brcmf_sdio_exit(void);
 +void brcmf_sdio_init(void);
 +void brcmf_sdio_register(void);
  #endif
  #ifdef CONFIG_BRCMFMAC_USB
 -extern void brcmf_usb_exit(void);
 -extern void brcmf_usb_init(void);
 +void brcmf_usb_exit(void);
 +void brcmf_usb_register(void);
  #endif
  
  #endif				/* _BRCMF_BUS_H_ */
diff --cc drivers/net/wireless/rtlwifi/rtl8188ee/phy.h
index 71ddf4f,d4545f0..8e1f1be
--- a/drivers/net/wireless/rtlwifi/rtl8188ee/phy.h
+++ b/drivers/net/wireless/rtlwifi/rtl8188ee/phy.h
@@@ -200,26 -200,29 +200,25 @@@ enum _ANT_DIV_TYPE 
  	CGCS_RX_SW_ANTDIV		= 0x05,
  };
  
 -extern u32 rtl88e_phy_query_bb_reg(struct ieee80211_hw *hw,
 -				   u32 regaddr, u32 bitmask);
 -extern void rtl88e_phy_set_bb_reg(struct ieee80211_hw *hw,
 -				  u32 regaddr, u32 bitmask, u32 data);
 -extern u32 rtl88e_phy_query_rf_reg(struct ieee80211_hw *hw,
 -				   enum radio_path rfpath, u32 regaddr,
 -				   u32 bitmask);
 -extern void rtl88e_phy_set_rf_reg(struct ieee80211_hw *hw,
 -				  enum radio_path rfpath, u32 regaddr,
 -				  u32 bitmask, u32 data);
 -extern bool rtl88e_phy_mac_config(struct ieee80211_hw *hw);
 -extern bool rtl88e_phy_bb_config(struct ieee80211_hw *hw);
 -extern bool rtl88e_phy_rf_config(struct ieee80211_hw *hw);
 -extern void rtl88e_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw);
 -extern void rtl88e_phy_get_txpower_level(struct ieee80211_hw *hw,
 -					 long *powerlevel);
 -extern void rtl88e_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel);
 -extern void rtl88e_phy_set_bw_mode_callback(struct ieee80211_hw *hw);
 -extern void rtl88e_phy_set_bw_mode(struct ieee80211_hw *hw,
 -				   enum nl80211_channel_type ch_type);
 -extern void rtl88e_phy_sw_chnl_callback(struct ieee80211_hw *hw);
 -extern u8 rtl88e_phy_sw_chnl(struct ieee80211_hw *hw);
 -extern void rtl88e_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery);
 +u32 rtl88e_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask);
 +void rtl88e_phy_set_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask,
 +			   u32 data);
 +u32 rtl88e_phy_query_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath,
 +			    u32 regaddr, u32 bitmask);
 +void rtl88e_phy_set_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath,
 +			   u32 regaddr, u32 bitmask, u32 data);
 +bool rtl88e_phy_mac_config(struct ieee80211_hw *hw);
 +bool rtl88e_phy_bb_config(struct ieee80211_hw *hw);
 +bool rtl88e_phy_rf_config(struct ieee80211_hw *hw);
 +void rtl88e_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw);
 +void rtl88e_phy_get_txpower_level(struct ieee80211_hw *hw, long *powerlevel);
 +void rtl88e_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel);
- void rtl88e_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation);
 +void rtl88e_phy_set_bw_mode_callback(struct ieee80211_hw *hw);
 +void rtl88e_phy_set_bw_mode(struct ieee80211_hw *hw,
 +			    enum nl80211_channel_type ch_type);
 +void rtl88e_phy_sw_chnl_callback(struct ieee80211_hw *hw);
 +u8 rtl88e_phy_sw_chnl(struct ieee80211_hw *hw);
 +void rtl88e_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery);
  void rtl88e_phy_lc_calibrate(struct ieee80211_hw *hw);
  void rtl88e_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain);
  bool rtl88e_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
diff --cc drivers/net/wireless/rtlwifi/rtl8192ce/phy.h
index f8973e5,aeb268b..9bb4658
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/phy.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.h
@@@ -199,14 -200,15 +197,14 @@@ bool rtl92c_phy_mac_config(struct ieee8
  bool rtl92ce_phy_bb_config(struct ieee80211_hw *hw);
  bool rtl92c_phy_rf_config(struct ieee80211_hw *hw);
  bool rtl92c_phy_config_rf_with_feaderfile(struct ieee80211_hw *hw,
 -						 enum radio_path rfpath);
 +					  enum radio_path rfpath);
  void rtl92c_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw);
 -void rtl92c_phy_get_txpower_level(struct ieee80211_hw *hw,
 -					 long *powerlevel);
 +void rtl92c_phy_get_txpower_level(struct ieee80211_hw *hw, long *powerlevel);
  void rtl92c_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel);
- bool rtl92c_phy_update_txpower_dbm(struct ieee80211_hw *hw, long power_indbm);
- void rtl92c_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation);
+ bool rtl92c_phy_update_txpower_dbm(struct ieee80211_hw *hw,
+ 					  long power_indbm);
  void rtl92c_phy_set_bw_mode(struct ieee80211_hw *hw,
 -				   enum nl80211_channel_type ch_type);
 +			    enum nl80211_channel_type ch_type);
  void rtl92c_phy_sw_chnl_callback(struct ieee80211_hw *hw);
  u8 rtl92c_phy_sw_chnl(struct ieee80211_hw *hw);
  void rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery);
@@@ -217,10 -220,10 +215,10 @@@ void _rtl92ce_phy_lc_calibrate(struct i
  void rtl92c_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain);
  bool rtl92c_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
  					  enum radio_path rfpath);
- bool rtl8192_phy_check_is_legal_rfpath(struct ieee80211_hw *hw, u32 rfpath);
- bool rtl92c_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype);
+ bool rtl8192_phy_check_is_legal_rfpath(struct ieee80211_hw *hw,
+ 					      u32 rfpath);
  bool rtl92ce_phy_set_rf_power_state(struct ieee80211_hw *hw,
 -					  enum rf_pwrstate rfpwr_state);
 +				    enum rf_pwrstate rfpwr_state);
  void rtl92ce_phy_set_rf_on(struct ieee80211_hw *hw);
  bool rtl92c_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype);
  void rtl92c_phy_set_io(struct ieee80211_hw *hw);
diff --cc drivers/net/wireless/rtlwifi/rtl8192de/phy.h
index 0f993f4,bef3040..33df0d1c
--- a/drivers/net/wireless/rtlwifi/rtl8192de/phy.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192de/phy.h
@@@ -127,24 -125,26 +125,23 @@@ static inline void rtl92d_release_cckan
  			*flag);
  }
  
 -extern u32 rtl92d_phy_query_bb_reg(struct ieee80211_hw *hw,
 -				   u32 regaddr, u32 bitmask);
 -extern void rtl92d_phy_set_bb_reg(struct ieee80211_hw *hw,
 -				  u32 regaddr, u32 bitmask, u32 data);
 -extern u32 rtl92d_phy_query_rf_reg(struct ieee80211_hw *hw,
 -				   enum radio_path rfpath, u32 regaddr,
 -				   u32 bitmask);
 -extern void rtl92d_phy_set_rf_reg(struct ieee80211_hw *hw,
 -				  enum radio_path rfpath, u32 regaddr,
 -				  u32 bitmask, u32 data);
 -extern bool rtl92d_phy_mac_config(struct ieee80211_hw *hw);
 -extern bool rtl92d_phy_bb_config(struct ieee80211_hw *hw);
 -extern bool rtl92d_phy_rf_config(struct ieee80211_hw *hw);
 -extern bool rtl92c_phy_config_rf_with_feaderfile(struct ieee80211_hw *hw,
 -						 enum radio_path rfpath);
 -extern void rtl92d_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw);
 -extern void rtl92d_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel);
 -extern void rtl92d_phy_set_bw_mode(struct ieee80211_hw *hw,
 -				   enum nl80211_channel_type ch_type);
 -extern u8 rtl92d_phy_sw_chnl(struct ieee80211_hw *hw);
 +u32 rtl92d_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask);
 +void rtl92d_phy_set_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask,
 +			   u32 data);
 +u32 rtl92d_phy_query_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath,
 +			    u32 regaddr, u32 bitmask);
 +void rtl92d_phy_set_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath,
 +			   u32 regaddr, u32 bitmask, u32 data);
 +bool rtl92d_phy_mac_config(struct ieee80211_hw *hw);
 +bool rtl92d_phy_bb_config(struct ieee80211_hw *hw);
 +bool rtl92d_phy_rf_config(struct ieee80211_hw *hw);
 +bool rtl92c_phy_config_rf_with_feaderfile(struct ieee80211_hw *hw,
 +					  enum radio_path rfpath);
 +void rtl92d_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw);
 +void rtl92d_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel);
- void rtl92d_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation);
 +void rtl92d_phy_set_bw_mode(struct ieee80211_hw *hw,
 +			    enum nl80211_channel_type ch_type);
 +u8 rtl92d_phy_sw_chnl(struct ieee80211_hw *hw);
  bool rtl92d_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
  					  enum rf_content content,
  					  enum radio_path rfpath);
diff --cc drivers/net/wireless/rtlwifi/rtl8723ae/phy.h
index bbb950d,3d8f9e3..bb18023
--- a/drivers/net/wireless/rtlwifi/rtl8723ae/phy.h
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/phy.h
@@@ -183,33 -183,34 +183,30 @@@ struct tx_power_struct 
  	u32 mcs_original_offset[4][16];
  };
  
 -extern u32 rtl8723ae_phy_query_bb_reg(struct ieee80211_hw *hw,
 -				      u32 regaddr, u32 bitmask);
 -extern void rtl8723ae_phy_set_bb_reg(struct ieee80211_hw *hw,
 -				     u32 regaddr, u32 bitmask, u32 data);
 -extern u32 rtl8723ae_phy_query_rf_reg(struct ieee80211_hw *hw,
 -				      enum radio_path rfpath, u32 regaddr,
 -				      u32 bitmask);
 -extern void rtl8723ae_phy_set_rf_reg(struct ieee80211_hw *hw,
 -				     enum radio_path rfpath, u32 regaddr,
 -				     u32 bitmask, u32 data);
 -extern bool rtl8723ae_phy_mac_config(struct ieee80211_hw *hw);
 -extern bool rtl8723ae_phy_bb_config(struct ieee80211_hw *hw);
 -extern bool rtl8723ae_phy_rf_config(struct ieee80211_hw *hw);
 -extern bool rtl92c_phy_config_rf_with_feaderfile(struct ieee80211_hw *hw,
 -						 enum radio_path rfpath);
 -extern void rtl8723ae_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw);
 -extern void rtl8723ae_phy_get_txpower_level(struct ieee80211_hw *hw,
 -					    long *powerlevel);
 -extern void rtl8723ae_phy_set_txpower_level(struct ieee80211_hw *hw,
 -					    u8 channel);
 -extern bool rtl8723ae_phy_update_txpower_dbm(struct ieee80211_hw *hw,
 -					     long power_indbm);
 -extern void rtl8723ae_phy_set_bw_mode_callback(struct ieee80211_hw *hw);
 -extern void rtl8723ae_phy_set_bw_mode(struct ieee80211_hw *hw,
 -				      enum nl80211_channel_type ch_type);
 -extern void rtl8723ae_phy_sw_chnl_callback(struct ieee80211_hw *hw);
 -extern u8 rtl8723ae_phy_sw_chnl(struct ieee80211_hw *hw);
 -extern void rtl8723ae_phy_iq_calibrate(struct ieee80211_hw *hw, bool recovery);
 +u32 rtl8723ae_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr,
 +			       u32 bitmask);
- void rtl8723ae_phy_set_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask,
- 			      u32 data);
- u32 rtl8723ae_phy_query_rf_reg(struct ieee80211_hw *hw,
- 			       enum radio_path rfpath, u32 regaddr,
- 			       u32 bitmask);
- void rtl8723ae_phy_set_rf_reg(struct ieee80211_hw *hw,
- 			      enum radio_path rfpath, u32 regaddr, u32 bitmask,
- 			      u32 data);
++void rtl8723ae_phy_set_bb_reg(struct ieee80211_hw *hw, u32 regaddr,
++			      u32 bitmask, u32 data);
++u32 rtl8723ae_phy_query_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath,
++			       u32 regaddr, u32 bitmask);
++void rtl8723ae_phy_set_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath,
++			      u32 regaddr, u32 bitmask, u32 data);
 +bool rtl8723ae_phy_mac_config(struct ieee80211_hw *hw);
 +bool rtl8723ae_phy_bb_config(struct ieee80211_hw *hw);
 +bool rtl8723ae_phy_rf_config(struct ieee80211_hw *hw);
 +bool rtl92c_phy_config_rf_with_feaderfile(struct ieee80211_hw *hw,
 +					  enum radio_path rfpath);
 +void rtl8723ae_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw);
 +void rtl8723ae_phy_get_txpower_level(struct ieee80211_hw *hw, long *powerlevel);
 +void rtl8723ae_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel);
 +bool rtl8723ae_phy_update_txpower_dbm(struct ieee80211_hw *hw,
- 				      long power_indbm);
- void rtl8723ae_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation);
++                                      long power_indbm);
 +void rtl8723ae_phy_set_bw_mode_callback(struct ieee80211_hw *hw);
 +void rtl8723ae_phy_set_bw_mode(struct ieee80211_hw *hw,
 +			       enum nl80211_channel_type ch_type);
 +void rtl8723ae_phy_sw_chnl_callback(struct ieee80211_hw *hw);
 +u8 rtl8723ae_phy_sw_chnl(struct ieee80211_hw *hw);
 +void rtl8723ae_phy_iq_calibrate(struct ieee80211_hw *hw, bool recovery);
  void rtl8723ae_phy_lc_calibrate(struct ieee80211_hw *hw);
  void rtl8723ae_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain);
  bool rtl8723ae_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply

* [PATCH 2/2] ixgbe: enable l2 forwarding acceleration for macvlans
From: Neil Horman @ 2013-10-04 20:10 UTC (permalink / raw)
  To: netdev; +Cc: John Fastabend, Andy Gospodarek, David Miller, Neil Horman
In-Reply-To: <1380917405-23801-1-git-send-email-nhorman@tuxdriver.com>

Now that l2 acceleration ops are in place from the prior patch, enable ixgbe to
take advantage of these operations.  Allow it to allocate queues for a macvlan
so that when we transmit a frame, we can do the switching in hardware inside the
ixgbe card, rather than in software.

Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
CC: John Fastabend <john.r.fastabend@intel.com>
CC: Andy Gospodarek <andy@greyhouse.net>
CC: "David S. Miller" <davem@davemloft.net>
---
 drivers/net/ethernet/intel/ixgbe/ixgbe.h         |  33 +-
 drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c |   4 +-
 drivers/net/ethernet/intel/ixgbe/ixgbe_l2a.h     |  54 ++++
 drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c     |  15 +-
 drivers/net/ethernet/intel/ixgbe/ixgbe_main.c    | 373 +++++++++++++++++------
 5 files changed, 387 insertions(+), 92 deletions(-)
 create mode 100644 drivers/net/ethernet/intel/ixgbe/ixgbe_l2a.h

diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe.h b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
index 0ac6b11..e924efa 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
@@ -219,6 +219,17 @@ enum ixgbe_ring_state_t {
 	__IXGBE_RX_FCOE,
 };
 
+struct ixgbe_fwd_adapter {
+	unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)];
+	struct net_device *netdev;
+	struct ixgbe_adapter *real_adapter;
+	unsigned int tx_base_queue;
+	unsigned int rx_base_queue;
+	struct net_device_stats net_stats;
+	int pool;
+	bool online;
+};
+
 #define check_for_tx_hang(ring) \
 	test_bit(__IXGBE_TX_DETECT_HANG, &(ring)->state)
 #define set_check_for_tx_hang(ring) \
@@ -236,6 +247,7 @@ struct ixgbe_ring {
 	struct ixgbe_q_vector *q_vector; /* backpointer to host q_vector */
 	struct net_device *netdev;	/* netdev ring belongs to */
 	struct device *dev;		/* device for DMA mapping */
+	struct ixgbe_fwd_adapter *l2_accel_priv;
 	void *desc;			/* descriptor ring memory */
 	union {
 		struct ixgbe_tx_buffer *tx_buffer_info;
@@ -244,6 +256,7 @@ struct ixgbe_ring {
 	unsigned long last_rx_timestamp;
 	unsigned long state;
 	u8 __iomem *tail;
+	struct net_device *vmdq_netdev;
 	dma_addr_t dma;			/* phys. address of descriptor ring */
 	unsigned int size;		/* length in bytes */
 
@@ -288,11 +301,15 @@ enum ixgbe_ring_f_enum {
 };
 
 #define IXGBE_MAX_RSS_INDICES  16
-#define IXGBE_MAX_VMDQ_INDICES 64
+#define IXGBE_MAX_VMDQ_INDICES 32
 #define IXGBE_MAX_FDIR_INDICES 63	/* based on q_vector limit */
 #define IXGBE_MAX_FCOE_INDICES  8
 #define MAX_RX_QUEUES (IXGBE_MAX_FDIR_INDICES + 1)
 #define MAX_TX_QUEUES (IXGBE_MAX_FDIR_INDICES + 1)
+#define IXGBE_MAX_L2A_QUEUES 4
+#define IXGBE_MAX_L2A_QUEUES 4
+#define IXGBE_BAD_L2A_QUEUE 3
+
 struct ixgbe_ring_feature {
 	u16 limit;	/* upper limit on feature indices */
 	u16 indices;	/* current value of indices */
@@ -738,6 +755,7 @@ struct ixgbe_adapter {
 #endif /*CONFIG_DEBUG_FS*/
 
 	u8 default_up;
+	unsigned long fwd_bitmask; /* Bitmask indicating in use pools */
 };
 
 struct ixgbe_fdir_filter {
@@ -879,9 +897,14 @@ static inline void ixgbe_dbg_adapter_exit(struct ixgbe_adapter *adapter) {}
 static inline void ixgbe_dbg_init(void) {}
 static inline void ixgbe_dbg_exit(void) {}
 #endif /* CONFIG_DEBUG_FS */
+static inline struct net_device *netdev_ring(const struct ixgbe_ring *ring)
+{
+	return ring->vmdq_netdev ? ring->vmdq_netdev : ring->netdev;
+}
+
 static inline struct netdev_queue *txring_txq(const struct ixgbe_ring *ring)
 {
-	return netdev_get_tx_queue(ring->netdev, ring->queue_index);
+	return netdev_get_tx_queue(netdev_ring(ring), ring->queue_index);
 }
 
 extern void ixgbe_ptp_init(struct ixgbe_adapter *adapter);
@@ -915,4 +938,10 @@ extern void ixgbe_ptp_check_pps_event(struct ixgbe_adapter *adapter, u32 eicr);
 void ixgbe_sriov_reinit(struct ixgbe_adapter *adapter);
 #endif
 
+int ixgbe_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd);
+int ixgbe_write_uc_addr_list(struct net_device *netdev);
+netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb,
+				  struct ixgbe_adapter *adapter,
+				  struct ixgbe_ring *tx_ring);
+void ixgbe_clean_rx_ring(struct ixgbe_ring *rx_ring);
 #endif /* _IXGBE_H_ */
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
index e8649ab..277af14 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
@@ -150,8 +150,8 @@ static const char ixgbe_gstrings_test[][ETH_GSTRING_LEN] = {
 };
 #define IXGBE_TEST_LEN sizeof(ixgbe_gstrings_test) / ETH_GSTRING_LEN
 
-static int ixgbe_get_settings(struct net_device *netdev,
-                              struct ethtool_cmd *ecmd)
+int ixgbe_get_settings(struct net_device *netdev,
+		       struct ethtool_cmd *ecmd)
 {
 	struct ixgbe_adapter *adapter = netdev_priv(netdev);
 	struct ixgbe_hw *hw = &adapter->hw;
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_l2a.h b/drivers/net/ethernet/intel/ixgbe/ixgbe_l2a.h
new file mode 100644
index 0000000..2f36584
--- /dev/null
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_l2a.h
@@ -0,0 +1,54 @@
+/*******************************************************************************
+
+  Intel 10 Gigabit PCI Express Linux driver
+  Copyright(c) 1999 - 2013 Intel Corporation.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms and conditions of the GNU General Public License,
+  version 2, as published by the Free Software Foundation.
+
+  This program is distributed in the hope it will be useful, but WITHOUT
+  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+  more details.
+
+  You should have received a copy of the GNU General Public License along with
+  this program; if not, write to the Free Software Foundation, Inc.,
+  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+  The full GNU General Public License is included in this distribution in
+  the file called "COPYING".
+
+  Contact Information:
+  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
+  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+
+*******************************************************************************/
+#include "ixgbe.h"
+
+
+static inline void ixgbe_irq_enable_queues(struct ixgbe_adapter *adapter,
+					   u64 qmask)
+{
+	u32 mask;
+	struct ixgbe_hw *hw = &adapter->hw;
+
+	switch (hw->mac.type) {
+	case ixgbe_mac_82598EB:
+		mask = (IXGBE_EIMS_RTX_QUEUE & qmask);
+		IXGBE_WRITE_REG(hw, IXGBE_EIMS, mask);
+		break;
+	case ixgbe_mac_82599EB:
+	case ixgbe_mac_X540:
+		mask = (qmask & 0xFFFFFFFF);
+		if (mask)
+			IXGBE_WRITE_REG(hw, IXGBE_EIMS_EX(0), mask);
+		mask = (qmask >> 32);
+		if (mask)
+			IXGBE_WRITE_REG(hw, IXGBE_EIMS_EX(1), mask);
+		break;
+	default:
+		break;
+	}
+	/* skip the flush */
+}
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c
index 90b4e10..e2dd635 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c
@@ -500,7 +500,8 @@ static bool ixgbe_set_sriov_queues(struct ixgbe_adapter *adapter)
 #endif
 
 	/* only proceed if SR-IOV is enabled */
-	if (!(adapter->flags & IXGBE_FLAG_SRIOV_ENABLED))
+	if (!(adapter->flags & IXGBE_FLAG_SRIOV_ENABLED) &&
+	    !(adapter->flags & IXGBE_FLAG_VMDQ_ENABLED))
 		return false;
 
 	/* Add starting offset to total pool count */
@@ -852,7 +853,11 @@ static int ixgbe_alloc_q_vector(struct ixgbe_adapter *adapter,
 
 		/* apply Tx specific ring traits */
 		ring->count = adapter->tx_ring_count;
-		ring->queue_index = txr_idx;
+		if (adapter->num_rx_pools > 1)
+			ring->queue_index =
+				txr_idx % adapter->num_rx_queues_per_pool;
+		else
+			ring->queue_index = txr_idx;
 
 		/* assign ring to adapter */
 		adapter->tx_ring[txr_idx] = ring;
@@ -895,7 +900,11 @@ static int ixgbe_alloc_q_vector(struct ixgbe_adapter *adapter,
 #endif /* IXGBE_FCOE */
 		/* apply Rx specific ring traits */
 		ring->count = adapter->rx_ring_count;
-		ring->queue_index = rxr_idx;
+		if (adapter->num_rx_pools > 1)
+			ring->queue_index =
+				rxr_idx % adapter->num_rx_queues_per_pool;
+		else
+			ring->queue_index = rxr_idx;
 
 		/* assign ring to adapter */
 		adapter->rx_ring[rxr_idx] = ring;
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index 0ade0cd..5fa553f 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -52,6 +52,7 @@
 #include "ixgbe_common.h"
 #include "ixgbe_dcb_82599.h"
 #include "ixgbe_sriov.h"
+#include "ixgbe_l2a.h"
 
 char ixgbe_driver_name[] = "ixgbe";
 static const char ixgbe_driver_string[] =
@@ -118,6 +119,8 @@ static DEFINE_PCI_DEVICE_TABLE(ixgbe_pci_tbl) = {
 };
 MODULE_DEVICE_TABLE(pci, ixgbe_pci_tbl);
 
+netdev_tx_t ixgbe_fwd_xmit_frame(struct sk_buff *skb, void *priv);
+
 #ifdef CONFIG_IXGBE_DCA
 static int ixgbe_notify_dca(struct notifier_block *, unsigned long event,
 			    void *p);
@@ -872,7 +875,8 @@ static u64 ixgbe_get_tx_completed(struct ixgbe_ring *ring)
 
 static u64 ixgbe_get_tx_pending(struct ixgbe_ring *ring)
 {
-	struct ixgbe_adapter *adapter = netdev_priv(ring->netdev);
+	struct net_device *dev = ring->netdev;
+	struct ixgbe_adapter *adapter = netdev_priv(dev);
 	struct ixgbe_hw *hw = &adapter->hw;
 
 	u32 head = IXGBE_READ_REG(hw, IXGBE_TDH(ring->reg_idx));
@@ -1055,7 +1059,7 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector,
 			tx_ring->next_to_use, i,
 			tx_ring->tx_buffer_info[i].time_stamp, jiffies);
 
-		netif_stop_subqueue(tx_ring->netdev, tx_ring->queue_index);
+		netif_stop_subqueue(netdev_ring(tx_ring), tx_ring->queue_index);
 
 		e_info(probe,
 		       "tx hang %d detected on queue %d, resetting adapter\n",
@@ -1072,16 +1076,16 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector,
 				  total_packets, total_bytes);
 
 #define TX_WAKE_THRESHOLD (DESC_NEEDED * 2)
-	if (unlikely(total_packets && netif_carrier_ok(tx_ring->netdev) &&
+	if (unlikely(total_packets && netif_carrier_ok(netdev_ring(tx_ring)) &&
 		     (ixgbe_desc_unused(tx_ring) >= TX_WAKE_THRESHOLD))) {
 		/* Make sure that anybody stopping the queue after this
 		 * sees the new next_to_clean.
 		 */
 		smp_mb();
-		if (__netif_subqueue_stopped(tx_ring->netdev,
+		if (__netif_subqueue_stopped(netdev_ring(tx_ring),
 					     tx_ring->queue_index)
 		    && !test_bit(__IXGBE_DOWN, &adapter->state)) {
-			netif_wake_subqueue(tx_ring->netdev,
+			netif_wake_subqueue(netdev_ring(tx_ring),
 					    tx_ring->queue_index);
 			++tx_ring->tx_stats.restart_queue;
 		}
@@ -1226,7 +1230,7 @@ static inline void ixgbe_rx_hash(struct ixgbe_ring *ring,
 				 union ixgbe_adv_rx_desc *rx_desc,
 				 struct sk_buff *skb)
 {
-	if (ring->netdev->features & NETIF_F_RXHASH)
+	if (netdev_ring(ring)->features & NETIF_F_RXHASH)
 		skb->rxhash = le32_to_cpu(rx_desc->wb.lower.hi_dword.rss);
 }
 
@@ -1260,10 +1264,12 @@ static inline void ixgbe_rx_checksum(struct ixgbe_ring *ring,
 				     union ixgbe_adv_rx_desc *rx_desc,
 				     struct sk_buff *skb)
 {
+	struct net_device *dev = netdev_ring(ring);
+
 	skb_checksum_none_assert(skb);
 
 	/* Rx csum disabled */
-	if (!(ring->netdev->features & NETIF_F_RXCSUM))
+	if (!(dev->features & NETIF_F_RXCSUM))
 		return;
 
 	/* if IP and error */
@@ -1559,7 +1565,7 @@ static void ixgbe_process_skb_fields(struct ixgbe_ring *rx_ring,
 				     union ixgbe_adv_rx_desc *rx_desc,
 				     struct sk_buff *skb)
 {
-	struct net_device *dev = rx_ring->netdev;
+	struct net_device *dev = netdev_ring(rx_ring);
 
 	ixgbe_update_rsc_stats(rx_ring, skb);
 
@@ -1739,7 +1745,7 @@ static bool ixgbe_cleanup_headers(struct ixgbe_ring *rx_ring,
 				  union ixgbe_adv_rx_desc *rx_desc,
 				  struct sk_buff *skb)
 {
-	struct net_device *netdev = rx_ring->netdev;
+	struct net_device *netdev = netdev_ring(rx_ring);
 
 	/* verify that the packet does not have any known errors */
 	if (unlikely(ixgbe_test_staterr(rx_desc,
@@ -1905,7 +1911,7 @@ static struct sk_buff *ixgbe_fetch_rx_buffer(struct ixgbe_ring *rx_ring,
 #endif
 
 		/* allocate a skb to store the frags */
-		skb = netdev_alloc_skb_ip_align(rx_ring->netdev,
+		skb = netdev_alloc_skb_ip_align(netdev_ring(rx_ring),
 						IXGBE_RX_HDR_SIZE);
 		if (unlikely(!skb)) {
 			rx_ring->rx_stats.alloc_rx_buff_failed++;
@@ -1986,6 +1992,7 @@ static int ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector,
 	struct ixgbe_adapter *adapter = q_vector->adapter;
 	int ddp_bytes;
 	unsigned int mss = 0;
+	struct net_device *netdev = netdev_ring(rx_ring);
 #endif /* IXGBE_FCOE */
 	u16 cleaned_count = ixgbe_desc_unused(rx_ring);
 
@@ -1993,6 +2000,10 @@ static int ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector,
 		union ixgbe_adv_rx_desc *rx_desc;
 		struct sk_buff *skb;
 
+		if (rx_ring->l2_accel_priv) {
+			printk(KERN_CRIT "RECEIVING ON AN ACCELERATED QUEUE\n");
+		}
+
 		/* return some buffers to hardware, one at a time is too slow */
 		if (cleaned_count >= IXGBE_RX_BUFFER_WRITE) {
 			ixgbe_alloc_rx_buffers(rx_ring, cleaned_count);
@@ -2041,7 +2052,7 @@ static int ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector,
 			/* include DDPed FCoE data */
 			if (ddp_bytes > 0) {
 				if (!mss) {
-					mss = rx_ring->netdev->mtu -
+					mss = netdev->mtu -
 						sizeof(struct fcoe_hdr) -
 						sizeof(struct fc_frame_header) -
 						sizeof(struct fcoe_crc_eof);
@@ -2455,58 +2466,6 @@ static void ixgbe_check_lsc(struct ixgbe_adapter *adapter)
 	}
 }
 
-static inline void ixgbe_irq_enable_queues(struct ixgbe_adapter *adapter,
-					   u64 qmask)
-{
-	u32 mask;
-	struct ixgbe_hw *hw = &adapter->hw;
-
-	switch (hw->mac.type) {
-	case ixgbe_mac_82598EB:
-		mask = (IXGBE_EIMS_RTX_QUEUE & qmask);
-		IXGBE_WRITE_REG(hw, IXGBE_EIMS, mask);
-		break;
-	case ixgbe_mac_82599EB:
-	case ixgbe_mac_X540:
-		mask = (qmask & 0xFFFFFFFF);
-		if (mask)
-			IXGBE_WRITE_REG(hw, IXGBE_EIMS_EX(0), mask);
-		mask = (qmask >> 32);
-		if (mask)
-			IXGBE_WRITE_REG(hw, IXGBE_EIMS_EX(1), mask);
-		break;
-	default:
-		break;
-	}
-	/* skip the flush */
-}
-
-static inline void ixgbe_irq_disable_queues(struct ixgbe_adapter *adapter,
-					    u64 qmask)
-{
-	u32 mask;
-	struct ixgbe_hw *hw = &adapter->hw;
-
-	switch (hw->mac.type) {
-	case ixgbe_mac_82598EB:
-		mask = (IXGBE_EIMS_RTX_QUEUE & qmask);
-		IXGBE_WRITE_REG(hw, IXGBE_EIMC, mask);
-		break;
-	case ixgbe_mac_82599EB:
-	case ixgbe_mac_X540:
-		mask = (qmask & 0xFFFFFFFF);
-		if (mask)
-			IXGBE_WRITE_REG(hw, IXGBE_EIMC_EX(0), mask);
-		mask = (qmask >> 32);
-		if (mask)
-			IXGBE_WRITE_REG(hw, IXGBE_EIMC_EX(1), mask);
-		break;
-	default:
-		break;
-	}
-	/* skip the flush */
-}
-
 /**
  * ixgbe_irq_enable - Enable default interrupt generation settings
  * @adapter: board private structure
@@ -2946,6 +2905,7 @@ static void ixgbe_configure_msi_and_legacy(struct ixgbe_adapter *adapter)
 void ixgbe_configure_tx_ring(struct ixgbe_adapter *adapter,
 			     struct ixgbe_ring *ring)
 {
+	struct net_device *netdev = netdev_ring(ring);
 	struct ixgbe_hw *hw = &adapter->hw;
 	u64 tdba = ring->dma;
 	int wait_loop = 10;
@@ -3005,7 +2965,7 @@ void ixgbe_configure_tx_ring(struct ixgbe_adapter *adapter,
 		struct ixgbe_q_vector *q_vector = ring->q_vector;
 
 		if (q_vector)
-			netif_set_xps_queue(adapter->netdev,
+			netif_set_xps_queue(netdev,
 					    &q_vector->affinity_mask,
 					    ring->queue_index);
 	}
@@ -3395,7 +3355,7 @@ static void ixgbe_setup_psrtype(struct ixgbe_adapter *adapter)
 {
 	struct ixgbe_hw *hw = &adapter->hw;
 	int rss_i = adapter->ring_feature[RING_F_RSS].indices;
-	int p;
+	u16 pool;
 
 	/* PSRTYPE must be initialized in non 82598 adapters */
 	u32 psrtype = IXGBE_PSRTYPE_TCPHDR |
@@ -3412,9 +3372,8 @@ static void ixgbe_setup_psrtype(struct ixgbe_adapter *adapter)
 	else if (rss_i > 1)
 		psrtype |= 1 << 29;
 
-	for (p = 0; p < adapter->num_rx_pools; p++)
-		IXGBE_WRITE_REG(hw, IXGBE_PSRTYPE(VMDQ_P(p)),
-				psrtype);
+	for_each_set_bit(pool, &adapter->fwd_bitmask, 32)
+		IXGBE_WRITE_REG(hw, IXGBE_PSRTYPE(VMDQ_P(pool)), psrtype);
 }
 
 static void ixgbe_configure_virtualization(struct ixgbe_adapter *adapter)
@@ -3683,6 +3642,8 @@ static void ixgbe_vlan_strip_disable(struct ixgbe_adapter *adapter)
 	case ixgbe_mac_82599EB:
 	case ixgbe_mac_X540:
 		for (i = 0; i < adapter->num_rx_queues; i++) {
+			if (adapter->rx_ring[i]->vmdq_netdev)
+				continue;
 			j = adapter->rx_ring[i]->reg_idx;
 			vlnctrl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(j));
 			vlnctrl &= ~IXGBE_RXDCTL_VME;
@@ -3713,6 +3674,8 @@ static void ixgbe_vlan_strip_enable(struct ixgbe_adapter *adapter)
 	case ixgbe_mac_82599EB:
 	case ixgbe_mac_X540:
 		for (i = 0; i < adapter->num_rx_queues; i++) {
+			if (adapter->rx_ring[i]->vmdq_netdev)
+				continue;
 			j = adapter->rx_ring[i]->reg_idx;
 			vlnctrl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(j));
 			vlnctrl |= IXGBE_RXDCTL_VME;
@@ -3743,15 +3706,16 @@ static void ixgbe_restore_vlan(struct ixgbe_adapter *adapter)
  *                0 on no addresses written
  *                X on writing X addresses to the RAR table
  **/
-static int ixgbe_write_uc_addr_list(struct net_device *netdev)
+int ixgbe_write_uc_addr_list(struct net_device *netdev)
 {
 	struct ixgbe_adapter *adapter = netdev_priv(netdev);
 	struct ixgbe_hw *hw = &adapter->hw;
 	unsigned int rar_entries = hw->mac.num_rar_entries - 1;
 	int count = 0;
 
-	/* In SR-IOV mode significantly less RAR entries are available */
-	if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED)
+	/* In SR-IOV/VMDQ modes significantly less RAR entries are available */
+	if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED ||
+	    adapter->flags & IXGBE_FLAG_VMDQ_ENABLED)
 		rar_entries = IXGBE_MAX_PF_MACVLANS - 1;
 
 	/* return ENOMEM indicating insufficient memory for addresses */
@@ -3772,6 +3736,7 @@ static int ixgbe_write_uc_addr_list(struct net_device *netdev)
 			count++;
 		}
 	}
+
 	/* write the addresses in reverse order to avoid write combining */
 	for (; rar_entries > 0 ; rar_entries--)
 		hw->mac.ops.clear_rar(hw, rar_entries);
@@ -4133,6 +4098,7 @@ static void ixgbe_configure(struct ixgbe_adapter *adapter)
 	ixgbe_configure_virtualization(adapter);
 
 	ixgbe_set_rx_mode(adapter->netdev);
+
 	ixgbe_restore_vlan(adapter);
 
 	switch (hw->mac.type) {
@@ -4459,7 +4425,7 @@ void ixgbe_reset(struct ixgbe_adapter *adapter)
  * ixgbe_clean_rx_ring - Free Rx Buffers per Queue
  * @rx_ring: ring to free buffers from
  **/
-static void ixgbe_clean_rx_ring(struct ixgbe_ring *rx_ring)
+void ixgbe_clean_rx_ring(struct ixgbe_ring *rx_ring)
 {
 	struct device *dev = rx_ring->dev;
 	unsigned long size;
@@ -4838,6 +4804,8 @@ static int ixgbe_sw_init(struct ixgbe_adapter *adapter)
 		return -EIO;
 	}
 
+	/* PF holds first pool slot */
+	set_bit(0, &adapter->fwd_bitmask);
 	set_bit(__IXGBE_DOWN, &adapter->state);
 
 	return 0;
@@ -5143,7 +5111,7 @@ static int ixgbe_change_mtu(struct net_device *netdev, int new_mtu)
 static int ixgbe_open(struct net_device *netdev)
 {
 	struct ixgbe_adapter *adapter = netdev_priv(netdev);
-	int err;
+	int err, queues;
 
 	/* disallow open during test */
 	if (test_bit(__IXGBE_TESTING, &adapter->state))
@@ -5168,16 +5136,22 @@ static int ixgbe_open(struct net_device *netdev)
 		goto err_req_irq;
 
 	/* Notify the stack of the actual queue counts. */
-	err = netif_set_real_num_tx_queues(netdev,
-					   adapter->num_rx_pools > 1 ? 1 :
-					   adapter->num_tx_queues);
+	if (adapter->num_rx_pools > 1 &&
+	    adapter->num_tx_queues > IXGBE_MAX_L2A_QUEUES)
+		queues = IXGBE_MAX_L2A_QUEUES;
+	else
+		queues = adapter->num_tx_queues;
+
+	err = netif_set_real_num_tx_queues(netdev, queues);
 	if (err)
 		goto err_set_queues;
 
-
-	err = netif_set_real_num_rx_queues(netdev,
-					   adapter->num_rx_pools > 1 ? 1 :
-					   adapter->num_rx_queues);
+	if (adapter->num_rx_pools > 1 &&
+	    adapter->num_rx_queues > IXGBE_MAX_L2A_QUEUES)
+		queues = IXGBE_MAX_L2A_QUEUES;
+	else
+		queues = adapter->num_rx_queues;
+	err = netif_set_real_num_rx_queues(netdev, queues);
 	if (err)
 		goto err_set_queues;
 
@@ -5215,7 +5189,6 @@ static int ixgbe_close(struct net_device *netdev)
 	struct ixgbe_adapter *adapter = netdev_priv(netdev);
 
 	ixgbe_ptp_stop(adapter);
-
 	ixgbe_down(adapter);
 	ixgbe_free_irq(adapter);
 
@@ -6576,7 +6549,7 @@ static void ixgbe_atr(struct ixgbe_ring *ring,
 
 static int __ixgbe_maybe_stop_tx(struct ixgbe_ring *tx_ring, u16 size)
 {
-	netif_stop_subqueue(tx_ring->netdev, tx_ring->queue_index);
+	netif_stop_subqueue(netdev_ring(tx_ring), tx_ring->queue_index);
 	/* Herbert's original patch had:
 	 *  smp_mb__after_netif_stop_queue();
 	 * but since that doesn't exist yet, just open code it. */
@@ -6588,7 +6561,7 @@ static int __ixgbe_maybe_stop_tx(struct ixgbe_ring *tx_ring, u16 size)
 		return -EBUSY;
 
 	/* A reprieve! - use start_queue because it doesn't call schedule */
-	netif_start_subqueue(tx_ring->netdev, tx_ring->queue_index);
+	netif_start_subqueue(netdev_ring(tx_ring), tx_ring->queue_index);
 	++tx_ring->tx_stats.restart_queue;
 	return 0;
 }
@@ -6639,6 +6612,9 @@ netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb,
 			  struct ixgbe_ring *tx_ring)
 {
 	struct ixgbe_tx_buffer *first;
+#ifdef IXGBE_FCOE
+	struct net_device *dev;
+#endif
 	int tso;
 	u32 tx_flags = 0;
 	unsigned short f;
@@ -6730,9 +6706,10 @@ netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb,
 	first->protocol = protocol;
 
 #ifdef IXGBE_FCOE
+	dev = netdev_ring(tx_ring);
 	/* setup tx offload for FCoE */
 	if ((protocol == __constant_htons(ETH_P_FCOE)) &&
-	    (tx_ring->netdev->features & (NETIF_F_FSO | NETIF_F_FCOE_CRC))) {
+	    (dev->features & (NETIF_F_FSO | NETIF_F_FCOE_CRC))) {
 		tso = ixgbe_fso(tx_ring, first, &hdr_len);
 		if (tso < 0)
 			goto out_drop;
@@ -6784,7 +6761,15 @@ static netdev_tx_t ixgbe_xmit_frame(struct sk_buff *skb,
 		skb_set_tail_pointer(skb, 17);
 	}
 
-	tx_ring = adapter->tx_ring[skb->queue_mapping];
+	if (skb->accel_priv) {
+		struct ixgbe_fwd_adapter *fwd_adapter = skb->accel_priv;
+		unsigned int queue;
+
+		queue = skb->queue_mapping + fwd_adapter->tx_base_queue;
+		tx_ring = fwd_adapter->real_adapter->tx_ring[queue];
+	} else 
+		tx_ring = adapter->tx_ring[skb->queue_mapping];
+
 	return ixgbe_xmit_frame_ring(skb, adapter, tx_ring);
 }
 
@@ -7057,6 +7042,7 @@ int ixgbe_setup_tc(struct net_device *dev, u8 tc)
 	 */
 	if (netif_running(dev))
 		ixgbe_close(dev);
+
 	ixgbe_clear_interrupt_scheme(adapter);
 
 #ifdef CONFIG_IXGBE_DCB
@@ -7305,6 +7291,217 @@ static int ixgbe_ndo_bridge_getlink(struct sk_buff *skb, u32 pid, u32 seq,
 	return ndo_dflt_bridge_getlink(skb, pid, seq, dev, mode);
 }
 
+static void ixgbe_irq_disable_queues(struct ixgbe_adapter *adapter, u64 qmask)
+{
+	u32 mask;
+	struct ixgbe_hw *hw = &adapter->hw;
+
+	switch (hw->mac.type) {
+	case ixgbe_mac_82598EB:
+		mask = (IXGBE_EIMS_RTX_QUEUE & qmask);
+		IXGBE_WRITE_REG(hw, IXGBE_EIMC, mask);
+		break;
+	case ixgbe_mac_82599EB:
+	case ixgbe_mac_X540:
+		mask = (qmask & 0xFFFFFFFF);
+		if (mask)
+			IXGBE_WRITE_REG(hw, IXGBE_EIMC_EX(0), mask);
+		mask = (qmask >> 32);
+		if (mask)
+			IXGBE_WRITE_REG(hw, IXGBE_EIMC_EX(1), mask);
+		break;
+	default:
+		break;
+	}
+}
+
+static void ixgbe_add_mac_filter(struct ixgbe_adapter *adapter,
+				 u8 *addr, u16 pool)
+{
+	struct ixgbe_hw *hw = &adapter->hw;
+	unsigned int entry;
+
+	entry = hw->mac.num_rar_entries - pool;
+	hw->mac.ops.set_rar(hw, entry, addr, VMDQ_P(pool), IXGBE_RAH_AV);
+}
+
+static void ixgbe_fwd_psrtype(struct ixgbe_fwd_adapter *vadapter)
+{
+	struct ixgbe_adapter *adapter = vadapter->real_adapter;
+	int rss_i = vadapter->netdev->real_num_rx_queues;
+	struct ixgbe_hw *hw = &adapter->hw;
+	u16 pool = vadapter->pool;
+	u32 psrtype = IXGBE_PSRTYPE_TCPHDR |
+		      IXGBE_PSRTYPE_UDPHDR |
+		      IXGBE_PSRTYPE_IPV4HDR |
+		      IXGBE_PSRTYPE_L2HDR |
+		      IXGBE_PSRTYPE_IPV6HDR;
+
+	if (hw->mac.type == ixgbe_mac_82598EB)
+		return;
+
+	if (rss_i > 3)
+		psrtype |= 2 << 29;
+	else if (rss_i > 1)
+		psrtype |= 1 << 29;
+
+	IXGBE_WRITE_REG(hw, IXGBE_PSRTYPE(VMDQ_P(pool)), psrtype);
+}
+
+static void ixgbe_enable_fwd_ring(struct ixgbe_adapter *adapter,
+				  struct ixgbe_ring *rx_ring,
+				  struct ixgbe_fwd_adapter *accel)
+{
+	rx_ring->l2_accel_priv = accel;
+	ixgbe_configure_rx_ring(adapter, rx_ring);
+}
+
+
+static void ixgbe_disable_fwd_ring(struct ixgbe_fwd_adapter *vadapter,
+				   struct ixgbe_ring *rx_ring)
+{
+	struct ixgbe_adapter *adapter = vadapter->real_adapter;
+	int index = rx_ring->queue_index + vadapter->rx_base_queue;
+
+	/* shutdown specific queue receive and wait for dma to settle */
+	ixgbe_disable_rx_queue(adapter, rx_ring);
+	usleep_range(10000, 20000);
+	ixgbe_irq_disable_queues(adapter, ((u64)1 << index));
+	ixgbe_clean_rx_ring(rx_ring);
+	rx_ring->l2_accel_priv = NULL;
+}
+
+int ixgbe_fwd_ring_up(struct net_device *vdev, struct ixgbe_fwd_adapter *accel)
+{
+	struct ixgbe_adapter *adapter = accel->real_adapter;
+	unsigned int rxbase = accel->pool * adapter->num_rx_queues_per_pool;
+	unsigned int txbase = accel->pool * adapter->num_rx_queues_per_pool;
+	int err, i;
+
+
+	accel->rx_base_queue = rxbase;
+	accel->tx_base_queue = txbase;
+
+	for (i = 0; i < vdev->num_rx_queues; i++)
+		ixgbe_disable_fwd_ring(accel, adapter->rx_ring[rxbase + i]);
+
+	for (i = 0; i < vdev->num_rx_queues; i++) {
+		adapter->rx_ring[rxbase + i]->vmdq_netdev = vdev;
+		ixgbe_enable_fwd_ring(adapter, adapter->rx_ring[rxbase + i], accel);
+	}
+
+	for (i = 0; i < vdev->num_tx_queues; i++)
+		adapter->tx_ring[txbase + i]->vmdq_netdev = vdev;
+
+	if (is_valid_ether_addr(vdev->dev_addr))
+		ixgbe_add_mac_filter(adapter, vdev->dev_addr, accel->pool);
+
+	err = netif_set_real_num_tx_queues(vdev, vdev->num_tx_queues);
+	if (err)
+		goto err_set_queues;
+	err = netif_set_real_num_rx_queues(vdev, vdev->num_rx_queues);
+	if (err)
+		goto err_set_queues;
+
+	ixgbe_fwd_psrtype(accel);
+	netif_tx_start_all_queues(vdev);
+	return 0;
+err_set_queues:
+	for (i = 0; i < vdev->num_rx_queues; i++)
+		ixgbe_disable_fwd_ring(accel, adapter->rx_ring[rxbase + i]);
+	return err;
+}
+
+int ixgbe_fwd_ring_down(struct net_device *vdev, struct ixgbe_fwd_adapter *accel)
+{
+	struct ixgbe_adapter *adapter = accel->real_adapter;
+	unsigned int rxbase = accel->rx_base_queue;
+	int i;
+
+	netif_tx_stop_all_queues(vdev);
+
+	for (i = 0; i < vdev->num_rx_queues; i++)
+		ixgbe_disable_fwd_ring(accel, adapter->rx_ring[rxbase + i]);
+
+	return 0;
+}
+
+static void* ixgbe_fwd_add(struct net_device *pdev, struct net_device *vdev)
+{
+	struct ixgbe_fwd_adapter *fwd_adapter = NULL;
+	struct ixgbe_adapter *adapter = netdev_priv(pdev);
+	int pool, vmdq_pool, base_queue;
+	int err;
+
+	/* Check for hardware restriction on number of rx/tx queues */
+	if (vdev->num_rx_queues != vdev->num_tx_queues ||
+	    vdev->num_tx_queues > IXGBE_MAX_L2A_QUEUES ||
+	    vdev->num_tx_queues == IXGBE_BAD_L2A_QUEUE) {
+		netdev_info(pdev, "%s: Supports RX/TX Queue counts 1,2, and 4\n",
+		       pdev->name);
+		return ERR_PTR(-EINVAL);
+	}
+
+	if (adapter->num_rx_pools > IXGBE_MAX_VMDQ_INDICES)
+		return ERR_PTR(-EBUSY);
+
+	fwd_adapter = kcalloc(1, sizeof(struct ixgbe_fwd_adapter), GFP_KERNEL);
+	if (!fwd_adapter)
+		return ERR_PTR(-ENOMEM);
+
+	pool = find_first_zero_bit(&adapter->fwd_bitmask, 32);
+	adapter->num_rx_pools++;
+	set_bit(pool, &adapter->fwd_bitmask);
+
+	/* Enable VMDq flag so device will be set in VM mode */
+	adapter->flags |= IXGBE_FLAG_VMDQ_ENABLED | IXGBE_FLAG_SRIOV_ENABLED;
+	adapter->ring_feature[RING_F_VMDQ].limit = adapter->num_rx_pools;
+	adapter->ring_feature[RING_F_VMDQ].offset = 0;
+	adapter->ring_feature[RING_F_RSS].limit = IXGBE_MAX_L2A_QUEUES;
+
+	/* Force reinit of ring allocation with VMDQ enabled */
+	ixgbe_setup_tc(pdev, netdev_get_num_tc(pdev));
+
+	/* Configure VSI adapter structure */
+	vmdq_pool = VMDQ_P(pool);
+	base_queue = vmdq_pool * adapter->num_rx_queues_per_pool;
+
+	netdev_dbg(pdev, "pool %i:%i queues %i:%i VSI bitmask %lx\n",
+		   pool, adapter->num_rx_pools,
+		   base_queue, base_queue + adapter->num_rx_queues_per_pool,
+		   adapter->fwd_bitmask);
+
+	fwd_adapter->pool = pool;
+	fwd_adapter->netdev = vdev;
+	fwd_adapter->real_adapter = adapter;
+	fwd_adapter->rx_base_queue = base_queue;
+	fwd_adapter->tx_base_queue = base_queue;
+
+	err = ixgbe_fwd_ring_up(vdev, fwd_adapter);	
+	if (!err) {
+		kfree(fwd_adapter);
+		return ERR_PTR(err);
+	}
+	return fwd_adapter;
+}
+
+static void ixgbe_fwd_del(struct net_device *pdev, void *priv)
+{
+	struct ixgbe_fwd_adapter *fwd_adapter = priv; 
+	struct ixgbe_adapter *adapter = fwd_adapter->real_adapter;
+
+	clear_bit(fwd_adapter->pool, &adapter->fwd_bitmask);
+	adapter->num_rx_pools--;
+
+	ixgbe_fwd_ring_down(fwd_adapter->netdev, fwd_adapter);
+
+	netdev_dbg(pdev, "pool %i:%i queues %i:%i VSI bitmask %lx\n",
+		   fwd_adapter->pool, adapter->num_rx_pools,
+		   fwd_adapter->rx_base_queue,
+		   fwd_adapter->rx_base_queue + adapter->num_rx_queues_per_pool,
+		   adapter->fwd_bitmask);
+}
+
 static const struct net_device_ops ixgbe_netdev_ops = {
 	.ndo_open		= ixgbe_open,
 	.ndo_stop		= ixgbe_close,
@@ -7351,6 +7548,11 @@ static const struct net_device_ops ixgbe_netdev_ops = {
 	.ndo_bridge_getlink	= ixgbe_ndo_bridge_getlink,
 };
 
+const struct forwarding_accel_ops  ixgbe_fwd_ops = {
+	.fwd_accel_add_station = ixgbe_fwd_add,
+	.fwd_accel_del_station = ixgbe_fwd_del,
+};
+
 /**
  * ixgbe_enumerate_functions - Get the number of ports this device has
  * @adapter: adapter structure
@@ -7554,6 +7756,7 @@ static int ixgbe_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	}
 
 	netdev->netdev_ops = &ixgbe_netdev_ops;
+	netdev->fwd_ops = &ixgbe_fwd_ops;
 	ixgbe_set_ethtool_ops(netdev);
 	netdev->watchdog_timeo = 5 * HZ;
 	strncpy(netdev->name, pci_name(pdev), sizeof(netdev->name) - 1);
-- 
1.8.3.1

^ permalink raw reply related

* [PATCH 1/2] net: Add layer 2 hardware acceleration operations for macvlan devices
From: Neil Horman @ 2013-10-04 20:10 UTC (permalink / raw)
  To: netdev; +Cc: John Fastabend, Andy Gospodarek, David Miller, Neil Horman
In-Reply-To: <1380917405-23801-1-git-send-email-nhorman@tuxdriver.com>

Add a operations structure that allows a network interface to export the fact
that it supports package forwarding in hardware between physical interfaces and
other mac layer devices assigned to it (such as macvlans).  this operaions
structure can be used by virtual mac devices to bypass software switching so
that forwarding can be done in hardware more efficiently.

Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
CC: John Fastabend <john.r.fastabend@intel.com>
CC: Andy Gospodarek <andy@greyhouse.net>
CC: "David S. Miller" <davem@davemloft.net>
---
 drivers/net/macvlan.c      | 32 ++++++++++++++++++++++++++++++++
 include/linux/if_macvlan.h |  1 +
 include/linux/netdevice.h  | 22 ++++++++++++++++++++++
 include/linux/skbuff.h     |  9 ++++++---
 net/core/dev.c             |  3 +++
 5 files changed, 64 insertions(+), 3 deletions(-)

diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
index 9bf46bd..38d0fc5 100644
--- a/drivers/net/macvlan.c
+++ b/drivers/net/macvlan.c
@@ -297,7 +297,17 @@ netdev_tx_t macvlan_start_xmit(struct sk_buff *skb,
 	int ret;
 	const struct macvlan_dev *vlan = netdev_priv(dev);
 
+	if (vlan->fwd_priv) {
+		skb->dev = vlan->lowerdev;
+		skb->accel_priv = vlan->fwd_priv;
+		ret = dev_queue_xmit(skb);
+		if (likely(ret == NETDEV_TX_OK))
+			goto update_stats;
+	}
+
+	skb->accel_priv = NULL;
 	ret = macvlan_queue_xmit(skb, dev);
+update_stats:
 	if (likely(ret == NET_XMIT_SUCCESS || ret == NET_XMIT_CN)) {
 		struct macvlan_pcpu_stats *pcpu_stats;
 
@@ -347,6 +357,18 @@ static int macvlan_open(struct net_device *dev)
 		goto hash_add;
 	}
 
+	if (fwd_accel_supports(lowerdev, FA_FLG_STA_SUPPORT)) {
+		vlan->fwd_priv = fwd_accel_add_station(lowerdev, dev);
+		/*
+		 * If we get a NULL pointer back, or if we get an error
+		 * then we should just fall through to the non accelerated path
+		 */
+		if (IS_ERR_OR_NULL(vlan->fwd_priv))
+			vlan->fwd_priv = NULL;
+		else
+			return 0;
+	}
+
 	err = -EBUSY;
 	if (macvlan_addr_busy(vlan->port, dev->dev_addr))
 		goto out;
@@ -367,6 +389,10 @@ hash_add:
 del_unicast:
 	dev_uc_del(lowerdev, dev->dev_addr);
 out:
+	if (vlan->fwd_priv) {
+		fwd_accel_del_station(lowerdev, vlan->fwd_priv);
+		vlan->fwd_priv = NULL;
+	}
 	return err;
 }
 
@@ -391,6 +417,11 @@ static int macvlan_stop(struct net_device *dev)
 
 hash_del:
 	macvlan_hash_del(vlan, !dev->dismantle);
+	if (vlan->fwd_priv) {
+		fwd_accel_del_station(lowerdev, vlan->fwd_priv);
+		vlan->fwd_priv = NULL;
+	}
+
 	return 0;
 }
 
@@ -801,6 +832,7 @@ int macvlan_common_newlink(struct net *src_net, struct net_device *dev,
 		if (err < 0)
 			return err;
 	}
+
 	port = macvlan_port_get_rtnl(lowerdev);
 
 	/* Only 1 macvlan device can be created in passthru mode */
diff --git a/include/linux/if_macvlan.h b/include/linux/if_macvlan.h
index ddd33fd..c270285 100644
--- a/include/linux/if_macvlan.h
+++ b/include/linux/if_macvlan.h
@@ -61,6 +61,7 @@ struct macvlan_dev {
 	struct hlist_node	hlist;
 	struct macvlan_port	*port;
 	struct net_device	*lowerdev;
+	void			*fwd_priv;
 	struct macvlan_pcpu_stats __percpu *pcpu_stats;
 
 	DECLARE_BITMAP(mc_filter, MACVLAN_MC_FILTER_SZ);
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 3de49ac..ea18f07 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -1100,6 +1100,27 @@ struct net_device_ops {
 };
 
 /*
+ * Flags to ennumerate hardware acceleration support
+ */
+#define FA_FLG_STA_SUPPORT (1 << 1)
+
+#define fwd_accel_supports(dev, feature) (dev->fwd_ops->flags & feature)
+#define fwd_accel_add_station(pdev, vdev) dev->fwd_ops->fwd_accel_add_station(pdev, vdev)
+#define fwd_accel_del_station(pdev, priv) dev->fwd_ops->fwd_accel_del_station(pdev, priv)
+
+struct forwarding_accel_ops {
+	unsigned int flags;
+
+	/*
+	 * fwd_accel_[add|del]_station must be set if
+	 * FA_FLG_STA_SUPPORT is set
+	 */
+	void*	(*fwd_accel_add_station)(struct net_device *pdev,
+					struct net_device *vdev);
+	void	(*fwd_accel_del_station)(struct net_device *pdev, void *priv);
+};
+
+/*
  *	The DEVICE structure.
  *	Actually, this whole structure is a big mistake.  It mixes I/O
  *	data with strictly "high-level" data, and it has to know about
@@ -1183,6 +1204,7 @@ struct net_device {
 	/* Management operations */
 	const struct net_device_ops *netdev_ops;
 	const struct ethtool_ops *ethtool_ops;
+	const struct forwarding_accel_ops *fwd_ops;
 
 	/* Hardware header description */
 	const struct header_ops *header_ops;
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 2ddb48d..0be9152 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -426,9 +426,12 @@ struct sk_buff {
 	char			cb[48] __aligned(8);
 
 	unsigned long		_skb_refdst;
-#ifdef CONFIG_XFRM
-	struct	sec_path	*sp;
-#endif
+
+	union {
+		struct	sec_path	*sp;
+		void 			*accel_priv;
+	};
+
 	unsigned int		len,
 				data_len;
 	__u16			mac_len,
diff --git a/net/core/dev.c b/net/core/dev.c
index 5c713f2..5f99382 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -5992,6 +5992,7 @@ struct netdev_queue *dev_ingress_queue_create(struct net_device *dev)
 }
 
 static const struct ethtool_ops default_ethtool_ops;
+static const struct forwarding_accel_ops default_fwd_ops;
 
 void netdev_set_default_ethtool_ops(struct net_device *dev,
 				    const struct ethtool_ops *ops)
@@ -6090,6 +6091,8 @@ struct net_device *alloc_netdev_mqs(int sizeof_priv, const char *name,
 	dev->group = INIT_NETDEV_GROUP;
 	if (!dev->ethtool_ops)
 		dev->ethtool_ops = &default_ethtool_ops;
+	if (!dev->fwd_ops)
+		dev->fwd_ops = &default_fwd_ops;
 	return dev;
 
 free_all:
-- 
1.8.3.1

^ permalink raw reply related

* [RFC PATCH 0/2 v2] net: alternate proposal for using macvlans with forwarding acceleration
From: Neil Horman @ 2013-10-04 20:10 UTC (permalink / raw)
  To: netdev; +Cc: John Fastabend, Andy Gospodarek, David Miller
In-Reply-To: <1380140209-24587-1-git-send-email-nhorman@tuxdriver.com>

Hey all-
     heres the next, updated version of the vsi/macvlan integration that we've
been discussing.

Some change notes:

* Changes to the fowarding ops structure - Removed the priv_size field, and
added a flags field.  Removal of the priv_size field was accomplished by just
having the add method return a void * and using ERR_PTR and PTR_ERR checks,
which also allows us to allocate memory for the acceleration path in the driver,
which I like.  I'm not super happy still with how I'm using the flags (currenly
only used to indicate support for feature sets), but at least we have the flags
now, and they can be exposed to user space via iproute2 or ethtool if need be

* Changes to the Transmit path - Specifically I'm using dev_queue_xmit to send
frames now, which I like as it makes the macvlan subject to the lowerdevs qdisc
configuration.

* Changes to the acceleration fail path behavior - Now if we don't/can't use
acceleration, we just fall back to using the normal macvlan software switch
strategy

* General clenups (some renaming, that I'm not super sure of, but I though
forwarding acceleration (fwd) would be a better prefix than l2 acceleration).

Still a long way to go I think, and lots of tweaking to do, but I didn't want to
keep you waiting John.  Anywho, take a look at what I'm doing and feel free to
rip it apart.

Thanks!
Neil

^ permalink raw reply

* Re: [PATCH net-next v2 2/3] udp: Add udp early demux
From: Eric Dumazet @ 2013-10-04 20:02 UTC (permalink / raw)
  To: Shawn Bohrer; +Cc: David Miller, netdev, tomk, Shawn Bohrer
In-Reply-To: <1380914896-24754-3-git-send-email-shawn.bohrer@gmail.com>

On Fri, 2013-10-04 at 14:28 -0500, Shawn Bohrer wrote:

> +
> +/* For unicast we should only early demux connected sockets or we can
> + * break forwarding setups.  The chains here can be long so only check
> + * if the first socket is an exact match and if not move on.
> + */
> +static struct sock *__udp4_lib_demux_lookup(struct net *net,
> +					    __be16 loc_port, __be32 loc_addr,
> +					    __be16 rmt_port, __be32 rmt_addr,
> +					    int dif)
> +{
> +	struct sock *sk, *result;
> +	struct hlist_nulls_node *node;
> +	unsigned short hnum = ntohs(loc_port);
> +	unsigned int slot = udp_hashfn(net, hnum, udp_table.mask);
> +	struct udp_hslot *hslot = &udp_table.hash[slot];
> +	INET_ADDR_COOKIE(acookie, rmt_addr, loc_addr)
> +	const __portpair ports = INET_COMBINED_PORTS(rmt_port, hnum);
> +
> +	rcu_read_lock();
> +	result = NULL;
> +	sk_nulls_for_each_rcu(sk, node, &hslot->head) {
> +		if (INET_MATCH(sk, net, acookie,
> +			       rmt_addr, loc_addr, ports, dif))
> +			result = sk;
> +		/* Only check first socket in chain */
> +		break;
> +	}
> +
> +	if (result) {
> +		if (unlikely(!atomic_inc_not_zero_hint(&result->sk_refcnt, 2)))
> +			result = NULL;

Here you must check again the keys (because of UDP sockets being
SLAB_DESTROY_BY_RCU , this socket might have been freed and reused
elsewhere)

	else
		if (unlikely!(INET_MATCH(result, net, acookie,
					 rmt_addr, loc_addr,
					 ports, dif))) {
			sock_put(result);
			result = NULL;
		}


> +	}
> +	rcu_read_unlock();
> +	return result;
> +}
> +

^ permalink raw reply

* [PATCH net-next v2 3/3] net: ipv4 only populate IP_PKTINFO when needed
From: Shawn Bohrer @ 2013-10-04 19:28 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, tomk, Eric Dumazet, Shawn Bohrer
In-Reply-To: <1380914896-24754-1-git-send-email-shawn.bohrer@gmail.com>

From: Shawn Bohrer <sbohrer@rgmadvisors.com>

The since the removal of the routing cache computing
fib_compute_spec_dst() does a fib_table lookup for each UDP multicast
packet received.  This has introduced a performance regression for some
UDP workloads.

This change skips populating the packet info for sockets that do not have
IP_PKTINFO set.

Benchmark results from a netperf UDP_RR test:
Before 89789.68 transactions/s
After  90587.62 transactions/s

Benchmark results from a fio 1 byte UDP multicast pingpong test
(Multicast one way unicast response):
Before 12.63us RTT
After  12.48us RTT

Signed-off-by: Shawn Bohrer <sbohrer@rgmadvisors.com>
---
v2 changes:

* ipv4_pktinfo_prepare() now takes a const struct sock*

 include/net/ip.h       |    2 +-
 net/ipv4/ip_sockglue.c |    5 +++--
 net/ipv4/raw.c         |    2 +-
 net/ipv4/udp.c         |    2 +-
 4 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/include/net/ip.h b/include/net/ip.h
index 16078f4..b39ebe5 100644
--- a/include/net/ip.h
+++ b/include/net/ip.h
@@ -459,7 +459,7 @@ int ip_options_rcv_srr(struct sk_buff *skb);
  *	Functions provided by ip_sockglue.c
  */
 
-void ipv4_pktinfo_prepare(struct sk_buff *skb);
+void ipv4_pktinfo_prepare(const struct sock *sk, struct sk_buff *skb);
 void ip_cmsg_recv(struct msghdr *msg, struct sk_buff *skb);
 int ip_cmsg_send(struct net *net, struct msghdr *msg, struct ipcm_cookie *ipc);
 int ip_setsockopt(struct sock *sk, int level, int optname, char __user *optval,
diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c
index 56e3445..0626f2c 100644
--- a/net/ipv4/ip_sockglue.c
+++ b/net/ipv4/ip_sockglue.c
@@ -1052,11 +1052,12 @@ e_inval:
  * destination in skb->cb[] before dst drop.
  * This way, receiver doesnt make cache line misses to read rtable.
  */
-void ipv4_pktinfo_prepare(struct sk_buff *skb)
+void ipv4_pktinfo_prepare(const struct sock *sk, struct sk_buff *skb)
 {
 	struct in_pktinfo *pktinfo = PKTINFO_SKB_CB(skb);
 
-	if (skb_rtable(skb)) {
+	if ((inet_sk(sk)->cmsg_flags & IP_CMSG_PKTINFO) &&
+	    skb_rtable(skb)) {
 		pktinfo->ipi_ifindex = inet_iif(skb);
 		pktinfo->ipi_spec_dst.s_addr = fib_compute_spec_dst(skb);
 	} else {
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c
index b2fa14c..41e1d28 100644
--- a/net/ipv4/raw.c
+++ b/net/ipv4/raw.c
@@ -299,7 +299,7 @@ static int raw_rcv_skb(struct sock *sk, struct sk_buff *skb)
 {
 	/* Charge it to the socket. */
 
-	ipv4_pktinfo_prepare(skb);
+	ipv4_pktinfo_prepare(sk, skb);
 	if (sock_queue_rcv_skb(sk, skb) < 0) {
 		kfree_skb(skb);
 		return NET_RX_DROP;
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index a3e575f..79017ff 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -1544,7 +1544,7 @@ int udp_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
 
 	rc = 0;
 
-	ipv4_pktinfo_prepare(skb);
+	ipv4_pktinfo_prepare(sk, skb);
 	bh_lock_sock(sk);
 	if (!sock_owned_by_user(sk))
 		rc = __udp_queue_rcv_skb(sk, skb);
-- 
1.7.7.6

^ permalink raw reply related

* [PATCH net-next v2 2/3] udp: Add udp early demux
From: Shawn Bohrer @ 2013-10-04 19:28 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, tomk, Eric Dumazet, Shawn Bohrer
In-Reply-To: <1380914896-24754-1-git-send-email-shawn.bohrer@gmail.com>

From: Shawn Bohrer <sbohrer@rgmadvisors.com>

The removal of the routing cache introduced a performance regression for
some UDP workloads since a dst lookup must be done for each packet.
This change caches the dst per socket in a similar manner to what we do
for TCP by implementing early_demux.

For UDP multicast we can only cache the dst if there is only one
receiving socket on the host.  Since caching only works when there is
one receiving socket we do the multicast socket lookup using RCU.

For UDP unicast we only demux sockets with an exact match in order to
not break forwarding setups.  Additionally since the hash chains may be
long we only check the first socket to see if it is a match and not
waste extra time searching the whole chain when we might not find an
exact match.

Benchmark results from a netperf UDP_RR test:
Before 87961.22 transactions/s
After  89789.68 transactions/s

Benchmark results from a fio 1 byte UDP multicast pingpong test
(Multicast one way unicast response):
Before 12.97us RTT
After  12.63us RTT

Signed-off-by: Shawn Bohrer <sbohrer@rgmadvisors.com>
---
v2 Changes:

* Unicast UDP early demux now requires an exact socket match and only
tests first socket in UDP hash chain.

 include/net/sock.h |    2 +-
 include/net/udp.h  |    1 +
 net/ipv4/af_inet.c |    1 +
 net/ipv4/udp.c     |  188 +++++++++++++++++++++++++++++++++++++++++++++++-----
 4 files changed, 173 insertions(+), 19 deletions(-)

diff --git a/include/net/sock.h b/include/net/sock.h
index e3bf213..7953254 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -218,7 +218,7 @@ struct cg_proto;
   *	@sk_lock:	synchronizer
   *	@sk_rcvbuf: size of receive buffer in bytes
   *	@sk_wq: sock wait queue and async head
-  *	@sk_rx_dst: receive input route used by early tcp demux
+  *	@sk_rx_dst: receive input route used by early demux
   *	@sk_dst_cache: destination cache
   *	@sk_dst_lock: destination cache lock
   *	@sk_policy: flow policy
diff --git a/include/net/udp.h b/include/net/udp.h
index 510b8cb..fe4ba9f 100644
--- a/include/net/udp.h
+++ b/include/net/udp.h
@@ -175,6 +175,7 @@ int udp_lib_get_port(struct sock *sk, unsigned short snum,
 		     unsigned int hash2_nulladdr);
 
 /* net/ipv4/udp.c */
+void udp_v4_early_demux(struct sk_buff *skb);
 int udp_get_port(struct sock *sk, unsigned short snum,
 		 int (*saddr_cmp)(const struct sock *,
 				  const struct sock *));
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index cfeb85c..35913fb 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -1546,6 +1546,7 @@ static const struct net_protocol tcp_protocol = {
 };
 
 static const struct net_protocol udp_protocol = {
+	.early_demux =	udp_v4_early_demux,
 	.handler =	udp_rcv,
 	.err_handler =	udp_err,
 	.no_policy =	1,
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 5950e12..a3e575f 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -103,6 +103,7 @@
 #include <linux/seq_file.h>
 #include <net/net_namespace.h>
 #include <net/icmp.h>
+#include <net/inet_hashtables.h>
 #include <net/route.h>
 #include <net/checksum.h>
 #include <net/xfrm.h>
@@ -565,6 +566,26 @@ struct sock *udp4_lib_lookup(struct net *net, __be32 saddr, __be16 sport,
 }
 EXPORT_SYMBOL_GPL(udp4_lib_lookup);
 
+static inline bool __udp_is_mcast_sock(struct net *net, struct sock *sk,
+				       __be16 loc_port, __be32 loc_addr,
+				       __be16 rmt_port, __be32 rmt_addr,
+				       int dif, unsigned short hnum)
+{
+	struct inet_sock *inet = inet_sk(sk);
+
+	if (!net_eq(sock_net(sk), net) ||
+	    udp_sk(sk)->udp_port_hash != hnum ||
+	    (inet->inet_daddr && inet->inet_daddr != rmt_addr) ||
+	    (inet->inet_dport != rmt_port && inet->inet_dport) ||
+	    (inet->inet_rcv_saddr && inet->inet_rcv_saddr != loc_addr) ||
+	    ipv6_only_sock(sk) ||
+	    (sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif))
+		return false;
+	if (!ip_mc_sf_allow(sk, loc_addr, rmt_addr, dif))
+		return false;
+	return true;
+}
+
 static inline struct sock *udp_v4_mcast_next(struct net *net, struct sock *sk,
 					     __be16 loc_port, __be32 loc_addr,
 					     __be16 rmt_port, __be32 rmt_addr,
@@ -575,20 +596,11 @@ static inline struct sock *udp_v4_mcast_next(struct net *net, struct sock *sk,
 	unsigned short hnum = ntohs(loc_port);
 
 	sk_nulls_for_each_from(s, node) {
-		struct inet_sock *inet = inet_sk(s);
-
-		if (!net_eq(sock_net(s), net) ||
-		    udp_sk(s)->udp_port_hash != hnum ||
-		    (inet->inet_daddr && inet->inet_daddr != rmt_addr) ||
-		    (inet->inet_dport != rmt_port && inet->inet_dport) ||
-		    (inet->inet_rcv_saddr &&
-		     inet->inet_rcv_saddr != loc_addr) ||
-		    ipv6_only_sock(s) ||
-		    (s->sk_bound_dev_if && s->sk_bound_dev_if != dif))
-			continue;
-		if (!ip_mc_sf_allow(s, loc_addr, rmt_addr, dif))
-			continue;
-		goto found;
+		if (__udp_is_mcast_sock(net, s,
+					loc_port, loc_addr,
+					rmt_port, rmt_addr,
+					dif, hnum))
+			goto found;
 	}
 	s = NULL;
 found:
@@ -1581,6 +1593,14 @@ static void flush_stack(struct sock **stack, unsigned int count,
 		kfree_skb(skb1);
 }
 
+static void udp_sk_rx_dst_set(struct sock *sk, const struct sk_buff *skb)
+{
+	struct dst_entry *dst = skb_dst(skb);
+
+	dst_hold(dst);
+	sk->sk_rx_dst = dst;
+}
+
 /*
  *	Multicasts and broadcasts go to each listener.
  *
@@ -1709,11 +1729,28 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
 	if (udp4_csum_init(skb, uh, proto))
 		goto csum_error;
 
-	if (rt->rt_flags & (RTCF_BROADCAST|RTCF_MULTICAST))
-		return __udp4_lib_mcast_deliver(net, skb, uh,
-				saddr, daddr, udptable);
+	if (skb->sk) {
+		int ret;
+		sk = skb->sk;
+
+		if (unlikely(sk->sk_rx_dst == NULL))
+			udp_sk_rx_dst_set(sk, skb);
+
+		ret = udp_queue_rcv_skb(sk, skb);
+
+		/* a return value > 0 means to resubmit the input, but
+		 * it wants the return to be -protocol, or 0
+		 */
+		if (ret > 0)
+			return -ret;
+		return 0;
+	} else {
+		if (rt->rt_flags & (RTCF_BROADCAST|RTCF_MULTICAST))
+			return __udp4_lib_mcast_deliver(net, skb, uh,
+					saddr, daddr, udptable);
 
-	sk = __udp4_lib_lookup_skb(skb, uh->source, uh->dest, udptable);
+		sk = __udp4_lib_lookup_skb(skb, uh->source, uh->dest, udptable);
+	}
 
 	if (sk != NULL) {
 		int ret;
@@ -1771,6 +1808,121 @@ drop:
 	return 0;
 }
 
+/* We can only early demux multicast if there is a single matching socket.
+ * If more than one socket found returns NULL
+ */
+static struct sock *__udp4_lib_mcast_demux_lookup(struct net *net,
+						  __be16 loc_port, __be32 loc_addr,
+						  __be16 rmt_port, __be32 rmt_addr,
+						  int dif)
+{
+	struct sock *sk, *result;
+	struct hlist_nulls_node *node;
+	unsigned short hnum = ntohs(loc_port);
+	unsigned int count, slot = udp_hashfn(net, hnum, udp_table.mask);
+	struct udp_hslot *hslot = &udp_table.hash[slot];
+
+	rcu_read_lock();
+begin:
+	count = 0;
+	result = NULL;
+	sk_nulls_for_each_rcu(sk, node, &hslot->head) {
+		if (__udp_is_mcast_sock(net, sk,
+					loc_port, loc_addr,
+					rmt_port, rmt_addr,
+					dif, hnum)) {
+			result = sk;
+			++count;
+		}
+	}
+	/*
+	 * if the nulls value we got at the end of this lookup is
+	 * not the expected one, we must restart lookup.
+	 * We probably met an item that was moved to another chain.
+	 */
+	if (get_nulls_value(node) != slot)
+		goto begin;
+
+	if (result) {
+		if (count != 1 ||
+		    unlikely(!atomic_inc_not_zero_hint(&result->sk_refcnt, 2)))
+			result = NULL;
+	}
+	rcu_read_unlock();
+	return result;
+}
+
+/* For unicast we should only early demux connected sockets or we can
+ * break forwarding setups.  The chains here can be long so only check
+ * if the first socket is an exact match and if not move on.
+ */
+static struct sock *__udp4_lib_demux_lookup(struct net *net,
+					    __be16 loc_port, __be32 loc_addr,
+					    __be16 rmt_port, __be32 rmt_addr,
+					    int dif)
+{
+	struct sock *sk, *result;
+	struct hlist_nulls_node *node;
+	unsigned short hnum = ntohs(loc_port);
+	unsigned int slot = udp_hashfn(net, hnum, udp_table.mask);
+	struct udp_hslot *hslot = &udp_table.hash[slot];
+	INET_ADDR_COOKIE(acookie, rmt_addr, loc_addr)
+	const __portpair ports = INET_COMBINED_PORTS(rmt_port, hnum);
+
+	rcu_read_lock();
+	result = NULL;
+	sk_nulls_for_each_rcu(sk, node, &hslot->head) {
+		if (INET_MATCH(sk, net, acookie,
+			       rmt_addr, loc_addr, ports, dif))
+			result = sk;
+		/* Only check first socket in chain */
+		break;
+	}
+
+	if (result) {
+		if (unlikely(!atomic_inc_not_zero_hint(&result->sk_refcnt, 2)))
+			result = NULL;
+	}
+	rcu_read_unlock();
+	return result;
+}
+
+void udp_v4_early_demux(struct sk_buff *skb)
+{
+	const struct iphdr *iph = ip_hdr(skb);
+	const struct udphdr *uh = udp_hdr(skb);
+	struct sock *sk;
+	struct dst_entry *dst;
+	struct net *net = dev_net(skb->dev);
+	int dif = skb->dev->ifindex;
+
+	/* validate the packet */
+	if (!pskb_may_pull(skb, skb_transport_offset(skb) + sizeof(struct udphdr)))
+		return;
+
+	if (skb->pkt_type == PACKET_BROADCAST ||
+	    skb->pkt_type == PACKET_MULTICAST)
+		sk = __udp4_lib_mcast_demux_lookup(net, uh->dest, iph->daddr,
+						   uh->source, iph->saddr, dif);
+	else if (skb->pkt_type == PACKET_HOST)
+		sk = __udp4_lib_demux_lookup(net, uh->dest, iph->daddr,
+					     uh->source, iph->saddr, dif);
+	else
+		return;
+
+	if (!sk)
+		return;
+
+	skb->sk = sk;
+	skb->destructor = sock_edemux;
+	dst = sk->sk_rx_dst;
+
+	if (dst)
+		dst = dst_check(dst, 0);
+	if (dst)
+		skb_dst_set_noref(skb, dst);
+}
+
 int udp_rcv(struct sk_buff *skb)
 {
 	return __udp4_lib_rcv(skb, &udp_table, IPPROTO_UDP);
-- 
1.7.7.6

^ permalink raw reply related

* [PATCH net-next v2 1/3] udp: Only allow busy read/poll on connected sockets
From: Shawn Bohrer @ 2013-10-04 19:28 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, tomk, Eric Dumazet, Shawn Bohrer
In-Reply-To: <1380914896-24754-1-git-send-email-shawn.bohrer@gmail.com>

From: Shawn Bohrer <sbohrer@rgmadvisors.com>

UDP sockets can receive packets from multiple endpoints and thus may be
received on multiple receive queues.  Since packets packets can arrive
on multiple receive queues we should not mark the napi_id for all
packets.  This makes busy read/poll only work for connected UDP sockets.

This additionally enables busy read/poll for UDP multicast packets as
long as the socket is connected by moving the check into
__udp_queue_rcv_skb().

Signed-off-by: Shawn Bohrer <sbohrer@rgmadvisors.com>
Suggested-by: Eric Dumazet <edumazet@google.com>
Acked-by: Eric Dumazet <edumazet@google.com>
---
 net/ipv4/udp.c |    5 +++--
 net/ipv6/udp.c |    5 +++--
 2 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index c41833e..5950e12 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -1405,8 +1405,10 @@ static int __udp_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
 {
 	int rc;
 
-	if (inet_sk(sk)->inet_daddr)
+	if (inet_sk(sk)->inet_daddr) {
 		sock_rps_save_rxhash(sk, skb);
+		sk_mark_napi_id(sk, skb);
+	}
 
 	rc = sock_queue_rcv_skb(sk, skb);
 	if (rc < 0) {
@@ -1716,7 +1718,6 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
 	if (sk != NULL) {
 		int ret;
 
-		sk_mark_napi_id(sk, skb);
 		ret = udp_queue_rcv_skb(sk, skb);
 		sock_put(sk);
 
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 8119791..3753247 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -549,8 +549,10 @@ static int __udpv6_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
 {
 	int rc;
 
-	if (!ipv6_addr_any(&inet6_sk(sk)->daddr))
+	if (!ipv6_addr_any(&inet6_sk(sk)->daddr)) {
 		sock_rps_save_rxhash(sk, skb);
+		sk_mark_napi_id(sk, skb);
+	}
 
 	rc = sock_queue_rcv_skb(sk, skb);
 	if (rc < 0) {
@@ -844,7 +846,6 @@ int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
 	if (sk != NULL) {
 		int ret;
 
-		sk_mark_napi_id(sk, skb);
 		ret = udpv6_queue_rcv_skb(sk, skb);
 		sock_put(sk);
 
-- 
1.7.7.6

^ permalink raw reply related

* [PATCH net-next v2 0/3] Improve UDP multicast receive latency
From: Shawn Bohrer @ 2013-10-04 19:28 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, tomk, Eric Dumazet, Shawn Bohrer

From: Shawn Bohrer <sbohrer@rgmadvisors.com>

The removal of the routing cache in 3.6 had impacted the latency of our
UDP multicast workload.  This patch series brings down the latency to
what we were seeing with 3.4.

Patch 1 "udp: Only allow busy read/poll on connected sockets" is mostly
done for correctness and because it allows unifying the unicast and
multicast paths when a socket is found in early demux.  It can also
improve latency for a connected multicast socket if busy read/poll is
used.

Patches 2&3 remove the fib lookups and restore latency for our workload
to the pre 3.6 levels.

Benchmark results from a netperf UDP_RR test:
v3.12-rc3-447-g40dc9ab kernel   87961.22 transactions/s
v3.12-rc3-447-g40dc9ab + series 90587.62 transactions/s

Benchmark results from a fio 1 byte UDP multicast pingpong test
(Multicast one way unicast response):
v3.12-rc3-447-g40dc9ab kernel   12.97us RTT
v3.12-rc3-447-g40dc9ab + series 12.48us RTT

v2 Changes:

* Unicast UDP early demux now requires an exact socket match and only
tests first socket in UDP hash chain.
* ipv4_pktinfo_prepare() now takes a const struct sock*

Shawn Bohrer (3):
  udp: Only allow busy read/poll on connected sockets
  udp: Add udp early demux
  net: ipv4 only populate IP_PKTINFO when needed

 include/net/ip.h       |    2 +-
 include/net/sock.h     |    2 +-
 include/net/udp.h      |    1 +
 net/ipv4/af_inet.c     |    1 +
 net/ipv4/ip_sockglue.c |    5 +-
 net/ipv4/raw.c         |    2 +-
 net/ipv4/udp.c         |  195 ++++++++++++++++++++++++++++++++++++++++++-----
 net/ipv6/udp.c         |    5 +-
 8 files changed, 185 insertions(+), 28 deletions(-)

-- 
1.7.7.6

^ permalink raw reply

* [PATCH net-next 09/10] qlcnic: Register netdev in FAILED state for 83xx/84xx
From: Himanshu Madhani @ 2013-10-04 18:30 UTC (permalink / raw)
  To: davem
  Cc: netdev, Dept_NX_Linux_NIC_Driver, Sucheta Chakraborty,
	himanshu.madhani
In-Reply-To: <cover.1380937706.git.himanshu.madhani@qlogic.com>

From: Sucheta Chakraborty <sucheta.chakraborty@qlogic.com>

o Without failing probe, register netdev when device is in FAILED state.
o Device will come up with minimum functionality and allow diagnostics and
  repair of the adapter.

Signed-off-by: Sucheta Chakraborty <sucheta.chakraborty@qlogic.com>
Signed-off-by: Himanshu Madhani <himanshu.madhani@qlogic.com>
---
 drivers/net/ethernet/qlogic/qlcnic/qlcnic.h        |  1 +
 .../net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c    | 32 ++++++++++++++-----
 .../net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c  | 16 ++++++----
 .../net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c    |  6 ++--
 drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c   | 37 +++++++++++++++++-----
 drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c  |  8 ++---
 6 files changed, 67 insertions(+), 33 deletions(-)

diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
index 728bb88..2a0a7b4 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
@@ -961,6 +961,7 @@ struct qlcnic_ipaddr {
 #define __QLCNIC_SRIOV_CAPABLE		11
 #define __QLCNIC_MBX_POLL_ENABLE	12
 #define __QLCNIC_DIAG_MODE		13
+#define __QLCNIC_MAINTENANCE_MODE	16
 
 #define QLCNIC_INTERRUPT_TEST		1
 #define QLCNIC_LOOPBACK_TEST		2
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
index a126bdf..f81e2dd 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
@@ -325,7 +325,8 @@ inline void qlcnic_83xx_clear_legacy_intr_mask(struct qlcnic_adapter *adapter)
 
 inline void qlcnic_83xx_set_legacy_intr_mask(struct qlcnic_adapter *adapter)
 {
-	writel(1, adapter->tgt_mask_reg);
+	if (adapter->tgt_mask_reg)
+		writel(1, adapter->tgt_mask_reg);
 }
 
 /* Enable MSI-x and INT-x interrupts */
@@ -498,8 +499,11 @@ void qlcnic_83xx_free_mbx_intr(struct qlcnic_adapter *adapter)
 		num_msix = 0;
 
 	msleep(20);
-	synchronize_irq(adapter->msix_entries[num_msix].vector);
-	free_irq(adapter->msix_entries[num_msix].vector, adapter);
+
+	if (adapter->msix_entries) {
+		synchronize_irq(adapter->msix_entries[num_msix].vector);
+		free_irq(adapter->msix_entries[num_msix].vector, adapter);
+	}
 }
 
 int qlcnic_83xx_setup_mbx_intr(struct qlcnic_adapter *adapter)
@@ -760,6 +764,9 @@ int qlcnic_83xx_issue_cmd(struct qlcnic_adapter *adapter,
 	int cmd_type, err, opcode;
 	unsigned long timeout;
 
+	if (!mbx)
+		return -EIO;
+
 	opcode = LSW(cmd->req.arg[0]);
 	cmd_type = cmd->type;
 	err = mbx->ops->enqueue_cmd(adapter, cmd, &timeout);
@@ -3049,11 +3056,14 @@ int qlcnic_83xx_get_settings(struct qlcnic_adapter *adapter,
 	int status = 0;
 	struct qlcnic_hardware_context *ahw = adapter->ahw;
 
-	/* Get port configuration info */
-	status = qlcnic_83xx_get_port_info(adapter);
-	/* Get Link Status related info */
-	config = qlcnic_83xx_test_link(adapter);
-	ahw->module_type = QLC_83XX_SFP_MODULE_TYPE(config);
+	if (!test_bit(__QLCNIC_MAINTENANCE_MODE, &adapter->state)) {
+		/* Get port configuration info */
+		status = qlcnic_83xx_get_port_info(adapter);
+		/* Get Link Status related info */
+		config = qlcnic_83xx_test_link(adapter);
+		ahw->module_type = QLC_83XX_SFP_MODULE_TYPE(config);
+	}
+
 	/* hard code until there is a way to get it from flash */
 	ahw->board_type = QLCNIC_BRDTYPE_83XX_10G;
 
@@ -3530,6 +3540,9 @@ void qlcnic_83xx_reinit_mbx_work(struct qlcnic_mailbox *mbx)
 
 void qlcnic_83xx_free_mailbox(struct qlcnic_mailbox *mbx)
 {
+	if (!mbx)
+		return;
+
 	destroy_workqueue(mbx->work_q);
 	kfree(mbx);
 }
@@ -3650,6 +3663,9 @@ void qlcnic_83xx_detach_mailbox_work(struct qlcnic_adapter *adapter)
 {
 	struct qlcnic_mailbox *mbx = adapter->ahw->mailbox;
 
+	if (!mbx)
+		return;
+
 	clear_bit(QLC_83XX_MBX_READY, &mbx->status);
 	complete(&mbx->completion);
 	cancel_work_sync(&mbx->work);
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c
index e2cd484..4a8a3f1 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c
@@ -2190,20 +2190,24 @@ int qlcnic_83xx_init(struct qlcnic_adapter *adapter, int pci_using_dac)
 			return err;
 	}
 
+	if (qlcnic_83xx_read_flash_descriptor_table(adapter) ||
+	    qlcnic_83xx_read_flash_mfg_id(adapter)) {
+		dev_err(&adapter->pdev->dev, "Failed reading flash mfg id\n");
+		err = -ENOTRECOVERABLE;
+		goto detach_mbx;
+	}
+
 	err = qlcnic_83xx_check_hw_status(adapter);
 	if (err)
 		goto detach_mbx;
 
-	if (!qlcnic_83xx_read_flash_descriptor_table(adapter))
-		qlcnic_83xx_read_flash_mfg_id(adapter);
-
 	err = qlcnic_83xx_get_fw_info(adapter);
 	if (err)
 		goto detach_mbx;
 
 	err = qlcnic_83xx_idc_init(adapter);
 	if (err)
-		goto clear_fw_info;
+		goto detach_mbx;
 
 	err = qlcnic_setup_intr(adapter, 0, 0);
 	if (err) {
@@ -2247,12 +2251,10 @@ disable_mbx_intr:
 disable_intr:
 	qlcnic_teardown_intr(adapter);
 
-clear_fw_info:
-	kfree(ahw->fw_info);
-
 detach_mbx:
 	qlcnic_83xx_detach_mailbox_work(adapter);
 	qlcnic_83xx_free_mailbox(ahw->mailbox);
+	ahw->mailbox = NULL;
 exit:
 	return err;
 }
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c
index 7e8d39a..66a2a58 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c
@@ -1692,7 +1692,6 @@ qlcnic_set_dump(struct net_device *netdev, struct ethtool_dump *val)
 	struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump;
 	bool valid_mask = false;
 	int i, ret = 0;
-	u32 state;
 
 	switch (val->flag) {
 	case QLCNIC_FORCE_FW_DUMP_KEY:
@@ -1745,9 +1744,8 @@ qlcnic_set_dump(struct net_device *netdev, struct ethtool_dump *val)
 
 	case QLCNIC_SET_QUIESCENT:
 	case QLCNIC_RESET_QUIESCENT:
-		state = QLC_SHARED_REG_RD32(adapter, QLCNIC_CRB_DEV_STATE);
-		if (state == QLCNIC_DEV_FAILED || (state == QLCNIC_DEV_BADBAD))
-			netdev_info(netdev, "Device in FAILED state\n");
+		if (test_bit(__QLCNIC_MAINTENANCE_MODE, &adapter->state))
+			netdev_info(netdev, "Device is in non-operational state\n");
 		break;
 
 	default:
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
index 565e531..3c1aa26 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
@@ -2305,10 +2305,23 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 		qlcnic_83xx_check_vf(adapter, ent);
 		adapter->portnum = adapter->ahw->pci_func;
 		err = qlcnic_83xx_init(adapter, pci_using_dac);
+
 		if (err) {
-			dev_err(&pdev->dev, "%s: failed\n", __func__);
-			goto err_out_free_hw;
+			switch (err) {
+			case -ENOTRECOVERABLE:
+				dev_err(&pdev->dev, "Adapter initialization failed due to a faulty hardware.\n"
+					"\t\tPlease replace the adapter with new one and return the faulty adapter for repair\n");
+				goto err_out_free_hw;
+			case -ENOMEM:
+				dev_err(&pdev->dev, "Adapter initialization failed. Please reboot\n");
+				goto err_out_free_hw;
+			default:
+				dev_err(&pdev->dev, "Adapter initialization failed. A reboot may be required to recover from this failure.\n"
+					"\t\tIf reboot does not help to recover from this failure, try a flash update of the adapter\n");
+				goto err_out_maintenance_mode;
+			}
 		}
+
 		if (qlcnic_sriov_vf_check(adapter))
 			return 0;
 	} else {
@@ -2408,8 +2421,16 @@ err_out_disable_pdev:
 	return err;
 
 err_out_maintenance_mode:
+	set_bit(__QLCNIC_MAINTENANCE_MODE, &adapter->state);
 	netdev->netdev_ops = &qlcnic_netdev_failed_ops;
 	SET_ETHTOOL_OPS(netdev, &qlcnic_ethtool_failed_ops);
+	ahw->port_type = QLCNIC_XGBE;
+
+	if (qlcnic_83xx_check(adapter))
+		adapter->tgt_status_reg = NULL;
+	else
+		ahw->board_type = QLCNIC_BRDTYPE_P3P_10G_SFP_PLUS;
+
 	err = register_netdev(netdev);
 
 	if (err) {
@@ -2532,12 +2553,11 @@ static int qlcnic_resume(struct pci_dev *pdev)
 static int qlcnic_open(struct net_device *netdev)
 {
 	struct qlcnic_adapter *adapter = netdev_priv(netdev);
-	u32 state;
 	int err;
 
-	state = QLC_SHARED_REG_RD32(adapter, QLCNIC_CRB_DEV_STATE);
-	if (state == QLCNIC_DEV_FAILED || state == QLCNIC_DEV_BADBAD) {
-		netdev_err(netdev, "%s: Device is in FAILED state\n", __func__);
+	if (test_bit(__QLCNIC_MAINTENANCE_MODE, &adapter->state)) {
+		netdev_err(netdev, "%s: Device is in non-operational state\n",
+			   __func__);
 
 		return -EIO;
 	}
@@ -3250,8 +3270,9 @@ void qlcnic_82xx_dev_request_reset(struct qlcnic_adapter *adapter, u32 key)
 		return;
 
 	state = QLC_SHARED_REG_RD32(adapter, QLCNIC_CRB_DEV_STATE);
-	if (state == QLCNIC_DEV_FAILED || state == QLCNIC_DEV_BADBAD) {
-		netdev_err(adapter->netdev, "%s: Device is in FAILED state\n",
+
+	if (test_bit(__QLCNIC_MAINTENANCE_MODE, &adapter->state)) {
+		netdev_err(adapter->netdev, "%s: Device is in non-operational state\n",
 			   __func__);
 		qlcnic_api_unlock(adapter);
 
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c
index 019f437..e8b1ce6 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c
@@ -1272,7 +1272,6 @@ void qlcnic_remove_sysfs_entries(struct qlcnic_adapter *adapter)
 void qlcnic_create_diag_entries(struct qlcnic_adapter *adapter)
 {
 	struct device *dev = &adapter->pdev->dev;
-	u32 state;
 
 	if (device_create_bin_file(dev, &bin_attr_port_stats))
 		dev_info(dev, "failed to create port stats sysfs entry");
@@ -1286,8 +1285,7 @@ void qlcnic_create_diag_entries(struct qlcnic_adapter *adapter)
 	if (device_create_bin_file(dev, &bin_attr_mem))
 		dev_info(dev, "failed to create mem sysfs entry\n");
 
-	state = QLC_SHARED_REG_RD32(adapter, QLCNIC_CRB_DEV_STATE);
-	if (state == QLCNIC_DEV_FAILED || state == QLCNIC_DEV_BADBAD)
+	if (test_bit(__QLCNIC_MAINTENANCE_MODE, &adapter->state))
 		return;
 
 	if (device_create_bin_file(dev, &bin_attr_pci_config))
@@ -1313,7 +1311,6 @@ void qlcnic_create_diag_entries(struct qlcnic_adapter *adapter)
 void qlcnic_remove_diag_entries(struct qlcnic_adapter *adapter)
 {
 	struct device *dev = &adapter->pdev->dev;
-	u32 state;
 
 	device_remove_bin_file(dev, &bin_attr_port_stats);
 
@@ -1323,8 +1320,7 @@ void qlcnic_remove_diag_entries(struct qlcnic_adapter *adapter)
 	device_remove_bin_file(dev, &bin_attr_crb);
 	device_remove_bin_file(dev, &bin_attr_mem);
 
-	state = QLC_SHARED_REG_RD32(adapter, QLCNIC_CRB_DEV_STATE);
-	if (state == QLCNIC_DEV_FAILED || state == QLCNIC_DEV_BADBAD)
+	if (test_bit(__QLCNIC_MAINTENANCE_MODE, &adapter->state))
 		return;
 
 	device_remove_bin_file(dev, &bin_attr_pci_config);
-- 
1.8.1.4

^ permalink raw reply related

* [PATCH net-next 10/10] qlcnic: update version to 5.3.51
From: Himanshu Madhani @ 2013-10-04 18:30 UTC (permalink / raw)
  To: davem; +Cc: netdev, Dept_NX_Linux_NIC_Driver, Himanshu Madhani
In-Reply-To: <cover.1380937706.git.himanshu.madhani@qlogic.com>

From: Himanshu Madhani <himanshu.madhani@qlogic.com>

Signed-off-by: Himanshu Madhani <himanshu.madhani@qlogic.com>
---
 drivers/net/ethernet/qlogic/qlcnic/qlcnic.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
index 2a0a7b4..db83edf 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
@@ -38,8 +38,8 @@
 
 #define _QLCNIC_LINUX_MAJOR 5
 #define _QLCNIC_LINUX_MINOR 3
-#define _QLCNIC_LINUX_SUBVERSION 50
-#define QLCNIC_LINUX_VERSIONID  "5.3.50"
+#define _QLCNIC_LINUX_SUBVERSION 51
+#define QLCNIC_LINUX_VERSIONID  "5.3.51"
 #define QLCNIC_DRV_IDC_VER  0x01
 #define QLCNIC_DRIVER_VERSION  ((_QLCNIC_LINUX_MAJOR << 16) |\
 		 (_QLCNIC_LINUX_MINOR << 8) | (_QLCNIC_LINUX_SUBVERSION))
-- 
1.8.1.4

^ permalink raw reply related

* [PATCH net-next 08/10] qlcnic: Skip unknown entry type while collecting firmware dump
From: Himanshu Madhani @ 2013-10-04 18:30 UTC (permalink / raw)
  To: davem; +Cc: netdev, Dept_NX_Linux_NIC_Driver, Shahed Shaikh, himanshu.madhani
In-Reply-To: <cover.1380937706.git.himanshu.madhani@qlogic.com>

From: Shahed Shaikh <shahed.shaikh@qlogic.com>

o Driver aborts the minidump collection operation when it finds
  an unknown entry opcode. This patch skips unknown entry type
  and resumes the minidump collection operation.
o Removed a comparision of collected dump size with expected dump size.
  Size may differ when driver decides to skip an entry.

Signed-off-by: Shahed Shaikh <shahed.shaikh@qlogic.com>
Signed-off-by: Himanshu Madhani <himanshu.madhani@qlogic.com>
---
 .../net/ethernet/qlogic/qlcnic/qlcnic_minidump.c   | 41 ++++++++++------------
 1 file changed, 19 insertions(+), 22 deletions(-)

diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_minidump.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_minidump.c
index 1551360..7763962 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_minidump.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_minidump.c
@@ -1187,41 +1187,38 @@ int qlcnic_dump_fw(struct qlcnic_adapter *adapter)
 		}
 
 		if (ops_index == ops_cnt) {
-			dev_info(&adapter->pdev->dev,
-				 "Invalid entry type %d, exiting dump\n",
+			dev_info(dev, "Skipping unknown entry opcode %d\n",
 				 entry->hdr.type);
-			goto error;
+			entry->hdr.flags |= QLCNIC_DUMP_SKIP;
+			entry_offset += entry->hdr.offset;
+			continue;
 		}
 
 		/* Collect dump for this entry */
 		dump = fw_dump_ops[ops_index].handler(adapter, entry, buffer);
-		if (!qlcnic_valid_dump_entry(&adapter->pdev->dev, entry, dump))
+		if (!qlcnic_valid_dump_entry(dev, entry, dump)) {
 			entry->hdr.flags |= QLCNIC_DUMP_SKIP;
+			entry_offset += entry->hdr.offset;
+			continue;
+		}
+
 		buf_offset += entry->hdr.cap_size;
 		entry_offset += entry->hdr.offset;
 		buffer = fw_dump->data + buf_offset;
 	}
-	if (dump_size != buf_offset) {
-		dev_info(&adapter->pdev->dev,
-			 "Captured(%d) and expected size(%d) do not match\n",
-			 buf_offset, dump_size);
-		goto error;
-	} else {
-		fw_dump->clr = 1;
-		snprintf(mesg, sizeof(mesg), "FW_DUMP=%s",
-			 adapter->netdev->name);
-		dev_info(&adapter->pdev->dev, "%s: Dump data, %d bytes captured\n",
-			 adapter->netdev->name, fw_dump->size);
-		/* Send a udev event to notify availability of FW dump */
-		kobject_uevent_env(&adapter->pdev->dev.kobj, KOBJ_CHANGE, msg);
-		return 0;
-	}
-error:
+
+	fw_dump->clr = 1;
+	snprintf(mesg, sizeof(mesg), "FW_DUMP=%s", adapter->netdev->name);
+	dev_info(dev, "%s: Dump data %d bytes captured, template header size %d bytes\n",
+		 adapter->netdev->name, fw_dump->size, tmpl_hdr->size);
+	/* Send a udev event to notify availability of FW dump */
+	kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, msg);
+
 	if (fw_dump->use_pex_dma)
 		dma_free_coherent(dev, QLC_PEX_DMA_READ_SIZE,
 				  fw_dump->dma_buffer, fw_dump->phys_addr);
-	vfree(fw_dump->data);
-	return -EINVAL;
+
+	return 0;
 }
 
 void qlcnic_83xx_get_minidump_template(struct qlcnic_adapter *adapter)
-- 
1.8.1.4

^ permalink raw reply related

* [PATCH net-next 07/10] qlcnic: Validate Tx queue only for 82xx adapters.
From: Himanshu Madhani @ 2013-10-04 18:30 UTC (permalink / raw)
  To: davem; +Cc: netdev, Dept_NX_Linux_NIC_Driver, Himanshu Madhani
In-Reply-To: <cover.1380937706.git.himanshu.madhani@qlogic.com>

From: Himanshu Madhani <himanshu.madhani@qlogic.com>

o validate Tx queue only in case of adapters which supports
  multi Tx queue.

  This patch is to fix regression introduced in commit
  aa4a1f7df7cbb98797c9f4edfde3c726e2b3841f
  "qlcnic: Enable Tx queue changes using ethtool for 82xx Series adapter"

Signed-off-by: Himanshu Madhani <himanshu.madhani@qlogic.com>
---
 drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c | 2 +-
 drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c    | 8 +-------
 2 files changed, 2 insertions(+), 8 deletions(-)

diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c
index 01edc09..7e8d39a 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c
@@ -698,7 +698,7 @@ static int qlcnic_set_channels(struct net_device *dev,
 			return err;
 	}
 
-	if (channel->tx_count) {
+	if (qlcnic_82xx_check(adapter) && channel->tx_count) {
 		err = qlcnic_validate_max_tx_rings(adapter, channel->tx_count);
 		if (err)
 			return err;
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
index aaf67bd..565e531 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
@@ -3647,11 +3647,6 @@ int qlcnic_validate_max_tx_rings(struct qlcnic_adapter *adapter, u32 txq)
 	u8 max_hw = QLCNIC_MAX_TX_RINGS;
 	u32 max_allowed;
 
-	if (!qlcnic_82xx_check(adapter)) {
-		netdev_err(netdev, "No Multi TX-Q support\n");
-		return -EINVAL;
-	}
-
 	if (!qlcnic_use_msi_x && !qlcnic_use_msi) {
 		netdev_err(netdev, "No Multi TX-Q support in INT-x mode\n");
 		return -EINVAL;
@@ -3691,8 +3686,7 @@ int qlcnic_validate_max_rss(struct qlcnic_adapter *adapter,
 	u8 max_hw = adapter->ahw->max_rx_ques;
 	u32 max_allowed;
 
-	if (qlcnic_82xx_check(adapter) && !qlcnic_use_msi_x &&
-	    !qlcnic_use_msi) {
+	if (!qlcnic_use_msi_x && !qlcnic_use_msi) {
 		netdev_err(netdev, "No RSS support in INT-x mode\n");
 		return -EINVAL;
 	}
-- 
1.8.1.4

^ permalink raw reply related

* [PATCH net-next 06/10] qlcnic: dcb code cleanup and refactoring.
From: Himanshu Madhani @ 2013-10-04 18:30 UTC (permalink / raw)
  To: davem
  Cc: netdev, Dept_NX_Linux_NIC_Driver, Sucheta Chakraborty,
	himanshu.madhani
In-Reply-To: <cover.1380937706.git.himanshu.madhani@qlogic.com>

From: Sucheta Chakraborty <sucheta.chakraborty@qlogic.com>

o Move dcb specific function definitions to dcb files.
o Move dcb specific variables to qlcnic_dcb structure.

Signed-off-by: Sucheta Chakraborty <sucheta.chakraborty@qlogic.com>
Signed-off-by: Himanshu Madhani <himanshu.madhani@qlogic.com>
---
 drivers/net/ethernet/qlogic/qlcnic/qlcnic.h        |  96 -----------
 .../net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c    |   2 +-
 .../net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c  |   9 +-
 drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.c    | 182 ++++++++++-----------
 drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.h    | 109 ++++++++++--
 drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c     |   2 +-
 drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c   |  24 +--
 .../ethernet/qlogic/qlcnic/qlcnic_sriov_common.c   |   9 +-
 8 files changed, 206 insertions(+), 227 deletions(-)

diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
index a3c4379..728bb88 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
@@ -961,8 +961,6 @@ struct qlcnic_ipaddr {
 #define __QLCNIC_SRIOV_CAPABLE		11
 #define __QLCNIC_MBX_POLL_ENABLE	12
 #define __QLCNIC_DIAG_MODE		13
-#define __QLCNIC_DCB_STATE		14
-#define __QLCNIC_DCB_IN_AEN		15
 
 #define QLCNIC_INTERRUPT_TEST		1
 #define QLCNIC_LOOPBACK_TEST		2
@@ -2116,98 +2114,4 @@ static inline bool qlcnic_sriov_vf_check(struct qlcnic_adapter *adapter)
 
 	return status;
 }
-
-static inline int qlcnic_dcb_get_hw_capability(struct qlcnic_adapter *adapter)
-{
-	struct qlcnic_dcb *dcb = adapter->dcb;
-
-	if (dcb && dcb->ops->get_hw_capability)
-		return dcb->ops->get_hw_capability(adapter);
-
-	return 0;
-}
-
-static inline void qlcnic_dcb_free(struct qlcnic_adapter *adapter)
-{
-	struct qlcnic_dcb *dcb = adapter->dcb;
-
-	if (dcb && dcb->ops->free)
-		dcb->ops->free(adapter);
-}
-
-static inline int qlcnic_dcb_attach(struct qlcnic_adapter *adapter)
-{
-	struct qlcnic_dcb *dcb = adapter->dcb;
-
-	if (dcb && dcb->ops->attach)
-		return dcb->ops->attach(adapter);
-
-	return 0;
-}
-
-static inline int
-qlcnic_dcb_query_hw_capability(struct qlcnic_adapter *adapter, char *buf)
-{
-	struct qlcnic_dcb *dcb = adapter->dcb;
-
-	if (dcb && dcb->ops->query_hw_capability)
-		return dcb->ops->query_hw_capability(adapter, buf);
-
-	return 0;
-}
-
-static inline void qlcnic_dcb_get_info(struct qlcnic_adapter *adapter)
-{
-	struct qlcnic_dcb *dcb = adapter->dcb;
-
-	if (dcb && dcb->ops->get_info)
-		dcb->ops->get_info(adapter);
-}
-
-static inline int
-qlcnic_dcb_query_cee_param(struct qlcnic_adapter *adapter, char *buf, u8 type)
-{
-	struct qlcnic_dcb *dcb = adapter->dcb;
-
-	if (dcb && dcb->ops->query_cee_param)
-		return dcb->ops->query_cee_param(adapter, buf, type);
-
-	return 0;
-}
-
-static inline int qlcnic_dcb_get_cee_cfg(struct qlcnic_adapter *adapter)
-{
-	struct qlcnic_dcb *dcb = adapter->dcb;
-
-	if (dcb && dcb->ops->get_cee_cfg)
-		return dcb->ops->get_cee_cfg(adapter);
-
-	return 0;
-}
-
-static inline void
-qlcnic_dcb_register_aen(struct qlcnic_adapter *adapter, u8 flag)
-{
-	struct qlcnic_dcb *dcb = adapter->dcb;
-
-	if (dcb && dcb->ops->register_aen)
-		dcb->ops->register_aen(adapter, flag);
-}
-
-static inline void qlcnic_dcb_handle_aen(struct qlcnic_adapter *adapter,
-					 void *msg)
-{
-	struct qlcnic_dcb *dcb = adapter->dcb;
-
-	if (dcb && dcb->ops->handle_aen)
-		dcb->ops->handle_aen(adapter, msg);
-}
-
-static inline void qlcnic_dcb_init_dcbnl_ops(struct qlcnic_adapter *adapter)
-{
-	struct qlcnic_dcb *dcb = adapter->dcb;
-
-	if (dcb && dcb->ops->init_dcbnl_ops)
-		dcb->ops->init_dcbnl_ops(adapter);
-}
 #endif				/* __QLCNIC_H_ */
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
index 268fda6..a126bdf 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
@@ -902,7 +902,7 @@ void __qlcnic_83xx_process_aen(struct qlcnic_adapter *adapter)
 			 QLCNIC_MBX_RSP(event[0]));
 		break;
 	case QLCNIC_MBX_DCBX_CONFIG_CHANGE_EVENT:
-		qlcnic_dcb_handle_aen(adapter, (void *)&event[1]);
+		qlcnic_dcb_aen_handler(adapter->dcb, (void *)&event[1]);
 		break;
 	default:
 		dev_dbg(&adapter->pdev->dev, "Unsupported AEN:0x%x.\n",
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c
index d303fab..e2cd484 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c
@@ -636,7 +636,7 @@ int qlcnic_83xx_idc_reattach_driver(struct qlcnic_adapter *adapter)
 	if (adapter->portnum == 0)
 		qlcnic_set_drv_version(adapter);
 
-	qlcnic_dcb_get_info(adapter);
+	qlcnic_dcb_get_info(adapter->dcb);
 	qlcnic_83xx_idc_attach_driver(adapter);
 
 	return 0;
@@ -2174,6 +2174,7 @@ static int qlcnic_83xx_get_fw_info(struct qlcnic_adapter *adapter)
 int qlcnic_83xx_init(struct qlcnic_adapter *adapter, int pci_using_dac)
 {
 	struct qlcnic_hardware_context *ahw = adapter->ahw;
+	struct qlcnic_dcb *dcb;
 	int err = 0;
 
 	ahw->msix_supported = !!qlcnic_use_msi_x;
@@ -2231,8 +2232,10 @@ int qlcnic_83xx_init(struct qlcnic_adapter *adapter, int pci_using_dac)
 	if (err)
 		goto disable_mbx_intr;
 
-	if (adapter->dcb && qlcnic_dcb_attach(adapter))
-		qlcnic_clear_dcb_ops(adapter);
+	dcb = adapter->dcb;
+
+	if (dcb && qlcnic_dcb_attach(dcb))
+		qlcnic_clear_dcb_ops(dcb);
 
 	/* Periodically monitor device status */
 	qlcnic_83xx_idc_poll_dev_state(&adapter->fw_work.work);
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.c
index d62d5ce..5ab7fd7 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.c
@@ -57,22 +57,22 @@ static const struct dcbnl_rtnl_ops qlcnic_dcbnl_ops;
 static void qlcnic_dcb_aen_work(struct work_struct *);
 static void qlcnic_dcb_data_cee_param_map(struct qlcnic_adapter *);
 
-static inline void __qlcnic_init_dcbnl_ops(struct qlcnic_adapter *);
-static void __qlcnic_dcb_free(struct qlcnic_adapter *);
-static int __qlcnic_dcb_attach(struct qlcnic_adapter *);
-static int __qlcnic_dcb_query_hw_capability(struct qlcnic_adapter *, char *);
-static void __qlcnic_dcb_get_info(struct qlcnic_adapter *);
-
-static int qlcnic_82xx_dcb_get_hw_capability(struct qlcnic_adapter *);
-static int qlcnic_82xx_dcb_query_cee_param(struct qlcnic_adapter *, char *, u8);
-static int qlcnic_82xx_dcb_get_cee_cfg(struct qlcnic_adapter *);
-static void qlcnic_82xx_dcb_handle_aen(struct qlcnic_adapter *, void *);
-
-static int qlcnic_83xx_dcb_get_hw_capability(struct qlcnic_adapter *);
-static int qlcnic_83xx_dcb_query_cee_param(struct qlcnic_adapter *, char *, u8);
-static int qlcnic_83xx_dcb_get_cee_cfg(struct qlcnic_adapter *);
-static int qlcnic_83xx_dcb_register_aen(struct qlcnic_adapter *, bool);
-static void qlcnic_83xx_dcb_handle_aen(struct qlcnic_adapter *, void *);
+static inline void __qlcnic_init_dcbnl_ops(struct qlcnic_dcb *);
+static void __qlcnic_dcb_free(struct qlcnic_dcb *);
+static int __qlcnic_dcb_attach(struct qlcnic_dcb *);
+static int __qlcnic_dcb_query_hw_capability(struct qlcnic_dcb *, char *);
+static void __qlcnic_dcb_get_info(struct qlcnic_dcb *);
+
+static int qlcnic_82xx_dcb_get_hw_capability(struct qlcnic_dcb *);
+static int qlcnic_82xx_dcb_query_cee_param(struct qlcnic_dcb *, char *, u8);
+static int qlcnic_82xx_dcb_get_cee_cfg(struct qlcnic_dcb *);
+static void qlcnic_82xx_dcb_aen_handler(struct qlcnic_dcb *, void *);
+
+static int qlcnic_83xx_dcb_get_hw_capability(struct qlcnic_dcb *);
+static int qlcnic_83xx_dcb_query_cee_param(struct qlcnic_dcb *, char *, u8);
+static int qlcnic_83xx_dcb_get_cee_cfg(struct qlcnic_dcb *);
+static int qlcnic_83xx_dcb_register_aen(struct qlcnic_dcb *, bool);
+static void qlcnic_83xx_dcb_aen_handler(struct qlcnic_dcb *, void *);
 
 struct qlcnic_dcb_capability {
 	bool	tsa_capability;
@@ -180,7 +180,7 @@ static struct qlcnic_dcb_ops qlcnic_83xx_dcb_ops = {
 	.query_cee_param	= qlcnic_83xx_dcb_query_cee_param,
 	.get_cee_cfg		= qlcnic_83xx_dcb_get_cee_cfg,
 	.register_aen		= qlcnic_83xx_dcb_register_aen,
-	.handle_aen		= qlcnic_83xx_dcb_handle_aen,
+	.aen_handler		= qlcnic_83xx_dcb_aen_handler,
 };
 
 static struct qlcnic_dcb_ops qlcnic_82xx_dcb_ops = {
@@ -193,7 +193,7 @@ static struct qlcnic_dcb_ops qlcnic_82xx_dcb_ops = {
 	.get_hw_capability	= qlcnic_82xx_dcb_get_hw_capability,
 	.query_cee_param	= qlcnic_82xx_dcb_query_cee_param,
 	.get_cee_cfg		= qlcnic_82xx_dcb_get_cee_cfg,
-	.handle_aen		= qlcnic_82xx_dcb_handle_aen,
+	.aen_handler		= qlcnic_82xx_dcb_aen_handler,
 };
 
 static u8 qlcnic_dcb_get_num_app(struct qlcnic_adapter *adapter, u32 val)
@@ -242,10 +242,10 @@ static int qlcnic_dcb_prio_count(u8 up_tc_map)
 	return j;
 }
 
-static inline void __qlcnic_init_dcbnl_ops(struct qlcnic_adapter *adapter)
+static inline void __qlcnic_init_dcbnl_ops(struct qlcnic_dcb *dcb)
 {
-	if (test_bit(__QLCNIC_DCB_STATE, &adapter->state))
-		adapter->netdev->dcbnl_ops = &qlcnic_dcbnl_ops;
+	if (test_bit(QLCNIC_DCB_STATE, &dcb->state))
+		dcb->adapter->netdev->dcbnl_ops = &qlcnic_dcbnl_ops;
 }
 
 static void qlcnic_set_dcb_ops(struct qlcnic_adapter *adapter)
@@ -256,7 +256,7 @@ static void qlcnic_set_dcb_ops(struct qlcnic_adapter *adapter)
 		adapter->dcb->ops = &qlcnic_83xx_dcb_ops;
 }
 
-int __qlcnic_register_dcb(struct qlcnic_adapter *adapter)
+int qlcnic_register_dcb(struct qlcnic_adapter *adapter)
 {
 	struct qlcnic_dcb *dcb;
 
@@ -267,20 +267,22 @@ int __qlcnic_register_dcb(struct qlcnic_adapter *adapter)
 	adapter->dcb = dcb;
 	dcb->adapter = adapter;
 	qlcnic_set_dcb_ops(adapter);
+	dcb->state = 0;
 
 	return 0;
 }
 
-static void __qlcnic_dcb_free(struct qlcnic_adapter *adapter)
+static void __qlcnic_dcb_free(struct qlcnic_dcb *dcb)
 {
-	struct qlcnic_dcb *dcb = adapter->dcb;
+	struct qlcnic_adapter *adapter;
 
 	if (!dcb)
 		return;
 
-	qlcnic_dcb_register_aen(adapter, 0);
+	adapter = dcb->adapter;
+	qlcnic_dcb_register_aen(dcb, 0);
 
-	while (test_bit(__QLCNIC_DCB_IN_AEN, &adapter->state))
+	while (test_bit(QLCNIC_DCB_AEN_MODE, &dcb->state))
 		usleep_range(10000, 11000);
 
 	cancel_delayed_work_sync(&dcb->aen_work);
@@ -298,23 +300,22 @@ static void __qlcnic_dcb_free(struct qlcnic_adapter *adapter)
 	adapter->dcb = NULL;
 }
 
-static void __qlcnic_dcb_get_info(struct qlcnic_adapter *adapter)
+static void __qlcnic_dcb_get_info(struct qlcnic_dcb *dcb)
 {
-	qlcnic_dcb_get_hw_capability(adapter);
-	qlcnic_dcb_get_cee_cfg(adapter);
-	qlcnic_dcb_register_aen(adapter, 1);
+	qlcnic_dcb_get_hw_capability(dcb);
+	qlcnic_dcb_get_cee_cfg(dcb);
+	qlcnic_dcb_register_aen(dcb, 1);
 }
 
-static int __qlcnic_dcb_attach(struct qlcnic_adapter *adapter)
+static int __qlcnic_dcb_attach(struct qlcnic_dcb *dcb)
 {
-	struct qlcnic_dcb *dcb = adapter->dcb;
 	int err = 0;
 
 	INIT_DELAYED_WORK(&dcb->aen_work, qlcnic_dcb_aen_work);
 
 	dcb->wq = create_singlethread_workqueue("qlcnic-dcb");
 	if (!dcb->wq) {
-		dev_err(&adapter->pdev->dev,
+		dev_err(&dcb->adapter->pdev->dev,
 			"DCB workqueue allocation failed. DCB will be disabled\n");
 		return -1;
 	}
@@ -331,7 +332,7 @@ static int __qlcnic_dcb_attach(struct qlcnic_adapter *adapter)
 		goto out_free_cfg;
 	}
 
-	qlcnic_dcb_get_info(adapter);
+	qlcnic_dcb_get_info(dcb);
 
 	return 0;
 out_free_cfg:
@@ -345,9 +346,9 @@ out_free_wq:
 	return err;
 }
 
-static int __qlcnic_dcb_query_hw_capability(struct qlcnic_adapter *adapter,
-					    char *buf)
+static int __qlcnic_dcb_query_hw_capability(struct qlcnic_dcb *dcb, char *buf)
 {
+	struct qlcnic_adapter *adapter = dcb->adapter;
 	struct qlcnic_cmd_args cmd;
 	u32 mbx_out;
 	int err;
@@ -371,15 +372,15 @@ static int __qlcnic_dcb_query_hw_capability(struct qlcnic_adapter *adapter,
 	return err;
 }
 
-static int __qlcnic_dcb_get_capability(struct qlcnic_adapter *adapter, u32 *val)
+static int __qlcnic_dcb_get_capability(struct qlcnic_dcb *dcb, u32 *val)
 {
-	struct qlcnic_dcb_capability *cap = &adapter->dcb->cfg->capability;
+	struct qlcnic_dcb_capability *cap = &dcb->cfg->capability;
 	u32 mbx_out;
 	int err;
 
 	memset(cap, 0, sizeof(struct qlcnic_dcb_capability));
 
-	err = qlcnic_dcb_query_hw_capability(adapter, (char *)val);
+	err = qlcnic_dcb_query_hw_capability(dcb, (char *)val);
 	if (err)
 		return err;
 
@@ -397,21 +398,21 @@ static int __qlcnic_dcb_get_capability(struct qlcnic_adapter *adapter, u32 *val)
 	if (cap->max_num_tc > QLC_DCB_MAX_TC ||
 	    cap->max_ets_tc > cap->max_num_tc ||
 	    cap->max_pfc_tc > cap->max_num_tc) {
-		dev_err(&adapter->pdev->dev, "Invalid DCB configuration\n");
+		dev_err(&dcb->adapter->pdev->dev, "Invalid DCB configuration\n");
 		return -EINVAL;
 	}
 
 	return err;
 }
 
-static int qlcnic_82xx_dcb_get_hw_capability(struct qlcnic_adapter *adapter)
+static int qlcnic_82xx_dcb_get_hw_capability(struct qlcnic_dcb *dcb)
 {
-	struct qlcnic_dcb_cfg *cfg = adapter->dcb->cfg;
+	struct qlcnic_dcb_cfg *cfg = dcb->cfg;
 	struct qlcnic_dcb_capability *cap;
 	u32 mbx_out;
 	int err;
 
-	err = __qlcnic_dcb_get_capability(adapter, &mbx_out);
+	err = __qlcnic_dcb_get_capability(dcb, &mbx_out);
 	if (err)
 		return err;
 
@@ -419,15 +420,16 @@ static int qlcnic_82xx_dcb_get_hw_capability(struct qlcnic_adapter *adapter)
 	cap->dcb_capability = DCB_CAP_DCBX_VER_CEE | DCB_CAP_DCBX_LLD_MANAGED;
 
 	if (cap->dcb_capability && cap->tsa_capability && cap->ets_capability)
-		set_bit(__QLCNIC_DCB_STATE, &adapter->state);
+		set_bit(QLCNIC_DCB_STATE, &dcb->state);
 
 	return err;
 }
 
-static int qlcnic_82xx_dcb_query_cee_param(struct qlcnic_adapter *adapter,
+static int qlcnic_82xx_dcb_query_cee_param(struct qlcnic_dcb *dcb,
 					   char *buf, u8 type)
 {
 	u16 size = sizeof(struct qlcnic_82xx_dcb_param_mbx_le);
+	struct qlcnic_adapter *adapter = dcb->adapter;
 	struct qlcnic_82xx_dcb_param_mbx_le *prsp_le;
 	struct device *dev = &adapter->pdev->dev;
 	dma_addr_t cardrsp_phys_addr;
@@ -447,8 +449,7 @@ static int qlcnic_82xx_dcb_query_cee_param(struct qlcnic_adapter *adapter,
 		return -EINVAL;
 	}
 
-	addr = dma_alloc_coherent(&adapter->pdev->dev, size, &cardrsp_phys_addr,
-				  GFP_KERNEL);
+	addr = dma_alloc_coherent(dev, size, &cardrsp_phys_addr, GFP_KERNEL);
 	if (addr == NULL)
 		return -ENOMEM;
 
@@ -488,72 +489,67 @@ out:
 	qlcnic_free_mbx_args(&cmd);
 
 out_free_rsp:
-	dma_free_coherent(&adapter->pdev->dev, size, addr, cardrsp_phys_addr);
+	dma_free_coherent(dev, size, addr, cardrsp_phys_addr);
 
 	return err;
 }
 
-static int qlcnic_82xx_dcb_get_cee_cfg(struct qlcnic_adapter *adapter)
+static int qlcnic_82xx_dcb_get_cee_cfg(struct qlcnic_dcb *dcb)
 {
 	struct qlcnic_dcb_mbx_params *mbx;
 	int err;
 
-	mbx = adapter->dcb->param;
+	mbx = dcb->param;
 	if (!mbx)
 		return 0;
 
-	err = qlcnic_dcb_query_cee_param(adapter, (char *)&mbx->type[0],
+	err = qlcnic_dcb_query_cee_param(dcb, (char *)&mbx->type[0],
 					 QLC_DCB_LOCAL_PARAM_FWID);
 	if (err)
 		return err;
 
-	err = qlcnic_dcb_query_cee_param(adapter, (char *)&mbx->type[1],
+	err = qlcnic_dcb_query_cee_param(dcb, (char *)&mbx->type[1],
 					 QLC_DCB_OPER_PARAM_FWID);
 	if (err)
 		return err;
 
-	err = qlcnic_dcb_query_cee_param(adapter, (char *)&mbx->type[2],
+	err = qlcnic_dcb_query_cee_param(dcb, (char *)&mbx->type[2],
 					 QLC_DCB_PEER_PARAM_FWID);
 	if (err)
 		return err;
 
 	mbx->prio_tc_map = QLC_82XX_DCB_PRIO_TC_MAP;
 
-	qlcnic_dcb_data_cee_param_map(adapter);
+	qlcnic_dcb_data_cee_param_map(dcb->adapter);
 
 	return err;
 }
 
 static void qlcnic_dcb_aen_work(struct work_struct *work)
 {
-	struct qlcnic_adapter *adapter;
 	struct qlcnic_dcb *dcb;
 
 	dcb = container_of(work, struct qlcnic_dcb, aen_work.work);
-	adapter = dcb->adapter;
 
-	qlcnic_dcb_get_cee_cfg(adapter);
-	clear_bit(__QLCNIC_DCB_IN_AEN, &adapter->state);
+	qlcnic_dcb_get_cee_cfg(dcb);
+	clear_bit(QLCNIC_DCB_AEN_MODE, &dcb->state);
 }
 
-static void qlcnic_82xx_dcb_handle_aen(struct qlcnic_adapter *adapter,
-				       void *data)
+static void qlcnic_82xx_dcb_aen_handler(struct qlcnic_dcb *dcb, void *data)
 {
-	struct qlcnic_dcb *dcb = adapter->dcb;
-
-	if (test_and_set_bit(__QLCNIC_DCB_IN_AEN, &adapter->state))
+	if (test_and_set_bit(QLCNIC_DCB_AEN_MODE, &dcb->state))
 		return;
 
 	queue_delayed_work(dcb->wq, &dcb->aen_work, 0);
 }
 
-static int qlcnic_83xx_dcb_get_hw_capability(struct qlcnic_adapter *adapter)
+static int qlcnic_83xx_dcb_get_hw_capability(struct qlcnic_dcb *dcb)
 {
-	struct qlcnic_dcb_capability *cap = &adapter->dcb->cfg->capability;
+	struct qlcnic_dcb_capability *cap = &dcb->cfg->capability;
 	u32 mbx_out;
 	int err;
 
-	err = __qlcnic_dcb_get_capability(adapter, &mbx_out);
+	err = __qlcnic_dcb_get_capability(dcb, &mbx_out);
 	if (err)
 		return err;
 
@@ -565,14 +561,15 @@ static int qlcnic_83xx_dcb_get_hw_capability(struct qlcnic_adapter *adapter)
 		cap->dcb_capability |= DCB_CAP_DCBX_LLD_MANAGED;
 
 	if (cap->dcb_capability && cap->tsa_capability && cap->ets_capability)
-		set_bit(__QLCNIC_DCB_STATE, &adapter->state);
+		set_bit(QLCNIC_DCB_STATE, &dcb->state);
 
 	return err;
 }
 
-static int qlcnic_83xx_dcb_query_cee_param(struct qlcnic_adapter *adapter,
+static int qlcnic_83xx_dcb_query_cee_param(struct qlcnic_dcb *dcb,
 					   char *buf, u8 idx)
 {
+	struct qlcnic_adapter *adapter = dcb->adapter;
 	struct qlcnic_dcb_mbx_params mbx_out;
 	int err, i, j, k, max_app, size;
 	struct qlcnic_dcb_param *each;
@@ -632,24 +629,23 @@ out:
 	return err;
 }
 
-static int qlcnic_83xx_dcb_get_cee_cfg(struct qlcnic_adapter *adapter)
+static int qlcnic_83xx_dcb_get_cee_cfg(struct qlcnic_dcb *dcb)
 {
-	struct qlcnic_dcb *dcb = adapter->dcb;
 	int err;
 
-	err = qlcnic_dcb_query_cee_param(adapter, (char *)dcb->param, 0);
+	err = qlcnic_dcb_query_cee_param(dcb, (char *)dcb->param, 0);
 	if (err)
 		return err;
 
-	qlcnic_dcb_data_cee_param_map(adapter);
+	qlcnic_dcb_data_cee_param_map(dcb->adapter);
 
 	return err;
 }
 
-static int qlcnic_83xx_dcb_register_aen(struct qlcnic_adapter *adapter,
-					bool flag)
+static int qlcnic_83xx_dcb_register_aen(struct qlcnic_dcb *dcb, bool flag)
 {
 	u8 val = (flag ? QLCNIC_CMD_INIT_NIC_FUNC : QLCNIC_CMD_STOP_NIC_FUNC);
+	struct qlcnic_adapter *adapter = dcb->adapter;
 	struct qlcnic_cmd_args cmd;
 	int err;
 
@@ -669,19 +665,17 @@ static int qlcnic_83xx_dcb_register_aen(struct qlcnic_adapter *adapter,
 	return err;
 }
 
-static void qlcnic_83xx_dcb_handle_aen(struct qlcnic_adapter *adapter,
-				       void *data)
+static void qlcnic_83xx_dcb_aen_handler(struct qlcnic_dcb *dcb, void *data)
 {
-	struct qlcnic_dcb *dcb = adapter->dcb;
 	u32 *val = data;
 
-	if (test_and_set_bit(__QLCNIC_DCB_IN_AEN, &adapter->state))
+	if (test_and_set_bit(QLCNIC_DCB_AEN_MODE, &dcb->state))
 		return;
 
 	if (*val & BIT_8)
-		set_bit(__QLCNIC_DCB_STATE, &adapter->state);
+		set_bit(QLCNIC_DCB_STATE, &dcb->state);
 	else
-		clear_bit(__QLCNIC_DCB_STATE, &adapter->state);
+		clear_bit(QLCNIC_DCB_STATE, &dcb->state);
 
 	queue_delayed_work(dcb->wq, &dcb->aen_work, 0);
 }
@@ -814,7 +808,7 @@ static u8 qlcnic_dcb_get_state(struct net_device *netdev)
 {
 	struct qlcnic_adapter *adapter = netdev_priv(netdev);
 
-	return test_bit(__QLCNIC_DCB_STATE, &adapter->state);
+	return test_bit(QLCNIC_DCB_STATE, &adapter->dcb->state);
 }
 
 static void qlcnic_dcb_get_perm_hw_addr(struct net_device *netdev, u8 *addr)
@@ -834,7 +828,7 @@ qlcnic_dcb_get_pg_tc_cfg_tx(struct net_device *netdev, int tc, u8 *prio,
 	type = &adapter->dcb->cfg->type[QLC_DCB_OPER_IDX];
 	*prio = *pgid = *bw_per = *up_tc_map = 0;
 
-	if (!test_bit(__QLCNIC_DCB_STATE, &adapter->state) ||
+	if (!test_bit(QLCNIC_DCB_STATE, &adapter->dcb->state) ||
 	    !type->tc_param_valid)
 		return;
 
@@ -870,7 +864,7 @@ static void qlcnic_dcb_get_pg_bwg_cfg_tx(struct net_device *netdev, int pgid,
 	*bw_pct = 0;
 	type = &adapter->dcb->cfg->type[QLC_DCB_OPER_IDX];
 
-	if (!test_bit(__QLCNIC_DCB_STATE, &adapter->state) ||
+	if (!test_bit(QLCNIC_DCB_STATE, &adapter->dcb->state) ||
 	    !type->tc_param_valid)
 		return;
 
@@ -896,7 +890,7 @@ static void qlcnic_dcb_get_pfc_cfg(struct net_device *netdev, int prio,
 	*setting = 0;
 	type = &adapter->dcb->cfg->type[QLC_DCB_OPER_IDX];
 
-	if (!test_bit(__QLCNIC_DCB_STATE, &adapter->state) ||
+	if (!test_bit(QLCNIC_DCB_STATE, &adapter->dcb->state) ||
 	    !type->pfc_mode_enable)
 		return;
 
@@ -915,7 +909,7 @@ static u8 qlcnic_dcb_get_capability(struct net_device *netdev, int capid,
 {
 	struct qlcnic_adapter *adapter = netdev_priv(netdev);
 
-	if (!test_bit(__QLCNIC_DCB_STATE, &adapter->state))
+	if (!test_bit(QLCNIC_DCB_STATE, &adapter->dcb->state))
 		return 0;
 
 	switch (capid) {
@@ -944,7 +938,7 @@ static int qlcnic_dcb_get_num_tcs(struct net_device *netdev, int attr, u8 *num)
 	struct qlcnic_adapter *adapter = netdev_priv(netdev);
 	struct qlcnic_dcb_cfg *cfg = adapter->dcb->cfg;
 
-	if (!test_bit(__QLCNIC_DCB_STATE, &adapter->state))
+	if (!test_bit(QLCNIC_DCB_STATE, &adapter->dcb->state))
 		return -EINVAL;
 
 	switch (attr) {
@@ -967,7 +961,7 @@ static u8 qlcnic_dcb_get_app(struct net_device *netdev, u8 idtype, u16 id)
 				.protocol = id,
 			     };
 
-	if (!test_bit(__QLCNIC_DCB_STATE, &adapter->state))
+	if (!test_bit(QLCNIC_DCB_STATE, &adapter->dcb->state))
 		return 0;
 
 	return dcb_getapp(netdev, &app);
@@ -978,7 +972,7 @@ static u8 qlcnic_dcb_get_pfc_state(struct net_device *netdev)
 	struct qlcnic_adapter *adapter = netdev_priv(netdev);
 	struct qlcnic_dcb *dcb = adapter->dcb;
 
-	if (!test_bit(__QLCNIC_DCB_STATE, &adapter->state))
+	if (!test_bit(QLCNIC_DCB_STATE, &dcb->state))
 		return 0;
 
 	return dcb->cfg->type[QLC_DCB_OPER_IDX].pfc_mode_enable;
@@ -989,7 +983,7 @@ static u8 qlcnic_dcb_get_dcbx(struct net_device *netdev)
 	struct qlcnic_adapter *adapter = netdev_priv(netdev);
 	struct qlcnic_dcb_cfg *cfg = adapter->dcb->cfg;
 
-	if (!test_bit(__QLCNIC_DCB_STATE, &adapter->state))
+	if (!test_bit(QLCNIC_DCB_STATE, &adapter->dcb->state))
 		return 0;
 
 	return cfg->capability.dcb_capability;
@@ -1000,7 +994,7 @@ static u8 qlcnic_dcb_get_feat_cfg(struct net_device *netdev, int fid, u8 *flag)
 	struct qlcnic_adapter *adapter = netdev_priv(netdev);
 	struct qlcnic_dcb_cee *type;
 
-	if (!test_bit(__QLCNIC_DCB_STATE, &adapter->state))
+	if (!test_bit(QLCNIC_DCB_STATE, &adapter->dcb->state))
 		return 1;
 
 	type = &adapter->dcb->cfg->type[QLC_DCB_OPER_IDX];
@@ -1055,7 +1049,7 @@ static int qlcnic_dcb_peer_app_info(struct net_device *netdev,
 
 	*app_count = 0;
 
-	if (!test_bit(__QLCNIC_DCB_STATE, &adapter->state))
+	if (!test_bit(QLCNIC_DCB_STATE, &adapter->dcb->state))
 		return 0;
 
 	peer = &adapter->dcb->cfg->type[QLC_DCB_PEER_IDX];
@@ -1076,7 +1070,7 @@ static int qlcnic_dcb_peer_app_table(struct net_device *netdev,
 	struct qlcnic_dcb_app *app;
 	int i, j;
 
-	if (!test_bit(__QLCNIC_DCB_STATE, &adapter->state))
+	if (!test_bit(QLCNIC_DCB_STATE, &adapter->dcb->state))
 		return 0;
 
 	peer = &adapter->dcb->cfg->type[QLC_DCB_PEER_IDX];
@@ -1101,7 +1095,7 @@ static int qlcnic_dcb_cee_peer_get_pg(struct net_device *netdev,
 	struct qlcnic_dcb_cee *peer;
 	u8 i, j, k, map;
 
-	if (!test_bit(__QLCNIC_DCB_STATE, &adapter->state))
+	if (!test_bit(QLCNIC_DCB_STATE, &adapter->dcb->state))
 		return 0;
 
 	peer = &adapter->dcb->cfg->type[QLC_DCB_PEER_IDX];
@@ -1136,7 +1130,7 @@ static int qlcnic_dcb_cee_peer_get_pfc(struct net_device *netdev,
 
 	pfc->pfc_en = 0;
 
-	if (!test_bit(__QLCNIC_DCB_STATE, &adapter->state))
+	if (!test_bit(QLCNIC_DCB_STATE, &adapter->dcb->state))
 		return 0;
 
 	peer = &cfg->type[QLC_DCB_PEER_IDX];
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.h
index b87ce9f..c04ae0c 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.h
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.h
@@ -8,26 +8,29 @@
 #ifndef __QLCNIC_DCBX_H
 #define __QLCNIC_DCBX_H
 
-void qlcnic_clear_dcb_ops(struct qlcnic_adapter *);
+#define QLCNIC_DCB_STATE	0
+#define QLCNIC_DCB_AEN_MODE	1
 
 #ifdef CONFIG_QLCNIC_DCB
-int __qlcnic_register_dcb(struct qlcnic_adapter *);
+int qlcnic_register_dcb(struct qlcnic_adapter *);
 #else
-static inline int __qlcnic_register_dcb(struct qlcnic_adapter *adapter)
+static inline int qlcnic_register_dcb(struct qlcnic_adapter *adapter)
 { return 0; }
 #endif
 
+struct qlcnic_dcb;
+
 struct qlcnic_dcb_ops {
-	void (*init_dcbnl_ops) (struct qlcnic_adapter *);
-	void (*free) (struct qlcnic_adapter *);
-	int (*attach) (struct qlcnic_adapter *);
-	int (*query_hw_capability) (struct qlcnic_adapter *, char *);
-	int (*get_hw_capability) (struct qlcnic_adapter *);
-	void (*get_info) (struct qlcnic_adapter *);
-	int (*query_cee_param) (struct qlcnic_adapter *, char *, u8);
-	int (*get_cee_cfg) (struct qlcnic_adapter *);
-	int (*register_aen) (struct qlcnic_adapter *, bool);
-	void (*handle_aen) (struct qlcnic_adapter *, void *);
+	int (*query_hw_capability) (struct qlcnic_dcb *, char *);
+	int (*get_hw_capability) (struct qlcnic_dcb *);
+	int (*query_cee_param) (struct qlcnic_dcb *, char *, u8);
+	void (*init_dcbnl_ops) (struct qlcnic_dcb *);
+	int (*register_aen) (struct qlcnic_dcb *, bool);
+	void (*aen_handler) (struct qlcnic_dcb *, void *);
+	int (*get_cee_cfg) (struct qlcnic_dcb *);
+	void (*get_info) (struct qlcnic_dcb *);
+	int (*attach) (struct qlcnic_dcb *);
+	void (*free) (struct qlcnic_dcb *);
 };
 
 struct qlcnic_dcb {
@@ -37,5 +40,85 @@ struct qlcnic_dcb {
 	struct workqueue_struct		*wq;
 	struct qlcnic_dcb_ops		*ops;
 	struct qlcnic_dcb_cfg		*cfg;
+	unsigned long			state;
 };
+
+static inline void qlcnic_clear_dcb_ops(struct qlcnic_dcb *dcb)
+{
+	kfree(dcb);
+	dcb = NULL;
+}
+
+static inline int qlcnic_dcb_get_hw_capability(struct qlcnic_dcb *dcb)
+{
+	if (dcb && dcb->ops->get_hw_capability)
+		return dcb->ops->get_hw_capability(dcb);
+
+	return 0;
+}
+
+static inline void qlcnic_dcb_free(struct qlcnic_dcb *dcb)
+{
+	if (dcb && dcb->ops->free)
+		dcb->ops->free(dcb);
+}
+
+static inline int qlcnic_dcb_attach(struct qlcnic_dcb *dcb)
+{
+	if (dcb && dcb->ops->attach)
+		return dcb->ops->attach(dcb);
+
+	return 0;
+}
+
+static inline int
+qlcnic_dcb_query_hw_capability(struct qlcnic_dcb *dcb, char *buf)
+{
+	if (dcb && dcb->ops->query_hw_capability)
+		return dcb->ops->query_hw_capability(dcb, buf);
+
+	return 0;
+}
+
+static inline void qlcnic_dcb_get_info(struct qlcnic_dcb *dcb)
+{
+	if (dcb && dcb->ops->get_info)
+		dcb->ops->get_info(dcb);
+}
+
+static inline int
+qlcnic_dcb_query_cee_param(struct qlcnic_dcb *dcb, char *buf, u8 type)
+{
+	if (dcb && dcb->ops->query_cee_param)
+		return dcb->ops->query_cee_param(dcb, buf, type);
+
+	return 0;
+}
+
+static inline int qlcnic_dcb_get_cee_cfg(struct qlcnic_dcb *dcb)
+{
+	if (dcb && dcb->ops->get_cee_cfg)
+		return dcb->ops->get_cee_cfg(dcb);
+
+	return 0;
+}
+
+static inline void
+qlcnic_dcb_register_aen(struct qlcnic_dcb *dcb, u8 flag)
+{
+	if (dcb && dcb->ops->register_aen)
+		dcb->ops->register_aen(dcb, flag);
+}
+
+static inline void qlcnic_dcb_aen_handler(struct qlcnic_dcb *dcb, void *msg)
+{
+	if (dcb && dcb->ops->aen_handler)
+		dcb->ops->aen_handler(dcb, msg);
+}
+
+static inline void qlcnic_dcb_init_dcbnl_ops(struct qlcnic_dcb *dcb)
+{
+	if (dcb && dcb->ops->init_dcbnl_ops)
+		dcb->ops->init_dcbnl_ops(dcb);
+}
 #endif
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c
index 11b4bb8..897627d 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c
@@ -1011,7 +1011,7 @@ static void qlcnic_handle_fw_message(int desc_cnt, int index,
 		}
 		break;
 	case QLCNIC_C2H_OPCODE_GET_DCB_AEN:
-		qlcnic_dcb_handle_aen(adapter, (void *)&msg);
+		qlcnic_dcb_aen_handler(adapter->dcb, (void *)&msg);
 		break;
 	default:
 		break;
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
index 807d382..aaf67bd 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
@@ -2071,7 +2071,7 @@ qlcnic_setup_netdev(struct qlcnic_adapter *adapter, struct net_device *netdev,
 		return err;
 	}
 
-	qlcnic_dcb_init_dcbnl_ops(adapter);
+	qlcnic_dcb_init_dcbnl_ops(adapter->dcb);
 
 	return 0;
 }
@@ -2166,17 +2166,6 @@ void qlcnic_set_drv_version(struct qlcnic_adapter *adapter)
 		qlcnic_fw_cmd_set_drv_version(adapter, fw_cmd);
 }
 
-static int qlcnic_register_dcb(struct qlcnic_adapter *adapter)
-{
-	return __qlcnic_register_dcb(adapter);
-}
-
-void qlcnic_clear_dcb_ops(struct qlcnic_adapter *adapter)
-{
-	kfree(adapter->dcb);
-	adapter->dcb = NULL;
-}
-
 static int
 qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
@@ -2185,6 +2174,7 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	struct qlcnic_hardware_context *ahw;
 	int err, pci_using_dac = -1;
 	char board_name[QLCNIC_MAX_BOARD_NAME_LEN + 19]; /* MAC + ": " + name */
+	struct qlcnic_dcb *dcb;
 
 	if (pdev->is_virtfn)
 		return -ENODEV;
@@ -2305,8 +2295,10 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 
 		adapter->flags |= QLCNIC_NEED_FLR;
 
-		if (adapter->dcb && qlcnic_dcb_attach(adapter))
-			qlcnic_clear_dcb_ops(adapter);
+		dcb = adapter->dcb;
+
+		if (dcb && qlcnic_dcb_attach(dcb))
+			qlcnic_clear_dcb_ops(dcb);
 
 	} else if (qlcnic_83xx_check(adapter)) {
 		adapter->max_drv_tx_rings = 1;
@@ -2448,7 +2440,7 @@ static void qlcnic_remove(struct pci_dev *pdev)
 	qlcnic_cancel_idc_work(adapter);
 	ahw = adapter->ahw;
 
-	qlcnic_dcb_free(adapter);
+	qlcnic_dcb_free(adapter->dcb);
 
 	unregister_netdev(netdev);
 	qlcnic_sriov_cleanup(adapter);
@@ -3326,7 +3318,7 @@ qlcnic_attach_work(struct work_struct *work)
 		return;
 	}
 attach:
-	qlcnic_dcb_get_info(adapter);
+	qlcnic_dcb_get_info(adapter->dcb);
 
 	if (netif_running(netdev)) {
 		if (qlcnic_up(adapter, netdev))
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c
index 392b9bd..8b96e29 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c
@@ -500,6 +500,7 @@ static int qlcnic_sriov_vf_init_driver(struct qlcnic_adapter *adapter)
 static int qlcnic_sriov_setup_vf(struct qlcnic_adapter *adapter,
 				 int pci_using_dac)
 {
+	struct qlcnic_dcb *dcb;
 	int err;
 
 	INIT_LIST_HEAD(&adapter->vf_mc_list);
@@ -533,8 +534,10 @@ static int qlcnic_sriov_setup_vf(struct qlcnic_adapter *adapter,
 	if (err)
 		goto err_out_send_channel_term;
 
-	if (adapter->dcb && qlcnic_dcb_attach(adapter))
-		qlcnic_clear_dcb_ops(adapter);
+	dcb = adapter->dcb;
+
+	if (dcb && qlcnic_dcb_attach(dcb))
+		qlcnic_clear_dcb_ops(dcb);
 
 	err = qlcnic_setup_netdev(adapter, adapter->netdev, pci_using_dac);
 	if (err)
@@ -1577,7 +1580,7 @@ static int qlcnic_sriov_vf_reinit_driver(struct qlcnic_adapter *adapter)
 	if (err)
 		goto err_out_term_channel;
 
-	qlcnic_dcb_get_info(adapter);
+	qlcnic_dcb_get_info(adapter->dcb);
 
 	return 0;
 
-- 
1.8.1.4

^ permalink raw reply related

* [PATCH net-next 05/10] qlcnic: Remove redundant eSwitch enable commands
From: Himanshu Madhani @ 2013-10-04 18:30 UTC (permalink / raw)
  To: davem; +Cc: netdev, Dept_NX_Linux_NIC_Driver, Sony Chacko, himanshu.madhani
In-Reply-To: <cover.1380937706.git.himanshu.madhani@qlogic.com>

From: Sony Chacko <sony.chacko@qlogic.com>

When more than one NIC physical functions are enabled on a port,
eSwitch on that port gets enabled automatically. Driver
need not explicitly enable the eSwitch.

Signed-off-by: Sony Chacko <sony.chacko@qlogic.com>
Signed-off-by: Himanshu Madhani <himanshu.madhani@qlogic.com>
---
 .../net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h    |  2 +-
 .../net/ethernet/qlogic/qlcnic/qlcnic_83xx_vnic.c  | 23 ++++------------------
 drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c   | 13 ++++++------
 3 files changed, 12 insertions(+), 26 deletions(-)

diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h
index 2883b57..9f4e4c4 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h
@@ -629,7 +629,7 @@ int qlcnic_83xx_config_vnic_opmode(struct qlcnic_adapter *);
 int qlcnic_83xx_get_vnic_vport_info(struct qlcnic_adapter *,
 				    struct qlcnic_info *, u8);
 int qlcnic_83xx_get_vnic_pf_info(struct qlcnic_adapter *, struct qlcnic_info *);
-int qlcnic_83xx_enable_port_eswitch(struct qlcnic_adapter *, int);
+int qlcnic_83xx_set_port_eswitch_status(struct qlcnic_adapter *, int, int *);
 
 void qlcnic_83xx_get_minidump_template(struct qlcnic_adapter *);
 void qlcnic_83xx_get_stats(struct qlcnic_adapter *adapter, u64 *data);
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_vnic.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_vnic.c
index 63cdddf..97caf10 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_vnic.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_vnic.c
@@ -257,8 +257,8 @@ int qlcnic_83xx_check_vnic_state(struct qlcnic_adapter *adapter)
 	return 0;
 }
 
-static int qlcnic_83xx_get_eswitch_port_info(struct qlcnic_adapter *adapter,
-					     int func, int *port_id)
+int qlcnic_83xx_set_port_eswitch_status(struct qlcnic_adapter *adapter,
+					int func, int *port_id)
 {
 	struct qlcnic_info nic_info;
 	int err = 0;
@@ -274,23 +274,8 @@ static int qlcnic_83xx_get_eswitch_port_info(struct qlcnic_adapter *adapter,
 	else
 		err = -EIO;
 
-	return err;
-}
-
-int qlcnic_83xx_enable_port_eswitch(struct qlcnic_adapter *adapter, int func)
-{
-	int id, err = 0;
-
-	err = qlcnic_83xx_get_eswitch_port_info(adapter, func, &id);
-	if (err)
-		return err;
-
-	if (!(adapter->eswitch[id].flags & QLCNIC_SWITCH_ENABLE)) {
-		if (!qlcnic_enable_eswitch(adapter, id, 1))
-			adapter->eswitch[id].flags |= QLCNIC_SWITCH_ENABLE;
-		else
-			err = -EIO;
-	}
+	if (!err)
+		adapter->eswitch[*port_id].flags |= QLCNIC_SWITCH_ENABLE;
 
 	return err;
 }
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
index ffc652f..807d382 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
@@ -819,7 +819,7 @@ static bool qlcnic_port_eswitch_cfg_capability(struct qlcnic_adapter *adapter)
 int qlcnic_init_pci_info(struct qlcnic_adapter *adapter)
 {
 	struct qlcnic_pci_info *pci_info;
-	int i, ret = 0, j = 0;
+	int i, id = 0, ret = 0, j = 0;
 	u16 act_pci_func;
 	u8 pfn;
 
@@ -860,7 +860,8 @@ int qlcnic_init_pci_info(struct qlcnic_adapter *adapter)
 			continue;
 
 		if (qlcnic_port_eswitch_cfg_capability(adapter)) {
-			if (!qlcnic_83xx_enable_port_eswitch(adapter, pfn))
+			if (!qlcnic_83xx_set_port_eswitch_status(adapter, pfn,
+								 &id))
 				adapter->npars[j].eswitch_status = true;
 			else
 				continue;
@@ -879,12 +880,12 @@ int qlcnic_init_pci_info(struct qlcnic_adapter *adapter)
 		j++;
 	}
 
-	if (qlcnic_82xx_check(adapter)) {
+	/* Update eSwitch status for adapters without per port eSwitch
+	 * configuration capability
+	 */
+	if (!qlcnic_port_eswitch_cfg_capability(adapter)) {
 		for (i = 0; i < QLCNIC_NIU_MAX_XG_PORTS; i++)
 			adapter->eswitch[i].flags |= QLCNIC_SWITCH_ENABLE;
-	} else if (!qlcnic_port_eswitch_cfg_capability(adapter)) {
-		for (i = 0; i < QLCNIC_NIU_MAX_XG_PORTS; i++)
-			qlcnic_enable_eswitch(adapter, i, 1);
 	}
 
 	kfree(pci_info);
-- 
1.8.1.4

^ permalink raw reply related

* [PATCH net-next 01/10] qlcnic: Print informational messages only once during driver load.
From: Himanshu Madhani @ 2013-10-04 18:30 UTC (permalink / raw)
  To: davem
  Cc: netdev, Dept_NX_Linux_NIC_Driver, Sucheta Chakraborty,
	himanshu.madhani
In-Reply-To: <cover.1380937706.git.himanshu.madhani@qlogic.com>

From: Sucheta Chakraborty <sucheta.chakraborty@qlogic.com>

Signed-off-by: Sucheta Chakraborty <sucheta.chakraborty@qlogic.com>
Signed-off-by: Himanshu Madhani <himanshu.madhani@qlogic.com>
---
 drivers/net/ethernet/qlogic/qlcnic/qlcnic.h        |  1 +
 .../net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c    | 12 -----------
 .../net/ethernet/qlogic/qlcnic/qlcnic_83xx_vnic.c  | 25 ++++++++++++++++++----
 drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c   |  1 +
 4 files changed, 23 insertions(+), 16 deletions(-)

diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
index 81bf836..a3c4379 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
@@ -1199,6 +1199,7 @@ struct qlcnic_npar_info {
 	u8	promisc_mode;
 	u8	offload_flags;
 	u8      pci_func;
+	u8      mac[ETH_ALEN];
 };
 
 struct qlcnic_eswitch {
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
index 3ca00e0..66e94dc 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
@@ -2321,19 +2321,7 @@ int qlcnic_83xx_get_pci_info(struct qlcnic_adapter *adapter,
 			i++;
 			memcpy(pci_info->mac + sizeof(u32), &cmd.rsp.arg[i], 2);
 			i = i + 3;
-			if (ahw->op_mode == QLCNIC_MGMT_FUNC)
-				dev_info(dev, "id = %d active = %d type = %d\n"
-					 "\tport = %d min bw = %d max bw = %d\n"
-					 "\tmac_addr =  %pM\n", pci_info->id,
-					 pci_info->active, pci_info->type,
-					 pci_info->default_port,
-					 pci_info->tx_min_bw,
-					 pci_info->tx_max_bw, pci_info->mac);
 		}
-		if (ahw->op_mode == QLCNIC_MGMT_FUNC)
-			dev_info(dev, "Max functions = %d, active functions = %d\n",
-				 ahw->max_pci_func, ahw->act_pci_func);
-
 	} else {
 		dev_err(dev, "Failed to get PCI Info, error = %d\n", err);
 		err = -EIO;
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_vnic.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_vnic.c
index 0248a4c..63cdddf 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_vnic.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_vnic.c
@@ -94,13 +94,30 @@ qlcnic_83xx_config_vnic_buff_descriptors(struct qlcnic_adapter *adapter)
  **/
 static int qlcnic_83xx_init_mgmt_vnic(struct qlcnic_adapter *adapter)
 {
-	int err = -EIO;
+	struct qlcnic_hardware_context *ahw = adapter->ahw;
+	struct device *dev = &adapter->pdev->dev;
+	struct qlcnic_npar_info *npar;
+	int i, err = -EIO;
 
 	qlcnic_83xx_get_minidump_template(adapter);
+
 	if (!(adapter->flags & QLCNIC_ADAPTER_INITIALIZED)) {
 		if (qlcnic_init_pci_info(adapter))
 			return err;
 
+		npar = adapter->npars;
+
+		for (i = 0; i < ahw->act_pci_func; i++, npar++) {
+			dev_info(dev, "id = %d active = %d type = %d\n"
+				 "\tport = %d min bw = %d max bw = %d\n"
+				 "\tmac_addr =  %pM\n", npar->pci_func,
+				 npar->active, npar->type, npar->phy_port,
+				 npar->min_bw, npar->max_bw, npar->mac);
+		}
+
+		dev_info(dev, "Max functions = %d, active functions = %d\n",
+			 ahw->max_pci_func, ahw->act_pci_func);
+
 		if (qlcnic_83xx_set_vnic_opmode(adapter))
 			return err;
 
@@ -115,12 +132,12 @@ static int qlcnic_83xx_init_mgmt_vnic(struct qlcnic_adapter *adapter)
 		return err;
 
 	qlcnic_83xx_config_vnic_buff_descriptors(adapter);
-	adapter->ahw->msix_supported = !!qlcnic_use_msi_x;
+	ahw->msix_supported = qlcnic_use_msi_x ? 1 : 0;
 	adapter->flags |= QLCNIC_ADAPTER_INITIALIZED;
 	qlcnic_83xx_enable_vnic_mode(adapter, 1);
 
-	dev_info(&adapter->pdev->dev, "HAL Version: %d, Management function\n",
-		 adapter->ahw->fw_hal_version);
+	dev_info(dev, "HAL Version: %d, Management function\n",
+		 ahw->fw_hal_version);
 
 	return 0;
 }
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
index 21d00a0..11bedc5 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
@@ -875,6 +875,7 @@ int qlcnic_init_pci_info(struct qlcnic_adapter *adapter)
 		adapter->npars[j].min_bw = pci_info[i].tx_min_bw;
 		adapter->npars[j].max_bw = pci_info[i].tx_max_bw;
 
+		memcpy(&adapter->npars[j].mac, &pci_info[i].mac, ETH_ALEN);
 		j++;
 	}
 
-- 
1.8.1.4

^ permalink raw reply related

* [PATCH net-next 00/10] qlcnic: fixes and ethtool enhancements.
From: Himanshu Madhani @ 2013-10-04 18:30 UTC (permalink / raw)
  To: davem; +Cc: netdev, Dept_NX_Linux_NIC_Driver, Himanshu Madhani

From: Himanshu Madhani <himanshu.madhani@qlogic.com>

This patch series contains

o patch to fix regression introduced by commit
  aa4a1f7df7cbb98797c9f4edfde3c726e2b3841f.
o updates to ethtool for pause settings and enhance
  register dump to display mask and ring indices.
o cleanup in DCB code and remove redundant eSwitch enablement command.
o fixed firmware dump collection logic to skip unknown entries.
o fix to register device if adapter is in FAILED state.

Please apply to net-next.

Thanks,
Himanshu

Himanshu Madhani (2):
  qlcnic: Validate Tx queue only for 82xx adapters.
  qlcnic: update version to 5.3.51

Jitendra Kalsaria (1):
  qlcnic: Update ethtool standard pause settings.

Pratik Pujar (2):
  qlcnic: Enhance ethtool to display ring indices and interrupt mask
  qlcnic: Firmware dump collection when auto recovery is disabled.

Shahed Shaikh (1):
  qlcnic: Skip unknown entry type while collecting firmware dump

Sony Chacko (1):
  qlcnic: Remove redundant eSwitch enable commands

Sucheta Chakraborty (3):
  qlcnic: Print informational messages only once during driver load.
  qlcnic: dcb code cleanup and refactoring.
  qlcnic: Register netdev in FAILED state for 83xx/84xx

 drivers/net/ethernet/qlogic/qlcnic/qlcnic.h        | 102 +-----------
 .../net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c    |  72 ++++----
 .../net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h    |   5 +-
 .../net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c  |  36 ++--
 .../net/ethernet/qlogic/qlcnic/qlcnic_83xx_vnic.c  |  48 +++---
 drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.c    | 182 ++++++++++-----------
 drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.h    | 109 ++++++++++--
 .../net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c    |  69 +++++---
 drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c     |   2 +-
 drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c   |  90 +++++-----
 .../net/ethernet/qlogic/qlcnic/qlcnic_minidump.c   |  41 +++--
 .../ethernet/qlogic/qlcnic/qlcnic_sriov_common.c   |   9 +-
 drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c  |   8 +-
 13 files changed, 417 insertions(+), 356 deletions(-)

-- 
1.8.1.4

^ permalink raw reply

* [PATCH net-next 03/10] qlcnic: Firmware dump collection when auto recovery is disabled.
From: Himanshu Madhani @ 2013-10-04 18:30 UTC (permalink / raw)
  To: davem; +Cc: netdev, Dept_NX_Linux_NIC_Driver, Pratik Pujar, himanshu.madhani
In-Reply-To: <cover.1380937706.git.himanshu.madhani@qlogic.com>

From: Pratik Pujar <pratik.pujar@qlogic.com>

o Allow collecting the firmware dump of halted firmware when auto
  recovery is disabled.

Signed-off-by: Pratik Pujar <pratik.pujar@qlogic.com>
Signed-off-by: Himanshu Madhani <himanshu.madhani@qlogic.com>
---
 drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c | 11 +++++++++++
 drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c      |  7 ++++++-
 2 files changed, 17 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c
index f09e787..d303fab 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c
@@ -818,6 +818,7 @@ static int qlcnic_83xx_idc_ready_state(struct qlcnic_adapter *adapter)
 	struct qlcnic_hardware_context *ahw = adapter->ahw;
 	struct qlcnic_mailbox *mbx = ahw->mailbox;
 	int ret = 0;
+	u32 owner;
 	u32 val;
 
 	/* Perform NIC configuration based ready state entry actions */
@@ -846,6 +847,10 @@ static int qlcnic_83xx_idc_ready_state(struct qlcnic_adapter *adapter)
 			clear_bit(QLC_83XX_MBX_READY, &mbx->status);
 			set_bit(__QLCNIC_RESETTING, &adapter->state);
 			qlcnic_83xx_idc_enter_need_reset_state(adapter, 1);
+		}  else {
+			owner = qlcnic_83xx_idc_find_reset_owner_id(adapter);
+			if (ahw->pci_func == owner)
+				qlcnic_dump_fw(adapter);
 		}
 		return -EIO;
 	}
@@ -1058,6 +1063,12 @@ void qlcnic_83xx_idc_poll_dev_state(struct work_struct *work)
 	adapter->ahw->idc.prev_state = adapter->ahw->idc.curr_state;
 	qlcnic_83xx_periodic_tasks(adapter);
 
+	/* Do not reschedule if firmaware is in hanged state and auto
+	 * recovery is disabled
+	 */
+	if ((adapter->flags & QLCNIC_FW_HANG) && !qlcnic_auto_fw_reset)
+		return;
+
 	/* Re-schedule the function */
 	if (test_bit(QLC_83XX_MODULE_LOADED, &adapter->ahw->idc.status))
 		qlcnic_schedule_work(adapter, qlcnic_83xx_idc_poll_dev_state,
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
index 11bedc5..ffc652f 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
@@ -3350,6 +3350,8 @@ done:
 static int
 qlcnic_check_health(struct qlcnic_adapter *adapter)
 {
+	struct qlcnic_hardware_context *ahw = adapter->ahw;
+	struct qlcnic_fw_dump *fw_dump = &ahw->fw_dump;
 	u32 state = 0, heartbeat;
 	u32 peg_status;
 	int err = 0;
@@ -3374,7 +3376,7 @@ qlcnic_check_health(struct qlcnic_adapter *adapter)
 		if (adapter->need_fw_reset)
 			goto detach;
 
-		if (adapter->ahw->reset_context && qlcnic_auto_fw_reset)
+		if (ahw->reset_context && qlcnic_auto_fw_reset)
 			qlcnic_reset_hw_context(adapter);
 
 		return 0;
@@ -3417,6 +3419,9 @@ detach:
 
 		qlcnic_schedule_work(adapter, qlcnic_detach_work, 0);
 		QLCDB(adapter, DRV, "fw recovery scheduled.\n");
+	} else if (!qlcnic_auto_fw_reset && fw_dump->enable &&
+		   adapter->flags & QLCNIC_FW_RESET_OWNER) {
+		qlcnic_dump_fw(adapter);
 	}
 
 	return 1;
-- 
1.8.1.4

^ permalink raw reply related

* [PATCH net-next 04/10] qlcnic: Update ethtool standard pause settings.
From: Himanshu Madhani @ 2013-10-04 18:30 UTC (permalink / raw)
  To: davem; +Cc: netdev, Dept_NX_Linux_NIC_Driver, Jitendra Kalsaria,
	himanshu.madhani
In-Reply-To: <cover.1380937706.git.himanshu.madhani@qlogic.com>

From: Jitendra Kalsaria <jitendra.kalsaria@qlogic.com>

Update ethtool standard pause parameter settings and display

Signed-off-by: Jitendra Kalsaria <jitendra.kalsaria@qlogic.com>
Signed-off-by: Himanshu Madhani <himanshu.madhani@qlogic.com>
---
 drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c | 18 +++++++++++++++---
 drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h |  3 +++
 2 files changed, 18 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
index c2df4ce..268fda6 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
@@ -3369,10 +3369,21 @@ void qlcnic_83xx_get_pauseparam(struct qlcnic_adapter *adapter,
 	}
 	config = ahw->port_config;
 	if (config & QLC_83XX_CFG_STD_PAUSE) {
-		if (config & QLC_83XX_CFG_STD_TX_PAUSE)
+		switch (MSW(config)) {
+		case QLC_83XX_TX_PAUSE:
+			pause->tx_pause = 1;
+			break;
+		case QLC_83XX_RX_PAUSE:
+			pause->rx_pause = 1;
+			break;
+		case QLC_83XX_TX_RX_PAUSE:
+		default:
+			/* Backward compatibility for existing
+			 * flash definitions
+			 */
 			pause->tx_pause = 1;
-		if (config & QLC_83XX_CFG_STD_RX_PAUSE)
 			pause->rx_pause = 1;
+		}
 	}
 
 	if (QLC_83XX_AUTONEG(config))
@@ -3415,7 +3426,8 @@ int qlcnic_83xx_set_pauseparam(struct qlcnic_adapter *adapter,
 		ahw->port_config &= ~QLC_83XX_CFG_STD_RX_PAUSE;
 		ahw->port_config |= QLC_83XX_CFG_STD_TX_PAUSE;
 	} else if (!pause->rx_pause && !pause->tx_pause) {
-		ahw->port_config &= ~QLC_83XX_CFG_STD_TX_RX_PAUSE;
+		ahw->port_config &= ~(QLC_83XX_CFG_STD_TX_RX_PAUSE |
+				      QLC_83XX_CFG_STD_PAUSE);
 	}
 	status = qlcnic_83xx_set_port_config(adapter);
 	if (status) {
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h
index 533e150..2883b57 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h
@@ -363,6 +363,9 @@ enum qlcnic_83xx_states {
 #define QLC_83XX_LINK_EEE(data)		((data) & BIT_13)
 #define QLC_83XX_DCBX(data)			(((data) >> 28) & 7)
 #define QLC_83XX_AUTONEG(data)			((data) & BIT_15)
+#define QLC_83XX_TX_PAUSE			0x10
+#define QLC_83XX_RX_PAUSE			0x20
+#define QLC_83XX_TX_RX_PAUSE			0x30
 #define QLC_83XX_CFG_STD_PAUSE			(1 << 5)
 #define QLC_83XX_CFG_STD_TX_PAUSE		(1 << 20)
 #define QLC_83XX_CFG_STD_RX_PAUSE		(2 << 20)
-- 
1.8.1.4

^ permalink raw reply related

* [PATCH net-next 02/10] qlcnic: Enhance ethtool to display ring indices and interrupt mask
From: Himanshu Madhani @ 2013-10-04 18:30 UTC (permalink / raw)
  To: davem; +Cc: netdev, Dept_NX_Linux_NIC_Driver, Pratik Pujar, himanshu.madhani
In-Reply-To: <cover.1380937706.git.himanshu.madhani@qlogic.com>

From: Pratik Pujar <pratik.pujar@qlogic.com>

o Updated ethtool -d <ethX> option to display ring indices for Transmit(Tx),
  Receive(Rx), and Status(St) rings.
o Updated ethtool -d <ethX> option to display ring interrupt mask for Transmit(Tx),
  and Status(St) rings.

Signed-off-by: Pratik Pujar <pratik.pujar@qlogic.com>
Signed-off-by: Himanshu Madhani <himanshu.madhani@qlogic.com>
---
 .../net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c    |  8 +--
 .../net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c    | 61 +++++++++++++++++-----
 2 files changed, 51 insertions(+), 18 deletions(-)

diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
index 66e94dc..c2df4ce 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
@@ -3267,12 +3267,12 @@ int qlcnic_83xx_reg_test(struct qlcnic_adapter *adapter)
 	return 0;
 }
 
-int qlcnic_83xx_get_regs_len(struct qlcnic_adapter *adapter)
+inline int qlcnic_83xx_get_regs_len(struct qlcnic_adapter *adapter)
 {
 	return (ARRAY_SIZE(qlcnic_83xx_ext_reg_tbl) *
-		sizeof(adapter->ahw->ext_reg_tbl)) +
-		(ARRAY_SIZE(qlcnic_83xx_reg_tbl) +
-		sizeof(adapter->ahw->reg_tbl));
+		sizeof(*adapter->ahw->ext_reg_tbl)) +
+		(ARRAY_SIZE(qlcnic_83xx_reg_tbl) *
+		sizeof(*adapter->ahw->reg_tbl));
 }
 
 int qlcnic_83xx_get_registers(struct qlcnic_adapter *adapter, u32 *regs_buff)
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c
index ebe4c86..01edc09 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c
@@ -187,8 +187,11 @@ static int qlcnic_dev_statistics_len(struct qlcnic_adapter *adapter)
 		return -1;
 }
 
-#define QLCNIC_RING_REGS_COUNT	20
-#define QLCNIC_RING_REGS_LEN	(QLCNIC_RING_REGS_COUNT * sizeof(u32))
+#define	QLCNIC_TX_RING_MARKER		0xAAAAAAAA
+#define	QLCNIC_RX_RING_MARKER		0XBBBBBBBB
+#define	QLCNIC_SDS_RING_MARKER		0XCCCCCCCC
+#define	QLCNIC_TX_INTR_NOT_CONFIGURED	0X78563412
+
 #define QLCNIC_MAX_EEPROM_LEN   1024
 
 static const u32 diag_registers[] = {
@@ -221,6 +224,14 @@ static const u32 ext_diag_registers[] = {
 #define QLCNIC_MGMT_API_VERSION	2
 #define QLCNIC_ETHTOOL_REGS_VER	3
 
+static inline int qlcnic_get_ring_regs_len(struct qlcnic_adapter *adapter)
+{
+	int ring_regs_cnt = (adapter->max_drv_tx_rings * 5) +
+			    (adapter->max_rds_rings * 2) +
+			    (adapter->max_sds_rings * 3) + 5;
+	return ring_regs_cnt * sizeof(u32);
+}
+
 static int qlcnic_get_regs_len(struct net_device *dev)
 {
 	struct qlcnic_adapter *adapter = netdev_priv(dev);
@@ -231,7 +242,9 @@ static int qlcnic_get_regs_len(struct net_device *dev)
 	else
 		len = sizeof(ext_diag_registers) + sizeof(diag_registers);
 
-	return QLCNIC_RING_REGS_LEN + len + QLCNIC_DEV_INFO_SIZE + 1;
+	len += ((QLCNIC_DEV_INFO_SIZE + 2) * sizeof(u32));
+	len += qlcnic_get_ring_regs_len(adapter);
+	return len;
 }
 
 static int qlcnic_get_eeprom_len(struct net_device *dev)
@@ -493,6 +506,8 @@ qlcnic_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p)
 	struct qlcnic_adapter *adapter = netdev_priv(dev);
 	struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx;
 	struct qlcnic_host_sds_ring *sds_ring;
+	struct qlcnic_host_rds_ring *rds_rings;
+	struct qlcnic_host_tx_ring *tx_ring;
 	u32 *regs_buff = p;
 	int ring, i = 0;
 
@@ -512,21 +527,39 @@ qlcnic_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p)
 	if (!test_bit(__QLCNIC_DEV_UP, &adapter->state))
 		return;
 
-	regs_buff[i++] = 0xFFEFCDAB; /* Marker btw regs and ring count*/
-
-	regs_buff[i++] = 1; /* No. of tx ring */
-	regs_buff[i++] = le32_to_cpu(*(adapter->tx_ring->hw_consumer));
-	regs_buff[i++] = readl(adapter->tx_ring->crb_cmd_producer);
-
-	regs_buff[i++] = 2; /* No. of rx ring */
-	regs_buff[i++] = readl(recv_ctx->rds_rings[0].crb_rcv_producer);
-	regs_buff[i++] = readl(recv_ctx->rds_rings[1].crb_rcv_producer);
-
-	regs_buff[i++] = adapter->max_sds_rings;
+	/* Marker btw regs and TX ring count */
+	regs_buff[i++] = QLCNIC_TX_RING_MARKER;
+
+	regs_buff[i++] = adapter->max_drv_tx_rings; /* No. of TX ring */
+	for (ring = 0; ring < adapter->max_drv_tx_rings; ring++) {
+		tx_ring = &adapter->tx_ring[ring];
+		regs_buff[i++] = le32_to_cpu(*(tx_ring->hw_consumer));
+		regs_buff[i++] = tx_ring->sw_consumer;
+		regs_buff[i++] = readl(tx_ring->crb_cmd_producer);
+		regs_buff[i++] = tx_ring->producer;
+		if (tx_ring->crb_intr_mask)
+			regs_buff[i++] = readl(tx_ring->crb_intr_mask);
+		else
+			regs_buff[i++] = QLCNIC_TX_INTR_NOT_CONFIGURED;
+	}
+	/* Marker btw TX ring regs and RDS ring count */
+	regs_buff[i++] = QLCNIC_RX_RING_MARKER;
+
+	regs_buff[i++] = adapter->max_rds_rings; /* No. of RX ring */
+	for (ring = 0; ring < adapter->max_rds_rings; ring++) {
+		rds_rings = &recv_ctx->rds_rings[ring];
+		regs_buff[i++] = readl(rds_rings->crb_rcv_producer);
+		regs_buff[i++] = rds_rings->producer;
+	}
+	/* Marker btw RDS ring regs and SDS ring count */
+	regs_buff[i++] = QLCNIC_SDS_RING_MARKER;
 
+	regs_buff[i++] = adapter->max_sds_rings; /* No. of SDS ring */
 	for (ring = 0; ring < adapter->max_sds_rings; ring++) {
 		sds_ring = &(recv_ctx->sds_rings[ring]);
 		regs_buff[i++] = readl(sds_ring->crb_sts_consumer);
+		regs_buff[i++] = sds_ring->consumer;
+		regs_buff[i++] = readl(sds_ring->crb_intr_mask);
 	}
 }
 
-- 
1.8.1.4

^ permalink raw reply related

* Re: [PATCH] ip: make -resolve addr to print names rather than addresses
From: Sami Kerola @ 2013-10-04 18:49 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: netdev
In-Reply-To: <20131004112530.1cab081c@nehalam.linuxnetplumber.net>

On 4 October 2013 19:25, Stephen Hemminger <stephen@networkplumber.org> wrote:
> On Mon, 30 Sep 2013 22:01:48 +0100 Sami Kerola <kerolasa@iki.fi> wrote:
>
>> As a system admin I occasionally want to be able to check that all
>> interfaces has a name in DNS or /etc/hosts file.
>
> This shouldn't be the default. It will change the result that user's expect now.

Doesn't the format_host() print exactly the same output as before,
unless -r is defined.
I intended resolution to happen when

ip -r addr

is used, but not when the -r is not specified. Or did I somehow messed
up the logic?

-- 
Sami Kerola
http://www.iki.fi/kerolasa/

^ permalink raw reply

* Re: [PATCH] ip: Showing peer of veth type dev in ip link (ip cmd side)
From: Masatake YAMATO @ 2013-10-04 18:42 UTC (permalink / raw)
  To: stephen; +Cc: netdev
In-Reply-To: <20131004112350.06818715@nehalam.linuxnetplumber.net>

Thank you those who review my patch and give me comments.
I'll revise the patch.

Forgive me sending the same patches twice accidentally.

Masatake YAMATO

> On Fri,  4 Oct 2013 13:06:05 +0900
> Masatake YAMATO <yamato@redhat.com> wrote:
> 
>> Implement print_opt method to veth to show peer ifindex
>> as ethtool -S does.
>> 
>> A patch submitted with following subject is needed:
>> 
>>    veth: Showing peer of veth type dev in ip link (kernel side)
>> 
>> Signed-off-by: Masatake YAMATO <yamato@redhat.com>
> 
> NAK, see kernel comments

^ permalink raw reply

* pull request: wireless-next 2013-10-04
From: John W. Linville @ 2013-10-04 18:16 UTC (permalink / raw)
  To: davem; +Cc: linux-wireless, netdev

[-- Attachment #1: Type: text/plain, Size: 27026 bytes --]

Dave,

Please pull this batch of patches intended for the 3.13 stream!

Regarding the Bluetooth bits, Gustavo says:

"The big work here is from Marcel and Johan. They did a lot of work
in the L2CAP, HCI and MGMT layers. The most important ones are the
addition of a new MGMT command to enable/disable LE advertisement
and the introduction of the HCI user channel to allow applications
to get directly and exclusive access to Bluetooth devices."

As to the ath10k bits, Kalle says:

"Bartosz dropped support for qca98xx hw1.0 hardware from ath10k, it's
just too much to support it. Michal added support for the new firmware
interface. Marek fixed WEP in AP and IBSS mode. Rest of the changes are
minor fixes or cleanups."

And also:

"Major changes are:

* throughput improvements including aligning the RX frames correctly and
  optimising HTT layer (Michal)

* remove qca98xx hw1.0 support (Bartosz)

* add support for firmware version 999.999.0.636 (Michal)

* firmware htt statistics support (Kalle)

* fix WEP in AP and IBSS mode (Marek)

* fix a mutex unlock balance in debugfs file (Shafi)

And of course there's a lot of smaller fixes and cleanup."

For the wl12xx bits, Luca says:

"Here are some patches intended for 3.13.  Eliad is upstreaming a bunch
of patches that have been pending in the internal tree.  Mostly bugfixes
and other small improvements."

Along with that...

Arend and friends bring us a batch of brcmfmac updates, Larry Finger
offers some rtlwifi refactoring, and Sujith sends the usual batch of
ath9k updates.  As usual, there are a number of other small updates
from a variety of players as well.

Please let me know if there are any problems!

Thanks,

John

---

The following changes since commit
96f817fedec48b59c9e8b22141cec4e56ad47913:

  tcp: shrink tcp6_timewait_sock by one cache line (2013-10-03
  17:43:39 -0400)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next.git
  for-davem

for you to fetch changes up to
c522ddf1aea71c2cb8ea4876697bc69bdfb5446f:

  Merge branch 'master' of
  git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next
  into for-davem (2013-10-04 13:26:50 -0400)

----------------------------------------------------------------

Albert Pool (1):
      ar5523: Add USB ID of D-Link WUA-2340 rev A1

Amitkumar Karwar (4):
      Bluetooth: btmrvl: add btmrvl_send_sync_cmd() function
      Bluetooth: btmrvl: get rid of struct btmrvl_cmd
      Bluetooth: btmrvl: add setup handler
      Bluetooth: btmrvl: add calibration data download support

Arend van Spriel (2):
      brcmfmac: fix sparse error 'bad constant expression'
      brcmfmac: rework rx path bus interface

Arik Nemtsov (3):
      wlcore: ROC on AP channel before auth reply
      wlcore: re-enable idle handling
      wlcore: always register dummy hardirq

Bartosz Markowski (5):
      ath10k: Remove qca98xx hw1.0 support
      ath10k: update supported FW build version
      ath10k: set the UART baud rate to 19200
      ath10k: remove obsolete INIT STATUS definitions
      ath10k: define ath10k_debug_start/_stop as static inline

Catalin Iacob (1):
      rtlwifi: remove duplicate declarations and macros in headers

Chris Metcalf (1):
      ath9k: mark wmi_event_swba as __packed

Dave Jones (1):
      ath10k: add missing braces to ath10k_pci_tx_pipe_cleanup

DoHyun Pyun (8):
      Bluetooth: Add the definition and structure for Set Reserved LT_ADDR
      Bluetooth: Add the definition and structure for Delete Reserved LT_ADDR
      Bluetooth: Add the definition and structure for Set CSB Data
      Bluetooth: Add the structure for Write Sync Train Parameters
      Bluetooth: Add the definition and structure for Set CSB
      Bluetooth: Add the definition for Start Synchronization Train
      Bluetooth: Add the definition and stcuture for Sync Train Complete
      Bluetooth: Add the definition for Slave Page Response Timeout

Eliad Peller (2):
      wlcore: remove unsupported channels
      wlcore: clarify and fix regulatory domain bit translation

Franky Lin (4):
      brcmfmac: sync firmware event list
      brcmfmac: add BCM4339 SDIO interface support
      brcmfmac: add valid core index check in related functions
      brcmfmac: reserve memory for bus layer in sk_buff::cb

Gabor Juhos (1):
      rt2x00: rt2800lib: fix band selection and LNA PE control for RT3593 PCIe cards

Gustavo Padovan (1):
      Merge git://git.kernel.org/.../bluetooth/bluetooth

Hante Meuleman (1):
      brcmfmac: Use fw filename and nvram based of devid for sdio.

Janusz Dziedzic (2):
      ath10k: setup peer UAPSD flag correctly
      ath10k: check allocation errors in CE

Jingoo Han (21):
      wireless: ath10k: remove unnecessary pci_set_drvdata()
      mwifiex: Remove casting the return value which is a void pointer
      wireless: ath5k: use dev_get_platdata()
      wireless: ath9k: use dev_get_platdata()
      wireless: brcmfmac: use dev_get_platdata()
      wireless: cw1200: use dev_get_platdata()
      wireless: libertas: use dev_get_platdata()
      wireless: wl1251: use dev_get_platdata()
      wireless: wlcore: use dev_get_platdata()
      wireless: wl12xx: use dev_get_platdata()
      wireless: rtlwifi: remove unnecessary pci_set_drvdata()
      wireless: iwlegacy: remove unnecessary pci_set_drvdata()
      wireless: adm8211: remove unnecessary pci_set_drvdata()
      wireless: airo: remove unnecessary pci_set_drvdata()
      wireless: ath10k: remove unnecessary pci_set_drvdata()
      wireless: wil6210: remove unnecessary pci_set_drvdata()
      wireless: ipw2x00: remove unnecessary pci_set_drvdata()
      wireless: mwl8k: remove unnecessary pci_set_drvdata()
      wireless: orinoco: remove unnecessary pci_set_drvdata()
      wireless: p54pci: remove unnecessary pci_set_drvdata()
      wireless: rtl818x: remove unnecessary pci_set_drvdata()

Johan Hedberg (23):
      Bluetooth: Remove unused event mask struct
      Bluetooth: Fix double error response for l2cap_create_chan_req
      Bluetooth: Fix L2CAP error return used for failed channel lookups
      Bluetooth: Fix L2CAP Disconnect response for unknown CID
      Bluetooth: Fix L2CAP command reject reason
      Bluetooth: Fix sending responses to identified L2CAP response packets
      Bluetooth: Fix responding to invalid L2CAP signaling commands
      Bluetooth: Fix waiting for clearing of BT_SK_SUSPEND flag
      Bluetooth: Add synchronization train parameters reading support
      Bluetooth: Add event mask page 2 setting support
      Bluetooth: Add clarifying comment to bt_sock_wait_state()
      Bluetooth: Clean up socket locking in l2cap_sock_recvmsg
      Bluetooth: Fix busy return for mgmt_set_powered in some cases
      Bluetooth: Move mgmt response convenience functions to a better location
      Bluetooth: Use async request for LE enable/disable
      Bluetooth: Add new mgmt setting for LE advertising
      Bluetooth: Add new mgmt_set_advertising command
      Bluetooth: Refactor hci_dev_open to a separate hci_dev_do_open function
      Bluetooth: Fix workqueue synchronization in hci_dev_open
      Bluetooth: Introduce a new HCI_BREDR_ENABLED flag
      Bluetooth: Add a new mgmt_set_bredr command
      Bluetooth: Fix REJECTED vs NOT_SUPPORTED mgmt responses
      Bluetooth: Fix advertising data flags with disabled BR/EDR

Johannes Berg (1):
      iwlwifi: pcie: fix merge damage

John W. Linville (5):
      Merge branch 'for-linville' of git://github.com/kvalo/ath
      Merge branch 'for-linville' of git://git.kernel.org/.../luca/wl12xx
      Merge tag 'for-linville-20131001' of git://github.com/kvalo/ath
      Merge branch 'for-upstream' of git://git.kernel.org/.../bluetooth/bluetooth-next
      Merge branch 'master' of git://git.kernel.org/.../linville/wireless-next into for-davem

Kalle Valo (22):
      ath10k: remove un ar_pci->cacheline_sz field
      ath10k: pci: make host_ce_config_wlan[] more readable
      ath10k: make target_ce_config_wlan more readable
      ath10k: remove void pointer from struct ath10k_pci_compl
      ath10k: convert ath10k_pci_reg_read/write32() to take struct ath10k
      ath10k: clean up ath10k_ce_completed_send_next_nolock()
      ath10k: convert ath10k_pci_wake() to return
      ath10k: simplify ath10k_ce_init() wake up handling
      ath10k: check chip id from the soc register during probe
      ath10k: add chip_id file to debugfs
      ath10k: add trace event ath10k_htt_stats
      ath10k: implement ath10k_debug_start/stop()
      ath10k: add htt_stats_enable debugfs file
      ath10k: add BMI log level
      ath10k: rename ATH10K_DBG_CORE to BOOT
      ath10k: cleanup debug messages in core.c
      ath10k: add boot debug messages to pci.c and ce.c
      ath10k: add boot debug messages to htc.c
      ath10k: add boot messages to htt.c
      ath10k: clean mac.c debug messages
      ath10k: print phymode as a string
      ath10k: delete struct ce_sendlist

Kevin Lo (1):
      rt2x00: Fix rf register for RT3070

Larry Finger (16):
      rtlwifi: rtl8192cu: Convert driver to use rtl_process_phyinfo()
      rtlwifi: rtl8192du: Fix smatch errors in /rtl8192de/dm.c
      rtlwifi: rtl8192de: Fix smatch warnings in rtl8192de/hw.c
      rtlwifi: rtl8192cu: Fix smatch warning in rtl8192cu/trx.c
      rtlwifi: rtl8192_common: Fix smatch errors and warnings in rtl8192c/dm_common.c
      rtlwifi: Fix smatch warning in pci.c
      rtlwifi: Fix smatch warnings in usb.c
      rtlwifi: rtl8188ee: Fix smatch warning in rtl8188ee/hw.c
      rtlwifi: Remove all remaining references to variable 'noise' in rtl_stats struct
      rtlwifi: Implement a common rtl_phy_scan_operation_backup() routine
      rtlwifi: rtl8192cu: Convert to use new rtl_phy_scan_operation_backup() routine
      rtlwifi: rtl8192ce: Convert driver to use new rtl_phy_scan_operation_backup() routine
      rtlwifi: rtl8192c: Remove rtl8192c_phy_scan_operation_backup()
      rtlwifi: rtl8192ce: Convert driver to use new rtl_phy_scan_operation_backup() routine
      rtlwifi: rtl8723ae: Convert driver to use new rtl_phy_scan_operation_backup() routine
      rtlwifi: rtl8188ee: Convert driver to use new rtl_phy_scan_operation_backup() routine

Marcel Holtmann (35):
      Bluetooth: Refactor raw socket filter into more readable code
      Bluetooth: Fix handling of getpeername() for HCI sockets
      Bluetooth: Fix handling of getsockname() for HCI sockets
      Bluetooth: Report error for HCI reset ioctl when device is down
      Bluetooth: Fix error handling for HCI socket options
      Bluetooth: Restrict ioctls to HCI raw channel sockets
      Bluetooth: Introduce user channel flag for HCI devices
      Bluetooth: Introduce new HCI socket channel for user operation
      Bluetooth: Use devname:vhci module alias for virtual HCI driver
      Bluetooth: Add support creating virtual AMP controllers
      Bluetooth: Disable upper layer connections when user channel is active
      Bluetooth: Use GFP_KERNEL when cloning SKB in a workqueue
      Bluetooth: Only schedule raw queue when user channel is active
      Bluetooth: Use only 2 bits for controller type information
      Bluetooth: Replace BDADDR_LOCAL with BDADDR_NONE
      Bluetooth: Provide high speed configuration option
      Bluetooth: Send new settings event when changing high speed option
      Bluetooth: Require CAP_NET_ADMIN for HCI User Channel operation
      Bluetooth: Enable -D__CHECK_ENDIAN__ for sparse by default
      Bluetooth: Restrict disabling of HS when controller is powered off
      Bluetooth: Add management command for setting static address
      Bluetooth: Increment management interface revision
      Bluetooth: Fix memory leak with L2CAP signal channels
      Bluetooth: Restrict SSP setting changes to BR/EDR enabled controllers
      Bluetooth: Allow setting static address even if LE is disabled
      Bluetooth: Restrict loading of link keys to BR/EDR capable controllers
      Bluetooth: Restrict loading of long term keys to LE capable controllers
      Bluetooth: Allow changing device class when BR/EDR is disabled
      Bluetooth: Fix switch statement order for L2CAP fixed channels
      Bluetooth: Don't copy L2CAP LE signalling to raw sockets
      Bluetooth: SMP packets are only valid on LE connections
      Bluetooth: L2CAP connectionless channels are only valid for BR/EDR
      Bluetooth: Drop packets on ATT fixed channel on BR/EDR
      Bluetooth: Check minimum length of SMP packets
      Bluetooth: Only one command per L2CAP LE signalling is supported

Marek Puzyniak (1):
      ath10k: fix WEP in AP and IBSS mode

Michal Kazior (36):
      ath10k: clean up monitor start code
      ath10k: use sizeof(*var) in kmalloc
      ath10k: clean up PCI completion states
      ath10k: print errcode when CE ring setup fails
      ath10k: fix HTT service setup
      ath10k: implement 802.3 SNAP rx decap type A-MSDU handling
      ath10k: plug possible memory leak in WMI
      ath10k: add support for firmware newer than 636
      ath10k: add support for HTT 3.0
      ath10k: use inline ce_state structure
      ath10k: remove ce_op_state
      ath10k: remove unused ce_attr parameters
      ath10k: rename hif_ce_pipe_info to ath10k_pci_pipe
      ath10k: rename ce_state to ath10k_ce_pipe
      ath10k: rename ce_ring_state to ath10k_ce_ring
      ath10k: prevent CE from looping indefinitely
      ath10k: simplify HTC credits calculation
      ath10k: add HTC TX credits replenishing notification
      ath10k: make WMI commands block by design
      ath10k: simplify HTC command submitting
      ath10k: improve beacon submission latency
      ath10k: remove wmi pending count limit
      ath10k: remove wmi event worker thread
      ath10k: fix tracing build for ath10k_wmi_cmd
      ath10k: fix num_sends_allowed replenishing
      ath10k: use num_pending_tx instead of msdu id bitmap
      ath10k: avoid needless memset on TX path
      ath10k: decouple HTT TX completions
      ath10k: cleanup HTT TX functions
      ath10k: use msdu headroom to store txfrag
      ath10k: report A-MSDU subframes individually
      ath10k: document decap modes
      ath10k: cleanup RX decap handling
      ath10k: fix Native Wifi decap mode RX
      ath10k: align RX frames properly
      ath10k: replenish HTT RX buffers in a tasklet

Mohammed Shafi Shajakhan (1):
      ath10k: Fix mutex unlock balance

Peter Senna Tschudin (2):
      Bluetooth: Fix assignment of 0/1 to bool variables
      wireless: rtlwifi: Replace variable with a break

Sachin Kamat (1):
      net: ath9k: Use NULL instead of false

Stanislaw Gruszka (2):
      rt2800: comment enable radio initialization sequence
      rt2800: add support for radio chip RF3070

Sujith Manoharan (21):
      ath10k: Calculate correct peer PHY mode for VHT
      ath9k: Update initvals for AR9565 1.0
      ath9k: Bypass EEPROM for diversity cap for AR9565
      ath9k: Fix antenna diversity init for AR9565
      ath9k: Use correct RX gain table for AR9565
      ath9k: Add support for AR9565 v1.0.1 LNA diversity
      ath9k: Enable antenna diversity for WB335
      ath9k: Identify CUS252 cards
      ath9k: Identify WB335 Antenna configuration
      ath9k: Fix regulatory compliance for AR9462/AR9565
      ath9k: Add and use initvals for channel 14
      ath9k: Update AR9485 1.1 initvals
      ath9k: Add DELL 1707 to supported card table
      ath9k: Fix calibration for AR9462
      ath9k: Fix issue with parsing malformed CFP IE
      ath9k: Handle abnormal NAV in AP mode
      ath9k: Use bitops for calibration flags
      ath9k: Fix PeakDetect calibration for AR9462
      ath9k: Fix NF calibration for single stream cards
      ath9k: Handle FATAL interrupts correctly
      ath9k: Remove incorrect diversity initialization

Victor Goldenshtein (4):
      wlcore: cleanup scan debug prints
      wlcore: fix unsafe dereference of the wlvif
      wl18xx: fix boot process in high temperature environment
      wl18xx: print new RDL versions during boot

Xose Vazquez Perez (1):
      wireless: rt2x00: rt2800usb: add new devices

Yair Shapira (2):
      wlcore: add new plt power-mode: CHIP_AWAKE
      wlcore: disable elp sleep while in plt mode

Zefir Kurtisi (1):
      ath9k: replace snprintf() with scnprintf()

 drivers/bluetooth/Makefile                         |   2 +
 drivers/bluetooth/btmrvl_drv.h                     |  12 +-
 drivers/bluetooth/btmrvl_main.c                    | 269 ++++++----
 drivers/bluetooth/btmrvl_sdio.c                    |  15 +-
 drivers/bluetooth/btmrvl_sdio.h                    |   2 +
 drivers/bluetooth/hci_vhci.c                       | 170 +++++--
 drivers/net/wireless/adm8211.c                     |   1 -
 drivers/net/wireless/airo.c                        |   1 -
 drivers/net/wireless/ath/ar5523/ar5523.c           |   1 +
 drivers/net/wireless/ath/ath10k/bmi.c              |  42 +-
 drivers/net/wireless/ath/ath10k/ce.c               | 382 ++++++--------
 drivers/net/wireless/ath/ath10k/ce.h               | 120 +----
 drivers/net/wireless/ath/ath10k/core.c             |  70 ++-
 drivers/net/wireless/ath/ath10k/core.h             |  35 +-
 drivers/net/wireless/ath/ath10k/debug.c            | 144 +++++-
 drivers/net/wireless/ath/ath10k/debug.h            |  14 +-
 drivers/net/wireless/ath/ath10k/htc.c              | 241 +++------
 drivers/net/wireless/ath/ath10k/htc.h              |   5 +-
 drivers/net/wireless/ath/ath10k/htt.c              |  19 +-
 drivers/net/wireless/ath/ath10k/htt.h              |  13 +-
 drivers/net/wireless/ath/ath10k/htt_rx.c           | 314 ++++++------
 drivers/net/wireless/ath/ath10k/htt_tx.c           | 285 ++++++-----
 drivers/net/wireless/ath/ath10k/hw.h               |  25 +-
 drivers/net/wireless/ath/ath10k/mac.c              | 244 +++++----
 drivers/net/wireless/ath/ath10k/pci.c              | 446 +++++++++-------
 drivers/net/wireless/ath/ath10k/pci.h              |  73 ++-
 drivers/net/wireless/ath/ath10k/rx_desc.h          |  24 +-
 drivers/net/wireless/ath/ath10k/trace.h            |  32 +-
 drivers/net/wireless/ath/ath10k/txrx.c             |  67 +--
 drivers/net/wireless/ath/ath10k/txrx.h             |   5 +-
 drivers/net/wireless/ath/ath10k/wmi.c              | 232 ++++-----
 drivers/net/wireless/ath/ath10k/wmi.h              |  71 ++-
 drivers/net/wireless/ath/ath5k/ahb.c               |  15 +-
 drivers/net/wireless/ath/ath9k/ahb.c               |   4 +-
 drivers/net/wireless/ath/ath9k/antenna.c           |  36 +-
 drivers/net/wireless/ath/ath9k/ar5008_phy.c        |   5 +-
 drivers/net/wireless/ath/ath9k/ar9002_calib.c      |   4 +-
 drivers/net/wireless/ath/ath9k/ar9002_phy.c        |   3 +-
 drivers/net/wireless/ath/ath9k/ar9003_calib.c      |  92 +++-
 drivers/net/wireless/ath/ath9k/ar9003_eeprom.c     |  34 +-
 drivers/net/wireless/ath/ath9k/ar9003_eeprom.h     |   2 +
 drivers/net/wireless/ath/ath9k/ar9003_hw.c         |   5 +
 drivers/net/wireless/ath/ath9k/ar9003_mci.c        |   6 +-
 drivers/net/wireless/ath/ath9k/ar9003_phy.c        |  32 +-
 drivers/net/wireless/ath/ath9k/ar9003_phy.h        |   4 +
 drivers/net/wireless/ath/ath9k/ar9003_rtt.c        |  58 ++-
 drivers/net/wireless/ath/ath9k/ar9485_initvals.h   | 218 ++++++--
 .../net/wireless/ath/ath9k/ar9565_1p0_initvals.h   |  24 +-
 drivers/net/wireless/ath/ath9k/ath9k.h             |  20 +-
 drivers/net/wireless/ath/ath9k/beacon.c            |   2 +
 drivers/net/wireless/ath/ath9k/calib.c             |  14 +-
 drivers/net/wireless/ath/ath9k/debug.c             | 446 ++++++++--------
 drivers/net/wireless/ath/ath9k/debug.h             |  12 +-
 drivers/net/wireless/ath/ath9k/dfs_debug.c         |  25 +-
 drivers/net/wireless/ath/ath9k/dfs_pri_detector.c  |   2 +-
 drivers/net/wireless/ath/ath9k/eeprom_4k.c         |  10 +-
 drivers/net/wireless/ath/ath9k/eeprom_9287.c       |   8 +-
 drivers/net/wireless/ath/ath9k/eeprom_def.c        |  12 +-
 drivers/net/wireless/ath/ath9k/gpio.c              |  22 +-
 drivers/net/wireless/ath/ath9k/htc_drv_debug.c     | 456 ++++++++---------
 drivers/net/wireless/ath/ath9k/hw.c                |  59 ++-
 drivers/net/wireless/ath/ath9k/hw.h                |  26 +-
 drivers/net/wireless/ath/ath9k/init.c              |  20 +
 drivers/net/wireless/ath/ath9k/link.c              |  12 +-
 drivers/net/wireless/ath/ath9k/main.c              |  10 +-
 drivers/net/wireless/ath/ath9k/pci.c               | 195 ++++++-
 drivers/net/wireless/ath/ath9k/rc.c                |  32 +-
 drivers/net/wireless/ath/ath9k/wmi.h               |   2 +-
 drivers/net/wireless/ath/ath9k/xmit.c              |   2 +-
 drivers/net/wireless/ath/wil6210/pcie_bus.c        |   1 -
 .../net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c |  13 +-
 drivers/net/wireless/brcm80211/brcmfmac/dhd.h      |   2 -
 drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h  |   2 +-
 .../net/wireless/brcm80211/brcmfmac/dhd_linux.c    |  38 +-
 drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | 234 +++++----
 drivers/net/wireless/brcm80211/brcmfmac/fweh.h     |   5 +-
 drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c |   2 +
 .../net/wireless/brcm80211/brcmfmac/sdio_chip.c    |  28 +
 .../net/wireless/brcm80211/brcmfmac/sdio_chip.h    |   8 +
 drivers/net/wireless/brcm80211/brcmfmac/usb.c      |   5 +-
 .../net/wireless/brcm80211/include/brcm_hw_ids.h   |   1 +
 drivers/net/wireless/cw1200/cw1200_spi.c           |   4 +-
 drivers/net/wireless/ipw2x00/ipw2200.c             |   2 -
 drivers/net/wireless/iwlegacy/3945-mac.c           |   2 -
 drivers/net/wireless/iwlegacy/4965-mac.c           |   2 -
 drivers/net/wireless/iwlwifi/pcie/trans.c          |   8 +-
 drivers/net/wireless/libertas/if_spi.c             |   2 +-
 drivers/net/wireless/mwifiex/pcie.c                |   6 +-
 drivers/net/wireless/mwl8k.c                       |   2 -
 drivers/net/wireless/orinoco/orinoco_nortel.c      |   2 -
 drivers/net/wireless/orinoco/orinoco_pci.c         |   2 -
 drivers/net/wireless/orinoco/orinoco_plx.c         |   2 -
 drivers/net/wireless/orinoco/orinoco_tmd.c         |   2 -
 drivers/net/wireless/p54/p54pci.c                  |   1 -
 drivers/net/wireless/rt2x00/rt2800.h               |   2 +
 drivers/net/wireless/rt2x00/rt2800lib.c            |  49 +-
 drivers/net/wireless/rt2x00/rt2800usb.c            |  17 +-
 drivers/net/wireless/rtl818x/rtl8180/dev.c         |   1 -
 drivers/net/wireless/rtlwifi/base.c                |  29 ++
 drivers/net/wireless/rtlwifi/base.h                |   2 +-
 drivers/net/wireless/rtlwifi/efuse.c               |  18 +-
 drivers/net/wireless/rtlwifi/pci.c                 |   4 -
 drivers/net/wireless/rtlwifi/rtl8188ee/hw.c        |   1 +
 drivers/net/wireless/rtlwifi/rtl8188ee/phy.c       |  28 -
 drivers/net/wireless/rtlwifi/rtl8188ee/phy.h       |   1 -
 drivers/net/wireless/rtlwifi/rtl8188ee/sw.c        |   3 +-
 drivers/net/wireless/rtlwifi/rtl8188ee/trx.c       |   1 -
 drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c  |  25 +-
 drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c |  30 --
 drivers/net/wireless/rtlwifi/rtl8192c/phy_common.h |   4 -
 drivers/net/wireless/rtlwifi/rtl8192ce/def.h       |   2 -
 drivers/net/wireless/rtlwifi/rtl8192ce/phy.h       |   4 -
 drivers/net/wireless/rtlwifi/rtl8192ce/reg.h       |  20 -
 drivers/net/wireless/rtlwifi/rtl8192ce/sw.c        |   3 +-
 drivers/net/wireless/rtlwifi/rtl8192ce/trx.c       |   1 -
 drivers/net/wireless/rtlwifi/rtl8192cu/mac.c       | 187 +------
 drivers/net/wireless/rtlwifi/rtl8192cu/sw.c        |   3 +-
 drivers/net/wireless/rtlwifi/rtl8192cu/trx.c       |   2 -
 drivers/net/wireless/rtlwifi/rtl8192de/dm.c        |   8 +-
 drivers/net/wireless/rtlwifi/rtl8192de/hw.c        |  18 -
 drivers/net/wireless/rtlwifi/rtl8192de/phy.c       |  28 -
 drivers/net/wireless/rtlwifi/rtl8192de/phy.h       |   4 -
 drivers/net/wireless/rtlwifi/rtl8192de/sw.c        |   3 +-
 drivers/net/wireless/rtlwifi/rtl8192de/trx.c       |   1 -
 drivers/net/wireless/rtlwifi/rtl8192se/reg.h       |   5 -
 drivers/net/wireless/rtlwifi/rtl8192se/trx.c       |   1 -
 drivers/net/wireless/rtlwifi/rtl8723ae/phy.c       |  29 --
 drivers/net/wireless/rtlwifi/rtl8723ae/phy.h       |   1 -
 drivers/net/wireless/rtlwifi/rtl8723ae/sw.c        |   3 +-
 drivers/net/wireless/rtlwifi/rtl8723ae/trx.c       |   1 -
 drivers/net/wireless/rtlwifi/usb.c                 |   6 +-
 drivers/net/wireless/rtlwifi/wifi.h                |   2 -
 drivers/net/wireless/ti/wl1251/spi.c               |   2 +-
 drivers/net/wireless/ti/wl12xx/main.c              |   2 +-
 drivers/net/wireless/ti/wl18xx/main.c              |  95 +++-
 drivers/net/wireless/ti/wl18xx/reg.h               |  33 +-
 drivers/net/wireless/ti/wlcore/cmd.c               |  58 ++-
 drivers/net/wireless/ti/wlcore/main.c              | 158 +++++-
 drivers/net/wireless/ti/wlcore/ps.c                |   4 +
 drivers/net/wireless/ti/wlcore/scan.c              |  27 +-
 drivers/net/wireless/ti/wlcore/spi.c               |   2 +-
 drivers/net/wireless/ti/wlcore/testmode.c          |  13 +-
 drivers/net/wireless/ti/wlcore/tx.c                |  27 +-
 drivers/net/wireless/ti/wlcore/tx.h                |   3 +
 drivers/net/wireless/ti/wlcore/wlcore.h            |   2 +
 drivers/net/wireless/ti/wlcore/wlcore_i.h          |  11 +
 include/net/bluetooth/bluetooth.h                  |   5 +-
 include/net/bluetooth/hci.h                        |  81 ++-
 include/net/bluetooth/hci_core.h                   |   2 +-
 include/net/bluetooth/l2cap.h                      |   1 +
 include/net/bluetooth/mgmt.h                       |  11 +
 net/bluetooth/Makefile                             |   2 +
 net/bluetooth/af_bluetooth.c                       |  41 ++
 net/bluetooth/hci_conn.c                           |   4 +
 net/bluetooth/hci_core.c                           | 189 +++++--
 net/bluetooth/hci_event.c                          |  17 +-
 net/bluetooth/hci_sock.c                           | 204 ++++++--
 net/bluetooth/l2cap_core.c                         | 162 +++---
 net/bluetooth/l2cap_sock.c                         |  20 +-
 net/bluetooth/mgmt.c                               | 562 ++++++++++++++++-----
 net/bluetooth/rfcomm/sock.c                        |   7 +-
 net/bluetooth/smp.c                                |  15 +-
 162 files changed, 4802 insertions(+), 3186 deletions(-)
-- 
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: 836 bytes --]

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox