diff options
Diffstat (limited to 'drivers/net')
131 files changed, 2653 insertions, 700 deletions
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index f342278539d5..494b888a6568 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig | |||
| @@ -139,7 +139,7 @@ config MACVTAP | |||
| 139 | This adds a specialized tap character device driver that is based | 139 | This adds a specialized tap character device driver that is based |
| 140 | on the MAC-VLAN network interface, called macvtap. A macvtap device | 140 | on the MAC-VLAN network interface, called macvtap. A macvtap device |
| 141 | can be added in the same way as a macvlan device, using 'type | 141 | can be added in the same way as a macvlan device, using 'type |
| 142 | macvlan', and then be accessed through the tap user space interface. | 142 | macvtap', and then be accessed through the tap user space interface. |
| 143 | 143 | ||
| 144 | To compile this driver as a module, choose M here: the module | 144 | To compile this driver as a module, choose M here: the module |
| 145 | will be called macvtap. | 145 | will be called macvtap. |
diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c index cce1f1bf90b4..dcde56057fe1 100644 --- a/drivers/net/bonding/bond_3ad.c +++ b/drivers/net/bonding/bond_3ad.c | |||
| @@ -181,7 +181,7 @@ static inline int __agg_has_partner(struct aggregator *agg) | |||
| 181 | */ | 181 | */ |
| 182 | static inline void __disable_port(struct port *port) | 182 | static inline void __disable_port(struct port *port) |
| 183 | { | 183 | { |
| 184 | bond_set_slave_inactive_flags(port->slave); | 184 | bond_set_slave_inactive_flags(port->slave, BOND_SLAVE_NOTIFY_LATER); |
| 185 | } | 185 | } |
| 186 | 186 | ||
| 187 | /** | 187 | /** |
| @@ -193,7 +193,7 @@ static inline void __enable_port(struct port *port) | |||
| 193 | struct slave *slave = port->slave; | 193 | struct slave *slave = port->slave; |
| 194 | 194 | ||
| 195 | if ((slave->link == BOND_LINK_UP) && IS_UP(slave->dev)) | 195 | if ((slave->link == BOND_LINK_UP) && IS_UP(slave->dev)) |
| 196 | bond_set_slave_active_flags(slave); | 196 | bond_set_slave_active_flags(slave, BOND_SLAVE_NOTIFY_LATER); |
| 197 | } | 197 | } |
| 198 | 198 | ||
| 199 | /** | 199 | /** |
| @@ -1796,8 +1796,6 @@ void bond_3ad_initiate_agg_selection(struct bonding *bond, int timeout) | |||
| 1796 | BOND_AD_INFO(bond).agg_select_timer = timeout; | 1796 | BOND_AD_INFO(bond).agg_select_timer = timeout; |
| 1797 | } | 1797 | } |
| 1798 | 1798 | ||
| 1799 | static u16 aggregator_identifier; | ||
| 1800 | |||
| 1801 | /** | 1799 | /** |
| 1802 | * bond_3ad_initialize - initialize a bond's 802.3ad parameters and structures | 1800 | * bond_3ad_initialize - initialize a bond's 802.3ad parameters and structures |
| 1803 | * @bond: bonding struct to work on | 1801 | * @bond: bonding struct to work on |
| @@ -1811,7 +1809,7 @@ void bond_3ad_initialize(struct bonding *bond, u16 tick_resolution) | |||
| 1811 | if (!MAC_ADDRESS_EQUAL(&(BOND_AD_INFO(bond).system.sys_mac_addr), | 1809 | if (!MAC_ADDRESS_EQUAL(&(BOND_AD_INFO(bond).system.sys_mac_addr), |
| 1812 | bond->dev->dev_addr)) { | 1810 | bond->dev->dev_addr)) { |
| 1813 | 1811 | ||
| 1814 | aggregator_identifier = 0; | 1812 | BOND_AD_INFO(bond).aggregator_identifier = 0; |
| 1815 | 1813 | ||
| 1816 | BOND_AD_INFO(bond).system.sys_priority = 0xFFFF; | 1814 | BOND_AD_INFO(bond).system.sys_priority = 0xFFFF; |
| 1817 | BOND_AD_INFO(bond).system.sys_mac_addr = *((struct mac_addr *)bond->dev->dev_addr); | 1815 | BOND_AD_INFO(bond).system.sys_mac_addr = *((struct mac_addr *)bond->dev->dev_addr); |
| @@ -1880,7 +1878,7 @@ void bond_3ad_bind_slave(struct slave *slave) | |||
| 1880 | ad_initialize_agg(aggregator); | 1878 | ad_initialize_agg(aggregator); |
| 1881 | 1879 | ||
| 1882 | aggregator->aggregator_mac_address = *((struct mac_addr *)bond->dev->dev_addr); | 1880 | aggregator->aggregator_mac_address = *((struct mac_addr *)bond->dev->dev_addr); |
| 1883 | aggregator->aggregator_identifier = (++aggregator_identifier); | 1881 | aggregator->aggregator_identifier = ++BOND_AD_INFO(bond).aggregator_identifier; |
| 1884 | aggregator->slave = slave; | 1882 | aggregator->slave = slave; |
| 1885 | aggregator->is_active = 0; | 1883 | aggregator->is_active = 0; |
| 1886 | aggregator->num_of_ports = 0; | 1884 | aggregator->num_of_ports = 0; |
| @@ -2064,6 +2062,7 @@ void bond_3ad_state_machine_handler(struct work_struct *work) | |||
| 2064 | struct list_head *iter; | 2062 | struct list_head *iter; |
| 2065 | struct slave *slave; | 2063 | struct slave *slave; |
| 2066 | struct port *port; | 2064 | struct port *port; |
| 2065 | bool should_notify_rtnl = BOND_SLAVE_NOTIFY_LATER; | ||
| 2067 | 2066 | ||
| 2068 | read_lock(&bond->lock); | 2067 | read_lock(&bond->lock); |
| 2069 | rcu_read_lock(); | 2068 | rcu_read_lock(); |
| @@ -2121,8 +2120,19 @@ void bond_3ad_state_machine_handler(struct work_struct *work) | |||
| 2121 | } | 2120 | } |
| 2122 | 2121 | ||
| 2123 | re_arm: | 2122 | re_arm: |
| 2123 | bond_for_each_slave_rcu(bond, slave, iter) { | ||
| 2124 | if (slave->should_notify) { | ||
| 2125 | should_notify_rtnl = BOND_SLAVE_NOTIFY_NOW; | ||
| 2126 | break; | ||
| 2127 | } | ||
| 2128 | } | ||
| 2124 | rcu_read_unlock(); | 2129 | rcu_read_unlock(); |
| 2125 | read_unlock(&bond->lock); | 2130 | read_unlock(&bond->lock); |
| 2131 | |||
| 2132 | if (should_notify_rtnl && rtnl_trylock()) { | ||
| 2133 | bond_slave_state_notify(bond); | ||
| 2134 | rtnl_unlock(); | ||
| 2135 | } | ||
| 2126 | queue_delayed_work(bond->wq, &bond->ad_work, ad_delta_in_ticks); | 2136 | queue_delayed_work(bond->wq, &bond->ad_work, ad_delta_in_ticks); |
| 2127 | } | 2137 | } |
| 2128 | 2138 | ||
diff --git a/drivers/net/bonding/bond_3ad.h b/drivers/net/bonding/bond_3ad.h index 13dc9d3c5e34..f4dd9592ac62 100644 --- a/drivers/net/bonding/bond_3ad.h +++ b/drivers/net/bonding/bond_3ad.h | |||
| @@ -253,6 +253,7 @@ struct ad_system { | |||
| 253 | struct ad_bond_info { | 253 | struct ad_bond_info { |
| 254 | struct ad_system system; /* 802.3ad system structure */ | 254 | struct ad_system system; /* 802.3ad system structure */ |
| 255 | u32 agg_select_timer; // Timer to select aggregator after all adapter's hand shakes | 255 | u32 agg_select_timer; // Timer to select aggregator after all adapter's hand shakes |
| 256 | u16 aggregator_identifier; | ||
| 256 | }; | 257 | }; |
| 257 | 258 | ||
| 258 | struct ad_slave_info { | 259 | struct ad_slave_info { |
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 4c08018d7333..e5628fc725c3 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c | |||
| @@ -829,21 +829,25 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active) | |||
| 829 | if (bond_is_lb(bond)) { | 829 | if (bond_is_lb(bond)) { |
| 830 | bond_alb_handle_active_change(bond, new_active); | 830 | bond_alb_handle_active_change(bond, new_active); |
| 831 | if (old_active) | 831 | if (old_active) |
| 832 | bond_set_slave_inactive_flags(old_active); | 832 | bond_set_slave_inactive_flags(old_active, |
| 833 | BOND_SLAVE_NOTIFY_NOW); | ||
| 833 | if (new_active) | 834 | if (new_active) |
| 834 | bond_set_slave_active_flags(new_active); | 835 | bond_set_slave_active_flags(new_active, |
| 836 | BOND_SLAVE_NOTIFY_NOW); | ||
| 835 | } else { | 837 | } else { |
| 836 | rcu_assign_pointer(bond->curr_active_slave, new_active); | 838 | rcu_assign_pointer(bond->curr_active_slave, new_active); |
| 837 | } | 839 | } |
| 838 | 840 | ||
| 839 | if (bond->params.mode == BOND_MODE_ACTIVEBACKUP) { | 841 | if (bond->params.mode == BOND_MODE_ACTIVEBACKUP) { |
| 840 | if (old_active) | 842 | if (old_active) |
| 841 | bond_set_slave_inactive_flags(old_active); | 843 | bond_set_slave_inactive_flags(old_active, |
| 844 | BOND_SLAVE_NOTIFY_NOW); | ||
| 842 | 845 | ||
| 843 | if (new_active) { | 846 | if (new_active) { |
| 844 | bool should_notify_peers = false; | 847 | bool should_notify_peers = false; |
| 845 | 848 | ||
| 846 | bond_set_slave_active_flags(new_active); | 849 | bond_set_slave_active_flags(new_active, |
| 850 | BOND_SLAVE_NOTIFY_NOW); | ||
| 847 | 851 | ||
| 848 | if (bond->params.fail_over_mac) | 852 | if (bond->params.fail_over_mac) |
| 849 | bond_do_fail_over_mac(bond, new_active, | 853 | bond_do_fail_over_mac(bond, new_active, |
| @@ -1193,6 +1197,11 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) | |||
| 1193 | return -EBUSY; | 1197 | return -EBUSY; |
| 1194 | } | 1198 | } |
| 1195 | 1199 | ||
| 1200 | if (bond_dev == slave_dev) { | ||
| 1201 | pr_err("%s: cannot enslave bond to itself.\n", bond_dev->name); | ||
| 1202 | return -EPERM; | ||
| 1203 | } | ||
| 1204 | |||
| 1196 | /* vlan challenged mutual exclusion */ | 1205 | /* vlan challenged mutual exclusion */ |
| 1197 | /* no need to lock since we're protected by rtnl_lock */ | 1206 | /* no need to lock since we're protected by rtnl_lock */ |
| 1198 | if (slave_dev->features & NETIF_F_VLAN_CHALLENGED) { | 1207 | if (slave_dev->features & NETIF_F_VLAN_CHALLENGED) { |
| @@ -1270,9 +1279,13 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) | |||
| 1270 | 1279 | ||
| 1271 | if (slave_ops->ndo_set_mac_address == NULL) { | 1280 | if (slave_ops->ndo_set_mac_address == NULL) { |
| 1272 | if (!bond_has_slaves(bond)) { | 1281 | if (!bond_has_slaves(bond)) { |
| 1273 | pr_warning("%s: Warning: The first slave device specified does not support setting the MAC address. Setting fail_over_mac to active.", | 1282 | pr_warn("%s: Warning: The first slave device specified does not support setting the MAC address.\n", |
| 1274 | bond_dev->name); | 1283 | bond_dev->name); |
| 1275 | bond->params.fail_over_mac = BOND_FOM_ACTIVE; | 1284 | if (bond->params.mode == BOND_MODE_ACTIVEBACKUP) { |
| 1285 | bond->params.fail_over_mac = BOND_FOM_ACTIVE; | ||
| 1286 | pr_warn("%s: Setting fail_over_mac to active for active-backup mode.\n", | ||
| 1287 | bond_dev->name); | ||
| 1288 | } | ||
| 1276 | } else if (bond->params.fail_over_mac != BOND_FOM_ACTIVE) { | 1289 | } else if (bond->params.fail_over_mac != BOND_FOM_ACTIVE) { |
| 1277 | pr_err("%s: Error: The slave device specified does not support setting the MAC address, but fail_over_mac is not set to active.\n", | 1290 | pr_err("%s: Error: The slave device specified does not support setting the MAC address, but fail_over_mac is not set to active.\n", |
| 1278 | bond_dev->name); | 1291 | bond_dev->name); |
| @@ -1315,7 +1328,8 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) | |||
| 1315 | */ | 1328 | */ |
| 1316 | memcpy(new_slave->perm_hwaddr, slave_dev->dev_addr, ETH_ALEN); | 1329 | memcpy(new_slave->perm_hwaddr, slave_dev->dev_addr, ETH_ALEN); |
| 1317 | 1330 | ||
| 1318 | if (!bond->params.fail_over_mac) { | 1331 | if (!bond->params.fail_over_mac || |
| 1332 | bond->params.mode != BOND_MODE_ACTIVEBACKUP) { | ||
| 1319 | /* | 1333 | /* |
| 1320 | * Set slave to master's mac address. The application already | 1334 | * Set slave to master's mac address. The application already |
| 1321 | * set the master's mac address to that of the first slave | 1335 | * set the master's mac address to that of the first slave |
| @@ -1458,14 +1472,15 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) | |||
| 1458 | 1472 | ||
| 1459 | switch (bond->params.mode) { | 1473 | switch (bond->params.mode) { |
| 1460 | case BOND_MODE_ACTIVEBACKUP: | 1474 | case BOND_MODE_ACTIVEBACKUP: |
| 1461 | bond_set_slave_inactive_flags(new_slave); | 1475 | bond_set_slave_inactive_flags(new_slave, |
| 1476 | BOND_SLAVE_NOTIFY_NOW); | ||
| 1462 | break; | 1477 | break; |
| 1463 | case BOND_MODE_8023AD: | 1478 | case BOND_MODE_8023AD: |
| 1464 | /* in 802.3ad mode, the internal mechanism | 1479 | /* in 802.3ad mode, the internal mechanism |
| 1465 | * will activate the slaves in the selected | 1480 | * will activate the slaves in the selected |
| 1466 | * aggregator | 1481 | * aggregator |
| 1467 | */ | 1482 | */ |
| 1468 | bond_set_slave_inactive_flags(new_slave); | 1483 | bond_set_slave_inactive_flags(new_slave, BOND_SLAVE_NOTIFY_NOW); |
| 1469 | /* if this is the first slave */ | 1484 | /* if this is the first slave */ |
| 1470 | if (!prev_slave) { | 1485 | if (!prev_slave) { |
| 1471 | SLAVE_AD_INFO(new_slave).id = 1; | 1486 | SLAVE_AD_INFO(new_slave).id = 1; |
| @@ -1483,7 +1498,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) | |||
| 1483 | case BOND_MODE_TLB: | 1498 | case BOND_MODE_TLB: |
| 1484 | case BOND_MODE_ALB: | 1499 | case BOND_MODE_ALB: |
| 1485 | bond_set_active_slave(new_slave); | 1500 | bond_set_active_slave(new_slave); |
| 1486 | bond_set_slave_inactive_flags(new_slave); | 1501 | bond_set_slave_inactive_flags(new_slave, BOND_SLAVE_NOTIFY_NOW); |
| 1487 | break; | 1502 | break; |
| 1488 | default: | 1503 | default: |
| 1489 | pr_debug("This slave is always active in trunk mode\n"); | 1504 | pr_debug("This slave is always active in trunk mode\n"); |
| @@ -1505,7 +1520,6 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) | |||
| 1505 | slave_dev->npinfo = bond->dev->npinfo; | 1520 | slave_dev->npinfo = bond->dev->npinfo; |
| 1506 | if (slave_dev->npinfo) { | 1521 | if (slave_dev->npinfo) { |
| 1507 | if (slave_enable_netpoll(new_slave)) { | 1522 | if (slave_enable_netpoll(new_slave)) { |
| 1508 | read_unlock(&bond->lock); | ||
| 1509 | pr_info("Error, %s: master_dev is using netpoll, " | 1523 | pr_info("Error, %s: master_dev is using netpoll, " |
| 1510 | "but new slave device does not support netpoll.\n", | 1524 | "but new slave device does not support netpoll.\n", |
| 1511 | bond_dev->name); | 1525 | bond_dev->name); |
| @@ -1539,9 +1553,11 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) | |||
| 1539 | bond_set_carrier(bond); | 1553 | bond_set_carrier(bond); |
| 1540 | 1554 | ||
| 1541 | if (USES_PRIMARY(bond->params.mode)) { | 1555 | if (USES_PRIMARY(bond->params.mode)) { |
| 1556 | block_netpoll_tx(); | ||
| 1542 | write_lock_bh(&bond->curr_slave_lock); | 1557 | write_lock_bh(&bond->curr_slave_lock); |
| 1543 | bond_select_active_slave(bond); | 1558 | bond_select_active_slave(bond); |
| 1544 | write_unlock_bh(&bond->curr_slave_lock); | 1559 | write_unlock_bh(&bond->curr_slave_lock); |
| 1560 | unblock_netpoll_tx(); | ||
| 1545 | } | 1561 | } |
| 1546 | 1562 | ||
| 1547 | pr_info("%s: enslaving %s as a%s interface with a%s link.\n", | 1563 | pr_info("%s: enslaving %s as a%s interface with a%s link.\n", |
| @@ -1567,10 +1583,12 @@ err_detach: | |||
| 1567 | if (bond->primary_slave == new_slave) | 1583 | if (bond->primary_slave == new_slave) |
| 1568 | bond->primary_slave = NULL; | 1584 | bond->primary_slave = NULL; |
| 1569 | if (bond->curr_active_slave == new_slave) { | 1585 | if (bond->curr_active_slave == new_slave) { |
| 1586 | block_netpoll_tx(); | ||
| 1570 | write_lock_bh(&bond->curr_slave_lock); | 1587 | write_lock_bh(&bond->curr_slave_lock); |
| 1571 | bond_change_active_slave(bond, NULL); | 1588 | bond_change_active_slave(bond, NULL); |
| 1572 | bond_select_active_slave(bond); | 1589 | bond_select_active_slave(bond); |
| 1573 | write_unlock_bh(&bond->curr_slave_lock); | 1590 | write_unlock_bh(&bond->curr_slave_lock); |
| 1591 | unblock_netpoll_tx(); | ||
| 1574 | } | 1592 | } |
| 1575 | slave_disable_netpoll(new_slave); | 1593 | slave_disable_netpoll(new_slave); |
| 1576 | 1594 | ||
| @@ -1579,7 +1597,8 @@ err_close: | |||
| 1579 | dev_close(slave_dev); | 1597 | dev_close(slave_dev); |
| 1580 | 1598 | ||
| 1581 | err_restore_mac: | 1599 | err_restore_mac: |
| 1582 | if (!bond->params.fail_over_mac) { | 1600 | if (!bond->params.fail_over_mac || |
| 1601 | bond->params.mode != BOND_MODE_ACTIVEBACKUP) { | ||
| 1583 | /* XXX TODO - fom follow mode needs to change master's | 1602 | /* XXX TODO - fom follow mode needs to change master's |
| 1584 | * MAC if this slave's MAC is in use by the bond, or at | 1603 | * MAC if this slave's MAC is in use by the bond, or at |
| 1585 | * least print a warning. | 1604 | * least print a warning. |
| @@ -1645,9 +1664,6 @@ static int __bond_release_one(struct net_device *bond_dev, | |||
| 1645 | return -EINVAL; | 1664 | return -EINVAL; |
| 1646 | } | 1665 | } |
| 1647 | 1666 | ||
| 1648 | /* release the slave from its bond */ | ||
| 1649 | bond->slave_cnt--; | ||
| 1650 | |||
| 1651 | bond_sysfs_slave_del(slave); | 1667 | bond_sysfs_slave_del(slave); |
| 1652 | 1668 | ||
| 1653 | bond_upper_dev_unlink(bond_dev, slave_dev); | 1669 | bond_upper_dev_unlink(bond_dev, slave_dev); |
| @@ -1672,7 +1688,8 @@ static int __bond_release_one(struct net_device *bond_dev, | |||
| 1672 | 1688 | ||
| 1673 | bond->current_arp_slave = NULL; | 1689 | bond->current_arp_slave = NULL; |
| 1674 | 1690 | ||
| 1675 | if (!all && !bond->params.fail_over_mac) { | 1691 | if (!all && (!bond->params.fail_over_mac || |
| 1692 | bond->params.mode != BOND_MODE_ACTIVEBACKUP)) { | ||
| 1676 | if (ether_addr_equal_64bits(bond_dev->dev_addr, slave->perm_hwaddr) && | 1693 | if (ether_addr_equal_64bits(bond_dev->dev_addr, slave->perm_hwaddr) && |
| 1677 | bond_has_slaves(bond)) | 1694 | bond_has_slaves(bond)) |
| 1678 | pr_warn("%s: Warning: the permanent HWaddr of %s - %pM - is still in use by %s. Set the HWaddr of %s to a different address to avoid conflicts.\n", | 1695 | pr_warn("%s: Warning: the permanent HWaddr of %s - %pM - is still in use by %s. Set the HWaddr of %s to a different address to avoid conflicts.\n", |
| @@ -1728,6 +1745,7 @@ static int __bond_release_one(struct net_device *bond_dev, | |||
| 1728 | 1745 | ||
| 1729 | unblock_netpoll_tx(); | 1746 | unblock_netpoll_tx(); |
| 1730 | synchronize_rcu(); | 1747 | synchronize_rcu(); |
| 1748 | bond->slave_cnt--; | ||
| 1731 | 1749 | ||
| 1732 | if (!bond_has_slaves(bond)) { | 1750 | if (!bond_has_slaves(bond)) { |
| 1733 | call_netdevice_notifiers(NETDEV_CHANGEADDR, bond->dev); | 1751 | call_netdevice_notifiers(NETDEV_CHANGEADDR, bond->dev); |
| @@ -1769,7 +1787,8 @@ static int __bond_release_one(struct net_device *bond_dev, | |||
| 1769 | /* close slave before restoring its mac address */ | 1787 | /* close slave before restoring its mac address */ |
| 1770 | dev_close(slave_dev); | 1788 | dev_close(slave_dev); |
| 1771 | 1789 | ||
| 1772 | if (bond->params.fail_over_mac != BOND_FOM_ACTIVE) { | 1790 | if (bond->params.fail_over_mac != BOND_FOM_ACTIVE || |
| 1791 | bond->params.mode != BOND_MODE_ACTIVEBACKUP) { | ||
| 1773 | /* restore original ("permanent") mac address */ | 1792 | /* restore original ("permanent") mac address */ |
| 1774 | memcpy(addr.sa_data, slave->perm_hwaddr, ETH_ALEN); | 1793 | memcpy(addr.sa_data, slave->perm_hwaddr, ETH_ALEN); |
| 1775 | addr.sa_family = slave_dev->type; | 1794 | addr.sa_family = slave_dev->type; |
| @@ -2004,7 +2023,8 @@ static void bond_miimon_commit(struct bonding *bond) | |||
| 2004 | 2023 | ||
| 2005 | if (bond->params.mode == BOND_MODE_ACTIVEBACKUP || | 2024 | if (bond->params.mode == BOND_MODE_ACTIVEBACKUP || |
| 2006 | bond->params.mode == BOND_MODE_8023AD) | 2025 | bond->params.mode == BOND_MODE_8023AD) |
| 2007 | bond_set_slave_inactive_flags(slave); | 2026 | bond_set_slave_inactive_flags(slave, |
| 2027 | BOND_SLAVE_NOTIFY_NOW); | ||
| 2008 | 2028 | ||
| 2009 | pr_info("%s: link status definitely down for interface %s, disabling it\n", | 2029 | pr_info("%s: link status definitely down for interface %s, disabling it\n", |
| 2010 | bond->dev->name, slave->dev->name); | 2030 | bond->dev->name, slave->dev->name); |
| @@ -2551,7 +2571,8 @@ static void bond_ab_arp_commit(struct bonding *bond) | |||
| 2551 | slave->link = BOND_LINK_UP; | 2571 | slave->link = BOND_LINK_UP; |
| 2552 | if (bond->current_arp_slave) { | 2572 | if (bond->current_arp_slave) { |
| 2553 | bond_set_slave_inactive_flags( | 2573 | bond_set_slave_inactive_flags( |
| 2554 | bond->current_arp_slave); | 2574 | bond->current_arp_slave, |
| 2575 | BOND_SLAVE_NOTIFY_NOW); | ||
| 2555 | bond->current_arp_slave = NULL; | 2576 | bond->current_arp_slave = NULL; |
| 2556 | } | 2577 | } |
| 2557 | 2578 | ||
| @@ -2571,7 +2592,8 @@ static void bond_ab_arp_commit(struct bonding *bond) | |||
| 2571 | slave->link_failure_count++; | 2592 | slave->link_failure_count++; |
| 2572 | 2593 | ||
| 2573 | slave->link = BOND_LINK_DOWN; | 2594 | slave->link = BOND_LINK_DOWN; |
| 2574 | bond_set_slave_inactive_flags(slave); | 2595 | bond_set_slave_inactive_flags(slave, |
| 2596 | BOND_SLAVE_NOTIFY_NOW); | ||
| 2575 | 2597 | ||
| 2576 | pr_info("%s: link status definitely down for interface %s, disabling it\n", | 2598 | pr_info("%s: link status definitely down for interface %s, disabling it\n", |
| 2577 | bond->dev->name, slave->dev->name); | 2599 | bond->dev->name, slave->dev->name); |
| @@ -2604,17 +2626,17 @@ do_failover: | |||
| 2604 | 2626 | ||
| 2605 | /* | 2627 | /* |
| 2606 | * Send ARP probes for active-backup mode ARP monitor. | 2628 | * Send ARP probes for active-backup mode ARP monitor. |
| 2629 | * | ||
| 2630 | * Called with rcu_read_lock hold. | ||
| 2607 | */ | 2631 | */ |
| 2608 | static bool bond_ab_arp_probe(struct bonding *bond) | 2632 | static bool bond_ab_arp_probe(struct bonding *bond) |
| 2609 | { | 2633 | { |
| 2610 | struct slave *slave, *before = NULL, *new_slave = NULL, | 2634 | struct slave *slave, *before = NULL, *new_slave = NULL, |
| 2611 | *curr_arp_slave, *curr_active_slave; | 2635 | *curr_arp_slave = rcu_dereference(bond->current_arp_slave), |
| 2636 | *curr_active_slave = rcu_dereference(bond->curr_active_slave); | ||
| 2612 | struct list_head *iter; | 2637 | struct list_head *iter; |
| 2613 | bool found = false; | 2638 | bool found = false; |
| 2614 | 2639 | bool should_notify_rtnl = BOND_SLAVE_NOTIFY_LATER; | |
| 2615 | rcu_read_lock(); | ||
| 2616 | curr_arp_slave = rcu_dereference(bond->current_arp_slave); | ||
| 2617 | curr_active_slave = rcu_dereference(bond->curr_active_slave); | ||
| 2618 | 2640 | ||
| 2619 | if (curr_arp_slave && curr_active_slave) | 2641 | if (curr_arp_slave && curr_active_slave) |
| 2620 | pr_info("PROBE: c_arp %s && cas %s BAD\n", | 2642 | pr_info("PROBE: c_arp %s && cas %s BAD\n", |
| @@ -2623,32 +2645,23 @@ static bool bond_ab_arp_probe(struct bonding *bond) | |||
| 2623 | 2645 | ||
| 2624 | if (curr_active_slave) { | 2646 | if (curr_active_slave) { |
| 2625 | bond_arp_send_all(bond, curr_active_slave); | 2647 | bond_arp_send_all(bond, curr_active_slave); |
| 2626 | rcu_read_unlock(); | 2648 | return should_notify_rtnl; |
| 2627 | return true; | ||
| 2628 | } | 2649 | } |
| 2629 | rcu_read_unlock(); | ||
| 2630 | 2650 | ||
| 2631 | /* if we don't have a curr_active_slave, search for the next available | 2651 | /* if we don't have a curr_active_slave, search for the next available |
| 2632 | * backup slave from the current_arp_slave and make it the candidate | 2652 | * backup slave from the current_arp_slave and make it the candidate |
| 2633 | * for becoming the curr_active_slave | 2653 | * for becoming the curr_active_slave |
| 2634 | */ | 2654 | */ |
| 2635 | 2655 | ||
| 2636 | if (!rtnl_trylock()) | ||
| 2637 | return false; | ||
| 2638 | /* curr_arp_slave might have gone away */ | ||
| 2639 | curr_arp_slave = ACCESS_ONCE(bond->current_arp_slave); | ||
| 2640 | |||
| 2641 | if (!curr_arp_slave) { | 2656 | if (!curr_arp_slave) { |
| 2642 | curr_arp_slave = bond_first_slave(bond); | 2657 | curr_arp_slave = bond_first_slave_rcu(bond); |
| 2643 | if (!curr_arp_slave) { | 2658 | if (!curr_arp_slave) |
| 2644 | rtnl_unlock(); | 2659 | return should_notify_rtnl; |
| 2645 | return true; | ||
| 2646 | } | ||
| 2647 | } | 2660 | } |
| 2648 | 2661 | ||
| 2649 | bond_set_slave_inactive_flags(curr_arp_slave); | 2662 | bond_set_slave_inactive_flags(curr_arp_slave, BOND_SLAVE_NOTIFY_LATER); |
| 2650 | 2663 | ||
| 2651 | bond_for_each_slave(bond, slave, iter) { | 2664 | bond_for_each_slave_rcu(bond, slave, iter) { |
| 2652 | if (!found && !before && IS_UP(slave->dev)) | 2665 | if (!found && !before && IS_UP(slave->dev)) |
| 2653 | before = slave; | 2666 | before = slave; |
| 2654 | 2667 | ||
| @@ -2666,7 +2679,8 @@ static bool bond_ab_arp_probe(struct bonding *bond) | |||
| 2666 | if (slave->link_failure_count < UINT_MAX) | 2679 | if (slave->link_failure_count < UINT_MAX) |
| 2667 | slave->link_failure_count++; | 2680 | slave->link_failure_count++; |
| 2668 | 2681 | ||
| 2669 | bond_set_slave_inactive_flags(slave); | 2682 | bond_set_slave_inactive_flags(slave, |
| 2683 | BOND_SLAVE_NOTIFY_LATER); | ||
| 2670 | 2684 | ||
| 2671 | pr_info("%s: backup interface %s is now down.\n", | 2685 | pr_info("%s: backup interface %s is now down.\n", |
| 2672 | bond->dev->name, slave->dev->name); | 2686 | bond->dev->name, slave->dev->name); |
| @@ -2678,26 +2692,31 @@ static bool bond_ab_arp_probe(struct bonding *bond) | |||
| 2678 | if (!new_slave && before) | 2692 | if (!new_slave && before) |
| 2679 | new_slave = before; | 2693 | new_slave = before; |
| 2680 | 2694 | ||
| 2681 | if (!new_slave) { | 2695 | if (!new_slave) |
| 2682 | rtnl_unlock(); | 2696 | goto check_state; |
| 2683 | return true; | ||
| 2684 | } | ||
| 2685 | 2697 | ||
| 2686 | new_slave->link = BOND_LINK_BACK; | 2698 | new_slave->link = BOND_LINK_BACK; |
| 2687 | bond_set_slave_active_flags(new_slave); | 2699 | bond_set_slave_active_flags(new_slave, BOND_SLAVE_NOTIFY_LATER); |
| 2688 | bond_arp_send_all(bond, new_slave); | 2700 | bond_arp_send_all(bond, new_slave); |
| 2689 | new_slave->jiffies = jiffies; | 2701 | new_slave->jiffies = jiffies; |
| 2690 | rcu_assign_pointer(bond->current_arp_slave, new_slave); | 2702 | rcu_assign_pointer(bond->current_arp_slave, new_slave); |
| 2691 | rtnl_unlock(); | ||
| 2692 | 2703 | ||
| 2693 | return true; | 2704 | check_state: |
| 2705 | bond_for_each_slave_rcu(bond, slave, iter) { | ||
| 2706 | if (slave->should_notify) { | ||
| 2707 | should_notify_rtnl = BOND_SLAVE_NOTIFY_NOW; | ||
| 2708 | break; | ||
| 2709 | } | ||
| 2710 | } | ||
| 2711 | return should_notify_rtnl; | ||
| 2694 | } | 2712 | } |
| 2695 | 2713 | ||
| 2696 | static void bond_activebackup_arp_mon(struct work_struct *work) | 2714 | static void bond_activebackup_arp_mon(struct work_struct *work) |
| 2697 | { | 2715 | { |
| 2698 | struct bonding *bond = container_of(work, struct bonding, | 2716 | struct bonding *bond = container_of(work, struct bonding, |
| 2699 | arp_work.work); | 2717 | arp_work.work); |
| 2700 | bool should_notify_peers = false, should_commit = false; | 2718 | bool should_notify_peers = false; |
| 2719 | bool should_notify_rtnl = false; | ||
| 2701 | int delta_in_ticks; | 2720 | int delta_in_ticks; |
| 2702 | 2721 | ||
| 2703 | delta_in_ticks = msecs_to_jiffies(bond->params.arp_interval); | 2722 | delta_in_ticks = msecs_to_jiffies(bond->params.arp_interval); |
| @@ -2706,11 +2725,12 @@ static void bond_activebackup_arp_mon(struct work_struct *work) | |||
| 2706 | goto re_arm; | 2725 | goto re_arm; |
| 2707 | 2726 | ||
| 2708 | rcu_read_lock(); | 2727 | rcu_read_lock(); |
| 2728 | |||
| 2709 | should_notify_peers = bond_should_notify_peers(bond); | 2729 | should_notify_peers = bond_should_notify_peers(bond); |
| 2710 | should_commit = bond_ab_arp_inspect(bond); | ||
| 2711 | rcu_read_unlock(); | ||
| 2712 | 2730 | ||
| 2713 | if (should_commit) { | 2731 | if (bond_ab_arp_inspect(bond)) { |
| 2732 | rcu_read_unlock(); | ||
| 2733 | |||
| 2714 | /* Race avoidance with bond_close flush of workqueue */ | 2734 | /* Race avoidance with bond_close flush of workqueue */ |
| 2715 | if (!rtnl_trylock()) { | 2735 | if (!rtnl_trylock()) { |
| 2716 | delta_in_ticks = 1; | 2736 | delta_in_ticks = 1; |
| @@ -2719,23 +2739,28 @@ static void bond_activebackup_arp_mon(struct work_struct *work) | |||
| 2719 | } | 2739 | } |
| 2720 | 2740 | ||
| 2721 | bond_ab_arp_commit(bond); | 2741 | bond_ab_arp_commit(bond); |
| 2742 | |||
| 2722 | rtnl_unlock(); | 2743 | rtnl_unlock(); |
| 2744 | rcu_read_lock(); | ||
| 2723 | } | 2745 | } |
| 2724 | 2746 | ||
| 2725 | if (!bond_ab_arp_probe(bond)) { | 2747 | should_notify_rtnl = bond_ab_arp_probe(bond); |
| 2726 | /* rtnl locking failed, re-arm */ | 2748 | rcu_read_unlock(); |
| 2727 | delta_in_ticks = 1; | ||
| 2728 | should_notify_peers = false; | ||
| 2729 | } | ||
| 2730 | 2749 | ||
| 2731 | re_arm: | 2750 | re_arm: |
| 2732 | if (bond->params.arp_interval) | 2751 | if (bond->params.arp_interval) |
| 2733 | queue_delayed_work(bond->wq, &bond->arp_work, delta_in_ticks); | 2752 | queue_delayed_work(bond->wq, &bond->arp_work, delta_in_ticks); |
| 2734 | 2753 | ||
| 2735 | if (should_notify_peers) { | 2754 | if (should_notify_peers || should_notify_rtnl) { |
| 2736 | if (!rtnl_trylock()) | 2755 | if (!rtnl_trylock()) |
| 2737 | return; | 2756 | return; |
| 2738 | call_netdevice_notifiers(NETDEV_NOTIFY_PEERS, bond->dev); | 2757 | |
| 2758 | if (should_notify_peers) | ||
| 2759 | call_netdevice_notifiers(NETDEV_NOTIFY_PEERS, | ||
| 2760 | bond->dev); | ||
| 2761 | if (should_notify_rtnl) | ||
| 2762 | bond_slave_state_notify(bond); | ||
| 2763 | |||
| 2739 | rtnl_unlock(); | 2764 | rtnl_unlock(); |
| 2740 | } | 2765 | } |
| 2741 | } | 2766 | } |
| @@ -2857,9 +2882,12 @@ static int bond_slave_netdev_event(unsigned long event, | |||
| 2857 | pr_info("%s: Primary slave changed to %s, reselecting active slave.\n", | 2882 | pr_info("%s: Primary slave changed to %s, reselecting active slave.\n", |
| 2858 | bond->dev->name, bond->primary_slave ? slave_dev->name : | 2883 | bond->dev->name, bond->primary_slave ? slave_dev->name : |
| 2859 | "none"); | 2884 | "none"); |
| 2885 | |||
| 2886 | block_netpoll_tx(); | ||
| 2860 | write_lock_bh(&bond->curr_slave_lock); | 2887 | write_lock_bh(&bond->curr_slave_lock); |
| 2861 | bond_select_active_slave(bond); | 2888 | bond_select_active_slave(bond); |
| 2862 | write_unlock_bh(&bond->curr_slave_lock); | 2889 | write_unlock_bh(&bond->curr_slave_lock); |
| 2890 | unblock_netpoll_tx(); | ||
| 2863 | break; | 2891 | break; |
| 2864 | case NETDEV_FEAT_CHANGE: | 2892 | case NETDEV_FEAT_CHANGE: |
| 2865 | bond_compute_features(bond); | 2893 | bond_compute_features(bond); |
| @@ -3032,9 +3060,11 @@ static int bond_open(struct net_device *bond_dev) | |||
| 3032 | bond_for_each_slave(bond, slave, iter) { | 3060 | bond_for_each_slave(bond, slave, iter) { |
| 3033 | if ((bond->params.mode == BOND_MODE_ACTIVEBACKUP) | 3061 | if ((bond->params.mode == BOND_MODE_ACTIVEBACKUP) |
| 3034 | && (slave != bond->curr_active_slave)) { | 3062 | && (slave != bond->curr_active_slave)) { |
| 3035 | bond_set_slave_inactive_flags(slave); | 3063 | bond_set_slave_inactive_flags(slave, |
| 3064 | BOND_SLAVE_NOTIFY_NOW); | ||
| 3036 | } else { | 3065 | } else { |
| 3037 | bond_set_slave_active_flags(slave); | 3066 | bond_set_slave_active_flags(slave, |
| 3067 | BOND_SLAVE_NOTIFY_NOW); | ||
| 3038 | } | 3068 | } |
| 3039 | } | 3069 | } |
| 3040 | read_unlock(&bond->curr_slave_lock); | 3070 | read_unlock(&bond->curr_slave_lock); |
| @@ -3431,7 +3461,8 @@ static int bond_set_mac_address(struct net_device *bond_dev, void *addr) | |||
| 3431 | /* If fail_over_mac is enabled, do nothing and return success. | 3461 | /* If fail_over_mac is enabled, do nothing and return success. |
| 3432 | * Returning an error causes ifenslave to fail. | 3462 | * Returning an error causes ifenslave to fail. |
| 3433 | */ | 3463 | */ |
| 3434 | if (bond->params.fail_over_mac) | 3464 | if (bond->params.fail_over_mac && |
| 3465 | bond->params.mode == BOND_MODE_ACTIVEBACKUP) | ||
| 3435 | return 0; | 3466 | return 0; |
| 3436 | 3467 | ||
| 3437 | if (!is_valid_ether_addr(sa->sa_data)) | 3468 | if (!is_valid_ether_addr(sa->sa_data)) |
| @@ -3692,7 +3723,7 @@ static inline int bond_slave_override(struct bonding *bond, | |||
| 3692 | 3723 | ||
| 3693 | 3724 | ||
| 3694 | static u16 bond_select_queue(struct net_device *dev, struct sk_buff *skb, | 3725 | static u16 bond_select_queue(struct net_device *dev, struct sk_buff *skb, |
| 3695 | void *accel_priv) | 3726 | void *accel_priv, select_queue_fallback_t fallback) |
| 3696 | { | 3727 | { |
| 3697 | /* | 3728 | /* |
| 3698 | * This helper function exists to help dev_pick_tx get the correct | 3729 | * This helper function exists to help dev_pick_tx get the correct |
diff --git a/drivers/net/bonding/bond_options.c b/drivers/net/bonding/bond_options.c index 11cb943222d5..c37878432717 100644 --- a/drivers/net/bonding/bond_options.c +++ b/drivers/net/bonding/bond_options.c | |||
| @@ -14,7 +14,7 @@ | |||
| 14 | #include <linux/errno.h> | 14 | #include <linux/errno.h> |
| 15 | #include <linux/if.h> | 15 | #include <linux/if.h> |
| 16 | #include <linux/netdevice.h> | 16 | #include <linux/netdevice.h> |
| 17 | #include <linux/rwlock.h> | 17 | #include <linux/spinlock.h> |
| 18 | #include <linux/rcupdate.h> | 18 | #include <linux/rcupdate.h> |
| 19 | #include <linux/ctype.h> | 19 | #include <linux/ctype.h> |
| 20 | #include <linux/inet.h> | 20 | #include <linux/inet.h> |
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h index 86ccfb9f71cc..2b0fdec695f7 100644 --- a/drivers/net/bonding/bonding.h +++ b/drivers/net/bonding/bonding.h | |||
| @@ -195,7 +195,8 @@ struct slave { | |||
| 195 | s8 new_link; | 195 | s8 new_link; |
| 196 | u8 backup:1, /* indicates backup slave. Value corresponds with | 196 | u8 backup:1, /* indicates backup slave. Value corresponds with |
| 197 | BOND_STATE_ACTIVE and BOND_STATE_BACKUP */ | 197 | BOND_STATE_ACTIVE and BOND_STATE_BACKUP */ |
| 198 | inactive:1; /* indicates inactive slave */ | 198 | inactive:1, /* indicates inactive slave */ |
| 199 | should_notify:1; /* indicateds whether the state changed */ | ||
| 199 | u8 duplex; | 200 | u8 duplex; |
| 200 | u32 original_mtu; | 201 | u32 original_mtu; |
| 201 | u32 link_failure_count; | 202 | u32 link_failure_count; |
| @@ -303,6 +304,24 @@ static inline void bond_set_backup_slave(struct slave *slave) | |||
| 303 | } | 304 | } |
| 304 | } | 305 | } |
| 305 | 306 | ||
| 307 | static inline void bond_set_slave_state(struct slave *slave, | ||
| 308 | int slave_state, bool notify) | ||
| 309 | { | ||
| 310 | if (slave->backup == slave_state) | ||
| 311 | return; | ||
| 312 | |||
| 313 | slave->backup = slave_state; | ||
| 314 | if (notify) { | ||
| 315 | rtmsg_ifinfo(RTM_NEWLINK, slave->dev, 0, GFP_KERNEL); | ||
| 316 | slave->should_notify = 0; | ||
| 317 | } else { | ||
| 318 | if (slave->should_notify) | ||
| 319 | slave->should_notify = 0; | ||
| 320 | else | ||
| 321 | slave->should_notify = 1; | ||
| 322 | } | ||
| 323 | } | ||
| 324 | |||
| 306 | static inline void bond_slave_state_change(struct bonding *bond) | 325 | static inline void bond_slave_state_change(struct bonding *bond) |
| 307 | { | 326 | { |
| 308 | struct list_head *iter; | 327 | struct list_head *iter; |
| @@ -316,6 +335,19 @@ static inline void bond_slave_state_change(struct bonding *bond) | |||
| 316 | } | 335 | } |
| 317 | } | 336 | } |
| 318 | 337 | ||
| 338 | static inline void bond_slave_state_notify(struct bonding *bond) | ||
| 339 | { | ||
| 340 | struct list_head *iter; | ||
| 341 | struct slave *tmp; | ||
| 342 | |||
| 343 | bond_for_each_slave(bond, tmp, iter) { | ||
| 344 | if (tmp->should_notify) { | ||
| 345 | rtmsg_ifinfo(RTM_NEWLINK, tmp->dev, 0, GFP_KERNEL); | ||
| 346 | tmp->should_notify = 0; | ||
| 347 | } | ||
| 348 | } | ||
| 349 | } | ||
| 350 | |||
| 319 | static inline int bond_slave_state(struct slave *slave) | 351 | static inline int bond_slave_state(struct slave *slave) |
| 320 | { | 352 | { |
| 321 | return slave->backup; | 353 | return slave->backup; |
| @@ -343,6 +375,9 @@ static inline bool bond_is_active_slave(struct slave *slave) | |||
| 343 | #define BOND_ARP_VALIDATE_ALL (BOND_ARP_VALIDATE_ACTIVE | \ | 375 | #define BOND_ARP_VALIDATE_ALL (BOND_ARP_VALIDATE_ACTIVE | \ |
| 344 | BOND_ARP_VALIDATE_BACKUP) | 376 | BOND_ARP_VALIDATE_BACKUP) |
| 345 | 377 | ||
| 378 | #define BOND_SLAVE_NOTIFY_NOW true | ||
| 379 | #define BOND_SLAVE_NOTIFY_LATER false | ||
| 380 | |||
| 346 | static inline int slave_do_arp_validate(struct bonding *bond, | 381 | static inline int slave_do_arp_validate(struct bonding *bond, |
| 347 | struct slave *slave) | 382 | struct slave *slave) |
| 348 | { | 383 | { |
| @@ -394,17 +429,19 @@ static inline void bond_netpoll_send_skb(const struct slave *slave, | |||
| 394 | } | 429 | } |
| 395 | #endif | 430 | #endif |
| 396 | 431 | ||
| 397 | static inline void bond_set_slave_inactive_flags(struct slave *slave) | 432 | static inline void bond_set_slave_inactive_flags(struct slave *slave, |
| 433 | bool notify) | ||
| 398 | { | 434 | { |
| 399 | if (!bond_is_lb(slave->bond)) | 435 | if (!bond_is_lb(slave->bond)) |
| 400 | bond_set_backup_slave(slave); | 436 | bond_set_slave_state(slave, BOND_STATE_BACKUP, notify); |
| 401 | if (!slave->bond->params.all_slaves_active) | 437 | if (!slave->bond->params.all_slaves_active) |
| 402 | slave->inactive = 1; | 438 | slave->inactive = 1; |
| 403 | } | 439 | } |
| 404 | 440 | ||
| 405 | static inline void bond_set_slave_active_flags(struct slave *slave) | 441 | static inline void bond_set_slave_active_flags(struct slave *slave, |
| 442 | bool notify) | ||
| 406 | { | 443 | { |
| 407 | bond_set_active_slave(slave); | 444 | bond_set_slave_state(slave, BOND_STATE_ACTIVE, notify); |
| 408 | slave->inactive = 0; | 445 | slave->inactive = 0; |
| 409 | } | 446 | } |
| 410 | 447 | ||
diff --git a/drivers/net/can/Kconfig b/drivers/net/can/Kconfig index d447b881bbde..9e7d95dae2c7 100644 --- a/drivers/net/can/Kconfig +++ b/drivers/net/can/Kconfig | |||
| @@ -104,7 +104,7 @@ config CAN_JANZ_ICAN3 | |||
| 104 | 104 | ||
| 105 | config CAN_FLEXCAN | 105 | config CAN_FLEXCAN |
| 106 | tristate "Support for Freescale FLEXCAN based chips" | 106 | tristate "Support for Freescale FLEXCAN based chips" |
| 107 | depends on (ARM && CPU_LITTLE_ENDIAN) || PPC | 107 | depends on ARM || PPC |
| 108 | ---help--- | 108 | ---help--- |
| 109 | Say Y here if you want to support for Freescale FlexCAN. | 109 | Say Y here if you want to support for Freescale FlexCAN. |
| 110 | 110 | ||
diff --git a/drivers/net/can/dev.c b/drivers/net/can/dev.c index 13a909822e25..fc59bc6f040b 100644 --- a/drivers/net/can/dev.c +++ b/drivers/net/can/dev.c | |||
| @@ -323,19 +323,10 @@ void can_put_echo_skb(struct sk_buff *skb, struct net_device *dev, | |||
| 323 | } | 323 | } |
| 324 | 324 | ||
| 325 | if (!priv->echo_skb[idx]) { | 325 | if (!priv->echo_skb[idx]) { |
| 326 | struct sock *srcsk = skb->sk; | ||
| 327 | 326 | ||
| 328 | if (atomic_read(&skb->users) != 1) { | 327 | skb = can_create_echo_skb(skb); |
| 329 | struct sk_buff *old_skb = skb; | 328 | if (!skb) |
| 330 | 329 | return; | |
| 331 | skb = skb_clone(old_skb, GFP_ATOMIC); | ||
| 332 | kfree_skb(old_skb); | ||
| 333 | if (!skb) | ||
| 334 | return; | ||
| 335 | } else | ||
| 336 | skb_orphan(skb); | ||
| 337 | |||
| 338 | skb->sk = srcsk; | ||
| 339 | 330 | ||
| 340 | /* make settings for echo to reduce code in irq context */ | 331 | /* make settings for echo to reduce code in irq context */ |
| 341 | skb->protocol = htons(ETH_P_CAN); | 332 | skb->protocol = htons(ETH_P_CAN); |
diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c index aaed97bee471..61376abdab39 100644 --- a/drivers/net/can/flexcan.c +++ b/drivers/net/can/flexcan.c | |||
| @@ -144,6 +144,8 @@ | |||
| 144 | 144 | ||
| 145 | #define FLEXCAN_MB_CODE_MASK (0xf0ffffff) | 145 | #define FLEXCAN_MB_CODE_MASK (0xf0ffffff) |
| 146 | 146 | ||
| 147 | #define FLEXCAN_TIMEOUT_US (50) | ||
| 148 | |||
| 147 | /* | 149 | /* |
| 148 | * FLEXCAN hardware feature flags | 150 | * FLEXCAN hardware feature flags |
| 149 | * | 151 | * |
| @@ -235,9 +237,12 @@ static const struct can_bittiming_const flexcan_bittiming_const = { | |||
| 235 | }; | 237 | }; |
| 236 | 238 | ||
| 237 | /* | 239 | /* |
| 238 | * Abstract off the read/write for arm versus ppc. | 240 | * Abstract off the read/write for arm versus ppc. This |
| 241 | * assumes that PPC uses big-endian registers and everything | ||
| 242 | * else uses little-endian registers, independent of CPU | ||
| 243 | * endianess. | ||
| 239 | */ | 244 | */ |
| 240 | #if defined(__BIG_ENDIAN) | 245 | #if defined(CONFIG_PPC) |
| 241 | static inline u32 flexcan_read(void __iomem *addr) | 246 | static inline u32 flexcan_read(void __iomem *addr) |
| 242 | { | 247 | { |
| 243 | return in_be32(addr); | 248 | return in_be32(addr); |
| @@ -259,6 +264,22 @@ static inline void flexcan_write(u32 val, void __iomem *addr) | |||
| 259 | } | 264 | } |
| 260 | #endif | 265 | #endif |
| 261 | 266 | ||
| 267 | static inline int flexcan_transceiver_enable(const struct flexcan_priv *priv) | ||
| 268 | { | ||
| 269 | if (!priv->reg_xceiver) | ||
| 270 | return 0; | ||
| 271 | |||
| 272 | return regulator_enable(priv->reg_xceiver); | ||
| 273 | } | ||
| 274 | |||
| 275 | static inline int flexcan_transceiver_disable(const struct flexcan_priv *priv) | ||
| 276 | { | ||
| 277 | if (!priv->reg_xceiver) | ||
| 278 | return 0; | ||
| 279 | |||
| 280 | return regulator_disable(priv->reg_xceiver); | ||
| 281 | } | ||
| 282 | |||
| 262 | static inline int flexcan_has_and_handle_berr(const struct flexcan_priv *priv, | 283 | static inline int flexcan_has_and_handle_berr(const struct flexcan_priv *priv, |
| 263 | u32 reg_esr) | 284 | u32 reg_esr) |
| 264 | { | 285 | { |
| @@ -266,26 +287,95 @@ static inline int flexcan_has_and_handle_berr(const struct flexcan_priv *priv, | |||
| 266 | (reg_esr & FLEXCAN_ESR_ERR_BUS); | 287 | (reg_esr & FLEXCAN_ESR_ERR_BUS); |
| 267 | } | 288 | } |
| 268 | 289 | ||
| 269 | static inline void flexcan_chip_enable(struct flexcan_priv *priv) | 290 | static int flexcan_chip_enable(struct flexcan_priv *priv) |
| 270 | { | 291 | { |
| 271 | struct flexcan_regs __iomem *regs = priv->base; | 292 | struct flexcan_regs __iomem *regs = priv->base; |
| 293 | unsigned int timeout = FLEXCAN_TIMEOUT_US / 10; | ||
| 272 | u32 reg; | 294 | u32 reg; |
| 273 | 295 | ||
| 274 | reg = flexcan_read(®s->mcr); | 296 | reg = flexcan_read(®s->mcr); |
| 275 | reg &= ~FLEXCAN_MCR_MDIS; | 297 | reg &= ~FLEXCAN_MCR_MDIS; |
| 276 | flexcan_write(reg, ®s->mcr); | 298 | flexcan_write(reg, ®s->mcr); |
| 277 | 299 | ||
| 278 | udelay(10); | 300 | while (timeout-- && (flexcan_read(®s->mcr) & FLEXCAN_MCR_LPM_ACK)) |
| 301 | usleep_range(10, 20); | ||
| 302 | |||
| 303 | if (flexcan_read(®s->mcr) & FLEXCAN_MCR_LPM_ACK) | ||
| 304 | return -ETIMEDOUT; | ||
| 305 | |||
| 306 | return 0; | ||
| 279 | } | 307 | } |
| 280 | 308 | ||
| 281 | static inline void flexcan_chip_disable(struct flexcan_priv *priv) | 309 | static int flexcan_chip_disable(struct flexcan_priv *priv) |
| 282 | { | 310 | { |
| 283 | struct flexcan_regs __iomem *regs = priv->base; | 311 | struct flexcan_regs __iomem *regs = priv->base; |
| 312 | unsigned int timeout = FLEXCAN_TIMEOUT_US / 10; | ||
| 284 | u32 reg; | 313 | u32 reg; |
| 285 | 314 | ||
| 286 | reg = flexcan_read(®s->mcr); | 315 | reg = flexcan_read(®s->mcr); |
| 287 | reg |= FLEXCAN_MCR_MDIS; | 316 | reg |= FLEXCAN_MCR_MDIS; |
| 288 | flexcan_write(reg, ®s->mcr); | 317 | flexcan_write(reg, ®s->mcr); |
| 318 | |||
| 319 | while (timeout-- && !(flexcan_read(®s->mcr) & FLEXCAN_MCR_LPM_ACK)) | ||
| 320 | usleep_range(10, 20); | ||
| 321 | |||
| 322 | if (!(flexcan_read(®s->mcr) & FLEXCAN_MCR_LPM_ACK)) | ||
| 323 | return -ETIMEDOUT; | ||
| 324 | |||
| 325 | return 0; | ||
| 326 | } | ||
| 327 | |||
| 328 | static int flexcan_chip_freeze(struct flexcan_priv *priv) | ||
| 329 | { | ||
| 330 | struct flexcan_regs __iomem *regs = priv->base; | ||
| 331 | unsigned int timeout = 1000 * 1000 * 10 / priv->can.bittiming.bitrate; | ||
| 332 | u32 reg; | ||
| 333 | |||
| 334 | reg = flexcan_read(®s->mcr); | ||
| 335 | reg |= FLEXCAN_MCR_HALT; | ||
| 336 | flexcan_write(reg, ®s->mcr); | ||
| 337 | |||
| 338 | while (timeout-- && !(flexcan_read(®s->mcr) & FLEXCAN_MCR_FRZ_ACK)) | ||
| 339 | usleep_range(100, 200); | ||
| 340 | |||
| 341 | if (!(flexcan_read(®s->mcr) & FLEXCAN_MCR_FRZ_ACK)) | ||
| 342 | return -ETIMEDOUT; | ||
| 343 | |||
| 344 | return 0; | ||
| 345 | } | ||
| 346 | |||
| 347 | static int flexcan_chip_unfreeze(struct flexcan_priv *priv) | ||
| 348 | { | ||
| 349 | struct flexcan_regs __iomem *regs = priv->base; | ||
| 350 | unsigned int timeout = FLEXCAN_TIMEOUT_US / 10; | ||
| 351 | u32 reg; | ||
| 352 | |||
| 353 | reg = flexcan_read(®s->mcr); | ||
| 354 | reg &= ~FLEXCAN_MCR_HALT; | ||
| 355 | flexcan_write(reg, ®s->mcr); | ||
| 356 | |||
| 357 | while (timeout-- && (flexcan_read(®s->mcr) & FLEXCAN_MCR_FRZ_ACK)) | ||
| 358 | usleep_range(10, 20); | ||
| 359 | |||
| 360 | if (flexcan_read(®s->mcr) & FLEXCAN_MCR_FRZ_ACK) | ||
| 361 | return -ETIMEDOUT; | ||
| 362 | |||
| 363 | return 0; | ||
| 364 | } | ||
| 365 | |||
| 366 | static int flexcan_chip_softreset(struct flexcan_priv *priv) | ||
| 367 | { | ||
| 368 | struct flexcan_regs __iomem *regs = priv->base; | ||
| 369 | unsigned int timeout = FLEXCAN_TIMEOUT_US / 10; | ||
| 370 | |||
| 371 | flexcan_write(FLEXCAN_MCR_SOFTRST, ®s->mcr); | ||
| 372 | while (timeout-- && (flexcan_read(®s->mcr) & FLEXCAN_MCR_SOFTRST)) | ||
| 373 | usleep_range(10, 20); | ||
| 374 | |||
| 375 | if (flexcan_read(®s->mcr) & FLEXCAN_MCR_SOFTRST) | ||
| 376 | return -ETIMEDOUT; | ||
| 377 | |||
| 378 | return 0; | ||
| 289 | } | 379 | } |
| 290 | 380 | ||
| 291 | static int flexcan_get_berr_counter(const struct net_device *dev, | 381 | static int flexcan_get_berr_counter(const struct net_device *dev, |
| @@ -706,19 +796,14 @@ static int flexcan_chip_start(struct net_device *dev) | |||
| 706 | u32 reg_mcr, reg_ctrl; | 796 | u32 reg_mcr, reg_ctrl; |
| 707 | 797 | ||
| 708 | /* enable module */ | 798 | /* enable module */ |
| 709 | flexcan_chip_enable(priv); | 799 | err = flexcan_chip_enable(priv); |
| 800 | if (err) | ||
| 801 | return err; | ||
| 710 | 802 | ||
| 711 | /* soft reset */ | 803 | /* soft reset */ |
| 712 | flexcan_write(FLEXCAN_MCR_SOFTRST, ®s->mcr); | 804 | err = flexcan_chip_softreset(priv); |
| 713 | udelay(10); | 805 | if (err) |
| 714 | 806 | goto out_chip_disable; | |
| 715 | reg_mcr = flexcan_read(®s->mcr); | ||
| 716 | if (reg_mcr & FLEXCAN_MCR_SOFTRST) { | ||
| 717 | netdev_err(dev, "Failed to softreset can module (mcr=0x%08x)\n", | ||
| 718 | reg_mcr); | ||
| 719 | err = -ENODEV; | ||
| 720 | goto out; | ||
| 721 | } | ||
| 722 | 807 | ||
| 723 | flexcan_set_bittiming(dev); | 808 | flexcan_set_bittiming(dev); |
| 724 | 809 | ||
| @@ -785,16 +870,14 @@ static int flexcan_chip_start(struct net_device *dev) | |||
| 785 | if (priv->devtype_data->features & FLEXCAN_HAS_V10_FEATURES) | 870 | if (priv->devtype_data->features & FLEXCAN_HAS_V10_FEATURES) |
| 786 | flexcan_write(0x0, ®s->rxfgmask); | 871 | flexcan_write(0x0, ®s->rxfgmask); |
| 787 | 872 | ||
| 788 | if (priv->reg_xceiver) { | 873 | err = flexcan_transceiver_enable(priv); |
| 789 | err = regulator_enable(priv->reg_xceiver); | 874 | if (err) |
| 790 | if (err) | 875 | goto out_chip_disable; |
| 791 | goto out; | ||
| 792 | } | ||
| 793 | 876 | ||
| 794 | /* synchronize with the can bus */ | 877 | /* synchronize with the can bus */ |
| 795 | reg_mcr = flexcan_read(®s->mcr); | 878 | err = flexcan_chip_unfreeze(priv); |
| 796 | reg_mcr &= ~FLEXCAN_MCR_HALT; | 879 | if (err) |
| 797 | flexcan_write(reg_mcr, ®s->mcr); | 880 | goto out_transceiver_disable; |
| 798 | 881 | ||
| 799 | priv->can.state = CAN_STATE_ERROR_ACTIVE; | 882 | priv->can.state = CAN_STATE_ERROR_ACTIVE; |
| 800 | 883 | ||
| @@ -807,7 +890,9 @@ static int flexcan_chip_start(struct net_device *dev) | |||
| 807 | 890 | ||
| 808 | return 0; | 891 | return 0; |
| 809 | 892 | ||
| 810 | out: | 893 | out_transceiver_disable: |
| 894 | flexcan_transceiver_disable(priv); | ||
| 895 | out_chip_disable: | ||
| 811 | flexcan_chip_disable(priv); | 896 | flexcan_chip_disable(priv); |
| 812 | return err; | 897 | return err; |
| 813 | } | 898 | } |
| @@ -822,18 +907,17 @@ static void flexcan_chip_stop(struct net_device *dev) | |||
| 822 | { | 907 | { |
| 823 | struct flexcan_priv *priv = netdev_priv(dev); | 908 | struct flexcan_priv *priv = netdev_priv(dev); |
| 824 | struct flexcan_regs __iomem *regs = priv->base; | 909 | struct flexcan_regs __iomem *regs = priv->base; |
| 825 | u32 reg; | 910 | |
| 911 | /* freeze + disable module */ | ||
| 912 | flexcan_chip_freeze(priv); | ||
| 913 | flexcan_chip_disable(priv); | ||
| 826 | 914 | ||
| 827 | /* Disable all interrupts */ | 915 | /* Disable all interrupts */ |
| 828 | flexcan_write(0, ®s->imask1); | 916 | flexcan_write(0, ®s->imask1); |
| 917 | flexcan_write(priv->reg_ctrl_default & ~FLEXCAN_CTRL_ERR_ALL, | ||
| 918 | ®s->ctrl); | ||
| 829 | 919 | ||
| 830 | /* Disable + halt module */ | 920 | flexcan_transceiver_disable(priv); |
| 831 | reg = flexcan_read(®s->mcr); | ||
| 832 | reg |= FLEXCAN_MCR_MDIS | FLEXCAN_MCR_HALT; | ||
| 833 | flexcan_write(reg, ®s->mcr); | ||
| 834 | |||
| 835 | if (priv->reg_xceiver) | ||
| 836 | regulator_disable(priv->reg_xceiver); | ||
| 837 | priv->can.state = CAN_STATE_STOPPED; | 921 | priv->can.state = CAN_STATE_STOPPED; |
| 838 | 922 | ||
| 839 | return; | 923 | return; |
| @@ -863,7 +947,7 @@ static int flexcan_open(struct net_device *dev) | |||
| 863 | /* start chip and queuing */ | 947 | /* start chip and queuing */ |
| 864 | err = flexcan_chip_start(dev); | 948 | err = flexcan_chip_start(dev); |
| 865 | if (err) | 949 | if (err) |
| 866 | goto out_close; | 950 | goto out_free_irq; |
| 867 | 951 | ||
| 868 | can_led_event(dev, CAN_LED_EVENT_OPEN); | 952 | can_led_event(dev, CAN_LED_EVENT_OPEN); |
| 869 | 953 | ||
| @@ -872,6 +956,8 @@ static int flexcan_open(struct net_device *dev) | |||
| 872 | 956 | ||
| 873 | return 0; | 957 | return 0; |
| 874 | 958 | ||
| 959 | out_free_irq: | ||
| 960 | free_irq(dev->irq, dev); | ||
| 875 | out_close: | 961 | out_close: |
| 876 | close_candev(dev); | 962 | close_candev(dev); |
| 877 | out_disable_per: | 963 | out_disable_per: |
| @@ -942,12 +1028,16 @@ static int register_flexcandev(struct net_device *dev) | |||
| 942 | goto out_disable_ipg; | 1028 | goto out_disable_ipg; |
| 943 | 1029 | ||
| 944 | /* select "bus clock", chip must be disabled */ | 1030 | /* select "bus clock", chip must be disabled */ |
| 945 | flexcan_chip_disable(priv); | 1031 | err = flexcan_chip_disable(priv); |
| 1032 | if (err) | ||
| 1033 | goto out_disable_per; | ||
| 946 | reg = flexcan_read(®s->ctrl); | 1034 | reg = flexcan_read(®s->ctrl); |
| 947 | reg |= FLEXCAN_CTRL_CLK_SRC; | 1035 | reg |= FLEXCAN_CTRL_CLK_SRC; |
| 948 | flexcan_write(reg, ®s->ctrl); | 1036 | flexcan_write(reg, ®s->ctrl); |
| 949 | 1037 | ||
| 950 | flexcan_chip_enable(priv); | 1038 | err = flexcan_chip_enable(priv); |
| 1039 | if (err) | ||
| 1040 | goto out_chip_disable; | ||
| 951 | 1041 | ||
| 952 | /* set freeze, halt and activate FIFO, restrict register access */ | 1042 | /* set freeze, halt and activate FIFO, restrict register access */ |
| 953 | reg = flexcan_read(®s->mcr); | 1043 | reg = flexcan_read(®s->mcr); |
| @@ -964,14 +1054,15 @@ static int register_flexcandev(struct net_device *dev) | |||
| 964 | if (!(reg & FLEXCAN_MCR_FEN)) { | 1054 | if (!(reg & FLEXCAN_MCR_FEN)) { |
| 965 | netdev_err(dev, "Could not enable RX FIFO, unsupported core\n"); | 1055 | netdev_err(dev, "Could not enable RX FIFO, unsupported core\n"); |
| 966 | err = -ENODEV; | 1056 | err = -ENODEV; |
| 967 | goto out_disable_per; | 1057 | goto out_chip_disable; |
| 968 | } | 1058 | } |
| 969 | 1059 | ||
| 970 | err = register_candev(dev); | 1060 | err = register_candev(dev); |
| 971 | 1061 | ||
| 972 | out_disable_per: | ||
| 973 | /* disable core and turn off clocks */ | 1062 | /* disable core and turn off clocks */ |
| 1063 | out_chip_disable: | ||
| 974 | flexcan_chip_disable(priv); | 1064 | flexcan_chip_disable(priv); |
| 1065 | out_disable_per: | ||
| 975 | clk_disable_unprepare(priv->clk_per); | 1066 | clk_disable_unprepare(priv->clk_per); |
| 976 | out_disable_ipg: | 1067 | out_disable_ipg: |
| 977 | clk_disable_unprepare(priv->clk_ipg); | 1068 | clk_disable_unprepare(priv->clk_ipg); |
| @@ -1101,9 +1192,10 @@ static int flexcan_probe(struct platform_device *pdev) | |||
| 1101 | static int flexcan_remove(struct platform_device *pdev) | 1192 | static int flexcan_remove(struct platform_device *pdev) |
| 1102 | { | 1193 | { |
| 1103 | struct net_device *dev = platform_get_drvdata(pdev); | 1194 | struct net_device *dev = platform_get_drvdata(pdev); |
| 1195 | struct flexcan_priv *priv = netdev_priv(dev); | ||
| 1104 | 1196 | ||
| 1105 | unregister_flexcandev(dev); | 1197 | unregister_flexcandev(dev); |
| 1106 | 1198 | netif_napi_del(&priv->napi); | |
| 1107 | free_candev(dev); | 1199 | free_candev(dev); |
| 1108 | 1200 | ||
| 1109 | return 0; | 1201 | return 0; |
| @@ -1114,8 +1206,11 @@ static int flexcan_suspend(struct device *device) | |||
| 1114 | { | 1206 | { |
| 1115 | struct net_device *dev = dev_get_drvdata(device); | 1207 | struct net_device *dev = dev_get_drvdata(device); |
| 1116 | struct flexcan_priv *priv = netdev_priv(dev); | 1208 | struct flexcan_priv *priv = netdev_priv(dev); |
| 1209 | int err; | ||
| 1117 | 1210 | ||
| 1118 | flexcan_chip_disable(priv); | 1211 | err = flexcan_chip_disable(priv); |
| 1212 | if (err) | ||
| 1213 | return err; | ||
| 1119 | 1214 | ||
| 1120 | if (netif_running(dev)) { | 1215 | if (netif_running(dev)) { |
| 1121 | netif_stop_queue(dev); | 1216 | netif_stop_queue(dev); |
| @@ -1136,9 +1231,7 @@ static int flexcan_resume(struct device *device) | |||
| 1136 | netif_device_attach(dev); | 1231 | netif_device_attach(dev); |
| 1137 | netif_start_queue(dev); | 1232 | netif_start_queue(dev); |
| 1138 | } | 1233 | } |
| 1139 | flexcan_chip_enable(priv); | 1234 | return flexcan_chip_enable(priv); |
| 1140 | |||
| 1141 | return 0; | ||
| 1142 | } | 1235 | } |
| 1143 | #endif /* CONFIG_PM_SLEEP */ | 1236 | #endif /* CONFIG_PM_SLEEP */ |
| 1144 | 1237 | ||
diff --git a/drivers/net/can/janz-ican3.c b/drivers/net/can/janz-ican3.c index e24e6690d672..71594e5676fd 100644 --- a/drivers/net/can/janz-ican3.c +++ b/drivers/net/can/janz-ican3.c | |||
| @@ -18,6 +18,7 @@ | |||
| 18 | #include <linux/netdevice.h> | 18 | #include <linux/netdevice.h> |
| 19 | #include <linux/can.h> | 19 | #include <linux/can.h> |
| 20 | #include <linux/can/dev.h> | 20 | #include <linux/can/dev.h> |
| 21 | #include <linux/can/skb.h> | ||
| 21 | #include <linux/can/error.h> | 22 | #include <linux/can/error.h> |
| 22 | 23 | ||
| 23 | #include <linux/mfd/janz.h> | 24 | #include <linux/mfd/janz.h> |
| @@ -1133,20 +1134,9 @@ static void ican3_handle_message(struct ican3_dev *mod, struct ican3_msg *msg) | |||
| 1133 | */ | 1134 | */ |
| 1134 | static void ican3_put_echo_skb(struct ican3_dev *mod, struct sk_buff *skb) | 1135 | static void ican3_put_echo_skb(struct ican3_dev *mod, struct sk_buff *skb) |
| 1135 | { | 1136 | { |
| 1136 | struct sock *srcsk = skb->sk; | 1137 | skb = can_create_echo_skb(skb); |
| 1137 | 1138 | if (!skb) | |
| 1138 | if (atomic_read(&skb->users) != 1) { | 1139 | return; |
| 1139 | struct sk_buff *old_skb = skb; | ||
| 1140 | |||
| 1141 | skb = skb_clone(old_skb, GFP_ATOMIC); | ||
| 1142 | kfree_skb(old_skb); | ||
| 1143 | if (!skb) | ||
| 1144 | return; | ||
| 1145 | } else { | ||
| 1146 | skb_orphan(skb); | ||
| 1147 | } | ||
| 1148 | |||
| 1149 | skb->sk = srcsk; | ||
| 1150 | 1140 | ||
| 1151 | /* save this skb for tx interrupt echo handling */ | 1141 | /* save this skb for tx interrupt echo handling */ |
| 1152 | skb_queue_tail(&mod->echoq, skb); | 1142 | skb_queue_tail(&mod->echoq, skb); |
| @@ -1322,7 +1312,7 @@ static int ican3_napi(struct napi_struct *napi, int budget) | |||
| 1322 | 1312 | ||
| 1323 | /* process all communication messages */ | 1313 | /* process all communication messages */ |
| 1324 | while (true) { | 1314 | while (true) { |
| 1325 | struct ican3_msg msg; | 1315 | struct ican3_msg uninitialized_var(msg); |
| 1326 | ret = ican3_recv_msg(mod, &msg); | 1316 | ret = ican3_recv_msg(mod, &msg); |
| 1327 | if (ret) | 1317 | if (ret) |
| 1328 | break; | 1318 | break; |
diff --git a/drivers/net/can/usb/kvaser_usb.c b/drivers/net/can/usb/kvaser_usb.c index 6c859bba8b65..e77d11049747 100644 --- a/drivers/net/can/usb/kvaser_usb.c +++ b/drivers/net/can/usb/kvaser_usb.c | |||
| @@ -473,6 +473,8 @@ static int kvaser_usb_get_card_info(struct kvaser_usb *dev) | |||
| 473 | return err; | 473 | return err; |
| 474 | 474 | ||
| 475 | dev->nchannels = msg.u.cardinfo.nchannels; | 475 | dev->nchannels = msg.u.cardinfo.nchannels; |
| 476 | if (dev->nchannels > MAX_NET_DEVICES) | ||
| 477 | return -EINVAL; | ||
| 476 | 478 | ||
| 477 | return 0; | 479 | return 0; |
| 478 | } | 480 | } |
diff --git a/drivers/net/can/vcan.c b/drivers/net/can/vcan.c index 0a2a5ee79a17..4e94057ef5cf 100644 --- a/drivers/net/can/vcan.c +++ b/drivers/net/can/vcan.c | |||
| @@ -46,6 +46,7 @@ | |||
| 46 | #include <linux/if_ether.h> | 46 | #include <linux/if_ether.h> |
| 47 | #include <linux/can.h> | 47 | #include <linux/can.h> |
| 48 | #include <linux/can/dev.h> | 48 | #include <linux/can/dev.h> |
| 49 | #include <linux/can/skb.h> | ||
| 49 | #include <linux/slab.h> | 50 | #include <linux/slab.h> |
| 50 | #include <net/rtnetlink.h> | 51 | #include <net/rtnetlink.h> |
| 51 | 52 | ||
| @@ -109,25 +110,23 @@ static netdev_tx_t vcan_tx(struct sk_buff *skb, struct net_device *dev) | |||
| 109 | stats->rx_packets++; | 110 | stats->rx_packets++; |
| 110 | stats->rx_bytes += cfd->len; | 111 | stats->rx_bytes += cfd->len; |
| 111 | } | 112 | } |
| 112 | kfree_skb(skb); | 113 | consume_skb(skb); |
| 113 | return NETDEV_TX_OK; | 114 | return NETDEV_TX_OK; |
| 114 | } | 115 | } |
| 115 | 116 | ||
| 116 | /* perform standard echo handling for CAN network interfaces */ | 117 | /* perform standard echo handling for CAN network interfaces */ |
| 117 | 118 | ||
| 118 | if (loop) { | 119 | if (loop) { |
| 119 | struct sock *srcsk = skb->sk; | ||
| 120 | 120 | ||
| 121 | skb = skb_share_check(skb, GFP_ATOMIC); | 121 | skb = can_create_echo_skb(skb); |
| 122 | if (!skb) | 122 | if (!skb) |
| 123 | return NETDEV_TX_OK; | 123 | return NETDEV_TX_OK; |
| 124 | 124 | ||
| 125 | /* receive with packet counting */ | 125 | /* receive with packet counting */ |
| 126 | skb->sk = srcsk; | ||
| 127 | vcan_rx(skb, dev); | 126 | vcan_rx(skb, dev); |
| 128 | } else { | 127 | } else { |
| 129 | /* no looped packets => no counting */ | 128 | /* no looped packets => no counting */ |
| 130 | kfree_skb(skb); | 129 | consume_skb(skb); |
| 131 | } | 130 | } |
| 132 | return NETDEV_TX_OK; | 131 | return NETDEV_TX_OK; |
| 133 | } | 132 | } |
diff --git a/drivers/net/ethernet/3com/3c59x.c b/drivers/net/ethernet/3com/3c59x.c index 0f4241c6e97e..238ccea965c8 100644 --- a/drivers/net/ethernet/3com/3c59x.c +++ b/drivers/net/ethernet/3com/3c59x.c | |||
| @@ -3294,7 +3294,6 @@ static int __init vortex_init(void) | |||
| 3294 | 3294 | ||
| 3295 | static void __exit vortex_eisa_cleanup(void) | 3295 | static void __exit vortex_eisa_cleanup(void) |
| 3296 | { | 3296 | { |
| 3297 | struct vortex_private *vp; | ||
| 3298 | void __iomem *ioaddr; | 3297 | void __iomem *ioaddr; |
| 3299 | 3298 | ||
| 3300 | #ifdef CONFIG_EISA | 3299 | #ifdef CONFIG_EISA |
| @@ -3303,7 +3302,6 @@ static void __exit vortex_eisa_cleanup(void) | |||
| 3303 | #endif | 3302 | #endif |
| 3304 | 3303 | ||
| 3305 | if (compaq_net_device) { | 3304 | if (compaq_net_device) { |
| 3306 | vp = netdev_priv(compaq_net_device); | ||
| 3307 | ioaddr = ioport_map(compaq_net_device->base_addr, | 3305 | ioaddr = ioport_map(compaq_net_device->base_addr, |
| 3308 | VORTEX_TOTAL_SIZE); | 3306 | VORTEX_TOTAL_SIZE); |
| 3309 | 3307 | ||
diff --git a/drivers/net/ethernet/allwinner/sun4i-emac.c b/drivers/net/ethernet/allwinner/sun4i-emac.c index 0cc21437478c..511f6eecd58b 100644 --- a/drivers/net/ethernet/allwinner/sun4i-emac.c +++ b/drivers/net/ethernet/allwinner/sun4i-emac.c | |||
| @@ -929,6 +929,9 @@ static int emac_resume(struct platform_device *dev) | |||
| 929 | } | 929 | } |
| 930 | 930 | ||
| 931 | static const struct of_device_id emac_of_match[] = { | 931 | static const struct of_device_id emac_of_match[] = { |
| 932 | {.compatible = "allwinner,sun4i-a10-emac",}, | ||
| 933 | |||
| 934 | /* Deprecated */ | ||
| 932 | {.compatible = "allwinner,sun4i-emac",}, | 935 | {.compatible = "allwinner,sun4i-emac",}, |
| 933 | {}, | 936 | {}, |
| 934 | }; | 937 | }; |
diff --git a/drivers/net/ethernet/atheros/alx/main.c b/drivers/net/ethernet/atheros/alx/main.c index e92ffd6e1c15..2e45f6ec1bf0 100644 --- a/drivers/net/ethernet/atheros/alx/main.c +++ b/drivers/net/ethernet/atheros/alx/main.c | |||
| @@ -1292,6 +1292,7 @@ static int alx_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
| 1292 | alx = netdev_priv(netdev); | 1292 | alx = netdev_priv(netdev); |
| 1293 | spin_lock_init(&alx->hw.mdio_lock); | 1293 | spin_lock_init(&alx->hw.mdio_lock); |
| 1294 | spin_lock_init(&alx->irq_lock); | 1294 | spin_lock_init(&alx->irq_lock); |
| 1295 | spin_lock_init(&alx->stats_lock); | ||
| 1295 | alx->dev = netdev; | 1296 | alx->dev = netdev; |
| 1296 | alx->hw.pdev = pdev; | 1297 | alx->hw.pdev = pdev; |
| 1297 | alx->msg_enable = NETIF_MSG_LINK | NETIF_MSG_HW | NETIF_MSG_IFUP | | 1298 | alx->msg_enable = NETIF_MSG_LINK | NETIF_MSG_HW | NETIF_MSG_IFUP | |
diff --git a/drivers/net/ethernet/broadcom/b44.c b/drivers/net/ethernet/broadcom/b44.c index 1f7b5aa114fa..8a7bf7dad898 100644 --- a/drivers/net/ethernet/broadcom/b44.c +++ b/drivers/net/ethernet/broadcom/b44.c | |||
| @@ -1484,6 +1484,10 @@ static int b44_open(struct net_device *dev) | |||
| 1484 | add_timer(&bp->timer); | 1484 | add_timer(&bp->timer); |
| 1485 | 1485 | ||
| 1486 | b44_enable_ints(bp); | 1486 | b44_enable_ints(bp); |
| 1487 | |||
| 1488 | if (bp->flags & B44_FLAG_EXTERNAL_PHY) | ||
| 1489 | phy_start(bp->phydev); | ||
| 1490 | |||
| 1487 | netif_start_queue(dev); | 1491 | netif_start_queue(dev); |
| 1488 | out: | 1492 | out: |
| 1489 | return err; | 1493 | return err; |
| @@ -1646,6 +1650,9 @@ static int b44_close(struct net_device *dev) | |||
| 1646 | 1650 | ||
| 1647 | netif_stop_queue(dev); | 1651 | netif_stop_queue(dev); |
| 1648 | 1652 | ||
| 1653 | if (bp->flags & B44_FLAG_EXTERNAL_PHY) | ||
| 1654 | phy_stop(bp->phydev); | ||
| 1655 | |||
| 1649 | napi_disable(&bp->napi); | 1656 | napi_disable(&bp->napi); |
| 1650 | 1657 | ||
| 1651 | del_timer_sync(&bp->timer); | 1658 | del_timer_sync(&bp->timer); |
| @@ -2222,7 +2229,12 @@ static void b44_adjust_link(struct net_device *dev) | |||
| 2222 | } | 2229 | } |
| 2223 | 2230 | ||
| 2224 | if (status_changed) { | 2231 | if (status_changed) { |
| 2225 | b44_check_phy(bp); | 2232 | u32 val = br32(bp, B44_TX_CTRL); |
| 2233 | if (bp->flags & B44_FLAG_FULL_DUPLEX) | ||
| 2234 | val |= TX_CTRL_DUPLEX; | ||
| 2235 | else | ||
| 2236 | val &= ~TX_CTRL_DUPLEX; | ||
| 2237 | bw32(bp, B44_TX_CTRL, val); | ||
| 2226 | phy_print_status(phydev); | 2238 | phy_print_status(phydev); |
| 2227 | } | 2239 | } |
| 2228 | } | 2240 | } |
diff --git a/drivers/net/ethernet/broadcom/bnx2.c b/drivers/net/ethernet/broadcom/bnx2.c index 9d2dedadf2df..cda25ac45b47 100644 --- a/drivers/net/ethernet/broadcom/bnx2.c +++ b/drivers/net/ethernet/broadcom/bnx2.c | |||
| @@ -85,7 +85,7 @@ MODULE_FIRMWARE(FW_RV2P_FILE_09_Ax); | |||
| 85 | 85 | ||
| 86 | static int disable_msi = 0; | 86 | static int disable_msi = 0; |
| 87 | 87 | ||
| 88 | module_param(disable_msi, int, 0); | 88 | module_param(disable_msi, int, S_IRUGO); |
| 89 | MODULE_PARM_DESC(disable_msi, "Disable Message Signaled Interrupt (MSI)"); | 89 | MODULE_PARM_DESC(disable_msi, "Disable Message Signaled Interrupt (MSI)"); |
| 90 | 90 | ||
| 91 | typedef enum { | 91 | typedef enum { |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c index 9d7419e0390b..dbcff509dc3f 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | |||
| @@ -1873,7 +1873,7 @@ void bnx2x_netif_stop(struct bnx2x *bp, int disable_hw) | |||
| 1873 | } | 1873 | } |
| 1874 | 1874 | ||
| 1875 | u16 bnx2x_select_queue(struct net_device *dev, struct sk_buff *skb, | 1875 | u16 bnx2x_select_queue(struct net_device *dev, struct sk_buff *skb, |
| 1876 | void *accel_priv) | 1876 | void *accel_priv, select_queue_fallback_t fallback) |
| 1877 | { | 1877 | { |
| 1878 | struct bnx2x *bp = netdev_priv(dev); | 1878 | struct bnx2x *bp = netdev_priv(dev); |
| 1879 | 1879 | ||
| @@ -1895,7 +1895,7 @@ u16 bnx2x_select_queue(struct net_device *dev, struct sk_buff *skb, | |||
| 1895 | } | 1895 | } |
| 1896 | 1896 | ||
| 1897 | /* select a non-FCoE queue */ | 1897 | /* select a non-FCoE queue */ |
| 1898 | return __netdev_pick_tx(dev, skb) % BNX2X_NUM_ETH_QUEUES(bp); | 1898 | return fallback(dev, skb) % BNX2X_NUM_ETH_QUEUES(bp); |
| 1899 | } | 1899 | } |
| 1900 | 1900 | ||
| 1901 | void bnx2x_set_num_queues(struct bnx2x *bp) | 1901 | void bnx2x_set_num_queues(struct bnx2x *bp) |
| @@ -3875,7 +3875,9 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
| 3875 | xmit_type); | 3875 | xmit_type); |
| 3876 | } | 3876 | } |
| 3877 | 3877 | ||
| 3878 | /* Add the macs to the parsing BD this is a vf */ | 3878 | /* Add the macs to the parsing BD if this is a vf or if |
| 3879 | * Tx Switching is enabled. | ||
| 3880 | */ | ||
| 3879 | if (IS_VF(bp)) { | 3881 | if (IS_VF(bp)) { |
| 3880 | /* override GRE parameters in BD */ | 3882 | /* override GRE parameters in BD */ |
| 3881 | bnx2x_set_fw_mac_addr(&pbd_e2->data.mac_addr.src_hi, | 3883 | bnx2x_set_fw_mac_addr(&pbd_e2->data.mac_addr.src_hi, |
| @@ -3887,6 +3889,11 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
| 3887 | &pbd_e2->data.mac_addr.dst_mid, | 3889 | &pbd_e2->data.mac_addr.dst_mid, |
| 3888 | &pbd_e2->data.mac_addr.dst_lo, | 3890 | &pbd_e2->data.mac_addr.dst_lo, |
| 3889 | eth->h_dest); | 3891 | eth->h_dest); |
| 3892 | } else if (bp->flags & TX_SWITCHING) { | ||
| 3893 | bnx2x_set_fw_mac_addr(&pbd_e2->data.mac_addr.dst_hi, | ||
| 3894 | &pbd_e2->data.mac_addr.dst_mid, | ||
| 3895 | &pbd_e2->data.mac_addr.dst_lo, | ||
| 3896 | eth->h_dest); | ||
| 3890 | } | 3897 | } |
| 3891 | 3898 | ||
| 3892 | SET_FLAG(pbd_e2_parsing_data, | 3899 | SET_FLAG(pbd_e2_parsing_data, |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h index 17d1689aec6b..a89a40f88c25 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h | |||
| @@ -496,7 +496,7 @@ int bnx2x_set_vf_vlan(struct net_device *netdev, int vf, u16 vlan, u8 qos); | |||
| 496 | 496 | ||
| 497 | /* select_queue callback */ | 497 | /* select_queue callback */ |
| 498 | u16 bnx2x_select_queue(struct net_device *dev, struct sk_buff *skb, | 498 | u16 bnx2x_select_queue(struct net_device *dev, struct sk_buff *skb, |
| 499 | void *accel_priv); | 499 | void *accel_priv, select_queue_fallback_t fallback); |
| 500 | 500 | ||
| 501 | static inline void bnx2x_update_rx_prod(struct bnx2x *bp, | 501 | static inline void bnx2x_update_rx_prod(struct bnx2x *bp, |
| 502 | struct bnx2x_fastpath *fp, | 502 | struct bnx2x_fastpath *fp, |
| @@ -936,7 +936,7 @@ static inline int bnx2x_func_start(struct bnx2x *bp) | |||
| 936 | else /* CHIP_IS_E1X */ | 936 | else /* CHIP_IS_E1X */ |
| 937 | start_params->network_cos_mode = FW_WRR; | 937 | start_params->network_cos_mode = FW_WRR; |
| 938 | 938 | ||
| 939 | start_params->gre_tunnel_mode = IPGRE_TUNNEL; | 939 | start_params->gre_tunnel_mode = L2GRE_TUNNEL; |
| 940 | start_params->gre_tunnel_rss = GRE_INNER_HEADERS_RSS; | 940 | start_params->gre_tunnel_rss = GRE_INNER_HEADERS_RSS; |
| 941 | 941 | ||
| 942 | return bnx2x_func_state_change(bp, &func_params); | 942 | return bnx2x_func_state_change(bp, &func_params); |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index c9c445e7b4a5..7d4382286457 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | |||
| @@ -95,29 +95,29 @@ MODULE_FIRMWARE(FW_FILE_NAME_E1H); | |||
| 95 | MODULE_FIRMWARE(FW_FILE_NAME_E2); | 95 | MODULE_FIRMWARE(FW_FILE_NAME_E2); |
| 96 | 96 | ||
| 97 | int bnx2x_num_queues; | 97 | int bnx2x_num_queues; |
| 98 | module_param_named(num_queues, bnx2x_num_queues, int, 0); | 98 | module_param_named(num_queues, bnx2x_num_queues, int, S_IRUGO); |
| 99 | MODULE_PARM_DESC(num_queues, | 99 | MODULE_PARM_DESC(num_queues, |
| 100 | " Set number of queues (default is as a number of CPUs)"); | 100 | " Set number of queues (default is as a number of CPUs)"); |
| 101 | 101 | ||
| 102 | static int disable_tpa; | 102 | static int disable_tpa; |
| 103 | module_param(disable_tpa, int, 0); | 103 | module_param(disable_tpa, int, S_IRUGO); |
| 104 | MODULE_PARM_DESC(disable_tpa, " Disable the TPA (LRO) feature"); | 104 | MODULE_PARM_DESC(disable_tpa, " Disable the TPA (LRO) feature"); |
| 105 | 105 | ||
| 106 | static int int_mode; | 106 | static int int_mode; |
| 107 | module_param(int_mode, int, 0); | 107 | module_param(int_mode, int, S_IRUGO); |
| 108 | MODULE_PARM_DESC(int_mode, " Force interrupt mode other than MSI-X " | 108 | MODULE_PARM_DESC(int_mode, " Force interrupt mode other than MSI-X " |
| 109 | "(1 INT#x; 2 MSI)"); | 109 | "(1 INT#x; 2 MSI)"); |
| 110 | 110 | ||
| 111 | static int dropless_fc; | 111 | static int dropless_fc; |
| 112 | module_param(dropless_fc, int, 0); | 112 | module_param(dropless_fc, int, S_IRUGO); |
| 113 | MODULE_PARM_DESC(dropless_fc, " Pause on exhausted host ring"); | 113 | MODULE_PARM_DESC(dropless_fc, " Pause on exhausted host ring"); |
| 114 | 114 | ||
| 115 | static int mrrs = -1; | 115 | static int mrrs = -1; |
| 116 | module_param(mrrs, int, 0); | 116 | module_param(mrrs, int, S_IRUGO); |
| 117 | MODULE_PARM_DESC(mrrs, " Force Max Read Req Size (0..3) (for debug)"); | 117 | MODULE_PARM_DESC(mrrs, " Force Max Read Req Size (0..3) (for debug)"); |
| 118 | 118 | ||
| 119 | static int debug; | 119 | static int debug; |
| 120 | module_param(debug, int, 0); | 120 | module_param(debug, int, S_IRUGO); |
| 121 | MODULE_PARM_DESC(debug, " Default debug msglevel"); | 121 | MODULE_PARM_DESC(debug, " Default debug msglevel"); |
| 122 | 122 | ||
| 123 | struct workqueue_struct *bnx2x_wq; | 123 | struct workqueue_struct *bnx2x_wq; |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c index aec5ef2ed7ce..e42f48df6e94 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c | |||
| @@ -1446,12 +1446,12 @@ static void bnx2x_vf_igu_reset(struct bnx2x *bp, struct bnx2x_virtf *vf) | |||
| 1446 | if (vf->cfg_flags & VF_CFG_INT_SIMD) | 1446 | if (vf->cfg_flags & VF_CFG_INT_SIMD) |
| 1447 | val |= IGU_VF_CONF_SINGLE_ISR_EN; | 1447 | val |= IGU_VF_CONF_SINGLE_ISR_EN; |
| 1448 | val &= ~IGU_VF_CONF_PARENT_MASK; | 1448 | val &= ~IGU_VF_CONF_PARENT_MASK; |
| 1449 | val |= BP_FUNC(bp) << IGU_VF_CONF_PARENT_SHIFT; /* parent PF */ | 1449 | val |= (BP_ABS_FUNC(bp) >> 1) << IGU_VF_CONF_PARENT_SHIFT; |
| 1450 | REG_WR(bp, IGU_REG_VF_CONFIGURATION, val); | 1450 | REG_WR(bp, IGU_REG_VF_CONFIGURATION, val); |
| 1451 | 1451 | ||
| 1452 | DP(BNX2X_MSG_IOV, | 1452 | DP(BNX2X_MSG_IOV, |
| 1453 | "value in IGU_REG_VF_CONFIGURATION of vf %d after write %x\n", | 1453 | "value in IGU_REG_VF_CONFIGURATION of vf %d after write is 0x%08x\n", |
| 1454 | vf->abs_vfid, REG_RD(bp, IGU_REG_VF_CONFIGURATION)); | 1454 | vf->abs_vfid, val); |
| 1455 | 1455 | ||
| 1456 | bnx2x_pretend_func(bp, BP_ABS_FUNC(bp)); | 1456 | bnx2x_pretend_func(bp, BP_ABS_FUNC(bp)); |
| 1457 | 1457 | ||
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index e2ca03e23dc1..3b6d0ba86c71 100644 --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c | |||
| @@ -2609,13 +2609,14 @@ static int tg3_phy_reset_5703_4_5(struct tg3 *tp) | |||
| 2609 | 2609 | ||
| 2610 | tg3_writephy(tp, MII_CTRL1000, phy9_orig); | 2610 | tg3_writephy(tp, MII_CTRL1000, phy9_orig); |
| 2611 | 2611 | ||
| 2612 | if (!tg3_readphy(tp, MII_TG3_EXT_CTRL, ®32)) { | 2612 | err = tg3_readphy(tp, MII_TG3_EXT_CTRL, ®32); |
| 2613 | reg32 &= ~0x3000; | 2613 | if (err) |
| 2614 | tg3_writephy(tp, MII_TG3_EXT_CTRL, reg32); | 2614 | return err; |
| 2615 | } else if (!err) | ||
| 2616 | err = -EBUSY; | ||
| 2617 | 2615 | ||
| 2618 | return err; | 2616 | reg32 &= ~0x3000; |
| 2617 | tg3_writephy(tp, MII_TG3_EXT_CTRL, reg32); | ||
| 2618 | |||
| 2619 | return 0; | ||
| 2619 | } | 2620 | } |
| 2620 | 2621 | ||
| 2621 | static void tg3_carrier_off(struct tg3 *tp) | 2622 | static void tg3_carrier_off(struct tg3 *tp) |
| @@ -6842,8 +6843,7 @@ static int tg3_rx(struct tg3_napi *tnapi, int budget) | |||
| 6842 | 6843 | ||
| 6843 | work_mask |= opaque_key; | 6844 | work_mask |= opaque_key; |
| 6844 | 6845 | ||
| 6845 | if ((desc->err_vlan & RXD_ERR_MASK) != 0 && | 6846 | if (desc->err_vlan & RXD_ERR_MASK) { |
| 6846 | (desc->err_vlan != RXD_ERR_ODD_NIBBLE_RCVD_MII)) { | ||
| 6847 | drop_it: | 6847 | drop_it: |
| 6848 | tg3_recycle_rx(tnapi, tpr, opaque_key, | 6848 | tg3_recycle_rx(tnapi, tpr, opaque_key, |
| 6849 | desc_idx, *post_ptr); | 6849 | desc_idx, *post_ptr); |
| @@ -14113,12 +14113,12 @@ static int tg3_change_mtu(struct net_device *dev, int new_mtu) | |||
| 14113 | 14113 | ||
| 14114 | tg3_netif_stop(tp); | 14114 | tg3_netif_stop(tp); |
| 14115 | 14115 | ||
| 14116 | tg3_set_mtu(dev, tp, new_mtu); | ||
| 14117 | |||
| 14116 | tg3_full_lock(tp, 1); | 14118 | tg3_full_lock(tp, 1); |
| 14117 | 14119 | ||
| 14118 | tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); | 14120 | tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); |
| 14119 | 14121 | ||
| 14120 | tg3_set_mtu(dev, tp, new_mtu); | ||
| 14121 | |||
| 14122 | /* Reset PHY, otherwise the read DMA engine will be in a mode that | 14122 | /* Reset PHY, otherwise the read DMA engine will be in a mode that |
| 14123 | * breaks all requests to 256 bytes. | 14123 | * breaks all requests to 256 bytes. |
| 14124 | */ | 14124 | */ |
diff --git a/drivers/net/ethernet/broadcom/tg3.h b/drivers/net/ethernet/broadcom/tg3.h index ef472385bce4..04321e5a356e 100644 --- a/drivers/net/ethernet/broadcom/tg3.h +++ b/drivers/net/ethernet/broadcom/tg3.h | |||
| @@ -2608,7 +2608,11 @@ struct tg3_rx_buffer_desc { | |||
| 2608 | #define RXD_ERR_TOO_SMALL 0x00400000 | 2608 | #define RXD_ERR_TOO_SMALL 0x00400000 |
| 2609 | #define RXD_ERR_NO_RESOURCES 0x00800000 | 2609 | #define RXD_ERR_NO_RESOURCES 0x00800000 |
| 2610 | #define RXD_ERR_HUGE_FRAME 0x01000000 | 2610 | #define RXD_ERR_HUGE_FRAME 0x01000000 |
| 2611 | #define RXD_ERR_MASK 0xffff0000 | 2611 | |
| 2612 | #define RXD_ERR_MASK (RXD_ERR_BAD_CRC | RXD_ERR_COLLISION | \ | ||
| 2613 | RXD_ERR_LINK_LOST | RXD_ERR_PHY_DECODE | \ | ||
| 2614 | RXD_ERR_MAC_ABRT | RXD_ERR_TOO_SMALL | \ | ||
| 2615 | RXD_ERR_NO_RESOURCES | RXD_ERR_HUGE_FRAME) | ||
| 2612 | 2616 | ||
| 2613 | u32 reserved; | 2617 | u32 reserved; |
| 2614 | u32 opaque; | 2618 | u32 opaque; |
diff --git a/drivers/net/ethernet/brocade/bna/bnad.c b/drivers/net/ethernet/brocade/bna/bnad.c index cf64f3d0b60d..4ad1187e82fb 100644 --- a/drivers/net/ethernet/brocade/bna/bnad.c +++ b/drivers/net/ethernet/brocade/bna/bnad.c | |||
| @@ -707,7 +707,8 @@ bnad_cq_process(struct bnad *bnad, struct bna_ccb *ccb, int budget) | |||
| 707 | else | 707 | else |
| 708 | skb_checksum_none_assert(skb); | 708 | skb_checksum_none_assert(skb); |
| 709 | 709 | ||
| 710 | if (flags & BNA_CQ_EF_VLAN) | 710 | if ((flags & BNA_CQ_EF_VLAN) && |
| 711 | (bnad->netdev->features & NETIF_F_HW_VLAN_CTAG_RX)) | ||
| 711 | __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), ntohs(cmpl->vlan_tag)); | 712 | __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), ntohs(cmpl->vlan_tag)); |
| 712 | 713 | ||
| 713 | if (BNAD_RXBUF_IS_SK_BUFF(unmap_q->type)) | 714 | if (BNAD_RXBUF_IS_SK_BUFF(unmap_q->type)) |
| @@ -2094,7 +2095,9 @@ bnad_init_rx_config(struct bnad *bnad, struct bna_rx_config *rx_config) | |||
| 2094 | rx_config->q1_buf_size = BFI_SMALL_RXBUF_SIZE; | 2095 | rx_config->q1_buf_size = BFI_SMALL_RXBUF_SIZE; |
| 2095 | } | 2096 | } |
| 2096 | 2097 | ||
| 2097 | rx_config->vlan_strip_status = BNA_STATUS_T_ENABLED; | 2098 | rx_config->vlan_strip_status = |
| 2099 | (bnad->netdev->features & NETIF_F_HW_VLAN_CTAG_RX) ? | ||
| 2100 | BNA_STATUS_T_ENABLED : BNA_STATUS_T_DISABLED; | ||
| 2098 | } | 2101 | } |
| 2099 | 2102 | ||
| 2100 | static void | 2103 | static void |
| @@ -3245,11 +3248,6 @@ bnad_set_rx_mode(struct net_device *netdev) | |||
| 3245 | BNA_RXMODE_ALLMULTI; | 3248 | BNA_RXMODE_ALLMULTI; |
| 3246 | bna_rx_mode_set(bnad->rx_info[0].rx, new_mode, mode_mask, NULL); | 3249 | bna_rx_mode_set(bnad->rx_info[0].rx, new_mode, mode_mask, NULL); |
| 3247 | 3250 | ||
| 3248 | if (bnad->cfg_flags & BNAD_CF_PROMISC) | ||
| 3249 | bna_rx_vlan_strip_disable(bnad->rx_info[0].rx); | ||
| 3250 | else | ||
| 3251 | bna_rx_vlan_strip_enable(bnad->rx_info[0].rx); | ||
| 3252 | |||
| 3253 | spin_unlock_irqrestore(&bnad->bna_lock, flags); | 3251 | spin_unlock_irqrestore(&bnad->bna_lock, flags); |
| 3254 | } | 3252 | } |
| 3255 | 3253 | ||
| @@ -3374,6 +3372,27 @@ bnad_vlan_rx_kill_vid(struct net_device *netdev, __be16 proto, u16 vid) | |||
| 3374 | return 0; | 3372 | return 0; |
| 3375 | } | 3373 | } |
| 3376 | 3374 | ||
| 3375 | static int bnad_set_features(struct net_device *dev, netdev_features_t features) | ||
| 3376 | { | ||
| 3377 | struct bnad *bnad = netdev_priv(dev); | ||
| 3378 | netdev_features_t changed = features ^ dev->features; | ||
| 3379 | |||
| 3380 | if ((changed & NETIF_F_HW_VLAN_CTAG_RX) && netif_running(dev)) { | ||
| 3381 | unsigned long flags; | ||
| 3382 | |||
| 3383 | spin_lock_irqsave(&bnad->bna_lock, flags); | ||
| 3384 | |||
| 3385 | if (features & NETIF_F_HW_VLAN_CTAG_RX) | ||
| 3386 | bna_rx_vlan_strip_enable(bnad->rx_info[0].rx); | ||
| 3387 | else | ||
| 3388 | bna_rx_vlan_strip_disable(bnad->rx_info[0].rx); | ||
| 3389 | |||
| 3390 | spin_unlock_irqrestore(&bnad->bna_lock, flags); | ||
| 3391 | } | ||
| 3392 | |||
| 3393 | return 0; | ||
| 3394 | } | ||
| 3395 | |||
| 3377 | #ifdef CONFIG_NET_POLL_CONTROLLER | 3396 | #ifdef CONFIG_NET_POLL_CONTROLLER |
| 3378 | static void | 3397 | static void |
| 3379 | bnad_netpoll(struct net_device *netdev) | 3398 | bnad_netpoll(struct net_device *netdev) |
| @@ -3421,6 +3440,7 @@ static const struct net_device_ops bnad_netdev_ops = { | |||
| 3421 | .ndo_change_mtu = bnad_change_mtu, | 3440 | .ndo_change_mtu = bnad_change_mtu, |
| 3422 | .ndo_vlan_rx_add_vid = bnad_vlan_rx_add_vid, | 3441 | .ndo_vlan_rx_add_vid = bnad_vlan_rx_add_vid, |
| 3423 | .ndo_vlan_rx_kill_vid = bnad_vlan_rx_kill_vid, | 3442 | .ndo_vlan_rx_kill_vid = bnad_vlan_rx_kill_vid, |
| 3443 | .ndo_set_features = bnad_set_features, | ||
| 3424 | #ifdef CONFIG_NET_POLL_CONTROLLER | 3444 | #ifdef CONFIG_NET_POLL_CONTROLLER |
| 3425 | .ndo_poll_controller = bnad_netpoll | 3445 | .ndo_poll_controller = bnad_netpoll |
| 3426 | #endif | 3446 | #endif |
| @@ -3433,14 +3453,14 @@ bnad_netdev_init(struct bnad *bnad, bool using_dac) | |||
| 3433 | 3453 | ||
| 3434 | netdev->hw_features = NETIF_F_SG | NETIF_F_RXCSUM | | 3454 | netdev->hw_features = NETIF_F_SG | NETIF_F_RXCSUM | |
| 3435 | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | | 3455 | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | |
| 3436 | NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_HW_VLAN_CTAG_TX; | 3456 | NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_HW_VLAN_CTAG_TX | |
| 3457 | NETIF_F_HW_VLAN_CTAG_RX; | ||
| 3437 | 3458 | ||
| 3438 | netdev->vlan_features = NETIF_F_SG | NETIF_F_HIGHDMA | | 3459 | netdev->vlan_features = NETIF_F_SG | NETIF_F_HIGHDMA | |
| 3439 | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | | 3460 | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | |
| 3440 | NETIF_F_TSO | NETIF_F_TSO6; | 3461 | NETIF_F_TSO | NETIF_F_TSO6; |
| 3441 | 3462 | ||
| 3442 | netdev->features |= netdev->hw_features | | 3463 | netdev->features |= netdev->hw_features | NETIF_F_HW_VLAN_CTAG_FILTER; |
| 3443 | NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_HW_VLAN_CTAG_FILTER; | ||
| 3444 | 3464 | ||
| 3445 | if (using_dac) | 3465 | if (using_dac) |
| 3446 | netdev->features |= NETIF_F_HIGHDMA; | 3466 | netdev->features |= NETIF_F_HIGHDMA; |
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c index 43ab35fea48d..34e2488767d9 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | |||
| @@ -6179,6 +6179,7 @@ static struct pci_driver cxgb4_driver = { | |||
| 6179 | .id_table = cxgb4_pci_tbl, | 6179 | .id_table = cxgb4_pci_tbl, |
| 6180 | .probe = init_one, | 6180 | .probe = init_one, |
| 6181 | .remove = remove_one, | 6181 | .remove = remove_one, |
| 6182 | .shutdown = remove_one, | ||
| 6182 | .err_handler = &cxgb4_eeh, | 6183 | .err_handler = &cxgb4_eeh, |
| 6183 | }; | 6184 | }; |
| 6184 | 6185 | ||
diff --git a/drivers/net/ethernet/dec/tulip/tulip_core.c b/drivers/net/ethernet/dec/tulip/tulip_core.c index add05f14b38b..1642de78aac8 100644 --- a/drivers/net/ethernet/dec/tulip/tulip_core.c +++ b/drivers/net/ethernet/dec/tulip/tulip_core.c | |||
| @@ -1939,6 +1939,7 @@ static void tulip_remove_one(struct pci_dev *pdev) | |||
| 1939 | pci_iounmap(pdev, tp->base_addr); | 1939 | pci_iounmap(pdev, tp->base_addr); |
| 1940 | free_netdev (dev); | 1940 | free_netdev (dev); |
| 1941 | pci_release_regions (pdev); | 1941 | pci_release_regions (pdev); |
| 1942 | pci_disable_device(pdev); | ||
| 1942 | 1943 | ||
| 1943 | /* pci_power_off (pdev, -1); */ | 1944 | /* pci_power_off (pdev, -1); */ |
| 1944 | } | 1945 | } |
diff --git a/drivers/net/ethernet/emulex/benet/be.h b/drivers/net/ethernet/emulex/benet/be.h index 8d09615da585..05529e273050 100644 --- a/drivers/net/ethernet/emulex/benet/be.h +++ b/drivers/net/ethernet/emulex/benet/be.h | |||
| @@ -350,11 +350,13 @@ struct be_drv_stats { | |||
| 350 | u32 roce_drops_crc; | 350 | u32 roce_drops_crc; |
| 351 | }; | 351 | }; |
| 352 | 352 | ||
| 353 | /* A vlan-id of 0xFFFF must be used to clear transparent vlan-tagging */ | ||
| 354 | #define BE_RESET_VLAN_TAG_ID 0xFFFF | ||
| 355 | |||
| 353 | struct be_vf_cfg { | 356 | struct be_vf_cfg { |
| 354 | unsigned char mac_addr[ETH_ALEN]; | 357 | unsigned char mac_addr[ETH_ALEN]; |
| 355 | int if_handle; | 358 | int if_handle; |
| 356 | int pmac_id; | 359 | int pmac_id; |
| 357 | u16 def_vid; | ||
| 358 | u16 vlan_tag; | 360 | u16 vlan_tag; |
| 359 | u32 tx_rate; | 361 | u32 tx_rate; |
| 360 | }; | 362 | }; |
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index 04ac9c6a0d39..36c80612e21a 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c | |||
| @@ -913,24 +913,14 @@ static int be_ipv6_tx_stall_chk(struct be_adapter *adapter, | |||
| 913 | return BE3_chip(adapter) && be_ipv6_exthdr_check(skb); | 913 | return BE3_chip(adapter) && be_ipv6_exthdr_check(skb); |
| 914 | } | 914 | } |
| 915 | 915 | ||
| 916 | static struct sk_buff *be_xmit_workarounds(struct be_adapter *adapter, | 916 | static struct sk_buff *be_lancer_xmit_workarounds(struct be_adapter *adapter, |
| 917 | struct sk_buff *skb, | 917 | struct sk_buff *skb, |
| 918 | bool *skip_hw_vlan) | 918 | bool *skip_hw_vlan) |
| 919 | { | 919 | { |
| 920 | struct vlan_ethhdr *veh = (struct vlan_ethhdr *)skb->data; | 920 | struct vlan_ethhdr *veh = (struct vlan_ethhdr *)skb->data; |
| 921 | unsigned int eth_hdr_len; | 921 | unsigned int eth_hdr_len; |
| 922 | struct iphdr *ip; | 922 | struct iphdr *ip; |
| 923 | 923 | ||
| 924 | /* Lancer, SH-R ASICs have a bug wherein Packets that are 32 bytes or less | ||
| 925 | * may cause a transmit stall on that port. So the work-around is to | ||
| 926 | * pad short packets (<= 32 bytes) to a 36-byte length. | ||
| 927 | */ | ||
| 928 | if (unlikely(!BEx_chip(adapter) && skb->len <= 32)) { | ||
| 929 | if (skb_padto(skb, 36)) | ||
| 930 | goto tx_drop; | ||
| 931 | skb->len = 36; | ||
| 932 | } | ||
| 933 | |||
| 934 | /* For padded packets, BE HW modifies tot_len field in IP header | 924 | /* For padded packets, BE HW modifies tot_len field in IP header |
| 935 | * incorrecly when VLAN tag is inserted by HW. | 925 | * incorrecly when VLAN tag is inserted by HW. |
| 936 | * For padded packets, Lancer computes incorrect checksum. | 926 | * For padded packets, Lancer computes incorrect checksum. |
| @@ -959,7 +949,7 @@ static struct sk_buff *be_xmit_workarounds(struct be_adapter *adapter, | |||
| 959 | vlan_tx_tag_present(skb)) { | 949 | vlan_tx_tag_present(skb)) { |
| 960 | skb = be_insert_vlan_in_pkt(adapter, skb, skip_hw_vlan); | 950 | skb = be_insert_vlan_in_pkt(adapter, skb, skip_hw_vlan); |
| 961 | if (unlikely(!skb)) | 951 | if (unlikely(!skb)) |
| 962 | goto tx_drop; | 952 | goto err; |
| 963 | } | 953 | } |
| 964 | 954 | ||
| 965 | /* HW may lockup when VLAN HW tagging is requested on | 955 | /* HW may lockup when VLAN HW tagging is requested on |
| @@ -981,15 +971,39 @@ static struct sk_buff *be_xmit_workarounds(struct be_adapter *adapter, | |||
| 981 | be_vlan_tag_tx_chk(adapter, skb)) { | 971 | be_vlan_tag_tx_chk(adapter, skb)) { |
| 982 | skb = be_insert_vlan_in_pkt(adapter, skb, skip_hw_vlan); | 972 | skb = be_insert_vlan_in_pkt(adapter, skb, skip_hw_vlan); |
| 983 | if (unlikely(!skb)) | 973 | if (unlikely(!skb)) |
| 984 | goto tx_drop; | 974 | goto err; |
| 985 | } | 975 | } |
| 986 | 976 | ||
| 987 | return skb; | 977 | return skb; |
| 988 | tx_drop: | 978 | tx_drop: |
| 989 | dev_kfree_skb_any(skb); | 979 | dev_kfree_skb_any(skb); |
| 980 | err: | ||
| 990 | return NULL; | 981 | return NULL; |
| 991 | } | 982 | } |
| 992 | 983 | ||
| 984 | static struct sk_buff *be_xmit_workarounds(struct be_adapter *adapter, | ||
| 985 | struct sk_buff *skb, | ||
| 986 | bool *skip_hw_vlan) | ||
| 987 | { | ||
| 988 | /* Lancer, SH-R ASICs have a bug wherein Packets that are 32 bytes or | ||
| 989 | * less may cause a transmit stall on that port. So the work-around is | ||
| 990 | * to pad short packets (<= 32 bytes) to a 36-byte length. | ||
| 991 | */ | ||
| 992 | if (unlikely(!BEx_chip(adapter) && skb->len <= 32)) { | ||
| 993 | if (skb_padto(skb, 36)) | ||
| 994 | return NULL; | ||
| 995 | skb->len = 36; | ||
| 996 | } | ||
| 997 | |||
| 998 | if (BEx_chip(adapter) || lancer_chip(adapter)) { | ||
| 999 | skb = be_lancer_xmit_workarounds(adapter, skb, skip_hw_vlan); | ||
| 1000 | if (!skb) | ||
| 1001 | return NULL; | ||
| 1002 | } | ||
| 1003 | |||
| 1004 | return skb; | ||
| 1005 | } | ||
| 1006 | |||
| 993 | static netdev_tx_t be_xmit(struct sk_buff *skb, struct net_device *netdev) | 1007 | static netdev_tx_t be_xmit(struct sk_buff *skb, struct net_device *netdev) |
| 994 | { | 1008 | { |
| 995 | struct be_adapter *adapter = netdev_priv(netdev); | 1009 | struct be_adapter *adapter = netdev_priv(netdev); |
| @@ -1157,6 +1171,14 @@ ret: | |||
| 1157 | return status; | 1171 | return status; |
| 1158 | } | 1172 | } |
| 1159 | 1173 | ||
| 1174 | static void be_clear_promisc(struct be_adapter *adapter) | ||
| 1175 | { | ||
| 1176 | adapter->promiscuous = false; | ||
| 1177 | adapter->flags &= ~BE_FLAGS_VLAN_PROMISC; | ||
| 1178 | |||
| 1179 | be_cmd_rx_filter(adapter, IFF_PROMISC, OFF); | ||
| 1180 | } | ||
| 1181 | |||
| 1160 | static void be_set_rx_mode(struct net_device *netdev) | 1182 | static void be_set_rx_mode(struct net_device *netdev) |
| 1161 | { | 1183 | { |
| 1162 | struct be_adapter *adapter = netdev_priv(netdev); | 1184 | struct be_adapter *adapter = netdev_priv(netdev); |
| @@ -1170,9 +1192,7 @@ static void be_set_rx_mode(struct net_device *netdev) | |||
| 1170 | 1192 | ||
| 1171 | /* BE was previously in promiscuous mode; disable it */ | 1193 | /* BE was previously in promiscuous mode; disable it */ |
| 1172 | if (adapter->promiscuous) { | 1194 | if (adapter->promiscuous) { |
| 1173 | adapter->promiscuous = false; | 1195 | be_clear_promisc(adapter); |
| 1174 | be_cmd_rx_filter(adapter, IFF_PROMISC, OFF); | ||
| 1175 | |||
| 1176 | if (adapter->vlans_added) | 1196 | if (adapter->vlans_added) |
| 1177 | be_vid_config(adapter); | 1197 | be_vid_config(adapter); |
| 1178 | } | 1198 | } |
| @@ -1287,24 +1307,20 @@ static int be_set_vf_vlan(struct net_device *netdev, | |||
| 1287 | 1307 | ||
| 1288 | if (vlan || qos) { | 1308 | if (vlan || qos) { |
| 1289 | vlan |= qos << VLAN_PRIO_SHIFT; | 1309 | vlan |= qos << VLAN_PRIO_SHIFT; |
| 1290 | if (vf_cfg->vlan_tag != vlan) { | 1310 | if (vf_cfg->vlan_tag != vlan) |
| 1291 | /* If this is new value, program it. Else skip. */ | ||
| 1292 | vf_cfg->vlan_tag = vlan; | ||
| 1293 | status = be_cmd_set_hsw_config(adapter, vlan, vf + 1, | 1311 | status = be_cmd_set_hsw_config(adapter, vlan, vf + 1, |
| 1294 | vf_cfg->if_handle, 0); | 1312 | vf_cfg->if_handle, 0); |
| 1295 | } | ||
| 1296 | } else { | 1313 | } else { |
| 1297 | /* Reset Transparent Vlan Tagging. */ | 1314 | /* Reset Transparent Vlan Tagging. */ |
| 1298 | vf_cfg->vlan_tag = 0; | 1315 | status = be_cmd_set_hsw_config(adapter, BE_RESET_VLAN_TAG_ID, |
| 1299 | vlan = vf_cfg->def_vid; | 1316 | vf + 1, vf_cfg->if_handle, 0); |
| 1300 | status = be_cmd_set_hsw_config(adapter, vlan, vf + 1, | ||
| 1301 | vf_cfg->if_handle, 0); | ||
| 1302 | } | 1317 | } |
| 1303 | 1318 | ||
| 1304 | 1319 | if (!status) | |
| 1305 | if (status) | 1320 | vf_cfg->vlan_tag = vlan; |
| 1321 | else | ||
| 1306 | dev_info(&adapter->pdev->dev, | 1322 | dev_info(&adapter->pdev->dev, |
| 1307 | "VLAN %d config on VF %d failed\n", vlan, vf); | 1323 | "VLAN %d config on VF %d failed\n", vlan, vf); |
| 1308 | return status; | 1324 | return status; |
| 1309 | } | 1325 | } |
| 1310 | 1326 | ||
| @@ -3013,11 +3029,11 @@ static int be_vf_setup_init(struct be_adapter *adapter) | |||
| 3013 | 3029 | ||
| 3014 | static int be_vf_setup(struct be_adapter *adapter) | 3030 | static int be_vf_setup(struct be_adapter *adapter) |
| 3015 | { | 3031 | { |
| 3032 | struct device *dev = &adapter->pdev->dev; | ||
| 3016 | struct be_vf_cfg *vf_cfg; | 3033 | struct be_vf_cfg *vf_cfg; |
| 3017 | u16 def_vlan, lnk_speed; | ||
| 3018 | int status, old_vfs, vf; | 3034 | int status, old_vfs, vf; |
| 3019 | struct device *dev = &adapter->pdev->dev; | ||
| 3020 | u32 privileges; | 3035 | u32 privileges; |
| 3036 | u16 lnk_speed; | ||
| 3021 | 3037 | ||
| 3022 | old_vfs = pci_num_vf(adapter->pdev); | 3038 | old_vfs = pci_num_vf(adapter->pdev); |
| 3023 | if (old_vfs) { | 3039 | if (old_vfs) { |
| @@ -3084,12 +3100,6 @@ static int be_vf_setup(struct be_adapter *adapter) | |||
| 3084 | if (!status) | 3100 | if (!status) |
| 3085 | vf_cfg->tx_rate = lnk_speed; | 3101 | vf_cfg->tx_rate = lnk_speed; |
| 3086 | 3102 | ||
| 3087 | status = be_cmd_get_hsw_config(adapter, &def_vlan, | ||
| 3088 | vf + 1, vf_cfg->if_handle, NULL); | ||
| 3089 | if (status) | ||
| 3090 | goto err; | ||
| 3091 | vf_cfg->def_vid = def_vlan; | ||
| 3092 | |||
| 3093 | if (!old_vfs) | 3103 | if (!old_vfs) |
| 3094 | be_cmd_enable_vf(adapter, vf + 1); | 3104 | be_cmd_enable_vf(adapter, vf + 1); |
| 3095 | } | 3105 | } |
diff --git a/drivers/net/ethernet/ethoc.c b/drivers/net/ethernet/ethoc.c index 4de8cfd149cf..55e0fa03dc90 100644 --- a/drivers/net/ethernet/ethoc.c +++ b/drivers/net/ethernet/ethoc.c | |||
| @@ -13,6 +13,7 @@ | |||
| 13 | 13 | ||
| 14 | #include <linux/dma-mapping.h> | 14 | #include <linux/dma-mapping.h> |
| 15 | #include <linux/etherdevice.h> | 15 | #include <linux/etherdevice.h> |
| 16 | #include <linux/clk.h> | ||
| 16 | #include <linux/crc32.h> | 17 | #include <linux/crc32.h> |
| 17 | #include <linux/interrupt.h> | 18 | #include <linux/interrupt.h> |
| 18 | #include <linux/io.h> | 19 | #include <linux/io.h> |
| @@ -51,6 +52,7 @@ MODULE_PARM_DESC(buffer_size, "DMA buffer allocation size"); | |||
| 51 | #define ETH_HASH0 0x48 | 52 | #define ETH_HASH0 0x48 |
| 52 | #define ETH_HASH1 0x4c | 53 | #define ETH_HASH1 0x4c |
| 53 | #define ETH_TXCTRL 0x50 | 54 | #define ETH_TXCTRL 0x50 |
| 55 | #define ETH_END 0x54 | ||
| 54 | 56 | ||
| 55 | /* mode register */ | 57 | /* mode register */ |
| 56 | #define MODER_RXEN (1 << 0) /* receive enable */ | 58 | #define MODER_RXEN (1 << 0) /* receive enable */ |
| @@ -179,6 +181,7 @@ MODULE_PARM_DESC(buffer_size, "DMA buffer allocation size"); | |||
| 179 | * @membase: pointer to buffer memory region | 181 | * @membase: pointer to buffer memory region |
| 180 | * @dma_alloc: dma allocated buffer size | 182 | * @dma_alloc: dma allocated buffer size |
| 181 | * @io_region_size: I/O memory region size | 183 | * @io_region_size: I/O memory region size |
| 184 | * @num_bd: number of buffer descriptors | ||
| 182 | * @num_tx: number of send buffers | 185 | * @num_tx: number of send buffers |
| 183 | * @cur_tx: last send buffer written | 186 | * @cur_tx: last send buffer written |
| 184 | * @dty_tx: last buffer actually sent | 187 | * @dty_tx: last buffer actually sent |
| @@ -199,6 +202,7 @@ struct ethoc { | |||
| 199 | int dma_alloc; | 202 | int dma_alloc; |
| 200 | resource_size_t io_region_size; | 203 | resource_size_t io_region_size; |
| 201 | 204 | ||
| 205 | unsigned int num_bd; | ||
| 202 | unsigned int num_tx; | 206 | unsigned int num_tx; |
| 203 | unsigned int cur_tx; | 207 | unsigned int cur_tx; |
| 204 | unsigned int dty_tx; | 208 | unsigned int dty_tx; |
| @@ -216,6 +220,7 @@ struct ethoc { | |||
| 216 | 220 | ||
| 217 | struct phy_device *phy; | 221 | struct phy_device *phy; |
| 218 | struct mii_bus *mdio; | 222 | struct mii_bus *mdio; |
| 223 | struct clk *clk; | ||
| 219 | s8 phy_id; | 224 | s8 phy_id; |
| 220 | }; | 225 | }; |
| 221 | 226 | ||
| @@ -688,6 +693,11 @@ static int ethoc_mdio_probe(struct net_device *dev) | |||
| 688 | } | 693 | } |
| 689 | 694 | ||
| 690 | priv->phy = phy; | 695 | priv->phy = phy; |
| 696 | phy->advertising &= ~(ADVERTISED_1000baseT_Full | | ||
| 697 | ADVERTISED_1000baseT_Half); | ||
| 698 | phy->supported &= ~(SUPPORTED_1000baseT_Full | | ||
| 699 | SUPPORTED_1000baseT_Half); | ||
| 700 | |||
| 691 | return 0; | 701 | return 0; |
| 692 | } | 702 | } |
| 693 | 703 | ||
| @@ -890,6 +900,102 @@ out: | |||
| 890 | return NETDEV_TX_OK; | 900 | return NETDEV_TX_OK; |
| 891 | } | 901 | } |
| 892 | 902 | ||
| 903 | static int ethoc_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) | ||
| 904 | { | ||
| 905 | struct ethoc *priv = netdev_priv(dev); | ||
| 906 | struct phy_device *phydev = priv->phy; | ||
| 907 | |||
| 908 | if (!phydev) | ||
| 909 | return -EOPNOTSUPP; | ||
| 910 | |||
| 911 | return phy_ethtool_gset(phydev, cmd); | ||
| 912 | } | ||
| 913 | |||
| 914 | static int ethoc_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) | ||
| 915 | { | ||
| 916 | struct ethoc *priv = netdev_priv(dev); | ||
| 917 | struct phy_device *phydev = priv->phy; | ||
| 918 | |||
| 919 | if (!phydev) | ||
| 920 | return -EOPNOTSUPP; | ||
| 921 | |||
| 922 | return phy_ethtool_sset(phydev, cmd); | ||
| 923 | } | ||
| 924 | |||
| 925 | static int ethoc_get_regs_len(struct net_device *netdev) | ||
| 926 | { | ||
| 927 | return ETH_END; | ||
| 928 | } | ||
| 929 | |||
| 930 | static void ethoc_get_regs(struct net_device *dev, struct ethtool_regs *regs, | ||
| 931 | void *p) | ||
| 932 | { | ||
| 933 | struct ethoc *priv = netdev_priv(dev); | ||
| 934 | u32 *regs_buff = p; | ||
| 935 | unsigned i; | ||
| 936 | |||
| 937 | regs->version = 0; | ||
| 938 | for (i = 0; i < ETH_END / sizeof(u32); ++i) | ||
| 939 | regs_buff[i] = ethoc_read(priv, i * sizeof(u32)); | ||
| 940 | } | ||
| 941 | |||
| 942 | static void ethoc_get_ringparam(struct net_device *dev, | ||
| 943 | struct ethtool_ringparam *ring) | ||
| 944 | { | ||
| 945 | struct ethoc *priv = netdev_priv(dev); | ||
| 946 | |||
| 947 | ring->rx_max_pending = priv->num_bd - 1; | ||
| 948 | ring->rx_mini_max_pending = 0; | ||
| 949 | ring->rx_jumbo_max_pending = 0; | ||
| 950 | ring->tx_max_pending = priv->num_bd - 1; | ||
| 951 | |||
| 952 | ring->rx_pending = priv->num_rx; | ||
| 953 | ring->rx_mini_pending = 0; | ||
| 954 | ring->rx_jumbo_pending = 0; | ||
| 955 | ring->tx_pending = priv->num_tx; | ||
| 956 | } | ||
| 957 | |||
| 958 | static int ethoc_set_ringparam(struct net_device *dev, | ||
| 959 | struct ethtool_ringparam *ring) | ||
| 960 | { | ||
| 961 | struct ethoc *priv = netdev_priv(dev); | ||
| 962 | |||
| 963 | if (ring->tx_pending < 1 || ring->rx_pending < 1 || | ||
| 964 | ring->tx_pending + ring->rx_pending > priv->num_bd) | ||
| 965 | return -EINVAL; | ||
| 966 | if (ring->rx_mini_pending || ring->rx_jumbo_pending) | ||
| 967 | return -EINVAL; | ||
| 968 | |||
| 969 | if (netif_running(dev)) { | ||
| 970 | netif_tx_disable(dev); | ||
| 971 | ethoc_disable_rx_and_tx(priv); | ||
| 972 | ethoc_disable_irq(priv, INT_MASK_TX | INT_MASK_RX); | ||
| 973 | synchronize_irq(dev->irq); | ||
| 974 | } | ||
| 975 | |||
| 976 | priv->num_tx = rounddown_pow_of_two(ring->tx_pending); | ||
| 977 | priv->num_rx = ring->rx_pending; | ||
| 978 | ethoc_init_ring(priv, dev->mem_start); | ||
| 979 | |||
| 980 | if (netif_running(dev)) { | ||
| 981 | ethoc_enable_irq(priv, INT_MASK_TX | INT_MASK_RX); | ||
| 982 | ethoc_enable_rx_and_tx(priv); | ||
| 983 | netif_wake_queue(dev); | ||
| 984 | } | ||
| 985 | return 0; | ||
| 986 | } | ||
| 987 | |||
| 988 | const struct ethtool_ops ethoc_ethtool_ops = { | ||
| 989 | .get_settings = ethoc_get_settings, | ||
| 990 | .set_settings = ethoc_set_settings, | ||
| 991 | .get_regs_len = ethoc_get_regs_len, | ||
| 992 | .get_regs = ethoc_get_regs, | ||
| 993 | .get_link = ethtool_op_get_link, | ||
| 994 | .get_ringparam = ethoc_get_ringparam, | ||
| 995 | .set_ringparam = ethoc_set_ringparam, | ||
| 996 | .get_ts_info = ethtool_op_get_ts_info, | ||
| 997 | }; | ||
| 998 | |||
| 893 | static const struct net_device_ops ethoc_netdev_ops = { | 999 | static const struct net_device_ops ethoc_netdev_ops = { |
| 894 | .ndo_open = ethoc_open, | 1000 | .ndo_open = ethoc_open, |
| 895 | .ndo_stop = ethoc_stop, | 1001 | .ndo_stop = ethoc_stop, |
| @@ -917,6 +1023,8 @@ static int ethoc_probe(struct platform_device *pdev) | |||
| 917 | int num_bd; | 1023 | int num_bd; |
| 918 | int ret = 0; | 1024 | int ret = 0; |
| 919 | bool random_mac = false; | 1025 | bool random_mac = false; |
| 1026 | struct ethoc_platform_data *pdata = dev_get_platdata(&pdev->dev); | ||
| 1027 | u32 eth_clkfreq = pdata ? pdata->eth_clkfreq : 0; | ||
| 920 | 1028 | ||
| 921 | /* allocate networking device */ | 1029 | /* allocate networking device */ |
| 922 | netdev = alloc_etherdev(sizeof(struct ethoc)); | 1030 | netdev = alloc_etherdev(sizeof(struct ethoc)); |
| @@ -1016,6 +1124,7 @@ static int ethoc_probe(struct platform_device *pdev) | |||
| 1016 | ret = -ENODEV; | 1124 | ret = -ENODEV; |
| 1017 | goto error; | 1125 | goto error; |
| 1018 | } | 1126 | } |
| 1127 | priv->num_bd = num_bd; | ||
| 1019 | /* num_tx must be a power of two */ | 1128 | /* num_tx must be a power of two */ |
| 1020 | priv->num_tx = rounddown_pow_of_two(num_bd >> 1); | 1129 | priv->num_tx = rounddown_pow_of_two(num_bd >> 1); |
| 1021 | priv->num_rx = num_bd - priv->num_tx; | 1130 | priv->num_rx = num_bd - priv->num_tx; |
| @@ -1030,8 +1139,7 @@ static int ethoc_probe(struct platform_device *pdev) | |||
| 1030 | } | 1139 | } |
| 1031 | 1140 | ||
| 1032 | /* Allow the platform setup code to pass in a MAC address. */ | 1141 | /* Allow the platform setup code to pass in a MAC address. */ |
| 1033 | if (dev_get_platdata(&pdev->dev)) { | 1142 | if (pdata) { |
| 1034 | struct ethoc_platform_data *pdata = dev_get_platdata(&pdev->dev); | ||
| 1035 | memcpy(netdev->dev_addr, pdata->hwaddr, IFHWADDRLEN); | 1143 | memcpy(netdev->dev_addr, pdata->hwaddr, IFHWADDRLEN); |
| 1036 | priv->phy_id = pdata->phy_id; | 1144 | priv->phy_id = pdata->phy_id; |
| 1037 | } else { | 1145 | } else { |
| @@ -1069,6 +1177,27 @@ static int ethoc_probe(struct platform_device *pdev) | |||
| 1069 | if (random_mac) | 1177 | if (random_mac) |
| 1070 | netdev->addr_assign_type = NET_ADDR_RANDOM; | 1178 | netdev->addr_assign_type = NET_ADDR_RANDOM; |
| 1071 | 1179 | ||
| 1180 | /* Allow the platform setup code to adjust MII management bus clock. */ | ||
| 1181 | if (!eth_clkfreq) { | ||
| 1182 | struct clk *clk = devm_clk_get(&pdev->dev, NULL); | ||
| 1183 | |||
| 1184 | if (!IS_ERR(clk)) { | ||
| 1185 | priv->clk = clk; | ||
| 1186 | clk_prepare_enable(clk); | ||
| 1187 | eth_clkfreq = clk_get_rate(clk); | ||
| 1188 | } | ||
| 1189 | } | ||
| 1190 | if (eth_clkfreq) { | ||
| 1191 | u32 clkdiv = MIIMODER_CLKDIV(eth_clkfreq / 2500000 + 1); | ||
| 1192 | |||
| 1193 | if (!clkdiv) | ||
| 1194 | clkdiv = 2; | ||
| 1195 | dev_dbg(&pdev->dev, "setting MII clkdiv to %u\n", clkdiv); | ||
| 1196 | ethoc_write(priv, MIIMODER, | ||
| 1197 | (ethoc_read(priv, MIIMODER) & MIIMODER_NOPRE) | | ||
| 1198 | clkdiv); | ||
| 1199 | } | ||
| 1200 | |||
| 1072 | /* register MII bus */ | 1201 | /* register MII bus */ |
| 1073 | priv->mdio = mdiobus_alloc(); | 1202 | priv->mdio = mdiobus_alloc(); |
| 1074 | if (!priv->mdio) { | 1203 | if (!priv->mdio) { |
| @@ -1111,6 +1240,7 @@ static int ethoc_probe(struct platform_device *pdev) | |||
| 1111 | netdev->netdev_ops = ðoc_netdev_ops; | 1240 | netdev->netdev_ops = ðoc_netdev_ops; |
| 1112 | netdev->watchdog_timeo = ETHOC_TIMEOUT; | 1241 | netdev->watchdog_timeo = ETHOC_TIMEOUT; |
| 1113 | netdev->features |= 0; | 1242 | netdev->features |= 0; |
| 1243 | netdev->ethtool_ops = ðoc_ethtool_ops; | ||
| 1114 | 1244 | ||
| 1115 | /* setup NAPI */ | 1245 | /* setup NAPI */ |
| 1116 | netif_napi_add(netdev, &priv->napi, ethoc_poll, 64); | 1246 | netif_napi_add(netdev, &priv->napi, ethoc_poll, 64); |
| @@ -1133,6 +1263,8 @@ free_mdio: | |||
| 1133 | kfree(priv->mdio->irq); | 1263 | kfree(priv->mdio->irq); |
| 1134 | mdiobus_free(priv->mdio); | 1264 | mdiobus_free(priv->mdio); |
| 1135 | free: | 1265 | free: |
| 1266 | if (priv->clk) | ||
| 1267 | clk_disable_unprepare(priv->clk); | ||
| 1136 | free_netdev(netdev); | 1268 | free_netdev(netdev); |
| 1137 | out: | 1269 | out: |
| 1138 | return ret; | 1270 | return ret; |
| @@ -1157,6 +1289,8 @@ static int ethoc_remove(struct platform_device *pdev) | |||
| 1157 | kfree(priv->mdio->irq); | 1289 | kfree(priv->mdio->irq); |
| 1158 | mdiobus_free(priv->mdio); | 1290 | mdiobus_free(priv->mdio); |
| 1159 | } | 1291 | } |
| 1292 | if (priv->clk) | ||
| 1293 | clk_disable_unprepare(priv->clk); | ||
| 1160 | unregister_netdev(netdev); | 1294 | unregister_netdev(netdev); |
| 1161 | free_netdev(netdev); | 1295 | free_netdev(netdev); |
| 1162 | } | 1296 | } |
diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c index d4782b42401b..479a7cba45c0 100644 --- a/drivers/net/ethernet/freescale/fec_main.c +++ b/drivers/net/ethernet/freescale/fec_main.c | |||
| @@ -389,12 +389,6 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *ndev) | |||
| 389 | netdev_err(ndev, "Tx DMA memory map failed\n"); | 389 | netdev_err(ndev, "Tx DMA memory map failed\n"); |
| 390 | return NETDEV_TX_OK; | 390 | return NETDEV_TX_OK; |
| 391 | } | 391 | } |
| 392 | /* Send it on its way. Tell FEC it's ready, interrupt when done, | ||
| 393 | * it's the last BD of the frame, and to put the CRC on the end. | ||
| 394 | */ | ||
| 395 | status |= (BD_ENET_TX_READY | BD_ENET_TX_INTR | ||
| 396 | | BD_ENET_TX_LAST | BD_ENET_TX_TC); | ||
| 397 | bdp->cbd_sc = status; | ||
| 398 | 392 | ||
| 399 | if (fep->bufdesc_ex) { | 393 | if (fep->bufdesc_ex) { |
| 400 | 394 | ||
| @@ -416,6 +410,13 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *ndev) | |||
| 416 | } | 410 | } |
| 417 | } | 411 | } |
| 418 | 412 | ||
| 413 | /* Send it on its way. Tell FEC it's ready, interrupt when done, | ||
| 414 | * it's the last BD of the frame, and to put the CRC on the end. | ||
| 415 | */ | ||
| 416 | status |= (BD_ENET_TX_READY | BD_ENET_TX_INTR | ||
| 417 | | BD_ENET_TX_LAST | BD_ENET_TX_TC); | ||
| 418 | bdp->cbd_sc = status; | ||
| 419 | |||
| 419 | bdp_pre = fec_enet_get_prevdesc(bdp, fep); | 420 | bdp_pre = fec_enet_get_prevdesc(bdp, fep); |
| 420 | if ((id_entry->driver_data & FEC_QUIRK_ERR006358) && | 421 | if ((id_entry->driver_data & FEC_QUIRK_ERR006358) && |
| 421 | !(bdp_pre->cbd_sc & BD_ENET_TX_READY)) { | 422 | !(bdp_pre->cbd_sc & BD_ENET_TX_READY)) { |
| @@ -1778,8 +1779,6 @@ fec_enet_open(struct net_device *ndev) | |||
| 1778 | struct fec_enet_private *fep = netdev_priv(ndev); | 1779 | struct fec_enet_private *fep = netdev_priv(ndev); |
| 1779 | int ret; | 1780 | int ret; |
| 1780 | 1781 | ||
| 1781 | napi_enable(&fep->napi); | ||
| 1782 | |||
| 1783 | /* I should reset the ring buffers here, but I don't yet know | 1782 | /* I should reset the ring buffers here, but I don't yet know |
| 1784 | * a simple way to do that. | 1783 | * a simple way to do that. |
| 1785 | */ | 1784 | */ |
| @@ -1794,6 +1793,8 @@ fec_enet_open(struct net_device *ndev) | |||
| 1794 | fec_enet_free_buffers(ndev); | 1793 | fec_enet_free_buffers(ndev); |
| 1795 | return ret; | 1794 | return ret; |
| 1796 | } | 1795 | } |
| 1796 | |||
| 1797 | napi_enable(&fep->napi); | ||
| 1797 | phy_start(fep->phy_dev); | 1798 | phy_start(fep->phy_dev); |
| 1798 | netif_start_queue(ndev); | 1799 | netif_start_queue(ndev); |
| 1799 | fep->opened = 1; | 1800 | fep->opened = 1; |
diff --git a/drivers/net/ethernet/intel/e100.c b/drivers/net/ethernet/intel/e100.c index cbaba4442d4b..bf7a01ef9a57 100644 --- a/drivers/net/ethernet/intel/e100.c +++ b/drivers/net/ethernet/intel/e100.c | |||
| @@ -3034,7 +3034,7 @@ static void __e100_shutdown(struct pci_dev *pdev, bool *enable_wake) | |||
| 3034 | *enable_wake = false; | 3034 | *enable_wake = false; |
| 3035 | } | 3035 | } |
| 3036 | 3036 | ||
| 3037 | pci_disable_device(pdev); | 3037 | pci_clear_master(pdev); |
| 3038 | } | 3038 | } |
| 3039 | 3039 | ||
| 3040 | static int __e100_power_off(struct pci_dev *pdev, bool wake) | 3040 | static int __e100_power_off(struct pci_dev *pdev, bool wake) |
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index 6d4ada72dfd0..18076c4178b4 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | |||
| @@ -6881,7 +6881,7 @@ static inline int ixgbe_maybe_stop_tx(struct ixgbe_ring *tx_ring, u16 size) | |||
| 6881 | } | 6881 | } |
| 6882 | 6882 | ||
| 6883 | static u16 ixgbe_select_queue(struct net_device *dev, struct sk_buff *skb, | 6883 | static u16 ixgbe_select_queue(struct net_device *dev, struct sk_buff *skb, |
| 6884 | void *accel_priv) | 6884 | void *accel_priv, select_queue_fallback_t fallback) |
| 6885 | { | 6885 | { |
| 6886 | struct ixgbe_fwd_adapter *fwd_adapter = accel_priv; | 6886 | struct ixgbe_fwd_adapter *fwd_adapter = accel_priv; |
| 6887 | #ifdef IXGBE_FCOE | 6887 | #ifdef IXGBE_FCOE |
| @@ -6907,7 +6907,7 @@ static u16 ixgbe_select_queue(struct net_device *dev, struct sk_buff *skb, | |||
| 6907 | if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED) | 6907 | if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED) |
| 6908 | break; | 6908 | break; |
| 6909 | default: | 6909 | default: |
| 6910 | return __netdev_pick_tx(dev, skb); | 6910 | return fallback(dev, skb); |
| 6911 | } | 6911 | } |
| 6912 | 6912 | ||
| 6913 | f = &adapter->ring_feature[RING_F_FCOE]; | 6913 | f = &adapter->ring_feature[RING_F_FCOE]; |
| @@ -6920,7 +6920,7 @@ static u16 ixgbe_select_queue(struct net_device *dev, struct sk_buff *skb, | |||
| 6920 | 6920 | ||
| 6921 | return txq + f->offset; | 6921 | return txq + f->offset; |
| 6922 | #else | 6922 | #else |
| 6923 | return __netdev_pick_tx(dev, skb); | 6923 | return fallback(dev, skb); |
| 6924 | #endif | 6924 | #endif |
| 6925 | } | 6925 | } |
| 6926 | 6926 | ||
diff --git a/drivers/net/ethernet/lantiq_etop.c b/drivers/net/ethernet/lantiq_etop.c index 8f9266c64c75..fd4b6aecf6ee 100644 --- a/drivers/net/ethernet/lantiq_etop.c +++ b/drivers/net/ethernet/lantiq_etop.c | |||
| @@ -619,7 +619,7 @@ ltq_etop_set_multicast_list(struct net_device *dev) | |||
| 619 | 619 | ||
| 620 | static u16 | 620 | static u16 |
| 621 | ltq_etop_select_queue(struct net_device *dev, struct sk_buff *skb, | 621 | ltq_etop_select_queue(struct net_device *dev, struct sk_buff *skb, |
| 622 | void *accel_priv) | 622 | void *accel_priv, select_queue_fallback_t fallback) |
| 623 | { | 623 | { |
| 624 | /* we are currently only using the first queue */ | 624 | /* we are currently only using the first queue */ |
| 625 | return 0; | 625 | return 0; |
diff --git a/drivers/net/ethernet/marvell/Kconfig b/drivers/net/ethernet/marvell/Kconfig index 6300fd27f2db..68e6a6613e9a 100644 --- a/drivers/net/ethernet/marvell/Kconfig +++ b/drivers/net/ethernet/marvell/Kconfig | |||
| @@ -43,12 +43,12 @@ config MVMDIO | |||
| 43 | This driver is used by the MV643XX_ETH and MVNETA drivers. | 43 | This driver is used by the MV643XX_ETH and MVNETA drivers. |
| 44 | 44 | ||
| 45 | config MVNETA | 45 | config MVNETA |
| 46 | tristate "Marvell Armada 370/XP network interface support" | 46 | tristate "Marvell Armada 370/38x/XP network interface support" |
| 47 | depends on MACH_ARMADA_370_XP | 47 | depends on PLAT_ORION |
| 48 | select MVMDIO | 48 | select MVMDIO |
| 49 | ---help--- | 49 | ---help--- |
| 50 | This driver supports the network interface units in the | 50 | This driver supports the network interface units in the |
| 51 | Marvell ARMADA XP and ARMADA 370 SoC family. | 51 | Marvell ARMADA XP, ARMADA 370 and ARMADA 38x SoC family. |
| 52 | 52 | ||
| 53 | Note that this driver is distinct from the mv643xx_eth | 53 | Note that this driver is distinct from the mv643xx_eth |
| 54 | driver, which should be used for the older Marvell SoCs | 54 | driver, which should be used for the older Marvell SoCs |
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_tx.c b/drivers/net/ethernet/mellanox/mlx4/en_tx.c index 8e8a7eb43a2c..13457032d15f 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_tx.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_tx.c | |||
| @@ -629,7 +629,7 @@ static void build_inline_wqe(struct mlx4_en_tx_desc *tx_desc, struct sk_buff *sk | |||
| 629 | } | 629 | } |
| 630 | 630 | ||
| 631 | u16 mlx4_en_select_queue(struct net_device *dev, struct sk_buff *skb, | 631 | u16 mlx4_en_select_queue(struct net_device *dev, struct sk_buff *skb, |
| 632 | void *accel_priv) | 632 | void *accel_priv, select_queue_fallback_t fallback) |
| 633 | { | 633 | { |
| 634 | struct mlx4_en_priv *priv = netdev_priv(dev); | 634 | struct mlx4_en_priv *priv = netdev_priv(dev); |
| 635 | u16 rings_p_up = priv->num_tx_rings_p_up; | 635 | u16 rings_p_up = priv->num_tx_rings_p_up; |
| @@ -641,7 +641,7 @@ u16 mlx4_en_select_queue(struct net_device *dev, struct sk_buff *skb, | |||
| 641 | if (vlan_tx_tag_present(skb)) | 641 | if (vlan_tx_tag_present(skb)) |
| 642 | up = vlan_tx_tag_get(skb) >> VLAN_PRIO_SHIFT; | 642 | up = vlan_tx_tag_get(skb) >> VLAN_PRIO_SHIFT; |
| 643 | 643 | ||
| 644 | return __netdev_pick_tx(dev, skb) % rings_p_up + up * rings_p_up; | 644 | return fallback(dev, skb) % rings_p_up + up * rings_p_up; |
| 645 | } | 645 | } |
| 646 | 646 | ||
| 647 | static void mlx4_bf_copy(void __iomem *dst, unsigned long *src, unsigned bytecnt) | 647 | static void mlx4_bf_copy(void __iomem *dst, unsigned long *src, unsigned bytecnt) |
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4.h b/drivers/net/ethernet/mellanox/mlx4/mlx4.h index 6b65f7795215..7aec6c833973 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mlx4.h +++ b/drivers/net/ethernet/mellanox/mlx4/mlx4.h | |||
| @@ -51,8 +51,8 @@ | |||
| 51 | 51 | ||
| 52 | #define DRV_NAME "mlx4_core" | 52 | #define DRV_NAME "mlx4_core" |
| 53 | #define PFX DRV_NAME ": " | 53 | #define PFX DRV_NAME ": " |
| 54 | #define DRV_VERSION "1.1" | 54 | #define DRV_VERSION "2.2-1" |
| 55 | #define DRV_RELDATE "Dec, 2011" | 55 | #define DRV_RELDATE "Feb, 2014" |
| 56 | 56 | ||
| 57 | #define MLX4_FS_UDP_UC_EN (1 << 1) | 57 | #define MLX4_FS_UDP_UC_EN (1 << 1) |
| 58 | #define MLX4_FS_TCP_UC_EN (1 << 2) | 58 | #define MLX4_FS_TCP_UC_EN (1 << 2) |
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h index 3af04c3f42ea..b57e8c87a34e 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h +++ b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h | |||
| @@ -57,8 +57,8 @@ | |||
| 57 | #include "en_port.h" | 57 | #include "en_port.h" |
| 58 | 58 | ||
| 59 | #define DRV_NAME "mlx4_en" | 59 | #define DRV_NAME "mlx4_en" |
| 60 | #define DRV_VERSION "2.0" | 60 | #define DRV_VERSION "2.2-1" |
| 61 | #define DRV_RELDATE "Dec 2011" | 61 | #define DRV_RELDATE "Feb 2014" |
| 62 | 62 | ||
| 63 | #define MLX4_EN_MSG_LEVEL (NETIF_MSG_LINK | NETIF_MSG_IFDOWN) | 63 | #define MLX4_EN_MSG_LEVEL (NETIF_MSG_LINK | NETIF_MSG_IFDOWN) |
| 64 | 64 | ||
| @@ -723,7 +723,7 @@ int mlx4_en_arm_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq); | |||
| 723 | 723 | ||
| 724 | void mlx4_en_tx_irq(struct mlx4_cq *mcq); | 724 | void mlx4_en_tx_irq(struct mlx4_cq *mcq); |
| 725 | u16 mlx4_en_select_queue(struct net_device *dev, struct sk_buff *skb, | 725 | u16 mlx4_en_select_queue(struct net_device *dev, struct sk_buff *skb, |
| 726 | void *accel_priv); | 726 | void *accel_priv, select_queue_fallback_t fallback); |
| 727 | netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev); | 727 | netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev); |
| 728 | 728 | ||
| 729 | int mlx4_en_create_tx_ring(struct mlx4_en_priv *priv, | 729 | int mlx4_en_create_tx_ring(struct mlx4_en_priv *priv, |
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/Kconfig b/drivers/net/ethernet/mellanox/mlx5/core/Kconfig index 157fe8df2c3e..8ff57e8e3e91 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/Kconfig +++ b/drivers/net/ethernet/mellanox/mlx5/core/Kconfig | |||
| @@ -4,5 +4,5 @@ | |||
| 4 | 4 | ||
| 5 | config MLX5_CORE | 5 | config MLX5_CORE |
| 6 | tristate | 6 | tristate |
| 7 | depends on PCI && X86 | 7 | depends on PCI |
| 8 | default n | 8 | default n |
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c index a064f06e0cb8..23b7e2d35a93 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/main.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c | |||
| @@ -46,8 +46,8 @@ | |||
| 46 | #include "mlx5_core.h" | 46 | #include "mlx5_core.h" |
| 47 | 47 | ||
| 48 | #define DRIVER_NAME "mlx5_core" | 48 | #define DRIVER_NAME "mlx5_core" |
| 49 | #define DRIVER_VERSION "1.0" | 49 | #define DRIVER_VERSION "2.2-1" |
| 50 | #define DRIVER_RELDATE "June 2013" | 50 | #define DRIVER_RELDATE "Feb 2014" |
| 51 | 51 | ||
| 52 | MODULE_AUTHOR("Eli Cohen <eli@mellanox.com>"); | 52 | MODULE_AUTHOR("Eli Cohen <eli@mellanox.com>"); |
| 53 | MODULE_DESCRIPTION("Mellanox ConnectX-IB HCA core library"); | 53 | MODULE_DESCRIPTION("Mellanox ConnectX-IB HCA core library"); |
diff --git a/drivers/net/ethernet/neterion/vxge/vxge-main.c b/drivers/net/ethernet/neterion/vxge/vxge-main.c index 1ded50ca1600..e46e8698e630 100644 --- a/drivers/net/ethernet/neterion/vxge/vxge-main.c +++ b/drivers/net/ethernet/neterion/vxge/vxge-main.c | |||
| @@ -726,9 +726,6 @@ static int vxge_learn_mac(struct vxgedev *vdev, u8 *mac_header) | |||
| 726 | int vpath_idx = 0; | 726 | int vpath_idx = 0; |
| 727 | enum vxge_hw_status status = VXGE_HW_OK; | 727 | enum vxge_hw_status status = VXGE_HW_OK; |
| 728 | struct vxge_vpath *vpath = NULL; | 728 | struct vxge_vpath *vpath = NULL; |
| 729 | struct __vxge_hw_device *hldev; | ||
| 730 | |||
| 731 | hldev = pci_get_drvdata(vdev->pdev); | ||
| 732 | 729 | ||
| 733 | mac_address = (u8 *)&mac_addr; | 730 | mac_address = (u8 *)&mac_addr; |
| 734 | memcpy(mac_address, mac_header, ETH_ALEN); | 731 | memcpy(mac_address, mac_header, ETH_ALEN); |
| @@ -2443,9 +2440,6 @@ static void vxge_rem_msix_isr(struct vxgedev *vdev) | |||
| 2443 | 2440 | ||
| 2444 | static void vxge_rem_isr(struct vxgedev *vdev) | 2441 | static void vxge_rem_isr(struct vxgedev *vdev) |
| 2445 | { | 2442 | { |
| 2446 | struct __vxge_hw_device *hldev; | ||
| 2447 | hldev = pci_get_drvdata(vdev->pdev); | ||
| 2448 | |||
| 2449 | #ifdef CONFIG_PCI_MSI | 2443 | #ifdef CONFIG_PCI_MSI |
| 2450 | if (vdev->config.intr_type == MSI_X) { | 2444 | if (vdev->config.intr_type == MSI_X) { |
| 2451 | vxge_rem_msix_isr(vdev); | 2445 | vxge_rem_msix_isr(vdev); |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c index 4146664d4d6a..27c4f131863b 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c | |||
| @@ -340,6 +340,7 @@ int qlcnic_83xx_setup_intr(struct qlcnic_adapter *adapter) | |||
| 340 | if (qlcnic_sriov_vf_check(adapter)) | 340 | if (qlcnic_sriov_vf_check(adapter)) |
| 341 | return -EINVAL; | 341 | return -EINVAL; |
| 342 | num_msix = 1; | 342 | num_msix = 1; |
| 343 | adapter->drv_sds_rings = QLCNIC_SINGLE_RING; | ||
| 343 | adapter->drv_tx_rings = QLCNIC_SINGLE_RING; | 344 | adapter->drv_tx_rings = QLCNIC_SINGLE_RING; |
| 344 | } | 345 | } |
| 345 | } | 346 | } |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.c index 77f1bce432d2..7d4f54912bad 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.c | |||
| @@ -807,7 +807,7 @@ qlcnic_dcb_get_pg_tc_cfg_tx(struct net_device *netdev, int tc, u8 *prio, | |||
| 807 | !type->tc_param_valid) | 807 | !type->tc_param_valid) |
| 808 | return; | 808 | return; |
| 809 | 809 | ||
| 810 | if (tc < 0 || (tc > QLC_DCB_MAX_TC)) | 810 | if (tc < 0 || (tc >= QLC_DCB_MAX_TC)) |
| 811 | return; | 811 | return; |
| 812 | 812 | ||
| 813 | tc_cfg = &type->tc_cfg[tc]; | 813 | tc_cfg = &type->tc_cfg[tc]; |
| @@ -843,7 +843,7 @@ static void qlcnic_dcb_get_pg_bwg_cfg_tx(struct net_device *netdev, int pgid, | |||
| 843 | !type->tc_param_valid) | 843 | !type->tc_param_valid) |
| 844 | return; | 844 | return; |
| 845 | 845 | ||
| 846 | if (pgid < 0 || pgid > QLC_DCB_MAX_PG) | 846 | if (pgid < 0 || pgid >= QLC_DCB_MAX_PG) |
| 847 | return; | 847 | return; |
| 848 | 848 | ||
| 849 | pgcfg = &type->pg_cfg[pgid]; | 849 | pgcfg = &type->pg_cfg[pgid]; |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c index ba78c7481fa3..1222865cfb73 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | |||
| @@ -816,9 +816,10 @@ static int qlcnic_82xx_setup_intr(struct qlcnic_adapter *adapter) | |||
| 816 | 816 | ||
| 817 | if (!(adapter->flags & QLCNIC_MSIX_ENABLED)) { | 817 | if (!(adapter->flags & QLCNIC_MSIX_ENABLED)) { |
| 818 | qlcnic_disable_multi_tx(adapter); | 818 | qlcnic_disable_multi_tx(adapter); |
| 819 | adapter->drv_sds_rings = QLCNIC_SINGLE_RING; | ||
| 819 | 820 | ||
| 820 | err = qlcnic_enable_msi_legacy(adapter); | 821 | err = qlcnic_enable_msi_legacy(adapter); |
| 821 | if (!err) | 822 | if (err) |
| 822 | return err; | 823 | return err; |
| 823 | } | 824 | } |
| 824 | } | 825 | } |
| @@ -3863,7 +3864,7 @@ int qlcnic_validate_rings(struct qlcnic_adapter *adapter, __u32 ring_cnt, | |||
| 3863 | strcpy(buf, "Tx"); | 3864 | strcpy(buf, "Tx"); |
| 3864 | } | 3865 | } |
| 3865 | 3866 | ||
| 3866 | if (!qlcnic_use_msi_x && !qlcnic_use_msi) { | 3867 | if (!QLCNIC_IS_MSI_FAMILY(adapter)) { |
| 3867 | netdev_err(netdev, "No RSS/TSS support in INT-x mode\n"); | 3868 | netdev_err(netdev, "No RSS/TSS support in INT-x mode\n"); |
| 3868 | return -EINVAL; | 3869 | return -EINVAL; |
| 3869 | } | 3870 | } |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c index 09acf15c3a56..e5277a632671 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c | |||
| @@ -13,8 +13,6 @@ | |||
| 13 | #define QLC_VF_MIN_TX_RATE 100 | 13 | #define QLC_VF_MIN_TX_RATE 100 |
| 14 | #define QLC_VF_MAX_TX_RATE 9999 | 14 | #define QLC_VF_MAX_TX_RATE 9999 |
| 15 | #define QLC_MAC_OPCODE_MASK 0x7 | 15 | #define QLC_MAC_OPCODE_MASK 0x7 |
| 16 | #define QLC_MAC_STAR_ADD 6 | ||
| 17 | #define QLC_MAC_STAR_DEL 7 | ||
| 18 | #define QLC_VF_FLOOD_BIT BIT_16 | 16 | #define QLC_VF_FLOOD_BIT BIT_16 |
| 19 | #define QLC_FLOOD_MODE 0x5 | 17 | #define QLC_FLOOD_MODE 0x5 |
| 20 | 18 | ||
| @@ -1206,13 +1204,6 @@ static int qlcnic_sriov_validate_cfg_macvlan(struct qlcnic_adapter *adapter, | |||
| 1206 | struct qlcnic_vport *vp = vf->vp; | 1204 | struct qlcnic_vport *vp = vf->vp; |
| 1207 | u8 op, new_op; | 1205 | u8 op, new_op; |
| 1208 | 1206 | ||
| 1209 | if (((cmd->req.arg[1] & QLC_MAC_OPCODE_MASK) == QLC_MAC_STAR_ADD) || | ||
| 1210 | ((cmd->req.arg[1] & QLC_MAC_OPCODE_MASK) == QLC_MAC_STAR_DEL)) { | ||
| 1211 | netdev_err(adapter->netdev, "MAC + any VLAN filter not allowed from VF %d\n", | ||
| 1212 | vf->pci_func); | ||
| 1213 | return -EINVAL; | ||
| 1214 | } | ||
| 1215 | |||
| 1216 | if (!(cmd->req.arg[1] & BIT_8)) | 1207 | if (!(cmd->req.arg[1] & BIT_8)) |
| 1217 | return -EINVAL; | 1208 | return -EINVAL; |
| 1218 | 1209 | ||
diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index 91a67ae8f17b..e9779653cd4c 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c | |||
| @@ -7118,6 +7118,8 @@ rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
| 7118 | } | 7118 | } |
| 7119 | 7119 | ||
| 7120 | mutex_init(&tp->wk.mutex); | 7120 | mutex_init(&tp->wk.mutex); |
| 7121 | u64_stats_init(&tp->rx_stats.syncp); | ||
| 7122 | u64_stats_init(&tp->tx_stats.syncp); | ||
| 7121 | 7123 | ||
| 7122 | /* Get MAC address */ | 7124 | /* Get MAC address */ |
| 7123 | for (i = 0; i < ETH_ALEN; i++) | 7125 | for (i = 0; i < ETH_ALEN; i++) |
diff --git a/drivers/net/ethernet/sfc/ptp.c b/drivers/net/ethernet/sfc/ptp.c index eb75fbd11a01..d7a36829649a 100644 --- a/drivers/net/ethernet/sfc/ptp.c +++ b/drivers/net/ethernet/sfc/ptp.c | |||
| @@ -1668,6 +1668,13 @@ void efx_ptp_event(struct efx_nic *efx, efx_qword_t *ev) | |||
| 1668 | struct efx_ptp_data *ptp = efx->ptp_data; | 1668 | struct efx_ptp_data *ptp = efx->ptp_data; |
| 1669 | int code = EFX_QWORD_FIELD(*ev, MCDI_EVENT_CODE); | 1669 | int code = EFX_QWORD_FIELD(*ev, MCDI_EVENT_CODE); |
| 1670 | 1670 | ||
| 1671 | if (!ptp) { | ||
| 1672 | if (net_ratelimit()) | ||
| 1673 | netif_warn(efx, drv, efx->net_dev, | ||
| 1674 | "Received PTP event but PTP not set up\n"); | ||
| 1675 | return; | ||
| 1676 | } | ||
| 1677 | |||
| 1671 | if (!ptp->enabled) | 1678 | if (!ptp->enabled) |
| 1672 | return; | 1679 | return; |
| 1673 | 1680 | ||
diff --git a/drivers/net/ethernet/sfc/tx.c b/drivers/net/ethernet/sfc/tx.c index c49d1fb16965..75d11fa4eb0a 100644 --- a/drivers/net/ethernet/sfc/tx.c +++ b/drivers/net/ethernet/sfc/tx.c | |||
| @@ -429,7 +429,9 @@ netdev_tx_t efx_enqueue_skb(struct efx_tx_queue *tx_queue, struct sk_buff *skb) | |||
| 429 | } | 429 | } |
| 430 | 430 | ||
| 431 | /* Transfer ownership of the skb to the final buffer */ | 431 | /* Transfer ownership of the skb to the final buffer */ |
| 432 | #ifdef EFX_USE_PIO | ||
| 432 | finish_packet: | 433 | finish_packet: |
| 434 | #endif | ||
| 433 | buffer->skb = skb; | 435 | buffer->skb = skb; |
| 434 | buffer->flags = EFX_TX_BUF_SKB | dma_flags; | 436 | buffer->flags = EFX_TX_BUF_SKB | dma_flags; |
| 435 | 437 | ||
diff --git a/drivers/net/ethernet/stmicro/stmmac/Kconfig b/drivers/net/ethernet/stmicro/stmmac/Kconfig index e2f202e3932f..f2d7c702c77f 100644 --- a/drivers/net/ethernet/stmicro/stmmac/Kconfig +++ b/drivers/net/ethernet/stmicro/stmmac/Kconfig | |||
| @@ -37,6 +37,17 @@ config DWMAC_SUNXI | |||
| 37 | stmmac device driver. This driver is used for A20/A31 | 37 | stmmac device driver. This driver is used for A20/A31 |
| 38 | GMAC ethernet controller. | 38 | GMAC ethernet controller. |
| 39 | 39 | ||
| 40 | config DWMAC_STI | ||
| 41 | bool "STi GMAC support" | ||
| 42 | depends on STMMAC_PLATFORM && ARCH_STI | ||
| 43 | default y | ||
| 44 | ---help--- | ||
| 45 | Support for ethernet controller on STi SOCs. | ||
| 46 | |||
| 47 | This selects STi SoC glue layer support for the stmmac | ||
| 48 | device driver. This driver is used on for the STi series | ||
| 49 | SOCs GMAC ethernet controller. | ||
| 50 | |||
| 40 | config STMMAC_PCI | 51 | config STMMAC_PCI |
| 41 | bool "STMMAC PCI bus support" | 52 | bool "STMMAC PCI bus support" |
| 42 | depends on STMMAC_ETH && PCI | 53 | depends on STMMAC_ETH && PCI |
diff --git a/drivers/net/ethernet/stmicro/stmmac/Makefile b/drivers/net/ethernet/stmicro/stmmac/Makefile index ecadecea79b2..dcef28775dad 100644 --- a/drivers/net/ethernet/stmicro/stmmac/Makefile +++ b/drivers/net/ethernet/stmicro/stmmac/Makefile | |||
| @@ -2,6 +2,7 @@ obj-$(CONFIG_STMMAC_ETH) += stmmac.o | |||
| 2 | stmmac-$(CONFIG_STMMAC_PLATFORM) += stmmac_platform.o | 2 | stmmac-$(CONFIG_STMMAC_PLATFORM) += stmmac_platform.o |
| 3 | stmmac-$(CONFIG_STMMAC_PCI) += stmmac_pci.o | 3 | stmmac-$(CONFIG_STMMAC_PCI) += stmmac_pci.o |
| 4 | stmmac-$(CONFIG_DWMAC_SUNXI) += dwmac-sunxi.o | 4 | stmmac-$(CONFIG_DWMAC_SUNXI) += dwmac-sunxi.o |
| 5 | stmmac-$(CONFIG_DWMAC_STI) += dwmac-sti.o | ||
| 5 | stmmac-objs:= stmmac_main.o stmmac_ethtool.o stmmac_mdio.o ring_mode.o \ | 6 | stmmac-objs:= stmmac_main.o stmmac_ethtool.o stmmac_mdio.o ring_mode.o \ |
| 6 | chain_mode.o dwmac_lib.o dwmac1000_core.o dwmac1000_dma.o \ | 7 | chain_mode.o dwmac_lib.o dwmac1000_core.o dwmac1000_dma.o \ |
| 7 | dwmac100_core.o dwmac100_dma.o enh_desc.o norm_desc.o \ | 8 | dwmac100_core.o dwmac100_dma.o enh_desc.o norm_desc.o \ |
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c new file mode 100644 index 000000000000..552bbc17863c --- /dev/null +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c | |||
| @@ -0,0 +1,330 @@ | |||
| 1 | /** | ||
| 2 | * dwmac-sti.c - STMicroelectronics DWMAC Specific Glue layer | ||
| 3 | * | ||
| 4 | * Copyright (C) 2003-2014 STMicroelectronics (R&D) Limited | ||
| 5 | * Author: Srinivas Kandagatla <srinivas.kandagatla@st.com> | ||
| 6 | * | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify | ||
| 9 | * it under the terms of the GNU General Public License as published by | ||
| 10 | * the Free Software Foundation; either version 2 of the License, or | ||
| 11 | * (at your option) any later version. | ||
| 12 | */ | ||
| 13 | |||
| 14 | #include <linux/kernel.h> | ||
| 15 | #include <linux/slab.h> | ||
| 16 | #include <linux/platform_device.h> | ||
| 17 | #include <linux/stmmac.h> | ||
| 18 | #include <linux/phy.h> | ||
| 19 | #include <linux/mfd/syscon.h> | ||
| 20 | #include <linux/regmap.h> | ||
| 21 | #include <linux/clk.h> | ||
| 22 | #include <linux/of.h> | ||
| 23 | #include <linux/of_net.h> | ||
| 24 | |||
| 25 | /** | ||
| 26 | * STi GMAC glue logic. | ||
| 27 | * -------------------- | ||
| 28 | * | ||
| 29 | * _ | ||
| 30 | * | \ | ||
| 31 | * --------|0 \ ETH_SEL_INTERNAL_NOTEXT_PHYCLK | ||
| 32 | * phyclk | |___________________________________________ | ||
| 33 | * | | | (phyclk-in) | ||
| 34 | * --------|1 / | | ||
| 35 | * int-clk |_ / | | ||
| 36 | * | _ | ||
| 37 | * | | \ | ||
| 38 | * |_______|1 \ ETH_SEL_TX_RETIME_CLK | ||
| 39 | * | |___________________________ | ||
| 40 | * | | (tx-retime-clk) | ||
| 41 | * _______|0 / | ||
| 42 | * | |_ / | ||
| 43 | * _ | | ||
| 44 | * | \ | | ||
| 45 | * --------|0 \ | | ||
| 46 | * clk_125 | |__| | ||
| 47 | * | | ETH_SEL_TXCLK_NOT_CLK125 | ||
| 48 | * --------|1 / | ||
| 49 | * txclk |_ / | ||
| 50 | * | ||
| 51 | * | ||
| 52 | * ETH_SEL_INTERNAL_NOTEXT_PHYCLK is valid only for RMII where PHY can | ||
| 53 | * generate 50MHz clock or MAC can generate it. | ||
| 54 | * This bit is configured by "st,ext-phyclk" property. | ||
| 55 | * | ||
| 56 | * ETH_SEL_TXCLK_NOT_CLK125 is only valid for gigabit modes, where the 125Mhz | ||
| 57 | * clock either comes from clk-125 pin or txclk pin. This configuration is | ||
| 58 | * totally driven by the board wiring. This bit is configured by | ||
| 59 | * "st,tx-retime-src" property. | ||
| 60 | * | ||
| 61 | * TXCLK configuration is different for different phy interface modes | ||
| 62 | * and changes according to link speed in modes like RGMII. | ||
| 63 | * | ||
| 64 | * Below table summarizes the clock requirement and clock sources for | ||
| 65 | * supported phy interface modes with link speeds. | ||
| 66 | * ________________________________________________ | ||
| 67 | *| PHY_MODE | 1000 Mbit Link | 100 Mbit Link | | ||
| 68 | * ------------------------------------------------ | ||
| 69 | *| MII | n/a | 25Mhz | | ||
| 70 | *| | | txclk | | ||
| 71 | * ------------------------------------------------ | ||
| 72 | *| GMII | 125Mhz | 25Mhz | | ||
| 73 | *| | clk-125/txclk | txclk | | ||
| 74 | * ------------------------------------------------ | ||
| 75 | *| RGMII | 125Mhz | 25Mhz | | ||
| 76 | *| | clk-125/txclk | clkgen | | ||
| 77 | * ------------------------------------------------ | ||
| 78 | *| RMII | n/a | 25Mhz | | ||
| 79 | *| | |clkgen/phyclk-in | | ||
| 80 | * ------------------------------------------------ | ||
| 81 | * | ||
| 82 | * TX lines are always retimed with a clk, which can vary depending | ||
| 83 | * on the board configuration. Below is the table of these bits | ||
| 84 | * in eth configuration register depending on source of retime clk. | ||
| 85 | * | ||
| 86 | *--------------------------------------------------------------- | ||
| 87 | * src | tx_rt_clk | int_not_ext_phyclk | txclk_n_clk125| | ||
| 88 | *--------------------------------------------------------------- | ||
| 89 | * txclk | 0 | n/a | 1 | | ||
| 90 | *--------------------------------------------------------------- | ||
| 91 | * ck_125| 0 | n/a | 0 | | ||
| 92 | *--------------------------------------------------------------- | ||
| 93 | * phyclk| 1 | 0 | n/a | | ||
| 94 | *--------------------------------------------------------------- | ||
| 95 | * clkgen| 1 | 1 | n/a | | ||
| 96 | *--------------------------------------------------------------- | ||
| 97 | */ | ||
| 98 | |||
| 99 | /* Register definition */ | ||
| 100 | |||
| 101 | /* 3 bits [8:6] | ||
| 102 | * [6:6] ETH_SEL_TXCLK_NOT_CLK125 | ||
| 103 | * [7:7] ETH_SEL_INTERNAL_NOTEXT_PHYCLK | ||
| 104 | * [8:8] ETH_SEL_TX_RETIME_CLK | ||
| 105 | * | ||
| 106 | */ | ||
| 107 | |||
| 108 | #define TX_RETIME_SRC_MASK GENMASK(8, 6) | ||
| 109 | #define ETH_SEL_TX_RETIME_CLK BIT(8) | ||
| 110 | #define ETH_SEL_INTERNAL_NOTEXT_PHYCLK BIT(7) | ||
| 111 | #define ETH_SEL_TXCLK_NOT_CLK125 BIT(6) | ||
| 112 | |||
| 113 | #define ENMII_MASK GENMASK(5, 5) | ||
| 114 | #define ENMII BIT(5) | ||
| 115 | |||
| 116 | /** | ||
| 117 | * 3 bits [4:2] | ||
| 118 | * 000-GMII/MII | ||
| 119 | * 001-RGMII | ||
| 120 | * 010-SGMII | ||
| 121 | * 100-RMII | ||
| 122 | */ | ||
| 123 | #define MII_PHY_SEL_MASK GENMASK(4, 2) | ||
| 124 | #define ETH_PHY_SEL_RMII BIT(4) | ||
| 125 | #define ETH_PHY_SEL_SGMII BIT(3) | ||
| 126 | #define ETH_PHY_SEL_RGMII BIT(2) | ||
| 127 | #define ETH_PHY_SEL_GMII 0x0 | ||
| 128 | #define ETH_PHY_SEL_MII 0x0 | ||
| 129 | |||
| 130 | #define IS_PHY_IF_MODE_RGMII(iface) (iface == PHY_INTERFACE_MODE_RGMII || \ | ||
| 131 | iface == PHY_INTERFACE_MODE_RGMII_ID || \ | ||
| 132 | iface == PHY_INTERFACE_MODE_RGMII_RXID || \ | ||
| 133 | iface == PHY_INTERFACE_MODE_RGMII_TXID) | ||
| 134 | |||
| 135 | #define IS_PHY_IF_MODE_GBIT(iface) (IS_PHY_IF_MODE_RGMII(iface) || \ | ||
| 136 | iface == PHY_INTERFACE_MODE_GMII) | ||
| 137 | |||
| 138 | struct sti_dwmac { | ||
| 139 | int interface; | ||
| 140 | bool ext_phyclk; | ||
| 141 | bool is_tx_retime_src_clk_125; | ||
| 142 | struct clk *clk; | ||
| 143 | int reg; | ||
| 144 | struct device *dev; | ||
| 145 | struct regmap *regmap; | ||
| 146 | }; | ||
| 147 | |||
| 148 | static u32 phy_intf_sels[] = { | ||
| 149 | [PHY_INTERFACE_MODE_MII] = ETH_PHY_SEL_MII, | ||
| 150 | [PHY_INTERFACE_MODE_GMII] = ETH_PHY_SEL_GMII, | ||
| 151 | [PHY_INTERFACE_MODE_RGMII] = ETH_PHY_SEL_RGMII, | ||
| 152 | [PHY_INTERFACE_MODE_RGMII_ID] = ETH_PHY_SEL_RGMII, | ||
| 153 | [PHY_INTERFACE_MODE_SGMII] = ETH_PHY_SEL_SGMII, | ||
| 154 | [PHY_INTERFACE_MODE_RMII] = ETH_PHY_SEL_RMII, | ||
| 155 | }; | ||
| 156 | |||
| 157 | enum { | ||
| 158 | TX_RETIME_SRC_NA = 0, | ||
| 159 | TX_RETIME_SRC_TXCLK = 1, | ||
| 160 | TX_RETIME_SRC_CLK_125, | ||
| 161 | TX_RETIME_SRC_PHYCLK, | ||
| 162 | TX_RETIME_SRC_CLKGEN, | ||
| 163 | }; | ||
| 164 | |||
| 165 | static const char *const tx_retime_srcs[] = { | ||
| 166 | [TX_RETIME_SRC_NA] = "", | ||
| 167 | [TX_RETIME_SRC_TXCLK] = "txclk", | ||
| 168 | [TX_RETIME_SRC_CLK_125] = "clk_125", | ||
| 169 | [TX_RETIME_SRC_PHYCLK] = "phyclk", | ||
| 170 | [TX_RETIME_SRC_CLKGEN] = "clkgen", | ||
| 171 | }; | ||
| 172 | |||
| 173 | static u32 tx_retime_val[] = { | ||
| 174 | [TX_RETIME_SRC_TXCLK] = ETH_SEL_TXCLK_NOT_CLK125, | ||
| 175 | [TX_RETIME_SRC_CLK_125] = 0x0, | ||
| 176 | [TX_RETIME_SRC_PHYCLK] = ETH_SEL_TX_RETIME_CLK, | ||
| 177 | [TX_RETIME_SRC_CLKGEN] = ETH_SEL_TX_RETIME_CLK | | ||
| 178 | ETH_SEL_INTERNAL_NOTEXT_PHYCLK, | ||
| 179 | }; | ||
| 180 | |||
| 181 | static void setup_retime_src(struct sti_dwmac *dwmac, u32 spd) | ||
| 182 | { | ||
| 183 | u32 src = 0, freq = 0; | ||
| 184 | |||
| 185 | if (spd == SPEED_100) { | ||
| 186 | if (dwmac->interface == PHY_INTERFACE_MODE_MII || | ||
| 187 | dwmac->interface == PHY_INTERFACE_MODE_GMII) { | ||
| 188 | src = TX_RETIME_SRC_TXCLK; | ||
| 189 | } else if (dwmac->interface == PHY_INTERFACE_MODE_RMII) { | ||
| 190 | if (dwmac->ext_phyclk) { | ||
| 191 | src = TX_RETIME_SRC_PHYCLK; | ||
| 192 | } else { | ||
| 193 | src = TX_RETIME_SRC_CLKGEN; | ||
| 194 | freq = 50000000; | ||
| 195 | } | ||
| 196 | |||
| 197 | } else if (IS_PHY_IF_MODE_RGMII(dwmac->interface)) { | ||
| 198 | src = TX_RETIME_SRC_CLKGEN; | ||
| 199 | freq = 25000000; | ||
| 200 | } | ||
| 201 | |||
| 202 | if (src == TX_RETIME_SRC_CLKGEN && dwmac->clk) | ||
| 203 | clk_set_rate(dwmac->clk, freq); | ||
| 204 | |||
| 205 | } else if (spd == SPEED_1000) { | ||
| 206 | if (dwmac->is_tx_retime_src_clk_125) | ||
| 207 | src = TX_RETIME_SRC_CLK_125; | ||
| 208 | else | ||
| 209 | src = TX_RETIME_SRC_TXCLK; | ||
| 210 | } | ||
| 211 | |||
| 212 | regmap_update_bits(dwmac->regmap, dwmac->reg, | ||
| 213 | TX_RETIME_SRC_MASK, tx_retime_val[src]); | ||
| 214 | } | ||
| 215 | |||
| 216 | static void sti_dwmac_exit(struct platform_device *pdev, void *priv) | ||
| 217 | { | ||
| 218 | struct sti_dwmac *dwmac = priv; | ||
| 219 | |||
| 220 | if (dwmac->clk) | ||
| 221 | clk_disable_unprepare(dwmac->clk); | ||
| 222 | } | ||
| 223 | |||
| 224 | static void sti_fix_mac_speed(void *priv, unsigned int spd) | ||
| 225 | { | ||
| 226 | struct sti_dwmac *dwmac = priv; | ||
| 227 | |||
| 228 | setup_retime_src(dwmac, spd); | ||
| 229 | |||
| 230 | return; | ||
| 231 | } | ||
| 232 | |||
| 233 | static int sti_dwmac_parse_data(struct sti_dwmac *dwmac, | ||
| 234 | struct platform_device *pdev) | ||
| 235 | { | ||
| 236 | struct resource *res; | ||
| 237 | struct device *dev = &pdev->dev; | ||
| 238 | struct device_node *np = dev->of_node; | ||
| 239 | struct regmap *regmap; | ||
| 240 | int err; | ||
| 241 | |||
| 242 | if (!np) | ||
| 243 | return -EINVAL; | ||
| 244 | |||
| 245 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "sti-ethconf"); | ||
| 246 | if (!res) | ||
| 247 | return -ENODATA; | ||
| 248 | |||
| 249 | regmap = syscon_regmap_lookup_by_phandle(np, "st,syscon"); | ||
| 250 | if (IS_ERR(regmap)) | ||
| 251 | return PTR_ERR(regmap); | ||
| 252 | |||
| 253 | dwmac->dev = dev; | ||
| 254 | dwmac->interface = of_get_phy_mode(np); | ||
| 255 | dwmac->regmap = regmap; | ||
| 256 | dwmac->reg = res->start; | ||
| 257 | dwmac->ext_phyclk = of_property_read_bool(np, "st,ext-phyclk"); | ||
| 258 | dwmac->is_tx_retime_src_clk_125 = false; | ||
| 259 | |||
| 260 | if (IS_PHY_IF_MODE_GBIT(dwmac->interface)) { | ||
| 261 | const char *rs; | ||
| 262 | |||
| 263 | err = of_property_read_string(np, "st,tx-retime-src", &rs); | ||
| 264 | if (err < 0) { | ||
| 265 | dev_err(dev, "st,tx-retime-src not specified\n"); | ||
| 266 | return err; | ||
| 267 | } | ||
| 268 | |||
| 269 | if (!strcasecmp(rs, "clk_125")) | ||
| 270 | dwmac->is_tx_retime_src_clk_125 = true; | ||
| 271 | } | ||
| 272 | |||
| 273 | dwmac->clk = devm_clk_get(dev, "sti-ethclk"); | ||
| 274 | |||
| 275 | if (IS_ERR(dwmac->clk)) | ||
| 276 | dwmac->clk = NULL; | ||
| 277 | |||
| 278 | return 0; | ||
| 279 | } | ||
| 280 | |||
| 281 | static int sti_dwmac_init(struct platform_device *pdev, void *priv) | ||
| 282 | { | ||
| 283 | struct sti_dwmac *dwmac = priv; | ||
| 284 | struct regmap *regmap = dwmac->regmap; | ||
| 285 | int iface = dwmac->interface; | ||
| 286 | u32 reg = dwmac->reg; | ||
| 287 | u32 val, spd; | ||
| 288 | |||
| 289 | if (dwmac->clk) | ||
| 290 | clk_prepare_enable(dwmac->clk); | ||
| 291 | |||
| 292 | regmap_update_bits(regmap, reg, MII_PHY_SEL_MASK, phy_intf_sels[iface]); | ||
| 293 | |||
| 294 | val = (iface == PHY_INTERFACE_MODE_REVMII) ? 0 : ENMII; | ||
| 295 | regmap_update_bits(regmap, reg, ENMII_MASK, val); | ||
| 296 | |||
| 297 | if (IS_PHY_IF_MODE_GBIT(iface)) | ||
| 298 | spd = SPEED_1000; | ||
| 299 | else | ||
| 300 | spd = SPEED_100; | ||
| 301 | |||
| 302 | setup_retime_src(dwmac, spd); | ||
| 303 | |||
| 304 | return 0; | ||
| 305 | } | ||
| 306 | |||
| 307 | static void *sti_dwmac_setup(struct platform_device *pdev) | ||
| 308 | { | ||
| 309 | struct sti_dwmac *dwmac; | ||
| 310 | int ret; | ||
| 311 | |||
| 312 | dwmac = devm_kzalloc(&pdev->dev, sizeof(*dwmac), GFP_KERNEL); | ||
| 313 | if (!dwmac) | ||
| 314 | return ERR_PTR(-ENOMEM); | ||
| 315 | |||
| 316 | ret = sti_dwmac_parse_data(dwmac, pdev); | ||
| 317 | if (ret) { | ||
| 318 | dev_err(&pdev->dev, "Unable to parse OF data\n"); | ||
| 319 | return ERR_PTR(ret); | ||
| 320 | } | ||
| 321 | |||
| 322 | return dwmac; | ||
| 323 | } | ||
| 324 | |||
| 325 | const struct stmmac_of_data sti_gmac_data = { | ||
| 326 | .fix_mac_speed = sti_fix_mac_speed, | ||
| 327 | .setup = sti_dwmac_setup, | ||
| 328 | .init = sti_dwmac_init, | ||
| 329 | .exit = sti_dwmac_exit, | ||
| 330 | }; | ||
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h index d9af26ed58ee..f9e60d7918c4 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h | |||
| @@ -133,6 +133,9 @@ bool stmmac_eee_init(struct stmmac_priv *priv); | |||
| 133 | #ifdef CONFIG_DWMAC_SUNXI | 133 | #ifdef CONFIG_DWMAC_SUNXI |
| 134 | extern const struct stmmac_of_data sun7i_gmac_data; | 134 | extern const struct stmmac_of_data sun7i_gmac_data; |
| 135 | #endif | 135 | #endif |
| 136 | #ifdef CONFIG_DWMAC_STI | ||
| 137 | extern const struct stmmac_of_data sti_gmac_data; | ||
| 138 | #endif | ||
| 136 | extern struct platform_driver stmmac_pltfr_driver; | 139 | extern struct platform_driver stmmac_pltfr_driver; |
| 137 | static inline int stmmac_register_platform(void) | 140 | static inline int stmmac_register_platform(void) |
| 138 | { | 141 | { |
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index a2e7d2c96e36..078ad0ec8593 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | |||
| @@ -1705,7 +1705,7 @@ static int stmmac_open(struct net_device *dev) | |||
| 1705 | priv->dma_rx_size = STMMAC_ALIGN(dma_rxsize); | 1705 | priv->dma_rx_size = STMMAC_ALIGN(dma_rxsize); |
| 1706 | priv->dma_buf_sz = STMMAC_ALIGN(buf_sz); | 1706 | priv->dma_buf_sz = STMMAC_ALIGN(buf_sz); |
| 1707 | 1707 | ||
| 1708 | alloc_dma_desc_resources(priv); | 1708 | ret = alloc_dma_desc_resources(priv); |
| 1709 | if (ret < 0) { | 1709 | if (ret < 0) { |
| 1710 | pr_err("%s: DMA descriptors allocation failed\n", __func__); | 1710 | pr_err("%s: DMA descriptors allocation failed\n", __func__); |
| 1711 | goto dma_desc_error; | 1711 | goto dma_desc_error; |
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c index 5884a7d2063b..c61bc72b8e90 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c | |||
| @@ -33,6 +33,11 @@ static const struct of_device_id stmmac_dt_ids[] = { | |||
| 33 | #ifdef CONFIG_DWMAC_SUNXI | 33 | #ifdef CONFIG_DWMAC_SUNXI |
| 34 | { .compatible = "allwinner,sun7i-a20-gmac", .data = &sun7i_gmac_data}, | 34 | { .compatible = "allwinner,sun7i-a20-gmac", .data = &sun7i_gmac_data}, |
| 35 | #endif | 35 | #endif |
| 36 | #ifdef CONFIG_DWMAC_STI | ||
| 37 | { .compatible = "st,stih415-dwmac", .data = &sti_gmac_data}, | ||
| 38 | { .compatible = "st,stih416-dwmac", .data = &sti_gmac_data}, | ||
| 39 | { .compatible = "st,stih127-dwmac", .data = &sti_gmac_data}, | ||
| 40 | #endif | ||
| 36 | /* SoC specific glue layers should come before generic bindings */ | 41 | /* SoC specific glue layers should come before generic bindings */ |
| 37 | { .compatible = "st,spear600-gmac"}, | 42 | { .compatible = "st,spear600-gmac"}, |
| 38 | { .compatible = "snps,dwmac-3.610"}, | 43 | { .compatible = "snps,dwmac-3.610"}, |
diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c index bde63e3af96f..ffd4d12acf6d 100644 --- a/drivers/net/ethernet/ti/cpsw.c +++ b/drivers/net/ethernet/ti/cpsw.c | |||
| @@ -554,7 +554,7 @@ static void cpsw_set_promiscious(struct net_device *ndev, bool enable) | |||
| 554 | * common for both the interface as the interface shares | 554 | * common for both the interface as the interface shares |
| 555 | * the same hardware resource. | 555 | * the same hardware resource. |
| 556 | */ | 556 | */ |
| 557 | for (i = 0; i <= priv->data.slaves; i++) | 557 | for (i = 0; i < priv->data.slaves; i++) |
| 558 | if (priv->slaves[i].ndev->flags & IFF_PROMISC) | 558 | if (priv->slaves[i].ndev->flags & IFF_PROMISC) |
| 559 | flag = true; | 559 | flag = true; |
| 560 | 560 | ||
| @@ -578,7 +578,7 @@ static void cpsw_set_promiscious(struct net_device *ndev, bool enable) | |||
| 578 | unsigned long timeout = jiffies + HZ; | 578 | unsigned long timeout = jiffies + HZ; |
| 579 | 579 | ||
| 580 | /* Disable Learn for all ports */ | 580 | /* Disable Learn for all ports */ |
| 581 | for (i = 0; i <= priv->data.slaves; i++) { | 581 | for (i = 0; i < priv->data.slaves; i++) { |
| 582 | cpsw_ale_control_set(ale, i, | 582 | cpsw_ale_control_set(ale, i, |
| 583 | ALE_PORT_NOLEARN, 1); | 583 | ALE_PORT_NOLEARN, 1); |
| 584 | cpsw_ale_control_set(ale, i, | 584 | cpsw_ale_control_set(ale, i, |
| @@ -606,7 +606,7 @@ static void cpsw_set_promiscious(struct net_device *ndev, bool enable) | |||
| 606 | cpsw_ale_control_set(ale, 0, ALE_P0_UNI_FLOOD, 0); | 606 | cpsw_ale_control_set(ale, 0, ALE_P0_UNI_FLOOD, 0); |
| 607 | 607 | ||
| 608 | /* Enable Learn for all ports */ | 608 | /* Enable Learn for all ports */ |
| 609 | for (i = 0; i <= priv->data.slaves; i++) { | 609 | for (i = 0; i < priv->data.slaves; i++) { |
| 610 | cpsw_ale_control_set(ale, i, | 610 | cpsw_ale_control_set(ale, i, |
| 611 | ALE_PORT_NOLEARN, 0); | 611 | ALE_PORT_NOLEARN, 0); |
| 612 | cpsw_ale_control_set(ale, i, | 612 | cpsw_ale_control_set(ale, i, |
| @@ -1164,11 +1164,17 @@ static void cpsw_init_host_port(struct cpsw_priv *priv) | |||
| 1164 | 1164 | ||
| 1165 | static void cpsw_slave_stop(struct cpsw_slave *slave, struct cpsw_priv *priv) | 1165 | static void cpsw_slave_stop(struct cpsw_slave *slave, struct cpsw_priv *priv) |
| 1166 | { | 1166 | { |
| 1167 | u32 slave_port; | ||
| 1168 | |||
| 1169 | slave_port = cpsw_get_slave_port(priv, slave->slave_num); | ||
| 1170 | |||
| 1167 | if (!slave->phy) | 1171 | if (!slave->phy) |
| 1168 | return; | 1172 | return; |
| 1169 | phy_stop(slave->phy); | 1173 | phy_stop(slave->phy); |
| 1170 | phy_disconnect(slave->phy); | 1174 | phy_disconnect(slave->phy); |
| 1171 | slave->phy = NULL; | 1175 | slave->phy = NULL; |
| 1176 | cpsw_ale_control_set(priv->ale, slave_port, | ||
| 1177 | ALE_PORT_STATE, ALE_PORT_STATE_DISABLE); | ||
| 1172 | } | 1178 | } |
| 1173 | 1179 | ||
| 1174 | static int cpsw_ndo_open(struct net_device *ndev) | 1180 | static int cpsw_ndo_open(struct net_device *ndev) |
| @@ -1878,14 +1884,29 @@ static int cpsw_probe_dt(struct cpsw_platform_data *data, | |||
| 1878 | mdio_node = of_find_node_by_phandle(be32_to_cpup(parp)); | 1884 | mdio_node = of_find_node_by_phandle(be32_to_cpup(parp)); |
| 1879 | phyid = be32_to_cpup(parp+1); | 1885 | phyid = be32_to_cpup(parp+1); |
| 1880 | mdio = of_find_device_by_node(mdio_node); | 1886 | mdio = of_find_device_by_node(mdio_node); |
| 1881 | snprintf(slave_data->phy_id, sizeof(slave_data->phy_id), | 1887 | |
| 1882 | PHY_ID_FMT, mdio->name, phyid); | 1888 | if (strncmp(mdio->name, "gpio", 4) == 0) { |
| 1889 | /* GPIO bitbang MDIO driver attached */ | ||
| 1890 | struct mii_bus *bus = dev_get_drvdata(&mdio->dev); | ||
| 1891 | |||
| 1892 | snprintf(slave_data->phy_id, sizeof(slave_data->phy_id), | ||
| 1893 | PHY_ID_FMT, bus->id, phyid); | ||
| 1894 | } else { | ||
| 1895 | /* davinci MDIO driver attached */ | ||
| 1896 | snprintf(slave_data->phy_id, sizeof(slave_data->phy_id), | ||
| 1897 | PHY_ID_FMT, mdio->name, phyid); | ||
| 1898 | } | ||
| 1883 | 1899 | ||
| 1884 | mac_addr = of_get_mac_address(slave_node); | 1900 | mac_addr = of_get_mac_address(slave_node); |
| 1885 | if (mac_addr) | 1901 | if (mac_addr) |
| 1886 | memcpy(slave_data->mac_addr, mac_addr, ETH_ALEN); | 1902 | memcpy(slave_data->mac_addr, mac_addr, ETH_ALEN); |
| 1887 | 1903 | ||
| 1888 | slave_data->phy_if = of_get_phy_mode(slave_node); | 1904 | slave_data->phy_if = of_get_phy_mode(slave_node); |
| 1905 | if (slave_data->phy_if < 0) { | ||
| 1906 | pr_err("Missing or malformed slave[%d] phy-mode property\n", | ||
| 1907 | i); | ||
| 1908 | return slave_data->phy_if; | ||
| 1909 | } | ||
| 1889 | 1910 | ||
| 1890 | if (data->dual_emac) { | 1911 | if (data->dual_emac) { |
| 1891 | if (of_property_read_u32(slave_node, "dual_emac_res_vlan", | 1912 | if (of_property_read_u32(slave_node, "dual_emac_res_vlan", |
diff --git a/drivers/net/ethernet/tile/tilegx.c b/drivers/net/ethernet/tile/tilegx.c index 023237a65720..17503da9f7a5 100644 --- a/drivers/net/ethernet/tile/tilegx.c +++ b/drivers/net/ethernet/tile/tilegx.c | |||
| @@ -2071,7 +2071,7 @@ static int tile_net_tx(struct sk_buff *skb, struct net_device *dev) | |||
| 2071 | 2071 | ||
| 2072 | /* Return subqueue id on this core (one per core). */ | 2072 | /* Return subqueue id on this core (one per core). */ |
| 2073 | static u16 tile_net_select_queue(struct net_device *dev, struct sk_buff *skb, | 2073 | static u16 tile_net_select_queue(struct net_device *dev, struct sk_buff *skb, |
| 2074 | void *accel_priv) | 2074 | void *accel_priv, select_queue_fallback_t fallback) |
| 2075 | { | 2075 | { |
| 2076 | return smp_processor_id(); | 2076 | return smp_processor_id(); |
| 2077 | } | 2077 | } |
diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c index 1ec65feebb9e..4bfdf8c7ada0 100644 --- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c +++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c | |||
| @@ -26,6 +26,7 @@ | |||
| 26 | #include <linux/netdevice.h> | 26 | #include <linux/netdevice.h> |
| 27 | #include <linux/of_mdio.h> | 27 | #include <linux/of_mdio.h> |
| 28 | #include <linux/of_platform.h> | 28 | #include <linux/of_platform.h> |
| 29 | #include <linux/of_irq.h> | ||
| 29 | #include <linux/of_address.h> | 30 | #include <linux/of_address.h> |
| 30 | #include <linux/skbuff.h> | 31 | #include <linux/skbuff.h> |
| 31 | #include <linux/spinlock.h> | 32 | #include <linux/spinlock.h> |
| @@ -600,7 +601,8 @@ static void axienet_start_xmit_done(struct net_device *ndev) | |||
| 600 | size += status & XAXIDMA_BD_STS_ACTUAL_LEN_MASK; | 601 | size += status & XAXIDMA_BD_STS_ACTUAL_LEN_MASK; |
| 601 | packets++; | 602 | packets++; |
| 602 | 603 | ||
| 603 | lp->tx_bd_ci = ++lp->tx_bd_ci % TX_BD_NUM; | 604 | ++lp->tx_bd_ci; |
| 605 | lp->tx_bd_ci %= TX_BD_NUM; | ||
| 604 | cur_p = &lp->tx_bd_v[lp->tx_bd_ci]; | 606 | cur_p = &lp->tx_bd_v[lp->tx_bd_ci]; |
| 605 | status = cur_p->status; | 607 | status = cur_p->status; |
| 606 | } | 608 | } |
| @@ -686,7 +688,8 @@ static int axienet_start_xmit(struct sk_buff *skb, struct net_device *ndev) | |||
| 686 | skb_headlen(skb), DMA_TO_DEVICE); | 688 | skb_headlen(skb), DMA_TO_DEVICE); |
| 687 | 689 | ||
| 688 | for (ii = 0; ii < num_frag; ii++) { | 690 | for (ii = 0; ii < num_frag; ii++) { |
| 689 | lp->tx_bd_tail = ++lp->tx_bd_tail % TX_BD_NUM; | 691 | ++lp->tx_bd_tail; |
| 692 | lp->tx_bd_tail %= TX_BD_NUM; | ||
| 690 | cur_p = &lp->tx_bd_v[lp->tx_bd_tail]; | 693 | cur_p = &lp->tx_bd_v[lp->tx_bd_tail]; |
| 691 | frag = &skb_shinfo(skb)->frags[ii]; | 694 | frag = &skb_shinfo(skb)->frags[ii]; |
| 692 | cur_p->phys = dma_map_single(ndev->dev.parent, | 695 | cur_p->phys = dma_map_single(ndev->dev.parent, |
| @@ -702,7 +705,8 @@ static int axienet_start_xmit(struct sk_buff *skb, struct net_device *ndev) | |||
| 702 | tail_p = lp->tx_bd_p + sizeof(*lp->tx_bd_v) * lp->tx_bd_tail; | 705 | tail_p = lp->tx_bd_p + sizeof(*lp->tx_bd_v) * lp->tx_bd_tail; |
| 703 | /* Start the transfer */ | 706 | /* Start the transfer */ |
| 704 | axienet_dma_out32(lp, XAXIDMA_TX_TDESC_OFFSET, tail_p); | 707 | axienet_dma_out32(lp, XAXIDMA_TX_TDESC_OFFSET, tail_p); |
| 705 | lp->tx_bd_tail = ++lp->tx_bd_tail % TX_BD_NUM; | 708 | ++lp->tx_bd_tail; |
| 709 | lp->tx_bd_tail %= TX_BD_NUM; | ||
| 706 | 710 | ||
| 707 | return NETDEV_TX_OK; | 711 | return NETDEV_TX_OK; |
| 708 | } | 712 | } |
| @@ -774,7 +778,8 @@ static void axienet_recv(struct net_device *ndev) | |||
| 774 | cur_p->status = 0; | 778 | cur_p->status = 0; |
| 775 | cur_p->sw_id_offset = (u32) new_skb; | 779 | cur_p->sw_id_offset = (u32) new_skb; |
| 776 | 780 | ||
| 777 | lp->rx_bd_ci = ++lp->rx_bd_ci % RX_BD_NUM; | 781 | ++lp->rx_bd_ci; |
| 782 | lp->rx_bd_ci %= RX_BD_NUM; | ||
| 778 | cur_p = &lp->rx_bd_v[lp->rx_bd_ci]; | 783 | cur_p = &lp->rx_bd_v[lp->rx_bd_ci]; |
| 779 | } | 784 | } |
| 780 | 785 | ||
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c index 7756118c2f0a..7141a1937360 100644 --- a/drivers/net/hyperv/netvsc_drv.c +++ b/drivers/net/hyperv/netvsc_drv.c | |||
| @@ -88,8 +88,12 @@ static int netvsc_open(struct net_device *net) | |||
| 88 | { | 88 | { |
| 89 | struct net_device_context *net_device_ctx = netdev_priv(net); | 89 | struct net_device_context *net_device_ctx = netdev_priv(net); |
| 90 | struct hv_device *device_obj = net_device_ctx->device_ctx; | 90 | struct hv_device *device_obj = net_device_ctx->device_ctx; |
| 91 | struct netvsc_device *nvdev; | ||
| 92 | struct rndis_device *rdev; | ||
| 91 | int ret = 0; | 93 | int ret = 0; |
| 92 | 94 | ||
| 95 | netif_carrier_off(net); | ||
| 96 | |||
| 93 | /* Open up the device */ | 97 | /* Open up the device */ |
| 94 | ret = rndis_filter_open(device_obj); | 98 | ret = rndis_filter_open(device_obj); |
| 95 | if (ret != 0) { | 99 | if (ret != 0) { |
| @@ -99,6 +103,11 @@ static int netvsc_open(struct net_device *net) | |||
| 99 | 103 | ||
| 100 | netif_start_queue(net); | 104 | netif_start_queue(net); |
| 101 | 105 | ||
| 106 | nvdev = hv_get_drvdata(device_obj); | ||
| 107 | rdev = nvdev->extension; | ||
| 108 | if (!rdev->link_state) | ||
| 109 | netif_carrier_on(net); | ||
| 110 | |||
| 102 | return ret; | 111 | return ret; |
| 103 | } | 112 | } |
| 104 | 113 | ||
| @@ -229,23 +238,24 @@ void netvsc_linkstatus_callback(struct hv_device *device_obj, | |||
| 229 | struct net_device *net; | 238 | struct net_device *net; |
| 230 | struct net_device_context *ndev_ctx; | 239 | struct net_device_context *ndev_ctx; |
| 231 | struct netvsc_device *net_device; | 240 | struct netvsc_device *net_device; |
| 241 | struct rndis_device *rdev; | ||
| 232 | 242 | ||
| 233 | net_device = hv_get_drvdata(device_obj); | 243 | net_device = hv_get_drvdata(device_obj); |
| 244 | rdev = net_device->extension; | ||
| 245 | |||
| 246 | rdev->link_state = status != 1; | ||
| 247 | |||
| 234 | net = net_device->ndev; | 248 | net = net_device->ndev; |
| 235 | 249 | ||
| 236 | if (!net) { | 250 | if (!net || net->reg_state != NETREG_REGISTERED) |
| 237 | netdev_err(net, "got link status but net device " | ||
| 238 | "not initialized yet\n"); | ||
| 239 | return; | 251 | return; |
| 240 | } | ||
| 241 | 252 | ||
| 253 | ndev_ctx = netdev_priv(net); | ||
| 242 | if (status == 1) { | 254 | if (status == 1) { |
| 243 | netif_carrier_on(net); | ||
| 244 | ndev_ctx = netdev_priv(net); | ||
| 245 | schedule_delayed_work(&ndev_ctx->dwork, 0); | 255 | schedule_delayed_work(&ndev_ctx->dwork, 0); |
| 246 | schedule_delayed_work(&ndev_ctx->dwork, msecs_to_jiffies(20)); | 256 | schedule_delayed_work(&ndev_ctx->dwork, msecs_to_jiffies(20)); |
| 247 | } else { | 257 | } else { |
| 248 | netif_carrier_off(net); | 258 | schedule_delayed_work(&ndev_ctx->dwork, 0); |
| 249 | } | 259 | } |
| 250 | } | 260 | } |
| 251 | 261 | ||
| @@ -388,17 +398,35 @@ static const struct net_device_ops device_ops = { | |||
| 388 | * current context when receiving RNDIS_STATUS_MEDIA_CONNECT event. So, add | 398 | * current context when receiving RNDIS_STATUS_MEDIA_CONNECT event. So, add |
| 389 | * another netif_notify_peers() into a delayed work, otherwise GARP packet | 399 | * another netif_notify_peers() into a delayed work, otherwise GARP packet |
| 390 | * will not be sent after quick migration, and cause network disconnection. | 400 | * will not be sent after quick migration, and cause network disconnection. |
| 401 | * Also, we update the carrier status here. | ||
| 391 | */ | 402 | */ |
| 392 | static void netvsc_send_garp(struct work_struct *w) | 403 | static void netvsc_link_change(struct work_struct *w) |
| 393 | { | 404 | { |
| 394 | struct net_device_context *ndev_ctx; | 405 | struct net_device_context *ndev_ctx; |
| 395 | struct net_device *net; | 406 | struct net_device *net; |
| 396 | struct netvsc_device *net_device; | 407 | struct netvsc_device *net_device; |
| 408 | struct rndis_device *rdev; | ||
| 409 | bool notify; | ||
| 410 | |||
| 411 | rtnl_lock(); | ||
| 397 | 412 | ||
| 398 | ndev_ctx = container_of(w, struct net_device_context, dwork.work); | 413 | ndev_ctx = container_of(w, struct net_device_context, dwork.work); |
| 399 | net_device = hv_get_drvdata(ndev_ctx->device_ctx); | 414 | net_device = hv_get_drvdata(ndev_ctx->device_ctx); |
| 415 | rdev = net_device->extension; | ||
| 400 | net = net_device->ndev; | 416 | net = net_device->ndev; |
| 401 | netdev_notify_peers(net); | 417 | |
| 418 | if (rdev->link_state) { | ||
| 419 | netif_carrier_off(net); | ||
| 420 | notify = false; | ||
| 421 | } else { | ||
| 422 | netif_carrier_on(net); | ||
| 423 | notify = true; | ||
| 424 | } | ||
| 425 | |||
| 426 | rtnl_unlock(); | ||
| 427 | |||
| 428 | if (notify) | ||
| 429 | netdev_notify_peers(net); | ||
| 402 | } | 430 | } |
| 403 | 431 | ||
| 404 | 432 | ||
| @@ -414,13 +442,10 @@ static int netvsc_probe(struct hv_device *dev, | |||
| 414 | if (!net) | 442 | if (!net) |
| 415 | return -ENOMEM; | 443 | return -ENOMEM; |
| 416 | 444 | ||
| 417 | /* Set initial state */ | ||
| 418 | netif_carrier_off(net); | ||
| 419 | |||
| 420 | net_device_ctx = netdev_priv(net); | 445 | net_device_ctx = netdev_priv(net); |
| 421 | net_device_ctx->device_ctx = dev; | 446 | net_device_ctx->device_ctx = dev; |
| 422 | hv_set_drvdata(dev, net); | 447 | hv_set_drvdata(dev, net); |
| 423 | INIT_DELAYED_WORK(&net_device_ctx->dwork, netvsc_send_garp); | 448 | INIT_DELAYED_WORK(&net_device_ctx->dwork, netvsc_link_change); |
| 424 | INIT_WORK(&net_device_ctx->work, do_set_multicast); | 449 | INIT_WORK(&net_device_ctx->work, do_set_multicast); |
| 425 | 450 | ||
| 426 | net->netdev_ops = &device_ops; | 451 | net->netdev_ops = &device_ops; |
| @@ -443,8 +468,6 @@ static int netvsc_probe(struct hv_device *dev, | |||
| 443 | } | 468 | } |
| 444 | memcpy(net->dev_addr, device_info.mac_adr, ETH_ALEN); | 469 | memcpy(net->dev_addr, device_info.mac_adr, ETH_ALEN); |
| 445 | 470 | ||
| 446 | netif_carrier_on(net); | ||
| 447 | |||
| 448 | ret = register_netdev(net); | 471 | ret = register_netdev(net); |
| 449 | if (ret != 0) { | 472 | if (ret != 0) { |
| 450 | pr_err("Unable to register netdev.\n"); | 473 | pr_err("Unable to register netdev.\n"); |
diff --git a/drivers/net/irda/Kconfig b/drivers/net/irda/Kconfig index 2dc82f1d2e70..3da44d5d9149 100644 --- a/drivers/net/irda/Kconfig +++ b/drivers/net/irda/Kconfig | |||
| @@ -210,13 +210,6 @@ config KINGSUN_DONGLE | |||
| 210 | To compile it as a module, choose M here: the module will be called | 210 | To compile it as a module, choose M here: the module will be called |
| 211 | kingsun-sir. | 211 | kingsun-sir. |
| 212 | 212 | ||
| 213 | config EP7211_DONGLE | ||
| 214 | tristate "Cirrus Logic clps711x I/R support" | ||
| 215 | depends on IRTTY_SIR && ARCH_CLPS711X && IRDA | ||
| 216 | help | ||
| 217 | Say Y here if you want to build support for the Cirrus logic | ||
| 218 | EP7211 chipset's infrared module. | ||
| 219 | |||
| 220 | config KSDAZZLE_DONGLE | 213 | config KSDAZZLE_DONGLE |
| 221 | tristate "KingSun Dazzle IrDA-USB dongle" | 214 | tristate "KingSun Dazzle IrDA-USB dongle" |
| 222 | depends on IRDA && USB | 215 | depends on IRDA && USB |
diff --git a/drivers/net/irda/Makefile b/drivers/net/irda/Makefile index dfc64537f62f..be8ab5b9a4a2 100644 --- a/drivers/net/irda/Makefile +++ b/drivers/net/irda/Makefile | |||
| @@ -35,7 +35,6 @@ obj-$(CONFIG_MCP2120_DONGLE) += mcp2120-sir.o | |||
| 35 | obj-$(CONFIG_ACT200L_DONGLE) += act200l-sir.o | 35 | obj-$(CONFIG_ACT200L_DONGLE) += act200l-sir.o |
| 36 | obj-$(CONFIG_MA600_DONGLE) += ma600-sir.o | 36 | obj-$(CONFIG_MA600_DONGLE) += ma600-sir.o |
| 37 | obj-$(CONFIG_TOIM3232_DONGLE) += toim3232-sir.o | 37 | obj-$(CONFIG_TOIM3232_DONGLE) += toim3232-sir.o |
| 38 | obj-$(CONFIG_EP7211_DONGLE) += ep7211-sir.o | ||
| 39 | obj-$(CONFIG_KINGSUN_DONGLE) += kingsun-sir.o | 38 | obj-$(CONFIG_KINGSUN_DONGLE) += kingsun-sir.o |
| 40 | obj-$(CONFIG_KSDAZZLE_DONGLE) += ksdazzle-sir.o | 39 | obj-$(CONFIG_KSDAZZLE_DONGLE) += ksdazzle-sir.o |
| 41 | obj-$(CONFIG_KS959_DONGLE) += ks959-sir.o | 40 | obj-$(CONFIG_KS959_DONGLE) += ks959-sir.o |
diff --git a/drivers/net/irda/ep7211-sir.c b/drivers/net/irda/ep7211-sir.c deleted file mode 100644 index 5fe1f4dd3369..000000000000 --- a/drivers/net/irda/ep7211-sir.c +++ /dev/null | |||
| @@ -1,70 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * IR port driver for the Cirrus Logic CLPS711X processors | ||
| 3 | * | ||
| 4 | * Copyright 2001, Blue Mug Inc. All rights reserved. | ||
| 5 | * Copyright 2007, Samuel Ortiz <samuel@sortiz.org> | ||
| 6 | */ | ||
| 7 | |||
| 8 | #include <linux/module.h> | ||
| 9 | #include <linux/platform_device.h> | ||
| 10 | |||
| 11 | #include <mach/hardware.h> | ||
| 12 | |||
| 13 | #include "sir-dev.h" | ||
| 14 | |||
| 15 | static int clps711x_dongle_open(struct sir_dev *dev) | ||
| 16 | { | ||
| 17 | unsigned int syscon; | ||
| 18 | |||
| 19 | /* Turn on the SIR encoder. */ | ||
| 20 | syscon = clps_readl(SYSCON1); | ||
| 21 | syscon |= SYSCON1_SIREN; | ||
| 22 | clps_writel(syscon, SYSCON1); | ||
| 23 | |||
| 24 | return 0; | ||
| 25 | } | ||
| 26 | |||
| 27 | static int clps711x_dongle_close(struct sir_dev *dev) | ||
| 28 | { | ||
| 29 | unsigned int syscon; | ||
| 30 | |||
| 31 | /* Turn off the SIR encoder. */ | ||
| 32 | syscon = clps_readl(SYSCON1); | ||
| 33 | syscon &= ~SYSCON1_SIREN; | ||
| 34 | clps_writel(syscon, SYSCON1); | ||
| 35 | |||
| 36 | return 0; | ||
| 37 | } | ||
| 38 | |||
| 39 | static struct dongle_driver clps711x_dongle = { | ||
| 40 | .owner = THIS_MODULE, | ||
| 41 | .driver_name = "EP7211 IR driver", | ||
| 42 | .type = IRDA_EP7211_DONGLE, | ||
| 43 | .open = clps711x_dongle_open, | ||
| 44 | .close = clps711x_dongle_close, | ||
| 45 | }; | ||
| 46 | |||
| 47 | static int clps711x_sir_probe(struct platform_device *pdev) | ||
| 48 | { | ||
| 49 | return irda_register_dongle(&clps711x_dongle); | ||
| 50 | } | ||
| 51 | |||
| 52 | static int clps711x_sir_remove(struct platform_device *pdev) | ||
| 53 | { | ||
| 54 | return irda_unregister_dongle(&clps711x_dongle); | ||
| 55 | } | ||
| 56 | |||
| 57 | static struct platform_driver clps711x_sir_driver = { | ||
| 58 | .driver = { | ||
| 59 | .name = "sir-clps711x", | ||
| 60 | .owner = THIS_MODULE, | ||
| 61 | }, | ||
| 62 | .probe = clps711x_sir_probe, | ||
| 63 | .remove = clps711x_sir_remove, | ||
| 64 | }; | ||
| 65 | module_platform_driver(clps711x_sir_driver); | ||
| 66 | |||
| 67 | MODULE_AUTHOR("Samuel Ortiz <samuel@sortiz.org>"); | ||
| 68 | MODULE_DESCRIPTION("EP7211 IR dongle driver"); | ||
| 69 | MODULE_LICENSE("GPL"); | ||
| 70 | MODULE_ALIAS("irda-dongle-13"); /* IRDA_EP7211_DONGLE */ | ||
diff --git a/drivers/net/irda/irtty-sir.c b/drivers/net/irda/irtty-sir.c index 177441afeb96..24b6dddd7f2f 100644 --- a/drivers/net/irda/irtty-sir.c +++ b/drivers/net/irda/irtty-sir.c | |||
| @@ -522,7 +522,6 @@ static void irtty_close(struct tty_struct *tty) | |||
| 522 | sirdev_put_instance(priv->dev); | 522 | sirdev_put_instance(priv->dev); |
| 523 | 523 | ||
| 524 | /* Stop tty */ | 524 | /* Stop tty */ |
| 525 | irtty_stop_receiver(tty, TRUE); | ||
| 526 | clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags); | 525 | clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags); |
| 527 | if (tty->ops->stop) | 526 | if (tty->ops->stop) |
| 528 | tty->ops->stop(tty); | 527 | tty->ops->stop(tty); |
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c index 8433de4509c7..1831fb7cd017 100644 --- a/drivers/net/macvlan.c +++ b/drivers/net/macvlan.c | |||
| @@ -506,6 +506,9 @@ static int macvlan_change_mtu(struct net_device *dev, int new_mtu) | |||
| 506 | static struct lock_class_key macvlan_netdev_xmit_lock_key; | 506 | static struct lock_class_key macvlan_netdev_xmit_lock_key; |
| 507 | static struct lock_class_key macvlan_netdev_addr_lock_key; | 507 | static struct lock_class_key macvlan_netdev_addr_lock_key; |
| 508 | 508 | ||
| 509 | #define ALWAYS_ON_FEATURES \ | ||
| 510 | (NETIF_F_SG | NETIF_F_GEN_CSUM | NETIF_F_GSO_SOFTWARE | NETIF_F_LLTX) | ||
| 511 | |||
| 509 | #define MACVLAN_FEATURES \ | 512 | #define MACVLAN_FEATURES \ |
| 510 | (NETIF_F_SG | NETIF_F_ALL_CSUM | NETIF_F_HIGHDMA | NETIF_F_FRAGLIST | \ | 513 | (NETIF_F_SG | NETIF_F_ALL_CSUM | NETIF_F_HIGHDMA | NETIF_F_FRAGLIST | \ |
| 511 | NETIF_F_GSO | NETIF_F_TSO | NETIF_F_UFO | NETIF_F_GSO_ROBUST | \ | 514 | NETIF_F_GSO | NETIF_F_TSO | NETIF_F_UFO | NETIF_F_GSO_ROBUST | \ |
| @@ -539,7 +542,7 @@ static int macvlan_init(struct net_device *dev) | |||
| 539 | dev->state = (dev->state & ~MACVLAN_STATE_MASK) | | 542 | dev->state = (dev->state & ~MACVLAN_STATE_MASK) | |
| 540 | (lowerdev->state & MACVLAN_STATE_MASK); | 543 | (lowerdev->state & MACVLAN_STATE_MASK); |
| 541 | dev->features = lowerdev->features & MACVLAN_FEATURES; | 544 | dev->features = lowerdev->features & MACVLAN_FEATURES; |
| 542 | dev->features |= NETIF_F_LLTX; | 545 | dev->features |= ALWAYS_ON_FEATURES; |
| 543 | dev->gso_max_size = lowerdev->gso_max_size; | 546 | dev->gso_max_size = lowerdev->gso_max_size; |
| 544 | dev->iflink = lowerdev->ifindex; | 547 | dev->iflink = lowerdev->ifindex; |
| 545 | dev->hard_header_len = lowerdev->hard_header_len; | 548 | dev->hard_header_len = lowerdev->hard_header_len; |
| @@ -699,7 +702,7 @@ static netdev_features_t macvlan_fix_features(struct net_device *dev, | |||
| 699 | features = netdev_increment_features(vlan->lowerdev->features, | 702 | features = netdev_increment_features(vlan->lowerdev->features, |
| 700 | features, | 703 | features, |
| 701 | mask); | 704 | mask); |
| 702 | features |= NETIF_F_LLTX; | 705 | features |= ALWAYS_ON_FEATURES; |
| 703 | 706 | ||
| 704 | return features; | 707 | return features; |
| 705 | } | 708 | } |
| @@ -879,14 +882,15 @@ int macvlan_common_newlink(struct net *src_net, struct net_device *dev, | |||
| 879 | dev->priv_flags |= IFF_MACVLAN; | 882 | dev->priv_flags |= IFF_MACVLAN; |
| 880 | err = netdev_upper_dev_link(lowerdev, dev); | 883 | err = netdev_upper_dev_link(lowerdev, dev); |
| 881 | if (err) | 884 | if (err) |
| 882 | goto destroy_port; | 885 | goto unregister_netdev; |
| 883 | |||
| 884 | 886 | ||
| 885 | list_add_tail_rcu(&vlan->list, &port->vlans); | 887 | list_add_tail_rcu(&vlan->list, &port->vlans); |
| 886 | netif_stacked_transfer_operstate(lowerdev, dev); | 888 | netif_stacked_transfer_operstate(lowerdev, dev); |
| 887 | 889 | ||
| 888 | return 0; | 890 | return 0; |
| 889 | 891 | ||
| 892 | unregister_netdev: | ||
| 893 | unregister_netdevice(dev); | ||
| 890 | destroy_port: | 894 | destroy_port: |
| 891 | port->count -= 1; | 895 | port->count -= 1; |
| 892 | if (!port->count) | 896 | if (!port->count) |
diff --git a/drivers/net/phy/dp83640.c b/drivers/net/phy/dp83640.c index 547725fa8671..98e7cbf720a5 100644 --- a/drivers/net/phy/dp83640.c +++ b/drivers/net/phy/dp83640.c | |||
| @@ -437,7 +437,10 @@ static int ptp_dp83640_enable(struct ptp_clock_info *ptp, | |||
| 437 | if (on) { | 437 | if (on) { |
| 438 | gpio_num = gpio_tab[EXTTS0_GPIO + index]; | 438 | gpio_num = gpio_tab[EXTTS0_GPIO + index]; |
| 439 | evnt |= (gpio_num & EVNT_GPIO_MASK) << EVNT_GPIO_SHIFT; | 439 | evnt |= (gpio_num & EVNT_GPIO_MASK) << EVNT_GPIO_SHIFT; |
| 440 | evnt |= EVNT_RISE; | 440 | if (rq->extts.flags & PTP_FALLING_EDGE) |
| 441 | evnt |= EVNT_FALL; | ||
| 442 | else | ||
| 443 | evnt |= EVNT_RISE; | ||
| 441 | } | 444 | } |
| 442 | ext_write(0, phydev, PAGE5, PTP_EVNT, evnt); | 445 | ext_write(0, phydev, PAGE5, PTP_EVNT, evnt); |
| 443 | return 0; | 446 | return 0; |
| @@ -1003,11 +1006,6 @@ static int dp83640_probe(struct phy_device *phydev) | |||
| 1003 | } else | 1006 | } else |
| 1004 | list_add_tail(&dp83640->list, &clock->phylist); | 1007 | list_add_tail(&dp83640->list, &clock->phylist); |
| 1005 | 1008 | ||
| 1006 | if (clock->chosen && !list_empty(&clock->phylist)) | ||
| 1007 | recalibrate(clock); | ||
| 1008 | else | ||
| 1009 | enable_broadcast(dp83640->phydev, clock->page, 1); | ||
| 1010 | |||
| 1011 | dp83640_clock_put(clock); | 1009 | dp83640_clock_put(clock); |
| 1012 | return 0; | 1010 | return 0; |
| 1013 | 1011 | ||
| @@ -1058,6 +1056,21 @@ static void dp83640_remove(struct phy_device *phydev) | |||
| 1058 | kfree(dp83640); | 1056 | kfree(dp83640); |
| 1059 | } | 1057 | } |
| 1060 | 1058 | ||
| 1059 | static int dp83640_config_init(struct phy_device *phydev) | ||
| 1060 | { | ||
| 1061 | struct dp83640_private *dp83640 = phydev->priv; | ||
| 1062 | struct dp83640_clock *clock = dp83640->clock; | ||
| 1063 | |||
| 1064 | if (clock->chosen && !list_empty(&clock->phylist)) | ||
| 1065 | recalibrate(clock); | ||
| 1066 | else | ||
| 1067 | enable_broadcast(phydev, clock->page, 1); | ||
| 1068 | |||
| 1069 | enable_status_frames(phydev, true); | ||
| 1070 | ext_write(0, phydev, PAGE4, PTP_CTL, PTP_ENABLE); | ||
| 1071 | return 0; | ||
| 1072 | } | ||
| 1073 | |||
| 1061 | static int dp83640_ack_interrupt(struct phy_device *phydev) | 1074 | static int dp83640_ack_interrupt(struct phy_device *phydev) |
| 1062 | { | 1075 | { |
| 1063 | int err = phy_read(phydev, MII_DP83640_MISR); | 1076 | int err = phy_read(phydev, MII_DP83640_MISR); |
| @@ -1195,11 +1208,6 @@ static int dp83640_hwtstamp(struct phy_device *phydev, struct ifreq *ifr) | |||
| 1195 | 1208 | ||
| 1196 | mutex_lock(&dp83640->clock->extreg_lock); | 1209 | mutex_lock(&dp83640->clock->extreg_lock); |
| 1197 | 1210 | ||
| 1198 | if (dp83640->hwts_tx_en || dp83640->hwts_rx_en) { | ||
| 1199 | enable_status_frames(phydev, true); | ||
| 1200 | ext_write(0, phydev, PAGE4, PTP_CTL, PTP_ENABLE); | ||
| 1201 | } | ||
| 1202 | |||
| 1203 | ext_write(0, phydev, PAGE5, PTP_TXCFG0, txcfg0); | 1211 | ext_write(0, phydev, PAGE5, PTP_TXCFG0, txcfg0); |
| 1204 | ext_write(0, phydev, PAGE5, PTP_RXCFG0, rxcfg0); | 1212 | ext_write(0, phydev, PAGE5, PTP_RXCFG0, rxcfg0); |
| 1205 | 1213 | ||
| @@ -1281,6 +1289,7 @@ static void dp83640_txtstamp(struct phy_device *phydev, | |||
| 1281 | } | 1289 | } |
| 1282 | /* fall through */ | 1290 | /* fall through */ |
| 1283 | case HWTSTAMP_TX_ON: | 1291 | case HWTSTAMP_TX_ON: |
| 1292 | skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS; | ||
| 1284 | skb_queue_tail(&dp83640->tx_queue, skb); | 1293 | skb_queue_tail(&dp83640->tx_queue, skb); |
| 1285 | schedule_work(&dp83640->ts_work); | 1294 | schedule_work(&dp83640->ts_work); |
| 1286 | break; | 1295 | break; |
| @@ -1330,6 +1339,7 @@ static struct phy_driver dp83640_driver = { | |||
| 1330 | .flags = PHY_HAS_INTERRUPT, | 1339 | .flags = PHY_HAS_INTERRUPT, |
| 1331 | .probe = dp83640_probe, | 1340 | .probe = dp83640_probe, |
| 1332 | .remove = dp83640_remove, | 1341 | .remove = dp83640_remove, |
| 1342 | .config_init = dp83640_config_init, | ||
| 1333 | .config_aneg = genphy_config_aneg, | 1343 | .config_aneg = genphy_config_aneg, |
| 1334 | .read_status = genphy_read_status, | 1344 | .read_status = genphy_read_status, |
| 1335 | .ack_interrupt = dp83640_ack_interrupt, | 1345 | .ack_interrupt = dp83640_ack_interrupt, |
diff --git a/drivers/net/phy/mdio-sun4i.c b/drivers/net/phy/mdio-sun4i.c index bb88bc7d81fb..9367acc84fbb 100644 --- a/drivers/net/phy/mdio-sun4i.c +++ b/drivers/net/phy/mdio-sun4i.c | |||
| @@ -170,6 +170,9 @@ static int sun4i_mdio_remove(struct platform_device *pdev) | |||
| 170 | } | 170 | } |
| 171 | 171 | ||
| 172 | static const struct of_device_id sun4i_mdio_dt_ids[] = { | 172 | static const struct of_device_id sun4i_mdio_dt_ids[] = { |
| 173 | { .compatible = "allwinner,sun4i-a10-mdio" }, | ||
| 174 | |||
| 175 | /* Deprecated */ | ||
| 173 | { .compatible = "allwinner,sun4i-mdio" }, | 176 | { .compatible = "allwinner,sun4i-mdio" }, |
| 174 | { } | 177 | { } |
| 175 | }; | 178 | }; |
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c index 4b03e63639b7..4b970f7624c0 100644 --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c | |||
| @@ -719,7 +719,7 @@ int phy_resume(struct phy_device *phydev) | |||
| 719 | static int genphy_config_advert(struct phy_device *phydev) | 719 | static int genphy_config_advert(struct phy_device *phydev) |
| 720 | { | 720 | { |
| 721 | u32 advertise; | 721 | u32 advertise; |
| 722 | int oldadv, adv; | 722 | int oldadv, adv, bmsr; |
| 723 | int err, changed = 0; | 723 | int err, changed = 0; |
| 724 | 724 | ||
| 725 | /* Only allow advertising what this PHY supports */ | 725 | /* Only allow advertising what this PHY supports */ |
| @@ -744,26 +744,36 @@ static int genphy_config_advert(struct phy_device *phydev) | |||
| 744 | changed = 1; | 744 | changed = 1; |
| 745 | } | 745 | } |
| 746 | 746 | ||
| 747 | bmsr = phy_read(phydev, MII_BMSR); | ||
| 748 | if (bmsr < 0) | ||
| 749 | return bmsr; | ||
| 750 | |||
| 751 | /* Per 802.3-2008, Section 22.2.4.2.16 Extended status all | ||
| 752 | * 1000Mbits/sec capable PHYs shall have the BMSR_ESTATEN bit set to a | ||
| 753 | * logical 1. | ||
| 754 | */ | ||
| 755 | if (!(bmsr & BMSR_ESTATEN)) | ||
| 756 | return changed; | ||
| 757 | |||
| 747 | /* Configure gigabit if it's supported */ | 758 | /* Configure gigabit if it's supported */ |
| 759 | adv = phy_read(phydev, MII_CTRL1000); | ||
| 760 | if (adv < 0) | ||
| 761 | return adv; | ||
| 762 | |||
| 763 | oldadv = adv; | ||
| 764 | adv &= ~(ADVERTISE_1000FULL | ADVERTISE_1000HALF); | ||
| 765 | |||
| 748 | if (phydev->supported & (SUPPORTED_1000baseT_Half | | 766 | if (phydev->supported & (SUPPORTED_1000baseT_Half | |
| 749 | SUPPORTED_1000baseT_Full)) { | 767 | SUPPORTED_1000baseT_Full)) { |
| 750 | adv = phy_read(phydev, MII_CTRL1000); | ||
| 751 | if (adv < 0) | ||
| 752 | return adv; | ||
| 753 | |||
| 754 | oldadv = adv; | ||
| 755 | adv &= ~(ADVERTISE_1000FULL | ADVERTISE_1000HALF); | ||
| 756 | adv |= ethtool_adv_to_mii_ctrl1000_t(advertise); | 768 | adv |= ethtool_adv_to_mii_ctrl1000_t(advertise); |
| 757 | 769 | if (adv != oldadv) | |
| 758 | if (adv != oldadv) { | ||
| 759 | err = phy_write(phydev, MII_CTRL1000, adv); | ||
| 760 | |||
| 761 | if (err < 0) | ||
| 762 | return err; | ||
| 763 | changed = 1; | 770 | changed = 1; |
| 764 | } | ||
| 765 | } | 771 | } |
| 766 | 772 | ||
| 773 | err = phy_write(phydev, MII_CTRL1000, adv); | ||
| 774 | if (err < 0) | ||
| 775 | return err; | ||
| 776 | |||
| 767 | return changed; | 777 | return changed; |
| 768 | } | 778 | } |
| 769 | 779 | ||
| @@ -906,6 +916,8 @@ int genphy_read_status(struct phy_device *phydev) | |||
| 906 | int err; | 916 | int err; |
| 907 | int lpa; | 917 | int lpa; |
| 908 | int lpagb = 0; | 918 | int lpagb = 0; |
| 919 | int common_adv; | ||
| 920 | int common_adv_gb = 0; | ||
| 909 | 921 | ||
| 910 | /* Update the link, but return if there was an error */ | 922 | /* Update the link, but return if there was an error */ |
| 911 | err = genphy_update_link(phydev); | 923 | err = genphy_update_link(phydev); |
| @@ -927,7 +939,7 @@ int genphy_read_status(struct phy_device *phydev) | |||
| 927 | 939 | ||
| 928 | phydev->lp_advertising = | 940 | phydev->lp_advertising = |
| 929 | mii_stat1000_to_ethtool_lpa_t(lpagb); | 941 | mii_stat1000_to_ethtool_lpa_t(lpagb); |
| 930 | lpagb &= adv << 2; | 942 | common_adv_gb = lpagb & adv << 2; |
| 931 | } | 943 | } |
| 932 | 944 | ||
| 933 | lpa = phy_read(phydev, MII_LPA); | 945 | lpa = phy_read(phydev, MII_LPA); |
| @@ -940,25 +952,25 @@ int genphy_read_status(struct phy_device *phydev) | |||
| 940 | if (adv < 0) | 952 | if (adv < 0) |
| 941 | return adv; | 953 | return adv; |
| 942 | 954 | ||
| 943 | lpa &= adv; | 955 | common_adv = lpa & adv; |
| 944 | 956 | ||
| 945 | phydev->speed = SPEED_10; | 957 | phydev->speed = SPEED_10; |
| 946 | phydev->duplex = DUPLEX_HALF; | 958 | phydev->duplex = DUPLEX_HALF; |
| 947 | phydev->pause = 0; | 959 | phydev->pause = 0; |
| 948 | phydev->asym_pause = 0; | 960 | phydev->asym_pause = 0; |
| 949 | 961 | ||
| 950 | if (lpagb & (LPA_1000FULL | LPA_1000HALF)) { | 962 | if (common_adv_gb & (LPA_1000FULL | LPA_1000HALF)) { |
| 951 | phydev->speed = SPEED_1000; | 963 | phydev->speed = SPEED_1000; |
| 952 | 964 | ||
| 953 | if (lpagb & LPA_1000FULL) | 965 | if (common_adv_gb & LPA_1000FULL) |
| 954 | phydev->duplex = DUPLEX_FULL; | 966 | phydev->duplex = DUPLEX_FULL; |
| 955 | } else if (lpa & (LPA_100FULL | LPA_100HALF)) { | 967 | } else if (common_adv & (LPA_100FULL | LPA_100HALF)) { |
| 956 | phydev->speed = SPEED_100; | 968 | phydev->speed = SPEED_100; |
| 957 | 969 | ||
| 958 | if (lpa & LPA_100FULL) | 970 | if (common_adv & LPA_100FULL) |
| 959 | phydev->duplex = DUPLEX_FULL; | 971 | phydev->duplex = DUPLEX_FULL; |
| 960 | } else | 972 | } else |
| 961 | if (lpa & LPA_10FULL) | 973 | if (common_adv & LPA_10FULL) |
| 962 | phydev->duplex = DUPLEX_FULL; | 974 | phydev->duplex = DUPLEX_FULL; |
| 963 | 975 | ||
| 964 | if (phydev->duplex == DUPLEX_FULL) { | 976 | if (phydev->duplex == DUPLEX_FULL) { |
diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c index 28407426fd6f..c8624a8235ab 100644 --- a/drivers/net/team/team.c +++ b/drivers/net/team/team.c | |||
| @@ -1648,7 +1648,7 @@ static netdev_tx_t team_xmit(struct sk_buff *skb, struct net_device *dev) | |||
| 1648 | } | 1648 | } |
| 1649 | 1649 | ||
| 1650 | static u16 team_select_queue(struct net_device *dev, struct sk_buff *skb, | 1650 | static u16 team_select_queue(struct net_device *dev, struct sk_buff *skb, |
| 1651 | void *accel_priv) | 1651 | void *accel_priv, select_queue_fallback_t fallback) |
| 1652 | { | 1652 | { |
| 1653 | /* | 1653 | /* |
| 1654 | * This helper function exists to help dev_pick_tx get the correct | 1654 | * This helper function exists to help dev_pick_tx get the correct |
diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 44c4db8450f0..26f8635b027d 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c | |||
| @@ -366,7 +366,7 @@ static inline void tun_flow_save_rps_rxhash(struct tun_flow_entry *e, u32 hash) | |||
| 366 | * hope the rxq no. may help here. | 366 | * hope the rxq no. may help here. |
| 367 | */ | 367 | */ |
| 368 | static u16 tun_select_queue(struct net_device *dev, struct sk_buff *skb, | 368 | static u16 tun_select_queue(struct net_device *dev, struct sk_buff *skb, |
| 369 | void *accel_priv) | 369 | void *accel_priv, select_queue_fallback_t fallback) |
| 370 | { | 370 | { |
| 371 | struct tun_struct *tun = netdev_priv(dev); | 371 | struct tun_struct *tun = netdev_priv(dev); |
| 372 | struct tun_flow_entry *e; | 372 | struct tun_flow_entry *e; |
| @@ -1686,7 +1686,9 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) | |||
| 1686 | TUN_USER_FEATURES | NETIF_F_HW_VLAN_CTAG_TX | | 1686 | TUN_USER_FEATURES | NETIF_F_HW_VLAN_CTAG_TX | |
| 1687 | NETIF_F_HW_VLAN_STAG_TX; | 1687 | NETIF_F_HW_VLAN_STAG_TX; |
| 1688 | dev->features = dev->hw_features; | 1688 | dev->features = dev->hw_features; |
| 1689 | dev->vlan_features = dev->features; | 1689 | dev->vlan_features = dev->features & |
| 1690 | ~(NETIF_F_HW_VLAN_CTAG_TX | | ||
| 1691 | NETIF_F_HW_VLAN_STAG_TX); | ||
| 1690 | 1692 | ||
| 1691 | INIT_LIST_HEAD(&tun->disabled); | 1693 | INIT_LIST_HEAD(&tun->disabled); |
| 1692 | err = tun_attach(tun, file, false); | 1694 | err = tun_attach(tun, file, false); |
diff --git a/drivers/net/usb/Kconfig b/drivers/net/usb/Kconfig index 6b638a066c1d..7e7269fd3707 100644 --- a/drivers/net/usb/Kconfig +++ b/drivers/net/usb/Kconfig | |||
| @@ -292,6 +292,21 @@ config USB_NET_SR9700 | |||
| 292 | This option adds support for CoreChip-sz SR9700 based USB 1.1 | 292 | This option adds support for CoreChip-sz SR9700 based USB 1.1 |
| 293 | 10/100 Ethernet adapters. | 293 | 10/100 Ethernet adapters. |
| 294 | 294 | ||
| 295 | config USB_NET_SR9800 | ||
| 296 | tristate "CoreChip-sz SR9800 based USB 2.0 10/100 ethernet devices" | ||
| 297 | depends on USB_USBNET | ||
| 298 | select CRC32 | ||
| 299 | ---help--- | ||
| 300 | Say Y if you want to use one of the following 100Mbps USB Ethernet | ||
| 301 | device based on the CoreChip-sz SR9800 chip. | ||
| 302 | |||
| 303 | This driver makes the adapter appear as a normal Ethernet interface, | ||
| 304 | typically on eth0, if it is the only ethernet device, or perhaps on | ||
| 305 | eth1, if you have a PCI or ISA ethernet card installed. | ||
| 306 | |||
| 307 | To compile this driver as a module, choose M here: the | ||
| 308 | module will be called sr9800. | ||
| 309 | |||
| 295 | config USB_NET_SMSC75XX | 310 | config USB_NET_SMSC75XX |
| 296 | tristate "SMSC LAN75XX based USB 2.0 gigabit ethernet devices" | 311 | tristate "SMSC LAN75XX based USB 2.0 gigabit ethernet devices" |
| 297 | depends on USB_USBNET | 312 | depends on USB_USBNET |
diff --git a/drivers/net/usb/Makefile b/drivers/net/usb/Makefile index b17b5e88bbaf..433f0a00c683 100644 --- a/drivers/net/usb/Makefile +++ b/drivers/net/usb/Makefile | |||
| @@ -15,6 +15,7 @@ obj-$(CONFIG_USB_NET_CDCETHER) += cdc_ether.o r815x.o | |||
| 15 | obj-$(CONFIG_USB_NET_CDC_EEM) += cdc_eem.o | 15 | obj-$(CONFIG_USB_NET_CDC_EEM) += cdc_eem.o |
| 16 | obj-$(CONFIG_USB_NET_DM9601) += dm9601.o | 16 | obj-$(CONFIG_USB_NET_DM9601) += dm9601.o |
| 17 | obj-$(CONFIG_USB_NET_SR9700) += sr9700.o | 17 | obj-$(CONFIG_USB_NET_SR9700) += sr9700.o |
| 18 | obj-$(CONFIG_USB_NET_SR9800) += sr9800.o | ||
| 18 | obj-$(CONFIG_USB_NET_SMSC75XX) += smsc75xx.o | 19 | obj-$(CONFIG_USB_NET_SMSC75XX) += smsc75xx.o |
| 19 | obj-$(CONFIG_USB_NET_SMSC95XX) += smsc95xx.o | 20 | obj-$(CONFIG_USB_NET_SMSC95XX) += smsc95xx.o |
| 20 | obj-$(CONFIG_USB_NET_GL620A) += gl620a.o | 21 | obj-$(CONFIG_USB_NET_GL620A) += gl620a.o |
diff --git a/drivers/net/usb/asix_devices.c b/drivers/net/usb/asix_devices.c index 9765a7d4766d..5d194093f3e1 100644 --- a/drivers/net/usb/asix_devices.c +++ b/drivers/net/usb/asix_devices.c | |||
| @@ -917,7 +917,8 @@ static const struct driver_info ax88178_info = { | |||
| 917 | .status = asix_status, | 917 | .status = asix_status, |
| 918 | .link_reset = ax88178_link_reset, | 918 | .link_reset = ax88178_link_reset, |
| 919 | .reset = ax88178_reset, | 919 | .reset = ax88178_reset, |
| 920 | .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_LINK_INTR, | 920 | .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_LINK_INTR | |
| 921 | FLAG_MULTI_PACKET, | ||
| 921 | .rx_fixup = asix_rx_fixup_common, | 922 | .rx_fixup = asix_rx_fixup_common, |
| 922 | .tx_fixup = asix_tx_fixup, | 923 | .tx_fixup = asix_tx_fixup, |
| 923 | }; | 924 | }; |
diff --git a/drivers/net/usb/ax88179_178a.c b/drivers/net/usb/ax88179_178a.c index d6f64dad05bc..054e59ca6946 100644 --- a/drivers/net/usb/ax88179_178a.c +++ b/drivers/net/usb/ax88179_178a.c | |||
| @@ -1029,20 +1029,12 @@ static int ax88179_bind(struct usbnet *dev, struct usb_interface *intf) | |||
| 1029 | dev->mii.phy_id = 0x03; | 1029 | dev->mii.phy_id = 0x03; |
| 1030 | dev->mii.supports_gmii = 1; | 1030 | dev->mii.supports_gmii = 1; |
| 1031 | 1031 | ||
| 1032 | if (usb_device_no_sg_constraint(dev->udev)) | ||
| 1033 | dev->can_dma_sg = 1; | ||
| 1034 | |||
| 1035 | dev->net->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | | 1032 | dev->net->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | |
| 1036 | NETIF_F_RXCSUM; | 1033 | NETIF_F_RXCSUM; |
| 1037 | 1034 | ||
| 1038 | dev->net->hw_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | | 1035 | dev->net->hw_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | |
| 1039 | NETIF_F_RXCSUM; | 1036 | NETIF_F_RXCSUM; |
| 1040 | 1037 | ||
| 1041 | if (dev->can_dma_sg) { | ||
| 1042 | dev->net->features |= NETIF_F_SG | NETIF_F_TSO; | ||
| 1043 | dev->net->hw_features |= NETIF_F_SG | NETIF_F_TSO; | ||
| 1044 | } | ||
| 1045 | |||
| 1046 | /* Enable checksum offload */ | 1038 | /* Enable checksum offload */ |
| 1047 | *tmp = AX_RXCOE_IP | AX_RXCOE_TCP | AX_RXCOE_UDP | | 1039 | *tmp = AX_RXCOE_IP | AX_RXCOE_TCP | AX_RXCOE_UDP | |
| 1048 | AX_RXCOE_TCPV6 | AX_RXCOE_UDPV6; | 1040 | AX_RXCOE_TCPV6 | AX_RXCOE_UDPV6; |
| @@ -1118,6 +1110,10 @@ static int ax88179_rx_fixup(struct usbnet *dev, struct sk_buff *skb) | |||
| 1118 | u16 hdr_off; | 1110 | u16 hdr_off; |
| 1119 | u32 *pkt_hdr; | 1111 | u32 *pkt_hdr; |
| 1120 | 1112 | ||
| 1113 | /* This check is no longer done by usbnet */ | ||
| 1114 | if (skb->len < dev->net->hard_header_len) | ||
| 1115 | return 0; | ||
| 1116 | |||
| 1121 | skb_trim(skb, skb->len - 4); | 1117 | skb_trim(skb, skb->len - 4); |
| 1122 | memcpy(&rx_hdr, skb_tail_pointer(skb), 4); | 1118 | memcpy(&rx_hdr, skb_tail_pointer(skb), 4); |
| 1123 | le32_to_cpus(&rx_hdr); | 1119 | le32_to_cpus(&rx_hdr); |
| @@ -1391,6 +1387,19 @@ static const struct driver_info ax88178a_info = { | |||
| 1391 | .tx_fixup = ax88179_tx_fixup, | 1387 | .tx_fixup = ax88179_tx_fixup, |
| 1392 | }; | 1388 | }; |
| 1393 | 1389 | ||
| 1390 | static const struct driver_info dlink_dub1312_info = { | ||
| 1391 | .description = "D-Link DUB-1312 USB 3.0 to Gigabit Ethernet Adapter", | ||
| 1392 | .bind = ax88179_bind, | ||
| 1393 | .unbind = ax88179_unbind, | ||
| 1394 | .status = ax88179_status, | ||
| 1395 | .link_reset = ax88179_link_reset, | ||
| 1396 | .reset = ax88179_reset, | ||
| 1397 | .stop = ax88179_stop, | ||
| 1398 | .flags = FLAG_ETHER | FLAG_FRAMING_AX, | ||
| 1399 | .rx_fixup = ax88179_rx_fixup, | ||
| 1400 | .tx_fixup = ax88179_tx_fixup, | ||
| 1401 | }; | ||
| 1402 | |||
| 1394 | static const struct driver_info sitecom_info = { | 1403 | static const struct driver_info sitecom_info = { |
| 1395 | .description = "Sitecom USB 3.0 to Gigabit Adapter", | 1404 | .description = "Sitecom USB 3.0 to Gigabit Adapter", |
| 1396 | .bind = ax88179_bind, | 1405 | .bind = ax88179_bind, |
| @@ -1417,6 +1426,19 @@ static const struct driver_info samsung_info = { | |||
| 1417 | .tx_fixup = ax88179_tx_fixup, | 1426 | .tx_fixup = ax88179_tx_fixup, |
| 1418 | }; | 1427 | }; |
| 1419 | 1428 | ||
| 1429 | static const struct driver_info lenovo_info = { | ||
| 1430 | .description = "Lenovo OneLinkDock Gigabit LAN", | ||
| 1431 | .bind = ax88179_bind, | ||
| 1432 | .unbind = ax88179_unbind, | ||
| 1433 | .status = ax88179_status, | ||
| 1434 | .link_reset = ax88179_link_reset, | ||
| 1435 | .reset = ax88179_reset, | ||
| 1436 | .stop = ax88179_stop, | ||
| 1437 | .flags = FLAG_ETHER | FLAG_FRAMING_AX, | ||
| 1438 | .rx_fixup = ax88179_rx_fixup, | ||
| 1439 | .tx_fixup = ax88179_tx_fixup, | ||
| 1440 | }; | ||
| 1441 | |||
| 1420 | static const struct usb_device_id products[] = { | 1442 | static const struct usb_device_id products[] = { |
| 1421 | { | 1443 | { |
| 1422 | /* ASIX AX88179 10/100/1000 */ | 1444 | /* ASIX AX88179 10/100/1000 */ |
| @@ -1427,6 +1449,10 @@ static const struct usb_device_id products[] = { | |||
| 1427 | USB_DEVICE(0x0b95, 0x178a), | 1449 | USB_DEVICE(0x0b95, 0x178a), |
| 1428 | .driver_info = (unsigned long)&ax88178a_info, | 1450 | .driver_info = (unsigned long)&ax88178a_info, |
| 1429 | }, { | 1451 | }, { |
| 1452 | /* D-Link DUB-1312 USB 3.0 to Gigabit Ethernet Adapter */ | ||
| 1453 | USB_DEVICE(0x2001, 0x4a00), | ||
| 1454 | .driver_info = (unsigned long)&dlink_dub1312_info, | ||
| 1455 | }, { | ||
| 1430 | /* Sitecom USB 3.0 to Gigabit Adapter */ | 1456 | /* Sitecom USB 3.0 to Gigabit Adapter */ |
| 1431 | USB_DEVICE(0x0df6, 0x0072), | 1457 | USB_DEVICE(0x0df6, 0x0072), |
| 1432 | .driver_info = (unsigned long)&sitecom_info, | 1458 | .driver_info = (unsigned long)&sitecom_info, |
| @@ -1434,6 +1460,10 @@ static const struct usb_device_id products[] = { | |||
| 1434 | /* Samsung USB Ethernet Adapter */ | 1460 | /* Samsung USB Ethernet Adapter */ |
| 1435 | USB_DEVICE(0x04e8, 0xa100), | 1461 | USB_DEVICE(0x04e8, 0xa100), |
| 1436 | .driver_info = (unsigned long)&samsung_info, | 1462 | .driver_info = (unsigned long)&samsung_info, |
| 1463 | }, { | ||
| 1464 | /* Lenovo OneLinkDock Gigabit LAN */ | ||
| 1465 | USB_DEVICE(0x17ef, 0x304b), | ||
| 1466 | .driver_info = (unsigned long)&lenovo_info, | ||
| 1437 | }, | 1467 | }, |
| 1438 | { }, | 1468 | { }, |
| 1439 | }; | 1469 | }; |
diff --git a/drivers/net/usb/gl620a.c b/drivers/net/usb/gl620a.c index e4a8a93fbaf7..1cc24e6f23e2 100644 --- a/drivers/net/usb/gl620a.c +++ b/drivers/net/usb/gl620a.c | |||
| @@ -84,6 +84,10 @@ static int genelink_rx_fixup(struct usbnet *dev, struct sk_buff *skb) | |||
| 84 | u32 size; | 84 | u32 size; |
| 85 | u32 count; | 85 | u32 count; |
| 86 | 86 | ||
| 87 | /* This check is no longer done by usbnet */ | ||
| 88 | if (skb->len < dev->net->hard_header_len) | ||
| 89 | return 0; | ||
| 90 | |||
| 87 | header = (struct gl_header *) skb->data; | 91 | header = (struct gl_header *) skb->data; |
| 88 | 92 | ||
| 89 | // get the packet count of the received skb | 93 | // get the packet count of the received skb |
diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index 1a482344b3f5..660bd5ea9fc0 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c | |||
| @@ -1201,16 +1201,18 @@ static void hso_std_serial_read_bulk_callback(struct urb *urb) | |||
| 1201 | struct hso_serial *serial = urb->context; | 1201 | struct hso_serial *serial = urb->context; |
| 1202 | int status = urb->status; | 1202 | int status = urb->status; |
| 1203 | 1203 | ||
| 1204 | D4("\n--- Got serial_read_bulk callback %02x ---", status); | ||
| 1205 | |||
| 1204 | /* sanity check */ | 1206 | /* sanity check */ |
| 1205 | if (!serial) { | 1207 | if (!serial) { |
| 1206 | D1("serial == NULL"); | 1208 | D1("serial == NULL"); |
| 1207 | return; | 1209 | return; |
| 1208 | } else if (status) { | 1210 | } |
| 1211 | if (status) { | ||
| 1209 | handle_usb_error(status, __func__, serial->parent); | 1212 | handle_usb_error(status, __func__, serial->parent); |
| 1210 | return; | 1213 | return; |
| 1211 | } | 1214 | } |
| 1212 | 1215 | ||
| 1213 | D4("\n--- Got serial_read_bulk callback %02x ---", status); | ||
| 1214 | D1("Actual length = %d\n", urb->actual_length); | 1216 | D1("Actual length = %d\n", urb->actual_length); |
| 1215 | DUMP1(urb->transfer_buffer, urb->actual_length); | 1217 | DUMP1(urb->transfer_buffer, urb->actual_length); |
| 1216 | 1218 | ||
| @@ -1218,25 +1220,13 @@ static void hso_std_serial_read_bulk_callback(struct urb *urb) | |||
| 1218 | if (serial->port.count == 0) | 1220 | if (serial->port.count == 0) |
| 1219 | return; | 1221 | return; |
| 1220 | 1222 | ||
| 1221 | if (status == 0) { | 1223 | if (serial->parent->port_spec & HSO_INFO_CRC_BUG) |
| 1222 | if (serial->parent->port_spec & HSO_INFO_CRC_BUG) | 1224 | fix_crc_bug(urb, serial->in_endp->wMaxPacketSize); |
| 1223 | fix_crc_bug(urb, serial->in_endp->wMaxPacketSize); | 1225 | /* Valid data, handle RX data */ |
| 1224 | /* Valid data, handle RX data */ | 1226 | spin_lock(&serial->serial_lock); |
| 1225 | spin_lock(&serial->serial_lock); | 1227 | serial->rx_urb_filled[hso_urb_to_index(serial, urb)] = 1; |
| 1226 | serial->rx_urb_filled[hso_urb_to_index(serial, urb)] = 1; | 1228 | put_rxbuf_data_and_resubmit_bulk_urb(serial); |
| 1227 | put_rxbuf_data_and_resubmit_bulk_urb(serial); | 1229 | spin_unlock(&serial->serial_lock); |
| 1228 | spin_unlock(&serial->serial_lock); | ||
| 1229 | } else if (status == -ENOENT || status == -ECONNRESET) { | ||
| 1230 | /* Unlinked - check for throttled port. */ | ||
| 1231 | D2("Port %d, successfully unlinked urb", serial->minor); | ||
| 1232 | spin_lock(&serial->serial_lock); | ||
| 1233 | serial->rx_urb_filled[hso_urb_to_index(serial, urb)] = 0; | ||
| 1234 | hso_resubmit_rx_bulk_urb(serial, urb); | ||
| 1235 | spin_unlock(&serial->serial_lock); | ||
| 1236 | } else { | ||
| 1237 | D2("Port %d, status = %d for read urb", serial->minor, status); | ||
| 1238 | return; | ||
| 1239 | } | ||
| 1240 | } | 1230 | } |
| 1241 | 1231 | ||
| 1242 | /* | 1232 | /* |
diff --git a/drivers/net/usb/mcs7830.c b/drivers/net/usb/mcs7830.c index a305a7b2dae6..82d844a8ebd0 100644 --- a/drivers/net/usb/mcs7830.c +++ b/drivers/net/usb/mcs7830.c | |||
| @@ -526,8 +526,9 @@ static int mcs7830_rx_fixup(struct usbnet *dev, struct sk_buff *skb) | |||
| 526 | { | 526 | { |
| 527 | u8 status; | 527 | u8 status; |
| 528 | 528 | ||
| 529 | if (skb->len == 0) { | 529 | /* This check is no longer done by usbnet */ |
| 530 | dev_err(&dev->udev->dev, "unexpected empty rx frame\n"); | 530 | if (skb->len < dev->net->hard_header_len) { |
| 531 | dev_err(&dev->udev->dev, "unexpected tiny rx frame\n"); | ||
| 531 | return 0; | 532 | return 0; |
| 532 | } | 533 | } |
| 533 | 534 | ||
diff --git a/drivers/net/usb/net1080.c b/drivers/net/usb/net1080.c index 0a85d9227775..4cbdb1307f3e 100644 --- a/drivers/net/usb/net1080.c +++ b/drivers/net/usb/net1080.c | |||
| @@ -364,6 +364,10 @@ static int net1080_rx_fixup(struct usbnet *dev, struct sk_buff *skb) | |||
| 364 | struct nc_trailer *trailer; | 364 | struct nc_trailer *trailer; |
| 365 | u16 hdr_len, packet_len; | 365 | u16 hdr_len, packet_len; |
| 366 | 366 | ||
| 367 | /* This check is no longer done by usbnet */ | ||
| 368 | if (skb->len < dev->net->hard_header_len) | ||
| 369 | return 0; | ||
| 370 | |||
| 367 | if (!(skb->len & 0x01)) { | 371 | if (!(skb->len & 0x01)) { |
| 368 | netdev_dbg(dev->net, "rx framesize %d range %d..%d mtu %d\n", | 372 | netdev_dbg(dev->net, "rx framesize %d range %d..%d mtu %d\n", |
| 369 | skb->len, dev->net->hard_header_len, dev->hard_mtu, | 373 | skb->len, dev->net->hard_header_len, dev->hard_mtu, |
diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c index 23bdd5b9274d..313cb6cd4848 100644 --- a/drivers/net/usb/qmi_wwan.c +++ b/drivers/net/usb/qmi_wwan.c | |||
| @@ -80,10 +80,10 @@ static int qmi_wwan_rx_fixup(struct usbnet *dev, struct sk_buff *skb) | |||
| 80 | { | 80 | { |
| 81 | __be16 proto; | 81 | __be16 proto; |
| 82 | 82 | ||
| 83 | /* usbnet rx_complete guarantees that skb->len is at least | 83 | /* This check is no longer done by usbnet */ |
| 84 | * hard_header_len, so we can inspect the dest address without | 84 | if (skb->len < dev->net->hard_header_len) |
| 85 | * checking skb->len | 85 | return 0; |
| 86 | */ | 86 | |
| 87 | switch (skb->data[0] & 0xf0) { | 87 | switch (skb->data[0] & 0xf0) { |
| 88 | case 0x40: | 88 | case 0x40: |
| 89 | proto = htons(ETH_P_IP); | 89 | proto = htons(ETH_P_IP); |
| @@ -712,6 +712,7 @@ static const struct usb_device_id products[] = { | |||
| 712 | {QMI_FIXED_INTF(0x19d2, 0x1255, 3)}, | 712 | {QMI_FIXED_INTF(0x19d2, 0x1255, 3)}, |
| 713 | {QMI_FIXED_INTF(0x19d2, 0x1255, 4)}, | 713 | {QMI_FIXED_INTF(0x19d2, 0x1255, 4)}, |
| 714 | {QMI_FIXED_INTF(0x19d2, 0x1256, 4)}, | 714 | {QMI_FIXED_INTF(0x19d2, 0x1256, 4)}, |
| 715 | {QMI_FIXED_INTF(0x19d2, 0x1270, 5)}, /* ZTE MF667 */ | ||
| 715 | {QMI_FIXED_INTF(0x19d2, 0x1401, 2)}, | 716 | {QMI_FIXED_INTF(0x19d2, 0x1401, 2)}, |
| 716 | {QMI_FIXED_INTF(0x19d2, 0x1402, 2)}, /* ZTE MF60 */ | 717 | {QMI_FIXED_INTF(0x19d2, 0x1402, 2)}, /* ZTE MF60 */ |
| 717 | {QMI_FIXED_INTF(0x19d2, 0x1424, 2)}, | 718 | {QMI_FIXED_INTF(0x19d2, 0x1424, 2)}, |
| @@ -723,6 +724,7 @@ static const struct usb_device_id products[] = { | |||
| 723 | {QMI_FIXED_INTF(0x1199, 0x68a2, 8)}, /* Sierra Wireless MC7710 in QMI mode */ | 724 | {QMI_FIXED_INTF(0x1199, 0x68a2, 8)}, /* Sierra Wireless MC7710 in QMI mode */ |
| 724 | {QMI_FIXED_INTF(0x1199, 0x68a2, 19)}, /* Sierra Wireless MC7710 in QMI mode */ | 725 | {QMI_FIXED_INTF(0x1199, 0x68a2, 19)}, /* Sierra Wireless MC7710 in QMI mode */ |
| 725 | {QMI_FIXED_INTF(0x1199, 0x901c, 8)}, /* Sierra Wireless EM7700 */ | 726 | {QMI_FIXED_INTF(0x1199, 0x901c, 8)}, /* Sierra Wireless EM7700 */ |
| 727 | {QMI_FIXED_INTF(0x1199, 0x9051, 8)}, /* Netgear AirCard 340U */ | ||
| 726 | {QMI_FIXED_INTF(0x1bbb, 0x011e, 4)}, /* Telekom Speedstick LTE II (Alcatel One Touch L100V LTE) */ | 728 | {QMI_FIXED_INTF(0x1bbb, 0x011e, 4)}, /* Telekom Speedstick LTE II (Alcatel One Touch L100V LTE) */ |
| 727 | {QMI_FIXED_INTF(0x2357, 0x0201, 4)}, /* TP-LINK HSUPA Modem MA180 */ | 729 | {QMI_FIXED_INTF(0x2357, 0x0201, 4)}, /* TP-LINK HSUPA Modem MA180 */ |
| 728 | {QMI_FIXED_INTF(0x2357, 0x9000, 4)}, /* TP-LINK MA260 */ | 730 | {QMI_FIXED_INTF(0x2357, 0x9000, 4)}, /* TP-LINK MA260 */ |
| @@ -730,6 +732,7 @@ static const struct usb_device_id products[] = { | |||
| 730 | {QMI_FIXED_INTF(0x1bc7, 0x1201, 2)}, /* Telit LE920 */ | 732 | {QMI_FIXED_INTF(0x1bc7, 0x1201, 2)}, /* Telit LE920 */ |
| 731 | {QMI_FIXED_INTF(0x0b3c, 0xc005, 6)}, /* Olivetti Olicard 200 */ | 733 | {QMI_FIXED_INTF(0x0b3c, 0xc005, 6)}, /* Olivetti Olicard 200 */ |
| 732 | {QMI_FIXED_INTF(0x1e2d, 0x0060, 4)}, /* Cinterion PLxx */ | 734 | {QMI_FIXED_INTF(0x1e2d, 0x0060, 4)}, /* Cinterion PLxx */ |
| 735 | {QMI_FIXED_INTF(0x1e2d, 0x0053, 4)}, /* Cinterion PHxx,PXxx */ | ||
| 733 | 736 | ||
| 734 | /* 4. Gobi 1000 devices */ | 737 | /* 4. Gobi 1000 devices */ |
| 735 | {QMI_GOBI1K_DEVICE(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */ | 738 | {QMI_GOBI1K_DEVICE(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */ |
diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index e8fac732c6f1..d89dbe395ad2 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c | |||
| @@ -2273,22 +2273,21 @@ static int rtl8152_open(struct net_device *netdev) | |||
| 2273 | struct r8152 *tp = netdev_priv(netdev); | 2273 | struct r8152 *tp = netdev_priv(netdev); |
| 2274 | int res = 0; | 2274 | int res = 0; |
| 2275 | 2275 | ||
| 2276 | rtl8152_set_speed(tp, AUTONEG_ENABLE, | ||
| 2277 | tp->mii.supports_gmii ? SPEED_1000 : SPEED_100, | ||
| 2278 | DUPLEX_FULL); | ||
| 2279 | tp->speed = 0; | ||
| 2280 | netif_carrier_off(netdev); | ||
| 2281 | netif_start_queue(netdev); | ||
| 2282 | set_bit(WORK_ENABLE, &tp->flags); | ||
| 2276 | res = usb_submit_urb(tp->intr_urb, GFP_KERNEL); | 2283 | res = usb_submit_urb(tp->intr_urb, GFP_KERNEL); |
| 2277 | if (res) { | 2284 | if (res) { |
| 2278 | if (res == -ENODEV) | 2285 | if (res == -ENODEV) |
| 2279 | netif_device_detach(tp->netdev); | 2286 | netif_device_detach(tp->netdev); |
| 2280 | netif_warn(tp, ifup, netdev, "intr_urb submit failed: %d\n", | 2287 | netif_warn(tp, ifup, netdev, "intr_urb submit failed: %d\n", |
| 2281 | res); | 2288 | res); |
| 2282 | return res; | ||
| 2283 | } | 2289 | } |
| 2284 | 2290 | ||
| 2285 | rtl8152_set_speed(tp, AUTONEG_ENABLE, | ||
| 2286 | tp->mii.supports_gmii ? SPEED_1000 : SPEED_100, | ||
| 2287 | DUPLEX_FULL); | ||
| 2288 | tp->speed = 0; | ||
| 2289 | netif_carrier_off(netdev); | ||
| 2290 | netif_start_queue(netdev); | ||
| 2291 | set_bit(WORK_ENABLE, &tp->flags); | ||
| 2292 | 2291 | ||
| 2293 | return res; | 2292 | return res; |
| 2294 | } | 2293 | } |
| @@ -2298,8 +2297,8 @@ static int rtl8152_close(struct net_device *netdev) | |||
| 2298 | struct r8152 *tp = netdev_priv(netdev); | 2297 | struct r8152 *tp = netdev_priv(netdev); |
| 2299 | int res = 0; | 2298 | int res = 0; |
| 2300 | 2299 | ||
| 2301 | usb_kill_urb(tp->intr_urb); | ||
| 2302 | clear_bit(WORK_ENABLE, &tp->flags); | 2300 | clear_bit(WORK_ENABLE, &tp->flags); |
| 2301 | usb_kill_urb(tp->intr_urb); | ||
| 2303 | cancel_delayed_work_sync(&tp->schedule); | 2302 | cancel_delayed_work_sync(&tp->schedule); |
| 2304 | netif_stop_queue(netdev); | 2303 | netif_stop_queue(netdev); |
| 2305 | tasklet_disable(&tp->tl); | 2304 | tasklet_disable(&tp->tl); |
diff --git a/drivers/net/usb/rndis_host.c b/drivers/net/usb/rndis_host.c index a48bc0f20c1a..524a47a28120 100644 --- a/drivers/net/usb/rndis_host.c +++ b/drivers/net/usb/rndis_host.c | |||
| @@ -492,6 +492,10 @@ EXPORT_SYMBOL_GPL(rndis_unbind); | |||
| 492 | */ | 492 | */ |
| 493 | int rndis_rx_fixup(struct usbnet *dev, struct sk_buff *skb) | 493 | int rndis_rx_fixup(struct usbnet *dev, struct sk_buff *skb) |
| 494 | { | 494 | { |
| 495 | /* This check is no longer done by usbnet */ | ||
| 496 | if (skb->len < dev->net->hard_header_len) | ||
| 497 | return 0; | ||
| 498 | |||
| 495 | /* peripheral may have batched packets to us... */ | 499 | /* peripheral may have batched packets to us... */ |
| 496 | while (likely(skb->len)) { | 500 | while (likely(skb->len)) { |
| 497 | struct rndis_data_hdr *hdr = (void *)skb->data; | 501 | struct rndis_data_hdr *hdr = (void *)skb->data; |
diff --git a/drivers/net/usb/smsc75xx.c b/drivers/net/usb/smsc75xx.c index f17b9e02dd34..d9e7892262fa 100644 --- a/drivers/net/usb/smsc75xx.c +++ b/drivers/net/usb/smsc75xx.c | |||
| @@ -2106,6 +2106,10 @@ static void smsc75xx_rx_csum_offload(struct usbnet *dev, struct sk_buff *skb, | |||
| 2106 | 2106 | ||
| 2107 | static int smsc75xx_rx_fixup(struct usbnet *dev, struct sk_buff *skb) | 2107 | static int smsc75xx_rx_fixup(struct usbnet *dev, struct sk_buff *skb) |
| 2108 | { | 2108 | { |
| 2109 | /* This check is no longer done by usbnet */ | ||
| 2110 | if (skb->len < dev->net->hard_header_len) | ||
| 2111 | return 0; | ||
| 2112 | |||
| 2109 | while (skb->len > 0) { | 2113 | while (skb->len > 0) { |
| 2110 | u32 rx_cmd_a, rx_cmd_b, align_count, size; | 2114 | u32 rx_cmd_a, rx_cmd_b, align_count, size; |
| 2111 | struct sk_buff *ax_skb; | 2115 | struct sk_buff *ax_skb; |
diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c index 8dd54a0f7b29..424db65e4396 100644 --- a/drivers/net/usb/smsc95xx.c +++ b/drivers/net/usb/smsc95xx.c | |||
| @@ -1723,6 +1723,10 @@ static void smsc95xx_rx_csum_offload(struct sk_buff *skb) | |||
| 1723 | 1723 | ||
| 1724 | static int smsc95xx_rx_fixup(struct usbnet *dev, struct sk_buff *skb) | 1724 | static int smsc95xx_rx_fixup(struct usbnet *dev, struct sk_buff *skb) |
| 1725 | { | 1725 | { |
| 1726 | /* This check is no longer done by usbnet */ | ||
| 1727 | if (skb->len < dev->net->hard_header_len) | ||
| 1728 | return 0; | ||
| 1729 | |||
| 1726 | while (skb->len > 0) { | 1730 | while (skb->len > 0) { |
| 1727 | u32 header, align_count; | 1731 | u32 header, align_count; |
| 1728 | struct sk_buff *ax_skb; | 1732 | struct sk_buff *ax_skb; |
diff --git a/drivers/net/usb/sr9800.c b/drivers/net/usb/sr9800.c new file mode 100644 index 000000000000..b94a0fbb8b3b --- /dev/null +++ b/drivers/net/usb/sr9800.c | |||
| @@ -0,0 +1,874 @@ | |||
| 1 | /* CoreChip-sz SR9800 one chip USB 2.0 Ethernet Devices | ||
| 2 | * | ||
| 3 | * Author : Liu Junliang <liujunliang_ljl@163.com> | ||
| 4 | * | ||
| 5 | * Based on asix_common.c, asix_devices.c | ||
| 6 | * | ||
| 7 | * This file is licensed under the terms of the GNU General Public License | ||
| 8 | * version 2. This program is licensed "as is" without any warranty of any | ||
| 9 | * kind, whether express or implied.* | ||
| 10 | */ | ||
| 11 | |||
| 12 | #include <linux/module.h> | ||
| 13 | #include <linux/kmod.h> | ||
| 14 | #include <linux/init.h> | ||
| 15 | #include <linux/netdevice.h> | ||
| 16 | #include <linux/etherdevice.h> | ||
| 17 | #include <linux/ethtool.h> | ||
| 18 | #include <linux/workqueue.h> | ||
| 19 | #include <linux/mii.h> | ||
| 20 | #include <linux/usb.h> | ||
| 21 | #include <linux/crc32.h> | ||
| 22 | #include <linux/usb/usbnet.h> | ||
| 23 | #include <linux/slab.h> | ||
| 24 | #include <linux/if_vlan.h> | ||
| 25 | |||
| 26 | #include "sr9800.h" | ||
| 27 | |||
| 28 | static int sr_read_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index, | ||
| 29 | u16 size, void *data) | ||
| 30 | { | ||
| 31 | int err; | ||
| 32 | |||
| 33 | err = usbnet_read_cmd(dev, cmd, SR_REQ_RD_REG, value, index, | ||
| 34 | data, size); | ||
| 35 | if ((err != size) && (err >= 0)) | ||
| 36 | err = -EINVAL; | ||
| 37 | |||
| 38 | return err; | ||
| 39 | } | ||
| 40 | |||
| 41 | static int sr_write_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index, | ||
| 42 | u16 size, void *data) | ||
| 43 | { | ||
| 44 | int err; | ||
| 45 | |||
| 46 | err = usbnet_write_cmd(dev, cmd, SR_REQ_WR_REG, value, index, | ||
| 47 | data, size); | ||
| 48 | if ((err != size) && (err >= 0)) | ||
| 49 | err = -EINVAL; | ||
| 50 | |||
| 51 | return err; | ||
| 52 | } | ||
| 53 | |||
| 54 | static void | ||
| 55 | sr_write_cmd_async(struct usbnet *dev, u8 cmd, u16 value, u16 index, | ||
| 56 | u16 size, void *data) | ||
| 57 | { | ||
| 58 | usbnet_write_cmd_async(dev, cmd, SR_REQ_WR_REG, value, index, data, | ||
| 59 | size); | ||
| 60 | } | ||
| 61 | |||
| 62 | static int sr_rx_fixup(struct usbnet *dev, struct sk_buff *skb) | ||
| 63 | { | ||
| 64 | int offset = 0; | ||
| 65 | |||
| 66 | /* This check is no longer done by usbnet */ | ||
| 67 | if (skb->len < dev->net->hard_header_len) | ||
| 68 | return 0; | ||
| 69 | |||
| 70 | while (offset + sizeof(u32) < skb->len) { | ||
| 71 | struct sk_buff *sr_skb; | ||
| 72 | u16 size; | ||
| 73 | u32 header = get_unaligned_le32(skb->data + offset); | ||
| 74 | |||
| 75 | offset += sizeof(u32); | ||
| 76 | /* get the packet length */ | ||
| 77 | size = (u16) (header & 0x7ff); | ||
| 78 | if (size != ((~header >> 16) & 0x07ff)) { | ||
| 79 | netdev_err(dev->net, "%s : Bad Header Length\n", | ||
| 80 | __func__); | ||
| 81 | return 0; | ||
| 82 | } | ||
| 83 | |||
| 84 | if ((size > dev->net->mtu + ETH_HLEN + VLAN_HLEN) || | ||
| 85 | (size + offset > skb->len)) { | ||
| 86 | netdev_err(dev->net, "%s : Bad RX Length %d\n", | ||
| 87 | __func__, size); | ||
| 88 | return 0; | ||
| 89 | } | ||
| 90 | sr_skb = netdev_alloc_skb_ip_align(dev->net, size); | ||
| 91 | if (!sr_skb) | ||
| 92 | return 0; | ||
| 93 | |||
| 94 | skb_put(sr_skb, size); | ||
| 95 | memcpy(sr_skb->data, skb->data + offset, size); | ||
| 96 | usbnet_skb_return(dev, sr_skb); | ||
| 97 | |||
| 98 | offset += (size + 1) & 0xfffe; | ||
| 99 | } | ||
| 100 | |||
| 101 | if (skb->len != offset) { | ||
| 102 | netdev_err(dev->net, "%s : Bad SKB Length %d\n", __func__, | ||
| 103 | skb->len); | ||
| 104 | return 0; | ||
| 105 | } | ||
| 106 | |||
| 107 | return 1; | ||
| 108 | } | ||
| 109 | |||
| 110 | static struct sk_buff *sr_tx_fixup(struct usbnet *dev, struct sk_buff *skb, | ||
| 111 | gfp_t flags) | ||
| 112 | { | ||
| 113 | int headroom = skb_headroom(skb); | ||
| 114 | int tailroom = skb_tailroom(skb); | ||
| 115 | u32 padbytes = 0xffff0000; | ||
| 116 | u32 packet_len; | ||
| 117 | int padlen; | ||
| 118 | |||
| 119 | padlen = ((skb->len + 4) % (dev->maxpacket - 1)) ? 0 : 4; | ||
| 120 | |||
| 121 | if ((!skb_cloned(skb)) && ((headroom + tailroom) >= (4 + padlen))) { | ||
| 122 | if ((headroom < 4) || (tailroom < padlen)) { | ||
| 123 | skb->data = memmove(skb->head + 4, skb->data, | ||
| 124 | skb->len); | ||
| 125 | skb_set_tail_pointer(skb, skb->len); | ||
| 126 | } | ||
| 127 | } else { | ||
| 128 | struct sk_buff *skb2; | ||
| 129 | skb2 = skb_copy_expand(skb, 4, padlen, flags); | ||
| 130 | dev_kfree_skb_any(skb); | ||
| 131 | skb = skb2; | ||
| 132 | if (!skb) | ||
| 133 | return NULL; | ||
| 134 | } | ||
| 135 | |||
| 136 | skb_push(skb, 4); | ||
| 137 | packet_len = (((skb->len - 4) ^ 0x0000ffff) << 16) + (skb->len - 4); | ||
| 138 | cpu_to_le32s(&packet_len); | ||
| 139 | skb_copy_to_linear_data(skb, &packet_len, sizeof(packet_len)); | ||
| 140 | |||
| 141 | if (padlen) { | ||
| 142 | cpu_to_le32s(&padbytes); | ||
| 143 | memcpy(skb_tail_pointer(skb), &padbytes, sizeof(padbytes)); | ||
| 144 | skb_put(skb, sizeof(padbytes)); | ||
| 145 | } | ||
| 146 | |||
| 147 | return skb; | ||
| 148 | } | ||
| 149 | |||
| 150 | static void sr_status(struct usbnet *dev, struct urb *urb) | ||
| 151 | { | ||
| 152 | struct sr9800_int_data *event; | ||
| 153 | int link; | ||
| 154 | |||
| 155 | if (urb->actual_length < 8) | ||
| 156 | return; | ||
| 157 | |||
| 158 | event = urb->transfer_buffer; | ||
| 159 | link = event->link & 0x01; | ||
| 160 | if (netif_carrier_ok(dev->net) != link) { | ||
| 161 | usbnet_link_change(dev, link, 1); | ||
| 162 | netdev_dbg(dev->net, "Link Status is: %d\n", link); | ||
| 163 | } | ||
| 164 | |||
| 165 | return; | ||
| 166 | } | ||
| 167 | |||
| 168 | static inline int sr_set_sw_mii(struct usbnet *dev) | ||
| 169 | { | ||
| 170 | int ret; | ||
| 171 | |||
| 172 | ret = sr_write_cmd(dev, SR_CMD_SET_SW_MII, 0x0000, 0, 0, NULL); | ||
| 173 | if (ret < 0) | ||
| 174 | netdev_err(dev->net, "Failed to enable software MII access\n"); | ||
| 175 | return ret; | ||
| 176 | } | ||
| 177 | |||
| 178 | static inline int sr_set_hw_mii(struct usbnet *dev) | ||
| 179 | { | ||
| 180 | int ret; | ||
| 181 | |||
| 182 | ret = sr_write_cmd(dev, SR_CMD_SET_HW_MII, 0x0000, 0, 0, NULL); | ||
| 183 | if (ret < 0) | ||
| 184 | netdev_err(dev->net, "Failed to enable hardware MII access\n"); | ||
| 185 | return ret; | ||
| 186 | } | ||
| 187 | |||
| 188 | static inline int sr_get_phy_addr(struct usbnet *dev) | ||
| 189 | { | ||
| 190 | u8 buf[2]; | ||
| 191 | int ret; | ||
| 192 | |||
| 193 | ret = sr_read_cmd(dev, SR_CMD_READ_PHY_ID, 0, 0, 2, buf); | ||
| 194 | if (ret < 0) { | ||
| 195 | netdev_err(dev->net, "%s : Error reading PHYID register:%02x\n", | ||
| 196 | __func__, ret); | ||
| 197 | goto out; | ||
| 198 | } | ||
| 199 | netdev_dbg(dev->net, "%s : returning 0x%04x\n", __func__, | ||
| 200 | *((__le16 *)buf)); | ||
| 201 | |||
| 202 | ret = buf[1]; | ||
| 203 | |||
| 204 | out: | ||
| 205 | return ret; | ||
| 206 | } | ||
| 207 | |||
| 208 | static int sr_sw_reset(struct usbnet *dev, u8 flags) | ||
| 209 | { | ||
| 210 | int ret; | ||
| 211 | |||
| 212 | ret = sr_write_cmd(dev, SR_CMD_SW_RESET, flags, 0, 0, NULL); | ||
| 213 | if (ret < 0) | ||
| 214 | netdev_err(dev->net, "Failed to send software reset:%02x\n", | ||
| 215 | ret); | ||
| 216 | |||
| 217 | return ret; | ||
| 218 | } | ||
| 219 | |||
| 220 | static u16 sr_read_rx_ctl(struct usbnet *dev) | ||
| 221 | { | ||
| 222 | __le16 v; | ||
| 223 | int ret; | ||
| 224 | |||
| 225 | ret = sr_read_cmd(dev, SR_CMD_READ_RX_CTL, 0, 0, 2, &v); | ||
| 226 | if (ret < 0) { | ||
| 227 | netdev_err(dev->net, "Error reading RX_CTL register:%02x\n", | ||
| 228 | ret); | ||
| 229 | goto out; | ||
| 230 | } | ||
| 231 | |||
| 232 | ret = le16_to_cpu(v); | ||
| 233 | out: | ||
| 234 | return ret; | ||
| 235 | } | ||
| 236 | |||
| 237 | static int sr_write_rx_ctl(struct usbnet *dev, u16 mode) | ||
| 238 | { | ||
| 239 | int ret; | ||
| 240 | |||
| 241 | netdev_dbg(dev->net, "%s : mode = 0x%04x\n", __func__, mode); | ||
| 242 | ret = sr_write_cmd(dev, SR_CMD_WRITE_RX_CTL, mode, 0, 0, NULL); | ||
| 243 | if (ret < 0) | ||
| 244 | netdev_err(dev->net, | ||
| 245 | "Failed to write RX_CTL mode to 0x%04x:%02x\n", | ||
| 246 | mode, ret); | ||
| 247 | |||
| 248 | return ret; | ||
| 249 | } | ||
| 250 | |||
| 251 | static u16 sr_read_medium_status(struct usbnet *dev) | ||
| 252 | { | ||
| 253 | __le16 v; | ||
| 254 | int ret; | ||
| 255 | |||
| 256 | ret = sr_read_cmd(dev, SR_CMD_READ_MEDIUM_STATUS, 0, 0, 2, &v); | ||
| 257 | if (ret < 0) { | ||
| 258 | netdev_err(dev->net, | ||
| 259 | "Error reading Medium Status register:%02x\n", ret); | ||
| 260 | return ret; /* TODO: callers not checking for error ret */ | ||
| 261 | } | ||
| 262 | |||
| 263 | return le16_to_cpu(v); | ||
| 264 | } | ||
| 265 | |||
| 266 | static int sr_write_medium_mode(struct usbnet *dev, u16 mode) | ||
| 267 | { | ||
| 268 | int ret; | ||
| 269 | |||
| 270 | netdev_dbg(dev->net, "%s : mode = 0x%04x\n", __func__, mode); | ||
| 271 | ret = sr_write_cmd(dev, SR_CMD_WRITE_MEDIUM_MODE, mode, 0, 0, NULL); | ||
| 272 | if (ret < 0) | ||
| 273 | netdev_err(dev->net, | ||
| 274 | "Failed to write Medium Mode mode to 0x%04x:%02x\n", | ||
| 275 | mode, ret); | ||
| 276 | return ret; | ||
| 277 | } | ||
| 278 | |||
| 279 | static int sr_write_gpio(struct usbnet *dev, u16 value, int sleep) | ||
| 280 | { | ||
| 281 | int ret; | ||
| 282 | |||
| 283 | netdev_dbg(dev->net, "%s : value = 0x%04x\n", __func__, value); | ||
| 284 | ret = sr_write_cmd(dev, SR_CMD_WRITE_GPIOS, value, 0, 0, NULL); | ||
| 285 | if (ret < 0) | ||
| 286 | netdev_err(dev->net, "Failed to write GPIO value 0x%04x:%02x\n", | ||
| 287 | value, ret); | ||
| 288 | if (sleep) | ||
| 289 | msleep(sleep); | ||
| 290 | |||
| 291 | return ret; | ||
| 292 | } | ||
| 293 | |||
| 294 | /* SR9800 have a 16-bit RX_CTL value */ | ||
| 295 | static void sr_set_multicast(struct net_device *net) | ||
| 296 | { | ||
| 297 | struct usbnet *dev = netdev_priv(net); | ||
| 298 | struct sr_data *data = (struct sr_data *)&dev->data; | ||
| 299 | u16 rx_ctl = SR_DEFAULT_RX_CTL; | ||
| 300 | |||
| 301 | if (net->flags & IFF_PROMISC) { | ||
| 302 | rx_ctl |= SR_RX_CTL_PRO; | ||
| 303 | } else if (net->flags & IFF_ALLMULTI || | ||
| 304 | netdev_mc_count(net) > SR_MAX_MCAST) { | ||
| 305 | rx_ctl |= SR_RX_CTL_AMALL; | ||
| 306 | } else if (netdev_mc_empty(net)) { | ||
| 307 | /* just broadcast and directed */ | ||
| 308 | } else { | ||
| 309 | /* We use the 20 byte dev->data | ||
| 310 | * for our 8 byte filter buffer | ||
| 311 | * to avoid allocating memory that | ||
| 312 | * is tricky to free later | ||
| 313 | */ | ||
| 314 | struct netdev_hw_addr *ha; | ||
| 315 | u32 crc_bits; | ||
| 316 | |||
| 317 | memset(data->multi_filter, 0, SR_MCAST_FILTER_SIZE); | ||
| 318 | |||
| 319 | /* Build the multicast hash filter. */ | ||
| 320 | netdev_for_each_mc_addr(ha, net) { | ||
| 321 | crc_bits = ether_crc(ETH_ALEN, ha->addr) >> 26; | ||
| 322 | data->multi_filter[crc_bits >> 3] |= | ||
| 323 | 1 << (crc_bits & 7); | ||
| 324 | } | ||
| 325 | |||
| 326 | sr_write_cmd_async(dev, SR_CMD_WRITE_MULTI_FILTER, 0, 0, | ||
| 327 | SR_MCAST_FILTER_SIZE, data->multi_filter); | ||
| 328 | |||
| 329 | rx_ctl |= SR_RX_CTL_AM; | ||
| 330 | } | ||
| 331 | |||
| 332 | sr_write_cmd_async(dev, SR_CMD_WRITE_RX_CTL, rx_ctl, 0, 0, NULL); | ||
| 333 | } | ||
| 334 | |||
| 335 | static int sr_mdio_read(struct net_device *net, int phy_id, int loc) | ||
| 336 | { | ||
| 337 | struct usbnet *dev = netdev_priv(net); | ||
| 338 | __le16 res; | ||
| 339 | |||
| 340 | mutex_lock(&dev->phy_mutex); | ||
| 341 | sr_set_sw_mii(dev); | ||
| 342 | sr_read_cmd(dev, SR_CMD_READ_MII_REG, phy_id, (__u16)loc, 2, &res); | ||
| 343 | sr_set_hw_mii(dev); | ||
| 344 | mutex_unlock(&dev->phy_mutex); | ||
| 345 | |||
| 346 | netdev_dbg(dev->net, | ||
| 347 | "%s : phy_id=0x%02x, loc=0x%02x, returns=0x%04x\n", __func__, | ||
| 348 | phy_id, loc, le16_to_cpu(res)); | ||
| 349 | |||
| 350 | return le16_to_cpu(res); | ||
| 351 | } | ||
| 352 | |||
| 353 | static void | ||
| 354 | sr_mdio_write(struct net_device *net, int phy_id, int loc, int val) | ||
| 355 | { | ||
| 356 | struct usbnet *dev = netdev_priv(net); | ||
| 357 | __le16 res = cpu_to_le16(val); | ||
| 358 | |||
| 359 | netdev_dbg(dev->net, | ||
| 360 | "%s : phy_id=0x%02x, loc=0x%02x, val=0x%04x\n", __func__, | ||
| 361 | phy_id, loc, val); | ||
| 362 | mutex_lock(&dev->phy_mutex); | ||
| 363 | sr_set_sw_mii(dev); | ||
| 364 | sr_write_cmd(dev, SR_CMD_WRITE_MII_REG, phy_id, (__u16)loc, 2, &res); | ||
| 365 | sr_set_hw_mii(dev); | ||
| 366 | mutex_unlock(&dev->phy_mutex); | ||
| 367 | } | ||
| 368 | |||
| 369 | /* Get the PHY Identifier from the PHYSID1 & PHYSID2 MII registers */ | ||
| 370 | static u32 sr_get_phyid(struct usbnet *dev) | ||
| 371 | { | ||
| 372 | int phy_reg; | ||
| 373 | u32 phy_id; | ||
| 374 | int i; | ||
| 375 | |||
| 376 | /* Poll for the rare case the FW or phy isn't ready yet. */ | ||
| 377 | for (i = 0; i < 100; i++) { | ||
| 378 | phy_reg = sr_mdio_read(dev->net, dev->mii.phy_id, MII_PHYSID1); | ||
| 379 | if (phy_reg != 0 && phy_reg != 0xFFFF) | ||
| 380 | break; | ||
| 381 | mdelay(1); | ||
| 382 | } | ||
| 383 | |||
| 384 | if (phy_reg <= 0 || phy_reg == 0xFFFF) | ||
| 385 | return 0; | ||
| 386 | |||
| 387 | phy_id = (phy_reg & 0xffff) << 16; | ||
| 388 | |||
| 389 | phy_reg = sr_mdio_read(dev->net, dev->mii.phy_id, MII_PHYSID2); | ||
| 390 | if (phy_reg < 0) | ||
| 391 | return 0; | ||
| 392 | |||
| 393 | phy_id |= (phy_reg & 0xffff); | ||
| 394 | |||
| 395 | return phy_id; | ||
| 396 | } | ||
| 397 | |||
| 398 | static void | ||
| 399 | sr_get_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo) | ||
| 400 | { | ||
| 401 | struct usbnet *dev = netdev_priv(net); | ||
| 402 | u8 opt; | ||
| 403 | |||
| 404 | if (sr_read_cmd(dev, SR_CMD_READ_MONITOR_MODE, 0, 0, 1, &opt) < 0) { | ||
| 405 | wolinfo->supported = 0; | ||
| 406 | wolinfo->wolopts = 0; | ||
| 407 | return; | ||
| 408 | } | ||
| 409 | wolinfo->supported = WAKE_PHY | WAKE_MAGIC; | ||
| 410 | wolinfo->wolopts = 0; | ||
| 411 | if (opt & SR_MONITOR_LINK) | ||
| 412 | wolinfo->wolopts |= WAKE_PHY; | ||
| 413 | if (opt & SR_MONITOR_MAGIC) | ||
| 414 | wolinfo->wolopts |= WAKE_MAGIC; | ||
| 415 | } | ||
| 416 | |||
| 417 | static int | ||
| 418 | sr_set_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo) | ||
| 419 | { | ||
| 420 | struct usbnet *dev = netdev_priv(net); | ||
| 421 | u8 opt = 0; | ||
| 422 | |||
| 423 | if (wolinfo->wolopts & WAKE_PHY) | ||
| 424 | opt |= SR_MONITOR_LINK; | ||
| 425 | if (wolinfo->wolopts & WAKE_MAGIC) | ||
| 426 | opt |= SR_MONITOR_MAGIC; | ||
| 427 | |||
| 428 | if (sr_write_cmd(dev, SR_CMD_WRITE_MONITOR_MODE, | ||
| 429 | opt, 0, 0, NULL) < 0) | ||
| 430 | return -EINVAL; | ||
| 431 | |||
| 432 | return 0; | ||
| 433 | } | ||
| 434 | |||
| 435 | static int sr_get_eeprom_len(struct net_device *net) | ||
| 436 | { | ||
| 437 | struct usbnet *dev = netdev_priv(net); | ||
| 438 | struct sr_data *data = (struct sr_data *)&dev->data; | ||
| 439 | |||
| 440 | return data->eeprom_len; | ||
| 441 | } | ||
| 442 | |||
| 443 | static int sr_get_eeprom(struct net_device *net, | ||
| 444 | struct ethtool_eeprom *eeprom, u8 *data) | ||
| 445 | { | ||
| 446 | struct usbnet *dev = netdev_priv(net); | ||
| 447 | __le16 *ebuf = (__le16 *)data; | ||
| 448 | int ret; | ||
| 449 | int i; | ||
| 450 | |||
| 451 | /* Crude hack to ensure that we don't overwrite memory | ||
| 452 | * if an odd length is supplied | ||
| 453 | */ | ||
| 454 | if (eeprom->len % 2) | ||
| 455 | return -EINVAL; | ||
| 456 | |||
| 457 | eeprom->magic = SR_EEPROM_MAGIC; | ||
| 458 | |||
| 459 | /* sr9800 returns 2 bytes from eeprom on read */ | ||
| 460 | for (i = 0; i < eeprom->len / 2; i++) { | ||
| 461 | ret = sr_read_cmd(dev, SR_CMD_READ_EEPROM, eeprom->offset + i, | ||
| 462 | 0, 2, &ebuf[i]); | ||
| 463 | if (ret < 0) | ||
| 464 | return -EINVAL; | ||
| 465 | } | ||
| 466 | return 0; | ||
| 467 | } | ||
| 468 | |||
| 469 | static void sr_get_drvinfo(struct net_device *net, | ||
| 470 | struct ethtool_drvinfo *info) | ||
| 471 | { | ||
| 472 | struct usbnet *dev = netdev_priv(net); | ||
| 473 | struct sr_data *data = (struct sr_data *)&dev->data; | ||
| 474 | |||
| 475 | /* Inherit standard device info */ | ||
| 476 | usbnet_get_drvinfo(net, info); | ||
| 477 | strncpy(info->driver, DRIVER_NAME, sizeof(info->driver)); | ||
| 478 | strncpy(info->version, DRIVER_VERSION, sizeof(info->version)); | ||
| 479 | info->eedump_len = data->eeprom_len; | ||
| 480 | } | ||
| 481 | |||
| 482 | static u32 sr_get_link(struct net_device *net) | ||
| 483 | { | ||
| 484 | struct usbnet *dev = netdev_priv(net); | ||
| 485 | |||
| 486 | return mii_link_ok(&dev->mii); | ||
| 487 | } | ||
| 488 | |||
| 489 | static int sr_ioctl(struct net_device *net, struct ifreq *rq, int cmd) | ||
| 490 | { | ||
| 491 | struct usbnet *dev = netdev_priv(net); | ||
| 492 | |||
| 493 | return generic_mii_ioctl(&dev->mii, if_mii(rq), cmd, NULL); | ||
| 494 | } | ||
| 495 | |||
| 496 | static int sr_set_mac_address(struct net_device *net, void *p) | ||
| 497 | { | ||
| 498 | struct usbnet *dev = netdev_priv(net); | ||
| 499 | struct sr_data *data = (struct sr_data *)&dev->data; | ||
| 500 | struct sockaddr *addr = p; | ||
| 501 | |||
| 502 | if (netif_running(net)) | ||
| 503 | return -EBUSY; | ||
| 504 | if (!is_valid_ether_addr(addr->sa_data)) | ||
| 505 | return -EADDRNOTAVAIL; | ||
| 506 | |||
| 507 | memcpy(net->dev_addr, addr->sa_data, ETH_ALEN); | ||
| 508 | |||
| 509 | /* We use the 20 byte dev->data | ||
| 510 | * for our 6 byte mac buffer | ||
| 511 | * to avoid allocating memory that | ||
| 512 | * is tricky to free later | ||
| 513 | */ | ||
| 514 | memcpy(data->mac_addr, addr->sa_data, ETH_ALEN); | ||
| 515 | sr_write_cmd_async(dev, SR_CMD_WRITE_NODE_ID, 0, 0, ETH_ALEN, | ||
| 516 | data->mac_addr); | ||
| 517 | |||
| 518 | return 0; | ||
| 519 | } | ||
| 520 | |||
| 521 | static const struct ethtool_ops sr9800_ethtool_ops = { | ||
| 522 | .get_drvinfo = sr_get_drvinfo, | ||
| 523 | .get_link = sr_get_link, | ||
| 524 | .get_msglevel = usbnet_get_msglevel, | ||
| 525 | .set_msglevel = usbnet_set_msglevel, | ||
| 526 | .get_wol = sr_get_wol, | ||
| 527 | .set_wol = sr_set_wol, | ||
| 528 | .get_eeprom_len = sr_get_eeprom_len, | ||
| 529 | .get_eeprom = sr_get_eeprom, | ||
| 530 | .get_settings = usbnet_get_settings, | ||
| 531 | .set_settings = usbnet_set_settings, | ||
| 532 | .nway_reset = usbnet_nway_reset, | ||
| 533 | }; | ||
| 534 | |||
| 535 | static int sr9800_link_reset(struct usbnet *dev) | ||
| 536 | { | ||
| 537 | struct ethtool_cmd ecmd = { .cmd = ETHTOOL_GSET }; | ||
| 538 | u16 mode; | ||
| 539 | |||
| 540 | mii_check_media(&dev->mii, 1, 1); | ||
| 541 | mii_ethtool_gset(&dev->mii, &ecmd); | ||
| 542 | mode = SR9800_MEDIUM_DEFAULT; | ||
| 543 | |||
| 544 | if (ethtool_cmd_speed(&ecmd) != SPEED_100) | ||
| 545 | mode &= ~SR_MEDIUM_PS; | ||
| 546 | |||
| 547 | if (ecmd.duplex != DUPLEX_FULL) | ||
| 548 | mode &= ~SR_MEDIUM_FD; | ||
| 549 | |||
| 550 | netdev_dbg(dev->net, "%s : speed: %u duplex: %d mode: 0x%04x\n", | ||
| 551 | __func__, ethtool_cmd_speed(&ecmd), ecmd.duplex, mode); | ||
| 552 | |||
| 553 | sr_write_medium_mode(dev, mode); | ||
| 554 | |||
| 555 | return 0; | ||
| 556 | } | ||
| 557 | |||
| 558 | |||
| 559 | static int sr9800_set_default_mode(struct usbnet *dev) | ||
| 560 | { | ||
| 561 | u16 rx_ctl; | ||
| 562 | int ret; | ||
| 563 | |||
| 564 | sr_mdio_write(dev->net, dev->mii.phy_id, MII_BMCR, BMCR_RESET); | ||
| 565 | sr_mdio_write(dev->net, dev->mii.phy_id, MII_ADVERTISE, | ||
| 566 | ADVERTISE_ALL | ADVERTISE_CSMA); | ||
| 567 | mii_nway_restart(&dev->mii); | ||
| 568 | |||
| 569 | ret = sr_write_medium_mode(dev, SR9800_MEDIUM_DEFAULT); | ||
| 570 | if (ret < 0) | ||
| 571 | goto out; | ||
| 572 | |||
| 573 | ret = sr_write_cmd(dev, SR_CMD_WRITE_IPG012, | ||
| 574 | SR9800_IPG0_DEFAULT | SR9800_IPG1_DEFAULT, | ||
| 575 | SR9800_IPG2_DEFAULT, 0, NULL); | ||
| 576 | if (ret < 0) { | ||
| 577 | netdev_dbg(dev->net, "Write IPG,IPG1,IPG2 failed: %d\n", ret); | ||
| 578 | goto out; | ||
| 579 | } | ||
| 580 | |||
| 581 | /* Set RX_CTL to default values with 2k buffer, and enable cactus */ | ||
| 582 | ret = sr_write_rx_ctl(dev, SR_DEFAULT_RX_CTL); | ||
| 583 | if (ret < 0) | ||
| 584 | goto out; | ||
| 585 | |||
| 586 | rx_ctl = sr_read_rx_ctl(dev); | ||
| 587 | netdev_dbg(dev->net, "RX_CTL is 0x%04x after all initializations\n", | ||
| 588 | rx_ctl); | ||
| 589 | |||
| 590 | rx_ctl = sr_read_medium_status(dev); | ||
| 591 | netdev_dbg(dev->net, "Medium Status:0x%04x after all initializations\n", | ||
| 592 | rx_ctl); | ||
| 593 | |||
| 594 | return 0; | ||
| 595 | out: | ||
| 596 | return ret; | ||
| 597 | } | ||
| 598 | |||
| 599 | static int sr9800_reset(struct usbnet *dev) | ||
| 600 | { | ||
| 601 | struct sr_data *data = (struct sr_data *)&dev->data; | ||
| 602 | int ret, embd_phy; | ||
| 603 | u16 rx_ctl; | ||
| 604 | |||
| 605 | ret = sr_write_gpio(dev, | ||
| 606 | SR_GPIO_RSE | SR_GPIO_GPO_2 | SR_GPIO_GPO2EN, 5); | ||
| 607 | if (ret < 0) | ||
| 608 | goto out; | ||
| 609 | |||
| 610 | embd_phy = ((sr_get_phy_addr(dev) & 0x1f) == 0x10 ? 1 : 0); | ||
| 611 | |||
| 612 | ret = sr_write_cmd(dev, SR_CMD_SW_PHY_SELECT, embd_phy, 0, 0, NULL); | ||
| 613 | if (ret < 0) { | ||
| 614 | netdev_dbg(dev->net, "Select PHY #1 failed: %d\n", ret); | ||
| 615 | goto out; | ||
| 616 | } | ||
| 617 | |||
| 618 | ret = sr_sw_reset(dev, SR_SWRESET_IPPD | SR_SWRESET_PRL); | ||
| 619 | if (ret < 0) | ||
| 620 | goto out; | ||
| 621 | |||
| 622 | msleep(150); | ||
| 623 | |||
| 624 | ret = sr_sw_reset(dev, SR_SWRESET_CLEAR); | ||
| 625 | if (ret < 0) | ||
| 626 | goto out; | ||
| 627 | |||
| 628 | msleep(150); | ||
| 629 | |||
| 630 | if (embd_phy) { | ||
| 631 | ret = sr_sw_reset(dev, SR_SWRESET_IPRL); | ||
| 632 | if (ret < 0) | ||
| 633 | goto out; | ||
| 634 | } else { | ||
| 635 | ret = sr_sw_reset(dev, SR_SWRESET_PRTE); | ||
| 636 | if (ret < 0) | ||
| 637 | goto out; | ||
| 638 | } | ||
| 639 | |||
| 640 | msleep(150); | ||
| 641 | rx_ctl = sr_read_rx_ctl(dev); | ||
| 642 | netdev_dbg(dev->net, "RX_CTL is 0x%04x after software reset\n", rx_ctl); | ||
| 643 | ret = sr_write_rx_ctl(dev, 0x0000); | ||
| 644 | if (ret < 0) | ||
| 645 | goto out; | ||
| 646 | |||
| 647 | rx_ctl = sr_read_rx_ctl(dev); | ||
| 648 | netdev_dbg(dev->net, "RX_CTL is 0x%04x setting to 0x0000\n", rx_ctl); | ||
| 649 | |||
| 650 | ret = sr_sw_reset(dev, SR_SWRESET_PRL); | ||
| 651 | if (ret < 0) | ||
| 652 | goto out; | ||
| 653 | |||
| 654 | msleep(150); | ||
| 655 | |||
| 656 | ret = sr_sw_reset(dev, SR_SWRESET_IPRL | SR_SWRESET_PRL); | ||
| 657 | if (ret < 0) | ||
| 658 | goto out; | ||
| 659 | |||
| 660 | msleep(150); | ||
| 661 | |||
| 662 | ret = sr9800_set_default_mode(dev); | ||
| 663 | if (ret < 0) | ||
| 664 | goto out; | ||
| 665 | |||
| 666 | /* Rewrite MAC address */ | ||
| 667 | memcpy(data->mac_addr, dev->net->dev_addr, ETH_ALEN); | ||
| 668 | ret = sr_write_cmd(dev, SR_CMD_WRITE_NODE_ID, 0, 0, ETH_ALEN, | ||
| 669 | data->mac_addr); | ||
| 670 | if (ret < 0) | ||
| 671 | goto out; | ||
| 672 | |||
| 673 | return 0; | ||
| 674 | |||
| 675 | out: | ||
| 676 | return ret; | ||
| 677 | } | ||
| 678 | |||
| 679 | static const struct net_device_ops sr9800_netdev_ops = { | ||
| 680 | .ndo_open = usbnet_open, | ||
| 681 | .ndo_stop = usbnet_stop, | ||
| 682 | .ndo_start_xmit = usbnet_start_xmit, | ||
| 683 | .ndo_tx_timeout = usbnet_tx_timeout, | ||
| 684 | .ndo_change_mtu = usbnet_change_mtu, | ||
| 685 | .ndo_set_mac_address = sr_set_mac_address, | ||
| 686 | .ndo_validate_addr = eth_validate_addr, | ||
| 687 | .ndo_do_ioctl = sr_ioctl, | ||
| 688 | .ndo_set_rx_mode = sr_set_multicast, | ||
| 689 | }; | ||
| 690 | |||
| 691 | static int sr9800_phy_powerup(struct usbnet *dev) | ||
| 692 | { | ||
| 693 | int ret; | ||
| 694 | |||
| 695 | /* set the embedded Ethernet PHY in power-down state */ | ||
| 696 | ret = sr_sw_reset(dev, SR_SWRESET_IPPD | SR_SWRESET_IPRL); | ||
| 697 | if (ret < 0) { | ||
| 698 | netdev_err(dev->net, "Failed to power down PHY : %d\n", ret); | ||
| 699 | return ret; | ||
| 700 | } | ||
| 701 | msleep(20); | ||
| 702 | |||
| 703 | /* set the embedded Ethernet PHY in power-up state */ | ||
| 704 | ret = sr_sw_reset(dev, SR_SWRESET_IPRL); | ||
| 705 | if (ret < 0) { | ||
| 706 | netdev_err(dev->net, "Failed to reset PHY: %d\n", ret); | ||
| 707 | return ret; | ||
| 708 | } | ||
| 709 | msleep(600); | ||
| 710 | |||
| 711 | /* set the embedded Ethernet PHY in reset state */ | ||
| 712 | ret = sr_sw_reset(dev, SR_SWRESET_CLEAR); | ||
| 713 | if (ret < 0) { | ||
| 714 | netdev_err(dev->net, "Failed to power up PHY: %d\n", ret); | ||
| 715 | return ret; | ||
| 716 | } | ||
| 717 | msleep(20); | ||
| 718 | |||
| 719 | /* set the embedded Ethernet PHY in power-up state */ | ||
| 720 | ret = sr_sw_reset(dev, SR_SWRESET_IPRL); | ||
| 721 | if (ret < 0) { | ||
| 722 | netdev_err(dev->net, "Failed to reset PHY: %d\n", ret); | ||
| 723 | return ret; | ||
| 724 | } | ||
| 725 | |||
| 726 | return 0; | ||
| 727 | } | ||
| 728 | |||
| 729 | static int sr9800_bind(struct usbnet *dev, struct usb_interface *intf) | ||
| 730 | { | ||
| 731 | struct sr_data *data = (struct sr_data *)&dev->data; | ||
| 732 | u16 led01_mux, led23_mux; | ||
| 733 | int ret, embd_phy; | ||
| 734 | u32 phyid; | ||
| 735 | u16 rx_ctl; | ||
| 736 | |||
| 737 | data->eeprom_len = SR9800_EEPROM_LEN; | ||
| 738 | |||
| 739 | usbnet_get_endpoints(dev, intf); | ||
| 740 | |||
| 741 | /* LED Setting Rule : | ||
| 742 | * AABB:CCDD | ||
| 743 | * AA : MFA0(LED0) | ||
| 744 | * BB : MFA1(LED1) | ||
| 745 | * CC : MFA2(LED2), Reserved for SR9800 | ||
| 746 | * DD : MFA3(LED3), Reserved for SR9800 | ||
| 747 | */ | ||
| 748 | led01_mux = (SR_LED_MUX_LINK_ACTIVE << 8) | SR_LED_MUX_LINK; | ||
| 749 | led23_mux = (SR_LED_MUX_LINK_ACTIVE << 8) | SR_LED_MUX_TX_ACTIVE; | ||
| 750 | ret = sr_write_cmd(dev, SR_CMD_LED_MUX, led01_mux, led23_mux, 0, NULL); | ||
| 751 | if (ret < 0) { | ||
| 752 | netdev_err(dev->net, "set LINK LED failed : %d\n", ret); | ||
| 753 | goto out; | ||
| 754 | } | ||
| 755 | |||
| 756 | /* Get the MAC address */ | ||
| 757 | ret = sr_read_cmd(dev, SR_CMD_READ_NODE_ID, 0, 0, ETH_ALEN, | ||
| 758 | dev->net->dev_addr); | ||
| 759 | if (ret < 0) { | ||
| 760 | netdev_dbg(dev->net, "Failed to read MAC address: %d\n", ret); | ||
| 761 | return ret; | ||
| 762 | } | ||
| 763 | netdev_dbg(dev->net, "mac addr : %pM\n", dev->net->dev_addr); | ||
| 764 | |||
| 765 | /* Initialize MII structure */ | ||
| 766 | dev->mii.dev = dev->net; | ||
| 767 | dev->mii.mdio_read = sr_mdio_read; | ||
| 768 | dev->mii.mdio_write = sr_mdio_write; | ||
| 769 | dev->mii.phy_id_mask = 0x1f; | ||
| 770 | dev->mii.reg_num_mask = 0x1f; | ||
| 771 | dev->mii.phy_id = sr_get_phy_addr(dev); | ||
| 772 | |||
| 773 | dev->net->netdev_ops = &sr9800_netdev_ops; | ||
| 774 | dev->net->ethtool_ops = &sr9800_ethtool_ops; | ||
| 775 | |||
| 776 | embd_phy = ((dev->mii.phy_id & 0x1f) == 0x10 ? 1 : 0); | ||
| 777 | /* Reset the PHY to normal operation mode */ | ||
| 778 | ret = sr_write_cmd(dev, SR_CMD_SW_PHY_SELECT, embd_phy, 0, 0, NULL); | ||
| 779 | if (ret < 0) { | ||
| 780 | netdev_dbg(dev->net, "Select PHY #1 failed: %d\n", ret); | ||
| 781 | return ret; | ||
| 782 | } | ||
| 783 | |||
| 784 | /* Init PHY routine */ | ||
| 785 | ret = sr9800_phy_powerup(dev); | ||
| 786 | if (ret < 0) | ||
| 787 | goto out; | ||
| 788 | |||
| 789 | rx_ctl = sr_read_rx_ctl(dev); | ||
| 790 | netdev_dbg(dev->net, "RX_CTL is 0x%04x after software reset\n", rx_ctl); | ||
| 791 | ret = sr_write_rx_ctl(dev, 0x0000); | ||
| 792 | if (ret < 0) | ||
| 793 | goto out; | ||
| 794 | |||
| 795 | rx_ctl = sr_read_rx_ctl(dev); | ||
| 796 | netdev_dbg(dev->net, "RX_CTL is 0x%04x setting to 0x0000\n", rx_ctl); | ||
| 797 | |||
| 798 | /* Read PHYID register *AFTER* the PHY was reset properly */ | ||
| 799 | phyid = sr_get_phyid(dev); | ||
| 800 | netdev_dbg(dev->net, "PHYID=0x%08x\n", phyid); | ||
| 801 | |||
| 802 | /* medium mode setting */ | ||
| 803 | ret = sr9800_set_default_mode(dev); | ||
| 804 | if (ret < 0) | ||
| 805 | goto out; | ||
| 806 | |||
| 807 | if (dev->udev->speed == USB_SPEED_HIGH) { | ||
| 808 | ret = sr_write_cmd(dev, SR_CMD_BULKIN_SIZE, | ||
| 809 | SR9800_BULKIN_SIZE[SR9800_MAX_BULKIN_4K].byte_cnt, | ||
| 810 | SR9800_BULKIN_SIZE[SR9800_MAX_BULKIN_4K].threshold, | ||
| 811 | 0, NULL); | ||
| 812 | if (ret < 0) { | ||
| 813 | netdev_err(dev->net, "Reset RX_CTL failed: %d\n", ret); | ||
| 814 | goto out; | ||
| 815 | } | ||
| 816 | dev->rx_urb_size = | ||
| 817 | SR9800_BULKIN_SIZE[SR9800_MAX_BULKIN_4K].size; | ||
| 818 | } else { | ||
| 819 | ret = sr_write_cmd(dev, SR_CMD_BULKIN_SIZE, | ||
| 820 | SR9800_BULKIN_SIZE[SR9800_MAX_BULKIN_2K].byte_cnt, | ||
| 821 | SR9800_BULKIN_SIZE[SR9800_MAX_BULKIN_2K].threshold, | ||
| 822 | 0, NULL); | ||
| 823 | if (ret < 0) { | ||
| 824 | netdev_err(dev->net, "Reset RX_CTL failed: %d\n", ret); | ||
| 825 | goto out; | ||
| 826 | } | ||
| 827 | dev->rx_urb_size = | ||
| 828 | SR9800_BULKIN_SIZE[SR9800_MAX_BULKIN_2K].size; | ||
| 829 | } | ||
| 830 | netdev_dbg(dev->net, "%s : setting rx_urb_size with : %zu\n", __func__, | ||
| 831 | dev->rx_urb_size); | ||
| 832 | return 0; | ||
| 833 | |||
| 834 | out: | ||
| 835 | return ret; | ||
| 836 | } | ||
| 837 | |||
| 838 | static const struct driver_info sr9800_driver_info = { | ||
| 839 | .description = "CoreChip SR9800 USB 2.0 Ethernet", | ||
| 840 | .bind = sr9800_bind, | ||
| 841 | .status = sr_status, | ||
| 842 | .link_reset = sr9800_link_reset, | ||
| 843 | .reset = sr9800_reset, | ||
| 844 | .flags = DRIVER_FLAG, | ||
| 845 | .rx_fixup = sr_rx_fixup, | ||
| 846 | .tx_fixup = sr_tx_fixup, | ||
| 847 | }; | ||
| 848 | |||
| 849 | static const struct usb_device_id products[] = { | ||
| 850 | { | ||
| 851 | USB_DEVICE(0x0fe6, 0x9800), /* SR9800 Device */ | ||
| 852 | .driver_info = (unsigned long) &sr9800_driver_info, | ||
| 853 | }, | ||
| 854 | {}, /* END */ | ||
| 855 | }; | ||
| 856 | |||
| 857 | MODULE_DEVICE_TABLE(usb, products); | ||
| 858 | |||
| 859 | static struct usb_driver sr_driver = { | ||
| 860 | .name = DRIVER_NAME, | ||
| 861 | .id_table = products, | ||
| 862 | .probe = usbnet_probe, | ||
| 863 | .suspend = usbnet_suspend, | ||
| 864 | .resume = usbnet_resume, | ||
| 865 | .disconnect = usbnet_disconnect, | ||
| 866 | .supports_autosuspend = 1, | ||
| 867 | }; | ||
| 868 | |||
| 869 | module_usb_driver(sr_driver); | ||
| 870 | |||
| 871 | MODULE_AUTHOR("Liu Junliang <liujunliang_ljl@163.com"); | ||
| 872 | MODULE_VERSION(DRIVER_VERSION); | ||
| 873 | MODULE_DESCRIPTION("SR9800 USB 2.0 USB2NET Dev : http://www.corechip-sz.com"); | ||
| 874 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/net/usb/sr9800.h b/drivers/net/usb/sr9800.h new file mode 100644 index 000000000000..18f670251275 --- /dev/null +++ b/drivers/net/usb/sr9800.h | |||
| @@ -0,0 +1,202 @@ | |||
| 1 | /* CoreChip-sz SR9800 one chip USB 2.0 Ethernet Devices | ||
| 2 | * | ||
| 3 | * Author : Liu Junliang <liujunliang_ljl@163.com> | ||
| 4 | * | ||
| 5 | * This file is licensed under the terms of the GNU General Public License | ||
| 6 | * version 2. This program is licensed "as is" without any warranty of any | ||
| 7 | * kind, whether express or implied. | ||
| 8 | */ | ||
| 9 | |||
| 10 | #ifndef _SR9800_H | ||
| 11 | #define _SR9800_H | ||
| 12 | |||
| 13 | /* SR9800 spec. command table on Linux Platform */ | ||
| 14 | |||
| 15 | /* command : Software Station Management Control Reg */ | ||
| 16 | #define SR_CMD_SET_SW_MII 0x06 | ||
| 17 | /* command : PHY Read Reg */ | ||
| 18 | #define SR_CMD_READ_MII_REG 0x07 | ||
| 19 | /* command : PHY Write Reg */ | ||
| 20 | #define SR_CMD_WRITE_MII_REG 0x08 | ||
| 21 | /* command : Hardware Station Management Control Reg */ | ||
| 22 | #define SR_CMD_SET_HW_MII 0x0a | ||
| 23 | /* command : SROM Read Reg */ | ||
| 24 | #define SR_CMD_READ_EEPROM 0x0b | ||
| 25 | /* command : SROM Write Reg */ | ||
| 26 | #define SR_CMD_WRITE_EEPROM 0x0c | ||
| 27 | /* command : SROM Write Enable Reg */ | ||
| 28 | #define SR_CMD_WRITE_ENABLE 0x0d | ||
| 29 | /* command : SROM Write Disable Reg */ | ||
| 30 | #define SR_CMD_WRITE_DISABLE 0x0e | ||
| 31 | /* command : RX Control Read Reg */ | ||
| 32 | #define SR_CMD_READ_RX_CTL 0x0f | ||
| 33 | #define SR_RX_CTL_PRO (1 << 0) | ||
| 34 | #define SR_RX_CTL_AMALL (1 << 1) | ||
| 35 | #define SR_RX_CTL_SEP (1 << 2) | ||
| 36 | #define SR_RX_CTL_AB (1 << 3) | ||
| 37 | #define SR_RX_CTL_AM (1 << 4) | ||
| 38 | #define SR_RX_CTL_AP (1 << 5) | ||
| 39 | #define SR_RX_CTL_ARP (1 << 6) | ||
| 40 | #define SR_RX_CTL_SO (1 << 7) | ||
| 41 | #define SR_RX_CTL_RH1M (1 << 8) | ||
| 42 | #define SR_RX_CTL_RH2M (1 << 9) | ||
| 43 | #define SR_RX_CTL_RH3M (1 << 10) | ||
| 44 | /* command : RX Control Write Reg */ | ||
| 45 | #define SR_CMD_WRITE_RX_CTL 0x10 | ||
| 46 | /* command : IPG0/IPG1/IPG2 Control Read Reg */ | ||
| 47 | #define SR_CMD_READ_IPG012 0x11 | ||
| 48 | /* command : IPG0/IPG1/IPG2 Control Write Reg */ | ||
| 49 | #define SR_CMD_WRITE_IPG012 0x12 | ||
| 50 | /* command : Node ID Read Reg */ | ||
| 51 | #define SR_CMD_READ_NODE_ID 0x13 | ||
| 52 | /* command : Node ID Write Reg */ | ||
| 53 | #define SR_CMD_WRITE_NODE_ID 0x14 | ||
| 54 | /* command : Multicast Filter Array Read Reg */ | ||
| 55 | #define SR_CMD_READ_MULTI_FILTER 0x15 | ||
| 56 | /* command : Multicast Filter Array Write Reg */ | ||
| 57 | #define SR_CMD_WRITE_MULTI_FILTER 0x16 | ||
| 58 | /* command : Eth/HomePNA PHY Address Reg */ | ||
| 59 | #define SR_CMD_READ_PHY_ID 0x19 | ||
| 60 | /* command : Medium Status Read Reg */ | ||
| 61 | #define SR_CMD_READ_MEDIUM_STATUS 0x1a | ||
| 62 | #define SR_MONITOR_LINK (1 << 1) | ||
| 63 | #define SR_MONITOR_MAGIC (1 << 2) | ||
| 64 | #define SR_MONITOR_HSFS (1 << 4) | ||
| 65 | /* command : Medium Status Write Reg */ | ||
| 66 | #define SR_CMD_WRITE_MEDIUM_MODE 0x1b | ||
| 67 | #define SR_MEDIUM_GM (1 << 0) | ||
| 68 | #define SR_MEDIUM_FD (1 << 1) | ||
| 69 | #define SR_MEDIUM_AC (1 << 2) | ||
| 70 | #define SR_MEDIUM_ENCK (1 << 3) | ||
| 71 | #define SR_MEDIUM_RFC (1 << 4) | ||
| 72 | #define SR_MEDIUM_TFC (1 << 5) | ||
| 73 | #define SR_MEDIUM_JFE (1 << 6) | ||
| 74 | #define SR_MEDIUM_PF (1 << 7) | ||
| 75 | #define SR_MEDIUM_RE (1 << 8) | ||
| 76 | #define SR_MEDIUM_PS (1 << 9) | ||
| 77 | #define SR_MEDIUM_RSV (1 << 10) | ||
| 78 | #define SR_MEDIUM_SBP (1 << 11) | ||
| 79 | #define SR_MEDIUM_SM (1 << 12) | ||
| 80 | /* command : Monitor Mode Status Read Reg */ | ||
| 81 | #define SR_CMD_READ_MONITOR_MODE 0x1c | ||
| 82 | /* command : Monitor Mode Status Write Reg */ | ||
| 83 | #define SR_CMD_WRITE_MONITOR_MODE 0x1d | ||
| 84 | /* command : GPIO Status Read Reg */ | ||
| 85 | #define SR_CMD_READ_GPIOS 0x1e | ||
| 86 | #define SR_GPIO_GPO0EN (1 << 0) /* GPIO0 Output enable */ | ||
| 87 | #define SR_GPIO_GPO_0 (1 << 1) /* GPIO0 Output value */ | ||
| 88 | #define SR_GPIO_GPO1EN (1 << 2) /* GPIO1 Output enable */ | ||
| 89 | #define SR_GPIO_GPO_1 (1 << 3) /* GPIO1 Output value */ | ||
| 90 | #define SR_GPIO_GPO2EN (1 << 4) /* GPIO2 Output enable */ | ||
| 91 | #define SR_GPIO_GPO_2 (1 << 5) /* GPIO2 Output value */ | ||
| 92 | #define SR_GPIO_RESERVED (1 << 6) /* Reserved */ | ||
| 93 | #define SR_GPIO_RSE (1 << 7) /* Reload serial EEPROM */ | ||
| 94 | /* command : GPIO Status Write Reg */ | ||
| 95 | #define SR_CMD_WRITE_GPIOS 0x1f | ||
| 96 | /* command : Eth PHY Power and Reset Control Reg */ | ||
| 97 | #define SR_CMD_SW_RESET 0x20 | ||
| 98 | #define SR_SWRESET_CLEAR 0x00 | ||
| 99 | #define SR_SWRESET_RR (1 << 0) | ||
| 100 | #define SR_SWRESET_RT (1 << 1) | ||
| 101 | #define SR_SWRESET_PRTE (1 << 2) | ||
| 102 | #define SR_SWRESET_PRL (1 << 3) | ||
| 103 | #define SR_SWRESET_BZ (1 << 4) | ||
| 104 | #define SR_SWRESET_IPRL (1 << 5) | ||
| 105 | #define SR_SWRESET_IPPD (1 << 6) | ||
| 106 | /* command : Software Interface Selection Status Read Reg */ | ||
| 107 | #define SR_CMD_SW_PHY_STATUS 0x21 | ||
| 108 | /* command : Software Interface Selection Status Write Reg */ | ||
| 109 | #define SR_CMD_SW_PHY_SELECT 0x22 | ||
| 110 | /* command : BULK in Buffer Size Reg */ | ||
| 111 | #define SR_CMD_BULKIN_SIZE 0x2A | ||
| 112 | /* command : LED_MUX Control Reg */ | ||
| 113 | #define SR_CMD_LED_MUX 0x70 | ||
| 114 | #define SR_LED_MUX_TX_ACTIVE (1 << 0) | ||
| 115 | #define SR_LED_MUX_RX_ACTIVE (1 << 1) | ||
| 116 | #define SR_LED_MUX_COLLISION (1 << 2) | ||
| 117 | #define SR_LED_MUX_DUP_COL (1 << 3) | ||
| 118 | #define SR_LED_MUX_DUP (1 << 4) | ||
| 119 | #define SR_LED_MUX_SPEED (1 << 5) | ||
| 120 | #define SR_LED_MUX_LINK_ACTIVE (1 << 6) | ||
| 121 | #define SR_LED_MUX_LINK (1 << 7) | ||
| 122 | |||
| 123 | /* Register Access Flags */ | ||
| 124 | #define SR_REQ_RD_REG (USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE) | ||
| 125 | #define SR_REQ_WR_REG (USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE) | ||
| 126 | |||
| 127 | /* Multicast Filter Array size & Max Number */ | ||
| 128 | #define SR_MCAST_FILTER_SIZE 8 | ||
| 129 | #define SR_MAX_MCAST 64 | ||
| 130 | |||
| 131 | /* IPG0/1/2 Default Value */ | ||
| 132 | #define SR9800_IPG0_DEFAULT 0x15 | ||
| 133 | #define SR9800_IPG1_DEFAULT 0x0c | ||
| 134 | #define SR9800_IPG2_DEFAULT 0x12 | ||
| 135 | |||
| 136 | /* Medium Status Default Mode */ | ||
| 137 | #define SR9800_MEDIUM_DEFAULT \ | ||
| 138 | (SR_MEDIUM_FD | SR_MEDIUM_RFC | \ | ||
| 139 | SR_MEDIUM_TFC | SR_MEDIUM_PS | \ | ||
| 140 | SR_MEDIUM_AC | SR_MEDIUM_RE) | ||
| 141 | |||
| 142 | /* RX Control Default Setting */ | ||
| 143 | #define SR_DEFAULT_RX_CTL \ | ||
| 144 | (SR_RX_CTL_SO | SR_RX_CTL_AB | SR_RX_CTL_RH1M) | ||
| 145 | |||
| 146 | /* EEPROM Magic Number & EEPROM Size */ | ||
| 147 | #define SR_EEPROM_MAGIC 0xdeadbeef | ||
| 148 | #define SR9800_EEPROM_LEN 0xff | ||
| 149 | |||
| 150 | /* SR9800 Driver Version and Driver Name */ | ||
| 151 | #define DRIVER_VERSION "11-Nov-2013" | ||
| 152 | #define DRIVER_NAME "CoreChips" | ||
| 153 | #define DRIVER_FLAG \ | ||
| 154 | (FLAG_ETHER | FLAG_FRAMING_AX | FLAG_LINK_INTR | FLAG_MULTI_PACKET) | ||
| 155 | |||
| 156 | /* SR9800 BULKIN Buffer Size */ | ||
| 157 | #define SR9800_MAX_BULKIN_2K 0 | ||
| 158 | #define SR9800_MAX_BULKIN_4K 1 | ||
| 159 | #define SR9800_MAX_BULKIN_6K 2 | ||
| 160 | #define SR9800_MAX_BULKIN_8K 3 | ||
| 161 | #define SR9800_MAX_BULKIN_16K 4 | ||
| 162 | #define SR9800_MAX_BULKIN_20K 5 | ||
| 163 | #define SR9800_MAX_BULKIN_24K 6 | ||
| 164 | #define SR9800_MAX_BULKIN_32K 7 | ||
| 165 | |||
| 166 | struct {unsigned short size, byte_cnt, threshold; } SR9800_BULKIN_SIZE[] = { | ||
| 167 | /* 2k */ | ||
| 168 | {2048, 0x8000, 0x8001}, | ||
| 169 | /* 4k */ | ||
| 170 | {4096, 0x8100, 0x8147}, | ||
| 171 | /* 6k */ | ||
| 172 | {6144, 0x8200, 0x81EB}, | ||
| 173 | /* 8k */ | ||
| 174 | {8192, 0x8300, 0x83D7}, | ||
| 175 | /* 16 */ | ||
| 176 | {16384, 0x8400, 0x851E}, | ||
| 177 | /* 20k */ | ||
| 178 | {20480, 0x8500, 0x8666}, | ||
| 179 | /* 24k */ | ||
| 180 | {24576, 0x8600, 0x87AE}, | ||
| 181 | /* 32k */ | ||
| 182 | {32768, 0x8700, 0x8A3D}, | ||
| 183 | }; | ||
| 184 | |||
| 185 | /* This structure cannot exceed sizeof(unsigned long [5]) AKA 20 bytes */ | ||
| 186 | struct sr_data { | ||
| 187 | u8 multi_filter[SR_MCAST_FILTER_SIZE]; | ||
| 188 | u8 mac_addr[ETH_ALEN]; | ||
| 189 | u8 phymode; | ||
| 190 | u8 ledmode; | ||
| 191 | u8 eeprom_len; | ||
| 192 | }; | ||
| 193 | |||
| 194 | struct sr9800_int_data { | ||
| 195 | __le16 res1; | ||
| 196 | u8 link; | ||
| 197 | __le16 res2; | ||
| 198 | u8 status; | ||
| 199 | __le16 res3; | ||
| 200 | } __packed; | ||
| 201 | |||
| 202 | #endif /* _SR9800_H */ | ||
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index 4671da755e7b..dd10d5817d2a 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c | |||
| @@ -542,17 +542,19 @@ static inline void rx_process (struct usbnet *dev, struct sk_buff *skb) | |||
| 542 | } | 542 | } |
| 543 | // else network stack removes extra byte if we forced a short packet | 543 | // else network stack removes extra byte if we forced a short packet |
| 544 | 544 | ||
| 545 | if (skb->len) { | 545 | /* all data was already cloned from skb inside the driver */ |
| 546 | /* all data was already cloned from skb inside the driver */ | 546 | if (dev->driver_info->flags & FLAG_MULTI_PACKET) |
| 547 | if (dev->driver_info->flags & FLAG_MULTI_PACKET) | 547 | goto done; |
| 548 | dev_kfree_skb_any(skb); | 548 | |
| 549 | else | 549 | if (skb->len < ETH_HLEN) { |
| 550 | usbnet_skb_return(dev, skb); | 550 | dev->net->stats.rx_errors++; |
| 551 | dev->net->stats.rx_length_errors++; | ||
| 552 | netif_dbg(dev, rx_err, dev->net, "rx length %d\n", skb->len); | ||
| 553 | } else { | ||
| 554 | usbnet_skb_return(dev, skb); | ||
| 551 | return; | 555 | return; |
| 552 | } | 556 | } |
| 553 | 557 | ||
| 554 | netif_dbg(dev, rx_err, dev->net, "drop\n"); | ||
| 555 | dev->net->stats.rx_errors++; | ||
| 556 | done: | 558 | done: |
| 557 | skb_queue_tail(&dev->done, skb); | 559 | skb_queue_tail(&dev->done, skb); |
| 558 | } | 560 | } |
| @@ -574,13 +576,6 @@ static void rx_complete (struct urb *urb) | |||
| 574 | switch (urb_status) { | 576 | switch (urb_status) { |
| 575 | /* success */ | 577 | /* success */ |
| 576 | case 0: | 578 | case 0: |
| 577 | if (skb->len < dev->net->hard_header_len) { | ||
| 578 | state = rx_cleanup; | ||
| 579 | dev->net->stats.rx_errors++; | ||
| 580 | dev->net->stats.rx_length_errors++; | ||
| 581 | netif_dbg(dev, rx_err, dev->net, | ||
| 582 | "rx length %d\n", skb->len); | ||
| 583 | } | ||
| 584 | break; | 579 | break; |
| 585 | 580 | ||
| 586 | /* stalls need manual reset. this is rare ... except that | 581 | /* stalls need manual reset. this is rare ... except that |
diff --git a/drivers/net/veth.c b/drivers/net/veth.c index 2ec2041b62d4..5b374370f71c 100644 --- a/drivers/net/veth.c +++ b/drivers/net/veth.c | |||
| @@ -285,7 +285,8 @@ static void veth_setup(struct net_device *dev) | |||
| 285 | dev->ethtool_ops = &veth_ethtool_ops; | 285 | dev->ethtool_ops = &veth_ethtool_ops; |
| 286 | dev->features |= NETIF_F_LLTX; | 286 | dev->features |= NETIF_F_LLTX; |
| 287 | dev->features |= VETH_FEATURES; | 287 | dev->features |= VETH_FEATURES; |
| 288 | dev->vlan_features = dev->features; | 288 | dev->vlan_features = dev->features & |
| 289 | ~(NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_STAG_TX); | ||
| 289 | dev->destructor = veth_dev_free; | 290 | dev->destructor = veth_dev_free; |
| 290 | 291 | ||
| 291 | dev->hw_features = VETH_FEATURES; | 292 | dev->hw_features = VETH_FEATURES; |
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index d75f8edf4fb3..5632a99cbbd2 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c | |||
| @@ -1711,7 +1711,8 @@ static int virtnet_probe(struct virtio_device *vdev) | |||
| 1711 | /* If we can receive ANY GSO packets, we must allocate large ones. */ | 1711 | /* If we can receive ANY GSO packets, we must allocate large ones. */ |
| 1712 | if (virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_TSO4) || | 1712 | if (virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_TSO4) || |
| 1713 | virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_TSO6) || | 1713 | virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_TSO6) || |
| 1714 | virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_ECN)) | 1714 | virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_ECN) || |
| 1715 | virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_UFO)) | ||
| 1715 | vi->big_packets = true; | 1716 | vi->big_packets = true; |
| 1716 | 1717 | ||
| 1717 | if (virtio_has_feature(vdev, VIRTIO_NET_F_MRG_RXBUF)) | 1718 | if (virtio_has_feature(vdev, VIRTIO_NET_F_MRG_RXBUF)) |
diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c index 026a313c2d2d..b0f705c2378f 100644 --- a/drivers/net/vxlan.c +++ b/drivers/net/vxlan.c | |||
| @@ -469,7 +469,6 @@ static inline struct hlist_head *vxlan_fdb_head(struct vxlan_dev *vxlan, | |||
| 469 | /* Look up Ethernet address in forwarding table */ | 469 | /* Look up Ethernet address in forwarding table */ |
| 470 | static struct vxlan_fdb *__vxlan_find_mac(struct vxlan_dev *vxlan, | 470 | static struct vxlan_fdb *__vxlan_find_mac(struct vxlan_dev *vxlan, |
| 471 | const u8 *mac) | 471 | const u8 *mac) |
| 472 | |||
| 473 | { | 472 | { |
| 474 | struct hlist_head *head = vxlan_fdb_head(vxlan, mac); | 473 | struct hlist_head *head = vxlan_fdb_head(vxlan, mac); |
| 475 | struct vxlan_fdb *f; | 474 | struct vxlan_fdb *f; |
| @@ -596,10 +595,8 @@ static struct sk_buff **vxlan_gro_receive(struct sk_buff **head, struct sk_buff | |||
| 596 | NAPI_GRO_CB(p)->same_flow = 0; | 595 | NAPI_GRO_CB(p)->same_flow = 0; |
| 597 | continue; | 596 | continue; |
| 598 | } | 597 | } |
| 599 | goto found; | ||
| 600 | } | 598 | } |
| 601 | 599 | ||
| 602 | found: | ||
| 603 | type = eh->h_proto; | 600 | type = eh->h_proto; |
| 604 | 601 | ||
| 605 | rcu_read_lock(); | 602 | rcu_read_lock(); |
diff --git a/drivers/net/wan/dlci.c b/drivers/net/wan/dlci.c index 0d1c7592efa0..19f7cb2cdef3 100644 --- a/drivers/net/wan/dlci.c +++ b/drivers/net/wan/dlci.c | |||
| @@ -71,12 +71,9 @@ static int dlci_header(struct sk_buff *skb, struct net_device *dev, | |||
| 71 | const void *saddr, unsigned len) | 71 | const void *saddr, unsigned len) |
| 72 | { | 72 | { |
| 73 | struct frhdr hdr; | 73 | struct frhdr hdr; |
| 74 | struct dlci_local *dlp; | ||
| 75 | unsigned int hlen; | 74 | unsigned int hlen; |
| 76 | char *dest; | 75 | char *dest; |
| 77 | 76 | ||
| 78 | dlp = netdev_priv(dev); | ||
| 79 | |||
| 80 | hdr.control = FRAD_I_UI; | 77 | hdr.control = FRAD_I_UI; |
| 81 | switch (type) | 78 | switch (type) |
| 82 | { | 79 | { |
| @@ -107,11 +104,9 @@ static int dlci_header(struct sk_buff *skb, struct net_device *dev, | |||
| 107 | 104 | ||
| 108 | static void dlci_receive(struct sk_buff *skb, struct net_device *dev) | 105 | static void dlci_receive(struct sk_buff *skb, struct net_device *dev) |
| 109 | { | 106 | { |
| 110 | struct dlci_local *dlp; | ||
| 111 | struct frhdr *hdr; | 107 | struct frhdr *hdr; |
| 112 | int process, header; | 108 | int process, header; |
| 113 | 109 | ||
| 114 | dlp = netdev_priv(dev); | ||
| 115 | if (!pskb_may_pull(skb, sizeof(*hdr))) { | 110 | if (!pskb_may_pull(skb, sizeof(*hdr))) { |
| 116 | netdev_notice(dev, "invalid data no header\n"); | 111 | netdev_notice(dev, "invalid data no header\n"); |
| 117 | dev->stats.rx_errors++; | 112 | dev->stats.rx_errors++; |
diff --git a/drivers/net/wireless/ath/ar5523/ar5523.c b/drivers/net/wireless/ath/ar5523/ar5523.c index 8aa20df55e50..507d9a9ee69a 100644 --- a/drivers/net/wireless/ath/ar5523/ar5523.c +++ b/drivers/net/wireless/ath/ar5523/ar5523.c | |||
| @@ -1764,7 +1764,7 @@ static struct usb_device_id ar5523_id_table[] = { | |||
| 1764 | AR5523_DEVICE_UG(0x07d1, 0x3a07), /* D-Link / WUA-2340 rev A1 */ | 1764 | AR5523_DEVICE_UG(0x07d1, 0x3a07), /* D-Link / WUA-2340 rev A1 */ |
| 1765 | AR5523_DEVICE_UG(0x1690, 0x0712), /* Gigaset / AR5523 */ | 1765 | AR5523_DEVICE_UG(0x1690, 0x0712), /* Gigaset / AR5523 */ |
| 1766 | AR5523_DEVICE_UG(0x1690, 0x0710), /* Gigaset / SMCWUSBTG */ | 1766 | AR5523_DEVICE_UG(0x1690, 0x0710), /* Gigaset / SMCWUSBTG */ |
| 1767 | AR5523_DEVICE_UG(0x129b, 0x160c), /* Gigaset / USB stick 108 | 1767 | AR5523_DEVICE_UG(0x129b, 0x160b), /* Gigaset / USB stick 108 |
| 1768 | (CyberTAN Technology) */ | 1768 | (CyberTAN Technology) */ |
| 1769 | AR5523_DEVICE_UG(0x16ab, 0x7801), /* Globalsun / AR5523_1 */ | 1769 | AR5523_DEVICE_UG(0x16ab, 0x7801), /* Globalsun / AR5523_1 */ |
| 1770 | AR5523_DEVICE_UX(0x16ab, 0x7811), /* Globalsun / AR5523_2 */ | 1770 | AR5523_DEVICE_UX(0x16ab, 0x7811), /* Globalsun / AR5523_2 */ |
diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c index d6bc7cb61bfb..1a2973b7acf2 100644 --- a/drivers/net/wireless/ath/ath5k/phy.c +++ b/drivers/net/wireless/ath/ath5k/phy.c | |||
| @@ -110,7 +110,7 @@ ath5k_hw_radio_revision(struct ath5k_hw *ah, enum ieee80211_band band) | |||
| 110 | ath5k_hw_reg_write(ah, 0x00010000, AR5K_PHY(0x20)); | 110 | ath5k_hw_reg_write(ah, 0x00010000, AR5K_PHY(0x20)); |
| 111 | 111 | ||
| 112 | if (ah->ah_version == AR5K_AR5210) { | 112 | if (ah->ah_version == AR5K_AR5210) { |
| 113 | srev = ath5k_hw_reg_read(ah, AR5K_PHY(256) >> 28) & 0xf; | 113 | srev = (ath5k_hw_reg_read(ah, AR5K_PHY(256)) >> 28) & 0xf; |
| 114 | ret = (u16)ath5k_hw_bitswap(srev, 4) + 1; | 114 | ret = (u16)ath5k_hw_bitswap(srev, 4) + 1; |
| 115 | } else { | 115 | } else { |
| 116 | srev = (ath5k_hw_reg_read(ah, AR5K_PHY(0x100)) >> 24) & 0xff; | 116 | srev = (ath5k_hw_reg_read(ah, AR5K_PHY(0x100)) >> 24) & 0xff; |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index 25243cbc07f0..b8daff78b9d1 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | |||
| @@ -5065,6 +5065,10 @@ static u16 ar9003_hw_get_max_edge_power(struct ar9300_eeprom *eep, | |||
| 5065 | break; | 5065 | break; |
| 5066 | } | 5066 | } |
| 5067 | } | 5067 | } |
| 5068 | |||
| 5069 | if (is2GHz && !twiceMaxEdgePower) | ||
| 5070 | twiceMaxEdgePower = 60; | ||
| 5071 | |||
| 5068 | return twiceMaxEdgePower; | 5072 | return twiceMaxEdgePower; |
| 5069 | } | 5073 | } |
| 5070 | 5074 | ||
diff --git a/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h b/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h index 1cc13569b17b..1b6b4d0cfa97 100644 --- a/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h | |||
| @@ -57,7 +57,7 @@ static const u32 ar9462_2p0_baseband_postamble[][5] = { | |||
| 57 | {0x00009e14, 0x37b95d5e, 0x37b9605e, 0x3236605e, 0x32365a5e}, | 57 | {0x00009e14, 0x37b95d5e, 0x37b9605e, 0x3236605e, 0x32365a5e}, |
| 58 | {0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | 58 | {0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, |
| 59 | {0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c}, | 59 | {0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c}, |
| 60 | {0x00009e20, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce}, | 60 | {0x00009e20, 0x000003a5, 0x000003a5, 0x000003a5, 0x000003a5}, |
| 61 | {0x00009e2c, 0x0000001c, 0x0000001c, 0x00000021, 0x00000021}, | 61 | {0x00009e2c, 0x0000001c, 0x0000001c, 0x00000021, 0x00000021}, |
| 62 | {0x00009e3c, 0xcf946220, 0xcf946220, 0xcfd5c782, 0xcfd5c282}, | 62 | {0x00009e3c, 0xcf946220, 0xcf946220, 0xcfd5c782, 0xcfd5c282}, |
| 63 | {0x00009e44, 0x62321e27, 0x62321e27, 0xfe291e27, 0xfe291e27}, | 63 | {0x00009e44, 0x62321e27, 0x62321e27, 0xfe291e27, 0xfe291e27}, |
| @@ -96,7 +96,7 @@ static const u32 ar9462_2p0_baseband_postamble[][5] = { | |||
| 96 | {0x0000ae04, 0x001c0000, 0x001c0000, 0x001c0000, 0x00100000}, | 96 | {0x0000ae04, 0x001c0000, 0x001c0000, 0x001c0000, 0x00100000}, |
| 97 | {0x0000ae18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | 97 | {0x0000ae18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, |
| 98 | {0x0000ae1c, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c}, | 98 | {0x0000ae1c, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c}, |
| 99 | {0x0000ae20, 0x000001b5, 0x000001b5, 0x000001ce, 0x000001ce}, | 99 | {0x0000ae20, 0x000001a6, 0x000001a6, 0x000001aa, 0x000001aa}, |
| 100 | {0x0000b284, 0x00000000, 0x00000000, 0x00000550, 0x00000550}, | 100 | {0x0000b284, 0x00000000, 0x00000000, 0x00000550, 0x00000550}, |
| 101 | }; | 101 | }; |
| 102 | 102 | ||
diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index 58da3468d1f0..99a203174f45 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h | |||
| @@ -262,6 +262,8 @@ enum tid_aggr_state { | |||
| 262 | struct ath9k_htc_sta { | 262 | struct ath9k_htc_sta { |
| 263 | u8 index; | 263 | u8 index; |
| 264 | enum tid_aggr_state tid_state[ATH9K_HTC_MAX_TID]; | 264 | enum tid_aggr_state tid_state[ATH9K_HTC_MAX_TID]; |
| 265 | struct work_struct rc_update_work; | ||
| 266 | struct ath9k_htc_priv *htc_priv; | ||
| 265 | }; | 267 | }; |
| 266 | 268 | ||
| 267 | #define ATH9K_HTC_RXBUF 256 | 269 | #define ATH9K_HTC_RXBUF 256 |
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index f4e1de20d99c..c57d6b859c04 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c | |||
| @@ -34,6 +34,10 @@ static int ath9k_htc_btcoex_enable; | |||
| 34 | module_param_named(btcoex_enable, ath9k_htc_btcoex_enable, int, 0444); | 34 | module_param_named(btcoex_enable, ath9k_htc_btcoex_enable, int, 0444); |
| 35 | MODULE_PARM_DESC(btcoex_enable, "Enable wifi-BT coexistence"); | 35 | MODULE_PARM_DESC(btcoex_enable, "Enable wifi-BT coexistence"); |
| 36 | 36 | ||
| 37 | static int ath9k_ps_enable; | ||
| 38 | module_param_named(ps_enable, ath9k_ps_enable, int, 0444); | ||
| 39 | MODULE_PARM_DESC(ps_enable, "Enable WLAN PowerSave"); | ||
| 40 | |||
| 37 | #define CHAN2G(_freq, _idx) { \ | 41 | #define CHAN2G(_freq, _idx) { \ |
| 38 | .center_freq = (_freq), \ | 42 | .center_freq = (_freq), \ |
| 39 | .hw_value = (_idx), \ | 43 | .hw_value = (_idx), \ |
| @@ -725,12 +729,14 @@ static void ath9k_set_hw_capab(struct ath9k_htc_priv *priv, | |||
| 725 | IEEE80211_HW_SPECTRUM_MGMT | | 729 | IEEE80211_HW_SPECTRUM_MGMT | |
| 726 | IEEE80211_HW_HAS_RATE_CONTROL | | 730 | IEEE80211_HW_HAS_RATE_CONTROL | |
| 727 | IEEE80211_HW_RX_INCLUDES_FCS | | 731 | IEEE80211_HW_RX_INCLUDES_FCS | |
| 728 | IEEE80211_HW_SUPPORTS_PS | | ||
| 729 | IEEE80211_HW_PS_NULLFUNC_STACK | | 732 | IEEE80211_HW_PS_NULLFUNC_STACK | |
| 730 | IEEE80211_HW_REPORTS_TX_ACK_STATUS | | 733 | IEEE80211_HW_REPORTS_TX_ACK_STATUS | |
| 731 | IEEE80211_HW_MFP_CAPABLE | | 734 | IEEE80211_HW_MFP_CAPABLE | |
| 732 | IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING; | 735 | IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING; |
| 733 | 736 | ||
| 737 | if (ath9k_ps_enable) | ||
| 738 | hw->flags |= IEEE80211_HW_SUPPORTS_PS; | ||
| 739 | |||
| 734 | hw->wiphy->interface_modes = | 740 | hw->wiphy->interface_modes = |
| 735 | BIT(NL80211_IFTYPE_STATION) | | 741 | BIT(NL80211_IFTYPE_STATION) | |
| 736 | BIT(NL80211_IFTYPE_ADHOC) | | 742 | BIT(NL80211_IFTYPE_ADHOC) | |
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index 608d739d1378..c9254a61ca52 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c | |||
| @@ -1270,18 +1270,50 @@ static void ath9k_htc_configure_filter(struct ieee80211_hw *hw, | |||
| 1270 | mutex_unlock(&priv->mutex); | 1270 | mutex_unlock(&priv->mutex); |
| 1271 | } | 1271 | } |
| 1272 | 1272 | ||
| 1273 | static void ath9k_htc_sta_rc_update_work(struct work_struct *work) | ||
| 1274 | { | ||
| 1275 | struct ath9k_htc_sta *ista = | ||
| 1276 | container_of(work, struct ath9k_htc_sta, rc_update_work); | ||
| 1277 | struct ieee80211_sta *sta = | ||
| 1278 | container_of((void *)ista, struct ieee80211_sta, drv_priv); | ||
| 1279 | struct ath9k_htc_priv *priv = ista->htc_priv; | ||
| 1280 | struct ath_common *common = ath9k_hw_common(priv->ah); | ||
| 1281 | struct ath9k_htc_target_rate trate; | ||
| 1282 | |||
| 1283 | mutex_lock(&priv->mutex); | ||
| 1284 | ath9k_htc_ps_wakeup(priv); | ||
| 1285 | |||
| 1286 | memset(&trate, 0, sizeof(struct ath9k_htc_target_rate)); | ||
| 1287 | ath9k_htc_setup_rate(priv, sta, &trate); | ||
| 1288 | if (!ath9k_htc_send_rate_cmd(priv, &trate)) | ||
| 1289 | ath_dbg(common, CONFIG, | ||
| 1290 | "Supported rates for sta: %pM updated, rate caps: 0x%X\n", | ||
| 1291 | sta->addr, be32_to_cpu(trate.capflags)); | ||
| 1292 | else | ||
| 1293 | ath_dbg(common, CONFIG, | ||
| 1294 | "Unable to update supported rates for sta: %pM\n", | ||
| 1295 | sta->addr); | ||
| 1296 | |||
| 1297 | ath9k_htc_ps_restore(priv); | ||
| 1298 | mutex_unlock(&priv->mutex); | ||
| 1299 | } | ||
| 1300 | |||
| 1273 | static int ath9k_htc_sta_add(struct ieee80211_hw *hw, | 1301 | static int ath9k_htc_sta_add(struct ieee80211_hw *hw, |
| 1274 | struct ieee80211_vif *vif, | 1302 | struct ieee80211_vif *vif, |
| 1275 | struct ieee80211_sta *sta) | 1303 | struct ieee80211_sta *sta) |
| 1276 | { | 1304 | { |
| 1277 | struct ath9k_htc_priv *priv = hw->priv; | 1305 | struct ath9k_htc_priv *priv = hw->priv; |
| 1306 | struct ath9k_htc_sta *ista = (struct ath9k_htc_sta *) sta->drv_priv; | ||
| 1278 | int ret; | 1307 | int ret; |
| 1279 | 1308 | ||
| 1280 | mutex_lock(&priv->mutex); | 1309 | mutex_lock(&priv->mutex); |
| 1281 | ath9k_htc_ps_wakeup(priv); | 1310 | ath9k_htc_ps_wakeup(priv); |
| 1282 | ret = ath9k_htc_add_station(priv, vif, sta); | 1311 | ret = ath9k_htc_add_station(priv, vif, sta); |
| 1283 | if (!ret) | 1312 | if (!ret) { |
| 1313 | INIT_WORK(&ista->rc_update_work, ath9k_htc_sta_rc_update_work); | ||
| 1314 | ista->htc_priv = priv; | ||
| 1284 | ath9k_htc_init_rate(priv, sta); | 1315 | ath9k_htc_init_rate(priv, sta); |
| 1316 | } | ||
| 1285 | ath9k_htc_ps_restore(priv); | 1317 | ath9k_htc_ps_restore(priv); |
| 1286 | mutex_unlock(&priv->mutex); | 1318 | mutex_unlock(&priv->mutex); |
| 1287 | 1319 | ||
| @@ -1293,12 +1325,13 @@ static int ath9k_htc_sta_remove(struct ieee80211_hw *hw, | |||
| 1293 | struct ieee80211_sta *sta) | 1325 | struct ieee80211_sta *sta) |
| 1294 | { | 1326 | { |
| 1295 | struct ath9k_htc_priv *priv = hw->priv; | 1327 | struct ath9k_htc_priv *priv = hw->priv; |
| 1296 | struct ath9k_htc_sta *ista; | 1328 | struct ath9k_htc_sta *ista = (struct ath9k_htc_sta *) sta->drv_priv; |
| 1297 | int ret; | 1329 | int ret; |
| 1298 | 1330 | ||
| 1331 | cancel_work_sync(&ista->rc_update_work); | ||
| 1332 | |||
| 1299 | mutex_lock(&priv->mutex); | 1333 | mutex_lock(&priv->mutex); |
| 1300 | ath9k_htc_ps_wakeup(priv); | 1334 | ath9k_htc_ps_wakeup(priv); |
| 1301 | ista = (struct ath9k_htc_sta *) sta->drv_priv; | ||
| 1302 | htc_sta_drain(priv->htc, ista->index); | 1335 | htc_sta_drain(priv->htc, ista->index); |
| 1303 | ret = ath9k_htc_remove_station(priv, vif, sta); | 1336 | ret = ath9k_htc_remove_station(priv, vif, sta); |
| 1304 | ath9k_htc_ps_restore(priv); | 1337 | ath9k_htc_ps_restore(priv); |
| @@ -1311,28 +1344,12 @@ static void ath9k_htc_sta_rc_update(struct ieee80211_hw *hw, | |||
| 1311 | struct ieee80211_vif *vif, | 1344 | struct ieee80211_vif *vif, |
| 1312 | struct ieee80211_sta *sta, u32 changed) | 1345 | struct ieee80211_sta *sta, u32 changed) |
| 1313 | { | 1346 | { |
| 1314 | struct ath9k_htc_priv *priv = hw->priv; | 1347 | struct ath9k_htc_sta *ista = (struct ath9k_htc_sta *) sta->drv_priv; |
| 1315 | struct ath_common *common = ath9k_hw_common(priv->ah); | ||
| 1316 | struct ath9k_htc_target_rate trate; | ||
| 1317 | |||
| 1318 | mutex_lock(&priv->mutex); | ||
| 1319 | ath9k_htc_ps_wakeup(priv); | ||
| 1320 | 1348 | ||
| 1321 | if (changed & IEEE80211_RC_SUPP_RATES_CHANGED) { | 1349 | if (!(changed & IEEE80211_RC_SUPP_RATES_CHANGED)) |
| 1322 | memset(&trate, 0, sizeof(struct ath9k_htc_target_rate)); | 1350 | return; |
| 1323 | ath9k_htc_setup_rate(priv, sta, &trate); | ||
| 1324 | if (!ath9k_htc_send_rate_cmd(priv, &trate)) | ||
| 1325 | ath_dbg(common, CONFIG, | ||
| 1326 | "Supported rates for sta: %pM updated, rate caps: 0x%X\n", | ||
| 1327 | sta->addr, be32_to_cpu(trate.capflags)); | ||
| 1328 | else | ||
| 1329 | ath_dbg(common, CONFIG, | ||
| 1330 | "Unable to update supported rates for sta: %pM\n", | ||
| 1331 | sta->addr); | ||
| 1332 | } | ||
| 1333 | 1351 | ||
| 1334 | ath9k_htc_ps_restore(priv); | 1352 | schedule_work(&ista->rc_update_work); |
| 1335 | mutex_unlock(&priv->mutex); | ||
| 1336 | } | 1353 | } |
| 1337 | 1354 | ||
| 1338 | static int ath9k_htc_conf_tx(struct ieee80211_hw *hw, | 1355 | static int ath9k_htc_conf_tx(struct ieee80211_hw *hw, |
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index fbf43c05713f..303ce27964c1 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c | |||
| @@ -1316,7 +1316,7 @@ static bool ath9k_hw_set_reset(struct ath_hw *ah, int type) | |||
| 1316 | if (AR_SREV_9300_20_OR_LATER(ah)) | 1316 | if (AR_SREV_9300_20_OR_LATER(ah)) |
| 1317 | udelay(50); | 1317 | udelay(50); |
| 1318 | else if (AR_SREV_9100(ah)) | 1318 | else if (AR_SREV_9100(ah)) |
| 1319 | udelay(10000); | 1319 | mdelay(10); |
| 1320 | else | 1320 | else |
| 1321 | udelay(100); | 1321 | udelay(100); |
| 1322 | 1322 | ||
| @@ -1534,7 +1534,7 @@ EXPORT_SYMBOL(ath9k_hw_check_nav); | |||
| 1534 | bool ath9k_hw_check_alive(struct ath_hw *ah) | 1534 | bool ath9k_hw_check_alive(struct ath_hw *ah) |
| 1535 | { | 1535 | { |
| 1536 | int count = 50; | 1536 | int count = 50; |
| 1537 | u32 reg; | 1537 | u32 reg, last_val; |
| 1538 | 1538 | ||
| 1539 | if (AR_SREV_9300(ah)) | 1539 | if (AR_SREV_9300(ah)) |
| 1540 | return !ath9k_hw_detect_mac_hang(ah); | 1540 | return !ath9k_hw_detect_mac_hang(ah); |
| @@ -1542,9 +1542,13 @@ bool ath9k_hw_check_alive(struct ath_hw *ah) | |||
| 1542 | if (AR_SREV_9285_12_OR_LATER(ah)) | 1542 | if (AR_SREV_9285_12_OR_LATER(ah)) |
| 1543 | return true; | 1543 | return true; |
| 1544 | 1544 | ||
| 1545 | last_val = REG_READ(ah, AR_OBS_BUS_1); | ||
| 1545 | do { | 1546 | do { |
| 1546 | reg = REG_READ(ah, AR_OBS_BUS_1); | 1547 | reg = REG_READ(ah, AR_OBS_BUS_1); |
| 1548 | if (reg != last_val) | ||
| 1549 | return true; | ||
| 1547 | 1550 | ||
| 1551 | last_val = reg; | ||
| 1548 | if ((reg & 0x7E7FFFEF) == 0x00702400) | 1552 | if ((reg & 0x7E7FFFEF) == 0x00702400) |
| 1549 | continue; | 1553 | continue; |
| 1550 | 1554 | ||
| @@ -1556,6 +1560,8 @@ bool ath9k_hw_check_alive(struct ath_hw *ah) | |||
| 1556 | default: | 1560 | default: |
| 1557 | return true; | 1561 | return true; |
| 1558 | } | 1562 | } |
| 1563 | |||
| 1564 | udelay(1); | ||
| 1559 | } while (count-- > 0); | 1565 | } while (count-- > 0); |
| 1560 | 1566 | ||
| 1561 | return false; | 1567 | return false; |
| @@ -2051,9 +2057,8 @@ static bool ath9k_hw_set_power_awake(struct ath_hw *ah) | |||
| 2051 | 2057 | ||
| 2052 | REG_SET_BIT(ah, AR_RTC_FORCE_WAKE, | 2058 | REG_SET_BIT(ah, AR_RTC_FORCE_WAKE, |
| 2053 | AR_RTC_FORCE_WAKE_EN); | 2059 | AR_RTC_FORCE_WAKE_EN); |
| 2054 | |||
| 2055 | if (AR_SREV_9100(ah)) | 2060 | if (AR_SREV_9100(ah)) |
| 2056 | udelay(10000); | 2061 | mdelay(10); |
| 2057 | else | 2062 | else |
| 2058 | udelay(50); | 2063 | udelay(50); |
| 2059 | 2064 | ||
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index c36de303c8f3..1fc2e5a26b52 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c | |||
| @@ -57,6 +57,10 @@ static int ath9k_bt_ant_diversity; | |||
| 57 | module_param_named(bt_ant_diversity, ath9k_bt_ant_diversity, int, 0444); | 57 | module_param_named(bt_ant_diversity, ath9k_bt_ant_diversity, int, 0444); |
| 58 | MODULE_PARM_DESC(bt_ant_diversity, "Enable WLAN/BT RX antenna diversity"); | 58 | MODULE_PARM_DESC(bt_ant_diversity, "Enable WLAN/BT RX antenna diversity"); |
| 59 | 59 | ||
| 60 | static int ath9k_ps_enable; | ||
| 61 | module_param_named(ps_enable, ath9k_ps_enable, int, 0444); | ||
| 62 | MODULE_PARM_DESC(ps_enable, "Enable WLAN PowerSave"); | ||
| 63 | |||
| 60 | bool is_ath9k_unloaded; | 64 | bool is_ath9k_unloaded; |
| 61 | /* We use the hw_value as an index into our private channel structure */ | 65 | /* We use the hw_value as an index into our private channel structure */ |
| 62 | 66 | ||
| @@ -903,13 +907,15 @@ static void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) | |||
| 903 | hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | | 907 | hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | |
| 904 | IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | | 908 | IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | |
| 905 | IEEE80211_HW_SIGNAL_DBM | | 909 | IEEE80211_HW_SIGNAL_DBM | |
| 906 | IEEE80211_HW_SUPPORTS_PS | | ||
| 907 | IEEE80211_HW_PS_NULLFUNC_STACK | | 910 | IEEE80211_HW_PS_NULLFUNC_STACK | |
| 908 | IEEE80211_HW_SPECTRUM_MGMT | | 911 | IEEE80211_HW_SPECTRUM_MGMT | |
| 909 | IEEE80211_HW_REPORTS_TX_ACK_STATUS | | 912 | IEEE80211_HW_REPORTS_TX_ACK_STATUS | |
| 910 | IEEE80211_HW_SUPPORTS_RC_TABLE | | 913 | IEEE80211_HW_SUPPORTS_RC_TABLE | |
| 911 | IEEE80211_HW_SUPPORTS_HT_CCK_RATES; | 914 | IEEE80211_HW_SUPPORTS_HT_CCK_RATES; |
| 912 | 915 | ||
| 916 | if (ath9k_ps_enable) | ||
| 917 | hw->flags |= IEEE80211_HW_SUPPORTS_PS; | ||
| 918 | |||
| 913 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) { | 919 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) { |
| 914 | hw->flags |= IEEE80211_HW_AMPDU_AGGREGATION; | 920 | hw->flags |= IEEE80211_HW_AMPDU_AGGREGATION; |
| 915 | 921 | ||
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index a0ebdd000fc2..82e340d3ec60 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c | |||
| @@ -732,11 +732,18 @@ static struct ath_rxbuf *ath_get_next_rx_buf(struct ath_softc *sc, | |||
| 732 | return NULL; | 732 | return NULL; |
| 733 | 733 | ||
| 734 | /* | 734 | /* |
| 735 | * mark descriptor as zero-length and set the 'more' | 735 | * Re-check previous descriptor, in case it has been filled |
| 736 | * flag to ensure that both buffers get discarded | 736 | * in the mean time. |
| 737 | */ | 737 | */ |
| 738 | rs->rs_datalen = 0; | 738 | ret = ath9k_hw_rxprocdesc(ah, ds, rs); |
| 739 | rs->rs_more = true; | 739 | if (ret == -EINPROGRESS) { |
| 740 | /* | ||
| 741 | * mark descriptor as zero-length and set the 'more' | ||
| 742 | * flag to ensure that both buffers get discarded | ||
| 743 | */ | ||
| 744 | rs->rs_datalen = 0; | ||
| 745 | rs->rs_more = true; | ||
| 746 | } | ||
| 740 | } | 747 | } |
| 741 | 748 | ||
| 742 | list_del(&bf->list); | 749 | list_del(&bf->list); |
| @@ -985,32 +992,32 @@ static int ath9k_rx_skb_preprocess(struct ath_softc *sc, | |||
| 985 | struct ath_common *common = ath9k_hw_common(ah); | 992 | struct ath_common *common = ath9k_hw_common(ah); |
| 986 | struct ieee80211_hdr *hdr; | 993 | struct ieee80211_hdr *hdr; |
| 987 | bool discard_current = sc->rx.discard_next; | 994 | bool discard_current = sc->rx.discard_next; |
| 988 | int ret = 0; | ||
| 989 | 995 | ||
| 990 | /* | 996 | /* |
| 991 | * Discard corrupt descriptors which are marked in | 997 | * Discard corrupt descriptors which are marked in |
| 992 | * ath_get_next_rx_buf(). | 998 | * ath_get_next_rx_buf(). |
| 993 | */ | 999 | */ |
| 994 | sc->rx.discard_next = rx_stats->rs_more; | ||
| 995 | if (discard_current) | 1000 | if (discard_current) |
| 996 | return -EINVAL; | 1001 | goto corrupt; |
| 1002 | |||
| 1003 | sc->rx.discard_next = false; | ||
| 997 | 1004 | ||
| 998 | /* | 1005 | /* |
| 999 | * Discard zero-length packets. | 1006 | * Discard zero-length packets. |
| 1000 | */ | 1007 | */ |
| 1001 | if (!rx_stats->rs_datalen) { | 1008 | if (!rx_stats->rs_datalen) { |
| 1002 | RX_STAT_INC(rx_len_err); | 1009 | RX_STAT_INC(rx_len_err); |
| 1003 | return -EINVAL; | 1010 | goto corrupt; |
| 1004 | } | 1011 | } |
| 1005 | 1012 | ||
| 1006 | /* | 1013 | /* |
| 1007 | * rs_status follows rs_datalen so if rs_datalen is too large | 1014 | * rs_status follows rs_datalen so if rs_datalen is too large |
| 1008 | * we can take a hint that hardware corrupted it, so ignore | 1015 | * we can take a hint that hardware corrupted it, so ignore |
| 1009 | * those frames. | 1016 | * those frames. |
| 1010 | */ | 1017 | */ |
| 1011 | if (rx_stats->rs_datalen > (common->rx_bufsize - ah->caps.rx_status_len)) { | 1018 | if (rx_stats->rs_datalen > (common->rx_bufsize - ah->caps.rx_status_len)) { |
| 1012 | RX_STAT_INC(rx_len_err); | 1019 | RX_STAT_INC(rx_len_err); |
| 1013 | return -EINVAL; | 1020 | goto corrupt; |
| 1014 | } | 1021 | } |
| 1015 | 1022 | ||
| 1016 | /* Only use status info from the last fragment */ | 1023 | /* Only use status info from the last fragment */ |
| @@ -1024,10 +1031,8 @@ static int ath9k_rx_skb_preprocess(struct ath_softc *sc, | |||
| 1024 | * This is different from the other corrupt descriptor | 1031 | * This is different from the other corrupt descriptor |
| 1025 | * condition handled above. | 1032 | * condition handled above. |
| 1026 | */ | 1033 | */ |
| 1027 | if (rx_stats->rs_status & ATH9K_RXERR_CORRUPT_DESC) { | 1034 | if (rx_stats->rs_status & ATH9K_RXERR_CORRUPT_DESC) |
| 1028 | ret = -EINVAL; | 1035 | goto corrupt; |
| 1029 | goto exit; | ||
| 1030 | } | ||
| 1031 | 1036 | ||
| 1032 | hdr = (struct ieee80211_hdr *) (skb->data + ah->caps.rx_status_len); | 1037 | hdr = (struct ieee80211_hdr *) (skb->data + ah->caps.rx_status_len); |
| 1033 | 1038 | ||
| @@ -1043,18 +1048,15 @@ static int ath9k_rx_skb_preprocess(struct ath_softc *sc, | |||
| 1043 | if (ath_process_fft(sc, hdr, rx_stats, rx_status->mactime)) | 1048 | if (ath_process_fft(sc, hdr, rx_stats, rx_status->mactime)) |
| 1044 | RX_STAT_INC(rx_spectral); | 1049 | RX_STAT_INC(rx_spectral); |
| 1045 | 1050 | ||
| 1046 | ret = -EINVAL; | 1051 | return -EINVAL; |
| 1047 | goto exit; | ||
| 1048 | } | 1052 | } |
| 1049 | 1053 | ||
| 1050 | /* | 1054 | /* |
| 1051 | * everything but the rate is checked here, the rate check is done | 1055 | * everything but the rate is checked here, the rate check is done |
| 1052 | * separately to avoid doing two lookups for a rate for each frame. | 1056 | * separately to avoid doing two lookups for a rate for each frame. |
| 1053 | */ | 1057 | */ |
| 1054 | if (!ath9k_rx_accept(common, hdr, rx_status, rx_stats, decrypt_error)) { | 1058 | if (!ath9k_rx_accept(common, hdr, rx_status, rx_stats, decrypt_error)) |
| 1055 | ret = -EINVAL; | 1059 | return -EINVAL; |
| 1056 | goto exit; | ||
| 1057 | } | ||
| 1058 | 1060 | ||
| 1059 | if (ath_is_mybeacon(common, hdr)) { | 1061 | if (ath_is_mybeacon(common, hdr)) { |
| 1060 | RX_STAT_INC(rx_beacons); | 1062 | RX_STAT_INC(rx_beacons); |
| @@ -1064,15 +1066,11 @@ static int ath9k_rx_skb_preprocess(struct ath_softc *sc, | |||
| 1064 | /* | 1066 | /* |
| 1065 | * This shouldn't happen, but have a safety check anyway. | 1067 | * This shouldn't happen, but have a safety check anyway. |
| 1066 | */ | 1068 | */ |
| 1067 | if (WARN_ON(!ah->curchan)) { | 1069 | if (WARN_ON(!ah->curchan)) |
| 1068 | ret = -EINVAL; | 1070 | return -EINVAL; |
| 1069 | goto exit; | ||
| 1070 | } | ||
| 1071 | 1071 | ||
| 1072 | if (ath9k_process_rate(common, hw, rx_stats, rx_status)) { | 1072 | if (ath9k_process_rate(common, hw, rx_stats, rx_status)) |
| 1073 | ret =-EINVAL; | 1073 | return -EINVAL; |
| 1074 | goto exit; | ||
| 1075 | } | ||
| 1076 | 1074 | ||
| 1077 | ath9k_process_rssi(common, hw, rx_stats, rx_status); | 1075 | ath9k_process_rssi(common, hw, rx_stats, rx_status); |
| 1078 | 1076 | ||
| @@ -1087,9 +1085,11 @@ static int ath9k_rx_skb_preprocess(struct ath_softc *sc, | |||
| 1087 | sc->rx.num_pkts++; | 1085 | sc->rx.num_pkts++; |
| 1088 | #endif | 1086 | #endif |
| 1089 | 1087 | ||
| 1090 | exit: | 1088 | return 0; |
| 1091 | sc->rx.discard_next = false; | 1089 | |
| 1092 | return ret; | 1090 | corrupt: |
| 1091 | sc->rx.discard_next = rx_stats->rs_more; | ||
| 1092 | return -EINVAL; | ||
| 1093 | } | 1093 | } |
| 1094 | 1094 | ||
| 1095 | static void ath9k_rx_skb_postprocess(struct ath_common *common, | 1095 | static void ath9k_rx_skb_postprocess(struct ath_common *common, |
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 0a75e2f68c9d..f042a18c8495 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c | |||
| @@ -1444,14 +1444,16 @@ void ath_tx_aggr_sleep(struct ieee80211_sta *sta, struct ath_softc *sc, | |||
| 1444 | for (tidno = 0, tid = &an->tid[tidno]; | 1444 | for (tidno = 0, tid = &an->tid[tidno]; |
| 1445 | tidno < IEEE80211_NUM_TIDS; tidno++, tid++) { | 1445 | tidno < IEEE80211_NUM_TIDS; tidno++, tid++) { |
| 1446 | 1446 | ||
| 1447 | if (!tid->sched) | ||
| 1448 | continue; | ||
| 1449 | |||
| 1450 | ac = tid->ac; | 1447 | ac = tid->ac; |
| 1451 | txq = ac->txq; | 1448 | txq = ac->txq; |
| 1452 | 1449 | ||
| 1453 | ath_txq_lock(sc, txq); | 1450 | ath_txq_lock(sc, txq); |
| 1454 | 1451 | ||
| 1452 | if (!tid->sched) { | ||
| 1453 | ath_txq_unlock(sc, txq); | ||
| 1454 | continue; | ||
| 1455 | } | ||
| 1456 | |||
| 1455 | buffered = ath_tid_has_buffered(tid); | 1457 | buffered = ath_tid_has_buffered(tid); |
| 1456 | 1458 | ||
| 1457 | tid->sched = false; | 1459 | tid->sched = false; |
| @@ -2184,14 +2186,15 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
| 2184 | txq->stopped = true; | 2186 | txq->stopped = true; |
| 2185 | } | 2187 | } |
| 2186 | 2188 | ||
| 2189 | if (txctl->an) | ||
| 2190 | tid = ath_get_skb_tid(sc, txctl->an, skb); | ||
| 2191 | |||
| 2187 | if (info->flags & IEEE80211_TX_CTL_PS_RESPONSE) { | 2192 | if (info->flags & IEEE80211_TX_CTL_PS_RESPONSE) { |
| 2188 | ath_txq_unlock(sc, txq); | 2193 | ath_txq_unlock(sc, txq); |
| 2189 | txq = sc->tx.uapsdq; | 2194 | txq = sc->tx.uapsdq; |
| 2190 | ath_txq_lock(sc, txq); | 2195 | ath_txq_lock(sc, txq); |
| 2191 | } else if (txctl->an && | 2196 | } else if (txctl->an && |
| 2192 | ieee80211_is_data_present(hdr->frame_control)) { | 2197 | ieee80211_is_data_present(hdr->frame_control)) { |
| 2193 | tid = ath_get_skb_tid(sc, txctl->an, skb); | ||
| 2194 | |||
| 2195 | WARN_ON(tid->ac->txq != txctl->txq); | 2198 | WARN_ON(tid->ac->txq != txctl->txq); |
| 2196 | 2199 | ||
| 2197 | if (info->flags & IEEE80211_TX_CTL_CLEAR_PS_FILT) | 2200 | if (info->flags & IEEE80211_TX_CTL_CLEAR_PS_FILT) |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c index 3e991897d7ca..119ee6eaf1c3 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | |||
| @@ -457,7 +457,6 @@ struct brcmf_sdio { | |||
| 457 | 457 | ||
| 458 | u8 tx_hdrlen; /* sdio bus header length for tx packet */ | 458 | u8 tx_hdrlen; /* sdio bus header length for tx packet */ |
| 459 | bool txglom; /* host tx glomming enable flag */ | 459 | bool txglom; /* host tx glomming enable flag */ |
| 460 | struct sk_buff *txglom_sgpad; /* scatter-gather padding buffer */ | ||
| 461 | u16 head_align; /* buffer pointer alignment */ | 460 | u16 head_align; /* buffer pointer alignment */ |
| 462 | u16 sgentry_align; /* scatter-gather buffer alignment */ | 461 | u16 sgentry_align; /* scatter-gather buffer alignment */ |
| 463 | }; | 462 | }; |
| @@ -1944,9 +1943,8 @@ static int brcmf_sdio_txpkt_prep_sg(struct brcmf_sdio *bus, | |||
| 1944 | if (lastfrm && chain_pad) | 1943 | if (lastfrm && chain_pad) |
| 1945 | tail_pad += blksize - chain_pad; | 1944 | tail_pad += blksize - chain_pad; |
| 1946 | if (skb_tailroom(pkt) < tail_pad && pkt->len > blksize) { | 1945 | if (skb_tailroom(pkt) < tail_pad && pkt->len > blksize) { |
| 1947 | pkt_pad = bus->txglom_sgpad; | 1946 | pkt_pad = brcmu_pkt_buf_get_skb(tail_pad + tail_chop + |
| 1948 | if (pkt_pad == NULL) | 1947 | bus->head_align); |
| 1949 | brcmu_pkt_buf_get_skb(tail_pad + tail_chop); | ||
| 1950 | if (pkt_pad == NULL) | 1948 | if (pkt_pad == NULL) |
| 1951 | return -ENOMEM; | 1949 | return -ENOMEM; |
| 1952 | ret = brcmf_sdio_txpkt_hdalign(bus, pkt_pad); | 1950 | ret = brcmf_sdio_txpkt_hdalign(bus, pkt_pad); |
| @@ -1957,6 +1955,7 @@ static int brcmf_sdio_txpkt_prep_sg(struct brcmf_sdio *bus, | |||
| 1957 | tail_chop); | 1955 | tail_chop); |
| 1958 | *(u32 *)(pkt_pad->cb) = ALIGN_SKB_FLAG + tail_chop; | 1956 | *(u32 *)(pkt_pad->cb) = ALIGN_SKB_FLAG + tail_chop; |
| 1959 | skb_trim(pkt, pkt->len - tail_chop); | 1957 | skb_trim(pkt, pkt->len - tail_chop); |
| 1958 | skb_trim(pkt_pad, tail_pad + tail_chop); | ||
| 1960 | __skb_queue_after(pktq, pkt, pkt_pad); | 1959 | __skb_queue_after(pktq, pkt, pkt_pad); |
| 1961 | } else { | 1960 | } else { |
| 1962 | ntail = pkt->data_len + tail_pad - | 1961 | ntail = pkt->data_len + tail_pad - |
| @@ -2011,7 +2010,7 @@ brcmf_sdio_txpkt_prep(struct brcmf_sdio *bus, struct sk_buff_head *pktq, | |||
| 2011 | return ret; | 2010 | return ret; |
| 2012 | head_pad = (u16)ret; | 2011 | head_pad = (u16)ret; |
| 2013 | if (head_pad) | 2012 | if (head_pad) |
| 2014 | memset(pkt_next->data, 0, head_pad + bus->tx_hdrlen); | 2013 | memset(pkt_next->data + bus->tx_hdrlen, 0, head_pad); |
| 2015 | 2014 | ||
| 2016 | total_len += pkt_next->len; | 2015 | total_len += pkt_next->len; |
| 2017 | 2016 | ||
| @@ -3486,10 +3485,6 @@ static int brcmf_sdio_bus_preinit(struct device *dev) | |||
| 3486 | bus->txglom = false; | 3485 | bus->txglom = false; |
| 3487 | value = 1; | 3486 | value = 1; |
| 3488 | pad_size = bus->sdiodev->func[2]->cur_blksize << 1; | 3487 | pad_size = bus->sdiodev->func[2]->cur_blksize << 1; |
| 3489 | bus->txglom_sgpad = brcmu_pkt_buf_get_skb(pad_size); | ||
| 3490 | if (!bus->txglom_sgpad) | ||
| 3491 | brcmf_err("allocating txglom padding skb failed, reduced performance\n"); | ||
| 3492 | |||
| 3493 | err = brcmf_iovar_data_set(bus->sdiodev->dev, "bus:rxglom", | 3488 | err = brcmf_iovar_data_set(bus->sdiodev->dev, "bus:rxglom", |
| 3494 | &value, sizeof(u32)); | 3489 | &value, sizeof(u32)); |
| 3495 | if (err < 0) { | 3490 | if (err < 0) { |
| @@ -4053,7 +4048,6 @@ void brcmf_sdio_remove(struct brcmf_sdio *bus) | |||
| 4053 | brcmf_sdio_chip_detach(&bus->ci); | 4048 | brcmf_sdio_chip_detach(&bus->ci); |
| 4054 | } | 4049 | } |
| 4055 | 4050 | ||
| 4056 | brcmu_pkt_buf_free_skb(bus->txglom_sgpad); | ||
| 4057 | kfree(bus->rxbuf); | 4051 | kfree(bus->rxbuf); |
| 4058 | kfree(bus->hdrbuf); | 4052 | kfree(bus->hdrbuf); |
| 4059 | kfree(bus); | 4053 | kfree(bus); |
diff --git a/drivers/net/wireless/hostap/hostap_ap.c b/drivers/net/wireless/hostap/hostap_ap.c index d36e252d2ccb..596525528f50 100644 --- a/drivers/net/wireless/hostap/hostap_ap.c +++ b/drivers/net/wireless/hostap/hostap_ap.c | |||
| @@ -147,7 +147,7 @@ static void ap_free_sta(struct ap_data *ap, struct sta_info *sta) | |||
| 147 | 147 | ||
| 148 | if (!sta->ap && sta->u.sta.challenge) | 148 | if (!sta->ap && sta->u.sta.challenge) |
| 149 | kfree(sta->u.sta.challenge); | 149 | kfree(sta->u.sta.challenge); |
| 150 | del_timer(&sta->timer); | 150 | del_timer_sync(&sta->timer); |
| 151 | #endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */ | 151 | #endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */ |
| 152 | 152 | ||
| 153 | kfree(sta); | 153 | kfree(sta); |
diff --git a/drivers/net/wireless/hostap/hostap_proc.c b/drivers/net/wireless/hostap/hostap_proc.c index aa7ad3a7a69b..4e5c0f8c9496 100644 --- a/drivers/net/wireless/hostap/hostap_proc.c +++ b/drivers/net/wireless/hostap/hostap_proc.c | |||
| @@ -496,7 +496,7 @@ void hostap_init_proc(local_info_t *local) | |||
| 496 | 496 | ||
| 497 | void hostap_remove_proc(local_info_t *local) | 497 | void hostap_remove_proc(local_info_t *local) |
| 498 | { | 498 | { |
| 499 | remove_proc_subtree(local->ddev->name, hostap_proc); | 499 | proc_remove(local->proc); |
| 500 | } | 500 | } |
| 501 | 501 | ||
| 502 | 502 | ||
diff --git a/drivers/net/wireless/iwlwifi/dvm/mac80211.c b/drivers/net/wireless/iwlwifi/dvm/mac80211.c index c24d1d3d55f6..73086c1629ca 100644 --- a/drivers/net/wireless/iwlwifi/dvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/dvm/mac80211.c | |||
| @@ -696,6 +696,24 @@ static int iwlagn_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
| 696 | return ret; | 696 | return ret; |
| 697 | } | 697 | } |
| 698 | 698 | ||
| 699 | static inline bool iwl_enable_rx_ampdu(const struct iwl_cfg *cfg) | ||
| 700 | { | ||
| 701 | if (iwlwifi_mod_params.disable_11n & IWL_DISABLE_HT_RXAGG) | ||
| 702 | return false; | ||
| 703 | return true; | ||
| 704 | } | ||
| 705 | |||
| 706 | static inline bool iwl_enable_tx_ampdu(const struct iwl_cfg *cfg) | ||
| 707 | { | ||
| 708 | if (iwlwifi_mod_params.disable_11n & IWL_DISABLE_HT_TXAGG) | ||
| 709 | return false; | ||
| 710 | if (iwlwifi_mod_params.disable_11n & IWL_ENABLE_HT_TXAGG) | ||
| 711 | return true; | ||
| 712 | |||
| 713 | /* disabled by default */ | ||
| 714 | return false; | ||
| 715 | } | ||
| 716 | |||
| 699 | static int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw, | 717 | static int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw, |
| 700 | struct ieee80211_vif *vif, | 718 | struct ieee80211_vif *vif, |
| 701 | enum ieee80211_ampdu_mlme_action action, | 719 | enum ieee80211_ampdu_mlme_action action, |
| @@ -717,7 +735,7 @@ static int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw, | |||
| 717 | 735 | ||
| 718 | switch (action) { | 736 | switch (action) { |
| 719 | case IEEE80211_AMPDU_RX_START: | 737 | case IEEE80211_AMPDU_RX_START: |
| 720 | if (iwlwifi_mod_params.disable_11n & IWL_DISABLE_HT_RXAGG) | 738 | if (!iwl_enable_rx_ampdu(priv->cfg)) |
| 721 | break; | 739 | break; |
| 722 | IWL_DEBUG_HT(priv, "start Rx\n"); | 740 | IWL_DEBUG_HT(priv, "start Rx\n"); |
| 723 | ret = iwl_sta_rx_agg_start(priv, sta, tid, *ssn); | 741 | ret = iwl_sta_rx_agg_start(priv, sta, tid, *ssn); |
| @@ -729,7 +747,7 @@ static int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw, | |||
| 729 | case IEEE80211_AMPDU_TX_START: | 747 | case IEEE80211_AMPDU_TX_START: |
| 730 | if (!priv->trans->ops->txq_enable) | 748 | if (!priv->trans->ops->txq_enable) |
| 731 | break; | 749 | break; |
| 732 | if (iwlwifi_mod_params.disable_11n & IWL_DISABLE_HT_TXAGG) | 750 | if (!iwl_enable_tx_ampdu(priv->cfg)) |
| 733 | break; | 751 | break; |
| 734 | IWL_DEBUG_HT(priv, "start Tx\n"); | 752 | IWL_DEBUG_HT(priv, "start Tx\n"); |
| 735 | ret = iwlagn_tx_agg_start(priv, vif, sta, tid, ssn); | 753 | ret = iwlagn_tx_agg_start(priv, vif, sta, tid, ssn); |
diff --git a/drivers/net/wireless/iwlwifi/dvm/sta.c b/drivers/net/wireless/iwlwifi/dvm/sta.c index c0d070c5df5e..9cdd91cdf661 100644 --- a/drivers/net/wireless/iwlwifi/dvm/sta.c +++ b/drivers/net/wireless/iwlwifi/dvm/sta.c | |||
| @@ -590,6 +590,7 @@ void iwl_deactivate_station(struct iwl_priv *priv, const u8 sta_id, | |||
| 590 | sizeof(priv->tid_data[sta_id][tid])); | 590 | sizeof(priv->tid_data[sta_id][tid])); |
| 591 | 591 | ||
| 592 | priv->stations[sta_id].used &= ~IWL_STA_DRIVER_ACTIVE; | 592 | priv->stations[sta_id].used &= ~IWL_STA_DRIVER_ACTIVE; |
| 593 | priv->stations[sta_id].used &= ~IWL_STA_UCODE_INPROGRESS; | ||
| 593 | 594 | ||
| 594 | priv->num_stations--; | 595 | priv->num_stations--; |
| 595 | 596 | ||
diff --git a/drivers/net/wireless/iwlwifi/dvm/tx.c b/drivers/net/wireless/iwlwifi/dvm/tx.c index a6839dfcb82d..398dd096674c 100644 --- a/drivers/net/wireless/iwlwifi/dvm/tx.c +++ b/drivers/net/wireless/iwlwifi/dvm/tx.c | |||
| @@ -1291,8 +1291,6 @@ int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv, | |||
| 1291 | struct iwl_compressed_ba_resp *ba_resp = (void *)pkt->data; | 1291 | struct iwl_compressed_ba_resp *ba_resp = (void *)pkt->data; |
| 1292 | struct iwl_ht_agg *agg; | 1292 | struct iwl_ht_agg *agg; |
| 1293 | struct sk_buff_head reclaimed_skbs; | 1293 | struct sk_buff_head reclaimed_skbs; |
| 1294 | struct ieee80211_tx_info *info; | ||
| 1295 | struct ieee80211_hdr *hdr; | ||
| 1296 | struct sk_buff *skb; | 1294 | struct sk_buff *skb; |
| 1297 | int sta_id; | 1295 | int sta_id; |
| 1298 | int tid; | 1296 | int tid; |
| @@ -1379,22 +1377,28 @@ int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv, | |||
| 1379 | freed = 0; | 1377 | freed = 0; |
| 1380 | 1378 | ||
| 1381 | skb_queue_walk(&reclaimed_skbs, skb) { | 1379 | skb_queue_walk(&reclaimed_skbs, skb) { |
| 1382 | hdr = (struct ieee80211_hdr *)skb->data; | 1380 | struct ieee80211_hdr *hdr = (void *)skb->data; |
| 1381 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
| 1383 | 1382 | ||
| 1384 | if (ieee80211_is_data_qos(hdr->frame_control)) | 1383 | if (ieee80211_is_data_qos(hdr->frame_control)) |
| 1385 | freed++; | 1384 | freed++; |
| 1386 | else | 1385 | else |
| 1387 | WARN_ON_ONCE(1); | 1386 | WARN_ON_ONCE(1); |
| 1388 | 1387 | ||
| 1389 | info = IEEE80211_SKB_CB(skb); | ||
| 1390 | iwl_trans_free_tx_cmd(priv->trans, info->driver_data[1]); | 1388 | iwl_trans_free_tx_cmd(priv->trans, info->driver_data[1]); |
| 1391 | 1389 | ||
| 1390 | memset(&info->status, 0, sizeof(info->status)); | ||
| 1391 | /* Packet was transmitted successfully, failures come as single | ||
| 1392 | * frames because before failing a frame the firmware transmits | ||
| 1393 | * it without aggregation at least once. | ||
| 1394 | */ | ||
| 1395 | info->flags |= IEEE80211_TX_STAT_ACK; | ||
| 1396 | |||
| 1392 | if (freed == 1) { | 1397 | if (freed == 1) { |
| 1393 | /* this is the first skb we deliver in this batch */ | 1398 | /* this is the first skb we deliver in this batch */ |
| 1394 | /* put the rate scaling data there */ | 1399 | /* put the rate scaling data there */ |
| 1395 | info = IEEE80211_SKB_CB(skb); | 1400 | info = IEEE80211_SKB_CB(skb); |
| 1396 | memset(&info->status, 0, sizeof(info->status)); | 1401 | memset(&info->status, 0, sizeof(info->status)); |
| 1397 | info->flags |= IEEE80211_TX_STAT_ACK; | ||
| 1398 | info->flags |= IEEE80211_TX_STAT_AMPDU; | 1402 | info->flags |= IEEE80211_TX_STAT_AMPDU; |
| 1399 | info->status.ampdu_ack_len = ba_resp->txed_2_done; | 1403 | info->status.ampdu_ack_len = ba_resp->txed_2_done; |
| 1400 | info->status.ampdu_len = ba_resp->txed; | 1404 | info->status.ampdu_len = ba_resp->txed; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.c b/drivers/net/wireless/iwlwifi/iwl-drv.c index c3728163be46..75103554cd63 100644 --- a/drivers/net/wireless/iwlwifi/iwl-drv.c +++ b/drivers/net/wireless/iwlwifi/iwl-drv.c | |||
| @@ -1286,7 +1286,7 @@ module_param_named(swcrypto, iwlwifi_mod_params.sw_crypto, int, S_IRUGO); | |||
| 1286 | MODULE_PARM_DESC(swcrypto, "using crypto in software (default 0 [hardware])"); | 1286 | MODULE_PARM_DESC(swcrypto, "using crypto in software (default 0 [hardware])"); |
| 1287 | module_param_named(11n_disable, iwlwifi_mod_params.disable_11n, uint, S_IRUGO); | 1287 | module_param_named(11n_disable, iwlwifi_mod_params.disable_11n, uint, S_IRUGO); |
| 1288 | MODULE_PARM_DESC(11n_disable, | 1288 | MODULE_PARM_DESC(11n_disable, |
| 1289 | "disable 11n functionality, bitmap: 1: full, 2: agg TX, 4: agg RX"); | 1289 | "disable 11n functionality, bitmap: 1: full, 2: disable agg TX, 4: disable agg RX, 8 enable agg TX"); |
| 1290 | module_param_named(amsdu_size_8K, iwlwifi_mod_params.amsdu_size_8K, | 1290 | module_param_named(amsdu_size_8K, iwlwifi_mod_params.amsdu_size_8K, |
| 1291 | int, S_IRUGO); | 1291 | int, S_IRUGO); |
| 1292 | MODULE_PARM_DESC(amsdu_size_8K, "enable 8K amsdu size (default 0)"); | 1292 | MODULE_PARM_DESC(amsdu_size_8K, "enable 8K amsdu size (default 0)"); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-modparams.h b/drivers/net/wireless/iwlwifi/iwl-modparams.h index 0a84ade7edac..b29075c3da8e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-modparams.h +++ b/drivers/net/wireless/iwlwifi/iwl-modparams.h | |||
| @@ -79,9 +79,12 @@ enum iwl_power_level { | |||
| 79 | IWL_POWER_NUM | 79 | IWL_POWER_NUM |
| 80 | }; | 80 | }; |
| 81 | 81 | ||
| 82 | #define IWL_DISABLE_HT_ALL BIT(0) | 82 | enum iwl_disable_11n { |
| 83 | #define IWL_DISABLE_HT_TXAGG BIT(1) | 83 | IWL_DISABLE_HT_ALL = BIT(0), |
| 84 | #define IWL_DISABLE_HT_RXAGG BIT(2) | 84 | IWL_DISABLE_HT_TXAGG = BIT(1), |
| 85 | IWL_DISABLE_HT_RXAGG = BIT(2), | ||
| 86 | IWL_ENABLE_HT_TXAGG = BIT(3), | ||
| 87 | }; | ||
| 85 | 88 | ||
| 86 | /** | 89 | /** |
| 87 | * struct iwl_mod_params | 90 | * struct iwl_mod_params |
| @@ -90,7 +93,7 @@ enum iwl_power_level { | |||
| 90 | * | 93 | * |
| 91 | * @sw_crypto: using hardware encryption, default = 0 | 94 | * @sw_crypto: using hardware encryption, default = 0 |
| 92 | * @disable_11n: disable 11n capabilities, default = 0, | 95 | * @disable_11n: disable 11n capabilities, default = 0, |
| 93 | * use IWL_DISABLE_HT_* constants | 96 | * use IWL_[DIS,EN]ABLE_HT_* constants |
| 94 | * @amsdu_size_8K: enable 8K amsdu size, default = 0 | 97 | * @amsdu_size_8K: enable 8K amsdu size, default = 0 |
| 95 | * @restart_fw: restart firmware, default = 1 | 98 | * @restart_fw: restart firmware, default = 1 |
| 96 | * @wd_disable: enable stuck queue check, default = 0 | 99 | * @wd_disable: enable stuck queue check, default = 0 |
diff --git a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c index f06f4cbe1317..725e954d8475 100644 --- a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c +++ b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c | |||
| @@ -182,6 +182,11 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg, | |||
| 182 | 182 | ||
| 183 | for (ch_idx = 0; ch_idx < IWL_NUM_CHANNELS; ch_idx++) { | 183 | for (ch_idx = 0; ch_idx < IWL_NUM_CHANNELS; ch_idx++) { |
| 184 | ch_flags = __le16_to_cpup(nvm_ch_flags + ch_idx); | 184 | ch_flags = __le16_to_cpup(nvm_ch_flags + ch_idx); |
| 185 | |||
| 186 | if (ch_idx >= NUM_2GHZ_CHANNELS && | ||
| 187 | !data->sku_cap_band_52GHz_enable) | ||
| 188 | ch_flags &= ~NVM_CHANNEL_VALID; | ||
| 189 | |||
| 185 | if (!(ch_flags & NVM_CHANNEL_VALID)) { | 190 | if (!(ch_flags & NVM_CHANNEL_VALID)) { |
| 186 | IWL_DEBUG_EEPROM(dev, | 191 | IWL_DEBUG_EEPROM(dev, |
| 187 | "Ch. %d Flags %x [%sGHz] - No traffic\n", | 192 | "Ch. %d Flags %x [%sGHz] - No traffic\n", |
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h index 73cbba7424f2..9426905de6b2 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h | |||
| @@ -504,6 +504,7 @@ struct iwl_scan_offload_profile { | |||
| 504 | * @match_notify: clients waiting for match found notification | 504 | * @match_notify: clients waiting for match found notification |
| 505 | * @pass_match: clients waiting for the results | 505 | * @pass_match: clients waiting for the results |
| 506 | * @active_clients: active clients bitmap - enum scan_framework_client | 506 | * @active_clients: active clients bitmap - enum scan_framework_client |
| 507 | * @any_beacon_notify: clients waiting for match notification without match | ||
| 507 | */ | 508 | */ |
| 508 | struct iwl_scan_offload_profile_cfg { | 509 | struct iwl_scan_offload_profile_cfg { |
| 509 | struct iwl_scan_offload_profile profiles[IWL_SCAN_MAX_PROFILES]; | 510 | struct iwl_scan_offload_profile profiles[IWL_SCAN_MAX_PROFILES]; |
| @@ -512,7 +513,8 @@ struct iwl_scan_offload_profile_cfg { | |||
| 512 | u8 match_notify; | 513 | u8 match_notify; |
| 513 | u8 pass_match; | 514 | u8 pass_match; |
| 514 | u8 active_clients; | 515 | u8 active_clients; |
| 515 | u8 reserved[3]; | 516 | u8 any_beacon_notify; |
| 517 | u8 reserved[2]; | ||
| 516 | } __packed; | 518 | } __packed; |
| 517 | 519 | ||
| 518 | /** | 520 | /** |
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index c49b5073c251..c35b8661b395 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c | |||
| @@ -246,7 +246,7 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm) | |||
| 246 | else | 246 | else |
| 247 | hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; | 247 | hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; |
| 248 | 248 | ||
| 249 | if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_SCHED_SCAN) { | 249 | if (0 && mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_SCHED_SCAN) { |
| 250 | hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN; | 250 | hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN; |
| 251 | hw->wiphy->max_sched_scan_ssids = PROBE_OPTION_MAX; | 251 | hw->wiphy->max_sched_scan_ssids = PROBE_OPTION_MAX; |
| 252 | hw->wiphy->max_match_sets = IWL_SCAN_MAX_PROFILES; | 252 | hw->wiphy->max_match_sets = IWL_SCAN_MAX_PROFILES; |
| @@ -328,6 +328,24 @@ static void iwl_mvm_mac_tx(struct ieee80211_hw *hw, | |||
| 328 | ieee80211_free_txskb(hw, skb); | 328 | ieee80211_free_txskb(hw, skb); |
| 329 | } | 329 | } |
| 330 | 330 | ||
| 331 | static inline bool iwl_enable_rx_ampdu(const struct iwl_cfg *cfg) | ||
| 332 | { | ||
| 333 | if (iwlwifi_mod_params.disable_11n & IWL_DISABLE_HT_RXAGG) | ||
| 334 | return false; | ||
| 335 | return true; | ||
| 336 | } | ||
| 337 | |||
| 338 | static inline bool iwl_enable_tx_ampdu(const struct iwl_cfg *cfg) | ||
| 339 | { | ||
| 340 | if (iwlwifi_mod_params.disable_11n & IWL_DISABLE_HT_TXAGG) | ||
| 341 | return false; | ||
| 342 | if (iwlwifi_mod_params.disable_11n & IWL_ENABLE_HT_TXAGG) | ||
| 343 | return true; | ||
| 344 | |||
| 345 | /* enabled by default */ | ||
| 346 | return true; | ||
| 347 | } | ||
| 348 | |||
| 331 | static int iwl_mvm_mac_ampdu_action(struct ieee80211_hw *hw, | 349 | static int iwl_mvm_mac_ampdu_action(struct ieee80211_hw *hw, |
| 332 | struct ieee80211_vif *vif, | 350 | struct ieee80211_vif *vif, |
| 333 | enum ieee80211_ampdu_mlme_action action, | 351 | enum ieee80211_ampdu_mlme_action action, |
| @@ -347,7 +365,7 @@ static int iwl_mvm_mac_ampdu_action(struct ieee80211_hw *hw, | |||
| 347 | 365 | ||
| 348 | switch (action) { | 366 | switch (action) { |
| 349 | case IEEE80211_AMPDU_RX_START: | 367 | case IEEE80211_AMPDU_RX_START: |
| 350 | if (iwlwifi_mod_params.disable_11n & IWL_DISABLE_HT_RXAGG) { | 368 | if (!iwl_enable_rx_ampdu(mvm->cfg)) { |
| 351 | ret = -EINVAL; | 369 | ret = -EINVAL; |
| 352 | break; | 370 | break; |
| 353 | } | 371 | } |
| @@ -357,7 +375,7 @@ static int iwl_mvm_mac_ampdu_action(struct ieee80211_hw *hw, | |||
| 357 | ret = iwl_mvm_sta_rx_agg(mvm, sta, tid, 0, false); | 375 | ret = iwl_mvm_sta_rx_agg(mvm, sta, tid, 0, false); |
| 358 | break; | 376 | break; |
| 359 | case IEEE80211_AMPDU_TX_START: | 377 | case IEEE80211_AMPDU_TX_START: |
| 360 | if (iwlwifi_mod_params.disable_11n & IWL_DISABLE_HT_TXAGG) { | 378 | if (!iwl_enable_tx_ampdu(mvm->cfg)) { |
| 361 | ret = -EINVAL; | 379 | ret = -EINVAL; |
| 362 | break; | 380 | break; |
| 363 | } | 381 | } |
diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h index e4ead86f06d6..2b0ba1fc3c82 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h | |||
| @@ -152,7 +152,7 @@ enum iwl_power_scheme { | |||
| 152 | IWL_POWER_SCHEME_LP | 152 | IWL_POWER_SCHEME_LP |
| 153 | }; | 153 | }; |
| 154 | 154 | ||
| 155 | #define IWL_CONN_MAX_LISTEN_INTERVAL 70 | 155 | #define IWL_CONN_MAX_LISTEN_INTERVAL 10 |
| 156 | #define IWL_UAPSD_AC_INFO (IEEE80211_WMM_IE_STA_QOSINFO_AC_VO |\ | 156 | #define IWL_UAPSD_AC_INFO (IEEE80211_WMM_IE_STA_QOSINFO_AC_VO |\ |
| 157 | IEEE80211_WMM_IE_STA_QOSINFO_AC_VI |\ | 157 | IEEE80211_WMM_IE_STA_QOSINFO_AC_VI |\ |
| 158 | IEEE80211_WMM_IE_STA_QOSINFO_AC_BK |\ | 158 | IEEE80211_WMM_IE_STA_QOSINFO_AC_BK |\ |
diff --git a/drivers/net/wireless/iwlwifi/mvm/scan.c b/drivers/net/wireless/iwlwifi/mvm/scan.c index 0e0007960612..742afc429c94 100644 --- a/drivers/net/wireless/iwlwifi/mvm/scan.c +++ b/drivers/net/wireless/iwlwifi/mvm/scan.c | |||
| @@ -344,7 +344,8 @@ int iwl_mvm_scan_request(struct iwl_mvm *mvm, | |||
| 344 | 344 | ||
| 345 | iwl_mvm_scan_fill_ssids(cmd, req, basic_ssid ? 1 : 0); | 345 | iwl_mvm_scan_fill_ssids(cmd, req, basic_ssid ? 1 : 0); |
| 346 | 346 | ||
| 347 | cmd->tx_cmd.tx_flags = cpu_to_le32(TX_CMD_FLG_SEQ_CTL); | 347 | cmd->tx_cmd.tx_flags = cpu_to_le32(TX_CMD_FLG_SEQ_CTL | |
| 348 | TX_CMD_FLG_BT_DIS); | ||
| 348 | cmd->tx_cmd.sta_id = mvm->aux_sta.sta_id; | 349 | cmd->tx_cmd.sta_id = mvm->aux_sta.sta_id; |
| 349 | cmd->tx_cmd.life_time = cpu_to_le32(TX_CMD_LIFE_TIME_INFINITE); | 350 | cmd->tx_cmd.life_time = cpu_to_le32(TX_CMD_LIFE_TIME_INFINITE); |
| 350 | cmd->tx_cmd.rate_n_flags = | 351 | cmd->tx_cmd.rate_n_flags = |
| @@ -807,6 +808,8 @@ int iwl_mvm_config_sched_scan_profiles(struct iwl_mvm *mvm, | |||
| 807 | profile_cfg->active_clients = SCAN_CLIENT_SCHED_SCAN; | 808 | profile_cfg->active_clients = SCAN_CLIENT_SCHED_SCAN; |
| 808 | profile_cfg->pass_match = SCAN_CLIENT_SCHED_SCAN; | 809 | profile_cfg->pass_match = SCAN_CLIENT_SCHED_SCAN; |
| 809 | profile_cfg->match_notify = SCAN_CLIENT_SCHED_SCAN; | 810 | profile_cfg->match_notify = SCAN_CLIENT_SCHED_SCAN; |
| 811 | if (!req->n_match_sets || !req->match_sets[0].ssid.ssid_len) | ||
| 812 | profile_cfg->any_beacon_notify = SCAN_CLIENT_SCHED_SCAN; | ||
| 810 | 813 | ||
| 811 | for (i = 0; i < req->n_match_sets; i++) { | 814 | for (i = 0; i < req->n_match_sets; i++) { |
| 812 | profile = &profile_cfg->profiles[i]; | 815 | profile = &profile_cfg->profiles[i]; |
diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.c b/drivers/net/wireless/iwlwifi/mvm/sta.c index ec1812133235..3397f59cd4e4 100644 --- a/drivers/net/wireless/iwlwifi/mvm/sta.c +++ b/drivers/net/wireless/iwlwifi/mvm/sta.c | |||
| @@ -652,7 +652,7 @@ int iwl_mvm_send_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | |||
| 652 | { | 652 | { |
| 653 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); | 653 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); |
| 654 | static const u8 _baddr[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; | 654 | static const u8 _baddr[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; |
| 655 | static const u8 *baddr = _baddr; | 655 | const u8 *baddr = _baddr; |
| 656 | 656 | ||
| 657 | lockdep_assert_held(&mvm->mutex); | 657 | lockdep_assert_held(&mvm->mutex); |
| 658 | 658 | ||
diff --git a/drivers/net/wireless/iwlwifi/mvm/tx.c b/drivers/net/wireless/iwlwifi/mvm/tx.c index 90378c217bc7..76ee486039d7 100644 --- a/drivers/net/wireless/iwlwifi/mvm/tx.c +++ b/drivers/net/wireless/iwlwifi/mvm/tx.c | |||
| @@ -659,8 +659,14 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm, | |||
| 659 | rcu_read_lock(); | 659 | rcu_read_lock(); |
| 660 | 660 | ||
| 661 | sta = rcu_dereference(mvm->fw_id_to_mac_id[sta_id]); | 661 | sta = rcu_dereference(mvm->fw_id_to_mac_id[sta_id]); |
| 662 | /* | ||
| 663 | * sta can't be NULL otherwise it'd mean that the sta has been freed in | ||
| 664 | * the firmware while we still have packets for it in the Tx queues. | ||
| 665 | */ | ||
| 666 | if (WARN_ON_ONCE(!sta)) | ||
| 667 | goto out; | ||
| 662 | 668 | ||
| 663 | if (!IS_ERR_OR_NULL(sta)) { | 669 | if (!IS_ERR(sta)) { |
| 664 | mvmsta = iwl_mvm_sta_from_mac80211(sta); | 670 | mvmsta = iwl_mvm_sta_from_mac80211(sta); |
| 665 | 671 | ||
| 666 | if (tid != IWL_TID_NON_QOS) { | 672 | if (tid != IWL_TID_NON_QOS) { |
| @@ -675,7 +681,6 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm, | |||
| 675 | spin_unlock_bh(&mvmsta->lock); | 681 | spin_unlock_bh(&mvmsta->lock); |
| 676 | } | 682 | } |
| 677 | } else { | 683 | } else { |
| 678 | sta = NULL; | ||
| 679 | mvmsta = NULL; | 684 | mvmsta = NULL; |
| 680 | } | 685 | } |
| 681 | 686 | ||
| @@ -683,42 +688,38 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm, | |||
| 683 | * If the txq is not an AMPDU queue, there is no chance we freed | 688 | * If the txq is not an AMPDU queue, there is no chance we freed |
| 684 | * several skbs. Check that out... | 689 | * several skbs. Check that out... |
| 685 | */ | 690 | */ |
| 686 | if (txq_id < mvm->first_agg_queue && !WARN_ON(skb_freed > 1) && | 691 | if (txq_id >= mvm->first_agg_queue) |
| 687 | atomic_sub_and_test(skb_freed, &mvm->pending_frames[sta_id])) { | 692 | goto out; |
| 688 | if (mvmsta) { | 693 | |
| 689 | /* | 694 | /* We can't free more than one frame at once on a shared queue */ |
| 690 | * If there are no pending frames for this STA, notify | 695 | WARN_ON(skb_freed > 1); |
| 691 | * mac80211 that this station can go to sleep in its | 696 | |
| 692 | * STA table. | 697 | /* If we have still frames from this STA nothing to do here */ |
| 693 | */ | 698 | if (!atomic_sub_and_test(skb_freed, &mvm->pending_frames[sta_id])) |
| 694 | if (mvmsta->vif->type == NL80211_IFTYPE_AP) | 699 | goto out; |
| 695 | ieee80211_sta_block_awake(mvm->hw, sta, false); | 700 | |
| 696 | /* | 701 | if (mvmsta && mvmsta->vif->type == NL80211_IFTYPE_AP) { |
| 697 | * We might very well have taken mvmsta pointer while | 702 | /* |
| 698 | * the station was being removed. The remove flow might | 703 | * If there are no pending frames for this STA, notify |
| 699 | * have seen a pending_frame (because we didn't take | 704 | * mac80211 that this station can go to sleep in its |
| 700 | * the lock) even if now the queues are drained. So make | 705 | * STA table. |
| 701 | * really sure now that this the station is not being | 706 | * If mvmsta is not NULL, sta is valid. |
| 702 | * removed. If it is, run the drain worker to remove it. | 707 | */ |
| 703 | */ | 708 | ieee80211_sta_block_awake(mvm->hw, sta, false); |
| 704 | spin_lock_bh(&mvmsta->lock); | ||
| 705 | sta = rcu_dereference(mvm->fw_id_to_mac_id[sta_id]); | ||
| 706 | if (!sta || PTR_ERR(sta) == -EBUSY) { | ||
| 707 | /* | ||
| 708 | * Station disappeared in the meantime: | ||
| 709 | * so we are draining. | ||
| 710 | */ | ||
| 711 | set_bit(sta_id, mvm->sta_drained); | ||
| 712 | schedule_work(&mvm->sta_drained_wk); | ||
| 713 | } | ||
| 714 | spin_unlock_bh(&mvmsta->lock); | ||
| 715 | } else if (!mvmsta && PTR_ERR(sta) == -EBUSY) { | ||
| 716 | /* Tx response without STA, so we are draining */ | ||
| 717 | set_bit(sta_id, mvm->sta_drained); | ||
| 718 | schedule_work(&mvm->sta_drained_wk); | ||
| 719 | } | ||
| 720 | } | 709 | } |
| 721 | 710 | ||
| 711 | if (PTR_ERR(sta) == -EBUSY || PTR_ERR(sta) == -ENOENT) { | ||
| 712 | /* | ||
| 713 | * We are draining and this was the last packet - pre_rcu_remove | ||
| 714 | * has been called already. We might be after the | ||
| 715 | * synchronize_net already. | ||
| 716 | * Don't rely on iwl_mvm_rm_sta to see the empty Tx queues. | ||
| 717 | */ | ||
| 718 | set_bit(sta_id, mvm->sta_drained); | ||
| 719 | schedule_work(&mvm->sta_drained_wk); | ||
| 720 | } | ||
| 721 | |||
| 722 | out: | ||
| 722 | rcu_read_unlock(); | 723 | rcu_read_unlock(); |
| 723 | } | 724 | } |
| 724 | 725 | ||
| @@ -821,16 +822,12 @@ int iwl_mvm_rx_ba_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb, | |||
| 821 | struct iwl_mvm_ba_notif *ba_notif = (void *)pkt->data; | 822 | struct iwl_mvm_ba_notif *ba_notif = (void *)pkt->data; |
| 822 | struct sk_buff_head reclaimed_skbs; | 823 | struct sk_buff_head reclaimed_skbs; |
| 823 | struct iwl_mvm_tid_data *tid_data; | 824 | struct iwl_mvm_tid_data *tid_data; |
| 824 | struct ieee80211_tx_info *info; | ||
| 825 | struct ieee80211_sta *sta; | 825 | struct ieee80211_sta *sta; |
| 826 | struct iwl_mvm_sta *mvmsta; | 826 | struct iwl_mvm_sta *mvmsta; |
| 827 | struct ieee80211_hdr *hdr; | ||
| 828 | struct sk_buff *skb; | 827 | struct sk_buff *skb; |
| 829 | int sta_id, tid, freed; | 828 | int sta_id, tid, freed; |
| 830 | |||
| 831 | /* "flow" corresponds to Tx queue */ | 829 | /* "flow" corresponds to Tx queue */ |
| 832 | u16 scd_flow = le16_to_cpu(ba_notif->scd_flow); | 830 | u16 scd_flow = le16_to_cpu(ba_notif->scd_flow); |
| 833 | |||
| 834 | /* "ssn" is start of block-ack Tx window, corresponds to index | 831 | /* "ssn" is start of block-ack Tx window, corresponds to index |
| 835 | * (in Tx queue's circular buffer) of first TFD/frame in window */ | 832 | * (in Tx queue's circular buffer) of first TFD/frame in window */ |
| 836 | u16 ba_resp_scd_ssn = le16_to_cpu(ba_notif->scd_ssn); | 833 | u16 ba_resp_scd_ssn = le16_to_cpu(ba_notif->scd_ssn); |
| @@ -887,22 +884,26 @@ int iwl_mvm_rx_ba_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb, | |||
| 887 | freed = 0; | 884 | freed = 0; |
| 888 | 885 | ||
| 889 | skb_queue_walk(&reclaimed_skbs, skb) { | 886 | skb_queue_walk(&reclaimed_skbs, skb) { |
| 890 | hdr = (struct ieee80211_hdr *)skb->data; | 887 | struct ieee80211_hdr *hdr = (void *)skb->data; |
| 888 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
| 891 | 889 | ||
| 892 | if (ieee80211_is_data_qos(hdr->frame_control)) | 890 | if (ieee80211_is_data_qos(hdr->frame_control)) |
| 893 | freed++; | 891 | freed++; |
| 894 | else | 892 | else |
| 895 | WARN_ON_ONCE(1); | 893 | WARN_ON_ONCE(1); |
| 896 | 894 | ||
| 897 | info = IEEE80211_SKB_CB(skb); | ||
| 898 | iwl_trans_free_tx_cmd(mvm->trans, info->driver_data[1]); | 895 | iwl_trans_free_tx_cmd(mvm->trans, info->driver_data[1]); |
| 899 | 896 | ||
| 897 | memset(&info->status, 0, sizeof(info->status)); | ||
| 898 | /* Packet was transmitted successfully, failures come as single | ||
| 899 | * frames because before failing a frame the firmware transmits | ||
| 900 | * it without aggregation at least once. | ||
| 901 | */ | ||
| 902 | info->flags |= IEEE80211_TX_STAT_ACK; | ||
| 903 | |||
| 900 | if (freed == 1) { | 904 | if (freed == 1) { |
| 901 | /* this is the first skb we deliver in this batch */ | 905 | /* this is the first skb we deliver in this batch */ |
| 902 | /* put the rate scaling data there */ | 906 | /* put the rate scaling data there */ |
| 903 | info = IEEE80211_SKB_CB(skb); | ||
| 904 | memset(&info->status, 0, sizeof(info->status)); | ||
| 905 | info->flags |= IEEE80211_TX_STAT_ACK; | ||
| 906 | info->flags |= IEEE80211_TX_STAT_AMPDU; | 907 | info->flags |= IEEE80211_TX_STAT_AMPDU; |
| 907 | info->status.ampdu_ack_len = ba_notif->txed_2_done; | 908 | info->status.ampdu_ack_len = ba_notif->txed_2_done; |
| 908 | info->status.ampdu_len = ba_notif->txed; | 909 | info->status.ampdu_len = ba_notif->txed; |
diff --git a/drivers/net/wireless/iwlwifi/mvm/utils.c b/drivers/net/wireless/iwlwifi/mvm/utils.c index a4a5e25623c3..86989df69356 100644 --- a/drivers/net/wireless/iwlwifi/mvm/utils.c +++ b/drivers/net/wireless/iwlwifi/mvm/utils.c | |||
| @@ -411,6 +411,8 @@ void iwl_mvm_dump_nic_error_log(struct iwl_mvm *mvm) | |||
| 411 | mvm->status, table.valid); | 411 | mvm->status, table.valid); |
| 412 | } | 412 | } |
| 413 | 413 | ||
| 414 | IWL_ERR(mvm, "Loaded firmware version: %s\n", mvm->fw->fw_version); | ||
| 415 | |||
| 414 | trace_iwlwifi_dev_ucode_error(trans->dev, table.error_id, table.tsf_low, | 416 | trace_iwlwifi_dev_ucode_error(trans->dev, table.error_id, table.tsf_low, |
| 415 | table.data1, table.data2, table.data3, | 417 | table.data1, table.data2, table.data3, |
| 416 | table.blink1, table.blink2, table.ilink1, | 418 | table.blink1, table.blink2, table.ilink1, |
diff --git a/drivers/net/wireless/iwlwifi/pcie/drv.c b/drivers/net/wireless/iwlwifi/pcie/drv.c index 3040924f5f3c..f47bcbe2945a 100644 --- a/drivers/net/wireless/iwlwifi/pcie/drv.c +++ b/drivers/net/wireless/iwlwifi/pcie/drv.c | |||
| @@ -359,20 +359,25 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = { | |||
| 359 | /* 7265 Series */ | 359 | /* 7265 Series */ |
| 360 | {IWL_PCI_DEVICE(0x095A, 0x5010, iwl7265_2ac_cfg)}, | 360 | {IWL_PCI_DEVICE(0x095A, 0x5010, iwl7265_2ac_cfg)}, |
| 361 | {IWL_PCI_DEVICE(0x095A, 0x5110, iwl7265_2ac_cfg)}, | 361 | {IWL_PCI_DEVICE(0x095A, 0x5110, iwl7265_2ac_cfg)}, |
| 362 | {IWL_PCI_DEVICE(0x095A, 0x5112, iwl7265_2ac_cfg)}, | ||
| 363 | {IWL_PCI_DEVICE(0x095A, 0x5100, iwl7265_2ac_cfg)}, | ||
| 364 | {IWL_PCI_DEVICE(0x095A, 0x510A, iwl7265_2ac_cfg)}, | ||
| 362 | {IWL_PCI_DEVICE(0x095B, 0x5310, iwl7265_2ac_cfg)}, | 365 | {IWL_PCI_DEVICE(0x095B, 0x5310, iwl7265_2ac_cfg)}, |
| 363 | {IWL_PCI_DEVICE(0x095B, 0x5302, iwl7265_2ac_cfg)}, | 366 | {IWL_PCI_DEVICE(0x095B, 0x5302, iwl7265_2ac_cfg)}, |
| 364 | {IWL_PCI_DEVICE(0x095B, 0x5210, iwl7265_2ac_cfg)}, | 367 | {IWL_PCI_DEVICE(0x095B, 0x5210, iwl7265_2ac_cfg)}, |
| 365 | {IWL_PCI_DEVICE(0x095A, 0x5012, iwl7265_2ac_cfg)}, | 368 | {IWL_PCI_DEVICE(0x095A, 0x5012, iwl7265_2ac_cfg)}, |
| 366 | {IWL_PCI_DEVICE(0x095A, 0x500A, iwl7265_2ac_cfg)}, | ||
| 367 | {IWL_PCI_DEVICE(0x095A, 0x5410, iwl7265_2ac_cfg)}, | 369 | {IWL_PCI_DEVICE(0x095A, 0x5410, iwl7265_2ac_cfg)}, |
| 368 | {IWL_PCI_DEVICE(0x095A, 0x5400, iwl7265_2ac_cfg)}, | 370 | {IWL_PCI_DEVICE(0x095A, 0x5400, iwl7265_2ac_cfg)}, |
| 369 | {IWL_PCI_DEVICE(0x095A, 0x1010, iwl7265_2ac_cfg)}, | 371 | {IWL_PCI_DEVICE(0x095A, 0x1010, iwl7265_2ac_cfg)}, |
| 370 | {IWL_PCI_DEVICE(0x095A, 0x5000, iwl7265_2n_cfg)}, | 372 | {IWL_PCI_DEVICE(0x095A, 0x5000, iwl7265_2n_cfg)}, |
| 373 | {IWL_PCI_DEVICE(0x095A, 0x500A, iwl7265_2n_cfg)}, | ||
| 371 | {IWL_PCI_DEVICE(0x095B, 0x5200, iwl7265_2n_cfg)}, | 374 | {IWL_PCI_DEVICE(0x095B, 0x5200, iwl7265_2n_cfg)}, |
| 372 | {IWL_PCI_DEVICE(0x095A, 0x5002, iwl7265_n_cfg)}, | 375 | {IWL_PCI_DEVICE(0x095A, 0x5002, iwl7265_n_cfg)}, |
| 373 | {IWL_PCI_DEVICE(0x095B, 0x5202, iwl7265_n_cfg)}, | 376 | {IWL_PCI_DEVICE(0x095B, 0x5202, iwl7265_n_cfg)}, |
| 374 | {IWL_PCI_DEVICE(0x095A, 0x9010, iwl7265_2ac_cfg)}, | 377 | {IWL_PCI_DEVICE(0x095A, 0x9010, iwl7265_2ac_cfg)}, |
| 378 | {IWL_PCI_DEVICE(0x095A, 0x9012, iwl7265_2ac_cfg)}, | ||
| 375 | {IWL_PCI_DEVICE(0x095A, 0x9110, iwl7265_2ac_cfg)}, | 379 | {IWL_PCI_DEVICE(0x095A, 0x9110, iwl7265_2ac_cfg)}, |
| 380 | {IWL_PCI_DEVICE(0x095A, 0x9112, iwl7265_2ac_cfg)}, | ||
| 376 | {IWL_PCI_DEVICE(0x095A, 0x9210, iwl7265_2ac_cfg)}, | 381 | {IWL_PCI_DEVICE(0x095A, 0x9210, iwl7265_2ac_cfg)}, |
| 377 | {IWL_PCI_DEVICE(0x095A, 0x9510, iwl7265_2ac_cfg)}, | 382 | {IWL_PCI_DEVICE(0x095A, 0x9510, iwl7265_2ac_cfg)}, |
| 378 | {IWL_PCI_DEVICE(0x095A, 0x9310, iwl7265_2ac_cfg)}, | 383 | {IWL_PCI_DEVICE(0x095A, 0x9310, iwl7265_2ac_cfg)}, |
diff --git a/drivers/net/wireless/libertas/cfg.c b/drivers/net/wireless/libertas/cfg.c index 32f75007a825..cb6d189bc3e6 100644 --- a/drivers/net/wireless/libertas/cfg.c +++ b/drivers/net/wireless/libertas/cfg.c | |||
| @@ -621,7 +621,7 @@ static int lbs_ret_scan(struct lbs_private *priv, unsigned long dummy, | |||
| 621 | id = *pos++; | 621 | id = *pos++; |
| 622 | elen = *pos++; | 622 | elen = *pos++; |
| 623 | left -= 2; | 623 | left -= 2; |
| 624 | if (elen > left || elen == 0) { | 624 | if (elen > left) { |
| 625 | lbs_deb_scan("scan response: invalid IE fmt\n"); | 625 | lbs_deb_scan("scan response: invalid IE fmt\n"); |
| 626 | goto done; | 626 | goto done; |
| 627 | } | 627 | } |
diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c index 4d79761b9c87..9d3d2758ec35 100644 --- a/drivers/net/wireless/mwifiex/main.c +++ b/drivers/net/wireless/mwifiex/main.c | |||
| @@ -748,7 +748,7 @@ static struct net_device_stats *mwifiex_get_stats(struct net_device *dev) | |||
| 748 | 748 | ||
| 749 | static u16 | 749 | static u16 |
| 750 | mwifiex_netdev_select_wmm_queue(struct net_device *dev, struct sk_buff *skb, | 750 | mwifiex_netdev_select_wmm_queue(struct net_device *dev, struct sk_buff *skb, |
| 751 | void *accel_priv) | 751 | void *accel_priv, select_queue_fallback_t fallback) |
| 752 | { | 752 | { |
| 753 | skb->priority = cfg80211_classify8021d(skb, NULL); | 753 | skb->priority = cfg80211_classify8021d(skb, NULL); |
| 754 | return mwifiex_1d_to_wmm_queue[skb->priority]; | 754 | return mwifiex_1d_to_wmm_queue[skb->priority]; |
diff --git a/drivers/net/wireless/mwifiex/pcie.c b/drivers/net/wireless/mwifiex/pcie.c index 03688aa14e8a..7fe7b53fb17a 100644 --- a/drivers/net/wireless/mwifiex/pcie.c +++ b/drivers/net/wireless/mwifiex/pcie.c | |||
| @@ -1211,6 +1211,12 @@ static int mwifiex_pcie_process_recv_data(struct mwifiex_adapter *adapter) | |||
| 1211 | rd_index = card->rxbd_rdptr & reg->rx_mask; | 1211 | rd_index = card->rxbd_rdptr & reg->rx_mask; |
| 1212 | skb_data = card->rx_buf_list[rd_index]; | 1212 | skb_data = card->rx_buf_list[rd_index]; |
| 1213 | 1213 | ||
| 1214 | /* If skb allocation was failed earlier for Rx packet, | ||
| 1215 | * rx_buf_list[rd_index] would have been left with a NULL. | ||
| 1216 | */ | ||
| 1217 | if (!skb_data) | ||
| 1218 | return -ENOMEM; | ||
| 1219 | |||
| 1214 | MWIFIEX_SKB_PACB(skb_data, &buf_pa); | 1220 | MWIFIEX_SKB_PACB(skb_data, &buf_pa); |
| 1215 | pci_unmap_single(card->dev, buf_pa, MWIFIEX_RX_DATA_BUF_SIZE, | 1221 | pci_unmap_single(card->dev, buf_pa, MWIFIEX_RX_DATA_BUF_SIZE, |
| 1216 | PCI_DMA_FROMDEVICE); | 1222 | PCI_DMA_FROMDEVICE); |
| @@ -1525,6 +1531,14 @@ static int mwifiex_pcie_process_cmd_complete(struct mwifiex_adapter *adapter) | |||
| 1525 | if (adapter->ps_state == PS_STATE_SLEEP_CFM) { | 1531 | if (adapter->ps_state == PS_STATE_SLEEP_CFM) { |
| 1526 | mwifiex_process_sleep_confirm_resp(adapter, skb->data, | 1532 | mwifiex_process_sleep_confirm_resp(adapter, skb->data, |
| 1527 | skb->len); | 1533 | skb->len); |
| 1534 | mwifiex_pcie_enable_host_int(adapter); | ||
| 1535 | if (mwifiex_write_reg(adapter, | ||
| 1536 | PCIE_CPU_INT_EVENT, | ||
| 1537 | CPU_INTR_SLEEP_CFM_DONE)) { | ||
| 1538 | dev_warn(adapter->dev, | ||
| 1539 | "Write register failed\n"); | ||
| 1540 | return -1; | ||
| 1541 | } | ||
| 1528 | while (reg->sleep_cookie && (count++ < 10) && | 1542 | while (reg->sleep_cookie && (count++ < 10) && |
| 1529 | mwifiex_pcie_ok_to_access_hw(adapter)) | 1543 | mwifiex_pcie_ok_to_access_hw(adapter)) |
| 1530 | usleep_range(50, 60); | 1544 | usleep_range(50, 60); |
| @@ -1993,23 +2007,9 @@ static void mwifiex_interrupt_status(struct mwifiex_adapter *adapter) | |||
| 1993 | adapter->int_status |= pcie_ireg; | 2007 | adapter->int_status |= pcie_ireg; |
| 1994 | spin_unlock_irqrestore(&adapter->int_lock, flags); | 2008 | spin_unlock_irqrestore(&adapter->int_lock, flags); |
| 1995 | 2009 | ||
| 1996 | if (pcie_ireg & HOST_INTR_CMD_DONE) { | 2010 | if (!adapter->pps_uapsd_mode && |
| 1997 | if ((adapter->ps_state == PS_STATE_SLEEP_CFM) || | 2011 | adapter->ps_state == PS_STATE_SLEEP && |
| 1998 | (adapter->ps_state == PS_STATE_SLEEP)) { | 2012 | mwifiex_pcie_ok_to_access_hw(adapter)) { |
| 1999 | mwifiex_pcie_enable_host_int(adapter); | ||
| 2000 | if (mwifiex_write_reg(adapter, | ||
| 2001 | PCIE_CPU_INT_EVENT, | ||
| 2002 | CPU_INTR_SLEEP_CFM_DONE) | ||
| 2003 | ) { | ||
| 2004 | dev_warn(adapter->dev, | ||
| 2005 | "Write register failed\n"); | ||
| 2006 | return; | ||
| 2007 | |||
| 2008 | } | ||
| 2009 | } | ||
| 2010 | } else if (!adapter->pps_uapsd_mode && | ||
| 2011 | adapter->ps_state == PS_STATE_SLEEP && | ||
| 2012 | mwifiex_pcie_ok_to_access_hw(adapter)) { | ||
| 2013 | /* Potentially for PCIe we could get other | 2013 | /* Potentially for PCIe we could get other |
| 2014 | * interrupts like shared. Don't change power | 2014 | * interrupts like shared. Don't change power |
| 2015 | * state until cookie is set */ | 2015 | * state until cookie is set */ |
diff --git a/drivers/net/wireless/mwifiex/usb.c b/drivers/net/wireless/mwifiex/usb.c index e8ebbd4bc3cd..208748804a55 100644 --- a/drivers/net/wireless/mwifiex/usb.c +++ b/drivers/net/wireless/mwifiex/usb.c | |||
| @@ -22,8 +22,6 @@ | |||
| 22 | 22 | ||
| 23 | #define USB_VERSION "1.0" | 23 | #define USB_VERSION "1.0" |
| 24 | 24 | ||
| 25 | static const char usbdriver_name[] = "usb8xxx"; | ||
| 26 | |||
| 27 | static struct mwifiex_if_ops usb_ops; | 25 | static struct mwifiex_if_ops usb_ops; |
| 28 | static struct semaphore add_remove_card_sem; | 26 | static struct semaphore add_remove_card_sem; |
| 29 | static struct usb_card_rec *usb_card; | 27 | static struct usb_card_rec *usb_card; |
| @@ -527,13 +525,6 @@ static int mwifiex_usb_resume(struct usb_interface *intf) | |||
| 527 | MWIFIEX_BSS_ROLE_ANY), | 525 | MWIFIEX_BSS_ROLE_ANY), |
| 528 | MWIFIEX_ASYNC_CMD); | 526 | MWIFIEX_ASYNC_CMD); |
| 529 | 527 | ||
| 530 | #ifdef CONFIG_PM | ||
| 531 | /* Resume handler may be called due to remote wakeup, | ||
| 532 | * force to exit suspend anyway | ||
| 533 | */ | ||
| 534 | usb_disable_autosuspend(card->udev); | ||
| 535 | #endif /* CONFIG_PM */ | ||
| 536 | |||
| 537 | return 0; | 528 | return 0; |
| 538 | } | 529 | } |
| 539 | 530 | ||
| @@ -567,13 +558,12 @@ static void mwifiex_usb_disconnect(struct usb_interface *intf) | |||
| 567 | } | 558 | } |
| 568 | 559 | ||
| 569 | static struct usb_driver mwifiex_usb_driver = { | 560 | static struct usb_driver mwifiex_usb_driver = { |
| 570 | .name = usbdriver_name, | 561 | .name = "mwifiex_usb", |
| 571 | .probe = mwifiex_usb_probe, | 562 | .probe = mwifiex_usb_probe, |
| 572 | .disconnect = mwifiex_usb_disconnect, | 563 | .disconnect = mwifiex_usb_disconnect, |
| 573 | .id_table = mwifiex_usb_table, | 564 | .id_table = mwifiex_usb_table, |
| 574 | .suspend = mwifiex_usb_suspend, | 565 | .suspend = mwifiex_usb_suspend, |
| 575 | .resume = mwifiex_usb_resume, | 566 | .resume = mwifiex_usb_resume, |
| 576 | .supports_autosuspend = 1, | ||
| 577 | }; | 567 | }; |
| 578 | 568 | ||
| 579 | static int mwifiex_usb_tx_init(struct mwifiex_adapter *adapter) | 569 | static int mwifiex_usb_tx_init(struct mwifiex_adapter *adapter) |
diff --git a/drivers/net/wireless/mwifiex/wmm.c b/drivers/net/wireless/mwifiex/wmm.c index 13eaeed03898..981cf6e7c73b 100644 --- a/drivers/net/wireless/mwifiex/wmm.c +++ b/drivers/net/wireless/mwifiex/wmm.c | |||
| @@ -559,7 +559,8 @@ mwifiex_clean_txrx(struct mwifiex_private *priv) | |||
| 559 | mwifiex_wmm_delete_all_ralist(priv); | 559 | mwifiex_wmm_delete_all_ralist(priv); |
| 560 | memcpy(tos_to_tid, ac_to_tid, sizeof(tos_to_tid)); | 560 | memcpy(tos_to_tid, ac_to_tid, sizeof(tos_to_tid)); |
| 561 | 561 | ||
| 562 | if (priv->adapter->if_ops.clean_pcie_ring) | 562 | if (priv->adapter->if_ops.clean_pcie_ring && |
| 563 | !priv->adapter->surprise_removed) | ||
| 563 | priv->adapter->if_ops.clean_pcie_ring(priv->adapter); | 564 | priv->adapter->if_ops.clean_pcie_ring(priv->adapter); |
| 564 | spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, flags); | 565 | spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, flags); |
| 565 | } | 566 | } |
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c index abc5f56f29fe..2f1cd929c6f6 100644 --- a/drivers/net/wireless/rt2x00/rt2500pci.c +++ b/drivers/net/wireless/rt2x00/rt2500pci.c | |||
| @@ -1877,6 +1877,11 @@ static int rt2500pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
| 1877 | EEPROM_MAC_ADDR_0)); | 1877 | EEPROM_MAC_ADDR_0)); |
| 1878 | 1878 | ||
| 1879 | /* | 1879 | /* |
| 1880 | * Disable powersaving as default. | ||
| 1881 | */ | ||
| 1882 | rt2x00dev->hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; | ||
| 1883 | |||
| 1884 | /* | ||
| 1880 | * Initialize hw_mode information. | 1885 | * Initialize hw_mode information. |
| 1881 | */ | 1886 | */ |
| 1882 | spec->supported_bands = SUPPORT_BAND_2GHZ; | 1887 | spec->supported_bands = SUPPORT_BAND_2GHZ; |
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index 9f16824cd1bc..d849d590de25 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c | |||
| @@ -1706,6 +1706,11 @@ static int rt2500usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
| 1706 | IEEE80211_HW_SUPPORTS_PS | | 1706 | IEEE80211_HW_SUPPORTS_PS | |
| 1707 | IEEE80211_HW_PS_NULLFUNC_STACK; | 1707 | IEEE80211_HW_PS_NULLFUNC_STACK; |
| 1708 | 1708 | ||
| 1709 | /* | ||
| 1710 | * Disable powersaving as default. | ||
| 1711 | */ | ||
| 1712 | rt2x00dev->hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; | ||
| 1713 | |||
| 1709 | SET_IEEE80211_DEV(rt2x00dev->hw, rt2x00dev->dev); | 1714 | SET_IEEE80211_DEV(rt2x00dev->hw, rt2x00dev->dev); |
| 1710 | SET_IEEE80211_PERM_ADDR(rt2x00dev->hw, | 1715 | SET_IEEE80211_PERM_ADDR(rt2x00dev->hw, |
| 1711 | rt2x00_eeprom_addr(rt2x00dev, | 1716 | rt2x00_eeprom_addr(rt2x00dev, |
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index b8f5b06006c4..7f8b5d156c8c 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c | |||
| @@ -7458,10 +7458,9 @@ static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
| 7458 | u32 reg; | 7458 | u32 reg; |
| 7459 | 7459 | ||
| 7460 | /* | 7460 | /* |
| 7461 | * Disable powersaving as default on PCI devices. | 7461 | * Disable powersaving as default. |
| 7462 | */ | 7462 | */ |
| 7463 | if (rt2x00_is_pci(rt2x00dev) || rt2x00_is_soc(rt2x00dev)) | 7463 | rt2x00dev->hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; |
| 7464 | rt2x00dev->hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; | ||
| 7465 | 7464 | ||
| 7466 | /* | 7465 | /* |
| 7467 | * Initialize all hw fields. | 7466 | * Initialize all hw fields. |
diff --git a/drivers/net/wireless/rtl818x/rtl8180/dev.c b/drivers/net/wireless/rtl818x/rtl8180/dev.c index 8ec17aad0e52..3867d1470b36 100644 --- a/drivers/net/wireless/rtl818x/rtl8180/dev.c +++ b/drivers/net/wireless/rtl818x/rtl8180/dev.c | |||
| @@ -107,6 +107,7 @@ static void rtl8180_handle_rx(struct ieee80211_hw *dev) | |||
| 107 | struct rtl8180_priv *priv = dev->priv; | 107 | struct rtl8180_priv *priv = dev->priv; |
| 108 | unsigned int count = 32; | 108 | unsigned int count = 32; |
| 109 | u8 signal, agc, sq; | 109 | u8 signal, agc, sq; |
| 110 | dma_addr_t mapping; | ||
| 110 | 111 | ||
| 111 | while (count--) { | 112 | while (count--) { |
| 112 | struct rtl8180_rx_desc *entry = &priv->rx_ring[priv->rx_idx]; | 113 | struct rtl8180_rx_desc *entry = &priv->rx_ring[priv->rx_idx]; |
| @@ -128,6 +129,17 @@ static void rtl8180_handle_rx(struct ieee80211_hw *dev) | |||
| 128 | if (unlikely(!new_skb)) | 129 | if (unlikely(!new_skb)) |
| 129 | goto done; | 130 | goto done; |
| 130 | 131 | ||
| 132 | mapping = pci_map_single(priv->pdev, | ||
| 133 | skb_tail_pointer(new_skb), | ||
| 134 | MAX_RX_SIZE, PCI_DMA_FROMDEVICE); | ||
| 135 | |||
| 136 | if (pci_dma_mapping_error(priv->pdev, mapping)) { | ||
| 137 | kfree_skb(new_skb); | ||
| 138 | dev_err(&priv->pdev->dev, "RX DMA map error\n"); | ||
| 139 | |||
| 140 | goto done; | ||
| 141 | } | ||
| 142 | |||
| 131 | pci_unmap_single(priv->pdev, | 143 | pci_unmap_single(priv->pdev, |
| 132 | *((dma_addr_t *)skb->cb), | 144 | *((dma_addr_t *)skb->cb), |
| 133 | MAX_RX_SIZE, PCI_DMA_FROMDEVICE); | 145 | MAX_RX_SIZE, PCI_DMA_FROMDEVICE); |
| @@ -158,9 +170,7 @@ static void rtl8180_handle_rx(struct ieee80211_hw *dev) | |||
| 158 | 170 | ||
| 159 | skb = new_skb; | 171 | skb = new_skb; |
| 160 | priv->rx_buf[priv->rx_idx] = skb; | 172 | priv->rx_buf[priv->rx_idx] = skb; |
| 161 | *((dma_addr_t *) skb->cb) = | 173 | *((dma_addr_t *) skb->cb) = mapping; |
| 162 | pci_map_single(priv->pdev, skb_tail_pointer(skb), | ||
| 163 | MAX_RX_SIZE, PCI_DMA_FROMDEVICE); | ||
| 164 | } | 174 | } |
| 165 | 175 | ||
| 166 | done: | 176 | done: |
| @@ -266,6 +276,13 @@ static void rtl8180_tx(struct ieee80211_hw *dev, | |||
| 266 | mapping = pci_map_single(priv->pdev, skb->data, | 276 | mapping = pci_map_single(priv->pdev, skb->data, |
| 267 | skb->len, PCI_DMA_TODEVICE); | 277 | skb->len, PCI_DMA_TODEVICE); |
| 268 | 278 | ||
| 279 | if (pci_dma_mapping_error(priv->pdev, mapping)) { | ||
| 280 | kfree_skb(skb); | ||
| 281 | dev_err(&priv->pdev->dev, "TX DMA mapping error\n"); | ||
| 282 | return; | ||
| 283 | |||
| 284 | } | ||
| 285 | |||
| 269 | tx_flags = RTL818X_TX_DESC_FLAG_OWN | RTL818X_TX_DESC_FLAG_FS | | 286 | tx_flags = RTL818X_TX_DESC_FLAG_OWN | RTL818X_TX_DESC_FLAG_FS | |
| 270 | RTL818X_TX_DESC_FLAG_LS | | 287 | RTL818X_TX_DESC_FLAG_LS | |
| 271 | (ieee80211_get_tx_rate(dev, info)->hw_value << 24) | | 288 | (ieee80211_get_tx_rate(dev, info)->hw_value << 24) | |
diff --git a/drivers/net/wireless/rtl818x/rtl8187/rtl8187.h b/drivers/net/wireless/rtl818x/rtl8187/rtl8187.h index 56aee067f324..a6ad79f61bf9 100644 --- a/drivers/net/wireless/rtl818x/rtl8187/rtl8187.h +++ b/drivers/net/wireless/rtl818x/rtl8187/rtl8187.h | |||
| @@ -15,6 +15,8 @@ | |||
| 15 | #ifndef RTL8187_H | 15 | #ifndef RTL8187_H |
| 16 | #define RTL8187_H | 16 | #define RTL8187_H |
| 17 | 17 | ||
| 18 | #include <linux/cache.h> | ||
| 19 | |||
| 18 | #include "rtl818x.h" | 20 | #include "rtl818x.h" |
| 19 | #include "leds.h" | 21 | #include "leds.h" |
| 20 | 22 | ||
| @@ -139,7 +141,10 @@ struct rtl8187_priv { | |||
| 139 | u8 aifsn[4]; | 141 | u8 aifsn[4]; |
| 140 | u8 rfkill_mask; | 142 | u8 rfkill_mask; |
| 141 | struct { | 143 | struct { |
| 142 | __le64 buf; | 144 | union { |
| 145 | __le64 buf; | ||
| 146 | u8 dummy1[L1_CACHE_BYTES]; | ||
| 147 | } ____cacheline_aligned; | ||
| 143 | struct sk_buff_head queue; | 148 | struct sk_buff_head queue; |
| 144 | } b_tx_status; /* This queue is used by both -b and non-b devices */ | 149 | } b_tx_status; /* This queue is used by both -b and non-b devices */ |
| 145 | struct mutex io_mutex; | 150 | struct mutex io_mutex; |
| @@ -147,7 +152,8 @@ struct rtl8187_priv { | |||
| 147 | u8 bits8; | 152 | u8 bits8; |
| 148 | __le16 bits16; | 153 | __le16 bits16; |
| 149 | __le32 bits32; | 154 | __le32 bits32; |
| 150 | } *io_dmabuf; | 155 | u8 dummy2[L1_CACHE_BYTES]; |
| 156 | } *io_dmabuf ____cacheline_aligned; | ||
| 151 | bool rfkill_off; | 157 | bool rfkill_off; |
| 152 | u16 seqno; | 158 | u16 seqno; |
| 153 | }; | 159 | }; |
diff --git a/drivers/net/wireless/rtlwifi/ps.c b/drivers/net/wireless/rtlwifi/ps.c index deedae3c5449..d1c0191a195b 100644 --- a/drivers/net/wireless/rtlwifi/ps.c +++ b/drivers/net/wireless/rtlwifi/ps.c | |||
| @@ -48,7 +48,7 @@ bool rtl_ps_enable_nic(struct ieee80211_hw *hw) | |||
| 48 | 48 | ||
| 49 | /*<2> Enable Adapter */ | 49 | /*<2> Enable Adapter */ |
| 50 | if (rtlpriv->cfg->ops->hw_init(hw)) | 50 | if (rtlpriv->cfg->ops->hw_init(hw)) |
| 51 | return 1; | 51 | return false; |
| 52 | RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); | 52 | RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); |
| 53 | 53 | ||
| 54 | /*<3> Enable Interrupt */ | 54 | /*<3> Enable Interrupt */ |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c index a82b30a1996c..2eb0b38384dd 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c | |||
| @@ -937,14 +937,26 @@ int rtl92ce_hw_init(struct ieee80211_hw *hw) | |||
| 937 | bool is92c; | 937 | bool is92c; |
| 938 | int err; | 938 | int err; |
| 939 | u8 tmp_u1b; | 939 | u8 tmp_u1b; |
| 940 | unsigned long flags; | ||
| 940 | 941 | ||
| 941 | rtlpci->being_init_adapter = true; | 942 | rtlpci->being_init_adapter = true; |
| 943 | |||
| 944 | /* Since this function can take a very long time (up to 350 ms) | ||
| 945 | * and can be called with irqs disabled, reenable the irqs | ||
| 946 | * to let the other devices continue being serviced. | ||
| 947 | * | ||
| 948 | * It is safe doing so since our own interrupts will only be enabled | ||
| 949 | * in a subsequent step. | ||
| 950 | */ | ||
| 951 | local_save_flags(flags); | ||
| 952 | local_irq_enable(); | ||
| 953 | |||
| 942 | rtlpriv->intf_ops->disable_aspm(hw); | 954 | rtlpriv->intf_ops->disable_aspm(hw); |
| 943 | rtstatus = _rtl92ce_init_mac(hw); | 955 | rtstatus = _rtl92ce_init_mac(hw); |
| 944 | if (!rtstatus) { | 956 | if (!rtstatus) { |
| 945 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Init MAC failed\n"); | 957 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Init MAC failed\n"); |
| 946 | err = 1; | 958 | err = 1; |
| 947 | return err; | 959 | goto exit; |
| 948 | } | 960 | } |
| 949 | 961 | ||
| 950 | err = rtl92c_download_fw(hw); | 962 | err = rtl92c_download_fw(hw); |
| @@ -952,7 +964,7 @@ int rtl92ce_hw_init(struct ieee80211_hw *hw) | |||
| 952 | RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, | 964 | RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, |
| 953 | "Failed to download FW. Init HW without FW now..\n"); | 965 | "Failed to download FW. Init HW without FW now..\n"); |
| 954 | err = 1; | 966 | err = 1; |
| 955 | return err; | 967 | goto exit; |
| 956 | } | 968 | } |
| 957 | 969 | ||
| 958 | rtlhal->last_hmeboxnum = 0; | 970 | rtlhal->last_hmeboxnum = 0; |
| @@ -1032,6 +1044,8 @@ int rtl92ce_hw_init(struct ieee80211_hw *hw) | |||
| 1032 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "under 1.5V\n"); | 1044 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "under 1.5V\n"); |
| 1033 | } | 1045 | } |
| 1034 | rtl92c_dm_init(hw); | 1046 | rtl92c_dm_init(hw); |
| 1047 | exit: | ||
| 1048 | local_irq_restore(flags); | ||
| 1035 | rtlpci->being_init_adapter = false; | 1049 | rtlpci->being_init_adapter = false; |
| 1036 | return err; | 1050 | return err; |
| 1037 | } | 1051 | } |
diff --git a/drivers/net/xen-netback/common.h b/drivers/net/xen-netback/common.h index 4c76bcb9a879..ae413a2cbee7 100644 --- a/drivers/net/xen-netback/common.h +++ b/drivers/net/xen-netback/common.h | |||
| @@ -143,11 +143,7 @@ struct xenvif { | |||
| 143 | char rx_irq_name[IFNAMSIZ+4]; /* DEVNAME-rx */ | 143 | char rx_irq_name[IFNAMSIZ+4]; /* DEVNAME-rx */ |
| 144 | struct xen_netif_rx_back_ring rx; | 144 | struct xen_netif_rx_back_ring rx; |
| 145 | struct sk_buff_head rx_queue; | 145 | struct sk_buff_head rx_queue; |
| 146 | bool rx_queue_stopped; | 146 | RING_IDX rx_last_skb_slots; |
| 147 | /* Set when the RX interrupt is triggered by the frontend. | ||
| 148 | * The worker thread may need to wake the queue. | ||
| 149 | */ | ||
| 150 | bool rx_event; | ||
| 151 | 147 | ||
| 152 | /* This array is allocated seperately as it is large */ | 148 | /* This array is allocated seperately as it is large */ |
| 153 | struct gnttab_copy *grant_copy_op; | 149 | struct gnttab_copy *grant_copy_op; |
diff --git a/drivers/net/xen-netback/interface.c b/drivers/net/xen-netback/interface.c index b9de31ea7fc4..7669d49a67e2 100644 --- a/drivers/net/xen-netback/interface.c +++ b/drivers/net/xen-netback/interface.c | |||
| @@ -100,7 +100,6 @@ static irqreturn_t xenvif_rx_interrupt(int irq, void *dev_id) | |||
| 100 | { | 100 | { |
| 101 | struct xenvif *vif = dev_id; | 101 | struct xenvif *vif = dev_id; |
| 102 | 102 | ||
| 103 | vif->rx_event = true; | ||
| 104 | xenvif_kick_thread(vif); | 103 | xenvif_kick_thread(vif); |
| 105 | 104 | ||
| 106 | return IRQ_HANDLED; | 105 | return IRQ_HANDLED; |
diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c index 6b62c3eb8e18..e5284bca2d90 100644 --- a/drivers/net/xen-netback/netback.c +++ b/drivers/net/xen-netback/netback.c | |||
| @@ -476,7 +476,6 @@ static void xenvif_rx_action(struct xenvif *vif) | |||
| 476 | unsigned long offset; | 476 | unsigned long offset; |
| 477 | struct skb_cb_overlay *sco; | 477 | struct skb_cb_overlay *sco; |
| 478 | bool need_to_notify = false; | 478 | bool need_to_notify = false; |
| 479 | bool ring_full = false; | ||
| 480 | 479 | ||
| 481 | struct netrx_pending_operations npo = { | 480 | struct netrx_pending_operations npo = { |
| 482 | .copy = vif->grant_copy_op, | 481 | .copy = vif->grant_copy_op, |
| @@ -486,7 +485,7 @@ static void xenvif_rx_action(struct xenvif *vif) | |||
| 486 | skb_queue_head_init(&rxq); | 485 | skb_queue_head_init(&rxq); |
| 487 | 486 | ||
| 488 | while ((skb = skb_dequeue(&vif->rx_queue)) != NULL) { | 487 | while ((skb = skb_dequeue(&vif->rx_queue)) != NULL) { |
| 489 | int max_slots_needed; | 488 | RING_IDX max_slots_needed; |
| 490 | int i; | 489 | int i; |
| 491 | 490 | ||
| 492 | /* We need a cheap worse case estimate for the number of | 491 | /* We need a cheap worse case estimate for the number of |
| @@ -509,9 +508,10 @@ static void xenvif_rx_action(struct xenvif *vif) | |||
| 509 | if (!xenvif_rx_ring_slots_available(vif, max_slots_needed)) { | 508 | if (!xenvif_rx_ring_slots_available(vif, max_slots_needed)) { |
| 510 | skb_queue_head(&vif->rx_queue, skb); | 509 | skb_queue_head(&vif->rx_queue, skb); |
| 511 | need_to_notify = true; | 510 | need_to_notify = true; |
| 512 | ring_full = true; | 511 | vif->rx_last_skb_slots = max_slots_needed; |
| 513 | break; | 512 | break; |
| 514 | } | 513 | } else |
| 514 | vif->rx_last_skb_slots = 0; | ||
| 515 | 515 | ||
| 516 | sco = (struct skb_cb_overlay *)skb->cb; | 516 | sco = (struct skb_cb_overlay *)skb->cb; |
| 517 | sco->meta_slots_used = xenvif_gop_skb(skb, &npo); | 517 | sco->meta_slots_used = xenvif_gop_skb(skb, &npo); |
| @@ -522,8 +522,6 @@ static void xenvif_rx_action(struct xenvif *vif) | |||
| 522 | 522 | ||
| 523 | BUG_ON(npo.meta_prod > ARRAY_SIZE(vif->meta)); | 523 | BUG_ON(npo.meta_prod > ARRAY_SIZE(vif->meta)); |
| 524 | 524 | ||
| 525 | vif->rx_queue_stopped = !npo.copy_prod && ring_full; | ||
| 526 | |||
| 527 | if (!npo.copy_prod) | 525 | if (!npo.copy_prod) |
| 528 | goto done; | 526 | goto done; |
| 529 | 527 | ||
| @@ -1473,8 +1471,8 @@ static struct xen_netif_rx_response *make_rx_response(struct xenvif *vif, | |||
| 1473 | 1471 | ||
| 1474 | static inline int rx_work_todo(struct xenvif *vif) | 1472 | static inline int rx_work_todo(struct xenvif *vif) |
| 1475 | { | 1473 | { |
| 1476 | return (!skb_queue_empty(&vif->rx_queue) && !vif->rx_queue_stopped) || | 1474 | return !skb_queue_empty(&vif->rx_queue) && |
| 1477 | vif->rx_event; | 1475 | xenvif_rx_ring_slots_available(vif, vif->rx_last_skb_slots); |
| 1478 | } | 1476 | } |
| 1479 | 1477 | ||
| 1480 | static inline int tx_work_todo(struct xenvif *vif) | 1478 | static inline int tx_work_todo(struct xenvif *vif) |
| @@ -1560,8 +1558,6 @@ int xenvif_kthread(void *data) | |||
| 1560 | if (!skb_queue_empty(&vif->rx_queue)) | 1558 | if (!skb_queue_empty(&vif->rx_queue)) |
| 1561 | xenvif_rx_action(vif); | 1559 | xenvif_rx_action(vif); |
| 1562 | 1560 | ||
| 1563 | vif->rx_event = false; | ||
| 1564 | |||
| 1565 | if (skb_queue_empty(&vif->rx_queue) && | 1561 | if (skb_queue_empty(&vif->rx_queue) && |
| 1566 | netif_queue_stopped(vif->dev)) | 1562 | netif_queue_stopped(vif->dev)) |
| 1567 | xenvif_start_queue(vif); | 1563 | xenvif_start_queue(vif); |
diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c index ff04d4f95baa..e30d80033cbc 100644 --- a/drivers/net/xen-netfront.c +++ b/drivers/net/xen-netfront.c | |||
| @@ -907,6 +907,7 @@ static int handle_incoming_queue(struct net_device *dev, | |||
| 907 | 907 | ||
| 908 | /* Ethernet work: Delayed to here as it peeks the header. */ | 908 | /* Ethernet work: Delayed to here as it peeks the header. */ |
| 909 | skb->protocol = eth_type_trans(skb, dev); | 909 | skb->protocol = eth_type_trans(skb, dev); |
| 910 | skb_reset_network_header(skb); | ||
| 910 | 911 | ||
| 911 | if (checksum_setup(dev, skb)) { | 912 | if (checksum_setup(dev, skb)) { |
| 912 | kfree_skb(skb); | 913 | kfree_skb(skb); |
| @@ -1832,7 +1833,6 @@ static void netback_changed(struct xenbus_device *dev, | |||
| 1832 | case XenbusStateReconfiguring: | 1833 | case XenbusStateReconfiguring: |
| 1833 | case XenbusStateReconfigured: | 1834 | case XenbusStateReconfigured: |
| 1834 | case XenbusStateUnknown: | 1835 | case XenbusStateUnknown: |
| 1835 | case XenbusStateClosed: | ||
| 1836 | break; | 1836 | break; |
| 1837 | 1837 | ||
| 1838 | case XenbusStateInitWait: | 1838 | case XenbusStateInitWait: |
| @@ -1847,6 +1847,10 @@ static void netback_changed(struct xenbus_device *dev, | |||
| 1847 | netdev_notify_peers(netdev); | 1847 | netdev_notify_peers(netdev); |
| 1848 | break; | 1848 | break; |
| 1849 | 1849 | ||
| 1850 | case XenbusStateClosed: | ||
| 1851 | if (dev->state == XenbusStateClosed) | ||
| 1852 | break; | ||
| 1853 | /* Missed the backend's CLOSING state -- fallthrough */ | ||
| 1850 | case XenbusStateClosing: | 1854 | case XenbusStateClosing: |
| 1851 | xenbus_frontend_closed(dev); | 1855 | xenbus_frontend_closed(dev); |
| 1852 | break; | 1856 | break; |
