Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net
Trivial conflict in CAN on file rename. Conflicts: drivers/net/can/m_can/tcan4x5x-core.c Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
commit
833d22f2f9
@ -19,7 +19,9 @@ description: |
|
|||||||
properties:
|
properties:
|
||||||
compatible:
|
compatible:
|
||||||
enum:
|
enum:
|
||||||
- nxp,pf8x00
|
- nxp,pf8100
|
||||||
|
- nxp,pf8121a
|
||||||
|
- nxp,pf8200
|
||||||
|
|
||||||
reg:
|
reg:
|
||||||
maxItems: 1
|
maxItems: 1
|
||||||
@ -118,7 +120,7 @@ examples:
|
|||||||
#size-cells = <0>;
|
#size-cells = <0>;
|
||||||
|
|
||||||
pmic@8 {
|
pmic@8 {
|
||||||
compatible = "nxp,pf8x00";
|
compatible = "nxp,pf8100";
|
||||||
reg = <0x08>;
|
reg = <0x08>;
|
||||||
|
|
||||||
regulators {
|
regulators {
|
||||||
|
@ -44,6 +44,7 @@ First Level Nodes - PMIC
|
|||||||
Definition: Must be one of below:
|
Definition: Must be one of below:
|
||||||
"qcom,pm8005-rpmh-regulators"
|
"qcom,pm8005-rpmh-regulators"
|
||||||
"qcom,pm8009-rpmh-regulators"
|
"qcom,pm8009-rpmh-regulators"
|
||||||
|
"qcom,pm8009-1-rpmh-regulators"
|
||||||
"qcom,pm8150-rpmh-regulators"
|
"qcom,pm8150-rpmh-regulators"
|
||||||
"qcom,pm8150l-rpmh-regulators"
|
"qcom,pm8150l-rpmh-regulators"
|
||||||
"qcom,pm8350-rpmh-regulators"
|
"qcom,pm8350-rpmh-regulators"
|
||||||
|
@ -164,46 +164,56 @@ Devlink health reporters
|
|||||||
|
|
||||||
NPA Reporters
|
NPA Reporters
|
||||||
-------------
|
-------------
|
||||||
The NPA reporters are responsible for reporting and recovering the following group of errors
|
The NPA reporters are responsible for reporting and recovering the following group of errors:
|
||||||
|
|
||||||
1. GENERAL events
|
1. GENERAL events
|
||||||
|
|
||||||
- Error due to operation of unmapped PF.
|
- Error due to operation of unmapped PF.
|
||||||
- Error due to disabled alloc/free for other HW blocks (NIX, SSO, TIM, DPI and AURA).
|
- Error due to disabled alloc/free for other HW blocks (NIX, SSO, TIM, DPI and AURA).
|
||||||
|
|
||||||
2. ERROR events
|
2. ERROR events
|
||||||
|
|
||||||
- Fault due to NPA_AQ_INST_S read or NPA_AQ_RES_S write.
|
- Fault due to NPA_AQ_INST_S read or NPA_AQ_RES_S write.
|
||||||
- AQ Doorbell Error.
|
- AQ Doorbell Error.
|
||||||
|
|
||||||
3. RAS events
|
3. RAS events
|
||||||
|
|
||||||
- RAS Error Reporting for NPA_AQ_INST_S/NPA_AQ_RES_S.
|
- RAS Error Reporting for NPA_AQ_INST_S/NPA_AQ_RES_S.
|
||||||
|
|
||||||
4. RVU events
|
4. RVU events
|
||||||
|
|
||||||
- Error due to unmapped slot.
|
- Error due to unmapped slot.
|
||||||
|
|
||||||
Sample Output
|
Sample Output::
|
||||||
-------------
|
|
||||||
~# devlink health
|
~# devlink health
|
||||||
pci/0002:01:00.0:
|
pci/0002:01:00.0:
|
||||||
reporter hw_npa_intr
|
reporter hw_npa_intr
|
||||||
state healthy error 2872 recover 2872 last_dump_date 2020-12-10 last_dump_time 09:39:09 grace_period 0 auto_recover true auto_dump true
|
state healthy error 2872 recover 2872 last_dump_date 2020-12-10 last_dump_time 09:39:09 grace_period 0 auto_recover true auto_dump true
|
||||||
reporter hw_npa_gen
|
reporter hw_npa_gen
|
||||||
state healthy error 2872 recover 2872 last_dump_date 2020-12-11 last_dump_time 04:43:04 grace_period 0 auto_recover true auto_dump true
|
state healthy error 2872 recover 2872 last_dump_date 2020-12-11 last_dump_time 04:43:04 grace_period 0 auto_recover true auto_dump true
|
||||||
reporter hw_npa_err
|
reporter hw_npa_err
|
||||||
state healthy error 2871 recover 2871 last_dump_date 2020-12-10 last_dump_time 09:39:17 grace_period 0 auto_recover true auto_dump true
|
state healthy error 2871 recover 2871 last_dump_date 2020-12-10 last_dump_time 09:39:17 grace_period 0 auto_recover true auto_dump true
|
||||||
reporter hw_npa_ras
|
reporter hw_npa_ras
|
||||||
state healthy error 0 recover 0 last_dump_date 2020-12-10 last_dump_time 09:32:40 grace_period 0 auto_recover true auto_dump true
|
state healthy error 0 recover 0 last_dump_date 2020-12-10 last_dump_time 09:32:40 grace_period 0 auto_recover true auto_dump true
|
||||||
|
|
||||||
Each reporter dumps the
|
Each reporter dumps the
|
||||||
|
|
||||||
- Error Type
|
- Error Type
|
||||||
- Error Register value
|
- Error Register value
|
||||||
- Reason in words
|
- Reason in words
|
||||||
|
|
||||||
For eg:
|
For example::
|
||||||
~# devlink health dump show pci/0002:01:00.0 reporter hw_npa_gen
|
|
||||||
NPA_AF_GENERAL:
|
~# devlink health dump show pci/0002:01:00.0 reporter hw_npa_gen
|
||||||
NPA General Interrupt Reg : 1
|
NPA_AF_GENERAL:
|
||||||
NIX0: free disabled RX
|
NPA General Interrupt Reg : 1
|
||||||
~# devlink health dump show pci/0002:01:00.0 reporter hw_npa_intr
|
NIX0: free disabled RX
|
||||||
NPA_AF_RVU:
|
~# devlink health dump show pci/0002:01:00.0 reporter hw_npa_intr
|
||||||
NPA RVU Interrupt Reg : 1
|
NPA_AF_RVU:
|
||||||
Unmap Slot Error
|
NPA RVU Interrupt Reg : 1
|
||||||
~# devlink health dump show pci/0002:01:00.0 reporter hw_npa_err
|
Unmap Slot Error
|
||||||
NPA_AF_ERR:
|
~# devlink health dump show pci/0002:01:00.0 reporter hw_npa_err
|
||||||
NPA Error Interrupt Reg : 4096
|
NPA_AF_ERR:
|
||||||
AQ Doorbell Error
|
NPA Error Interrupt Reg : 4096
|
||||||
|
AQ Doorbell Error
|
||||||
|
@ -64,8 +64,8 @@ ndo_do_ioctl:
|
|||||||
Context: process
|
Context: process
|
||||||
|
|
||||||
ndo_get_stats:
|
ndo_get_stats:
|
||||||
Synchronization: dev_base_lock rwlock.
|
Synchronization: rtnl_lock() semaphore, dev_base_lock rwlock, or RCU.
|
||||||
Context: nominally process, but don't sleep inside an rwlock
|
Context: atomic (can't sleep under rwlock or RCU)
|
||||||
|
|
||||||
ndo_start_xmit:
|
ndo_start_xmit:
|
||||||
Synchronization: __netif_tx_lock spinlock.
|
Synchronization: __netif_tx_lock spinlock.
|
||||||
|
@ -10848,7 +10848,7 @@ F: drivers/media/radio/radio-maxiradio*
|
|||||||
|
|
||||||
MCAN MMIO DEVICE DRIVER
|
MCAN MMIO DEVICE DRIVER
|
||||||
M: Dan Murphy <dmurphy@ti.com>
|
M: Dan Murphy <dmurphy@ti.com>
|
||||||
M: Sriram Dash <sriram.dash@samsung.com>
|
M: Pankaj Sharma <pankj.sharma@samsung.com>
|
||||||
L: linux-can@vger.kernel.org
|
L: linux-can@vger.kernel.org
|
||||||
S: Maintained
|
S: Maintained
|
||||||
F: Documentation/devicetree/bindings/net/can/bosch,m_can.yaml
|
F: Documentation/devicetree/bindings/net/can/bosch,m_can.yaml
|
||||||
|
@ -60,6 +60,7 @@ static void chacha_doneon(u32 *state, u8 *dst, const u8 *src,
|
|||||||
chacha_block_xor_neon(state, d, s, nrounds);
|
chacha_block_xor_neon(state, d, s, nrounds);
|
||||||
if (d != dst)
|
if (d != dst)
|
||||||
memcpy(dst, buf, bytes);
|
memcpy(dst, buf, bytes);
|
||||||
|
state[12]++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,7 +39,8 @@ static int ecdh_set_secret(struct crypto_kpp *tfm, const void *buf,
|
|||||||
struct ecdh params;
|
struct ecdh params;
|
||||||
unsigned int ndigits;
|
unsigned int ndigits;
|
||||||
|
|
||||||
if (crypto_ecdh_decode_key(buf, len, ¶ms) < 0)
|
if (crypto_ecdh_decode_key(buf, len, ¶ms) < 0 ||
|
||||||
|
params.key_size > sizeof(ctx->private_key))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
ndigits = ecdh_supported_curve(params.curve_id);
|
ndigits = ecdh_supported_curve(params.curve_id);
|
||||||
|
@ -582,8 +582,12 @@ void regmap_debugfs_init(struct regmap *map)
|
|||||||
devname = dev_name(map->dev);
|
devname = dev_name(map->dev);
|
||||||
|
|
||||||
if (name) {
|
if (name) {
|
||||||
map->debugfs_name = kasprintf(GFP_KERNEL, "%s-%s",
|
if (!map->debugfs_name) {
|
||||||
|
map->debugfs_name = kasprintf(GFP_KERNEL, "%s-%s",
|
||||||
devname, name);
|
devname, name);
|
||||||
|
if (!map->debugfs_name)
|
||||||
|
return;
|
||||||
|
}
|
||||||
name = map->debugfs_name;
|
name = map->debugfs_name;
|
||||||
} else {
|
} else {
|
||||||
name = devname;
|
name = devname;
|
||||||
@ -591,9 +595,10 @@ void regmap_debugfs_init(struct regmap *map)
|
|||||||
|
|
||||||
if (!strcmp(name, "dummy")) {
|
if (!strcmp(name, "dummy")) {
|
||||||
kfree(map->debugfs_name);
|
kfree(map->debugfs_name);
|
||||||
|
|
||||||
map->debugfs_name = kasprintf(GFP_KERNEL, "dummy%d",
|
map->debugfs_name = kasprintf(GFP_KERNEL, "dummy%d",
|
||||||
dummy_index);
|
dummy_index);
|
||||||
|
if (!map->debugfs_name)
|
||||||
|
return;
|
||||||
name = map->debugfs_name;
|
name = map->debugfs_name;
|
||||||
dummy_index++;
|
dummy_index++;
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,7 @@ if MISDN != n
|
|||||||
config MISDN_DSP
|
config MISDN_DSP
|
||||||
tristate "Digital Audio Processing of transparent data"
|
tristate "Digital Audio Processing of transparent data"
|
||||||
depends on MISDN
|
depends on MISDN
|
||||||
|
select BITREVERSE
|
||||||
help
|
help
|
||||||
Enable support for digital audio processing capability.
|
Enable support for digital audio processing capability.
|
||||||
|
|
||||||
|
@ -645,11 +645,20 @@ static int bareudp_link_config(struct net_device *dev,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void bareudp_dellink(struct net_device *dev, struct list_head *head)
|
||||||
|
{
|
||||||
|
struct bareudp_dev *bareudp = netdev_priv(dev);
|
||||||
|
|
||||||
|
list_del(&bareudp->next);
|
||||||
|
unregister_netdevice_queue(dev, head);
|
||||||
|
}
|
||||||
|
|
||||||
static int bareudp_newlink(struct net *net, struct net_device *dev,
|
static int bareudp_newlink(struct net *net, struct net_device *dev,
|
||||||
struct nlattr *tb[], struct nlattr *data[],
|
struct nlattr *tb[], struct nlattr *data[],
|
||||||
struct netlink_ext_ack *extack)
|
struct netlink_ext_ack *extack)
|
||||||
{
|
{
|
||||||
struct bareudp_conf conf;
|
struct bareudp_conf conf;
|
||||||
|
LIST_HEAD(list_kill);
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
err = bareudp2info(data, &conf, extack);
|
err = bareudp2info(data, &conf, extack);
|
||||||
@ -662,17 +671,14 @@ static int bareudp_newlink(struct net *net, struct net_device *dev,
|
|||||||
|
|
||||||
err = bareudp_link_config(dev, tb);
|
err = bareudp_link_config(dev, tb);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
goto err_unconfig;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
|
|
||||||
static void bareudp_dellink(struct net_device *dev, struct list_head *head)
|
err_unconfig:
|
||||||
{
|
bareudp_dellink(dev, &list_kill);
|
||||||
struct bareudp_dev *bareudp = netdev_priv(dev);
|
unregister_netdevice_many(&list_kill);
|
||||||
|
return err;
|
||||||
list_del(&bareudp->next);
|
|
||||||
unregister_netdevice_queue(dev, head);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t bareudp_get_size(const struct net_device *dev)
|
static size_t bareudp_get_size(const struct net_device *dev)
|
||||||
|
@ -123,6 +123,7 @@ config CAN_JANZ_ICAN3
|
|||||||
config CAN_KVASER_PCIEFD
|
config CAN_KVASER_PCIEFD
|
||||||
depends on PCI
|
depends on PCI
|
||||||
tristate "Kvaser PCIe FD cards"
|
tristate "Kvaser PCIe FD cards"
|
||||||
|
select CRC32
|
||||||
help
|
help
|
||||||
This is a driver for the Kvaser PCI Express CAN FD family.
|
This is a driver for the Kvaser PCI Express CAN FD family.
|
||||||
|
|
||||||
|
@ -1852,8 +1852,6 @@ EXPORT_SYMBOL_GPL(m_can_class_register);
|
|||||||
void m_can_class_unregister(struct m_can_classdev *cdev)
|
void m_can_class_unregister(struct m_can_classdev *cdev)
|
||||||
{
|
{
|
||||||
unregister_candev(cdev->net);
|
unregister_candev(cdev->net);
|
||||||
|
|
||||||
m_can_clk_stop(cdev);
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(m_can_class_unregister);
|
EXPORT_SYMBOL_GPL(m_can_class_unregister);
|
||||||
|
|
||||||
|
@ -108,30 +108,6 @@ static inline struct tcan4x5x_priv *cdev_to_priv(struct m_can_classdev *cdev)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct can_bittiming_const tcan4x5x_bittiming_const = {
|
|
||||||
.name = KBUILD_MODNAME,
|
|
||||||
.tseg1_min = 2,
|
|
||||||
.tseg1_max = 31,
|
|
||||||
.tseg2_min = 2,
|
|
||||||
.tseg2_max = 16,
|
|
||||||
.sjw_max = 16,
|
|
||||||
.brp_min = 1,
|
|
||||||
.brp_max = 32,
|
|
||||||
.brp_inc = 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct can_bittiming_const tcan4x5x_data_bittiming_const = {
|
|
||||||
.name = KBUILD_MODNAME,
|
|
||||||
.tseg1_min = 1,
|
|
||||||
.tseg1_max = 32,
|
|
||||||
.tseg2_min = 1,
|
|
||||||
.tseg2_max = 16,
|
|
||||||
.sjw_max = 16,
|
|
||||||
.brp_min = 1,
|
|
||||||
.brp_max = 32,
|
|
||||||
.brp_inc = 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
static void tcan4x5x_check_wake(struct tcan4x5x_priv *priv)
|
static void tcan4x5x_check_wake(struct tcan4x5x_priv *priv)
|
||||||
{
|
{
|
||||||
int wake_state = 0;
|
int wake_state = 0;
|
||||||
@ -373,8 +349,6 @@ static int tcan4x5x_can_probe(struct spi_device *spi)
|
|||||||
mcan_class->dev = &spi->dev;
|
mcan_class->dev = &spi->dev;
|
||||||
mcan_class->ops = &tcan4x5x_ops;
|
mcan_class->ops = &tcan4x5x_ops;
|
||||||
mcan_class->is_peripheral = true;
|
mcan_class->is_peripheral = true;
|
||||||
mcan_class->bit_timing = &tcan4x5x_bittiming_const;
|
|
||||||
mcan_class->data_timing = &tcan4x5x_data_bittiming_const;
|
|
||||||
mcan_class->net->irq = spi->irq;
|
mcan_class->net->irq = spi->irq;
|
||||||
|
|
||||||
spi_set_drvdata(spi, priv);
|
spi_set_drvdata(spi, priv);
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
# SPDX-License-Identifier: GPL-2.0
|
# SPDX-License-Identifier: GPL-2.0
|
||||||
config CAN_RCAR
|
config CAN_RCAR
|
||||||
tristate "Renesas R-Car CAN controller"
|
tristate "Renesas R-Car and RZ/G CAN controller"
|
||||||
depends on ARCH_RENESAS || ARM
|
depends on ARCH_RENESAS || ARM
|
||||||
help
|
help
|
||||||
Say Y here if you want to use CAN controller found on Renesas R-Car
|
Say Y here if you want to use CAN controller found on Renesas R-Car
|
||||||
SoCs.
|
or RZ/G SoCs.
|
||||||
|
|
||||||
To compile this driver as a module, choose M here: the module will
|
To compile this driver as a module, choose M here: the module will
|
||||||
be called rcar_can.
|
be called rcar_can.
|
||||||
|
@ -1368,13 +1368,10 @@ static int mcp251xfd_handle_tefif(struct mcp251xfd_priv *priv)
|
|||||||
struct mcp251xfd_tx_ring *tx_ring = priv->tx;
|
struct mcp251xfd_tx_ring *tx_ring = priv->tx;
|
||||||
struct spi_transfer *last_xfer;
|
struct spi_transfer *last_xfer;
|
||||||
|
|
||||||
tx_ring->tail += len;
|
|
||||||
|
|
||||||
/* Increment the TEF FIFO tail pointer 'len' times in
|
/* Increment the TEF FIFO tail pointer 'len' times in
|
||||||
* a single SPI message.
|
* a single SPI message.
|
||||||
*/
|
*
|
||||||
|
* Note:
|
||||||
/* Note:
|
|
||||||
*
|
*
|
||||||
* "cs_change == 1" on the last transfer results in an
|
* "cs_change == 1" on the last transfer results in an
|
||||||
* active chip select after the complete SPI
|
* active chip select after the complete SPI
|
||||||
@ -1391,6 +1388,8 @@ static int mcp251xfd_handle_tefif(struct mcp251xfd_priv *priv)
|
|||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
|
tx_ring->tail += len;
|
||||||
|
|
||||||
err = mcp251xfd_check_tef_tail(priv);
|
err = mcp251xfd_check_tef_tail(priv);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
@ -1553,10 +1552,8 @@ mcp251xfd_handle_rxif_ring(struct mcp251xfd_priv *priv,
|
|||||||
|
|
||||||
/* Increment the RX FIFO tail pointer 'len' times in a
|
/* Increment the RX FIFO tail pointer 'len' times in a
|
||||||
* single SPI message.
|
* single SPI message.
|
||||||
*/
|
*
|
||||||
ring->tail += len;
|
* Note:
|
||||||
|
|
||||||
/* Note:
|
|
||||||
*
|
*
|
||||||
* "cs_change == 1" on the last transfer results in an
|
* "cs_change == 1" on the last transfer results in an
|
||||||
* active chip select after the complete SPI
|
* active chip select after the complete SPI
|
||||||
@ -1572,6 +1569,8 @@ mcp251xfd_handle_rxif_ring(struct mcp251xfd_priv *priv,
|
|||||||
last_xfer->cs_change = 1;
|
last_xfer->cs_change = 1;
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
|
ring->tail += len;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -4,6 +4,7 @@ config NET_DSA_HIRSCHMANN_HELLCREEK
|
|||||||
depends on HAS_IOMEM
|
depends on HAS_IOMEM
|
||||||
depends on NET_DSA
|
depends on NET_DSA
|
||||||
depends on PTP_1588_CLOCK
|
depends on PTP_1588_CLOCK
|
||||||
|
depends on LEDS_CLASS
|
||||||
select NET_DSA_TAG_HELLCREEK
|
select NET_DSA_TAG_HELLCREEK
|
||||||
help
|
help
|
||||||
This driver adds support for Hirschmann Hellcreek TSN switches.
|
This driver adds support for Hirschmann Hellcreek TSN switches.
|
||||||
|
@ -1436,11 +1436,12 @@ static void gswip_phylink_validate(struct dsa_switch *ds, int port,
|
|||||||
phylink_set(mask, Pause);
|
phylink_set(mask, Pause);
|
||||||
phylink_set(mask, Asym_Pause);
|
phylink_set(mask, Asym_Pause);
|
||||||
|
|
||||||
/* With the exclusion of MII and Reverse MII, we support Gigabit,
|
/* With the exclusion of MII, Reverse MII and Reduced MII, we
|
||||||
* including Half duplex
|
* support Gigabit, including Half duplex
|
||||||
*/
|
*/
|
||||||
if (state->interface != PHY_INTERFACE_MODE_MII &&
|
if (state->interface != PHY_INTERFACE_MODE_MII &&
|
||||||
state->interface != PHY_INTERFACE_MODE_REVMII) {
|
state->interface != PHY_INTERFACE_MODE_REVMII &&
|
||||||
|
state->interface != PHY_INTERFACE_MODE_RMII) {
|
||||||
phylink_set(mask, 1000baseT_Full);
|
phylink_set(mask, 1000baseT_Full);
|
||||||
phylink_set(mask, 1000baseT_Half);
|
phylink_set(mask, 1000baseT_Half);
|
||||||
}
|
}
|
||||||
|
@ -621,7 +621,7 @@ static void chtls_reset_synq(struct listen_ctx *listen_ctx)
|
|||||||
|
|
||||||
while (!skb_queue_empty(&listen_ctx->synq)) {
|
while (!skb_queue_empty(&listen_ctx->synq)) {
|
||||||
struct chtls_sock *csk =
|
struct chtls_sock *csk =
|
||||||
container_of((struct synq *)__skb_dequeue
|
container_of((struct synq *)skb_peek
|
||||||
(&listen_ctx->synq), struct chtls_sock, synq);
|
(&listen_ctx->synq), struct chtls_sock, synq);
|
||||||
struct sock *child = csk->sk;
|
struct sock *child = csk->sk;
|
||||||
|
|
||||||
@ -1109,6 +1109,7 @@ static struct sock *chtls_recv_sock(struct sock *lsk,
|
|||||||
const struct cpl_pass_accept_req *req,
|
const struct cpl_pass_accept_req *req,
|
||||||
struct chtls_dev *cdev)
|
struct chtls_dev *cdev)
|
||||||
{
|
{
|
||||||
|
struct adapter *adap = pci_get_drvdata(cdev->pdev);
|
||||||
struct neighbour *n = NULL;
|
struct neighbour *n = NULL;
|
||||||
struct inet_sock *newinet;
|
struct inet_sock *newinet;
|
||||||
const struct iphdr *iph;
|
const struct iphdr *iph;
|
||||||
@ -1118,9 +1119,10 @@ static struct sock *chtls_recv_sock(struct sock *lsk,
|
|||||||
struct dst_entry *dst;
|
struct dst_entry *dst;
|
||||||
struct tcp_sock *tp;
|
struct tcp_sock *tp;
|
||||||
struct sock *newsk;
|
struct sock *newsk;
|
||||||
|
bool found = false;
|
||||||
u16 port_id;
|
u16 port_id;
|
||||||
int rxq_idx;
|
int rxq_idx;
|
||||||
int step;
|
int step, i;
|
||||||
|
|
||||||
iph = (const struct iphdr *)network_hdr;
|
iph = (const struct iphdr *)network_hdr;
|
||||||
newsk = tcp_create_openreq_child(lsk, oreq, cdev->askb);
|
newsk = tcp_create_openreq_child(lsk, oreq, cdev->askb);
|
||||||
@ -1152,7 +1154,7 @@ static struct sock *chtls_recv_sock(struct sock *lsk,
|
|||||||
n = dst_neigh_lookup(dst, &ip6h->saddr);
|
n = dst_neigh_lookup(dst, &ip6h->saddr);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
if (!n)
|
if (!n || !n->dev)
|
||||||
goto free_sk;
|
goto free_sk;
|
||||||
|
|
||||||
ndev = n->dev;
|
ndev = n->dev;
|
||||||
@ -1161,6 +1163,13 @@ static struct sock *chtls_recv_sock(struct sock *lsk,
|
|||||||
if (is_vlan_dev(ndev))
|
if (is_vlan_dev(ndev))
|
||||||
ndev = vlan_dev_real_dev(ndev);
|
ndev = vlan_dev_real_dev(ndev);
|
||||||
|
|
||||||
|
for_each_port(adap, i)
|
||||||
|
if (cdev->ports[i] == ndev)
|
||||||
|
found = true;
|
||||||
|
|
||||||
|
if (!found)
|
||||||
|
goto free_dst;
|
||||||
|
|
||||||
port_id = cxgb4_port_idx(ndev);
|
port_id = cxgb4_port_idx(ndev);
|
||||||
|
|
||||||
csk = chtls_sock_create(cdev);
|
csk = chtls_sock_create(cdev);
|
||||||
@ -1238,6 +1247,7 @@ static struct sock *chtls_recv_sock(struct sock *lsk,
|
|||||||
free_csk:
|
free_csk:
|
||||||
chtls_sock_release(&csk->kref);
|
chtls_sock_release(&csk->kref);
|
||||||
free_dst:
|
free_dst:
|
||||||
|
neigh_release(n);
|
||||||
dst_release(dst);
|
dst_release(dst);
|
||||||
free_sk:
|
free_sk:
|
||||||
inet_csk_prepare_forced_close(newsk);
|
inet_csk_prepare_forced_close(newsk);
|
||||||
@ -1387,7 +1397,7 @@ static void chtls_pass_accept_request(struct sock *sk,
|
|||||||
|
|
||||||
newsk = chtls_recv_sock(sk, oreq, network_hdr, req, cdev);
|
newsk = chtls_recv_sock(sk, oreq, network_hdr, req, cdev);
|
||||||
if (!newsk)
|
if (!newsk)
|
||||||
goto free_oreq;
|
goto reject;
|
||||||
|
|
||||||
if (chtls_get_module(newsk))
|
if (chtls_get_module(newsk))
|
||||||
goto reject;
|
goto reject;
|
||||||
@ -1403,8 +1413,6 @@ static void chtls_pass_accept_request(struct sock *sk,
|
|||||||
kfree_skb(skb);
|
kfree_skb(skb);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
free_oreq:
|
|
||||||
chtls_reqsk_free(oreq);
|
|
||||||
reject:
|
reject:
|
||||||
mk_tid_release(reply_skb, 0, tid);
|
mk_tid_release(reply_skb, 0, tid);
|
||||||
cxgb4_ofld_send(cdev->lldi->ports[0], reply_skb);
|
cxgb4_ofld_send(cdev->lldi->ports[0], reply_skb);
|
||||||
@ -1589,6 +1597,11 @@ static int chtls_pass_establish(struct chtls_dev *cdev, struct sk_buff *skb)
|
|||||||
sk_wake_async(sk, 0, POLL_OUT);
|
sk_wake_async(sk, 0, POLL_OUT);
|
||||||
|
|
||||||
data = lookup_stid(cdev->tids, stid);
|
data = lookup_stid(cdev->tids, stid);
|
||||||
|
if (!data) {
|
||||||
|
/* listening server close */
|
||||||
|
kfree_skb(skb);
|
||||||
|
goto unlock;
|
||||||
|
}
|
||||||
lsk = ((struct listen_ctx *)data)->lsk;
|
lsk = ((struct listen_ctx *)data)->lsk;
|
||||||
|
|
||||||
bh_lock_sock(lsk);
|
bh_lock_sock(lsk);
|
||||||
@ -1997,39 +2010,6 @@ static void t4_defer_reply(struct sk_buff *skb, struct chtls_dev *cdev,
|
|||||||
spin_unlock_bh(&cdev->deferq.lock);
|
spin_unlock_bh(&cdev->deferq.lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void send_abort_rpl(struct sock *sk, struct sk_buff *skb,
|
|
||||||
struct chtls_dev *cdev, int status, int queue)
|
|
||||||
{
|
|
||||||
struct cpl_abort_req_rss *req = cplhdr(skb);
|
|
||||||
struct sk_buff *reply_skb;
|
|
||||||
struct chtls_sock *csk;
|
|
||||||
|
|
||||||
csk = rcu_dereference_sk_user_data(sk);
|
|
||||||
|
|
||||||
reply_skb = alloc_skb(sizeof(struct cpl_abort_rpl),
|
|
||||||
GFP_KERNEL);
|
|
||||||
|
|
||||||
if (!reply_skb) {
|
|
||||||
req->status = (queue << 1);
|
|
||||||
t4_defer_reply(skb, cdev, send_defer_abort_rpl);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
set_abort_rpl_wr(reply_skb, GET_TID(req), status);
|
|
||||||
kfree_skb(skb);
|
|
||||||
|
|
||||||
set_wr_txq(reply_skb, CPL_PRIORITY_DATA, queue);
|
|
||||||
if (csk_conn_inline(csk)) {
|
|
||||||
struct l2t_entry *e = csk->l2t_entry;
|
|
||||||
|
|
||||||
if (e && sk->sk_state != TCP_SYN_RECV) {
|
|
||||||
cxgb4_l2t_send(csk->egress_dev, reply_skb, e);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cxgb4_ofld_send(cdev->lldi->ports[0], reply_skb);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void chtls_send_abort_rpl(struct sock *sk, struct sk_buff *skb,
|
static void chtls_send_abort_rpl(struct sock *sk, struct sk_buff *skb,
|
||||||
struct chtls_dev *cdev,
|
struct chtls_dev *cdev,
|
||||||
int status, int queue)
|
int status, int queue)
|
||||||
@ -2078,9 +2058,9 @@ static void bl_abort_syn_rcv(struct sock *lsk, struct sk_buff *skb)
|
|||||||
queue = csk->txq_idx;
|
queue = csk->txq_idx;
|
||||||
|
|
||||||
skb->sk = NULL;
|
skb->sk = NULL;
|
||||||
|
chtls_send_abort_rpl(child, skb, BLOG_SKB_CB(skb)->cdev,
|
||||||
|
CPL_ABORT_NO_RST, queue);
|
||||||
do_abort_syn_rcv(child, lsk);
|
do_abort_syn_rcv(child, lsk);
|
||||||
send_abort_rpl(child, skb, BLOG_SKB_CB(skb)->cdev,
|
|
||||||
CPL_ABORT_NO_RST, queue);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int abort_syn_rcv(struct sock *sk, struct sk_buff *skb)
|
static int abort_syn_rcv(struct sock *sk, struct sk_buff *skb)
|
||||||
@ -2110,8 +2090,8 @@ static int abort_syn_rcv(struct sock *sk, struct sk_buff *skb)
|
|||||||
if (!sock_owned_by_user(psk)) {
|
if (!sock_owned_by_user(psk)) {
|
||||||
int queue = csk->txq_idx;
|
int queue = csk->txq_idx;
|
||||||
|
|
||||||
|
chtls_send_abort_rpl(sk, skb, cdev, CPL_ABORT_NO_RST, queue);
|
||||||
do_abort_syn_rcv(sk, psk);
|
do_abort_syn_rcv(sk, psk);
|
||||||
send_abort_rpl(sk, skb, cdev, CPL_ABORT_NO_RST, queue);
|
|
||||||
} else {
|
} else {
|
||||||
skb->sk = sk;
|
skb->sk = sk;
|
||||||
BLOG_SKB_CB(skb)->backlog_rcv = bl_abort_syn_rcv;
|
BLOG_SKB_CB(skb)->backlog_rcv = bl_abort_syn_rcv;
|
||||||
@ -2129,9 +2109,6 @@ static void chtls_abort_req_rss(struct sock *sk, struct sk_buff *skb)
|
|||||||
int queue = csk->txq_idx;
|
int queue = csk->txq_idx;
|
||||||
|
|
||||||
if (is_neg_adv(req->status)) {
|
if (is_neg_adv(req->status)) {
|
||||||
if (sk->sk_state == TCP_SYN_RECV)
|
|
||||||
chtls_set_tcb_tflag(sk, 0, 0);
|
|
||||||
|
|
||||||
kfree_skb(skb);
|
kfree_skb(skb);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -2158,12 +2135,12 @@ static void chtls_abort_req_rss(struct sock *sk, struct sk_buff *skb)
|
|||||||
if (sk->sk_state == TCP_SYN_RECV && !abort_syn_rcv(sk, skb))
|
if (sk->sk_state == TCP_SYN_RECV && !abort_syn_rcv(sk, skb))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
chtls_release_resources(sk);
|
|
||||||
chtls_conn_done(sk);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
chtls_send_abort_rpl(sk, skb, BLOG_SKB_CB(skb)->cdev,
|
chtls_send_abort_rpl(sk, skb, BLOG_SKB_CB(skb)->cdev,
|
||||||
rst_status, queue);
|
rst_status, queue);
|
||||||
|
chtls_release_resources(sk);
|
||||||
|
chtls_conn_done(sk);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void chtls_abort_rpl_rss(struct sock *sk, struct sk_buff *skb)
|
static void chtls_abort_rpl_rss(struct sock *sk, struct sk_buff *skb)
|
||||||
|
@ -223,3 +223,4 @@ static struct platform_driver fs_enet_bb_mdio_driver = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
module_platform_driver(fs_enet_bb_mdio_driver);
|
module_platform_driver(fs_enet_bb_mdio_driver);
|
||||||
|
MODULE_LICENSE("GPL");
|
||||||
|
@ -224,3 +224,4 @@ static struct platform_driver fs_enet_fec_mdio_driver = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
module_platform_driver(fs_enet_fec_mdio_driver);
|
module_platform_driver(fs_enet_fec_mdio_driver);
|
||||||
|
MODULE_LICENSE("GPL");
|
||||||
|
@ -169,7 +169,7 @@ struct hclgevf_mbx_arq_ring {
|
|||||||
#define hclge_mbx_ring_ptr_move_crq(crq) \
|
#define hclge_mbx_ring_ptr_move_crq(crq) \
|
||||||
(crq->next_to_use = (crq->next_to_use + 1) % crq->desc_num)
|
(crq->next_to_use = (crq->next_to_use + 1) % crq->desc_num)
|
||||||
#define hclge_mbx_tail_ptr_move_arq(arq) \
|
#define hclge_mbx_tail_ptr_move_arq(arq) \
|
||||||
(arq.tail = (arq.tail + 1) % HCLGE_MBX_MAX_ARQ_MSG_SIZE)
|
(arq.tail = (arq.tail + 1) % HCLGE_MBX_MAX_ARQ_MSG_NUM)
|
||||||
#define hclge_mbx_head_ptr_move_arq(arq) \
|
#define hclge_mbx_head_ptr_move_arq(arq) \
|
||||||
(arq.head = (arq.head + 1) % HCLGE_MBX_MAX_ARQ_MSG_SIZE)
|
(arq.head = (arq.head + 1) % HCLGE_MBX_MAX_ARQ_MSG_NUM)
|
||||||
#endif
|
#endif
|
||||||
|
@ -752,7 +752,8 @@ static int hclge_get_sset_count(struct hnae3_handle *handle, int stringset)
|
|||||||
handle->flags |= HNAE3_SUPPORT_SERDES_SERIAL_LOOPBACK;
|
handle->flags |= HNAE3_SUPPORT_SERDES_SERIAL_LOOPBACK;
|
||||||
handle->flags |= HNAE3_SUPPORT_SERDES_PARALLEL_LOOPBACK;
|
handle->flags |= HNAE3_SUPPORT_SERDES_PARALLEL_LOOPBACK;
|
||||||
|
|
||||||
if (hdev->hw.mac.phydev) {
|
if (hdev->hw.mac.phydev && hdev->hw.mac.phydev->drv &&
|
||||||
|
hdev->hw.mac.phydev->drv->set_loopback) {
|
||||||
count += 1;
|
count += 1;
|
||||||
handle->flags |= HNAE3_SUPPORT_PHY_LOOPBACK;
|
handle->flags |= HNAE3_SUPPORT_PHY_LOOPBACK;
|
||||||
}
|
}
|
||||||
@ -4537,8 +4538,8 @@ static int hclge_set_rss_tuple(struct hnae3_handle *handle,
|
|||||||
req->ipv4_sctp_en = tuple_sets;
|
req->ipv4_sctp_en = tuple_sets;
|
||||||
break;
|
break;
|
||||||
case SCTP_V6_FLOW:
|
case SCTP_V6_FLOW:
|
||||||
if ((nfc->data & RXH_L4_B_0_1) ||
|
if (hdev->ae_dev->dev_version <= HNAE3_DEVICE_VERSION_V2 &&
|
||||||
(nfc->data & RXH_L4_B_2_3))
|
(nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
req->ipv6_sctp_en = tuple_sets;
|
req->ipv6_sctp_en = tuple_sets;
|
||||||
@ -4730,6 +4731,8 @@ static void hclge_rss_init_cfg(struct hclge_dev *hdev)
|
|||||||
vport[i].rss_tuple_sets.ipv6_udp_en =
|
vport[i].rss_tuple_sets.ipv6_udp_en =
|
||||||
HCLGE_RSS_INPUT_TUPLE_OTHER;
|
HCLGE_RSS_INPUT_TUPLE_OTHER;
|
||||||
vport[i].rss_tuple_sets.ipv6_sctp_en =
|
vport[i].rss_tuple_sets.ipv6_sctp_en =
|
||||||
|
hdev->ae_dev->dev_version <= HNAE3_DEVICE_VERSION_V2 ?
|
||||||
|
HCLGE_RSS_INPUT_TUPLE_SCTP_NO_PORT :
|
||||||
HCLGE_RSS_INPUT_TUPLE_SCTP;
|
HCLGE_RSS_INPUT_TUPLE_SCTP;
|
||||||
vport[i].rss_tuple_sets.ipv6_fragment_en =
|
vport[i].rss_tuple_sets.ipv6_fragment_en =
|
||||||
HCLGE_RSS_INPUT_TUPLE_OTHER;
|
HCLGE_RSS_INPUT_TUPLE_OTHER;
|
||||||
|
@ -107,6 +107,8 @@
|
|||||||
#define HCLGE_D_IP_BIT BIT(2)
|
#define HCLGE_D_IP_BIT BIT(2)
|
||||||
#define HCLGE_S_IP_BIT BIT(3)
|
#define HCLGE_S_IP_BIT BIT(3)
|
||||||
#define HCLGE_V_TAG_BIT BIT(4)
|
#define HCLGE_V_TAG_BIT BIT(4)
|
||||||
|
#define HCLGE_RSS_INPUT_TUPLE_SCTP_NO_PORT \
|
||||||
|
(HCLGE_D_IP_BIT | HCLGE_S_IP_BIT | HCLGE_V_TAG_BIT)
|
||||||
|
|
||||||
#define HCLGE_RSS_TC_SIZE_0 1
|
#define HCLGE_RSS_TC_SIZE_0 1
|
||||||
#define HCLGE_RSS_TC_SIZE_1 2
|
#define HCLGE_RSS_TC_SIZE_1 2
|
||||||
|
@ -917,8 +917,8 @@ static int hclgevf_set_rss_tuple(struct hnae3_handle *handle,
|
|||||||
req->ipv4_sctp_en = tuple_sets;
|
req->ipv4_sctp_en = tuple_sets;
|
||||||
break;
|
break;
|
||||||
case SCTP_V6_FLOW:
|
case SCTP_V6_FLOW:
|
||||||
if ((nfc->data & RXH_L4_B_0_1) ||
|
if (hdev->ae_dev->dev_version <= HNAE3_DEVICE_VERSION_V2 &&
|
||||||
(nfc->data & RXH_L4_B_2_3))
|
(nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
req->ipv6_sctp_en = tuple_sets;
|
req->ipv6_sctp_en = tuple_sets;
|
||||||
@ -2502,7 +2502,10 @@ static void hclgevf_rss_init_cfg(struct hclgevf_dev *hdev)
|
|||||||
tuple_sets->ipv4_fragment_en = HCLGEVF_RSS_INPUT_TUPLE_OTHER;
|
tuple_sets->ipv4_fragment_en = HCLGEVF_RSS_INPUT_TUPLE_OTHER;
|
||||||
tuple_sets->ipv6_tcp_en = HCLGEVF_RSS_INPUT_TUPLE_OTHER;
|
tuple_sets->ipv6_tcp_en = HCLGEVF_RSS_INPUT_TUPLE_OTHER;
|
||||||
tuple_sets->ipv6_udp_en = HCLGEVF_RSS_INPUT_TUPLE_OTHER;
|
tuple_sets->ipv6_udp_en = HCLGEVF_RSS_INPUT_TUPLE_OTHER;
|
||||||
tuple_sets->ipv6_sctp_en = HCLGEVF_RSS_INPUT_TUPLE_SCTP;
|
tuple_sets->ipv6_sctp_en =
|
||||||
|
hdev->ae_dev->dev_version <= HNAE3_DEVICE_VERSION_V2 ?
|
||||||
|
HCLGEVF_RSS_INPUT_TUPLE_SCTP_NO_PORT :
|
||||||
|
HCLGEVF_RSS_INPUT_TUPLE_SCTP;
|
||||||
tuple_sets->ipv6_fragment_en = HCLGEVF_RSS_INPUT_TUPLE_OTHER;
|
tuple_sets->ipv6_fragment_en = HCLGEVF_RSS_INPUT_TUPLE_OTHER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -122,6 +122,8 @@
|
|||||||
#define HCLGEVF_D_IP_BIT BIT(2)
|
#define HCLGEVF_D_IP_BIT BIT(2)
|
||||||
#define HCLGEVF_S_IP_BIT BIT(3)
|
#define HCLGEVF_S_IP_BIT BIT(3)
|
||||||
#define HCLGEVF_V_TAG_BIT BIT(4)
|
#define HCLGEVF_V_TAG_BIT BIT(4)
|
||||||
|
#define HCLGEVF_RSS_INPUT_TUPLE_SCTP_NO_PORT \
|
||||||
|
(HCLGEVF_D_IP_BIT | HCLGEVF_S_IP_BIT | HCLGEVF_V_TAG_BIT)
|
||||||
|
|
||||||
#define HCLGEVF_STATS_TIMER_INTERVAL 36U
|
#define HCLGEVF_STATS_TIMER_INTERVAL 36U
|
||||||
|
|
||||||
|
@ -4432,7 +4432,7 @@ static int mvneta_xdp_setup(struct net_device *dev, struct bpf_prog *prog,
|
|||||||
struct bpf_prog *old_prog;
|
struct bpf_prog *old_prog;
|
||||||
|
|
||||||
if (prog && dev->mtu > MVNETA_MAX_RX_BUF_SIZE) {
|
if (prog && dev->mtu > MVNETA_MAX_RX_BUF_SIZE) {
|
||||||
NL_SET_ERR_MSG_MOD(extack, "Jumbo frames not supported on XDP");
|
NL_SET_ERR_MSG_MOD(extack, "MTU too large for XDP");
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -871,8 +871,10 @@ static int cgx_lmac_init(struct cgx *cgx)
|
|||||||
if (!lmac)
|
if (!lmac)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
lmac->name = kcalloc(1, sizeof("cgx_fwi_xxx_yyy"), GFP_KERNEL);
|
lmac->name = kcalloc(1, sizeof("cgx_fwi_xxx_yyy"), GFP_KERNEL);
|
||||||
if (!lmac->name)
|
if (!lmac->name) {
|
||||||
return -ENOMEM;
|
err = -ENOMEM;
|
||||||
|
goto err_lmac_free;
|
||||||
|
}
|
||||||
sprintf(lmac->name, "cgx_fwi_%d_%d", cgx->cgx_id, i);
|
sprintf(lmac->name, "cgx_fwi_%d_%d", cgx->cgx_id, i);
|
||||||
lmac->lmac_id = i;
|
lmac->lmac_id = i;
|
||||||
lmac->cgx = cgx;
|
lmac->cgx = cgx;
|
||||||
@ -883,7 +885,7 @@ static int cgx_lmac_init(struct cgx *cgx)
|
|||||||
CGX_LMAC_FWI + i * 9),
|
CGX_LMAC_FWI + i * 9),
|
||||||
cgx_fwi_event_handler, 0, lmac->name, lmac);
|
cgx_fwi_event_handler, 0, lmac->name, lmac);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
goto err_irq;
|
||||||
|
|
||||||
/* Enable interrupt */
|
/* Enable interrupt */
|
||||||
cgx_write(cgx, lmac->lmac_id, CGXX_CMRX_INT_ENA_W1S,
|
cgx_write(cgx, lmac->lmac_id, CGXX_CMRX_INT_ENA_W1S,
|
||||||
@ -895,6 +897,12 @@ static int cgx_lmac_init(struct cgx *cgx)
|
|||||||
}
|
}
|
||||||
|
|
||||||
return cgx_lmac_verify_fwi_version(cgx);
|
return cgx_lmac_verify_fwi_version(cgx);
|
||||||
|
|
||||||
|
err_irq:
|
||||||
|
kfree(lmac->name);
|
||||||
|
err_lmac_free:
|
||||||
|
kfree(lmac);
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cgx_lmac_exit(struct cgx *cgx)
|
static int cgx_lmac_exit(struct cgx *cgx)
|
||||||
|
@ -626,6 +626,11 @@ bool mlx5e_rep_tc_update_skb(struct mlx5_cqe64 *cqe,
|
|||||||
if (!reg_c0)
|
if (!reg_c0)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
/* If reg_c0 is not equal to the default flow tag then skb->mark
|
||||||
|
* is not supported and must be reset back to 0.
|
||||||
|
*/
|
||||||
|
skb->mark = 0;
|
||||||
|
|
||||||
priv = netdev_priv(skb->dev);
|
priv = netdev_priv(skb->dev);
|
||||||
esw = priv->mdev->priv.eswitch;
|
esw = priv->mdev->priv.eswitch;
|
||||||
|
|
||||||
|
@ -118,16 +118,17 @@ struct mlx5_ct_tuple {
|
|||||||
u16 zone;
|
u16 zone;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct mlx5_ct_shared_counter {
|
struct mlx5_ct_counter {
|
||||||
struct mlx5_fc *counter;
|
struct mlx5_fc *counter;
|
||||||
refcount_t refcount;
|
refcount_t refcount;
|
||||||
|
bool is_shared;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct mlx5_ct_entry {
|
struct mlx5_ct_entry {
|
||||||
struct rhash_head node;
|
struct rhash_head node;
|
||||||
struct rhash_head tuple_node;
|
struct rhash_head tuple_node;
|
||||||
struct rhash_head tuple_nat_node;
|
struct rhash_head tuple_nat_node;
|
||||||
struct mlx5_ct_shared_counter *shared_counter;
|
struct mlx5_ct_counter *counter;
|
||||||
unsigned long cookie;
|
unsigned long cookie;
|
||||||
unsigned long restore_cookie;
|
unsigned long restore_cookie;
|
||||||
struct mlx5_ct_tuple tuple;
|
struct mlx5_ct_tuple tuple;
|
||||||
@ -394,13 +395,14 @@ mlx5_tc_ct_set_tuple_match(struct mlx5e_priv *priv, struct mlx5_flow_spec *spec,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
mlx5_tc_ct_shared_counter_put(struct mlx5_tc_ct_priv *ct_priv, struct mlx5_ct_entry *entry)
|
mlx5_tc_ct_counter_put(struct mlx5_tc_ct_priv *ct_priv, struct mlx5_ct_entry *entry)
|
||||||
{
|
{
|
||||||
if (!refcount_dec_and_test(&entry->shared_counter->refcount))
|
if (entry->counter->is_shared &&
|
||||||
|
!refcount_dec_and_test(&entry->counter->refcount))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
mlx5_fc_destroy(ct_priv->dev, entry->shared_counter->counter);
|
mlx5_fc_destroy(ct_priv->dev, entry->counter->counter);
|
||||||
kfree(entry->shared_counter);
|
kfree(entry->counter);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -699,7 +701,7 @@ mlx5_tc_ct_entry_add_rule(struct mlx5_tc_ct_priv *ct_priv,
|
|||||||
attr->dest_ft = ct_priv->post_ct;
|
attr->dest_ft = ct_priv->post_ct;
|
||||||
attr->ft = nat ? ct_priv->ct_nat : ct_priv->ct;
|
attr->ft = nat ? ct_priv->ct_nat : ct_priv->ct;
|
||||||
attr->outer_match_level = MLX5_MATCH_L4;
|
attr->outer_match_level = MLX5_MATCH_L4;
|
||||||
attr->counter = entry->shared_counter->counter;
|
attr->counter = entry->counter->counter;
|
||||||
attr->flags |= MLX5_ESW_ATTR_FLAG_NO_IN_PORT;
|
attr->flags |= MLX5_ESW_ATTR_FLAG_NO_IN_PORT;
|
||||||
|
|
||||||
mlx5_tc_ct_set_tuple_match(netdev_priv(ct_priv->netdev), spec, flow_rule);
|
mlx5_tc_ct_set_tuple_match(netdev_priv(ct_priv->netdev), spec, flow_rule);
|
||||||
@ -732,13 +734,34 @@ err_attr:
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct mlx5_ct_shared_counter *
|
static struct mlx5_ct_counter *
|
||||||
|
mlx5_tc_ct_counter_create(struct mlx5_tc_ct_priv *ct_priv)
|
||||||
|
{
|
||||||
|
struct mlx5_ct_counter *counter;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
counter = kzalloc(sizeof(*counter), GFP_KERNEL);
|
||||||
|
if (!counter)
|
||||||
|
return ERR_PTR(-ENOMEM);
|
||||||
|
|
||||||
|
counter->is_shared = false;
|
||||||
|
counter->counter = mlx5_fc_create(ct_priv->dev, true);
|
||||||
|
if (IS_ERR(counter->counter)) {
|
||||||
|
ct_dbg("Failed to create counter for ct entry");
|
||||||
|
ret = PTR_ERR(counter->counter);
|
||||||
|
kfree(counter);
|
||||||
|
return ERR_PTR(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
return counter;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct mlx5_ct_counter *
|
||||||
mlx5_tc_ct_shared_counter_get(struct mlx5_tc_ct_priv *ct_priv,
|
mlx5_tc_ct_shared_counter_get(struct mlx5_tc_ct_priv *ct_priv,
|
||||||
struct mlx5_ct_entry *entry)
|
struct mlx5_ct_entry *entry)
|
||||||
{
|
{
|
||||||
struct mlx5_ct_tuple rev_tuple = entry->tuple;
|
struct mlx5_ct_tuple rev_tuple = entry->tuple;
|
||||||
struct mlx5_ct_shared_counter *shared_counter;
|
struct mlx5_ct_counter *shared_counter;
|
||||||
struct mlx5_core_dev *dev = ct_priv->dev;
|
|
||||||
struct mlx5_ct_entry *rev_entry;
|
struct mlx5_ct_entry *rev_entry;
|
||||||
__be16 tmp_port;
|
__be16 tmp_port;
|
||||||
int ret;
|
int ret;
|
||||||
@ -767,25 +790,20 @@ mlx5_tc_ct_shared_counter_get(struct mlx5_tc_ct_priv *ct_priv,
|
|||||||
rev_entry = rhashtable_lookup_fast(&ct_priv->ct_tuples_ht, &rev_tuple,
|
rev_entry = rhashtable_lookup_fast(&ct_priv->ct_tuples_ht, &rev_tuple,
|
||||||
tuples_ht_params);
|
tuples_ht_params);
|
||||||
if (rev_entry) {
|
if (rev_entry) {
|
||||||
if (refcount_inc_not_zero(&rev_entry->shared_counter->refcount)) {
|
if (refcount_inc_not_zero(&rev_entry->counter->refcount)) {
|
||||||
mutex_unlock(&ct_priv->shared_counter_lock);
|
mutex_unlock(&ct_priv->shared_counter_lock);
|
||||||
return rev_entry->shared_counter;
|
return rev_entry->counter;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mutex_unlock(&ct_priv->shared_counter_lock);
|
mutex_unlock(&ct_priv->shared_counter_lock);
|
||||||
|
|
||||||
shared_counter = kzalloc(sizeof(*shared_counter), GFP_KERNEL);
|
shared_counter = mlx5_tc_ct_counter_create(ct_priv);
|
||||||
if (!shared_counter)
|
if (IS_ERR(shared_counter)) {
|
||||||
return ERR_PTR(-ENOMEM);
|
ret = PTR_ERR(shared_counter);
|
||||||
|
|
||||||
shared_counter->counter = mlx5_fc_create(dev, true);
|
|
||||||
if (IS_ERR(shared_counter->counter)) {
|
|
||||||
ct_dbg("Failed to create counter for ct entry");
|
|
||||||
ret = PTR_ERR(shared_counter->counter);
|
|
||||||
kfree(shared_counter);
|
|
||||||
return ERR_PTR(ret);
|
return ERR_PTR(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
shared_counter->is_shared = true;
|
||||||
refcount_set(&shared_counter->refcount, 1);
|
refcount_set(&shared_counter->refcount, 1);
|
||||||
return shared_counter;
|
return shared_counter;
|
||||||
}
|
}
|
||||||
@ -798,10 +816,13 @@ mlx5_tc_ct_entry_add_rules(struct mlx5_tc_ct_priv *ct_priv,
|
|||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
entry->shared_counter = mlx5_tc_ct_shared_counter_get(ct_priv, entry);
|
if (nf_ct_acct_enabled(dev_net(ct_priv->netdev)))
|
||||||
if (IS_ERR(entry->shared_counter)) {
|
entry->counter = mlx5_tc_ct_counter_create(ct_priv);
|
||||||
err = PTR_ERR(entry->shared_counter);
|
else
|
||||||
ct_dbg("Failed to create counter for ct entry");
|
entry->counter = mlx5_tc_ct_shared_counter_get(ct_priv, entry);
|
||||||
|
|
||||||
|
if (IS_ERR(entry->counter)) {
|
||||||
|
err = PTR_ERR(entry->counter);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -820,7 +841,7 @@ mlx5_tc_ct_entry_add_rules(struct mlx5_tc_ct_priv *ct_priv,
|
|||||||
err_nat:
|
err_nat:
|
||||||
mlx5_tc_ct_entry_del_rule(ct_priv, entry, false);
|
mlx5_tc_ct_entry_del_rule(ct_priv, entry, false);
|
||||||
err_orig:
|
err_orig:
|
||||||
mlx5_tc_ct_shared_counter_put(ct_priv, entry);
|
mlx5_tc_ct_counter_put(ct_priv, entry);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -918,7 +939,7 @@ mlx5_tc_ct_del_ft_entry(struct mlx5_tc_ct_priv *ct_priv,
|
|||||||
rhashtable_remove_fast(&ct_priv->ct_tuples_ht, &entry->tuple_node,
|
rhashtable_remove_fast(&ct_priv->ct_tuples_ht, &entry->tuple_node,
|
||||||
tuples_ht_params);
|
tuples_ht_params);
|
||||||
mutex_unlock(&ct_priv->shared_counter_lock);
|
mutex_unlock(&ct_priv->shared_counter_lock);
|
||||||
mlx5_tc_ct_shared_counter_put(ct_priv, entry);
|
mlx5_tc_ct_counter_put(ct_priv, entry);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -956,7 +977,7 @@ mlx5_tc_ct_block_flow_offload_stats(struct mlx5_ct_ft *ft,
|
|||||||
if (!entry)
|
if (!entry)
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
|
|
||||||
mlx5_fc_query_cached(entry->shared_counter->counter, &bytes, &packets, &lastuse);
|
mlx5_fc_query_cached(entry->counter->counter, &bytes, &packets, &lastuse);
|
||||||
flow_stats_update(&f->stats, bytes, packets, 0, lastuse,
|
flow_stats_update(&f->stats, bytes, packets, 0, lastuse,
|
||||||
FLOW_ACTION_HW_STATS_DELAYED);
|
FLOW_ACTION_HW_STATS_DELAYED);
|
||||||
|
|
||||||
|
@ -371,6 +371,15 @@ struct mlx5e_swp_spec {
|
|||||||
u8 tun_l4_proto;
|
u8 tun_l4_proto;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static inline void mlx5e_eseg_swp_offsets_add_vlan(struct mlx5_wqe_eth_seg *eseg)
|
||||||
|
{
|
||||||
|
/* SWP offsets are in 2-bytes words */
|
||||||
|
eseg->swp_outer_l3_offset += VLAN_HLEN / 2;
|
||||||
|
eseg->swp_outer_l4_offset += VLAN_HLEN / 2;
|
||||||
|
eseg->swp_inner_l3_offset += VLAN_HLEN / 2;
|
||||||
|
eseg->swp_inner_l4_offset += VLAN_HLEN / 2;
|
||||||
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
mlx5e_set_eseg_swp(struct sk_buff *skb, struct mlx5_wqe_eth_seg *eseg,
|
mlx5e_set_eseg_swp(struct sk_buff *skb, struct mlx5_wqe_eth_seg *eseg,
|
||||||
struct mlx5e_swp_spec *swp_spec)
|
struct mlx5e_swp_spec *swp_spec)
|
||||||
|
@ -51,7 +51,7 @@ static inline bool mlx5_geneve_tx_allowed(struct mlx5_core_dev *mdev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
mlx5e_tx_tunnel_accel(struct sk_buff *skb, struct mlx5_wqe_eth_seg *eseg)
|
mlx5e_tx_tunnel_accel(struct sk_buff *skb, struct mlx5_wqe_eth_seg *eseg, u16 ihs)
|
||||||
{
|
{
|
||||||
struct mlx5e_swp_spec swp_spec = {};
|
struct mlx5e_swp_spec swp_spec = {};
|
||||||
unsigned int offset = 0;
|
unsigned int offset = 0;
|
||||||
@ -85,6 +85,8 @@ mlx5e_tx_tunnel_accel(struct sk_buff *skb, struct mlx5_wqe_eth_seg *eseg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
mlx5e_set_eseg_swp(skb, eseg, &swp_spec);
|
mlx5e_set_eseg_swp(skb, eseg, &swp_spec);
|
||||||
|
if (skb_vlan_tag_present(skb) && ihs)
|
||||||
|
mlx5e_eseg_swp_offsets_add_vlan(eseg);
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
@ -163,7 +165,7 @@ static inline unsigned int mlx5e_accel_tx_ids_len(struct mlx5e_txqsq *sq,
|
|||||||
|
|
||||||
static inline bool mlx5e_accel_tx_eseg(struct mlx5e_priv *priv,
|
static inline bool mlx5e_accel_tx_eseg(struct mlx5e_priv *priv,
|
||||||
struct sk_buff *skb,
|
struct sk_buff *skb,
|
||||||
struct mlx5_wqe_eth_seg *eseg)
|
struct mlx5_wqe_eth_seg *eseg, u16 ihs)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_MLX5_EN_IPSEC
|
#ifdef CONFIG_MLX5_EN_IPSEC
|
||||||
if (xfrm_offload(skb))
|
if (xfrm_offload(skb))
|
||||||
@ -172,7 +174,7 @@ static inline bool mlx5e_accel_tx_eseg(struct mlx5e_priv *priv,
|
|||||||
|
|
||||||
#if IS_ENABLED(CONFIG_GENEVE)
|
#if IS_ENABLED(CONFIG_GENEVE)
|
||||||
if (skb->encapsulation)
|
if (skb->encapsulation)
|
||||||
mlx5e_tx_tunnel_accel(skb, eseg);
|
mlx5e_tx_tunnel_accel(skb, eseg, ihs);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -1010,6 +1010,22 @@ static int mlx5e_get_link_ksettings(struct net_device *netdev,
|
|||||||
return mlx5e_ethtool_get_link_ksettings(priv, link_ksettings);
|
return mlx5e_ethtool_get_link_ksettings(priv, link_ksettings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int mlx5e_speed_validate(struct net_device *netdev, bool ext,
|
||||||
|
const unsigned long link_modes, u8 autoneg)
|
||||||
|
{
|
||||||
|
/* Extended link-mode has no speed limitations. */
|
||||||
|
if (ext)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if ((link_modes & MLX5E_PROT_MASK(MLX5E_56GBASE_R4)) &&
|
||||||
|
autoneg != AUTONEG_ENABLE) {
|
||||||
|
netdev_err(netdev, "%s: 56G link speed requires autoneg enabled\n",
|
||||||
|
__func__);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static u32 mlx5e_ethtool2ptys_adver_link(const unsigned long *link_modes)
|
static u32 mlx5e_ethtool2ptys_adver_link(const unsigned long *link_modes)
|
||||||
{
|
{
|
||||||
u32 i, ptys_modes = 0;
|
u32 i, ptys_modes = 0;
|
||||||
@ -1103,13 +1119,9 @@ int mlx5e_ethtool_set_link_ksettings(struct mlx5e_priv *priv,
|
|||||||
link_modes = autoneg == AUTONEG_ENABLE ? ethtool2ptys_adver_func(adver) :
|
link_modes = autoneg == AUTONEG_ENABLE ? ethtool2ptys_adver_func(adver) :
|
||||||
mlx5e_port_speed2linkmodes(mdev, speed, !ext);
|
mlx5e_port_speed2linkmodes(mdev, speed, !ext);
|
||||||
|
|
||||||
if ((link_modes & MLX5E_PROT_MASK(MLX5E_56GBASE_R4)) &&
|
err = mlx5e_speed_validate(priv->netdev, ext, link_modes, autoneg);
|
||||||
autoneg != AUTONEG_ENABLE) {
|
if (err)
|
||||||
netdev_err(priv->netdev, "%s: 56G link speed requires autoneg enabled\n",
|
|
||||||
__func__);
|
|
||||||
err = -EINVAL;
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
|
||||||
|
|
||||||
link_modes = link_modes & eproto.cap;
|
link_modes = link_modes & eproto.cap;
|
||||||
if (!link_modes) {
|
if (!link_modes) {
|
||||||
|
@ -942,6 +942,7 @@ static int mlx5e_create_ttc_table_groups(struct mlx5e_ttc_table *ttc,
|
|||||||
in = kvzalloc(inlen, GFP_KERNEL);
|
in = kvzalloc(inlen, GFP_KERNEL);
|
||||||
if (!in) {
|
if (!in) {
|
||||||
kfree(ft->g);
|
kfree(ft->g);
|
||||||
|
ft->g = NULL;
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1087,6 +1088,7 @@ static int mlx5e_create_inner_ttc_table_groups(struct mlx5e_ttc_table *ttc)
|
|||||||
in = kvzalloc(inlen, GFP_KERNEL);
|
in = kvzalloc(inlen, GFP_KERNEL);
|
||||||
if (!in) {
|
if (!in) {
|
||||||
kfree(ft->g);
|
kfree(ft->g);
|
||||||
|
ft->g = NULL;
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1390,6 +1392,7 @@ err_destroy_groups:
|
|||||||
ft->g[ft->num_groups] = NULL;
|
ft->g[ft->num_groups] = NULL;
|
||||||
mlx5e_destroy_groups(ft);
|
mlx5e_destroy_groups(ft);
|
||||||
kvfree(in);
|
kvfree(in);
|
||||||
|
kfree(ft->g);
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
@ -3161,7 +3161,8 @@ static void mlx5e_modify_admin_state(struct mlx5_core_dev *mdev,
|
|||||||
|
|
||||||
mlx5_set_port_admin_status(mdev, state);
|
mlx5_set_port_admin_status(mdev, state);
|
||||||
|
|
||||||
if (mlx5_eswitch_mode(mdev) != MLX5_ESWITCH_LEGACY)
|
if (mlx5_eswitch_mode(mdev) == MLX5_ESWITCH_OFFLOADS ||
|
||||||
|
!MLX5_CAP_GEN(mdev, uplink_follow))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (state == MLX5_PORT_UP)
|
if (state == MLX5_PORT_UP)
|
||||||
|
@ -682,9 +682,9 @@ void mlx5e_tx_mpwqe_ensure_complete(struct mlx5e_txqsq *sq)
|
|||||||
|
|
||||||
static bool mlx5e_txwqe_build_eseg(struct mlx5e_priv *priv, struct mlx5e_txqsq *sq,
|
static bool mlx5e_txwqe_build_eseg(struct mlx5e_priv *priv, struct mlx5e_txqsq *sq,
|
||||||
struct sk_buff *skb, struct mlx5e_accel_tx_state *accel,
|
struct sk_buff *skb, struct mlx5e_accel_tx_state *accel,
|
||||||
struct mlx5_wqe_eth_seg *eseg)
|
struct mlx5_wqe_eth_seg *eseg, u16 ihs)
|
||||||
{
|
{
|
||||||
if (unlikely(!mlx5e_accel_tx_eseg(priv, skb, eseg)))
|
if (unlikely(!mlx5e_accel_tx_eseg(priv, skb, eseg, ihs)))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
mlx5e_txwqe_build_eseg_csum(sq, skb, accel, eseg);
|
mlx5e_txwqe_build_eseg_csum(sq, skb, accel, eseg);
|
||||||
@ -714,7 +714,8 @@ netdev_tx_t mlx5e_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||||||
if (mlx5e_tx_skb_supports_mpwqe(skb, &attr)) {
|
if (mlx5e_tx_skb_supports_mpwqe(skb, &attr)) {
|
||||||
struct mlx5_wqe_eth_seg eseg = {};
|
struct mlx5_wqe_eth_seg eseg = {};
|
||||||
|
|
||||||
if (unlikely(!mlx5e_txwqe_build_eseg(priv, sq, skb, &accel, &eseg)))
|
if (unlikely(!mlx5e_txwqe_build_eseg(priv, sq, skb, &accel, &eseg,
|
||||||
|
attr.ihs)))
|
||||||
return NETDEV_TX_OK;
|
return NETDEV_TX_OK;
|
||||||
|
|
||||||
mlx5e_sq_xmit_mpwqe(sq, skb, &eseg, netdev_xmit_more());
|
mlx5e_sq_xmit_mpwqe(sq, skb, &eseg, netdev_xmit_more());
|
||||||
@ -731,7 +732,7 @@ netdev_tx_t mlx5e_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||||||
/* May update the WQE, but may not post other WQEs. */
|
/* May update the WQE, but may not post other WQEs. */
|
||||||
mlx5e_accel_tx_finish(sq, wqe, &accel,
|
mlx5e_accel_tx_finish(sq, wqe, &accel,
|
||||||
(struct mlx5_wqe_inline_seg *)(wqe->data + wqe_attr.ds_cnt_inl));
|
(struct mlx5_wqe_inline_seg *)(wqe->data + wqe_attr.ds_cnt_inl));
|
||||||
if (unlikely(!mlx5e_txwqe_build_eseg(priv, sq, skb, &accel, &wqe->eth)))
|
if (unlikely(!mlx5e_txwqe_build_eseg(priv, sq, skb, &accel, &wqe->eth, attr.ihs)))
|
||||||
return NETDEV_TX_OK;
|
return NETDEV_TX_OK;
|
||||||
|
|
||||||
mlx5e_sq_xmit_wqe(sq, skb, &attr, &wqe_attr, wqe, pi, netdev_xmit_more());
|
mlx5e_sq_xmit_wqe(sq, skb, &attr, &wqe_attr, wqe, pi, netdev_xmit_more());
|
||||||
|
@ -95,22 +95,21 @@ int esw_acl_egress_lgcy_setup(struct mlx5_eswitch *esw,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!IS_ERR_OR_NULL(vport->egress.acl))
|
if (!vport->egress.acl) {
|
||||||
return 0;
|
vport->egress.acl = esw_acl_table_create(esw, vport->vport,
|
||||||
|
MLX5_FLOW_NAMESPACE_ESW_EGRESS,
|
||||||
|
table_size);
|
||||||
|
if (IS_ERR(vport->egress.acl)) {
|
||||||
|
err = PTR_ERR(vport->egress.acl);
|
||||||
|
vport->egress.acl = NULL;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
vport->egress.acl = esw_acl_table_create(esw, vport->vport,
|
err = esw_acl_egress_lgcy_groups_create(esw, vport);
|
||||||
MLX5_FLOW_NAMESPACE_ESW_EGRESS,
|
if (err)
|
||||||
table_size);
|
goto out;
|
||||||
if (IS_ERR(vport->egress.acl)) {
|
|
||||||
err = PTR_ERR(vport->egress.acl);
|
|
||||||
vport->egress.acl = NULL;
|
|
||||||
goto out;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
err = esw_acl_egress_lgcy_groups_create(esw, vport);
|
|
||||||
if (err)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
esw_debug(esw->dev,
|
esw_debug(esw->dev,
|
||||||
"vport[%d] configure egress rules, vlan(%d) qos(%d)\n",
|
"vport[%d] configure egress rules, vlan(%d) qos(%d)\n",
|
||||||
vport->vport, vport->info.vlan, vport->info.qos);
|
vport->vport, vport->info.vlan, vport->info.qos);
|
||||||
|
@ -564,7 +564,9 @@ void mlx5_lag_add(struct mlx5_core_dev *dev, struct net_device *netdev)
|
|||||||
struct mlx5_core_dev *tmp_dev;
|
struct mlx5_core_dev *tmp_dev;
|
||||||
int i, err;
|
int i, err;
|
||||||
|
|
||||||
if (!MLX5_CAP_GEN(dev, vport_group_manager))
|
if (!MLX5_CAP_GEN(dev, vport_group_manager) ||
|
||||||
|
!MLX5_CAP_GEN(dev, lag_master) ||
|
||||||
|
MLX5_CAP_GEN(dev, num_lag_ports) != MLX5_MAX_PORTS)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
tmp_dev = mlx5_get_next_phys_dev(dev);
|
tmp_dev = mlx5_get_next_phys_dev(dev);
|
||||||
@ -582,12 +584,9 @@ void mlx5_lag_add(struct mlx5_core_dev *dev, struct net_device *netdev)
|
|||||||
if (mlx5_lag_dev_add_pf(ldev, dev, netdev) < 0)
|
if (mlx5_lag_dev_add_pf(ldev, dev, netdev) < 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (i = 0; i < MLX5_MAX_PORTS; i++) {
|
for (i = 0; i < MLX5_MAX_PORTS; i++)
|
||||||
tmp_dev = ldev->pf[i].dev;
|
if (!ldev->pf[i].dev)
|
||||||
if (!tmp_dev || !MLX5_CAP_GEN(tmp_dev, lag_master) ||
|
|
||||||
MLX5_CAP_GEN(tmp_dev, num_lag_ports) != MLX5_MAX_PORTS)
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
if (i >= MLX5_MAX_PORTS)
|
if (i >= MLX5_MAX_PORTS)
|
||||||
ldev->flags |= MLX5_LAG_FLAG_READY;
|
ldev->flags |= MLX5_LAG_FLAG_READY;
|
||||||
|
@ -1368,8 +1368,10 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *id)
|
|||||||
MLX5_COREDEV_VF : MLX5_COREDEV_PF;
|
MLX5_COREDEV_VF : MLX5_COREDEV_PF;
|
||||||
|
|
||||||
dev->priv.adev_idx = mlx5_adev_idx_alloc();
|
dev->priv.adev_idx = mlx5_adev_idx_alloc();
|
||||||
if (dev->priv.adev_idx < 0)
|
if (dev->priv.adev_idx < 0) {
|
||||||
return dev->priv.adev_idx;
|
err = dev->priv.adev_idx;
|
||||||
|
goto adev_init_err;
|
||||||
|
}
|
||||||
|
|
||||||
err = mlx5_mdev_init(dev, prof_sel);
|
err = mlx5_mdev_init(dev, prof_sel);
|
||||||
if (err)
|
if (err)
|
||||||
@ -1403,6 +1405,7 @@ pci_init_err:
|
|||||||
mlx5_mdev_uninit(dev);
|
mlx5_mdev_uninit(dev);
|
||||||
mdev_init_err:
|
mdev_init_err:
|
||||||
mlx5_adev_idx_free(dev->priv.adev_idx);
|
mlx5_adev_idx_free(dev->priv.adev_idx);
|
||||||
|
adev_init_err:
|
||||||
mlx5_devlink_free(devlink);
|
mlx5_devlink_free(devlink);
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
|
@ -116,7 +116,7 @@ free:
|
|||||||
static void mlx5_rdma_del_roce_addr(struct mlx5_core_dev *dev)
|
static void mlx5_rdma_del_roce_addr(struct mlx5_core_dev *dev)
|
||||||
{
|
{
|
||||||
mlx5_core_roce_gid_set(dev, 0, 0, 0,
|
mlx5_core_roce_gid_set(dev, 0, 0, 0,
|
||||||
NULL, NULL, false, 0, 0);
|
NULL, NULL, false, 0, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mlx5_rdma_make_default_gid(struct mlx5_core_dev *dev, union ib_gid *gid)
|
static void mlx5_rdma_make_default_gid(struct mlx5_core_dev *dev, union ib_gid *gid)
|
||||||
|
@ -506,10 +506,14 @@ static int mac_sonic_platform_probe(struct platform_device *pdev)
|
|||||||
|
|
||||||
err = register_netdev(dev);
|
err = register_netdev(dev);
|
||||||
if (err)
|
if (err)
|
||||||
goto out;
|
goto undo_probe;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
undo_probe:
|
||||||
|
dma_free_coherent(lp->device,
|
||||||
|
SIZEOF_SONIC_DESC * SONIC_BUS_SCALE(lp->dma_bitmode),
|
||||||
|
lp->descriptors, lp->descriptors_laddr);
|
||||||
out:
|
out:
|
||||||
free_netdev(dev);
|
free_netdev(dev);
|
||||||
|
|
||||||
@ -584,12 +588,16 @@ static int mac_sonic_nubus_probe(struct nubus_board *board)
|
|||||||
|
|
||||||
err = register_netdev(ndev);
|
err = register_netdev(ndev);
|
||||||
if (err)
|
if (err)
|
||||||
goto out;
|
goto undo_probe;
|
||||||
|
|
||||||
nubus_set_drvdata(board, ndev);
|
nubus_set_drvdata(board, ndev);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
undo_probe:
|
||||||
|
dma_free_coherent(lp->device,
|
||||||
|
SIZEOF_SONIC_DESC * SONIC_BUS_SCALE(lp->dma_bitmode),
|
||||||
|
lp->descriptors, lp->descriptors_laddr);
|
||||||
out:
|
out:
|
||||||
free_netdev(ndev);
|
free_netdev(ndev);
|
||||||
return err;
|
return err;
|
||||||
|
@ -229,11 +229,14 @@ int xtsonic_probe(struct platform_device *pdev)
|
|||||||
sonic_msg_init(dev);
|
sonic_msg_init(dev);
|
||||||
|
|
||||||
if ((err = register_netdev(dev)))
|
if ((err = register_netdev(dev)))
|
||||||
goto out1;
|
goto undo_probe1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
out1:
|
undo_probe1:
|
||||||
|
dma_free_coherent(lp->device,
|
||||||
|
SIZEOF_SONIC_DESC * SONIC_BUS_SCALE(lp->dma_bitmode),
|
||||||
|
lp->descriptors, lp->descriptors_laddr);
|
||||||
release_region(dev->base_addr, SONIC_MEM_SIZE);
|
release_region(dev->base_addr, SONIC_MEM_SIZE);
|
||||||
out:
|
out:
|
||||||
free_netdev(dev);
|
free_netdev(dev);
|
||||||
|
@ -78,6 +78,7 @@ config QED
|
|||||||
depends on PCI
|
depends on PCI
|
||||||
select ZLIB_INFLATE
|
select ZLIB_INFLATE
|
||||||
select CRC8
|
select CRC8
|
||||||
|
select CRC32
|
||||||
select NET_DEVLINK
|
select NET_DEVLINK
|
||||||
help
|
help
|
||||||
This enables the support for Marvell FastLinQ adapters family.
|
This enables the support for Marvell FastLinQ adapters family.
|
||||||
|
@ -64,6 +64,7 @@ struct emac_variant {
|
|||||||
* @variant: reference to the current board variant
|
* @variant: reference to the current board variant
|
||||||
* @regmap: regmap for using the syscon
|
* @regmap: regmap for using the syscon
|
||||||
* @internal_phy_powered: Does the internal PHY is enabled
|
* @internal_phy_powered: Does the internal PHY is enabled
|
||||||
|
* @use_internal_phy: Is the internal PHY selected for use
|
||||||
* @mux_handle: Internal pointer used by mdio-mux lib
|
* @mux_handle: Internal pointer used by mdio-mux lib
|
||||||
*/
|
*/
|
||||||
struct sunxi_priv_data {
|
struct sunxi_priv_data {
|
||||||
@ -74,6 +75,7 @@ struct sunxi_priv_data {
|
|||||||
const struct emac_variant *variant;
|
const struct emac_variant *variant;
|
||||||
struct regmap_field *regmap_field;
|
struct regmap_field *regmap_field;
|
||||||
bool internal_phy_powered;
|
bool internal_phy_powered;
|
||||||
|
bool use_internal_phy;
|
||||||
void *mux_handle;
|
void *mux_handle;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -539,8 +541,11 @@ static const struct stmmac_dma_ops sun8i_dwmac_dma_ops = {
|
|||||||
.dma_interrupt = sun8i_dwmac_dma_interrupt,
|
.dma_interrupt = sun8i_dwmac_dma_interrupt,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static int sun8i_dwmac_power_internal_phy(struct stmmac_priv *priv);
|
||||||
|
|
||||||
static int sun8i_dwmac_init(struct platform_device *pdev, void *priv)
|
static int sun8i_dwmac_init(struct platform_device *pdev, void *priv)
|
||||||
{
|
{
|
||||||
|
struct net_device *ndev = platform_get_drvdata(pdev);
|
||||||
struct sunxi_priv_data *gmac = priv;
|
struct sunxi_priv_data *gmac = priv;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@ -554,13 +559,25 @@ static int sun8i_dwmac_init(struct platform_device *pdev, void *priv)
|
|||||||
|
|
||||||
ret = clk_prepare_enable(gmac->tx_clk);
|
ret = clk_prepare_enable(gmac->tx_clk);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
if (gmac->regulator)
|
|
||||||
regulator_disable(gmac->regulator);
|
|
||||||
dev_err(&pdev->dev, "Could not enable AHB clock\n");
|
dev_err(&pdev->dev, "Could not enable AHB clock\n");
|
||||||
return ret;
|
goto err_disable_regulator;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gmac->use_internal_phy) {
|
||||||
|
ret = sun8i_dwmac_power_internal_phy(netdev_priv(ndev));
|
||||||
|
if (ret)
|
||||||
|
goto err_disable_clk;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
err_disable_clk:
|
||||||
|
clk_disable_unprepare(gmac->tx_clk);
|
||||||
|
err_disable_regulator:
|
||||||
|
if (gmac->regulator)
|
||||||
|
regulator_disable(gmac->regulator);
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sun8i_dwmac_core_init(struct mac_device_info *hw,
|
static void sun8i_dwmac_core_init(struct mac_device_info *hw,
|
||||||
@ -831,7 +848,6 @@ static int mdio_mux_syscon_switch_fn(int current_child, int desired_child,
|
|||||||
struct sunxi_priv_data *gmac = priv->plat->bsp_priv;
|
struct sunxi_priv_data *gmac = priv->plat->bsp_priv;
|
||||||
u32 reg, val;
|
u32 reg, val;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
bool need_power_ephy = false;
|
|
||||||
|
|
||||||
if (current_child ^ desired_child) {
|
if (current_child ^ desired_child) {
|
||||||
regmap_field_read(gmac->regmap_field, ®);
|
regmap_field_read(gmac->regmap_field, ®);
|
||||||
@ -839,13 +855,12 @@ static int mdio_mux_syscon_switch_fn(int current_child, int desired_child,
|
|||||||
case DWMAC_SUN8I_MDIO_MUX_INTERNAL_ID:
|
case DWMAC_SUN8I_MDIO_MUX_INTERNAL_ID:
|
||||||
dev_info(priv->device, "Switch mux to internal PHY");
|
dev_info(priv->device, "Switch mux to internal PHY");
|
||||||
val = (reg & ~H3_EPHY_MUX_MASK) | H3_EPHY_SELECT;
|
val = (reg & ~H3_EPHY_MUX_MASK) | H3_EPHY_SELECT;
|
||||||
|
gmac->use_internal_phy = true;
|
||||||
need_power_ephy = true;
|
|
||||||
break;
|
break;
|
||||||
case DWMAC_SUN8I_MDIO_MUX_EXTERNAL_ID:
|
case DWMAC_SUN8I_MDIO_MUX_EXTERNAL_ID:
|
||||||
dev_info(priv->device, "Switch mux to external PHY");
|
dev_info(priv->device, "Switch mux to external PHY");
|
||||||
val = (reg & ~H3_EPHY_MUX_MASK) | H3_EPHY_SHUTDOWN;
|
val = (reg & ~H3_EPHY_MUX_MASK) | H3_EPHY_SHUTDOWN;
|
||||||
need_power_ephy = false;
|
gmac->use_internal_phy = false;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
dev_err(priv->device, "Invalid child ID %x\n",
|
dev_err(priv->device, "Invalid child ID %x\n",
|
||||||
@ -853,7 +868,7 @@ static int mdio_mux_syscon_switch_fn(int current_child, int desired_child,
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
regmap_field_write(gmac->regmap_field, val);
|
regmap_field_write(gmac->regmap_field, val);
|
||||||
if (need_power_ephy) {
|
if (gmac->use_internal_phy) {
|
||||||
ret = sun8i_dwmac_power_internal_phy(priv);
|
ret = sun8i_dwmac_power_internal_phy(priv);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
@ -883,22 +898,23 @@ static int sun8i_dwmac_register_mdio_mux(struct stmmac_priv *priv)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sun8i_dwmac_set_syscon(struct stmmac_priv *priv)
|
static int sun8i_dwmac_set_syscon(struct device *dev,
|
||||||
|
struct plat_stmmacenet_data *plat)
|
||||||
{
|
{
|
||||||
struct sunxi_priv_data *gmac = priv->plat->bsp_priv;
|
struct sunxi_priv_data *gmac = plat->bsp_priv;
|
||||||
struct device_node *node = priv->device->of_node;
|
struct device_node *node = dev->of_node;
|
||||||
int ret;
|
int ret;
|
||||||
u32 reg, val;
|
u32 reg, val;
|
||||||
|
|
||||||
ret = regmap_field_read(gmac->regmap_field, &val);
|
ret = regmap_field_read(gmac->regmap_field, &val);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_err(priv->device, "Fail to read from regmap field.\n");
|
dev_err(dev, "Fail to read from regmap field.\n");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
reg = gmac->variant->default_syscon_value;
|
reg = gmac->variant->default_syscon_value;
|
||||||
if (reg != val)
|
if (reg != val)
|
||||||
dev_warn(priv->device,
|
dev_warn(dev,
|
||||||
"Current syscon value is not the default %x (expect %x)\n",
|
"Current syscon value is not the default %x (expect %x)\n",
|
||||||
val, reg);
|
val, reg);
|
||||||
|
|
||||||
@ -911,9 +927,9 @@ static int sun8i_dwmac_set_syscon(struct stmmac_priv *priv)
|
|||||||
/* Force EPHY xtal frequency to 24MHz. */
|
/* Force EPHY xtal frequency to 24MHz. */
|
||||||
reg |= H3_EPHY_CLK_SEL;
|
reg |= H3_EPHY_CLK_SEL;
|
||||||
|
|
||||||
ret = of_mdio_parse_addr(priv->device, priv->plat->phy_node);
|
ret = of_mdio_parse_addr(dev, plat->phy_node);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
dev_err(priv->device, "Could not parse MDIO addr\n");
|
dev_err(dev, "Could not parse MDIO addr\n");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
/* of_mdio_parse_addr returns a valid (0 ~ 31) PHY
|
/* of_mdio_parse_addr returns a valid (0 ~ 31) PHY
|
||||||
@ -929,17 +945,17 @@ static int sun8i_dwmac_set_syscon(struct stmmac_priv *priv)
|
|||||||
|
|
||||||
if (!of_property_read_u32(node, "allwinner,tx-delay-ps", &val)) {
|
if (!of_property_read_u32(node, "allwinner,tx-delay-ps", &val)) {
|
||||||
if (val % 100) {
|
if (val % 100) {
|
||||||
dev_err(priv->device, "tx-delay must be a multiple of 100\n");
|
dev_err(dev, "tx-delay must be a multiple of 100\n");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
val /= 100;
|
val /= 100;
|
||||||
dev_dbg(priv->device, "set tx-delay to %x\n", val);
|
dev_dbg(dev, "set tx-delay to %x\n", val);
|
||||||
if (val <= gmac->variant->tx_delay_max) {
|
if (val <= gmac->variant->tx_delay_max) {
|
||||||
reg &= ~(gmac->variant->tx_delay_max <<
|
reg &= ~(gmac->variant->tx_delay_max <<
|
||||||
SYSCON_ETXDC_SHIFT);
|
SYSCON_ETXDC_SHIFT);
|
||||||
reg |= (val << SYSCON_ETXDC_SHIFT);
|
reg |= (val << SYSCON_ETXDC_SHIFT);
|
||||||
} else {
|
} else {
|
||||||
dev_err(priv->device, "Invalid TX clock delay: %d\n",
|
dev_err(dev, "Invalid TX clock delay: %d\n",
|
||||||
val);
|
val);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
@ -947,17 +963,17 @@ static int sun8i_dwmac_set_syscon(struct stmmac_priv *priv)
|
|||||||
|
|
||||||
if (!of_property_read_u32(node, "allwinner,rx-delay-ps", &val)) {
|
if (!of_property_read_u32(node, "allwinner,rx-delay-ps", &val)) {
|
||||||
if (val % 100) {
|
if (val % 100) {
|
||||||
dev_err(priv->device, "rx-delay must be a multiple of 100\n");
|
dev_err(dev, "rx-delay must be a multiple of 100\n");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
val /= 100;
|
val /= 100;
|
||||||
dev_dbg(priv->device, "set rx-delay to %x\n", val);
|
dev_dbg(dev, "set rx-delay to %x\n", val);
|
||||||
if (val <= gmac->variant->rx_delay_max) {
|
if (val <= gmac->variant->rx_delay_max) {
|
||||||
reg &= ~(gmac->variant->rx_delay_max <<
|
reg &= ~(gmac->variant->rx_delay_max <<
|
||||||
SYSCON_ERXDC_SHIFT);
|
SYSCON_ERXDC_SHIFT);
|
||||||
reg |= (val << SYSCON_ERXDC_SHIFT);
|
reg |= (val << SYSCON_ERXDC_SHIFT);
|
||||||
} else {
|
} else {
|
||||||
dev_err(priv->device, "Invalid RX clock delay: %d\n",
|
dev_err(dev, "Invalid RX clock delay: %d\n",
|
||||||
val);
|
val);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
@ -968,7 +984,7 @@ static int sun8i_dwmac_set_syscon(struct stmmac_priv *priv)
|
|||||||
if (gmac->variant->support_rmii)
|
if (gmac->variant->support_rmii)
|
||||||
reg &= ~SYSCON_RMII_EN;
|
reg &= ~SYSCON_RMII_EN;
|
||||||
|
|
||||||
switch (priv->plat->interface) {
|
switch (plat->interface) {
|
||||||
case PHY_INTERFACE_MODE_MII:
|
case PHY_INTERFACE_MODE_MII:
|
||||||
/* default */
|
/* default */
|
||||||
break;
|
break;
|
||||||
@ -982,8 +998,8 @@ static int sun8i_dwmac_set_syscon(struct stmmac_priv *priv)
|
|||||||
reg |= SYSCON_RMII_EN | SYSCON_ETCS_EXT_GMII;
|
reg |= SYSCON_RMII_EN | SYSCON_ETCS_EXT_GMII;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
dev_err(priv->device, "Unsupported interface mode: %s",
|
dev_err(dev, "Unsupported interface mode: %s",
|
||||||
phy_modes(priv->plat->interface));
|
phy_modes(plat->interface));
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1004,17 +1020,10 @@ static void sun8i_dwmac_exit(struct platform_device *pdev, void *priv)
|
|||||||
struct sunxi_priv_data *gmac = priv;
|
struct sunxi_priv_data *gmac = priv;
|
||||||
|
|
||||||
if (gmac->variant->soc_has_internal_phy) {
|
if (gmac->variant->soc_has_internal_phy) {
|
||||||
/* sun8i_dwmac_exit could be called with mdiomux uninit */
|
|
||||||
if (gmac->mux_handle)
|
|
||||||
mdio_mux_uninit(gmac->mux_handle);
|
|
||||||
if (gmac->internal_phy_powered)
|
if (gmac->internal_phy_powered)
|
||||||
sun8i_dwmac_unpower_internal_phy(gmac);
|
sun8i_dwmac_unpower_internal_phy(gmac);
|
||||||
}
|
}
|
||||||
|
|
||||||
sun8i_dwmac_unset_syscon(gmac);
|
|
||||||
|
|
||||||
reset_control_put(gmac->rst_ephy);
|
|
||||||
|
|
||||||
clk_disable_unprepare(gmac->tx_clk);
|
clk_disable_unprepare(gmac->tx_clk);
|
||||||
|
|
||||||
if (gmac->regulator)
|
if (gmac->regulator)
|
||||||
@ -1049,16 +1058,11 @@ static struct mac_device_info *sun8i_dwmac_setup(void *ppriv)
|
|||||||
{
|
{
|
||||||
struct mac_device_info *mac;
|
struct mac_device_info *mac;
|
||||||
struct stmmac_priv *priv = ppriv;
|
struct stmmac_priv *priv = ppriv;
|
||||||
int ret;
|
|
||||||
|
|
||||||
mac = devm_kzalloc(priv->device, sizeof(*mac), GFP_KERNEL);
|
mac = devm_kzalloc(priv->device, sizeof(*mac), GFP_KERNEL);
|
||||||
if (!mac)
|
if (!mac)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
ret = sun8i_dwmac_set_syscon(priv);
|
|
||||||
if (ret)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
mac->pcsr = priv->ioaddr;
|
mac->pcsr = priv->ioaddr;
|
||||||
mac->mac = &sun8i_dwmac_ops;
|
mac->mac = &sun8i_dwmac_ops;
|
||||||
mac->dma = &sun8i_dwmac_dma_ops;
|
mac->dma = &sun8i_dwmac_dma_ops;
|
||||||
@ -1134,10 +1138,6 @@ static int sun8i_dwmac_probe(struct platform_device *pdev)
|
|||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
|
|
||||||
if (IS_ERR(plat_dat))
|
|
||||||
return PTR_ERR(plat_dat);
|
|
||||||
|
|
||||||
gmac = devm_kzalloc(dev, sizeof(*gmac), GFP_KERNEL);
|
gmac = devm_kzalloc(dev, sizeof(*gmac), GFP_KERNEL);
|
||||||
if (!gmac)
|
if (!gmac)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
@ -1201,11 +1201,15 @@ static int sun8i_dwmac_probe(struct platform_device *pdev)
|
|||||||
ret = of_get_phy_mode(dev->of_node, &interface);
|
ret = of_get_phy_mode(dev->of_node, &interface);
|
||||||
if (ret)
|
if (ret)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
plat_dat->interface = interface;
|
|
||||||
|
plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
|
||||||
|
if (IS_ERR(plat_dat))
|
||||||
|
return PTR_ERR(plat_dat);
|
||||||
|
|
||||||
/* platform data specifying hardware features and callbacks.
|
/* platform data specifying hardware features and callbacks.
|
||||||
* hardware features were copied from Allwinner drivers.
|
* hardware features were copied from Allwinner drivers.
|
||||||
*/
|
*/
|
||||||
|
plat_dat->interface = interface;
|
||||||
plat_dat->rx_coe = STMMAC_RX_COE_TYPE2;
|
plat_dat->rx_coe = STMMAC_RX_COE_TYPE2;
|
||||||
plat_dat->tx_coe = 1;
|
plat_dat->tx_coe = 1;
|
||||||
plat_dat->has_sun8i = true;
|
plat_dat->has_sun8i = true;
|
||||||
@ -1214,9 +1218,13 @@ static int sun8i_dwmac_probe(struct platform_device *pdev)
|
|||||||
plat_dat->exit = sun8i_dwmac_exit;
|
plat_dat->exit = sun8i_dwmac_exit;
|
||||||
plat_dat->setup = sun8i_dwmac_setup;
|
plat_dat->setup = sun8i_dwmac_setup;
|
||||||
|
|
||||||
|
ret = sun8i_dwmac_set_syscon(&pdev->dev, plat_dat);
|
||||||
|
if (ret)
|
||||||
|
goto dwmac_deconfig;
|
||||||
|
|
||||||
ret = sun8i_dwmac_init(pdev, plat_dat->bsp_priv);
|
ret = sun8i_dwmac_init(pdev, plat_dat->bsp_priv);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
goto dwmac_syscon;
|
||||||
|
|
||||||
ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
|
ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
|
||||||
if (ret)
|
if (ret)
|
||||||
@ -1230,7 +1238,7 @@ static int sun8i_dwmac_probe(struct platform_device *pdev)
|
|||||||
if (gmac->variant->soc_has_internal_phy) {
|
if (gmac->variant->soc_has_internal_phy) {
|
||||||
ret = get_ephy_nodes(priv);
|
ret = get_ephy_nodes(priv);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto dwmac_exit;
|
goto dwmac_remove;
|
||||||
ret = sun8i_dwmac_register_mdio_mux(priv);
|
ret = sun8i_dwmac_register_mdio_mux(priv);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_err(&pdev->dev, "Failed to register mux\n");
|
dev_err(&pdev->dev, "Failed to register mux\n");
|
||||||
@ -1239,15 +1247,42 @@ static int sun8i_dwmac_probe(struct platform_device *pdev)
|
|||||||
} else {
|
} else {
|
||||||
ret = sun8i_dwmac_reset(priv);
|
ret = sun8i_dwmac_reset(priv);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto dwmac_exit;
|
goto dwmac_remove;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
dwmac_mux:
|
dwmac_mux:
|
||||||
sun8i_dwmac_unset_syscon(gmac);
|
reset_control_put(gmac->rst_ephy);
|
||||||
|
clk_put(gmac->ephy_clk);
|
||||||
|
dwmac_remove:
|
||||||
|
stmmac_dvr_remove(&pdev->dev);
|
||||||
dwmac_exit:
|
dwmac_exit:
|
||||||
|
sun8i_dwmac_exit(pdev, gmac);
|
||||||
|
dwmac_syscon:
|
||||||
|
sun8i_dwmac_unset_syscon(gmac);
|
||||||
|
dwmac_deconfig:
|
||||||
|
stmmac_remove_config_dt(pdev, plat_dat);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int sun8i_dwmac_remove(struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
struct net_device *ndev = platform_get_drvdata(pdev);
|
||||||
|
struct stmmac_priv *priv = netdev_priv(ndev);
|
||||||
|
struct sunxi_priv_data *gmac = priv->plat->bsp_priv;
|
||||||
|
|
||||||
|
if (gmac->variant->soc_has_internal_phy) {
|
||||||
|
mdio_mux_uninit(gmac->mux_handle);
|
||||||
|
sun8i_dwmac_unpower_internal_phy(gmac);
|
||||||
|
reset_control_put(gmac->rst_ephy);
|
||||||
|
clk_put(gmac->ephy_clk);
|
||||||
|
}
|
||||||
|
|
||||||
stmmac_pltfr_remove(pdev);
|
stmmac_pltfr_remove(pdev);
|
||||||
return ret;
|
sun8i_dwmac_unset_syscon(gmac);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct of_device_id sun8i_dwmac_match[] = {
|
static const struct of_device_id sun8i_dwmac_match[] = {
|
||||||
@ -1269,7 +1304,7 @@ MODULE_DEVICE_TABLE(of, sun8i_dwmac_match);
|
|||||||
|
|
||||||
static struct platform_driver sun8i_dwmac_driver = {
|
static struct platform_driver sun8i_dwmac_driver = {
|
||||||
.probe = sun8i_dwmac_probe,
|
.probe = sun8i_dwmac_probe,
|
||||||
.remove = stmmac_pltfr_remove,
|
.remove = sun8i_dwmac_remove,
|
||||||
.driver = {
|
.driver = {
|
||||||
.name = "dwmac-sun8i",
|
.name = "dwmac-sun8i",
|
||||||
.pm = &stmmac_pltfr_pm_ops,
|
.pm = &stmmac_pltfr_pm_ops,
|
||||||
|
@ -1199,7 +1199,10 @@ cdc_ncm_fill_tx_frame(struct usbnet *dev, struct sk_buff *skb, __le32 sign)
|
|||||||
* accordingly. Otherwise, we should check here.
|
* accordingly. Otherwise, we should check here.
|
||||||
*/
|
*/
|
||||||
if (ctx->drvflags & CDC_NCM_FLAG_NDP_TO_END)
|
if (ctx->drvflags & CDC_NCM_FLAG_NDP_TO_END)
|
||||||
delayed_ndp_size = ALIGN(ctx->max_ndp_size, ctx->tx_ndp_modulus);
|
delayed_ndp_size = ctx->max_ndp_size +
|
||||||
|
max_t(u32,
|
||||||
|
ctx->tx_ndp_modulus,
|
||||||
|
ctx->tx_modulus + ctx->tx_remainder) - 1;
|
||||||
else
|
else
|
||||||
delayed_ndp_size = 0;
|
delayed_ndp_size = 0;
|
||||||
|
|
||||||
@ -1410,7 +1413,8 @@ cdc_ncm_fill_tx_frame(struct usbnet *dev, struct sk_buff *skb, __le32 sign)
|
|||||||
if (!(dev->driver_info->flags & FLAG_SEND_ZLP) &&
|
if (!(dev->driver_info->flags & FLAG_SEND_ZLP) &&
|
||||||
skb_out->len > ctx->min_tx_pkt) {
|
skb_out->len > ctx->min_tx_pkt) {
|
||||||
padding_count = ctx->tx_curr_size - skb_out->len;
|
padding_count = ctx->tx_curr_size - skb_out->len;
|
||||||
skb_put_zero(skb_out, padding_count);
|
if (!WARN_ON(padding_count > ctx->tx_curr_size))
|
||||||
|
skb_put_zero(skb_out, padding_count);
|
||||||
} else if (skb_out->len < ctx->tx_curr_size &&
|
} else if (skb_out->len < ctx->tx_curr_size &&
|
||||||
(skb_out->len % dev->maxpacket) == 0) {
|
(skb_out->len % dev->maxpacket) == 0) {
|
||||||
skb_put_u8(skb_out, 0); /* force short packet */
|
skb_put_u8(skb_out, 0); /* force short packet */
|
||||||
|
@ -282,6 +282,7 @@ config SLIC_DS26522
|
|||||||
tristate "Slic Maxim ds26522 card support"
|
tristate "Slic Maxim ds26522 card support"
|
||||||
depends on SPI
|
depends on SPI
|
||||||
depends on FSL_SOC || ARCH_MXC || ARCH_LAYERSCAPE || COMPILE_TEST
|
depends on FSL_SOC || ARCH_MXC || ARCH_LAYERSCAPE || COMPILE_TEST
|
||||||
|
select BITREVERSE
|
||||||
help
|
help
|
||||||
This module initializes and configures the slic maxim card
|
This module initializes and configures the slic maxim card
|
||||||
in T1 or E1 mode.
|
in T1 or E1 mode.
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
config WIL6210
|
config WIL6210
|
||||||
tristate "Wilocity 60g WiFi card wil6210 support"
|
tristate "Wilocity 60g WiFi card wil6210 support"
|
||||||
select WANT_DEV_COREDUMP
|
select WANT_DEV_COREDUMP
|
||||||
|
select CRC32
|
||||||
depends on CFG80211
|
depends on CFG80211
|
||||||
depends on PCI
|
depends on PCI
|
||||||
default n
|
default n
|
||||||
|
@ -64,6 +64,7 @@ config DP83640_PHY
|
|||||||
depends on NETWORK_PHY_TIMESTAMPING
|
depends on NETWORK_PHY_TIMESTAMPING
|
||||||
depends on PHYLIB
|
depends on PHYLIB
|
||||||
depends on PTP_1588_CLOCK
|
depends on PTP_1588_CLOCK
|
||||||
|
select CRC32
|
||||||
help
|
help
|
||||||
Supports the DP83640 PHYTER with IEEE 1588 features.
|
Supports the DP83640 PHYTER with IEEE 1588 features.
|
||||||
|
|
||||||
@ -78,6 +79,7 @@ config DP83640_PHY
|
|||||||
config PTP_1588_CLOCK_INES
|
config PTP_1588_CLOCK_INES
|
||||||
tristate "ZHAW InES PTP time stamping IP core"
|
tristate "ZHAW InES PTP time stamping IP core"
|
||||||
depends on NETWORK_PHY_TIMESTAMPING
|
depends on NETWORK_PHY_TIMESTAMPING
|
||||||
|
depends on HAS_IOMEM
|
||||||
depends on PHYLIB
|
depends on PHYLIB
|
||||||
depends on PTP_1588_CLOCK
|
depends on PTP_1588_CLOCK
|
||||||
help
|
help
|
||||||
|
@ -881,6 +881,7 @@ config REGULATOR_QCOM_RPM
|
|||||||
config REGULATOR_QCOM_RPMH
|
config REGULATOR_QCOM_RPMH
|
||||||
tristate "Qualcomm Technologies, Inc. RPMh regulator driver"
|
tristate "Qualcomm Technologies, Inc. RPMh regulator driver"
|
||||||
depends on QCOM_RPMH || (QCOM_RPMH=n && COMPILE_TEST)
|
depends on QCOM_RPMH || (QCOM_RPMH=n && COMPILE_TEST)
|
||||||
|
depends on QCOM_COMMAND_DB || (QCOM_COMMAND_DB=n && COMPILE_TEST)
|
||||||
help
|
help
|
||||||
This driver supports control of PMIC regulators via the RPMh hardware
|
This driver supports control of PMIC regulators via the RPMh hardware
|
||||||
block found on Qualcomm Technologies Inc. SoCs. RPMh regulator
|
block found on Qualcomm Technologies Inc. SoCs. RPMh regulator
|
||||||
|
@ -15,6 +15,36 @@
|
|||||||
#include <linux/regulator/of_regulator.h>
|
#include <linux/regulator/of_regulator.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
|
|
||||||
|
/* Typical regulator startup times as per data sheet in uS */
|
||||||
|
#define BD71847_BUCK1_STARTUP_TIME 144
|
||||||
|
#define BD71847_BUCK2_STARTUP_TIME 162
|
||||||
|
#define BD71847_BUCK3_STARTUP_TIME 162
|
||||||
|
#define BD71847_BUCK4_STARTUP_TIME 240
|
||||||
|
#define BD71847_BUCK5_STARTUP_TIME 270
|
||||||
|
#define BD71847_BUCK6_STARTUP_TIME 200
|
||||||
|
#define BD71847_LDO1_STARTUP_TIME 440
|
||||||
|
#define BD71847_LDO2_STARTUP_TIME 370
|
||||||
|
#define BD71847_LDO3_STARTUP_TIME 310
|
||||||
|
#define BD71847_LDO4_STARTUP_TIME 400
|
||||||
|
#define BD71847_LDO5_STARTUP_TIME 530
|
||||||
|
#define BD71847_LDO6_STARTUP_TIME 400
|
||||||
|
|
||||||
|
#define BD71837_BUCK1_STARTUP_TIME 160
|
||||||
|
#define BD71837_BUCK2_STARTUP_TIME 180
|
||||||
|
#define BD71837_BUCK3_STARTUP_TIME 180
|
||||||
|
#define BD71837_BUCK4_STARTUP_TIME 180
|
||||||
|
#define BD71837_BUCK5_STARTUP_TIME 160
|
||||||
|
#define BD71837_BUCK6_STARTUP_TIME 240
|
||||||
|
#define BD71837_BUCK7_STARTUP_TIME 220
|
||||||
|
#define BD71837_BUCK8_STARTUP_TIME 200
|
||||||
|
#define BD71837_LDO1_STARTUP_TIME 440
|
||||||
|
#define BD71837_LDO2_STARTUP_TIME 370
|
||||||
|
#define BD71837_LDO3_STARTUP_TIME 310
|
||||||
|
#define BD71837_LDO4_STARTUP_TIME 400
|
||||||
|
#define BD71837_LDO5_STARTUP_TIME 310
|
||||||
|
#define BD71837_LDO6_STARTUP_TIME 400
|
||||||
|
#define BD71837_LDO7_STARTUP_TIME 530
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* BD718(37/47/50) have two "enable control modes". ON/OFF can either be
|
* BD718(37/47/50) have two "enable control modes". ON/OFF can either be
|
||||||
* controlled by software - or by PMIC internal HW state machine. Whether
|
* controlled by software - or by PMIC internal HW state machine. Whether
|
||||||
@ -613,6 +643,7 @@ static struct bd718xx_regulator_data bd71847_regulators[] = {
|
|||||||
.vsel_mask = DVS_BUCK_RUN_MASK,
|
.vsel_mask = DVS_BUCK_RUN_MASK,
|
||||||
.enable_reg = BD718XX_REG_BUCK1_CTRL,
|
.enable_reg = BD718XX_REG_BUCK1_CTRL,
|
||||||
.enable_mask = BD718XX_BUCK_EN,
|
.enable_mask = BD718XX_BUCK_EN,
|
||||||
|
.enable_time = BD71847_BUCK1_STARTUP_TIME,
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.of_parse_cb = buck_set_hw_dvs_levels,
|
.of_parse_cb = buck_set_hw_dvs_levels,
|
||||||
},
|
},
|
||||||
@ -646,6 +677,7 @@ static struct bd718xx_regulator_data bd71847_regulators[] = {
|
|||||||
.vsel_mask = DVS_BUCK_RUN_MASK,
|
.vsel_mask = DVS_BUCK_RUN_MASK,
|
||||||
.enable_reg = BD718XX_REG_BUCK2_CTRL,
|
.enable_reg = BD718XX_REG_BUCK2_CTRL,
|
||||||
.enable_mask = BD718XX_BUCK_EN,
|
.enable_mask = BD718XX_BUCK_EN,
|
||||||
|
.enable_time = BD71847_BUCK2_STARTUP_TIME,
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.of_parse_cb = buck_set_hw_dvs_levels,
|
.of_parse_cb = buck_set_hw_dvs_levels,
|
||||||
},
|
},
|
||||||
@ -680,6 +712,7 @@ static struct bd718xx_regulator_data bd71847_regulators[] = {
|
|||||||
.linear_range_selectors = bd71847_buck3_volt_range_sel,
|
.linear_range_selectors = bd71847_buck3_volt_range_sel,
|
||||||
.enable_reg = BD718XX_REG_1ST_NODVS_BUCK_CTRL,
|
.enable_reg = BD718XX_REG_1ST_NODVS_BUCK_CTRL,
|
||||||
.enable_mask = BD718XX_BUCK_EN,
|
.enable_mask = BD718XX_BUCK_EN,
|
||||||
|
.enable_time = BD71847_BUCK3_STARTUP_TIME,
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
},
|
},
|
||||||
.init = {
|
.init = {
|
||||||
@ -706,6 +739,7 @@ static struct bd718xx_regulator_data bd71847_regulators[] = {
|
|||||||
.vsel_range_mask = BD71847_BUCK4_RANGE_MASK,
|
.vsel_range_mask = BD71847_BUCK4_RANGE_MASK,
|
||||||
.linear_range_selectors = bd71847_buck4_volt_range_sel,
|
.linear_range_selectors = bd71847_buck4_volt_range_sel,
|
||||||
.enable_mask = BD718XX_BUCK_EN,
|
.enable_mask = BD718XX_BUCK_EN,
|
||||||
|
.enable_time = BD71847_BUCK4_STARTUP_TIME,
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
},
|
},
|
||||||
.init = {
|
.init = {
|
||||||
@ -727,6 +761,7 @@ static struct bd718xx_regulator_data bd71847_regulators[] = {
|
|||||||
.vsel_mask = BD718XX_3RD_NODVS_BUCK_MASK,
|
.vsel_mask = BD718XX_3RD_NODVS_BUCK_MASK,
|
||||||
.enable_reg = BD718XX_REG_3RD_NODVS_BUCK_CTRL,
|
.enable_reg = BD718XX_REG_3RD_NODVS_BUCK_CTRL,
|
||||||
.enable_mask = BD718XX_BUCK_EN,
|
.enable_mask = BD718XX_BUCK_EN,
|
||||||
|
.enable_time = BD71847_BUCK5_STARTUP_TIME,
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
},
|
},
|
||||||
.init = {
|
.init = {
|
||||||
@ -750,6 +785,7 @@ static struct bd718xx_regulator_data bd71847_regulators[] = {
|
|||||||
.vsel_mask = BD718XX_4TH_NODVS_BUCK_MASK,
|
.vsel_mask = BD718XX_4TH_NODVS_BUCK_MASK,
|
||||||
.enable_reg = BD718XX_REG_4TH_NODVS_BUCK_CTRL,
|
.enable_reg = BD718XX_REG_4TH_NODVS_BUCK_CTRL,
|
||||||
.enable_mask = BD718XX_BUCK_EN,
|
.enable_mask = BD718XX_BUCK_EN,
|
||||||
|
.enable_time = BD71847_BUCK6_STARTUP_TIME,
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
},
|
},
|
||||||
.init = {
|
.init = {
|
||||||
@ -775,6 +811,7 @@ static struct bd718xx_regulator_data bd71847_regulators[] = {
|
|||||||
.linear_range_selectors = bd718xx_ldo1_volt_range_sel,
|
.linear_range_selectors = bd718xx_ldo1_volt_range_sel,
|
||||||
.enable_reg = BD718XX_REG_LDO1_VOLT,
|
.enable_reg = BD718XX_REG_LDO1_VOLT,
|
||||||
.enable_mask = BD718XX_LDO_EN,
|
.enable_mask = BD718XX_LDO_EN,
|
||||||
|
.enable_time = BD71847_LDO1_STARTUP_TIME,
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
},
|
},
|
||||||
.init = {
|
.init = {
|
||||||
@ -796,6 +833,7 @@ static struct bd718xx_regulator_data bd71847_regulators[] = {
|
|||||||
.n_voltages = ARRAY_SIZE(ldo_2_volts),
|
.n_voltages = ARRAY_SIZE(ldo_2_volts),
|
||||||
.enable_reg = BD718XX_REG_LDO2_VOLT,
|
.enable_reg = BD718XX_REG_LDO2_VOLT,
|
||||||
.enable_mask = BD718XX_LDO_EN,
|
.enable_mask = BD718XX_LDO_EN,
|
||||||
|
.enable_time = BD71847_LDO2_STARTUP_TIME,
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
},
|
},
|
||||||
.init = {
|
.init = {
|
||||||
@ -818,6 +856,7 @@ static struct bd718xx_regulator_data bd71847_regulators[] = {
|
|||||||
.vsel_mask = BD718XX_LDO3_MASK,
|
.vsel_mask = BD718XX_LDO3_MASK,
|
||||||
.enable_reg = BD718XX_REG_LDO3_VOLT,
|
.enable_reg = BD718XX_REG_LDO3_VOLT,
|
||||||
.enable_mask = BD718XX_LDO_EN,
|
.enable_mask = BD718XX_LDO_EN,
|
||||||
|
.enable_time = BD71847_LDO3_STARTUP_TIME,
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
},
|
},
|
||||||
.init = {
|
.init = {
|
||||||
@ -840,6 +879,7 @@ static struct bd718xx_regulator_data bd71847_regulators[] = {
|
|||||||
.vsel_mask = BD718XX_LDO4_MASK,
|
.vsel_mask = BD718XX_LDO4_MASK,
|
||||||
.enable_reg = BD718XX_REG_LDO4_VOLT,
|
.enable_reg = BD718XX_REG_LDO4_VOLT,
|
||||||
.enable_mask = BD718XX_LDO_EN,
|
.enable_mask = BD718XX_LDO_EN,
|
||||||
|
.enable_time = BD71847_LDO4_STARTUP_TIME,
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
},
|
},
|
||||||
.init = {
|
.init = {
|
||||||
@ -865,6 +905,7 @@ static struct bd718xx_regulator_data bd71847_regulators[] = {
|
|||||||
.linear_range_selectors = bd71847_ldo5_volt_range_sel,
|
.linear_range_selectors = bd71847_ldo5_volt_range_sel,
|
||||||
.enable_reg = BD718XX_REG_LDO5_VOLT,
|
.enable_reg = BD718XX_REG_LDO5_VOLT,
|
||||||
.enable_mask = BD718XX_LDO_EN,
|
.enable_mask = BD718XX_LDO_EN,
|
||||||
|
.enable_time = BD71847_LDO5_STARTUP_TIME,
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
},
|
},
|
||||||
.init = {
|
.init = {
|
||||||
@ -889,6 +930,7 @@ static struct bd718xx_regulator_data bd71847_regulators[] = {
|
|||||||
.vsel_mask = BD718XX_LDO6_MASK,
|
.vsel_mask = BD718XX_LDO6_MASK,
|
||||||
.enable_reg = BD718XX_REG_LDO6_VOLT,
|
.enable_reg = BD718XX_REG_LDO6_VOLT,
|
||||||
.enable_mask = BD718XX_LDO_EN,
|
.enable_mask = BD718XX_LDO_EN,
|
||||||
|
.enable_time = BD71847_LDO6_STARTUP_TIME,
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
},
|
},
|
||||||
.init = {
|
.init = {
|
||||||
@ -942,6 +984,7 @@ static struct bd718xx_regulator_data bd71837_regulators[] = {
|
|||||||
.vsel_mask = DVS_BUCK_RUN_MASK,
|
.vsel_mask = DVS_BUCK_RUN_MASK,
|
||||||
.enable_reg = BD718XX_REG_BUCK1_CTRL,
|
.enable_reg = BD718XX_REG_BUCK1_CTRL,
|
||||||
.enable_mask = BD718XX_BUCK_EN,
|
.enable_mask = BD718XX_BUCK_EN,
|
||||||
|
.enable_time = BD71837_BUCK1_STARTUP_TIME,
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.of_parse_cb = buck_set_hw_dvs_levels,
|
.of_parse_cb = buck_set_hw_dvs_levels,
|
||||||
},
|
},
|
||||||
@ -975,6 +1018,7 @@ static struct bd718xx_regulator_data bd71837_regulators[] = {
|
|||||||
.vsel_mask = DVS_BUCK_RUN_MASK,
|
.vsel_mask = DVS_BUCK_RUN_MASK,
|
||||||
.enable_reg = BD718XX_REG_BUCK2_CTRL,
|
.enable_reg = BD718XX_REG_BUCK2_CTRL,
|
||||||
.enable_mask = BD718XX_BUCK_EN,
|
.enable_mask = BD718XX_BUCK_EN,
|
||||||
|
.enable_time = BD71837_BUCK2_STARTUP_TIME,
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.of_parse_cb = buck_set_hw_dvs_levels,
|
.of_parse_cb = buck_set_hw_dvs_levels,
|
||||||
},
|
},
|
||||||
@ -1005,6 +1049,7 @@ static struct bd718xx_regulator_data bd71837_regulators[] = {
|
|||||||
.vsel_mask = DVS_BUCK_RUN_MASK,
|
.vsel_mask = DVS_BUCK_RUN_MASK,
|
||||||
.enable_reg = BD71837_REG_BUCK3_CTRL,
|
.enable_reg = BD71837_REG_BUCK3_CTRL,
|
||||||
.enable_mask = BD718XX_BUCK_EN,
|
.enable_mask = BD718XX_BUCK_EN,
|
||||||
|
.enable_time = BD71837_BUCK3_STARTUP_TIME,
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.of_parse_cb = buck_set_hw_dvs_levels,
|
.of_parse_cb = buck_set_hw_dvs_levels,
|
||||||
},
|
},
|
||||||
@ -1033,6 +1078,7 @@ static struct bd718xx_regulator_data bd71837_regulators[] = {
|
|||||||
.vsel_mask = DVS_BUCK_RUN_MASK,
|
.vsel_mask = DVS_BUCK_RUN_MASK,
|
||||||
.enable_reg = BD71837_REG_BUCK4_CTRL,
|
.enable_reg = BD71837_REG_BUCK4_CTRL,
|
||||||
.enable_mask = BD718XX_BUCK_EN,
|
.enable_mask = BD718XX_BUCK_EN,
|
||||||
|
.enable_time = BD71837_BUCK4_STARTUP_TIME,
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.of_parse_cb = buck_set_hw_dvs_levels,
|
.of_parse_cb = buck_set_hw_dvs_levels,
|
||||||
},
|
},
|
||||||
@ -1065,6 +1111,7 @@ static struct bd718xx_regulator_data bd71837_regulators[] = {
|
|||||||
.linear_range_selectors = bd71837_buck5_volt_range_sel,
|
.linear_range_selectors = bd71837_buck5_volt_range_sel,
|
||||||
.enable_reg = BD718XX_REG_1ST_NODVS_BUCK_CTRL,
|
.enable_reg = BD718XX_REG_1ST_NODVS_BUCK_CTRL,
|
||||||
.enable_mask = BD718XX_BUCK_EN,
|
.enable_mask = BD718XX_BUCK_EN,
|
||||||
|
.enable_time = BD71837_BUCK5_STARTUP_TIME,
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
},
|
},
|
||||||
.init = {
|
.init = {
|
||||||
@ -1088,6 +1135,7 @@ static struct bd718xx_regulator_data bd71837_regulators[] = {
|
|||||||
.vsel_mask = BD71837_BUCK6_MASK,
|
.vsel_mask = BD71837_BUCK6_MASK,
|
||||||
.enable_reg = BD718XX_REG_2ND_NODVS_BUCK_CTRL,
|
.enable_reg = BD718XX_REG_2ND_NODVS_BUCK_CTRL,
|
||||||
.enable_mask = BD718XX_BUCK_EN,
|
.enable_mask = BD718XX_BUCK_EN,
|
||||||
|
.enable_time = BD71837_BUCK6_STARTUP_TIME,
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
},
|
},
|
||||||
.init = {
|
.init = {
|
||||||
@ -1109,6 +1157,7 @@ static struct bd718xx_regulator_data bd71837_regulators[] = {
|
|||||||
.vsel_mask = BD718XX_3RD_NODVS_BUCK_MASK,
|
.vsel_mask = BD718XX_3RD_NODVS_BUCK_MASK,
|
||||||
.enable_reg = BD718XX_REG_3RD_NODVS_BUCK_CTRL,
|
.enable_reg = BD718XX_REG_3RD_NODVS_BUCK_CTRL,
|
||||||
.enable_mask = BD718XX_BUCK_EN,
|
.enable_mask = BD718XX_BUCK_EN,
|
||||||
|
.enable_time = BD71837_BUCK7_STARTUP_TIME,
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
},
|
},
|
||||||
.init = {
|
.init = {
|
||||||
@ -1132,6 +1181,7 @@ static struct bd718xx_regulator_data bd71837_regulators[] = {
|
|||||||
.vsel_mask = BD718XX_4TH_NODVS_BUCK_MASK,
|
.vsel_mask = BD718XX_4TH_NODVS_BUCK_MASK,
|
||||||
.enable_reg = BD718XX_REG_4TH_NODVS_BUCK_CTRL,
|
.enable_reg = BD718XX_REG_4TH_NODVS_BUCK_CTRL,
|
||||||
.enable_mask = BD718XX_BUCK_EN,
|
.enable_mask = BD718XX_BUCK_EN,
|
||||||
|
.enable_time = BD71837_BUCK8_STARTUP_TIME,
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
},
|
},
|
||||||
.init = {
|
.init = {
|
||||||
@ -1157,6 +1207,7 @@ static struct bd718xx_regulator_data bd71837_regulators[] = {
|
|||||||
.linear_range_selectors = bd718xx_ldo1_volt_range_sel,
|
.linear_range_selectors = bd718xx_ldo1_volt_range_sel,
|
||||||
.enable_reg = BD718XX_REG_LDO1_VOLT,
|
.enable_reg = BD718XX_REG_LDO1_VOLT,
|
||||||
.enable_mask = BD718XX_LDO_EN,
|
.enable_mask = BD718XX_LDO_EN,
|
||||||
|
.enable_time = BD71837_LDO1_STARTUP_TIME,
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
},
|
},
|
||||||
.init = {
|
.init = {
|
||||||
@ -1178,6 +1229,7 @@ static struct bd718xx_regulator_data bd71837_regulators[] = {
|
|||||||
.n_voltages = ARRAY_SIZE(ldo_2_volts),
|
.n_voltages = ARRAY_SIZE(ldo_2_volts),
|
||||||
.enable_reg = BD718XX_REG_LDO2_VOLT,
|
.enable_reg = BD718XX_REG_LDO2_VOLT,
|
||||||
.enable_mask = BD718XX_LDO_EN,
|
.enable_mask = BD718XX_LDO_EN,
|
||||||
|
.enable_time = BD71837_LDO2_STARTUP_TIME,
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
},
|
},
|
||||||
.init = {
|
.init = {
|
||||||
@ -1200,6 +1252,7 @@ static struct bd718xx_regulator_data bd71837_regulators[] = {
|
|||||||
.vsel_mask = BD718XX_LDO3_MASK,
|
.vsel_mask = BD718XX_LDO3_MASK,
|
||||||
.enable_reg = BD718XX_REG_LDO3_VOLT,
|
.enable_reg = BD718XX_REG_LDO3_VOLT,
|
||||||
.enable_mask = BD718XX_LDO_EN,
|
.enable_mask = BD718XX_LDO_EN,
|
||||||
|
.enable_time = BD71837_LDO3_STARTUP_TIME,
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
},
|
},
|
||||||
.init = {
|
.init = {
|
||||||
@ -1222,6 +1275,7 @@ static struct bd718xx_regulator_data bd71837_regulators[] = {
|
|||||||
.vsel_mask = BD718XX_LDO4_MASK,
|
.vsel_mask = BD718XX_LDO4_MASK,
|
||||||
.enable_reg = BD718XX_REG_LDO4_VOLT,
|
.enable_reg = BD718XX_REG_LDO4_VOLT,
|
||||||
.enable_mask = BD718XX_LDO_EN,
|
.enable_mask = BD718XX_LDO_EN,
|
||||||
|
.enable_time = BD71837_LDO4_STARTUP_TIME,
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
},
|
},
|
||||||
.init = {
|
.init = {
|
||||||
@ -1246,6 +1300,7 @@ static struct bd718xx_regulator_data bd71837_regulators[] = {
|
|||||||
.vsel_mask = BD71837_LDO5_MASK,
|
.vsel_mask = BD71837_LDO5_MASK,
|
||||||
.enable_reg = BD718XX_REG_LDO5_VOLT,
|
.enable_reg = BD718XX_REG_LDO5_VOLT,
|
||||||
.enable_mask = BD718XX_LDO_EN,
|
.enable_mask = BD718XX_LDO_EN,
|
||||||
|
.enable_time = BD71837_LDO5_STARTUP_TIME,
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
},
|
},
|
||||||
.init = {
|
.init = {
|
||||||
@ -1272,6 +1327,7 @@ static struct bd718xx_regulator_data bd71837_regulators[] = {
|
|||||||
.vsel_mask = BD718XX_LDO6_MASK,
|
.vsel_mask = BD718XX_LDO6_MASK,
|
||||||
.enable_reg = BD718XX_REG_LDO6_VOLT,
|
.enable_reg = BD718XX_REG_LDO6_VOLT,
|
||||||
.enable_mask = BD718XX_LDO_EN,
|
.enable_mask = BD718XX_LDO_EN,
|
||||||
|
.enable_time = BD71837_LDO6_STARTUP_TIME,
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
},
|
},
|
||||||
.init = {
|
.init = {
|
||||||
@ -1296,6 +1352,7 @@ static struct bd718xx_regulator_data bd71837_regulators[] = {
|
|||||||
.vsel_mask = BD71837_LDO7_MASK,
|
.vsel_mask = BD71837_LDO7_MASK,
|
||||||
.enable_reg = BD71837_REG_LDO7_VOLT,
|
.enable_reg = BD71837_REG_LDO7_VOLT,
|
||||||
.enable_mask = BD718XX_LDO_EN,
|
.enable_mask = BD718XX_LDO_EN,
|
||||||
|
.enable_time = BD71837_LDO7_STARTUP_TIME,
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
},
|
},
|
||||||
.init = {
|
.init = {
|
||||||
|
@ -469,13 +469,17 @@ static int pf8x00_i2c_probe(struct i2c_client *client)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static const struct of_device_id pf8x00_dt_ids[] = {
|
static const struct of_device_id pf8x00_dt_ids[] = {
|
||||||
{ .compatible = "nxp,pf8x00",},
|
{ .compatible = "nxp,pf8100",},
|
||||||
|
{ .compatible = "nxp,pf8121a",},
|
||||||
|
{ .compatible = "nxp,pf8200",},
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
MODULE_DEVICE_TABLE(of, pf8x00_dt_ids);
|
MODULE_DEVICE_TABLE(of, pf8x00_dt_ids);
|
||||||
|
|
||||||
static const struct i2c_device_id pf8x00_i2c_id[] = {
|
static const struct i2c_device_id pf8x00_i2c_id[] = {
|
||||||
{ "pf8x00", 0 },
|
{ "pf8100", 0 },
|
||||||
|
{ "pf8121a", 0 },
|
||||||
|
{ "pf8200", 0 },
|
||||||
{},
|
{},
|
||||||
};
|
};
|
||||||
MODULE_DEVICE_TABLE(i2c, pf8x00_i2c_id);
|
MODULE_DEVICE_TABLE(i2c, pf8x00_i2c_id);
|
||||||
|
@ -726,7 +726,7 @@ static const struct rpmh_vreg_hw_data pmic5_ftsmps510 = {
|
|||||||
static const struct rpmh_vreg_hw_data pmic5_hfsmps515 = {
|
static const struct rpmh_vreg_hw_data pmic5_hfsmps515 = {
|
||||||
.regulator_type = VRM,
|
.regulator_type = VRM,
|
||||||
.ops = &rpmh_regulator_vrm_ops,
|
.ops = &rpmh_regulator_vrm_ops,
|
||||||
.voltage_range = REGULATOR_LINEAR_RANGE(2800000, 0, 4, 1600),
|
.voltage_range = REGULATOR_LINEAR_RANGE(2800000, 0, 4, 16000),
|
||||||
.n_voltages = 5,
|
.n_voltages = 5,
|
||||||
.pmic_mode_map = pmic_mode_map_pmic5_smps,
|
.pmic_mode_map = pmic_mode_map_pmic5_smps,
|
||||||
.of_map_mode = rpmh_regulator_pmic4_smps_of_map_mode,
|
.of_map_mode = rpmh_regulator_pmic4_smps_of_map_mode,
|
||||||
|
@ -1079,7 +1079,8 @@ struct qeth_card *qeth_get_card_by_busid(char *bus_id);
|
|||||||
void qeth_set_allowed_threads(struct qeth_card *card, unsigned long threads,
|
void qeth_set_allowed_threads(struct qeth_card *card, unsigned long threads,
|
||||||
int clear_start_mask);
|
int clear_start_mask);
|
||||||
int qeth_threads_running(struct qeth_card *, unsigned long);
|
int qeth_threads_running(struct qeth_card *, unsigned long);
|
||||||
int qeth_set_offline(struct qeth_card *card, bool resetting);
|
int qeth_set_offline(struct qeth_card *card, const struct qeth_discipline *disc,
|
||||||
|
bool resetting);
|
||||||
|
|
||||||
int qeth_send_ipa_cmd(struct qeth_card *, struct qeth_cmd_buffer *,
|
int qeth_send_ipa_cmd(struct qeth_card *, struct qeth_cmd_buffer *,
|
||||||
int (*reply_cb)
|
int (*reply_cb)
|
||||||
|
@ -5507,12 +5507,12 @@ out:
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int qeth_set_online(struct qeth_card *card)
|
static int qeth_set_online(struct qeth_card *card,
|
||||||
|
const struct qeth_discipline *disc)
|
||||||
{
|
{
|
||||||
bool carrier_ok;
|
bool carrier_ok;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
mutex_lock(&card->discipline_mutex);
|
|
||||||
mutex_lock(&card->conf_mutex);
|
mutex_lock(&card->conf_mutex);
|
||||||
QETH_CARD_TEXT(card, 2, "setonlin");
|
QETH_CARD_TEXT(card, 2, "setonlin");
|
||||||
|
|
||||||
@ -5529,7 +5529,7 @@ static int qeth_set_online(struct qeth_card *card)
|
|||||||
/* no need for locking / error handling at this early stage: */
|
/* no need for locking / error handling at this early stage: */
|
||||||
qeth_set_real_num_tx_queues(card, qeth_tx_actual_queues(card));
|
qeth_set_real_num_tx_queues(card, qeth_tx_actual_queues(card));
|
||||||
|
|
||||||
rc = card->discipline->set_online(card, carrier_ok);
|
rc = disc->set_online(card, carrier_ok);
|
||||||
if (rc)
|
if (rc)
|
||||||
goto err_online;
|
goto err_online;
|
||||||
|
|
||||||
@ -5537,7 +5537,6 @@ static int qeth_set_online(struct qeth_card *card)
|
|||||||
kobject_uevent(&card->gdev->dev.kobj, KOBJ_CHANGE);
|
kobject_uevent(&card->gdev->dev.kobj, KOBJ_CHANGE);
|
||||||
|
|
||||||
mutex_unlock(&card->conf_mutex);
|
mutex_unlock(&card->conf_mutex);
|
||||||
mutex_unlock(&card->discipline_mutex);
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err_online:
|
err_online:
|
||||||
@ -5552,15 +5551,14 @@ err_hardsetup:
|
|||||||
qdio_free(CARD_DDEV(card));
|
qdio_free(CARD_DDEV(card));
|
||||||
|
|
||||||
mutex_unlock(&card->conf_mutex);
|
mutex_unlock(&card->conf_mutex);
|
||||||
mutex_unlock(&card->discipline_mutex);
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
int qeth_set_offline(struct qeth_card *card, bool resetting)
|
int qeth_set_offline(struct qeth_card *card, const struct qeth_discipline *disc,
|
||||||
|
bool resetting)
|
||||||
{
|
{
|
||||||
int rc, rc2, rc3;
|
int rc, rc2, rc3;
|
||||||
|
|
||||||
mutex_lock(&card->discipline_mutex);
|
|
||||||
mutex_lock(&card->conf_mutex);
|
mutex_lock(&card->conf_mutex);
|
||||||
QETH_CARD_TEXT(card, 3, "setoffl");
|
QETH_CARD_TEXT(card, 3, "setoffl");
|
||||||
|
|
||||||
@ -5581,7 +5579,7 @@ int qeth_set_offline(struct qeth_card *card, bool resetting)
|
|||||||
|
|
||||||
cancel_work_sync(&card->rx_mode_work);
|
cancel_work_sync(&card->rx_mode_work);
|
||||||
|
|
||||||
card->discipline->set_offline(card);
|
disc->set_offline(card);
|
||||||
|
|
||||||
qeth_qdio_clear_card(card, 0);
|
qeth_qdio_clear_card(card, 0);
|
||||||
qeth_drain_output_queues(card);
|
qeth_drain_output_queues(card);
|
||||||
@ -5602,16 +5600,19 @@ int qeth_set_offline(struct qeth_card *card, bool resetting)
|
|||||||
kobject_uevent(&card->gdev->dev.kobj, KOBJ_CHANGE);
|
kobject_uevent(&card->gdev->dev.kobj, KOBJ_CHANGE);
|
||||||
|
|
||||||
mutex_unlock(&card->conf_mutex);
|
mutex_unlock(&card->conf_mutex);
|
||||||
mutex_unlock(&card->discipline_mutex);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(qeth_set_offline);
|
EXPORT_SYMBOL_GPL(qeth_set_offline);
|
||||||
|
|
||||||
static int qeth_do_reset(void *data)
|
static int qeth_do_reset(void *data)
|
||||||
{
|
{
|
||||||
|
const struct qeth_discipline *disc;
|
||||||
struct qeth_card *card = data;
|
struct qeth_card *card = data;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
|
/* Lock-free, other users will block until we are done. */
|
||||||
|
disc = card->discipline;
|
||||||
|
|
||||||
QETH_CARD_TEXT(card, 2, "recover1");
|
QETH_CARD_TEXT(card, 2, "recover1");
|
||||||
if (!qeth_do_run_thread(card, QETH_RECOVER_THREAD))
|
if (!qeth_do_run_thread(card, QETH_RECOVER_THREAD))
|
||||||
return 0;
|
return 0;
|
||||||
@ -5619,8 +5620,8 @@ static int qeth_do_reset(void *data)
|
|||||||
dev_warn(&card->gdev->dev,
|
dev_warn(&card->gdev->dev,
|
||||||
"A recovery process has been started for the device\n");
|
"A recovery process has been started for the device\n");
|
||||||
|
|
||||||
qeth_set_offline(card, true);
|
qeth_set_offline(card, disc, true);
|
||||||
rc = qeth_set_online(card);
|
rc = qeth_set_online(card, disc);
|
||||||
if (!rc) {
|
if (!rc) {
|
||||||
dev_info(&card->gdev->dev,
|
dev_info(&card->gdev->dev,
|
||||||
"Device successfully recovered!\n");
|
"Device successfully recovered!\n");
|
||||||
@ -6584,6 +6585,7 @@ static int qeth_core_probe_device(struct ccwgroup_device *gdev)
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
card->info.layer_enforced = true;
|
card->info.layer_enforced = true;
|
||||||
|
/* It's so early that we don't need the discipline_mutex yet. */
|
||||||
rc = qeth_core_load_discipline(card, enforced_disc);
|
rc = qeth_core_load_discipline(card, enforced_disc);
|
||||||
if (rc)
|
if (rc)
|
||||||
goto err_load;
|
goto err_load;
|
||||||
@ -6616,10 +6618,12 @@ static void qeth_core_remove_device(struct ccwgroup_device *gdev)
|
|||||||
|
|
||||||
QETH_CARD_TEXT(card, 2, "removedv");
|
QETH_CARD_TEXT(card, 2, "removedv");
|
||||||
|
|
||||||
|
mutex_lock(&card->discipline_mutex);
|
||||||
if (card->discipline) {
|
if (card->discipline) {
|
||||||
card->discipline->remove(gdev);
|
card->discipline->remove(gdev);
|
||||||
qeth_core_free_discipline(card);
|
qeth_core_free_discipline(card);
|
||||||
}
|
}
|
||||||
|
mutex_unlock(&card->discipline_mutex);
|
||||||
|
|
||||||
qeth_free_qdio_queues(card);
|
qeth_free_qdio_queues(card);
|
||||||
|
|
||||||
@ -6634,6 +6638,7 @@ static int qeth_core_set_online(struct ccwgroup_device *gdev)
|
|||||||
int rc = 0;
|
int rc = 0;
|
||||||
enum qeth_discipline_id def_discipline;
|
enum qeth_discipline_id def_discipline;
|
||||||
|
|
||||||
|
mutex_lock(&card->discipline_mutex);
|
||||||
if (!card->discipline) {
|
if (!card->discipline) {
|
||||||
def_discipline = IS_IQD(card) ? QETH_DISCIPLINE_LAYER3 :
|
def_discipline = IS_IQD(card) ? QETH_DISCIPLINE_LAYER3 :
|
||||||
QETH_DISCIPLINE_LAYER2;
|
QETH_DISCIPLINE_LAYER2;
|
||||||
@ -6647,16 +6652,23 @@ static int qeth_core_set_online(struct ccwgroup_device *gdev)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = qeth_set_online(card);
|
rc = qeth_set_online(card, card->discipline);
|
||||||
|
|
||||||
err:
|
err:
|
||||||
|
mutex_unlock(&card->discipline_mutex);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int qeth_core_set_offline(struct ccwgroup_device *gdev)
|
static int qeth_core_set_offline(struct ccwgroup_device *gdev)
|
||||||
{
|
{
|
||||||
struct qeth_card *card = dev_get_drvdata(&gdev->dev);
|
struct qeth_card *card = dev_get_drvdata(&gdev->dev);
|
||||||
|
int rc;
|
||||||
|
|
||||||
return qeth_set_offline(card, false);
|
mutex_lock(&card->discipline_mutex);
|
||||||
|
rc = qeth_set_offline(card, card->discipline, false);
|
||||||
|
mutex_unlock(&card->discipline_mutex);
|
||||||
|
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void qeth_core_shutdown(struct ccwgroup_device *gdev)
|
static void qeth_core_shutdown(struct ccwgroup_device *gdev)
|
||||||
|
@ -2208,7 +2208,7 @@ static void qeth_l2_remove_device(struct ccwgroup_device *gdev)
|
|||||||
wait_event(card->wait_q, qeth_threads_running(card, 0xffffffff) == 0);
|
wait_event(card->wait_q, qeth_threads_running(card, 0xffffffff) == 0);
|
||||||
|
|
||||||
if (gdev->state == CCWGROUP_ONLINE)
|
if (gdev->state == CCWGROUP_ONLINE)
|
||||||
qeth_set_offline(card, false);
|
qeth_set_offline(card, card->discipline, false);
|
||||||
|
|
||||||
cancel_work_sync(&card->close_dev_work);
|
cancel_work_sync(&card->close_dev_work);
|
||||||
if (card->dev->reg_state == NETREG_REGISTERED)
|
if (card->dev->reg_state == NETREG_REGISTERED)
|
||||||
|
@ -1813,7 +1813,7 @@ static netdev_features_t qeth_l3_osa_features_check(struct sk_buff *skb,
|
|||||||
struct net_device *dev,
|
struct net_device *dev,
|
||||||
netdev_features_t features)
|
netdev_features_t features)
|
||||||
{
|
{
|
||||||
if (qeth_get_ip_version(skb) != 4)
|
if (vlan_get_protocol(skb) != htons(ETH_P_IP))
|
||||||
features &= ~NETIF_F_HW_VLAN_CTAG_TX;
|
features &= ~NETIF_F_HW_VLAN_CTAG_TX;
|
||||||
return qeth_features_check(skb, dev, features);
|
return qeth_features_check(skb, dev, features);
|
||||||
}
|
}
|
||||||
@ -1971,7 +1971,7 @@ static void qeth_l3_remove_device(struct ccwgroup_device *cgdev)
|
|||||||
wait_event(card->wait_q, qeth_threads_running(card, 0xffffffff) == 0);
|
wait_event(card->wait_q, qeth_threads_running(card, 0xffffffff) == 0);
|
||||||
|
|
||||||
if (cgdev->state == CCWGROUP_ONLINE)
|
if (cgdev->state == CCWGROUP_ONLINE)
|
||||||
qeth_set_offline(card, false);
|
qeth_set_offline(card, card->discipline, false);
|
||||||
|
|
||||||
cancel_work_sync(&card->close_dev_work);
|
cancel_work_sync(&card->close_dev_work);
|
||||||
if (card->dev->reg_state == NETREG_REGISTERED)
|
if (card->dev->reg_state == NETREG_REGISTERED)
|
||||||
|
@ -189,24 +189,26 @@ static int altera_spi_txrx(struct spi_master *master,
|
|||||||
|
|
||||||
/* send the first byte */
|
/* send the first byte */
|
||||||
altera_spi_tx_word(hw);
|
altera_spi_tx_word(hw);
|
||||||
} else {
|
|
||||||
while (hw->count < hw->len) {
|
|
||||||
altera_spi_tx_word(hw);
|
|
||||||
|
|
||||||
for (;;) {
|
return 1;
|
||||||
altr_spi_readl(hw, ALTERA_SPI_STATUS, &val);
|
|
||||||
if (val & ALTERA_SPI_STATUS_RRDY_MSK)
|
|
||||||
break;
|
|
||||||
|
|
||||||
cpu_relax();
|
|
||||||
}
|
|
||||||
|
|
||||||
altera_spi_rx_word(hw);
|
|
||||||
}
|
|
||||||
spi_finalize_current_transfer(master);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return t->len;
|
while (hw->count < hw->len) {
|
||||||
|
altera_spi_tx_word(hw);
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
altr_spi_readl(hw, ALTERA_SPI_STATUS, &val);
|
||||||
|
if (val & ALTERA_SPI_STATUS_RRDY_MSK)
|
||||||
|
break;
|
||||||
|
|
||||||
|
cpu_relax();
|
||||||
|
}
|
||||||
|
|
||||||
|
altera_spi_rx_word(hw);
|
||||||
|
}
|
||||||
|
spi_finalize_current_transfer(master);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static irqreturn_t altera_spi_irq(int irq, void *dev)
|
static irqreturn_t altera_spi_irq(int irq, void *dev)
|
||||||
|
@ -83,6 +83,7 @@ struct spi_geni_master {
|
|||||||
spinlock_t lock;
|
spinlock_t lock;
|
||||||
int irq;
|
int irq;
|
||||||
bool cs_flag;
|
bool cs_flag;
|
||||||
|
bool abort_failed;
|
||||||
};
|
};
|
||||||
|
|
||||||
static int get_spi_clk_cfg(unsigned int speed_hz,
|
static int get_spi_clk_cfg(unsigned int speed_hz,
|
||||||
@ -141,8 +142,49 @@ static void handle_fifo_timeout(struct spi_master *spi,
|
|||||||
spin_unlock_irq(&mas->lock);
|
spin_unlock_irq(&mas->lock);
|
||||||
|
|
||||||
time_left = wait_for_completion_timeout(&mas->abort_done, HZ);
|
time_left = wait_for_completion_timeout(&mas->abort_done, HZ);
|
||||||
if (!time_left)
|
if (!time_left) {
|
||||||
dev_err(mas->dev, "Failed to cancel/abort m_cmd\n");
|
dev_err(mas->dev, "Failed to cancel/abort m_cmd\n");
|
||||||
|
|
||||||
|
/*
|
||||||
|
* No need for a lock since SPI core has a lock and we never
|
||||||
|
* access this from an interrupt.
|
||||||
|
*/
|
||||||
|
mas->abort_failed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool spi_geni_is_abort_still_pending(struct spi_geni_master *mas)
|
||||||
|
{
|
||||||
|
struct geni_se *se = &mas->se;
|
||||||
|
u32 m_irq, m_irq_en;
|
||||||
|
|
||||||
|
if (!mas->abort_failed)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The only known case where a transfer times out and then a cancel
|
||||||
|
* times out then an abort times out is if something is blocking our
|
||||||
|
* interrupt handler from running. Avoid starting any new transfers
|
||||||
|
* until that sorts itself out.
|
||||||
|
*/
|
||||||
|
spin_lock_irq(&mas->lock);
|
||||||
|
m_irq = readl(se->base + SE_GENI_M_IRQ_STATUS);
|
||||||
|
m_irq_en = readl(se->base + SE_GENI_M_IRQ_EN);
|
||||||
|
spin_unlock_irq(&mas->lock);
|
||||||
|
|
||||||
|
if (m_irq & m_irq_en) {
|
||||||
|
dev_err(mas->dev, "Interrupts pending after abort: %#010x\n",
|
||||||
|
m_irq & m_irq_en);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If we're here the problem resolved itself so no need to check more
|
||||||
|
* on future transfers.
|
||||||
|
*/
|
||||||
|
mas->abort_failed = false;
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void spi_geni_set_cs(struct spi_device *slv, bool set_flag)
|
static void spi_geni_set_cs(struct spi_device *slv, bool set_flag)
|
||||||
@ -158,10 +200,21 @@ static void spi_geni_set_cs(struct spi_device *slv, bool set_flag)
|
|||||||
if (set_flag == mas->cs_flag)
|
if (set_flag == mas->cs_flag)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
mas->cs_flag = set_flag;
|
|
||||||
|
|
||||||
pm_runtime_get_sync(mas->dev);
|
pm_runtime_get_sync(mas->dev);
|
||||||
|
|
||||||
|
if (spi_geni_is_abort_still_pending(mas)) {
|
||||||
|
dev_err(mas->dev, "Can't set chip select\n");
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
spin_lock_irq(&mas->lock);
|
spin_lock_irq(&mas->lock);
|
||||||
|
if (mas->cur_xfer) {
|
||||||
|
dev_err(mas->dev, "Can't set CS when prev xfer running\n");
|
||||||
|
spin_unlock_irq(&mas->lock);
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
mas->cs_flag = set_flag;
|
||||||
reinit_completion(&mas->cs_done);
|
reinit_completion(&mas->cs_done);
|
||||||
if (set_flag)
|
if (set_flag)
|
||||||
geni_se_setup_m_cmd(se, SPI_CS_ASSERT, 0);
|
geni_se_setup_m_cmd(se, SPI_CS_ASSERT, 0);
|
||||||
@ -170,9 +223,12 @@ static void spi_geni_set_cs(struct spi_device *slv, bool set_flag)
|
|||||||
spin_unlock_irq(&mas->lock);
|
spin_unlock_irq(&mas->lock);
|
||||||
|
|
||||||
time_left = wait_for_completion_timeout(&mas->cs_done, HZ);
|
time_left = wait_for_completion_timeout(&mas->cs_done, HZ);
|
||||||
if (!time_left)
|
if (!time_left) {
|
||||||
|
dev_warn(mas->dev, "Timeout setting chip select\n");
|
||||||
handle_fifo_timeout(spi, NULL);
|
handle_fifo_timeout(spi, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
exit:
|
||||||
pm_runtime_put(mas->dev);
|
pm_runtime_put(mas->dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -280,6 +336,9 @@ static int spi_geni_prepare_message(struct spi_master *spi,
|
|||||||
int ret;
|
int ret;
|
||||||
struct spi_geni_master *mas = spi_master_get_devdata(spi);
|
struct spi_geni_master *mas = spi_master_get_devdata(spi);
|
||||||
|
|
||||||
|
if (spi_geni_is_abort_still_pending(mas))
|
||||||
|
return -EBUSY;
|
||||||
|
|
||||||
ret = setup_fifo_params(spi_msg->spi, spi);
|
ret = setup_fifo_params(spi_msg->spi, spi);
|
||||||
if (ret)
|
if (ret)
|
||||||
dev_err(mas->dev, "Couldn't select mode %d\n", ret);
|
dev_err(mas->dev, "Couldn't select mode %d\n", ret);
|
||||||
@ -354,6 +413,12 @@ static bool geni_spi_handle_tx(struct spi_geni_master *mas)
|
|||||||
unsigned int bytes_per_fifo_word = geni_byte_per_fifo_word(mas);
|
unsigned int bytes_per_fifo_word = geni_byte_per_fifo_word(mas);
|
||||||
unsigned int i = 0;
|
unsigned int i = 0;
|
||||||
|
|
||||||
|
/* Stop the watermark IRQ if nothing to send */
|
||||||
|
if (!mas->cur_xfer) {
|
||||||
|
writel(0, se->base + SE_GENI_TX_WATERMARK_REG);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
max_bytes = (mas->tx_fifo_depth - mas->tx_wm) * bytes_per_fifo_word;
|
max_bytes = (mas->tx_fifo_depth - mas->tx_wm) * bytes_per_fifo_word;
|
||||||
if (mas->tx_rem_bytes < max_bytes)
|
if (mas->tx_rem_bytes < max_bytes)
|
||||||
max_bytes = mas->tx_rem_bytes;
|
max_bytes = mas->tx_rem_bytes;
|
||||||
@ -396,6 +461,14 @@ static void geni_spi_handle_rx(struct spi_geni_master *mas)
|
|||||||
if (rx_last_byte_valid && rx_last_byte_valid < 4)
|
if (rx_last_byte_valid && rx_last_byte_valid < 4)
|
||||||
rx_bytes -= bytes_per_fifo_word - rx_last_byte_valid;
|
rx_bytes -= bytes_per_fifo_word - rx_last_byte_valid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Clear out the FIFO and bail if nowhere to put it */
|
||||||
|
if (!mas->cur_xfer) {
|
||||||
|
for (i = 0; i < DIV_ROUND_UP(rx_bytes, bytes_per_fifo_word); i++)
|
||||||
|
readl(se->base + SE_GENI_RX_FIFOn);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (mas->rx_rem_bytes < rx_bytes)
|
if (mas->rx_rem_bytes < rx_bytes)
|
||||||
rx_bytes = mas->rx_rem_bytes;
|
rx_bytes = mas->rx_rem_bytes;
|
||||||
|
|
||||||
@ -495,6 +568,9 @@ static int spi_geni_transfer_one(struct spi_master *spi,
|
|||||||
{
|
{
|
||||||
struct spi_geni_master *mas = spi_master_get_devdata(spi);
|
struct spi_geni_master *mas = spi_master_get_devdata(spi);
|
||||||
|
|
||||||
|
if (spi_geni_is_abort_still_pending(mas))
|
||||||
|
return -EBUSY;
|
||||||
|
|
||||||
/* Terminate and return success for 0 byte length transfer */
|
/* Terminate and return success for 0 byte length transfer */
|
||||||
if (!xfer->len)
|
if (!xfer->len)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -493,9 +493,9 @@ static u32 stm32h7_spi_prepare_fthlv(struct stm32_spi *spi, u32 xfer_len)
|
|||||||
|
|
||||||
/* align packet size with data registers access */
|
/* align packet size with data registers access */
|
||||||
if (spi->cur_bpw > 8)
|
if (spi->cur_bpw > 8)
|
||||||
fthlv -= (fthlv % 2); /* multiple of 2 */
|
fthlv += (fthlv % 2) ? 1 : 0;
|
||||||
else
|
else
|
||||||
fthlv -= (fthlv % 4); /* multiple of 4 */
|
fthlv += (fthlv % 4) ? (4 - (fthlv % 4)) : 0;
|
||||||
|
|
||||||
if (!fthlv)
|
if (!fthlv)
|
||||||
fthlv = 1;
|
fthlv = 1;
|
||||||
|
@ -1108,6 +1108,7 @@ static int spi_transfer_wait(struct spi_controller *ctlr,
|
|||||||
{
|
{
|
||||||
struct spi_statistics *statm = &ctlr->statistics;
|
struct spi_statistics *statm = &ctlr->statistics;
|
||||||
struct spi_statistics *stats = &msg->spi->statistics;
|
struct spi_statistics *stats = &msg->spi->statistics;
|
||||||
|
u32 speed_hz = xfer->speed_hz;
|
||||||
unsigned long long ms;
|
unsigned long long ms;
|
||||||
|
|
||||||
if (spi_controller_is_slave(ctlr)) {
|
if (spi_controller_is_slave(ctlr)) {
|
||||||
@ -1116,8 +1117,11 @@ static int spi_transfer_wait(struct spi_controller *ctlr,
|
|||||||
return -EINTR;
|
return -EINTR;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
if (!speed_hz)
|
||||||
|
speed_hz = 100000;
|
||||||
|
|
||||||
ms = 8LL * 1000LL * xfer->len;
|
ms = 8LL * 1000LL * xfer->len;
|
||||||
do_div(ms, xfer->speed_hz);
|
do_div(ms, speed_hz);
|
||||||
ms += ms + 200; /* some tolerance */
|
ms += ms + 200; /* some tolerance */
|
||||||
|
|
||||||
if (ms > UINT_MAX)
|
if (ms > UINT_MAX)
|
||||||
@ -3378,8 +3382,9 @@ int spi_setup(struct spi_device *spi)
|
|||||||
if (status)
|
if (status)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
if (!spi->max_speed_hz ||
|
if (spi->controller->max_speed_hz &&
|
||||||
spi->max_speed_hz > spi->controller->max_speed_hz)
|
(!spi->max_speed_hz ||
|
||||||
|
spi->max_speed_hz > spi->controller->max_speed_hz))
|
||||||
spi->max_speed_hz = spi->controller->max_speed_hz;
|
spi->max_speed_hz = spi->controller->max_speed_hz;
|
||||||
|
|
||||||
mutex_lock(&spi->controller->io_mutex);
|
mutex_lock(&spi->controller->io_mutex);
|
||||||
|
@ -401,6 +401,20 @@ config MIPS_EJTAG_FDC_KGDB_CHAN
|
|||||||
help
|
help
|
||||||
FDC channel number to use for KGDB.
|
FDC channel number to use for KGDB.
|
||||||
|
|
||||||
|
config NULL_TTY
|
||||||
|
tristate "NULL TTY driver"
|
||||||
|
help
|
||||||
|
Say Y here if you want a NULL TTY which simply discards messages.
|
||||||
|
|
||||||
|
This is useful to allow userspace applications which expect a console
|
||||||
|
device to work without modifications even when no console is
|
||||||
|
available or desired.
|
||||||
|
|
||||||
|
In order to use this driver, you should redirect the console to this
|
||||||
|
TTY, or boot the kernel with console=ttynull.
|
||||||
|
|
||||||
|
If unsure, say N.
|
||||||
|
|
||||||
config TRACE_ROUTER
|
config TRACE_ROUTER
|
||||||
tristate "Trace data router for MIPI P1149.7 cJTAG standard"
|
tristate "Trace data router for MIPI P1149.7 cJTAG standard"
|
||||||
depends on TRACE_SINK
|
depends on TRACE_SINK
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
obj-$(CONFIG_TTY) += tty_io.o n_tty.o tty_ioctl.o tty_ldisc.o \
|
obj-$(CONFIG_TTY) += tty_io.o n_tty.o tty_ioctl.o tty_ldisc.o \
|
||||||
tty_buffer.o tty_port.o tty_mutex.o \
|
tty_buffer.o tty_port.o tty_mutex.o \
|
||||||
tty_ldsem.o tty_baudrate.o tty_jobctrl.o \
|
tty_ldsem.o tty_baudrate.o tty_jobctrl.o \
|
||||||
n_null.o ttynull.o
|
n_null.o
|
||||||
obj-$(CONFIG_LEGACY_PTYS) += pty.o
|
obj-$(CONFIG_LEGACY_PTYS) += pty.o
|
||||||
obj-$(CONFIG_UNIX98_PTYS) += pty.o
|
obj-$(CONFIG_UNIX98_PTYS) += pty.o
|
||||||
obj-$(CONFIG_AUDIT) += tty_audit.o
|
obj-$(CONFIG_AUDIT) += tty_audit.o
|
||||||
@ -25,6 +25,7 @@ obj-$(CONFIG_ISI) += isicom.o
|
|||||||
obj-$(CONFIG_MOXA_INTELLIO) += moxa.o
|
obj-$(CONFIG_MOXA_INTELLIO) += moxa.o
|
||||||
obj-$(CONFIG_MOXA_SMARTIO) += mxser.o
|
obj-$(CONFIG_MOXA_SMARTIO) += mxser.o
|
||||||
obj-$(CONFIG_NOZOMI) += nozomi.o
|
obj-$(CONFIG_NOZOMI) += nozomi.o
|
||||||
|
obj-$(CONFIG_NULL_TTY) += ttynull.o
|
||||||
obj-$(CONFIG_ROCKETPORT) += rocket.o
|
obj-$(CONFIG_ROCKETPORT) += rocket.o
|
||||||
obj-$(CONFIG_SYNCLINK_GT) += synclink_gt.o
|
obj-$(CONFIG_SYNCLINK_GT) += synclink_gt.o
|
||||||
obj-$(CONFIG_PPC_EPAPR_HV_BYTECHAN) += ehv_bytechan.o
|
obj-$(CONFIG_PPC_EPAPR_HV_BYTECHAN) += ehv_bytechan.o
|
||||||
|
@ -2,13 +2,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2019 Axis Communications AB
|
* Copyright (C) 2019 Axis Communications AB
|
||||||
*
|
*
|
||||||
* The console is useful for userspace applications which expect a console
|
|
||||||
* device to work without modifications even when no console is available
|
|
||||||
* or desired.
|
|
||||||
*
|
|
||||||
* In order to use this driver, you should redirect the console to this
|
|
||||||
* TTY, or boot the kernel with console=ttynull.
|
|
||||||
*
|
|
||||||
* Based on ttyprintk.c:
|
* Based on ttyprintk.c:
|
||||||
* Copyright (C) 2010 Samo Pogacnik
|
* Copyright (C) 2010 Samo Pogacnik
|
||||||
*/
|
*/
|
||||||
@ -66,17 +59,6 @@ static struct console ttynull_console = {
|
|||||||
.device = ttynull_device,
|
.device = ttynull_device,
|
||||||
};
|
};
|
||||||
|
|
||||||
void __init register_ttynull_console(void)
|
|
||||||
{
|
|
||||||
if (!ttynull_driver)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (add_preferred_console(ttynull_console.name, 0, NULL))
|
|
||||||
return;
|
|
||||||
|
|
||||||
register_console(&ttynull_console);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int __init ttynull_init(void)
|
static int __init ttynull_init(void)
|
||||||
{
|
{
|
||||||
struct tty_driver *driver;
|
struct tty_driver *driver;
|
||||||
|
@ -30,7 +30,12 @@
|
|||||||
#define VHOST_VSOCK_PKT_WEIGHT 256
|
#define VHOST_VSOCK_PKT_WEIGHT 256
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
VHOST_VSOCK_FEATURES = VHOST_FEATURES,
|
VHOST_VSOCK_FEATURES = VHOST_FEATURES |
|
||||||
|
(1ULL << VIRTIO_F_ACCESS_PLATFORM)
|
||||||
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
VHOST_VSOCK_BACKEND_FEATURES = (1ULL << VHOST_BACKEND_F_IOTLB_MSG_V2)
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Used to track all the vhost_vsock instances on the system. */
|
/* Used to track all the vhost_vsock instances on the system. */
|
||||||
@ -94,6 +99,9 @@ vhost_transport_do_send_pkt(struct vhost_vsock *vsock,
|
|||||||
if (!vhost_vq_get_backend(vq))
|
if (!vhost_vq_get_backend(vq))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
if (!vq_meta_prefetch(vq))
|
||||||
|
goto out;
|
||||||
|
|
||||||
/* Avoid further vmexits, we're already processing the virtqueue */
|
/* Avoid further vmexits, we're already processing the virtqueue */
|
||||||
vhost_disable_notify(&vsock->dev, vq);
|
vhost_disable_notify(&vsock->dev, vq);
|
||||||
|
|
||||||
@ -449,6 +457,9 @@ static void vhost_vsock_handle_tx_kick(struct vhost_work *work)
|
|||||||
if (!vhost_vq_get_backend(vq))
|
if (!vhost_vq_get_backend(vq))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
if (!vq_meta_prefetch(vq))
|
||||||
|
goto out;
|
||||||
|
|
||||||
vhost_disable_notify(&vsock->dev, vq);
|
vhost_disable_notify(&vsock->dev, vq);
|
||||||
do {
|
do {
|
||||||
u32 len;
|
u32 len;
|
||||||
@ -766,8 +777,12 @@ static int vhost_vsock_set_features(struct vhost_vsock *vsock, u64 features)
|
|||||||
mutex_lock(&vsock->dev.mutex);
|
mutex_lock(&vsock->dev.mutex);
|
||||||
if ((features & (1 << VHOST_F_LOG_ALL)) &&
|
if ((features & (1 << VHOST_F_LOG_ALL)) &&
|
||||||
!vhost_log_access_ok(&vsock->dev)) {
|
!vhost_log_access_ok(&vsock->dev)) {
|
||||||
mutex_unlock(&vsock->dev.mutex);
|
goto err;
|
||||||
return -EFAULT;
|
}
|
||||||
|
|
||||||
|
if ((features & (1ULL << VIRTIO_F_ACCESS_PLATFORM))) {
|
||||||
|
if (vhost_init_device_iotlb(&vsock->dev, true))
|
||||||
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(vsock->vqs); i++) {
|
for (i = 0; i < ARRAY_SIZE(vsock->vqs); i++) {
|
||||||
@ -778,6 +793,10 @@ static int vhost_vsock_set_features(struct vhost_vsock *vsock, u64 features)
|
|||||||
}
|
}
|
||||||
mutex_unlock(&vsock->dev.mutex);
|
mutex_unlock(&vsock->dev.mutex);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
err:
|
||||||
|
mutex_unlock(&vsock->dev.mutex);
|
||||||
|
return -EFAULT;
|
||||||
}
|
}
|
||||||
|
|
||||||
static long vhost_vsock_dev_ioctl(struct file *f, unsigned int ioctl,
|
static long vhost_vsock_dev_ioctl(struct file *f, unsigned int ioctl,
|
||||||
@ -811,6 +830,18 @@ static long vhost_vsock_dev_ioctl(struct file *f, unsigned int ioctl,
|
|||||||
if (copy_from_user(&features, argp, sizeof(features)))
|
if (copy_from_user(&features, argp, sizeof(features)))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
return vhost_vsock_set_features(vsock, features);
|
return vhost_vsock_set_features(vsock, features);
|
||||||
|
case VHOST_GET_BACKEND_FEATURES:
|
||||||
|
features = VHOST_VSOCK_BACKEND_FEATURES;
|
||||||
|
if (copy_to_user(argp, &features, sizeof(features)))
|
||||||
|
return -EFAULT;
|
||||||
|
return 0;
|
||||||
|
case VHOST_SET_BACKEND_FEATURES:
|
||||||
|
if (copy_from_user(&features, argp, sizeof(features)))
|
||||||
|
return -EFAULT;
|
||||||
|
if (features & ~VHOST_VSOCK_BACKEND_FEATURES)
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
vhost_set_backend_features(&vsock->dev, features);
|
||||||
|
return 0;
|
||||||
default:
|
default:
|
||||||
mutex_lock(&vsock->dev.mutex);
|
mutex_lock(&vsock->dev.mutex);
|
||||||
r = vhost_dev_ioctl(&vsock->dev, ioctl, argp);
|
r = vhost_dev_ioctl(&vsock->dev, ioctl, argp);
|
||||||
@ -823,6 +854,34 @@ static long vhost_vsock_dev_ioctl(struct file *f, unsigned int ioctl,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ssize_t vhost_vsock_chr_read_iter(struct kiocb *iocb, struct iov_iter *to)
|
||||||
|
{
|
||||||
|
struct file *file = iocb->ki_filp;
|
||||||
|
struct vhost_vsock *vsock = file->private_data;
|
||||||
|
struct vhost_dev *dev = &vsock->dev;
|
||||||
|
int noblock = file->f_flags & O_NONBLOCK;
|
||||||
|
|
||||||
|
return vhost_chr_read_iter(dev, to, noblock);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t vhost_vsock_chr_write_iter(struct kiocb *iocb,
|
||||||
|
struct iov_iter *from)
|
||||||
|
{
|
||||||
|
struct file *file = iocb->ki_filp;
|
||||||
|
struct vhost_vsock *vsock = file->private_data;
|
||||||
|
struct vhost_dev *dev = &vsock->dev;
|
||||||
|
|
||||||
|
return vhost_chr_write_iter(dev, from);
|
||||||
|
}
|
||||||
|
|
||||||
|
static __poll_t vhost_vsock_chr_poll(struct file *file, poll_table *wait)
|
||||||
|
{
|
||||||
|
struct vhost_vsock *vsock = file->private_data;
|
||||||
|
struct vhost_dev *dev = &vsock->dev;
|
||||||
|
|
||||||
|
return vhost_chr_poll(file, dev, wait);
|
||||||
|
}
|
||||||
|
|
||||||
static const struct file_operations vhost_vsock_fops = {
|
static const struct file_operations vhost_vsock_fops = {
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.open = vhost_vsock_dev_open,
|
.open = vhost_vsock_dev_open,
|
||||||
@ -830,6 +889,9 @@ static const struct file_operations vhost_vsock_fops = {
|
|||||||
.llseek = noop_llseek,
|
.llseek = noop_llseek,
|
||||||
.unlocked_ioctl = vhost_vsock_dev_ioctl,
|
.unlocked_ioctl = vhost_vsock_dev_ioctl,
|
||||||
.compat_ioctl = compat_ptr_ioctl,
|
.compat_ioctl = compat_ptr_ioctl,
|
||||||
|
.read_iter = vhost_vsock_chr_read_iter,
|
||||||
|
.write_iter = vhost_vsock_chr_write_iter,
|
||||||
|
.poll = vhost_vsock_chr_poll,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct miscdevice vhost_vsock_misc = {
|
static struct miscdevice vhost_vsock_misc = {
|
||||||
|
@ -42,6 +42,15 @@ enum {
|
|||||||
* to an inode.
|
* to an inode.
|
||||||
*/
|
*/
|
||||||
BTRFS_INODE_NO_XATTRS,
|
BTRFS_INODE_NO_XATTRS,
|
||||||
|
/*
|
||||||
|
* Set when we are in a context where we need to start a transaction and
|
||||||
|
* have dirty pages with the respective file range locked. This is to
|
||||||
|
* ensure that when reserving space for the transaction, if we are low
|
||||||
|
* on available space and need to flush delalloc, we will not flush
|
||||||
|
* delalloc for this inode, because that could result in a deadlock (on
|
||||||
|
* the file range, inode's io_tree).
|
||||||
|
*/
|
||||||
|
BTRFS_INODE_NO_DELALLOC_FLUSH,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* in memory btrfs inode */
|
/* in memory btrfs inode */
|
||||||
|
@ -2555,8 +2555,14 @@ out:
|
|||||||
* @p: Holds all btree nodes along the search path
|
* @p: Holds all btree nodes along the search path
|
||||||
* @root: The root node of the tree
|
* @root: The root node of the tree
|
||||||
* @key: The key we are looking for
|
* @key: The key we are looking for
|
||||||
* @ins_len: Indicates purpose of search, for inserts it is 1, for
|
* @ins_len: Indicates purpose of search:
|
||||||
* deletions it's -1. 0 for plain searches
|
* >0 for inserts it's size of item inserted (*)
|
||||||
|
* <0 for deletions
|
||||||
|
* 0 for plain searches, not modifying the tree
|
||||||
|
*
|
||||||
|
* (*) If size of item inserted doesn't include
|
||||||
|
* sizeof(struct btrfs_item), then p->search_for_extension must
|
||||||
|
* be set.
|
||||||
* @cow: boolean should CoW operations be performed. Must always be 1
|
* @cow: boolean should CoW operations be performed. Must always be 1
|
||||||
* when modifying the tree.
|
* when modifying the tree.
|
||||||
*
|
*
|
||||||
@ -2717,6 +2723,20 @@ cow_done:
|
|||||||
|
|
||||||
if (level == 0) {
|
if (level == 0) {
|
||||||
p->slots[level] = slot;
|
p->slots[level] = slot;
|
||||||
|
/*
|
||||||
|
* Item key already exists. In this case, if we are
|
||||||
|
* allowed to insert the item (for example, in dir_item
|
||||||
|
* case, item key collision is allowed), it will be
|
||||||
|
* merged with the original item. Only the item size
|
||||||
|
* grows, no new btrfs item will be added. If
|
||||||
|
* search_for_extension is not set, ins_len already
|
||||||
|
* accounts the size btrfs_item, deduct it here so leaf
|
||||||
|
* space check will be correct.
|
||||||
|
*/
|
||||||
|
if (ret == 0 && ins_len > 0 && !p->search_for_extension) {
|
||||||
|
ASSERT(ins_len >= sizeof(struct btrfs_item));
|
||||||
|
ins_len -= sizeof(struct btrfs_item);
|
||||||
|
}
|
||||||
if (ins_len > 0 &&
|
if (ins_len > 0 &&
|
||||||
btrfs_leaf_free_space(b) < ins_len) {
|
btrfs_leaf_free_space(b) < ins_len) {
|
||||||
if (write_lock_level < 1) {
|
if (write_lock_level < 1) {
|
||||||
|
@ -131,6 +131,8 @@ enum {
|
|||||||
* defrag
|
* defrag
|
||||||
*/
|
*/
|
||||||
BTRFS_FS_STATE_REMOUNTING,
|
BTRFS_FS_STATE_REMOUNTING,
|
||||||
|
/* Filesystem in RO mode */
|
||||||
|
BTRFS_FS_STATE_RO,
|
||||||
/* Track if a transaction abort has been reported on this filesystem */
|
/* Track if a transaction abort has been reported on this filesystem */
|
||||||
BTRFS_FS_STATE_TRANS_ABORTED,
|
BTRFS_FS_STATE_TRANS_ABORTED,
|
||||||
/*
|
/*
|
||||||
@ -367,6 +369,12 @@ struct btrfs_path {
|
|||||||
unsigned int search_commit_root:1;
|
unsigned int search_commit_root:1;
|
||||||
unsigned int need_commit_sem:1;
|
unsigned int need_commit_sem:1;
|
||||||
unsigned int skip_release_on_error:1;
|
unsigned int skip_release_on_error:1;
|
||||||
|
/*
|
||||||
|
* Indicate that new item (btrfs_search_slot) is extending already
|
||||||
|
* existing item and ins_len contains only the data size and not item
|
||||||
|
* header (ie. sizeof(struct btrfs_item) is not included).
|
||||||
|
*/
|
||||||
|
unsigned int search_for_extension:1;
|
||||||
};
|
};
|
||||||
#define BTRFS_MAX_EXTENT_ITEM_SIZE(r) ((BTRFS_LEAF_DATA_SIZE(r->fs_info) >> 4) - \
|
#define BTRFS_MAX_EXTENT_ITEM_SIZE(r) ((BTRFS_LEAF_DATA_SIZE(r->fs_info) >> 4) - \
|
||||||
sizeof(struct btrfs_item))
|
sizeof(struct btrfs_item))
|
||||||
@ -2885,10 +2893,26 @@ static inline int btrfs_fs_closing(struct btrfs_fs_info *fs_info)
|
|||||||
* If we remount the fs to be R/O or umount the fs, the cleaner needn't do
|
* If we remount the fs to be R/O or umount the fs, the cleaner needn't do
|
||||||
* anything except sleeping. This function is used to check the status of
|
* anything except sleeping. This function is used to check the status of
|
||||||
* the fs.
|
* the fs.
|
||||||
|
* We check for BTRFS_FS_STATE_RO to avoid races with a concurrent remount,
|
||||||
|
* since setting and checking for SB_RDONLY in the superblock's flags is not
|
||||||
|
* atomic.
|
||||||
*/
|
*/
|
||||||
static inline int btrfs_need_cleaner_sleep(struct btrfs_fs_info *fs_info)
|
static inline int btrfs_need_cleaner_sleep(struct btrfs_fs_info *fs_info)
|
||||||
{
|
{
|
||||||
return fs_info->sb->s_flags & SB_RDONLY || btrfs_fs_closing(fs_info);
|
return test_bit(BTRFS_FS_STATE_RO, &fs_info->fs_state) ||
|
||||||
|
btrfs_fs_closing(fs_info);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void btrfs_set_sb_rdonly(struct super_block *sb)
|
||||||
|
{
|
||||||
|
sb->s_flags |= SB_RDONLY;
|
||||||
|
set_bit(BTRFS_FS_STATE_RO, &btrfs_sb(sb)->fs_state);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void btrfs_clear_sb_rdonly(struct super_block *sb)
|
||||||
|
{
|
||||||
|
sb->s_flags &= ~SB_RDONLY;
|
||||||
|
clear_bit(BTRFS_FS_STATE_RO, &btrfs_sb(sb)->fs_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* tree mod log functions from ctree.c */
|
/* tree mod log functions from ctree.c */
|
||||||
@ -3073,7 +3097,8 @@ int btrfs_truncate_inode_items(struct btrfs_trans_handle *trans,
|
|||||||
u32 min_type);
|
u32 min_type);
|
||||||
|
|
||||||
int btrfs_start_delalloc_snapshot(struct btrfs_root *root);
|
int btrfs_start_delalloc_snapshot(struct btrfs_root *root);
|
||||||
int btrfs_start_delalloc_roots(struct btrfs_fs_info *fs_info, u64 nr);
|
int btrfs_start_delalloc_roots(struct btrfs_fs_info *fs_info, u64 nr,
|
||||||
|
bool in_reclaim_context);
|
||||||
int btrfs_set_extent_delalloc(struct btrfs_inode *inode, u64 start, u64 end,
|
int btrfs_set_extent_delalloc(struct btrfs_inode *inode, u64 start, u64 end,
|
||||||
unsigned int extra_bits,
|
unsigned int extra_bits,
|
||||||
struct extent_state **cached_state);
|
struct extent_state **cached_state);
|
||||||
|
@ -715,7 +715,7 @@ static int btrfs_dev_replace_finishing(struct btrfs_fs_info *fs_info,
|
|||||||
* flush all outstanding I/O and inode extent mappings before the
|
* flush all outstanding I/O and inode extent mappings before the
|
||||||
* copy operation is declared as being finished
|
* copy operation is declared as being finished
|
||||||
*/
|
*/
|
||||||
ret = btrfs_start_delalloc_roots(fs_info, U64_MAX);
|
ret = btrfs_start_delalloc_roots(fs_info, U64_MAX, false);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
mutex_unlock(&dev_replace->lock_finishing_cancel_unmount);
|
mutex_unlock(&dev_replace->lock_finishing_cancel_unmount);
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -199,16 +199,15 @@ static struct btrfs_block_group *find_next_block_group(
|
|||||||
static struct btrfs_block_group *peek_discard_list(
|
static struct btrfs_block_group *peek_discard_list(
|
||||||
struct btrfs_discard_ctl *discard_ctl,
|
struct btrfs_discard_ctl *discard_ctl,
|
||||||
enum btrfs_discard_state *discard_state,
|
enum btrfs_discard_state *discard_state,
|
||||||
int *discard_index)
|
int *discard_index, u64 now)
|
||||||
{
|
{
|
||||||
struct btrfs_block_group *block_group;
|
struct btrfs_block_group *block_group;
|
||||||
const u64 now = ktime_get_ns();
|
|
||||||
|
|
||||||
spin_lock(&discard_ctl->lock);
|
spin_lock(&discard_ctl->lock);
|
||||||
again:
|
again:
|
||||||
block_group = find_next_block_group(discard_ctl, now);
|
block_group = find_next_block_group(discard_ctl, now);
|
||||||
|
|
||||||
if (block_group && now > block_group->discard_eligible_time) {
|
if (block_group && now >= block_group->discard_eligible_time) {
|
||||||
if (block_group->discard_index == BTRFS_DISCARD_INDEX_UNUSED &&
|
if (block_group->discard_index == BTRFS_DISCARD_INDEX_UNUSED &&
|
||||||
block_group->used != 0) {
|
block_group->used != 0) {
|
||||||
if (btrfs_is_block_group_data_only(block_group))
|
if (btrfs_is_block_group_data_only(block_group))
|
||||||
@ -222,12 +221,11 @@ again:
|
|||||||
block_group->discard_state = BTRFS_DISCARD_EXTENTS;
|
block_group->discard_state = BTRFS_DISCARD_EXTENTS;
|
||||||
}
|
}
|
||||||
discard_ctl->block_group = block_group;
|
discard_ctl->block_group = block_group;
|
||||||
|
}
|
||||||
|
if (block_group) {
|
||||||
*discard_state = block_group->discard_state;
|
*discard_state = block_group->discard_state;
|
||||||
*discard_index = block_group->discard_index;
|
*discard_index = block_group->discard_index;
|
||||||
} else {
|
|
||||||
block_group = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
spin_unlock(&discard_ctl->lock);
|
spin_unlock(&discard_ctl->lock);
|
||||||
|
|
||||||
return block_group;
|
return block_group;
|
||||||
@ -330,28 +328,15 @@ void btrfs_discard_queue_work(struct btrfs_discard_ctl *discard_ctl,
|
|||||||
btrfs_discard_schedule_work(discard_ctl, false);
|
btrfs_discard_schedule_work(discard_ctl, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
static void __btrfs_discard_schedule_work(struct btrfs_discard_ctl *discard_ctl,
|
||||||
* btrfs_discard_schedule_work - responsible for scheduling the discard work
|
u64 now, bool override)
|
||||||
* @discard_ctl: discard control
|
|
||||||
* @override: override the current timer
|
|
||||||
*
|
|
||||||
* Discards are issued by a delayed workqueue item. @override is used to
|
|
||||||
* update the current delay as the baseline delay interval is reevaluated on
|
|
||||||
* transaction commit. This is also maxed with any other rate limit.
|
|
||||||
*/
|
|
||||||
void btrfs_discard_schedule_work(struct btrfs_discard_ctl *discard_ctl,
|
|
||||||
bool override)
|
|
||||||
{
|
{
|
||||||
struct btrfs_block_group *block_group;
|
struct btrfs_block_group *block_group;
|
||||||
const u64 now = ktime_get_ns();
|
|
||||||
|
|
||||||
spin_lock(&discard_ctl->lock);
|
|
||||||
|
|
||||||
if (!btrfs_run_discard_work(discard_ctl))
|
if (!btrfs_run_discard_work(discard_ctl))
|
||||||
goto out;
|
return;
|
||||||
|
|
||||||
if (!override && delayed_work_pending(&discard_ctl->work))
|
if (!override && delayed_work_pending(&discard_ctl->work))
|
||||||
goto out;
|
return;
|
||||||
|
|
||||||
block_group = find_next_block_group(discard_ctl, now);
|
block_group = find_next_block_group(discard_ctl, now);
|
||||||
if (block_group) {
|
if (block_group) {
|
||||||
@ -393,7 +378,24 @@ void btrfs_discard_schedule_work(struct btrfs_discard_ctl *discard_ctl,
|
|||||||
mod_delayed_work(discard_ctl->discard_workers,
|
mod_delayed_work(discard_ctl->discard_workers,
|
||||||
&discard_ctl->work, nsecs_to_jiffies(delay));
|
&discard_ctl->work, nsecs_to_jiffies(delay));
|
||||||
}
|
}
|
||||||
out:
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* btrfs_discard_schedule_work - responsible for scheduling the discard work
|
||||||
|
* @discard_ctl: discard control
|
||||||
|
* @override: override the current timer
|
||||||
|
*
|
||||||
|
* Discards are issued by a delayed workqueue item. @override is used to
|
||||||
|
* update the current delay as the baseline delay interval is reevaluated on
|
||||||
|
* transaction commit. This is also maxed with any other rate limit.
|
||||||
|
*/
|
||||||
|
void btrfs_discard_schedule_work(struct btrfs_discard_ctl *discard_ctl,
|
||||||
|
bool override)
|
||||||
|
{
|
||||||
|
const u64 now = ktime_get_ns();
|
||||||
|
|
||||||
|
spin_lock(&discard_ctl->lock);
|
||||||
|
__btrfs_discard_schedule_work(discard_ctl, now, override);
|
||||||
spin_unlock(&discard_ctl->lock);
|
spin_unlock(&discard_ctl->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -438,13 +440,18 @@ static void btrfs_discard_workfn(struct work_struct *work)
|
|||||||
int discard_index = 0;
|
int discard_index = 0;
|
||||||
u64 trimmed = 0;
|
u64 trimmed = 0;
|
||||||
u64 minlen = 0;
|
u64 minlen = 0;
|
||||||
|
u64 now = ktime_get_ns();
|
||||||
|
|
||||||
discard_ctl = container_of(work, struct btrfs_discard_ctl, work.work);
|
discard_ctl = container_of(work, struct btrfs_discard_ctl, work.work);
|
||||||
|
|
||||||
block_group = peek_discard_list(discard_ctl, &discard_state,
|
block_group = peek_discard_list(discard_ctl, &discard_state,
|
||||||
&discard_index);
|
&discard_index, now);
|
||||||
if (!block_group || !btrfs_run_discard_work(discard_ctl))
|
if (!block_group || !btrfs_run_discard_work(discard_ctl))
|
||||||
return;
|
return;
|
||||||
|
if (now < block_group->discard_eligible_time) {
|
||||||
|
btrfs_discard_schedule_work(discard_ctl, false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* Perform discarding */
|
/* Perform discarding */
|
||||||
minlen = discard_minlen[discard_index];
|
minlen = discard_minlen[discard_index];
|
||||||
@ -474,13 +481,6 @@ static void btrfs_discard_workfn(struct work_struct *work)
|
|||||||
discard_ctl->discard_extent_bytes += trimmed;
|
discard_ctl->discard_extent_bytes += trimmed;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Updated without locks as this is inside the workfn and nothing else
|
|
||||||
* is reading the values
|
|
||||||
*/
|
|
||||||
discard_ctl->prev_discard = trimmed;
|
|
||||||
discard_ctl->prev_discard_time = ktime_get_ns();
|
|
||||||
|
|
||||||
/* Determine next steps for a block_group */
|
/* Determine next steps for a block_group */
|
||||||
if (block_group->discard_cursor >= btrfs_block_group_end(block_group)) {
|
if (block_group->discard_cursor >= btrfs_block_group_end(block_group)) {
|
||||||
if (discard_state == BTRFS_DISCARD_BITMAPS) {
|
if (discard_state == BTRFS_DISCARD_BITMAPS) {
|
||||||
@ -496,11 +496,13 @@ static void btrfs_discard_workfn(struct work_struct *work)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
now = ktime_get_ns();
|
||||||
spin_lock(&discard_ctl->lock);
|
spin_lock(&discard_ctl->lock);
|
||||||
|
discard_ctl->prev_discard = trimmed;
|
||||||
|
discard_ctl->prev_discard_time = now;
|
||||||
discard_ctl->block_group = NULL;
|
discard_ctl->block_group = NULL;
|
||||||
|
__btrfs_discard_schedule_work(discard_ctl, now, false);
|
||||||
spin_unlock(&discard_ctl->lock);
|
spin_unlock(&discard_ctl->lock);
|
||||||
|
|
||||||
btrfs_discard_schedule_work(discard_ctl, false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1729,7 +1729,7 @@ static int cleaner_kthread(void *arg)
|
|||||||
*/
|
*/
|
||||||
btrfs_delete_unused_bgs(fs_info);
|
btrfs_delete_unused_bgs(fs_info);
|
||||||
sleep:
|
sleep:
|
||||||
clear_bit(BTRFS_FS_CLEANER_RUNNING, &fs_info->flags);
|
clear_and_wake_up_bit(BTRFS_FS_CLEANER_RUNNING, &fs_info->flags);
|
||||||
if (kthread_should_park())
|
if (kthread_should_park())
|
||||||
kthread_parkme();
|
kthread_parkme();
|
||||||
if (kthread_should_stop())
|
if (kthread_should_stop())
|
||||||
@ -2830,6 +2830,9 @@ static int init_mount_fs_info(struct btrfs_fs_info *fs_info, struct super_block
|
|||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
btrfs_init_delayed_root(fs_info->delayed_root);
|
btrfs_init_delayed_root(fs_info->delayed_root);
|
||||||
|
|
||||||
|
if (sb_rdonly(sb))
|
||||||
|
set_bit(BTRFS_FS_STATE_RO, &fs_info->fs_state);
|
||||||
|
|
||||||
return btrfs_alloc_stripe_hash_table(fs_info);
|
return btrfs_alloc_stripe_hash_table(fs_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2969,6 +2972,7 @@ int btrfs_start_pre_rw_mount(struct btrfs_fs_info *fs_info)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ret = btrfs_find_orphan_roots(fs_info);
|
||||||
out:
|
out:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -3383,10 +3387,6 @@ int __cold open_ctree(struct super_block *sb, struct btrfs_fs_devices *fs_device
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = btrfs_find_orphan_roots(fs_info);
|
|
||||||
if (ret)
|
|
||||||
goto fail_qgroup;
|
|
||||||
|
|
||||||
fs_info->fs_root = btrfs_get_fs_root(fs_info, BTRFS_FS_TREE_OBJECTID, true);
|
fs_info->fs_root = btrfs_get_fs_root(fs_info, BTRFS_FS_TREE_OBJECTID, true);
|
||||||
if (IS_ERR(fs_info->fs_root)) {
|
if (IS_ERR(fs_info->fs_root)) {
|
||||||
err = PTR_ERR(fs_info->fs_root);
|
err = PTR_ERR(fs_info->fs_root);
|
||||||
@ -4181,6 +4181,9 @@ void __cold close_ctree(struct btrfs_fs_info *fs_info)
|
|||||||
invalidate_inode_pages2(fs_info->btree_inode->i_mapping);
|
invalidate_inode_pages2(fs_info->btree_inode->i_mapping);
|
||||||
btrfs_stop_all_workers(fs_info);
|
btrfs_stop_all_workers(fs_info);
|
||||||
|
|
||||||
|
/* We shouldn't have any transaction open at this point */
|
||||||
|
ASSERT(list_empty(&fs_info->trans_list));
|
||||||
|
|
||||||
clear_bit(BTRFS_FS_OPEN, &fs_info->flags);
|
clear_bit(BTRFS_FS_OPEN, &fs_info->flags);
|
||||||
free_root_pointers(fs_info, true);
|
free_root_pointers(fs_info, true);
|
||||||
btrfs_free_fs_roots(fs_info);
|
btrfs_free_fs_roots(fs_info);
|
||||||
|
@ -844,6 +844,7 @@ int lookup_inline_extent_backref(struct btrfs_trans_handle *trans,
|
|||||||
want = extent_ref_type(parent, owner);
|
want = extent_ref_type(parent, owner);
|
||||||
if (insert) {
|
if (insert) {
|
||||||
extra_size = btrfs_extent_inline_ref_size(want);
|
extra_size = btrfs_extent_inline_ref_size(want);
|
||||||
|
path->search_for_extension = 1;
|
||||||
path->keep_locks = 1;
|
path->keep_locks = 1;
|
||||||
} else
|
} else
|
||||||
extra_size = -1;
|
extra_size = -1;
|
||||||
@ -996,6 +997,7 @@ again:
|
|||||||
out:
|
out:
|
||||||
if (insert) {
|
if (insert) {
|
||||||
path->keep_locks = 0;
|
path->keep_locks = 0;
|
||||||
|
path->search_for_extension = 0;
|
||||||
btrfs_unlock_up_safe(path, 1);
|
btrfs_unlock_up_safe(path, 1);
|
||||||
}
|
}
|
||||||
return err;
|
return err;
|
||||||
|
@ -1016,8 +1016,10 @@ again:
|
|||||||
}
|
}
|
||||||
|
|
||||||
btrfs_release_path(path);
|
btrfs_release_path(path);
|
||||||
|
path->search_for_extension = 1;
|
||||||
ret = btrfs_search_slot(trans, root, &file_key, path,
|
ret = btrfs_search_slot(trans, root, &file_key, path,
|
||||||
csum_size, 1);
|
csum_size, 1);
|
||||||
|
path->search_for_extension = 0;
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
@ -9390,7 +9390,8 @@ static struct btrfs_delalloc_work *btrfs_alloc_delalloc_work(struct inode *inode
|
|||||||
* some fairly slow code that needs optimization. This walks the list
|
* some fairly slow code that needs optimization. This walks the list
|
||||||
* of all the inodes with pending delalloc and forces them to disk.
|
* of all the inodes with pending delalloc and forces them to disk.
|
||||||
*/
|
*/
|
||||||
static int start_delalloc_inodes(struct btrfs_root *root, u64 *nr, bool snapshot)
|
static int start_delalloc_inodes(struct btrfs_root *root, u64 *nr, bool snapshot,
|
||||||
|
bool in_reclaim_context)
|
||||||
{
|
{
|
||||||
struct btrfs_inode *binode;
|
struct btrfs_inode *binode;
|
||||||
struct inode *inode;
|
struct inode *inode;
|
||||||
@ -9411,6 +9412,11 @@ static int start_delalloc_inodes(struct btrfs_root *root, u64 *nr, bool snapshot
|
|||||||
|
|
||||||
list_move_tail(&binode->delalloc_inodes,
|
list_move_tail(&binode->delalloc_inodes,
|
||||||
&root->delalloc_inodes);
|
&root->delalloc_inodes);
|
||||||
|
|
||||||
|
if (in_reclaim_context &&
|
||||||
|
test_bit(BTRFS_INODE_NO_DELALLOC_FLUSH, &binode->runtime_flags))
|
||||||
|
continue;
|
||||||
|
|
||||||
inode = igrab(&binode->vfs_inode);
|
inode = igrab(&binode->vfs_inode);
|
||||||
if (!inode) {
|
if (!inode) {
|
||||||
cond_resched_lock(&root->delalloc_lock);
|
cond_resched_lock(&root->delalloc_lock);
|
||||||
@ -9464,10 +9470,11 @@ int btrfs_start_delalloc_snapshot(struct btrfs_root *root)
|
|||||||
if (test_bit(BTRFS_FS_STATE_ERROR, &fs_info->fs_state))
|
if (test_bit(BTRFS_FS_STATE_ERROR, &fs_info->fs_state))
|
||||||
return -EROFS;
|
return -EROFS;
|
||||||
|
|
||||||
return start_delalloc_inodes(root, &nr, true);
|
return start_delalloc_inodes(root, &nr, true, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
int btrfs_start_delalloc_roots(struct btrfs_fs_info *fs_info, u64 nr)
|
int btrfs_start_delalloc_roots(struct btrfs_fs_info *fs_info, u64 nr,
|
||||||
|
bool in_reclaim_context)
|
||||||
{
|
{
|
||||||
struct btrfs_root *root;
|
struct btrfs_root *root;
|
||||||
struct list_head splice;
|
struct list_head splice;
|
||||||
@ -9490,7 +9497,7 @@ int btrfs_start_delalloc_roots(struct btrfs_fs_info *fs_info, u64 nr)
|
|||||||
&fs_info->delalloc_roots);
|
&fs_info->delalloc_roots);
|
||||||
spin_unlock(&fs_info->delalloc_root_lock);
|
spin_unlock(&fs_info->delalloc_root_lock);
|
||||||
|
|
||||||
ret = start_delalloc_inodes(root, &nr, false);
|
ret = start_delalloc_inodes(root, &nr, false, in_reclaim_context);
|
||||||
btrfs_put_root(root);
|
btrfs_put_root(root);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -4951,7 +4951,7 @@ long btrfs_ioctl(struct file *file, unsigned int
|
|||||||
case BTRFS_IOC_SYNC: {
|
case BTRFS_IOC_SYNC: {
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = btrfs_start_delalloc_roots(fs_info, U64_MAX);
|
ret = btrfs_start_delalloc_roots(fs_info, U64_MAX, false);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
ret = btrfs_sync_fs(inode->i_sb, 1);
|
ret = btrfs_sync_fs(inode->i_sb, 1);
|
||||||
|
@ -3190,6 +3190,12 @@ out:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool rescan_should_stop(struct btrfs_fs_info *fs_info)
|
||||||
|
{
|
||||||
|
return btrfs_fs_closing(fs_info) ||
|
||||||
|
test_bit(BTRFS_FS_STATE_REMOUNTING, &fs_info->fs_state);
|
||||||
|
}
|
||||||
|
|
||||||
static void btrfs_qgroup_rescan_worker(struct btrfs_work *work)
|
static void btrfs_qgroup_rescan_worker(struct btrfs_work *work)
|
||||||
{
|
{
|
||||||
struct btrfs_fs_info *fs_info = container_of(work, struct btrfs_fs_info,
|
struct btrfs_fs_info *fs_info = container_of(work, struct btrfs_fs_info,
|
||||||
@ -3198,6 +3204,7 @@ static void btrfs_qgroup_rescan_worker(struct btrfs_work *work)
|
|||||||
struct btrfs_trans_handle *trans = NULL;
|
struct btrfs_trans_handle *trans = NULL;
|
||||||
int err = -ENOMEM;
|
int err = -ENOMEM;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
bool stopped = false;
|
||||||
|
|
||||||
path = btrfs_alloc_path();
|
path = btrfs_alloc_path();
|
||||||
if (!path)
|
if (!path)
|
||||||
@ -3210,7 +3217,7 @@ static void btrfs_qgroup_rescan_worker(struct btrfs_work *work)
|
|||||||
path->skip_locking = 1;
|
path->skip_locking = 1;
|
||||||
|
|
||||||
err = 0;
|
err = 0;
|
||||||
while (!err && !btrfs_fs_closing(fs_info)) {
|
while (!err && !(stopped = rescan_should_stop(fs_info))) {
|
||||||
trans = btrfs_start_transaction(fs_info->fs_root, 0);
|
trans = btrfs_start_transaction(fs_info->fs_root, 0);
|
||||||
if (IS_ERR(trans)) {
|
if (IS_ERR(trans)) {
|
||||||
err = PTR_ERR(trans);
|
err = PTR_ERR(trans);
|
||||||
@ -3253,7 +3260,7 @@ out:
|
|||||||
}
|
}
|
||||||
|
|
||||||
mutex_lock(&fs_info->qgroup_rescan_lock);
|
mutex_lock(&fs_info->qgroup_rescan_lock);
|
||||||
if (!btrfs_fs_closing(fs_info))
|
if (!stopped)
|
||||||
fs_info->qgroup_flags &= ~BTRFS_QGROUP_STATUS_FLAG_RESCAN;
|
fs_info->qgroup_flags &= ~BTRFS_QGROUP_STATUS_FLAG_RESCAN;
|
||||||
if (trans) {
|
if (trans) {
|
||||||
ret = update_qgroup_status_item(trans);
|
ret = update_qgroup_status_item(trans);
|
||||||
@ -3272,7 +3279,7 @@ out:
|
|||||||
|
|
||||||
btrfs_end_transaction(trans);
|
btrfs_end_transaction(trans);
|
||||||
|
|
||||||
if (btrfs_fs_closing(fs_info)) {
|
if (stopped) {
|
||||||
btrfs_info(fs_info, "qgroup scan paused");
|
btrfs_info(fs_info, "qgroup scan paused");
|
||||||
} else if (err >= 0) {
|
} else if (err >= 0) {
|
||||||
btrfs_info(fs_info, "qgroup scan completed%s",
|
btrfs_info(fs_info, "qgroup scan completed%s",
|
||||||
@ -3530,16 +3537,6 @@ static int try_flush_qgroup(struct btrfs_root *root)
|
|||||||
int ret;
|
int ret;
|
||||||
bool can_commit = true;
|
bool can_commit = true;
|
||||||
|
|
||||||
/*
|
|
||||||
* We don't want to run flush again and again, so if there is a running
|
|
||||||
* one, we won't try to start a new flush, but exit directly.
|
|
||||||
*/
|
|
||||||
if (test_and_set_bit(BTRFS_ROOT_QGROUP_FLUSHING, &root->state)) {
|
|
||||||
wait_event(root->qgroup_flush_wait,
|
|
||||||
!test_bit(BTRFS_ROOT_QGROUP_FLUSHING, &root->state));
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If current process holds a transaction, we shouldn't flush, as we
|
* If current process holds a transaction, we shouldn't flush, as we
|
||||||
* assume all space reservation happens before a transaction handle is
|
* assume all space reservation happens before a transaction handle is
|
||||||
@ -3554,6 +3551,26 @@ static int try_flush_qgroup(struct btrfs_root *root)
|
|||||||
current->journal_info != BTRFS_SEND_TRANS_STUB)
|
current->journal_info != BTRFS_SEND_TRANS_STUB)
|
||||||
can_commit = false;
|
can_commit = false;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We don't want to run flush again and again, so if there is a running
|
||||||
|
* one, we won't try to start a new flush, but exit directly.
|
||||||
|
*/
|
||||||
|
if (test_and_set_bit(BTRFS_ROOT_QGROUP_FLUSHING, &root->state)) {
|
||||||
|
/*
|
||||||
|
* We are already holding a transaction, thus we can block other
|
||||||
|
* threads from flushing. So exit right now. This increases
|
||||||
|
* the chance of EDQUOT for heavy load and near limit cases.
|
||||||
|
* But we can argue that if we're already near limit, EDQUOT is
|
||||||
|
* unavoidable anyway.
|
||||||
|
*/
|
||||||
|
if (!can_commit)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
wait_event(root->qgroup_flush_wait,
|
||||||
|
!test_bit(BTRFS_ROOT_QGROUP_FLUSHING, &root->state));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
ret = btrfs_start_delalloc_snapshot(root);
|
ret = btrfs_start_delalloc_snapshot(root);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -89,6 +89,19 @@ static int copy_inline_to_page(struct btrfs_inode *inode,
|
|||||||
if (ret)
|
if (ret)
|
||||||
goto out_unlock;
|
goto out_unlock;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* After dirtying the page our caller will need to start a transaction,
|
||||||
|
* and if we are low on metadata free space, that can cause flushing of
|
||||||
|
* delalloc for all inodes in order to get metadata space released.
|
||||||
|
* However we are holding the range locked for the whole duration of
|
||||||
|
* the clone/dedupe operation, so we may deadlock if that happens and no
|
||||||
|
* other task releases enough space. So mark this inode as not being
|
||||||
|
* possible to flush to avoid such deadlock. We will clear that flag
|
||||||
|
* when we finish cloning all extents, since a transaction is started
|
||||||
|
* after finding each extent to clone.
|
||||||
|
*/
|
||||||
|
set_bit(BTRFS_INODE_NO_DELALLOC_FLUSH, &inode->runtime_flags);
|
||||||
|
|
||||||
if (comp_type == BTRFS_COMPRESS_NONE) {
|
if (comp_type == BTRFS_COMPRESS_NONE) {
|
||||||
char *map;
|
char *map;
|
||||||
|
|
||||||
@ -549,6 +562,8 @@ process_slot:
|
|||||||
out:
|
out:
|
||||||
btrfs_free_path(path);
|
btrfs_free_path(path);
|
||||||
kvfree(buf);
|
kvfree(buf);
|
||||||
|
clear_bit(BTRFS_INODE_NO_DELALLOC_FLUSH, &BTRFS_I(inode)->runtime_flags);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -236,6 +236,7 @@ struct waiting_dir_move {
|
|||||||
* after this directory is moved, we can try to rmdir the ino rmdir_ino.
|
* after this directory is moved, we can try to rmdir the ino rmdir_ino.
|
||||||
*/
|
*/
|
||||||
u64 rmdir_ino;
|
u64 rmdir_ino;
|
||||||
|
u64 rmdir_gen;
|
||||||
bool orphanized;
|
bool orphanized;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -316,7 +317,7 @@ static int is_waiting_for_move(struct send_ctx *sctx, u64 ino);
|
|||||||
static struct waiting_dir_move *
|
static struct waiting_dir_move *
|
||||||
get_waiting_dir_move(struct send_ctx *sctx, u64 ino);
|
get_waiting_dir_move(struct send_ctx *sctx, u64 ino);
|
||||||
|
|
||||||
static int is_waiting_for_rm(struct send_ctx *sctx, u64 dir_ino);
|
static int is_waiting_for_rm(struct send_ctx *sctx, u64 dir_ino, u64 gen);
|
||||||
|
|
||||||
static int need_send_hole(struct send_ctx *sctx)
|
static int need_send_hole(struct send_ctx *sctx)
|
||||||
{
|
{
|
||||||
@ -2299,7 +2300,7 @@ static int get_cur_path(struct send_ctx *sctx, u64 ino, u64 gen,
|
|||||||
|
|
||||||
fs_path_reset(name);
|
fs_path_reset(name);
|
||||||
|
|
||||||
if (is_waiting_for_rm(sctx, ino)) {
|
if (is_waiting_for_rm(sctx, ino, gen)) {
|
||||||
ret = gen_unique_name(sctx, ino, gen, name);
|
ret = gen_unique_name(sctx, ino, gen, name);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto out;
|
goto out;
|
||||||
@ -2858,8 +2859,8 @@ out:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct orphan_dir_info *
|
static struct orphan_dir_info *add_orphan_dir_info(struct send_ctx *sctx,
|
||||||
add_orphan_dir_info(struct send_ctx *sctx, u64 dir_ino)
|
u64 dir_ino, u64 dir_gen)
|
||||||
{
|
{
|
||||||
struct rb_node **p = &sctx->orphan_dirs.rb_node;
|
struct rb_node **p = &sctx->orphan_dirs.rb_node;
|
||||||
struct rb_node *parent = NULL;
|
struct rb_node *parent = NULL;
|
||||||
@ -2868,20 +2869,23 @@ add_orphan_dir_info(struct send_ctx *sctx, u64 dir_ino)
|
|||||||
while (*p) {
|
while (*p) {
|
||||||
parent = *p;
|
parent = *p;
|
||||||
entry = rb_entry(parent, struct orphan_dir_info, node);
|
entry = rb_entry(parent, struct orphan_dir_info, node);
|
||||||
if (dir_ino < entry->ino) {
|
if (dir_ino < entry->ino)
|
||||||
p = &(*p)->rb_left;
|
p = &(*p)->rb_left;
|
||||||
} else if (dir_ino > entry->ino) {
|
else if (dir_ino > entry->ino)
|
||||||
p = &(*p)->rb_right;
|
p = &(*p)->rb_right;
|
||||||
} else {
|
else if (dir_gen < entry->gen)
|
||||||
|
p = &(*p)->rb_left;
|
||||||
|
else if (dir_gen > entry->gen)
|
||||||
|
p = &(*p)->rb_right;
|
||||||
|
else
|
||||||
return entry;
|
return entry;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
odi = kmalloc(sizeof(*odi), GFP_KERNEL);
|
odi = kmalloc(sizeof(*odi), GFP_KERNEL);
|
||||||
if (!odi)
|
if (!odi)
|
||||||
return ERR_PTR(-ENOMEM);
|
return ERR_PTR(-ENOMEM);
|
||||||
odi->ino = dir_ino;
|
odi->ino = dir_ino;
|
||||||
odi->gen = 0;
|
odi->gen = dir_gen;
|
||||||
odi->last_dir_index_offset = 0;
|
odi->last_dir_index_offset = 0;
|
||||||
|
|
||||||
rb_link_node(&odi->node, parent, p);
|
rb_link_node(&odi->node, parent, p);
|
||||||
@ -2889,8 +2893,8 @@ add_orphan_dir_info(struct send_ctx *sctx, u64 dir_ino)
|
|||||||
return odi;
|
return odi;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct orphan_dir_info *
|
static struct orphan_dir_info *get_orphan_dir_info(struct send_ctx *sctx,
|
||||||
get_orphan_dir_info(struct send_ctx *sctx, u64 dir_ino)
|
u64 dir_ino, u64 gen)
|
||||||
{
|
{
|
||||||
struct rb_node *n = sctx->orphan_dirs.rb_node;
|
struct rb_node *n = sctx->orphan_dirs.rb_node;
|
||||||
struct orphan_dir_info *entry;
|
struct orphan_dir_info *entry;
|
||||||
@ -2901,15 +2905,19 @@ get_orphan_dir_info(struct send_ctx *sctx, u64 dir_ino)
|
|||||||
n = n->rb_left;
|
n = n->rb_left;
|
||||||
else if (dir_ino > entry->ino)
|
else if (dir_ino > entry->ino)
|
||||||
n = n->rb_right;
|
n = n->rb_right;
|
||||||
|
else if (gen < entry->gen)
|
||||||
|
n = n->rb_left;
|
||||||
|
else if (gen > entry->gen)
|
||||||
|
n = n->rb_right;
|
||||||
else
|
else
|
||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int is_waiting_for_rm(struct send_ctx *sctx, u64 dir_ino)
|
static int is_waiting_for_rm(struct send_ctx *sctx, u64 dir_ino, u64 gen)
|
||||||
{
|
{
|
||||||
struct orphan_dir_info *odi = get_orphan_dir_info(sctx, dir_ino);
|
struct orphan_dir_info *odi = get_orphan_dir_info(sctx, dir_ino, gen);
|
||||||
|
|
||||||
return odi != NULL;
|
return odi != NULL;
|
||||||
}
|
}
|
||||||
@ -2954,7 +2962,7 @@ static int can_rmdir(struct send_ctx *sctx, u64 dir, u64 dir_gen,
|
|||||||
key.type = BTRFS_DIR_INDEX_KEY;
|
key.type = BTRFS_DIR_INDEX_KEY;
|
||||||
key.offset = 0;
|
key.offset = 0;
|
||||||
|
|
||||||
odi = get_orphan_dir_info(sctx, dir);
|
odi = get_orphan_dir_info(sctx, dir, dir_gen);
|
||||||
if (odi)
|
if (odi)
|
||||||
key.offset = odi->last_dir_index_offset;
|
key.offset = odi->last_dir_index_offset;
|
||||||
|
|
||||||
@ -2985,7 +2993,7 @@ static int can_rmdir(struct send_ctx *sctx, u64 dir, u64 dir_gen,
|
|||||||
|
|
||||||
dm = get_waiting_dir_move(sctx, loc.objectid);
|
dm = get_waiting_dir_move(sctx, loc.objectid);
|
||||||
if (dm) {
|
if (dm) {
|
||||||
odi = add_orphan_dir_info(sctx, dir);
|
odi = add_orphan_dir_info(sctx, dir, dir_gen);
|
||||||
if (IS_ERR(odi)) {
|
if (IS_ERR(odi)) {
|
||||||
ret = PTR_ERR(odi);
|
ret = PTR_ERR(odi);
|
||||||
goto out;
|
goto out;
|
||||||
@ -2993,12 +3001,13 @@ static int can_rmdir(struct send_ctx *sctx, u64 dir, u64 dir_gen,
|
|||||||
odi->gen = dir_gen;
|
odi->gen = dir_gen;
|
||||||
odi->last_dir_index_offset = found_key.offset;
|
odi->last_dir_index_offset = found_key.offset;
|
||||||
dm->rmdir_ino = dir;
|
dm->rmdir_ino = dir;
|
||||||
|
dm->rmdir_gen = dir_gen;
|
||||||
ret = 0;
|
ret = 0;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (loc.objectid > send_progress) {
|
if (loc.objectid > send_progress) {
|
||||||
odi = add_orphan_dir_info(sctx, dir);
|
odi = add_orphan_dir_info(sctx, dir, dir_gen);
|
||||||
if (IS_ERR(odi)) {
|
if (IS_ERR(odi)) {
|
||||||
ret = PTR_ERR(odi);
|
ret = PTR_ERR(odi);
|
||||||
goto out;
|
goto out;
|
||||||
@ -3038,6 +3047,7 @@ static int add_waiting_dir_move(struct send_ctx *sctx, u64 ino, bool orphanized)
|
|||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
dm->ino = ino;
|
dm->ino = ino;
|
||||||
dm->rmdir_ino = 0;
|
dm->rmdir_ino = 0;
|
||||||
|
dm->rmdir_gen = 0;
|
||||||
dm->orphanized = orphanized;
|
dm->orphanized = orphanized;
|
||||||
|
|
||||||
while (*p) {
|
while (*p) {
|
||||||
@ -3183,7 +3193,7 @@ static int path_loop(struct send_ctx *sctx, struct fs_path *name,
|
|||||||
while (ino != BTRFS_FIRST_FREE_OBJECTID) {
|
while (ino != BTRFS_FIRST_FREE_OBJECTID) {
|
||||||
fs_path_reset(name);
|
fs_path_reset(name);
|
||||||
|
|
||||||
if (is_waiting_for_rm(sctx, ino))
|
if (is_waiting_for_rm(sctx, ino, gen))
|
||||||
break;
|
break;
|
||||||
if (is_waiting_for_move(sctx, ino)) {
|
if (is_waiting_for_move(sctx, ino)) {
|
||||||
if (*ancestor_ino == 0)
|
if (*ancestor_ino == 0)
|
||||||
@ -3223,6 +3233,7 @@ static int apply_dir_move(struct send_ctx *sctx, struct pending_dir_move *pm)
|
|||||||
u64 parent_ino, parent_gen;
|
u64 parent_ino, parent_gen;
|
||||||
struct waiting_dir_move *dm = NULL;
|
struct waiting_dir_move *dm = NULL;
|
||||||
u64 rmdir_ino = 0;
|
u64 rmdir_ino = 0;
|
||||||
|
u64 rmdir_gen;
|
||||||
u64 ancestor;
|
u64 ancestor;
|
||||||
bool is_orphan;
|
bool is_orphan;
|
||||||
int ret;
|
int ret;
|
||||||
@ -3237,6 +3248,7 @@ static int apply_dir_move(struct send_ctx *sctx, struct pending_dir_move *pm)
|
|||||||
dm = get_waiting_dir_move(sctx, pm->ino);
|
dm = get_waiting_dir_move(sctx, pm->ino);
|
||||||
ASSERT(dm);
|
ASSERT(dm);
|
||||||
rmdir_ino = dm->rmdir_ino;
|
rmdir_ino = dm->rmdir_ino;
|
||||||
|
rmdir_gen = dm->rmdir_gen;
|
||||||
is_orphan = dm->orphanized;
|
is_orphan = dm->orphanized;
|
||||||
free_waiting_dir_move(sctx, dm);
|
free_waiting_dir_move(sctx, dm);
|
||||||
|
|
||||||
@ -3273,6 +3285,7 @@ static int apply_dir_move(struct send_ctx *sctx, struct pending_dir_move *pm)
|
|||||||
dm = get_waiting_dir_move(sctx, pm->ino);
|
dm = get_waiting_dir_move(sctx, pm->ino);
|
||||||
ASSERT(dm);
|
ASSERT(dm);
|
||||||
dm->rmdir_ino = rmdir_ino;
|
dm->rmdir_ino = rmdir_ino;
|
||||||
|
dm->rmdir_gen = rmdir_gen;
|
||||||
}
|
}
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@ -3291,7 +3304,7 @@ static int apply_dir_move(struct send_ctx *sctx, struct pending_dir_move *pm)
|
|||||||
struct orphan_dir_info *odi;
|
struct orphan_dir_info *odi;
|
||||||
u64 gen;
|
u64 gen;
|
||||||
|
|
||||||
odi = get_orphan_dir_info(sctx, rmdir_ino);
|
odi = get_orphan_dir_info(sctx, rmdir_ino, rmdir_gen);
|
||||||
if (!odi) {
|
if (!odi) {
|
||||||
/* already deleted */
|
/* already deleted */
|
||||||
goto finish;
|
goto finish;
|
||||||
|
@ -532,7 +532,7 @@ static void shrink_delalloc(struct btrfs_fs_info *fs_info,
|
|||||||
|
|
||||||
loops = 0;
|
loops = 0;
|
||||||
while ((delalloc_bytes || dio_bytes) && loops < 3) {
|
while ((delalloc_bytes || dio_bytes) && loops < 3) {
|
||||||
btrfs_start_delalloc_roots(fs_info, items);
|
btrfs_start_delalloc_roots(fs_info, items, true);
|
||||||
|
|
||||||
loops++;
|
loops++;
|
||||||
if (wait_ordered && !trans) {
|
if (wait_ordered && !trans) {
|
||||||
|
@ -175,7 +175,7 @@ void __btrfs_handle_fs_error(struct btrfs_fs_info *fs_info, const char *function
|
|||||||
btrfs_discard_stop(fs_info);
|
btrfs_discard_stop(fs_info);
|
||||||
|
|
||||||
/* btrfs handle error by forcing the filesystem readonly */
|
/* btrfs handle error by forcing the filesystem readonly */
|
||||||
sb->s_flags |= SB_RDONLY;
|
btrfs_set_sb_rdonly(sb);
|
||||||
btrfs_info(fs_info, "forced readonly");
|
btrfs_info(fs_info, "forced readonly");
|
||||||
/*
|
/*
|
||||||
* Note that a running device replace operation is not canceled here
|
* Note that a running device replace operation is not canceled here
|
||||||
@ -1953,7 +1953,7 @@ static int btrfs_remount(struct super_block *sb, int *flags, char *data)
|
|||||||
/* avoid complains from lockdep et al. */
|
/* avoid complains from lockdep et al. */
|
||||||
up(&fs_info->uuid_tree_rescan_sem);
|
up(&fs_info->uuid_tree_rescan_sem);
|
||||||
|
|
||||||
sb->s_flags |= SB_RDONLY;
|
btrfs_set_sb_rdonly(sb);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Setting SB_RDONLY will put the cleaner thread to
|
* Setting SB_RDONLY will put the cleaner thread to
|
||||||
@ -1964,10 +1964,42 @@ static int btrfs_remount(struct super_block *sb, int *flags, char *data)
|
|||||||
*/
|
*/
|
||||||
btrfs_delete_unused_bgs(fs_info);
|
btrfs_delete_unused_bgs(fs_info);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The cleaner task could be already running before we set the
|
||||||
|
* flag BTRFS_FS_STATE_RO (and SB_RDONLY in the superblock).
|
||||||
|
* We must make sure that after we finish the remount, i.e. after
|
||||||
|
* we call btrfs_commit_super(), the cleaner can no longer start
|
||||||
|
* a transaction - either because it was dropping a dead root,
|
||||||
|
* running delayed iputs or deleting an unused block group (the
|
||||||
|
* cleaner picked a block group from the list of unused block
|
||||||
|
* groups before we were able to in the previous call to
|
||||||
|
* btrfs_delete_unused_bgs()).
|
||||||
|
*/
|
||||||
|
wait_on_bit(&fs_info->flags, BTRFS_FS_CLEANER_RUNNING,
|
||||||
|
TASK_UNINTERRUPTIBLE);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We've set the superblock to RO mode, so we might have made
|
||||||
|
* the cleaner task sleep without running all pending delayed
|
||||||
|
* iputs. Go through all the delayed iputs here, so that if an
|
||||||
|
* unmount happens without remounting RW we don't end up at
|
||||||
|
* finishing close_ctree() with a non-empty list of delayed
|
||||||
|
* iputs.
|
||||||
|
*/
|
||||||
|
btrfs_run_delayed_iputs(fs_info);
|
||||||
|
|
||||||
btrfs_dev_replace_suspend_for_unmount(fs_info);
|
btrfs_dev_replace_suspend_for_unmount(fs_info);
|
||||||
btrfs_scrub_cancel(fs_info);
|
btrfs_scrub_cancel(fs_info);
|
||||||
btrfs_pause_balance(fs_info);
|
btrfs_pause_balance(fs_info);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Pause the qgroup rescan worker if it is running. We don't want
|
||||||
|
* it to be still running after we are in RO mode, as after that,
|
||||||
|
* by the time we unmount, it might have left a transaction open,
|
||||||
|
* so we would leak the transaction and/or crash.
|
||||||
|
*/
|
||||||
|
btrfs_qgroup_wait_for_completion(fs_info, false);
|
||||||
|
|
||||||
ret = btrfs_commit_super(fs_info);
|
ret = btrfs_commit_super(fs_info);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto restore;
|
goto restore;
|
||||||
@ -2006,7 +2038,7 @@ static int btrfs_remount(struct super_block *sb, int *flags, char *data)
|
|||||||
if (ret)
|
if (ret)
|
||||||
goto restore;
|
goto restore;
|
||||||
|
|
||||||
sb->s_flags &= ~SB_RDONLY;
|
btrfs_clear_sb_rdonly(sb);
|
||||||
|
|
||||||
set_bit(BTRFS_FS_OPEN, &fs_info->flags);
|
set_bit(BTRFS_FS_OPEN, &fs_info->flags);
|
||||||
}
|
}
|
||||||
@ -2028,6 +2060,8 @@ restore:
|
|||||||
/* We've hit an error - don't reset SB_RDONLY */
|
/* We've hit an error - don't reset SB_RDONLY */
|
||||||
if (sb_rdonly(sb))
|
if (sb_rdonly(sb))
|
||||||
old_flags |= SB_RDONLY;
|
old_flags |= SB_RDONLY;
|
||||||
|
if (!(old_flags & SB_RDONLY))
|
||||||
|
clear_bit(BTRFS_FS_STATE_RO, &fs_info->fs_state);
|
||||||
sb->s_flags = old_flags;
|
sb->s_flags = old_flags;
|
||||||
fs_info->mount_opt = old_opts;
|
fs_info->mount_opt = old_opts;
|
||||||
fs_info->compress_type = old_compress_type;
|
fs_info->compress_type = old_compress_type;
|
||||||
|
@ -55,8 +55,14 @@ struct inode *btrfs_new_test_inode(void)
|
|||||||
struct inode *inode;
|
struct inode *inode;
|
||||||
|
|
||||||
inode = new_inode(test_mnt->mnt_sb);
|
inode = new_inode(test_mnt->mnt_sb);
|
||||||
if (inode)
|
if (!inode)
|
||||||
inode_init_owner(inode, NULL, S_IFREG);
|
return NULL;
|
||||||
|
|
||||||
|
inode->i_mode = S_IFREG;
|
||||||
|
BTRFS_I(inode)->location.type = BTRFS_INODE_ITEM_KEY;
|
||||||
|
BTRFS_I(inode)->location.objectid = BTRFS_FIRST_FREE_OBJECTID;
|
||||||
|
BTRFS_I(inode)->location.offset = 0;
|
||||||
|
inode_init_owner(inode, NULL, S_IFREG);
|
||||||
|
|
||||||
return inode;
|
return inode;
|
||||||
}
|
}
|
||||||
|
@ -232,11 +232,6 @@ static noinline int test_btrfs_get_extent(u32 sectorsize, u32 nodesize)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
inode->i_mode = S_IFREG;
|
|
||||||
BTRFS_I(inode)->location.type = BTRFS_INODE_ITEM_KEY;
|
|
||||||
BTRFS_I(inode)->location.objectid = BTRFS_FIRST_FREE_OBJECTID;
|
|
||||||
BTRFS_I(inode)->location.offset = 0;
|
|
||||||
|
|
||||||
fs_info = btrfs_alloc_dummy_fs_info(nodesize, sectorsize);
|
fs_info = btrfs_alloc_dummy_fs_info(nodesize, sectorsize);
|
||||||
if (!fs_info) {
|
if (!fs_info) {
|
||||||
test_std_err(TEST_ALLOC_FS_INFO);
|
test_std_err(TEST_ALLOC_FS_INFO);
|
||||||
@ -835,10 +830,6 @@ static int test_hole_first(u32 sectorsize, u32 nodesize)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
BTRFS_I(inode)->location.type = BTRFS_INODE_ITEM_KEY;
|
|
||||||
BTRFS_I(inode)->location.objectid = BTRFS_FIRST_FREE_OBJECTID;
|
|
||||||
BTRFS_I(inode)->location.offset = 0;
|
|
||||||
|
|
||||||
fs_info = btrfs_alloc_dummy_fs_info(nodesize, sectorsize);
|
fs_info = btrfs_alloc_dummy_fs_info(nodesize, sectorsize);
|
||||||
if (!fs_info) {
|
if (!fs_info) {
|
||||||
test_std_err(TEST_ALLOC_FS_INFO);
|
test_std_err(TEST_ALLOC_FS_INFO);
|
||||||
|
@ -2592,7 +2592,7 @@ int btrfs_init_new_device(struct btrfs_fs_info *fs_info, const char *device_path
|
|||||||
set_blocksize(device->bdev, BTRFS_BDEV_BLOCKSIZE);
|
set_blocksize(device->bdev, BTRFS_BDEV_BLOCKSIZE);
|
||||||
|
|
||||||
if (seeding_dev) {
|
if (seeding_dev) {
|
||||||
sb->s_flags &= ~SB_RDONLY;
|
btrfs_clear_sb_rdonly(sb);
|
||||||
ret = btrfs_prepare_sprout(fs_info);
|
ret = btrfs_prepare_sprout(fs_info);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
btrfs_abort_transaction(trans, ret);
|
btrfs_abort_transaction(trans, ret);
|
||||||
@ -2728,7 +2728,7 @@ error_sysfs:
|
|||||||
mutex_unlock(&fs_info->fs_devices->device_list_mutex);
|
mutex_unlock(&fs_info->fs_devices->device_list_mutex);
|
||||||
error_trans:
|
error_trans:
|
||||||
if (seeding_dev)
|
if (seeding_dev)
|
||||||
sb->s_flags |= SB_RDONLY;
|
btrfs_set_sb_rdonly(sb);
|
||||||
if (trans)
|
if (trans)
|
||||||
btrfs_end_transaction(trans);
|
btrfs_end_transaction(trans);
|
||||||
error_free_zone:
|
error_free_zone:
|
||||||
|
14
fs/select.c
14
fs/select.c
@ -1011,14 +1011,17 @@ static int do_sys_poll(struct pollfd __user *ufds, unsigned int nfds,
|
|||||||
fdcount = do_poll(head, &table, end_time);
|
fdcount = do_poll(head, &table, end_time);
|
||||||
poll_freewait(&table);
|
poll_freewait(&table);
|
||||||
|
|
||||||
|
if (!user_write_access_begin(ufds, nfds * sizeof(*ufds)))
|
||||||
|
goto out_fds;
|
||||||
|
|
||||||
for (walk = head; walk; walk = walk->next) {
|
for (walk = head; walk; walk = walk->next) {
|
||||||
struct pollfd *fds = walk->entries;
|
struct pollfd *fds = walk->entries;
|
||||||
int j;
|
int j;
|
||||||
|
|
||||||
for (j = 0; j < walk->len; j++, ufds++)
|
for (j = walk->len; j; fds++, ufds++, j--)
|
||||||
if (__put_user(fds[j].revents, &ufds->revents))
|
unsafe_put_user(fds->revents, &ufds->revents, Efault);
|
||||||
goto out_fds;
|
|
||||||
}
|
}
|
||||||
|
user_write_access_end();
|
||||||
|
|
||||||
err = fdcount;
|
err = fdcount;
|
||||||
out_fds:
|
out_fds:
|
||||||
@ -1030,6 +1033,11 @@ out_fds:
|
|||||||
}
|
}
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
|
Efault:
|
||||||
|
user_write_access_end();
|
||||||
|
err = -EFAULT;
|
||||||
|
goto out_fds;
|
||||||
}
|
}
|
||||||
|
|
||||||
static long do_restart_poll(struct restart_block *restart_block)
|
static long do_restart_poll(struct restart_block *restart_block)
|
||||||
|
@ -186,12 +186,9 @@ extern int braille_register_console(struct console *, int index,
|
|||||||
extern int braille_unregister_console(struct console *);
|
extern int braille_unregister_console(struct console *);
|
||||||
#ifdef CONFIG_TTY
|
#ifdef CONFIG_TTY
|
||||||
extern void console_sysfs_notify(void);
|
extern void console_sysfs_notify(void);
|
||||||
extern void register_ttynull_console(void);
|
|
||||||
#else
|
#else
|
||||||
static inline void console_sysfs_notify(void)
|
static inline void console_sysfs_notify(void)
|
||||||
{ }
|
{ }
|
||||||
static inline void register_ttynull_console(void)
|
|
||||||
{ }
|
|
||||||
#endif
|
#endif
|
||||||
extern bool console_suspend_enabled;
|
extern bool console_suspend_enabled;
|
||||||
|
|
||||||
|
@ -1280,7 +1280,8 @@ struct mlx5_ifc_cmd_hca_cap_bits {
|
|||||||
u8 ece_support[0x1];
|
u8 ece_support[0x1];
|
||||||
u8 reserved_at_a4[0x7];
|
u8 reserved_at_a4[0x7];
|
||||||
u8 log_max_srq[0x5];
|
u8 log_max_srq[0x5];
|
||||||
u8 reserved_at_b0[0x2];
|
u8 reserved_at_b0[0x1];
|
||||||
|
u8 uplink_follow[0x1];
|
||||||
u8 ts_cqe_to_dest_cqn[0x1];
|
u8 ts_cqe_to_dest_cqn[0x1];
|
||||||
u8 reserved_at_b3[0xd];
|
u8 reserved_at_b3[0xd];
|
||||||
|
|
||||||
|
@ -75,8 +75,9 @@ struct rtnl_link_stats {
|
|||||||
*
|
*
|
||||||
* @rx_dropped: Number of packets received but not processed,
|
* @rx_dropped: Number of packets received but not processed,
|
||||||
* e.g. due to lack of resources or unsupported protocol.
|
* e.g. due to lack of resources or unsupported protocol.
|
||||||
* For hardware interfaces this counter should not include packets
|
* For hardware interfaces this counter may include packets discarded
|
||||||
* dropped by the device which are counted separately in
|
* due to L2 address filtering but should not include packets dropped
|
||||||
|
* by the device due to buffer exhaustion which are counted separately in
|
||||||
* @rx_missed_errors (since procfs folds those two counters together).
|
* @rx_missed_errors (since procfs folds those two counters together).
|
||||||
*
|
*
|
||||||
* @tx_dropped: Number of packets dropped on their way to transmission,
|
* @tx_dropped: Number of packets dropped on their way to transmission,
|
||||||
|
10
init/main.c
10
init/main.c
@ -1480,14 +1480,8 @@ void __init console_on_rootfs(void)
|
|||||||
struct file *file = filp_open("/dev/console", O_RDWR, 0);
|
struct file *file = filp_open("/dev/console", O_RDWR, 0);
|
||||||
|
|
||||||
if (IS_ERR(file)) {
|
if (IS_ERR(file)) {
|
||||||
pr_err("Warning: unable to open an initial console. Fallback to ttynull.\n");
|
pr_err("Warning: unable to open an initial console.\n");
|
||||||
register_ttynull_console();
|
return;
|
||||||
|
|
||||||
file = filp_open("/dev/console", O_RDWR, 0);
|
|
||||||
if (IS_ERR(file)) {
|
|
||||||
pr_err("Warning: Failed to add ttynull console. No stdin, stdout, and stderr for the init process!\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
init_dup(file);
|
init_dup(file);
|
||||||
init_dup(file);
|
init_dup(file);
|
||||||
|
@ -159,6 +159,7 @@ again:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* set info->task and info->tid */
|
/* set info->task and info->tid */
|
||||||
|
info->task = curr_task;
|
||||||
if (curr_tid == info->tid) {
|
if (curr_tid == info->tid) {
|
||||||
curr_fd = info->fd;
|
curr_fd = info->fd;
|
||||||
} else {
|
} else {
|
||||||
|
@ -284,7 +284,8 @@ static int register_vlan_device(struct net_device *real_dev, u16 vlan_id)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
out_free_newdev:
|
out_free_newdev:
|
||||||
if (new_dev->reg_state == NETREG_UNINITIALIZED)
|
if (new_dev->reg_state == NETREG_UNINITIALIZED ||
|
||||||
|
new_dev->reg_state == NETREG_UNREGISTERED)
|
||||||
free_netdev(new_dev);
|
free_netdev(new_dev);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
@ -302,7 +302,7 @@ static int __ip_finish_output(struct net *net, struct sock *sk, struct sk_buff *
|
|||||||
if (skb_is_gso(skb))
|
if (skb_is_gso(skb))
|
||||||
return ip_finish_output_gso(net, sk, skb, mtu);
|
return ip_finish_output_gso(net, sk, skb, mtu);
|
||||||
|
|
||||||
if (skb->len > mtu || (IPCB(skb)->flags & IPSKB_FRAG_PMTU))
|
if (skb->len > mtu || IPCB(skb)->frag_max_size)
|
||||||
return ip_fragment(net, sk, skb, mtu, ip_finish_output2);
|
return ip_fragment(net, sk, skb, mtu, ip_finish_output2);
|
||||||
|
|
||||||
return ip_finish_output2(net, sk, skb);
|
return ip_finish_output2(net, sk, skb);
|
||||||
|
@ -759,8 +759,11 @@ void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev,
|
|||||||
goto tx_error;
|
goto tx_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tnl_update_pmtu(dev, skb, rt, tnl_params->frag_off, inner_iph,
|
df = tnl_params->frag_off;
|
||||||
0, 0, false)) {
|
if (skb->protocol == htons(ETH_P_IP) && !tunnel->ignore_df)
|
||||||
|
df |= (inner_iph->frag_off & htons(IP_DF));
|
||||||
|
|
||||||
|
if (tnl_update_pmtu(dev, skb, rt, df, inner_iph, 0, 0, false)) {
|
||||||
ip_rt_put(rt);
|
ip_rt_put(rt);
|
||||||
goto tx_error;
|
goto tx_error;
|
||||||
}
|
}
|
||||||
@ -788,10 +791,6 @@ void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev,
|
|||||||
ttl = ip4_dst_hoplimit(&rt->dst);
|
ttl = ip4_dst_hoplimit(&rt->dst);
|
||||||
}
|
}
|
||||||
|
|
||||||
df = tnl_params->frag_off;
|
|
||||||
if (skb->protocol == htons(ETH_P_IP) && !tunnel->ignore_df)
|
|
||||||
df |= (inner_iph->frag_off&htons(IP_DF));
|
|
||||||
|
|
||||||
max_headroom = LL_RESERVED_SPACE(rt->dst.dev) + sizeof(struct iphdr)
|
max_headroom = LL_RESERVED_SPACE(rt->dst.dev) + sizeof(struct iphdr)
|
||||||
+ rt->dst.header_len + ip_encap_hlen(&tunnel->encap);
|
+ rt->dst.header_len + ip_encap_hlen(&tunnel->encap);
|
||||||
if (max_headroom > dev->needed_headroom)
|
if (max_headroom > dev->needed_headroom)
|
||||||
|
@ -627,7 +627,7 @@ static int nh_check_attr_group(struct net *net, struct nlattr *tb[],
|
|||||||
for (i = NHA_GROUP_TYPE + 1; i < __NHA_MAX; ++i) {
|
for (i = NHA_GROUP_TYPE + 1; i < __NHA_MAX; ++i) {
|
||||||
if (!tb[i])
|
if (!tb[i])
|
||||||
continue;
|
continue;
|
||||||
if (tb[NHA_FDB])
|
if (i == NHA_FDB)
|
||||||
continue;
|
continue;
|
||||||
NL_SET_ERR_MSG(extack,
|
NL_SET_ERR_MSG(extack,
|
||||||
"No other attributes can be set in nexthop groups");
|
"No other attributes can be set in nexthop groups");
|
||||||
@ -1459,8 +1459,10 @@ static struct nexthop *nexthop_create_group(struct net *net,
|
|||||||
return nh;
|
return nh;
|
||||||
|
|
||||||
out_no_nh:
|
out_no_nh:
|
||||||
for (; i >= 0; --i)
|
for (i--; i >= 0; --i) {
|
||||||
|
list_del(&nhg->nh_entries[i].nh_list);
|
||||||
nexthop_put(nhg->nh_entries[i].nh);
|
nexthop_put(nhg->nh_entries[i].nh);
|
||||||
|
}
|
||||||
|
|
||||||
kfree(nhg->spare);
|
kfree(nhg->spare);
|
||||||
kfree(nhg);
|
kfree(nhg);
|
||||||
|
@ -1025,6 +1025,8 @@ static void fib6_purge_rt(struct fib6_info *rt, struct fib6_node *fn,
|
|||||||
{
|
{
|
||||||
struct fib6_table *table = rt->fib6_table;
|
struct fib6_table *table = rt->fib6_table;
|
||||||
|
|
||||||
|
/* Flush all cached dst in exception table */
|
||||||
|
rt6_flush_exceptions(rt);
|
||||||
fib6_drop_pcpu_from(rt, table);
|
fib6_drop_pcpu_from(rt, table);
|
||||||
|
|
||||||
if (rt->nh && !list_empty(&rt->nh_list))
|
if (rt->nh && !list_empty(&rt->nh_list))
|
||||||
@ -1927,9 +1929,6 @@ static void fib6_del_route(struct fib6_table *table, struct fib6_node *fn,
|
|||||||
net->ipv6.rt6_stats->fib_rt_entries--;
|
net->ipv6.rt6_stats->fib_rt_entries--;
|
||||||
net->ipv6.rt6_stats->fib_discarded_routes++;
|
net->ipv6.rt6_stats->fib_discarded_routes++;
|
||||||
|
|
||||||
/* Flush all cached dst in exception table */
|
|
||||||
rt6_flush_exceptions(rt);
|
|
||||||
|
|
||||||
/* Reset round-robin state, if necessary */
|
/* Reset round-robin state, if necessary */
|
||||||
if (rcu_access_pointer(fn->rr_ptr) == rt)
|
if (rcu_access_pointer(fn->rr_ptr) == rt)
|
||||||
fn->rr_ptr = NULL;
|
fn->rr_ptr = NULL;
|
||||||
|
@ -755,7 +755,7 @@ static void qrtr_ns_data_ready(struct sock *sk)
|
|||||||
queue_work(qrtr_ns.workqueue, &qrtr_ns.work);
|
queue_work(qrtr_ns.workqueue, &qrtr_ns.work);
|
||||||
}
|
}
|
||||||
|
|
||||||
void qrtr_ns_init(void)
|
int qrtr_ns_init(void)
|
||||||
{
|
{
|
||||||
struct sockaddr_qrtr sq;
|
struct sockaddr_qrtr sq;
|
||||||
int ret;
|
int ret;
|
||||||
@ -766,7 +766,7 @@ void qrtr_ns_init(void)
|
|||||||
ret = sock_create_kern(&init_net, AF_QIPCRTR, SOCK_DGRAM,
|
ret = sock_create_kern(&init_net, AF_QIPCRTR, SOCK_DGRAM,
|
||||||
PF_QIPCRTR, &qrtr_ns.sock);
|
PF_QIPCRTR, &qrtr_ns.sock);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return;
|
return ret;
|
||||||
|
|
||||||
ret = kernel_getsockname(qrtr_ns.sock, (struct sockaddr *)&sq);
|
ret = kernel_getsockname(qrtr_ns.sock, (struct sockaddr *)&sq);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
@ -797,12 +797,13 @@ void qrtr_ns_init(void)
|
|||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto err_wq;
|
goto err_wq;
|
||||||
|
|
||||||
return;
|
return 0;
|
||||||
|
|
||||||
err_wq:
|
err_wq:
|
||||||
destroy_workqueue(qrtr_ns.workqueue);
|
destroy_workqueue(qrtr_ns.workqueue);
|
||||||
err_sock:
|
err_sock:
|
||||||
sock_release(qrtr_ns.sock);
|
sock_release(qrtr_ns.sock);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(qrtr_ns_init);
|
EXPORT_SYMBOL_GPL(qrtr_ns_init);
|
||||||
|
|
||||||
|
@ -1287,13 +1287,19 @@ static int __init qrtr_proto_init(void)
|
|||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
rc = sock_register(&qrtr_family);
|
rc = sock_register(&qrtr_family);
|
||||||
if (rc) {
|
if (rc)
|
||||||
proto_unregister(&qrtr_proto);
|
goto err_proto;
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
qrtr_ns_init();
|
rc = qrtr_ns_init();
|
||||||
|
if (rc)
|
||||||
|
goto err_sock;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
err_sock:
|
||||||
|
sock_unregister(qrtr_family.family);
|
||||||
|
err_proto:
|
||||||
|
proto_unregister(&qrtr_proto);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
postcore_initcall(qrtr_proto_init);
|
postcore_initcall(qrtr_proto_init);
|
||||||
|
@ -29,7 +29,7 @@ void qrtr_endpoint_unregister(struct qrtr_endpoint *ep);
|
|||||||
|
|
||||||
int qrtr_endpoint_post(struct qrtr_endpoint *ep, const void *data, size_t len);
|
int qrtr_endpoint_post(struct qrtr_endpoint *ep, const void *data, size_t len);
|
||||||
|
|
||||||
void qrtr_ns_init(void);
|
int qrtr_ns_init(void);
|
||||||
|
|
||||||
void qrtr_ns_remove(void);
|
void qrtr_ns_remove(void);
|
||||||
|
|
||||||
|
@ -21,6 +21,7 @@ config CFG80211
|
|||||||
tristate "cfg80211 - wireless configuration API"
|
tristate "cfg80211 - wireless configuration API"
|
||||||
depends on RFKILL || !RFKILL
|
depends on RFKILL || !RFKILL
|
||||||
select FW_LOADER
|
select FW_LOADER
|
||||||
|
select CRC32
|
||||||
# may need to update this when certificates are changed and are
|
# may need to update this when certificates are changed and are
|
||||||
# using a different algorithm, though right now they shouldn't
|
# using a different algorithm, though right now they shouldn't
|
||||||
# (this is here rather than below to allow it to be a module)
|
# (this is here rather than below to allow it to be a module)
|
||||||
|
@ -22,9 +22,9 @@ always-y += $(GCC_PLUGIN)
|
|||||||
GCC_PLUGINS_DIR = $(shell $(CC) -print-file-name=plugin)
|
GCC_PLUGINS_DIR = $(shell $(CC) -print-file-name=plugin)
|
||||||
|
|
||||||
plugin_cxxflags = -Wp,-MMD,$(depfile) $(KBUILD_HOSTCXXFLAGS) -fPIC \
|
plugin_cxxflags = -Wp,-MMD,$(depfile) $(KBUILD_HOSTCXXFLAGS) -fPIC \
|
||||||
-I $(GCC_PLUGINS_DIR)/include -I $(obj) -std=gnu++98 \
|
-I $(GCC_PLUGINS_DIR)/include -I $(obj) -std=gnu++11 \
|
||||||
-fno-rtti -fno-exceptions -fasynchronous-unwind-tables \
|
-fno-rtti -fno-exceptions -fasynchronous-unwind-tables \
|
||||||
-ggdb -Wno-narrowing -Wno-unused-variable -Wno-c++11-compat \
|
-ggdb -Wno-narrowing -Wno-unused-variable \
|
||||||
-Wno-format-diag
|
-Wno-format-diag
|
||||||
|
|
||||||
plugin_ldflags = -shared
|
plugin_ldflags = -shared
|
||||||
|
@ -2220,8 +2220,6 @@ static const struct snd_pci_quirk power_save_denylist[] = {
|
|||||||
SND_PCI_QUIRK(0x1849, 0x7662, "Asrock H81M-HDS", 0),
|
SND_PCI_QUIRK(0x1849, 0x7662, "Asrock H81M-HDS", 0),
|
||||||
/* https://bugzilla.redhat.com/show_bug.cgi?id=1525104 */
|
/* https://bugzilla.redhat.com/show_bug.cgi?id=1525104 */
|
||||||
SND_PCI_QUIRK(0x1043, 0x8733, "Asus Prime X370-Pro", 0),
|
SND_PCI_QUIRK(0x1043, 0x8733, "Asus Prime X370-Pro", 0),
|
||||||
/* https://bugzilla.redhat.com/show_bug.cgi?id=1581607 */
|
|
||||||
SND_PCI_QUIRK(0x1558, 0x3501, "Clevo W35xSS_370SS", 0),
|
|
||||||
/* https://bugzilla.redhat.com/show_bug.cgi?id=1525104 */
|
/* https://bugzilla.redhat.com/show_bug.cgi?id=1525104 */
|
||||||
SND_PCI_QUIRK(0x1558, 0x6504, "Clevo W65_67SB", 0),
|
SND_PCI_QUIRK(0x1558, 0x6504, "Clevo W65_67SB", 0),
|
||||||
/* https://bugzilla.redhat.com/show_bug.cgi?id=1525104 */
|
/* https://bugzilla.redhat.com/show_bug.cgi?id=1525104 */
|
||||||
|
@ -1070,6 +1070,7 @@ static int patch_conexant_auto(struct hda_codec *codec)
|
|||||||
static const struct hda_device_id snd_hda_id_conexant[] = {
|
static const struct hda_device_id snd_hda_id_conexant[] = {
|
||||||
HDA_CODEC_ENTRY(0x14f11f86, "CX8070", patch_conexant_auto),
|
HDA_CODEC_ENTRY(0x14f11f86, "CX8070", patch_conexant_auto),
|
||||||
HDA_CODEC_ENTRY(0x14f12008, "CX8200", patch_conexant_auto),
|
HDA_CODEC_ENTRY(0x14f12008, "CX8200", patch_conexant_auto),
|
||||||
|
HDA_CODEC_ENTRY(0x14f120d0, "CX11970", patch_conexant_auto),
|
||||||
HDA_CODEC_ENTRY(0x14f15045, "CX20549 (Venice)", patch_conexant_auto),
|
HDA_CODEC_ENTRY(0x14f15045, "CX20549 (Venice)", patch_conexant_auto),
|
||||||
HDA_CODEC_ENTRY(0x14f15047, "CX20551 (Waikiki)", patch_conexant_auto),
|
HDA_CODEC_ENTRY(0x14f15047, "CX20551 (Waikiki)", patch_conexant_auto),
|
||||||
HDA_CODEC_ENTRY(0x14f15051, "CX20561 (Hermosa)", patch_conexant_auto),
|
HDA_CODEC_ENTRY(0x14f15051, "CX20561 (Hermosa)", patch_conexant_auto),
|
||||||
|
@ -1733,7 +1733,7 @@ static void silent_stream_disable(struct hda_codec *codec,
|
|||||||
per_pin->silent_stream = false;
|
per_pin->silent_stream = false;
|
||||||
|
|
||||||
unlock_out:
|
unlock_out:
|
||||||
mutex_unlock(&spec->pcm_lock);
|
mutex_unlock(&per_pin->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* update ELD and jack state via audio component */
|
/* update ELD and jack state via audio component */
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user