Netdev List
 help / color / mirror / Atom feed
* [PATCH 2/4 net-next] tg3: Add NVRAM support for 5762
From: Michael Chan @ 2013-01-06 22:51 UTC (permalink / raw)
  To: davem; +Cc: netdev, nsujir
In-Reply-To: <1357512670-17636-1-git-send-email-mchan@broadcom.com>

Detect NVRAM types for 5762 and read OTP firmware version.

Signed-off-by: Michael Chan <mchan@broadcom.com>
---
 drivers/net/ethernet/broadcom/tg3.c |   96 ++++++++++++++++++++++++++++++++++-
 drivers/net/ethernet/broadcom/tg3.h |   15 ++++++
 2 files changed, 110 insertions(+), 1 deletions(-)

diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c
index 01e3201..6eab7d7 100644
--- a/drivers/net/ethernet/broadcom/tg3.c
+++ b/drivers/net/ethernet/broadcom/tg3.c
@@ -330,6 +330,9 @@ static DEFINE_PCI_DEVICE_TABLE(tg3_pci_tbl) = {
 	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5719)},
 	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5720)},
 	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57762)},
+	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5762)},
+	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5725)},
+	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5727)},
 	{PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_9DXX)},
 	{PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_9MXX)},
 	{PCI_DEVICE(PCI_VENDOR_ID_ALTIMA, PCI_DEVICE_ID_ALTIMA_AC1000)},
@@ -13714,6 +13717,20 @@ static void tg3_get_5720_nvram_info(struct tg3 *tp)
 	nvcfg1 = tr32(NVRAM_CFG1);
 	nvmpinstrp = nvcfg1 & NVRAM_CFG1_5752VENDOR_MASK;
 
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5762) {
+		if (!(nvcfg1 & NVRAM_CFG1_5762VENDOR_MASK)) {
+			tg3_flag_set(tp, NO_NVRAM);
+			return;
+		}
+
+		switch (nvmpinstrp) {
+		case FLASH_5762_EEPROM_HD:
+			nvmpinstrp = FLASH_5720_EEPROM_HD;
+		case FLASH_5762_EEPROM_LD:
+			nvmpinstrp = FLASH_5720_EEPROM_LD;
+		}
+	}
+
 	switch (nvmpinstrp) {
 	case FLASH_5720_EEPROM_HD:
 	case FLASH_5720_EEPROM_LD:
@@ -13817,6 +13834,17 @@ static void tg3_get_5720_nvram_info(struct tg3 *tp)
 	tg3_nvram_get_pagesize(tp, nvcfg1);
 	if (tp->nvram_pagesize != 264 && tp->nvram_pagesize != 528)
 		tg3_flag_set(tp, NO_NVRAM_ADDR_TRANS);
+
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5762) {
+		u32 val;
+
+		if (tg3_nvram_read(tp, 0, &val))
+			return;
+
+		if (val != TG3_EEPROM_MAGIC &&
+		    (val & TG3_EEPROM_MAGIC_FW_MSK) != TG3_EEPROM_MAGIC_FW)
+			tg3_flag_set(tp, NO_NVRAM);
+	}
 }
 
 /* Chips other than 5700/5701 use the NVRAM for fetching info. */
@@ -13866,7 +13894,8 @@ static void tg3_nvram_init(struct tg3 *tp)
 		else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
 			 GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719)
 			tg3_get_5717_nvram_info(tp);
-		else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720)
+		else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720 ||
+			 GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5762)
 			tg3_get_5720_nvram_info(tp);
 		else
 			tg3_get_nvram_info(tp);
@@ -14168,6 +14197,39 @@ done:
 		device_set_wakeup_capable(&tp->pdev->dev, false);
 }
 
+static int tg3_ape_otp_read(struct tg3 *tp, u32 offset, u32 *val)
+{
+	int i, err;
+	u32 val2, off = offset * 8;
+
+	err = tg3_nvram_lock(tp);
+	if (err)
+		return err;
+
+	tg3_ape_write32(tp, TG3_APE_OTP_ADDR, off | APE_OTP_ADDR_CPU_ENABLE);
+	tg3_ape_write32(tp, TG3_APE_OTP_CTRL, APE_OTP_CTRL_PROG_EN |
+			APE_OTP_CTRL_CMD_RD | APE_OTP_CTRL_START);
+	tg3_ape_read32(tp, TG3_APE_OTP_CTRL);
+	udelay(10);
+
+	for (i = 0; i < 100; i++) {
+		val2 = tg3_ape_read32(tp, TG3_APE_OTP_STATUS);
+		if (val2 & APE_OTP_STATUS_CMD_DONE) {
+			*val = tg3_ape_read32(tp, TG3_APE_OTP_RD_DATA);
+			break;
+		}
+		udelay(10);
+	}
+
+	tg3_ape_write32(tp, TG3_APE_OTP_CTRL, 0);
+
+	tg3_nvram_unlock(tp);
+	if (val2 & APE_OTP_STATUS_CMD_DONE)
+		return 0;
+
+	return -EBUSY;
+}
+
 static int tg3_issue_otp_command(struct tg3 *tp, u32 cmd)
 {
 	int i;
@@ -14708,6 +14770,8 @@ static void tg3_read_dash_ver(struct tg3 *tp)
 
 	if (tg3_flag(tp, APE_HAS_NCSI))
 		fwtype = "NCSI";
+	else if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_5725)
+		fwtype = "SMASH";
 	else
 		fwtype = "DASH";
 
@@ -14721,6 +14785,31 @@ static void tg3_read_dash_ver(struct tg3 *tp)
 		 (apedata & APE_FW_VERSION_BLDMSK));
 }
 
+static void tg3_read_otp_ver(struct tg3 *tp)
+{
+	u32 val, val2;
+
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5762)
+		return;
+
+	if (!tg3_ape_otp_read(tp, OTP_ADDRESS_MAGIC0, &val) &&
+	    !tg3_ape_otp_read(tp, OTP_ADDRESS_MAGIC0 + 4, &val2) &&
+	    TG3_OTP_MAGIC0_VALID(val)) {
+		u64 val64 = (u64) val << 32 | val2;
+		u32 ver = 0;
+		int i, vlen;
+
+		for (i = 0; i < 7; i++) {
+			if ((val64 & 0xff) == 0)
+				break;
+			ver = val64 & 0xff;
+			val64 >>= 8;
+		}
+		vlen = strlen(tp->fw_ver);
+		snprintf(&tp->fw_ver[vlen], TG3_VER_SIZE - vlen, " .%02d", ver);
+	}
+}
+
 static void tg3_read_fw_ver(struct tg3 *tp)
 {
 	u32 val;
@@ -14731,6 +14820,7 @@ static void tg3_read_fw_ver(struct tg3 *tp)
 
 	if (tg3_flag(tp, NO_NVRAM)) {
 		strcat(tp->fw_ver, "sb");
+		tg3_read_otp_ver(tp);
 		return;
 	}
 
@@ -15428,6 +15518,10 @@ static int tg3_get_invariants(struct tg3 *tp, const struct pci_device_id *ent)
 					      GRC_LCLCTRL_GPIO_OUTPUT0;
 	}
 
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5762)
+		tp->grc_local_ctrl |=
+			tr32(GRC_LOCAL_CTRL) & GRC_LCLCTRL_GPIO_UART_SEL;
+
 	/* Switch out of Vaux if it is a NIC */
 	tg3_pwrsrc_switch_to_vmain(tp);
 
diff --git a/drivers/net/ethernet/broadcom/tg3.h b/drivers/net/ethernet/broadcom/tg3.h
index 46d43f7..39afc0e 100644
--- a/drivers/net/ethernet/broadcom/tg3.h
+++ b/drivers/net/ethernet/broadcom/tg3.h
@@ -1859,6 +1859,7 @@
 #define  FLASH_VENDOR_SST_SMALL		 0x00000001
 #define  FLASH_VENDOR_SST_LARGE		 0x02000001
 #define  NVRAM_CFG1_5752VENDOR_MASK	 0x03c00003
+#define  NVRAM_CFG1_5762VENDOR_MASK	 0x03e00003
 #define  FLASH_5752VENDOR_ATMEL_EEPROM_64KHZ	 0x00000000
 #define  FLASH_5752VENDOR_ATMEL_EEPROM_376KHZ	 0x02000000
 #define  FLASH_5752VENDOR_ATMEL_FLASH_BUFFERED	 0x02000003
@@ -2376,6 +2377,20 @@
 #define  APE_LOCK_REQ_DRIVER		 0x00001000
 #define TG3_APE_LOCK_GRANT		0x004c
 #define  APE_LOCK_GRANT_DRIVER		 0x00001000
+#define TG3_APE_OTP_CTRL		0x00e8
+#define  APE_OTP_CTRL_PROG_EN		 0x200000
+#define  APE_OTP_CTRL_CMD_RD		 0x000000
+#define  APE_OTP_CTRL_START		 0x000001
+#define TG3_APE_OTP_STATUS		0x00ec
+#define  APE_OTP_STATUS_CMD_DONE	 0x000001
+#define TG3_APE_OTP_ADDR		0x00f0
+#define  APE_OTP_ADDR_CPU_ENABLE	 0x80000000
+#define TG3_APE_OTP_RD_DATA		0x00f8
+
+#define OTP_ADDRESS_MAGIC0		 0x00000050
+#define TG3_OTP_MAGIC0_VALID(val)		\
+	((((val) & 0xf0000000) == 0xa0000000) ||\
+	 (((val) & 0x0f000000) == 0x0a000000))
 
 /* APE shared memory.  Accessible through BAR1 */
 #define TG3_APE_SHMEM_BASE		0x4000
-- 
1.7.1

^ permalink raw reply related

* [PATCH 1/4 net-next] tg3: Add support for new 5762 ASIC
From: Michael Chan @ 2013-01-06 22:51 UTC (permalink / raw)
  To: davem; +Cc: netdev, nsujir

Add basic support for 5762 which is a 57765_PLUS class device.

Signed-off-by: Michael Chan <mchan@broadcom.com>
---
 drivers/net/ethernet/broadcom/tg3.c |   91 +++++++++++++++++++++++++---------
 drivers/net/ethernet/broadcom/tg3.h |   15 +++++-
 2 files changed, 81 insertions(+), 25 deletions(-)

diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c
index 78ea90c..01e3201 100644
--- a/drivers/net/ethernet/broadcom/tg3.c
+++ b/drivers/net/ethernet/broadcom/tg3.c
@@ -2632,6 +2632,9 @@ out:
 		tg3_writephy(tp, MII_TG3_FET_PTEST, 0x12);
 	}
 
+	if (tp->pci_chip_rev_id == CHIPREV_ID_5762_A0)
+		tg3_phydsp_write(tp, 0xffb, 0x4000);
+
 	tg3_phy_toggle_automdix(tp, 1);
 	tg3_phy_set_wirespeed(tp);
 	return 0;
@@ -4037,6 +4040,7 @@ static int tg3_phy_autoneg_cfg(struct tg3 *tp, u32 advertise, u32 flowctrl)
 			tg3_phydsp_write(tp, MII_TG3_DSP_TAP26, val);
 			/* Fall through */
 		case ASIC_REV_5720:
+		case ASIC_REV_5762:
 			if (!tg3_phydsp_read(tp, MII_TG3_DSP_CH34TP2, &val))
 				tg3_phydsp_write(tp, MII_TG3_DSP_CH34TP2, val |
 						 MII_TG3_DSP_CH34TP2_HIBW01);
@@ -5484,7 +5488,8 @@ static int tg3_setup_phy(struct tg3 *tp, int force_reset)
 
 	val = (2 << TX_LENGTHS_IPG_CRS_SHIFT) |
 	      (6 << TX_LENGTHS_IPG_SHIFT);
-	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720)
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720 ||
+	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5762)
 		val |= tr32(MAC_TX_LENGTHS) &
 		       (TX_LENGTHS_JMB_FRM_LEN_MSK |
 			TX_LENGTHS_CNT_DWN_VAL_MSK);
@@ -8672,7 +8677,8 @@ static void tg3_rings_reset(struct tg3 *tp)
 		limit = NIC_SRAM_SEND_RCB + TG3_BDINFO_SIZE * 16;
 	else if (tg3_flag(tp, 5717_PLUS))
 		limit = NIC_SRAM_SEND_RCB + TG3_BDINFO_SIZE * 4;
-	else if (tg3_flag(tp, 57765_CLASS))
+	else if (tg3_flag(tp, 57765_CLASS) ||
+		 GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5762)
 		limit = NIC_SRAM_SEND_RCB + TG3_BDINFO_SIZE * 2;
 	else
 		limit = NIC_SRAM_SEND_RCB + TG3_BDINFO_SIZE;
@@ -8689,6 +8695,7 @@ static void tg3_rings_reset(struct tg3 *tp)
 	else if (!tg3_flag(tp, 5705_PLUS))
 		limit = NIC_SRAM_RCV_RET_RCB + TG3_BDINFO_SIZE * 16;
 	else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 ||
+		 GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5762 ||
 		 tg3_flag(tp, 57765_CLASS))
 		limit = NIC_SRAM_RCV_RET_RCB + TG3_BDINFO_SIZE * 4;
 	else
@@ -8979,9 +8986,12 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
 
 	/* Enable MAC control of LPI */
 	if (tp->phy_flags & TG3_PHYFLG_EEE_CAP) {
-		tw32_f(TG3_CPMU_EEE_LNKIDL_CTRL,
-		       TG3_CPMU_EEE_LNKIDL_PCIE_NL0 |
-		       TG3_CPMU_EEE_LNKIDL_UART_IDL);
+		val = TG3_CPMU_EEE_LNKIDL_PCIE_NL0 |
+		      TG3_CPMU_EEE_LNKIDL_UART_IDL;
+		if (tp->pci_chip_rev_id == CHIPREV_ID_57765_A0)
+			val |= TG3_CPMU_EEE_LNKIDL_APE_TX_MT;
+
+		tw32_f(TG3_CPMU_EEE_LNKIDL_CTRL, val);
 
 		tw32_f(TG3_CPMU_EEE_CTRL,
 		       TG3_CPMU_EEE_CTRL_EXIT_20_1_US);
@@ -9156,7 +9166,8 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
 		if (tp->pci_chip_rev_id == CHIPREV_ID_57765_A0)
 			val &= ~DMA_RWCTRL_CRDRDR_RDMA_MRRS_MSK;
 		if (!tg3_flag(tp, 57765_CLASS) &&
-		    GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5717)
+		    GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5717 &&
+		    GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5762)
 			val |= DMA_RWCTRL_TAGGED_STAT_WA;
 		tw32(TG3PCI_DMA_RW_CTRL, val | tp->dma_rwctrl);
 	} else if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5784 &&
@@ -9308,7 +9319,8 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
 			tw32(RCVDBDI_JUMBO_BD + TG3_BDINFO_MAXLEN_FLAGS,
 			     val | BDINFO_FLAGS_USE_EXT_RECV);
 			if (!tg3_flag(tp, USE_JUMBO_BDFLAG) ||
-			    tg3_flag(tp, 57765_CLASS))
+			    tg3_flag(tp, 57765_CLASS) ||
+			    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5762)
 				tw32(RCVDBDI_JUMBO_BD + TG3_BDINFO_NIC_ADDR,
 				     NIC_SRAM_RX_JUMBO_BUFFER_DESC);
 		} else {
@@ -9350,7 +9362,8 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
 	      (6 << TX_LENGTHS_IPG_SHIFT) |
 	      (32 << TX_LENGTHS_SLOT_TIME_SHIFT);
 
-	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720)
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720 ||
+	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5762)
 		val |= tr32(MAC_TX_LENGTHS) &
 		       (TX_LENGTHS_JMB_FRM_LEN_MSK |
 			TX_LENGTHS_CNT_DWN_VAL_MSK);
@@ -9404,7 +9417,8 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
 	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780)
 		rdmac_mode |= RDMAC_MODE_IPV6_LSO_EN;
 
-	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720)
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720 ||
+	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5762)
 		rdmac_mode |= tr32(RDMAC_MODE) & RDMAC_MODE_H2BNC_VLAN_DET;
 
 	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 ||
