Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Pull networking fixes from David Miller: 1) Fix ARM BPF JIT handling of negative 'k' values, from Chen Gang. 2) Insufficient space reserved for bridge netlink values, fix from Stephen Hemminger. 3) Some dst_neigh_lookup*() callers don't interpret error pointer correctly, fix from Zhouyi Zhou. 4) Fix transport match in SCTP active_path loops, from Xugeng Zhang. 5) Fix qeth driver handling of multi-order SKB frags, from Frank Blaschka. 6) fec driver is missing napi_disable() call, resulting in crashes on unload, from Georg Hofmann. 7) Don't try to handle PMTU events on a listening socket, fix from Eric Dumazet. 8) Fix timestamp location calculations in IP option processing, from David Ward. 9) FIB_TABLE_HASHSZ setting is not controlled by the correct kconfig tests, from Denis V Lunev. 10) Fix TX descriptor push handling in SFC driver, from Ben Hutchings. 11) Fix isdn/hisax and tulip/de4x5 kconfig dependencies, from Arnd Bergmann. 12) bnx2x statistics don't handle 4GB rollover correctly, fix from Maciej Żenczykowski. 13) Openvswitch bug fixes for vport del/new error reporting, missing genlmsg_end() call in netlink processing, and mis-parsing of LLC/SNAP ethernet types. From Rich Lane. 14) SKB pfmemalloc state should only be propagated from the head page of a compound page, fix from Pavel Emelyanov. 15) Fix link handling in tg3 driver for 5715 chips when autonegotation is disabled. From Nithin Sujir. 16) Fix inverted test of cpdma_check_free_tx_desc return value in davinci_emac driver, from Mugunthan V N. 17) vlan_depth is incorrectly calculated in skb_network_protocol(), from Li RongQing. 18) Fix probing of Gobi 1K devices in qmi_wwan driver, and fix NCM device mode backwards compat in cdc_ncm driver. From Bjørn Mork. * git://git.kernel.org/pub/scm/linux/kernel/git/davem/net: (52 commits) inet: limit length of fragment queue hash table bucket lists qeth: Fix scatter-gather regression qeth: Fix invalid router settings handling qeth: delay feature trace tcp: dont handle MTU reduction on LISTEN socket bnx2x: fix occasional statistics off-by-4GB error vhost/net: fix heads usage of ubuf_info bridge: Add support for setting BR_ROOT_BLOCK flag. bnx2x: add missing napi deletion in error path drivers: net: ethernet: ti: davinci_emac: fix usage of cpdma_check_free_tx_desc() ethernet/tulip: DE4x5 needs VIRT_TO_BUS isdn: hisax: netjet requires VIRT_TO_BUS net: cdc_ncm, cdc_mbim: allow user to prefer NCM for backwards compatibility rtnetlink: Mask the rta_type when range checking Revert "ip_gre: make ipgre_tunnel_xmit() not parse network header as IP unconditionally" Fix dst_neigh_lookup/dst_neigh_lookup_skb return value handling bug smsc75xx: configuration help incorrectly mentions smsc95xx net: fec: fix missing napi_disable call net: fec: restart the FEC when PHY speed changes skb: Propagate pfmemalloc on skb from head page only ...
This commit is contained in:
commit
7b1b3fd74e
|
@ -576,7 +576,7 @@ load_ind:
|
||||||
/* x = ((*(frame + k)) & 0xf) << 2; */
|
/* x = ((*(frame + k)) & 0xf) << 2; */
|
||||||
ctx->seen |= SEEN_X | SEEN_DATA | SEEN_CALL;
|
ctx->seen |= SEEN_X | SEEN_DATA | SEEN_CALL;
|
||||||
/* the interpreter should deal with the negative K */
|
/* the interpreter should deal with the negative K */
|
||||||
if (k < 0)
|
if ((int)k < 0)
|
||||||
return -1;
|
return -1;
|
||||||
/* offset in r1: we might have to take the slow path */
|
/* offset in r1: we might have to take the slow path */
|
||||||
emit_mov_i(r_off, k, ctx);
|
emit_mov_i(r_off, k, ctx);
|
||||||
|
|
|
@ -74,8 +74,10 @@ static struct usb_device_id ath3k_table[] = {
|
||||||
|
|
||||||
/* Atheros AR3012 with sflash firmware*/
|
/* Atheros AR3012 with sflash firmware*/
|
||||||
{ USB_DEVICE(0x0CF3, 0x3004) },
|
{ USB_DEVICE(0x0CF3, 0x3004) },
|
||||||
|
{ USB_DEVICE(0x0CF3, 0x3008) },
|
||||||
{ USB_DEVICE(0x0CF3, 0x311D) },
|
{ USB_DEVICE(0x0CF3, 0x311D) },
|
||||||
{ USB_DEVICE(0x13d3, 0x3375) },
|
{ USB_DEVICE(0x13d3, 0x3375) },
|
||||||
|
{ USB_DEVICE(0x04CA, 0x3004) },
|
||||||
{ USB_DEVICE(0x04CA, 0x3005) },
|
{ USB_DEVICE(0x04CA, 0x3005) },
|
||||||
{ USB_DEVICE(0x04CA, 0x3006) },
|
{ USB_DEVICE(0x04CA, 0x3006) },
|
||||||
{ USB_DEVICE(0x04CA, 0x3008) },
|
{ USB_DEVICE(0x04CA, 0x3008) },
|
||||||
|
@ -106,8 +108,10 @@ static struct usb_device_id ath3k_blist_tbl[] = {
|
||||||
|
|
||||||
/* Atheros AR3012 with sflash firmware*/
|
/* Atheros AR3012 with sflash firmware*/
|
||||||
{ USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 },
|
{ USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 },
|
||||||
|
{ USB_DEVICE(0x0cf3, 0x3008), .driver_info = BTUSB_ATH3012 },
|
||||||
{ USB_DEVICE(0x0cf3, 0x311D), .driver_info = BTUSB_ATH3012 },
|
{ USB_DEVICE(0x0cf3, 0x311D), .driver_info = BTUSB_ATH3012 },
|
||||||
{ USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 },
|
{ USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 },
|
||||||
|
{ USB_DEVICE(0x04ca, 0x3004), .driver_info = BTUSB_ATH3012 },
|
||||||
{ USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 },
|
{ USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 },
|
||||||
{ USB_DEVICE(0x04ca, 0x3006), .driver_info = BTUSB_ATH3012 },
|
{ USB_DEVICE(0x04ca, 0x3006), .driver_info = BTUSB_ATH3012 },
|
||||||
{ USB_DEVICE(0x04ca, 0x3008), .driver_info = BTUSB_ATH3012 },
|
{ USB_DEVICE(0x04ca, 0x3008), .driver_info = BTUSB_ATH3012 },
|
||||||
|
|
|
@ -132,8 +132,10 @@ static struct usb_device_id blacklist_table[] = {
|
||||||
|
|
||||||
/* Atheros 3012 with sflash firmware */
|
/* Atheros 3012 with sflash firmware */
|
||||||
{ USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 },
|
{ USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 },
|
||||||
|
{ USB_DEVICE(0x0cf3, 0x3008), .driver_info = BTUSB_ATH3012 },
|
||||||
{ USB_DEVICE(0x0cf3, 0x311d), .driver_info = BTUSB_ATH3012 },
|
{ USB_DEVICE(0x0cf3, 0x311d), .driver_info = BTUSB_ATH3012 },
|
||||||
{ USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 },
|
{ USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 },
|
||||||
|
{ USB_DEVICE(0x04ca, 0x3004), .driver_info = BTUSB_ATH3012 },
|
||||||
{ USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 },
|
{ USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 },
|
||||||
{ USB_DEVICE(0x04ca, 0x3006), .driver_info = BTUSB_ATH3012 },
|
{ USB_DEVICE(0x04ca, 0x3006), .driver_info = BTUSB_ATH3012 },
|
||||||
{ USB_DEVICE(0x04ca, 0x3008), .driver_info = BTUSB_ATH3012 },
|
{ USB_DEVICE(0x04ca, 0x3008), .driver_info = BTUSB_ATH3012 },
|
||||||
|
|
|
@ -1575,6 +1575,12 @@ static int c4iw_reconnect(struct c4iw_ep *ep)
|
||||||
|
|
||||||
neigh = dst_neigh_lookup(ep->dst,
|
neigh = dst_neigh_lookup(ep->dst,
|
||||||
&ep->com.cm_id->remote_addr.sin_addr.s_addr);
|
&ep->com.cm_id->remote_addr.sin_addr.s_addr);
|
||||||
|
if (!neigh) {
|
||||||
|
pr_err("%s - cannot alloc neigh.\n", __func__);
|
||||||
|
err = -ENOMEM;
|
||||||
|
goto fail4;
|
||||||
|
}
|
||||||
|
|
||||||
/* get a l2t entry */
|
/* get a l2t entry */
|
||||||
if (neigh->dev->flags & IFF_LOOPBACK) {
|
if (neigh->dev->flags & IFF_LOOPBACK) {
|
||||||
PDBG("%s LOOPBACK\n", __func__);
|
PDBG("%s LOOPBACK\n", __func__);
|
||||||
|
@ -3053,6 +3059,12 @@ static int rx_pkt(struct c4iw_dev *dev, struct sk_buff *skb)
|
||||||
dst = &rt->dst;
|
dst = &rt->dst;
|
||||||
neigh = dst_neigh_lookup_skb(dst, skb);
|
neigh = dst_neigh_lookup_skb(dst, skb);
|
||||||
|
|
||||||
|
if (!neigh) {
|
||||||
|
pr_err("%s - failed to allocate neigh!\n",
|
||||||
|
__func__);
|
||||||
|
goto free_dst;
|
||||||
|
}
|
||||||
|
|
||||||
if (neigh->dev->flags & IFF_LOOPBACK) {
|
if (neigh->dev->flags & IFF_LOOPBACK) {
|
||||||
pdev = ip_dev_find(&init_net, iph->daddr);
|
pdev = ip_dev_find(&init_net, iph->daddr);
|
||||||
e = cxgb4_l2t_get(dev->rdev.lldi.l2t, neigh,
|
e = cxgb4_l2t_get(dev->rdev.lldi.l2t, neigh,
|
||||||
|
|
|
@ -237,7 +237,8 @@ config HISAX_MIC
|
||||||
|
|
||||||
config HISAX_NETJET
|
config HISAX_NETJET
|
||||||
bool "NETjet card"
|
bool "NETjet card"
|
||||||
depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K || (MIPS && !CPU_LITTLE_ENDIAN) || FRV || (XTENSA && !CPU_LITTLE_ENDIAN)))
|
depends on PCI && (BROKEN || !(PPC || PARISC || M68K || (MIPS && !CPU_LITTLE_ENDIAN) || FRV || (XTENSA && !CPU_LITTLE_ENDIAN)))
|
||||||
|
depends on VIRT_TO_BUS
|
||||||
help
|
help
|
||||||
This enables HiSax support for the NetJet from Traverse
|
This enables HiSax support for the NetJet from Traverse
|
||||||
Technologies.
|
Technologies.
|
||||||
|
@ -248,7 +249,8 @@ config HISAX_NETJET
|
||||||
|
|
||||||
config HISAX_NETJET_U
|
config HISAX_NETJET_U
|
||||||
bool "NETspider U card"
|
bool "NETspider U card"
|
||||||
depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K || (MIPS && !CPU_LITTLE_ENDIAN) || FRV || (XTENSA && !CPU_LITTLE_ENDIAN)))
|
depends on PCI && (BROKEN || !(PPC || PARISC || M68K || (MIPS && !CPU_LITTLE_ENDIAN) || FRV || (XTENSA && !CPU_LITTLE_ENDIAN)))
|
||||||
|
depends on VIRT_TO_BUS
|
||||||
help
|
help
|
||||||
This enables HiSax support for the Netspider U interface ISDN card
|
This enables HiSax support for the Netspider U interface ISDN card
|
||||||
from Traverse Technologies.
|
from Traverse Technologies.
|
||||||
|
|
|
@ -1746,6 +1746,8 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
|
||||||
|
|
||||||
bond_compute_features(bond);
|
bond_compute_features(bond);
|
||||||
|
|
||||||
|
bond_update_speed_duplex(new_slave);
|
||||||
|
|
||||||
read_lock(&bond->lock);
|
read_lock(&bond->lock);
|
||||||
|
|
||||||
new_slave->last_arp_rx = jiffies -
|
new_slave->last_arp_rx = jiffies -
|
||||||
|
@ -1798,8 +1800,6 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
|
||||||
new_slave->link == BOND_LINK_DOWN ? "DOWN" :
|
new_slave->link == BOND_LINK_DOWN ? "DOWN" :
|
||||||
(new_slave->link == BOND_LINK_UP ? "UP" : "BACK"));
|
(new_slave->link == BOND_LINK_UP ? "UP" : "BACK"));
|
||||||
|
|
||||||
bond_update_speed_duplex(new_slave);
|
|
||||||
|
|
||||||
if (USES_PRIMARY(bond->params.mode) && bond->params.primary[0]) {
|
if (USES_PRIMARY(bond->params.mode) && bond->params.primary[0]) {
|
||||||
/* if there is a primary slave, remember it */
|
/* if there is a primary slave, remember it */
|
||||||
if (strcmp(bond->params.primary, new_slave->dev->name) == 0) {
|
if (strcmp(bond->params.primary, new_slave->dev->name) == 0) {
|
||||||
|
@ -2374,8 +2374,6 @@ static void bond_miimon_commit(struct bonding *bond)
|
||||||
bond_set_backup_slave(slave);
|
bond_set_backup_slave(slave);
|
||||||
}
|
}
|
||||||
|
|
||||||
bond_update_speed_duplex(slave);
|
|
||||||
|
|
||||||
pr_info("%s: link status definitely up for interface %s, %u Mbps %s duplex.\n",
|
pr_info("%s: link status definitely up for interface %s, %u Mbps %s duplex.\n",
|
||||||
bond->dev->name, slave->dev->name,
|
bond->dev->name, slave->dev->name,
|
||||||
slave->speed, slave->duplex ? "full" : "half");
|
slave->speed, slave->duplex ? "full" : "half");
|
||||||
|
|
|
@ -2760,6 +2760,7 @@ load_error2:
|
||||||
bp->port.pmf = 0;
|
bp->port.pmf = 0;
|
||||||
load_error1:
|
load_error1:
|
||||||
bnx2x_napi_disable(bp);
|
bnx2x_napi_disable(bp);
|
||||||
|
bnx2x_del_all_napi(bp);
|
||||||
|
|
||||||
/* clear pf_load status, as it was already set */
|
/* clear pf_load status, as it was already set */
|
||||||
if (IS_PF(bp))
|
if (IS_PF(bp))
|
||||||
|
|
|
@ -459,8 +459,9 @@ struct bnx2x_fw_port_stats_old {
|
||||||
|
|
||||||
#define UPDATE_QSTAT(s, t) \
|
#define UPDATE_QSTAT(s, t) \
|
||||||
do { \
|
do { \
|
||||||
qstats->t##_hi = qstats_old->t##_hi + le32_to_cpu(s.hi); \
|
|
||||||
qstats->t##_lo = qstats_old->t##_lo + le32_to_cpu(s.lo); \
|
qstats->t##_lo = qstats_old->t##_lo + le32_to_cpu(s.lo); \
|
||||||
|
qstats->t##_hi = qstats_old->t##_hi + le32_to_cpu(s.hi) \
|
||||||
|
+ ((qstats->t##_lo < qstats_old->t##_lo) ? 1 : 0); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define UPDATE_QSTAT_OLD(f) \
|
#define UPDATE_QSTAT_OLD(f) \
|
||||||
|
|
|
@ -4130,6 +4130,14 @@ static void tg3_phy_copper_begin(struct tg3 *tp)
|
||||||
tp->link_config.active_speed = tp->link_config.speed;
|
tp->link_config.active_speed = tp->link_config.speed;
|
||||||
tp->link_config.active_duplex = tp->link_config.duplex;
|
tp->link_config.active_duplex = tp->link_config.duplex;
|
||||||
|
|
||||||
|
if (tg3_asic_rev(tp) == ASIC_REV_5714) {
|
||||||
|
/* With autoneg disabled, 5715 only links up when the
|
||||||
|
* advertisement register has the configured speed
|
||||||
|
* enabled.
|
||||||
|
*/
|
||||||
|
tg3_writephy(tp, MII_ADVERTISE, ADVERTISE_ALL);
|
||||||
|
}
|
||||||
|
|
||||||
bmcr = 0;
|
bmcr = 0;
|
||||||
switch (tp->link_config.speed) {
|
switch (tp->link_config.speed) {
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -497,8 +497,9 @@ int t4_memory_write(struct adapter *adap, int mtype, u32 addr, u32 len,
|
||||||
}
|
}
|
||||||
|
|
||||||
#define EEPROM_STAT_ADDR 0x7bfc
|
#define EEPROM_STAT_ADDR 0x7bfc
|
||||||
#define VPD_BASE 0
|
|
||||||
#define VPD_LEN 512
|
#define VPD_LEN 512
|
||||||
|
#define VPD_BASE 0x400
|
||||||
|
#define VPD_BASE_OLD 0
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* t4_seeprom_wp - enable/disable EEPROM write protection
|
* t4_seeprom_wp - enable/disable EEPROM write protection
|
||||||
|
@ -524,7 +525,7 @@ int t4_seeprom_wp(struct adapter *adapter, bool enable)
|
||||||
int get_vpd_params(struct adapter *adapter, struct vpd_params *p)
|
int get_vpd_params(struct adapter *adapter, struct vpd_params *p)
|
||||||
{
|
{
|
||||||
u32 cclk_param, cclk_val;
|
u32 cclk_param, cclk_val;
|
||||||
int i, ret;
|
int i, ret, addr;
|
||||||
int ec, sn;
|
int ec, sn;
|
||||||
u8 *vpd, csum;
|
u8 *vpd, csum;
|
||||||
unsigned int vpdr_len, kw_offset, id_len;
|
unsigned int vpdr_len, kw_offset, id_len;
|
||||||
|
@ -533,7 +534,12 @@ int get_vpd_params(struct adapter *adapter, struct vpd_params *p)
|
||||||
if (!vpd)
|
if (!vpd)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
ret = pci_read_vpd(adapter->pdev, VPD_BASE, VPD_LEN, vpd);
|
ret = pci_read_vpd(adapter->pdev, VPD_BASE, sizeof(u32), vpd);
|
||||||
|
if (ret < 0)
|
||||||
|
goto out;
|
||||||
|
addr = *vpd == 0x82 ? VPD_BASE : VPD_BASE_OLD;
|
||||||
|
|
||||||
|
ret = pci_read_vpd(adapter->pdev, addr, VPD_LEN, vpd);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
|
|
@ -108,6 +108,7 @@ config TULIP_DM910X
|
||||||
config DE4X5
|
config DE4X5
|
||||||
tristate "Generic DECchip & DIGITAL EtherWORKS PCI/EISA"
|
tristate "Generic DECchip & DIGITAL EtherWORKS PCI/EISA"
|
||||||
depends on (PCI || EISA)
|
depends on (PCI || EISA)
|
||||||
|
depends on VIRT_TO_BUS || ALPHA || PPC || SPARC
|
||||||
select CRC32
|
select CRC32
|
||||||
---help---
|
---help---
|
||||||
This is support for the DIGITAL series of PCI/EISA Ethernet cards.
|
This is support for the DIGITAL series of PCI/EISA Ethernet cards.
|
||||||
|
|
|
@ -934,24 +934,28 @@ static void fec_enet_adjust_link(struct net_device *ndev)
|
||||||
goto spin_unlock;
|
goto spin_unlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Duplex link change */
|
|
||||||
if (phy_dev->link) {
|
if (phy_dev->link) {
|
||||||
if (fep->full_duplex != phy_dev->duplex) {
|
if (!fep->link) {
|
||||||
fec_restart(ndev, phy_dev->duplex);
|
|
||||||
/* prevent unnecessary second fec_restart() below */
|
|
||||||
fep->link = phy_dev->link;
|
fep->link = phy_dev->link;
|
||||||
status_change = 1;
|
status_change = 1;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* Link on or off change */
|
if (fep->full_duplex != phy_dev->duplex)
|
||||||
if (phy_dev->link != fep->link) {
|
status_change = 1;
|
||||||
fep->link = phy_dev->link;
|
|
||||||
if (phy_dev->link)
|
if (phy_dev->speed != fep->speed) {
|
||||||
|
fep->speed = phy_dev->speed;
|
||||||
|
status_change = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if any of the above changed restart the FEC */
|
||||||
|
if (status_change)
|
||||||
fec_restart(ndev, phy_dev->duplex);
|
fec_restart(ndev, phy_dev->duplex);
|
||||||
else
|
} else {
|
||||||
|
if (fep->link) {
|
||||||
fec_stop(ndev);
|
fec_stop(ndev);
|
||||||
status_change = 1;
|
status_change = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
spin_unlock:
|
spin_unlock:
|
||||||
|
@ -1437,6 +1441,7 @@ fec_enet_close(struct net_device *ndev)
|
||||||
struct fec_enet_private *fep = netdev_priv(ndev);
|
struct fec_enet_private *fep = netdev_priv(ndev);
|
||||||
|
|
||||||
/* Don't know what to do yet. */
|
/* Don't know what to do yet. */
|
||||||
|
napi_disable(&fep->napi);
|
||||||
fep->opened = 0;
|
fep->opened = 0;
|
||||||
netif_stop_queue(ndev);
|
netif_stop_queue(ndev);
|
||||||
fec_stop(ndev);
|
fec_stop(ndev);
|
||||||
|
|
|
@ -240,6 +240,7 @@ struct fec_enet_private {
|
||||||
phy_interface_t phy_interface;
|
phy_interface_t phy_interface;
|
||||||
int link;
|
int link;
|
||||||
int full_duplex;
|
int full_duplex;
|
||||||
|
int speed;
|
||||||
struct completion mdio_done;
|
struct completion mdio_done;
|
||||||
int irq[FEC_IRQ_NUM];
|
int irq[FEC_IRQ_NUM];
|
||||||
int bufdesc_ex;
|
int bufdesc_ex;
|
||||||
|
|
|
@ -376,7 +376,8 @@ efx_may_push_tx_desc(struct efx_tx_queue *tx_queue, unsigned int write_count)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
tx_queue->empty_read_count = 0;
|
tx_queue->empty_read_count = 0;
|
||||||
return ((empty_read_count ^ write_count) & ~EFX_EMPTY_COUNT_VALID) == 0;
|
return ((empty_read_count ^ write_count) & ~EFX_EMPTY_COUNT_VALID) == 0
|
||||||
|
&& tx_queue->write_count - write_count == 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* For each entry inserted into the software descriptor ring, create a
|
/* For each entry inserted into the software descriptor ring, create a
|
||||||
|
|
|
@ -905,7 +905,7 @@ static netdev_tx_t cpsw_ndo_start_xmit(struct sk_buff *skb,
|
||||||
/* If there is no more tx desc left free then we need to
|
/* If there is no more tx desc left free then we need to
|
||||||
* tell the kernel to stop sending us tx frames.
|
* tell the kernel to stop sending us tx frames.
|
||||||
*/
|
*/
|
||||||
if (unlikely(cpdma_check_free_tx_desc(priv->txch)))
|
if (unlikely(!cpdma_check_free_tx_desc(priv->txch)))
|
||||||
netif_stop_queue(ndev);
|
netif_stop_queue(ndev);
|
||||||
|
|
||||||
return NETDEV_TX_OK;
|
return NETDEV_TX_OK;
|
||||||
|
|
|
@ -1102,7 +1102,7 @@ static int emac_dev_xmit(struct sk_buff *skb, struct net_device *ndev)
|
||||||
/* If there is no more tx desc left free then we need to
|
/* If there is no more tx desc left free then we need to
|
||||||
* tell the kernel to stop sending us tx frames.
|
* tell the kernel to stop sending us tx frames.
|
||||||
*/
|
*/
|
||||||
if (unlikely(cpdma_check_free_tx_desc(priv->txchan)))
|
if (unlikely(!cpdma_check_free_tx_desc(priv->txchan)))
|
||||||
netif_stop_queue(ndev);
|
netif_stop_queue(ndev);
|
||||||
|
|
||||||
return NETDEV_TX_OK;
|
return NETDEV_TX_OK;
|
||||||
|
|
|
@ -666,6 +666,7 @@ static int netconsole_netdev_event(struct notifier_block *this,
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
spin_lock_irqsave(&target_list_lock, flags);
|
spin_lock_irqsave(&target_list_lock, flags);
|
||||||
|
restart:
|
||||||
list_for_each_entry(nt, &target_list, list) {
|
list_for_each_entry(nt, &target_list, list) {
|
||||||
netconsole_target_get(nt);
|
netconsole_target_get(nt);
|
||||||
if (nt->np.dev == dev) {
|
if (nt->np.dev == dev) {
|
||||||
|
@ -678,15 +679,17 @@ static int netconsole_netdev_event(struct notifier_block *this,
|
||||||
case NETDEV_UNREGISTER:
|
case NETDEV_UNREGISTER:
|
||||||
/*
|
/*
|
||||||
* rtnl_lock already held
|
* rtnl_lock already held
|
||||||
|
* we might sleep in __netpoll_cleanup()
|
||||||
*/
|
*/
|
||||||
if (nt->np.dev) {
|
spin_unlock_irqrestore(&target_list_lock, flags);
|
||||||
__netpoll_cleanup(&nt->np);
|
__netpoll_cleanup(&nt->np);
|
||||||
dev_put(nt->np.dev);
|
spin_lock_irqsave(&target_list_lock, flags);
|
||||||
nt->np.dev = NULL;
|
dev_put(nt->np.dev);
|
||||||
}
|
nt->np.dev = NULL;
|
||||||
nt->enabled = 0;
|
nt->enabled = 0;
|
||||||
stopped = true;
|
stopped = true;
|
||||||
break;
|
netconsole_target_put(nt);
|
||||||
|
goto restart;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
netconsole_target_put(nt);
|
netconsole_target_put(nt);
|
||||||
|
|
|
@ -268,7 +268,7 @@ config USB_NET_SMSC75XX
|
||||||
select CRC16
|
select CRC16
|
||||||
select CRC32
|
select CRC32
|
||||||
help
|
help
|
||||||
This option adds support for SMSC LAN95XX based USB 2.0
|
This option adds support for SMSC LAN75XX based USB 2.0
|
||||||
Gigabit Ethernet adapters.
|
Gigabit Ethernet adapters.
|
||||||
|
|
||||||
config USB_NET_SMSC95XX
|
config USB_NET_SMSC95XX
|
||||||
|
|
|
@ -68,18 +68,9 @@ static int cdc_mbim_bind(struct usbnet *dev, struct usb_interface *intf)
|
||||||
struct cdc_ncm_ctx *ctx;
|
struct cdc_ncm_ctx *ctx;
|
||||||
struct usb_driver *subdriver = ERR_PTR(-ENODEV);
|
struct usb_driver *subdriver = ERR_PTR(-ENODEV);
|
||||||
int ret = -ENODEV;
|
int ret = -ENODEV;
|
||||||
u8 data_altsetting = CDC_NCM_DATA_ALTSETTING_NCM;
|
u8 data_altsetting = cdc_ncm_select_altsetting(dev, intf);
|
||||||
struct cdc_mbim_state *info = (void *)&dev->data;
|
struct cdc_mbim_state *info = (void *)&dev->data;
|
||||||
|
|
||||||
/* see if interface supports MBIM alternate setting */
|
|
||||||
if (intf->num_altsetting == 2) {
|
|
||||||
if (!cdc_ncm_comm_intf_is_mbim(intf->cur_altsetting))
|
|
||||||
usb_set_interface(dev->udev,
|
|
||||||
intf->cur_altsetting->desc.bInterfaceNumber,
|
|
||||||
CDC_NCM_COMM_ALTSETTING_MBIM);
|
|
||||||
data_altsetting = CDC_NCM_DATA_ALTSETTING_MBIM;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Probably NCM, defer for cdc_ncm_bind */
|
/* Probably NCM, defer for cdc_ncm_bind */
|
||||||
if (!cdc_ncm_comm_intf_is_mbim(intf->cur_altsetting))
|
if (!cdc_ncm_comm_intf_is_mbim(intf->cur_altsetting))
|
||||||
goto err;
|
goto err;
|
||||||
|
|
|
@ -55,6 +55,14 @@
|
||||||
|
|
||||||
#define DRIVER_VERSION "14-Mar-2012"
|
#define DRIVER_VERSION "14-Mar-2012"
|
||||||
|
|
||||||
|
#if IS_ENABLED(CONFIG_USB_NET_CDC_MBIM)
|
||||||
|
static bool prefer_mbim = true;
|
||||||
|
#else
|
||||||
|
static bool prefer_mbim;
|
||||||
|
#endif
|
||||||
|
module_param(prefer_mbim, bool, S_IRUGO | S_IWUSR);
|
||||||
|
MODULE_PARM_DESC(prefer_mbim, "Prefer MBIM setting on dual NCM/MBIM functions");
|
||||||
|
|
||||||
static void cdc_ncm_txpath_bh(unsigned long param);
|
static void cdc_ncm_txpath_bh(unsigned long param);
|
||||||
static void cdc_ncm_tx_timeout_start(struct cdc_ncm_ctx *ctx);
|
static void cdc_ncm_tx_timeout_start(struct cdc_ncm_ctx *ctx);
|
||||||
static enum hrtimer_restart cdc_ncm_tx_timer_cb(struct hrtimer *hr_timer);
|
static enum hrtimer_restart cdc_ncm_tx_timer_cb(struct hrtimer *hr_timer);
|
||||||
|
@ -550,9 +558,12 @@ void cdc_ncm_unbind(struct usbnet *dev, struct usb_interface *intf)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(cdc_ncm_unbind);
|
EXPORT_SYMBOL_GPL(cdc_ncm_unbind);
|
||||||
|
|
||||||
static int cdc_ncm_bind(struct usbnet *dev, struct usb_interface *intf)
|
/* Select the MBIM altsetting iff it is preferred and available,
|
||||||
|
* returning the number of the corresponding data interface altsetting
|
||||||
|
*/
|
||||||
|
u8 cdc_ncm_select_altsetting(struct usbnet *dev, struct usb_interface *intf)
|
||||||
{
|
{
|
||||||
int ret;
|
struct usb_host_interface *alt;
|
||||||
|
|
||||||
/* The MBIM spec defines a NCM compatible default altsetting,
|
/* The MBIM spec defines a NCM compatible default altsetting,
|
||||||
* which we may have matched:
|
* which we may have matched:
|
||||||
|
@ -568,23 +579,27 @@ static int cdc_ncm_bind(struct usbnet *dev, struct usb_interface *intf)
|
||||||
* endpoint descriptors, shall be constructed according to
|
* endpoint descriptors, shall be constructed according to
|
||||||
* the rules given in section 6 (USB Device Model) of this
|
* the rules given in section 6 (USB Device Model) of this
|
||||||
* specification."
|
* specification."
|
||||||
*
|
|
||||||
* Do not bind to such interfaces, allowing cdc_mbim to handle
|
|
||||||
* them
|
|
||||||
*/
|
*/
|
||||||
#if IS_ENABLED(CONFIG_USB_NET_CDC_MBIM)
|
if (prefer_mbim && intf->num_altsetting == 2) {
|
||||||
if ((intf->num_altsetting == 2) &&
|
alt = usb_altnum_to_altsetting(intf, CDC_NCM_COMM_ALTSETTING_MBIM);
|
||||||
!usb_set_interface(dev->udev,
|
if (alt && cdc_ncm_comm_intf_is_mbim(alt) &&
|
||||||
intf->cur_altsetting->desc.bInterfaceNumber,
|
!usb_set_interface(dev->udev,
|
||||||
CDC_NCM_COMM_ALTSETTING_MBIM)) {
|
intf->cur_altsetting->desc.bInterfaceNumber,
|
||||||
if (cdc_ncm_comm_intf_is_mbim(intf->cur_altsetting))
|
CDC_NCM_COMM_ALTSETTING_MBIM))
|
||||||
return -ENODEV;
|
return CDC_NCM_DATA_ALTSETTING_MBIM;
|
||||||
else
|
|
||||||
usb_set_interface(dev->udev,
|
|
||||||
intf->cur_altsetting->desc.bInterfaceNumber,
|
|
||||||
CDC_NCM_COMM_ALTSETTING_NCM);
|
|
||||||
}
|
}
|
||||||
#endif
|
return CDC_NCM_DATA_ALTSETTING_NCM;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(cdc_ncm_select_altsetting);
|
||||||
|
|
||||||
|
static int cdc_ncm_bind(struct usbnet *dev, struct usb_interface *intf)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
/* MBIM backwards compatible function? */
|
||||||
|
cdc_ncm_select_altsetting(dev, intf);
|
||||||
|
if (cdc_ncm_comm_intf_is_mbim(intf->cur_altsetting))
|
||||||
|
return -ENODEV;
|
||||||
|
|
||||||
/* NCM data altsetting is always 1 */
|
/* NCM data altsetting is always 1 */
|
||||||
ret = cdc_ncm_bind_common(dev, intf, 1);
|
ret = cdc_ncm_bind_common(dev, intf, 1);
|
||||||
|
|
|
@ -139,16 +139,9 @@ static int qmi_wwan_bind(struct usbnet *dev, struct usb_interface *intf)
|
||||||
|
|
||||||
BUILD_BUG_ON((sizeof(((struct usbnet *)0)->data) < sizeof(struct qmi_wwan_state)));
|
BUILD_BUG_ON((sizeof(((struct usbnet *)0)->data) < sizeof(struct qmi_wwan_state)));
|
||||||
|
|
||||||
/* control and data is shared? */
|
/* set up initial state */
|
||||||
if (intf->cur_altsetting->desc.bNumEndpoints == 3) {
|
info->control = intf;
|
||||||
info->control = intf;
|
info->data = intf;
|
||||||
info->data = intf;
|
|
||||||
goto shared;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* else require a single interrupt status endpoint on control intf */
|
|
||||||
if (intf->cur_altsetting->desc.bNumEndpoints != 1)
|
|
||||||
goto err;
|
|
||||||
|
|
||||||
/* and a number of CDC descriptors */
|
/* and a number of CDC descriptors */
|
||||||
while (len > 3) {
|
while (len > 3) {
|
||||||
|
@ -207,25 +200,14 @@ next_desc:
|
||||||
buf += h->bLength;
|
buf += h->bLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* did we find all the required ones? */
|
/* Use separate control and data interfaces if we found a CDC Union */
|
||||||
if (!(found & (1 << USB_CDC_HEADER_TYPE)) ||
|
if (cdc_union) {
|
||||||
!(found & (1 << USB_CDC_UNION_TYPE))) {
|
info->data = usb_ifnum_to_if(dev->udev, cdc_union->bSlaveInterface0);
|
||||||
dev_err(&intf->dev, "CDC functional descriptors missing\n");
|
if (desc->bInterfaceNumber != cdc_union->bMasterInterface0 || !info->data) {
|
||||||
goto err;
|
dev_err(&intf->dev, "bogus CDC Union: master=%u, slave=%u\n",
|
||||||
}
|
cdc_union->bMasterInterface0, cdc_union->bSlaveInterface0);
|
||||||
|
goto err;
|
||||||
/* verify CDC Union */
|
}
|
||||||
if (desc->bInterfaceNumber != cdc_union->bMasterInterface0) {
|
|
||||||
dev_err(&intf->dev, "bogus CDC Union: master=%u\n", cdc_union->bMasterInterface0);
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* need to save these for unbind */
|
|
||||||
info->control = intf;
|
|
||||||
info->data = usb_ifnum_to_if(dev->udev, cdc_union->bSlaveInterface0);
|
|
||||||
if (!info->data) {
|
|
||||||
dev_err(&intf->dev, "bogus CDC Union: slave=%u\n", cdc_union->bSlaveInterface0);
|
|
||||||
goto err;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* errors aren't fatal - we can live with the dynamic address */
|
/* errors aren't fatal - we can live with the dynamic address */
|
||||||
|
@ -235,11 +217,12 @@ next_desc:
|
||||||
}
|
}
|
||||||
|
|
||||||
/* claim data interface and set it up */
|
/* claim data interface and set it up */
|
||||||
status = usb_driver_claim_interface(driver, info->data, dev);
|
if (info->control != info->data) {
|
||||||
if (status < 0)
|
status = usb_driver_claim_interface(driver, info->data, dev);
|
||||||
goto err;
|
if (status < 0)
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
shared:
|
|
||||||
status = qmi_wwan_register_subdriver(dev);
|
status = qmi_wwan_register_subdriver(dev);
|
||||||
if (status < 0 && info->control != info->data) {
|
if (status < 0 && info->control != info->data) {
|
||||||
usb_set_intfdata(info->data, NULL);
|
usb_set_intfdata(info->data, NULL);
|
||||||
|
|
|
@ -1117,10 +1117,9 @@ mwifiex_cmd_802_11_ad_hoc_join(struct mwifiex_private *priv,
|
||||||
adhoc_join->bss_descriptor.bssid,
|
adhoc_join->bss_descriptor.bssid,
|
||||||
adhoc_join->bss_descriptor.ssid);
|
adhoc_join->bss_descriptor.ssid);
|
||||||
|
|
||||||
for (i = 0; bss_desc->supported_rates[i] &&
|
for (i = 0; i < MWIFIEX_SUPPORTED_RATES &&
|
||||||
i < MWIFIEX_SUPPORTED_RATES;
|
bss_desc->supported_rates[i]; i++)
|
||||||
i++)
|
;
|
||||||
;
|
|
||||||
rates_size = i;
|
rates_size = i;
|
||||||
|
|
||||||
/* Copy Data Rates from the Rates recorded in scan response */
|
/* Copy Data Rates from the Rates recorded in scan response */
|
||||||
|
|
|
@ -55,10 +55,10 @@ config RT61PCI
|
||||||
|
|
||||||
config RT2800PCI
|
config RT2800PCI
|
||||||
tristate "Ralink rt27xx/rt28xx/rt30xx (PCI/PCIe/PCMCIA) support"
|
tristate "Ralink rt27xx/rt28xx/rt30xx (PCI/PCIe/PCMCIA) support"
|
||||||
depends on PCI || RALINK_RT288X || RALINK_RT305X
|
depends on PCI || SOC_RT288X || SOC_RT305X
|
||||||
select RT2800_LIB
|
select RT2800_LIB
|
||||||
select RT2X00_LIB_PCI if PCI
|
select RT2X00_LIB_PCI if PCI
|
||||||
select RT2X00_LIB_SOC if RALINK_RT288X || RALINK_RT305X
|
select RT2X00_LIB_SOC if SOC_RT288X || SOC_RT305X
|
||||||
select RT2X00_LIB_FIRMWARE
|
select RT2X00_LIB_FIRMWARE
|
||||||
select RT2X00_LIB_CRYPTO
|
select RT2X00_LIB_CRYPTO
|
||||||
select CRC_CCITT
|
select CRC_CCITT
|
||||||
|
|
|
@ -89,7 +89,7 @@ static void rt2800pci_mcu_status(struct rt2x00_dev *rt2x00dev, const u8 token)
|
||||||
rt2x00pci_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0);
|
rt2x00pci_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(CONFIG_RALINK_RT288X) || defined(CONFIG_RALINK_RT305X)
|
#if defined(CONFIG_SOC_RT288X) || defined(CONFIG_SOC_RT305X)
|
||||||
static int rt2800pci_read_eeprom_soc(struct rt2x00_dev *rt2x00dev)
|
static int rt2800pci_read_eeprom_soc(struct rt2x00_dev *rt2x00dev)
|
||||||
{
|
{
|
||||||
void __iomem *base_addr = ioremap(0x1F040000, EEPROM_SIZE);
|
void __iomem *base_addr = ioremap(0x1F040000, EEPROM_SIZE);
|
||||||
|
@ -107,7 +107,7 @@ static inline int rt2800pci_read_eeprom_soc(struct rt2x00_dev *rt2x00dev)
|
||||||
{
|
{
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_RALINK_RT288X || CONFIG_RALINK_RT305X */
|
#endif /* CONFIG_SOC_RT288X || CONFIG_SOC_RT305X */
|
||||||
|
|
||||||
#ifdef CONFIG_PCI
|
#ifdef CONFIG_PCI
|
||||||
static void rt2800pci_eepromregister_read(struct eeprom_93cx6 *eeprom)
|
static void rt2800pci_eepromregister_read(struct eeprom_93cx6 *eeprom)
|
||||||
|
@ -1177,7 +1177,7 @@ MODULE_DEVICE_TABLE(pci, rt2800pci_device_table);
|
||||||
#endif /* CONFIG_PCI */
|
#endif /* CONFIG_PCI */
|
||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
|
|
||||||
#if defined(CONFIG_RALINK_RT288X) || defined(CONFIG_RALINK_RT305X)
|
#if defined(CONFIG_SOC_RT288X) || defined(CONFIG_SOC_RT305X)
|
||||||
static int rt2800soc_probe(struct platform_device *pdev)
|
static int rt2800soc_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
return rt2x00soc_probe(pdev, &rt2800pci_ops);
|
return rt2x00soc_probe(pdev, &rt2800pci_ops);
|
||||||
|
@ -1194,7 +1194,7 @@ static struct platform_driver rt2800soc_driver = {
|
||||||
.suspend = rt2x00soc_suspend,
|
.suspend = rt2x00soc_suspend,
|
||||||
.resume = rt2x00soc_resume,
|
.resume = rt2x00soc_resume,
|
||||||
};
|
};
|
||||||
#endif /* CONFIG_RALINK_RT288X || CONFIG_RALINK_RT305X */
|
#endif /* CONFIG_SOC_RT288X || CONFIG_SOC_RT305X */
|
||||||
|
|
||||||
#ifdef CONFIG_PCI
|
#ifdef CONFIG_PCI
|
||||||
static int rt2800pci_probe(struct pci_dev *pci_dev,
|
static int rt2800pci_probe(struct pci_dev *pci_dev,
|
||||||
|
@ -1217,7 +1217,7 @@ static int __init rt2800pci_init(void)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
#if defined(CONFIG_RALINK_RT288X) || defined(CONFIG_RALINK_RT305X)
|
#if defined(CONFIG_SOC_RT288X) || defined(CONFIG_SOC_RT305X)
|
||||||
ret = platform_driver_register(&rt2800soc_driver);
|
ret = platform_driver_register(&rt2800soc_driver);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -1225,7 +1225,7 @@ static int __init rt2800pci_init(void)
|
||||||
#ifdef CONFIG_PCI
|
#ifdef CONFIG_PCI
|
||||||
ret = pci_register_driver(&rt2800pci_driver);
|
ret = pci_register_driver(&rt2800pci_driver);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
#if defined(CONFIG_RALINK_RT288X) || defined(CONFIG_RALINK_RT305X)
|
#if defined(CONFIG_SOC_RT288X) || defined(CONFIG_SOC_RT305X)
|
||||||
platform_driver_unregister(&rt2800soc_driver);
|
platform_driver_unregister(&rt2800soc_driver);
|
||||||
#endif
|
#endif
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -1240,7 +1240,7 @@ static void __exit rt2800pci_exit(void)
|
||||||
#ifdef CONFIG_PCI
|
#ifdef CONFIG_PCI
|
||||||
pci_unregister_driver(&rt2800pci_driver);
|
pci_unregister_driver(&rt2800pci_driver);
|
||||||
#endif
|
#endif
|
||||||
#if defined(CONFIG_RALINK_RT288X) || defined(CONFIG_RALINK_RT305X)
|
#if defined(CONFIG_SOC_RT288X) || defined(CONFIG_SOC_RT305X)
|
||||||
platform_driver_unregister(&rt2800soc_driver);
|
platform_driver_unregister(&rt2800soc_driver);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -1377,74 +1377,57 @@ void rtl92cu_card_disable(struct ieee80211_hw *hw)
|
||||||
|
|
||||||
void rtl92cu_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid)
|
void rtl92cu_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid)
|
||||||
{
|
{
|
||||||
/* dummy routine needed for callback from rtl_op_configure_filter() */
|
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||||
|
struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
|
||||||
|
u32 reg_rcr = rtl_read_dword(rtlpriv, REG_RCR);
|
||||||
|
|
||||||
|
if (rtlpriv->psc.rfpwr_state != ERFON)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (check_bssid) {
|
||||||
|
u8 tmp;
|
||||||
|
if (IS_NORMAL_CHIP(rtlhal->version)) {
|
||||||
|
reg_rcr |= (RCR_CBSSID_DATA | RCR_CBSSID_BCN);
|
||||||
|
tmp = BIT(4);
|
||||||
|
} else {
|
||||||
|
reg_rcr |= RCR_CBSSID;
|
||||||
|
tmp = BIT(4) | BIT(5);
|
||||||
|
}
|
||||||
|
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR,
|
||||||
|
(u8 *) (®_rcr));
|
||||||
|
_rtl92cu_set_bcn_ctrl_reg(hw, 0, tmp);
|
||||||
|
} else {
|
||||||
|
u8 tmp;
|
||||||
|
if (IS_NORMAL_CHIP(rtlhal->version)) {
|
||||||
|
reg_rcr &= ~(RCR_CBSSID_DATA | RCR_CBSSID_BCN);
|
||||||
|
tmp = BIT(4);
|
||||||
|
} else {
|
||||||
|
reg_rcr &= ~RCR_CBSSID;
|
||||||
|
tmp = BIT(4) | BIT(5);
|
||||||
|
}
|
||||||
|
reg_rcr &= (~(RCR_CBSSID_DATA | RCR_CBSSID_BCN));
|
||||||
|
rtlpriv->cfg->ops->set_hw_reg(hw,
|
||||||
|
HW_VAR_RCR, (u8 *) (®_rcr));
|
||||||
|
_rtl92cu_set_bcn_ctrl_reg(hw, tmp, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*========================================================================== */
|
/*========================================================================== */
|
||||||
|
|
||||||
static void _rtl92cu_set_check_bssid(struct ieee80211_hw *hw,
|
|
||||||
enum nl80211_iftype type)
|
|
||||||
{
|
|
||||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
|
||||||
u32 reg_rcr = rtl_read_dword(rtlpriv, REG_RCR);
|
|
||||||
struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
|
|
||||||
struct rtl_phy *rtlphy = &(rtlpriv->phy);
|
|
||||||
u8 filterout_non_associated_bssid = false;
|
|
||||||
|
|
||||||
switch (type) {
|
|
||||||
case NL80211_IFTYPE_ADHOC:
|
|
||||||
case NL80211_IFTYPE_STATION:
|
|
||||||
filterout_non_associated_bssid = true;
|
|
||||||
break;
|
|
||||||
case NL80211_IFTYPE_UNSPECIFIED:
|
|
||||||
case NL80211_IFTYPE_AP:
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (filterout_non_associated_bssid) {
|
|
||||||
if (IS_NORMAL_CHIP(rtlhal->version)) {
|
|
||||||
switch (rtlphy->current_io_type) {
|
|
||||||
case IO_CMD_RESUME_DM_BY_SCAN:
|
|
||||||
reg_rcr |= (RCR_CBSSID_DATA | RCR_CBSSID_BCN);
|
|
||||||
rtlpriv->cfg->ops->set_hw_reg(hw,
|
|
||||||
HW_VAR_RCR, (u8 *)(®_rcr));
|
|
||||||
/* enable update TSF */
|
|
||||||
_rtl92cu_set_bcn_ctrl_reg(hw, 0, BIT(4));
|
|
||||||
break;
|
|
||||||
case IO_CMD_PAUSE_DM_BY_SCAN:
|
|
||||||
reg_rcr &= ~(RCR_CBSSID_DATA | RCR_CBSSID_BCN);
|
|
||||||
rtlpriv->cfg->ops->set_hw_reg(hw,
|
|
||||||
HW_VAR_RCR, (u8 *)(®_rcr));
|
|
||||||
/* disable update TSF */
|
|
||||||
_rtl92cu_set_bcn_ctrl_reg(hw, BIT(4), 0);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
reg_rcr |= (RCR_CBSSID);
|
|
||||||
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR,
|
|
||||||
(u8 *)(®_rcr));
|
|
||||||
_rtl92cu_set_bcn_ctrl_reg(hw, 0, (BIT(4)|BIT(5)));
|
|
||||||
}
|
|
||||||
} else if (filterout_non_associated_bssid == false) {
|
|
||||||
if (IS_NORMAL_CHIP(rtlhal->version)) {
|
|
||||||
reg_rcr &= (~(RCR_CBSSID_DATA | RCR_CBSSID_BCN));
|
|
||||||
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR,
|
|
||||||
(u8 *)(®_rcr));
|
|
||||||
_rtl92cu_set_bcn_ctrl_reg(hw, BIT(4), 0);
|
|
||||||
} else {
|
|
||||||
reg_rcr &= (~RCR_CBSSID);
|
|
||||||
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR,
|
|
||||||
(u8 *)(®_rcr));
|
|
||||||
_rtl92cu_set_bcn_ctrl_reg(hw, (BIT(4)|BIT(5)), 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int rtl92cu_set_network_type(struct ieee80211_hw *hw, enum nl80211_iftype type)
|
int rtl92cu_set_network_type(struct ieee80211_hw *hw, enum nl80211_iftype type)
|
||||||
{
|
{
|
||||||
|
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||||
|
|
||||||
if (_rtl92cu_set_media_status(hw, type))
|
if (_rtl92cu_set_media_status(hw, type))
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
_rtl92cu_set_check_bssid(hw, type);
|
|
||||||
|
if (rtlpriv->mac80211.link_state == MAC80211_LINKED) {
|
||||||
|
if (type != NL80211_IFTYPE_AP)
|
||||||
|
rtl92cu_set_check_bssid(hw, true);
|
||||||
|
} else {
|
||||||
|
rtl92cu_set_check_bssid(hw, false);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2058,8 +2041,6 @@ void rtl92cu_update_hal_rate_table(struct ieee80211_hw *hw,
|
||||||
(shortgi_rate << 4) | (shortgi_rate);
|
(shortgi_rate << 4) | (shortgi_rate);
|
||||||
}
|
}
|
||||||
rtl_write_dword(rtlpriv, REG_ARFR0 + ratr_index * 4, ratr_value);
|
rtl_write_dword(rtlpriv, REG_ARFR0 + ratr_index * 4, ratr_value);
|
||||||
RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, "%x\n",
|
|
||||||
rtl_read_dword(rtlpriv, REG_ARFR0));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void rtl92cu_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level)
|
void rtl92cu_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level)
|
||||||
|
|
|
@ -916,6 +916,7 @@ int qeth_send_control_data(struct qeth_card *, int, struct qeth_cmd_buffer *,
|
||||||
void *reply_param);
|
void *reply_param);
|
||||||
int qeth_get_priority_queue(struct qeth_card *, struct sk_buff *, int, int);
|
int qeth_get_priority_queue(struct qeth_card *, struct sk_buff *, int, int);
|
||||||
int qeth_get_elements_no(struct qeth_card *, void *, struct sk_buff *, int);
|
int qeth_get_elements_no(struct qeth_card *, void *, struct sk_buff *, int);
|
||||||
|
int qeth_get_elements_for_frags(struct sk_buff *);
|
||||||
int qeth_do_send_packet_fast(struct qeth_card *, struct qeth_qdio_out_q *,
|
int qeth_do_send_packet_fast(struct qeth_card *, struct qeth_qdio_out_q *,
|
||||||
struct sk_buff *, struct qeth_hdr *, int, int, int);
|
struct sk_buff *, struct qeth_hdr *, int, int, int);
|
||||||
int qeth_do_send_packet(struct qeth_card *, struct qeth_qdio_out_q *,
|
int qeth_do_send_packet(struct qeth_card *, struct qeth_qdio_out_q *,
|
||||||
|
|
|
@ -3679,6 +3679,25 @@ int qeth_get_priority_queue(struct qeth_card *card, struct sk_buff *skb,
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(qeth_get_priority_queue);
|
EXPORT_SYMBOL_GPL(qeth_get_priority_queue);
|
||||||
|
|
||||||
|
int qeth_get_elements_for_frags(struct sk_buff *skb)
|
||||||
|
{
|
||||||
|
int cnt, length, e, elements = 0;
|
||||||
|
struct skb_frag_struct *frag;
|
||||||
|
char *data;
|
||||||
|
|
||||||
|
for (cnt = 0; cnt < skb_shinfo(skb)->nr_frags; cnt++) {
|
||||||
|
frag = &skb_shinfo(skb)->frags[cnt];
|
||||||
|
data = (char *)page_to_phys(skb_frag_page(frag)) +
|
||||||
|
frag->page_offset;
|
||||||
|
length = frag->size;
|
||||||
|
e = PFN_UP((unsigned long)data + length - 1) -
|
||||||
|
PFN_DOWN((unsigned long)data);
|
||||||
|
elements += e;
|
||||||
|
}
|
||||||
|
return elements;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(qeth_get_elements_for_frags);
|
||||||
|
|
||||||
int qeth_get_elements_no(struct qeth_card *card, void *hdr,
|
int qeth_get_elements_no(struct qeth_card *card, void *hdr,
|
||||||
struct sk_buff *skb, int elems)
|
struct sk_buff *skb, int elems)
|
||||||
{
|
{
|
||||||
|
@ -3686,7 +3705,8 @@ int qeth_get_elements_no(struct qeth_card *card, void *hdr,
|
||||||
int elements_needed = PFN_UP((unsigned long)skb->data + dlen - 1) -
|
int elements_needed = PFN_UP((unsigned long)skb->data + dlen - 1) -
|
||||||
PFN_DOWN((unsigned long)skb->data);
|
PFN_DOWN((unsigned long)skb->data);
|
||||||
|
|
||||||
elements_needed += skb_shinfo(skb)->nr_frags;
|
elements_needed += qeth_get_elements_for_frags(skb);
|
||||||
|
|
||||||
if ((elements_needed + elems) > QETH_MAX_BUFFER_ELEMENTS(card)) {
|
if ((elements_needed + elems) > QETH_MAX_BUFFER_ELEMENTS(card)) {
|
||||||
QETH_DBF_MESSAGE(2, "Invalid size of IP packet "
|
QETH_DBF_MESSAGE(2, "Invalid size of IP packet "
|
||||||
"(Number=%d / Length=%d). Discarded.\n",
|
"(Number=%d / Length=%d). Discarded.\n",
|
||||||
|
@ -3771,12 +3791,23 @@ static inline void __qeth_fill_buffer(struct sk_buff *skb,
|
||||||
|
|
||||||
for (cnt = 0; cnt < skb_shinfo(skb)->nr_frags; cnt++) {
|
for (cnt = 0; cnt < skb_shinfo(skb)->nr_frags; cnt++) {
|
||||||
frag = &skb_shinfo(skb)->frags[cnt];
|
frag = &skb_shinfo(skb)->frags[cnt];
|
||||||
buffer->element[element].addr = (char *)
|
data = (char *)page_to_phys(skb_frag_page(frag)) +
|
||||||
page_to_phys(skb_frag_page(frag))
|
frag->page_offset;
|
||||||
+ frag->page_offset;
|
length = frag->size;
|
||||||
buffer->element[element].length = frag->size;
|
while (length > 0) {
|
||||||
buffer->element[element].eflags = SBAL_EFLAGS_MIDDLE_FRAG;
|
length_here = PAGE_SIZE -
|
||||||
element++;
|
((unsigned long) data % PAGE_SIZE);
|
||||||
|
if (length < length_here)
|
||||||
|
length_here = length;
|
||||||
|
|
||||||
|
buffer->element[element].addr = data;
|
||||||
|
buffer->element[element].length = length_here;
|
||||||
|
buffer->element[element].eflags =
|
||||||
|
SBAL_EFLAGS_MIDDLE_FRAG;
|
||||||
|
length -= length_here;
|
||||||
|
data += length_here;
|
||||||
|
element++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (buffer->element[element - 1].eflags)
|
if (buffer->element[element - 1].eflags)
|
||||||
|
|
|
@ -623,7 +623,7 @@ static int qeth_l3_send_setrouting(struct qeth_card *card,
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void qeth_l3_correct_routing_type(struct qeth_card *card,
|
static int qeth_l3_correct_routing_type(struct qeth_card *card,
|
||||||
enum qeth_routing_types *type, enum qeth_prot_versions prot)
|
enum qeth_routing_types *type, enum qeth_prot_versions prot)
|
||||||
{
|
{
|
||||||
if (card->info.type == QETH_CARD_TYPE_IQD) {
|
if (card->info.type == QETH_CARD_TYPE_IQD) {
|
||||||
|
@ -632,7 +632,7 @@ static void qeth_l3_correct_routing_type(struct qeth_card *card,
|
||||||
case PRIMARY_CONNECTOR:
|
case PRIMARY_CONNECTOR:
|
||||||
case SECONDARY_CONNECTOR:
|
case SECONDARY_CONNECTOR:
|
||||||
case MULTICAST_ROUTER:
|
case MULTICAST_ROUTER:
|
||||||
return;
|
return 0;
|
||||||
default:
|
default:
|
||||||
goto out_inval;
|
goto out_inval;
|
||||||
}
|
}
|
||||||
|
@ -641,17 +641,18 @@ static void qeth_l3_correct_routing_type(struct qeth_card *card,
|
||||||
case NO_ROUTER:
|
case NO_ROUTER:
|
||||||
case PRIMARY_ROUTER:
|
case PRIMARY_ROUTER:
|
||||||
case SECONDARY_ROUTER:
|
case SECONDARY_ROUTER:
|
||||||
return;
|
return 0;
|
||||||
case MULTICAST_ROUTER:
|
case MULTICAST_ROUTER:
|
||||||
if (qeth_is_ipafunc_supported(card, prot,
|
if (qeth_is_ipafunc_supported(card, prot,
|
||||||
IPA_OSA_MC_ROUTER))
|
IPA_OSA_MC_ROUTER))
|
||||||
return;
|
return 0;
|
||||||
default:
|
default:
|
||||||
goto out_inval;
|
goto out_inval;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
out_inval:
|
out_inval:
|
||||||
*type = NO_ROUTER;
|
*type = NO_ROUTER;
|
||||||
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int qeth_l3_setrouting_v4(struct qeth_card *card)
|
int qeth_l3_setrouting_v4(struct qeth_card *card)
|
||||||
|
@ -660,8 +661,10 @@ int qeth_l3_setrouting_v4(struct qeth_card *card)
|
||||||
|
|
||||||
QETH_CARD_TEXT(card, 3, "setrtg4");
|
QETH_CARD_TEXT(card, 3, "setrtg4");
|
||||||
|
|
||||||
qeth_l3_correct_routing_type(card, &card->options.route4.type,
|
rc = qeth_l3_correct_routing_type(card, &card->options.route4.type,
|
||||||
QETH_PROT_IPV4);
|
QETH_PROT_IPV4);
|
||||||
|
if (rc)
|
||||||
|
return rc;
|
||||||
|
|
||||||
rc = qeth_l3_send_setrouting(card, card->options.route4.type,
|
rc = qeth_l3_send_setrouting(card, card->options.route4.type,
|
||||||
QETH_PROT_IPV4);
|
QETH_PROT_IPV4);
|
||||||
|
@ -683,8 +686,10 @@ int qeth_l3_setrouting_v6(struct qeth_card *card)
|
||||||
|
|
||||||
if (!qeth_is_supported(card, IPA_IPV6))
|
if (!qeth_is_supported(card, IPA_IPV6))
|
||||||
return 0;
|
return 0;
|
||||||
qeth_l3_correct_routing_type(card, &card->options.route6.type,
|
rc = qeth_l3_correct_routing_type(card, &card->options.route6.type,
|
||||||
QETH_PROT_IPV6);
|
QETH_PROT_IPV6);
|
||||||
|
if (rc)
|
||||||
|
return rc;
|
||||||
|
|
||||||
rc = qeth_l3_send_setrouting(card, card->options.route6.type,
|
rc = qeth_l3_send_setrouting(card, card->options.route6.type,
|
||||||
QETH_PROT_IPV6);
|
QETH_PROT_IPV6);
|
||||||
|
@ -2898,7 +2903,9 @@ static inline int qeth_l3_tso_elements(struct sk_buff *skb)
|
||||||
tcp_hdr(skb)->doff * 4;
|
tcp_hdr(skb)->doff * 4;
|
||||||
int tcpd_len = skb->len - (tcpd - (unsigned long)skb->data);
|
int tcpd_len = skb->len - (tcpd - (unsigned long)skb->data);
|
||||||
int elements = PFN_UP(tcpd + tcpd_len - 1) - PFN_DOWN(tcpd);
|
int elements = PFN_UP(tcpd + tcpd_len - 1) - PFN_DOWN(tcpd);
|
||||||
elements += skb_shinfo(skb)->nr_frags;
|
|
||||||
|
elements += qeth_get_elements_for_frags(skb);
|
||||||
|
|
||||||
return elements;
|
return elements;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3348,7 +3355,6 @@ static int __qeth_l3_set_online(struct ccwgroup_device *gdev, int recovery_mode)
|
||||||
rc = -ENODEV;
|
rc = -ENODEV;
|
||||||
goto out_remove;
|
goto out_remove;
|
||||||
}
|
}
|
||||||
qeth_trace_features(card);
|
|
||||||
|
|
||||||
if (!card->dev && qeth_l3_setup_netdev(card)) {
|
if (!card->dev && qeth_l3_setup_netdev(card)) {
|
||||||
rc = -ENODEV;
|
rc = -ENODEV;
|
||||||
|
@ -3425,6 +3431,7 @@ contin:
|
||||||
qeth_l3_set_multicast_list(card->dev);
|
qeth_l3_set_multicast_list(card->dev);
|
||||||
rtnl_unlock();
|
rtnl_unlock();
|
||||||
}
|
}
|
||||||
|
qeth_trace_features(card);
|
||||||
/* let user_space know that device is online */
|
/* let user_space know that device is online */
|
||||||
kobject_uevent(&gdev->dev.kobj, KOBJ_CHANGE);
|
kobject_uevent(&gdev->dev.kobj, KOBJ_CHANGE);
|
||||||
mutex_unlock(&card->conf_mutex);
|
mutex_unlock(&card->conf_mutex);
|
||||||
|
|
|
@ -87,6 +87,8 @@ static ssize_t qeth_l3_dev_route_store(struct qeth_card *card,
|
||||||
rc = qeth_l3_setrouting_v6(card);
|
rc = qeth_l3_setrouting_v6(card);
|
||||||
}
|
}
|
||||||
out:
|
out:
|
||||||
|
if (rc)
|
||||||
|
route->type = old_route_type;
|
||||||
mutex_unlock(&card->conf_mutex);
|
mutex_unlock(&card->conf_mutex);
|
||||||
return rc ? rc : count;
|
return rc ? rc : count;
|
||||||
}
|
}
|
||||||
|
|
|
@ -339,7 +339,8 @@ static void handle_tx(struct vhost_net *net)
|
||||||
msg.msg_controllen = 0;
|
msg.msg_controllen = 0;
|
||||||
ubufs = NULL;
|
ubufs = NULL;
|
||||||
} else {
|
} else {
|
||||||
struct ubuf_info *ubuf = &vq->ubuf_info[head];
|
struct ubuf_info *ubuf;
|
||||||
|
ubuf = vq->ubuf_info + vq->upend_idx;
|
||||||
|
|
||||||
vq->heads[vq->upend_idx].len =
|
vq->heads[vq->upend_idx].len =
|
||||||
VHOST_DMA_IN_PROGRESS;
|
VHOST_DMA_IN_PROGRESS;
|
||||||
|
|
|
@ -500,7 +500,7 @@ struct sk_buff {
|
||||||
union {
|
union {
|
||||||
__u32 mark;
|
__u32 mark;
|
||||||
__u32 dropcount;
|
__u32 dropcount;
|
||||||
__u32 avail_size;
|
__u32 reserved_tailroom;
|
||||||
};
|
};
|
||||||
|
|
||||||
sk_buff_data_t inner_transport_header;
|
sk_buff_data_t inner_transport_header;
|
||||||
|
@ -1288,11 +1288,13 @@ static inline void __skb_fill_page_desc(struct sk_buff *skb, int i,
|
||||||
* do not lose pfmemalloc information as the pages would not be
|
* do not lose pfmemalloc information as the pages would not be
|
||||||
* allocated using __GFP_MEMALLOC.
|
* allocated using __GFP_MEMALLOC.
|
||||||
*/
|
*/
|
||||||
if (page->pfmemalloc && !page->mapping)
|
|
||||||
skb->pfmemalloc = true;
|
|
||||||
frag->page.p = page;
|
frag->page.p = page;
|
||||||
frag->page_offset = off;
|
frag->page_offset = off;
|
||||||
skb_frag_size_set(frag, size);
|
skb_frag_size_set(frag, size);
|
||||||
|
|
||||||
|
page = compound_head(page);
|
||||||
|
if (page->pfmemalloc && !page->mapping)
|
||||||
|
skb->pfmemalloc = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1447,7 +1449,10 @@ static inline int skb_tailroom(const struct sk_buff *skb)
|
||||||
*/
|
*/
|
||||||
static inline int skb_availroom(const struct sk_buff *skb)
|
static inline int skb_availroom(const struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
return skb_is_nonlinear(skb) ? 0 : skb->avail_size - skb->len;
|
if (skb_is_nonlinear(skb))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return skb->end - skb->tail - skb->reserved_tailroom;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -127,6 +127,7 @@ struct cdc_ncm_ctx {
|
||||||
u16 connected;
|
u16 connected;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extern u8 cdc_ncm_select_altsetting(struct usbnet *dev, struct usb_interface *intf);
|
||||||
extern int cdc_ncm_bind_common(struct usbnet *dev, struct usb_interface *intf, u8 data_altsetting);
|
extern int cdc_ncm_bind_common(struct usbnet *dev, struct usb_interface *intf, u8 data_altsetting);
|
||||||
extern void cdc_ncm_unbind(struct usbnet *dev, struct usb_interface *intf);
|
extern void cdc_ncm_unbind(struct usbnet *dev, struct usb_interface *intf);
|
||||||
extern struct sk_buff *cdc_ncm_fill_tx_frame(struct cdc_ncm_ctx *ctx, struct sk_buff *skb, __le32 sign);
|
extern struct sk_buff *cdc_ncm_fill_tx_frame(struct cdc_ncm_ctx *ctx, struct sk_buff *skb, __le32 sign);
|
||||||
|
|
|
@ -413,13 +413,15 @@ static inline int dst_neigh_output(struct dst_entry *dst, struct neighbour *n,
|
||||||
|
|
||||||
static inline struct neighbour *dst_neigh_lookup(const struct dst_entry *dst, const void *daddr)
|
static inline struct neighbour *dst_neigh_lookup(const struct dst_entry *dst, const void *daddr)
|
||||||
{
|
{
|
||||||
return dst->ops->neigh_lookup(dst, NULL, daddr);
|
struct neighbour *n = dst->ops->neigh_lookup(dst, NULL, daddr);
|
||||||
|
return IS_ERR(n) ? NULL : n;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline struct neighbour *dst_neigh_lookup_skb(const struct dst_entry *dst,
|
static inline struct neighbour *dst_neigh_lookup_skb(const struct dst_entry *dst,
|
||||||
struct sk_buff *skb)
|
struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
return dst->ops->neigh_lookup(dst, skb, NULL);
|
struct neighbour *n = dst->ops->neigh_lookup(dst, skb, NULL);
|
||||||
|
return IS_ERR(n) ? NULL : n;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void dst_link_failure(struct sk_buff *skb)
|
static inline void dst_link_failure(struct sk_buff *skb)
|
||||||
|
|
|
@ -43,6 +43,13 @@ struct inet_frag_queue {
|
||||||
|
|
||||||
#define INETFRAGS_HASHSZ 64
|
#define INETFRAGS_HASHSZ 64
|
||||||
|
|
||||||
|
/* averaged:
|
||||||
|
* max_depth = default ipfrag_high_thresh / INETFRAGS_HASHSZ /
|
||||||
|
* rounded up (SKB_TRUELEN(0) + sizeof(struct ipq or
|
||||||
|
* struct frag_queue))
|
||||||
|
*/
|
||||||
|
#define INETFRAGS_MAXDEPTH 128
|
||||||
|
|
||||||
struct inet_frags {
|
struct inet_frags {
|
||||||
struct hlist_head hash[INETFRAGS_HASHSZ];
|
struct hlist_head hash[INETFRAGS_HASHSZ];
|
||||||
/* This rwlock is a global lock (seperate per IPv4, IPv6 and
|
/* This rwlock is a global lock (seperate per IPv4, IPv6 and
|
||||||
|
@ -76,6 +83,8 @@ int inet_frag_evictor(struct netns_frags *nf, struct inet_frags *f, bool force);
|
||||||
struct inet_frag_queue *inet_frag_find(struct netns_frags *nf,
|
struct inet_frag_queue *inet_frag_find(struct netns_frags *nf,
|
||||||
struct inet_frags *f, void *key, unsigned int hash)
|
struct inet_frags *f, void *key, unsigned int hash)
|
||||||
__releases(&f->lock);
|
__releases(&f->lock);
|
||||||
|
void inet_frag_maybe_warn_overflow(struct inet_frag_queue *q,
|
||||||
|
const char *prefix);
|
||||||
|
|
||||||
static inline void inet_frag_put(struct inet_frag_queue *q, struct inet_frags *f)
|
static inline void inet_frag_put(struct inet_frag_queue *q, struct inet_frags *f)
|
||||||
{
|
{
|
||||||
|
|
|
@ -152,19 +152,17 @@ struct fib_result_nl {
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef CONFIG_IP_ROUTE_MULTIPATH
|
#ifdef CONFIG_IP_ROUTE_MULTIPATH
|
||||||
|
|
||||||
#define FIB_RES_NH(res) ((res).fi->fib_nh[(res).nh_sel])
|
#define FIB_RES_NH(res) ((res).fi->fib_nh[(res).nh_sel])
|
||||||
|
|
||||||
#define FIB_TABLE_HASHSZ 2
|
|
||||||
|
|
||||||
#else /* CONFIG_IP_ROUTE_MULTIPATH */
|
#else /* CONFIG_IP_ROUTE_MULTIPATH */
|
||||||
|
|
||||||
#define FIB_RES_NH(res) ((res).fi->fib_nh[0])
|
#define FIB_RES_NH(res) ((res).fi->fib_nh[0])
|
||||||
|
|
||||||
#define FIB_TABLE_HASHSZ 256
|
|
||||||
|
|
||||||
#endif /* CONFIG_IP_ROUTE_MULTIPATH */
|
#endif /* CONFIG_IP_ROUTE_MULTIPATH */
|
||||||
|
|
||||||
|
#ifdef CONFIG_IP_MULTIPLE_TABLES
|
||||||
|
#define FIB_TABLE_HASHSZ 256
|
||||||
|
#else
|
||||||
|
#define FIB_TABLE_HASHSZ 2
|
||||||
|
#endif
|
||||||
|
|
||||||
extern __be32 fib_info_update_nh_saddr(struct net *net, struct fib_nh *nh);
|
extern __be32 fib_info_update_nh_saddr(struct net *net, struct fib_nh *nh);
|
||||||
|
|
||||||
#define FIB_RES_SADDR(net, res) \
|
#define FIB_RES_SADDR(net, res) \
|
||||||
|
|
|
@ -1288,7 +1288,8 @@ static int batadv_iv_ogm_receive(struct sk_buff *skb,
|
||||||
batadv_ogm_packet = (struct batadv_ogm_packet *)packet_buff;
|
batadv_ogm_packet = (struct batadv_ogm_packet *)packet_buff;
|
||||||
|
|
||||||
/* unpack the aggregated packets and process them one by one */
|
/* unpack the aggregated packets and process them one by one */
|
||||||
do {
|
while (batadv_iv_ogm_aggr_packet(buff_pos, packet_len,
|
||||||
|
batadv_ogm_packet->tt_num_changes)) {
|
||||||
tt_buff = packet_buff + buff_pos + BATADV_OGM_HLEN;
|
tt_buff = packet_buff + buff_pos + BATADV_OGM_HLEN;
|
||||||
|
|
||||||
batadv_iv_ogm_process(ethhdr, batadv_ogm_packet, tt_buff,
|
batadv_iv_ogm_process(ethhdr, batadv_ogm_packet, tt_buff,
|
||||||
|
@ -1299,8 +1300,7 @@ static int batadv_iv_ogm_receive(struct sk_buff *skb,
|
||||||
|
|
||||||
packet_pos = packet_buff + buff_pos;
|
packet_pos = packet_buff + buff_pos;
|
||||||
batadv_ogm_packet = (struct batadv_ogm_packet *)packet_pos;
|
batadv_ogm_packet = (struct batadv_ogm_packet *)packet_pos;
|
||||||
} while (batadv_iv_ogm_aggr_packet(buff_pos, packet_len,
|
}
|
||||||
batadv_ogm_packet->tt_num_changes));
|
|
||||||
|
|
||||||
kfree_skb(skb);
|
kfree_skb(skb);
|
||||||
return NET_RX_SUCCESS;
|
return NET_RX_SUCCESS;
|
||||||
|
|
|
@ -29,6 +29,7 @@ static inline size_t br_port_info_size(void)
|
||||||
+ nla_total_size(1) /* IFLA_BRPORT_MODE */
|
+ nla_total_size(1) /* IFLA_BRPORT_MODE */
|
||||||
+ nla_total_size(1) /* IFLA_BRPORT_GUARD */
|
+ nla_total_size(1) /* IFLA_BRPORT_GUARD */
|
||||||
+ nla_total_size(1) /* IFLA_BRPORT_PROTECT */
|
+ nla_total_size(1) /* IFLA_BRPORT_PROTECT */
|
||||||
|
+ nla_total_size(1) /* IFLA_BRPORT_FAST_LEAVE */
|
||||||
+ 0;
|
+ 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -329,6 +330,7 @@ static int br_setport(struct net_bridge_port *p, struct nlattr *tb[])
|
||||||
br_set_port_flag(p, tb, IFLA_BRPORT_MODE, BR_HAIRPIN_MODE);
|
br_set_port_flag(p, tb, IFLA_BRPORT_MODE, BR_HAIRPIN_MODE);
|
||||||
br_set_port_flag(p, tb, IFLA_BRPORT_GUARD, BR_BPDU_GUARD);
|
br_set_port_flag(p, tb, IFLA_BRPORT_GUARD, BR_BPDU_GUARD);
|
||||||
br_set_port_flag(p, tb, IFLA_BRPORT_FAST_LEAVE, BR_MULTICAST_FAST_LEAVE);
|
br_set_port_flag(p, tb, IFLA_BRPORT_FAST_LEAVE, BR_MULTICAST_FAST_LEAVE);
|
||||||
|
br_set_port_flag(p, tb, IFLA_BRPORT_PROTECT, BR_ROOT_BLOCK);
|
||||||
|
|
||||||
if (tb[IFLA_BRPORT_COST]) {
|
if (tb[IFLA_BRPORT_COST]) {
|
||||||
err = br_stp_set_path_cost(p, nla_get_u32(tb[IFLA_BRPORT_COST]));
|
err = br_stp_set_path_cost(p, nla_get_u32(tb[IFLA_BRPORT_COST]));
|
||||||
|
|
|
@ -2219,9 +2219,9 @@ struct sk_buff *skb_mac_gso_segment(struct sk_buff *skb,
|
||||||
struct sk_buff *segs = ERR_PTR(-EPROTONOSUPPORT);
|
struct sk_buff *segs = ERR_PTR(-EPROTONOSUPPORT);
|
||||||
struct packet_offload *ptype;
|
struct packet_offload *ptype;
|
||||||
__be16 type = skb->protocol;
|
__be16 type = skb->protocol;
|
||||||
|
int vlan_depth = ETH_HLEN;
|
||||||
|
|
||||||
while (type == htons(ETH_P_8021Q)) {
|
while (type == htons(ETH_P_8021Q)) {
|
||||||
int vlan_depth = ETH_HLEN;
|
|
||||||
struct vlan_hdr *vh;
|
struct vlan_hdr *vh;
|
||||||
|
|
||||||
if (unlikely(!pskb_may_pull(skb, vlan_depth + VLAN_HLEN)))
|
if (unlikely(!pskb_may_pull(skb, vlan_depth + VLAN_HLEN)))
|
||||||
|
|
|
@ -2621,7 +2621,7 @@ static int rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
|
||||||
struct rtattr *attr = (void *)nlh + NLMSG_ALIGN(min_len);
|
struct rtattr *attr = (void *)nlh + NLMSG_ALIGN(min_len);
|
||||||
|
|
||||||
while (RTA_OK(attr, attrlen)) {
|
while (RTA_OK(attr, attrlen)) {
|
||||||
unsigned int flavor = attr->rta_type;
|
unsigned int flavor = attr->rta_type & NLA_TYPE_MASK;
|
||||||
if (flavor) {
|
if (flavor) {
|
||||||
if (flavor > rta_max[sz_idx])
|
if (flavor > rta_max[sz_idx])
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include <linux/rtnetlink.h>
|
#include <linux/rtnetlink.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
|
|
||||||
|
#include <net/sock.h>
|
||||||
#include <net/inet_frag.h>
|
#include <net/inet_frag.h>
|
||||||
|
|
||||||
static void inet_frag_secret_rebuild(unsigned long dummy)
|
static void inet_frag_secret_rebuild(unsigned long dummy)
|
||||||
|
@ -277,6 +278,7 @@ struct inet_frag_queue *inet_frag_find(struct netns_frags *nf,
|
||||||
__releases(&f->lock)
|
__releases(&f->lock)
|
||||||
{
|
{
|
||||||
struct inet_frag_queue *q;
|
struct inet_frag_queue *q;
|
||||||
|
int depth = 0;
|
||||||
|
|
||||||
hlist_for_each_entry(q, &f->hash[hash], list) {
|
hlist_for_each_entry(q, &f->hash[hash], list) {
|
||||||
if (q->net == nf && f->match(q, key)) {
|
if (q->net == nf && f->match(q, key)) {
|
||||||
|
@ -284,9 +286,25 @@ struct inet_frag_queue *inet_frag_find(struct netns_frags *nf,
|
||||||
read_unlock(&f->lock);
|
read_unlock(&f->lock);
|
||||||
return q;
|
return q;
|
||||||
}
|
}
|
||||||
|
depth++;
|
||||||
}
|
}
|
||||||
read_unlock(&f->lock);
|
read_unlock(&f->lock);
|
||||||
|
|
||||||
return inet_frag_create(nf, f, key);
|
if (depth <= INETFRAGS_MAXDEPTH)
|
||||||
|
return inet_frag_create(nf, f, key);
|
||||||
|
else
|
||||||
|
return ERR_PTR(-ENOBUFS);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(inet_frag_find);
|
EXPORT_SYMBOL(inet_frag_find);
|
||||||
|
|
||||||
|
void inet_frag_maybe_warn_overflow(struct inet_frag_queue *q,
|
||||||
|
const char *prefix)
|
||||||
|
{
|
||||||
|
static const char msg[] = "inet_frag_find: Fragment hash bucket"
|
||||||
|
" list length grew over limit " __stringify(INETFRAGS_MAXDEPTH)
|
||||||
|
". Dropping fragment.\n";
|
||||||
|
|
||||||
|
if (PTR_ERR(q) == -ENOBUFS)
|
||||||
|
LIMIT_NETDEBUG(KERN_WARNING "%s%s", prefix, msg);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(inet_frag_maybe_warn_overflow);
|
||||||
|
|
|
@ -292,14 +292,11 @@ static inline struct ipq *ip_find(struct net *net, struct iphdr *iph, u32 user)
|
||||||
hash = ipqhashfn(iph->id, iph->saddr, iph->daddr, iph->protocol);
|
hash = ipqhashfn(iph->id, iph->saddr, iph->daddr, iph->protocol);
|
||||||
|
|
||||||
q = inet_frag_find(&net->ipv4.frags, &ip4_frags, &arg, hash);
|
q = inet_frag_find(&net->ipv4.frags, &ip4_frags, &arg, hash);
|
||||||
if (q == NULL)
|
if (IS_ERR_OR_NULL(q)) {
|
||||||
goto out_nomem;
|
inet_frag_maybe_warn_overflow(q, pr_fmt());
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
return container_of(q, struct ipq, q);
|
return container_of(q, struct ipq, q);
|
||||||
|
|
||||||
out_nomem:
|
|
||||||
LIMIT_NETDEBUG(KERN_ERR pr_fmt("ip_frag_create: no memory left !\n"));
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Is the fragment too far ahead to be part of ipq? */
|
/* Is the fragment too far ahead to be part of ipq? */
|
||||||
|
|
|
@ -798,10 +798,7 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev
|
||||||
|
|
||||||
if (dev->header_ops && dev->type == ARPHRD_IPGRE) {
|
if (dev->header_ops && dev->type == ARPHRD_IPGRE) {
|
||||||
gre_hlen = 0;
|
gre_hlen = 0;
|
||||||
if (skb->protocol == htons(ETH_P_IP))
|
tiph = (const struct iphdr *)skb->data;
|
||||||
tiph = (const struct iphdr *)skb->data;
|
|
||||||
else
|
|
||||||
tiph = &tunnel->parms.iph;
|
|
||||||
} else {
|
} else {
|
||||||
gre_hlen = tunnel->hlen;
|
gre_hlen = tunnel->hlen;
|
||||||
tiph = &tunnel->parms.iph;
|
tiph = &tunnel->parms.iph;
|
||||||
|
|
|
@ -370,7 +370,6 @@ int ip_options_compile(struct net *net,
|
||||||
}
|
}
|
||||||
switch (optptr[3]&0xF) {
|
switch (optptr[3]&0xF) {
|
||||||
case IPOPT_TS_TSONLY:
|
case IPOPT_TS_TSONLY:
|
||||||
opt->ts = optptr - iph;
|
|
||||||
if (skb)
|
if (skb)
|
||||||
timeptr = &optptr[optptr[2]-1];
|
timeptr = &optptr[optptr[2]-1];
|
||||||
opt->ts_needtime = 1;
|
opt->ts_needtime = 1;
|
||||||
|
@ -381,7 +380,6 @@ int ip_options_compile(struct net *net,
|
||||||
pp_ptr = optptr + 2;
|
pp_ptr = optptr + 2;
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
opt->ts = optptr - iph;
|
|
||||||
if (rt) {
|
if (rt) {
|
||||||
spec_dst_fill(&spec_dst, skb);
|
spec_dst_fill(&spec_dst, skb);
|
||||||
memcpy(&optptr[optptr[2]-1], &spec_dst, 4);
|
memcpy(&optptr[optptr[2]-1], &spec_dst, 4);
|
||||||
|
@ -396,7 +394,6 @@ int ip_options_compile(struct net *net,
|
||||||
pp_ptr = optptr + 2;
|
pp_ptr = optptr + 2;
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
opt->ts = optptr - iph;
|
|
||||||
{
|
{
|
||||||
__be32 addr;
|
__be32 addr;
|
||||||
memcpy(&addr, &optptr[optptr[2]-1], 4);
|
memcpy(&addr, &optptr[optptr[2]-1], 4);
|
||||||
|
@ -429,12 +426,12 @@ int ip_options_compile(struct net *net,
|
||||||
pp_ptr = optptr + 3;
|
pp_ptr = optptr + 3;
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
opt->ts = optptr - iph;
|
|
||||||
if (skb) {
|
if (skb) {
|
||||||
optptr[3] = (optptr[3]&0xF)|((overflow+1)<<4);
|
optptr[3] = (optptr[3]&0xF)|((overflow+1)<<4);
|
||||||
opt->is_changed = 1;
|
opt->is_changed = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
opt->ts = optptr - iph;
|
||||||
break;
|
break;
|
||||||
case IPOPT_RA:
|
case IPOPT_RA:
|
||||||
if (optlen < 4) {
|
if (optlen < 4) {
|
||||||
|
|
|
@ -775,7 +775,7 @@ struct sk_buff *sk_stream_alloc_skb(struct sock *sk, int size, gfp_t gfp)
|
||||||
* Make sure that we have exactly size bytes
|
* Make sure that we have exactly size bytes
|
||||||
* available to the caller, no more, no less.
|
* available to the caller, no more, no less.
|
||||||
*/
|
*/
|
||||||
skb->avail_size = size;
|
skb->reserved_tailroom = skb->end - skb->tail - size;
|
||||||
return skb;
|
return skb;
|
||||||
}
|
}
|
||||||
__kfree_skb(skb);
|
__kfree_skb(skb);
|
||||||
|
|
|
@ -274,13 +274,6 @@ static void tcp_v4_mtu_reduced(struct sock *sk)
|
||||||
struct inet_sock *inet = inet_sk(sk);
|
struct inet_sock *inet = inet_sk(sk);
|
||||||
u32 mtu = tcp_sk(sk)->mtu_info;
|
u32 mtu = tcp_sk(sk)->mtu_info;
|
||||||
|
|
||||||
/* We are not interested in TCP_LISTEN and open_requests (SYN-ACKs
|
|
||||||
* send out by Linux are always <576bytes so they should go through
|
|
||||||
* unfragmented).
|
|
||||||
*/
|
|
||||||
if (sk->sk_state == TCP_LISTEN)
|
|
||||||
return;
|
|
||||||
|
|
||||||
dst = inet_csk_update_pmtu(sk, mtu);
|
dst = inet_csk_update_pmtu(sk, mtu);
|
||||||
if (!dst)
|
if (!dst)
|
||||||
return;
|
return;
|
||||||
|
@ -408,6 +401,13 @@ void tcp_v4_err(struct sk_buff *icmp_skb, u32 info)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
if (code == ICMP_FRAG_NEEDED) { /* PMTU discovery (RFC1191) */
|
if (code == ICMP_FRAG_NEEDED) { /* PMTU discovery (RFC1191) */
|
||||||
|
/* We are not interested in TCP_LISTEN and open_requests
|
||||||
|
* (SYN-ACKs send out by Linux are always <576bytes so
|
||||||
|
* they should go through unfragmented).
|
||||||
|
*/
|
||||||
|
if (sk->sk_state == TCP_LISTEN)
|
||||||
|
goto out;
|
||||||
|
|
||||||
tp->mtu_info = info;
|
tp->mtu_info = info;
|
||||||
if (!sock_owned_by_user(sk)) {
|
if (!sock_owned_by_user(sk)) {
|
||||||
tcp_v4_mtu_reduced(sk);
|
tcp_v4_mtu_reduced(sk);
|
||||||
|
|
|
@ -1298,7 +1298,6 @@ static void __pskb_trim_head(struct sk_buff *skb, int len)
|
||||||
eat = min_t(int, len, skb_headlen(skb));
|
eat = min_t(int, len, skb_headlen(skb));
|
||||||
if (eat) {
|
if (eat) {
|
||||||
__skb_pull(skb, eat);
|
__skb_pull(skb, eat);
|
||||||
skb->avail_size -= eat;
|
|
||||||
len -= eat;
|
len -= eat;
|
||||||
if (!len)
|
if (!len)
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -14,6 +14,8 @@
|
||||||
* 2 of the License, or (at your option) any later version.
|
* 2 of the License, or (at your option) any later version.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define pr_fmt(fmt) "IPv6-nf: " fmt
|
||||||
|
|
||||||
#include <linux/errno.h>
|
#include <linux/errno.h>
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
#include <linux/string.h>
|
#include <linux/string.h>
|
||||||
|
@ -180,13 +182,11 @@ static inline struct frag_queue *fq_find(struct net *net, __be32 id,
|
||||||
|
|
||||||
q = inet_frag_find(&net->nf_frag.frags, &nf_frags, &arg, hash);
|
q = inet_frag_find(&net->nf_frag.frags, &nf_frags, &arg, hash);
|
||||||
local_bh_enable();
|
local_bh_enable();
|
||||||
if (q == NULL)
|
if (IS_ERR_OR_NULL(q)) {
|
||||||
goto oom;
|
inet_frag_maybe_warn_overflow(q, pr_fmt());
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
return container_of(q, struct frag_queue, q);
|
return container_of(q, struct frag_queue, q);
|
||||||
|
|
||||||
oom:
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,9 @@
|
||||||
* YOSHIFUJI,H. @USAGI Always remove fragment header to
|
* YOSHIFUJI,H. @USAGI Always remove fragment header to
|
||||||
* calculate ICV correctly.
|
* calculate ICV correctly.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define pr_fmt(fmt) "IPv6: " fmt
|
||||||
|
|
||||||
#include <linux/errno.h>
|
#include <linux/errno.h>
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
#include <linux/string.h>
|
#include <linux/string.h>
|
||||||
|
@ -185,9 +188,10 @@ fq_find(struct net *net, __be32 id, const struct in6_addr *src, const struct in6
|
||||||
hash = inet6_hash_frag(id, src, dst, ip6_frags.rnd);
|
hash = inet6_hash_frag(id, src, dst, ip6_frags.rnd);
|
||||||
|
|
||||||
q = inet_frag_find(&net->ipv6.frags, &ip6_frags, &arg, hash);
|
q = inet_frag_find(&net->ipv6.frags, &ip6_frags, &arg, hash);
|
||||||
if (q == NULL)
|
if (IS_ERR_OR_NULL(q)) {
|
||||||
|
inet_frag_maybe_warn_overflow(q, pr_fmt());
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
return container_of(q, struct frag_queue, q);
|
return container_of(q, struct frag_queue, q);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -389,6 +389,13 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type == ICMPV6_PKT_TOOBIG) {
|
if (type == ICMPV6_PKT_TOOBIG) {
|
||||||
|
/* We are not interested in TCP_LISTEN and open_requests
|
||||||
|
* (SYN-ACKs send out by Linux are always <576bytes so
|
||||||
|
* they should go through unfragmented).
|
||||||
|
*/
|
||||||
|
if (sk->sk_state == TCP_LISTEN)
|
||||||
|
goto out;
|
||||||
|
|
||||||
tp->mtu_info = ntohl(info);
|
tp->mtu_info = ntohl(info);
|
||||||
if (!sock_owned_by_user(sk))
|
if (!sock_owned_by_user(sk))
|
||||||
tcp_v6_mtu_reduced(sk);
|
tcp_v6_mtu_reduced(sk);
|
||||||
|
|
|
@ -68,7 +68,8 @@ static void nfc_llcp_socket_purge(struct nfc_llcp_sock *sock)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void nfc_llcp_socket_release(struct nfc_llcp_local *local, bool listen)
|
static void nfc_llcp_socket_release(struct nfc_llcp_local *local, bool listen,
|
||||||
|
int err)
|
||||||
{
|
{
|
||||||
struct sock *sk;
|
struct sock *sk;
|
||||||
struct hlist_node *tmp;
|
struct hlist_node *tmp;
|
||||||
|
@ -100,7 +101,10 @@ static void nfc_llcp_socket_release(struct nfc_llcp_local *local, bool listen)
|
||||||
|
|
||||||
nfc_llcp_accept_unlink(accept_sk);
|
nfc_llcp_accept_unlink(accept_sk);
|
||||||
|
|
||||||
|
if (err)
|
||||||
|
accept_sk->sk_err = err;
|
||||||
accept_sk->sk_state = LLCP_CLOSED;
|
accept_sk->sk_state = LLCP_CLOSED;
|
||||||
|
accept_sk->sk_state_change(sk);
|
||||||
|
|
||||||
bh_unlock_sock(accept_sk);
|
bh_unlock_sock(accept_sk);
|
||||||
|
|
||||||
|
@ -123,7 +127,10 @@ static void nfc_llcp_socket_release(struct nfc_llcp_local *local, bool listen)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (err)
|
||||||
|
sk->sk_err = err;
|
||||||
sk->sk_state = LLCP_CLOSED;
|
sk->sk_state = LLCP_CLOSED;
|
||||||
|
sk->sk_state_change(sk);
|
||||||
|
|
||||||
bh_unlock_sock(sk);
|
bh_unlock_sock(sk);
|
||||||
|
|
||||||
|
@ -133,6 +140,36 @@ static void nfc_llcp_socket_release(struct nfc_llcp_local *local, bool listen)
|
||||||
}
|
}
|
||||||
|
|
||||||
write_unlock(&local->sockets.lock);
|
write_unlock(&local->sockets.lock);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If we want to keep the listening sockets alive,
|
||||||
|
* we don't touch the RAW ones.
|
||||||
|
*/
|
||||||
|
if (listen == true)
|
||||||
|
return;
|
||||||
|
|
||||||
|
write_lock(&local->raw_sockets.lock);
|
||||||
|
|
||||||
|
sk_for_each_safe(sk, tmp, &local->raw_sockets.head) {
|
||||||
|
llcp_sock = nfc_llcp_sock(sk);
|
||||||
|
|
||||||
|
bh_lock_sock(sk);
|
||||||
|
|
||||||
|
nfc_llcp_socket_purge(llcp_sock);
|
||||||
|
|
||||||
|
if (err)
|
||||||
|
sk->sk_err = err;
|
||||||
|
sk->sk_state = LLCP_CLOSED;
|
||||||
|
sk->sk_state_change(sk);
|
||||||
|
|
||||||
|
bh_unlock_sock(sk);
|
||||||
|
|
||||||
|
sock_orphan(sk);
|
||||||
|
|
||||||
|
sk_del_node_init(sk);
|
||||||
|
}
|
||||||
|
|
||||||
|
write_unlock(&local->raw_sockets.lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct nfc_llcp_local *nfc_llcp_local_get(struct nfc_llcp_local *local)
|
struct nfc_llcp_local *nfc_llcp_local_get(struct nfc_llcp_local *local)
|
||||||
|
@ -142,6 +179,17 @@ struct nfc_llcp_local *nfc_llcp_local_get(struct nfc_llcp_local *local)
|
||||||
return local;
|
return local;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void local_cleanup(struct nfc_llcp_local *local, bool listen)
|
||||||
|
{
|
||||||
|
nfc_llcp_socket_release(local, listen, ENXIO);
|
||||||
|
del_timer_sync(&local->link_timer);
|
||||||
|
skb_queue_purge(&local->tx_queue);
|
||||||
|
cancel_work_sync(&local->tx_work);
|
||||||
|
cancel_work_sync(&local->rx_work);
|
||||||
|
cancel_work_sync(&local->timeout_work);
|
||||||
|
kfree_skb(local->rx_pending);
|
||||||
|
}
|
||||||
|
|
||||||
static void local_release(struct kref *ref)
|
static void local_release(struct kref *ref)
|
||||||
{
|
{
|
||||||
struct nfc_llcp_local *local;
|
struct nfc_llcp_local *local;
|
||||||
|
@ -149,13 +197,7 @@ static void local_release(struct kref *ref)
|
||||||
local = container_of(ref, struct nfc_llcp_local, ref);
|
local = container_of(ref, struct nfc_llcp_local, ref);
|
||||||
|
|
||||||
list_del(&local->list);
|
list_del(&local->list);
|
||||||
nfc_llcp_socket_release(local, false);
|
local_cleanup(local, false);
|
||||||
del_timer_sync(&local->link_timer);
|
|
||||||
skb_queue_purge(&local->tx_queue);
|
|
||||||
cancel_work_sync(&local->tx_work);
|
|
||||||
cancel_work_sync(&local->rx_work);
|
|
||||||
cancel_work_sync(&local->timeout_work);
|
|
||||||
kfree_skb(local->rx_pending);
|
|
||||||
kfree(local);
|
kfree(local);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1348,7 +1390,7 @@ void nfc_llcp_mac_is_down(struct nfc_dev *dev)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* Close and purge all existing sockets */
|
/* Close and purge all existing sockets */
|
||||||
nfc_llcp_socket_release(local, true);
|
nfc_llcp_socket_release(local, true, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void nfc_llcp_mac_is_up(struct nfc_dev *dev, u32 target_idx,
|
void nfc_llcp_mac_is_up(struct nfc_dev *dev, u32 target_idx,
|
||||||
|
@ -1427,6 +1469,8 @@ void nfc_llcp_unregister_device(struct nfc_dev *dev)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
local_cleanup(local, false);
|
||||||
|
|
||||||
nfc_llcp_local_put(local);
|
nfc_llcp_local_put(local);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -278,6 +278,8 @@ struct sock *nfc_llcp_accept_dequeue(struct sock *parent,
|
||||||
|
|
||||||
pr_debug("Returning sk state %d\n", sk->sk_state);
|
pr_debug("Returning sk state %d\n", sk->sk_state);
|
||||||
|
|
||||||
|
sk_acceptq_removed(parent);
|
||||||
|
|
||||||
return sk;
|
return sk;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -58,7 +58,7 @@ static int __pop_vlan_tci(struct sk_buff *skb, __be16 *current_tci)
|
||||||
|
|
||||||
if (skb->ip_summed == CHECKSUM_COMPLETE)
|
if (skb->ip_summed == CHECKSUM_COMPLETE)
|
||||||
skb->csum = csum_sub(skb->csum, csum_partial(skb->data
|
skb->csum = csum_sub(skb->csum, csum_partial(skb->data
|
||||||
+ ETH_HLEN, VLAN_HLEN, 0));
|
+ (2 * ETH_ALEN), VLAN_HLEN, 0));
|
||||||
|
|
||||||
vhdr = (struct vlan_hdr *)(skb->data + ETH_HLEN);
|
vhdr = (struct vlan_hdr *)(skb->data + ETH_HLEN);
|
||||||
*current_tci = vhdr->h_vlan_TCI;
|
*current_tci = vhdr->h_vlan_TCI;
|
||||||
|
@ -115,7 +115,7 @@ static int push_vlan(struct sk_buff *skb, const struct ovs_action_push_vlan *vla
|
||||||
|
|
||||||
if (skb->ip_summed == CHECKSUM_COMPLETE)
|
if (skb->ip_summed == CHECKSUM_COMPLETE)
|
||||||
skb->csum = csum_add(skb->csum, csum_partial(skb->data
|
skb->csum = csum_add(skb->csum, csum_partial(skb->data
|
||||||
+ ETH_HLEN, VLAN_HLEN, 0));
|
+ (2 * ETH_ALEN), VLAN_HLEN, 0));
|
||||||
|
|
||||||
}
|
}
|
||||||
__vlan_hwaccel_put_tag(skb, ntohs(vlan->vlan_tci) & ~VLAN_TAG_PRESENT);
|
__vlan_hwaccel_put_tag(skb, ntohs(vlan->vlan_tci) & ~VLAN_TAG_PRESENT);
|
||||||
|
|
|
@ -394,6 +394,7 @@ static int queue_userspace_packet(struct net *net, int dp_ifindex,
|
||||||
|
|
||||||
skb_copy_and_csum_dev(skb, nla_data(nla));
|
skb_copy_and_csum_dev(skb, nla_data(nla));
|
||||||
|
|
||||||
|
genlmsg_end(user_skb, upcall);
|
||||||
err = genlmsg_unicast(net, user_skb, upcall_info->portid);
|
err = genlmsg_unicast(net, user_skb, upcall_info->portid);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
@ -1690,6 +1691,7 @@ static int ovs_vport_cmd_new(struct sk_buff *skb, struct genl_info *info)
|
||||||
if (IS_ERR(vport))
|
if (IS_ERR(vport))
|
||||||
goto exit_unlock;
|
goto exit_unlock;
|
||||||
|
|
||||||
|
err = 0;
|
||||||
reply = ovs_vport_cmd_build_info(vport, info->snd_portid, info->snd_seq,
|
reply = ovs_vport_cmd_build_info(vport, info->snd_portid, info->snd_seq,
|
||||||
OVS_VPORT_CMD_NEW);
|
OVS_VPORT_CMD_NEW);
|
||||||
if (IS_ERR(reply)) {
|
if (IS_ERR(reply)) {
|
||||||
|
@ -1771,6 +1773,7 @@ static int ovs_vport_cmd_del(struct sk_buff *skb, struct genl_info *info)
|
||||||
if (IS_ERR(reply))
|
if (IS_ERR(reply))
|
||||||
goto exit_unlock;
|
goto exit_unlock;
|
||||||
|
|
||||||
|
err = 0;
|
||||||
ovs_dp_detach_port(vport);
|
ovs_dp_detach_port(vport);
|
||||||
|
|
||||||
genl_notify(reply, genl_info_net(info), info->snd_portid,
|
genl_notify(reply, genl_info_net(info), info->snd_portid,
|
||||||
|
|
|
@ -482,7 +482,11 @@ static __be16 parse_ethertype(struct sk_buff *skb)
|
||||||
return htons(ETH_P_802_2);
|
return htons(ETH_P_802_2);
|
||||||
|
|
||||||
__skb_pull(skb, sizeof(struct llc_snap_hdr));
|
__skb_pull(skb, sizeof(struct llc_snap_hdr));
|
||||||
return llc->ethertype;
|
|
||||||
|
if (ntohs(llc->ethertype) >= 1536)
|
||||||
|
return llc->ethertype;
|
||||||
|
|
||||||
|
return htons(ETH_P_802_2);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int parse_icmpv6(struct sk_buff *skb, struct sw_flow_key *key,
|
static int parse_icmpv6(struct sk_buff *skb, struct sw_flow_key *key,
|
||||||
|
|
|
@ -43,8 +43,7 @@ static void netdev_port_receive(struct vport *vport, struct sk_buff *skb)
|
||||||
|
|
||||||
/* Make our own copy of the packet. Otherwise we will mangle the
|
/* Make our own copy of the packet. Otherwise we will mangle the
|
||||||
* packet for anyone who came before us (e.g. tcpdump via AF_PACKET).
|
* packet for anyone who came before us (e.g. tcpdump via AF_PACKET).
|
||||||
* (No one comes after us, since we tell handle_bridge() that we took
|
*/
|
||||||
* the packet.) */
|
|
||||||
skb = skb_share_check(skb, GFP_ATOMIC);
|
skb = skb_share_check(skb, GFP_ATOMIC);
|
||||||
if (unlikely(!skb))
|
if (unlikely(!skb))
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -325,8 +325,7 @@ int ovs_vport_get_options(const struct vport *vport, struct sk_buff *skb)
|
||||||
* @skb: skb that was received
|
* @skb: skb that was received
|
||||||
*
|
*
|
||||||
* Must be called with rcu_read_lock. The packet cannot be shared and
|
* Must be called with rcu_read_lock. The packet cannot be shared and
|
||||||
* skb->data should point to the Ethernet header. The caller must have already
|
* skb->data should point to the Ethernet header.
|
||||||
* called compute_ip_summed() to initialize the checksumming fields.
|
|
||||||
*/
|
*/
|
||||||
void ovs_vport_receive(struct vport *vport, struct sk_buff *skb)
|
void ovs_vport_receive(struct vport *vport, struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1079,7 +1079,7 @@ struct sctp_transport *sctp_assoc_lookup_tsn(struct sctp_association *asoc,
|
||||||
transports) {
|
transports) {
|
||||||
|
|
||||||
if (transport == active)
|
if (transport == active)
|
||||||
break;
|
continue;
|
||||||
list_for_each_entry(chunk, &transport->transmitted,
|
list_for_each_entry(chunk, &transport->transmitted,
|
||||||
transmitted_list) {
|
transmitted_list) {
|
||||||
if (key == chunk->subh.data_hdr->tsn) {
|
if (key == chunk->subh.data_hdr->tsn) {
|
||||||
|
|
|
@ -2082,7 +2082,7 @@ sctp_disposition_t sctp_sf_do_5_2_4_dupcook(struct net *net,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Delete the tempory new association. */
|
/* Delete the tempory new association. */
|
||||||
sctp_add_cmd_sf(commands, SCTP_CMD_NEW_ASOC, SCTP_ASOC(new_asoc));
|
sctp_add_cmd_sf(commands, SCTP_CMD_SET_ASOC, SCTP_ASOC(new_asoc));
|
||||||
sctp_add_cmd_sf(commands, SCTP_CMD_DELETE_TCB, SCTP_NULL());
|
sctp_add_cmd_sf(commands, SCTP_CMD_DELETE_TCB, SCTP_NULL());
|
||||||
|
|
||||||
/* Restore association pointer to provide SCTP command interpeter
|
/* Restore association pointer to provide SCTP command interpeter
|
||||||
|
|
Loading…
Reference in New Issue