diff options
author | Ingo Molnar <mingo@kernel.org> | 2014-02-27 06:41:17 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2014-02-27 06:41:17 -0500 |
commit | ff5a7088f0f04dd246e514f898cab0c863c3598d (patch) | |
tree | 68a8f588e60fba05ee54b74b32a3269a72d130b9 /drivers/net | |
parent | 7e74efcf76c16f851df5c838c143c4a1865ea9fa (diff) | |
parent | e3703f8cdfcf39c25c4338c3ad8e68891cca3731 (diff) |
Merge branch 'perf/urgent' into perf/core
Merge the latest fixes before queueing up new changes.
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'drivers/net')
101 files changed, 2099 insertions, 400 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..6d20fbde8d43 100644 --- a/drivers/net/bonding/bond_3ad.c +++ b/drivers/net/bonding/bond_3ad.c | |||
@@ -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; |
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..1c6104d3501d 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c | |||
@@ -1270,9 +1270,13 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) | |||
1270 | 1270 | ||
1271 | if (slave_ops->ndo_set_mac_address == NULL) { | 1271 | if (slave_ops->ndo_set_mac_address == NULL) { |
1272 | if (!bond_has_slaves(bond)) { | 1272 | 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.", | 1273 | pr_warn("%s: Warning: The first slave device specified does not support setting the MAC address.\n", |
1274 | bond_dev->name); | 1274 | bond_dev->name); |
1275 | bond->params.fail_over_mac = BOND_FOM_ACTIVE; | 1275 | if (bond->params.mode == BOND_MODE_ACTIVEBACKUP) { |
1276 | bond->params.fail_over_mac = BOND_FOM_ACTIVE; | ||
1277 | pr_warn("%s: Setting fail_over_mac to active for active-backup mode.\n", | ||
1278 | bond_dev->name); | ||
1279 | } | ||
1276 | } else if (bond->params.fail_over_mac != BOND_FOM_ACTIVE) { | 1280 | } 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", | 1281 | 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); | 1282 | bond_dev->name); |
@@ -1315,7 +1319,8 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) | |||
1315 | */ | 1319 | */ |
1316 | memcpy(new_slave->perm_hwaddr, slave_dev->dev_addr, ETH_ALEN); | 1320 | memcpy(new_slave->perm_hwaddr, slave_dev->dev_addr, ETH_ALEN); |
1317 | 1321 | ||
1318 | if (!bond->params.fail_over_mac) { | 1322 | if (!bond->params.fail_over_mac || |
1323 | bond->params.mode != BOND_MODE_ACTIVEBACKUP) { | ||
1319 | /* | 1324 | /* |
1320 | * Set slave to master's mac address. The application already | 1325 | * Set slave to master's mac address. The application already |
1321 | * set the master's mac address to that of the first slave | 1326 | * set the master's mac address to that of the first slave |
@@ -1505,7 +1510,6 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) | |||
1505 | slave_dev->npinfo = bond->dev->npinfo; | 1510 | slave_dev->npinfo = bond->dev->npinfo; |
1506 | if (slave_dev->npinfo) { | 1511 | if (slave_dev->npinfo) { |
1507 | if (slave_enable_netpoll(new_slave)) { | 1512 | if (slave_enable_netpoll(new_slave)) { |
1508 | read_unlock(&bond->lock); | ||
1509 | pr_info("Error, %s: master_dev is using netpoll, " | 1513 | pr_info("Error, %s: master_dev is using netpoll, " |
1510 | "but new slave device does not support netpoll.\n", | 1514 | "but new slave device does not support netpoll.\n", |
1511 | bond_dev->name); | 1515 | bond_dev->name); |
@@ -1539,9 +1543,11 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) | |||
1539 | bond_set_carrier(bond); | 1543 | bond_set_carrier(bond); |
1540 | 1544 | ||
1541 | if (USES_PRIMARY(bond->params.mode)) { | 1545 | if (USES_PRIMARY(bond->params.mode)) { |
1546 | block_netpoll_tx(); | ||
1542 | write_lock_bh(&bond->curr_slave_lock); | 1547 | write_lock_bh(&bond->curr_slave_lock); |
1543 | bond_select_active_slave(bond); | 1548 | bond_select_active_slave(bond); |
1544 | write_unlock_bh(&bond->curr_slave_lock); | 1549 | write_unlock_bh(&bond->curr_slave_lock); |
1550 | unblock_netpoll_tx(); | ||
1545 | } | 1551 | } |
1546 | 1552 | ||
1547 | pr_info("%s: enslaving %s as a%s interface with a%s link.\n", | 1553 | pr_info("%s: enslaving %s as a%s interface with a%s link.\n", |
@@ -1567,10 +1573,12 @@ err_detach: | |||
1567 | if (bond->primary_slave == new_slave) | 1573 | if (bond->primary_slave == new_slave) |
1568 | bond->primary_slave = NULL; | 1574 | bond->primary_slave = NULL; |
1569 | if (bond->curr_active_slave == new_slave) { | 1575 | if (bond->curr_active_slave == new_slave) { |
1576 | block_netpoll_tx(); | ||
1570 | write_lock_bh(&bond->curr_slave_lock); | 1577 | write_lock_bh(&bond->curr_slave_lock); |
1571 | bond_change_active_slave(bond, NULL); | 1578 | bond_change_active_slave(bond, NULL); |
1572 | bond_select_active_slave(bond); | 1579 | bond_select_active_slave(bond); |
1573 | write_unlock_bh(&bond->curr_slave_lock); | 1580 | write_unlock_bh(&bond->curr_slave_lock); |
1581 | unblock_netpoll_tx(); | ||
1574 | } | 1582 | } |
1575 | slave_disable_netpoll(new_slave); | 1583 | slave_disable_netpoll(new_slave); |
1576 | 1584 | ||
@@ -1579,7 +1587,8 @@ err_close: | |||
1579 | dev_close(slave_dev); | 1587 | dev_close(slave_dev); |
1580 | 1588 | ||
1581 | err_restore_mac: | 1589 | err_restore_mac: |
1582 | if (!bond->params.fail_over_mac) { | 1590 | if (!bond->params.fail_over_mac || |
1591 | bond->params.mode != BOND_MODE_ACTIVEBACKUP) { | ||
1583 | /* XXX TODO - fom follow mode needs to change master's | 1592 | /* 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 | 1593 | * MAC if this slave's MAC is in use by the bond, or at |
1585 | * least print a warning. | 1594 | * least print a warning. |
@@ -1672,7 +1681,8 @@ static int __bond_release_one(struct net_device *bond_dev, | |||
1672 | 1681 | ||
1673 | bond->current_arp_slave = NULL; | 1682 | bond->current_arp_slave = NULL; |
1674 | 1683 | ||
1675 | if (!all && !bond->params.fail_over_mac) { | 1684 | if (!all && (!bond->params.fail_over_mac || |
1685 | bond->params.mode != BOND_MODE_ACTIVEBACKUP)) { | ||
1676 | if (ether_addr_equal_64bits(bond_dev->dev_addr, slave->perm_hwaddr) && | 1686 | if (ether_addr_equal_64bits(bond_dev->dev_addr, slave->perm_hwaddr) && |
1677 | bond_has_slaves(bond)) | 1687 | 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", | 1688 | 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", |
@@ -1769,7 +1779,8 @@ static int __bond_release_one(struct net_device *bond_dev, | |||
1769 | /* close slave before restoring its mac address */ | 1779 | /* close slave before restoring its mac address */ |
1770 | dev_close(slave_dev); | 1780 | dev_close(slave_dev); |
1771 | 1781 | ||
1772 | if (bond->params.fail_over_mac != BOND_FOM_ACTIVE) { | 1782 | if (bond->params.fail_over_mac != BOND_FOM_ACTIVE || |
1783 | bond->params.mode != BOND_MODE_ACTIVEBACKUP) { | ||
1773 | /* restore original ("permanent") mac address */ | 1784 | /* restore original ("permanent") mac address */ |
1774 | memcpy(addr.sa_data, slave->perm_hwaddr, ETH_ALEN); | 1785 | memcpy(addr.sa_data, slave->perm_hwaddr, ETH_ALEN); |
1775 | addr.sa_family = slave_dev->type; | 1786 | addr.sa_family = slave_dev->type; |
@@ -2857,9 +2868,12 @@ static int bond_slave_netdev_event(unsigned long event, | |||
2857 | pr_info("%s: Primary slave changed to %s, reselecting active slave.\n", | 2868 | pr_info("%s: Primary slave changed to %s, reselecting active slave.\n", |
2858 | bond->dev->name, bond->primary_slave ? slave_dev->name : | 2869 | bond->dev->name, bond->primary_slave ? slave_dev->name : |
2859 | "none"); | 2870 | "none"); |
2871 | |||
2872 | block_netpoll_tx(); | ||
2860 | write_lock_bh(&bond->curr_slave_lock); | 2873 | write_lock_bh(&bond->curr_slave_lock); |
2861 | bond_select_active_slave(bond); | 2874 | bond_select_active_slave(bond); |
2862 | write_unlock_bh(&bond->curr_slave_lock); | 2875 | write_unlock_bh(&bond->curr_slave_lock); |
2876 | unblock_netpoll_tx(); | ||
2863 | break; | 2877 | break; |
2864 | case NETDEV_FEAT_CHANGE: | 2878 | case NETDEV_FEAT_CHANGE: |
2865 | bond_compute_features(bond); | 2879 | bond_compute_features(bond); |
@@ -3431,7 +3445,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. | 3445 | /* If fail_over_mac is enabled, do nothing and return success. |
3432 | * Returning an error causes ifenslave to fail. | 3446 | * Returning an error causes ifenslave to fail. |
3433 | */ | 3447 | */ |
3434 | if (bond->params.fail_over_mac) | 3448 | if (bond->params.fail_over_mac && |
3449 | bond->params.mode == BOND_MODE_ACTIVEBACKUP) | ||
3435 | return 0; | 3450 | return 0; |
3436 | 3451 | ||
3437 | if (!is_valid_ether_addr(sa->sa_data)) | 3452 | if (!is_valid_ether_addr(sa->sa_data)) |
@@ -3692,7 +3707,7 @@ static inline int bond_slave_override(struct bonding *bond, | |||
3692 | 3707 | ||
3693 | 3708 | ||
3694 | static u16 bond_select_queue(struct net_device *dev, struct sk_buff *skb, | 3709 | static u16 bond_select_queue(struct net_device *dev, struct sk_buff *skb, |
3695 | void *accel_priv) | 3710 | void *accel_priv, select_queue_fallback_t fallback) |
3696 | { | 3711 | { |
3697 | /* | 3712 | /* |
3698 | * This helper function exists to help dev_pick_tx get the correct | 3713 | * 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/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..320bef2dba42 100644 --- a/drivers/net/can/flexcan.c +++ b/drivers/net/can/flexcan.c | |||
@@ -235,9 +235,12 @@ static const struct can_bittiming_const flexcan_bittiming_const = { | |||
235 | }; | 235 | }; |
236 | 236 | ||
237 | /* | 237 | /* |
238 | * Abstract off the read/write for arm versus ppc. | 238 | * Abstract off the read/write for arm versus ppc. This |
239 | * assumes that PPC uses big-endian registers and everything | ||
240 | * else uses little-endian registers, independent of CPU | ||
241 | * endianess. | ||
239 | */ | 242 | */ |
240 | #if defined(__BIG_ENDIAN) | 243 | #if defined(CONFIG_PPC) |
241 | static inline u32 flexcan_read(void __iomem *addr) | 244 | static inline u32 flexcan_read(void __iomem *addr) |
242 | { | 245 | { |
243 | return in_be32(addr); | 246 | return in_be32(addr); |
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/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..66c0df78c3ff 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) |
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..3167ed6593b0 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) |
@@ -14113,12 +14114,12 @@ static int tg3_change_mtu(struct net_device *dev, int new_mtu) | |||
14113 | 14114 | ||
14114 | tg3_netif_stop(tp); | 14115 | tg3_netif_stop(tp); |
14115 | 14116 | ||
14117 | tg3_set_mtu(dev, tp, new_mtu); | ||
14118 | |||
14116 | tg3_full_lock(tp, 1); | 14119 | tg3_full_lock(tp, 1); |
14117 | 14120 | ||
14118 | tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); | 14121 | tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); |
14119 | 14122 | ||
14120 | tg3_set_mtu(dev, tp, new_mtu); | ||
14121 | |||
14122 | /* Reset PHY, otherwise the read DMA engine will be in a mode that | 14123 | /* Reset PHY, otherwise the read DMA engine will be in a mode that |
14123 | * breaks all requests to 256 bytes. | 14124 | * breaks all requests to 256 bytes. |
14124 | */ | 14125 | */ |
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/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..903362a7b584 100644 --- a/drivers/net/ethernet/freescale/fec_main.c +++ b/drivers/net/ethernet/freescale/fec_main.c | |||
@@ -1778,8 +1778,6 @@ fec_enet_open(struct net_device *ndev) | |||
1778 | struct fec_enet_private *fep = netdev_priv(ndev); | 1778 | struct fec_enet_private *fep = netdev_priv(ndev); |
1779 | int ret; | 1779 | int ret; |
1780 | 1780 | ||
1781 | napi_enable(&fep->napi); | ||
1782 | |||
1783 | /* I should reset the ring buffers here, but I don't yet know | 1781 | /* I should reset the ring buffers here, but I don't yet know |
1784 | * a simple way to do that. | 1782 | * a simple way to do that. |
1785 | */ | 1783 | */ |
@@ -1794,6 +1792,8 @@ fec_enet_open(struct net_device *ndev) | |||
1794 | fec_enet_free_buffers(ndev); | 1792 | fec_enet_free_buffers(ndev); |
1795 | return ret; | 1793 | return ret; |
1796 | } | 1794 | } |
1795 | |||
1796 | napi_enable(&fep->napi); | ||
1797 | phy_start(fep->phy_dev); | 1797 | phy_start(fep->phy_dev); |
1798 | netif_start_queue(ndev); | 1798 | netif_start_queue(ndev); |
1799 | fep->opened = 1; | 1799 | 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_en.h b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h index 3af04c3f42ea..9ca223bc90fc 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h +++ b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h | |||
@@ -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/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/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_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..651087b5c8da 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, |
@@ -1878,14 +1878,29 @@ static int cpsw_probe_dt(struct cpsw_platform_data *data, | |||
1878 | mdio_node = of_find_node_by_phandle(be32_to_cpup(parp)); | 1878 | mdio_node = of_find_node_by_phandle(be32_to_cpup(parp)); |
1879 | phyid = be32_to_cpup(parp+1); | 1879 | phyid = be32_to_cpup(parp+1); |
1880 | mdio = of_find_device_by_node(mdio_node); | 1880 | mdio = of_find_device_by_node(mdio_node); |
1881 | snprintf(slave_data->phy_id, sizeof(slave_data->phy_id), | 1881 | |
1882 | PHY_ID_FMT, mdio->name, phyid); | 1882 | if (strncmp(mdio->name, "gpio", 4) == 0) { |
1883 | /* GPIO bitbang MDIO driver attached */ | ||
1884 | struct mii_bus *bus = dev_get_drvdata(&mdio->dev); | ||
1885 | |||
1886 | snprintf(slave_data->phy_id, sizeof(slave_data->phy_id), | ||
1887 | PHY_ID_FMT, bus->id, phyid); | ||
1888 | } else { | ||
1889 | /* davinci MDIO driver attached */ | ||
1890 | snprintf(slave_data->phy_id, sizeof(slave_data->phy_id), | ||
1891 | PHY_ID_FMT, mdio->name, phyid); | ||
1892 | } | ||
1883 | 1893 | ||
1884 | mac_addr = of_get_mac_address(slave_node); | 1894 | mac_addr = of_get_mac_address(slave_node); |
1885 | if (mac_addr) | 1895 | if (mac_addr) |
1886 | memcpy(slave_data->mac_addr, mac_addr, ETH_ALEN); | 1896 | memcpy(slave_data->mac_addr, mac_addr, ETH_ALEN); |
1887 | 1897 | ||
1888 | slave_data->phy_if = of_get_phy_mode(slave_node); | 1898 | slave_data->phy_if = of_get_phy_mode(slave_node); |
1899 | if (slave_data->phy_if < 0) { | ||
1900 | pr_err("Missing or malformed slave[%d] phy-mode property\n", | ||
1901 | i); | ||
1902 | return slave_data->phy_if; | ||
1903 | } | ||
1889 | 1904 | ||
1890 | if (data->dual_emac) { | 1905 | if (data->dual_emac) { |
1891 | if (of_property_read_u32(slave_node, "dual_emac_res_vlan", | 1906 | 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..a5d21893670d 100644 --- a/drivers/net/macvlan.c +++ b/drivers/net/macvlan.c | |||
@@ -879,14 +879,15 @@ int macvlan_common_newlink(struct net *src_net, struct net_device *dev, | |||
879 | dev->priv_flags |= IFF_MACVLAN; | 879 | dev->priv_flags |= IFF_MACVLAN; |
880 | err = netdev_upper_dev_link(lowerdev, dev); | 880 | err = netdev_upper_dev_link(lowerdev, dev); |
881 | if (err) | 881 | if (err) |
882 | goto destroy_port; | 882 | goto unregister_netdev; |
883 | |||
884 | 883 | ||
885 | list_add_tail_rcu(&vlan->list, &port->vlans); | 884 | list_add_tail_rcu(&vlan->list, &port->vlans); |
886 | netif_stacked_transfer_operstate(lowerdev, dev); | 885 | netif_stacked_transfer_operstate(lowerdev, dev); |
887 | 886 | ||
888 | return 0; | 887 | return 0; |
889 | 888 | ||
889 | unregister_netdev: | ||
890 | unregister_netdevice(dev); | ||
890 | destroy_port: | 891 | destroy_port: |
891 | port->count -= 1; | 892 | port->count -= 1; |
892 | if (!port->count) | 893 | 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..82514e72b3d8 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 | ||
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..8fe9cb7d0f72 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; |
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..955df81a4358 100644 --- a/drivers/net/usb/ax88179_178a.c +++ b/drivers/net/usb/ax88179_178a.c | |||
@@ -1118,6 +1118,10 @@ static int ax88179_rx_fixup(struct usbnet *dev, struct sk_buff *skb) | |||
1118 | u16 hdr_off; | 1118 | u16 hdr_off; |
1119 | u32 *pkt_hdr; | 1119 | u32 *pkt_hdr; |
1120 | 1120 | ||
1121 | /* This check is no longer done by usbnet */ | ||
1122 | if (skb->len < dev->net->hard_header_len) | ||
1123 | return 0; | ||
1124 | |||
1121 | skb_trim(skb, skb->len - 4); | 1125 | skb_trim(skb, skb->len - 4); |
1122 | memcpy(&rx_hdr, skb_tail_pointer(skb), 4); | 1126 | memcpy(&rx_hdr, skb_tail_pointer(skb), 4); |
1123 | le32_to_cpus(&rx_hdr); | 1127 | le32_to_cpus(&rx_hdr); |
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/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/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..11eab9f01fd8 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 | ||
@@ -2051,9 +2051,8 @@ static bool ath9k_hw_set_power_awake(struct ath_hw *ah) | |||
2051 | 2051 | ||
2052 | REG_SET_BIT(ah, AR_RTC_FORCE_WAKE, | 2052 | REG_SET_BIT(ah, AR_RTC_FORCE_WAKE, |
2053 | AR_RTC_FORCE_WAKE_EN); | 2053 | AR_RTC_FORCE_WAKE_EN); |
2054 | |||
2055 | if (AR_SREV_9100(ah)) | 2054 | if (AR_SREV_9100(ah)) |
2056 | udelay(10000); | 2055 | mdelay(10); |
2057 | else | 2056 | else |
2058 | udelay(50); | 2057 | udelay(50); |
2059 | 2058 | ||
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/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/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/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..4df12fa9d336 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); | 709 | } |
705 | sta = rcu_dereference(mvm->fw_id_to_mac_id[sta_id]); | 710 | |
706 | if (!sta || PTR_ERR(sta) == -EBUSY) { | 711 | if (PTR_ERR(sta) == -EBUSY || PTR_ERR(sta) == -ENOENT) { |
707 | /* | 712 | /* |
708 | * Station disappeared in the meantime: | 713 | * We are draining and this was the last packet - pre_rcu_remove |
709 | * so we are draining. | 714 | * has been called already. We might be after the |
710 | */ | 715 | * synchronize_net already. |
711 | set_bit(sta_id, mvm->sta_drained); | 716 | * Don't rely on iwl_mvm_rm_sta to see the empty Tx queues. |
712 | schedule_work(&mvm->sta_drained_wk); | 717 | */ |
713 | } | 718 | set_bit(sta_id, mvm->sta_drained); |
714 | spin_unlock_bh(&mvmsta->lock); | 719 | schedule_work(&mvm->sta_drained_wk); |
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 | } | 720 | } |
721 | 721 | ||
722 | out: | ||
722 | rcu_read_unlock(); | 723 | rcu_read_unlock(); |
723 | } | 724 | } |
724 | 725 | ||
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/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/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..f9daa9e183f2 100644 --- a/drivers/net/xen-netfront.c +++ b/drivers/net/xen-netfront.c | |||
@@ -1832,7 +1832,6 @@ static void netback_changed(struct xenbus_device *dev, | |||
1832 | case XenbusStateReconfiguring: | 1832 | case XenbusStateReconfiguring: |
1833 | case XenbusStateReconfigured: | 1833 | case XenbusStateReconfigured: |
1834 | case XenbusStateUnknown: | 1834 | case XenbusStateUnknown: |
1835 | case XenbusStateClosed: | ||
1836 | break; | 1835 | break; |
1837 | 1836 | ||
1838 | case XenbusStateInitWait: | 1837 | case XenbusStateInitWait: |
@@ -1847,6 +1846,10 @@ static void netback_changed(struct xenbus_device *dev, | |||
1847 | netdev_notify_peers(netdev); | 1846 | netdev_notify_peers(netdev); |
1848 | break; | 1847 | break; |
1849 | 1848 | ||
1849 | case XenbusStateClosed: | ||
1850 | if (dev->state == XenbusStateClosed) | ||
1851 | break; | ||
1852 | /* Missed the backend's CLOSING state -- fallthrough */ | ||
1850 | case XenbusStateClosing: | 1853 | case XenbusStateClosing: |
1851 | xenbus_frontend_closed(dev); | 1854 | xenbus_frontend_closed(dev); |
1852 | break; | 1855 | break; |