@@ -9412,8 +9426,16 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
 	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785 ||
 	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780 ||
 	    tg3_flag(tp, 57765_PLUS)) {
-		val = tr32(TG3_RDMA_RSRVCTRL_REG);
-		if (tp->pci_chip_rev_id == CHIPREV_ID_5719_A0) {
+		u32 tgtreg;
+
+		if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5762)
+			tgtreg = TG3_RDMA_RSRVCTRL_REG2;
+		else
+			tgtreg = TG3_RDMA_RSRVCTRL_REG;
+
+		val = tr32(tgtreg);
+		if (tp->pci_chip_rev_id == CHIPREV_ID_5719_A0 ||
+		    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5762) {
 			val &= ~(TG3_RDMA_RSRVCTRL_TXMRGN_MASK |
 				 TG3_RDMA_RSRVCTRL_FIFO_LWM_MASK |
 				 TG3_RDMA_RSRVCTRL_FIFO_HWM_MASK);
@@ -9421,14 +9443,21 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
 			       TG3_RDMA_RSRVCTRL_FIFO_LWM_1_5K |
 			       TG3_RDMA_RSRVCTRL_FIFO_HWM_1_5K;
 		}
-		tw32(TG3_RDMA_RSRVCTRL_REG,
-		     val | TG3_RDMA_RSRVCTRL_FIFO_OFLW_FIX);
+		tw32(tgtreg, val | TG3_RDMA_RSRVCTRL_FIFO_OFLW_FIX);
 	}
 
 	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 ||
-	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720) {
-		val = tr32(TG3_LSO_RD_DMA_CRPTEN_CTRL);
-		tw32(TG3_LSO_RD_DMA_CRPTEN_CTRL, val |
+	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720 ||
+	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5762) {
+		u32 tgtreg;
+
+		if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5762)
+			tgtreg = TG3_LSO_RD_DMA_CRPTEN_CTRL2;
+		else
+			tgtreg = TG3_LSO_RD_DMA_CRPTEN_CTRL;
+
+		val = tr32(tgtreg);
+		tw32(tgtreg, val |
 		     TG3_LSO_RD_DMA_CRPTEN_CTRL_BLEN_BD_4K |
 		     TG3_LSO_RD_DMA_CRPTEN_CTRL_BLEN_LSO_4K);
 	}
@@ -9661,7 +9690,8 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
 	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)
 		tp->tx_mode |= TX_MODE_MBUF_LOCKUP_FIX;
 
