Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Pull networking fixes from David Miller: "Looks like a lot, but mostly driver fixes scattered all over as usual. Of note: 1) Add conditional sched in nf conntrack in cleanup to avoid NMI watchdogs. From Florian Westphal. 2) Fix deadlock in nfnetlink cttimeout, also from Floarian. 3) Fix handling of slaves in bonding ARP monitor validation, from Jay Vosburgh. 4) Callers of ip_cmsg_send() are responsible for freeing IP options, some were not doing so. Fix from Eric Dumazet. 5) Fix per-cpu bugs in mvneta driver, from Gregory CLEMENT. 6) Fix vlan handling in mv88e6xxx DSA driver, from Vivien Didelot. 7) bcm7xxx PHY driver bug fixes from Florian Fainelli. 8) Avoid unaligned accesses to protocol headers wrt. GRE, from Alexander Duyck. 9) SKB leaks and other problems in arc_emac driver, from Alexander Kochetkov. 10) tcp_v4_inbound_md5_hash() releases listener socket instead of request socket on error path, oops. Fix from Eric Dumazet. 11) Missing socket release in pppoe_rcv_core() that seems to have existed basically forever. From Guillaume Nault. 12) Missing slave_dev unregister in dsa_slave_create() error path, from Florian Fainelli. 13) crypto_alloc_hash() never returns NULL, fix return value check in __tcp_alloc_md5sig_pool. From Insu Yun. 14) Properly expire exception route entries in ipv4, from Xin Long. 15) Fix races in tcp/dccp listener socket dismantle, from Eric Dumazet. 16) Don't set IFF_TX_SKB_SHARING in vxlan, geneve, or GRE, it's not legal. These drivers modify the SKB on transmit. From Jiri Benc. 17) Fix regression in the initialziation of netdev->tx_queue_len. From Phil Sutter. 18) Missing unlock in tipc_nl_add_bc_link() error path, from Insu Yun. 19) SCTP port hash sizing does not properly ensure that table is a power of two in size. From Neil Horman. 20) Fix initializing of software copy of MAC address in fmvj18x_cs driver, from Ken Kawasaki" * git://git.kernel.org/pub/scm/linux/kernel/git/davem/net: (129 commits) bnx2x: Fix 84833 phy command handler bnx2x: Fix led setting for 84858 phy. bnx2x: Correct 84858 PHY fw version bnx2x: Fix 84833 RX CRC bnx2x: Fix link-forcing for KR2 net: ethernet: davicom: fix devicetree irq resource fmvj18x_cs: fix incorrect indexing of dev->dev_addr[] when copying the MAC address Driver: Vmxnet3: Update Rx ring 2 max size net: netcp: rework the code for get/set sw_data in dma desc soc: ti: knav_dma: rename pad in struct knav_dma_desc to sw_data net: ti: netcp: restore get/set_pad_info() functionality MAINTAINERS: Drop myself as xen netback maintainer sctp: Fix port hash table size computation can: ems_usb: Fix possible tx overflow Bluetooth: hci_core: Avoid mixing up req_complete and req_complete_skb net: bcmgenet: Fix internal PHY link state af_unix: Don't use continue to re-execute unix_stream_read_generic loop unix_diag: fix incorrect sign extension in unix_lookup_by_ino bnxt_en: Failure to update PHY is not fatal condition. bnxt_en: Remove unnecessary call to update PHY settings. ...
This commit is contained in:
commit
dea08e6044
|
@ -82,8 +82,8 @@ Example:
|
|||
"ch16", "ch17", "ch18", "ch19",
|
||||
"ch20", "ch21", "ch22", "ch23",
|
||||
"ch24";
|
||||
clocks = <&mstp8_clks R8A7795_CLK_ETHERAVB>;
|
||||
power-domains = <&cpg_clocks>;
|
||||
clocks = <&cpg CPG_MOD 812>;
|
||||
power-domains = <&cpg>;
|
||||
phy-mode = "rgmii-id";
|
||||
phy-handle = <&phy0>;
|
||||
|
||||
|
|
|
@ -12013,7 +12013,6 @@ F: arch/arm64/xen/
|
|||
F: arch/arm64/include/asm/xen/
|
||||
|
||||
XEN NETWORK BACKEND DRIVER
|
||||
M: Ian Campbell <ian.campbell@citrix.com>
|
||||
M: Wei Liu <wei.liu2@citrix.com>
|
||||
L: xen-devel@lists.xenproject.org (moderated for non-subscribers)
|
||||
L: netdev@vger.kernel.org
|
||||
|
|
|
@ -1681,9 +1681,12 @@ static int __mlx4_ib_modify_qp(struct ib_qp *ibqp,
|
|||
}
|
||||
|
||||
if (qp->ibqp.uobject)
|
||||
context->usr_page = cpu_to_be32(to_mucontext(ibqp->uobject->context)->uar.index);
|
||||
context->usr_page = cpu_to_be32(
|
||||
mlx4_to_hw_uar_index(dev->dev,
|
||||
to_mucontext(ibqp->uobject->context)->uar.index));
|
||||
else
|
||||
context->usr_page = cpu_to_be32(dev->priv_uar.index);
|
||||
context->usr_page = cpu_to_be32(
|
||||
mlx4_to_hw_uar_index(dev->dev, dev->priv_uar.index));
|
||||
|
||||
if (attr_mask & IB_QP_DEST_QPN)
|
||||
context->remote_qpn = cpu_to_be32(attr->dest_qp_num);
|
||||
|
|
|
@ -373,13 +373,7 @@ static void gigaset_freecshw(struct cardstate *cs)
|
|||
|
||||
static void gigaset_device_release(struct device *dev)
|
||||
{
|
||||
struct cardstate *cs = dev_get_drvdata(dev);
|
||||
|
||||
if (!cs)
|
||||
return;
|
||||
dev_set_drvdata(dev, NULL);
|
||||
kfree(cs->hw.ser);
|
||||
cs->hw.ser = NULL;
|
||||
kfree(container_of(dev, struct ser_cardstate, dev.dev));
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -408,7 +402,6 @@ static int gigaset_initcshw(struct cardstate *cs)
|
|||
cs->hw.ser = NULL;
|
||||
return rc;
|
||||
}
|
||||
dev_set_drvdata(&cs->hw.ser->dev.dev, cs);
|
||||
|
||||
tasklet_init(&cs->write_tasklet,
|
||||
gigaset_modem_fill, (unsigned long) cs);
|
||||
|
|
|
@ -392,7 +392,7 @@ read_dma(struct tiger_ch *bc, u32 idx, int cnt)
|
|||
}
|
||||
stat = bchannel_get_rxbuf(&bc->bch, cnt);
|
||||
/* only transparent use the count here, HDLC overun is detected later */
|
||||
if (stat == ENOMEM) {
|
||||
if (stat == -ENOMEM) {
|
||||
pr_warning("%s.B%d: No memory for %d bytes\n",
|
||||
card->name, bc->bch.nr, cnt);
|
||||
return;
|
||||
|
|
|
@ -214,6 +214,8 @@ static void bond_uninit(struct net_device *bond_dev);
|
|||
static struct rtnl_link_stats64 *bond_get_stats(struct net_device *bond_dev,
|
||||
struct rtnl_link_stats64 *stats);
|
||||
static void bond_slave_arr_handler(struct work_struct *work);
|
||||
static bool bond_time_in_interval(struct bonding *bond, unsigned long last_act,
|
||||
int mod);
|
||||
|
||||
/*---------------------------- General routines -----------------------------*/
|
||||
|
||||
|
@ -2127,6 +2129,7 @@ static void bond_miimon_commit(struct bonding *bond)
|
|||
continue;
|
||||
|
||||
case BOND_LINK_UP:
|
||||
bond_update_speed_duplex(slave);
|
||||
bond_set_slave_link_state(slave, BOND_LINK_UP,
|
||||
BOND_SLAVE_NOTIFY_NOW);
|
||||
slave->last_link_up = jiffies;
|
||||
|
@ -2459,7 +2462,7 @@ int bond_arp_rcv(const struct sk_buff *skb, struct bonding *bond,
|
|||
struct slave *slave)
|
||||
{
|
||||
struct arphdr *arp = (struct arphdr *)skb->data;
|
||||
struct slave *curr_active_slave;
|
||||
struct slave *curr_active_slave, *curr_arp_slave;
|
||||
unsigned char *arp_ptr;
|
||||
__be32 sip, tip;
|
||||
int alen, is_arp = skb->protocol == __cpu_to_be16(ETH_P_ARP);
|
||||
|
@ -2506,26 +2509,41 @@ int bond_arp_rcv(const struct sk_buff *skb, struct bonding *bond,
|
|||
&sip, &tip);
|
||||
|
||||
curr_active_slave = rcu_dereference(bond->curr_active_slave);
|
||||
curr_arp_slave = rcu_dereference(bond->current_arp_slave);
|
||||
|
||||
/* Backup slaves won't see the ARP reply, but do come through
|
||||
* here for each ARP probe (so we swap the sip/tip to validate
|
||||
* the probe). In a "redundant switch, common router" type of
|
||||
* configuration, the ARP probe will (hopefully) travel from
|
||||
* the active, through one switch, the router, then the other
|
||||
* switch before reaching the backup.
|
||||
/* We 'trust' the received ARP enough to validate it if:
|
||||
*
|
||||
* We 'trust' the arp requests if there is an active slave and
|
||||
* it received valid arp reply(s) after it became active. This
|
||||
* is done to avoid endless looping when we can't reach the
|
||||
* (a) the slave receiving the ARP is active (which includes the
|
||||
* current ARP slave, if any), or
|
||||
*
|
||||
* (b) the receiving slave isn't active, but there is a currently
|
||||
* active slave and it received valid arp reply(s) after it became
|
||||
* the currently active slave, or
|
||||
*
|
||||
* (c) there is an ARP slave that sent an ARP during the prior ARP
|
||||
* interval, and we receive an ARP reply on any slave. We accept
|
||||
* these because switch FDB update delays may deliver the ARP
|
||||
* reply to a slave other than the sender of the ARP request.
|
||||
*
|
||||
* Note: for (b), backup slaves are receiving the broadcast ARP
|
||||
* request, not a reply. This request passes from the sending
|
||||
* slave through the L2 switch(es) to the receiving slave. Since
|
||||
* this is checking the request, sip/tip are swapped for
|
||||
* validation.
|
||||
*
|
||||
* This is done to avoid endless looping when we can't reach the
|
||||
* arp_ip_target and fool ourselves with our own arp requests.
|
||||
*/
|
||||
|
||||
if (bond_is_active_slave(slave))
|
||||
bond_validate_arp(bond, slave, sip, tip);
|
||||
else if (curr_active_slave &&
|
||||
time_after(slave_last_rx(bond, curr_active_slave),
|
||||
curr_active_slave->last_link_up))
|
||||
bond_validate_arp(bond, slave, tip, sip);
|
||||
else if (curr_arp_slave && (arp->ar_op == htons(ARPOP_REPLY)) &&
|
||||
bond_time_in_interval(bond,
|
||||
dev_trans_start(curr_arp_slave->dev), 1))
|
||||
bond_validate_arp(bond, slave, sip, tip);
|
||||
|
||||
out_unlock:
|
||||
if (arp != (struct arphdr *)skb->data)
|
||||
|
|
|
@ -117,6 +117,9 @@ MODULE_LICENSE("GPL v2");
|
|||
*/
|
||||
#define EMS_USB_ARM7_CLOCK 8000000
|
||||
|
||||
#define CPC_TX_QUEUE_TRIGGER_LOW 25
|
||||
#define CPC_TX_QUEUE_TRIGGER_HIGH 35
|
||||
|
||||
/*
|
||||
* CAN-Message representation in a CPC_MSG. Message object type is
|
||||
* CPC_MSG_TYPE_CAN_FRAME or CPC_MSG_TYPE_RTR_FRAME or
|
||||
|
@ -278,6 +281,11 @@ static void ems_usb_read_interrupt_callback(struct urb *urb)
|
|||
switch (urb->status) {
|
||||
case 0:
|
||||
dev->free_slots = dev->intr_in_buffer[1];
|
||||
if(dev->free_slots > CPC_TX_QUEUE_TRIGGER_HIGH){
|
||||
if (netif_queue_stopped(netdev)){
|
||||
netif_wake_queue(netdev);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case -ECONNRESET: /* unlink */
|
||||
|
@ -526,8 +534,6 @@ static void ems_usb_write_bulk_callback(struct urb *urb)
|
|||
/* Release context */
|
||||
context->echo_index = MAX_TX_URBS;
|
||||
|
||||
if (netif_queue_stopped(netdev))
|
||||
netif_wake_queue(netdev);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -587,7 +593,7 @@ static int ems_usb_start(struct ems_usb *dev)
|
|||
int err, i;
|
||||
|
||||
dev->intr_in_buffer[0] = 0;
|
||||
dev->free_slots = 15; /* initial size */
|
||||
dev->free_slots = 50; /* initial size */
|
||||
|
||||
for (i = 0; i < MAX_RX_URBS; i++) {
|
||||
struct urb *urb = NULL;
|
||||
|
@ -835,7 +841,7 @@ static netdev_tx_t ems_usb_start_xmit(struct sk_buff *skb, struct net_device *ne
|
|||
|
||||
/* Slow down tx path */
|
||||
if (atomic_read(&dev->active_tx_urbs) >= MAX_TX_URBS ||
|
||||
dev->free_slots < 5) {
|
||||
dev->free_slots < CPC_TX_QUEUE_TRIGGER_LOW) {
|
||||
netif_stop_queue(netdev);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
static const struct mv88e6xxx_switch_id mv88e6352_table[] = {
|
||||
{ PORT_SWITCH_ID_6172, "Marvell 88E6172" },
|
||||
{ PORT_SWITCH_ID_6176, "Marvell 88E6176" },
|
||||
{ PORT_SWITCH_ID_6240, "Marvell 88E6240" },
|
||||
{ PORT_SWITCH_ID_6320, "Marvell 88E6320" },
|
||||
{ PORT_SWITCH_ID_6320_A1, "Marvell 88E6320 (A1)" },
|
||||
{ PORT_SWITCH_ID_6320_A2, "Marvell 88e6320 (A2)" },
|
||||
|
|
|
@ -1555,7 +1555,7 @@ static int _mv88e6xxx_port_vlan_del(struct dsa_switch *ds, int port, u16 vid)
|
|||
|
||||
if (vlan.vid != vid || !vlan.valid ||
|
||||
vlan.data[port] == GLOBAL_VTU_DATA_MEMBER_TAG_NON_MEMBER)
|
||||
return -ENOENT;
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
vlan.data[port] = GLOBAL_VTU_DATA_MEMBER_TAG_NON_MEMBER;
|
||||
|
||||
|
@ -1582,6 +1582,7 @@ int mv88e6xxx_port_vlan_del(struct dsa_switch *ds, int port,
|
|||
const struct switchdev_obj_port_vlan *vlan)
|
||||
{
|
||||
struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
|
||||
const u16 defpvid = 4000 + ds->index * DSA_MAX_PORTS + port;
|
||||
u16 pvid, vid;
|
||||
int err = 0;
|
||||
|
||||
|
@ -1597,7 +1598,8 @@ int mv88e6xxx_port_vlan_del(struct dsa_switch *ds, int port,
|
|||
goto unlock;
|
||||
|
||||
if (vid == pvid) {
|
||||
err = _mv88e6xxx_port_pvid_set(ds, port, 0);
|
||||
/* restore reserved VLAN ID */
|
||||
err = _mv88e6xxx_port_pvid_set(ds, port, defpvid);
|
||||
if (err)
|
||||
goto unlock;
|
||||
}
|
||||
|
@ -1889,26 +1891,20 @@ unlock:
|
|||
|
||||
int mv88e6xxx_port_bridge_join(struct dsa_switch *ds, int port, u32 members)
|
||||
{
|
||||
struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
|
||||
const u16 pvid = 4000 + ds->index * DSA_MAX_PORTS + port;
|
||||
int err;
|
||||
|
||||
/* The port joined a bridge, so leave its reserved VLAN */
|
||||
mutex_lock(&ps->smi_mutex);
|
||||
err = _mv88e6xxx_port_vlan_del(ds, port, pvid);
|
||||
if (!err)
|
||||
err = _mv88e6xxx_port_pvid_set(ds, port, 0);
|
||||
mutex_unlock(&ps->smi_mutex);
|
||||
return err;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mv88e6xxx_port_bridge_leave(struct dsa_switch *ds, int port, u32 members)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mv88e6xxx_setup_port_default_vlan(struct dsa_switch *ds, int port)
|
||||
{
|
||||
struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
|
||||
const u16 pvid = 4000 + ds->index * DSA_MAX_PORTS + port;
|
||||
int err;
|
||||
|
||||
/* The port left the bridge, so join its reserved VLAN */
|
||||
mutex_lock(&ps->smi_mutex);
|
||||
err = _mv88e6xxx_port_vlan_add(ds, port, pvid, true);
|
||||
if (!err)
|
||||
|
@ -2192,8 +2188,7 @@ int mv88e6xxx_setup_ports(struct dsa_switch *ds)
|
|||
if (dsa_is_cpu_port(ds, i) || dsa_is_dsa_port(ds, i))
|
||||
continue;
|
||||
|
||||
/* setup the unbridged state */
|
||||
ret = mv88e6xxx_port_bridge_leave(ds, i, 0);
|
||||
ret = mv88e6xxx_setup_port_default_vlan(ds, i);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -1501,6 +1501,7 @@ static const struct pcmcia_device_id pcnet_ids[] = {
|
|||
PCMCIA_DEVICE_MANF_CARD(0x026f, 0x030a),
|
||||
PCMCIA_DEVICE_MANF_CARD(0x0274, 0x1103),
|
||||
PCMCIA_DEVICE_MANF_CARD(0x0274, 0x1121),
|
||||
PCMCIA_DEVICE_MANF_CARD(0xc001, 0x0009),
|
||||
PCMCIA_DEVICE_PROD_ID12("2408LAN", "Ethernet", 0x352fff7f, 0x00b2e941),
|
||||
PCMCIA_DEVICE_PROD_ID1234("Socket", "CF 10/100 Ethernet Card", "Revision B", "05/11/06", 0xb38bcc2e, 0x4de88352, 0xeaca6c8d, 0x7e57c22e),
|
||||
PCMCIA_DEVICE_PROD_ID123("Cardwell", "PCMCIA", "ETHERNET", 0x9533672e, 0x281f1c5d, 0x3ff7175b),
|
||||
|
|
|
@ -2380,7 +2380,7 @@ static int et131x_tx_dma_memory_alloc(struct et131x_adapter *adapter)
|
|||
sizeof(u32),
|
||||
&tx_ring->tx_status_pa,
|
||||
GFP_KERNEL);
|
||||
if (!tx_ring->tx_status_pa) {
|
||||
if (!tx_ring->tx_status) {
|
||||
dev_err(&adapter->pdev->dev,
|
||||
"Cannot alloc memory for Tx status block\n");
|
||||
return -ENOMEM;
|
||||
|
|
|
@ -50,8 +50,8 @@ static const char version[] =
|
|||
static void write_rreg(u_long base, u_int reg, u_int val)
|
||||
{
|
||||
asm volatile(
|
||||
"str%?h %1, [%2] @ NET_RAP\n\t"
|
||||
"str%?h %0, [%2, #-4] @ NET_RDP"
|
||||
"strh %1, [%2] @ NET_RAP\n\t"
|
||||
"strh %0, [%2, #-4] @ NET_RDP"
|
||||
:
|
||||
: "r" (val), "r" (reg), "r" (ISAIO_BASE + 0x0464));
|
||||
}
|
||||
|
@ -60,8 +60,8 @@ static inline unsigned short read_rreg(u_long base_addr, u_int reg)
|
|||
{
|
||||
unsigned short v;
|
||||
asm volatile(
|
||||
"str%?h %1, [%2] @ NET_RAP\n\t"
|
||||
"ldr%?h %0, [%2, #-4] @ NET_RDP"
|
||||
"strh %1, [%2] @ NET_RAP\n\t"
|
||||
"ldrh %0, [%2, #-4] @ NET_RDP"
|
||||
: "=r" (v)
|
||||
: "r" (reg), "r" (ISAIO_BASE + 0x0464));
|
||||
return v;
|
||||
|
@ -70,8 +70,8 @@ static inline unsigned short read_rreg(u_long base_addr, u_int reg)
|
|||
static inline void write_ireg(u_long base, u_int reg, u_int val)
|
||||
{
|
||||
asm volatile(
|
||||
"str%?h %1, [%2] @ NET_RAP\n\t"
|
||||
"str%?h %0, [%2, #8] @ NET_IDP"
|
||||
"strh %1, [%2] @ NET_RAP\n\t"
|
||||
"strh %0, [%2, #8] @ NET_IDP"
|
||||
:
|
||||
: "r" (val), "r" (reg), "r" (ISAIO_BASE + 0x0464));
|
||||
}
|
||||
|
@ -80,8 +80,8 @@ static inline unsigned short read_ireg(u_long base_addr, u_int reg)
|
|||
{
|
||||
u_short v;
|
||||
asm volatile(
|
||||
"str%?h %1, [%2] @ NAT_RAP\n\t"
|
||||
"ldr%?h %0, [%2, #8] @ NET_IDP\n\t"
|
||||
"strh %1, [%2] @ NAT_RAP\n\t"
|
||||
"ldrh %0, [%2, #8] @ NET_IDP\n\t"
|
||||
: "=r" (v)
|
||||
: "r" (reg), "r" (ISAIO_BASE + 0x0464));
|
||||
return v;
|
||||
|
@ -96,7 +96,7 @@ am_writebuffer(struct net_device *dev, u_int offset, unsigned char *buf, unsigne
|
|||
offset = ISAMEM_BASE + (offset << 1);
|
||||
length = (length + 1) & ~1;
|
||||
if ((int)buf & 2) {
|
||||
asm volatile("str%?h %2, [%0], #4"
|
||||
asm volatile("strh %2, [%0], #4"
|
||||
: "=&r" (offset) : "0" (offset), "r" (buf[0] | (buf[1] << 8)));
|
||||
buf += 2;
|
||||
length -= 2;
|
||||
|
@ -104,20 +104,20 @@ am_writebuffer(struct net_device *dev, u_int offset, unsigned char *buf, unsigne
|
|||
while (length > 8) {
|
||||
register unsigned int tmp asm("r2"), tmp2 asm("r3");
|
||||
asm volatile(
|
||||
"ldm%?ia %0!, {%1, %2}"
|
||||
"ldmia %0!, {%1, %2}"
|
||||
: "+r" (buf), "=&r" (tmp), "=&r" (tmp2));
|
||||
length -= 8;
|
||||
asm volatile(
|
||||
"str%?h %1, [%0], #4\n\t"
|
||||
"mov%? %1, %1, lsr #16\n\t"
|
||||
"str%?h %1, [%0], #4\n\t"
|
||||
"str%?h %2, [%0], #4\n\t"
|
||||
"mov%? %2, %2, lsr #16\n\t"
|
||||
"str%?h %2, [%0], #4"
|
||||
"strh %1, [%0], #4\n\t"
|
||||
"mov %1, %1, lsr #16\n\t"
|
||||
"strh %1, [%0], #4\n\t"
|
||||
"strh %2, [%0], #4\n\t"
|
||||
"mov %2, %2, lsr #16\n\t"
|
||||
"strh %2, [%0], #4"
|
||||
: "+r" (offset), "=&r" (tmp), "=&r" (tmp2));
|
||||
}
|
||||
while (length > 0) {
|
||||
asm volatile("str%?h %2, [%0], #4"
|
||||
asm volatile("strh %2, [%0], #4"
|
||||
: "=&r" (offset) : "0" (offset), "r" (buf[0] | (buf[1] << 8)));
|
||||
buf += 2;
|
||||
length -= 2;
|
||||
|
@ -132,23 +132,23 @@ am_readbuffer(struct net_device *dev, u_int offset, unsigned char *buf, unsigned
|
|||
if ((int)buf & 2) {
|
||||
unsigned int tmp;
|
||||
asm volatile(
|
||||
"ldr%?h %2, [%0], #4\n\t"
|
||||
"str%?b %2, [%1], #1\n\t"
|
||||
"mov%? %2, %2, lsr #8\n\t"
|
||||
"str%?b %2, [%1], #1"
|
||||
"ldrh %2, [%0], #4\n\t"
|
||||
"strb %2, [%1], #1\n\t"
|
||||
"mov %2, %2, lsr #8\n\t"
|
||||
"strb %2, [%1], #1"
|
||||
: "=&r" (offset), "=&r" (buf), "=r" (tmp): "0" (offset), "1" (buf));
|
||||
length -= 2;
|
||||
}
|
||||
while (length > 8) {
|
||||
register unsigned int tmp asm("r2"), tmp2 asm("r3"), tmp3;
|
||||
asm volatile(
|
||||
"ldr%?h %2, [%0], #4\n\t"
|
||||
"ldr%?h %4, [%0], #4\n\t"
|
||||
"ldr%?h %3, [%0], #4\n\t"
|
||||
"orr%? %2, %2, %4, lsl #16\n\t"
|
||||
"ldr%?h %4, [%0], #4\n\t"
|
||||
"orr%? %3, %3, %4, lsl #16\n\t"
|
||||
"stm%?ia %1!, {%2, %3}"
|
||||
"ldrh %2, [%0], #4\n\t"
|
||||
"ldrh %4, [%0], #4\n\t"
|
||||
"ldrh %3, [%0], #4\n\t"
|
||||
"orr %2, %2, %4, lsl #16\n\t"
|
||||
"ldrh %4, [%0], #4\n\t"
|
||||
"orr %3, %3, %4, lsl #16\n\t"
|
||||
"stmia %1!, {%2, %3}"
|
||||
: "=&r" (offset), "=&r" (buf), "=r" (tmp), "=r" (tmp2), "=r" (tmp3)
|
||||
: "0" (offset), "1" (buf));
|
||||
length -= 8;
|
||||
|
@ -156,10 +156,10 @@ am_readbuffer(struct net_device *dev, u_int offset, unsigned char *buf, unsigned
|
|||
while (length > 0) {
|
||||
unsigned int tmp;
|
||||
asm volatile(
|
||||
"ldr%?h %2, [%0], #4\n\t"
|
||||
"str%?b %2, [%1], #1\n\t"
|
||||
"mov%? %2, %2, lsr #8\n\t"
|
||||
"str%?b %2, [%1], #1"
|
||||
"ldrh %2, [%0], #4\n\t"
|
||||
"strb %2, [%1], #1\n\t"
|
||||
"mov %2, %2, lsr #8\n\t"
|
||||
"strb %2, [%1], #1"
|
||||
: "=&r" (offset), "=&r" (buf), "=r" (tmp) : "0" (offset), "1" (buf));
|
||||
length -= 2;
|
||||
}
|
||||
|
|
|
@ -547,8 +547,8 @@ static int __init lance_probe1(struct net_device *dev, int ioaddr, int irq, int
|
|||
/* Make certain the data structures used by the LANCE are aligned and DMAble. */
|
||||
|
||||
lp = kzalloc(sizeof(*lp), GFP_DMA | GFP_KERNEL);
|
||||
if(lp==NULL)
|
||||
return -ENODEV;
|
||||
if (!lp)
|
||||
return -ENOMEM;
|
||||
if (lance_debug > 6) printk(" (#0x%05lx)", (unsigned long)lp);
|
||||
dev->ml_priv = lp;
|
||||
lp->name = chipname;
|
||||
|
|
|
@ -163,7 +163,7 @@ static void arc_emac_tx_clean(struct net_device *ndev)
|
|||
struct sk_buff *skb = tx_buff->skb;
|
||||
unsigned int info = le32_to_cpu(txbd->info);
|
||||
|
||||
if ((info & FOR_EMAC) || !txbd->data)
|
||||
if ((info & FOR_EMAC) || !txbd->data || !skb)
|
||||
break;
|
||||
|
||||
if (unlikely(info & (DROP | DEFR | LTCL | UFLO))) {
|
||||
|
@ -191,6 +191,7 @@ static void arc_emac_tx_clean(struct net_device *ndev)
|
|||
|
||||
txbd->data = 0;
|
||||
txbd->info = 0;
|
||||
tx_buff->skb = NULL;
|
||||
|
||||
*txbd_dirty = (*txbd_dirty + 1) % TX_BD_NUM;
|
||||
}
|
||||
|
@ -446,6 +447,9 @@ static int arc_emac_open(struct net_device *ndev)
|
|||
*last_rx_bd = (*last_rx_bd + 1) % RX_BD_NUM;
|
||||
}
|
||||
|
||||
priv->txbd_curr = 0;
|
||||
priv->txbd_dirty = 0;
|
||||
|
||||
/* Clean Tx BD's */
|
||||
memset(priv->txbd, 0, TX_RING_SZ);
|
||||
|
||||
|
@ -513,6 +517,64 @@ static void arc_emac_set_rx_mode(struct net_device *ndev)
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* arc_free_tx_queue - free skb from tx queue
|
||||
* @ndev: Pointer to the network device.
|
||||
*
|
||||
* This function must be called while EMAC disable
|
||||
*/
|
||||
static void arc_free_tx_queue(struct net_device *ndev)
|
||||
{
|
||||
struct arc_emac_priv *priv = netdev_priv(ndev);
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < TX_BD_NUM; i++) {
|
||||
struct arc_emac_bd *txbd = &priv->txbd[i];
|
||||
struct buffer_state *tx_buff = &priv->tx_buff[i];
|
||||
|
||||
if (tx_buff->skb) {
|
||||
dma_unmap_single(&ndev->dev, dma_unmap_addr(tx_buff, addr),
|
||||
dma_unmap_len(tx_buff, len), DMA_TO_DEVICE);
|
||||
|
||||
/* return the sk_buff to system */
|
||||
dev_kfree_skb_irq(tx_buff->skb);
|
||||
}
|
||||
|
||||
txbd->info = 0;
|
||||
txbd->data = 0;
|
||||
tx_buff->skb = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* arc_free_rx_queue - free skb from rx queue
|
||||
* @ndev: Pointer to the network device.
|
||||
*
|
||||
* This function must be called while EMAC disable
|
||||
*/
|
||||
static void arc_free_rx_queue(struct net_device *ndev)
|
||||
{
|
||||
struct arc_emac_priv *priv = netdev_priv(ndev);
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < RX_BD_NUM; i++) {
|
||||
struct arc_emac_bd *rxbd = &priv->rxbd[i];
|
||||
struct buffer_state *rx_buff = &priv->rx_buff[i];
|
||||
|
||||
if (rx_buff->skb) {
|
||||
dma_unmap_single(&ndev->dev, dma_unmap_addr(rx_buff, addr),
|
||||
dma_unmap_len(rx_buff, len), DMA_FROM_DEVICE);
|
||||
|
||||
/* return the sk_buff to system */
|
||||
dev_kfree_skb_irq(rx_buff->skb);
|
||||
}
|
||||
|
||||
rxbd->info = 0;
|
||||
rxbd->data = 0;
|
||||
rx_buff->skb = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* arc_emac_stop - Close the network device.
|
||||
* @ndev: Pointer to the network device.
|
||||
|
@ -534,6 +596,10 @@ static int arc_emac_stop(struct net_device *ndev)
|
|||
/* Disable EMAC */
|
||||
arc_reg_clr(priv, R_CTRL, EN_MASK);
|
||||
|
||||
/* Return the sk_buff to system */
|
||||
arc_free_tx_queue(ndev);
|
||||
arc_free_rx_queue(ndev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -610,7 +676,6 @@ static int arc_emac_tx(struct sk_buff *skb, struct net_device *ndev)
|
|||
dma_unmap_addr_set(&priv->tx_buff[*txbd_curr], addr, addr);
|
||||
dma_unmap_len_set(&priv->tx_buff[*txbd_curr], len, len);
|
||||
|
||||
priv->tx_buff[*txbd_curr].skb = skb;
|
||||
priv->txbd[*txbd_curr].data = cpu_to_le32(addr);
|
||||
|
||||
/* Make sure pointer to data buffer is set */
|
||||
|
@ -620,6 +685,11 @@ static int arc_emac_tx(struct sk_buff *skb, struct net_device *ndev)
|
|||
|
||||
*info = cpu_to_le32(FOR_EMAC | FIRST_OR_LAST_MASK | len);
|
||||
|
||||
/* Make sure info word is set */
|
||||
wmb();
|
||||
|
||||
priv->tx_buff[*txbd_curr].skb = skb;
|
||||
|
||||
/* Increment index to point to the next BD */
|
||||
*txbd_curr = (*txbd_curr + 1) % TX_BD_NUM;
|
||||
|
||||
|
|
|
@ -6185,26 +6185,80 @@ static int bnx2x_format_ver(u32 num, u8 *str, u16 *len)
|
|||
shift -= 4;
|
||||
digit = ((num & mask) >> shift);
|
||||
if (digit == 0 && remove_leading_zeros) {
|
||||
mask = mask >> 4;
|
||||
continue;
|
||||
} else if (digit < 0xa)
|
||||
*str_ptr = '0';
|
||||
} else {
|
||||
if (digit < 0xa)
|
||||
*str_ptr = digit + '0';
|
||||
else
|
||||
*str_ptr = digit - 0xa + 'a';
|
||||
|
||||
remove_leading_zeros = 0;
|
||||
str_ptr++;
|
||||
(*len)--;
|
||||
}
|
||||
mask = mask >> 4;
|
||||
if (shift == 4*4) {
|
||||
if (remove_leading_zeros) {
|
||||
str_ptr++;
|
||||
(*len)--;
|
||||
}
|
||||
*str_ptr = '.';
|
||||
str_ptr++;
|
||||
(*len)--;
|
||||
remove_leading_zeros = 1;
|
||||
}
|
||||
}
|
||||
if (remove_leading_zeros)
|
||||
(*len)--;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bnx2x_3_seq_format_ver(u32 num, u8 *str, u16 *len)
|
||||
{
|
||||
u8 *str_ptr = str;
|
||||
u32 mask = 0x00f00000;
|
||||
u8 shift = 8*3;
|
||||
u8 digit;
|
||||
u8 remove_leading_zeros = 1;
|
||||
|
||||
if (*len < 10) {
|
||||
/* Need more than 10chars for this format */
|
||||
*str_ptr = '\0';
|
||||
(*len)--;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
while (shift > 0) {
|
||||
shift -= 4;
|
||||
digit = ((num & mask) >> shift);
|
||||
if (digit == 0 && remove_leading_zeros) {
|
||||
*str_ptr = '0';
|
||||
} else {
|
||||
if (digit < 0xa)
|
||||
*str_ptr = digit + '0';
|
||||
else
|
||||
*str_ptr = digit - 0xa + 'a';
|
||||
|
||||
remove_leading_zeros = 0;
|
||||
str_ptr++;
|
||||
(*len)--;
|
||||
}
|
||||
mask = mask >> 4;
|
||||
if ((shift == 4*4) || (shift == 4*2)) {
|
||||
if (remove_leading_zeros) {
|
||||
str_ptr++;
|
||||
(*len)--;
|
||||
}
|
||||
*str_ptr = '.';
|
||||
str_ptr++;
|
||||
(*len)--;
|
||||
remove_leading_zeros = 1;
|
||||
}
|
||||
}
|
||||
if (remove_leading_zeros)
|
||||
(*len)--;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bnx2x_null_format_ver(u32 spirom_ver, u8 *str, u16 *len)
|
||||
{
|
||||
|
@ -9677,8 +9731,9 @@ static void bnx2x_save_848xx_spirom_version(struct bnx2x_phy *phy,
|
|||
|
||||
if (bnx2x_is_8483x_8485x(phy)) {
|
||||
bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD, 0x400f, &fw_ver1);
|
||||
bnx2x_save_spirom_version(bp, port, fw_ver1 & 0xfff,
|
||||
phy->ver_addr);
|
||||
if (phy->type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84858)
|
||||
fw_ver1 &= 0xfff;
|
||||
bnx2x_save_spirom_version(bp, port, fw_ver1, phy->ver_addr);
|
||||
} else {
|
||||
/* For 32-bit registers in 848xx, access via MDIO2ARM i/f. */
|
||||
/* (1) set reg 0xc200_0014(SPI_BRIDGE_CTRL_2) to 0x03000000 */
|
||||
|
@ -9732,16 +9787,32 @@ static void bnx2x_save_848xx_spirom_version(struct bnx2x_phy *phy,
|
|||
static void bnx2x_848xx_set_led(struct bnx2x *bp,
|
||||
struct bnx2x_phy *phy)
|
||||
{
|
||||
u16 val, offset, i;
|
||||
u16 val, led3_blink_rate, offset, i;
|
||||
static struct bnx2x_reg_set reg_set[] = {
|
||||
{MDIO_PMA_DEVAD, MDIO_PMA_REG_8481_LED1_MASK, 0x0080},
|
||||
{MDIO_PMA_DEVAD, MDIO_PMA_REG_8481_LED2_MASK, 0x0018},
|
||||
{MDIO_PMA_DEVAD, MDIO_PMA_REG_8481_LED3_MASK, 0x0006},
|
||||
{MDIO_PMA_DEVAD, MDIO_PMA_REG_8481_LED3_BLINK, 0x0000},
|
||||
{MDIO_PMA_DEVAD, MDIO_PMA_REG_84823_CTL_SLOW_CLK_CNT_HIGH,
|
||||
MDIO_PMA_REG_84823_BLINK_RATE_VAL_15P9HZ},
|
||||
{MDIO_AN_DEVAD, 0xFFFB, 0xFFFD}
|
||||
};
|
||||
|
||||
if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84858) {
|
||||
/* Set LED5 source */
|
||||
bnx2x_cl45_write(bp, phy,
|
||||
MDIO_PMA_DEVAD,
|
||||
MDIO_PMA_REG_8481_LED5_MASK,
|
||||
0x90);
|
||||
led3_blink_rate = 0x000f;
|
||||
} else {
|
||||
led3_blink_rate = 0x0000;
|
||||
}
|
||||
/* Set LED3 BLINK */
|
||||
bnx2x_cl45_write(bp, phy,
|
||||
MDIO_PMA_DEVAD,
|
||||
MDIO_PMA_REG_8481_LED3_BLINK,
|
||||
led3_blink_rate);
|
||||
|
||||
/* PHYC_CTL_LED_CTL */
|
||||
bnx2x_cl45_read(bp, phy,
|
||||
MDIO_PMA_DEVAD,
|
||||
|
@ -9749,6 +9820,9 @@ static void bnx2x_848xx_set_led(struct bnx2x *bp,
|
|||
val &= 0xFE00;
|
||||
val |= 0x0092;
|
||||
|
||||
if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84858)
|
||||
val |= 2 << 12; /* LED5 ON based on source */
|
||||
|
||||
bnx2x_cl45_write(bp, phy,
|
||||
MDIO_PMA_DEVAD,
|
||||
MDIO_PMA_REG_8481_LINK_SIGNAL, val);
|
||||
|
@ -9762,10 +9836,17 @@ static void bnx2x_848xx_set_led(struct bnx2x *bp,
|
|||
else
|
||||
offset = MDIO_PMA_REG_84823_CTL_LED_CTL_1;
|
||||
|
||||
/* stretch_en for LED3*/
|
||||
if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84858)
|
||||
val = MDIO_PMA_REG_84858_ALLOW_GPHY_ACT |
|
||||
MDIO_PMA_REG_84823_LED3_STRETCH_EN;
|
||||
else
|
||||
val = MDIO_PMA_REG_84823_LED3_STRETCH_EN;
|
||||
|
||||
/* stretch_en for LEDs */
|
||||
bnx2x_cl45_read_or_write(bp, phy,
|
||||
MDIO_PMA_DEVAD, offset,
|
||||
MDIO_PMA_REG_84823_LED3_STRETCH_EN);
|
||||
MDIO_PMA_DEVAD,
|
||||
offset,
|
||||
val);
|
||||
}
|
||||
|
||||
static void bnx2x_848xx_specific_func(struct bnx2x_phy *phy,
|
||||
|
@ -9775,7 +9856,7 @@ static void bnx2x_848xx_specific_func(struct bnx2x_phy *phy,
|
|||
struct bnx2x *bp = params->bp;
|
||||
switch (action) {
|
||||
case PHY_INIT:
|
||||
if (!bnx2x_is_8483x_8485x(phy)) {
|
||||
if (bnx2x_is_8483x_8485x(phy)) {
|
||||
/* Save spirom version */
|
||||
bnx2x_save_848xx_spirom_version(phy, bp, params->port);
|
||||
}
|
||||
|
@ -10036,15 +10117,20 @@ static int bnx2x_84858_cmd_hdlr(struct bnx2x_phy *phy,
|
|||
|
||||
static int bnx2x_84833_cmd_hdlr(struct bnx2x_phy *phy,
|
||||
struct link_params *params, u16 fw_cmd,
|
||||
u16 cmd_args[], int argc)
|
||||
u16 cmd_args[], int argc, int process)
|
||||
{
|
||||
int idx;
|
||||
u16 val;
|
||||
struct bnx2x *bp = params->bp;
|
||||
int rc = 0;
|
||||
|
||||
if (process == PHY84833_MB_PROCESS2) {
|
||||
/* Write CMD_OPEN_OVERRIDE to STATUS reg */
|
||||
bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
|
||||
MDIO_848xx_CMD_HDLR_STATUS,
|
||||
PHY84833_STATUS_CMD_OPEN_OVERRIDE);
|
||||
}
|
||||
|
||||
for (idx = 0; idx < PHY848xx_CMDHDLR_WAIT; idx++) {
|
||||
bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD,
|
||||
MDIO_848xx_CMD_HDLR_STATUS, &val);
|
||||
|
@ -10054,15 +10140,27 @@ static int bnx2x_84833_cmd_hdlr(struct bnx2x_phy *phy,
|
|||
}
|
||||
if (idx >= PHY848xx_CMDHDLR_WAIT) {
|
||||
DP(NETIF_MSG_LINK, "FW cmd: FW not ready.\n");
|
||||
/* if the status is CMD_COMPLETE_PASS or CMD_COMPLETE_ERROR
|
||||
* clear the status to CMD_CLEAR_COMPLETE
|
||||
*/
|
||||
if (val == PHY84833_STATUS_CMD_COMPLETE_PASS ||
|
||||
val == PHY84833_STATUS_CMD_COMPLETE_ERROR) {
|
||||
bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
|
||||
MDIO_848xx_CMD_HDLR_STATUS,
|
||||
PHY84833_STATUS_CMD_CLEAR_COMPLETE);
|
||||
}
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Prepare argument(s) and issue command */
|
||||
if (process == PHY84833_MB_PROCESS1 ||
|
||||
process == PHY84833_MB_PROCESS2) {
|
||||
/* Prepare argument(s) */
|
||||
for (idx = 0; idx < argc; idx++) {
|
||||
bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
|
||||
MDIO_848xx_CMD_HDLR_DATA1 + idx,
|
||||
cmd_args[idx]);
|
||||
}
|
||||
}
|
||||
|
||||
bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
|
||||
MDIO_848xx_CMD_HDLR_COMMAND, fw_cmd);
|
||||
for (idx = 0; idx < PHY848xx_CMDHDLR_WAIT; idx++) {
|
||||
|
@ -10076,24 +10174,30 @@ static int bnx2x_84833_cmd_hdlr(struct bnx2x_phy *phy,
|
|||
if ((idx >= PHY848xx_CMDHDLR_WAIT) ||
|
||||
(val == PHY84833_STATUS_CMD_COMPLETE_ERROR)) {
|
||||
DP(NETIF_MSG_LINK, "FW cmd failed.\n");
|
||||
return -EINVAL;
|
||||
rc = -EINVAL;
|
||||
}
|
||||
if (process == PHY84833_MB_PROCESS3 && rc == 0) {
|
||||
/* Gather returning data */
|
||||
for (idx = 0; idx < argc; idx++) {
|
||||
bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD,
|
||||
MDIO_848xx_CMD_HDLR_DATA1 + idx,
|
||||
&cmd_args[idx]);
|
||||
}
|
||||
}
|
||||
if (val == PHY84833_STATUS_CMD_COMPLETE_ERROR ||
|
||||
val == PHY84833_STATUS_CMD_COMPLETE_PASS) {
|
||||
bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
|
||||
MDIO_848xx_CMD_HDLR_STATUS,
|
||||
PHY84833_STATUS_CMD_CLEAR_COMPLETE);
|
||||
return 0;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int bnx2x_848xx_cmd_hdlr(struct bnx2x_phy *phy,
|
||||
struct link_params *params,
|
||||
u16 fw_cmd,
|
||||
u16 cmd_args[], int argc)
|
||||
u16 cmd_args[], int argc,
|
||||
int process)
|
||||
{
|
||||
struct bnx2x *bp = params->bp;
|
||||
|
||||
|
@ -10106,7 +10210,7 @@ static int bnx2x_848xx_cmd_hdlr(struct bnx2x_phy *phy,
|
|||
argc);
|
||||
} else {
|
||||
return bnx2x_84833_cmd_hdlr(phy, params, fw_cmd, cmd_args,
|
||||
argc);
|
||||
argc, process);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -10133,7 +10237,7 @@ static int bnx2x_848xx_pair_swap_cfg(struct bnx2x_phy *phy,
|
|||
|
||||
status = bnx2x_848xx_cmd_hdlr(phy, params,
|
||||
PHY848xx_CMD_SET_PAIR_SWAP, data,
|
||||
PHY848xx_CMDHDLR_MAX_ARGS);
|
||||
2, PHY84833_MB_PROCESS2);
|
||||
if (status == 0)
|
||||
DP(NETIF_MSG_LINK, "Pairswap OK, val=0x%x\n", data[1]);
|
||||
|
||||
|
@ -10222,8 +10326,8 @@ static int bnx2x_8483x_disable_eee(struct bnx2x_phy *phy,
|
|||
DP(NETIF_MSG_LINK, "Don't Advertise 10GBase-T EEE\n");
|
||||
|
||||
/* Prevent Phy from working in EEE and advertising it */
|
||||
rc = bnx2x_848xx_cmd_hdlr(phy, params,
|
||||
PHY848xx_CMD_SET_EEE_MODE, &cmd_args, 1);
|
||||
rc = bnx2x_848xx_cmd_hdlr(phy, params, PHY848xx_CMD_SET_EEE_MODE,
|
||||
&cmd_args, 1, PHY84833_MB_PROCESS1);
|
||||
if (rc) {
|
||||
DP(NETIF_MSG_LINK, "EEE disable failed.\n");
|
||||
return rc;
|
||||
|
@ -10240,8 +10344,8 @@ static int bnx2x_8483x_enable_eee(struct bnx2x_phy *phy,
|
|||
struct bnx2x *bp = params->bp;
|
||||
u16 cmd_args = 1;
|
||||
|
||||
rc = bnx2x_848xx_cmd_hdlr(phy, params,
|
||||
PHY848xx_CMD_SET_EEE_MODE, &cmd_args, 1);
|
||||
rc = bnx2x_848xx_cmd_hdlr(phy, params, PHY848xx_CMD_SET_EEE_MODE,
|
||||
&cmd_args, 1, PHY84833_MB_PROCESS1);
|
||||
if (rc) {
|
||||
DP(NETIF_MSG_LINK, "EEE enable failed.\n");
|
||||
return rc;
|
||||
|
@ -10362,7 +10466,7 @@ static int bnx2x_848x3_config_init(struct bnx2x_phy *phy,
|
|||
cmd_args[3] = PHY84833_CONSTANT_LATENCY;
|
||||
rc = bnx2x_848xx_cmd_hdlr(phy, params,
|
||||
PHY848xx_CMD_SET_EEE_MODE, cmd_args,
|
||||
PHY848xx_CMDHDLR_MAX_ARGS);
|
||||
4, PHY84833_MB_PROCESS1);
|
||||
if (rc)
|
||||
DP(NETIF_MSG_LINK, "Cfg AutogrEEEn failed.\n");
|
||||
}
|
||||
|
@ -10416,6 +10520,32 @@ static int bnx2x_848x3_config_init(struct bnx2x_phy *phy,
|
|||
vars->eee_status &= ~SHMEM_EEE_SUPPORTED_MASK;
|
||||
}
|
||||
|
||||
if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833) {
|
||||
/* Additional settings for jumbo packets in 1000BASE-T mode */
|
||||
/* Allow rx extended length */
|
||||
bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD,
|
||||
MDIO_AN_REG_8481_AUX_CTRL, &val);
|
||||
val |= 0x4000;
|
||||
bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
|
||||
MDIO_AN_REG_8481_AUX_CTRL, val);
|
||||
/* TX FIFO Elasticity LSB */
|
||||
bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD,
|
||||
MDIO_AN_REG_8481_1G_100T_EXT_CTRL, &val);
|
||||
val |= 0x1;
|
||||
bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
|
||||
MDIO_AN_REG_8481_1G_100T_EXT_CTRL, val);
|
||||
/* TX FIFO Elasticity MSB */
|
||||
/* Enable expansion register 0x46 (Pattern Generator status) */
|
||||
bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
|
||||
MDIO_AN_REG_8481_EXPANSION_REG_ACCESS, 0xf46);
|
||||
|
||||
bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD,
|
||||
MDIO_AN_REG_8481_EXPANSION_REG_RD_RW, &val);
|
||||
val |= 0x4000;
|
||||
bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
|
||||
MDIO_AN_REG_8481_EXPANSION_REG_RD_RW, val);
|
||||
}
|
||||
|
||||
if (bnx2x_is_8483x_8485x(phy)) {
|
||||
/* Bring PHY out of super isolate mode as the final step. */
|
||||
bnx2x_cl45_read_and_write(bp, phy,
|
||||
|
@ -10555,6 +10685,17 @@ static u8 bnx2x_848xx_read_status(struct bnx2x_phy *phy,
|
|||
return link_up;
|
||||
}
|
||||
|
||||
static int bnx2x_8485x_format_ver(u32 raw_ver, u8 *str, u16 *len)
|
||||
{
|
||||
int status = 0;
|
||||
u32 num;
|
||||
|
||||
num = ((raw_ver & 0xF80) >> 7) << 16 | ((raw_ver & 0x7F) << 8) |
|
||||
((raw_ver & 0xF000) >> 12);
|
||||
status = bnx2x_3_seq_format_ver(num, str, len);
|
||||
return status;
|
||||
}
|
||||
|
||||
static int bnx2x_848xx_format_ver(u32 raw_ver, u8 *str, u16 *len)
|
||||
{
|
||||
int status = 0;
|
||||
|
@ -10651,10 +10792,25 @@ static void bnx2x_848xx_set_link_led(struct bnx2x_phy *phy,
|
|||
0x0);
|
||||
|
||||
} else {
|
||||
/* LED 1 OFF */
|
||||
bnx2x_cl45_write(bp, phy,
|
||||
MDIO_PMA_DEVAD,
|
||||
MDIO_PMA_REG_8481_LED1_MASK,
|
||||
0x0);
|
||||
|
||||
if (phy->type ==
|
||||
PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84858) {
|
||||
/* LED 2 OFF */
|
||||
bnx2x_cl45_write(bp, phy,
|
||||
MDIO_PMA_DEVAD,
|
||||
MDIO_PMA_REG_8481_LED2_MASK,
|
||||
0x0);
|
||||
/* LED 3 OFF */
|
||||
bnx2x_cl45_write(bp, phy,
|
||||
MDIO_PMA_DEVAD,
|
||||
MDIO_PMA_REG_8481_LED3_MASK,
|
||||
0x0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case LED_MODE_FRONT_PANEL_OFF:
|
||||
|
@ -10713,6 +10869,19 @@ static void bnx2x_848xx_set_link_led(struct bnx2x_phy *phy,
|
|||
MDIO_PMA_REG_8481_SIGNAL_MASK,
|
||||
0x0);
|
||||
}
|
||||
if (phy->type ==
|
||||
PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84858) {
|
||||
/* LED 2 OFF */
|
||||
bnx2x_cl45_write(bp, phy,
|
||||
MDIO_PMA_DEVAD,
|
||||
MDIO_PMA_REG_8481_LED2_MASK,
|
||||
0x0);
|
||||
/* LED 3 OFF */
|
||||
bnx2x_cl45_write(bp, phy,
|
||||
MDIO_PMA_DEVAD,
|
||||
MDIO_PMA_REG_8481_LED3_MASK,
|
||||
0x0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case LED_MODE_ON:
|
||||
|
@ -10776,6 +10945,25 @@ static void bnx2x_848xx_set_link_led(struct bnx2x_phy *phy,
|
|||
params->port*4,
|
||||
NIG_MASK_MI_INT);
|
||||
}
|
||||
}
|
||||
if (phy->type ==
|
||||
PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84858) {
|
||||
/* Tell LED3 to constant on */
|
||||
bnx2x_cl45_read(bp, phy,
|
||||
MDIO_PMA_DEVAD,
|
||||
MDIO_PMA_REG_8481_LINK_SIGNAL,
|
||||
&val);
|
||||
val &= ~(7<<6);
|
||||
val |= (2<<6); /* A83B[8:6]= 2 */
|
||||
bnx2x_cl45_write(bp, phy,
|
||||
MDIO_PMA_DEVAD,
|
||||
MDIO_PMA_REG_8481_LINK_SIGNAL,
|
||||
val);
|
||||
bnx2x_cl45_write(bp, phy,
|
||||
MDIO_PMA_DEVAD,
|
||||
MDIO_PMA_REG_8481_LED3_MASK,
|
||||
0x20);
|
||||
} else {
|
||||
bnx2x_cl45_write(bp, phy,
|
||||
MDIO_PMA_DEVAD,
|
||||
MDIO_PMA_REG_8481_SIGNAL_MASK,
|
||||
|
@ -10853,6 +11041,17 @@ static void bnx2x_848xx_set_link_led(struct bnx2x_phy *phy,
|
|||
MDIO_PMA_DEVAD,
|
||||
MDIO_PMA_REG_8481_LINK_SIGNAL,
|
||||
val);
|
||||
if (phy->type ==
|
||||
PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84858) {
|
||||
bnx2x_cl45_write(bp, phy,
|
||||
MDIO_PMA_DEVAD,
|
||||
MDIO_PMA_REG_8481_LED2_MASK,
|
||||
0x18);
|
||||
bnx2x_cl45_write(bp, phy,
|
||||
MDIO_PMA_DEVAD,
|
||||
MDIO_PMA_REG_8481_LED3_MASK,
|
||||
0x06);
|
||||
}
|
||||
if (phy->type ==
|
||||
PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84834) {
|
||||
/* Restore LED4 source to external link,
|
||||
|
@ -11982,7 +12181,7 @@ static const struct bnx2x_phy phy_84858 = {
|
|||
.read_status = (read_status_t)bnx2x_848xx_read_status,
|
||||
.link_reset = (link_reset_t)bnx2x_848x3_link_reset,
|
||||
.config_loopback = (config_loopback_t)NULL,
|
||||
.format_fw_ver = (format_fw_ver_t)bnx2x_848xx_format_ver,
|
||||
.format_fw_ver = (format_fw_ver_t)bnx2x_8485x_format_ver,
|
||||
.hw_reset = (hw_reset_t)bnx2x_84833_hw_reset_phy,
|
||||
.set_link_led = (set_link_led_t)bnx2x_848xx_set_link_led,
|
||||
.phy_specific_func = (phy_specific_func_t)bnx2x_848xx_specific_func
|
||||
|
@ -13807,8 +14006,10 @@ void bnx2x_period_func(struct link_params *params, struct link_vars *vars)
|
|||
if (CHIP_IS_E3(bp)) {
|
||||
struct bnx2x_phy *phy = ¶ms->phy[INT_PHY];
|
||||
bnx2x_set_aer_mmd(params, phy);
|
||||
if ((phy->supported & SUPPORTED_20000baseKR2_Full) &&
|
||||
(phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_20G))
|
||||
if (((phy->req_line_speed == SPEED_AUTO_NEG) &&
|
||||
(phy->speed_cap_mask &
|
||||
PORT_HW_CFG_SPEED_CAPABILITY_D0_20G)) ||
|
||||
(phy->req_line_speed == SPEED_20000))
|
||||
bnx2x_check_kr2_wa(params, vars, phy);
|
||||
bnx2x_check_over_curr(params, vars);
|
||||
if (vars->rx_tx_asic_rst)
|
||||
|
|
|
@ -7296,6 +7296,8 @@ Theotherbitsarereservedandshouldbezero*/
|
|||
#define MDIO_PMA_REG_84823_CTL_LED_CTL_1 0xa8e3
|
||||
#define MDIO_PMA_REG_84833_CTL_LED_CTL_1 0xa8ec
|
||||
#define MDIO_PMA_REG_84823_LED3_STRETCH_EN 0x0080
|
||||
/* BCM84858 only */
|
||||
#define MDIO_PMA_REG_84858_ALLOW_GPHY_ACT 0x8000
|
||||
|
||||
/* BCM84833 only */
|
||||
#define MDIO_84833_TOP_CFG_FW_REV 0x400f
|
||||
|
@ -7337,6 +7339,10 @@ Theotherbitsarereservedandshouldbezero*/
|
|||
#define PHY84833_STATUS_CMD_NOT_OPEN_FOR_CMDS 0x0040
|
||||
#define PHY84833_STATUS_CMD_CLEAR_COMPLETE 0x0080
|
||||
#define PHY84833_STATUS_CMD_OPEN_OVERRIDE 0xa5a5
|
||||
/* Mailbox Process */
|
||||
#define PHY84833_MB_PROCESS1 1
|
||||
#define PHY84833_MB_PROCESS2 2
|
||||
#define PHY84833_MB_PROCESS3 3
|
||||
|
||||
/* Mailbox status set used by 84858 only */
|
||||
#define PHY84858_STATUS_CMD_RECEIVED 0x0001
|
||||
|
|
|
@ -69,7 +69,7 @@ MODULE_VERSION(DRV_MODULE_VERSION);
|
|||
#define BNXT_RX_DMA_OFFSET NET_SKB_PAD
|
||||
#define BNXT_RX_COPY_THRESH 256
|
||||
|
||||
#define BNXT_TX_PUSH_THRESH 92
|
||||
#define BNXT_TX_PUSH_THRESH 164
|
||||
|
||||
enum board_idx {
|
||||
BCM57301,
|
||||
|
@ -223,11 +223,12 @@ static netdev_tx_t bnxt_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||
}
|
||||
|
||||
if (free_size == bp->tx_ring_size && length <= bp->tx_push_thresh) {
|
||||
struct tx_push_bd *push = txr->tx_push;
|
||||
struct tx_bd *tx_push = &push->txbd1;
|
||||
struct tx_bd_ext *tx_push1 = &push->txbd2;
|
||||
void *pdata = tx_push1 + 1;
|
||||
int j;
|
||||
struct tx_push_buffer *tx_push_buf = txr->tx_push;
|
||||
struct tx_push_bd *tx_push = &tx_push_buf->push_bd;
|
||||
struct tx_bd_ext *tx_push1 = &tx_push->txbd2;
|
||||
void *pdata = tx_push_buf->data;
|
||||
u64 *end;
|
||||
int j, push_len;
|
||||
|
||||
/* Set COAL_NOW to be ready quickly for the next push */
|
||||
tx_push->tx_bd_len_flags_type =
|
||||
|
@ -247,6 +248,9 @@ static netdev_tx_t bnxt_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||
tx_push1->tx_bd_cfa_meta = cpu_to_le32(vlan_tag_flags);
|
||||
tx_push1->tx_bd_cfa_action = cpu_to_le32(cfa_action);
|
||||
|
||||
end = PTR_ALIGN(pdata + length + 1, 8) - 1;
|
||||
*end = 0;
|
||||
|
||||
skb_copy_from_linear_data(skb, pdata, len);
|
||||
pdata += len;
|
||||
for (j = 0; j < last_frag; j++) {
|
||||
|
@ -261,22 +265,29 @@ static netdev_tx_t bnxt_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||
pdata += skb_frag_size(frag);
|
||||
}
|
||||
|
||||
memcpy(txbd, tx_push, sizeof(*txbd));
|
||||
txbd->tx_bd_len_flags_type = tx_push->tx_bd_len_flags_type;
|
||||
txbd->tx_bd_haddr = txr->data_mapping;
|
||||
prod = NEXT_TX(prod);
|
||||
txbd = &txr->tx_desc_ring[TX_RING(prod)][TX_IDX(prod)];
|
||||
memcpy(txbd, tx_push1, sizeof(*txbd));
|
||||
prod = NEXT_TX(prod);
|
||||
push->doorbell =
|
||||
tx_push->doorbell =
|
||||
cpu_to_le32(DB_KEY_TX_PUSH | DB_LONG_TX_PUSH | prod);
|
||||
txr->tx_prod = prod;
|
||||
|
||||
netdev_tx_sent_queue(txq, skb->len);
|
||||
|
||||
__iowrite64_copy(txr->tx_doorbell, push,
|
||||
(length + sizeof(*push) + 8) / 8);
|
||||
push_len = (length + sizeof(*tx_push) + 7) / 8;
|
||||
if (push_len > 16) {
|
||||
__iowrite64_copy(txr->tx_doorbell, tx_push_buf, 16);
|
||||
__iowrite64_copy(txr->tx_doorbell + 4, tx_push_buf + 1,
|
||||
push_len - 16);
|
||||
} else {
|
||||
__iowrite64_copy(txr->tx_doorbell, tx_push_buf,
|
||||
push_len);
|
||||
}
|
||||
|
||||
tx_buf->is_push = 1;
|
||||
|
||||
goto tx_done;
|
||||
}
|
||||
|
||||
|
@ -1753,7 +1764,7 @@ static int bnxt_alloc_tx_rings(struct bnxt *bp)
|
|||
push_size = L1_CACHE_ALIGN(sizeof(struct tx_push_bd) +
|
||||
bp->tx_push_thresh);
|
||||
|
||||
if (push_size > 128) {
|
||||
if (push_size > 256) {
|
||||
push_size = 0;
|
||||
bp->tx_push_thresh = 0;
|
||||
}
|
||||
|
@ -1772,7 +1783,6 @@ static int bnxt_alloc_tx_rings(struct bnxt *bp)
|
|||
return rc;
|
||||
|
||||
if (bp->tx_push_size) {
|
||||
struct tx_bd *txbd;
|
||||
dma_addr_t mapping;
|
||||
|
||||
/* One pre-allocated DMA buffer to backup
|
||||
|
@ -1786,13 +1796,11 @@ static int bnxt_alloc_tx_rings(struct bnxt *bp)
|
|||
if (!txr->tx_push)
|
||||
return -ENOMEM;
|
||||
|
||||
txbd = &txr->tx_push->txbd1;
|
||||
|
||||
mapping = txr->tx_push_mapping +
|
||||
sizeof(struct tx_push_bd);
|
||||
txbd->tx_bd_haddr = cpu_to_le64(mapping);
|
||||
txr->data_mapping = cpu_to_le64(mapping);
|
||||
|
||||
memset(txbd + 1, 0, sizeof(struct tx_bd_ext));
|
||||
memset(txr->tx_push, 0, sizeof(struct tx_push_bd));
|
||||
}
|
||||
ring->queue_id = bp->q_info[j].queue_id;
|
||||
if (i % bp->tx_nr_rings_per_tc == (bp->tx_nr_rings_per_tc - 1))
|
||||
|
@ -4546,20 +4554,18 @@ static int bnxt_update_phy_setting(struct bnxt *bp)
|
|||
if (!(link_info->autoneg & BNXT_AUTONEG_FLOW_CTRL) &&
|
||||
link_info->force_pause_setting != link_info->req_flow_ctrl)
|
||||
update_pause = true;
|
||||
if (link_info->req_duplex != link_info->duplex_setting)
|
||||
update_link = true;
|
||||
if (!(link_info->autoneg & BNXT_AUTONEG_SPEED)) {
|
||||
if (BNXT_AUTO_MODE(link_info->auto_mode))
|
||||
update_link = true;
|
||||
if (link_info->req_link_speed != link_info->force_link_speed)
|
||||
update_link = true;
|
||||
if (link_info->req_duplex != link_info->duplex_setting)
|
||||
update_link = true;
|
||||
} else {
|
||||
if (link_info->auto_mode == BNXT_LINK_AUTO_NONE)
|
||||
update_link = true;
|
||||
if (link_info->advertising != link_info->auto_link_speeds)
|
||||
update_link = true;
|
||||
if (link_info->req_link_speed != link_info->auto_link_speed)
|
||||
update_link = true;
|
||||
}
|
||||
|
||||
if (update_link)
|
||||
|
@ -4636,7 +4642,7 @@ static int __bnxt_open_nic(struct bnxt *bp, bool irq_re_init, bool link_re_init)
|
|||
if (link_re_init) {
|
||||
rc = bnxt_update_phy_setting(bp);
|
||||
if (rc)
|
||||
goto open_err;
|
||||
netdev_warn(bp->dev, "failed to update phy settings\n");
|
||||
}
|
||||
|
||||
if (irq_re_init) {
|
||||
|
@ -4654,6 +4660,7 @@ static int __bnxt_open_nic(struct bnxt *bp, bool irq_re_init, bool link_re_init)
|
|||
/* Enable TX queues */
|
||||
bnxt_tx_enable(bp);
|
||||
mod_timer(&bp->timer, jiffies + bp->current_interval);
|
||||
bnxt_update_link(bp, true);
|
||||
|
||||
return 0;
|
||||
|
||||
|
@ -5670,22 +5677,16 @@ static int bnxt_probe_phy(struct bnxt *bp)
|
|||
}
|
||||
|
||||
/*initialize the ethool setting copy with NVM settings */
|
||||
if (BNXT_AUTO_MODE(link_info->auto_mode))
|
||||
link_info->autoneg |= BNXT_AUTONEG_SPEED;
|
||||
|
||||
if (link_info->auto_pause_setting & BNXT_LINK_PAUSE_BOTH) {
|
||||
if (link_info->auto_pause_setting == BNXT_LINK_PAUSE_BOTH)
|
||||
link_info->autoneg |= BNXT_AUTONEG_FLOW_CTRL;
|
||||
if (BNXT_AUTO_MODE(link_info->auto_mode)) {
|
||||
link_info->autoneg = BNXT_AUTONEG_SPEED |
|
||||
BNXT_AUTONEG_FLOW_CTRL;
|
||||
link_info->advertising = link_info->auto_link_speeds;
|
||||
link_info->req_flow_ctrl = link_info->auto_pause_setting;
|
||||
} else if (link_info->force_pause_setting & BNXT_LINK_PAUSE_BOTH) {
|
||||
} else {
|
||||
link_info->req_link_speed = link_info->force_link_speed;
|
||||
link_info->req_duplex = link_info->duplex_setting;
|
||||
link_info->req_flow_ctrl = link_info->force_pause_setting;
|
||||
}
|
||||
link_info->req_duplex = link_info->duplex_setting;
|
||||
if (link_info->autoneg & BNXT_AUTONEG_SPEED)
|
||||
link_info->req_link_speed = link_info->auto_link_speed;
|
||||
else
|
||||
link_info->req_link_speed = link_info->force_link_speed;
|
||||
link_info->advertising = link_info->auto_link_speeds;
|
||||
snprintf(phy_ver, PHY_VER_STR_LEN, " ph %d.%d.%d",
|
||||
link_info->phy_ver[0],
|
||||
link_info->phy_ver[1],
|
||||
|
|
|
@ -411,8 +411,8 @@ struct rx_tpa_end_cmp_ext {
|
|||
|
||||
#define BNXT_NUM_TESTS(bp) 0
|
||||
|
||||
#define BNXT_DEFAULT_RX_RING_SIZE 1023
|
||||
#define BNXT_DEFAULT_TX_RING_SIZE 512
|
||||
#define BNXT_DEFAULT_RX_RING_SIZE 511
|
||||
#define BNXT_DEFAULT_TX_RING_SIZE 511
|
||||
|
||||
#define MAX_TPA 64
|
||||
|
||||
|
@ -523,10 +523,16 @@ struct bnxt_ring_struct {
|
|||
|
||||
struct tx_push_bd {
|
||||
__le32 doorbell;
|
||||
struct tx_bd txbd1;
|
||||
__le32 tx_bd_len_flags_type;
|
||||
u32 tx_bd_opaque;
|
||||
struct tx_bd_ext txbd2;
|
||||
};
|
||||
|
||||
struct tx_push_buffer {
|
||||
struct tx_push_bd push_bd;
|
||||
u32 data[25];
|
||||
};
|
||||
|
||||
struct bnxt_tx_ring_info {
|
||||
struct bnxt_napi *bnapi;
|
||||
u16 tx_prod;
|
||||
|
@ -538,8 +544,9 @@ struct bnxt_tx_ring_info {
|
|||
|
||||
dma_addr_t tx_desc_mapping[MAX_TX_PAGES];
|
||||
|
||||
struct tx_push_bd *tx_push;
|
||||
struct tx_push_buffer *tx_push;
|
||||
dma_addr_t tx_push_mapping;
|
||||
__le64 data_mapping;
|
||||
|
||||
#define BNXT_DEV_STATE_CLOSING 0x1
|
||||
u32 dev_state;
|
||||
|
|
|
@ -486,15 +486,8 @@ static u32 bnxt_fw_to_ethtool_support_spds(struct bnxt_link_info *link_info)
|
|||
speed_mask |= SUPPORTED_2500baseX_Full;
|
||||
if (fw_speeds & BNXT_LINK_SPEED_MSK_10GB)
|
||||
speed_mask |= SUPPORTED_10000baseT_Full;
|
||||
/* TODO: support 25GB, 50GB with different cable type */
|
||||
if (fw_speeds & BNXT_LINK_SPEED_MSK_20GB)
|
||||
speed_mask |= SUPPORTED_20000baseMLD2_Full |
|
||||
SUPPORTED_20000baseKR2_Full;
|
||||
if (fw_speeds & BNXT_LINK_SPEED_MSK_40GB)
|
||||
speed_mask |= SUPPORTED_40000baseKR4_Full |
|
||||
SUPPORTED_40000baseCR4_Full |
|
||||
SUPPORTED_40000baseSR4_Full |
|
||||
SUPPORTED_40000baseLR4_Full;
|
||||
speed_mask |= SUPPORTED_40000baseCR4_Full;
|
||||
|
||||
return speed_mask;
|
||||
}
|
||||
|
@ -514,15 +507,8 @@ static u32 bnxt_fw_to_ethtool_advertised_spds(struct bnxt_link_info *link_info)
|
|||
speed_mask |= ADVERTISED_2500baseX_Full;
|
||||
if (fw_speeds & BNXT_LINK_SPEED_MSK_10GB)
|
||||
speed_mask |= ADVERTISED_10000baseT_Full;
|
||||
/* TODO: how to advertise 20, 25, 40, 50GB with different cable type ?*/
|
||||
if (fw_speeds & BNXT_LINK_SPEED_MSK_20GB)
|
||||
speed_mask |= ADVERTISED_20000baseMLD2_Full |
|
||||
ADVERTISED_20000baseKR2_Full;
|
||||
if (fw_speeds & BNXT_LINK_SPEED_MSK_40GB)
|
||||
speed_mask |= ADVERTISED_40000baseKR4_Full |
|
||||
ADVERTISED_40000baseCR4_Full |
|
||||
ADVERTISED_40000baseSR4_Full |
|
||||
ADVERTISED_40000baseLR4_Full;
|
||||
speed_mask |= ADVERTISED_40000baseCR4_Full;
|
||||
return speed_mask;
|
||||
}
|
||||
|
||||
|
@ -557,11 +543,12 @@ static int bnxt_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
|
|||
u16 ethtool_speed;
|
||||
|
||||
cmd->supported = bnxt_fw_to_ethtool_support_spds(link_info);
|
||||
cmd->supported |= SUPPORTED_Pause | SUPPORTED_Asym_Pause;
|
||||
|
||||
if (link_info->auto_link_speeds)
|
||||
cmd->supported |= SUPPORTED_Autoneg;
|
||||
|
||||
if (BNXT_AUTO_MODE(link_info->auto_mode)) {
|
||||
if (link_info->autoneg) {
|
||||
cmd->advertising =
|
||||
bnxt_fw_to_ethtool_advertised_spds(link_info);
|
||||
cmd->advertising |= ADVERTISED_Autoneg;
|
||||
|
@ -570,28 +557,16 @@ static int bnxt_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
|
|||
cmd->autoneg = AUTONEG_DISABLE;
|
||||
cmd->advertising = 0;
|
||||
}
|
||||
if (link_info->auto_pause_setting & BNXT_LINK_PAUSE_BOTH) {
|
||||
if (link_info->autoneg & BNXT_AUTONEG_FLOW_CTRL) {
|
||||
if ((link_info->auto_pause_setting & BNXT_LINK_PAUSE_BOTH) ==
|
||||
BNXT_LINK_PAUSE_BOTH) {
|
||||
cmd->advertising |= ADVERTISED_Pause;
|
||||
cmd->supported |= SUPPORTED_Pause;
|
||||
} else {
|
||||
cmd->advertising |= ADVERTISED_Asym_Pause;
|
||||
cmd->supported |= SUPPORTED_Asym_Pause;
|
||||
if (link_info->auto_pause_setting &
|
||||
BNXT_LINK_PAUSE_RX)
|
||||
cmd->advertising |= ADVERTISED_Pause;
|
||||
}
|
||||
} else if (link_info->force_pause_setting & BNXT_LINK_PAUSE_BOTH) {
|
||||
if ((link_info->force_pause_setting & BNXT_LINK_PAUSE_BOTH) ==
|
||||
BNXT_LINK_PAUSE_BOTH) {
|
||||
cmd->supported |= SUPPORTED_Pause;
|
||||
} else {
|
||||
cmd->supported |= SUPPORTED_Asym_Pause;
|
||||
if (link_info->force_pause_setting &
|
||||
BNXT_LINK_PAUSE_RX)
|
||||
cmd->supported |= SUPPORTED_Pause;
|
||||
}
|
||||
}
|
||||
|
||||
cmd->port = PORT_NONE;
|
||||
|
@ -670,6 +645,9 @@ static u16 bnxt_get_fw_auto_link_speeds(u32 advertising)
|
|||
if (advertising & ADVERTISED_10000baseT_Full)
|
||||
fw_speed_mask |= BNXT_LINK_SPEED_MSK_10GB;
|
||||
|
||||
if (advertising & ADVERTISED_40000baseCR4_Full)
|
||||
fw_speed_mask |= BNXT_LINK_SPEED_MSK_40GB;
|
||||
|
||||
return fw_speed_mask;
|
||||
}
|
||||
|
||||
|
@ -729,7 +707,7 @@ static int bnxt_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
|
|||
speed = ethtool_cmd_speed(cmd);
|
||||
link_info->req_link_speed = bnxt_get_fw_speed(dev, speed);
|
||||
link_info->req_duplex = BNXT_LINK_DUPLEX_FULL;
|
||||
link_info->autoneg &= ~BNXT_AUTONEG_SPEED;
|
||||
link_info->autoneg = 0;
|
||||
link_info->advertising = 0;
|
||||
}
|
||||
|
||||
|
@ -748,8 +726,7 @@ static void bnxt_get_pauseparam(struct net_device *dev,
|
|||
|
||||
if (BNXT_VF(bp))
|
||||
return;
|
||||
epause->autoneg = !!(link_info->auto_pause_setting &
|
||||
BNXT_LINK_PAUSE_BOTH);
|
||||
epause->autoneg = !!(link_info->autoneg & BNXT_AUTONEG_FLOW_CTRL);
|
||||
epause->rx_pause = ((link_info->pause & BNXT_LINK_PAUSE_RX) != 0);
|
||||
epause->tx_pause = ((link_info->pause & BNXT_LINK_PAUSE_TX) != 0);
|
||||
}
|
||||
|
@ -765,6 +742,9 @@ static int bnxt_set_pauseparam(struct net_device *dev,
|
|||
return rc;
|
||||
|
||||
if (epause->autoneg) {
|
||||
if (!(link_info->autoneg & BNXT_AUTONEG_SPEED))
|
||||
return -EINVAL;
|
||||
|
||||
link_info->autoneg |= BNXT_AUTONEG_FLOW_CTRL;
|
||||
link_info->req_flow_ctrl |= BNXT_LINK_PAUSE_BOTH;
|
||||
} else {
|
||||
|
|
|
@ -2445,8 +2445,7 @@ static void bcmgenet_irq_task(struct work_struct *work)
|
|||
}
|
||||
|
||||
/* Link UP/DOWN event */
|
||||
if ((priv->hw_params->flags & GENET_HAS_MDIO_INTR) &&
|
||||
(priv->irq0_stat & UMAC_IRQ_LINK_EVENT)) {
|
||||
if (priv->irq0_stat & UMAC_IRQ_LINK_EVENT) {
|
||||
phy_mac_interrupt(priv->phydev,
|
||||
!!(priv->irq0_stat & UMAC_IRQ_LINK_UP));
|
||||
priv->irq0_stat &= ~UMAC_IRQ_LINK_EVENT;
|
||||
|
|
|
@ -1683,7 +1683,7 @@ static int octeon_setup_droq(struct octeon_device *oct, int q_no, int num_descs,
|
|||
dev_dbg(&oct->pci_dev->dev, "Creating Droq: %d\n", q_no);
|
||||
/* droq creation and local register settings. */
|
||||
ret_val = octeon_create_droq(oct, q_no, num_descs, desc_size, app_ctx);
|
||||
if (ret_val == -1)
|
||||
if (ret_val < 0)
|
||||
return ret_val;
|
||||
|
||||
if (ret_val == 1) {
|
||||
|
@ -2524,7 +2524,7 @@ static void handle_timestamp(struct octeon_device *oct,
|
|||
|
||||
octeon_swap_8B_data(&resp->timestamp, 1);
|
||||
|
||||
if (unlikely((skb_shinfo(skb)->tx_flags | SKBTX_IN_PROGRESS) != 0)) {
|
||||
if (unlikely((skb_shinfo(skb)->tx_flags & SKBTX_IN_PROGRESS) != 0)) {
|
||||
struct skb_shared_hwtstamps ts;
|
||||
u64 ns = resp->timestamp;
|
||||
|
||||
|
|
|
@ -983,5 +983,5 @@ int octeon_create_droq(struct octeon_device *oct,
|
|||
|
||||
create_droq_fail:
|
||||
octeon_delete_droq(oct, q_no);
|
||||
return -1;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
|
|
@ -574,8 +574,7 @@ static inline void nicvf_set_rxhash(struct net_device *netdev,
|
|||
|
||||
static void nicvf_rcv_pkt_handler(struct net_device *netdev,
|
||||
struct napi_struct *napi,
|
||||
struct cmp_queue *cq,
|
||||
struct cqe_rx_t *cqe_rx, int cqe_type)
|
||||
struct cqe_rx_t *cqe_rx)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
struct nicvf *nic = netdev_priv(netdev);
|
||||
|
@ -591,7 +590,7 @@ static void nicvf_rcv_pkt_handler(struct net_device *netdev,
|
|||
}
|
||||
|
||||
/* Check for errors */
|
||||
err = nicvf_check_cqe_rx_errs(nic, cq, cqe_rx);
|
||||
err = nicvf_check_cqe_rx_errs(nic, cqe_rx);
|
||||
if (err && !cqe_rx->rb_cnt)
|
||||
return;
|
||||
|
||||
|
@ -682,8 +681,7 @@ loop:
|
|||
cq_idx, cq_desc->cqe_type);
|
||||
switch (cq_desc->cqe_type) {
|
||||
case CQE_TYPE_RX:
|
||||
nicvf_rcv_pkt_handler(netdev, napi, cq,
|
||||
cq_desc, CQE_TYPE_RX);
|
||||
nicvf_rcv_pkt_handler(netdev, napi, cq_desc);
|
||||
work_done++;
|
||||
break;
|
||||
case CQE_TYPE_SEND:
|
||||
|
@ -1125,7 +1123,6 @@ int nicvf_stop(struct net_device *netdev)
|
|||
|
||||
/* Clear multiqset info */
|
||||
nic->pnicvf = nic;
|
||||
nic->sqs_count = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1354,6 +1351,9 @@ void nicvf_update_stats(struct nicvf *nic)
|
|||
drv_stats->tx_frames_ok = stats->tx_ucast_frames_ok +
|
||||
stats->tx_bcast_frames_ok +
|
||||
stats->tx_mcast_frames_ok;
|
||||
drv_stats->rx_frames_ok = stats->rx_ucast_frames +
|
||||
stats->rx_bcast_frames +
|
||||
stats->rx_mcast_frames;
|
||||
drv_stats->rx_drops = stats->rx_drop_red +
|
||||
stats->rx_drop_overrun;
|
||||
drv_stats->tx_drops = stats->tx_drops;
|
||||
|
@ -1538,6 +1538,9 @@ static int nicvf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||
|
||||
nicvf_send_vf_struct(nic);
|
||||
|
||||
if (!pass1_silicon(nic->pdev))
|
||||
nic->hw_tso = true;
|
||||
|
||||
/* Check if this VF is in QS only mode */
|
||||
if (nic->sqs_mode)
|
||||
return 0;
|
||||
|
@ -1557,9 +1560,6 @@ static int nicvf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||
|
||||
netdev->vlan_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO;
|
||||
|
||||
if (!pass1_silicon(nic->pdev))
|
||||
nic->hw_tso = true;
|
||||
|
||||
netdev->netdev_ops = &nicvf_netdev_ops;
|
||||
netdev->watchdog_timeo = NICVF_TX_TIMEOUT;
|
||||
|
||||
|
|
|
@ -1329,16 +1329,12 @@ void nicvf_update_sq_stats(struct nicvf *nic, int sq_idx)
|
|||
}
|
||||
|
||||
/* Check for errors in the receive cmp.queue entry */
|
||||
int nicvf_check_cqe_rx_errs(struct nicvf *nic,
|
||||
struct cmp_queue *cq, struct cqe_rx_t *cqe_rx)
|
||||
int nicvf_check_cqe_rx_errs(struct nicvf *nic, struct cqe_rx_t *cqe_rx)
|
||||
{
|
||||
struct nicvf_hw_stats *stats = &nic->hw_stats;
|
||||
struct nicvf_drv_stats *drv_stats = &nic->drv_stats;
|
||||
|
||||
if (!cqe_rx->err_level && !cqe_rx->err_opcode) {
|
||||
drv_stats->rx_frames_ok++;
|
||||
if (!cqe_rx->err_level && !cqe_rx->err_opcode)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (netif_msg_rx_err(nic))
|
||||
netdev_err(nic->netdev,
|
||||
|
|
|
@ -338,8 +338,7 @@ u64 nicvf_queue_reg_read(struct nicvf *nic,
|
|||
/* Stats */
|
||||
void nicvf_update_rq_stats(struct nicvf *nic, int rq_idx);
|
||||
void nicvf_update_sq_stats(struct nicvf *nic, int sq_idx);
|
||||
int nicvf_check_cqe_rx_errs(struct nicvf *nic,
|
||||
struct cmp_queue *cq, struct cqe_rx_t *cqe_rx);
|
||||
int nicvf_check_cqe_rx_errs(struct nicvf *nic, struct cqe_rx_t *cqe_rx);
|
||||
int nicvf_check_cqe_tx_errs(struct nicvf *nic,
|
||||
struct cmp_queue *cq, struct cqe_send_t *cqe_tx);
|
||||
#endif /* NICVF_QUEUES_H */
|
||||
|
|
|
@ -681,6 +681,24 @@ int t3_seeprom_wp(struct adapter *adapter, int enable)
|
|||
return t3_seeprom_write(adapter, EEPROM_STAT_ADDR, enable ? 0xc : 0);
|
||||
}
|
||||
|
||||
static int vpdstrtouint(char *s, int len, unsigned int base, unsigned int *val)
|
||||
{
|
||||
char tok[len + 1];
|
||||
|
||||
memcpy(tok, s, len);
|
||||
tok[len] = 0;
|
||||
return kstrtouint(strim(tok), base, val);
|
||||
}
|
||||
|
||||
static int vpdstrtou16(char *s, int len, unsigned int base, u16 *val)
|
||||
{
|
||||
char tok[len + 1];
|
||||
|
||||
memcpy(tok, s, len);
|
||||
tok[len] = 0;
|
||||
return kstrtou16(strim(tok), base, val);
|
||||
}
|
||||
|
||||
/**
|
||||
* get_vpd_params - read VPD parameters from VPD EEPROM
|
||||
* @adapter: adapter to read
|
||||
|
@ -709,19 +727,19 @@ static int get_vpd_params(struct adapter *adapter, struct vpd_params *p)
|
|||
return ret;
|
||||
}
|
||||
|
||||
ret = kstrtouint(vpd.cclk_data, 10, &p->cclk);
|
||||
ret = vpdstrtouint(vpd.cclk_data, vpd.cclk_len, 10, &p->cclk);
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = kstrtouint(vpd.mclk_data, 10, &p->mclk);
|
||||
ret = vpdstrtouint(vpd.mclk_data, vpd.mclk_len, 10, &p->mclk);
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = kstrtouint(vpd.uclk_data, 10, &p->uclk);
|
||||
ret = vpdstrtouint(vpd.uclk_data, vpd.uclk_len, 10, &p->uclk);
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = kstrtouint(vpd.mdc_data, 10, &p->mdc);
|
||||
ret = vpdstrtouint(vpd.mdc_data, vpd.mdc_len, 10, &p->mdc);
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = kstrtouint(vpd.mt_data, 10, &p->mem_timing);
|
||||
ret = vpdstrtouint(vpd.mt_data, vpd.mt_len, 10, &p->mem_timing);
|
||||
if (ret)
|
||||
return ret;
|
||||
memcpy(p->sn, vpd.sn_data, SERNUM_LEN);
|
||||
|
@ -733,10 +751,12 @@ static int get_vpd_params(struct adapter *adapter, struct vpd_params *p)
|
|||
} else {
|
||||
p->port_type[0] = hex_to_bin(vpd.port0_data[0]);
|
||||
p->port_type[1] = hex_to_bin(vpd.port1_data[0]);
|
||||
ret = kstrtou16(vpd.xaui0cfg_data, 16, &p->xauicfg[0]);
|
||||
ret = vpdstrtou16(vpd.xaui0cfg_data, vpd.xaui0cfg_len, 16,
|
||||
&p->xauicfg[0]);
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = kstrtou16(vpd.xaui1cfg_data, 16, &p->xauicfg[1]);
|
||||
ret = vpdstrtou16(vpd.xaui1cfg_data, vpd.xaui1cfg_len, 16,
|
||||
&p->xauicfg[1]);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -165,6 +165,7 @@ CH_PCI_DEVICE_ID_TABLE_DEFINE_BEGIN
|
|||
CH_PCI_ID_TABLE_FENTRY(0x5098), /* Custom 2x40G QSFP */
|
||||
CH_PCI_ID_TABLE_FENTRY(0x5099), /* Custom 2x40G QSFP */
|
||||
CH_PCI_ID_TABLE_FENTRY(0x509a), /* Custom T520-CR */
|
||||
CH_PCI_ID_TABLE_FENTRY(0x509b), /* Custom T540-CR LOM */
|
||||
|
||||
/* T6 adapters:
|
||||
*/
|
||||
|
|
|
@ -128,7 +128,6 @@ struct board_info {
|
|||
struct resource *data_res;
|
||||
struct resource *addr_req; /* resources requested */
|
||||
struct resource *data_req;
|
||||
struct resource *irq_res;
|
||||
|
||||
int irq_wake;
|
||||
|
||||
|
@ -1300,22 +1299,16 @@ static int
|
|||
dm9000_open(struct net_device *dev)
|
||||
{
|
||||
struct board_info *db = netdev_priv(dev);
|
||||
unsigned long irqflags = db->irq_res->flags & IRQF_TRIGGER_MASK;
|
||||
|
||||
if (netif_msg_ifup(db))
|
||||
dev_dbg(db->dev, "enabling %s\n", dev->name);
|
||||
|
||||
/* If there is no IRQ type specified, default to something that
|
||||
* may work, and tell the user that this is a problem */
|
||||
|
||||
if (irqflags == IRQF_TRIGGER_NONE)
|
||||
irqflags = irq_get_trigger_type(dev->irq);
|
||||
|
||||
if (irqflags == IRQF_TRIGGER_NONE)
|
||||
/* If there is no IRQ type specified, tell the user that this is a
|
||||
* problem
|
||||
*/
|
||||
if (irq_get_trigger_type(dev->irq) == IRQF_TRIGGER_NONE)
|
||||
dev_warn(db->dev, "WARNING: no IRQ resource flags set.\n");
|
||||
|
||||
irqflags |= IRQF_SHARED;
|
||||
|
||||
/* GPIO0 on pre-activate PHY, Reg 1F is not set by reset */
|
||||
iow(db, DM9000_GPR, 0); /* REG_1F bit0 activate phyxcer */
|
||||
mdelay(1); /* delay needs by DM9000B */
|
||||
|
@ -1323,7 +1316,8 @@ dm9000_open(struct net_device *dev)
|
|||
/* Initialize DM9000 board */
|
||||
dm9000_init_dm9000(dev);
|
||||
|
||||
if (request_irq(dev->irq, dm9000_interrupt, irqflags, dev->name, dev))
|
||||
if (request_irq(dev->irq, dm9000_interrupt, IRQF_SHARED,
|
||||
dev->name, dev))
|
||||
return -EAGAIN;
|
||||
/* Now that we have an interrupt handler hooked up we can unmask
|
||||
* our interrupts
|
||||
|
@ -1500,15 +1494,22 @@ dm9000_probe(struct platform_device *pdev)
|
|||
|
||||
db->addr_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
db->data_res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
|
||||
db->irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
|
||||
|
||||
if (db->addr_res == NULL || db->data_res == NULL ||
|
||||
db->irq_res == NULL) {
|
||||
dev_err(db->dev, "insufficient resources\n");
|
||||
if (!db->addr_res || !db->data_res) {
|
||||
dev_err(db->dev, "insufficient resources addr=%p data=%p\n",
|
||||
db->addr_res, db->data_res);
|
||||
ret = -ENOENT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ndev->irq = platform_get_irq(pdev, 0);
|
||||
if (ndev->irq < 0) {
|
||||
dev_err(db->dev, "interrupt resource unavailable: %d\n",
|
||||
ndev->irq);
|
||||
ret = ndev->irq;
|
||||
goto out;
|
||||
}
|
||||
|
||||
db->irq_wake = platform_get_irq(pdev, 1);
|
||||
if (db->irq_wake >= 0) {
|
||||
dev_dbg(db->dev, "wakeup irq %d\n", db->irq_wake);
|
||||
|
@ -1570,7 +1571,6 @@ dm9000_probe(struct platform_device *pdev)
|
|||
|
||||
/* fill in parameters for net-dev structure */
|
||||
ndev->base_addr = (unsigned long)db->io_addr;
|
||||
ndev->irq = db->irq_res->start;
|
||||
|
||||
/* ensure at least we have a default set of IO routines */
|
||||
dm9000_set_io(db, iosize);
|
||||
|
|
|
@ -469,8 +469,8 @@ static int fmvj18x_config(struct pcmcia_device *link)
|
|||
goto failed;
|
||||
}
|
||||
/* Read MACID from CIS */
|
||||
for (i = 5; i < 11; i++)
|
||||
dev->dev_addr[i] = buf[i];
|
||||
for (i = 0; i < 6; i++)
|
||||
dev->dev_addr[i] = buf[i + 5];
|
||||
kfree(buf);
|
||||
} else {
|
||||
if (pcmcia_get_mac_from_cis(link, dev))
|
||||
|
|
|
@ -370,6 +370,11 @@ struct mvneta_port {
|
|||
struct net_device *dev;
|
||||
struct notifier_block cpu_notifier;
|
||||
int rxq_def;
|
||||
/* Protect the access to the percpu interrupt registers,
|
||||
* ensuring that the configuration remains coherent.
|
||||
*/
|
||||
spinlock_t lock;
|
||||
bool is_stopped;
|
||||
|
||||
/* Core clock */
|
||||
struct clk *clk;
|
||||
|
@ -1038,6 +1043,43 @@ static void mvneta_set_autoneg(struct mvneta_port *pp, int enable)
|
|||
}
|
||||
}
|
||||
|
||||
static void mvneta_percpu_unmask_interrupt(void *arg)
|
||||
{
|
||||
struct mvneta_port *pp = arg;
|
||||
|
||||
/* All the queue are unmasked, but actually only the ones
|
||||
* mapped to this CPU will be unmasked
|
||||
*/
|
||||
mvreg_write(pp, MVNETA_INTR_NEW_MASK,
|
||||
MVNETA_RX_INTR_MASK_ALL |
|
||||
MVNETA_TX_INTR_MASK_ALL |
|
||||
MVNETA_MISCINTR_INTR_MASK);
|
||||
}
|
||||
|
||||
static void mvneta_percpu_mask_interrupt(void *arg)
|
||||
{
|
||||
struct mvneta_port *pp = arg;
|
||||
|
||||
/* All the queue are masked, but actually only the ones
|
||||
* mapped to this CPU will be masked
|
||||
*/
|
||||
mvreg_write(pp, MVNETA_INTR_NEW_MASK, 0);
|
||||
mvreg_write(pp, MVNETA_INTR_OLD_MASK, 0);
|
||||
mvreg_write(pp, MVNETA_INTR_MISC_MASK, 0);
|
||||
}
|
||||
|
||||
static void mvneta_percpu_clear_intr_cause(void *arg)
|
||||
{
|
||||
struct mvneta_port *pp = arg;
|
||||
|
||||
/* All the queue are cleared, but actually only the ones
|
||||
* mapped to this CPU will be cleared
|
||||
*/
|
||||
mvreg_write(pp, MVNETA_INTR_NEW_CAUSE, 0);
|
||||
mvreg_write(pp, MVNETA_INTR_MISC_CAUSE, 0);
|
||||
mvreg_write(pp, MVNETA_INTR_OLD_CAUSE, 0);
|
||||
}
|
||||
|
||||
/* This method sets defaults to the NETA port:
|
||||
* Clears interrupt Cause and Mask registers.
|
||||
* Clears all MAC tables.
|
||||
|
@ -1055,14 +1097,10 @@ static void mvneta_defaults_set(struct mvneta_port *pp)
|
|||
int max_cpu = num_present_cpus();
|
||||
|
||||
/* Clear all Cause registers */
|
||||
mvreg_write(pp, MVNETA_INTR_NEW_CAUSE, 0);
|
||||
mvreg_write(pp, MVNETA_INTR_OLD_CAUSE, 0);
|
||||
mvreg_write(pp, MVNETA_INTR_MISC_CAUSE, 0);
|
||||
on_each_cpu(mvneta_percpu_clear_intr_cause, pp, true);
|
||||
|
||||
/* Mask all interrupts */
|
||||
mvreg_write(pp, MVNETA_INTR_NEW_MASK, 0);
|
||||
mvreg_write(pp, MVNETA_INTR_OLD_MASK, 0);
|
||||
mvreg_write(pp, MVNETA_INTR_MISC_MASK, 0);
|
||||
on_each_cpu(mvneta_percpu_mask_interrupt, pp, true);
|
||||
mvreg_write(pp, MVNETA_INTR_ENABLE, 0);
|
||||
|
||||
/* Enable MBUS Retry bit16 */
|
||||
|
@ -2528,34 +2566,9 @@ static int mvneta_setup_txqs(struct mvneta_port *pp)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void mvneta_percpu_unmask_interrupt(void *arg)
|
||||
{
|
||||
struct mvneta_port *pp = arg;
|
||||
|
||||
/* All the queue are unmasked, but actually only the ones
|
||||
* maped to this CPU will be unmasked
|
||||
*/
|
||||
mvreg_write(pp, MVNETA_INTR_NEW_MASK,
|
||||
MVNETA_RX_INTR_MASK_ALL |
|
||||
MVNETA_TX_INTR_MASK_ALL |
|
||||
MVNETA_MISCINTR_INTR_MASK);
|
||||
}
|
||||
|
||||
static void mvneta_percpu_mask_interrupt(void *arg)
|
||||
{
|
||||
struct mvneta_port *pp = arg;
|
||||
|
||||
/* All the queue are masked, but actually only the ones
|
||||
* maped to this CPU will be masked
|
||||
*/
|
||||
mvreg_write(pp, MVNETA_INTR_NEW_MASK, 0);
|
||||
mvreg_write(pp, MVNETA_INTR_OLD_MASK, 0);
|
||||
mvreg_write(pp, MVNETA_INTR_MISC_MASK, 0);
|
||||
}
|
||||
|
||||
static void mvneta_start_dev(struct mvneta_port *pp)
|
||||
{
|
||||
unsigned int cpu;
|
||||
int cpu;
|
||||
|
||||
mvneta_max_rx_size_set(pp, pp->pkt_size);
|
||||
mvneta_txq_max_tx_size_set(pp, pp->pkt_size);
|
||||
|
@ -2564,16 +2577,15 @@ static void mvneta_start_dev(struct mvneta_port *pp)
|
|||
mvneta_port_enable(pp);
|
||||
|
||||
/* Enable polling on the port */
|
||||
for_each_present_cpu(cpu) {
|
||||
for_each_online_cpu(cpu) {
|
||||
struct mvneta_pcpu_port *port = per_cpu_ptr(pp->ports, cpu);
|
||||
|
||||
napi_enable(&port->napi);
|
||||
}
|
||||
|
||||
/* Unmask interrupts. It has to be done from each CPU */
|
||||
for_each_online_cpu(cpu)
|
||||
smp_call_function_single(cpu, mvneta_percpu_unmask_interrupt,
|
||||
pp, true);
|
||||
on_each_cpu(mvneta_percpu_unmask_interrupt, pp, true);
|
||||
|
||||
mvreg_write(pp, MVNETA_INTR_MISC_MASK,
|
||||
MVNETA_CAUSE_PHY_STATUS_CHANGE |
|
||||
MVNETA_CAUSE_LINK_CHANGE |
|
||||
|
@ -2589,7 +2601,7 @@ static void mvneta_stop_dev(struct mvneta_port *pp)
|
|||
|
||||
phy_stop(pp->phy_dev);
|
||||
|
||||
for_each_present_cpu(cpu) {
|
||||
for_each_online_cpu(cpu) {
|
||||
struct mvneta_pcpu_port *port = per_cpu_ptr(pp->ports, cpu);
|
||||
|
||||
napi_disable(&port->napi);
|
||||
|
@ -2604,13 +2616,10 @@ static void mvneta_stop_dev(struct mvneta_port *pp)
|
|||
mvneta_port_disable(pp);
|
||||
|
||||
/* Clear all ethernet port interrupts */
|
||||
mvreg_write(pp, MVNETA_INTR_MISC_CAUSE, 0);
|
||||
mvreg_write(pp, MVNETA_INTR_OLD_CAUSE, 0);
|
||||
on_each_cpu(mvneta_percpu_clear_intr_cause, pp, true);
|
||||
|
||||
/* Mask all ethernet port interrupts */
|
||||
mvreg_write(pp, MVNETA_INTR_NEW_MASK, 0);
|
||||
mvreg_write(pp, MVNETA_INTR_OLD_MASK, 0);
|
||||
mvreg_write(pp, MVNETA_INTR_MISC_MASK, 0);
|
||||
on_each_cpu(mvneta_percpu_mask_interrupt, pp, true);
|
||||
|
||||
mvneta_tx_reset(pp);
|
||||
mvneta_rx_reset(pp);
|
||||
|
@ -2847,11 +2856,20 @@ static void mvneta_percpu_disable(void *arg)
|
|||
disable_percpu_irq(pp->dev->irq);
|
||||
}
|
||||
|
||||
/* Electing a CPU must be done in an atomic way: it should be done
|
||||
* after or before the removal/insertion of a CPU and this function is
|
||||
* not reentrant.
|
||||
*/
|
||||
static void mvneta_percpu_elect(struct mvneta_port *pp)
|
||||
{
|
||||
int online_cpu_idx, max_cpu, cpu, i = 0;
|
||||
int elected_cpu = 0, max_cpu, cpu, i = 0;
|
||||
|
||||
/* Use the cpu associated to the rxq when it is online, in all
|
||||
* the other cases, use the cpu 0 which can't be offline.
|
||||
*/
|
||||
if (cpu_online(pp->rxq_def))
|
||||
elected_cpu = pp->rxq_def;
|
||||
|
||||
online_cpu_idx = pp->rxq_def % num_online_cpus();
|
||||
max_cpu = num_present_cpus();
|
||||
|
||||
for_each_online_cpu(cpu) {
|
||||
|
@ -2862,7 +2880,7 @@ static void mvneta_percpu_elect(struct mvneta_port *pp)
|
|||
if ((rxq % max_cpu) == cpu)
|
||||
rxq_map |= MVNETA_CPU_RXQ_ACCESS(rxq);
|
||||
|
||||
if (i == online_cpu_idx)
|
||||
if (cpu == elected_cpu)
|
||||
/* Map the default receive queue queue to the
|
||||
* elected CPU
|
||||
*/
|
||||
|
@ -2873,7 +2891,7 @@ static void mvneta_percpu_elect(struct mvneta_port *pp)
|
|||
* the CPU bound to the default RX queue
|
||||
*/
|
||||
if (txq_number == 1)
|
||||
txq_map = (i == online_cpu_idx) ?
|
||||
txq_map = (cpu == elected_cpu) ?
|
||||
MVNETA_CPU_TXQ_ACCESS(1) : 0;
|
||||
else
|
||||
txq_map = mvreg_read(pp, MVNETA_CPU_MAP(cpu)) &
|
||||
|
@ -2902,6 +2920,14 @@ static int mvneta_percpu_notifier(struct notifier_block *nfb,
|
|||
switch (action) {
|
||||
case CPU_ONLINE:
|
||||
case CPU_ONLINE_FROZEN:
|
||||
spin_lock(&pp->lock);
|
||||
/* Configuring the driver for a new CPU while the
|
||||
* driver is stopping is racy, so just avoid it.
|
||||
*/
|
||||
if (pp->is_stopped) {
|
||||
spin_unlock(&pp->lock);
|
||||
break;
|
||||
}
|
||||
netif_tx_stop_all_queues(pp->dev);
|
||||
|
||||
/* We have to synchronise on tha napi of each CPU
|
||||
|
@ -2917,9 +2943,7 @@ static int mvneta_percpu_notifier(struct notifier_block *nfb,
|
|||
}
|
||||
|
||||
/* Mask all ethernet port interrupts */
|
||||
mvreg_write(pp, MVNETA_INTR_NEW_MASK, 0);
|
||||
mvreg_write(pp, MVNETA_INTR_OLD_MASK, 0);
|
||||
mvreg_write(pp, MVNETA_INTR_MISC_MASK, 0);
|
||||
on_each_cpu(mvneta_percpu_mask_interrupt, pp, true);
|
||||
napi_enable(&port->napi);
|
||||
|
||||
|
||||
|
@ -2934,27 +2958,25 @@ static int mvneta_percpu_notifier(struct notifier_block *nfb,
|
|||
*/
|
||||
mvneta_percpu_elect(pp);
|
||||
|
||||
/* Unmask all ethernet port interrupts, as this
|
||||
* notifier is called for each CPU then the CPU to
|
||||
* Queue mapping is applied
|
||||
*/
|
||||
mvreg_write(pp, MVNETA_INTR_NEW_MASK,
|
||||
MVNETA_RX_INTR_MASK(rxq_number) |
|
||||
MVNETA_TX_INTR_MASK(txq_number) |
|
||||
MVNETA_MISCINTR_INTR_MASK);
|
||||
/* Unmask all ethernet port interrupts */
|
||||
on_each_cpu(mvneta_percpu_unmask_interrupt, pp, true);
|
||||
mvreg_write(pp, MVNETA_INTR_MISC_MASK,
|
||||
MVNETA_CAUSE_PHY_STATUS_CHANGE |
|
||||
MVNETA_CAUSE_LINK_CHANGE |
|
||||
MVNETA_CAUSE_PSC_SYNC_CHANGE);
|
||||
netif_tx_start_all_queues(pp->dev);
|
||||
spin_unlock(&pp->lock);
|
||||
break;
|
||||
case CPU_DOWN_PREPARE:
|
||||
case CPU_DOWN_PREPARE_FROZEN:
|
||||
netif_tx_stop_all_queues(pp->dev);
|
||||
/* Thanks to this lock we are sure that any pending
|
||||
* cpu election is done
|
||||
*/
|
||||
spin_lock(&pp->lock);
|
||||
/* Mask all ethernet port interrupts */
|
||||
mvreg_write(pp, MVNETA_INTR_NEW_MASK, 0);
|
||||
mvreg_write(pp, MVNETA_INTR_OLD_MASK, 0);
|
||||
mvreg_write(pp, MVNETA_INTR_MISC_MASK, 0);
|
||||
on_each_cpu(mvneta_percpu_mask_interrupt, pp, true);
|
||||
spin_unlock(&pp->lock);
|
||||
|
||||
napi_synchronize(&port->napi);
|
||||
napi_disable(&port->napi);
|
||||
|
@ -2968,12 +2990,11 @@ static int mvneta_percpu_notifier(struct notifier_block *nfb,
|
|||
case CPU_DEAD:
|
||||
case CPU_DEAD_FROZEN:
|
||||
/* Check if a new CPU must be elected now this on is down */
|
||||
spin_lock(&pp->lock);
|
||||
mvneta_percpu_elect(pp);
|
||||
spin_unlock(&pp->lock);
|
||||
/* Unmask all ethernet port interrupts */
|
||||
mvreg_write(pp, MVNETA_INTR_NEW_MASK,
|
||||
MVNETA_RX_INTR_MASK(rxq_number) |
|
||||
MVNETA_TX_INTR_MASK(txq_number) |
|
||||
MVNETA_MISCINTR_INTR_MASK);
|
||||
on_each_cpu(mvneta_percpu_unmask_interrupt, pp, true);
|
||||
mvreg_write(pp, MVNETA_INTR_MISC_MASK,
|
||||
MVNETA_CAUSE_PHY_STATUS_CHANGE |
|
||||
MVNETA_CAUSE_LINK_CHANGE |
|
||||
|
@ -2988,7 +3009,7 @@ static int mvneta_percpu_notifier(struct notifier_block *nfb,
|
|||
static int mvneta_open(struct net_device *dev)
|
||||
{
|
||||
struct mvneta_port *pp = netdev_priv(dev);
|
||||
int ret, cpu;
|
||||
int ret;
|
||||
|
||||
pp->pkt_size = MVNETA_RX_PKT_SIZE(pp->dev->mtu);
|
||||
pp->frag_size = SKB_DATA_ALIGN(MVNETA_RX_BUF_SIZE(pp->pkt_size)) +
|
||||
|
@ -3010,22 +3031,12 @@ static int mvneta_open(struct net_device *dev)
|
|||
goto err_cleanup_txqs;
|
||||
}
|
||||
|
||||
/* Even though the documentation says that request_percpu_irq
|
||||
* doesn't enable the interrupts automatically, it actually
|
||||
* does so on the local CPU.
|
||||
*
|
||||
* Make sure it's disabled.
|
||||
*/
|
||||
mvneta_percpu_disable(pp);
|
||||
|
||||
/* Enable per-CPU interrupt on all the CPU to handle our RX
|
||||
* queue interrupts
|
||||
*/
|
||||
for_each_online_cpu(cpu)
|
||||
smp_call_function_single(cpu, mvneta_percpu_enable,
|
||||
pp, true);
|
||||
|
||||
on_each_cpu(mvneta_percpu_enable, pp, true);
|
||||
|
||||
pp->is_stopped = false;
|
||||
/* Register a CPU notifier to handle the case where our CPU
|
||||
* might be taken offline.
|
||||
*/
|
||||
|
@ -3057,13 +3068,20 @@ err_cleanup_rxqs:
|
|||
static int mvneta_stop(struct net_device *dev)
|
||||
{
|
||||
struct mvneta_port *pp = netdev_priv(dev);
|
||||
int cpu;
|
||||
|
||||
/* Inform that we are stopping so we don't want to setup the
|
||||
* driver for new CPUs in the notifiers
|
||||
*/
|
||||
spin_lock(&pp->lock);
|
||||
pp->is_stopped = true;
|
||||
mvneta_stop_dev(pp);
|
||||
mvneta_mdio_remove(pp);
|
||||
unregister_cpu_notifier(&pp->cpu_notifier);
|
||||
for_each_present_cpu(cpu)
|
||||
smp_call_function_single(cpu, mvneta_percpu_disable, pp, true);
|
||||
/* Now that the notifier are unregistered, we can release le
|
||||
* lock
|
||||
*/
|
||||
spin_unlock(&pp->lock);
|
||||
on_each_cpu(mvneta_percpu_disable, pp, true);
|
||||
free_percpu_irq(dev->irq, pp->ports);
|
||||
mvneta_cleanup_rxqs(pp);
|
||||
mvneta_cleanup_txqs(pp);
|
||||
|
@ -3312,9 +3330,7 @@ static int mvneta_config_rss(struct mvneta_port *pp)
|
|||
|
||||
netif_tx_stop_all_queues(pp->dev);
|
||||
|
||||
for_each_online_cpu(cpu)
|
||||
smp_call_function_single(cpu, mvneta_percpu_mask_interrupt,
|
||||
pp, true);
|
||||
on_each_cpu(mvneta_percpu_mask_interrupt, pp, true);
|
||||
|
||||
/* We have to synchronise on the napi of each CPU */
|
||||
for_each_online_cpu(cpu) {
|
||||
|
@ -3335,7 +3351,9 @@ static int mvneta_config_rss(struct mvneta_port *pp)
|
|||
mvreg_write(pp, MVNETA_PORT_CONFIG, val);
|
||||
|
||||
/* Update the elected CPU matching the new rxq_def */
|
||||
spin_lock(&pp->lock);
|
||||
mvneta_percpu_elect(pp);
|
||||
spin_unlock(&pp->lock);
|
||||
|
||||
/* We have to synchronise on the napi of each CPU */
|
||||
for_each_online_cpu(cpu) {
|
||||
|
|
|
@ -3061,7 +3061,7 @@ static int mvpp2_prs_mac_da_accept(struct mvpp2 *priv, int port,
|
|||
|
||||
pe = kzalloc(sizeof(*pe), GFP_KERNEL);
|
||||
if (!pe)
|
||||
return -1;
|
||||
return -ENOMEM;
|
||||
mvpp2_prs_tcam_lu_set(pe, MVPP2_PRS_LU_MAC);
|
||||
pe->index = tid;
|
||||
|
||||
|
@ -3077,7 +3077,7 @@ static int mvpp2_prs_mac_da_accept(struct mvpp2 *priv, int port,
|
|||
if (pmap == 0) {
|
||||
if (add) {
|
||||
kfree(pe);
|
||||
return -1;
|
||||
return -EINVAL;
|
||||
}
|
||||
mvpp2_prs_hw_inv(priv, pe->index);
|
||||
priv->prs_shadow[pe->index].valid = false;
|
||||
|
|
|
@ -182,10 +182,17 @@ void mlx4_enter_error_state(struct mlx4_dev_persistent *persist)
|
|||
err = mlx4_reset_slave(dev);
|
||||
else
|
||||
err = mlx4_reset_master(dev);
|
||||
BUG_ON(err != 0);
|
||||
|
||||
dev->persist->state |= MLX4_DEVICE_STATE_INTERNAL_ERROR;
|
||||
if (!err) {
|
||||
mlx4_err(dev, "device was reset successfully\n");
|
||||
} else {
|
||||
/* EEH could have disabled the PCI channel during reset. That's
|
||||
* recoverable and the PCI error flow will handle it.
|
||||
*/
|
||||
if (!pci_channel_offline(dev->persist->pdev))
|
||||
BUG_ON(1);
|
||||
}
|
||||
dev->persist->state |= MLX4_DEVICE_STATE_INTERNAL_ERROR;
|
||||
mutex_unlock(&persist->device_state_mutex);
|
||||
|
||||
/* At that step HW was already reset, now notify clients */
|
||||
|
|
|
@ -318,7 +318,9 @@ int mlx4_cq_alloc(struct mlx4_dev *dev, int nent,
|
|||
if (timestamp_en)
|
||||
cq_context->flags |= cpu_to_be32(1 << 19);
|
||||
|
||||
cq_context->logsize_usrpage = cpu_to_be32((ilog2(nent) << 24) | uar->index);
|
||||
cq_context->logsize_usrpage =
|
||||
cpu_to_be32((ilog2(nent) << 24) |
|
||||
mlx4_to_hw_uar_index(dev, uar->index));
|
||||
cq_context->comp_eqn = priv->eq_table.eq[MLX4_CQ_TO_EQ_VECTOR(vector)].eqn;
|
||||
cq_context->log_page_size = mtt->page_shift - MLX4_ICM_PAGE_SHIFT;
|
||||
|
||||
|
|
|
@ -236,6 +236,24 @@ static const struct ptp_clock_info mlx4_en_ptp_clock_info = {
|
|||
.enable = mlx4_en_phc_enable,
|
||||
};
|
||||
|
||||
#define MLX4_EN_WRAP_AROUND_SEC 10ULL
|
||||
|
||||
/* This function calculates the max shift that enables the user range
|
||||
* of MLX4_EN_WRAP_AROUND_SEC values in the cycles register.
|
||||
*/
|
||||
static u32 freq_to_shift(u16 freq)
|
||||
{
|
||||
u32 freq_khz = freq * 1000;
|
||||
u64 max_val_cycles = freq_khz * 1000 * MLX4_EN_WRAP_AROUND_SEC;
|
||||
u64 max_val_cycles_rounded = is_power_of_2(max_val_cycles + 1) ?
|
||||
max_val_cycles : roundup_pow_of_two(max_val_cycles) - 1;
|
||||
/* calculate max possible multiplier in order to fit in 64bit */
|
||||
u64 max_mul = div_u64(0xffffffffffffffffULL, max_val_cycles_rounded);
|
||||
|
||||
/* This comes from the reverse of clocksource_khz2mult */
|
||||
return ilog2(div_u64(max_mul * freq_khz, 1000000));
|
||||
}
|
||||
|
||||
void mlx4_en_init_timestamp(struct mlx4_en_dev *mdev)
|
||||
{
|
||||
struct mlx4_dev *dev = mdev->dev;
|
||||
|
@ -254,12 +272,7 @@ void mlx4_en_init_timestamp(struct mlx4_en_dev *mdev)
|
|||
memset(&mdev->cycles, 0, sizeof(mdev->cycles));
|
||||
mdev->cycles.read = mlx4_en_read_clock;
|
||||
mdev->cycles.mask = CLOCKSOURCE_MASK(48);
|
||||
/* Using shift to make calculation more accurate. Since current HW
|
||||
* clock frequency is 427 MHz, and cycles are given using a 48 bits
|
||||
* register, the biggest shift when calculating using u64, is 14
|
||||
* (max_cycles * multiplier < 2^64)
|
||||
*/
|
||||
mdev->cycles.shift = 14;
|
||||
mdev->cycles.shift = freq_to_shift(dev->caps.hca_core_clock);
|
||||
mdev->cycles.mult =
|
||||
clocksource_khz2mult(1000 * dev->caps.hca_core_clock, mdev->cycles.shift);
|
||||
mdev->nominal_c_mult = mdev->cycles.mult;
|
||||
|
|
|
@ -2344,8 +2344,6 @@ out:
|
|||
/* set offloads */
|
||||
priv->dev->hw_enc_features |= NETIF_F_IP_CSUM | NETIF_F_RXCSUM |
|
||||
NETIF_F_TSO | NETIF_F_GSO_UDP_TUNNEL;
|
||||
priv->dev->hw_features |= NETIF_F_GSO_UDP_TUNNEL;
|
||||
priv->dev->features |= NETIF_F_GSO_UDP_TUNNEL;
|
||||
}
|
||||
|
||||
static void mlx4_en_del_vxlan_offloads(struct work_struct *work)
|
||||
|
@ -2356,8 +2354,6 @@ static void mlx4_en_del_vxlan_offloads(struct work_struct *work)
|
|||
/* unset offloads */
|
||||
priv->dev->hw_enc_features &= ~(NETIF_F_IP_CSUM | NETIF_F_RXCSUM |
|
||||
NETIF_F_TSO | NETIF_F_GSO_UDP_TUNNEL);
|
||||
priv->dev->hw_features &= ~NETIF_F_GSO_UDP_TUNNEL;
|
||||
priv->dev->features &= ~NETIF_F_GSO_UDP_TUNNEL;
|
||||
|
||||
ret = mlx4_SET_PORT_VXLAN(priv->mdev->dev, priv->port,
|
||||
VXLAN_STEER_BY_OUTER_MAC, 0);
|
||||
|
@ -2980,6 +2976,11 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
|
|||
priv->rss_hash_fn = ETH_RSS_HASH_TOP;
|
||||
}
|
||||
|
||||
if (mdev->dev->caps.tunnel_offload_mode == MLX4_TUNNEL_OFFLOAD_MODE_VXLAN) {
|
||||
dev->hw_features |= NETIF_F_GSO_UDP_TUNNEL;
|
||||
dev->features |= NETIF_F_GSO_UDP_TUNNEL;
|
||||
}
|
||||
|
||||
mdev->pndev[port] = dev;
|
||||
mdev->upper[port] = NULL;
|
||||
|
||||
|
|
|
@ -238,11 +238,11 @@ int mlx4_en_DUMP_ETH_STATS(struct mlx4_en_dev *mdev, u8 port, u8 reset)
|
|||
stats->collisions = 0;
|
||||
stats->rx_dropped = be32_to_cpu(mlx4_en_stats->RDROP);
|
||||
stats->rx_length_errors = be32_to_cpu(mlx4_en_stats->RdropLength);
|
||||
stats->rx_over_errors = be32_to_cpu(mlx4_en_stats->RdropOvflw);
|
||||
stats->rx_over_errors = 0;
|
||||
stats->rx_crc_errors = be32_to_cpu(mlx4_en_stats->RCRC);
|
||||
stats->rx_frame_errors = 0;
|
||||
stats->rx_fifo_errors = be32_to_cpu(mlx4_en_stats->RdropOvflw);
|
||||
stats->rx_missed_errors = be32_to_cpu(mlx4_en_stats->RdropOvflw);
|
||||
stats->rx_missed_errors = 0;
|
||||
stats->tx_aborted_errors = 0;
|
||||
stats->tx_carrier_errors = 0;
|
||||
stats->tx_fifo_errors = 0;
|
||||
|
|
|
@ -58,7 +58,8 @@ void mlx4_en_fill_qp_context(struct mlx4_en_priv *priv, int size, int stride,
|
|||
} else {
|
||||
context->sq_size_stride = ilog2(TXBB_SIZE) - 4;
|
||||
}
|
||||
context->usr_page = cpu_to_be32(mdev->priv_uar.index);
|
||||
context->usr_page = cpu_to_be32(mlx4_to_hw_uar_index(mdev->dev,
|
||||
mdev->priv_uar.index));
|
||||
context->local_qpn = cpu_to_be32(qpn);
|
||||
context->pri_path.ackto = 1 & 0x07;
|
||||
context->pri_path.sched_queue = 0x83 | (priv->port - 1) << 6;
|
||||
|
|
|
@ -213,7 +213,9 @@ int mlx4_en_activate_tx_ring(struct mlx4_en_priv *priv,
|
|||
mlx4_en_fill_qp_context(priv, ring->size, ring->stride, 1, 0, ring->qpn,
|
||||
ring->cqn, user_prio, &ring->context);
|
||||
if (ring->bf_alloced)
|
||||
ring->context.usr_page = cpu_to_be32(ring->bf.uar->index);
|
||||
ring->context.usr_page =
|
||||
cpu_to_be32(mlx4_to_hw_uar_index(mdev->dev,
|
||||
ring->bf.uar->index));
|
||||
|
||||
err = mlx4_qp_to_ready(mdev->dev, &ring->wqres.mtt, &ring->context,
|
||||
&ring->qp, &ring->qp_state);
|
||||
|
|
|
@ -940,9 +940,10 @@ static void __iomem *mlx4_get_eq_uar(struct mlx4_dev *dev, struct mlx4_eq *eq)
|
|||
|
||||
if (!priv->eq_table.uar_map[index]) {
|
||||
priv->eq_table.uar_map[index] =
|
||||
ioremap(pci_resource_start(dev->persist->pdev, 2) +
|
||||
((eq->eqn / 4) << PAGE_SHIFT),
|
||||
PAGE_SIZE);
|
||||
ioremap(
|
||||
pci_resource_start(dev->persist->pdev, 2) +
|
||||
((eq->eqn / 4) << (dev->uar_page_shift)),
|
||||
(1 << (dev->uar_page_shift)));
|
||||
if (!priv->eq_table.uar_map[index]) {
|
||||
mlx4_err(dev, "Couldn't map EQ doorbell for EQN 0x%06x\n",
|
||||
eq->eqn);
|
||||
|
|
|
@ -168,6 +168,20 @@ struct mlx4_port_config {
|
|||
|
||||
static atomic_t pf_loading = ATOMIC_INIT(0);
|
||||
|
||||
static inline void mlx4_set_num_reserved_uars(struct mlx4_dev *dev,
|
||||
struct mlx4_dev_cap *dev_cap)
|
||||
{
|
||||
/* The reserved_uars is calculated by system page size unit.
|
||||
* Therefore, adjustment is added when the uar page size is less
|
||||
* than the system page size
|
||||
*/
|
||||
dev->caps.reserved_uars =
|
||||
max_t(int,
|
||||
mlx4_get_num_reserved_uar(dev),
|
||||
dev_cap->reserved_uars /
|
||||
(1 << (PAGE_SHIFT - dev->uar_page_shift)));
|
||||
}
|
||||
|
||||
int mlx4_check_port_params(struct mlx4_dev *dev,
|
||||
enum mlx4_port_type *port_type)
|
||||
{
|
||||
|
@ -386,8 +400,6 @@ static int mlx4_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
|
|||
dev->caps.reserved_mtts = dev_cap->reserved_mtts;
|
||||
dev->caps.reserved_mrws = dev_cap->reserved_mrws;
|
||||
|
||||
/* The first 128 UARs are used for EQ doorbells */
|
||||
dev->caps.reserved_uars = max_t(int, 128, dev_cap->reserved_uars);
|
||||
dev->caps.reserved_pds = dev_cap->reserved_pds;
|
||||
dev->caps.reserved_xrcds = (dev->caps.flags & MLX4_DEV_CAP_FLAG_XRC) ?
|
||||
dev_cap->reserved_xrcds : 0;
|
||||
|
@ -405,6 +417,15 @@ static int mlx4_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
|
|||
dev->caps.max_gso_sz = dev_cap->max_gso_sz;
|
||||
dev->caps.max_rss_tbl_sz = dev_cap->max_rss_tbl_sz;
|
||||
|
||||
/* Save uar page shift */
|
||||
if (!mlx4_is_slave(dev)) {
|
||||
/* Virtual PCI function needs to determine UAR page size from
|
||||
* firmware. Only master PCI function can set the uar page size
|
||||
*/
|
||||
dev->uar_page_shift = DEFAULT_UAR_PAGE_SHIFT;
|
||||
mlx4_set_num_reserved_uars(dev, dev_cap);
|
||||
}
|
||||
|
||||
if (dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_PHV_EN) {
|
||||
struct mlx4_init_hca_param hca_param;
|
||||
|
||||
|
@ -815,16 +836,25 @@ static int mlx4_slave_cap(struct mlx4_dev *dev)
|
|||
return -ENODEV;
|
||||
}
|
||||
|
||||
/* slave gets uar page size from QUERY_HCA fw command */
|
||||
dev->caps.uar_page_size = 1 << (hca_param.uar_page_sz + 12);
|
||||
/* Set uar_page_shift for VF */
|
||||
dev->uar_page_shift = hca_param.uar_page_sz + 12;
|
||||
|
||||
/* TODO: relax this assumption */
|
||||
if (dev->caps.uar_page_size != PAGE_SIZE) {
|
||||
mlx4_err(dev, "UAR size:%d != kernel PAGE_SIZE of %ld\n",
|
||||
dev->caps.uar_page_size, PAGE_SIZE);
|
||||
/* Make sure the master uar page size is valid */
|
||||
if (dev->uar_page_shift > PAGE_SHIFT) {
|
||||
mlx4_err(dev,
|
||||
"Invalid configuration: uar page size is larger than system page size\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/* Set reserved_uars based on the uar_page_shift */
|
||||
mlx4_set_num_reserved_uars(dev, &dev_cap);
|
||||
|
||||
/* Although uar page size in FW differs from system page size,
|
||||
* upper software layers (mlx4_ib, mlx4_en and part of mlx4_core)
|
||||
* still works with assumption that uar page size == system page size
|
||||
*/
|
||||
dev->caps.uar_page_size = PAGE_SIZE;
|
||||
|
||||
memset(&func_cap, 0, sizeof(func_cap));
|
||||
err = mlx4_QUERY_FUNC_CAP(dev, 0, &func_cap);
|
||||
if (err) {
|
||||
|
@ -2179,8 +2209,12 @@ static int mlx4_init_hca(struct mlx4_dev *dev)
|
|||
|
||||
dev->caps.max_fmr_maps = (1 << (32 - ilog2(dev->caps.num_mpts))) - 1;
|
||||
|
||||
init_hca.log_uar_sz = ilog2(dev->caps.num_uars);
|
||||
init_hca.uar_page_sz = PAGE_SHIFT - 12;
|
||||
/* Always set UAR page size 4KB, set log_uar_sz accordingly */
|
||||
init_hca.log_uar_sz = ilog2(dev->caps.num_uars) +
|
||||
PAGE_SHIFT -
|
||||
DEFAULT_UAR_PAGE_SHIFT;
|
||||
init_hca.uar_page_sz = DEFAULT_UAR_PAGE_SHIFT - 12;
|
||||
|
||||
init_hca.mw_enabled = 0;
|
||||
if (dev->caps.flags & MLX4_DEV_CAP_FLAG_MEM_WINDOW ||
|
||||
dev->caps.bmme_flags & MLX4_BMME_FLAG_TYPE_2_WIN)
|
||||
|
|
|
@ -269,9 +269,15 @@ EXPORT_SYMBOL_GPL(mlx4_bf_free);
|
|||
|
||||
int mlx4_init_uar_table(struct mlx4_dev *dev)
|
||||
{
|
||||
if (dev->caps.num_uars <= 128) {
|
||||
mlx4_err(dev, "Only %d UAR pages (need more than 128)\n",
|
||||
dev->caps.num_uars);
|
||||
int num_reserved_uar = mlx4_get_num_reserved_uar(dev);
|
||||
|
||||
mlx4_dbg(dev, "uar_page_shift = %d", dev->uar_page_shift);
|
||||
mlx4_dbg(dev, "Effective reserved_uars=%d", dev->caps.reserved_uars);
|
||||
|
||||
if (dev->caps.num_uars <= num_reserved_uar) {
|
||||
mlx4_err(
|
||||
dev, "Only %d UAR pages (need more than %d)\n",
|
||||
dev->caps.num_uars, num_reserved_uar);
|
||||
mlx4_err(dev, "Increase firmware log2_uar_bar_megabytes?\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
|
|
@ -915,11 +915,13 @@ static int handle_existing_counter(struct mlx4_dev *dev, u8 slave, int port,
|
|||
|
||||
spin_lock_irq(mlx4_tlock(dev));
|
||||
r = find_res(dev, counter_index, RES_COUNTER);
|
||||
if (!r || r->owner != slave)
|
||||
if (!r || r->owner != slave) {
|
||||
ret = -EINVAL;
|
||||
} else {
|
||||
counter = container_of(r, struct res_counter, com);
|
||||
if (!counter->port)
|
||||
counter->port = port;
|
||||
}
|
||||
|
||||
spin_unlock_irq(mlx4_tlock(dev));
|
||||
return ret;
|
||||
|
|
|
@ -2024,7 +2024,7 @@ static int mlx5e_get_vf_stats(struct net_device *dev,
|
|||
vf_stats);
|
||||
}
|
||||
|
||||
static struct net_device_ops mlx5e_netdev_ops = {
|
||||
static const struct net_device_ops mlx5e_netdev_ops_basic = {
|
||||
.ndo_open = mlx5e_open,
|
||||
.ndo_stop = mlx5e_close,
|
||||
.ndo_start_xmit = mlx5e_xmit,
|
||||
|
@ -2038,6 +2038,25 @@ static struct net_device_ops mlx5e_netdev_ops = {
|
|||
.ndo_do_ioctl = mlx5e_ioctl,
|
||||
};
|
||||
|
||||
static const struct net_device_ops mlx5e_netdev_ops_sriov = {
|
||||
.ndo_open = mlx5e_open,
|
||||
.ndo_stop = mlx5e_close,
|
||||
.ndo_start_xmit = mlx5e_xmit,
|
||||
.ndo_get_stats64 = mlx5e_get_stats,
|
||||
.ndo_set_rx_mode = mlx5e_set_rx_mode,
|
||||
.ndo_set_mac_address = mlx5e_set_mac,
|
||||
.ndo_vlan_rx_add_vid = mlx5e_vlan_rx_add_vid,
|
||||
.ndo_vlan_rx_kill_vid = mlx5e_vlan_rx_kill_vid,
|
||||
.ndo_set_features = mlx5e_set_features,
|
||||
.ndo_change_mtu = mlx5e_change_mtu,
|
||||
.ndo_do_ioctl = mlx5e_ioctl,
|
||||
.ndo_set_vf_mac = mlx5e_set_vf_mac,
|
||||
.ndo_set_vf_vlan = mlx5e_set_vf_vlan,
|
||||
.ndo_get_vf_config = mlx5e_get_vf_config,
|
||||
.ndo_set_vf_link_state = mlx5e_set_vf_link_state,
|
||||
.ndo_get_vf_stats = mlx5e_get_vf_stats,
|
||||
};
|
||||
|
||||
static int mlx5e_check_required_hca_cap(struct mlx5_core_dev *mdev)
|
||||
{
|
||||
if (MLX5_CAP_GEN(mdev, port_type) != MLX5_CAP_PORT_TYPE_ETH)
|
||||
|
@ -2137,18 +2156,11 @@ static void mlx5e_build_netdev(struct net_device *netdev)
|
|||
|
||||
SET_NETDEV_DEV(netdev, &mdev->pdev->dev);
|
||||
|
||||
if (priv->params.num_tc > 1)
|
||||
mlx5e_netdev_ops.ndo_select_queue = mlx5e_select_queue;
|
||||
if (MLX5_CAP_GEN(mdev, vport_group_manager))
|
||||
netdev->netdev_ops = &mlx5e_netdev_ops_sriov;
|
||||
else
|
||||
netdev->netdev_ops = &mlx5e_netdev_ops_basic;
|
||||
|
||||
if (MLX5_CAP_GEN(mdev, vport_group_manager)) {
|
||||
mlx5e_netdev_ops.ndo_set_vf_mac = mlx5e_set_vf_mac;
|
||||
mlx5e_netdev_ops.ndo_set_vf_vlan = mlx5e_set_vf_vlan;
|
||||
mlx5e_netdev_ops.ndo_get_vf_config = mlx5e_get_vf_config;
|
||||
mlx5e_netdev_ops.ndo_set_vf_link_state = mlx5e_set_vf_link_state;
|
||||
mlx5e_netdev_ops.ndo_get_vf_stats = mlx5e_get_vf_stats;
|
||||
}
|
||||
|
||||
netdev->netdev_ops = &mlx5e_netdev_ops;
|
||||
netdev->watchdog_timeo = 15 * HZ;
|
||||
|
||||
netdev->ethtool_ops = &mlx5e_ethtool_ops;
|
||||
|
|
|
@ -49,7 +49,7 @@
|
|||
#define MLXSW_PORT_MID 0xd000
|
||||
|
||||
#define MLXSW_PORT_MAX_PHY_PORTS 0x40
|
||||
#define MLXSW_PORT_MAX_PORTS MLXSW_PORT_MAX_PHY_PORTS
|
||||
#define MLXSW_PORT_MAX_PORTS (MLXSW_PORT_MAX_PHY_PORTS + 1)
|
||||
|
||||
#define MLXSW_PORT_DEVID_BITS_OFFSET 10
|
||||
#define MLXSW_PORT_PHY_BITS_OFFSET 4
|
||||
|
|
|
@ -873,6 +873,62 @@ static inline void mlxsw_reg_spvm_pack(char *payload, u8 local_port,
|
|||
}
|
||||
}
|
||||
|
||||
/* SPAFT - Switch Port Acceptable Frame Types
|
||||
* ------------------------------------------
|
||||
* The Switch Port Acceptable Frame Types register configures the frame
|
||||
* admittance of the port.
|
||||
*/
|
||||
#define MLXSW_REG_SPAFT_ID 0x2010
|
||||
#define MLXSW_REG_SPAFT_LEN 0x08
|
||||
|
||||
static const struct mlxsw_reg_info mlxsw_reg_spaft = {
|
||||
.id = MLXSW_REG_SPAFT_ID,
|
||||
.len = MLXSW_REG_SPAFT_LEN,
|
||||
};
|
||||
|
||||
/* reg_spaft_local_port
|
||||
* Local port number.
|
||||
* Access: Index
|
||||
*
|
||||
* Note: CPU port is not supported (all tag types are allowed).
|
||||
*/
|
||||
MLXSW_ITEM32(reg, spaft, local_port, 0x00, 16, 8);
|
||||
|
||||
/* reg_spaft_sub_port
|
||||
* Virtual port within the physical port.
|
||||
* Should be set to 0 when virtual ports are not enabled on the port.
|
||||
* Access: RW
|
||||
*/
|
||||
MLXSW_ITEM32(reg, spaft, sub_port, 0x00, 8, 8);
|
||||
|
||||
/* reg_spaft_allow_untagged
|
||||
* When set, untagged frames on the ingress are allowed (default).
|
||||
* Access: RW
|
||||
*/
|
||||
MLXSW_ITEM32(reg, spaft, allow_untagged, 0x04, 31, 1);
|
||||
|
||||
/* reg_spaft_allow_prio_tagged
|
||||
* When set, priority tagged frames on the ingress are allowed (default).
|
||||
* Access: RW
|
||||
*/
|
||||
MLXSW_ITEM32(reg, spaft, allow_prio_tagged, 0x04, 30, 1);
|
||||
|
||||
/* reg_spaft_allow_tagged
|
||||
* When set, tagged frames on the ingress are allowed (default).
|
||||
* Access: RW
|
||||
*/
|
||||
MLXSW_ITEM32(reg, spaft, allow_tagged, 0x04, 29, 1);
|
||||
|
||||
static inline void mlxsw_reg_spaft_pack(char *payload, u8 local_port,
|
||||
bool allow_untagged)
|
||||
{
|
||||
MLXSW_REG_ZERO(spaft, payload);
|
||||
mlxsw_reg_spaft_local_port_set(payload, local_port);
|
||||
mlxsw_reg_spaft_allow_untagged_set(payload, allow_untagged);
|
||||
mlxsw_reg_spaft_allow_prio_tagged_set(payload, true);
|
||||
mlxsw_reg_spaft_allow_tagged_set(payload, true);
|
||||
}
|
||||
|
||||
/* SFGC - Switch Flooding Group Configuration
|
||||
* ------------------------------------------
|
||||
* The following register controls the association of flooding tables and MIDs
|
||||
|
@ -3203,6 +3259,8 @@ static inline const char *mlxsw_reg_id_str(u16 reg_id)
|
|||
return "SPVID";
|
||||
case MLXSW_REG_SPVM_ID:
|
||||
return "SPVM";
|
||||
case MLXSW_REG_SPAFT_ID:
|
||||
return "SPAFT";
|
||||
case MLXSW_REG_SFGC_ID:
|
||||
return "SFGC";
|
||||
case MLXSW_REG_SFTR_ID:
|
||||
|
|
|
@ -2123,6 +2123,8 @@ static int mlxsw_sp_port_bridge_leave(struct mlxsw_sp_port *mlxsw_sp_port,
|
|||
if (flush_fdb && mlxsw_sp_port_fdb_flush(mlxsw_sp_port))
|
||||
netdev_err(mlxsw_sp_port->dev, "Failed to flush FDB\n");
|
||||
|
||||
mlxsw_sp_port_pvid_set(mlxsw_sp_port, 1);
|
||||
|
||||
mlxsw_sp_port->learning = 0;
|
||||
mlxsw_sp_port->learning_sync = 0;
|
||||
mlxsw_sp_port->uc_flood = 0;
|
||||
|
@ -2746,6 +2748,13 @@ static int mlxsw_sp_vport_bridge_leave(struct mlxsw_sp_port *mlxsw_sp_vport,
|
|||
goto err_vport_flood_set;
|
||||
}
|
||||
|
||||
err = mlxsw_sp_port_stp_state_set(mlxsw_sp_vport, vid,
|
||||
MLXSW_REG_SPMS_STATE_FORWARDING);
|
||||
if (err) {
|
||||
netdev_err(dev, "Failed to set STP state\n");
|
||||
goto err_port_stp_state_set;
|
||||
}
|
||||
|
||||
if (flush_fdb && mlxsw_sp_vport_fdb_flush(mlxsw_sp_vport))
|
||||
netdev_err(dev, "Failed to flush FDB\n");
|
||||
|
||||
|
@ -2763,6 +2772,7 @@ static int mlxsw_sp_vport_bridge_leave(struct mlxsw_sp_port *mlxsw_sp_vport,
|
|||
|
||||
return 0;
|
||||
|
||||
err_port_stp_state_set:
|
||||
err_vport_flood_set:
|
||||
err_port_vid_learning_set:
|
||||
err_port_vid_to_fid_validate:
|
||||
|
|
|
@ -254,5 +254,6 @@ int mlxsw_sp_port_kill_vid(struct net_device *dev,
|
|||
int mlxsw_sp_vport_flood_set(struct mlxsw_sp_port *mlxsw_sp_vport, u16 vfid,
|
||||
bool set, bool only_uc);
|
||||
void mlxsw_sp_port_active_vlans_del(struct mlxsw_sp_port *mlxsw_sp_port);
|
||||
int mlxsw_sp_port_pvid_set(struct mlxsw_sp_port *mlxsw_sp_port, u16 vid);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -370,7 +370,8 @@ static int mlxsw_sp_port_attr_set(struct net_device *dev,
|
|||
return err;
|
||||
}
|
||||
|
||||
static int mlxsw_sp_port_pvid_set(struct mlxsw_sp_port *mlxsw_sp_port, u16 vid)
|
||||
static int __mlxsw_sp_port_pvid_set(struct mlxsw_sp_port *mlxsw_sp_port,
|
||||
u16 vid)
|
||||
{
|
||||
struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
|
||||
char spvid_pl[MLXSW_REG_SPVID_LEN];
|
||||
|
@ -379,6 +380,53 @@ static int mlxsw_sp_port_pvid_set(struct mlxsw_sp_port *mlxsw_sp_port, u16 vid)
|
|||
return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(spvid), spvid_pl);
|
||||
}
|
||||
|
||||
static int mlxsw_sp_port_allow_untagged_set(struct mlxsw_sp_port *mlxsw_sp_port,
|
||||
bool allow)
|
||||
{
|
||||
struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
|
||||
char spaft_pl[MLXSW_REG_SPAFT_LEN];
|
||||
|
||||
mlxsw_reg_spaft_pack(spaft_pl, mlxsw_sp_port->local_port, allow);
|
||||
return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(spaft), spaft_pl);
|
||||
}
|
||||
|
||||
int mlxsw_sp_port_pvid_set(struct mlxsw_sp_port *mlxsw_sp_port, u16 vid)
|
||||
{
|
||||
struct net_device *dev = mlxsw_sp_port->dev;
|
||||
int err;
|
||||
|
||||
if (!vid) {
|
||||
err = mlxsw_sp_port_allow_untagged_set(mlxsw_sp_port, false);
|
||||
if (err) {
|
||||
netdev_err(dev, "Failed to disallow untagged traffic\n");
|
||||
return err;
|
||||
}
|
||||
} else {
|
||||
err = __mlxsw_sp_port_pvid_set(mlxsw_sp_port, vid);
|
||||
if (err) {
|
||||
netdev_err(dev, "Failed to set PVID\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Only allow if not already allowed. */
|
||||
if (!mlxsw_sp_port->pvid) {
|
||||
err = mlxsw_sp_port_allow_untagged_set(mlxsw_sp_port,
|
||||
true);
|
||||
if (err) {
|
||||
netdev_err(dev, "Failed to allow untagged traffic\n");
|
||||
goto err_port_allow_untagged_set;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mlxsw_sp_port->pvid = vid;
|
||||
return 0;
|
||||
|
||||
err_port_allow_untagged_set:
|
||||
__mlxsw_sp_port_pvid_set(mlxsw_sp_port, mlxsw_sp_port->pvid);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int mlxsw_sp_fid_create(struct mlxsw_sp *mlxsw_sp, u16 fid)
|
||||
{
|
||||
char sfmr_pl[MLXSW_REG_SFMR_LEN];
|
||||
|
@ -540,7 +588,12 @@ static int __mlxsw_sp_port_vlans_add(struct mlxsw_sp_port *mlxsw_sp_port,
|
|||
netdev_err(dev, "Unable to add PVID %d\n", vid_begin);
|
||||
goto err_port_pvid_set;
|
||||
}
|
||||
mlxsw_sp_port->pvid = vid_begin;
|
||||
} else if (!flag_pvid && old_pvid >= vid_begin && old_pvid <= vid_end) {
|
||||
err = mlxsw_sp_port_pvid_set(mlxsw_sp_port, 0);
|
||||
if (err) {
|
||||
netdev_err(dev, "Unable to del PVID\n");
|
||||
goto err_port_pvid_set;
|
||||
}
|
||||
}
|
||||
|
||||
/* Changing activity bits only if HW operation succeded */
|
||||
|
@ -892,20 +945,18 @@ static int __mlxsw_sp_port_vlans_del(struct mlxsw_sp_port *mlxsw_sp_port,
|
|||
return err;
|
||||
}
|
||||
|
||||
if (init)
|
||||
goto out;
|
||||
|
||||
pvid = mlxsw_sp_port->pvid;
|
||||
if (pvid >= vid_begin && pvid <= vid_end && pvid != 1) {
|
||||
/* Default VLAN is always 1 */
|
||||
err = mlxsw_sp_port_pvid_set(mlxsw_sp_port, 1);
|
||||
if (pvid >= vid_begin && pvid <= vid_end) {
|
||||
err = mlxsw_sp_port_pvid_set(mlxsw_sp_port, 0);
|
||||
if (err) {
|
||||
netdev_err(dev, "Unable to del PVID %d\n", pvid);
|
||||
return err;
|
||||
}
|
||||
mlxsw_sp_port->pvid = 1;
|
||||
}
|
||||
|
||||
if (init)
|
||||
goto out;
|
||||
|
||||
err = __mlxsw_sp_port_flood_set(mlxsw_sp_port, vid_begin, vid_end,
|
||||
false, false);
|
||||
if (err) {
|
||||
|
|
|
@ -6137,28 +6137,28 @@ static void rtl_hw_start_8168h_1(struct rtl8169_private *tp)
|
|||
sw_cnt_1ms_ini = 16000000/rg_saw_cnt;
|
||||
sw_cnt_1ms_ini &= 0x0fff;
|
||||
data = r8168_mac_ocp_read(tp, 0xd412);
|
||||
data &= 0x0fff;
|
||||
data &= ~0x0fff;
|
||||
data |= sw_cnt_1ms_ini;
|
||||
r8168_mac_ocp_write(tp, 0xd412, data);
|
||||
}
|
||||
|
||||
data = r8168_mac_ocp_read(tp, 0xe056);
|
||||
data &= 0xf0;
|
||||
data |= 0x07;
|
||||
data &= ~0xf0;
|
||||
data |= 0x70;
|
||||
r8168_mac_ocp_write(tp, 0xe056, data);
|
||||
|
||||
data = r8168_mac_ocp_read(tp, 0xe052);
|
||||
data &= 0x8008;
|
||||
data |= 0x6000;
|
||||
data &= ~0x6000;
|
||||
data |= 0x8008;
|
||||
r8168_mac_ocp_write(tp, 0xe052, data);
|
||||
|
||||
data = r8168_mac_ocp_read(tp, 0xe0d6);
|
||||
data &= 0x01ff;
|
||||
data &= ~0x01ff;
|
||||
data |= 0x017f;
|
||||
r8168_mac_ocp_write(tp, 0xe0d6, data);
|
||||
|
||||
data = r8168_mac_ocp_read(tp, 0xd420);
|
||||
data &= 0x0fff;
|
||||
data &= ~0x0fff;
|
||||
data |= 0x047f;
|
||||
r8168_mac_ocp_write(tp, 0xd420, data);
|
||||
|
||||
|
|
|
@ -1139,6 +1139,7 @@ static int ravb_set_ringparam(struct net_device *ndev,
|
|||
if (netif_running(ndev)) {
|
||||
netif_device_detach(ndev);
|
||||
/* Stop PTP Clock driver */
|
||||
if (priv->chip_id == RCAR_GEN2)
|
||||
ravb_ptp_stop(ndev);
|
||||
/* Wait for DMA stopping */
|
||||
error = ravb_stop_dma(ndev);
|
||||
|
@ -1170,6 +1171,7 @@ static int ravb_set_ringparam(struct net_device *ndev,
|
|||
ravb_emac_init(ndev);
|
||||
|
||||
/* Initialise PTP Clock driver */
|
||||
if (priv->chip_id == RCAR_GEN2)
|
||||
ravb_ptp_init(ndev, priv->pdev);
|
||||
|
||||
netif_device_attach(ndev);
|
||||
|
@ -1298,6 +1300,7 @@ static void ravb_tx_timeout_work(struct work_struct *work)
|
|||
netif_tx_stop_all_queues(ndev);
|
||||
|
||||
/* Stop PTP Clock driver */
|
||||
if (priv->chip_id == RCAR_GEN2)
|
||||
ravb_ptp_stop(ndev);
|
||||
|
||||
/* Wait for DMA stopping */
|
||||
|
@ -1311,6 +1314,7 @@ static void ravb_tx_timeout_work(struct work_struct *work)
|
|||
ravb_emac_init(ndev);
|
||||
|
||||
/* Initialise PTP Clock driver */
|
||||
if (priv->chip_id == RCAR_GEN2)
|
||||
ravb_ptp_init(ndev, priv->pdev);
|
||||
|
||||
netif_tx_start_all_queues(ndev);
|
||||
|
@ -1814,10 +1818,6 @@ static int ravb_probe(struct platform_device *pdev)
|
|||
CCC_OPC_CONFIG | CCC_GAC | CCC_CSEL_HPB, CCC);
|
||||
}
|
||||
|
||||
/* Set CSEL value */
|
||||
ravb_write(ndev, (ravb_read(ndev, CCC) & ~CCC_CSEL) | CCC_CSEL_HPB,
|
||||
CCC);
|
||||
|
||||
/* Set GTI value */
|
||||
error = ravb_set_gti(ndev);
|
||||
if (error)
|
||||
|
|
|
@ -2342,8 +2342,8 @@ static int smc_drv_probe(struct platform_device *pdev)
|
|||
}
|
||||
|
||||
ndev->irq = platform_get_irq(pdev, 0);
|
||||
if (ndev->irq <= 0) {
|
||||
ret = -ENODEV;
|
||||
if (ndev->irq < 0) {
|
||||
ret = ndev->irq;
|
||||
goto out_release_io;
|
||||
}
|
||||
/*
|
||||
|
|
|
@ -63,8 +63,12 @@ static void cpsw_gmii_sel_am3352(struct cpsw_phy_sel_priv *priv,
|
|||
mode = AM33XX_GMII_SEL_MODE_RGMII;
|
||||
break;
|
||||
|
||||
case PHY_INTERFACE_MODE_MII:
|
||||
default:
|
||||
dev_warn(priv->dev,
|
||||
"Unsupported PHY mode: \"%s\". Defaulting to MII.\n",
|
||||
phy_modes(phy_mode));
|
||||
/* fallthrough */
|
||||
case PHY_INTERFACE_MODE_MII:
|
||||
mode = AM33XX_GMII_SEL_MODE_MII;
|
||||
break;
|
||||
};
|
||||
|
@ -106,8 +110,12 @@ static void cpsw_gmii_sel_dra7xx(struct cpsw_phy_sel_priv *priv,
|
|||
mode = AM33XX_GMII_SEL_MODE_RGMII;
|
||||
break;
|
||||
|
||||
case PHY_INTERFACE_MODE_MII:
|
||||
default:
|
||||
dev_warn(priv->dev,
|
||||
"Unsupported PHY mode: \"%s\". Defaulting to MII.\n",
|
||||
phy_modes(phy_mode));
|
||||
/* fallthrough */
|
||||
case PHY_INTERFACE_MODE_MII:
|
||||
mode = AM33XX_GMII_SEL_MODE_MII;
|
||||
break;
|
||||
};
|
||||
|
|
|
@ -117,21 +117,17 @@ static void get_pkt_info(dma_addr_t *buff, u32 *buff_len, dma_addr_t *ndesc,
|
|||
*ndesc = le32_to_cpu(desc->next_desc);
|
||||
}
|
||||
|
||||
static void get_pad_info(u32 *pad0, u32 *pad1, u32 *pad2, struct knav_dma_desc *desc)
|
||||
static u32 get_sw_data(int index, struct knav_dma_desc *desc)
|
||||
{
|
||||
*pad0 = le32_to_cpu(desc->pad[0]);
|
||||
*pad1 = le32_to_cpu(desc->pad[1]);
|
||||
*pad2 = le32_to_cpu(desc->pad[2]);
|
||||
/* No Endian conversion needed as this data is untouched by hw */
|
||||
return desc->sw_data[index];
|
||||
}
|
||||
|
||||
static void get_pad_ptr(void **padptr, struct knav_dma_desc *desc)
|
||||
{
|
||||
u64 pad64;
|
||||
|
||||
pad64 = le32_to_cpu(desc->pad[0]) +
|
||||
((u64)le32_to_cpu(desc->pad[1]) << 32);
|
||||
*padptr = (void *)(uintptr_t)pad64;
|
||||
}
|
||||
/* use these macros to get sw data */
|
||||
#define GET_SW_DATA0(desc) get_sw_data(0, desc)
|
||||
#define GET_SW_DATA1(desc) get_sw_data(1, desc)
|
||||
#define GET_SW_DATA2(desc) get_sw_data(2, desc)
|
||||
#define GET_SW_DATA3(desc) get_sw_data(3, desc)
|
||||
|
||||
static void get_org_pkt_info(dma_addr_t *buff, u32 *buff_len,
|
||||
struct knav_dma_desc *desc)
|
||||
|
@ -163,13 +159,18 @@ static void set_desc_info(u32 desc_info, u32 pkt_info,
|
|||
desc->packet_info = cpu_to_le32(pkt_info);
|
||||
}
|
||||
|
||||
static void set_pad_info(u32 pad0, u32 pad1, u32 pad2, struct knav_dma_desc *desc)
|
||||
static void set_sw_data(int index, u32 data, struct knav_dma_desc *desc)
|
||||
{
|
||||
desc->pad[0] = cpu_to_le32(pad0);
|
||||
desc->pad[1] = cpu_to_le32(pad1);
|
||||
desc->pad[2] = cpu_to_le32(pad1);
|
||||
/* No Endian conversion needed as this data is untouched by hw */
|
||||
desc->sw_data[index] = data;
|
||||
}
|
||||
|
||||
/* use these macros to set sw data */
|
||||
#define SET_SW_DATA0(data, desc) set_sw_data(0, data, desc)
|
||||
#define SET_SW_DATA1(data, desc) set_sw_data(1, data, desc)
|
||||
#define SET_SW_DATA2(data, desc) set_sw_data(2, data, desc)
|
||||
#define SET_SW_DATA3(data, desc) set_sw_data(3, data, desc)
|
||||
|
||||
static void set_org_pkt_info(dma_addr_t buff, u32 buff_len,
|
||||
struct knav_dma_desc *desc)
|
||||
{
|
||||
|
@ -581,7 +582,6 @@ static void netcp_free_rx_desc_chain(struct netcp_intf *netcp,
|
|||
dma_addr_t dma_desc, dma_buf;
|
||||
unsigned int buf_len, dma_sz = sizeof(*ndesc);
|
||||
void *buf_ptr;
|
||||
u32 pad[2];
|
||||
u32 tmp;
|
||||
|
||||
get_words(&dma_desc, 1, &desc->next_desc);
|
||||
|
@ -593,14 +593,20 @@ static void netcp_free_rx_desc_chain(struct netcp_intf *netcp,
|
|||
break;
|
||||
}
|
||||
get_pkt_info(&dma_buf, &tmp, &dma_desc, ndesc);
|
||||
get_pad_ptr(&buf_ptr, ndesc);
|
||||
/* warning!!!! We are retrieving the virtual ptr in the sw_data
|
||||
* field as a 32bit value. Will not work on 64bit machines
|
||||
*/
|
||||
buf_ptr = (void *)GET_SW_DATA0(ndesc);
|
||||
buf_len = (int)GET_SW_DATA1(desc);
|
||||
dma_unmap_page(netcp->dev, dma_buf, PAGE_SIZE, DMA_FROM_DEVICE);
|
||||
__free_page(buf_ptr);
|
||||
knav_pool_desc_put(netcp->rx_pool, desc);
|
||||
}
|
||||
|
||||
get_pad_info(&pad[0], &pad[1], &buf_len, desc);
|
||||
buf_ptr = (void *)(uintptr_t)(pad[0] + ((u64)pad[1] << 32));
|
||||
/* warning!!!! We are retrieving the virtual ptr in the sw_data
|
||||
* field as a 32bit value. Will not work on 64bit machines
|
||||
*/
|
||||
buf_ptr = (void *)GET_SW_DATA0(desc);
|
||||
buf_len = (int)GET_SW_DATA1(desc);
|
||||
|
||||
if (buf_ptr)
|
||||
netcp_frag_free(buf_len <= PAGE_SIZE, buf_ptr);
|
||||
|
@ -639,7 +645,6 @@ static int netcp_process_one_rx_packet(struct netcp_intf *netcp)
|
|||
dma_addr_t dma_desc, dma_buff;
|
||||
struct netcp_packet p_info;
|
||||
struct sk_buff *skb;
|
||||
u32 pad[2];
|
||||
void *org_buf_ptr;
|
||||
|
||||
dma_desc = knav_queue_pop(netcp->rx_queue, &dma_sz);
|
||||
|
@ -653,8 +658,11 @@ static int netcp_process_one_rx_packet(struct netcp_intf *netcp)
|
|||
}
|
||||
|
||||
get_pkt_info(&dma_buff, &buf_len, &dma_desc, desc);
|
||||
get_pad_info(&pad[0], &pad[1], &org_buf_len, desc);
|
||||
org_buf_ptr = (void *)(uintptr_t)(pad[0] + ((u64)pad[1] << 32));
|
||||
/* warning!!!! We are retrieving the virtual ptr in the sw_data
|
||||
* field as a 32bit value. Will not work on 64bit machines
|
||||
*/
|
||||
org_buf_ptr = (void *)GET_SW_DATA0(desc);
|
||||
org_buf_len = (int)GET_SW_DATA1(desc);
|
||||
|
||||
if (unlikely(!org_buf_ptr)) {
|
||||
dev_err(netcp->ndev_dev, "NULL bufptr in desc\n");
|
||||
|
@ -679,7 +687,6 @@ static int netcp_process_one_rx_packet(struct netcp_intf *netcp)
|
|||
/* Fill in the page fragment list */
|
||||
while (dma_desc) {
|
||||
struct page *page;
|
||||
void *ptr;
|
||||
|
||||
ndesc = knav_pool_desc_unmap(netcp->rx_pool, dma_desc, dma_sz);
|
||||
if (unlikely(!ndesc)) {
|
||||
|
@ -688,8 +695,10 @@ static int netcp_process_one_rx_packet(struct netcp_intf *netcp)
|
|||
}
|
||||
|
||||
get_pkt_info(&dma_buff, &buf_len, &dma_desc, ndesc);
|
||||
get_pad_ptr(&ptr, ndesc);
|
||||
page = ptr;
|
||||
/* warning!!!! We are retrieving the virtual ptr in the sw_data
|
||||
* field as a 32bit value. Will not work on 64bit machines
|
||||
*/
|
||||
page = (struct page *)GET_SW_DATA0(desc);
|
||||
|
||||
if (likely(dma_buff && buf_len && page)) {
|
||||
dma_unmap_page(netcp->dev, dma_buff, PAGE_SIZE,
|
||||
|
@ -777,7 +786,10 @@ static void netcp_free_rx_buf(struct netcp_intf *netcp, int fdq)
|
|||
}
|
||||
|
||||
get_org_pkt_info(&dma, &buf_len, desc);
|
||||
get_pad_ptr(&buf_ptr, desc);
|
||||
/* warning!!!! We are retrieving the virtual ptr in the sw_data
|
||||
* field as a 32bit value. Will not work on 64bit machines
|
||||
*/
|
||||
buf_ptr = (void *)GET_SW_DATA0(desc);
|
||||
|
||||
if (unlikely(!dma)) {
|
||||
dev_err(netcp->ndev_dev, "NULL orig_buff in desc\n");
|
||||
|
@ -829,7 +841,7 @@ static int netcp_allocate_rx_buf(struct netcp_intf *netcp, int fdq)
|
|||
struct page *page;
|
||||
dma_addr_t dma;
|
||||
void *bufptr;
|
||||
u32 pad[3];
|
||||
u32 sw_data[2];
|
||||
|
||||
/* Allocate descriptor */
|
||||
hwdesc = knav_pool_desc_get(netcp->rx_pool);
|
||||
|
@ -846,7 +858,7 @@ static int netcp_allocate_rx_buf(struct netcp_intf *netcp, int fdq)
|
|||
SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
|
||||
|
||||
bufptr = netdev_alloc_frag(primary_buf_len);
|
||||
pad[2] = primary_buf_len;
|
||||
sw_data[1] = primary_buf_len;
|
||||
|
||||
if (unlikely(!bufptr)) {
|
||||
dev_warn_ratelimited(netcp->ndev_dev,
|
||||
|
@ -858,9 +870,10 @@ static int netcp_allocate_rx_buf(struct netcp_intf *netcp, int fdq)
|
|||
if (unlikely(dma_mapping_error(netcp->dev, dma)))
|
||||
goto fail;
|
||||
|
||||
pad[0] = lower_32_bits((uintptr_t)bufptr);
|
||||
pad[1] = upper_32_bits((uintptr_t)bufptr);
|
||||
|
||||
/* warning!!!! We are saving the virtual ptr in the sw_data
|
||||
* field as a 32bit value. Will not work on 64bit machines
|
||||
*/
|
||||
sw_data[0] = (u32)bufptr;
|
||||
} else {
|
||||
/* Allocate a secondary receive queue entry */
|
||||
page = alloc_page(GFP_ATOMIC | GFP_DMA | __GFP_COLD);
|
||||
|
@ -870,9 +883,11 @@ static int netcp_allocate_rx_buf(struct netcp_intf *netcp, int fdq)
|
|||
}
|
||||
buf_len = PAGE_SIZE;
|
||||
dma = dma_map_page(netcp->dev, page, 0, buf_len, DMA_TO_DEVICE);
|
||||
pad[0] = lower_32_bits(dma);
|
||||
pad[1] = upper_32_bits(dma);
|
||||
pad[2] = 0;
|
||||
/* warning!!!! We are saving the virtual ptr in the sw_data
|
||||
* field as a 32bit value. Will not work on 64bit machines
|
||||
*/
|
||||
sw_data[0] = (u32)page;
|
||||
sw_data[1] = 0;
|
||||
}
|
||||
|
||||
desc_info = KNAV_DMA_DESC_PS_INFO_IN_DESC;
|
||||
|
@ -882,7 +897,8 @@ static int netcp_allocate_rx_buf(struct netcp_intf *netcp, int fdq)
|
|||
pkt_info |= (netcp->rx_queue_id & KNAV_DMA_DESC_RETQ_MASK) <<
|
||||
KNAV_DMA_DESC_RETQ_SHIFT;
|
||||
set_org_pkt_info(dma, buf_len, hwdesc);
|
||||
set_pad_info(pad[0], pad[1], pad[2], hwdesc);
|
||||
SET_SW_DATA0(sw_data[0], hwdesc);
|
||||
SET_SW_DATA1(sw_data[1], hwdesc);
|
||||
set_desc_info(desc_info, pkt_info, hwdesc);
|
||||
|
||||
/* Push to FDQs */
|
||||
|
@ -971,7 +987,6 @@ static int netcp_process_tx_compl_packets(struct netcp_intf *netcp,
|
|||
unsigned int budget)
|
||||
{
|
||||
struct knav_dma_desc *desc;
|
||||
void *ptr;
|
||||
struct sk_buff *skb;
|
||||
unsigned int dma_sz;
|
||||
dma_addr_t dma;
|
||||
|
@ -988,8 +1003,10 @@ static int netcp_process_tx_compl_packets(struct netcp_intf *netcp,
|
|||
continue;
|
||||
}
|
||||
|
||||
get_pad_ptr(&ptr, desc);
|
||||
skb = ptr;
|
||||
/* warning!!!! We are retrieving the virtual ptr in the sw_data
|
||||
* field as a 32bit value. Will not work on 64bit machines
|
||||
*/
|
||||
skb = (struct sk_buff *)GET_SW_DATA0(desc);
|
||||
netcp_free_tx_desc_chain(netcp, desc, dma_sz);
|
||||
if (!skb) {
|
||||
dev_err(netcp->ndev_dev, "No skb in Tx desc\n");
|
||||
|
@ -1194,10 +1211,10 @@ static int netcp_tx_submit_skb(struct netcp_intf *netcp,
|
|||
}
|
||||
|
||||
set_words(&tmp, 1, &desc->packet_info);
|
||||
tmp = lower_32_bits((uintptr_t)&skb);
|
||||
set_words(&tmp, 1, &desc->pad[0]);
|
||||
tmp = upper_32_bits((uintptr_t)&skb);
|
||||
set_words(&tmp, 1, &desc->pad[1]);
|
||||
/* warning!!!! We are saving the virtual ptr in the sw_data
|
||||
* field as a 32bit value. Will not work on 64bit machines
|
||||
*/
|
||||
SET_SW_DATA0((u32)skb, desc);
|
||||
|
||||
if (tx_pipe->flags & SWITCH_TO_PORT_IN_TAGINFO) {
|
||||
tmp = tx_pipe->switch_to_port;
|
||||
|
|
|
@ -1039,17 +1039,34 @@ static netdev_tx_t geneve_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||
return geneve_xmit_skb(skb, dev, info);
|
||||
}
|
||||
|
||||
static int geneve_change_mtu(struct net_device *dev, int new_mtu)
|
||||
static int __geneve_change_mtu(struct net_device *dev, int new_mtu, bool strict)
|
||||
{
|
||||
/* GENEVE overhead is not fixed, so we can't enforce a more
|
||||
* precise max MTU.
|
||||
/* The max_mtu calculation does not take account of GENEVE
|
||||
* options, to avoid excluding potentially valid
|
||||
* configurations.
|
||||
*/
|
||||
if (new_mtu < 68 || new_mtu > IP_MAX_MTU)
|
||||
int max_mtu = IP_MAX_MTU - GENEVE_BASE_HLEN - sizeof(struct iphdr)
|
||||
- dev->hard_header_len;
|
||||
|
||||
if (new_mtu < 68)
|
||||
return -EINVAL;
|
||||
|
||||
if (new_mtu > max_mtu) {
|
||||
if (strict)
|
||||
return -EINVAL;
|
||||
|
||||
new_mtu = max_mtu;
|
||||
}
|
||||
|
||||
dev->mtu = new_mtu;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int geneve_change_mtu(struct net_device *dev, int new_mtu)
|
||||
{
|
||||
return __geneve_change_mtu(dev, new_mtu, true);
|
||||
}
|
||||
|
||||
static int geneve_fill_metadata_dst(struct net_device *dev, struct sk_buff *skb)
|
||||
{
|
||||
struct ip_tunnel_info *info = skb_tunnel_info(skb);
|
||||
|
@ -1161,6 +1178,7 @@ static void geneve_setup(struct net_device *dev)
|
|||
dev->hw_features |= NETIF_F_GSO_SOFTWARE;
|
||||
|
||||
netif_keep_dst(dev);
|
||||
dev->priv_flags &= ~IFF_TX_SKB_SHARING;
|
||||
dev->priv_flags |= IFF_LIVE_ADDR_CHANGE | IFF_NO_QUEUE;
|
||||
eth_hw_addr_random(dev);
|
||||
}
|
||||
|
@ -1452,14 +1470,15 @@ struct net_device *geneve_dev_create_fb(struct net *net, const char *name,
|
|||
return dev;
|
||||
|
||||
err = geneve_configure(net, dev, &geneve_remote_unspec,
|
||||
0, 0, 0, htons(dst_port), true, 0);
|
||||
0, 0, 0, htons(dst_port), true,
|
||||
GENEVE_F_UDP_ZERO_CSUM6_RX);
|
||||
if (err)
|
||||
goto err;
|
||||
|
||||
/* openvswitch users expect packet sizes to be unrestricted,
|
||||
* so set the largest MTU we can.
|
||||
*/
|
||||
err = geneve_change_mtu(dev, IP_MAX_MTU);
|
||||
err = __geneve_change_mtu(dev, IP_MAX_MTU, false);
|
||||
if (err)
|
||||
goto err;
|
||||
|
||||
|
|
|
@ -1089,6 +1089,9 @@ static int netvsc_probe(struct hv_device *dev,
|
|||
net->ethtool_ops = ðtool_ops;
|
||||
SET_NETDEV_DEV(net, &dev->device);
|
||||
|
||||
/* We always need headroom for rndis header */
|
||||
net->needed_headroom = RNDIS_AND_PPI_SIZE;
|
||||
|
||||
/* Notify the netvsc driver of the new device */
|
||||
memset(&device_info, 0, sizeof(device_info));
|
||||
device_info.ring_size = ring_size;
|
||||
|
|
|
@ -250,10 +250,6 @@ static int bcm7xxx_config_init(struct phy_device *phydev)
|
|||
phy_write(phydev, MII_BCM7XXX_AUX_MODE, MII_BCM7XX_64CLK_MDIO);
|
||||
phy_read(phydev, MII_BCM7XXX_AUX_MODE);
|
||||
|
||||
/* Workaround only required for 100Mbits/sec capable PHYs */
|
||||
if (phydev->supported & PHY_GBIT_FEATURES)
|
||||
return 0;
|
||||
|
||||
/* set shadow mode 2 */
|
||||
ret = phy_set_clr_bits(phydev, MII_BCM7XXX_TEST,
|
||||
MII_BCM7XXX_SHD_MODE_2, MII_BCM7XXX_SHD_MODE_2);
|
||||
|
@ -270,7 +266,7 @@ static int bcm7xxx_config_init(struct phy_device *phydev)
|
|||
phy_write(phydev, MII_BCM7XXX_100TX_FALSE_CAR, 0x7555);
|
||||
|
||||
/* reset shadow mode 2 */
|
||||
ret = phy_set_clr_bits(phydev, MII_BCM7XXX_TEST, MII_BCM7XXX_SHD_MODE_2, 0);
|
||||
ret = phy_set_clr_bits(phydev, MII_BCM7XXX_TEST, 0, MII_BCM7XXX_SHD_MODE_2);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
|
@ -307,11 +303,6 @@ static int bcm7xxx_suspend(struct phy_device *phydev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int bcm7xxx_dummy_config_init(struct phy_device *phydev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define BCM7XXX_28NM_GPHY(_oui, _name) \
|
||||
{ \
|
||||
.phy_id = (_oui), \
|
||||
|
@ -337,7 +328,7 @@ static struct phy_driver bcm7xxx_driver[] = {
|
|||
.phy_id = PHY_ID_BCM7425,
|
||||
.phy_id_mask = 0xfffffff0,
|
||||
.name = "Broadcom BCM7425",
|
||||
.features = PHY_GBIT_FEATURES |
|
||||
.features = PHY_BASIC_FEATURES |
|
||||
SUPPORTED_Pause | SUPPORTED_Asym_Pause,
|
||||
.flags = PHY_IS_INTERNAL,
|
||||
.config_init = bcm7xxx_config_init,
|
||||
|
@ -349,7 +340,7 @@ static struct phy_driver bcm7xxx_driver[] = {
|
|||
.phy_id = PHY_ID_BCM7429,
|
||||
.phy_id_mask = 0xfffffff0,
|
||||
.name = "Broadcom BCM7429",
|
||||
.features = PHY_GBIT_FEATURES |
|
||||
.features = PHY_BASIC_FEATURES |
|
||||
SUPPORTED_Pause | SUPPORTED_Asym_Pause,
|
||||
.flags = PHY_IS_INTERNAL,
|
||||
.config_init = bcm7xxx_config_init,
|
||||
|
@ -361,34 +352,10 @@ static struct phy_driver bcm7xxx_driver[] = {
|
|||
.phy_id = PHY_ID_BCM7435,
|
||||
.phy_id_mask = 0xfffffff0,
|
||||
.name = "Broadcom BCM7435",
|
||||
.features = PHY_GBIT_FEATURES |
|
||||
SUPPORTED_Pause | SUPPORTED_Asym_Pause,
|
||||
.flags = PHY_IS_INTERNAL,
|
||||
.config_init = bcm7xxx_config_init,
|
||||
.config_aneg = genphy_config_aneg,
|
||||
.read_status = genphy_read_status,
|
||||
.suspend = bcm7xxx_suspend,
|
||||
.resume = bcm7xxx_config_init,
|
||||
}, {
|
||||
.phy_id = PHY_BCM_OUI_4,
|
||||
.phy_id_mask = 0xffff0000,
|
||||
.name = "Broadcom BCM7XXX 40nm",
|
||||
.features = PHY_GBIT_FEATURES |
|
||||
SUPPORTED_Pause | SUPPORTED_Asym_Pause,
|
||||
.flags = PHY_IS_INTERNAL,
|
||||
.config_init = bcm7xxx_config_init,
|
||||
.config_aneg = genphy_config_aneg,
|
||||
.read_status = genphy_read_status,
|
||||
.suspend = bcm7xxx_suspend,
|
||||
.resume = bcm7xxx_config_init,
|
||||
}, {
|
||||
.phy_id = PHY_BCM_OUI_5,
|
||||
.phy_id_mask = 0xffffff00,
|
||||
.name = "Broadcom BCM7XXX 65nm",
|
||||
.features = PHY_BASIC_FEATURES |
|
||||
SUPPORTED_Pause | SUPPORTED_Asym_Pause,
|
||||
.flags = PHY_IS_INTERNAL,
|
||||
.config_init = bcm7xxx_dummy_config_init,
|
||||
.config_init = bcm7xxx_config_init,
|
||||
.config_aneg = genphy_config_aneg,
|
||||
.read_status = genphy_read_status,
|
||||
.suspend = bcm7xxx_suspend,
|
||||
|
@ -404,8 +371,6 @@ static struct mdio_device_id __maybe_unused bcm7xxx_tbl[] = {
|
|||
{ PHY_ID_BCM7439, 0xfffffff0, },
|
||||
{ PHY_ID_BCM7435, 0xfffffff0, },
|
||||
{ PHY_ID_BCM7445, 0xfffffff0, },
|
||||
{ PHY_BCM_OUI_4, 0xffff0000 },
|
||||
{ PHY_BCM_OUI_5, 0xffffff00 },
|
||||
{ }
|
||||
};
|
||||
|
||||
|
|
|
@ -446,6 +446,12 @@ static int m88e1510_config_aneg(struct phy_device *phydev)
|
|||
if (err < 0)
|
||||
return err;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int marvell_config_init(struct phy_device *phydev)
|
||||
{
|
||||
/* Set registers from marvell,reg-init DT property */
|
||||
return marvell_of_reg_init(phydev);
|
||||
}
|
||||
|
||||
|
@ -495,7 +501,7 @@ static int m88e1116r_config_init(struct phy_device *phydev)
|
|||
|
||||
mdelay(500);
|
||||
|
||||
return 0;
|
||||
return marvell_config_init(phydev);
|
||||
}
|
||||
|
||||
static int m88e3016_config_init(struct phy_device *phydev)
|
||||
|
@ -514,7 +520,7 @@ static int m88e3016_config_init(struct phy_device *phydev)
|
|||
if (reg < 0)
|
||||
return reg;
|
||||
|
||||
return 0;
|
||||
return marvell_config_init(phydev);
|
||||
}
|
||||
|
||||
static int m88e1111_config_init(struct phy_device *phydev)
|
||||
|
@ -1078,6 +1084,7 @@ static struct phy_driver marvell_drivers[] = {
|
|||
.features = PHY_GBIT_FEATURES,
|
||||
.probe = marvell_probe,
|
||||
.flags = PHY_HAS_INTERRUPT,
|
||||
.config_init = &marvell_config_init,
|
||||
.config_aneg = &marvell_config_aneg,
|
||||
.read_status = &genphy_read_status,
|
||||
.ack_interrupt = &marvell_ack_interrupt,
|
||||
|
@ -1149,6 +1156,7 @@ static struct phy_driver marvell_drivers[] = {
|
|||
.features = PHY_GBIT_FEATURES,
|
||||
.flags = PHY_HAS_INTERRUPT,
|
||||
.probe = marvell_probe,
|
||||
.config_init = &marvell_config_init,
|
||||
.config_aneg = &m88e1121_config_aneg,
|
||||
.read_status = &marvell_read_status,
|
||||
.ack_interrupt = &marvell_ack_interrupt,
|
||||
|
@ -1167,6 +1175,7 @@ static struct phy_driver marvell_drivers[] = {
|
|||
.features = PHY_GBIT_FEATURES,
|
||||
.flags = PHY_HAS_INTERRUPT,
|
||||
.probe = marvell_probe,
|
||||
.config_init = &marvell_config_init,
|
||||
.config_aneg = &m88e1318_config_aneg,
|
||||
.read_status = &marvell_read_status,
|
||||
.ack_interrupt = &marvell_ack_interrupt,
|
||||
|
@ -1259,6 +1268,7 @@ static struct phy_driver marvell_drivers[] = {
|
|||
.features = PHY_GBIT_FEATURES,
|
||||
.flags = PHY_HAS_INTERRUPT,
|
||||
.probe = marvell_probe,
|
||||
.config_init = &marvell_config_init,
|
||||
.config_aneg = &m88e1510_config_aneg,
|
||||
.read_status = &marvell_read_status,
|
||||
.ack_interrupt = &marvell_ack_interrupt,
|
||||
|
@ -1277,6 +1287,7 @@ static struct phy_driver marvell_drivers[] = {
|
|||
.features = PHY_GBIT_FEATURES,
|
||||
.flags = PHY_HAS_INTERRUPT,
|
||||
.probe = marvell_probe,
|
||||
.config_init = &marvell_config_init,
|
||||
.config_aneg = &m88e1510_config_aneg,
|
||||
.read_status = &marvell_read_status,
|
||||
.ack_interrupt = &marvell_ack_interrupt,
|
||||
|
|
|
@ -1410,7 +1410,7 @@ int genphy_config_init(struct phy_device *phydev)
|
|||
|
||||
features = (SUPPORTED_TP | SUPPORTED_MII
|
||||
| SUPPORTED_AUI | SUPPORTED_FIBRE |
|
||||
SUPPORTED_BNC);
|
||||
SUPPORTED_BNC | SUPPORTED_Pause | SUPPORTED_Asym_Pause);
|
||||
|
||||
/* Do we support autonegotiation? */
|
||||
val = phy_read(phydev, MII_BMSR);
|
||||
|
|
|
@ -395,6 +395,8 @@ static int pppoe_rcv_core(struct sock *sk, struct sk_buff *skb)
|
|||
|
||||
if (!__pppoe_xmit(sk_pppox(relay_po), skb))
|
||||
goto abort_put;
|
||||
|
||||
sock_put(sk_pppox(relay_po));
|
||||
} else {
|
||||
if (sock_queue_rcv_skb(sk, skb))
|
||||
goto abort_kfree;
|
||||
|
|
|
@ -395,6 +395,10 @@ config USB_NET_RNDIS_HOST
|
|||
The protocol specification is incomplete, and is controlled by
|
||||
(and for) Microsoft; it isn't an "Open" ecosystem or market.
|
||||
|
||||
config USB_NET_CDC_SUBSET_ENABLE
|
||||
tristate
|
||||
depends on USB_NET_CDC_SUBSET
|
||||
|
||||
config USB_NET_CDC_SUBSET
|
||||
tristate "Simple USB Network Links (CDC Ethernet subset)"
|
||||
depends on USB_USBNET
|
||||
|
@ -413,6 +417,7 @@ config USB_NET_CDC_SUBSET
|
|||
config USB_ALI_M5632
|
||||
bool "ALi M5632 based 'USB 2.0 Data Link' cables"
|
||||
depends on USB_NET_CDC_SUBSET
|
||||
select USB_NET_CDC_SUBSET_ENABLE
|
||||
help
|
||||
Choose this option if you're using a host-to-host cable
|
||||
based on this design, which supports USB 2.0 high speed.
|
||||
|
@ -420,6 +425,7 @@ config USB_ALI_M5632
|
|||
config USB_AN2720
|
||||
bool "AnchorChips 2720 based cables (Xircom PGUNET, ...)"
|
||||
depends on USB_NET_CDC_SUBSET
|
||||
select USB_NET_CDC_SUBSET_ENABLE
|
||||
help
|
||||
Choose this option if you're using a host-to-host cable
|
||||
based on this design. Note that AnchorChips is now a
|
||||
|
@ -428,6 +434,7 @@ config USB_AN2720
|
|||
config USB_BELKIN
|
||||
bool "eTEK based host-to-host cables (Advance, Belkin, ...)"
|
||||
depends on USB_NET_CDC_SUBSET
|
||||
select USB_NET_CDC_SUBSET_ENABLE
|
||||
default y
|
||||
help
|
||||
Choose this option if you're using a host-to-host cable
|
||||
|
@ -437,6 +444,7 @@ config USB_BELKIN
|
|||
config USB_ARMLINUX
|
||||
bool "Embedded ARM Linux links (iPaq, ...)"
|
||||
depends on USB_NET_CDC_SUBSET
|
||||
select USB_NET_CDC_SUBSET_ENABLE
|
||||
default y
|
||||
help
|
||||
Choose this option to support the "usb-eth" networking driver
|
||||
|
@ -454,6 +462,7 @@ config USB_ARMLINUX
|
|||
config USB_EPSON2888
|
||||
bool "Epson 2888 based firmware (DEVELOPMENT)"
|
||||
depends on USB_NET_CDC_SUBSET
|
||||
select USB_NET_CDC_SUBSET_ENABLE
|
||||
help
|
||||
Choose this option to support the usb networking links used
|
||||
by some sample firmware from Epson.
|
||||
|
@ -461,6 +470,7 @@ config USB_EPSON2888
|
|||
config USB_KC2190
|
||||
bool "KT Technology KC2190 based cables (InstaNet)"
|
||||
depends on USB_NET_CDC_SUBSET
|
||||
select USB_NET_CDC_SUBSET_ENABLE
|
||||
help
|
||||
Choose this option if you're using a host-to-host cable
|
||||
with one of these chips.
|
||||
|
|
|
@ -23,7 +23,7 @@ obj-$(CONFIG_USB_NET_GL620A) += gl620a.o
|
|||
obj-$(CONFIG_USB_NET_NET1080) += net1080.o
|
||||
obj-$(CONFIG_USB_NET_PLUSB) += plusb.o
|
||||
obj-$(CONFIG_USB_NET_RNDIS_HOST) += rndis_host.o
|
||||
obj-$(CONFIG_USB_NET_CDC_SUBSET) += cdc_subset.o
|
||||
obj-$(CONFIG_USB_NET_CDC_SUBSET_ENABLE) += cdc_subset.o
|
||||
obj-$(CONFIG_USB_NET_ZAURUS) += zaurus.o
|
||||
obj-$(CONFIG_USB_NET_MCS7830) += mcs7830.o
|
||||
obj-$(CONFIG_USB_USBNET) += usbnet.o
|
||||
|
|
|
@ -637,6 +637,7 @@ static const struct usb_device_id products[] = {
|
|||
|
||||
/* 3. Combined interface devices matching on interface number */
|
||||
{QMI_FIXED_INTF(0x0408, 0xea42, 4)}, /* Yota / Megafon M100-1 */
|
||||
{QMI_FIXED_INTF(0x05c6, 0x6001, 3)}, /* 4G LTE usb-modem U901 */
|
||||
{QMI_FIXED_INTF(0x05c6, 0x7000, 0)},
|
||||
{QMI_FIXED_INTF(0x05c6, 0x7001, 1)},
|
||||
{QMI_FIXED_INTF(0x05c6, 0x7002, 1)},
|
||||
|
|
|
@ -377,7 +377,7 @@ union Vmxnet3_GenericDesc {
|
|||
#define VMXNET3_TX_RING_MAX_SIZE 4096
|
||||
#define VMXNET3_TC_RING_MAX_SIZE 4096
|
||||
#define VMXNET3_RX_RING_MAX_SIZE 4096
|
||||
#define VMXNET3_RX_RING2_MAX_SIZE 2048
|
||||
#define VMXNET3_RX_RING2_MAX_SIZE 4096
|
||||
#define VMXNET3_RC_RING_MAX_SIZE 8192
|
||||
|
||||
/* a list of reasons for queue stop */
|
||||
|
|
|
@ -69,10 +69,10 @@
|
|||
/*
|
||||
* Version numbers
|
||||
*/
|
||||
#define VMXNET3_DRIVER_VERSION_STRING "1.4.5.0-k"
|
||||
#define VMXNET3_DRIVER_VERSION_STRING "1.4.6.0-k"
|
||||
|
||||
/* a 32-bit int, each byte encode a verion number in VMXNET3_DRIVER_VERSION */
|
||||
#define VMXNET3_DRIVER_VERSION_NUM 0x01040500
|
||||
#define VMXNET3_DRIVER_VERSION_NUM 0x01040600
|
||||
|
||||
#if defined(CONFIG_PCI_MSI)
|
||||
/* RSS only makes sense if MSI-X is supported. */
|
||||
|
|
|
@ -2171,9 +2171,11 @@ static netdev_tx_t vxlan_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||
#endif
|
||||
}
|
||||
|
||||
if (vxlan->flags & VXLAN_F_COLLECT_METADATA &&
|
||||
info && info->mode & IP_TUNNEL_INFO_TX) {
|
||||
if (vxlan->flags & VXLAN_F_COLLECT_METADATA) {
|
||||
if (info && info->mode & IP_TUNNEL_INFO_TX)
|
||||
vxlan_xmit_one(skb, dev, NULL, false);
|
||||
else
|
||||
kfree_skb(skb);
|
||||
return NETDEV_TX_OK;
|
||||
}
|
||||
|
||||
|
@ -2537,6 +2539,7 @@ static void vxlan_setup(struct net_device *dev)
|
|||
dev->hw_features |= NETIF_F_GSO_SOFTWARE;
|
||||
dev->hw_features |= NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_STAG_TX;
|
||||
netif_keep_dst(dev);
|
||||
dev->priv_flags &= ~IFF_TX_SKB_SHARING;
|
||||
dev->priv_flags |= IFF_LIVE_ADDR_CHANGE | IFF_NO_QUEUE;
|
||||
|
||||
INIT_LIST_HEAD(&vxlan->next);
|
||||
|
|
|
@ -1626,7 +1626,7 @@ try:
|
|||
if (state & Xpr) {
|
||||
void __iomem *scc_addr;
|
||||
unsigned long ring;
|
||||
int i;
|
||||
unsigned int i;
|
||||
|
||||
/*
|
||||
* - the busy condition happens (sometimes);
|
||||
|
|
|
@ -53,7 +53,6 @@ config IWLWIFI_LEDS
|
|||
|
||||
config IWLDVM
|
||||
tristate "Intel Wireless WiFi DVM Firmware support"
|
||||
depends on m
|
||||
help
|
||||
This is the driver that supports the DVM firmware. The list
|
||||
of the devices that use this firmware is available here:
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
*
|
||||
* Copyright(c) 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2014 - 2015 Intel Mobile Communications GmbH
|
||||
* Copyright(c) 2016 Intel Deutschland GmbH
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
|
@ -70,12 +71,15 @@
|
|||
|
||||
/* Highest firmware API version supported */
|
||||
#define IWL8000_UCODE_API_MAX 20
|
||||
#define IWL8265_UCODE_API_MAX 20
|
||||
|
||||
/* Oldest version we won't warn about */
|
||||
#define IWL8000_UCODE_API_OK 13
|
||||
#define IWL8265_UCODE_API_OK 20
|
||||
|
||||
/* Lowest firmware API version supported */
|
||||
#define IWL8000_UCODE_API_MIN 13
|
||||
#define IWL8265_UCODE_API_MIN 20
|
||||
|
||||
/* NVM versions */
|
||||
#define IWL8000_NVM_VERSION 0x0a1d
|
||||
|
@ -93,6 +97,10 @@
|
|||
#define IWL8000_MODULE_FIRMWARE(api) \
|
||||
IWL8000_FW_PRE "-" __stringify(api) ".ucode"
|
||||
|
||||
#define IWL8265_FW_PRE "iwlwifi-8265-"
|
||||
#define IWL8265_MODULE_FIRMWARE(api) \
|
||||
IWL8265_FW_PRE __stringify(api) ".ucode"
|
||||
|
||||
#define NVM_HW_SECTION_NUM_FAMILY_8000 10
|
||||
#define DEFAULT_NVM_FILE_FAMILY_8000B "nvmData-8000B"
|
||||
#define DEFAULT_NVM_FILE_FAMILY_8000C "nvmData-8000C"
|
||||
|
@ -144,10 +152,7 @@ static const struct iwl_tt_params iwl8000_tt_params = {
|
|||
.support_tx_backoff = true,
|
||||
};
|
||||
|
||||
#define IWL_DEVICE_8000 \
|
||||
.ucode_api_max = IWL8000_UCODE_API_MAX, \
|
||||
.ucode_api_ok = IWL8000_UCODE_API_OK, \
|
||||
.ucode_api_min = IWL8000_UCODE_API_MIN, \
|
||||
#define IWL_DEVICE_8000_COMMON \
|
||||
.device_family = IWL_DEVICE_FAMILY_8000, \
|
||||
.max_inst_size = IWL60_RTC_INST_SIZE, \
|
||||
.max_data_size = IWL60_RTC_DATA_SIZE, \
|
||||
|
@ -167,10 +172,28 @@ static const struct iwl_tt_params iwl8000_tt_params = {
|
|||
.thermal_params = &iwl8000_tt_params, \
|
||||
.apmg_not_supported = true
|
||||
|
||||
#define IWL_DEVICE_8000 \
|
||||
IWL_DEVICE_8000_COMMON, \
|
||||
.ucode_api_max = IWL8000_UCODE_API_MAX, \
|
||||
.ucode_api_ok = IWL8000_UCODE_API_OK, \
|
||||
.ucode_api_min = IWL8000_UCODE_API_MIN \
|
||||
|
||||
#define IWL_DEVICE_8260 \
|
||||
IWL_DEVICE_8000_COMMON, \
|
||||
.ucode_api_max = IWL8000_UCODE_API_MAX, \
|
||||
.ucode_api_ok = IWL8000_UCODE_API_OK, \
|
||||
.ucode_api_min = IWL8000_UCODE_API_MIN \
|
||||
|
||||
#define IWL_DEVICE_8265 \
|
||||
IWL_DEVICE_8000_COMMON, \
|
||||
.ucode_api_max = IWL8265_UCODE_API_MAX, \
|
||||
.ucode_api_ok = IWL8265_UCODE_API_OK, \
|
||||
.ucode_api_min = IWL8265_UCODE_API_MIN \
|
||||
|
||||
const struct iwl_cfg iwl8260_2n_cfg = {
|
||||
.name = "Intel(R) Dual Band Wireless N 8260",
|
||||
.fw_name_pre = IWL8000_FW_PRE,
|
||||
IWL_DEVICE_8000,
|
||||
IWL_DEVICE_8260,
|
||||
.ht_params = &iwl8000_ht_params,
|
||||
.nvm_ver = IWL8000_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL8000_TX_POWER_VERSION,
|
||||
|
@ -179,7 +202,7 @@ const struct iwl_cfg iwl8260_2n_cfg = {
|
|||
const struct iwl_cfg iwl8260_2ac_cfg = {
|
||||
.name = "Intel(R) Dual Band Wireless AC 8260",
|
||||
.fw_name_pre = IWL8000_FW_PRE,
|
||||
IWL_DEVICE_8000,
|
||||
IWL_DEVICE_8260,
|
||||
.ht_params = &iwl8000_ht_params,
|
||||
.nvm_ver = IWL8000_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL8000_TX_POWER_VERSION,
|
||||
|
@ -188,8 +211,8 @@ const struct iwl_cfg iwl8260_2ac_cfg = {
|
|||
|
||||
const struct iwl_cfg iwl8265_2ac_cfg = {
|
||||
.name = "Intel(R) Dual Band Wireless AC 8265",
|
||||
.fw_name_pre = IWL8000_FW_PRE,
|
||||
IWL_DEVICE_8000,
|
||||
.fw_name_pre = IWL8265_FW_PRE,
|
||||
IWL_DEVICE_8265,
|
||||
.ht_params = &iwl8000_ht_params,
|
||||
.nvm_ver = IWL8000_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL8000_TX_POWER_VERSION,
|
||||
|
@ -209,7 +232,7 @@ const struct iwl_cfg iwl4165_2ac_cfg = {
|
|||
const struct iwl_cfg iwl8260_2ac_sdio_cfg = {
|
||||
.name = "Intel(R) Dual Band Wireless-AC 8260",
|
||||
.fw_name_pre = IWL8000_FW_PRE,
|
||||
IWL_DEVICE_8000,
|
||||
IWL_DEVICE_8260,
|
||||
.ht_params = &iwl8000_ht_params,
|
||||
.nvm_ver = IWL8000_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL8000_TX_POWER_VERSION,
|
||||
|
@ -236,3 +259,4 @@ const struct iwl_cfg iwl4165_2ac_sdio_cfg = {
|
|||
};
|
||||
|
||||
MODULE_FIRMWARE(IWL8000_MODULE_FIRMWARE(IWL8000_UCODE_API_OK));
|
||||
MODULE_FIRMWARE(IWL8265_MODULE_FIRMWARE(IWL8265_UCODE_API_OK));
|
||||
|
|
|
@ -243,8 +243,10 @@ static int iwl_request_firmware(struct iwl_drv *drv, bool first)
|
|||
if (drv->trans->cfg->device_family == IWL_DEVICE_FAMILY_8000) {
|
||||
char rev_step = 'A' + CSR_HW_REV_STEP(drv->trans->hw_rev);
|
||||
|
||||
snprintf(drv->firmware_name, sizeof(drv->firmware_name),
|
||||
"%s%c-%s.ucode", name_pre, rev_step, tag);
|
||||
if (rev_step != 'A')
|
||||
snprintf(drv->firmware_name,
|
||||
sizeof(drv->firmware_name), "%s%c-%s.ucode",
|
||||
name_pre, rev_step, tag);
|
||||
}
|
||||
|
||||
IWL_DEBUG_INFO(drv, "attempting to load firmware %s'%s'\n",
|
||||
|
|
|
@ -1298,6 +1298,10 @@ int iwl_mvm_sched_scan_start(struct iwl_mvm *mvm,
|
|||
return -EBUSY;
|
||||
}
|
||||
|
||||
/* we don't support "match all" in the firmware */
|
||||
if (!req->n_match_sets)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
ret = iwl_mvm_check_running_scans(mvm, type);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
|
|
@ -490,6 +490,15 @@ static inline void iwl_enable_interrupts(struct iwl_trans *trans)
|
|||
iwl_write32(trans, CSR_INT_MASK, trans_pcie->inta_mask);
|
||||
}
|
||||
|
||||
static inline void iwl_enable_fw_load_int(struct iwl_trans *trans)
|
||||
{
|
||||
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
|
||||
|
||||
IWL_DEBUG_ISR(trans, "Enabling FW load interrupt\n");
|
||||
trans_pcie->inta_mask = CSR_INT_BIT_FH_TX;
|
||||
iwl_write32(trans, CSR_INT_MASK, trans_pcie->inta_mask);
|
||||
}
|
||||
|
||||
static inline void iwl_enable_rfkill_int(struct iwl_trans *trans)
|
||||
{
|
||||
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
|
||||
|
|
|
@ -1438,9 +1438,11 @@ irqreturn_t iwl_pcie_irq_handler(int irq, void *dev_id)
|
|||
inta & ~trans_pcie->inta_mask);
|
||||
}
|
||||
|
||||
/* Re-enable all interrupts */
|
||||
/* only Re-enable if disabled by irq */
|
||||
if (test_bit(STATUS_INT_ENABLED, &trans->status))
|
||||
/* we are loading the firmware, enable FH_TX interrupt only */
|
||||
if (handled & CSR_INT_BIT_FH_TX)
|
||||
iwl_enable_fw_load_int(trans);
|
||||
/* only Re-enable all interrupt if disabled by irq */
|
||||
else if (test_bit(STATUS_INT_ENABLED, &trans->status))
|
||||
iwl_enable_interrupts(trans);
|
||||
/* Re-enable RF_KILL if it occurred */
|
||||
else if (handled & CSR_INT_BIT_RF_KILL)
|
||||
|
|
|
@ -1021,82 +1021,6 @@ static int iwl_pcie_load_given_ucode_8000(struct iwl_trans *trans,
|
|||
&first_ucode_section);
|
||||
}
|
||||
|
||||
static int iwl_trans_pcie_start_fw(struct iwl_trans *trans,
|
||||
const struct fw_img *fw, bool run_in_rfkill)
|
||||
{
|
||||
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
|
||||
bool hw_rfkill;
|
||||
int ret;
|
||||
|
||||
mutex_lock(&trans_pcie->mutex);
|
||||
|
||||
/* Someone called stop_device, don't try to start_fw */
|
||||
if (trans_pcie->is_down) {
|
||||
IWL_WARN(trans,
|
||||
"Can't start_fw since the HW hasn't been started\n");
|
||||
ret = EIO;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* This may fail if AMT took ownership of the device */
|
||||
if (iwl_pcie_prepare_card_hw(trans)) {
|
||||
IWL_WARN(trans, "Exit HW not ready\n");
|
||||
ret = -EIO;
|
||||
goto out;
|
||||
}
|
||||
|
||||
iwl_enable_rfkill_int(trans);
|
||||
|
||||
/* If platform's RF_KILL switch is NOT set to KILL */
|
||||
hw_rfkill = iwl_is_rfkill_set(trans);
|
||||
if (hw_rfkill)
|
||||
set_bit(STATUS_RFKILL, &trans->status);
|
||||
else
|
||||
clear_bit(STATUS_RFKILL, &trans->status);
|
||||
iwl_trans_pcie_rf_kill(trans, hw_rfkill);
|
||||
if (hw_rfkill && !run_in_rfkill) {
|
||||
ret = -ERFKILL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
iwl_write32(trans, CSR_INT, 0xFFFFFFFF);
|
||||
|
||||
ret = iwl_pcie_nic_init(trans);
|
||||
if (ret) {
|
||||
IWL_ERR(trans, "Unable to init nic\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* make sure rfkill handshake bits are cleared */
|
||||
iwl_write32(trans, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
|
||||
iwl_write32(trans, CSR_UCODE_DRV_GP1_CLR,
|
||||
CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED);
|
||||
|
||||
/* clear (again), then enable host interrupts */
|
||||
iwl_write32(trans, CSR_INT, 0xFFFFFFFF);
|
||||
iwl_enable_interrupts(trans);
|
||||
|
||||
/* really make sure rfkill handshake bits are cleared */
|
||||
iwl_write32(trans, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
|
||||
iwl_write32(trans, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
|
||||
|
||||
/* Load the given image to the HW */
|
||||
if (trans->cfg->device_family == IWL_DEVICE_FAMILY_8000)
|
||||
ret = iwl_pcie_load_given_ucode_8000(trans, fw);
|
||||
else
|
||||
ret = iwl_pcie_load_given_ucode(trans, fw);
|
||||
|
||||
out:
|
||||
mutex_unlock(&trans_pcie->mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void iwl_trans_pcie_fw_alive(struct iwl_trans *trans, u32 scd_addr)
|
||||
{
|
||||
iwl_pcie_reset_ict(trans);
|
||||
iwl_pcie_tx_start(trans, scd_addr);
|
||||
}
|
||||
|
||||
static void _iwl_trans_pcie_stop_device(struct iwl_trans *trans, bool low_power)
|
||||
{
|
||||
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
|
||||
|
@ -1127,7 +1051,8 @@ static void _iwl_trans_pcie_stop_device(struct iwl_trans *trans, bool low_power)
|
|||
* already dead.
|
||||
*/
|
||||
if (test_and_clear_bit(STATUS_DEVICE_ENABLED, &trans->status)) {
|
||||
IWL_DEBUG_INFO(trans, "DEVICE_ENABLED bit was set and is now cleared\n");
|
||||
IWL_DEBUG_INFO(trans,
|
||||
"DEVICE_ENABLED bit was set and is now cleared\n");
|
||||
iwl_pcie_tx_stop(trans);
|
||||
iwl_pcie_rx_stop(trans);
|
||||
|
||||
|
@ -1161,7 +1086,6 @@ static void _iwl_trans_pcie_stop_device(struct iwl_trans *trans, bool low_power)
|
|||
iwl_disable_interrupts(trans);
|
||||
spin_unlock(&trans_pcie->irq_lock);
|
||||
|
||||
|
||||
/* clear all status bits */
|
||||
clear_bit(STATUS_SYNC_HCMD_ACTIVE, &trans->status);
|
||||
clear_bit(STATUS_INT_ENABLED, &trans->status);
|
||||
|
@ -1194,10 +1118,116 @@ static void _iwl_trans_pcie_stop_device(struct iwl_trans *trans, bool low_power)
|
|||
if (hw_rfkill != was_hw_rfkill)
|
||||
iwl_trans_pcie_rf_kill(trans, hw_rfkill);
|
||||
|
||||
/* re-take ownership to prevent other users from stealing the deivce */
|
||||
/* re-take ownership to prevent other users from stealing the device */
|
||||
iwl_pcie_prepare_card_hw(trans);
|
||||
}
|
||||
|
||||
static int iwl_trans_pcie_start_fw(struct iwl_trans *trans,
|
||||
const struct fw_img *fw, bool run_in_rfkill)
|
||||
{
|
||||
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
|
||||
bool hw_rfkill;
|
||||
int ret;
|
||||
|
||||
/* This may fail if AMT took ownership of the device */
|
||||
if (iwl_pcie_prepare_card_hw(trans)) {
|
||||
IWL_WARN(trans, "Exit HW not ready\n");
|
||||
ret = -EIO;
|
||||
goto out;
|
||||
}
|
||||
|
||||
iwl_enable_rfkill_int(trans);
|
||||
|
||||
iwl_write32(trans, CSR_INT, 0xFFFFFFFF);
|
||||
|
||||
/*
|
||||
* We enabled the RF-Kill interrupt and the handler may very
|
||||
* well be running. Disable the interrupts to make sure no other
|
||||
* interrupt can be fired.
|
||||
*/
|
||||
iwl_disable_interrupts(trans);
|
||||
|
||||
/* Make sure it finished running */
|
||||
synchronize_irq(trans_pcie->pci_dev->irq);
|
||||
|
||||
mutex_lock(&trans_pcie->mutex);
|
||||
|
||||
/* If platform's RF_KILL switch is NOT set to KILL */
|
||||
hw_rfkill = iwl_is_rfkill_set(trans);
|
||||
if (hw_rfkill)
|
||||
set_bit(STATUS_RFKILL, &trans->status);
|
||||
else
|
||||
clear_bit(STATUS_RFKILL, &trans->status);
|
||||
iwl_trans_pcie_rf_kill(trans, hw_rfkill);
|
||||
if (hw_rfkill && !run_in_rfkill) {
|
||||
ret = -ERFKILL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Someone called stop_device, don't try to start_fw */
|
||||
if (trans_pcie->is_down) {
|
||||
IWL_WARN(trans,
|
||||
"Can't start_fw since the HW hasn't been started\n");
|
||||
ret = -EIO;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* make sure rfkill handshake bits are cleared */
|
||||
iwl_write32(trans, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
|
||||
iwl_write32(trans, CSR_UCODE_DRV_GP1_CLR,
|
||||
CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED);
|
||||
|
||||
/* clear (again), then enable host interrupts */
|
||||
iwl_write32(trans, CSR_INT, 0xFFFFFFFF);
|
||||
|
||||
ret = iwl_pcie_nic_init(trans);
|
||||
if (ret) {
|
||||
IWL_ERR(trans, "Unable to init nic\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* Now, we load the firmware and don't want to be interrupted, even
|
||||
* by the RF-Kill interrupt (hence mask all the interrupt besides the
|
||||
* FH_TX interrupt which is needed to load the firmware). If the
|
||||
* RF-Kill switch is toggled, we will find out after having loaded
|
||||
* the firmware and return the proper value to the caller.
|
||||
*/
|
||||
iwl_enable_fw_load_int(trans);
|
||||
|
||||
/* really make sure rfkill handshake bits are cleared */
|
||||
iwl_write32(trans, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
|
||||
iwl_write32(trans, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
|
||||
|
||||
/* Load the given image to the HW */
|
||||
if (trans->cfg->device_family == IWL_DEVICE_FAMILY_8000)
|
||||
ret = iwl_pcie_load_given_ucode_8000(trans, fw);
|
||||
else
|
||||
ret = iwl_pcie_load_given_ucode(trans, fw);
|
||||
iwl_enable_interrupts(trans);
|
||||
|
||||
/* re-check RF-Kill state since we may have missed the interrupt */
|
||||
hw_rfkill = iwl_is_rfkill_set(trans);
|
||||
if (hw_rfkill)
|
||||
set_bit(STATUS_RFKILL, &trans->status);
|
||||
else
|
||||
clear_bit(STATUS_RFKILL, &trans->status);
|
||||
|
||||
iwl_trans_pcie_rf_kill(trans, hw_rfkill);
|
||||
if (hw_rfkill && !run_in_rfkill)
|
||||
ret = -ERFKILL;
|
||||
|
||||
out:
|
||||
mutex_unlock(&trans_pcie->mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void iwl_trans_pcie_fw_alive(struct iwl_trans *trans, u32 scd_addr)
|
||||
{
|
||||
iwl_pcie_reset_ict(trans);
|
||||
iwl_pcie_tx_start(trans, scd_addr);
|
||||
}
|
||||
|
||||
static void iwl_trans_pcie_stop_device(struct iwl_trans *trans, bool low_power)
|
||||
{
|
||||
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
|
||||
|
|
|
@ -138,6 +138,11 @@ static void _rtl_rc_rate_set_series(struct rtl_priv *rtlpriv,
|
|||
((wireless_mode == WIRELESS_MODE_N_5G) ||
|
||||
(wireless_mode == WIRELESS_MODE_N_24G)))
|
||||
rate->flags |= IEEE80211_TX_RC_MCS;
|
||||
if (sta && sta->vht_cap.vht_supported &&
|
||||
(wireless_mode == WIRELESS_MODE_AC_5G ||
|
||||
wireless_mode == WIRELESS_MODE_AC_24G ||
|
||||
wireless_mode == WIRELESS_MODE_AC_ONLY))
|
||||
rate->flags |= IEEE80211_TX_RC_VHT_MCS;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -175,14 +175,14 @@ int wlcore_set_partition(struct wl1271 *wl,
|
|||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
/* We don't need the size of the last partition, as it is
|
||||
* automatically calculated based on the total memory size and
|
||||
* the sizes of the previous partitions.
|
||||
*/
|
||||
ret = wlcore_raw_write32(wl, HW_PART3_START_ADDR, p->mem3.start);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
ret = wlcore_raw_write32(wl, HW_PART3_SIZE_ADDR, p->mem3.size);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -36,8 +36,8 @@
|
|||
#define HW_PART1_START_ADDR (HW_PARTITION_REGISTERS_ADDR + 12)
|
||||
#define HW_PART2_SIZE_ADDR (HW_PARTITION_REGISTERS_ADDR + 16)
|
||||
#define HW_PART2_START_ADDR (HW_PARTITION_REGISTERS_ADDR + 20)
|
||||
#define HW_PART3_SIZE_ADDR (HW_PARTITION_REGISTERS_ADDR + 24)
|
||||
#define HW_PART3_START_ADDR (HW_PARTITION_REGISTERS_ADDR + 28)
|
||||
#define HW_PART3_START_ADDR (HW_PARTITION_REGISTERS_ADDR + 24)
|
||||
|
||||
#define HW_ACCESS_REGISTER_SIZE 4
|
||||
|
||||
#define HW_ACCESS_PRAM_MAX_RANGE 0x3c000
|
||||
|
|
|
@ -44,6 +44,8 @@
|
|||
|
||||
#include <linux/timecounter.h>
|
||||
|
||||
#define DEFAULT_UAR_PAGE_SHIFT 12
|
||||
|
||||
#define MAX_MSIX_P_PORT 17
|
||||
#define MAX_MSIX 64
|
||||
#define MIN_MSIX_P_PORT 5
|
||||
|
@ -856,6 +858,7 @@ struct mlx4_dev {
|
|||
u64 regid_promisc_array[MLX4_MAX_PORTS + 1];
|
||||
u64 regid_allmulti_array[MLX4_MAX_PORTS + 1];
|
||||
struct mlx4_vf_dev *dev_vfs;
|
||||
u8 uar_page_shift;
|
||||
};
|
||||
|
||||
struct mlx4_clock_params {
|
||||
|
@ -1528,4 +1531,14 @@ int mlx4_ACCESS_PTYS_REG(struct mlx4_dev *dev,
|
|||
int mlx4_get_internal_clock_params(struct mlx4_dev *dev,
|
||||
struct mlx4_clock_params *params);
|
||||
|
||||
static inline int mlx4_to_hw_uar_index(struct mlx4_dev *dev, int index)
|
||||
{
|
||||
return (index << (PAGE_SHIFT - dev->uar_page_shift));
|
||||
}
|
||||
|
||||
static inline int mlx4_get_num_reserved_uar(struct mlx4_dev *dev)
|
||||
{
|
||||
/* The first 128 UARs are used for EQ doorbells */
|
||||
return (128 >> (PAGE_SHIFT - dev->uar_page_shift));
|
||||
}
|
||||
#endif /* MLX4_DEVICE_H */
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -3718,7 +3718,7 @@ void *netdev_lower_get_next_private_rcu(struct net_device *dev,
|
|||
void *netdev_lower_get_next(struct net_device *dev,
|
||||
struct list_head **iter);
|
||||
#define netdev_for_each_lower_dev(dev, ldev, iter) \
|
||||
for (iter = &(dev)->adj_list.lower, \
|
||||
for (iter = (dev)->adj_list.lower.next, \
|
||||
ldev = netdev_lower_get_next(dev, &(iter)); \
|
||||
ldev; \
|
||||
ldev = netdev_lower_get_next(dev, &(iter)))
|
||||
|
|
|
@ -44,6 +44,7 @@
|
|||
|
||||
#define KNAV_DMA_NUM_EPIB_WORDS 4
|
||||
#define KNAV_DMA_NUM_PS_WORDS 16
|
||||
#define KNAV_DMA_NUM_SW_DATA_WORDS 4
|
||||
#define KNAV_DMA_FDQ_PER_CHAN 4
|
||||
|
||||
/* Tx channel scheduling priority */
|
||||
|
@ -142,6 +143,7 @@ struct knav_dma_cfg {
|
|||
* @orig_buff: buff pointer since 'buff' can be overwritten
|
||||
* @epib: Extended packet info block
|
||||
* @psdata: Protocol specific
|
||||
* @sw_data: Software private data not touched by h/w
|
||||
*/
|
||||
struct knav_dma_desc {
|
||||
__le32 desc_info;
|
||||
|
@ -154,7 +156,7 @@ struct knav_dma_desc {
|
|||
__le32 orig_buff;
|
||||
__le32 epib[KNAV_DMA_NUM_EPIB_WORDS];
|
||||
__le32 psdata[KNAV_DMA_NUM_PS_WORDS];
|
||||
__le32 pad[4];
|
||||
u32 sw_data[KNAV_DMA_NUM_SW_DATA_WORDS];
|
||||
} ____cacheline_aligned;
|
||||
|
||||
#if IS_ENABLED(CONFIG_KEYSTONE_NAVIGATOR_DMA)
|
||||
|
|
|
@ -270,7 +270,8 @@ struct dst_entry *inet_csk_route_child_sock(const struct sock *sk,
|
|||
struct sock *newsk,
|
||||
const struct request_sock *req);
|
||||
|
||||
void inet_csk_reqsk_queue_add(struct sock *sk, struct request_sock *req,
|
||||
struct sock *inet_csk_reqsk_queue_add(struct sock *sk,
|
||||
struct request_sock *req,
|
||||
struct sock *child);
|
||||
void inet_csk_reqsk_queue_hash_add(struct sock *sk, struct request_sock *req,
|
||||
unsigned long timeout);
|
||||
|
|
|
@ -61,6 +61,7 @@ struct fib_nh_exception {
|
|||
struct rtable __rcu *fnhe_rth_input;
|
||||
struct rtable __rcu *fnhe_rth_output;
|
||||
unsigned long fnhe_stamp;
|
||||
struct rcu_head rcu;
|
||||
};
|
||||
|
||||
struct fnhe_hash_bucket {
|
||||
|
|
|
@ -1625,7 +1625,7 @@ static int atalk_sendmsg(struct socket *sock, struct msghdr *msg, size_t len)
|
|||
|
||||
rt = atrtr_find(&at_hint);
|
||||
}
|
||||
err = ENETUNREACH;
|
||||
err = -ENETUNREACH;
|
||||
if (!rt)
|
||||
goto out;
|
||||
|
||||
|
|
|
@ -527,10 +527,11 @@ void batadv_gw_node_update(struct batadv_priv *bat_priv,
|
|||
* gets dereferenced.
|
||||
*/
|
||||
spin_lock_bh(&bat_priv->gw.list_lock);
|
||||
if (!hlist_unhashed(&gw_node->list)) {
|
||||
hlist_del_init_rcu(&gw_node->list);
|
||||
spin_unlock_bh(&bat_priv->gw.list_lock);
|
||||
|
||||
batadv_gw_node_free_ref(gw_node);
|
||||
}
|
||||
spin_unlock_bh(&bat_priv->gw.list_lock);
|
||||
|
||||
curr_gw = batadv_gw_get_selected_gw_node(bat_priv);
|
||||
if (gw_node == curr_gw)
|
||||
|
|
|
@ -75,6 +75,28 @@ out:
|
|||
return hard_iface;
|
||||
}
|
||||
|
||||
/**
|
||||
* batadv_mutual_parents - check if two devices are each others parent
|
||||
* @dev1: 1st net_device
|
||||
* @dev2: 2nd net_device
|
||||
*
|
||||
* veth devices come in pairs and each is the parent of the other!
|
||||
*
|
||||
* Return: true if the devices are each others parent, otherwise false
|
||||
*/
|
||||
static bool batadv_mutual_parents(const struct net_device *dev1,
|
||||
const struct net_device *dev2)
|
||||
{
|
||||
int dev1_parent_iflink = dev_get_iflink(dev1);
|
||||
int dev2_parent_iflink = dev_get_iflink(dev2);
|
||||
|
||||
if (!dev1_parent_iflink || !dev2_parent_iflink)
|
||||
return false;
|
||||
|
||||
return (dev1_parent_iflink == dev2->ifindex) &&
|
||||
(dev2_parent_iflink == dev1->ifindex);
|
||||
}
|
||||
|
||||
/**
|
||||
* batadv_is_on_batman_iface - check if a device is a batman iface descendant
|
||||
* @net_dev: the device to check
|
||||
|
@ -108,6 +130,9 @@ static bool batadv_is_on_batman_iface(const struct net_device *net_dev)
|
|||
if (WARN(!parent_dev, "Cannot find parent device"))
|
||||
return false;
|
||||
|
||||
if (batadv_mutual_parents(net_dev, parent_dev))
|
||||
return false;
|
||||
|
||||
ret = batadv_is_on_batman_iface(parent_dev);
|
||||
|
||||
return ret;
|
||||
|
|
|
@ -303,10 +303,12 @@ static void batadv_tt_global_size_mod(struct batadv_orig_node *orig_node,
|
|||
|
||||
if (atomic_add_return(v, &vlan->tt.num_entries) == 0) {
|
||||
spin_lock_bh(&orig_node->vlan_list_lock);
|
||||
if (!hlist_unhashed(&vlan->list)) {
|
||||
hlist_del_init_rcu(&vlan->list);
|
||||
spin_unlock_bh(&orig_node->vlan_list_lock);
|
||||
batadv_orig_node_vlan_free_ref(vlan);
|
||||
}
|
||||
spin_unlock_bh(&orig_node->vlan_list_lock);
|
||||
}
|
||||
|
||||
batadv_orig_node_vlan_free_ref(vlan);
|
||||
}
|
||||
|
|
|
@ -4112,8 +4112,10 @@ void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status,
|
|||
break;
|
||||
}
|
||||
|
||||
*req_complete = bt_cb(skb)->hci.req_complete;
|
||||
if (bt_cb(skb)->hci.req_flags & HCI_REQ_SKB)
|
||||
*req_complete_skb = bt_cb(skb)->hci.req_complete_skb;
|
||||
else
|
||||
*req_complete = bt_cb(skb)->hci.req_complete;
|
||||
kfree_skb(skb);
|
||||
}
|
||||
spin_unlock_irqrestore(&hdev->cmd_q.lock, flags);
|
||||
|
|
|
@ -425,8 +425,8 @@ static int br_mdb_add_group(struct net_bridge *br, struct net_bridge_port *port,
|
|||
mp = br_mdb_ip_get(mdb, group);
|
||||
if (!mp) {
|
||||
mp = br_multicast_new_group(br, port, group);
|
||||
err = PTR_ERR(mp);
|
||||
if (IS_ERR(mp))
|
||||
err = PTR_ERR_OR_ZERO(mp);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
|
|
|
@ -159,7 +159,7 @@ static int cfrfml_receive(struct cflayer *layr, struct cfpkt *pkt)
|
|||
tmppkt = NULL;
|
||||
|
||||
/* Verify that length is correct */
|
||||
err = EPROTO;
|
||||
err = -EPROTO;
|
||||
if (rfml->pdu_size != cfpkt_getlen(pkt) - RFM_HEAD_SIZE + 1)
|
||||
goto out;
|
||||
}
|
||||
|
|
|
@ -5379,12 +5379,12 @@ void *netdev_lower_get_next(struct net_device *dev, struct list_head **iter)
|
|||
{
|
||||
struct netdev_adjacent *lower;
|
||||
|
||||
lower = list_entry((*iter)->next, struct netdev_adjacent, list);
|
||||
lower = list_entry(*iter, struct netdev_adjacent, list);
|
||||
|
||||
if (&lower->list == &dev->adj_list.lower)
|
||||
return NULL;
|
||||
|
||||
*iter = &lower->list;
|
||||
*iter = lower->list.next;
|
||||
|
||||
return lower->dev;
|
||||
}
|
||||
|
@ -7422,8 +7422,10 @@ struct net_device *alloc_netdev_mqs(int sizeof_priv, const char *name,
|
|||
dev->priv_flags = IFF_XMIT_DST_RELEASE | IFF_XMIT_DST_RELEASE_PERM;
|
||||
setup(dev);
|
||||
|
||||
if (!dev->tx_queue_len)
|
||||
if (!dev->tx_queue_len) {
|
||||
dev->priv_flags |= IFF_NO_QUEUE;
|
||||
dev->tx_queue_len = 1;
|
||||
}
|
||||
|
||||
dev->num_tx_queues = txqs;
|
||||
dev->real_num_tx_queues = txqs;
|
||||
|
|
|
@ -399,6 +399,13 @@ ip_proto_again:
|
|||
goto out_bad;
|
||||
proto = eth->h_proto;
|
||||
nhoff += sizeof(*eth);
|
||||
|
||||
/* Cap headers that we access via pointers at the
|
||||
* end of the Ethernet header as our maximum alignment
|
||||
* at that point is only 2 bytes.
|
||||
*/
|
||||
if (NET_IP_ALIGN)
|
||||
hlen = nhoff;
|
||||
}
|
||||
|
||||
key_control->flags |= FLOW_DIS_ENCAPSULATION;
|
||||
|
|
|
@ -824,26 +824,26 @@ lookup:
|
|||
|
||||
if (sk->sk_state == DCCP_NEW_SYN_RECV) {
|
||||
struct request_sock *req = inet_reqsk(sk);
|
||||
struct sock *nsk = NULL;
|
||||
struct sock *nsk;
|
||||
|
||||
sk = req->rsk_listener;
|
||||
if (likely(sk->sk_state == DCCP_LISTEN)) {
|
||||
nsk = dccp_check_req(sk, skb, req);
|
||||
} else {
|
||||
if (unlikely(sk->sk_state != DCCP_LISTEN)) {
|
||||
inet_csk_reqsk_queue_drop_and_put(sk, req);
|
||||
goto lookup;
|
||||
}
|
||||
sock_hold(sk);
|
||||
nsk = dccp_check_req(sk, skb, req);
|
||||
if (!nsk) {
|
||||
reqsk_put(req);
|
||||
goto discard_it;
|
||||
goto discard_and_relse;
|
||||
}
|
||||
if (nsk == sk) {
|
||||
sock_hold(sk);
|
||||
reqsk_put(req);
|
||||
} else if (dccp_child_process(sk, nsk, skb)) {
|
||||
dccp_v4_ctl_send_reset(sk, skb);
|
||||
goto discard_it;
|
||||
goto discard_and_relse;
|
||||
} else {
|
||||
sock_put(sk);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -691,26 +691,26 @@ lookup:
|
|||
|
||||
if (sk->sk_state == DCCP_NEW_SYN_RECV) {
|
||||
struct request_sock *req = inet_reqsk(sk);
|
||||
struct sock *nsk = NULL;
|
||||
struct sock *nsk;
|
||||
|
||||
sk = req->rsk_listener;
|
||||
if (likely(sk->sk_state == DCCP_LISTEN)) {
|
||||
nsk = dccp_check_req(sk, skb, req);
|
||||
} else {
|
||||
if (unlikely(sk->sk_state != DCCP_LISTEN)) {
|
||||
inet_csk_reqsk_queue_drop_and_put(sk, req);
|
||||
goto lookup;
|
||||
}
|
||||
sock_hold(sk);
|
||||
nsk = dccp_check_req(sk, skb, req);
|
||||
if (!nsk) {
|
||||
reqsk_put(req);
|
||||
goto discard_it;
|
||||
goto discard_and_relse;
|
||||
}
|
||||
if (nsk == sk) {
|
||||
sock_hold(sk);
|
||||
reqsk_put(req);
|
||||
} else if (dccp_child_process(sk, nsk, skb)) {
|
||||
dccp_v6_ctl_send_reset(sk, skb);
|
||||
goto discard_it;
|
||||
goto discard_and_relse;
|
||||
} else {
|
||||
sock_put(sk);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1194,7 +1194,6 @@ int dsa_slave_create(struct dsa_switch *ds, struct device *parent,
|
|||
if (ret) {
|
||||
netdev_err(master, "error %d registering interface %s\n",
|
||||
ret, slave_dev->name);
|
||||
phy_disconnect(p->phy);
|
||||
ds->ports[port] = NULL;
|
||||
free_netdev(slave_dev);
|
||||
return ret;
|
||||
|
@ -1205,6 +1204,7 @@ int dsa_slave_create(struct dsa_switch *ds, struct device *parent,
|
|||
ret = dsa_slave_phy_setup(p, slave_dev);
|
||||
if (ret) {
|
||||
netdev_err(master, "error %d setting up slave phy\n", ret);
|
||||
unregister_netdev(slave_dev);
|
||||
free_netdev(slave_dev);
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -1847,7 +1847,7 @@ static int inet_netconf_get_devconf(struct sk_buff *in_skb,
|
|||
if (err < 0)
|
||||
goto errout;
|
||||
|
||||
err = EINVAL;
|
||||
err = -EINVAL;
|
||||
if (!tb[NETCONFA_IFINDEX])
|
||||
goto errout;
|
||||
|
||||
|
|
|
@ -789,7 +789,8 @@ static void inet_child_forget(struct sock *sk, struct request_sock *req,
|
|||
reqsk_put(req);
|
||||
}
|
||||
|
||||
void inet_csk_reqsk_queue_add(struct sock *sk, struct request_sock *req,
|
||||
struct sock *inet_csk_reqsk_queue_add(struct sock *sk,
|
||||
struct request_sock *req,
|
||||
struct sock *child)
|
||||
{
|
||||
struct request_sock_queue *queue = &inet_csk(sk)->icsk_accept_queue;
|
||||
|
@ -797,6 +798,7 @@ void inet_csk_reqsk_queue_add(struct sock *sk, struct request_sock *req,
|
|||
spin_lock(&queue->rskq_lock);
|
||||
if (unlikely(sk->sk_state != TCP_LISTEN)) {
|
||||
inet_child_forget(sk, req, child);
|
||||
child = NULL;
|
||||
} else {
|
||||
req->sk = child;
|
||||
req->dl_next = NULL;
|
||||
|
@ -808,6 +810,7 @@ void inet_csk_reqsk_queue_add(struct sock *sk, struct request_sock *req,
|
|||
sk_acceptq_added(sk);
|
||||
}
|
||||
spin_unlock(&queue->rskq_lock);
|
||||
return child;
|
||||
}
|
||||
EXPORT_SYMBOL(inet_csk_reqsk_queue_add);
|
||||
|
||||
|
@ -817,10 +820,7 @@ struct sock *inet_csk_complete_hashdance(struct sock *sk, struct sock *child,
|
|||
if (own_req) {
|
||||
inet_csk_reqsk_queue_drop(sk, req);
|
||||
reqsk_queue_removed(&inet_csk(sk)->icsk_accept_queue, req);
|
||||
inet_csk_reqsk_queue_add(sk, req, child);
|
||||
/* Warning: caller must not call reqsk_put(req);
|
||||
* child stole last reference on it.
|
||||
*/
|
||||
if (inet_csk_reqsk_queue_add(sk, req, child))
|
||||
return child;
|
||||
}
|
||||
/* Too bad, another child took ownership of the request, undo. */
|
||||
|
|
|
@ -1055,6 +1055,7 @@ static void ipgre_tap_setup(struct net_device *dev)
|
|||
{
|
||||
ether_setup(dev);
|
||||
dev->netdev_ops = &gre_tap_netdev_ops;
|
||||
dev->priv_flags &= ~IFF_TX_SKB_SHARING;
|
||||
dev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
|
||||
ip_tunnel_setup(dev, gre_tap_net_id);
|
||||
}
|
||||
|
|
|
@ -249,6 +249,8 @@ int ip_cmsg_send(struct net *net, struct msghdr *msg, struct ipcm_cookie *ipc,
|
|||
switch (cmsg->cmsg_type) {
|
||||
case IP_RETOPTS:
|
||||
err = cmsg->cmsg_len - CMSG_ALIGN(sizeof(struct cmsghdr));
|
||||
|
||||
/* Our caller is responsible for freeing ipc->opt */
|
||||
err = ip_options_get(net, &ipc->opt, CMSG_DATA(cmsg),
|
||||
err < 40 ? err : 40);
|
||||
if (err)
|
||||
|
|
|
@ -746,8 +746,10 @@ static int ping_v4_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
|
|||
|
||||
if (msg->msg_controllen) {
|
||||
err = ip_cmsg_send(sock_net(sk), msg, &ipc, false);
|
||||
if (err)
|
||||
if (unlikely(err)) {
|
||||
kfree(ipc.opt);
|
||||
return err;
|
||||
}
|
||||
if (ipc.opt)
|
||||
free = 1;
|
||||
}
|
||||
|
|
|
@ -547,8 +547,10 @@ static int raw_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
|
|||
|
||||
if (msg->msg_controllen) {
|
||||
err = ip_cmsg_send(net, msg, &ipc, false);
|
||||
if (err)
|
||||
if (unlikely(err)) {
|
||||
kfree(ipc.opt);
|
||||
goto out;
|
||||
}
|
||||
if (ipc.opt)
|
||||
free = 1;
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue