* [PATCH] net: wireless: intel: iwlwifi: dvm: fix tid mask
From: Seraphime Kirkovski @ 2017-06-07 22:33 UTC (permalink / raw)
To: luca
Cc: Seraphime Kirkovski, Johannes Berg, Emmanuel Grumbach,
Luca Coelho, Intel Linux Wireless, Kalle Valo,
open list:INTEL WIRELESS WIFI LINK (iwlwifi),
open list:NETWORKING DRIVERS, open list
Currently the tid mask covers the first 4 bits of iwlagn_tx_resp::ra_tid,
which gives 16 possible values for tid.
This is problematic because IWL_MAX_TID_COUNT is 8, so indexing
iwl_priv::tid_data can go very wrong.
With UBSAN I can it happening while establishing the first connection
after module load.
[ 272.143440] UBSAN: Undefined behaviour in drivers/net/wireless/intel/iwlwifi/dvm/tx.c:777:32
[ 272.143447] index 8 is out of range for type 'iwl_tid_data [8]'
[ 272.143457] CPU: 0 PID: 4605 Comm: irq/32-iwlwifi Not tainted 4.12.0-dirty #2
[ 272.143460] Hardware name: Hewlett-Packard HP EliteBook 2560p/162B, BIOS 68SSU Ver. F.02 07/26/2011
[ 272.143462] Call Trace:
[ 272.143472] dump_stack+0x9c/0x10b
[ 272.143477] ? _atomic_dec_and_lock+0x285/0x285
[ 272.143486] ubsan_epilogue+0xd/0x4e
[ 272.143493] __ubsan_handle_out_of_bounds+0xef/0x118
[ 272.143498] ? __ubsan_handle_shift_out_of_bounds+0x221/0x221
[ 272.143519] ? iwl_trans_pcie_reclaim+0x153/0xc90 [iwlwifi]
[ 272.143539] iwlagn_check_ratid_empty+0x337/0x410 [iwldvm]
[ 272.143556] ? iwl_hcmd_names_cmp+0x2f/0x60 [iwlwifi]
[ 272.143571] iwlagn_rx_reply_tx+0x8a4/0x1820 [iwldvm]
Signed-off-by: Seraphime Kirkovski <kirkseraph@gmail.com>
---
I'm currently running this patch on my machines and I have wifi.
The patch presumes а cleanup patch, I sent yesterday:
https://www.spinics.net/lists/kernel/msg2526314.html
drivers/net/wireless/intel/iwlwifi/dvm/commands.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/commands.h b/drivers/net/wireless/intel/iwlwifi/dvm/commands.h
index 37d2ba5ae852..e5994df9ea4c 100644
--- a/drivers/net/wireless/intel/iwlwifi/dvm/commands.h
+++ b/drivers/net/wireless/intel/iwlwifi/dvm/commands.h
@@ -1448,7 +1448,7 @@ struct agg_tx_status {
*/
/* refer to ra_tid */
#define IWLAGN_TX_RES_TID_POS 0
-#define IWLAGN_TX_RES_TID_MSK 0x0f
+#define IWLAGN_TX_RES_TID_MSK 0x07
#define IWLAGN_TX_RES_RA_POS 4
#define IWLAGN_TX_RES_RA_MSK 0xf0
--
2.11.0
^ permalink raw reply related
* Question about tcp_filter() in tcp_v6_do_rcv()
From: Chenbo Feng @ 2017-06-07 22:35 UTC (permalink / raw)
To: netdev; +Cc: Lorenzo Colitti, Alexei Starovoitov, Daniel Borkmann, Chenbo Feng
Hello everybody,
I am testing eBPF programs on ipv6 and I just find out the tcp_filter()
function (previously named sk_filter()) is called both in tcp_v6_rcv()
and tcp_v6_do_rcv(). In contrast, it is only called by tcp_v4_rcv() in
ipv4 layer. I guess this implementation is used to capture some corner
cases in ipv6 ingress route but I cannot find why. Could I know why we
need this in two similar places in ipv6 transportation layer?
I have tried to dig into the commit history and the related code path
but I did not see any obvious reason for doing so. And my problem with
it is when a eBPF program is attached to a socket or a cgroup in ingress
side, the filter program will be applied on some packets twice. And it
affect the accuracy when using eBPF program for traffic accounting.
Thanks!
Chenbo Feng
^ permalink raw reply
* Re: ath9k_htc - Division by zero in kernel (as well as firmware panic)
From: Tobias Diedrich @ 2017-06-07 22:39 UTC (permalink / raw)
To: Oleksij Rempel
Cc: Nathan Royce, QCA ath9k Development, Kalle Valo, linux-wireless,
netdev, linux-kernel, ath9k_htc_fw
In-Reply-To: <92468e50-409f-c54f-8bf8-87587061d98e@rempel-privat.de>
[-- Attachment #1: Type: text/plain, Size: 14410 bytes --]
Oleksij Rempel wrote:
> Am 07.06.2017 um 02:12 schrieb Tobias Diedrich:
> > Oleksij Rempel wrote:
> >> Yes, this is "normal" problem. The firmware has no error handler for PCI
> >> bus related exceptions. So if we filed to read PCI bus first time, we
> >> have choice to Ooops and stall or Ooops and reboot ASAP. So we reboot
> >> and provide an kernel "firmware panic!" message.
> >> Every one who can or will to fix this, is welcome.
> >>
> >>> *****
> >>> Jun 02 14:55:30 computer kernel: usb 1-1.1: ath: firmware panic!
> >>> exccause: 0x0000000d; pc: 0x0090ae81; badvaddr: 0x10ff4038.
> > [...]
> >
> >> memdmp 50ae78 50ae88
> >
> > 50ae78: 6c10 0412 6aa2 0c02 0088 20c0 2008 1940 l...j..........@
> >
> > [...copy to bin...]
> > $ bin/objdump -b binary -m xtensa -D /tmp/memdump.bin
> > [..]
> > 0: 6c1004 entry a1, 32
> > 3: 126aa2 l32r a2, 0xfffdaa8c
> > 6: 0c0200 memw
> > 9: 8820 l32i.n a8, a2, 0 <----------Exception cause PC still points at load
> > b: c020 movi.n a2, 0
> > d: 081940 extui a9, a8, 1, 1
> >
> > Judging from that it should be fairly simple to at least implement
> > some sort of retry, possible after triggering a PCIe link retrain?
>
> I assume, yes.
>
> > There are some related PCIe root complex registers that may point to
> > what exactly failed if they were dumped.
> >
> > The root complex registers live at 0x00040000 and I think match the
> > registers described for the root complex in the AR9344 datasheet.
>
> Suddenly I don't have ar7010 docs to tell..
>
> > PCIE_INT_MASK would map to 0x40050 and has a bit for SYS_ERR:
> > "A system error. The RC Core asserts CFG_SYS_ERR_RC if any device in
> > the hierarchy reports any of the following errors and the associated
> > enable bit is set in the Root Control register: ERR_COR, ERR_FATAL,
> > ERR_NONFATAL."
> >
> > AFAICS link retrain can be done by setting bit3 (INIT_RST,
> > "Application request to initiate a training reset") in
> > PCIE_APP (0x40000).
> >
> > See sboot/magpie_1_1/sboot/cmnos/eeprom/src/cmnos_eeprom.c (which
> > flips some bits in the RC to enable the PCIe bus for reading the
> > EEPROM).
> >
> > The root complex pci configuration space is at 0x20000 which could
> > have further error details:
> >> memdmp 20000 20200
> >
> > 020000: a02a 168c 0010 0006 0000 0001 0001 0000 .*..............
> > 020010: 0000 0000 0000 0000 0000 0000 0000 0000 ................
> > 020020: 0000 0000 0000 0000 0000 0000 0000 0000 ................
> > 020030: 0000 0000 0000 0040 0000 0000 0000 01ff .......@........
> > 020040: 5bc3 5001 0000 0000 0000 0000 0000 0000 [.P.............
> > 020050: 0080 7005 0000 0000 0000 0000 0000 0000 ..p.............
> > 020060: 0000 0000 0000 0000 0000 0000 0000 0000 ................
> > 020070: 0042 0010 0000 8701 0000 2010 0013 4411 .B............D.
> > 020080: 3011 0000 0000 0000 00c0 03c0 0000 0000 0...............
> > 020090: 0000 0000 0000 0010 0000 0000 0000 0000 ................
> > 0200a0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
> > 0200b0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
> > 0200c0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
> > 0200d0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
> > 0200e0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
> > 0200f0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
> > 020100: 1401 0001 0000 0000 0000 0000 0006 2030 ...............0
> > 020110: 0000 0000 0000 2000 0000 00a0 0000 0000 ................
> > 020120: 0000 0000 0000 0000 0000 0000 0000 0000 ................
> > 020130: 0000 0000 0000 0000 0000 0000 0000 0000 ................
> > 020140: 0001 0002 0000 0000 0000 0000 0000 0000 ................
> > 020150: 0000 0000 8000 00ff 0000 0000 0000 0000 ................
> > 020160: 0000 0000 0000 0000 0000 0000 0000 0000 ................
> > 020170: 0000 0000 0000 0000 0000 0000 0000 0000 ................
> > 020180: 0000 0000 0000 0000 0000 0000 0000 0000 ................
> > 020190: 0000 0000 0000 0000 0000 0000 0000 0000 ................
> > 0201a0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
> > 0201b0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
> > 0201c0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
> > 0201d0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
> > 0201e0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
> > 0201f0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
> >
> > Transformed into something suitable for feeding into lspci -F:
> >
> > 00:00.0 Description filled in by lspci
> > 00: 8c 16 2a a0 06 00 10 00 01 00 00 00 00 00 01 00
> > 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> > 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> > 30: 00 00 00 00 40 00 00 00 00 00 00 00 ff 01 00 00
> > 40: 01 50 c3 5b 00 00 00 00 00 00 00 00 00 00 00 00
> > 50: 05 70 80 00 00 00 00 00 00 00 00 00 00 00 00 00
> > 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> > 70: 10 00 42 00 01 87 00 00 10 20 00 00 11 44 13 00
> > 80: 00 00 11 30 00 00 00 00 c0 03 c0 00 00 00 00 00
> > 90: 00 00 00 00 10 00 00 00 00 00 00 00 00 00 00 00
> > a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> > b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> > c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> > d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> > e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> > f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> >
> > $ lspci -F /tmp/hexdump -vvv
> > 00:00.0 Non-VGA unclassified device: Qualcomm Atheros Device a02a (rev 01)
> > !!! Invalid class 0000 for header type 01
> > Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx-
> > Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
> > Latency: 0
> > Interrupt: pin A routed to IRQ 255
> > Bus: primary=00, secondary=00, subordinate=00, sec-latency=0
> > I/O behind bridge: 00000000-00000fff
> > Memory behind bridge: 00000000-000fffff
> > Prefetchable memory behind bridge: 00000000-000fffff
> > Secondary status: 66MHz- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- <SERR- <PERR-
> > BridgeCtl: Parity- SERR- NoISA- VGA- MAbort- >Reset- FastB2B-
> > PriDiscTmr- SecDiscTmr- DiscTmrStat- DiscTmrSERREn-
> > Capabilities: [40] Power Management version 3
> > Flags: PMEClk- DSI- D1+ D2- AuxCurrent=375mA PME(D0+,D1+,D2-,D3hot+,D3cold-)
> > Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=0 PME-
> > Capabilities: [50] MSI: Enable- Count=1/1 Maskable- 64bit+
> > Address: 0000000000000000 Data: 0000
> > Capabilities: [70] Express (v2) Root Port (Slot-), MSI 00
> > DevCap: MaxPayload 256 bytes, PhantFunc 0
> > ExtTag- RBE+
> > DevCtl: Report errors: Correctable- Non-Fatal- Fatal- Unsupported-
> > RlxdOrd+ ExtTag- PhantFunc- AuxPwr- NoSnoop-
> > MaxPayload 128 bytes, MaxReadReq 512 bytes
> > DevSta: CorrErr- UncorrErr- FatalErr- UnsuppReq- AuxPwr- TransPend-
> > LnkCap: Port #0, Speed 2.5GT/s, Width x1, ASPM L0s, Exit Latency L0s <1us, L1 <64us
> > ClockPM- Surprise- LLActRep+ BwNot- ASPMOptComp-
> > LnkCtl: ASPM Disabled; RCB 64 bytes Disabled- CommClk-
> > ExtSynch- ClockPM- AutWidDis- BWInt- AutBWInt-
> > LnkSta: Speed 2.5GT/s, Width x1, TrErr- Train- SlotClk+ DLActive+ BWMgmt- ABWMgmt-
> > RootCtl: ErrCorrectable- ErrNon-Fatal- ErrFatal- PMEIntEna- CRSVisible-
> > RootCap: CRSVisible-
> > RootSta: PME ReqID 0000, PMEStatus- PMEPending-
> > DevCap2: Completion Timeout: Not Supported, TimeoutDis+, LTR-, OBFF Not Supported ARIFwd-
> > DevCtl2: Completion Timeout: 50us to 50ms, TimeoutDis-, LTR-, OBFF Disabled ARIFwd-
> > LnkCtl2: Target Link Speed: 2.5GT/s, EnterCompliance- SpeedDis-
> > Transmit Margin: Normal Operating Range, EnterModifiedCompliance- ComplianceSOS-
> > Compliance De-emphasis: -6dB
> > LnkSta2: Current De-emphasis Level: -6dB, EqualizationComplete-, EqualizationPhase1-
> > EqualizationPhase2-, EqualizationPhase3-, LinkEqualizationRequest-
> >
>
> Looks promising :)
>
POC seems to work, though this may additionally need to restore wifi
state as well, no guarantees there.
>str 40018 3
00040018 : 00000003
>
Retry(1) failed PCIe access @0x10ff4038
Before: int_mask=0 app=ffc1 reset=0
After: int_mask=0 app=ffc1 reset=7
wlan int status=0
>str 40018 3
00040018 : 00000003
>
Retry(1) failed PCIe access @0x10ff4038
Before: int_mask=0 app=ffc1 reset=0
After: int_mask=0 app=ffc1 reset=7
wlan int status=0
>
diff --git a/target_firmware/magpie_fw_dev/target/init/app_start.c b/target_firmware/magpie_fw_dev/target/init/app_start.c
index 8fa9c8b..fea62c1 100644
--- a/target_firmware/magpie_fw_dev/target/init/app_start.c
+++ b/target_firmware/magpie_fw_dev/target/init/app_start.c
@@ -137,6 +137,13 @@ void __section(boot) __noreturn __visible app_start(void)
A_PRINTF(" A_WDT_INIT()\n\r");
+#if defined(PROJECT_MAGPIE)
+ // For some reason needs to be called again here for the
+ // exception handlers to work properly, at least on the XBOX
+ // adapter.
+ fatal_exception_func();
+#endif
+
#if defined(PROJECT_K2)
save_cmnos_printf = fw_cmnos_printf;
#endif
diff --git a/target_firmware/magpie_fw_dev/target/init/init.c b/target_firmware/magpie_fw_dev/target/init/init.c
index 7484c05..cad2519 100755
--- a/target_firmware/magpie_fw_dev/target/init/init.c
+++ b/target_firmware/magpie_fw_dev/target/init/init.c
@@ -212,6 +212,78 @@ LOCAL void zfGenWrongEpidEvent(uint32_t epid)
mUSB_EP3_XFER_DONE();
}
+static void
+AR7010_pcie_reset(void)
+{
+#define PCIE_RC_ACCESS_DELAY 20
+
+#define PCI_RC_RESET_BIT BIT6
+#define PCI_RC_PHY_RESET_BIT BIT7
+#define PCI_RC_PLL_RESET_BIT BIT8
+#define PCI_RC_PHY_SHIFT_RESET_BIT BIT10
+
+#define HAL_WORD_REG_WRITE(addr, val) do { *((uint32_t*)(addr)) = val; } while (0)
+#define HAL_WORD_REG_READ(addr) (*((uint32_t*)(addr)))
+
+#define CMD_PCI_RC_RESET_ON() HAL_WORD_REG_WRITE(MAGPIE_REG_RST_RESET_ADDR, \
+ (HAL_WORD_REG_READ(MAGPIE_REG_RST_RESET_ADDR)| \
+ (PCI_RC_PHY_SHIFT_RESET_BIT|PCI_RC_PLL_RESET_BIT|PCI_RC_PHY_RESET_BIT|PCI_RC_RESET_BIT)))
+
+#define CMD_PCI_RC_RESET_CLR() HAL_WORD_REG_WRITE(MAGPIE_REG_RST_RESET_ADDR, \
+ (HAL_WORD_REG_READ(MAGPIE_REG_RST_RESET_ADDR)& \
+ (~(PCI_RC_PHY_SHIFT_RESET_BIT|PCI_RC_PLL_RESET_BIT|PCI_RC_PHY_RESET_BIT|PCI_RC_RESET_BIT))))
+
+ int i;
+
+ CMD_PCI_RC_RESET_ON();
+ A_DELAY_USECS(PCIE_RC_ACCESS_DELAY);
+
+ /* dereset the reset */
+ CMD_PCI_RC_RESET_CLR();
+ A_DELAY_USECS(500);
+
+ /* 7. set bus master and memory space enable */
+ DEBUG_SYSTEM_STATE = (DEBUG_SYSTEM_STATE&(~0xff)) | 0x45;
+ HAL_WORD_REG_WRITE(0x00020004, (HAL_WORD_REG_READ(0x00020004)|(BIT1|BIT2)));
+ A_DELAY_USECS(PCIE_RC_ACCESS_DELAY);
+
+ /* 7.5. asser pcie_ep reset */
+ HAL_WORD_REG_WRITE(0x00040018, (HAL_WORD_REG_READ(0x00040018) & ~(0x1 << 2)));
+ A_DELAY_USECS(PCIE_RC_ACCESS_DELAY);
+
+ /* 7.5. de-asser pcie_ep reset */
+ HAL_WORD_REG_WRITE(0x00040018, (HAL_WORD_REG_READ(0x00040018)|(0x1 << 2)));
+ A_DELAY_USECS(PCIE_RC_ACCESS_DELAY);
+
+ /* 8. set app_ltssm_enable */
+ DEBUG_SYSTEM_STATE = (DEBUG_SYSTEM_STATE&(~0xff)) | 0x46;
+ HAL_WORD_REG_WRITE(0x00040000, (HAL_WORD_REG_READ(0x00040000)|0xffc1));
+
+ /*!
+ * Receive control (PCIE_RESET),
+ * 0x40018, BIT0: LINK_UP, PHY Link up -PHY Link up/down indicator
+ * in case the link up is not ready and we access the 0x14000000,
+ * vmc will hang here
+ */
+
+ /* poll 0x40018/bit0 (1000 times) until it turns to 1 */
+ i = 10000;
+ while(i-->0)
+ {
+ uint32_t reg_value = HAL_WORD_REG_READ(0x00040018);
+ if( reg_value & BIT0 )
+ break;
+ A_DELAY_USECS(PCIE_RC_ACCESS_DELAY);
+ }
+
+ HAL_WORD_REG_WRITE(0x14000004, (HAL_WORD_REG_READ(0x14000004)|0x116));
+ A_DELAY_USECS(PCIE_RC_ACCESS_DELAY);
+
+ HAL_WORD_REG_WRITE(0x14000010, (HAL_WORD_REG_READ(0x14000010)|EEPROM_CTRL_BASE));
+}
+
+static int exception_retries = 0;
+
void
AR6002_fatal_exception_handler_patch(CPU_exception_frame_t *exc_frame)
{
@@ -226,6 +298,32 @@ AR6002_fatal_exception_handler_patch(CPU_exception_frame_t *exc_frame)
dump.pc = exc_frame->xt_pc;
dump.assline = 0;
+ if (dump.badvaddr >= 0x10000000 &&
+ dump.badvaddr < 0x18000000) {
+ // Exception while accessing PCIe memory space.
+ volatile uint32_t *pcie_app = (uint32_t*) 0x40000;
+ volatile uint32_t *pcie_reset = (uint32_t*) 0x40018;
+ volatile uint32_t *pcie_int_mask = (uint32_t*) 0x40050;
+
+ // Maybe retry.
+ if (++exception_retries < 2) {
+ A_PRINTF("\nRetry(%d) failed PCIe access @0x%x\n",
+ exception_retries, dump.badvaddr);
+ A_PRINTF("Before: int_mask=%x app=%x reset=%x\n", *pcie_int_mask, *pcie_app, *pcie_reset);
+
+ AR7010_pcie_reset();
+
+ A_PRINTF("After: int_mask=%x app=%x reset=%x\n", *pcie_int_mask, *pcie_app, *pcie_reset);
+
+ // This should recurse if we failed to recover.
+ A_PRINTF("wlan int status=%x\n", HAL_WORD_REG_READ(0x10ff4038));
+
+ // Reset retry counter.
+ exception_retries = 0;
+ return;
+ }
+ }
+
zfGenExceptionEvent(dump.exc_frame.xt_exccause, dump.pc, dump.badvaddr);
#if SYSTEM_MODULE_PRINT
--
Tobias PGP: http://8ef7ddba.uguu.de
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply related
* Re: [PATCH v3 5/6] dt-bindings: display: amlogic: DT fix s/resets-names/reset-names/
From: Rob Herring @ 2017-06-07 22:42 UTC (permalink / raw)
To: Geert Uytterhoeven
Cc: Mark Rutland, devicetree, Neil Armstrong, Catalin Marinas,
Chanho Min, Will Deacon, linux-kernel, dri-devel, netdev,
Paul Mackerras, Michael Ellerman, Kevin Hilman, Carlo Caione,
linux-amlogic, linuxppc-dev, linux-arm-kernel
In-Reply-To: <1496407129-13527-6-git-send-email-geert+renesas@glider.be>
On Fri, Jun 02, 2017 at 02:38:48PM +0200, Geert Uytterhoeven wrote:
> Fixes: 8cceda5349377e30 ("dt-bindings: Add bindings for the Amlogic Meson dw-hdmi extension")
> Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
> ---
> v3:
> - New.
> ---
> Documentation/devicetree/bindings/display/amlogic,meson-dw-hdmi.txt | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
Acked-by: Rob Herring <robh@kernel.org>
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply
* Re: [PATCH v3 6/6] dt-bindings: net: btusb: DT fix s/interrupt-name/interrupt-names/
From: Rob Herring @ 2017-06-07 22:43 UTC (permalink / raw)
To: Geert Uytterhoeven
Cc: Mark Rutland, devicetree, Neil Armstrong, Catalin Marinas,
Chanho Min, Will Deacon, linux-kernel, dri-devel, netdev,
Paul Mackerras, Michael Ellerman, Kevin Hilman, Carlo Caione,
linux-amlogic, linuxppc-dev, linux-arm-kernel
In-Reply-To: <1496407129-13527-7-git-send-email-geert+renesas@glider.be>
On Fri, Jun 02, 2017 at 02:38:49PM +0200, Geert Uytterhoeven wrote:
> Fixes: fd913ef7ce619467 ("Bluetooth: btusb: Add out-of-band wakeup support")
> Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
> ---
> v3:
> - New.
> ---
> Documentation/devicetree/bindings/net/btusb.txt | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
Acked-by: Rob Herring <robh@kernel.org>
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply
* [PATCH net v2 1/3] netvsc: fix rcu dereference warning from ethtool
From: Stephen Hemminger @ 2017-06-07 22:53 UTC (permalink / raw)
To: kys, haiyangz, sthemmin; +Cc: devel, netdev
In-Reply-To: <20170607225349.28359-1-sthemmin@microsoft.com>
The ethtool info command calls the netvsc get_sset_count with RTNL
but not with RCU. Which causes warning:
drivers/net/hyperv/netvsc_drv.c:1010 suspicious rcu_dereference_check() usage!
Signed-off-by: Stephen Hemminger <sthemmin@microsoft.com>
---
drivers/net/hyperv/netvsc_drv.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
index 4421a6d00375..d93e4da25fd2 100644
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -1028,7 +1028,7 @@ static const struct {
static int netvsc_get_sset_count(struct net_device *dev, int string_set)
{
struct net_device_context *ndc = netdev_priv(dev);
- struct netvsc_device *nvdev = rcu_dereference(ndc->nvdev);
+ struct netvsc_device *nvdev = rtnl_dereference(ndc->nvdev);
if (!nvdev)
return -ENODEV;
--
2.11.0
^ permalink raw reply related
* [PATCH net v2 0/3] netvsc: bug fixes
From: Stephen Hemminger @ 2017-06-07 22:53 UTC (permalink / raw)
To: kys, haiyangz, sthemmin; +Cc: devel, netdev
These are bugfixes for netvsc driver in 4.12.
Stephen Hemminger (3):
netvsc: fix rcu dereference warning from ethtool
netvsc: fix net poll mode
netvsc: move filter setting to rndis_device
drivers/net/hyperv/hyperv_net.h | 5 ++--
drivers/net/hyperv/netvsc_drv.c | 54 +++++++++++++--------------------------
drivers/net/hyperv/rndis_filter.c | 30 +++++++++++++++++++++-
3 files changed, 50 insertions(+), 39 deletions(-)
Note: trying out some scripting to check for obvious issues,
build, test, then send email. Eventually want to expand it to
spin up full test rig on Azure.
Please let me know if there are any issues.
The good part about scripting is that it does the same thing everytime;
the bad part is that it will make the same mistakes everytime.
--
2.11.0
^ permalink raw reply
* [PATCH net v2 2/3] netvsc: fix net poll mode
From: Stephen Hemminger @ 2017-06-07 22:53 UTC (permalink / raw)
To: kys, haiyangz, sthemmin; +Cc: devel, netdev
In-Reply-To: <20170607225349.28359-1-sthemmin@microsoft.com>
The ndo_poll_controller function needs to schedule NAPI to pick
up arriving packets and send completions. Otherwise no data
will ever be received. For simple case of netconsole, it also
will allow send completions to happen. Without this netpoll
will eventually get stuck.
Signed-off-by: Stephen Hemminger <sthemmin@microsoft.com>
---
drivers/net/hyperv/netvsc_drv.c | 19 +++++++++++++++----
1 file changed, 15 insertions(+), 4 deletions(-)
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
index d93e4da25fd2..252e5d52d17e 100644
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -1158,11 +1158,22 @@ netvsc_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *info,
}
#ifdef CONFIG_NET_POLL_CONTROLLER
-static void netvsc_poll_controller(struct net_device *net)
+static void netvsc_poll_controller(struct net_device *dev)
{
- /* As netvsc_start_xmit() works synchronous we don't have to
- * trigger anything here.
- */
+ struct net_device_context *ndc = netdev_priv(dev);
+ struct netvsc_device *ndev;
+ int i;
+
+ rcu_read_lock();
+ ndev = rcu_dereference(ndc->nvdev);
+ if (ndev) {
+ for (i = 0; i < ndev->num_chn; i++) {
+ struct netvsc_channel *nvchan = &ndev->chan_table[i];
+
+ napi_schedule(&nvchan->napi);
+ }
+ }
+ rcu_read_unlock();
}
#endif
--
2.11.0
^ permalink raw reply related
* [PATCH net v2 3/3] netvsc: move filter setting to rndis_device
From: Stephen Hemminger @ 2017-06-07 22:53 UTC (permalink / raw)
To: kys, haiyangz, sthemmin; +Cc: devel, netdev
In-Reply-To: <20170607225349.28359-1-sthemmin@microsoft.com>
The work queue and handling of network filter parameters should
be in rndis_device. This gets rid of warning from RCU checks,
eliminates a race and cleans up code.
Signed-off-by: Stephen Hemminger <sthemmin@microsoft.com>
---
v2 - instead of adding locking to do_set_mulitcast, move the
workqueue to rndis portion of driver where it fits better.
drivers/net/hyperv/hyperv_net.h | 5 +++--
drivers/net/hyperv/netvsc_drv.c | 33 ++-------------------------------
drivers/net/hyperv/rndis_filter.c | 30 +++++++++++++++++++++++++++++-
3 files changed, 34 insertions(+), 34 deletions(-)
diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h
index 262b2ea576a3..6066f1bcaf2d 100644
--- a/drivers/net/hyperv/hyperv_net.h
+++ b/drivers/net/hyperv/hyperv_net.h
@@ -171,6 +171,8 @@ struct rndis_device {
spinlock_t request_lock;
struct list_head req_list;
+ struct work_struct mcast_work;
+
u8 hw_mac_adr[ETH_ALEN];
u8 rss_key[NETVSC_HASH_KEYLEN];
u16 ind_table[ITAB_NUM];
@@ -201,6 +203,7 @@ int rndis_filter_open(struct netvsc_device *nvdev);
int rndis_filter_close(struct netvsc_device *nvdev);
int rndis_filter_device_add(struct hv_device *dev,
struct netvsc_device_info *info);
+void rndis_filter_update(struct netvsc_device *nvdev);
void rndis_filter_device_remove(struct hv_device *dev,
struct netvsc_device *nvdev);
int rndis_filter_set_rss_param(struct rndis_device *rdev,
@@ -211,7 +214,6 @@ int rndis_filter_receive(struct net_device *ndev,
struct vmbus_channel *channel,
void *data, u32 buflen);
-int rndis_filter_set_packet_filter(struct rndis_device *dev, u32 new_filter);
int rndis_filter_set_device_mac(struct net_device *ndev, char *mac);
void netvsc_switch_datapath(struct net_device *nv_dev, bool vf);
@@ -696,7 +698,6 @@ struct net_device_context {
/* list protection */
spinlock_t lock;
- struct work_struct work;
u32 msg_enable; /* debug level */
u32 tx_checksum_mask;
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
index 252e5d52d17e..82d6c022ca85 100644
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -56,37 +56,12 @@ static int debug = -1;
module_param(debug, int, S_IRUGO);
MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)");
-static void do_set_multicast(struct work_struct *w)
-{
- struct net_device_context *ndevctx =
- container_of(w, struct net_device_context, work);
- struct hv_device *device_obj = ndevctx->device_ctx;
- struct net_device *ndev = hv_get_drvdata(device_obj);
- struct netvsc_device *nvdev = rcu_dereference(ndevctx->nvdev);
- struct rndis_device *rdev;
-
- if (!nvdev)
- return;
-
- rdev = nvdev->extension;
- if (rdev == NULL)
- return;
-
- if (ndev->flags & IFF_PROMISC)
- rndis_filter_set_packet_filter(rdev,
- NDIS_PACKET_TYPE_PROMISCUOUS);
- else
- rndis_filter_set_packet_filter(rdev,
- NDIS_PACKET_TYPE_BROADCAST |
- NDIS_PACKET_TYPE_ALL_MULTICAST |
- NDIS_PACKET_TYPE_DIRECTED);
-}
-
static void netvsc_set_multicast_list(struct net_device *net)
{
struct net_device_context *net_device_ctx = netdev_priv(net);
+ struct netvsc_device *nvdev = rtnl_dereference(net_device_ctx->nvdev);
- schedule_work(&net_device_ctx->work);
+ rndis_filter_update(nvdev);
}
static int netvsc_open(struct net_device *net)
@@ -123,8 +98,6 @@ static int netvsc_close(struct net_device *net)
netif_tx_disable(net);
- /* Make sure netvsc_set_multicast_list doesn't re-enable filter! */
- cancel_work_sync(&net_device_ctx->work);
ret = rndis_filter_close(nvdev);
if (ret != 0) {
netdev_err(net, "unable to close device (ret %d).\n", ret);
@@ -1563,7 +1536,6 @@ static int netvsc_probe(struct hv_device *dev,
hv_set_drvdata(dev, net);
INIT_DELAYED_WORK(&net_device_ctx->dwork, netvsc_link_change);
- INIT_WORK(&net_device_ctx->work, do_set_multicast);
spin_lock_init(&net_device_ctx->lock);
INIT_LIST_HEAD(&net_device_ctx->reconfig_events);
@@ -1633,7 +1605,6 @@ static int netvsc_remove(struct hv_device *dev)
netif_device_detach(net);
cancel_delayed_work_sync(&ndev_ctx->dwork);
- cancel_work_sync(&ndev_ctx->work);
/*
* Call to the vsc driver to let it know that the device is being
diff --git a/drivers/net/hyperv/rndis_filter.c b/drivers/net/hyperv/rndis_filter.c
index f9d5b0b8209a..cb79cd081f42 100644
--- a/drivers/net/hyperv/rndis_filter.c
+++ b/drivers/net/hyperv/rndis_filter.c
@@ -31,6 +31,7 @@
#include "hyperv_net.h"
+static void rndis_set_multicast(struct work_struct *w);
#define RNDIS_EXT_LEN PAGE_SIZE
struct rndis_request {
@@ -76,6 +77,7 @@ static struct rndis_device *get_rndis_device(void)
spin_lock_init(&device->request_lock);
INIT_LIST_HEAD(&device->req_list);
+ INIT_WORK(&device->mcast_work, rndis_set_multicast);
device->state = RNDIS_DEV_UNINITIALIZED;
@@ -815,7 +817,8 @@ static int rndis_filter_query_link_speed(struct rndis_device *dev)
return ret;
}
-int rndis_filter_set_packet_filter(struct rndis_device *dev, u32 new_filter)
+static int rndis_filter_set_packet_filter(struct rndis_device *dev,
+ u32 new_filter)
{
struct rndis_request *request;
struct rndis_set_request *set;
@@ -846,6 +849,28 @@ int rndis_filter_set_packet_filter(struct rndis_device *dev, u32 new_filter)
return ret;
}
+static void rndis_set_multicast(struct work_struct *w)
+{
+ struct rndis_device *rdev
+ = container_of(w, struct rndis_device, mcast_work);
+
+ if (rdev->ndev->flags & IFF_PROMISC)
+ rndis_filter_set_packet_filter(rdev,
+ NDIS_PACKET_TYPE_PROMISCUOUS);
+ else
+ rndis_filter_set_packet_filter(rdev,
+ NDIS_PACKET_TYPE_BROADCAST |
+ NDIS_PACKET_TYPE_ALL_MULTICAST |
+ NDIS_PACKET_TYPE_DIRECTED);
+}
+
+void rndis_filter_update(struct netvsc_device *nvdev)
+{
+ struct rndis_device *rdev = nvdev->extension;
+
+ schedule_work(&rdev->mcast_work);
+}
+
static int rndis_filter_init_device(struct rndis_device *dev)
{
struct rndis_request *request;
@@ -973,6 +998,9 @@ static int rndis_filter_close_device(struct rndis_device *dev)
if (dev->state != RNDIS_DEV_DATAINITIALIZED)
return 0;
+ /* Make sure rndis_set_multicast doesn't re-enable filter! */
+ cancel_work_sync(&dev->mcast_work);
+
ret = rndis_filter_set_packet_filter(dev, 0);
if (ret == -ENODEV)
ret = 0;
--
2.11.0
^ permalink raw reply related
* Re: Question about tcp_filter() in tcp_v6_do_rcv()
From: Eric Dumazet @ 2017-06-07 23:06 UTC (permalink / raw)
To: Chenbo Feng
Cc: netdev, Lorenzo Colitti, Alexei Starovoitov, Daniel Borkmann,
Chenbo Feng
In-Reply-To: <c49c55de-5356-0804-9baf-f0ed12829055@gmail.com>
On Wed, 2017-06-07 at 15:35 -0700, Chenbo Feng wrote:
> Hello everybody,
>
> I am testing eBPF programs on ipv6 and I just find out the tcp_filter()
> function (previously named sk_filter()) is called both in tcp_v6_rcv()
> and tcp_v6_do_rcv(). In contrast, it is only called by tcp_v4_rcv() in
> ipv4 layer. I guess this implementation is used to capture some corner
> cases in ipv6 ingress route but I cannot find why. Could I know why we
> need this in two similar places in ipv6 transportation layer?
>
> I have tried to dig into the commit history and the related code path
> but I did not see any obvious reason for doing so. And my problem with
> it is when a eBPF program is attached to a socket or a cgroup in ingress
> side, the filter program will be applied on some packets twice. And it
> affect the accuracy when using eBPF program for traffic accounting.
It seems this was added in this commit
commit 5234b9f7d650fe64975695d835cb9413e1d75f46
Author: James Morris <jmorris@intercode.com.au>
Date: Thu Feb 6 09:49:40 2003 -0800
[LSM]: Networking socket SKB receive hook.
You can find the history tree in :
[remote "origin"]
url = git://git.kernel.org/pub/scm/linux/kernel/git/tglx/history.git
fetch = +refs/heads/*:refs/remotes/origin/*
The call from tcp_v6_do_rcv() should be removed I guess
^ permalink raw reply
* Re: [PATCH net] net: Zero ifla_vf_info in rtnl_fill_vfinfo()
From: Greg Rose @ 2017-06-07 23:10 UTC (permalink / raw)
To: Yuval Mintz; +Cc: Michal Schmidt, davem, netdev
In-Reply-To: <20170607180033.19747-1-Yuval.Mintz@cavium.com>
On 06/07/2017 11:00 AM, Yuval Mintz wrote:
> Some of the structure's fields are not initialized by the
> rtnetlink. If driver doesn't set those in ndo_get_vf_config(),
> they'd leak memory to user.
>
> Signed-off-by: Yuval Mintz <Yuval.Mintz@cavium.com>
> CC: Michal Schmidt <mschmidt@redhat.com>
> ---
> net/core/rtnetlink.c | 3 ++-
> 1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
> index 9e2c0a7..5e61456 100644
> --- a/net/core/rtnetlink.c
> +++ b/net/core/rtnetlink.c
> @@ -1124,6 +1124,8 @@ static noinline_for_stack int rtnl_fill_vfinfo(struct sk_buff *skb,
> struct ifla_vf_mac vf_mac;
> struct ifla_vf_info ivi;
>
> + memset(&ivi, 0, sizeof(ivi));
> +
> /* Not all SR-IOV capable drivers support the
> * spoofcheck and "RSS query enable" query. Preset to
> * -1 so the user space tool can detect that the driver
> @@ -1132,7 +1134,6 @@ static noinline_for_stack int rtnl_fill_vfinfo(struct sk_buff *skb,
> ivi.spoofchk = -1;
> ivi.rss_query_en = -1;
> ivi.trusted = -1;
> - memset(ivi.mac, 0, sizeof(ivi.mac));
> /* The default value for VF link state is "auto"
> * IFLA_VF_LINK_STATE_AUTO which equals zero
> */
>
It's been a few years since I worked in this code but I do recall this portion. Good idea...
Thanks!
Reviewed-by: Greg Rose <gvrose8192@gmail.com>
^ permalink raw reply
* Re: [PATCH v3 3/3] net/cxgb4: Use new PCI_DEV_FLAGS_NO_RELAXED_ORDERING flag
From: Alexander Duyck @ 2017-06-07 23:24 UTC (permalink / raw)
To: Ding Tianhong
Cc: Casey Leedom, Ashok Raj, Bjorn Helgaas, Michael Werner,
Ganesh Goudar, Asit K Mallick, Patrick J Cramer,
Suravee Suthikulpanit, Bob Shaw, h, Amir Ancel, Gabriele Paoloni,
David Laight, Jeff Kirsher, Catalin Marinas, Will Deacon,
Mark Rutland, Robin Murphy, David Miller, linux-arm-kernel
In-Reply-To: <1496826968-10152-4-git-send-email-dingtianhong@huawei.com>
On Wed, Jun 7, 2017 at 2:16 AM, Ding Tianhong <dingtianhong@huawei.com> wrote:
> From: Casey Leedom <leedom@chelsio.com>
>
> cxgb4 Ethernet driver now queries Root Complex Port to determine if it can
> send TLPs to it with the Relaxed Ordering Attribute set.
>
> Signed-off-by: Casey Leedom <leedom@chelsio.com>
> Signed-off-by: Ding Tianhong <dingtianhong@huawei.com>
So I am pretty sure this patch doesn't work with patch 2. We need to
update it so that it doesn't check the root complex but instead checks
itself to see if it is allowed to use relaxed ordering.
What we need here is the ability to detect if relaxed ordering is
disabled, and if so take the steps needed to enable peer to peer
relaxed ordering without enabling relaxed ordering to the root
complex. Do I have that right Casey?
> ---
> drivers/net/ethernet/chelsio/cxgb4/cxgb4.h | 1 +
> drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 17 +++++++++++++++++
> drivers/net/ethernet/chelsio/cxgb4/sge.c | 5 +++--
> 3 files changed, 21 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
> index e88c180..478f25a 100644
> --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
> +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
> @@ -521,6 +521,7 @@ enum { /* adapter flags */
> USING_SOFT_PARAMS = (1 << 6),
> MASTER_PF = (1 << 7),
> FW_OFLD_CONN = (1 << 9),
> + ROOT_NO_RELAXED_ORDERING = (1 << 10),
> };
>
> enum {
> diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
> index 38a5c67..fbfe341 100644
> --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
> +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
> @@ -4628,6 +4628,7 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
> #ifdef CONFIG_PCI_IOV
> u32 v, port_vec;
> #endif
> + struct pci_dev *root;
>
> printk_once(KERN_INFO "%s - version %s\n", DRV_DESC, DRV_VERSION);
>
> @@ -4726,6 +4727,22 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
> adapter->msg_enable = DFLT_MSG_ENABLE;
> memset(adapter->chan_map, 0xff, sizeof(adapter->chan_map));
>
> + /* If possible, we use PCIe Relaxed Ordering Attribute to deliver
> + * Ingress Packet Data to Free List Buffers in order to allow for
> + * chipset performance optimizations between the Root Complex and
> + * Memory Controllers. (Messages to the associated Ingress Queue
> + * notifying new Packet Placement in the Free Lists Buffers will be
> + * send without the Relaxed Ordering Attribute thus guaranteing that
> + * all preceding PCIe Transaction Layer Packets will be processed
> + * first.) But some Root Complexes have various issues with Upstream
> + * Transaction Layer Packets with the Relaxed Ordering Attribute set.
> + * So we check our Root Complex to see if it's flaged with advice
> + * against using Relaxed Ordering.
> + */
> + root = pci_find_pcie_root_port(adapter->pdev);
> + if (pcie_get_relaxed_ordering(root))
> + adapter->flags |= ROOT_NO_RELAXED_ORDERING;
> +
> spin_lock_init(&adapter->stats_lock);
> spin_lock_init(&adapter->tid_release_lock);
> spin_lock_init(&adapter->win0_lock);
> diff --git a/drivers/net/ethernet/chelsio/cxgb4/sge.c b/drivers/net/ethernet/chelsio/cxgb4/sge.c
> index f05f0d4..ac229a3 100644
> --- a/drivers/net/ethernet/chelsio/cxgb4/sge.c
> +++ b/drivers/net/ethernet/chelsio/cxgb4/sge.c
> @@ -2571,6 +2571,7 @@ int t4_sge_alloc_rxq(struct adapter *adap, struct sge_rspq *iq, bool fwevtq,
> struct fw_iq_cmd c;
> struct sge *s = &adap->sge;
> struct port_info *pi = netdev_priv(dev);
> + int relaxed = !(adap->flags & ROOT_NO_RELAXED_ORDERING);
>
> /* Size needs to be multiple of 16, including status entry. */
> iq->size = roundup(iq->size, 16);
> @@ -2624,8 +2625,8 @@ int t4_sge_alloc_rxq(struct adapter *adap, struct sge_rspq *iq, bool fwevtq,
>
> flsz = fl->size / 8 + s->stat_len / sizeof(struct tx_desc);
> c.iqns_to_fl0congen |= htonl(FW_IQ_CMD_FL0PACKEN_F |
> - FW_IQ_CMD_FL0FETCHRO_F |
> - FW_IQ_CMD_FL0DATARO_F |
> + FW_IQ_CMD_FL0FETCHRO_V(relaxed) |
> + FW_IQ_CMD_FL0DATARO_V(relaxed) |
> FW_IQ_CMD_FL0PADEN_F);
> if (cong >= 0)
> c.iqns_to_fl0congen |=
> --
> 1.9.0
>
>
^ permalink raw reply
* Re: [PATCH net-next v2 5/5] net: dsa: Stop accessing ds->dst->cpu_dp in drivers
From: Vivien Didelot @ 2017-06-07 23:24 UTC (permalink / raw)
To: Florian Fainelli
Cc: netdev, Andrew Lunn, John Crispin, David Miller, Sean Wang
In-Reply-To: <c8ecc6c3-2780-cf63-24f6-b546e837430e@gmail.com>
Hi Florian,
Sorry to bother you again, I don't want to be annoying but I might not
get things right still.
Florian Fainelli <f.fainelli@gmail.com> writes:
>>>> So as I said in v2, now that a driver is guaranteed that dp->cpu_dp is
>>>> correctly assigned at setup time, isn't better (especially for future
>>>> multi-CPU support) to provide an helper which returns the CPU port for a
>>>> given port? i.e. dsa_get_cpu_port(struct dsa_switch *ds, int port).
>>>>
>>>> Or is there something blocking? I might be wrong.
>>>
>>> mt7530.c needs access to the CPU port at ops->setup() time which is
>>> why this is still here.
>>
>> Yes, mt7530 is the only one doing this and has an hardcoded CPU port. So
>> what I meant was, shouldn't we have this instead:
>>
>> struct dsa_port *dsa_get_cpu_port(struct dsa_switch *ds, int port)
>> {
>> return ds->ports[port].cpu_dp;
>> }
>
> We don't actually have a CPU port point to itself:
>
> +
> + for (i = 0; i < ds->num_ports; i++) {
> + p = &ds->ports[i];
> + if (!dsa_port_is_valid(p) ||
> + i == index) <=============
> + continue;
> +
> + p->cpu_dp = port;
> + }
> }
>
>>
>> And:
>>
>> - dn = ds->dst->cpu_dp->netdev->dev.of_node->parent;
>> + cpu_dp = dsa_get_cpu_port(ds, MT7530_CPU_PORT);
>> + dn = cpu_dp->netdev->dev.of_node->parent;
>
> If we are giving the port number to get its cpu_dp pointer back, that
> seems a bit pointless.
What a driver may want is the master interface (e.g. eth0), actually
soldered to the dedicated switch CPU port, that will be used to
send/receive frames.
Also I do not think that it is a good thing that a DSA driver play much
in dsa_port structures (they are ideally DSA core only specific data).
They only seem to need the master interface, so what I see is:
static inline struct net_device *dsa_get_master(struct dsa_switch *ds, int port)
{
struct dsa_port *dp = &ds->ports[port];
if (!dsa_is_cpu_port(ds, port))
dp = dp->cpu_dp;
return dp->netdev;
}
> I still think the helper with fls(ds->cpu_port_mask) - 1 is better in
> that it will return what you have configured from Device Tree/platform
> data. MT7530 does allow the CPU port being arbitrary, and it would
> disable MTK tags in that case.
If MT7530 allows several CPU ports, what is MT7530_CPU_PORT then?
(Maybe Sean can give me some details here?)
Now let's think that you can have several CPU ports (as with mv88e6xxx).
I think it is the driver responsibility to iterate over CPU capable
ports and inspect the master devices if they need to, instead of having
DSA core return an arbitrary one (which might be the wrong one.)
This is a static data (describing to which SoC interface a switch CPU
port is wired) that should've been parsed by DSA core before setup.
Thanks,
Vivien
^ permalink raw reply
* YOUR PAYMENT
From: Barrister Mike Obi @ 2017-06-07 23:21 UTC (permalink / raw)
Hello Beneficiary.
I will send you the payment information only if contact me and assure me that you are the rightful person to receive $6.5Million Dollars. If you do not contact me I will cancel the money transfer as I will then know that this is not the rightful person.contact Phone+22968323497 email address:westernofficer7@gmail.com
Send your full information immediately and once i confirm it i will proceed sending your MTCN and senders name so that you can pick up your first payment of $5000 today.so make sure you fill this form below:
Your full receiver name..................
Your Country ......and your state..............
Your address.........................
Your mobile phone number.......................
Your private email.............................
Your Occupation....................
Your Drive license or ID card...................
Regards
Barrister Mike Obi
^ permalink raw reply
* [PATCH RFC net-next 0/4] Mellanox, MLX5 E-Switch break down
From: Saeed Mahameed @ 2017-06-07 23:42 UTC (permalink / raw)
To: netdev, Jes Sorensen; +Cc: kernel-team, Or Gerlitz, Tzahi Oved, Saeed Mahameed
Based on Jes Sorensen work to make eswitch_offloads optional at
compilation time, here is an initial RFC series that provides similar
behavior, but here we do more accurate zoom in into eswitch and we break
it into two HW components (MPFS & ESWITCH) to not break any functionality,
and provide more modular separation.
In this series we provide the following modular separation
and give the option of compiling out:
MLX5_MPFS: Multi-Physical Function Switch (MPFs) needed only for Multi-PF configurations
MLX5_ESWITCH: SRIOV Ethernet Switch
With this separation, E-Switch becomes responsible only for ethernet SRIOV and needed only
when SRIOV in enabled, otherwise it is not required.
The two patches at the beginning are for preparation and cleanup only.
Thanks,
Saeed.
Saeed Mahameed (4):
net/mlx5e: Rearrange netdevice ops structures
net/mlx5e: NIC netdev init flow cleanup
net/mlx5: Separate between eswitch and MPFS l2 table logic
net/mlx5: Add CONFIG_MLX5_ESWITCH Kconfig
drivers/net/ethernet/mellanox/mlx5/core/Kconfig | 15 ++
drivers/net/ethernet/mellanox/mlx5/core/Makefile | 8 +-
drivers/net/ethernet/mellanox/mlx5/core/en_fs.c | 14 +-
drivers/net/ethernet/mellanox/mlx5/core/en_main.c | 69 ++++----
drivers/net/ethernet/mellanox/mlx5/core/en_rep.c | 13 ++
drivers/net/ethernet/mellanox/mlx5/core/en_rep.h | 9 +
drivers/net/ethernet/mellanox/mlx5/core/en_rx.c | 2 +
drivers/net/ethernet/mellanox/mlx5/core/en_tc.h | 7 +
drivers/net/ethernet/mellanox/mlx5/core/eswitch.c | 189 ++++----------------
drivers/net/ethernet/mellanox/mlx5/core/eswitch.h | 78 ++------
drivers/net/ethernet/mellanox/mlx5/core/main.c | 34 ++--
drivers/net/ethernet/mellanox/mlx5/core/mpfs.c | 205 ++++++++++++++++++++++
drivers/net/ethernet/mellanox/mlx5/core/mpfs.h | 98 +++++++++++
include/linux/mlx5/driver.h | 2 +
14 files changed, 473 insertions(+), 270 deletions(-)
create mode 100644 drivers/net/ethernet/mellanox/mlx5/core/mpfs.c
create mode 100644 drivers/net/ethernet/mellanox/mlx5/core/mpfs.h
--
2.11.0
^ permalink raw reply
* [PATCH RFC net-next 2/4] net/mlx5e: NIC netdev init flow cleanup
From: Saeed Mahameed @ 2017-06-07 23:42 UTC (permalink / raw)
To: netdev, Jes Sorensen; +Cc: kernel-team, Or Gerlitz, Tzahi Oved, Saeed Mahameed
In-Reply-To: <20170607234214.24723-1-saeedm@mellanox.com>
Remove redundant mlx5_eswitch_unregister_vport_rep in mlx5e_add error
flow.
Hide mlx5e_rep_priv and eswitch internal structures from en_main.c in
preparation for downstream patches which allows compiling the driver
without en_rep and eswitch.
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
---
drivers/net/ethernet/mellanox/mlx5/core/en_main.c | 20 ++++++--------------
drivers/net/ethernet/mellanox/mlx5/core/en_rep.c | 13 +++++++++++++
drivers/net/ethernet/mellanox/mlx5/core/en_rep.h | 1 +
3 files changed, 20 insertions(+), 14 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
index 931347b797c4..1514027a5c51 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
@@ -4357,32 +4357,28 @@ static void mlx5e_detach(struct mlx5_core_dev *mdev, void *vpriv)
static void *mlx5e_add(struct mlx5_core_dev *mdev)
{
- struct mlx5_eswitch *esw = mdev->priv.eswitch;
- int total_vfs = MLX5_TOTAL_VPORTS(mdev);
- struct mlx5e_rep_priv *rpriv = NULL;
+ struct net_device *netdev;
+ void *rpriv = NULL;
void *priv;
- int vport;
int err;
- struct net_device *netdev;
err = mlx5e_check_required_hca_cap(mdev);
if (err)
return NULL;
if (MLX5_CAP_GEN(mdev, vport_group_manager)) {
- rpriv = kzalloc(sizeof(*rpriv), GFP_KERNEL);
+ rpriv = mlx5e_alloc_nic_rep_priv(mdev);
if (!rpriv) {
- mlx5_core_warn(mdev,
- "Not creating net device, Failed to alloc rep priv data\n");
+ mlx5_core_warn(mdev, "Failed to alloc NIC rep priv data\n");
return NULL;
}
- rpriv->rep = &esw->offloads.vport_reps[0];
}
netdev = mlx5e_create_netdev(mdev, &mlx5e_nic_profile, rpriv);
if (!netdev) {
mlx5_core_err(mdev, "mlx5e_create_netdev failed\n");
- goto err_unregister_reps;
+ kfree(rpriv);
+ return NULL;
}
priv = netdev_priv(netdev);
@@ -4407,10 +4403,6 @@ static void *mlx5e_add(struct mlx5_core_dev *mdev)
err_destroy_netdev:
mlx5e_destroy_netdev(priv);
-err_unregister_reps:
- for (vport = 1; vport < total_vfs; vport++)
- mlx5_eswitch_unregister_vport_rep(esw, vport);
-
kfree(rpriv);
return NULL;
}
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
index 79462c0368a0..8d673d61cd11 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
@@ -1089,3 +1089,16 @@ void mlx5e_unregister_vport_reps(struct mlx5e_priv *priv)
mlx5e_rep_unregister_vf_vports(priv); /* VFs vports */
mlx5_eswitch_unregister_vport_rep(esw, 0); /* UPLINK PF*/
}
+
+void* mlx5e_alloc_nic_rep_priv(struct mlx5_core_dev *mdev)
+{
+ struct mlx5_eswitch *esw = mdev->priv.eswitch;
+ struct mlx5e_rep_priv *rpriv;
+
+ rpriv = kzalloc(sizeof(*rpriv), GFP_KERNEL);
+ if (!rpriv)
+ return NULL;
+
+ rpriv->rep = &esw->offloads.vport_reps[0];
+ return rpriv;
+}
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.h b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.h
index a0a1a7a1d6c0..23e43bbf928d 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.h
@@ -123,6 +123,7 @@ struct mlx5e_encap_entry {
int encap_size;
};
+void *mlx5e_alloc_nic_rep_priv(struct mlx5_core_dev *mdev);
void mlx5e_register_vport_reps(struct mlx5e_priv *priv);
void mlx5e_unregister_vport_reps(struct mlx5e_priv *priv);
bool mlx5e_is_uplink_rep(struct mlx5e_priv *priv);
--
2.11.0
^ permalink raw reply related
* [PATCH RFC net-next 4/4] net/mlx5: Add CONFIG_MLX5_ESWITCH Kconfig
From: Saeed Mahameed @ 2017-06-07 23:42 UTC (permalink / raw)
To: netdev, Jes Sorensen; +Cc: kernel-team, Or Gerlitz, Tzahi Oved, Saeed Mahameed
In-Reply-To: <20170607234214.24723-1-saeedm@mellanox.com>
This patch gives the option to chose whether to compile the driver with or
without eswitch/eswitch_offloads(switchdev mode)/en_rep(VF representors)
and en_tc offloads.
It also removes most of the above modules headers declarations and stubs
out the API functions which are used outside these modules.
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
---
drivers/net/ethernet/mellanox/mlx5/core/Kconfig | 7 +++++
drivers/net/ethernet/mellanox/mlx5/core/Makefile | 6 +++--
drivers/net/ethernet/mellanox/mlx5/core/en_main.c | 33 +++++++++++++++--------
drivers/net/ethernet/mellanox/mlx5/core/en_rep.h | 8 ++++++
drivers/net/ethernet/mellanox/mlx5/core/en_rx.c | 2 ++
drivers/net/ethernet/mellanox/mlx5/core/en_tc.h | 7 +++++
drivers/net/ethernet/mellanox/mlx5/core/eswitch.h | 23 +++++++++++-----
drivers/net/ethernet/mellanox/mlx5/core/main.c | 10 +------
8 files changed, 68 insertions(+), 28 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/Kconfig b/drivers/net/ethernet/mellanox/mlx5/core/Kconfig
index 49559e11af86..4024069139a2 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/Kconfig
+++ b/drivers/net/ethernet/mellanox/mlx5/core/Kconfig
@@ -38,6 +38,13 @@ config MLX5_MPFS
Mellanox Technologies Ethernet Multi-Physical Function Switch (MPFS)
support in ConnectX NIC.
+config MLX5_ESWITCH
+ bool "Mellanox Technologies MLX5 SRIOV E-Switch support"
+ depends on MLX5_CORE_EN
+ default y
+ ---help---
+ Mellanox Technologies Ethernet SRIOV E-Switch support in ConnectX NIC.
+
config MLX5_CORE_EN_DCB
bool "Data Center Bridging (DCB) Support"
default y
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/Makefile b/drivers/net/ethernet/mellanox/mlx5/core/Makefile
index 8c493aeec392..2ca2dc1b1147 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/Makefile
+++ b/drivers/net/ethernet/mellanox/mlx5/core/Makefile
@@ -8,13 +8,15 @@ mlx5_core-y := main.o cmd.o debugfs.o fw.o eq.o uar.o pagealloc.o \
mlx5_core-$(CONFIG_MLX5_FPGA) += fpga/cmd.o fpga/core.o
-mlx5_core-$(CONFIG_MLX5_CORE_EN) += wq.o eswitch.o eswitch_offloads.o \
+mlx5_core-$(CONFIG_MLX5_CORE_EN) += wq.o \
en_main.o en_common.o en_fs.o en_ethtool.o en_tx.o \
en_rx.o en_rx_am.o en_txrx.o en_clock.o vxlan.o \
- en_tc.o en_arfs.o en_rep.o en_fs_ethtool.o en_selftest.o
+ en_arfs.o en_fs_ethtool.o en_selftest.o
mlx5_core-$(CONFIG_MLX5_MPFS) += mpfs.o
+mlx5_core-$(CONFIG_MLX5_ESWITCH) += eswitch.o eswitch_offloads.o en_rep.o en_tc.o
+
mlx5_core-$(CONFIG_MLX5_CORE_EN_DCB) += en_dcbnl.o
mlx5_core-$(CONFIG_MLX5_CORE_IPOIB) += ipoib.o
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
index 1514027a5c51..1f0a1b78f609 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
@@ -2961,9 +2961,8 @@ static int mlx5e_modify_channels_vsd(struct mlx5e_channels *chs, bool vsd)
return 0;
}
-static int mlx5e_setup_tc(struct net_device *netdev, u8 tc)
+static int mlx5e_setup_tc(struct mlx5e_priv *priv, u8 tc)
{
- struct mlx5e_priv *priv = netdev_priv(netdev);
struct mlx5e_channels new_channels = {};
int err = 0;
@@ -2995,6 +2994,7 @@ static int mlx5e_ndo_setup_tc(struct net_device *dev, u32 handle,
{
struct mlx5e_priv *priv = netdev_priv(dev);
+#ifdef CONFIG_MLX5_ESWITCH
if (TC_H_MAJ(handle) != TC_H_MAJ(TC_H_INGRESS))
goto mqprio;
@@ -3013,12 +3013,13 @@ static int mlx5e_ndo_setup_tc(struct net_device *dev, u32 handle,
}
mqprio:
+#endif
if (tc->type != TC_SETUP_MQPRIO)
- return -EINVAL;
+ return -EOPNOTSUPP;
tc->mqprio->hw = TC_MQPRIO_HW_OFFLOAD_TCS;
- return mlx5e_setup_tc(dev, tc->mqprio->num_tc);
+ return mlx5e_setup_tc(priv, tc->mqprio->num_tc);
}
static void
@@ -3316,6 +3317,7 @@ static int mlx5e_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
}
}
+#ifdef CONFIG_MLX5_ESWITCH
static int mlx5e_set_vf_mac(struct net_device *dev, int vf, u8 *mac)
{
struct mlx5e_priv *priv = netdev_priv(dev);
@@ -3418,6 +3420,7 @@ static int mlx5e_get_vf_stats(struct net_device *dev,
return mlx5_eswitch_get_vport_stats(mdev->priv.eswitch, vf + 1,
vf_stats);
}
+#endif
static void mlx5e_add_vxlan_port(struct net_device *netdev,
struct udp_tunnel_info *ti)
@@ -3659,6 +3662,7 @@ static const struct net_device_ops mlx5e_netdev_ops_basic = {
#endif
};
+#ifdef CONFIG_MLX5_ESWITCH
static const struct net_device_ops mlx5e_netdev_ops_sriov = {
.ndo_open = mlx5e_open,
.ndo_stop = mlx5e_close,
@@ -3697,6 +3701,7 @@ static const struct net_device_ops mlx5e_netdev_ops_sriov = {
.ndo_has_offload_stats = mlx5e_has_offload_stats,
.ndo_get_offload_stats = mlx5e_get_offload_stats,
};
+#endif
static int mlx5e_check_required_hca_cap(struct mlx5_core_dev *mdev)
{
@@ -3923,9 +3928,11 @@ static void mlx5e_set_netdev_dev_addr(struct net_device *netdev)
}
}
+#if IS_ENABLED(CONFIG_NET_SWITCHDEV) && IS_ENABLED(CONFIG_MLX5_ESWITCH)
static const struct switchdev_ops mlx5e_switchdev_ops = {
.switchdev_port_attr_get = mlx5e_attr_get,
};
+#endif
static void mlx5e_build_nic_netdev(struct net_device *netdev)
{
@@ -3936,15 +3943,17 @@ static void mlx5e_build_nic_netdev(struct net_device *netdev)
SET_NETDEV_DEV(netdev, &mdev->pdev->dev);
- if (MLX5_CAP_GEN(mdev, vport_group_manager)) {
- netdev->netdev_ops = &mlx5e_netdev_ops_sriov;
#ifdef CONFIG_MLX5_CORE_EN_DCB
- if (MLX5_CAP_GEN(mdev, qos))
- netdev->dcbnl_ops = &mlx5e_dcbnl_ops;
+ if (MLX5_CAP_GEN(mdev, vport_group_manager) && MLX5_CAP_GEN(mdev, qos))
+ netdev->dcbnl_ops = &mlx5e_dcbnl_ops;
+#endif
+
+#ifdef CONFIG_MLX5_ESWITCH
+ if (MLX5_CAP_GEN(mdev, vport_group_manager))
+ netdev->netdev_ops = &mlx5e_netdev_ops_sriov;
+ else
#endif
- } else {
netdev->netdev_ops = &mlx5e_netdev_ops_basic;
- }
netdev->watchdog_timeo = 15 * HZ;
@@ -4016,7 +4025,7 @@ static void mlx5e_build_nic_netdev(struct net_device *netdev)
mlx5e_set_netdev_dev_addr(netdev);
-#ifdef CONFIG_NET_SWITCHDEV
+#if IS_ENABLED(CONFIG_NET_SWITCHDEV) && IS_ENABLED(CONFIG_MLX5_ESWITCH)
if (MLX5_CAP_GEN(mdev, vport_group_manager))
netdev->switchdev_ops = &mlx5e_switchdev_ops;
#endif
@@ -4366,6 +4375,7 @@ static void *mlx5e_add(struct mlx5_core_dev *mdev)
if (err)
return NULL;
+#ifdef CONFIG_MLX5_ESWITCH
if (MLX5_CAP_GEN(mdev, vport_group_manager)) {
rpriv = mlx5e_alloc_nic_rep_priv(mdev);
if (!rpriv) {
@@ -4373,6 +4383,7 @@ static void *mlx5e_add(struct mlx5_core_dev *mdev)
return NULL;
}
}
+#endif
netdev = mlx5e_create_netdev(mdev, &mlx5e_nic_profile, rpriv);
if (!netdev) {
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.h b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.h
index 23e43bbf928d..5659ed9f51e6 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.h
@@ -38,6 +38,7 @@
#include "eswitch.h"
#include "en.h"
+#ifdef CONFIG_MLX5_ESWITCH
struct mlx5e_neigh_update_table {
struct rhashtable neigh_ht;
/* Save the neigh hash entries in a list in addition to the hash table
@@ -142,5 +143,12 @@ void mlx5e_rep_encap_entry_detach(struct mlx5e_priv *priv,
struct mlx5e_encap_entry *e);
void mlx5e_rep_queue_neigh_stats_work(struct mlx5e_priv *priv);
+#else /* CONFIG_MLX5_ESWITCH */
+static inline void mlx5e_register_vport_reps(struct mlx5e_priv *priv) {}
+static inline void mlx5e_unregister_vport_reps(struct mlx5e_priv *priv) {}
+static inline bool mlx5e_is_uplink_rep(struct mlx5e_priv *priv) { return false; }
+static inline int mlx5e_add_sqs_fwd_rules(struct mlx5e_priv *priv) { return 0; }
+static inline void mlx5e_remove_sqs_fwd_rules(struct mlx5e_priv *priv) {}
+#endif
#endif /* __MLX5E_REP_H__ */
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
index 66b5fec15313..7d2860252dce 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
@@ -806,6 +806,7 @@ void mlx5e_handle_rx_cqe(struct mlx5e_rq *rq, struct mlx5_cqe64 *cqe)
&wqe->next.next_wqe_index);
}
+#ifdef CONFIG_MLX5_ESWITCH
void mlx5e_handle_rx_cqe_rep(struct mlx5e_rq *rq, struct mlx5_cqe64 *cqe)
{
struct net_device *netdev = rq->netdev;
@@ -838,6 +839,7 @@ void mlx5e_handle_rx_cqe_rep(struct mlx5e_rq *rq, struct mlx5_cqe64 *cqe)
mlx5_wq_ll_pop(&rq->wq, wqe_counter_be,
&wqe->next.next_wqe_index);
}
+#endif
static inline void mlx5e_mpwqe_fill_rx_skb(struct mlx5e_rq *rq,
struct mlx5_cqe64 *cqe,
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.h b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.h
index ecbe30d808ae..36473ec65ce8 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.h
@@ -35,6 +35,7 @@
#define MLX5E_TC_FLOW_ID_MASK 0x0000ffff
+#ifdef CONFIG_MLX5_ESWITCH
int mlx5e_tc_init(struct mlx5e_priv *priv);
void mlx5e_tc_cleanup(struct mlx5e_priv *priv);
@@ -60,4 +61,10 @@ static inline int mlx5e_tc_num_filters(struct mlx5e_priv *priv)
return atomic_read(&priv->fs.tc.ht.nelems);
}
+#else /* CONFIG_MLX5_ESWITCH */
+static inline int mlx5e_tc_init(struct mlx5e_priv *priv) { return 0; }
+static inline void mlx5e_tc_cleanup(struct mlx5e_priv *priv) {}
+static inline int mlx5e_tc_num_filters(struct mlx5e_priv *priv) { return 0; }
+#endif
+
#endif /* __MLX5_EN_TC_H__ */
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
index a0203c7f6cf6..4806e81dec03 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
@@ -39,6 +39,14 @@
#include <linux/mlx5/device.h>
#include "mpfs.h"
+enum {
+ SRIOV_NONE,
+ SRIOV_LEGACY,
+ SRIOV_OFFLOADS
+};
+
+#ifdef CONFIG_MLX5_ESWITCH
+
#define MLX5_MAX_UC_PER_VPORT(dev) \
(1 << MLX5_CAP_GEN(dev, log_max_current_uc_list))
@@ -125,12 +133,6 @@ struct mlx5_eswitch_fdb {
};
};
-enum {
- SRIOV_NONE,
- SRIOV_LEGACY,
- SRIOV_OFFLOADS
-};
-
struct mlx5_esw_sq {
struct mlx5_flow_handle *send_to_vport_rule;
struct list_head list;
@@ -291,4 +293,13 @@ int __mlx5_eswitch_set_vport_vlan(struct mlx5_eswitch *esw,
#define esw_debug(dev, format, ...) \
mlx5_core_dbg_mask(dev, MLX5_DEBUG_ESWITCH_MASK, format, ##__VA_ARGS__)
+#else /* CONFIG_MLX5_ESWITCH */
+/* eswitch API stubs */
+static inline int mlx5_eswitch_init(struct mlx5_core_dev *dev) { return 0; }
+static inline void mlx5_eswitch_cleanup(struct mlx5_eswitch *esw) {}
+static inline void mlx5_eswitch_vport_event(struct mlx5_eswitch *esw, struct mlx5_eqe *eqe) {}
+static inline int mlx5_eswitch_enable_sriov(struct mlx5_eswitch *esw, int nvfs, int mode) { return -EOPNOTSUPP; }
+static inline void mlx5_eswitch_disable_sriov(struct mlx5_eswitch *esw) {}
+#endif /* CONFIG_MLX5_ESWITCH */
+
#endif /* __MLX5_ESWITCH_H__ */
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c
index 70db4257930e..8b78925f8850 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/main.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c
@@ -54,9 +54,7 @@
#include "mlx5_core.h"
#include "fs_core.h"
#include "mpfs.h"
-#ifdef CONFIG_MLX5_CORE_EN
#include "eswitch.h"
-#endif
#include "fpga/core.h"
MODULE_AUTHOR("Eli Cohen <eli@mellanox.com>");
@@ -948,13 +946,11 @@ static int mlx5_init_once(struct mlx5_core_dev *dev, struct mlx5_priv *priv)
goto err_rl_cleanup;
}
-#ifdef CONFIG_MLX5_CORE_EN
err = mlx5_eswitch_init(dev);
if (err) {
dev_err(&pdev->dev, "Failed to init eswitch %d\n", err);
goto err_mpfs_cleanup;
}
-#endif
err = mlx5_sriov_init(dev);
if (err) {
@@ -965,10 +961,8 @@ static int mlx5_init_once(struct mlx5_core_dev *dev, struct mlx5_priv *priv)
return 0;
err_eswitch_cleanup:
-#ifdef CONFIG_MLX5_CORE_EN
mlx5_eswitch_cleanup(dev->priv.eswitch);
err_mpfs_cleanup:
-#endif
mlx5_mpfs_cleanup(dev);
err_rl_cleanup:
mlx5_cleanup_rl_table(dev);
@@ -988,9 +982,7 @@ static int mlx5_init_once(struct mlx5_core_dev *dev, struct mlx5_priv *priv)
static void mlx5_cleanup_once(struct mlx5_core_dev *dev)
{
mlx5_sriov_cleanup(dev);
-#ifdef CONFIG_MLX5_CORE_EN
mlx5_eswitch_cleanup(dev->priv.eswitch);
-#endif
mlx5_mpfs_cleanup(dev);
mlx5_cleanup_rl_table(dev);
mlx5_cleanup_mkey_table(dev);
@@ -1283,7 +1275,7 @@ struct mlx5_core_event_handler {
};
static const struct devlink_ops mlx5_devlink_ops = {
-#ifdef CONFIG_MLX5_CORE_EN
+#ifdef CONFIG_MLX5_ESWITCH
.eswitch_mode_set = mlx5_devlink_eswitch_mode_set,
.eswitch_mode_get = mlx5_devlink_eswitch_mode_get,
.eswitch_inline_mode_set = mlx5_devlink_eswitch_inline_mode_set,
--
2.11.0
^ permalink raw reply related
* [PATCH RFC net-next 3/4] net/mlx5: Separate between eswitch and MPFS l2 table logic
From: Saeed Mahameed @ 2017-06-07 23:42 UTC (permalink / raw)
To: netdev, Jes Sorensen; +Cc: kernel-team, Or Gerlitz, Tzahi Oved, Saeed Mahameed
In-Reply-To: <20170607234214.24723-1-saeedm@mellanox.com>
Multi-Physical Function Switch (MPFs) is required for when multi-PF
configuration is enabled to allow passing user configured unicast MAC
addresses to the requesting PF.
Before this patch eswitch.c used to manage the HW MPFS l2 table,
eswitch always enabled vport(0) (NIC PF) vport's contexts update on unicast
mac address list changes, to populate the PF's MPFS L2 table accordingly,
even if SRIOV was not enabled.
In downstream patch we would like to allow compiling the driver without
eswitch functionalities, for that we move MPFS l2 table logic out
of eswitch.c into its own file, and provide Kconfig flag (MLX5_MPFS) to
allow compiling out MPFS for those who don't want Multi-PF support
NIC PF netdevice will now directly update MPFS l2 table via the new MPFS
API. VF netdevice has no access to MPFS L2 table, so e-Switch will remain
responsible of updating its PF MPFS l2 table on behalf of its VFs.
Due to this change we also don't require enabling vport(0) (PF vport)
unicast mac changes events anymore, for when SRIOV is not enabled.
Which means eswitch is now activated only on SRIOV activation, and not
required otherwise.
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
---
drivers/net/ethernet/mellanox/mlx5/core/Kconfig | 8 +
drivers/net/ethernet/mellanox/mlx5/core/Makefile | 2 +
drivers/net/ethernet/mellanox/mlx5/core/en_fs.c | 14 +-
drivers/net/ethernet/mellanox/mlx5/core/eswitch.c | 189 ++++----------------
drivers/net/ethernet/mellanox/mlx5/core/eswitch.h | 55 +-----
drivers/net/ethernet/mellanox/mlx5/core/main.c | 26 ++-
drivers/net/ethernet/mellanox/mlx5/core/mpfs.c | 205 ++++++++++++++++++++++
drivers/net/ethernet/mellanox/mlx5/core/mpfs.h | 98 +++++++++++
include/linux/mlx5/driver.h | 2 +
9 files changed, 376 insertions(+), 223 deletions(-)
create mode 100644 drivers/net/ethernet/mellanox/mlx5/core/mpfs.c
create mode 100644 drivers/net/ethernet/mellanox/mlx5/core/mpfs.h
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/Kconfig b/drivers/net/ethernet/mellanox/mlx5/core/Kconfig
index cf1ef48bfd8d..49559e11af86 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/Kconfig
+++ b/drivers/net/ethernet/mellanox/mlx5/core/Kconfig
@@ -30,6 +30,14 @@ config MLX5_CORE_EN
---help---
Ethernet support in Mellanox Technologies ConnectX-4 NIC.
+config MLX5_MPFS
+ bool "Mellanox Technologies MLX5 MPFS support"
+ depends on MLX5_CORE_EN
+ default y
+ ---help---
+ Mellanox Technologies Ethernet Multi-Physical Function Switch (MPFS)
+ support in ConnectX NIC.
+
config MLX5_CORE_EN_DCB
bool "Data Center Bridging (DCB) Support"
default y
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/Makefile b/drivers/net/ethernet/mellanox/mlx5/core/Makefile
index 12556c03eec4..8c493aeec392 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/Makefile
+++ b/drivers/net/ethernet/mellanox/mlx5/core/Makefile
@@ -13,6 +13,8 @@ mlx5_core-$(CONFIG_MLX5_CORE_EN) += wq.o eswitch.o eswitch_offloads.o \
en_rx.o en_rx_am.o en_txrx.o en_clock.o vxlan.o \
en_tc.o en_arfs.o en_rep.o en_fs_ethtool.o en_selftest.o
+mlx5_core-$(CONFIG_MLX5_MPFS) += mpfs.o
+
mlx5_core-$(CONFIG_MLX5_CORE_EN_DCB) += en_dcbnl.o
mlx5_core-$(CONFIG_MLX5_CORE_IPOIB) += ipoib.o
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_fs.c b/drivers/net/ethernet/mellanox/mlx5/core/en_fs.c
index 7acc4fba7ece..5a782618f1b5 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_fs.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_fs.c
@@ -36,6 +36,7 @@
#include <linux/tcp.h>
#include <linux/mlx5/fs.h>
#include "en.h"
+#include "mpfs.h"
static int mlx5e_add_l2_flow_rule(struct mlx5e_priv *priv,
struct mlx5e_l2_rule *ai, int type);
@@ -363,17 +364,28 @@ static void mlx5e_del_vlan_rules(struct mlx5e_priv *priv)
static void mlx5e_execute_l2_action(struct mlx5e_priv *priv,
struct mlx5e_l2_hash_node *hn)
{
- switch (hn->action) {
+ u8 action = hn->action;
+ int l2_err = 0;
+
+ switch (action) {
case MLX5E_ACTION_ADD:
mlx5e_add_l2_flow_rule(priv, &hn->ai, MLX5E_FULLMATCH);
+ /* mlx5_mpfs_add_mac will skip mc addresses */
+ l2_err = mlx5_mpfs_add_mac(priv->mdev, hn->ai.addr);
hn->action = MLX5E_ACTION_NONE;
break;
case MLX5E_ACTION_DEL:
+ /* mlx5_mpfs_del_mac will skip mc addresses */
+ l2_err = mlx5_mpfs_del_mac(priv->mdev, hn->ai.addr);
mlx5e_del_l2_flow_rule(priv, &hn->ai);
mlx5e_del_l2_from_hash(hn);
break;
}
+
+ if (l2_err)
+ netdev_warn(priv->netdev, "L2 table, failed to %s mac %pM, err(%d)\n",
+ action == MLX5E_ACTION_ADD ? "add" : "del", hn->ai.addr, l2_err);
}
static void mlx5e_sync_netdev_addr(struct mlx5e_priv *priv)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
index 81dfcd90b1f5..33e3b9a2f966 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
@@ -46,13 +46,6 @@ enum {
MLX5_ACTION_DEL = 2,
};
-/* E-Switch UC L2 table hash node */
-struct esw_uc_addr {
- struct l2addr_node node;
- u32 table_index;
- u32 vport;
-};
-
/* Vport UC/MC hash node */
struct vport_addr {
struct l2addr_node node;
@@ -154,81 +147,6 @@ static int modify_esw_vport_cvlan(struct mlx5_core_dev *dev, u32 vport,
return modify_esw_vport_context_cmd(dev, vport, in, sizeof(in));
}
-/* HW L2 Table (MPFS) management */
-static int set_l2_table_entry_cmd(struct mlx5_core_dev *dev, u32 index,
- u8 *mac, u8 vlan_valid, u16 vlan)
-{
- u32 in[MLX5_ST_SZ_DW(set_l2_table_entry_in)] = {0};
- u32 out[MLX5_ST_SZ_DW(set_l2_table_entry_out)] = {0};
- u8 *in_mac_addr;
-
- MLX5_SET(set_l2_table_entry_in, in, opcode,
- MLX5_CMD_OP_SET_L2_TABLE_ENTRY);
- MLX5_SET(set_l2_table_entry_in, in, table_index, index);
- MLX5_SET(set_l2_table_entry_in, in, vlan_valid, vlan_valid);
- MLX5_SET(set_l2_table_entry_in, in, vlan, vlan);
-
- in_mac_addr = MLX5_ADDR_OF(set_l2_table_entry_in, in, mac_address);
- ether_addr_copy(&in_mac_addr[2], mac);
-
- return mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
-}
-
-static int del_l2_table_entry_cmd(struct mlx5_core_dev *dev, u32 index)
-{
- u32 in[MLX5_ST_SZ_DW(delete_l2_table_entry_in)] = {0};
- u32 out[MLX5_ST_SZ_DW(delete_l2_table_entry_out)] = {0};
-
- MLX5_SET(delete_l2_table_entry_in, in, opcode,
- MLX5_CMD_OP_DELETE_L2_TABLE_ENTRY);
- MLX5_SET(delete_l2_table_entry_in, in, table_index, index);
- return mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
-}
-
-static int alloc_l2_table_index(struct mlx5_l2_table *l2_table, u32 *ix)
-{
- int err = 0;
-
- *ix = find_first_zero_bit(l2_table->bitmap, l2_table->size);
- if (*ix >= l2_table->size)
- err = -ENOSPC;
- else
- __set_bit(*ix, l2_table->bitmap);
-
- return err;
-}
-
-static void free_l2_table_index(struct mlx5_l2_table *l2_table, u32 ix)
-{
- __clear_bit(ix, l2_table->bitmap);
-}
-
-static int set_l2_table_entry(struct mlx5_core_dev *dev, u8 *mac,
- u8 vlan_valid, u16 vlan,
- u32 *index)
-{
- struct mlx5_l2_table *l2_table = &dev->priv.eswitch->l2_table;
- int err;
-
- err = alloc_l2_table_index(l2_table, index);
- if (err)
- return err;
-
- err = set_l2_table_entry_cmd(dev, *index, mac, vlan_valid, vlan);
- if (err)
- free_l2_table_index(l2_table, *index);
-
- return err;
-}
-
-static void del_l2_table_entry(struct mlx5_core_dev *dev, u32 index)
-{
- struct mlx5_l2_table *l2_table = &dev->priv.eswitch->l2_table;
-
- del_l2_table_entry_cmd(dev, index);
- free_l2_table_index(l2_table, index);
-}
-
/* E-Switch FDB */
static struct mlx5_flow_handle *
__esw_fdb_set_vport_rule(struct mlx5_eswitch *esw, u32 vport, bool rx_rule,
@@ -455,65 +373,58 @@ typedef int (*vport_addr_action)(struct mlx5_eswitch *esw,
static int esw_add_uc_addr(struct mlx5_eswitch *esw, struct vport_addr *vaddr)
{
- struct hlist_head *hash = esw->l2_table.l2_hash;
- struct esw_uc_addr *esw_uc;
u8 *mac = vaddr->node.addr;
u32 vport = vaddr->vport;
int err;
- esw_uc = l2addr_hash_find(hash, mac, struct esw_uc_addr);
- if (esw_uc) {
+ /* Skip l2_table_add for PFs,
+ * it is already done by the PF netdev in mlx5e_execute_l2_action
+ */
+ if (!vport)
+ goto fdb_add;
+
+ err = mlx5_mpfs_add_mac(esw->dev, mac);
+ if (err) {
esw_warn(esw->dev,
- "Failed to set L2 mac(%pM) for vport(%d), mac is already in use by vport(%d)\n",
- mac, vport, esw_uc->vport);
- return -EEXIST;
+ "Failed to add L2 table mac(%pM) for vport(%d), err(%d)\n",
+ mac, vport, err);
+ return err;
}
- esw_uc = l2addr_hash_add(hash, mac, struct esw_uc_addr, GFP_KERNEL);
- if (!esw_uc)
- return -ENOMEM;
- esw_uc->vport = vport;
-
- err = set_l2_table_entry(esw->dev, mac, 0, 0, &esw_uc->table_index);
- if (err)
- goto abort;
-
+fdb_add:
/* SRIOV is enabled: Forward UC MAC to vport */
if (esw->fdb_table.fdb && esw->mode == SRIOV_LEGACY)
vaddr->flow_rule = esw_fdb_set_vport_rule(esw, mac, vport);
- esw_debug(esw->dev, "\tADDED UC MAC: vport[%d] %pM index:%d fr(%p)\n",
- vport, mac, esw_uc->table_index, vaddr->flow_rule);
- return err;
-abort:
- l2addr_hash_del(esw_uc);
+ esw_debug(esw->dev, "\tADDED UC MAC: vport[%d] %pM fr(%p)\n",
+ vport, mac, vaddr->flow_rule);
+
return err;
}
static int esw_del_uc_addr(struct mlx5_eswitch *esw, struct vport_addr *vaddr)
{
- struct hlist_head *hash = esw->l2_table.l2_hash;
- struct esw_uc_addr *esw_uc;
u8 *mac = vaddr->node.addr;
u32 vport = vaddr->vport;
+ int err = 0;
- esw_uc = l2addr_hash_find(hash, mac, struct esw_uc_addr);
- if (!esw_uc || esw_uc->vport != vport) {
- esw_debug(esw->dev,
- "MAC(%pM) doesn't belong to vport (%d)\n",
- mac, vport);
- return -EINVAL;
- }
- esw_debug(esw->dev, "\tDELETE UC MAC: vport[%d] %pM index:%d fr(%p)\n",
- vport, mac, esw_uc->table_index, vaddr->flow_rule);
+ /* Skip l2_table_del for PFs,
+ * it is already done by the PF netdev in mlx5e_execute_l2_action
+ */
+ if (!vport)
+ goto fdb_del;
- del_l2_table_entry(esw->dev, esw_uc->table_index);
+ err = mlx5_mpfs_del_mac(esw->dev, mac);
+ if (err)
+ esw_warn(esw->dev,
+ "Failed to del L2 table mac(%pM) for vport(%d), err(%d)\n",
+ mac, vport, err);
+fdb_del:
if (vaddr->flow_rule)
mlx5_del_flow_rules(vaddr->flow_rule);
vaddr->flow_rule = NULL;
- l2addr_hash_del(esw_uc);
return 0;
}
@@ -1635,7 +1546,6 @@ int mlx5_eswitch_enable_sriov(struct mlx5_eswitch *esw, int nvfs, int mode)
esw_info(esw->dev, "E-Switch enable SRIOV: nvfs(%d) mode (%d)\n", nvfs, mode);
esw->mode = mode;
- esw_disable_vport(esw, 0);
if (mode == SRIOV_LEGACY)
err = esw_create_legacy_fdb_table(esw, nvfs + 1);
@@ -1648,7 +1558,11 @@ int mlx5_eswitch_enable_sriov(struct mlx5_eswitch *esw, int nvfs, int mode)
if (err)
esw_warn(esw->dev, "Failed to create eswitch TSAR");
- enabled_events = (mode == SRIOV_LEGACY) ? SRIOV_VPORT_EVENTS : UC_ADDR_CHANGE;
+ /* Don't enable vport events when in SRIOV_OFFLOADS mode, since:
+ * 1. L2 table (MPFS) is programmed by PF/VF representors netdevs set_rx_mode
+ * 2. FDB/Eswitch is programmed by user space tools
+ */
+ enabled_events = (mode == SRIOV_LEGACY) ? SRIOV_VPORT_EVENTS : 0;
for (i = 0; i <= nvfs; i++)
esw_enable_vport(esw, i, enabled_events);
@@ -1657,7 +1571,6 @@ int mlx5_eswitch_enable_sriov(struct mlx5_eswitch *esw, int nvfs, int mode)
return 0;
abort:
- esw_enable_vport(esw, 0, UC_ADDR_CHANGE);
esw->mode = SRIOV_NONE;
return err;
}
@@ -1692,32 +1605,10 @@ void mlx5_eswitch_disable_sriov(struct mlx5_eswitch *esw)
esw_offloads_cleanup(esw, nvports);
esw->mode = SRIOV_NONE;
- /* VPORT 0 (PF) must be enabled back with non-sriov configuration */
- esw_enable_vport(esw, 0, UC_ADDR_CHANGE);
-}
-
-void mlx5_eswitch_attach(struct mlx5_eswitch *esw)
-{
- if (!esw || !MLX5_CAP_GEN(esw->dev, vport_group_manager) ||
- MLX5_CAP_GEN(esw->dev, port_type) != MLX5_CAP_PORT_TYPE_ETH)
- return;
-
- esw_enable_vport(esw, 0, UC_ADDR_CHANGE);
- /* VF Vports will be enabled when SRIOV is enabled */
-}
-
-void mlx5_eswitch_detach(struct mlx5_eswitch *esw)
-{
- if (!esw || !MLX5_CAP_GEN(esw->dev, vport_group_manager) ||
- MLX5_CAP_GEN(esw->dev, port_type) != MLX5_CAP_PORT_TYPE_ETH)
- return;
-
- esw_disable_vport(esw, 0);
}
int mlx5_eswitch_init(struct mlx5_core_dev *dev)
{
- int l2_table_size = 1 << MLX5_CAP_GEN(dev, log_max_l2_table);
int total_vports = MLX5_TOTAL_VPORTS(dev);
struct mlx5_eswitch *esw;
int vport_num;
@@ -1728,8 +1619,8 @@ int mlx5_eswitch_init(struct mlx5_core_dev *dev)
return 0;
esw_info(dev,
- "Total vports %d, l2 table size(%d), per vport: max uc(%d) max mc(%d)\n",
- total_vports, l2_table_size,
+ "Total vports %d, per vport: max uc(%d) max mc(%d)\n",
+ total_vports,
MLX5_MAX_UC_PER_VPORT(dev),
MLX5_MAX_MC_PER_VPORT(dev));
@@ -1739,14 +1630,6 @@ int mlx5_eswitch_init(struct mlx5_core_dev *dev)
esw->dev = dev;
- esw->l2_table.bitmap = kcalloc(BITS_TO_LONGS(l2_table_size),
- sizeof(uintptr_t), GFP_KERNEL);
- if (!esw->l2_table.bitmap) {
- err = -ENOMEM;
- goto abort;
- }
- esw->l2_table.size = l2_table_size;
-
esw->work_queue = create_singlethread_workqueue("mlx5_esw_wq");
if (!esw->work_queue) {
err = -ENOMEM;
@@ -1796,7 +1679,6 @@ int mlx5_eswitch_init(struct mlx5_core_dev *dev)
abort:
if (esw->work_queue)
destroy_workqueue(esw->work_queue);
- kfree(esw->l2_table.bitmap);
kfree(esw->vports);
kfree(esw->offloads.vport_reps);
kfree(esw);
@@ -1813,7 +1695,6 @@ void mlx5_eswitch_cleanup(struct mlx5_eswitch *esw)
esw->dev->priv.eswitch = NULL;
destroy_workqueue(esw->work_queue);
- kfree(esw->l2_table.bitmap);
kfree(esw->offloads.vport_reps);
kfree(esw->vports);
kfree(esw);
@@ -1838,7 +1719,7 @@ void mlx5_eswitch_vport_event(struct mlx5_eswitch *esw, struct mlx5_eqe *eqe)
/* Vport Administration */
#define ESW_ALLOWED(esw) \
- (esw && MLX5_CAP_GEN(esw->dev, vport_group_manager) && mlx5_core_is_pf(esw->dev))
+ (esw && MLX5_VPORT_MANAGER(esw->dev))
#define LEGAL_VPORT(esw, vport) (vport >= 0 && vport < esw->total_vports)
int mlx5_eswitch_set_vport_mac(struct mlx5_eswitch *esw,
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
index b746f62c8c79..a0203c7f6cf6 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
@@ -37,6 +37,7 @@
#include <linux/if_link.h>
#include <net/devlink.h>
#include <linux/mlx5/device.h>
+#include "mpfs.h"
#define MLX5_MAX_UC_PER_VPORT(dev) \
(1 << MLX5_CAP_GEN(dev, log_max_current_uc_list))
@@ -44,9 +45,6 @@
#define MLX5_MAX_MC_PER_VPORT(dev) \
(1 << MLX5_CAP_GEN(dev, log_max_current_mc_list))
-#define MLX5_L2_ADDR_HASH_SIZE (BIT(BITS_PER_BYTE))
-#define MLX5_L2_ADDR_HASH(addr) (addr[5])
-
#define FDB_UPLINK_VPORT 0xffff
#define MLX5_MIN_BW_SHARE 1
@@ -54,48 +52,6 @@
#define MLX5_RATE_TO_BW_SHARE(rate, divider, limit) \
min_t(u32, max_t(u32, (rate) / (divider), MLX5_MIN_BW_SHARE), limit)
-/* L2 -mac address based- hash helpers */
-struct l2addr_node {
- struct hlist_node hlist;
- u8 addr[ETH_ALEN];
-};
-
-#define for_each_l2hash_node(hn, tmp, hash, i) \
- for (i = 0; i < MLX5_L2_ADDR_HASH_SIZE; i++) \
- hlist_for_each_entry_safe(hn, tmp, &hash[i], hlist)
-
-#define l2addr_hash_find(hash, mac, type) ({ \
- int ix = MLX5_L2_ADDR_HASH(mac); \
- bool found = false; \
- type *ptr = NULL; \
- \
- hlist_for_each_entry(ptr, &hash[ix], node.hlist) \
- if (ether_addr_equal(ptr->node.addr, mac)) {\
- found = true; \
- break; \
- } \
- if (!found) \
- ptr = NULL; \
- ptr; \
-})
-
-#define l2addr_hash_add(hash, mac, type, gfp) ({ \
- int ix = MLX5_L2_ADDR_HASH(mac); \
- type *ptr = NULL; \
- \
- ptr = kzalloc(sizeof(type), gfp); \
- if (ptr) { \
- ether_addr_copy(ptr->node.addr, mac); \
- hlist_add_head(&ptr->node.hlist, &hash[ix]);\
- } \
- ptr; \
-})
-
-#define l2addr_hash_del(ptr) ({ \
- hlist_del(&ptr->node.hlist); \
- kfree(ptr); \
-})
-
struct vport_ingress {
struct mlx5_flow_table *acl;
struct mlx5_flow_group *allow_untagged_spoofchk_grp;
@@ -150,12 +106,6 @@ struct mlx5_vport {
u16 enabled_events;
};
-struct mlx5_l2_table {
- struct hlist_head l2_hash[MLX5_L2_ADDR_HASH_SIZE];
- u32 size;
- unsigned long *bitmap;
-};
-
struct mlx5_eswitch_fdb {
void *fdb;
union {
@@ -221,7 +171,6 @@ struct esw_mc_addr { /* SRIOV only */
struct mlx5_eswitch {
struct mlx5_core_dev *dev;
- struct mlx5_l2_table l2_table;
struct mlx5_eswitch_fdb fdb_table;
struct hlist_head mc_table[MLX5_L2_ADDR_HASH_SIZE];
struct workqueue_struct *work_queue;
@@ -249,8 +198,6 @@ int esw_offloads_init(struct mlx5_eswitch *esw, int nvports);
/* E-Switch API */
int mlx5_eswitch_init(struct mlx5_core_dev *dev);
void mlx5_eswitch_cleanup(struct mlx5_eswitch *esw);
-void mlx5_eswitch_attach(struct mlx5_eswitch *esw);
-void mlx5_eswitch_detach(struct mlx5_eswitch *esw);
void mlx5_eswitch_vport_event(struct mlx5_eswitch *esw, struct mlx5_eqe *eqe);
int mlx5_eswitch_enable_sriov(struct mlx5_eswitch *esw, int nvfs, int mode);
void mlx5_eswitch_disable_sriov(struct mlx5_eswitch *esw);
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c
index 361cd112bb5b..70db4257930e 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/main.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c
@@ -53,6 +53,7 @@
#include <net/devlink.h>
#include "mlx5_core.h"
#include "fs_core.h"
+#include "mpfs.h"
#ifdef CONFIG_MLX5_CORE_EN
#include "eswitch.h"
#endif
@@ -941,11 +942,17 @@ static int mlx5_init_once(struct mlx5_core_dev *dev, struct mlx5_priv *priv)
goto err_tables_cleanup;
}
+ err = mlx5_mpfs_init(dev);
+ if (err) {
+ dev_err(&pdev->dev, "Failed to init l2 table %d\n", err);
+ goto err_rl_cleanup;
+ }
+
#ifdef CONFIG_MLX5_CORE_EN
err = mlx5_eswitch_init(dev);
if (err) {
dev_err(&pdev->dev, "Failed to init eswitch %d\n", err);
- goto err_rl_cleanup;
+ goto err_mpfs_cleanup;
}
#endif
@@ -960,11 +967,11 @@ static int mlx5_init_once(struct mlx5_core_dev *dev, struct mlx5_priv *priv)
err_eswitch_cleanup:
#ifdef CONFIG_MLX5_CORE_EN
mlx5_eswitch_cleanup(dev->priv.eswitch);
-
-err_rl_cleanup:
+err_mpfs_cleanup:
#endif
+ mlx5_mpfs_cleanup(dev);
+err_rl_cleanup:
mlx5_cleanup_rl_table(dev);
-
err_tables_cleanup:
mlx5_cleanup_mkey_table(dev);
mlx5_cleanup_srq_table(dev);
@@ -984,6 +991,7 @@ static void mlx5_cleanup_once(struct mlx5_core_dev *dev)
#ifdef CONFIG_MLX5_CORE_EN
mlx5_eswitch_cleanup(dev->priv.eswitch);
#endif
+ mlx5_mpfs_cleanup(dev);
mlx5_cleanup_rl_table(dev);
mlx5_cleanup_mkey_table(dev);
mlx5_cleanup_srq_table(dev);
@@ -1137,10 +1145,6 @@ static int mlx5_load_one(struct mlx5_core_dev *dev, struct mlx5_priv *priv,
goto err_fs;
}
-#ifdef CONFIG_MLX5_CORE_EN
- mlx5_eswitch_attach(dev->priv.eswitch);
-#endif
-
err = mlx5_sriov_attach(dev);
if (err) {
dev_err(&pdev->dev, "sriov init failed %d\n", err);
@@ -1174,9 +1178,6 @@ static int mlx5_load_one(struct mlx5_core_dev *dev, struct mlx5_priv *priv,
mlx5_sriov_detach(dev);
err_sriov:
-#ifdef CONFIG_MLX5_CORE_EN
- mlx5_eswitch_detach(dev->priv.eswitch);
-#endif
mlx5_cleanup_fs(dev);
err_fs:
@@ -1248,9 +1249,6 @@ static int mlx5_unload_one(struct mlx5_core_dev *dev, struct mlx5_priv *priv,
mlx5_detach_device(dev);
mlx5_sriov_detach(dev);
-#ifdef CONFIG_MLX5_CORE_EN
- mlx5_eswitch_detach(dev->priv.eswitch);
-#endif
mlx5_cleanup_fs(dev);
mlx5_irq_clear_affinity_hints(dev);
free_comp_eqs(dev);
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/mpfs.c b/drivers/net/ethernet/mellanox/mlx5/core/mpfs.c
new file mode 100644
index 000000000000..af5e49f3482f
--- /dev/null
+++ b/drivers/net/ethernet/mellanox/mlx5/core/mpfs.c
@@ -0,0 +1,205 @@
+/*
+ * Copyright (c) 2017, Mellanox Technologies. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * - Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <linux/etherdevice.h>
+#include <linux/mlx5/driver.h>
+#include <linux/mlx5/mlx5_ifc.h>
+#include "mlx5_core.h"
+#include "mpfs.h"
+
+/* HW L2 Table (MPFS) management */
+static int set_l2table_entry_cmd(struct mlx5_core_dev *dev, u32 index, u8 *mac)
+{
+ u32 in[MLX5_ST_SZ_DW(set_l2_table_entry_in)] = {0};
+ u32 out[MLX5_ST_SZ_DW(set_l2_table_entry_out)] = {0};
+ u8 *in_mac_addr;
+
+ MLX5_SET(set_l2_table_entry_in, in, opcode, MLX5_CMD_OP_SET_L2_TABLE_ENTRY);
+ MLX5_SET(set_l2_table_entry_in, in, table_index, index);
+
+ in_mac_addr = MLX5_ADDR_OF(set_l2_table_entry_in, in, mac_address);
+ ether_addr_copy(&in_mac_addr[2], mac);
+
+ return mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
+}
+
+static int del_l2table_entry_cmd(struct mlx5_core_dev *dev, u32 index)
+{
+ u32 in[MLX5_ST_SZ_DW(delete_l2_table_entry_in)] = {0};
+ u32 out[MLX5_ST_SZ_DW(delete_l2_table_entry_out)] = {0};
+
+ MLX5_SET(delete_l2_table_entry_in, in, opcode, MLX5_CMD_OP_DELETE_L2_TABLE_ENTRY);
+ MLX5_SET(delete_l2_table_entry_in, in, table_index, index);
+ return mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
+}
+
+/* UC L2 table hash node */
+struct l2table_node {
+ struct l2addr_node node;
+ u32 index; /* index in HW l2 table */
+};
+
+struct mlx5_mpfs {
+ struct hlist_head hash[MLX5_L2_ADDR_HASH_SIZE];
+ struct mutex lock; /* Synchronize l2 table access */
+ u32 size;
+ unsigned long *bitmap;
+};
+
+static int alloc_l2table_index(struct mlx5_mpfs *l2table, u32 *ix)
+{
+ int err = 0;
+
+ *ix = find_first_zero_bit(l2table->bitmap, l2table->size);
+ if (*ix >= l2table->size)
+ err = -ENOSPC;
+ else
+ __set_bit(*ix, l2table->bitmap);
+
+ return err;
+}
+
+static void free_l2table_index(struct mlx5_mpfs *l2table, u32 ix)
+{
+ __clear_bit(ix, l2table->bitmap);
+}
+
+int mlx5_mpfs_init(struct mlx5_core_dev *dev)
+{
+ int l2table_size = 1 << MLX5_CAP_GEN(dev, log_max_l2_table);
+ struct mlx5_mpfs *mpfs;
+
+ if (!MLX5_VPORT_MANAGER(dev))
+ return 0;
+
+ mpfs = kzalloc(sizeof(*mpfs), GFP_KERNEL);
+ if (!mpfs)
+ return -ENOMEM;
+
+ mutex_init(&mpfs->lock);
+ mpfs->size = l2table_size;
+ mpfs->bitmap = kcalloc(BITS_TO_LONGS(l2table_size),
+ sizeof(uintptr_t), GFP_KERNEL);
+ if (!mpfs->bitmap) {
+ kfree(mpfs);
+ return -ENOMEM;
+ }
+
+ dev->priv.mpfs = mpfs;
+ return 0;
+}
+
+void mlx5_mpfs_cleanup(struct mlx5_core_dev *dev)
+{
+ struct mlx5_mpfs *mpfs = dev->priv.mpfs;
+
+ if (!MLX5_VPORT_MANAGER(dev))
+ return;
+
+ WARN_ON(!hlist_empty(mpfs->hash));
+ kfree(mpfs->bitmap);
+ kfree(mpfs);
+}
+
+int mlx5_mpfs_add_mac(struct mlx5_core_dev *dev, u8 *mac)
+{
+ struct mlx5_mpfs *mpfs = dev->priv.mpfs;
+ struct l2table_node *l2addr;
+ u32 index;
+ int err;
+
+ if (!MLX5_VPORT_MANAGER(dev))
+ return 0;
+
+ if (is_multicast_ether_addr(mac))
+ return 0;
+
+ mutex_lock(&mpfs->lock);
+
+ l2addr = l2addr_hash_find(mpfs->hash, mac, struct l2table_node);
+ if (l2addr) {
+ err = -EEXIST;
+ goto abort;
+ }
+
+ err = alloc_l2table_index(mpfs, &index);
+ if (err)
+ goto abort;
+
+ l2addr = l2addr_hash_add(mpfs->hash, mac, struct l2table_node, GFP_KERNEL);
+ if (!l2addr) {
+ free_l2table_index(mpfs, index);
+ err = -ENOMEM;
+ goto abort;
+ }
+
+ l2addr->index = index;
+ err = set_l2table_entry_cmd(dev, index, mac);
+ if (err) {
+ l2addr_hash_del(l2addr);
+ free_l2table_index(mpfs, index);
+ }
+
+abort:
+ mutex_unlock(&mpfs->lock);
+ return err;
+}
+
+int mlx5_mpfs_del_mac(struct mlx5_core_dev *dev, u8 *mac)
+{
+ struct mlx5_mpfs *mpfs = dev->priv.mpfs;
+ struct l2table_node *l2addr;
+ u32 index;
+ int err;
+
+ if (!MLX5_VPORT_MANAGER(dev))
+ return 0;
+
+ if (is_multicast_ether_addr(mac))
+ return 0;
+
+ mutex_lock(&mpfs->lock);
+
+ l2addr = l2addr_hash_find(mpfs->hash, mac, struct l2table_node);
+ if (!l2addr) {
+ err = -ENOENT;
+ goto unlock;
+ }
+
+ index = l2addr->index;
+ del_l2table_entry_cmd(dev, index);
+ l2addr_hash_del(l2addr);
+ free_l2table_index(mpfs, index);
+unlock:
+ mutex_unlock(&mpfs->lock);
+ return err;
+}
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/mpfs.h b/drivers/net/ethernet/mellanox/mlx5/core/mpfs.h
new file mode 100644
index 000000000000..1db560f689a6
--- /dev/null
+++ b/drivers/net/ethernet/mellanox/mlx5/core/mpfs.h
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2017, Mellanox Technologies, Ltd. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * - Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef __MLX5_MPFS_H__
+#define __MLX5_MPFS_H__
+
+#include <linux/if_ether.h>
+#include <linux/mlx5/device.h>
+
+#define MLX5_VPORT_MANAGER(mdev) \
+ (MLX5_CAP_GEN(mdev, vport_group_manager) && mlx5_core_is_pf(mdev))
+
+/* L2 -mac address based- hash helpers */
+#define MLX5_L2_ADDR_HASH_SIZE (BIT(BITS_PER_BYTE))
+#define MLX5_L2_ADDR_HASH(addr) (addr[5])
+
+struct l2addr_node {
+ struct hlist_node hlist;
+ u8 addr[ETH_ALEN];
+};
+
+#define for_each_l2hash_node(hn, tmp, hash, i) \
+ for (i = 0; i < MLX5_L2_ADDR_HASH_SIZE; i++) \
+ hlist_for_each_entry_safe(hn, tmp, &(hash)[i], hlist)
+
+#define l2addr_hash_find(hash, mac, type) ({ \
+ int ix = MLX5_L2_ADDR_HASH(mac); \
+ bool found = false; \
+ type *ptr = NULL; \
+ \
+ hlist_for_each_entry(ptr, &(hash)[ix], node.hlist) \
+ if (ether_addr_equal(ptr->node.addr, mac)) {\
+ found = true; \
+ break; \
+ } \
+ if (!found) \
+ ptr = NULL; \
+ ptr; \
+})
+
+#define l2addr_hash_add(hash, mac, type, gfp) ({ \
+ int ix = MLX5_L2_ADDR_HASH(mac); \
+ type *ptr = NULL; \
+ \
+ ptr = kzalloc(sizeof(type), gfp); \
+ if (ptr) { \
+ ether_addr_copy(ptr->node.addr, mac); \
+ hlist_add_head(&ptr->node.hlist, &(hash)[ix]);\
+ } \
+ ptr; \
+})
+
+#define l2addr_hash_del(ptr) ({ \
+ hlist_del(&(ptr)->node.hlist); \
+ kfree(ptr); \
+})
+
+#ifdef CONFIG_MLX5_MPFS
+int mlx5_mpfs_init(struct mlx5_core_dev *dev);
+void mlx5_mpfs_cleanup(struct mlx5_core_dev *dev);
+int mlx5_mpfs_add_mac(struct mlx5_core_dev *dev, u8 *mac);
+int mlx5_mpfs_del_mac(struct mlx5_core_dev *dev, u8 *mac);
+#else /* #ifndef CONFIG_MLX5_MPFS */
+static inline int mlx5_mpfs_init(struct mlx5_core_dev *dev) { return 0; }
+static inline void mlx5_mpfs_cleanup(struct mlx5_core_dev *dev) {}
+static inline int mlx5_mpfs_add_mac(struct mlx5_core_dev *dev, u8 *mac) { return 0; }
+static inline int mlx5_mpfs_del_mac(struct mlx5_core_dev *dev, u8 *mac) { return 0; }
+#endif
+#endif
diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h
index 6ea2f5734e37..382f688b7231 100644
--- a/include/linux/mlx5/driver.h
+++ b/include/linux/mlx5/driver.h
@@ -545,6 +545,7 @@ struct mlx5_fc_stats {
unsigned long sampling_interval; /* jiffies */
};
+struct mlx5_mpfs;
struct mlx5_eswitch;
struct mlx5_lag;
struct mlx5_pagefault;
@@ -642,6 +643,7 @@ struct mlx5_priv {
spinlock_t ctx_lock;
struct mlx5_flow_steering *steering;
+ struct mlx5_mpfs *mpfs;
struct mlx5_eswitch *eswitch;
struct mlx5_core_sriov sriov;
struct mlx5_lag *lag;
--
2.11.0
^ permalink raw reply related
* [PATCH RFC net-next 1/4] net/mlx5e: Rearrange netdevice ops structures
From: Saeed Mahameed @ 2017-06-07 23:42 UTC (permalink / raw)
To: netdev, Jes Sorensen; +Cc: kernel-team, Or Gerlitz, Tzahi Oved, Saeed Mahameed
In-Reply-To: <20170607234214.24723-1-saeedm@mellanox.com>
Since we are going to allow compiling the driver without eswitch,
it means we will have to compile out mlx5e_netdev_ops_sriov and will
replace it with mlx5e_netdev_ops_basic.
Move missing vxlan ndos into mlx5e_netdev_ops_basic.
Rearrange some ndos in mlx5e_netdev_ops_sriov and put vf/eswitch related
ndos towards the end of the struct.
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
---
drivers/net/ethernet/mellanox/mlx5/core/en_main.c | 16 ++++++++++------
1 file changed, 10 insertions(+), 6 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
index cdff04b2aea1..931347b797c4 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
@@ -3646,6 +3646,9 @@ static const struct net_device_ops mlx5e_netdev_ops_basic = {
.ndo_change_mtu = mlx5e_change_mtu,
.ndo_do_ioctl = mlx5e_ioctl,
.ndo_set_tx_maxrate = mlx5e_set_tx_maxrate,
+ .ndo_udp_tunnel_add = mlx5e_add_vxlan_port,
+ .ndo_udp_tunnel_del = mlx5e_del_vxlan_port,
+ .ndo_features_check = mlx5e_features_check,
#ifdef CONFIG_RFS_ACCEL
.ndo_rx_flow_steer = mlx5e_rx_flow_steer,
#endif
@@ -3670,13 +3673,19 @@ static const struct net_device_ops mlx5e_netdev_ops_sriov = {
.ndo_set_features = mlx5e_set_features,
.ndo_change_mtu = mlx5e_change_mtu,
.ndo_do_ioctl = mlx5e_ioctl,
+ .ndo_set_tx_maxrate = mlx5e_set_tx_maxrate,
.ndo_udp_tunnel_add = mlx5e_add_vxlan_port,
.ndo_udp_tunnel_del = mlx5e_del_vxlan_port,
- .ndo_set_tx_maxrate = mlx5e_set_tx_maxrate,
.ndo_features_check = mlx5e_features_check,
#ifdef CONFIG_RFS_ACCEL
.ndo_rx_flow_steer = mlx5e_rx_flow_steer,
#endif
+ .ndo_tx_timeout = mlx5e_tx_timeout,
+ .ndo_xdp = mlx5e_xdp,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = mlx5e_netpoll,
+#endif
+ /* SRIOV E-Switch NDOs */
.ndo_set_vf_mac = mlx5e_set_vf_mac,
.ndo_set_vf_vlan = mlx5e_set_vf_vlan,
.ndo_set_vf_spoofchk = mlx5e_set_vf_spoofchk,
@@ -3685,11 +3694,6 @@ static const struct net_device_ops mlx5e_netdev_ops_sriov = {
.ndo_get_vf_config = mlx5e_get_vf_config,
.ndo_set_vf_link_state = mlx5e_set_vf_link_state,
.ndo_get_vf_stats = mlx5e_get_vf_stats,
- .ndo_tx_timeout = mlx5e_tx_timeout,
- .ndo_xdp = mlx5e_xdp,
-#ifdef CONFIG_NET_POLL_CONTROLLER
- .ndo_poll_controller = mlx5e_netpoll,
-#endif
.ndo_has_offload_stats = mlx5e_has_offload_stats,
.ndo_get_offload_stats = mlx5e_get_offload_stats,
};
--
2.11.0
^ permalink raw reply related
* linux-next: build failure after merge of the net tree
From: Stephen Rothwell @ 2017-06-08 0:08 UTC (permalink / raw)
To: David Miller, Networking
Cc: Linux-Next Mailing List, Linux Kernel Mailing List, Hans de Goede,
Greg Kroah-Hartman
Hi all,
After merging the net tree, today's linux-next build (x86_64 allmodconfig)
failed like this:
drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c: In function 'rtw_cfg80211_add_monitor_if':
drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c:2670:10: error: 'struct net_device' has no member named 'destructor'
mon_ndev->destructor = rtw_ndev_destructor;
^
Caused by commit
cf124db566e6 ("net: Fix inconsistent teardown and release of private netdev state.")
from the net tree interacting with commit
554c0a3abf21 ("staging: Add rtl8723bs sdio wifi driver"
from Linus' tree (v4.12-rc1).
I applied the following merge fix patch for today.
From: Stephen Rothwell <sfr@canb.auug.org.au>
Date: Thu, 8 Jun 2017 09:49:26 +1000
Subject: [PATCH] net: fix up for "Fix inconsistent teardown and release of private netdev state"
Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
---
drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c | 3 ++-
drivers/staging/rtl8723bs/os_dep/os_intfs.c | 2 --
2 files changed, 2 insertions(+), 3 deletions(-)
diff --git a/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c b/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c
index 36c3189fc4b7..bd4352fe2de3 100644
--- a/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c
+++ b/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c
@@ -2667,7 +2667,8 @@ static int rtw_cfg80211_add_monitor_if (struct adapter *padapter, char *name, st
mon_ndev->type = ARPHRD_IEEE80211_RADIOTAP;
strncpy(mon_ndev->name, name, IFNAMSIZ);
mon_ndev->name[IFNAMSIZ - 1] = 0;
- mon_ndev->destructor = rtw_ndev_destructor;
+ mon_ndev->needs_free_netdev = true;
+ mon_ndev->priv_destructor = rtw_ndev_destructor;
mon_ndev->netdev_ops = &rtw_cfg80211_monitor_if_ops;
diff --git a/drivers/staging/rtl8723bs/os_dep/os_intfs.c b/drivers/staging/rtl8723bs/os_dep/os_intfs.c
index f83cfc76505c..021589913681 100644
--- a/drivers/staging/rtl8723bs/os_dep/os_intfs.c
+++ b/drivers/staging/rtl8723bs/os_dep/os_intfs.c
@@ -1207,8 +1207,6 @@ void rtw_ndev_destructor(struct net_device *ndev)
if (ndev->ieee80211_ptr)
kfree((u8 *)ndev->ieee80211_ptr);
-
- free_netdev(ndev);
}
void rtw_dev_unload(struct adapter *padapter)
--
2.11.0
--
Cheers,
Stephen Rothwell
^ permalink raw reply related
* Re: [PATCH 1/2] ip_tunnel: fix potential issue in ip_tunnel_rcv
From: 严海双 @ 2017-06-08 0:10 UTC (permalink / raw)
To: Eric Dumazet; +Cc: David S. Miller, netdev, linux-kernel
In-Reply-To: <1496846893.736.41.camel@edumazet-glaptop3.roam.corp.google.com>
> On 7 Jun 2017, at 10:48 PM, Eric Dumazet <eric.dumazet@gmail.com> wrote:
>
> On Wed, 2017-06-07 at 22:16 +0800, Haishuang Yan wrote:
>> When ip_tunnel_rcv fails, the tun_dst won't be freed, so move
>> skb_dst_set to begin and tun_dst would be freed by kfree_skb.
>>
>> Signed-off-by: Haishuang Yan <yanhaishuang@cmss.chinamobile.com>
>> ---
>
> Please add the missing Fixes: tag and CC author of the patch that added
> this bug, so that he has a chance to comment and avoid future similar
> bugs.
>
> Thanks.
>
>
>
Ok, I will add these information in v2 commit.
Thanks.
^ permalink raw reply
* Re: linux-next: build failure after merge of the net tree
From: David Miller @ 2017-06-08 0:17 UTC (permalink / raw)
To: sfr; +Cc: netdev, linux-next, linux-kernel, hdegoede, gregkh
In-Reply-To: <20170608100858.4c1b18db@canb.auug.org.au>
From: Stephen Rothwell <sfr@canb.auug.org.au>
Date: Thu, 8 Jun 2017 10:08:58 +1000
> I applied the following merge fix patch for today.
>
> From: Stephen Rothwell <sfr@canb.auug.org.au>
> Date: Thu, 8 Jun 2017 09:49:26 +1000
> Subject: [PATCH] net: fix up for "Fix inconsistent teardown and release of private netdev state"
>
> Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
Looks good to me, thanks Stephen.
^ permalink raw reply
* Re: [PATCH net-next v2 5/5] net: dsa: Stop accessing ds->dst->cpu_dp in drivers
From: Florian Fainelli @ 2017-06-08 0:27 UTC (permalink / raw)
To: Vivien Didelot; +Cc: netdev, Andrew Lunn, John Crispin, David Miller, Sean Wang
In-Reply-To: <87wp8nv0tr.fsf@weeman.i-did-not-set--mail-host-address--so-tickle-me>
On 06/07/2017 04:24 PM, Vivien Didelot wrote:
> Hi Florian,
>
> Sorry to bother you again, I don't want to be annoying but I might not
> get things right still.
>
> Florian Fainelli <f.fainelli@gmail.com> writes:
>
>>>>> So as I said in v2, now that a driver is guaranteed that dp->cpu_dp is
>>>>> correctly assigned at setup time, isn't better (especially for future
>>>>> multi-CPU support) to provide an helper which returns the CPU port for a
>>>>> given port? i.e. dsa_get_cpu_port(struct dsa_switch *ds, int port).
>>>>>
>>>>> Or is there something blocking? I might be wrong.
>>>>
>>>> mt7530.c needs access to the CPU port at ops->setup() time which is
>>>> why this is still here.
>>>
>>> Yes, mt7530 is the only one doing this and has an hardcoded CPU port. So
>>> what I meant was, shouldn't we have this instead:
>>>
>>> struct dsa_port *dsa_get_cpu_port(struct dsa_switch *ds, int port)
>>> {
>>> return ds->ports[port].cpu_dp;
>>> }
>>
>> We don't actually have a CPU port point to itself:
>>
>> +
>> + for (i = 0; i < ds->num_ports; i++) {
>> + p = &ds->ports[i];
>> + if (!dsa_port_is_valid(p) ||
>> + i == index) <=============
>> + continue;
>> +
>> + p->cpu_dp = port;
>> + }
>> }
>>
>>>
>>> And:
>>>
>>> - dn = ds->dst->cpu_dp->netdev->dev.of_node->parent;
>>> + cpu_dp = dsa_get_cpu_port(ds, MT7530_CPU_PORT);
>>> + dn = cpu_dp->netdev->dev.of_node->parent;
>>
>> If we are giving the port number to get its cpu_dp pointer back, that
>> seems a bit pointless.
>
> What a driver may want is the master interface (e.g. eth0), actually
> soldered to the dedicated switch CPU port, that will be used to
> send/receive frames.>
> Also I do not think that it is a good thing that a DSA driver play much
> in dsa_port structures (they are ideally DSA core only specific data).
> They only seem to need the master interface, so what I see is:
>
> static inline struct net_device *dsa_get_master(struct dsa_switch *ds, int port)
> {
> struct dsa_port *dp = &ds->ports[port];
>
> if (!dsa_is_cpu_port(ds, port))
> dp = dp->cpu_dp;
>
> return dp->netdev;
> }
The port parameter is kind of pointless, that is what I was trying to
say, see below.
>
>> I still think the helper with fls(ds->cpu_port_mask) - 1 is better in
>> that it will return what you have configured from Device Tree/platform
>> data. MT7530 does allow the CPU port being arbitrary, and it would
>> disable MTK tags in that case.
>
> If MT7530 allows several CPU ports, what is MT7530_CPU_PORT then?
> (Maybe Sean can give me some details here?)
MT7530_CPU_PORT = 6 and there is a define above for 7 ports, so it is
presumably the default CPU port that the switch uses. With Broadcom
switches you could have port 5, 7 or 8 as CPU ports but 8 is still the
default for most 9-ports capable switches.
>
> Now let's think that you can have several CPU ports (as with mv88e6xxx).
> I think it is the driver responsibility to iterate over CPU capable
> ports and inspect the master devices if they need to, instead of having
> DSA core return an arbitrary one (which might be the wrong one.)
OK, then are you okay if I do this in mt7530.c instead:
diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index 1e46418a3b74..d5b63958dd85 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -907,17 +907,26 @@ static int
mt7530_setup(struct dsa_switch *ds)
{
struct mt7530_priv *priv = ds->priv;
+ struct dsa_port *port;
int ret, i;
u32 id, val;
struct device_node *dn;
struct mt7530_dummy_poll p;
- /* The parent node of cpu_dp->netdev which holds the common system
- * controller also is the container for two GMACs nodes representing
- * as two netdev instances.
- */
- dn = ds->dst->cpu_dp->netdev->dev.of_node->parent;
- priv->ethernet = syscon_node_to_regmap(dn);
+ for (i = 0; i < ds->num_ports; i++) {
+ port = &ds->ports[i];
+ /* The parent node of cpu_dp->netdev which holds the common
+ * system controller also is the container for two GMACs
nodes
+ * representing as two netdev instances.
+ */
+ if (dsa_is_cpu_port(ds, i)) {
+ dn = port->netdev->dev.of_node->parent;
+ if (priv->ethernet)
+ return -EEXIST;
+ priv->ethernet = syscon_node_to_regmap(dn);
+ }
+ }
+
if (IS_ERR(priv->ethernet))
return PTR_ERR(priv->ethernet);
>
> This is a static data (describing to which SoC interface a switch CPU
> port is wired) that should've been parsed by DSA core before setup.
Yes, sure.
--
Florian
^ permalink raw reply related
* [PATCH v2 1/2] ip_tunnel: fix potential issue in ip_tunnel_rcv
From: Haishuang Yan @ 2017-06-08 0:57 UTC (permalink / raw)
To: =David S. Miller, Alexey Kuznetsov, James Morris,
Hideaki YOSHIFUJI, Patrick McHardy
Cc: netdev, linux-kernel, Haishuang Yan, Pravin B Shelar,
Haishuang Yan
When ip_tunnel_rcv fails, the tun_dst won't be freed, so move
skb_dst_set to begin and tun_dst would be freed by kfree_skb.
CC: Pravin B Shelar <pshelar@nicira.com>
Fixes: 2e15ea390e6f ("ip_gre: Add support to collect tunnel metadata.")
Signed-off-by: Haishuang Yan <yanhaishuang@cmss.chinamobile.com390e>
---
net/ipv4/ip_tunnel.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/net/ipv4/ip_tunnel.c b/net/ipv4/ip_tunnel.c
index b878ecb..27fc20f 100644
--- a/net/ipv4/ip_tunnel.c
+++ b/net/ipv4/ip_tunnel.c
@@ -386,6 +386,9 @@ int ip_tunnel_rcv(struct ip_tunnel *tunnel, struct sk_buff *skb,
const struct iphdr *iph = ip_hdr(skb);
int err;
+ if (tun_dst)
+ skb_dst_set(skb, (struct dst_entry *)tun_dst);
+
#ifdef CONFIG_NET_IPGRE_BROADCAST
if (ipv4_is_multicast(iph->daddr)) {
tunnel->dev->stats.multicast++;
@@ -439,9 +442,6 @@ int ip_tunnel_rcv(struct ip_tunnel *tunnel, struct sk_buff *skb,
skb->dev = tunnel->dev;
}
- if (tun_dst)
- skb_dst_set(skb, (struct dst_entry *)tun_dst);
-
gro_cells_receive(&tunnel->gro_cells, skb);
return 0;
--
1.8.3.1
^ permalink raw reply related
* [PATCH v2 2/2] ip6_tunnel: fix potential issue in __ip6_tnl_rcv
From: Haishuang Yan @ 2017-06-08 0:57 UTC (permalink / raw)
To: =David S. Miller, Alexey Kuznetsov, James Morris,
Hideaki YOSHIFUJI, Patrick McHardy
Cc: netdev, linux-kernel, Haishuang Yan, Alexei Starovoitov
In-Reply-To: <1496883476-17445-1-git-send-email-yanhaishuang@cmss.chinamobile.com>
When __ip6_tnl_rcv fails, the tun_dst won't be freed, so move
skb_dst_set to begin and tun_dst would be freed by kfree_skb.
CC: Alexei Starovoitov <ast@fb.com>
Fixes: 8d79266bc48c ("ip6_tunnel: add collect_md mode to IPv6 tunnels")
Signed-off-by: Haishuang Yan <yanhaishuang@cmss.chinamobile.com>
---
net/ipv6/ip6_tunnel.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index 9b37f97..bf45f1b 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -789,6 +789,9 @@ static int __ip6_tnl_rcv(struct ip6_tnl *tunnel, struct sk_buff *skb,
const struct ipv6hdr *ipv6h = ipv6_hdr(skb);
int err;
+ if (tun_dst)
+ skb_dst_set(skb, (struct dst_entry *)tun_dst);
+
if ((!(tpi->flags & TUNNEL_CSUM) &&
(tunnel->parms.i_flags & TUNNEL_CSUM)) ||
((tpi->flags & TUNNEL_CSUM) &&
@@ -852,9 +855,6 @@ static int __ip6_tnl_rcv(struct ip6_tnl *tunnel, struct sk_buff *skb,
skb_scrub_packet(skb, !net_eq(tunnel->net, dev_net(tunnel->dev)));
- if (tun_dst)
- skb_dst_set(skb, (struct dst_entry *)tun_dst);
-
gro_cells_receive(&tunnel->gro_cells, skb);
return 0;
--
1.8.3.1
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox