* [RFC PATCH 3/6] cdc_ncm: add needed members to cdc_ncm_ctx for refactoring
From: Enrico Mioso @ 2014-12-29 10:09 UTC (permalink / raw)
To: netdev; +Cc: Enrico Mioso
In-Reply-To: <1419847788-25610-1-git-send-email-mrkiko.rs@gmail.com>
We intend to use something like a TX queue - so prepare the driver's header
file for this.
Signed-Off-By: Enrico Mioso <mrkiko.rs@gmail.com>
---
include/linux/usb/cdc_ncm.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/include/linux/usb/cdc_ncm.h b/include/linux/usb/cdc_ncm.h
index 7c9b484..6710555 100644
--- a/include/linux/usb/cdc_ncm.h
+++ b/include/linux/usb/cdc_ncm.h
@@ -100,6 +100,7 @@ struct cdc_ncm_ctx {
struct sk_buff *tx_curr_skb;
struct sk_buff *tx_rem_skb;
__le32 tx_rem_sign;
+ struct sk_buff_head tx_skb_queue;
spinlock_t mtx;
atomic_t stop;
--
2.2.1
^ permalink raw reply related
* [RFC PATCH 2/6] cdc_ncm: be more precise in comments for cdc_ncm_prepare_skb_ncm16
From: Enrico Mioso @ 2014-12-29 10:09 UTC (permalink / raw)
To: netdev; +Cc: Enrico Mioso
In-Reply-To: <1419847788-25610-1-git-send-email-mrkiko.rs@gmail.com>
The function might return NULL: callers must be prepared to this possibility.
Signed-Off-By: Enrico Mioso <mrkiko.rs@gmail.com>
---
drivers/net/usb/cdc_ncm.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c
index 48fee7a..bcd9437 100644
--- a/drivers/net/usb/cdc_ncm.c
+++ b/drivers/net/usb/cdc_ncm.c
@@ -1015,7 +1015,7 @@ static struct usb_cdc_ncm_ndp16 *cdc_ncm_ndp16(struct cdc_ncm_ctx *ctx, struct s
}
/* Allocate new SKB for use with 16-bit NCM according to actual TX/RX
- settings */
+ settings; returns NULL in case of errors */
struct sk_buff *
cdc_ncm_prepare_skb_ncm16(struct sk_buff *skb, struct cdc_ncm_ctx *ctx)
{
--
2.2.1
^ permalink raw reply related
* [RFC PATCH 1/6] cdc_ncm: factor out skb allocation and finalizzing
From: Enrico Mioso @ 2014-12-29 10:09 UTC (permalink / raw)
To: netdev; +Cc: Enrico Mioso
In-Reply-To: <1419847788-25610-1-git-send-email-mrkiko.rs@gmail.com>
This might help when we will refactor the code to prepare frames only when we
have enough data, allowing us to re-order the position of different NCM
fields.
Signed-Off-By: Enrico Mioso <mrkiko.rs@gmail.com>
---
drivers/net/usb/cdc_ncm.c | 46 +++++++++++++++++++++++++++++++++++-----------
1 file changed, 35 insertions(+), 11 deletions(-)
diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c
index 389a3a4..48fee7a 100644
--- a/drivers/net/usb/cdc_ncm.c
+++ b/drivers/net/usb/cdc_ncm.c
@@ -1014,6 +1014,36 @@ static struct usb_cdc_ncm_ndp16 *cdc_ncm_ndp16(struct cdc_ncm_ctx *ctx, struct s
return ndp16;
}
+/* Allocate new SKB for use with 16-bit NCM according to actual TX/RX
+ settings */
+struct sk_buff *
+cdc_ncm_prepare_skb_ncm16(struct sk_buff *skb, struct cdc_ncm_ctx *ctx)
+{
+ struct usb_cdc_ncm_nth16 *nth16;
+
+ skb = alloc_skb(ctx->tx_max, GFP_ATOMIC);
+ if (skb == NULL)
+ goto exit_no_mem;
+
+ /* fill out the initial 16-bit NTB header */
+ nth16 = (struct usb_cdc_ncm_nth16 *)memset(skb_put(skb, sizeof(struct usb_cdc_ncm_nth16)), 0, sizeof(struct usb_cdc_ncm_nth16));
+ nth16->dwSignature = cpu_to_le32(USB_CDC_NCM_NTH16_SIGN);
+ nth16->wHeaderLength = cpu_to_le16(sizeof(struct usb_cdc_ncm_nth16));
+ nth16->wSequence = cpu_to_le16(ctx->tx_seq++);
+
+exit_no_mem:
+ return skb;
+}
+
+/* Adjust 16-bit NCM header frame length */
+struct usb_cdc_ncm_nth16 *
+cdc_ncm_finalize_nth16(struct usb_cdc_ncm_nth16 *nth16, struct sk_buff *skb)
+{
+ nth16 = (struct usb_cdc_ncm_nth16 *)skb->data;
+ nth16->wBlockLength = cpu_to_le16(skb->len);
+ return nth16;
+}
+
struct sk_buff *
cdc_ncm_fill_tx_frame(struct usbnet *dev, struct sk_buff *skb, __le32 sign)
{
@@ -1037,7 +1067,7 @@ cdc_ncm_fill_tx_frame(struct usbnet *dev, struct sk_buff *skb, __le32 sign)
/* allocate a new OUT skb */
if (!skb_out) {
- skb_out = alloc_skb(ctx->tx_max, GFP_ATOMIC);
+ skb_out = cdc_ncm_prepare_skb_ncm16(skb_out, ctx);
if (skb_out == NULL) {
if (skb != NULL) {
dev_kfree_skb_any(skb);
@@ -1045,11 +1075,6 @@ cdc_ncm_fill_tx_frame(struct usbnet *dev, struct sk_buff *skb, __le32 sign)
}
goto exit_no_skb;
}
- /* fill out the initial 16-bit NTB header */
- nth16 = (struct usb_cdc_ncm_nth16 *)memset(skb_put(skb_out, sizeof(struct usb_cdc_ncm_nth16)), 0, sizeof(struct usb_cdc_ncm_nth16));
- nth16->dwSignature = cpu_to_le32(USB_CDC_NCM_NTH16_SIGN);
- nth16->wHeaderLength = cpu_to_le16(sizeof(struct usb_cdc_ncm_nth16));
- nth16->wSequence = cpu_to_le16(ctx->tx_seq++);
/* count total number of frames in this NTB */
ctx->tx_curr_frame_num = 0;
@@ -1165,11 +1190,10 @@ cdc_ncm_fill_tx_frame(struct usbnet *dev, struct sk_buff *skb, __le32 sign)
ctx->tx_max - skb_out->len);
else if (skb_out->len < ctx->tx_max && (skb_out->len % dev->maxpacket) == 0)
*skb_put(skb_out, 1) = 0; /* force short packet */
-
- /* set final frame length */
- nth16 = (struct usb_cdc_ncm_nth16 *)skb_out->data;
- nth16->wBlockLength = cpu_to_le16(skb_out->len);
-
+
+ /* Finalize packet */
+ nth16 = cdc_ncm_finalize_nth16(nth16, skb_out);
+
/* return skb */
ctx->tx_curr_skb = NULL;
dev->net->stats.tx_packets += ctx->tx_curr_frame_num;
--
2.2.1
^ permalink raw reply related
* [RFC PATCH 0/6] cdc_ncm: some basic refactoring
From: Enrico Mioso @ 2014-12-29 10:09 UTC (permalink / raw)
To: netdev; +Cc: Enrico Mioso
Here is some work I did to move in the direction of refactoring the cdc_ncm
module, to allow for future further changes.
This is work in progress (WIP): and I know some changes are controversial. In
particular, the modification you can see related to cdc_ncm.h header file is
useless at this point. But actually it can be useful for learning from your
opinions: is this the right thing to do?
Thank in advance to anyone reviewing this code.
The final objective would be to have the driver accumulate frames as it does
now, but in a skb queue (sk_buff_head), and then generating the NCM frame
itself only when needed (queue full / flueshed).
I need assistance / help: the logic seems hard to follow for me (is it me or
is it little bit convoluted?).
Thank you for any help, waiting for your comments.
Note: please CC me as I am not subscribed to this list.
Enrico Mioso (6):
cdc_ncm: factor out skb allocation and finalizzing
cdc_ncm: be more precise in comments for cdc_ncm_prepare_skb_ncm16
cdc_ncm: add needed members to cdc_ncm_ctx for refactoring
cdc_ncm: update specs URL
cdc_ncm: fix typo
cdc_ncm: factor out NDP preparation and frame linking
drivers/net/usb/cdc_ncm.c | 74 ++++++++++++++++++++++++++++++++-------------
include/linux/usb/cdc_ncm.h | 1 +
2 files changed, 54 insertions(+), 21 deletions(-)
--
2.2.1
^ permalink raw reply
* [PATCH v3 6/6] GMAC: add document for Rockchip RK3288 GMAC
From: Roger Chen @ 2014-12-29 9:44 UTC (permalink / raw)
To: heiko
Cc: peppe.cavallaro, netdev, linux-kernel, linux-rockchip, kever.yang,
eddie.cai, roger.chen
In-Reply-To: <1419846152-14531-1-git-send-email-roger.chen@rock-chips.com>
The document descripts how to add properties for GMAC in device tree.
change since v2:
1. remove power-gpio, reset-gpio, phyirq-gpio, pmu_regulator setting
2. add "snps,reset-gpio", "snps,reset-active-low;" "snps,reset-delays-us"
Signed-off-by: Roger Chen <roger.chen@rock-chips.com>
---
.../devicetree/bindings/net/rockchip-dwmac.txt | 67 ++++++++++++++++++++
1 file changed, 67 insertions(+)
create mode 100644 Documentation/devicetree/bindings/net/rockchip-dwmac.txt
diff --git a/Documentation/devicetree/bindings/net/rockchip-dwmac.txt b/Documentation/devicetree/bindings/net/rockchip-dwmac.txt
new file mode 100644
index 0000000..94d887f
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/rockchip-dwmac.txt
@@ -0,0 +1,67 @@
+Rockchip SoC RK3288 10/100/1000 Ethernet driver(GMAC)
+
+The device node has following properties.
+
+Required properties:
+ - compatible: Can be "rockchip,rk3288-gmac".
+ - reg: addresses and length of the register sets for the device.
+ - interrupts: Should contain the GMAC interrupts.
+ - interrupt-names: Should contain the interrupt names "macirq".
+ - rockchip,grf: phandle to the syscon grf used to control speed and mode.
+ - clocks: <&cru SCLK_MAC>: clock selector for main clock, from PLL or PHY.
+ <&cru SCLK_MAC_PLL>: PLL clock for SCLK_MAC
+ <&cru SCLK_MAC_RX>: clock gate for RX
+ <&cru SCLK_MAC_TX>: clock gate for TX
+ <&cru SCLK_MACREF>: clock gate for RMII referce clock
+ <&cru SCLK_MACREF_OUT> clock gate for RMII reference clock output
+ <&cru ACLK_GMAC>: AXI clock gate for GMAC
+ <&cru PCLK_GMAC>: APB clock gate for GMAC
+ - clock-names: One name for each entry in the clocks property.
+ - phy-mode: See ethernet.txt file in the same directory.
+ - pinctrl-names: Names corresponding to the numbered pinctrl states.
+ - pinctrl-0: pin-control mode. can be <&rgmii_pins> or <&rmii_pins>.
+ - clock_in_out: For RGMII, it must be "input", means main clock(125MHz)
+ is not sourced from SoC's PLL, but input from PHY; For RMII, "input" means
+ PHY provides the reference clock(50MHz), "output" means GMAC provides the
+ reference clock.
+ - snps,reset-gpio gpio number for phy reset.
+ - snps,reset-active-low boolean flag to indicate if phy reset is active low.
+ - assigned-clocks: main clock, should be <&cru SCLK_MAC>;
+ - assigned-clock-parents = parent of main clock.
+ can be <&ext_gmac> or <&cru SCLK_MAC_PLL>.
+
+Optional properties:
+ - tx_delay: Delay value for TXD timing. Range value is 0~0x7F, 0x30 as default.
+ - rx_delay: Delay value for RXD timing. Range value is 0~0x7F, 0x10 as default.
+
+Example:
+
+gmac: ethernet@ff290000 {
+ compatible = "rockchip,rk3288-gmac";
+ reg = <0xff290000 0x10000>;
+ interrupts = <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "macirq";
+ rockchip,grf = <&grf>;
+ clocks = <&cru SCLK_MAC>,
+ <&cru SCLK_MAC_RX>, <&cru SCLK_MAC_TX>,
+ <&cru SCLK_MACREF>, <&cru SCLK_MACREF_OUT>,
+ <&cru ACLK_GMAC>, <&cru PCLK_GMAC>;
+ clock-names = "stmmaceth",
+ "mac_clk_rx", "mac_clk_tx",
+ "clk_mac_ref", "clk_mac_refout",
+ "aclk_mac", "pclk_mac";
+ phy-mode = "rgmii";
+ pinctrl-names = "default";
+ pinctrl-0 = <&rgmii_pins /*&rmii_pins*/>;
+
+ clock_in_out = "input";
+ snps,reset-gpio = <&gpio4 7 0>;
+ snps,reset-active-low;
+
+ assigned-clocks = <&cru SCLK_MAC>;
+ assigned-clock-parents = <&ext_gmac>;
+ tx_delay = <0x30>;
+ rx_delay = <0x10>;
+
+ status = "ok";
+};
--
1.7.9.5
^ permalink raw reply related
* [PATCH v3 5/6] ARM: dts: rockchip: enable gmac on RK3288 evb board
From: Roger Chen @ 2014-12-29 9:44 UTC (permalink / raw)
To: heiko
Cc: peppe.cavallaro, netdev, linux-kernel, linux-rockchip, kever.yang,
eddie.cai, roger.chen
In-Reply-To: <1419846152-14531-1-git-send-email-roger.chen@rock-chips.com>
enable gmac in rk3288-evb-rk808.dts
changes since v2:
1. add fixed regulator for PHY
2. remove power-gpio, reset-gpio, phyirq-gpio, pmu_regulator setting
3. add "snps,reset-gpio", "snps,reset-active-low;" "snps,reset-delays-us"
Signed-off-by: Roger Chen <roger.chen@rock-chips.com>
---
arch/arm/boot/dts/rk3288-evb-rk808.dts | 23 +++++++++++++++++++++++
arch/arm/boot/dts/rk3288-evb.dtsi | 17 +++++++++++++++++
2 files changed, 40 insertions(+)
diff --git a/arch/arm/boot/dts/rk3288-evb-rk808.dts b/arch/arm/boot/dts/rk3288-evb-rk808.dts
index d8c775e6..831a7aa 100644
--- a/arch/arm/boot/dts/rk3288-evb-rk808.dts
+++ b/arch/arm/boot/dts/rk3288-evb-rk808.dts
@@ -15,6 +15,13 @@
/ {
compatible = "rockchip,rk3288-evb-rk808", "rockchip,rk3288";
+
+ ext_gmac: external-gmac-clock {
+ compatible = "fixed-clock";
+ clock-frequency = <125000000>;
+ clock-output-names = "ext_gmac";
+ #clock-cells = <0>;
+ };
};
&cpu0 {
@@ -152,3 +159,19 @@
};
};
};
+
+&gmac {
+ phy_regulator = "vcc_phy";
+ phy-mode = "rgmii";
+ clock_in_out = "input";
+ snps,reset-gpio = <&gpio4 7 0>;
+ snps,reset-active-low;
+ snps,reset-delays-us = <0 10000 1000000>;
+ assigned-clocks = <&cru SCLK_MAC>;
+ assigned-clock-parents = <&ext_gmac>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&rgmii_pins>;
+ tx_delay = <0x30>;
+ rx_delay = <0x10>;
+ status = "ok";
+};
diff --git a/arch/arm/boot/dts/rk3288-evb.dtsi b/arch/arm/boot/dts/rk3288-evb.dtsi
index cb83cea..fe1d13c 100644
--- a/arch/arm/boot/dts/rk3288-evb.dtsi
+++ b/arch/arm/boot/dts/rk3288-evb.dtsi
@@ -90,6 +90,17 @@
regulator-always-on;
regulator-boot-on;
};
+
+ vcc_phy: vcc-phy-regulator {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&gpio0 6 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <ð_phy_pwr>;
+ regulator-name = "vcc_phy";
+ regulator-always-on;
+ regulator-boot-on;
+ };
};
&emmc {
@@ -172,6 +183,12 @@
rockchip,pins = <0 14 RK_FUNC_GPIO &pcfg_pull_none>;
};
};
+
+ eth_phy {
+ eth_phy_pwr: eth-phy-pwr {
+ rockchip,pins = <0 6 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
};
&usb_host0_ehci {
--
1.7.9.5
^ permalink raw reply related
* [PATCH v3 4/6] ARM: dts: rockchip: add gmac info for rk3288
From: Roger Chen @ 2014-12-29 9:44 UTC (permalink / raw)
To: heiko
Cc: peppe.cavallaro, netdev, linux-kernel, linux-rockchip, kever.yang,
eddie.cai, roger.chen
In-Reply-To: <1419846152-14531-1-git-send-email-roger.chen@rock-chips.com>
add gmac info in rk3288.dtsi for GMAC driver
changes since v2:
1. add drive-strength in the pinctrl settings
Signed-off-by: Roger Chen <roger.chen@rock-chips.com>
---
arch/arm/boot/dts/rk3288.dtsi | 54 +++++++++++++++++++++++++++++++++++++++++
1 file changed, 54 insertions(+)
diff --git a/arch/arm/boot/dts/rk3288.dtsi b/arch/arm/boot/dts/rk3288.dtsi
index 0f50d5d..5a26db0 100644
--- a/arch/arm/boot/dts/rk3288.dtsi
+++ b/arch/arm/boot/dts/rk3288.dtsi
@@ -358,6 +358,22 @@
status = "disabled";
};
+ gmac: ethernet@ff290000 {
+ compatible = "rockchip,rk3288-gmac";
+ reg = <0xff290000 0x10000>;
+ interrupts = <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "macirq";
+ rockchip,grf = <&grf>;
+ clocks = <&cru SCLK_MAC>,
+ <&cru SCLK_MAC_RX>, <&cru SCLK_MAC_TX>,
+ <&cru SCLK_MACREF>, <&cru SCLK_MACREF_OUT>,
+ <&cru ACLK_GMAC>, <&cru PCLK_GMAC>;
+ clock-names = "stmmaceth",
+ "mac_clk_rx", "mac_clk_tx",
+ "clk_mac_ref", "clk_mac_refout",
+ "aclk_mac", "pclk_mac";
+ };
+
usb_host0_ehci: usb@ff500000 {
compatible = "generic-ehci";
reg = <0xff500000 0x100>;
@@ -703,6 +719,11 @@
bias-disable;
};
+ pcfg_pull_none_12ma: pcfg-pull-none-12ma {
+ bias-disable;
+ drive-strength = <12>;
+ };
+
i2c0 {
i2c0_xfer: i2c0-xfer {
rockchip,pins = <0 15 RK_FUNC_1 &pcfg_pull_none>,
@@ -1040,5 +1061,38 @@
rockchip,pins = <7 23 3 &pcfg_pull_none>;
};
};
+
+ gmac {
+ rgmii_pins: rgmii-pins {
+ rockchip,pins = <3 30 3 &pcfg_pull_none>,
+ <3 31 3 &pcfg_pull_none>,
+ <3 26 3 &pcfg_pull_none>,
+ <3 27 3 &pcfg_pull_none>,
+ <3 28 3 &pcfg_pull_none_12ma>,
+ <3 29 3 &pcfg_pull_none_12ma>,
+ <3 24 3 &pcfg_pull_none_12ma>,
+ <3 25 3 &pcfg_pull_none_12ma>,
+ <4 0 3 &pcfg_pull_none>,
+ <4 5 3 &pcfg_pull_none>,
+ <4 6 3 &pcfg_pull_none>,
+ <4 9 3 &pcfg_pull_none_12ma>,
+ <4 4 3 &pcfg_pull_none_12ma>,
+ <4 1 3 &pcfg_pull_none>,
+ <4 3 3 &pcfg_pull_none>;
+ };
+
+ rmii_pins: rmii-pins {
+ rockchip,pins = <3 30 3 &pcfg_pull_none>,
+ <3 31 3 &pcfg_pull_none>,
+ <3 28 3 &pcfg_pull_none>,
+ <3 29 3 &pcfg_pull_none>,
+ <4 0 3 &pcfg_pull_none>,
+ <4 5 3 &pcfg_pull_none>,
+ <4 4 3 &pcfg_pull_none>,
+ <4 1 3 &pcfg_pull_none>,
+ <4 2 3 &pcfg_pull_none>,
+ <4 3 3 &pcfg_pull_none>;
+ };
+ };
};
};
--
1.7.9.5
^ permalink raw reply related
* [PATCH v3 3/6] GMAC: modify CRU config for Rockchip RK3288 SoCs integrated GMAC
From: Roger Chen @ 2014-12-29 9:44 UTC (permalink / raw)
To: heiko
Cc: peppe.cavallaro, netdev, linux-kernel, linux-rockchip, kever.yang,
eddie.cai, roger.chen
In-Reply-To: <1419846152-14531-1-git-send-email-roger.chen@rock-chips.com>
modify CRU config for GMAC driver
changes since v2:
1. remove SCLK_MAC_PLL
Signed-off-by: Roger Chen <roger.chen@rock-chips.com>
---
drivers/clk/rockchip/clk-rk3288.c | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/drivers/clk/rockchip/clk-rk3288.c b/drivers/clk/rockchip/clk-rk3288.c
index 2327829..6e88a29 100644
--- a/drivers/clk/rockchip/clk-rk3288.c
+++ b/drivers/clk/rockchip/clk-rk3288.c
@@ -187,7 +187,7 @@ PNAME(mux_uart2_p) = { "uart2_src", "uart2_frac", "xin24m" };
PNAME(mux_uart3_p) = { "uart3_src", "uart3_frac", "xin24m" };
PNAME(mux_uart4_p) = { "uart4_src", "uart4_frac", "xin24m" };
PNAME(mux_cif_out_p) = { "cif_src", "xin24m" };
-PNAME(mux_macref_p) = { "mac_src", "ext_gmac" };
+PNAME(mux_mac_p) = { "mac_pll_src", "ext_gmac" };
PNAME(mux_hsadcout_p) = { "hsadc_src", "ext_hsadc" };
PNAME(mux_edp_24m_p) = { "ext_edp_24m", "xin24m" };
PNAME(mux_tspout_p) = { "cpll", "gpll", "npll", "xin27m" };
@@ -560,18 +560,18 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = {
MUX(SCLK_UART4, "sclk_uart4", mux_uart4_p, 0,
RK3288_CLKSEL_CON(3), 8, 2, MFLAGS),
- COMPOSITE(0, "mac_src", mux_pll_src_npll_cpll_gpll_p, 0,
+ COMPOSITE(0, "mac_pll_src", mux_pll_src_npll_cpll_gpll_p, 0,
RK3288_CLKSEL_CON(21), 0, 2, MFLAGS, 8, 5, DFLAGS,
RK3288_CLKGATE_CON(2), 5, GFLAGS),
- MUX(0, "macref", mux_macref_p, 0,
+ MUX(SCLK_MAC, "mac_clk", mux_mac_p, 0,
RK3288_CLKSEL_CON(21), 4, 1, MFLAGS),
- GATE(0, "sclk_macref_out", "macref", 0,
+ GATE(SCLK_MACREF_OUT, "sclk_macref_out", "mac_clk", 0,
RK3288_CLKGATE_CON(5), 3, GFLAGS),
- GATE(SCLK_MACREF, "sclk_macref", "macref", 0,
+ GATE(SCLK_MACREF, "sclk_macref", "mac_clk", 0,
RK3288_CLKGATE_CON(5), 2, GFLAGS),
- GATE(SCLK_MAC_RX, "sclk_mac_rx", "macref", 0,
+ GATE(SCLK_MAC_RX, "sclk_mac_rx", "mac_clk", 0,
RK3288_CLKGATE_CON(5), 0, GFLAGS),
- GATE(SCLK_MAC_TX, "sclk_mac_tx", "macref", 0,
+ GATE(SCLK_MAC_TX, "sclk_mac_tx", "mac_clk", 0,
RK3288_CLKGATE_CON(5), 1, GFLAGS),
COMPOSITE(0, "hsadc_src", mux_pll_src_cpll_gpll_p, 0,
--
1.7.9.5
^ permalink raw reply related
* [PATCH v3 2/6] GMAC: define clock ID used for GMAC
From: Roger Chen @ 2014-12-29 9:43 UTC (permalink / raw)
To: heiko
Cc: peppe.cavallaro, netdev, linux-kernel, linux-rockchip, kever.yang,
eddie.cai, roger.chen
In-Reply-To: <1419846152-14531-1-git-send-email-roger.chen@rock-chips.com>
changes since v2:
1. remove SCLK_MAC_PLL
Signed-off-by: Roger Chen <roger.chen@rock-chips.com>
---
include/dt-bindings/clock/rk3288-cru.h | 3 +++
1 file changed, 3 insertions(+)
diff --git a/include/dt-bindings/clock/rk3288-cru.h b/include/dt-bindings/clock/rk3288-cru.h
index 100a08c..81eb35b 100644
--- a/include/dt-bindings/clock/rk3288-cru.h
+++ b/include/dt-bindings/clock/rk3288-cru.h
@@ -72,6 +72,9 @@
#define SCLK_HEVC_CABAC 111
#define SCLK_HEVC_CORE 112
+#define SCLK_MAC 151
+#define SCLK_MACREF_OUT 152
+
#define DCLK_VOP0 190
#define DCLK_VOP1 191
--
1.7.9.5
^ permalink raw reply related
* [PATCH v3 1/6] GMAC: add driver for Rockchip RK3288 SoCs integrated GMAC
From: Roger Chen @ 2014-12-29 9:43 UTC (permalink / raw)
To: heiko
Cc: peppe.cavallaro, netdev, linux-kernel, linux-rockchip, kever.yang,
eddie.cai, roger.chen
In-Reply-To: <1419846152-14531-1-git-send-email-roger.chen@rock-chips.com>
This driver is based on stmmac driver.
changes since v2:
- use tab instead of space for macros
- use HIWORD_UPDATE macro for GMAC_CLK_RX_DL_CFG and GMAC_CLK_TX_DL_CFG
- remove drive-strength setting in the driver and set it in the pinctrl settings
- use dev_err instead of pr_err
- remove clock names's macros, just use the real name of the clock
- use devm_clk_get() instead of clk_get()
- remove clk_set_parent(bsp_priv->clk_mac, bsp_priv->clk_mac_pll)
- remove gpio setting for LDO, just use regulator API
- remove phy reset using gpio in the glue layer, it has been handled in the stmmac driver
- remove handling phy interrupt (mii interrupt)
changes since v1:
- use BIT() to set register
- combine two remap_write() operations into one for the same register
- use macros for register value setting
- remove grf fail check in rk_gmac_setup() and save all the check in set_rgmii_speed()
- remove .tx_coe=1 in rk_gmac_data
Signed-off-by: Roger Chen <roger.chen@rock-chips.com>
---
drivers/net/ethernet/stmicro/stmmac/Makefile | 2 +-
drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c | 459 ++++++++++++++++++++
.../net/ethernet/stmicro/stmmac/stmmac_platform.c | 1 +
.../net/ethernet/stmicro/stmmac/stmmac_platform.h | 1 +
4 files changed, 462 insertions(+), 1 deletion(-)
create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
diff --git a/drivers/net/ethernet/stmicro/stmmac/Makefile b/drivers/net/ethernet/stmicro/stmmac/Makefile
index ac4d562..73c2715 100644
--- a/drivers/net/ethernet/stmicro/stmmac/Makefile
+++ b/drivers/net/ethernet/stmicro/stmmac/Makefile
@@ -6,7 +6,7 @@ stmmac-objs:= stmmac_main.o stmmac_ethtool.o stmmac_mdio.o ring_mode.o \
obj-$(CONFIG_STMMAC_PLATFORM) += stmmac-platform.o
stmmac-platform-objs:= stmmac_platform.o dwmac-meson.o dwmac-sunxi.o \
- dwmac-sti.o dwmac-socfpga.o
+ dwmac-sti.o dwmac-socfpga.o dwmac-rk.o
obj-$(CONFIG_STMMAC_PCI) += stmmac-pci.o
stmmac-pci-objs:= stmmac_pci.o
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
new file mode 100644
index 0000000..35f9b86
--- /dev/null
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
@@ -0,0 +1,459 @@
+/**
+ * dwmac-rk.c - Rockchip RK3288 DWMAC specific glue layer
+ *
+ * Copyright (C) 2014 Chen-Zhi (Roger Chen)
+ *
+ * Chen-Zhi (Roger Chen) <roger.chen@rock-chips.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/stmmac.h>
+#include <linux/bitops.h>
+#include <linux/clk.h>
+#include <linux/phy.h>
+#include <linux/of_net.h>
+#include <linux/gpio.h>
+#include <linux/of_gpio.h>
+#include <linux/of_device.h>
+#include <linux/regulator/consumer.h>
+#include <linux/delay.h>
+#include <linux/mfd/syscon.h>
+#include <linux/regmap.h>
+
+struct rk_priv_data {
+ struct platform_device *pdev;
+ int phy_iface;
+ char regulator[32];
+
+ bool clk_enabled;
+ bool clock_input;
+
+ struct clk *clk_mac;
+ struct clk *clk_mac_pll;
+ struct clk *gmac_clkin;
+ struct clk *mac_clk_rx;
+ struct clk *mac_clk_tx;
+ struct clk *clk_mac_ref;
+ struct clk *clk_mac_refout;
+ struct clk *aclk_mac;
+ struct clk *pclk_mac;
+
+ int tx_delay;
+ int rx_delay;
+
+ struct regmap *grf;
+};
+
+#define HIWORD_UPDATE(val, mask, shift) \
+ ((val) << (shift) | (mask) << ((shift) + 16))
+
+#define GRF_BIT(nr) (BIT(nr) | BIT(nr+16))
+#define GRF_CLR_BIT(nr) (BIT(nr+16))
+
+#define RK3288_GRF_SOC_CON1 0x0248
+#define RK3288_GRF_SOC_CON3 0x0250
+#define RK3288_GRF_GPIO3D_E 0x01ec
+#define RK3288_GRF_GPIO4A_E 0x01f0
+#define RK3288_GRF_GPIO4B_E 0x01f4
+
+/*RK3288_GRF_SOC_CON1*/
+#define GMAC_PHY_INTF_SEL_RGMII (GRF_BIT(6) | GRF_CLR_BIT(7) | GRF_CLR_BIT(8))
+#define GMAC_PHY_INTF_SEL_RMII (GRF_CLR_BIT(6) | GRF_CLR_BIT(7) | GRF_BIT(8))
+#define GMAC_FLOW_CTRL GRF_BIT(9)
+#define GMAC_FLOW_CTRL_CLR GRF_CLR_BIT(9)
+#define GMAC_SPEED_10M GRF_CLR_BIT(10)
+#define GMAC_SPEED_100M GRF_BIT(10)
+#define GMAC_RMII_CLK_25M GRF_BIT(11)
+#define GMAC_RMII_CLK_2_5M GRF_CLR_BIT(11)
+#define GMAC_CLK_125M (GRF_CLR_BIT(12) | GRF_CLR_BIT(13))
+#define GMAC_CLK_25M (GRF_BIT(12) | GRF_BIT(13))
+#define GMAC_CLK_2_5M (GRF_CLR_BIT(12) | GRF_BIT(13))
+#define GMAC_RMII_MODE GRF_BIT(14)
+#define GMAC_RMII_MODE_CLR GRF_CLR_BIT(14)
+
+/*RK3288_GRF_SOC_CON3*/
+#define GMAC_TXCLK_DLY_ENABLE GRF_BIT(14)
+#define GMAC_TXCLK_DLY_DISABLE GRF_CLR_BIT(14)
+#define GMAC_RXCLK_DLY_ENABLE GRF_BIT(15)
+#define GMAC_RXCLK_DLY_DISABLE GRF_CLR_BIT(15)
+#define GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 7)
+#define GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0)
+
+static void set_to_rgmii(struct rk_priv_data *bsp_priv,
+ int tx_delay, int rx_delay)
+{
+ struct device *dev = &bsp_priv->pdev->dev;
+
+ if (IS_ERR(bsp_priv->grf)) {
+ dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
+ return;
+ }
+
+ regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1,
+ GMAC_PHY_INTF_SEL_RGMII | GMAC_RMII_MODE_CLR);
+ regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON3,
+ GMAC_RXCLK_DLY_ENABLE | GMAC_TXCLK_DLY_ENABLE |
+ GMAC_CLK_RX_DL_CFG(rx_delay) |
+ GMAC_CLK_TX_DL_CFG(tx_delay));
+}
+
+static void set_to_rmii(struct rk_priv_data *bsp_priv)
+{
+ struct device *dev = &bsp_priv->pdev->dev;
+
+ if (IS_ERR(bsp_priv->grf)) {
+ dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
+ return;
+ }
+
+ regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1,
+ GMAC_PHY_INTF_SEL_RMII | GMAC_RMII_MODE);
+}
+
+static void set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed)
+{
+ struct device *dev = &bsp_priv->pdev->dev;
+
+ if (IS_ERR(bsp_priv->grf)) {
+ dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
+ return;
+ }
+
+ if (speed == 10)
+ regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1, GMAC_CLK_2_5M);
+ else if (speed == 100)
+ regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1, GMAC_CLK_25M);
+ else if (speed == 1000)
+ regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1, GMAC_CLK_125M);
+ else
+ dev_err(dev, "unknown speed value for RGMII! speed=%d", speed);
+}
+
+static void set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
+{
+ struct device *dev = &bsp_priv->pdev->dev;
+
+ if (IS_ERR(bsp_priv->grf)) {
+ dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
+ return;
+ }
+
+ if (speed == 10) {
+ regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1,
+ GMAC_RMII_CLK_2_5M | GMAC_SPEED_10M);
+ } else if (speed == 100) {
+ regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1,
+ GMAC_RMII_CLK_25M | GMAC_SPEED_100M);
+ } else {
+ dev_err(dev, "unknown speed value for RMII! speed=%d", speed);
+ }
+}
+
+static int gmac_clk_init(struct rk_priv_data *bsp_priv)
+{
+ struct device *dev = &bsp_priv->pdev->dev;
+
+ bsp_priv->clk_enabled = false;
+
+ bsp_priv->mac_clk_rx = devm_clk_get(dev, "mac_clk_rx");
+ if (IS_ERR(bsp_priv->mac_clk_rx))
+ dev_err(dev, "%s: cannot get clock %s\n",
+ __func__, "mac_clk_rx");
+
+ bsp_priv->mac_clk_tx = devm_clk_get(dev, "mac_clk_tx");
+ if (IS_ERR(bsp_priv->mac_clk_tx))
+ dev_err(dev, "%s: cannot get clock %s\n",
+ __func__, "mac_clk_tx");
+
+ bsp_priv->aclk_mac = devm_clk_get(dev, "aclk_mac");
+ if (IS_ERR(bsp_priv->aclk_mac))
+ dev_err(dev, "%s: cannot get clock %s\n",
+ __func__, "aclk_mac");
+
+ bsp_priv->pclk_mac = devm_clk_get(dev, "pclk_mac");
+ if (IS_ERR(bsp_priv->pclk_mac))
+ dev_err(dev, "%s: cannot get clock %s\n",
+ __func__, "pclk_mac");
+
+ bsp_priv->clk_mac = devm_clk_get(dev, "stmmaceth");
+ if (IS_ERR(bsp_priv->clk_mac))
+ dev_err(dev, "%s: cannot get clock %s\n",
+ __func__, "stmmaceth");
+
+ if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RMII) {
+ bsp_priv->clk_mac_ref = devm_clk_get(dev, "clk_mac_ref");
+ if (IS_ERR(bsp_priv->clk_mac_ref))
+ dev_err(dev, "%s: cannot get clock %s\n",
+ __func__, "clk_mac_ref");
+
+ if (!bsp_priv->clock_input) {
+ bsp_priv->clk_mac_refout =
+ devm_clk_get(dev, "clk_mac_refout");
+ if (IS_ERR(bsp_priv->clk_mac_refout))
+ dev_err(dev, "%s: cannot get clock %s\n",
+ __func__, "clk_mac_refout");
+ }
+ }
+
+ if (bsp_priv->clock_input) {
+ dev_info(dev, "%s: clock input from PHY\n", __func__);
+ } else {
+ if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RMII)
+ clk_set_rate(bsp_priv->clk_mac_pll, 50000000);
+ }
+
+ return 0;
+}
+
+static int gmac_clk_enable(struct rk_priv_data *bsp_priv, bool enable)
+{
+ int phy_iface = phy_iface = bsp_priv->phy_iface;
+
+ if (enable) {
+ if (!bsp_priv->clk_enabled) {
+ if (phy_iface == PHY_INTERFACE_MODE_RMII) {
+ if (!IS_ERR(bsp_priv->mac_clk_rx))
+ clk_prepare_enable(
+ bsp_priv->mac_clk_rx);
+
+ if (!IS_ERR(bsp_priv->clk_mac_ref))
+ clk_prepare_enable(
+ bsp_priv->clk_mac_ref);
+
+ if (!IS_ERR(bsp_priv->clk_mac_refout))
+ clk_prepare_enable(
+ bsp_priv->clk_mac_refout);
+ }
+
+ if (!IS_ERR(bsp_priv->aclk_mac))
+ clk_prepare_enable(bsp_priv->aclk_mac);
+
+ if (!IS_ERR(bsp_priv->pclk_mac))
+ clk_prepare_enable(bsp_priv->pclk_mac);
+
+ if (!IS_ERR(bsp_priv->mac_clk_tx))
+ clk_prepare_enable(bsp_priv->mac_clk_tx);
+
+ /**
+ * if (!IS_ERR(bsp_priv->clk_mac))
+ * clk_prepare_enable(bsp_priv->clk_mac);
+ */
+ mdelay(5);
+ bsp_priv->clk_enabled = true;
+ }
+ } else {
+ if (bsp_priv->clk_enabled) {
+ if (phy_iface == PHY_INTERFACE_MODE_RMII) {
+ if (!IS_ERR(bsp_priv->mac_clk_rx))
+ clk_disable_unprepare(
+ bsp_priv->mac_clk_rx);
+
+ if (!IS_ERR(bsp_priv->clk_mac_ref))
+ clk_disable_unprepare(
+ bsp_priv->clk_mac_ref);
+
+ if (!IS_ERR(bsp_priv->clk_mac_refout))
+ clk_disable_unprepare(
+ bsp_priv->clk_mac_refout);
+ }
+
+ if (!IS_ERR(bsp_priv->aclk_mac))
+ clk_disable_unprepare(bsp_priv->aclk_mac);
+
+ if (!IS_ERR(bsp_priv->pclk_mac))
+ clk_disable_unprepare(bsp_priv->pclk_mac);
+
+ if (!IS_ERR(bsp_priv->mac_clk_tx))
+ clk_disable_unprepare(bsp_priv->mac_clk_tx);
+ /**
+ * if (!IS_ERR(bsp_priv->clk_mac))
+ * clk_disable_unprepare(bsp_priv->clk_mac);
+ */
+ bsp_priv->clk_enabled = false;
+ }
+ }
+
+ return 0;
+}
+
+static int phy_power_on(struct rk_priv_data *bsp_priv, bool enable)
+{
+ struct regulator *ldo;
+ char *ldostr = bsp_priv->regulator;
+ int ret;
+ struct device *dev = &bsp_priv->pdev->dev;
+
+ if (!ldostr) {
+ dev_err(dev, "%s: no ldo found\n", __func__);
+ return -1;
+ }
+
+ ldo = regulator_get(NULL, ldostr);
+ if (!ldo) {
+ dev_err(dev, "\n%s get ldo %s failed\n", __func__, ldostr);
+ } else {
+ if (enable) {
+ if (!regulator_is_enabled(ldo)) {
+ regulator_set_voltage(ldo, 3300000, 3300000);
+ ret = regulator_enable(ldo);
+ if (ret != 0)
+ dev_err(dev, "%s: fail to enable %s\n",
+ __func__, ldostr);
+ else
+ dev_info(dev, "turn on ldo done.\n");
+ } else {
+ dev_warn(dev, "%s is enabled before enable",
+ ldostr);
+ }
+ } else {
+ if (regulator_is_enabled(ldo)) {
+ ret = regulator_disable(ldo);
+ if (ret != 0)
+ dev_err(dev, "%s: fail to disable %s\n",
+ __func__, ldostr);
+ else
+ dev_info(dev, "turn off ldo done.\n");
+ } else {
+ dev_warn(dev, "%s is disabled before disable",
+ ldostr);
+ }
+ }
+ regulator_put(ldo);
+ }
+
+ return 0;
+}
+
+static void *rk_gmac_setup(struct platform_device *pdev)
+{
+ struct rk_priv_data *bsp_priv;
+ struct device *dev = &pdev->dev;
+ int ret;
+ const char *strings = NULL;
+ int value;
+
+ bsp_priv = devm_kzalloc(dev, sizeof(*bsp_priv), GFP_KERNEL);
+ if (!bsp_priv)
+ return ERR_PTR(-ENOMEM);
+
+ bsp_priv->phy_iface = of_get_phy_mode(dev->of_node);
+
+ ret = of_property_read_string(dev->of_node, "phy_regulator", &strings);
+ if (ret) {
+ dev_warn(dev, "%s: Can not read property: phy_regulator.\n",
+ __func__);
+ } else {
+ dev_info(dev, "%s: PHY power controlled by regulator(%s).\n",
+ __func__, strings);
+ strcpy(bsp_priv->regulator, strings);
+ }
+
+ ret = of_property_read_string(dev->of_node, "clock_in_out", &strings);
+ if (ret) {
+ dev_err(dev, "%s: Can not read property: clock_in_out.\n",
+ __func__);
+ bsp_priv->clock_input = true;
+ } else {
+ dev_info(dev, "%s: clock input or output? (%s).\n",
+ __func__, strings);
+ if (!strcmp(strings, "input"))
+ bsp_priv->clock_input = true;
+ else
+ bsp_priv->clock_input = false;
+ }
+
+ ret = of_property_read_u32(dev->of_node, "tx_delay", &value);
+ if (ret) {
+ bsp_priv->tx_delay = 0x30;
+ dev_err(dev, "%s: Can not read property: tx_delay.", __func__);
+ dev_err(dev, "%s: set tx_delay to 0x%x\n",
+ __func__, bsp_priv->tx_delay);
+ } else {
+ dev_info(dev, "%s: TX delay(0x%x).\n", __func__, value);
+ bsp_priv->tx_delay = value;
+ }
+
+ ret = of_property_read_u32(dev->of_node, "rx_delay", &value);
+ if (ret) {
+ bsp_priv->rx_delay = 0x10;
+ dev_err(dev, "%s: Can not read property: rx_delay.", __func__);
+ dev_err(dev, "%s: set rx_delay to 0x%x\n",
+ __func__, bsp_priv->rx_delay);
+ } else {
+ dev_info(dev, "%s: RX delay(0x%x).\n", __func__, value);
+ bsp_priv->rx_delay = value;
+ }
+
+ bsp_priv->grf = syscon_regmap_lookup_by_phandle(dev->of_node,
+ "rockchip,grf");
+ bsp_priv->pdev = pdev;
+
+ /*rmii or rgmii*/
+ if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RGMII) {
+ dev_info(dev, "%s: init for RGMII\n", __func__);
+ set_to_rgmii(bsp_priv, bsp_priv->tx_delay, bsp_priv->rx_delay);
+ } else if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RMII) {
+ dev_info(dev, "%s: init for RMII\n", __func__);
+ set_to_rmii(bsp_priv);
+ } else {
+ dev_err(dev, "%s: NO interface defined!\n", __func__);
+ }
+
+ gmac_clk_init(bsp_priv);
+
+ return bsp_priv;
+}
+
+static int rk_gmac_init(struct platform_device *pdev, void *priv)
+{
+ struct rk_priv_data *bsp_priv = priv;
+ int ret;
+
+ ret = phy_power_on(bsp_priv, true);
+ if (ret)
+ return ret;
+
+ ret = gmac_clk_enable(bsp_priv, true);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static void rk_gmac_exit(struct platform_device *pdev, void *priv)
+{
+ struct rk_priv_data *gmac = priv;
+
+ phy_power_on(gmac, false);
+ gmac_clk_enable(gmac, false);
+}
+
+static void rk_fix_speed(void *priv, unsigned int speed)
+{
+ struct rk_priv_data *bsp_priv = priv;
+ struct device *dev = &bsp_priv->pdev->dev;
+
+ if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RGMII)
+ set_rgmii_speed(bsp_priv, speed);
+ else if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RMII)
+ set_rmii_speed(bsp_priv, speed);
+ else
+ dev_err(dev, "unsupported interface %d", bsp_priv->phy_iface);
+}
+
+const struct stmmac_of_data rk3288_gmac_data = {
+ .has_gmac = 1,
+ .fix_mac_speed = rk_fix_speed,
+ .setup = rk_gmac_setup,
+ .init = rk_gmac_init,
+ .exit = rk_gmac_exit,
+};
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
index 15814b7..6794993 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
@@ -33,6 +33,7 @@
static const struct of_device_id stmmac_dt_ids[] = {
/* SoC specific glue layers should come before generic bindings */
+ { .compatible = "rockchip,rk3288-gmac", .data = &rk3288_gmac_data},
{ .compatible = "amlogic,meson6-dwmac", .data = &meson6_dwmac_data},
{ .compatible = "allwinner,sun7i-a20-gmac", .data = &sun7i_gmac_data},
{ .compatible = "st,stih415-dwmac", .data = &stih4xx_dwmac_data},
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.h b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.h
index 25dd1f7..093eb99 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.h
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.h
@@ -24,5 +24,6 @@ extern const struct stmmac_of_data sun7i_gmac_data;
extern const struct stmmac_of_data stih4xx_dwmac_data;
extern const struct stmmac_of_data stid127_dwmac_data;
extern const struct stmmac_of_data socfpga_gmac_data;
+extern const struct stmmac_of_data rk3288_gmac_data;
#endif /* __STMMAC_PLATFORM_H__ */
--
1.7.9.5
^ permalink raw reply related
* [PATCH v3 0/6] support GMAC driver for RK3288
From: Roger Chen @ 2014-12-29 9:42 UTC (permalink / raw)
To: heiko
Cc: peppe.cavallaro, netdev, linux-kernel, linux-rockchip, kever.yang,
eddie.cai, roger.chen
Roger Chen (6):
patch1: add driver for Rockchip RK3288 SoCs integrated GMAC
patch2: define clock ID used for GMAC
patch3: modify CRU config for Rockchip RK3288 SoCs integrated GMAC
patch4: dts: rockchip: add gmac info for rk3288
patch5: dts: rockchip: enable gmac on RK3288 evb board
patch6: add document for Rockchip RK3288 GMAC
Tested on rk3288 evb board:
Execute the following command to enable ethernet,
set local IP and ping a remote host.
busybox ifconfig eth0 up
busybox ifconfig eth0 192.168.1.111
ping 192.168.1.1
--
1.7.9.5
^ permalink raw reply
* Re: am335x: cpsw: interrupt failure
From: Yegor Yefremov @ 2014-12-29 9:33 UTC (permalink / raw)
To: Felipe Balbi; +Cc: netdev, N, Mugunthan V, linux-omap@vger.kernel.org
In-Reply-To: <CAGm1_kuYrGsfjRO6TVr554yS8dcD4_Z9-j9KL0xpD=X+31OkXQ@mail.gmail.com>
On Fri, Dec 12, 2014 at 8:19 PM, Yegor Yefremov
<yegorslists@googlemail.com> wrote:
> On Fri, Dec 12, 2014 at 6:32 PM, Felipe Balbi <balbi@ti.com> wrote:
>> Hi,
>>
>> On Fri, Dec 12, 2014 at 01:00:51PM +0100, Yegor Yefremov wrote:
>>> U-Boot version: 2014.07
>>> Kernel config is omap2plus with enabled USB
>>>
>>> # cat /proc/version
>>> Linux version 3.18.0 (user@user-VirtualBox) (gcc version 4.8.3
>>> 20140320 (prerelease) (Sourcery CodeBench Lite 2014.05-29) ) #6 SMP
>>> Mon Dec 8 22:47:43 CET 2014
>>
>> Wasn't GCC 4.8.x total crap for building ARM kernels ? IIRC it was even
>> blacklisted. Can you try with 4.9.x just to make sure ?
>
> Will do.
Adding linux-omap. Beginning of this discussion:
http://comments.gmane.org/gmane.linux.network/341427
Quick summary: starting with kernel 3.18 or commit
55601c9f24670ba926ebdd4d712ac3b177232330 am335x (at least BBB and some
custom boards) stalls at high network load. Reproducible via nuttcp
within some minutes
nuttcp -S (on BBB)
nuttcp -t -N 4 -T30m 192.168.1.235 (on host)
As Felipe Balbi suggested, I tried both 4.8.3 and 4.9.2 toolchains,
but both show the same behavior.
Linux version 3.18.0 (user@user-VirtualBox) (gcc version 4.8.3
20140320 (prerelease) (Sourcery CodeBench Lite 2014.05-29) ) #6 SMP
Mon Dec 8 22:47:43 CET 2014
Linux version 3.18.1 (user@user-VirtualBox) (gcc version 4.9.2
(Buildroot 2015.02-git-00582-g10b9761) ) #1 SMP Mon Dec 29 09:22:29
CET 2014
Let me know, if you can reproduce this issue.
Thanks.
Yegor
^ permalink raw reply
* Re: [PATCH] ipnetns: fix exec for netns not in NETNS_RUN_DIR
From: Shahar Lev @ 2014-12-29 9:25 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: netdev
In-Reply-To: <20141227100548.4fbd3e31@urahara>
>
> This breaks existing users since you now require full pathname.
>
Providing a full path is not a requirement.
If there's no dash ('/') in the parameter provided it defaults to
opening relative to NETNS_RUN_DIR (the existing behavior).
So this is just an extension.
^ permalink raw reply
* Re: [PATCH net-next] net: stmmac: add BQL support
From: Florian Fainelli @ 2014-12-29 7:48 UTC (permalink / raw)
To: Beniamino Galvani
Cc: David S. Miller, Giuseppe Cavallaro, netdev,
linux-kernel@vger.kernel.org
In-Reply-To: <1419778631-23067-1-git-send-email-b.galvani@gmail.com>
2014-12-28 6:57 GMT-08:00 Beniamino Galvani <b.galvani@gmail.com>:
> Add support for Byte Queue Limits to the STMicro MAC driver.
>
> Tested on a Amlogic S805 Cortex-A5 board, where the use of BQL
> slightly decreases the ping latency from ~10ms to ~3ms when the
> 100Mbps link is saturated by TCP streams. No difference is
> observed at 1Gbps.
>
> Signed-off-by: Beniamino Galvani <b.galvani@gmail.com>
> ---
[snip]
> priv->dev->stats.tx_errors++;
> @@ -2049,6 +2057,7 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)
> skb_tx_timestamp(skb);
>
> priv->hw->dma->enable_dma_transmission(priv->ioaddr);
> + netdev_sent_queue(dev, skb->len);
You are introducing a potential use after free here in case tx_lock is
eliminated one day and your TX reclaim logic kicks in and frees the
freshly transmitted SKB, it would be safer to just cache skb->len in a
local variable, and use it here.
>
> spin_unlock(&priv->tx_lock);
> return NETDEV_TX_OK;
--
Florian
^ permalink raw reply
* RE: [PATCH/RFC flow-net-next 04/10] net: flow: Add counters to flows
From: Arad, Ronen @ 2014-12-29 7:31 UTC (permalink / raw)
To: Simon Horman, Fastabend, John R, netdev@vger.kernel.org
In-Reply-To: <1419819340-19000-5-git-send-email-simon.horman@netronome.com>
>-----Original Message-----
>From: netdev-owner@vger.kernel.org [mailto:netdev-owner@vger.kernel.org] On
>Behalf Of Simon Horman
>Sent: Monday, December 29, 2014 4:16 AM
>To: Fastabend, John R; netdev@vger.kernel.org
>Cc: Simon Horman
>Subject: [PATCH/RFC flow-net-next 04/10] net: flow: Add counters to flows
>
>It may be useful for hardware flow table support for counters to be exposed
>via the flow API. One possible use case of this is for Open vSwitch to use
>the flow API in conjunction with its existing datapath flow management
>scheme which in a nutshell treats the datapath as a cache that times out
>idle entries.
>
>This patch exposes optionally exposes three counters:
>- Number of packets that have matched a flow
>- Number of bytes of packets that have matched a flow
>- The time in ms when the flow was last hit
>
>Inspired by the flow counters present in Open Flow.
>
>Signed-off-by: Simon Horman <simon.horman@netronome.com>
>
>---
>
>Compile tested only
>---
> include/uapi/linux/if_flow.h | 24 ++++++++++++++++++++++++
> net/core/flow_table.c | 27 +++++++++++++++++++++++++++
> 2 files changed, 51 insertions(+)
>
>diff --git a/include/uapi/linux/if_flow.h b/include/uapi/linux/if_flow.h
>index 28da45b..18214ea 100644
>--- a/include/uapi/linux/if_flow.h
>+++ b/include/uapi/linux/if_flow.h
>@@ -127,6 +127,9 @@
> * [NET_FLOW_ATTR_PRIORITY]
> * [NET_FLOW_ATTR_IDLE_TIMEOUT]
> * [NET_FLOW_ATTR_HARD_TIMEOUT]
>+ * [NET_FLOW_ATTR_BYTE_COUNT]
>+ * [NET_FLOW_ATTR_PACKET_COUNT]
>+ * [NET_FLOW_ATTR_LAST_USED]
> * [NET_FLOW_ATTR_MATCHES]
> * [NET_FLOW_FIELD_REF]
> * [NET_FLOW_FIELD_REF]
>@@ -153,6 +156,9 @@
> * [NET_FLOW_ATTR_PRIORITY]
> * [NET_FLOW_ATTR_IDLE_TIMEOUT]
> * [NET_FLOW_ATTR_HARD_TIMEOUT]
>+ * [NET_FLOW_ATTR_BYTE_COUNT]
>+ * [NET_FLOW_ATTR_PACKET_COUNT]
>+ * [NET_FLOW_ATTR_LAST_USED]
> * [NET_FLOW_MATCHES]
> * [NET_FLOW_FIELD_REF]
> * [NET_FLOW_FIELD_REF]
>@@ -365,6 +371,9 @@ enum {
> * @idle_timeout idle timeout of flow in seconds. Zero for no timeout.
> * @hard_timeout timeout of flow regardless of use in seconds.
> * Zero for no timeout.
>+ * @byte_count bytes recieved
>+ * @byte_count packets recieved
>+ * @last_used time of most recent use (msec since system initialisation)
> *
> * Flows must match all entries in match set.
> */
>@@ -374,6 +383,9 @@ struct net_flow_flow {
> int priority;
> __u32 idle_timeout;
> __u32 hard_timeout;
>+ __u64 byte_count;
>+ __u64 packet_count;
>+ __u64 last_used;
> struct net_flow_field_ref *matches;
> struct net_flow_action *actions;
> };
>@@ -414,6 +426,9 @@ enum {
> NET_FLOW_ATTR_ACTIONS,
> NET_FLOW_ATTR_IDLE_TIMEOUT,
> NET_FLOW_ATTR_HARD_TIMEOUT,
>+ NET_FLOW_ATTR_BYTE_COUNT,
>+ NET_FLOW_ATTR_PACKET_COUNT,
>+ NET_FLOW_ATTR_LAST_USED,
> __NET_FLOW_ATTR_MAX,
> };
> #define NET_FLOW_ATTR_MAX (__NET_FLOW_ATTR_MAX - 1)
>@@ -465,6 +480,15 @@ enum {
>
> /* Table supports idle timeout of flows */
> NET_FLOW_TABLE_F_HARD_TIMEOUT = (1 << 1),
>+
>+ /* Table supports byte counter for flows */
>+ NET_FLOW_TABLE_F_BYTE_COUNT = (1 << 2),
>+
>+ /* Table supports packet counter for flows */
>+ NET_FLOW_TABLE_F_PACKET_COUNT = (1 << 3),
>+
>+ /* Table supports last used counter for flows */
>+ NET_FLOW_TABLE_F_PACKET_LAST_USED = (1 << 4),
> };
>
> #if 0
>diff --git a/net/core/flow_table.c b/net/core/flow_table.c
>index 89ba9bc..070e646 100644
>--- a/net/core/flow_table.c
>+++ b/net/core/flow_table.c
>@@ -54,6 +54,9 @@ struct nla_policy net_flow_flow_policy[NET_FLOW_ATTR_MAX +
>1] = {
> [NET_FLOW_ATTR_PRIORITY] = { .type = NLA_U32 },
> [NET_FLOW_ATTR_IDLE_TIMEOUT] = { .type = NLA_U32 },
> [NET_FLOW_ATTR_HARD_TIMEOUT] = { .type = NLA_U32 },
>+ [NET_FLOW_ATTR_BYTE_COUNT] = { .type = NLA_U64 },
>+ [NET_FLOW_ATTR_PACKET_COUNT] = { .type = NLA_U64 },
>+ [NET_FLOW_ATTR_LAST_USED] = { .type = NLA_U64 },
> [NET_FLOW_ATTR_MATCHES] = { .type = NLA_NESTED },
> [NET_FLOW_ATTR_ACTIONS] = { .type = NLA_NESTED },
> };
>@@ -206,6 +209,16 @@ int net_flow_put_flow(struct sk_buff *skb, struct
>net_flow_flow *flow)
> nla_put_u32(skb, NET_FLOW_ATTR_HARD_TIMEOUT, flow->hard_timeout))
> goto flows_put_failure;
>
>+ if (flow->byte_count &&
>+ nla_put_u32(skb, NET_FLOW_ATTR_BYTE_COUNT, flow->byte_count))
>+ goto flows_put_failure;
>+ if (flow->packet_count &&
>+ nla_put_u32(skb, NET_FLOW_ATTR_PACKET_COUNT, flow->packet_count))
>+ goto flows_put_failure;
>+ if (flow->last_used &&
>+ nla_put_u32(skb, NET_FLOW_ATTR_LAST_USED, flow->last_used))
>+ goto flows_put_failure;
>+
The flow byte_count, packet_count, and last_used fields are defined as __u64 and related netlink attributes are of type NLA_U64 but nla_put_u32() is used to add them to the netlink msg.
> matches = nla_nest_start(skb, NET_FLOW_ATTR_MATCHES);
> if (!matches)
> goto flows_put_failure;
>@@ -536,6 +549,13 @@ static int net_flow_get_flow(struct net_flow_flow *flow,
>struct nlattr *attr)
> if (f[NET_FLOW_ATTR_HARD_TIMEOUT])
> flow->hard_timeout = nla_get_u32(f[NET_FLOW_ATTR_HARD_TIMEOUT]);
>
>+ if (f[NET_FLOW_ATTR_BYTE_COUNT])
>+ flow->byte_count = nla_get_u64(f[NET_FLOW_ATTR_BYTE_COUNT]);
>+ if (f[NET_FLOW_ATTR_PACKET_COUNT])
>+ flow->packet_count = nla_get_u64(f[NET_FLOW_ATTR_PACKET_COUNT]);
>+ if (f[NET_FLOW_ATTR_LAST_USED])
>+ flow->last_used = nla_get_u64(f[NET_FLOW_ATTR_LAST_USED]);
>+
> flow->matches = NULL;
> flow->actions = NULL;
>
>@@ -1386,6 +1406,13 @@ static int net_flow_table_cmd_flows(struct sk_buff
>*recv_skb,
> if (this.hard_timeout)
> used_features |= NET_FLOW_TABLE_F_HARD_TIMEOUT;
>
>+ if (this.byte_count)
>+ used_features |= NET_FLOW_TABLE_F_BYTE_COUNT;
>+ if (this.packet_count)
>+ used_features |= NET_FLOW_TABLE_F_PACKET_COUNT;
>+ if (this.last_used)
>+ used_features |= NET_FLOW_TABLE_F_PACKET_LAST_USED;
>+
> err = net_flow_table_check_features(dev, this.table_id,
> used_features);
> if (err)
>--
>2.1.3
>
>--
>To unsubscribe from this list: send the line "unsubscribe netdev" in
>the body of a message to majordomo@vger.kernel.org
>More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH] bonding: move ipoib_header_ops to vmlinux
From: Wengang @ 2014-12-29 7:13 UTC (permalink / raw)
To: David Miller
Cc: netdev-u79uwXL29TY76Z2rM5mHXA, linux-rdma-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20141125.010741.450666241983239119.davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org>
Hi David,
This is a real case not a potential crash. The call stack is like this:
crash> bt
PID: 47323 TASK: ffff881722954140 CPU: 13 COMMAND: "arping"
#0 [ffff881518437860] machine_kexec at ffffffff8103aac9
#1 [ffff8815184378d0] crash_kexec at ffffffff810b9943
#2 [ffff8815184379a0] oops_end at ffffffff8150e9b8
#3 [ffff8815184379d0] no_context at ffffffff8104855c
#4 [ffff881518437a10] __bad_area_nosemaphore at ffffffff81048685
#5 [ffff881518437a60] bad_area_nosemaphore at ffffffff810487e3
#6 [ffff881518437a70] do_page_fault at ffffffff81511558
#7 [ffff881518437b80] page_fault at ffffffff8150df55
[exception RIP: packet_snd+608]
RIP: ffffffff814ddbc0 RSP: ffff881518437c38 RFLAGS: 00010282
RAX: ffffffffa0316040 RBX: ffff881518437e58 RCX: 0000000000000000
RDX: 0000000000000048 RSI: 0000000000000038 RDI: ffff88172508a080
RBP: ffff881518437ca8 R8: ffff88176568f400 R9: 0000000000000038
R10: ffff88172508a080 R11: 0000000000000000 R12: ffff8817e94f2080
R13: ffff8817eba0f400 R14: ffff8817eaef6000 R15: 0000000000000038
ORIG_RAX: ffffffffffffffff CS: 0010 SS: 0018
#8 [ffff881518437cb0] packet_sendmsg at ffffffff814ddee3
#9 [ffff881518437cc0] sock_sendmsg at ffffffff8142ad3f
#10 [ffff881518437e40] sys_sendto at ffffffff8142af09
#11 [ffff881518437f80] system_call_fastpath at ffffffff81515c42
RIP: 00007f4a03095853 RSP: 00007fffad354bf8 RFLAGS: 00010202
RAX: 000000000000002c RBX: ffffffff81515c42 RCX: 00007f4a02fde7ce
RDX: 0000000000000038 RSI: 00007fffad354ab0 RDI: 0000000000000003
RBP: 0000000000000038 R8: 00007f4a03b87e00 R9: 0000000000000020
R10: 0000000000000000 R11: 0000000000000246 R12: 00007f4a03b87e00
R13: 00007f4a03b87e4c R14: 00007fffad354ae4 R15: 00007f4a03b87e98
ORIG_RAX: 000000000000002c CS: 0033 SS: 002b
Though the crash is not based on mainline code, mainline has the same issue.
I think Or Gerlitz answered the question "IPOIB should not work over
bonding as it requires that the device use ARPHRD_ETHER.".
IPoIB devices can be enslaved to both bonding and teaming in their HA mode,
the bond device type becomes ARPHRD_INFINIBAND when this happens.
So, what information else do you need?
thanks,
wengang
于 2014年11月25日 14:07, David Miller 写道:
> From: Wengang Wang <wen.gang.wang-QHcLZuEGTsvQT0dZR+AlfA@public.gmane.org>
> Date: Tue, 25 Nov 2014 13:36:08 +0800
>
>> When last slave of a bonding master is removed, the bonding then does not work.
>> At the time if packet_snd is called against with a master net_device, it calls
>> then header_ops->create which points to slave's header_ops. In case the slave
>> is ipoib and the module is unloaded, header_ops would point to invalid address.
>> Accessing it will cause problem.
>> This patch tries to fix this issue by moving ipoib_header_ops to vmlinux to keep
>> it valid even when ipoib module is unloaded.
>>
>> Signed-off-by: Wengang Wang <wen.gang.wang-QHcLZuEGTsvQT0dZR+AlfA@public.gmane.org>
> IPOIB should not work over bonding as it requires that the device
> use ARPHRD_ETHER.
>
> Someone mentioned this, and I did not see any response.
>
> Please show how a legitimate real bonding configuration can be
> created, reproduce a stray memory access, and therefore potentially
> cause a crash.
>
> Using various debugging features of the kernel should allow you to
> trigger an assertion quite easily if this bug really exists.
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: net-next + qemu
From: Michael S. Tsirkin @ 2014-12-29 7:03 UTC (permalink / raw)
To: Scott Feldman; +Cc: David Miller, netdev
In-Reply-To: <CAE4R7bB8Fdx2u+RmX=HAhz8T-GHWtot7fSU-PKCrUYvxMnf0aQ@mail.gmail.com>
On Sun, Dec 28, 2014 at 10:48:40PM -0800, Scott Feldman wrote:
> Hi Michael,
>
> I was doing some testing with latest net-next and latest qemu and
> can't get Linux to load an image when using -drive
> file=xxx.img,if=virtio. I git bisected net-next and the breakage
> happened on this commit in net-next:
>
> 38eb4a2 virtio_pci: split out legacy device support
>
> Qemu image will load if I remove if=virtio.
>
> Are things in transition right now, and I just got unlucky with this
> combination of net-next and qemu?
>
> -scott
Yes, if you make virtio-pci modular, it won't load unless
you have this commit:
commit 5ff16110c637726111662c1df41afd9df7ef36bd
Author: Herbert Xu <herbert@gondor.apana.org.au>
Date: Wed Dec 17 00:54:03 2014 +0200
virtio_pci: restore module attributes
So v3.19-rc1 is OK, but net-next/master is not.
Dave - will v3.19-rc1 be merged into net-next?
Could you please confirm?
--
MST
^ permalink raw reply
* Re: [PATCH v3 00/20] kselftest install target feature
From: Michael Ellerman @ 2014-12-29 4:53 UTC (permalink / raw)
To: Shuah Khan
Cc: mmarek-AlSwsSmVLrQ, gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r,
akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
rostedt-nx8X9YLhiw1AfugRpC6u6w, mingo-H+wXaHxf7aLQT0dZR+AlfA,
davem-fT/PcQaiUtIeIZ0/mPfg9Q, keescook-F7+t8E8rja9g9hUCZPvPmw,
tranmanphong-Re5JQEeQqe8AvxtiuMwx3w, cov-sgV2jX0FEOL9JmXXK+q4OQ,
dh.herrmann-Re5JQEeQqe8AvxtiuMwx3w, hughd-hpIqsD4AKlfQT0dZR+AlfA,
bobby.prani-Re5JQEeQqe8AvxtiuMwx3w,
serge.hallyn-GeWIH/nMZzLQT0dZR+AlfA,
ebiederm-aS9lmoZGLiVWk0Htik3J/w, tim.bird-/MT0OVThwyLZJqsBc5GL+g,
josh-iaAMLnmF4UmaiuxdJuQwMA, koct9i-Re5JQEeQqe8AvxtiuMwx3w,
linux-kbuild-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-api-u79uwXL29TY76Z2rM5mHXA, netdev-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <cover.1419387513.git.shuahkh-JPH+aEBZ4P+UEJcrhfAQsw@public.gmane.org>
On Wed, 2014-12-24 at 09:27 -0700, Shuah Khan wrote:
> This patch series adds a new kselftest_install make target
> to enable selftest install. When make kselftest_install is
> run, selftests are installed on the system. A new install
> target is added to selftests Makefile which will install
> targets for the tests that are specified in INSTALL_TARGETS.
> During install, a script is generated to run tests that are
> installed. This script will be installed in the selftest install
> directory. Individual test Makefiles are changed to add to the
> script. This will allow new tests to add install and run test
> commands to the generated kselftest script. kselftest target
> now depends on kselftest_install and runs the generated kselftest
> script to reduce duplicate work and for common look and feel when
> running tests.
>
> This approach leverages and extends the existing framework that
> uses makefile targets to implement run_tests and adds install
> target. This will scale well as new tests get added and makes
> it easier for test writers to add install target at the same
> time new test gets added.
>
> This v3 series reduces duplicate code to generate script
> in indiviual test Makefiles and consolidates support in
> selftests main Makefile. In the main Makefile, it does
> minimal work to set and export install path. In this
> series exec and powerpc tests are not included in the
> install, this work will be done in future patches. exec
> and powerpc are still run when make kselftest is invoked.
Any particular reason you excluded the powerpc tests? Going by a quick count,
powerpc has 32 of the 54 self tests, ie. more than half.
Sorry I didn't get a chance to review v1 or v2, but is this really the best
solution we can come up with? It seems to involve a lot of boiler plate getting
repeated in every Makefile.
I'm off this week so I can't immediately come up with something better, I'll
try in the new year.
cheers
^ permalink raw reply
* Re: [PATCH 15/27] net: sxgbe: Use setup_timer
From: GIRISH K S @ 2014-12-29 4:50 UTC (permalink / raw)
To: Julia Lawall, ByungHo An
Cc: kernel-janitors@vger.kernel.org, Vipul Chandrakant,
netdev@vger.kernel.org, linux-kernel@vger.kernel.org
------- Original Message -------
Sender : Julia Lawall<Julia.Lawall@lip6.fr>
Date : Dec 26, 2014 20:05 (GMT+05:30)
Title : [PATCH 15/27] net: sxgbe: Use setup_timer
Convert a call to init_timer and accompanying intializations of
the timer's data and function fields to a call to setup_timer.
A simplified version of the semantic match that fixes this problem is as
follows: (http://coccinelle.lip6.fr/)
//
@@
expression t,f,d;
@@
-init_timer(&t);
+setup_timer(&t,f,d);
-t.function = f;
-t.data = d;
//
Signed-off-by: Julia Lawall
---
drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c | 10 ++++------
1 file changed, 4 insertions(+), 6 deletions(-)
diff --git a/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c b/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c
index 6984944..b6612d6 100644
--- a/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c
+++ b/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c
@@ -133,9 +133,8 @@ bool sxgbe_eee_init(struct sxgbe_priv_data * const priv)
return false;
priv->eee_active = 1;
- init_timer(&priv->eee_ctrl_timer);
- priv->eee_ctrl_timer.function = sxgbe_eee_ctrl_timer;
- priv->eee_ctrl_timer.data = (unsigned long)priv;
+ setup_timer(&priv->eee_ctrl_timer, sxgbe_eee_ctrl_timer,
+ (unsigned long)priv);
priv->eee_ctrl_timer.expires = SXGBE_LPI_TIMER(eee_timer);
add_timer(&priv->eee_ctrl_timer);
@@ -1009,10 +1008,9 @@ static void sxgbe_tx_init_coalesce(struct sxgbe_priv_data *priv)
struct sxgbe_tx_queue *p = priv->txq[queue_num];
p->tx_coal_frames = SXGBE_TX_FRAMES;
p->tx_coal_timer = SXGBE_COAL_TX_TIMER;
- init_timer(&p->txtimer);
+ setup_timer(&p->txtimer, sxgbe_tx_timer,
+ (unsigned long)&priv->txq[queue_num]);
p->txtimer.expires = SXGBE_COAL_TIMER(p->tx_coal_timer);
- p->txtimer.data = (unsigned long)&priv->txq[queue_num];
- p->txtimer.function = sxgbe_tx_timer;
add_timer(&p->txtimer);
}
}
Looks good to me.
Acked by: Girish K S <ks.giri@samsung.com>
^ permalink raw reply related
* [PATCH] net: flow: Allow actions and matches to be NULL in net_flow_put_flow()
From: Simon Horman @ 2014-12-29 2:20 UTC (permalink / raw)
To: John Fastabend, netdev; +Cc: Simon Horman
This makes the handing of the absence of actions or matches
symmetric with net_flow_get_flow().
Signed-off-by: Simon Horman <simon.horman@netronome.com>
---
net/core/flow_table.c | 40 ++++++++++++++++++++++------------------
1 file changed, 22 insertions(+), 18 deletions(-)
diff --git a/net/core/flow_table.c b/net/core/flow_table.c
index df2adf6..0992806 100644
--- a/net/core/flow_table.c
+++ b/net/core/flow_table.c
@@ -196,32 +196,36 @@ int net_flow_put_flow(struct sk_buff *skb, struct net_flow_flow *flow)
nla_put_u32(skb, NET_FLOW_ATTR_PRIORITY, flow->priority))
goto flows_put_failure;
- matches = nla_nest_start(skb, NET_FLOW_ATTR_MATCHES);
- if (!matches)
- goto flows_put_failure;
- for (j = 0; flow->matches[j].header; j++) {
- struct net_flow_field_ref *f = &flow->matches[j];
+ if (flow->matches) {
+ matches = nla_nest_start(skb, NET_FLOW_ATTR_MATCHES);
+ if (!matches)
+ goto flows_put_failure;
+ for (j = 0; flow->matches[j].header; j++) {
+ struct net_flow_field_ref *f = &flow->matches[j];
- if (!f->header)
- continue;
+ if (!f->header)
+ continue;
- nla_put(skb, NET_FLOW_FIELD_REF, sizeof(*f), f);
+ nla_put(skb, NET_FLOW_FIELD_REF, sizeof(*f), f);
+ }
+ nla_nest_end(skb, matches);
}
- nla_nest_end(skb, matches);
-
- actions = nla_nest_start(skb, NET_FLOW_ATTR_ACTIONS);
- if (!actions)
- goto flows_put_failure;
- for (i = 0; flow->actions[i].uid; i++) {
- err = net_flow_put_flow_action(skb, &flow->actions[i]);
- if (err) {
- nla_nest_cancel(skb, actions);
+ if (flow->actions) {
+ actions = nla_nest_start(skb, NET_FLOW_ATTR_ACTIONS);
+ if (!actions)
goto flows_put_failure;
+
+ for (i = 0; flow->actions[i].uid; i++) {
+ err = net_flow_put_flow_action(skb, &flow->actions[i]);
+ if (err) {
+ nla_nest_cancel(skb, actions);
+ goto flows_put_failure;
+ }
}
+ nla_nest_end(skb, actions);
}
- nla_nest_end(skb, actions);
nla_nest_end(skb, flows);
return 0;
--
2.1.3
^ permalink raw reply related
* [PATCH] net: flow: Guard against accessing non-existent attributes
From: Simon Horman @ 2014-12-29 2:17 UTC (permalink / raw)
To: John Fastabend, netdev; +Cc: Simon Horman
Signed-off-by: Simon Horman <simon.horman@netronome.com>
---
net/core/flow_table.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/net/core/flow_table.c b/net/core/flow_table.c
index 5937fb7..df2adf6 100644
--- a/net/core/flow_table.c
+++ b/net/core/flow_table.c
@@ -480,6 +480,10 @@ static int net_flow_get_action(struct net_flow_action *a, struct nlattr *attr)
if (err < 0)
return err;
+ if (!act[NET_FLOW_ACTION_ATTR_UID] ||
+ !act[NET_FLOW_ACTION_ATTR_SIGNATURE])
+ return -EINVAL;
+
a->uid = nla_get_u32(act[NET_FLOW_ACTION_ATTR_UID]);
nla_for_each_nested(args, act[NET_FLOW_ACTION_ATTR_SIGNATURE], rem)
@@ -513,6 +517,10 @@ static int net_flow_get_flow(struct net_flow_flow *flow, struct nlattr *attr)
if (err < 0)
return -EINVAL;
+ if (!f[NET_FLOW_ATTR_TABLE] || !f[NET_FLOW_ATTR_UID] ||
+ !f[NET_FLOW_ATTR_PRIORITY])
+ return -EINVAL;
+
flow->table_id = nla_get_u32(f[NET_FLOW_ATTR_TABLE]);
flow->uid = nla_get_u32(f[NET_FLOW_ATTR_UID]);
flow->priority = nla_get_u32(f[NET_FLOW_ATTR_PRIORITY]);
@@ -1209,6 +1217,9 @@ static int net_flow_table_cmd_get_flows(struct sk_buff *skb,
if (err)
goto out;
+ if (!tb[NET_FLOW_TABLE_FLOWS_TABLE])
+ goto out;
+
table = nla_get_u32(tb[NET_FLOW_TABLE_FLOWS_TABLE]);
if (tb[NET_FLOW_TABLE_FLOWS_MINPRIO])
--
2.1.3
^ permalink raw reply related
* [PATCH/RFC flow-net-next 10/10] net: flow: Add flow removed notification for eviction
From: Simon Horman @ 2014-12-29 2:15 UTC (permalink / raw)
To: John Fastabend, netdev; +Cc: Simon Horman
In-Reply-To: <1419819340-19000-1-git-send-email-simon.horman@netronome.com>
This adds a flag to flows to allow flow removed notifications
to be sent when eviction occurs.
Inspired by OpenFlow.
Signed-off-by: Simon Horman <simon.horman@netronome.com>
---
Compile tested only
---
include/uapi/linux/if_flow.h | 2 ++
1 file changed, 2 insertions(+)
diff --git a/include/uapi/linux/if_flow.h b/include/uapi/linux/if_flow.h
index 7264629..9db7b30 100644
--- a/include/uapi/linux/if_flow.h
+++ b/include/uapi/linux/if_flow.h
@@ -792,12 +792,14 @@ enum net_flow_rem_reason {
NET_FLOW_REM_FLOW_REASON_IDLE_TIMEOUT, /* Idle timeout */
NET_FLOW_REM_FLOW_REASON_HARD_TIMEOUT, /* Hard timeout */
NET_FLOW_REM_FLOW_REASON_DELETE, /* Deleted (by NET_FLOW_TABLE_CMD_DEL_FLOWS) */
+ NET_FLOW_REM_FLOW_REASON_EVICTION, /* Evicted by switch */
};
enum {
NET_FLOW_REM_F_IDLE_TIMEOUT = (1 << NET_FLOW_REM_FLOW_REASON_IDLE_TIMEOUT),
NET_FLOW_REM_F_HARD_TIMEOUT = (1 << NET_FLOW_REM_FLOW_REASON_HARD_TIMEOUT),
NET_FLOW_REM_F_DELETE = (1 << NET_FLOW_REM_FLOW_REASON_DELETE),
+ NET_FLOW_REM_F_EVICTION = (1 << NET_FLOW_REM_FLOW_REASON_EVICTION),
};
enum {
--
2.1.3
^ permalink raw reply related
* [PATCH/RFC flow-net-next 09/10] net: flow: Add eviction flags to table configuration
From: Simon Horman @ 2014-12-29 2:15 UTC (permalink / raw)
To: John Fastabend, netdev; +Cc: Simon Horman
In-Reply-To: <1419819340-19000-1-git-send-email-simon.horman@netronome.com>
The intention is to allow run-time configuration of if and how
a switch or switch-like device may evict flows from tables in
the case of resource contention.
Inspired by a feature of the same name in in OpenFlow.
Signed-off-by: Simon Horman <simon.horman@netronome.com>
---
include/uapi/linux/if_flow.h | 16 ++++++++++++++++
net/core/flow_table.c | 11 ++++++++---
2 files changed, 24 insertions(+), 3 deletions(-)
diff --git a/include/uapi/linux/if_flow.h b/include/uapi/linux/if_flow.h
index bd29145..7264629 100644
--- a/include/uapi/linux/if_flow.h
+++ b/include/uapi/linux/if_flow.h
@@ -186,6 +186,7 @@
* [NET_FLOW_TABLE_CONFIGS]
* [NET_FLOW_TABLE_CONFIG_TABLE]
* [NET_FLOW_TABLE_CONFIG_TABLE_ATTR_UID]
+ * [NET_FLOW_TABLE_CONFIG_TABLE_ATTR_EVICTION]
* ...
*
* Set Flow Notification <Request>,
@@ -742,9 +743,11 @@ enum {
* @brief flow table configuration
*
* @table unique identifier of table
+ * @eviction flags to control eviction. Bitmask of NET_FLOW_EVICTION_F_*
*/
struct net_flow_table_config {
int table;
+ __u32 eviction;
};
enum {
@@ -757,10 +760,23 @@ enum {
enum {
NET_FLOW_TABLE_CONFIG_TABLE_ATTR_UNSPEC,
NET_FLOW_TABLE_CONFIG_TABLE_ATTR_UID,
+ NET_FLOW_TABLE_CONFIG_TABLE_ATTR_EVICTION,
__NET_FLOW_TABLE_CONFIG_TABLE_ATTR_MAX,
};
#define NET_FLOW_TABLE_CONFIG_TABLE_ATTR_MAX (__NET_FLOW_TABLE_CONFIG_TABLE_ATTR_MAX - 1)
+
+enum {
+ /* Eviction enabled.
+ * Must be set for any eviction to occur */
+ NET_FLOW_EVICTION_F_ENABLE = (0 << 1),
+
+ /* Evict entries based on their importance */
+ NET_FLOW_EVICTION_F_IMPORTANCE = (1 << 1),
+ /* Evict entries based on how close they are to timing out */
+ NET_FLOW_EVICTION_F_TIMEOUT = (2 << 1),
+};
+
enum {
NET_FLOW_REM_FLOW_UNSPEC,
NET_FLOW_REM_FLOW_TABLE,
diff --git a/net/core/flow_table.c b/net/core/flow_table.c
index 6c44311..3030246 100644
--- a/net/core/flow_table.c
+++ b/net/core/flow_table.c
@@ -1595,13 +1595,14 @@ static int net_flow_table_cmd_get_table_config(struct sk_buff *skb,
}
if (nla_put_u32(msg, NET_FLOW_TABLE_CONFIG_TABLE_ATTR_UID,
- table)) {
+ table) ||
+ nla_put_u32(msg,
+ NET_FLOW_TABLE_CONFIG_TABLE_ATTR_EVICTION,
+ tc->eviction)) {
err = -ENOBUFS;
goto err;
}
- /* Write other attributes of tc: Currently none are defined. */
-
nla_nest_end(msg, config);
}
@@ -1669,6 +1670,10 @@ static int net_flow_table_cmd_set_table_config(struct sk_buff *skb,
new_tc = *tc;
+ if (!tb[NET_FLOW_TABLE_CONFIG_TABLE_ATTR_EVICTION]) {
+ new_tc.eviction = nla_get_u32(tb[NET_FLOW_TABLE_CONFIG_TABLE_ATTR_EVICTION]);
+ }
+
err = dev->netdev_ops->ndo_flow_table_set_table_config(dev, &new_tc);
if (err)
goto out;
--
2.1.3
^ permalink raw reply related
* [PATCH/RFC flow-net-next 08/10] net: flow: Add get and set table config commands
From: Simon Horman @ 2014-12-29 2:15 UTC (permalink / raw)
To: John Fastabend, netdev; +Cc: Simon Horman
In-Reply-To: <1419819340-19000-1-git-send-email-simon.horman@netronome.com>
The intention of this is to allow querying and setting of
configuration attributes of tables which may be useful to manipulate
at runtime. A subsequent patch which proposes per-table eviction settings
will make use of this.
Signed-off-by: Simon Horman <simon.horman@netronome.com>
---
Compile tested only
---
include/linux/netdevice.h | 4 +
include/uapi/linux/if_flow.h | 39 ++++++++++
net/core/flow_table.c | 176 +++++++++++++++++++++++++++++++++++++++++++
3 files changed, 219 insertions(+)
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 1174ab7..6073004 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -1171,6 +1171,10 @@ struct net_device_ops {
int (*ndo_flow_get_notification)(struct net_device *dev,
u32 type, u32 **pids,
size_t *n_pids);
+ struct net_flow_table_config *(*ndo_flow_table_get_table_config)(struct net_device *dev,
+ int table);
+ int (*ndo_flow_table_set_table_config)(struct net_device *dev,
+ struct net_flow_table_config *tc);
};
/**
diff --git a/include/uapi/linux/if_flow.h b/include/uapi/linux/if_flow.h
index 91fcfb4..bd29145 100644
--- a/include/uapi/linux/if_flow.h
+++ b/include/uapi/linux/if_flow.h
@@ -177,6 +177,17 @@
* [..]
* [...]
*
+ * Get Table Settings <REQUEST> and <REPLY>, and
+ * Set Table Settings <REQUEST> description
+ *
+ * This is intended for configuring run-time attributes of a table.
+ * No such attributes are defined yet.
+ *
+ * [NET_FLOW_TABLE_CONFIGS]
+ * [NET_FLOW_TABLE_CONFIG_TABLE]
+ * [NET_FLOW_TABLE_CONFIG_TABLE_ATTR_UID]
+ * ...
+ *
* Set Flow Notification <Request>,
* Get Flow Notification <Request> and
* Get Flow Notification <Reply> description.
@@ -726,6 +737,30 @@ enum {
};
#define NET_FLOW_NOTIFICATION_ATTR_MAX (__NET_FLOW_NOTIFICATION_ATTR_MAX - 1)
+/**
+ * @struct net_flow_table
+ * @brief flow table configuration
+ *
+ * @table unique identifier of table
+ */
+struct net_flow_table_config {
+ int table;
+};
+
+enum {
+ NET_FLOW_TABLE_CONFIG_UNSPEC,
+ NET_FLOW_TABLE_CONFIG_TABLE,
+ __NET_FLOW_TABLE_CONFIG_MAX,
+};
+#define NET_FLOW_TABLE_CONFIG_MAX (__NET_FLOW_TABLE_CONFIG_MAX - 1)
+
+enum {
+ NET_FLOW_TABLE_CONFIG_TABLE_ATTR_UNSPEC,
+ NET_FLOW_TABLE_CONFIG_TABLE_ATTR_UID,
+ __NET_FLOW_TABLE_CONFIG_TABLE_ATTR_MAX,
+};
+#define NET_FLOW_TABLE_CONFIG_TABLE_ATTR_MAX (__NET_FLOW_TABLE_CONFIG_TABLE_ATTR_MAX - 1)
+
enum {
NET_FLOW_REM_FLOW_UNSPEC,
NET_FLOW_REM_FLOW_TABLE,
@@ -763,6 +798,7 @@ enum {
NET_FLOW_FLOWS_ERROR,
NET_FLOW_NOTIFICATION,
NET_FLOW_REM_FLOW,
+ NET_FLOW_TABLE_CONFIGS,
__NET_FLOW_MAX,
NET_FLOW_MAX = (__NET_FLOW_MAX - 1),
@@ -784,6 +820,9 @@ enum {
NET_FLOW_TABLE_CMD_CREATE_TABLE,
NET_FLOW_TABLE_CMD_DESTROY_TABLE,
+ NET_FLOW_TABLE_CMD_SET_TABLE_CONFIG,
+ NET_FLOW_TABLE_CMD_GET_TABLE_CONFIG,
+
NET_FLOW_TABLE_CMD_SET_NOTIFICATION,
NET_FLOW_TABLE_CMD_GET_NOTIFICATION,
diff --git a/net/core/flow_table.c b/net/core/flow_table.c
index 0bf399c..6c44311 100644
--- a/net/core/flow_table.c
+++ b/net/core/flow_table.c
@@ -1514,6 +1514,172 @@ out:
}
static const
+
+struct nla_policy net_flow_table_config_policy[NET_FLOW_TABLE_CONFIG_MAX + 1] = {
+ [NET_FLOW_TABLE_CONFIG_TABLE] = { .type = NLA_U32,},
+};
+
+static int net_flow_table_cmd_get_table_config(struct sk_buff *skb,
+ struct genl_info *info)
+{
+ int rem, err;
+ struct genlmsghdr *hdr;
+ struct net_device *dev;
+ struct nlattr *tattr;
+ struct sk_buff *msg = NULL;
+
+ dev = net_flow_table_get_dev(info);
+ if (!dev)
+ return -EINVAL;
+
+ if (!dev->netdev_ops->ndo_flow_table_get_table_config) {
+ err = -EOPNOTSUPP;
+ goto err;
+ }
+
+ if (!info->attrs[NET_FLOW_TABLE_CONFIGS]) {
+ err = -EINVAL;
+ goto err;
+ }
+
+ msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
+ if (!msg) {
+ err = -ENOBUFS;
+ goto err;
+ }
+
+ hdr = genlmsg_put(msg, info->snd_portid, info->snd_seq,
+ &net_flow_nl_family, 0,
+ NET_FLOW_TABLE_CMD_GET_TABLE_CONFIG);
+ if (!hdr) {
+ err = -ENOBUFS;
+ goto err;
+ }
+
+ if (nla_put_u32(msg, NET_FLOW_IDENTIFIER_TYPE, NET_FLOW_IDENTIFIER_IFINDEX) ||
+ nla_put_u32(msg, NET_FLOW_IDENTIFIER, dev->ifindex)) {
+ err = -ENOBUFS;
+ goto err;
+ }
+
+ nla_for_each_nested(tattr, info->attrs[NET_FLOW_TABLE_CONFIGS], rem) {
+ const struct net_flow_table_config *tc;
+ int table;
+ struct nlattr *config;
+ struct nlattr *tb[NET_FLOW_TABLE_CONFIG_TABLE_ATTR_MAX+1];
+
+ if (nla_type(tattr) != NET_FLOW_TABLE_CONFIG_TABLE)
+ continue;
+
+ err = nla_parse_nested(tb, NET_FLOW_TABLE_FLOWS_MAX,
+ tattr, net_flow_table_flows_policy);
+ if (err)
+ goto err;
+
+ if (!tb[NET_FLOW_TABLE_CONFIG_TABLE_ATTR_UID]) {
+ err = -EINVAL;
+ goto err;
+ }
+ table = nla_get_u32(tb[NET_FLOW_TABLE_CONFIG_TABLE_ATTR_UID]);
+
+ tc = dev->netdev_ops->ndo_flow_table_get_table_config(dev, table);
+ if (IS_ERR(tc)) {
+ err = PTR_ERR(tc);
+ goto err;
+ }
+
+ config = nla_nest_start(msg, NET_FLOW_FLOWS);
+ if (!config) {
+ err = -EMSGSIZE;
+ goto err;
+ }
+
+ if (nla_put_u32(msg, NET_FLOW_TABLE_CONFIG_TABLE_ATTR_UID,
+ table)) {
+ err = -ENOBUFS;
+ goto err;
+ }
+
+ /* Write other attributes of tc: Currently none are defined. */
+
+ nla_nest_end(msg, config);
+ }
+
+ err = genlmsg_end(msg, hdr);
+ if (err < 0)
+ goto err;
+
+ dev_put(dev);
+
+ return genlmsg_reply(msg, info);
+
+err:
+ dev_put(dev);
+ nlmsg_free(msg);
+ return err;
+}
+
+static int net_flow_table_cmd_set_table_config(struct sk_buff *skb,
+ struct genl_info *info)
+{
+ int rem, err;
+ struct net_device *dev;
+ struct nlattr *tattr;
+
+ dev = net_flow_table_get_dev(info);
+ if (!dev)
+ return -EINVAL;
+
+ if (!dev->netdev_ops->ndo_flow_table_get_table_config ||
+ !dev->netdev_ops->ndo_flow_table_set_table_config) {
+ err = -EOPNOTSUPP;
+ goto out;
+ }
+
+ if (!info->attrs[NET_FLOW_TABLE_CONFIGS]) {
+ err = -EINVAL;
+ goto out;
+ }
+
+ nla_for_each_nested(tattr, info->attrs[NET_FLOW_TABLE_CONFIGS], rem) {
+ int table;
+ struct net_flow_table_config *tc;
+ struct net_flow_table_config new_tc;
+ struct nlattr *tb[NET_FLOW_TABLE_CONFIG_TABLE_ATTR_MAX+1];
+
+ if (nla_type(tattr) != NET_FLOW_TABLE_CONFIG_TABLE)
+ continue;
+
+ err = nla_parse_nested(tb, NET_FLOW_TABLE_FLOWS_MAX,
+ tattr, net_flow_table_flows_policy);
+ if (err)
+ goto out;
+
+ if (!tb[NET_FLOW_TABLE_CONFIG_TABLE_ATTR_UID]) {
+ err = -EINVAL;
+ goto out;
+ }
+ table = nla_get_u32(tb[NET_FLOW_TABLE_CONFIG_TABLE_ATTR_UID]);
+
+ tc = dev->netdev_ops->ndo_flow_table_get_table_config(dev, table);
+ if (IS_ERR(tc)) {
+ err = PTR_ERR(tc);
+ goto out;
+ }
+
+ new_tc = *tc;
+
+ err = dev->netdev_ops->ndo_flow_table_set_table_config(dev, &new_tc);
+ if (err)
+ goto out;
+ }
+
+out:
+ dev_put(dev);
+ return err;
+}
+
+static const
struct nla_policy net_flow_notification_policy[NET_FLOW_NOTIFICATION_ATTR_MAX + 1] = {
[NET_FLOW_NOTIFICATION_ATTR_TYPE] = { .type = NLA_U32,},
[NET_FLOW_NOTIFICATION_ATTR_PIDS] = { .type = NLA_U32,},
@@ -1789,6 +1955,16 @@ static const struct genl_ops net_flow_table_nl_ops[] = {
.flags = GENL_ADMIN_PERM,
},
{
+ .cmd = NET_FLOW_TABLE_CMD_SET_TABLE_CONFIG,
+ .doit = net_flow_table_cmd_set_table_config,
+ .flags = GENL_ADMIN_PERM,
+ },
+ {
+ .cmd = NET_FLOW_TABLE_CMD_GET_TABLE_CONFIG,
+ .doit = net_flow_table_cmd_get_table_config,
+ .flags = GENL_ADMIN_PERM,
+ },
+ {
.cmd = NET_FLOW_TABLE_CMD_SET_NOTIFICATION,
.doit = net_flow_table_cmd_set_notification,
.flags = GENL_ADMIN_PERM,
--
2.1.3
^ permalink raw reply related
* [PATCH/RFC flow-net-next 07/10] net: flow: Add importance to flows
From: Simon Horman @ 2014-12-29 2:15 UTC (permalink / raw)
To: John Fastabend, netdev; +Cc: Simon Horman
In-Reply-To: <1419819340-19000-1-git-send-email-simon.horman@netronome.com>
This is in preparation for adding support for eviction of flows
from tables when resource contention occurs. The importance of
a flow may be used to influence the eviction algorithm.
Inspired by the eviction feature of OpenFlow.
Signed-off-by: Simon Horman <simon.horman@netronome.com>
---
Compile tested only
---
include/uapi/linux/if_flow.h | 14 ++++++++++++++
net/core/flow_table.c | 12 ++++++++++++
2 files changed, 26 insertions(+)
diff --git a/include/uapi/linux/if_flow.h b/include/uapi/linux/if_flow.h
index d1643f3..91fcfb4 100644
--- a/include/uapi/linux/if_flow.h
+++ b/include/uapi/linux/if_flow.h
@@ -126,6 +126,7 @@
* [NET_FLOW_ATTR_TABLE]
* [NET_FLOW_ATTR_UID]
* [NET_FLOW_ATTR_PRIORITY]
+ * [NET_FLOW_ATTR_IMPORTANCE]
* [NET_FLOW_ATTR_IDLE_TIMEOUT]
* [NET_FLOW_ATTR_HARD_TIMEOUT]
* [NET_FLOW_ATTR_BYTE_COUNT]
@@ -155,6 +156,7 @@
* [NET_FLOW_ATTR_TABLE]
* [NET_FLOW_ATTR_UID]
* [NET_FLOW_ATTR_PRIORITY]
+ * [NET_FLOW_ATTR_IMPORTANCE]
* [NET_FLOW_ATTR_IDLE_TIMEOUT]
* [NET_FLOW_ATTR_HARD_TIMEOUT]
* [NET_FLOW_ATTR_BYTE_COUNT]
@@ -425,6 +427,11 @@ enum {
*
* @uid unique identifier for flow
* @priority priority to execute flow match/action in table
+ * @importance importance of flow used to influence flow eviction algorithm
+ * If eviction is enabled and uses importance then
+ * flows with lower importance values must be evicted
+ * before those with higher importance values.
+ * The values 0xffff ff00 - 0xffff ffff are reserved for future use.
* @match null terminated set of match uids match criteria
* @action null terminated set of action uids to apply to match
* @idle_timeout idle timeout of flow in seconds. Zero for no timeout.
@@ -442,6 +449,7 @@ struct net_flow_flow {
int table_id;
int uid;
int priority;
+ __u32 importance;
__u32 idle_timeout;
__u32 hard_timeout;
__u32 flow_rem;
@@ -484,6 +492,7 @@ enum {
NET_FLOW_ATTR_TABLE,
NET_FLOW_ATTR_UID,
NET_FLOW_ATTR_PRIORITY,
+ NET_FLOW_ATTR_IMPORTANCE,
NET_FLOW_ATTR_MATCHES,
NET_FLOW_ATTR_ACTIONS,
NET_FLOW_ATTR_IDLE_TIMEOUT,
@@ -496,6 +505,8 @@ enum {
};
#define NET_FLOW_ATTR_MAX (__NET_FLOW_ATTR_MAX - 1)
+#define NET_FLOW_ATTR_IMPORTANCE_MAX (0xfffffff00 - 1)
+
/**
* @struct net_flow_table
* @brief define flow table with supported match/actions
@@ -557,6 +568,9 @@ enum {
/* Table supports last used counter for flows */
NET_FLOW_TABLE_F_PACKET_LAST_USED = (1 << 4),
+
+ /* Table supports importance of flows */
+ NET_FLOW_TABLE_F_IMPORTANCE = (1 << 5),
};
#if 0
diff --git a/net/core/flow_table.c b/net/core/flow_table.c
index 10b113f..0bf399c 100644
--- a/net/core/flow_table.c
+++ b/net/core/flow_table.c
@@ -53,6 +53,7 @@ struct nla_policy net_flow_flow_policy[NET_FLOW_ATTR_MAX + 1] = {
[NET_FLOW_ATTR_TABLE] = { .type = NLA_U32 },
[NET_FLOW_ATTR_UID] = { .type = NLA_U32 },
[NET_FLOW_ATTR_PRIORITY] = { .type = NLA_U32 },
+ [NET_FLOW_ATTR_IMPORTANCE] = { .type = NLA_U32 },
[NET_FLOW_ATTR_IDLE_TIMEOUT] = { .type = NLA_U32 },
[NET_FLOW_ATTR_HARD_TIMEOUT] = { .type = NLA_U32 },
[NET_FLOW_ATTR_BYTE_COUNT] = { .type = NLA_U64 },
@@ -206,6 +207,11 @@ int net_flow_put_flow(struct sk_buff *skb, struct net_flow_flow *flow)
nla_put_u32(skb, NET_FLOW_ATTR_PRIORITY, flow->priority))
goto flows_put_failure;
+ if (flow->importance &&
+ (nla_put_u32(skb, NET_FLOW_ATTR_IMPORTANCE, flow->importance) ||
+ flow->importance > NET_FLOW_ATTR_IMPORTANCE_MAX))
+ goto flows_put_failure;
+
if (flow->idle_timeout &&
nla_put_u32(skb, NET_FLOW_ATTR_IDLE_TIMEOUT, flow->idle_timeout))
goto flows_put_failure;
@@ -556,6 +562,9 @@ static int net_flow_get_flow(struct net_flow_flow *flow, struct nlattr *attr)
flow->uid = nla_get_u32(f[NET_FLOW_ATTR_UID]);
flow->priority = nla_get_u32(f[NET_FLOW_ATTR_PRIORITY]);
+ if (f[NET_FLOW_ATTR_IMPORTANCE])
+ flow->importance = nla_get_u32(f[NET_FLOW_ATTR_IMPORTANCE]);
+
if (f[NET_FLOW_ATTR_IDLE_TIMEOUT])
flow->idle_timeout = nla_get_u32(f[NET_FLOW_ATTR_IDLE_TIMEOUT]);
if (f[NET_FLOW_ATTR_HARD_TIMEOUT])
@@ -1423,6 +1432,9 @@ static int net_flow_table_cmd_flows(struct sk_buff *recv_skb,
if (err)
goto out;
+ if (this.importance)
+ used_features |= NET_FLOW_TABLE_F_IMPORTANCE;
+
if (this.idle_timeout)
used_features |= NET_FLOW_TABLE_F_IDLE_TIMEOUT;
if (this.hard_timeout)
--
2.1.3
^ 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