-	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720) {
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720 ||
+	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5762) {
 		val = TX_MODE_JMB_FRM_LEN | TX_MODE_CNT_DN_MODE;
 		tp->tx_mode &= ~val;
 		tp->tx_mode |= tr32(MAC_TX_MODE) & val;
@@ -12342,7 +12372,8 @@ static int tg3_test_memory(struct tg3 *tp)
 
 	if (tg3_flag(tp, 5717_PLUS))
 		mem_tbl = mem_tbl_5717;
-	else if (tg3_flag(tp, 57765_CLASS))
+	else if (tg3_flag(tp, 57765_CLASS) ||
+		 GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5762)
 		mem_tbl = mem_tbl_57765;
 	else if (tg3_flag(tp, 5755_PLUS))
 		mem_tbl = mem_tbl_5755;
@@ -14296,6 +14327,7 @@ static int tg3_phy_probe(struct tg3 *tp)
 	if (!(tp->phy_flags & TG3_PHYFLG_ANY_SERDES) &&
 	    (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 ||
 	     GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720 ||
+	     GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5762 ||
 	     (tp->pdev->device == TG3PCI_DEVICE_TIGON3_5718 &&
 	      tp->pci_chip_rev_id != CHIPREV_ID_5717_A0) ||
 	     (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765 &&
@@ -14785,7 +14817,10 @@ static void tg3_detect_asic_rev(struct tg3 *tp, u32 misc_ctrl_reg)
 		    tp->pdev->device == TG3PCI_DEVICE_TIGON3_5717_C ||
 		    tp->pdev->device == TG3PCI_DEVICE_TIGON3_5718 ||
 		    tp->pdev->device == TG3PCI_DEVICE_TIGON3_5719 ||
-		    tp->pdev->device == TG3PCI_DEVICE_TIGON3_5720)
+		    tp->pdev->device == TG3PCI_DEVICE_TIGON3_5720 ||
+		    tp->pdev->device == TG3PCI_DEVICE_TIGON3_5762 ||
+		    tp->pdev->device == TG3PCI_DEVICE_TIGON3_5725 ||
+		    tp->pdev->device == TG3PCI_DEVICE_TIGON3_5727)
 			reg = TG3PCI_GEN2_PRODID_ASICREV;
 		else if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_57781 ||
 			 tp->pdev->device == TG3PCI_DEVICE_TIGON3_57785 ||
@@ -14822,7 +14857,8 @@ static void tg3_detect_asic_rev(struct tg3 *tp, u32 misc_ctrl_reg)
 	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57766)
 		tg3_flag_set(tp, 57765_CLASS);
 
-	if (tg3_flag(tp, 57765_CLASS) || tg3_flag(tp, 5717_PLUS))
+	if (tg3_flag(tp, 57765_CLASS) || tg3_flag(tp, 5717_PLUS) ||
+	     GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5762)
 		tg3_flag_set(tp, 57765_PLUS);
 
 	/* Intentionally exclude ASIC_REV_5906 */
@@ -15113,7 +15149,8 @@ static int tg3_get_invariants(struct tg3 *tp, const struct pci_device_id *ent)
 
 	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
 	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 ||
-	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720)
+	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720 ||
+	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5762)
 		tg3_flag_set(tp, LRG_PROD_RING_CAP);
 
 	if (tg3_flag(tp, 57765_PLUS) &&
@@ -15481,7 +15518,8 @@ static int tg3_get_invariants(struct tg3 *tp, const struct pci_device_id *ent)
 
 	/* Initialize data/descriptor byte/word swapping. */
 	val = tr32(GRC_MODE);
-	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720)
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720 ||
+	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5762)
 		val &= (GRC_MODE_BYTE_SWAP_B2HRX_DATA |
 			GRC_MODE_WORD_SWAP_B2HRX_DATA |
 			GRC_MODE_B2HRX_ENABLE |
@@ -16238,6 +16276,7 @@ static char *tg3_phy_string(struct tg3 *tp)
 	case TG3_PHY_ID_BCM57765:	return "57765";
 	case TG3_PHY_ID_BCM5719C:	return "5719C";
 	case TG3_PHY_ID_BCM5720C:	return "5720C";
+	case TG3_PHY_ID_BCM5762:	return "5762C";
 	case TG3_PHY_ID_BCM8002:	return "8002/serdes";
 	case 0:			return "serdes";
 	default:		return "unknown";
@@ -16413,7 +16452,10 @@ static int tg3_init_one(struct pci_dev *pdev,
 	    tp->pdev->device == TG3PCI_DEVICE_TIGON3_5717_C ||
 	    tp->pdev->device == TG3PCI_DEVICE_TIGON3_5718 ||
 	    tp->pdev->device == TG3PCI_DEVICE_TIGON3_5719 ||
-	    tp->pdev->device == TG3PCI_DEVICE_TIGON3_5720) {
+	    tp->pdev->device == TG3PCI_DEVICE_TIGON3_5720 ||
+	    tp->pdev->device == TG3PCI_DEVICE_TIGON3_5762 ||
+	    tp->pdev->device == TG3PCI_DEVICE_TIGON3_5725 ||
+	    tp->pdev->device == TG3PCI_DEVICE_TIGON3_5727) {
 		tg3_flag_set(tp, ENABLE_APE);
 		tp->aperegs = pci_ioremap_bar(pdev, BAR_2);
 		if (!tp->aperegs) {
@@ -16608,7 +16650,8 @@ static int tg3_init_one(struct pci_dev *pdev,
 	pci_set_drvdata(pdev, dev);
 
 	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 ||
-	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720)
+	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720 ||
+	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5762)
 		tg3_flag_set(tp, PTP_CAPABLE);
 
 	if (tg3_flag(tp, 5717_PLUS)) {
diff --git a/drivers/net/ethernet/broadcom/tg3.h b/drivers/net/ethernet/broadcom/tg3.h
index 247d954..46d43f7 100644
--- a/drivers/net/ethernet/broadcom/tg3.h
+++ b/drivers/net/ethernet/broadcom/tg3.h
@@ -65,6 +65,9 @@
 #define  TG3PCI_DEVICE_TIGON3_57766	 0x1686
 #define  TG3PCI_DEVICE_TIGON3_57786	 0x16b3
 #define  TG3PCI_DEVICE_TIGON3_57782	 0x16b7
+#define  TG3PCI_DEVICE_TIGON3_5762	 0x1687
+#define  TG3PCI_DEVICE_TIGON3_5725	 0x1643
+#define  TG3PCI_DEVICE_TIGON3_5727	 0x16f3
 /* 0x04 --> 0x2c unused */
 #define TG3PCI_SUBVENDOR_ID_BROADCOM		PCI_VENDOR_ID_BROADCOM
 #define TG3PCI_SUBDEVICE_ID_BROADCOM_95700A6	0x1644
@@ -159,6 +162,7 @@
 #define  CHIPREV_ID_57765_A0		 0x57785000
 #define  CHIPREV_ID_5719_A0		 0x05719000
 #define  CHIPREV_ID_5720_A0		 0x05720000
+#define  CHIPREV_ID_5762_A0		 0x05762000
 #define  GET_ASIC_REV(CHIP_REV_ID)	((CHIP_REV_ID) >> 12)
 #define   ASIC_REV_5700			 0x07
 #define   ASIC_REV_5701			 0x00
@@ -182,6 +186,7 @@
 #define   ASIC_REV_5719			 0x5719
 #define   ASIC_REV_5720			 0x5720
 #define   ASIC_REV_57766		 0x57766
+#define   ASIC_REV_5762			 0x5762
 #define  GET_CHIP_REV(CHIP_REV_ID)	((CHIP_REV_ID) >> 8)
 #define   CHIPREV_5700_AX		 0x70
 #define   CHIPREV_5700_BX		 0x71
@@ -1178,6 +1183,7 @@
 #define TG3_CPMU_EEE_LNKIDL_CTRL	0x000036bc
 #define  TG3_CPMU_EEE_LNKIDL_PCIE_NL0	 0x01000000
 #define  TG3_CPMU_EEE_LNKIDL_UART_IDL	 0x00000004
+#define  TG3_CPMU_EEE_LNKIDL_APE_TX_MT	 0x00000002
 /* 0x36c0 --> 0x36d0 unused */
 
 #define TG3_CPMU_EEE_CTRL		0x000036d0
@@ -1400,7 +1406,10 @@
 #define  RDMAC_STATUS_FIFOURUN		 0x00000080
 #define  RDMAC_STATUS_FIFOOREAD		 0x00000100
 #define  RDMAC_STATUS_LNGREAD		 0x00000200
-/* 0x4808 --> 0x4900 unused */
+/* 0x4808 --> 0x4890 unused */
+
+#define TG3_RDMA_RSRVCTRL_REG2		0x00004890
+#define TG3_LSO_RD_DMA_CRPTEN_CTRL2	0x000048a0
 
 #define TG3_RDMA_RSRVCTRL_REG		0x00004900
 #define TG3_RDMA_RSRVCTRL_FIFO_OFLW_FIX	 0x00000004
@@ -1910,6 +1919,8 @@
 #define  FLASH_5717VENDOR_ST_45USPT	 0x03400001
 #define  FLASH_5720_EEPROM_HD		 0x00000001
 #define  FLASH_5720_EEPROM_LD		 0x00000003
+#define  FLASH_5762_EEPROM_HD		 0x02000001
+#define  FLASH_5762_EEPROM_LD		 0x02000003
 #define  FLASH_5720VENDOR_M_ATMEL_DB011D 0x01000000
 #define  FLASH_5720VENDOR_M_ATMEL_DB021D 0x01000002
 #define  FLASH_5720VENDOR_M_ATMEL_DB041D 0x01000001
@@ -3206,6 +3217,7 @@ struct tg3 {
 #define TG3_PHY_ID_BCM57765		0x5c0d8a40
 #define TG3_PHY_ID_BCM5719C		0x5c0d8a20
 #define TG3_PHY_ID_BCM5720C		0x5c0d8b60
+#define TG3_PHY_ID_BCM5762		0x85803780
 #define TG3_PHY_ID_BCM5906		0xdc00ac40
 #define TG3_PHY_ID_BCM8002		0x60010140
 #define TG3_PHY_ID_INVALID		0xffffffff
@@ -3230,6 +3242,7 @@ struct tg3 {
 	 (X) == TG3_PHY_ID_BCM5906 || (X) == TG3_PHY_ID_BCM5761 || \
 	 (X) == TG3_PHY_ID_BCM5718C || (X) == TG3_PHY_ID_BCM5718S || \
 	 (X) == TG3_PHY_ID_BCM57765 || (X) == TG3_PHY_ID_BCM5719C || \
+	 (X) == TG3_PHY_ID_BCM5720C || (X) == TG3_PHY_ID_BCM5762 || \
 	 (X) == TG3_PHY_ID_BCM8002)
 
 	u32				phy_flags;
-- 
1.7.1

^ permalink raw reply related

* [patch net] ethtool: set addr_assign_type to NET_ADDR_SET when addr is passed on create
From: Jiri Pirko @ 2013-01-06 22:38 UTC (permalink / raw)
  To: netdev; +Cc: davem, bhutchings, shemminger, sassmann

In case user passed address via netlink during create, NET_ADDR_PERM was set.
That is not correct so fix this by setting NET_ADDR_SET.

Signed-off-by: Jiri Pirko <jiri@resnulli.us>
---
 net/core/rtnetlink.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 9969afb..9a419b0 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -1667,9 +1667,11 @@ struct net_device *rtnl_create_link(struct net *net,
 
 	if (tb[IFLA_MTU])
 		dev->mtu = nla_get_u32(tb[IFLA_MTU]);
-	if (tb[IFLA_ADDRESS])
+	if (tb[IFLA_ADDRESS]) {
 		memcpy(dev->dev_addr, nla_data(tb[IFLA_ADDRESS]),
 				nla_len(tb[IFLA_ADDRESS]));
+		dev->addr_assign_type = NET_ADDR_SET;
+	}
 	if (tb[IFLA_BROADCAST])
 		memcpy(dev->broadcast, nla_data(tb[IFLA_BROADCAST]),
 				nla_len(tb[IFLA_BROADCAST]));
-- 
1.8.1

^ permalink raw reply related

* [patch net-next] ethtool: set addr_assign_type to NET_ADDR_SET when addr is passed on create
From: Jiri Pirko @ 2013-01-06 22:41 UTC (permalink / raw)
  To: netdev; +Cc: davem, bhutchings, shemminger, sassmann

In case user passed address via netlink during create, NET_ADDR_PERM was set.
That is not correct so fix this by setting NET_ADDR_SET.

Signed-off-by: Jiri Pirko <jiri@resnulli.us>
---
 net/core/rtnetlink.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 9969afb..9a419b0 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -1667,9 +1667,11 @@ struct net_device *rtnl_create_link(struct net *net,
 
 	if (tb[IFLA_MTU])
 		dev->mtu = nla_get_u32(tb[IFLA_MTU]);
-	if (tb[IFLA_ADDRESS])
+	if (tb[IFLA_ADDRESS]) {
 		memcpy(dev->dev_addr, nla_data(tb[IFLA_ADDRESS]),
 				nla_len(tb[IFLA_ADDRESS]));
+		dev->addr_assign_type = NET_ADDR_SET;
+	}
 	if (tb[IFLA_BROADCAST])
 		memcpy(dev->broadcast, nla_data(tb[IFLA_BROADCAST]),
 				nla_len(tb[IFLA_BROADCAST]));
-- 
1.8.1

^ permalink raw reply related

* [PATCH] chelsio: Use netdev_<level> and pr_<level>
From: Joe Perches @ 2013-01-06 23:34 UTC (permalink / raw)
  To: Divy Le Ray, Dimitris Michailidis, Casey Leedom; +Cc: netdev, linux-kernel

Use more current logging styles.

Convert printks to pr_<level> and
printks with ("%s: ...", dev->name to netdev_<level>(dev, "...

Add pr_fmt #defines where appropriate.
Coalesce formats.
Use pr_<level>_once where appropriate.

Signed-off-by: Joe Perches <joe@perches.com>
---
 drivers/net/ethernet/chelsio/cxgb/cxgb2.c          | 28 +++++------
 drivers/net/ethernet/chelsio/cxgb/sge.c            |  6 +--
 drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c    | 42 ++++++++---------
 drivers/net/ethernet/chelsio/cxgb3/cxgb3_offload.c | 54 ++++++++++------------
 drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c    |  2 +-
 .../net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c    | 23 ++++-----
 6 files changed, 66 insertions(+), 89 deletions(-)

diff --git a/drivers/net/ethernet/chelsio/cxgb/cxgb2.c b/drivers/net/ethernet/chelsio/cxgb/cxgb2.c
index c8fdeaa..20d2085 100644
--- a/drivers/net/ethernet/chelsio/cxgb/cxgb2.c
+++ b/drivers/net/ethernet/chelsio/cxgb/cxgb2.c
@@ -131,7 +131,7 @@ static void t1_set_rxmode(struct net_device *dev)
 static void link_report(struct port_info *p)
 {
 	if (!netif_carrier_ok(p->dev))
-		printk(KERN_INFO "%s: link down\n", p->dev->name);
+		netdev_info(p->dev, "link down\n");
 	else {
 		const char *s = "10Mbps";
 
@@ -141,9 +141,9 @@ static void link_report(struct port_info *p)
 			case SPEED_100:   s = "100Mbps"; break;
 		}
 
-		printk(KERN_INFO "%s: link up, %s, %s-duplex\n",
-		       p->dev->name, s,
-		       p->link_config.duplex == DUPLEX_FULL ? "full" : "half");
+		netdev_info(p->dev, "link up, %s, %s-duplex\n",
+			    s, p->link_config.duplex == DUPLEX_FULL
+			    ? "full" : "half");
 	}
 }
 
@@ -976,19 +976,13 @@ static const struct net_device_ops cxgb_netdev_ops = {
 
 static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
-	static int version_printed;
-
 	int i, err, pci_using_dac = 0;
 	unsigned long mmio_start, mmio_len;
 	const struct board_info *bi;
 	struct adapter *adapter = NULL;
 	struct port_info *pi;
 
-	if (!version_printed) {
-		printk(KERN_INFO "%s - version %s\n", DRV_DESCRIPTION,
-		       DRV_VERSION);
-		++version_printed;
-	}
+	pr_info_once("%s - version %s\n", DRV_DESCRIPTION, DRV_VERSION);
 
 	err = pci_enable_device(pdev);
 	if (err)
@@ -1124,8 +1118,8 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 	for (i = 0; i < bi->port_number; ++i) {
 		err = register_netdev(adapter->port[i].dev);
 		if (err)
-			pr_warning("%s: cannot register net device %s, skipping\n",
-				   pci_name(pdev), adapter->port[i].dev->name);
+			pr_warn("%s: cannot register net device %s, skipping\n",
+				pci_name(pdev), adapter->port[i].dev->name);
 		else {
 			/*
 			 * Change the name we use for messages to the name of
@@ -1143,10 +1137,10 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 		goto out_release_adapter_res;
 	}
 
-	printk(KERN_INFO "%s: %s (rev %d), %s %dMHz/%d-bit\n", adapter->name,
-	       bi->desc, adapter->params.chip_revision,
-	       adapter->params.pci.is_pcix ? "PCIX" : "PCI",
-	       adapter->params.pci.speed, adapter->params.pci.width);
+	pr_info("%s: %s (rev %d), %s %dMHz/%d-bit\n",
+		adapter->name, bi->desc, adapter->params.chip_revision,
+		adapter->params.pci.is_pcix ? "PCIX" : "PCI",
+		adapter->params.pci.speed, adapter->params.pci.width);
 
 	/*
 	 * Set the T1B ASIC and memory clocks.
diff --git a/drivers/net/ethernet/chelsio/cxgb/sge.c b/drivers/net/ethernet/chelsio/cxgb/sge.c
index d84872e..4829769 100644
--- a/drivers/net/ethernet/chelsio/cxgb/sge.c
+++ b/drivers/net/ethernet/chelsio/cxgb/sge.c
@@ -1822,8 +1822,8 @@ netdev_tx_t t1_start_xmit(struct sk_buff *skb, struct net_device *dev)
 		 */
 		if (unlikely(skb->len < ETH_HLEN ||
 			     skb->len > dev->mtu + eth_hdr_len(skb->data))) {
-			pr_debug("%s: packet size %d hdr %d mtu%d\n", dev->name,
-				 skb->len, eth_hdr_len(skb->data), dev->mtu);
+			netdev_dbg(dev, "packet size %d hdr %d mtu%d\n",
+				   skb->len, eth_hdr_len(skb->data), dev->mtu);
 			dev_kfree_skb_any(skb);
 			return NETDEV_TX_OK;
 		}
@@ -1831,7 +1831,7 @@ netdev_tx_t t1_start_xmit(struct sk_buff *skb, struct net_device *dev)
 		if (skb->ip_summed == CHECKSUM_PARTIAL &&
 		    ip_hdr(skb)->protocol == IPPROTO_UDP) {
 			if (unlikely(skb_checksum_help(skb))) {
-				pr_debug("%s: unable to do udp checksum\n", dev->name);
+				netdev_dbg(dev, "unable to do udp checksum\n");
 				dev_kfree_skb_any(skb);
 				return NETDEV_TX_OK;
 			}
diff --git a/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c b/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c
index f15ee32..2b5e621 100644
--- a/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c
+++ b/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c
@@ -29,6 +29,9 @@
  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/init.h>
@@ -153,7 +156,7 @@ struct workqueue_struct *cxgb3_wq;
 static void link_report(struct net_device *dev)
 {
 	if (!netif_carrier_ok(dev))
-		printk(KERN_INFO "%s: link down\n", dev->name);
+		netdev_info(dev, "link down\n");
 	else {
 		const char *s = "10Mbps";
 		const struct port_info *p = netdev_priv(dev);
@@ -170,8 +173,9 @@ static void link_report(struct net_device *dev)
 			break;
 		}
 
-		printk(KERN_INFO "%s: link up, %s, %s-duplex\n", dev->name, s,
-		       p->link_config.duplex == DUPLEX_FULL ? "full" : "half");
+		netdev_info(dev, "link up, %s, %s-duplex\n",
+			    s, p->link_config.duplex == DUPLEX_FULL
+			    ? "full" : "half");
 	}
 }
 
@@ -318,10 +322,10 @@ void t3_os_phymod_changed(struct adapter *adap, int port_id)
 	const struct port_info *pi = netdev_priv(dev);
 
 	if (pi->phy.modtype == phy_modtype_none)
-		printk(KERN_INFO "%s: PHY module unplugged\n", dev->name);
+		netdev_info(dev, "PHY module unplugged\n");
 	else
-		printk(KERN_INFO "%s: %s PHY module inserted\n", dev->name,
-		       mod_str[pi->phy.modtype]);
+		netdev_info(dev, "%s PHY module inserted\n",
+			    mod_str[pi->phy.modtype]);
 }
 
 static void cxgb_set_rxmode(struct net_device *dev)
@@ -1422,8 +1426,7 @@ static int cxgb_open(struct net_device *dev)
 	if (is_offload(adapter) && !ofld_disable) {
 		err = offload_open(dev);
 		if (err)
-			printk(KERN_WARNING
-			       "Could not initialize offload capabilities\n");
+			pr_warn("Could not initialize offload capabilities\n");
 	}
 
 	netif_set_real_num_tx_queues(dev, pi->nqsets);
@@ -3132,14 +3135,13 @@ static void print_port_info(struct adapter *adap, const struct adapter_info *ai)
 
 		if (!test_bit(i, &adap->registered_device_map))
 			continue;
-		printk(KERN_INFO "%s: %s %s %sNIC (rev %d) %s%s\n",
-		       dev->name, ai->desc, pi->phy.desc,
-		       is_offload(adap) ? "R" : "", adap->params.rev, buf,
-		       (adap->flags & USING_MSIX) ? " MSI-X" :
-		       (adap->flags & USING_MSI) ? " MSI" : "");
+		netdev_info(dev, "%s %s %sNIC (rev %d) %s%s\n",
+			    ai->desc, pi->phy.desc,
+			    is_offload(adap) ? "R" : "", adap->params.rev, buf,
+			    (adap->flags & USING_MSIX) ? " MSI-X" :
+			    (adap->flags & USING_MSI) ? " MSI" : "");
 		if (adap->name == dev->name && adap->params.vpd.mclk)
-			printk(KERN_INFO
-			       "%s: %uMB CM, %uMB PMTX, %uMB PMRX, S/N: %s\n",
+			pr_info("%s: %uMB CM, %uMB PMTX, %uMB PMRX, S/N: %s\n",
 			       adap->name, t3_mc7_size(&adap->cm) >> 20,
 			       t3_mc7_size(&adap->pmtx) >> 20,
 			       t3_mc7_size(&adap->pmrx) >> 20,
@@ -3177,24 +3179,18 @@ static void cxgb3_init_iscsi_mac(struct net_device *dev)
 			NETIF_F_IPV6_CSUM | NETIF_F_HIGHDMA)
 static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
-	static int version_printed;
-
 	int i, err, pci_using_dac = 0;
 	resource_size_t mmio_start, mmio_len;
 	const struct adapter_info *ai;
 	struct adapter *adapter = NULL;
 	struct port_info *pi;
 
-	if (!version_printed) {
-		printk(KERN_INFO "%s - version %s\n", DRV_DESC, DRV_VERSION);
-		++version_printed;
-	}
+	pr_info_once("%s - version %s\n", DRV_DESC, DRV_VERSION);
 
 	if (!cxgb3_wq) {
 		cxgb3_wq = create_singlethread_workqueue(DRV_NAME);
 		if (!cxgb3_wq) {
-			printk(KERN_ERR DRV_NAME
-			       ": cannot initialize work queue\n");
+			pr_err("cannot initialize work queue\n");
 			return -ENOMEM;
 		}
 	}
diff --git a/drivers/net/ethernet/chelsio/cxgb3/cxgb3_offload.c b/drivers/net/ethernet/chelsio/cxgb3/cxgb3_offload.c
index 3f1f501..91d02eb 100644
--- a/drivers/net/ethernet/chelsio/cxgb3/cxgb3_offload.c
+++ b/drivers/net/ethernet/chelsio/cxgb3/cxgb3_offload.c
@@ -30,6 +30,8 @@
  * SOFTWARE.
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/list.h>
 #include <linux/slab.h>
 #include <net/neighbour.h>
@@ -235,8 +237,7 @@ static int cxgb_ulp_iscsi_ctl(struct adapter *adapter, unsigned int req,
 		if ((val >> S_MAXRXDATA) != 0x3f60) {
 			val &= (M_RXCOALESCESIZE << S_RXCOALESCESIZE);
 			val |= V_MAXRXDATA(0x3f60);
-			printk(KERN_INFO
-				"%s, iscsi set MaxRxData to 16224 (0x%x).\n",
+			pr_info("%s, iscsi set MaxRxData to 16224 (0x%x)\n",
 				adapter->name, val);
 			t3_write_reg(adapter, A_TP_PARA_REG2, val);
 		}
@@ -256,8 +257,7 @@ static int cxgb_ulp_iscsi_ctl(struct adapter *adapter, unsigned int req,
 		for (i = 0; i < 4; i++)
 			val |= (uiip->pgsz_factor[i] & 0xF) << (8 * i);
 		if (val && (val != t3_read_reg(adapter, A_ULPRX_ISCSI_PSZ))) {
-			printk(KERN_INFO
-				"%s, setting iscsi pgsz 0x%x, %u,%u,%u,%u.\n",
+			pr_info("%s, setting iscsi pgsz 0x%x, %u,%u,%u,%u\n",
 				adapter->name, val, uiip->pgsz_factor[0],
 				uiip->pgsz_factor[1], uiip->pgsz_factor[2],
 				uiip->pgsz_factor[3]);
@@ -709,8 +709,7 @@ static int do_smt_write_rpl(struct t3cdev *dev, struct sk_buff *skb)
 	struct cpl_smt_write_rpl *rpl = cplhdr(skb);
 
 	if (rpl->status != CPL_ERR_NONE)
-		printk(KERN_ERR
-		       "Unexpected SMT_WRITE_RPL status %u for entry %u\n",
+		pr_err("Unexpected SMT_WRITE_RPL status %u for entry %u\n",
 		       rpl->status, GET_TID(rpl));
 
 	return CPL_RET_BUF_DONE;
@@ -721,8 +720,7 @@ static int do_l2t_write_rpl(struct t3cdev *dev, struct sk_buff *skb)
 	struct cpl_l2t_write_rpl *rpl = cplhdr(skb);
 
 	if (rpl->status != CPL_ERR_NONE)
-		printk(KERN_ERR
-		       "Unexpected L2T_WRITE_RPL status %u for entry %u\n",
+		pr_err("Unexpected L2T_WRITE_RPL status %u for entry %u\n",
 		       rpl->status, GET_TID(rpl));
 
 	return CPL_RET_BUF_DONE;
@@ -733,8 +731,7 @@ static int do_rte_write_rpl(struct t3cdev *dev, struct sk_buff *skb)
 	struct cpl_rte_write_rpl *rpl = cplhdr(skb);
 
 	if (rpl->status != CPL_ERR_NONE)
-		printk(KERN_ERR
-		       "Unexpected RTE_WRITE_RPL status %u for entry %u\n",
+		pr_err("Unexpected RTE_WRITE_RPL status %u for entry %u\n",
 		       rpl->status, GET_TID(rpl));
 
 	return CPL_RET_BUF_DONE;
@@ -754,7 +751,7 @@ static int do_act_open_rpl(struct t3cdev *dev, struct sk_buff *skb)
 								    t3c_tid->
 								    ctx);
 	} else {
-		printk(KERN_ERR "%s: received clientless CPL command 0x%x\n",
+		pr_err("%s: received clientless CPL command 0x%x\n",
 		       dev->name, CPL_ACT_OPEN_RPL);
 		return CPL_RET_BUF_DONE | CPL_RET_BAD_MSG;
 	}
@@ -772,7 +769,7 @@ static int do_stid_rpl(struct t3cdev *dev, struct sk_buff *skb)
 		return t3c_tid->client->handlers[p->opcode] (dev, skb,
 							     t3c_tid->ctx);
 	} else {
-		printk(KERN_ERR "%s: received clientless CPL command 0x%x\n",
+		pr_err("%s: received clientless CPL command 0x%x\n",
 		       dev->name, p->opcode);
 		return CPL_RET_BUF_DONE | CPL_RET_BAD_MSG;
 	}
@@ -790,7 +787,7 @@ static int do_hwtid_rpl(struct t3cdev *dev, struct sk_buff *skb)
 		return t3c_tid->client->handlers[p->opcode]
 		    (dev, skb, t3c_tid->ctx);
 	} else {
-		printk(KERN_ERR "%s: received clientless CPL command 0x%x\n",
+		pr_err("%s: received clientless CPL command 0x%x\n",
 		       dev->name, p->opcode);
 		return CPL_RET_BUF_DONE | CPL_RET_BAD_MSG;
 	}
@@ -817,7 +814,7 @@ static int do_cr(struct t3cdev *dev, struct sk_buff *skb)
 		return t3c_tid->client->handlers[CPL_PASS_ACCEPT_REQ]
 		    (dev, skb, t3c_tid->ctx);
 	} else {
-		printk(KERN_ERR "%s: received clientless CPL command 0x%x\n",
+		pr_err("%s: received clientless CPL command 0x%x\n",
 		       dev->name, CPL_PASS_ACCEPT_REQ);
 		return CPL_RET_BUF_DONE | CPL_RET_BAD_MSG;
 	}
@@ -911,7 +908,7 @@ static int do_act_establish(struct t3cdev *dev, struct sk_buff *skb)
 		return t3c_tid->client->handlers[CPL_ACT_ESTABLISH]
 		    (dev, skb, t3c_tid->ctx);
 	} else {
-		printk(KERN_ERR "%s: received clientless CPL command 0x%x\n",
+		pr_err("%s: received clientless CPL command 0x%x\n",
 		       dev->name, CPL_ACT_ESTABLISH);
 		return CPL_RET_BUF_DONE | CPL_RET_BAD_MSG;
 	}
@@ -957,7 +954,7 @@ static int do_term(struct t3cdev *dev, struct sk_buff *skb)
 		return t3c_tid->client->handlers[opcode] (dev, skb,
 							  t3c_tid->ctx);
 	} else {
-		printk(KERN_ERR "%s: received clientless CPL command 0x%x\n",
+		pr_err("%s: received clientless CPL command 0x%x\n",
 		       dev->name, opcode);
 		return CPL_RET_BUF_DONE | CPL_RET_BAD_MSG;
 	}
@@ -994,8 +991,7 @@ static struct notifier_block nb = {
  */
 static int do_bad_cpl(struct t3cdev *dev, struct sk_buff *skb)
 {
-	printk(KERN_ERR "%s: received bad CPL command 0x%x\n", dev->name,
-	       *skb->data);
+	pr_err("%s: received bad CPL command 0x%x\n", dev->name, *skb->data);
 	return CPL_RET_BUF_DONE | CPL_RET_BAD_MSG;
 }
 
@@ -1013,8 +1009,8 @@ void t3_register_cpl_handler(unsigned int opcode, cpl_handler_func h)
 	if (opcode < NUM_CPL_CMDS)
 		cpl_handlers[opcode] = h ? h : do_bad_cpl;
 	else
-		printk(KERN_ERR "T3C: handler registration for "
-		       "opcode %x failed\n", opcode);
+		pr_err("T3C: handler registration for opcode %x failed\n",
+		       opcode);
 }
 
 EXPORT_SYMBOL(t3_register_cpl_handler);
@@ -1033,9 +1029,8 @@ static int process_rx(struct t3cdev *dev, struct sk_buff **skbs, int n)
 		if (ret & CPL_RET_UNKNOWN_TID) {
 			union opcode_tid *p = cplhdr(skb);
 
-			printk(KERN_ERR "%s: CPL message (opcode %u) had "
-			       "unknown TID %u\n", dev->name, opcode,
-			       G_TID(ntohl(p->opcode_tid)));
+			pr_err("%s: CPL message (opcode %u) had unknown TID %u\n",
+			       dev->name, opcode, G_TID(ntohl(p->opcode_tid)));
 		}
 #endif
 		if (ret & CPL_RET_BUF_DONE)
@@ -1099,7 +1094,7 @@ static void set_l2t_ix(struct t3cdev *tdev, u32 tid, struct l2t_entry *e)
 
 	skb = alloc_skb(sizeof(*req), GFP_ATOMIC);
 	if (!skb) {
-		printk(KERN_ERR "%s: cannot allocate skb!\n", __func__);
+		pr_err("%s: cannot allocate skb!\n", __func__);
 		return;
 	}
 	skb->priority = CPL_PRIORITY_CONTROL;
@@ -1132,23 +1127,22 @@ static void cxgb_redirect(struct dst_entry *old, struct neighbour *old_neigh,
 	if (!is_offloading(olddev))
 		return;
 	if (!is_offloading(newdev)) {
-		printk(KERN_WARNING "%s: Redirect to non-offload "
-		       "device ignored.\n", __func__);
+		pr_warn("%s: Redirect to non-offload device ignored\n",
+			__func__);
 		return;
 	}
 	tdev = dev2t3cdev(olddev);
 	BUG_ON(!tdev);
 	if (tdev != dev2t3cdev(newdev)) {
-		printk(KERN_WARNING "%s: Redirect to different "
-		       "offload device ignored.\n", __func__);
+		pr_warn("%s: Redirect to different offload device ignored\n",
+			__func__);
 		return;
 	}
 
 	/* Add new L2T entry */
 	e = t3_l2t_get(tdev, new, newdev, daddr);
 	if (!e) {
-		printk(KERN_ERR "%s: couldn't allocate new l2t entry!\n",
-		       __func__);
+		pr_err("%s: couldn't allocate new l2t entry!\n", __func__);
 		return;
 	}
 
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
index f0718e1..aa63b66 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
@@ -5131,7 +5131,7 @@ static int __init cxgb4_init_module(void)
 	/* Debugfs support is optional, just warn if this fails */
 	cxgb4_debugfs_root = debugfs_create_dir(KBUILD_MODNAME, NULL);
 	if (!cxgb4_debugfs_root)
-		pr_warning("could not create debugfs entry, continuing\n");
+		pr_warn("could not create debugfs entry, continuing\n");
 
 	ret = pci_register_driver(&cxgb4_driver);
 	if (ret < 0)
diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c
index 0188df7..56b46ab 100644
--- a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c
+++ b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c
@@ -33,6 +33,8 @@
  * SOFTWARE.
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/init.h>
@@ -196,11 +198,10 @@ void t4vf_os_link_changed(struct adapter *adapter, int pidx, int link_ok)
 			break;
 		}
 
-		printk(KERN_INFO "%s: link up, %s, full-duplex, %s PAUSE\n",
-		       dev->name, s, fc);
+		netdev_info(dev, "link up, %s, full-duplex, %s PAUSE\n", s, fc);
 	} else {
 		netif_carrier_off(dev);
-		printk(KERN_INFO "%s: link down\n", dev->name);
+		netdev_info(dev, "link down\n");
 	}
 }
 
@@ -2465,8 +2466,6 @@ static const struct net_device_ops cxgb4vf_netdev_ops	= {
 static int cxgb4vf_pci_probe(struct pci_dev *pdev,
 			     const struct pci_device_id *ent)
 {
-	static int version_printed;
-
 	int pci_using_dac;
 	int err, pidx;
 	unsigned int pmask;
@@ -2478,10 +2477,7 @@ static int cxgb4vf_pci_probe(struct pci_dev *pdev,
 	 * Print our driver banner the first time we're called to initialize a
 	 * device.
 	 */
-	if (version_printed == 0) {
-		printk(KERN_INFO "%s - version %s\n", DRV_DESC, DRV_VERSION);
-		version_printed = 1;
-	}
+	pr_info_once("%s - version %s\n", DRV_DESC, DRV_VERSION);
 
 	/*
 	 * Initialize generic PCI device state.
@@ -2920,18 +2916,15 @@ static int __init cxgb4vf_module_init(void)
 	 * Vet our module parameters.
 	 */
 	if (msi != MSI_MSIX && msi != MSI_MSI) {
-		printk(KERN_WARNING KBUILD_MODNAME
-		       ": bad module parameter msi=%d; must be %d"
-		       " (MSI-X or MSI) or %d (MSI)\n",
-		       msi, MSI_MSIX, MSI_MSI);
+		pr_warn("bad module parameter msi=%d; must be %d (MSI-X or MSI) or %d (MSI)\n",
+			msi, MSI_MSIX, MSI_MSI);
 		return -EINVAL;
 	}
 
 	/* Debugfs support is optional, just warn if this fails */
 	cxgb4vf_debugfs_root = debugfs_create_dir(KBUILD_MODNAME, NULL);
 	if (IS_ERR_OR_NULL(cxgb4vf_debugfs_root))
-		printk(KERN_WARNING KBUILD_MODNAME ": could not create"
-		       " debugfs entry, continuing\n");
+		pr_warn("could not create debugfs entry, continuing\n");
 
 	ret = pci_register_driver(&cxgb4vf_driver);
 	if (ret < 0 && !IS_ERR_OR_NULL(cxgb4vf_debugfs_root))

^ permalink raw reply related

* Re: [PATCH 19/19] netfilter: gre: fix resource leak when unregister gre proto
From: Gao feng @ 2013-01-07  1:27 UTC (permalink / raw)
  To: Pablo Neira Ayuso; +Cc: netfilter-devel, netdev, canqunzhang, kaber, ebiederm
In-Reply-To: <20130105035048.GA20027@1984>

Hi Pablo,

On 01/05/13 11:50, Pablo Neira Ayuso wrote:
> Hi Gao,
> 
> On Fri, Dec 28, 2012 at 10:36:46AM +0800, Gao feng wrote:
>> Currectly we unregister proto before all conntrack entries of
>> this proto being destroyed. so in function destroy_conntrack
>> we can't find proper l4proto to call l4proto->destroy.
>> this will cause resource leak.
> 
> Good catch.
> 
> But better to remove the entries before unregistering the protocol
> tracker, so l4proto->destroy is always called.
> 

I think the reason we unregister proto before remove all entries
is to avoid new entry for this protocol being created.

If we remove all contrack entries before unregistration, there maybe
some new entries being created between nf_ct_iterate_cleanup and
nf_conntrack_l4proto_unregister_net.this will cause some terrible things.

SO I think we should make proto unavailable first,remove all entries next,
and remove proto from nf_ct_protos arrays finally.

^ permalink raw reply

* Re: [PATCH 19/19] netfilter: gre: fix resource leak when unregister gre proto
From: Pablo Neira Ayuso @ 2013-01-07  2:15 UTC (permalink / raw)
  To: Gao feng; +Cc: netfilter-devel, netdev, canqunzhang, kaber, ebiederm
In-Reply-To: <50EA2489.3070309@cn.fujitsu.com>

Hi Gao,

On Mon, Jan 07, 2013 at 09:27:37AM +0800, Gao feng wrote:
> Hi Pablo,
> 
> On 01/05/13 11:50, Pablo Neira Ayuso wrote:
> > Hi Gao,
> > 
> > On Fri, Dec 28, 2012 at 10:36:46AM +0800, Gao feng wrote:
> >> Currectly we unregister proto before all conntrack entries of
> >> this proto being destroyed. so in function destroy_conntrack
> >> we can't find proper l4proto to call l4proto->destroy.
> >> this will cause resource leak.
> > 
> > Good catch.
> > 
> > But better to remove the entries before unregistering the protocol
> > tracker, so l4proto->destroy is always called.
> > 
> 
> I think the reason we unregister proto before remove all entries
> is to avoid new entry for this protocol being created.
> 
> If we remove all contrack entries before unregistration, there maybe
> some new entries being created between nf_ct_iterate_cleanup and
> nf_conntrack_l4proto_unregister_net.this will cause some terrible things.

Leaks are less likely to happen, but may well still happen while
racing with protocol removal, agreed.

> SO I think we should make proto unavailable first,remove all entries next,
> and remove proto from nf_ct_protos arrays finally.

Your proposal adds a branch in the packet path to fix an issue that is
specific of the GRE protocol tracker. In the current code, this fixes
the memory leak while removing the nf_conntrack_proto_gre module,
which is a rare operation.

We have to come with a less intrusive solution.

Regards.

^ permalink raw reply

* Re: [PATCH 19/19] netfilter: gre: fix resource leak when unregister gre proto
From: Pablo Neira Ayuso @ 2013-01-07  2:38 UTC (permalink / raw)
  To: Gao feng; +Cc: netfilter-devel, netdev, canqunzhang, kaber, ebiederm
In-Reply-To: <20130107021517.GA12215@1984>

On Mon, Jan 07, 2013 at 03:15:17AM +0100, Pablo Neira Ayuso wrote:
> Hi Gao,
> 
> On Mon, Jan 07, 2013 at 09:27:37AM +0800, Gao feng wrote:
> > Hi Pablo,
> > 
> > On 01/05/13 11:50, Pablo Neira Ayuso wrote:
> > > Hi Gao,
> > > 
> > > On Fri, Dec 28, 2012 at 10:36:46AM +0800, Gao feng wrote:
> > >> Currectly we unregister proto before all conntrack entries of
> > >> this proto being destroyed. so in function destroy_conntrack
> > >> we can't find proper l4proto to call l4proto->destroy.
> > >> this will cause resource leak.
> > > 
> > > Good catch.
> > > 
> > > But better to remove the entries before unregistering the protocol
> > > tracker, so l4proto->destroy is always called.
> > > 
> > 
> > I think the reason we unregister proto before remove all entries
> > is to avoid new entry for this protocol being created.
> > 
> > If we remove all contrack entries before unregistration, there maybe
> > some new entries being created between nf_ct_iterate_cleanup and
> > nf_conntrack_l4proto_unregister_net.this will cause some terrible things.
> 
> Leaks are less likely to happen, but may well still happen while
> racing with protocol removal, agreed.
> 
> > SO I think we should make proto unavailable first,remove all entries next,
> > and remove proto from nf_ct_protos arrays finally.
> 
> Your proposal adds a branch in the packet path to fix an issue that is
> specific of the GRE protocol tracker. In the current code, this fixes
> the memory leak while removing the nf_conntrack_proto_gre module,
> which is a rare operation.
> 
> We have to come with a less intrusive solution.

Wait. The existing code is calling nf_ct_gre_keymap_flush in
proto_gre_net_exit path, so those keymap objects are not leaked.

^ permalink raw reply

* Re: [PATCH] drivers/net/wireless/ipw2x00: use strlcpy instead of strncpy
From: Chen Gang @ 2013-01-07  2:49 UTC (permalink / raw)
  To: Joe Perches; +Cc: stas.yakovlev, linville, linux-wireless, netdev
In-Reply-To: <1357396966.21156.4.camel@joe-AO722>

于 2013年01月05日 22:42, Joe Perches 写道:
> This happens because escaped is declared the wrong size.
> 
> It'd be better to change
> 	char escaped[IW_ESSID_MAX_SIZE * 2 + 1];
> to
> 	DECLARE_SSID_BUF(escaped);
> and use
> 	print_ssid(escaped, network->ssid, network->ssid_len)
> in the debug.
> 

  if what you said is true:
    it is better to delete escaped variable
    use ssid instead of escaped, directly.

  but I think the original author intended to use escaped instead of ssid
    DECLARE_SSID_BUF(ssid)  (line 5525, 5737)
    use ssid to print debug information directly
      (such as: line 5530..5535, 5545..5549, 5745..5749, ...)
    when need print additional information, use escaped
      (line 5559..5569, 5773..5782, 5791..5799)

  so, I still suggest:
    only fix the bug (use strlcpy instead of strncpy)
    and not touch original features which orignal author intended using.

  Regards

gchen.

in drivers/net/wireless/ipw2x00/ipw2200.c:

 5519 static int ipw_find_adhoc_network(struct ipw_priv *priv,
 5520                                   struct ipw_network_match *match,
 5521                                   struct libipw_network *network,
 5522                                   int roaming)
 5523 {
 5524         struct ipw_supported_rates rates;
 5525         DECLARE_SSID_BUF(ssid);
 5526 
 5527         /* Verify that this network's capability is compatible with the
 5528          * current mode (AdHoc or Infrastructure) */
 5529         if ((priv->ieee->iw_mode == IW_MODE_ADHOC &&
 5530              !(network->capability & WLAN_CAPABILITY_IBSS))) {
 5531                 IPW_DEBUG_MERGE("Network '%s (%pM)' excluded due to "
 5532                                 "capability mismatch.\n",
 5533                                 print_ssid(ssid, network->ssid,
 5534                                            network->ssid_len),
 5535                                 network->bssid);
 5536                 return 0;
 5537         }
 5538 
 5539         if (unlikely(roaming)) {
 5540                 /* If we are roaming, then ensure check if this is a valid
 5541                  * network to try and roam to */
 5542                 if ((network->ssid_len != match->network->ssid_len) ||
 5543                     memcmp(network->ssid, match->network->ssid,
 5544                            network->ssid_len)) {
 5545                         IPW_DEBUG_MERGE("Network '%s (%pM)' excluded "
 5546                                         "because of non-network ESSID.\n",
 5547                                         print_ssid(ssid, network->ssid,
 5548                                                    network->ssid_len),
 5549                                         network->bssid);
 5550                         return 0;
 5551                 }
 5552         } else {
 5553                 /* If an ESSID has been configured then compare the broadcast
 5554                  * ESSID to ours */
 5555                 if ((priv->config & CFG_STATIC_ESSID) &&
 5556                     ((network->ssid_len != priv->essid_len) ||
 5557                      memcmp(network->ssid, priv->essid,
 5558                             min(network->ssid_len, priv->essid_len)))) {
 5559                         char escaped[IW_ESSID_MAX_SIZE * 2 + 1];
 5560 
 5561                         strncpy(escaped,
 5562                                 print_ssid(ssid, network->ssid,
 5563                                            network->ssid_len),
 5564                                 sizeof(escaped));
 5565                         IPW_DEBUG_MERGE("Network '%s (%pM)' excluded "
 5566                                         "because of ESSID mismatch: '%s'.\n",
 5567                                         escaped, network->bssid,
 5568                                         print_ssid(ssid, priv->essid,
 5569                                                    priv->essid_len));
 5570                         return 0;
 5571                 }
 5572         }
 ...
 
 5732 static int ipw_best_network(struct ipw_priv *priv,
 5733                             struct ipw_network_match *match,
 5734                             struct libipw_network *network, int roaming)
 5735 {
 5736         struct ipw_supported_rates rates;
 5737         DECLARE_SSID_BUF(ssid);
 5738 
 5739         /* Verify that this network's capability is compatible with the
 5740          * current mode (AdHoc or Infrastructure) */
 5741         if ((priv->ieee->iw_mode == IW_MODE_INFRA &&
 5742              !(network->capability & WLAN_CAPABILITY_ESS)) ||
 5743             (priv->ieee->iw_mode == IW_MODE_ADHOC &&
 5744              !(network->capability & WLAN_CAPABILITY_IBSS))) {
 5745                 IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded due to "
 5746                                 "capability mismatch.\n",
 5747                                 print_ssid(ssid, network->ssid,
 5748                                            network->ssid_len),
 5749                                 network->bssid);
 5750                 return 0;
 5751         }
 5752 
 5753         if (unlikely(roaming)) {
 5754                 /* If we are roaming, then ensure check if this is a valid
 5755                  * network to try and roam to */
 5756                 if ((network->ssid_len != match->network->ssid_len) ||
 5757                     memcmp(network->ssid, match->network->ssid,
 5758                            network->ssid_len)) {
 5759                         IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded "
 5760                                         "because of non-network ESSID.\n",
 5761                                         print_ssid(ssid, network->ssid,
 5762                                                    network->ssid_len),
 5763                                         network->bssid);
 5764                         return 0;
 5765                 }
 5766         } else {
 5767                 /* If an ESSID has been configured then compare the broadcast
 5768                  * ESSID to ours */
 5769                 if ((priv->config & CFG_STATIC_ESSID) &&
 5770                     ((network->ssid_len != priv->essid_len) ||
 5771                      memcmp(network->ssid, priv->essid,
 5772                             min(network->ssid_len, priv->essid_len)))) {
 5773                         char escaped[IW_ESSID_MAX_SIZE * 2 + 1];
 5774                         strncpy(escaped,
 5775                                 print_ssid(ssid, network->ssid,
 5776                                            network->ssid_len),
 5777                                 sizeof(escaped));
 5778                         IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded "
 5779                                         "because of ESSID mismatch: '%s'.\n",
 5780                                         escaped, network->bssid,
 5781                                         print_ssid(ssid, priv->essid,
 5782                                                    priv->essid_len));
 5783                         return 0;
 5784                 }
 5785         }
 5786 
 5787         /* If the old network rate is better than this one, don't bother
 5788          * testing everything else. */
 5789         if (match->network && match->network->stats.rssi > network->stats.rssi) {
 5790                 char escaped[IW_ESSID_MAX_SIZE * 2 + 1];
 5791                 strncpy(escaped,
 5792                         print_ssid(ssid, network->ssid, network->ssid_len),
 5793                         sizeof(escaped));
 5794                 IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded because "
 5795                                 "'%s (%pM)' has a stronger signal.\n",
 5796                                 escaped, network->bssid,
 5797                                 print_ssid(ssid, match->network->ssid,
 5798                                            match->network->ssid_len),
 5799                                 match->network->bssid);
 5800                 return 0;
 5801         }

-- 
Chen Gang

Asianux Corporation

^ permalink raw reply

* Re: [PATCH] drivers/net/wireless/ipw2x00: use strlcpy instead of strncpy
From: Chen Gang F T @ 2013-01-07  2:57 UTC (permalink / raw)
  To: Chen Gang
  Cc: Joe Perches, stas.yakovlev-Re5JQEeQqe8AvxtiuMwx3w,
	linville-2XuSBdqkA4R54TAoqtyWWQ,
	linux-wireless-u79uwXL29TY76Z2rM5mHXA,
	netdev-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <50EA37CE.1090901-bOixZGp5f+dBDgjK7y7TUQ@public.gmane.org>

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

于 2013年01月07日 10:49, Chen Gang 写道:
> 于 2013年01月05日 22:42, Joe Perches 写道:
>> This happens because escaped is declared the wrong size.
>>
>> It'd be better to change
>> 	char escaped[IW_ESSID_MAX_SIZE * 2 + 1];
>> to
>> 	DECLARE_SSID_BUF(escaped);
>> and use
>> 	print_ssid(escaped, network->ssid, network->ssid_len)
>> in the debug.
>>
> 
>   if what you said is true:
>     it is better to delete escaped variable
>     use ssid instead of escaped, directly.
> 
   oh, sorry, it is my fault.
   we need use duplicate buffer to print different contents, at the same time.

   :-)

   but I still suggest to keep original author using
      maybe he intend to keep the print size for output format
      so I think it is better to only fix bug, not touch the features. 

   Regards

 gchen.



>   but I think the original author intended to use escaped instead of ssid
>     DECLARE_SSID_BUF(ssid)  (line 5525, 5737)
>     use ssid to print debug information directly
>       (such as: line 5530..5535, 5545..5549, 5745..5749, ...)
>     when need print additional information, use escaped
>       (line 5559..5569, 5773..5782, 5791..5799)
> 
>   so, I still suggest:
>     only fix the bug (use strlcpy instead of strncpy)
>     and not touch original features which orignal author intended using.
> 
>   Regards
> 
> gchen.
> 
> in drivers/net/wireless/ipw2x00/ipw2200.c:
> 
>  5519 static int ipw_find_adhoc_network(struct ipw_priv *priv,
>  5520                                   struct ipw_network_match *match,
>  5521                                   struct libipw_network *network,
>  5522                                   int roaming)
>  5523 {
>  5524         struct ipw_supported_rates rates;
>  5525         DECLARE_SSID_BUF(ssid);
>  5526 
>  5527         /* Verify that this network's capability is compatible with the
>  5528          * current mode (AdHoc or Infrastructure) */
>  5529         if ((priv->ieee->iw_mode == IW_MODE_ADHOC &&
>  5530              !(network->capability & WLAN_CAPABILITY_IBSS))) {
>  5531                 IPW_DEBUG_MERGE("Network '%s (%pM)' excluded due to "
>  5532                                 "capability mismatch.\n",
>  5533                                 print_ssid(ssid, network->ssid,
>  5534                                            network->ssid_len),
>  5535                                 network->bssid);
>  5536                 return 0;
>  5537         }
>  5538 
>  5539         if (unlikely(roaming)) {
>  5540                 /* If we are roaming, then ensure check if this is a valid
>  5541                  * network to try and roam to */
>  5542                 if ((network->ssid_len != match->network->ssid_len) ||
>  5543                     memcmp(network->ssid, match->network->ssid,
>  5544                            network->ssid_len)) {
>  5545                         IPW_DEBUG_MERGE("Network '%s (%pM)' excluded "
>  5546                                         "because of non-network ESSID.\n",
>  5547                                         print_ssid(ssid, network->ssid,
>  5548                                                    network->ssid_len),
>  5549                                         network->bssid);
>  5550                         return 0;
>  5551                 }
>  5552         } else {
>  5553                 /* If an ESSID has been configured then compare the broadcast
>  5554                  * ESSID to ours */
>  5555                 if ((priv->config & CFG_STATIC_ESSID) &&
>  5556                     ((network->ssid_len != priv->essid_len) ||
>  5557                      memcmp(network->ssid, priv->essid,
>  5558                             min(network->ssid_len, priv->essid_len)))) {
>  5559                         char escaped[IW_ESSID_MAX_SIZE * 2 + 1];
>  5560 
>  5561                         strncpy(escaped,
>  5562                                 print_ssid(ssid, network->ssid,
>  5563                                            network->ssid_len),
>  5564                                 sizeof(escaped));
>  5565                         IPW_DEBUG_MERGE("Network '%s (%pM)' excluded "
>  5566                                         "because of ESSID mismatch: '%s'.\n",
>  5567                                         escaped, network->bssid,
>  5568                                         print_ssid(ssid, priv->essid,
>  5569                                                    priv->essid_len));
>  5570                         return 0;
>  5571                 }
>  5572         }
>  ...
>  
>  5732 static int ipw_best_network(struct ipw_priv *priv,
>  5733                             struct ipw_network_match *match,
>  5734                             struct libipw_network *network, int roaming)
>  5735 {
>  5736         struct ipw_supported_rates rates;
>  5737         DECLARE_SSID_BUF(ssid);
>  5738 
>  5739         /* Verify that this network's capability is compatible with the
>  5740          * current mode (AdHoc or Infrastructure) */
>  5741         if ((priv->ieee->iw_mode == IW_MODE_INFRA &&
>  5742              !(network->capability & WLAN_CAPABILITY_ESS)) ||
>  5743             (priv->ieee->iw_mode == IW_MODE_ADHOC &&
>  5744              !(network->capability & WLAN_CAPABILITY_IBSS))) {
>  5745                 IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded due to "
>  5746                                 "capability mismatch.\n",
>  5747                                 print_ssid(ssid, network->ssid,
>  5748                                            network->ssid_len),
>  5749                                 network->bssid);
>  5750                 return 0;
>  5751         }
>  5752 
>  5753         if (unlikely(roaming)) {
>  5754                 /* If we are roaming, then ensure check if this is a valid
>  5755                  * network to try and roam to */
>  5756                 if ((network->ssid_len != match->network->ssid_len) ||
>  5757                     memcmp(network->ssid, match->network->ssid,
>  5758                            network->ssid_len)) {
>  5759                         IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded "
>  5760                                         "because of non-network ESSID.\n",
>  5761                                         print_ssid(ssid, network->ssid,
>  5762                                                    network->ssid_len),
>  5763                                         network->bssid);
>  5764                         return 0;
>  5765                 }
>  5766         } else {
>  5767                 /* If an ESSID has been configured then compare the broadcast
>  5768                  * ESSID to ours */
>  5769                 if ((priv->config & CFG_STATIC_ESSID) &&
>  5770                     ((network->ssid_len != priv->essid_len) ||
>  5771                      memcmp(network->ssid, priv->essid,
>  5772                             min(network->ssid_len, priv->essid_len)))) {
>  5773                         char escaped[IW_ESSID_MAX_SIZE * 2 + 1];
>  5774                         strncpy(escaped,
>  5775                                 print_ssid(ssid, network->ssid,
>  5776                                            network->ssid_len),
>  5777                                 sizeof(escaped));
>  5778                         IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded "
>  5779                                         "because of ESSID mismatch: '%s'.\n",
>  5780                                         escaped, network->bssid,
>  5781                                         print_ssid(ssid, priv->essid,
>  5782                                                    priv->essid_len));
>  5783                         return 0;
>  5784                 }
>  5785         }
>  5786 
>  5787         /* If the old network rate is better than this one, don't bother
>  5788          * testing everything else. */
>  5789         if (match->network && match->network->stats.rssi > network->stats.rssi) {
>  5790                 char escaped[IW_ESSID_MAX_SIZE * 2 + 1];
>  5791                 strncpy(escaped,
>  5792                         print_ssid(ssid, network->ssid, network->ssid_len),
>  5793                         sizeof(escaped));
>  5794                 IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded because "
>  5795                                 "'%s (%pM)' has a stronger signal.\n",
>  5796                                 escaped, network->bssid,
>  5797                                 print_ssid(ssid, match->network->ssid,
>  5798                                            match->network->ssid_len),
>  5799                                 match->network->bssid);
>  5800                 return 0;
>  5801         }
> 


-- 
Chen Gang

Flying Transformer

[-- Attachment #2: chen_gang_flying_transformer.vcf --]
[-- Type: text/x-vcard, Size: 67 bytes --]

begin:vcard
fn:Chen Gang
n:;Chen Gang
version:2.1
end:vcard


^ permalink raw reply

* Re: [PATCH net-next v3 0/3] netpoll: add IPv6 support
From: Cong Wang @ 2013-01-07  2:58 UTC (permalink / raw)
  To: David Miller; +Cc: netdev
In-Reply-To: <20130103.192041.782458185484678551.davem@davemloft.net>

On Thu, 2013-01-03 at 19:20 -0800, David Miller wrote:
> From: Cong Wang <amwang@redhat.com>
> Date: Fri,  4 Jan 2013 11:14:30 +0800
> 
> > (Resend with a cover letter)
> > 
> > v3: fix CONFIG_IPV6=m case
> > 
> > v2: use bool for ipv6 flag
> >     fix !CONFIG_IPV6 case
> > 
> > This patchset implements netpoll over IPv6.
> 
> Thanks for submitting this properly.
> 
> But disallowing ipv6 netpoll support when IPV6=m is an unacceptable
> limitation, compiling IPV6 as a module is common and in fact
> recommended.
> 
> We've solved problems like this before, by putting the needed ipv6
> routines into a seperate library that is built statically into the
> kernel when necessary.
> 
> You should use a similar approach here.

Hmm, here we need ndisc_parse_options() and udp6_csum_init(). Not sure
if both can be inlined?

Thanks!

^ permalink raw reply

* Re: [PATCH 19/19] netfilter: gre: fix resource leak when unregister gre proto
From: Gao feng @ 2013-01-07  2:59 UTC (permalink / raw)
  To: Pablo Neira Ayuso; +Cc: netfilter-devel, netdev, canqunzhang, kaber, ebiederm
In-Reply-To: <20130107023808.GA14431@1984>

On 01/07/13 10:38, Pablo Neira Ayuso wrote:
> On Mon, Jan 07, 2013 at 03:15:17AM +0100, Pablo Neira Ayuso wrote:
>> Hi Gao,
>>
>> On Mon, Jan 07, 2013 at 09:27:37AM +0800, Gao feng wrote:
>>> Hi Pablo,
>>>
>>> On 01/05/13 11:50, Pablo Neira Ayuso wrote:
>>>> Hi Gao,
>>>>
>>>> On Fri, Dec 28, 2012 at 10:36:46AM +0800, Gao feng wrote:
>>>>> Currectly we unregister proto before all conntrack entries of
>>>>> this proto being destroyed. so in function destroy_conntrack
>>>>> we can't find proper l4proto to call l4proto->destroy.
>>>>> this will cause resource leak.
>>>>
>>>> Good catch.
>>>>
>>>> But better to remove the entries before unregistering the protocol
>>>> tracker, so l4proto->destroy is always called.
>>>>
>>>
>>> I think the reason we unregister proto before remove all entries
>>> is to avoid new entry for this protocol being created.
>>>
>>> If we remove all contrack entries before unregistration, there maybe
>>> some new entries being created between nf_ct_iterate_cleanup and
>>> nf_conntrack_l4proto_unregister_net.this will cause some terrible things.
>>
>> Leaks are less likely to happen, but may well still happen while
>> racing with protocol removal, agreed.
>>
>>> SO I think we should make proto unavailable first,remove all entries next,
>>> and remove proto from nf_ct_protos arrays finally.
>>
>> Your proposal adds a branch in the packet path to fix an issue that is
>> specific of the GRE protocol tracker. In the current code, this fixes
>> the memory leak while removing the nf_conntrack_proto_gre module,
>> which is a rare operation.
>>
>> We have to come with a less intrusive solution.
> 
> Wait. The existing code is calling nf_ct_gre_keymap_flush in
> proto_gre_net_exit path, so those keymap objects are not leaked.

Agree, it looks like nf_ct_gre_keymap_flush is added to solve this
problem.

Please ignore this patch.

Thanks!

^ permalink raw reply

* [PATCH v2 1/1 net-next] net: fec: report correct hardware stamping info to ethtool
From: Frank Li @ 2013-01-07  2:25 UTC (permalink / raw)
  To: lznuaa, shawn.guo, richardcochran, davem, linux-arm-kernel,
	netdev
  Cc: s.hauer, Frank Li

Report correct hardware stamping capability by ethtool interface.
The v1.0 ptp4l check it.

Signed-off-by: Frank Li <Frank.Li@freescale.com>
---
Change v1->v2
 1. s/capibilty/capability/
 2. apply Sascha's feedback 
    avoid return the return value of ethtool_op_get_ts_info()
    when bufdesc_ex ==  1

 drivers/net/ethernet/freescale/fec.c |   31 ++++++++++++++++++++++++++++++-
 1 files changed, 30 insertions(+), 1 deletions(-)

diff --git a/drivers/net/ethernet/freescale/fec.c b/drivers/net/ethernet/freescale/fec.c
index a379319..1c117e5 100644
--- a/drivers/net/ethernet/freescale/fec.c
+++ b/drivers/net/ethernet/freescale/fec.c
@@ -1173,12 +1173,41 @@ static void fec_enet_get_drvinfo(struct net_device *ndev,
 	strcpy(info->bus_info, dev_name(&ndev->dev));
 }
 
+static int fec_enet_get_ts_info(struct net_device *ndev,
+				struct ethtool_ts_info *info)
+{
+	struct fec_enet_private *fep = netdev_priv(ndev);
+
+	if (fep->bufdesc_ex) {
+
+		info->so_timestamping = SOF_TIMESTAMPING_TX_SOFTWARE |
+					SOF_TIMESTAMPING_RX_SOFTWARE |
+					SOF_TIMESTAMPING_SOFTWARE |
+					SOF_TIMESTAMPING_TX_HARDWARE |
+					SOF_TIMESTAMPING_RX_HARDWARE |
+					SOF_TIMESTAMPING_RAW_HARDWARE;
+		if (fep->ptp_clock)
+			info->phc_index = ptp_clock_index(fep->ptp_clock);
+		else
+			info->phc_index = -1;
+
+		info->tx_types = (1 << HWTSTAMP_TX_OFF) |
+				 (1 << HWTSTAMP_TX_ON);
+
+		info->rx_filters = (1 << HWTSTAMP_FILTER_NONE) |
+				   (1 << HWTSTAMP_FILTER_ALL);
+		return 0;
+	} else {
+		return ethtool_op_get_ts_info(ndev, info);
+	}
+}
+
 static const struct ethtool_ops fec_enet_ethtool_ops = {
 	.get_settings		= fec_enet_get_settings,
 	.set_settings		= fec_enet_set_settings,
 	.get_drvinfo		= fec_enet_get_drvinfo,
 	.get_link		= ethtool_op_get_link,
-	.get_ts_info		= ethtool_op_get_ts_info,
+	.get_ts_info		= fec_enet_get_ts_info,
 };
 
 static int fec_enet_ioctl(struct net_device *ndev, struct ifreq *rq, int cmd)
-- 
1.7.1

^ permalink raw reply related

* Re: [PATCH 19/19] netfilter: gre: fix resource leak when unregister gre proto
From: Gao feng @ 2013-01-07  3:05 UTC (permalink / raw)
  To: Pablo Neira Ayuso; +Cc: netfilter-devel, netdev, canqunzhang, kaber, ebiederm
In-Reply-To: <50EA3A1F.8020108@cn.fujitsu.com>

On 01/07/13 10:59, Gao feng wrote:
> On 01/07/13 10:38, Pablo Neira Ayuso wrote:
>> On Mon, Jan 07, 2013 at 03:15:17AM +0100, Pablo Neira Ayuso wrote:
>>> Hi Gao,
>>>
>>> On Mon, Jan 07, 2013 at 09:27:37AM +0800, Gao feng wrote:
>>>> Hi Pablo,
>>>>
>>>> On 01/05/13 11:50, Pablo Neira Ayuso wrote:
>>>>> Hi Gao,
>>>>>
>>>>> On Fri, Dec 28, 2012 at 10:36:46AM +0800, Gao feng wrote:
>>>>>> Currectly we unregister proto before all conntrack entries of
>>>>>> this proto being destroyed. so in function destroy_conntrack
>>>>>> we can't find proper l4proto to call l4proto->destroy.
>>>>>> this will cause resource leak.
>>>>>
>>>>> Good catch.
>>>>>
>>>>> But better to remove the entries before unregistering the protocol
>>>>> tracker, so l4proto->destroy is always called.
>>>>>
>>>>
>>>> I think the reason we unregister proto before remove all entries
>>>> is to avoid new entry for this protocol being created.
>>>>
>>>> If we remove all contrack entries before unregistration, there maybe
>>>> some new entries being created between nf_ct_iterate_cleanup and
>>>> nf_conntrack_l4proto_unregister_net.this will cause some terrible things.
>>>
>>> Leaks are less likely to happen, but may well still happen while
>>> racing with protocol removal, agreed.
>>>
>>>> SO I think we should make proto unavailable first,remove all entries next,
>>>> and remove proto from nf_ct_protos arrays finally.
>>>
>>> Your proposal adds a branch in the packet path to fix an issue that is
>>> specific of the GRE protocol tracker. In the current code, this fixes
>>> the memory leak while removing the nf_conntrack_proto_gre module,
>>> which is a rare operation.
>>>
>>> We have to come with a less intrusive solution.
>>
>> Wait. The existing code is calling nf_ct_gre_keymap_flush in
>> proto_gre_net_exit path, so those keymap objects are not leaked.
> 
> Agree, it looks like nf_ct_gre_keymap_flush is added to solve this
> problem.
> 
> Please ignore this patch.

I mean ignore the codes of gre part.
I still think nf_ct_iterate_cleanup doesn't make sure all entries being
destroyed.

I will resend this patch.

Thanks!

^ permalink raw reply

* Re: [PATCH] drivers/net/wireless/ipw2x00: use strlcpy instead of strncpy
From: Joe Perches @ 2013-01-07  3:19 UTC (permalink / raw)
  To: Chen Gang; +Cc: stas.yakovlev, linville, linux-wireless, netdev
In-Reply-To: <50EA37CE.1090901@asianux.com>

On Mon, 2013-01-07 at 10:49 +0800, Chen Gang wrote:
>   but I think the original author intended to use escaped instead of ssid
>     DECLARE_SSID_BUF(ssid)  (line 5525, 5737)
>     use ssid to print debug information directly
>       (such as: line 5530..5535, 5545..5549, 5745..5749, ...)
>     when need print additional information, use escaped
>       (line 5559..5569, 5773..5782, 5791..5799)
> 
>   so, I still suggest:
>     only fix the bug (use strlcpy instead of strncpy)
>     and not touch original features which orignal author intended using.

More likely John Linville just missed the conversions.
4+ years ago.

commit 9387b7caf3049168fc97a8a9111af8fe2143af18
Author: John W. Linville <linville@tuxdriver.com>
Date:   Tue Sep 30 20:59:05 2008 -0400

    wireless: use individual buffers for printing ssid values
  
    Also change escape_ssid to print_ssid to match print_mac semantics.
    
    Signed-off-by: John W. Linville <linville@tuxdriver.com>

Maybe these days this should be another vsprintf %p extension
like %pM when the DECLARE_MAC_BUF/print_mac uses were converted.

(or maybe extend %ph for ssids with %*phs, length, array)

But if and until then, I suggest this instead:

 drivers/net/wireless/ipw2x00/ipw2200.c | 38 ++++++++++++++--------------------
 1 file changed, 15 insertions(+), 23 deletions(-)

diff --git a/drivers/net/wireless/ipw2x00/ipw2200.c b/drivers/net/wireless/ipw2x00/ipw2200.c
index 844f201..3dc6a92 100644
--- a/drivers/net/wireless/ipw2x00/ipw2200.c
+++ b/drivers/net/wireless/ipw2x00/ipw2200.c
@@ -5556,15 +5556,12 @@ static int ipw_find_adhoc_network(struct ipw_priv *priv,
 		    ((network->ssid_len != priv->essid_len) ||
 		     memcmp(network->ssid, priv->essid,
 			    min(network->ssid_len, priv->essid_len)))) {
-			char escaped[IW_ESSID_MAX_SIZE * 2 + 1];
+			DECLARE_SSID_BUF(escaped);
 
-			strncpy(escaped,
-				print_ssid(ssid, network->ssid,
-					   network->ssid_len),
-				sizeof(escaped));
-			IPW_DEBUG_MERGE("Network '%s (%pM)' excluded "
-					"because of ESSID mismatch: '%s'.\n",
-					escaped, network->bssid,
+			IPW_DEBUG_MERGE("Network '%s (%pM)' excluded because of ESSID mismatch: '%s'\n",
+					print_ssid(escaped, network->ssid,
+						   network->ssid_len),
+					network->bssid,
 					print_ssid(ssid, priv->essid,
 						   priv->essid_len));
 			return 0;
@@ -5770,14 +5767,11 @@ static int ipw_best_network(struct ipw_priv *priv,
 		    ((network->ssid_len != priv->essid_len) ||
 		     memcmp(network->ssid, priv->essid,
 			    min(network->ssid_len, priv->essid_len)))) {
-			char escaped[IW_ESSID_MAX_SIZE * 2 + 1];
-			strncpy(escaped,
-				print_ssid(ssid, network->ssid,
-					   network->ssid_len),
-				sizeof(escaped));
-			IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded "
-					"because of ESSID mismatch: '%s'.\n",
-					escaped, network->bssid,
+			DECLARE_SSID_BUF(escaped);
+			IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded because of ESSID mismatch: '%s'\n",
+					print_ssid(escaped, network->ssid,
+						   network->ssid_len),
+					network->bssid,
 					print_ssid(ssid, priv->essid,
 						   priv->essid_len));
 			return 0;
@@ -5787,13 +5781,11 @@ static int ipw_best_network(struct ipw_priv *priv,
 	/* If the old network rate is better than this one, don't bother
 	 * testing everything else. */
 	if (match->network && match->network->stats.rssi > network->stats.rssi) {
-		char escaped[IW_ESSID_MAX_SIZE * 2 + 1];
-		strncpy(escaped,
-			print_ssid(ssid, network->ssid, network->ssid_len),
-			sizeof(escaped));
-		IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded because "
-				"'%s (%pM)' has a stronger signal.\n",
-				escaped, network->bssid,
+		DECLARE_SSID_BUF(escaped);
+		IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded because '%s (%pM)' has a stronger signal\n",
+				print_ssid(escaped, network->ssid,
+					   network->ssid_len),
+				network->bssid,
 				print_ssid(ssid, match->network->ssid,
 					   match->network->ssid_len),
 				match->network->bssid);

^ permalink raw reply related

* Re: [PATCH 19/19] netfilter: gre: fix resource leak when unregister gre proto
From: Pablo Neira Ayuso @ 2013-01-07  3:27 UTC (permalink / raw)
  To: Gao feng; +Cc: netfilter-devel, netdev, canqunzhang, kaber, ebiederm
In-Reply-To: <50EA3B68.1080001@cn.fujitsu.com>

On Mon, Jan 07, 2013 at 11:05:12AM +0800, Gao feng wrote:
> On 01/07/13 10:59, Gao feng wrote:
> > On 01/07/13 10:38, Pablo Neira Ayuso wrote:
> >> On Mon, Jan 07, 2013 at 03:15:17AM +0100, Pablo Neira Ayuso wrote:
> >>> Hi Gao,
> >>>
> >>> On Mon, Jan 07, 2013 at 09:27:37AM +0800, Gao feng wrote:
> >>>> Hi Pablo,
> >>>>
> >>>> On 01/05/13 11:50, Pablo Neira Ayuso wrote:
> >>>>> Hi Gao,
> >>>>>
> >>>>> On Fri, Dec 28, 2012 at 10:36:46AM +0800, Gao feng wrote:
> >>>>>> Currectly we unregister proto before all conntrack entries of
> >>>>>> this proto being destroyed. so in function destroy_conntrack
> >>>>>> we can't find proper l4proto to call l4proto->destroy.
> >>>>>> this will cause resource leak.
> >>>>>
> >>>>> Good catch.
> >>>>>
> >>>>> But better to remove the entries before unregistering the protocol
> >>>>> tracker, so l4proto->destroy is always called.
> >>>>>
> >>>>
> >>>> I think the reason we unregister proto before remove all entries
> >>>> is to avoid new entry for this protocol being created.
> >>>>
> >>>> If we remove all contrack entries before unregistration, there maybe
> >>>> some new entries being created between nf_ct_iterate_cleanup and
> >>>> nf_conntrack_l4proto_unregister_net.this will cause some terrible things.
> >>>
> >>> Leaks are less likely to happen, but may well still happen while
> >>> racing with protocol removal, agreed.
> >>>
> >>>> SO I think we should make proto unavailable first,remove all entries next,
> >>>> and remove proto from nf_ct_protos arrays finally.
> >>>
> >>> Your proposal adds a branch in the packet path to fix an issue that is
> >>> specific of the GRE protocol tracker. In the current code, this fixes
> >>> the memory leak while removing the nf_conntrack_proto_gre module,
> >>> which is a rare operation.
> >>>
> >>> We have to come with a less intrusive solution.
> >>
> >> Wait. The existing code is calling nf_ct_gre_keymap_flush in
> >> proto_gre_net_exit path, so those keymap objects are not leaked.
> > 
> > Agree, it looks like nf_ct_gre_keymap_flush is added to solve this
> > problem.
> > 
> > Please ignore this patch.
> 
> I mean ignore the codes of gre part.
> I still think nf_ct_iterate_cleanup doesn't make sure all entries being
> destroyed.

There is another round of nf_ct_iterate cleanup in
nf_conntrack_cleanup_net. So I don't see any possible leak so far. Let
me know if you find anything.

Thanks.

^ permalink raw reply

* Re: [PATCH] drivers/net/wireless/ipw2x00: use strlcpy instead of strncpy
From: Chen Gang F T @ 2013-01-07  3:42 UTC (permalink / raw)
  To: Joe Perches; +Cc: Chen Gang, stas.yakovlev, linville, linux-wireless, netdev
In-Reply-To: <1357528746.4940.31.camel@joe-AO722>

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

于 2013年01月07日 11:19, Joe Perches 写道:
> On Mon, 2013-01-07 at 10:49 +0800, Chen Gang wrote:
>>   but I think the original author intended to use escaped instead of ssid
>>     DECLARE_SSID_BUF(ssid)  (line 5525, 5737)
>>     use ssid to print debug information directly
>>       (such as: line 5530..5535, 5545..5549, 5745..5749, ...)
>>     when need print additional information, use escaped
>>       (line 5559..5569, 5773..5782, 5791..5799)
>>
>>   so, I still suggest:
>>     only fix the bug (use strlcpy instead of strncpy)
>>     and not touch original features which orignal author intended using.
> 
> More likely John Linville just missed the conversions.
> 4+ years ago.
> 

  I wonder why it is not integrated into main branch.
    maybe we miss it.
      if so, I suggest to integrate it (better also add Reported-by gang.chen@asianux.com  :-) )
    maybe original author intended using short length.
      if so, I suggest to integrate my patch (using strlcpy instead of strncpy).

  for me:
    using long size instead of original short size, will change the output format.
    it seems not a good idea to change the original output format.
      (especially, the original output format has existence 4+ years).

  so, at least:
    for only fixing bug, not touching original features
      it is an executable method (is a valuable patch).
      although maybe it is not a best method (is not a very good patch).

 Regards

gchen.

> commit 9387b7caf3049168fc97a8a9111af8fe2143af18
> Author: John W. Linville <linville@tuxdriver.com>
> Date:   Tue Sep 30 20:59:05 2008 -0400
> 
>     wireless: use individual buffers for printing ssid values
>   
>     Also change escape_ssid to print_ssid to match print_mac semantics.
>     
>     Signed-off-by: John W. Linville <linville@tuxdriver.com>
> 
> Maybe these days this should be another vsprintf %p extension
> like %pM when the DECLARE_MAC_BUF/print_mac uses were converted.
> 
> (or maybe extend %ph for ssids with %*phs, length, array)
> 
> But if and until then, I suggest this instead:
> 
>  drivers/net/wireless/ipw2x00/ipw2200.c | 38 ++++++++++++++--------------------
>  1 file changed, 15 insertions(+), 23 deletions(-)
> 
> diff --git a/drivers/net/wireless/ipw2x00/ipw2200.c b/drivers/net/wireless/ipw2x00/ipw2200.c
> index 844f201..3dc6a92 100644
> --- a/drivers/net/wireless/ipw2x00/ipw2200.c
> +++ b/drivers/net/wireless/ipw2x00/ipw2200.c
> @@ -5556,15 +5556,12 @@ static int ipw_find_adhoc_network(struct ipw_priv *priv,
>  		    ((network->ssid_len != priv->essid_len) ||
>  		     memcmp(network->ssid, priv->essid,
>  			    min(network->ssid_len, priv->essid_len)))) {
> -			char escaped[IW_ESSID_MAX_SIZE * 2 + 1];
> +			DECLARE_SSID_BUF(escaped);
>  
> -			strncpy(escaped,
> -				print_ssid(ssid, network->ssid,
> -					   network->ssid_len),
> -				sizeof(escaped));
> -			IPW_DEBUG_MERGE("Network '%s (%pM)' excluded "
> -					"because of ESSID mismatch: '%s'.\n",
> -					escaped, network->bssid,
> +			IPW_DEBUG_MERGE("Network '%s (%pM)' excluded because of ESSID mismatch: '%s'\n",
> +					print_ssid(escaped, network->ssid,
> +						   network->ssid_len),
> +					network->bssid,
>  					print_ssid(ssid, priv->essid,
>  						   priv->essid_len));
>  			return 0;
> @@ -5770,14 +5767,11 @@ static int ipw_best_network(struct ipw_priv *priv,
>  		    ((network->ssid_len != priv->essid_len) ||
>  		     memcmp(network->ssid, priv->essid,
>  			    min(network->ssid_len, priv->essid_len)))) {
> -			char escaped[IW_ESSID_MAX_SIZE * 2 + 1];
> -			strncpy(escaped,
> -				print_ssid(ssid, network->ssid,
> -					   network->ssid_len),
> -				sizeof(escaped));
> -			IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded "
> -					"because of ESSID mismatch: '%s'.\n",
> -					escaped, network->bssid,
> +			DECLARE_SSID_BUF(escaped);
> +			IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded because of ESSID mismatch: '%s'\n",
> +					print_ssid(escaped, network->ssid,
> +						   network->ssid_len),
> +					network->bssid,
>  					print_ssid(ssid, priv->essid,
>  						   priv->essid_len));
>  			return 0;
> @@ -5787,13 +5781,11 @@ static int ipw_best_network(struct ipw_priv *priv,
>  	/* If the old network rate is better than this one, don't bother
>  	 * testing everything else. */
>  	if (match->network && match->network->stats.rssi > network->stats.rssi) {
> -		char escaped[IW_ESSID_MAX_SIZE * 2 + 1];
> -		strncpy(escaped,
> -			print_ssid(ssid, network->ssid, network->ssid_len),
> -			sizeof(escaped));
> -		IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded because "
> -				"'%s (%pM)' has a stronger signal.\n",
> -				escaped, network->bssid,
> +		DECLARE_SSID_BUF(escaped);
> +		IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded because '%s (%pM)' has a stronger signal\n",
> +				print_ssid(escaped, network->ssid,
> +					   network->ssid_len),
> +				network->bssid,
>  				print_ssid(ssid, match->network->ssid,
>  					   match->network->ssid_len),
>  				match->network->bssid);
> 
> 
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 


-- 
Chen Gang

Flying Transformer

[-- Attachment #2: chen_gang_flying_transformer.vcf --]
[-- Type: text/x-vcard, Size: 67 bytes --]

begin:vcard
fn:Chen Gang
n:;Chen Gang
version:2.1
end:vcard


^ permalink raw reply

* Re: [PATCH 19/19] netfilter: gre: fix resource leak when unregister gre proto
From: Gao feng @ 2013-01-07  3:43 UTC (permalink / raw)
  To: Pablo Neira Ayuso; +Cc: netfilter-devel, netdev, canqunzhang, kaber, ebiederm
In-Reply-To: <20130107032711.GA18953@1984>

On 01/07/13 11:27, Pablo Neira Ayuso wrote:
> On Mon, Jan 07, 2013 at 11:05:12AM +0800, Gao feng wrote:
>> On 01/07/13 10:59, Gao feng wrote:
>>> On 01/07/13 10:38, Pablo Neira Ayuso wrote:
>>>> On Mon, Jan 07, 2013 at 03:15:17AM +0100, Pablo Neira Ayuso wrote:
>>>>> Hi Gao,
>>>>>
>>>>> On Mon, Jan 07, 2013 at 09:27:37AM +0800, Gao feng wrote:
>>>>>> Hi Pablo,
>>>>>>
>>>>>> On 01/05/13 11:50, Pablo Neira Ayuso wrote:
>>>>>>> Hi Gao,
>>>>>>>
>>>>>>> On Fri, Dec 28, 2012 at 10:36:46AM +0800, Gao feng wrote:
>>>>>>>> Currectly we unregister proto before all conntrack entries of
>>>>>>>> this proto being destroyed. so in function destroy_conntrack
>>>>>>>> we can't find proper l4proto to call l4proto->destroy.
>>>>>>>> this will cause resource leak.
>>>>>>>
>>>>>>> Good catch.
>>>>>>>
>>>>>>> But better to remove the entries before unregistering the protocol
>>>>>>> tracker, so l4proto->destroy is always called.
>>>>>>>
>>>>>>
>>>>>> I think the reason we unregister proto before remove all entries
>>>>>> is to avoid new entry for this protocol being created.
>>>>>>
>>>>>> If we remove all contrack entries before unregistration, there maybe
>>>>>> some new entries being created between nf_ct_iterate_cleanup and
>>>>>> nf_conntrack_l4proto_unregister_net.this will cause some terrible things.
>>>>>
>>>>> Leaks are less likely to happen, but may well still happen while
>>>>> racing with protocol removal, agreed.
>>>>>
>>>>>> SO I think we should make proto unavailable first,remove all entries next,
>>>>>> and remove proto from nf_ct_protos arrays finally.
>>>>>
>>>>> Your proposal adds a branch in the packet path to fix an issue that is
>>>>> specific of the GRE protocol tracker. In the current code, this fixes
>>>>> the memory leak while removing the nf_conntrack_proto_gre module,
>>>>> which is a rare operation.
>>>>>
>>>>> We have to come with a less intrusive solution.
>>>>
>>>> Wait. The existing code is calling nf_ct_gre_keymap_flush in
>>>> proto_gre_net_exit path, so those keymap objects are not leaked.
>>>
>>> Agree, it looks like nf_ct_gre_keymap_flush is added to solve this
>>> problem.
>>>
>>> Please ignore this patch.
>>
>> I mean ignore the codes of gre part.
>> I still think nf_ct_iterate_cleanup doesn't make sure all entries being
>> destroyed.
> 
> There is another round of nf_ct_iterate cleanup in
> nf_conntrack_cleanup_net. So I don't see any possible leak so far. Let
> me know if you find anything.
> 

Ok,I am wrong...
Please ignore this patch. ;)

^ permalink raw reply

* Re: [PATCH net-next v3 0/3] netpoll: add IPv6 support
From: David Miller @ 2013-01-07  3:49 UTC (permalink / raw)
  To: amwang; +Cc: netdev
In-Reply-To: <1357527485.20798.4.camel@cr0>

From: Cong Wang <amwang@redhat.com>
Date: Mon, 07 Jan 2013 10:58:05 +0800

> On Thu, 2013-01-03 at 19:20 -0800, David Miller wrote:
>> From: Cong Wang <amwang@redhat.com>
>> Date: Fri,  4 Jan 2013 11:14:30 +0800
>> 
>> > (Resend with a cover letter)
>> > 
>> > v3: fix CONFIG_IPV6=m case
>> > 
>> > v2: use bool for ipv6 flag
>> >     fix !CONFIG_IPV6 case
>> > 
>> > This patchset implements netpoll over IPv6.
>> 
>> Thanks for submitting this properly.
>> 
>> But disallowing ipv6 netpoll support when IPV6=m is an unacceptable
>> limitation, compiling IPV6 as a module is common and in fact
>> recommended.
>> 
>> We've solved problems like this before, by putting the needed ipv6
>> routines into a seperate library that is built statically into the
>> kernel when necessary.
>> 
>> You should use a similar approach here.
> 
> Hmm, here we need ndisc_parse_options() and udp6_csum_init(). Not sure
> if both can be inlined?

I didn't say "inline", read my email again.

We put such routines into a static library of ipv6 routines
that gets statically built into vmlinux even if ipv6 is
modular.

I'm not explaining this agin.

^ permalink raw reply

* [PATCH] tcp: fix MSG_SENDPAGE_NOTLAST logic
From: Eric Dumazet @ 2013-01-07  4:21 UTC (permalink / raw)
  To: Willy Tarreau, David Miller; +Cc: netdev, linux-kernel
In-Reply-To: <20130106195359.GN16031@1wt.eu>

From: Eric Dumazet <edumazet@google.com>

commit 35f9c09fe9c72e (tcp: tcp_sendpages() should call tcp_push() once)
added an internal flag : MSG_SENDPAGE_NOTLAST meant to be set on all
frags but the last one for a splice() call.

The condition used to set the flag in pipe_to_sendpage() relied on
splice() user passing the exact number of bytes present in the pipe,
or a smaller one.

But some programs pass an arbitrary high value, and the test fails.

The effect of this bug is a lack of tcp_push() at the end of a
splice(pipe -> socket) call, and possibly very slow or erratic TCP
sessions.

We should both test sd->total_len and fact that another fragment
is in the pipe (pipe->nrbufs > 1)

Many thanks to Willy for providing very clear bug report, bisection
and test programs.

Reported-by: Willy Tarreau <w@1wt.eu>
Bisected-by: Willy Tarreau <w@1wt.eu>
Tested-by: Willy Tarreau <w@1wt.eu>
Signed-off-by: Eric Dumazet <edumazet@google.com>
---
 fs/splice.c |    4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/fs/splice.c b/fs/splice.c
index 8890604..6909d89 100644
--- a/fs/splice.c
+++ b/fs/splice.c
@@ -696,8 +696,10 @@ static int pipe_to_sendpage(struct pipe_inode_info *pipe,
 		return -EINVAL;
 
 	more = (sd->flags & SPLICE_F_MORE) ? MSG_MORE : 0;
-	if (sd->len < sd->total_len)
+
+	if (sd->len < sd->total_len && pipe->nrbufs > 1)
 		more |= MSG_SENDPAGE_NOTLAST;
+
 	return file->f_op->sendpage(file, buf->page, buf->offset,
 				    sd->len, &pos, more);
 }

^ permalink raw reply related

* Re: [PATCH V3 2/2] vhost: handle polling errors
From: Jason Wang @ 2013-01-07  4:38 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: kvm, eric.dumazet, netdev, linux-kernel, virtualization, davem
In-Reply-To: <20130106132201.GC18612@redhat.com>

On 01/06/2013 09:22 PM, Michael S. Tsirkin wrote:
> On Sun, Jan 06, 2013 at 03:18:38PM +0800, Jason Wang wrote:
>> Polling errors were ignored by vhost/vhost_net, this may lead to crash when
>> trying to remove vhost from waitqueue when after the polling is failed. Solve
>> this problem by:
>>
>> - checking the poll->wqh before trying to remove from waitqueue
>> - report an error when poll() returns a POLLERR in vhost_start_poll()
>> - report an error when vhost_start_poll() fails in
>>   vhost_vring_ioctl()/vhost_net_set_backend() which is used to notify the
>>   failure to userspace.
>> - report an error in the data path in vhost_net when meet polling errors.
>>
>> After those changes, we can safely drop the tx polling state in vhost_net since
>> it was replaced by the checking of poll->wqh.
>>
>> Signed-off-by: Jason Wang <jasowang@redhat.com>
>> ---
>>  drivers/vhost/net.c   |   74 ++++++++++++++++--------------------------------
>>  drivers/vhost/vhost.c |   31 +++++++++++++++-----
>>  drivers/vhost/vhost.h |    2 +-
>>  3 files changed, 49 insertions(+), 58 deletions(-)
>>
>> diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c
>> index d10ad6f..125c1e5 100644
>> --- a/drivers/vhost/net.c
>> +++ b/drivers/vhost/net.c
>> @@ -64,20 +64,10 @@ enum {
>>  	VHOST_NET_VQ_MAX = 2,
>>  };
>>  
>> -enum vhost_net_poll_state {
>> -	VHOST_NET_POLL_DISABLED = 0,
>> -	VHOST_NET_POLL_STARTED = 1,
>> -	VHOST_NET_POLL_STOPPED = 2,
>> -};
>> -
>>  struct vhost_net {
>>  	struct vhost_dev dev;
>>  	struct vhost_virtqueue vqs[VHOST_NET_VQ_MAX];
>>  	struct vhost_poll poll[VHOST_NET_VQ_MAX];
>> -	/* Tells us whether we are polling a socket for TX.
>> -	 * We only do this when socket buffer fills up.
>> -	 * Protected by tx vq lock. */
>> -	enum vhost_net_poll_state tx_poll_state;
>>  	/* Number of TX recently submitted.
>>  	 * Protected by tx vq lock. */
>>  	unsigned tx_packets;
>> @@ -155,24 +145,6 @@ static void copy_iovec_hdr(const struct iovec *from, struct iovec *to,
>>  	}
>>  }
>>  
>> -/* Caller must have TX VQ lock */
>> -static void tx_poll_stop(struct vhost_net *net)
>> -{
>> -	if (likely(net->tx_poll_state != VHOST_NET_POLL_STARTED))
>> -		return;
>> -	vhost_poll_stop(net->poll + VHOST_NET_VQ_TX);
>> -	net->tx_poll_state = VHOST_NET_POLL_STOPPED;
>> -}
>> -
>> -/* Caller must have TX VQ lock */
>> -static void tx_poll_start(struct vhost_net *net, struct socket *sock)
>> -{
>> -	if (unlikely(net->tx_poll_state != VHOST_NET_POLL_STOPPED))
>> -		return;
>> -	vhost_poll_start(net->poll + VHOST_NET_VQ_TX, sock->file);
>> -	net->tx_poll_state = VHOST_NET_POLL_STARTED;
>> -}
>> -
>>  /* In case of DMA done not in order in lower device driver for some reason.
>>   * upend_idx is used to track end of used idx, done_idx is used to track head
>>   * of used idx. Once lower device DMA done contiguously, we will signal KVM
>> @@ -227,6 +199,7 @@ static void vhost_zerocopy_callback(struct ubuf_info *ubuf, bool success)
>>  static void handle_tx(struct vhost_net *net)
>>  {
>>  	struct vhost_virtqueue *vq = &net->dev.vqs[VHOST_NET_VQ_TX];
>> +	struct vhost_poll *poll = net->poll + VHOST_NET_VQ_TX;
>>  	unsigned out, in, s;
>>  	int head;
>>  	struct msghdr msg = {
>> @@ -252,7 +225,8 @@ static void handle_tx(struct vhost_net *net)
>>  	wmem = atomic_read(&sock->sk->sk_wmem_alloc);
>>  	if (wmem >= sock->sk->sk_sndbuf) {
>>  		mutex_lock(&vq->mutex);
>> -		tx_poll_start(net, sock);
>> +		if (vhost_poll_start(poll, sock->file))
>> +			vq_err(vq, "Fail to start TX polling\n");
> s/Fail/Failed/
>
> A question though: how can this happen? Could you clarify please?
> Maybe we can find a way to prevent this error?

Two conditions I think this can happen:

1) a buggy userspace disable a queue through TUNSETQUEUE
2) the net device were gone

For 1, looks like we can delay the disabling until the refcnt goes to
zero. For 2 may needs more changes. Not sure it's worth to do this work,
maybe a warning is enough just like other failure.
>
>>  		mutex_unlock(&vq->mutex);
>>  		return;
>>  	}
>> @@ -261,7 +235,7 @@ static void handle_tx(struct vhost_net *net)
>>  	vhost_disable_notify(&net->dev, vq);
>>  
>>  	if (wmem < sock->sk->sk_sndbuf / 2)
>> -		tx_poll_stop(net);
>> +		vhost_poll_stop(poll);
>>  	hdr_size = vq->vhost_hlen;
>>  	zcopy = vq->ubufs;
>>  
>> @@ -283,8 +257,10 @@ static void handle_tx(struct vhost_net *net)
>>  
>>  			wmem = atomic_read(&sock->sk->sk_wmem_alloc);
>>  			if (wmem >= sock->sk->sk_sndbuf * 3 / 4) {
>> -				tx_poll_start(net, sock);
>> -				set_bit(SOCK_ASYNC_NOSPACE, &sock->flags);
>> +				if (vhost_poll_start(poll, sock->file))
>> +					vq_err(vq, "Fail to start TX polling\n");
>> +				else
>> +					set_bit(SOCK_ASYNC_NOSPACE, &sock->flags);
>>  				break;
>>  			}
>>  			/* If more outstanding DMAs, queue the work.
>> @@ -294,8 +270,10 @@ static void handle_tx(struct vhost_net *net)
>>  				    (vq->upend_idx - vq->done_idx) :
>>  				    (vq->upend_idx + UIO_MAXIOV - vq->done_idx);
>>  			if (unlikely(num_pends > VHOST_MAX_PEND)) {
>> -				tx_poll_start(net, sock);
>> -				set_bit(SOCK_ASYNC_NOSPACE, &sock->flags);
>> +				if (vhost_poll_start(poll, sock->file))
>> +					vq_err(vq, "Fail to start TX polling\n");
>> +				else
>> +					set_bit(SOCK_ASYNC_NOSPACE, &sock->flags);
>>  				break;
>>  			}
>>  			if (unlikely(vhost_enable_notify(&net->dev, vq))) {
>> @@ -360,7 +338,8 @@ static void handle_tx(struct vhost_net *net)
>>  			}
>>  			vhost_discard_vq_desc(vq, 1);
>>  			if (err == -EAGAIN || err == -ENOBUFS)
>> -				tx_poll_start(net, sock);
>> +				if (vhost_poll_start(poll, sock->file))
>> +					vq_err(vq, "Fail to start TX polling\n");
>>  			break;
>>  		}
>>  		if (err != len)
>> @@ -623,7 +602,6 @@ static int vhost_net_open(struct inode *inode, struct file *f)
>>  
>>  	vhost_poll_init(n->poll + VHOST_NET_VQ_TX, handle_tx_net, POLLOUT, dev);
>>  	vhost_poll_init(n->poll + VHOST_NET_VQ_RX, handle_rx_net, POLLIN, dev);
>> -	n->tx_poll_state = VHOST_NET_POLL_DISABLED;
>>  
>>  	f->private_data = n;
>>  
>> @@ -633,29 +611,25 @@ static int vhost_net_open(struct inode *inode, struct file *f)
>>  static void vhost_net_disable_vq(struct vhost_net *n,
>>  				 struct vhost_virtqueue *vq)
>>  {
>> +	struct vhost_poll *poll = n->poll + (vq - n->vqs);
>> +
>>  	if (!vq->private_data)
>>  		return;
>> -	if (vq == n->vqs + VHOST_NET_VQ_TX) {
>> -		tx_poll_stop(n);
>> -		n->tx_poll_state = VHOST_NET_POLL_DISABLED;
>> -	} else
>> -		vhost_poll_stop(n->poll + VHOST_NET_VQ_RX);
>> +	vhost_poll_stop(poll);
>>  }
>>  
>> -static void vhost_net_enable_vq(struct vhost_net *n,
>> +static int vhost_net_enable_vq(struct vhost_net *n,
>>  				struct vhost_virtqueue *vq)
>>  {
>>  	struct socket *sock;
>> +	struct vhost_poll *poll = n->poll + (vq - n->vqs);
>>  
>>  	sock = rcu_dereference_protected(vq->private_data,
>>  					 lockdep_is_held(&vq->mutex));
>>  	if (!sock)
>> -		return;
>> -	if (vq == n->vqs + VHOST_NET_VQ_TX) {
>> -		n->tx_poll_state = VHOST_NET_POLL_STOPPED;
>> -		tx_poll_start(n, sock);
>> -	} else
>> -		vhost_poll_start(n->poll + VHOST_NET_VQ_RX, sock->file);
>> +		return 0;
>> +
>> +	return vhost_poll_start(poll, sock->file);
>>  }
>>  
>>  static struct socket *vhost_net_stop_vq(struct vhost_net *n,
>> @@ -833,7 +807,9 @@ static long vhost_net_set_backend(struct vhost_net *n, unsigned index, int fd)
>>  		r = vhost_init_used(vq);
>>  		if (r)
>>  			goto err_used;
>> -		vhost_net_enable_vq(n, vq);
>> +		r = vhost_net_enable_vq(n, vq);
>> +		if (r)
>> +			goto err_used;
>>  
>>  		oldubufs = vq->ubufs;
>>  		vq->ubufs = ubufs;
>> diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c
>> index 34389f7..5c7a466 100644
>> --- a/drivers/vhost/vhost.c
>> +++ b/drivers/vhost/vhost.c
>> @@ -77,26 +77,41 @@ void vhost_poll_init(struct vhost_poll *poll, vhost_work_fn_t fn,
>>  	init_poll_funcptr(&poll->table, vhost_poll_func);
>>  	poll->mask = mask;
>>  	poll->dev = dev;
>> +	poll->wqh = NULL;
>>  
>>  	vhost_work_init(&poll->work, fn);
>>  }
>>  
>> +/* Stop polling a file. After this function returns, it becomes safe to drop the
>> + * file reference. You must also flush afterwards. */
>> +void vhost_poll_stop(struct vhost_poll *poll)
>> +{
>> +	if (poll->wqh) {
>> +		remove_wait_queue(poll->wqh, &poll->wait);
>> +		poll->wqh = NULL;
>> +	}
>> +}
>> +
>>  /* Start polling a file. We add ourselves to file's wait queue. The caller must
>>   * keep a reference to a file until after vhost_poll_stop is called. */
>> -void vhost_poll_start(struct vhost_poll *poll, struct file *file)
>> +int vhost_poll_start(struct vhost_poll *poll, struct file *file)
>>  {
>>  	unsigned long mask;
>> +	int ret = 0;
>> +
>> +	if (poll->wqh)
>> +		return -EBUSY;
>>  
> I think this should return success: we are already polling.
> Otherwise this would trigger a bug below I think.

Ok.
>
>>  	mask = file->f_op->poll(file, &poll->table);
>>  	if (mask)
>>  		vhost_poll_wakeup(&poll->wait, 0, 0, (void *)mask);
>> -}
>>  
>> -/* Stop polling a file. After this function returns, it becomes safe to drop the
>> - * file reference. You must also flush afterwards. */
>> -void vhost_poll_stop(struct vhost_poll *poll)
>> -{
>> -	remove_wait_queue(poll->wqh, &poll->wait);
>> +	if (mask & POLLERR) {
>> +		ret = -EINVAL;
>> +		vhost_poll_stop(poll);
>> +	}
>> +
>> +	return ret;
>>  }
>>  
>>  static bool vhost_work_seq_done(struct vhost_dev *dev, struct vhost_work *work,
>> @@ -792,7 +807,7 @@ long vhost_vring_ioctl(struct vhost_dev *d, int ioctl, void __user *argp)
>>  		fput(filep);
>>  
>>  	if (pollstart && vq->handle_kick)
>> -		vhost_poll_start(&vq->poll, vq->kick);
>> +		r = vhost_poll_start(&vq->poll, vq->kick);
>>  
>>  	mutex_unlock(&vq->mutex);
>>  
>> diff --git a/drivers/vhost/vhost.h b/drivers/vhost/vhost.h
>> index 2639c58..17261e2 100644
>> --- a/drivers/vhost/vhost.h
>> +++ b/drivers/vhost/vhost.h
>> @@ -42,7 +42,7 @@ void vhost_work_queue(struct vhost_dev *dev, struct vhost_work *work);
>>  
>>  void vhost_poll_init(struct vhost_poll *poll, vhost_work_fn_t fn,
>>  		     unsigned long mask, struct vhost_dev *dev);
>> -void vhost_poll_start(struct vhost_poll *poll, struct file *file);
>> +int vhost_poll_start(struct vhost_poll *poll, struct file *file);
>>  void vhost_poll_stop(struct vhost_poll *poll);
>>  void vhost_poll_flush(struct vhost_poll *poll);
>>  void vhost_poll_queue(struct vhost_poll *poll);
>> -- 
>> 1.7.1
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* [PATCH] drivers/net/wireless/iwlegacy: use strlcpy instead of strncpy
From: Chen Gang @ 2013-01-07  4:42 UTC (permalink / raw)
  To: sgruszka, linville; +Cc: linux-wireless, netdev


  The fields must be null-terminated, or simple_strtoul will cause issue.

Signed-off-by: Chen Gang <gang.chen@asianux.com>
---
 drivers/net/wireless/iwlegacy/3945-mac.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/iwlegacy/3945-mac.c b/drivers/net/wireless/iwlegacy/3945-mac.c
index d604b40..3726cd6 100644
--- a/drivers/net/wireless/iwlegacy/3945-mac.c
+++ b/drivers/net/wireless/iwlegacy/3945-mac.c
@@ -3273,7 +3273,7 @@ il3945_store_measurement(struct device *d, struct device_attribute *attr,
 
 	if (count) {
 		char *p = buffer;
-		strncpy(buffer, buf, min(sizeof(buffer), count));
+		strlcpy(buffer, buf, sizeof(buffer));
 		channel = simple_strtoul(p, NULL, 0);
 		if (channel)
 			params.channel = channel;
-- 
1.7.10.4

^ permalink raw reply related

* [RFC PATCH] vsprintf: Add %p*D extension for 80211 SSIDs
From: Joe Perches @ 2013-01-07  4:49 UTC (permalink / raw)
  To: John W. Linville; +Cc: Chen Gang, stas.yakovlev, linux-wireless, netdev
In-Reply-To: <1357528746.4940.31.camel@joe-AO722>

On Sun, 2013-01-06 at 19:19 -0800, Joe Perches wrote:
> Maybe these days this should be another vsprintf %p extension
> like %pM when the DECLARE_MAC_BUF/print_mac uses were converted.
> 
> (or maybe extend %ph for ssids with %*phs, length, array)

Maybe like this:

 lib/vsprintf.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 55 insertions(+), 2 deletions(-)

diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index fab33a9..98916a0 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -26,6 +26,7 @@
 #include <linux/math64.h>
 #include <linux/uaccess.h>
 #include <linux/ioport.h>
+#include <linux/ieee80211.h>
 #include <net/addrconf.h>
 
 #include <asm/page.h>		/* for PAGE_SIZE */
@@ -660,10 +661,59 @@ char *resource_string(char *buf, char *end, struct resource *res,
 }
 
 static noinline_for_stack
+char *ssid_string(char *buf, char *end, u8 *addr, struct printf_spec spec,
+		  const char *fmt)
+{
+	int i, len = 1;		/* if we pass %*p, field width remains
+				   negative value, fallback to the default */
+
+	if (spec.field_width == 0)
+		/* nothing to print */
+		return buf;
+
+	if (ZERO_OR_NULL_PTR(addr))
+		/* NULL pointer */
+		return string(buf, end, NULL, spec);
+
+	if (spec.field_width > 0)
+		len = min_t(int, spec.field_width, IEEE80211_MAX_SSID_LEN);
+
+	for (i = 0; i < len && buf < end; i++) {
+		if (isprint(addr[i])) {
+			*buf++ = addr[i];
+			continue;
+		}
+		*buf++ = '\\';
+		if (buf >= end)
+			continue;
+		if (addr[i] == '\0')
+			*buf++ = '0';
+		else if (addr[i] == '\n')
+			*buf++ = 'n';
+		else if (addr[i] == '\r')
+			*buf++ = 'r';
+		else if (addr[i] == '\t')
+			*buf++ = 't';
+		else if (addr[i] == '\\')
+			*buf++ = '\\';
+		else {
+			if (buf < end)
+				*buf++ = ((addr[i] >> 6) & 7) + '0';
+			if (buf < end)
+				*buf++ = ((addr[i] >> 3) & 7) + '0';
+			if (buf < end)
+				*buf++ = ((addr[i] >> 0) & 7) + '0';
+		}
+	}
+
+	return buf;
+}
+
+static noinline_for_stack
 char *hex_string(char *buf, char *end, u8 *addr, struct printf_spec spec,
 		 const char *fmt)
 {
-	int i, len = 1;		/* if we pass '%ph[CDN]', field witdh remains
+	int i, len = 1;		/* if we pass '%ph[CDN]', field width remains
 				   negative value, fallback to the default */
 	char separator;
 
@@ -695,7 +745,6 @@ char *hex_string(char *buf, char *end, u8 *addr, struct printf_spec spec,
 
 	for (i = 0; i < len && buf < end - 1; i++) {
 		buf = hex_byte_pack(buf, addr[i]);
-
 		if (buf < end && separator && i != len - 1)
 			*buf++ = separator;
 	}
@@ -1016,6 +1065,8 @@ int kptr_restrict __read_mostly;
  *             [0][1][2][3]-[4][5]-[6][7]-[8][9]-[10][11][12][13][14][15]
  *           little endian output byte order is:
  *             [3][2][1][0]-[5][4]-[7][6]-[8][9]-[10][11][12][13][14][15]
+ * - 'D' For a 80211 SSID, it prints the SSID escaping any non-printable
+         characters with a leading \ and octal or [0nrt\]
  * - 'V' For a struct va_format which contains a format string * and va_list *,
  *       call vsnprintf(->format, *->va_list).
  *       Implements a "recursive vsnprintf".
@@ -1088,6 +1139,8 @@ char *pointer(const char *fmt, char *buf, char *end, void *ptr,
 		break;
 	case 'U':
 		return uuid_string(buf, end, ptr, spec, fmt);
+	case 'D':
+		return ssid_string(buf, end, ptr, spec, fmt);
 	case 'V':
 		{
 			va_list va;

^ permalink raw reply related

* Re: Bug#697357: bridging broken over bond interfaces
From: Ben Hutchings @ 2013-01-07  4:58 UTC (permalink / raw)
  To: netdev
  Cc: Bastian Blank, 697357, Peter Palfrader, Stephen Hemminger,
	Jay Vosburgh, Andy Gospodarek
In-Reply-To: <20130104124012.GH14827@anguilla.noreply.org>

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

Forwarding this to netdev since the bug is still present in Linux 3.7.1.
For those joining us, this thread is archive at
<http://bugs.debian.org/697357>.

On Fri, 2013-01-04 at 13:40 +0100, Peter Palfrader wrote:
> On Fri, 04 Jan 2013, Bastian Blank wrote:
> 
> > On Fri, Jan 04, 2013 at 12:17:12PM +0100, Peter Palfrader wrote:
> > > I tried to set up a new KVM host in the usual way:
> > >   - have a bond0 interface over all physcial eth* interfaces
> > >   - create a br0 over that bond0 and any vnet* interfaces for the
> > >     guests.
> 
> Also, arp works through the bridge, forgot to mention that.
> 
> > > *   Manually switching the eth* to promiscious mode makes stuff work.
> > 
> > Okay, so a workaround is available.
> > 
> > When did it last work? Does it work with the kernel from experimental?
> 
> It works nicely on stable, e.g. pasquini.debian.org:
> 
> | weasel@pasquini:~$ sudo brctl show
> | bridge name     bridge id               STP enabled     interfaces
> | br0             8000.e83935a9ec10       no              bond0
> |                                                         tap0
> |                                                         tap1
> |                                                         tap2
> | br1             8000.e83935a9ec10       no              bond0.221
> | br2             8000.da1343affe92       no              bond0.3301
> |                                                         tap3
> 
> And there the bond interface is promisc automatically:
> weasel@pasquini:~$ ip a | grep -i bond
> | 2: eth0: <BROADCAST,MULTICAST,SLAVE,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master bond0 state UP qlen 1000
> | 3: eth1: <BROADCAST,MULTICAST,SLAVE,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master bond0 state UP qlen 1000
> | 4: bond0: <BROADCAST,MULTICAST,PROMISC,MASTER,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP 
> | 7: bond0.221@bond0: <BROADCAST,MULTICAST,MASTER,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP 
> | 9: bond0.3301@bond0: <BROADCAST,MULTICAST,MASTER,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP 
> 
> Likewise it works as expected when one does br directly on eth0, without any
> bonding.
> 
> It's also broken with linux-image-3.7-trunk-amd64_3.7.1-1~experimental.1_amd64.deb.

-- 
Ben Hutchings
If you seem to know what you are doing, you'll be given more to do.

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 828 bytes --]

^ permalink raw reply

* Re: [PATCH] tcp: fix MSG_SENDPAGE_NOTLAST logic
From: David Miller @ 2013-01-07  4:59 UTC (permalink / raw)
  To: eric.dumazet; +Cc: w, netdev, linux-kernel
In-Reply-To: <1357532509.6919.1715.camel@edumazet-glaptop>

From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Sun, 06 Jan 2013 20:21:49 -0800

> From: Eric Dumazet <edumazet@google.com>
> 
> commit 35f9c09fe9c72e (tcp: tcp_sendpages() should call tcp_push() once)
> added an internal flag : MSG_SENDPAGE_NOTLAST meant to be set on all
> frags but the last one for a splice() call.
> 
> The condition used to set the flag in pipe_to_sendpage() relied on
> splice() user passing the exact number of bytes present in the pipe,
> or a smaller one.
> 
> But some programs pass an arbitrary high value, and the test fails.
> 
> The effect of this bug is a lack of tcp_push() at the end of a
> splice(pipe -> socket) call, and possibly very slow or erratic TCP
> sessions.
> 
> We should both test sd->total_len and fact that another fragment
> is in the pipe (pipe->nrbufs > 1)
> 
> Many thanks to Willy for providing very clear bug report, bisection
> and test programs.
> 
> Reported-by: Willy Tarreau <w@1wt.eu>
> Bisected-by: Willy Tarreau <w@1wt.eu>
> Tested-by: Willy Tarreau <w@1wt.eu>
> Signed-off-by: Eric Dumazet <edumazet@google.com>

Applied and queued up for -stable, thanks everyone.

^ 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