mirror of
https://github.com/armbian/linux-cix.git
synced 2026-01-06 12:30:45 -08:00
Merge tag 'net-6.6-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net
Pull networking fixes from Jakub Kicinski:
"Including fixes from Bluetooth, netfilter, BPF and WiFi.
I didn't collect precise data but feels like we've got a lot of 6.5
fixes here. WiFi fixes are most user-awaited.
Current release - regressions:
- Bluetooth: fix hci_link_tx_to RCU lock usage
Current release - new code bugs:
- bpf: mprog: fix maximum program check on mprog attachment
- eth: ti: icssg-prueth: fix signedness bug in prueth_init_tx_chns()
Previous releases - regressions:
- ipv6: tcp: add a missing nf_reset_ct() in 3WHS handling
- vringh: don't use vringh_kiov_advance() in vringh_iov_xfer(), it
doesn't handle zero length like we expected
- wifi:
- cfg80211: fix cqm_config access race, fix crashes with brcmfmac
- iwlwifi: mvm: handle PS changes in vif_cfg_changed
- mac80211: fix mesh id corruption on 32 bit systems
- mt76: mt76x02: fix MT76x0 external LNA gain handling
- Bluetooth: fix handling of HCI_QUIRK_STRICT_DUPLICATE_FILTER
- l2tp: fix handling of transhdrlen in __ip{,6}_append_data()
- dsa: mv88e6xxx: avoid EEPROM timeout when EEPROM is absent
- eth: stmmac: fix the incorrect parameter after refactoring
Previous releases - always broken:
- net: replace calls to sock->ops->connect() with kernel_connect(),
prevent address rewrite in kernel_bind(); otherwise BPF hooks may
modify arguments, unexpectedly to the caller
- tcp: fix delayed ACKs when reads and writes align with MSS
- bpf:
- verifier: unconditionally reset backtrack_state masks on global
func exit
- s390: let arch_prepare_bpf_trampoline return program size, fix
struct_ops offsets
- sockmap: fix accounting of available bytes in presence of PEEKs
- sockmap: reject sk_msg egress redirects to non-TCP sockets
- ipv4/fib: send netlink notify when delete source address routes
- ethtool: plca: fix width of reads when parsing netlink commands
- netfilter: nft_payload: rebuild vlan header on h_proto access
- Bluetooth: hci_codec: fix leaking memory of local_codecs
- eth: intel: ice: always add legacy 32byte RXDID in supported_rxdids
- eth: stmmac:
- dwmac-stm32: fix resume on STM32 MCU
- remove buggy and unneeded stmmac_poll_controller, depend on NAPI
- ibmveth: always recompute TCP pseudo-header checksum, fix use of
the driver with Open vSwitch
- wifi:
- rtw88: rtw8723d: fix MAC address offset in EEPROM
- mt76: fix lock dependency problem for wed_lock
- mwifiex: sanity check data reported by the device
- iwlwifi: ensure ack flag is properly cleared
- iwlwifi: mvm: fix a memory corruption due to bad pointer arithm
- iwlwifi: mvm: fix incorrect usage of scan API
Misc:
- wifi: mac80211: work around Cisco AP 9115 VHT MPDU length"
* tag 'net-6.6-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net: (99 commits)
MAINTAINERS: update Matthieu's email address
mptcp: userspace pm allow creating id 0 subflow
mptcp: fix delegated action races
net: stmmac: remove unneeded stmmac_poll_controller
net: lan743x: also select PHYLIB
net: ethernet: mediatek: disable irq before schedule napi
net: mana: Fix oversized sge0 for GSO packets
net: mana: Fix the tso_bytes calculation
net: mana: Fix TX CQE error handling
netlink: annotate data-races around sk->sk_err
sctp: update hb timer immediately after users change hb_interval
sctp: update transport state when processing a dupcook packet
tcp: fix delayed ACKs for MSS boundary condition
tcp: fix quick-ack counting to count actual ACKs of new data
page_pool: fix documentation typos
tipc: fix a potential deadlock on &tx->lock
net: stmmac: dwmac-stm32: fix resume on STM32 MCU
ipv4: Set offload_failed flag in fibmatch results
netfilter: nf_tables: nft_set_rbtree: fix spurious insertion failure
netfilter: nf_tables: Deduplicate nft_register_obj audit logs
...
This commit is contained in:
1
.mailmap
1
.mailmap
@@ -377,6 +377,7 @@ Matthew Wilcox <willy@infradead.org> <willy@debian.org>
|
||||
Matthew Wilcox <willy@infradead.org> <willy@linux.intel.com>
|
||||
Matthew Wilcox <willy@infradead.org> <willy@parisc-linux.org>
|
||||
Matthias Fuchs <socketcan@esd.eu> <matthias.fuchs@esd.eu>
|
||||
Matthieu Baerts <matttbe@kernel.org> <matthieu.baerts@tessares.net>
|
||||
Matthieu CASTET <castet.matthieu@free.fr>
|
||||
Matti Vaittinen <mazziesaccount@gmail.com> <matti.vaittinen@fi.rohmeurope.com>
|
||||
Matt Ranostay <matt.ranostay@konsulko.com> <matt@ranostay.consulting>
|
||||
|
||||
12
MAINTAINERS
12
MAINTAINERS
@@ -470,7 +470,6 @@ F: drivers/hwmon/adm1029.c
|
||||
ADM8211 WIRELESS DRIVER
|
||||
L: linux-wireless@vger.kernel.org
|
||||
S: Orphan
|
||||
W: https://wireless.wiki.kernel.org/
|
||||
F: drivers/net/wireless/admtek/adm8211.*
|
||||
|
||||
ADP1653 FLASH CONTROLLER DRIVER
|
||||
@@ -9531,10 +9530,8 @@ F: Documentation/devicetree/bindings/iio/pressure/honeywell,mprls0025pa.yaml
|
||||
F: drivers/iio/pressure/mprls0025pa.c
|
||||
|
||||
HOST AP DRIVER
|
||||
M: Jouni Malinen <j@w1.fi>
|
||||
L: linux-wireless@vger.kernel.org
|
||||
S: Obsolete
|
||||
W: http://w1.fi/hostap-driver.html
|
||||
F: drivers/net/wireless/intersil/hostap/
|
||||
|
||||
HP BIOSCFG DRIVER
|
||||
@@ -14947,7 +14944,7 @@ K: macsec
|
||||
K: \bmdo_
|
||||
|
||||
NETWORKING [MPTCP]
|
||||
M: Matthieu Baerts <matthieu.baerts@tessares.net>
|
||||
M: Matthieu Baerts <matttbe@kernel.org>
|
||||
M: Mat Martineau <martineau@kernel.org>
|
||||
L: netdev@vger.kernel.org
|
||||
L: mptcp@lists.linux.dev
|
||||
@@ -17602,6 +17599,7 @@ M: Kalle Valo <kvalo@kernel.org>
|
||||
M: Jeff Johnson <quic_jjohnson@quicinc.com>
|
||||
L: ath12k@lists.infradead.org
|
||||
S: Supported
|
||||
W: https://wireless.wiki.kernel.org/en/users/Drivers/ath12k
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git
|
||||
F: drivers/net/wireless/ath/ath12k/
|
||||
|
||||
@@ -18132,8 +18130,6 @@ REALTEK WIRELESS DRIVER (rtlwifi family)
|
||||
M: Ping-Ke Shih <pkshih@realtek.com>
|
||||
L: linux-wireless@vger.kernel.org
|
||||
S: Maintained
|
||||
W: https://wireless.wiki.kernel.org/
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-testing.git
|
||||
F: drivers/net/wireless/realtek/rtlwifi/
|
||||
|
||||
REALTEK WIRELESS DRIVER (rtw88)
|
||||
@@ -18661,7 +18657,6 @@ F: drivers/media/dvb-frontends/rtl2832_sdr*
|
||||
RTL8180 WIRELESS DRIVER
|
||||
L: linux-wireless@vger.kernel.org
|
||||
S: Orphan
|
||||
W: https://wireless.wiki.kernel.org/
|
||||
F: drivers/net/wireless/realtek/rtl818x/rtl8180/
|
||||
|
||||
RTL8187 WIRELESS DRIVER
|
||||
@@ -18669,14 +18664,12 @@ M: Hin-Tak Leung <hintak.leung@gmail.com>
|
||||
M: Larry Finger <Larry.Finger@lwfinger.net>
|
||||
L: linux-wireless@vger.kernel.org
|
||||
S: Maintained
|
||||
W: https://wireless.wiki.kernel.org/
|
||||
F: drivers/net/wireless/realtek/rtl818x/rtl8187/
|
||||
|
||||
RTL8XXXU WIRELESS DRIVER (rtl8xxxu)
|
||||
M: Jes Sorensen <Jes.Sorensen@gmail.com>
|
||||
L: linux-wireless@vger.kernel.org
|
||||
S: Maintained
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/jes/linux.git rtl8xxxu-devel
|
||||
F: drivers/net/wireless/realtek/rtl8xxxu/
|
||||
|
||||
RTRS TRANSPORT DRIVERS
|
||||
@@ -21658,7 +21651,6 @@ L: linux-wireless@vger.kernel.org
|
||||
S: Orphan
|
||||
W: https://wireless.wiki.kernel.org/en/users/Drivers/wl12xx
|
||||
W: https://wireless.wiki.kernel.org/en/users/Drivers/wl1251
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/luca/wl12xx.git
|
||||
F: drivers/net/wireless/ti/
|
||||
|
||||
TIMEKEEPING, CLOCKSOURCE CORE, NTP, ALARMTIMER
|
||||
|
||||
@@ -2513,7 +2513,7 @@ int arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *image,
|
||||
return -E2BIG;
|
||||
}
|
||||
|
||||
return ret;
|
||||
return tjit.common.prg;
|
||||
}
|
||||
|
||||
bool bpf_jit_supports_subprog_tailcalls(void)
|
||||
|
||||
@@ -4419,6 +4419,7 @@ static int btusb_probe(struct usb_interface *intf,
|
||||
|
||||
if (id->driver_info & BTUSB_QCA_ROME) {
|
||||
data->setup_on_usb = btusb_setup_qca;
|
||||
hdev->shutdown = btusb_shutdown_qca;
|
||||
hdev->set_bdaddr = btusb_set_bdaddr_ath3012;
|
||||
hdev->cmd_timeout = btusb_qca_cmd_timeout;
|
||||
set_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks);
|
||||
|
||||
@@ -558,6 +558,9 @@ int k3_udma_glue_tx_get_irq(struct k3_udma_glue_tx_channel *tx_chn)
|
||||
tx_chn->virq = k3_ringacc_get_ring_irq_num(tx_chn->ringtxcq);
|
||||
}
|
||||
|
||||
if (!tx_chn->virq)
|
||||
return -ENXIO;
|
||||
|
||||
return tx_chn->virq;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(k3_udma_glue_tx_get_irq);
|
||||
|
||||
@@ -2958,14 +2958,16 @@ static void mv88e6xxx_hardware_reset(struct mv88e6xxx_chip *chip)
|
||||
* from the wrong location resulting in the switch booting
|
||||
* to wrong mode and inoperable.
|
||||
*/
|
||||
mv88e6xxx_g1_wait_eeprom_done(chip);
|
||||
if (chip->info->ops->get_eeprom)
|
||||
mv88e6xxx_g2_eeprom_wait(chip);
|
||||
|
||||
gpiod_set_value_cansleep(gpiod, 1);
|
||||
usleep_range(10000, 20000);
|
||||
gpiod_set_value_cansleep(gpiod, 0);
|
||||
usleep_range(10000, 20000);
|
||||
|
||||
mv88e6xxx_g1_wait_eeprom_done(chip);
|
||||
if (chip->info->ops->get_eeprom)
|
||||
mv88e6xxx_g2_eeprom_wait(chip);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -75,37 +75,6 @@ static int mv88e6xxx_g1_wait_init_ready(struct mv88e6xxx_chip *chip)
|
||||
return mv88e6xxx_g1_wait_bit(chip, MV88E6XXX_G1_STS, bit, 1);
|
||||
}
|
||||
|
||||
void mv88e6xxx_g1_wait_eeprom_done(struct mv88e6xxx_chip *chip)
|
||||
{
|
||||
const unsigned long timeout = jiffies + 1 * HZ;
|
||||
u16 val;
|
||||
int err;
|
||||
|
||||
/* Wait up to 1 second for the switch to finish reading the
|
||||
* EEPROM.
|
||||
*/
|
||||
while (time_before(jiffies, timeout)) {
|
||||
err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_STS, &val);
|
||||
if (err) {
|
||||
dev_err(chip->dev, "Error reading status");
|
||||
return;
|
||||
}
|
||||
|
||||
/* If the switch is still resetting, it may not
|
||||
* respond on the bus, and so MDIO read returns
|
||||
* 0xffff. Differentiate between that, and waiting for
|
||||
* the EEPROM to be done by bit 0 being set.
|
||||
*/
|
||||
if (val != 0xffff &&
|
||||
val & BIT(MV88E6XXX_G1_STS_IRQ_EEPROM_DONE))
|
||||
return;
|
||||
|
||||
usleep_range(1000, 2000);
|
||||
}
|
||||
|
||||
dev_err(chip->dev, "Timeout waiting for EEPROM done");
|
||||
}
|
||||
|
||||
/* Offset 0x01: Switch MAC Address Register Bytes 0 & 1
|
||||
* Offset 0x02: Switch MAC Address Register Bytes 2 & 3
|
||||
* Offset 0x03: Switch MAC Address Register Bytes 4 & 5
|
||||
|
||||
@@ -282,7 +282,6 @@ int mv88e6xxx_g1_set_switch_mac(struct mv88e6xxx_chip *chip, u8 *addr);
|
||||
int mv88e6185_g1_reset(struct mv88e6xxx_chip *chip);
|
||||
int mv88e6352_g1_reset(struct mv88e6xxx_chip *chip);
|
||||
int mv88e6250_g1_reset(struct mv88e6xxx_chip *chip);
|
||||
void mv88e6xxx_g1_wait_eeprom_done(struct mv88e6xxx_chip *chip);
|
||||
|
||||
int mv88e6185_g1_ppu_enable(struct mv88e6xxx_chip *chip);
|
||||
int mv88e6185_g1_ppu_disable(struct mv88e6xxx_chip *chip);
|
||||
|
||||
@@ -340,7 +340,7 @@ int mv88e6xxx_g2_pot_clear(struct mv88e6xxx_chip *chip)
|
||||
* Offset 0x15: EEPROM Addr (for 8-bit data access)
|
||||
*/
|
||||
|
||||
static int mv88e6xxx_g2_eeprom_wait(struct mv88e6xxx_chip *chip)
|
||||
int mv88e6xxx_g2_eeprom_wait(struct mv88e6xxx_chip *chip)
|
||||
{
|
||||
int bit = __bf_shf(MV88E6XXX_G2_EEPROM_CMD_BUSY);
|
||||
int err;
|
||||
|
||||
@@ -365,6 +365,7 @@ int mv88e6xxx_g2_trunk_clear(struct mv88e6xxx_chip *chip);
|
||||
|
||||
int mv88e6xxx_g2_device_mapping_write(struct mv88e6xxx_chip *chip, int target,
|
||||
int port);
|
||||
int mv88e6xxx_g2_eeprom_wait(struct mv88e6xxx_chip *chip);
|
||||
|
||||
extern const struct mv88e6xxx_irq_ops mv88e6097_watchdog_ops;
|
||||
extern const struct mv88e6xxx_irq_ops mv88e6250_watchdog_ops;
|
||||
|
||||
@@ -1303,24 +1303,23 @@ static void ibmveth_rx_csum_helper(struct sk_buff *skb,
|
||||
* the user space for finding a flow. During this process, OVS computes
|
||||
* checksum on the first packet when CHECKSUM_PARTIAL flag is set.
|
||||
*
|
||||
* So, re-compute TCP pseudo header checksum when configured for
|
||||
* trunk mode.
|
||||
* So, re-compute TCP pseudo header checksum.
|
||||
*/
|
||||
|
||||
if (iph_proto == IPPROTO_TCP) {
|
||||
struct tcphdr *tcph = (struct tcphdr *)(skb->data + iphlen);
|
||||
|
||||
if (tcph->check == 0x0000) {
|
||||
/* Recompute TCP pseudo header checksum */
|
||||
if (adapter->is_active_trunk) {
|
||||
tcphdrlen = skb->len - iphlen;
|
||||
if (skb_proto == ETH_P_IP)
|
||||
tcph->check =
|
||||
~csum_tcpudp_magic(iph->saddr,
|
||||
iph->daddr, tcphdrlen, iph_proto, 0);
|
||||
else if (skb_proto == ETH_P_IPV6)
|
||||
tcph->check =
|
||||
~csum_ipv6_magic(&iph6->saddr,
|
||||
&iph6->daddr, tcphdrlen, iph_proto, 0);
|
||||
}
|
||||
tcphdrlen = skb->len - iphlen;
|
||||
if (skb_proto == ETH_P_IP)
|
||||
tcph->check =
|
||||
~csum_tcpudp_magic(iph->saddr,
|
||||
iph->daddr, tcphdrlen, iph_proto, 0);
|
||||
else if (skb_proto == ETH_P_IPV6)
|
||||
tcph->check =
|
||||
~csum_ipv6_magic(&iph6->saddr,
|
||||
&iph6->daddr, tcphdrlen, iph_proto, 0);
|
||||
/* Setup SKB fields for checksum offload */
|
||||
skb_partial_csum_set(skb, iphlen,
|
||||
offsetof(struct tcphdr, check));
|
||||
|
||||
@@ -2617,12 +2617,14 @@ static int ice_vc_query_rxdid(struct ice_vf *vf)
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* Read flexiflag registers to determine whether the
|
||||
* corresponding RXDID is configured and supported or not.
|
||||
* Since Legacy 16byte descriptor format is not supported,
|
||||
* start from Legacy 32byte descriptor.
|
||||
/* RXDIDs supported by DDP package can be read from the register
|
||||
* to get the supported RXDID bitmap. But the legacy 32byte RXDID
|
||||
* is not listed in DDP package, add it in the bitmap manually.
|
||||
* Legacy 16byte descriptor is not supported.
|
||||
*/
|
||||
for (i = ICE_RXDID_LEGACY_1; i < ICE_FLEX_DESC_RXDID_MAX_NUM; i++) {
|
||||
rxdid->supported_rxdids |= BIT(ICE_RXDID_LEGACY_1);
|
||||
|
||||
for (i = ICE_RXDID_FLEX_NIC; i < ICE_FLEX_DESC_RXDID_MAX_NUM; i++) {
|
||||
regval = rd32(hw, GLFLXP_RXDID_FLAGS(i, 0));
|
||||
if ((regval >> GLFLXP_RXDID_FLAGS_FLEXIFLAG_4N_S)
|
||||
& GLFLXP_RXDID_FLAGS_FLEXIFLAG_4N_M)
|
||||
|
||||
@@ -2195,7 +2195,7 @@ struct rx_ring_info {
|
||||
struct sk_buff *skb;
|
||||
dma_addr_t data_addr;
|
||||
DEFINE_DMA_UNMAP_LEN(data_size);
|
||||
dma_addr_t frag_addr[ETH_JUMBO_MTU >> PAGE_SHIFT];
|
||||
dma_addr_t frag_addr[ETH_JUMBO_MTU >> PAGE_SHIFT ?: 1];
|
||||
};
|
||||
|
||||
enum flow_control {
|
||||
|
||||
@@ -3171,8 +3171,8 @@ static irqreturn_t mtk_handle_irq_rx(int irq, void *_eth)
|
||||
|
||||
eth->rx_events++;
|
||||
if (likely(napi_schedule_prep(ð->rx_napi))) {
|
||||
__napi_schedule(ð->rx_napi);
|
||||
mtk_rx_irq_disable(eth, eth->soc->txrx.rx_irq_done_mask);
|
||||
__napi_schedule(ð->rx_napi);
|
||||
}
|
||||
|
||||
return IRQ_HANDLED;
|
||||
@@ -3184,8 +3184,8 @@ static irqreturn_t mtk_handle_irq_tx(int irq, void *_eth)
|
||||
|
||||
eth->tx_events++;
|
||||
if (likely(napi_schedule_prep(ð->tx_napi))) {
|
||||
__napi_schedule(ð->tx_napi);
|
||||
mtk_tx_irq_disable(eth, MTK_TX_DONE_INT);
|
||||
__napi_schedule(ð->tx_napi);
|
||||
}
|
||||
|
||||
return IRQ_HANDLED;
|
||||
|
||||
@@ -46,6 +46,7 @@ config LAN743X
|
||||
tristate "LAN743x support"
|
||||
depends on PCI
|
||||
depends on PTP_1588_CLOCK_OPTIONAL
|
||||
select PHYLIB
|
||||
select FIXED_PHY
|
||||
select CRC16
|
||||
select CRC32
|
||||
|
||||
@@ -91,63 +91,137 @@ static unsigned int mana_checksum_info(struct sk_buff *skb)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void mana_add_sge(struct mana_tx_package *tp, struct mana_skb_head *ash,
|
||||
int sg_i, dma_addr_t da, int sge_len, u32 gpa_mkey)
|
||||
{
|
||||
ash->dma_handle[sg_i] = da;
|
||||
ash->size[sg_i] = sge_len;
|
||||
|
||||
tp->wqe_req.sgl[sg_i].address = da;
|
||||
tp->wqe_req.sgl[sg_i].mem_key = gpa_mkey;
|
||||
tp->wqe_req.sgl[sg_i].size = sge_len;
|
||||
}
|
||||
|
||||
static int mana_map_skb(struct sk_buff *skb, struct mana_port_context *apc,
|
||||
struct mana_tx_package *tp)
|
||||
struct mana_tx_package *tp, int gso_hs)
|
||||
{
|
||||
struct mana_skb_head *ash = (struct mana_skb_head *)skb->head;
|
||||
int hsg = 1; /* num of SGEs of linear part */
|
||||
struct gdma_dev *gd = apc->ac->gdma_dev;
|
||||
int skb_hlen = skb_headlen(skb);
|
||||
int sge0_len, sge1_len = 0;
|
||||
struct gdma_context *gc;
|
||||
struct device *dev;
|
||||
skb_frag_t *frag;
|
||||
dma_addr_t da;
|
||||
int sg_i;
|
||||
int i;
|
||||
|
||||
gc = gd->gdma_context;
|
||||
dev = gc->dev;
|
||||
da = dma_map_single(dev, skb->data, skb_headlen(skb), DMA_TO_DEVICE);
|
||||
|
||||
if (gso_hs && gso_hs < skb_hlen) {
|
||||
sge0_len = gso_hs;
|
||||
sge1_len = skb_hlen - gso_hs;
|
||||
} else {
|
||||
sge0_len = skb_hlen;
|
||||
}
|
||||
|
||||
da = dma_map_single(dev, skb->data, sge0_len, DMA_TO_DEVICE);
|
||||
if (dma_mapping_error(dev, da))
|
||||
return -ENOMEM;
|
||||
|
||||
ash->dma_handle[0] = da;
|
||||
ash->size[0] = skb_headlen(skb);
|
||||
|
||||
tp->wqe_req.sgl[0].address = ash->dma_handle[0];
|
||||
tp->wqe_req.sgl[0].mem_key = gd->gpa_mkey;
|
||||
tp->wqe_req.sgl[0].size = ash->size[0];
|
||||
|
||||
for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
|
||||
frag = &skb_shinfo(skb)->frags[i];
|
||||
da = skb_frag_dma_map(dev, frag, 0, skb_frag_size(frag),
|
||||
DMA_TO_DEVICE);
|
||||
mana_add_sge(tp, ash, 0, da, sge0_len, gd->gpa_mkey);
|
||||
|
||||
if (sge1_len) {
|
||||
sg_i = 1;
|
||||
da = dma_map_single(dev, skb->data + sge0_len, sge1_len,
|
||||
DMA_TO_DEVICE);
|
||||
if (dma_mapping_error(dev, da))
|
||||
goto frag_err;
|
||||
|
||||
ash->dma_handle[i + 1] = da;
|
||||
ash->size[i + 1] = skb_frag_size(frag);
|
||||
mana_add_sge(tp, ash, sg_i, da, sge1_len, gd->gpa_mkey);
|
||||
hsg = 2;
|
||||
}
|
||||
|
||||
tp->wqe_req.sgl[i + 1].address = ash->dma_handle[i + 1];
|
||||
tp->wqe_req.sgl[i + 1].mem_key = gd->gpa_mkey;
|
||||
tp->wqe_req.sgl[i + 1].size = ash->size[i + 1];
|
||||
for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
|
||||
sg_i = hsg + i;
|
||||
|
||||
frag = &skb_shinfo(skb)->frags[i];
|
||||
da = skb_frag_dma_map(dev, frag, 0, skb_frag_size(frag),
|
||||
DMA_TO_DEVICE);
|
||||
if (dma_mapping_error(dev, da))
|
||||
goto frag_err;
|
||||
|
||||
mana_add_sge(tp, ash, sg_i, da, skb_frag_size(frag),
|
||||
gd->gpa_mkey);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
frag_err:
|
||||
for (i = i - 1; i >= 0; i--)
|
||||
dma_unmap_page(dev, ash->dma_handle[i + 1], ash->size[i + 1],
|
||||
for (i = sg_i - 1; i >= hsg; i--)
|
||||
dma_unmap_page(dev, ash->dma_handle[i], ash->size[i],
|
||||
DMA_TO_DEVICE);
|
||||
|
||||
dma_unmap_single(dev, ash->dma_handle[0], ash->size[0], DMA_TO_DEVICE);
|
||||
for (i = hsg - 1; i >= 0; i--)
|
||||
dma_unmap_single(dev, ash->dma_handle[i], ash->size[i],
|
||||
DMA_TO_DEVICE);
|
||||
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* Handle the case when GSO SKB linear length is too large.
|
||||
* MANA NIC requires GSO packets to put only the packet header to SGE0.
|
||||
* So, we need 2 SGEs for the skb linear part which contains more than the
|
||||
* header.
|
||||
* Return a positive value for the number of SGEs, or a negative value
|
||||
* for an error.
|
||||
*/
|
||||
static int mana_fix_skb_head(struct net_device *ndev, struct sk_buff *skb,
|
||||
int gso_hs)
|
||||
{
|
||||
int num_sge = 1 + skb_shinfo(skb)->nr_frags;
|
||||
int skb_hlen = skb_headlen(skb);
|
||||
|
||||
if (gso_hs < skb_hlen) {
|
||||
num_sge++;
|
||||
} else if (gso_hs > skb_hlen) {
|
||||
if (net_ratelimit())
|
||||
netdev_err(ndev,
|
||||
"TX nonlinear head: hs:%d, skb_hlen:%d\n",
|
||||
gso_hs, skb_hlen);
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return num_sge;
|
||||
}
|
||||
|
||||
/* Get the GSO packet's header size */
|
||||
static int mana_get_gso_hs(struct sk_buff *skb)
|
||||
{
|
||||
int gso_hs;
|
||||
|
||||
if (skb->encapsulation) {
|
||||
gso_hs = skb_inner_tcp_all_headers(skb);
|
||||
} else {
|
||||
if (skb_shinfo(skb)->gso_type & SKB_GSO_UDP_L4) {
|
||||
gso_hs = skb_transport_offset(skb) +
|
||||
sizeof(struct udphdr);
|
||||
} else {
|
||||
gso_hs = skb_tcp_all_headers(skb);
|
||||
}
|
||||
}
|
||||
|
||||
return gso_hs;
|
||||
}
|
||||
|
||||
netdev_tx_t mana_start_xmit(struct sk_buff *skb, struct net_device *ndev)
|
||||
{
|
||||
enum mana_tx_pkt_format pkt_fmt = MANA_SHORT_PKT_FMT;
|
||||
struct mana_port_context *apc = netdev_priv(ndev);
|
||||
int gso_hs = 0; /* zero for non-GSO pkts */
|
||||
u16 txq_idx = skb_get_queue_mapping(skb);
|
||||
struct gdma_dev *gd = apc->ac->gdma_dev;
|
||||
bool ipv4 = false, ipv6 = false;
|
||||
@@ -159,7 +233,6 @@ netdev_tx_t mana_start_xmit(struct sk_buff *skb, struct net_device *ndev)
|
||||
struct mana_txq *txq;
|
||||
struct mana_cq *cq;
|
||||
int err, len;
|
||||
u16 ihs;
|
||||
|
||||
if (unlikely(!apc->port_is_up))
|
||||
goto tx_drop;
|
||||
@@ -209,19 +282,6 @@ netdev_tx_t mana_start_xmit(struct sk_buff *skb, struct net_device *ndev)
|
||||
pkg.wqe_req.client_data_unit = 0;
|
||||
|
||||
pkg.wqe_req.num_sge = 1 + skb_shinfo(skb)->nr_frags;
|
||||
WARN_ON_ONCE(pkg.wqe_req.num_sge > MAX_TX_WQE_SGL_ENTRIES);
|
||||
|
||||
if (pkg.wqe_req.num_sge <= ARRAY_SIZE(pkg.sgl_array)) {
|
||||
pkg.wqe_req.sgl = pkg.sgl_array;
|
||||
} else {
|
||||
pkg.sgl_ptr = kmalloc_array(pkg.wqe_req.num_sge,
|
||||
sizeof(struct gdma_sge),
|
||||
GFP_ATOMIC);
|
||||
if (!pkg.sgl_ptr)
|
||||
goto tx_drop_count;
|
||||
|
||||
pkg.wqe_req.sgl = pkg.sgl_ptr;
|
||||
}
|
||||
|
||||
if (skb->protocol == htons(ETH_P_IP))
|
||||
ipv4 = true;
|
||||
@@ -229,6 +289,26 @@ netdev_tx_t mana_start_xmit(struct sk_buff *skb, struct net_device *ndev)
|
||||
ipv6 = true;
|
||||
|
||||
if (skb_is_gso(skb)) {
|
||||
int num_sge;
|
||||
|
||||
gso_hs = mana_get_gso_hs(skb);
|
||||
|
||||
num_sge = mana_fix_skb_head(ndev, skb, gso_hs);
|
||||
if (num_sge > 0)
|
||||
pkg.wqe_req.num_sge = num_sge;
|
||||
else
|
||||
goto tx_drop_count;
|
||||
|
||||
u64_stats_update_begin(&tx_stats->syncp);
|
||||
if (skb->encapsulation) {
|
||||
tx_stats->tso_inner_packets++;
|
||||
tx_stats->tso_inner_bytes += skb->len - gso_hs;
|
||||
} else {
|
||||
tx_stats->tso_packets++;
|
||||
tx_stats->tso_bytes += skb->len - gso_hs;
|
||||
}
|
||||
u64_stats_update_end(&tx_stats->syncp);
|
||||
|
||||
pkg.tx_oob.s_oob.is_outer_ipv4 = ipv4;
|
||||
pkg.tx_oob.s_oob.is_outer_ipv6 = ipv6;
|
||||
|
||||
@@ -252,28 +332,6 @@ netdev_tx_t mana_start_xmit(struct sk_buff *skb, struct net_device *ndev)
|
||||
&ipv6_hdr(skb)->daddr, 0,
|
||||
IPPROTO_TCP, 0);
|
||||
}
|
||||
|
||||
if (skb->encapsulation) {
|
||||
ihs = skb_inner_tcp_all_headers(skb);
|
||||
u64_stats_update_begin(&tx_stats->syncp);
|
||||
tx_stats->tso_inner_packets++;
|
||||
tx_stats->tso_inner_bytes += skb->len - ihs;
|
||||
u64_stats_update_end(&tx_stats->syncp);
|
||||
} else {
|
||||
if (skb_shinfo(skb)->gso_type & SKB_GSO_UDP_L4) {
|
||||
ihs = skb_transport_offset(skb) + sizeof(struct udphdr);
|
||||
} else {
|
||||
ihs = skb_tcp_all_headers(skb);
|
||||
if (ipv6_has_hopopt_jumbo(skb))
|
||||
ihs -= sizeof(struct hop_jumbo_hdr);
|
||||
}
|
||||
|
||||
u64_stats_update_begin(&tx_stats->syncp);
|
||||
tx_stats->tso_packets++;
|
||||
tx_stats->tso_bytes += skb->len - ihs;
|
||||
u64_stats_update_end(&tx_stats->syncp);
|
||||
}
|
||||
|
||||
} else if (skb->ip_summed == CHECKSUM_PARTIAL) {
|
||||
csum_type = mana_checksum_info(skb);
|
||||
|
||||
@@ -296,11 +354,25 @@ netdev_tx_t mana_start_xmit(struct sk_buff *skb, struct net_device *ndev)
|
||||
} else {
|
||||
/* Can't do offload of this type of checksum */
|
||||
if (skb_checksum_help(skb))
|
||||
goto free_sgl_ptr;
|
||||
goto tx_drop_count;
|
||||
}
|
||||
}
|
||||
|
||||
if (mana_map_skb(skb, apc, &pkg)) {
|
||||
WARN_ON_ONCE(pkg.wqe_req.num_sge > MAX_TX_WQE_SGL_ENTRIES);
|
||||
|
||||
if (pkg.wqe_req.num_sge <= ARRAY_SIZE(pkg.sgl_array)) {
|
||||
pkg.wqe_req.sgl = pkg.sgl_array;
|
||||
} else {
|
||||
pkg.sgl_ptr = kmalloc_array(pkg.wqe_req.num_sge,
|
||||
sizeof(struct gdma_sge),
|
||||
GFP_ATOMIC);
|
||||
if (!pkg.sgl_ptr)
|
||||
goto tx_drop_count;
|
||||
|
||||
pkg.wqe_req.sgl = pkg.sgl_ptr;
|
||||
}
|
||||
|
||||
if (mana_map_skb(skb, apc, &pkg, gso_hs)) {
|
||||
u64_stats_update_begin(&tx_stats->syncp);
|
||||
tx_stats->mana_map_err++;
|
||||
u64_stats_update_end(&tx_stats->syncp);
|
||||
@@ -1258,11 +1330,16 @@ static void mana_unmap_skb(struct sk_buff *skb, struct mana_port_context *apc)
|
||||
struct mana_skb_head *ash = (struct mana_skb_head *)skb->head;
|
||||
struct gdma_context *gc = apc->ac->gdma_dev->gdma_context;
|
||||
struct device *dev = gc->dev;
|
||||
int i;
|
||||
int hsg, i;
|
||||
|
||||
dma_unmap_single(dev, ash->dma_handle[0], ash->size[0], DMA_TO_DEVICE);
|
||||
/* Number of SGEs of linear part */
|
||||
hsg = (skb_is_gso(skb) && skb_headlen(skb) > ash->size[0]) ? 2 : 1;
|
||||
|
||||
for (i = 1; i < skb_shinfo(skb)->nr_frags + 1; i++)
|
||||
for (i = 0; i < hsg; i++)
|
||||
dma_unmap_single(dev, ash->dma_handle[i], ash->size[i],
|
||||
DMA_TO_DEVICE);
|
||||
|
||||
for (i = hsg; i < skb_shinfo(skb)->nr_frags + hsg; i++)
|
||||
dma_unmap_page(dev, ash->dma_handle[i], ash->size[i],
|
||||
DMA_TO_DEVICE);
|
||||
}
|
||||
@@ -1317,19 +1394,23 @@ static void mana_poll_tx_cq(struct mana_cq *cq)
|
||||
case CQE_TX_VPORT_IDX_OUT_OF_RANGE:
|
||||
case CQE_TX_VPORT_DISABLED:
|
||||
case CQE_TX_VLAN_TAGGING_VIOLATION:
|
||||
WARN_ONCE(1, "TX: CQE error %d: ignored.\n",
|
||||
cqe_oob->cqe_hdr.cqe_type);
|
||||
if (net_ratelimit())
|
||||
netdev_err(ndev, "TX: CQE error %d\n",
|
||||
cqe_oob->cqe_hdr.cqe_type);
|
||||
|
||||
apc->eth_stats.tx_cqe_err++;
|
||||
break;
|
||||
|
||||
default:
|
||||
/* If the CQE type is unexpected, log an error, assert,
|
||||
* and go through the error path.
|
||||
/* If the CQE type is unknown, log an error,
|
||||
* and still free the SKB, update tail, etc.
|
||||
*/
|
||||
WARN_ONCE(1, "TX: Unexpected CQE type %d: HW BUG?\n",
|
||||
cqe_oob->cqe_hdr.cqe_type);
|
||||
if (net_ratelimit())
|
||||
netdev_err(ndev, "TX: unknown CQE type %d\n",
|
||||
cqe_oob->cqe_hdr.cqe_type);
|
||||
|
||||
apc->eth_stats.tx_cqe_unknown_type++;
|
||||
return;
|
||||
break;
|
||||
}
|
||||
|
||||
if (WARN_ON_ONCE(txq->gdma_txq_id != completions[i].wq_num))
|
||||
|
||||
@@ -110,9 +110,9 @@ struct qed_ll2_info {
|
||||
enum core_tx_dest tx_dest;
|
||||
u8 tx_stats_en;
|
||||
bool main_func_queue;
|
||||
struct qed_ll2_cbs cbs;
|
||||
struct qed_ll2_rx_queue rx_queue;
|
||||
struct qed_ll2_tx_queue tx_queue;
|
||||
struct qed_ll2_cbs cbs;
|
||||
};
|
||||
|
||||
extern const struct qed_ll2_ops qed_ll2_ops_pass;
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
* Copyright (C) 2022 Renesas Electronics Corporation
|
||||
*/
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/etherdevice.h>
|
||||
@@ -1049,7 +1050,7 @@ static void rswitch_rmac_setting(struct rswitch_etha *etha, const u8 *mac)
|
||||
static void rswitch_etha_enable_mii(struct rswitch_etha *etha)
|
||||
{
|
||||
rswitch_modify(etha->addr, MPIC, MPIC_PSMCS_MASK | MPIC_PSMHT_MASK,
|
||||
MPIC_PSMCS(0x05) | MPIC_PSMHT(0x06));
|
||||
MPIC_PSMCS(etha->psmcs) | MPIC_PSMHT(0x06));
|
||||
rswitch_modify(etha->addr, MPSM, 0, MPSM_MFF_C45);
|
||||
}
|
||||
|
||||
@@ -1693,6 +1694,12 @@ static void rswitch_etha_init(struct rswitch_private *priv, int index)
|
||||
etha->index = index;
|
||||
etha->addr = priv->addr + RSWITCH_ETHA_OFFSET + index * RSWITCH_ETHA_SIZE;
|
||||
etha->coma_addr = priv->addr;
|
||||
|
||||
/* MPIC.PSMCS = (clk [MHz] / (MDC frequency [MHz] * 2) - 1.
|
||||
* Calculating PSMCS value as MDC frequency = 2.5MHz. So, multiply
|
||||
* both the numerator and the denominator by 10.
|
||||
*/
|
||||
etha->psmcs = clk_get_rate(priv->clk) / 100000 / (25 * 2) - 1;
|
||||
}
|
||||
|
||||
static int rswitch_device_alloc(struct rswitch_private *priv, int index)
|
||||
@@ -1900,6 +1907,10 @@ static int renesas_eth_sw_probe(struct platform_device *pdev)
|
||||
return -ENOMEM;
|
||||
spin_lock_init(&priv->lock);
|
||||
|
||||
priv->clk = devm_clk_get(&pdev->dev, NULL);
|
||||
if (IS_ERR(priv->clk))
|
||||
return PTR_ERR(priv->clk);
|
||||
|
||||
attr = soc_device_match(rswitch_soc_no_speed_change);
|
||||
if (attr)
|
||||
priv->etha_no_runtime_change = true;
|
||||
|
||||
@@ -915,6 +915,7 @@ struct rswitch_etha {
|
||||
bool external_phy;
|
||||
struct mii_bus *mii;
|
||||
phy_interface_t phy_interface;
|
||||
u32 psmcs;
|
||||
u8 mac_addr[MAX_ADDR_LEN];
|
||||
int link;
|
||||
int speed;
|
||||
@@ -1012,6 +1013,7 @@ struct rswitch_private {
|
||||
struct rswitch_mfwd mfwd;
|
||||
|
||||
spinlock_t lock; /* lock interrupt registers' control */
|
||||
struct clk *clk;
|
||||
|
||||
bool etha_no_runtime_change;
|
||||
bool gwca_halt;
|
||||
|
||||
@@ -104,6 +104,7 @@ struct stm32_ops {
|
||||
int (*parse_data)(struct stm32_dwmac *dwmac,
|
||||
struct device *dev);
|
||||
u32 syscfg_eth_mask;
|
||||
bool clk_rx_enable_in_suspend;
|
||||
};
|
||||
|
||||
static int stm32_dwmac_init(struct plat_stmmacenet_data *plat_dat)
|
||||
@@ -121,7 +122,8 @@ static int stm32_dwmac_init(struct plat_stmmacenet_data *plat_dat)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (!dwmac->dev->power.is_suspended) {
|
||||
if (!dwmac->ops->clk_rx_enable_in_suspend ||
|
||||
!dwmac->dev->power.is_suspended) {
|
||||
ret = clk_prepare_enable(dwmac->clk_rx);
|
||||
if (ret) {
|
||||
clk_disable_unprepare(dwmac->clk_tx);
|
||||
@@ -513,7 +515,8 @@ static struct stm32_ops stm32mp1_dwmac_data = {
|
||||
.suspend = stm32mp1_suspend,
|
||||
.resume = stm32mp1_resume,
|
||||
.parse_data = stm32mp1_parse_data,
|
||||
.syscfg_eth_mask = SYSCFG_MP1_ETH_MASK
|
||||
.syscfg_eth_mask = SYSCFG_MP1_ETH_MASK,
|
||||
.clk_rx_enable_in_suspend = true
|
||||
};
|
||||
|
||||
static const struct of_device_id stm32_dwmac_match[] = {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user