Pull networking updates from David Miller: "Here is my initial pull request for the networking subsystem during this merge window: 1) Support for ESN in AH (RFC 4302) from Fan Du. 2) Add full kernel doc for ethtool command structures, from Ben Hutchings. 3) Add BCM7xxx PHY driver, from Florian Fainelli. 4) Export computed TCP rate information in netlink socket dumps, from Eric Dumazet. 5) Allow IPSEC SA to be dumped partially using a filter, from Nicolas Dichtel. 6) Convert many drivers to pci_enable_msix_range(), from Alexander Gordeev. 7) Record SKB timestamps more efficiently, from Eric Dumazet. 8) Switch to microsecond resolution for TCP round trip times, also from Eric Dumazet. 9) Clean up and fix 6lowpan fragmentation handling by making use of the existing inet_frag api for it's implementation. 10) Add TX grant mapping to xen-netback driver, from Zoltan Kiss. 11) Auto size SKB lengths when composing netlink messages based upon past message sizes used, from Eric Dumazet. 12) qdisc dumps can take a long time, add a cond_resched(), From Eric Dumazet. 13) Sanitize netpoll core and drivers wrt. SKB handling semantics. Get rid of never-used-in-tree netpoll RX handling. From Eric W Biederman. 14) Support inter-address-family and namespace changing in VTI tunnel driver(s). From Steffen Klassert. 15) Add Altera TSE driver, from Vince Bridgers. 16) Optimizing csum_replace2() so that it doesn't adjust the checksum by checksumming the entire header, from Eric Dumazet. 17) Expand BPF internal implementation for faster interpreting, more direct translations into JIT'd code, and much cleaner uses of BPF filtering in non-socket ocntexts. From Daniel Borkmann and Alexei Starovoitov" * git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next: (1976 commits) netpoll: Use skb_irq_freeable to make zap_completion_queue safe. net: Add a test to see if a skb is freeable in irq context qlcnic: Fix build failure due to undefined reference to `vxlan_get_rx_port' net: ptp: move PTP classifier in its own file net: sxgbe: make "core_ops" static net: sxgbe: fix logical vs bitwise operation net: sxgbe: sxgbe_mdio_register() frees the bus Call efx_set_channels() before efx->type->dimension_resources() xen-netback: disable rogue vif in kthread context net/mlx4: Set proper build dependancy with vxlan be2net: fix build dependency on VxLAN mac802154: make csma/cca parameters per-wpan mac802154: allow only one WPAN to be up at any given time net: filter: minor: fix kdoc in __sk_run_filter netlink: don't compare the nul-termination in nla_strcmp can: c_can: Avoid led toggling for every packet. can: c_can: Simplify TX interrupt cleanup can: c_can: Store dlc private can: c_can: Reduce register access can: c_can: Make the code readable ...
Unified · Split
| @@ -7,3 +7,23 @@ Description: · 6 unmodified lines | |||
| 7 | by the device during bus enumeration, encoded in hexadecimal. | 7 | by the device during bus enumeration, encoded in hexadecimal. |
| 8 | This ID is used to match the device with the appropriate | 8 | This ID is used to match the device with the appropriate |
| 9 | driver. | 9 | driver. |
| 10 | |||
| 11 | What: /sys/bus/mdio_bus/devices/.../phy_interface | ||
| 12 | Date: February 2014 | ||
| 13 | KernelVersion: 3.15 | ||
| 14 | Contact: netdev@vger.kernel.org | ||
| 15 | Description: | ||
| 16 | This attribute contains the PHY interface as configured by the | ||
| 17 | Ethernet driver during bus enumeration, encoded in string. | ||
| 18 | This interface mode is used to configure the Ethernet MAC with the | ||
| 19 | appropriate mode for its data lines to the PHY hardware. | ||
| 20 | |||
| 21 | What: /sys/bus/mdio_bus/devices/.../phy_has_fixups | ||
| 22 | Date: February 2014 | ||
| 23 | KernelVersion: 3.15 | ||
| 24 | Contact: netdev@vger.kernel.org | ||
| 25 | Description: | ||
| 26 | This attribute contains the boolean value whether a given PHY | ||
| 27 | device has had any "fixup" workaround running on it, encoded as | ||
| 28 | a boolean. This information is provided to help troubleshooting | ||
| 29 | PHY configurations. | ||
| @@ -0,0 +1,199 @@ | |||
| 1 | What: /sys/class/net/<iface>/addr_assign_type | ||
| 2 | Date: July 2010 | ||
| 3 | KernelVersion: 3.2 | ||
| 4 | Contact: netdev@vger.kernel.org | ||
| 5 | Description: | ||
| 6 | Indicates the address assignment type. Possible values are: | ||
| 7 | 0: permanent address | ||
| 8 | 1: randomly generated | ||
| 9 | 2: stolen from another device | ||
| 10 | 3: set using dev_set_mac_address | ||
| 11 | |||
| 12 | What: /sys/class/net/<iface>/addr_len | ||
| 13 | Date: April 2005 | ||
| 14 | KernelVersion: 2.6.12 | ||
| 15 | Contact: netdev@vger.kernel.org | ||
| 16 | Description: | ||
| 17 | Indicates the hardware address size in bytes. | ||
| 18 | Values vary based on the lower-level protocol used by the | ||
| 19 | interface (Ethernet, FDDI, ATM, IEEE 802.15.4...). See | ||
| 20 | include/uapi/linux/if_*.h for actual values. | ||
| 21 | |||
| 22 | What: /sys/class/net/<iface>/address | ||
| 23 | Date: April 2005 | ||
| 24 | KernelVersion: 2.6.12 | ||
| 25 | Contact: netdev@vger.kernel.org | ||
| 26 | Description: | ||
| 27 | Hardware address currently assigned to this interface. | ||
| 28 | Format is a string, e.g: 00:11:22:33:44:55 for an Ethernet MAC | ||
| 29 | address. | ||
| 30 | |||
| 31 | What: /sys/class/net/<iface>/broadcast | ||
| 32 | Date: April 2005 | ||
| 33 | KernelVersion: 2.6.12 | ||
| 34 | Contact: netdev@vger.kernel.org | ||
| 35 | Description: | ||
| 36 | Hardware broadcast address for this interface. Format is a | ||
| 37 | string, e.g: ff:ff:ff:ff:ff:ff for an Ethernet broadcast MAC | ||
| 38 | address. | ||
| 39 | |||
| 40 | What: /sys/class/net/<iface>/carrier | ||
| 41 | Date: April 2005 | ||
| 42 | KernelVersion: 2.6.12 | ||
| 43 | Contact: netdev@vger.kernel.org | ||
| 44 | Description: | ||
| 45 | Indicates the current physical link state of the interface. | ||
| 46 | Posssible values are: | ||
| 47 | 0: physical link is down | ||
| 48 | 1: physical link is up | ||
| 49 | |||
| 50 | Note: some special devices, e.g: bonding and team drivers will | ||
| 51 | allow this attribute to be written to force a link state for | ||
| 52 | operating correctly and designating another fallback interface. | ||
| 53 | |||
| 54 | What: /sys/class/net/<iface>/dev_id | ||
| 55 | Date: April 2008 | ||
| 56 | KernelVersion: 2.6.26 | ||
| 57 | Contact: netdev@vger.kernel.org | ||
| 58 | Description: | ||
| 59 | Indicates the device unique identifier. Format is an hexadecimal | ||
| 60 | value. This is used to disambiguate interfaces which might be | ||
| 61 | stacked (e.g: VLAN interfaces) but still have the same MAC | ||
| 62 | address as their parent device. | ||
| 63 | |||
| 64 | What: /sys/class/net/<iface>/dormant | ||
| 65 | Date: March 2006 | ||
| 66 | KernelVersion: 2.6.17 | ||
| 67 | Contact: netdev@vger.kernel.org | ||
| 68 | Description: | ||
| 69 | Indicates whether the interface is in dormant state. Possible | ||
| 70 | values are: | ||
| 71 | 0: interface is not dormant | ||
| 72 | 1: interface is dormant | ||
| 73 | |||
| 74 | This attribute can be used by supplicant software to signal that | ||
| 75 | the device is not usable unless some supplicant-based | ||
| 76 | authentication is performed (e.g: 802.1x). 'link_mode' attribute | ||
| 77 | will also reflect the dormant state. | ||
| 78 | |||
| 79 | What: /sys/clas/net/<iface>/duplex | ||
| 80 | Date: October 2009 | ||
| 81 | KernelVersion: 2.6.33 | ||
| 82 | Contact: netdev@vger.kernel.org | ||
| 83 | Description: | ||
| 84 | Indicates the interface latest or current duplex value. Possible | ||
| 85 | values are: | ||
| 86 | half: half duplex | ||
| 87 | full: full duplex | ||
| 88 | |||
| 89 | Note: This attribute is only valid for interfaces that implement | ||
| 90 | the ethtool get_settings method (mostly Ethernet). | ||
| 91 | |||
| 92 | What: /sys/class/net/<iface>/flags | ||
| 93 | Date: April 2005 | ||
| 94 | KernelVersion: 2.6.12 | ||
| 95 | Contact: netdev@vger.kernel.org | ||
| 96 | Description: | ||
| 97 | Indicates the interface flags as a bitmask in hexadecimal. See | ||
| 98 | include/uapi/linux/if.h for a list of all possible values and | ||
| 99 | the flags semantics. | ||
| 100 | |||
| 101 | What: /sys/class/net/<iface>/ifalias | ||
| 102 | Date: September 2008 | ||
| 103 | KernelVersion: 2.6.28 | ||
| 104 | Contact: netdev@vger.kernel.org | ||
| 105 | Description: | ||
| 106 | Indicates/stores an interface alias name as a string. This can | ||
| 107 | be used for system management purposes. | ||
| 108 | |||
| 109 | What: /sys/class/net/<iface>/ifindex | ||
| 110 | Date: April 2005 | ||
| 111 | KernelVersion: 2.6.12 | ||
| 112 | Contact: netdev@vger.kernel.org | ||
| 113 | Description: | ||
| 114 | Indicates the system-wide interface unique index identifier as a | ||
| 115 | decimal number. This attribute is used for mapping an interface | ||
| 116 | identifier to an interface name. It is used throughout the | ||
| 117 | networking stack for specifying the interface specific | ||
| 118 | requests/events. | ||
| 119 | |||
| 120 | What: /sys/class/net/<iface>/iflink | ||
| 121 | Date: April 2005 | ||
| 122 | KernelVersion: 2.6.12 | ||
| 123 | Contact: netdev@vger.kernel.org | ||
| 124 | Description: | ||
| 125 | Indicates the system-wide interface unique index identifier a | ||
| 126 | the interface is linked to. Format is decimal. This attribute is | ||
| 127 | used to resolve interfaces chaining, linking and stacking. | ||
| 128 | Physical interfaces have the same 'ifindex' and 'iflink' values. | ||
| 129 | |||
| 130 | What: /sys/class/net/<iface>/link_mode | ||
| 131 | Date: March 2006 | ||
| 132 | KernelVersion: 2.6.17 | ||
| 133 | Contact: netdev@vger.kernel.org | ||
| 134 | Description: | ||
| 135 | Indicates the interface link mode, as a decimal number. This | ||
| 136 | attribute should be used in conjunction with 'dormant' attribute | ||
| 137 | to determine the interface usability. Possible values: | ||
| 138 | 0: default link mode | ||
| 139 | 1: dormant link mode | ||
| 140 | |||
| 141 | What: /sys/class/net/<iface>/mtu | ||
| 142 | Date: April 2005 | ||
| 143 | KernelVersion: 2.6.12 | ||
| 144 | Contact: netdev@vger.kernel.org | ||
| 145 | Description: | ||
| 146 | Indicates the interface currently configured MTU value, in | ||
| 147 | bytes, and in decimal format. Specific values depends on the | ||
| 148 | lower-level interface protocol used. Ethernet devices will show | ||
| 149 | a 'mtu' attribute value of 1500 unless changed. | ||
| 150 | |||
| 151 | What: /sys/calss/net/<iface>/netdev_group | ||
| 152 | Date: January 2011 | ||
| 153 | KernelVersion: 2.6.39 | ||
| 154 | Contact: netdev@vger.kernel.org | ||
| 155 | Description: | ||
| 156 | Indicates the interface network device group, as a decimal | ||
| 157 | integer. Default value is 0 which corresponds to the initial | ||
| 158 | network devices group. The group can be changed to affect | ||
| 159 | routing decisions (see: net/ipv4/fib_rules and | ||
| 160 | net/ipv6/fib6_rules.c). | ||
| 161 | |||
| 162 | What: /sys/class/net/<iface>/operstate | ||
| 163 | Date: March 2006 | ||
| 164 | KernelVersion: 2.6.17 | ||
| 165 | Contact: netdev@vger.kernel.org | ||
| 166 | Description: | ||
| 167 | Indicates the interface RFC2863 operational state as a string. | ||
| 168 | Possible values are: | ||
| 169 | "unknown", "notpresent", "down", "lowerlayerdown", "testing", | ||
| 170 | "dormant", "up". | ||
| 171 | |||
| 172 | What: /sys/class/net/<iface>/speed | ||
| 173 | Date: October 2009 | ||
| 174 | KernelVersion: 2.6.33 | ||
| 175 | Contact: netdev@vger.kernel.org | ||
| 176 | Description: | ||
| 177 | Indicates the interface latest or current speed value. Value is | ||
| 178 | an integer representing the link speed in Mbits/sec. | ||
| 179 | |||
| 180 | Note: this attribute is only valid for interfaces that implement | ||
| 181 | the ethtool get_settings method (mostly Ethernet ). | ||
| 182 | |||
| 183 | What: /sys/class/net/<iface>/tx_queue_len | ||
| 184 | Date: April 2005 | ||
| 185 | KernelVersion: 2.6.12 | ||
| 186 | Contact: netdev@vger.kernel.org | ||
| 187 | Description: | ||
| 188 | Indicates the interface transmit queue len in number of packets, | ||
| 189 | as an integer value. Value depend on the type of interface, | ||
| 190 | Ethernet network adapters have a default value of 1000 unless | ||
| 191 | configured otherwise | ||
| 192 | |||
| 193 | What: /sys/class/net/<iface>/type | ||
| 194 | Date: April 2005 | ||
| 195 | KernelVersion: 2.6.12 | ||
| 196 | Contact: netdev@vger.kernel.org | ||
| 197 | Description: | ||
| 198 | Indicates the interface protocol type as a decimal value. See | ||
| 199 | include/uapi/linux/if_arp.h for all possible values. | ||
| @@ -76,6 +76,15 @@ Description: · 75 unmodified lines | |||
| 76 | is used to classify clients as "isolated" by the | 76 | is used to classify clients as "isolated" by the |
| 77 | Extended Isolation feature. | 77 | Extended Isolation feature. |
| 78 | 78 | ||
| 79 | What: /sys/class/net/<mesh_iface>/mesh/multicast_mode | ||
| 80 | Date: Feb 2014 | ||
| 81 | Contact: Linus Lüssing <linus.luessing@web.de> | ||
| 82 | Description: | ||
| 83 | Indicates whether multicast optimizations are enabled | ||
| 84 | or disabled. If set to zero then all nodes in the | ||
| 85 | mesh are going to use classic flooding for any | ||
| 86 | multicast packet with no optimizations. | ||
| 87 | |||
| 79 | What: /sys/class/net/<mesh_iface>/mesh/network_coding | 88 | What: /sys/class/net/<mesh_iface>/mesh/network_coding |
| 80 | Date: Nov 2012 | 89 | Date: Nov 2012 |
| 81 | Contact: Martin Hundeboll <martin@hundeboll.net> | 90 | Contact: Martin Hundeboll <martin@hundeboll.net> |
| @@ -54,6 +54,26 @@ Description: · 53 unmodified lines | |||
| 54 | This file contains the number of programmable periodic | 54 | This file contains the number of programmable periodic |
| 55 | output channels offered by the PTP hardware clock. | 55 | output channels offered by the PTP hardware clock. |
| 56 | 56 | ||
| 57 | What: /sys/class/ptp/ptpN/n_pins | ||
| 58 | Date: March 2014 | ||
| 59 | Contact: Richard Cochran <richardcochran@gmail.com> | ||
| 60 | Description: | ||
| 61 | This file contains the number of programmable pins | ||
| 62 | offered by the PTP hardware clock. | ||
| 63 | |||
| 64 | What: /sys/class/ptp/ptpN/pins | ||
| 65 | Date: March 2014 | ||
| 66 | Contact: Richard Cochran <richardcochran@gmail.com> | ||
| 67 | Description: | ||
| 68 | This directory contains one file for each programmable | ||
| 69 | pin offered by the PTP hardware clock. The file name | ||
| 70 | is the hardware dependent pin name. Reading from this | ||
| 71 | file produces two numbers, the assigned function (see | ||
| 72 | the PTP_PF_ enumeration values in linux/ptp_clock.h) | ||
| 73 | and the channel number. The function and channel | ||
| 74 | assignment may be changed by two writing numbers into | ||
| 75 | the file. | ||
| 76 | |||
| 57 | What: /sys/class/ptp/ptpN/pps_avaiable | 77 | What: /sys/class/ptp/ptpN/pps_avaiable |
| 58 | Date: September 2010 | 78 | Date: September 2010 |
| 59 | Contact: Richard Cochran <richardcochran@gmail.com> | 79 | Contact: Richard Cochran <richardcochran@gmail.com> |
| @@ -98,6 +98,8 @@ · 97 unmodified lines | |||
| 98 | !Finclude/net/cfg80211.h priv_to_wiphy | 98 | !Finclude/net/cfg80211.h priv_to_wiphy |
| 99 | !Finclude/net/cfg80211.h set_wiphy_dev | 99 | !Finclude/net/cfg80211.h set_wiphy_dev |
| 100 | !Finclude/net/cfg80211.h wdev_priv | 100 | !Finclude/net/cfg80211.h wdev_priv |
| 101 | !Finclude/net/cfg80211.h ieee80211_iface_limit | ||
| 102 | !Finclude/net/cfg80211.h ieee80211_iface_combination | ||
| 101 | </chapter> | 103 | </chapter> |
| 102 | <chapter> | 104 | <chapter> |
| 103 | <title>Actions and configuration</title> | 105 | <title>Actions and configuration</title> |
| @@ -353,6 +353,7 @@ Your cooperation is appreciated. · 352 unmodified lines | |||
| 353 | 133 = /dev/exttrp External device trap | 353 | 133 = /dev/exttrp External device trap |
| 354 | 134 = /dev/apm_bios Advanced Power Management BIOS | 354 | 134 = /dev/apm_bios Advanced Power Management BIOS |
| 355 | 135 = /dev/rtc Real Time Clock | 355 | 135 = /dev/rtc Real Time Clock |
| 356 | 137 = /dev/vhci Bluetooth virtual HCI driver | ||
| 356 | 139 = /dev/openprom SPARC OpenBoot PROM | 357 | 139 = /dev/openprom SPARC OpenBoot PROM |
| 357 | 140 = /dev/relay8 Berkshire Products Octal relay card | 358 | 140 = /dev/relay8 Berkshire Products Octal relay card |
| 358 | 141 = /dev/relay16 Berkshire Products ISO-16 relay card | 359 | 141 = /dev/relay16 Berkshire Products ISO-16 relay card |
| @@ -5,13 +5,9 @@ Required properties: · 4 unmodified lines | |||
| 5 | "allwinner,sun4i-emac") | 5 | "allwinner,sun4i-emac") |
| 6 | - reg: address and length of the register set for the device. | 6 | - reg: address and length of the register set for the device. |
| 7 | - interrupts: interrupt for the device | 7 | - interrupts: interrupt for the device |
| 8 | - phy: A phandle to a phy node defining the PHY address (as the reg | 8 | - phy: see ethernet.txt file in the same directory. |
| 9 | property, a single integer). | ||
| 10 | - clocks: A phandle to the reference clock for this device | 9 | - clocks: A phandle to the reference clock for this device |
| 11 | 10 | ||
| 12 | Optional properties: | ||
| 13 | - (local-)mac-address: mac address to be used by this driver | ||
| 14 | |||
| 15 | Example: | 11 | Example: |
| 16 | 12 | ||
| 17 | emac: ethernet@01c0b000 { | 13 | emac: ethernet@01c0b000 { |
| @@ -0,0 +1,114 @@ | |||
| 1 | * Altera Triple-Speed Ethernet MAC driver (TSE) | ||
| 2 | |||
| 3 | Required properties: | ||
| 4 | - compatible: Should be "altr,tse-1.0" for legacy SGDMA based TSE, and should | ||
| 5 | be "altr,tse-msgdma-1.0" for the preferred MSGDMA based TSE. | ||
| 6 | ALTR is supported for legacy device trees, but is deprecated. | ||
| 7 | altr should be used for all new designs. | ||
| 8 | - reg: Address and length of the register set for the device. It contains | ||
| 9 | the information of registers in the same order as described by reg-names | ||
| 10 | - reg-names: Should contain the reg names | ||
| 11 | "control_port": MAC configuration space region | ||
| 12 | "tx_csr": xDMA Tx dispatcher control and status space region | ||
| 13 | "tx_desc": MSGDMA Tx dispatcher descriptor space region | ||
| 14 | "rx_csr" : xDMA Rx dispatcher control and status space region | ||
| 15 | "rx_desc": MSGDMA Rx dispatcher descriptor space region | ||
| 16 | "rx_resp": MSGDMA Rx dispatcher response space region | ||
| 17 | "s1": SGDMA descriptor memory | ||
| 18 | - interrupts: Should contain the TSE interrupts and it's mode. | ||
| 19 | - interrupt-names: Should contain the interrupt names | ||
| 20 | "rx_irq": xDMA Rx dispatcher interrupt | ||
| 21 | "tx_irq": xDMA Tx dispatcher interrupt | ||
| 22 | - rx-fifo-depth: MAC receive FIFO buffer depth in bytes | ||
| 23 | - tx-fifo-depth: MAC transmit FIFO buffer depth in bytes | ||
| 24 | - phy-mode: See ethernet.txt in the same directory. | ||
| 25 | - phy-handle: See ethernet.txt in the same directory. | ||
| 26 | - phy-addr: See ethernet.txt in the same directory. A configuration should | ||
| 27 | include phy-handle or phy-addr. | ||
| 28 | - altr,has-supplementary-unicast: | ||
| 29 | If present, TSE supports additional unicast addresses. | ||
| 30 | Otherwise additional unicast addresses are not supported. | ||
| 31 | - altr,has-hash-multicast-filter: | ||
| 32 | If present, TSE supports a hash based multicast filter. | ||
| 33 | Otherwise, hash-based multicast filtering is not supported. | ||
| 34 | |||
| 35 | - mdio device tree subnode: When the TSE has a phy connected to its local | ||
| 36 | mdio, there must be device tree subnode with the following | ||
| 37 | required properties: | ||
| 38 | |||
| 39 | - compatible: Must be "altr,tse-mdio". | ||
| 40 | - #address-cells: Must be <1>. | ||
| 41 | - #size-cells: Must be <0>. | ||
| 42 | |||
| 43 | For each phy on the mdio bus, there must be a node with the following | ||
| 44 | fields: | ||
| 45 | |||
| 46 | - reg: phy id used to communicate to phy. | ||
| 47 | - device_type: Must be "ethernet-phy". | ||
| 48 | |||
| 49 | Optional properties: | ||
| 50 | - local-mac-address: See ethernet.txt in the same directory. | ||
| 51 | - max-frame-size: See ethernet.txt in the same directory. | ||
| 52 | |||
| 53 | Example: | ||
| 54 | |||
| 55 | tse_sub_0_eth_tse_0: ethernet@0x1,00000000 { | ||
| 56 | compatible = "altr,tse-msgdma-1.0"; | ||
| 57 | reg = <0x00000001 0x00000000 0x00000400>, | ||
| 58 | <0x00000001 0x00000460 0x00000020>, | ||
| 59 | <0x00000001 0x00000480 0x00000020>, | ||
| 60 | <0x00000001 0x000004A0 0x00000008>, | ||
| 61 | <0x00000001 0x00000400 0x00000020>, | ||
| 62 | <0x00000001 0x00000420 0x00000020>; | ||
| 63 | reg-names = "control_port", "rx_csr", "rx_desc", "rx_resp", "tx_csr", "tx_desc"; | ||
| 64 | interrupt-parent = <&hps_0_arm_gic_0>; | ||
| 65 | interrupts = <0 41 4>, <0 40 4>; | ||
| 66 | interrupt-names = "rx_irq", "tx_irq"; | ||
| 67 | rx-fifo-depth = <2048>; | ||
| 68 | tx-fifo-depth = <2048>; | ||
| 69 | address-bits = <48>; | ||
| 70 | max-frame-size = <1500>; | ||
| 71 | local-mac-address = [ 00 00 00 00 00 00 ]; | ||
| 72 | phy-mode = "gmii"; | ||
| 73 | altr,has-supplementary-unicast; | ||
| 74 | altr,has-hash-multicast-filter; | ||
| 75 | phy-handle = <&phy0>; | ||
| 76 | mdio { | ||
| 77 | compatible = "altr,tse-mdio"; | ||
| 78 | #address-cells = <1>; | ||
| 79 | #size-cells = <0>; | ||
| 80 | phy0: ethernet-phy@0 { | ||
| 81 | reg = <0x0>; | ||
| 82 | device_type = "ethernet-phy"; | ||
| 83 | }; | ||
| 84 | |||
| 85 | phy1: ethernet-phy@1 { | ||
| 86 | reg = <0x1>; | ||
| 87 | device_type = "ethernet-phy"; | ||
| 88 | }; | ||
| 89 | |||
| 90 | }; | ||
| 91 | }; | ||
| 92 | |||
| 93 | tse_sub_1_eth_tse_0: ethernet@0x1,00001000 { | ||
| 94 | compatible = "altr,tse-msgdma-1.0"; | ||
| 95 | reg = <0x00000001 0x00001000 0x00000400>, | ||
| 96 | <0x00000001 0x00001460 0x00000020>, | ||
| 97 | <0x00000001 0x00001480 0x00000020>, | ||
| 98 | <0x00000001 0x000014A0 0x00000008>, | ||
| 99 | <0x00000001 0x00001400 0x00000020>, | ||
| 100 | <0x00000001 0x00001420 0x00000020>; | ||
| 101 | reg-names = "control_port", "rx_csr", "rx_desc", "rx_resp", "tx_csr", "tx_desc"; | ||
| 102 | interrupt-parent = <&hps_0_arm_gic_0>; | ||
| 103 | interrupts = <0 43 4>, <0 42 4>; | ||
| 104 | interrupt-names = "rx_irq", "tx_irq"; | ||
| 105 | rx-fifo-depth = <2048>; | ||
| 106 | tx-fifo-depth = <2048>; | ||
| 107 | address-bits = <48>; | ||
| 108 | max-frame-size = <1500>; | ||
| 109 | local-mac-address = [ 00 00 00 00 00 00 ]; | ||
| 110 | phy-mode = "gmii"; | ||
| 111 | altr,has-supplementary-unicast; | ||
| 112 | altr,has-hash-multicast-filter; | ||
| 113 | phy-handle = <&phy1>; | ||
| 114 | }; | ||
| @@ -6,19 +6,12 @@ Required properties: · 5 unmodified lines | |||
| 6 | - interrupts: Should contain the EMAC interrupts | 6 | - interrupts: Should contain the EMAC interrupts |
| 7 | - clock-frequency: CPU frequency. It is needed to calculate and set polling | 7 | - clock-frequency: CPU frequency. It is needed to calculate and set polling |
| 8 | period of EMAC. | 8 | period of EMAC. |
| 9 | - max-speed: Maximum supported data-rate in Mbit/s. In some HW configurations | 9 | - max-speed: see ethernet.txt file in the same directory. |
| 10 | bandwidth of external memory controller might be a limiting factor. That's why | 10 | - phy: see ethernet.txt file in the same directory. |
| 11 | it's required to specify which data-rate is supported on current SoC or FPGA. | ||
| 12 | For example if only 10 Mbit/s is supported (10BASE-T) set "10". If 100 Mbit/s is | ||
| 13 | supported (100BASE-TX) set "100". | ||
| 14 | - phy: PHY device attached to the EMAC via MDIO bus | ||
| 15 | 11 | ||
| 16 | Child nodes of the driver are the individual PHY devices connected to the | 12 | Child nodes of the driver are the individual PHY devices connected to the |
| 17 | MDIO bus. They must have a "reg" property given the PHY address on the MDIO bus. | 13 | MDIO bus. They must have a "reg" property given the PHY address on the MDIO bus. |
| 18 | 14 | ||
| 19 | Optional properties: | ||
| 20 | - mac-address: 6 bytes, mac address | ||
| 21 | |||
| 22 | Examples: | 15 | Examples: |
| 23 | 16 | ||
| 24 | ethernet@c0fc2000 { | 17 | ethernet@c0fc2000 { |
| @@ -0,0 +1,121 @@ | |||
| 1 | * Broadcom BCM7xxx Ethernet Controller (GENET) | ||
| 2 | |||
| 3 | Required properties: | ||
| 4 | - compatible: should contain one of "brcm,genet-v1", "brcm,genet-v2", | ||
| 5 | "brcm,genet-v3", "brcm,genet-v4". | ||
| 6 | - reg: address and length of the register set for the device | ||
| 7 | - interrupts: must be two cells, the first cell is the general purpose | ||
| 8 | interrupt line, while the second cell is the interrupt for the ring | ||
| 9 | RX and TX queues operating in ring mode | ||
| 10 | - phy-mode: see ethernet.txt file in the same directory | ||
| 11 | - #address-cells: should be 1 | ||
| 12 | - #size-cells: should be 1 | ||
| 13 | |||
| 14 | Optional properties: | ||
| 15 | - clocks: When provided, must be two phandles to the functional clocks nodes | ||
| 16 | of the GENET block. The first phandle is the main GENET clock used during | ||
| 17 | normal operation, while the second phandle is the Wake-on-LAN clock. | ||
| 18 | - clock-names: When provided, names of the functional clock phandles, first | ||
| 19 | name should be "enet" and second should be "enet-wol". | ||
| 20 | |||
| 21 | - phy-handle: See ethernet.txt file in the same directory; used to describe | ||
| 22 | configurations where a PHY (internal or external) is used. | ||
| 23 | |||
| 24 | - fixed-link: When the GENET interface is connected to a MoCA hardware block or | ||
| 25 | when operating in a RGMII to RGMII type of connection, or when the MDIO bus is | ||
| 26 | voluntarily disabled, this property should be used to describe the "fixed link". | ||
| 27 | See Documentation/devicetree/bindings/net/fsl-tsec-phy.txt for information on | ||
| 28 | the property specifics | ||
| 29 | |||
| 30 | Required child nodes: | ||
| 31 | |||
| 32 | - mdio bus node: this node should always be present regarless of the PHY | ||
| 33 | configuration of the GENET instance | ||
| 34 | |||
| 35 | MDIO bus node required properties: | ||
| 36 | |||
| 37 | - compatible: should contain one of "brcm,genet-mdio-v1", "brcm,genet-mdio-v2" | ||
| 38 | "brcm,genet-mdio-v3", "brcm,genet-mdio-v4", the version has to match the | ||
| 39 | parent node compatible property (e.g: brcm,genet-v4 pairs with | ||
| 40 | brcm,genet-mdio-v4) | ||
| 41 | - reg: address and length relative to the parent node base register address | ||
| 42 | - #address-cells: address cell for MDIO bus addressing, should be 1 | ||
| 43 | - #size-cells: size of the cells for MDIO bus addressing, should be 0 | ||
| 44 | |||
| 45 | Ethernet PHY node properties: | ||
| 46 | |||
| 47 | See Documentation/devicetree/bindings/net/phy.txt for the list of required and | ||
| 48 | optional properties. | ||
| 49 | |||
| 50 | Internal Gigabit PHY example: | ||
| 51 | |||
| 52 | ethernet@f0b60000 { | ||
| 53 | phy-mode = "internal"; | ||
| 54 | phy-handle = <&phy1>; | ||
| 55 | mac-address = [ 00 10 18 36 23 1a ]; | ||
| 56 | compatible = "brcm,genet-v4"; | ||
| 57 | #address-cells = <0x1>; | ||
| 58 | #size-cells = <0x1>; | ||
| 59 | reg = <0xf0b60000 0xfc4c>; | ||
| 60 | interrupts = <0x0 0x14 0x0>, <0x0 0x15 0x0>; | ||
| 61 | |||
| 62 | mdio@e14 { | ||
| 63 | compatible = "brcm,genet-mdio-v4"; | ||
| 64 | #address-cells = <0x1>; | ||
| 65 | #size-cells = <0x0>; | ||
| 66 | reg = <0xe14 0x8>; | ||
| 67 | |||
| 68 | phy1: ethernet-phy@1 { | ||
| 69 | max-speed = <1000>; | ||
| 70 | reg = <0x1>; | ||
| 71 | compatible = "brcm,28nm-gphy", "ethernet-phy-ieee802.3-c22"; | ||
| 72 | }; | ||
| 73 | }; | ||
| 74 | }; | ||
| 75 | |||
| 76 | MoCA interface / MAC to MAC example: | ||
| 77 | |||
| 78 | ethernet@f0b80000 { | ||
| 79 | phy-mode = "moca"; | ||
| 80 | fixed-link = <1 0 1000 0 0>; | ||
| 81 | mac-address = [ 00 10 18 36 24 1a ]; | ||
| 82 | compatible = "brcm,genet-v4"; | ||
| 83 | #address-cells = <0x1>; | ||
| 84 | #size-cells = <0x1>; | ||
| 85 | reg = <0xf0b80000 0xfc4c>; | ||
| 86 | interrupts = <0x0 0x16 0x0>, <0x0 0x17 0x0>; | ||
| 87 | |||
| 88 | mdio@e14 { | ||
| 89 | compatible = "brcm,genet-mdio-v4"; | ||
| 90 | #address-cells = <0x1>; | ||
| 91 | #size-cells = <0x0>; | ||
| 92 | reg = <0xe14 0x8>; | ||
| 93 | }; | ||
| 94 | }; | ||
| 95 | |||
| 96 | |||
| 97 | External MDIO-connected Gigabit PHY/switch: | ||
| 98 | |||
| 99 | ethernet@f0ba0000 { | ||
| 100 | phy-mode = "rgmii"; | ||
| 101 | phy-handle = <&phy0>; | ||
| 102 | mac-address = [ 00 10 18 36 26 1a ]; | ||
| 103 | compatible = "brcm,genet-v4"; | ||
| 104 | #address-cells = <0x1>; | ||
| 105 | #size-cells = <0x1>; | ||
| 106 | reg = <0xf0ba0000 0xfc4c>; | ||
| 107 | interrupts = <0x0 0x18 0x0>, <0x0 0x19 0x0>; | ||
| 108 | |||
| 109 | mdio@0e14 { | ||
| 110 | compatible = "brcm,genet-mdio-v4"; | ||
| 111 | #address-cells = <0x1>; | ||
| 112 | #size-cells = <0x0>; | ||
| 113 | reg = <0xe14 0x8>; | ||
| 114 | |||
| 115 | phy0: ethernet-phy@0 { | ||
| 116 | max-speed = <1000>; | ||
| 117 | reg = <0x0>; | ||
| 118 | compatible = "brcm,bcm53125", "ethernet-phy-ieee802.3-c22"; | ||
| 119 | }; | ||
| 120 | }; | ||
| 121 | }; | ||
| @@ -12,6 +12,10 @@ Required properties: · 11 unmodified lines | |||
| 12 | 12 | ||
| 13 | Optional properties: | 13 | Optional properties: |
| 14 | 14 | ||
| 15 | - reg-io-width : Specify the size (in bytes) of the IO accesses that | ||
| 16 | should be performed on the device. Valid value is 1, 2 or 4. | ||
| 17 | Default to 1 (8 bits). | ||
| 18 | |||
| 15 | - nxp,external-clock-frequency : Frequency of the external oscillator | 19 | - nxp,external-clock-frequency : Frequency of the external oscillator |
| 16 | clock in Hz. Note that the internal clock frequency used by the | 20 | clock in Hz. Note that the internal clock frequency used by the |
| 17 | SJA1000 is half of that value. If not specified, a default value | 21 | SJA1000 is half of that value. If not specified, a default value |
| @@ -18,12 +18,7 @@ Properties: · 17 unmodified lines | |||
| 18 | - interrupts: Two interrupt specifiers. The first is the MIX | 18 | - interrupts: Two interrupt specifiers. The first is the MIX |
| 19 | interrupt routing and the second the routing for the AGL interrupts. | 19 | interrupt routing and the second the routing for the AGL interrupts. |
| 20 | 20 | ||
| 21 | - mac-address: Optional, the MAC address to assign to the device. | 21 | - phy-handle: Optional, see ethernet.txt file in the same directory. |
| 22 | |||
| 23 | - local-mac-address: Optional, the MAC address to assign to the device | ||
| 24 | if mac-address is not specified. | ||
| 25 | |||
| 26 | - phy-handle: Optional, a phandle for the PHY device connected to this device. | ||
| 27 | 22 | ||
| 28 | Example: | 23 | Example: |
| 29 | ethernet@1070000100800 { | 24 | ethernet@1070000100800 { |
| @@ -35,12 +35,7 @@ Properties for PIP port which is a child the PIP interface: · 34 unmodified lines | |||
| 35 | 35 | ||
| 36 | - reg: The port number within the interface group. | 36 | - reg: The port number within the interface group. |
| 37 | 37 | ||
| 38 | - mac-address: Optional, the MAC address to assign to the device. | 38 | - phy-handle: Optional, see ethernet.txt file in the same directory. |
| 39 | |||
| 40 | - local-mac-address: Optional, the MAC address to assign to the device | ||
| 41 | if mac-address is not specified. | ||
| 42 | |||
| 43 | - phy-handle: Optional, a phandle for the PHY device connected to this device. | ||
| 44 | 39 | ||
| 45 | Example: | 40 | Example: |
| 46 | 41 | ||
| @@ -6,11 +6,7 @@ Required properties: · 5 unmodified lines | |||
| 6 | or the generic form: "cdns,emac". | 6 | or the generic form: "cdns,emac". |
| 7 | - reg: Address and length of the register set for the device | 7 | - reg: Address and length of the register set for the device |
| 8 | - interrupts: Should contain macb interrupt | 8 | - interrupts: Should contain macb interrupt |
| 9 | - phy-mode: String, operation mode of the PHY interface. | 9 | - phy-mode: see ethernet.txt file in the same directory. |
| 10 | Supported values are: "mii", "rmii". | ||
| 11 | |||
| 12 | Optional properties: | ||
| 13 | - local-mac-address: 6 bytes, mac address | ||
| 14 | 10 | ||
| 15 | Examples: | 11 | Examples: |
| 16 | 12 | ||
| @@ -28,9 +28,8 @@ Optional properties: · 27 unmodified lines | |||
| 28 | Slave Properties: | 28 | Slave Properties: |
| 29 | Required properties: | 29 | Required properties: |
| 30 | - phy_id : Specifies slave phy id | 30 | - phy_id : Specifies slave phy id |
| 31 | - phy-mode : The interface between the SoC and the PHY (a string | 31 | - phy-mode : See ethernet.txt file in the same directory |
| 32 | that of_get_phy_mode() can understand) | 32 | - mac-address : See ethernet.txt file in the same directory |
| 33 | - mac-address : Specifies slave MAC address | ||
| 34 | 33 | ||
| 35 | Optional properties: | 34 | Optional properties: |
| 36 | - dual_emac_res_vlan : Specifies VID to be used to segregate the ports | 35 | - dual_emac_res_vlan : Specifies VID to be used to segregate the ports |
| @@ -9,8 +9,6 @@ Required properties: · 8 unmodified lines | |||
| 9 | - interrupts : interrupt specifier specific to interrupt controller | 9 | - interrupts : interrupt specifier specific to interrupt controller |
| 10 | 10 | ||
| 11 | Optional properties: | 11 | Optional properties: |
| 12 | - local-mac-address : A bytestring of 6 bytes specifying Ethernet MAC address | ||
| 13 | to use (from firmware or bootloader) | ||
| 14 | - davicom,no-eeprom : Configuration EEPROM is not available | 12 | - davicom,no-eeprom : Configuration EEPROM is not available |
| 15 | - davicom,ext-phy : Use external PHY | 13 | - davicom,ext-phy : Use external PHY |
| 16 | 14 | ||
| @@ -17,9 +17,8 @@ Required properties: · 16 unmodified lines | |||
| 17 | Miscellaneous Interrupt> | 17 | Miscellaneous Interrupt> |
| 18 | 18 | ||
| 19 | Optional properties: | 19 | Optional properties: |
| 20 | - phy-handle: Contains a phandle to an Ethernet PHY. | 20 | - phy-handle: See ethernet.txt file in the same directory. |
| 21 | If absent, davinci_emac driver defaults to 100/FULL. | 21 | If absent, davinci_emac driver defaults to 100/FULL. |
| 22 | - local-mac-address : 6 bytes, mac address | ||
| 23 | - ti,davinci-rmii-en: 1 byte, 1 means use RMII | 22 | - ti,davinci-rmii-en: 1 byte, 1 means use RMII |
| 24 | - ti,davinci-no-bd-ram: boolean, does EMAC have BD RAM? | 23 | - ti,davinci-no-bd-ram: boolean, does EMAC have BD RAM? |
| 25 | 24 | ||
| @@ -0,0 +1,25 @@ | |||
| 1 | The following properties are common to the Ethernet controllers: | ||
| 2 | |||
| 3 | - local-mac-address: array of 6 bytes, specifies the MAC address that was | ||
| 4 | assigned to the network device; | ||
| 5 | - mac-address: array of 6 bytes, specifies the MAC address that was last used by | ||
| 6 | the boot program; should be used in cases where the MAC address assigned to | ||
| 7 | the device by the boot program is different from the "local-mac-address" | ||
| 8 | property; | ||
| 9 | - max-speed: number, specifies maximum speed in Mbit/s supported by the device; | ||
| 10 | - max-frame-size: number, maximum transfer unit (IEEE defined MTU), rather than | ||
| 11 | the maximum frame size (there's contradiction in ePAPR). | ||
| 12 | - phy-mode: string, operation mode of the PHY interface; supported values are | ||
| 13 | "mii", "gmii", "sgmii", "tbi", "rev-mii", "rmii", "rgmii", "rgmii-id", | ||
| 14 | "rgmii-rxid", "rgmii-txid", "rtbi", "smii", "xgmii"; this is now a de-facto | ||
| 15 | standard property; | ||
| 16 | - phy-connection-type: the same as "phy-mode" property but described in ePAPR; | ||
| 17 | - phy-handle: phandle, specifies a reference to a node representing a PHY | ||
| 18 | device; this property is described in ePAPR and so preferred; | ||
| 19 | - phy: the same as "phy-handle" property, not recommended for new bindings. | ||
| 20 | - phy-device: the same as "phy-handle" property, not recommended for new | ||
| 21 | bindings. | ||
| 22 | |||
| 23 | Child nodes of the Ethernet controller are typically the individual PHY devices | ||
| 24 | connected via the MDIO bus (sometimes the MDIO bus controller is separate). | ||
| 25 | They are described in the phy.txt file in this same directory. | ||
| @@ -4,12 +4,9 @@ Required properties: · 3 unmodified lines | |||
| 4 | - compatible : Should be "fsl,<soc>-fec" | 4 | - compatible : Should be "fsl,<soc>-fec" |
| 5 | - reg : Address and length of the register set for the device | 5 | - reg : Address and length of the register set for the device |
| 6 | - interrupts : Should contain fec interrupt | 6 | - interrupts : Should contain fec interrupt |
| 7 | - phy-mode : String, operation mode of the PHY interface. | 7 | - phy-mode : See ethernet.txt file in the same directory |
| 8 | Supported values are: "mii", "gmii", "sgmii", "tbi", "rmii", | ||
| 9 | "rgmii", "rgmii-id", "rgmii-rxid", "rgmii-txid", "rtbi", "smii". | ||
| 10 | 8 | ||
| 11 | Optional properties: | 9 | Optional properties: |
| 12 | - local-mac-address : 6 bytes, mac address | ||
| 13 | - phy-reset-gpios : Should specify the gpio for phy reset | 10 | - phy-reset-gpios : Should specify the gpio for phy reset |
| 14 | - phy-reset-duration : Reset duration in milliseconds. Should present | 11 | - phy-reset-duration : Reset duration in milliseconds. Should present |
| 15 | only if property "phy-reset-gpios" is available. Missing the property | 12 | only if property "phy-reset-gpios" is available. Missing the property |
| @@ -38,22 +38,17 @@ Properties: · 37 unmodified lines | |||
| 38 | - model : Model of the device. Can be "TSEC", "eTSEC", or "FEC" | 38 | - model : Model of the device. Can be "TSEC", "eTSEC", or "FEC" |
| 39 | - compatible : Should be "gianfar" | 39 | - compatible : Should be "gianfar" |
| 40 | - reg : Offset and length of the register set for the device | 40 | - reg : Offset and length of the register set for the device |
| 41 | - local-mac-address : List of bytes representing the ethernet address of | ||
| 42 | this controller | ||
| 43 | - interrupts : For FEC devices, the first interrupt is the device's | 41 | - interrupts : For FEC devices, the first interrupt is the device's |
| 44 | interrupt. For TSEC and eTSEC devices, the first interrupt is | 42 | interrupt. For TSEC and eTSEC devices, the first interrupt is |
| 45 | transmit, the second is receive, and the third is error. | 43 | transmit, the second is receive, and the third is error. |
| 46 | - phy-handle : The phandle for the PHY connected to this ethernet | 44 | - phy-handle : See ethernet.txt file in the same directory. |
| 47 | controller. | ||
| 48 | - fixed-link : <a b c d e> where a is emulated phy id - choose any, | 45 | - fixed-link : <a b c d e> where a is emulated phy id - choose any, |
| 49 | but unique to the all specified fixed-links, b is duplex - 0 half, | 46 | but unique to the all specified fixed-links, b is duplex - 0 half, |
| 50 | 1 full, c is link speed - d#10/d#100/d#1000, d is pause - 0 no | 47 | 1 full, c is link speed - d#10/d#100/d#1000, d is pause - 0 no |
| 51 | pause, 1 pause, e is asym_pause - 0 no asym_pause, 1 asym_pause. | 48 | pause, 1 pause, e is asym_pause - 0 no asym_pause, 1 asym_pause. |
| 52 | - phy-connection-type : a string naming the controller/PHY interface type, | 49 | - phy-connection-type : See ethernet.txt file in the same directory. |
| 53 | i.e., "mii" (default), "rmii", "gmii", "rgmii", "rgmii-id", "sgmii", | 50 | This property is only really needed if the connection is of type |
| 54 | "tbi", or "rtbi". This property is only really needed if the connection | 51 | "rgmii-id", as all other connection types are detected by hardware. |
| 55 | is of type "rgmii-id", as all other connection types are detected by | ||
| 56 | hardware. | ||
| 57 | - fsl,magic-packet : If present, indicates that the hardware supports | 52 | - fsl,magic-packet : If present, indicates that the hardware supports |
| 58 | waking up via magic packet. | 53 | waking up via magic packet. |
| 59 | - bd-stash : If present, indicates that the hardware supports stashing | 54 | - bd-stash : If present, indicates that the hardware supports stashing |
| @@ -6,10 +6,9 @@ Required properties: · 5 unmodified lines | |||
| 6 | - interrupts: Should contain ethernet controller interrupt | 6 | - interrupts: Should contain ethernet controller interrupt |
| 7 | 7 | ||
| 8 | Optional properties: | 8 | Optional properties: |
| 9 | - phy-mode: String, operation mode of the PHY interface. | 9 | - phy-mode: See ethernet.txt file in the same directory. If the property is |
| 10 | Supported values are: "mii", "rmii" (default) | 10 | absent, "rmii" is assumed. |
| 11 | - use-iram: Use LPC32xx internal SRAM (IRAM) for DMA buffering | 11 | - use-iram: Use LPC32xx internal SRAM (IRAM) for DMA buffering |
| 12 | - local-mac-address : 6 bytes, mac address | ||
| 13 | 12 | ||
| 14 | Example: | 13 | Example: |
| 15 | 14 | ||
| @@ -8,16 +8,12 @@ Required properties: · 7 unmodified lines | |||
| 8 | the Cadence GEM, or the generic form: "cdns,gem". | 8 | the Cadence GEM, or the generic form: "cdns,gem". |
| 9 | - reg: Address and length of the register set for the device | 9 | - reg: Address and length of the register set for the device |
| 10 | - interrupts: Should contain macb interrupt | 10 | - interrupts: Should contain macb interrupt |
| 11 | - phy-mode: String, operation mode of the PHY interface. | 11 | - phy-mode: See ethernet.txt file in the same directory. |
| 12 | Supported values are: "mii", "rmii", "gmii", "rgmii". | ||
| 13 | - clock-names: Tuple listing input clock names. | 12 | - clock-names: Tuple listing input clock names. |
| 14 | Required elements: 'pclk', 'hclk' | 13 | Required elements: 'pclk', 'hclk' |
| 15 | Optional elements: 'tx_clk' | 14 | Optional elements: 'tx_clk' |
| 16 | - clocks: Phandles to input clocks. | 15 | - clocks: Phandles to input clocks. |
| 17 | 16 | ||
| 18 | Optional properties: | ||
| 19 | - local-mac-address: 6 bytes, mac address | ||
| 20 | |||
| 21 | Examples: | 17 | Examples: |
| 22 | 18 | ||
| 23 | macb0: ethernet@fffc4000 { | 19 | macb0: ethernet@fffc4000 { |
| @@ -4,10 +4,8 @@ Required properties: · 3 unmodified lines | |||
| 4 | - compatible: should be "marvell,armada-370-neta". | 4 | - compatible: should be "marvell,armada-370-neta". |
| 5 | - reg: address and length of the register set for the device. | 5 | - reg: address and length of the register set for the device. |
| 6 | - interrupts: interrupt for the device | 6 | - interrupts: interrupt for the device |
| 7 | - phy: A phandle to a phy node defining the PHY address (as the reg | 7 | - phy: See ethernet.txt file in the same directory. |
| 8 | property, a single integer). | 8 | - phy-mode: See ethernet.txt file in the same directory |
| 9 | - phy-mode: The interface between the SoC and the PHY (a string that | ||
| 10 | of_get_phy_mode() can understand) | ||
| 11 | - clocks: a pointer to the reference clock for this device. | 9 | - clocks: a pointer to the reference clock for this device. |
| 12 | 10 | ||
| 13 | Example: | 11 | Example: |
| @@ -36,7 +36,7 @@ Required port properties: · 35 unmodified lines | |||
| 36 | "marvell,kirkwood-eth-port". | 36 | "marvell,kirkwood-eth-port". |
| 37 | - reg: port number relative to ethernet controller, shall be 0, 1, or 2. | 37 | - reg: port number relative to ethernet controller, shall be 0, 1, or 2. |
| 38 | - interrupts: port interrupt. | 38 | - interrupts: port interrupt. |
| 39 | - local-mac-address: 6 bytes MAC address. | 39 | - local-mac-address: See ethernet.txt file in the same directory. |
| 40 | 40 | ||
| 41 | Optional port properties: | 41 | Optional port properties: |
| 42 | - marvell,tx-queue-size: size of the transmit ring buffer. | 42 | - marvell,tx-queue-size: size of the transmit ring buffer. |
| @@ -48,7 +48,7 @@ Optional port properties: · 5 unmodified lines | |||
| 48 | 48 | ||
| 49 | and | 49 | and |
| 50 | 50 | ||
| 51 | - phy-handle: phandle reference to ethernet PHY. | 51 | - phy-handle: See ethernet.txt file in the same directory. |
| 52 | 52 | ||
| 53 | or | 53 | or |
| 54 | 54 | ||
| @@ -6,5 +6,4 @@ Required properties: · 5 unmodified lines | |||
| 6 | - interrupts : interrupt connection | 6 | - interrupts : interrupt connection |
| 7 | 7 | ||
| 8 | Optional properties: | 8 | Optional properties: |
| 9 | - local-mac-address : Ethernet mac address to use | ||
| 10 | - vdd-supply: supply for Ethernet mac | 9 | - vdd-supply: supply for Ethernet mac |
| @@ -0,0 +1,18 @@ | |||
| 1 | Micrel PHY properties. | ||
| 2 | |||
| 3 | These properties cover the base properties Micrel PHYs. | ||
| 4 | |||
| 5 | Optional properties: | ||
| 6 | |||
| 7 | - micrel,led-mode : LED mode value to set for PHYs with configurable LEDs. | ||
| 8 | |||
| 9 | Configure the LED mode with single value. The list of PHYs and | ||
| 10 | the bits that are currently supported: | ||
| 11 | |||
| 12 | KSZ8001: register 0x1e, bits 15..14 | ||
| 13 | KSZ8041: register 0x1e, bits 15..14 | ||
| 14 | KSZ8021: register 0x1f, bits 5..4 | ||
| 15 | KSZ8031: register 0x1f, bits 5..4 | ||
| 16 | KSZ8051: register 0x1f, bits 5..4 | ||
| 17 | |||
| 18 | See the respective PHY datasheet for the mode values. | ||
| @@ -0,0 +1,34 @@ | |||
| 1 | * Texas Instruments TRF7970A RFID/NFC/15693 Transceiver | ||
| 2 | |||
| 3 | Required properties: | ||
| 4 | - compatible: Should be "ti,trf7970a". | ||
| 5 | - spi-max-frequency: Maximum SPI frequency (<= 2000000). | ||
| 6 | - interrupt-parent: phandle of parent interrupt handler. | ||
| 7 | - interrupts: A single interrupt specifier. | ||
| 8 | - ti,enable-gpios: Two GPIO entries used for 'EN' and 'EN2' pins on the | ||
| 9 | TRF7970A. | ||
| 10 | - vin-supply: Regulator for supply voltage to VIN pin | ||
| 11 | |||
| 12 | Optional SoC Specific Properties: | ||
| 13 | - pinctrl-names: Contains only one value - "default". | ||
| 14 | - pintctrl-0: Specifies the pin control groups used for this controller. | ||
| 15 | |||
| 16 | Example (for ARM-based BeagleBone with TRF7970A on SPI1): | ||
| 17 | |||
| 18 | &spi1 { | ||
| 19 | status = "okay"; | ||
| 20 | |||
| 21 | nfc@0 { | ||
| 22 | compatible = "ti,trf7970a"; | ||
| 23 | reg = <0>; | ||
| 24 | pinctrl-names = "default"; | ||
| 25 | pinctrl-0 = <&trf7970a_default>; | ||
| 26 | spi-max-frequency = <2000000>; | ||
| 27 | interrupt-parent = <&gpio2>; | ||
| 28 | interrupts = <14 0>; | ||
| 29 | ti,enable-gpios = <&gpio2 2 GPIO_ACTIVE_LOW>, | ||
| 30 | <&gpio2 5 GPIO_ACTIVE_LOW>; | ||
| 31 | vin-supply = <&ldo3_reg>; | ||
| 32 | status = "okay"; | ||
| 33 | }; | ||
| 34 | }; | ||
| @@ -21,10 +21,18 @@ Optional Properties: · 20 unmodified lines | |||
| 21 | elements. | 21 | elements. |
| 22 | - max-speed: Maximum PHY supported speed (10, 100, 1000...) | 22 | - max-speed: Maximum PHY supported speed (10, 100, 1000...) |
| 23 | 23 | ||
| 24 | If the phy's identifier is known then the list may contain an entry | ||
| 25 | of the form: "ethernet-phy-idAAAA.BBBB" where | ||
| 26 | AAAA - The value of the 16 bit Phy Identifier 1 register as | ||
| 27 | 4 hex digits. This is the chip vendor OUI bits 3:18 | ||
| 28 | BBBB - The value of the 16 bit Phy Identifier 2 register as | ||
| 29 | 4 hex digits. This is the chip vendor OUI bits 19:24, | ||
| 30 | followed by 10 bits of a vendor specific ID. | ||
| 31 | |||
| 24 | Example: | 32 | Example: |
| 25 | 33 | ||
| 26 | ethernet-phy@0 { | 34 | ethernet-phy@0 { |
| 27 | compatible = "ethernet-phy-ieee802.3-c22"; | 35 | compatible = "ethernet-phy-id0141.0e90", "ethernet-phy-ieee802.3-c22"; |
| 28 | interrupt-parent = <40000>; | 36 | interrupt-parent = <40000>; |
| 29 | interrupts = <35 1>; | 37 | interrupts = <35 1>; |
| 30 | reg = <0>; | 38 | reg = <0>; |
| @@ -0,0 +1,52 @@ | |||
| 1 | * Samsung 10G Ethernet driver (SXGBE) | ||
| 2 | |||
| 3 | Required properties: | ||
| 4 | - compatible: Should be "samsung,sxgbe-v2.0a" | ||
| 5 | - reg: Address and length of the register set for the device | ||
| 6 | - interrupt-parent: Should be the phandle for the interrupt controller | ||
| 7 | that services interrupts for this device | ||
| 8 | - interrupts: Should contain the SXGBE interrupts | ||
| 9 | These interrupts are ordered by fixed and follows variable | ||
| 10 | trasmit DMA interrupts, receive DMA interrupts and lpi interrupt. | ||
| 11 | index 0 - this is fixed common interrupt of SXGBE and it is always | ||
| 12 | available. | ||
| 13 | index 1 to 25 - 8 variable trasmit interrupts, variable 16 receive interrupts | ||
| 14 | and 1 optional lpi interrupt. | ||
| 15 | - phy-mode: String, operation mode of the PHY interface. | ||
| 16 | Supported values are: "sgmii", "xgmii". | ||
| 17 | - samsung,pbl: Integer, Programmable Burst Length. | ||
| 18 | Supported values are 1, 2, 4, 8, 16, or 32. | ||
| 19 | - samsung,burst-map: Integer, Program the possible bursts supported by sxgbe | ||
| 20 | This is an interger and represents allowable DMA bursts when fixed burst. | ||
| 21 | Allowable range is 0x01-0x3F. When this field is set fixed burst is enabled. | ||
| 22 | When fixed length is needed for burst mode, it can be set within allowable | ||
| 23 | range. | ||
| 24 | |||
| 25 | Optional properties: | ||
| 26 | - mac-address: 6 bytes, mac address | ||
| 27 | - max-frame-size: Maximum Transfer Unit (IEEE defined MTU), rather | ||
| 28 | than the maximum frame size. | ||
| 29 | |||
| 30 | Example: | ||
| 31 | |||
| 32 | aliases { | ||
| 33 | ethernet0 = <&sxgbe0>; | ||
| 34 | }; | ||
| 35 | |||
| 36 | sxgbe0: ethernet@1a040000 { | ||
| 37 | compatible = "samsung,sxgbe-v2.0a"; | ||
| 38 | reg = <0 0x1a040000 0 0x10000>; | ||
| 39 | interrupt-parent = <&gic>; | ||
| 40 | interrupts = <0 209 4>, <0 185 4>, <0 186 4>, <0 187 4>, | ||
| 41 | <0 188 4>, <0 189 4>, <0 190 4>, <0 191 4>, | ||
| 42 | <0 192 4>, <0 193 4>, <0 194 4>, <0 195 4>, | ||
| 43 | <0 196 4>, <0 197 4>, <0 198 4>, <0 199 4>, | ||
| 44 | <0 200 4>, <0 201 4>, <0 202 4>, <0 203 4>, | ||
| 45 | <0 204 4>, <0 205 4>, <0 206 4>, <0 207 4>, | ||
| 46 | <0 208 4>, <0 210 4>; | ||
| 47 | samsung,pbl = <0x08> | ||
| 48 | samsung,burst-map = <0x20> | ||
| 49 | mac-address = [ 00 11 22 33 44 55 ]; /* Filled in by U-Boot */ | ||
| 50 | max-frame-size = <9000>; | ||
| 51 | phy-mode = "xgmii"; | ||
| 52 | }; | ||
| @@ -0,0 +1,55 @@ | |||
| 1 | * Renesas Electronics SH EtherMAC | ||
| 2 | |||
| 3 | This file provides information on what the device node for the SH EtherMAC | ||
| 4 | interface contains. | ||
| 5 | |||
| 6 | Required properties: | ||
| 7 | - compatible: "renesas,gether-r8a7740" if the device is a part of R8A7740 SoC. | ||
| 8 | "renesas,ether-r8a7778" if the device is a part of R8A7778 SoC. | ||
| 9 | "renesas,ether-r8a7779" if the device is a part of R8A7779 SoC. | ||
| 10 | "renesas,ether-r8a7790" if the device is a part of R8A7790 SoC. | ||
| 11 | "renesas,ether-r8a7791" if the device is a part of R8A7791 SoC. | ||
| 12 | "renesas,ether-r7s72100" if the device is a part of R7S72100 SoC. | ||
| 13 | - reg: offset and length of (1) the E-DMAC/feLic register block (required), | ||
| 14 | (2) the TSU register block (optional). | ||
| 15 | - interrupts: interrupt specifier for the sole interrupt. | ||
| 16 | - phy-mode: see ethernet.txt file in the same directory. | ||
| 17 | - phy-handle: see ethernet.txt file in the same directory. | ||
| 18 | - #address-cells: number of address cells for the MDIO bus, must be equal to 1. | ||
| 19 | - #size-cells: number of size cells on the MDIO bus, must be equal to 0. | ||
| 20 | - clocks: clock phandle and specifier pair. | ||
| 21 | - pinctrl-0: phandle, referring to a default pin configuration node. | ||
| 22 | |||
| 23 | Optional properties: | ||
| 24 | - interrupt-parent: the phandle for the interrupt controller that services | ||
| 25 | interrupts for this device. | ||
| 26 | - pinctrl-names: pin configuration state name ("default"). | ||
| 27 | - renesas,no-ether-link: boolean, specify when a board does not provide a proper | ||
| 28 | Ether LINK signal. | ||
| 29 | - renesas,ether-link-active-low: boolean, specify when the Ether LINK signal is | ||
| 30 | active-low instead of normal active-high. | ||
| 31 | |||
| 32 | Example (Lager board): | ||
| 33 | |||
| 34 | ethernet@ee700000 { | ||
| 35 | compatible = "renesas,ether-r8a7790"; | ||
| 36 | reg = <0 0xee700000 0 0x400>; | ||
| 37 | interrupt-parent = <&gic>; | ||
| 38 | interrupts = <0 162 IRQ_TYPE_LEVEL_HIGH>; | ||
| 39 | clocks = <&mstp8_clks R8A7790_CLK_ETHER>; | ||
| 40 | phy-mode = "rmii"; | ||
| 41 | phy-handle = <&phy1>; | ||
| 42 | pinctrl-0 = <ðer_pins>; | ||
| 43 | pinctrl-names = "default"; | ||
| 44 | renesas,ether-link-active-low; | ||
| 45 | #address-cells = <1>; | ||
| 46 | #size-cells = <0>; | ||
| 47 | |||
| 48 | phy1: ethernet-phy@1 { | ||
| 49 | reg = <1>; | ||
| 50 | interrupt-parent = <&irqc0>; | ||
| 51 | interrupts = <0 IRQ_TYPE_LEVEL_LOW>; | ||
| 52 | pinctrl-0 = <&phy1_pins>; | ||
| 53 | pinctrl-names = "default"; | ||
| 54 | }; | ||
| 55 | }; | ||
| @@ -6,8 +6,7 @@ Required properties: · 5 unmodified lines | |||
| 6 | - interrupts : interrupt connection | 6 | - interrupts : interrupt connection |
| 7 | 7 | ||
| 8 | Optional properties: | 8 | Optional properties: |
| 9 | - phy-device : phandle to Ethernet phy | 9 | - phy-device : see ethernet.txt file in the same directory |
| 10 | - local-mac-address : Ethernet mac address to use | ||
| 11 | - reg-io-width : Mask of sizes (in bytes) of the IO accesses that | 10 | - reg-io-width : Mask of sizes (in bytes) of the IO accesses that |
| 12 | are supported on the device. Valid value for SMSC LAN91c111 are | 11 | are supported on the device. Valid value for SMSC LAN91c111 are |
| 13 | 1, 2 or 4. If it's omitted or invalid, the size would be 2 meaning | 12 | 1, 2 or 4. If it's omitted or invalid, the size would be 2 meaning |
| @@ -6,9 +6,7 @@ Required properties: · 5 unmodified lines | |||
| 6 | - interrupts : Should contain SMSC LAN interrupt line | 6 | - interrupts : Should contain SMSC LAN interrupt line |
| 7 | - interrupt-parent : Should be the phandle for the interrupt controller | 7 | - interrupt-parent : Should be the phandle for the interrupt controller |
| 8 | that services interrupts for this device | 8 | that services interrupts for this device |
| 9 | - phy-mode : String, operation mode of the PHY interface. | 9 | - phy-mode : See ethernet.txt file in the same directory |
| 10 | Supported values are: "mii", "gmii", "sgmii", "tbi", "rmii", | ||
| 11 | "rgmii", "rgmii-id", "rgmii-rxid", "rgmii-txid", "rtbi", "smii". | ||
| 12 | 10 | ||
| 13 | Optional properties: | 11 | Optional properties: |
| 14 | - reg-shift : Specify the quantity to shift the register offsets by | 12 | - reg-shift : Specify the quantity to shift the register offsets by |
| @@ -23,7 +21,6 @@ Optional properties: · 8 unmodified lines | |||
| 23 | external PHY | 21 | external PHY |
| 24 | - smsc,save-mac-address : Indicates that mac address needs to be saved | 22 | - smsc,save-mac-address : Indicates that mac address needs to be saved |
| 25 | before resetting the controller | 23 | before resetting the controller |
| 26 | - local-mac-address : 6 bytes, mac address | ||
| 27 | 24 | ||
| 28 | Examples: | 25 | Examples: |
| 29 | 26 | ||
| @@ -10,8 +10,7 @@ Required properties: · 9 unmodified lines | |||
| 10 | - interrupt-names: Should contain the interrupt names "macirq" | 10 | - interrupt-names: Should contain the interrupt names "macirq" |
| 11 | "eth_wake_irq" if this interrupt is supported in the "interrupts" | 11 | "eth_wake_irq" if this interrupt is supported in the "interrupts" |
| 12 | property | 12 | property |
| 13 | - phy-mode: String, operation mode of the PHY interface. | 13 | - phy-mode: See ethernet.txt file in the same directory. |
| 14 | Supported values are: "mii", "rmii", "gmii", "rgmii". | ||
| 15 | - snps,reset-gpio gpio number for phy reset. | 14 | - snps,reset-gpio gpio number for phy reset. |
| 16 | - snps,reset-active-low boolean flag to indicate if phy reset is active low. | 15 | - snps,reset-active-low boolean flag to indicate if phy reset is active low. |
| 17 | - snps,reset-delays-us is triplet of delays | 16 | - snps,reset-delays-us is triplet of delays |
| @@ -28,12 +27,10 @@ Required properties: · 10 unmodified lines | |||
| 28 | ignored if force_thresh_dma_mode is set. | 27 | ignored if force_thresh_dma_mode is set. |
| 29 | 28 | ||
| 30 | Optional properties: | 29 | Optional properties: |
| 31 | - mac-address: 6 bytes, mac address | ||
| 32 | - resets: Should contain a phandle to the STMMAC reset signal, if any | 30 | - resets: Should contain a phandle to the STMMAC reset signal, if any |
| 33 | - reset-names: Should contain the reset signal name "stmmaceth", if a | 31 | - reset-names: Should contain the reset signal name "stmmaceth", if a |
| 34 | reset phandle is given | 32 | reset phandle is given |
| 35 | - max-frame-size: Maximum Transfer Unit (IEEE defined MTU), rather | 33 | - max-frame-size: See ethernet.txt file in the same directory |
| 36 | than the maximum frame size. | ||
| 37 | 34 | ||
| 38 | Examples: | 35 | Examples: |
| 39 | 36 | ||
| @@ -0,0 +1,39 @@ | |||
| 1 | * Texas Instruments wl1251 wireless lan controller | ||
| 2 | |||
| 3 | The wl1251 chip can be connected via SPI or via SDIO. This | ||
| 4 | document describes the binding for the SPI connected chip. | ||
| 5 | |||
| 6 | Required properties: | ||
| 7 | - compatible : Should be "ti,wl1251" | ||
| 8 | - reg : Chip select address of device | ||
| 9 | - spi-max-frequency : Maximum SPI clocking speed of device in Hz | ||
| 10 | - interrupts : Should contain interrupt line | ||
| 11 | - interrupt-parent : Should be the phandle for the interrupt controller | ||
| 12 | that services interrupts for this device | ||
| 13 | - vio-supply : phandle to regulator providing VIO | ||
| 14 | - ti,power-gpio : GPIO connected to chip's PMEN pin | ||
| 15 | |||
| 16 | Optional properties: | ||
| 17 | - ti,wl1251-has-eeprom : boolean, the wl1251 has an eeprom connected, which | ||
| 18 | provides configuration data (calibration, MAC, ...) | ||
| 19 | - Please consult Documentation/devicetree/bindings/spi/spi-bus.txt | ||
| 20 | for optional SPI connection related properties, | ||
| 21 | |||
| 22 | Examples: | ||
| 23 | |||
| 24 | &spi1 { | ||
| 25 | wl1251@0 { | ||
| 26 | compatible = "ti,wl1251"; | ||
| 27 | |||
| 28 | reg = <0>; | ||
| 29 | spi-max-frequency = <48000000>; | ||
| 30 | spi-cpol; | ||
| 31 | spi-cpha; | ||
| 32 | |||
| 33 | interrupt-parent = <&gpio2>; | ||
| 34 | interrupts = <10 IRQ_TYPE_NONE>; /* gpio line 42 */ | ||
| 35 | |||
| 36 | vio-supply = <&vio>; | ||
| 37 | ti,power-gpio = <&gpio3 23 GPIO_ACTIVE_HIGH>; /* 87 */ | ||
| 38 | }; | ||
| 39 | }; | ||
| @@ -0,0 +1,263 @@ | |||
| 1 | Altera Triple-Speed Ethernet MAC driver | ||
| 2 | |||
| 3 | Copyright (C) 2008-2014 Altera Corporation | ||
| 4 | |||
| 5 | This is the driver for the Altera Triple-Speed Ethernet (TSE) controllers | ||
| 6 | using the SGDMA and MSGDMA soft DMA IP components. The driver uses the | ||
| 7 | platform bus to obtain component resources. The designs used to test this | ||
| 8 | driver were built for a Cyclone(R) V SOC FPGA board, a Cyclone(R) V FPGA board, | ||
| 9 | and tested with ARM and NIOS processor hosts seperately. The anticipated use | ||
| 10 | cases are simple communications between an embedded system and an external peer | ||
| 11 | for status and simple configuration of the embedded system. | ||
| 12 | |||
| 13 | For more information visit www.altera.com and www.rocketboards.org. Support | ||
| 14 | forums for the driver may be found on www.rocketboards.org, and a design used | ||
| 15 | to test this driver may be found there as well. Support is also available from | ||
| 16 | the maintainer of this driver, found in MAINTAINERS. | ||
| 17 | |||
| 18 | The Triple-Speed Ethernet, SGDMA, and MSGDMA components are all soft IP | ||
| 19 | components that can be assembled and built into an FPGA using the Altera | ||
| 20 | Quartus toolchain. Quartus 13.1 and 14.0 were used to build the design that | ||
| 21 | this driver was tested against. The sopc2dts tool is used to create the | ||
| 22 | device tree for the driver, and may be found at rocketboards.org. | ||
| 23 | |||
| 24 | The driver probe function examines the device tree and determines if the | ||
| 25 | Triple-Speed Ethernet instance is using an SGDMA or MSGDMA component. The | ||
| 26 | probe function then installs the appropriate set of DMA routines to | ||
| 27 | initialize, setup transmits, receives, and interrupt handling primitives for | ||
| 28 | the respective configurations. | ||
| 29 | |||
| 30 | The SGDMA component is to be deprecated in the near future (over the next 1-2 | ||
| 31 | years as of this writing in early 2014) in favor of the MSGDMA component. | ||
| 32 | SGDMA support is included for existing designs and reference in case a | ||
| 33 | developer wishes to support their own soft DMA logic and driver support. Any | ||
| 34 | new designs should not use the SGDMA. | ||
| 35 | |||
| 36 | The SGDMA supports only a single transmit or receive operation at a time, and | ||
| 37 | therefore will not perform as well compared to the MSGDMA soft IP. Please | ||
| 38 | visit www.altera.com for known, documented SGDMA errata. | ||
| 39 | |||
| 40 | Scatter-gather DMA is not supported by the SGDMA or MSGDMA at this time. | ||
| 41 | Scatter-gather DMA will be added to a future maintenance update to this | ||
| 42 | driver. | ||
| 43 | |||
| 44 | Jumbo frames are not supported at this time. | ||
| 45 | |||
| 46 | The driver limits PHY operations to 10/100Mbps, and has not yet been fully | ||
| 47 | tested for 1Gbps. This support will be added in a future maintenance update. | ||
| 48 | |||
| 49 | 1) Kernel Configuration | ||
| 50 | The kernel configuration option is ALTERA_TSE: | ||
| 51 | Device Drivers ---> Network device support ---> Ethernet driver support ---> | ||
| 52 | Altera Triple-Speed Ethernet MAC support (ALTERA_TSE) | ||
| 53 | |||
| 54 | 2) Driver parameters list: | ||
| 55 | debug: message level (0: no output, 16: all); | ||
| 56 | dma_rx_num: Number of descriptors in the RX list (default is 64); | ||
| 57 | dma_tx_num: Number of descriptors in the TX list (default is 64). | ||
| 58 | |||
| 59 | 3) Command line options | ||
| 60 | Driver parameters can be also passed in command line by using: | ||
| 61 | altera_tse=dma_rx_num:128,dma_tx_num:512 | ||
| 62 | |||
| 63 | 4) Driver information and notes | ||
| 64 | |||
| 65 | 4.1) Transmit process | ||
| 66 | When the driver's transmit routine is called by the kernel, it sets up a | ||
| 67 | transmit descriptor by calling the underlying DMA transmit routine (SGDMA or | ||
| 68 | MSGDMA), and initites a transmit operation. Once the transmit is complete, an | ||
| 69 | interrupt is driven by the transmit DMA logic. The driver handles the transmit | ||
| 70 | completion in the context of the interrupt handling chain by recycling | ||
| 71 | resource required to send and track the requested transmit operation. | ||
| 72 | |||
| 73 | 4.2) Receive process | ||
| 74 | The driver will post receive buffers to the receive DMA logic during driver | ||
| 75 | intialization. Receive buffers may or may not be queued depending upon the | ||
| 76 | underlying DMA logic (MSGDMA is able queue receive buffers, SGDMA is not able | ||
| 77 | to queue receive buffers to the SGDMA receive logic). When a packet is | ||
| 78 | received, the DMA logic generates an interrupt. The driver handles a receive | ||
| 79 | interrupt by obtaining the DMA receive logic status, reaping receive | ||
| 80 | completions until no more receive completions are available. | ||
| 81 | |||
| 82 | 4.3) Interrupt Mitigation | ||
| 83 | The driver is able to mitigate the number of its DMA interrupts | ||
| 84 | using NAPI for receive operations. Interrupt mitigation is not yet supported | ||
| 85 | for transmit operations, but will be added in a future maintenance release. | ||
| 86 | |||
| 87 | 4.4) Ethtool support | ||
| 88 | Ethtool is supported. Driver statistics and internal errors can be taken using: | ||
| 89 | ethtool -S ethX command. It is possible to dump registers etc. | ||
| 90 | |||
| 91 | 4.5) PHY Support | ||
| 92 | The driver is compatible with PAL to work with PHY and GPHY devices. | ||
| 93 | |||
| 94 | 4.7) List of source files: | ||
| 95 | o Kconfig | ||
| 96 | o Makefile | ||
| 97 | o altera_tse_main.c: main network device driver | ||
| 98 | o altera_tse_ethtool.c: ethtool support | ||
| 99 | o altera_tse.h: private driver structure and common definitions | ||
| 100 | o altera_msgdma.h: MSGDMA implementation function definitions | ||
| 101 | o altera_sgdma.h: SGDMA implementation function definitions | ||
| 102 | o altera_msgdma.c: MSGDMA implementation | ||
| 103 | o altera_sgdma.c: SGDMA implementation | ||
| 104 | o altera_sgdmahw.h: SGDMA register and descriptor definitions | ||
| 105 | o altera_msgdmahw.h: MSGDMA register and descriptor definitions | ||
| 106 | o altera_utils.c: Driver utility functions | ||
| 107 | o altera_utils.h: Driver utility function definitions | ||
| 108 | |||
| 109 | 5) Debug Information | ||
| 110 | |||
| 111 | The driver exports debug information such as internal statistics, | ||
| 112 | debug information, MAC and DMA registers etc. | ||
| 113 | |||
| 114 | A user may use the ethtool support to get statistics: | ||
| 115 | e.g. using: ethtool -S ethX (that shows the statistics counters) | ||
| 116 | or sees the MAC registers: e.g. using: ethtool -d ethX | ||
| 117 | |||
| 118 | The developer can also use the "debug" module parameter to get | ||
| 119 | further debug information. | ||
| 120 | |||
| 121 | 6) Statistics Support | ||
| 122 | |||
| 123 | The controller and driver support a mix of IEEE standard defined statistics, | ||
| 124 | RFC defined statistics, and driver or Altera defined statistics. The four | ||
| 125 | specifications containing the standard definitions for these statistics are | ||
| 126 | as follows: | ||
| 127 | |||
| 128 | o IEEE 802.3-2012 - IEEE Standard for Ethernet. | ||
| 129 | o RFC 2863 found at http://www.rfc-editor.org/rfc/rfc2863.txt. | ||
| 130 | o RFC 2819 found at http://www.rfc-editor.org/rfc/rfc2819.txt. | ||
| 131 | o Altera Triple Speed Ethernet User Guide, found at http://www.altera.com | ||
| 132 | |||
| 133 | The statistics supported by the TSE and the device driver are as follows: | ||
| 134 | |||
| 135 | "tx_packets" is equivalent to aFramesTransmittedOK defined in IEEE 802.3-2012, | ||
| 136 | Section 5.2.2.1.2. This statistics is the count of frames that are successfully | ||
| 137 | transmitted. | ||
| 138 | |||
| 139 | "rx_packets" is equivalent to aFramesReceivedOK defined in IEEE 802.3-2012, | ||
| 140 | Section 5.2.2.1.5. This statistic is the count of frames that are successfully | ||
| 141 | received. This count does not include any error packets such as CRC errors, | ||
| 142 | length errors, or alignment errors. | ||
| 143 | |||
| 144 | "rx_crc_errors" is equivalent to aFrameCheckSequenceErrors defined in IEEE | ||
| 145 | 802.3-2012, Section 5.2.2.1.6. This statistic is the count of frames that are | ||
| 146 | an integral number of bytes in length and do not pass the CRC test as the frame | ||
| 147 | is received. | ||
| 148 | |||
| 149 | "rx_align_errors" is equivalent to aAlignmentErrors defined in IEEE 802.3-2012, | ||
| 150 | Section 5.2.2.1.7. This statistic is the count of frames that are not an | ||
| 151 | integral number of bytes in length and do not pass the CRC test as the frame is | ||
| 152 | received. | ||
| 153 | |||
| 154 | "tx_bytes" is equivalent to aOctetsTransmittedOK defined in IEEE 802.3-2012, | ||
| 155 | Section 5.2.2.1.8. This statistic is the count of data and pad bytes | ||
| 156 | successfully transmitted from the interface. | ||
| 157 | |||
| 158 | "rx_bytes" is equivalent to aOctetsReceivedOK defined in IEEE 802.3-2012, | ||
| 159 | Section 5.2.2.1.14. This statistic is the count of data and pad bytes | ||
| 160 | successfully received by the controller. | ||
| 161 | |||
| 162 | "tx_pause" is equivalent to aPAUSEMACCtrlFramesTransmitted defined in IEEE | ||
| 163 | 802.3-2012, Section 30.3.4.2. This statistic is a count of PAUSE frames | ||
| 164 | transmitted from the network controller. | ||
| 165 | |||
| 166 | "rx_pause" is equivalent to aPAUSEMACCtrlFramesReceived defined in IEEE | ||
| 167 | 802.3-2012, Section 30.3.4.3. This statistic is a count of PAUSE frames | ||
| 168 | received by the network controller. | ||
| 169 | |||
| 170 | "rx_errors" is equivalent to ifInErrors defined in RFC 2863. This statistic is | ||
| 171 | a count of the number of packets received containing errors that prevented the | ||
| 172 | packet from being delivered to a higher level protocol. | ||
| 173 | |||
| 174 | "tx_errors" is equivalent to ifOutErrors defined in RFC 2863. This statistic | ||
| 175 | is a count of the number of packets that could not be transmitted due to errors. | ||
| 176 | |||
| 177 | "rx_unicast" is equivalent to ifInUcastPkts defined in RFC 2863. This | ||
| 178 | statistic is a count of the number of packets received that were not addressed | ||
| 179 | to the broadcast address or a multicast group. | ||
| 180 | |||
| 181 | "rx_multicast" is equivalent to ifInMulticastPkts defined in RFC 2863. This | ||
| 182 | statistic is a count of the number of packets received that were addressed to | ||
| 183 | a multicast address group. | ||
| 184 | |||
| 185 | "rx_broadcast" is equivalent to ifInBroadcastPkts defined in RFC 2863. This | ||
| 186 | statistic is a count of the number of packets received that were addressed to | ||
| 187 | the broadcast address. | ||
| 188 | |||
| 189 | "tx_discards" is equivalent to ifOutDiscards defined in RFC 2863. This | ||
| 190 | statistic is the number of outbound packets not transmitted even though an | ||
| 191 | error was not detected. An example of a reason this might occur is to free up | ||
| 192 | internal buffer space. | ||
| 193 | |||
| 194 | "tx_unicast" is equivalent to ifOutUcastPkts defined in RFC 2863. This | ||
| 195 | statistic counts the number of packets transmitted that were not addressed to | ||
| 196 | a multicast group or broadcast address. | ||
| 197 | |||
| 198 | "tx_multicast" is equivalent to ifOutMulticastPkts defined in RFC 2863. This | ||
| 199 | statistic counts the number of packets transmitted that were addressed to a | ||
| 200 | multicast group. | ||
| 201 | |||
| 202 | "tx_broadcast" is equivalent to ifOutBroadcastPkts defined in RFC 2863. This | ||
| 203 | statistic counts the number of packets transmitted that were addressed to a | ||
| 204 | broadcast address. | ||
| 205 | |||
| 206 | "ether_drops" is equivalent to etherStatsDropEvents defined in RFC 2819. | ||
| 207 | This statistic counts the number of packets dropped due to lack of internal | ||
| 208 | controller resources. | ||
| 209 | |||
| 210 | "rx_total_bytes" is equivalent to etherStatsOctets defined in RFC 2819. | ||
| 211 | This statistic counts the total number of bytes received by the controller, | ||
| 212 | including error and discarded packets. | ||
| 213 | |||
| 214 | "rx_total_packets" is equivalent to etherStatsPkts defined in RFC 2819. | ||
| 215 | This statistic counts the total number of packets received by the controller, | ||
| 216 | including error, discarded, unicast, multicast, and broadcast packets. | ||
| 217 | |||
| 218 | "rx_undersize" is equivalent to etherStatsUndersizePkts defined in RFC 2819. | ||
| 219 | This statistic counts the number of correctly formed packets received less | ||
| 220 | than 64 bytes long. | ||
| 221 | |||
| 222 | "rx_oversize" is equivalent to etherStatsOversizePkts defined in RFC 2819. | ||
| 223 | This statistic counts the number of correctly formed packets greater than 1518 | ||
| 224 | bytes long. | ||
| 225 | |||
| 226 | "rx_64_bytes" is equivalent to etherStatsPkts64Octets defined in RFC 2819. | ||
| 227 | This statistic counts the total number of packets received that were 64 octets | ||
| 228 | in length. | ||
| 229 | |||
| 230 | "rx_65_127_bytes" is equivalent to etherStatsPkts65to127Octets defined in RFC | ||
| 231 | 2819. This statistic counts the total number of packets received that were | ||
| 232 | between 65 and 127 octets in length inclusive. | ||
| 233 | |||
| 234 | "rx_128_255_bytes" is equivalent to etherStatsPkts128to255Octets defined in | ||
| 235 | RFC 2819. This statistic is the total number of packets received that were | ||
| 236 | between 128 and 255 octets in length inclusive. | ||
| 237 | |||
| 238 | "rx_256_511_bytes" is equivalent to etherStatsPkts256to511Octets defined in | ||
| 239 | RFC 2819. This statistic is the total number of packets received that were | ||
| 240 | between 256 and 511 octets in length inclusive. | ||
| 241 | |||
| 242 | "rx_512_1023_bytes" is equivalent to etherStatsPkts512to1023Octets defined in | ||
| 243 | RFC 2819. This statistic is the total number of packets received that were | ||
| 244 | between 512 and 1023 octets in length inclusive. | ||
| 245 | |||
| 246 | "rx_1024_1518_bytes" is equivalent to etherStatsPkts1024to1518Octets define | ||
| 247 | in RFC 2819. This statistic is the total number of packets received that were | ||
| 248 | between 1024 and 1518 octets in length inclusive. | ||
| 249 | |||
| 250 | "rx_gte_1519_bytes" is a statistic defined specific to the behavior of the | ||
| 251 | Altera TSE. This statistics counts the number of received good and errored | ||
| 252 | frames between the length of 1519 and the maximum frame length configured | ||
| 253 | in the frm_length register. See the Altera TSE User Guide for More details. | ||
| 254 | |||
| 255 | "rx_jabbers" is equivalent to etherStatsJabbers defined in RFC 2819. This | ||
| 256 | statistic is the total number of packets received that were longer than 1518 | ||
| 257 | octets, and had either a bad CRC with an integral number of octets (CRC Error) | ||
| 258 | or a bad CRC with a non-integral number of octets (Alignment Error). | ||
| 259 | |||
| 260 | "rx_runts" is equivalent to etherStatsFragments defined in RFC 2819. This | ||
| 261 | statistic is the total number of packets received that were less than 64 octets | ||
| 262 | in length and had either a bad CRC with an integral number of octets (CRC | ||
| 263 | error) or a bad CRC with a non-integral number of octets (Alignment Error). | ||
| @@ -270,16 +270,15 @@ arp_ip_target · 269 unmodified lines | |||
| 270 | arp_validate | 270 | arp_validate |
| 271 | 271 | ||
| 272 | Specifies whether or not ARP probes and replies should be | 272 | Specifies whether or not ARP probes and replies should be |
| 273 | validated in the active-backup mode. This causes the ARP | 273 | validated in any mode that supports arp monitoring, or whether |
| 274 | monitor to examine the incoming ARP requests and replies, and | 274 | non-ARP traffic should be filtered (disregarded) for link |
| 275 | only consider a slave to be up if it is receiving the | 275 | monitoring purposes. |
| 276 | appropriate ARP traffic. | ||
| 277 | 276 | ||
| 278 | Possible values are: | 277 | Possible values are: |
| 279 | 278 | ||
| 280 | none or 0 | 279 | none or 0 |
| 281 | 280 | ||
| 282 | No validation is performed. This is the default. | 281 | No validation or filtering is performed. |
| 283 | 282 | ||
| 284 | active or 1 | 283 | active or 1 |
| 285 | 284 | ||
| @@ -293,31 +292,68 @@ arp_validate · 7 unmodified lines | |||
| 293 | 292 | ||
| 294 | Validation is performed for all slaves. | 293 | Validation is performed for all slaves. |
| 295 | 294 | ||
| 296 | For the active slave, the validation checks ARP replies to | 295 | filter or 4 |
| 297 | confirm that they were generated by an arp_ip_target. Since | 296 | |
| 298 | backup slaves do not typically receive these replies, the | 297 | Filtering is applied to all slaves. No validation is |
| 299 | validation performed for backup slaves is on the ARP request | 298 | performed. |
| 300 | sent out via the active slave. It is possible that some | 299 | |
| 301 | switch or network configurations may result in situations | 300 | filter_active or 5 |
| 302 | wherein the backup slaves do not receive the ARP requests; in | 301 | |
| 303 | such a situation, validation of backup slaves must be | 302 | Filtering is applied to all slaves, validation is performed |
| 304 | disabled. | 303 | only for the active slave. |
| 305 | 304 | ||
| 306 | The validation of ARP requests on backup slaves is mainly | 305 | filter_backup or 6 |
| 307 | helping bonding to decide which slaves are more likely to | 306 | |
| 308 | work in case of the active slave failure, it doesn't really | 307 | Filtering is applied to all slaves, validation is performed |
| 309 | guarantee that the backup slave will work if it's selected | 308 | only for backup slaves. |
| 310 | as the next active slave. | 309 | |
| 311 | 310 | Validation: | |
| 312 | This option is useful in network configurations in which | 311 | |
| 313 | multiple bonding hosts are concurrently issuing ARPs to one or | 312 | Enabling validation causes the ARP monitor to examine the incoming |
| 314 | more targets beyond a common switch. Should the link between | 313 | ARP requests and replies, and only consider a slave to be up if it |
| 315 | the switch and target fail (but not the switch itself), the | 314 | is receiving the appropriate ARP traffic. |
| 316 | probe traffic generated by the multiple bonding instances will | 315 | |
| 317 | fool the standard ARP monitor into considering the links as | 316 | For an active slave, the validation checks ARP replies to confirm |
| 318 | still up. Use of the arp_validate option can resolve this, as | 317 | that they were generated by an arp_ip_target. Since backup slaves |
| 319 | the ARP monitor will only consider ARP requests and replies | 318 | do not typically receive these replies, the validation performed |
| 320 | associated with its own instance of bonding. | 319 | for backup slaves is on the broadcast ARP request sent out via the |
| 320 | active slave. It is possible that some switch or network | ||
| 321 | configurations may result in situations wherein the backup slaves | ||
| 322 | do not receive the ARP requests; in such a situation, validation | ||
| 323 | of backup slaves must be disabled. | ||
| 324 | |||
| 325 | The validation of ARP requests on backup slaves is mainly helping | ||
| 326 | bonding to decide which slaves are more likely to work in case of | ||
| 327 | the active slave failure, it doesn't really guarantee that the | ||
| 328 | backup slave will work if it's selected as the next active slave. | ||
| 329 | |||
| 330 | Validation is useful in network configurations in which multiple | ||
| 331 | bonding hosts are concurrently issuing ARPs to one or more targets | ||
| 332 | beyond a common switch. Should the link between the switch and | ||
| 333 | target fail (but not the switch itself), the probe traffic | ||
| 334 | generated by the multiple bonding instances will fool the standard | ||
| 335 | ARP monitor into considering the links as still up. Use of | ||
| 336 | validation can resolve this, as the ARP monitor will only consider | ||
| 337 | ARP requests and replies associated with its own instance of | ||
| 338 | bonding. | ||
| 339 | |||
| 340 | Filtering: | ||
| 341 | |||
| 342 | Enabling filtering causes the ARP monitor to only use incoming ARP | ||
| 343 | packets for link availability purposes. Arriving packets that are | ||
| 344 | not ARPs are delivered normally, but do not count when determining | ||
| 345 | if a slave is available. | ||
| 346 | |||
| 347 | Filtering operates by only considering the reception of ARP | ||
| 348 | packets (any ARP packet, regardless of source or destination) when | ||
| 349 | determining if a slave has received traffic for link availability | ||
| 350 | purposes. | ||
| 351 | |||
| 352 | Filtering is useful in network configurations in which significant | ||
| 353 | levels of third party broadcast traffic would fool the standard | ||
| 354 | ARP monitor into considering the links as still up. Use of | ||
| 355 | filtering can resolve this, as only ARP traffic is considered for | ||
| 356 | link availability purposes. | ||
| 321 | 357 | ||
| 322 | This option was added in bonding version 3.1.0. | 358 | This option was added in bonding version 3.1.0. |
| 323 | 359 | ||
| @@ -1017,7 +1017,7 @@ solution for a couple of reasons: · 1016 unmodified lines | |||
| 1017 | in case of a bus-off condition after the specified delay time | 1017 | in case of a bus-off condition after the specified delay time |
| 1018 | in milliseconds. By default it's off. | 1018 | in milliseconds. By default it's off. |
| 1019 | 1019 | ||
| 1020 | "bitrate 125000 sample_point 0.875" | 1020 | "bitrate 125000 sample-point 0.875" |
| 1021 | Shows the real bit-rate in bits/sec and the sample-point in the | 1021 | Shows the real bit-rate in bits/sec and the sample-point in the |
| 1022 | range 0.000..0.999. If the calculation of bit-timing parameters | 1022 | range 0.000..0.999. If the calculation of bit-timing parameters |
| 1023 | is enabled in the kernel (CONFIG_CAN_CALC_BITTIMING=y), the | 1023 | is enabled in the kernel (CONFIG_CAN_CALC_BITTIMING=y), the |
| @@ -546,6 +546,130 @@ ffffffffa0069c8f + <x>: · 545 unmodified lines | |||
| 546 | For BPF JIT developers, bpf_jit_disasm, bpf_asm and bpf_dbg provides a useful | 546 | For BPF JIT developers, bpf_jit_disasm, bpf_asm and bpf_dbg provides a useful |
| 547 | toolchain for developing and testing the kernel's JIT compiler. | 547 | toolchain for developing and testing the kernel's JIT compiler. |
| 548 | 548 | ||
| 549 | BPF kernel internals | ||
| 550 | -------------------- | ||
| 551 | Internally, for the kernel interpreter, a different BPF instruction set | ||
| 552 | format with similar underlying principles from BPF described in previous | ||
| 553 | paragraphs is being used. However, the instruction set format is modelled | ||
| 554 | closer to the underlying architecture to mimic native instruction sets, so | ||
| 555 | that a better performance can be achieved (more details later). | ||
| 556 | |||
| 557 | It is designed to be JITed with one to one mapping, which can also open up | ||
| 558 | the possibility for GCC/LLVM compilers to generate optimized BPF code through | ||
| 559 | a BPF backend that performs almost as fast as natively compiled code. | ||
| 560 | |||
| 561 | The new instruction set was originally designed with the possible goal in | ||
| 562 | mind to write programs in "restricted C" and compile into BPF with a optional | ||
| 563 | GCC/LLVM backend, so that it can just-in-time map to modern 64-bit CPUs with | ||
| 564 | minimal performance overhead over two steps, that is, C -> BPF -> native code. | ||
| 565 | |||
| 566 | Currently, the new format is being used for running user BPF programs, which | ||
| 567 | includes seccomp BPF, classic socket filters, cls_bpf traffic classifier, | ||
| 568 | team driver's classifier for its load-balancing mode, netfilter's xt_bpf | ||
| 569 | extension, PTP dissector/classifier, and much more. They are all internally | ||
| 570 | converted by the kernel into the new instruction set representation and run | ||
| 571 | in the extended interpreter. For in-kernel handlers, this all works | ||
| 572 | transparently by using sk_unattached_filter_create() for setting up the | ||
| 573 | filter, resp. sk_unattached_filter_destroy() for destroying it. The macro | ||
| 574 | SK_RUN_FILTER(filter, ctx) transparently invokes the right BPF function to | ||
| 575 | run the filter. 'filter' is a pointer to struct sk_filter that we got from | ||
| 576 | sk_unattached_filter_create(), and 'ctx' the given context (e.g. skb pointer). | ||
| 577 | All constraints and restrictions from sk_chk_filter() apply before a | ||
| 578 | conversion to the new layout is being done behind the scenes! | ||
| 579 | |||
| 580 | Currently, for JITing, the user BPF format is being used and current BPF JIT | ||
| 581 | compilers reused whenever possible. In other words, we do not (yet!) perform | ||
| 582 | a JIT compilation in the new layout, however, future work will successively | ||
| 583 | migrate traditional JIT compilers into the new instruction format as well, so | ||
| 584 | that they will profit from the very same benefits. Thus, when speaking about | ||
| 585 | JIT in the following, a JIT compiler (TBD) for the new instruction format is | ||
| 586 | meant in this context. | ||
| 587 | |||
| 588 | Some core changes of the new internal format: | ||
| 589 | |||
| 590 | - Number of registers increase from 2 to 10: | ||
| 591 | |||
| 592 | The old format had two registers A and X, and a hidden frame pointer. The | ||
| 593 | new layout extends this to be 10 internal registers and a read-only frame | ||
| 594 | pointer. Since 64-bit CPUs are passing arguments to functions via registers | ||
| 595 | the number of args from BPF program to in-kernel function is restricted | ||
| 596 | to 5 and one register is used to accept return value from an in-kernel | ||
| 597 | function. Natively, x86_64 passes first 6 arguments in registers, aarch64/ | ||
| 598 | sparcv9/mips64 have 7 - 8 registers for arguments; x86_64 has 6 callee saved | ||
| 599 | registers, and aarch64/sparcv9/mips64 have 11 or more callee saved registers. | ||
| 600 | |||
| 601 | Therefore, BPF calling convention is defined as: | ||
| 602 | |||
| 603 | * R0 - return value from in-kernel function | ||
| 604 | * R1 - R5 - arguments from BPF program to in-kernel function | ||
| 605 | * R6 - R9 - callee saved registers that in-kernel function will preserve | ||
| 606 | * R10 - read-only frame pointer to access stack | ||
| 607 | |||
| 608 | Thus, all BPF registers map one to one to HW registers on x86_64, aarch64, | ||
| 609 | etc, and BPF calling convention maps directly to ABIs used by the kernel on | ||
| 610 | 64-bit architectures. | ||
| 611 | |||
| 612 | On 32-bit architectures JIT may map programs that use only 32-bit arithmetic | ||
| 613 | and may let more complex programs to be interpreted. | ||
| 614 | |||
| 615 | R0 - R5 are scratch registers and BPF program needs spill/fill them if | ||
| 616 | necessary across calls. Note that there is only one BPF program (== one BPF | ||
| 617 | main routine) and it cannot call other BPF functions, it can only call | ||
| 618 | predefined in-kernel functions, though. | ||
| 619 | |||
| 620 | - Register width increases from 32-bit to 64-bit: | ||
| 621 | |||
| 622 | Still, the semantics of the original 32-bit ALU operations are preserved | ||
| 623 | via 32-bit subregisters. All BPF registers are 64-bit with 32-bit lower | ||
| 624 | subregisters that zero-extend into 64-bit if they are being written to. | ||
| 625 | That behavior maps directly to x86_64 and arm64 subregister definition, but | ||
| 626 | makes other JITs more difficult. | ||
| 627 | |||
| 628 | 32-bit architectures run 64-bit internal BPF programs via interpreter. | ||
| 629 | Their JITs may convert BPF programs that only use 32-bit subregisters into | ||
| 630 | native instruction set and let the rest being interpreted. | ||
| 631 | |||
| 632 | Operation is 64-bit, because on 64-bit architectures, pointers are also | ||
| 633 | 64-bit wide, and we want to pass 64-bit values in/out of kernel functions, | ||
| 634 | so 32-bit BPF registers would otherwise require to define register-pair | ||
| 635 | ABI, thus, there won't be able to use a direct BPF register to HW register | ||
| 636 | mapping and JIT would need to do combine/split/move operations for every | ||
| 637 | register in and out of the function, which is complex, bug prone and slow. | ||
| 638 | Another reason is the use of atomic 64-bit counters. | ||
| 639 | |||
| 640 | - Conditional jt/jf targets replaced with jt/fall-through: | ||
| 641 | |||
| 642 | While the original design has constructs such as "if (cond) jump_true; | ||
| 643 | else jump_false;", they are being replaced into alternative constructs like | ||
| 644 | "if (cond) jump_true; /* else fall-through */". | ||
| 645 | |||
| 646 | - Introduces bpf_call insn and register passing convention for zero overhead | ||
| 647 | calls from/to other kernel functions: | ||
| 648 | |||
| 649 | After a kernel function call, R1 - R5 are reset to unreadable and R0 has a | ||
| 650 | return type of the function. Since R6 - R9 are callee saved, their state is | ||
| 651 | preserved across the call. | ||
| 652 | |||
| 653 | Also in the new design, BPF is limited to 4096 insns, which means that any | ||
| 654 | program will terminate quickly and will only call a fixed number of kernel | ||
| 655 | functions. Original BPF and the new format are two operand instructions, | ||
| 656 | which helps to do one-to-one mapping between BPF insn and x86 insn during JIT. | ||
| 657 | |||
| 658 | The input context pointer for invoking the interpreter function is generic, | ||
| 659 | its content is defined by a specific use case. For seccomp register R1 points | ||
| 660 | to seccomp_data, for converted BPF filters R1 points to a skb. | ||
| 661 | |||
| 662 | A program, that is translated internally consists of the following elements: | ||
| 663 | |||
| 664 | op:16, jt:8, jf:8, k:32 ==> op:8, a_reg:4, x_reg:4, off:16, imm:32 | ||
| 665 | |||
| 666 | Just like the original BPF, the new format runs within a controlled environment, | ||
| 667 | is deterministic and the kernel can easily prove that. The safety of the program | ||
| 668 | can be determined in two steps: first step does depth-first-search to disallow | ||
| 669 | loops and other CFG validation; second step starts from the first insn and | ||
| 670 | descends all possible paths. It simulates execution of every insn and observes | ||
| 671 | the state change of registers and stack. | ||
| 672 | |||
| 549 | Misc | 673 | Misc |
| 550 | ---- | 674 | ---- |
| 551 | 675 | ||
| @@ -561,3 +685,4 @@ the underlying architecture. · 9 unmodified lines | |||
| 561 | 685 | ||
| 562 | Jay Schulist <jschlst@samba.org> | 686 | Jay Schulist <jschlst@samba.org> |
| 563 | Daniel Borkmann <dborkman@redhat.com> | 687 | Daniel Borkmann <dborkman@redhat.com> |
| 688 | Alexei Starovoitov <ast@plumgrid.com> | ||
| @@ -1,38 +1,8 @@ | |||
| 1 | The Gianfar Ethernet Driver | 1 | The Gianfar Ethernet Driver |
| 2 | Sysfs File description | ||
| 3 | 2 | ||
| 4 | Author: Andy Fleming <afleming@freescale.com> | 3 | Author: Andy Fleming <afleming@freescale.com> |
| 5 | Updated: 2005-07-28 | 4 | Updated: 2005-07-28 |
| 6 | 5 | ||
| 7 | SYSFS | ||
| 8 | |||
| 9 | Several of the features of the gianfar driver are controlled | ||
| 10 | through sysfs files. These are: | ||
| 11 | |||
| 12 | bd_stash: | ||
| 13 | To stash RX Buffer Descriptors in the L2, echo 'on' or '1' to | ||
| 14 | bd_stash, echo 'off' or '0' to disable | ||
| 15 | |||
| 16 | rx_stash_len: | ||
| 17 | To stash the first n bytes of the packet in L2, echo the number | ||
| 18 | of bytes to buf_stash_len. echo 0 to disable. | ||
| 19 | |||
| 20 | WARNING: You could really screw these up if you set them too low or high! | ||
| 21 | fifo_threshold: | ||
| 22 | To change the number of bytes the controller needs in the | ||
| 23 | fifo before it starts transmission, echo the number of bytes to | ||
| 24 | fifo_thresh. Range should be 0-511. | ||
| 25 | |||
| 26 | fifo_starve: | ||
| 27 | When the FIFO has less than this many bytes during a transmit, it | ||
| 28 | enters starve mode, and increases the priority of TX memory | ||
| 29 | transactions. To change, echo the number of bytes to | ||
| 30 | fifo_starve. Range should be 0-511. | ||
| 31 | |||
| 32 | fifo_starve_off: | ||
| 33 | Once in starve mode, the FIFO remains there until it has this | ||
| 34 | many bytes. To change, echo the number of bytes to | ||
| 35 | fifo_starve_off. Range should be 0-511. | ||
| 36 | 6 | ||
| 37 | CHECKSUM OFFLOADING | 7 | CHECKSUM OFFLOADING |
| 38 | 8 | ||
| @@ -36,54 +36,6 @@ Default Value: 0 · 35 unmodified lines | |||
| 36 | This parameter adds support for SR-IOV. It causes the driver to spawn up to | 36 | This parameter adds support for SR-IOV. It causes the driver to spawn up to |
| 37 | max_vfs worth of virtual function. | 37 | max_vfs worth of virtual function. |
| 38 | 38 | ||
| 39 | QueuePairs | ||
| 40 | ---------- | ||
| 41 | Valid Range: 0-1 | ||
| 42 | Default Value: 1 (TX and RX will be paired onto one interrupt vector) | ||
| 43 | |||
| 44 | If set to 0, when MSI-X is enabled, the TX and RX will attempt to occupy | ||
| 45 | separate vectors. | ||
| 46 | |||
| 47 | This option can be overridden to 1 if there are not sufficient interrupts | ||
| 48 | available. This can occur if any combination of RSS, VMDQ, and max_vfs | ||
| 49 | results in more than 4 queues being used. | ||
| 50 | |||
| 51 | Node | ||
| 52 | ---- | ||
| 53 | Valid Range: 0-n | ||
| 54 | Default Value: -1 (off) | ||
| 55 | |||
| 56 | 0 - n: where n is the number of the NUMA node that should be used to | ||
| 57 | allocate memory for this adapter port. | ||
| 58 | -1: uses the driver default of allocating memory on whichever processor is | ||
| 59 | running insmod/modprobe. | ||
| 60 | |||
| 61 | The Node parameter will allow you to pick which NUMA node you want to have | ||
| 62 | the adapter allocate memory from. All driver structures, in-memory queues, | ||
| 63 | and receive buffers will be allocated on the node specified. This parameter | ||
| 64 | is only useful when interrupt affinity is specified, otherwise some portion | ||
| 65 | of the time the interrupt could run on a different core than the memory is | ||
| 66 | allocated on, causing slower memory access and impacting throughput, CPU, or | ||
| 67 | both. | ||
| 68 | |||
| 69 | EEE | ||
| 70 | --- | ||
| 71 | Valid Range: 0-1 | ||
| 72 | Default Value: 1 (enabled) | ||
| 73 | |||
| 74 | A link between two EEE-compliant devices will result in periodic bursts of | ||
| 75 | data followed by long periods where in the link is in an idle state. This Low | ||
| 76 | Power Idle (LPI) state is supported in both 1Gbps and 100Mbps link speeds. | ||
| 77 | NOTE: EEE support requires autonegotiation. | ||
| 78 | |||
| 79 | DMAC | ||
| 80 | ---- | ||
| 81 | Valid Range: 0-1 | ||
| 82 | Default Value: 1 (enabled) | ||
| 83 | Enables or disables DMA Coalescing feature. | ||
| 84 | |||
| 85 | |||
| 86 | |||
| 87 | Additional Configurations | 39 | Additional Configurations |
| 88 | ========================= | 40 | ========================= |
| 89 | 41 | ||
| @@ -48,7 +48,7 @@ The MDIO bus · 47 unmodified lines | |||
| 48 | time, so it is safe for them to block, waiting for an interrupt to signal | 48 | time, so it is safe for them to block, waiting for an interrupt to signal |
| 49 | the operation is complete | 49 | the operation is complete |
| 50 | 50 | ||
| 51 | 2) A reset function is necessary. This is used to return the bus to an | 51 | 2) A reset function is optional. This is used to return the bus to an |
| 52 | initialized state. | 52 | initialized state. |
| 53 | 53 | ||
| 54 | 3) A probe function is needed. This function should set up anything the bus | 54 | 3) A probe function is needed. This function should set up anything the bus |
| @@ -253,16 +253,25 @@ Writing a PHY driver · 198 unmodified lines | |||
| 253 | 253 | ||
| 254 | Each driver consists of a number of function pointers: | 254 | Each driver consists of a number of function pointers: |
| 255 | 255 | ||
| 256 | soft_reset: perform a PHY software reset | ||
| 256 | config_init: configures PHY into a sane state after a reset. | 257 | config_init: configures PHY into a sane state after a reset. |
| 257 | For instance, a Davicom PHY requires descrambling disabled. | 258 | For instance, a Davicom PHY requires descrambling disabled. |
| 258 | probe: Allocate phy->priv, optionally refuse to bind. | 259 | probe: Allocate phy->priv, optionally refuse to bind. |
| 259 | PHY may not have been reset or had fixups run yet. | 260 | PHY may not have been reset or had fixups run yet. |
| 260 | suspend/resume: power management | 261 | suspend/resume: power management |
| 261 | config_aneg: Changes the speed/duplex/negotiation settings | 262 | config_aneg: Changes the speed/duplex/negotiation settings |
| 263 | aneg_done: Determines the auto-negotiation result | ||
| 262 | read_status: Reads the current speed/duplex/negotiation settings | 264 | read_status: Reads the current speed/duplex/negotiation settings |
| 263 | ack_interrupt: Clear a pending interrupt | 265 | ack_interrupt: Clear a pending interrupt |
| 266 | did_interrupt: Checks if the PHY generated an interrupt | ||
| 264 | config_intr: Enable or disable interrupts | 267 | config_intr: Enable or disable interrupts |
| 265 | remove: Does any driver take-down | 268 | remove: Does any driver take-down |
| 269 | ts_info: Queries about the HW timestamping status | ||
| 270 | hwtstamp: Set the PHY HW timestamping configuration | ||
| 271 | rxtstamp: Requests a receive timestamp at the PHY level for a 'skb' | ||
| 272 | txtsamp: Requests a transmit timestamp at the PHY level for a 'skb' | ||
| 273 | set_wol: Enable Wake-on-LAN at the PHY level | ||
| 274 | get_wol: Get the Wake-on-LAN status at the PHY level | ||
| 266 | 275 | ||
| 267 | Of these, only config_aneg and read_status are required to be | 276 | Of these, only config_aneg and read_status are required to be |
| 268 | assigned by the driver code. The rest are optional. Also, it is | 277 | assigned by the driver code. The rest are optional. Also, it is |
| @@ -102,13 +102,18 @@ Examples: · 101 unmodified lines | |||
| 102 | The 'minimum' MAC is what you set with dstmac. | 102 | The 'minimum' MAC is what you set with dstmac. |
| 103 | 103 | ||
| 104 | pgset "flag [name]" Set a flag to determine behaviour. Current flags | 104 | pgset "flag [name]" Set a flag to determine behaviour. Current flags |
| 105 | are: IPSRC_RND #IP Source is random (between min/max), | 105 | are: IPSRC_RND # IP source is random (between min/max) |
| 106 | IPDST_RND, UDPSRC_RND, | 106 | IPDST_RND # IP destination is random |
| 107 | UDPDST_RND, MACSRC_RND, MACDST_RND | 107 | UDPSRC_RND, UDPDST_RND, |
| 108 | MACSRC_RND, MACDST_RND | ||
| 109 | TXSIZE_RND, IPV6, | ||
| 108 | MPLS_RND, VID_RND, SVID_RND | 110 | MPLS_RND, VID_RND, SVID_RND |
| 111 | FLOW_SEQ, | ||
| 109 | QUEUE_MAP_RND # queue map random | 112 | QUEUE_MAP_RND # queue map random |
| 110 | QUEUE_MAP_CPU # queue map mirrors smp_processor_id() | 113 | QUEUE_MAP_CPU # queue map mirrors smp_processor_id() |
| 111 | IPSEC # Make IPsec encapsulation for packet | 114 | UDPCSUM, |
| 115 | IPSEC # IPsec encapsulation (needs CONFIG_XFRM) | ||
| 116 | NODE_ALLOC # node specific memory allocation | ||
| 112 | 117 | ||
| 113 | pgset spi SPI_VALUE Set specific SA used to transform packet. | 118 | pgset spi SPI_VALUE Set specific SA used to transform packet. |
| 114 | 119 | ||
| @@ -233,13 +238,22 @@ udp_dst_max · 118 unmodified lines | |||
| 233 | 238 | ||
| 234 | flag | 239 | flag |
| 235 | IPSRC_RND | 240 | IPSRC_RND |
| 236 | TXSIZE_RND | ||
| 237 | IPDST_RND | 241 | IPDST_RND |
| 238 | UDPSRC_RND | 242 | UDPSRC_RND |
| 239 | UDPDST_RND | 243 | UDPDST_RND |
| 240 | MACSRC_RND | 244 | MACSRC_RND |
| 241 | MACDST_RND | 245 | MACDST_RND |
| 246 | TXSIZE_RND | ||
| 247 | IPV6 | ||
| 248 | MPLS_RND | ||
| 249 | VID_RND | ||
| 250 | SVID_RND | ||
| 251 | FLOW_SEQ | ||
| 252 | QUEUE_MAP_RND | ||
| 253 | QUEUE_MAP_CPU | ||
| 254 | UDPCSUM | ||
| 242 | IPSEC | 255 | IPSEC |
| 256 | NODE_ALLOC | ||
| 243 | 257 | ||
| 244 | dst_min | 258 | dst_min |
| 245 | dst_max | 259 | dst_max |
| @@ -27,6 +27,8 @@ Contents of this document: · 26 unmodified lines | |||
| 27 | 27 | ||
| 28 | (*) AF_RXRPC kernel interface. | 28 | (*) AF_RXRPC kernel interface. |
| 29 | 29 | ||
| 30 | (*) Configurable parameters. | ||
| 31 | |||
| 30 | 32 | ||
| 31 | ======== | 33 | ======== |
| 32 | OVERVIEW | 34 | OVERVIEW |
| @@ -864,3 +866,82 @@ The kernel interface functions are as follows: · 831 unmodified lines | |||
| 864 | 866 | ||
| 865 | This is used to allocate a null RxRPC key that can be used to indicate | 867 | This is used to allocate a null RxRPC key that can be used to indicate |
| 866 | anonymous security for a particular domain. | 868 | anonymous security for a particular domain. |
| 869 | |||
| 870 | |||
| 871 | ======================= | ||
| 872 | CONFIGURABLE PARAMETERS | ||
| 873 | ======================= | ||
| 874 | |||
| 875 | The RxRPC protocol driver has a number of configurable parameters that can be | ||
| 876 | adjusted through sysctls in /proc/net/rxrpc/: | ||
| 877 | |||
| 878 | (*) req_ack_delay | ||
| 879 | |||
| 880 | The amount of time in milliseconds after receiving a packet with the | ||
| 881 | request-ack flag set before we honour the flag and actually send the | ||
| 882 | requested ack. | ||
| 883 | |||
| 884 | Usually the other side won't stop sending packets until the advertised | ||
| 885 | reception window is full (to a maximum of 255 packets), so delaying the | ||
| 886 | ACK permits several packets to be ACK'd in one go. | ||
| 887 | |||
| 888 | (*) soft_ack_delay | ||
| 889 | |||
| 890 | The amount of time in milliseconds after receiving a new packet before we | ||
| 891 | generate a soft-ACK to tell the sender that it doesn't need to resend. | ||
| 892 | |||
| 893 | (*) idle_ack_delay | ||
| 894 | |||
| 895 | The amount of time in milliseconds after all the packets currently in the | ||
| 896 | received queue have been consumed before we generate a hard-ACK to tell | ||
| 897 | the sender it can free its buffers, assuming no other reason occurs that | ||
| 898 | we would send an ACK. | ||
| 899 | |||
| 900 | (*) resend_timeout | ||
| 901 | |||
| 902 | The amount of time in milliseconds after transmitting a packet before we | ||
| 903 | transmit it again, assuming no ACK is received from the receiver telling | ||
| 904 | us they got it. | ||
| 905 | |||
| 906 | (*) max_call_lifetime | ||
| 907 | |||
| 908 | The maximum amount of time in seconds that a call may be in progress | ||
| 909 | before we preemptively kill it. | ||
| 910 | |||
| 911 | (*) dead_call_expiry | ||
| 912 | |||
| 913 | The amount of time in seconds before we remove a dead call from the call | ||
| 914 | list. Dead calls are kept around for a little while for the purpose of | ||
| 915 | repeating ACK and ABORT packets. | ||
| 916 | |||
| 917 | (*) connection_expiry | ||
| 918 | |||
| 919 | The amount of time in seconds after a connection was last used before we | ||
| 920 | remove it from the connection list. Whilst a connection is in existence, | ||
| 921 | it serves as a placeholder for negotiated security; when it is deleted, | ||
| 922 | the security must be renegotiated. | ||
| 923 | |||
| 924 | (*) transport_expiry | ||
| 925 | |||
| 926 | The amount of time in seconds after a transport was last used before we | ||
| 927 | remove it from the transport list. Whilst a transport is in existence, it | ||
| 928 | serves to anchor the peer data and keeps the connection ID counter. | ||
| 929 | |||
| 930 | (*) rxrpc_rx_window_size | ||
| 931 | |||
| 932 | The size of the receive window in packets. This is the maximum number of | ||
| 933 | unconsumed received packets we're willing to hold in memory for any | ||
| 934 | particular call. | ||
| 935 | |||
| 936 | (*) rxrpc_rx_mtu | ||
| 937 | |||
| 938 | The maximum packet MTU size that we're willing to receive in bytes. This | ||
| 939 | indicates to the peer whether we're willing to accept jumbo packets. | ||
| 940 | |||
| 941 | (*) rxrpc_rx_jumbo_max | ||
| 942 | |||
| 943 | The maximum number of packets that we're willing to accept in a jumbo | ||
| 944 | packet. Non-terminal packets in a jumbo packet must contain a four byte | ||
| 945 | header plus exactly 1412 bytes of data. The terminal packet must contain | ||
| 946 | a four byte header plus any amount of data. In any event, a jumbo packet | ||
| 947 | may not exceed rxrpc_rx_mtu in size. | ||
| @@ -30,7 +30,7 @@ A congestion control mechanism can be registered through functions in · 29 unmodified lines | |||
| 30 | tcp_cong.c. The functions used by the congestion control mechanism are | 30 | tcp_cong.c. The functions used by the congestion control mechanism are |
| 31 | registered via passing a tcp_congestion_ops struct to | 31 | registered via passing a tcp_congestion_ops struct to |
| 32 | tcp_register_congestion_control. As a minimum name, ssthresh, | 32 | tcp_register_congestion_control. As a minimum name, ssthresh, |
| 33 | cong_avoid, min_cwnd must be valid. | 33 | cong_avoid must be valid. |
| 34 | 34 | ||
| 35 | Private data for a congestion control mechanism is stored in tp->ca_priv. | 35 | Private data for a congestion control mechanism is stored in tp->ca_priv. |
| 36 | tcp_ca(tp) returns a pointer to this space. This is preallocated space - it | 36 | tcp_ca(tp) returns a pointer to this space. This is preallocated space - it |
| @@ -202,6 +202,9 @@ Time stamps for outgoing packets are to be generated as follows: · 201 unmodified lines | |||
| 202 | and not free the skb. A driver not supporting hardware time stamping doesn't | 202 | and not free the skb. A driver not supporting hardware time stamping doesn't |
| 203 | do that. A driver must never touch sk_buff::tstamp! It is used to store | 203 | do that. A driver must never touch sk_buff::tstamp! It is used to store |
| 204 | software generated time stamps by the network subsystem. | 204 | software generated time stamps by the network subsystem. |
| 205 | - Driver should call skb_tx_timestamp() as close to passing sk_buff to hardware | ||
| 206 | as possible. skb_tx_timestamp() provides a software time stamp if requested | ||
| 207 | and hardware timestamping is not possible (SKBTX_IN_PROGRESS not set). | ||
| 205 | - As soon as the driver has sent the packet and/or obtained a | 208 | - As soon as the driver has sent the packet and/or obtained a |
| 206 | hardware time stamp for it, it passes the time stamp back by | 209 | hardware time stamp for it, it passes the time stamp back by |
| 207 | calling skb_hwtstamp_tx() with the original skb, the raw | 210 | calling skb_hwtstamp_tx() with the original skb, the raw |
| @@ -212,6 +215,3 @@ Time stamps for outgoing packets are to be generated as follows: · 4 unmodified lines | |||
| 212 | this would occur at a later time in the processing pipeline than other | 215 | this would occur at a later time in the processing pipeline than other |
| 213 | software time stamping and therefore could lead to unexpected deltas | 216 | software time stamping and therefore could lead to unexpected deltas |
| 214 | between time stamps. | 217 | between time stamps. |
| 215 | - If the driver did not set the SKBTX_IN_PROGRESS flag (see above), then | ||
| 216 | dev_hard_start_xmit() checks whether software time stamping | ||
| 217 | is wanted as fallback and potentially generates the time stamp. | ||
| @@ -19,6 +19,7 @@ · 18 unmodified lines | |||
| 19 | */ | 19 | */ |
| 20 | #include <errno.h> | 20 | #include <errno.h> |
| 21 | #include <fcntl.h> | 21 | #include <fcntl.h> |
| 22 | #include <inttypes.h> | ||
| 22 | #include <math.h> | 23 | #include <math.h> |
| 23 | #include <signal.h> | 24 | #include <signal.h> |
| 24 | #include <stdio.h> | 25 | #include <stdio.h> |
| @@ -120,11 +121,19 @@ static void usage(char *progname) · 95 unmodified lines | |||
| 120 | " -i val index for event/trigger\n" | 121 | " -i val index for event/trigger\n" |
| 121 | " -k val measure the time offset between system and phc clock\n" | 122 | " -k val measure the time offset between system and phc clock\n" |
| 122 | " for 'val' times (Maximum 25)\n" | 123 | " for 'val' times (Maximum 25)\n" |
| 124 | " -l list the current pin configuration\n" | ||
| 125 | " -L pin,val configure pin index 'pin' with function 'val'\n" | ||
| 126 | " the channel index is taken from the '-i' option\n" | ||
| 127 | " 'val' specifies the auxiliary function:\n" | ||
| 128 | " 0 - none\n" | ||
| 129 | " 1 - external time stamp\n" | ||
| 130 | " 2 - periodic output\n" | ||
| 123 | " -p val enable output with a period of 'val' nanoseconds\n" | 131 | " -p val enable output with a period of 'val' nanoseconds\n" |
| 124 | " -P val enable or disable (val=1|0) the system clock PPS\n" | 132 | " -P val enable or disable (val=1|0) the system clock PPS\n" |
| 125 | " -s set the ptp clock time from the system time\n" | 133 | " -s set the ptp clock time from the system time\n" |
| 126 | " -S set the system time from the ptp clock time\n" | 134 | " -S set the system time from the ptp clock time\n" |
| 127 | " -t val shift the ptp clock time by 'val' seconds\n", | 135 | " -t val shift the ptp clock time by 'val' seconds\n" |
| 136 | " -T val set the ptp clock time to 'val' seconds\n", | ||
| 128 | progname); | 137 | progname); |
| 129 | } | 138 | } |
| 130 | 139 | ||
| @@ -134,6 +143,7 @@ int main(int argc, char *argv[]) · 3 unmodified lines | |||
| 134 | struct ptp_extts_event event; | 143 | struct ptp_extts_event event; |
| 135 | struct ptp_extts_request extts_request; | 144 | struct ptp_extts_request extts_request; |
| 136 | struct ptp_perout_request perout_request; | 145 | struct ptp_perout_request perout_request; |
| 146 | struct ptp_pin_desc desc; | ||
| 137 | struct timespec ts; | 147 | struct timespec ts; |
| 138 | struct timex tx; | 148 | struct timex tx; |
| 139 | 149 | ||
| @@ -156,12 +166,15 @@ int main(int argc, char *argv[]) · 16 unmodified lines | |||
| 156 | int extts = 0; | 166 | int extts = 0; |
| 157 | int gettime = 0; | 167 | int gettime = 0; |
| 158 | int index = 0; | 168 | int index = 0; |
| 169 | int list_pins = 0; | ||
| 159 | int oneshot = 0; | 170 | int oneshot = 0; |
| 160 | int pct_offset = 0; | 171 | int pct_offset = 0; |
| 161 | int n_samples = 0; | 172 | int n_samples = 0; |
| 162 | int periodic = 0; | 173 | int periodic = 0; |
| 163 | int perout = -1; | 174 | int perout = -1; |
| 175 | int pin_index = -1, pin_func; | ||
| 164 | int pps = -1; | 176 | int pps = -1; |
| 177 | int seconds = 0; | ||
| 165 | int settime = 0; | 178 | int settime = 0; |
| 166 | 179 | ||
| 167 | int64_t t1, t2, tp; | 180 | int64_t t1, t2, tp; |
| @@ -169,7 +182,7 @@ int main(int argc, char *argv[]) · 1 unmodified line | |||
| 169 | 182 | ||
| 170 | progname = strrchr(argv[0], '/'); | 183 | progname = strrchr(argv[0], '/'); |
| 171 | progname = progname ? 1+progname : argv[0]; | 184 | progname = progname ? 1+progname : argv[0]; |
| 172 | while (EOF != (c = getopt(argc, argv, "a:A:cd:e:f:ghi:k:p:P:sSt:v"))) { | 185 | while (EOF != (c = getopt(argc, argv, "a:A:cd:e:f:ghi:k:lL:p:P:sSt:T:v"))) { |
| 173 | switch (c) { | 186 | switch (c) { |
| 174 | case 'a': | 187 | case 'a': |
| 175 | oneshot = atoi(optarg); | 188 | oneshot = atoi(optarg); |
| @@ -199,6 +212,16 @@ int main(int argc, char *argv[]) · 23 unmodified lines | |||
| 199 | pct_offset = 1; | 212 | pct_offset = 1; |
| 200 | n_samples = atoi(optarg); | 213 | n_samples = atoi(optarg); |
| 201 | break; | 214 | break; |
| 215 | case 'l': | ||
| 216 | list_pins = 1; | ||
| 217 | break; | ||
| 218 | case 'L': | ||
| 219 | cnt = sscanf(optarg, "%d,%d", &pin_index, &pin_func); | ||
| 220 | if (cnt != 2) { | ||
| 221 | usage(progname); | ||
| 222 | return -1; | ||
| 223 | } | ||
| 224 | break; | ||
| 202 | case 'p': | 225 | case 'p': |
| 203 | perout = atoi(optarg); | 226 | perout = atoi(optarg); |
| 204 | break; | 227 | break; |
| @@ -214,6 +237,10 @@ int main(int argc, char *argv[]) · 9 unmodified lines | |||
| 214 | case 't': | 237 | case 't': |
| 215 | adjtime = atoi(optarg); | 238 | adjtime = atoi(optarg); |
| 216 | break; | 239 | break; |
| 240 | case 'T': | ||
| 241 | settime = 3; | ||
| 242 | seconds = atoi(optarg); | ||
| 243 | break; | ||
| 217 | case 'h': | 244 | case 'h': |
| 218 | usage(progname); | 245 | usage(progname); |
| 219 | return 0; | 246 | return 0; |
| @@ -245,12 +272,14 @@ int main(int argc, char *argv[]) · 25 unmodified lines | |||
| 245 | " %d programmable alarms\n" | 272 | " %d programmable alarms\n" |
| 246 | " %d external time stamp channels\n" | 273 | " %d external time stamp channels\n" |
| 247 | " %d programmable periodic signals\n" | 274 | " %d programmable periodic signals\n" |
| 248 | " %d pulse per second\n", | 275 | " %d pulse per second\n" |
| 276 | " %d programmable pins\n", | ||
| 249 | caps.max_adj, | 277 | caps.max_adj, |
| 250 | caps.n_alarm, | 278 | caps.n_alarm, |
| 251 | caps.n_ext_ts, | 279 | caps.n_ext_ts, |
| 252 | caps.n_per_out, | 280 | caps.n_per_out, |
| 253 | caps.pps); | 281 | caps.pps, |
| 282 | caps.n_pins); | ||
| 254 | } | 283 | } |
| 255 | } | 284 | } |
| 256 | 285 | ||
| @@ -304,6 +333,16 @@ int main(int argc, char *argv[]) · 47 unmodified lines | |||
| 304 | } | 333 | } |
| 305 | } | 334 | } |
| 306 | 335 | ||
| 336 | if (settime == 3) { | ||
| 337 | ts.tv_sec = seconds; | ||
| 338 | ts.tv_nsec = 0; | ||
| 339 | if (clock_settime(clkid, &ts)) { | ||
| 340 | perror("clock_settime"); | ||
| 341 | } else { | ||
| 342 | puts("set time okay"); | ||
| 343 | } | ||
| 344 | } | ||
| 345 | |||
| 307 | if (extts) { | 346 | if (extts) { |
| 308 | memset(&extts_request, 0, sizeof(extts_request)); | 347 | memset(&extts_request, 0, sizeof(extts_request)); |
| 309 | extts_request.index = index; | 348 | extts_request.index = index; |
| @@ -331,6 +370,24 @@ int main(int argc, char *argv[]) · 21 unmodified lines | |||
| 331 | } | 370 | } |
| 332 | } | 371 | } |
| 333 | 372 | ||
| 373 | if (list_pins) { | ||
| 374 | int n_pins = 0; | ||
| 375 | if (ioctl(fd, PTP_CLOCK_GETCAPS, &caps)) { | ||
| 376 | perror("PTP_CLOCK_GETCAPS"); | ||
| 377 | } else { | ||
| 378 | n_pins = caps.n_pins; | ||
| 379 | } | ||
| 380 | for (i = 0; i < n_pins; i++) { | ||
| 381 | desc.index = i; | ||
| 382 | if (ioctl(fd, PTP_PIN_GETFUNC, &desc)) { | ||
| 383 | perror("PTP_PIN_GETFUNC"); | ||
| 384 | break; | ||
| 385 | } | ||
| 386 | printf("name %s index %u func %u chan %u\n", | ||
| 387 | desc.name, desc.index, desc.func, desc.chan); | ||
| 388 | } | ||
| 389 | } | ||
| 390 | |||
| 334 | if (oneshot) { | 391 | if (oneshot) { |
| 335 | install_handler(SIGALRM, handle_alarm); | 392 | install_handler(SIGALRM, handle_alarm); |
| 336 | /* Create a timer. */ | 393 | /* Create a timer. */ |
| @@ -392,6 +449,18 @@ int main(int argc, char *argv[]) · 55 unmodified lines | |||
| 392 | } | 449 | } |
| 393 | } | 450 | } |
| 394 | 451 | ||
| 452 | if (pin_index >= 0) { | ||
| 453 | memset(&desc, 0, sizeof(desc)); | ||
| 454 | desc.index = pin_index; | ||
| 455 | desc.func = pin_func; | ||
| 456 | desc.chan = index; | ||
| 457 | if (ioctl(fd, PTP_PIN_SETFUNC, &desc)) { | ||
| 458 | perror("PTP_PIN_SETFUNC"); | ||
| 459 | } else { | ||
| 460 | puts("set pin function okay"); | ||
| 461 | } | ||
| 462 | } | ||
| 463 | |||
| 395 | if (pps != -1) { | 464 | if (pps != -1) { |
| 396 | int enable = pps ? 1 : 0; | 465 | int enable = pps ? 1 : 0; |
| 397 | if (ioctl(fd, PTP_ENABLE_PPS, enable)) { | 466 | if (ioctl(fd, PTP_ENABLE_PPS, enable)) { |
| @@ -428,14 +497,14 @@ int main(int argc, char *argv[]) · 30 unmodified lines | |||
| 428 | interval = t2 - t1; | 497 | interval = t2 - t1; |
| 429 | offset = (t2 + t1) / 2 - tp; | 498 | offset = (t2 + t1) / 2 - tp; |
| 430 | 499 | ||
| 431 | printf("system time: %ld.%ld\n", | 500 | printf("system time: %" PRId64 ".%u\n", |
| 432 | (pct+2*i)->sec, (pct+2*i)->nsec); | 501 | (pct+2*i)->sec, (pct+2*i)->nsec); |
| 433 | printf("phc time: %ld.%ld\n", | 502 | printf("phc time: %" PRId64 ".%u\n", |
| 434 | (pct+2*i+1)->sec, (pct+2*i+1)->nsec); | 503 | (pct+2*i+1)->sec, (pct+2*i+1)->nsec); |
| 435 | printf("system time: %ld.%ld\n", | 504 | printf("system time: %" PRId64 ".%u\n", |
| 436 | (pct+2*i+2)->sec, (pct+2*i+2)->nsec); | 505 | (pct+2*i+2)->sec, (pct+2*i+2)->nsec); |
| 437 | printf("system/phc clock time offset is %ld ns\n" | 506 | printf("system/phc clock time offset is %" PRId64 " ns\n" |
| 438 | "system clock time delay is %ld ns\n", | 507 | "system clock time delay is %" PRId64 " ns\n", |
| 439 | offset, interval); | 508 | offset, interval); |
| 440 | } | 509 | } |
| 441 | 510 | ||
| @@ -536,6 +536,13 @@ S: Odd Fixes · 535 unmodified lines | |||
| 536 | L: linux-alpha@vger.kernel.org | 536 | L: linux-alpha@vger.kernel.org |
| 537 | F: arch/alpha/ | 537 | F: arch/alpha/ |
| 538 | 538 | ||
| 539 | ALTERA TRIPLE SPEED ETHERNET DRIVER | ||
| 540 | M: Vince Bridgers <vbridgers2013@gmail.com | ||
| 541 | L: netdev@vger.kernel.org | ||
| 542 | L: nios2-dev@lists.rocketboards.org (moderated for non-subscribers) | ||
| 543 | S: Maintained | ||
| 544 | F: drivers/net/ethernet/altera/ | ||
| 545 | |||
| 539 | ALTERA UART/JTAG UART SERIAL DRIVERS | 546 | ALTERA UART/JTAG UART SERIAL DRIVERS |
| 540 | M: Tobias Klauser <tklauser@distanz.ch> | 547 | M: Tobias Klauser <tklauser@distanz.ch> |
| 541 | L: linux-serial@vger.kernel.org | 548 | L: linux-serial@vger.kernel.org |
| @@ -1848,6 +1855,12 @@ L: netdev@vger.kernel.org · 1306 unmodified lines | |||
| 1848 | S: Supported | 1855 | S: Supported |
| 1849 | F: drivers/net/ethernet/broadcom/b44.* | 1856 | F: drivers/net/ethernet/broadcom/b44.* |
| 1850 | 1857 | ||
| 1858 | BROADCOM GENET ETHERNET DRIVER | ||
| 1859 | M: Florian Fainelli <f.fainelli@gmail.com> | ||
| 1860 | L: netdev@vger.kernel.org | ||
| 1861 | S: Supported | ||
| 1862 | F: drivers/net/ethernet/broadcom/genet/ | ||
| 1863 | |||
| 1851 | BROADCOM BNX2 GIGABIT ETHERNET DRIVER | 1864 | BROADCOM BNX2 GIGABIT ETHERNET DRIVER |
| 1852 | M: Michael Chan <mchan@broadcom.com> | 1865 | M: Michael Chan <mchan@broadcom.com> |
| 1853 | L: netdev@vger.kernel.org | 1866 | L: netdev@vger.kernel.org |
| @@ -6043,6 +6056,7 @@ L: netdev@vger.kernel.org · 4189 unmodified lines | |||
| 6043 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/klassert/ipsec.git | 6056 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/klassert/ipsec.git |
| 6044 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/klassert/ipsec-next.git | 6057 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/klassert/ipsec-next.git |
| 6045 | S: Maintained | 6058 | S: Maintained |
| 6059 | F: net/core/flow.c | ||
| 6046 | F: net/xfrm/ | 6060 | F: net/xfrm/ |
| 6047 | F: net/key/ | 6061 | F: net/key/ |
| 6048 | F: net/ipv4/xfrm* | 6062 | F: net/ipv4/xfrm* |
| @@ -6118,6 +6132,7 @@ F: include/net/nfc/ · 69 unmodified lines | |||
| 6118 | F: include/uapi/linux/nfc.h | 6132 | F: include/uapi/linux/nfc.h |
| 6119 | F: drivers/nfc/ | 6133 | F: drivers/nfc/ |
| 6120 | F: include/linux/platform_data/pn544.h | 6134 | F: include/linux/platform_data/pn544.h |
| 6135 | F: Documentation/devicetree/bindings/net/nfc/ | ||
| 6121 | 6136 | ||
| 6122 | NFS, SUNRPC, AND LOCKD CLIENTS | 6137 | NFS, SUNRPC, AND LOCKD CLIENTS |
| 6123 | M: Trond Myklebust <trond.myklebust@primarydata.com> | 6138 | M: Trond Myklebust <trond.myklebust@primarydata.com> |
| @@ -7077,13 +7092,8 @@ F: Documentation/networking/LICENSE.qla3xxx · 953 unmodified lines | |||
| 7077 | F: drivers/net/ethernet/qlogic/qla3xxx.* | 7092 | F: drivers/net/ethernet/qlogic/qla3xxx.* |
| 7078 | 7093 | ||
| 7079 | QLOGIC QLCNIC (1/10)Gb ETHERNET DRIVER | 7094 | QLOGIC QLCNIC (1/10)Gb ETHERNET DRIVER |
| 7080 | M: Himanshu Madhani <himanshu.madhani@qlogic.com> | ||
| 7081 | M: Rajesh Borundia <rajesh.borundia@qlogic.com> | ||
| 7082 | M: Shahed Shaikh <shahed.shaikh@qlogic.com> | 7095 | M: Shahed Shaikh <shahed.shaikh@qlogic.com> |
| 7083 | M: Jitendra Kalsaria <jitendra.kalsaria@qlogic.com> | 7096 | M: Dept-HSGLinuxNICDev@qlogic.com |
| 7084 | M: Sony Chacko <sony.chacko@qlogic.com> | ||
| 7085 | M: Sucheta Chakraborty <sucheta.chakraborty@qlogic.com> | ||
| 7086 | M: linux-driver@qlogic.com | ||
| 7087 | L: netdev@vger.kernel.org | 7097 | L: netdev@vger.kernel.org |
| 7088 | S: Supported | 7098 | S: Supported |
| 7089 | F: drivers/net/ethernet/qlogic/qlcnic/ | 7099 | F: drivers/net/ethernet/qlogic/qlcnic/ |
| @@ -7579,6 +7589,15 @@ S: Supported · 489 unmodified lines | |||
| 7579 | L: linux-samsung-soc@vger.kernel.org (moderated for non-subscribers) | 7589 | L: linux-samsung-soc@vger.kernel.org (moderated for non-subscribers) |
| 7580 | F: drivers/clk/samsung/ | 7590 | F: drivers/clk/samsung/ |
| 7581 | 7591 | ||
| 7592 | SAMSUNG SXGBE DRIVERS | ||
| 7593 | M: Byungho An <bh74.an@samsung.com> | ||
| 7594 | M: Girish K S <ks.giri@samsung.com> | ||
| 7595 | M: Siva Reddy Kallam <siva.kallam@samsung.com> | ||
| 7596 | M: Vipul Pandya <vipul.pandya@samsung.com> | ||
| 7597 | S: Supported | ||
| 7598 | L: netdev@vger.kernel.org | ||
| 7599 | F: drivers/net/ethernet/samsung/sxgbe/ | ||
| 7600 | |||
| 7582 | SERIAL DRIVERS | 7601 | SERIAL DRIVERS |
| 7583 | M: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 7602 | M: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| 7584 | L: linux-serial@vger.kernel.org | 7603 | L: linux-serial@vger.kernel.org |
| @@ -536,11 +536,13 @@ static struct spi_board_info omap3pandora_spi_board_info[] __initdata = { · 535 unmodified lines | |||
| 536 | 536 | ||
| 537 | static void __init pandora_wl1251_init(void) | 537 | static void __init pandora_wl1251_init(void) |
| 538 | { | 538 | { |
| 539 | struct wl12xx_platform_data pandora_wl1251_pdata; | 539 | struct wl1251_platform_data pandora_wl1251_pdata; |
| 540 | int ret; | 540 | int ret; |
| 541 | 541 | ||
| 542 | memset(&pandora_wl1251_pdata, 0, sizeof(pandora_wl1251_pdata)); | 542 | memset(&pandora_wl1251_pdata, 0, sizeof(pandora_wl1251_pdata)); |
| 543 | 543 | ||
| 544 | pandora_wl1251_pdata.power_gpio = -1; | ||
| 545 | |||
| 544 | ret = gpio_request_one(PANDORA_WIFI_IRQ_GPIO, GPIOF_IN, "wl1251 irq"); | 546 | ret = gpio_request_one(PANDORA_WIFI_IRQ_GPIO, GPIOF_IN, "wl1251 irq"); |
| 545 | if (ret < 0) | 547 | if (ret < 0) |
| 546 | goto fail; | 548 | goto fail; |
| @@ -550,7 +552,7 @@ static void __init pandora_wl1251_init(void) · 3 unmodified lines | |||
| 550 | goto fail_irq; | 552 | goto fail_irq; |
| 551 | 553 | ||
| 552 | pandora_wl1251_pdata.use_eeprom = true; | 554 | pandora_wl1251_pdata.use_eeprom = true; |
| 553 | ret = wl12xx_set_platform_data(&pandora_wl1251_pdata); | 555 | ret = wl1251_set_platform_data(&pandora_wl1251_pdata); |
| 554 | if (ret < 0) | 556 | if (ret < 0) |
| 555 | goto fail_irq; | 557 | goto fail_irq; |
| 556 | 558 | ||
| @@ -84,7 +84,7 @@ enum { · 83 unmodified lines | |||
| 84 | RX51_SPI_MIPID, /* LCD panel */ | 84 | RX51_SPI_MIPID, /* LCD panel */ |
| 85 | }; | 85 | }; |
| 86 | 86 | ||
| 87 | static struct wl12xx_platform_data wl1251_pdata; | 87 | static struct wl1251_platform_data wl1251_pdata; |
| 88 | static struct tsc2005_platform_data tsc2005_pdata; | 88 | static struct tsc2005_platform_data tsc2005_pdata; |
| 89 | 89 | ||
| 90 | #if defined(CONFIG_SENSORS_LIS3_I2C) || defined(CONFIG_SENSORS_LIS3_I2C_MODULE) | 90 | #if defined(CONFIG_SENSORS_LIS3_I2C) || defined(CONFIG_SENSORS_LIS3_I2C_MODULE) |
| @@ -1173,13 +1173,7 @@ static inline void board_smc91x_init(void) · 1082 unmodified lines | |||
| 1173 | 1173 | ||
| 1174 | #endif | 1174 | #endif |
| 1175 | 1175 | ||
| 1176 | static void rx51_wl1251_set_power(bool enable) | ||
| 1177 | { | ||
| 1178 | gpio_set_value(RX51_WL1251_POWER_GPIO, enable); | ||
| 1179 | } | ||
| 1180 | |||
| 1181 | static struct gpio rx51_wl1251_gpios[] __initdata = { | 1176 | static struct gpio rx51_wl1251_gpios[] __initdata = { |
| 1182 | { RX51_WL1251_POWER_GPIO, GPIOF_OUT_INIT_LOW, "wl1251 power" }, | ||
| 1183 | { RX51_WL1251_IRQ_GPIO, GPIOF_IN, "wl1251 irq" }, | 1177 | { RX51_WL1251_IRQ_GPIO, GPIOF_IN, "wl1251 irq" }, |
| 1184 | }; | 1178 | }; |
| 1185 | 1179 | ||
| @@ -1196,17 +1190,16 @@ static void __init rx51_init_wl1251(void) · 10 unmodified lines | |||
| 1196 | if (irq < 0) | 1190 | if (irq < 0) |
| 1197 | goto err_irq; | 1191 | goto err_irq; |
| 1198 | 1192 | ||
| 1199 | wl1251_pdata.set_power = rx51_wl1251_set_power; | 1193 | wl1251_pdata.power_gpio = RX51_WL1251_POWER_GPIO; |
| 1200 | rx51_peripherals_spi_board_info[RX51_SPI_WL1251].irq = irq; | 1194 | rx51_peripherals_spi_board_info[RX51_SPI_WL1251].irq = irq; |
| 1201 | 1195 | ||
| 1202 | return; | 1196 | return; |
| 1203 | 1197 | ||
| 1204 | err_irq: | 1198 | err_irq: |
| 1205 | gpio_free(RX51_WL1251_IRQ_GPIO); | 1199 | gpio_free(RX51_WL1251_IRQ_GPIO); |
| 1206 | gpio_free(RX51_WL1251_POWER_GPIO); | ||
| 1207 | error: | 1200 | error: |
| 1208 | printk(KERN_ERR "wl1251 board initialisation failed\n"); | 1201 | printk(KERN_ERR "wl1251 board initialisation failed\n"); |
| 1209 | wl1251_pdata.set_power = NULL; | 1202 | wl1251_pdata.power_gpio = -1; |
| 1210 | 1203 | ||
| 1211 | /* | 1204 | /* |
| 1212 | * Now rx51_peripherals_spi_board_info[1].irq is zero and | 1205 | * Now rx51_peripherals_spi_board_info[1].irq is zero and |
| @@ -825,8 +825,8 @@ b_epilogue: · 824 unmodified lines | |||
| 825 | break; | 825 | break; |
| 826 | case BPF_S_ANC_RXHASH: | 826 | case BPF_S_ANC_RXHASH: |
| 827 | ctx->seen |= SEEN_SKB; | 827 | ctx->seen |= SEEN_SKB; |
| 828 | BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, rxhash) != 4); | 828 | BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, hash) != 4); |
| 829 | off = offsetof(struct sk_buff, rxhash); | 829 | off = offsetof(struct sk_buff, hash); |
| 830 | emit(ARM_LDR_I(r_A, r_skb, off), ctx); | 830 | emit(ARM_LDR_I(r_A, r_skb, off), ctx); |
| 831 | break; | 831 | break; |
| 832 | case BPF_S_ANC_VLAN_TAG: | 832 | case BPF_S_ANC_VLAN_TAG: |
| @@ -925,6 +925,7 @@ void bpf_jit_compile(struct sk_filter *fp) · 92 unmodified lines | |||
| 925 | bpf_jit_dump(fp->len, alloc_size, 2, ctx.target); | 925 | bpf_jit_dump(fp->len, alloc_size, 2, ctx.target); |
| 926 | 926 | ||
| 927 | fp->bpf_func = (void *)ctx.target; | 927 | fp->bpf_func = (void *)ctx.target; |
| 928 | fp->jited = 1; | ||
| 928 | out: | 929 | out: |
| 929 | kfree(ctx.offsets); | 930 | kfree(ctx.offsets); |
| 930 | return; | 931 | return; |
| @@ -932,7 +933,7 @@ out: · 1 unmodified line | |||
| 932 | 933 | ||
| 933 | void bpf_jit_free(struct sk_filter *fp) | 934 | void bpf_jit_free(struct sk_filter *fp) |
| 934 | { | 935 | { |
| 935 | if (fp->bpf_func != sk_run_filter) | 936 | if (fp->jited) |
| 936 | module_free(NULL, fp->bpf_func); | 937 | module_free(NULL, fp->bpf_func); |
| 937 | kfree(fp); | 938 | kfree(fp); |
| 938 | } | 939 | } |
| @@ -390,9 +390,9 @@ static int bpf_jit_build_body(struct sk_filter *fp, u32 *image, · 389 unmodified lines | |||
| 390 | mark)); | 390 | mark)); |
| 391 | break; | 391 | break; |
| 392 | case BPF_S_ANC_RXHASH: | 392 | case BPF_S_ANC_RXHASH: |
| 393 | BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, rxhash) != 4); | 393 | BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, hash) != 4); |
| 394 | PPC_LWZ_OFFS(r_A, r_skb, offsetof(struct sk_buff, | 394 | PPC_LWZ_OFFS(r_A, r_skb, offsetof(struct sk_buff, |
| 395 | rxhash)); | 395 | hash)); |
| 396 | break; | 396 | break; |
| 397 | case BPF_S_ANC_VLAN_TAG: | 397 | case BPF_S_ANC_VLAN_TAG: |
| 398 | case BPF_S_ANC_VLAN_TAG_PRESENT: | 398 | case BPF_S_ANC_VLAN_TAG_PRESENT: |
| @@ -689,6 +689,7 @@ void bpf_jit_compile(struct sk_filter *fp) · 290 unmodified lines | |||
| 689 | ((u64 *)image)[0] = (u64)code_base; | 689 | ((u64 *)image)[0] = (u64)code_base; |
| 690 | ((u64 *)image)[1] = local_paca->kernel_toc; | 690 | ((u64 *)image)[1] = local_paca->kernel_toc; |
| 691 | fp->bpf_func = (void *)image; | 691 | fp->bpf_func = (void *)image; |
| 692 | fp->jited = 1; | ||
| 692 | } | 693 | } |
| 693 | out: | 694 | out: |
| 694 | kfree(addrs); | 695 | kfree(addrs); |
| @@ -697,7 +698,7 @@ out: · 2 unmodified lines | |||
| 697 | 698 | ||
| 698 | void bpf_jit_free(struct sk_filter *fp) | 699 | void bpf_jit_free(struct sk_filter *fp) |
| 699 | { | 700 | { |
| 700 | if (fp->bpf_func != sk_run_filter) | 701 | if (fp->jited) |
| 701 | module_free(NULL, fp->bpf_func); | 702 | module_free(NULL, fp->bpf_func); |
| 702 | kfree(fp); | 703 | kfree(fp); |
| 703 | } | 704 | } |
| @@ -737,10 +737,10 @@ call_fn: /* lg %r1,<d(function)>(%r13) */ · 736 unmodified lines | |||
| 737 | /* icm %r5,3,<d(type)>(%r1) */ | 737 | /* icm %r5,3,<d(type)>(%r1) */ |
| 738 | EMIT4_DISP(0xbf531000, offsetof(struct net_device, type)); | 738 | EMIT4_DISP(0xbf531000, offsetof(struct net_device, type)); |
| 739 | break; | 739 | break; |
| 740 | case BPF_S_ANC_RXHASH: /* A = skb->rxhash */ | 740 | case BPF_S_ANC_RXHASH: /* A = skb->hash */ |
| 741 | BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, rxhash) != 4); | 741 | BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, hash) != 4); |
| 742 | /* l %r5,<d(rxhash)>(%r2) */ | 742 | /* l %r5,<d(hash)>(%r2) */ |
| 743 | EMIT4_DISP(0x58502000, offsetof(struct sk_buff, rxhash)); | 743 | EMIT4_DISP(0x58502000, offsetof(struct sk_buff, hash)); |
| 744 | break; | 744 | break; |
| 745 | case BPF_S_ANC_VLAN_TAG: | 745 | case BPF_S_ANC_VLAN_TAG: |
| 746 | case BPF_S_ANC_VLAN_TAG_PRESENT: | 746 | case BPF_S_ANC_VLAN_TAG_PRESENT: |
| @@ -877,6 +877,7 @@ void bpf_jit_compile(struct sk_filter *fp) · 130 unmodified lines | |||
| 877 | if (jit.start) { | 877 | if (jit.start) { |
| 878 | set_memory_ro((unsigned long)header, header->pages); | 878 | set_memory_ro((unsigned long)header, header->pages); |
| 879 | fp->bpf_func = (void *) jit.start; | 879 | fp->bpf_func = (void *) jit.start; |
| 880 | fp->jited = 1; | ||
| 880 | } | 881 | } |
| 881 | out: | 882 | out: |
| 882 | kfree(addrs); | 883 | kfree(addrs); |
| @@ -887,10 +888,12 @@ void bpf_jit_free(struct sk_filter *fp) · 4 unmodified lines | |||
| 887 | unsigned long addr = (unsigned long)fp->bpf_func & PAGE_MASK; | 888 | unsigned long addr = (unsigned long)fp->bpf_func & PAGE_MASK; |
| 888 | struct bpf_binary_header *header = (void *)addr; | 889 | struct bpf_binary_header *header = (void *)addr; |
| 889 | 890 | ||
| 890 | if (fp->bpf_func == sk_run_filter) | 891 | if (!fp->jited) |
| 891 | goto free_filter; | 892 | goto free_filter; |
| 893 | |||
| 892 | set_memory_rw(addr, header->pages); | 894 | set_memory_rw(addr, header->pages); |
| 893 | module_free(NULL, header); | 895 | module_free(NULL, header); |
| 896 | |||
| 894 | free_filter: | 897 | free_filter: |
| 895 | kfree(fp); | 898 | kfree(fp); |
| 896 | } | 899 | } |
| @@ -618,7 +618,7 @@ void bpf_jit_compile(struct sk_filter *fp) · 617 unmodified lines | |||
| 618 | emit_load16(r_A, struct net_device, type, r_A); | 618 | emit_load16(r_A, struct net_device, type, r_A); |
| 619 | break; | 619 | break; |
| 620 | case BPF_S_ANC_RXHASH: | 620 | case BPF_S_ANC_RXHASH: |
| 621 | emit_skb_load32(rxhash, r_A); | 621 | emit_skb_load32(hash, r_A); |
| 622 | break; | 622 | break; |
| 623 | case BPF_S_ANC_VLAN_TAG: | 623 | case BPF_S_ANC_VLAN_TAG: |
| 624 | case BPF_S_ANC_VLAN_TAG_PRESENT: | 624 | case BPF_S_ANC_VLAN_TAG_PRESENT: |
| @@ -809,6 +809,7 @@ cond_branch: f_offset = addrs[i + filter[i].jf]; · 184 unmodified lines | |||
| 809 | if (image) { | 809 | if (image) { |
| 810 | bpf_flush_icache(image, image + proglen); | 810 | bpf_flush_icache(image, image + proglen); |
| 811 | fp->bpf_func = (void *)image; | 811 | fp->bpf_func = (void *)image; |
| 812 | fp->jited = 1; | ||
| 812 | } | 813 | } |
| 813 | out: | 814 | out: |
| 814 | kfree(addrs); | 815 | kfree(addrs); |
| @@ -817,7 +818,7 @@ out: · 2 unmodified lines | |||
| 817 | 818 | ||
| 818 | void bpf_jit_free(struct sk_filter *fp) | 819 | void bpf_jit_free(struct sk_filter *fp) |
| 819 | { | 820 | { |
| 820 | if (fp->bpf_func != sk_run_filter) | 821 | if (fp->jited) |
| 821 | module_free(NULL, fp->bpf_func); | 822 | module_free(NULL, fp->bpf_func); |
| 822 | kfree(fp); | 823 | kfree(fp); |
| 823 | } | 824 | } |
| @@ -240,7 +240,7 @@ static int uml_net_start_xmit(struct sk_buff *skb, struct net_device *dev) · 239 unmodified lines | |||
| 240 | 240 | ||
| 241 | spin_unlock_irqrestore(&lp->lock, flags); | 241 | spin_unlock_irqrestore(&lp->lock, flags); |
| 242 | 242 | ||
| 243 | dev_kfree_skb(skb); | 243 | dev_consume_skb_any(skb); |
| 244 | 244 | ||
| 245 | return NETDEV_TX_OK; | 245 | return NETDEV_TX_OK; |
| 246 | } | 246 | } |
| @@ -553,13 +553,13 @@ void bpf_jit_compile(struct sk_filter *fp) · 552 unmodified lines | |||
| 553 | } | 553 | } |
| 554 | break; | 554 | break; |
| 555 | case BPF_S_ANC_RXHASH: | 555 | case BPF_S_ANC_RXHASH: |
| 556 | BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, rxhash) != 4); | 556 | BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, hash) != 4); |
| 557 | if (is_imm8(offsetof(struct sk_buff, rxhash))) { | 557 | if (is_imm8(offsetof(struct sk_buff, hash))) { |
| 558 | /* mov off8(%rdi),%eax */ | 558 | /* mov off8(%rdi),%eax */ |
| 559 | EMIT3(0x8b, 0x47, offsetof(struct sk_buff, rxhash)); | 559 | EMIT3(0x8b, 0x47, offsetof(struct sk_buff, hash)); |
| 560 | } else { | 560 | } else { |
| 561 | EMIT2(0x8b, 0x87); | 561 | EMIT2(0x8b, 0x87); |
| 562 | EMIT(offsetof(struct sk_buff, rxhash), 4); | 562 | EMIT(offsetof(struct sk_buff, hash), 4); |
| 563 | } | 563 | } |
| 564 | break; | 564 | break; |
| 565 | case BPF_S_ANC_QUEUE: | 565 | case BPF_S_ANC_QUEUE: |
| @@ -772,6 +772,7 @@ cond_branch: f_offset = addrs[i + filter[i].jf] - addrs[i]; · 206 unmodified lines | |||
| 772 | bpf_flush_icache(header, image + proglen); | 772 | bpf_flush_icache(header, image + proglen); |
| 773 | set_memory_ro((unsigned long)header, header->pages); | 773 | set_memory_ro((unsigned long)header, header->pages); |
| 774 | fp->bpf_func = (void *)image; | 774 | fp->bpf_func = (void *)image; |
| 775 | fp->jited = 1; | ||
| 775 | } | 776 | } |
| 776 | out: | 777 | out: |
| 777 | kfree(addrs); | 778 | kfree(addrs); |
| @@ -791,7 +792,7 @@ static void bpf_jit_free_deferred(struct work_struct *work) · 13 unmodified lines | |||
| 791 | 792 | ||
| 792 | void bpf_jit_free(struct sk_filter *fp) | 793 | void bpf_jit_free(struct sk_filter *fp) |
| 793 | { | 794 | { |
| 794 | if (fp->bpf_func != sk_run_filter) { | 795 | if (fp->jited) { |
| 795 | INIT_WORK(&fp->work, bpf_jit_free_deferred); | 796 | INIT_WORK(&fp->work, bpf_jit_free_deferred); |
| 796 | schedule_work(&fp->work); | 797 | schedule_work(&fp->work); |
| 797 | } else { | 798 | } else { |
| @@ -435,9 +435,9 @@ static inline uint64_t blkg_stat_read(struct blkg_stat *stat) · 434 unmodified lines | |||
| 435 | uint64_t v; | 435 | uint64_t v; |
| 436 | 436 | ||
| 437 | do { | 437 | do { |
| 438 | start = u64_stats_fetch_begin_bh(&stat->syncp); | 438 | start = u64_stats_fetch_begin_irq(&stat->syncp); |
| 439 | v = stat->cnt; | 439 | v = stat->cnt; |
| 440 | } while (u64_stats_fetch_retry_bh(&stat->syncp, start)); | 440 | } while (u64_stats_fetch_retry_irq(&stat->syncp, start)); |
| 441 | 441 | ||
| 442 | return v; | 442 | return v; |
| 443 | } | 443 | } |
| @@ -508,9 +508,9 @@ static inline struct blkg_rwstat blkg_rwstat_read(struct blkg_rwstat *rwstat) · 64 unmodified lines | |||
| 508 | struct blkg_rwstat tmp; | 508 | struct blkg_rwstat tmp; |
| 509 | 509 | ||
| 510 | do { | 510 | do { |
| 511 | start = u64_stats_fetch_begin_bh(&rwstat->syncp); | 511 | start = u64_stats_fetch_begin_irq(&rwstat->syncp); |
| 512 | tmp = *rwstat; | 512 | tmp = *rwstat; |
| 513 | } while (u64_stats_fetch_retry_bh(&rwstat->syncp, start)); | 513 | } while (u64_stats_fetch_retry_irq(&rwstat->syncp, start)); |
| 514 | 514 | ||
| 515 | return tmp; | 515 | return tmp; |
| 516 | } | 516 | } |
| @@ -1925,7 +1925,7 @@ static int ucode_init(loader_block *lb, amb_dev *dev) · 1924 unmodified lines | |||
| 1925 | const struct firmware *fw; | 1925 | const struct firmware *fw; |
| 1926 | unsigned long start_address; | 1926 | unsigned long start_address; |
| 1927 | const struct ihex_binrec *rec; | 1927 | const struct ihex_binrec *rec; |
| 1928 | const char *errmsg = 0; | 1928 | const char *errmsg = NULL; |
| 1929 | int res; | 1929 | int res; |
| 1930 | 1930 | ||
| 1931 | res = request_ihex_firmware(&fw, "atmsar11.fw", &dev->pci_dev->dev); | 1931 | res = request_ihex_firmware(&fw, "atmsar11.fw", &dev->pci_dev->dev); |
| @@ -736,8 +736,8 @@ static void process_txdone_queue (struct fs_dev *dev, struct queue *q) · 735 unmodified lines | |||
| 736 | 736 | ||
| 737 | skb = td->skb; | 737 | skb = td->skb; |
| 738 | if (skb == FS_VCC (ATM_SKB(skb)->vcc)->last_skb) { | 738 | if (skb == FS_VCC (ATM_SKB(skb)->vcc)->last_skb) { |
| 739 | wake_up_interruptible (& FS_VCC (ATM_SKB(skb)->vcc)->close_wait); | ||
| 740 | FS_VCC (ATM_SKB(skb)->vcc)->last_skb = NULL; | 739 | FS_VCC (ATM_SKB(skb)->vcc)->last_skb = NULL; |
| 740 | wake_up_interruptible (& FS_VCC (ATM_SKB(skb)->vcc)->close_wait); | ||
| 741 | } | 741 | } |
| 742 | td->dev->ntxpckts--; | 742 | td->dev->ntxpckts--; |
| 743 | 743 | ||
| @@ -1123,7 +1123,7 @@ static void fs_close(struct atm_vcc *atm_vcc) · 379 unmodified lines | |||
| 1123 | this sleep_on, we'll lose any reference to these packets. Memory leak! | 1123 | this sleep_on, we'll lose any reference to these packets. Memory leak! |
| 1124 | On the other hand, it's awfully convenient that we can abort a "close" that | 1124 | On the other hand, it's awfully convenient that we can abort a "close" that |
| 1125 | is taking too long. Maybe just use non-interruptible sleep on? -- REW */ | 1125 | is taking too long. Maybe just use non-interruptible sleep on? -- REW */ |
| 1126 | interruptible_sleep_on (& vcc->close_wait); | 1126 | wait_event_interruptible(vcc->close_wait, !vcc->last_skb); |
| 1127 | } | 1127 | } |
| 1128 | 1128 | ||
| 1129 | txtp = &atm_vcc->qos.txtp; | 1129 | txtp = &atm_vcc->qos.txtp; |
| @@ -2000,7 +2000,7 @@ static void firestream_remove_one(struct pci_dev *pdev) · 870 unmodified lines | |||
| 2000 | 2000 | ||
| 2001 | fs_dprintk (FS_DEBUG_CLEANUP, "Freeing irq%d.\n", dev->irq); | 2001 | fs_dprintk (FS_DEBUG_CLEANUP, "Freeing irq%d.\n", dev->irq); |
| 2002 | free_irq (dev->irq, dev); | 2002 | free_irq (dev->irq, dev); |
| 2003 | del_timer (&dev->timer); | 2003 | del_timer_sync (&dev->timer); |
| 2004 | 2004 | ||
| 2005 | atm_dev_deregister(dev->atm_dev); | 2005 | atm_dev_deregister(dev->atm_dev); |
| 2006 | free_queue (dev, &dev->hp_txq); | 2006 | free_queue (dev, &dev->hp_txq); |
| @@ -368,9 +368,9 @@ EXPORT_SYMBOL(idt77105_init); · 367 unmodified lines | |||
| 368 | 368 | ||
| 369 | static void __exit idt77105_exit(void) | 369 | static void __exit idt77105_exit(void) |
| 370 | { | 370 | { |
| 371 | /* turn off timers */ | 371 | /* turn off timers */ |
| 372 | del_timer(&stats_timer); | 372 | del_timer_sync(&stats_timer); |
| 373 | del_timer(&restart_timer); | 373 | del_timer_sync(&restart_timer); |
| 374 | } | 374 | } |
| 375 | 375 | ||
| 376 | module_exit(idt77105_exit); | 376 | module_exit(idt77105_exit); |
| @@ -639,9 +639,9 @@ static int ns_init_card(int i, struct pci_dev *pcidev) · 638 unmodified lines | |||
| 639 | card->hbnr.init = NUM_HB; | 639 | card->hbnr.init = NUM_HB; |
| 640 | card->hbnr.max = MAX_HB; | 640 | card->hbnr.max = MAX_HB; |
| 641 | 641 | ||
| 642 | card->sm_handle = 0x00000000; | 642 | card->sm_handle = NULL; |
| 643 | card->sm_addr = 0x00000000; | 643 | card->sm_addr = 0x00000000; |
| 644 | card->lg_handle = 0x00000000; | 644 | card->lg_handle = NULL; |
| 645 | card->lg_addr = 0x00000000; | 645 | card->lg_addr = 0x00000000; |
| 646 | 646 | ||
| 647 | card->efbie = 1; /* To prevent push_rxbufs from enabling the interrupt */ | 647 | card->efbie = 1; /* To prevent push_rxbufs from enabling the interrupt */ |
| @@ -979,7 +979,7 @@ static void push_rxbufs(ns_dev * card, struct sk_buff *skb) · 331 unmodified lines | |||
| 979 | addr2 = card->sm_addr; | 979 | addr2 = card->sm_addr; |
| 980 | handle2 = card->sm_handle; | 980 | handle2 = card->sm_handle; |
| 981 | card->sm_addr = 0x00000000; | 981 | card->sm_addr = 0x00000000; |
| 982 | card->sm_handle = 0x00000000; | 982 | card->sm_handle = NULL; |
| 983 | } else { /* (!sm_addr) */ | 983 | } else { /* (!sm_addr) */ |
| 984 | 984 | ||
| 985 | card->sm_addr = addr1; | 985 | card->sm_addr = addr1; |
| @@ -993,7 +993,7 @@ static void push_rxbufs(ns_dev * card, struct sk_buff *skb) · 7 unmodified lines | |||
| 993 | addr2 = card->lg_addr; | 993 | addr2 = card->lg_addr; |
| 994 | handle2 = card->lg_handle; | 994 | handle2 = card->lg_handle; |
| 995 | card->lg_addr = 0x00000000; | 995 | card->lg_addr = 0x00000000; |
| 996 | card->lg_handle = 0x00000000; | 996 | card->lg_handle = NULL; |
| 997 | } else { /* (!lg_addr) */ | 997 | } else { /* (!lg_addr) */ |
| 998 | 998 | ||
| 999 | card->lg_addr = addr1; | 999 | card->lg_addr = addr1; |
| @@ -1739,10 +1739,10 @@ static int push_scqe(ns_dev * card, vc_map * vc, scq_info * scq, ns_scqe * tbd, · 739 unmodified lines | |||
| 1739 | } | 1739 | } |
| 1740 | 1740 | ||
| 1741 | scq->full = 1; | 1741 | scq->full = 1; |
| 1742 | spin_unlock_irqrestore(&scq->lock, flags); | 1742 | wait_event_interruptible_lock_irq_timeout(scq->scqfull_waitq, |
| 1743 | interruptible_sleep_on_timeout(&scq->scqfull_waitq, | 1743 | scq->tail != scq->next, |
| 1744 | SCQFULL_TIMEOUT); | 1744 | scq->lock, |
| 1745 | spin_lock_irqsave(&scq->lock, flags); | 1745 | SCQFULL_TIMEOUT); |
| 1746 | 1746 | ||
| 1747 | if (scq->full) { | 1747 | if (scq->full) { |
| 1748 | spin_unlock_irqrestore(&scq->lock, flags); | 1748 | spin_unlock_irqrestore(&scq->lock, flags); |
| @@ -1789,10 +1789,10 @@ static int push_scqe(ns_dev * card, vc_map * vc, scq_info * scq, ns_scqe * tbd, · 40 unmodified lines | |||
| 1789 | scq->full = 1; | 1789 | scq->full = 1; |
| 1790 | if (has_run++) | 1790 | if (has_run++) |
| 1791 | break; | 1791 | break; |
| 1792 | spin_unlock_irqrestore(&scq->lock, flags); | 1792 | wait_event_interruptible_lock_irq_timeout(scq->scqfull_waitq, |
| 1793 | interruptible_sleep_on_timeout(&scq->scqfull_waitq, | 1793 | scq->tail != scq->next, |
| 1794 | SCQFULL_TIMEOUT); | 1794 | scq->lock, |
| 1795 | spin_lock_irqsave(&scq->lock, flags); | 1795 | SCQFULL_TIMEOUT); |
| 1796 | } | 1796 | } |
| 1797 | 1797 | ||
| 1798 | if (!scq->full) { | 1798 | if (!scq->full) { |
| @@ -760,7 +760,7 @@ static irqreturn_t solos_irq(int irq, void *dev_id) · 759 unmodified lines | |||
| 760 | return IRQ_RETVAL(handled); | 760 | return IRQ_RETVAL(handled); |
| 761 | } | 761 | } |
| 762 | 762 | ||
| 763 | void solos_bh(unsigned long card_arg) | 763 | static void solos_bh(unsigned long card_arg) |
| 764 | { | 764 | { |
| 765 | struct solos_card *card = (void *)card_arg; | 765 | struct solos_card *card = (void *)card_arg; |
| 766 | uint32_t card_flags; | 766 | uint32_t card_flags; |
| @@ -218,7 +218,14 @@ int bcma_gpio_init(struct bcma_drv_cc *cc) · 217 unmodified lines | |||
| 218 | #if IS_BUILTIN(CONFIG_BCMA_HOST_SOC) | 218 | #if IS_BUILTIN(CONFIG_BCMA_HOST_SOC) |
| 219 | chip->to_irq = bcma_gpio_to_irq; | 219 | chip->to_irq = bcma_gpio_to_irq; |
| 220 | #endif | 220 | #endif |
| 221 | chip->ngpio = 16; | 221 | switch (cc->core->bus->chipinfo.id) { |
| 222 | case BCMA_CHIP_ID_BCM5357: | ||
| 223 | chip->ngpio = 32; | ||
| 224 | break; | ||
| 225 | default: | ||
| 226 | chip->ngpio = 16; | ||
| 227 | } | ||
| 228 | |||
| 222 | /* There is just one SoC in one device and its GPIO addresses should be | 229 | /* There is just one SoC in one device and its GPIO addresses should be |
| 223 | * deterministic to address them more easily. The other buses could get | 230 | * deterministic to address them more easily. The other buses could get |
| 224 | * a random base number. */ | 231 | * a random base number. */ |
| @@ -62,50 +62,54 @@ static const struct usb_device_id ath3k_table[] = { · 61 unmodified lines | |||
| 62 | { USB_DEVICE(0x0CF3, 0x3000) }, | 62 | { USB_DEVICE(0x0CF3, 0x3000) }, |
| 63 | 63 | ||
| 64 | /* Atheros AR3011 with sflash firmware*/ | 64 | /* Atheros AR3011 with sflash firmware*/ |
| 65 | { USB_DEVICE(0x0489, 0xE027) }, | ||
| 66 | { USB_DEVICE(0x0489, 0xE03D) }, | ||
| 67 | { USB_DEVICE(0x0930, 0x0215) }, | ||
| 65 | { USB_DEVICE(0x0CF3, 0x3002) }, | 68 | { USB_DEVICE(0x0CF3, 0x3002) }, |
| 66 | { USB_DEVICE(0x0CF3, 0xE019) }, | 69 | { USB_DEVICE(0x0CF3, 0xE019) }, |
| 67 | { USB_DEVICE(0x13d3, 0x3304) }, | 70 | { USB_DEVICE(0x13d3, 0x3304) }, |
| 68 | { USB_DEVICE(0x0930, 0x0215) }, | ||
| 69 | { USB_DEVICE(0x0489, 0xE03D) }, | ||
| 70 | { USB_DEVICE(0x0489, 0xE027) }, | ||
| 71 | 71 | ||
| 72 | /* Atheros AR9285 Malbec with sflash firmware */ | 72 | /* Atheros AR9285 Malbec with sflash firmware */ |
| 73 | { USB_DEVICE(0x03F0, 0x311D) }, | 73 | { USB_DEVICE(0x03F0, 0x311D) }, |
| 74 | 74 | ||
| 75 | /* Atheros AR3012 with sflash firmware*/ | 75 | /* Atheros AR3012 with sflash firmware*/ |
| 76 | { USB_DEVICE(0x0CF3, 0x0036) }, | 76 | { USB_DEVICE(0x0489, 0xe04d) }, |
| 77 | { USB_DEVICE(0x0CF3, 0x3004) }, | 77 | { USB_DEVICE(0x0489, 0xe04e) }, |
| 78 | { USB_DEVICE(0x0CF3, 0x3008) }, | 78 | { USB_DEVICE(0x0489, 0xe057) }, |
| 79 | { USB_DEVICE(0x0CF3, 0x311D) }, | 79 | { USB_DEVICE(0x0489, 0xe056) }, |
| 80 | { USB_DEVICE(0x0CF3, 0x817a) }, | 80 | { USB_DEVICE(0x0489, 0xe05f) }, |
| 81 | { USB_DEVICE(0x13d3, 0x3375) }, | 81 | { USB_DEVICE(0x04c5, 0x1330) }, |
| 82 | { USB_DEVICE(0x04CA, 0x3004) }, | 82 | { USB_DEVICE(0x04CA, 0x3004) }, |
| 83 | { USB_DEVICE(0x04CA, 0x3005) }, | 83 | { USB_DEVICE(0x04CA, 0x3005) }, |
| 84 | { USB_DEVICE(0x04CA, 0x3006) }, | 84 | { USB_DEVICE(0x04CA, 0x3006) }, |
| 85 | { USB_DEVICE(0x04CA, 0x3008) }, | 85 | { USB_DEVICE(0x04CA, 0x3008) }, |
| 86 | { USB_DEVICE(0x04CA, 0x300b) }, | 86 | { USB_DEVICE(0x04CA, 0x300b) }, |
| 87 | { USB_DEVICE(0x13d3, 0x3362) }, | ||
| 88 | { USB_DEVICE(0x0CF3, 0xE004) }, | ||
| 89 | { USB_DEVICE(0x0CF3, 0xE005) }, | ||
| 90 | { USB_DEVICE(0x0930, 0x0219) }, | 87 | { USB_DEVICE(0x0930, 0x0219) }, |
| 91 | { USB_DEVICE(0x0930, 0x0220) }, | 88 | { USB_DEVICE(0x0930, 0x0220) }, |
| 92 | { USB_DEVICE(0x0489, 0xe057) }, | 89 | { USB_DEVICE(0x0b05, 0x17d0) }, |
| 93 | { USB_DEVICE(0x13d3, 0x3393) }, | 90 | { USB_DEVICE(0x0CF3, 0x0036) }, |
| 94 | { USB_DEVICE(0x0489, 0xe04e) }, | 91 | { USB_DEVICE(0x0CF3, 0x3004) }, |
| 95 | { USB_DEVICE(0x0489, 0xe056) }, | 92 | { USB_DEVICE(0x0CF3, 0x3005) }, |
| 96 | { USB_DEVICE(0x0489, 0xe04d) }, | 93 | { USB_DEVICE(0x0CF3, 0x3008) }, |
| 97 | { USB_DEVICE(0x04c5, 0x1330) }, | 94 | { USB_DEVICE(0x0CF3, 0x311D) }, |
| 98 | { USB_DEVICE(0x13d3, 0x3402) }, | 95 | { USB_DEVICE(0x0CF3, 0x311E) }, |
| 96 | { USB_DEVICE(0x0CF3, 0x311F) }, | ||
| 99 | { USB_DEVICE(0x0cf3, 0x3121) }, | 97 | { USB_DEVICE(0x0cf3, 0x3121) }, |
| 98 | { USB_DEVICE(0x0CF3, 0x817a) }, | ||
| 100 | { USB_DEVICE(0x0cf3, 0xe003) }, | 99 | { USB_DEVICE(0x0cf3, 0xe003) }, |
| 101 | { USB_DEVICE(0x0489, 0xe05f) }, | 100 | { USB_DEVICE(0x0CF3, 0xE004) }, |
| 101 | { USB_DEVICE(0x0CF3, 0xE005) }, | ||
| 102 | { USB_DEVICE(0x13d3, 0x3362) }, | ||
| 103 | { USB_DEVICE(0x13d3, 0x3375) }, | ||
| 104 | { USB_DEVICE(0x13d3, 0x3393) }, | ||
| 105 | { USB_DEVICE(0x13d3, 0x3402) }, | ||
| 102 | 106 | ||
| 103 | /* Atheros AR5BBU12 with sflash firmware */ | 107 | /* Atheros AR5BBU12 with sflash firmware */ |
| 104 | { USB_DEVICE(0x0489, 0xE02C) }, | 108 | { USB_DEVICE(0x0489, 0xE02C) }, |
| 105 | 109 | ||
| 106 | /* Atheros AR5BBU22 with sflash firmware */ | 110 | /* Atheros AR5BBU22 with sflash firmware */ |
| 107 | { USB_DEVICE(0x0489, 0xE03C) }, | ||
| 108 | { USB_DEVICE(0x0489, 0xE036) }, | 111 | { USB_DEVICE(0x0489, 0xE036) }, |
| 112 | { USB_DEVICE(0x0489, 0xE03C) }, | ||
| 109 | 113 | ||
| 110 | { } /* Terminating entry */ | 114 | { } /* Terminating entry */ |
| 111 | }; | 115 | }; |
| @@ -118,36 +122,40 @@ MODULE_DEVICE_TABLE(usb, ath3k_table); · 6 unmodified lines | |||
| 118 | static const struct usb_device_id ath3k_blist_tbl[] = { | 122 | static const struct usb_device_id ath3k_blist_tbl[] = { |
| 119 | 123 | ||
| 120 | /* Atheros AR3012 with sflash firmware*/ | 124 | /* Atheros AR3012 with sflash firmware*/ |
| 121 | { USB_DEVICE(0x0CF3, 0x0036), .driver_info = BTUSB_ATH3012 }, | 125 | { USB_DEVICE(0x0489, 0xe04e), .driver_info = BTUSB_ATH3012 }, |
| 122 | { USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 }, | 126 | { USB_DEVICE(0x0489, 0xe04d), .driver_info = BTUSB_ATH3012 }, |
| 123 | { USB_DEVICE(0x0cf3, 0x3008), .driver_info = BTUSB_ATH3012 }, | 127 | { USB_DEVICE(0x0489, 0xe056), .driver_info = BTUSB_ATH3012 }, |
| 124 | { USB_DEVICE(0x0cf3, 0x311D), .driver_info = BTUSB_ATH3012 }, | 128 | { USB_DEVICE(0x0489, 0xe057), .driver_info = BTUSB_ATH3012 }, |
| 125 | { USB_DEVICE(0x0CF3, 0x817a), .driver_info = BTUSB_ATH3012 }, | 129 | { USB_DEVICE(0x0489, 0xe05f), .driver_info = BTUSB_ATH3012 }, |
| 126 | { USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 }, | 130 | { USB_DEVICE(0x04c5, 0x1330), .driver_info = BTUSB_ATH3012 }, |
| 127 | { USB_DEVICE(0x04ca, 0x3004), .driver_info = BTUSB_ATH3012 }, | 131 | { USB_DEVICE(0x04ca, 0x3004), .driver_info = BTUSB_ATH3012 }, |
| 128 | { USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 }, | 132 | { USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 }, |
| 129 | { USB_DEVICE(0x04ca, 0x3006), .driver_info = BTUSB_ATH3012 }, | 133 | { USB_DEVICE(0x04ca, 0x3006), .driver_info = BTUSB_ATH3012 }, |
| 130 | { USB_DEVICE(0x04ca, 0x3008), .driver_info = BTUSB_ATH3012 }, | 134 | { USB_DEVICE(0x04ca, 0x3008), .driver_info = BTUSB_ATH3012 }, |
| 131 | { USB_DEVICE(0x04ca, 0x300b), .driver_info = BTUSB_ATH3012 }, | 135 | { USB_DEVICE(0x04ca, 0x300b), .driver_info = BTUSB_ATH3012 }, |
| 132 | { USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 }, | ||
| 133 | { USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 }, | ||
| 134 | { USB_DEVICE(0x0cf3, 0xe005), .driver_info = BTUSB_ATH3012 }, | ||
| 135 | { USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 }, | 136 | { USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 }, |
| 136 | { USB_DEVICE(0x0930, 0x0220), .driver_info = BTUSB_ATH3012 }, | 137 | { USB_DEVICE(0x0930, 0x0220), .driver_info = BTUSB_ATH3012 }, |
| 137 | { USB_DEVICE(0x0489, 0xe057), .driver_info = BTUSB_ATH3012 }, | 138 | { USB_DEVICE(0x0b05, 0x17d0), .driver_info = BTUSB_ATH3012 }, |
| 138 | { USB_DEVICE(0x13d3, 0x3393), .driver_info = BTUSB_ATH3012 }, | 139 | { USB_DEVICE(0x0CF3, 0x0036), .driver_info = BTUSB_ATH3012 }, |
| 139 | { USB_DEVICE(0x0489, 0xe04e), .driver_info = BTUSB_ATH3012 }, | 140 | { USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 }, |
| 140 | { USB_DEVICE(0x0489, 0xe056), .driver_info = BTUSB_ATH3012 }, | 141 | { USB_DEVICE(0x0cf3, 0x3005), .driver_info = BTUSB_ATH3012 }, |
| 141 | { USB_DEVICE(0x0489, 0xe04d), .driver_info = BTUSB_ATH3012 }, | 142 | { USB_DEVICE(0x0cf3, 0x3008), .driver_info = BTUSB_ATH3012 }, |
| 142 | { USB_DEVICE(0x04c5, 0x1330), .driver_info = BTUSB_ATH3012 }, | 143 | { USB_DEVICE(0x0cf3, 0x311D), .driver_info = BTUSB_ATH3012 }, |
| 143 | { USB_DEVICE(0x13d3, 0x3402), .driver_info = BTUSB_ATH3012 }, | 144 | { USB_DEVICE(0x0cf3, 0x311E), .driver_info = BTUSB_ATH3012 }, |
| 145 | { USB_DEVICE(0x0cf3, 0x311F), .driver_info = BTUSB_ATH3012 }, | ||
| 144 | { USB_DEVICE(0x0cf3, 0x3121), .driver_info = BTUSB_ATH3012 }, | 146 | { USB_DEVICE(0x0cf3, 0x3121), .driver_info = BTUSB_ATH3012 }, |
| 147 | { USB_DEVICE(0x0CF3, 0x817a), .driver_info = BTUSB_ATH3012 }, | ||
| 148 | { USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 }, | ||
| 149 | { USB_DEVICE(0x0cf3, 0xe005), .driver_info = BTUSB_ATH3012 }, | ||
| 145 | { USB_DEVICE(0x0cf3, 0xe003), .driver_info = BTUSB_ATH3012 }, | 150 | { USB_DEVICE(0x0cf3, 0xe003), .driver_info = BTUSB_ATH3012 }, |
| 146 | { USB_DEVICE(0x0489, 0xe05f), .driver_info = BTUSB_ATH3012 }, | 151 | { USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 }, |
| 152 | { USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 }, | ||
| 153 | { USB_DEVICE(0x13d3, 0x3393), .driver_info = BTUSB_ATH3012 }, | ||
| 154 | { USB_DEVICE(0x13d3, 0x3402), .driver_info = BTUSB_ATH3012 }, | ||
| 147 | 155 | ||
| 148 | /* Atheros AR5BBU22 with sflash firmware */ | 156 | /* Atheros AR5BBU22 with sflash firmware */ |
| 149 | { USB_DEVICE(0x0489, 0xE03C), .driver_info = BTUSB_ATH3012 }, | ||
| 150 | { USB_DEVICE(0x0489, 0xE036), .driver_info = BTUSB_ATH3012 }, | 157 | { USB_DEVICE(0x0489, 0xE036), .driver_info = BTUSB_ATH3012 }, |
| 158 | { USB_DEVICE(0x0489, 0xE03C), .driver_info = BTUSB_ATH3012 }, | ||
| 151 | 159 | ||
| 152 | { } /* Terminating entry */ | 160 | { } /* Terminating entry */ |
| 153 | }; | 161 | }; |
| @@ -174,10 +182,9 @@ static int ath3k_load_firmware(struct usb_device *udev, · 20 unmodified lines | |||
| 174 | } | 182 | } |
| 175 | 183 | ||
| 176 | memcpy(send_buf, firmware->data, 20); | 184 | memcpy(send_buf, firmware->data, 20); |
| 177 | if ((err = usb_control_msg(udev, pipe, | 185 | err = usb_control_msg(udev, pipe, USB_REQ_DFU_DNLOAD, USB_TYPE_VENDOR, |
| 178 | USB_REQ_DFU_DNLOAD, | 186 | 0, 0, send_buf, 20, USB_CTRL_SET_TIMEOUT); |
| 179 | USB_TYPE_VENDOR, 0, 0, | 187 | if (err < 0) { |
| 180 | send_buf, 20, USB_CTRL_SET_TIMEOUT)) < 0) { | ||
| 181 | BT_ERR("Can't change to loading configuration err"); | 188 | BT_ERR("Can't change to loading configuration err"); |
| 182 | goto error; | 189 | goto error; |
| 183 | } | 190 | } |
| @@ -360,7 +367,7 @@ static int ath3k_load_patch(struct usb_device *udev) · 176 unmodified lines | |||
| 360 | } | 367 | } |
| 361 | 368 | ||
| 362 | snprintf(filename, ATH3K_NAME_LEN, "ar3k/AthrBT_0x%08x.dfu", | 369 | snprintf(filename, ATH3K_NAME_LEN, "ar3k/AthrBT_0x%08x.dfu", |
| 363 | fw_version.rom_version); | 370 | le32_to_cpu(fw_version.rom_version)); |
| 364 | 371 | ||
| 365 | ret = request_firmware(&firmware, filename, &udev->dev); | 372 | ret = request_firmware(&firmware, filename, &udev->dev); |
| 366 | if (ret < 0) { | 373 | if (ret < 0) { |
| @@ -422,7 +429,7 @@ static int ath3k_load_syscfg(struct usb_device *udev) · 55 unmodified lines | |||
| 422 | } | 429 | } |
| 423 | 430 | ||
| 424 | snprintf(filename, ATH3K_NAME_LEN, "ar3k/ramps_0x%08x_%d%s", | 431 | snprintf(filename, ATH3K_NAME_LEN, "ar3k/ramps_0x%08x_%d%s", |
| 425 | fw_version.rom_version, clk_value, ".dfu"); | 432 | le32_to_cpu(fw_version.rom_version), clk_value, ".dfu"); |
| 426 | 433 | ||
| 427 | ret = request_firmware(&firmware, filename, &udev->dev); | 434 | ret = request_firmware(&firmware, filename, &udev->dev); |
| 428 | if (ret < 0) { | 435 | if (ret < 0) { |
| @@ -131,8 +131,11 @@ static int bfusb_send_bulk(struct bfusb_data *data, struct sk_buff *skb) · 130 unmodified lines | |||
| 131 | 131 | ||
| 132 | BT_DBG("bfusb %p skb %p len %d", data, skb, skb->len); | 132 | BT_DBG("bfusb %p skb %p len %d", data, skb, skb->len); |
| 133 | 133 | ||
| 134 | if (!urb && !(urb = usb_alloc_urb(0, GFP_ATOMIC))) | 134 | if (!urb) { |
| 135 | return -ENOMEM; | 135 | urb = usb_alloc_urb(0, GFP_ATOMIC); |
| 136 | if (!urb) | ||
| 137 | return -ENOMEM; | ||
| 138 | } | ||
| 136 | 139 | ||
| 137 | pipe = usb_sndbulkpipe(data->udev, data->bulk_out_ep); | 140 | pipe = usb_sndbulkpipe(data->udev, data->bulk_out_ep); |
| 138 | 141 | ||
| @@ -218,8 +221,11 @@ static int bfusb_rx_submit(struct bfusb_data *data, struct urb *urb) · 79 unmodified lines | |||
| 218 | 221 | ||
| 219 | BT_DBG("bfusb %p urb %p", data, urb); | 222 | BT_DBG("bfusb %p urb %p", data, urb); |
| 220 | 223 | ||
| 221 | if (!urb && !(urb = usb_alloc_urb(0, GFP_ATOMIC))) | 224 | if (!urb) { |
| 222 | return -ENOMEM; | 225 | urb = usb_alloc_urb(0, GFP_ATOMIC); |
| 226 | if (!urb) | ||
| 227 | return -ENOMEM; | ||
| 228 | } | ||
| 223 | 229 | ||
| 224 | skb = bt_skb_alloc(size, GFP_ATOMIC); | 230 | skb = bt_skb_alloc(size, GFP_ATOMIC); |
| 225 | if (!skb) { | 231 | if (!skb) { |
| @@ -257,7 +257,8 @@ static void bluecard_write_wakeup(bluecard_info_t *info) · 256 unmodified lines | |||
| 257 | ready_bit = XMIT_BUF_ONE_READY; | 257 | ready_bit = XMIT_BUF_ONE_READY; |
| 258 | } | 258 | } |
| 259 | 259 | ||
| 260 | if (!(skb = skb_dequeue(&(info->txq)))) | 260 | skb = skb_dequeue(&(info->txq)); |
| 261 | if (!skb) | ||
| 261 | break; | 262 | break; |
| 262 | 263 | ||
| 263 | if (bt_cb(skb)->pkt_type & 0x80) { | 264 | if (bt_cb(skb)->pkt_type & 0x80) { |
| @@ -391,7 +392,8 @@ static void bluecard_receive(bluecard_info_t *info, unsigned int offset) · 127 unmodified lines | |||
| 391 | if (info->rx_skb == NULL) { | 392 | if (info->rx_skb == NULL) { |
| 392 | info->rx_state = RECV_WAIT_PACKET_TYPE; | 393 | info->rx_state = RECV_WAIT_PACKET_TYPE; |
| 393 | info->rx_count = 0; | 394 | info->rx_count = 0; |
| 394 | if (!(info->rx_skb = bt_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC))) { | 395 | info->rx_skb = bt_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC); |
| 396 | if (!info->rx_skb) { | ||
| 395 | BT_ERR("Can't allocate mem for new packet"); | 397 | BT_ERR("Can't allocate mem for new packet"); |
| 396 | return; | 398 | return; |
| 397 | } | 399 | } |
| @@ -566,7 +568,8 @@ static int bluecard_hci_set_baud_rate(struct hci_dev *hdev, int baud) · 168 unmodified lines | |||
| 566 | /* Ericsson baud rate command */ | 568 | /* Ericsson baud rate command */ |
| 567 | unsigned char cmd[] = { HCI_COMMAND_PKT, 0x09, 0xfc, 0x01, 0x03 }; | 569 | unsigned char cmd[] = { HCI_COMMAND_PKT, 0x09, 0xfc, 0x01, 0x03 }; |
| 568 | 570 | ||
| 569 | if (!(skb = bt_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC))) { | 571 | skb = bt_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC); |
| 572 | if (!skb) { | ||
| 570 | BT_ERR("Can't allocate mem for new packet"); | 573 | BT_ERR("Can't allocate mem for new packet"); |
| 571 | return -1; | 574 | return -1; |
| 572 | } | 575 | } |
| @@ -898,7 +901,7 @@ static void bluecard_release(struct pcmcia_device *link) · 325 unmodified lines | |||
| 898 | 901 | ||
| 899 | bluecard_close(info); | 902 | bluecard_close(info); |
| 900 | 903 | ||
| 901 | del_timer(&(info->timer)); | 904 | del_timer_sync(&(info->timer)); |
| 902 | 905 | ||
| 903 | pcmcia_disable_device(link); | 906 | pcmcia_disable_device(link); |
| 904 | } | 907 | } |
| @@ -193,8 +193,8 @@ static void bt3c_write_wakeup(bt3c_info_t *info) · 192 unmodified lines | |||
| 193 | if (!pcmcia_dev_present(info->p_dev)) | 193 | if (!pcmcia_dev_present(info->p_dev)) |
| 194 | break; | 194 | break; |
| 195 | 195 | ||
| 196 | 196 | skb = skb_dequeue(&(info->txq)); | |
| 197 | if (!(skb = skb_dequeue(&(info->txq)))) { | 197 | if (!skb) { |
| 198 | clear_bit(XMIT_SENDING, &(info->tx_state)); | 198 | clear_bit(XMIT_SENDING, &(info->tx_state)); |
| 199 | break; | 199 | break; |
| 200 | } | 200 | } |
| @@ -238,7 +238,8 @@ static void bt3c_receive(bt3c_info_t *info) · 37 unmodified lines | |||
| 238 | if (info->rx_skb == NULL) { | 238 | if (info->rx_skb == NULL) { |
| 239 | info->rx_state = RECV_WAIT_PACKET_TYPE; | 239 | info->rx_state = RECV_WAIT_PACKET_TYPE; |
| 240 | info->rx_count = 0; | 240 | info->rx_count = 0; |
| 241 | if (!(info->rx_skb = bt_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC))) { | 241 | info->rx_skb = bt_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC); |
| 242 | if (!info->rx_skb) { | ||
| 242 | BT_ERR("Can't allocate mem for new packet"); | 243 | BT_ERR("Can't allocate mem for new packet"); |
| 243 | return; | 244 | return; |
| 244 | } | 245 | } |
| @@ -59,12 +59,13 @@ bool btmrvl_check_evtpkt(struct btmrvl_private *priv, struct sk_buff *skb) · 58 unmodified lines | |||
| 59 | priv->btmrvl_dev.sendcmdflag = false; | 59 | priv->btmrvl_dev.sendcmdflag = false; |
| 60 | priv->adapter->cmd_complete = true; | 60 | priv->adapter->cmd_complete = true; |
| 61 | wake_up_interruptible(&priv->adapter->cmd_wait_q); | 61 | wake_up_interruptible(&priv->adapter->cmd_wait_q); |
| 62 | } | ||
| 63 | 62 | ||
| 64 | if (hci_opcode_ogf(opcode) == 0x3F) { | 63 | if (hci_opcode_ogf(opcode) == 0x3F) { |
| 65 | BT_DBG("vendor event skipped: opcode=%#4.4x", opcode); | 64 | BT_DBG("vendor event skipped: opcode=%#4.4x", |
| 66 | kfree_skb(skb); | 65 | opcode); |
| 67 | return false; | 66 | kfree_skb(skb); |
| 67 | return false; | ||
| 68 | } | ||
| 68 | } | 69 | } |
| 69 | } | 70 | } |
| 70 | 71 | ||
| @@ -149,7 +149,8 @@ static void btuart_write_wakeup(btuart_info_t *info) · 148 unmodified lines | |||
| 149 | if (!pcmcia_dev_present(info->p_dev)) | 149 | if (!pcmcia_dev_present(info->p_dev)) |
| 150 | return; | 150 | return; |
| 151 | 151 | ||
| 152 | if (!(skb = skb_dequeue(&(info->txq)))) | 152 | skb = skb_dequeue(&(info->txq)); |
| 153 | if (!skb) | ||
| 153 | break; | 154 | break; |
| 154 | 155 | ||
| 155 | /* Send frame */ | 156 | /* Send frame */ |
| @@ -190,7 +191,8 @@ static void btuart_receive(btuart_info_t *info) · 34 unmodified lines | |||
| 190 | if (info->rx_skb == NULL) { | 191 | if (info->rx_skb == NULL) { |
| 191 | info->rx_state = RECV_WAIT_PACKET_TYPE; | 192 | info->rx_state = RECV_WAIT_PACKET_TYPE; |
| 192 | info->rx_count = 0; | 193 | info->rx_count = 0; |
| 193 | if (!(info->rx_skb = bt_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC))) { | 194 | info->rx_skb = bt_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC); |
| 195 | if (!info->rx_skb) { | ||
| 194 | BT_ERR("Can't allocate mem for new packet"); | 196 | BT_ERR("Can't allocate mem for new packet"); |
| 195 | return; | 197 | return; |
| 196 | } | 198 | } |
| @@ -101,21 +101,24 @@ static const struct usb_device_id btusb_table[] = { · 100 unmodified lines | |||
| 101 | { USB_DEVICE(0x0c10, 0x0000) }, | 101 | { USB_DEVICE(0x0c10, 0x0000) }, |
| 102 | 102 | ||
| 103 | /* Broadcom BCM20702A0 */ | 103 | /* Broadcom BCM20702A0 */ |
| 104 | { USB_DEVICE(0x0489, 0xe042) }, | ||
| 105 | { USB_DEVICE(0x04ca, 0x2003) }, | ||
| 104 | { USB_DEVICE(0x0b05, 0x17b5) }, | 106 | { USB_DEVICE(0x0b05, 0x17b5) }, |
| 105 | { USB_DEVICE(0x0b05, 0x17cb) }, | 107 | { USB_DEVICE(0x0b05, 0x17cb) }, |
| 106 | { USB_DEVICE(0x04ca, 0x2003) }, | ||
| 107 | { USB_DEVICE(0x0489, 0xe042) }, | ||
| 108 | { USB_DEVICE(0x413c, 0x8197) }, | 108 | { USB_DEVICE(0x413c, 0x8197) }, |
| 109 | 109 | ||
| 110 | /* Foxconn - Hon Hai */ | 110 | /* Foxconn - Hon Hai */ |
| 111 | { USB_VENDOR_AND_INTERFACE_INFO(0x0489, 0xff, 0x01, 0x01) }, | 111 | { USB_VENDOR_AND_INTERFACE_INFO(0x0489, 0xff, 0x01, 0x01) }, |
| 112 | 112 | ||
| 113 | /*Broadcom devices with vendor specific id */ | 113 | /* Broadcom devices with vendor specific id */ |
| 114 | { USB_VENDOR_AND_INTERFACE_INFO(0x0a5c, 0xff, 0x01, 0x01) }, | 114 | { USB_VENDOR_AND_INTERFACE_INFO(0x0a5c, 0xff, 0x01, 0x01) }, |
| 115 | 115 | ||
| 116 | /* Belkin F8065bf - Broadcom based */ | 116 | /* Belkin F8065bf - Broadcom based */ |
| 117 | { USB_VENDOR_AND_INTERFACE_INFO(0x050d, 0xff, 0x01, 0x01) }, | 117 | { USB_VENDOR_AND_INTERFACE_INFO(0x050d, 0xff, 0x01, 0x01) }, |
| 118 | 118 | ||
| 119 | /* IMC Networks - Broadcom based */ | ||
| 120 | { USB_VENDOR_AND_INTERFACE_INFO(0x13d3, 0xff, 0x01, 0x01) }, | ||
| 121 | |||
| 119 | { } /* Terminating entry */ | 122 | { } /* Terminating entry */ |
| 120 | }; | 123 | }; |
| 121 | 124 | ||
| @@ -129,55 +132,59 @@ static const struct usb_device_id blacklist_table[] = { · 7 unmodified lines | |||
| 129 | { USB_DEVICE(0x0a5c, 0x2033), .driver_info = BTUSB_IGNORE }, | 132 | { USB_DEVICE(0x0a5c, 0x2033), .driver_info = BTUSB_IGNORE }, |
| 130 | 133 | ||
| 131 | /* Atheros 3011 with sflash firmware */ | 134 | /* Atheros 3011 with sflash firmware */ |
| 135 | { USB_DEVICE(0x0489, 0xe027), .driver_info = BTUSB_IGNORE }, | ||
| 136 | { USB_DEVICE(0x0489, 0xe03d), .driver_info = BTUSB_IGNORE }, | ||
| 137 | { USB_DEVICE(0x0930, 0x0215), .driver_info = BTUSB_IGNORE }, | ||
| 132 | { USB_DEVICE(0x0cf3, 0x3002), .driver_info = BTUSB_IGNORE }, | 138 | { USB_DEVICE(0x0cf3, 0x3002), .driver_info = BTUSB_IGNORE }, |
| 133 | { USB_DEVICE(0x0cf3, 0xe019), .driver_info = BTUSB_IGNORE }, | 139 | { USB_DEVICE(0x0cf3, 0xe019), .driver_info = BTUSB_IGNORE }, |
| 134 | { USB_DEVICE(0x13d3, 0x3304), .driver_info = BTUSB_IGNORE }, | 140 | { USB_DEVICE(0x13d3, 0x3304), .driver_info = BTUSB_IGNORE }, |
| 135 | { USB_DEVICE(0x0930, 0x0215), .driver_info = BTUSB_IGNORE }, | ||
| 136 | { USB_DEVICE(0x0489, 0xe03d), .driver_info = BTUSB_IGNORE }, | ||
| 137 | { USB_DEVICE(0x0489, 0xe027), .driver_info = BTUSB_IGNORE }, | ||
| 138 | 141 | ||
| 139 | /* Atheros AR9285 Malbec with sflash firmware */ | 142 | /* Atheros AR9285 Malbec with sflash firmware */ |
| 140 | { USB_DEVICE(0x03f0, 0x311d), .driver_info = BTUSB_IGNORE }, | 143 | { USB_DEVICE(0x03f0, 0x311d), .driver_info = BTUSB_IGNORE }, |
| 141 | 144 | ||
| 142 | /* Atheros 3012 with sflash firmware */ | 145 | /* Atheros 3012 with sflash firmware */ |
| 143 | { USB_DEVICE(0x0cf3, 0x0036), .driver_info = BTUSB_ATH3012 }, | 146 | { USB_DEVICE(0x0489, 0xe04d), .driver_info = BTUSB_ATH3012 }, |
| 144 | { USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 }, | 147 | { USB_DEVICE(0x0489, 0xe04e), .driver_info = BTUSB_ATH3012 }, |
| 145 | { USB_DEVICE(0x0cf3, 0x3008), .driver_info = BTUSB_ATH3012 }, | 148 | { USB_DEVICE(0x0489, 0xe056), .driver_info = BTUSB_ATH3012 }, |
| 146 | { USB_DEVICE(0x0cf3, 0x311d), .driver_info = BTUSB_ATH3012 }, | 149 | { USB_DEVICE(0x0489, 0xe057), .driver_info = BTUSB_ATH3012 }, |
| 147 | { USB_DEVICE(0x0cf3, 0x817a), .driver_info = BTUSB_ATH3012 }, | 150 | { USB_DEVICE(0x0489, 0xe05f), .driver_info = BTUSB_ATH3012 }, |
| 148 | { USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 }, | 151 | { USB_DEVICE(0x04c5, 0x1330), .driver_info = BTUSB_ATH3012 }, |
| 149 | { USB_DEVICE(0x04ca, 0x3004), .driver_info = BTUSB_ATH3012 }, | 152 | { USB_DEVICE(0x04ca, 0x3004), .driver_info = BTUSB_ATH3012 }, |
| 150 | { USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 }, | 153 | { USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 }, |
| 151 | { USB_DEVICE(0x04ca, 0x3006), .driver_info = BTUSB_ATH3012 }, | 154 | { USB_DEVICE(0x04ca, 0x3006), .driver_info = BTUSB_ATH3012 }, |
| 152 | { USB_DEVICE(0x04ca, 0x3008), .driver_info = BTUSB_ATH3012 }, | 155 | { USB_DEVICE(0x04ca, 0x3008), .driver_info = BTUSB_ATH3012 }, |
| 153 | { USB_DEVICE(0x04ca, 0x300b), .driver_info = BTUSB_ATH3012 }, | 156 | { USB_DEVICE(0x04ca, 0x300b), .driver_info = BTUSB_ATH3012 }, |
| 154 | { USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 }, | ||
| 155 | { USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 }, | ||
| 156 | { USB_DEVICE(0x0cf3, 0xe005), .driver_info = BTUSB_ATH3012 }, | ||
| 157 | { USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 }, | 157 | { USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 }, |
| 158 | { USB_DEVICE(0x0930, 0x0220), .driver_info = BTUSB_ATH3012 }, | 158 | { USB_DEVICE(0x0930, 0x0220), .driver_info = BTUSB_ATH3012 }, |
| 159 | { USB_DEVICE(0x0489, 0xe057), .driver_info = BTUSB_ATH3012 }, | 159 | { USB_DEVICE(0x0b05, 0x17d0), .driver_info = BTUSB_ATH3012 }, |
| 160 | { USB_DEVICE(0x13d3, 0x3393), .driver_info = BTUSB_ATH3012 }, | 160 | { USB_DEVICE(0x0cf3, 0x0036), .driver_info = BTUSB_ATH3012 }, |
| 161 | { USB_DEVICE(0x0489, 0xe04e), .driver_info = BTUSB_ATH3012 }, | 161 | { USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 }, |
| 162 | { USB_DEVICE(0x0489, 0xe056), .driver_info = BTUSB_ATH3012 }, | 162 | { USB_DEVICE(0x0cf3, 0x3005), .driver_info = BTUSB_ATH3012 }, |
| 163 | { USB_DEVICE(0x0489, 0xe04d), .driver_info = BTUSB_ATH3012 }, | 163 | { USB_DEVICE(0x0cf3, 0x3008), .driver_info = BTUSB_ATH3012 }, |
| 164 | { USB_DEVICE(0x04c5, 0x1330), .driver_info = BTUSB_ATH3012 }, | 164 | { USB_DEVICE(0x0cf3, 0x311d), .driver_info = BTUSB_ATH3012 }, |
| 165 | { USB_DEVICE(0x13d3, 0x3402), .driver_info = BTUSB_ATH3012 }, | 165 | { USB_DEVICE(0x0cf3, 0x311e), .driver_info = BTUSB_ATH3012 }, |
| 166 | { USB_DEVICE(0x0cf3, 0x311f), .driver_info = BTUSB_ATH3012 }, | ||
| 166 | { USB_DEVICE(0x0cf3, 0x3121), .driver_info = BTUSB_ATH3012 }, | 167 | { USB_DEVICE(0x0cf3, 0x3121), .driver_info = BTUSB_ATH3012 }, |
| 168 | { USB_DEVICE(0x0cf3, 0x817a), .driver_info = BTUSB_ATH3012 }, | ||
| 167 | { USB_DEVICE(0x0cf3, 0xe003), .driver_info = BTUSB_ATH3012 }, | 169 | { USB_DEVICE(0x0cf3, 0xe003), .driver_info = BTUSB_ATH3012 }, |
| 168 | { USB_DEVICE(0x0489, 0xe05f), .driver_info = BTUSB_ATH3012 }, | 170 | { USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 }, |
| 171 | { USB_DEVICE(0x0cf3, 0xe005), .driver_info = BTUSB_ATH3012 }, | ||
| 172 | { USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 }, | ||
| 173 | { USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 }, | ||
| 174 | { USB_DEVICE(0x13d3, 0x3393), .driver_info = BTUSB_ATH3012 }, | ||
| 175 | { USB_DEVICE(0x13d3, 0x3402), .driver_info = BTUSB_ATH3012 }, | ||
| 169 | 176 | ||
| 170 | /* Atheros AR5BBU12 with sflash firmware */ | 177 | /* Atheros AR5BBU12 with sflash firmware */ |
| 171 | { USB_DEVICE(0x0489, 0xe02c), .driver_info = BTUSB_IGNORE }, | 178 | { USB_DEVICE(0x0489, 0xe02c), .driver_info = BTUSB_IGNORE }, |
| 172 | 179 | ||
| 173 | /* Atheros AR5BBU12 with sflash firmware */ | 180 | /* Atheros AR5BBU12 with sflash firmware */ |
| 174 | { USB_DEVICE(0x0489, 0xe03c), .driver_info = BTUSB_ATH3012 }, | ||
| 175 | { USB_DEVICE(0x0489, 0xe036), .driver_info = BTUSB_ATH3012 }, | 181 | { USB_DEVICE(0x0489, 0xe036), .driver_info = BTUSB_ATH3012 }, |
| 182 | { USB_DEVICE(0x0489, 0xe03c), .driver_info = BTUSB_ATH3012 }, | ||
| 176 | 183 | ||
| 177 | /* Broadcom BCM2035 */ | 184 | /* Broadcom BCM2035 */ |
| 178 | { USB_DEVICE(0x0a5c, 0x2035), .driver_info = BTUSB_WRONG_SCO_MTU }, | ||
| 179 | { USB_DEVICE(0x0a5c, 0x200a), .driver_info = BTUSB_WRONG_SCO_MTU }, | ||
| 180 | { USB_DEVICE(0x0a5c, 0x2009), .driver_info = BTUSB_BCM92035 }, | 185 | { USB_DEVICE(0x0a5c, 0x2009), .driver_info = BTUSB_BCM92035 }, |
| 186 | { USB_DEVICE(0x0a5c, 0x200a), .driver_info = BTUSB_WRONG_SCO_MTU }, | ||
| 187 | { USB_DEVICE(0x0a5c, 0x2035), .driver_info = BTUSB_WRONG_SCO_MTU }, | ||
| 181 | 188 | ||
| 182 | /* Broadcom BCM2045 */ | 189 | /* Broadcom BCM2045 */ |
| 183 | { USB_DEVICE(0x0a5c, 0x2039), .driver_info = BTUSB_WRONG_SCO_MTU }, | 190 | { USB_DEVICE(0x0a5c, 0x2039), .driver_info = BTUSB_WRONG_SCO_MTU }, |
| @@ -153,7 +153,8 @@ static void dtl1_write_wakeup(dtl1_info_t *info) · 152 unmodified lines | |||
| 153 | if (!pcmcia_dev_present(info->p_dev)) | 153 | if (!pcmcia_dev_present(info->p_dev)) |
| 154 | return; | 154 | return; |
| 155 | 155 | ||
| 156 | if (!(skb = skb_dequeue(&(info->txq)))) | 156 | skb = skb_dequeue(&(info->txq)); |
| 157 | if (!skb) | ||
| 157 | break; | 158 | break; |
| 158 | 159 | ||
| 159 | /* Send frame */ | 160 | /* Send frame */ |
| @@ -215,13 +216,15 @@ static void dtl1_receive(dtl1_info_t *info) · 55 unmodified lines | |||
| 215 | info->hdev->stat.byte_rx++; | 216 | info->hdev->stat.byte_rx++; |
| 216 | 217 | ||
| 217 | /* Allocate packet */ | 218 | /* Allocate packet */ |
| 218 | if (info->rx_skb == NULL) | 219 | if (info->rx_skb == NULL) { |
| 219 | if (!(info->rx_skb = bt_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC))) { | 220 | info->rx_skb = bt_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC); |
| 221 | if (!info->rx_skb) { | ||
| 220 | BT_ERR("Can't allocate mem for new packet"); | 222 | BT_ERR("Can't allocate mem for new packet"); |
| 221 | info->rx_state = RECV_WAIT_NSH; | 223 | info->rx_state = RECV_WAIT_NSH; |
| 222 | info->rx_count = NSHL; | 224 | info->rx_count = NSHL; |
| 223 | return; | 225 | return; |
| 224 | } | 226 | } |
| 227 | } | ||
| 225 | 228 | ||
| 226 | *skb_put(info->rx_skb, 1) = inb(iobase + UART_RX); | 229 | *skb_put(info->rx_skb, 1) = inb(iobase + UART_RX); |
| 227 | nsh = (nsh_t *)info->rx_skb->data; | 230 | nsh = (nsh_t *)info->rx_skb->data; |
| @@ -291,7 +291,8 @@ static struct sk_buff *bcsp_dequeue(struct hci_uart *hu) · 290 unmodified lines | |||
| 291 | /* First of all, check for unreliable messages in the queue, | 291 | /* First of all, check for unreliable messages in the queue, |
| 292 | since they have priority */ | 292 | since they have priority */ |
| 293 | 293 | ||
| 294 | if ((skb = skb_dequeue(&bcsp->unrel)) != NULL) { | 294 | skb = skb_dequeue(&bcsp->unrel); |
| 295 | if (skb != NULL) { | ||
| 295 | struct sk_buff *nskb = bcsp_prepare_pkt(bcsp, skb->data, skb->len, bt_cb(skb)->pkt_type); | 296 | struct sk_buff *nskb = bcsp_prepare_pkt(bcsp, skb->data, skb->len, bt_cb(skb)->pkt_type); |
| 296 | if (nskb) { | 297 | if (nskb) { |
| 297 | kfree_skb(skb); | 298 | kfree_skb(skb); |
| @@ -308,16 +309,20 @@ static struct sk_buff *bcsp_dequeue(struct hci_uart *hu) · 10 unmodified lines | |||
| 308 | 309 | ||
| 309 | spin_lock_irqsave_nested(&bcsp->unack.lock, flags, SINGLE_DEPTH_NESTING); | 310 | spin_lock_irqsave_nested(&bcsp->unack.lock, flags, SINGLE_DEPTH_NESTING); |
| 310 | 311 | ||
| 311 | if (bcsp->unack.qlen < BCSP_TXWINSIZE && (skb = skb_dequeue(&bcsp->rel)) != NULL) { | 312 | if (bcsp->unack.qlen < BCSP_TXWINSIZE) { |
| 312 | struct sk_buff *nskb = bcsp_prepare_pkt(bcsp, skb->data, skb->len, bt_cb(skb)->pkt_type); | 313 | skb = skb_dequeue(&bcsp->rel); |
| 313 | if (nskb) { | 314 | if (skb != NULL) { |
| 314 | __skb_queue_tail(&bcsp->unack, skb); | 315 | struct sk_buff *nskb = bcsp_prepare_pkt(bcsp, skb->data, skb->len, |
| 315 | mod_timer(&bcsp->tbcsp, jiffies + HZ / 4); | 316 | bt_cb(skb)->pkt_type); |
| 316 | spin_unlock_irqrestore(&bcsp->unack.lock, flags); | 317 | if (nskb) { |
| 317 | return nskb; | 318 | __skb_queue_tail(&bcsp->unack, skb); |
| 318 | } else { | 319 | mod_timer(&bcsp->tbcsp, jiffies + HZ / 4); |
| 319 | skb_queue_head(&bcsp->rel, skb); | 320 | spin_unlock_irqrestore(&bcsp->unack.lock, flags); |
| 320 | BT_ERR("Could not dequeue pkt because alloc_skb failed"); | 321 | return nskb; |
| 322 | } else { | ||
| 323 | skb_queue_head(&bcsp->rel, skb); | ||
| 324 | BT_ERR("Could not dequeue pkt because alloc_skb failed"); | ||
| 325 | } | ||
| 321 | } | 326 | } |
| 322 | } | 327 | } |
| 323 | 328 | ||
| @@ -715,6 +720,9 @@ static int bcsp_open(struct hci_uart *hu) · 391 unmodified lines | |||
| 715 | static int bcsp_close(struct hci_uart *hu) | 720 | static int bcsp_close(struct hci_uart *hu) |
| 716 | { | 721 | { |
| 717 | struct bcsp_struct *bcsp = hu->priv; | 722 | struct bcsp_struct *bcsp = hu->priv; |
| 723 | |||
| 724 | del_timer_sync(&bcsp->tbcsp); | ||
| 725 | |||
| 718 | hu->priv = NULL; | 726 | hu->priv = NULL; |
| 719 | 727 | ||
| 720 | BT_DBG("hu %p", hu); | 728 | BT_DBG("hu %p", hu); |
| @@ -722,7 +730,6 @@ static int bcsp_close(struct hci_uart *hu) · 1 unmodified line | |||
| 722 | skb_queue_purge(&bcsp->unack); | 730 | skb_queue_purge(&bcsp->unack); |
| 723 | skb_queue_purge(&bcsp->rel); | 731 | skb_queue_purge(&bcsp->rel); |
| 724 | skb_queue_purge(&bcsp->unrel); | 732 | skb_queue_purge(&bcsp->unrel); |
| 725 | del_timer(&bcsp->tbcsp); | ||
| 726 | 733 | ||
| 727 | kfree(bcsp); | 734 | kfree(bcsp); |
| 728 | return 0; | 735 | return 0; |
| @@ -206,12 +206,12 @@ static int h5_close(struct hci_uart *hu) · 205 unmodified lines | |||
| 206 | { | 206 | { |
| 207 | struct h5 *h5 = hu->priv; | 207 | struct h5 *h5 = hu->priv; |
| 208 | 208 | ||
| 209 | del_timer_sync(&h5->timer); | ||
| 210 | |||
| 209 | skb_queue_purge(&h5->unack); | 211 | skb_queue_purge(&h5->unack); |
| 210 | skb_queue_purge(&h5->rel); | 212 | skb_queue_purge(&h5->rel); |
| 211 | skb_queue_purge(&h5->unrel); | 213 | skb_queue_purge(&h5->unrel); |
| 212 | 214 | ||
| 213 | del_timer(&h5->timer); | ||
| 214 | |||
| 215 | kfree(h5); | 215 | kfree(h5); |
| 216 | 216 | ||
| 217 | return 0; | 217 | return 0; |
| @@ -673,7 +673,8 @@ static struct sk_buff *h5_dequeue(struct hci_uart *hu) · 455 unmodified lines | |||
| 673 | return h5_prepare_pkt(hu, HCI_3WIRE_LINK_PKT, wakeup_req, 2); | 673 | return h5_prepare_pkt(hu, HCI_3WIRE_LINK_PKT, wakeup_req, 2); |
| 674 | } | 674 | } |
| 675 | 675 | ||
| 676 | if ((skb = skb_dequeue(&h5->unrel)) != NULL) { | 676 | skb = skb_dequeue(&h5->unrel); |
| 677 | if (skb != NULL) { | ||
| 677 | nskb = h5_prepare_pkt(hu, bt_cb(skb)->pkt_type, | 678 | nskb = h5_prepare_pkt(hu, bt_cb(skb)->pkt_type, |
| 678 | skb->data, skb->len); | 679 | skb->data, skb->len); |
| 679 | if (nskb) { | 680 | if (nskb) { |
| @@ -690,7 +691,8 @@ static struct sk_buff *h5_dequeue(struct hci_uart *hu) · 10 unmodified lines | |||
| 690 | if (h5->unack.qlen >= h5->tx_win) | 691 | if (h5->unack.qlen >= h5->tx_win) |
| 691 | goto unlock; | 692 | goto unlock; |
| 692 | 693 | ||
| 693 | if ((skb = skb_dequeue(&h5->rel)) != NULL) { | 694 | skb = skb_dequeue(&h5->rel); |
| 695 | if (skb != NULL) { | ||
| 694 | nskb = h5_prepare_pkt(hu, bt_cb(skb)->pkt_type, | 696 | nskb = h5_prepare_pkt(hu, bt_cb(skb)->pkt_type, |
| 695 | skb->data, skb->len); | 697 | skb->data, skb->len); |
| 696 | if (nskb) { | 698 | if (nskb) { |
| @@ -271,7 +271,8 @@ static int hci_uart_tty_open(struct tty_struct *tty) · 270 unmodified lines | |||
| 271 | if (tty->ops->write == NULL) | 271 | if (tty->ops->write == NULL) |
| 272 | return -EOPNOTSUPP; | 272 | return -EOPNOTSUPP; |
| 273 | 273 | ||
| 274 | if (!(hu = kzalloc(sizeof(struct hci_uart), GFP_KERNEL))) { | 274 | hu = kzalloc(sizeof(struct hci_uart), GFP_KERNEL); |
| 275 | if (!hu) { | ||
| 275 | BT_ERR("Can't allocate control structure"); | 276 | BT_ERR("Can't allocate control structure"); |
| 276 | return -ENFILE; | 277 | return -ENFILE; |
| 277 | } | 278 | } |
| @@ -569,7 +570,8 @@ static int __init hci_uart_init(void) · 291 unmodified lines | |||
| 569 | hci_uart_ldisc.write_wakeup = hci_uart_tty_wakeup; | 570 | hci_uart_ldisc.write_wakeup = hci_uart_tty_wakeup; |
| 570 | hci_uart_ldisc.owner = THIS_MODULE; | 571 | hci_uart_ldisc.owner = THIS_MODULE; |
| 571 | 572 | ||
| 572 | if ((err = tty_register_ldisc(N_HCI, &hci_uart_ldisc))) { | 573 | err = tty_register_ldisc(N_HCI, &hci_uart_ldisc); |
| 574 | if (err) { | ||
| 573 | BT_ERR("HCI line discipline registration failed. (%d)", err); | 575 | BT_ERR("HCI line discipline registration failed. (%d)", err); |
| 574 | return err; | 576 | return err; |
| 575 | } | 577 | } |
| @@ -614,7 +616,8 @@ static void __exit hci_uart_exit(void) · 38 unmodified lines | |||
| 614 | #endif | 616 | #endif |
| 615 | 617 | ||
| 616 | /* Release tty registration of line discipline */ | 618 | /* Release tty registration of line discipline */ |
| 617 | if ((err = tty_unregister_ldisc(N_HCI))) | 619 | err = tty_unregister_ldisc(N_HCI); |
| 620 | if (err) | ||
| 618 | BT_ERR("Can't unregister HCI line discipline (%d)", err); | 621 | BT_ERR("Can't unregister HCI line discipline (%d)", err); |
| 619 | } | 622 | } |
| 620 | 623 | ||
| @@ -359,7 +359,7 @@ static const struct file_operations vhci_fops = { · 358 unmodified lines | |||
| 359 | static struct miscdevice vhci_miscdev= { | 359 | static struct miscdevice vhci_miscdev= { |
| 360 | .name = "vhci", | 360 | .name = "vhci", |
| 361 | .fops = &vhci_fops, | 361 | .fops = &vhci_fops, |
| 362 | .minor = MISC_DYNAMIC_MINOR, | 362 | .minor = VHCI_MINOR, |
| 363 | }; | 363 | }; |
| 364 | 364 | ||
| 365 | static int __init vhci_init(void) | 365 | static int __init vhci_init(void) |
| @@ -385,3 +385,4 @@ MODULE_DESCRIPTION("Bluetooth virtual HCI driver ver " VERSION); · 19 unmodified lines | |||
| 385 | MODULE_VERSION(VERSION); | 385 | MODULE_VERSION(VERSION); |
| 386 | MODULE_LICENSE("GPL"); | 386 | MODULE_LICENSE("GPL"); |
| 387 | MODULE_ALIAS("devname:vhci"); | 387 | MODULE_ALIAS("devname:vhci"); |
| 388 | MODULE_ALIAS_MISCDEV(VHCI_MINOR); | ||
| @@ -145,7 +145,6 @@ static int cn_call_callback(struct sk_buff *skb) · 144 unmodified lines | |||
| 145 | spin_unlock_bh(&dev->cbdev->queue_lock); | 145 | spin_unlock_bh(&dev->cbdev->queue_lock); |
| 146 | 146 | ||
| 147 | if (cbq != NULL) { | 147 | if (cbq != NULL) { |
| 148 | err = 0; | ||
| 149 | cbq->callback(msg, nsp); | 148 | cbq->callback(msg, nsp); |
| 150 | kfree_skb(skb); | 149 | kfree_skb(skb); |
| 151 | cn_queue_release_callback(cbq); | 150 | cn_queue_release_callback(cbq); |
| @@ -1647,6 +1647,15 @@ static inline int act_open_has_tid(int status) · 1646 unmodified lines | |||
| 1647 | status != CPL_ERR_ARP_MISS; | 1647 | status != CPL_ERR_ARP_MISS; |
| 1648 | } | 1648 | } |
| 1649 | 1649 | ||
| 1650 | /* Returns whether a CPL status conveys negative advice. | ||
| 1651 | */ | ||
| 1652 | static int is_neg_adv(unsigned int status) | ||
| 1653 | { | ||
| 1654 | return status == CPL_ERR_RTX_NEG_ADVICE || | ||
| 1655 | status == CPL_ERR_PERSIST_NEG_ADVICE || | ||
| 1656 | status == CPL_ERR_KEEPALV_NEG_ADVICE; | ||
| 1657 | } | ||
| 1658 | |||
| 1650 | #define ACT_OPEN_RETRY_COUNT 2 | 1659 | #define ACT_OPEN_RETRY_COUNT 2 |
| 1651 | 1660 | ||
| 1652 | static int import_ep(struct c4iw_ep *ep, int iptype, __u8 *peer_ip, | 1661 | static int import_ep(struct c4iw_ep *ep, int iptype, __u8 *peer_ip, |
| @@ -1835,7 +1844,7 @@ static int act_open_rpl(struct c4iw_dev *dev, struct sk_buff *skb) · 182 unmodified lines | |||
| 1835 | PDBG("%s ep %p atid %u status %u errno %d\n", __func__, ep, atid, | 1844 | PDBG("%s ep %p atid %u status %u errno %d\n", __func__, ep, atid, |
| 1836 | status, status2errno(status)); | 1845 | status, status2errno(status)); |
| 1837 | 1846 | ||
| 1838 | if (status == CPL_ERR_RTX_NEG_ADVICE) { | 1847 | if (is_neg_adv(status)) { |
| 1839 | printk(KERN_WARNING MOD "Connection problems for atid %u\n", | 1848 | printk(KERN_WARNING MOD "Connection problems for atid %u\n", |
| 1840 | atid); | 1849 | atid); |
| 1841 | return 0; | 1850 | return 0; |
| @@ -2265,15 +2274,6 @@ static int peer_close(struct c4iw_dev *dev, struct sk_buff *skb) · 423 unmodified lines | |||
| 2265 | return 0; | 2274 | return 0; |
| 2266 | } | 2275 | } |
| 2267 | 2276 | ||
| 2268 | /* | ||
| 2269 | * Returns whether an ABORT_REQ_RSS message is a negative advice. | ||
| 2270 | */ | ||
| 2271 | static int is_neg_adv_abort(unsigned int status) | ||
| 2272 | { | ||
| 2273 | return status == CPL_ERR_RTX_NEG_ADVICE || | ||
| 2274 | status == CPL_ERR_PERSIST_NEG_ADVICE; | ||
| 2275 | } | ||
| 2276 | |||
| 2277 | static int peer_abort(struct c4iw_dev *dev, struct sk_buff *skb) | 2277 | static int peer_abort(struct c4iw_dev *dev, struct sk_buff *skb) |
| 2278 | { | 2278 | { |
| 2279 | struct cpl_abort_req_rss *req = cplhdr(skb); | 2279 | struct cpl_abort_req_rss *req = cplhdr(skb); |
| @@ -2287,7 +2287,7 @@ static int peer_abort(struct c4iw_dev *dev, struct sk_buff *skb) · 7 unmodified lines | |||
| 2287 | unsigned int tid = GET_TID(req); | 2287 | unsigned int tid = GET_TID(req); |
| 2288 | 2288 | ||
| 2289 | ep = lookup_tid(t, tid); | 2289 | ep = lookup_tid(t, tid); |
| 2290 | if (is_neg_adv_abort(req->status)) { | 2290 | if (is_neg_adv(req->status)) { |
| 2291 | PDBG("%s neg_adv_abort ep %p tid %u\n", __func__, ep, | 2291 | PDBG("%s neg_adv_abort ep %p tid %u\n", __func__, ep, |
| 2292 | ep->hwtid); | 2292 | ep->hwtid); |
| 2293 | return 0; | 2293 | return 0; |
| @@ -3570,7 +3570,7 @@ static int peer_abort_intr(struct c4iw_dev *dev, struct sk_buff *skb) · 1276 unmodified lines | |||
| 3570 | kfree_skb(skb); | 3570 | kfree_skb(skb); |
| 3571 | return 0; | 3571 | return 0; |
| 3572 | } | 3572 | } |
| 3573 | if (is_neg_adv_abort(req->status)) { | 3573 | if (is_neg_adv(req->status)) { |
| 3574 | PDBG("%s neg_adv_abort ep %p tid %u\n", __func__, ep, | 3574 | PDBG("%s neg_adv_abort ep %p tid %u\n", __func__, ep, |
| 3575 | ep->hwtid); | 3575 | ep->hwtid); |
| 3576 | kfree_skb(skb); | 3576 | kfree_skb(skb); |
| @@ -64,6 +64,10 @@ struct uld_ctx { · 63 unmodified lines | |||
| 64 | static LIST_HEAD(uld_ctx_list); | 64 | static LIST_HEAD(uld_ctx_list); |
| 65 | static DEFINE_MUTEX(dev_mutex); | 65 | static DEFINE_MUTEX(dev_mutex); |
| 66 | 66 | ||
| 67 | #define DB_FC_RESUME_SIZE 64 | ||
| 68 | #define DB_FC_RESUME_DELAY 1 | ||
| 69 | #define DB_FC_DRAIN_THRESH 0 | ||
| 70 | |||
| 67 | static struct dentry *c4iw_debugfs_root; | 71 | static struct dentry *c4iw_debugfs_root; |
| 68 | 72 | ||
| 69 | struct c4iw_debugfs_data { | 73 | struct c4iw_debugfs_data { |
| @@ -282,7 +286,7 @@ static const struct file_operations stag_debugfs_fops = { · 212 unmodified lines | |||
| 282 | .llseek = default_llseek, | 286 | .llseek = default_llseek, |
| 283 | }; | 287 | }; |
| 284 | 288 | ||
| 285 | static char *db_state_str[] = {"NORMAL", "FLOW_CONTROL", "RECOVERY"}; | 289 | static char *db_state_str[] = {"NORMAL", "FLOW_CONTROL", "RECOVERY", "STOPPED"}; |
| 286 | 290 | ||
| 287 | static int stats_show(struct seq_file *seq, void *v) | 291 | static int stats_show(struct seq_file *seq, void *v) |
| 288 | { | 292 | { |
| @@ -311,9 +315,10 @@ static int stats_show(struct seq_file *seq, void *v) · 22 unmodified lines | |||
| 311 | seq_printf(seq, " DB FULL: %10llu\n", dev->rdev.stats.db_full); | 315 | seq_printf(seq, " DB FULL: %10llu\n", dev->rdev.stats.db_full); |
| 312 | seq_printf(seq, " DB EMPTY: %10llu\n", dev->rdev.stats.db_empty); | 316 | seq_printf(seq, " DB EMPTY: %10llu\n", dev->rdev.stats.db_empty); |
| 313 | seq_printf(seq, " DB DROP: %10llu\n", dev->rdev.stats.db_drop); | 317 | seq_printf(seq, " DB DROP: %10llu\n", dev->rdev.stats.db_drop); |
| 314 | seq_printf(seq, " DB State: %s Transitions %llu\n", | 318 | seq_printf(seq, " DB State: %s Transitions %llu FC Interruptions %llu\n", |
| 315 | db_state_str[dev->db_state], | 319 | db_state_str[dev->db_state], |
| 316 | dev->rdev.stats.db_state_transitions); | 320 | dev->rdev.stats.db_state_transitions, |
| 321 | dev->rdev.stats.db_fc_interruptions); | ||
| 317 | seq_printf(seq, "TCAM_FULL: %10llu\n", dev->rdev.stats.tcam_full); | 322 | seq_printf(seq, "TCAM_FULL: %10llu\n", dev->rdev.stats.tcam_full); |
| 318 | seq_printf(seq, "ACT_OFLD_CONN_FAILS: %10llu\n", | 323 | seq_printf(seq, "ACT_OFLD_CONN_FAILS: %10llu\n", |
| 319 | dev->rdev.stats.act_ofld_conn_fails); | 324 | dev->rdev.stats.act_ofld_conn_fails); |
| @@ -643,6 +648,12 @@ static int c4iw_rdev_open(struct c4iw_rdev *rdev) · 323 unmodified lines | |||
| 643 | printk(KERN_ERR MOD "error %d initializing ocqp pool\n", err); | 648 | printk(KERN_ERR MOD "error %d initializing ocqp pool\n", err); |
| 644 | goto err4; | 649 | goto err4; |
| 645 | } | 650 | } |
| 651 | rdev->status_page = (struct t4_dev_status_page *) | ||
| 652 | __get_free_page(GFP_KERNEL); | ||
| 653 | if (!rdev->status_page) { | ||
| 654 | pr_err(MOD "error allocating status page\n"); | ||
| 655 | goto err4; | ||
| 656 | } | ||
| 646 | return 0; | 657 | return 0; |
| 647 | err4: | 658 | err4: |
| 648 | c4iw_rqtpool_destroy(rdev); | 659 | c4iw_rqtpool_destroy(rdev); |
| @@ -656,6 +667,7 @@ err1: · 7 unmodified lines | |||
| 656 | 667 | ||
| 657 | static void c4iw_rdev_close(struct c4iw_rdev *rdev) | 668 | static void c4iw_rdev_close(struct c4iw_rdev *rdev) |
| 658 | { | 669 | { |
| 670 | free_page((unsigned long)rdev->status_page); | ||
| 659 | c4iw_pblpool_destroy(rdev); | 671 | c4iw_pblpool_destroy(rdev); |
| 660 | c4iw_rqtpool_destroy(rdev); | 672 | c4iw_rqtpool_destroy(rdev); |
| 661 | c4iw_destroy_resource(&rdev->resource); | 673 | c4iw_destroy_resource(&rdev->resource); |
| @@ -703,18 +715,6 @@ static struct c4iw_dev *c4iw_alloc(const struct cxgb4_lld_info *infop) · 41 unmodified lines | |||
| 703 | pr_info("%s: On-Chip Queues not supported on this device.\n", | 715 | pr_info("%s: On-Chip Queues not supported on this device.\n", |
| 704 | pci_name(infop->pdev)); | 716 | pci_name(infop->pdev)); |
| 705 | 717 | ||
| 706 | if (!is_t4(infop->adapter_type)) { | ||
| 707 | if (!allow_db_fc_on_t5) { | ||
| 708 | db_fc_threshold = 100000; | ||
| 709 | pr_info("DB Flow Control Disabled.\n"); | ||
| 710 | } | ||
| 711 | |||
| 712 | if (!allow_db_coalescing_on_t5) { | ||
| 713 | db_coalescing_threshold = -1; | ||
| 714 | pr_info("DB Coalescing Disabled.\n"); | ||
| 715 | } | ||
| 716 | } | ||
| 717 | |||
| 718 | devp = (struct c4iw_dev *)ib_alloc_device(sizeof(*devp)); | 718 | devp = (struct c4iw_dev *)ib_alloc_device(sizeof(*devp)); |
| 719 | if (!devp) { | 719 | if (!devp) { |
| 720 | printk(KERN_ERR MOD "Cannot allocate ib device\n"); | 720 | printk(KERN_ERR MOD "Cannot allocate ib device\n"); |
| @@ -749,6 +749,7 @@ static struct c4iw_dev *c4iw_alloc(const struct cxgb4_lld_info *infop) · 28 unmodified lines | |||
| 749 | spin_lock_init(&devp->lock); | 749 | spin_lock_init(&devp->lock); |
| 750 | mutex_init(&devp->rdev.stats.lock); | 750 | mutex_init(&devp->rdev.stats.lock); |
| 751 | mutex_init(&devp->db_mutex); | 751 | mutex_init(&devp->db_mutex); |
| 752 | INIT_LIST_HEAD(&devp->db_fc_list); | ||
| 752 | 753 | ||
| 753 | if (c4iw_debugfs_root) { | 754 | if (c4iw_debugfs_root) { |
| 754 | devp->debugfs_root = debugfs_create_dir( | 755 | devp->debugfs_root = debugfs_create_dir( |
| @@ -977,13 +978,16 @@ static int disable_qp_db(int id, void *p, void *data) · 222 unmodified lines | |||
| 977 | 978 | ||
| 978 | static void stop_queues(struct uld_ctx *ctx) | 979 | static void stop_queues(struct uld_ctx *ctx) |
| 979 | { | 980 | { |
| 980 | spin_lock_irq(&ctx->dev->lock); | 981 | unsigned long flags; |
| 981 | if (ctx->dev->db_state == NORMAL) { | 982 | |
| 982 | ctx->dev->rdev.stats.db_state_transitions++; | 983 | spin_lock_irqsave(&ctx->dev->lock, flags); |
| 983 | ctx->dev->db_state = FLOW_CONTROL; | 984 | ctx->dev->rdev.stats.db_state_transitions++; |
| 985 | ctx->dev->db_state = STOPPED; | ||
| 986 | if (ctx->dev->rdev.flags & T4_STATUS_PAGE_DISABLED) | ||
| 984 | idr_for_each(&ctx->dev->qpidr, disable_qp_db, NULL); | 987 | idr_for_each(&ctx->dev->qpidr, disable_qp_db, NULL); |
| 985 | } | 988 | else |
| 986 | spin_unlock_irq(&ctx->dev->lock); | 989 | ctx->dev->rdev.status_page->db_off = 1; |
| 990 | spin_unlock_irqrestore(&ctx->dev->lock, flags); | ||
| 987 | } | 991 | } |
| 988 | 992 | ||
| 989 | static int enable_qp_db(int id, void *p, void *data) | 993 | static int enable_qp_db(int id, void *p, void *data) |
| @@ -994,15 +998,70 @@ static int enable_qp_db(int id, void *p, void *data) · 4 unmodified lines | |||
| 994 | return 0; | 998 | return 0; |
| 995 | } | 999 | } |
| 996 | 1000 | ||
| 1001 | static void resume_rc_qp(struct c4iw_qp *qp) | ||
| 1002 | { | ||
| 1003 | spin_lock(&qp->lock); | ||
| 1004 | t4_ring_sq_db(&qp->wq, qp->wq.sq.wq_pidx_inc); | ||
| 1005 | qp->wq.sq.wq_pidx_inc = 0; | ||
| 1006 | t4_ring_rq_db(&qp->wq, qp->wq.rq.wq_pidx_inc); | ||
| 1007 | qp->wq.rq.wq_pidx_inc = 0; | ||
| 1008 | spin_unlock(&qp->lock); | ||
| 1009 | } | ||
| 1010 | |||
| 1011 | static void resume_a_chunk(struct uld_ctx *ctx) | ||
| 1012 | { | ||
| 1013 | int i; | ||
| 1014 | struct c4iw_qp *qp; | ||
| 1015 | |||
| 1016 | for (i = 0; i < DB_FC_RESUME_SIZE; i++) { | ||
| 1017 | qp = list_first_entry(&ctx->dev->db_fc_list, struct c4iw_qp, | ||
| 1018 | db_fc_entry); | ||
| 1019 | list_del_init(&qp->db_fc_entry); | ||
| 1020 | resume_rc_qp(qp); | ||
| 1021 | if (list_empty(&ctx->dev->db_fc_list)) | ||
| 1022 | break; | ||
| 1023 | } | ||
| 1024 | } | ||
| 1025 | |||
| 997 | static void resume_queues(struct uld_ctx *ctx) | 1026 | static void resume_queues(struct uld_ctx *ctx) |
| 998 | { | 1027 | { |
| 999 | spin_lock_irq(&ctx->dev->lock); | 1028 | spin_lock_irq(&ctx->dev->lock); |
| 1000 | if (ctx->dev->qpcnt <= db_fc_threshold && | 1029 | if (ctx->dev->db_state != STOPPED) |
| 1001 | ctx->dev->db_state == FLOW_CONTROL) { | 1030 | goto out; |
| 1002 | ctx->dev->db_state = NORMAL; | 1031 | ctx->dev->db_state = FLOW_CONTROL; |
| 1003 | ctx->dev->rdev.stats.db_state_transitions++; | 1032 | while (1) { |
| 1004 | idr_for_each(&ctx->dev->qpidr, enable_qp_db, NULL); | 1033 | if (list_empty(&ctx->dev->db_fc_list)) { |
| 1034 | WARN_ON(ctx->dev->db_state != FLOW_CONTROL); | ||
| 1035 | ctx->dev->db_state = NORMAL; | ||
| 1036 | ctx->dev->rdev.stats.db_state_transitions++; | ||
| 1037 | if (ctx->dev->rdev.flags & T4_STATUS_PAGE_DISABLED) { | ||
| 1038 | idr_for_each(&ctx->dev->qpidr, enable_qp_db, | ||
| 1039 | NULL); | ||
| 1040 | } else { | ||
| 1041 | ctx->dev->rdev.status_page->db_off = 0; | ||
| 1042 | } | ||
| 1043 | break; | ||
| 1044 | } else { | ||
| 1045 | if (cxgb4_dbfifo_count(ctx->dev->rdev.lldi.ports[0], 1) | ||
| 1046 | < (ctx->dev->rdev.lldi.dbfifo_int_thresh << | ||
| 1047 | DB_FC_DRAIN_THRESH)) { | ||
| 1048 | resume_a_chunk(ctx); | ||
| 1049 | } | ||
| 1050 | if (!list_empty(&ctx->dev->db_fc_list)) { | ||
| 1051 | spin_unlock_irq(&ctx->dev->lock); | ||
| 1052 | if (DB_FC_RESUME_DELAY) { | ||
| 1053 | set_current_state(TASK_UNINTERRUPTIBLE); | ||
| 1054 | schedule_timeout(DB_FC_RESUME_DELAY); | ||
| 1055 | } | ||
| 1056 | spin_lock_irq(&ctx->dev->lock); | ||
| 1057 | if (ctx->dev->db_state != FLOW_CONTROL) | ||
| 1058 | break; | ||
| 1059 | } | ||
| 1060 | } | ||
| 1005 | } | 1061 | } |
| 1062 | out: | ||
| 1063 | if (ctx->dev->db_state != NORMAL) | ||
| 1064 | ctx->dev->rdev.stats.db_fc_interruptions++; | ||
| 1006 | spin_unlock_irq(&ctx->dev->lock); | 1065 | spin_unlock_irq(&ctx->dev->lock); |
| 1007 | } | 1066 | } |
| 1008 | 1067 | ||
| @@ -1028,12 +1087,12 @@ static int count_qps(int id, void *p, void *data) · 19 unmodified lines | |||
| 1028 | return 0; | 1087 | return 0; |
| 1029 | } | 1088 | } |
| 1030 | 1089 | ||
| 1031 | static void deref_qps(struct qp_list qp_list) | 1090 | static void deref_qps(struct qp_list *qp_list) |
| 1032 | { | 1091 | { |
| 1033 | int idx; | 1092 | int idx; |
| 1034 | 1093 | ||
| 1035 | for (idx = 0; idx < qp_list.idx; idx++) | 1094 | for (idx = 0; idx < qp_list->idx; idx++) |
| 1036 | c4iw_qp_rem_ref(&qp_list.qps[idx]->ibqp); | 1095 | c4iw_qp_rem_ref(&qp_list->qps[idx]->ibqp); |
| 1037 | } | 1096 | } |
| 1038 | 1097 | ||
| 1039 | static void recover_lost_dbs(struct uld_ctx *ctx, struct qp_list *qp_list) | 1098 | static void recover_lost_dbs(struct uld_ctx *ctx, struct qp_list *qp_list) |
| @@ -1044,17 +1103,22 @@ static void recover_lost_dbs(struct uld_ctx *ctx, struct qp_list *qp_list) · 4 unmodified lines | |||
| 1044 | for (idx = 0; idx < qp_list->idx; idx++) { | 1103 | for (idx = 0; idx < qp_list->idx; idx++) { |
| 1045 | struct c4iw_qp *qp = qp_list->qps[idx]; | 1104 | struct c4iw_qp *qp = qp_list->qps[idx]; |
| 1046 | 1105 | ||
| 1106 | spin_lock_irq(&qp->rhp->lock); | ||
| 1107 | spin_lock(&qp->lock); | ||
| 1047 | ret = cxgb4_sync_txq_pidx(qp->rhp->rdev.lldi.ports[0], | 1108 | ret = cxgb4_sync_txq_pidx(qp->rhp->rdev.lldi.ports[0], |
| 1048 | qp->wq.sq.qid, | 1109 | qp->wq.sq.qid, |
| 1049 | t4_sq_host_wq_pidx(&qp->wq), | 1110 | t4_sq_host_wq_pidx(&qp->wq), |
| 1050 | t4_sq_wq_size(&qp->wq)); | 1111 | t4_sq_wq_size(&qp->wq)); |
| 1051 | if (ret) { | 1112 | if (ret) { |
| 1052 | printk(KERN_ERR MOD "%s: Fatal error - " | 1113 | pr_err(KERN_ERR MOD "%s: Fatal error - " |
| 1053 | "DB overflow recovery failed - " | 1114 | "DB overflow recovery failed - " |
| 1054 | "error syncing SQ qid %u\n", | 1115 | "error syncing SQ qid %u\n", |
| 1055 | pci_name(ctx->lldi.pdev), qp->wq.sq.qid); | 1116 | pci_name(ctx->lldi.pdev), qp->wq.sq.qid); |
| 1117 | spin_unlock(&qp->lock); | ||
| 1118 | spin_unlock_irq(&qp->rhp->lock); | ||
| 1056 | return; | 1119 | return; |
| 1057 | } | 1120 | } |
| 1121 | qp->wq.sq.wq_pidx_inc = 0; | ||
| 1058 | 1122 | ||
| 1059 | ret = cxgb4_sync_txq_pidx(qp->rhp->rdev.lldi.ports[0], | 1123 | ret = cxgb4_sync_txq_pidx(qp->rhp->rdev.lldi.ports[0], |
| 1060 | qp->wq.rq.qid, | 1124 | qp->wq.rq.qid, |
| @@ -1062,12 +1126,17 @@ static void recover_lost_dbs(struct uld_ctx *ctx, struct qp_list *qp_list) · 1 unmodified line | |||
| 1062 | t4_rq_wq_size(&qp->wq)); | 1126 | t4_rq_wq_size(&qp->wq)); |
| 1063 | 1127 | ||
| 1064 | if (ret) { | 1128 | if (ret) { |
| 1065 | printk(KERN_ERR MOD "%s: Fatal error - " | 1129 | pr_err(KERN_ERR MOD "%s: Fatal error - " |
| 1066 | "DB overflow recovery failed - " | 1130 | "DB overflow recovery failed - " |
| 1067 | "error syncing RQ qid %u\n", | 1131 | "error syncing RQ qid %u\n", |
| 1068 | pci_name(ctx->lldi.pdev), qp->wq.rq.qid); | 1132 | pci_name(ctx->lldi.pdev), qp->wq.rq.qid); |
| 1133 | spin_unlock(&qp->lock); | ||
| 1134 | spin_unlock_irq(&qp->rhp->lock); | ||
| 1069 | return; | 1135 | return; |
| 1070 | } | 1136 | } |
| 1137 | qp->wq.rq.wq_pidx_inc = 0; | ||
| 1138 | spin_unlock(&qp->lock); | ||
| 1139 | spin_unlock_irq(&qp->rhp->lock); | ||
| 1071 | 1140 | ||
| 1072 | /* Wait for the dbfifo to drain */ | 1141 | /* Wait for the dbfifo to drain */ |
| 1073 | while (cxgb4_dbfifo_count(qp->rhp->rdev.lldi.ports[0], 1) > 0) { | 1142 | while (cxgb4_dbfifo_count(qp->rhp->rdev.lldi.ports[0], 1) > 0) { |
| @@ -1083,36 +1152,22 @@ static void recover_queues(struct uld_ctx *ctx) · 9 unmodified lines | |||
| 1083 | struct qp_list qp_list; | 1152 | struct qp_list qp_list; |
| 1084 | int ret; | 1153 | int ret; |
| 1085 | 1154 | ||
| 1086 | /* lock out kernel db ringers */ | ||
| 1087 | mutex_lock(&ctx->dev->db_mutex); | ||
| 1088 | |||
| 1089 | /* put all queues in to recovery mode */ | ||
| 1090 | spin_lock_irq(&ctx->dev->lock); | ||
| 1091 | ctx->dev->db_state = RECOVERY; | ||
| 1092 | ctx->dev->rdev.stats.db_state_transitions++; | ||
| 1093 | idr_for_each(&ctx->dev->qpidr, disable_qp_db, NULL); | ||
| 1094 | spin_unlock_irq(&ctx->dev->lock); | ||
| 1095 | |||
| 1096 | /* slow everybody down */ | 1155 | /* slow everybody down */ |
| 1097 | set_current_state(TASK_UNINTERRUPTIBLE); | 1156 | set_current_state(TASK_UNINTERRUPTIBLE); |
| 1098 | schedule_timeout(usecs_to_jiffies(1000)); | 1157 | schedule_timeout(usecs_to_jiffies(1000)); |
| 1099 | 1158 | ||
| 1100 | /* Wait for the dbfifo to completely drain. */ | ||
| 1101 | while (cxgb4_dbfifo_count(ctx->dev->rdev.lldi.ports[0], 1) > 0) { | ||
| 1102 | set_current_state(TASK_UNINTERRUPTIBLE); | ||
| 1103 | schedule_timeout(usecs_to_jiffies(10)); | ||
| 1104 | } | ||
| 1105 | |||
| 1106 | /* flush the SGE contexts */ | 1159 | /* flush the SGE contexts */ |
| 1107 | ret = cxgb4_flush_eq_cache(ctx->dev->rdev.lldi.ports[0]); | 1160 | ret = cxgb4_flush_eq_cache(ctx->dev->rdev.lldi.ports[0]); |
| 1108 | if (ret) { | 1161 | if (ret) { |
| 1109 | printk(KERN_ERR MOD "%s: Fatal error - DB overflow recovery failed\n", | 1162 | printk(KERN_ERR MOD "%s: Fatal error - DB overflow recovery failed\n", |
| 1110 | pci_name(ctx->lldi.pdev)); | 1163 | pci_name(ctx->lldi.pdev)); |
| 1111 | goto out; | 1164 | return; |
| 1112 | } | 1165 | } |
| 1113 | 1166 | ||
| 1114 | /* Count active queues so we can build a list of queues to recover */ | 1167 | /* Count active queues so we can build a list of queues to recover */ |
| 1115 | spin_lock_irq(&ctx->dev->lock); | 1168 | spin_lock_irq(&ctx->dev->lock); |
| 1169 | WARN_ON(ctx->dev->db_state != STOPPED); | ||
| 1170 | ctx->dev->db_state = RECOVERY; | ||
| 1116 | idr_for_each(&ctx->dev->qpidr, count_qps, &count); | 1171 | idr_for_each(&ctx->dev->qpidr, count_qps, &count); |
| 1117 | 1172 | ||
| 1118 | qp_list.qps = kzalloc(count * sizeof *qp_list.qps, GFP_ATOMIC); | 1173 | qp_list.qps = kzalloc(count * sizeof *qp_list.qps, GFP_ATOMIC); |
| @@ -1120,7 +1175,7 @@ static void recover_queues(struct uld_ctx *ctx) · 1 unmodified line | |||
| 1120 | printk(KERN_ERR MOD "%s: Fatal error - DB overflow recovery failed\n", | 1175 | printk(KERN_ERR MOD "%s: Fatal error - DB overflow recovery failed\n", |
| 1121 | pci_name(ctx->lldi.pdev)); | 1176 | pci_name(ctx->lldi.pdev)); |
| 1122 | spin_unlock_irq(&ctx->dev->lock); | 1177 | spin_unlock_irq(&ctx->dev->lock); |
| 1123 | goto out; | 1178 | return; |
| 1124 | } | 1179 | } |
| 1125 | qp_list.idx = 0; | 1180 | qp_list.idx = 0; |
| 1126 | 1181 | ||
| @@ -1133,29 +1188,13 @@ static void recover_queues(struct uld_ctx *ctx) · 6 unmodified lines | |||
| 1133 | recover_lost_dbs(ctx, &qp_list); | 1188 | recover_lost_dbs(ctx, &qp_list); |
| 1134 | 1189 | ||
| 1135 | /* we're almost done! deref the qps and clean up */ | 1190 | /* we're almost done! deref the qps and clean up */ |
| 1136 | deref_qps(qp_list); | 1191 | deref_qps(&qp_list); |
| 1137 | kfree(qp_list.qps); | 1192 | kfree(qp_list.qps); |
| 1138 | 1193 | ||
| 1139 | /* Wait for the dbfifo to completely drain again */ | ||
| 1140 | while (cxgb4_dbfifo_count(ctx->dev->rdev.lldi.ports[0], 1) > 0) { | ||
| 1141 | set_current_state(TASK_UNINTERRUPTIBLE); | ||
| 1142 | schedule_timeout(usecs_to_jiffies(10)); | ||
| 1143 | } | ||
| 1144 | |||
| 1145 | /* resume the queues */ | ||
| 1146 | spin_lock_irq(&ctx->dev->lock); | 1194 | spin_lock_irq(&ctx->dev->lock); |
| 1147 | if (ctx->dev->qpcnt > db_fc_threshold) | 1195 | WARN_ON(ctx->dev->db_state != RECOVERY); |
| 1148 | ctx->dev->db_state = FLOW_CONTROL; | 1196 | ctx->dev->db_state = STOPPED; |
| 1149 | else { | ||
| 1150 | ctx->dev->db_state = NORMAL; | ||
| 1151 | idr_for_each(&ctx->dev->qpidr, enable_qp_db, NULL); | ||
| 1152 | } | ||
| 1153 | ctx->dev->rdev.stats.db_state_transitions++; | ||
| 1154 | spin_unlock_irq(&ctx->dev->lock); | 1197 | spin_unlock_irq(&ctx->dev->lock); |
| 1155 | |||
| 1156 | out: | ||
| 1157 | /* start up kernel db ringers again */ | ||
| 1158 | mutex_unlock(&ctx->dev->db_mutex); | ||
| 1159 | } | 1198 | } |
| 1160 | 1199 | ||
| 1161 | static int c4iw_uld_control(void *handle, enum cxgb4_control control, ...) | 1200 | static int c4iw_uld_control(void *handle, enum cxgb4_control control, ...) |
| @@ -1165,9 +1204,7 @@ static int c4iw_uld_control(void *handle, enum cxgb4_control control, ...) · 3 unmodified lines | |||
| 1165 | switch (control) { | 1204 | switch (control) { |
| 1166 | case CXGB4_CONTROL_DB_FULL: | 1205 | case CXGB4_CONTROL_DB_FULL: |
| 1167 | stop_queues(ctx); | 1206 | stop_queues(ctx); |
| 1168 | mutex_lock(&ctx->dev->rdev.stats.lock); | ||
| 1169 | ctx->dev->rdev.stats.db_full++; | 1207 | ctx->dev->rdev.stats.db_full++; |
| 1170 | mutex_unlock(&ctx->dev->rdev.stats.lock); | ||
| 1171 | break; | 1208 | break; |
| 1172 | case CXGB4_CONTROL_DB_EMPTY: | 1209 | case CXGB4_CONTROL_DB_EMPTY: |
| 1173 | resume_queues(ctx); | 1210 | resume_queues(ctx); |
| @@ -109,6 +109,7 @@ struct c4iw_dev_ucontext { · 108 unmodified lines | |||
| 109 | 109 | ||
| 110 | enum c4iw_rdev_flags { | 110 | enum c4iw_rdev_flags { |
| 111 | T4_FATAL_ERROR = (1<<0), | 111 | T4_FATAL_ERROR = (1<<0), |
| 112 | T4_STATUS_PAGE_DISABLED = (1<<1), | ||
| 112 | }; | 113 | }; |
| 113 | 114 | ||
| 114 | struct c4iw_stat { | 115 | struct c4iw_stat { |
| @@ -130,6 +131,7 @@ struct c4iw_stats { · 15 unmodified lines | |||
| 130 | u64 db_empty; | 131 | u64 db_empty; |
| 131 | u64 db_drop; | 132 | u64 db_drop; |
| 132 | u64 db_state_transitions; | 133 | u64 db_state_transitions; |
| 134 | u64 db_fc_interruptions; | ||
| 133 | u64 tcam_full; | 135 | u64 tcam_full; |
| 134 | u64 act_ofld_conn_fails; | 136 | u64 act_ofld_conn_fails; |
| 135 | u64 pas_ofld_conn_fails; | 137 | u64 pas_ofld_conn_fails; |
| @@ -150,6 +152,7 @@ struct c4iw_rdev { · 14 unmodified lines | |||
| 150 | unsigned long oc_mw_pa; | 152 | unsigned long oc_mw_pa; |
| 151 | void __iomem *oc_mw_kva; | 153 | void __iomem *oc_mw_kva; |
| 152 | struct c4iw_stats stats; | 154 | struct c4iw_stats stats; |
| 155 | struct t4_dev_status_page *status_page; | ||
| 153 | }; | 156 | }; |
| 154 | 157 | ||
| 155 | static inline int c4iw_fatal_error(struct c4iw_rdev *rdev) | 158 | static inline int c4iw_fatal_error(struct c4iw_rdev *rdev) |
| @@ -211,7 +214,8 @@ static inline int c4iw_wait_for_reply(struct c4iw_rdev *rdev, · 55 unmodified lines | |||
| 211 | enum db_state { | 214 | enum db_state { |
| 212 | NORMAL = 0, | 215 | NORMAL = 0, |
| 213 | FLOW_CONTROL = 1, | 216 | FLOW_CONTROL = 1, |
| 214 | RECOVERY = 2 | 217 | RECOVERY = 2, |
| 218 | STOPPED = 3 | ||
| 215 | }; | 219 | }; |
| 216 | 220 | ||
| 217 | struct c4iw_dev { | 221 | struct c4iw_dev { |
| @@ -225,10 +229,10 @@ struct c4iw_dev { · 7 unmodified lines | |||
| 225 | struct mutex db_mutex; | 229 | struct mutex db_mutex; |
| 226 | struct dentry *debugfs_root; | 230 | struct dentry *debugfs_root; |
| 227 | enum db_state db_state; | 231 | enum db_state db_state; |
| 228 | int qpcnt; | ||
| 229 | struct idr hwtid_idr; | 232 | struct idr hwtid_idr; |
| 230 | struct idr atid_idr; | 233 | struct idr atid_idr; |
| 231 | struct idr stid_idr; | 234 | struct idr stid_idr; |
| 235 | struct list_head db_fc_list; | ||
| 232 | }; | 236 | }; |
| 233 | 237 | ||
| 234 | static inline struct c4iw_dev *to_c4iw_dev(struct ib_device *ibdev) | 238 | static inline struct c4iw_dev *to_c4iw_dev(struct ib_device *ibdev) |
| @@ -432,6 +436,7 @@ struct c4iw_qp_attributes { · 197 unmodified lines | |||
| 432 | 436 | ||
| 433 | struct c4iw_qp { | 437 | struct c4iw_qp { |
| 434 | struct ib_qp ibqp; | 438 | struct ib_qp ibqp; |
| 439 | struct list_head db_fc_entry; | ||
| 435 | struct c4iw_dev *rhp; | 440 | struct c4iw_dev *rhp; |
| 436 | struct c4iw_ep *ep; | 441 | struct c4iw_ep *ep; |
| 437 | struct c4iw_qp_attributes attr; | 442 | struct c4iw_qp_attributes attr; |
| @@ -106,15 +106,56 @@ static struct ib_ucontext *c4iw_alloc_ucontext(struct ib_device *ibdev, · 105 unmodified lines | |||
| 106 | { | 106 | { |
| 107 | struct c4iw_ucontext *context; | 107 | struct c4iw_ucontext *context; |
| 108 | struct c4iw_dev *rhp = to_c4iw_dev(ibdev); | 108 | struct c4iw_dev *rhp = to_c4iw_dev(ibdev); |
| 109 | static int warned; | ||
| 110 | struct c4iw_alloc_ucontext_resp uresp; | ||
| 111 | int ret = 0; | ||
| 112 | struct c4iw_mm_entry *mm = NULL; | ||
| 109 | 113 | ||
| 110 | PDBG("%s ibdev %p\n", __func__, ibdev); | 114 | PDBG("%s ibdev %p\n", __func__, ibdev); |
| 111 | context = kzalloc(sizeof(*context), GFP_KERNEL); | 115 | context = kzalloc(sizeof(*context), GFP_KERNEL); |
| 112 | if (!context) | 116 | if (!context) { |
| 113 | return ERR_PTR(-ENOMEM); | 117 | ret = -ENOMEM; |
| 118 | goto err; | ||
| 119 | } | ||
| 120 | |||
| 114 | c4iw_init_dev_ucontext(&rhp->rdev, &context->uctx); | 121 | c4iw_init_dev_ucontext(&rhp->rdev, &context->uctx); |
| 115 | INIT_LIST_HEAD(&context->mmaps); | 122 | INIT_LIST_HEAD(&context->mmaps); |
| 116 | spin_lock_init(&context->mmap_lock); | 123 | spin_lock_init(&context->mmap_lock); |
| 124 | |||
| 125 | if (udata->outlen < sizeof(uresp)) { | ||
| 126 | if (!warned++) | ||
| 127 | pr_err(MOD "Warning - downlevel libcxgb4 (non-fatal), device status page disabled."); | ||
| 128 | rhp->rdev.flags |= T4_STATUS_PAGE_DISABLED; | ||
| 129 | } else { | ||
| 130 | mm = kmalloc(sizeof(*mm), GFP_KERNEL); | ||
| 131 | if (!mm) { | ||
| 132 | ret = -ENOMEM; | ||
| 133 | goto err_free; | ||
| 134 | } | ||
| 135 | |||
| 136 | uresp.status_page_size = PAGE_SIZE; | ||
| 137 | |||
| 138 | spin_lock(&context->mmap_lock); | ||
| 139 | uresp.status_page_key = context->key; | ||
| 140 | context->key += PAGE_SIZE; | ||
| 141 | spin_unlock(&context->mmap_lock); | ||
| 142 | |||
| 143 | ret = ib_copy_to_udata(udata, &uresp, sizeof(uresp)); | ||
| 144 | if (ret) | ||
| 145 | goto err_mm; | ||
| 146 | |||
| 147 | mm->key = uresp.status_page_key; | ||
| 148 | mm->addr = virt_to_phys(rhp->rdev.status_page); | ||
| 149 | mm->len = PAGE_SIZE; | ||
| 150 | insert_mmap(context, mm); | ||
| 151 | } | ||
| 117 | return &context->ibucontext; | 152 | return &context->ibucontext; |
| 153 | err_mm: | ||
| 154 | kfree(mm); | ||
| 155 | err_free: | ||
| 156 | kfree(context); | ||
| 157 | err: | ||
| 158 | return ERR_PTR(ret); | ||
| 118 | } | 159 | } |
| 119 | 160 | ||
| 120 | static int c4iw_mmap(struct ib_ucontext *context, struct vm_area_struct *vma) | 161 | static int c4iw_mmap(struct ib_ucontext *context, struct vm_area_struct *vma) |
| @@ -638,6 +638,46 @@ void c4iw_qp_rem_ref(struct ib_qp *qp) · 637 unmodified lines | |||
| 638 | wake_up(&(to_c4iw_qp(qp)->wait)); | 638 | wake_up(&(to_c4iw_qp(qp)->wait)); |
| 639 | } | 639 | } |
| 640 | 640 | ||
| 641 | static void add_to_fc_list(struct list_head *head, struct list_head *entry) | ||
| 642 | { | ||
| 643 | if (list_empty(entry)) | ||
| 644 | list_add_tail(entry, head); | ||
| 645 | } | ||
| 646 | |||
| 647 | static int ring_kernel_sq_db(struct c4iw_qp *qhp, u16 inc) | ||
| 648 | { | ||
| 649 | unsigned long flags; | ||
| 650 | |||
| 651 | spin_lock_irqsave(&qhp->rhp->lock, flags); | ||
| 652 | spin_lock(&qhp->lock); | ||
| 653 | if (qhp->rhp->db_state == NORMAL) { | ||
| 654 | t4_ring_sq_db(&qhp->wq, inc); | ||
| 655 | } else { | ||
| 656 | add_to_fc_list(&qhp->rhp->db_fc_list, &qhp->db_fc_entry); | ||
| 657 | qhp->wq.sq.wq_pidx_inc += inc; | ||
| 658 | } | ||
| 659 | spin_unlock(&qhp->lock); | ||
| 660 | spin_unlock_irqrestore(&qhp->rhp->lock, flags); | ||
| 661 | return 0; | ||
| 662 | } | ||
| 663 | |||
| 664 | static int ring_kernel_rq_db(struct c4iw_qp *qhp, u16 inc) | ||
| 665 | { | ||
| 666 | unsigned long flags; | ||
| 667 | |||
| 668 | spin_lock_irqsave(&qhp->rhp->lock, flags); | ||
| 669 | spin_lock(&qhp->lock); | ||
| 670 | if (qhp->rhp->db_state == NORMAL) { | ||
| 671 | t4_ring_rq_db(&qhp->wq, inc); | ||
| 672 | } else { | ||
| 673 | add_to_fc_list(&qhp->rhp->db_fc_list, &qhp->db_fc_entry); | ||
| 674 | qhp->wq.rq.wq_pidx_inc += inc; | ||
| 675 | } | ||
| 676 | spin_unlock(&qhp->lock); | ||
| 677 | spin_unlock_irqrestore(&qhp->rhp->lock, flags); | ||
| 678 | return 0; | ||
| 679 | } | ||
| 680 | |||
| 641 | int c4iw_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, | 681 | int c4iw_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, |
| 642 | struct ib_send_wr **bad_wr) | 682 | struct ib_send_wr **bad_wr) |
| 643 | { | 683 | { |
| @@ -750,9 +790,13 @@ int c4iw_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, · 106 unmodified lines | |||
| 750 | t4_sq_produce(&qhp->wq, len16); | 790 | t4_sq_produce(&qhp->wq, len16); |
| 751 | idx += DIV_ROUND_UP(len16*16, T4_EQ_ENTRY_SIZE); | 791 | idx += DIV_ROUND_UP(len16*16, T4_EQ_ENTRY_SIZE); |
| 752 | } | 792 | } |
| 753 | if (t4_wq_db_enabled(&qhp->wq)) | 793 | if (!qhp->rhp->rdev.status_page->db_off) { |
| 754 | t4_ring_sq_db(&qhp->wq, idx); | 794 | t4_ring_sq_db(&qhp->wq, idx); |
| 755 | spin_unlock_irqrestore(&qhp->lock, flag); | 795 | spin_unlock_irqrestore(&qhp->lock, flag); |
| 796 | } else { | ||
| 797 | spin_unlock_irqrestore(&qhp->lock, flag); | ||
| 798 | ring_kernel_sq_db(qhp, idx); | ||
| 799 | } | ||
| 756 | return err; | 800 | return err; |
| 757 | } | 801 | } |
| 758 | 802 | ||
| @@ -812,9 +856,13 @@ int c4iw_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *wr, · 53 unmodified lines | |||
| 812 | wr = wr->next; | 856 | wr = wr->next; |
| 813 | num_wrs--; | 857 | num_wrs--; |
| 814 | } | 858 | } |
| 815 | if (t4_wq_db_enabled(&qhp->wq)) | 859 | if (!qhp->rhp->rdev.status_page->db_off) { |
| 816 | t4_ring_rq_db(&qhp->wq, idx); | 860 | t4_ring_rq_db(&qhp->wq, idx); |
| 817 | spin_unlock_irqrestore(&qhp->lock, flag); | 861 | spin_unlock_irqrestore(&qhp->lock, flag); |
| 862 | } else { | ||
| 863 | spin_unlock_irqrestore(&qhp->lock, flag); | ||
| 864 | ring_kernel_rq_db(qhp, idx); | ||
| 865 | } | ||
| 818 | return err; | 866 | return err; |
| 819 | } | 867 | } |
| 820 | 868 | ||
| @@ -1200,35 +1248,6 @@ out: · 379 unmodified lines | |||
| 1200 | return ret; | 1248 | return ret; |
| 1201 | } | 1249 | } |
| 1202 | 1250 | ||
| 1203 | /* | ||
| 1204 | * Called by the library when the qp has user dbs disabled due to | ||
| 1205 | * a DB_FULL condition. This function will single-thread all user | ||
| 1206 | * DB rings to avoid overflowing the hw db-fifo. | ||
| 1207 | */ | ||
| 1208 | static int ring_kernel_db(struct c4iw_qp *qhp, u32 qid, u16 inc) | ||
| 1209 | { | ||
| 1210 | int delay = db_delay_usecs; | ||
| 1211 | |||
| 1212 | mutex_lock(&qhp->rhp->db_mutex); | ||
| 1213 | do { | ||
| 1214 | |||
| 1215 | /* | ||
| 1216 | * The interrupt threshold is dbfifo_int_thresh << 6. So | ||
| 1217 | * make sure we don't cross that and generate an interrupt. | ||
| 1218 | */ | ||
| 1219 | if (cxgb4_dbfifo_count(qhp->rhp->rdev.lldi.ports[0], 1) < | ||
| 1220 | (qhp->rhp->rdev.lldi.dbfifo_int_thresh << 5)) { | ||
| 1221 | writel(QID(qid) | PIDX(inc), qhp->wq.db); | ||
| 1222 | break; | ||
| 1223 | } | ||
| 1224 | set_current_state(TASK_UNINTERRUPTIBLE); | ||
| 1225 | schedule_timeout(usecs_to_jiffies(delay)); | ||
| 1226 | delay = min(delay << 1, 2000); | ||
| 1227 | } while (1); | ||
| 1228 | mutex_unlock(&qhp->rhp->db_mutex); | ||
| 1229 | return 0; | ||
| 1230 | } | ||
| 1231 | |||
| 1232 | int c4iw_modify_qp(struct c4iw_dev *rhp, struct c4iw_qp *qhp, | 1251 | int c4iw_modify_qp(struct c4iw_dev *rhp, struct c4iw_qp *qhp, |
| 1233 | enum c4iw_qp_attr_mask mask, | 1252 | enum c4iw_qp_attr_mask mask, |
| 1234 | struct c4iw_qp_attributes *attrs, | 1253 | struct c4iw_qp_attributes *attrs, |
| @@ -1278,11 +1297,11 @@ int c4iw_modify_qp(struct c4iw_dev *rhp, struct c4iw_qp *qhp, · 43 unmodified lines | |||
| 1278 | } | 1297 | } |
| 1279 | 1298 | ||
| 1280 | if (mask & C4IW_QP_ATTR_SQ_DB) { | 1299 | if (mask & C4IW_QP_ATTR_SQ_DB) { |
| 1281 | ret = ring_kernel_db(qhp, qhp->wq.sq.qid, attrs->sq_db_inc); | 1300 | ret = ring_kernel_sq_db(qhp, attrs->sq_db_inc); |
| 1282 | goto out; | 1301 | goto out; |
| 1283 | } | 1302 | } |
| 1284 | if (mask & C4IW_QP_ATTR_RQ_DB) { | 1303 | if (mask & C4IW_QP_ATTR_RQ_DB) { |
| 1285 | ret = ring_kernel_db(qhp, qhp->wq.rq.qid, attrs->rq_db_inc); | 1304 | ret = ring_kernel_rq_db(qhp, attrs->rq_db_inc); |
| 1286 | goto out; | 1305 | goto out; |
| 1287 | } | 1306 | } |
| 1288 | 1307 | ||
| @@ -1465,14 +1484,6 @@ out: · 176 unmodified lines | |||
| 1465 | return ret; | 1484 | return ret; |
| 1466 | } | 1485 | } |
| 1467 | 1486 | ||
| 1468 | static int enable_qp_db(int id, void *p, void *data) | ||
| 1469 | { | ||
| 1470 | struct c4iw_qp *qp = p; | ||
| 1471 | |||
| 1472 | t4_enable_wq_db(&qp->wq); | ||
| 1473 | return 0; | ||
| 1474 | } | ||
| 1475 | |||
| 1476 | int c4iw_destroy_qp(struct ib_qp *ib_qp) | 1487 | int c4iw_destroy_qp(struct ib_qp *ib_qp) |
| 1477 | { | 1488 | { |
| 1478 | struct c4iw_dev *rhp; | 1489 | struct c4iw_dev *rhp; |
| @@ -1490,22 +1501,15 @@ int c4iw_destroy_qp(struct ib_qp *ib_qp) · 11 unmodified lines | |||
| 1490 | c4iw_modify_qp(rhp, qhp, C4IW_QP_ATTR_NEXT_STATE, &attrs, 0); | 1501 | c4iw_modify_qp(rhp, qhp, C4IW_QP_ATTR_NEXT_STATE, &attrs, 0); |
| 1491 | wait_event(qhp->wait, !qhp->ep); | 1502 | wait_event(qhp->wait, !qhp->ep); |
| 1492 | 1503 | ||
| 1493 | spin_lock_irq(&rhp->lock); | 1504 | remove_handle(rhp, &rhp->qpidr, qhp->wq.sq.qid); |
| 1494 | remove_handle_nolock(rhp, &rhp->qpidr, qhp->wq.sq.qid); | ||
| 1495 | rhp->qpcnt--; | ||
| 1496 | BUG_ON(rhp->qpcnt < 0); | ||
| 1497 | if (rhp->qpcnt <= db_fc_threshold && rhp->db_state == FLOW_CONTROL) { | ||
| 1498 | rhp->rdev.stats.db_state_transitions++; | ||
| 1499 | rhp->db_state = NORMAL; | ||
| 1500 | idr_for_each(&rhp->qpidr, enable_qp_db, NULL); | ||
| 1501 | } | ||
| 1502 | if (db_coalescing_threshold >= 0) | ||
| 1503 | if (rhp->qpcnt <= db_coalescing_threshold) | ||
| 1504 | cxgb4_enable_db_coalescing(rhp->rdev.lldi.ports[0]); | ||
| 1505 | spin_unlock_irq(&rhp->lock); | ||
| 1506 | atomic_dec(&qhp->refcnt); | 1505 | atomic_dec(&qhp->refcnt); |
| 1507 | wait_event(qhp->wait, !atomic_read(&qhp->refcnt)); | 1506 | wait_event(qhp->wait, !atomic_read(&qhp->refcnt)); |
| 1508 | 1507 | ||
| 1508 | spin_lock_irq(&rhp->lock); | ||
| 1509 | if (!list_empty(&qhp->db_fc_entry)) | ||
| 1510 | list_del_init(&qhp->db_fc_entry); | ||
| 1511 | spin_unlock_irq(&rhp->lock); | ||
| 1512 | |||
| 1509 | ucontext = ib_qp->uobject ? | 1513 | ucontext = ib_qp->uobject ? |
| 1510 | to_c4iw_ucontext(ib_qp->uobject->context) : NULL; | 1514 | to_c4iw_ucontext(ib_qp->uobject->context) : NULL; |
| 1511 | destroy_qp(&rhp->rdev, &qhp->wq, | 1515 | destroy_qp(&rhp->rdev, &qhp->wq, |
| @@ -1516,14 +1520,6 @@ int c4iw_destroy_qp(struct ib_qp *ib_qp) · 4 unmodified lines | |||
| 1516 | return 0; | 1520 | return 0; |
| 1517 | } | 1521 | } |
| 1518 | 1522 | ||
| 1519 | static int disable_qp_db(int id, void *p, void *data) | ||
| 1520 | { | ||
| 1521 | struct c4iw_qp *qp = p; | ||
| 1522 | |||
| 1523 | t4_disable_wq_db(&qp->wq); | ||
| 1524 | return 0; | ||
| 1525 | } | ||
| 1526 | |||
| 1527 | struct ib_qp *c4iw_create_qp(struct ib_pd *pd, struct ib_qp_init_attr *attrs, | 1523 | struct ib_qp *c4iw_create_qp(struct ib_pd *pd, struct ib_qp_init_attr *attrs, |
| 1528 | struct ib_udata *udata) | 1524 | struct ib_udata *udata) |
| 1529 | { | 1525 | { |
| @@ -1610,20 +1606,7 @@ struct ib_qp *c4iw_create_qp(struct ib_pd *pd, struct ib_qp_init_attr *attrs, · 80 unmodified lines | |||
| 1610 | init_waitqueue_head(&qhp->wait); | 1606 | init_waitqueue_head(&qhp->wait); |
| 1611 | atomic_set(&qhp->refcnt, 1); | 1607 | atomic_set(&qhp->refcnt, 1); |
| 1612 | 1608 | ||
| 1613 | spin_lock_irq(&rhp->lock); | 1609 | ret = insert_handle(rhp, &rhp->qpidr, qhp, qhp->wq.sq.qid); |
| 1614 | if (rhp->db_state != NORMAL) | ||
| 1615 | t4_disable_wq_db(&qhp->wq); | ||
| 1616 | rhp->qpcnt++; | ||
| 1617 | if (rhp->qpcnt > db_fc_threshold && rhp->db_state == NORMAL) { | ||
| 1618 | rhp->rdev.stats.db_state_transitions++; | ||
| 1619 | rhp->db_state = FLOW_CONTROL; | ||
| 1620 | idr_for_each(&rhp->qpidr, disable_qp_db, NULL); | ||
| 1621 | } | ||
| 1622 | if (db_coalescing_threshold >= 0) | ||
| 1623 | if (rhp->qpcnt > db_coalescing_threshold) | ||
| 1624 | cxgb4_disable_db_coalescing(rhp->rdev.lldi.ports[0]); | ||
| 1625 | ret = insert_handle_nolock(rhp, &rhp->qpidr, qhp, qhp->wq.sq.qid); | ||
| 1626 | spin_unlock_irq(&rhp->lock); | ||
| 1627 | if (ret) | 1610 | if (ret) |
| 1628 | goto err2; | 1611 | goto err2; |
| 1629 | 1612 | ||
| @@ -1709,6 +1692,7 @@ struct ib_qp *c4iw_create_qp(struct ib_pd *pd, struct ib_qp_init_attr *attrs, · 79 unmodified lines | |||
| 1709 | } | 1692 | } |
| 1710 | qhp->ibqp.qp_num = qhp->wq.sq.qid; | 1693 | qhp->ibqp.qp_num = qhp->wq.sq.qid; |
| 1711 | init_timer(&(qhp->timer)); | 1694 | init_timer(&(qhp->timer)); |
| 1695 | INIT_LIST_HEAD(&qhp->db_fc_entry); | ||
| 1712 | PDBG("%s qhp %p sq_num_entries %d, rq_num_entries %d qpid 0x%0x\n", | 1696 | PDBG("%s qhp %p sq_num_entries %d, rq_num_entries %d qpid 0x%0x\n", |
| 1713 | __func__, qhp, qhp->attr.sq_num_entries, qhp->attr.rq_num_entries, | 1697 | __func__, qhp, qhp->attr.sq_num_entries, qhp->attr.rq_num_entries, |
| 1714 | qhp->wq.sq.qid); | 1698 | qhp->wq.sq.qid); |
| @@ -300,6 +300,7 @@ struct t4_sq { · 299 unmodified lines | |||
| 300 | u16 cidx; | 300 | u16 cidx; |
| 301 | u16 pidx; | 301 | u16 pidx; |
| 302 | u16 wq_pidx; | 302 | u16 wq_pidx; |
| 303 | u16 wq_pidx_inc; | ||
| 303 | u16 flags; | 304 | u16 flags; |
| 304 | short flush_cidx; | 305 | short flush_cidx; |
| 305 | }; | 306 | }; |
| @@ -324,6 +325,7 @@ struct t4_rq { · 18 unmodified lines | |||
| 324 | u16 cidx; | 325 | u16 cidx; |
| 325 | u16 pidx; | 326 | u16 pidx; |
| 326 | u16 wq_pidx; | 327 | u16 wq_pidx; |
| 328 | u16 wq_pidx_inc; | ||
| 327 | }; | 329 | }; |
| 328 | 330 | ||
| 329 | struct t4_wq { | 331 | struct t4_wq { |
| @@ -609,3 +611,7 @@ static inline void t4_set_cq_in_error(struct t4_cq *cq) · 279 unmodified lines | |||
| 609 | ((struct t4_status_page *)&cq->queue[cq->size])->qp_err = 1; | 611 | ((struct t4_status_page *)&cq->queue[cq->size])->qp_err = 1; |
| 610 | } | 612 | } |
| 611 | #endif | 613 | #endif |
| 614 | |||
| 615 | struct t4_dev_status_page { | ||
| 616 | u8 db_off; | ||
| 617 | }; | ||
| @@ -70,4 +70,9 @@ struct c4iw_create_qp_resp { · 69 unmodified lines | |||
| 70 | __u32 qid_mask; | 70 | __u32 qid_mask; |
| 71 | __u32 flags; | 71 | __u32 flags; |
| 72 | }; | 72 | }; |
| 73 | |||
| 74 | struct c4iw_alloc_ucontext_resp { | ||
| 75 | __u64 status_page_key; | ||
| 76 | __u32 status_page_size; | ||
| 77 | }; | ||
| 73 | #endif | 78 | #endif |
| @@ -154,7 +154,7 @@ void mlx4_ib_notify_slaves_on_guid_change(struct mlx4_ib_dev *dev, · 153 unmodified lines | |||
| 154 | continue; | 154 | continue; |
| 155 | 155 | ||
| 156 | slave_id = (block_num * NUM_ALIAS_GUID_IN_REC) + i ; | 156 | slave_id = (block_num * NUM_ALIAS_GUID_IN_REC) + i ; |
| 157 | if (slave_id >= dev->dev->num_slaves) | 157 | if (slave_id >= dev->dev->num_vfs + 1) |
| 158 | return; | 158 | return; |
| 159 | tmp_cur_ag = *(__be64 *)&p_data[i * GUID_REC_SIZE]; | 159 | tmp_cur_ag = *(__be64 *)&p_data[i * GUID_REC_SIZE]; |
| 160 | form_cache_ag = get_cached_alias_guid(dev, port_num, | 160 | form_cache_ag = get_cached_alias_guid(dev, port_num, |
| @@ -61,6 +61,11 @@ struct cm_generic_msg { · 60 unmodified lines | |||
| 61 | __be32 remote_comm_id; | 61 | __be32 remote_comm_id; |
| 62 | }; | 62 | }; |
| 63 | 63 | ||
| 64 | struct cm_sidr_generic_msg { | ||
| 65 | struct ib_mad_hdr hdr; | ||
| 66 | __be32 request_id; | ||
| 67 | }; | ||
| 68 | |||
| 64 | struct cm_req_msg { | 69 | struct cm_req_msg { |
| 65 | unsigned char unused[0x60]; | 70 | unsigned char unused[0x60]; |
| 66 | union ib_gid primary_path_sgid; | 71 | union ib_gid primary_path_sgid; |
| @@ -69,28 +74,62 @@ struct cm_req_msg { · 2 unmodified lines | |||
| 69 | 74 | ||
| 70 | static void set_local_comm_id(struct ib_mad *mad, u32 cm_id) | 75 | static void set_local_comm_id(struct ib_mad *mad, u32 cm_id) |
| 71 | { | 76 | { |
| 72 | struct cm_generic_msg *msg = (struct cm_generic_msg *)mad; | 77 | if (mad->mad_hdr.attr_id == CM_SIDR_REQ_ATTR_ID) { |
| 73 | msg->local_comm_id = cpu_to_be32(cm_id); | 78 | struct cm_sidr_generic_msg *msg = |
| 79 | (struct cm_sidr_generic_msg *)mad; | ||
| 80 | msg->request_id = cpu_to_be32(cm_id); | ||
| 81 | } else if (mad->mad_hdr.attr_id == CM_SIDR_REP_ATTR_ID) { | ||
| 82 | pr_err("trying to set local_comm_id in SIDR_REP\n"); | ||
| 83 | return; | ||
| 84 | } else { | ||
| 85 | struct cm_generic_msg *msg = (struct cm_generic_msg *)mad; | ||
| 86 | msg->local_comm_id = cpu_to_be32(cm_id); | ||
| 87 | } | ||
| 74 | } | 88 | } |
| 75 | 89 | ||
| 76 | static u32 get_local_comm_id(struct ib_mad *mad) | 90 | static u32 get_local_comm_id(struct ib_mad *mad) |
| 77 | { | 91 | { |
| 78 | struct cm_generic_msg *msg = (struct cm_generic_msg *)mad; | 92 | if (mad->mad_hdr.attr_id == CM_SIDR_REQ_ATTR_ID) { |
| 79 | 93 | struct cm_sidr_generic_msg *msg = | |
| 80 | return be32_to_cpu(msg->local_comm_id); | 94 | (struct cm_sidr_generic_msg *)mad; |
| 95 | return be32_to_cpu(msg->request_id); | ||
| 96 | } else if (mad->mad_hdr.attr_id == CM_SIDR_REP_ATTR_ID) { | ||
| 97 | pr_err("trying to set local_comm_id in SIDR_REP\n"); | ||
| 98 | return -1; | ||
| 99 | } else { | ||
| 100 | struct cm_generic_msg *msg = (struct cm_generic_msg *)mad; | ||
| 101 | return be32_to_cpu(msg->local_comm_id); | ||
| 102 | } | ||
| 81 | } | 103 | } |
| 82 | 104 | ||
| 83 | static void set_remote_comm_id(struct ib_mad *mad, u32 cm_id) | 105 | static void set_remote_comm_id(struct ib_mad *mad, u32 cm_id) |
| 84 | { | 106 | { |
| 85 | struct cm_generic_msg *msg = (struct cm_generic_msg *)mad; | 107 | if (mad->mad_hdr.attr_id == CM_SIDR_REP_ATTR_ID) { |
| 86 | msg->remote_comm_id = cpu_to_be32(cm_id); | 108 | struct cm_sidr_generic_msg *msg = |
| 109 | (struct cm_sidr_generic_msg *)mad; | ||
| 110 | msg->request_id = cpu_to_be32(cm_id); | ||
| 111 | } else if (mad->mad_hdr.attr_id == CM_SIDR_REQ_ATTR_ID) { | ||
| 112 | pr_err("trying to set remote_comm_id in SIDR_REQ\n"); | ||
| 113 | return; | ||
| 114 | } else { | ||
| 115 | struct cm_generic_msg *msg = (struct cm_generic_msg *)mad; | ||
| 116 | msg->remote_comm_id = cpu_to_be32(cm_id); | ||
| 117 | } | ||
| 87 | } | 118 | } |
| 88 | 119 | ||
| 89 | static u32 get_remote_comm_id(struct ib_mad *mad) | 120 | static u32 get_remote_comm_id(struct ib_mad *mad) |
| 90 | { | 121 | { |
| 91 | struct cm_generic_msg *msg = (struct cm_generic_msg *)mad; | 122 | if (mad->mad_hdr.attr_id == CM_SIDR_REP_ATTR_ID) { |
| 92 | 123 | struct cm_sidr_generic_msg *msg = | |
| 93 | return be32_to_cpu(msg->remote_comm_id); | 124 | (struct cm_sidr_generic_msg *)mad; |
| 125 | return be32_to_cpu(msg->request_id); | ||
| 126 | } else if (mad->mad_hdr.attr_id == CM_SIDR_REQ_ATTR_ID) { | ||
| 127 | pr_err("trying to set remote_comm_id in SIDR_REQ\n"); | ||
| 128 | return -1; | ||
| 129 | } else { | ||
| 130 | struct cm_generic_msg *msg = (struct cm_generic_msg *)mad; | ||
| 131 | return be32_to_cpu(msg->remote_comm_id); | ||
| 132 | } | ||
| 94 | } | 133 | } |
| 95 | 134 | ||
| 96 | static union ib_gid gid_from_req_msg(struct ib_device *ibdev, struct ib_mad *mad) | 135 | static union ib_gid gid_from_req_msg(struct ib_device *ibdev, struct ib_mad *mad) |
| @@ -282,19 +321,21 @@ int mlx4_ib_multiplex_cm_handler(struct ib_device *ibdev, int port, int slave_id · 185 unmodified lines | |||
| 282 | u32 sl_cm_id; | 321 | u32 sl_cm_id; |
| 283 | int pv_cm_id = -1; | 322 | int pv_cm_id = -1; |
| 284 | 323 | ||
| 285 | sl_cm_id = get_local_comm_id(mad); | ||
| 286 | |||
| 287 | if (mad->mad_hdr.attr_id == CM_REQ_ATTR_ID || | 324 | if (mad->mad_hdr.attr_id == CM_REQ_ATTR_ID || |
| 288 | mad->mad_hdr.attr_id == CM_REP_ATTR_ID) { | 325 | mad->mad_hdr.attr_id == CM_REP_ATTR_ID || |
| 326 | mad->mad_hdr.attr_id == CM_SIDR_REQ_ATTR_ID) { | ||
| 327 | sl_cm_id = get_local_comm_id(mad); | ||
| 289 | id = id_map_alloc(ibdev, slave_id, sl_cm_id); | 328 | id = id_map_alloc(ibdev, slave_id, sl_cm_id); |
| 290 | if (IS_ERR(id)) { | 329 | if (IS_ERR(id)) { |
| 291 | mlx4_ib_warn(ibdev, "%s: id{slave: %d, sl_cm_id: 0x%x} Failed to id_map_alloc\n", | 330 | mlx4_ib_warn(ibdev, "%s: id{slave: %d, sl_cm_id: 0x%x} Failed to id_map_alloc\n", |
| 292 | __func__, slave_id, sl_cm_id); | 331 | __func__, slave_id, sl_cm_id); |
| 293 | return PTR_ERR(id); | 332 | return PTR_ERR(id); |
| 294 | } | 333 | } |
| 295 | } else if (mad->mad_hdr.attr_id == CM_REJ_ATTR_ID) { | 334 | } else if (mad->mad_hdr.attr_id == CM_REJ_ATTR_ID || |
| 335 | mad->mad_hdr.attr_id == CM_SIDR_REP_ATTR_ID) { | ||
| 296 | return 0; | 336 | return 0; |
| 297 | } else { | 337 | } else { |
| 338 | sl_cm_id = get_local_comm_id(mad); | ||
| 298 | id = id_map_get(ibdev, &pv_cm_id, slave_id, sl_cm_id); | 339 | id = id_map_get(ibdev, &pv_cm_id, slave_id, sl_cm_id); |
| 299 | } | 340 | } |
| 300 | 341 | ||
| @@ -315,14 +356,18 @@ int mlx4_ib_multiplex_cm_handler(struct ib_device *ibdev, int port, int slave_id · 14 unmodified lines | |||
| 315 | } | 356 | } |
| 316 | 357 | ||
| 317 | int mlx4_ib_demux_cm_handler(struct ib_device *ibdev, int port, int *slave, | 358 | int mlx4_ib_demux_cm_handler(struct ib_device *ibdev, int port, int *slave, |
| 318 | struct ib_mad *mad) | 359 | struct ib_mad *mad) |
| 319 | { | 360 | { |
| 320 | u32 pv_cm_id; | 361 | u32 pv_cm_id; |
| 321 | struct id_map_entry *id; | 362 | struct id_map_entry *id; |
| 322 | 363 | ||
| 323 | if (mad->mad_hdr.attr_id == CM_REQ_ATTR_ID) { | 364 | if (mad->mad_hdr.attr_id == CM_REQ_ATTR_ID || |
| 365 | mad->mad_hdr.attr_id == CM_SIDR_REQ_ATTR_ID) { | ||
| 324 | union ib_gid gid; | 366 | union ib_gid gid; |
| 325 | 367 | ||
| 368 | if (!slave) | ||
| 369 | return 0; | ||
| 370 | |||
| 326 | gid = gid_from_req_msg(ibdev, mad); | 371 | gid = gid_from_req_msg(ibdev, mad); |
| 327 | *slave = mlx4_ib_find_real_gid(ibdev, port, gid.global.interface_id); | 372 | *slave = mlx4_ib_find_real_gid(ibdev, port, gid.global.interface_id); |
| 328 | if (*slave < 0) { | 373 | if (*slave < 0) { |
| @@ -341,7 +386,8 @@ int mlx4_ib_demux_cm_handler(struct ib_device *ibdev, int port, int *slave, · 12 unmodified lines | |||
| 341 | return -ENOENT; | 386 | return -ENOENT; |
| 342 | } | 387 | } |
| 343 | 388 | ||
| 344 | *slave = id->slave_id; | 389 | if (slave) |
| 390 | *slave = id->slave_id; | ||
| 345 | set_remote_comm_id(mad, id->sl_cm_id); | 391 | set_remote_comm_id(mad, id->sl_cm_id); |
| 346 | 392 | ||
| 347 | if (mad->mad_hdr.attr_id == CM_DREQ_ATTR_ID) | 393 | if (mad->mad_hdr.attr_id == CM_DREQ_ATTR_ID) |
| @@ -564,7 +564,7 @@ static int mlx4_ib_ipoib_csum_ok(__be16 status, __be16 checksum) · 563 unmodified lines | |||
| 564 | } | 564 | } |
| 565 | 565 | ||
| 566 | static int use_tunnel_data(struct mlx4_ib_qp *qp, struct mlx4_ib_cq *cq, struct ib_wc *wc, | 566 | static int use_tunnel_data(struct mlx4_ib_qp *qp, struct mlx4_ib_cq *cq, struct ib_wc *wc, |
| 567 | unsigned tail, struct mlx4_cqe *cqe) | 567 | unsigned tail, struct mlx4_cqe *cqe, int is_eth) |
| 568 | { | 568 | { |
| 569 | struct mlx4_ib_proxy_sqp_hdr *hdr; | 569 | struct mlx4_ib_proxy_sqp_hdr *hdr; |
| 570 | 570 | ||
| @@ -574,12 +574,20 @@ static int use_tunnel_data(struct mlx4_ib_qp *qp, struct mlx4_ib_cq *cq, struct · 3 unmodified lines | |||
| 574 | DMA_FROM_DEVICE); | 574 | DMA_FROM_DEVICE); |
| 575 | hdr = (struct mlx4_ib_proxy_sqp_hdr *) (qp->sqp_proxy_rcv[tail].addr); | 575 | hdr = (struct mlx4_ib_proxy_sqp_hdr *) (qp->sqp_proxy_rcv[tail].addr); |
| 576 | wc->pkey_index = be16_to_cpu(hdr->tun.pkey_index); | 576 | wc->pkey_index = be16_to_cpu(hdr->tun.pkey_index); |
| 577 | wc->slid = be16_to_cpu(hdr->tun.slid_mac_47_32); | ||
| 578 | wc->sl = (u8) (be16_to_cpu(hdr->tun.sl_vid) >> 12); | ||
| 579 | wc->src_qp = be32_to_cpu(hdr->tun.flags_src_qp) & 0xFFFFFF; | 577 | wc->src_qp = be32_to_cpu(hdr->tun.flags_src_qp) & 0xFFFFFF; |
| 580 | wc->wc_flags |= (hdr->tun.g_ml_path & 0x80) ? (IB_WC_GRH) : 0; | 578 | wc->wc_flags |= (hdr->tun.g_ml_path & 0x80) ? (IB_WC_GRH) : 0; |
| 581 | wc->dlid_path_bits = 0; | 579 | wc->dlid_path_bits = 0; |
| 582 | 580 | ||
| 581 | if (is_eth) { | ||
| 582 | wc->vlan_id = be16_to_cpu(hdr->tun.sl_vid); | ||
| 583 | memcpy(&(wc->smac[0]), (char *)&hdr->tun.mac_31_0, 4); | ||
| 584 | memcpy(&(wc->smac[4]), (char *)&hdr->tun.slid_mac_47_32, 2); | ||
| 585 | wc->wc_flags |= (IB_WC_WITH_VLAN | IB_WC_WITH_SMAC); | ||
| 586 | } else { | ||
| 587 | wc->slid = be16_to_cpu(hdr->tun.slid_mac_47_32); | ||
| 588 | wc->sl = (u8) (be16_to_cpu(hdr->tun.sl_vid) >> 12); | ||
| 589 | } | ||
| 590 | |||
| 583 | return 0; | 591 | return 0; |
| 584 | } | 592 | } |
| 585 | 593 | ||
| @@ -594,6 +602,7 @@ static int mlx4_ib_poll_one(struct mlx4_ib_cq *cq, · 8 unmodified lines | |||
| 594 | struct mlx4_srq *msrq = NULL; | 602 | struct mlx4_srq *msrq = NULL; |
| 595 | int is_send; | 603 | int is_send; |
| 596 | int is_error; | 604 | int is_error; |
| 605 | int is_eth; | ||
| 597 | u32 g_mlpath_rqpn; | 606 | u32 g_mlpath_rqpn; |
| 598 | u16 wqe_ctr; | 607 | u16 wqe_ctr; |
| 599 | unsigned tail = 0; | 608 | unsigned tail = 0; |
| @@ -778,11 +787,15 @@ repoll: · 178 unmodified lines | |||
| 778 | break; | 787 | break; |
| 779 | } | 788 | } |
| 780 | 789 | ||
| 790 | is_eth = (rdma_port_get_link_layer(wc->qp->device, | ||
| 791 | (*cur_qp)->port) == | ||
| 792 | IB_LINK_LAYER_ETHERNET); | ||
| 781 | if (mlx4_is_mfunc(to_mdev(cq->ibcq.device)->dev)) { | 793 | if (mlx4_is_mfunc(to_mdev(cq->ibcq.device)->dev)) { |
| 782 | if ((*cur_qp)->mlx4_ib_qp_type & | 794 | if ((*cur_qp)->mlx4_ib_qp_type & |
| 783 | (MLX4_IB_QPT_PROXY_SMI_OWNER | | 795 | (MLX4_IB_QPT_PROXY_SMI_OWNER | |
| 784 | MLX4_IB_QPT_PROXY_SMI | MLX4_IB_QPT_PROXY_GSI)) | 796 | MLX4_IB_QPT_PROXY_SMI | MLX4_IB_QPT_PROXY_GSI)) |
| 785 | return use_tunnel_data(*cur_qp, cq, wc, tail, cqe); | 797 | return use_tunnel_data(*cur_qp, cq, wc, tail, |
| 798 | cqe, is_eth); | ||
| 786 | } | 799 | } |
| 787 | 800 | ||
| 788 | wc->slid = be16_to_cpu(cqe->rlid); | 801 | wc->slid = be16_to_cpu(cqe->rlid); |
| @@ -793,20 +806,21 @@ repoll: · 4 unmodified lines | |||
| 793 | wc->pkey_index = be32_to_cpu(cqe->immed_rss_invalid) & 0x7f; | 806 | wc->pkey_index = be32_to_cpu(cqe->immed_rss_invalid) & 0x7f; |
| 794 | wc->wc_flags |= mlx4_ib_ipoib_csum_ok(cqe->status, | 807 | wc->wc_flags |= mlx4_ib_ipoib_csum_ok(cqe->status, |
| 795 | cqe->checksum) ? IB_WC_IP_CSUM_OK : 0; | 808 | cqe->checksum) ? IB_WC_IP_CSUM_OK : 0; |
| 796 | if (rdma_port_get_link_layer(wc->qp->device, | 809 | if (is_eth) { |
| 797 | (*cur_qp)->port) == IB_LINK_LAYER_ETHERNET) | ||
| 798 | wc->sl = be16_to_cpu(cqe->sl_vid) >> 13; | 810 | wc->sl = be16_to_cpu(cqe->sl_vid) >> 13; |
| 799 | else | 811 | if (be32_to_cpu(cqe->vlan_my_qpn) & |
| 800 | wc->sl = be16_to_cpu(cqe->sl_vid) >> 12; | 812 | MLX4_CQE_VLAN_PRESENT_MASK) { |
| 801 | if (be32_to_cpu(cqe->vlan_my_qpn) & MLX4_CQE_VLAN_PRESENT_MASK) { | 813 | wc->vlan_id = be16_to_cpu(cqe->sl_vid) & |
| 802 | wc->vlan_id = be16_to_cpu(cqe->sl_vid) & | 814 | MLX4_CQE_VID_MASK; |
| 803 | MLX4_CQE_VID_MASK; | 815 | } else { |
| 816 | wc->vlan_id = 0xffff; | ||
| 817 | } | ||
| 818 | memcpy(wc->smac, cqe->smac, ETH_ALEN); | ||
| 819 | wc->wc_flags |= (IB_WC_WITH_VLAN | IB_WC_WITH_SMAC); | ||
| 804 | } else { | 820 | } else { |
| 821 | wc->sl = be16_to_cpu(cqe->sl_vid) >> 12; | ||
| 805 | wc->vlan_id = 0xffff; | 822 | wc->vlan_id = 0xffff; |
| 806 | } | 823 | } |
| 807 | wc->wc_flags |= IB_WC_WITH_VLAN; | ||
| 808 | memcpy(wc->smac, cqe->smac, ETH_ALEN); | ||
| 809 | wc->wc_flags |= IB_WC_WITH_SMAC; | ||
| 810 | } | 824 | } |
| 811 | 825 | ||
| 812 | return 0; | 826 | return 0; |
| @@ -467,6 +467,7 @@ int mlx4_ib_send_to_slave(struct mlx4_ib_dev *dev, int slave, u8 port, · 466 unmodified lines | |||
| 467 | int ret = 0; | 467 | int ret = 0; |
| 468 | u16 tun_pkey_ix; | 468 | u16 tun_pkey_ix; |
| 469 | u16 cached_pkey; | 469 | u16 cached_pkey; |
| 470 | u8 is_eth = dev->dev->caps.port_type[port] == MLX4_PORT_TYPE_ETH; | ||
| 470 | 471 | ||
| 471 | if (dest_qpt > IB_QPT_GSI) | 472 | if (dest_qpt > IB_QPT_GSI) |
| 472 | return -EINVAL; | 473 | return -EINVAL; |
| @@ -509,6 +510,10 @@ int mlx4_ib_send_to_slave(struct mlx4_ib_dev *dev, int slave, u8 port, · 36 unmodified lines | |||
| 509 | * The driver will set the force loopback bit in post_send */ | 510 | * The driver will set the force loopback bit in post_send */ |
| 510 | memset(&attr, 0, sizeof attr); | 511 | memset(&attr, 0, sizeof attr); |
| 511 | attr.port_num = port; | 512 | attr.port_num = port; |
| 513 | if (is_eth) { | ||
| 514 | memcpy(&attr.grh.dgid.raw[0], &grh->dgid.raw[0], 16); | ||
| 515 | attr.ah_flags = IB_AH_GRH; | ||
| 516 | } | ||
| 512 | ah = ib_create_ah(tun_ctx->pd, &attr); | 517 | ah = ib_create_ah(tun_ctx->pd, &attr); |
| 513 | if (IS_ERR(ah)) | 518 | if (IS_ERR(ah)) |
| 514 | return -ENOMEM; | 519 | return -ENOMEM; |
| @@ -540,11 +545,36 @@ int mlx4_ib_send_to_slave(struct mlx4_ib_dev *dev, int slave, u8 port, · 25 unmodified lines | |||
| 540 | 545 | ||
| 541 | /* adjust tunnel data */ | 546 | /* adjust tunnel data */ |
| 542 | tun_mad->hdr.pkey_index = cpu_to_be16(tun_pkey_ix); | 547 | tun_mad->hdr.pkey_index = cpu_to_be16(tun_pkey_ix); |
| 543 | tun_mad->hdr.sl_vid = cpu_to_be16(((u16)(wc->sl)) << 12); | ||
| 544 | tun_mad->hdr.slid_mac_47_32 = cpu_to_be16(wc->slid); | ||
| 545 | tun_mad->hdr.flags_src_qp = cpu_to_be32(wc->src_qp & 0xFFFFFF); | 548 | tun_mad->hdr.flags_src_qp = cpu_to_be32(wc->src_qp & 0xFFFFFF); |
| 546 | tun_mad->hdr.g_ml_path = (grh && (wc->wc_flags & IB_WC_GRH)) ? 0x80 : 0; | 549 | tun_mad->hdr.g_ml_path = (grh && (wc->wc_flags & IB_WC_GRH)) ? 0x80 : 0; |
| 547 | 550 | ||
| 551 | if (is_eth) { | ||
| 552 | u16 vlan = 0; | ||
| 553 | if (mlx4_get_slave_default_vlan(dev->dev, port, slave, &vlan, | ||
| 554 | NULL)) { | ||
| 555 | /* VST mode */ | ||
| 556 | if (vlan != wc->vlan_id) | ||
| 557 | /* Packet vlan is not the VST-assigned vlan. | ||
| 558 | * Drop the packet. | ||
| 559 | */ | ||
| 560 | goto out; | ||
| 561 | else | ||
| 562 | /* Remove the vlan tag before forwarding | ||
| 563 | * the packet to the VF. | ||
| 564 | */ | ||
| 565 | vlan = 0xffff; | ||
| 566 | } else { | ||
| 567 | vlan = wc->vlan_id; | ||
| 568 | } | ||
| 569 | |||
| 570 | tun_mad->hdr.sl_vid = cpu_to_be16(vlan); | ||
| 571 | memcpy((char *)&tun_mad->hdr.mac_31_0, &(wc->smac[0]), 4); | ||
| 572 | memcpy((char *)&tun_mad->hdr.slid_mac_47_32, &(wc->smac[4]), 2); | ||
| 573 | } else { | ||
| 574 | tun_mad->hdr.sl_vid = cpu_to_be16(((u16)(wc->sl)) << 12); | ||
| 575 | tun_mad->hdr.slid_mac_47_32 = cpu_to_be16(wc->slid); | ||
| 576 | } | ||
| 577 | |||
| 548 | ib_dma_sync_single_for_device(&dev->ib_dev, | 578 | ib_dma_sync_single_for_device(&dev->ib_dev, |
| 549 | tun_qp->tx_ring[tun_tx_ix].buf.map, | 579 | tun_qp->tx_ring[tun_tx_ix].buf.map, |
| 550 | sizeof (struct mlx4_rcv_tunnel_mad), | 580 | sizeof (struct mlx4_rcv_tunnel_mad), |
| @@ -580,6 +610,41 @@ static int mlx4_ib_demux_mad(struct ib_device *ibdev, u8 port, · 29 unmodified lines | |||
| 580 | int err; | 610 | int err; |
| 581 | int slave; | 611 | int slave; |
| 582 | u8 *slave_id; | 612 | u8 *slave_id; |
| 613 | int is_eth = 0; | ||
| 614 | |||
| 615 | if (rdma_port_get_link_layer(ibdev, port) == IB_LINK_LAYER_INFINIBAND) | ||
| 616 | is_eth = 0; | ||
| 617 | else | ||
| 618 | is_eth = 1; | ||
| 619 | |||
| 620 | if (is_eth) { | ||
| 621 | if (!(wc->wc_flags & IB_WC_GRH)) { | ||
| 622 | mlx4_ib_warn(ibdev, "RoCE grh not present.\n"); | ||
| 623 | return -EINVAL; | ||
| 624 | } | ||
| 625 | if (mad->mad_hdr.mgmt_class != IB_MGMT_CLASS_CM) { | ||
| 626 | mlx4_ib_warn(ibdev, "RoCE mgmt class is not CM\n"); | ||
| 627 | return -EINVAL; | ||
| 628 | } | ||
| 629 | if (mlx4_get_slave_from_roce_gid(dev->dev, port, grh->dgid.raw, &slave)) { | ||
| 630 | mlx4_ib_warn(ibdev, "failed matching grh\n"); | ||
| 631 | return -ENOENT; | ||
| 632 | } | ||
| 633 | if (slave >= dev->dev->caps.sqp_demux) { | ||
| 634 | mlx4_ib_warn(ibdev, "slave id: %d is bigger than allowed:%d\n", | ||
| 635 | slave, dev->dev->caps.sqp_demux); | ||
| 636 | return -ENOENT; | ||
| 637 | } | ||
| 638 | |||
| 639 | if (mlx4_ib_demux_cm_handler(ibdev, port, NULL, mad)) | ||
| 640 | return 0; | ||
| 641 | |||
| 642 | err = mlx4_ib_send_to_slave(dev, slave, port, wc->qp->qp_type, wc, grh, mad); | ||
| 643 | if (err) | ||
| 644 | pr_debug("failed sending to slave %d via tunnel qp (%d)\n", | ||
| 645 | slave, err); | ||
| 646 | return 0; | ||
| 647 | } | ||
| 583 | 648 | ||
| 584 | /* Initially assume that this mad is for us */ | 649 | /* Initially assume that this mad is for us */ |
| 585 | slave = mlx4_master_func_num(dev->dev); | 650 | slave = mlx4_master_func_num(dev->dev); |
| @@ -1076,8 +1141,9 @@ static int is_proxy_qp0(struct mlx4_ib_dev *dev, int qpn, int slave) · 490 unmodified lines | |||
| 1076 | 1141 | ||
| 1077 | 1142 | ||
| 1078 | int mlx4_ib_send_to_wire(struct mlx4_ib_dev *dev, int slave, u8 port, | 1143 | int mlx4_ib_send_to_wire(struct mlx4_ib_dev *dev, int slave, u8 port, |
| 1079 | enum ib_qp_type dest_qpt, u16 pkey_index, u32 remote_qpn, | 1144 | enum ib_qp_type dest_qpt, u16 pkey_index, |
| 1080 | u32 qkey, struct ib_ah_attr *attr, struct ib_mad *mad) | 1145 | u32 remote_qpn, u32 qkey, struct ib_ah_attr *attr, |
| 1146 | u8 *s_mac, struct ib_mad *mad) | ||
| 1081 | { | 1147 | { |
| 1082 | struct ib_sge list; | 1148 | struct ib_sge list; |
| 1083 | struct ib_send_wr wr, *bad_wr; | 1149 | struct ib_send_wr wr, *bad_wr; |
| @@ -1166,6 +1232,9 @@ int mlx4_ib_send_to_wire(struct mlx4_ib_dev *dev, int slave, u8 port, · 82 unmodified lines | |||
| 1166 | wr.num_sge = 1; | 1232 | wr.num_sge = 1; |
| 1167 | wr.opcode = IB_WR_SEND; | 1233 | wr.opcode = IB_WR_SEND; |
| 1168 | wr.send_flags = IB_SEND_SIGNALED; | 1234 | wr.send_flags = IB_SEND_SIGNALED; |
| 1235 | if (s_mac) | ||
| 1236 | memcpy(to_mah(ah)->av.eth.s_mac, s_mac, 6); | ||
| 1237 | |||
| 1169 | 1238 | ||
| 1170 | ret = ib_post_send(send_qp, &wr, &bad_wr); | 1239 | ret = ib_post_send(send_qp, &wr, &bad_wr); |
| 1171 | out: | 1240 | out: |
| @@ -1174,6 +1243,22 @@ out: · 2 unmodified lines | |||
| 1174 | return ret; | 1243 | return ret; |
| 1175 | } | 1244 | } |
| 1176 | 1245 | ||
| 1246 | static int get_slave_base_gid_ix(struct mlx4_ib_dev *dev, int slave, int port) | ||
| 1247 | { | ||
| 1248 | if (rdma_port_get_link_layer(&dev->ib_dev, port) == IB_LINK_LAYER_INFINIBAND) | ||
| 1249 | return slave; | ||
| 1250 | return mlx4_get_base_gid_ix(dev->dev, slave, port); | ||
| 1251 | } | ||
| 1252 | |||
| 1253 | static void fill_in_real_sgid_index(struct mlx4_ib_dev *dev, int slave, int port, | ||
| 1254 | struct ib_ah_attr *ah_attr) | ||
| 1255 | { | ||
| 1256 | if (rdma_port_get_link_layer(&dev->ib_dev, port) == IB_LINK_LAYER_INFINIBAND) | ||
| 1257 | ah_attr->grh.sgid_index = slave; | ||
| 1258 | else | ||
| 1259 | ah_attr->grh.sgid_index += get_slave_base_gid_ix(dev, slave, port); | ||
| 1260 | } | ||
| 1261 | |||
| 1177 | static void mlx4_ib_multiplex_mad(struct mlx4_ib_demux_pv_ctx *ctx, struct ib_wc *wc) | 1262 | static void mlx4_ib_multiplex_mad(struct mlx4_ib_demux_pv_ctx *ctx, struct ib_wc *wc) |
| 1178 | { | 1263 | { |
| 1179 | struct mlx4_ib_dev *dev = to_mdev(ctx->ib_dev); | 1264 | struct mlx4_ib_dev *dev = to_mdev(ctx->ib_dev); |
| @@ -1184,6 +1269,7 @@ static void mlx4_ib_multiplex_mad(struct mlx4_ib_demux_pv_ctx *ctx, struct ib_wc · 4 unmodified lines | |||
| 1184 | struct ib_ah_attr ah_attr; | 1269 | struct ib_ah_attr ah_attr; |
| 1185 | u8 *slave_id; | 1270 | u8 *slave_id; |
| 1186 | int slave; | 1271 | int slave; |
| 1272 | int port; | ||
| 1187 | 1273 | ||
| 1188 | /* Get slave that sent this packet */ | 1274 | /* Get slave that sent this packet */ |
| 1189 | if (wc->src_qp < dev->dev->phys_caps.base_proxy_sqpn || | 1275 | if (wc->src_qp < dev->dev->phys_caps.base_proxy_sqpn || |
| @@ -1260,12 +1346,18 @@ static void mlx4_ib_multiplex_mad(struct mlx4_ib_demux_pv_ctx *ctx, struct ib_wc · 70 unmodified lines | |||
| 1260 | memcpy(&ah.av, &tunnel->hdr.av, sizeof (struct mlx4_av)); | 1346 | memcpy(&ah.av, &tunnel->hdr.av, sizeof (struct mlx4_av)); |
| 1261 | ah.ibah.device = ctx->ib_dev; | 1347 | ah.ibah.device = ctx->ib_dev; |
| 1262 | mlx4_ib_query_ah(&ah.ibah, &ah_attr); | 1348 | mlx4_ib_query_ah(&ah.ibah, &ah_attr); |
| 1263 | if ((ah_attr.ah_flags & IB_AH_GRH) && | 1349 | if (ah_attr.ah_flags & IB_AH_GRH) |
| 1264 | (ah_attr.grh.sgid_index != slave)) { | 1350 | fill_in_real_sgid_index(dev, slave, ctx->port, &ah_attr); |
| 1265 | mlx4_ib_warn(ctx->ib_dev, "slave:%d accessed invalid sgid_index:%d\n", | 1351 | |
| 1266 | slave, ah_attr.grh.sgid_index); | 1352 | port = mlx4_slave_convert_port(dev->dev, slave, ah_attr.port_num); |
| 1353 | if (port < 0) | ||
| 1267 | return; | 1354 | return; |
| 1268 | } | 1355 | ah_attr.port_num = port; |
| 1356 | memcpy(ah_attr.dmac, tunnel->hdr.mac, 6); | ||
| 1357 | ah_attr.vlan_id = be16_to_cpu(tunnel->hdr.vlan); | ||
| 1358 | /* if slave have default vlan use it */ | ||
| 1359 | mlx4_get_slave_default_vlan(dev->dev, ctx->port, slave, | ||
| 1360 | &ah_attr.vlan_id, &ah_attr.sl); | ||
| 1269 | 1361 | ||
| 1270 | mlx4_ib_send_to_wire(dev, slave, ctx->port, | 1362 | mlx4_ib_send_to_wire(dev, slave, ctx->port, |
| 1271 | is_proxy_qp0(dev, wc->src_qp, slave) ? | 1363 | is_proxy_qp0(dev, wc->src_qp, slave) ? |
| @@ -1273,7 +1365,7 @@ static void mlx4_ib_multiplex_mad(struct mlx4_ib_demux_pv_ctx *ctx, struct ib_wc · 1 unmodified line | |||
| 1273 | be16_to_cpu(tunnel->hdr.pkey_index), | 1365 | be16_to_cpu(tunnel->hdr.pkey_index), |
| 1274 | be32_to_cpu(tunnel->hdr.remote_qpn), | 1366 | be32_to_cpu(tunnel->hdr.remote_qpn), |
| 1275 | be32_to_cpu(tunnel->hdr.qkey), | 1367 | be32_to_cpu(tunnel->hdr.qkey), |
| 1276 | &ah_attr, &tunnel->mad); | 1368 | &ah_attr, wc->smac, &tunnel->mad); |
| 1277 | } | 1369 | } |
| 1278 | 1370 | ||
| 1279 | static int mlx4_ib_alloc_pv_bufs(struct mlx4_ib_demux_pv_ctx *ctx, | 1371 | static int mlx4_ib_alloc_pv_bufs(struct mlx4_ib_demux_pv_ctx *ctx, |
| @@ -1850,7 +1942,15 @@ static int mlx4_ib_alloc_demux_ctx(struct mlx4_ib_dev *dev, · 570 unmodified lines | |||
| 1850 | ctx->port = port; | 1942 | ctx->port = port; |
| 1851 | ctx->ib_dev = &dev->ib_dev; | 1943 | ctx->ib_dev = &dev->ib_dev; |
| 1852 | 1944 | ||
| 1853 | for (i = 0; i < dev->dev->caps.sqp_demux; i++) { | 1945 | for (i = 0; |
| 1946 | i < min(dev->dev->caps.sqp_demux, (u16)(dev->dev->num_vfs + 1)); | ||
| 1947 | i++) { | ||
| 1948 | struct mlx4_active_ports actv_ports = | ||
| 1949 | mlx4_get_active_ports(dev->dev, i); | ||
| 1950 | |||
| 1951 | if (!test_bit(port - 1, actv_ports.ports)) | ||
| 1952 | continue; | ||
| 1953 | |||
| 1854 | ret = alloc_pv_object(dev, i, port, &ctx->tun[i]); | 1954 | ret = alloc_pv_object(dev, i, port, &ctx->tun[i]); |
| 1855 | if (ret) { | 1955 | if (ret) { |
| 1856 | ret = -ENOMEM; | 1956 | ret = -ENOMEM; |
| @@ -1546,7 +1546,7 @@ static int mlx4_ib_addr_event(int event, struct net_device *event_netdev, · 1545 unmodified lines | |||
| 1546 | iboe = &ibdev->iboe; | 1546 | iboe = &ibdev->iboe; |
| 1547 | spin_lock(&iboe->lock); | 1547 | spin_lock(&iboe->lock); |
| 1548 | 1548 | ||
| 1549 | for (port = 1; port <= MLX4_MAX_PORTS; ++port) | 1549 | for (port = 1; port <= ibdev->dev->caps.num_ports; ++port) |
| 1550 | if ((netif_is_bond_master(real_dev) && | 1550 | if ((netif_is_bond_master(real_dev) && |
| 1551 | (real_dev == iboe->masters[port - 1])) || | 1551 | (real_dev == iboe->masters[port - 1])) || |
| 1552 | (!netif_is_bond_master(real_dev) && | 1552 | (!netif_is_bond_master(real_dev) && |
| @@ -1569,14 +1569,14 @@ static u8 mlx4_ib_get_dev_port(struct net_device *dev, · 16 unmodified lines | |||
| 1569 | 1569 | ||
| 1570 | iboe = &ibdev->iboe; | 1570 | iboe = &ibdev->iboe; |
| 1571 | 1571 | ||
| 1572 | for (port = 1; port <= MLX4_MAX_PORTS; ++port) | 1572 | for (port = 1; port <= ibdev->dev->caps.num_ports; ++port) |
| 1573 | if ((netif_is_bond_master(real_dev) && | 1573 | if ((netif_is_bond_master(real_dev) && |
| 1574 | (real_dev == iboe->masters[port - 1])) || | 1574 | (real_dev == iboe->masters[port - 1])) || |
| 1575 | (!netif_is_bond_master(real_dev) && | 1575 | (!netif_is_bond_master(real_dev) && |
| 1576 | (real_dev == iboe->netdevs[port - 1]))) | 1576 | (real_dev == iboe->netdevs[port - 1]))) |
| 1577 | break; | 1577 | break; |
| 1578 | 1578 | ||
| 1579 | if ((port == 0) || (port > MLX4_MAX_PORTS)) | 1579 | if ((port == 0) || (port > ibdev->dev->caps.num_ports)) |
| 1580 | return 0; | 1580 | return 0; |
| 1581 | else | 1581 | else |
| 1582 | return port; | 1582 | return port; |
| @@ -1626,7 +1626,7 @@ static void mlx4_ib_get_dev_addr(struct net_device *dev, · 43 unmodified lines | |||
| 1626 | union ib_gid gid; | 1626 | union ib_gid gid; |
| 1627 | 1627 | ||
| 1628 | 1628 | ||
| 1629 | if ((port == 0) || (port > MLX4_MAX_PORTS)) | 1629 | if ((port == 0) || (port > ibdev->dev->caps.num_ports)) |
| 1630 | return; | 1630 | return; |
| 1631 | 1631 | ||
| 1632 | /* IPv4 gids */ | 1632 | /* IPv4 gids */ |
| @@ -1888,14 +1888,6 @@ static void *mlx4_ib_add(struct mlx4_dev *dev) · 255 unmodified lines | |||
| 1888 | 1888 | ||
| 1889 | pr_info_once("%s", mlx4_ib_version); | 1889 | pr_info_once("%s", mlx4_ib_version); |
| 1890 | 1890 | ||
| 1891 | mlx4_foreach_non_ib_transport_port(i, dev) | ||
| 1892 | num_ports++; | ||
| 1893 | |||
| 1894 | if (mlx4_is_mfunc(dev) && num_ports) { | ||
| 1895 | dev_err(&dev->pdev->dev, "RoCE is not supported over SRIOV as yet\n"); | ||
| 1896 | return NULL; | ||
| 1897 | } | ||
| 1898 | |||
| 1899 | num_ports = 0; | 1891 | num_ports = 0; |
| 1900 | mlx4_foreach_ib_transport_port(i, dev) | 1892 | mlx4_foreach_ib_transport_port(i, dev) |
| 1901 | num_ports++; | 1893 | num_ports++; |
| @@ -2331,17 +2323,24 @@ static void do_slave_init(struct mlx4_ib_dev *ibdev, int slave, int do_init) · 429 unmodified lines | |||
| 2331 | struct mlx4_dev *dev = ibdev->dev; | 2323 | struct mlx4_dev *dev = ibdev->dev; |
| 2332 | int i; | 2324 | int i; |
| 2333 | unsigned long flags; | 2325 | unsigned long flags; |
| 2326 | struct mlx4_active_ports actv_ports; | ||
| 2327 | unsigned int ports; | ||
| 2328 | unsigned int first_port; | ||
| 2334 | 2329 | ||
| 2335 | if (!mlx4_is_master(dev)) | 2330 | if (!mlx4_is_master(dev)) |
| 2336 | return; | 2331 | return; |
| 2337 | 2332 | ||
| 2338 | dm = kcalloc(dev->caps.num_ports, sizeof *dm, GFP_ATOMIC); | 2333 | actv_ports = mlx4_get_active_ports(dev, slave); |
| 2334 | ports = bitmap_weight(actv_ports.ports, dev->caps.num_ports); | ||
| 2335 | first_port = find_first_bit(actv_ports.ports, dev->caps.num_ports); | ||
| 2336 | |||
| 2337 | dm = kcalloc(ports, sizeof(*dm), GFP_ATOMIC); | ||
| 2339 | if (!dm) { | 2338 | if (!dm) { |
| 2340 | pr_err("failed to allocate memory for tunneling qp update\n"); | 2339 | pr_err("failed to allocate memory for tunneling qp update\n"); |
| 2341 | goto out; | 2340 | goto out; |
| 2342 | } | 2341 | } |
| 2343 | 2342 | ||
| 2344 | for (i = 0; i < dev->caps.num_ports; i++) { | 2343 | for (i = 0; i < ports; i++) { |
| 2345 | dm[i] = kmalloc(sizeof (struct mlx4_ib_demux_work), GFP_ATOMIC); | 2344 | dm[i] = kmalloc(sizeof (struct mlx4_ib_demux_work), GFP_ATOMIC); |
| 2346 | if (!dm[i]) { | 2345 | if (!dm[i]) { |
| 2347 | pr_err("failed to allocate memory for tunneling qp update work struct\n"); | 2346 | pr_err("failed to allocate memory for tunneling qp update work struct\n"); |
| @@ -2353,9 +2352,9 @@ static void do_slave_init(struct mlx4_ib_dev *ibdev, int slave, int do_init) · 5 unmodified lines | |||
| 2353 | } | 2352 | } |
| 2354 | } | 2353 | } |
| 2355 | /* initialize or tear down tunnel QPs for the slave */ | 2354 | /* initialize or tear down tunnel QPs for the slave */ |
| 2356 | for (i = 0; i < dev->caps.num_ports; i++) { | 2355 | for (i = 0; i < ports; i++) { |
| 2357 | INIT_WORK(&dm[i]->work, mlx4_ib_tunnels_update_work); | 2356 | INIT_WORK(&dm[i]->work, mlx4_ib_tunnels_update_work); |
| 2358 | dm[i]->port = i + 1; | 2357 | dm[i]->port = first_port + i + 1; |
| 2359 | dm[i]->slave = slave; | 2358 | dm[i]->slave = slave; |
| 2360 | dm[i]->do_init = do_init; | 2359 | dm[i]->do_init = do_init; |
| 2361 | dm[i]->dev = ibdev; | 2360 | dm[i]->dev = ibdev; |
| @@ -215,8 +215,9 @@ static int send_mad_to_wire(struct mlx4_ib_demux_ctx *ctx, struct ib_mad *mad) · 214 unmodified lines | |||
| 215 | } | 215 | } |
| 216 | mlx4_ib_query_ah(dev->sm_ah[ctx->port - 1], &ah_attr); | 216 | mlx4_ib_query_ah(dev->sm_ah[ctx->port - 1], &ah_attr); |
| 217 | spin_unlock(&dev->sm_lock); | 217 | spin_unlock(&dev->sm_lock); |
| 218 | return mlx4_ib_send_to_wire(dev, mlx4_master_func_num(dev->dev), ctx->port, | 218 | return mlx4_ib_send_to_wire(dev, mlx4_master_func_num(dev->dev), |
| 219 | IB_QPT_GSI, 0, 1, IB_QP1_QKEY, &ah_attr, mad); | 219 | ctx->port, IB_QPT_GSI, 0, 1, IB_QP1_QKEY, |
| 220 | &ah_attr, NULL, mad); | ||
| 220 | } | 221 | } |
| 221 | 222 | ||
| 222 | static int send_mad_to_slave(int slave, struct mlx4_ib_demux_ctx *ctx, | 223 | static int send_mad_to_slave(int slave, struct mlx4_ib_demux_ctx *ctx, |
| @@ -241,6 +241,22 @@ struct mlx4_ib_proxy_sqp_hdr { · 240 unmodified lines | |||
| 241 | struct mlx4_rcv_tunnel_hdr tun; | 241 | struct mlx4_rcv_tunnel_hdr tun; |
| 242 | } __packed; | 242 | } __packed; |
| 243 | 243 | ||
| 244 | struct mlx4_roce_smac_vlan_info { | ||
| 245 | u64 smac; | ||
| 246 | int smac_index; | ||
| 247 | int smac_port; | ||
| 248 | u64 candidate_smac; | ||
| 249 | int candidate_smac_index; | ||
| 250 | int candidate_smac_port; | ||
| 251 | u16 vid; | ||
| 252 | int vlan_index; | ||
| 253 | int vlan_port; | ||
| 254 | u16 candidate_vid; | ||
| 255 | int candidate_vlan_index; | ||
| 256 | int candidate_vlan_port; | ||
| 257 | int update_vid; | ||
| 258 | }; | ||
| 259 | |||
| 244 | struct mlx4_ib_qp { | 260 | struct mlx4_ib_qp { |
| 245 | struct ib_qp ibqp; | 261 | struct ib_qp ibqp; |
| 246 | struct mlx4_qp mqp; | 262 | struct mlx4_qp mqp; |
| @@ -273,8 +289,9 @@ struct mlx4_ib_qp { · 26 unmodified lines | |||
| 273 | struct list_head gid_list; | 289 | struct list_head gid_list; |
| 274 | struct list_head steering_rules; | 290 | struct list_head steering_rules; |
| 275 | struct mlx4_ib_buf *sqp_proxy_rcv; | 291 | struct mlx4_ib_buf *sqp_proxy_rcv; |
| 292 | struct mlx4_roce_smac_vlan_info pri; | ||
| 293 | struct mlx4_roce_smac_vlan_info alt; | ||
| 276 | u64 reg_id; | 294 | u64 reg_id; |
| 277 | |||
| 278 | }; | 295 | }; |
| 279 | 296 | ||
| 280 | struct mlx4_ib_srq { | 297 | struct mlx4_ib_srq { |
| @@ -720,9 +737,12 @@ void mlx4_ib_tunnels_update_work(struct work_struct *work); · 439 unmodified lines | |||
| 720 | int mlx4_ib_send_to_slave(struct mlx4_ib_dev *dev, int slave, u8 port, | 737 | int mlx4_ib_send_to_slave(struct mlx4_ib_dev *dev, int slave, u8 port, |
| 721 | enum ib_qp_type qpt, struct ib_wc *wc, | 738 | enum ib_qp_type qpt, struct ib_wc *wc, |
| 722 | struct ib_grh *grh, struct ib_mad *mad); | 739 | struct ib_grh *grh, struct ib_mad *mad); |
| 740 | |||
| 723 | int mlx4_ib_send_to_wire(struct mlx4_ib_dev *dev, int slave, u8 port, | 741 | int mlx4_ib_send_to_wire(struct mlx4_ib_dev *dev, int slave, u8 port, |
| 724 | enum ib_qp_type dest_qpt, u16 pkey_index, u32 remote_qpn, | 742 | enum ib_qp_type dest_qpt, u16 pkey_index, u32 remote_qpn, |
| 725 | u32 qkey, struct ib_ah_attr *attr, struct ib_mad *mad); | 743 | u32 qkey, struct ib_ah_attr *attr, u8 *s_mac, |
| 744 | struct ib_mad *mad); | ||
| 745 | |||
| 726 | __be64 mlx4_ib_get_new_demux_tid(struct mlx4_ib_demux_ctx *ctx); | 746 | __be64 mlx4_ib_get_new_demux_tid(struct mlx4_ib_demux_ctx *ctx); |
| 727 | 747 | ||
| 728 | int mlx4_ib_demux_cm_handler(struct ib_device *ibdev, int port, int *slave, | 748 | int mlx4_ib_demux_cm_handler(struct ib_device *ibdev, int port, int *slave, |
| @@ -662,10 +662,14 @@ static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd, · 661 unmodified lines | |||
| 662 | if (!sqp) | 662 | if (!sqp) |
| 663 | return -ENOMEM; | 663 | return -ENOMEM; |
| 664 | qp = &sqp->qp; | 664 | qp = &sqp->qp; |
| 665 | qp->pri.vid = 0xFFFF; | ||
| 666 | qp->alt.vid = 0xFFFF; | ||
| 665 | } else { | 667 | } else { |
| 666 | qp = kzalloc(sizeof (struct mlx4_ib_qp), GFP_KERNEL); | 668 | qp = kzalloc(sizeof (struct mlx4_ib_qp), GFP_KERNEL); |
| 667 | if (!qp) | 669 | if (!qp) |
| 668 | return -ENOMEM; | 670 | return -ENOMEM; |
| 671 | qp->pri.vid = 0xFFFF; | ||
| 672 | qp->alt.vid = 0xFFFF; | ||
| 669 | } | 673 | } |
| 670 | } else | 674 | } else |
| 671 | qp = *caller_qp; | 675 | qp = *caller_qp; |
| @@ -940,11 +944,32 @@ static void destroy_qp_common(struct mlx4_ib_dev *dev, struct mlx4_ib_qp *qp, · 268 unmodified lines | |||
| 940 | { | 944 | { |
| 941 | struct mlx4_ib_cq *send_cq, *recv_cq; | 945 | struct mlx4_ib_cq *send_cq, *recv_cq; |
| 942 | 946 | ||
| 943 | if (qp->state != IB_QPS_RESET) | 947 | if (qp->state != IB_QPS_RESET) { |
| 944 | if (mlx4_qp_modify(dev->dev, NULL, to_mlx4_state(qp->state), | 948 | if (mlx4_qp_modify(dev->dev, NULL, to_mlx4_state(qp->state), |
| 945 | MLX4_QP_STATE_RST, NULL, 0, 0, &qp->mqp)) | 949 | MLX4_QP_STATE_RST, NULL, 0, 0, &qp->mqp)) |
| 946 | pr_warn("modify QP %06x to RESET failed.\n", | 950 | pr_warn("modify QP %06x to RESET failed.\n", |
| 947 | qp->mqp.qpn); | 951 | qp->mqp.qpn); |
| 952 | if (qp->pri.smac) { | ||
| 953 | mlx4_unregister_mac(dev->dev, qp->pri.smac_port, qp->pri.smac); | ||
| 954 | qp->pri.smac = 0; | ||
| 955 | } | ||
| 956 | if (qp->alt.smac) { | ||
| 957 | mlx4_unregister_mac(dev->dev, qp->alt.smac_port, qp->alt.smac); | ||
| 958 | qp->alt.smac = 0; | ||
| 959 | } | ||
| 960 | if (qp->pri.vid < 0x1000) { | ||
| 961 | mlx4_unregister_vlan(dev->dev, qp->pri.vlan_port, qp->pri.vid); | ||
| 962 | qp->pri.vid = 0xFFFF; | ||
| 963 | qp->pri.candidate_vid = 0xFFFF; | ||
| 964 | qp->pri.update_vid = 0; | ||
| 965 | } | ||
| 966 | if (qp->alt.vid < 0x1000) { | ||
| 967 | mlx4_unregister_vlan(dev->dev, qp->alt.vlan_port, qp->alt.vid); | ||
| 968 | qp->alt.vid = 0xFFFF; | ||
| 969 | qp->alt.candidate_vid = 0xFFFF; | ||
| 970 | qp->alt.update_vid = 0; | ||
| 971 | } | ||
| 972 | } | ||
| 948 | 973 | ||
| 949 | get_cqs(qp, &send_cq, &recv_cq); | 974 | get_cqs(qp, &send_cq, &recv_cq); |
| 950 | 975 | ||
| @@ -1057,6 +1082,8 @@ struct ib_qp *mlx4_ib_create_qp(struct ib_pd *pd, · 106 unmodified lines | |||
| 1057 | qp = kzalloc(sizeof *qp, GFP_KERNEL); | 1082 | qp = kzalloc(sizeof *qp, GFP_KERNEL); |
| 1058 | if (!qp) | 1083 | if (!qp) |
| 1059 | return ERR_PTR(-ENOMEM); | 1084 | return ERR_PTR(-ENOMEM); |
| 1085 | qp->pri.vid = 0xFFFF; | ||
| 1086 | qp->alt.vid = 0xFFFF; | ||
| 1060 | /* fall through */ | 1087 | /* fall through */ |
| 1061 | case IB_QPT_UD: | 1088 | case IB_QPT_UD: |
| 1062 | { | 1089 | { |
| @@ -1188,12 +1215,13 @@ static void mlx4_set_sched(struct mlx4_qp_path *path, u8 port) · 125 unmodified lines | |||
| 1188 | 1215 | ||
| 1189 | static int _mlx4_set_path(struct mlx4_ib_dev *dev, const struct ib_ah_attr *ah, | 1216 | static int _mlx4_set_path(struct mlx4_ib_dev *dev, const struct ib_ah_attr *ah, |
| 1190 | u64 smac, u16 vlan_tag, struct mlx4_qp_path *path, | 1217 | u64 smac, u16 vlan_tag, struct mlx4_qp_path *path, |
| 1191 | u8 port) | 1218 | struct mlx4_roce_smac_vlan_info *smac_info, u8 port) |
| 1192 | { | 1219 | { |
| 1193 | int is_eth = rdma_port_get_link_layer(&dev->ib_dev, port) == | 1220 | int is_eth = rdma_port_get_link_layer(&dev->ib_dev, port) == |
| 1194 | IB_LINK_LAYER_ETHERNET; | 1221 | IB_LINK_LAYER_ETHERNET; |
| 1195 | int vidx; | 1222 | int vidx; |
| 1196 | int smac_index; | 1223 | int smac_index; |
| 1224 | int err; | ||
| 1197 | 1225 | ||
| 1198 | 1226 | ||
| 1199 | path->grh_mylmc = ah->src_path_bits & 0x7f; | 1227 | path->grh_mylmc = ah->src_path_bits & 0x7f; |
| @@ -1223,61 +1251,103 @@ static int _mlx4_set_path(struct mlx4_ib_dev *dev, const struct ib_ah_attr *ah, · 23 unmodified lines | |||
| 1223 | } | 1251 | } |
| 1224 | 1252 | ||
| 1225 | if (is_eth) { | 1253 | if (is_eth) { |
| 1226 | path->sched_queue = MLX4_IB_DEFAULT_SCHED_QUEUE | | ||
| 1227 | ((port - 1) << 6) | ((ah->sl & 7) << 3); | ||
| 1228 | |||
| 1229 | if (!(ah->ah_flags & IB_AH_GRH)) | 1254 | if (!(ah->ah_flags & IB_AH_GRH)) |
| 1230 | return -1; | 1255 | return -1; |
| 1231 | 1256 | ||
| 1232 | memcpy(path->dmac, ah->dmac, ETH_ALEN); | 1257 | path->sched_queue = MLX4_IB_DEFAULT_SCHED_QUEUE | |
| 1233 | path->ackto = MLX4_IB_LINK_TYPE_ETH; | 1258 | ((port - 1) << 6) | ((ah->sl & 7) << 3); |
| 1234 | /* find the index into MAC table for IBoE */ | ||
| 1235 | if (!is_zero_ether_addr((const u8 *)&smac)) { | ||
| 1236 | if (mlx4_find_cached_mac(dev->dev, port, smac, | ||
| 1237 | &smac_index)) | ||
| 1238 | return -ENOENT; | ||
| 1239 | } else { | ||
| 1240 | smac_index = 0; | ||
| 1241 | } | ||
| 1242 | |||
| 1243 | path->grh_mylmc &= 0x80 | smac_index; | ||
| 1244 | 1259 | ||
| 1245 | path->feup |= MLX4_FEUP_FORCE_ETH_UP; | 1260 | path->feup |= MLX4_FEUP_FORCE_ETH_UP; |
| 1246 | if (vlan_tag < 0x1000) { | 1261 | if (vlan_tag < 0x1000) { |
| 1247 | if (mlx4_find_cached_vlan(dev->dev, port, vlan_tag, &vidx)) | 1262 | if (smac_info->vid < 0x1000) { |
| 1248 | return -ENOENT; | 1263 | /* both valid vlan ids */ |
| 1249 | 1264 | if (smac_info->vid != vlan_tag) { | |
| 1250 | path->vlan_index = vidx; | 1265 | /* different VIDs. unreg old and reg new */ |
| 1251 | path->fl = 1 << 6; | 1266 | err = mlx4_register_vlan(dev->dev, port, vlan_tag, &vidx); |
| 1267 | if (err) | ||
| 1268 | return err; | ||
| 1269 | smac_info->candidate_vid = vlan_tag; | ||
| 1270 | smac_info->candidate_vlan_index = vidx; | ||
| 1271 | smac_info->candidate_vlan_port = port; | ||
| 1272 | smac_info->update_vid = 1; | ||
| 1273 | path->vlan_index = vidx; | ||
| 1274 | } else { | ||
| 1275 | path->vlan_index = smac_info->vlan_index; | ||
| 1276 | } | ||
| 1277 | } else { | ||
| 1278 | /* no current vlan tag in qp */ | ||
| 1279 | err = mlx4_register_vlan(dev->dev, port, vlan_tag, &vidx); | ||
| 1280 | if (err) | ||
| 1281 | return err; | ||
| 1282 | smac_info->candidate_vid = vlan_tag; | ||
| 1283 | smac_info->candidate_vlan_index = vidx; | ||
| 1284 | smac_info->candidate_vlan_port = port; | ||
| 1285 | smac_info->update_vid = 1; | ||
| 1286 | path->vlan_index = vidx; | ||
| 1287 | } | ||
| 1252 | path->feup |= MLX4_FVL_FORCE_ETH_VLAN; | 1288 | path->feup |= MLX4_FVL_FORCE_ETH_VLAN; |
| 1289 | path->fl = 1 << 6; | ||
| 1290 | } else { | ||
| 1291 | /* have current vlan tag. unregister it at modify-qp success */ | ||
| 1292 | if (smac_info->vid < 0x1000) { | ||
| 1293 | smac_info->candidate_vid = 0xFFFF; | ||
| 1294 | smac_info->update_vid = 1; | ||
| 1295 | } | ||
| 1253 | } | 1296 | } |
| 1254 | } else | 1297 | |
| 1298 | /* get smac_index for RoCE use. | ||
| 1299 | * If no smac was yet assigned, register one. | ||
| 1300 | * If one was already assigned, but the new mac differs, | ||
| 1301 | * unregister the old one and register the new one. | ||
| 1302 | */ | ||
| 1303 | if (!smac_info->smac || smac_info->smac != smac) { | ||
| 1304 | /* register candidate now, unreg if needed, after success */ | ||
| 1305 | smac_index = mlx4_register_mac(dev->dev, port, smac); | ||
| 1306 | if (smac_index >= 0) { | ||
| 1307 | smac_info->candidate_smac_index = smac_index; | ||
| 1308 | smac_info->candidate_smac = smac; | ||
| 1309 | smac_info->candidate_smac_port = port; | ||
| 1310 | } else { | ||
| 1311 | return -EINVAL; | ||
| 1312 | } | ||
| 1313 | } else { | ||
| 1314 | smac_index = smac_info->smac_index; | ||
| 1315 | } | ||
| 1316 | |||
| 1317 | memcpy(path->dmac, ah->dmac, 6); | ||
| 1318 | path->ackto = MLX4_IB_LINK_TYPE_ETH; | ||
| 1319 | /* put MAC table smac index for IBoE */ | ||
| 1320 | path->grh_mylmc = (u8) (smac_index) | 0x80; | ||
| 1321 | } else { | ||
| 1255 | path->sched_queue = MLX4_IB_DEFAULT_SCHED_QUEUE | | 1322 | path->sched_queue = MLX4_IB_DEFAULT_SCHED_QUEUE | |
| 1256 | ((port - 1) << 6) | ((ah->sl & 0xf) << 2); | 1323 | ((port - 1) << 6) | ((ah->sl & 0xf) << 2); |
| 1324 | } | ||
| 1257 | 1325 | ||
| 1258 | return 0; | 1326 | return 0; |
| 1259 | } | 1327 | } |
| 1260 | 1328 | ||
| 1261 | static int mlx4_set_path(struct mlx4_ib_dev *dev, const struct ib_qp_attr *qp, | 1329 | static int mlx4_set_path(struct mlx4_ib_dev *dev, const struct ib_qp_attr *qp, |
| 1262 | enum ib_qp_attr_mask qp_attr_mask, | 1330 | enum ib_qp_attr_mask qp_attr_mask, |
| 1331 | struct mlx4_ib_qp *mqp, | ||
| 1263 | struct mlx4_qp_path *path, u8 port) | 1332 | struct mlx4_qp_path *path, u8 port) |
| 1264 | { | 1333 | { |
| 1265 | return _mlx4_set_path(dev, &qp->ah_attr, | 1334 | return _mlx4_set_path(dev, &qp->ah_attr, |
| 1266 | mlx4_mac_to_u64((u8 *)qp->smac), | 1335 | mlx4_mac_to_u64((u8 *)qp->smac), |
| 1267 | (qp_attr_mask & IB_QP_VID) ? qp->vlan_id : 0xffff, | 1336 | (qp_attr_mask & IB_QP_VID) ? qp->vlan_id : 0xffff, |
| 1268 | path, port); | 1337 | path, &mqp->pri, port); |
| 1269 | } | 1338 | } |
| 1270 | 1339 | ||
| 1271 | static int mlx4_set_alt_path(struct mlx4_ib_dev *dev, | 1340 | static int mlx4_set_alt_path(struct mlx4_ib_dev *dev, |
| 1272 | const struct ib_qp_attr *qp, | 1341 | const struct ib_qp_attr *qp, |
| 1273 | enum ib_qp_attr_mask qp_attr_mask, | 1342 | enum ib_qp_attr_mask qp_attr_mask, |
| 1343 | struct mlx4_ib_qp *mqp, | ||
| 1274 | struct mlx4_qp_path *path, u8 port) | 1344 | struct mlx4_qp_path *path, u8 port) |
| 1275 | { | 1345 | { |
| 1276 | return _mlx4_set_path(dev, &qp->alt_ah_attr, | 1346 | return _mlx4_set_path(dev, &qp->alt_ah_attr, |
| 1277 | mlx4_mac_to_u64((u8 *)qp->alt_smac), | 1347 | mlx4_mac_to_u64((u8 *)qp->alt_smac), |
| 1278 | (qp_attr_mask & IB_QP_ALT_VID) ? | 1348 | (qp_attr_mask & IB_QP_ALT_VID) ? |
| 1279 | qp->alt_vlan_id : 0xffff, | 1349 | qp->alt_vlan_id : 0xffff, |
| 1280 | path, port); | 1350 | path, &mqp->alt, port); |
| 1281 | } | 1351 | } |
| 1282 | 1352 | ||
| 1283 | static void update_mcg_macs(struct mlx4_ib_dev *dev, struct mlx4_ib_qp *qp) | 1353 | static void update_mcg_macs(struct mlx4_ib_dev *dev, struct mlx4_ib_qp *qp) |
| @@ -1292,6 +1362,37 @@ static void update_mcg_macs(struct mlx4_ib_dev *dev, struct mlx4_ib_qp *qp) · 8 unmodified lines | |||
| 1292 | } | 1362 | } |
| 1293 | } | 1363 | } |
| 1294 | 1364 | ||
| 1365 | static int handle_eth_ud_smac_index(struct mlx4_ib_dev *dev, struct mlx4_ib_qp *qp, u8 *smac, | ||
| 1366 | struct mlx4_qp_context *context) | ||
| 1367 | { | ||
| 1368 | struct net_device *ndev; | ||
| 1369 | u64 u64_mac; | ||
| 1370 | int smac_index; | ||
| 1371 | |||
| 1372 | |||
| 1373 | ndev = dev->iboe.netdevs[qp->port - 1]; | ||
| 1374 | if (ndev) { | ||
| 1375 | smac = ndev->dev_addr; | ||
| 1376 | u64_mac = mlx4_mac_to_u64(smac); | ||
| 1377 | } else { | ||
| 1378 | u64_mac = dev->dev->caps.def_mac[qp->port]; | ||
| 1379 | } | ||
| 1380 | |||
| 1381 | context->pri_path.sched_queue = MLX4_IB_DEFAULT_SCHED_QUEUE | ((qp->port - 1) << 6); | ||
| 1382 | if (!qp->pri.smac) { | ||
| 1383 | smac_index = mlx4_register_mac(dev->dev, qp->port, u64_mac); | ||
| 1384 | if (smac_index >= 0) { | ||
| 1385 | qp->pri.candidate_smac_index = smac_index; | ||
| 1386 | qp->pri.candidate_smac = u64_mac; | ||
| 1387 | qp->pri.candidate_smac_port = qp->port; | ||
| 1388 | context->pri_path.grh_mylmc = 0x80 | (u8) smac_index; | ||
| 1389 | } else { | ||
| 1390 | return -ENOENT; | ||
| 1391 | } | ||
| 1392 | } | ||
| 1393 | return 0; | ||
| 1394 | } | ||
| 1395 | |||
| 1295 | static int __mlx4_ib_modify_qp(struct ib_qp *ibqp, | 1396 | static int __mlx4_ib_modify_qp(struct ib_qp *ibqp, |
| 1296 | const struct ib_qp_attr *attr, int attr_mask, | 1397 | const struct ib_qp_attr *attr, int attr_mask, |
| 1297 | enum ib_qp_state cur_state, enum ib_qp_state new_state) | 1398 | enum ib_qp_state cur_state, enum ib_qp_state new_state) |
| @@ -1403,7 +1504,7 @@ static int __mlx4_ib_modify_qp(struct ib_qp *ibqp, · 105 unmodified lines | |||
| 1403 | } | 1504 | } |
| 1404 | 1505 | ||
| 1405 | if (attr_mask & IB_QP_AV) { | 1506 | if (attr_mask & IB_QP_AV) { |
| 1406 | if (mlx4_set_path(dev, attr, attr_mask, &context->pri_path, | 1507 | if (mlx4_set_path(dev, attr, attr_mask, qp, &context->pri_path, |
| 1407 | attr_mask & IB_QP_PORT ? | 1508 | attr_mask & IB_QP_PORT ? |
| 1408 | attr->port_num : qp->port)) | 1509 | attr->port_num : qp->port)) |
| 1409 | goto out; | 1510 | goto out; |
| @@ -1426,7 +1527,8 @@ static int __mlx4_ib_modify_qp(struct ib_qp *ibqp, · 16 unmodified lines | |||
| 1426 | dev->dev->caps.pkey_table_len[attr->alt_port_num]) | 1527 | dev->dev->caps.pkey_table_len[attr->alt_port_num]) |
| 1427 | goto out; | 1528 | goto out; |
| 1428 | 1529 | ||
| 1429 | if (mlx4_set_alt_path(dev, attr, attr_mask, &context->alt_path, | 1530 | if (mlx4_set_alt_path(dev, attr, attr_mask, qp, |
| 1531 | &context->alt_path, | ||
| 1430 | attr->alt_port_num)) | 1532 | attr->alt_port_num)) |
| 1431 | goto out; | 1533 | goto out; |
| 1432 | 1534 | ||
| @@ -1532,6 +1634,20 @@ static int __mlx4_ib_modify_qp(struct ib_qp *ibqp, · 99 unmodified lines | |||
| 1532 | context->pri_path.fl = 0x80; | 1634 | context->pri_path.fl = 0x80; |
| 1533 | context->pri_path.sched_queue |= MLX4_IB_DEFAULT_SCHED_QUEUE; | 1635 | context->pri_path.sched_queue |= MLX4_IB_DEFAULT_SCHED_QUEUE; |
| 1534 | } | 1636 | } |
| 1637 | if (rdma_port_get_link_layer(&dev->ib_dev, qp->port) == | ||
| 1638 | IB_LINK_LAYER_ETHERNET) { | ||
| 1639 | if (qp->mlx4_ib_qp_type == MLX4_IB_QPT_TUN_GSI || | ||
| 1640 | qp->mlx4_ib_qp_type == MLX4_IB_QPT_GSI) | ||
| 1641 | context->pri_path.feup = 1 << 7; /* don't fsm */ | ||
| 1642 | /* handle smac_index */ | ||
| 1643 | if (qp->mlx4_ib_qp_type == MLX4_IB_QPT_UD || | ||
| 1644 | qp->mlx4_ib_qp_type == MLX4_IB_QPT_PROXY_GSI || | ||
| 1645 | qp->mlx4_ib_qp_type == MLX4_IB_QPT_TUN_GSI) { | ||
| 1646 | err = handle_eth_ud_smac_index(dev, qp, (u8 *)attr->smac, context); | ||
| 1647 | if (err) | ||
| 1648 | return -EINVAL; | ||
| 1649 | } | ||
| 1650 | } | ||
| 1535 | } | 1651 | } |
| 1536 | 1652 | ||
| 1537 | if (qp->ibqp.qp_type == IB_QPT_RAW_PACKET) | 1653 | if (qp->ibqp.qp_type == IB_QPT_RAW_PACKET) |
| @@ -1619,28 +1735,113 @@ static int __mlx4_ib_modify_qp(struct ib_qp *ibqp, · 81 unmodified lines | |||
| 1619 | * If we moved a kernel QP to RESET, clean up all old CQ | 1735 | * If we moved a kernel QP to RESET, clean up all old CQ |
| 1620 | * entries and reinitialize the QP. | 1736 | * entries and reinitialize the QP. |
| 1621 | */ | 1737 | */ |
| 1622 | if (new_state == IB_QPS_RESET && !ibqp->uobject) { | 1738 | if (new_state == IB_QPS_RESET) { |
| 1623 | mlx4_ib_cq_clean(recv_cq, qp->mqp.qpn, | 1739 | if (!ibqp->uobject) { |
| 1624 | ibqp->srq ? to_msrq(ibqp->srq): NULL); | 1740 | mlx4_ib_cq_clean(recv_cq, qp->mqp.qpn, |
| 1625 | if (send_cq != recv_cq) | 1741 | ibqp->srq ? to_msrq(ibqp->srq) : NULL); |
| 1626 | mlx4_ib_cq_clean(send_cq, qp->mqp.qpn, NULL); | 1742 | if (send_cq != recv_cq) |
| 1743 | mlx4_ib_cq_clean(send_cq, qp->mqp.qpn, NULL); | ||
| 1744 | |||
| 1745 | qp->rq.head = 0; | ||
| 1746 | qp->rq.tail = 0; | ||
| 1747 | qp->sq.head = 0; | ||
| 1748 | qp->sq.tail = 0; | ||
| 1749 | qp->sq_next_wqe = 0; | ||
| 1750 | if (qp->rq.wqe_cnt) | ||
| 1751 | *qp->db.db = 0; | ||
| 1627 | 1752 | ||
| 1628 | qp->rq.head = 0; | 1753 | if (qp->flags & MLX4_IB_QP_NETIF) |
| 1629 | qp->rq.tail = 0; | 1754 | mlx4_ib_steer_qp_reg(dev, qp, 0); |
| 1630 | qp->sq.head = 0; | 1755 | } |
| 1631 | qp->sq.tail = 0; | 1756 | if (qp->pri.smac) { |
| 1632 | qp->sq_next_wqe = 0; | 1757 | mlx4_unregister_mac(dev->dev, qp->pri.smac_port, qp->pri.smac); |
| 1633 | if (qp->rq.wqe_cnt) | 1758 | qp->pri.smac = 0; |
| 1634 | *qp->db.db = 0; | 1759 | } |
| 1760 | if (qp->alt.smac) { | ||
| 1761 | mlx4_unregister_mac(dev->dev, qp->alt.smac_port, qp->alt.smac); | ||
| 1762 | qp->alt.smac = 0; | ||
| 1763 | } | ||
| 1764 | if (qp->pri.vid < 0x1000) { | ||
| 1765 | mlx4_unregister_vlan(dev->dev, qp->pri.vlan_port, qp->pri.vid); | ||
| 1766 | qp->pri.vid = 0xFFFF; | ||
| 1767 | qp->pri.candidate_vid = 0xFFFF; | ||
| 1768 | qp->pri.update_vid = 0; | ||
| 1769 | } | ||
| 1635 | 1770 | ||
| 1636 | if (qp->flags & MLX4_IB_QP_NETIF) | 1771 | if (qp->alt.vid < 0x1000) { |
| 1637 | mlx4_ib_steer_qp_reg(dev, qp, 0); | 1772 | mlx4_unregister_vlan(dev->dev, qp->alt.vlan_port, qp->alt.vid); |
| 1773 | qp->alt.vid = 0xFFFF; | ||
| 1774 | qp->alt.candidate_vid = 0xFFFF; | ||
| 1775 | qp->alt.update_vid = 0; | ||
| 1776 | } | ||
| 1638 | } | 1777 | } |
| 1639 | |||
| 1640 | out: | 1778 | out: |
| 1641 | if (err && steer_qp) | 1779 | if (err && steer_qp) |
| 1642 | mlx4_ib_steer_qp_reg(dev, qp, 0); | 1780 | mlx4_ib_steer_qp_reg(dev, qp, 0); |
| 1643 | kfree(context); | 1781 | kfree(context); |
| 1782 | if (qp->pri.candidate_smac) { | ||
| 1783 | if (err) { | ||
| 1784 | mlx4_unregister_mac(dev->dev, qp->pri.candidate_smac_port, qp->pri.candidate_smac); | ||
| 1785 | } else { | ||
| 1786 | if (qp->pri.smac) | ||
| 1787 | mlx4_unregister_mac(dev->dev, qp->pri.smac_port, qp->pri.smac); | ||
| 1788 | qp->pri.smac = qp->pri.candidate_smac; | ||
| 1789 | qp->pri.smac_index = qp->pri.candidate_smac_index; | ||
| 1790 | qp->pri.smac_port = qp->pri.candidate_smac_port; | ||
| 1791 | } | ||
| 1792 | qp->pri.candidate_smac = 0; | ||
| 1793 | qp->pri.candidate_smac_index = 0; | ||
| 1794 | qp->pri.candidate_smac_port = 0; | ||
| 1795 | } | ||
| 1796 | if (qp->alt.candidate_smac) { | ||
| 1797 | if (err) { | ||
| 1798 | mlx4_unregister_mac(dev->dev, qp->alt.candidate_smac_port, qp->alt.candidate_smac); | ||
| 1799 | } else { | ||
| 1800 | if (qp->alt.smac) | ||
| 1801 | mlx4_unregister_mac(dev->dev, qp->alt.smac_port, qp->alt.smac); | ||
| 1802 | qp->alt.smac = qp->alt.candidate_smac; | ||
| 1803 | qp->alt.smac_index = qp->alt.candidate_smac_index; | ||
| 1804 | qp->alt.smac_port = qp->alt.candidate_smac_port; | ||
| 1805 | } | ||
| 1806 | qp->alt.candidate_smac = 0; | ||
| 1807 | qp->alt.candidate_smac_index = 0; | ||
| 1808 | qp->alt.candidate_smac_port = 0; | ||
| 1809 | } | ||
| 1810 | |||
| 1811 | if (qp->pri.update_vid) { | ||
| 1812 | if (err) { | ||
| 1813 | if (qp->pri.candidate_vid < 0x1000) | ||
| 1814 | mlx4_unregister_vlan(dev->dev, qp->pri.candidate_vlan_port, | ||
| 1815 | qp->pri.candidate_vid); | ||
| 1816 | } else { | ||
| 1817 | if (qp->pri.vid < 0x1000) | ||
| 1818 | mlx4_unregister_vlan(dev->dev, qp->pri.vlan_port, | ||
| 1819 | qp->pri.vid); | ||
| 1820 | qp->pri.vid = qp->pri.candidate_vid; | ||
| 1821 | qp->pri.vlan_port = qp->pri.candidate_vlan_port; | ||
| 1822 | qp->pri.vlan_index = qp->pri.candidate_vlan_index; | ||
| 1823 | } | ||
| 1824 | qp->pri.candidate_vid = 0xFFFF; | ||
| 1825 | qp->pri.update_vid = 0; | ||
| 1826 | } | ||
| 1827 | |||
| 1828 | if (qp->alt.update_vid) { | ||
| 1829 | if (err) { | ||
| 1830 | if (qp->alt.candidate_vid < 0x1000) | ||
| 1831 | mlx4_unregister_vlan(dev->dev, qp->alt.candidate_vlan_port, | ||
| 1832 | qp->alt.candidate_vid); | ||
| 1833 | } else { | ||
| 1834 | if (qp->alt.vid < 0x1000) | ||
| 1835 | mlx4_unregister_vlan(dev->dev, qp->alt.vlan_port, | ||
| 1836 | qp->alt.vid); | ||
| 1837 | qp->alt.vid = qp->alt.candidate_vid; | ||
| 1838 | qp->alt.vlan_port = qp->alt.candidate_vlan_port; | ||
| 1839 | qp->alt.vlan_index = qp->alt.candidate_vlan_index; | ||
| 1840 | } | ||
| 1841 | qp->alt.candidate_vid = 0xFFFF; | ||
| 1842 | qp->alt.update_vid = 0; | ||
| 1843 | } | ||
| 1844 | |||
| 1644 | return err; | 1845 | return err; |
| 1645 | } | 1846 | } |
| 1646 | 1847 | ||
| @@ -1842,9 +2043,9 @@ static int build_mlx_header(struct mlx4_ib_sqp *sqp, struct ib_send_wr *wr, · 195 unmodified lines | |||
| 1842 | { | 2043 | { |
| 1843 | struct ib_device *ib_dev = sqp->qp.ibqp.device; | 2044 | struct ib_device *ib_dev = sqp->qp.ibqp.device; |
| 1844 | struct mlx4_wqe_mlx_seg *mlx = wqe; | 2045 | struct mlx4_wqe_mlx_seg *mlx = wqe; |
| 2046 | struct mlx4_wqe_ctrl_seg *ctrl = wqe; | ||
| 1845 | struct mlx4_wqe_inline_seg *inl = wqe + sizeof *mlx; | 2047 | struct mlx4_wqe_inline_seg *inl = wqe + sizeof *mlx; |
| 1846 | struct mlx4_ib_ah *ah = to_mah(wr->wr.ud.ah); | 2048 | struct mlx4_ib_ah *ah = to_mah(wr->wr.ud.ah); |
| 1847 | struct net_device *ndev; | ||
| 1848 | union ib_gid sgid; | 2049 | union ib_gid sgid; |
| 1849 | u16 pkey; | 2050 | u16 pkey; |
| 1850 | int send_size; | 2051 | int send_size; |
| @@ -1868,12 +2069,11 @@ static int build_mlx_header(struct mlx4_ib_sqp *sqp, struct ib_send_wr *wr, · 17 unmodified lines | |||
| 1868 | /* When multi-function is enabled, the ib_core gid | 2069 | /* When multi-function is enabled, the ib_core gid |
| 1869 | * indexes don't necessarily match the hw ones, so | 2070 | * indexes don't necessarily match the hw ones, so |
| 1870 | * we must use our own cache */ | 2071 | * we must use our own cache */ |
| 1871 | sgid.global.subnet_prefix = | 2072 | err = mlx4_get_roce_gid_from_slave(to_mdev(ib_dev)->dev, |
| 1872 | to_mdev(ib_dev)->sriov.demux[sqp->qp.port - 1]. | 2073 | be32_to_cpu(ah->av.ib.port_pd) >> 24, |
| 1873 | subnet_prefix; | 2074 | ah->av.ib.gid_index, &sgid.raw[0]); |
| 1874 | sgid.global.interface_id = | 2075 | if (err) |
| 1875 | to_mdev(ib_dev)->sriov.demux[sqp->qp.port - 1]. | 2076 | return err; |
| 1876 | guid_cache[ah->av.ib.gid_index]; | ||
| 1877 | } else { | 2077 | } else { |
| 1878 | err = ib_get_cached_gid(ib_dev, | 2078 | err = ib_get_cached_gid(ib_dev, |
| 1879 | be32_to_cpu(ah->av.ib.port_pd) >> 24, | 2079 | be32_to_cpu(ah->av.ib.port_pd) >> 24, |
| @@ -1902,6 +2102,9 @@ static int build_mlx_header(struct mlx4_ib_sqp *sqp, struct ib_send_wr *wr, · 22 unmodified lines | |||
| 1902 | sqp->ud_header.grh.flow_label = | 2102 | sqp->ud_header.grh.flow_label = |
| 1903 | ah->av.ib.sl_tclass_flowlabel & cpu_to_be32(0xfffff); | 2103 | ah->av.ib.sl_tclass_flowlabel & cpu_to_be32(0xfffff); |
| 1904 | sqp->ud_header.grh.hop_limit = ah->av.ib.hop_limit; | 2104 | sqp->ud_header.grh.hop_limit = ah->av.ib.hop_limit; |
| 2105 | if (is_eth) | ||
| 2106 | memcpy(sqp->ud_header.grh.source_gid.raw, sgid.raw, 16); | ||
| 2107 | else { | ||
| 1905 | if (mlx4_is_mfunc(to_mdev(ib_dev)->dev)) { | 2108 | if (mlx4_is_mfunc(to_mdev(ib_dev)->dev)) { |
| 1906 | /* When multi-function is enabled, the ib_core gid | 2109 | /* When multi-function is enabled, the ib_core gid |
| 1907 | * indexes don't necessarily match the hw ones, so | 2110 | * indexes don't necessarily match the hw ones, so |
| @@ -1917,6 +2120,7 @@ static int build_mlx_header(struct mlx4_ib_sqp *sqp, struct ib_send_wr *wr, · 9 unmodified lines | |||
| 1917 | be32_to_cpu(ah->av.ib.port_pd) >> 24, | 2120 | be32_to_cpu(ah->av.ib.port_pd) >> 24, |
| 1918 | ah->av.ib.gid_index, | 2121 | ah->av.ib.gid_index, |
| 1919 | &sqp->ud_header.grh.source_gid); | 2122 | &sqp->ud_header.grh.source_gid); |
| 2123 | } | ||
| 1920 | memcpy(sqp->ud_header.grh.destination_gid.raw, | 2124 | memcpy(sqp->ud_header.grh.destination_gid.raw, |
| 1921 | ah->av.ib.dgid, 16); | 2125 | ah->av.ib.dgid, 16); |
| 1922 | } | 2126 | } |
| @@ -1949,16 +2153,23 @@ static int build_mlx_header(struct mlx4_ib_sqp *sqp, struct ib_send_wr *wr, · 26 unmodified lines | |||
| 1949 | 2153 | ||
| 1950 | if (is_eth) { | 2154 | if (is_eth) { |
| 1951 | u8 *smac; | 2155 | u8 *smac; |
| 2156 | struct in6_addr in6; | ||
| 2157 | |||
| 1952 | u16 pcp = (be32_to_cpu(ah->av.ib.sl_tclass_flowlabel) >> 29) << 13; | 2158 | u16 pcp = (be32_to_cpu(ah->av.ib.sl_tclass_flowlabel) >> 29) << 13; |
| 1953 | 2159 | ||
| 1954 | mlx->sched_prio = cpu_to_be16(pcp); | 2160 | mlx->sched_prio = cpu_to_be16(pcp); |
| 1955 | 2161 | ||
| 1956 | memcpy(sqp->ud_header.eth.dmac_h, ah->av.eth.mac, 6); | 2162 | memcpy(sqp->ud_header.eth.dmac_h, ah->av.eth.mac, 6); |
| 1957 | /* FIXME: cache smac value? */ | 2163 | /* FIXME: cache smac value? */ |
| 1958 | ndev = to_mdev(sqp->qp.ibqp.device)->iboe.netdevs[sqp->qp.port - 1]; | 2164 | memcpy(&ctrl->srcrb_flags16[0], ah->av.eth.mac, 2); |
| 1959 | if (!ndev) | 2165 | memcpy(&ctrl->imm, ah->av.eth.mac + 2, 4); |
| 1960 | return -ENODEV; | 2166 | memcpy(&in6, sgid.raw, sizeof(in6)); |
| 1961 | smac = ndev->dev_addr; | 2167 | |
| 2168 | if (!mlx4_is_mfunc(to_mdev(ib_dev)->dev)) | ||
| 2169 | smac = to_mdev(sqp->qp.ibqp.device)-> | ||
| 2170 | iboe.netdevs[sqp->qp.port - 1]->dev_addr; | ||
| 2171 | else /* use the src mac of the tunnel */ | ||
| 2172 | smac = ah->av.eth.s_mac; | ||
| 1962 | memcpy(sqp->ud_header.eth.smac_h, smac, 6); | 2173 | memcpy(sqp->ud_header.eth.smac_h, smac, 6); |
| 1963 | if (!memcmp(sqp->ud_header.eth.smac_h, sqp->ud_header.eth.dmac_h, 6)) | 2174 | if (!memcmp(sqp->ud_header.eth.smac_h, sqp->ud_header.eth.dmac_h, 6)) |
| 1964 | mlx->flags |= cpu_to_be32(MLX4_WQE_CTRL_FORCE_LOOPBACK); | 2175 | mlx->flags |= cpu_to_be32(MLX4_WQE_CTRL_FORCE_LOOPBACK); |
| @@ -2190,6 +2401,8 @@ static void build_tunnel_header(struct ib_send_wr *wr, void *wqe, unsigned *mlx_ · 225 unmodified lines | |||
| 2190 | hdr.remote_qpn = cpu_to_be32(wr->wr.ud.remote_qpn); | 2401 | hdr.remote_qpn = cpu_to_be32(wr->wr.ud.remote_qpn); |
| 2191 | hdr.pkey_index = cpu_to_be16(wr->wr.ud.pkey_index); | 2402 | hdr.pkey_index = cpu_to_be16(wr->wr.ud.pkey_index); |
| 2192 | hdr.qkey = cpu_to_be32(wr->wr.ud.remote_qkey); | 2403 | hdr.qkey = cpu_to_be32(wr->wr.ud.remote_qkey); |
| 2404 | memcpy(hdr.mac, ah->av.eth.mac, 6); | ||
| 2405 | hdr.vlan = ah->av.eth.vlan; | ||
| 2193 | 2406 | ||
| 2194 | spc = MLX4_INLINE_ALIGN - | 2407 | spc = MLX4_INLINE_ALIGN - |
| 2195 | ((unsigned long) (inl + 1) & (MLX4_INLINE_ALIGN - 1)); | 2408 | ((unsigned long) (inl + 1) & (MLX4_INLINE_ALIGN - 1)); |
| @@ -627,6 +627,7 @@ static int register_one_pkey_tree(struct mlx4_ib_dev *dev, int slave) · 626 unmodified lines | |||
| 627 | int port; | 627 | int port; |
| 628 | struct kobject *p, *t; | 628 | struct kobject *p, *t; |
| 629 | struct mlx4_port *mport; | 629 | struct mlx4_port *mport; |
| 630 | struct mlx4_active_ports actv_ports; | ||
| 630 | 631 | ||
| 631 | get_name(dev, name, slave, sizeof name); | 632 | get_name(dev, name, slave, sizeof name); |
| 632 | 633 | ||
| @@ -649,7 +650,11 @@ static int register_one_pkey_tree(struct mlx4_ib_dev *dev, int slave) · 16 unmodified lines | |||
| 649 | goto err_ports; | 650 | goto err_ports; |
| 650 | } | 651 | } |
| 651 | 652 | ||
| 653 | actv_ports = mlx4_get_active_ports(dev->dev, slave); | ||
| 654 | |||
| 652 | for (port = 1; port <= dev->dev->caps.num_ports; ++port) { | 655 | for (port = 1; port <= dev->dev->caps.num_ports; ++port) { |
| 656 | if (!test_bit(port - 1, actv_ports.ports)) | ||
| 657 | continue; | ||
| 653 | err = add_port(dev, port, slave); | 658 | err = add_port(dev, port, slave); |
| 654 | if (err) | 659 | if (err) |
| 655 | goto err_add; | 660 | goto err_add; |
| @@ -796,7 +796,7 @@ static void __exit act2000_exit(void) · 795 unmodified lines | |||
| 796 | act2000_card *last; | 796 | act2000_card *last; |
| 797 | while (card) { | 797 | while (card) { |
| 798 | unregister_card(card); | 798 | unregister_card(card); |
| 799 | del_timer(&card->ptimer); | 799 | del_timer_sync(&card->ptimer); |
| 800 | card = card->next; | 800 | card = card->next; |
| 801 | } | 801 | } |
| 802 | card = cards; | 802 | card = cards; |
| @@ -86,12 +86,13 @@ isdn_divert_read(struct file *file, char __user *buf, size_t count, loff_t *off) · 85 unmodified lines | |||
| 86 | struct divert_info *inf; | 86 | struct divert_info *inf; |
| 87 | int len; | 87 | int len; |
| 88 | 88 | ||
| 89 | if (!*((struct divert_info **) file->private_data)) { | 89 | if (!(inf = *((struct divert_info **) file->private_data))) { |
| 90 | if (file->f_flags & O_NONBLOCK) | 90 | if (file->f_flags & O_NONBLOCK) |
| 91 | return -EAGAIN; | 91 | return -EAGAIN; |
| 92 | interruptible_sleep_on(&(rd_queue)); | 92 | wait_event_interruptible(rd_queue, (inf = |
| 93 | *((struct divert_info **) file->private_data))); | ||
| 93 | } | 94 | } |
| 94 | if (!(inf = *((struct divert_info **) file->private_data))) | 95 | if (!inf) |
| 95 | return (0); | 96 | return (0); |
| 96 | 97 | ||
| 97 | inf->usage_cnt--; /* new usage count */ | 98 | inf->usage_cnt--; /* new usage count */ |
| @@ -509,7 +509,8 @@ static void · 508 unmodified lines | |||
| 509 | set_arcofi(struct IsdnCardState *cs, int bc) { | 509 | set_arcofi(struct IsdnCardState *cs, int bc) { |
| 510 | cs->dc.isac.arcofi_bc = bc; | 510 | cs->dc.isac.arcofi_bc = bc; |
| 511 | arcofi_fsm(cs, ARCOFI_START, &ARCOFI_COP_5); | 511 | arcofi_fsm(cs, ARCOFI_START, &ARCOFI_COP_5); |
| 512 | interruptible_sleep_on(&cs->dc.isac.arcofi_wait); | 512 | wait_event_interruptible(cs->dc.isac.arcofi_wait, |
| 513 | cs->dc.isac.arcofi_state == ARCOFI_NOP); | ||
| 513 | } | 514 | } |
| 514 | 515 | ||
| 515 | static int | 516 | static int |
| @@ -528,7 +529,8 @@ check_arcofi(struct IsdnCardState *cs) · 12 unmodified lines | |||
| 528 | } | 529 | } |
| 529 | cs->dc.isac.arcofi_bc = 0; | 530 | cs->dc.isac.arcofi_bc = 0; |
| 530 | arcofi_fsm(cs, ARCOFI_START, &ARCOFI_VERSION); | 531 | arcofi_fsm(cs, ARCOFI_START, &ARCOFI_VERSION); |
| 531 | interruptible_sleep_on(&cs->dc.isac.arcofi_wait); | 532 | wait_event_interruptible(cs->dc.isac.arcofi_wait, |
| 533 | cs->dc.isac.arcofi_state == ARCOFI_NOP); | ||
| 532 | if (!test_and_clear_bit(FLG_ARCOFI_ERROR, &cs->HW_Flags)) { | 534 | if (!test_and_clear_bit(FLG_ARCOFI_ERROR, &cs->HW_Flags)) { |
| 533 | debugl1(cs, "Arcofi response received %d bytes", cs->dc.isac.mon_rxp); | 535 | debugl1(cs, "Arcofi response received %d bytes", cs->dc.isac.mon_rxp); |
| 534 | p = cs->dc.isac.mon_rx; | 536 | p = cs->dc.isac.mon_rx; |
| @@ -595,7 +597,8 @@ check_arcofi(struct IsdnCardState *cs) · 60 unmodified lines | |||
| 595 | Elsa_Types[cs->subtyp], | 597 | Elsa_Types[cs->subtyp], |
| 596 | cs->hw.elsa.base + 8); | 598 | cs->hw.elsa.base + 8); |
| 597 | arcofi_fsm(cs, ARCOFI_START, &ARCOFI_XOP_0); | 599 | arcofi_fsm(cs, ARCOFI_START, &ARCOFI_XOP_0); |
| 598 | interruptible_sleep_on(&cs->dc.isac.arcofi_wait); | 600 | wait_event_interruptible(cs->dc.isac.arcofi_wait, |
| 601 | cs->dc.isac.arcofi_state == ARCOFI_NOP); | ||
| 599 | return (1); | 602 | return (1); |
| 600 | } | 603 | } |
| 601 | return (0); | 604 | return (0); |
| @@ -573,7 +573,8 @@ modem_l2l1(struct PStack *st, int pr, void *arg) · 572 unmodified lines | |||
| 573 | test_and_clear_bit(BC_FLG_ACTIV, &bcs->Flag); | 573 | test_and_clear_bit(BC_FLG_ACTIV, &bcs->Flag); |
| 574 | bcs->cs->dc.isac.arcofi_bc = st->l1.bc; | 574 | bcs->cs->dc.isac.arcofi_bc = st->l1.bc; |
| 575 | arcofi_fsm(bcs->cs, ARCOFI_START, &ARCOFI_XOP_0); | 575 | arcofi_fsm(bcs->cs, ARCOFI_START, &ARCOFI_XOP_0); |
| 576 | interruptible_sleep_on(&bcs->cs->dc.isac.arcofi_wait); | 576 | wait_event_interruptible(bcs->cs->dc.isac.arcofi_wait, |
| 577 | bcs->cs->dc.isac.arcofi_state == ARCOFI_NOP); | ||
| 577 | bcs->cs->hw.elsa.MFlag = 1; | 578 | bcs->cs->hw.elsa.MFlag = 1; |
| 578 | } else { | 579 | } else { |
| 579 | printk(KERN_WARNING "ElsaSer: unknown pr %x\n", pr); | 580 | printk(KERN_WARNING "ElsaSer: unknown pr %x\n", pr); |
| @@ -175,14 +175,15 @@ hysdn_log_read(struct file *file, char __user *buf, size_t count, loff_t *off) · 174 unmodified lines | |||
| 175 | int len; | 175 | int len; |
| 176 | hysdn_card *card = PDE_DATA(file_inode(file)); | 176 | hysdn_card *card = PDE_DATA(file_inode(file)); |
| 177 | 177 | ||
| 178 | if (!*((struct log_data **) file->private_data)) { | 178 | if (!(inf = *((struct log_data **) file->private_data))) { |
| 179 | struct procdata *pd = card->proclog; | 179 | struct procdata *pd = card->proclog; |
| 180 | if (file->f_flags & O_NONBLOCK) | 180 | if (file->f_flags & O_NONBLOCK) |
| 181 | return (-EAGAIN); | 181 | return (-EAGAIN); |
| 182 | 182 | ||
| 183 | interruptible_sleep_on(&(pd->rd_queue)); | 183 | wait_event_interruptible(pd->rd_queue, (inf = |
| 184 | *((struct log_data **) file->private_data))); | ||
| 184 | } | 185 | } |
| 185 | if (!(inf = *((struct log_data **) file->private_data))) | 186 | if (!inf) |
| 186 | return (0); | 187 | return (0); |
| 187 | 188 | ||
| 188 | inf->usage_cnt--; /* new usage count */ | 189 | inf->usage_cnt--; /* new usage count */ |
| @@ -777,7 +777,8 @@ isdn_readbchan(int di, int channel, u_char *buf, u_char *fp, int len, wait_queue · 776 unmodified lines | |||
| 777 | return 0; | 777 | return 0; |
| 778 | if (skb_queue_empty(&dev->drv[di]->rpqueue[channel])) { | 778 | if (skb_queue_empty(&dev->drv[di]->rpqueue[channel])) { |
| 779 | if (sleep) | 779 | if (sleep) |
| 780 | interruptible_sleep_on(sleep); | 780 | wait_event_interruptible(*sleep, |
| 781 | !skb_queue_empty(&dev->drv[di]->rpqueue[channel])); | ||
| 781 | else | 782 | else |
| 782 | return 0; | 783 | return 0; |
| 783 | } | 784 | } |
| @@ -1072,7 +1073,8 @@ isdn_read(struct file *file, char __user *buf, size_t count, loff_t *off) · 288 unmodified lines | |||
| 1072 | retval = -EAGAIN; | 1073 | retval = -EAGAIN; |
| 1073 | goto out; | 1074 | goto out; |
| 1074 | } | 1075 | } |
| 1075 | interruptible_sleep_on(&(dev->info_waitq)); | 1076 | wait_event_interruptible(dev->info_waitq, |
| 1077 | file->private_data); | ||
| 1076 | } | 1078 | } |
| 1077 | p = isdn_statstr(); | 1079 | p = isdn_statstr(); |
| 1078 | file->private_data = NULL; | 1080 | file->private_data = NULL; |
| @@ -1128,7 +1130,8 @@ isdn_read(struct file *file, char __user *buf, size_t count, loff_t *off) · 49 unmodified lines | |||
| 1128 | retval = -EAGAIN; | 1130 | retval = -EAGAIN; |
| 1129 | goto out; | 1131 | goto out; |
| 1130 | } | 1132 | } |
| 1131 | interruptible_sleep_on(&(dev->drv[drvidx]->st_waitq)); | 1133 | wait_event_interruptible(dev->drv[drvidx]->st_waitq, |
| 1134 | dev->drv[drvidx]->stavail); | ||
| 1132 | } | 1135 | } |
| 1133 | if (dev->drv[drvidx]->interface->readstat) { | 1136 | if (dev->drv[drvidx]->interface->readstat) { |
| 1134 | if (count > dev->drv[drvidx]->stavail) | 1137 | if (count > dev->drv[drvidx]->stavail) |
| @@ -1188,8 +1191,8 @@ isdn_write(struct file *file, const char __user *buf, size_t count, loff_t *off) · 53 unmodified lines | |||
| 1188 | goto out; | 1191 | goto out; |
| 1189 | } | 1192 | } |
| 1190 | chidx = isdn_minor2chan(minor); | 1193 | chidx = isdn_minor2chan(minor); |
| 1191 | while ((retval = isdn_writebuf_stub(drvidx, chidx, buf, count)) == 0) | 1194 | wait_event_interruptible(dev->drv[drvidx]->snd_waitq[chidx], |
| 1192 | interruptible_sleep_on(&dev->drv[drvidx]->snd_waitq[chidx]); | 1195 | (retval = isdn_writebuf_stub(drvidx, chidx, buf, count))); |
| 1193 | goto out; | 1196 | goto out; |
| 1194 | } | 1197 | } |
| 1195 | if (minor <= ISDN_MINOR_CTRLMAX) { | 1198 | if (minor <= ISDN_MINOR_CTRLMAX) { |
| @@ -2378,7 +2381,7 @@ static void __exit isdn_exit(void) · 1182 unmodified lines | |||
| 2378 | } | 2381 | } |
| 2379 | isdn_tty_exit(); | 2382 | isdn_tty_exit(); |
| 2380 | unregister_chrdev(ISDN_MAJOR, "isdn"); | 2383 | unregister_chrdev(ISDN_MAJOR, "isdn"); |
| 2381 | del_timer(&dev->timer); | 2384 | del_timer_sync(&dev->timer); |
| 2382 | /* call vfree with interrupts enabled, else it will hang */ | 2385 | /* call vfree with interrupts enabled, else it will hang */ |
| 2383 | vfree(dev); | 2386 | vfree(dev); |
| 2384 | printk(KERN_NOTICE "ISDN-subsystem unloaded\n"); | 2387 | printk(KERN_NOTICE "ISDN-subsystem unloaded\n"); |
| @@ -378,10 +378,15 @@ isdn_ppp_release(int min, struct file *file) · 377 unmodified lines | |||
| 378 | is->slcomp = NULL; | 378 | is->slcomp = NULL; |
| 379 | #endif | 379 | #endif |
| 380 | #ifdef CONFIG_IPPP_FILTER | 380 | #ifdef CONFIG_IPPP_FILTER |
| 381 | kfree(is->pass_filter); | 381 | if (is->pass_filter) { |
| 382 | is->pass_filter = NULL; | 382 | sk_unattached_filter_destroy(is->pass_filter); |
| 383 | kfree(is->active_filter); | 383 | is->pass_filter = NULL; |
| 384 | is->active_filter = NULL; | 384 | } |
| 385 | |||
| 386 | if (is->active_filter) { | ||
| 387 | sk_unattached_filter_destroy(is->active_filter); | ||
| 388 | is->active_filter = NULL; | ||
| 389 | } | ||
| 385 | #endif | 390 | #endif |
| 386 | 391 | ||
| 387 | /* TODO: if this was the previous master: link the stuff to the new master */ | 392 | /* TODO: if this was the previous master: link the stuff to the new master */ |
| @@ -629,25 +634,41 @@ isdn_ppp_ioctl(int min, struct file *file, unsigned int cmd, unsigned long arg) · 241 unmodified lines | |||
| 629 | #ifdef CONFIG_IPPP_FILTER | 634 | #ifdef CONFIG_IPPP_FILTER |
| 630 | case PPPIOCSPASS: | 635 | case PPPIOCSPASS: |
| 631 | { | 636 | { |
| 637 | struct sock_fprog fprog; | ||
| 632 | struct sock_filter *code; | 638 | struct sock_filter *code; |
| 633 | int len = get_filter(argp, &code); | 639 | int err, len = get_filter(argp, &code); |
| 640 | |||
| 634 | if (len < 0) | 641 | if (len < 0) |
| 635 | return len; | 642 | return len; |
| 636 | kfree(is->pass_filter); | 643 | |
| 637 | is->pass_filter = code; | 644 | fprog.len = len; |
| 638 | is->pass_len = len; | 645 | fprog.filter = code; |
| 639 | break; | 646 | |
| 647 | if (is->pass_filter) | ||
| 648 | sk_unattached_filter_destroy(is->pass_filter); | ||
| 649 | err = sk_unattached_filter_create(&is->pass_filter, &fprog); | ||
| 650 | kfree(code); | ||
| 651 | |||
| 652 | return err; | ||
| 640 | } | 653 | } |
| 641 | case PPPIOCSACTIVE: | 654 | case PPPIOCSACTIVE: |
| 642 | { | 655 | { |
| 656 | struct sock_fprog fprog; | ||
| 643 | struct sock_filter *code; | 657 | struct sock_filter *code; |
| 644 | int len = get_filter(argp, &code); | 658 | int err, len = get_filter(argp, &code); |
| 659 | |||
| 645 | if (len < 0) | 660 | if (len < 0) |
| 646 | return len; | 661 | return len; |
| 647 | kfree(is->active_filter); | 662 | |
| 648 | is->active_filter = code; | 663 | fprog.len = len; |
| 649 | is->active_len = len; | 664 | fprog.filter = code; |
| 650 | break; | 665 | |
| 666 | if (is->active_filter) | ||
| 667 | sk_unattached_filter_destroy(is->active_filter); | ||
| 668 | err = sk_unattached_filter_create(&is->active_filter, &fprog); | ||
| 669 | kfree(code); | ||
| 670 | |||
| 671 | return err; | ||
| 651 | } | 672 | } |
| 652 | #endif /* CONFIG_IPPP_FILTER */ | 673 | #endif /* CONFIG_IPPP_FILTER */ |
| 653 | default: | 674 | default: |
| @@ -1147,14 +1168,14 @@ isdn_ppp_push_higher(isdn_net_dev *net_dev, isdn_net_local *lp, struct sk_buff * · 493 unmodified lines | |||
| 1147 | } | 1168 | } |
| 1148 | 1169 | ||
| 1149 | if (is->pass_filter | 1170 | if (is->pass_filter |
| 1150 | && sk_run_filter(skb, is->pass_filter) == 0) { | 1171 | && SK_RUN_FILTER(is->pass_filter, skb) == 0) { |
| 1151 | if (is->debug & 0x2) | 1172 | if (is->debug & 0x2) |
| 1152 | printk(KERN_DEBUG "IPPP: inbound frame filtered.\n"); | 1173 | printk(KERN_DEBUG "IPPP: inbound frame filtered.\n"); |
| 1153 | kfree_skb(skb); | 1174 | kfree_skb(skb); |
| 1154 | return; | 1175 | return; |
| 1155 | } | 1176 | } |
| 1156 | if (!(is->active_filter | 1177 | if (!(is->active_filter |
| 1157 | && sk_run_filter(skb, is->active_filter) == 0)) { | 1178 | && SK_RUN_FILTER(is->active_filter, skb) == 0)) { |
| 1158 | if (is->debug & 0x2) | 1179 | if (is->debug & 0x2) |
| 1159 | printk(KERN_DEBUG "IPPP: link-active filter: resetting huptimer.\n"); | 1180 | printk(KERN_DEBUG "IPPP: link-active filter: resetting huptimer.\n"); |
| 1160 | lp->huptimer = 0; | 1181 | lp->huptimer = 0; |
| @@ -1293,14 +1314,14 @@ isdn_ppp_xmit(struct sk_buff *skb, struct net_device *netdev) · 132 unmodified lines | |||
| 1293 | } | 1314 | } |
| 1294 | 1315 | ||
| 1295 | if (ipt->pass_filter | 1316 | if (ipt->pass_filter |
| 1296 | && sk_run_filter(skb, ipt->pass_filter) == 0) { | 1317 | && SK_RUN_FILTER(ipt->pass_filter, skb) == 0) { |
| 1297 | if (ipt->debug & 0x4) | 1318 | if (ipt->debug & 0x4) |
| 1298 | printk(KERN_DEBUG "IPPP: outbound frame filtered.\n"); | 1319 | printk(KERN_DEBUG "IPPP: outbound frame filtered.\n"); |
| 1299 | kfree_skb(skb); | 1320 | kfree_skb(skb); |
| 1300 | goto unlock; | 1321 | goto unlock; |
| 1301 | } | 1322 | } |
| 1302 | if (!(ipt->active_filter | 1323 | if (!(ipt->active_filter |
| 1303 | && sk_run_filter(skb, ipt->active_filter) == 0)) { | 1324 | && SK_RUN_FILTER(ipt->active_filter, skb) == 0)) { |
| 1304 | if (ipt->debug & 0x4) | 1325 | if (ipt->debug & 0x4) |
| 1305 | printk(KERN_DEBUG "IPPP: link-active filter: resetting huptimer.\n"); | 1326 | printk(KERN_DEBUG "IPPP: link-active filter: resetting huptimer.\n"); |
| 1306 | lp->huptimer = 0; | 1327 | lp->huptimer = 0; |
| @@ -1490,9 +1511,9 @@ int isdn_ppp_autodial_filter(struct sk_buff *skb, isdn_net_local *lp) · 183 unmodified lines | |||
| 1490 | } | 1511 | } |
| 1491 | 1512 | ||
| 1492 | drop |= is->pass_filter | 1513 | drop |= is->pass_filter |
| 1493 | && sk_run_filter(skb, is->pass_filter) == 0; | 1514 | && SK_RUN_FILTER(is->pass_filter, skb) == 0; |
| 1494 | drop |= is->active_filter | 1515 | drop |= is->active_filter |
| 1495 | && sk_run_filter(skb, is->active_filter) == 0; | 1516 | && SK_RUN_FILTER(is->active_filter, skb) == 0; |
| 1496 | 1517 | ||
| 1497 | skb_push(skb, IPPP_MAX_HEADER - 4); | 1518 | skb_push(skb, IPPP_MAX_HEADER - 4); |
| 1498 | return drop; | 1519 | return drop; |
| @@ -796,6 +796,7 @@ static void set_running_timeout(unsigned long ptr) · 795 unmodified lines | |||
| 796 | #endif | 796 | #endif |
| 797 | dev = (struct pcbit_dev *) ptr; | 797 | dev = (struct pcbit_dev *) ptr; |
| 798 | 798 | ||
| 799 | dev->l2_state = L2_DOWN; | ||
| 799 | wake_up_interruptible(&dev->set_running_wq); | 800 | wake_up_interruptible(&dev->set_running_wq); |
| 800 | } | 801 | } |
| 801 | 802 | ||
| @@ -818,7 +819,8 @@ static int set_protocol_running(struct pcbit_dev *dev) · 16 unmodified lines | |||
| 818 | 819 | ||
| 819 | add_timer(&dev->set_running_timer); | 820 | add_timer(&dev->set_running_timer); |
| 820 | 821 | ||
| 821 | interruptible_sleep_on(&dev->set_running_wq); | 822 | wait_event(dev->set_running_wq, dev->l2_state == L2_RUNNING || |
| 823 | dev->l2_state == L2_DOWN); | ||
| 822 | 824 | ||
| 823 | del_timer(&dev->set_running_timer); | 825 | del_timer(&dev->set_running_timer); |
| 824 | 826 | ||
| @@ -842,8 +844,6 @@ static int set_protocol_running(struct pcbit_dev *dev) · 17 unmodified lines | |||
| 842 | printk(KERN_DEBUG "pcbit: initialization failed\n"); | 844 | printk(KERN_DEBUG "pcbit: initialization failed\n"); |
| 843 | printk(KERN_DEBUG "pcbit: firmware not loaded\n"); | 845 | printk(KERN_DEBUG "pcbit: firmware not loaded\n"); |
| 844 | 846 | ||
| 845 | dev->l2_state = L2_DOWN; | ||
| 846 | |||
| 847 | #ifdef DEBUG | 847 | #ifdef DEBUG |
| 848 | printk(KERN_DEBUG "Bank3 = %02x\n", | 848 | printk(KERN_DEBUG "Bank3 = %02x\n", |
| 849 | readb(dev->sh_mem + BANK3)); | 849 | readb(dev->sh_mem + BANK3)); |
| @@ -390,8 +390,8 @@ static void __exit sc_exit(void) · 389 unmodified lines | |||
| 390 | /* | 390 | /* |
| 391 | * kill the timers | 391 | * kill the timers |
| 392 | */ | 392 | */ |
| 393 | del_timer(&(sc_adapter[i]->reset_timer)); | 393 | del_timer_sync(&(sc_adapter[i]->reset_timer)); |
| 394 | del_timer(&(sc_adapter[i]->stat_timer)); | 394 | del_timer_sync(&(sc_adapter[i]->stat_timer)); |
| 395 | 395 | ||
| 396 | /* | 396 | /* |
| 397 | * Tell I4L we're toast | 397 | * Tell I4L we're toast |
| @@ -177,11 +177,6 @@ config NETCONSOLE_DYNAMIC · 176 unmodified lines | |||
| 177 | config NETPOLL | 177 | config NETPOLL |
| 178 | def_bool NETCONSOLE | 178 | def_bool NETCONSOLE |
| 179 | 179 | ||
| 180 | config NETPOLL_TRAP | ||
| 181 | bool "Netpoll traffic trapping" | ||
| 182 | default n | ||
| 183 | depends on NETPOLL | ||
| 184 | |||
| 185 | config NET_POLL_CONTROLLER | 180 | config NET_POLL_CONTROLLER |
| 186 | def_bool NETPOLL | 181 | def_bool NETPOLL |
| 187 | 182 | ||
| @@ -768,11 +768,11 @@ static int ad_lacpdu_send(struct port *port) · 767 unmodified lines | |||
| 768 | 768 | ||
| 769 | lacpdu_header = (struct lacpdu_header *)skb_put(skb, length); | 769 | lacpdu_header = (struct lacpdu_header *)skb_put(skb, length); |
| 770 | 770 | ||
| 771 | memcpy(lacpdu_header->hdr.h_dest, lacpdu_mcast_addr, ETH_ALEN); | 771 | ether_addr_copy(lacpdu_header->hdr.h_dest, lacpdu_mcast_addr); |
| 772 | /* Note: source address is set to be the member's PERMANENT address, | 772 | /* Note: source address is set to be the member's PERMANENT address, |
| 773 | * because we use it to identify loopback lacpdus in receive. | 773 | * because we use it to identify loopback lacpdus in receive. |
| 774 | */ | 774 | */ |
| 775 | memcpy(lacpdu_header->hdr.h_source, slave->perm_hwaddr, ETH_ALEN); | 775 | ether_addr_copy(lacpdu_header->hdr.h_source, slave->perm_hwaddr); |
| 776 | lacpdu_header->hdr.h_proto = PKT_TYPE_LACPDU; | 776 | lacpdu_header->hdr.h_proto = PKT_TYPE_LACPDU; |
| 777 | 777 | ||
| 778 | lacpdu_header->lacpdu = port->lacpdu; | 778 | lacpdu_header->lacpdu = port->lacpdu; |
| @@ -810,11 +810,11 @@ static int ad_marker_send(struct port *port, struct bond_marker *marker) · 31 unmodified lines | |||
| 810 | 810 | ||
| 811 | marker_header = (struct bond_marker_header *)skb_put(skb, length); | 811 | marker_header = (struct bond_marker_header *)skb_put(skb, length); |
| 812 | 812 | ||
| 813 | memcpy(marker_header->hdr.h_dest, lacpdu_mcast_addr, ETH_ALEN); | 813 | ether_addr_copy(marker_header->hdr.h_dest, lacpdu_mcast_addr); |
| 814 | /* Note: source address is set to be the member's PERMANENT address, | 814 | /* Note: source address is set to be the member's PERMANENT address, |
| 815 | * because we use it to identify loopback MARKERs in receive. | 815 | * because we use it to identify loopback MARKERs in receive. |
| 816 | */ | 816 | */ |
| 817 | memcpy(marker_header->hdr.h_source, slave->perm_hwaddr, ETH_ALEN); | 817 | ether_addr_copy(marker_header->hdr.h_source, slave->perm_hwaddr); |
| 818 | marker_header->hdr.h_proto = PKT_TYPE_LACPDU; | 818 | marker_header->hdr.h_proto = PKT_TYPE_LACPDU; |
| 819 | 819 | ||
| 820 | marker_header->marker = *marker; | 820 | marker_header->marker = *marker; |
| @@ -1079,7 +1079,8 @@ static void ad_rx_machine(struct lacpdu *lacpdu, struct port *port) · 258 unmodified lines | |||
| 1079 | /* detect loopback situation */ | 1079 | /* detect loopback situation */ |
| 1080 | if (MAC_ADDRESS_EQUAL(&(lacpdu->actor_system), | 1080 | if (MAC_ADDRESS_EQUAL(&(lacpdu->actor_system), |
| 1081 | &(port->actor_system))) { | 1081 | &(port->actor_system))) { |
| 1082 | pr_err("%s: An illegal loopback occurred on adapter (%s).\nCheck the configuration to verify that all adapters are connected to 802.3ad compliant switch ports\n", | 1082 | pr_err("%s: An illegal loopback occurred on adapter (%s)\n" |
| 1083 | "Check the configuration to verify that all adapters are connected to 802.3ad compliant switch ports\n", | ||
| 1083 | port->slave->bond->dev->name, | 1084 | port->slave->bond->dev->name, |
| 1084 | port->slave->dev->name); | 1085 | port->slave->dev->name); |
| 1085 | return; | 1086 | return; |
| @@ -1283,11 +1284,11 @@ static void ad_port_selection_logic(struct port *port) · 197 unmodified lines | |||
| 1283 | /* meaning: the port was related to an aggregator | 1284 | /* meaning: the port was related to an aggregator |
| 1284 | * but was not on the aggregator port list | 1285 | * but was not on the aggregator port list |
| 1285 | */ | 1286 | */ |
| 1286 | pr_warn("%s: Warning: Port %d (on %s) was related to aggregator %d but was not on its port list\n", | 1287 | pr_warn_ratelimited("%s: Warning: Port %d (on %s) was related to aggregator %d but was not on its port list\n", |
| 1287 | port->slave->bond->dev->name, | 1288 | port->slave->bond->dev->name, |
| 1288 | port->actor_port_number, | 1289 | port->actor_port_number, |
| 1289 | port->slave->dev->name, | 1290 | port->slave->dev->name, |
| 1290 | port->aggregator->aggregator_identifier); | 1291 | port->aggregator->aggregator_identifier); |
| 1291 | } | 1292 | } |
| 1292 | } | 1293 | } |
| 1293 | /* search on all aggregators for a suitable aggregator for this port */ | 1294 | /* search on all aggregators for a suitable aggregator for this port */ |
| @@ -1444,9 +1445,9 @@ static struct aggregator *ad_agg_selection_test(struct aggregator *best, · 150 unmodified lines | |||
| 1444 | break; | 1445 | break; |
| 1445 | 1446 | ||
| 1446 | default: | 1447 | default: |
| 1447 | pr_warn("%s: Impossible agg select mode %d\n", | 1448 | pr_warn_ratelimited("%s: Impossible agg select mode %d\n", |
| 1448 | curr->slave->bond->dev->name, | 1449 | curr->slave->bond->dev->name, |
| 1449 | __get_agg_selection_mode(curr->lag_ports)); | 1450 | __get_agg_selection_mode(curr->lag_ports)); |
| 1450 | break; | 1451 | break; |
| 1451 | } | 1452 | } |
| 1452 | 1453 | ||
| @@ -1559,9 +1560,9 @@ static void ad_agg_selection_logic(struct aggregator *agg) · 106 unmodified lines | |||
| 1559 | 1560 | ||
| 1560 | /* check if any partner replys */ | 1561 | /* check if any partner replys */ |
| 1561 | if (best->is_individual) { | 1562 | if (best->is_individual) { |
| 1562 | pr_warn("%s: Warning: No 802.3ad response from the link partner for any adapters in the bond\n", | 1563 | pr_warn_ratelimited("%s: Warning: No 802.3ad response from the link partner for any adapters in the bond\n", |
| 1563 | best->slave ? | 1564 | best->slave ? |
| 1564 | best->slave->bond->dev->name : "NULL"); | 1565 | best->slave->bond->dev->name : "NULL"); |
| 1565 | } | 1566 | } |
| 1566 | 1567 | ||
| 1567 | best->is_active = 1; | 1568 | best->is_active = 1; |
| @@ -1948,7 +1949,7 @@ void bond_3ad_unbind_slave(struct slave *slave) · 380 unmodified lines | |||
| 1948 | * new aggregator | 1949 | * new aggregator |
| 1949 | */ | 1950 | */ |
| 1950 | if ((new_aggregator) && ((!new_aggregator->lag_ports) || ((new_aggregator->lag_ports == port) && !new_aggregator->lag_ports->next_port_in_aggregator))) { | 1951 | if ((new_aggregator) && ((!new_aggregator->lag_ports) || ((new_aggregator->lag_ports == port) && !new_aggregator->lag_ports->next_port_in_aggregator))) { |
| 1951 | pr_debug("Some port(s) related to LAG %d - replaceing with LAG %d\n", | 1952 | pr_debug("Some port(s) related to LAG %d - replacing with LAG %d\n", |
| 1952 | aggregator->aggregator_identifier, | 1953 | aggregator->aggregator_identifier, |
| 1953 | new_aggregator->aggregator_identifier); | 1954 | new_aggregator->aggregator_identifier); |
| 1954 | 1955 | ||
| @@ -2080,8 +2081,8 @@ void bond_3ad_state_machine_handler(struct work_struct *work) · 125 unmodified lines | |||
| 2080 | /* select the active aggregator for the bond */ | 2081 | /* select the active aggregator for the bond */ |
| 2081 | if (port) { | 2082 | if (port) { |
| 2082 | if (!port->slave) { | 2083 | if (!port->slave) { |
| 2083 | pr_warn("%s: Warning: bond's first port is uninitialized\n", | 2084 | pr_warn_ratelimited("%s: Warning: bond's first port is uninitialized\n", |
| 2084 | bond->dev->name); | 2085 | bond->dev->name); |
| 2085 | goto re_arm; | 2086 | goto re_arm; |
| 2086 | } | 2087 | } |
| 2087 | 2088 | ||
| @@ -2095,8 +2096,8 @@ void bond_3ad_state_machine_handler(struct work_struct *work) · 7 unmodified lines | |||
| 2095 | bond_for_each_slave_rcu(bond, slave, iter) { | 2096 | bond_for_each_slave_rcu(bond, slave, iter) { |
| 2096 | port = &(SLAVE_AD_INFO(slave).port); | 2097 | port = &(SLAVE_AD_INFO(slave).port); |
| 2097 | if (!port->slave) { | 2098 | if (!port->slave) { |
| 2098 | pr_warn("%s: Warning: Found an uninitialized port\n", | 2099 | pr_warn_ratelimited("%s: Warning: Found an uninitialized port\n", |
| 2099 | bond->dev->name); | 2100 | bond->dev->name); |
| 2100 | goto re_arm; | 2101 | goto re_arm; |
| 2101 | } | 2102 | } |
| 2102 | 2103 | ||
| @@ -2157,8 +2158,8 @@ static int bond_3ad_rx_indication(struct lacpdu *lacpdu, struct slave *slave, · 54 unmodified lines | |||
| 2157 | port = &(SLAVE_AD_INFO(slave).port); | 2158 | port = &(SLAVE_AD_INFO(slave).port); |
| 2158 | 2159 | ||
| 2159 | if (!port->slave) { | 2160 | if (!port->slave) { |
| 2160 | pr_warn("%s: Warning: port of slave %s is uninitialized\n", | 2161 | pr_warn_ratelimited("%s: Warning: port of slave %s is uninitialized\n", |
| 2161 | slave->dev->name, slave->bond->dev->name); | 2162 | slave->dev->name, slave->bond->dev->name); |
| 2162 | return ret; | 2163 | return ret; |
| 2163 | } | 2164 | } |
| 2164 | 2165 | ||
| @@ -2310,9 +2311,9 @@ void bond_3ad_handle_link_change(struct slave *slave, char link) · 145 unmodified lines | |||
| 2310 | port->actor_oper_port_key = (port->actor_admin_port_key &= | 2311 | port->actor_oper_port_key = (port->actor_admin_port_key &= |
| 2311 | ~AD_SPEED_KEY_BITS); | 2312 | ~AD_SPEED_KEY_BITS); |
| 2312 | } | 2313 | } |
| 2313 | pr_debug("Port %d changed link status to %s", | 2314 | pr_debug("Port %d changed link status to %s\n", |
| 2314 | port->actor_port_number, | 2315 | port->actor_port_number, |
| 2315 | (link == BOND_LINK_UP) ? "UP" : "DOWN"); | 2316 | link == BOND_LINK_UP ? "UP" : "DOWN"); |
| 2316 | /* there is no need to reselect a new aggregator, just signal the | 2317 | /* there is no need to reselect a new aggregator, just signal the |
| 2317 | * state machines to reinitialize | 2318 | * state machines to reinitialize |
| 2318 | */ | 2319 | */ |
| @@ -2390,17 +2391,16 @@ int __bond_3ad_get_active_agg_info(struct bonding *bond, · 71 unmodified lines | |||
| 2390 | } | 2391 | } |
| 2391 | } | 2392 | } |
| 2392 | 2393 | ||
| 2393 | if (aggregator) { | 2394 | if (!aggregator) |
| 2394 | ad_info->aggregator_id = aggregator->aggregator_identifier; | 2395 | return -1; |
| 2395 | ad_info->ports = aggregator->num_of_ports; | ||
| 2396 | ad_info->actor_key = aggregator->actor_oper_aggregator_key; | ||
| 2397 | ad_info->partner_key = aggregator->partner_oper_aggregator_key; | ||
| 2398 | memcpy(ad_info->partner_system, | ||
| 2399 | aggregator->partner_system.mac_addr_value, ETH_ALEN); | ||
| 2400 | return 0; | ||
| 2401 | } | ||
| 2402 | 2396 | ||
| 2403 | return -1; | 2397 | ad_info->aggregator_id = aggregator->aggregator_identifier; |
| 2398 | ad_info->ports = aggregator->num_of_ports; | ||
| 2399 | ad_info->actor_key = aggregator->actor_oper_aggregator_key; | ||
| 2400 | ad_info->partner_key = aggregator->partner_oper_aggregator_key; | ||
| 2401 | ether_addr_copy(ad_info->partner_system, | ||
| 2402 | aggregator->partner_system.mac_addr_value); | ||
| 2403 | return 0; | ||
| 2404 | } | 2404 | } |
| 2405 | 2405 | ||
| 2406 | /* Wrapper used to hold bond->lock so no slave manipulation can occur */ | 2406 | /* Wrapper used to hold bond->lock so no slave manipulation can occur */ |
| @@ -2479,7 +2479,7 @@ out: · 72 unmodified lines | |||
| 2479 | return NETDEV_TX_OK; | 2479 | return NETDEV_TX_OK; |
| 2480 | err_free: | 2480 | err_free: |
| 2481 | /* no suitable interface, frame not sent */ | 2481 | /* no suitable interface, frame not sent */ |
| 2482 | kfree_skb(skb); | 2482 | dev_kfree_skb_any(skb); |
| 2483 | goto out; | 2483 | goto out; |
| 2484 | } | 2484 | } |
| 2485 | 2485 | ||
| @@ -28,7 +28,7 @@ · 27 unmodified lines | |||
| 28 | #include <linux/netdevice.h> | 28 | #include <linux/netdevice.h> |
| 29 | #include <linux/if_ether.h> | 29 | #include <linux/if_ether.h> |
| 30 | 30 | ||
| 31 | // General definitions | 31 | /* General definitions */ |
| 32 | #define PKT_TYPE_LACPDU cpu_to_be16(ETH_P_SLOW) | 32 | #define PKT_TYPE_LACPDU cpu_to_be16(ETH_P_SLOW) |
| 33 | #define AD_TIMER_INTERVAL 100 /*msec*/ | 33 | #define AD_TIMER_INTERVAL 100 /*msec*/ |
| 34 | 34 | ||
| @@ -47,54 +47,54 @@ enum { · 12 unmodified lines | |||
| 47 | BOND_AD_COUNT = 2, | 47 | BOND_AD_COUNT = 2, |
| 48 | }; | 48 | }; |
| 49 | 49 | ||
| 50 | // rx machine states(43.4.11 in the 802.3ad standard) | 50 | /* rx machine states(43.4.11 in the 802.3ad standard) */ |
| 51 | typedef enum { | 51 | typedef enum { |
| 52 | AD_RX_DUMMY, | 52 | AD_RX_DUMMY, |
| 53 | AD_RX_INITIALIZE, // rx Machine | 53 | AD_RX_INITIALIZE, /* rx Machine */ |
| 54 | AD_RX_PORT_DISABLED, // rx Machine | 54 | AD_RX_PORT_DISABLED, /* rx Machine */ |
| 55 | AD_RX_LACP_DISABLED, // rx Machine | 55 | AD_RX_LACP_DISABLED, /* rx Machine */ |
| 56 | AD_RX_EXPIRED, // rx Machine | 56 | AD_RX_EXPIRED, /* rx Machine */ |
| 57 | AD_RX_DEFAULTED, // rx Machine | 57 | AD_RX_DEFAULTED, /* rx Machine */ |
| 58 | AD_RX_CURRENT // rx Machine | 58 | AD_RX_CURRENT /* rx Machine */ |
| 59 | } rx_states_t; | 59 | } rx_states_t; |
| 60 | 60 | ||
| 61 | // periodic machine states(43.4.12 in the 802.3ad standard) | 61 | /* periodic machine states(43.4.12 in the 802.3ad standard) */ |
| 62 | typedef enum { | 62 | typedef enum { |
| 63 | AD_PERIODIC_DUMMY, | 63 | AD_PERIODIC_DUMMY, |
| 64 | AD_NO_PERIODIC, // periodic machine | 64 | AD_NO_PERIODIC, /* periodic machine */ |
| 65 | AD_FAST_PERIODIC, // periodic machine | 65 | AD_FAST_PERIODIC, /* periodic machine */ |
| 66 | AD_SLOW_PERIODIC, // periodic machine | 66 | AD_SLOW_PERIODIC, /* periodic machine */ |
| 67 | AD_PERIODIC_TX // periodic machine | 67 | AD_PERIODIC_TX /* periodic machine */ |
| 68 | } periodic_states_t; | 68 | } periodic_states_t; |
| 69 | 69 | ||
| 70 | // mux machine states(43.4.13 in the 802.3ad standard) | 70 | /* mux machine states(43.4.13 in the 802.3ad standard) */ |
| 71 | typedef enum { | 71 | typedef enum { |
| 72 | AD_MUX_DUMMY, | 72 | AD_MUX_DUMMY, |
| 73 | AD_MUX_DETACHED, // mux machine | 73 | AD_MUX_DETACHED, /* mux machine */ |
| 74 | AD_MUX_WAITING, // mux machine | 74 | AD_MUX_WAITING, /* mux machine */ |
| 75 | AD_MUX_ATTACHED, // mux machine | 75 | AD_MUX_ATTACHED, /* mux machine */ |
| 76 | AD_MUX_COLLECTING_DISTRIBUTING // mux machine | 76 | AD_MUX_COLLECTING_DISTRIBUTING /* mux machine */ |
| 77 | } mux_states_t; | 77 | } mux_states_t; |
| 78 | 78 | ||
| 79 | // tx machine states(43.4.15 in the 802.3ad standard) | 79 | /* tx machine states(43.4.15 in the 802.3ad standard) */ |
| 80 | typedef enum { | 80 | typedef enum { |
| 81 | AD_TX_DUMMY, | 81 | AD_TX_DUMMY, |
| 82 | AD_TRANSMIT // tx Machine | 82 | AD_TRANSMIT /* tx Machine */ |
| 83 | } tx_states_t; | 83 | } tx_states_t; |
| 84 | 84 | ||
| 85 | // rx indication types | 85 | /* rx indication types */ |
| 86 | typedef enum { | 86 | typedef enum { |
| 87 | AD_TYPE_LACPDU = 1, // type lacpdu | 87 | AD_TYPE_LACPDU = 1, /* type lacpdu */ |
| 88 | AD_TYPE_MARKER // type marker | 88 | AD_TYPE_MARKER /* type marker */ |
| 89 | } pdu_type_t; | 89 | } pdu_type_t; |
| 90 | 90 | ||
| 91 | // rx marker indication types | 91 | /* rx marker indication types */ |
| 92 | typedef enum { | 92 | typedef enum { |
| 93 | AD_MARKER_INFORMATION_SUBTYPE = 1, // marker imformation subtype | 93 | AD_MARKER_INFORMATION_SUBTYPE = 1, /* marker imformation subtype */ |
| 94 | AD_MARKER_RESPONSE_SUBTYPE // marker response subtype | 94 | AD_MARKER_RESPONSE_SUBTYPE /* marker response subtype */ |
| 95 | } bond_marker_subtype_t; | 95 | } bond_marker_subtype_t; |
| 96 | 96 | ||
| 97 | // timers types(43.4.9 in the 802.3ad standard) | 97 | /* timers types(43.4.9 in the 802.3ad standard) */ |
| 98 | typedef enum { | 98 | typedef enum { |
| 99 | AD_CURRENT_WHILE_TIMER, | 99 | AD_CURRENT_WHILE_TIMER, |
| 100 | AD_ACTOR_CHURN_TIMER, | 100 | AD_ACTOR_CHURN_TIMER, |
| @@ -105,35 +105,35 @@ typedef enum { · 4 unmodified lines | |||
| 105 | 105 | ||
| 106 | #pragma pack(1) | 106 | #pragma pack(1) |
| 107 | 107 | ||
| 108 | // Link Aggregation Control Protocol(LACP) data unit structure(43.4.2.2 in the 802.3ad standard) | 108 | /* Link Aggregation Control Protocol(LACP) data unit structure(43.4.2.2 in the 802.3ad standard) */ |
| 109 | typedef struct lacpdu { | 109 | typedef struct lacpdu { |
| 110 | u8 subtype; // = LACP(= 0x01) | 110 | u8 subtype; /* = LACP(= 0x01) */ |
| 111 | u8 version_number; | 111 | u8 version_number; |
| 112 | u8 tlv_type_actor_info; // = actor information(type/length/value) | 112 | u8 tlv_type_actor_info; /* = actor information(type/length/value) */ |
| 113 | u8 actor_information_length; // = 20 | 113 | u8 actor_information_length; /* = 20 */ |
| 114 | __be16 actor_system_priority; | 114 | __be16 actor_system_priority; |
| 115 | struct mac_addr actor_system; | 115 | struct mac_addr actor_system; |
| 116 | __be16 actor_key; | 116 | __be16 actor_key; |
| 117 | __be16 actor_port_priority; | 117 | __be16 actor_port_priority; |
| 118 | __be16 actor_port; | 118 | __be16 actor_port; |
| 119 | u8 actor_state; | 119 | u8 actor_state; |
| 120 | u8 reserved_3_1[3]; // = 0 | 120 | u8 reserved_3_1[3]; /* = 0 */ |
| 121 | u8 tlv_type_partner_info; // = partner information | 121 | u8 tlv_type_partner_info; /* = partner information */ |
| 122 | u8 partner_information_length; // = 20 | 122 | u8 partner_information_length; /* = 20 */ |
| 123 | __be16 partner_system_priority; | 123 | __be16 partner_system_priority; |
| 124 | struct mac_addr partner_system; | 124 | struct mac_addr partner_system; |
| 125 | __be16 partner_key; | 125 | __be16 partner_key; |
| 126 | __be16 partner_port_priority; | 126 | __be16 partner_port_priority; |
| 127 | __be16 partner_port; | 127 | __be16 partner_port; |
| 128 | u8 partner_state; | 128 | u8 partner_state; |
| 129 | u8 reserved_3_2[3]; // = 0 | 129 | u8 reserved_3_2[3]; /* = 0 */ |
| 130 | u8 tlv_type_collector_info; // = collector information | 130 | u8 tlv_type_collector_info; /* = collector information */ |
| 131 | u8 collector_information_length; // = 16 | 131 | u8 collector_information_length;/* = 16 */ |
| 132 | __be16 collector_max_delay; | 132 | __be16 collector_max_delay; |
| 133 | u8 reserved_12[12]; | 133 | u8 reserved_12[12]; |
| 134 | u8 tlv_type_terminator; // = terminator | 134 | u8 tlv_type_terminator; /* = terminator */ |
| 135 | u8 terminator_length; // = 0 | 135 | u8 terminator_length; /* = 0 */ |
| 136 | u8 reserved_50[50]; // = 0 | 136 | u8 reserved_50[50]; /* = 0 */ |
| 137 | } __packed lacpdu_t; | 137 | } __packed lacpdu_t; |
| 138 | 138 | ||
| 139 | typedef struct lacpdu_header { | 139 | typedef struct lacpdu_header { |
| @@ -141,20 +141,20 @@ typedef struct lacpdu_header { · 1 unmodified line | |||
| 141 | struct lacpdu lacpdu; | 141 | struct lacpdu lacpdu; |
| 142 | } __packed lacpdu_header_t; | 142 | } __packed lacpdu_header_t; |
| 143 | 143 | ||
| 144 | // Marker Protocol Data Unit(PDU) structure(43.5.3.2 in the 802.3ad standard) | 144 | /* Marker Protocol Data Unit(PDU) structure(43.5.3.2 in the 802.3ad standard) */ |
| 145 | typedef struct bond_marker { | 145 | typedef struct bond_marker { |
| 146 | u8 subtype; // = 0x02 (marker PDU) | 146 | u8 subtype; /* = 0x02 (marker PDU) */ |
| 147 | u8 version_number; // = 0x01 | 147 | u8 version_number; /* = 0x01 */ |
| 148 | u8 tlv_type; // = 0x01 (marker information) | 148 | u8 tlv_type; /* = 0x01 (marker information) */ |
| 149 | // = 0x02 (marker response information) | 149 | /* = 0x02 (marker response information) */ |
| 150 | u8 marker_length; // = 0x16 | 150 | u8 marker_length; /* = 0x16 */ |
| 151 | u16 requester_port; // The number assigned to the port by the requester | 151 | u16 requester_port; /* The number assigned to the port by the requester */ |
| 152 | struct mac_addr requester_system; // The requester's system id | 152 | struct mac_addr requester_system; /* The requester's system id */ |
| 153 | u32 requester_transaction_id; // The transaction id allocated by the requester, | 153 | u32 requester_transaction_id; /* The transaction id allocated by the requester, */ |
| 154 | u16 pad; // = 0 | 154 | u16 pad; /* = 0 */ |
| 155 | u8 tlv_type_terminator; // = 0x00 | 155 | u8 tlv_type_terminator; /* = 0x00 */ |
| 156 | u8 terminator_length; // = 0x00 | 156 | u8 terminator_length; /* = 0x00 */ |
| 157 | u8 reserved_90[90]; // = 0 | 157 | u8 reserved_90[90]; /* = 0 */ |
| 158 | } __packed bond_marker_t; | 158 | } __packed bond_marker_t; |
| 159 | 159 | ||
| 160 | typedef struct bond_marker_header { | 160 | typedef struct bond_marker_header { |
| @@ -173,7 +173,7 @@ struct port; · 12 unmodified lines | |||
| 173 | #pragma pack(8) | 173 | #pragma pack(8) |
| 174 | #endif | 174 | #endif |
| 175 | 175 | ||
| 176 | // aggregator structure(43.4.5 in the 802.3ad standard) | 176 | /* aggregator structure(43.4.5 in the 802.3ad standard) */ |
| 177 | typedef struct aggregator { | 177 | typedef struct aggregator { |
| 178 | struct mac_addr aggregator_mac_address; | 178 | struct mac_addr aggregator_mac_address; |
| 179 | u16 aggregator_identifier; | 179 | u16 aggregator_identifier; |
| @@ -183,12 +183,12 @@ typedef struct aggregator { · 3 unmodified lines | |||
| 183 | struct mac_addr partner_system; | 183 | struct mac_addr partner_system; |
| 184 | u16 partner_system_priority; | 184 | u16 partner_system_priority; |
| 185 | u16 partner_oper_aggregator_key; | 185 | u16 partner_oper_aggregator_key; |
| 186 | u16 receive_state; // BOOLEAN | 186 | u16 receive_state; /* BOOLEAN */ |
| 187 | u16 transmit_state; // BOOLEAN | 187 | u16 transmit_state; /* BOOLEAN */ |
| 188 | struct port *lag_ports; | 188 | struct port *lag_ports; |
| 189 | // ****** PRIVATE PARAMETERS ****** | 189 | /* ****** PRIVATE PARAMETERS ****** */ |
| 190 | struct slave *slave; // pointer to the bond slave that this aggregator belongs to | 190 | struct slave *slave; /* pointer to the bond slave that this aggregator belongs to */ |
| 191 | u16 is_active; // BOOLEAN. Indicates if this aggregator is active | 191 | u16 is_active; /* BOOLEAN. Indicates if this aggregator is active */ |
| 192 | u16 num_of_ports; | 192 | u16 num_of_ports; |
| 193 | } aggregator_t; | 193 | } aggregator_t; |
| 194 | 194 | ||
| @@ -201,12 +201,12 @@ struct port_params { · 6 unmodified lines | |||
| 201 | u16 port_state; | 201 | u16 port_state; |
| 202 | }; | 202 | }; |
| 203 | 203 | ||
| 204 | // port structure(43.4.6 in the 802.3ad standard) | 204 | /* port structure(43.4.6 in the 802.3ad standard) */ |
| 205 | typedef struct port { | 205 | typedef struct port { |
| 206 | u16 actor_port_number; | 206 | u16 actor_port_number; |
| 207 | u16 actor_port_priority; | 207 | u16 actor_port_priority; |
| 208 | struct mac_addr actor_system; // This parameter is added here although it is not specified in the standard, just for simplification | 208 | struct mac_addr actor_system; /* This parameter is added here although it is not specified in the standard, just for simplification */ |
| 209 | u16 actor_system_priority; // This parameter is added here although it is not specified in the standard, just for simplification | 209 | u16 actor_system_priority; /* This parameter is added here although it is not specified in the standard, just for simplification */ |
| 210 | u16 actor_port_aggregator_identifier; | 210 | u16 actor_port_aggregator_identifier; |
| 211 | bool ntt; | 211 | bool ntt; |
| 212 | u16 actor_admin_port_key; | 212 | u16 actor_admin_port_key; |
| @@ -219,24 +219,24 @@ typedef struct port { · 6 unmodified lines | |||
| 219 | 219 | ||
| 220 | bool is_enabled; | 220 | bool is_enabled; |
| 221 | 221 | ||
| 222 | // ****** PRIVATE PARAMETERS ****** | 222 | /* ****** PRIVATE PARAMETERS ****** */ |
| 223 | u16 sm_vars; // all state machines variables for this port | 223 | u16 sm_vars; /* all state machines variables for this port */ |
| 224 | rx_states_t sm_rx_state; // state machine rx state | 224 | rx_states_t sm_rx_state; /* state machine rx state */ |
| 225 | u16 sm_rx_timer_counter; // state machine rx timer counter | 225 | u16 sm_rx_timer_counter; /* state machine rx timer counter */ |
| 226 | periodic_states_t sm_periodic_state;// state machine periodic state | 226 | periodic_states_t sm_periodic_state; /* state machine periodic state */ |
| 227 | u16 sm_periodic_timer_counter; // state machine periodic timer counter | 227 | u16 sm_periodic_timer_counter; /* state machine periodic timer counter */ |
| 228 | mux_states_t sm_mux_state; // state machine mux state | 228 | mux_states_t sm_mux_state; /* state machine mux state */ |
| 229 | u16 sm_mux_timer_counter; // state machine mux timer counter | 229 | u16 sm_mux_timer_counter; /* state machine mux timer counter */ |
| 230 | tx_states_t sm_tx_state; // state machine tx state | 230 | tx_states_t sm_tx_state; /* state machine tx state */ |
| 231 | u16 sm_tx_timer_counter; // state machine tx timer counter(allways on - enter to transmit state 3 time per second) | 231 | u16 sm_tx_timer_counter; /* state machine tx timer counter(allways on - enter to transmit state 3 time per second) */ |
| 232 | struct slave *slave; // pointer to the bond slave that this port belongs to | 232 | struct slave *slave; /* pointer to the bond slave that this port belongs to */ |
| 233 | struct aggregator *aggregator; // pointer to an aggregator that this port related to | 233 | struct aggregator *aggregator; /* pointer to an aggregator that this port related to */ |
| 234 | struct port *next_port_in_aggregator; // Next port on the linked list of the parent aggregator | 234 | struct port *next_port_in_aggregator; /* Next port on the linked list of the parent aggregator */ |
| 235 | u32 transaction_id; // continuous number for identification of Marker PDU's; | 235 | u32 transaction_id; /* continuous number for identification of Marker PDU's; */ |
| 236 | struct lacpdu lacpdu; // the lacpdu that will be sent for this port | 236 | struct lacpdu lacpdu; /* the lacpdu that will be sent for this port */ |
| 237 | } port_t; | 237 | } port_t; |
| 238 | 238 | ||
| 239 | // system structure | 239 | /* system structure */ |
| 240 | struct ad_system { | 240 | struct ad_system { |
| 241 | u16 sys_priority; | 241 | u16 sys_priority; |
| 242 | struct mac_addr sys_mac_addr; | 242 | struct mac_addr sys_mac_addr; |
| @@ -246,27 +246,26 @@ struct ad_system { · 3 unmodified lines | |||
| 246 | #pragma pack() | 246 | #pragma pack() |
| 247 | #endif | 247 | #endif |
| 248 | 248 | ||
| 249 | // ================= AD Exported structures to the main bonding code ================== | 249 | /* ========== AD Exported structures to the main bonding code ========== */ |
| 250 | #define BOND_AD_INFO(bond) ((bond)->ad_info) | 250 | #define BOND_AD_INFO(bond) ((bond)->ad_info) |
| 251 | #define SLAVE_AD_INFO(slave) ((slave)->ad_info) | 251 | #define SLAVE_AD_INFO(slave) ((slave)->ad_info) |
| 252 | 252 | ||
| 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 | u16 aggregator_identifier; |
| 257 | }; | 257 | }; |
| 258 | 258 | ||
| 259 | struct ad_slave_info { | 259 | struct ad_slave_info { |
| 260 | struct aggregator aggregator; // 802.3ad aggregator structure | 260 | struct aggregator aggregator; /* 802.3ad aggregator structure */ |
| 261 | struct port port; // 802.3ad port structure | 261 | struct port port; /* 802.3ad port structure */ |
| 262 | spinlock_t state_machine_lock; /* mutex state machines vs. | 262 | spinlock_t state_machine_lock; /* mutex state machines vs. incoming LACPDU */ |
| 263 | incoming LACPDU */ | ||
| 264 | u16 id; | 263 | u16 id; |
| 265 | }; | 264 | }; |
| 266 | 265 | ||
| 267 | // ================= AD Exported functions to the main bonding code ================== | 266 | /* ========== AD Exported functions to the main bonding code ========== */ |
| 268 | void bond_3ad_initialize(struct bonding *bond, u16 tick_resolution); | 267 | void bond_3ad_initialize(struct bonding *bond, u16 tick_resolution); |
| 269 | void bond_3ad_bind_slave(struct slave *slave); | 268 | void bond_3ad_bind_slave(struct slave *slave); |
| 270 | void bond_3ad_unbind_slave(struct slave *slave); | 269 | void bond_3ad_unbind_slave(struct slave *slave); |
| 271 | void bond_3ad_state_machine_handler(struct work_struct *); | 270 | void bond_3ad_state_machine_handler(struct work_struct *); |
| 272 | void bond_3ad_initiate_agg_selection(struct bonding *bond, int timeout); | 271 | void bond_3ad_initiate_agg_selection(struct bonding *bond, int timeout); |
| @@ -281,5 +280,5 @@ int bond_3ad_lacpdu_recv(const struct sk_buff *skb, struct bonding *bond, · 8 unmodified lines | |||
| 281 | struct slave *slave); | 280 | struct slave *slave); |
| 282 | int bond_3ad_set_carrier(struct bonding *bond); | 281 | int bond_3ad_set_carrier(struct bonding *bond); |
| 283 | void bond_3ad_update_lacp_rate(struct bonding *bond); | 282 | void bond_3ad_update_lacp_rate(struct bonding *bond); |
| 284 | #endif //__BOND_3AD_H__ | 283 | #endif /* __BOND_3AD_H__ */ |
| 285 | 284 | ||
| @@ -93,9 +93,8 @@ static inline u8 _simple_hash(const u8 *hash_start, int hash_size) · 92 unmodified lines | |||
| 93 | int i; | 93 | int i; |
| 94 | u8 hash = 0; | 94 | u8 hash = 0; |
| 95 | 95 | ||
| 96 | for (i = 0; i < hash_size; i++) { | 96 | for (i = 0; i < hash_size; i++) |
| 97 | hash ^= hash_start[i]; | 97 | hash ^= hash_start[i]; |
| 98 | } | ||
| 99 | 98 | ||
| 100 | return hash; | 99 | return hash; |
| 101 | } | 100 | } |
| @@ -190,9 +189,8 @@ static int tlb_initialize(struct bonding *bond) · 88 unmodified lines | |||
| 190 | 189 | ||
| 191 | bond_info->tx_hashtbl = new_hashtbl; | 190 | bond_info->tx_hashtbl = new_hashtbl; |
| 192 | 191 | ||
| 193 | for (i = 0; i < TLB_HASH_TABLE_SIZE; i++) { | 192 | for (i = 0; i < TLB_HASH_TABLE_SIZE; i++) |
| 194 | tlb_init_table_entry(&bond_info->tx_hashtbl[i], 0); | 193 | tlb_init_table_entry(&bond_info->tx_hashtbl[i], 0); |
| 195 | } | ||
| 196 | 194 | ||
| 197 | _unlock_tx_hashtbl_bh(bond); | 195 | _unlock_tx_hashtbl_bh(bond); |
| 198 | 196 | ||
| @@ -264,9 +262,8 @@ static struct slave *__tlb_choose_channel(struct bonding *bond, u32 hash_index, · 65 unmodified lines | |||
| 264 | hash_table[hash_index].next = next_index; | 262 | hash_table[hash_index].next = next_index; |
| 265 | hash_table[hash_index].prev = TLB_NULL_INDEX; | 263 | hash_table[hash_index].prev = TLB_NULL_INDEX; |
| 266 | 264 | ||
| 267 | if (next_index != TLB_NULL_INDEX) { | 265 | if (next_index != TLB_NULL_INDEX) |
| 268 | hash_table[next_index].prev = hash_index; | 266 | hash_table[next_index].prev = hash_index; |
| 269 | } | ||
| 270 | 267 | ||
| 271 | slave_info->head = hash_index; | 268 | slave_info->head = hash_index; |
| 272 | slave_info->load += | 269 | slave_info->load += |
| @@ -274,9 +271,8 @@ static struct slave *__tlb_choose_channel(struct bonding *bond, u32 hash_index, · 1 unmodified line | |||
| 274 | } | 271 | } |
| 275 | } | 272 | } |
| 276 | 273 | ||
| 277 | if (assigned_slave) { | 274 | if (assigned_slave) |
| 278 | hash_table[hash_index].tx_bytes += skb_len; | 275 | hash_table[hash_index].tx_bytes += skb_len; |
| 279 | } | ||
| 280 | 276 | ||
| 281 | return assigned_slave; | 277 | return assigned_slave; |
| 282 | } | 278 | } |
| @@ -329,7 +325,7 @@ static void rlb_update_entry_from_arp(struct bonding *bond, struct arp_pkt *arp) · 46 unmodified lines | |||
| 329 | 325 | ||
| 330 | _lock_rx_hashtbl_bh(bond); | 326 | _lock_rx_hashtbl_bh(bond); |
| 331 | 327 | ||
| 332 | hash_index = _simple_hash((u8*)&(arp->ip_src), sizeof(arp->ip_src)); | 328 | hash_index = _simple_hash((u8 *)&(arp->ip_src), sizeof(arp->ip_src)); |
| 333 | client_info = &(bond_info->rx_hashtbl[hash_index]); | 329 | client_info = &(bond_info->rx_hashtbl[hash_index]); |
| 334 | 330 | ||
| 335 | if ((client_info->assigned) && | 331 | if ((client_info->assigned) && |
| @@ -337,7 +333,7 @@ static void rlb_update_entry_from_arp(struct bonding *bond, struct arp_pkt *arp) · 1 unmodified line | |||
| 337 | (client_info->ip_dst == arp->ip_src) && | 333 | (client_info->ip_dst == arp->ip_src) && |
| 338 | (!ether_addr_equal_64bits(client_info->mac_dst, arp->mac_src))) { | 334 | (!ether_addr_equal_64bits(client_info->mac_dst, arp->mac_src))) { |
| 339 | /* update the clients MAC address */ | 335 | /* update the clients MAC address */ |
| 340 | memcpy(client_info->mac_dst, arp->mac_src, ETH_ALEN); | 336 | ether_addr_copy(client_info->mac_dst, arp->mac_src); |
| 341 | client_info->ntt = 1; | 337 | client_info->ntt = 1; |
| 342 | bond_info->rx_ntt = 1; | 338 | bond_info->rx_ntt = 1; |
| 343 | } | 339 | } |
| @@ -451,9 +447,8 @@ static struct slave *__rlb_next_rx_slave(struct bonding *bond) · 107 unmodified lines | |||
| 451 | */ | 447 | */ |
| 452 | static void rlb_teach_disabled_mac_on_primary(struct bonding *bond, u8 addr[]) | 448 | static void rlb_teach_disabled_mac_on_primary(struct bonding *bond, u8 addr[]) |
| 453 | { | 449 | { |
| 454 | if (!bond->curr_active_slave) { | 450 | if (!bond->curr_active_slave) |
| 455 | return; | 451 | return; |
| 456 | } | ||
| 457 | 452 | ||
| 458 | if (!bond->alb_info.primary_is_promisc) { | 453 | if (!bond->alb_info.primary_is_promisc) { |
| 459 | if (!dev_set_promiscuity(bond->curr_active_slave->dev, 1)) | 454 | if (!dev_set_promiscuity(bond->curr_active_slave->dev, 1)) |
| @@ -513,9 +508,8 @@ static void rlb_clear_slave(struct bonding *bond, struct slave *slave) · 53 unmodified lines | |||
| 513 | 508 | ||
| 514 | write_lock_bh(&bond->curr_slave_lock); | 509 | write_lock_bh(&bond->curr_slave_lock); |
| 515 | 510 | ||
| 516 | if (slave != bond->curr_active_slave) { | 511 | if (slave != bond->curr_active_slave) |
| 517 | rlb_teach_disabled_mac_on_primary(bond, slave->dev->dev_addr); | 512 | rlb_teach_disabled_mac_on_primary(bond, slave->dev->dev_addr); |
| 518 | } | ||
| 519 | 513 | ||
| 520 | write_unlock_bh(&bond->curr_slave_lock); | 514 | write_unlock_bh(&bond->curr_slave_lock); |
| 521 | } | 515 | } |
| @@ -524,9 +518,8 @@ static void rlb_update_client(struct rlb_client_info *client_info) · 2 unmodified lines | |||
| 524 | { | 518 | { |
| 525 | int i; | 519 | int i; |
| 526 | 520 | ||
| 527 | if (!client_info->slave) { | 521 | if (!client_info->slave) |
| 528 | return; | 522 | return; |
| 529 | } | ||
| 530 | 523 | ||
| 531 | for (i = 0; i < RLB_ARP_BURST_SIZE; i++) { | 524 | for (i = 0; i < RLB_ARP_BURST_SIZE; i++) { |
| 532 | struct sk_buff *skb; | 525 | struct sk_buff *skb; |
| @@ -574,9 +567,8 @@ static void rlb_update_rx_clients(struct bonding *bond) · 41 unmodified lines | |||
| 574 | client_info = &(bond_info->rx_hashtbl[hash_index]); | 567 | client_info = &(bond_info->rx_hashtbl[hash_index]); |
| 575 | if (client_info->ntt) { | 568 | if (client_info->ntt) { |
| 576 | rlb_update_client(client_info); | 569 | rlb_update_client(client_info); |
| 577 | if (bond_info->rlb_update_retry_counter == 0) { | 570 | if (bond_info->rlb_update_retry_counter == 0) |
| 578 | client_info->ntt = 0; | 571 | client_info->ntt = 0; |
| 579 | } | ||
| 580 | } | 572 | } |
| 581 | } | 573 | } |
| 582 | 574 | ||
| @@ -610,10 +602,10 @@ static void rlb_req_update_slave_clients(struct bonding *bond, struct slave *sla · 27 unmodified lines | |||
| 610 | } | 602 | } |
| 611 | } | 603 | } |
| 612 | 604 | ||
| 613 | // update the team's flag only after the whole iteration | 605 | /* update the team's flag only after the whole iteration */ |
| 614 | if (ntt) { | 606 | if (ntt) { |
| 615 | bond_info->rx_ntt = 1; | 607 | bond_info->rx_ntt = 1; |
| 616 | //fasten the change | 608 | /* fasten the change */ |
| 617 | bond_info->rlb_update_retry_counter = RLB_UPDATE_RETRY; | 609 | bond_info->rlb_update_retry_counter = RLB_UPDATE_RETRY; |
| 618 | } | 610 | } |
| 619 | 611 | ||
| @@ -677,9 +669,9 @@ static struct slave *rlb_choose_channel(struct sk_buff *skb, struct bonding *bon · 57 unmodified lines | |||
| 677 | /* the entry is already assigned to this client */ | 669 | /* the entry is already assigned to this client */ |
| 678 | if (!ether_addr_equal_64bits(arp->mac_dst, mac_bcast)) { | 670 | if (!ether_addr_equal_64bits(arp->mac_dst, mac_bcast)) { |
| 679 | /* update mac address from arp */ | 671 | /* update mac address from arp */ |
| 680 | memcpy(client_info->mac_dst, arp->mac_dst, ETH_ALEN); | 672 | ether_addr_copy(client_info->mac_dst, arp->mac_dst); |
| 681 | } | 673 | } |
| 682 | memcpy(client_info->mac_src, arp->mac_src, ETH_ALEN); | 674 | ether_addr_copy(client_info->mac_src, arp->mac_src); |
| 683 | 675 | ||
| 684 | assigned_slave = client_info->slave; | 676 | assigned_slave = client_info->slave; |
| 685 | if (assigned_slave) { | 677 | if (assigned_slave) { |
| @@ -719,8 +711,8 @@ static struct slave *rlb_choose_channel(struct sk_buff *skb, struct bonding *bon · 33 unmodified lines | |||
| 719 | * will be updated with clients actual unicast mac address | 711 | * will be updated with clients actual unicast mac address |
| 720 | * upon receiving an arp reply. | 712 | * upon receiving an arp reply. |
| 721 | */ | 713 | */ |
| 722 | memcpy(client_info->mac_dst, arp->mac_dst, ETH_ALEN); | 714 | ether_addr_copy(client_info->mac_dst, arp->mac_dst); |
| 723 | memcpy(client_info->mac_src, arp->mac_src, ETH_ALEN); | 715 | ether_addr_copy(client_info->mac_src, arp->mac_src); |
| 724 | client_info->slave = assigned_slave; | 716 | client_info->slave = assigned_slave; |
| 725 | 717 | ||
| 726 | if (!ether_addr_equal_64bits(client_info->mac_dst, mac_bcast)) { | 718 | if (!ether_addr_equal_64bits(client_info->mac_dst, mac_bcast)) { |
| @@ -770,9 +762,8 @@ static struct slave *rlb_arp_xmit(struct sk_buff *skb, struct bonding *bond) · 43 unmodified lines | |||
| 770 | * rx channel | 762 | * rx channel |
| 771 | */ | 763 | */ |
| 772 | tx_slave = rlb_choose_channel(skb, bond); | 764 | tx_slave = rlb_choose_channel(skb, bond); |
| 773 | if (tx_slave) { | 765 | if (tx_slave) |
| 774 | memcpy(arp->mac_src,tx_slave->dev->dev_addr, ETH_ALEN); | 766 | ether_addr_copy(arp->mac_src, tx_slave->dev->dev_addr); |
| 775 | } | ||
| 776 | pr_debug("Server sent ARP Reply packet\n"); | 767 | pr_debug("Server sent ARP Reply packet\n"); |
| 777 | } else if (arp->op_code == htons(ARPOP_REQUEST)) { | 768 | } else if (arp->op_code == htons(ARPOP_REQUEST)) { |
| 778 | /* Create an entry in the rx_hashtbl for this client as a | 769 | /* Create an entry in the rx_hashtbl for this client as a |
| @@ -824,9 +815,8 @@ static void rlb_rebalance(struct bonding *bond) · 45 unmodified lines | |||
| 824 | } | 815 | } |
| 825 | 816 | ||
| 826 | /* update the team's flag only after the whole iteration */ | 817 | /* update the team's flag only after the whole iteration */ |
| 827 | if (ntt) { | 818 | if (ntt) |
| 828 | bond_info->rx_ntt = 1; | 819 | bond_info->rx_ntt = 1; |
| 829 | } | ||
| 830 | _unlock_rx_hashtbl_bh(bond); | 820 | _unlock_rx_hashtbl_bh(bond); |
| 831 | } | 821 | } |
| 832 | 822 | ||
| @@ -923,7 +913,7 @@ static void rlb_src_link(struct bonding *bond, u32 ip_src_hash, u32 ip_dst_hash) · 90 unmodified lines | |||
| 923 | static void rlb_purge_src_ip(struct bonding *bond, struct arp_pkt *arp) | 913 | static void rlb_purge_src_ip(struct bonding *bond, struct arp_pkt *arp) |
| 924 | { | 914 | { |
| 925 | struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond)); | 915 | struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond)); |
| 926 | u32 ip_src_hash = _simple_hash((u8*)&(arp->ip_src), sizeof(arp->ip_src)); | 916 | u32 ip_src_hash = _simple_hash((u8 *)&(arp->ip_src), sizeof(arp->ip_src)); |
| 927 | u32 index; | 917 | u32 index; |
| 928 | 918 | ||
| 929 | _lock_rx_hashtbl_bh(bond); | 919 | _lock_rx_hashtbl_bh(bond); |
| @@ -957,9 +947,8 @@ static int rlb_initialize(struct bonding *bond) · 27 unmodified lines | |||
| 957 | 947 | ||
| 958 | bond_info->rx_hashtbl_used_head = RLB_NULL_INDEX; | 948 | bond_info->rx_hashtbl_used_head = RLB_NULL_INDEX; |
| 959 | 949 | ||
| 960 | for (i = 0; i < RLB_HASH_TABLE_SIZE; i++) { | 950 | for (i = 0; i < RLB_HASH_TABLE_SIZE; i++) |
| 961 | rlb_init_table_entry(bond_info->rx_hashtbl + i); | 951 | rlb_init_table_entry(bond_info->rx_hashtbl + i); |
| 962 | } | ||
| 963 | 952 | ||
| 964 | _unlock_rx_hashtbl_bh(bond); | 953 | _unlock_rx_hashtbl_bh(bond); |
| 965 | 954 | ||
| @@ -1014,9 +1003,9 @@ static void alb_send_lp_vid(struct slave *slave, u8 mac_addr[], · 48 unmodified lines | |||
| 1014 | char *data; | 1003 | char *data; |
| 1015 | 1004 | ||
| 1016 | memset(&pkt, 0, size); | 1005 | memset(&pkt, 0, size); |
| 1017 | memcpy(pkt.mac_dst, mac_addr, ETH_ALEN); | 1006 | ether_addr_copy(pkt.mac_dst, mac_addr); |
| 1018 | memcpy(pkt.mac_src, mac_addr, ETH_ALEN); | 1007 | ether_addr_copy(pkt.mac_src, mac_addr); |
| 1019 | pkt.type = cpu_to_be16(ETH_P_LOOP); | 1008 | pkt.type = cpu_to_be16(ETH_P_LOOPBACK); |
| 1020 | 1009 | ||
| 1021 | skb = dev_alloc_skb(size); | 1010 | skb = dev_alloc_skb(size); |
| 1022 | if (!skb) | 1011 | if (!skb) |
| @@ -1097,7 +1086,7 @@ static void alb_swap_mac_addr(struct slave *slave1, struct slave *slave2) · 74 unmodified lines | |||
| 1097 | { | 1086 | { |
| 1098 | u8 tmp_mac_addr[ETH_ALEN]; | 1087 | u8 tmp_mac_addr[ETH_ALEN]; |
| 1099 | 1088 | ||
| 1100 | memcpy(tmp_mac_addr, slave1->dev->dev_addr, ETH_ALEN); | 1089 | ether_addr_copy(tmp_mac_addr, slave1->dev->dev_addr); |
| 1101 | alb_set_slave_mac_addr(slave1, slave2->dev->dev_addr); | 1090 | alb_set_slave_mac_addr(slave1, slave2->dev->dev_addr); |
| 1102 | alb_set_slave_mac_addr(slave2, tmp_mac_addr); | 1091 | alb_set_slave_mac_addr(slave2, tmp_mac_addr); |
| 1103 | 1092 | ||
| @@ -1254,9 +1243,9 @@ static int alb_handle_addr_collision_on_attach(struct bonding *bond, struct slav · 150 unmodified lines | |||
| 1254 | if (free_mac_slave) { | 1243 | if (free_mac_slave) { |
| 1255 | alb_set_slave_mac_addr(slave, free_mac_slave->perm_hwaddr); | 1244 | alb_set_slave_mac_addr(slave, free_mac_slave->perm_hwaddr); |
| 1256 | 1245 | ||
| 1257 | pr_warning("%s: Warning: the hw address of slave %s is in use by the bond; giving it the hw address of %s\n", | 1246 | pr_warn("%s: Warning: the hw address of slave %s is in use by the bond; giving it the hw address of %s\n", |
| 1258 | bond->dev->name, slave->dev->name, | 1247 | bond->dev->name, slave->dev->name, |
| 1259 | free_mac_slave->dev->name); | 1248 | free_mac_slave->dev->name); |
| 1260 | 1249 | ||
| 1261 | } else if (has_bond_addr) { | 1250 | } else if (has_bond_addr) { |
| 1262 | pr_err("%s: Error: the hw address of slave %s is in use by the bond; couldn't find a slave with a free hw address to give it (this should not have happened)\n", | 1251 | pr_err("%s: Error: the hw address of slave %s is in use by the bond; couldn't find a slave with a free hw address to give it (this should not have happened)\n", |
| @@ -1294,12 +1283,12 @@ static int alb_set_mac_address(struct bonding *bond, void *addr) · 31 unmodified lines | |||
| 1294 | 1283 | ||
| 1295 | bond_for_each_slave(bond, slave, iter) { | 1284 | bond_for_each_slave(bond, slave, iter) { |
| 1296 | /* save net_device's current hw address */ | 1285 | /* save net_device's current hw address */ |
| 1297 | memcpy(tmp_addr, slave->dev->dev_addr, ETH_ALEN); | 1286 | ether_addr_copy(tmp_addr, slave->dev->dev_addr); |
| 1298 | 1287 | ||
| 1299 | res = dev_set_mac_address(slave->dev, addr); | 1288 | res = dev_set_mac_address(slave->dev, addr); |
| 1300 | 1289 | ||
| 1301 | /* restore net_device's hw address */ | 1290 | /* restore net_device's hw address */ |
| 1302 | memcpy(slave->dev->dev_addr, tmp_addr, ETH_ALEN); | 1291 | ether_addr_copy(slave->dev->dev_addr, tmp_addr); |
| 1303 | 1292 | ||
| 1304 | if (res) | 1293 | if (res) |
| 1305 | goto unwind; | 1294 | goto unwind; |
| @@ -1315,9 +1304,9 @@ unwind: · 9 unmodified lines | |||
| 1315 | bond_for_each_slave(bond, rollback_slave, iter) { | 1304 | bond_for_each_slave(bond, rollback_slave, iter) { |
| 1316 | if (rollback_slave == slave) | 1305 | if (rollback_slave == slave) |
| 1317 | break; | 1306 | break; |
| 1318 | memcpy(tmp_addr, rollback_slave->dev->dev_addr, ETH_ALEN); | 1307 | ether_addr_copy(tmp_addr, rollback_slave->dev->dev_addr); |
| 1319 | dev_set_mac_address(rollback_slave->dev, &sa); | 1308 | dev_set_mac_address(rollback_slave->dev, &sa); |
| 1320 | memcpy(rollback_slave->dev->dev_addr, tmp_addr, ETH_ALEN); | 1309 | ether_addr_copy(rollback_slave->dev->dev_addr, tmp_addr); |
| 1321 | } | 1310 | } |
| 1322 | 1311 | ||
| 1323 | return res; | 1312 | return res; |
| @@ -1330,9 +1319,8 @@ int bond_alb_initialize(struct bonding *bond, int rlb_enabled) · 6 unmodified lines | |||
| 1330 | int res; | 1319 | int res; |
| 1331 | 1320 | ||
| 1332 | res = tlb_initialize(bond); | 1321 | res = tlb_initialize(bond); |
| 1333 | if (res) { | 1322 | if (res) |
| 1334 | return res; | 1323 | return res; |
| 1335 | } | ||
| 1336 | 1324 | ||
| 1337 | if (rlb_enabled) { | 1325 | if (rlb_enabled) { |
| 1338 | bond->alb_info.rlb_enabled = 1; | 1326 | bond->alb_info.rlb_enabled = 1; |
| @@ -1355,9 +1343,8 @@ void bond_alb_deinitialize(struct bonding *bond) · 16 unmodified lines | |||
| 1355 | 1343 | ||
| 1356 | tlb_deinitialize(bond); | 1344 | tlb_deinitialize(bond); |
| 1357 | 1345 | ||
| 1358 | if (bond_info->rlb_enabled) { | 1346 | if (bond_info->rlb_enabled) |
| 1359 | rlb_deinitialize(bond); | 1347 | rlb_deinitialize(bond); |
| 1360 | } | ||
| 1361 | } | 1348 | } |
| 1362 | 1349 | ||
| 1363 | int bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev) | 1350 | int bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev) |
| @@ -1436,14 +1423,13 @@ int bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev) · 72 unmodified lines | |||
| 1436 | break; | 1423 | break; |
| 1437 | } | 1424 | } |
| 1438 | 1425 | ||
| 1439 | hash_start = (char*)eth_data->h_dest; | 1426 | hash_start = (char *)eth_data->h_dest; |
| 1440 | hash_size = ETH_ALEN; | 1427 | hash_size = ETH_ALEN; |
| 1441 | break; | 1428 | break; |
| 1442 | case ETH_P_ARP: | 1429 | case ETH_P_ARP: |
| 1443 | do_tx_balance = 0; | 1430 | do_tx_balance = 0; |
| 1444 | if (bond_info->rlb_enabled) { | 1431 | if (bond_info->rlb_enabled) |
| 1445 | tx_slave = rlb_arp_xmit(skb, bond); | 1432 | tx_slave = rlb_arp_xmit(skb, bond); |
| 1446 | } | ||
| 1447 | break; | 1433 | break; |
| 1448 | default: | 1434 | default: |
| 1449 | do_tx_balance = 0; | 1435 | do_tx_balance = 0; |
| @@ -1463,23 +1449,22 @@ int bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev) · 13 unmodified lines | |||
| 1463 | 1449 | ||
| 1464 | if (tx_slave && SLAVE_IS_OK(tx_slave)) { | 1450 | if (tx_slave && SLAVE_IS_OK(tx_slave)) { |
| 1465 | if (tx_slave != rcu_dereference(bond->curr_active_slave)) { | 1451 | if (tx_slave != rcu_dereference(bond->curr_active_slave)) { |
| 1466 | memcpy(eth_data->h_source, | 1452 | ether_addr_copy(eth_data->h_source, |
| 1467 | tx_slave->dev->dev_addr, | 1453 | tx_slave->dev->dev_addr); |
| 1468 | ETH_ALEN); | ||
| 1469 | } | 1454 | } |
| 1470 | 1455 | ||
| 1471 | bond_dev_queue_xmit(bond, skb, tx_slave->dev); | 1456 | bond_dev_queue_xmit(bond, skb, tx_slave->dev); |
| 1472 | goto out; | 1457 | goto out; |
| 1473 | } else { | 1458 | } |
| 1474 | if (tx_slave) { | 1459 | |
| 1475 | _lock_tx_hashtbl(bond); | 1460 | if (tx_slave) { |
| 1476 | __tlb_clear_slave(bond, tx_slave, 0); | 1461 | _lock_tx_hashtbl(bond); |
| 1477 | _unlock_tx_hashtbl(bond); | 1462 | __tlb_clear_slave(bond, tx_slave, 0); |
| 1478 | } | 1463 | _unlock_tx_hashtbl(bond); |
| 1479 | } | 1464 | } |
| 1480 | 1465 | ||
| 1481 | /* no suitable interface, frame not sent */ | 1466 | /* no suitable interface, frame not sent */ |
| 1482 | kfree_skb(skb); | 1467 | dev_kfree_skb_any(skb); |
| 1483 | out: | 1468 | out: |
| 1484 | return NETDEV_TX_OK; | 1469 | return NETDEV_TX_OK; |
| 1485 | } | 1470 | } |
| @@ -1577,11 +1562,10 @@ void bond_alb_monitor(struct work_struct *work) · 91 unmodified lines | |||
| 1577 | --bond_info->rlb_update_delay_counter; | 1562 | --bond_info->rlb_update_delay_counter; |
| 1578 | } else { | 1563 | } else { |
| 1579 | rlb_update_rx_clients(bond); | 1564 | rlb_update_rx_clients(bond); |
| 1580 | if (bond_info->rlb_update_retry_counter) { | 1565 | if (bond_info->rlb_update_retry_counter) |
| 1581 | --bond_info->rlb_update_retry_counter; | 1566 | --bond_info->rlb_update_retry_counter; |
| 1582 | } else { | 1567 | else |
| 1583 | bond_info->rx_ntt = 0; | 1568 | bond_info->rx_ntt = 0; |
| 1584 | } | ||
| 1585 | } | 1569 | } |
| 1586 | } | 1570 | } |
| 1587 | } | 1571 | } |
| @@ -1598,23 +1582,20 @@ int bond_alb_init_slave(struct bonding *bond, struct slave *slave) · 10 unmodified lines | |||
| 1598 | int res; | 1582 | int res; |
| 1599 | 1583 | ||
| 1600 | res = alb_set_slave_mac_addr(slave, slave->perm_hwaddr); | 1584 | res = alb_set_slave_mac_addr(slave, slave->perm_hwaddr); |
| 1601 | if (res) { | 1585 | if (res) |
| 1602 | return res; | 1586 | return res; |
| 1603 | } | ||
| 1604 | 1587 | ||
| 1605 | res = alb_handle_addr_collision_on_attach(bond, slave); | 1588 | res = alb_handle_addr_collision_on_attach(bond, slave); |
| 1606 | if (res) { | 1589 | if (res) |
| 1607 | return res; | 1590 | return res; |
| 1608 | } | ||
| 1609 | 1591 | ||
| 1610 | tlb_init_slave(slave); | 1592 | tlb_init_slave(slave); |
| 1611 | 1593 | ||
| 1612 | /* order a rebalance ASAP */ | 1594 | /* order a rebalance ASAP */ |
| 1613 | bond->alb_info.tx_rebalance_counter = BOND_TLB_REBALANCE_TICKS; | 1595 | bond->alb_info.tx_rebalance_counter = BOND_TLB_REBALANCE_TICKS; |
| 1614 | 1596 | ||
| 1615 | if (bond->alb_info.rlb_enabled) { | 1597 | if (bond->alb_info.rlb_enabled) |
| 1616 | bond->alb_info.rlb_rebalance = 1; | 1598 | bond->alb_info.rlb_rebalance = 1; |
| 1617 | } | ||
| 1618 | 1599 | ||
| 1619 | return 0; | 1600 | return 0; |
| 1620 | } | 1601 | } |
| @@ -1645,9 +1626,8 @@ void bond_alb_handle_link_change(struct bonding *bond, struct slave *slave, char · 24 unmodified lines | |||
| 1645 | 1626 | ||
| 1646 | if (link == BOND_LINK_DOWN) { | 1627 | if (link == BOND_LINK_DOWN) { |
| 1647 | tlb_clear_slave(bond, slave, 0); | 1628 | tlb_clear_slave(bond, slave, 0); |
| 1648 | if (bond->alb_info.rlb_enabled) { | 1629 | if (bond->alb_info.rlb_enabled) |
| 1649 | rlb_clear_slave(bond, slave); | 1630 | rlb_clear_slave(bond, slave); |
| 1650 | } | ||
| 1651 | } else if (link == BOND_LINK_UP) { | 1631 | } else if (link == BOND_LINK_UP) { |
| 1652 | /* order a rebalance ASAP */ | 1632 | /* order a rebalance ASAP */ |
| 1653 | bond_info->tx_rebalance_counter = BOND_TLB_REBALANCE_TICKS; | 1633 | bond_info->tx_rebalance_counter = BOND_TLB_REBALANCE_TICKS; |
| @@ -1723,14 +1703,14 @@ void bond_alb_handle_active_change(struct bonding *bond, struct slave *new_slave · 69 unmodified lines | |||
| 1723 | struct sockaddr sa; | 1703 | struct sockaddr sa; |
| 1724 | u8 tmp_addr[ETH_ALEN]; | 1704 | u8 tmp_addr[ETH_ALEN]; |
| 1725 | 1705 | ||
| 1726 | memcpy(tmp_addr, new_slave->dev->dev_addr, ETH_ALEN); | 1706 | ether_addr_copy(tmp_addr, new_slave->dev->dev_addr); |
| 1727 | 1707 | ||
| 1728 | memcpy(sa.sa_data, bond->dev->dev_addr, bond->dev->addr_len); | 1708 | memcpy(sa.sa_data, bond->dev->dev_addr, bond->dev->addr_len); |
| 1729 | sa.sa_family = bond->dev->type; | 1709 | sa.sa_family = bond->dev->type; |
| 1730 | /* we don't care if it can't change its mac, best effort */ | 1710 | /* we don't care if it can't change its mac, best effort */ |
| 1731 | dev_set_mac_address(new_slave->dev, &sa); | 1711 | dev_set_mac_address(new_slave->dev, &sa); |
| 1732 | 1712 | ||
| 1733 | memcpy(new_slave->dev->dev_addr, tmp_addr, ETH_ALEN); | 1713 | ether_addr_copy(new_slave->dev->dev_addr, tmp_addr); |
| 1734 | } | 1714 | } |
| 1735 | 1715 | ||
| 1736 | /* curr_active_slave must be set before calling alb_swap_mac_addr */ | 1716 | /* curr_active_slave must be set before calling alb_swap_mac_addr */ |
| @@ -1759,14 +1739,12 @@ int bond_alb_set_mac_address(struct net_device *bond_dev, void *addr) · 22 unmodified lines | |||
| 1759 | struct slave *swap_slave; | 1739 | struct slave *swap_slave; |
| 1760 | int res; | 1740 | int res; |
| 1761 | 1741 | ||
| 1762 | if (!is_valid_ether_addr(sa->sa_data)) { | 1742 | if (!is_valid_ether_addr(sa->sa_data)) |
| 1763 | return -EADDRNOTAVAIL; | 1743 | return -EADDRNOTAVAIL; |
| 1764 | } | ||
| 1765 | 1744 | ||
| 1766 | res = alb_set_mac_address(bond, addr); | 1745 | res = alb_set_mac_address(bond, addr); |
| 1767 | if (res) { | 1746 | if (res) |
| 1768 | return res; | 1747 | return res; |
| 1769 | } | ||
| 1770 | 1748 | ||
| 1771 | memcpy(bond_dev->dev_addr, sa->sa_data, bond_dev->addr_len); | 1749 | memcpy(bond_dev->dev_addr, sa->sa_data, bond_dev->addr_len); |
| 1772 | 1750 | ||
| @@ -1774,9 +1752,8 @@ int bond_alb_set_mac_address(struct net_device *bond_dev, void *addr) · 1 unmodified line | |||
| 1774 | * Otherwise we'll need to pass the new address to it and handle | 1752 | * Otherwise we'll need to pass the new address to it and handle |
| 1775 | * duplications. | 1753 | * duplications. |
| 1776 | */ | 1754 | */ |
| 1777 | if (!bond->curr_active_slave) { | 1755 | if (!bond->curr_active_slave) |
| 1778 | return 0; | 1756 | return 0; |
| 1779 | } | ||
| 1780 | 1757 | ||
| 1781 | swap_slave = bond_slave_has_mac(bond, bond_dev->dev_addr); | 1758 | swap_slave = bond_slave_has_mac(bond, bond_dev->dev_addr); |
| 1782 | 1759 | ||
| @@ -1800,8 +1777,7 @@ int bond_alb_set_mac_address(struct net_device *bond_dev, void *addr) · 17 unmodified lines | |||
| 1800 | 1777 | ||
| 1801 | void bond_alb_clear_vlan(struct bonding *bond, unsigned short vlan_id) | 1778 | void bond_alb_clear_vlan(struct bonding *bond, unsigned short vlan_id) |
| 1802 | { | 1779 | { |
| 1803 | if (bond->alb_info.rlb_enabled) { | 1780 | if (bond->alb_info.rlb_enabled) |
| 1804 | rlb_clear_vlan(bond, vlan_id); | 1781 | rlb_clear_vlan(bond, vlan_id); |
| 1805 | } | ||
| 1806 | } | 1782 | } |
| 1807 | 1783 | ||
| @@ -69,7 +69,7 @@ void bond_debug_register(struct bonding *bond) · 68 unmodified lines | |||
| 69 | debugfs_create_dir(bond->dev->name, bonding_debug_root); | 69 | debugfs_create_dir(bond->dev->name, bonding_debug_root); |
| 70 | 70 | ||
| 71 | if (!bond->debug_dir) { | 71 | if (!bond->debug_dir) { |
| 72 | pr_warning("%s: Warning: failed to register to debugfs\n", | 72 | pr_warn("%s: Warning: failed to register to debugfs\n", |
| 73 | bond->dev->name); | 73 | bond->dev->name); |
| 74 | return; | 74 | return; |
| 75 | } | 75 | } |
| @@ -98,9 +98,8 @@ void bond_debug_reregister(struct bonding *bond) · 22 unmodified lines | |||
| 98 | if (d) { | 98 | if (d) { |
| 99 | bond->debug_dir = d; | 99 | bond->debug_dir = d; |
| 100 | } else { | 100 | } else { |
| 101 | pr_warning("%s: Warning: failed to reregister, " | 101 | pr_warn("%s: Warning: failed to reregister, so just unregister old one\n", |
| 102 | "so just unregister old one\n", | 102 | bond->dev->name); |
| 103 | bond->dev->name); | ||
| 104 | bond_debug_unregister(bond); | 103 | bond_debug_unregister(bond); |
| 105 | } | 104 | } |
| 106 | } | 105 | } |
| @@ -110,8 +109,7 @@ void bond_create_debugfs(void) · 3 unmodified lines | |||
| 110 | bonding_debug_root = debugfs_create_dir("bonding", NULL); | 109 | bonding_debug_root = debugfs_create_dir("bonding", NULL); |
| 111 | 110 | ||
| 112 | if (!bonding_debug_root) { | 111 | if (!bonding_debug_root) { |
| 113 | pr_warning("Warning: Cannot create bonding directory" | 112 | pr_warn("Warning: Cannot create bonding directory in debugfs\n"); |
| 114 | " in debugfs\n"); | ||
| 115 | } | 113 | } |
| 116 | } | 114 | } |
| 117 | 115 | ||
| @@ -673,12 +673,12 @@ static void bond_do_fail_over_mac(struct bonding *bond, · 672 unmodified lines | |||
| 673 | write_unlock_bh(&bond->curr_slave_lock); | 673 | write_unlock_bh(&bond->curr_slave_lock); |
| 674 | 674 | ||
| 675 | if (old_active) { | 675 | if (old_active) { |
| 676 | memcpy(tmp_mac, new_active->dev->dev_addr, ETH_ALEN); | 676 | ether_addr_copy(tmp_mac, new_active->dev->dev_addr); |
| 677 | memcpy(saddr.sa_data, old_active->dev->dev_addr, | 677 | ether_addr_copy(saddr.sa_data, |
| 678 | ETH_ALEN); | 678 | old_active->dev->dev_addr); |
| 679 | saddr.sa_family = new_active->dev->type; | 679 | saddr.sa_family = new_active->dev->type; |
| 680 | } else { | 680 | } else { |
| 681 | memcpy(saddr.sa_data, bond->dev->dev_addr, ETH_ALEN); | 681 | ether_addr_copy(saddr.sa_data, bond->dev->dev_addr); |
| 682 | saddr.sa_family = bond->dev->type; | 682 | saddr.sa_family = bond->dev->type; |
| 683 | } | 683 | } |
| 684 | 684 | ||
| @@ -692,7 +692,7 @@ static void bond_do_fail_over_mac(struct bonding *bond, · 7 unmodified lines | |||
| 692 | if (!old_active) | 692 | if (!old_active) |
| 693 | goto out; | 693 | goto out; |
| 694 | 694 | ||
| 695 | memcpy(saddr.sa_data, tmp_mac, ETH_ALEN); | 695 | ether_addr_copy(saddr.sa_data, tmp_mac); |
| 696 | saddr.sa_family = old_active->dev->type; | 696 | saddr.sa_family = old_active->dev->type; |
| 697 | 697 | ||
| 698 | rv = dev_set_mac_address(old_active->dev, &saddr); | 698 | rv = dev_set_mac_address(old_active->dev, &saddr); |
| @@ -798,11 +798,11 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active) · 99 unmodified lines | |||
| 798 | return; | 798 | return; |
| 799 | 799 | ||
| 800 | if (new_active) { | 800 | if (new_active) { |
| 801 | new_active->jiffies = jiffies; | 801 | new_active->last_link_up = jiffies; |
| 802 | 802 | ||
| 803 | if (new_active->link == BOND_LINK_BACK) { | 803 | if (new_active->link == BOND_LINK_BACK) { |
| 804 | if (USES_PRIMARY(bond->params.mode)) { | 804 | if (USES_PRIMARY(bond->params.mode)) { |
| 805 | pr_info("%s: making interface %s the new active one %d ms earlier.\n", | 805 | pr_info("%s: making interface %s the new active one %d ms earlier\n", |
| 806 | bond->dev->name, new_active->dev->name, | 806 | bond->dev->name, new_active->dev->name, |
| 807 | (bond->params.updelay - new_active->delay) * bond->params.miimon); | 807 | (bond->params.updelay - new_active->delay) * bond->params.miimon); |
| 808 | } | 808 | } |
| @@ -817,7 +817,7 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active) · 8 unmodified lines | |||
| 817 | bond_alb_handle_link_change(bond, new_active, BOND_LINK_UP); | 817 | bond_alb_handle_link_change(bond, new_active, BOND_LINK_UP); |
| 818 | } else { | 818 | } else { |
| 819 | if (USES_PRIMARY(bond->params.mode)) { | 819 | if (USES_PRIMARY(bond->params.mode)) { |
| 820 | pr_info("%s: making interface %s the new active one.\n", | 820 | pr_info("%s: making interface %s the new active one\n", |
| 821 | bond->dev->name, new_active->dev->name); | 821 | bond->dev->name, new_active->dev->name); |
| 822 | } | 822 | } |
| 823 | } | 823 | } |
| @@ -910,7 +910,7 @@ void bond_select_active_slave(struct bonding *bond) · 86 unmodified lines | |||
| 910 | pr_info("%s: first active interface up!\n", | 910 | pr_info("%s: first active interface up!\n", |
| 911 | bond->dev->name); | 911 | bond->dev->name); |
| 912 | } else { | 912 | } else { |
| 913 | pr_info("%s: now running without any active interface !\n", | 913 | pr_info("%s: now running without any active interface!\n", |
| 914 | bond->dev->name); | 914 | bond->dev->name); |
| 915 | } | 915 | } |
| 916 | } | 916 | } |
| @@ -922,12 +922,12 @@ static inline int slave_enable_netpoll(struct slave *slave) · 5 unmodified lines | |||
| 922 | struct netpoll *np; | 922 | struct netpoll *np; |
| 923 | int err = 0; | 923 | int err = 0; |
| 924 | 924 | ||
| 925 | np = kzalloc(sizeof(*np), GFP_ATOMIC); | 925 | np = kzalloc(sizeof(*np), GFP_KERNEL); |
| 926 | err = -ENOMEM; | 926 | err = -ENOMEM; |
| 927 | if (!np) | 927 | if (!np) |
| 928 | goto out; | 928 | goto out; |
| 929 | 929 | ||
| 930 | err = __netpoll_setup(np, slave->dev, GFP_ATOMIC); | 930 | err = __netpoll_setup(np, slave->dev); |
| 931 | if (err) { | 931 | if (err) { |
| 932 | kfree(np); | 932 | kfree(np); |
| 933 | goto out; | 933 | goto out; |
| @@ -946,14 +946,6 @@ static inline void slave_disable_netpoll(struct slave *slave) · 12 unmodified lines | |||
| 946 | slave->np = NULL; | 946 | slave->np = NULL; |
| 947 | __netpoll_free_async(np); | 947 | __netpoll_free_async(np); |
| 948 | } | 948 | } |
| 949 | static inline bool slave_dev_support_netpoll(struct net_device *slave_dev) | ||
| 950 | { | ||
| 951 | if (slave_dev->priv_flags & IFF_DISABLE_NETPOLL) | ||
| 952 | return false; | ||
| 953 | if (!slave_dev->netdev_ops->ndo_poll_controller) | ||
| 954 | return false; | ||
| 955 | return true; | ||
| 956 | } | ||
| 957 | 949 | ||
| 958 | static void bond_poll_controller(struct net_device *bond_dev) | 950 | static void bond_poll_controller(struct net_device *bond_dev) |
| 959 | { | 951 | { |
| @@ -970,7 +962,7 @@ static void bond_netpoll_cleanup(struct net_device *bond_dev) · 10 unmodified lines | |||
| 970 | slave_disable_netpoll(slave); | 962 | slave_disable_netpoll(slave); |
| 971 | } | 963 | } |
| 972 | 964 | ||
| 973 | static int bond_netpoll_setup(struct net_device *dev, struct netpoll_info *ni, gfp_t gfp) | 965 | static int bond_netpoll_setup(struct net_device *dev, struct netpoll_info *ni) |
| 974 | { | 966 | { |
| 975 | struct bonding *bond = netdev_priv(dev); | 967 | struct bonding *bond = netdev_priv(dev); |
| 976 | struct list_head *iter; | 968 | struct list_head *iter; |
| @@ -1119,9 +1111,6 @@ static rx_handler_result_t bond_handle_frame(struct sk_buff **pskb) · 142 unmodified lines | |||
| 1119 | slave = bond_slave_get_rcu(skb->dev); | 1111 | slave = bond_slave_get_rcu(skb->dev); |
| 1120 | bond = slave->bond; | 1112 | bond = slave->bond; |
| 1121 | 1113 | ||
| 1122 | if (bond->params.arp_interval) | ||
| 1123 | slave->dev->last_rx = jiffies; | ||
| 1124 | |||
| 1125 | recv_probe = ACCESS_ONCE(bond->recv_probe); | 1114 | recv_probe = ACCESS_ONCE(bond->recv_probe); |
| 1126 | if (recv_probe) { | 1115 | if (recv_probe) { |
| 1127 | ret = recv_probe(skb, bond, slave); | 1116 | ret = recv_probe(skb, bond, slave); |
| @@ -1146,7 +1135,7 @@ static rx_handler_result_t bond_handle_frame(struct sk_buff **pskb) · 18 unmodified lines | |||
| 1146 | kfree_skb(skb); | 1135 | kfree_skb(skb); |
| 1147 | return RX_HANDLER_CONSUMED; | 1136 | return RX_HANDLER_CONSUMED; |
| 1148 | } | 1137 | } |
| 1149 | memcpy(eth_hdr(skb)->h_dest, bond->dev->dev_addr, ETH_ALEN); | 1138 | ether_addr_copy(eth_hdr(skb)->h_dest, bond->dev->dev_addr); |
| 1150 | } | 1139 | } |
| 1151 | 1140 | ||
| 1152 | return ret; | 1141 | return ret; |
| @@ -1187,13 +1176,13 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) · 34 unmodified lines | |||
| 1187 | if (!bond->params.use_carrier && | 1176 | if (!bond->params.use_carrier && |
| 1188 | slave_dev->ethtool_ops->get_link == NULL && | 1177 | slave_dev->ethtool_ops->get_link == NULL && |
| 1189 | slave_ops->ndo_do_ioctl == NULL) { | 1178 | slave_ops->ndo_do_ioctl == NULL) { |
| 1190 | pr_warning("%s: Warning: no link monitoring support for %s\n", | 1179 | pr_warn("%s: Warning: no link monitoring support for %s\n", |
| 1191 | bond_dev->name, slave_dev->name); | 1180 | bond_dev->name, slave_dev->name); |
| 1192 | } | 1181 | } |
| 1193 | 1182 | ||
| 1194 | /* already enslaved */ | 1183 | /* already enslaved */ |
| 1195 | if (slave_dev->flags & IFF_SLAVE) { | 1184 | if (slave_dev->flags & IFF_SLAVE) { |
| 1196 | pr_debug("Error, Device was already enslaved\n"); | 1185 | pr_debug("Error: Device was already enslaved\n"); |
| 1197 | return -EBUSY; | 1186 | return -EBUSY; |
| 1198 | } | 1187 | } |
| 1199 | 1188 | ||
| @@ -1211,9 +1200,9 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) · 11 unmodified lines | |||
| 1211 | bond_dev->name, slave_dev->name, bond_dev->name); | 1200 | bond_dev->name, slave_dev->name, bond_dev->name); |
| 1212 | return -EPERM; | 1201 | return -EPERM; |
| 1213 | } else { | 1202 | } else { |
| 1214 | pr_warning("%s: Warning: enslaved VLAN challenged slave %s. Adding VLANs will be blocked as long as %s is part of bond %s\n", | 1203 | pr_warn("%s: Warning: enslaved VLAN challenged slave %s. Adding VLANs will be blocked as long as %s is part of bond %s\n", |
| 1215 | bond_dev->name, slave_dev->name, | 1204 | bond_dev->name, slave_dev->name, |
| 1216 | slave_dev->name, bond_dev->name); | 1205 | slave_dev->name, bond_dev->name); |
| 1217 | } | 1206 | } |
| 1218 | } else { | 1207 | } else { |
| 1219 | pr_debug("%s: ! NETIF_F_VLAN_CHALLENGED\n", slave_dev->name); | 1208 | pr_debug("%s: ! NETIF_F_VLAN_CHALLENGED\n", slave_dev->name); |
| @@ -1226,7 +1215,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) · 6 unmodified lines | |||
| 1226 | * enslaving it; the old ifenslave will not. | 1215 | * enslaving it; the old ifenslave will not. |
| 1227 | */ | 1216 | */ |
| 1228 | if ((slave_dev->flags & IFF_UP)) { | 1217 | if ((slave_dev->flags & IFF_UP)) { |
| 1229 | pr_err("%s is up. This may be due to an out of date ifenslave.\n", | 1218 | pr_err("%s is up - this may be due to an out of date ifenslave\n", |
| 1230 | slave_dev->name); | 1219 | slave_dev->name); |
| 1231 | res = -EPERM; | 1220 | res = -EPERM; |
| 1232 | goto err_undo_flags; | 1221 | goto err_undo_flags; |
| @@ -1270,24 +1259,23 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) · 37 unmodified lines | |||
| 1270 | bond_dev); | 1259 | bond_dev); |
| 1271 | } | 1260 | } |
| 1272 | } else if (bond_dev->type != slave_dev->type) { | 1261 | } else if (bond_dev->type != slave_dev->type) { |
| 1273 | pr_err("%s ether type (%d) is different from other slaves (%d), can not enslave it.\n", | 1262 | pr_err("%s ether type (%d) is different from other slaves (%d), can not enslave it\n", |
| 1274 | slave_dev->name, | 1263 | slave_dev->name, slave_dev->type, bond_dev->type); |
| 1275 | slave_dev->type, bond_dev->type); | ||
| 1276 | res = -EINVAL; | 1264 | res = -EINVAL; |
| 1277 | goto err_undo_flags; | 1265 | goto err_undo_flags; |
| 1278 | } | 1266 | } |
| 1279 | 1267 | ||
| 1280 | if (slave_ops->ndo_set_mac_address == NULL) { | 1268 | if (slave_ops->ndo_set_mac_address == NULL) { |
| 1281 | if (!bond_has_slaves(bond)) { | 1269 | if (!bond_has_slaves(bond)) { |
| 1282 | pr_warn("%s: Warning: The first slave device specified does not support setting the MAC address.\n", | 1270 | pr_warn("%s: Warning: The first slave device specified does not support setting the MAC address\n", |
| 1283 | bond_dev->name); | 1271 | bond_dev->name); |
| 1284 | if (bond->params.mode == BOND_MODE_ACTIVEBACKUP) { | 1272 | if (bond->params.mode == BOND_MODE_ACTIVEBACKUP) { |
| 1285 | bond->params.fail_over_mac = BOND_FOM_ACTIVE; | 1273 | bond->params.fail_over_mac = BOND_FOM_ACTIVE; |
| 1286 | pr_warn("%s: Setting fail_over_mac to active for active-backup mode.\n", | 1274 | pr_warn("%s: Setting fail_over_mac to active for active-backup mode\n", |
| 1287 | bond_dev->name); | 1275 | bond_dev->name); |
| 1288 | } | 1276 | } |
| 1289 | } else if (bond->params.fail_over_mac != BOND_FOM_ACTIVE) { | 1277 | } else if (bond->params.fail_over_mac != BOND_FOM_ACTIVE) { |
| 1290 | pr_err("%s: Error: The slave device specified does not support setting the MAC address, but fail_over_mac is not set to active.\n", | 1278 | 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", |
| 1291 | bond_dev->name); | 1279 | bond_dev->name); |
| 1292 | res = -EOPNOTSUPP; | 1280 | res = -EOPNOTSUPP; |
| 1293 | goto err_undo_flags; | 1281 | goto err_undo_flags; |
| @@ -1326,7 +1314,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) · 32 unmodified lines | |||
| 1326 | * that need it, and for restoring it upon release, and then | 1314 | * that need it, and for restoring it upon release, and then |
| 1327 | * set it to the master's address | 1315 | * set it to the master's address |
| 1328 | */ | 1316 | */ |
| 1329 | memcpy(new_slave->perm_hwaddr, slave_dev->dev_addr, ETH_ALEN); | 1317 | ether_addr_copy(new_slave->perm_hwaddr, slave_dev->dev_addr); |
| 1330 | 1318 | ||
| 1331 | if (!bond->params.fail_over_mac || | 1319 | if (!bond->params.fail_over_mac || |
| 1332 | bond->params.mode != BOND_MODE_ACTIVEBACKUP) { | 1320 | bond->params.mode != BOND_MODE_ACTIVEBACKUP) { |
| @@ -1410,10 +1398,10 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) · 77 unmodified lines | |||
| 1410 | 1398 | ||
| 1411 | bond_update_speed_duplex(new_slave); | 1399 | bond_update_speed_duplex(new_slave); |
| 1412 | 1400 | ||
| 1413 | new_slave->last_arp_rx = jiffies - | 1401 | new_slave->last_rx = jiffies - |
| 1414 | (msecs_to_jiffies(bond->params.arp_interval) + 1); | 1402 | (msecs_to_jiffies(bond->params.arp_interval) + 1); |
| 1415 | for (i = 0; i < BOND_MAX_ARP_TARGETS; i++) | 1403 | for (i = 0; i < BOND_MAX_ARP_TARGETS; i++) |
| 1416 | new_slave->target_last_arp_rx[i] = new_slave->last_arp_rx; | 1404 | new_slave->target_last_arp_rx[i] = new_slave->last_rx; |
| 1417 | 1405 | ||
| 1418 | if (bond->params.miimon && !bond->params.use_carrier) { | 1406 | if (bond->params.miimon && !bond->params.use_carrier) { |
| 1419 | link_reporting = bond_check_dev_link(bond, slave_dev, 1); | 1407 | link_reporting = bond_check_dev_link(bond, slave_dev, 1); |
| @@ -1428,12 +1416,12 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) · 8 unmodified lines | |||
| 1428 | * supported); thus, we don't need to change | 1416 | * supported); thus, we don't need to change |
| 1429 | * the messages for netif_carrier. | 1417 | * the messages for netif_carrier. |
| 1430 | */ | 1418 | */ |
| 1431 | pr_warning("%s: Warning: MII and ETHTOOL support not available for interface %s, and arp_interval/arp_ip_target module parameters not specified, thus bonding will not detect link failures! see bonding.txt for details.\n", | 1419 | pr_warn("%s: Warning: MII and ETHTOOL support not available for interface %s, and arp_interval/arp_ip_target module parameters not specified, thus bonding will not detect link failures! see bonding.txt for details\n", |
| 1432 | bond_dev->name, slave_dev->name); | 1420 | bond_dev->name, slave_dev->name); |
| 1433 | } else if (link_reporting == -1) { | 1421 | } else if (link_reporting == -1) { |
| 1434 | /* unable get link status using mii/ethtool */ | 1422 | /* unable get link status using mii/ethtool */ |
| 1435 | pr_warning("%s: Warning: can't get link status from interface %s; the network driver associated with this interface does not support MII or ETHTOOL link status reporting, thus miimon has no effect on this interface.\n", | 1423 | pr_warn("%s: Warning: can't get link status from interface %s; the network driver associated with this interface does not support MII or ETHTOOL link status reporting, thus miimon has no effect on this interface\n", |
| 1436 | bond_dev->name, slave_dev->name); | 1424 | bond_dev->name, slave_dev->name); |
| 1437 | } | 1425 | } |
| 1438 | } | 1426 | } |
| 1439 | 1427 | ||
| @@ -1457,10 +1445,10 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) · 17 unmodified lines | |||
| 1457 | } | 1445 | } |
| 1458 | 1446 | ||
| 1459 | if (new_slave->link != BOND_LINK_DOWN) | 1447 | if (new_slave->link != BOND_LINK_DOWN) |
| 1460 | new_slave->jiffies = jiffies; | 1448 | new_slave->last_link_up = jiffies; |
| 1461 | pr_debug("Initial state of slave_dev is BOND_LINK_%s\n", | 1449 | pr_debug("Initial state of slave_dev is BOND_LINK_%s\n", |
| 1462 | new_slave->link == BOND_LINK_DOWN ? "DOWN" : | 1450 | new_slave->link == BOND_LINK_DOWN ? "DOWN" : |
| 1463 | (new_slave->link == BOND_LINK_UP ? "UP" : "BACK")); | 1451 | (new_slave->link == BOND_LINK_UP ? "UP" : "BACK")); |
| 1464 | 1452 | ||
| 1465 | if (USES_PRIMARY(bond->params.mode) && bond->params.primary[0]) { | 1453 | if (USES_PRIMARY(bond->params.mode) && bond->params.primary[0]) { |
| 1466 | /* if there is a primary slave, remember it */ | 1454 | /* if there is a primary slave, remember it */ |
| @@ -1520,9 +1508,8 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) · 53 unmodified lines | |||
| 1520 | slave_dev->npinfo = bond->dev->npinfo; | 1508 | slave_dev->npinfo = bond->dev->npinfo; |
| 1521 | if (slave_dev->npinfo) { | 1509 | if (slave_dev->npinfo) { |
| 1522 | if (slave_enable_netpoll(new_slave)) { | 1510 | if (slave_enable_netpoll(new_slave)) { |
| 1523 | pr_info("Error, %s: master_dev is using netpoll, " | 1511 | pr_info("Error, %s: master_dev is using netpoll, but new slave device does not support netpoll\n", |
| 1524 | "but new slave device does not support netpoll.\n", | 1512 | bond_dev->name); |
| 1525 | bond_dev->name); | ||
| 1526 | res = -EBUSY; | 1513 | res = -EBUSY; |
| 1527 | goto err_detach; | 1514 | goto err_detach; |
| 1528 | } | 1515 | } |
| @@ -1560,10 +1547,10 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) · 31 unmodified lines | |||
| 1560 | unblock_netpoll_tx(); | 1547 | unblock_netpoll_tx(); |
| 1561 | } | 1548 | } |
| 1562 | 1549 | ||
| 1563 | pr_info("%s: enslaving %s as a%s interface with a%s link.\n", | 1550 | pr_info("%s: Enslaving %s as %s interface with %s link\n", |
| 1564 | bond_dev->name, slave_dev->name, | 1551 | bond_dev->name, slave_dev->name, |
| 1565 | bond_is_active_slave(new_slave) ? "n active" : " backup", | 1552 | bond_is_active_slave(new_slave) ? "an active" : "a backup", |
| 1566 | new_slave->link != BOND_LINK_DOWN ? "n up" : " down"); | 1553 | new_slave->link != BOND_LINK_DOWN ? "an up" : "a down"); |
| 1567 | 1554 | ||
| 1568 | /* enslave is successful */ | 1555 | /* enslave is successful */ |
| 1569 | return 0; | 1556 | return 0; |
| @@ -1603,7 +1590,7 @@ err_restore_mac: · 33 unmodified lines | |||
| 1603 | * MAC if this slave's MAC is in use by the bond, or at | 1590 | * MAC if this slave's MAC is in use by the bond, or at |
| 1604 | * least print a warning. | 1591 | * least print a warning. |
| 1605 | */ | 1592 | */ |
| 1606 | memcpy(addr.sa_data, new_slave->perm_hwaddr, ETH_ALEN); | 1593 | ether_addr_copy(addr.sa_data, new_slave->perm_hwaddr); |
| 1607 | addr.sa_family = slave_dev->type; | 1594 | addr.sa_family = slave_dev->type; |
| 1608 | dev_set_mac_address(slave_dev, &addr); | 1595 | dev_set_mac_address(slave_dev, &addr); |
| 1609 | } | 1596 | } |
| @@ -1648,7 +1635,7 @@ static int __bond_release_one(struct net_device *bond_dev, · 38 unmodified lines | |||
| 1648 | /* slave is not a slave or master is not master of this slave */ | 1635 | /* slave is not a slave or master is not master of this slave */ |
| 1649 | if (!(slave_dev->flags & IFF_SLAVE) || | 1636 | if (!(slave_dev->flags & IFF_SLAVE) || |
| 1650 | !netdev_has_upper_dev(slave_dev, bond_dev)) { | 1637 | !netdev_has_upper_dev(slave_dev, bond_dev)) { |
| 1651 | pr_err("%s: Error: cannot release %s.\n", | 1638 | pr_err("%s: Error: cannot release %s\n", |
| 1652 | bond_dev->name, slave_dev->name); | 1639 | bond_dev->name, slave_dev->name); |
| 1653 | return -EINVAL; | 1640 | return -EINVAL; |
| 1654 | } | 1641 | } |
| @@ -1679,7 +1666,7 @@ static int __bond_release_one(struct net_device *bond_dev, · 24 unmodified lines | |||
| 1679 | 1666 | ||
| 1680 | write_unlock_bh(&bond->lock); | 1667 | write_unlock_bh(&bond->lock); |
| 1681 | 1668 | ||
| 1682 | pr_info("%s: releasing %s interface %s\n", | 1669 | pr_info("%s: Releasing %s interface %s\n", |
| 1683 | bond_dev->name, | 1670 | bond_dev->name, |
| 1684 | bond_is_active_slave(slave) ? "active" : "backup", | 1671 | bond_is_active_slave(slave) ? "active" : "backup", |
| 1685 | slave_dev->name); | 1672 | slave_dev->name); |
| @@ -1692,10 +1679,10 @@ static int __bond_release_one(struct net_device *bond_dev, · 6 unmodified lines | |||
| 1692 | bond->params.mode != BOND_MODE_ACTIVEBACKUP)) { | 1679 | bond->params.mode != BOND_MODE_ACTIVEBACKUP)) { |
| 1693 | if (ether_addr_equal_64bits(bond_dev->dev_addr, slave->perm_hwaddr) && | 1680 | if (ether_addr_equal_64bits(bond_dev->dev_addr, slave->perm_hwaddr) && |
| 1694 | bond_has_slaves(bond)) | 1681 | bond_has_slaves(bond)) |
| 1695 | pr_warn("%s: Warning: the permanent HWaddr of %s - %pM - is still in use by %s. Set the HWaddr of %s to a different address to avoid conflicts.\n", | 1682 | 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", |
| 1696 | bond_dev->name, slave_dev->name, | 1683 | bond_dev->name, slave_dev->name, |
| 1697 | slave->perm_hwaddr, | 1684 | slave->perm_hwaddr, |
| 1698 | bond_dev->name, slave_dev->name); | 1685 | bond_dev->name, slave_dev->name); |
| 1699 | } | 1686 | } |
| 1700 | 1687 | ||
| 1701 | if (bond->primary_slave == slave) | 1688 | if (bond->primary_slave == slave) |
| @@ -1736,10 +1723,10 @@ static int __bond_release_one(struct net_device *bond_dev, · 34 unmodified lines | |||
| 1736 | eth_hw_addr_random(bond_dev); | 1723 | eth_hw_addr_random(bond_dev); |
| 1737 | 1724 | ||
| 1738 | if (vlan_uses_dev(bond_dev)) { | 1725 | if (vlan_uses_dev(bond_dev)) { |
| 1739 | pr_warning("%s: Warning: clearing HW address of %s while it still has VLANs.\n", | 1726 | pr_warn("%s: Warning: clearing HW address of %s while it still has VLANs\n", |
| 1740 | bond_dev->name, bond_dev->name); | 1727 | bond_dev->name, bond_dev->name); |
| 1741 | pr_warning("%s: When re-adding slaves, make sure the bond's HW address matches its VLANs'.\n", | 1728 | pr_warn("%s: When re-adding slaves, make sure the bond's HW address matches its VLANs\n", |
| 1742 | bond_dev->name); | 1729 | bond_dev->name); |
| 1743 | } | 1730 | } |
| 1744 | } | 1731 | } |
| 1745 | 1732 | ||
| @@ -1755,7 +1742,7 @@ static int __bond_release_one(struct net_device *bond_dev, · 9 unmodified lines | |||
| 1755 | bond_compute_features(bond); | 1742 | bond_compute_features(bond); |
| 1756 | if (!(bond_dev->features & NETIF_F_VLAN_CHALLENGED) && | 1743 | if (!(bond_dev->features & NETIF_F_VLAN_CHALLENGED) && |
| 1757 | (old_features & NETIF_F_VLAN_CHALLENGED)) | 1744 | (old_features & NETIF_F_VLAN_CHALLENGED)) |
| 1758 | pr_info("%s: last VLAN challenged slave %s left bond %s. VLAN blocking is removed\n", | 1745 | pr_info("%s: last VLAN challenged slave %s left bond %s - VLAN blocking is removed\n", |
| 1759 | bond_dev->name, slave_dev->name, bond_dev->name); | 1746 | bond_dev->name, slave_dev->name, bond_dev->name); |
| 1760 | 1747 | ||
| 1761 | /* must do this from outside any spinlocks */ | 1748 | /* must do this from outside any spinlocks */ |
| @@ -1790,7 +1777,7 @@ static int __bond_release_one(struct net_device *bond_dev, · 28 unmodified lines | |||
| 1790 | if (bond->params.fail_over_mac != BOND_FOM_ACTIVE || | 1777 | if (bond->params.fail_over_mac != BOND_FOM_ACTIVE || |
| 1791 | bond->params.mode != BOND_MODE_ACTIVEBACKUP) { | 1778 | bond->params.mode != BOND_MODE_ACTIVEBACKUP) { |
| 1792 | /* restore original ("permanent") mac address */ | 1779 | /* restore original ("permanent") mac address */ |
| 1793 | memcpy(addr.sa_data, slave->perm_hwaddr, ETH_ALEN); | 1780 | ether_addr_copy(addr.sa_data, slave->perm_hwaddr); |
| 1794 | addr.sa_family = slave_dev->type; | 1781 | addr.sa_family = slave_dev->type; |
| 1795 | dev_set_mac_address(slave_dev, &addr); | 1782 | dev_set_mac_address(slave_dev, &addr); |
| 1796 | } | 1783 | } |
| @@ -1823,7 +1810,7 @@ static int bond_release_and_destroy(struct net_device *bond_dev, · 26 unmodified lines | |||
| 1823 | ret = bond_release(bond_dev, slave_dev); | 1810 | ret = bond_release(bond_dev, slave_dev); |
| 1824 | if (ret == 0 && !bond_has_slaves(bond)) { | 1811 | if (ret == 0 && !bond_has_slaves(bond)) { |
| 1825 | bond_dev->priv_flags |= IFF_DISABLE_NETPOLL; | 1812 | bond_dev->priv_flags |= IFF_DISABLE_NETPOLL; |
| 1826 | pr_info("%s: destroying bond %s.\n", | 1813 | pr_info("%s: Destroying bond %s\n", |
| 1827 | bond_dev->name, bond_dev->name); | 1814 | bond_dev->name, bond_dev->name); |
| 1828 | unregister_netdevice(bond_dev); | 1815 | unregister_netdevice(bond_dev); |
| 1829 | } | 1816 | } |
| @@ -1837,9 +1824,7 @@ static int bond_info_query(struct net_device *bond_dev, struct ifbond *info) · 7 unmodified lines | |||
| 1837 | info->bond_mode = bond->params.mode; | 1824 | info->bond_mode = bond->params.mode; |
| 1838 | info->miimon = bond->params.miimon; | 1825 | info->miimon = bond->params.miimon; |
| 1839 | 1826 | ||
| 1840 | read_lock(&bond->lock); | ||
| 1841 | info->num_slaves = bond->slave_cnt; | 1827 | info->num_slaves = bond->slave_cnt; |
| 1842 | read_unlock(&bond->lock); | ||
| 1843 | 1828 | ||
| 1844 | return 0; | 1829 | return 0; |
| 1845 | } | 1830 | } |
| @@ -1851,7 +1836,6 @@ static int bond_slave_info_query(struct net_device *bond_dev, struct ifslave *in · 5 unmodified lines | |||
| 1851 | int i = 0, res = -ENODEV; | 1836 | int i = 0, res = -ENODEV; |
| 1852 | struct slave *slave; | 1837 | struct slave *slave; |
| 1853 | 1838 | ||
| 1854 | read_lock(&bond->lock); | ||
| 1855 | bond_for_each_slave(bond, slave, iter) { | 1839 | bond_for_each_slave(bond, slave, iter) { |
| 1856 | if (i++ == (int)info->slave_id) { | 1840 | if (i++ == (int)info->slave_id) { |
| 1857 | res = 0; | 1841 | res = 0; |
| @@ -1862,7 +1846,6 @@ static int bond_slave_info_query(struct net_device *bond_dev, struct ifslave *in · 4 unmodified lines | |||
| 1862 | break; | 1846 | break; |
| 1863 | } | 1847 | } |
| 1864 | } | 1848 | } |
| 1865 | read_unlock(&bond->lock); | ||
| 1866 | 1849 | ||
| 1867 | return res; | 1850 | return res; |
| 1868 | } | 1851 | } |
| @@ -1892,7 +1875,7 @@ static int bond_miimon_inspect(struct bonding *bond) · 23 unmodified lines | |||
| 1892 | slave->link = BOND_LINK_FAIL; | 1875 | slave->link = BOND_LINK_FAIL; |
| 1893 | slave->delay = bond->params.downdelay; | 1876 | slave->delay = bond->params.downdelay; |
| 1894 | if (slave->delay) { | 1877 | if (slave->delay) { |
| 1895 | pr_info("%s: link status down for %sinterface %s, disabling it in %d ms.\n", | 1878 | pr_info("%s: link status down for %sinterface %s, disabling it in %d ms\n", |
| 1896 | bond->dev->name, | 1879 | bond->dev->name, |
| 1897 | (bond->params.mode == | 1880 | (bond->params.mode == |
| 1898 | BOND_MODE_ACTIVEBACKUP) ? | 1881 | BOND_MODE_ACTIVEBACKUP) ? |
| @@ -1908,8 +1891,8 @@ static int bond_miimon_inspect(struct bonding *bond) · 9 unmodified lines | |||
| 1908 | * recovered before downdelay expired | 1891 | * recovered before downdelay expired |
| 1909 | */ | 1892 | */ |
| 1910 | slave->link = BOND_LINK_UP; | 1893 | slave->link = BOND_LINK_UP; |
| 1911 | slave->jiffies = jiffies; | 1894 | slave->last_link_up = jiffies; |
| 1912 | pr_info("%s: link status up again after %d ms for interface %s.\n", | 1895 | pr_info("%s: link status up again after %d ms for interface %s\n", |
| 1913 | bond->dev->name, | 1896 | bond->dev->name, |
| 1914 | (bond->params.downdelay - slave->delay) * | 1897 | (bond->params.downdelay - slave->delay) * |
| 1915 | bond->params.miimon, | 1898 | bond->params.miimon, |
| @@ -1934,7 +1917,7 @@ static int bond_miimon_inspect(struct bonding *bond) · 18 unmodified lines | |||
| 1934 | slave->delay = bond->params.updelay; | 1917 | slave->delay = bond->params.updelay; |
| 1935 | 1918 | ||
| 1936 | if (slave->delay) { | 1919 | if (slave->delay) { |
| 1937 | pr_info("%s: link status up for interface %s, enabling it in %d ms.\n", | 1920 | pr_info("%s: link status up for interface %s, enabling it in %d ms\n", |
| 1938 | bond->dev->name, slave->dev->name, | 1921 | bond->dev->name, slave->dev->name, |
| 1939 | ignore_updelay ? 0 : | 1922 | ignore_updelay ? 0 : |
| 1940 | bond->params.updelay * | 1923 | bond->params.updelay * |
| @@ -1944,7 +1927,7 @@ static int bond_miimon_inspect(struct bonding *bond) · 3 unmodified lines | |||
| 1944 | case BOND_LINK_BACK: | 1927 | case BOND_LINK_BACK: |
| 1945 | if (!link_state) { | 1928 | if (!link_state) { |
| 1946 | slave->link = BOND_LINK_DOWN; | 1929 | slave->link = BOND_LINK_DOWN; |
| 1947 | pr_info("%s: link status down again after %d ms for interface %s.\n", | 1930 | pr_info("%s: link status down again after %d ms for interface %s\n", |
| 1948 | bond->dev->name, | 1931 | bond->dev->name, |
| 1949 | (bond->params.updelay - slave->delay) * | 1932 | (bond->params.updelay - slave->delay) * |
| 1950 | bond->params.miimon, | 1933 | bond->params.miimon, |
| @@ -1983,7 +1966,7 @@ static void bond_miimon_commit(struct bonding *bond) · 32 unmodified lines | |||
| 1983 | 1966 | ||
| 1984 | case BOND_LINK_UP: | 1967 | case BOND_LINK_UP: |
| 1985 | slave->link = BOND_LINK_UP; | 1968 | slave->link = BOND_LINK_UP; |
| 1986 | slave->jiffies = jiffies; | 1969 | slave->last_link_up = jiffies; |
| 1987 | 1970 | ||
| 1988 | if (bond->params.mode == BOND_MODE_8023AD) { | 1971 | if (bond->params.mode == BOND_MODE_8023AD) { |
| 1989 | /* prevent it from being the active one */ | 1972 | /* prevent it from being the active one */ |
| @@ -1996,7 +1979,7 @@ static void bond_miimon_commit(struct bonding *bond) · 6 unmodified lines | |||
| 1996 | bond_set_backup_slave(slave); | 1979 | bond_set_backup_slave(slave); |
| 1997 | } | 1980 | } |
| 1998 | 1981 | ||
| 1999 | pr_info("%s: link status definitely up for interface %s, %u Mbps %s duplex.\n", | 1982 | pr_info("%s: link status definitely up for interface %s, %u Mbps %s duplex\n", |
| 2000 | bond->dev->name, slave->dev->name, | 1983 | bond->dev->name, slave->dev->name, |
| 2001 | slave->speed == SPEED_UNKNOWN ? 0 : slave->speed, | 1984 | slave->speed == SPEED_UNKNOWN ? 0 : slave->speed, |
| 2002 | slave->duplex ? "full" : "half"); | 1985 | slave->duplex ? "full" : "half"); |
| @@ -2141,24 +2124,40 @@ static bool bond_has_this_ip(struct bonding *bond, __be32 ip) · 138 unmodified lines | |||
| 2141 | * switches in VLAN mode (especially if ports are configured as | 2124 | * switches in VLAN mode (especially if ports are configured as |
| 2142 | * "native" to a VLAN) might not pass non-tagged frames. | 2125 | * "native" to a VLAN) might not pass non-tagged frames. |
| 2143 | */ | 2126 | */ |
| 2144 | static void bond_arp_send(struct net_device *slave_dev, int arp_op, __be32 dest_ip, __be32 src_ip, unsigned short vlan_id) | 2127 | static void bond_arp_send(struct net_device *slave_dev, int arp_op, |
| 2128 | __be32 dest_ip, __be32 src_ip, | ||
| 2129 | struct bond_vlan_tag *inner, | ||
| 2130 | struct bond_vlan_tag *outer) | ||
| 2145 | { | 2131 | { |
| 2146 | struct sk_buff *skb; | 2132 | struct sk_buff *skb; |
| 2147 | 2133 | ||
| 2148 | pr_debug("arp %d on slave %s: dst %pI4 src %pI4 vid %d\n", arp_op, | 2134 | pr_debug("arp %d on slave %s: dst %pI4 src %pI4\n", |
| 2149 | slave_dev->name, &dest_ip, &src_ip, vlan_id); | 2135 | arp_op, slave_dev->name, &dest_ip, &src_ip); |
| 2150 | 2136 | ||
| 2151 | skb = arp_create(arp_op, ETH_P_ARP, dest_ip, slave_dev, src_ip, | 2137 | skb = arp_create(arp_op, ETH_P_ARP, dest_ip, slave_dev, src_ip, |
| 2152 | NULL, slave_dev->dev_addr, NULL); | 2138 | NULL, slave_dev->dev_addr, NULL); |
| 2153 | 2139 | ||
| 2154 | if (!skb) { | 2140 | if (!skb) { |
| 2155 | pr_err("ARP packet allocation failed\n"); | 2141 | net_err_ratelimited("ARP packet allocation failed\n"); |
| 2156 | return; | 2142 | return; |
| 2157 | } | 2143 | } |
| 2158 | if (vlan_id) { | 2144 | if (outer->vlan_id) { |
| 2159 | skb = vlan_put_tag(skb, htons(ETH_P_8021Q), vlan_id); | 2145 | if (inner->vlan_id) { |
| 2146 | pr_debug("inner tag: proto %X vid %X\n", | ||
| 2147 | ntohs(inner->vlan_proto), inner->vlan_id); | ||
| 2148 | skb = __vlan_put_tag(skb, inner->vlan_proto, | ||
| 2149 | inner->vlan_id); | ||
| 2150 | if (!skb) { | ||
| 2151 | net_err_ratelimited("failed to insert inner VLAN tag\n"); | ||
| 2152 | return; | ||
| 2153 | } | ||
| 2154 | } | ||
| 2155 | |||
| 2156 | pr_debug("outer reg: proto %X vid %X\n", | ||
| 2157 | ntohs(outer->vlan_proto), outer->vlan_id); | ||
| 2158 | skb = vlan_put_tag(skb, outer->vlan_proto, outer->vlan_id); | ||
| 2160 | if (!skb) { | 2159 | if (!skb) { |
| 2161 | pr_err("failed to insert VLAN tag\n"); | 2160 | net_err_ratelimited("failed to insert outer VLAN tag\n"); |
| 2162 | return; | 2161 | return; |
| 2163 | } | 2162 | } |
| 2164 | } | 2163 | } |
| @@ -2171,23 +2170,32 @@ static void bond_arp_send_all(struct bonding *bond, struct slave *slave) · 6 unmodified lines | |||
| 2171 | struct net_device *upper, *vlan_upper; | 2170 | struct net_device *upper, *vlan_upper; |
| 2172 | struct list_head *iter, *vlan_iter; | 2171 | struct list_head *iter, *vlan_iter; |
| 2173 | struct rtable *rt; | 2172 | struct rtable *rt; |
| 2173 | struct bond_vlan_tag inner, outer; | ||
| 2174 | __be32 *targets = bond->params.arp_targets, addr; | 2174 | __be32 *targets = bond->params.arp_targets, addr; |
| 2175 | int i, vlan_id; | 2175 | int i; |
| 2176 | 2176 | ||
| 2177 | for (i = 0; i < BOND_MAX_ARP_TARGETS && targets[i]; i++) { | 2177 | for (i = 0; i < BOND_MAX_ARP_TARGETS && targets[i]; i++) { |
| 2178 | pr_debug("basa: target %pI4\n", &targets[i]); | 2178 | pr_debug("basa: target %pI4\n", &targets[i]); |
| 2179 | inner.vlan_proto = 0; | ||
| 2180 | inner.vlan_id = 0; | ||
| 2181 | outer.vlan_proto = 0; | ||
| 2182 | outer.vlan_id = 0; | ||
| 2179 | 2183 | ||
| 2180 | /* Find out through which dev should the packet go */ | 2184 | /* Find out through which dev should the packet go */ |
| 2181 | rt = ip_route_output(dev_net(bond->dev), targets[i], 0, | 2185 | rt = ip_route_output(dev_net(bond->dev), targets[i], 0, |
| 2182 | RTO_ONLINK, 0); | 2186 | RTO_ONLINK, 0); |
| 2183 | if (IS_ERR(rt)) { | 2187 | if (IS_ERR(rt)) { |
| 2184 | pr_debug("%s: no route to arp_ip_target %pI4\n", | 2188 | /* there's no route to target - try to send arp |
| 2185 | bond->dev->name, &targets[i]); | 2189 | * probe to generate any traffic (arp_validate=0) |
| 2190 | */ | ||
| 2191 | if (bond->params.arp_validate) | ||
| 2192 | net_warn_ratelimited("%s: no route to arp_ip_target %pI4 and arp_validate is set\n", | ||
| 2193 | bond->dev->name, | ||
| 2194 | &targets[i]); | ||
| 2195 | bond_arp_send(slave->dev, ARPOP_REQUEST, targets[i], 0, &inner, &outer); | ||
| 2186 | continue; | 2196 | continue; |
| 2187 | } | 2197 | } |
| 2188 | 2198 | ||
| 2189 | vlan_id = 0; | ||
| 2190 | |||
| 2191 | /* bond device itself */ | 2199 | /* bond device itself */ |
| 2192 | if (rt->dst.dev == bond->dev) | 2200 | if (rt->dst.dev == bond->dev) |
| 2193 | goto found; | 2201 | goto found; |
| @@ -2197,17 +2205,30 @@ static void bond_arp_send_all(struct bonding *bond, struct slave *slave) · 3 unmodified lines | |||
| 2197 | * found we verify its upper dev list, searching for the | 2205 | * found we verify its upper dev list, searching for the |
| 2198 | * rt->dst.dev. If found we save the tag of the vlan and | 2206 | * rt->dst.dev. If found we save the tag of the vlan and |
| 2199 | * proceed to send the packet. | 2207 | * proceed to send the packet. |
| 2200 | * | ||
| 2201 | * TODO: QinQ? | ||
| 2202 | */ | 2208 | */ |
| 2203 | netdev_for_each_all_upper_dev_rcu(bond->dev, vlan_upper, | 2209 | netdev_for_each_all_upper_dev_rcu(bond->dev, vlan_upper, |
| 2204 | vlan_iter) { | 2210 | vlan_iter) { |
| 2205 | if (!is_vlan_dev(vlan_upper)) | 2211 | if (!is_vlan_dev(vlan_upper)) |
| 2206 | continue; | 2212 | continue; |
| 2213 | |||
| 2214 | if (vlan_upper == rt->dst.dev) { | ||
| 2215 | outer.vlan_proto = vlan_dev_vlan_proto(vlan_upper); | ||
| 2216 | outer.vlan_id = vlan_dev_vlan_id(vlan_upper); | ||
| 2217 | rcu_read_unlock(); | ||
| 2218 | goto found; | ||
| 2219 | } | ||
| 2207 | netdev_for_each_all_upper_dev_rcu(vlan_upper, upper, | 2220 | netdev_for_each_all_upper_dev_rcu(vlan_upper, upper, |
| 2208 | iter) { | 2221 | iter) { |
| 2209 | if (upper == rt->dst.dev) { | 2222 | if (upper == rt->dst.dev) { |
| 2210 | vlan_id = vlan_dev_vlan_id(vlan_upper); | 2223 | /* If the upper dev is a vlan dev too, |
| 2224 | * set the vlan tag to inner tag. | ||
| 2225 | */ | ||
| 2226 | if (is_vlan_dev(upper)) { | ||
| 2227 | inner.vlan_proto = vlan_dev_vlan_proto(upper); | ||
| 2228 | inner.vlan_id = vlan_dev_vlan_id(upper); | ||
| 2229 | } | ||
| 2230 | outer.vlan_proto = vlan_dev_vlan_proto(vlan_upper); | ||
| 2231 | outer.vlan_id = vlan_dev_vlan_id(vlan_upper); | ||
| 2211 | rcu_read_unlock(); | 2232 | rcu_read_unlock(); |
| 2212 | goto found; | 2233 | goto found; |
| 2213 | } | 2234 | } |
| @@ -2220,10 +2241,6 @@ static void bond_arp_send_all(struct bonding *bond, struct slave *slave) · 6 unmodified lines | |||
| 2220 | */ | 2241 | */ |
| 2221 | netdev_for_each_all_upper_dev_rcu(bond->dev, upper, iter) { | 2242 | netdev_for_each_all_upper_dev_rcu(bond->dev, upper, iter) { |
| 2222 | if (upper == rt->dst.dev) { | 2243 | if (upper == rt->dst.dev) { |
| 2223 | /* if it's a vlan - get its VID */ | ||
| 2224 | if (is_vlan_dev(upper)) | ||
| 2225 | vlan_id = vlan_dev_vlan_id(upper); | ||
| 2226 | |||
| 2227 | rcu_read_unlock(); | 2244 | rcu_read_unlock(); |
| 2228 | goto found; | 2245 | goto found; |
| 2229 | } | 2246 | } |
| @@ -2242,7 +2259,7 @@ found: · 12 unmodified lines | |||
| 2242 | addr = bond_confirm_addr(rt->dst.dev, targets[i], 0); | 2259 | addr = bond_confirm_addr(rt->dst.dev, targets[i], 0); |
| 2243 | ip_rt_put(rt); | 2260 | ip_rt_put(rt); |
| 2244 | bond_arp_send(slave->dev, ARPOP_REQUEST, targets[i], | 2261 | bond_arp_send(slave->dev, ARPOP_REQUEST, targets[i], |
| 2245 | addr, vlan_id); | 2262 | addr, &inner, &outer); |
| 2246 | } | 2263 | } |
| 2247 | } | 2264 | } |
| 2248 | 2265 | ||
| @@ -2260,7 +2277,7 @@ static void bond_validate_arp(struct bonding *bond, struct slave *slave, __be32 · 11 unmodified lines | |||
| 2260 | pr_debug("bva: sip %pI4 not found in targets\n", &sip); | 2277 | pr_debug("bva: sip %pI4 not found in targets\n", &sip); |
| 2261 | return; | 2278 | return; |
| 2262 | } | 2279 | } |
| 2263 | slave->last_arp_rx = jiffies; | 2280 | slave->last_rx = jiffies; |
| 2264 | slave->target_last_arp_rx[i] = jiffies; | 2281 | slave->target_last_arp_rx[i] = jiffies; |
| 2265 | } | 2282 | } |
| 2266 | 2283 | ||
| @@ -2268,17 +2285,19 @@ int bond_arp_rcv(const struct sk_buff *skb, struct bonding *bond, · 1 unmodified line | |||
| 2268 | struct slave *slave) | 2285 | struct slave *slave) |
| 2269 | { | 2286 | { |
| 2270 | struct arphdr *arp = (struct arphdr *)skb->data; | 2287 | struct arphdr *arp = (struct arphdr *)skb->data; |
| 2288 | struct slave *curr_active_slave; | ||
| 2271 | unsigned char *arp_ptr; | 2289 | unsigned char *arp_ptr; |
| 2272 | __be32 sip, tip; | 2290 | __be32 sip, tip; |
| 2273 | int alen; | 2291 | int alen, is_arp = skb->protocol == __cpu_to_be16(ETH_P_ARP); |
| 2274 | 2292 | ||
| 2275 | if (skb->protocol != __cpu_to_be16(ETH_P_ARP)) | 2293 | if (!slave_do_arp_validate(bond, slave)) { |
| 2294 | if ((slave_do_arp_validate_only(bond, slave) && is_arp) || | ||
| 2295 | !slave_do_arp_validate_only(bond, slave)) | ||
| 2296 | slave->last_rx = jiffies; | ||
| 2276 | return RX_HANDLER_ANOTHER; | 2297 | return RX_HANDLER_ANOTHER; |
| 2277 | 2298 | } else if (!is_arp) { | |
| 2278 | read_lock(&bond->lock); | 2299 | return RX_HANDLER_ANOTHER; |
| 2279 | 2300 | } | |
| 2280 | if (!slave_do_arp_validate(bond, slave)) | ||
| 2281 | goto out_unlock; | ||
| 2282 | 2301 | ||
| 2283 | alen = arp_hdr_len(bond->dev); | 2302 | alen = arp_hdr_len(bond->dev); |
| 2284 | 2303 | ||
| @@ -2312,6 +2331,8 @@ int bond_arp_rcv(const struct sk_buff *skb, struct bonding *bond, · 27 unmodified lines | |||
| 2312 | bond->params.arp_validate, slave_do_arp_validate(bond, slave), | 2331 | bond->params.arp_validate, slave_do_arp_validate(bond, slave), |
| 2313 | &sip, &tip); | 2332 | &sip, &tip); |
| 2314 | 2333 | ||
| 2334 | curr_active_slave = rcu_dereference(bond->curr_active_slave); | ||
| 2335 | |||
| 2315 | /* | 2336 | /* |
| 2316 | * Backup slaves won't see the ARP reply, but do come through | 2337 | * Backup slaves won't see the ARP reply, but do come through |
| 2317 | * here for each ARP probe (so we swap the sip/tip to validate | 2338 | * here for each ARP probe (so we swap the sip/tip to validate |
| @@ -2325,15 +2346,15 @@ int bond_arp_rcv(const struct sk_buff *skb, struct bonding *bond, · 7 unmodified lines | |||
| 2325 | * is done to avoid endless looping when we can't reach the | 2346 | * is done to avoid endless looping when we can't reach the |
| 2326 | * arp_ip_target and fool ourselves with our own arp requests. | 2347 | * arp_ip_target and fool ourselves with our own arp requests. |
| 2327 | */ | 2348 | */ |
| 2349 | |||
| 2328 | if (bond_is_active_slave(slave)) | 2350 | if (bond_is_active_slave(slave)) |
| 2329 | bond_validate_arp(bond, slave, sip, tip); | 2351 | bond_validate_arp(bond, slave, sip, tip); |
| 2330 | else if (bond->curr_active_slave && | 2352 | else if (curr_active_slave && |
| 2331 | time_after(slave_last_rx(bond, bond->curr_active_slave), | 2353 | time_after(slave_last_rx(bond, curr_active_slave), |
| 2332 | bond->curr_active_slave->jiffies)) | 2354 | curr_active_slave->last_link_up)) |
| 2333 | bond_validate_arp(bond, slave, tip, sip); | 2355 | bond_validate_arp(bond, slave, tip, sip); |
| 2334 | 2356 | ||
| 2335 | out_unlock: | 2357 | out_unlock: |
| 2336 | read_unlock(&bond->lock); | ||
| 2337 | if (arp != (struct arphdr *)skb->data) | 2358 | if (arp != (struct arphdr *)skb->data) |
| 2338 | kfree(arp); | 2359 | kfree(arp); |
| 2339 | return RX_HANDLER_ANOTHER; | 2360 | return RX_HANDLER_ANOTHER; |
| @@ -2376,9 +2397,9 @@ static void bond_loadbalance_arp_mon(struct work_struct *work) · 36 unmodified lines | |||
| 2376 | oldcurrent = ACCESS_ONCE(bond->curr_active_slave); | 2397 | oldcurrent = ACCESS_ONCE(bond->curr_active_slave); |
| 2377 | /* see if any of the previous devices are up now (i.e. they have | 2398 | /* see if any of the previous devices are up now (i.e. they have |
| 2378 | * xmt and rcv traffic). the curr_active_slave does not come into | 2399 | * xmt and rcv traffic). the curr_active_slave does not come into |
| 2379 | * the picture unless it is null. also, slave->jiffies is not needed | 2400 | * the picture unless it is null. also, slave->last_link_up is not |
| 2380 | * here because we send an arp on each slave and give a slave as | 2401 | * needed here because we send an arp on each slave and give a slave |
| 2381 | * long as it needs to get the tx/rx within the delta. | 2402 | * as long as it needs to get the tx/rx within the delta. |
| 2382 | * TODO: what about up/down delay in arp mode? it wasn't here before | 2403 | * TODO: what about up/down delay in arp mode? it wasn't here before |
| 2383 | * so it can wait | 2404 | * so it can wait |
| 2384 | */ | 2405 | */ |
| @@ -2387,7 +2408,7 @@ static void bond_loadbalance_arp_mon(struct work_struct *work) · 2 unmodified lines | |||
| 2387 | 2408 | ||
| 2388 | if (slave->link != BOND_LINK_UP) { | 2409 | if (slave->link != BOND_LINK_UP) { |
| 2389 | if (bond_time_in_interval(bond, trans_start, 1) && | 2410 | if (bond_time_in_interval(bond, trans_start, 1) && |
| 2390 | bond_time_in_interval(bond, slave->dev->last_rx, 1)) { | 2411 | bond_time_in_interval(bond, slave->last_rx, 1)) { |
| 2391 | 2412 | ||
| 2392 | slave->link = BOND_LINK_UP; | 2413 | slave->link = BOND_LINK_UP; |
| 2393 | slave_state_changed = 1; | 2414 | slave_state_changed = 1; |
| @@ -2398,7 +2419,7 @@ static void bond_loadbalance_arp_mon(struct work_struct *work) · 4 unmodified lines | |||
| 2398 | * is closed. | 2419 | * is closed. |
| 2399 | */ | 2420 | */ |
| 2400 | if (!oldcurrent) { | 2421 | if (!oldcurrent) { |
| 2401 | pr_info("%s: link status definitely up for interface %s, ", | 2422 | pr_info("%s: link status definitely up for interface %s\n", |
| 2402 | bond->dev->name, | 2423 | bond->dev->name, |
| 2403 | slave->dev->name); | 2424 | slave->dev->name); |
| 2404 | do_failover = 1; | 2425 | do_failover = 1; |
| @@ -2416,7 +2437,7 @@ static void bond_loadbalance_arp_mon(struct work_struct *work) · 11 unmodified lines | |||
| 2416 | * if we don't know our ip yet | 2437 | * if we don't know our ip yet |
| 2417 | */ | 2438 | */ |
| 2418 | if (!bond_time_in_interval(bond, trans_start, 2) || | 2439 | if (!bond_time_in_interval(bond, trans_start, 2) || |
| 2419 | !bond_time_in_interval(bond, slave->dev->last_rx, 2)) { | 2440 | !bond_time_in_interval(bond, slave->last_rx, 2)) { |
| 2420 | 2441 | ||
| 2421 | slave->link = BOND_LINK_DOWN; | 2442 | slave->link = BOND_LINK_DOWN; |
| 2422 | slave_state_changed = 1; | 2443 | slave_state_changed = 1; |
| @@ -2424,9 +2445,8 @@ static void bond_loadbalance_arp_mon(struct work_struct *work) · 1 unmodified line | |||
| 2424 | if (slave->link_failure_count < UINT_MAX) | 2445 | if (slave->link_failure_count < UINT_MAX) |
| 2425 | slave->link_failure_count++; | 2446 | slave->link_failure_count++; |
| 2426 | 2447 | ||
| 2427 | pr_info("%s: interface %s is now down.\n", | 2448 | pr_info("%s: interface %s is now down\n", |
| 2428 | bond->dev->name, | 2449 | bond->dev->name, slave->dev->name); |
| 2429 | slave->dev->name); | ||
| 2430 | 2450 | ||
| 2431 | if (slave == oldcurrent) | 2451 | if (slave == oldcurrent) |
| 2432 | do_failover = 1; | 2452 | do_failover = 1; |
| @@ -2505,7 +2525,7 @@ static int bond_ab_arp_inspect(struct bonding *bond) · 72 unmodified lines | |||
| 2505 | * active. This avoids bouncing, as the last receive | 2525 | * active. This avoids bouncing, as the last receive |
| 2506 | * times need a full ARP monitor cycle to be updated. | 2526 | * times need a full ARP monitor cycle to be updated. |
| 2507 | */ | 2527 | */ |
| 2508 | if (bond_time_in_interval(bond, slave->jiffies, 2)) | 2528 | if (bond_time_in_interval(bond, slave->last_link_up, 2)) |
| 2509 | continue; | 2529 | continue; |
| 2510 | 2530 | ||
| 2511 | /* | 2531 | /* |
| @@ -2576,7 +2596,7 @@ static void bond_ab_arp_commit(struct bonding *bond) · 64 unmodified lines | |||
| 2576 | bond->current_arp_slave = NULL; | 2596 | bond->current_arp_slave = NULL; |
| 2577 | } | 2597 | } |
| 2578 | 2598 | ||
| 2579 | pr_info("%s: link status definitely up for interface %s.\n", | 2599 | pr_info("%s: link status definitely up for interface %s\n", |
| 2580 | bond->dev->name, slave->dev->name); | 2600 | bond->dev->name, slave->dev->name); |
| 2581 | 2601 | ||
| 2582 | if (!bond->curr_active_slave || | 2602 | if (!bond->curr_active_slave || |
| @@ -2682,7 +2702,7 @@ static bool bond_ab_arp_probe(struct bonding *bond) · 99 unmodified lines | |||
| 2682 | bond_set_slave_inactive_flags(slave, | 2702 | bond_set_slave_inactive_flags(slave, |
| 2683 | BOND_SLAVE_NOTIFY_LATER); | 2703 | BOND_SLAVE_NOTIFY_LATER); |
| 2684 | 2704 | ||
| 2685 | pr_info("%s: backup interface %s is now down.\n", | 2705 | pr_info("%s: backup interface %s is now down\n", |
| 2686 | bond->dev->name, slave->dev->name); | 2706 | bond->dev->name, slave->dev->name); |
| 2687 | } | 2707 | } |
| 2688 | if (slave == curr_arp_slave) | 2708 | if (slave == curr_arp_slave) |
| @@ -2698,7 +2718,7 @@ static bool bond_ab_arp_probe(struct bonding *bond) · 9 unmodified lines | |||
| 2698 | new_slave->link = BOND_LINK_BACK; | 2718 | new_slave->link = BOND_LINK_BACK; |
| 2699 | bond_set_slave_active_flags(new_slave, BOND_SLAVE_NOTIFY_LATER); | 2719 | bond_set_slave_active_flags(new_slave, BOND_SLAVE_NOTIFY_LATER); |
| 2700 | bond_arp_send_all(bond, new_slave); | 2720 | bond_arp_send_all(bond, new_slave); |
| 2701 | new_slave->jiffies = jiffies; | 2721 | new_slave->last_link_up = jiffies; |
| 2702 | rcu_assign_pointer(bond->current_arp_slave, new_slave); | 2722 | rcu_assign_pointer(bond->current_arp_slave, new_slave); |
| 2703 | 2723 | ||
| 2704 | check_state: | 2724 | check_state: |
| @@ -2879,9 +2899,9 @@ static int bond_slave_netdev_event(unsigned long event, · 174 unmodified lines | |||
| 2879 | break; | 2899 | break; |
| 2880 | } | 2900 | } |
| 2881 | 2901 | ||
| 2882 | pr_info("%s: Primary slave changed to %s, reselecting active slave.\n", | 2902 | pr_info("%s: Primary slave changed to %s, reselecting active slave\n", |
| 2883 | bond->dev->name, bond->primary_slave ? slave_dev->name : | 2903 | bond->dev->name, |
| 2884 | "none"); | 2904 | bond->primary_slave ? slave_dev->name : "none"); |
| 2885 | 2905 | ||
| 2886 | block_netpoll_tx(); | 2906 | block_netpoll_tx(); |
| 2887 | write_lock_bh(&bond->curr_slave_lock); | 2907 | write_lock_bh(&bond->curr_slave_lock); |
| @@ -2917,8 +2937,7 @@ static int bond_netdev_event(struct notifier_block *this, · 29 unmodified lines | |||
| 2917 | struct net_device *event_dev = netdev_notifier_info_to_dev(ptr); | 2937 | struct net_device *event_dev = netdev_notifier_info_to_dev(ptr); |
| 2918 | 2938 | ||
| 2919 | pr_debug("event_dev: %s, event: %lx\n", | 2939 | pr_debug("event_dev: %s, event: %lx\n", |
| 2920 | event_dev ? event_dev->name : "None", | 2940 | event_dev ? event_dev->name : "None", event); |
| 2921 | event); | ||
| 2922 | 2941 | ||
| 2923 | if (!(event_dev->priv_flags & IFF_BONDING)) | 2942 | if (!(event_dev->priv_flags & IFF_BONDING)) |
| 2924 | return NOTIFY_DONE; | 2943 | return NOTIFY_DONE; |
| @@ -2967,7 +2986,7 @@ static bool bond_flow_dissect(struct bonding *bond, struct sk_buff *skb, · 42 unmodified lines | |||
| 2967 | fk->ports = 0; | 2986 | fk->ports = 0; |
| 2968 | noff = skb_network_offset(skb); | 2987 | noff = skb_network_offset(skb); |
| 2969 | if (skb->protocol == htons(ETH_P_IP)) { | 2988 | if (skb->protocol == htons(ETH_P_IP)) { |
| 2970 | if (!pskb_may_pull(skb, noff + sizeof(*iph))) | 2989 | if (unlikely(!pskb_may_pull(skb, noff + sizeof(*iph)))) |
| 2971 | return false; | 2990 | return false; |
| 2972 | iph = ip_hdr(skb); | 2991 | iph = ip_hdr(skb); |
| 2973 | fk->src = iph->saddr; | 2992 | fk->src = iph->saddr; |
| @@ -2976,7 +2995,7 @@ static bool bond_flow_dissect(struct bonding *bond, struct sk_buff *skb, · 2 unmodified lines | |||
| 2976 | if (!ip_is_fragment(iph)) | 2995 | if (!ip_is_fragment(iph)) |
| 2977 | proto = iph->protocol; | 2996 | proto = iph->protocol; |
| 2978 | } else if (skb->protocol == htons(ETH_P_IPV6)) { | 2997 | } else if (skb->protocol == htons(ETH_P_IPV6)) { |
| 2979 | if (!pskb_may_pull(skb, noff + sizeof(*iph6))) | 2998 | if (unlikely(!pskb_may_pull(skb, noff + sizeof(*iph6)))) |
| 2980 | return false; | 2999 | return false; |
| 2981 | iph6 = ipv6_hdr(skb); | 3000 | iph6 = ipv6_hdr(skb); |
| 2982 | fk->src = (__force __be32)ipv6_addr_hash(&iph6->saddr); | 3001 | fk->src = (__force __be32)ipv6_addr_hash(&iph6->saddr); |
| @@ -3087,8 +3106,7 @@ static int bond_open(struct net_device *bond_dev) · 104 unmodified lines | |||
| 3087 | 3106 | ||
| 3088 | if (bond->params.arp_interval) { /* arp interval, in milliseconds. */ | 3107 | if (bond->params.arp_interval) { /* arp interval, in milliseconds. */ |
| 3089 | queue_delayed_work(bond->wq, &bond->arp_work, 0); | 3108 | queue_delayed_work(bond->wq, &bond->arp_work, 0); |
| 3090 | if (bond->params.arp_validate) | 3109 | bond->recv_probe = bond_arp_rcv; |
| 3091 | bond->recv_probe = bond_arp_rcv; | ||
| 3092 | } | 3110 | } |
| 3093 | 3111 | ||
| 3094 | if (bond->params.mode == BOND_MODE_8023AD) { | 3112 | if (bond->params.mode == BOND_MODE_8023AD) { |
| @@ -3375,8 +3393,8 @@ static int bond_change_mtu(struct net_device *bond_dev, int new_mtu) · 280 unmodified lines | |||
| 3375 | struct list_head *iter; | 3393 | struct list_head *iter; |
| 3376 | int res = 0; | 3394 | int res = 0; |
| 3377 | 3395 | ||
| 3378 | pr_debug("bond=%p, name=%s, new_mtu=%d\n", bond, | 3396 | pr_debug("bond=%p, name=%s, new_mtu=%d\n", |
| 3379 | (bond_dev ? bond_dev->name : "None"), new_mtu); | 3397 | bond, bond_dev ? bond_dev->name : "None", new_mtu); |
| 3380 | 3398 | ||
| 3381 | /* Can't hold bond->lock with bh disabled here since | 3399 | /* Can't hold bond->lock with bh disabled here since |
| 3382 | * some base drivers panic. On the other hand we can't | 3400 | * some base drivers panic. On the other hand we can't |
| @@ -3395,8 +3413,7 @@ static int bond_change_mtu(struct net_device *bond_dev, int new_mtu) · 12 unmodified lines | |||
| 3395 | 3413 | ||
| 3396 | bond_for_each_slave(bond, slave, iter) { | 3414 | bond_for_each_slave(bond, slave, iter) { |
| 3397 | pr_debug("s %p c_m %p\n", | 3415 | pr_debug("s %p c_m %p\n", |
| 3398 | slave, | 3416 | slave, slave->dev->netdev_ops->ndo_change_mtu); |
| 3399 | slave->dev->netdev_ops->ndo_change_mtu); | ||
| 3400 | 3417 | ||
| 3401 | res = dev_set_mtu(slave->dev, new_mtu); | 3418 | res = dev_set_mtu(slave->dev, new_mtu); |
| 3402 | 3419 | ||
| @@ -3484,15 +3501,7 @@ static int bond_set_mac_address(struct net_device *bond_dev, void *addr) · 81 unmodified lines | |||
| 3484 | */ | 3501 | */ |
| 3485 | 3502 | ||
| 3486 | bond_for_each_slave(bond, slave, iter) { | 3503 | bond_for_each_slave(bond, slave, iter) { |
| 3487 | const struct net_device_ops *slave_ops = slave->dev->netdev_ops; | ||
| 3488 | pr_debug("slave %p %s\n", slave, slave->dev->name); | 3504 | pr_debug("slave %p %s\n", slave, slave->dev->name); |
| 3489 | |||
| 3490 | if (slave_ops->ndo_set_mac_address == NULL) { | ||
| 3491 | res = -EOPNOTSUPP; | ||
| 3492 | pr_debug("EOPNOTSUPP %s\n", slave->dev->name); | ||
| 3493 | goto unwind; | ||
| 3494 | } | ||
| 3495 | |||
| 3496 | res = dev_set_mac_address(slave->dev, addr); | 3505 | res = dev_set_mac_address(slave->dev, addr); |
| 3497 | if (res) { | 3506 | if (res) { |
| 3498 | /* TODO: consider downing the slave | 3507 | /* TODO: consider downing the slave |
| @@ -3568,7 +3577,7 @@ static void bond_xmit_slave_id(struct bonding *bond, struct sk_buff *skb, int sl · 69 unmodified lines | |||
| 3568 | } | 3577 | } |
| 3569 | } | 3578 | } |
| 3570 | /* no slave that can tx has been found */ | 3579 | /* no slave that can tx has been found */ |
| 3571 | kfree_skb(skb); | 3580 | dev_kfree_skb_any(skb); |
| 3572 | } | 3581 | } |
| 3573 | 3582 | ||
| 3574 | /** | 3583 | /** |
| @@ -3644,7 +3653,7 @@ static int bond_xmit_activebackup(struct sk_buff *skb, struct net_device *bond_d · 69 unmodified lines | |||
| 3644 | if (slave) | 3653 | if (slave) |
| 3645 | bond_dev_queue_xmit(bond, skb, slave->dev); | 3654 | bond_dev_queue_xmit(bond, skb, slave->dev); |
| 3646 | else | 3655 | else |
| 3647 | kfree_skb(skb); | 3656 | dev_kfree_skb_any(skb); |
| 3648 | 3657 | ||
| 3649 | return NETDEV_TX_OK; | 3658 | return NETDEV_TX_OK; |
| 3650 | } | 3659 | } |
| @@ -3676,8 +3685,8 @@ static int bond_xmit_broadcast(struct sk_buff *skb, struct net_device *bond_dev) · 25 unmodified lines | |||
| 3676 | struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC); | 3685 | struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC); |
| 3677 | 3686 | ||
| 3678 | if (!skb2) { | 3687 | if (!skb2) { |
| 3679 | pr_err("%s: Error: bond_xmit_broadcast(): skb_clone() failed\n", | 3688 | net_err_ratelimited("%s: Error: %s: skb_clone() failed\n", |
| 3680 | bond_dev->name); | 3689 | bond_dev->name, __func__); |
| 3681 | continue; | 3690 | continue; |
| 3682 | } | 3691 | } |
| 3683 | /* bond_dev_queue_xmit always returns 0 */ | 3692 | /* bond_dev_queue_xmit always returns 0 */ |
| @@ -3687,7 +3696,7 @@ static int bond_xmit_broadcast(struct sk_buff *skb, struct net_device *bond_dev) · 3 unmodified lines | |||
| 3687 | if (slave && IS_UP(slave->dev) && slave->link == BOND_LINK_UP) | 3696 | if (slave && IS_UP(slave->dev) && slave->link == BOND_LINK_UP) |
| 3688 | bond_dev_queue_xmit(bond, skb, slave->dev); | 3697 | bond_dev_queue_xmit(bond, skb, slave->dev); |
| 3689 | else | 3698 | else |
| 3690 | kfree_skb(skb); | 3699 | dev_kfree_skb_any(skb); |
| 3691 | 3700 | ||
| 3692 | return NETDEV_TX_OK; | 3701 | return NETDEV_TX_OK; |
| 3693 | } | 3702 | } |
| @@ -3774,7 +3783,7 @@ static netdev_tx_t __bond_start_xmit(struct sk_buff *skb, struct net_device *dev · 80 unmodified lines | |||
| 3774 | pr_err("%s: Error: Unknown bonding mode %d\n", | 3783 | pr_err("%s: Error: Unknown bonding mode %d\n", |
| 3775 | dev->name, bond->params.mode); | 3784 | dev->name, bond->params.mode); |
| 3776 | WARN_ON_ONCE(1); | 3785 | WARN_ON_ONCE(1); |
| 3777 | kfree_skb(skb); | 3786 | dev_kfree_skb_any(skb); |
| 3778 | return NETDEV_TX_OK; | 3787 | return NETDEV_TX_OK; |
| 3779 | } | 3788 | } |
| 3780 | } | 3789 | } |
| @@ -3788,14 +3797,14 @@ static netdev_tx_t bond_start_xmit(struct sk_buff *skb, struct net_device *dev) · 7 unmodified lines | |||
| 3788 | * If we risk deadlock from transmitting this in the | 3797 | * If we risk deadlock from transmitting this in the |
| 3789 | * netpoll path, tell netpoll to queue the frame for later tx | 3798 | * netpoll path, tell netpoll to queue the frame for later tx |
| 3790 | */ | 3799 | */ |
| 3791 | if (is_netpoll_tx_blocked(dev)) | 3800 | if (unlikely(is_netpoll_tx_blocked(dev))) |
| 3792 | return NETDEV_TX_BUSY; | 3801 | return NETDEV_TX_BUSY; |
| 3793 | 3802 | ||
| 3794 | rcu_read_lock(); | 3803 | rcu_read_lock(); |
| 3795 | if (bond_has_slaves(bond)) | 3804 | if (bond_has_slaves(bond)) |
| 3796 | ret = __bond_start_xmit(skb, dev); | 3805 | ret = __bond_start_xmit(skb, dev); |
| 3797 | else | 3806 | else |
| 3798 | kfree_skb(skb); | 3807 | dev_kfree_skb_any(skb); |
| 3799 | rcu_read_unlock(); | 3808 | rcu_read_unlock(); |
| 3800 | 3809 | ||
| 3801 | return ret; | 3810 | return ret; |
| @@ -3958,7 +3967,7 @@ static void bond_uninit(struct net_device *bond_dev) · 156 unmodified lines | |||
| 3958 | /* Release the bonded slaves */ | 3967 | /* Release the bonded slaves */ |
| 3959 | bond_for_each_slave(bond, slave, iter) | 3968 | bond_for_each_slave(bond, slave, iter) |
| 3960 | __bond_release_one(bond_dev, slave->dev, true); | 3969 | __bond_release_one(bond_dev, slave->dev, true); |
| 3961 | pr_info("%s: released all slaves\n", bond_dev->name); | 3970 | pr_info("%s: Released all slaves\n", bond_dev->name); |
| 3962 | 3971 | ||
| 3963 | list_del(&bond->bond_list); | 3972 | list_del(&bond->bond_list); |
| 3964 | 3973 | ||
| @@ -3967,56 +3976,11 @@ static void bond_uninit(struct net_device *bond_dev) · 2 unmodified lines | |||
| 3967 | 3976 | ||
| 3968 | /*------------------------- Module initialization ---------------------------*/ | 3977 | /*------------------------- Module initialization ---------------------------*/ |
| 3969 | 3978 | ||
| 3970 | int bond_parm_tbl_lookup(int mode, const struct bond_parm_tbl *tbl) | ||
| 3971 | { | ||
| 3972 | int i; | ||
| 3973 | |||
| 3974 | for (i = 0; tbl[i].modename; i++) | ||
| 3975 | if (mode == tbl[i].mode) | ||
| 3976 | return tbl[i].mode; | ||
| 3977 | |||
| 3978 | return -1; | ||
| 3979 | } | ||
| 3980 | |||
| 3981 | static int bond_parm_tbl_lookup_name(const char *modename, | ||
| 3982 | const struct bond_parm_tbl *tbl) | ||
| 3983 | { | ||
| 3984 | int i; | ||
| 3985 | |||
| 3986 | for (i = 0; tbl[i].modename; i++) | ||
| 3987 | if (strcmp(modename, tbl[i].modename) == 0) | ||
| 3988 | return tbl[i].mode; | ||
| 3989 | |||
| 3990 | return -1; | ||
| 3991 | } | ||
| 3992 | |||
| 3993 | /* | ||
| 3994 | * Convert string input module parms. Accept either the | ||
| 3995 | * number of the mode or its string name. A bit complicated because | ||
| 3996 | * some mode names are substrings of other names, and calls from sysfs | ||
| 3997 | * may have whitespace in the name (trailing newlines, for example). | ||
| 3998 | */ | ||
| 3999 | int bond_parse_parm(const char *buf, const struct bond_parm_tbl *tbl) | ||
| 4000 | { | ||
| 4001 | int modeint; | ||
| 4002 | char *p, modestr[BOND_MAX_MODENAME_LEN + 1]; | ||
| 4003 | |||
| 4004 | for (p = (char *)buf; *p; p++) | ||
| 4005 | if (!(isdigit(*p) || isspace(*p))) | ||
| 4006 | break; | ||
| 4007 | |||
| 4008 | if (*p && sscanf(buf, "%20s", modestr) != 0) | ||
| 4009 | return bond_parm_tbl_lookup_name(modestr, tbl); | ||
| 4010 | else if (sscanf(buf, "%d", &modeint) != 0) | ||
| 4011 | return bond_parm_tbl_lookup(modeint, tbl); | ||
| 4012 | |||
| 4013 | return -1; | ||
| 4014 | } | ||
| 4015 | |||
| 4016 | static int bond_check_params(struct bond_params *params) | 3979 | static int bond_check_params(struct bond_params *params) |
| 4017 | { | 3980 | { |
| 4018 | int arp_validate_value, fail_over_mac_value, primary_reselect_value, i; | 3981 | int arp_validate_value, fail_over_mac_value, primary_reselect_value, i; |
| 4019 | struct bond_opt_value newval, *valptr; | 3982 | struct bond_opt_value newval; |
| 3983 | const struct bond_opt_value *valptr; | ||
| 4020 | int arp_all_targets_value; | 3984 | int arp_all_targets_value; |
| 4021 | 3985 | ||
| 4022 | /* | 3986 | /* |
| @@ -4036,7 +4000,7 @@ static int bond_check_params(struct bond_params *params) · 13 unmodified lines | |||
| 4036 | if ((bond_mode != BOND_MODE_XOR) && | 4000 | if ((bond_mode != BOND_MODE_XOR) && |
| 4037 | (bond_mode != BOND_MODE_8023AD)) { | 4001 | (bond_mode != BOND_MODE_8023AD)) { |
| 4038 | pr_info("xmit_hash_policy param is irrelevant in mode %s\n", | 4002 | pr_info("xmit_hash_policy param is irrelevant in mode %s\n", |
| 4039 | bond_mode_name(bond_mode)); | 4003 | bond_mode_name(bond_mode)); |
| 4040 | } else { | 4004 | } else { |
| 4041 | bond_opt_initstr(&newval, xmit_hash_policy); | 4005 | bond_opt_initstr(&newval, xmit_hash_policy); |
| 4042 | valptr = bond_opt_parse(bond_opt_get(BOND_OPT_XMIT_HASH), | 4006 | valptr = bond_opt_parse(bond_opt_get(BOND_OPT_XMIT_HASH), |
| @@ -4077,74 +4041,71 @@ static int bond_check_params(struct bond_params *params) · 34 unmodified lines | |||
| 4077 | } | 4041 | } |
| 4078 | params->ad_select = valptr->value; | 4042 | params->ad_select = valptr->value; |
| 4079 | if (bond_mode != BOND_MODE_8023AD) | 4043 | if (bond_mode != BOND_MODE_8023AD) |
| 4080 | pr_warning("ad_select param only affects 802.3ad mode\n"); | 4044 | pr_warn("ad_select param only affects 802.3ad mode\n"); |
| 4081 | } else { | 4045 | } else { |
| 4082 | params->ad_select = BOND_AD_STABLE; | 4046 | params->ad_select = BOND_AD_STABLE; |
| 4083 | } | 4047 | } |
| 4084 | 4048 | ||
| 4085 | if (max_bonds < 0) { | 4049 | if (max_bonds < 0) { |
| 4086 | pr_warning("Warning: max_bonds (%d) not in range %d-%d, so it was reset to BOND_DEFAULT_MAX_BONDS (%d)\n", | 4050 | pr_warn("Warning: max_bonds (%d) not in range %d-%d, so it was reset to BOND_DEFAULT_MAX_BONDS (%d)\n", |
| 4087 | max_bonds, 0, INT_MAX, BOND_DEFAULT_MAX_BONDS); | 4051 | max_bonds, 0, INT_MAX, BOND_DEFAULT_MAX_BONDS); |
| 4088 | max_bonds = BOND_DEFAULT_MAX_BONDS; | 4052 | max_bonds = BOND_DEFAULT_MAX_BONDS; |
| 4089 | } | 4053 | } |
| 4090 | 4054 | ||
| 4091 | if (miimon < 0) { | 4055 | if (miimon < 0) { |
| 4092 | pr_warning("Warning: miimon module parameter (%d), not in range 0-%d, so it was reset to 0\n", | 4056 | pr_warn("Warning: miimon module parameter (%d), not in range 0-%d, so it was reset to 0\n", |
| 4093 | miimon, INT_MAX); | 4057 | miimon, INT_MAX); |
| 4094 | miimon = 0; | 4058 | miimon = 0; |
| 4095 | } | 4059 | } |
| 4096 | 4060 | ||
| 4097 | if (updelay < 0) { | 4061 | if (updelay < 0) { |
| 4098 | pr_warning("Warning: updelay module parameter (%d), not in range 0-%d, so it was reset to 0\n", | 4062 | pr_warn("Warning: updelay module parameter (%d), not in range 0-%d, so it was reset to 0\n", |
| 4099 | updelay, INT_MAX); | 4063 | updelay, INT_MAX); |
| 4100 | updelay = 0; | 4064 | updelay = 0; |
| 4101 | } | 4065 | } |
| 4102 | 4066 | ||
| 4103 | if (downdelay < 0) { | 4067 | if (downdelay < 0) { |
| 4104 | pr_warning("Warning: downdelay module parameter (%d), not in range 0-%d, so it was reset to 0\n", | 4068 | pr_warn("Warning: downdelay module parameter (%d), not in range 0-%d, so it was reset to 0\n", |
| 4105 | downdelay, INT_MAX); | 4069 | downdelay, INT_MAX); |
| 4106 | downdelay = 0; | 4070 | downdelay = 0; |
| 4107 | } | 4071 | } |
| 4108 | 4072 | ||
| 4109 | if ((use_carrier != 0) && (use_carrier != 1)) { | 4073 | if ((use_carrier != 0) && (use_carrier != 1)) { |
| 4110 | pr_warning("Warning: use_carrier module parameter (%d), not of valid value (0/1), so it was set to 1\n", | 4074 | pr_warn("Warning: use_carrier module parameter (%d), not of valid value (0/1), so it was set to 1\n", |
| 4111 | use_carrier); | 4075 | use_carrier); |
| 4112 | use_carrier = 1; | 4076 | use_carrier = 1; |
| 4113 | } | 4077 | } |
| 4114 | 4078 | ||
| 4115 | if (num_peer_notif < 0 || num_peer_notif > 255) { | 4079 | if (num_peer_notif < 0 || num_peer_notif > 255) { |
| 4116 | pr_warning("Warning: num_grat_arp/num_unsol_na (%d) not in range 0-255 so it was reset to 1\n", | 4080 | pr_warn("Warning: num_grat_arp/num_unsol_na (%d) not in range 0-255 so it was reset to 1\n", |
| 4117 | num_peer_notif); | 4081 | num_peer_notif); |
| 4118 | num_peer_notif = 1; | 4082 | num_peer_notif = 1; |
| 4119 | } | 4083 | } |
| 4120 | 4084 | ||
| 4121 | /* reset values for 802.3ad/TLB/ALB */ | 4085 | /* reset values for 802.3ad/TLB/ALB */ |
| 4122 | if (BOND_NO_USES_ARP(bond_mode)) { | 4086 | if (BOND_NO_USES_ARP(bond_mode)) { |
| 4123 | if (!miimon) { | 4087 | if (!miimon) { |
| 4124 | pr_warning("Warning: miimon must be specified, otherwise bonding will not detect link failure, speed and duplex which are essential for 802.3ad operation\n"); | 4088 | pr_warn("Warning: miimon must be specified, otherwise bonding will not detect link failure, speed and duplex which are essential for 802.3ad operation\n"); |
| 4125 | pr_warning("Forcing miimon to 100msec\n"); | 4089 | pr_warn("Forcing miimon to 100msec\n"); |
| 4126 | miimon = BOND_DEFAULT_MIIMON; | 4090 | miimon = BOND_DEFAULT_MIIMON; |
| 4127 | } | 4091 | } |
| 4128 | } | 4092 | } |
| 4129 | 4093 | ||
| 4130 | if (tx_queues < 1 || tx_queues > 255) { | 4094 | if (tx_queues < 1 || tx_queues > 255) { |
| 4131 | pr_warning("Warning: tx_queues (%d) should be between " | 4095 | pr_warn("Warning: tx_queues (%d) should be between 1 and 255, resetting to %d\n", |
| 4132 | "1 and 255, resetting to %d\n", | 4096 | tx_queues, BOND_DEFAULT_TX_QUEUES); |
| 4133 | tx_queues, BOND_DEFAULT_TX_QUEUES); | ||
| 4134 | tx_queues = BOND_DEFAULT_TX_QUEUES; | 4097 | tx_queues = BOND_DEFAULT_TX_QUEUES; |
| 4135 | } | 4098 | } |
| 4136 | 4099 | ||
| 4137 | if ((all_slaves_active != 0) && (all_slaves_active != 1)) { | 4100 | if ((all_slaves_active != 0) && (all_slaves_active != 1)) { |
| 4138 | pr_warning("Warning: all_slaves_active module parameter (%d), " | 4101 | pr_warn("Warning: all_slaves_active module parameter (%d), not of valid value (0/1), so it was set to 0\n", |
| 4139 | "not of valid value (0/1), so it was set to " | 4102 | all_slaves_active); |
| 4140 | "0\n", all_slaves_active); | ||
| 4141 | all_slaves_active = 0; | 4103 | all_slaves_active = 0; |
| 4142 | } | 4104 | } |
| 4143 | 4105 | ||
| 4144 | if (resend_igmp < 0 || resend_igmp > 255) { | 4106 | if (resend_igmp < 0 || resend_igmp > 255) { |
| 4145 | pr_warning("Warning: resend_igmp (%d) should be between " | 4107 | pr_warn("Warning: resend_igmp (%d) should be between 0 and 255, resetting to %d\n", |
| 4146 | "0 and 255, resetting to %d\n", | 4108 | resend_igmp, BOND_DEFAULT_RESEND_IGMP); |
| 4147 | resend_igmp, BOND_DEFAULT_RESEND_IGMP); | ||
| 4148 | resend_igmp = BOND_DEFAULT_RESEND_IGMP; | 4109 | resend_igmp = BOND_DEFAULT_RESEND_IGMP; |
| 4149 | } | 4110 | } |
| 4150 | 4111 | ||
| @@ -4165,37 +4126,36 @@ static int bond_check_params(struct bond_params *params) · 14 unmodified lines | |||
| 4165 | /* just warn the user the up/down delay will have | 4126 | /* just warn the user the up/down delay will have |
| 4166 | * no effect since miimon is zero... | 4127 | * no effect since miimon is zero... |
| 4167 | */ | 4128 | */ |
| 4168 | pr_warning("Warning: miimon module parameter not set and updelay (%d) or downdelay (%d) module parameter is set; updelay and downdelay have no effect unless miimon is set\n", | 4129 | pr_warn("Warning: miimon module parameter not set and updelay (%d) or downdelay (%d) module parameter is set; updelay and downdelay have no effect unless miimon is set\n", |
| 4169 | updelay, downdelay); | 4130 | updelay, downdelay); |
| 4170 | } | 4131 | } |
| 4171 | } else { | 4132 | } else { |
| 4172 | /* don't allow arp monitoring */ | 4133 | /* don't allow arp monitoring */ |
| 4173 | if (arp_interval) { | 4134 | if (arp_interval) { |
| 4174 | pr_warning("Warning: miimon (%d) and arp_interval (%d) can't be used simultaneously, disabling ARP monitoring\n", | 4135 | pr_warn("Warning: miimon (%d) and arp_interval (%d) can't be used simultaneously, disabling ARP monitoring\n", |
| 4175 | miimon, arp_interval); | 4136 | miimon, arp_interval); |
| 4176 | arp_interval = 0; | 4137 | arp_interval = 0; |
| 4177 | } | 4138 | } |
| 4178 | 4139 | ||
| 4179 | if ((updelay % miimon) != 0) { | 4140 | if ((updelay % miimon) != 0) { |
| 4180 | pr_warning("Warning: updelay (%d) is not a multiple of miimon (%d), updelay rounded to %d ms\n", | 4141 | pr_warn("Warning: updelay (%d) is not a multiple of miimon (%d), updelay rounded to %d ms\n", |
| 4181 | updelay, miimon, | 4142 | updelay, miimon, (updelay / miimon) * miimon); |
| 4182 | (updelay / miimon) * miimon); | ||
| 4183 | } | 4143 | } |
| 4184 | 4144 | ||
| 4185 | updelay /= miimon; | 4145 | updelay /= miimon; |
| 4186 | 4146 | ||
| 4187 | if ((downdelay % miimon) != 0) { | 4147 | if ((downdelay % miimon) != 0) { |
| 4188 | pr_warning("Warning: downdelay (%d) is not a multiple of miimon (%d), downdelay rounded to %d ms\n", | 4148 | pr_warn("Warning: downdelay (%d) is not a multiple of miimon (%d), downdelay rounded to %d ms\n", |
| 4189 | downdelay, miimon, | 4149 | downdelay, miimon, |
| 4190 | (downdelay / miimon) * miimon); | 4150 | (downdelay / miimon) * miimon); |
| 4191 | } | 4151 | } |
| 4192 | 4152 | ||
| 4193 | downdelay /= miimon; | 4153 | downdelay /= miimon; |
| 4194 | } | 4154 | } |
| 4195 | 4155 | ||
| 4196 | if (arp_interval < 0) { | 4156 | if (arp_interval < 0) { |
| 4197 | pr_warning("Warning: arp_interval module parameter (%d) , not in range 0-%d, so it was reset to 0\n", | 4157 | pr_warn("Warning: arp_interval module parameter (%d), not in range 0-%d, so it was reset to 0\n", |
| 4198 | arp_interval, INT_MAX); | 4158 | arp_interval, INT_MAX); |
| 4199 | arp_interval = 0; | 4159 | arp_interval = 0; |
| 4200 | } | 4160 | } |
| 4201 | 4161 | ||
| @@ -4206,30 +4166,26 @@ static int bond_check_params(struct bond_params *params) · 4 unmodified lines | |||
| 4206 | __be32 ip; | 4166 | __be32 ip; |
| 4207 | if (!in4_pton(arp_ip_target[i], -1, (u8 *)&ip, -1, NULL) || | 4167 | if (!in4_pton(arp_ip_target[i], -1, (u8 *)&ip, -1, NULL) || |
| 4208 | IS_IP_TARGET_UNUSABLE_ADDRESS(ip)) { | 4168 | IS_IP_TARGET_UNUSABLE_ADDRESS(ip)) { |
| 4209 | pr_warning("Warning: bad arp_ip_target module parameter (%s), ARP monitoring will not be performed\n", | 4169 | pr_warn("Warning: bad arp_ip_target module parameter (%s), ARP monitoring will not be performed\n", |
| 4210 | arp_ip_target[i]); | 4170 | arp_ip_target[i]); |
| 4211 | arp_interval = 0; | 4171 | arp_interval = 0; |
| 4212 | } else { | 4172 | } else { |
| 4213 | if (bond_get_targets_ip(arp_target, ip) == -1) | 4173 | if (bond_get_targets_ip(arp_target, ip) == -1) |
| 4214 | arp_target[arp_ip_count++] = ip; | 4174 | arp_target[arp_ip_count++] = ip; |
| 4215 | else | 4175 | else |
| 4216 | pr_warning("Warning: duplicate address %pI4 in arp_ip_target, skipping\n", | 4176 | pr_warn("Warning: duplicate address %pI4 in arp_ip_target, skipping\n", |
| 4217 | &ip); | 4177 | &ip); |
| 4218 | } | 4178 | } |
| 4219 | } | 4179 | } |
| 4220 | 4180 | ||
| 4221 | if (arp_interval && !arp_ip_count) { | 4181 | if (arp_interval && !arp_ip_count) { |
| 4222 | /* don't allow arping if no arp_ip_target given... */ | 4182 | /* don't allow arping if no arp_ip_target given... */ |
| 4223 | pr_warning("Warning: arp_interval module parameter (%d) specified without providing an arp_ip_target parameter, arp_interval was reset to 0\n", | 4183 | pr_warn("Warning: arp_interval module parameter (%d) specified without providing an arp_ip_target parameter, arp_interval was reset to 0\n", |
| 4224 | arp_interval); | 4184 | arp_interval); |
| 4225 | arp_interval = 0; | 4185 | arp_interval = 0; |
| 4226 | } | 4186 | } |
| 4227 | 4187 | ||
| 4228 | if (arp_validate) { | 4188 | if (arp_validate) { |
| 4229 | if (bond_mode != BOND_MODE_ACTIVEBACKUP) { | ||
| 4230 | pr_err("arp_validate only supported in active-backup mode\n"); | ||
| 4231 | return -EINVAL; | ||
| 4232 | } | ||
| 4233 | if (!arp_interval) { | 4189 | if (!arp_interval) { |
| 4234 | pr_err("arp_validate requires arp_interval\n"); | 4190 | pr_err("arp_validate requires arp_interval\n"); |
| 4235 | return -EINVAL; | 4191 | return -EINVAL; |
| @@ -4271,23 +4227,23 @@ static int bond_check_params(struct bond_params *params) · 35 unmodified lines | |||
| 4271 | arp_interval, valptr->string, arp_ip_count); | 4227 | arp_interval, valptr->string, arp_ip_count); |
| 4272 | 4228 | ||
| 4273 | for (i = 0; i < arp_ip_count; i++) | 4229 | for (i = 0; i < arp_ip_count; i++) |
| 4274 | pr_info(" %s", arp_ip_target[i]); | 4230 | pr_cont(" %s", arp_ip_target[i]); |
| 4275 | 4231 | ||
| 4276 | pr_info("\n"); | 4232 | pr_cont("\n"); |
| 4277 | 4233 | ||
| 4278 | } else if (max_bonds) { | 4234 | } else if (max_bonds) { |
| 4279 | /* miimon and arp_interval not set, we need one so things | 4235 | /* miimon and arp_interval not set, we need one so things |
| 4280 | * work as expected, see bonding.txt for details | 4236 | * work as expected, see bonding.txt for details |
| 4281 | */ | 4237 | */ |
| 4282 | pr_debug("Warning: either miimon or arp_interval and arp_ip_target module parameters must be specified, otherwise bonding will not detect link failures! see bonding.txt for details.\n"); | 4238 | pr_debug("Warning: either miimon or arp_interval and arp_ip_target module parameters must be specified, otherwise bonding will not detect link failures! see bonding.txt for details\n"); |
| 4283 | } | 4239 | } |
| 4284 | 4240 | ||
| 4285 | if (primary && !USES_PRIMARY(bond_mode)) { | 4241 | if (primary && !USES_PRIMARY(bond_mode)) { |
| 4286 | /* currently, using a primary only makes sense | 4242 | /* currently, using a primary only makes sense |
| 4287 | * in active backup, TLB or ALB modes | 4243 | * in active backup, TLB or ALB modes |
| 4288 | */ | 4244 | */ |
| 4289 | pr_warning("Warning: %s primary device specified but has no effect in %s mode\n", | 4245 | pr_warn("Warning: %s primary device specified but has no effect in %s mode\n", |
| 4290 | primary, bond_mode_name(bond_mode)); | 4246 | primary, bond_mode_name(bond_mode)); |
| 4291 | primary = NULL; | 4247 | primary = NULL; |
| 4292 | } | 4248 | } |
| 4293 | 4249 | ||
| @@ -4316,14 +4272,14 @@ static int bond_check_params(struct bond_params *params) · 22 unmodified lines | |||
| 4316 | } | 4272 | } |
| 4317 | fail_over_mac_value = valptr->value; | 4273 | fail_over_mac_value = valptr->value; |
| 4318 | if (bond_mode != BOND_MODE_ACTIVEBACKUP) | 4274 | if (bond_mode != BOND_MODE_ACTIVEBACKUP) |
| 4319 | pr_warning("Warning: fail_over_mac only affects active-backup mode.\n"); | 4275 | pr_warn("Warning: fail_over_mac only affects active-backup mode\n"); |
| 4320 | } else { | 4276 | } else { |
| 4321 | fail_over_mac_value = BOND_FOM_NONE; | 4277 | fail_over_mac_value = BOND_FOM_NONE; |
| 4322 | } | 4278 | } |
| 4323 | 4279 | ||
| 4324 | if (lp_interval == 0) { | 4280 | if (lp_interval == 0) { |
| 4325 | pr_warning("Warning: ip_interval must be between 1 and %d, so it was reset to %d\n", | 4281 | pr_warn("Warning: ip_interval must be between 1 and %d, so it was reset to %d\n", |
| 4326 | INT_MAX, BOND_ALB_DEFAULT_LP_INTERVAL); | 4282 | INT_MAX, BOND_ALB_DEFAULT_LP_INTERVAL); |
| 4327 | lp_interval = BOND_ALB_DEFAULT_LP_INTERVAL; | 4283 | lp_interval = BOND_ALB_DEFAULT_LP_INTERVAL; |
| 4328 | } | 4284 | } |
| 4329 | 4285 | ||
| @@ -181,7 +181,7 @@ static int bond_changelink(struct net_device *bond_dev, · 180 unmodified lines | |||
| 181 | int arp_interval = nla_get_u32(data[IFLA_BOND_ARP_INTERVAL]); | 181 | int arp_interval = nla_get_u32(data[IFLA_BOND_ARP_INTERVAL]); |
| 182 | 182 | ||
| 183 | if (arp_interval && miimon) { | 183 | if (arp_interval && miimon) { |
| 184 | pr_err("%s: ARP monitoring cannot be used with MII monitoring.\n", | 184 | pr_err("%s: ARP monitoring cannot be used with MII monitoring\n", |
| 185 | bond->dev->name); | 185 | bond->dev->name); |
| 186 | return -EINVAL; | 186 | return -EINVAL; |
| 187 | } | 187 | } |
| @@ -199,7 +199,7 @@ static int bond_changelink(struct net_device *bond_dev, · 11 unmodified lines | |||
| 199 | nla_for_each_nested(attr, data[IFLA_BOND_ARP_IP_TARGET], rem) { | 199 | nla_for_each_nested(attr, data[IFLA_BOND_ARP_IP_TARGET], rem) { |
| 200 | __be32 target = nla_get_be32(attr); | 200 | __be32 target = nla_get_be32(attr); |
| 201 | 201 | ||
| 202 | bond_opt_initval(&newval, target); | 202 | bond_opt_initval(&newval, (__force u64)target); |
| 203 | err = __bond_opt_set(bond, BOND_OPT_ARP_TARGETS, | 203 | err = __bond_opt_set(bond, BOND_OPT_ARP_TARGETS, |
| 204 | &newval); | 204 | &newval); |
| 205 | if (err) | 205 | if (err) |
| @@ -207,7 +207,7 @@ static int bond_changelink(struct net_device *bond_dev, · 1 unmodified line | |||
| 207 | i++; | 207 | i++; |
| 208 | } | 208 | } |
| 209 | if (i == 0 && bond->params.arp_interval) | 209 | if (i == 0 && bond->params.arp_interval) |
| 210 | pr_warn("%s: removing last arp target with arp_interval on\n", | 210 | pr_warn("%s: Removing last arp target with arp_interval on\n", |
| 211 | bond->dev->name); | 211 | bond->dev->name); |
| 212 | if (err) | 212 | if (err) |
| 213 | return err; | 213 | return err; |
| @@ -216,7 +216,7 @@ static int bond_changelink(struct net_device *bond_dev, · 2 unmodified lines | |||
| 216 | int arp_validate = nla_get_u32(data[IFLA_BOND_ARP_VALIDATE]); | 216 | int arp_validate = nla_get_u32(data[IFLA_BOND_ARP_VALIDATE]); |
| 217 | 217 | ||
| 218 | if (arp_validate && miimon) { | 218 | if (arp_validate && miimon) { |
| 219 | pr_err("%s: ARP validating cannot be used with MII monitoring.\n", | 219 | pr_err("%s: ARP validating cannot be used with MII monitoring\n", |
| 220 | bond->dev->name); | 220 | bond->dev->name); |
| 221 | return -EINVAL; | 221 | return -EINVAL; |
| 222 | } | 222 | } |
| @@ -20,7 +20,59 @@ · 19 unmodified lines | |||
| 20 | #include <linux/inet.h> | 20 | #include <linux/inet.h> |
| 21 | #include "bonding.h" | 21 | #include "bonding.h" |
| 22 | 22 | ||
| 23 | static struct bond_opt_value bond_mode_tbl[] = { | 23 | static int bond_option_active_slave_set(struct bonding *bond, |
| 24 | const struct bond_opt_value *newval); | ||
| 25 | static int bond_option_miimon_set(struct bonding *bond, | ||
| 26 | const struct bond_opt_value *newval); | ||
| 27 | static int bond_option_updelay_set(struct bonding *bond, | ||
| 28 | const struct bond_opt_value *newval); | ||
| 29 | static int bond_option_downdelay_set(struct bonding *bond, | ||
| 30 | const struct bond_opt_value *newval); | ||
| 31 | static int bond_option_use_carrier_set(struct bonding *bond, | ||
| 32 | const struct bond_opt_value *newval); | ||
| 33 | static int bond_option_arp_interval_set(struct bonding *bond, | ||
| 34 | const struct bond_opt_value *newval); | ||
| 35 | static int bond_option_arp_ip_target_add(struct bonding *bond, __be32 target); | ||
| 36 | static int bond_option_arp_ip_target_rem(struct bonding *bond, __be32 target); | ||
| 37 | static int bond_option_arp_ip_targets_set(struct bonding *bond, | ||
| 38 | const struct bond_opt_value *newval); | ||
| 39 | static int bond_option_arp_validate_set(struct bonding *bond, | ||
| 40 | const struct bond_opt_value *newval); | ||
| 41 | static int bond_option_arp_all_targets_set(struct bonding *bond, | ||
| 42 | const struct bond_opt_value *newval); | ||
| 43 | static int bond_option_primary_set(struct bonding *bond, | ||
| 44 | const struct bond_opt_value *newval); | ||
| 45 | static int bond_option_primary_reselect_set(struct bonding *bond, | ||
| 46 | const struct bond_opt_value *newval); | ||
| 47 | static int bond_option_fail_over_mac_set(struct bonding *bond, | ||
| 48 | const struct bond_opt_value *newval); | ||
| 49 | static int bond_option_xmit_hash_policy_set(struct bonding *bond, | ||
| 50 | const struct bond_opt_value *newval); | ||
| 51 | static int bond_option_resend_igmp_set(struct bonding *bond, | ||
| 52 | const struct bond_opt_value *newval); | ||
| 53 | static int bond_option_num_peer_notif_set(struct bonding *bond, | ||
| 54 | const struct bond_opt_value *newval); | ||
| 55 | static int bond_option_all_slaves_active_set(struct bonding *bond, | ||
| 56 | const struct bond_opt_value *newval); | ||
| 57 | static int bond_option_min_links_set(struct bonding *bond, | ||
| 58 | const struct bond_opt_value *newval); | ||
| 59 | static int bond_option_lp_interval_set(struct bonding *bond, | ||
| 60 | const struct bond_opt_value *newval); | ||
| 61 | static int bond_option_pps_set(struct bonding *bond, | ||
| 62 | const struct bond_opt_value *newval); | ||
| 63 | static int bond_option_lacp_rate_set(struct bonding *bond, | ||
| 64 | const struct bond_opt_value *newval); | ||
| 65 | static int bond_option_ad_select_set(struct bonding *bond, | ||
| 66 | const struct bond_opt_value *newval); | ||
| 67 | static int bond_option_queue_id_set(struct bonding *bond, | ||
| 68 | const struct bond_opt_value *newval); | ||
| 69 | static int bond_option_mode_set(struct bonding *bond, | ||
| 70 | const struct bond_opt_value *newval); | ||
| 71 | static int bond_option_slaves_set(struct bonding *bond, | ||
| 72 | const struct bond_opt_value *newval); | ||
| 73 | |||
| 74 | |||
| 75 | static const struct bond_opt_value bond_mode_tbl[] = { | ||
| 24 | { "balance-rr", BOND_MODE_ROUNDROBIN, BOND_VALFLAG_DEFAULT}, | 76 | { "balance-rr", BOND_MODE_ROUNDROBIN, BOND_VALFLAG_DEFAULT}, |
| 25 | { "active-backup", BOND_MODE_ACTIVEBACKUP, 0}, | 77 | { "active-backup", BOND_MODE_ACTIVEBACKUP, 0}, |
| 26 | { "balance-xor", BOND_MODE_XOR, 0}, | 78 | { "balance-xor", BOND_MODE_XOR, 0}, |
| @@ -31,13 +83,13 @@ static struct bond_opt_value bond_mode_tbl[] = { · 4 unmodified lines | |||
| 31 | { NULL, -1, 0}, | 83 | { NULL, -1, 0}, |
| 32 | }; | 84 | }; |
| 33 | 85 | ||
| 34 | static struct bond_opt_value bond_pps_tbl[] = { | 86 | static const struct bond_opt_value bond_pps_tbl[] = { |
| 35 | { "default", 1, BOND_VALFLAG_DEFAULT}, | 87 | { "default", 1, BOND_VALFLAG_DEFAULT}, |
| 36 | { "maxval", USHRT_MAX, BOND_VALFLAG_MAX}, | 88 | { "maxval", USHRT_MAX, BOND_VALFLAG_MAX}, |
| 37 | { NULL, -1, 0}, | 89 | { NULL, -1, 0}, |
| 38 | }; | 90 | }; |
| 39 | 91 | ||
| 40 | static struct bond_opt_value bond_xmit_hashtype_tbl[] = { | 92 | static const struct bond_opt_value bond_xmit_hashtype_tbl[] = { |
| 41 | { "layer2", BOND_XMIT_POLICY_LAYER2, BOND_VALFLAG_DEFAULT}, | 93 | { "layer2", BOND_XMIT_POLICY_LAYER2, BOND_VALFLAG_DEFAULT}, |
| 42 | { "layer3+4", BOND_XMIT_POLICY_LAYER34, 0}, | 94 | { "layer3+4", BOND_XMIT_POLICY_LAYER34, 0}, |
| 43 | { "layer2+3", BOND_XMIT_POLICY_LAYER23, 0}, | 95 | { "layer2+3", BOND_XMIT_POLICY_LAYER23, 0}, |
| @@ -46,85 +98,88 @@ static struct bond_opt_value bond_xmit_hashtype_tbl[] = { · 2 unmodified lines | |||
| 46 | { NULL, -1, 0}, | 98 | { NULL, -1, 0}, |
| 47 | }; | 99 | }; |
| 48 | 100 | ||
| 49 | static struct bond_opt_value bond_arp_validate_tbl[] = { | 101 | static const struct bond_opt_value bond_arp_validate_tbl[] = { |
| 50 | { "none", BOND_ARP_VALIDATE_NONE, BOND_VALFLAG_DEFAULT}, | 102 | { "none", BOND_ARP_VALIDATE_NONE, BOND_VALFLAG_DEFAULT}, |
| 51 | { "active", BOND_ARP_VALIDATE_ACTIVE, 0}, | 103 | { "active", BOND_ARP_VALIDATE_ACTIVE, 0}, |
| 52 | { "backup", BOND_ARP_VALIDATE_BACKUP, 0}, | 104 | { "backup", BOND_ARP_VALIDATE_BACKUP, 0}, |
| 53 | { "all", BOND_ARP_VALIDATE_ALL, 0}, | 105 | { "all", BOND_ARP_VALIDATE_ALL, 0}, |
| 54 | { NULL, -1, 0}, | 106 | { "filter", BOND_ARP_FILTER, 0}, |
| 107 | { "filter_active", BOND_ARP_FILTER_ACTIVE, 0}, | ||
| 108 | { "filter_backup", BOND_ARP_FILTER_BACKUP, 0}, | ||
| 109 | { NULL, -1, 0}, | ||
| 55 | }; | 110 | }; |
| 56 | 111 | ||
| 57 | static struct bond_opt_value bond_arp_all_targets_tbl[] = { | 112 | static const struct bond_opt_value bond_arp_all_targets_tbl[] = { |
| 58 | { "any", BOND_ARP_TARGETS_ANY, BOND_VALFLAG_DEFAULT}, | 113 | { "any", BOND_ARP_TARGETS_ANY, BOND_VALFLAG_DEFAULT}, |
| 59 | { "all", BOND_ARP_TARGETS_ALL, 0}, | 114 | { "all", BOND_ARP_TARGETS_ALL, 0}, |
| 60 | { NULL, -1, 0}, | 115 | { NULL, -1, 0}, |
| 61 | }; | 116 | }; |
| 62 | 117 | ||
| 63 | static struct bond_opt_value bond_fail_over_mac_tbl[] = { | 118 | static const struct bond_opt_value bond_fail_over_mac_tbl[] = { |
| 64 | { "none", BOND_FOM_NONE, BOND_VALFLAG_DEFAULT}, | 119 | { "none", BOND_FOM_NONE, BOND_VALFLAG_DEFAULT}, |
| 65 | { "active", BOND_FOM_ACTIVE, 0}, | 120 | { "active", BOND_FOM_ACTIVE, 0}, |
| 66 | { "follow", BOND_FOM_FOLLOW, 0}, | 121 | { "follow", BOND_FOM_FOLLOW, 0}, |
| 67 | { NULL, -1, 0}, | 122 | { NULL, -1, 0}, |
| 68 | }; | 123 | }; |
| 69 | 124 | ||
| 70 | static struct bond_opt_value bond_intmax_tbl[] = { | 125 | static const struct bond_opt_value bond_intmax_tbl[] = { |
| 71 | { "off", 0, BOND_VALFLAG_DEFAULT}, | 126 | { "off", 0, BOND_VALFLAG_DEFAULT}, |
| 72 | { "maxval", INT_MAX, BOND_VALFLAG_MAX}, | 127 | { "maxval", INT_MAX, BOND_VALFLAG_MAX}, |
| 73 | }; | 128 | }; |
| 74 | 129 | ||
| 75 | static struct bond_opt_value bond_lacp_rate_tbl[] = { | 130 | static const struct bond_opt_value bond_lacp_rate_tbl[] = { |
| 76 | { "slow", AD_LACP_SLOW, 0}, | 131 | { "slow", AD_LACP_SLOW, 0}, |
| 77 | { "fast", AD_LACP_FAST, 0}, | 132 | { "fast", AD_LACP_FAST, 0}, |
| 78 | { NULL, -1, 0}, | 133 | { NULL, -1, 0}, |
| 79 | }; | 134 | }; |
| 80 | 135 | ||
| 81 | static struct bond_opt_value bond_ad_select_tbl[] = { | 136 | static const struct bond_opt_value bond_ad_select_tbl[] = { |
| 82 | { "stable", BOND_AD_STABLE, BOND_VALFLAG_DEFAULT}, | 137 | { "stable", BOND_AD_STABLE, BOND_VALFLAG_DEFAULT}, |
| 83 | { "bandwidth", BOND_AD_BANDWIDTH, 0}, | 138 | { "bandwidth", BOND_AD_BANDWIDTH, 0}, |
| 84 | { "count", BOND_AD_COUNT, 0}, | 139 | { "count", BOND_AD_COUNT, 0}, |
| 85 | { NULL, -1, 0}, | 140 | { NULL, -1, 0}, |
| 86 | }; | 141 | }; |
| 87 | 142 | ||
| 88 | static struct bond_opt_value bond_num_peer_notif_tbl[] = { | 143 | static const struct bond_opt_value bond_num_peer_notif_tbl[] = { |
| 89 | { "off", 0, 0}, | 144 | { "off", 0, 0}, |
| 90 | { "maxval", 255, BOND_VALFLAG_MAX}, | 145 | { "maxval", 255, BOND_VALFLAG_MAX}, |
| 91 | { "default", 1, BOND_VALFLAG_DEFAULT}, | 146 | { "default", 1, BOND_VALFLAG_DEFAULT}, |
| 92 | { NULL, -1, 0} | 147 | { NULL, -1, 0} |
| 93 | }; | 148 | }; |
| 94 | 149 | ||
| 95 | static struct bond_opt_value bond_primary_reselect_tbl[] = { | 150 | static const struct bond_opt_value bond_primary_reselect_tbl[] = { |
| 96 | { "always", BOND_PRI_RESELECT_ALWAYS, BOND_VALFLAG_DEFAULT}, | 151 | { "always", BOND_PRI_RESELECT_ALWAYS, BOND_VALFLAG_DEFAULT}, |
| 97 | { "better", BOND_PRI_RESELECT_BETTER, 0}, | 152 | { "better", BOND_PRI_RESELECT_BETTER, 0}, |
| 98 | { "failure", BOND_PRI_RESELECT_FAILURE, 0}, | 153 | { "failure", BOND_PRI_RESELECT_FAILURE, 0}, |
| 99 | { NULL, -1}, | 154 | { NULL, -1}, |
| 100 | }; | 155 | }; |
| 101 | 156 | ||
| 102 | static struct bond_opt_value bond_use_carrier_tbl[] = { | 157 | static const struct bond_opt_value bond_use_carrier_tbl[] = { |
| 103 | { "off", 0, 0}, | 158 | { "off", 0, 0}, |
| 104 | { "on", 1, BOND_VALFLAG_DEFAULT}, | 159 | { "on", 1, BOND_VALFLAG_DEFAULT}, |
| 105 | { NULL, -1, 0} | 160 | { NULL, -1, 0} |
| 106 | }; | 161 | }; |
| 107 | 162 | ||
| 108 | static struct bond_opt_value bond_all_slaves_active_tbl[] = { | 163 | static const struct bond_opt_value bond_all_slaves_active_tbl[] = { |
| 109 | { "off", 0, BOND_VALFLAG_DEFAULT}, | 164 | { "off", 0, BOND_VALFLAG_DEFAULT}, |
| 110 | { "on", 1, 0}, | 165 | { "on", 1, 0}, |
| 111 | { NULL, -1, 0} | 166 | { NULL, -1, 0} |
| 112 | }; | 167 | }; |
| 113 | 168 | ||
| 114 | static struct bond_opt_value bond_resend_igmp_tbl[] = { | 169 | static const struct bond_opt_value bond_resend_igmp_tbl[] = { |
| 115 | { "off", 0, 0}, | 170 | { "off", 0, 0}, |
| 116 | { "maxval", 255, BOND_VALFLAG_MAX}, | 171 | { "maxval", 255, BOND_VALFLAG_MAX}, |
| 117 | { "default", 1, BOND_VALFLAG_DEFAULT}, | 172 | { "default", 1, BOND_VALFLAG_DEFAULT}, |
| 118 | { NULL, -1, 0} | 173 | { NULL, -1, 0} |
| 119 | }; | 174 | }; |
| 120 | 175 | ||
| 121 | static struct bond_opt_value bond_lp_interval_tbl[] = { | 176 | static const struct bond_opt_value bond_lp_interval_tbl[] = { |
| 122 | { "minval", 1, BOND_VALFLAG_MIN | BOND_VALFLAG_DEFAULT}, | 177 | { "minval", 1, BOND_VALFLAG_MIN | BOND_VALFLAG_DEFAULT}, |
| 123 | { "maxval", INT_MAX, BOND_VALFLAG_MAX}, | 178 | { "maxval", INT_MAX, BOND_VALFLAG_MAX}, |
| 124 | { NULL, -1, 0}, | 179 | { NULL, -1, 0}, |
| 125 | }; | 180 | }; |
| 126 | 181 | ||
| 127 | static struct bond_option bond_opts[] = { | 182 | static const struct bond_option bond_opts[] = { |
| 128 | [BOND_OPT_MODE] = { | 183 | [BOND_OPT_MODE] = { |
| 129 | .id = BOND_OPT_MODE, | 184 | .id = BOND_OPT_MODE, |
| 130 | .name = "mode", | 185 | .name = "mode", |
| @@ -152,7 +207,8 @@ static struct bond_option bond_opts[] = { · 21 unmodified lines | |||
| 152 | .id = BOND_OPT_ARP_VALIDATE, | 207 | .id = BOND_OPT_ARP_VALIDATE, |
| 153 | .name = "arp_validate", | 208 | .name = "arp_validate", |
| 154 | .desc = "validate src/dst of ARP probes", | 209 | .desc = "validate src/dst of ARP probes", |
| 155 | .unsuppmodes = BOND_MODE_ALL_EX(BIT(BOND_MODE_ACTIVEBACKUP)), | 210 | .unsuppmodes = BIT(BOND_MODE_8023AD) | BIT(BOND_MODE_TLB) | |
| 211 | BIT(BOND_MODE_ALB), | ||
| 156 | .values = bond_arp_validate_tbl, | 212 | .values = bond_arp_validate_tbl, |
| 157 | .set = bond_option_arp_validate_set | 213 | .set = bond_option_arp_validate_set |
| 158 | }, | 214 | }, |
| @@ -312,9 +368,9 @@ static struct bond_option bond_opts[] = { · 153 unmodified lines | |||
| 312 | }; | 368 | }; |
| 313 | 369 | ||
| 314 | /* Searches for a value in opt's values[] table */ | 370 | /* Searches for a value in opt's values[] table */ |
| 315 | struct bond_opt_value *bond_opt_get_val(unsigned int option, u64 val) | 371 | const struct bond_opt_value *bond_opt_get_val(unsigned int option, u64 val) |
| 316 | { | 372 | { |
| 317 | struct bond_option *opt; | 373 | const struct bond_option *opt; |
| 318 | int i; | 374 | int i; |
| 319 | 375 | ||
| 320 | opt = bond_opt_get(option); | 376 | opt = bond_opt_get(option); |
| @@ -328,7 +384,7 @@ struct bond_opt_value *bond_opt_get_val(unsigned int option, u64 val) · 7 unmodified lines | |||
| 328 | } | 384 | } |
| 329 | 385 | ||
| 330 | /* Searches for a value in opt's values[] table which matches the flagmask */ | 386 | /* Searches for a value in opt's values[] table which matches the flagmask */ |
| 331 | static struct bond_opt_value *bond_opt_get_flags(const struct bond_option *opt, | 387 | static const struct bond_opt_value *bond_opt_get_flags(const struct bond_option *opt, |
| 332 | u32 flagmask) | 388 | u32 flagmask) |
| 333 | { | 389 | { |
| 334 | int i; | 390 | int i; |
| @@ -345,7 +401,7 @@ static struct bond_opt_value *bond_opt_get_flags(const struct bond_option *opt, · 10 unmodified lines | |||
| 345 | */ | 401 | */ |
| 346 | static bool bond_opt_check_range(const struct bond_option *opt, u64 val) | 402 | static bool bond_opt_check_range(const struct bond_option *opt, u64 val) |
| 347 | { | 403 | { |
| 348 | struct bond_opt_value *minval, *maxval; | 404 | const struct bond_opt_value *minval, *maxval; |
| 349 | 405 | ||
| 350 | minval = bond_opt_get_flags(opt, BOND_VALFLAG_MIN); | 406 | minval = bond_opt_get_flags(opt, BOND_VALFLAG_MIN); |
| 351 | maxval = bond_opt_get_flags(opt, BOND_VALFLAG_MAX); | 407 | maxval = bond_opt_get_flags(opt, BOND_VALFLAG_MAX); |
| @@ -365,11 +421,12 @@ static bool bond_opt_check_range(const struct bond_option *opt, u64 val) · 13 unmodified lines | |||
| 365 | * or the struct_opt_value that matched. It also strips the new line from | 421 | * or the struct_opt_value that matched. It also strips the new line from |
| 366 | * @val->string if it's present. | 422 | * @val->string if it's present. |
| 367 | */ | 423 | */ |
| 368 | struct bond_opt_value *bond_opt_parse(const struct bond_option *opt, | 424 | const struct bond_opt_value *bond_opt_parse(const struct bond_option *opt, |
| 369 | struct bond_opt_value *val) | 425 | struct bond_opt_value *val) |
| 370 | { | 426 | { |
| 371 | char *p, valstr[BOND_OPT_MAX_NAMELEN + 1] = { 0, }; | 427 | char *p, valstr[BOND_OPT_MAX_NAMELEN + 1] = { 0, }; |
| 372 | struct bond_opt_value *tbl, *ret = NULL; | 428 | const struct bond_opt_value *tbl; |
| 429 | const struct bond_opt_value *ret = NULL; | ||
| 373 | bool checkval; | 430 | bool checkval; |
| 374 | int i, rv; | 431 | int i, rv; |
| 375 | 432 | ||
| @@ -448,7 +505,7 @@ static int bond_opt_check_deps(struct bonding *bond, · 72 unmodified lines | |||
| 448 | static void bond_opt_dep_print(struct bonding *bond, | 505 | static void bond_opt_dep_print(struct bonding *bond, |
| 449 | const struct bond_option *opt) | 506 | const struct bond_option *opt) |
| 450 | { | 507 | { |
| 451 | struct bond_opt_value *modeval; | 508 | const struct bond_opt_value *modeval; |
| 452 | struct bond_params *params; | 509 | struct bond_params *params; |
| 453 | 510 | ||
| 454 | params = &bond->params; | 511 | params = &bond->params; |
| @@ -461,9 +518,9 @@ static void bond_opt_dep_print(struct bonding *bond, · 6 unmodified lines | |||
| 461 | 518 | ||
| 462 | static void bond_opt_error_interpret(struct bonding *bond, | 519 | static void bond_opt_error_interpret(struct bonding *bond, |
| 463 | const struct bond_option *opt, | 520 | const struct bond_option *opt, |
| 464 | int error, struct bond_opt_value *val) | 521 | int error, const struct bond_opt_value *val) |
| 465 | { | 522 | { |
| 466 | struct bond_opt_value *minval, *maxval; | 523 | const struct bond_opt_value *minval, *maxval; |
| 467 | char *p; | 524 | char *p; |
| 468 | 525 | ||
| 469 | switch (error) { | 526 | switch (error) { |
| @@ -474,10 +531,10 @@ static void bond_opt_error_interpret(struct bonding *bond, · 4 unmodified lines | |||
| 474 | p = strchr(val->string, '\n'); | 531 | p = strchr(val->string, '\n'); |
| 475 | if (p) | 532 | if (p) |
| 476 | *p = '\0'; | 533 | *p = '\0'; |
| 477 | pr_err("%s: option %s: invalid value (%s).\n", | 534 | pr_err("%s: option %s: invalid value (%s)\n", |
| 478 | bond->dev->name, opt->name, val->string); | 535 | bond->dev->name, opt->name, val->string); |
| 479 | } else { | 536 | } else { |
| 480 | pr_err("%s: option %s: invalid value (%llu).\n", | 537 | pr_err("%s: option %s: invalid value (%llu)\n", |
| 481 | bond->dev->name, opt->name, val->value); | 538 | bond->dev->name, opt->name, val->value); |
| 482 | } | 539 | } |
| 483 | } | 540 | } |
| @@ -485,7 +542,7 @@ static void bond_opt_error_interpret(struct bonding *bond, · 1 unmodified line | |||
| 485 | maxval = bond_opt_get_flags(opt, BOND_VALFLAG_MAX); | 542 | maxval = bond_opt_get_flags(opt, BOND_VALFLAG_MAX); |
| 486 | if (!maxval) | 543 | if (!maxval) |
| 487 | break; | 544 | break; |
| 488 | pr_err("%s: option %s: allowed values %llu - %llu.\n", | 545 | pr_err("%s: option %s: allowed values %llu - %llu\n", |
| 489 | bond->dev->name, opt->name, minval ? minval->value : 0, | 546 | bond->dev->name, opt->name, minval ? minval->value : 0, |
| 490 | maxval->value); | 547 | maxval->value); |
| 491 | break; | 548 | break; |
| @@ -493,11 +550,11 @@ static void bond_opt_error_interpret(struct bonding *bond, · 1 unmodified line | |||
| 493 | bond_opt_dep_print(bond, opt); | 550 | bond_opt_dep_print(bond, opt); |
| 494 | break; | 551 | break; |
| 495 | case -ENOTEMPTY: | 552 | case -ENOTEMPTY: |
| 496 | pr_err("%s: option %s: unable to set because the bond device has slaves.\n", | 553 | pr_err("%s: option %s: unable to set because the bond device has slaves\n", |
| 497 | bond->dev->name, opt->name); | 554 | bond->dev->name, opt->name); |
| 498 | break; | 555 | break; |
| 499 | case -EBUSY: | 556 | case -EBUSY: |
| 500 | pr_err("%s: option %s: unable to set because the bond device is up.\n", | 557 | pr_err("%s: option %s: unable to set because the bond device is up\n", |
| 501 | bond->dev->name, opt->name); | 558 | bond->dev->name, opt->name); |
| 502 | break; | 559 | break; |
| 503 | default: | 560 | default: |
| @@ -518,7 +575,7 @@ static void bond_opt_error_interpret(struct bonding *bond, · 14 unmodified lines | |||
| 518 | int __bond_opt_set(struct bonding *bond, | 575 | int __bond_opt_set(struct bonding *bond, |
| 519 | unsigned int option, struct bond_opt_value *val) | 576 | unsigned int option, struct bond_opt_value *val) |
| 520 | { | 577 | { |
| 521 | struct bond_opt_value *retval = NULL; | 578 | const struct bond_opt_value *retval = NULL; |
| 522 | const struct bond_option *opt; | 579 | const struct bond_option *opt; |
| 523 | int ret = -ENOENT; | 580 | int ret = -ENOENT; |
| 524 | 581 | ||
| @@ -573,7 +630,7 @@ int bond_opt_tryset_rtnl(struct bonding *bond, unsigned int option, char *buf) · 48 unmodified lines | |||
| 573 | * This function checks if option is valid and if so returns a pointer | 630 | * This function checks if option is valid and if so returns a pointer |
| 574 | * to its entry in the bond_opts[] option array. | 631 | * to its entry in the bond_opts[] option array. |
| 575 | */ | 632 | */ |
| 576 | struct bond_option *bond_opt_get(unsigned int option) | 633 | const struct bond_option *bond_opt_get(unsigned int option) |
| 577 | { | 634 | { |
| 578 | if (!BOND_OPT_VALID(option)) | 635 | if (!BOND_OPT_VALID(option)) |
| 579 | return NULL; | 636 | return NULL; |
| @@ -581,7 +638,7 @@ struct bond_option *bond_opt_get(unsigned int option) · 1 unmodified line | |||
| 581 | return &bond_opts[option]; | 638 | return &bond_opts[option]; |
| 582 | } | 639 | } |
| 583 | 640 | ||
| 584 | int bond_option_mode_set(struct bonding *bond, struct bond_opt_value *newval) | 641 | int bond_option_mode_set(struct bonding *bond, const struct bond_opt_value *newval) |
| 585 | { | 642 | { |
| 586 | if (BOND_NO_USES_ARP(newval->value) && bond->params.arp_interval) { | 643 | if (BOND_NO_USES_ARP(newval->value) && bond->params.arp_interval) { |
| 587 | pr_info("%s: %s mode is incompatible with arp monitoring, start mii monitoring\n", | 644 | pr_info("%s: %s mode is incompatible with arp monitoring, start mii monitoring\n", |
| @@ -590,7 +647,7 @@ int bond_option_mode_set(struct bonding *bond, struct bond_opt_value *newval) · 2 unmodified lines | |||
| 590 | bond->params.arp_interval = 0; | 647 | bond->params.arp_interval = 0; |
| 591 | /* set miimon to default value */ | 648 | /* set miimon to default value */ |
| 592 | bond->params.miimon = BOND_DEFAULT_MIIMON; | 649 | bond->params.miimon = BOND_DEFAULT_MIIMON; |
| 593 | pr_info("%s: Setting MII monitoring interval to %d.\n", | 650 | pr_info("%s: Setting MII monitoring interval to %d\n", |
| 594 | bond->dev->name, bond->params.miimon); | 651 | bond->dev->name, bond->params.miimon); |
| 595 | } | 652 | } |
| 596 | 653 | ||
| @@ -619,8 +676,8 @@ struct net_device *bond_option_active_slave_get(struct bonding *bond) · 22 unmodified lines | |||
| 619 | return __bond_option_active_slave_get(bond, bond->curr_active_slave); | 676 | return __bond_option_active_slave_get(bond, bond->curr_active_slave); |
| 620 | } | 677 | } |
| 621 | 678 | ||
| 622 | int bond_option_active_slave_set(struct bonding *bond, | 679 | static int bond_option_active_slave_set(struct bonding *bond, |
| 623 | struct bond_opt_value *newval) | 680 | const struct bond_opt_value *newval) |
| 624 | { | 681 | { |
| 625 | char ifname[IFNAMSIZ] = { 0, }; | 682 | char ifname[IFNAMSIZ] = { 0, }; |
| 626 | struct net_device *slave_dev; | 683 | struct net_device *slave_dev; |
| @@ -637,13 +694,13 @@ int bond_option_active_slave_set(struct bonding *bond, · 10 unmodified lines | |||
| 637 | 694 | ||
| 638 | if (slave_dev) { | 695 | if (slave_dev) { |
| 639 | if (!netif_is_bond_slave(slave_dev)) { | 696 | if (!netif_is_bond_slave(slave_dev)) { |
| 640 | pr_err("Device %s is not bonding slave.\n", | 697 | pr_err("Device %s is not bonding slave\n", |
| 641 | slave_dev->name); | 698 | slave_dev->name); |
| 642 | return -EINVAL; | 699 | return -EINVAL; |
| 643 | } | 700 | } |
| 644 | 701 | ||
| 645 | if (bond->dev != netdev_master_upper_dev_get(slave_dev)) { | 702 | if (bond->dev != netdev_master_upper_dev_get(slave_dev)) { |
| 646 | pr_err("%s: Device %s is not our slave.\n", | 703 | pr_err("%s: Device %s is not our slave\n", |
| 647 | bond->dev->name, slave_dev->name); | 704 | bond->dev->name, slave_dev->name); |
| 648 | return -EINVAL; | 705 | return -EINVAL; |
| 649 | } | 706 | } |
| @@ -654,9 +711,8 @@ int bond_option_active_slave_set(struct bonding *bond, · 4 unmodified lines | |||
| 654 | 711 | ||
| 655 | /* check to see if we are clearing active */ | 712 | /* check to see if we are clearing active */ |
| 656 | if (!slave_dev) { | 713 | if (!slave_dev) { |
| 657 | pr_info("%s: Clearing current active slave.\n", | 714 | pr_info("%s: Clearing current active slave\n", bond->dev->name); |
| 658 | bond->dev->name); | 715 | RCU_INIT_POINTER(bond->curr_active_slave, NULL); |
| 659 | rcu_assign_pointer(bond->curr_active_slave, NULL); | ||
| 660 | bond_select_active_slave(bond); | 716 | bond_select_active_slave(bond); |
| 661 | } else { | 717 | } else { |
| 662 | struct slave *old_active = bond->curr_active_slave; | 718 | struct slave *old_active = bond->curr_active_slave; |
| @@ -666,16 +722,16 @@ int bond_option_active_slave_set(struct bonding *bond, · 3 unmodified lines | |||
| 666 | 722 | ||
| 667 | if (new_active == old_active) { | 723 | if (new_active == old_active) { |
| 668 | /* do nothing */ | 724 | /* do nothing */ |
| 669 | pr_info("%s: %s is already the current active slave.\n", | 725 | pr_info("%s: %s is already the current active slave\n", |
| 670 | bond->dev->name, new_active->dev->name); | 726 | bond->dev->name, new_active->dev->name); |
| 671 | } else { | 727 | } else { |
| 672 | if (old_active && (new_active->link == BOND_LINK_UP) && | 728 | if (old_active && (new_active->link == BOND_LINK_UP) && |
| 673 | IS_UP(new_active->dev)) { | 729 | IS_UP(new_active->dev)) { |
| 674 | pr_info("%s: Setting %s as active slave.\n", | 730 | pr_info("%s: Setting %s as active slave\n", |
| 675 | bond->dev->name, new_active->dev->name); | 731 | bond->dev->name, new_active->dev->name); |
| 676 | bond_change_active_slave(bond, new_active); | 732 | bond_change_active_slave(bond, new_active); |
| 677 | } else { | 733 | } else { |
| 678 | pr_err("%s: Could not set %s as active slave; either %s is down or the link is down.\n", | 734 | pr_err("%s: Could not set %s as active slave; either %s is down or the link is down\n", |
| 679 | bond->dev->name, new_active->dev->name, | 735 | bond->dev->name, new_active->dev->name, |
| 680 | new_active->dev->name); | 736 | new_active->dev->name); |
| 681 | ret = -EINVAL; | 737 | ret = -EINVAL; |
| @@ -689,21 +745,22 @@ int bond_option_active_slave_set(struct bonding *bond, · 7 unmodified lines | |||
| 689 | return ret; | 745 | return ret; |
| 690 | } | 746 | } |
| 691 | 747 | ||
| 692 | int bond_option_miimon_set(struct bonding *bond, struct bond_opt_value *newval) | 748 | static int bond_option_miimon_set(struct bonding *bond, |
| 749 | const struct bond_opt_value *newval) | ||
| 693 | { | 750 | { |
| 694 | pr_info("%s: Setting MII monitoring interval to %llu.\n", | 751 | pr_info("%s: Setting MII monitoring interval to %llu\n", |
| 695 | bond->dev->name, newval->value); | 752 | bond->dev->name, newval->value); |
| 696 | bond->params.miimon = newval->value; | 753 | bond->params.miimon = newval->value; |
| 697 | if (bond->params.updelay) | 754 | if (bond->params.updelay) |
| 698 | pr_info("%s: Note: Updating updelay (to %d) since it is a multiple of the miimon value.\n", | 755 | pr_info("%s: Note: Updating updelay (to %d) since it is a multiple of the miimon value\n", |
| 699 | bond->dev->name, | 756 | bond->dev->name, |
| 700 | bond->params.updelay * bond->params.miimon); | 757 | bond->params.updelay * bond->params.miimon); |
| 701 | if (bond->params.downdelay) | 758 | if (bond->params.downdelay) |
| 702 | pr_info("%s: Note: Updating downdelay (to %d) since it is a multiple of the miimon value.\n", | 759 | pr_info("%s: Note: Updating downdelay (to %d) since it is a multiple of the miimon value\n", |
| 703 | bond->dev->name, | 760 | bond->dev->name, |
| 704 | bond->params.downdelay * bond->params.miimon); | 761 | bond->params.downdelay * bond->params.miimon); |
| 705 | if (newval->value && bond->params.arp_interval) { | 762 | if (newval->value && bond->params.arp_interval) { |
| 706 | pr_info("%s: MII monitoring cannot be used with ARP monitoring. Disabling ARP monitoring...\n", | 763 | pr_info("%s: MII monitoring cannot be used with ARP monitoring - disabling ARP monitoring...\n", |
| 707 | bond->dev->name); | 764 | bond->dev->name); |
| 708 | bond->params.arp_interval = 0; | 765 | bond->params.arp_interval = 0; |
| 709 | if (bond->params.arp_validate) | 766 | if (bond->params.arp_validate) |
| @@ -726,7 +783,8 @@ int bond_option_miimon_set(struct bonding *bond, struct bond_opt_value *newval) · 16 unmodified lines | |||
| 726 | return 0; | 783 | return 0; |
| 727 | } | 784 | } |
| 728 | 785 | ||
| 729 | int bond_option_updelay_set(struct bonding *bond, struct bond_opt_value *newval) | 786 | static int bond_option_updelay_set(struct bonding *bond, |
| 787 | const struct bond_opt_value *newval) | ||
| 730 | { | 788 | { |
| 731 | int value = newval->value; | 789 | int value = newval->value; |
| 732 | 790 | ||
| @@ -743,15 +801,14 @@ int bond_option_updelay_set(struct bonding *bond, struct bond_opt_value *newval) · 10 unmodified lines | |||
| 743 | bond->params.miimon); | 801 | bond->params.miimon); |
| 744 | } | 802 | } |
| 745 | bond->params.updelay = value / bond->params.miimon; | 803 | bond->params.updelay = value / bond->params.miimon; |
| 746 | pr_info("%s: Setting up delay to %d.\n", | 804 | pr_info("%s: Setting up delay to %d\n", |
| 747 | bond->dev->name, | 805 | bond->dev->name, bond->params.updelay * bond->params.miimon); |
| 748 | bond->params.updelay * bond->params.miimon); | ||
| 749 | 806 | ||
| 750 | return 0; | 807 | return 0; |
| 751 | } | 808 | } |
| 752 | 809 | ||
| 753 | int bond_option_downdelay_set(struct bonding *bond, | 810 | static int bond_option_downdelay_set(struct bonding *bond, |
| 754 | struct bond_opt_value *newval) | 811 | const struct bond_opt_value *newval) |
| 755 | { | 812 | { |
| 756 | int value = newval->value; | 813 | int value = newval->value; |
| 757 | 814 | ||
| @@ -768,37 +825,36 @@ int bond_option_downdelay_set(struct bonding *bond, · 10 unmodified lines | |||
| 768 | bond->params.miimon); | 825 | bond->params.miimon); |
| 769 | } | 826 | } |
| 770 | bond->params.downdelay = value / bond->params.miimon; | 827 | bond->params.downdelay = value / bond->params.miimon; |
| 771 | pr_info("%s: Setting down delay to %d.\n", | 828 | pr_info("%s: Setting down delay to %d\n", |
| 772 | bond->dev->name, | 829 | bond->dev->name, bond->params.downdelay * bond->params.miimon); |
| 773 | bond->params.downdelay * bond->params.miimon); | ||
| 774 | 830 | ||
| 775 | return 0; | 831 | return 0; |
| 776 | } | 832 | } |
| 777 | 833 | ||
| 778 | int bond_option_use_carrier_set(struct bonding *bond, | 834 | static int bond_option_use_carrier_set(struct bonding *bond, |
| 779 | struct bond_opt_value *newval) | 835 | const struct bond_opt_value *newval) |
| 780 | { | 836 | { |
| 781 | pr_info("%s: Setting use_carrier to %llu.\n", | 837 | pr_info("%s: Setting use_carrier to %llu\n", |
| 782 | bond->dev->name, newval->value); | 838 | bond->dev->name, newval->value); |
| 783 | bond->params.use_carrier = newval->value; | 839 | bond->params.use_carrier = newval->value; |
| 784 | 840 | ||
| 785 | return 0; | 841 | return 0; |
| 786 | } | 842 | } |
| 787 | 843 | ||
| 788 | int bond_option_arp_interval_set(struct bonding *bond, | 844 | static int bond_option_arp_interval_set(struct bonding *bond, |
| 789 | struct bond_opt_value *newval) | 845 | const struct bond_opt_value *newval) |
| 790 | { | 846 | { |
| 791 | pr_info("%s: Setting ARP monitoring interval to %llu.\n", | 847 | pr_info("%s: Setting ARP monitoring interval to %llu\n", |
| 792 | bond->dev->name, newval->value); | 848 | bond->dev->name, newval->value); |
| 793 | bond->params.arp_interval = newval->value; | 849 | bond->params.arp_interval = newval->value; |
| 794 | if (newval->value) { | 850 | if (newval->value) { |
| 795 | if (bond->params.miimon) { | 851 | if (bond->params.miimon) { |
| 796 | pr_info("%s: ARP monitoring cannot be used with MII monitoring. %s Disabling MII monitoring.\n", | 852 | pr_info("%s: ARP monitoring cannot be used with MII monitoring. %s Disabling MII monitoring\n", |
| 797 | bond->dev->name, bond->dev->name); | 853 | bond->dev->name, bond->dev->name); |
| 798 | bond->params.miimon = 0; | 854 | bond->params.miimon = 0; |
| 799 | } | 855 | } |
| 800 | if (!bond->params.arp_targets[0]) | 856 | if (!bond->params.arp_targets[0]) |
| 801 | pr_info("%s: ARP monitoring has been set up, but no ARP targets have been specified.\n", | 857 | pr_info("%s: ARP monitoring has been set up, but no ARP targets have been specified\n", |
| 802 | bond->dev->name); | 858 | bond->dev->name); |
| 803 | } | 859 | } |
| 804 | if (bond->dev->flags & IFF_UP) { | 860 | if (bond->dev->flags & IFF_UP) { |
| @@ -813,8 +869,7 @@ int bond_option_arp_interval_set(struct bonding *bond, · 8 unmodified lines | |||
| 813 | cancel_delayed_work_sync(&bond->arp_work); | 869 | cancel_delayed_work_sync(&bond->arp_work); |
| 814 | } else { | 870 | } else { |
| 815 | /* arp_validate can be set only in active-backup mode */ | 871 | /* arp_validate can be set only in active-backup mode */ |
| 816 | if (bond->params.arp_validate) | 872 | bond->recv_probe = bond_arp_rcv; |
| 817 | bond->recv_probe = bond_arp_rcv; | ||
| 818 | cancel_delayed_work_sync(&bond->mii_work); | 873 | cancel_delayed_work_sync(&bond->mii_work); |
| 819 | queue_delayed_work(bond->wq, &bond->arp_work, 0); | 874 | queue_delayed_work(bond->wq, &bond->arp_work, 0); |
| 820 | } | 875 | } |
| @@ -857,19 +912,18 @@ static int _bond_option_arp_ip_target_add(struct bonding *bond, __be32 target) · 36 unmodified lines | |||
| 857 | 912 | ||
| 858 | ind = bond_get_targets_ip(targets, 0); /* first free slot */ | 913 | ind = bond_get_targets_ip(targets, 0); /* first free slot */ |
| 859 | if (ind == -1) { | 914 | if (ind == -1) { |
| 860 | pr_err("%s: ARP target table is full!\n", | 915 | pr_err("%s: ARP target table is full!\n", bond->dev->name); |
| 861 | bond->dev->name); | ||
| 862 | return -EINVAL; | 916 | return -EINVAL; |
| 863 | } | 917 | } |
| 864 | 918 | ||
| 865 | pr_info("%s: adding ARP target %pI4.\n", bond->dev->name, &target); | 919 | pr_info("%s: Adding ARP target %pI4\n", bond->dev->name, &target); |
| 866 | 920 | ||
| 867 | _bond_options_arp_ip_target_set(bond, ind, target, jiffies); | 921 | _bond_options_arp_ip_target_set(bond, ind, target, jiffies); |
| 868 | 922 | ||
| 869 | return 0; | 923 | return 0; |
| 870 | } | 924 | } |
| 871 | 925 | ||
| 872 | int bond_option_arp_ip_target_add(struct bonding *bond, __be32 target) | 926 | static int bond_option_arp_ip_target_add(struct bonding *bond, __be32 target) |
| 873 | { | 927 | { |
| 874 | int ret; | 928 | int ret; |
| 875 | 929 | ||
| @@ -881,7 +935,7 @@ int bond_option_arp_ip_target_add(struct bonding *bond, __be32 target) · 5 unmodified lines | |||
| 881 | return ret; | 935 | return ret; |
| 882 | } | 936 | } |
| 883 | 937 | ||
| 884 | int bond_option_arp_ip_target_rem(struct bonding *bond, __be32 target) | 938 | static int bond_option_arp_ip_target_rem(struct bonding *bond, __be32 target) |
| 885 | { | 939 | { |
| 886 | __be32 *targets = bond->params.arp_targets; | 940 | __be32 *targets = bond->params.arp_targets; |
| 887 | struct list_head *iter; | 941 | struct list_head *iter; |
| @@ -897,17 +951,16 @@ int bond_option_arp_ip_target_rem(struct bonding *bond, __be32 target) · 9 unmodified lines | |||
| 897 | 951 | ||
| 898 | ind = bond_get_targets_ip(targets, target); | 952 | ind = bond_get_targets_ip(targets, target); |
| 899 | if (ind == -1) { | 953 | if (ind == -1) { |
| 900 | pr_err("%s: unable to remove nonexistent ARP target %pI4.\n", | 954 | pr_err("%s: unable to remove nonexistent ARP target %pI4\n", |
| 901 | bond->dev->name, &target); | 955 | bond->dev->name, &target); |
| 902 | return -EINVAL; | 956 | return -EINVAL; |
| 903 | } | 957 | } |
| 904 | 958 | ||
| 905 | if (ind == 0 && !targets[1] && bond->params.arp_interval) | 959 | if (ind == 0 && !targets[1] && bond->params.arp_interval) |
| 906 | pr_warn("%s: removing last arp target with arp_interval on\n", | 960 | pr_warn("%s: Removing last arp target with arp_interval on\n", |
| 907 | bond->dev->name); | 961 | bond->dev->name); |
| 908 | 962 | ||
| 909 | pr_info("%s: removing ARP target %pI4.\n", bond->dev->name, | 963 | pr_info("%s: Removing ARP target %pI4\n", bond->dev->name, &target); |
| 910 | &target); | ||
| 911 | 964 | ||
| 912 | /* not to race with bond_arp_rcv */ | 965 | /* not to race with bond_arp_rcv */ |
| 913 | write_lock_bh(&bond->lock); | 966 | write_lock_bh(&bond->lock); |
| @@ -938,8 +991,8 @@ void bond_option_arp_ip_targets_clear(struct bonding *bond) · 24 unmodified lines | |||
| 938 | write_unlock_bh(&bond->lock); | 991 | write_unlock_bh(&bond->lock); |
| 939 | } | 992 | } |
| 940 | 993 | ||
| 941 | int bond_option_arp_ip_targets_set(struct bonding *bond, | 994 | static int bond_option_arp_ip_targets_set(struct bonding *bond, |
| 942 | struct bond_opt_value *newval) | 995 | const struct bond_opt_value *newval) |
| 943 | { | 996 | { |
| 944 | int ret = -EPERM; | 997 | int ret = -EPERM; |
| 945 | __be32 target; | 998 | __be32 target; |
| @@ -955,7 +1008,7 @@ int bond_option_arp_ip_targets_set(struct bonding *bond, · 9 unmodified lines | |||
| 955 | else if (newval->string[0] == '-') | 1008 | else if (newval->string[0] == '-') |
| 956 | ret = bond_option_arp_ip_target_rem(bond, target); | 1009 | ret = bond_option_arp_ip_target_rem(bond, target); |
| 957 | else | 1010 | else |
| 958 | pr_err("no command found in arp_ip_targets file for bond %s. Use +<addr> or -<addr>.\n", | 1011 | pr_err("no command found in arp_ip_targets file for bond %s - use +<addr> or -<addr>\n", |
| 959 | bond->dev->name); | 1012 | bond->dev->name); |
| 960 | } else { | 1013 | } else { |
| 961 | target = newval->value; | 1014 | target = newval->value; |
| @@ -965,10 +1018,10 @@ int bond_option_arp_ip_targets_set(struct bonding *bond, · 3 unmodified lines | |||
| 965 | return ret; | 1018 | return ret; |
| 966 | } | 1019 | } |
| 967 | 1020 | ||
| 968 | int bond_option_arp_validate_set(struct bonding *bond, | 1021 | static int bond_option_arp_validate_set(struct bonding *bond, |
| 969 | struct bond_opt_value *newval) | 1022 | const struct bond_opt_value *newval) |
| 970 | { | 1023 | { |
| 971 | pr_info("%s: setting arp_validate to %s (%llu).\n", | 1024 | pr_info("%s: Setting arp_validate to %s (%llu)\n", |
| 972 | bond->dev->name, newval->string, newval->value); | 1025 | bond->dev->name, newval->string, newval->value); |
| 973 | 1026 | ||
| 974 | if (bond->dev->flags & IFF_UP) { | 1027 | if (bond->dev->flags & IFF_UP) { |
| @@ -982,17 +1035,18 @@ int bond_option_arp_validate_set(struct bonding *bond, · 7 unmodified lines | |||
| 982 | return 0; | 1035 | return 0; |
| 983 | } | 1036 | } |
| 984 | 1037 | ||
| 985 | int bond_option_arp_all_targets_set(struct bonding *bond, | 1038 | static int bond_option_arp_all_targets_set(struct bonding *bond, |
| 986 | struct bond_opt_value *newval) | 1039 | const struct bond_opt_value *newval) |
| 987 | { | 1040 | { |
| 988 | pr_info("%s: setting arp_all_targets to %s (%llu).\n", | 1041 | pr_info("%s: Setting arp_all_targets to %s (%llu)\n", |
| 989 | bond->dev->name, newval->string, newval->value); | 1042 | bond->dev->name, newval->string, newval->value); |
| 990 | bond->params.arp_all_targets = newval->value; | 1043 | bond->params.arp_all_targets = newval->value; |
| 991 | 1044 | ||
| 992 | return 0; | 1045 | return 0; |
| 993 | } | 1046 | } |
| 994 | 1047 | ||
| 995 | int bond_option_primary_set(struct bonding *bond, struct bond_opt_value *newval) | 1048 | static int bond_option_primary_set(struct bonding *bond, |
| 1049 | const struct bond_opt_value *newval) | ||
| 996 | { | 1050 | { |
| 997 | char *p, *primary = newval->string; | 1051 | char *p, *primary = newval->string; |
| 998 | struct list_head *iter; | 1052 | struct list_head *iter; |
| @@ -1007,8 +1061,7 @@ int bond_option_primary_set(struct bonding *bond, struct bond_opt_value *newval) · 8 unmodified lines | |||
| 1007 | *p = '\0'; | 1061 | *p = '\0'; |
| 1008 | /* check to see if we are clearing primary */ | 1062 | /* check to see if we are clearing primary */ |
| 1009 | if (!strlen(primary)) { | 1063 | if (!strlen(primary)) { |
| 1010 | pr_info("%s: Setting primary slave to None.\n", | 1064 | pr_info("%s: Setting primary slave to None\n", bond->dev->name); |
| 1011 | bond->dev->name); | ||
| 1012 | bond->primary_slave = NULL; | 1065 | bond->primary_slave = NULL; |
| 1013 | memset(bond->params.primary, 0, sizeof(bond->params.primary)); | 1066 | memset(bond->params.primary, 0, sizeof(bond->params.primary)); |
| 1014 | bond_select_active_slave(bond); | 1067 | bond_select_active_slave(bond); |
| @@ -1017,7 +1070,7 @@ int bond_option_primary_set(struct bonding *bond, struct bond_opt_value *newval) · 2 unmodified lines | |||
| 1017 | 1070 | ||
| 1018 | bond_for_each_slave(bond, slave, iter) { | 1071 | bond_for_each_slave(bond, slave, iter) { |
| 1019 | if (strncmp(slave->dev->name, primary, IFNAMSIZ) == 0) { | 1072 | if (strncmp(slave->dev->name, primary, IFNAMSIZ) == 0) { |
| 1020 | pr_info("%s: Setting %s as primary slave.\n", | 1073 | pr_info("%s: Setting %s as primary slave\n", |
| 1021 | bond->dev->name, slave->dev->name); | 1074 | bond->dev->name, slave->dev->name); |
| 1022 | bond->primary_slave = slave; | 1075 | bond->primary_slave = slave; |
| 1023 | strcpy(bond->params.primary, slave->dev->name); | 1076 | strcpy(bond->params.primary, slave->dev->name); |
| @@ -1027,15 +1080,14 @@ int bond_option_primary_set(struct bonding *bond, struct bond_opt_value *newval) · 3 unmodified lines | |||
| 1027 | } | 1080 | } |
| 1028 | 1081 | ||
| 1029 | if (bond->primary_slave) { | 1082 | if (bond->primary_slave) { |
| 1030 | pr_info("%s: Setting primary slave to None.\n", | 1083 | pr_info("%s: Setting primary slave to None\n", bond->dev->name); |
| 1031 | bond->dev->name); | ||
| 1032 | bond->primary_slave = NULL; | 1084 | bond->primary_slave = NULL; |
| 1033 | bond_select_active_slave(bond); | 1085 | bond_select_active_slave(bond); |
| 1034 | } | 1086 | } |
| 1035 | strncpy(bond->params.primary, primary, IFNAMSIZ); | 1087 | strncpy(bond->params.primary, primary, IFNAMSIZ); |
| 1036 | bond->params.primary[IFNAMSIZ - 1] = 0; | 1088 | bond->params.primary[IFNAMSIZ - 1] = 0; |
| 1037 | 1089 | ||
| 1038 | pr_info("%s: Recording %s as primary, but it has not been enslaved to %s yet.\n", | 1090 | pr_info("%s: Recording %s as primary, but it has not been enslaved to %s yet\n", |
| 1039 | bond->dev->name, primary, bond->dev->name); | 1091 | bond->dev->name, primary, bond->dev->name); |
| 1040 | 1092 | ||
| 1041 | out: | 1093 | out: |
| @@ -1046,10 +1098,10 @@ out: · 4 unmodified lines | |||
| 1046 | return 0; | 1098 | return 0; |
| 1047 | } | 1099 | } |
| 1048 | 1100 | ||
| 1049 | int bond_option_primary_reselect_set(struct bonding *bond, | 1101 | static int bond_option_primary_reselect_set(struct bonding *bond, |
| 1050 | struct bond_opt_value *newval) | 1102 | const struct bond_opt_value *newval) |
| 1051 | { | 1103 | { |
| 1052 | pr_info("%s: setting primary_reselect to %s (%llu).\n", | 1104 | pr_info("%s: Setting primary_reselect to %s (%llu)\n", |
| 1053 | bond->dev->name, newval->string, newval->value); | 1105 | bond->dev->name, newval->string, newval->value); |
| 1054 | bond->params.primary_reselect = newval->value; | 1106 | bond->params.primary_reselect = newval->value; |
| 1055 | 1107 | ||
| @@ -1062,46 +1114,46 @@ int bond_option_primary_reselect_set(struct bonding *bond, · 6 unmodified lines | |||
| 1062 | return 0; | 1114 | return 0; |
| 1063 | } | 1115 | } |
| 1064 | 1116 | ||
| 1065 | int bond_option_fail_over_mac_set(struct bonding *bond, | 1117 | static int bond_option_fail_over_mac_set(struct bonding *bond, |
| 1066 | struct bond_opt_value *newval) | 1118 | const struct bond_opt_value *newval) |
| 1067 | { | 1119 | { |
| 1068 | pr_info("%s: Setting fail_over_mac to %s (%llu).\n", | 1120 | pr_info("%s: Setting fail_over_mac to %s (%llu)\n", |
| 1069 | bond->dev->name, newval->string, newval->value); | 1121 | bond->dev->name, newval->string, newval->value); |
| 1070 | bond->params.fail_over_mac = newval->value; | 1122 | bond->params.fail_over_mac = newval->value; |
| 1071 | 1123 | ||
| 1072 | return 0; | 1124 | return 0; |
| 1073 | } | 1125 | } |
| 1074 | 1126 | ||
| 1075 | int bond_option_xmit_hash_policy_set(struct bonding *bond, | 1127 | static int bond_option_xmit_hash_policy_set(struct bonding *bond, |
| 1076 | struct bond_opt_value *newval) | 1128 | const struct bond_opt_value *newval) |
| 1077 | { | 1129 | { |
| 1078 | pr_info("%s: setting xmit hash policy to %s (%llu).\n", | 1130 | pr_info("%s: Setting xmit hash policy to %s (%llu)\n", |
| 1079 | bond->dev->name, newval->string, newval->value); | 1131 | bond->dev->name, newval->string, newval->value); |
| 1080 | bond->params.xmit_policy = newval->value; | 1132 | bond->params.xmit_policy = newval->value; |
| 1081 | 1133 | ||
| 1082 | return 0; | 1134 | return 0; |
| 1083 | } | 1135 | } |
| 1084 | 1136 | ||
| 1085 | int bond_option_resend_igmp_set(struct bonding *bond, | 1137 | static int bond_option_resend_igmp_set(struct bonding *bond, |
| 1086 | struct bond_opt_value *newval) | 1138 | const struct bond_opt_value *newval) |
| 1087 | { | 1139 | { |
| 1088 | pr_info("%s: Setting resend_igmp to %llu.\n", | 1140 | pr_info("%s: Setting resend_igmp to %llu\n", |
| 1089 | bond->dev->name, newval->value); | 1141 | bond->dev->name, newval->value); |
| 1090 | bond->params.resend_igmp = newval->value; | 1142 | bond->params.resend_igmp = newval->value; |
| 1091 | 1143 | ||
| 1092 | return 0; | 1144 | return 0; |
| 1093 | } | 1145 | } |
| 1094 | 1146 | ||
| 1095 | int bond_option_num_peer_notif_set(struct bonding *bond, | 1147 | static int bond_option_num_peer_notif_set(struct bonding *bond, |
| 1096 | struct bond_opt_value *newval) | 1148 | const struct bond_opt_value *newval) |
| 1097 | { | 1149 | { |
| 1098 | bond->params.num_peer_notif = newval->value; | 1150 | bond->params.num_peer_notif = newval->value; |
| 1099 | 1151 | ||
| 1100 | return 0; | 1152 | return 0; |
| 1101 | } | 1153 | } |
| 1102 | 1154 | ||
| 1103 | int bond_option_all_slaves_active_set(struct bonding *bond, | 1155 | static int bond_option_all_slaves_active_set(struct bonding *bond, |
| 1104 | struct bond_opt_value *newval) | 1156 | const struct bond_opt_value *newval) |
| 1105 | { | 1157 | { |
| 1106 | struct list_head *iter; | 1158 | struct list_head *iter; |
| 1107 | struct slave *slave; | 1159 | struct slave *slave; |
| @@ -1121,8 +1173,8 @@ int bond_option_all_slaves_active_set(struct bonding *bond, · 13 unmodified lines | |||
| 1121 | return 0; | 1173 | return 0; |
| 1122 | } | 1174 | } |
| 1123 | 1175 | ||
| 1124 | int bond_option_min_links_set(struct bonding *bond, | 1176 | static int bond_option_min_links_set(struct bonding *bond, |
| 1125 | struct bond_opt_value *newval) | 1177 | const struct bond_opt_value *newval) |
| 1126 | { | 1178 | { |
| 1127 | pr_info("%s: Setting min links value to %llu\n", | 1179 | pr_info("%s: Setting min links value to %llu\n", |
| 1128 | bond->dev->name, newval->value); | 1180 | bond->dev->name, newval->value); |
| @@ -1131,15 +1183,16 @@ int bond_option_min_links_set(struct bonding *bond, · 2 unmodified lines | |||
| 1131 | return 0; | 1183 | return 0; |
| 1132 | } | 1184 | } |
| 1133 | 1185 | ||
| 1134 | int bond_option_lp_interval_set(struct bonding *bond, | 1186 | static int bond_option_lp_interval_set(struct bonding *bond, |
| 1135 | struct bond_opt_value *newval) | 1187 | const struct bond_opt_value *newval) |
| 1136 | { | 1188 | { |
| 1137 | bond->params.lp_interval = newval->value; | 1189 | bond->params.lp_interval = newval->value; |
| 1138 | 1190 | ||
| 1139 | return 0; | 1191 | return 0; |
| 1140 | } | 1192 | } |
| 1141 | 1193 | ||
| 1142 | int bond_option_pps_set(struct bonding *bond, struct bond_opt_value *newval) | 1194 | static int bond_option_pps_set(struct bonding *bond, |
| 1195 | const struct bond_opt_value *newval) | ||
| 1143 | { | 1196 | { |
| 1144 | bond->params.packets_per_slave = newval->value; | 1197 | bond->params.packets_per_slave = newval->value; |
| 1145 | if (newval->value > 0) { | 1198 | if (newval->value > 0) { |
| @@ -1156,10 +1209,10 @@ int bond_option_pps_set(struct bonding *bond, struct bond_opt_value *newval) · 10 unmodified lines | |||
| 1156 | return 0; | 1209 | return 0; |
| 1157 | } | 1210 | } |
| 1158 | 1211 | ||
| 1159 | int bond_option_lacp_rate_set(struct bonding *bond, | 1212 | static int bond_option_lacp_rate_set(struct bonding *bond, |
| 1160 | struct bond_opt_value *newval) | 1213 | const struct bond_opt_value *newval) |
| 1161 | { | 1214 | { |
| 1162 | pr_info("%s: Setting LACP rate to %s (%llu).\n", | 1215 | pr_info("%s: Setting LACP rate to %s (%llu)\n", |
| 1163 | bond->dev->name, newval->string, newval->value); | 1216 | bond->dev->name, newval->string, newval->value); |
| 1164 | bond->params.lacp_fast = newval->value; | 1217 | bond->params.lacp_fast = newval->value; |
| 1165 | bond_3ad_update_lacp_rate(bond); | 1218 | bond_3ad_update_lacp_rate(bond); |
| @@ -1167,18 +1220,18 @@ int bond_option_lacp_rate_set(struct bonding *bond, · 1 unmodified line | |||
| 1167 | return 0; | 1220 | return 0; |
| 1168 | } | 1221 | } |
| 1169 | 1222 | ||
| 1170 | int bond_option_ad_select_set(struct bonding *bond, | 1223 | static int bond_option_ad_select_set(struct bonding *bond, |
| 1171 | struct bond_opt_value *newval) | 1224 | const struct bond_opt_value *newval) |
| 1172 | { | 1225 | { |
| 1173 | pr_info("%s: Setting ad_select to %s (%llu).\n", | 1226 | pr_info("%s: Setting ad_select to %s (%llu)\n", |
| 1174 | bond->dev->name, newval->string, newval->value); | 1227 | bond->dev->name, newval->string, newval->value); |
| 1175 | bond->params.ad_select = newval->value; | 1228 | bond->params.ad_select = newval->value; |
| 1176 | 1229 | ||
| 1177 | return 0; | 1230 | return 0; |
| 1178 | } | 1231 | } |
| 1179 | 1232 | ||
| 1180 | int bond_option_queue_id_set(struct bonding *bond, | 1233 | static int bond_option_queue_id_set(struct bonding *bond, |
| 1181 | struct bond_opt_value *newval) | 1234 | const struct bond_opt_value *newval) |
| 1182 | { | 1235 | { |
| 1183 | struct slave *slave, *update_slave; | 1236 | struct slave *slave, *update_slave; |
| 1184 | struct net_device *sdev; | 1237 | struct net_device *sdev; |
| @@ -1200,8 +1253,7 @@ int bond_option_queue_id_set(struct bonding *bond, · 15 unmodified lines | |||
| 1200 | goto err_no_cmd; | 1253 | goto err_no_cmd; |
| 1201 | 1254 | ||
| 1202 | /* Check buffer length, valid ifname and queue id */ | 1255 | /* Check buffer length, valid ifname and queue id */ |
| 1203 | if (strlen(newval->string) > IFNAMSIZ || | 1256 | if (!dev_valid_name(newval->string) || |
| 1204 | !dev_valid_name(newval->string) || | ||
| 1205 | qid > bond->dev->real_num_tx_queues) | 1257 | qid > bond->dev->real_num_tx_queues) |
| 1206 | goto err_no_cmd; | 1258 | goto err_no_cmd; |
| 1207 | 1259 | ||
| @@ -1233,14 +1285,14 @@ out: · 25 unmodified lines | |||
| 1233 | return ret; | 1285 | return ret; |
| 1234 | 1286 | ||
| 1235 | err_no_cmd: | 1287 | err_no_cmd: |
| 1236 | pr_info("invalid input for queue_id set for %s.\n", | 1288 | pr_info("invalid input for queue_id set for %s\n", bond->dev->name); |
| 1237 | bond->dev->name); | ||
| 1238 | ret = -EPERM; | 1289 | ret = -EPERM; |
| 1239 | goto out; | 1290 | goto out; |
| 1240 | 1291 | ||
| 1241 | } | 1292 | } |
| 1242 | 1293 | ||
| 1243 | int bond_option_slaves_set(struct bonding *bond, struct bond_opt_value *newval) | 1294 | static int bond_option_slaves_set(struct bonding *bond, |
| 1295 | const struct bond_opt_value *newval) | ||
| 1244 | { | 1296 | { |
| 1245 | char command[IFNAMSIZ + 1] = { 0, }; | 1297 | char command[IFNAMSIZ + 1] = { 0, }; |
| 1246 | struct net_device *dev; | 1298 | struct net_device *dev; |
| @@ -1255,7 +1307,7 @@ int bond_option_slaves_set(struct bonding *bond, struct bond_opt_value *newval) · 8 unmodified lines | |||
| 1255 | 1307 | ||
| 1256 | dev = __dev_get_by_name(dev_net(bond->dev), ifname); | 1308 | dev = __dev_get_by_name(dev_net(bond->dev), ifname); |
| 1257 | if (!dev) { | 1309 | if (!dev) { |
| 1258 | pr_info("%s: Interface %s does not exist!\n", | 1310 | pr_info("%s: interface %s does not exist!\n", |
| 1259 | bond->dev->name, ifname); | 1311 | bond->dev->name, ifname); |
| 1260 | ret = -ENODEV; | 1312 | ret = -ENODEV; |
| 1261 | goto out; | 1313 | goto out; |
| @@ -1263,12 +1315,12 @@ int bond_option_slaves_set(struct bonding *bond, struct bond_opt_value *newval) · 1 unmodified line | |||
| 1263 | 1315 | ||
| 1264 | switch (command[0]) { | 1316 | switch (command[0]) { |
| 1265 | case '+': | 1317 | case '+': |
| 1266 | pr_info("%s: Adding slave %s.\n", bond->dev->name, dev->name); | 1318 | pr_info("%s: Adding slave %s\n", bond->dev->name, dev->name); |
| 1267 | ret = bond_enslave(bond->dev, dev); | 1319 | ret = bond_enslave(bond->dev, dev); |
| 1268 | break; | 1320 | break; |
| 1269 | 1321 | ||
| 1270 | case '-': | 1322 | case '-': |
| 1271 | pr_info("%s: Removing slave %s.\n", bond->dev->name, dev->name); | 1323 | pr_info("%s: Removing slave %s\n", bond->dev->name, dev->name); |
| 1272 | ret = bond_release(bond->dev, dev); | 1324 | ret = bond_release(bond->dev, dev); |
| 1273 | break; | 1325 | break; |
| 1274 | 1326 | ||
| @@ -1280,7 +1332,7 @@ out: · 5 unmodified lines | |||
| 1280 | return ret; | 1332 | return ret; |
| 1281 | 1333 | ||
| 1282 | err_no_cmd: | 1334 | err_no_cmd: |
| 1283 | pr_err("no command found in slaves file for bond %s. Use +ifname or -ifname.\n", | 1335 | pr_err("no command found in slaves file for bond %s - use +ifname or -ifname\n", |
| 1284 | bond->dev->name); | 1336 | bond->dev->name); |
| 1285 | ret = -EPERM; | 1337 | ret = -EPERM; |
| 1286 | goto out; | 1338 | goto out; |
| @@ -81,8 +81,8 @@ struct bonding; · 80 unmodified lines | |||
| 81 | 81 | ||
| 82 | struct bond_option { | 82 | struct bond_option { |
| 83 | int id; | 83 | int id; |
| 84 | char *name; | 84 | const char *name; |
| 85 | char *desc; | 85 | const char *desc; |
| 86 | u32 flags; | 86 | u32 flags; |
| 87 | 87 | ||
| 88 | /* unsuppmodes is used to denote modes in which the option isn't | 88 | /* unsuppmodes is used to denote modes in which the option isn't |
| @@ -92,18 +92,19 @@ struct bond_option { · 3 unmodified lines | |||
| 92 | /* supported values which this option can have, can be a subset of | 92 | /* supported values which this option can have, can be a subset of |
| 93 | * BOND_OPTVAL_RANGE's value range | 93 | * BOND_OPTVAL_RANGE's value range |
| 94 | */ | 94 | */ |
| 95 | struct bond_opt_value *values; | 95 | const struct bond_opt_value *values; |
| 96 | 96 | ||
| 97 | int (*set)(struct bonding *bond, struct bond_opt_value *val); | 97 | int (*set)(struct bonding *bond, const struct bond_opt_value *val); |
| 98 | }; | 98 | }; |
| 99 | 99 | ||
| 100 | int __bond_opt_set(struct bonding *bond, unsigned int option, | 100 | int __bond_opt_set(struct bonding *bond, unsigned int option, |
| 101 | struct bond_opt_value *val); | 101 | struct bond_opt_value *val); |
| 102 | int bond_opt_tryset_rtnl(struct bonding *bond, unsigned int option, char *buf); | 102 | int bond_opt_tryset_rtnl(struct bonding *bond, unsigned int option, char *buf); |
| 103 | struct bond_opt_value *bond_opt_parse(const struct bond_option *opt, | 103 | |
| 104 | struct bond_opt_value *val); | 104 | const struct bond_opt_value *bond_opt_parse(const struct bond_option *opt, |
| 105 | struct bond_option *bond_opt_get(unsigned int option); | 105 | struct bond_opt_value *val); |
| 106 | struct bond_opt_value *bond_opt_get_val(unsigned int option, u64 val); | 106 | const struct bond_option *bond_opt_get(unsigned int option); |
| 107 | const struct bond_opt_value *bond_opt_get_val(unsigned int option, u64 val); | ||
| 107 | 108 | ||
| 108 | /* This helper is used to initialize a bond_opt_value structure for parameter | 109 | /* This helper is used to initialize a bond_opt_value structure for parameter |
| 109 | * passing. There should be either a valid string or value, but not both. | 110 | * passing. There should be either a valid string or value, but not both. |
| @@ -122,49 +123,6 @@ static inline void __bond_opt_init(struct bond_opt_value *optval, · 12 unmodified lines | |||
| 122 | #define bond_opt_initval(optval, value) __bond_opt_init(optval, NULL, value) | 123 | #define bond_opt_initval(optval, value) __bond_opt_init(optval, NULL, value) |
| 123 | #define bond_opt_initstr(optval, str) __bond_opt_init(optval, str, ULLONG_MAX) | 124 | #define bond_opt_initstr(optval, str) __bond_opt_init(optval, str, ULLONG_MAX) |
| 124 | 125 | ||
| 125 | int bond_option_mode_set(struct bonding *bond, struct bond_opt_value *newval); | ||
| 126 | int bond_option_pps_set(struct bonding *bond, struct bond_opt_value *newval); | ||
| 127 | int bond_option_xmit_hash_policy_set(struct bonding *bond, | ||
| 128 | struct bond_opt_value *newval); | ||
| 129 | int bond_option_arp_validate_set(struct bonding *bond, | ||
| 130 | struct bond_opt_value *newval); | ||
| 131 | int bond_option_arp_all_targets_set(struct bonding *bond, | ||
| 132 | struct bond_opt_value *newval); | ||
| 133 | int bond_option_fail_over_mac_set(struct bonding *bond, | ||
| 134 | struct bond_opt_value *newval); | ||
| 135 | int bond_option_arp_interval_set(struct bonding *bond, | ||
| 136 | struct bond_opt_value *newval); | ||
| 137 | int bond_option_arp_ip_targets_set(struct bonding *bond, | ||
| 138 | struct bond_opt_value *newval); | ||
| 139 | void bond_option_arp_ip_targets_clear(struct bonding *bond); | 126 | void bond_option_arp_ip_targets_clear(struct bonding *bond); |
| 140 | int bond_option_downdelay_set(struct bonding *bond, | 127 | |
| 141 | struct bond_opt_value *newval); | ||
| 142 | int bond_option_updelay_set(struct bonding *bond, | ||
| 143 | struct bond_opt_value *newval); | ||
| 144 | int bond_option_lacp_rate_set(struct bonding *bond, | ||
| 145 | struct bond_opt_value *newval); | ||
| 146 | int bond_option_min_links_set(struct bonding *bond, | ||
| 147 | struct bond_opt_value *newval); | ||
| 148 | int bond_option_ad_select_set(struct bonding *bond, | ||
| 149 | struct bond_opt_value *newval); | ||
| 150 | int bond_option_num_peer_notif_set(struct bonding *bond, | ||
| 151 | struct bond_opt_value *newval); | ||
| 152 | int bond_option_miimon_set(struct bonding *bond, struct bond_opt_value *newval); | ||
| 153 | int bond_option_primary_set(struct bonding *bond, | ||
| 154 | struct bond_opt_value *newval); | ||
| 155 | int bond_option_primary_reselect_set(struct bonding *bond, | ||
| 156 | struct bond_opt_value *newval); | ||
| 157 | int bond_option_use_carrier_set(struct bonding *bond, | ||
| 158 | struct bond_opt_value *newval); | ||
| 159 | int bond_option_active_slave_set(struct bonding *bond, | ||
| 160 | struct bond_opt_value *newval); | ||
| 161 | int bond_option_queue_id_set(struct bonding *bond, | ||
| 162 | struct bond_opt_value *newval); | ||
| 163 | int bond_option_all_slaves_active_set(struct bonding *bond, | ||
| 164 | struct bond_opt_value *newval); | ||
| 165 | int bond_option_resend_igmp_set(struct bonding *bond, | ||
| 166 | struct bond_opt_value *newval); | ||
| 167 | int bond_option_lp_interval_set(struct bonding *bond, | ||
| 168 | struct bond_opt_value *newval); | ||
| 169 | int bond_option_slaves_set(struct bonding *bond, struct bond_opt_value *newval); | ||
| 170 | #endif /* _BOND_OPTIONS_H */ | 128 | #endif /* _BOND_OPTIONS_H */ |
| @@ -65,13 +65,11 @@ static void bond_info_seq_stop(struct seq_file *seq, void *v) · 64 unmodified lines | |||
| 65 | static void bond_info_show_master(struct seq_file *seq) | 65 | static void bond_info_show_master(struct seq_file *seq) |
| 66 | { | 66 | { |
| 67 | struct bonding *bond = seq->private; | 67 | struct bonding *bond = seq->private; |
| 68 | struct bond_opt_value *optval; | 68 | const struct bond_opt_value *optval; |
| 69 | struct slave *curr; | 69 | struct slave *curr; |
| 70 | int i; | 70 | int i; |
| 71 | 71 | ||
| 72 | read_lock(&bond->curr_slave_lock); | 72 | curr = rcu_dereference(bond->curr_active_slave); |
| 73 | curr = bond->curr_active_slave; | ||
| 74 | read_unlock(&bond->curr_slave_lock); | ||
| 75 | 73 | ||
| 76 | seq_printf(seq, "Bonding Mode: %s", | 74 | seq_printf(seq, "Bonding Mode: %s", |
| 77 | bond_mode_name(bond->params.mode)); | 75 | bond_mode_name(bond->params.mode)); |
| @@ -254,8 +252,8 @@ void bond_create_proc_entry(struct bonding *bond) · 176 unmodified lines | |||
| 254 | S_IRUGO, bn->proc_dir, | 252 | S_IRUGO, bn->proc_dir, |
| 255 | &bond_info_fops, bond); | 253 | &bond_info_fops, bond); |
| 256 | if (bond->proc_entry == NULL) | 254 | if (bond->proc_entry == NULL) |
| 257 | pr_warning("Warning: Cannot create /proc/net/%s/%s\n", | 255 | pr_warn("Warning: Cannot create /proc/net/%s/%s\n", |
| 258 | DRV_NAME, bond_dev->name); | 256 | DRV_NAME, bond_dev->name); |
| 259 | else | 257 | else |
| 260 | memcpy(bond->proc_file_name, bond_dev->name, IFNAMSIZ); | 258 | memcpy(bond->proc_file_name, bond_dev->name, IFNAMSIZ); |
| 261 | } | 259 | } |
| @@ -281,8 +279,8 @@ void __net_init bond_create_proc_dir(struct bond_net *bn) · 19 unmodified lines | |||
| 281 | if (!bn->proc_dir) { | 279 | if (!bn->proc_dir) { |
| 282 | bn->proc_dir = proc_mkdir(DRV_NAME, bn->net->proc_net); | 280 | bn->proc_dir = proc_mkdir(DRV_NAME, bn->net->proc_net); |
| 283 | if (!bn->proc_dir) | 281 | if (!bn->proc_dir) |
| 284 | pr_warning("Warning: cannot create /proc/net/%s\n", | 282 | pr_warn("Warning: Cannot create /proc/net/%s\n", |
| 285 | DRV_NAME); | 283 | DRV_NAME); |
| 286 | } | 284 | } |
| 287 | } | 285 | } |
| 288 | 286 | ||
| @@ -117,9 +117,9 @@ static ssize_t bonding_store_bonds(struct class *cls, · 116 unmodified lines | |||
| 117 | rv = bond_create(bn->net, ifname); | 117 | rv = bond_create(bn->net, ifname); |
| 118 | if (rv) { | 118 | if (rv) { |
| 119 | if (rv == -EEXIST) | 119 | if (rv == -EEXIST) |
| 120 | pr_info("%s already exists.\n", ifname); | 120 | pr_info("%s already exists\n", ifname); |
| 121 | else | 121 | else |
| 122 | pr_info("%s creation failed.\n", ifname); | 122 | pr_info("%s creation failed\n", ifname); |
| 123 | res = rv; | 123 | res = rv; |
| 124 | } | 124 | } |
| 125 | } else if (command[0] == '-') { | 125 | } else if (command[0] == '-') { |
| @@ -144,7 +144,7 @@ static ssize_t bonding_store_bonds(struct class *cls, · 18 unmodified lines | |||
| 144 | return res; | 144 | return res; |
| 145 | 145 | ||
| 146 | err_no_cmd: | 146 | err_no_cmd: |
| 147 | pr_err("no command found in bonding_masters. Use +ifname or -ifname.\n"); | 147 | pr_err("no command found in bonding_masters - use +ifname or -ifname\n"); |
| 148 | return -EPERM; | 148 | return -EPERM; |
| 149 | } | 149 | } |
| 150 | 150 | ||
| @@ -220,7 +220,7 @@ static ssize_t bonding_show_mode(struct device *d, · 69 unmodified lines | |||
| 220 | struct device_attribute *attr, char *buf) | 220 | struct device_attribute *attr, char *buf) |
| 221 | { | 221 | { |
| 222 | struct bonding *bond = to_bond(d); | 222 | struct bonding *bond = to_bond(d); |
| 223 | struct bond_opt_value *val; | 223 | const struct bond_opt_value *val; |
| 224 | 224 | ||
| 225 | val = bond_opt_get_val(BOND_OPT_MODE, bond->params.mode); | 225 | val = bond_opt_get_val(BOND_OPT_MODE, bond->params.mode); |
| 226 | 226 | ||
| @@ -251,7 +251,7 @@ static ssize_t bonding_show_xmit_hash(struct device *d, · 24 unmodified lines | |||
| 251 | char *buf) | 251 | char *buf) |
| 252 | { | 252 | { |
| 253 | struct bonding *bond = to_bond(d); | 253 | struct bonding *bond = to_bond(d); |
| 254 | struct bond_opt_value *val; | 254 | const struct bond_opt_value *val; |
| 255 | 255 | ||
| 256 | val = bond_opt_get_val(BOND_OPT_XMIT_HASH, bond->params.xmit_policy); | 256 | val = bond_opt_get_val(BOND_OPT_XMIT_HASH, bond->params.xmit_policy); |
| 257 | 257 | ||
| @@ -282,7 +282,7 @@ static ssize_t bonding_show_arp_validate(struct device *d, · 24 unmodified lines | |||
| 282 | char *buf) | 282 | char *buf) |
| 283 | { | 283 | { |
| 284 | struct bonding *bond = to_bond(d); | 284 | struct bonding *bond = to_bond(d); |
| 285 | struct bond_opt_value *val; | 285 | const struct bond_opt_value *val; |
| 286 | 286 | ||
| 287 | val = bond_opt_get_val(BOND_OPT_ARP_VALIDATE, | 287 | val = bond_opt_get_val(BOND_OPT_ARP_VALIDATE, |
| 288 | bond->params.arp_validate); | 288 | bond->params.arp_validate); |
| @@ -314,7 +314,7 @@ static ssize_t bonding_show_arp_all_targets(struct device *d, · 25 unmodified lines | |||
| 314 | char *buf) | 314 | char *buf) |
| 315 | { | 315 | { |
| 316 | struct bonding *bond = to_bond(d); | 316 | struct bonding *bond = to_bond(d); |
| 317 | struct bond_opt_value *val; | 317 | const struct bond_opt_value *val; |
| 318 | 318 | ||
| 319 | val = bond_opt_get_val(BOND_OPT_ARP_ALL_TARGETS, | 319 | val = bond_opt_get_val(BOND_OPT_ARP_ALL_TARGETS, |
| 320 | bond->params.arp_all_targets); | 320 | bond->params.arp_all_targets); |
| @@ -348,7 +348,7 @@ static ssize_t bonding_show_fail_over_mac(struct device *d, · 27 unmodified lines | |||
| 348 | char *buf) | 348 | char *buf) |
| 349 | { | 349 | { |
| 350 | struct bonding *bond = to_bond(d); | 350 | struct bonding *bond = to_bond(d); |
| 351 | struct bond_opt_value *val; | 351 | const struct bond_opt_value *val; |
| 352 | 352 | ||
| 353 | val = bond_opt_get_val(BOND_OPT_FAIL_OVER_MAC, | 353 | val = bond_opt_get_val(BOND_OPT_FAIL_OVER_MAC, |
| 354 | bond->params.fail_over_mac); | 354 | bond->params.fail_over_mac); |
| @@ -505,7 +505,7 @@ static ssize_t bonding_show_lacp(struct device *d, · 150 unmodified lines | |||
| 505 | char *buf) | 505 | char *buf) |
| 506 | { | 506 | { |
| 507 | struct bonding *bond = to_bond(d); | 507 | struct bonding *bond = to_bond(d); |
| 508 | struct bond_opt_value *val; | 508 | const struct bond_opt_value *val; |
| 509 | 509 | ||
| 510 | val = bond_opt_get_val(BOND_OPT_LACP_RATE, bond->params.lacp_fast); | 510 | val = bond_opt_get_val(BOND_OPT_LACP_RATE, bond->params.lacp_fast); |
| 511 | 511 | ||
| @@ -558,7 +558,7 @@ static ssize_t bonding_show_ad_select(struct device *d, · 46 unmodified lines | |||
| 558 | char *buf) | 558 | char *buf) |
| 559 | { | 559 | { |
| 560 | struct bonding *bond = to_bond(d); | 560 | struct bonding *bond = to_bond(d); |
| 561 | struct bond_opt_value *val; | 561 | const struct bond_opt_value *val; |
| 562 | 562 | ||
| 563 | val = bond_opt_get_val(BOND_OPT_AD_SELECT, bond->params.ad_select); | 563 | val = bond_opt_get_val(BOND_OPT_AD_SELECT, bond->params.ad_select); |
| 564 | 564 | ||
| @@ -686,7 +686,7 @@ static ssize_t bonding_show_primary_reselect(struct device *d, · 121 unmodified lines | |||
| 686 | char *buf) | 686 | char *buf) |
| 687 | { | 687 | { |
| 688 | struct bonding *bond = to_bond(d); | 688 | struct bonding *bond = to_bond(d); |
| 689 | struct bond_opt_value *val; | 689 | const struct bond_opt_value *val; |
| 690 | 690 | ||
| 691 | val = bond_opt_get_val(BOND_OPT_PRIMARY_RESELECT, | 691 | val = bond_opt_get_val(BOND_OPT_PRIMARY_RESELECT, |
| 692 | bond->params.primary_reselect); | 692 | bond->params.primary_reselect); |
| @@ -1135,7 +1135,7 @@ int bond_create_sysfs(struct bond_net *bn) · 442 unmodified lines | |||
| 1135 | /* Is someone being kinky and naming a device bonding_master? */ | 1135 | /* Is someone being kinky and naming a device bonding_master? */ |
| 1136 | if (__dev_get_by_name(bn->net, | 1136 | if (__dev_get_by_name(bn->net, |
| 1137 | class_attr_bonding_masters.attr.name)) | 1137 | class_attr_bonding_masters.attr.name)) |
| 1138 | pr_err("network device named %s already exists in sysfs", | 1138 | pr_err("network device named %s already exists in sysfs\n", |
| 1139 | class_attr_bonding_masters.attr.name); | 1139 | class_attr_bonding_masters.attr.name); |
| 1140 | ret = 0; | 1140 | ret = 0; |
| 1141 | } | 1141 | } |
| @@ -188,8 +188,9 @@ struct slave { · 187 unmodified lines | |||
| 188 | struct net_device *dev; /* first - useful for panic debug */ | 188 | struct net_device *dev; /* first - useful for panic debug */ |
| 189 | struct bonding *bond; /* our master */ | 189 | struct bonding *bond; /* our master */ |
| 190 | int delay; | 190 | int delay; |
| 191 | unsigned long jiffies; | 191 | /* all three in jiffies */ |
| 192 | unsigned long last_arp_rx; | 192 | unsigned long last_link_up; |
| 193 | unsigned long last_rx; | ||
| 193 | unsigned long target_last_arp_rx[BOND_MAX_ARP_TARGETS]; | 194 | unsigned long target_last_arp_rx[BOND_MAX_ARP_TARGETS]; |
| 194 | s8 link; /* one of BOND_LINK_XXXX */ | 195 | s8 link; /* one of BOND_LINK_XXXX */ |
| 195 | s8 new_link; | 196 | s8 new_link; |
| @@ -265,6 +266,11 @@ struct bonding { · 69 unmodified lines | |||
| 265 | #define bond_slave_get_rtnl(dev) \ | 266 | #define bond_slave_get_rtnl(dev) \ |
| 266 | ((struct slave *) rtnl_dereference(dev->rx_handler_data)) | 267 | ((struct slave *) rtnl_dereference(dev->rx_handler_data)) |
| 267 | 268 | ||
| 269 | struct bond_vlan_tag { | ||
| 270 | __be16 vlan_proto; | ||
| 271 | unsigned short vlan_id; | ||
| 272 | }; | ||
| 273 | |||
| 268 | /** | 274 | /** |
| 269 | * Returns NULL if the net_device does not belong to any of the bond's slaves | 275 | * Returns NULL if the net_device does not belong to any of the bond's slaves |
| 270 | * | 276 | * |
| @@ -292,7 +298,7 @@ static inline void bond_set_active_slave(struct slave *slave) · 21 unmodified lines | |||
| 292 | { | 298 | { |
| 293 | if (slave->backup) { | 299 | if (slave->backup) { |
| 294 | slave->backup = 0; | 300 | slave->backup = 0; |
| 295 | rtmsg_ifinfo(RTM_NEWLINK, slave->dev, 0, GFP_KERNEL); | 301 | rtmsg_ifinfo(RTM_NEWLINK, slave->dev, 0, GFP_ATOMIC); |
| 296 | } | 302 | } |
| 297 | } | 303 | } |
| 298 | 304 | ||
| @@ -300,7 +306,7 @@ static inline void bond_set_backup_slave(struct slave *slave) · 1 unmodified line | |||
| 300 | { | 306 | { |
| 301 | if (!slave->backup) { | 307 | if (!slave->backup) { |
| 302 | slave->backup = 1; | 308 | slave->backup = 1; |
| 303 | rtmsg_ifinfo(RTM_NEWLINK, slave->dev, 0, GFP_KERNEL); | 309 | rtmsg_ifinfo(RTM_NEWLINK, slave->dev, 0, GFP_ATOMIC); |
| 304 | } | 310 | } |
| 305 | } | 311 | } |
| 306 | 312 | ||
| @@ -312,7 +318,7 @@ static inline void bond_set_slave_state(struct slave *slave, · 5 unmodified lines | |||
| 312 | 318 | ||
| 313 | slave->backup = slave_state; | 319 | slave->backup = slave_state; |
| 314 | if (notify) { | 320 | if (notify) { |
| 315 | rtmsg_ifinfo(RTM_NEWLINK, slave->dev, 0, GFP_KERNEL); | 321 | rtmsg_ifinfo(RTM_NEWLINK, slave->dev, 0, GFP_ATOMIC); |
| 316 | slave->should_notify = 0; | 322 | slave->should_notify = 0; |
| 317 | } else { | 323 | } else { |
| 318 | if (slave->should_notify) | 324 | if (slave->should_notify) |
| @@ -342,7 +348,7 @@ static inline void bond_slave_state_notify(struct bonding *bond) · 23 unmodified lines | |||
| 342 | 348 | ||
| 343 | bond_for_each_slave(bond, tmp, iter) { | 349 | bond_for_each_slave(bond, tmp, iter) { |
| 344 | if (tmp->should_notify) { | 350 | if (tmp->should_notify) { |
| 345 | rtmsg_ifinfo(RTM_NEWLINK, tmp->dev, 0, GFP_KERNEL); | 351 | rtmsg_ifinfo(RTM_NEWLINK, tmp->dev, 0, GFP_ATOMIC); |
| 346 | tmp->should_notify = 0; | 352 | tmp->should_notify = 0; |
| 347 | } | 353 | } |
| 348 | } | 354 | } |
| @@ -374,6 +380,11 @@ static inline bool bond_is_active_slave(struct slave *slave) · 25 unmodified lines | |||
| 374 | #define BOND_ARP_VALIDATE_BACKUP (1 << BOND_STATE_BACKUP) | 380 | #define BOND_ARP_VALIDATE_BACKUP (1 << BOND_STATE_BACKUP) |
| 375 | #define BOND_ARP_VALIDATE_ALL (BOND_ARP_VALIDATE_ACTIVE | \ | 381 | #define BOND_ARP_VALIDATE_ALL (BOND_ARP_VALIDATE_ACTIVE | \ |
| 376 | BOND_ARP_VALIDATE_BACKUP) | 382 | BOND_ARP_VALIDATE_BACKUP) |
| 383 | #define BOND_ARP_FILTER (BOND_ARP_VALIDATE_ALL + 1) | ||
| 384 | #define BOND_ARP_FILTER_ACTIVE (BOND_ARP_VALIDATE_ACTIVE | \ | ||
| 385 | BOND_ARP_FILTER) | ||
| 386 | #define BOND_ARP_FILTER_BACKUP (BOND_ARP_VALIDATE_BACKUP | \ | ||
| 387 | BOND_ARP_FILTER) | ||
| 377 | 388 | ||
| 378 | #define BOND_SLAVE_NOTIFY_NOW true | 389 | #define BOND_SLAVE_NOTIFY_NOW true |
| 379 | #define BOND_SLAVE_NOTIFY_LATER false | 390 | #define BOND_SLAVE_NOTIFY_LATER false |
| @@ -384,6 +395,12 @@ static inline int slave_do_arp_validate(struct bonding *bond, · 4 unmodified lines | |||
| 384 | return bond->params.arp_validate & (1 << bond_slave_state(slave)); | 395 | return bond->params.arp_validate & (1 << bond_slave_state(slave)); |
| 385 | } | 396 | } |
| 386 | 397 | ||
| 398 | static inline int slave_do_arp_validate_only(struct bonding *bond, | ||
| 399 | struct slave *slave) | ||
| 400 | { | ||
| 401 | return bond->params.arp_validate & BOND_ARP_FILTER; | ||
| 402 | } | ||
| 403 | |||
| 387 | /* Get the oldest arp which we've received on this slave for bond's | 404 | /* Get the oldest arp which we've received on this slave for bond's |
| 388 | * arp_targets. | 405 | * arp_targets. |
| 389 | */ | 406 | */ |
| @@ -403,14 +420,10 @@ static inline unsigned long slave_oldest_target_arp_rx(struct bonding *bond, · 13 unmodified lines | |||
| 403 | static inline unsigned long slave_last_rx(struct bonding *bond, | 420 | static inline unsigned long slave_last_rx(struct bonding *bond, |
| 404 | struct slave *slave) | 421 | struct slave *slave) |
| 405 | { | 422 | { |
| 406 | if (slave_do_arp_validate(bond, slave)) { | 423 | if (bond->params.arp_all_targets == BOND_ARP_TARGETS_ALL) |
| 407 | if (bond->params.arp_all_targets == BOND_ARP_TARGETS_ALL) | 424 | return slave_oldest_target_arp_rx(bond, slave); |
| 408 | return slave_oldest_target_arp_rx(bond, slave); | ||
| 409 | else | ||
| 410 | return slave->last_arp_rx; | ||
| 411 | } | ||
| 412 | 425 | ||
| 413 | return slave->dev->last_rx; | 426 | return slave->last_rx; |
| 414 | } | 427 | } |
| 415 | 428 | ||
| 416 | #ifdef CONFIG_NET_POLL_CONTROLLER | 429 | #ifdef CONFIG_NET_POLL_CONTROLLER |
| @@ -487,8 +500,6 @@ void bond_sysfs_slave_del(struct slave *slave); · 70 unmodified lines | |||
| 487 | int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev); | 500 | int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev); |
| 488 | int bond_release(struct net_device *bond_dev, struct net_device *slave_dev); | 501 | int bond_release(struct net_device *bond_dev, struct net_device *slave_dev); |
| 489 | int bond_xmit_hash(struct bonding *bond, struct sk_buff *skb, int count); | 502 | int bond_xmit_hash(struct bonding *bond, struct sk_buff *skb, int count); |
| 490 | int bond_parse_parm(const char *mode_arg, const struct bond_parm_tbl *tbl); | ||
| 491 | int bond_parm_tbl_lookup(int mode, const struct bond_parm_tbl *tbl); | ||
| 492 | void bond_select_active_slave(struct bonding *bond); | 503 | void bond_select_active_slave(struct bonding *bond); |
| 493 | void bond_change_active_slave(struct bonding *bond, struct slave *new_active); | 504 | void bond_change_active_slave(struct bonding *bond, struct slave *new_active); |
| 494 | void bond_create_debugfs(void); | 505 | void bond_create_debugfs(void); |
| @@ -501,8 +512,6 @@ void bond_setup(struct net_device *bond_dev); · 6 unmodified lines | |||
| 501 | unsigned int bond_get_num_tx_queues(void); | 512 | unsigned int bond_get_num_tx_queues(void); |
| 502 | int bond_netlink_init(void); | 513 | int bond_netlink_init(void); |
| 503 | void bond_netlink_fini(void); | 514 | void bond_netlink_fini(void); |
| 504 | int bond_option_arp_ip_target_add(struct bonding *bond, __be32 target); | ||
| 505 | int bond_option_arp_ip_target_rem(struct bonding *bond, __be32 target); | ||
| 506 | struct net_device *bond_option_active_slave_get_rcu(struct bonding *bond); | 515 | struct net_device *bond_option_active_slave_get_rcu(struct bonding *bond); |
| 507 | struct net_device *bond_option_active_slave_get(struct bonding *bond); | 516 | struct net_device *bond_option_active_slave_get(struct bonding *bond); |
| 508 | const char *bond_slave_link_status(s8 link); | 517 | const char *bond_slave_link_status(s8 link); |
| @@ -204,7 +204,6 @@ static void ldisc_receive(struct tty_struct *tty, const u8 *data, · 203 unmodified lines | |||
| 204 | 204 | ||
| 205 | skb->protocol = htons(ETH_P_CAIF); | 205 | skb->protocol = htons(ETH_P_CAIF); |
| 206 | skb_reset_mac_header(skb); | 206 | skb_reset_mac_header(skb); |
| 207 | skb->dev = ser->dev; | ||
| 208 | debugfs_rx(ser, data, count); | 207 | debugfs_rx(ser, data, count); |
| 209 | /* Push received packet up the stack. */ | 208 | /* Push received packet up the stack. */ |
| 210 | ret = netif_rx_ni(skb); | 209 | ret = netif_rx_ni(skb); |
| @@ -554,7 +554,6 @@ int cfspi_rxfrm(struct cfspi *cfspi, u8 *buf, size_t len) · 553 unmodified lines | |||
| 554 | 554 | ||
| 555 | skb->protocol = htons(ETH_P_CAIF); | 555 | skb->protocol = htons(ETH_P_CAIF); |
| 556 | skb_reset_mac_header(skb); | 556 | skb_reset_mac_header(skb); |
| 557 | skb->dev = cfspi->ndev; | ||
| 558 | 557 | ||
| 559 | /* | 558 | /* |
| 560 | * Push received packet up the stack. | 559 | * Push received packet up the stack. |
| @@ -420,7 +420,11 @@ static void at91_chip_start(struct net_device *dev) · 419 unmodified lines | |||
| 420 | at91_transceiver_switch(priv, 1); | 420 | at91_transceiver_switch(priv, 1); |
| 421 | 421 | ||
| 422 | /* enable chip */ | 422 | /* enable chip */ |
| 423 | at91_write(priv, AT91_MR, AT91_MR_CANEN); | 423 | if (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY) |
| 424 | reg_mr = AT91_MR_CANEN | AT91_MR_ABM; | ||
| 425 | else | ||
| 426 | reg_mr = AT91_MR_CANEN; | ||
| 427 | at91_write(priv, AT91_MR, reg_mr); | ||
| 424 | 428 | ||
| 425 | priv->can.state = CAN_STATE_ERROR_ACTIVE; | 429 | priv->can.state = CAN_STATE_ERROR_ACTIVE; |
| 426 | 430 | ||
| @@ -1190,6 +1194,7 @@ static const struct net_device_ops at91_netdev_ops = { · 763 unmodified lines | |||
| 1190 | .ndo_open = at91_open, | 1194 | .ndo_open = at91_open, |
| 1191 | .ndo_stop = at91_close, | 1195 | .ndo_stop = at91_close, |
| 1192 | .ndo_start_xmit = at91_start_xmit, | 1196 | .ndo_start_xmit = at91_start_xmit, |
| 1197 | .ndo_change_mtu = can_change_mtu, | ||
| 1193 | }; | 1198 | }; |
| 1194 | 1199 | ||
| 1195 | static ssize_t at91_sysfs_show_mb0_id(struct device *dev, | 1200 | static ssize_t at91_sysfs_show_mb0_id(struct device *dev, |
| @@ -1341,7 +1346,8 @@ static int at91_can_probe(struct platform_device *pdev) · 145 unmodified lines | |||
| 1341 | priv->can.bittiming_const = &at91_bittiming_const; | 1346 | priv->can.bittiming_const = &at91_bittiming_const; |
| 1342 | priv->can.do_set_mode = at91_set_mode; | 1347 | priv->can.do_set_mode = at91_set_mode; |
| 1343 | priv->can.do_get_berr_counter = at91_get_berr_counter; | 1348 | priv->can.do_get_berr_counter = at91_get_berr_counter; |
| 1344 | priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES; | 1349 | priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES | |
| 1350 | CAN_CTRLMODE_LISTENONLY; | ||
| 1345 | priv->dev = dev; | 1351 | priv->dev = dev; |
| 1346 | priv->reg_base = addr; | 1352 | priv->reg_base = addr; |
| 1347 | priv->devtype_data = *devtype_data; | 1353 | priv->devtype_data = *devtype_data; |
| @@ -528,6 +528,7 @@ static const struct net_device_ops bfin_can_netdev_ops = { · 527 unmodified lines | |||
| 528 | .ndo_open = bfin_can_open, | 528 | .ndo_open = bfin_can_open, |
| 529 | .ndo_stop = bfin_can_close, | 529 | .ndo_stop = bfin_can_close, |
| 530 | .ndo_start_xmit = bfin_can_start_xmit, | 530 | .ndo_start_xmit = bfin_can_start_xmit, |
| 531 | .ndo_change_mtu = can_change_mtu, | ||
| 531 | }; | 532 | }; |
| 532 | 533 | ||
| 533 | static int bfin_can_probe(struct platform_device *pdev) | 534 | static int bfin_can_probe(struct platform_device *pdev) |
| @@ -114,6 +114,14 @@ · 113 unmodified lines | |||
| 114 | IF_COMM_CONTROL | IF_COMM_TXRQST | \ | 114 | IF_COMM_CONTROL | IF_COMM_TXRQST | \ |
| 115 | IF_COMM_DATAA | IF_COMM_DATAB) | 115 | IF_COMM_DATAA | IF_COMM_DATAB) |
| 116 | 116 | ||
| 117 | /* For the low buffers we clear the interrupt bit, but keep newdat */ | ||
| 118 | #define IF_COMM_RCV_LOW (IF_COMM_MASK | IF_COMM_ARB | \ | ||
| 119 | IF_COMM_CONTROL | IF_COMM_CLR_INT_PND | \ | ||
| 120 | IF_COMM_DATAA | IF_COMM_DATAB) | ||
| 121 | |||
| 122 | /* For the high buffers we clear the interrupt bit and newdat */ | ||
| 123 | #define IF_COMM_RCV_HIGH (IF_COMM_RCV_LOW | IF_COMM_TXRQST) | ||
| 124 | |||
| 117 | /* IFx arbitration */ | 125 | /* IFx arbitration */ |
| 118 | #define IF_ARB_MSGVAL BIT(15) | 126 | #define IF_ARB_MSGVAL BIT(15) |
| 119 | #define IF_ARB_MSGXTD BIT(14) | 127 | #define IF_ARB_MSGXTD BIT(14) |
| @@ -122,7 +130,6 @@ · 2 unmodified lines | |||
| 122 | /* IFx message control */ | 130 | /* IFx message control */ |
| 123 | #define IF_MCONT_NEWDAT BIT(15) | 131 | #define IF_MCONT_NEWDAT BIT(15) |
| 124 | #define IF_MCONT_MSGLST BIT(14) | 132 | #define IF_MCONT_MSGLST BIT(14) |
| 125 | #define IF_MCONT_CLR_MSGLST (0 << 14) | ||
| 126 | #define IF_MCONT_INTPND BIT(13) | 133 | #define IF_MCONT_INTPND BIT(13) |
| 127 | #define IF_MCONT_UMASK BIT(12) | 134 | #define IF_MCONT_UMASK BIT(12) |
| 128 | #define IF_MCONT_TXIE BIT(11) | 135 | #define IF_MCONT_TXIE BIT(11) |
| @@ -133,31 +140,10 @@ · 4 unmodified lines | |||
| 133 | #define IF_MCONT_DLC_MASK 0xf | 140 | #define IF_MCONT_DLC_MASK 0xf |
| 134 | 141 | ||
| 135 | /* | 142 | /* |
| 136 | * IFx register masks: | 143 | * Use IF1 for RX and IF2 for TX |
| 137 | * allow easy operation on 16-bit registers when the | ||
| 138 | * argument is 32-bit instead | ||
| 139 | */ | 144 | */ |
| 140 | #define IFX_WRITE_LOW_16BIT(x) ((x) & 0xFFFF) | 145 | #define IF_RX 0 |
| 141 | #define IFX_WRITE_HIGH_16BIT(x) (((x) & 0xFFFF0000) >> 16) | 146 | #define IF_TX 1 |
| 142 | |||
| 143 | /* message object split */ | ||
| 144 | #define C_CAN_NO_OF_OBJECTS 32 | ||
| 145 | #define C_CAN_MSG_OBJ_RX_NUM 16 | ||
| 146 | #define C_CAN_MSG_OBJ_TX_NUM 16 | ||
| 147 | |||
| 148 | #define C_CAN_MSG_OBJ_RX_FIRST 1 | ||
| 149 | #define C_CAN_MSG_OBJ_RX_LAST (C_CAN_MSG_OBJ_RX_FIRST + \ | ||
| 150 | C_CAN_MSG_OBJ_RX_NUM - 1) | ||
| 151 | |||
| 152 | #define C_CAN_MSG_OBJ_TX_FIRST (C_CAN_MSG_OBJ_RX_LAST + 1) | ||
| 153 | #define C_CAN_MSG_OBJ_TX_LAST (C_CAN_MSG_OBJ_TX_FIRST + \ | ||
| 154 | C_CAN_MSG_OBJ_TX_NUM - 1) | ||
| 155 | |||
| 156 | #define C_CAN_MSG_OBJ_RX_SPLIT 9 | ||
| 157 | #define C_CAN_MSG_RX_LOW_LAST (C_CAN_MSG_OBJ_RX_SPLIT - 1) | ||
| 158 | |||
| 159 | #define C_CAN_NEXT_MSG_OBJ_MASK (C_CAN_MSG_OBJ_TX_NUM - 1) | ||
| 160 | #define RECEIVE_OBJECT_BITS 0x0000ffff | ||
| 161 | 147 | ||
| 162 | /* status interrupt */ | 148 | /* status interrupt */ |
| 163 | #define STATUS_INTERRUPT 0x8000 | 149 | #define STATUS_INTERRUPT 0x8000 |
| @@ -246,10 +232,9 @@ static inline int get_tx_next_msg_obj(const struct c_can_priv *priv) · 82 unmodified lines | |||
| 246 | C_CAN_MSG_OBJ_TX_FIRST; | 232 | C_CAN_MSG_OBJ_TX_FIRST; |
| 247 | } | 233 | } |
| 248 | 234 | ||
| 249 | static inline int get_tx_echo_msg_obj(const struct c_can_priv *priv) | 235 | static inline int get_tx_echo_msg_obj(int txecho) |
| 250 | { | 236 | { |
| 251 | return (priv->tx_echo & C_CAN_NEXT_MSG_OBJ_MASK) + | 237 | return (txecho & C_CAN_NEXT_MSG_OBJ_MASK) + C_CAN_MSG_OBJ_TX_FIRST; |
| 252 | C_CAN_MSG_OBJ_TX_FIRST; | ||
| 253 | } | 238 | } |
| 254 | 239 | ||
| 255 | static u32 c_can_read_reg32(struct c_can_priv *priv, enum reg index) | 240 | static u32 c_can_read_reg32(struct c_can_priv *priv, enum reg index) |
| @@ -366,18 +351,6 @@ static void c_can_write_msg_object(struct net_device *dev, · 110 unmodified lines | |||
| 366 | c_can_object_put(dev, iface, objno, IF_COMM_ALL); | 351 | c_can_object_put(dev, iface, objno, IF_COMM_ALL); |
| 367 | } | 352 | } |
| 368 | 353 | ||
| 369 | static inline void c_can_mark_rx_msg_obj(struct net_device *dev, | ||
| 370 | int iface, int ctrl_mask, | ||
| 371 | int obj) | ||
| 372 | { | ||
| 373 | struct c_can_priv *priv = netdev_priv(dev); | ||
| 374 | |||
| 375 | priv->write_reg(priv, C_CAN_IFACE(MSGCTRL_REG, iface), | ||
| 376 | ctrl_mask & ~(IF_MCONT_MSGLST | IF_MCONT_INTPND)); | ||
| 377 | c_can_object_put(dev, iface, obj, IF_COMM_CONTROL); | ||
| 378 | |||
| 379 | } | ||
| 380 | |||
| 381 | static inline void c_can_activate_all_lower_rx_msg_obj(struct net_device *dev, | 354 | static inline void c_can_activate_all_lower_rx_msg_obj(struct net_device *dev, |
| 382 | int iface, | 355 | int iface, |
| 383 | int ctrl_mask) | 356 | int ctrl_mask) |
| @@ -387,45 +360,27 @@ static inline void c_can_activate_all_lower_rx_msg_obj(struct net_device *dev, · 3 unmodified lines | |||
| 387 | 360 | ||
| 388 | for (i = C_CAN_MSG_OBJ_RX_FIRST; i <= C_CAN_MSG_RX_LOW_LAST; i++) { | 361 | for (i = C_CAN_MSG_OBJ_RX_FIRST; i <= C_CAN_MSG_RX_LOW_LAST; i++) { |
| 389 | priv->write_reg(priv, C_CAN_IFACE(MSGCTRL_REG, iface), | 362 | priv->write_reg(priv, C_CAN_IFACE(MSGCTRL_REG, iface), |
| 390 | ctrl_mask & ~(IF_MCONT_MSGLST | | 363 | ctrl_mask & ~IF_MCONT_NEWDAT); |
| 391 | IF_MCONT_INTPND | IF_MCONT_NEWDAT)); | ||
| 392 | c_can_object_put(dev, iface, i, IF_COMM_CONTROL); | 364 | c_can_object_put(dev, iface, i, IF_COMM_CONTROL); |
| 393 | } | 365 | } |
| 394 | } | 366 | } |
| 395 | 367 | ||
| 396 | static inline void c_can_activate_rx_msg_obj(struct net_device *dev, | 368 | static int c_can_handle_lost_msg_obj(struct net_device *dev, |
| 397 | int iface, int ctrl_mask, | 369 | int iface, int objno, u32 ctrl) |
| 398 | int obj) | ||
| 399 | { | ||
| 400 | struct c_can_priv *priv = netdev_priv(dev); | ||
| 401 | |||
| 402 | priv->write_reg(priv, C_CAN_IFACE(MSGCTRL_REG, iface), | ||
| 403 | ctrl_mask & ~(IF_MCONT_MSGLST | | ||
| 404 | IF_MCONT_INTPND | IF_MCONT_NEWDAT)); | ||
| 405 | c_can_object_put(dev, iface, obj, IF_COMM_CONTROL); | ||
| 406 | } | ||
| 407 | |||
| 408 | static void c_can_handle_lost_msg_obj(struct net_device *dev, | ||
| 409 | int iface, int objno) | ||
| 410 | { | 370 | { |
| 411 | struct c_can_priv *priv = netdev_priv(dev); | ||
| 412 | struct net_device_stats *stats = &dev->stats; | 371 | struct net_device_stats *stats = &dev->stats; |
| 413 | struct sk_buff *skb; | 372 | struct c_can_priv *priv = netdev_priv(dev); |
| 414 | struct can_frame *frame; | 373 | struct can_frame *frame; |
| 374 | struct sk_buff *skb; | ||
| 415 | 375 | ||
| 416 | netdev_err(dev, "msg lost in buffer %d\n", objno); | 376 | ctrl &= ~(IF_MCONT_MSGLST | IF_MCONT_INTPND | IF_MCONT_NEWDAT); |
| 417 | 377 | priv->write_reg(priv, C_CAN_IFACE(MSGCTRL_REG, iface), ctrl); | |
| 418 | c_can_object_get(dev, iface, objno, IF_COMM_ALL & ~IF_COMM_TXRQST); | 378 | c_can_object_put(dev, iface, objno, IF_COMM_CONTROL); |
| 419 | |||
| 420 | priv->write_reg(priv, C_CAN_IFACE(MSGCTRL_REG, iface), | ||
| 421 | IF_MCONT_CLR_MSGLST); | ||
| 422 | |||
| 423 | c_can_object_put(dev, 0, objno, IF_COMM_CONTROL); | ||
| 424 | 379 | ||
| 425 | /* create an error msg */ | 380 | /* create an error msg */ |
| 426 | skb = alloc_can_err_skb(dev, &frame); | 381 | skb = alloc_can_err_skb(dev, &frame); |
| 427 | if (unlikely(!skb)) | 382 | if (unlikely(!skb)) |
| 428 | return; | 383 | return 0; |
| 429 | 384 | ||
| 430 | frame->can_id |= CAN_ERR_CRTL; | 385 | frame->can_id |= CAN_ERR_CRTL; |
| 431 | frame->data[1] = CAN_ERR_CRTL_RX_OVERFLOW; | 386 | frame->data[1] = CAN_ERR_CRTL_RX_OVERFLOW; |
| @@ -433,6 +388,7 @@ static void c_can_handle_lost_msg_obj(struct net_device *dev, · 1 unmodified line | |||
| 433 | stats->rx_over_errors++; | 388 | stats->rx_over_errors++; |
| 434 | 389 | ||
| 435 | netif_receive_skb(skb); | 390 | netif_receive_skb(skb); |
| 391 | return 1; | ||
| 436 | } | 392 | } |
| 437 | 393 | ||
| 438 | static int c_can_read_msg_object(struct net_device *dev, int iface, int ctrl) | 394 | static int c_can_read_msg_object(struct net_device *dev, int iface, int ctrl) |
| @@ -477,9 +433,6 @@ static int c_can_read_msg_object(struct net_device *dev, int iface, int ctrl) · 38 unmodified lines | |||
| 477 | 433 | ||
| 478 | stats->rx_packets++; | 434 | stats->rx_packets++; |
| 479 | stats->rx_bytes += frame->can_dlc; | 435 | stats->rx_bytes += frame->can_dlc; |
| 480 | |||
| 481 | can_led_event(dev, CAN_LED_EVENT_RX); | ||
| 482 | |||
| 483 | return 0; | 436 | return 0; |
| 484 | } | 437 | } |
| 485 | 438 | ||
| @@ -548,10 +501,12 @@ static netdev_tx_t c_can_start_xmit(struct sk_buff *skb, · 62 unmodified lines | |||
| 548 | if (can_dropped_invalid_skb(dev, skb)) | 501 | if (can_dropped_invalid_skb(dev, skb)) |
| 549 | return NETDEV_TX_OK; | 502 | return NETDEV_TX_OK; |
| 550 | 503 | ||
| 504 | spin_lock_bh(&priv->xmit_lock); | ||
| 551 | msg_obj_no = get_tx_next_msg_obj(priv); | 505 | msg_obj_no = get_tx_next_msg_obj(priv); |
| 552 | 506 | ||
| 553 | /* prepare message object for transmission */ | 507 | /* prepare message object for transmission */ |
| 554 | c_can_write_msg_object(dev, 0, frame, msg_obj_no); | 508 | c_can_write_msg_object(dev, IF_TX, frame, msg_obj_no); |
| 509 | priv->dlc[msg_obj_no - C_CAN_MSG_OBJ_TX_FIRST] = frame->can_dlc; | ||
| 555 | can_put_echo_skb(skb, dev, msg_obj_no - C_CAN_MSG_OBJ_TX_FIRST); | 510 | can_put_echo_skb(skb, dev, msg_obj_no - C_CAN_MSG_OBJ_TX_FIRST); |
| 556 | 511 | ||
| 557 | /* | 512 | /* |
| @@ -562,10 +517,26 @@ static netdev_tx_t c_can_start_xmit(struct sk_buff *skb, · 4 unmodified lines | |||
| 562 | if (c_can_is_next_tx_obj_busy(priv, get_tx_next_msg_obj(priv)) || | 517 | if (c_can_is_next_tx_obj_busy(priv, get_tx_next_msg_obj(priv)) || |
| 563 | (priv->tx_next & C_CAN_NEXT_MSG_OBJ_MASK) == 0) | 518 | (priv->tx_next & C_CAN_NEXT_MSG_OBJ_MASK) == 0) |
| 564 | netif_stop_queue(dev); | 519 | netif_stop_queue(dev); |
| 520 | spin_unlock_bh(&priv->xmit_lock); | ||
| 565 | 521 | ||
| 566 | return NETDEV_TX_OK; | 522 | return NETDEV_TX_OK; |
| 567 | } | 523 | } |
| 568 | 524 | ||
| 525 | static int c_can_wait_for_ctrl_init(struct net_device *dev, | ||
| 526 | struct c_can_priv *priv, u32 init) | ||
| 527 | { | ||
| 528 | int retry = 0; | ||
| 529 | |||
| 530 | while (init != (priv->read_reg(priv, C_CAN_CTRL_REG) & CONTROL_INIT)) { | ||
| 531 | udelay(10); | ||
| 532 | if (retry++ > 1000) { | ||
| 533 | netdev_err(dev, "CCTRL: set CONTROL_INIT failed\n"); | ||
| 534 | return -EIO; | ||
| 535 | } | ||
| 536 | } | ||
| 537 | return 0; | ||
| 538 | } | ||
| 539 | |||
| 569 | static int c_can_set_bittiming(struct net_device *dev) | 540 | static int c_can_set_bittiming(struct net_device *dev) |
| 570 | { | 541 | { |
| 571 | unsigned int reg_btr, reg_brpe, ctrl_save; | 542 | unsigned int reg_btr, reg_brpe, ctrl_save; |
| @@ -573,6 +544,7 @@ static int c_can_set_bittiming(struct net_device *dev) · 1 unmodified line | |||
| 573 | u32 ten_bit_brp; | 544 | u32 ten_bit_brp; |
| 574 | struct c_can_priv *priv = netdev_priv(dev); | 545 | struct c_can_priv *priv = netdev_priv(dev); |
| 575 | const struct can_bittiming *bt = &priv->can.bittiming; | 546 | const struct can_bittiming *bt = &priv->can.bittiming; |
| 547 | int res; | ||
| 576 | 548 | ||
| 577 | /* c_can provides a 6-bit brp and 4-bit brpe fields */ | 549 | /* c_can provides a 6-bit brp and 4-bit brpe fields */ |
| 578 | ten_bit_brp = bt->brp - 1; | 550 | ten_bit_brp = bt->brp - 1; |
| @@ -590,13 +562,17 @@ static int c_can_set_bittiming(struct net_device *dev) · 11 unmodified lines | |||
| 590 | "setting BTR=%04x BRPE=%04x\n", reg_btr, reg_brpe); | 562 | "setting BTR=%04x BRPE=%04x\n", reg_btr, reg_brpe); |
| 591 | 563 | ||
| 592 | ctrl_save = priv->read_reg(priv, C_CAN_CTRL_REG); | 564 | ctrl_save = priv->read_reg(priv, C_CAN_CTRL_REG); |
| 593 | priv->write_reg(priv, C_CAN_CTRL_REG, | 565 | ctrl_save &= ~CONTROL_INIT; |
| 594 | ctrl_save | CONTROL_CCE | CONTROL_INIT); | 566 | priv->write_reg(priv, C_CAN_CTRL_REG, CONTROL_CCE | CONTROL_INIT); |
| 567 | res = c_can_wait_for_ctrl_init(dev, priv, CONTROL_INIT); | ||
| 568 | if (res) | ||
| 569 | return res; | ||
| 570 | |||
| 595 | priv->write_reg(priv, C_CAN_BTR_REG, reg_btr); | 571 | priv->write_reg(priv, C_CAN_BTR_REG, reg_btr); |
| 596 | priv->write_reg(priv, C_CAN_BRPEXT_REG, reg_brpe); | 572 | priv->write_reg(priv, C_CAN_BRPEXT_REG, reg_brpe); |
| 597 | priv->write_reg(priv, C_CAN_CTRL_REG, ctrl_save); | 573 | priv->write_reg(priv, C_CAN_CTRL_REG, ctrl_save); |
| 598 | 574 | ||
| 599 | return 0; | 575 | return c_can_wait_for_ctrl_init(dev, priv, 0); |
| 600 | } | 576 | } |
| 601 | 577 | ||
| 602 | /* | 578 | /* |
| @@ -614,14 +590,14 @@ static void c_can_configure_msg_objects(struct net_device *dev) · 11 unmodified lines | |||
| 614 | 590 | ||
| 615 | /* first invalidate all message objects */ | 591 | /* first invalidate all message objects */ |
| 616 | for (i = C_CAN_MSG_OBJ_RX_FIRST; i <= C_CAN_NO_OF_OBJECTS; i++) | 592 | for (i = C_CAN_MSG_OBJ_RX_FIRST; i <= C_CAN_NO_OF_OBJECTS; i++) |
| 617 | c_can_inval_msg_object(dev, 0, i); | 593 | c_can_inval_msg_object(dev, IF_RX, i); |
| 618 | 594 | ||
| 619 | /* setup receive message objects */ | 595 | /* setup receive message objects */ |
| 620 | for (i = C_CAN_MSG_OBJ_RX_FIRST; i < C_CAN_MSG_OBJ_RX_LAST; i++) | 596 | for (i = C_CAN_MSG_OBJ_RX_FIRST; i < C_CAN_MSG_OBJ_RX_LAST; i++) |
| 621 | c_can_setup_receive_object(dev, 0, i, 0, 0, | 597 | c_can_setup_receive_object(dev, IF_RX, i, 0, 0, |
| 622 | (IF_MCONT_RXIE | IF_MCONT_UMASK) & ~IF_MCONT_EOB); | 598 | (IF_MCONT_RXIE | IF_MCONT_UMASK) & ~IF_MCONT_EOB); |
| 623 | 599 | ||
| 624 | c_can_setup_receive_object(dev, 0, C_CAN_MSG_OBJ_RX_LAST, 0, 0, | 600 | c_can_setup_receive_object(dev, IF_RX, C_CAN_MSG_OBJ_RX_LAST, 0, 0, |
| 625 | IF_MCONT_EOB | IF_MCONT_RXIE | IF_MCONT_UMASK); | 601 | IF_MCONT_EOB | IF_MCONT_RXIE | IF_MCONT_UMASK); |
| 626 | } | 602 | } |
| 627 | 603 | ||
| @@ -631,7 +607,7 @@ static void c_can_configure_msg_objects(struct net_device *dev) · 3 unmodified lines | |||
| 631 | * - set operating mode | 607 | * - set operating mode |
| 632 | * - configure message objects | 608 | * - configure message objects |
| 633 | */ | 609 | */ |
| 634 | static void c_can_chip_config(struct net_device *dev) | 610 | static int c_can_chip_config(struct net_device *dev) |
| 635 | { | 611 | { |
| 636 | struct c_can_priv *priv = netdev_priv(dev); | 612 | struct c_can_priv *priv = netdev_priv(dev); |
| 637 | 613 | ||
| @@ -668,15 +644,18 @@ static void c_can_chip_config(struct net_device *dev) · 30 unmodified lines | |||
| 668 | priv->write_reg(priv, C_CAN_STS_REG, LEC_UNUSED); | 644 | priv->write_reg(priv, C_CAN_STS_REG, LEC_UNUSED); |
| 669 | 645 | ||
| 670 | /* set bittiming params */ | 646 | /* set bittiming params */ |
| 671 | c_can_set_bittiming(dev); | 647 | return c_can_set_bittiming(dev); |
| 672 | } | 648 | } |
| 673 | 649 | ||
| 674 | static void c_can_start(struct net_device *dev) | 650 | static int c_can_start(struct net_device *dev) |
| 675 | { | 651 | { |
| 676 | struct c_can_priv *priv = netdev_priv(dev); | 652 | struct c_can_priv *priv = netdev_priv(dev); |
| 653 | int err; | ||
| 677 | 654 | ||
| 678 | /* basic c_can configuration */ | 655 | /* basic c_can configuration */ |
| 679 | c_can_chip_config(dev); | 656 | err = c_can_chip_config(dev); |
| 657 | if (err) | ||
| 658 | return err; | ||
| 680 | 659 | ||
| 681 | priv->can.state = CAN_STATE_ERROR_ACTIVE; | 660 | priv->can.state = CAN_STATE_ERROR_ACTIVE; |
| 682 | 661 | ||
| @@ -685,6 +664,8 @@ static void c_can_start(struct net_device *dev) · 2 unmodified lines | |||
| 685 | 664 | ||
| 686 | /* enable status change, error and module interrupts */ | 665 | /* enable status change, error and module interrupts */ |
| 687 | c_can_enable_all_interrupts(priv, ENABLE_ALL_INTERRUPTS); | 666 | c_can_enable_all_interrupts(priv, ENABLE_ALL_INTERRUPTS); |
| 667 | |||
| 668 | return 0; | ||
| 688 | } | 669 | } |
| 689 | 670 | ||
| 690 | static void c_can_stop(struct net_device *dev) | 671 | static void c_can_stop(struct net_device *dev) |
| @@ -700,9 +681,13 @@ static void c_can_stop(struct net_device *dev) · 9 unmodified lines | |||
| 700 | 681 | ||
| 701 | static int c_can_set_mode(struct net_device *dev, enum can_mode mode) | 682 | static int c_can_set_mode(struct net_device *dev, enum can_mode mode) |
| 702 | { | 683 | { |
| 684 | int err; | ||
| 685 | |||
| 703 | switch (mode) { | 686 | switch (mode) { |
| 704 | case CAN_MODE_START: | 687 | case CAN_MODE_START: |
| 705 | c_can_start(dev); | 688 | err = c_can_start(dev); |
| 689 | if (err) | ||
| 690 | return err; | ||
| 706 | netif_wake_queue(dev); | 691 | netif_wake_queue(dev); |
| 707 | break; | 692 | break; |
| 708 | default: | 693 | default: |
| @@ -740,8 +725,6 @@ static int c_can_get_berr_counter(const struct net_device *dev, · 31 unmodified lines | |||
| 740 | } | 725 | } |
| 741 | 726 | ||
| 742 | /* | 727 | /* |
| 743 | * theory of operation: | ||
| 744 | * | ||
| 745 | * priv->tx_echo holds the number of the oldest can_frame put for | 728 | * priv->tx_echo holds the number of the oldest can_frame put for |
| 746 | * transmission into the hardware, but not yet ACKed by the CAN tx | 729 | * transmission into the hardware, but not yet ACKed by the CAN tx |
| 747 | * complete IRQ. | 730 | * complete IRQ. |
| @@ -752,33 +735,113 @@ static int c_can_get_berr_counter(const struct net_device *dev, · 4 unmodified lines | |||
| 752 | */ | 735 | */ |
| 753 | static void c_can_do_tx(struct net_device *dev) | 736 | static void c_can_do_tx(struct net_device *dev) |
| 754 | { | 737 | { |
| 755 | u32 val; | ||
| 756 | u32 msg_obj_no; | ||
| 757 | struct c_can_priv *priv = netdev_priv(dev); | 738 | struct c_can_priv *priv = netdev_priv(dev); |
| 758 | struct net_device_stats *stats = &dev->stats; | 739 | struct net_device_stats *stats = &dev->stats; |
| 740 | u32 val, obj, pkts = 0, bytes = 0; | ||
| 759 | 741 | ||
| 760 | for (/* nix */; (priv->tx_next - priv->tx_echo) > 0; priv->tx_echo++) { | 742 | spin_lock_bh(&priv->xmit_lock); |
| 761 | msg_obj_no = get_tx_echo_msg_obj(priv); | 743 | |
| 744 | for (; (priv->tx_next - priv->tx_echo) > 0; priv->tx_echo++) { | ||
| 745 | obj = get_tx_echo_msg_obj(priv->tx_echo); | ||
| 762 | val = c_can_read_reg32(priv, C_CAN_TXRQST1_REG); | 746 | val = c_can_read_reg32(priv, C_CAN_TXRQST1_REG); |
| 763 | if (!(val & (1 << (msg_obj_no - 1)))) { | 747 | |
| 764 | can_get_echo_skb(dev, | 748 | if (val & (1 << (obj - 1))) |
| 765 | msg_obj_no - C_CAN_MSG_OBJ_TX_FIRST); | ||
| 766 | c_can_object_get(dev, 0, msg_obj_no, IF_COMM_ALL); | ||
| 767 | stats->tx_bytes += priv->read_reg(priv, | ||
| 768 | C_CAN_IFACE(MSGCTRL_REG, 0)) | ||
| 769 | & IF_MCONT_DLC_MASK; | ||
| 770 | stats->tx_packets++; | ||
| 771 | can_led_event(dev, CAN_LED_EVENT_TX); | ||
| 772 | c_can_inval_msg_object(dev, 0, msg_obj_no); | ||
| 773 | } else { | ||
| 774 | break; | 749 | break; |
| 775 | } | 750 | |
| 751 | can_get_echo_skb(dev, obj - C_CAN_MSG_OBJ_TX_FIRST); | ||
| 752 | bytes += priv->dlc[obj - C_CAN_MSG_OBJ_TX_FIRST]; | ||
| 753 | pkts++; | ||
| 754 | c_can_inval_msg_object(dev, IF_TX, obj); | ||
| 776 | } | 755 | } |
| 777 | 756 | ||
| 778 | /* restart queue if wrap-up or if queue stalled on last pkt */ | 757 | /* restart queue if wrap-up or if queue stalled on last pkt */ |
| 779 | if (((priv->tx_next & C_CAN_NEXT_MSG_OBJ_MASK) != 0) || | 758 | if (((priv->tx_next & C_CAN_NEXT_MSG_OBJ_MASK) != 0) || |
| 780 | ((priv->tx_echo & C_CAN_NEXT_MSG_OBJ_MASK) == 0)) | 759 | ((priv->tx_echo & C_CAN_NEXT_MSG_OBJ_MASK) == 0)) |
| 781 | netif_wake_queue(dev); | 760 | netif_wake_queue(dev); |
| 761 | |||
| 762 | spin_unlock_bh(&priv->xmit_lock); | ||
| 763 | |||
| 764 | if (pkts) { | ||
| 765 | stats->tx_bytes += bytes; | ||
| 766 | stats->tx_packets += pkts; | ||
| 767 | can_led_event(dev, CAN_LED_EVENT_TX); | ||
| 768 | } | ||
| 769 | } | ||
| 770 | |||
| 771 | /* | ||
| 772 | * If we have a gap in the pending bits, that means we either | ||
| 773 | * raced with the hardware or failed to readout all upper | ||
| 774 | * objects in the last run due to quota limit. | ||
| 775 | */ | ||
| 776 | static u32 c_can_adjust_pending(u32 pend) | ||
| 777 | { | ||
| 778 | u32 weight, lasts; | ||
| 779 | |||
| 780 | if (pend == RECEIVE_OBJECT_BITS) | ||
| 781 | return pend; | ||
| 782 | |||
| 783 | /* | ||
| 784 | * If the last set bit is larger than the number of pending | ||
| 785 | * bits we have a gap. | ||
| 786 | */ | ||
| 787 | weight = hweight32(pend); | ||
| 788 | lasts = fls(pend); | ||
| 789 | |||
| 790 | /* If the bits are linear, nothing to do */ | ||
| 791 | if (lasts == weight) | ||
| 792 | return pend; | ||
| 793 | |||
| 794 | /* | ||
| 795 | * Find the first set bit after the gap. We walk backwards | ||
| 796 | * from the last set bit. | ||
| 797 | */ | ||
| 798 | for (lasts--; pend & (1 << (lasts - 1)); lasts--); | ||
| 799 | |||
| 800 | return pend & ~((1 << lasts) - 1); | ||
| 801 | } | ||
| 802 | |||
| 803 | static int c_can_read_objects(struct net_device *dev, struct c_can_priv *priv, | ||
| 804 | u32 pend, int quota) | ||
| 805 | { | ||
| 806 | u32 pkts = 0, ctrl, obj, mcmd; | ||
| 807 | |||
| 808 | while ((obj = ffs(pend)) && quota > 0) { | ||
| 809 | pend &= ~BIT(obj - 1); | ||
| 810 | |||
| 811 | mcmd = obj < C_CAN_MSG_RX_LOW_LAST ? | ||
| 812 | IF_COMM_RCV_LOW : IF_COMM_RCV_HIGH; | ||
| 813 | |||
| 814 | c_can_object_get(dev, IF_RX, obj, mcmd); | ||
| 815 | ctrl = priv->read_reg(priv, C_CAN_IFACE(MSGCTRL_REG, IF_RX)); | ||
| 816 | |||
| 817 | if (ctrl & IF_MCONT_MSGLST) { | ||
| 818 | int n = c_can_handle_lost_msg_obj(dev, IF_RX, obj, ctrl); | ||
| 819 | |||
| 820 | pkts += n; | ||
| 821 | quota -= n; | ||
| 822 | continue; | ||
| 823 | } | ||
| 824 | |||
| 825 | /* | ||
| 826 | * This really should not happen, but this covers some | ||
| 827 | * odd HW behaviour. Do not remove that unless you | ||
| 828 | * want to brick your machine. | ||
| 829 | */ | ||
| 830 | if (!(ctrl & IF_MCONT_NEWDAT)) | ||
| 831 | continue; | ||
| 832 | |||
| 833 | /* read the data from the message object */ | ||
| 834 | c_can_read_msg_object(dev, IF_RX, ctrl); | ||
| 835 | |||
| 836 | if (obj == C_CAN_MSG_RX_LOW_LAST) | ||
| 837 | /* activate all lower message objects */ | ||
| 838 | c_can_activate_all_lower_rx_msg_obj(dev, IF_RX, ctrl); | ||
| 839 | |||
| 840 | pkts++; | ||
| 841 | quota--; | ||
| 842 | } | ||
| 843 | |||
| 844 | return pkts; | ||
| 782 | } | 845 | } |
| 783 | 846 | ||
| 784 | /* | 847 | /* |
| @@ -805,10 +868,8 @@ static void c_can_do_tx(struct net_device *dev) · 20 unmodified lines | |||
| 805 | */ | 868 | */ |
| 806 | static int c_can_do_rx_poll(struct net_device *dev, int quota) | 869 | static int c_can_do_rx_poll(struct net_device *dev, int quota) |
| 807 | { | 870 | { |
| 808 | u32 num_rx_pkts = 0; | ||
| 809 | unsigned int msg_obj, msg_ctrl_save; | ||
| 810 | struct c_can_priv *priv = netdev_priv(dev); | 871 | struct c_can_priv *priv = netdev_priv(dev); |
| 811 | u16 val; | 872 | u32 pkts = 0, pend = 0, toread, n; |
| 812 | 873 | ||
| 813 | /* | 874 | /* |
| 814 | * It is faster to read only one 16bit register. This is only possible | 875 | * It is faster to read only one 16bit register. This is only possible |
| @@ -817,49 +878,31 @@ static int c_can_do_rx_poll(struct net_device *dev, int quota) · 2 unmodified lines | |||
| 817 | BUILD_BUG_ON_MSG(C_CAN_MSG_OBJ_RX_LAST > 16, | 878 | BUILD_BUG_ON_MSG(C_CAN_MSG_OBJ_RX_LAST > 16, |
| 818 | "Implementation does not support more message objects than 16"); | 879 | "Implementation does not support more message objects than 16"); |
| 819 | 880 | ||
| 820 | while (quota > 0 && (val = priv->read_reg(priv, C_CAN_INTPND1_REG))) { | 881 | while (quota > 0) { |
| 821 | while ((msg_obj = ffs(val)) && quota > 0) { | 882 | if (!pend) { |
| 822 | val &= ~BIT(msg_obj - 1); | 883 | pend = priv->read_reg(priv, C_CAN_INTPND1_REG); |
| 823 | 884 | if (!pend) | |
| 824 | c_can_object_get(dev, 0, msg_obj, IF_COMM_ALL & | 885 | break; |
| 825 | ~IF_COMM_TXRQST); | 886 | /* |
| 826 | msg_ctrl_save = priv->read_reg(priv, | 887 | * If the pending field has a gap, handle the |
| 827 | C_CAN_IFACE(MSGCTRL_REG, 0)); | 888 | * bits above the gap first. |
| 828 | 889 | */ | |
| 829 | if (msg_ctrl_save & IF_MCONT_MSGLST) { | 890 | toread = c_can_adjust_pending(pend); |
| 830 | c_can_handle_lost_msg_obj(dev, 0, msg_obj); | 891 | } else { |
| 831 | num_rx_pkts++; | 892 | toread = pend; |
| 832 | quota--; | ||
| 833 | continue; | ||
| 834 | } | ||
| 835 | |||
| 836 | if (msg_ctrl_save & IF_MCONT_EOB) | ||
| 837 | return num_rx_pkts; | ||
| 838 | |||
| 839 | if (!(msg_ctrl_save & IF_MCONT_NEWDAT)) | ||
| 840 | continue; | ||
| 841 | |||
| 842 | /* read the data from the message object */ | ||
| 843 | c_can_read_msg_object(dev, 0, msg_ctrl_save); | ||
| 844 | |||
| 845 | if (msg_obj < C_CAN_MSG_RX_LOW_LAST) | ||
| 846 | c_can_mark_rx_msg_obj(dev, 0, | ||
| 847 | msg_ctrl_save, msg_obj); | ||
| 848 | else if (msg_obj > C_CAN_MSG_RX_LOW_LAST) | ||
| 849 | /* activate this msg obj */ | ||
| 850 | c_can_activate_rx_msg_obj(dev, 0, | ||
| 851 | msg_ctrl_save, msg_obj); | ||
| 852 | else if (msg_obj == C_CAN_MSG_RX_LOW_LAST) | ||
| 853 | /* activate all lower message objects */ | ||
| 854 | c_can_activate_all_lower_rx_msg_obj(dev, | ||
| 855 | 0, msg_ctrl_save); | ||
| 856 | |||
| 857 | num_rx_pkts++; | ||
| 858 | quota--; | ||
| 859 | } | 893 | } |
| 894 | /* Remove the bits from pend */ | ||
| 895 | pend &= ~toread; | ||
| 896 | /* Read the objects */ | ||
| 897 | n = c_can_read_objects(dev, priv, toread, quota); | ||
| 898 | pkts += n; | ||
| 899 | quota -= n; | ||
| 860 | } | 900 | } |
| 861 | 901 | ||
| 862 | return num_rx_pkts; | 902 | if (pkts) |
| 903 | can_led_event(dev, CAN_LED_EVENT_RX); | ||
| 904 | |||
| 905 | return pkts; | ||
| 863 | } | 906 | } |
| 864 | 907 | ||
| 865 | static inline int c_can_has_and_handle_berr(struct c_can_priv *priv) | 908 | static inline int c_can_has_and_handle_berr(struct c_can_priv *priv) |
| @@ -1133,17 +1176,20 @@ static int c_can_open(struct net_device *dev) · 267 unmodified lines | |||
| 1133 | goto exit_irq_fail; | 1176 | goto exit_irq_fail; |
| 1134 | } | 1177 | } |
| 1135 | 1178 | ||
| 1136 | napi_enable(&priv->napi); | 1179 | /* start the c_can controller */ |
| 1180 | err = c_can_start(dev); | ||
| 1181 | if (err) | ||
| 1182 | goto exit_start_fail; | ||
| 1137 | 1183 | ||
| 1138 | can_led_event(dev, CAN_LED_EVENT_OPEN); | 1184 | can_led_event(dev, CAN_LED_EVENT_OPEN); |
| 1139 | 1185 | ||
| 1140 | /* start the c_can controller */ | 1186 | napi_enable(&priv->napi); |
| 1141 | c_can_start(dev); | ||
| 1142 | |||
| 1143 | netif_start_queue(dev); | 1187 | netif_start_queue(dev); |
| 1144 | 1188 | ||
| 1145 | return 0; | 1189 | return 0; |
| 1146 | 1190 | ||
| 1191 | exit_start_fail: | ||
| 1192 | free_irq(dev->irq, dev); | ||
| 1147 | exit_irq_fail: | 1193 | exit_irq_fail: |
| 1148 | close_candev(dev); | 1194 | close_candev(dev); |
| 1149 | exit_open_fail: | 1195 | exit_open_fail: |
| @@ -1180,6 +1226,7 @@ struct net_device *alloc_c_can_dev(void) · 30 unmodified lines | |||
| 1180 | return NULL; | 1226 | return NULL; |
| 1181 | 1227 | ||
| 1182 | priv = netdev_priv(dev); | 1228 | priv = netdev_priv(dev); |
| 1229 | spin_lock_init(&priv->xmit_lock); | ||
| 1183 | netif_napi_add(dev, &priv->napi, c_can_poll, C_CAN_NAPI_WEIGHT); | 1230 | netif_napi_add(dev, &priv->napi, c_can_poll, C_CAN_NAPI_WEIGHT); |
| 1184 | 1231 | ||
| 1185 | priv->dev = dev; | 1232 | priv->dev = dev; |
| @@ -1260,15 +1307,16 @@ int c_can_power_up(struct net_device *dev) · 74 unmodified lines | |||
| 1260 | if (time_after(jiffies, time_out)) | 1307 | if (time_after(jiffies, time_out)) |
| 1261 | return -ETIMEDOUT; | 1308 | return -ETIMEDOUT; |
| 1262 | 1309 | ||
| 1263 | c_can_start(dev); | 1310 | return c_can_start(dev); |
| 1264 | |||
| 1265 | return 0; | ||
| 1266 | } | 1311 | } |
| 1267 | EXPORT_SYMBOL_GPL(c_can_power_up); | 1312 | EXPORT_SYMBOL_GPL(c_can_power_up); |
| 1268 | #endif | 1313 | #endif |
| 1269 | 1314 | ||
| 1270 | void free_c_can_dev(struct net_device *dev) | 1315 | void free_c_can_dev(struct net_device *dev) |
| 1271 | { | 1316 | { |
| 1317 | struct c_can_priv *priv = netdev_priv(dev); | ||
| 1318 | |||
| 1319 | netif_napi_del(&priv->napi); | ||
| 1272 | free_candev(dev); | 1320 | free_candev(dev); |
| 1273 | } | 1321 | } |
| 1274 | EXPORT_SYMBOL_GPL(free_c_can_dev); | 1322 | EXPORT_SYMBOL_GPL(free_c_can_dev); |
| @@ -1277,6 +1325,7 @@ static const struct net_device_ops c_can_netdev_ops = { · 2 unmodified lines | |||
| 1277 | .ndo_open = c_can_open, | 1325 | .ndo_open = c_can_open, |
| 1278 | .ndo_stop = c_can_close, | 1326 | .ndo_stop = c_can_close, |
| 1279 | .ndo_start_xmit = c_can_start_xmit, | 1327 | .ndo_start_xmit = c_can_start_xmit, |
| 1328 | .ndo_change_mtu = can_change_mtu, | ||
| 1280 | }; | 1329 | }; |
| 1281 | 1330 | ||
| 1282 | int register_c_can_dev(struct net_device *dev) | 1331 | int register_c_can_dev(struct net_device *dev) |
| @@ -22,6 +22,33 @@ · 21 unmodified lines | |||
| 22 | #ifndef C_CAN_H | 22 | #ifndef C_CAN_H |
| 23 | #define C_CAN_H | 23 | #define C_CAN_H |
| 24 | 24 | ||
| 25 | /* | ||
| 26 | * IFx register masks: | ||
| 27 | * allow easy operation on 16-bit registers when the | ||
| 28 | * argument is 32-bit instead | ||
| 29 | */ | ||
| 30 | #define IFX_WRITE_LOW_16BIT(x) ((x) & 0xFFFF) | ||
| 31 | #define IFX_WRITE_HIGH_16BIT(x) (((x) & 0xFFFF0000) >> 16) | ||
| 32 | |||
| 33 | /* message object split */ | ||
| 34 | #define C_CAN_NO_OF_OBJECTS 32 | ||
| 35 | #define C_CAN_MSG_OBJ_RX_NUM 16 | ||
| 36 | #define C_CAN_MSG_OBJ_TX_NUM 16 | ||
| 37 | |||
| 38 | #define C_CAN_MSG_OBJ_RX_FIRST 1 | ||
| 39 | #define C_CAN_MSG_OBJ_RX_LAST (C_CAN_MSG_OBJ_RX_FIRST + \ | ||
| 40 | C_CAN_MSG_OBJ_RX_NUM - 1) | ||
| 41 | |||
| 42 | #define C_CAN_MSG_OBJ_TX_FIRST (C_CAN_MSG_OBJ_RX_LAST + 1) | ||
| 43 | #define C_CAN_MSG_OBJ_TX_LAST (C_CAN_MSG_OBJ_TX_FIRST + \ | ||
| 44 | C_CAN_MSG_OBJ_TX_NUM - 1) | ||
| 45 | |||
| 46 | #define C_CAN_MSG_OBJ_RX_SPLIT 9 | ||
| 47 | #define C_CAN_MSG_RX_LOW_LAST (C_CAN_MSG_OBJ_RX_SPLIT - 1) | ||
| 48 | |||
| 49 | #define C_CAN_NEXT_MSG_OBJ_MASK (C_CAN_MSG_OBJ_TX_NUM - 1) | ||
| 50 | #define RECEIVE_OBJECT_BITS 0x0000ffff | ||
| 51 | |||
| 25 | enum reg { | 52 | enum reg { |
| 26 | C_CAN_CTRL_REG = 0, | 53 | C_CAN_CTRL_REG = 0, |
| 27 | C_CAN_CTRL_EX_REG, | 54 | C_CAN_CTRL_EX_REG, |
| @@ -156,6 +183,7 @@ struct c_can_priv { · 128 unmodified lines | |||
| 156 | struct napi_struct napi; | 183 | struct napi_struct napi; |
| 157 | struct net_device *dev; | 184 | struct net_device *dev; |
| 158 | struct device *device; | 185 | struct device *device; |
| 186 | spinlock_t xmit_lock; | ||
| 159 | int tx_object; | 187 | int tx_object; |
| 160 | int current_status; | 188 | int current_status; |
| 161 | int last_status; | 189 | int last_status; |
| @@ -172,6 +200,7 @@ struct c_can_priv { · 10 unmodified lines | |||
| 172 | u32 __iomem *raminit_ctrlreg; | 200 | u32 __iomem *raminit_ctrlreg; |
| 173 | unsigned int instance; | 201 | unsigned int instance; |
| 174 | void (*raminit) (const struct c_can_priv *priv, bool enable); | 202 | void (*raminit) (const struct c_can_priv *priv, bool enable); |
| 203 | u32 dlc[C_CAN_MSG_OBJ_TX_NUM]; | ||
| 175 | }; | 204 | }; |
| 176 | 205 | ||
| 177 | struct net_device *alloc_c_can_dev(void); | 206 | struct net_device *alloc_c_can_dev(void); |
| @@ -37,8 +37,10 @@ · 36 unmodified lines | |||
| 37 | 37 | ||
| 38 | #include "c_can.h" | 38 | #include "c_can.h" |
| 39 | 39 | ||
| 40 | #define CAN_RAMINIT_START_MASK(i) (1 << (i)) | 40 | #define CAN_RAMINIT_START_MASK(i) (0x001 << (i)) |
| 41 | 41 | #define CAN_RAMINIT_DONE_MASK(i) (0x100 << (i)) | |
| 42 | #define CAN_RAMINIT_ALL_MASK(i) (0x101 << (i)) | ||
| 43 | static DEFINE_SPINLOCK(raminit_lock); | ||
| 42 | /* | 44 | /* |
| 43 | * 16-bit c_can registers can be arranged differently in the memory | 45 | * 16-bit c_can registers can be arranged differently in the memory |
| 44 | * architecture of different implementations. For example: 16-bit | 46 | * architecture of different implementations. For example: 16-bit |
| @@ -69,16 +71,41 @@ static void c_can_plat_write_reg_aligned_to_32bit(struct c_can_priv *priv, · 24 unmodified lines | |||
| 69 | writew(val, priv->base + 2 * priv->regs[index]); | 71 | writew(val, priv->base + 2 * priv->regs[index]); |
| 70 | } | 72 | } |
| 71 | 73 | ||
| 74 | static void c_can_hw_raminit_wait(const struct c_can_priv *priv, u32 mask, | ||
| 75 | u32 val) | ||
| 76 | { | ||
| 77 | /* We look only at the bits of our instance. */ | ||
| 78 | val &= mask; | ||
| 79 | while ((readl(priv->raminit_ctrlreg) & mask) != val) | ||
| 80 | udelay(1); | ||
| 81 | } | ||
| 82 | |||
| 72 | static void c_can_hw_raminit(const struct c_can_priv *priv, bool enable) | 83 | static void c_can_hw_raminit(const struct c_can_priv *priv, bool enable) |
| 73 | { | 84 | { |
| 74 | u32 val; | 85 | u32 mask = CAN_RAMINIT_ALL_MASK(priv->instance); |
| 75 | 86 | u32 ctrl; | |
| 76 | val = readl(priv->raminit_ctrlreg); | 87 | |
| 77 | if (enable) | 88 | spin_lock(&raminit_lock); |
| 78 | val |= CAN_RAMINIT_START_MASK(priv->instance); | 89 | |
| 79 | else | 90 | ctrl = readl(priv->raminit_ctrlreg); |
| 80 | val &= ~CAN_RAMINIT_START_MASK(priv->instance); | 91 | /* We clear the done and start bit first. The start bit is |
| 81 | writel(val, priv->raminit_ctrlreg); | 92 | * looking at the 0 -> transition, but is not self clearing; |
| 93 | * And we clear the init done bit as well. | ||
| 94 | */ | ||
| 95 | ctrl &= ~CAN_RAMINIT_START_MASK(priv->instance); | ||
| 96 | ctrl |= CAN_RAMINIT_DONE_MASK(priv->instance); | ||
| 97 | writel(ctrl, priv->raminit_ctrlreg); | ||
| 98 | ctrl &= ~CAN_RAMINIT_DONE_MASK(priv->instance); | ||
| 99 | c_can_hw_raminit_wait(priv, ctrl, mask); | ||
| 100 | |||
| 101 | if (enable) { | ||
| 102 | /* Set start bit and wait for the done bit. */ | ||
| 103 | ctrl |= CAN_RAMINIT_START_MASK(priv->instance); | ||
| 104 | writel(ctrl, priv->raminit_ctrlreg); | ||
| 105 | ctrl |= CAN_RAMINIT_DONE_MASK(priv->instance); | ||
| 106 | c_can_hw_raminit_wait(priv, ctrl, mask); | ||
| 107 | } | ||
| 108 | spin_unlock(&raminit_lock); | ||
| 82 | } | 109 | } |
| 83 | 110 | ||
| 84 | static struct platform_device_id c_can_id_table[] = { | 111 | static struct platform_device_id c_can_id_table[] = { |
| @@ -823,6 +823,7 @@ static const struct net_device_ops cc770_netdev_ops = { · 822 unmodified lines | |||
| 823 | .ndo_open = cc770_open, | 823 | .ndo_open = cc770_open, |
| 824 | .ndo_stop = cc770_close, | 824 | .ndo_stop = cc770_close, |
| 825 | .ndo_start_xmit = cc770_start_xmit, | 825 | .ndo_start_xmit = cc770_start_xmit, |
| 826 | .ndo_change_mtu = can_change_mtu, | ||
| 826 | }; | 827 | }; |
| 827 | 828 | ||
| 828 | int register_cc770dev(struct net_device *dev) | 829 | int register_cc770dev(struct net_device *dev) |
| @@ -99,10 +99,10 @@ static int can_update_spt(const struct can_bittiming_const *btc, · 98 unmodified lines | |||
| 99 | return 1000 * (tseg + 1 - *tseg2) / (tseg + 1); | 99 | return 1000 * (tseg + 1 - *tseg2) / (tseg + 1); |
| 100 | } | 100 | } |
| 101 | 101 | ||
| 102 | static int can_calc_bittiming(struct net_device *dev, struct can_bittiming *bt) | 102 | static int can_calc_bittiming(struct net_device *dev, struct can_bittiming *bt, |
| 103 | const struct can_bittiming_const *btc) | ||
| 103 | { | 104 | { |
| 104 | struct can_priv *priv = netdev_priv(dev); | 105 | struct can_priv *priv = netdev_priv(dev); |
| 105 | const struct can_bittiming_const *btc = priv->bittiming_const; | ||
| 106 | long rate, best_rate = 0; | 106 | long rate, best_rate = 0; |
| 107 | long best_error = 1000000000, error = 0; | 107 | long best_error = 1000000000, error = 0; |
| 108 | int best_tseg = 0, best_brp = 0, brp = 0; | 108 | int best_tseg = 0, best_brp = 0, brp = 0; |
| @@ -110,9 +110,6 @@ static int can_calc_bittiming(struct net_device *dev, struct can_bittiming *bt) · 1 unmodified line | |||
| 110 | int spt_error = 1000, spt = 0, sampl_pt; | 110 | int spt_error = 1000, spt = 0, sampl_pt; |
| 111 | u64 v64; | 111 | u64 v64; |
| 112 | 112 | ||
| 113 | if (!priv->bittiming_const) | ||
| 114 | return -ENOTSUPP; | ||
| 115 | |||
| 116 | /* Use CIA recommended sample points */ | 113 | /* Use CIA recommended sample points */ |
| 117 | if (bt->sample_point) { | 114 | if (bt->sample_point) { |
| 118 | sampl_pt = bt->sample_point; | 115 | sampl_pt = bt->sample_point; |
| @@ -204,7 +201,8 @@ static int can_calc_bittiming(struct net_device *dev, struct can_bittiming *bt) · 85 unmodified lines | |||
| 204 | return 0; | 201 | return 0; |
| 205 | } | 202 | } |
| 206 | #else /* !CONFIG_CAN_CALC_BITTIMING */ | 203 | #else /* !CONFIG_CAN_CALC_BITTIMING */ |
| 207 | static int can_calc_bittiming(struct net_device *dev, struct can_bittiming *bt) | 204 | static int can_calc_bittiming(struct net_device *dev, struct can_bittiming *bt, |
| 205 | const struct can_bittiming_const *btc) | ||
| 208 | { | 206 | { |
| 209 | netdev_err(dev, "bit-timing calculation not available\n"); | 207 | netdev_err(dev, "bit-timing calculation not available\n"); |
| 210 | return -EINVAL; | 208 | return -EINVAL; |
| @@ -217,16 +215,13 @@ static int can_calc_bittiming(struct net_device *dev, struct can_bittiming *bt) · 6 unmodified lines | |||
| 217 | * prescaler value brp. You can find more information in the header | 215 | * prescaler value brp. You can find more information in the header |
| 218 | * file linux/can/netlink.h. | 216 | * file linux/can/netlink.h. |
| 219 | */ | 217 | */ |
| 220 | static int can_fixup_bittiming(struct net_device *dev, struct can_bittiming *bt) | 218 | static int can_fixup_bittiming(struct net_device *dev, struct can_bittiming *bt, |
| 219 | const struct can_bittiming_const *btc) | ||
| 221 | { | 220 | { |
| 222 | struct can_priv *priv = netdev_priv(dev); | 221 | struct can_priv *priv = netdev_priv(dev); |
| 223 | const struct can_bittiming_const *btc = priv->bittiming_const; | ||
| 224 | int tseg1, alltseg; | 222 | int tseg1, alltseg; |
| 225 | u64 brp64; | 223 | u64 brp64; |
| 226 | 224 | ||
| 227 | if (!priv->bittiming_const) | ||
| 228 | return -ENOTSUPP; | ||
| 229 | |||
| 230 | tseg1 = bt->prop_seg + bt->phase_seg1; | 225 | tseg1 = bt->prop_seg + bt->phase_seg1; |
| 231 | if (!bt->sjw) | 226 | if (!bt->sjw) |
| 232 | bt->sjw = 1; | 227 | bt->sjw = 1; |
| @@ -254,26 +249,29 @@ static int can_fixup_bittiming(struct net_device *dev, struct can_bittiming *bt) · 21 unmodified lines | |||
| 254 | return 0; | 249 | return 0; |
| 255 | } | 250 | } |
| 256 | 251 | ||
| 257 | static int can_get_bittiming(struct net_device *dev, struct can_bittiming *bt) | 252 | static int can_get_bittiming(struct net_device *dev, struct can_bittiming *bt, |
| 253 | const struct can_bittiming_const *btc) | ||
| 258 | { | 254 | { |
| 259 | struct can_priv *priv = netdev_priv(dev); | ||
| 260 | int err; | 255 | int err; |
| 261 | 256 | ||
| 262 | /* Check if the CAN device has bit-timing parameters */ | 257 | /* Check if the CAN device has bit-timing parameters */ |
| 263 | if (priv->bittiming_const) { | 258 | if (!btc) |
| 259 | return -ENOTSUPP; | ||
| 264 | 260 | ||
| 265 | /* Non-expert mode? Check if the bitrate has been pre-defined */ | 261 | /* |
| 266 | if (!bt->tq) | 262 | * Depending on the given can_bittiming parameter structure the CAN |
| 267 | /* Determine bit-timing parameters */ | 263 | * timing parameters are calculated based on the provided bitrate OR |
| 268 | err = can_calc_bittiming(dev, bt); | 264 | * alternatively the CAN timing parameters (tq, prop_seg, etc.) are |
| 269 | else | 265 | * provided directly which are then checked and fixed up. |
| 270 | /* Check bit-timing params and calculate proper brp */ | 266 | */ |
| 271 | err = can_fixup_bittiming(dev, bt); | 267 | if (!bt->tq && bt->bitrate) |
| 272 | if (err) | 268 | err = can_calc_bittiming(dev, bt, btc); |
| 273 | return err; | 269 | else if (bt->tq && !bt->bitrate) |
| 274 | } | 270 | err = can_fixup_bittiming(dev, bt, btc); |
| 271 | else | ||
| 272 | err = -EINVAL; | ||
| 275 | 273 | ||
| 276 | return 0; | 274 | return err; |
| 277 | } | 275 | } |
| 278 | 276 | ||
| 279 | /* | 277 | /* |
| @@ -317,7 +315,9 @@ void can_put_echo_skb(struct sk_buff *skb, struct net_device *dev, · 37 unmodified lines | |||
| 317 | BUG_ON(idx >= priv->echo_skb_max); | 315 | BUG_ON(idx >= priv->echo_skb_max); |
| 318 | 316 | ||
| 319 | /* check flag whether this packet has to be looped back */ | 317 | /* check flag whether this packet has to be looped back */ |
| 320 | if (!(dev->flags & IFF_ECHO) || skb->pkt_type != PACKET_LOOPBACK) { | 318 | if (!(dev->flags & IFF_ECHO) || skb->pkt_type != PACKET_LOOPBACK || |
| 319 | (skb->protocol != htons(ETH_P_CAN) && | ||
| 320 | skb->protocol != htons(ETH_P_CANFD))) { | ||
| 321 | kfree_skb(skb); | 321 | kfree_skb(skb); |
| 322 | return; | 322 | return; |
| 323 | } | 323 | } |
| @@ -329,7 +329,6 @@ void can_put_echo_skb(struct sk_buff *skb, struct net_device *dev, · 5 unmodified lines | |||
| 329 | return; | 329 | return; |
| 330 | 330 | ||
| 331 | /* make settings for echo to reduce code in irq context */ | 331 | /* make settings for echo to reduce code in irq context */ |
| 332 | skb->protocol = htons(ETH_P_CAN); | ||
| 333 | skb->pkt_type = PACKET_BROADCAST; | 332 | skb->pkt_type = PACKET_BROADCAST; |
| 334 | skb->ip_summed = CHECKSUM_UNNECESSARY; | 333 | skb->ip_summed = CHECKSUM_UNNECESSARY; |
| 335 | skb->dev = dev; | 334 | skb->dev = dev; |
| @@ -512,6 +511,30 @@ struct sk_buff *alloc_can_skb(struct net_device *dev, struct can_frame **cf) · 176 unmodified lines | |||
| 512 | } | 511 | } |
| 513 | EXPORT_SYMBOL_GPL(alloc_can_skb); | 512 | EXPORT_SYMBOL_GPL(alloc_can_skb); |
| 514 | 513 | ||
| 514 | struct sk_buff *alloc_canfd_skb(struct net_device *dev, | ||
| 515 | struct canfd_frame **cfd) | ||
| 516 | { | ||
| 517 | struct sk_buff *skb; | ||
| 518 | |||
| 519 | skb = netdev_alloc_skb(dev, sizeof(struct can_skb_priv) + | ||
| 520 | sizeof(struct canfd_frame)); | ||
| 521 | if (unlikely(!skb)) | ||
| 522 | return NULL; | ||
| 523 | |||
| 524 | skb->protocol = htons(ETH_P_CANFD); | ||
| 525 | skb->pkt_type = PACKET_BROADCAST; | ||
| 526 | skb->ip_summed = CHECKSUM_UNNECESSARY; | ||
| 527 | |||
| 528 | can_skb_reserve(skb); | ||
| 529 | can_skb_prv(skb)->ifindex = dev->ifindex; | ||
| 530 | |||
| 531 | *cfd = (struct canfd_frame *)skb_put(skb, sizeof(struct canfd_frame)); | ||
| 532 | memset(*cfd, 0, sizeof(struct canfd_frame)); | ||
| 533 | |||
| 534 | return skb; | ||
| 535 | } | ||
| 536 | EXPORT_SYMBOL_GPL(alloc_canfd_skb); | ||
| 537 | |||
| 515 | struct sk_buff *alloc_can_err_skb(struct net_device *dev, struct can_frame **cf) | 538 | struct sk_buff *alloc_can_err_skb(struct net_device *dev, struct can_frame **cf) |
| 516 | { | 539 | { |
| 517 | struct sk_buff *skb; | 540 | struct sk_buff *skb; |
| @@ -571,6 +594,39 @@ void free_candev(struct net_device *dev) · 53 unmodified lines | |||
| 571 | } | 594 | } |
| 572 | EXPORT_SYMBOL_GPL(free_candev); | 595 | EXPORT_SYMBOL_GPL(free_candev); |
| 573 | 596 | ||
| 597 | /* | ||
| 598 | * changing MTU and control mode for CAN/CANFD devices | ||
| 599 | */ | ||
| 600 | int can_change_mtu(struct net_device *dev, int new_mtu) | ||
| 601 | { | ||
| 602 | struct can_priv *priv = netdev_priv(dev); | ||
| 603 | |||
| 604 | /* Do not allow changing the MTU while running */ | ||
| 605 | if (dev->flags & IFF_UP) | ||
| 606 | return -EBUSY; | ||
| 607 | |||
| 608 | /* allow change of MTU according to the CANFD ability of the device */ | ||
| 609 | switch (new_mtu) { | ||
| 610 | case CAN_MTU: | ||
| 611 | priv->ctrlmode &= ~CAN_CTRLMODE_FD; | ||
| 612 | break; | ||
| 613 | |||
| 614 | case CANFD_MTU: | ||
| 615 | if (!(priv->ctrlmode_supported & CAN_CTRLMODE_FD)) | ||
| 616 | return -EINVAL; | ||
| 617 | |||
| 618 | priv->ctrlmode |= CAN_CTRLMODE_FD; | ||
| 619 | break; | ||
| 620 | |||
| 621 | default: | ||
| 622 | return -EINVAL; | ||
| 623 | } | ||
| 624 | |||
| 625 | dev->mtu = new_mtu; | ||
| 626 | return 0; | ||
| 627 | } | ||
| 628 | EXPORT_SYMBOL_GPL(can_change_mtu); | ||
| 629 | |||
| 574 | /* | 630 | /* |
| 575 | * Common open function when the device gets opened. | 631 | * Common open function when the device gets opened. |
| 576 | * | 632 | * |
| @@ -581,11 +637,19 @@ int open_candev(struct net_device *dev) · 4 unmodified lines | |||
| 581 | { | 637 | { |
| 582 | struct can_priv *priv = netdev_priv(dev); | 638 | struct can_priv *priv = netdev_priv(dev); |
| 583 | 639 | ||
| 584 | if (!priv->bittiming.tq && !priv->bittiming.bitrate) { | 640 | if (!priv->bittiming.bitrate) { |
| 585 | netdev_err(dev, "bit-timing not yet defined\n"); | 641 | netdev_err(dev, "bit-timing not yet defined\n"); |
| 586 | return -EINVAL; | 642 | return -EINVAL; |
| 587 | } | 643 | } |
| 588 | 644 | ||
| 645 | /* For CAN FD the data bitrate has to be >= the arbitration bitrate */ | ||
| 646 | if ((priv->ctrlmode & CAN_CTRLMODE_FD) && | ||
| 647 | (!priv->data_bittiming.bitrate || | ||
| 648 | (priv->data_bittiming.bitrate < priv->bittiming.bitrate))) { | ||
| 649 | netdev_err(dev, "incorrect/missing data bit-timing\n"); | ||
| 650 | return -EINVAL; | ||
| 651 | } | ||
| 652 | |||
| 589 | /* Switch carrier on if device was stopped while in bus-off state */ | 653 | /* Switch carrier on if device was stopped while in bus-off state */ |
| 590 | if (!netif_carrier_ok(dev)) | 654 | if (!netif_carrier_ok(dev)) |
| 591 | netif_carrier_on(dev); | 655 | netif_carrier_on(dev); |
| @@ -624,6 +688,10 @@ static const struct nla_policy can_policy[IFLA_CAN_MAX + 1] = { · 32 unmodified lines | |||
| 624 | = { .len = sizeof(struct can_bittiming_const) }, | 688 | = { .len = sizeof(struct can_bittiming_const) }, |
| 625 | [IFLA_CAN_CLOCK] = { .len = sizeof(struct can_clock) }, | 689 | [IFLA_CAN_CLOCK] = { .len = sizeof(struct can_clock) }, |
| 626 | [IFLA_CAN_BERR_COUNTER] = { .len = sizeof(struct can_berr_counter) }, | 690 | [IFLA_CAN_BERR_COUNTER] = { .len = sizeof(struct can_berr_counter) }, |
| 691 | [IFLA_CAN_DATA_BITTIMING] | ||
| 692 | = { .len = sizeof(struct can_bittiming) }, | ||
| 693 | [IFLA_CAN_DATA_BITTIMING_CONST] | ||
| 694 | = { .len = sizeof(struct can_bittiming_const) }, | ||
| 627 | }; | 695 | }; |
| 628 | 696 | ||
| 629 | static int can_changelink(struct net_device *dev, | 697 | static int can_changelink(struct net_device *dev, |
| @@ -642,9 +710,7 @@ static int can_changelink(struct net_device *dev, · 12 unmodified lines | |||
| 642 | if (dev->flags & IFF_UP) | 710 | if (dev->flags & IFF_UP) |
| 643 | return -EBUSY; | 711 | return -EBUSY; |
| 644 | memcpy(&bt, nla_data(data[IFLA_CAN_BITTIMING]), sizeof(bt)); | 712 | memcpy(&bt, nla_data(data[IFLA_CAN_BITTIMING]), sizeof(bt)); |
| 645 | if ((!bt.bitrate && !bt.tq) || (bt.bitrate && bt.tq)) | 713 | err = can_get_bittiming(dev, &bt, priv->bittiming_const); |
| 646 | return -EINVAL; | ||
| 647 | err = can_get_bittiming(dev, &bt); | ||
| 648 | if (err) | 714 | if (err) |
| 649 | return err; | 715 | return err; |
| 650 | memcpy(&priv->bittiming, &bt, sizeof(bt)); | 716 | memcpy(&priv->bittiming, &bt, sizeof(bt)); |
| @@ -668,6 +734,12 @@ static int can_changelink(struct net_device *dev, · 17 unmodified lines | |||
| 668 | return -EOPNOTSUPP; | 734 | return -EOPNOTSUPP; |
| 669 | priv->ctrlmode &= ~cm->mask; | 735 | priv->ctrlmode &= ~cm->mask; |
| 670 | priv->ctrlmode |= cm->flags; | 736 | priv->ctrlmode |= cm->flags; |
| 737 | |||
| 738 | /* CAN_CTRLMODE_FD can only be set when driver supports FD */ | ||
| 739 | if (priv->ctrlmode & CAN_CTRLMODE_FD) | ||
| 740 | dev->mtu = CANFD_MTU; | ||
| 741 | else | ||
| 742 | dev->mtu = CAN_MTU; | ||
| 671 | } | 743 | } |
| 672 | 744 | ||
| 673 | if (data[IFLA_CAN_RESTART_MS]) { | 745 | if (data[IFLA_CAN_RESTART_MS]) { |
| @@ -686,6 +758,27 @@ static int can_changelink(struct net_device *dev, · 12 unmodified lines | |||
| 686 | return err; | 758 | return err; |
| 687 | } | 759 | } |
| 688 | 760 | ||
| 761 | if (data[IFLA_CAN_DATA_BITTIMING]) { | ||
| 762 | struct can_bittiming dbt; | ||
| 763 | |||
| 764 | /* Do not allow changing bittiming while running */ | ||
| 765 | if (dev->flags & IFF_UP) | ||
| 766 | return -EBUSY; | ||
| 767 | memcpy(&dbt, nla_data(data[IFLA_CAN_DATA_BITTIMING]), | ||
| 768 | sizeof(dbt)); | ||
| 769 | err = can_get_bittiming(dev, &dbt, priv->data_bittiming_const); | ||
| 770 | if (err) | ||
| 771 | return err; | ||
| 772 | memcpy(&priv->data_bittiming, &dbt, sizeof(dbt)); | ||
| 773 | |||
| 774 | if (priv->do_set_data_bittiming) { | ||
| 775 | /* Finally, set the bit-timing registers */ | ||
| 776 | err = priv->do_set_data_bittiming(dev); | ||
| 777 | if (err) | ||
| 778 | return err; | ||
| 779 | } | ||
| 780 | } | ||
| 781 | |||
| 689 | return 0; | 782 | return 0; |
| 690 | } | 783 | } |
| 691 | 784 | ||
| @@ -694,7 +787,8 @@ static size_t can_get_size(const struct net_device *dev) · 2 unmodified lines | |||
| 694 | struct can_priv *priv = netdev_priv(dev); | 787 | struct can_priv *priv = netdev_priv(dev); |
| 695 | size_t size = 0; | 788 | size_t size = 0; |
| 696 | 789 | ||
| 697 | size += nla_total_size(sizeof(struct can_bittiming)); /* IFLA_CAN_BITTIMING */ | 790 | if (priv->bittiming.bitrate) /* IFLA_CAN_BITTIMING */ |
| 791 | size += nla_total_size(sizeof(struct can_bittiming)); | ||
| 698 | if (priv->bittiming_const) /* IFLA_CAN_BITTIMING_CONST */ | 792 | if (priv->bittiming_const) /* IFLA_CAN_BITTIMING_CONST */ |
| 699 | size += nla_total_size(sizeof(struct can_bittiming_const)); | 793 | size += nla_total_size(sizeof(struct can_bittiming_const)); |
| 700 | size += nla_total_size(sizeof(struct can_clock)); /* IFLA_CAN_CLOCK */ | 794 | size += nla_total_size(sizeof(struct can_clock)); /* IFLA_CAN_CLOCK */ |
| @@ -703,6 +797,10 @@ static size_t can_get_size(const struct net_device *dev) · 2 unmodified lines | |||
| 703 | size += nla_total_size(sizeof(u32)); /* IFLA_CAN_RESTART_MS */ | 797 | size += nla_total_size(sizeof(u32)); /* IFLA_CAN_RESTART_MS */ |
| 704 | if (priv->do_get_berr_counter) /* IFLA_CAN_BERR_COUNTER */ | 798 | if (priv->do_get_berr_counter) /* IFLA_CAN_BERR_COUNTER */ |
| 705 | size += nla_total_size(sizeof(struct can_berr_counter)); | 799 | size += nla_total_size(sizeof(struct can_berr_counter)); |
| 800 | if (priv->data_bittiming.bitrate) /* IFLA_CAN_DATA_BITTIMING */ | ||
| 801 | size += nla_total_size(sizeof(struct can_bittiming)); | ||
| 802 | if (priv->data_bittiming_const) /* IFLA_CAN_DATA_BITTIMING_CONST */ | ||
| 803 | size += nla_total_size(sizeof(struct can_bittiming_const)); | ||
| 706 | 804 | ||
| 707 | return size; | 805 | return size; |
| 708 | } | 806 | } |
| @@ -716,19 +814,34 @@ static int can_fill_info(struct sk_buff *skb, const struct net_device *dev) · 7 unmodified lines | |||
| 716 | 814 | ||
| 717 | if (priv->do_get_state) | 815 | if (priv->do_get_state) |
| 718 | priv->do_get_state(dev, &state); | 816 | priv->do_get_state(dev, &state); |
| 719 | if (nla_put(skb, IFLA_CAN_BITTIMING, | 817 | |
| 720 | sizeof(priv->bittiming), &priv->bittiming) || | 818 | if ((priv->bittiming.bitrate && |
| 819 | nla_put(skb, IFLA_CAN_BITTIMING, | ||
| 820 | sizeof(priv->bittiming), &priv->bittiming)) || | ||
| 821 | |||
| 721 | (priv->bittiming_const && | 822 | (priv->bittiming_const && |
| 722 | nla_put(skb, IFLA_CAN_BITTIMING_CONST, | 823 | nla_put(skb, IFLA_CAN_BITTIMING_CONST, |
| 723 | sizeof(*priv->bittiming_const), priv->bittiming_const)) || | 824 | sizeof(*priv->bittiming_const), priv->bittiming_const)) || |
| 825 | |||
| 724 | nla_put(skb, IFLA_CAN_CLOCK, sizeof(cm), &priv->clock) || | 826 | nla_put(skb, IFLA_CAN_CLOCK, sizeof(cm), &priv->clock) || |
| 725 | nla_put_u32(skb, IFLA_CAN_STATE, state) || | 827 | nla_put_u32(skb, IFLA_CAN_STATE, state) || |
| 726 | nla_put(skb, IFLA_CAN_CTRLMODE, sizeof(cm), &cm) || | 828 | nla_put(skb, IFLA_CAN_CTRLMODE, sizeof(cm), &cm) || |
| 727 | nla_put_u32(skb, IFLA_CAN_RESTART_MS, priv->restart_ms) || | 829 | nla_put_u32(skb, IFLA_CAN_RESTART_MS, priv->restart_ms) || |
| 830 | |||
| 728 | (priv->do_get_berr_counter && | 831 | (priv->do_get_berr_counter && |
| 729 | !priv->do_get_berr_counter(dev, &bec) && | 832 | !priv->do_get_berr_counter(dev, &bec) && |
| 730 | nla_put(skb, IFLA_CAN_BERR_COUNTER, sizeof(bec), &bec))) | 833 | nla_put(skb, IFLA_CAN_BERR_COUNTER, sizeof(bec), &bec)) || |
| 834 | |||
| 835 | (priv->data_bittiming.bitrate && | ||
| 836 | nla_put(skb, IFLA_CAN_DATA_BITTIMING, | ||
| 837 | sizeof(priv->data_bittiming), &priv->data_bittiming)) || | ||
| 838 | |||
| 839 | (priv->data_bittiming_const && | ||
| 840 | nla_put(skb, IFLA_CAN_DATA_BITTIMING_CONST, | ||
| 841 | sizeof(*priv->data_bittiming_const), | ||
| 842 | priv->data_bittiming_const))) | ||
| 731 | return -EMSGSIZE; | 843 | return -EMSGSIZE; |
| 844 | |||
| 732 | return 0; | 845 | return 0; |
| 733 | } | 846 | } |
| 734 | 847 | ||
| @@ -1011,6 +1011,7 @@ static const struct net_device_ops flexcan_netdev_ops = { · 1010 unmodified lines | |||
| 1011 | .ndo_open = flexcan_open, | 1011 | .ndo_open = flexcan_open, |
| 1012 | .ndo_stop = flexcan_close, | 1012 | .ndo_stop = flexcan_close, |
| 1013 | .ndo_start_xmit = flexcan_start_xmit, | 1013 | .ndo_start_xmit = flexcan_start_xmit, |
| 1014 | .ndo_change_mtu = can_change_mtu, | ||
| 1014 | }; | 1015 | }; |
| 1015 | 1016 | ||
| 1016 | static int register_flexcandev(struct net_device *dev) | 1017 | static int register_flexcandev(struct net_device *dev) |
| @@ -1132,9 +1133,9 @@ static int flexcan_probe(struct platform_device *pdev) · 115 unmodified lines | |||
| 1132 | of_id = of_match_device(flexcan_of_match, &pdev->dev); | 1133 | of_id = of_match_device(flexcan_of_match, &pdev->dev); |
| 1133 | if (of_id) { | 1134 | if (of_id) { |
| 1134 | devtype_data = of_id->data; | 1135 | devtype_data = of_id->data; |
| 1135 | } else if (pdev->id_entry->driver_data) { | 1136 | } else if (platform_get_device_id(pdev)->driver_data) { |
| 1136 | devtype_data = (struct flexcan_devtype_data *) | 1137 | devtype_data = (struct flexcan_devtype_data *) |
| 1137 | pdev->id_entry->driver_data; | 1138 | platform_get_device_id(pdev)->driver_data; |
| 1138 | } else { | 1139 | } else { |
| 1139 | return -ENODEV; | 1140 | return -ENODEV; |
| 1140 | } | 1141 | } |
| @@ -1201,8 +1202,7 @@ static int flexcan_remove(struct platform_device *pdev) · 60 unmodified lines | |||
| 1201 | return 0; | 1202 | return 0; |
| 1202 | } | 1203 | } |
| 1203 | 1204 | ||
| 1204 | #ifdef CONFIG_PM_SLEEP | 1205 | static int __maybe_unused flexcan_suspend(struct device *device) |
| 1205 | static int flexcan_suspend(struct device *device) | ||
| 1206 | { | 1206 | { |
| 1207 | struct net_device *dev = dev_get_drvdata(device); | 1207 | struct net_device *dev = dev_get_drvdata(device); |
| 1208 | struct flexcan_priv *priv = netdev_priv(dev); | 1208 | struct flexcan_priv *priv = netdev_priv(dev); |
| @@ -1221,7 +1221,7 @@ static int flexcan_suspend(struct device *device) · 12 unmodified lines | |||
| 1221 | return 0; | 1221 | return 0; |
| 1222 | } | 1222 | } |
| 1223 | 1223 | ||
| 1224 | static int flexcan_resume(struct device *device) | 1224 | static int __maybe_unused flexcan_resume(struct device *device) |
| 1225 | { | 1225 | { |
| 1226 | struct net_device *dev = dev_get_drvdata(device); | 1226 | struct net_device *dev = dev_get_drvdata(device); |
| 1227 | struct flexcan_priv *priv = netdev_priv(dev); | 1227 | struct flexcan_priv *priv = netdev_priv(dev); |
| @@ -1233,7 +1233,6 @@ static int flexcan_resume(struct device *device) · 5 unmodified lines | |||
| 1233 | } | 1233 | } |
| 1234 | return flexcan_chip_enable(priv); | 1234 | return flexcan_chip_enable(priv); |
| 1235 | } | 1235 | } |
| 1236 | #endif /* CONFIG_PM_SLEEP */ | ||
| 1237 | 1236 | ||
| 1238 | static SIMPLE_DEV_PM_OPS(flexcan_pm_ops, flexcan_suspend, flexcan_resume); | 1237 | static SIMPLE_DEV_PM_OPS(flexcan_pm_ops, flexcan_suspend, flexcan_resume); |
| 1239 | 1238 | ||
| @@ -1578,6 +1578,7 @@ static const struct net_device_ops grcan_netdev_ops = { · 1577 unmodified lines | |||
| 1578 | .ndo_open = grcan_open, | 1578 | .ndo_open = grcan_open, |
| 1579 | .ndo_stop = grcan_close, | 1579 | .ndo_stop = grcan_close, |
| 1580 | .ndo_start_xmit = grcan_start_xmit, | 1580 | .ndo_start_xmit = grcan_start_xmit, |
| 1581 | .ndo_change_mtu = can_change_mtu, | ||
| 1581 | }; | 1582 | }; |
| 1582 | 1583 | ||
| 1583 | static int grcan_setup_netdev(struct platform_device *ofdev, | 1584 | static int grcan_setup_netdev(struct platform_device *ofdev, |
| @@ -198,9 +198,6 @@ struct ican3_dev { · 197 unmodified lines | |||
| 198 | struct net_device *ndev; | 198 | struct net_device *ndev; |
| 199 | struct napi_struct napi; | 199 | struct napi_struct napi; |
| 200 | 200 | ||
| 201 | /* Device for printing */ | ||
| 202 | struct device *dev; | ||
| 203 | |||
| 204 | /* module number */ | 201 | /* module number */ |
| 205 | unsigned int num; | 202 | unsigned int num; |
| 206 | 203 | ||
| @@ -295,7 +292,7 @@ static int ican3_old_recv_msg(struct ican3_dev *mod, struct ican3_msg *msg) · 88 unmodified lines | |||
| 295 | xord = locl ^ peer; | 292 | xord = locl ^ peer; |
| 296 | 293 | ||
| 297 | if ((xord & MSYNC_RB_MASK) == 0x00) { | 294 | if ((xord & MSYNC_RB_MASK) == 0x00) { |
| 298 | dev_dbg(mod->dev, "no mbox for reading\n"); | 295 | netdev_dbg(mod->ndev, "no mbox for reading\n"); |
| 299 | return -ENOMEM; | 296 | return -ENOMEM; |
| 300 | } | 297 | } |
| 301 | 298 | ||
| @@ -340,7 +337,7 @@ static int ican3_old_send_msg(struct ican3_dev *mod, struct ican3_msg *msg) · 38 unmodified lines | |||
| 340 | xord = locl ^ peer; | 337 | xord = locl ^ peer; |
| 341 | 338 | ||
| 342 | if ((xord & MSYNC_WB_MASK) == MSYNC_WB_MASK) { | 339 | if ((xord & MSYNC_WB_MASK) == MSYNC_WB_MASK) { |
| 343 | dev_err(mod->dev, "no mbox for writing\n"); | 340 | netdev_err(mod->ndev, "no mbox for writing\n"); |
| 344 | return -ENOMEM; | 341 | return -ENOMEM; |
| 345 | } | 342 | } |
| 346 | 343 | ||
| @@ -542,7 +539,7 @@ static int ican3_new_send_msg(struct ican3_dev *mod, struct ican3_msg *msg) · 195 unmodified lines | |||
| 542 | memcpy_fromio(&desc, desc_addr, sizeof(desc)); | 539 | memcpy_fromio(&desc, desc_addr, sizeof(desc)); |
| 543 | 540 | ||
| 544 | if (!(desc.control & DESC_VALID)) { | 541 | if (!(desc.control & DESC_VALID)) { |
| 545 | dev_dbg(mod->dev, "%s: no free buffers\n", __func__); | 542 | netdev_dbg(mod->ndev, "%s: no free buffers\n", __func__); |
| 546 | return -ENOMEM; | 543 | return -ENOMEM; |
| 547 | } | 544 | } |
| 548 | 545 | ||
| @@ -573,7 +570,7 @@ static int ican3_new_recv_msg(struct ican3_dev *mod, struct ican3_msg *msg) · 24 unmodified lines | |||
| 573 | memcpy_fromio(&desc, desc_addr, sizeof(desc)); | 570 | memcpy_fromio(&desc, desc_addr, sizeof(desc)); |
| 574 | 571 | ||
| 575 | if (!(desc.control & DESC_VALID)) { | 572 | if (!(desc.control & DESC_VALID)) { |
| 576 | dev_dbg(mod->dev, "%s: no buffers to recv\n", __func__); | 573 | netdev_dbg(mod->ndev, "%s: no buffers to recv\n", __func__); |
| 577 | return -ENOMEM; | 574 | return -ENOMEM; |
| 578 | } | 575 | } |
| 579 | 576 | ||
| @@ -883,7 +880,7 @@ static void can_frame_to_ican3(struct ican3_dev *mod, · 303 unmodified lines | |||
| 883 | */ | 880 | */ |
| 884 | static void ican3_handle_idvers(struct ican3_dev *mod, struct ican3_msg *msg) | 881 | static void ican3_handle_idvers(struct ican3_dev *mod, struct ican3_msg *msg) |
| 885 | { | 882 | { |
| 886 | dev_dbg(mod->dev, "IDVERS response: %s\n", msg->data); | 883 | netdev_dbg(mod->ndev, "IDVERS response: %s\n", msg->data); |
| 887 | } | 884 | } |
| 888 | 885 | ||
| 889 | static void ican3_handle_msglost(struct ican3_dev *mod, struct ican3_msg *msg) | 886 | static void ican3_handle_msglost(struct ican3_dev *mod, struct ican3_msg *msg) |
| @@ -899,7 +896,7 @@ static void ican3_handle_msglost(struct ican3_dev *mod, struct ican3_msg *msg) · 9 unmodified lines | |||
| 899 | * error frame for userspace | 896 | * error frame for userspace |
| 900 | */ | 897 | */ |
| 901 | if (msg->spec == MSG_MSGLOST) { | 898 | if (msg->spec == MSG_MSGLOST) { |
| 902 | dev_err(mod->dev, "lost %d control messages\n", msg->data[0]); | 899 | netdev_err(mod->ndev, "lost %d control messages\n", msg->data[0]); |
| 903 | return; | 900 | return; |
| 904 | } | 901 | } |
| 905 | 902 | ||
| @@ -939,13 +936,13 @@ static int ican3_handle_cevtind(struct ican3_dev *mod, struct ican3_msg *msg) · 33 unmodified lines | |||
| 939 | 936 | ||
| 940 | /* we can only handle the SJA1000 part */ | 937 | /* we can only handle the SJA1000 part */ |
| 941 | if (msg->data[1] != CEVTIND_CHIP_SJA1000) { | 938 | if (msg->data[1] != CEVTIND_CHIP_SJA1000) { |
| 942 | dev_err(mod->dev, "unable to handle errors on non-SJA1000\n"); | 939 | netdev_err(mod->ndev, "unable to handle errors on non-SJA1000\n"); |
| 943 | return -ENODEV; | 940 | return -ENODEV; |
| 944 | } | 941 | } |
| 945 | 942 | ||
| 946 | /* check the message length for sanity */ | 943 | /* check the message length for sanity */ |
| 947 | if (le16_to_cpu(msg->len) < 6) { | 944 | if (le16_to_cpu(msg->len) < 6) { |
| 948 | dev_err(mod->dev, "error message too short\n"); | 945 | netdev_err(mod->ndev, "error message too short\n"); |
| 949 | return -EINVAL; | 946 | return -EINVAL; |
| 950 | } | 947 | } |
| 951 | 948 | ||
| @@ -967,7 +964,7 @@ static int ican3_handle_cevtind(struct ican3_dev *mod, struct ican3_msg *msg) · 15 unmodified lines | |||
| 967 | */ | 964 | */ |
| 968 | if (isrc == CEVTIND_BEI) { | 965 | if (isrc == CEVTIND_BEI) { |
| 969 | int ret; | 966 | int ret; |
| 970 | dev_dbg(mod->dev, "bus error interrupt\n"); | 967 | netdev_dbg(mod->ndev, "bus error interrupt\n"); |
| 971 | 968 | ||
| 972 | /* TX error */ | 969 | /* TX error */ |
| 973 | if (!(ecc & ECC_DIR)) { | 970 | if (!(ecc & ECC_DIR)) { |
| @@ -983,7 +980,7 @@ static int ican3_handle_cevtind(struct ican3_dev *mod, struct ican3_msg *msg) · 9 unmodified lines | |||
| 983 | */ | 980 | */ |
| 984 | ret = ican3_set_buserror(mod, 1); | 981 | ret = ican3_set_buserror(mod, 1); |
| 985 | if (ret) { | 982 | if (ret) { |
| 986 | dev_err(mod->dev, "unable to re-enable bus-error\n"); | 983 | netdev_err(mod->ndev, "unable to re-enable bus-error\n"); |
| 987 | return ret; | 984 | return ret; |
| 988 | } | 985 | } |
| 989 | 986 | ||
| @@ -998,7 +995,7 @@ static int ican3_handle_cevtind(struct ican3_dev *mod, struct ican3_msg *msg) · 8 unmodified lines | |||
| 998 | 995 | ||
| 999 | /* data overrun interrupt */ | 996 | /* data overrun interrupt */ |
| 1000 | if (isrc == CEVTIND_DOI || isrc == CEVTIND_LOST) { | 997 | if (isrc == CEVTIND_DOI || isrc == CEVTIND_LOST) { |
| 1001 | dev_dbg(mod->dev, "data overrun interrupt\n"); | 998 | netdev_dbg(mod->ndev, "data overrun interrupt\n"); |
| 1002 | cf->can_id |= CAN_ERR_CRTL; | 999 | cf->can_id |= CAN_ERR_CRTL; |
| 1003 | cf->data[1] = CAN_ERR_CRTL_RX_OVERFLOW; | 1000 | cf->data[1] = CAN_ERR_CRTL_RX_OVERFLOW; |
| 1004 | stats->rx_over_errors++; | 1001 | stats->rx_over_errors++; |
| @@ -1007,7 +1004,7 @@ static int ican3_handle_cevtind(struct ican3_dev *mod, struct ican3_msg *msg) · 2 unmodified lines | |||
| 1007 | 1004 | ||
| 1008 | /* error warning + passive interrupt */ | 1005 | /* error warning + passive interrupt */ |
| 1009 | if (isrc == CEVTIND_EI) { | 1006 | if (isrc == CEVTIND_EI) { |
| 1010 | dev_dbg(mod->dev, "error warning + passive interrupt\n"); | 1007 | netdev_dbg(mod->ndev, "error warning + passive interrupt\n"); |
| 1011 | if (status & SR_BS) { | 1008 | if (status & SR_BS) { |
| 1012 | state = CAN_STATE_BUS_OFF; | 1009 | state = CAN_STATE_BUS_OFF; |
| 1013 | cf->can_id |= CAN_ERR_BUSOFF; | 1010 | cf->can_id |= CAN_ERR_BUSOFF; |
| @@ -1088,7 +1085,7 @@ static void ican3_handle_inquiry(struct ican3_dev *mod, struct ican3_msg *msg) · 74 unmodified lines | |||
| 1088 | complete(&mod->termination_comp); | 1085 | complete(&mod->termination_comp); |
| 1089 | break; | 1086 | break; |
| 1090 | default: | 1087 | default: |
| 1091 | dev_err(mod->dev, "received an unknown inquiry response\n"); | 1088 | netdev_err(mod->ndev, "received an unknown inquiry response\n"); |
| 1092 | break; | 1089 | break; |
| 1093 | } | 1090 | } |
| 1094 | } | 1091 | } |
| @@ -1096,7 +1093,7 @@ static void ican3_handle_inquiry(struct ican3_dev *mod, struct ican3_msg *msg) · 1 unmodified line | |||
| 1096 | static void ican3_handle_unknown_message(struct ican3_dev *mod, | 1093 | static void ican3_handle_unknown_message(struct ican3_dev *mod, |
| 1097 | struct ican3_msg *msg) | 1094 | struct ican3_msg *msg) |
| 1098 | { | 1095 | { |
| 1099 | dev_warn(mod->dev, "received unknown message: spec 0x%.2x length %d\n", | 1096 | netdev_warn(mod->ndev, "received unknown message: spec 0x%.2x length %d\n", |
| 1100 | msg->spec, le16_to_cpu(msg->len)); | 1097 | msg->spec, le16_to_cpu(msg->len)); |
| 1101 | } | 1098 | } |
| 1102 | 1099 | ||
| @@ -1105,7 +1102,7 @@ static void ican3_handle_unknown_message(struct ican3_dev *mod, · 2 unmodified lines | |||
| 1105 | */ | 1102 | */ |
| 1106 | static void ican3_handle_message(struct ican3_dev *mod, struct ican3_msg *msg) | 1103 | static void ican3_handle_message(struct ican3_dev *mod, struct ican3_msg *msg) |
| 1107 | { | 1104 | { |
| 1108 | dev_dbg(mod->dev, "%s: modno %d spec 0x%.2x len %d bytes\n", __func__, | 1105 | netdev_dbg(mod->ndev, "%s: modno %d spec 0x%.2x len %d bytes\n", __func__, |
| 1109 | mod->num, msg->spec, le16_to_cpu(msg->len)); | 1106 | mod->num, msg->spec, le16_to_cpu(msg->len)); |
| 1110 | 1107 | ||
| 1111 | switch (msg->spec) { | 1108 | switch (msg->spec) { |
| @@ -1406,7 +1403,7 @@ static int ican3_reset_module(struct ican3_dev *mod) · 294 unmodified lines | |||
| 1406 | msleep(10); | 1403 | msleep(10); |
| 1407 | } while (time_before(jiffies, start + HZ / 4)); | 1404 | } while (time_before(jiffies, start + HZ / 4)); |
| 1408 | 1405 | ||
| 1409 | dev_err(mod->dev, "failed to reset CAN module\n"); | 1406 | netdev_err(mod->ndev, "failed to reset CAN module\n"); |
| 1410 | return -ETIMEDOUT; | 1407 | return -ETIMEDOUT; |
| 1411 | } | 1408 | } |
| 1412 | 1409 | ||
| @@ -1425,7 +1422,7 @@ static int ican3_startup_module(struct ican3_dev *mod) · 12 unmodified lines | |||
| 1425 | 1422 | ||
| 1426 | ret = ican3_reset_module(mod); | 1423 | ret = ican3_reset_module(mod); |
| 1427 | if (ret) { | 1424 | if (ret) { |
| 1428 | dev_err(mod->dev, "unable to reset module\n"); | 1425 | netdev_err(mod->ndev, "unable to reset module\n"); |
| 1429 | return ret; | 1426 | return ret; |
| 1430 | } | 1427 | } |
| 1431 | 1428 | ||
| @@ -1434,41 +1431,41 @@ static int ican3_startup_module(struct ican3_dev *mod) · 2 unmodified lines | |||
| 1434 | 1431 | ||
| 1435 | ret = ican3_msg_connect(mod); | 1432 | ret = ican3_msg_connect(mod); |
| 1436 | if (ret) { | 1433 | if (ret) { |
| 1437 | dev_err(mod->dev, "unable to connect to module\n"); | 1434 | netdev_err(mod->ndev, "unable to connect to module\n"); |
| 1438 | return ret; | 1435 | return ret; |
| 1439 | } | 1436 | } |
| 1440 | 1437 | ||
| 1441 | ican3_init_new_host_interface(mod); | 1438 | ican3_init_new_host_interface(mod); |
| 1442 | ret = ican3_msg_newhostif(mod); | 1439 | ret = ican3_msg_newhostif(mod); |
| 1443 | if (ret) { | 1440 | if (ret) { |
| 1444 | dev_err(mod->dev, "unable to switch to new-style interface\n"); | 1441 | netdev_err(mod->ndev, "unable to switch to new-style interface\n"); |
| 1445 | return ret; | 1442 | return ret; |
| 1446 | } | 1443 | } |
| 1447 | 1444 | ||
| 1448 | /* default to "termination on" */ | 1445 | /* default to "termination on" */ |
| 1449 | ret = ican3_set_termination(mod, true); | 1446 | ret = ican3_set_termination(mod, true); |
| 1450 | if (ret) { | 1447 | if (ret) { |
| 1451 | dev_err(mod->dev, "unable to enable termination\n"); | 1448 | netdev_err(mod->ndev, "unable to enable termination\n"); |
| 1452 | return ret; | 1449 | return ret; |
| 1453 | } | 1450 | } |
| 1454 | 1451 | ||
| 1455 | /* default to "bus errors enabled" */ | 1452 | /* default to "bus errors enabled" */ |
| 1456 | ret = ican3_set_buserror(mod, 1); | 1453 | ret = ican3_set_buserror(mod, 1); |
| 1457 | if (ret) { | 1454 | if (ret) { |
| 1458 | dev_err(mod->dev, "unable to set bus-error\n"); | 1455 | netdev_err(mod->ndev, "unable to set bus-error\n"); |
| 1459 | return ret; | 1456 | return ret; |
| 1460 | } | 1457 | } |
| 1461 | 1458 | ||
| 1462 | ican3_init_fast_host_interface(mod); | 1459 | ican3_init_fast_host_interface(mod); |
| 1463 | ret = ican3_msg_fasthostif(mod); | 1460 | ret = ican3_msg_fasthostif(mod); |
| 1464 | if (ret) { | 1461 | if (ret) { |
| 1465 | dev_err(mod->dev, "unable to switch to fast host interface\n"); | 1462 | netdev_err(mod->ndev, "unable to switch to fast host interface\n"); |
| 1466 | return ret; | 1463 | return ret; |
| 1467 | } | 1464 | } |
| 1468 | 1465 | ||
| 1469 | ret = ican3_set_id_filter(mod, true); | 1466 | ret = ican3_set_id_filter(mod, true); |
| 1470 | if (ret) { | 1467 | if (ret) { |
| 1471 | dev_err(mod->dev, "unable to set acceptance filter\n"); | 1468 | netdev_err(mod->ndev, "unable to set acceptance filter\n"); |
| 1472 | return ret; | 1469 | return ret; |
| 1473 | } | 1470 | } |
| 1474 | 1471 | ||
| @@ -1487,14 +1484,14 @@ static int ican3_open(struct net_device *ndev) · 12 unmodified lines | |||
| 1487 | /* open the CAN layer */ | 1484 | /* open the CAN layer */ |
| 1488 | ret = open_candev(ndev); | 1485 | ret = open_candev(ndev); |
| 1489 | if (ret) { | 1486 | if (ret) { |
| 1490 | dev_err(mod->dev, "unable to start CAN layer\n"); | 1487 | netdev_err(mod->ndev, "unable to start CAN layer\n"); |
| 1491 | return ret; | 1488 | return ret; |
| 1492 | } | 1489 | } |
| 1493 | 1490 | ||
| 1494 | /* bring the bus online */ | 1491 | /* bring the bus online */ |
| 1495 | ret = ican3_set_bus_state(mod, true); | 1492 | ret = ican3_set_bus_state(mod, true); |
| 1496 | if (ret) { | 1493 | if (ret) { |
| 1497 | dev_err(mod->dev, "unable to set bus-on\n"); | 1494 | netdev_err(mod->ndev, "unable to set bus-on\n"); |
| 1498 | close_candev(ndev); | 1495 | close_candev(ndev); |
| 1499 | return ret; | 1496 | return ret; |
| 1500 | } | 1497 | } |
| @@ -1518,7 +1515,7 @@ static int ican3_stop(struct net_device *ndev) · 17 unmodified lines | |||
| 1518 | /* bring the bus offline, stop receiving packets */ | 1515 | /* bring the bus offline, stop receiving packets */ |
| 1519 | ret = ican3_set_bus_state(mod, false); | 1516 | ret = ican3_set_bus_state(mod, false); |
| 1520 | if (ret) { | 1517 | if (ret) { |
| 1521 | dev_err(mod->dev, "unable to set bus-off\n"); | 1518 | netdev_err(mod->ndev, "unable to set bus-off\n"); |
| 1522 | return ret; | 1519 | return ret; |
| 1523 | } | 1520 | } |
| 1524 | 1521 | ||
| @@ -1545,7 +1542,7 @@ static int ican3_xmit(struct sk_buff *skb, struct net_device *ndev) · 20 unmodified lines | |||
| 1545 | 1542 | ||
| 1546 | /* check that we can actually transmit */ | 1543 | /* check that we can actually transmit */ |
| 1547 | if (!ican3_txok(mod)) { | 1544 | if (!ican3_txok(mod)) { |
| 1548 | dev_err(mod->dev, "BUG: no free descriptors\n"); | 1545 | netdev_err(mod->ndev, "BUG: no free descriptors\n"); |
| 1549 | spin_unlock_irqrestore(&mod->lock, flags); | 1546 | spin_unlock_irqrestore(&mod->lock, flags); |
| 1550 | return NETDEV_TX_BUSY; | 1547 | return NETDEV_TX_BUSY; |
| 1551 | } | 1548 | } |
| @@ -1597,6 +1594,7 @@ static const struct net_device_ops ican3_netdev_ops = { · 45 unmodified lines | |||
| 1597 | .ndo_open = ican3_open, | 1594 | .ndo_open = ican3_open, |
| 1598 | .ndo_stop = ican3_stop, | 1595 | .ndo_stop = ican3_stop, |
| 1599 | .ndo_start_xmit = ican3_xmit, | 1596 | .ndo_start_xmit = ican3_xmit, |
| 1597 | .ndo_change_mtu = can_change_mtu, | ||
| 1600 | }; | 1598 | }; |
| 1601 | 1599 | ||
| 1602 | /* | 1600 | /* |
| @@ -1657,7 +1655,7 @@ static int ican3_set_mode(struct net_device *ndev, enum can_mode mode) · 54 unmodified lines | |||
| 1657 | /* bring the bus online */ | 1655 | /* bring the bus online */ |
| 1658 | ret = ican3_set_bus_state(mod, true); | 1656 | ret = ican3_set_bus_state(mod, true); |
| 1659 | if (ret) { | 1657 | if (ret) { |
| 1660 | dev_err(mod->dev, "unable to set bus-on\n"); | 1658 | netdev_err(ndev, "unable to set bus-on\n"); |
| 1661 | return ret; | 1659 | return ret; |
| 1662 | } | 1660 | } |
| 1663 | 1661 | ||
| @@ -1682,7 +1680,7 @@ static int ican3_get_berr_counter(const struct net_device *ndev, · 18 unmodified lines | |||
| 1682 | 1680 | ||
| 1683 | ret = wait_for_completion_timeout(&mod->buserror_comp, HZ); | 1681 | ret = wait_for_completion_timeout(&mod->buserror_comp, HZ); |
| 1684 | if (ret == 0) { | 1682 | if (ret == 0) { |
| 1685 | dev_info(mod->dev, "%s timed out\n", __func__); | 1683 | netdev_info(mod->ndev, "%s timed out\n", __func__); |
| 1686 | return -ETIMEDOUT; | 1684 | return -ETIMEDOUT; |
| 1687 | } | 1685 | } |
| 1688 | 1686 | ||
| @@ -1708,7 +1706,7 @@ static ssize_t ican3_sysfs_show_term(struct device *dev, · 19 unmodified lines | |||
| 1708 | 1706 | ||
| 1709 | ret = wait_for_completion_timeout(&mod->termination_comp, HZ); | 1707 | ret = wait_for_completion_timeout(&mod->termination_comp, HZ); |
| 1710 | if (ret == 0) { | 1708 | if (ret == 0) { |
| 1711 | dev_info(mod->dev, "%s timed out\n", __func__); | 1709 | netdev_info(mod->ndev, "%s timed out\n", __func__); |
| 1712 | return -ETIMEDOUT; | 1710 | return -ETIMEDOUT; |
| 1713 | } | 1711 | } |
| 1714 | 1712 | ||
| @@ -1778,7 +1776,6 @@ static int ican3_probe(struct platform_device *pdev) · 63 unmodified lines | |||
| 1778 | platform_set_drvdata(pdev, ndev); | 1776 | platform_set_drvdata(pdev, ndev); |
| 1779 | mod = netdev_priv(ndev); | 1777 | mod = netdev_priv(ndev); |
| 1780 | mod->ndev = ndev; | 1778 | mod->ndev = ndev; |
| 1781 | mod->dev = &pdev->dev; | ||
| 1782 | mod->num = pdata->modno; | 1779 | mod->num = pdata->modno; |
| 1783 | netif_napi_add(ndev, &mod->napi, ican3_napi, ICAN3_RX_BUFFERS); | 1780 | netif_napi_add(ndev, &mod->napi, ican3_napi, ICAN3_RX_BUFFERS); |
| 1784 | skb_queue_head_init(&mod->echoq); | 1781 | skb_queue_head_init(&mod->echoq); |
| @@ -601,10 +601,10 @@ static int mcp251x_do_set_bittiming(struct net_device *net) · 600 unmodified lines | |||
| 601 | (bt->prop_seg - 1)); | 601 | (bt->prop_seg - 1)); |
| 602 | mcp251x_write_bits(spi, CNF3, CNF3_PHSEG2_MASK, | 602 | mcp251x_write_bits(spi, CNF3, CNF3_PHSEG2_MASK, |
| 603 | (bt->phase_seg2 - 1)); | 603 | (bt->phase_seg2 - 1)); |
| 604 | dev_info(&spi->dev, "CNF: 0x%02x 0x%02x 0x%02x\n", | 604 | dev_dbg(&spi->dev, "CNF: 0x%02x 0x%02x 0x%02x\n", |
| 605 | mcp251x_read_reg(spi, CNF1), | 605 | mcp251x_read_reg(spi, CNF1), |
| 606 | mcp251x_read_reg(spi, CNF2), | 606 | mcp251x_read_reg(spi, CNF2), |
| 607 | mcp251x_read_reg(spi, CNF3)); | 607 | mcp251x_read_reg(spi, CNF3)); |
| 608 | 608 | ||
| 609 | return 0; | 609 | return 0; |
| 610 | } | 610 | } |
| @@ -672,7 +672,7 @@ static int mcp251x_hw_probe(struct spi_device *spi) · 61 unmodified lines | |||
| 672 | 672 | ||
| 673 | static int mcp251x_power_enable(struct regulator *reg, int enable) | 673 | static int mcp251x_power_enable(struct regulator *reg, int enable) |
| 674 | { | 674 | { |
| 675 | if (IS_ERR(reg)) | 675 | if (IS_ERR_OR_NULL(reg)) |
| 676 | return 0; | 676 | return 0; |
| 677 | 677 | ||
| 678 | if (enable) | 678 | if (enable) |
| @@ -996,6 +996,7 @@ static const struct net_device_ops mcp251x_netdev_ops = { · 317 unmodified lines | |||
| 996 | .ndo_open = mcp251x_open, | 996 | .ndo_open = mcp251x_open, |
| 997 | .ndo_stop = mcp251x_stop, | 997 | .ndo_stop = mcp251x_stop, |
| 998 | .ndo_start_xmit = mcp251x_hard_start_xmit, | 998 | .ndo_start_xmit = mcp251x_hard_start_xmit, |
| 999 | .ndo_change_mtu = can_change_mtu, | ||
| 999 | }; | 1000 | }; |
| 1000 | 1001 | ||
| 1001 | static const struct of_device_id mcp251x_of_match[] = { | 1002 | static const struct of_device_id mcp251x_of_match[] = { |
| @@ -1155,8 +1156,6 @@ static int mcp251x_can_probe(struct spi_device *spi) · 153 unmodified lines | |||
| 1155 | 1156 | ||
| 1156 | devm_can_led_init(net); | 1157 | devm_can_led_init(net); |
| 1157 | 1158 | ||
| 1158 | dev_info(&spi->dev, "probed\n"); | ||
| 1159 | |||
| 1160 | return ret; | 1159 | return ret; |
| 1161 | 1160 | ||
| 1162 | error_probe: | 1161 | error_probe: |
| @@ -1197,9 +1196,7 @@ static int mcp251x_can_remove(struct spi_device *spi) · 34 unmodified lines | |||
| 1197 | return 0; | 1196 | return 0; |
| 1198 | } | 1197 | } |
| 1199 | 1198 | ||
| 1200 | #ifdef CONFIG_PM_SLEEP | 1199 | static int __maybe_unused mcp251x_can_suspend(struct device *dev) |
| 1201 | |||
| 1202 | static int mcp251x_can_suspend(struct device *dev) | ||
| 1203 | { | 1200 | { |
| 1204 | struct spi_device *spi = to_spi_device(dev); | 1201 | struct spi_device *spi = to_spi_device(dev); |
| 1205 | struct mcp251x_priv *priv = spi_get_drvdata(spi); | 1202 | struct mcp251x_priv *priv = spi_get_drvdata(spi); |
| @@ -1221,7 +1218,7 @@ static int mcp251x_can_suspend(struct device *dev) · 15 unmodified lines | |||
| 1221 | priv->after_suspend = AFTER_SUSPEND_DOWN; | 1218 | priv->after_suspend = AFTER_SUSPEND_DOWN; |
| 1222 | } | 1219 | } |
| 1223 | 1220 | ||
| 1224 | if (!IS_ERR(priv->power)) { | 1221 | if (!IS_ERR_OR_NULL(priv->power)) { |
| 1225 | regulator_disable(priv->power); | 1222 | regulator_disable(priv->power); |
| 1226 | priv->after_suspend |= AFTER_SUSPEND_POWER; | 1223 | priv->after_suspend |= AFTER_SUSPEND_POWER; |
| 1227 | } | 1224 | } |
| @@ -1229,7 +1226,7 @@ static int mcp251x_can_suspend(struct device *dev) · 1 unmodified line | |||
| 1229 | return 0; | 1226 | return 0; |
| 1230 | } | 1227 | } |
| 1231 | 1228 | ||
| 1232 | static int mcp251x_can_resume(struct device *dev) | 1229 | static int __maybe_unused mcp251x_can_resume(struct device *dev) |
| 1233 | { | 1230 | { |
| 1234 | struct spi_device *spi = to_spi_device(dev); | 1231 | struct spi_device *spi = to_spi_device(dev); |
| 1235 | struct mcp251x_priv *priv = spi_get_drvdata(spi); | 1232 | struct mcp251x_priv *priv = spi_get_drvdata(spi); |
| @@ -1249,7 +1246,6 @@ static int mcp251x_can_resume(struct device *dev) · 13 unmodified lines | |||
| 1249 | enable_irq(spi->irq); | 1246 | enable_irq(spi->irq); |
| 1250 | return 0; | 1247 | return 0; |
| 1251 | } | 1248 | } |
| 1252 | #endif | ||
| 1253 | 1249 | ||
| 1254 | static SIMPLE_DEV_PM_OPS(mcp251x_can_pm_ops, mcp251x_can_suspend, | 1250 | static SIMPLE_DEV_PM_OPS(mcp251x_can_pm_ops, mcp251x_can_suspend, |
| 1255 | mcp251x_can_resume); | 1251 | mcp251x_can_resume); |
| @@ -647,9 +647,10 @@ static int mscan_close(struct net_device *dev) · 646 unmodified lines | |||
| 647 | } | 647 | } |
| 648 | 648 | ||
| 649 | static const struct net_device_ops mscan_netdev_ops = { | 649 | static const struct net_device_ops mscan_netdev_ops = { |
| 650 | .ndo_open = mscan_open, | 650 | .ndo_open = mscan_open, |
| 651 | .ndo_stop = mscan_close, | 651 | .ndo_stop = mscan_close, |
| 652 | .ndo_start_xmit = mscan_start_xmit, | 652 | .ndo_start_xmit = mscan_start_xmit, |
| 653 | .ndo_change_mtu = can_change_mtu, | ||
| 653 | }; | 654 | }; |
| 654 | 655 | ||
| 655 | int register_mscandev(struct net_device *dev, int mscan_clksrc) | 656 | int register_mscandev(struct net_device *dev, int mscan_clksrc) |
| @@ -950,6 +950,7 @@ static const struct net_device_ops pch_can_netdev_ops = { · 949 unmodified lines | |||
| 950 | .ndo_open = pch_can_open, | 950 | .ndo_open = pch_can_open, |
| 951 | .ndo_stop = pch_close, | 951 | .ndo_stop = pch_close, |
| 952 | .ndo_start_xmit = pch_xmit, | 952 | .ndo_start_xmit = pch_xmit, |
| 953 | .ndo_change_mtu = can_change_mtu, | ||
| 953 | }; | 954 | }; |
| 954 | 955 | ||
| 955 | static void pch_can_remove(struct pci_dev *pdev) | 956 | static void pch_can_remove(struct pci_dev *pdev) |
| @@ -17,16 +17,9 @@ config CAN_SJA1000_PLATFORM · 16 unmodified lines | |||
| 17 | the "platform bus" (Linux abstraction for directly to the | 17 | the "platform bus" (Linux abstraction for directly to the |
| 18 | processor attached devices). Which can be found on various | 18 | processor attached devices). Which can be found on various |
| 19 | boards from Phytec (http://www.phytec.de) like the PCM027, | 19 | boards from Phytec (http://www.phytec.de) like the PCM027, |
| 20 | PCM038. | 20 | PCM038. It also provides the OpenFirmware "platform bus" found |
| 21 | 21 | on embedded systems with OpenFirmware bindings, e.g. if you | |
| 22 | config CAN_SJA1000_OF_PLATFORM | 22 | have a PowerPC based system you may want to enable this option. |
| 23 | tristate "Generic OF Platform Bus based SJA1000 driver" | ||
| 24 | depends on OF | ||
| 25 | ---help--- | ||
| 26 | This driver adds support for the SJA1000 chips connected to | ||
| 27 | the OpenFirmware "platform bus" found on embedded systems with | ||
| 28 | OpenFirmware bindings, e.g. if you have a PowerPC based system | ||
| 29 | you may want to enable this option. | ||
| 30 | 23 | ||
| 31 | config CAN_EMS_PCMCIA | 24 | config CAN_EMS_PCMCIA |
| 32 | tristate "EMS CPC-CARD Card" | 25 | tristate "EMS CPC-CARD Card" |
| @@ -5,7 +5,6 @@ · 4 unmodified lines | |||
| 5 | obj-$(CONFIG_CAN_SJA1000) += sja1000.o | 5 | obj-$(CONFIG_CAN_SJA1000) += sja1000.o |
| 6 | obj-$(CONFIG_CAN_SJA1000_ISA) += sja1000_isa.o | 6 | obj-$(CONFIG_CAN_SJA1000_ISA) += sja1000_isa.o |
| 7 | obj-$(CONFIG_CAN_SJA1000_PLATFORM) += sja1000_platform.o | 7 | obj-$(CONFIG_CAN_SJA1000_PLATFORM) += sja1000_platform.o |
| 8 | obj-$(CONFIG_CAN_SJA1000_OF_PLATFORM) += sja1000_of_platform.o | ||
| 9 | obj-$(CONFIG_CAN_EMS_PCMCIA) += ems_pcmcia.o | 8 | obj-$(CONFIG_CAN_EMS_PCMCIA) += ems_pcmcia.o |
| 10 | obj-$(CONFIG_CAN_EMS_PCI) += ems_pci.o | 9 | obj-$(CONFIG_CAN_EMS_PCI) += ems_pci.o |
| 11 | obj-$(CONFIG_CAN_KVASER_PCI) += kvaser_pci.o | 10 | obj-$(CONFIG_CAN_KVASER_PCI) += kvaser_pci.o |
| @@ -323,6 +323,7 @@ static int ems_pci_add_card(struct pci_dev *pdev, · 322 unmodified lines | |||
| 323 | priv->cdr = EMS_PCI_CDR; | 323 | priv->cdr = EMS_PCI_CDR; |
| 324 | 324 | ||
| 325 | SET_NETDEV_DEV(dev, &pdev->dev); | 325 | SET_NETDEV_DEV(dev, &pdev->dev); |
| 326 | dev->dev_id = i; | ||
| 326 | 327 | ||
| 327 | if (card->version == 1) | 328 | if (card->version == 1) |
| 328 | /* reset int flag of pita */ | 329 | /* reset int flag of pita */ |
| @@ -211,6 +211,7 @@ static int ems_pcmcia_add_card(struct pcmcia_device *pdev, unsigned long base) · 210 unmodified lines | |||
| 211 | priv = netdev_priv(dev); | 211 | priv = netdev_priv(dev); |
| 212 | priv->priv = card; | 212 | priv->priv = card; |
| 213 | SET_NETDEV_DEV(dev, &pdev->dev); | 213 | SET_NETDEV_DEV(dev, &pdev->dev); |
| 214 | dev->dev_id = i; | ||
| 214 | 215 | ||
| 215 | priv->irq_flags = IRQF_SHARED; | 216 | priv->irq_flags = IRQF_SHARED; |
| 216 | dev->irq = pdev->irq; | 217 | dev->irq = pdev->irq; |
| @@ -270,6 +270,7 @@ static int kvaser_pci_add_chan(struct pci_dev *pdev, int channel, · 269 unmodified lines | |||
| 270 | priv->reg_base, board->conf_addr, dev->irq); | 270 | priv->reg_base, board->conf_addr, dev->irq); |
| 271 | 271 | ||
| 272 | SET_NETDEV_DEV(dev, &pdev->dev); | 272 | SET_NETDEV_DEV(dev, &pdev->dev); |
| 273 | dev->dev_id = channel; | ||
| 273 | 274 | ||
| 274 | /* Register SJA1000 device */ | 275 | /* Register SJA1000 device */ |
| 275 | err = register_sja1000dev(dev); | 276 | err = register_sja1000dev(dev); |
| @@ -642,6 +642,7 @@ static int peak_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) · 641 unmodified lines | |||
| 642 | icr |= chan->icr_mask; | 642 | icr |= chan->icr_mask; |
| 643 | 643 | ||
| 644 | SET_NETDEV_DEV(dev, &pdev->dev); | 644 | SET_NETDEV_DEV(dev, &pdev->dev); |
| 645 | dev->dev_id = i; | ||
| 645 | 646 | ||
| 646 | /* Create chain of SJA1000 devices */ | 647 | /* Create chain of SJA1000 devices */ |
| 647 | chan->prev_dev = pci_get_drvdata(pdev); | 648 | chan->prev_dev = pci_get_drvdata(pdev); |
| @@ -550,6 +550,7 @@ static int pcan_add_channels(struct pcan_pccard *card) · 549 unmodified lines | |||
| 550 | priv = netdev_priv(netdev); | 550 | priv = netdev_priv(netdev); |
| 551 | priv->priv = card; | 551 | priv->priv = card; |
| 552 | SET_NETDEV_DEV(netdev, &pdev->dev); | 552 | SET_NETDEV_DEV(netdev, &pdev->dev); |
| 553 | netdev->dev_id = i; | ||
| 553 | 554 | ||
| 554 | priv->irq_flags = IRQF_SHARED; | 555 | priv->irq_flags = IRQF_SHARED; |
| 555 | netdev->irq = pdev->irq; | 556 | netdev->irq = pdev->irq; |
| @@ -587,6 +587,7 @@ static int plx_pci_add_card(struct pci_dev *pdev, · 586 unmodified lines | |||
| 587 | priv->cdr = ci->cdr; | 587 | priv->cdr = ci->cdr; |
| 588 | 588 | ||
| 589 | SET_NETDEV_DEV(dev, &pdev->dev); | 589 | SET_NETDEV_DEV(dev, &pdev->dev); |
| 590 | dev->dev_id = i; | ||
| 590 | 591 | ||
| 591 | /* Register SJA1000 device */ | 592 | /* Register SJA1000 device */ |
| 592 | err = register_sja1000dev(dev); | 593 | err = register_sja1000dev(dev); |
| @@ -106,8 +106,7 @@ static int sja1000_probe_chip(struct net_device *dev) · 105 unmodified lines | |||
| 106 | struct sja1000_priv *priv = netdev_priv(dev); | 106 | struct sja1000_priv *priv = netdev_priv(dev); |
| 107 | 107 | ||
| 108 | if (priv->reg_base && sja1000_is_absent(priv)) { | 108 | if (priv->reg_base && sja1000_is_absent(priv)) { |
| 109 | printk(KERN_INFO "%s: probing @0x%lX failed\n", | 109 | netdev_err(dev, "probing failed\n"); |
| 110 | DRV_NAME, dev->base_addr); | ||
| 111 | return 0; | 110 | return 0; |
| 112 | } | 111 | } |
| 113 | return -1; | 112 | return -1; |
| @@ -643,9 +642,10 @@ void free_sja1000dev(struct net_device *dev) · 529 unmodified lines | |||
| 643 | EXPORT_SYMBOL_GPL(free_sja1000dev); | 642 | EXPORT_SYMBOL_GPL(free_sja1000dev); |
| 644 | 643 | ||
| 645 | static const struct net_device_ops sja1000_netdev_ops = { | 644 | static const struct net_device_ops sja1000_netdev_ops = { |
| 646 | .ndo_open = sja1000_open, | 645 | .ndo_open = sja1000_open, |
| 647 | .ndo_stop = sja1000_close, | 646 | .ndo_stop = sja1000_close, |
| 648 | .ndo_start_xmit = sja1000_start_xmit, | 647 | .ndo_start_xmit = sja1000_start_xmit, |
| 648 | .ndo_change_mtu = can_change_mtu, | ||
| 649 | }; | 649 | }; |
| 650 | 650 | ||
| 651 | int register_sja1000dev(struct net_device *dev) | 651 | int register_sja1000dev(struct net_device *dev) |
| @@ -1,220 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Driver for SJA1000 CAN controllers on the OpenFirmware platform bus | ||
| 3 | * | ||
| 4 | * Copyright (C) 2008-2009 Wolfgang Grandegger <wg@grandegger.com> | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the version 2 of the GNU General Public License | ||
| 8 | * as published by the Free Software Foundation | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, see <http://www.gnu.org/licenses/>. | ||
| 17 | */ | ||
| 18 | |||
| 19 | /* This is a generic driver for SJA1000 chips on the OpenFirmware platform | ||
| 20 | * bus found on embedded PowerPC systems. You need a SJA1000 CAN node | ||
| 21 | * definition in your flattened device tree source (DTS) file similar to: | ||
| 22 | * | ||
| 23 | * can@3,100 { | ||
| 24 | * compatible = "nxp,sja1000"; | ||
| 25 | * reg = <3 0x100 0x80>; | ||
| 26 | * interrupts = <2 0>; | ||
| 27 | * interrupt-parent = <&mpic>; | ||
| 28 | * nxp,external-clock-frequency = <16000000>; | ||
| 29 | * }; | ||
| 30 | * | ||
| 31 | * See "Documentation/devicetree/bindings/net/can/sja1000.txt" for further | ||
| 32 | * information. | ||
| 33 | */ | ||
| 34 | |||
| 35 | #include <linux/kernel.h> | ||
| 36 | #include <linux/module.h> | ||
| 37 | #include <linux/interrupt.h> | ||
| 38 | #include <linux/netdevice.h> | ||
| 39 | #include <linux/delay.h> | ||
| 40 | #include <linux/io.h> | ||
| 41 | #include <linux/can/dev.h> | ||
| 42 | |||
| 43 | #include <linux/of_platform.h> | ||
| 44 | #include <linux/of_address.h> | ||
| 45 | #include <linux/of_irq.h> | ||
| 46 | |||
| 47 | #include "sja1000.h" | ||
| 48 | |||
| 49 | #define DRV_NAME "sja1000_of_platform" | ||
| 50 | |||
| 51 | MODULE_AUTHOR("Wolfgang Grandegger <wg@grandegger.com>"); | ||
| 52 | MODULE_DESCRIPTION("Socket-CAN driver for SJA1000 on the OF platform bus"); | ||
| 53 | MODULE_LICENSE("GPL v2"); | ||
| 54 | |||
| 55 | #define SJA1000_OFP_CAN_CLOCK (16000000 / 2) | ||
| 56 | |||
| 57 | #define SJA1000_OFP_OCR OCR_TX0_PULLDOWN | ||
| 58 | #define SJA1000_OFP_CDR (CDR_CBP | CDR_CLK_OFF) | ||
| 59 | |||
| 60 | static u8 sja1000_ofp_read_reg(const struct sja1000_priv *priv, int reg) | ||
| 61 | { | ||
| 62 | return ioread8(priv->reg_base + reg); | ||
| 63 | } | ||
| 64 | |||
| 65 | static void sja1000_ofp_write_reg(const struct sja1000_priv *priv, | ||
| 66 | int reg, u8 val) | ||
| 67 | { | ||
| 68 | iowrite8(val, priv->reg_base + reg); | ||
| 69 | } | ||
| 70 | |||
| 71 | static int sja1000_ofp_remove(struct platform_device *ofdev) | ||
| 72 | { | ||
| 73 | struct net_device *dev = platform_get_drvdata(ofdev); | ||
| 74 | struct sja1000_priv *priv = netdev_priv(dev); | ||
| 75 | struct device_node *np = ofdev->dev.of_node; | ||
| 76 | struct resource res; | ||
| 77 | |||
| 78 | unregister_sja1000dev(dev); | ||
| 79 | free_sja1000dev(dev); | ||
| 80 | iounmap(priv->reg_base); | ||
| 81 | irq_dispose_mapping(dev->irq); | ||
| 82 | |||
| 83 | of_address_to_resource(np, 0, &res); | ||
| 84 | release_mem_region(res.start, resource_size(&res)); | ||
| 85 | |||
| 86 | return 0; | ||
| 87 | } | ||
| 88 | |||
| 89 | static int sja1000_ofp_probe(struct platform_device *ofdev) | ||
| 90 | { | ||
| 91 | struct device_node *np = ofdev->dev.of_node; | ||
| 92 | struct net_device *dev; | ||
| 93 | struct sja1000_priv *priv; | ||
| 94 | struct resource res; | ||
| 95 | u32 prop; | ||
| 96 | int err, irq, res_size; | ||
| 97 | void __iomem *base; | ||
| 98 | |||
| 99 | err = of_address_to_resource(np, 0, &res); | ||
| 100 | if (err) { | ||
| 101 | dev_err(&ofdev->dev, "invalid address\n"); | ||
| 102 | return err; | ||
| 103 | } | ||
| 104 | |||
| 105 | res_size = resource_size(&res); | ||
| 106 | |||
| 107 | if (!request_mem_region(res.start, res_size, DRV_NAME)) { | ||
| 108 | dev_err(&ofdev->dev, "couldn't request %pR\n", &res); | ||
| 109 | return -EBUSY; | ||
| 110 | } | ||
| 111 | |||
| 112 | base = ioremap_nocache(res.start, res_size); | ||
| 113 | if (!base) { | ||
| 114 | dev_err(&ofdev->dev, "couldn't ioremap %pR\n", &res); | ||
| 115 | err = -ENOMEM; | ||
| 116 | goto exit_release_mem; | ||
| 117 | } | ||
| 118 | |||
| 119 | irq = irq_of_parse_and_map(np, 0); | ||
| 120 | if (irq == 0) { | ||
| 121 | dev_err(&ofdev->dev, "no irq found\n"); | ||
| 122 | err = -ENODEV; | ||
| 123 | goto exit_unmap_mem; | ||
| 124 | } | ||
| 125 | |||
| 126 | dev = alloc_sja1000dev(0); | ||
| 127 | if (!dev) { | ||
| 128 | err = -ENOMEM; | ||
| 129 | goto exit_dispose_irq; | ||
| 130 | } | ||
| 131 | |||
| 132 | priv = netdev_priv(dev); | ||
| 133 | |||
| 134 | priv->read_reg = sja1000_ofp_read_reg; | ||
| 135 | priv->write_reg = sja1000_ofp_write_reg; | ||
| 136 | |||
| 137 | err = of_property_read_u32(np, "nxp,external-clock-frequency", &prop); | ||
| 138 | if (!err) | ||
| 139 | priv->can.clock.freq = prop / 2; | ||
| 140 | else | ||
| 141 | priv->can.clock.freq = SJA1000_OFP_CAN_CLOCK; /* default */ | ||
| 142 | |||
| 143 | err = of_property_read_u32(np, "nxp,tx-output-mode", &prop); | ||
| 144 | if (!err) | ||
| 145 | priv->ocr |= prop & OCR_MODE_MASK; | ||
| 146 | else | ||
| 147 | priv->ocr |= OCR_MODE_NORMAL; /* default */ | ||
| 148 | |||
| 149 | err = of_property_read_u32(np, "nxp,tx-output-config", &prop); | ||
| 150 | if (!err) | ||
| 151 | priv->ocr |= (prop << OCR_TX_SHIFT) & OCR_TX_MASK; | ||
| 152 | else | ||
| 153 | priv->ocr |= OCR_TX0_PULLDOWN; /* default */ | ||
| 154 | |||
| 155 | err = of_property_read_u32(np, "nxp,clock-out-frequency", &prop); | ||
| 156 | if (!err && prop) { | ||
| 157 | u32 divider = priv->can.clock.freq * 2 / prop; | ||
| 158 | |||
| 159 | if (divider > 1) | ||
| 160 | priv->cdr |= divider / 2 - 1; | ||
| 161 | else | ||
| 162 | priv->cdr |= CDR_CLKOUT_MASK; | ||
| 163 | } else { | ||
| 164 | priv->cdr |= CDR_CLK_OFF; /* default */ | ||
| 165 | } | ||
| 166 | |||
| 167 | if (!of_property_read_bool(np, "nxp,no-comparator-bypass")) | ||
| 168 | priv->cdr |= CDR_CBP; /* default */ | ||
| 169 | |||
| 170 | priv->irq_flags = IRQF_SHARED; | ||
| 171 | priv->reg_base = base; | ||
| 172 | |||
| 173 | dev->irq = irq; | ||
| 174 | |||
| 175 | dev_info(&ofdev->dev, | ||
| 176 | "reg_base=0x%p irq=%d clock=%d ocr=0x%02x cdr=0x%02x\n", | ||
| 177 | priv->reg_base, dev->irq, priv->can.clock.freq, | ||
| 178 | priv->ocr, priv->cdr); | ||
| 179 | |||
| 180 | platform_set_drvdata(ofdev, dev); | ||
| 181 | SET_NETDEV_DEV(dev, &ofdev->dev); | ||
| 182 | |||
| 183 | err = register_sja1000dev(dev); | ||
| 184 | if (err) { | ||
| 185 | dev_err(&ofdev->dev, "registering %s failed (err=%d)\n", | ||
| 186 | DRV_NAME, err); | ||
| 187 | goto exit_free_sja1000; | ||
| 188 | } | ||
| 189 | |||
| 190 | return 0; | ||
| 191 | |||
| 192 | exit_free_sja1000: | ||
| 193 | free_sja1000dev(dev); | ||
| 194 | exit_dispose_irq: | ||
| 195 | irq_dispose_mapping(irq); | ||
| 196 | exit_unmap_mem: | ||
| 197 | iounmap(base); | ||
| 198 | exit_release_mem: | ||
| 199 | release_mem_region(res.start, res_size); | ||
| 200 | |||
| 201 | return err; | ||
| 202 | } | ||
| 203 | |||
| 204 | static struct of_device_id sja1000_ofp_table[] = { | ||
| 205 | {.compatible = "nxp,sja1000"}, | ||
| 206 | {}, | ||
| 207 | }; | ||
| 208 | MODULE_DEVICE_TABLE(of, sja1000_ofp_table); | ||
| 209 | |||
| 210 | static struct platform_driver sja1000_ofp_driver = { | ||
| 211 | .driver = { | ||
| 212 | .owner = THIS_MODULE, | ||
| 213 | .name = DRV_NAME, | ||
| 214 | .of_match_table = sja1000_ofp_table, | ||
| 215 | }, | ||
| 216 | .probe = sja1000_ofp_probe, | ||
| 217 | .remove = sja1000_ofp_remove, | ||
| 218 | }; | ||
| 219 | |||
| 220 | module_platform_driver(sja1000_ofp_driver); | ||
| @@ -26,12 +26,16 @@ · 25 unmodified lines | |||
| 26 | #include <linux/can/dev.h> | 26 | #include <linux/can/dev.h> |
| 27 | #include <linux/can/platform/sja1000.h> | 27 | #include <linux/can/platform/sja1000.h> |
| 28 | #include <linux/io.h> | 28 | #include <linux/io.h> |
| 29 | #include <linux/of.h> | ||
| 30 | #include <linux/of_irq.h> | ||
| 29 | 31 | ||
| 30 | #include "sja1000.h" | 32 | #include "sja1000.h" |
| 31 | 33 | ||
| 32 | #define DRV_NAME "sja1000_platform" | 34 | #define DRV_NAME "sja1000_platform" |
| 35 | #define SP_CAN_CLOCK (16000000 / 2) | ||
| 33 | 36 | ||
| 34 | MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>"); | 37 | MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>"); |
| 38 | MODULE_AUTHOR("Wolfgang Grandegger <wg@grandegger.com>"); | ||
| 35 | MODULE_DESCRIPTION("Socket-CAN driver for SJA1000 on the platform bus"); | 39 | MODULE_DESCRIPTION("Socket-CAN driver for SJA1000 on the platform bus"); |
| 36 | MODULE_ALIAS("platform:" DRV_NAME); | 40 | MODULE_ALIAS("platform:" DRV_NAME); |
| 37 | MODULE_LICENSE("GPL v2"); | 41 | MODULE_LICENSE("GPL v2"); |
| @@ -66,59 +70,16 @@ static void sp_write_reg32(const struct sja1000_priv *priv, int reg, u8 val) · 28 unmodified lines | |||
| 66 | iowrite8(val, priv->reg_base + reg * 4); | 70 | iowrite8(val, priv->reg_base + reg * 4); |
| 67 | } | 71 | } |
| 68 | 72 | ||
| 69 | static int sp_probe(struct platform_device *pdev) | 73 | static void sp_populate(struct sja1000_priv *priv, |
| 74 | struct sja1000_platform_data *pdata, | ||
| 75 | unsigned long resource_mem_flags) | ||
| 70 | { | 76 | { |
| 71 | int err; | ||
| 72 | void __iomem *addr; | ||
| 73 | struct net_device *dev; | ||
| 74 | struct sja1000_priv *priv; | ||
| 75 | struct resource *res_mem, *res_irq; | ||
| 76 | struct sja1000_platform_data *pdata; | ||
| 77 | |||
| 78 | pdata = dev_get_platdata(&pdev->dev); | ||
| 79 | if (!pdata) { | ||
| 80 | dev_err(&pdev->dev, "No platform data provided!\n"); | ||
| 81 | err = -ENODEV; | ||
| 82 | goto exit; | ||
| 83 | } | ||
| 84 | |||
| 85 | res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
| 86 | res_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | ||
| 87 | if (!res_mem || !res_irq) { | ||
| 88 | err = -ENODEV; | ||
| 89 | goto exit; | ||
| 90 | } | ||
| 91 | |||
| 92 | if (!request_mem_region(res_mem->start, resource_size(res_mem), | ||
| 93 | DRV_NAME)) { | ||
| 94 | err = -EBUSY; | ||
| 95 | goto exit; | ||
| 96 | } | ||
| 97 | |||
| 98 | addr = ioremap_nocache(res_mem->start, resource_size(res_mem)); | ||
| 99 | if (!addr) { | ||
| 100 | err = -ENOMEM; | ||
| 101 | goto exit_release; | ||
| 102 | } | ||
| 103 | |||
| 104 | dev = alloc_sja1000dev(0); | ||
| 105 | if (!dev) { | ||
| 106 | err = -ENOMEM; | ||
| 107 | goto exit_iounmap; | ||
| 108 | } | ||
| 109 | priv = netdev_priv(dev); | ||
| 110 | |||
| 111 | dev->irq = res_irq->start; | ||
| 112 | priv->irq_flags = res_irq->flags & IRQF_TRIGGER_MASK; | ||
| 113 | if (res_irq->flags & IORESOURCE_IRQ_SHAREABLE) | ||
| 114 | priv->irq_flags |= IRQF_SHARED; | ||
| 115 | priv->reg_base = addr; | ||
| 116 | /* The CAN clock frequency is half the oscillator clock frequency */ | 77 | /* The CAN clock frequency is half the oscillator clock frequency */ |
| 117 | priv->can.clock.freq = pdata->osc_freq / 2; | 78 | priv->can.clock.freq = pdata->osc_freq / 2; |
| 118 | priv->ocr = pdata->ocr; | 79 | priv->ocr = pdata->ocr; |
| 119 | priv->cdr = pdata->cdr; | 80 | priv->cdr = pdata->cdr; |
| 120 | 81 | ||
| 121 | switch (res_mem->flags & IORESOURCE_MEM_TYPE_MASK) { | 82 | switch (resource_mem_flags & IORESOURCE_MEM_TYPE_MASK) { |
| 122 | case IORESOURCE_MEM_32BIT: | 83 | case IORESOURCE_MEM_32BIT: |
| 123 | priv->read_reg = sp_read_reg32; | 84 | priv->read_reg = sp_read_reg32; |
| 124 | priv->write_reg = sp_write_reg32; | 85 | priv->write_reg = sp_write_reg32; |
| @@ -133,6 +94,124 @@ static int sp_probe(struct platform_device *pdev) · 8 unmodified lines | |||
| 133 | priv->write_reg = sp_write_reg8; | 94 | priv->write_reg = sp_write_reg8; |
| 134 | break; | 95 | break; |
| 135 | } | 96 | } |
| 97 | } | ||
| 98 | |||
| 99 | static void sp_populate_of(struct sja1000_priv *priv, struct device_node *of) | ||
| 100 | { | ||
| 101 | int err; | ||
| 102 | u32 prop; | ||
| 103 | |||
| 104 | err = of_property_read_u32(of, "reg-io-width", &prop); | ||
| 105 | if (err) | ||
| 106 | prop = 1; /* 8 bit is default */ | ||
| 107 | |||
| 108 | switch (prop) { | ||
| 109 | case 4: | ||
| 110 | priv->read_reg = sp_read_reg32; | ||
| 111 | priv->write_reg = sp_write_reg32; | ||
| 112 | break; | ||
| 113 | case 2: | ||
| 114 | priv->read_reg = sp_read_reg16; | ||
| 115 | priv->write_reg = sp_write_reg16; | ||
| 116 | break; | ||
| 117 | case 1: /* fallthrough */ | ||
| 118 | default: | ||
| 119 | priv->read_reg = sp_read_reg8; | ||
| 120 | priv->write_reg = sp_write_reg8; | ||
| 121 | } | ||
| 122 | |||
| 123 | err = of_property_read_u32(of, "nxp,external-clock-frequency", &prop); | ||
| 124 | if (!err) | ||
| 125 | priv->can.clock.freq = prop / 2; | ||
| 126 | else | ||
| 127 | priv->can.clock.freq = SP_CAN_CLOCK; /* default */ | ||
| 128 | |||
| 129 | err = of_property_read_u32(of, "nxp,tx-output-mode", &prop); | ||
| 130 | if (!err) | ||
| 131 | priv->ocr |= prop & OCR_MODE_MASK; | ||
| 132 | else | ||
| 133 | priv->ocr |= OCR_MODE_NORMAL; /* default */ | ||
| 134 | |||
| 135 | err = of_property_read_u32(of, "nxp,tx-output-config", &prop); | ||
| 136 | if (!err) | ||
| 137 | priv->ocr |= (prop << OCR_TX_SHIFT) & OCR_TX_MASK; | ||
| 138 | else | ||
| 139 | priv->ocr |= OCR_TX0_PULLDOWN; /* default */ | ||
| 140 | |||
| 141 | err = of_property_read_u32(of, "nxp,clock-out-frequency", &prop); | ||
| 142 | if (!err && prop) { | ||
| 143 | u32 divider = priv->can.clock.freq * 2 / prop; | ||
| 144 | |||
| 145 | if (divider > 1) | ||
| 146 | priv->cdr |= divider / 2 - 1; | ||
| 147 | else | ||
| 148 | priv->cdr |= CDR_CLKOUT_MASK; | ||
| 149 | } else { | ||
| 150 | priv->cdr |= CDR_CLK_OFF; /* default */ | ||
| 151 | } | ||
| 152 | |||
| 153 | if (!of_property_read_bool(of, "nxp,no-comparator-bypass")) | ||
| 154 | priv->cdr |= CDR_CBP; /* default */ | ||
| 155 | } | ||
| 156 | |||
| 157 | static int sp_probe(struct platform_device *pdev) | ||
| 158 | { | ||
| 159 | int err, irq = 0; | ||
| 160 | void __iomem *addr; | ||
| 161 | struct net_device *dev; | ||
| 162 | struct sja1000_priv *priv; | ||
| 163 | struct resource *res_mem, *res_irq = NULL; | ||
| 164 | struct sja1000_platform_data *pdata; | ||
| 165 | struct device_node *of = pdev->dev.of_node; | ||
| 166 | |||
| 167 | pdata = dev_get_platdata(&pdev->dev); | ||
| 168 | if (!pdata && !of) { | ||
| 169 | dev_err(&pdev->dev, "No platform data provided!\n"); | ||
| 170 | return -ENODEV; | ||
| 171 | } | ||
| 172 | |||
| 173 | res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
| 174 | if (!res_mem) | ||
| 175 | return -ENODEV; | ||
| 176 | |||
| 177 | if (!devm_request_mem_region(&pdev->dev, res_mem->start, | ||
| 178 | resource_size(res_mem), DRV_NAME)) | ||
| 179 | return -EBUSY; | ||
| 180 | |||
| 181 | addr = devm_ioremap_nocache(&pdev->dev, res_mem->start, | ||
| 182 | resource_size(res_mem)); | ||
| 183 | if (!addr) | ||
| 184 | return -ENOMEM; | ||
| 185 | |||
| 186 | if (of) | ||
| 187 | irq = irq_of_parse_and_map(of, 0); | ||
| 188 | else | ||
| 189 | res_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | ||
| 190 | |||
| 191 | if (!irq && !res_irq) | ||
| 192 | return -ENODEV; | ||
| 193 | |||
| 194 | dev = alloc_sja1000dev(0); | ||
| 195 | if (!dev) | ||
| 196 | return -ENOMEM; | ||
| 197 | priv = netdev_priv(dev); | ||
| 198 | |||
| 199 | if (res_irq) { | ||
| 200 | irq = res_irq->start; | ||
| 201 | priv->irq_flags = res_irq->flags & IRQF_TRIGGER_MASK; | ||
| 202 | if (res_irq->flags & IORESOURCE_IRQ_SHAREABLE) | ||
| 203 | priv->irq_flags |= IRQF_SHARED; | ||
| 204 | } else { | ||
| 205 | priv->irq_flags = IRQF_SHARED; | ||
| 206 | } | ||
| 207 | |||
| 208 | dev->irq = irq; | ||
| 209 | priv->reg_base = addr; | ||
| 210 | |||
| 211 | if (of) | ||
| 212 | sp_populate_of(priv, of); | ||
| 213 | else | ||
| 214 | sp_populate(priv, pdata, res_mem->flags); | ||
| 136 | 215 | ||
| 137 | platform_set_drvdata(pdev, dev); | 216 | platform_set_drvdata(pdev, dev); |
| 138 | SET_NETDEV_DEV(dev, &pdev->dev); | 217 | SET_NETDEV_DEV(dev, &pdev->dev); |
| @@ -150,39 +229,32 @@ static int sp_probe(struct platform_device *pdev) · 11 unmodified lines | |||
| 150 | 229 | ||
| 151 | exit_free: | 230 | exit_free: |
| 152 | free_sja1000dev(dev); | 231 | free_sja1000dev(dev); |
| 153 | exit_iounmap: | ||
| 154 | iounmap(addr); | ||
| 155 | exit_release: | ||
| 156 | release_mem_region(res_mem->start, resource_size(res_mem)); | ||
| 157 | exit: | ||
| 158 | return err; | 232 | return err; |
| 159 | } | 233 | } |
| 160 | 234 | ||
| 161 | static int sp_remove(struct platform_device *pdev) | 235 | static int sp_remove(struct platform_device *pdev) |
| 162 | { | 236 | { |
| 163 | struct net_device *dev = platform_get_drvdata(pdev); | 237 | struct net_device *dev = platform_get_drvdata(pdev); |
| 164 | struct sja1000_priv *priv = netdev_priv(dev); | ||
| 165 | struct resource *res; | ||
| 166 | 238 | ||
| 167 | unregister_sja1000dev(dev); | 239 | unregister_sja1000dev(dev); |
| 168 | |||
| 169 | if (priv->reg_base) | ||
| 170 | iounmap(priv->reg_base); | ||
| 171 | |||
| 172 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
| 173 | release_mem_region(res->start, resource_size(res)); | ||
| 174 | |||
| 175 | free_sja1000dev(dev); | 240 | free_sja1000dev(dev); |
| 176 | 241 | ||
| 177 | return 0; | 242 | return 0; |
| 178 | } | 243 | } |
| 179 | 244 | ||
| 245 | static struct of_device_id sp_of_table[] = { | ||
| 246 | {.compatible = "nxp,sja1000"}, | ||
| 247 | {}, | ||
| 248 | }; | ||
| 249 | MODULE_DEVICE_TABLE(of, sp_of_table); | ||
| 250 | |||
| 180 | static struct platform_driver sp_driver = { | 251 | static struct platform_driver sp_driver = { |
| 181 | .probe = sp_probe, | 252 | .probe = sp_probe, |
| 182 | .remove = sp_remove, | 253 | .remove = sp_remove, |
| 183 | .driver = { | 254 | .driver = { |
| 184 | .name = DRV_NAME, | 255 | .name = DRV_NAME, |
| 185 | .owner = THIS_MODULE, | 256 | .owner = THIS_MODULE, |
| 257 | .of_match_table = sp_of_table, | ||
| 186 | }, | 258 | }, |
| 187 | }; | 259 | }; |
| 188 | 260 | ||
| @@ -411,10 +411,16 @@ static void slc_free_netdev(struct net_device *dev) · 410 unmodified lines | |||
| 411 | slcan_devs[i] = NULL; | 411 | slcan_devs[i] = NULL; |
| 412 | } | 412 | } |
| 413 | 413 | ||
| 414 | static int slcan_change_mtu(struct net_device *dev, int new_mtu) | ||
| 415 | { | ||
| 416 | return -EINVAL; | ||
| 417 | } | ||
| 418 | |||
| 414 | static const struct net_device_ops slc_netdev_ops = { | 419 | static const struct net_device_ops slc_netdev_ops = { |
| 415 | .ndo_open = slc_open, | 420 | .ndo_open = slc_open, |
| 416 | .ndo_stop = slc_close, | 421 | .ndo_stop = slc_close, |
| 417 | .ndo_start_xmit = slc_xmit, | 422 | .ndo_start_xmit = slc_xmit, |
| 423 | .ndo_change_mtu = slcan_change_mtu, | ||
| 418 | }; | 424 | }; |
| 419 | 425 | ||
| 420 | static void slc_setup(struct net_device *dev) | 426 | static void slc_setup(struct net_device *dev) |
| @@ -628,6 +628,7 @@ static const struct net_device_ops softing_netdev_ops = { · 627 unmodified lines | |||
| 628 | .ndo_open = softing_netdev_open, | 628 | .ndo_open = softing_netdev_open, |
| 629 | .ndo_stop = softing_netdev_stop, | 629 | .ndo_stop = softing_netdev_stop, |
| 630 | .ndo_start_xmit = softing_netdev_start_xmit, | 630 | .ndo_start_xmit = softing_netdev_start_xmit, |
| 631 | .ndo_change_mtu = can_change_mtu, | ||
| 631 | }; | 632 | }; |
| 632 | 633 | ||
| 633 | static const struct can_bittiming_const softing_btr_const = { | 634 | static const struct can_bittiming_const softing_btr_const = { |
| @@ -832,6 +833,7 @@ static int softing_pdev_probe(struct platform_device *pdev) · 198 unmodified lines | |||
| 832 | ret = -ENOMEM; | 833 | ret = -ENOMEM; |
| 833 | goto netdev_failed; | 834 | goto netdev_failed; |
| 834 | } | 835 | } |
| 836 | netdev->dev_id = j; | ||
| 835 | priv = netdev_priv(card->net[j]); | 837 | priv = netdev_priv(card->net[j]); |
| 836 | priv->index = j; | 838 | priv->index = j; |
| 837 | ret = softing_netdev_register(netdev); | 839 | ret = softing_netdev_register(netdev); |
| @@ -871,6 +871,7 @@ static const struct net_device_ops ti_hecc_netdev_ops = { · 870 unmodified lines | |||
| 871 | .ndo_open = ti_hecc_open, | 871 | .ndo_open = ti_hecc_open, |
| 872 | .ndo_stop = ti_hecc_close, | 872 | .ndo_stop = ti_hecc_close, |
| 873 | .ndo_start_xmit = ti_hecc_xmit, | 873 | .ndo_start_xmit = ti_hecc_xmit, |
| 874 | .ndo_change_mtu = can_change_mtu, | ||
| 874 | }; | 875 | }; |
| 875 | 876 | ||
| 876 | static int ti_hecc_probe(struct platform_device *pdev) | 877 | static int ti_hecc_probe(struct platform_device *pdev) |
| @@ -883,6 +883,7 @@ static const struct net_device_ops ems_usb_netdev_ops = { · 882 unmodified lines | |||
| 883 | .ndo_open = ems_usb_open, | 883 | .ndo_open = ems_usb_open, |
| 884 | .ndo_stop = ems_usb_close, | 884 | .ndo_stop = ems_usb_close, |
| 885 | .ndo_start_xmit = ems_usb_start_xmit, | 885 | .ndo_start_xmit = ems_usb_start_xmit, |
| 886 | .ndo_change_mtu = can_change_mtu, | ||
| 886 | }; | 887 | }; |
| 887 | 888 | ||
| 888 | static const struct can_bittiming_const ems_usb_bittiming_const = { | 889 | static const struct can_bittiming_const ems_usb_bittiming_const = { |
| @@ -888,6 +888,7 @@ static const struct net_device_ops esd_usb2_netdev_ops = { · 887 unmodified lines | |||
| 888 | .ndo_open = esd_usb2_open, | 888 | .ndo_open = esd_usb2_open, |
| 889 | .ndo_stop = esd_usb2_close, | 889 | .ndo_stop = esd_usb2_close, |
| 890 | .ndo_start_xmit = esd_usb2_start_xmit, | 890 | .ndo_start_xmit = esd_usb2_start_xmit, |
| 891 | .ndo_change_mtu = can_change_mtu, | ||
| 891 | }; | 892 | }; |
| 892 | 893 | ||
| 893 | static const struct can_bittiming_const esd_usb2_bittiming_const = { | 894 | static const struct can_bittiming_const esd_usb2_bittiming_const = { |
| @@ -1024,6 +1025,7 @@ static int esd_usb2_probe_one_net(struct usb_interface *intf, int index) · 130 unmodified lines | |||
| 1024 | netdev->netdev_ops = &esd_usb2_netdev_ops; | 1025 | netdev->netdev_ops = &esd_usb2_netdev_ops; |
| 1025 | 1026 | ||
| 1026 | SET_NETDEV_DEV(netdev, &intf->dev); | 1027 | SET_NETDEV_DEV(netdev, &intf->dev); |
| 1028 | netdev->dev_id = index; | ||
| 1027 | 1029 | ||
| 1028 | err = register_candev(netdev); | 1030 | err = register_candev(netdev); |
| 1029 | if (err) { | 1031 | if (err) { |
| @@ -1388,6 +1388,7 @@ static const struct net_device_ops kvaser_usb_netdev_ops = { · 1387 unmodified lines | |||
| 1388 | .ndo_open = kvaser_usb_open, | 1388 | .ndo_open = kvaser_usb_open, |
| 1389 | .ndo_stop = kvaser_usb_close, | 1389 | .ndo_stop = kvaser_usb_close, |
| 1390 | .ndo_start_xmit = kvaser_usb_start_xmit, | 1390 | .ndo_start_xmit = kvaser_usb_start_xmit, |
| 1391 | .ndo_change_mtu = can_change_mtu, | ||
| 1391 | }; | 1392 | }; |
| 1392 | 1393 | ||
| 1393 | static const struct can_bittiming_const kvaser_usb_bittiming_const = { | 1394 | static const struct can_bittiming_const kvaser_usb_bittiming_const = { |
| @@ -1529,6 +1530,7 @@ static int kvaser_usb_init_one(struct usb_interface *intf, · 135 unmodified lines | |||
| 1529 | netdev->netdev_ops = &kvaser_usb_netdev_ops; | 1530 | netdev->netdev_ops = &kvaser_usb_netdev_ops; |
| 1530 | 1531 | ||
| 1531 | SET_NETDEV_DEV(netdev, &intf->dev); | 1532 | SET_NETDEV_DEV(netdev, &intf->dev); |
| 1533 | netdev->dev_id = channel; | ||
| 1532 | 1534 | ||
| 1533 | dev->nets[channel] = priv; | 1535 | dev->nets[channel] = priv; |
| 1534 | 1536 | ||
| @@ -702,6 +702,7 @@ static const struct net_device_ops peak_usb_netdev_ops = { · 701 unmodified lines | |||
| 702 | .ndo_open = peak_usb_ndo_open, | 702 | .ndo_open = peak_usb_ndo_open, |
| 703 | .ndo_stop = peak_usb_ndo_stop, | 703 | .ndo_stop = peak_usb_ndo_stop, |
| 704 | .ndo_start_xmit = peak_usb_ndo_start_xmit, | 704 | .ndo_start_xmit = peak_usb_ndo_start_xmit, |
| 705 | .ndo_change_mtu = can_change_mtu, | ||
| 705 | }; | 706 | }; |
| 706 | 707 | ||
| 707 | /* | 708 | /* |
| @@ -769,6 +770,7 @@ static int peak_usb_create_dev(struct peak_usb_adapter *peak_usb_adapter, · 61 unmodified lines | |||
| 769 | usb_set_intfdata(intf, dev); | 770 | usb_set_intfdata(intf, dev); |
| 770 | 771 | ||
| 771 | SET_NETDEV_DEV(netdev, &intf->dev); | 772 | SET_NETDEV_DEV(netdev, &intf->dev); |
| 773 | netdev->dev_id = ctrl_idx; | ||
| 772 | 774 | ||
| 773 | err = register_candev(netdev); | 775 | err = register_candev(netdev); |
| 774 | if (err) { | 776 | if (err) { |
| @@ -697,8 +697,8 @@ static netdev_tx_t usb_8dev_start_xmit(struct sk_buff *skb, · 696 unmodified lines | |||
| 697 | return NETDEV_TX_OK; | 697 | return NETDEV_TX_OK; |
| 698 | 698 | ||
| 699 | nofreecontext: | 699 | nofreecontext: |
| 700 | usb_unanchor_urb(urb); | ||
| 701 | usb_free_coherent(priv->udev, size, buf, urb->transfer_dma); | 700 | usb_free_coherent(priv->udev, size, buf, urb->transfer_dma); |
| 701 | usb_free_urb(urb); | ||
| 702 | 702 | ||
| 703 | netdev_warn(netdev, "couldn't find free context"); | 703 | netdev_warn(netdev, "couldn't find free context"); |
| 704 | 704 | ||
| @@ -887,6 +887,7 @@ static const struct net_device_ops usb_8dev_netdev_ops = { · 182 unmodified lines | |||
| 887 | .ndo_open = usb_8dev_open, | 887 | .ndo_open = usb_8dev_open, |
| 888 | .ndo_stop = usb_8dev_close, | 888 | .ndo_stop = usb_8dev_close, |
| 889 | .ndo_start_xmit = usb_8dev_start_xmit, | 889 | .ndo_start_xmit = usb_8dev_start_xmit, |
| 890 | .ndo_change_mtu = can_change_mtu, | ||
| 890 | }; | 891 | }; |
| 891 | 892 | ||
| 892 | static const struct can_bittiming_const usb_8dev_bittiming_const = { | 893 | static const struct can_bittiming_const usb_8dev_bittiming_const = { |
| @@ -63,10 +63,10 @@ static struct rtnl_link_stats64 *dummy_get_stats64(struct net_device *dev, · 62 unmodified lines | |||
| 63 | 63 | ||
| 64 | dstats = per_cpu_ptr(dev->dstats, i); | 64 | dstats = per_cpu_ptr(dev->dstats, i); |
| 65 | do { | 65 | do { |
| 66 | start = u64_stats_fetch_begin_bh(&dstats->syncp); | 66 | start = u64_stats_fetch_begin_irq(&dstats->syncp); |
| 67 | tbytes = dstats->tx_bytes; | 67 | tbytes = dstats->tx_bytes; |
| 68 | tpackets = dstats->tx_packets; | 68 | tpackets = dstats->tx_packets; |
| 69 | } while (u64_stats_fetch_retry_bh(&dstats->syncp, start)); | 69 | } while (u64_stats_fetch_retry_irq(&dstats->syncp, start)); |
| 70 | stats->tx_bytes += tbytes; | 70 | stats->tx_bytes += tbytes; |
| 71 | stats->tx_packets += tpackets; | 71 | stats->tx_packets += tpackets; |
| 72 | } | 72 | } |
| @@ -88,16 +88,10 @@ static netdev_tx_t dummy_xmit(struct sk_buff *skb, struct net_device *dev) · 15 unmodified lines | |||
| 88 | 88 | ||
| 89 | static int dummy_dev_init(struct net_device *dev) | 89 | static int dummy_dev_init(struct net_device *dev) |
| 90 | { | 90 | { |
| 91 | int i; | 91 | dev->dstats = netdev_alloc_pcpu_stats(struct pcpu_dstats); |
| 92 | dev->dstats = alloc_percpu(struct pcpu_dstats); | ||
| 93 | if (!dev->dstats) | 92 | if (!dev->dstats) |
| 94 | return -ENOMEM; | 93 | return -ENOMEM; |
| 95 | 94 | ||
| 96 | for_each_possible_cpu(i) { | ||
| 97 | struct pcpu_dstats *dstats; | ||
| 98 | dstats = per_cpu_ptr(dev->dstats, i); | ||
| 99 | u64_stats_init(&dstats->syncp); | ||
| 100 | } | ||
| 101 | return 0; | 95 | return 0; |
| 102 | } | 96 | } |
| 103 | 97 | ||
| @@ -749,7 +749,7 @@ el3_start_xmit(struct sk_buff *skb, struct net_device *dev) · 748 unmodified lines | |||
| 749 | 749 | ||
| 750 | spin_unlock_irqrestore(&lp->lock, flags); | 750 | spin_unlock_irqrestore(&lp->lock, flags); |
| 751 | 751 | ||
| 752 | dev_kfree_skb (skb); | 752 | dev_consume_skb_any (skb); |
| 753 | 753 | ||
| 754 | /* Clear the Tx status stack. */ | 754 | /* Clear the Tx status stack. */ |
| 755 | { | 755 | { |
| @@ -1,23 +1,24 @@ | |||
| 1 | /*====================================================================== | 1 | /* ====================================================================== |
| 2 | 2 | * | |
| 3 | A PCMCIA ethernet driver for the 3com 3c589 card. | 3 | * A PCMCIA ethernet driver for the 3com 3c589 card. |
| 4 | 4 | * | |
| 5 | Copyright (C) 1999 David A. Hinds -- dahinds@users.sourceforge.net | 5 | * Copyright (C) 1999 David A. Hinds -- dahinds@users.sourceforge.net |
| 6 | 6 | * | |
| 7 | 3c589_cs.c 1.162 2001/10/13 00:08:50 | 7 | * 3c589_cs.c 1.162 2001/10/13 00:08:50 |
| 8 | 8 | * | |
| 9 | The network driver code is based on Donald Becker's 3c589 code: | 9 | * The network driver code is based on Donald Becker's 3c589 code: |
| 10 | 10 | * | |
| 11 | Written 1994 by Donald Becker. | 11 | * Written 1994 by Donald Becker. |
| 12 | Copyright 1993 United States Government as represented by the | 12 | * Copyright 1993 United States Government as represented by the |
| 13 | Director, National Security Agency. This software may be used and | 13 | * Director, National Security Agency. This software may be used and |
| 14 | distributed according to the terms of the GNU General Public License, | 14 | * distributed according to the terms of the GNU General Public License, |
| 15 | incorporated herein by reference. | 15 | * incorporated herein by reference. |
| 16 | Donald Becker may be reached at becker@scyld.com | 16 | * Donald Becker may be reached at becker@scyld.com |
| 17 | 17 | * | |
| 18 | Updated for 2.5.x by Alan Cox <alan@lxorguk.ukuu.org.uk> | 18 | * Updated for 2.5.x by Alan Cox <alan@lxorguk.ukuu.org.uk> |
| 19 | 19 | * | |
| 20 | ======================================================================*/ | 20 | * ====================================================================== |
| 21 | */ | ||
| 21 | 22 | ||
| 22 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | 23 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
| 23 | 24 | ||
| @@ -41,18 +42,20 @@ · 17 unmodified lines | |||
| 41 | #include <linux/ioport.h> | 42 | #include <linux/ioport.h> |
| 42 | #include <linux/bitops.h> | 43 | #include <linux/bitops.h> |
| 43 | #include <linux/jiffies.h> | 44 | #include <linux/jiffies.h> |
| 45 | #include <linux/uaccess.h> | ||
| 46 | #include <linux/io.h> | ||
| 44 | 47 | ||
| 45 | #include <pcmcia/cistpl.h> | 48 | #include <pcmcia/cistpl.h> |
| 46 | #include <pcmcia/cisreg.h> | 49 | #include <pcmcia/cisreg.h> |
| 47 | #include <pcmcia/ciscode.h> | 50 | #include <pcmcia/ciscode.h> |
| 48 | #include <pcmcia/ds.h> | 51 | #include <pcmcia/ds.h> |
| 49 | 52 | ||
| 50 | #include <asm/uaccess.h> | ||
| 51 | #include <asm/io.h> | ||
| 52 | 53 | ||
| 53 | /* To minimize the size of the driver source I only define operating | 54 | /* To minimize the size of the driver source I only define operating |
| 54 | constants if they are used several times. You'll need the manual | 55 | * constants if they are used several times. You'll need the manual |
| 55 | if you want to understand driver details. */ | 56 | * if you want to understand driver details. |
| 57 | */ | ||
| 58 | |||
| 56 | /* Offsets from base I/O address. */ | 59 | /* Offsets from base I/O address. */ |
| 57 | #define EL3_DATA 0x00 | 60 | #define EL3_DATA 0x00 |
| 58 | #define EL3_TIMER 0x0a | 61 | #define EL3_TIMER 0x0a |
| @@ -65,7 +68,9 @@ · 6 unmodified lines | |||
| 65 | #define EL3WINDOW(win_num) outw(SelectWindow + (win_num), ioaddr + EL3_CMD) | 68 | #define EL3WINDOW(win_num) outw(SelectWindow + (win_num), ioaddr + EL3_CMD) |
| 66 | 69 | ||
| 67 | /* The top five bits written to EL3_CMD are a command, the lower | 70 | /* The top five bits written to EL3_CMD are a command, the lower |
| 68 | 11 bits are the parameter, if applicable. */ | 71 | * 11 bits are the parameter, if applicable. |
| 72 | */ | ||
| 73 | |||
| 69 | enum c509cmd { | 74 | enum c509cmd { |
| 70 | TotalReset = 0<<11, | 75 | TotalReset = 0<<11, |
| 71 | SelectWindow = 1<<11, | 76 | SelectWindow = 1<<11, |
| @@ -190,138 +195,142 @@ static const struct net_device_ops el3_netdev_ops = { · 118 unmodified lines | |||
| 190 | 195 | ||
| 191 | static int tc589_probe(struct pcmcia_device *link) | 196 | static int tc589_probe(struct pcmcia_device *link) |
| 192 | { | 197 | { |
| 193 | struct el3_private *lp; | 198 | struct el3_private *lp; |
| 194 | struct net_device *dev; | 199 | struct net_device *dev; |
| 195 | 200 | ||
| 196 | dev_dbg(&link->dev, "3c589_attach()\n"); | 201 | dev_dbg(&link->dev, "3c589_attach()\n"); |
| 197 | 202 | ||
| 198 | /* Create new ethernet device */ | 203 | /* Create new ethernet device */ |
| 199 | dev = alloc_etherdev(sizeof(struct el3_private)); | 204 | dev = alloc_etherdev(sizeof(struct el3_private)); |
| 200 | if (!dev) | 205 | if (!dev) |
| 201 | return -ENOMEM; | 206 | return -ENOMEM; |
| 202 | lp = netdev_priv(dev); | 207 | lp = netdev_priv(dev); |
| 203 | link->priv = dev; | 208 | link->priv = dev; |
| 204 | lp->p_dev = link; | 209 | lp->p_dev = link; |
| 205 | 210 | ||
| 206 | spin_lock_init(&lp->lock); | 211 | spin_lock_init(&lp->lock); |
| 207 | link->resource[0]->end = 16; | 212 | link->resource[0]->end = 16; |
| 208 | link->resource[0]->flags |= IO_DATA_PATH_WIDTH_16; | 213 | link->resource[0]->flags |= IO_DATA_PATH_WIDTH_16; |
| 209 | 214 | ||
| 210 | link->config_flags |= CONF_ENABLE_IRQ; | 215 | link->config_flags |= CONF_ENABLE_IRQ; |
| 211 | link->config_index = 1; | 216 | link->config_index = 1; |
| 212 | 217 | ||
| 213 | dev->netdev_ops = &el3_netdev_ops; | 218 | dev->netdev_ops = &el3_netdev_ops; |
| 214 | dev->watchdog_timeo = TX_TIMEOUT; | 219 | dev->watchdog_timeo = TX_TIMEOUT; |
| 215 | 220 | ||
| 216 | SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops); | 221 | SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops); |
| 217 | 222 | ||
| 218 | return tc589_config(link); | 223 | return tc589_config(link); |
| 219 | } | 224 | } |
| 220 | 225 | ||
| 221 | static void tc589_detach(struct pcmcia_device *link) | 226 | static void tc589_detach(struct pcmcia_device *link) |
| 222 | { | 227 | { |
| 223 | struct net_device *dev = link->priv; | 228 | struct net_device *dev = link->priv; |
| 224 | 229 | ||
| 225 | dev_dbg(&link->dev, "3c589_detach\n"); | 230 | dev_dbg(&link->dev, "3c589_detach\n"); |
| 226 | 231 | ||
| 227 | unregister_netdev(dev); | 232 | unregister_netdev(dev); |
| 228 | 233 | ||
| 229 | tc589_release(link); | 234 | tc589_release(link); |
| 230 | 235 | ||
| 231 | free_netdev(dev); | 236 | free_netdev(dev); |
| 232 | } /* tc589_detach */ | 237 | } /* tc589_detach */ |
| 233 | 238 | ||
| 234 | static int tc589_config(struct pcmcia_device *link) | 239 | static int tc589_config(struct pcmcia_device *link) |
| 235 | { | 240 | { |
| 236 | struct net_device *dev = link->priv; | 241 | struct net_device *dev = link->priv; |
| 237 | __be16 *phys_addr; | 242 | __be16 *phys_addr; |
| 238 | int ret, i, j, multi = 0, fifo; | 243 | int ret, i, j, multi = 0, fifo; |
| 239 | unsigned int ioaddr; | 244 | unsigned int ioaddr; |
| 240 | static const char * const ram_split[] = {"5:3", "3:1", "1:1", "3:5"}; | 245 | static const char * const ram_split[] = {"5:3", "3:1", "1:1", "3:5"}; |
| 241 | u8 *buf; | 246 | u8 *buf; |
| 242 | size_t len; | 247 | size_t len; |
| 243 | 248 | ||
| 244 | dev_dbg(&link->dev, "3c589_config\n"); | 249 | dev_dbg(&link->dev, "3c589_config\n"); |
| 245 | 250 | ||
| 246 | phys_addr = (__be16 *)dev->dev_addr; | 251 | phys_addr = (__be16 *)dev->dev_addr; |
| 247 | /* Is this a 3c562? */ | 252 | /* Is this a 3c562? */ |
| 248 | if (link->manf_id != MANFID_3COM) | 253 | if (link->manf_id != MANFID_3COM) |
| 249 | dev_info(&link->dev, "hmmm, is this really a 3Com card??\n"); | 254 | dev_info(&link->dev, "hmmm, is this really a 3Com card??\n"); |
| 250 | multi = (link->card_id == PRODID_3COM_3C562); | 255 | multi = (link->card_id == PRODID_3COM_3C562); |
| 251 | 256 | ||
| 252 | link->io_lines = 16; | 257 | link->io_lines = 16; |
| 253 | 258 | ||
| 254 | /* For the 3c562, the base address must be xx00-xx7f */ | 259 | /* For the 3c562, the base address must be xx00-xx7f */ |
| 255 | for (i = j = 0; j < 0x400; j += 0x10) { | 260 | for (i = j = 0; j < 0x400; j += 0x10) { |
| 256 | if (multi && (j & 0x80)) continue; | 261 | if (multi && (j & 0x80)) |
| 257 | link->resource[0]->start = j ^ 0x300; | 262 | continue; |
| 258 | i = pcmcia_request_io(link); | 263 | link->resource[0]->start = j ^ 0x300; |
| 259 | if (i == 0) | 264 | i = pcmcia_request_io(link); |
| 260 | break; | 265 | if (i == 0) |
| 261 | } | 266 | break; |
| 262 | if (i != 0) | ||
| 263 | goto failed; | ||
| 264 | |||
| 265 | ret = pcmcia_request_irq(link, el3_interrupt); | ||
| 266 | if (ret) | ||
| 267 | goto failed; | ||
| 268 | |||
| 269 | ret = pcmcia_enable_device(link); | ||
| 270 | if (ret) | ||
| 271 | goto failed; | ||
| 272 | |||
| 273 | dev->irq = link->irq; | ||
| 274 | dev->base_addr = link->resource[0]->start; | ||
| 275 | ioaddr = dev->base_addr; | ||
| 276 | EL3WINDOW(0); | ||
| 277 | |||
| 278 | /* The 3c589 has an extra EEPROM for configuration info, including | ||
| 279 | the hardware address. The 3c562 puts the address in the CIS. */ | ||
| 280 | len = pcmcia_get_tuple(link, 0x88, &buf); | ||
| 281 | if (buf && len >= 6) { | ||
| 282 | for (i = 0; i < 3; i++) | ||
| 283 | phys_addr[i] = htons(le16_to_cpu(buf[i*2])); | ||
| 284 | kfree(buf); | ||
| 285 | } else { | ||
| 286 | kfree(buf); /* 0 < len < 6 */ | ||
| 287 | for (i = 0; i < 3; i++) | ||
| 288 | phys_addr[i] = htons(read_eeprom(ioaddr, i)); | ||
| 289 | if (phys_addr[0] == htons(0x6060)) { | ||
| 290 | dev_err(&link->dev, "IO port conflict at 0x%03lx-0x%03lx\n", | ||
| 291 | dev->base_addr, dev->base_addr+15); | ||
| 292 | goto failed; | ||
| 293 | } | 267 | } |
| 294 | } | 268 | if (i != 0) |
| 295 | 269 | goto failed; | |
| 296 | /* The address and resource configuration register aren't loaded from | 270 | |
| 297 | the EEPROM and *must* be set to 0 and IRQ3 for the PCMCIA version. */ | 271 | ret = pcmcia_request_irq(link, el3_interrupt); |
| 298 | outw(0x3f00, ioaddr + 8); | 272 | if (ret) |
| 299 | fifo = inl(ioaddr); | 273 | goto failed; |
| 300 | 274 | ||
| 301 | /* The if_port symbol can be set when the module is loaded */ | 275 | ret = pcmcia_enable_device(link); |
| 302 | if ((if_port >= 0) && (if_port <= 3)) | 276 | if (ret) |
| 303 | dev->if_port = if_port; | 277 | goto failed; |
| 304 | else | 278 | |
| 305 | dev_err(&link->dev, "invalid if_port requested\n"); | 279 | dev->irq = link->irq; |
| 306 | 280 | dev->base_addr = link->resource[0]->start; | |
| 307 | SET_NETDEV_DEV(dev, &link->dev); | 281 | ioaddr = dev->base_addr; |
| 308 | 282 | EL3WINDOW(0); | |
| 309 | if (register_netdev(dev) != 0) { | 283 | |
| 310 | dev_err(&link->dev, "register_netdev() failed\n"); | 284 | /* The 3c589 has an extra EEPROM for configuration info, including |
| 311 | goto failed; | 285 | * the hardware address. The 3c562 puts the address in the CIS. |
| 312 | } | 286 | */ |
| 313 | 287 | len = pcmcia_get_tuple(link, 0x88, &buf); | |
| 314 | netdev_info(dev, "3Com 3c%s, io %#3lx, irq %d, hw_addr %pM\n", | 288 | if (buf && len >= 6) { |
| 315 | (multi ? "562" : "589"), dev->base_addr, dev->irq, | 289 | for (i = 0; i < 3; i++) |
| 316 | dev->dev_addr); | 290 | phys_addr[i] = htons(le16_to_cpu(buf[i*2])); |
| 317 | netdev_info(dev, " %dK FIFO split %s Rx:Tx, %s xcvr\n", | 291 | kfree(buf); |
| 318 | (fifo & 7) ? 32 : 8, ram_split[(fifo >> 16) & 3], | 292 | } else { |
| 319 | if_names[dev->if_port]); | 293 | kfree(buf); /* 0 < len < 6 */ |
| 320 | return 0; | 294 | for (i = 0; i < 3; i++) |
| 295 | phys_addr[i] = htons(read_eeprom(ioaddr, i)); | ||
| 296 | if (phys_addr[0] == htons(0x6060)) { | ||
| 297 | dev_err(&link->dev, "IO port conflict at 0x%03lx-0x%03lx\n", | ||
| 298 | dev->base_addr, dev->base_addr+15); | ||
| 299 | goto failed; | ||
| 300 | } | ||
| 301 | } | ||
| 302 | |||
| 303 | /* The address and resource configuration register aren't loaded from | ||
| 304 | * the EEPROM and *must* be set to 0 and IRQ3 for the PCMCIA version. | ||
| 305 | */ | ||
| 306 | |||
| 307 | outw(0x3f00, ioaddr + 8); | ||
| 308 | fifo = inl(ioaddr); | ||
| 309 | |||
| 310 | /* The if_port symbol can be set when the module is loaded */ | ||
| 311 | if ((if_port >= 0) && (if_port <= 3)) | ||
| 312 | dev->if_port = if_port; | ||
| 313 | else | ||
| 314 | dev_err(&link->dev, "invalid if_port requested\n"); | ||
| 315 | |||
| 316 | SET_NETDEV_DEV(dev, &link->dev); | ||
| 317 | |||
| 318 | if (register_netdev(dev) != 0) { | ||
| 319 | dev_err(&link->dev, "register_netdev() failed\n"); | ||
| 320 | goto failed; | ||
| 321 | } | ||
| 322 | |||
| 323 | netdev_info(dev, "3Com 3c%s, io %#3lx, irq %d, hw_addr %pM\n", | ||
| 324 | (multi ? "562" : "589"), dev->base_addr, dev->irq, | ||
| 325 | dev->dev_addr); | ||
| 326 | netdev_info(dev, " %dK FIFO split %s Rx:Tx, %s xcvr\n", | ||
| 327 | (fifo & 7) ? 32 : 8, ram_split[(fifo >> 16) & 3], | ||
| 328 | if_names[dev->if_port]); | ||
| 329 | return 0; | ||
| 321 | 330 | ||
| 322 | failed: | 331 | failed: |
| 323 | tc589_release(link); | 332 | tc589_release(link); |
| 324 | return -ENODEV; | 333 | return -ENODEV; |
| 325 | } /* tc589_config */ | 334 | } /* tc589_config */ |
| 326 | 335 | ||
| 327 | static void tc589_release(struct pcmcia_device *link) | 336 | static void tc589_release(struct pcmcia_device *link) |
| @@ -353,113 +362,120 @@ static int tc589_resume(struct pcmcia_device *link) · 25 unmodified lines | |||
| 353 | 362 | ||
| 354 | /*====================================================================*/ | 363 | /*====================================================================*/ |
| 355 | 364 | ||
| 356 | /* | 365 | /* Use this for commands that may take time to finish */ |
| 357 | Use this for commands that may take time to finish | 366 | |
| 358 | */ | ||
| 359 | static void tc589_wait_for_completion(struct net_device *dev, int cmd) | 367 | static void tc589_wait_for_completion(struct net_device *dev, int cmd) |
| 360 | { | 368 | { |
| 361 | int i = 100; | 369 | int i = 100; |
| 362 | outw(cmd, dev->base_addr + EL3_CMD); | 370 | outw(cmd, dev->base_addr + EL3_CMD); |
| 363 | while (--i > 0) | 371 | while (--i > 0) |
| 364 | if (!(inw(dev->base_addr + EL3_STATUS) & 0x1000)) break; | 372 | if (!(inw(dev->base_addr + EL3_STATUS) & 0x1000)) |
| 365 | if (i == 0) | 373 | break; |
| 366 | netdev_warn(dev, "command 0x%04x did not complete!\n", cmd); | 374 | if (i == 0) |
| 375 | netdev_warn(dev, "command 0x%04x did not complete!\n", cmd); | ||
| 367 | } | 376 | } |
| 368 | 377 | ||
| 369 | /* | 378 | /* Read a word from the EEPROM using the regular EEPROM access register. |
| 370 | Read a word from the EEPROM using the regular EEPROM access register. | 379 | * Assume that we are in register window zero. |
| 371 | Assume that we are in register window zero. | 380 | */ |
| 372 | */ | 381 | |
| 373 | static u16 read_eeprom(unsigned int ioaddr, int index) | 382 | static u16 read_eeprom(unsigned int ioaddr, int index) |
| 374 | { | 383 | { |
| 375 | int i; | 384 | int i; |
| 376 | outw(EEPROM_READ + index, ioaddr + 10); | 385 | outw(EEPROM_READ + index, ioaddr + 10); |
| 377 | /* Reading the eeprom takes 162 us */ | 386 | /* Reading the eeprom takes 162 us */ |
| 378 | for (i = 1620; i >= 0; i--) | 387 | for (i = 1620; i >= 0; i--) |
| 379 | if ((inw(ioaddr + 10) & EEPROM_BUSY) == 0) | 388 | if ((inw(ioaddr + 10) & EEPROM_BUSY) == 0) |
| 380 | break; | 389 | break; |
| 381 | return inw(ioaddr + 12); | 390 | return inw(ioaddr + 12); |
| 382 | } | 391 | } |
| 383 | 392 | ||
| 384 | /* | 393 | /* Set transceiver type, perhaps to something other than what the user |
| 385 | Set transceiver type, perhaps to something other than what the user | 394 | * specified in dev->if_port. |
| 386 | specified in dev->if_port. | 395 | */ |
| 387 | */ | 396 | |
| 388 | static void tc589_set_xcvr(struct net_device *dev, int if_port) | 397 | static void tc589_set_xcvr(struct net_device *dev, int if_port) |
| 389 | { | 398 | { |
| 390 | struct el3_private *lp = netdev_priv(dev); | 399 | struct el3_private *lp = netdev_priv(dev); |
| 391 | unsigned int ioaddr = dev->base_addr; | 400 | unsigned int ioaddr = dev->base_addr; |
| 392 | 401 | ||
| 393 | EL3WINDOW(0); | 402 | EL3WINDOW(0); |
| 394 | switch (if_port) { | 403 | switch (if_port) { |
| 395 | case 0: case 1: outw(0, ioaddr + 6); break; | 404 | case 0: |
| 396 | case 2: outw(3<<14, ioaddr + 6); break; | 405 | case 1: |
| 397 | case 3: outw(1<<14, ioaddr + 6); break; | 406 | outw(0, ioaddr + 6); |
| 398 | } | 407 | break; |
| 399 | /* On PCMCIA, this just turns on the LED */ | 408 | case 2: |
| 400 | outw((if_port == 2) ? StartCoax : StopCoax, ioaddr + EL3_CMD); | 409 | outw(3<<14, ioaddr + 6); |
| 401 | /* 10baseT interface, enable link beat and jabber check. */ | 410 | break; |
| 402 | EL3WINDOW(4); | 411 | case 3: |
| 403 | outw(MEDIA_LED | ((if_port < 2) ? MEDIA_TP : 0), ioaddr + WN4_MEDIA); | 412 | outw(1<<14, ioaddr + 6); |
| 404 | EL3WINDOW(1); | 413 | break; |
| 405 | if (if_port == 2) | 414 | } |
| 406 | lp->media_status = ((dev->if_port == 0) ? 0x8000 : 0x4000); | 415 | /* On PCMCIA, this just turns on the LED */ |
| 407 | else | 416 | outw((if_port == 2) ? StartCoax : StopCoax, ioaddr + EL3_CMD); |
| 408 | lp->media_status = ((dev->if_port == 0) ? 0x4010 : 0x8800); | 417 | /* 10baseT interface, enable link beat and jabber check. */ |
| 418 | EL3WINDOW(4); | ||
| 419 | outw(MEDIA_LED | ((if_port < 2) ? MEDIA_TP : 0), ioaddr + WN4_MEDIA); | ||
| 420 | EL3WINDOW(1); | ||
| 421 | if (if_port == 2) | ||
| 422 | lp->media_status = ((dev->if_port == 0) ? 0x8000 : 0x4000); | ||
| 423 | else | ||
| 424 | lp->media_status = ((dev->if_port == 0) ? 0x4010 : 0x8800); | ||
| 409 | } | 425 | } |
| 410 | 426 | ||
| 411 | static void dump_status(struct net_device *dev) | 427 | static void dump_status(struct net_device *dev) |
| 412 | { | 428 | { |
| 413 | unsigned int ioaddr = dev->base_addr; | 429 | unsigned int ioaddr = dev->base_addr; |
| 414 | EL3WINDOW(1); | 430 | EL3WINDOW(1); |
| 415 | netdev_info(dev, " irq status %04x, rx status %04x, tx status %02x tx free %04x\n", | 431 | netdev_info(dev, " irq status %04x, rx status %04x, tx status %02x tx free %04x\n", |
| 416 | inw(ioaddr+EL3_STATUS), inw(ioaddr+RX_STATUS), | 432 | inw(ioaddr+EL3_STATUS), inw(ioaddr+RX_STATUS), |
| 417 | inb(ioaddr+TX_STATUS), inw(ioaddr+TX_FREE)); | 433 | inb(ioaddr+TX_STATUS), inw(ioaddr+TX_FREE)); |
| 418 | EL3WINDOW(4); | 434 | EL3WINDOW(4); |
| 419 | netdev_info(dev, " diagnostics: fifo %04x net %04x ethernet %04x media %04x\n", | 435 | netdev_info(dev, " diagnostics: fifo %04x net %04x ethernet %04x media %04x\n", |
| 420 | inw(ioaddr+0x04), inw(ioaddr+0x06), inw(ioaddr+0x08), | 436 | inw(ioaddr+0x04), inw(ioaddr+0x06), inw(ioaddr+0x08), |
| 421 | inw(ioaddr+0x0a)); | 437 | inw(ioaddr+0x0a)); |
| 422 | EL3WINDOW(1); | 438 | EL3WINDOW(1); |
| 423 | } | 439 | } |
| 424 | 440 | ||
| 425 | /* Reset and restore all of the 3c589 registers. */ | 441 | /* Reset and restore all of the 3c589 registers. */ |
| 426 | static void tc589_reset(struct net_device *dev) | 442 | static void tc589_reset(struct net_device *dev) |
| 427 | { | 443 | { |
| 428 | unsigned int ioaddr = dev->base_addr; | 444 | unsigned int ioaddr = dev->base_addr; |
| 429 | int i; | 445 | int i; |
| 430 | 446 | ||
| 431 | EL3WINDOW(0); | 447 | EL3WINDOW(0); |
| 432 | outw(0x0001, ioaddr + 4); /* Activate board. */ | 448 | outw(0x0001, ioaddr + 4); /* Activate board. */ |
| 433 | outw(0x3f00, ioaddr + 8); /* Set the IRQ line. */ | 449 | outw(0x3f00, ioaddr + 8); /* Set the IRQ line. */ |
| 434 | 450 | ||
| 435 | /* Set the station address in window 2. */ | 451 | /* Set the station address in window 2. */ |
| 436 | EL3WINDOW(2); | 452 | EL3WINDOW(2); |
| 437 | for (i = 0; i < 6; i++) | 453 | for (i = 0; i < 6; i++) |
| 438 | outb(dev->dev_addr[i], ioaddr + i); | 454 | outb(dev->dev_addr[i], ioaddr + i); |
| 439 | 455 | ||
| 440 | tc589_set_xcvr(dev, dev->if_port); | 456 | tc589_set_xcvr(dev, dev->if_port); |
| 441 | 457 | ||
| 442 | /* Switch to the stats window, and clear all stats by reading. */ | 458 | /* Switch to the stats window, and clear all stats by reading. */ |
| 443 | outw(StatsDisable, ioaddr + EL3_CMD); | 459 | outw(StatsDisable, ioaddr + EL3_CMD); |
| 444 | EL3WINDOW(6); | 460 | EL3WINDOW(6); |
| 445 | for (i = 0; i < 9; i++) | 461 | for (i = 0; i < 9; i++) |
| 446 | inb(ioaddr+i); | 462 | inb(ioaddr+i); |
| 447 | inw(ioaddr + 10); | 463 | inw(ioaddr + 10); |
| 448 | inw(ioaddr + 12); | 464 | inw(ioaddr + 12); |
| 449 | 465 | ||
| 450 | /* Switch to register set 1 for normal use. */ | 466 | /* Switch to register set 1 for normal use. */ |
| 451 | EL3WINDOW(1); | 467 | EL3WINDOW(1); |
| 452 | 468 | ||
| 453 | set_rx_mode(dev); | 469 | set_rx_mode(dev); |
| 454 | outw(StatsEnable, ioaddr + EL3_CMD); /* Turn on statistics. */ | 470 | outw(StatsEnable, ioaddr + EL3_CMD); /* Turn on statistics. */ |
| 455 | outw(RxEnable, ioaddr + EL3_CMD); /* Enable the receiver. */ | 471 | outw(RxEnable, ioaddr + EL3_CMD); /* Enable the receiver. */ |
| 456 | outw(TxEnable, ioaddr + EL3_CMD); /* Enable transmitter. */ | 472 | outw(TxEnable, ioaddr + EL3_CMD); /* Enable transmitter. */ |
| 457 | /* Allow status bits to be seen. */ | 473 | /* Allow status bits to be seen. */ |
| 458 | outw(SetStatusEnb | 0xff, ioaddr + EL3_CMD); | 474 | outw(SetStatusEnb | 0xff, ioaddr + EL3_CMD); |
| 459 | /* Ack all pending events, and set active indicator mask. */ | 475 | /* Ack all pending events, and set active indicator mask. */ |
| 460 | outw(AckIntr | IntLatch | TxAvailable | RxEarly | IntReq, | 476 | outw(AckIntr | IntLatch | TxAvailable | RxEarly | IntReq, |
| 461 | ioaddr + EL3_CMD); | 477 | ioaddr + EL3_CMD); |
| 462 | outw(SetIntrEnb | IntLatch | TxAvailable | RxComplete | StatsFull | 478 | outw(SetIntrEnb | IntLatch | TxAvailable | RxComplete | StatsFull |
| 463 | | AdapterFailure, ioaddr + EL3_CMD); | 479 | | AdapterFailure, ioaddr + EL3_CMD); |
| 464 | } | 480 | } |
| 465 | 481 | ||
| @@ -478,381 +494,406 @@ static const struct ethtool_ops netdev_ethtool_ops = { · 12 unmodified lines | |||
| 478 | 494 | ||
| 479 | static int el3_config(struct net_device *dev, struct ifmap *map) | 495 | static int el3_config(struct net_device *dev, struct ifmap *map) |
| 480 | { | 496 | { |
| 481 | if ((map->port != (u_char)(-1)) && (map->port != dev->if_port)) { | 497 | if ((map->port != (u_char)(-1)) && (map->port != dev->if_port)) { |
| 482 | if (map->port <= 3) { | 498 | if (map->port <= 3) { |
| 483 | dev->if_port = map->port; | 499 | dev->if_port = map->port; |
| 484 | netdev_info(dev, "switched to %s port\n", if_names[dev->if_port]); | 500 | netdev_info(dev, "switched to %s port\n", if_names[dev->if_port]); |
| 485 | tc589_set_xcvr(dev, dev->if_port); | 501 | tc589_set_xcvr(dev, dev->if_port); |
| 486 | } else | 502 | } else { |
| 487 | return -EINVAL; | 503 | return -EINVAL; |
| 488 | } | 504 | } |
| 489 | return 0; | 505 | } |
| 506 | return 0; | ||
| 490 | } | 507 | } |
| 491 | 508 | ||
| 492 | static int el3_open(struct net_device *dev) | 509 | static int el3_open(struct net_device *dev) |
| 493 | { | 510 | { |
| 494 | struct el3_private *lp = netdev_priv(dev); | 511 | struct el3_private *lp = netdev_priv(dev); |
| 495 | struct pcmcia_device *link = lp->p_dev; | 512 | struct pcmcia_device *link = lp->p_dev; |
| 496 | 513 | ||
| 497 | if (!pcmcia_dev_present(link)) | 514 | if (!pcmcia_dev_present(link)) |
| 498 | return -ENODEV; | 515 | return -ENODEV; |
| 499 | 516 | ||
| 500 | link->open++; | 517 | link->open++; |
| 501 | netif_start_queue(dev); | 518 | netif_start_queue(dev); |
| 502 | 519 | ||
| 503 | tc589_reset(dev); | 520 | tc589_reset(dev); |
| 504 | init_timer(&lp->media); | 521 | init_timer(&lp->media); |
| 505 | lp->media.function = media_check; | 522 | lp->media.function = media_check; |
| 506 | lp->media.data = (unsigned long) dev; | 523 | lp->media.data = (unsigned long) dev; |
| 507 | lp->media.expires = jiffies + HZ; | 524 | lp->media.expires = jiffies + HZ; |
| 508 | add_timer(&lp->media); | 525 | add_timer(&lp->media); |
| 509 | 526 | ||
| 510 | dev_dbg(&link->dev, "%s: opened, status %4.4x.\n", | 527 | dev_dbg(&link->dev, "%s: opened, status %4.4x.\n", |
| 511 | dev->name, inw(dev->base_addr + EL3_STATUS)); | 528 | dev->name, inw(dev->base_addr + EL3_STATUS)); |
| 512 | 529 | ||
| 513 | return 0; | 530 | return 0; |
| 514 | } | 531 | } |
| 515 | 532 | ||
| 516 | static void el3_tx_timeout(struct net_device *dev) | 533 | static void el3_tx_timeout(struct net_device *dev) |
| 517 | { | 534 | { |
| 518 | unsigned int ioaddr = dev->base_addr; | 535 | unsigned int ioaddr = dev->base_addr; |
| 519 | 536 | ||
| 520 | netdev_warn(dev, "Transmit timed out!\n"); | 537 | netdev_warn(dev, "Transmit timed out!\n"); |
| 521 | dump_status(dev); | 538 | dump_status(dev); |
| 522 | dev->stats.tx_errors++; | 539 | dev->stats.tx_errors++; |
| 523 | dev->trans_start = jiffies; /* prevent tx timeout */ | 540 | dev->trans_start = jiffies; /* prevent tx timeout */ |
| 524 | /* Issue TX_RESET and TX_START commands. */ | 541 | /* Issue TX_RESET and TX_START commands. */ |
| 525 | tc589_wait_for_completion(dev, TxReset); | 542 | tc589_wait_for_completion(dev, TxReset); |
| 526 | outw(TxEnable, ioaddr + EL3_CMD); | 543 | outw(TxEnable, ioaddr + EL3_CMD); |
| 527 | netif_wake_queue(dev); | 544 | netif_wake_queue(dev); |
| 528 | } | 545 | } |
| 529 | 546 | ||
| 530 | static void pop_tx_status(struct net_device *dev) | 547 | static void pop_tx_status(struct net_device *dev) |
| 531 | { | 548 | { |
| 532 | unsigned int ioaddr = dev->base_addr; | 549 | unsigned int ioaddr = dev->base_addr; |
| 533 | int i; | 550 | int i; |
| 534 | 551 | ||
| 535 | /* Clear the Tx status stack. */ | 552 | /* Clear the Tx status stack. */ |
| 536 | for (i = 32; i > 0; i--) { | 553 | for (i = 32; i > 0; i--) { |
| 537 | u_char tx_status = inb(ioaddr + TX_STATUS); | 554 | u_char tx_status = inb(ioaddr + TX_STATUS); |
| 538 | if (!(tx_status & 0x84)) break; | 555 | if (!(tx_status & 0x84)) |
| 539 | /* reset transmitter on jabber error or underrun */ | 556 | break; |
| 540 | if (tx_status & 0x30) | 557 | /* reset transmitter on jabber error or underrun */ |
| 541 | tc589_wait_for_completion(dev, TxReset); | 558 | if (tx_status & 0x30) |
| 542 | if (tx_status & 0x38) { | 559 | tc589_wait_for_completion(dev, TxReset); |
| 543 | netdev_dbg(dev, "transmit error: status 0x%02x\n", tx_status); | 560 | if (tx_status & 0x38) { |
| 544 | outw(TxEnable, ioaddr + EL3_CMD); | 561 | netdev_dbg(dev, "transmit error: status 0x%02x\n", tx_status); |
| 545 | dev->stats.tx_aborted_errors++; | 562 | outw(TxEnable, ioaddr + EL3_CMD); |
| 563 | dev->stats.tx_aborted_errors++; | ||
| 564 | } | ||
| 565 | outb(0x00, ioaddr + TX_STATUS); /* Pop the status stack. */ | ||
| 546 | } | 566 | } |
| 547 | outb(0x00, ioaddr + TX_STATUS); /* Pop the status stack. */ | ||
| 548 | } | ||
| 549 | } | 567 | } |
| 550 | 568 | ||
| 551 | static netdev_tx_t el3_start_xmit(struct sk_buff *skb, | 569 | static netdev_tx_t el3_start_xmit(struct sk_buff *skb, |
| 552 | struct net_device *dev) | 570 | struct net_device *dev) |
| 553 | { | 571 | { |
| 554 | unsigned int ioaddr = dev->base_addr; | 572 | unsigned int ioaddr = dev->base_addr; |
| 555 | struct el3_private *priv = netdev_priv(dev); | 573 | struct el3_private *priv = netdev_priv(dev); |
| 556 | unsigned long flags; | 574 | unsigned long flags; |
| 557 | 575 | ||
| 558 | netdev_dbg(dev, "el3_start_xmit(length = %ld) called, status %4.4x.\n", | 576 | netdev_dbg(dev, "el3_start_xmit(length = %ld) called, status %4.4x.\n", |
| 559 | (long)skb->len, inw(ioaddr + EL3_STATUS)); | 577 | (long)skb->len, inw(ioaddr + EL3_STATUS)); |
| 560 | 578 | ||
| 561 | spin_lock_irqsave(&priv->lock, flags); | 579 | spin_lock_irqsave(&priv->lock, flags); |
| 562 | 580 | ||
| 563 | dev->stats.tx_bytes += skb->len; | 581 | dev->stats.tx_bytes += skb->len; |
| 564 | 582 | ||
| 565 | /* Put out the doubleword header... */ | 583 | /* Put out the doubleword header... */ |
| 566 | outw(skb->len, ioaddr + TX_FIFO); | 584 | outw(skb->len, ioaddr + TX_FIFO); |
| 567 | outw(0x00, ioaddr + TX_FIFO); | 585 | outw(0x00, ioaddr + TX_FIFO); |
| 568 | /* ... and the packet rounded to a doubleword. */ | 586 | /* ... and the packet rounded to a doubleword. */ |
| 569 | outsl(ioaddr + TX_FIFO, skb->data, (skb->len + 3) >> 2); | 587 | outsl(ioaddr + TX_FIFO, skb->data, (skb->len + 3) >> 2); |
| 570 | 588 | ||
| 571 | if (inw(ioaddr + TX_FREE) <= 1536) { | 589 | if (inw(ioaddr + TX_FREE) <= 1536) { |
| 572 | netif_stop_queue(dev); | 590 | netif_stop_queue(dev); |
| 573 | /* Interrupt us when the FIFO has room for max-sized packet. */ | 591 | /* Interrupt us when the FIFO has room for max-sized packet. */ |
| 574 | outw(SetTxThreshold + 1536, ioaddr + EL3_CMD); | 592 | outw(SetTxThreshold + 1536, ioaddr + EL3_CMD); |
| 575 | } | 593 | } |
| 576 | 594 | ||
| 577 | pop_tx_status(dev); | 595 | pop_tx_status(dev); |
| 578 | spin_unlock_irqrestore(&priv->lock, flags); | 596 | spin_unlock_irqrestore(&priv->lock, flags); |
| 579 | dev_kfree_skb(skb); | 597 | dev_kfree_skb(skb); |
| 580 | 598 | ||
| 581 | return NETDEV_TX_OK; | 599 | return NETDEV_TX_OK; |
| 582 | } | 600 | } |
| 583 | 601 | ||
| 584 | /* The EL3 interrupt handler. */ | 602 | /* The EL3 interrupt handler. */ |
| 585 | static irqreturn_t el3_interrupt(int irq, void *dev_id) | 603 | static irqreturn_t el3_interrupt(int irq, void *dev_id) |
| 586 | { | 604 | { |
| 587 | struct net_device *dev = (struct net_device *) dev_id; | 605 | struct net_device *dev = (struct net_device *) dev_id; |
| 588 | struct el3_private *lp = netdev_priv(dev); | 606 | struct el3_private *lp = netdev_priv(dev); |
| 589 | unsigned int ioaddr; | 607 | unsigned int ioaddr; |
| 590 | __u16 status; | 608 | __u16 status; |
| 591 | int i = 0, handled = 1; | 609 | int i = 0, handled = 1; |
| 592 | 610 | ||
| 593 | if (!netif_device_present(dev)) | 611 | if (!netif_device_present(dev)) |
| 594 | return IRQ_NONE; | 612 | return IRQ_NONE; |
| 595 | 613 | ||
| 596 | ioaddr = dev->base_addr; | 614 | ioaddr = dev->base_addr; |
| 597 | 615 | ||
| 598 | netdev_dbg(dev, "interrupt, status %4.4x.\n", inw(ioaddr + EL3_STATUS)); | 616 | netdev_dbg(dev, "interrupt, status %4.4x.\n", inw(ioaddr + EL3_STATUS)); |
| 599 | 617 | ||
| 600 | spin_lock(&lp->lock); | 618 | spin_lock(&lp->lock); |
| 601 | while ((status = inw(ioaddr + EL3_STATUS)) & | 619 | while ((status = inw(ioaddr + EL3_STATUS)) & |
| 602 | (IntLatch | RxComplete | StatsFull)) { | 620 | (IntLatch | RxComplete | StatsFull)) { |
| 603 | if ((status & 0xe000) != 0x2000) { | 621 | if ((status & 0xe000) != 0x2000) { |
| 604 | netdev_dbg(dev, "interrupt from dead card\n"); | 622 | netdev_dbg(dev, "interrupt from dead card\n"); |
| 605 | handled = 0; | 623 | handled = 0; |
| 606 | break; | 624 | break; |
| 607 | } | 625 | } |
| 608 | if (status & RxComplete) | 626 | if (status & RxComplete) |
| 609 | el3_rx(dev); | 627 | el3_rx(dev); |
| 610 | if (status & TxAvailable) { | 628 | if (status & TxAvailable) { |
| 611 | netdev_dbg(dev, " TX room bit was handled.\n"); | 629 | netdev_dbg(dev, " TX room bit was handled.\n"); |
| 612 | /* There's room in the FIFO for a full-sized packet. */ | 630 | /* There's room in the FIFO for a full-sized packet. */ |
| 613 | outw(AckIntr | TxAvailable, ioaddr + EL3_CMD); | 631 | outw(AckIntr | TxAvailable, ioaddr + EL3_CMD); |
| 614 | netif_wake_queue(dev); | 632 | netif_wake_queue(dev); |
| 615 | } | 633 | } |
| 616 | if (status & TxComplete) | 634 | if (status & TxComplete) |
| 617 | pop_tx_status(dev); | 635 | pop_tx_status(dev); |
| 618 | if (status & (AdapterFailure | RxEarly | StatsFull)) { | 636 | if (status & (AdapterFailure | RxEarly | StatsFull)) { |
| 619 | /* Handle all uncommon interrupts. */ | 637 | /* Handle all uncommon interrupts. */ |
| 620 | if (status & StatsFull) /* Empty statistics. */ | 638 | if (status & StatsFull) /* Empty statistics. */ |
| 621 | update_stats(dev); | 639 | update_stats(dev); |
| 622 | if (status & RxEarly) { /* Rx early is unused. */ | 640 | if (status & RxEarly) { |
| 623 | el3_rx(dev); | 641 | /* Rx early is unused. */ |
| 624 | outw(AckIntr | RxEarly, ioaddr + EL3_CMD); | 642 | el3_rx(dev); |
| 625 | } | 643 | outw(AckIntr | RxEarly, ioaddr + EL3_CMD); |
| 626 | if (status & AdapterFailure) { | 644 | } |
| 627 | u16 fifo_diag; | 645 | if (status & AdapterFailure) { |
| 628 | EL3WINDOW(4); | 646 | u16 fifo_diag; |
| 629 | fifo_diag = inw(ioaddr + 4); | 647 | EL3WINDOW(4); |
| 630 | EL3WINDOW(1); | 648 | fifo_diag = inw(ioaddr + 4); |
| 631 | netdev_warn(dev, "adapter failure, FIFO diagnostic register %04x.\n", | 649 | EL3WINDOW(1); |
| 650 | netdev_warn(dev, "adapter failure, FIFO diagnostic register %04x.\n", | ||
| 632 | fifo_diag); | 651 | fifo_diag); |
| 633 | if (fifo_diag & 0x0400) { | 652 | if (fifo_diag & 0x0400) { |
| 634 | /* Tx overrun */ | 653 | /* Tx overrun */ |
| 635 | tc589_wait_for_completion(dev, TxReset); | 654 | tc589_wait_for_completion(dev, TxReset); |
| 636 | outw(TxEnable, ioaddr + EL3_CMD); | 655 | outw(TxEnable, ioaddr + EL3_CMD); |
| 656 | } | ||
| 657 | if (fifo_diag & 0x2000) { | ||
| 658 | /* Rx underrun */ | ||
| 659 | tc589_wait_for_completion(dev, RxReset); | ||
| 660 | set_rx_mode(dev); | ||
| 661 | outw(RxEnable, ioaddr + EL3_CMD); | ||
| 662 | } | ||
| 663 | outw(AckIntr | AdapterFailure, ioaddr + EL3_CMD); | ||
| 664 | } | ||
| 637 | } | 665 | } |
| 638 | if (fifo_diag & 0x2000) { | 666 | if (++i > 10) { |
| 639 | /* Rx underrun */ | 667 | netdev_err(dev, "infinite loop in interrupt, status %4.4x.\n", |
| 640 | tc589_wait_for_completion(dev, RxReset); | 668 | status); |
| 641 | set_rx_mode(dev); | 669 | /* Clear all interrupts */ |
| 642 | outw(RxEnable, ioaddr + EL3_CMD); | 670 | outw(AckIntr | 0xFF, ioaddr + EL3_CMD); |
| 671 | break; | ||
| 643 | } | 672 | } |
| 644 | outw(AckIntr | AdapterFailure, ioaddr + EL3_CMD); | 673 | /* Acknowledge the IRQ. */ |
| 645 | } | 674 | outw(AckIntr | IntReq | IntLatch, ioaddr + EL3_CMD); |
| 646 | } | 675 | } |
| 647 | if (++i > 10) { | 676 | lp->last_irq = jiffies; |
| 648 | netdev_err(dev, "infinite loop in interrupt, status %4.4x.\n", | 677 | spin_unlock(&lp->lock); |
| 649 | status); | 678 | netdev_dbg(dev, "exiting interrupt, status %4.4x.\n", |
| 650 | /* Clear all interrupts */ | 679 | inw(ioaddr + EL3_STATUS)); |
| 651 | outw(AckIntr | 0xFF, ioaddr + EL3_CMD); | 680 | return IRQ_RETVAL(handled); |
| 652 | break; | ||
| 653 | } | ||
| 654 | /* Acknowledge the IRQ. */ | ||
| 655 | outw(AckIntr | IntReq | IntLatch, ioaddr + EL3_CMD); | ||
| 656 | } | ||
| 657 | lp->last_irq = jiffies; | ||
| 658 | spin_unlock(&lp->lock); | ||
| 659 | netdev_dbg(dev, "exiting interrupt, status %4.4x.\n", | ||
| 660 | inw(ioaddr + EL3_STATUS)); | ||
| 661 | return IRQ_RETVAL(handled); | ||
| 662 | } | 681 | } |
| 663 | 682 | ||
| 664 | static void media_check(unsigned long arg) | 683 | static void media_check(unsigned long arg) |
| 665 | { | 684 | { |
| 666 | struct net_device *dev = (struct net_device *)(arg); | 685 | struct net_device *dev = (struct net_device *)(arg); |
| 667 | struct el3_private *lp = netdev_priv(dev); | 686 | struct el3_private *lp = netdev_priv(dev); |
| 668 | unsigned int ioaddr = dev->base_addr; | 687 | unsigned int ioaddr = dev->base_addr; |
| 669 | u16 media, errs; | 688 | u16 media, errs; |
| 670 | unsigned long flags; | 689 | unsigned long flags; |
| 671 | 690 | ||
| 672 | if (!netif_device_present(dev)) goto reschedule; | 691 | if (!netif_device_present(dev)) |
| 692 | goto reschedule; | ||
| 673 | 693 | ||
| 674 | /* Check for pending interrupt with expired latency timer: with | 694 | /* Check for pending interrupt with expired latency timer: with |
| 675 | this, we can limp along even if the interrupt is blocked */ | 695 | * this, we can limp along even if the interrupt is blocked |
| 676 | if ((inw(ioaddr + EL3_STATUS) & IntLatch) && | 696 | */ |
| 697 | if ((inw(ioaddr + EL3_STATUS) & IntLatch) && | ||
| 677 | (inb(ioaddr + EL3_TIMER) == 0xff)) { | 698 | (inb(ioaddr + EL3_TIMER) == 0xff)) { |
| 678 | if (!lp->fast_poll) | 699 | if (!lp->fast_poll) |
| 679 | netdev_warn(dev, "interrupt(s) dropped!\n"); | 700 | netdev_warn(dev, "interrupt(s) dropped!\n"); |
| 680 | 701 | ||
| 681 | local_irq_save(flags); | 702 | local_irq_save(flags); |
| 682 | el3_interrupt(dev->irq, dev); | 703 | el3_interrupt(dev->irq, dev); |
| 683 | local_irq_restore(flags); | 704 | local_irq_restore(flags); |
| 684 | 705 | ||
| 685 | lp->fast_poll = HZ; | 706 | lp->fast_poll = HZ; |
| 686 | } | 707 | } |
| 687 | if (lp->fast_poll) { | 708 | if (lp->fast_poll) { |
| 688 | lp->fast_poll--; | 709 | lp->fast_poll--; |
| 689 | lp->media.expires = jiffies + HZ/100; | 710 | lp->media.expires = jiffies + HZ/100; |
| 690 | add_timer(&lp->media); | 711 | add_timer(&lp->media); |
| 691 | return; | 712 | return; |
| 692 | } | 713 | } |
| 693 | 714 | ||
| 694 | /* lp->lock guards the EL3 window. Window should always be 1 except | 715 | /* lp->lock guards the EL3 window. Window should always be 1 except |
| 695 | when the lock is held */ | 716 | * when the lock is held |
| 696 | spin_lock_irqsave(&lp->lock, flags); | 717 | */ |
| 697 | EL3WINDOW(4); | 718 | |
| 698 | media = inw(ioaddr+WN4_MEDIA) & 0xc810; | 719 | spin_lock_irqsave(&lp->lock, flags); |
| 699 | 720 | EL3WINDOW(4); | |
| 700 | /* Ignore collisions unless we've had no irq's recently */ | 721 | media = inw(ioaddr+WN4_MEDIA) & 0xc810; |
| 701 | if (time_before(jiffies, lp->last_irq + HZ)) { | 722 | |
| 702 | media &= ~0x0010; | 723 | /* Ignore collisions unless we've had no irq's recently */ |
| 703 | } else { | 724 | if (time_before(jiffies, lp->last_irq + HZ)) { |
| 704 | /* Try harder to detect carrier errors */ | 725 | media &= ~0x0010; |
| 705 | EL3WINDOW(6); | 726 | } else { |
| 706 | outw(StatsDisable, ioaddr + EL3_CMD); | 727 | /* Try harder to detect carrier errors */ |
| 707 | errs = inb(ioaddr + 0); | 728 | EL3WINDOW(6); |
| 708 | outw(StatsEnable, ioaddr + EL3_CMD); | 729 | outw(StatsDisable, ioaddr + EL3_CMD); |
| 709 | dev->stats.tx_carrier_errors += errs; | 730 | errs = inb(ioaddr + 0); |
| 710 | if (errs || (lp->media_status & 0x0010)) media |= 0x0010; | 731 | outw(StatsEnable, ioaddr + EL3_CMD); |
| 711 | } | 732 | dev->stats.tx_carrier_errors += errs; |
| 733 | if (errs || (lp->media_status & 0x0010)) | ||
| 734 | media |= 0x0010; | ||
| 735 | } | ||
| 712 | 736 | ||
| 713 | if (media != lp->media_status) { | 737 | if (media != lp->media_status) { |
| 714 | if ((media & lp->media_status & 0x8000) && | 738 | if ((media & lp->media_status & 0x8000) && |
| 715 | ((lp->media_status ^ media) & 0x0800)) | 739 | ((lp->media_status ^ media) & 0x0800)) |
| 716 | netdev_info(dev, "%s link beat\n", | 740 | netdev_info(dev, "%s link beat\n", |
| 717 | (lp->media_status & 0x0800 ? "lost" : "found")); | 741 | (lp->media_status & 0x0800 ? "lost" : "found")); |
| 718 | else if ((media & lp->media_status & 0x4000) && | 742 | else if ((media & lp->media_status & 0x4000) && |
| 719 | ((lp->media_status ^ media) & 0x0010)) | 743 | ((lp->media_status ^ media) & 0x0010)) |
| 720 | netdev_info(dev, "coax cable %s\n", | 744 | netdev_info(dev, "coax cable %s\n", |
| 721 | (lp->media_status & 0x0010 ? "ok" : "problem")); | 745 | (lp->media_status & 0x0010 ? "ok" : "problem")); |
| 722 | if (dev->if_port == 0) { | 746 | if (dev->if_port == 0) { |
| 723 | if (media & 0x8000) { | 747 | if (media & 0x8000) { |
| 724 | if (media & 0x0800) | 748 | if (media & 0x0800) |
| 725 | netdev_info(dev, "flipped to 10baseT\n"); | 749 | netdev_info(dev, "flipped to 10baseT\n"); |
| 726 | else | 750 | else |
| 727 | tc589_set_xcvr(dev, 2); | 751 | tc589_set_xcvr(dev, 2); |
| 728 | } else if (media & 0x4000) { | 752 | } else if (media & 0x4000) { |
| 729 | if (media & 0x0010) | 753 | if (media & 0x0010) |
| 730 | tc589_set_xcvr(dev, 1); | 754 | tc589_set_xcvr(dev, 1); |
| 731 | else | 755 | else |
| 732 | netdev_info(dev, "flipped to 10base2\n"); | 756 | netdev_info(dev, "flipped to 10base2\n"); |
| 733 | } | 757 | } |
| 758 | } | ||
| 759 | lp->media_status = media; | ||
| 734 | } | 760 | } |
| 735 | lp->media_status = media; | ||
| 736 | } | ||
| 737 | 761 | ||
| 738 | EL3WINDOW(1); | 762 | EL3WINDOW(1); |
| 739 | spin_unlock_irqrestore(&lp->lock, flags); | 763 | spin_unlock_irqrestore(&lp->lock, flags); |
| 740 | 764 | ||
| 741 | reschedule: | 765 | reschedule: |
| 742 | lp->media.expires = jiffies + HZ; | 766 | lp->media.expires = jiffies + HZ; |
| 743 | add_timer(&lp->media); | 767 | add_timer(&lp->media); |
| 744 | } | 768 | } |
| 745 | 769 | ||
| 746 | static struct net_device_stats *el3_get_stats(struct net_device *dev) | 770 | static struct net_device_stats *el3_get_stats(struct net_device *dev) |
| 747 | { | 771 | { |
| 748 | struct el3_private *lp = netdev_priv(dev); | 772 | struct el3_private *lp = netdev_priv(dev); |
| 749 | unsigned long flags; | 773 | unsigned long flags; |
| 750 | struct pcmcia_device *link = lp->p_dev; | 774 | struct pcmcia_device *link = lp->p_dev; |
| 751 | 775 | ||
| 752 | if (pcmcia_dev_present(link)) { | 776 | if (pcmcia_dev_present(link)) { |
| 753 | spin_lock_irqsave(&lp->lock, flags); | 777 | spin_lock_irqsave(&lp->lock, flags); |
| 754 | update_stats(dev); | 778 | update_stats(dev); |
| 755 | spin_unlock_irqrestore(&lp->lock, flags); | 779 | spin_unlock_irqrestore(&lp->lock, flags); |
| 756 | } | 780 | } |
| 757 | return &dev->stats; | 781 | return &dev->stats; |
| 758 | } | 782 | } |
| 759 | 783 | ||
| 760 | /* | 784 | /* Update statistics. We change to register window 6, so this should be run |
| 761 | Update statistics. We change to register window 6, so this should be run | 785 | * single-threaded if the device is active. This is expected to be a rare |
| 762 | single-threaded if the device is active. This is expected to be a rare | 786 | * operation, and it's simpler for the rest of the driver to assume that |
| 763 | operation, and it's simpler for the rest of the driver to assume that | 787 | * window 1 is always valid rather than use a special window-state variable. |
| 764 | window 1 is always valid rather than use a special window-state variable. | 788 | * |
| 765 | 789 | * Caller must hold the lock for this | |
| 766 | Caller must hold the lock for this | ||
| 767 | */ | 790 | */ |
| 791 | |||
| 768 | static void update_stats(struct net_device *dev) | 792 | static void update_stats(struct net_device *dev) |
| 769 | { | 793 | { |
| 770 | unsigned int ioaddr = dev->base_addr; | 794 | unsigned int ioaddr = dev->base_addr; |
| 771 | 795 | ||
| 772 | netdev_dbg(dev, "updating the statistics.\n"); | 796 | netdev_dbg(dev, "updating the statistics.\n"); |
| 773 | /* Turn off statistics updates while reading. */ | 797 | /* Turn off statistics updates while reading. */ |
| 774 | outw(StatsDisable, ioaddr + EL3_CMD); | 798 | outw(StatsDisable, ioaddr + EL3_CMD); |
| 775 | /* Switch to the stats window, and read everything. */ | 799 | /* Switch to the stats window, and read everything. */ |
| 776 | EL3WINDOW(6); | 800 | EL3WINDOW(6); |
| 777 | dev->stats.tx_carrier_errors += inb(ioaddr + 0); | 801 | dev->stats.tx_carrier_errors += inb(ioaddr + 0); |
| 778 | dev->stats.tx_heartbeat_errors += inb(ioaddr + 1); | 802 | dev->stats.tx_heartbeat_errors += inb(ioaddr + 1); |
| 779 | /* Multiple collisions. */ inb(ioaddr + 2); | 803 | /* Multiple collisions. */ |
| 780 | dev->stats.collisions += inb(ioaddr + 3); | 804 | inb(ioaddr + 2); |
| 781 | dev->stats.tx_window_errors += inb(ioaddr + 4); | 805 | dev->stats.collisions += inb(ioaddr + 3); |
| 782 | dev->stats.rx_fifo_errors += inb(ioaddr + 5); | 806 | dev->stats.tx_window_errors += inb(ioaddr + 4); |
| 783 | dev->stats.tx_packets += inb(ioaddr + 6); | 807 | dev->stats.rx_fifo_errors += inb(ioaddr + 5); |
| 784 | /* Rx packets */ inb(ioaddr + 7); | 808 | dev->stats.tx_packets += inb(ioaddr + 6); |
| 785 | /* Tx deferrals */ inb(ioaddr + 8); | 809 | /* Rx packets */ |
| 786 | /* Rx octets */ inw(ioaddr + 10); | 810 | inb(ioaddr + 7); |
| 787 | /* Tx octets */ inw(ioaddr + 12); | 811 | /* Tx deferrals */ |
| 788 | 812 | inb(ioaddr + 8); | |
| 789 | /* Back to window 1, and turn statistics back on. */ | 813 | /* Rx octets */ |
| 790 | EL3WINDOW(1); | 814 | inw(ioaddr + 10); |
| 791 | outw(StatsEnable, ioaddr + EL3_CMD); | 815 | /* Tx octets */ |
| 816 | inw(ioaddr + 12); | ||
| 817 | |||
| 818 | /* Back to window 1, and turn statistics back on. */ | ||
| 819 | EL3WINDOW(1); | ||
| 820 | outw(StatsEnable, ioaddr + EL3_CMD); | ||
| 792 | } | 821 | } |
| 793 | 822 | ||
| 794 | static int el3_rx(struct net_device *dev) | 823 | static int el3_rx(struct net_device *dev) |
| 795 | { | 824 | { |
| 796 | unsigned int ioaddr = dev->base_addr; | 825 | unsigned int ioaddr = dev->base_addr; |
| 797 | int worklimit = 32; | 826 | int worklimit = 32; |
| 798 | short rx_status; | 827 | short rx_status; |
| 799 | 828 | ||
| 800 | netdev_dbg(dev, "in rx_packet(), status %4.4x, rx_status %4.4x.\n", | 829 | netdev_dbg(dev, "in rx_packet(), status %4.4x, rx_status %4.4x.\n", |
| 801 | inw(ioaddr+EL3_STATUS), inw(ioaddr+RX_STATUS)); | 830 | inw(ioaddr+EL3_STATUS), inw(ioaddr+RX_STATUS)); |
| 802 | while (!((rx_status = inw(ioaddr + RX_STATUS)) & 0x8000) && | 831 | while (!((rx_status = inw(ioaddr + RX_STATUS)) & 0x8000) && |
| 803 | worklimit > 0) { | 832 | worklimit > 0) { |
| 804 | worklimit--; | 833 | worklimit--; |
| 805 | if (rx_status & 0x4000) { /* Error, update stats. */ | 834 | if (rx_status & 0x4000) { /* Error, update stats. */ |
| 806 | short error = rx_status & 0x3800; | 835 | short error = rx_status & 0x3800; |
| 807 | dev->stats.rx_errors++; | 836 | dev->stats.rx_errors++; |
| 808 | switch (error) { | 837 | switch (error) { |
| 809 | case 0x0000: dev->stats.rx_over_errors++; break; | 838 | case 0x0000: |
| 810 | case 0x0800: dev->stats.rx_length_errors++; break; | 839 | dev->stats.rx_over_errors++; |
| 811 | case 0x1000: dev->stats.rx_frame_errors++; break; | 840 | break; |
| 812 | case 0x1800: dev->stats.rx_length_errors++; break; | 841 | case 0x0800: |
| 813 | case 0x2000: dev->stats.rx_frame_errors++; break; | 842 | dev->stats.rx_length_errors++; |
| 814 | case 0x2800: dev->stats.rx_crc_errors++; break; | 843 | break; |
| 815 | } | 844 | case 0x1000: |
| 816 | } else { | 845 | dev->stats.rx_frame_errors++; |
| 817 | short pkt_len = rx_status & 0x7ff; | 846 | break; |
| 818 | struct sk_buff *skb; | 847 | case 0x1800: |
| 819 | 848 | dev->stats.rx_length_errors++; | |
| 820 | skb = netdev_alloc_skb(dev, pkt_len + 5); | 849 | break; |
| 821 | 850 | case 0x2000: | |
| 822 | netdev_dbg(dev, " Receiving packet size %d status %4.4x.\n", | 851 | dev->stats.rx_frame_errors++; |
| 852 | break; | ||
| 853 | case 0x2800: | ||
| 854 | dev->stats.rx_crc_errors++; | ||
| 855 | break; | ||
| 856 | } | ||
| 857 | } else { | ||
| 858 | short pkt_len = rx_status & 0x7ff; | ||
| 859 | struct sk_buff *skb; | ||
| 860 | |||
| 861 | skb = netdev_alloc_skb(dev, pkt_len + 5); | ||
| 862 | |||
| 863 | netdev_dbg(dev, " Receiving packet size %d status %4.4x.\n", | ||
| 823 | pkt_len, rx_status); | 864 | pkt_len, rx_status); |
| 824 | if (skb != NULL) { | 865 | if (skb != NULL) { |
| 825 | skb_reserve(skb, 2); | 866 | skb_reserve(skb, 2); |
| 826 | insl(ioaddr+RX_FIFO, skb_put(skb, pkt_len), | 867 | insl(ioaddr+RX_FIFO, skb_put(skb, pkt_len), |
| 827 | (pkt_len+3)>>2); | 868 | (pkt_len+3)>>2); |
| 828 | skb->protocol = eth_type_trans(skb, dev); | 869 | skb->protocol = eth_type_trans(skb, dev); |
| 829 | netif_rx(skb); | 870 | netif_rx(skb); |
| 830 | dev->stats.rx_packets++; | 871 | dev->stats.rx_packets++; |
| 831 | dev->stats.rx_bytes += pkt_len; | 872 | dev->stats.rx_bytes += pkt_len; |
| 832 | } else { | 873 | } else { |
| 833 | netdev_dbg(dev, "couldn't allocate a sk_buff of size %d.\n", | 874 | netdev_dbg(dev, "couldn't allocate a sk_buff of size %d.\n", |
| 834 | pkt_len); | 875 | pkt_len); |
| 835 | dev->stats.rx_dropped++; | 876 | dev->stats.rx_dropped++; |
| 836 | } | 877 | } |
| 878 | } | ||
| 879 | /* Pop the top of the Rx FIFO */ | ||
| 880 | tc589_wait_for_completion(dev, RxDiscard); | ||
| 837 | } | 881 | } |
| 838 | /* Pop the top of the Rx FIFO */ | 882 | if (worklimit == 0) |
| 839 | tc589_wait_for_completion(dev, RxDiscard); | 883 | netdev_warn(dev, "too much work in el3_rx!\n"); |
| 840 | } | 884 | return 0; |
| 841 | if (worklimit == 0) | ||
| 842 | netdev_warn(dev, "too much work in el3_rx!\n"); | ||
| 843 | return 0; | ||
| 844 | } | 885 | } |
| 845 | 886 | ||
| 846 | static void set_rx_mode(struct net_device *dev) | 887 | static void set_rx_mode(struct net_device *dev) |
| 847 | { | 888 | { |
| 848 | unsigned int ioaddr = dev->base_addr; | 889 | unsigned int ioaddr = dev->base_addr; |
| 849 | u16 opts = SetRxFilter | RxStation | RxBroadcast; | 890 | u16 opts = SetRxFilter | RxStation | RxBroadcast; |
| 850 | 891 | ||
| 851 | if (dev->flags & IFF_PROMISC) | 892 | if (dev->flags & IFF_PROMISC) |
| 852 | opts |= RxMulticast | RxProm; | 893 | opts |= RxMulticast | RxProm; |
| 853 | else if (!netdev_mc_empty(dev) || (dev->flags & IFF_ALLMULTI)) | 894 | else if (!netdev_mc_empty(dev) || (dev->flags & IFF_ALLMULTI)) |
| 854 | opts |= RxMulticast; | 895 | opts |= RxMulticast; |
| 855 | outw(opts, ioaddr + EL3_CMD); | 896 | outw(opts, ioaddr + EL3_CMD); |
| 856 | } | 897 | } |
| 857 | 898 | ||
| 858 | static void set_multicast_list(struct net_device *dev) | 899 | static void set_multicast_list(struct net_device *dev) |
| @@ -867,44 +908,44 @@ static void set_multicast_list(struct net_device *dev) · 8 unmodified lines | |||
| 867 | 908 | ||
| 868 | static int el3_close(struct net_device *dev) | 909 | static int el3_close(struct net_device *dev) |
| 869 | { | 910 | { |
| 870 | struct el3_private *lp = netdev_priv(dev); | 911 | struct el3_private *lp = netdev_priv(dev); |
| 871 | struct pcmcia_device *link = lp->p_dev; | 912 | struct pcmcia_device *link = lp->p_dev; |
| 872 | unsigned int ioaddr = dev->base_addr; | 913 | unsigned int ioaddr = dev->base_addr; |
| 873 | 914 | ||
| 874 | dev_dbg(&link->dev, "%s: shutting down ethercard.\n", dev->name); | 915 | dev_dbg(&link->dev, "%s: shutting down ethercard.\n", dev->name); |
| 916 | |||
| 917 | if (pcmcia_dev_present(link)) { | ||
| 918 | /* Turn off statistics ASAP. We update dev->stats below. */ | ||
| 919 | outw(StatsDisable, ioaddr + EL3_CMD); | ||
| 920 | |||
| 921 | /* Disable the receiver and transmitter. */ | ||
| 922 | outw(RxDisable, ioaddr + EL3_CMD); | ||
| 923 | outw(TxDisable, ioaddr + EL3_CMD); | ||
| 924 | |||
| 925 | if (dev->if_port == 2) | ||
| 926 | /* Turn off thinnet power. Green! */ | ||
| 927 | outw(StopCoax, ioaddr + EL3_CMD); | ||
| 928 | else if (dev->if_port == 1) { | ||
| 929 | /* Disable link beat and jabber */ | ||
| 930 | EL3WINDOW(4); | ||
| 931 | outw(0, ioaddr + WN4_MEDIA); | ||
| 932 | } | ||
| 875 | 933 | ||
| 876 | if (pcmcia_dev_present(link)) { | 934 | /* Switching back to window 0 disables the IRQ. */ |
| 877 | /* Turn off statistics ASAP. We update dev->stats below. */ | 935 | EL3WINDOW(0); |
| 878 | outw(StatsDisable, ioaddr + EL3_CMD); | 936 | /* But we explicitly zero the IRQ line select anyway. */ |
| 937 | outw(0x0f00, ioaddr + WN0_IRQ); | ||
| 879 | 938 | ||
| 880 | /* Disable the receiver and transmitter. */ | 939 | /* Check if the card still exists */ |
| 881 | outw(RxDisable, ioaddr + EL3_CMD); | 940 | if ((inw(ioaddr+EL3_STATUS) & 0xe000) == 0x2000) |
| 882 | outw(TxDisable, ioaddr + EL3_CMD); | 941 | update_stats(dev); |
| 883 | |||
| 884 | if (dev->if_port == 2) | ||
| 885 | /* Turn off thinnet power. Green! */ | ||
| 886 | outw(StopCoax, ioaddr + EL3_CMD); | ||
| 887 | else if (dev->if_port == 1) { | ||
| 888 | /* Disable link beat and jabber */ | ||
| 889 | EL3WINDOW(4); | ||
| 890 | outw(0, ioaddr + WN4_MEDIA); | ||
| 891 | } | 942 | } |
| 892 | 943 | ||
| 893 | /* Switching back to window 0 disables the IRQ. */ | 944 | link->open--; |
| 894 | EL3WINDOW(0); | 945 | netif_stop_queue(dev); |
| 895 | /* But we explicitly zero the IRQ line select anyway. */ | 946 | del_timer_sync(&lp->media); |
| 896 | outw(0x0f00, ioaddr + WN0_IRQ); | ||
| 897 | |||
| 898 | /* Check if the card still exists */ | ||
| 899 | if ((inw(ioaddr+EL3_STATUS) & 0xe000) == 0x2000) | ||
| 900 | update_stats(dev); | ||
| 901 | } | ||
| 902 | |||
| 903 | link->open--; | ||
| 904 | netif_stop_queue(dev); | ||
| 905 | del_timer_sync(&lp->media); | ||
| 906 | 947 | ||
| 907 | return 0; | 948 | return 0; |
| 908 | } | 949 | } |
| 909 | 950 | ||
| 910 | static const struct pcmcia_device_id tc589_ids[] = { | 951 | static const struct pcmcia_device_id tc589_ids[] = { |
| @@ -2086,7 +2086,7 @@ vortex_start_xmit(struct sk_buff *skb, struct net_device *dev) · 2085 unmodified lines | |||
| 2086 | /* ... and the packet rounded to a doubleword. */ | 2086 | /* ... and the packet rounded to a doubleword. */ |
| 2087 | skb_tx_timestamp(skb); | 2087 | skb_tx_timestamp(skb); |
| 2088 | iowrite32_rep(ioaddr + TX_FIFO, skb->data, (skb->len + 3) >> 2); | 2088 | iowrite32_rep(ioaddr + TX_FIFO, skb->data, (skb->len + 3) >> 2); |
| 2089 | dev_kfree_skb (skb); | 2089 | dev_consume_skb_any (skb); |
| 2090 | if (ioread16(ioaddr + TxFree) > 1536) { | 2090 | if (ioread16(ioaddr + TxFree) > 1536) { |
| 2091 | netif_start_queue (dev); /* AKPM: redundant? */ | 2091 | netif_start_queue (dev); /* AKPM: redundant? */ |
| 2092 | } else { | 2092 | } else { |
| @@ -404,7 +404,7 @@ static netdev_tx_t __ei_start_xmit(struct sk_buff *skb, · 403 unmodified lines | |||
| 404 | spin_unlock(&ei_local->page_lock); | 404 | spin_unlock(&ei_local->page_lock); |
| 405 | enable_irq_lockdep_irqrestore(dev->irq, &flags); | 405 | enable_irq_lockdep_irqrestore(dev->irq, &flags); |
| 406 | skb_tx_timestamp(skb); | 406 | skb_tx_timestamp(skb); |
| 407 | dev_kfree_skb(skb); | 407 | dev_consume_skb_any(skb); |
| 408 | dev->stats.tx_bytes += send_length; | 408 | dev->stats.tx_bytes += send_length; |
| 409 | 409 | ||
| 410 | return NETDEV_TX_OK; | 410 | return NETDEV_TX_OK; |
| @@ -22,6 +22,7 @@ source "drivers/net/ethernet/adaptec/Kconfig" · 21 unmodified lines | |||
| 22 | source "drivers/net/ethernet/aeroflex/Kconfig" | 22 | source "drivers/net/ethernet/aeroflex/Kconfig" |
| 23 | source "drivers/net/ethernet/allwinner/Kconfig" | 23 | source "drivers/net/ethernet/allwinner/Kconfig" |
| 24 | source "drivers/net/ethernet/alteon/Kconfig" | 24 | source "drivers/net/ethernet/alteon/Kconfig" |
| 25 | source "drivers/net/ethernet/altera/Kconfig" | ||
| 25 | source "drivers/net/ethernet/amd/Kconfig" | 26 | source "drivers/net/ethernet/amd/Kconfig" |
| 26 | source "drivers/net/ethernet/apple/Kconfig" | 27 | source "drivers/net/ethernet/apple/Kconfig" |
| 27 | source "drivers/net/ethernet/arc/Kconfig" | 28 | source "drivers/net/ethernet/arc/Kconfig" |
| @@ -149,6 +150,7 @@ config S6GMAC · 121 unmodified lines | |||
| 149 | To compile this driver as a module, choose M here. The module | 150 | To compile this driver as a module, choose M here. The module |
| 150 | will be called s6gmac. | 151 | will be called s6gmac. |
| 151 | 152 | ||
| 153 | source "drivers/net/ethernet/samsung/Kconfig" | ||
| 152 | source "drivers/net/ethernet/seeq/Kconfig" | 154 | source "drivers/net/ethernet/seeq/Kconfig" |
| 153 | source "drivers/net/ethernet/silan/Kconfig" | 155 | source "drivers/net/ethernet/silan/Kconfig" |
| 154 | source "drivers/net/ethernet/sis/Kconfig" | 156 | source "drivers/net/ethernet/sis/Kconfig" |
| @@ -8,6 +8,7 @@ obj-$(CONFIG_NET_VENDOR_ADAPTEC) += adaptec/ · 7 unmodified lines | |||
| 8 | obj-$(CONFIG_GRETH) += aeroflex/ | 8 | obj-$(CONFIG_GRETH) += aeroflex/ |
| 9 | obj-$(CONFIG_NET_VENDOR_ALLWINNER) += allwinner/ | 9 | obj-$(CONFIG_NET_VENDOR_ALLWINNER) += allwinner/ |
| 10 | obj-$(CONFIG_NET_VENDOR_ALTEON) += alteon/ | 10 | obj-$(CONFIG_NET_VENDOR_ALTEON) += alteon/ |
| 11 | obj-$(CONFIG_ALTERA_TSE) += altera/ | ||
| 11 | obj-$(CONFIG_NET_VENDOR_AMD) += amd/ | 12 | obj-$(CONFIG_NET_VENDOR_AMD) += amd/ |
| 12 | obj-$(CONFIG_NET_VENDOR_APPLE) += apple/ | 13 | obj-$(CONFIG_NET_VENDOR_APPLE) += apple/ |
| 13 | obj-$(CONFIG_NET_VENDOR_ARC) += arc/ | 14 | obj-$(CONFIG_NET_VENDOR_ARC) += arc/ |
| @@ -60,6 +61,7 @@ obj-$(CONFIG_NET_VENDOR_REALTEK) += realtek/ · 46 unmodified lines | |||
| 60 | obj-$(CONFIG_SH_ETH) += renesas/ | 61 | obj-$(CONFIG_SH_ETH) += renesas/ |
| 61 | obj-$(CONFIG_NET_VENDOR_RDC) += rdc/ | 62 | obj-$(CONFIG_NET_VENDOR_RDC) += rdc/ |
| 62 | obj-$(CONFIG_S6GMAC) += s6gmac.o | 63 | obj-$(CONFIG_S6GMAC) += s6gmac.o |
| 64 | obj-$(CONFIG_NET_VENDOR_SAMSUNG) += samsung/ | ||
| 63 | obj-$(CONFIG_NET_VENDOR_SEEQ) += seeq/ | 65 | obj-$(CONFIG_NET_VENDOR_SEEQ) += seeq/ |
| 64 | obj-$(CONFIG_NET_VENDOR_SILAN) += silan/ | 66 | obj-$(CONFIG_NET_VENDOR_SILAN) += silan/ |
| 65 | obj-$(CONFIG_NET_VENDOR_SIS) += sis/ | 67 | obj-$(CONFIG_NET_VENDOR_SIS) += sis/ |
| @@ -307,11 +307,6 @@ static int bfin_mdiobus_write(struct mii_bus *bus, int phy_addr, int regnum, · 306 unmodified lines | |||
| 307 | return bfin_mdio_poll(); | 307 | return bfin_mdio_poll(); |
| 308 | } | 308 | } |
| 309 | 309 | ||
| 310 | static int bfin_mdiobus_reset(struct mii_bus *bus) | ||
| 311 | { | ||
| 312 | return 0; | ||
| 313 | } | ||
| 314 | |||
| 315 | static void bfin_mac_adjust_link(struct net_device *dev) | 310 | static void bfin_mac_adjust_link(struct net_device *dev) |
| 316 | { | 311 | { |
| 317 | struct bfin_mac_local *lp = netdev_priv(dev); | 312 | struct bfin_mac_local *lp = netdev_priv(dev); |
| @@ -1040,6 +1035,7 @@ static struct ptp_clock_info bfin_ptp_caps = { · 722 unmodified lines | |||
| 1040 | .n_alarm = 0, | 1035 | .n_alarm = 0, |
| 1041 | .n_ext_ts = 0, | 1036 | .n_ext_ts = 0, |
| 1042 | .n_per_out = 0, | 1037 | .n_per_out = 0, |
| 1038 | .n_pins = 0, | ||
| 1043 | .pps = 0, | 1039 | .pps = 0, |
| 1044 | .adjfreq = bfin_ptp_adjfreq, | 1040 | .adjfreq = bfin_ptp_adjfreq, |
| 1045 | .adjtime = bfin_ptp_adjtime, | 1041 | .adjtime = bfin_ptp_adjtime, |
| @@ -1086,7 +1082,7 @@ static inline void _tx_reclaim_skb(void) · 40 unmodified lines | |||
| 1086 | tx_list_head->desc_a.config &= ~DMAEN; | 1082 | tx_list_head->desc_a.config &= ~DMAEN; |
| 1087 | tx_list_head->status.status_word = 0; | 1083 | tx_list_head->status.status_word = 0; |
| 1088 | if (tx_list_head->skb) { | 1084 | if (tx_list_head->skb) { |
| 1089 | dev_kfree_skb(tx_list_head->skb); | 1085 | dev_consume_skb_any(tx_list_head->skb); |
| 1090 | tx_list_head->skb = NULL; | 1086 | tx_list_head->skb = NULL; |
| 1091 | } | 1087 | } |
| 1092 | tx_list_head = tx_list_head->next; | 1088 | tx_list_head = tx_list_head->next; |
| @@ -1823,7 +1819,6 @@ static int bfin_mii_bus_probe(struct platform_device *pdev) · 730 unmodified lines | |||
| 1823 | goto out_err_alloc; | 1819 | goto out_err_alloc; |
| 1824 | miibus->read = bfin_mdiobus_read; | 1820 | miibus->read = bfin_mdiobus_read; |
| 1825 | miibus->write = bfin_mdiobus_write; | 1821 | miibus->write = bfin_mdiobus_write; |
| 1826 | miibus->reset = bfin_mdiobus_reset; | ||
| 1827 | 1822 | ||
| 1828 | miibus->parent = &pdev->dev; | 1823 | miibus->parent = &pdev->dev; |
| 1829 | miibus->name = "bfin_mii_bus"; | 1824 | miibus->name = "bfin_mii_bus"; |
| @@ -1213,11 +1213,6 @@ static int greth_mdio_write(struct mii_bus *bus, int phy, int reg, u16 val) · 1212 unmodified lines | |||
| 1213 | return 0; | 1213 | return 0; |
| 1214 | } | 1214 | } |
| 1215 | 1215 | ||
| 1216 | static int greth_mdio_reset(struct mii_bus *bus) | ||
| 1217 | { | ||
| 1218 | return 0; | ||
| 1219 | } | ||
| 1220 | |||
| 1221 | static void greth_link_change(struct net_device *dev) | 1216 | static void greth_link_change(struct net_device *dev) |
| 1222 | { | 1217 | { |
| 1223 | struct greth_private *greth = netdev_priv(dev); | 1218 | struct greth_private *greth = netdev_priv(dev); |
| @@ -1332,7 +1327,6 @@ static int greth_mdio_init(struct greth_private *greth) · 108 unmodified lines | |||
| 1332 | snprintf(greth->mdio->id, MII_BUS_ID_SIZE, "%s-%d", greth->mdio->name, greth->irq); | 1327 | snprintf(greth->mdio->id, MII_BUS_ID_SIZE, "%s-%d", greth->mdio->name, greth->irq); |
| 1333 | greth->mdio->read = greth_mdio_read; | 1328 | greth->mdio->read = greth_mdio_read; |
| 1334 | greth->mdio->write = greth_mdio_write; | 1329 | greth->mdio->write = greth_mdio_write; |
| 1335 | greth->mdio->reset = greth_mdio_reset; | ||
| 1336 | greth->mdio->priv = greth; | 1330 | greth->mdio->priv = greth; |
| 1337 | 1331 | ||
| 1338 | greth->mdio->irq = greth->mdio_irqs; | 1332 | greth->mdio->irq = greth->mdio_irqs; |
| @@ -476,7 +476,7 @@ static int emac_start_xmit(struct sk_buff *skb, struct net_device *dev) · 475 unmodified lines | |||
| 476 | spin_unlock_irqrestore(&db->lock, flags); | 476 | spin_unlock_irqrestore(&db->lock, flags); |
| 477 | 477 | ||
| 478 | /* free this SKB */ | 478 | /* free this SKB */ |
| 479 | dev_kfree_skb(skb); | 479 | dev_consume_skb_any(skb); |
| 480 | 480 | ||
| 481 | return NETDEV_TX_OK; | 481 | return NETDEV_TX_OK; |
| 482 | } | 482 | } |
| @@ -0,0 +1,8 @@ | |||
| 1 | config ALTERA_TSE | ||
| 2 | tristate "Altera Triple-Speed Ethernet MAC support" | ||
| 3 | select PHYLIB | ||
| 4 | ---help--- | ||
| 5 | This driver supports the Altera Triple-Speed (TSE) Ethernet MAC. | ||
| 6 | |||
| 7 | To compile this driver as a module, choose M here. The module | ||
| 8 | will be called alteratse. | ||
| @@ -0,0 +1,7 @@ | |||
| 1 | # | ||
| 2 | # Makefile for the Altera device drivers. | ||
| 3 | # | ||
| 4 | |||
| 5 | obj-$(CONFIG_ALTERA_TSE) += altera_tse.o | ||
| 6 | altera_tse-objs := altera_tse_main.o altera_tse_ethtool.o \ | ||
| 7 | altera_msgdma.o altera_sgdma.o altera_utils.o | ||
| @@ -0,0 +1,202 @@ | |||
| 1 | /* Altera TSE SGDMA and MSGDMA Linux driver | ||
| 2 | * Copyright (C) 2014 Altera Corporation. All rights reserved | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or modify it | ||
| 5 | * under the terms and conditions of the GNU General Public License, | ||
| 6 | * version 2, as published by the Free Software Foundation. | ||
| 7 | * | ||
| 8 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
| 9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 10 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
| 11 | * more details. | ||
| 12 | * | ||
| 13 | * You should have received a copy of the GNU General Public License along with | ||
| 14 | * this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 15 | */ | ||
| 16 | |||
| 17 | #include <linux/netdevice.h> | ||
| 18 | #include "altera_utils.h" | ||
| 19 | #include "altera_tse.h" | ||
| 20 | #include "altera_msgdmahw.h" | ||
| 21 | |||
| 22 | /* No initialization work to do for MSGDMA */ | ||
| 23 | int msgdma_initialize(struct altera_tse_private *priv) | ||
| 24 | { | ||
| 25 | return 0; | ||
| 26 | } | ||
| 27 | |||
| 28 | void msgdma_uninitialize(struct altera_tse_private *priv) | ||
| 29 | { | ||
| 30 | } | ||
| 31 | |||
| 32 | void msgdma_reset(struct altera_tse_private *priv) | ||
| 33 | { | ||
| 34 | int counter; | ||
| 35 | struct msgdma_csr *txcsr = | ||
| 36 | (struct msgdma_csr *)priv->tx_dma_csr; | ||
| 37 | struct msgdma_csr *rxcsr = | ||
| 38 | (struct msgdma_csr *)priv->rx_dma_csr; | ||
| 39 | |||
| 40 | /* Reset Rx mSGDMA */ | ||
| 41 | iowrite32(MSGDMA_CSR_STAT_MASK, &rxcsr->status); | ||
| 42 | iowrite32(MSGDMA_CSR_CTL_RESET, &rxcsr->control); | ||
| 43 | |||
| 44 | counter = 0; | ||
| 45 | while (counter++ < ALTERA_TSE_SW_RESET_WATCHDOG_CNTR) { | ||
| 46 | if (tse_bit_is_clear(&rxcsr->status, | ||
| 47 | MSGDMA_CSR_STAT_RESETTING)) | ||
| 48 | break; | ||
| 49 | udelay(1); | ||
| 50 | } | ||
| 51 | |||
| 52 | if (counter >= ALTERA_TSE_SW_RESET_WATCHDOG_CNTR) | ||
| 53 | netif_warn(priv, drv, priv->dev, | ||
| 54 | "TSE Rx mSGDMA resetting bit never cleared!\n"); | ||
| 55 | |||
| 56 | /* clear all status bits */ | ||
| 57 | iowrite32(MSGDMA_CSR_STAT_MASK, &rxcsr->status); | ||
| 58 | |||
| 59 | /* Reset Tx mSGDMA */ | ||
| 60 | iowrite32(MSGDMA_CSR_STAT_MASK, &txcsr->status); | ||
| 61 | iowrite32(MSGDMA_CSR_CTL_RESET, &txcsr->control); | ||
| 62 | |||
| 63 | counter = 0; | ||
| 64 | while (counter++ < ALTERA_TSE_SW_RESET_WATCHDOG_CNTR) { | ||
| 65 | if (tse_bit_is_clear(&txcsr->status, | ||
| 66 | MSGDMA_CSR_STAT_RESETTING)) | ||
| 67 | break; | ||
| 68 | udelay(1); | ||
| 69 | } | ||
| 70 | |||
| 71 | if (counter >= ALTERA_TSE_SW_RESET_WATCHDOG_CNTR) | ||
| 72 | netif_warn(priv, drv, priv->dev, | ||
| 73 | "TSE Tx mSGDMA resetting bit never cleared!\n"); | ||
| 74 | |||
| 75 | /* clear all status bits */ | ||
| 76 | iowrite32(MSGDMA_CSR_STAT_MASK, &txcsr->status); | ||
| 77 | } | ||
| 78 | |||
| 79 | void msgdma_disable_rxirq(struct altera_tse_private *priv) | ||
| 80 | { | ||
| 81 | struct msgdma_csr *csr = priv->rx_dma_csr; | ||
| 82 | tse_clear_bit(&csr->control, MSGDMA_CSR_CTL_GLOBAL_INTR); | ||
| 83 | } | ||
| 84 | |||
| 85 | void msgdma_enable_rxirq(struct altera_tse_private *priv) | ||
| 86 | { | ||
| 87 | struct msgdma_csr *csr = priv->rx_dma_csr; | ||
| 88 | tse_set_bit(&csr->control, MSGDMA_CSR_CTL_GLOBAL_INTR); | ||
| 89 | } | ||
| 90 | |||
| 91 | void msgdma_disable_txirq(struct altera_tse_private *priv) | ||
| 92 | { | ||
| 93 | struct msgdma_csr *csr = priv->tx_dma_csr; | ||
| 94 | tse_clear_bit(&csr->control, MSGDMA_CSR_CTL_GLOBAL_INTR); | ||
| 95 | } | ||
| 96 | |||
| 97 | void msgdma_enable_txirq(struct altera_tse_private *priv) | ||
| 98 | { | ||
| 99 | struct msgdma_csr *csr = priv->tx_dma_csr; | ||
| 100 | tse_set_bit(&csr->control, MSGDMA_CSR_CTL_GLOBAL_INTR); | ||
| 101 | } | ||
| 102 | |||
| 103 | void msgdma_clear_rxirq(struct altera_tse_private *priv) | ||
| 104 | { | ||
| 105 | struct msgdma_csr *csr = priv->rx_dma_csr; | ||
| 106 | iowrite32(MSGDMA_CSR_STAT_IRQ, &csr->status); | ||
| 107 | } | ||
| 108 | |||
| 109 | void msgdma_clear_txirq(struct altera_tse_private *priv) | ||
| 110 | { | ||
| 111 | struct msgdma_csr *csr = priv->tx_dma_csr; | ||
| 112 | iowrite32(MSGDMA_CSR_STAT_IRQ, &csr->status); | ||
| 113 | } | ||
| 114 | |||
| 115 | /* return 0 to indicate transmit is pending */ | ||
| 116 | int msgdma_tx_buffer(struct altera_tse_private *priv, struct tse_buffer *buffer) | ||
| 117 | { | ||
| 118 | struct msgdma_extended_desc *desc = priv->tx_dma_desc; | ||
| 119 | |||
| 120 | iowrite32(lower_32_bits(buffer->dma_addr), &desc->read_addr_lo); | ||
| 121 | iowrite32(upper_32_bits(buffer->dma_addr), &desc->read_addr_hi); | ||
| 122 | iowrite32(0, &desc->write_addr_lo); | ||
| 123 | iowrite32(0, &desc->write_addr_hi); | ||
| 124 | iowrite32(buffer->len, &desc->len); | ||
| 125 | iowrite32(0, &desc->burst_seq_num); | ||
| 126 | iowrite32(MSGDMA_DESC_TX_STRIDE, &desc->stride); | ||
| 127 | iowrite32(MSGDMA_DESC_CTL_TX_SINGLE, &desc->control); | ||
| 128 | return 0; | ||
| 129 | } | ||
| 130 | |||
| 131 | u32 msgdma_tx_completions(struct altera_tse_private *priv) | ||
| 132 | { | ||
| 133 | u32 ready = 0; | ||
| 134 | u32 inuse; | ||
| 135 | u32 status; | ||
| 136 | struct msgdma_csr *txcsr = | ||
| 137 | (struct msgdma_csr *)priv->tx_dma_csr; | ||
| 138 | |||
| 139 | /* Get number of sent descriptors */ | ||
| 140 | inuse = ioread32(&txcsr->rw_fill_level) & 0xffff; | ||
| 141 | |||
| 142 | if (inuse) { /* Tx FIFO is not empty */ | ||
| 143 | ready = priv->tx_prod - priv->tx_cons - inuse - 1; | ||
| 144 | } else { | ||
| 145 | /* Check for buffered last packet */ | ||
| 146 | status = ioread32(&txcsr->status); | ||
| 147 | if (status & MSGDMA_CSR_STAT_BUSY) | ||
| 148 | ready = priv->tx_prod - priv->tx_cons - 1; | ||
| 149 | else | ||
| 150 | ready = priv->tx_prod - priv->tx_cons; | ||
| 151 | } | ||
| 152 | return ready; | ||
| 153 | } | ||
| 154 | |||
| 155 | /* Put buffer to the mSGDMA RX FIFO | ||
| 156 | */ | ||
| 157 | int msgdma_add_rx_desc(struct altera_tse_private *priv, | ||
| 158 | struct tse_buffer *rxbuffer) | ||
| 159 | { | ||
| 160 | struct msgdma_extended_desc *desc = priv->rx_dma_desc; | ||
| 161 | u32 len = priv->rx_dma_buf_sz; | ||
| 162 | dma_addr_t dma_addr = rxbuffer->dma_addr; | ||
| 163 | u32 control = (MSGDMA_DESC_CTL_END_ON_EOP | ||
| 164 | | MSGDMA_DESC_CTL_END_ON_LEN | ||
| 165 | | MSGDMA_DESC_CTL_TR_COMP_IRQ | ||
| 166 | | MSGDMA_DESC_CTL_EARLY_IRQ | ||
| 167 | | MSGDMA_DESC_CTL_TR_ERR_IRQ | ||
| 168 | | MSGDMA_DESC_CTL_GO); | ||
| 169 | |||
| 170 | iowrite32(0, &desc->read_addr_lo); | ||
| 171 | iowrite32(0, &desc->read_addr_hi); | ||
| 172 | iowrite32(lower_32_bits(dma_addr), &desc->write_addr_lo); | ||
| 173 | iowrite32(upper_32_bits(dma_addr), &desc->write_addr_hi); | ||
| 174 | iowrite32(len, &desc->len); | ||
| 175 | iowrite32(0, &desc->burst_seq_num); | ||
| 176 | iowrite32(0x00010001, &desc->stride); | ||
| 177 | iowrite32(control, &desc->control); | ||
| 178 | return 1; | ||
| 179 | } | ||
| 180 | |||
| 181 | /* status is returned on upper 16 bits, | ||
| 182 | * length is returned in lower 16 bits | ||
| 183 | */ | ||
| 184 | u32 msgdma_rx_status(struct altera_tse_private *priv) | ||
| 185 | { | ||
| 186 | u32 rxstatus = 0; | ||
| 187 | u32 pktlength; | ||
| 188 | u32 pktstatus; | ||
| 189 | struct msgdma_csr *rxcsr = | ||
| 190 | (struct msgdma_csr *)priv->rx_dma_csr; | ||
| 191 | struct msgdma_response *rxresp = | ||
| 192 | (struct msgdma_response *)priv->rx_dma_resp; | ||
| 193 | |||
| 194 | if (ioread32(&rxcsr->resp_fill_level) & 0xffff) { | ||
| 195 | pktlength = ioread32(&rxresp->bytes_transferred); | ||
| 196 | pktstatus = ioread32(&rxresp->status); | ||
| 197 | rxstatus = pktstatus; | ||
| 198 | rxstatus = rxstatus << 16; | ||
| 199 | rxstatus |= (pktlength & 0xffff); | ||
| 200 | } | ||
| 201 | return rxstatus; | ||
| 202 | } | ||
| @@ -0,0 +1,34 @@ | |||
| 1 | /* Altera TSE SGDMA and MSGDMA Linux driver | ||
| 2 | * Copyright (C) 2014 Altera Corporation. All rights reserved | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or modify it | ||
| 5 | * under the terms and conditions of the GNU General Public License, | ||
| 6 | * version 2, as published by the Free Software Foundation. | ||
| 7 | * | ||
| 8 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
| 9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 10 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
| 11 | * more details. | ||
| 12 | * | ||
| 13 | * You should have received a copy of the GNU General Public License along with | ||
| 14 | * this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 15 | */ | ||
| 16 | |||
| 17 | #ifndef __ALTERA_MSGDMA_H__ | ||
| 18 | #define __ALTERA_MSGDMA_H__ | ||
| 19 | |||
| 20 | void msgdma_reset(struct altera_tse_private *); | ||
| 21 | void msgdma_enable_txirq(struct altera_tse_private *); | ||
| 22 | void msgdma_enable_rxirq(struct altera_tse_private *); | ||
| 23 | void msgdma_disable_rxirq(struct altera_tse_private *); | ||
| 24 | void msgdma_disable_txirq(struct altera_tse_private *); | ||
| 25 | void msgdma_clear_rxirq(struct altera_tse_private *); | ||
| 26 | void msgdma_clear_txirq(struct altera_tse_private *); | ||
| 27 | u32 msgdma_tx_completions(struct altera_tse_private *); | ||
| 28 | int msgdma_add_rx_desc(struct altera_tse_private *, struct tse_buffer *); | ||
| 29 | int msgdma_tx_buffer(struct altera_tse_private *, struct tse_buffer *); | ||
| 30 | u32 msgdma_rx_status(struct altera_tse_private *); | ||
| 31 | int msgdma_initialize(struct altera_tse_private *); | ||
| 32 | void msgdma_uninitialize(struct altera_tse_private *); | ||
| 33 | |||
| 34 | #endif /* __ALTERA_MSGDMA_H__ */ | ||
| @@ -0,0 +1,167 @@ | |||
| 1 | /* Altera TSE SGDMA and MSGDMA Linux driver | ||
| 2 | * Copyright (C) 2014 Altera Corporation. All rights reserved | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or modify it | ||
| 5 | * under the terms and conditions of the GNU General Public License, | ||
| 6 | * version 2, as published by the Free Software Foundation. | ||
| 7 | * | ||
| 8 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
| 9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 10 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
| 11 | * more details. | ||
| 12 | * | ||
| 13 | * You should have received a copy of the GNU General Public License along with | ||
| 14 | * this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 15 | */ | ||
| 16 | |||
| 17 | #ifndef __ALTERA_MSGDMAHW_H__ | ||
| 18 | #define __ALTERA_MSGDMAHW_H__ | ||
| 19 | |||
| 20 | /* mSGDMA standard descriptor format | ||
| 21 | */ | ||
| 22 | struct msgdma_desc { | ||
| 23 | u32 read_addr; /* data buffer source address */ | ||
| 24 | u32 write_addr; /* data buffer destination address */ | ||
| 25 | u32 len; /* the number of bytes to transfer per descriptor */ | ||
| 26 | u32 control; /* characteristics of the transfer */ | ||
| 27 | }; | ||
| 28 | |||
| 29 | /* mSGDMA extended descriptor format | ||
| 30 | */ | ||
| 31 | struct msgdma_extended_desc { | ||
| 32 | u32 read_addr_lo; /* data buffer source address low bits */ | ||
| 33 | u32 write_addr_lo; /* data buffer destination address low bits */ | ||
| 34 | u32 len; /* the number of bytes to transfer | ||
| 35 | * per descriptor | ||
| 36 | */ | ||
| 37 | u32 burst_seq_num; /* bit 31:24 write burst | ||
| 38 | * bit 23:16 read burst | ||
| 39 | * bit 15:0 sequence number | ||
| 40 | */ | ||
| 41 | u32 stride; /* bit 31:16 write stride | ||
| 42 | * bit 15:0 read stride | ||
| 43 | */ | ||
| 44 | u32 read_addr_hi; /* data buffer source address high bits */ | ||
| 45 | u32 write_addr_hi; /* data buffer destination address high bits */ | ||
| 46 | u32 control; /* characteristics of the transfer */ | ||
| 47 | }; | ||
| 48 | |||
| 49 | /* mSGDMA descriptor control field bit definitions | ||
| 50 | */ | ||
| 51 | #define MSGDMA_DESC_CTL_SET_CH(x) ((x) & 0xff) | ||
| 52 | #define MSGDMA_DESC_CTL_GEN_SOP BIT(8) | ||
| 53 | #define MSGDMA_DESC_CTL_GEN_EOP BIT(9) | ||
| 54 | #define MSGDMA_DESC_CTL_PARK_READS BIT(10) | ||
| 55 | #define MSGDMA_DESC_CTL_PARK_WRITES BIT(11) | ||
| 56 | #define MSGDMA_DESC_CTL_END_ON_EOP BIT(12) | ||
| 57 | #define MSGDMA_DESC_CTL_END_ON_LEN BIT(13) | ||
| 58 | #define MSGDMA_DESC_CTL_TR_COMP_IRQ BIT(14) | ||
| 59 | #define MSGDMA_DESC_CTL_EARLY_IRQ BIT(15) | ||
| 60 | #define MSGDMA_DESC_CTL_TR_ERR_IRQ (0xff << 16) | ||
| 61 | #define MSGDMA_DESC_CTL_EARLY_DONE BIT(24) | ||
| 62 | /* Writing ‘1’ to the ‘go’ bit commits the entire descriptor into the | ||
| 63 | * descriptor FIFO(s) | ||
| 64 | */ | ||
| 65 | #define MSGDMA_DESC_CTL_GO BIT(31) | ||
| 66 | |||
| 67 | /* Tx buffer control flags | ||
| 68 | */ | ||
| 69 | #define MSGDMA_DESC_CTL_TX_FIRST (MSGDMA_DESC_CTL_GEN_SOP | \ | ||
| 70 | MSGDMA_DESC_CTL_TR_ERR_IRQ | \ | ||
| 71 | MSGDMA_DESC_CTL_GO) | ||
| 72 | |||
| 73 | #define MSGDMA_DESC_CTL_TX_MIDDLE (MSGDMA_DESC_CTL_TR_ERR_IRQ | \ | ||
| 74 | MSGDMA_DESC_CTL_GO) | ||
| 75 | |||
| 76 | #define MSGDMA_DESC_CTL_TX_LAST (MSGDMA_DESC_CTL_GEN_EOP | \ | ||
| 77 | MSGDMA_DESC_CTL_TR_COMP_IRQ | \ | ||
| 78 | MSGDMA_DESC_CTL_TR_ERR_IRQ | \ | ||
| 79 | MSGDMA_DESC_CTL_GO) | ||
| 80 | |||
| 81 | #define MSGDMA_DESC_CTL_TX_SINGLE (MSGDMA_DESC_CTL_GEN_SOP | \ | ||
| 82 | MSGDMA_DESC_CTL_GEN_EOP | \ | ||
| 83 | MSGDMA_DESC_CTL_TR_COMP_IRQ | \ | ||
| 84 | MSGDMA_DESC_CTL_TR_ERR_IRQ | \ | ||
| 85 | MSGDMA_DESC_CTL_GO) | ||
| 86 | |||
| 87 | #define MSGDMA_DESC_CTL_RX_SINGLE (MSGDMA_DESC_CTL_END_ON_EOP | \ | ||
| 88 | MSGDMA_DESC_CTL_END_ON_LEN | \ | ||
| 89 | MSGDMA_DESC_CTL_TR_COMP_IRQ | \ | ||
| 90 | MSGDMA_DESC_CTL_EARLY_IRQ | \ | ||
| 91 | MSGDMA_DESC_CTL_TR_ERR_IRQ | \ | ||
| 92 | MSGDMA_DESC_CTL_GO) | ||
| 93 | |||
| 94 | /* mSGDMA extended descriptor stride definitions | ||
| 95 | */ | ||
| 96 | #define MSGDMA_DESC_TX_STRIDE (0x00010001) | ||
| 97 | #define MSGDMA_DESC_RX_STRIDE (0x00010001) | ||
| 98 | |||
| 99 | /* mSGDMA dispatcher control and status register map | ||
| 100 | */ | ||
| 101 | struct msgdma_csr { | ||
| 102 | u32 status; /* Read/Clear */ | ||
| 103 | u32 control; /* Read/Write */ | ||
| 104 | u32 rw_fill_level; /* bit 31:16 - write fill level | ||
| 105 | * bit 15:0 - read fill level | ||
| 106 | */ | ||
| 107 | u32 resp_fill_level; /* bit 15:0 */ | ||
| 108 | u32 rw_seq_num; /* bit 31:16 - write sequence number | ||
| 109 | * bit 15:0 - read sequence number | ||
| 110 | */ | ||
| 111 | u32 pad[3]; /* reserved */ | ||
| 112 | }; | ||
| 113 | |||
| 114 | /* mSGDMA CSR status register bit definitions | ||
| 115 | */ | ||
| 116 | #define MSGDMA_CSR_STAT_BUSY BIT(0) | ||
| 117 | #define MSGDMA_CSR_STAT_DESC_BUF_EMPTY BIT(1) | ||
| 118 | #define MSGDMA_CSR_STAT_DESC_BUF_FULL BIT(2) | ||
| 119 | #define MSGDMA_CSR_STAT_RESP_BUF_EMPTY BIT(3) | ||
| 120 | #define MSGDMA_CSR_STAT_RESP_BUF_FULL BIT(4) | ||
| 121 | #define MSGDMA_CSR_STAT_STOPPED BIT(5) | ||
| 122 | #define MSGDMA_CSR_STAT_RESETTING BIT(6) | ||
| 123 | #define MSGDMA_CSR_STAT_STOPPED_ON_ERR BIT(7) | ||
| 124 | #define MSGDMA_CSR_STAT_STOPPED_ON_EARLY BIT(8) | ||
| 125 | #define MSGDMA_CSR_STAT_IRQ BIT(9) | ||
| 126 | #define MSGDMA_CSR_STAT_MASK 0x3FF | ||
| 127 | #define MSGDMA_CSR_STAT_MASK_WITHOUT_IRQ 0x1FF | ||
| 128 | |||
| 129 | #define MSGDMA_CSR_STAT_BUSY_GET(v) GET_BIT_VALUE(v, 0) | ||
| 130 | #define MSGDMA_CSR_STAT_DESC_BUF_EMPTY_GET(v) GET_BIT_VALUE(v, 1) | ||
| 131 | #define MSGDMA_CSR_STAT_DESC_BUF_FULL_GET(v) GET_BIT_VALUE(v, 2) | ||
| 132 | #define MSGDMA_CSR_STAT_RESP_BUF_EMPTY_GET(v) GET_BIT_VALUE(v, 3) | ||
| 133 | #define MSGDMA_CSR_STAT_RESP_BUF_FULL_GET(v) GET_BIT_VALUE(v, 4) | ||
| 134 | #define MSGDMA_CSR_STAT_STOPPED_GET(v) GET_BIT_VALUE(v, 5) | ||
| 135 | #define MSGDMA_CSR_STAT_RESETTING_GET(v) GET_BIT_VALUE(v, 6) | ||
| 136 | #define MSGDMA_CSR_STAT_STOPPED_ON_ERR_GET(v) GET_BIT_VALUE(v, 7) | ||
| 137 | #define MSGDMA_CSR_STAT_STOPPED_ON_EARLY_GET(v) GET_BIT_VALUE(v, 8) | ||
| 138 | #define MSGDMA_CSR_STAT_IRQ_GET(v) GET_BIT_VALUE(v, 9) | ||
| 139 | |||
| 140 | /* mSGDMA CSR control register bit definitions | ||
| 141 | */ | ||
| 142 | #define MSGDMA_CSR_CTL_STOP BIT(0) | ||
| 143 | #define MSGDMA_CSR_CTL_RESET BIT(1) | ||
| 144 | #define MSGDMA_CSR_CTL_STOP_ON_ERR BIT(2) | ||
| 145 | #define MSGDMA_CSR_CTL_STOP_ON_EARLY BIT(3) | ||
| 146 | #define MSGDMA_CSR_CTL_GLOBAL_INTR BIT(4) | ||
| 147 | #define MSGDMA_CSR_CTL_STOP_DESCS BIT(5) | ||
| 148 | |||
| 149 | /* mSGDMA CSR fill level bits | ||
| 150 | */ | ||
| 151 | #define MSGDMA_CSR_WR_FILL_LEVEL_GET(v) (((v) & 0xffff0000) >> 16) | ||
| 152 | #define MSGDMA_CSR_RD_FILL_LEVEL_GET(v) ((v) & 0x0000ffff) | ||
| 153 | #define MSGDMA_CSR_RESP_FILL_LEVEL_GET(v) ((v) & 0x0000ffff) | ||
| 154 | |||
| 155 | /* mSGDMA response register map | ||
| 156 | */ | ||
| 157 | struct msgdma_response { | ||
| 158 | u32 bytes_transferred; | ||
| 159 | u32 status; | ||
| 160 | }; | ||
| 161 | |||
| 162 | /* mSGDMA response register bit definitions | ||
| 163 | */ | ||
| 164 | #define MSGDMA_RESP_EARLY_TERM BIT(8) | ||
| 165 | #define MSGDMA_RESP_ERR_MASK 0xFF | ||
| 166 | |||
| 167 | #endif /* __ALTERA_MSGDMA_H__*/ | ||
| @@ -0,0 +1,509 @@ | |||
| 1 | /* Altera TSE SGDMA and MSGDMA Linux driver | ||
| 2 | * Copyright (C) 2014 Altera Corporation. All rights reserved | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or modify it | ||
| 5 | * under the terms and conditions of the GNU General Public License, | ||
| 6 | * version 2, as published by the Free Software Foundation. | ||
| 7 | * | ||
| 8 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
| 9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 10 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
| 11 | * more details. | ||
| 12 | * | ||
| 13 | * You should have received a copy of the GNU General Public License along with | ||
| 14 | * this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 15 | */ | ||
| 16 | |||
| 17 | #include <linux/list.h> | ||
| 18 | #include "altera_utils.h" | ||
| 19 | #include "altera_tse.h" | ||
| 20 | #include "altera_sgdmahw.h" | ||
| 21 | #include "altera_sgdma.h" | ||
| 22 | |||
| 23 | static void sgdma_descrip(struct sgdma_descrip *desc, | ||
| 24 | struct sgdma_descrip *ndesc, | ||
| 25 | dma_addr_t ndesc_phys, | ||
| 26 | dma_addr_t raddr, | ||
| 27 | dma_addr_t waddr, | ||
| 28 | u16 length, | ||
| 29 | int generate_eop, | ||
| 30 | int rfixed, | ||
| 31 | int wfixed); | ||
| 32 | |||
| 33 | static int sgdma_async_write(struct altera_tse_private *priv, | ||
| 34 | struct sgdma_descrip *desc); | ||
| 35 | |||
| 36 | static int sgdma_async_read(struct altera_tse_private *priv); | ||
| 37 | |||
| 38 | static dma_addr_t | ||
| 39 | sgdma_txphysaddr(struct altera_tse_private *priv, | ||
| 40 | struct sgdma_descrip *desc); | ||
| 41 | |||
| 42 | static dma_addr_t | ||
| 43 | sgdma_rxphysaddr(struct altera_tse_private *priv, | ||
| 44 | struct sgdma_descrip *desc); | ||
| 45 | |||
| 46 | static int sgdma_txbusy(struct altera_tse_private *priv); | ||
| 47 | |||
| 48 | static int sgdma_rxbusy(struct altera_tse_private *priv); | ||
| 49 | |||
| 50 | static void | ||
| 51 | queue_tx(struct altera_tse_private *priv, struct tse_buffer *buffer); | ||
| 52 | |||
| 53 | static void | ||
| 54 | queue_rx(struct altera_tse_private *priv, struct tse_buffer *buffer); | ||
| 55 | |||
| 56 | static struct tse_buffer * | ||
| 57 | dequeue_tx(struct altera_tse_private *priv); | ||
| 58 | |||
| 59 | static struct tse_buffer * | ||
| 60 | dequeue_rx(struct altera_tse_private *priv); | ||
| 61 | |||
| 62 | static struct tse_buffer * | ||
| 63 | queue_rx_peekhead(struct altera_tse_private *priv); | ||
| 64 | |||
| 65 | int sgdma_initialize(struct altera_tse_private *priv) | ||
| 66 | { | ||
| 67 | priv->txctrlreg = SGDMA_CTRLREG_ILASTD; | ||
| 68 | |||
| 69 | priv->rxctrlreg = SGDMA_CTRLREG_IDESCRIP | | ||
| 70 | SGDMA_CTRLREG_ILASTD; | ||
| 71 | |||
| 72 | INIT_LIST_HEAD(&priv->txlisthd); | ||
| 73 | INIT_LIST_HEAD(&priv->rxlisthd); | ||
| 74 | |||
| 75 | priv->rxdescphys = (dma_addr_t) 0; | ||
| 76 | priv->txdescphys = (dma_addr_t) 0; | ||
| 77 | |||
| 78 | priv->rxdescphys = dma_map_single(priv->device, priv->rx_dma_desc, | ||
| 79 | priv->rxdescmem, DMA_BIDIRECTIONAL); | ||
| 80 | |||
| 81 | if (dma_mapping_error(priv->device, priv->rxdescphys)) { | ||
| 82 | sgdma_uninitialize(priv); | ||
| 83 | netdev_err(priv->dev, "error mapping rx descriptor memory\n"); | ||
| 84 | return -EINVAL; | ||
| 85 | } | ||
| 86 | |||
| 87 | priv->txdescphys = dma_map_single(priv->device, priv->tx_dma_desc, | ||
| 88 | priv->txdescmem, DMA_TO_DEVICE); | ||
| 89 | |||
| 90 | if (dma_mapping_error(priv->device, priv->txdescphys)) { | ||
| 91 | sgdma_uninitialize(priv); | ||
| 92 | netdev_err(priv->dev, "error mapping tx descriptor memory\n"); | ||
| 93 | return -EINVAL; | ||
| 94 | } | ||
| 95 | |||
| 96 | return 0; | ||
| 97 | } | ||
| 98 | |||
| 99 | void sgdma_uninitialize(struct altera_tse_private *priv) | ||
| 100 | { | ||
| 101 | if (priv->rxdescphys) | ||
| 102 | dma_unmap_single(priv->device, priv->rxdescphys, | ||
| 103 | priv->rxdescmem, DMA_BIDIRECTIONAL); | ||
| 104 | |||
| 105 | if (priv->txdescphys) | ||
| 106 | dma_unmap_single(priv->device, priv->txdescphys, | ||
| 107 | priv->txdescmem, DMA_TO_DEVICE); | ||
| 108 | } | ||
| 109 | |||
| 110 | /* This function resets the SGDMA controller and clears the | ||
| 111 | * descriptor memory used for transmits and receives. | ||
| 112 | */ | ||
| 113 | void sgdma_reset(struct altera_tse_private *priv) | ||
| 114 | { | ||
| 115 | u32 *ptxdescripmem = (u32 *)priv->tx_dma_desc; | ||
| 116 | u32 txdescriplen = priv->txdescmem; | ||
| 117 | u32 *prxdescripmem = (u32 *)priv->rx_dma_desc; | ||
| 118 | u32 rxdescriplen = priv->rxdescmem; | ||
| 119 | struct sgdma_csr *ptxsgdma = (struct sgdma_csr *)priv->tx_dma_csr; | ||
| 120 | struct sgdma_csr *prxsgdma = (struct sgdma_csr *)priv->rx_dma_csr; | ||
| 121 | |||
| 122 | /* Initialize descriptor memory to 0 */ | ||
| 123 | memset(ptxdescripmem, 0, txdescriplen); | ||
| 124 | memset(prxdescripmem, 0, rxdescriplen); | ||
| 125 | |||
| 126 | iowrite32(SGDMA_CTRLREG_RESET, &ptxsgdma->control); | ||
| 127 | iowrite32(0, &ptxsgdma->control); | ||
| 128 | |||
| 129 | iowrite32(SGDMA_CTRLREG_RESET, &prxsgdma->control); | ||
| 130 | iowrite32(0, &prxsgdma->control); | ||
| 131 | } | ||
| 132 | |||
| 133 | void sgdma_enable_rxirq(struct altera_tse_private *priv) | ||
| 134 | { | ||
| 135 | struct sgdma_csr *csr = (struct sgdma_csr *)priv->rx_dma_csr; | ||
| 136 | priv->rxctrlreg |= SGDMA_CTRLREG_INTEN; | ||
| 137 | tse_set_bit(&csr->control, SGDMA_CTRLREG_INTEN); | ||
| 138 | } | ||
| 139 | |||
| 140 | void sgdma_enable_txirq(struct altera_tse_private *priv) | ||
| 141 | { | ||
| 142 | struct sgdma_csr *csr = (struct sgdma_csr *)priv->tx_dma_csr; | ||
| 143 | priv->txctrlreg |= SGDMA_CTRLREG_INTEN; | ||
| 144 | tse_set_bit(&csr->control, SGDMA_CTRLREG_INTEN); | ||
| 145 | } | ||
| 146 | |||
| 147 | /* for SGDMA, RX interrupts remain enabled after enabling */ | ||
| 148 | void sgdma_disable_rxirq(struct altera_tse_private *priv) | ||
| 149 | { | ||
| 150 | } | ||
| 151 | |||
| 152 | /* for SGDMA, TX interrupts remain enabled after enabling */ | ||
| 153 | void sgdma_disable_txirq(struct altera_tse_private *priv) | ||
| 154 | { | ||
| 155 | } | ||
| 156 | |||
| 157 | void sgdma_clear_rxirq(struct altera_tse_private *priv) | ||
| 158 | { | ||
| 159 | struct sgdma_csr *csr = (struct sgdma_csr *)priv->rx_dma_csr; | ||
| 160 | tse_set_bit(&csr->control, SGDMA_CTRLREG_CLRINT); | ||
| 161 | } | ||
| 162 | |||
| 163 | void sgdma_clear_txirq(struct altera_tse_private *priv) | ||
| 164 | { | ||
| 165 | struct sgdma_csr *csr = (struct sgdma_csr *)priv->tx_dma_csr; | ||
| 166 | tse_set_bit(&csr->control, SGDMA_CTRLREG_CLRINT); | ||
| 167 | } | ||
| 168 | |||
| 169 | /* transmits buffer through SGDMA. Returns number of buffers | ||
| 170 | * transmitted, 0 if not possible. | ||
| 171 | * | ||
| 172 | * tx_lock is held by the caller | ||
| 173 | */ | ||
| 174 | int sgdma_tx_buffer(struct altera_tse_private *priv, struct tse_buffer *buffer) | ||
| 175 | { | ||
| 176 | int pktstx = 0; | ||
| 177 | struct sgdma_descrip *descbase = | ||
| 178 | (struct sgdma_descrip *)priv->tx_dma_desc; | ||
| 179 | |||
| 180 | struct sgdma_descrip *cdesc = &descbase[0]; | ||
| 181 | struct sgdma_descrip *ndesc = &descbase[1]; | ||
| 182 | |||
| 183 | /* wait 'til the tx sgdma is ready for the next transmit request */ | ||
| 184 | if (sgdma_txbusy(priv)) | ||
| 185 | return 0; | ||
| 186 | |||
| 187 | sgdma_descrip(cdesc, /* current descriptor */ | ||
| 188 | ndesc, /* next descriptor */ | ||
| 189 | sgdma_txphysaddr(priv, ndesc), | ||
| 190 | buffer->dma_addr, /* address of packet to xmit */ | ||
| 191 | 0, /* write addr 0 for tx dma */ | ||
| 192 | buffer->len, /* length of packet */ | ||
| 193 | SGDMA_CONTROL_EOP, /* Generate EOP */ | ||
| 194 | 0, /* read fixed */ | ||
| 195 | SGDMA_CONTROL_WR_FIXED); /* Generate SOP */ | ||
| 196 | |||
| 197 | pktstx = sgdma_async_write(priv, cdesc); | ||
| 198 | |||
| 199 | /* enqueue the request to the pending transmit queue */ | ||
| 200 | queue_tx(priv, buffer); | ||
| 201 | |||
| 202 | return 1; | ||
| 203 | } | ||
| 204 | |||
| 205 | |||
| 206 | /* tx_lock held to protect access to queued tx list | ||
| 207 | */ | ||
| 208 | u32 sgdma_tx_completions(struct altera_tse_private *priv) | ||
| 209 | { | ||
| 210 | u32 ready = 0; | ||
| 211 | struct sgdma_descrip *desc = (struct sgdma_descrip *)priv->tx_dma_desc; | ||
| 212 | |||
| 213 | if (!sgdma_txbusy(priv) && | ||
| 214 | ((desc->control & SGDMA_CONTROL_HW_OWNED) == 0) && | ||
| 215 | (dequeue_tx(priv))) { | ||
| 216 | ready = 1; | ||
| 217 | } | ||
| 218 | |||
| 219 | return ready; | ||
| 220 | } | ||
| 221 | |||
| 222 | int sgdma_add_rx_desc(struct altera_tse_private *priv, | ||
| 223 | struct tse_buffer *rxbuffer) | ||
| 224 | { | ||
| 225 | queue_rx(priv, rxbuffer); | ||
| 226 | return sgdma_async_read(priv); | ||
| 227 | } | ||
| 228 | |||
| 229 | /* status is returned on upper 16 bits, | ||
| 230 | * length is returned in lower 16 bits | ||
| 231 | */ | ||
| 232 | u32 sgdma_rx_status(struct altera_tse_private *priv) | ||
| 233 | { | ||
| 234 | struct sgdma_csr *csr = (struct sgdma_csr *)priv->rx_dma_csr; | ||
| 235 | struct sgdma_descrip *base = (struct sgdma_descrip *)priv->rx_dma_desc; | ||
| 236 | struct sgdma_descrip *desc = NULL; | ||
| 237 | int pktsrx; | ||
| 238 | unsigned int rxstatus = 0; | ||
| 239 | unsigned int pktlength = 0; | ||
| 240 | unsigned int pktstatus = 0; | ||
| 241 | struct tse_buffer *rxbuffer = NULL; | ||
| 242 | |||
| 243 | dma_sync_single_for_cpu(priv->device, | ||
| 244 | priv->rxdescphys, | ||
| 245 | priv->rxdescmem, | ||
| 246 | DMA_BIDIRECTIONAL); | ||
| 247 | |||
| 248 | desc = &base[0]; | ||
| 249 | if ((ioread32(&csr->status) & SGDMA_STSREG_EOP) || | ||
| 250 | (desc->status & SGDMA_STATUS_EOP)) { | ||
| 251 | pktlength = desc->bytes_xferred; | ||
| 252 | pktstatus = desc->status & 0x3f; | ||
| 253 | rxstatus = pktstatus; | ||
| 254 | rxstatus = rxstatus << 16; | ||
| 255 | rxstatus |= (pktlength & 0xffff); | ||
| 256 | |||
| 257 | desc->status = 0; | ||
| 258 | |||
| 259 | rxbuffer = dequeue_rx(priv); | ||
| 260 | if (rxbuffer == NULL) | ||
| 261 | netdev_err(priv->dev, | ||
| 262 | "sgdma rx and rx queue empty!\n"); | ||
| 263 | |||
| 264 | /* kick the rx sgdma after reaping this descriptor */ | ||
| 265 | pktsrx = sgdma_async_read(priv); | ||
| 266 | } | ||
| 267 | |||
| 268 | return rxstatus; | ||
| 269 | } | ||
| 270 | |||
| 271 | |||
| 272 | /* Private functions */ | ||
| 273 | static void sgdma_descrip(struct sgdma_descrip *desc, | ||
| 274 | struct sgdma_descrip *ndesc, | ||
| 275 | dma_addr_t ndesc_phys, | ||
| 276 | dma_addr_t raddr, | ||
| 277 | dma_addr_t waddr, | ||
| 278 | u16 length, | ||
| 279 | int generate_eop, | ||
| 280 | int rfixed, | ||
| 281 | int wfixed) | ||
| 282 | { | ||
| 283 | /* Clear the next descriptor as not owned by hardware */ | ||
| 284 | u32 ctrl = ndesc->control; | ||
| 285 | ctrl &= ~SGDMA_CONTROL_HW_OWNED; | ||
| 286 | ndesc->control = ctrl; | ||
| 287 | |||
| 288 | ctrl = 0; | ||
| 289 | ctrl = SGDMA_CONTROL_HW_OWNED; | ||
| 290 | ctrl |= generate_eop; | ||
| 291 | ctrl |= rfixed; | ||
| 292 | ctrl |= wfixed; | ||
| 293 | |||
| 294 | /* Channel is implicitly zero, initialized to 0 by default */ | ||
| 295 | |||
| 296 | desc->raddr = raddr; | ||
| 297 | desc->waddr = waddr; | ||
| 298 | desc->next = lower_32_bits(ndesc_phys); | ||
| 299 | desc->control = ctrl; | ||
| 300 | desc->status = 0; | ||
| 301 | desc->rburst = 0; | ||
| 302 | desc->wburst = 0; | ||
| 303 | desc->bytes = length; | ||
| 304 | desc->bytes_xferred = 0; | ||
| 305 | } | ||
| 306 | |||
| 307 | /* If hardware is busy, don't restart async read. | ||
| 308 | * if status register is 0 - meaning initial state, restart async read, | ||
| 309 | * probably for the first time when populating a receive buffer. | ||
| 310 | * If read status indicate not busy and a status, restart the async | ||
| 311 | * DMA read. | ||
| 312 | */ | ||
| 313 | static int sgdma_async_read(struct altera_tse_private *priv) | ||
| 314 | { | ||
| 315 | struct sgdma_csr *csr = (struct sgdma_csr *)priv->rx_dma_csr; | ||
| 316 | struct sgdma_descrip *descbase = | ||
| 317 | (struct sgdma_descrip *)priv->rx_dma_desc; | ||
| 318 | |||
| 319 | struct sgdma_descrip *cdesc = &descbase[0]; | ||
| 320 | struct sgdma_descrip *ndesc = &descbase[1]; | ||
| 321 | |||
| 322 | unsigned int sts = ioread32(&csr->status); | ||
| 323 | struct tse_buffer *rxbuffer = NULL; | ||
| 324 | |||
| 325 | if (!sgdma_rxbusy(priv)) { | ||
| 326 | rxbuffer = queue_rx_peekhead(priv); | ||
| 327 | if (rxbuffer == NULL) | ||
| 328 | return 0; | ||
| 329 | |||
| 330 | sgdma_descrip(cdesc, /* current descriptor */ | ||
| 331 | ndesc, /* next descriptor */ | ||
| 332 | sgdma_rxphysaddr(priv, ndesc), | ||
| 333 | 0, /* read addr 0 for rx dma */ | ||
| 334 | rxbuffer->dma_addr, /* write addr for rx dma */ | ||
| 335 | 0, /* read 'til EOP */ | ||
| 336 | 0, /* EOP: NA for rx dma */ | ||
| 337 | 0, /* read fixed: NA for rx dma */ | ||
| 338 | 0); /* SOP: NA for rx DMA */ | ||
| 339 | |||
| 340 | /* clear control and status */ | ||
| 341 | iowrite32(0, &csr->control); | ||
| 342 | |||
| 343 | /* If status available, clear those bits */ | ||
| 344 | if (sts & 0xf) | ||
| 345 | iowrite32(0xf, &csr->status); | ||
| 346 | |||
| 347 | dma_sync_single_for_device(priv->device, | ||
| 348 | priv->rxdescphys, | ||
| 349 | priv->rxdescmem, | ||
| 350 | DMA_BIDIRECTIONAL); | ||
| 351 | |||
| 352 | iowrite32(lower_32_bits(sgdma_rxphysaddr(priv, cdesc)), | ||
| 353 | &csr->next_descrip); | ||
| 354 | |||
| 355 | iowrite32((priv->rxctrlreg | SGDMA_CTRLREG_START), | ||
| 356 | &csr->control); | ||
| 357 | |||
| 358 | return 1; | ||
| 359 | } | ||
| 360 | |||
| 361 | return 0; | ||
| 362 | } | ||
| 363 | |||
| 364 | static int sgdma_async_write(struct altera_tse_private *priv, | ||
| 365 | struct sgdma_descrip *desc) | ||
| 366 | { | ||
| 367 | struct sgdma_csr *csr = (struct sgdma_csr *)priv->tx_dma_csr; | ||
| 368 | |||
| 369 | if (sgdma_txbusy(priv)) | ||
| 370 | return 0; | ||
| 371 | |||
| 372 | /* clear control and status */ | ||
| 373 | iowrite32(0, &csr->control); | ||
| 374 | iowrite32(0x1f, &csr->status); | ||
| 375 | |||
| 376 | dma_sync_single_for_device(priv->device, priv->txdescphys, | ||
| 377 | priv->txdescmem, DMA_TO_DEVICE); | ||
| 378 | |||
| 379 | iowrite32(lower_32_bits(sgdma_txphysaddr(priv, desc)), | ||
| 380 | &csr->next_descrip); | ||
| 381 | |||
| 382 | iowrite32((priv->txctrlreg | SGDMA_CTRLREG_START), | ||
| 383 | &csr->control); | ||
| 384 | |||
| 385 | return 1; | ||
| 386 | } | ||
| 387 | |||
| 388 | static dma_addr_t | ||
| 389 | sgdma_txphysaddr(struct altera_tse_private *priv, | ||
| 390 | struct sgdma_descrip *desc) | ||
| 391 | { | ||
| 392 | dma_addr_t paddr = priv->txdescmem_busaddr; | ||
| 393 | uintptr_t offs = (uintptr_t)desc - (uintptr_t)priv->tx_dma_desc; | ||
| 394 | return (dma_addr_t)((uintptr_t)paddr + offs); | ||
| 395 | } | ||
| 396 | |||
| 397 | static dma_addr_t | ||
| 398 | sgdma_rxphysaddr(struct altera_tse_private *priv, | ||
| 399 | struct sgdma_descrip *desc) | ||
| 400 | { | ||
| 401 | dma_addr_t paddr = priv->rxdescmem_busaddr; | ||
| 402 | uintptr_t offs = (uintptr_t)desc - (uintptr_t)priv->rx_dma_desc; | ||
| 403 | return (dma_addr_t)((uintptr_t)paddr + offs); | ||
| 404 | } | ||
| 405 | |||
| 406 | #define list_remove_head(list, entry, type, member) \ | ||
| 407 | do { \ | ||
| 408 | entry = NULL; \ | ||
| 409 | if (!list_empty(list)) { \ | ||
| 410 | entry = list_entry((list)->next, type, member); \ | ||
| 411 | list_del_init(&entry->member); \ | ||
| 412 | } \ | ||
| 413 | } while (0) | ||
| 414 | |||
| 415 | #define list_peek_head(list, entry, type, member) \ | ||
| 416 | do { \ | ||
| 417 | entry = NULL; \ | ||
| 418 | if (!list_empty(list)) { \ | ||
| 419 | entry = list_entry((list)->next, type, member); \ | ||
| 420 | } \ | ||
| 421 | } while (0) | ||
| 422 | |||
| 423 | /* adds a tse_buffer to the tail of a tx buffer list. | ||
| 424 | * assumes the caller is managing and holding a mutual exclusion | ||
| 425 | * primitive to avoid simultaneous pushes/pops to the list. | ||
| 426 | */ | ||
| 427 | static void | ||
| 428 | queue_tx(struct altera_tse_private *priv, struct tse_buffer *buffer) | ||
| 429 | { | ||
| 430 | list_add_tail(&buffer->lh, &priv->txlisthd); | ||
| 431 | } | ||
| 432 | |||
| 433 | |||
| 434 | /* adds a tse_buffer to the tail of a rx buffer list | ||
| 435 | * assumes the caller is managing and holding a mutual exclusion | ||
| 436 | * primitive to avoid simultaneous pushes/pops to the list. | ||
| 437 | */ | ||
| 438 | static void | ||
| 439 | queue_rx(struct altera_tse_private *priv, struct tse_buffer *buffer) | ||
| 440 | { | ||
| 441 | list_add_tail(&buffer->lh, &priv->rxlisthd); | ||
| 442 | } | ||
| 443 | |||
| 444 | /* dequeues a tse_buffer from the transmit buffer list, otherwise | ||
| 445 | * returns NULL if empty. | ||
| 446 | * assumes the caller is managing and holding a mutual exclusion | ||
| 447 | * primitive to avoid simultaneous pushes/pops to the list. | ||
| 448 | */ | ||
| 449 | static struct tse_buffer * | ||
| 450 | dequeue_tx(struct altera_tse_private *priv) | ||
| 451 | { | ||
| 452 | struct tse_buffer *buffer = NULL; | ||
| 453 | list_remove_head(&priv->txlisthd, buffer, struct tse_buffer, lh); | ||
| 454 | return buffer; | ||
| 455 | } | ||
| 456 | |||
| 457 | /* dequeues a tse_buffer from the receive buffer list, otherwise | ||
| 458 | * returns NULL if empty | ||
| 459 | * assumes the caller is managing and holding a mutual exclusion | ||
| 460 | * primitive to avoid simultaneous pushes/pops to the list. | ||
| 461 | */ | ||
| 462 | static struct tse_buffer * | ||
| 463 | dequeue_rx(struct altera_tse_private *priv) | ||
| 464 | { | ||
| 465 | struct tse_buffer *buffer = NULL; | ||
| 466 | list_remove_head(&priv->rxlisthd, buffer, struct tse_buffer, lh); | ||
| 467 | return buffer; | ||
| 468 | } | ||
| 469 | |||
| 470 | /* dequeues a tse_buffer from the receive buffer list, otherwise | ||
| 471 | * returns NULL if empty | ||
| 472 | * assumes the caller is managing and holding a mutual exclusion | ||
| 473 | * primitive to avoid simultaneous pushes/pops to the list while the | ||
| 474 | * head is being examined. | ||
| 475 | */ | ||
| 476 | static struct tse_buffer * | ||
| 477 | queue_rx_peekhead(struct altera_tse_private *priv) | ||
| 478 | { | ||
| 479 | struct tse_buffer *buffer = NULL; | ||
| 480 | list_peek_head(&priv->rxlisthd, buffer, struct tse_buffer, lh); | ||
| 481 | return buffer; | ||
| 482 | } | ||
| 483 | |||
| 484 | /* check and return rx sgdma status without polling | ||
| 485 | */ | ||
| 486 | static int sgdma_rxbusy(struct altera_tse_private *priv) | ||
| 487 | { | ||
| 488 | struct sgdma_csr *csr = (struct sgdma_csr *)priv->rx_dma_csr; | ||
| 489 | return ioread32(&csr->status) & SGDMA_STSREG_BUSY; | ||
| 490 | } | ||
| 491 | |||
| 492 | /* waits for the tx sgdma to finish it's current operation, returns 0 | ||
| 493 | * when it transitions to nonbusy, returns 1 if the operation times out | ||
| 494 | */ | ||
| 495 | static int sgdma_txbusy(struct altera_tse_private *priv) | ||
| 496 | { | ||
| 497 | int delay = 0; | ||
| 498 | struct sgdma_csr *csr = (struct sgdma_csr *)priv->tx_dma_csr; | ||
| 499 | |||
| 500 | /* if DMA is busy, wait for current transactino to finish */ | ||
| 501 | while ((ioread32(&csr->status) & SGDMA_STSREG_BUSY) && (delay++ < 100)) | ||
| 502 | udelay(1); | ||
| 503 | |||
| 504 | if (ioread32(&csr->status) & SGDMA_STSREG_BUSY) { | ||
| 505 | netdev_err(priv->dev, "timeout waiting for tx dma\n"); | ||
| 506 | return 1; | ||
| 507 | } | ||
| 508 | return 0; | ||
| 509 | } | ||
| @@ -0,0 +1,35 @@ | |||
| 1 | /* Altera TSE SGDMA and MSGDMA Linux driver | ||
| 2 | * Copyright (C) 2014 Altera Corporation. All rights reserved | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or modify it | ||
| 5 | * under the terms and conditions of the GNU General Public License, | ||
| 6 | * version 2, as published by the Free Software Foundation. | ||
| 7 | * | ||
| 8 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
| 9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 10 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
| 11 | * more details. | ||
| 12 | * | ||
| 13 | * You should have received a copy of the GNU General Public License along with | ||
| 14 | * this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 15 | */ | ||
| 16 | |||
| 17 | #ifndef __ALTERA_SGDMA_H__ | ||
| 18 | #define __ALTERA_SGDMA_H__ | ||
| 19 | |||
| 20 | void sgdma_reset(struct altera_tse_private *); | ||
| 21 | void sgdma_enable_txirq(struct altera_tse_private *); | ||
| 22 | void sgdma_enable_rxirq(struct altera_tse_private *); | ||
| 23 | void sgdma_disable_rxirq(struct altera_tse_private *); | ||
| 24 | void sgdma_disable_txirq(struct altera_tse_private *); | ||
| 25 | void sgdma_clear_rxirq(struct altera_tse_private *); | ||
| 26 | void sgdma_clear_txirq(struct altera_tse_private *); | ||
| 27 | int sgdma_tx_buffer(struct altera_tse_private *priv, struct tse_buffer *); | ||
| 28 | u32 sgdma_tx_completions(struct altera_tse_private *); | ||
| 29 | int sgdma_add_rx_desc(struct altera_tse_private *priv, struct tse_buffer *); | ||
| 30 | void sgdma_status(struct altera_tse_private *); | ||
| 31 | u32 sgdma_rx_status(struct altera_tse_private *); | ||
| 32 | int sgdma_initialize(struct altera_tse_private *); | ||
| 33 | void sgdma_uninitialize(struct altera_tse_private *); | ||
| 34 | |||
| 35 | #endif /* __ALTERA_SGDMA_H__ */ | ||
| @@ -0,0 +1,124 @@ | |||
| 1 | /* Altera TSE SGDMA and MSGDMA Linux driver | ||
| 2 | * Copyright (C) 2014 Altera Corporation. All rights reserved | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or modify it | ||
| 5 | * under the terms and conditions of the GNU General Public License, | ||
| 6 | * version 2, as published by the Free Software Foundation. | ||
| 7 | * | ||
| 8 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
| 9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 10 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
| 11 | * more details. | ||
| 12 | * | ||
| 13 | * You should have received a copy of the GNU General Public License along with | ||
| 14 | * this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 15 | */ | ||
| 16 | |||
| 17 | #ifndef __ALTERA_SGDMAHW_H__ | ||
| 18 | #define __ALTERA_SGDMAHW_H__ | ||
| 19 | |||
| 20 | /* SGDMA descriptor structure */ | ||
| 21 | struct sgdma_descrip { | ||
| 22 | unsigned int raddr; /* address of data to be read */ | ||
| 23 | unsigned int pad1; | ||
| 24 | unsigned int waddr; | ||
| 25 | unsigned int pad2; | ||
| 26 | unsigned int next; | ||
| 27 | unsigned int pad3; | ||
| 28 | unsigned short bytes; | ||
| 29 | unsigned char rburst; | ||
| 30 | unsigned char wburst; | ||
| 31 | unsigned short bytes_xferred; /* 16 bits, bytes xferred */ | ||
| 32 | |||
| 33 | /* bit 0: error | ||
| 34 | * bit 1: length error | ||
| 35 | * bit 2: crc error | ||
| 36 | * bit 3: truncated error | ||
| 37 | * bit 4: phy error | ||
| 38 | * bit 5: collision error | ||
| 39 | * bit 6: reserved | ||
| 40 | * bit 7: status eop for recv case | ||
| 41 | */ | ||
| 42 | unsigned char status; | ||
| 43 | |||
| 44 | /* bit 0: eop | ||
| 45 | * bit 1: read_fixed | ||
| 46 | * bit 2: write fixed | ||
| 47 | * bits 3,4,5,6: Channel (always 0) | ||
| 48 | * bit 7: hardware owned | ||
| 49 | */ | ||
| 50 | unsigned char control; | ||
| 51 | } __packed; | ||
| 52 | |||
| 53 | |||
| 54 | #define SGDMA_STATUS_ERR BIT(0) | ||
| 55 | #define SGDMA_STATUS_LENGTH_ERR BIT(1) | ||
| 56 | #define SGDMA_STATUS_CRC_ERR BIT(2) | ||
| 57 | #define SGDMA_STATUS_TRUNC_ERR BIT(3) | ||
| 58 | #define SGDMA_STATUS_PHY_ERR BIT(4) | ||
| 59 | #define SGDMA_STATUS_COLL_ERR BIT(5) | ||
| 60 | #define SGDMA_STATUS_EOP BIT(7) | ||
| 61 | |||
| 62 | #define SGDMA_CONTROL_EOP BIT(0) | ||
| 63 | #define SGDMA_CONTROL_RD_FIXED BIT(1) | ||
| 64 | #define SGDMA_CONTROL_WR_FIXED BIT(2) | ||
| 65 | |||
| 66 | /* Channel is always 0, so just zero initialize it */ | ||
| 67 | |||
| 68 | #define SGDMA_CONTROL_HW_OWNED BIT(7) | ||
| 69 | |||
| 70 | /* SGDMA register space */ | ||
| 71 | struct sgdma_csr { | ||
| 72 | /* bit 0: error | ||
| 73 | * bit 1: eop | ||
| 74 | * bit 2: descriptor completed | ||
| 75 | * bit 3: chain completed | ||
| 76 | * bit 4: busy | ||
| 77 | * remainder reserved | ||
| 78 | */ | ||
| 79 | u32 status; | ||
| 80 | u32 pad1[3]; | ||
| 81 | |||
| 82 | /* bit 0: interrupt on error | ||
| 83 | * bit 1: interrupt on eop | ||
| 84 | * bit 2: interrupt after every descriptor | ||
| 85 | * bit 3: interrupt after last descrip in a chain | ||
| 86 | * bit 4: global interrupt enable | ||
| 87 | * bit 5: starts descriptor processing | ||
| 88 | * bit 6: stop core on dma error | ||
| 89 | * bit 7: interrupt on max descriptors | ||
| 90 | * bits 8-15: max descriptors to generate interrupt | ||
| 91 | * bit 16: Software reset | ||
| 92 | * bit 17: clears owned by hardware if 0, does not clear otherwise | ||
| 93 | * bit 18: enables descriptor polling mode | ||
| 94 | * bit 19-26: clocks before polling again | ||
| 95 | * bit 27-30: reserved | ||
| 96 | * bit 31: clear interrupt | ||
| 97 | */ | ||
| 98 | u32 control; | ||
| 99 | u32 pad2[3]; | ||
| 100 | u32 next_descrip; | ||
| 101 | u32 pad3[3]; | ||
| 102 | }; | ||
| 103 | |||
| 104 | |||
| 105 | #define SGDMA_STSREG_ERR BIT(0) /* Error */ | ||
| 106 | #define SGDMA_STSREG_EOP BIT(1) /* EOP */ | ||
| 107 | #define SGDMA_STSREG_DESCRIP BIT(2) /* Descriptor completed */ | ||
| 108 | #define SGDMA_STSREG_CHAIN BIT(3) /* Chain completed */ | ||
| 109 | #define SGDMA_STSREG_BUSY BIT(4) /* Controller busy */ | ||
| 110 | |||
| 111 | #define SGDMA_CTRLREG_IOE BIT(0) /* Interrupt on error */ | ||
| 112 | #define SGDMA_CTRLREG_IOEOP BIT(1) /* Interrupt on EOP */ | ||
| 113 | #define SGDMA_CTRLREG_IDESCRIP BIT(2) /* Interrupt after every descriptor */ | ||
| 114 | #define SGDMA_CTRLREG_ILASTD BIT(3) /* Interrupt after last descriptor */ | ||
| 115 | #define SGDMA_CTRLREG_INTEN BIT(4) /* Global Interrupt enable */ | ||
| 116 | #define SGDMA_CTRLREG_START BIT(5) /* starts descriptor processing */ | ||
| 117 | #define SGDMA_CTRLREG_STOPERR BIT(6) /* stop on dma error */ | ||
| 118 | #define SGDMA_CTRLREG_INTMAX BIT(7) /* Interrupt on max descriptors */ | ||
| 119 | #define SGDMA_CTRLREG_RESET BIT(16)/* Software reset */ | ||
| 120 | #define SGDMA_CTRLREG_COBHW BIT(17)/* Clears owned by hardware */ | ||
| 121 | #define SGDMA_CTRLREG_POLL BIT(18)/* enables descriptor polling mode */ | ||
| 122 | #define SGDMA_CTRLREG_CLRINT BIT(31)/* Clears interrupt */ | ||
| 123 | |||
| 124 | #endif /* __ALTERA_SGDMAHW_H__ */ | ||
| @@ -0,0 +1,486 @@ | |||
| 1 | /* Altera Triple-Speed Ethernet MAC driver | ||
| 2 | * Copyright (C) 2008-2014 Altera Corporation. All rights reserved | ||
| 3 | * | ||
| 4 | * Contributors: | ||
| 5 | * Dalon Westergreen | ||
| 6 | * Thomas Chou | ||
| 7 | * Ian Abbott | ||
| 8 | * Yuriy Kozlov | ||
| 9 | * Tobias Klauser | ||
| 10 | * Andriy Smolskyy | ||
| 11 | * Roman Bulgakov | ||
| 12 | * Dmytro Mytarchuk | ||
| 13 | * Matthew Gerlach | ||
| 14 | * | ||
| 15 | * Original driver contributed by SLS. | ||
| 16 | * Major updates contributed by GlobalLogic | ||
| 17 | * | ||
| 18 | * This program is free software; you can redistribute it and/or modify it | ||
| 19 | * under the terms and conditions of the GNU General Public License, | ||
| 20 | * version 2, as published by the Free Software Foundation. | ||
| 21 | * | ||
| 22 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
| 23 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 24 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
| 25 | * more details. | ||
| 26 | * | ||
| 27 | * You should have received a copy of the GNU General Public License along with | ||
| 28 | * this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 29 | */ | ||
| 30 | |||
| 31 | #ifndef __ALTERA_TSE_H__ | ||
| 32 | #define __ALTERA_TSE_H__ | ||
| 33 | |||
| 34 | #define ALTERA_TSE_RESOURCE_NAME "altera_tse" | ||
| 35 | |||
| 36 | #include <linux/bitops.h> | ||
| 37 | #include <linux/if_vlan.h> | ||
| 38 | #include <linux/list.h> | ||
| 39 | #include <linux/netdevice.h> | ||
| 40 | #include <linux/phy.h> | ||
| 41 | |||
| 42 | #define ALTERA_TSE_SW_RESET_WATCHDOG_CNTR 10000 | ||
| 43 | #define ALTERA_TSE_MAC_FIFO_WIDTH 4 /* TX/RX FIFO width in | ||
| 44 | * bytes | ||
| 45 | */ | ||
| 46 | /* Rx FIFO default settings */ | ||
| 47 | #define ALTERA_TSE_RX_SECTION_EMPTY 16 | ||
| 48 | #define ALTERA_TSE_RX_SECTION_FULL 0 | ||
| 49 | #define ALTERA_TSE_RX_ALMOST_EMPTY 8 | ||
| 50 | #define ALTERA_TSE_RX_ALMOST_FULL 8 | ||
| 51 | |||
| 52 | /* Tx FIFO default settings */ | ||
| 53 | #define ALTERA_TSE_TX_SECTION_EMPTY 16 | ||
| 54 | #define ALTERA_TSE_TX_SECTION_FULL 0 | ||
| 55 | #define ALTERA_TSE_TX_ALMOST_EMPTY 8 | ||
| 56 | #define ALTERA_TSE_TX_ALMOST_FULL 3 | ||
| 57 | |||
| 58 | /* MAC function configuration default settings */ | ||
| 59 | #define ALTERA_TSE_TX_IPG_LENGTH 12 | ||
| 60 | |||
| 61 | #define GET_BIT_VALUE(v, bit) (((v) >> (bit)) & 0x1) | ||
| 62 | |||
| 63 | /* MAC Command_Config Register Bit Definitions | ||
| 64 | */ | ||
| 65 | #define MAC_CMDCFG_TX_ENA BIT(0) | ||
| 66 | #define MAC_CMDCFG_RX_ENA BIT(1) | ||
| 67 | #define MAC_CMDCFG_XON_GEN BIT(2) | ||
| 68 | #define MAC_CMDCFG_ETH_SPEED BIT(3) | ||
| 69 | #define MAC_CMDCFG_PROMIS_EN BIT(4) | ||
| 70 | #define MAC_CMDCFG_PAD_EN BIT(5) | ||
| 71 | #define MAC_CMDCFG_CRC_FWD BIT(6) | ||
| 72 | #define MAC_CMDCFG_PAUSE_FWD BIT(7) | ||
| 73 | #define MAC_CMDCFG_PAUSE_IGNORE BIT(8) | ||
| 74 | #define MAC_CMDCFG_TX_ADDR_INS BIT(9) | ||
| 75 | #define MAC_CMDCFG_HD_ENA BIT(10) | ||
| 76 | #define MAC_CMDCFG_EXCESS_COL BIT(11) | ||
| 77 | #define MAC_CMDCFG_LATE_COL BIT(12) | ||
| 78 | #define MAC_CMDCFG_SW_RESET BIT(13) | ||
| 79 | #define MAC_CMDCFG_MHASH_SEL BIT(14) | ||
| 80 | #define MAC_CMDCFG_LOOP_ENA BIT(15) | ||
| 81 | #define MAC_CMDCFG_TX_ADDR_SEL(v) (((v) & 0x7) << 16) | ||
| 82 | #define MAC_CMDCFG_MAGIC_ENA BIT(19) | ||
| 83 | #define MAC_CMDCFG_SLEEP BIT(20) | ||
| 84 | #define MAC_CMDCFG_WAKEUP BIT(21) | ||
| 85 | #define MAC_CMDCFG_XOFF_GEN BIT(22) | ||
| 86 | #define MAC_CMDCFG_CNTL_FRM_ENA BIT(23) | ||
| 87 | #define MAC_CMDCFG_NO_LGTH_CHECK BIT(24) | ||
| 88 | #define MAC_CMDCFG_ENA_10 BIT(25) | ||
| 89 | #define MAC_CMDCFG_RX_ERR_DISC BIT(26) | ||
| 90 | #define MAC_CMDCFG_DISABLE_READ_TIMEOUT BIT(27) | ||
| 91 | #define MAC_CMDCFG_CNT_RESET BIT(31) | ||
| 92 | |||
| 93 | #define MAC_CMDCFG_TX_ENA_GET(v) GET_BIT_VALUE(v, 0) | ||
| 94 | #define MAC_CMDCFG_RX_ENA_GET(v) GET_BIT_VALUE(v, 1) | ||
| 95 | #define MAC_CMDCFG_XON_GEN_GET(v) GET_BIT_VALUE(v, 2) | ||
| 96 | #define MAC_CMDCFG_ETH_SPEED_GET(v) GET_BIT_VALUE(v, 3) | ||
| 97 | #define MAC_CMDCFG_PROMIS_EN_GET(v) GET_BIT_VALUE(v, 4) | ||
| 98 | #define MAC_CMDCFG_PAD_EN_GET(v) GET_BIT_VALUE(v, 5) | ||
| 99 | #define MAC_CMDCFG_CRC_FWD_GET(v) GET_BIT_VALUE(v, 6) | ||
| 100 | #define MAC_CMDCFG_PAUSE_FWD_GET(v) GET_BIT_VALUE(v, 7) | ||
| 101 | #define MAC_CMDCFG_PAUSE_IGNORE_GET(v) GET_BIT_VALUE(v, 8) | ||
| 102 | #define MAC_CMDCFG_TX_ADDR_INS_GET(v) GET_BIT_VALUE(v, 9) | ||
| 103 | #define MAC_CMDCFG_HD_ENA_GET(v) GET_BIT_VALUE(v, 10) | ||
| 104 | #define MAC_CMDCFG_EXCESS_COL_GET(v) GET_BIT_VALUE(v, 11) | ||
| 105 | #define MAC_CMDCFG_LATE_COL_GET(v) GET_BIT_VALUE(v, 12) | ||
| 106 | #define MAC_CMDCFG_SW_RESET_GET(v) GET_BIT_VALUE(v, 13) | ||
| 107 | #define MAC_CMDCFG_MHASH_SEL_GET(v) GET_BIT_VALUE(v, 14) | ||
| 108 | #define MAC_CMDCFG_LOOP_ENA_GET(v) GET_BIT_VALUE(v, 15) | ||
| 109 | #define MAC_CMDCFG_TX_ADDR_SEL_GET(v) (((v) >> 16) & 0x7) | ||
| 110 | #define MAC_CMDCFG_MAGIC_ENA_GET(v) GET_BIT_VALUE(v, 19) | ||
| 111 | #define MAC_CMDCFG_SLEEP_GET(v) GET_BIT_VALUE(v, 20) | ||
| 112 | #define MAC_CMDCFG_WAKEUP_GET(v) GET_BIT_VALUE(v, 21) | ||
| 113 | #define MAC_CMDCFG_XOFF_GEN_GET(v) GET_BIT_VALUE(v, 22) | ||
| 114 | #define MAC_CMDCFG_CNTL_FRM_ENA_GET(v) GET_BIT_VALUE(v, 23) | ||
| 115 | #define MAC_CMDCFG_NO_LGTH_CHECK_GET(v) GET_BIT_VALUE(v, 24) | ||
| 116 | #define MAC_CMDCFG_ENA_10_GET(v) GET_BIT_VALUE(v, 25) | ||
| 117 | #define MAC_CMDCFG_RX_ERR_DISC_GET(v) GET_BIT_VALUE(v, 26) | ||
| 118 | #define MAC_CMDCFG_DISABLE_READ_TIMEOUT_GET(v) GET_BIT_VALUE(v, 27) | ||
| 119 | #define MAC_CMDCFG_CNT_RESET_GET(v) GET_BIT_VALUE(v, 31) | ||
| 120 | |||
| 121 | /* MDIO registers within MAC register Space | ||
| 122 | */ | ||
| 123 | struct altera_tse_mdio { | ||
| 124 | u32 control; /* PHY device operation control register */ | ||
| 125 | u32 status; /* PHY device operation status register */ | ||
| 126 | u32 phy_id1; /* Bits 31:16 of PHY identifier */ | ||
| 127 | u32 phy_id2; /* Bits 15:0 of PHY identifier */ | ||
| 128 | u32 auto_negotiation_advertisement; /* Auto-negotiation | ||
| 129 | * advertisement | ||
| 130 | * register | ||
| 131 | */ | ||
| 132 | u32 remote_partner_base_page_ability; | ||
| 133 | |||
| 134 | u32 reg6; | ||
| 135 | u32 reg7; | ||
| 136 | u32 reg8; | ||
| 137 | u32 reg9; | ||
| 138 | u32 rega; | ||
| 139 | u32 regb; | ||
| 140 | u32 regc; | ||
| 141 | u32 regd; | ||
| 142 | u32 rege; | ||
| 143 | u32 regf; | ||
| 144 | u32 reg10; | ||
| 145 | u32 reg11; | ||
| 146 | u32 reg12; | ||
| 147 | u32 reg13; | ||
| 148 | u32 reg14; | ||
| 149 | u32 reg15; | ||
| 150 | u32 reg16; | ||
| 151 | u32 reg17; | ||
| 152 | u32 reg18; | ||
| 153 | u32 reg19; | ||
| 154 | u32 reg1a; | ||
| 155 | u32 reg1b; | ||
| 156 | u32 reg1c; | ||
| 157 | u32 reg1d; | ||
| 158 | u32 reg1e; | ||
| 159 | u32 reg1f; | ||
| 160 | }; | ||
| 161 | |||
| 162 | /* MAC register Space. Note that some of these registers may or may not be | ||
| 163 | * present depending upon options chosen by the user when the core was | ||
| 164 | * configured and built. Please consult the Altera Triple Speed Ethernet User | ||
| 165 | * Guide for details. | ||
| 166 | */ | ||
| 167 | struct altera_tse_mac { | ||
| 168 | /* Bits 15:0: MegaCore function revision (0x0800). Bit 31:16: Customer | ||
| 169 | * specific revision | ||
| 170 | */ | ||
| 171 | u32 megacore_revision; | ||
| 172 | /* Provides a memory location for user applications to test the device | ||
| 173 | * memory operation. | ||
| 174 | */ | ||
| 175 | u32 scratch_pad; | ||
| 176 | /* The host processor uses this register to control and configure the | ||
| 177 | * MAC block | ||
| 178 | */ | ||
| 179 | u32 command_config; | ||
| 180 | /* 32-bit primary MAC address word 0 bits 0 to 31 of the primary | ||
| 181 | * MAC address | ||
| 182 | */ | ||
| 183 | u32 mac_addr_0; | ||
| 184 | /* 32-bit primary MAC address word 1 bits 32 to 47 of the primary | ||
| 185 | * MAC address | ||
| 186 | */ | ||
| 187 | u32 mac_addr_1; | ||
| 188 | /* 14-bit maximum frame length. The MAC receive logic */ | ||
| 189 | u32 frm_length; | ||
| 190 | /* The pause quanta is used in each pause frame sent to a remote | ||
| 191 | * Ethernet device, in increments of 512 Ethernet bit times | ||
| 192 | */ | ||
| 193 | u32 pause_quanta; | ||
| 194 | /* 12-bit receive FIFO section-empty threshold */ | ||
| 195 | u32 rx_section_empty; | ||
| 196 | /* 12-bit receive FIFO section-full threshold */ | ||
| 197 | u32 rx_section_full; | ||
| 198 | /* 12-bit transmit FIFO section-empty threshold */ | ||
| 199 | u32 tx_section_empty; | ||
| 200 | /* 12-bit transmit FIFO section-full threshold */ | ||
| 201 | u32 tx_section_full; | ||
| 202 | /* 12-bit receive FIFO almost-empty threshold */ | ||
| 203 | u32 rx_almost_empty; | ||
| 204 | /* 12-bit receive FIFO almost-full threshold */ | ||
| 205 | u32 rx_almost_full; | ||
| 206 | /* 12-bit transmit FIFO almost-empty threshold */ | ||
| 207 | u32 tx_almost_empty; | ||
| 208 | /* 12-bit transmit FIFO almost-full threshold */ | ||
| 209 | u32 tx_almost_full; | ||
| 210 | /* MDIO address of PHY Device 0. Bits 0 to 4 hold a 5-bit PHY address */ | ||
| 211 | u32 mdio_phy0_addr; | ||
| 212 | /* MDIO address of PHY Device 1. Bits 0 to 4 hold a 5-bit PHY address */ | ||
| 213 | u32 mdio_phy1_addr; | ||
| 214 | |||
| 215 | /* Bit[15:0]—16-bit holdoff quanta */ | ||
| 216 | u32 holdoff_quant; | ||
| 217 | |||
| 218 | /* only if 100/1000 BaseX PCS, reserved otherwise */ | ||
| 219 | u32 reserved1[5]; | ||
| 220 | |||
| 221 | /* Minimum IPG between consecutive transmit frame in terms of bytes */ | ||
| 222 | u32 tx_ipg_length; | ||
| 223 | |||
| 224 | /* IEEE 802.3 oEntity Managed Object Support */ | ||
| 225 | |||
| 226 | /* The MAC addresses */ | ||
| 227 | u32 mac_id_1; | ||
| 228 | u32 mac_id_2; | ||
| 229 | |||
| 230 | /* Number of frames transmitted without error including pause frames */ | ||
| 231 | u32 frames_transmitted_ok; | ||
| 232 | /* Number of frames received without error including pause frames */ | ||
| 233 | u32 frames_received_ok; | ||
| 234 | /* Number of frames received with a CRC error */ | ||
| 235 | u32 frames_check_sequence_errors; | ||
| 236 | /* Frame received with an alignment error */ | ||
| 237 | u32 alignment_errors; | ||
| 238 | /* Sum of payload and padding octets of frames transmitted without | ||
| 239 | * error | ||
| 240 | */ | ||
| 241 | u32 octets_transmitted_ok; | ||
| 242 | /* Sum of payload and padding octets of frames received without error */ | ||
| 243 | u32 octets_received_ok; | ||
| 244 | |||
| 245 | /* IEEE 802.3 oPausedEntity Managed Object Support */ | ||
| 246 | |||
| 247 | /* Number of transmitted pause frames */ | ||
| 248 | u32 tx_pause_mac_ctrl_frames; | ||
| 249 | /* Number of Received pause frames */ | ||
| 250 | u32 rx_pause_mac_ctrl_frames; | ||
| 251 | |||
| 252 | /* IETF MIB (MIB-II) Object Support */ | ||
| 253 | |||
| 254 | /* Number of frames received with error */ | ||
| 255 | u32 if_in_errors; | ||
| 256 | /* Number of frames transmitted with error */ | ||
| 257 | u32 if_out_errors; | ||
| 258 | /* Number of valid received unicast frames */ | ||
| 259 | u32 if_in_ucast_pkts; | ||
| 260 | /* Number of valid received multicasts frames (without pause) */ | ||
| 261 | u32 if_in_multicast_pkts; | ||
| 262 | /* Number of valid received broadcast frames */ | ||
| 263 | u32 if_in_broadcast_pkts; | ||
| 264 | u32 if_out_discards; | ||
| 265 | /* The number of valid unicast frames transmitted */ | ||
| 266 | u32 if_out_ucast_pkts; | ||
| 267 | /* The number of valid multicast frames transmitted, | ||
| 268 | * excluding pause frames | ||
| 269 | */ | ||
| 270 | u32 if_out_multicast_pkts; | ||
| 271 | u32 if_out_broadcast_pkts; | ||
| 272 | |||
| 273 | /* IETF RMON MIB Object Support */ | ||
| 274 | |||
| 275 | /* Counts the number of dropped packets due to internal errors | ||
| 276 | * of the MAC client. | ||
| 277 | */ | ||
| 278 | u32 ether_stats_drop_events; | ||
| 279 | /* Total number of bytes received. Good and bad frames. */ | ||
| 280 | u32 ether_stats_octets; | ||
| 281 | /* Total number of packets received. Counts good and bad packets. */ | ||
| 282 | u32 ether_stats_pkts; | ||
| 283 | /* Number of packets received with less than 64 bytes. */ | ||
| 284 | u32 ether_stats_undersize_pkts; | ||
| 285 | /* The number of frames received that are longer than the | ||
| 286 | * value configured in the frm_length register | ||
| 287 | */ | ||
| 288 | u32 ether_stats_oversize_pkts; | ||
| 289 | /* Number of received packet with 64 bytes */ | ||
| 290 | u32 ether_stats_pkts_64_octets; | ||
| 291 | /* Frames (good and bad) with 65 to 127 bytes */ | ||
| 292 | u32 ether_stats_pkts_65to127_octets; | ||
| 293 | /* Frames (good and bad) with 128 to 255 bytes */ | ||
| 294 | u32 ether_stats_pkts_128to255_octets; | ||
| 295 | /* Frames (good and bad) with 256 to 511 bytes */ | ||
| 296 | u32 ether_stats_pkts_256to511_octets; | ||
| 297 | /* Frames (good and bad) with 512 to 1023 bytes */ | ||
| 298 | u32 ether_stats_pkts_512to1023_octets; | ||
| 299 | /* Frames (good and bad) with 1024 to 1518 bytes */ | ||
| 300 | u32 ether_stats_pkts_1024to1518_octets; | ||
| 301 | |||
| 302 | /* Any frame length from 1519 to the maximum length configured in the | ||
| 303 | * frm_length register, if it is greater than 1518 | ||
| 304 | */ | ||
| 305 | u32 ether_stats_pkts_1519tox_octets; | ||
| 306 | /* Too long frames with CRC error */ | ||
| 307 | u32 ether_stats_jabbers; | ||
| 308 | /* Too short frames with CRC error */ | ||
| 309 | u32 ether_stats_fragments; | ||
| 310 | |||
| 311 | u32 reserved2; | ||
| 312 | |||
| 313 | /* FIFO control register */ | ||
| 314 | u32 tx_cmd_stat; | ||
| 315 | u32 rx_cmd_stat; | ||
| 316 | |||
| 317 | /* Extended Statistics Counters */ | ||
| 318 | u32 msb_octets_transmitted_ok; | ||
| 319 | u32 msb_octets_received_ok; | ||
| 320 | u32 msb_ether_stats_octets; | ||
| 321 | |||
| 322 | u32 reserved3; | ||
| 323 | |||
| 324 | /* Multicast address resolution table, mapped in the controller address | ||
| 325 | * space | ||
| 326 | */ | ||
| 327 | u32 hash_table[64]; | ||
| 328 | |||
| 329 | /* Registers 0 to 31 within PHY device 0/1 connected to the MDIO PHY | ||
| 330 | * management interface | ||
| 331 | */ | ||
| 332 | struct altera_tse_mdio mdio_phy0; | ||
| 333 | struct altera_tse_mdio mdio_phy1; | ||
| 334 | |||
| 335 | /* 4 Supplemental MAC Addresses */ | ||
| 336 | u32 supp_mac_addr_0_0; | ||
| 337 | u32 supp_mac_addr_0_1; | ||
| 338 | u32 supp_mac_addr_1_0; | ||
| 339 | u32 supp_mac_addr_1_1; | ||
| 340 | u32 supp_mac_addr_2_0; | ||
| 341 | u32 supp_mac_addr_2_1; | ||
| 342 | u32 supp_mac_addr_3_0; | ||
| 343 | u32 supp_mac_addr_3_1; | ||
| 344 | |||
| 345 | u32 reserved4[8]; | ||
| 346 | |||
| 347 | /* IEEE 1588v2 Feature */ | ||
| 348 | u32 tx_period; | ||
| 349 | u32 tx_adjust_fns; | ||
| 350 | u32 tx_adjust_ns; | ||
| 351 | u32 rx_period; | ||
| 352 | u32 rx_adjust_fns; | ||
| 353 | u32 rx_adjust_ns; | ||
| 354 | |||
| 355 | u32 reserved5[42]; | ||
| 356 | }; | ||
| 357 | |||
| 358 | /* Transmit and Receive Command Registers Bit Definitions | ||
| 359 | */ | ||
| 360 | #define ALTERA_TSE_TX_CMD_STAT_OMIT_CRC BIT(17) | ||
| 361 | #define ALTERA_TSE_TX_CMD_STAT_TX_SHIFT16 BIT(18) | ||
| 362 | #define ALTERA_TSE_RX_CMD_STAT_RX_SHIFT16 BIT(25) | ||
| 363 | |||
| 364 | /* Wrapper around a pointer to a socket buffer, | ||
| 365 | * so a DMA handle can be stored along with the buffer | ||
| 366 | */ | ||
| 367 | struct tse_buffer { | ||
| 368 | struct list_head lh; | ||
| 369 | struct sk_buff *skb; | ||
| 370 | dma_addr_t dma_addr; | ||
| 371 | u32 len; | ||
| 372 | int mapped_as_page; | ||
| 373 | }; | ||
| 374 | |||
| 375 | struct altera_tse_private; | ||
| 376 | |||
| 377 | #define ALTERA_DTYPE_SGDMA 1 | ||
| 378 | #define ALTERA_DTYPE_MSGDMA 2 | ||
| 379 | |||
| 380 | /* standard DMA interface for SGDMA and MSGDMA */ | ||
| 381 | struct altera_dmaops { | ||
| 382 | int altera_dtype; | ||
| 383 | int dmamask; | ||
| 384 | void (*reset_dma)(struct altera_tse_private *); | ||
| 385 | void (*enable_txirq)(struct altera_tse_private *); | ||
| 386 | void (*enable_rxirq)(struct altera_tse_private *); | ||
| 387 | void (*disable_txirq)(struct altera_tse_private *); | ||
| 388 | void (*disable_rxirq)(struct altera_tse_private *); | ||
| 389 | void (*clear_txirq)(struct altera_tse_private *); | ||
| 390 | void (*clear_rxirq)(struct altera_tse_private *); | ||
| 391 | int (*tx_buffer)(struct altera_tse_private *, struct tse_buffer *); | ||
| 392 | u32 (*tx_completions)(struct altera_tse_private *); | ||
| 393 | int (*add_rx_desc)(struct altera_tse_private *, struct tse_buffer *); | ||
| 394 | u32 (*get_rx_status)(struct altera_tse_private *); | ||
| 395 | int (*init_dma)(struct altera_tse_private *); | ||
| 396 | void (*uninit_dma)(struct altera_tse_private *); | ||
| 397 | }; | ||
| 398 | |||
| 399 | /* This structure is private to each device. | ||
| 400 | */ | ||
| 401 | struct altera_tse_private { | ||
| 402 | struct net_device *dev; | ||
| 403 | struct device *device; | ||
| 404 | struct napi_struct napi; | ||
| 405 | |||
| 406 | /* MAC address space */ | ||
| 407 | struct altera_tse_mac __iomem *mac_dev; | ||
| 408 | |||
| 409 | /* TSE Revision */ | ||
| 410 | u32 revision; | ||
| 411 | |||
| 412 | /* mSGDMA Rx Dispatcher address space */ | ||
| 413 | void __iomem *rx_dma_csr; | ||
| 414 | void __iomem *rx_dma_desc; | ||
| 415 | void __iomem *rx_dma_resp; | ||
| 416 | |||
| 417 | /* mSGDMA Tx Dispatcher address space */ | ||
| 418 | void __iomem *tx_dma_csr; | ||
| 419 | void __iomem *tx_dma_desc; | ||
| 420 | |||
| 421 | /* Rx buffers queue */ | ||
| 422 | struct tse_buffer *rx_ring; | ||
| 423 | u32 rx_cons; | ||
| 424 | u32 rx_prod; | ||
| 425 | u32 rx_ring_size; | ||
| 426 | u32 rx_dma_buf_sz; | ||
| 427 | |||
| 428 | /* Tx ring buffer */ | ||
| 429 | struct tse_buffer *tx_ring; | ||
| 430 | u32 tx_prod; | ||
| 431 | u32 tx_cons; | ||
| 432 | u32 tx_ring_size; | ||
| 433 | |||
| 434 | /* Interrupts */ | ||
| 435 | u32 tx_irq; | ||
| 436 | u32 rx_irq; | ||
| 437 | |||
| 438 | /* RX/TX MAC FIFO configs */ | ||
| 439 | u32 tx_fifo_depth; | ||
| 440 | u32 rx_fifo_depth; | ||
| 441 | u32 max_mtu; | ||
| 442 | |||
| 443 | /* Hash filter settings */ | ||
| 444 | u32 hash_filter; | ||
| 445 | u32 added_unicast; | ||
| 446 | |||
| 447 | /* Descriptor memory info for managing SGDMA */ | ||
| 448 | u32 txdescmem; | ||
| 449 | u32 rxdescmem; | ||
| 450 | dma_addr_t rxdescmem_busaddr; | ||
| 451 | dma_addr_t txdescmem_busaddr; | ||
| 452 | u32 txctrlreg; | ||
| 453 | u32 rxctrlreg; | ||
| 454 | dma_addr_t rxdescphys; | ||
| 455 | dma_addr_t txdescphys; | ||
| 456 | |||
| 457 | struct list_head txlisthd; | ||
| 458 | struct list_head rxlisthd; | ||
| 459 | |||
| 460 | /* MAC command_config register protection */ | ||
| 461 | spinlock_t mac_cfg_lock; | ||
| 462 | /* Tx path protection */ | ||
| 463 | spinlock_t tx_lock; | ||
| 464 | /* Rx DMA & interrupt control protection */ | ||
| 465 | spinlock_t rxdma_irq_lock; | ||
| 466 | |||
| 467 | /* PHY */ | ||
| 468 | int phy_addr; /* PHY's MDIO address, -1 for autodetection */ | ||
| 469 | phy_interface_t phy_iface; | ||
| 470 | struct mii_bus *mdio; | ||
| 471 | struct phy_device *phydev; | ||
| 472 | int oldspeed; | ||
| 473 | int oldduplex; | ||
| 474 | int oldlink; | ||
| 475 | |||
| 476 | /* ethtool msglvl option */ | ||
| 477 | u32 msg_enable; | ||
| 478 | |||
| 479 | struct altera_dmaops *dmaops; | ||
| 480 | }; | ||
| 481 | |||
| 482 | /* Function prototypes | ||
| 483 | */ | ||
| 484 | void altera_tse_set_ethtool_ops(struct net_device *); | ||
| 485 | |||
| 486 | #endif /* __ALTERA_TSE_H__ */ | ||
| @@ -0,0 +1,235 @@ | |||
| 1 | /* Ethtool support for Altera Triple-Speed Ethernet MAC driver | ||
| 2 | * Copyright (C) 2008-2014 Altera Corporation. All rights reserved | ||
| 3 | * | ||
| 4 | * Contributors: | ||
| 5 | * Dalon Westergreen | ||
| 6 | * Thomas Chou | ||
| 7 | * Ian Abbott | ||
| 8 | * Yuriy Kozlov | ||
| 9 | * Tobias Klauser | ||
| 10 | * Andriy Smolskyy | ||
| 11 | * Roman Bulgakov | ||
| 12 | * Dmytro Mytarchuk | ||
| 13 | * | ||
| 14 | * Original driver contributed by SLS. | ||
| 15 | * Major updates contributed by GlobalLogic | ||
| 16 | * | ||
| 17 | * This program is free software; you can redistribute it and/or modify it | ||
| 18 | * under the terms and conditions of the GNU General Public License, | ||
| 19 | * version 2, as published by the Free Software Foundation. | ||
| 20 | * | ||
| 21 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
| 22 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 23 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
| 24 | * more details. | ||
| 25 | * | ||
| 26 | * You should have received a copy of the GNU General Public License along with | ||
| 27 | * this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 28 | */ | ||
| 29 | |||
| 30 | #include <linux/ethtool.h> | ||
| 31 | #include <linux/kernel.h> | ||
| 32 | #include <linux/netdevice.h> | ||
| 33 | #include <linux/phy.h> | ||
| 34 | |||
| 35 | #include "altera_tse.h" | ||
| 36 | |||
| 37 | #define TSE_STATS_LEN 31 | ||
| 38 | #define TSE_NUM_REGS 128 | ||
| 39 | |||
| 40 | static char const stat_gstrings[][ETH_GSTRING_LEN] = { | ||
| 41 | "tx_packets", | ||
| 42 | "rx_packets", | ||
| 43 | "rx_crc_errors", | ||
| 44 | "rx_align_errors", | ||
| 45 | "tx_bytes", | ||
| 46 | "rx_bytes", | ||
| 47 | "tx_pause", | ||
| 48 | "rx_pause", | ||
| 49 | "rx_errors", | ||
| 50 | "tx_errors", | ||
| 51 | "rx_unicast", | ||
| 52 | "rx_multicast", | ||
| 53 | "rx_broadcast", | ||
| 54 | "tx_discards", | ||
| 55 | "tx_unicast", | ||
| 56 | "tx_multicast", | ||
| 57 | "tx_broadcast", | ||
| 58 | "ether_drops", | ||
| 59 | "rx_total_bytes", | ||
| 60 | "rx_total_packets", | ||
| 61 | "rx_undersize", | ||
| 62 | "rx_oversize", | ||
| 63 | "rx_64_bytes", | ||
| 64 | "rx_65_127_bytes", | ||
| 65 | "rx_128_255_bytes", | ||
| 66 | "rx_256_511_bytes", | ||
| 67 | "rx_512_1023_bytes", | ||
| 68 | "rx_1024_1518_bytes", | ||
| 69 | "rx_gte_1519_bytes", | ||
| 70 | "rx_jabbers", | ||
| 71 | "rx_runts", | ||
| 72 | }; | ||
| 73 | |||
| 74 | static void tse_get_drvinfo(struct net_device *dev, | ||
| 75 | struct ethtool_drvinfo *info) | ||
| 76 | { | ||
| 77 | struct altera_tse_private *priv = netdev_priv(dev); | ||
| 78 | u32 rev = ioread32(&priv->mac_dev->megacore_revision); | ||
| 79 | |||
| 80 | strcpy(info->driver, "Altera TSE MAC IP Driver"); | ||
| 81 | strcpy(info->version, "v8.0"); | ||
| 82 | snprintf(info->fw_version, ETHTOOL_FWVERS_LEN, "v%d.%d", | ||
| 83 | rev & 0xFFFF, (rev & 0xFFFF0000) >> 16); | ||
| 84 | sprintf(info->bus_info, "platform"); | ||
| 85 | } | ||
| 86 | |||
| 87 | /* Fill in a buffer with the strings which correspond to the | ||
| 88 | * stats | ||
| 89 | */ | ||
| 90 | static void tse_gstrings(struct net_device *dev, u32 stringset, u8 *buf) | ||
| 91 | { | ||
| 92 | memcpy(buf, stat_gstrings, TSE_STATS_LEN * ETH_GSTRING_LEN); | ||
| 93 | } | ||
| 94 | |||
| 95 | static void tse_fill_stats(struct net_device *dev, struct ethtool_stats *dummy, | ||
| 96 | u64 *buf) | ||
| 97 | { | ||
| 98 | struct altera_tse_private *priv = netdev_priv(dev); | ||
| 99 | struct altera_tse_mac *mac = priv->mac_dev; | ||
| 100 | u64 ext; | ||
| 101 | |||
| 102 | buf[0] = ioread32(&mac->frames_transmitted_ok); | ||
| 103 | buf[1] = ioread32(&mac->frames_received_ok); | ||
| 104 | buf[2] = ioread32(&mac->frames_check_sequence_errors); | ||
| 105 | buf[3] = ioread32(&mac->alignment_errors); | ||
| 106 | |||
| 107 | /* Extended aOctetsTransmittedOK counter */ | ||
| 108 | ext = (u64) ioread32(&mac->msb_octets_transmitted_ok) << 32; | ||
| 109 | ext |= ioread32(&mac->octets_transmitted_ok); | ||
| 110 | buf[4] = ext; | ||
| 111 | |||
| 112 | /* Extended aOctetsReceivedOK counter */ | ||
| 113 | ext = (u64) ioread32(&mac->msb_octets_received_ok) << 32; | ||
| 114 | ext |= ioread32(&mac->octets_received_ok); | ||
| 115 | buf[5] = ext; | ||
| 116 | |||
| 117 | buf[6] = ioread32(&mac->tx_pause_mac_ctrl_frames); | ||
| 118 | buf[7] = ioread32(&mac->rx_pause_mac_ctrl_frames); | ||
| 119 | buf[8] = ioread32(&mac->if_in_errors); | ||
| 120 | buf[9] = ioread32(&mac->if_out_errors); | ||
| 121 | buf[10] = ioread32(&mac->if_in_ucast_pkts); | ||
| 122 | buf[11] = ioread32(&mac->if_in_multicast_pkts); | ||
| 123 | buf[12] = ioread32(&mac->if_in_broadcast_pkts); | ||
| 124 | buf[13] = ioread32(&mac->if_out_discards); | ||
| 125 | buf[14] = ioread32(&mac->if_out_ucast_pkts); | ||
| 126 | buf[15] = ioread32(&mac->if_out_multicast_pkts); | ||
| 127 | buf[16] = ioread32(&mac->if_out_broadcast_pkts); | ||
| 128 | buf[17] = ioread32(&mac->ether_stats_drop_events); | ||
| 129 | |||
| 130 | /* Extended etherStatsOctets counter */ | ||
| 131 | ext = (u64) ioread32(&mac->msb_ether_stats_octets) << 32; | ||
| 132 | ext |= ioread32(&mac->ether_stats_octets); | ||
| 133 | buf[18] = ext; | ||
| 134 | |||
| 135 | buf[19] = ioread32(&mac->ether_stats_pkts); | ||
| 136 | buf[20] = ioread32(&mac->ether_stats_undersize_pkts); | ||
| 137 | buf[21] = ioread32(&mac->ether_stats_oversize_pkts); | ||
| 138 | buf[22] = ioread32(&mac->ether_stats_pkts_64_octets); | ||
| 139 | buf[23] = ioread32(&mac->ether_stats_pkts_65to127_octets); | ||
| 140 | buf[24] = ioread32(&mac->ether_stats_pkts_128to255_octets); | ||
| 141 | buf[25] = ioread32(&mac->ether_stats_pkts_256to511_octets); | ||
| 142 | buf[26] = ioread32(&mac->ether_stats_pkts_512to1023_octets); | ||
| 143 | buf[27] = ioread32(&mac->ether_stats_pkts_1024to1518_octets); | ||
| 144 | buf[28] = ioread32(&mac->ether_stats_pkts_1519tox_octets); | ||
| 145 | buf[29] = ioread32(&mac->ether_stats_jabbers); | ||
| 146 | buf[30] = ioread32(&mac->ether_stats_fragments); | ||
| 147 | } | ||
| 148 | |||
| 149 | static int tse_sset_count(struct net_device *dev, int sset) | ||
| 150 | { | ||
| 151 | switch (sset) { | ||
| 152 | case ETH_SS_STATS: | ||
| 153 | return TSE_STATS_LEN; | ||
| 154 | default: | ||
| 155 | return -EOPNOTSUPP; | ||
| 156 | } | ||
| 157 | } | ||
| 158 | |||
| 159 | static u32 tse_get_msglevel(struct net_device *dev) | ||
| 160 | { | ||
| 161 | struct altera_tse_private *priv = netdev_priv(dev); | ||
| 162 | return priv->msg_enable; | ||
| 163 | } | ||
| 164 | |||
| 165 | static void tse_set_msglevel(struct net_device *dev, uint32_t data) | ||
| 166 | { | ||
| 167 | struct altera_tse_private *priv = netdev_priv(dev); | ||
| 168 | priv->msg_enable = data; | ||
| 169 | } | ||
| 170 | |||
| 171 | static int tse_reglen(struct net_device *dev) | ||
| 172 | { | ||
| 173 | return TSE_NUM_REGS * sizeof(u32); | ||
| 174 | } | ||
| 175 | |||
| 176 | static void tse_get_regs(struct net_device *dev, struct ethtool_regs *regs, | ||
| 177 | void *regbuf) | ||
| 178 | { | ||
| 179 | int i; | ||
| 180 | struct altera_tse_private *priv = netdev_priv(dev); | ||
| 181 | u32 *tse_mac_regs = (u32 *)priv->mac_dev; | ||
| 182 | u32 *buf = regbuf; | ||
| 183 | |||
| 184 | /* Set version to a known value, so ethtool knows | ||
| 185 | * how to do any special formatting of this data. | ||
| 186 | * This version number will need to change if and | ||
| 187 | * when this register table is changed. | ||
| 188 | */ | ||
| 189 | |||
| 190 | regs->version = 1; | ||
| 191 | |||
| 192 | for (i = 0; i < TSE_NUM_REGS; i++) | ||
| 193 | buf[i] = ioread32(&tse_mac_regs[i]); | ||
| 194 | } | ||
| 195 | |||
| 196 | static int tse_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) | ||
| 197 | { | ||
| 198 | struct altera_tse_private *priv = netdev_priv(dev); | ||
| 199 | struct phy_device *phydev = priv->phydev; | ||
| 200 | |||
| 201 | if (phydev == NULL) | ||
| 202 | return -ENODEV; | ||
| 203 | |||
| 204 | return phy_ethtool_gset(phydev, cmd); | ||
| 205 | } | ||
| 206 | |||
| 207 | static int tse_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) | ||
| 208 | { | ||
| 209 | struct altera_tse_private *priv = netdev_priv(dev); | ||
| 210 | struct phy_device *phydev = priv->phydev; | ||
| 211 | |||
| 212 | if (phydev == NULL) | ||
| 213 | return -ENODEV; | ||
| 214 | |||
| 215 | return phy_ethtool_sset(phydev, cmd); | ||
| 216 | } | ||
| 217 | |||
| 218 | static const struct ethtool_ops tse_ethtool_ops = { | ||
| 219 | .get_drvinfo = tse_get_drvinfo, | ||
| 220 | .get_regs_len = tse_reglen, | ||
| 221 | .get_regs = tse_get_regs, | ||
| 222 | .get_link = ethtool_op_get_link, | ||
| 223 | .get_settings = tse_get_settings, | ||
| 224 | .set_settings = tse_set_settings, | ||
| 225 | .get_strings = tse_gstrings, | ||
| 226 | .get_sset_count = tse_sset_count, | ||
| 227 | .get_ethtool_stats = tse_fill_stats, | ||
| 228 | .get_msglevel = tse_get_msglevel, | ||
| 229 | .set_msglevel = tse_set_msglevel, | ||
| 230 | }; | ||
| 231 | |||
| 232 | void altera_tse_set_ethtool_ops(struct net_device *netdev) | ||
| 233 | { | ||
| 234 | SET_ETHTOOL_OPS(netdev, &tse_ethtool_ops); | ||
| 235 | } | ||
| @@ -0,0 +1,1543 @@ | |||
| 1 | /* Altera Triple-Speed Ethernet MAC driver | ||
| 2 | * Copyright (C) 2008-2014 Altera Corporation. All rights reserved | ||
| 3 | * | ||
| 4 | * Contributors: | ||
| 5 | * Dalon Westergreen | ||
| 6 | * Thomas Chou | ||
| 7 | * Ian Abbott | ||
| 8 | * Yuriy Kozlov | ||
| 9 | * Tobias Klauser | ||
| 10 | * Andriy Smolskyy | ||
| 11 | * Roman Bulgakov | ||
| 12 | * Dmytro Mytarchuk | ||
| 13 | * Matthew Gerlach | ||
| 14 | * | ||
| 15 | * Original driver contributed by SLS. | ||
| 16 | * Major updates contributed by GlobalLogic | ||
| 17 | * | ||
| 18 | * This program is free software; you can redistribute it and/or modify it | ||
| 19 | * under the terms and conditions of the GNU General Public License, | ||
| 20 | * version 2, as published by the Free Software Foundation. | ||
| 21 | * | ||
| 22 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
| 23 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 24 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
| 25 | * more details. | ||
| 26 | * | ||
| 27 | * You should have received a copy of the GNU General Public License along with | ||
| 28 | * this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 29 | */ | ||
| 30 | |||
| 31 | #include <linux/atomic.h> | ||
| 32 | #include <linux/delay.h> | ||
| 33 | #include <linux/etherdevice.h> | ||
| 34 | #include <linux/if_vlan.h> | ||
| 35 | #include <linux/init.h> | ||
| 36 | #include <linux/interrupt.h> | ||
| 37 | #include <linux/io.h> | ||
| 38 | #include <linux/kernel.h> | ||
| 39 | #include <linux/module.h> | ||
| 40 | #include <linux/netdevice.h> | ||
| 41 | #include <linux/of_device.h> | ||
| 42 | #include <linux/of_mdio.h> | ||
| 43 | #include <linux/of_net.h> | ||
| 44 | #include <linux/of_platform.h> | ||
| 45 | #include <linux/phy.h> | ||
| 46 | #include <linux/platform_device.h> | ||
| 47 | #include <linux/skbuff.h> | ||
| 48 | #include <asm/cacheflush.h> | ||
| 49 | |||
| 50 | #include "altera_utils.h" | ||
| 51 | #include "altera_tse.h" | ||
| 52 | #include "altera_sgdma.h" | ||
| 53 | #include "altera_msgdma.h" | ||
| 54 | |||
| 55 | static atomic_t instance_count = ATOMIC_INIT(~0); | ||
| 56 | /* Module parameters */ | ||
| 57 | static int debug = -1; | ||
| 58 | module_param(debug, int, S_IRUGO | S_IWUSR); | ||
| 59 | MODULE_PARM_DESC(debug, "Message Level (-1: default, 0: no output, 16: all)"); | ||
| 60 | |||
| 61 | static const u32 default_msg_level = (NETIF_MSG_DRV | NETIF_MSG_PROBE | | ||
| 62 | NETIF_MSG_LINK | NETIF_MSG_IFUP | | ||
| 63 | NETIF_MSG_IFDOWN); | ||
| 64 | |||
| 65 | #define RX_DESCRIPTORS 64 | ||
| 66 | static int dma_rx_num = RX_DESCRIPTORS; | ||
| 67 | module_param(dma_rx_num, int, S_IRUGO | S_IWUSR); | ||
| 68 | MODULE_PARM_DESC(dma_rx_num, "Number of descriptors in the RX list"); | ||
| 69 | |||
| 70 | #define TX_DESCRIPTORS 64 | ||
| 71 | static int dma_tx_num = TX_DESCRIPTORS; | ||
| 72 | module_param(dma_tx_num, int, S_IRUGO | S_IWUSR); | ||
| 73 | MODULE_PARM_DESC(dma_tx_num, "Number of descriptors in the TX list"); | ||
| 74 | |||
| 75 | |||
| 76 | #define POLL_PHY (-1) | ||
| 77 | |||
| 78 | /* Make sure DMA buffer size is larger than the max frame size | ||
| 79 | * plus some alignment offset and a VLAN header. If the max frame size is | ||
| 80 | * 1518, a VLAN header would be additional 4 bytes and additional | ||
| 81 | * headroom for alignment is 2 bytes, 2048 is just fine. | ||
| 82 | */ | ||
| 83 | #define ALTERA_RXDMABUFFER_SIZE 2048 | ||
| 84 | |||
| 85 | /* Allow network stack to resume queueing packets after we've | ||
| 86 | * finished transmitting at least 1/4 of the packets in the queue. | ||
| 87 | */ | ||
| 88 | #define TSE_TX_THRESH(x) (x->tx_ring_size / 4) | ||
| 89 | |||
| 90 | #define TXQUEUESTOP_THRESHHOLD 2 | ||
| 91 | |||
| 92 | static struct of_device_id altera_tse_ids[]; | ||
| 93 | |||
| 94 | static inline u32 tse_tx_avail(struct altera_tse_private *priv) | ||
| 95 | { | ||
| 96 | return priv->tx_cons + priv->tx_ring_size - priv->tx_prod - 1; | ||
| 97 | } | ||
| 98 | |||
| 99 | /* MDIO specific functions | ||
| 100 | */ | ||
| 101 | static int altera_tse_mdio_read(struct mii_bus *bus, int mii_id, int regnum) | ||
| 102 | { | ||
| 103 | struct altera_tse_mac *mac = (struct altera_tse_mac *)bus->priv; | ||
| 104 | unsigned int *mdio_regs = (unsigned int *)&mac->mdio_phy0; | ||
| 105 | u32 data; | ||
| 106 | |||
| 107 | /* set MDIO address */ | ||
| 108 | iowrite32((mii_id & 0x1f), &mac->mdio_phy0_addr); | ||
| 109 | |||
| 110 | /* get the data */ | ||
| 111 | data = ioread32(&mdio_regs[regnum]) & 0xffff; | ||
| 112 | return data; | ||
| 113 | } | ||
| 114 | |||
| 115 | static int altera_tse_mdio_write(struct mii_bus *bus, int mii_id, int regnum, | ||
| 116 | u16 value) | ||
| 117 | { | ||
| 118 | struct altera_tse_mac *mac = (struct altera_tse_mac *)bus->priv; | ||
| 119 | unsigned int *mdio_regs = (unsigned int *)&mac->mdio_phy0; | ||
| 120 | |||
| 121 | /* set MDIO address */ | ||
| 122 | iowrite32((mii_id & 0x1f), &mac->mdio_phy0_addr); | ||
| 123 | |||
| 124 | /* write the data */ | ||
| 125 | iowrite32((u32) value, &mdio_regs[regnum]); | ||
| 126 | return 0; | ||
| 127 | } | ||
| 128 | |||
| 129 | static int altera_tse_mdio_create(struct net_device *dev, unsigned int id) | ||
| 130 | { | ||
| 131 | struct altera_tse_private *priv = netdev_priv(dev); | ||
| 132 | int ret; | ||
| 133 | int i; | ||
| 134 | struct device_node *mdio_node = NULL; | ||
| 135 | struct mii_bus *mdio = NULL; | ||
| 136 | struct device_node *child_node = NULL; | ||
| 137 | |||
| 138 | for_each_child_of_node(priv->device->of_node, child_node) { | ||
| 139 | if (of_device_is_compatible(child_node, "altr,tse-mdio")) { | ||
| 140 | mdio_node = child_node; | ||
| 141 | break; | ||
| 142 | } | ||
| 143 | } | ||
| 144 | |||
| 145 | if (mdio_node) { | ||
| 146 | netdev_dbg(dev, "FOUND MDIO subnode\n"); | ||
| 147 | } else { | ||
| 148 | netdev_dbg(dev, "NO MDIO subnode\n"); | ||
| 149 | return 0; | ||
| 150 | } | ||
| 151 | |||
| 152 | mdio = mdiobus_alloc(); | ||
| 153 | if (mdio == NULL) { | ||
| 154 | netdev_err(dev, "Error allocating MDIO bus\n"); | ||
| 155 | return -ENOMEM; | ||
| 156 | } | ||
| 157 | |||
| 158 | mdio->name = ALTERA_TSE_RESOURCE_NAME; | ||
| 159 | mdio->read = &altera_tse_mdio_read; | ||
| 160 | mdio->write = &altera_tse_mdio_write; | ||
| 161 | snprintf(mdio->id, MII_BUS_ID_SIZE, "%s-%u", mdio->name, id); | ||
| 162 | |||
| 163 | mdio->irq = kcalloc(PHY_MAX_ADDR, sizeof(int), GFP_KERNEL); | ||
| 164 | if (mdio->irq == NULL) { | ||
| 165 | ret = -ENOMEM; | ||
| 166 | goto out_free_mdio; | ||
| 167 | } | ||
| 168 | for (i = 0; i < PHY_MAX_ADDR; i++) | ||
| 169 | mdio->irq[i] = PHY_POLL; | ||
| 170 | |||
| 171 | mdio->priv = priv->mac_dev; | ||
| 172 | mdio->parent = priv->device; | ||
| 173 | |||
| 174 | ret = of_mdiobus_register(mdio, mdio_node); | ||
| 175 | if (ret != 0) { | ||
| 176 | netdev_err(dev, "Cannot register MDIO bus %s\n", | ||
| 177 | mdio->id); | ||
| 178 | goto out_free_mdio_irq; | ||
| 179 | } | ||
| 180 | |||
| 181 | if (netif_msg_drv(priv)) | ||
| 182 | netdev_info(dev, "MDIO bus %s: created\n", mdio->id); | ||
| 183 | |||
| 184 | priv->mdio = mdio; | ||
| 185 | return 0; | ||
| 186 | out_free_mdio_irq: | ||
| 187 | kfree(mdio->irq); | ||
| 188 | out_free_mdio: | ||
| 189 | mdiobus_free(mdio); | ||
| 190 | mdio = NULL; | ||
| 191 | return ret; | ||
| 192 | } | ||
| 193 | |||
| 194 | static void altera_tse_mdio_destroy(struct net_device *dev) | ||
| 195 | { | ||
| 196 | struct altera_tse_private *priv = netdev_priv(dev); | ||
| 197 | |||
| 198 | if (priv->mdio == NULL) | ||
| 199 | return; | ||
| 200 | |||
| 201 | if (netif_msg_drv(priv)) | ||
| 202 | netdev_info(dev, "MDIO bus %s: removed\n", | ||
| 203 | priv->mdio->id); | ||
| 204 | |||
| 205 | mdiobus_unregister(priv->mdio); | ||
| 206 | kfree(priv->mdio->irq); | ||
| 207 | mdiobus_free(priv->mdio); | ||
| 208 | priv->mdio = NULL; | ||
| 209 | } | ||
| 210 | |||
| 211 | static int tse_init_rx_buffer(struct altera_tse_private *priv, | ||
| 212 | struct tse_buffer *rxbuffer, int len) | ||
| 213 | { | ||
| 214 | rxbuffer->skb = netdev_alloc_skb_ip_align(priv->dev, len); | ||
| 215 | if (!rxbuffer->skb) | ||
| 216 | return -ENOMEM; | ||
| 217 | |||
| 218 | rxbuffer->dma_addr = dma_map_single(priv->device, rxbuffer->skb->data, | ||
| 219 | len, | ||
| 220 | DMA_FROM_DEVICE); | ||
| 221 | |||
| 222 | if (dma_mapping_error(priv->device, rxbuffer->dma_addr)) { | ||
| 223 | netdev_err(priv->dev, "%s: DMA mapping error\n", __func__); | ||
| 224 | dev_kfree_skb_any(rxbuffer->skb); | ||
| 225 | return -EINVAL; | ||
| 226 | } | ||
| 227 | rxbuffer->len = len; | ||
| 228 | return 0; | ||
| 229 | } | ||
| 230 | |||
| 231 | static void tse_free_rx_buffer(struct altera_tse_private *priv, | ||
| 232 | struct tse_buffer *rxbuffer) | ||
| 233 | { | ||
| 234 | struct sk_buff *skb = rxbuffer->skb; | ||
| 235 | dma_addr_t dma_addr = rxbuffer->dma_addr; | ||
| 236 | |||
| 237 | if (skb != NULL) { | ||
| 238 | if (dma_addr) | ||
| 239 | dma_unmap_single(priv->device, dma_addr, | ||
| 240 | rxbuffer->len, | ||
| 241 | DMA_FROM_DEVICE); | ||
| 242 | dev_kfree_skb_any(skb); | ||
| 243 | rxbuffer->skb = NULL; | ||
| 244 | rxbuffer->dma_addr = 0; | ||
| 245 | } | ||
| 246 | } | ||
| 247 | |||
| 248 | /* Unmap and free Tx buffer resources | ||
| 249 | */ | ||
| 250 | static void tse_free_tx_buffer(struct altera_tse_private *priv, | ||
| 251 | struct tse_buffer *buffer) | ||
| 252 | { | ||
| 253 | if (buffer->dma_addr) { | ||
| 254 | if (buffer->mapped_as_page) | ||
| 255 | dma_unmap_page(priv->device, buffer->dma_addr, | ||
| 256 | buffer->len, DMA_TO_DEVICE); | ||
| 257 | else | ||
| 258 | dma_unmap_single(priv->device, buffer->dma_addr, | ||
| 259 | buffer->len, DMA_TO_DEVICE); | ||
| 260 | buffer->dma_addr = 0; | ||
| 261 | } | ||
| 262 | if (buffer->skb) { | ||
| 263 | dev_kfree_skb_any(buffer->skb); | ||
| 264 | buffer->skb = NULL; | ||
| 265 | } | ||
| 266 | } | ||
| 267 | |||
| 268 | static int alloc_init_skbufs(struct altera_tse_private *priv) | ||
| 269 | { | ||
| 270 | unsigned int rx_descs = priv->rx_ring_size; | ||
| 271 | unsigned int tx_descs = priv->tx_ring_size; | ||
| 272 | int ret = -ENOMEM; | ||
| 273 | int i; | ||
| 274 | |||
| 275 | /* Create Rx ring buffer */ | ||
| 276 | priv->rx_ring = kcalloc(rx_descs, sizeof(struct tse_buffer), | ||
| 277 | GFP_KERNEL); | ||
| 278 | if (!priv->rx_ring) | ||
| 279 | goto err_rx_ring; | ||
| 280 | |||
| 281 | /* Create Tx ring buffer */ | ||
| 282 | priv->tx_ring = kcalloc(tx_descs, sizeof(struct tse_buffer), | ||
| 283 | GFP_KERNEL); | ||
| 284 | if (!priv->tx_ring) | ||
| 285 | goto err_tx_ring; | ||
| 286 | |||
| 287 | priv->tx_cons = 0; | ||
| 288 | priv->tx_prod = 0; | ||
| 289 | |||
| 290 | /* Init Rx ring */ | ||
| 291 | for (i = 0; i < rx_descs; i++) { | ||
| 292 | ret = tse_init_rx_buffer(priv, &priv->rx_ring[i], | ||
| 293 | priv->rx_dma_buf_sz); | ||
| 294 | if (ret) | ||
| 295 | goto err_init_rx_buffers; | ||
| 296 | } | ||
| 297 | |||
| 298 | priv->rx_cons = 0; | ||
| 299 | priv->rx_prod = 0; | ||
| 300 | |||
| 301 | return 0; | ||
| 302 | err_init_rx_buffers: | ||
| 303 | while (--i >= 0) | ||
| 304 | tse_free_rx_buffer(priv, &priv->rx_ring[i]); | ||
| 305 | kfree(priv->tx_ring); | ||
| 306 | err_tx_ring: | ||
| 307 | kfree(priv->rx_ring); | ||
| 308 | err_rx_ring: | ||
| 309 | return ret; | ||
| 310 | } | ||
| 311 | |||
| 312 | static void free_skbufs(struct net_device *dev) | ||
| 313 | { | ||
| 314 | struct altera_tse_private *priv = netdev_priv(dev); | ||
| 315 | unsigned int rx_descs = priv->rx_ring_size; | ||
| 316 | unsigned int tx_descs = priv->tx_ring_size; | ||
| 317 | int i; | ||
| 318 | |||
| 319 | /* Release the DMA TX/RX socket buffers */ | ||
| 320 | for (i = 0; i < rx_descs; i++) | ||
| 321 | tse_free_rx_buffer(priv, &priv->rx_ring[i]); | ||
| 322 | for (i = 0; i < tx_descs; i++) | ||
| 323 | tse_free_tx_buffer(priv, &priv->tx_ring[i]); | ||
| 324 | |||
| 325 | |||
| 326 | kfree(priv->tx_ring); | ||
| 327 | } | ||
| 328 | |||
| 329 | /* Reallocate the skb for the reception process | ||
| 330 | */ | ||
| 331 | static inline void tse_rx_refill(struct altera_tse_private *priv) | ||
| 332 | { | ||
| 333 | unsigned int rxsize = priv->rx_ring_size; | ||
| 334 | unsigned int entry; | ||
| 335 | int ret; | ||
| 336 | |||
| 337 | for (; priv->rx_cons - priv->rx_prod > 0; | ||
| 338 | priv->rx_prod++) { | ||
| 339 | entry = priv->rx_prod % rxsize; | ||
| 340 | if (likely(priv->rx_ring[entry].skb == NULL)) { | ||
| 341 | ret = tse_init_rx_buffer(priv, &priv->rx_ring[entry], | ||
| 342 | priv->rx_dma_buf_sz); | ||
| 343 | if (unlikely(ret != 0)) | ||
| 344 | break; | ||
| 345 | priv->dmaops->add_rx_desc(priv, &priv->rx_ring[entry]); | ||
| 346 | } | ||
| 347 | } | ||
| 348 | } | ||
| 349 | |||
| 350 | /* Pull out the VLAN tag and fix up the packet | ||
| 351 | */ | ||
| 352 | static inline void tse_rx_vlan(struct net_device *dev, struct sk_buff *skb) | ||
| 353 | { | ||
| 354 | struct ethhdr *eth_hdr; | ||
| 355 | u16 vid; | ||
| 356 | if ((dev->features & NETIF_F_HW_VLAN_CTAG_RX) && | ||
| 357 | !__vlan_get_tag(skb, &vid)) { | ||
| 358 | eth_hdr = (struct ethhdr *)skb->data; | ||
| 359 | memmove(skb->data + VLAN_HLEN, eth_hdr, ETH_ALEN * 2); | ||
| 360 | skb_pull(skb, VLAN_HLEN); | ||
| 361 | __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), vid); | ||
| 362 | } | ||
| 363 | } | ||
| 364 | |||
| 365 | /* Receive a packet: retrieve and pass over to upper levels | ||
| 366 | */ | ||
| 367 | static int tse_rx(struct altera_tse_private *priv, int limit) | ||
| 368 | { | ||
| 369 | unsigned int count = 0; | ||
| 370 | unsigned int next_entry; | ||
| 371 | struct sk_buff *skb; | ||
| 372 | unsigned int entry = priv->rx_cons % priv->rx_ring_size; | ||
| 373 | u32 rxstatus; | ||
| 374 | u16 pktlength; | ||
| 375 | u16 pktstatus; | ||
| 376 | |||
| 377 | while ((rxstatus = priv->dmaops->get_rx_status(priv)) != 0) { | ||
| 378 | pktstatus = rxstatus >> 16; | ||
| 379 | pktlength = rxstatus & 0xffff; | ||
| 380 | |||
| 381 | if ((pktstatus & 0xFF) || (pktlength == 0)) | ||
| 382 | netdev_err(priv->dev, | ||
| 383 | "RCV pktstatus %08X pktlength %08X\n", | ||
| 384 | pktstatus, pktlength); | ||
| 385 | |||
| 386 | count++; | ||
| 387 | next_entry = (++priv->rx_cons) % priv->rx_ring_size; | ||
| 388 | |||
| 389 | skb = priv->rx_ring[entry].skb; | ||
| 390 | if (unlikely(!skb)) { | ||
| 391 | netdev_err(priv->dev, | ||
| 392 | "%s: Inconsistent Rx descriptor chain\n", | ||
| 393 | __func__); | ||
| 394 | priv->dev->stats.rx_dropped++; | ||
| 395 | break; | ||
| 396 | } | ||
| 397 | priv->rx_ring[entry].skb = NULL; | ||
| 398 | |||
| 399 | skb_put(skb, pktlength); | ||
| 400 | |||
| 401 | /* make cache consistent with receive packet buffer */ | ||
| 402 | dma_sync_single_for_cpu(priv->device, | ||
| 403 | priv->rx_ring[entry].dma_addr, | ||
| 404 | priv->rx_ring[entry].len, | ||
| 405 | DMA_FROM_DEVICE); | ||
| 406 | |||
| 407 | dma_unmap_single(priv->device, priv->rx_ring[entry].dma_addr, | ||
| 408 | priv->rx_ring[entry].len, DMA_FROM_DEVICE); | ||
| 409 | |||
| 410 | if (netif_msg_pktdata(priv)) { | ||
| 411 | netdev_info(priv->dev, "frame received %d bytes\n", | ||
| 412 | pktlength); | ||
| 413 | print_hex_dump(KERN_ERR, "data: ", DUMP_PREFIX_OFFSET, | ||
| 414 | 16, 1, skb->data, pktlength, true); | ||
| 415 | } | ||
| 416 | |||
| 417 | tse_rx_vlan(priv->dev, skb); | ||
| 418 | |||
| 419 | skb->protocol = eth_type_trans(skb, priv->dev); | ||
| 420 | skb_checksum_none_assert(skb); | ||
| 421 | |||
| 422 | napi_gro_receive(&priv->napi, skb); | ||
| 423 | |||
| 424 | priv->dev->stats.rx_packets++; | ||
| 425 | priv->dev->stats.rx_bytes += pktlength; | ||
| 426 | |||
| 427 | entry = next_entry; | ||
| 428 | } | ||
| 429 | |||
| 430 | tse_rx_refill(priv); | ||
| 431 | return count; | ||
| 432 | } | ||
| 433 | |||
| 434 | /* Reclaim resources after transmission completes | ||
| 435 | */ | ||
| 436 | static int tse_tx_complete(struct altera_tse_private *priv) | ||
| 437 | { | ||
| 438 | unsigned int txsize = priv->tx_ring_size; | ||
| 439 | u32 ready; | ||
| 440 | unsigned int entry; | ||
| 441 | struct tse_buffer *tx_buff; | ||
| 442 | int txcomplete = 0; | ||
| 443 | |||
| 444 | spin_lock(&priv->tx_lock); | ||
| 445 | |||
| 446 | ready = priv->dmaops->tx_completions(priv); | ||
| 447 | |||
| 448 | /* Free sent buffers */ | ||
| 449 | while (ready && (priv->tx_cons != priv->tx_prod)) { | ||
| 450 | entry = priv->tx_cons % txsize; | ||
| 451 | tx_buff = &priv->tx_ring[entry]; | ||
| 452 | |||
| 453 | if (netif_msg_tx_done(priv)) | ||
| 454 | netdev_dbg(priv->dev, "%s: curr %d, dirty %d\n", | ||
| 455 | __func__, priv->tx_prod, priv->tx_cons); | ||
| 456 | |||
| 457 | if (likely(tx_buff->skb)) | ||
| 458 | priv->dev->stats.tx_packets++; | ||
| 459 | |||
| 460 | tse_free_tx_buffer(priv, tx_buff); | ||
| 461 | priv->tx_cons++; | ||
| 462 | |||
| 463 | txcomplete++; | ||
| 464 | ready--; | ||
| 465 | } | ||
| 466 | |||
| 467 | if (unlikely(netif_queue_stopped(priv->dev) && | ||
| 468 | tse_tx_avail(priv) > TSE_TX_THRESH(priv))) { | ||
| 469 | netif_tx_lock(priv->dev); | ||
| 470 | if (netif_queue_stopped(priv->dev) && | ||
| 471 | tse_tx_avail(priv) > TSE_TX_THRESH(priv)) { | ||
| 472 | if (netif_msg_tx_done(priv)) | ||
| 473 | netdev_dbg(priv->dev, "%s: restart transmit\n", | ||
| 474 | __func__); | ||
| 475 | netif_wake_queue(priv->dev); | ||
| 476 | } | ||
| 477 | netif_tx_unlock(priv->dev); | ||
| 478 | } | ||
| 479 | |||
| 480 | spin_unlock(&priv->tx_lock); | ||
| 481 | return txcomplete; | ||
| 482 | } | ||
| 483 | |||
| 484 | /* NAPI polling function | ||
| 485 | */ | ||
| 486 | static int tse_poll(struct napi_struct *napi, int budget) | ||
| 487 | { | ||
| 488 | struct altera_tse_private *priv = | ||
| 489 | container_of(napi, struct altera_tse_private, napi); | ||
| 490 | int rxcomplete = 0; | ||
| 491 | int txcomplete = 0; | ||
| 492 | unsigned long int flags; | ||
| 493 | |||
| 494 | txcomplete = tse_tx_complete(priv); | ||
| 495 | |||
| 496 | rxcomplete = tse_rx(priv, budget); | ||
| 497 | |||
| 498 | if (rxcomplete >= budget || txcomplete > 0) | ||
| 499 | return rxcomplete; | ||
| 500 | |||
| 501 | napi_gro_flush(napi, false); | ||
| 502 | __napi_complete(napi); | ||
| 503 | |||
| 504 | netdev_dbg(priv->dev, | ||
| 505 | "NAPI Complete, did %d packets with budget %d\n", | ||
| 506 | txcomplete+rxcomplete, budget); | ||
| 507 | |||
| 508 | spin_lock_irqsave(&priv->rxdma_irq_lock, flags); | ||
| 509 | priv->dmaops->enable_rxirq(priv); | ||
| 510 | priv->dmaops->enable_txirq(priv); | ||
| 511 | spin_unlock_irqrestore(&priv->rxdma_irq_lock, flags); | ||
| 512 | return rxcomplete + txcomplete; | ||
| 513 | } | ||
| 514 | |||
| 515 | /* DMA TX & RX FIFO interrupt routing | ||
| 516 | */ | ||
| 517 | static irqreturn_t altera_isr(int irq, void *dev_id) | ||
| 518 | { | ||
| 519 | struct net_device *dev = dev_id; | ||
| 520 | struct altera_tse_private *priv; | ||
| 521 | unsigned long int flags; | ||
| 522 | |||
| 523 | |||
| 524 | if (unlikely(!dev)) { | ||
| 525 | pr_err("%s: invalid dev pointer\n", __func__); | ||
| 526 | return IRQ_NONE; | ||
| 527 | } | ||
| 528 | priv = netdev_priv(dev); | ||
| 529 | |||
| 530 | /* turn off desc irqs and enable napi rx */ | ||
| 531 | spin_lock_irqsave(&priv->rxdma_irq_lock, flags); | ||
| 532 | |||
| 533 | if (likely(napi_schedule_prep(&priv->napi))) { | ||
| 534 | priv->dmaops->disable_rxirq(priv); | ||
| 535 | priv->dmaops->disable_txirq(priv); | ||
| 536 | __napi_schedule(&priv->napi); | ||
| 537 | } | ||
| 538 | |||
| 539 | /* reset IRQs */ | ||
| 540 | priv->dmaops->clear_rxirq(priv); | ||
| 541 | priv->dmaops->clear_txirq(priv); | ||
| 542 | |||
| 543 | spin_unlock_irqrestore(&priv->rxdma_irq_lock, flags); | ||
| 544 | |||
| 545 | return IRQ_HANDLED; | ||
| 546 | } | ||
| 547 | |||
| 548 | /* Transmit a packet (called by the kernel). Dispatches | ||
| 549 | * either the SGDMA method for transmitting or the | ||
| 550 | * MSGDMA method, assumes no scatter/gather support, | ||
| 551 | * implying an assumption that there's only one | ||
| 552 | * physically contiguous fragment starting at | ||
| 553 | * skb->data, for length of skb_headlen(skb). | ||
| 554 | */ | ||
| 555 | static int tse_start_xmit(struct sk_buff *skb, struct net_device *dev) | ||
| 556 | { | ||
| 557 | struct altera_tse_private *priv = netdev_priv(dev); | ||
| 558 | unsigned int txsize = priv->tx_ring_size; | ||
| 559 | unsigned int entry; | ||
| 560 | struct tse_buffer *buffer = NULL; | ||
| 561 | int nfrags = skb_shinfo(skb)->nr_frags; | ||
| 562 | unsigned int nopaged_len = skb_headlen(skb); | ||
| 563 | enum netdev_tx ret = NETDEV_TX_OK; | ||
| 564 | dma_addr_t dma_addr; | ||
| 565 | int txcomplete = 0; | ||
| 566 | |||
| 567 | spin_lock_bh(&priv->tx_lock); | ||
| 568 | |||
| 569 | if (unlikely(tse_tx_avail(priv) < nfrags + 1)) { | ||
| 570 | if (!netif_queue_stopped(dev)) { | ||
| 571 | netif_stop_queue(dev); | ||
| 572 | /* This is a hard error, log it. */ | ||
| 573 | netdev_err(priv->dev, | ||
| 574 | "%s: Tx list full when queue awake\n", | ||
| 575 | __func__); | ||
| 576 | } | ||
| 577 | ret = NETDEV_TX_BUSY; | ||
| 578 | goto out; | ||
| 579 | } | ||
| 580 | |||
| 581 | /* Map the first skb fragment */ | ||
| 582 | entry = priv->tx_prod % txsize; | ||
| 583 | buffer = &priv->tx_ring[entry]; | ||
| 584 | |||
| 585 | dma_addr = dma_map_single(priv->device, skb->data, nopaged_len, | ||
| 586 | DMA_TO_DEVICE); | ||
| 587 | if (dma_mapping_error(priv->device, dma_addr)) { | ||
| 588 | netdev_err(priv->dev, "%s: DMA mapping error\n", __func__); | ||
| 589 | ret = NETDEV_TX_OK; | ||
| 590 | goto out; | ||
| 591 | } | ||
| 592 | |||
| 593 | buffer->skb = skb; | ||
| 594 | buffer->dma_addr = dma_addr; | ||
| 595 | buffer->len = nopaged_len; | ||
| 596 | |||
| 597 | /* Push data out of the cache hierarchy into main memory */ | ||
| 598 | dma_sync_single_for_device(priv->device, buffer->dma_addr, | ||
| 599 | buffer->len, DMA_TO_DEVICE); | ||
| 600 | |||
| 601 | txcomplete = priv->dmaops->tx_buffer(priv, buffer); | ||
| 602 | |||
| 603 | skb_tx_timestamp(skb); | ||
| 604 | |||
| 605 | priv->tx_prod++; | ||
| 606 | dev->stats.tx_bytes += skb->len; | ||
| 607 | |||
| 608 | if (unlikely(tse_tx_avail(priv) <= TXQUEUESTOP_THRESHHOLD)) { | ||
| 609 | if (netif_msg_hw(priv)) | ||
| 610 | netdev_dbg(priv->dev, "%s: stop transmitted packets\n", | ||
| 611 | __func__); | ||
| 612 | netif_stop_queue(dev); | ||
| 613 | } | ||
| 614 | |||
| 615 | out: | ||
| 616 | spin_unlock_bh(&priv->tx_lock); | ||
| 617 | |||
| 618 | return ret; | ||
| 619 | } | ||
| 620 | |||
| 621 | /* Called every time the controller might need to be made | ||
| 622 | * aware of new link state. The PHY code conveys this | ||
| 623 | * information through variables in the phydev structure, and this | ||
| 624 | * function converts those variables into the appropriate | ||
| 625 | * register values, and can bring down the device if needed. | ||
| 626 | */ | ||
| 627 | static void altera_tse_adjust_link(struct net_device *dev) | ||
| 628 | { | ||
| 629 | struct altera_tse_private *priv = netdev_priv(dev); | ||
| 630 | struct phy_device *phydev = priv->phydev; | ||
| 631 | int new_state = 0; | ||
| 632 | |||
| 633 | /* only change config if there is a link */ | ||
| 634 | spin_lock(&priv->mac_cfg_lock); | ||
| 635 | if (phydev->link) { | ||
| 636 | /* Read old config */ | ||
| 637 | u32 cfg_reg = ioread32(&priv->mac_dev->command_config); | ||
| 638 | |||
| 639 | /* Check duplex */ | ||
| 640 | if (phydev->duplex != priv->oldduplex) { | ||
| 641 | new_state = 1; | ||
| 642 | if (!(phydev->duplex)) | ||
| 643 | cfg_reg |= MAC_CMDCFG_HD_ENA; | ||
| 644 | else | ||
| 645 | cfg_reg &= ~MAC_CMDCFG_HD_ENA; | ||
| 646 | |||
| 647 | netdev_dbg(priv->dev, "%s: Link duplex = 0x%x\n", | ||
| 648 | dev->name, phydev->duplex); | ||
| 649 | |||
| 650 | priv->oldduplex = phydev->duplex; | ||
| 651 | } | ||
| 652 | |||
| 653 | /* Check speed */ | ||
| 654 | if (phydev->speed != priv->oldspeed) { | ||
| 655 | new_state = 1; | ||
| 656 | switch (phydev->speed) { | ||
| 657 | case 1000: | ||
| 658 | cfg_reg |= MAC_CMDCFG_ETH_SPEED; | ||
| 659 | cfg_reg &= ~MAC_CMDCFG_ENA_10; | ||
| 660 | break; | ||
| 661 | case 100: | ||
| 662 | cfg_reg &= ~MAC_CMDCFG_ETH_SPEED; | ||
| 663 | cfg_reg &= ~MAC_CMDCFG_ENA_10; | ||
| 664 | break; | ||
| 665 | case 10: | ||
| 666 | cfg_reg &= ~MAC_CMDCFG_ETH_SPEED; | ||
| 667 | cfg_reg |= MAC_CMDCFG_ENA_10; | ||
| 668 | break; | ||
| 669 | default: | ||
| 670 | if (netif_msg_link(priv)) | ||
| 671 | netdev_warn(dev, "Speed (%d) is not 10/100/1000!\n", | ||
| 672 | phydev->speed); | ||
| 673 | break; | ||
| 674 | } | ||
| 675 | priv->oldspeed = phydev->speed; | ||
| 676 | } | ||
| 677 | iowrite32(cfg_reg, &priv->mac_dev->command_config); | ||
| 678 | |||
| 679 | if (!priv->oldlink) { | ||
| 680 | new_state = 1; | ||
| 681 | priv->oldlink = 1; | ||
| 682 | } | ||
| 683 | } else if (priv->oldlink) { | ||
| 684 | new_state = 1; | ||
| 685 | priv->oldlink = 0; | ||
| 686 | priv->oldspeed = 0; | ||
| 687 | priv->oldduplex = -1; | ||
| 688 | } | ||
| 689 | |||
| 690 | if (new_state && netif_msg_link(priv)) | ||
| 691 | phy_print_status(phydev); | ||
| 692 | |||
| 693 | spin_unlock(&priv->mac_cfg_lock); | ||
| 694 | } | ||
| 695 | static struct phy_device *connect_local_phy(struct net_device *dev) | ||
| 696 | { | ||
| 697 | struct altera_tse_private *priv = netdev_priv(dev); | ||
| 698 | struct phy_device *phydev = NULL; | ||
| 699 | char phy_id_fmt[MII_BUS_ID_SIZE + 3]; | ||
| 700 | int ret; | ||
| 701 | |||
| 702 | if (priv->phy_addr != POLL_PHY) { | ||
| 703 | snprintf(phy_id_fmt, MII_BUS_ID_SIZE + 3, PHY_ID_FMT, | ||
| 704 | priv->mdio->id, priv->phy_addr); | ||
| 705 | |||
| 706 | netdev_dbg(dev, "trying to attach to %s\n", phy_id_fmt); | ||
| 707 | |||
| 708 | phydev = phy_connect(dev, phy_id_fmt, &altera_tse_adjust_link, | ||
| 709 | priv->phy_iface); | ||
| 710 | if (IS_ERR(phydev)) | ||
| 711 | netdev_err(dev, "Could not attach to PHY\n"); | ||
| 712 | |||
| 713 | } else { | ||
| 714 | phydev = phy_find_first(priv->mdio); | ||
| 715 | if (phydev == NULL) { | ||
| 716 | netdev_err(dev, "No PHY found\n"); | ||
| 717 | return phydev; | ||
| 718 | } | ||
| 719 | |||
| 720 | ret = phy_connect_direct(dev, phydev, &altera_tse_adjust_link, | ||
| 721 | priv->phy_iface); | ||
| 722 | if (ret != 0) { | ||
| 723 | netdev_err(dev, "Could not attach to PHY\n"); | ||
| 724 | phydev = NULL; | ||
| 725 | } | ||
| 726 | } | ||
| 727 | return phydev; | ||
| 728 | } | ||
| 729 | |||
| 730 | /* Initialize driver's PHY state, and attach to the PHY | ||
| 731 | */ | ||
| 732 | static int init_phy(struct net_device *dev) | ||
| 733 | { | ||
| 734 | struct altera_tse_private *priv = netdev_priv(dev); | ||
| 735 | struct phy_device *phydev; | ||
| 736 | struct device_node *phynode; | ||
| 737 | |||
| 738 | priv->oldlink = 0; | ||
| 739 | priv->oldspeed = 0; | ||
| 740 | priv->oldduplex = -1; | ||
| 741 | |||
| 742 | phynode = of_parse_phandle(priv->device->of_node, "phy-handle", 0); | ||
| 743 | |||
| 744 | if (!phynode) { | ||
| 745 | netdev_dbg(dev, "no phy-handle found\n"); | ||
| 746 | if (!priv->mdio) { | ||
| 747 | netdev_err(dev, | ||
| 748 | "No phy-handle nor local mdio specified\n"); | ||
| 749 | return -ENODEV; | ||
| 750 | } | ||
| 751 | phydev = connect_local_phy(dev); | ||
| 752 | } else { | ||
| 753 | netdev_dbg(dev, "phy-handle found\n"); | ||
| 754 | phydev = of_phy_connect(dev, phynode, | ||
| 755 | &altera_tse_adjust_link, 0, priv->phy_iface); | ||
| 756 | } | ||
| 757 | |||
| 758 | if (!phydev) { | ||
| 759 | netdev_err(dev, "Could not find the PHY\n"); | ||
| 760 | return -ENODEV; | ||
| 761 | } | ||
| 762 | |||
| 763 | /* Stop Advertising 1000BASE Capability if interface is not GMII | ||
| 764 | * Note: Checkpatch throws CHECKs for the camel case defines below, | ||
| 765 | * it's ok to ignore. | ||
| 766 | */ | ||
| 767 | if ((priv->phy_iface == PHY_INTERFACE_MODE_MII) || | ||
| 768 | (priv->phy_iface == PHY_INTERFACE_MODE_RMII)) | ||
| 769 | phydev->advertising &= ~(SUPPORTED_1000baseT_Half | | ||
| 770 | SUPPORTED_1000baseT_Full); | ||
| 771 | |||
| 772 | /* Broken HW is sometimes missing the pull-up resistor on the | ||
| 773 | * MDIO line, which results in reads to non-existent devices returning | ||
| 774 | * 0 rather than 0xffff. Catch this here and treat 0 as a non-existent | ||
| 775 | * device as well. | ||
| 776 | * Note: phydev->phy_id is the result of reading the UID PHY registers. | ||
| 777 | */ | ||
| 778 | if (phydev->phy_id == 0) { | ||
| 779 | netdev_err(dev, "Bad PHY UID 0x%08x\n", phydev->phy_id); | ||
| 780 | phy_disconnect(phydev); | ||
| 781 | return -ENODEV; | ||
| 782 | } | ||
| 783 | |||
| 784 | netdev_dbg(dev, "attached to PHY %d UID 0x%08x Link = %d\n", | ||
| 785 | phydev->addr, phydev->phy_id, phydev->link); | ||
| 786 | |||
| 787 | priv->phydev = phydev; | ||
| 788 | return 0; | ||
| 789 | } | ||
| 790 | |||
| 791 | static void tse_update_mac_addr(struct altera_tse_private *priv, u8 *addr) | ||
| 792 | { | ||
| 793 | struct altera_tse_mac *mac = priv->mac_dev; | ||
| 794 | u32 msb; | ||
| 795 | u32 lsb; | ||
| 796 | |||
| 797 | msb = (addr[3] << 24) | (addr[2] << 16) | (addr[1] << 8) | addr[0]; | ||
| 798 | lsb = ((addr[5] << 8) | addr[4]) & 0xffff; | ||
| 799 | |||
| 800 | /* Set primary MAC address */ | ||
| 801 | iowrite32(msb, &mac->mac_addr_0); | ||
| 802 | iowrite32(lsb, &mac->mac_addr_1); | ||
| 803 | } | ||
| 804 | |||
| 805 | /* MAC software reset. | ||
| 806 | * When reset is triggered, the MAC function completes the current | ||
| 807 | * transmission or reception, and subsequently disables the transmit and | ||
| 808 | * receive logic, flushes the receive FIFO buffer, and resets the statistics | ||
| 809 | * counters. | ||
| 810 | */ | ||
| 811 | static int reset_mac(struct altera_tse_private *priv) | ||
| 812 | { | ||
| 813 | void __iomem *cmd_cfg_reg = &priv->mac_dev->command_config; | ||
| 814 | int counter; | ||
| 815 | u32 dat; | ||
| 816 | |||
| 817 | dat = ioread32(cmd_cfg_reg); | ||
| 818 | dat &= ~(MAC_CMDCFG_TX_ENA | MAC_CMDCFG_RX_ENA); | ||
| 819 | dat |= MAC_CMDCFG_SW_RESET | MAC_CMDCFG_CNT_RESET; | ||
| 820 | iowrite32(dat, cmd_cfg_reg); | ||
| 821 | |||
| 822 | counter = 0; | ||
| 823 | while (counter++ < ALTERA_TSE_SW_RESET_WATCHDOG_CNTR) { | ||
| 824 | if (tse_bit_is_clear(cmd_cfg_reg, MAC_CMDCFG_SW_RESET)) | ||
| 825 | break; | ||
| 826 | udelay(1); | ||
| 827 | } | ||
| 828 | |||
| 829 | if (counter >= ALTERA_TSE_SW_RESET_WATCHDOG_CNTR) { | ||
| 830 | dat = ioread32(cmd_cfg_reg); | ||
| 831 | dat &= ~MAC_CMDCFG_SW_RESET; | ||
| 832 | iowrite32(dat, cmd_cfg_reg); | ||
| 833 | return -1; | ||
| 834 | } | ||
| 835 | return 0; | ||
| 836 | } | ||
| 837 | |||
| 838 | /* Initialize MAC core registers | ||
| 839 | */ | ||
| 840 | static int init_mac(struct altera_tse_private *priv) | ||
| 841 | { | ||
| 842 | struct altera_tse_mac *mac = priv->mac_dev; | ||
| 843 | unsigned int cmd = 0; | ||
| 844 | u32 frm_length; | ||
| 845 | |||
| 846 | /* Setup Rx FIFO */ | ||
| 847 | iowrite32(priv->rx_fifo_depth - ALTERA_TSE_RX_SECTION_EMPTY, | ||
| 848 | &mac->rx_section_empty); | ||
| 849 | iowrite32(ALTERA_TSE_RX_SECTION_FULL, &mac->rx_section_full); | ||
| 850 | iowrite32(ALTERA_TSE_RX_ALMOST_EMPTY, &mac->rx_almost_empty); | ||
| 851 | iowrite32(ALTERA_TSE_RX_ALMOST_FULL, &mac->rx_almost_full); | ||
| 852 | |||
| 853 | /* Setup Tx FIFO */ | ||
| 854 | iowrite32(priv->tx_fifo_depth - ALTERA_TSE_TX_SECTION_EMPTY, | ||
| 855 | &mac->tx_section_empty); | ||
| 856 | iowrite32(ALTERA_TSE_TX_SECTION_FULL, &mac->tx_section_full); | ||
| 857 | iowrite32(ALTERA_TSE_TX_ALMOST_EMPTY, &mac->tx_almost_empty); | ||
| 858 | iowrite32(ALTERA_TSE_TX_ALMOST_FULL, &mac->tx_almost_full); | ||
| 859 | |||
| 860 | /* MAC Address Configuration */ | ||
| 861 | tse_update_mac_addr(priv, priv->dev->dev_addr); | ||
| 862 | |||
| 863 | /* MAC Function Configuration */ | ||
| 864 | frm_length = ETH_HLEN + priv->dev->mtu + ETH_FCS_LEN; | ||
| 865 | iowrite32(frm_length, &mac->frm_length); | ||
| 866 | iowrite32(ALTERA_TSE_TX_IPG_LENGTH, &mac->tx_ipg_length); | ||
| 867 | |||
| 868 | /* Disable RX/TX shift 16 for alignment of all received frames on 16-bit | ||
| 869 | * start address | ||
| 870 | */ | ||
| 871 | tse_clear_bit(&mac->rx_cmd_stat, ALTERA_TSE_RX_CMD_STAT_RX_SHIFT16); | ||
| 872 | tse_clear_bit(&mac->tx_cmd_stat, ALTERA_TSE_TX_CMD_STAT_TX_SHIFT16 | | ||
| 873 | ALTERA_TSE_TX_CMD_STAT_OMIT_CRC); | ||
| 874 | |||
| 875 | /* Set the MAC options */ | ||
| 876 | cmd = ioread32(&mac->command_config); | ||
| 877 | cmd |= MAC_CMDCFG_PAD_EN; /* Padding Removal on Receive */ | ||
| 878 | cmd &= ~MAC_CMDCFG_CRC_FWD; /* CRC Removal */ | ||
| 879 | cmd |= MAC_CMDCFG_RX_ERR_DISC; /* Automatically discard frames | ||
| 880 | * with CRC errors | ||
| 881 | */ | ||
| 882 | cmd |= MAC_CMDCFG_CNTL_FRM_ENA; | ||
| 883 | cmd &= ~MAC_CMDCFG_TX_ENA; | ||
| 884 | cmd &= ~MAC_CMDCFG_RX_ENA; | ||
| 885 | iowrite32(cmd, &mac->command_config); | ||
| 886 | |||
| 887 | if (netif_msg_hw(priv)) | ||
| 888 | dev_dbg(priv->device, | ||
| 889 | "MAC post-initialization: CMD_CONFIG = 0x%08x\n", cmd); | ||
| 890 | |||
| 891 | return 0; | ||
| 892 | } | ||
| 893 | |||
| 894 | /* Start/stop MAC transmission logic | ||
| 895 | */ | ||
| 896 | static void tse_set_mac(struct altera_tse_private *priv, bool enable) | ||
| 897 | { | ||
| 898 | struct altera_tse_mac *mac = priv->mac_dev; | ||
| 899 | u32 value = ioread32(&mac->command_config); | ||
| 900 | |||
| 901 | if (enable) | ||
| 902 | value |= MAC_CMDCFG_TX_ENA | MAC_CMDCFG_RX_ENA; | ||
| 903 | else | ||
| 904 | value &= ~(MAC_CMDCFG_TX_ENA | MAC_CMDCFG_RX_ENA); | ||
| 905 | |||
| 906 | iowrite32(value, &mac->command_config); | ||
| 907 | } | ||
| 908 | |||
| 909 | /* Change the MTU | ||
| 910 | */ | ||
| 911 | static int tse_change_mtu(struct net_device *dev, int new_mtu) | ||
| 912 | { | ||
| 913 | struct altera_tse_private *priv = netdev_priv(dev); | ||
| 914 | unsigned int max_mtu = priv->max_mtu; | ||
| 915 | unsigned int min_mtu = ETH_ZLEN + ETH_FCS_LEN; | ||
| 916 | |||
| 917 | if (netif_running(dev)) { | ||
| 918 | netdev_err(dev, "must be stopped to change its MTU\n"); | ||
| 919 | return -EBUSY; | ||
| 920 | } | ||
| 921 | |||
| 922 | if ((new_mtu < min_mtu) || (new_mtu > max_mtu)) { | ||
| 923 | netdev_err(dev, "invalid MTU, max MTU is: %u\n", max_mtu); | ||
| 924 | return -EINVAL; | ||
| 925 | } | ||
| 926 | |||
| 927 | dev->mtu = new_mtu; | ||
| 928 | netdev_update_features(dev); | ||
| 929 | |||
| 930 | return 0; | ||
| 931 | } | ||
| 932 | |||
| 933 | static void altera_tse_set_mcfilter(struct net_device *dev) | ||
| 934 | { | ||
| 935 | struct altera_tse_private *priv = netdev_priv(dev); | ||
| 936 | struct altera_tse_mac *mac = priv->mac_dev; | ||
| 937 | int i; | ||
| 938 | struct netdev_hw_addr *ha; | ||
| 939 | |||
| 940 | /* clear the hash filter */ | ||
| 941 | for (i = 0; i < 64; i++) | ||
| 942 | iowrite32(0, &(mac->hash_table[i])); | ||
| 943 | |||
| 944 | netdev_for_each_mc_addr(ha, dev) { | ||
| 945 | unsigned int hash = 0; | ||
| 946 | int mac_octet; | ||
| 947 | |||
| 948 | for (mac_octet = 5; mac_octet >= 0; mac_octet--) { | ||
| 949 | unsigned char xor_bit = 0; | ||
| 950 | unsigned char octet = ha->addr[mac_octet]; | ||
| 951 | unsigned int bitshift; | ||
| 952 | |||
| 953 | for (bitshift = 0; bitshift < 8; bitshift++) | ||
| 954 | xor_bit ^= ((octet >> bitshift) & 0x01); | ||
| 955 | |||
| 956 | hash = (hash << 1) | xor_bit; | ||
| 957 | } | ||
| 958 | iowrite32(1, &(mac->hash_table[hash])); | ||
| 959 | } | ||
| 960 | } | ||
| 961 | |||
| 962 | |||
| 963 | static void altera_tse_set_mcfilterall(struct net_device *dev) | ||
| 964 | { | ||
| 965 | struct altera_tse_private *priv = netdev_priv(dev); | ||
| 966 | struct altera_tse_mac *mac = priv->mac_dev; | ||
| 967 | int i; | ||
| 968 | |||
| 969 | /* set the hash filter */ | ||
| 970 | for (i = 0; i < 64; i++) | ||
| 971 | iowrite32(1, &(mac->hash_table[i])); | ||
| 972 | } | ||
| 973 | |||
| 974 | /* Set or clear the multicast filter for this adaptor | ||
| 975 | */ | ||
| 976 | static void tse_set_rx_mode_hashfilter(struct net_device *dev) | ||
| 977 | { | ||
| 978 | struct altera_tse_private *priv = netdev_priv(dev); | ||
| 979 | struct altera_tse_mac *mac = priv->mac_dev; | ||
| 980 | |||
| 981 | spin_lock(&priv->mac_cfg_lock); | ||
| 982 | |||
| 983 | if (dev->flags & IFF_PROMISC) | ||
| 984 | tse_set_bit(&mac->command_config, MAC_CMDCFG_PROMIS_EN); | ||
| 985 | |||
| 986 | if (dev->flags & IFF_ALLMULTI) | ||
| 987 | altera_tse_set_mcfilterall(dev); | ||
| 988 | else | ||
| 989 | altera_tse_set_mcfilter(dev); | ||
| 990 | |||
| 991 | spin_unlock(&priv->mac_cfg_lock); | ||
| 992 | } | ||
| 993 | |||
| 994 | /* Set or clear the multicast filter for this adaptor | ||
| 995 | */ | ||
| 996 | static void tse_set_rx_mode(struct net_device *dev) | ||
| 997 | { | ||
| 998 | struct altera_tse_private *priv = netdev_priv(dev); | ||
| 999 | struct altera_tse_mac *mac = priv->mac_dev; | ||
| 1000 | |||
| 1001 | spin_lock(&priv->mac_cfg_lock); | ||
| 1002 | |||
| 1003 | if ((dev->flags & IFF_PROMISC) || (dev->flags & IFF_ALLMULTI) || | ||
| 1004 | !netdev_mc_empty(dev) || !netdev_uc_empty(dev)) | ||
| 1005 | tse_set_bit(&mac->command_config, MAC_CMDCFG_PROMIS_EN); | ||
| 1006 | else | ||
| 1007 | tse_clear_bit(&mac->command_config, MAC_CMDCFG_PROMIS_EN); | ||
| 1008 | |||
| 1009 | spin_unlock(&priv->mac_cfg_lock); | ||
| 1010 | } | ||
| 1011 | |||
| 1012 | /* Open and initialize the interface | ||
| 1013 | */ | ||
| 1014 | static int tse_open(struct net_device *dev) | ||
| 1015 | { | ||
| 1016 | struct altera_tse_private *priv = netdev_priv(dev); | ||
| 1017 | int ret = 0; | ||
| 1018 | int i; | ||
| 1019 | unsigned long int flags; | ||
| 1020 | |||
| 1021 | /* Reset and configure TSE MAC and probe associated PHY */ | ||
| 1022 | ret = priv->dmaops->init_dma(priv); | ||
| 1023 | if (ret != 0) { | ||
| 1024 | netdev_err(dev, "Cannot initialize DMA\n"); | ||
| 1025 | goto phy_error; | ||
| 1026 | } | ||
| 1027 | |||
| 1028 | if (netif_msg_ifup(priv)) | ||
| 1029 | netdev_warn(dev, "device MAC address %pM\n", | ||
| 1030 | dev->dev_addr); | ||
| 1031 | |||
| 1032 | if ((priv->revision < 0xd00) || (priv->revision > 0xe00)) | ||
| 1033 | netdev_warn(dev, "TSE revision %x\n", priv->revision); | ||
| 1034 | |||
| 1035 | spin_lock(&priv->mac_cfg_lock); | ||
| 1036 | ret = reset_mac(priv); | ||
| 1037 | if (ret) | ||
| 1038 | netdev_err(dev, "Cannot reset MAC core (error: %d)\n", ret); | ||
| 1039 | |||
| 1040 | ret = init_mac(priv); | ||
| 1041 | spin_unlock(&priv->mac_cfg_lock); | ||
| 1042 | if (ret) { | ||
| 1043 | netdev_err(dev, "Cannot init MAC core (error: %d)\n", ret); | ||
| 1044 | goto alloc_skbuf_error; | ||
| 1045 | } | ||
| 1046 | |||
| 1047 | priv->dmaops->reset_dma(priv); | ||
| 1048 | |||
| 1049 | /* Create and initialize the TX/RX descriptors chains. */ | ||
| 1050 | priv->rx_ring_size = dma_rx_num; | ||
| 1051 | priv->tx_ring_size = dma_tx_num; | ||
| 1052 | ret = alloc_init_skbufs(priv); | ||
| 1053 | if (ret) { | ||
| 1054 | netdev_err(dev, "DMA descriptors initialization failed\n"); | ||
| 1055 | goto alloc_skbuf_error; | ||
| 1056 | } | ||
| 1057 | |||
| 1058 | |||
| 1059 | /* Register RX interrupt */ | ||
| 1060 | ret = request_irq(priv->rx_irq, altera_isr, IRQF_SHARED, | ||
| 1061 | dev->name, dev); | ||
| 1062 | if (ret) { | ||
| 1063 | netdev_err(dev, "Unable to register RX interrupt %d\n", | ||
| 1064 | priv->rx_irq); | ||
| 1065 | goto init_error; | ||
| 1066 | } | ||
| 1067 | |||
| 1068 | /* Register TX interrupt */ | ||
| 1069 | ret = request_irq(priv->tx_irq, altera_isr, IRQF_SHARED, | ||
| 1070 | dev->name, dev); | ||
| 1071 | if (ret) { | ||
| 1072 | netdev_err(dev, "Unable to register TX interrupt %d\n", | ||
| 1073 | priv->tx_irq); | ||
| 1074 | goto tx_request_irq_error; | ||
| 1075 | } | ||
| 1076 | |||
| 1077 | /* Enable DMA interrupts */ | ||
| 1078 | spin_lock_irqsave(&priv->rxdma_irq_lock, flags); | ||
| 1079 | priv->dmaops->enable_rxirq(priv); | ||
| 1080 | priv->dmaops->enable_txirq(priv); | ||
| 1081 | |||
| 1082 | /* Setup RX descriptor chain */ | ||
| 1083 | for (i = 0; i < priv->rx_ring_size; i++) | ||
| 1084 | priv->dmaops->add_rx_desc(priv, &priv->rx_ring[i]); | ||
| 1085 | |||
| 1086 | spin_unlock_irqrestore(&priv->rxdma_irq_lock, flags); | ||
| 1087 | |||
| 1088 | /* Start MAC Rx/Tx */ | ||
| 1089 | spin_lock(&priv->mac_cfg_lock); | ||
| 1090 | tse_set_mac(priv, true); | ||
| 1091 | spin_unlock(&priv->mac_cfg_lock); | ||
| 1092 | |||
| 1093 | if (priv->phydev) | ||
| 1094 | phy_start(priv->phydev); | ||
| 1095 | |||
| 1096 | napi_enable(&priv->napi); | ||
| 1097 | netif_start_queue(dev); | ||
| 1098 | |||
| 1099 | return 0; | ||
| 1100 | |||
| 1101 | tx_request_irq_error: | ||
| 1102 | free_irq(priv->rx_irq, dev); | ||
| 1103 | init_error: | ||
| 1104 | free_skbufs(dev); | ||
| 1105 | alloc_skbuf_error: | ||
| 1106 | if (priv->phydev) { | ||
| 1107 | phy_disconnect(priv->phydev); | ||
| 1108 | priv->phydev = NULL; | ||
| 1109 | } | ||
| 1110 | phy_error: | ||
| 1111 | return ret; | ||
| 1112 | } | ||
| 1113 | |||
| 1114 | /* Stop TSE MAC interface and put the device in an inactive state | ||
| 1115 | */ | ||
| 1116 | static int tse_shutdown(struct net_device *dev) | ||
| 1117 | { | ||
| 1118 | struct altera_tse_private *priv = netdev_priv(dev); | ||
| 1119 | int ret; | ||
| 1120 | unsigned long int flags; | ||
| 1121 | |||
| 1122 | /* Stop and disconnect the PHY */ | ||
| 1123 | if (priv->phydev) { | ||
| 1124 | phy_stop(priv->phydev); | ||
| 1125 | phy_disconnect(priv->phydev); | ||
| 1126 | priv->phydev = NULL; | ||
| 1127 | } | ||
| 1128 | |||
| 1129 | netif_stop_queue(dev); | ||
| 1130 | napi_disable(&priv->napi); | ||
| 1131 | |||
| 1132 | /* Disable DMA interrupts */ | ||
| 1133 | spin_lock_irqsave(&priv->rxdma_irq_lock, flags); | ||
| 1134 | priv->dmaops->disable_rxirq(priv); | ||
| 1135 | priv->dmaops->disable_txirq(priv); | ||
| 1136 | spin_unlock_irqrestore(&priv->rxdma_irq_lock, flags); | ||
| 1137 | |||
| 1138 | /* Free the IRQ lines */ | ||
| 1139 | free_irq(priv->rx_irq, dev); | ||
| 1140 | free_irq(priv->tx_irq, dev); | ||
| 1141 | |||
| 1142 | /* disable and reset the MAC, empties fifo */ | ||
| 1143 | spin_lock(&priv->mac_cfg_lock); | ||
| 1144 | spin_lock(&priv->tx_lock); | ||
| 1145 | |||
| 1146 | ret = reset_mac(priv); | ||
| 1147 | if (ret) | ||
| 1148 | netdev_err(dev, "Cannot reset MAC core (error: %d)\n", ret); | ||
| 1149 | priv->dmaops->reset_dma(priv); | ||
| 1150 | free_skbufs(dev); | ||
| 1151 | |||
| 1152 | spin_unlock(&priv->tx_lock); | ||
| 1153 | spin_unlock(&priv->mac_cfg_lock); | ||
| 1154 | |||
| 1155 | priv->dmaops->uninit_dma(priv); | ||
| 1156 | |||
| 1157 | return 0; | ||
| 1158 | } | ||
| 1159 | |||
| 1160 | static struct net_device_ops altera_tse_netdev_ops = { | ||
| 1161 | .ndo_open = tse_open, | ||
| 1162 | .ndo_stop = tse_shutdown, | ||
| 1163 | .ndo_start_xmit = tse_start_xmit, | ||
| 1164 | .ndo_set_mac_address = eth_mac_addr, | ||
| 1165 | .ndo_set_rx_mode = tse_set_rx_mode, | ||
| 1166 | .ndo_change_mtu = tse_change_mtu, | ||
| 1167 | .ndo_validate_addr = eth_validate_addr, | ||
| 1168 | }; | ||
| 1169 | |||
| 1170 | |||
| 1171 | static int request_and_map(struct platform_device *pdev, const char *name, | ||
| 1172 | struct resource **res, void __iomem **ptr) | ||
| 1173 | { | ||
| 1174 | struct resource *region; | ||
| 1175 | struct device *device = &pdev->dev; | ||
| 1176 | |||
| 1177 | *res = platform_get_resource_byname(pdev, IORESOURCE_MEM, name); | ||
| 1178 | if (*res == NULL) { | ||
| 1179 | dev_err(device, "resource %s not defined\n", name); | ||
| 1180 | return -ENODEV; | ||
| 1181 | } | ||
| 1182 | |||
| 1183 | region = devm_request_mem_region(device, (*res)->start, | ||
| 1184 | resource_size(*res), dev_name(device)); | ||
| 1185 | if (region == NULL) { | ||
| 1186 | dev_err(device, "unable to request %s\n", name); | ||
| 1187 | return -EBUSY; | ||
| 1188 | } | ||
| 1189 | |||
| 1190 | *ptr = devm_ioremap_nocache(device, region->start, | ||
| 1191 | resource_size(region)); | ||
| 1192 | if (*ptr == NULL) { | ||
| 1193 | dev_err(device, "ioremap_nocache of %s failed!", name); | ||
| 1194 | return -ENOMEM; | ||
| 1195 | } | ||
| 1196 | |||
| 1197 | return 0; | ||
| 1198 | } | ||
| 1199 | |||
| 1200 | /* Probe Altera TSE MAC device | ||
| 1201 | */ | ||
| 1202 | static int altera_tse_probe(struct platform_device *pdev) | ||
| 1203 | { | ||
| 1204 | struct net_device *ndev; | ||
| 1205 | int ret = -ENODEV; | ||
| 1206 | struct resource *control_port; | ||
| 1207 | struct resource *dma_res; | ||
| 1208 | struct altera_tse_private *priv; | ||
| 1209 | const unsigned char *macaddr; | ||
| 1210 | struct device_node *np = pdev->dev.of_node; | ||
| 1211 | void __iomem *descmap; | ||
| 1212 | const struct of_device_id *of_id = NULL; | ||
| 1213 | |||
| 1214 | ndev = alloc_etherdev(sizeof(struct altera_tse_private)); | ||
| 1215 | if (!ndev) { | ||
| 1216 | dev_err(&pdev->dev, "Could not allocate network device\n"); | ||
| 1217 | return -ENODEV; | ||
| 1218 | } | ||
| 1219 | |||
| 1220 | SET_NETDEV_DEV(ndev, &pdev->dev); | ||
| 1221 | |||
| 1222 | priv = netdev_priv(ndev); | ||
| 1223 | priv->device = &pdev->dev; | ||
| 1224 | priv->dev = ndev; | ||
| 1225 | priv->msg_enable = netif_msg_init(debug, default_msg_level); | ||
| 1226 | |||
| 1227 | of_id = of_match_device(altera_tse_ids, &pdev->dev); | ||
| 1228 | |||
| 1229 | if (of_id) | ||
| 1230 | priv->dmaops = (struct altera_dmaops *)of_id->data; | ||
| 1231 | |||
| 1232 | |||
| 1233 | if (priv->dmaops && | ||
| 1234 | priv->dmaops->altera_dtype == ALTERA_DTYPE_SGDMA) { | ||
| 1235 | /* Get the mapped address to the SGDMA descriptor memory */ | ||
| 1236 | ret = request_and_map(pdev, "s1", &dma_res, &descmap); | ||
| 1237 | if (ret) | ||
| 1238 | goto out_free; | ||
| 1239 | |||
| 1240 | /* Start of that memory is for transmit descriptors */ | ||
| 1241 | priv->tx_dma_desc = descmap; | ||
| 1242 | |||
| 1243 | /* First half is for tx descriptors, other half for tx */ | ||
| 1244 | priv->txdescmem = resource_size(dma_res)/2; | ||
| 1245 | |||
| 1246 | priv->txdescmem_busaddr = (dma_addr_t)dma_res->start; | ||
| 1247 | |||
| 1248 | priv->rx_dma_desc = (void __iomem *)((uintptr_t)(descmap + | ||
| 1249 | priv->txdescmem)); | ||
| 1250 | priv->rxdescmem = resource_size(dma_res)/2; | ||
| 1251 | priv->rxdescmem_busaddr = dma_res->start; | ||
| 1252 | priv->rxdescmem_busaddr += priv->txdescmem; | ||
| 1253 | |||
| 1254 | if (upper_32_bits(priv->rxdescmem_busaddr)) { | ||
| 1255 | dev_dbg(priv->device, | ||
| 1256 | "SGDMA bus addresses greater than 32-bits\n"); | ||
| 1257 | goto out_free; | ||
| 1258 | } | ||
| 1259 | if (upper_32_bits(priv->txdescmem_busaddr)) { | ||
| 1260 | dev_dbg(priv->device, | ||
| 1261 | "SGDMA bus addresses greater than 32-bits\n"); | ||
| 1262 | goto out_free; | ||
| 1263 | } | ||
| 1264 | } else if (priv->dmaops && | ||
| 1265 | priv->dmaops->altera_dtype == ALTERA_DTYPE_MSGDMA) { | ||
| 1266 | ret = request_and_map(pdev, "rx_resp", &dma_res, | ||
| 1267 | &priv->rx_dma_resp); | ||
| 1268 | if (ret) | ||
| 1269 | goto out_free; | ||
| 1270 | |||
| 1271 | ret = request_and_map(pdev, "tx_desc", &dma_res, | ||
| 1272 | &priv->tx_dma_desc); | ||
| 1273 | if (ret) | ||
| 1274 | goto out_free; | ||
| 1275 | |||
| 1276 | priv->txdescmem = resource_size(dma_res); | ||
| 1277 | priv->txdescmem_busaddr = dma_res->start; | ||
| 1278 | |||
| 1279 | ret = request_and_map(pdev, "rx_desc", &dma_res, | ||
| 1280 | &priv->rx_dma_desc); | ||
| 1281 | if (ret) | ||
| 1282 | goto out_free; | ||
| 1283 | |||
| 1284 | priv->rxdescmem = resource_size(dma_res); | ||
| 1285 | priv->rxdescmem_busaddr = dma_res->start; | ||
| 1286 | |||
| 1287 | } else { | ||
| 1288 | goto out_free; | ||
| 1289 | } | ||
| 1290 | |||
| 1291 | if (!dma_set_mask(priv->device, DMA_BIT_MASK(priv->dmaops->dmamask))) | ||
| 1292 | dma_set_coherent_mask(priv->device, | ||
| 1293 | DMA_BIT_MASK(priv->dmaops->dmamask)); | ||
| 1294 | else if (!dma_set_mask(priv->device, DMA_BIT_MASK(32))) | ||
| 1295 | dma_set_coherent_mask(priv->device, DMA_BIT_MASK(32)); | ||
| 1296 | else | ||
| 1297 | goto out_free; | ||
| 1298 | |||
| 1299 | /* MAC address space */ | ||
| 1300 | ret = request_and_map(pdev, "control_port", &control_port, | ||
| 1301 | (void __iomem **)&priv->mac_dev); | ||
| 1302 | if (ret) | ||
| 1303 | goto out_free; | ||
| 1304 | |||
| 1305 | /* xSGDMA Rx Dispatcher address space */ | ||
| 1306 | ret = request_and_map(pdev, "rx_csr", &dma_res, | ||
| 1307 | &priv->rx_dma_csr); | ||
| 1308 | if (ret) | ||
| 1309 | goto out_free; | ||
| 1310 | |||
| 1311 | |||
| 1312 | /* xSGDMA Tx Dispatcher address space */ | ||
| 1313 | ret = request_and_map(pdev, "tx_csr", &dma_res, | ||
| 1314 | &priv->tx_dma_csr); | ||
| 1315 | if (ret) | ||
| 1316 | goto out_free; | ||
| 1317 | |||
| 1318 | |||
| 1319 | /* Rx IRQ */ | ||
| 1320 | priv->rx_irq = platform_get_irq_byname(pdev, "rx_irq"); | ||
| 1321 | if (priv->rx_irq == -ENXIO) { | ||
| 1322 | dev_err(&pdev->dev, "cannot obtain Rx IRQ\n"); | ||
| 1323 | ret = -ENXIO; | ||
| 1324 | goto out_free; | ||
| 1325 | } | ||
| 1326 | |||
| 1327 | /* Tx IRQ */ | ||
| 1328 | priv->tx_irq = platform_get_irq_byname(pdev, "tx_irq"); | ||
| 1329 | if (priv->tx_irq == -ENXIO) { | ||
| 1330 | dev_err(&pdev->dev, "cannot obtain Tx IRQ\n"); | ||
| 1331 | ret = -ENXIO; | ||
| 1332 | goto out_free; | ||
| 1333 | } | ||
| 1334 | |||
| 1335 | /* get FIFO depths from device tree */ | ||
| 1336 | if (of_property_read_u32(pdev->dev.of_node, "rx-fifo-depth", | ||
| 1337 | &priv->rx_fifo_depth)) { | ||
| 1338 | dev_err(&pdev->dev, "cannot obtain rx-fifo-depth\n"); | ||
| 1339 | ret = -ENXIO; | ||
| 1340 | goto out_free; | ||
| 1341 | } | ||
| 1342 | |||
| 1343 | if (of_property_read_u32(pdev->dev.of_node, "tx-fifo-depth", | ||
| 1344 | &priv->rx_fifo_depth)) { | ||
| 1345 | dev_err(&pdev->dev, "cannot obtain tx-fifo-depth\n"); | ||
| 1346 | ret = -ENXIO; | ||
| 1347 | goto out_free; | ||
| 1348 | } | ||
| 1349 | |||
| 1350 | /* get hash filter settings for this instance */ | ||
| 1351 | priv->hash_filter = | ||
| 1352 | of_property_read_bool(pdev->dev.of_node, | ||
| 1353 | "altr,has-hash-multicast-filter"); | ||
| 1354 | |||
| 1355 | /* get supplemental address settings for this instance */ | ||
| 1356 | priv->added_unicast = | ||
| 1357 | of_property_read_bool(pdev->dev.of_node, | ||
| 1358 | "altr,has-supplementary-unicast"); | ||
| 1359 | |||
| 1360 | /* Max MTU is 1500, ETH_DATA_LEN */ | ||
| 1361 | priv->max_mtu = ETH_DATA_LEN; | ||
| 1362 | |||
| 1363 | /* Get the max mtu from the device tree. Note that the | ||
| 1364 | * "max-frame-size" parameter is actually max mtu. Definition | ||
| 1365 | * in the ePAPR v1.1 spec and usage differ, so go with usage. | ||
| 1366 | */ | ||
| 1367 | of_property_read_u32(pdev->dev.of_node, "max-frame-size", | ||
| 1368 | &priv->max_mtu); | ||
| 1369 | |||
| 1370 | /* The DMA buffer size already accounts for an alignment bias | ||
| 1371 | * to avoid unaligned access exceptions for the NIOS processor, | ||
| 1372 | */ | ||
| 1373 | priv->rx_dma_buf_sz = ALTERA_RXDMABUFFER_SIZE; | ||
| 1374 | |||
| 1375 | /* get default MAC address from device tree */ | ||
| 1376 | macaddr = of_get_mac_address(pdev->dev.of_node); | ||
| 1377 | if (macaddr) | ||
| 1378 | ether_addr_copy(ndev->dev_addr, macaddr); | ||
| 1379 | else | ||
| 1380 | eth_hw_addr_random(ndev); | ||
| 1381 | |||
| 1382 | priv->phy_iface = of_get_phy_mode(np); | ||
| 1383 | |||
| 1384 | /* try to get PHY address from device tree, use PHY autodetection if | ||
| 1385 | * no valid address is given | ||
| 1386 | */ | ||
| 1387 | if (of_property_read_u32(pdev->dev.of_node, "phy-addr", | ||
| 1388 | &priv->phy_addr)) { | ||
| 1389 | priv->phy_addr = POLL_PHY; | ||
| 1390 | } | ||
| 1391 | |||
| 1392 | if (!((priv->phy_addr == POLL_PHY) || | ||
| 1393 | ((priv->phy_addr >= 0) && (priv->phy_addr < PHY_MAX_ADDR)))) { | ||
| 1394 | dev_err(&pdev->dev, "invalid phy-addr specified %d\n", | ||
| 1395 | priv->phy_addr); | ||
| 1396 | goto out_free; | ||
| 1397 | } | ||
| 1398 | |||
| 1399 | /* Create/attach to MDIO bus */ | ||
| 1400 | ret = altera_tse_mdio_create(ndev, | ||
| 1401 | atomic_add_return(1, &instance_count)); | ||
| 1402 | |||
| 1403 | if (ret) | ||
| 1404 | goto out_free; | ||
| 1405 | |||
| 1406 | /* initialize netdev */ | ||
| 1407 | ether_setup(ndev); | ||
| 1408 | ndev->mem_start = control_port->start; | ||
| 1409 | ndev->mem_end = control_port->end; | ||
| 1410 | ndev->netdev_ops = &altera_tse_netdev_ops; | ||
| 1411 | altera_tse_set_ethtool_ops(ndev); | ||
| 1412 | |||
| 1413 | altera_tse_netdev_ops.ndo_set_rx_mode = tse_set_rx_mode; | ||
| 1414 | |||
| 1415 | if (priv->hash_filter) | ||
| 1416 | altera_tse_netdev_ops.ndo_set_rx_mode = | ||
| 1417 | tse_set_rx_mode_hashfilter; | ||
| 1418 | |||
| 1419 | /* Scatter/gather IO is not supported, | ||
| 1420 | * so it is turned off | ||
| 1421 | */ | ||
| 1422 | ndev->hw_features &= ~NETIF_F_SG; | ||
| 1423 | ndev->features |= ndev->hw_features | NETIF_F_HIGHDMA; | ||
| 1424 | |||
| 1425 | /* VLAN offloading of tagging, stripping and filtering is not | ||
| 1426 | * supported by hardware, but driver will accommodate the | ||
| 1427 | * extra 4-byte VLAN tag for processing by upper layers | ||
| 1428 | */ | ||
| 1429 | ndev->features |= NETIF_F_HW_VLAN_CTAG_RX; | ||
| 1430 | |||
| 1431 | /* setup NAPI interface */ | ||
| 1432 | netif_napi_add(ndev, &priv->napi, tse_poll, NAPI_POLL_WEIGHT); | ||
| 1433 | |||
| 1434 | spin_lock_init(&priv->mac_cfg_lock); | ||
| 1435 | spin_lock_init(&priv->tx_lock); | ||
| 1436 | spin_lock_init(&priv->rxdma_irq_lock); | ||
| 1437 | |||
| 1438 | ret = register_netdev(ndev); | ||
| 1439 | if (ret) { | ||
| 1440 | dev_err(&pdev->dev, "failed to register TSE net device\n"); | ||
| 1441 | goto out_free_mdio; | ||
| 1442 | } | ||
| 1443 | |||
| 1444 | platform_set_drvdata(pdev, ndev); | ||
| 1445 | |||
| 1446 | priv->revision = ioread32(&priv->mac_dev->megacore_revision); | ||
| 1447 | |||
| 1448 | if (netif_msg_probe(priv)) | ||
| 1449 | dev_info(&pdev->dev, "Altera TSE MAC version %d.%d at 0x%08lx irq %d/%d\n", | ||
| 1450 | (priv->revision >> 8) & 0xff, | ||
| 1451 | priv->revision & 0xff, | ||
| 1452 | (unsigned long) control_port->start, priv->rx_irq, | ||
| 1453 | priv->tx_irq); | ||
| 1454 | |||
| 1455 | ret = init_phy(ndev); | ||
| 1456 | if (ret != 0) { | ||
| 1457 | netdev_err(ndev, "Cannot attach to PHY (error: %d)\n", ret); | ||
| 1458 | goto out_free_mdio; | ||
| 1459 | } | ||
| 1460 | return 0; | ||
| 1461 | |||
| 1462 | out_free_mdio: | ||
| 1463 | altera_tse_mdio_destroy(ndev); | ||
| 1464 | out_free: | ||
| 1465 | free_netdev(ndev); | ||
| 1466 | return ret; | ||
| 1467 | } | ||
| 1468 | |||
| 1469 | /* Remove Altera TSE MAC device | ||
| 1470 | */ | ||
| 1471 | static int altera_tse_remove(struct platform_device *pdev) | ||
| 1472 | { | ||
| 1473 | struct net_device *ndev = platform_get_drvdata(pdev); | ||
| 1474 | |||
| 1475 | platform_set_drvdata(pdev, NULL); | ||
| 1476 | altera_tse_mdio_destroy(ndev); | ||
| 1477 | unregister_netdev(ndev); | ||
| 1478 | free_netdev(ndev); | ||
| 1479 | |||
| 1480 | return 0; | ||
| 1481 | } | ||
| 1482 | |||
| 1483 | struct altera_dmaops altera_dtype_sgdma = { | ||
| 1484 | .altera_dtype = ALTERA_DTYPE_SGDMA, | ||
| 1485 | .dmamask = 32, | ||
| 1486 | .reset_dma = sgdma_reset, | ||
| 1487 | .enable_txirq = sgdma_enable_txirq, | ||
| 1488 | .enable_rxirq = sgdma_enable_rxirq, | ||
| 1489 | .disable_txirq = sgdma_disable_txirq, | ||
| 1490 | .disable_rxirq = sgdma_disable_rxirq, | ||
| 1491 | .clear_txirq = sgdma_clear_txirq, | ||
| 1492 | .clear_rxirq = sgdma_clear_rxirq, | ||
| 1493 | .tx_buffer = sgdma_tx_buffer, | ||
| 1494 | .tx_completions = sgdma_tx_completions, | ||
| 1495 | .add_rx_desc = sgdma_add_rx_desc, | ||
| 1496 | .get_rx_status = sgdma_rx_status, | ||
| 1497 | .init_dma = sgdma_initialize, | ||
| 1498 | .uninit_dma = sgdma_uninitialize, | ||
| 1499 | }; | ||
| 1500 | |||
| 1501 | struct altera_dmaops altera_dtype_msgdma = { | ||
| 1502 | .altera_dtype = ALTERA_DTYPE_MSGDMA, | ||
| 1503 | .dmamask = 64, | ||
| 1504 | .reset_dma = msgdma_reset, | ||
| 1505 | .enable_txirq = msgdma_enable_txirq, | ||
| 1506 | .enable_rxirq = msgdma_enable_rxirq, | ||
| 1507 | .disable_txirq = msgdma_disable_txirq, | ||
| 1508 | .disable_rxirq = msgdma_disable_rxirq, | ||
| 1509 | .clear_txirq = msgdma_clear_txirq, | ||
| 1510 | .clear_rxirq = msgdma_clear_rxirq, | ||
| 1511 | .tx_buffer = msgdma_tx_buffer, | ||
| 1512 | .tx_completions = msgdma_tx_completions, | ||
| 1513 | .add_rx_desc = msgdma_add_rx_desc, | ||
| 1514 | .get_rx_status = msgdma_rx_status, | ||
| 1515 | .init_dma = msgdma_initialize, | ||
| 1516 | .uninit_dma = msgdma_uninitialize, | ||
| 1517 | }; | ||
| 1518 | |||
| 1519 | static struct of_device_id altera_tse_ids[] = { | ||
| 1520 | { .compatible = "altr,tse-msgdma-1.0", .data = &altera_dtype_msgdma, }, | ||
| 1521 | { .compatible = "altr,tse-1.0", .data = &altera_dtype_sgdma, }, | ||
| 1522 | { .compatible = "ALTR,tse-1.0", .data = &altera_dtype_sgdma, }, | ||
| 1523 | {}, | ||
| 1524 | }; | ||
| 1525 | MODULE_DEVICE_TABLE(of, altera_tse_ids); | ||
| 1526 | |||
| 1527 | static struct platform_driver altera_tse_driver = { | ||
| 1528 | .probe = altera_tse_probe, | ||
| 1529 | .remove = altera_tse_remove, | ||
| 1530 | .suspend = NULL, | ||
| 1531 | .resume = NULL, | ||
| 1532 | .driver = { | ||
| 1533 | .name = ALTERA_TSE_RESOURCE_NAME, | ||
| 1534 | .owner = THIS_MODULE, | ||
| 1535 | .of_match_table = altera_tse_ids, | ||
| 1536 | }, | ||
| 1537 | }; | ||
| 1538 | |||
| 1539 | module_platform_driver(altera_tse_driver); | ||
| 1540 | |||
| 1541 | MODULE_AUTHOR("Altera Corporation"); | ||
| 1542 | MODULE_DESCRIPTION("Altera Triple Speed Ethernet MAC driver"); | ||
| 1543 | MODULE_LICENSE("GPL v2"); | ||
| @@ -0,0 +1,44 @@ | |||
| 1 | /* Altera TSE SGDMA and MSGDMA Linux driver | ||
| 2 | * Copyright (C) 2014 Altera Corporation. All rights reserved | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or modify it | ||
| 5 | * under the terms and conditions of the GNU General Public License, | ||
| 6 | * version 2, as published by the Free Software Foundation. | ||
| 7 | * | ||
| 8 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
| 9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 10 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
| 11 | * more details. | ||
| 12 | * | ||
| 13 | * You should have received a copy of the GNU General Public License along with | ||
| 14 | * this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 15 | */ | ||
| 16 | |||
| 17 | #include "altera_tse.h" | ||
| 18 | #include "altera_utils.h" | ||
| 19 | |||
| 20 | void tse_set_bit(void __iomem *ioaddr, u32 bit_mask) | ||
| 21 | { | ||
| 22 | u32 value = ioread32(ioaddr); | ||
| 23 | value |= bit_mask; | ||
| 24 | iowrite32(value, ioaddr); | ||
| 25 | } | ||
| 26 | |||
| 27 | void tse_clear_bit(void __iomem *ioaddr, u32 bit_mask) | ||
| 28 | { | ||
| 29 | u32 value = ioread32(ioaddr); | ||
| 30 | value &= ~bit_mask; | ||
| 31 | iowrite32(value, ioaddr); | ||
| 32 | } | ||
| 33 | |||
| 34 | int tse_bit_is_set(void __iomem *ioaddr, u32 bit_mask) | ||
| 35 | { | ||
| 36 | u32 value = ioread32(ioaddr); | ||
| 37 | return (value & bit_mask) ? 1 : 0; | ||
| 38 | } | ||
| 39 | |||
| 40 | int tse_bit_is_clear(void __iomem *ioaddr, u32 bit_mask) | ||
| 41 | { | ||
| 42 | u32 value = ioread32(ioaddr); | ||
| 43 | return (value & bit_mask) ? 0 : 1; | ||
| 44 | } | ||
| @@ -0,0 +1,27 @@ | |||
| 1 | /* Altera TSE SGDMA and MSGDMA Linux driver | ||
| 2 | * Copyright (C) 2014 Altera Corporation. All rights reserved | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or modify it | ||
| 5 | * under the terms and conditions of the GNU General Public License, | ||
| 6 | * version 2, as published by the Free Software Foundation. | ||
| 7 | * | ||
| 8 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
| 9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 10 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
| 11 | * more details. | ||
| 12 | * | ||
| 13 | * You should have received a copy of the GNU General Public License along with | ||
| 14 | * this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 15 | */ | ||
| 16 | |||
| 17 | #include <linux/kernel.h> | ||
| 18 | |||
| 19 | #ifndef __ALTERA_UTILS_H__ | ||
| 20 | #define __ALTERA_UTILS_H__ | ||
| 21 | |||
| 22 | void tse_set_bit(void __iomem *ioaddr, u32 bit_mask); | ||
| 23 | void tse_clear_bit(void __iomem *ioaddr, u32 bit_mask); | ||
| 24 | int tse_bit_is_set(void __iomem *ioaddr, u32 bit_mask); | ||
| 25 | int tse_bit_is_clear(void __iomem *ioaddr, u32 bit_mask); | ||
| 26 | |||
| 27 | #endif /* __ALTERA_UTILS_H__*/ | ||
| @@ -578,7 +578,7 @@ int lance_start_xmit(struct sk_buff *skb, struct net_device *dev) · 577 unmodified lines | |||
| 578 | outs++; | 578 | outs++; |
| 579 | /* Kick the lance: transmit now */ | 579 | /* Kick the lance: transmit now */ |
| 580 | WRITERDP(lp, LE_C0_INEA | LE_C0_TDMD); | 580 | WRITERDP(lp, LE_C0_INEA | LE_C0_TDMD); |
| 581 | dev_kfree_skb(skb); | 581 | dev_consume_skb_any(skb); |
| 582 | 582 | ||
| 583 | spin_lock_irqsave(&lp->devlock, flags); | 583 | spin_lock_irqsave(&lp->devlock, flags); |
| 584 | if (TX_BUFFS_AVAIL) | 584 | if (TX_BUFFS_AVAIL) |
| @@ -472,7 +472,7 @@ am79c961_sendpacket(struct sk_buff *skb, struct net_device *dev) · 471 unmodified lines | |||
| 472 | if (am_readword(dev, priv->txhdr + (priv->txhead << 3) + 2) & TMD_OWN) | 472 | if (am_readword(dev, priv->txhdr + (priv->txhead << 3) + 2) & TMD_OWN) |
| 473 | netif_stop_queue(dev); | 473 | netif_stop_queue(dev); |
| 474 | 474 | ||
| 475 | dev_kfree_skb(skb); | 475 | dev_consume_skb_any(skb); |
| 476 | 476 | ||
| 477 | return NETDEV_TX_OK; | 477 | return NETDEV_TX_OK; |
| 478 | } | 478 | } |
| @@ -720,6 +720,9 @@ static int amd8111e_rx_poll(struct napi_struct *napi, int budget) · 719 unmodified lines | |||
| 720 | int rx_pkt_limit = budget; | 720 | int rx_pkt_limit = budget; |
| 721 | unsigned long flags; | 721 | unsigned long flags; |
| 722 | 722 | ||
| 723 | if (rx_pkt_limit <= 0) | ||
| 724 | goto rx_not_empty; | ||
| 725 | |||
| 723 | do{ | 726 | do{ |
| 724 | /* process receive packets until we use the quota*/ | 727 | /* process receive packets until we use the quota*/ |
| 725 | /* If we own the next entry, it's a new packet. Send it up. */ | 728 | /* If we own the next entry, it's a new packet. Send it up. */ |
| @@ -549,35 +549,35 @@ static void pcnet32_realloc_rx_ring(struct net_device *dev, · 548 unmodified lines | |||
| 549 | struct pcnet32_rx_head *new_rx_ring; | 549 | struct pcnet32_rx_head *new_rx_ring; |
| 550 | struct sk_buff **new_skb_list; | 550 | struct sk_buff **new_skb_list; |
| 551 | int new, overlap; | 551 | int new, overlap; |
| 552 | unsigned int entries = 1 << size; | ||
| 552 | 553 | ||
| 553 | new_rx_ring = pci_alloc_consistent(lp->pci_dev, | 554 | new_rx_ring = pci_alloc_consistent(lp->pci_dev, |
| 554 | sizeof(struct pcnet32_rx_head) * | 555 | sizeof(struct pcnet32_rx_head) * |
| 555 | (1 << size), | 556 | entries, |
| 556 | &new_ring_dma_addr); | 557 | &new_ring_dma_addr); |
| 557 | if (new_rx_ring == NULL) { | 558 | if (new_rx_ring == NULL) { |
| 558 | netif_err(lp, drv, dev, "Consistent memory allocation failed\n"); | 559 | netif_err(lp, drv, dev, "Consistent memory allocation failed\n"); |
| 559 | return; | 560 | return; |
| 560 | } | 561 | } |
| 561 | memset(new_rx_ring, 0, sizeof(struct pcnet32_rx_head) * (1 << size)); | 562 | memset(new_rx_ring, 0, sizeof(struct pcnet32_rx_head) * entries); |
| 562 | 563 | ||
| 563 | new_dma_addr_list = kcalloc(1 << size, sizeof(dma_addr_t), GFP_ATOMIC); | 564 | new_dma_addr_list = kcalloc(entries, sizeof(dma_addr_t), GFP_ATOMIC); |
| 564 | if (!new_dma_addr_list) | 565 | if (!new_dma_addr_list) |
| 565 | goto free_new_rx_ring; | 566 | goto free_new_rx_ring; |
| 566 | 567 | ||
| 567 | new_skb_list = kcalloc(1 << size, sizeof(struct sk_buff *), | 568 | new_skb_list = kcalloc(entries, sizeof(struct sk_buff *), GFP_ATOMIC); |
| 568 | GFP_ATOMIC); | ||
| 569 | if (!new_skb_list) | 569 | if (!new_skb_list) |
| 570 | goto free_new_lists; | 570 | goto free_new_lists; |
| 571 | 571 | ||
| 572 | /* first copy the current receive buffers */ | 572 | /* first copy the current receive buffers */ |
| 573 | overlap = min(size, lp->rx_ring_size); | 573 | overlap = min(entries, lp->rx_ring_size); |
| 574 | for (new = 0; new < overlap; new++) { | 574 | for (new = 0; new < overlap; new++) { |
| 575 | new_rx_ring[new] = lp->rx_ring[new]; | 575 | new_rx_ring[new] = lp->rx_ring[new]; |
| 576 | new_dma_addr_list[new] = lp->rx_dma_addr[new]; | 576 | new_dma_addr_list[new] = lp->rx_dma_addr[new]; |
| 577 | new_skb_list[new] = lp->rx_skbuff[new]; | 577 | new_skb_list[new] = lp->rx_skbuff[new]; |
| 578 | } | 578 | } |
| 579 | /* now allocate any new buffers needed */ | 579 | /* now allocate any new buffers needed */ |
| 580 | for (; new < size; new++) { | 580 | for (; new < entries; new++) { |
| 581 | struct sk_buff *rx_skbuff; | 581 | struct sk_buff *rx_skbuff; |
| 582 | new_skb_list[new] = netdev_alloc_skb(dev, PKT_BUF_SKB); | 582 | new_skb_list[new] = netdev_alloc_skb(dev, PKT_BUF_SKB); |
| 583 | rx_skbuff = new_skb_list[new]; | 583 | rx_skbuff = new_skb_list[new]; |
| @@ -592,6 +592,13 @@ static void pcnet32_realloc_rx_ring(struct net_device *dev, · 8 unmodified lines | |||
| 592 | new_dma_addr_list[new] = | 592 | new_dma_addr_list[new] = |
| 593 | pci_map_single(lp->pci_dev, rx_skbuff->data, | 593 | pci_map_single(lp->pci_dev, rx_skbuff->data, |
| 594 | PKT_BUF_SIZE, PCI_DMA_FROMDEVICE); | 594 | PKT_BUF_SIZE, PCI_DMA_FROMDEVICE); |
| 595 | if (pci_dma_mapping_error(lp->pci_dev, | ||
| 596 | new_dma_addr_list[new])) { | ||
| 597 | netif_err(lp, drv, dev, "%s dma mapping failed\n", | ||
| 598 | __func__); | ||
| 599 | dev_kfree_skb(new_skb_list[new]); | ||
| 600 | goto free_all_new; | ||
| 601 | } | ||
| 595 | new_rx_ring[new].base = cpu_to_le32(new_dma_addr_list[new]); | 602 | new_rx_ring[new].base = cpu_to_le32(new_dma_addr_list[new]); |
| 596 | new_rx_ring[new].buf_length = cpu_to_le16(NEG_BUF_SIZE); | 603 | new_rx_ring[new].buf_length = cpu_to_le16(NEG_BUF_SIZE); |
| 597 | new_rx_ring[new].status = cpu_to_le16(0x8000); | 604 | new_rx_ring[new].status = cpu_to_le16(0x8000); |
| @@ -599,8 +606,12 @@ static void pcnet32_realloc_rx_ring(struct net_device *dev, · 1 unmodified line | |||
| 599 | /* and free any unneeded buffers */ | 606 | /* and free any unneeded buffers */ |
| 600 | for (; new < lp->rx_ring_size; new++) { | 607 | for (; new < lp->rx_ring_size; new++) { |
| 601 | if (lp->rx_skbuff[new]) { | 608 | if (lp->rx_skbuff[new]) { |
| 602 | pci_unmap_single(lp->pci_dev, lp->rx_dma_addr[new], | 609 | if (!pci_dma_mapping_error(lp->pci_dev, |
| 603 | PKT_BUF_SIZE, PCI_DMA_FROMDEVICE); | 610 | lp->rx_dma_addr[new])) |
| 611 | pci_unmap_single(lp->pci_dev, | ||
| 612 | lp->rx_dma_addr[new], | ||
| 613 | PKT_BUF_SIZE, | ||
| 614 | PCI_DMA_FROMDEVICE); | ||
| 604 | dev_kfree_skb(lp->rx_skbuff[new]); | 615 | dev_kfree_skb(lp->rx_skbuff[new]); |
| 605 | } | 616 | } |
| 606 | } | 617 | } |
| @@ -612,7 +623,7 @@ static void pcnet32_realloc_rx_ring(struct net_device *dev, · 5 unmodified lines | |||
| 612 | lp->rx_ring_size, lp->rx_ring, | 623 | lp->rx_ring_size, lp->rx_ring, |
| 613 | lp->rx_ring_dma_addr); | 624 | lp->rx_ring_dma_addr); |
| 614 | 625 | ||
| 615 | lp->rx_ring_size = (1 << size); | 626 | lp->rx_ring_size = entries; |
| 616 | lp->rx_mod_mask = lp->rx_ring_size - 1; | 627 | lp->rx_mod_mask = lp->rx_ring_size - 1; |
| 617 | lp->rx_len_bits = (size << 4); | 628 | lp->rx_len_bits = (size << 4); |
| 618 | lp->rx_ring = new_rx_ring; | 629 | lp->rx_ring = new_rx_ring; |
| @@ -624,8 +635,12 @@ static void pcnet32_realloc_rx_ring(struct net_device *dev, · 5 unmodified lines | |||
| 624 | free_all_new: | 635 | free_all_new: |
| 625 | while (--new >= lp->rx_ring_size) { | 636 | while (--new >= lp->rx_ring_size) { |
| 626 | if (new_skb_list[new]) { | 637 | if (new_skb_list[new]) { |
| 627 | pci_unmap_single(lp->pci_dev, new_dma_addr_list[new], | 638 | if (!pci_dma_mapping_error(lp->pci_dev, |
| 628 | PKT_BUF_SIZE, PCI_DMA_FROMDEVICE); | 639 | new_dma_addr_list[new])) |
| 640 | pci_unmap_single(lp->pci_dev, | ||
| 641 | new_dma_addr_list[new], | ||
| 642 | PKT_BUF_SIZE, | ||
| 643 | PCI_DMA_FROMDEVICE); | ||
| 629 | dev_kfree_skb(new_skb_list[new]); | 644 | dev_kfree_skb(new_skb_list[new]); |
| 630 | } | 645 | } |
| 631 | } | 646 | } |
| @@ -634,8 +649,7 @@ free_new_lists: · 2 unmodified lines | |||
| 634 | kfree(new_dma_addr_list); | 649 | kfree(new_dma_addr_list); |
| 635 | free_new_rx_ring: | 650 | free_new_rx_ring: |
| 636 | pci_free_consistent(lp->pci_dev, | 651 | pci_free_consistent(lp->pci_dev, |
| 637 | sizeof(struct pcnet32_rx_head) * | 652 | sizeof(struct pcnet32_rx_head) * entries, |
| 638 | (1 << size), | ||
| 639 | new_rx_ring, | 653 | new_rx_ring, |
| 640 | new_ring_dma_addr); | 654 | new_ring_dma_addr); |
| 641 | } | 655 | } |
| @@ -650,8 +664,12 @@ static void pcnet32_purge_rx_ring(struct net_device *dev) · 8 unmodified lines | |||
| 650 | lp->rx_ring[i].status = 0; /* CPU owns buffer */ | 664 | lp->rx_ring[i].status = 0; /* CPU owns buffer */ |
| 651 | wmb(); /* Make sure adapter sees owner change */ | 665 | wmb(); /* Make sure adapter sees owner change */ |
| 652 | if (lp->rx_skbuff[i]) { | 666 | if (lp->rx_skbuff[i]) { |
| 653 | pci_unmap_single(lp->pci_dev, lp->rx_dma_addr[i], | 667 | if (!pci_dma_mapping_error(lp->pci_dev, |
| 654 | PKT_BUF_SIZE, PCI_DMA_FROMDEVICE); | 668 | lp->rx_dma_addr[i])) |
| 669 | pci_unmap_single(lp->pci_dev, | ||
| 670 | lp->rx_dma_addr[i], | ||
| 671 | PKT_BUF_SIZE, | ||
| 672 | PCI_DMA_FROMDEVICE); | ||
| 655 | dev_kfree_skb_any(lp->rx_skbuff[i]); | 673 | dev_kfree_skb_any(lp->rx_skbuff[i]); |
| 656 | } | 674 | } |
| 657 | lp->rx_skbuff[i] = NULL; | 675 | lp->rx_skbuff[i] = NULL; |
| @@ -930,6 +948,12 @@ static int pcnet32_loopback_test(struct net_device *dev, uint64_t * data1) · 272 unmodified lines | |||
| 930 | lp->tx_dma_addr[x] = | 948 | lp->tx_dma_addr[x] = |
| 931 | pci_map_single(lp->pci_dev, skb->data, skb->len, | 949 | pci_map_single(lp->pci_dev, skb->data, skb->len, |
| 932 | PCI_DMA_TODEVICE); | 950 | PCI_DMA_TODEVICE); |
| 951 | if (pci_dma_mapping_error(lp->pci_dev, lp->tx_dma_addr[x])) { | ||
| 952 | netif_printk(lp, hw, KERN_DEBUG, dev, | ||
| 953 | "DMA mapping error at line: %d!\n", | ||
| 954 | __LINE__); | ||
| 955 | goto clean_up; | ||
| 956 | } | ||
| 933 | lp->tx_ring[x].base = cpu_to_le32(lp->tx_dma_addr[x]); | 957 | lp->tx_ring[x].base = cpu_to_le32(lp->tx_dma_addr[x]); |
| 934 | wmb(); /* Make sure owner changes after all others are visible */ | 958 | wmb(); /* Make sure owner changes after all others are visible */ |
| 935 | lp->tx_ring[x].status = cpu_to_le16(status); | 959 | lp->tx_ring[x].status = cpu_to_le16(status); |
| @@ -1142,24 +1166,36 @@ static void pcnet32_rx_entry(struct net_device *dev, · 206 unmodified lines | |||
| 1142 | 1166 | ||
| 1143 | if (pkt_len > rx_copybreak) { | 1167 | if (pkt_len > rx_copybreak) { |
| 1144 | struct sk_buff *newskb; | 1168 | struct sk_buff *newskb; |
| 1169 | dma_addr_t new_dma_addr; | ||
| 1145 | 1170 | ||
| 1146 | newskb = netdev_alloc_skb(dev, PKT_BUF_SKB); | 1171 | newskb = netdev_alloc_skb(dev, PKT_BUF_SKB); |
| 1172 | /* | ||
| 1173 | * map the new buffer, if mapping fails, drop the packet and | ||
| 1174 | * reuse the old buffer | ||
| 1175 | */ | ||
| 1147 | if (newskb) { | 1176 | if (newskb) { |
| 1148 | skb_reserve(newskb, NET_IP_ALIGN); | 1177 | skb_reserve(newskb, NET_IP_ALIGN); |
| 1149 | skb = lp->rx_skbuff[entry]; | 1178 | new_dma_addr = pci_map_single(lp->pci_dev, |
| 1150 | pci_unmap_single(lp->pci_dev, | 1179 | newskb->data, |
| 1151 | lp->rx_dma_addr[entry], | 1180 | PKT_BUF_SIZE, |
| 1152 | PKT_BUF_SIZE, | 1181 | PCI_DMA_FROMDEVICE); |
| 1153 | PCI_DMA_FROMDEVICE); | 1182 | if (pci_dma_mapping_error(lp->pci_dev, new_dma_addr)) { |
| 1154 | skb_put(skb, pkt_len); | 1183 | netif_err(lp, rx_err, dev, |
| 1155 | lp->rx_skbuff[entry] = newskb; | 1184 | "DMA mapping error.\n"); |
| 1156 | lp->rx_dma_addr[entry] = | 1185 | dev_kfree_skb(newskb); |
| 1157 | pci_map_single(lp->pci_dev, | 1186 | skb = NULL; |
| 1158 | newskb->data, | 1187 | } else { |
| 1159 | PKT_BUF_SIZE, | 1188 | skb = lp->rx_skbuff[entry]; |
| 1160 | PCI_DMA_FROMDEVICE); | 1189 | pci_unmap_single(lp->pci_dev, |
| 1161 | rxp->base = cpu_to_le32(lp->rx_dma_addr[entry]); | 1190 | lp->rx_dma_addr[entry], |
| 1162 | rx_in_place = 1; | 1191 | PKT_BUF_SIZE, |
| 1192 | PCI_DMA_FROMDEVICE); | ||
| 1193 | skb_put(skb, pkt_len); | ||
| 1194 | lp->rx_skbuff[entry] = newskb; | ||
| 1195 | lp->rx_dma_addr[entry] = new_dma_addr; | ||
| 1196 | rxp->base = cpu_to_le32(new_dma_addr); | ||
| 1197 | rx_in_place = 1; | ||
| 1198 | } | ||
| 1163 | } else | 1199 | } else |
| 1164 | skb = NULL; | 1200 | skb = NULL; |
| 1165 | } else | 1201 | } else |
| @@ -2229,9 +2265,12 @@ static void pcnet32_purge_tx_ring(struct net_device *dev) · 1063 unmodified lines | |||
| 2229 | lp->tx_ring[i].status = 0; /* CPU owns buffer */ | 2265 | lp->tx_ring[i].status = 0; /* CPU owns buffer */ |
| 2230 | wmb(); /* Make sure adapter sees owner change */ | 2266 | wmb(); /* Make sure adapter sees owner change */ |
| 2231 | if (lp->tx_skbuff[i]) { | 2267 | if (lp->tx_skbuff[i]) { |
| 2232 | pci_unmap_single(lp->pci_dev, lp->tx_dma_addr[i], | 2268 | if (!pci_dma_mapping_error(lp->pci_dev, |
| 2233 | lp->tx_skbuff[i]->len, | 2269 | lp->tx_dma_addr[i])) |
| 2234 | PCI_DMA_TODEVICE); | 2270 | pci_unmap_single(lp->pci_dev, |
| 2271 | lp->tx_dma_addr[i], | ||
| 2272 | lp->tx_skbuff[i]->len, | ||
| 2273 | PCI_DMA_TODEVICE); | ||
| 2235 | dev_kfree_skb_any(lp->tx_skbuff[i]); | 2274 | dev_kfree_skb_any(lp->tx_skbuff[i]); |
| 2236 | } | 2275 | } |
| 2237 | lp->tx_skbuff[i] = NULL; | 2276 | lp->tx_skbuff[i] = NULL; |
| @@ -2264,10 +2303,19 @@ static int pcnet32_init_ring(struct net_device *dev) · 26 unmodified lines | |||
| 2264 | } | 2303 | } |
| 2265 | 2304 | ||
| 2266 | rmb(); | 2305 | rmb(); |
| 2267 | if (lp->rx_dma_addr[i] == 0) | 2306 | if (lp->rx_dma_addr[i] == 0) { |
| 2268 | lp->rx_dma_addr[i] = | 2307 | lp->rx_dma_addr[i] = |
| 2269 | pci_map_single(lp->pci_dev, rx_skbuff->data, | 2308 | pci_map_single(lp->pci_dev, rx_skbuff->data, |
| 2270 | PKT_BUF_SIZE, PCI_DMA_FROMDEVICE); | 2309 | PKT_BUF_SIZE, PCI_DMA_FROMDEVICE); |
| 2310 | if (pci_dma_mapping_error(lp->pci_dev, | ||
| 2311 | lp->rx_dma_addr[i])) { | ||
| 2312 | /* there is not much we can do at this point */ | ||
| 2313 | netif_err(lp, drv, dev, | ||
| 2314 | "%s pci dma mapping error\n", | ||
| 2315 | __func__); | ||
| 2316 | return -1; | ||
| 2317 | } | ||
| 2318 | } | ||
| 2271 | lp->rx_ring[i].base = cpu_to_le32(lp->rx_dma_addr[i]); | 2319 | lp->rx_ring[i].base = cpu_to_le32(lp->rx_dma_addr[i]); |
| 2272 | lp->rx_ring[i].buf_length = cpu_to_le16(NEG_BUF_SIZE); | 2320 | lp->rx_ring[i].buf_length = cpu_to_le16(NEG_BUF_SIZE); |
| 2273 | wmb(); /* Make sure owner changes after all others are visible */ | 2321 | wmb(); /* Make sure owner changes after all others are visible */ |
| @@ -2397,9 +2445,14 @@ static netdev_tx_t pcnet32_start_xmit(struct sk_buff *skb, · 123 unmodified lines | |||
| 2397 | 2445 | ||
| 2398 | lp->tx_ring[entry].misc = 0x00000000; | 2446 | lp->tx_ring[entry].misc = 0x00000000; |
| 2399 | 2447 | ||
| 2400 | lp->tx_skbuff[entry] = skb; | ||
| 2401 | lp->tx_dma_addr[entry] = | 2448 | lp->tx_dma_addr[entry] = |
| 2402 | pci_map_single(lp->pci_dev, skb->data, skb->len, PCI_DMA_TODEVICE); | 2449 | pci_map_single(lp->pci_dev, skb->data, skb->len, PCI_DMA_TODEVICE); |
| 2450 | if (pci_dma_mapping_error(lp->pci_dev, lp->tx_dma_addr[entry])) { | ||
| 2451 | dev_kfree_skb_any(skb); | ||
| 2452 | dev->stats.tx_dropped++; | ||
| 2453 | goto drop_packet; | ||
| 2454 | } | ||
| 2455 | lp->tx_skbuff[entry] = skb; | ||
| 2403 | lp->tx_ring[entry].base = cpu_to_le32(lp->tx_dma_addr[entry]); | 2456 | lp->tx_ring[entry].base = cpu_to_le32(lp->tx_dma_addr[entry]); |
| 2404 | wmb(); /* Make sure owner changes after all others are visible */ | 2457 | wmb(); /* Make sure owner changes after all others are visible */ |
| 2405 | lp->tx_ring[entry].status = cpu_to_le16(status); | 2458 | lp->tx_ring[entry].status = cpu_to_le16(status); |
| @@ -2414,6 +2467,7 @@ static netdev_tx_t pcnet32_start_xmit(struct sk_buff *skb, · 8 unmodified lines | |||
| 2414 | lp->tx_full = 1; | 2467 | lp->tx_full = 1; |
| 2415 | netif_stop_queue(dev); | 2468 | netif_stop_queue(dev); |
| 2416 | } | 2469 | } |
| 2470 | drop_packet: | ||
| 2417 | spin_unlock_irqrestore(&lp->lock, flags); | 2471 | spin_unlock_irqrestore(&lp->lock, flags); |
| 2418 | return NETDEV_TX_OK; | 2472 | return NETDEV_TX_OK; |
| 2419 | } | 2473 | } |
| @@ -535,7 +535,7 @@ static int alx_alloc_descriptors(struct alx_priv *alx) · 534 unmodified lines | |||
| 535 | if (!alx->descmem.virt) | 535 | if (!alx->descmem.virt) |
| 536 | goto out_free; | 536 | goto out_free; |
| 537 | 537 | ||
| 538 | alx->txq.tpd = (void *)alx->descmem.virt; | 538 | alx->txq.tpd = alx->descmem.virt; |
| 539 | alx->txq.tpd_dma = alx->descmem.dma; | 539 | alx->txq.tpd_dma = alx->descmem.dma; |
| 540 | 540 | ||
| 541 | /* alignment requirement for next block */ | 541 | /* alignment requirement for next block */ |
| @@ -1097,7 +1097,7 @@ static netdev_tx_t alx_start_xmit(struct sk_buff *skb, · 555 unmodified lines | |||
| 1097 | return NETDEV_TX_OK; | 1097 | return NETDEV_TX_OK; |
| 1098 | 1098 | ||
| 1099 | drop: | 1099 | drop: |
| 1100 | dev_kfree_skb(skb); | 1100 | dev_kfree_skb_any(skb); |
| 1101 | return NETDEV_TX_OK; | 1101 | return NETDEV_TX_OK; |
| 1102 | } | 1102 | } |
| 1103 | 1103 | ||
| @@ -832,7 +832,7 @@ static int atl1c_sw_init(struct atl1c_adapter *adapter) · 831 unmodified lines | |||
| 832 | } | 832 | } |
| 833 | 833 | ||
| 834 | static inline void atl1c_clean_buffer(struct pci_dev *pdev, | 834 | static inline void atl1c_clean_buffer(struct pci_dev *pdev, |
| 835 | struct atl1c_buffer *buffer_info, int in_irq) | 835 | struct atl1c_buffer *buffer_info) |
| 836 | { | 836 | { |
| 837 | u16 pci_driection; | 837 | u16 pci_driection; |
| 838 | if (buffer_info->flags & ATL1C_BUFFER_FREE) | 838 | if (buffer_info->flags & ATL1C_BUFFER_FREE) |
| @@ -850,12 +850,8 @@ static inline void atl1c_clean_buffer(struct pci_dev *pdev, · 11 unmodified lines | |||
| 850 | pci_unmap_page(pdev, buffer_info->dma, | 850 | pci_unmap_page(pdev, buffer_info->dma, |
| 851 | buffer_info->length, pci_driection); | 851 | buffer_info->length, pci_driection); |
| 852 | } | 852 | } |
| 853 | if (buffer_info->skb) { | 853 | if (buffer_info->skb) |
| 854 | if (in_irq) | 854 | dev_consume_skb_any(buffer_info->skb); |
| 855 | dev_kfree_skb_irq(buffer_info->skb); | ||
| 856 | else | ||
| 857 | dev_kfree_skb(buffer_info->skb); | ||
| 858 | } | ||
| 859 | buffer_info->dma = 0; | 855 | buffer_info->dma = 0; |
| 860 | buffer_info->skb = NULL; | 856 | buffer_info->skb = NULL; |
| 861 | ATL1C_SET_BUFFER_STATE(buffer_info, ATL1C_BUFFER_FREE); | 857 | ATL1C_SET_BUFFER_STATE(buffer_info, ATL1C_BUFFER_FREE); |
| @@ -875,7 +871,7 @@ static void atl1c_clean_tx_ring(struct atl1c_adapter *adapter, · 13 unmodified lines | |||
| 875 | ring_count = tpd_ring->count; | 871 | ring_count = tpd_ring->count; |
| 876 | for (index = 0; index < ring_count; index++) { | 872 | for (index = 0; index < ring_count; index++) { |
| 877 | buffer_info = &tpd_ring->buffer_info[index]; | 873 | buffer_info = &tpd_ring->buffer_info[index]; |
| 878 | atl1c_clean_buffer(pdev, buffer_info, 0); | 874 | atl1c_clean_buffer(pdev, buffer_info); |
| 879 | } | 875 | } |
| 880 | 876 | ||
| 881 | /* Zero out Tx-buffers */ | 877 | /* Zero out Tx-buffers */ |
| @@ -899,7 +895,7 @@ static void atl1c_clean_rx_ring(struct atl1c_adapter *adapter) · 17 unmodified lines | |||
| 899 | 895 | ||
| 900 | for (j = 0; j < rfd_ring->count; j++) { | 896 | for (j = 0; j < rfd_ring->count; j++) { |
| 901 | buffer_info = &rfd_ring->buffer_info[j]; | 897 | buffer_info = &rfd_ring->buffer_info[j]; |
| 902 | atl1c_clean_buffer(pdev, buffer_info, 0); | 898 | atl1c_clean_buffer(pdev, buffer_info); |
| 903 | } | 899 | } |
| 904 | /* zero out the descriptor ring */ | 900 | /* zero out the descriptor ring */ |
| 905 | memset(rfd_ring->desc, 0, rfd_ring->size); | 901 | memset(rfd_ring->desc, 0, rfd_ring->size); |
| @@ -1562,7 +1558,7 @@ static bool atl1c_clean_tx_irq(struct atl1c_adapter *adapter, · 656 unmodified lines | |||
| 1562 | 1558 | ||
| 1563 | while (next_to_clean != hw_next_to_clean) { | 1559 | while (next_to_clean != hw_next_to_clean) { |
| 1564 | buffer_info = &tpd_ring->buffer_info[next_to_clean]; | 1560 | buffer_info = &tpd_ring->buffer_info[next_to_clean]; |
| 1565 | atl1c_clean_buffer(pdev, buffer_info, 1); | 1561 | atl1c_clean_buffer(pdev, buffer_info); |
| 1566 | if (++next_to_clean == tpd_ring->count) | 1562 | if (++next_to_clean == tpd_ring->count) |
| 1567 | next_to_clean = 0; | 1563 | next_to_clean = 0; |
| 1568 | atomic_set(&tpd_ring->next_to_clean, next_to_clean); | 1564 | atomic_set(&tpd_ring->next_to_clean, next_to_clean); |
| @@ -1977,17 +1973,17 @@ static int atl1c_tso_csum(struct atl1c_adapter *adapter, · 408 unmodified lines | |||
| 1977 | enum atl1c_trans_queue type) | 1973 | enum atl1c_trans_queue type) |
| 1978 | { | 1974 | { |
| 1979 | struct pci_dev *pdev = adapter->pdev; | 1975 | struct pci_dev *pdev = adapter->pdev; |
| 1976 | unsigned short offload_type; | ||
| 1980 | u8 hdr_len; | 1977 | u8 hdr_len; |
| 1981 | u32 real_len; | 1978 | u32 real_len; |
| 1982 | unsigned short offload_type; | ||
| 1983 | int err; | ||
| 1984 | 1979 | ||
| 1985 | if (skb_is_gso(skb)) { | 1980 | if (skb_is_gso(skb)) { |
| 1986 | if (skb_header_cloned(skb)) { | 1981 | int err; |
| 1987 | err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC); | 1982 | |
| 1988 | if (unlikely(err)) | 1983 | err = skb_cow_head(skb, 0); |
| 1989 | return -1; | 1984 | if (err < 0) |
| 1990 | } | 1985 | return err; |
| 1986 | |||
| 1991 | offload_type = skb_shinfo(skb)->gso_type; | 1987 | offload_type = skb_shinfo(skb)->gso_type; |
| 1992 | 1988 | ||
| 1993 | if (offload_type & SKB_GSO_TCPV4) { | 1989 | if (offload_type & SKB_GSO_TCPV4) { |
| @@ -2085,7 +2081,7 @@ static void atl1c_tx_rollback(struct atl1c_adapter *adpt, · 91 unmodified lines | |||
| 2085 | while (index != tpd_ring->next_to_use) { | 2081 | while (index != tpd_ring->next_to_use) { |
| 2086 | tpd = ATL1C_TPD_DESC(tpd_ring, index); | 2082 | tpd = ATL1C_TPD_DESC(tpd_ring, index); |
| 2087 | buffer_info = &tpd_ring->buffer_info[index]; | 2083 | buffer_info = &tpd_ring->buffer_info[index]; |
| 2088 | atl1c_clean_buffer(adpt->pdev, buffer_info, 0); | 2084 | atl1c_clean_buffer(adpt->pdev, buffer_info); |
| 2089 | memset(tpd, 0, sizeof(struct atl1c_tpd_desc)); | 2085 | memset(tpd, 0, sizeof(struct atl1c_tpd_desc)); |
| 2090 | if (++index == tpd_ring->count) | 2086 | if (++index == tpd_ring->count) |
| 2091 | index = 0; | 2087 | index = 0; |
| @@ -2258,7 +2254,7 @@ static netdev_tx_t atl1c_xmit_frame(struct sk_buff *skb, · 166 unmodified lines | |||
| 2258 | /* roll back tpd/buffer */ | 2254 | /* roll back tpd/buffer */ |
| 2259 | atl1c_tx_rollback(adapter, tpd, type); | 2255 | atl1c_tx_rollback(adapter, tpd, type); |
| 2260 | spin_unlock_irqrestore(&adapter->tx_lock, flags); | 2256 | spin_unlock_irqrestore(&adapter->tx_lock, flags); |
| 2261 | dev_kfree_skb(skb); | 2257 | dev_kfree_skb_any(skb); |
| 2262 | } else { | 2258 | } else { |
| 2263 | atl1c_tx_queue(adapter, skb, tpd, type); | 2259 | atl1c_tx_queue(adapter, skb, tpd, type); |
| 2264 | spin_unlock_irqrestore(&adapter->tx_lock, flags); | 2260 | spin_unlock_irqrestore(&adapter->tx_lock, flags); |
| @@ -1641,17 +1641,17 @@ static u16 atl1e_cal_tdp_req(const struct sk_buff *skb) · 1640 unmodified lines | |||
| 1641 | static int atl1e_tso_csum(struct atl1e_adapter *adapter, | 1641 | static int atl1e_tso_csum(struct atl1e_adapter *adapter, |
| 1642 | struct sk_buff *skb, struct atl1e_tpd_desc *tpd) | 1642 | struct sk_buff *skb, struct atl1e_tpd_desc *tpd) |
| 1643 | { | 1643 | { |
| 1644 | unsigned short offload_type; | ||
| 1644 | u8 hdr_len; | 1645 | u8 hdr_len; |
| 1645 | u32 real_len; | 1646 | u32 real_len; |
| 1646 | unsigned short offload_type; | ||
| 1647 | int err; | ||
| 1648 | 1647 | ||
| 1649 | if (skb_is_gso(skb)) { | 1648 | if (skb_is_gso(skb)) { |
| 1650 | if (skb_header_cloned(skb)) { | 1649 | int err; |
| 1651 | err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC); | 1650 | |
| 1652 | if (unlikely(err)) | 1651 | err = skb_cow_head(skb, 0); |
| 1653 | return -1; | 1652 | if (err < 0) |
| 1654 | } | 1653 | return err; |
| 1654 | |||
| 1655 | offload_type = skb_shinfo(skb)->gso_type; | 1655 | offload_type = skb_shinfo(skb)->gso_type; |
| 1656 | 1656 | ||
| 1657 | if (offload_type & SKB_GSO_TCPV4) { | 1657 | if (offload_type & SKB_GSO_TCPV4) { |
| @@ -2118,18 +2118,17 @@ static u16 atl1_tpd_avail(struct atl1_tpd_ring *tpd_ring) · 2117 unmodified lines | |||
| 2118 | } | 2118 | } |
| 2119 | 2119 | ||
| 2120 | static int atl1_tso(struct atl1_adapter *adapter, struct sk_buff *skb, | 2120 | static int atl1_tso(struct atl1_adapter *adapter, struct sk_buff *skb, |
| 2121 | struct tx_packet_desc *ptpd) | 2121 | struct tx_packet_desc *ptpd) |
| 2122 | { | 2122 | { |
| 2123 | u8 hdr_len, ip_off; | 2123 | u8 hdr_len, ip_off; |
| 2124 | u32 real_len; | 2124 | u32 real_len; |
| 2125 | int err; | ||
| 2126 | 2125 | ||
| 2127 | if (skb_shinfo(skb)->gso_size) { | 2126 | if (skb_shinfo(skb)->gso_size) { |
| 2128 | if (skb_header_cloned(skb)) { | 2127 | int err; |
| 2129 | err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC); | 2128 | |
| 2130 | if (unlikely(err)) | 2129 | err = skb_cow_head(skb, 0); |
| 2131 | return -1; | 2130 | if (err < 0) |
| 2132 | } | 2131 | return err; |
| 2133 | 2132 | ||
| 2134 | if (skb->protocol == htons(ETH_P_IP)) { | 2133 | if (skb->protocol == htons(ETH_P_IP)) { |
| 2135 | struct iphdr *iph = ip_hdr(skb); | 2134 | struct iphdr *iph = ip_hdr(skb); |
| @@ -2175,7 +2174,7 @@ static int atl1_tso(struct atl1_adapter *adapter, struct sk_buff *skb, · 39 unmodified lines | |||
| 2175 | return 3; | 2174 | return 3; |
| 2176 | } | 2175 | } |
| 2177 | } | 2176 | } |
| 2178 | return false; | 2177 | return 0; |
| 2179 | } | 2178 | } |
| 2180 | 2179 | ||
| 2181 | static int atl1_tx_csum(struct atl1_adapter *adapter, struct sk_buff *skb, | 2180 | static int atl1_tx_csum(struct atl1_adapter *adapter, struct sk_buff *skb, |
| @@ -55,6 +55,7 @@ static const char atl2_driver_name[] = "atl2"; · 54 unmodified lines | |||
| 55 | static const char atl2_driver_string[] = "Atheros(R) L2 Ethernet Driver"; | 55 | static const char atl2_driver_string[] = "Atheros(R) L2 Ethernet Driver"; |
| 56 | static const char atl2_copyright[] = "Copyright (c) 2007 Atheros Corporation."; | 56 | static const char atl2_copyright[] = "Copyright (c) 2007 Atheros Corporation."; |
| 57 | static const char atl2_driver_version[] = ATL2_DRV_VERSION; | 57 | static const char atl2_driver_version[] = ATL2_DRV_VERSION; |
| 58 | static const struct ethtool_ops atl2_ethtool_ops; | ||
| 58 | 59 | ||
| 59 | MODULE_AUTHOR("Atheros Corporation <xiong.huang@atheros.com>, Chris Snook <csnook@redhat.com>"); | 60 | MODULE_AUTHOR("Atheros Corporation <xiong.huang@atheros.com>, Chris Snook <csnook@redhat.com>"); |
| 60 | MODULE_DESCRIPTION("Atheros Fast Ethernet Network Driver"); | 61 | MODULE_DESCRIPTION("Atheros Fast Ethernet Network Driver"); |
| @@ -71,8 +72,6 @@ static DEFINE_PCI_DEVICE_TABLE(atl2_pci_tbl) = { · 10 unmodified lines | |||
| 71 | }; | 72 | }; |
| 72 | MODULE_DEVICE_TABLE(pci, atl2_pci_tbl); | 73 | MODULE_DEVICE_TABLE(pci, atl2_pci_tbl); |
| 73 | 74 | ||
| 74 | static void atl2_set_ethtool_ops(struct net_device *netdev); | ||
| 75 | |||
| 76 | static void atl2_check_options(struct atl2_adapter *adapter); | 75 | static void atl2_check_options(struct atl2_adapter *adapter); |
| 77 | 76 | ||
| 78 | /** | 77 | /** |
| @@ -1397,7 +1396,7 @@ static int atl2_probe(struct pci_dev *pdev, const struct pci_device_id *ent) · 1318 unmodified lines | |||
| 1397 | atl2_setup_pcicmd(pdev); | 1396 | atl2_setup_pcicmd(pdev); |
| 1398 | 1397 | ||
| 1399 | netdev->netdev_ops = &atl2_netdev_ops; | 1398 | netdev->netdev_ops = &atl2_netdev_ops; |
| 1400 | atl2_set_ethtool_ops(netdev); | 1399 | SET_ETHTOOL_OPS(netdev, &atl2_ethtool_ops); |
| 1401 | netdev->watchdog_timeo = 5 * HZ; | 1400 | netdev->watchdog_timeo = 5 * HZ; |
| 1402 | strncpy(netdev->name, pci_name(pdev), sizeof(netdev->name) - 1); | 1401 | strncpy(netdev->name, pci_name(pdev), sizeof(netdev->name) - 1); |
| 1403 | 1402 | ||
| @@ -2105,11 +2104,6 @@ static const struct ethtool_ops atl2_ethtool_ops = { · 701 unmodified lines | |||
| 2105 | .set_eeprom = atl2_set_eeprom, | 2104 | .set_eeprom = atl2_set_eeprom, |
| 2106 | }; | 2105 | }; |
| 2107 | 2106 | ||
| 2108 | static void atl2_set_ethtool_ops(struct net_device *netdev) | ||
| 2109 | { | ||
| 2110 | SET_ETHTOOL_OPS(netdev, &atl2_ethtool_ops); | ||
| 2111 | } | ||
| 2112 | |||
| 2113 | #define LBYTESWAP(a) ((((a) & 0x00ff00ff) << 8) | \ | 2107 | #define LBYTESWAP(a) ((((a) & 0x00ff00ff) << 8) | \ |
| 2114 | (((a) & 0xff00ff00) >> 8)) | 2108 | (((a) & 0xff00ff00) >> 8)) |
| 2115 | #define LONGSWAP(a) ((LBYTESWAP(a) << 16) | (LBYTESWAP(a) >> 16)) | 2109 | #define LONGSWAP(a) ((LBYTESWAP(a) << 16) | (LBYTESWAP(a) >> 16)) |
| @@ -60,6 +60,17 @@ config BCM63XX_ENET · 59 unmodified lines | |||
| 60 | This driver supports the ethernet MACs in the Broadcom 63xx | 60 | This driver supports the ethernet MACs in the Broadcom 63xx |
| 61 | MIPS chipset family (BCM63XX). | 61 | MIPS chipset family (BCM63XX). |
| 62 | 62 | ||
| 63 | config BCMGENET | ||
| 64 | tristate "Broadcom GENET internal MAC support" | ||
| 65 | depends on OF | ||
| 66 | select MII | ||
| 67 | select PHYLIB | ||
| 68 | select FIXED_PHY if BCMGENET=y | ||
| 69 | select BCM7XXX_PHY | ||
| 70 | help | ||
| 71 | This driver supports the built-in Ethernet MACs found in the | ||
| 72 | Broadcom BCM7xxx Set Top Box family chipset. | ||
| 73 | |||
| 63 | config BNX2 | 74 | config BNX2 |
| 64 | tristate "Broadcom NetXtremeII support" | 75 | tristate "Broadcom NetXtremeII support" |
| 65 | depends on PCI | 76 | depends on PCI |
| @@ -4,6 +4,7 @@ · 3 unmodified lines | |||
| 4 | 4 | ||
| 5 | obj-$(CONFIG_B44) += b44.o | 5 | obj-$(CONFIG_B44) += b44.o |
| 6 | obj-$(CONFIG_BCM63XX_ENET) += bcm63xx_enet.o | 6 | obj-$(CONFIG_BCM63XX_ENET) += bcm63xx_enet.o |
| 7 | obj-$(CONFIG_BCMGENET) += genet/ | ||
| 7 | obj-$(CONFIG_BNX2) += bnx2.o | 8 | obj-$(CONFIG_BNX2) += bnx2.o |
| 8 | obj-$(CONFIG_CNIC) += cnic.o | 9 | obj-$(CONFIG_CNIC) += cnic.o |
| 9 | obj-$(CONFIG_BNX2X) += bnx2x/ | 10 | obj-$(CONFIG_BNX2X) += bnx2x/ |
| @@ -1685,7 +1685,7 @@ static struct rtnl_link_stats64 *b44_get_stats64(struct net_device *dev, · 1684 unmodified lines | |||
| 1685 | unsigned int start; | 1685 | unsigned int start; |
| 1686 | 1686 | ||
| 1687 | do { | 1687 | do { |
| 1688 | start = u64_stats_fetch_begin_bh(&hwstat->syncp); | 1688 | start = u64_stats_fetch_begin_irq(&hwstat->syncp); |
| 1689 | 1689 | ||
| 1690 | /* Convert HW stats into rtnl_link_stats64 stats. */ | 1690 | /* Convert HW stats into rtnl_link_stats64 stats. */ |
| 1691 | nstat->rx_packets = hwstat->rx_pkts; | 1691 | nstat->rx_packets = hwstat->rx_pkts; |
| @@ -1719,7 +1719,7 @@ static struct rtnl_link_stats64 *b44_get_stats64(struct net_device *dev, · 27 unmodified lines | |||
| 1719 | /* Carrier lost counter seems to be broken for some devices */ | 1719 | /* Carrier lost counter seems to be broken for some devices */ |
| 1720 | nstat->tx_carrier_errors = hwstat->tx_carrier_lost; | 1720 | nstat->tx_carrier_errors = hwstat->tx_carrier_lost; |
| 1721 | #endif | 1721 | #endif |
| 1722 | } while (u64_stats_fetch_retry_bh(&hwstat->syncp, start)); | 1722 | } while (u64_stats_fetch_retry_irq(&hwstat->syncp, start)); |
| 1723 | 1723 | ||
| 1724 | return nstat; | 1724 | return nstat; |
| 1725 | } | 1725 | } |
| @@ -2073,12 +2073,12 @@ static void b44_get_ethtool_stats(struct net_device *dev, · 347 unmodified lines | |||
| 2073 | do { | 2073 | do { |
| 2074 | data_src = &hwstat->tx_good_octets; | 2074 | data_src = &hwstat->tx_good_octets; |
| 2075 | data_dst = data; | 2075 | data_dst = data; |
| 2076 | start = u64_stats_fetch_begin_bh(&hwstat->syncp); | 2076 | start = u64_stats_fetch_begin_irq(&hwstat->syncp); |
| 2077 | 2077 | ||
| 2078 | for (i = 0; i < ARRAY_SIZE(b44_gstrings); i++) | 2078 | for (i = 0; i < ARRAY_SIZE(b44_gstrings); i++) |
| 2079 | *data_dst++ = *data_src++; | 2079 | *data_dst++ = *data_src++; |
| 2080 | 2080 | ||
| 2081 | } while (u64_stats_fetch_retry_bh(&hwstat->syncp, start)); | 2081 | } while (u64_stats_fetch_retry_irq(&hwstat->syncp, start)); |
| 2082 | } | 2082 | } |
| 2083 | 2083 | ||
| 2084 | static void b44_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) | 2084 | static void b44_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) |
| @@ -1722,9 +1722,6 @@ static const struct net_device_ops bcm_enet_ops = { · 1721 unmodified lines | |||
| 1722 | .ndo_set_rx_mode = bcm_enet_set_multicast_list, | 1722 | .ndo_set_rx_mode = bcm_enet_set_multicast_list, |
| 1723 | .ndo_do_ioctl = bcm_enet_ioctl, | 1723 | .ndo_do_ioctl = bcm_enet_ioctl, |
| 1724 | .ndo_change_mtu = bcm_enet_change_mtu, | 1724 | .ndo_change_mtu = bcm_enet_change_mtu, |
| 1725 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
| 1726 | .ndo_poll_controller = bcm_enet_netpoll, | ||
| 1727 | #endif | ||
| 1728 | }; | 1725 | }; |
| 1729 | 1726 | ||
| 1730 | /* | 1727 | /* |
| @@ -2886,7 +2886,7 @@ bnx2_tx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget) · 2885 unmodified lines | |||
| 2886 | sw_cons = BNX2_NEXT_TX_BD(sw_cons); | 2886 | sw_cons = BNX2_NEXT_TX_BD(sw_cons); |
| 2887 | 2887 | ||
| 2888 | tx_bytes += skb->len; | 2888 | tx_bytes += skb->len; |
| 2889 | dev_kfree_skb(skb); | 2889 | dev_kfree_skb_any(skb); |
| 2890 | tx_pkt++; | 2890 | tx_pkt++; |
| 2891 | if (tx_pkt == budget) | 2891 | if (tx_pkt == budget) |
| 2892 | break; | 2892 | break; |
| @@ -3133,6 +3133,9 @@ bnx2_rx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget) · 240 unmodified lines | |||
| 3133 | struct l2_fhdr *rx_hdr; | 3133 | struct l2_fhdr *rx_hdr; |
| 3134 | int rx_pkt = 0, pg_ring_used = 0; | 3134 | int rx_pkt = 0, pg_ring_used = 0; |
| 3135 | 3135 | ||
| 3136 | if (budget <= 0) | ||
| 3137 | return rx_pkt; | ||
| 3138 | |||
| 3136 | hw_cons = bnx2_get_hw_rx_cons(bnapi); | 3139 | hw_cons = bnx2_get_hw_rx_cons(bnapi); |
| 3137 | sw_cons = rxr->rx_cons; | 3140 | sw_cons = rxr->rx_cons; |
| 3138 | sw_prod = rxr->rx_prod; | 3141 | sw_prod = rxr->rx_prod; |
| @@ -6235,7 +6238,7 @@ bnx2_free_irq(struct bnx2 *bp) · 3096 unmodified lines | |||
| 6235 | static void | 6238 | static void |
| 6236 | bnx2_enable_msix(struct bnx2 *bp, int msix_vecs) | 6239 | bnx2_enable_msix(struct bnx2 *bp, int msix_vecs) |
| 6237 | { | 6240 | { |
| 6238 | int i, total_vecs, rc; | 6241 | int i, total_vecs; |
| 6239 | struct msix_entry msix_ent[BNX2_MAX_MSIX_VEC]; | 6242 | struct msix_entry msix_ent[BNX2_MAX_MSIX_VEC]; |
| 6240 | struct net_device *dev = bp->dev; | 6243 | struct net_device *dev = bp->dev; |
| 6241 | const int len = sizeof(bp->irq_tbl[0].name); | 6244 | const int len = sizeof(bp->irq_tbl[0].name); |
| @@ -6258,16 +6261,9 @@ bnx2_enable_msix(struct bnx2 *bp, int msix_vecs) · 16 unmodified lines | |||
| 6258 | #ifdef BCM_CNIC | 6261 | #ifdef BCM_CNIC |
| 6259 | total_vecs++; | 6262 | total_vecs++; |
| 6260 | #endif | 6263 | #endif |
| 6261 | rc = -ENOSPC; | 6264 | total_vecs = pci_enable_msix_range(bp->pdev, msix_ent, |
| 6262 | while (total_vecs >= BNX2_MIN_MSIX_VEC) { | 6265 | BNX2_MIN_MSIX_VEC, total_vecs); |
| 6263 | rc = pci_enable_msix(bp->pdev, msix_ent, total_vecs); | 6266 | if (total_vecs < 0) |
| 6264 | if (rc <= 0) | ||
| 6265 | break; | ||
| 6266 | if (rc > 0) | ||
| 6267 | total_vecs = rc; | ||
| 6268 | } | ||
| 6269 | |||
| 6270 | if (rc != 0) | ||
| 6271 | return; | 6267 | return; |
| 6272 | 6268 | ||
| 6273 | msix_vecs = total_vecs; | 6269 | msix_vecs = total_vecs; |
| @@ -6640,7 +6636,7 @@ bnx2_start_xmit(struct sk_buff *skb, struct net_device *dev) · 366 unmodified lines | |||
| 6640 | 6636 | ||
| 6641 | mapping = dma_map_single(&bp->pdev->dev, skb->data, len, PCI_DMA_TODEVICE); | 6637 | mapping = dma_map_single(&bp->pdev->dev, skb->data, len, PCI_DMA_TODEVICE); |
| 6642 | if (dma_mapping_error(&bp->pdev->dev, mapping)) { | 6638 | if (dma_mapping_error(&bp->pdev->dev, mapping)) { |
| 6643 | dev_kfree_skb(skb); | 6639 | dev_kfree_skb_any(skb); |
| 6644 | return NETDEV_TX_OK; | 6640 | return NETDEV_TX_OK; |
| 6645 | } | 6641 | } |
| 6646 | 6642 | ||
| @@ -6733,7 +6729,7 @@ dma_error: · 86 unmodified lines | |||
| 6733 | PCI_DMA_TODEVICE); | 6729 | PCI_DMA_TODEVICE); |
| 6734 | } | 6730 | } |
| 6735 | 6731 | ||
| 6736 | dev_kfree_skb(skb); | 6732 | dev_kfree_skb_any(skb); |
| 6737 | return NETDEV_TX_OK; | 6733 | return NETDEV_TX_OK; |
| 6738 | } | 6734 | } |
| 6739 | 6735 | ||
| @@ -26,8 +26,8 @@ · 25 unmodified lines | |||
| 26 | * (you will need to reboot afterwards) */ | 26 | * (you will need to reboot afterwards) */ |
| 27 | /* #define BNX2X_STOP_ON_ERROR */ | 27 | /* #define BNX2X_STOP_ON_ERROR */ |
| 28 | 28 | ||
| 29 | #define DRV_MODULE_VERSION "1.78.17-0" | 29 | #define DRV_MODULE_VERSION "1.78.19-0" |
| 30 | #define DRV_MODULE_RELDATE "2013/04/11" | 30 | #define DRV_MODULE_RELDATE "2014/02/10" |
| 31 | #define BNX2X_BC_VER 0x040200 | 31 | #define BNX2X_BC_VER 0x040200 |
| 32 | 32 | ||
| 33 | #if defined(CONFIG_DCB) | 33 | #if defined(CONFIG_DCB) |
| @@ -75,13 +75,22 @@ enum bnx2x_int_mode { · 41 unmodified lines | |||
| 75 | #define BNX2X_MSG_DCB 0x8000000 | 75 | #define BNX2X_MSG_DCB 0x8000000 |
| 76 | 76 | ||
| 77 | /* regular debug print */ | 77 | /* regular debug print */ |
| 78 | #define DP_INNER(fmt, ...) \ | ||
| 79 | pr_notice("[%s:%d(%s)]" fmt, \ | ||
| 80 | __func__, __LINE__, \ | ||
| 81 | bp->dev ? (bp->dev->name) : "?", \ | ||
| 82 | ##__VA_ARGS__); | ||
| 83 | |||
| 78 | #define DP(__mask, fmt, ...) \ | 84 | #define DP(__mask, fmt, ...) \ |
| 79 | do { \ | 85 | do { \ |
| 80 | if (unlikely(bp->msg_enable & (__mask))) \ | 86 | if (unlikely(bp->msg_enable & (__mask))) \ |
| 81 | pr_notice("[%s:%d(%s)]" fmt, \ | 87 | DP_INNER(fmt, ##__VA_ARGS__); \ |
| 82 | __func__, __LINE__, \ | 88 | } while (0) |
| 83 | bp->dev ? (bp->dev->name) : "?", \ | 89 | |
| 84 | ##__VA_ARGS__); \ | 90 | #define DP_AND(__mask, fmt, ...) \ |
| 91 | do { \ | ||
| 92 | if (unlikely((bp->msg_enable & (__mask)) == __mask)) \ | ||
| 93 | DP_INNER(fmt, ##__VA_ARGS__); \ | ||
| 85 | } while (0) | 94 | } while (0) |
| 86 | 95 | ||
| 87 | #define DP_CONT(__mask, fmt, ...) \ | 96 | #define DP_CONT(__mask, fmt, ...) \ |
| @@ -1146,10 +1155,6 @@ struct bnx2x_port { · 1058 unmodified lines | |||
| 1146 | (offsetof(struct bnx2x_eth_stats, stat_name) / 4) | 1155 | (offsetof(struct bnx2x_eth_stats, stat_name) / 4) |
| 1147 | 1156 | ||
| 1148 | /* slow path */ | 1157 | /* slow path */ |
| 1149 | |||
| 1150 | /* slow path work-queue */ | ||
| 1151 | extern struct workqueue_struct *bnx2x_wq; | ||
| 1152 | |||
| 1153 | #define BNX2X_MAX_NUM_OF_VFS 64 | 1158 | #define BNX2X_MAX_NUM_OF_VFS 64 |
| 1154 | #define BNX2X_VF_CID_WND 4 /* log num of queues per VF. HW config. */ | 1159 | #define BNX2X_VF_CID_WND 4 /* log num of queues per VF. HW config. */ |
| 1155 | #define BNX2X_CIDS_PER_VF (1 << BNX2X_VF_CID_WND) | 1160 | #define BNX2X_CIDS_PER_VF (1 << BNX2X_VF_CID_WND) |
| @@ -1261,6 +1266,7 @@ struct bnx2x_slowpath { · 105 unmodified lines | |||
| 1261 | union { | 1266 | union { |
| 1262 | struct client_init_ramrod_data init_data; | 1267 | struct client_init_ramrod_data init_data; |
| 1263 | struct client_update_ramrod_data update_data; | 1268 | struct client_update_ramrod_data update_data; |
| 1269 | struct tpa_update_ramrod_data tpa_data; | ||
| 1264 | } q_rdata; | 1270 | } q_rdata; |
| 1265 | 1271 | ||
| 1266 | union { | 1272 | union { |
| @@ -1392,7 +1398,7 @@ struct bnx2x_fw_stats_data { · 125 unmodified lines | |||
| 1392 | }; | 1398 | }; |
| 1393 | 1399 | ||
| 1394 | /* Public slow path states */ | 1400 | /* Public slow path states */ |
| 1395 | enum { | 1401 | enum sp_rtnl_flag { |
| 1396 | BNX2X_SP_RTNL_SETUP_TC, | 1402 | BNX2X_SP_RTNL_SETUP_TC, |
| 1397 | BNX2X_SP_RTNL_TX_TIMEOUT, | 1403 | BNX2X_SP_RTNL_TX_TIMEOUT, |
| 1398 | BNX2X_SP_RTNL_FAN_FAILURE, | 1404 | BNX2X_SP_RTNL_FAN_FAILURE, |
| @@ -1403,6 +1409,12 @@ enum { · 4 unmodified lines | |||
| 1403 | BNX2X_SP_RTNL_RX_MODE, | 1409 | BNX2X_SP_RTNL_RX_MODE, |
| 1404 | BNX2X_SP_RTNL_HYPERVISOR_VLAN, | 1410 | BNX2X_SP_RTNL_HYPERVISOR_VLAN, |
| 1405 | BNX2X_SP_RTNL_TX_STOP, | 1411 | BNX2X_SP_RTNL_TX_STOP, |
| 1412 | BNX2X_SP_RTNL_GET_DRV_VERSION, | ||
| 1413 | }; | ||
| 1414 | |||
| 1415 | enum bnx2x_iov_flag { | ||
| 1416 | BNX2X_IOV_HANDLE_VF_MSG, | ||
| 1417 | BNX2X_IOV_HANDLE_FLR, | ||
| 1406 | }; | 1418 | }; |
| 1407 | 1419 | ||
| 1408 | struct bnx2x_prev_path_list { | 1420 | struct bnx2x_prev_path_list { |
| @@ -1603,6 +1615,8 @@ struct bnx2x { · 194 unmodified lines | |||
| 1603 | int mrrs; | 1615 | int mrrs; |
| 1604 | 1616 | ||
| 1605 | struct delayed_work sp_task; | 1617 | struct delayed_work sp_task; |
| 1618 | struct delayed_work iov_task; | ||
| 1619 | |||
| 1606 | atomic_t interrupt_occurred; | 1620 | atomic_t interrupt_occurred; |
| 1607 | struct delayed_work sp_rtnl_task; | 1621 | struct delayed_work sp_rtnl_task; |
| 1608 | 1622 | ||
| @@ -1693,6 +1707,10 @@ struct bnx2x { · 84 unmodified lines | |||
| 1693 | struct bnx2x_slowpath *slowpath; | 1707 | struct bnx2x_slowpath *slowpath; |
| 1694 | dma_addr_t slowpath_mapping; | 1708 | dma_addr_t slowpath_mapping; |
| 1695 | 1709 | ||
| 1710 | /* Mechanism protecting the drv_info_to_mcp */ | ||
| 1711 | struct mutex drv_info_mutex; | ||
| 1712 | bool drv_info_mng_owner; | ||
| 1713 | |||
| 1696 | /* Total number of FW statistics requests */ | 1714 | /* Total number of FW statistics requests */ |
| 1697 | u8 fw_stats_num; | 1715 | u8 fw_stats_num; |
| 1698 | 1716 | ||
| @@ -1882,6 +1900,9 @@ struct bnx2x { · 183 unmodified lines | |||
| 1882 | /* operation indication for the sp_rtnl task */ | 1900 | /* operation indication for the sp_rtnl task */ |
| 1883 | unsigned long sp_rtnl_state; | 1901 | unsigned long sp_rtnl_state; |
| 1884 | 1902 | ||
| 1903 | /* Indication of the IOV tasks */ | ||
| 1904 | unsigned long iov_task_state; | ||
| 1905 | |||
| 1885 | /* DCBX Negotiation results */ | 1906 | /* DCBX Negotiation results */ |
| 1886 | struct dcbx_features dcbx_local_feat; | 1907 | struct dcbx_features dcbx_local_feat; |
| 1887 | u32 dcbx_error; | 1908 | u32 dcbx_error; |
| @@ -2525,6 +2546,8 @@ enum { · 637 unmodified lines | |||
| 2525 | 2546 | ||
| 2526 | void bnx2x_set_local_cmng(struct bnx2x *bp); | 2547 | void bnx2x_set_local_cmng(struct bnx2x *bp); |
| 2527 | 2548 | ||
| 2549 | void bnx2x_update_mng_version(struct bnx2x *bp); | ||
| 2550 | |||
| 2528 | #define MCPR_SCRATCH_BASE(bp) \ | 2551 | #define MCPR_SCRATCH_BASE(bp) \ |
| 2529 | (CHIP_IS_E1x(bp) ? MCP_REG_MCPR_SCRATCH : MCP_A_REG_MCPR_SCRATCH) | 2552 | (CHIP_IS_E1x(bp) ? MCP_REG_MCPR_SCRATCH : MCP_A_REG_MCPR_SCRATCH) |
| 2530 | 2553 | ||
| @@ -61,10 +61,14 @@ static void bnx2x_add_all_napi(struct bnx2x *bp) · 60 unmodified lines | |||
| 61 | 61 | ||
| 62 | static int bnx2x_calc_num_queues(struct bnx2x *bp) | 62 | static int bnx2x_calc_num_queues(struct bnx2x *bp) |
| 63 | { | 63 | { |
| 64 | return bnx2x_num_queues ? | 64 | int nq = bnx2x_num_queues ? : netif_get_num_default_rss_queues(); |
| 65 | min_t(int, bnx2x_num_queues, BNX2X_MAX_QUEUES(bp)) : | 65 | |
| 66 | min_t(int, netif_get_num_default_rss_queues(), | 66 | /* Reduce memory usage in kdump environment by using only one queue */ |
| 67 | BNX2X_MAX_QUEUES(bp)); | 67 | if (reset_devices) |
| 68 | nq = 1; | ||
| 69 | |||
| 70 | nq = clamp(nq, 1, BNX2X_MAX_QUEUES(bp)); | ||
| 71 | return nq; | ||
| 68 | } | 72 | } |
| 69 | 73 | ||
| 70 | /** | 74 | /** |
| @@ -868,6 +872,8 @@ static int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget) · 797 unmodified lines | |||
| 868 | if (unlikely(bp->panic)) | 872 | if (unlikely(bp->panic)) |
| 869 | return 0; | 873 | return 0; |
| 870 | #endif | 874 | #endif |
| 875 | if (budget <= 0) | ||
| 876 | return rx_pkt; | ||
| 871 | 877 | ||
| 872 | bd_cons = fp->rx_bd_cons; | 878 | bd_cons = fp->rx_bd_cons; |
| 873 | bd_prod = fp->rx_bd_prod; | 879 | bd_prod = fp->rx_bd_prod; |
| @@ -1638,36 +1644,16 @@ int bnx2x_enable_msix(struct bnx2x *bp) · 764 unmodified lines | |||
| 1638 | DP(BNX2X_MSG_SP, "about to request enable msix with %d vectors\n", | 1644 | DP(BNX2X_MSG_SP, "about to request enable msix with %d vectors\n", |
| 1639 | msix_vec); | 1645 | msix_vec); |
| 1640 | 1646 | ||
| 1641 | rc = pci_enable_msix(bp->pdev, &bp->msix_table[0], msix_vec); | 1647 | rc = pci_enable_msix_range(bp->pdev, &bp->msix_table[0], |
| 1642 | 1648 | BNX2X_MIN_MSIX_VEC_CNT(bp), msix_vec); | |
| 1643 | /* | 1649 | /* |
| 1644 | * reconfigure number of tx/rx queues according to available | 1650 | * reconfigure number of tx/rx queues according to available |
| 1645 | * MSI-X vectors | 1651 | * MSI-X vectors |
| 1646 | */ | 1652 | */ |
| 1647 | if (rc >= BNX2X_MIN_MSIX_VEC_CNT(bp)) { | 1653 | if (rc == -ENOSPC) { |
| 1648 | /* how less vectors we will have? */ | ||
| 1649 | int diff = msix_vec - rc; | ||
| 1650 | |||
| 1651 | BNX2X_DEV_INFO("Trying to use less MSI-X vectors: %d\n", rc); | ||
| 1652 | |||
| 1653 | rc = pci_enable_msix(bp->pdev, &bp->msix_table[0], rc); | ||
| 1654 | |||
| 1655 | if (rc) { | ||
| 1656 | BNX2X_DEV_INFO("MSI-X is not attainable rc %d\n", rc); | ||
| 1657 | goto no_msix; | ||
| 1658 | } | ||
| 1659 | /* | ||
| 1660 | * decrease number of queues by number of unallocated entries | ||
| 1661 | */ | ||
| 1662 | bp->num_ethernet_queues -= diff; | ||
| 1663 | bp->num_queues = bp->num_ethernet_queues + bp->num_cnic_queues; | ||
| 1664 | |||
| 1665 | BNX2X_DEV_INFO("New queue configuration set: %d\n", | ||
| 1666 | bp->num_queues); | ||
| 1667 | } else if (rc > 0) { | ||
| 1668 | /* Get by with single vector */ | 1654 | /* Get by with single vector */ |
| 1669 | rc = pci_enable_msix(bp->pdev, &bp->msix_table[0], 1); | 1655 | rc = pci_enable_msix_range(bp->pdev, &bp->msix_table[0], 1, 1); |
| 1670 | if (rc) { | 1656 | if (rc < 0) { |
| 1671 | BNX2X_DEV_INFO("Single MSI-X is not attainable rc %d\n", | 1657 | BNX2X_DEV_INFO("Single MSI-X is not attainable rc %d\n", |
| 1672 | rc); | 1658 | rc); |
| 1673 | goto no_msix; | 1659 | goto no_msix; |
| @@ -1680,8 +1666,22 @@ int bnx2x_enable_msix(struct bnx2x *bp) · 6 unmodified lines | |||
| 1680 | bp->num_ethernet_queues = 1; | 1666 | bp->num_ethernet_queues = 1; |
| 1681 | bp->num_queues = bp->num_ethernet_queues + bp->num_cnic_queues; | 1667 | bp->num_queues = bp->num_ethernet_queues + bp->num_cnic_queues; |
| 1682 | } else if (rc < 0) { | 1668 | } else if (rc < 0) { |
| 1683 | BNX2X_DEV_INFO("MSI-X is not attainable rc %d\n", rc); | 1669 | BNX2X_DEV_INFO("MSI-X is not attainable rc %d\n", rc); |
| 1684 | goto no_msix; | 1670 | goto no_msix; |
| 1671 | } else if (rc < msix_vec) { | ||
| 1672 | /* how less vectors we will have? */ | ||
| 1673 | int diff = msix_vec - rc; | ||
| 1674 | |||
| 1675 | BNX2X_DEV_INFO("Trying to use less MSI-X vectors: %d\n", rc); | ||
| 1676 | |||
| 1677 | /* | ||
| 1678 | * decrease number of queues by number of unallocated entries | ||
| 1679 | */ | ||
| 1680 | bp->num_ethernet_queues -= diff; | ||
| 1681 | bp->num_queues = bp->num_ethernet_queues + bp->num_cnic_queues; | ||
| 1682 | |||
| 1683 | BNX2X_DEV_INFO("New queue configuration set: %d\n", | ||
| 1684 | bp->num_queues); | ||
| 1685 | } | 1685 | } |
| 1686 | 1686 | ||
| 1687 | bp->flags |= USING_MSIX_FLAG; | 1687 | bp->flags |= USING_MSIX_FLAG; |
| @@ -2234,8 +2234,10 @@ static int bnx2x_alloc_fw_stats_mem(struct bnx2x *bp) · 546 unmodified lines | |||
| 2234 | sizeof(struct per_queue_stats) * num_queue_stats + | 2234 | sizeof(struct per_queue_stats) * num_queue_stats + |
| 2235 | sizeof(struct stats_counter); | 2235 | sizeof(struct stats_counter); |
| 2236 | 2236 | ||
| 2237 | BNX2X_PCI_ALLOC(bp->fw_stats, &bp->fw_stats_mapping, | 2237 | bp->fw_stats = BNX2X_PCI_ALLOC(&bp->fw_stats_mapping, |
| 2238 | bp->fw_stats_data_sz + bp->fw_stats_req_sz); | 2238 | bp->fw_stats_data_sz + bp->fw_stats_req_sz); |
| 2239 | if (!bp->fw_stats) | ||
| 2240 | goto alloc_mem_err; | ||
| 2239 | 2241 | ||
| 2240 | /* Set shortcuts */ | 2242 | /* Set shortcuts */ |
| 2241 | bp->fw_stats_req = (struct bnx2x_fw_stats_req *)bp->fw_stats; | 2243 | bp->fw_stats_req = (struct bnx2x_fw_stats_req *)bp->fw_stats; |
| @@ -2802,6 +2804,9 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) · 560 unmodified lines | |||
| 2802 | if (CNIC_ENABLED(bp)) | 2804 | if (CNIC_ENABLED(bp)) |
| 2803 | bnx2x_load_cnic(bp); | 2805 | bnx2x_load_cnic(bp); |
| 2804 | 2806 | ||
| 2807 | if (IS_PF(bp)) | ||
| 2808 | bnx2x_schedule_sp_rtnl(bp, BNX2X_SP_RTNL_GET_DRV_VERSION, 0); | ||
| 2809 | |||
| 2805 | if (IS_PF(bp) && SHMEM2_HAS(bp, drv_capabilities_flag)) { | 2810 | if (IS_PF(bp) && SHMEM2_HAS(bp, drv_capabilities_flag)) { |
| 2806 | /* mark driver is loaded in shmem2 */ | 2811 | /* mark driver is loaded in shmem2 */ |
| 2807 | u32 val; | 2812 | u32 val; |
| @@ -3028,6 +3033,10 @@ int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode, bool keep_link) · 220 unmodified lines | |||
| 3028 | bp->state = BNX2X_STATE_CLOSED; | 3033 | bp->state = BNX2X_STATE_CLOSED; |
| 3029 | bp->cnic_loaded = false; | 3034 | bp->cnic_loaded = false; |
| 3030 | 3035 | ||
| 3036 | /* Clear driver version indication in shmem */ | ||
| 3037 | if (IS_PF(bp)) | ||
| 3038 | bnx2x_update_mng_version(bp); | ||
| 3039 | |||
| 3031 | /* Check if there are pending parity attentions. If there are - set | 3040 | /* Check if there are pending parity attentions. If there are - set |
| 3032 | * RECOVERY_IN_PROGRESS. | 3041 | * RECOVERY_IN_PROGRESS. |
| 3033 | */ | 3042 | */ |
| @@ -4370,14 +4379,17 @@ static int bnx2x_alloc_fp_mem_at(struct bnx2x *bp, int index) · 1336 unmodified lines | |||
| 4370 | 4379 | ||
| 4371 | if (!IS_FCOE_IDX(index)) { | 4380 | if (!IS_FCOE_IDX(index)) { |
| 4372 | /* status blocks */ | 4381 | /* status blocks */ |
| 4373 | if (!CHIP_IS_E1x(bp)) | 4382 | if (!CHIP_IS_E1x(bp)) { |
| 4374 | BNX2X_PCI_ALLOC(sb->e2_sb, | 4383 | sb->e2_sb = BNX2X_PCI_ALLOC(&bnx2x_fp(bp, index, status_blk_mapping), |
| 4375 | &bnx2x_fp(bp, index, status_blk_mapping), | 4384 | sizeof(struct host_hc_status_block_e2)); |
| 4376 | sizeof(struct host_hc_status_block_e2)); | 4385 | if (!sb->e2_sb) |
| 4377 | else | 4386 | goto alloc_mem_err; |
| 4378 | BNX2X_PCI_ALLOC(sb->e1x_sb, | 4387 | } else { |
| 4379 | &bnx2x_fp(bp, index, status_blk_mapping), | 4388 | sb->e1x_sb = BNX2X_PCI_ALLOC(&bnx2x_fp(bp, index, status_blk_mapping), |
| 4380 | sizeof(struct host_hc_status_block_e1x)); | 4389 | sizeof(struct host_hc_status_block_e1x)); |
| 4390 | if (!sb->e1x_sb) | ||
| 4391 | goto alloc_mem_err; | ||
| 4392 | } | ||
| 4381 | } | 4393 | } |
| 4382 | 4394 | ||
| 4383 | /* FCoE Queue uses Default SB and doesn't ACK the SB, thus no need to | 4395 | /* FCoE Queue uses Default SB and doesn't ACK the SB, thus no need to |
| @@ -4396,35 +4408,49 @@ static int bnx2x_alloc_fp_mem_at(struct bnx2x *bp, int index) · 12 unmodified lines | |||
| 4396 | "allocating tx memory of fp %d cos %d\n", | 4408 | "allocating tx memory of fp %d cos %d\n", |
| 4397 | index, cos); | 4409 | index, cos); |
| 4398 | 4410 | ||
| 4399 | BNX2X_ALLOC(txdata->tx_buf_ring, | 4411 | txdata->tx_buf_ring = kcalloc(NUM_TX_BD, |
| 4400 | sizeof(struct sw_tx_bd) * NUM_TX_BD); | 4412 | sizeof(struct sw_tx_bd), |
| 4401 | BNX2X_PCI_ALLOC(txdata->tx_desc_ring, | 4413 | GFP_KERNEL); |
| 4402 | &txdata->tx_desc_mapping, | 4414 | if (!txdata->tx_buf_ring) |
| 4403 | sizeof(union eth_tx_bd_types) * NUM_TX_BD); | 4415 | goto alloc_mem_err; |
| 4416 | txdata->tx_desc_ring = BNX2X_PCI_ALLOC(&txdata->tx_desc_mapping, | ||
| 4417 | sizeof(union eth_tx_bd_types) * NUM_TX_BD); | ||
| 4418 | if (!txdata->tx_desc_ring) | ||
| 4419 | goto alloc_mem_err; | ||
| 4404 | } | 4420 | } |
| 4405 | } | 4421 | } |
| 4406 | 4422 | ||
| 4407 | /* Rx */ | 4423 | /* Rx */ |
| 4408 | if (!skip_rx_queue(bp, index)) { | 4424 | if (!skip_rx_queue(bp, index)) { |
| 4409 | /* fastpath rx rings: rx_buf rx_desc rx_comp */ | 4425 | /* fastpath rx rings: rx_buf rx_desc rx_comp */ |
| 4410 | BNX2X_ALLOC(bnx2x_fp(bp, index, rx_buf_ring), | 4426 | bnx2x_fp(bp, index, rx_buf_ring) = |
| 4411 | sizeof(struct sw_rx_bd) * NUM_RX_BD); | 4427 | kcalloc(NUM_RX_BD, sizeof(struct sw_rx_bd), GFP_KERNEL); |
| 4412 | BNX2X_PCI_ALLOC(bnx2x_fp(bp, index, rx_desc_ring), | 4428 | if (!bnx2x_fp(bp, index, rx_buf_ring)) |
| 4413 | &bnx2x_fp(bp, index, rx_desc_mapping), | 4429 | goto alloc_mem_err; |
| 4414 | sizeof(struct eth_rx_bd) * NUM_RX_BD); | 4430 | bnx2x_fp(bp, index, rx_desc_ring) = |
| 4431 | BNX2X_PCI_ALLOC(&bnx2x_fp(bp, index, rx_desc_mapping), | ||
| 4432 | sizeof(struct eth_rx_bd) * NUM_RX_BD); | ||
| 4433 | if (!bnx2x_fp(bp, index, rx_desc_ring)) | ||
| 4434 | goto alloc_mem_err; | ||
| 4415 | 4435 | ||
| 4416 | /* Seed all CQEs by 1s */ | 4436 | /* Seed all CQEs by 1s */ |
| 4417 | BNX2X_PCI_FALLOC(bnx2x_fp(bp, index, rx_comp_ring), | 4437 | bnx2x_fp(bp, index, rx_comp_ring) = |
| 4418 | &bnx2x_fp(bp, index, rx_comp_mapping), | 4438 | BNX2X_PCI_FALLOC(&bnx2x_fp(bp, index, rx_comp_mapping), |
| 4419 | sizeof(struct eth_fast_path_rx_cqe) * | 4439 | sizeof(struct eth_fast_path_rx_cqe) * NUM_RCQ_BD); |
| 4420 | NUM_RCQ_BD); | 4440 | if (!bnx2x_fp(bp, index, rx_comp_ring)) |
| 4441 | goto alloc_mem_err; | ||
| 4421 | 4442 | ||
| 4422 | /* SGE ring */ | 4443 | /* SGE ring */ |
| 4423 | BNX2X_ALLOC(bnx2x_fp(bp, index, rx_page_ring), | 4444 | bnx2x_fp(bp, index, rx_page_ring) = |
| 4424 | sizeof(struct sw_rx_page) * NUM_RX_SGE); | 4445 | kcalloc(NUM_RX_SGE, sizeof(struct sw_rx_page), |
| 4425 | BNX2X_PCI_ALLOC(bnx2x_fp(bp, index, rx_sge_ring), | 4446 | GFP_KERNEL); |
| 4426 | &bnx2x_fp(bp, index, rx_sge_mapping), | 4447 | if (!bnx2x_fp(bp, index, rx_page_ring)) |
| 4427 | BCM_PAGE_SIZE * NUM_RX_SGE_PAGES); | 4448 | goto alloc_mem_err; |
| 4449 | bnx2x_fp(bp, index, rx_sge_ring) = | ||
| 4450 | BNX2X_PCI_ALLOC(&bnx2x_fp(bp, index, rx_sge_mapping), | ||
| 4451 | BCM_PAGE_SIZE * NUM_RX_SGE_PAGES); | ||
| 4452 | if (!bnx2x_fp(bp, index, rx_sge_ring)) | ||
| 4453 | goto alloc_mem_err; | ||
| 4428 | /* RX BD ring */ | 4454 | /* RX BD ring */ |
| 4429 | bnx2x_set_next_page_rx_bd(fp); | 4455 | bnx2x_set_next_page_rx_bd(fp); |
| 4430 | 4456 | ||
| @@ -4780,12 +4806,8 @@ void bnx2x_tx_timeout(struct net_device *dev) · 349 unmodified lines | |||
| 4780 | bnx2x_panic(); | 4806 | bnx2x_panic(); |
| 4781 | #endif | 4807 | #endif |
| 4782 | 4808 | ||
| 4783 | smp_mb__before_clear_bit(); | ||
| 4784 | set_bit(BNX2X_SP_RTNL_TX_TIMEOUT, &bp->sp_rtnl_state); | ||
| 4785 | smp_mb__after_clear_bit(); | ||
| 4786 | |||
| 4787 | /* This allows the netif to be shutdown gracefully before resetting */ | 4809 | /* This allows the netif to be shutdown gracefully before resetting */ |
| 4788 | schedule_delayed_work(&bp->sp_rtnl_task, 0); | 4810 | bnx2x_schedule_sp_rtnl(bp, BNX2X_SP_RTNL_TX_TIMEOUT, 0); |
| 4789 | } | 4811 | } |
| 4790 | 4812 | ||
| 4791 | int bnx2x_suspend(struct pci_dev *pdev, pm_message_t state) | 4813 | int bnx2x_suspend(struct pci_dev *pdev, pm_message_t state) |
| @@ -4913,3 +4935,15 @@ void bnx2x_update_coalesce_sb_index(struct bnx2x *bp, u8 fw_sb_id, · 121 unmodified lines | |||
| 4913 | disable = disable ? 1 : (usec ? 0 : 1); | 4935 | disable = disable ? 1 : (usec ? 0 : 1); |
| 4914 | storm_memset_hc_disable(bp, port, fw_sb_id, sb_index, disable); | 4936 | storm_memset_hc_disable(bp, port, fw_sb_id, sb_index, disable); |
| 4915 | } | 4937 | } |
| 4938 | |||
| 4939 | void bnx2x_schedule_sp_rtnl(struct bnx2x *bp, enum sp_rtnl_flag flag, | ||
| 4940 | u32 verbose) | ||
| 4941 | { | ||
| 4942 | smp_mb__before_clear_bit(); | ||
| 4943 | set_bit(flag, &bp->sp_rtnl_state); | ||
| 4944 | smp_mb__after_clear_bit(); | ||
| 4945 | DP((BNX2X_MSG_SP | verbose), "Scheduling sp_rtnl task [Flag: %d]\n", | ||
| 4946 | flag); | ||
| 4947 | schedule_delayed_work(&bp->sp_rtnl_task, 0); | ||
| 4948 | } | ||
| 4949 | EXPORT_SYMBOL(bnx2x_schedule_sp_rtnl); | ||
| @@ -47,31 +47,26 @@ extern int bnx2x_num_queues; · 46 unmodified lines | |||
| 47 | } \ | 47 | } \ |
| 48 | } while (0) | 48 | } while (0) |
| 49 | 49 | ||
| 50 | #define BNX2X_PCI_ALLOC(x, y, size) \ | 50 | #define BNX2X_PCI_ALLOC(y, size) \ |
| 51 | do { \ | 51 | ({ \ |
| 52 | x = dma_zalloc_coherent(&bp->pdev->dev, size, y, GFP_KERNEL); \ | 52 | void *x = dma_zalloc_coherent(&bp->pdev->dev, size, y, GFP_KERNEL); \ |
| 53 | if (x == NULL) \ | 53 | if (x) \ |
| 54 | goto alloc_mem_err; \ | 54 | DP(NETIF_MSG_HW, \ |
| 55 | DP(NETIF_MSG_HW, "BNX2X_PCI_ALLOC: Physical %Lx Virtual %p\n", \ | 55 | "BNX2X_PCI_ALLOC: Physical %Lx Virtual %p\n", \ |
| 56 | (unsigned long long)(*y), x); \ | 56 | (unsigned long long)(*y), x); \ |
| 57 | } while (0) | 57 | x; \ |
| 58 | 58 | }) | |
| 59 | #define BNX2X_PCI_FALLOC(x, y, size) \ | 59 | #define BNX2X_PCI_FALLOC(y, size) \ |
| 60 | do { \ | 60 | ({ \ |
| 61 | x = dma_alloc_coherent(&bp->pdev->dev, size, y, GFP_KERNEL); \ | 61 | void *x = dma_alloc_coherent(&bp->pdev->dev, size, y, GFP_KERNEL); \ |
| 62 | if (x == NULL) \ | 62 | if (x) { \ |
| 63 | goto alloc_mem_err; \ | 63 | memset(x, 0xff, size); \ |
| 64 | memset((void *)x, 0xFFFFFFFF, size); \ | 64 | DP(NETIF_MSG_HW, \ |
| 65 | DP(NETIF_MSG_HW, "BNX2X_PCI_FALLOC: Physical %Lx Virtual %p\n",\ | 65 | "BNX2X_PCI_FALLOC: Physical %Lx Virtual %p\n", \ |
| 66 | (unsigned long long)(*y), x); \ | 66 | (unsigned long long)(*y), x); \ |
| 67 | } while (0) | 67 | } \ |
| 68 | 68 | x; \ | |
| 69 | #define BNX2X_ALLOC(x, size) \ | 69 | }) |
| 70 | do { \ | ||
| 71 | x = kzalloc(size, GFP_KERNEL); \ | ||
| 72 | if (x == NULL) \ | ||
| 73 | goto alloc_mem_err; \ | ||
| 74 | } while (0) | ||
| 75 | 70 | ||
| 76 | /*********************** Interfaces **************************** | 71 | /*********************** Interfaces **************************** |
| 77 | * Functions that need to be implemented by each driver version | 72 | * Functions that need to be implemented by each driver version |
| @@ -1324,4 +1319,7 @@ void bnx2x_fill_fw_str(struct bnx2x *bp, char *buf, size_t buf_len); · 1246 unmodified lines | |||
| 1324 | int bnx2x_drain_tx_queues(struct bnx2x *bp); | 1319 | int bnx2x_drain_tx_queues(struct bnx2x *bp); |
| 1325 | void bnx2x_squeeze_objects(struct bnx2x *bp); | 1320 | void bnx2x_squeeze_objects(struct bnx2x *bp); |
| 1326 | 1321 | ||
| 1322 | void bnx2x_schedule_sp_rtnl(struct bnx2x*, enum sp_rtnl_flag, | ||
| 1323 | u32 verbose); | ||
| 1324 | |||
| 1327 | #endif /* BNX2X_CMN_H */ | 1325 | #endif /* BNX2X_CMN_H */ |
| @@ -710,8 +710,7 @@ static inline void bnx2x_dcbx_update_tc_mapping(struct bnx2x *bp) · 709 unmodified lines | |||
| 710 | * as we are handling an attention on a work queue which must be | 710 | * as we are handling an attention on a work queue which must be |
| 711 | * flushed at some rtnl-locked contexts (e.g. if down) | 711 | * flushed at some rtnl-locked contexts (e.g. if down) |
| 712 | */ | 712 | */ |
| 713 | if (!test_and_set_bit(BNX2X_SP_RTNL_SETUP_TC, &bp->sp_rtnl_state)) | 713 | bnx2x_schedule_sp_rtnl(bp, BNX2X_SP_RTNL_SETUP_TC, 0); |
| 714 | schedule_delayed_work(&bp->sp_rtnl_task, 0); | ||
| 715 | } | 714 | } |
| 716 | 715 | ||
| 717 | void bnx2x_dcbx_set_params(struct bnx2x *bp, u32 state) | 716 | void bnx2x_dcbx_set_params(struct bnx2x *bp, u32 state) |
| @@ -764,10 +763,7 @@ void bnx2x_dcbx_set_params(struct bnx2x *bp, u32 state) · 46 unmodified lines | |||
| 764 | if (IS_MF(bp)) | 763 | if (IS_MF(bp)) |
| 765 | bnx2x_link_sync_notify(bp); | 764 | bnx2x_link_sync_notify(bp); |
| 766 | 765 | ||
| 767 | set_bit(BNX2X_SP_RTNL_TX_STOP, &bp->sp_rtnl_state); | 766 | bnx2x_schedule_sp_rtnl(bp, BNX2X_SP_RTNL_TX_STOP, 0); |
| 768 | |||
| 769 | schedule_delayed_work(&bp->sp_rtnl_task, 0); | ||
| 770 | |||
| 771 | return; | 767 | return; |
| 772 | } | 768 | } |
| 773 | case BNX2X_DCBX_STATE_TX_PAUSED: | 769 | case BNX2X_DCBX_STATE_TX_PAUSED: |
| @@ -2969,8 +2969,9 @@ static void bnx2x_self_test(struct net_device *dev, · 2968 unmodified lines | |||
| 2969 | #define IS_PORT_STAT(i) \ | 2969 | #define IS_PORT_STAT(i) \ |
| 2970 | ((bnx2x_stats_arr[i].flags & STATS_FLAGS_BOTH) == STATS_FLAGS_PORT) | 2970 | ((bnx2x_stats_arr[i].flags & STATS_FLAGS_BOTH) == STATS_FLAGS_PORT) |
| 2971 | #define IS_FUNC_STAT(i) (bnx2x_stats_arr[i].flags & STATS_FLAGS_FUNC) | 2971 | #define IS_FUNC_STAT(i) (bnx2x_stats_arr[i].flags & STATS_FLAGS_FUNC) |
| 2972 | #define IS_MF_MODE_STAT(bp) \ | 2972 | #define HIDE_PORT_STAT(bp) \ |
| 2973 | (IS_MF(bp) && !(bp->msg_enable & BNX2X_MSG_STATS)) | 2973 | ((IS_MF(bp) && !(bp->msg_enable & BNX2X_MSG_STATS)) || \ |
| 2974 | IS_VF(bp)) | ||
| 2974 | 2975 | ||
| 2975 | /* ethtool statistics are displayed for all regular ethernet queues and the | 2976 | /* ethtool statistics are displayed for all regular ethernet queues and the |
| 2976 | * fcoe L2 queue if not disabled | 2977 | * fcoe L2 queue if not disabled |
| @@ -2992,7 +2993,7 @@ static int bnx2x_get_sset_count(struct net_device *dev, int stringset) · 15 unmodified lines | |||
| 2992 | BNX2X_NUM_Q_STATS; | 2993 | BNX2X_NUM_Q_STATS; |
| 2993 | } else | 2994 | } else |
| 2994 | num_strings = 0; | 2995 | num_strings = 0; |
| 2995 | if (IS_MF_MODE_STAT(bp)) { | 2996 | if (HIDE_PORT_STAT(bp)) { |
| 2996 | for (i = 0; i < BNX2X_NUM_STATS; i++) | 2997 | for (i = 0; i < BNX2X_NUM_STATS; i++) |
| 2997 | if (IS_FUNC_STAT(i)) | 2998 | if (IS_FUNC_STAT(i)) |
| 2998 | num_strings++; | 2999 | num_strings++; |
| @@ -3047,7 +3048,7 @@ static void bnx2x_get_strings(struct net_device *dev, u32 stringset, u8 *buf) · 48 unmodified lines | |||
| 3047 | } | 3048 | } |
| 3048 | 3049 | ||
| 3049 | for (i = 0, j = 0; i < BNX2X_NUM_STATS; i++) { | 3050 | for (i = 0, j = 0; i < BNX2X_NUM_STATS; i++) { |
| 3050 | if (IS_MF_MODE_STAT(bp) && IS_PORT_STAT(i)) | 3051 | if (HIDE_PORT_STAT(bp) && IS_PORT_STAT(i)) |
| 3051 | continue; | 3052 | continue; |
| 3052 | strcpy(buf + (k + j)*ETH_GSTRING_LEN, | 3053 | strcpy(buf + (k + j)*ETH_GSTRING_LEN, |
| 3053 | bnx2x_stats_arr[i].string); | 3054 | bnx2x_stats_arr[i].string); |
| @@ -3105,7 +3106,7 @@ static void bnx2x_get_ethtool_stats(struct net_device *dev, · 51 unmodified lines | |||
| 3105 | 3106 | ||
| 3106 | hw_stats = (u32 *)&bp->eth_stats; | 3107 | hw_stats = (u32 *)&bp->eth_stats; |
| 3107 | for (i = 0, j = 0; i < BNX2X_NUM_STATS; i++) { | 3108 | for (i = 0, j = 0; i < BNX2X_NUM_STATS; i++) { |
| 3108 | if (IS_MF_MODE_STAT(bp) && IS_PORT_STAT(i)) | 3109 | if (HIDE_PORT_STAT(bp) && IS_PORT_STAT(i)) |
| 3109 | continue; | 3110 | continue; |
| 3110 | if (bnx2x_stats_arr[i].size == 0) { | 3111 | if (bnx2x_stats_arr[i].size == 0) { |
| 3111 | /* skip this counter */ | 3112 | /* skip this counter */ |
| @@ -87,7 +87,6 @@ · 86 unmodified lines | |||
| 87 | (IRO[156].base + ((vfId) * IRO[156].m1)) | 87 | (IRO[156].base + ((vfId) * IRO[156].m1)) |
| 88 | #define CSTORM_VF_TO_PF_OFFSET(funcId) \ | 88 | #define CSTORM_VF_TO_PF_OFFSET(funcId) \ |
| 89 | (IRO[150].base + ((funcId) * IRO[150].m1)) | 89 | (IRO[150].base + ((funcId) * IRO[150].m1)) |
| 90 | #define TSTORM_ACCEPT_CLASSIFY_FAILED_OFFSET (IRO[204].base) | ||
| 91 | #define TSTORM_APPROXIMATE_MATCH_MULTICAST_FILTERING_OFFSET(pfId) \ | 90 | #define TSTORM_APPROXIMATE_MATCH_MULTICAST_FILTERING_OFFSET(pfId) \ |
| 92 | (IRO[203].base + ((pfId) * IRO[203].m1)) | 91 | (IRO[203].base + ((pfId) * IRO[203].m1)) |
| 93 | #define TSTORM_ASSERT_LIST_INDEX_OFFSET (IRO[102].base) | 92 | #define TSTORM_ASSERT_LIST_INDEX_OFFSET (IRO[102].base) |
| @@ -2003,6 +2003,23 @@ struct shmem_lfa { · 2002 unmodified lines | |||
| 2003 | #define SHMEM_LFA_DONT_CLEAR_STAT (1<<24) | 2003 | #define SHMEM_LFA_DONT_CLEAR_STAT (1<<24) |
| 2004 | }; | 2004 | }; |
| 2005 | 2005 | ||
| 2006 | /* Used to support NSCI get OS driver version | ||
| 2007 | * on driver load the version value will be set | ||
| 2008 | * on driver unload driver value of 0x0 will be set. | ||
| 2009 | */ | ||
| 2010 | struct os_drv_ver { | ||
| 2011 | #define DRV_VER_NOT_LOADED 0 | ||
| 2012 | |||
| 2013 | /* personalties order is important */ | ||
| 2014 | #define DRV_PERS_ETHERNET 0 | ||
| 2015 | #define DRV_PERS_ISCSI 1 | ||
| 2016 | #define DRV_PERS_FCOE 2 | ||
| 2017 | |||
| 2018 | /* shmem2 struct is constant can't add more personalties here */ | ||
| 2019 | #define MAX_DRV_PERS 3 | ||
| 2020 | u32 versions[MAX_DRV_PERS]; | ||
| 2021 | }; | ||
| 2022 | |||
| 2006 | struct ncsi_oem_fcoe_features { | 2023 | struct ncsi_oem_fcoe_features { |
| 2007 | u32 fcoe_features1; | 2024 | u32 fcoe_features1; |
| 2008 | #define FCOE_FEATURES1_IOS_PER_CONNECTION_MASK 0x0000FFFF | 2025 | #define FCOE_FEATURES1_IOS_PER_CONNECTION_MASK 0x0000FFFF |
| @@ -2217,6 +2234,18 @@ struct shmem2_region { · 208 unmodified lines | |||
| 2217 | u32 reserved4; /* Offset 0x150 */ | 2234 | u32 reserved4; /* Offset 0x150 */ |
| 2218 | u32 link_attr_sync[PORT_MAX]; /* Offset 0x154 */ | 2235 | u32 link_attr_sync[PORT_MAX]; /* Offset 0x154 */ |
| 2219 | #define LINK_ATTR_SYNC_KR2_ENABLE (1<<0) | 2236 | #define LINK_ATTR_SYNC_KR2_ENABLE (1<<0) |
| 2237 | |||
| 2238 | u32 reserved5[2]; | ||
| 2239 | u32 reserved6[PORT_MAX]; | ||
| 2240 | |||
| 2241 | /* driver version for each personality */ | ||
| 2242 | struct os_drv_ver func_os_drv_ver[E2_FUNC_MAX]; /* Offset 0x16c */ | ||
| 2243 | |||
| 2244 | /* Flag to the driver that PF's drv_info_host_addr buffer was read */ | ||
| 2245 | u32 mfw_drv_indication; | ||
| 2246 | |||
| 2247 | /* We use indication for each PF (0..3) */ | ||
| 2248 | #define MFW_DRV_IND_READ_DONE_OFFSET(_pf_) (1 << (_pf_)) | ||
| 2220 | }; | 2249 | }; |
| 2221 | 2250 | ||
| 2222 | 2251 | ||
| @@ -2848,7 +2877,7 @@ struct afex_stats { · 625 unmodified lines | |||
| 2848 | 2877 | ||
| 2849 | #define BCM_5710_FW_MAJOR_VERSION 7 | 2878 | #define BCM_5710_FW_MAJOR_VERSION 7 |
| 2850 | #define BCM_5710_FW_MINOR_VERSION 8 | 2879 | #define BCM_5710_FW_MINOR_VERSION 8 |
| 2851 | #define BCM_5710_FW_REVISION_VERSION 17 | 2880 | #define BCM_5710_FW_REVISION_VERSION 19 |
| 2852 | #define BCM_5710_FW_ENGINEERING_VERSION 0 | 2881 | #define BCM_5710_FW_ENGINEERING_VERSION 0 |
| 2853 | #define BCM_5710_FW_COMPILE_FLAGS 1 | 2882 | #define BCM_5710_FW_COMPILE_FLAGS 1 |
| 2854 | 2883 | ||
| @@ -120,7 +120,8 @@ static int debug; · 119 unmodified lines | |||
| 120 | module_param(debug, int, S_IRUGO); | 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 | static struct workqueue_struct *bnx2x_wq; |
| 124 | struct workqueue_struct *bnx2x_iov_wq; | ||
| 124 | 125 | ||
| 125 | struct bnx2x_mac_vals { | 126 | struct bnx2x_mac_vals { |
| 126 | u32 xmac_addr; | 127 | u32 xmac_addr; |
| @@ -918,7 +919,7 @@ void bnx2x_panic_dump(struct bnx2x *bp, bool disable_int) · 791 unmodified lines | |||
| 918 | u16 start = 0, end = 0; | 919 | u16 start = 0, end = 0; |
| 919 | u8 cos; | 920 | u8 cos; |
| 920 | #endif | 921 | #endif |
| 921 | if (disable_int) | 922 | if (IS_PF(bp) && disable_int) |
| 922 | bnx2x_int_disable(bp); | 923 | bnx2x_int_disable(bp); |
| 923 | 924 | ||
| 924 | bp->stats_state = STATS_STATE_DISABLED; | 925 | bp->stats_state = STATS_STATE_DISABLED; |
| @@ -929,33 +930,41 @@ void bnx2x_panic_dump(struct bnx2x *bp, bool disable_int) · 4 unmodified lines | |||
| 929 | 930 | ||
| 930 | /* Indices */ | 931 | /* Indices */ |
| 931 | /* Common */ | 932 | /* Common */ |
| 932 | BNX2X_ERR("def_idx(0x%x) def_att_idx(0x%x) attn_state(0x%x) spq_prod_idx(0x%x) next_stats_cnt(0x%x)\n", | 933 | if (IS_PF(bp)) { |
| 933 | bp->def_idx, bp->def_att_idx, bp->attn_state, | 934 | struct host_sp_status_block *def_sb = bp->def_status_blk; |
| 934 | bp->spq_prod_idx, bp->stats_counter); | 935 | int data_size, cstorm_offset; |
| 935 | BNX2X_ERR("DSB: attn bits(0x%x) ack(0x%x) id(0x%x) idx(0x%x)\n", | 936 | |
| 936 | bp->def_status_blk->atten_status_block.attn_bits, | 937 | BNX2X_ERR("def_idx(0x%x) def_att_idx(0x%x) attn_state(0x%x) spq_prod_idx(0x%x) next_stats_cnt(0x%x)\n", |
| 937 | bp->def_status_blk->atten_status_block.attn_bits_ack, | 938 | bp->def_idx, bp->def_att_idx, bp->attn_state, |
| 938 | bp->def_status_blk->atten_status_block.status_block_id, | 939 | bp->spq_prod_idx, bp->stats_counter); |
| 939 | bp->def_status_blk->atten_status_block.attn_bits_index); | 940 | BNX2X_ERR("DSB: attn bits(0x%x) ack(0x%x) id(0x%x) idx(0x%x)\n", |
| 940 | BNX2X_ERR(" def ("); | 941 | def_sb->atten_status_block.attn_bits, |
| 941 | for (i = 0; i < HC_SP_SB_MAX_INDICES; i++) | 942 | def_sb->atten_status_block.attn_bits_ack, |
| 942 | pr_cont("0x%x%s", | 943 | def_sb->atten_status_block.status_block_id, |
| 943 | bp->def_status_blk->sp_sb.index_values[i], | 944 | def_sb->atten_status_block.attn_bits_index); |
| 944 | (i == HC_SP_SB_MAX_INDICES - 1) ? ") " : " "); | 945 | BNX2X_ERR(" def ("); |
| 945 | 946 | for (i = 0; i < HC_SP_SB_MAX_INDICES; i++) | |
| 946 | for (i = 0; i < sizeof(struct hc_sp_status_block_data)/sizeof(u32); i++) | 947 | pr_cont("0x%x%s", |
| 947 | *((u32 *)&sp_sb_data + i) = REG_RD(bp, BAR_CSTRORM_INTMEM + | 948 | def_sb->sp_sb.index_values[i], |
| 948 | CSTORM_SP_STATUS_BLOCK_DATA_OFFSET(func) + | 949 | (i == HC_SP_SB_MAX_INDICES - 1) ? ") " : " "); |
| 949 | i*sizeof(u32)); | 950 | |
| 950 | 951 | data_size = sizeof(struct hc_sp_status_block_data) / | |
| 951 | pr_cont("igu_sb_id(0x%x) igu_seg_id(0x%x) pf_id(0x%x) vnic_id(0x%x) vf_id(0x%x) vf_valid (0x%x) state(0x%x)\n", | 952 | sizeof(u32); |
| 952 | sp_sb_data.igu_sb_id, | 953 | cstorm_offset = CSTORM_SP_STATUS_BLOCK_DATA_OFFSET(func); |
| 953 | sp_sb_data.igu_seg_id, | 954 | for (i = 0; i < data_size; i++) |
| 954 | sp_sb_data.p_func.pf_id, | 955 | *((u32 *)&sp_sb_data + i) = |
| 955 | sp_sb_data.p_func.vnic_id, | 956 | REG_RD(bp, BAR_CSTRORM_INTMEM + cstorm_offset + |
| 956 | sp_sb_data.p_func.vf_id, | 957 | i * sizeof(u32)); |
| 957 | sp_sb_data.p_func.vf_valid, | 958 | |
| 958 | sp_sb_data.state); | 959 | pr_cont("igu_sb_id(0x%x) igu_seg_id(0x%x) pf_id(0x%x) vnic_id(0x%x) vf_id(0x%x) vf_valid (0x%x) state(0x%x)\n", |
| 960 | sp_sb_data.igu_sb_id, | ||
| 961 | sp_sb_data.igu_seg_id, | ||
| 962 | sp_sb_data.p_func.pf_id, | ||
| 963 | sp_sb_data.p_func.vnic_id, | ||
| 964 | sp_sb_data.p_func.vf_id, | ||
| 965 | sp_sb_data.p_func.vf_valid, | ||
| 966 | sp_sb_data.state); | ||
| 967 | } | ||
| 959 | 968 | ||
| 960 | for_each_eth_queue(bp, i) { | 969 | for_each_eth_queue(bp, i) { |
| 961 | struct bnx2x_fastpath *fp = &bp->fp[i]; | 970 | struct bnx2x_fastpath *fp = &bp->fp[i]; |
| @@ -1013,6 +1022,11 @@ void bnx2x_panic_dump(struct bnx2x *bp, bool disable_int) · 51 unmodified lines | |||
| 1013 | pr_cont("0x%x%s", | 1022 | pr_cont("0x%x%s", |
| 1014 | fp->sb_index_values[j], | 1023 | fp->sb_index_values[j], |
| 1015 | (j == loop - 1) ? ")" : " "); | 1024 | (j == loop - 1) ? ")" : " "); |
| 1025 | |||
| 1026 | /* VF cannot access FW refelection for status block */ | ||
| 1027 | if (IS_VF(bp)) | ||
| 1028 | continue; | ||
| 1029 | |||
| 1016 | /* fw sb data */ | 1030 | /* fw sb data */ |
| 1017 | data_size = CHIP_IS_E1x(bp) ? | 1031 | data_size = CHIP_IS_E1x(bp) ? |
| 1018 | sizeof(struct hc_status_block_data_e1x) : | 1032 | sizeof(struct hc_status_block_data_e1x) : |
| @@ -1064,16 +1078,18 @@ void bnx2x_panic_dump(struct bnx2x *bp, bool disable_int) · 45 unmodified lines | |||
| 1064 | } | 1078 | } |
| 1065 | 1079 | ||
| 1066 | #ifdef BNX2X_STOP_ON_ERROR | 1080 | #ifdef BNX2X_STOP_ON_ERROR |
| 1067 | 1081 | if (IS_PF(bp)) { | |
| 1068 | /* event queue */ | 1082 | /* event queue */ |
| 1069 | BNX2X_ERR("eq cons %x prod %x\n", bp->eq_cons, bp->eq_prod); | 1083 | BNX2X_ERR("eq cons %x prod %x\n", bp->eq_cons, bp->eq_prod); |
| 1070 | for (i = 0; i < NUM_EQ_DESC; i++) { | 1084 | for (i = 0; i < NUM_EQ_DESC; i++) { |
| 1071 | u32 *data = (u32 *)&bp->eq_ring[i].message.data; | 1085 | u32 *data = (u32 *)&bp->eq_ring[i].message.data; |
| 1072 | 1086 | ||
| 1073 | BNX2X_ERR("event queue [%d]: header: opcode %d, error %d\n", | 1087 | BNX2X_ERR("event queue [%d]: header: opcode %d, error %d\n", |
| 1074 | i, bp->eq_ring[i].message.opcode, | 1088 | i, bp->eq_ring[i].message.opcode, |
| 1075 | bp->eq_ring[i].message.error); | 1089 | bp->eq_ring[i].message.error); |
| 1076 | BNX2X_ERR("data: %x %x %x\n", data[0], data[1], data[2]); | 1090 | BNX2X_ERR("data: %x %x %x\n", |
| 1091 | data[0], data[1], data[2]); | ||
| 1092 | } | ||
| 1077 | } | 1093 | } |
| 1078 | 1094 | ||
| 1079 | /* Rings */ | 1095 | /* Rings */ |
| @@ -1140,8 +1156,10 @@ void bnx2x_panic_dump(struct bnx2x *bp, bool disable_int) · 60 unmodified lines | |||
| 1140 | } | 1156 | } |
| 1141 | } | 1157 | } |
| 1142 | #endif | 1158 | #endif |
| 1143 | bnx2x_fw_dump(bp); | 1159 | if (IS_PF(bp)) { |
| 1144 | bnx2x_mc_assert(bp); | 1160 | bnx2x_fw_dump(bp); |
| 1161 | bnx2x_mc_assert(bp); | ||
| 1162 | } | ||
| 1145 | BNX2X_ERR("end crash dump -----------------\n"); | 1163 | BNX2X_ERR("end crash dump -----------------\n"); |
| 1146 | } | 1164 | } |
| 1147 | 1165 | ||
| @@ -1814,6 +1832,11 @@ void bnx2x_sp_event(struct bnx2x_fastpath *fp, union eth_rx_cqe *rr_cqe) · 666 unmodified lines | |||
| 1814 | drv_cmd = BNX2X_Q_CMD_EMPTY; | 1832 | drv_cmd = BNX2X_Q_CMD_EMPTY; |
| 1815 | break; | 1833 | break; |
| 1816 | 1834 | ||
| 1835 | case (RAMROD_CMD_ID_ETH_TPA_UPDATE): | ||
| 1836 | DP(BNX2X_MSG_SP, "got tpa update ramrod CID=%d\n", cid); | ||
| 1837 | drv_cmd = BNX2X_Q_CMD_UPDATE_TPA; | ||
| 1838 | break; | ||
| 1839 | |||
| 1817 | default: | 1840 | default: |
| 1818 | BNX2X_ERR("unexpected MC reply (%d) on fp[%d]\n", | 1841 | BNX2X_ERR("unexpected MC reply (%d) on fp[%d]\n", |
| 1819 | command, fp->index); | 1842 | command, fp->index); |
| @@ -1834,8 +1857,6 @@ void bnx2x_sp_event(struct bnx2x_fastpath *fp, union eth_rx_cqe *rr_cqe) · 14 unmodified lines | |||
| 1834 | #else | 1857 | #else |
| 1835 | return; | 1858 | return; |
| 1836 | #endif | 1859 | #endif |
| 1837 | /* SRIOV: reschedule any 'in_progress' operations */ | ||
| 1838 | bnx2x_iov_sp_event(bp, cid, true); | ||
| 1839 | 1860 | ||
| 1840 | smp_mb__before_atomic_inc(); | 1861 | smp_mb__before_atomic_inc(); |
| 1841 | atomic_inc(&bp->cq_spq_left); | 1862 | atomic_inc(&bp->cq_spq_left); |
| @@ -3460,10 +3481,15 @@ static void bnx2x_handle_eee_event(struct bnx2x *bp) · 1618 unmodified lines | |||
| 3460 | bnx2x_fw_command(bp, DRV_MSG_CODE_EEE_RESULTS_ACK, 0); | 3481 | bnx2x_fw_command(bp, DRV_MSG_CODE_EEE_RESULTS_ACK, 0); |
| 3461 | } | 3482 | } |
| 3462 | 3483 | ||
| 3484 | #define BNX2X_UPDATE_DRV_INFO_IND_LENGTH (20) | ||
| 3485 | #define BNX2X_UPDATE_DRV_INFO_IND_COUNT (25) | ||
| 3486 | |||
| 3463 | static void bnx2x_handle_drv_info_req(struct bnx2x *bp) | 3487 | static void bnx2x_handle_drv_info_req(struct bnx2x *bp) |
| 3464 | { | 3488 | { |
| 3465 | enum drv_info_opcode op_code; | 3489 | enum drv_info_opcode op_code; |
| 3466 | u32 drv_info_ctl = SHMEM2_RD(bp, drv_info_control); | 3490 | u32 drv_info_ctl = SHMEM2_RD(bp, drv_info_control); |
| 3491 | bool release = false; | ||
| 3492 | int wait; | ||
| 3467 | 3493 | ||
| 3468 | /* if drv_info version supported by MFW doesn't match - send NACK */ | 3494 | /* if drv_info version supported by MFW doesn't match - send NACK */ |
| 3469 | if ((drv_info_ctl & DRV_INFO_CONTROL_VER_MASK) != DRV_INFO_CUR_VER) { | 3495 | if ((drv_info_ctl & DRV_INFO_CONTROL_VER_MASK) != DRV_INFO_CUR_VER) { |
| @@ -3474,6 +3500,9 @@ static void bnx2x_handle_drv_info_req(struct bnx2x *bp) · 4 unmodified lines | |||
| 3474 | op_code = (drv_info_ctl & DRV_INFO_CONTROL_OP_CODE_MASK) >> | 3500 | op_code = (drv_info_ctl & DRV_INFO_CONTROL_OP_CODE_MASK) >> |
| 3475 | DRV_INFO_CONTROL_OP_CODE_SHIFT; | 3501 | DRV_INFO_CONTROL_OP_CODE_SHIFT; |
| 3476 | 3502 | ||
| 3503 | /* Must prevent other flows from accessing drv_info_to_mcp */ | ||
| 3504 | mutex_lock(&bp->drv_info_mutex); | ||
| 3505 | |||
| 3477 | memset(&bp->slowpath->drv_info_to_mcp, 0, | 3506 | memset(&bp->slowpath->drv_info_to_mcp, 0, |
| 3478 | sizeof(union drv_info_to_mcp)); | 3507 | sizeof(union drv_info_to_mcp)); |
| 3479 | 3508 | ||
| @@ -3490,7 +3519,7 @@ static void bnx2x_handle_drv_info_req(struct bnx2x *bp) · 10 unmodified lines | |||
| 3490 | default: | 3519 | default: |
| 3491 | /* if op code isn't supported - send NACK */ | 3520 | /* if op code isn't supported - send NACK */ |
| 3492 | bnx2x_fw_command(bp, DRV_MSG_CODE_DRV_INFO_NACK, 0); | 3521 | bnx2x_fw_command(bp, DRV_MSG_CODE_DRV_INFO_NACK, 0); |
| 3493 | return; | 3522 | goto out; |
| 3494 | } | 3523 | } |
| 3495 | 3524 | ||
| 3496 | /* if we got drv_info attn from MFW then these fields are defined in | 3525 | /* if we got drv_info attn from MFW then these fields are defined in |
| @@ -3502,6 +3531,106 @@ static void bnx2x_handle_drv_info_req(struct bnx2x *bp) · 5 unmodified lines | |||
| 3502 | U64_HI(bnx2x_sp_mapping(bp, drv_info_to_mcp))); | 3531 | U64_HI(bnx2x_sp_mapping(bp, drv_info_to_mcp))); |
| 3503 | 3532 | ||
| 3504 | bnx2x_fw_command(bp, DRV_MSG_CODE_DRV_INFO_ACK, 0); | 3533 | bnx2x_fw_command(bp, DRV_MSG_CODE_DRV_INFO_ACK, 0); |
| 3534 | |||
| 3535 | /* Since possible management wants both this and get_driver_version | ||
| 3536 | * need to wait until management notifies us it finished utilizing | ||
| 3537 | * the buffer. | ||
| 3538 | */ | ||
| 3539 | if (!SHMEM2_HAS(bp, mfw_drv_indication)) { | ||
| 3540 | DP(BNX2X_MSG_MCP, "Management does not support indication\n"); | ||
| 3541 | } else if (!bp->drv_info_mng_owner) { | ||
| 3542 | u32 bit = MFW_DRV_IND_READ_DONE_OFFSET((BP_ABS_FUNC(bp) >> 1)); | ||
| 3543 | |||
| 3544 | for (wait = 0; wait < BNX2X_UPDATE_DRV_INFO_IND_COUNT; wait++) { | ||
| 3545 | u32 indication = SHMEM2_RD(bp, mfw_drv_indication); | ||
| 3546 | |||
| 3547 | /* Management is done; need to clear indication */ | ||
| 3548 | if (indication & bit) { | ||
| 3549 | SHMEM2_WR(bp, mfw_drv_indication, | ||
| 3550 | indication & ~bit); | ||
| 3551 | release = true; | ||
| 3552 | break; | ||
| 3553 | } | ||
| 3554 | |||
| 3555 | msleep(BNX2X_UPDATE_DRV_INFO_IND_LENGTH); | ||
| 3556 | } | ||
| 3557 | } | ||
| 3558 | if (!release) { | ||
| 3559 | DP(BNX2X_MSG_MCP, "Management did not release indication\n"); | ||
| 3560 | bp->drv_info_mng_owner = true; | ||
| 3561 | } | ||
| 3562 | |||
| 3563 | out: | ||
| 3564 | mutex_unlock(&bp->drv_info_mutex); | ||
| 3565 | } | ||
| 3566 | |||
| 3567 | static u32 bnx2x_update_mng_version_utility(u8 *version, bool bnx2x_format) | ||
| 3568 | { | ||
| 3569 | u8 vals[4]; | ||
| 3570 | int i = 0; | ||
| 3571 | |||
| 3572 | if (bnx2x_format) { | ||
| 3573 | i = sscanf(version, "1.%c%hhd.%hhd.%hhd", | ||
| 3574 | &vals[0], &vals[1], &vals[2], &vals[3]); | ||
| 3575 | if (i > 0) | ||
| 3576 | vals[0] -= '0'; | ||
| 3577 | } else { | ||
| 3578 | i = sscanf(version, "%hhd.%hhd.%hhd.%hhd", | ||
| 3579 | &vals[0], &vals[1], &vals[2], &vals[3]); | ||
| 3580 | } | ||
| 3581 | |||
| 3582 | while (i < 4) | ||
| 3583 | vals[i++] = 0; | ||
| 3584 | |||
| 3585 | return (vals[0] << 24) | (vals[1] << 16) | (vals[2] << 8) | vals[3]; | ||
| 3586 | } | ||
| 3587 | |||
| 3588 | void bnx2x_update_mng_version(struct bnx2x *bp) | ||
| 3589 | { | ||
| 3590 | u32 iscsiver = DRV_VER_NOT_LOADED; | ||
| 3591 | u32 fcoever = DRV_VER_NOT_LOADED; | ||
| 3592 | u32 ethver = DRV_VER_NOT_LOADED; | ||
| 3593 | int idx = BP_FW_MB_IDX(bp); | ||
| 3594 | u8 *version; | ||
| 3595 | |||
| 3596 | if (!SHMEM2_HAS(bp, func_os_drv_ver)) | ||
| 3597 | return; | ||
| 3598 | |||
| 3599 | mutex_lock(&bp->drv_info_mutex); | ||
| 3600 | /* Must not proceed when `bnx2x_handle_drv_info_req' is feasible */ | ||
| 3601 | if (bp->drv_info_mng_owner) | ||
| 3602 | goto out; | ||
| 3603 | |||
| 3604 | if (bp->state != BNX2X_STATE_OPEN) | ||
| 3605 | goto out; | ||
| 3606 | |||
| 3607 | /* Parse ethernet driver version */ | ||
| 3608 | ethver = bnx2x_update_mng_version_utility(DRV_MODULE_VERSION, true); | ||
| 3609 | if (!CNIC_LOADED(bp)) | ||
| 3610 | goto out; | ||
| 3611 | |||
| 3612 | /* Try getting storage driver version via cnic */ | ||
| 3613 | memset(&bp->slowpath->drv_info_to_mcp, 0, | ||
| 3614 | sizeof(union drv_info_to_mcp)); | ||
| 3615 | bnx2x_drv_info_iscsi_stat(bp); | ||
| 3616 | version = bp->slowpath->drv_info_to_mcp.iscsi_stat.version; | ||
| 3617 | iscsiver = bnx2x_update_mng_version_utility(version, false); | ||
| 3618 | |||
| 3619 | memset(&bp->slowpath->drv_info_to_mcp, 0, | ||
| 3620 | sizeof(union drv_info_to_mcp)); | ||
| 3621 | bnx2x_drv_info_fcoe_stat(bp); | ||
| 3622 | version = bp->slowpath->drv_info_to_mcp.fcoe_stat.version; | ||
| 3623 | fcoever = bnx2x_update_mng_version_utility(version, false); | ||
| 3624 | |||
| 3625 | out: | ||
| 3626 | SHMEM2_WR(bp, func_os_drv_ver[idx].versions[DRV_PERS_ETHERNET], ethver); | ||
| 3627 | SHMEM2_WR(bp, func_os_drv_ver[idx].versions[DRV_PERS_ISCSI], iscsiver); | ||
| 3628 | SHMEM2_WR(bp, func_os_drv_ver[idx].versions[DRV_PERS_FCOE], fcoever); | ||
| 3629 | |||
| 3630 | mutex_unlock(&bp->drv_info_mutex); | ||
| 3631 | |||
| 3632 | DP(BNX2X_MSG_MCP, "Setting driver version: ETH [%08x] iSCSI [%08x] FCoE [%08x]\n", | ||
| 3633 | ethver, iscsiver, fcoever); | ||
| 3505 | } | 3634 | } |
| 3506 | 3635 | ||
| 3507 | static void bnx2x_dcc_event(struct bnx2x *bp, u32 dcc_event) | 3636 | static void bnx2x_dcc_event(struct bnx2x *bp, u32 dcc_event) |
| @@ -3644,10 +3773,18 @@ int bnx2x_sp_post(struct bnx2x *bp, int command, int cid, · 136 unmodified lines | |||
| 3644 | cpu_to_le32((command << SPE_HDR_CMD_ID_SHIFT) | | 3773 | cpu_to_le32((command << SPE_HDR_CMD_ID_SHIFT) | |
| 3645 | HW_CID(bp, cid)); | 3774 | HW_CID(bp, cid)); |
| 3646 | 3775 | ||
| 3647 | type = (cmd_type << SPE_HDR_CONN_TYPE_SHIFT) & SPE_HDR_CONN_TYPE; | 3776 | /* In some cases, type may already contain the func-id |
| 3648 | 3777 | * mainly in SRIOV related use cases, so we add it here only | |
| 3649 | type |= ((BP_FUNC(bp) << SPE_HDR_FUNCTION_ID_SHIFT) & | 3778 | * if it's not already set. |
| 3650 | SPE_HDR_FUNCTION_ID); | 3779 | */ |
| 3780 | if (!(cmd_type & SPE_HDR_FUNCTION_ID)) { | ||
| 3781 | type = (cmd_type << SPE_HDR_CONN_TYPE_SHIFT) & | ||
| 3782 | SPE_HDR_CONN_TYPE; | ||
| 3783 | type |= ((BP_FUNC(bp) << SPE_HDR_FUNCTION_ID_SHIFT) & | ||
| 3784 | SPE_HDR_FUNCTION_ID); | ||
| 3785 | } else { | ||
| 3786 | type = cmd_type; | ||
| 3787 | } | ||
| 3651 | 3788 | ||
| 3652 | spe->hdr.type = cpu_to_le16(type); | 3789 | spe->hdr.type = cpu_to_le16(type); |
| 3653 | 3790 | ||
| @@ -3878,10 +4015,7 @@ static void bnx2x_fan_failure(struct bnx2x *bp) · 224 unmodified lines | |||
| 3878 | * This is due to some boards consuming sufficient power when driver is | 4015 | * This is due to some boards consuming sufficient power when driver is |
| 3879 | * up to overheat if fan fails. | 4016 | * up to overheat if fan fails. |
| 3880 | */ | 4017 | */ |
| 3881 | smp_mb__before_clear_bit(); | 4018 | bnx2x_schedule_sp_rtnl(bp, BNX2X_SP_RTNL_FAN_FAILURE, 0); |
| 3882 | set_bit(BNX2X_SP_RTNL_FAN_FAILURE, &bp->sp_rtnl_state); | ||
| 3883 | smp_mb__after_clear_bit(); | ||
| 3884 | schedule_delayed_work(&bp->sp_rtnl_task, 0); | ||
| 3885 | } | 4019 | } |
| 3886 | 4020 | ||
| 3887 | static void bnx2x_attn_int_deasserted0(struct bnx2x *bp, u32 attn) | 4021 | static void bnx2x_attn_int_deasserted0(struct bnx2x *bp, u32 attn) |
| @@ -4025,7 +4159,8 @@ static void bnx2x_attn_int_deasserted3(struct bnx2x *bp, u32 attn) · 137 unmodified lines | |||
| 4025 | bnx2x_handle_drv_info_req(bp); | 4159 | bnx2x_handle_drv_info_req(bp); |
| 4026 | 4160 | ||
| 4027 | if (val & DRV_STATUS_VF_DISABLED) | 4161 | if (val & DRV_STATUS_VF_DISABLED) |
| 4028 | bnx2x_vf_handle_flr_event(bp); | 4162 | bnx2x_schedule_iov_task(bp, |
| 4163 | BNX2X_IOV_HANDLE_FLR); | ||
| 4029 | 4164 | ||
| 4030 | if ((bp->port.pmf == 0) && (val & DRV_STATUS_PMF)) | 4165 | if ((bp->port.pmf == 0) && (val & DRV_STATUS_PMF)) |
| 4031 | bnx2x_pmf_update(bp); | 4166 | bnx2x_pmf_update(bp); |
| @@ -5216,14 +5351,14 @@ static void bnx2x_eq_int(struct bnx2x *bp) · 1184 unmodified lines | |||
| 5216 | /* handle eq element */ | 5351 | /* handle eq element */ |
| 5217 | switch (opcode) { | 5352 | switch (opcode) { |
| 5218 | case EVENT_RING_OPCODE_VF_PF_CHANNEL: | 5353 | case EVENT_RING_OPCODE_VF_PF_CHANNEL: |
| 5219 | DP(BNX2X_MSG_IOV, "vf pf channel element on eq\n"); | 5354 | bnx2x_vf_mbx_schedule(bp, |
| 5220 | bnx2x_vf_mbx(bp, &elem->message.data.vf_pf_event); | 5355 | &elem->message.data.vf_pf_event); |
| 5221 | continue; | 5356 | continue; |
| 5222 | 5357 | ||
| 5223 | case EVENT_RING_OPCODE_STAT_QUERY: | 5358 | case EVENT_RING_OPCODE_STAT_QUERY: |
| 5224 | DP(BNX2X_MSG_SP | BNX2X_MSG_STATS, | 5359 | DP_AND((BNX2X_MSG_SP | BNX2X_MSG_STATS), |
| 5225 | "got statistics comp event %d\n", | 5360 | "got statistics comp event %d\n", |
| 5226 | bp->stats_comp++); | 5361 | bp->stats_comp++); |
| 5227 | /* nothing to do with stats comp */ | 5362 | /* nothing to do with stats comp */ |
| 5228 | goto next_spqe; | 5363 | goto next_spqe; |
| 5229 | 5364 | ||
| @@ -5273,6 +5408,8 @@ static void bnx2x_eq_int(struct bnx2x *bp) · 43 unmodified lines | |||
| 5273 | break; | 5408 | break; |
| 5274 | 5409 | ||
| 5275 | } else { | 5410 | } else { |
| 5411 | int cmd = BNX2X_SP_RTNL_AFEX_F_UPDATE; | ||
| 5412 | |||
| 5276 | DP(BNX2X_MSG_SP | BNX2X_MSG_MCP, | 5413 | DP(BNX2X_MSG_SP | BNX2X_MSG_MCP, |
| 5277 | "AFEX: ramrod completed FUNCTION_UPDATE\n"); | 5414 | "AFEX: ramrod completed FUNCTION_UPDATE\n"); |
| 5278 | f_obj->complete_cmd(bp, f_obj, | 5415 | f_obj->complete_cmd(bp, f_obj, |
| @@ -5282,12 +5419,7 @@ static void bnx2x_eq_int(struct bnx2x *bp) · 3 unmodified lines | |||
| 5282 | * sp_rtnl task as all Queue SP operations | 5419 | * sp_rtnl task as all Queue SP operations |
| 5283 | * should run under rtnl_lock. | 5420 | * should run under rtnl_lock. |
| 5284 | */ | 5421 | */ |
| 5285 | smp_mb__before_clear_bit(); | 5422 | bnx2x_schedule_sp_rtnl(bp, cmd, 0); |
| 5286 | set_bit(BNX2X_SP_RTNL_AFEX_F_UPDATE, | ||
| 5287 | &bp->sp_rtnl_state); | ||
| 5288 | smp_mb__after_clear_bit(); | ||
| 5289 | |||
| 5290 | schedule_delayed_work(&bp->sp_rtnl_task, 0); | ||
| 5291 | } | 5423 | } |
| 5292 | 5424 | ||
| 5293 | goto next_spqe; | 5425 | goto next_spqe; |
| @@ -5435,13 +5567,6 @@ static void bnx2x_sp_task(struct work_struct *work) · 141 unmodified lines | |||
| 5435 | le16_to_cpu(bp->def_att_idx), IGU_INT_ENABLE, 1); | 5567 | le16_to_cpu(bp->def_att_idx), IGU_INT_ENABLE, 1); |
| 5436 | } | 5568 | } |
| 5437 | 5569 | ||
| 5438 | /* must be called after the EQ processing (since eq leads to sriov | ||
| 5439 | * ramrod completion flows). | ||
| 5440 | * This flow may have been scheduled by the arrival of a ramrod | ||
| 5441 | * completion, or by the sriov code rescheduling itself. | ||
| 5442 | */ | ||
| 5443 | bnx2x_iov_sp_task(bp); | ||
| 5444 | |||
| 5445 | /* afex - poll to check if VIFSET_ACK should be sent to MFW */ | 5570 | /* afex - poll to check if VIFSET_ACK should be sent to MFW */ |
| 5446 | if (test_and_clear_bit(BNX2X_AFEX_PENDING_VIFSET_MCP_ACK, | 5571 | if (test_and_clear_bit(BNX2X_AFEX_PENDING_VIFSET_MCP_ACK, |
| 5447 | &bp->sp_state)) { | 5572 | &bp->sp_state)) { |
| @@ -6005,18 +6130,6 @@ static void bnx2x_init_internal_common(struct bnx2x *bp) · 557 unmodified lines | |||
| 6005 | { | 6130 | { |
| 6006 | int i; | 6131 | int i; |
| 6007 | 6132 | ||
| 6008 | if (IS_MF_SI(bp)) | ||
| 6009 | /* | ||
| 6010 | * In switch independent mode, the TSTORM needs to accept | ||
| 6011 | * packets that failed classification, since approximate match | ||
| 6012 | * mac addresses aren't written to NIG LLH | ||
| 6013 | */ | ||
| 6014 | REG_WR8(bp, BAR_TSTRORM_INTMEM + | ||
| 6015 | TSTORM_ACCEPT_CLASSIFY_FAILED_OFFSET, 2); | ||
| 6016 | else if (!CHIP_IS_E1(bp)) /* 57710 doesn't support MF */ | ||
| 6017 | REG_WR8(bp, BAR_TSTRORM_INTMEM + | ||
| 6018 | TSTORM_ACCEPT_CLASSIFY_FAILED_OFFSET, 0); | ||
| 6019 | |||
| 6020 | /* Zero this manually as its initialization is | 6133 | /* Zero this manually as its initialization is |
| 6021 | currently missing in the initTool */ | 6134 | currently missing in the initTool */ |
| 6022 | for (i = 0; i < (USTORM_AGG_DATA_SIZE >> 2); i++) | 6135 | for (i = 0; i < (USTORM_AGG_DATA_SIZE >> 2); i++) |
| @@ -7989,19 +8102,25 @@ void bnx2x_free_mem(struct bnx2x *bp) · 1966 unmodified lines | |||
| 7989 | 8102 | ||
| 7990 | int bnx2x_alloc_mem_cnic(struct bnx2x *bp) | 8103 | int bnx2x_alloc_mem_cnic(struct bnx2x *bp) |
| 7991 | { | 8104 | { |
| 7992 | if (!CHIP_IS_E1x(bp)) | 8105 | if (!CHIP_IS_E1x(bp)) { |
| 7993 | /* size = the status block + ramrod buffers */ | 8106 | /* size = the status block + ramrod buffers */ |
| 7994 | BNX2X_PCI_ALLOC(bp->cnic_sb.e2_sb, &bp->cnic_sb_mapping, | 8107 | bp->cnic_sb.e2_sb = BNX2X_PCI_ALLOC(&bp->cnic_sb_mapping, |
| 7995 | sizeof(struct host_hc_status_block_e2)); | 8108 | sizeof(struct host_hc_status_block_e2)); |
| 7996 | else | 8109 | if (!bp->cnic_sb.e2_sb) |
| 7997 | BNX2X_PCI_ALLOC(bp->cnic_sb.e1x_sb, | 8110 | goto alloc_mem_err; |
| 7998 | &bp->cnic_sb_mapping, | 8111 | } else { |
| 7999 | sizeof(struct | 8112 | bp->cnic_sb.e1x_sb = BNX2X_PCI_ALLOC(&bp->cnic_sb_mapping, |
| 8000 | host_hc_status_block_e1x)); | 8113 | sizeof(struct host_hc_status_block_e1x)); |
| 8114 | if (!bp->cnic_sb.e1x_sb) | ||
| 8115 | goto alloc_mem_err; | ||
| 8116 | } | ||
| 8001 | 8117 | ||
| 8002 | if (CONFIGURE_NIC_MODE(bp) && !bp->t2) | 8118 | if (CONFIGURE_NIC_MODE(bp) && !bp->t2) { |
| 8003 | /* allocate searcher T2 table, as it wasn't allocated before */ | 8119 | /* allocate searcher T2 table, as it wasn't allocated before */ |
| 8004 | BNX2X_PCI_ALLOC(bp->t2, &bp->t2_mapping, SRC_T2_SZ); | 8120 | bp->t2 = BNX2X_PCI_ALLOC(&bp->t2_mapping, SRC_T2_SZ); |
| 8121 | if (!bp->t2) | ||
| 8122 | goto alloc_mem_err; | ||
| 8123 | } | ||
| 8005 | 8124 | ||
| 8006 | /* write address to which L5 should insert its values */ | 8125 | /* write address to which L5 should insert its values */ |
| 8007 | bp->cnic_eth_dev.addr_drv_info_to_mcp = | 8126 | bp->cnic_eth_dev.addr_drv_info_to_mcp = |
| @@ -8022,15 +8141,22 @@ int bnx2x_alloc_mem(struct bnx2x *bp) · 14 unmodified lines | |||
| 8022 | { | 8141 | { |
| 8023 | int i, allocated, context_size; | 8142 | int i, allocated, context_size; |
| 8024 | 8143 | ||
| 8025 | if (!CONFIGURE_NIC_MODE(bp) && !bp->t2) | 8144 | if (!CONFIGURE_NIC_MODE(bp) && !bp->t2) { |
| 8026 | /* allocate searcher T2 table */ | 8145 | /* allocate searcher T2 table */ |
| 8027 | BNX2X_PCI_ALLOC(bp->t2, &bp->t2_mapping, SRC_T2_SZ); | 8146 | bp->t2 = BNX2X_PCI_ALLOC(&bp->t2_mapping, SRC_T2_SZ); |
| 8147 | if (!bp->t2) | ||
| 8148 | goto alloc_mem_err; | ||
| 8149 | } | ||
| 8028 | 8150 | ||
| 8029 | BNX2X_PCI_ALLOC(bp->def_status_blk, &bp->def_status_blk_mapping, | 8151 | bp->def_status_blk = BNX2X_PCI_ALLOC(&bp->def_status_blk_mapping, |
| 8030 | sizeof(struct host_sp_status_block)); | 8152 | sizeof(struct host_sp_status_block)); |
| 8153 | if (!bp->def_status_blk) | ||
| 8154 | goto alloc_mem_err; | ||
| 8031 | 8155 | ||
| 8032 | BNX2X_PCI_ALLOC(bp->slowpath, &bp->slowpath_mapping, | 8156 | bp->slowpath = BNX2X_PCI_ALLOC(&bp->slowpath_mapping, |
| 8033 | sizeof(struct bnx2x_slowpath)); | 8157 | sizeof(struct bnx2x_slowpath)); |
| 8158 | if (!bp->slowpath) | ||
| 8159 | goto alloc_mem_err; | ||
| 8034 | 8160 | ||
| 8035 | /* Allocate memory for CDU context: | 8161 | /* Allocate memory for CDU context: |
| 8036 | * This memory is allocated separately and not in the generic ILT | 8162 | * This memory is allocated separately and not in the generic ILT |
| @@ -8050,12 +8176,16 @@ int bnx2x_alloc_mem(struct bnx2x *bp) · 13 unmodified lines | |||
| 8050 | for (i = 0, allocated = 0; allocated < context_size; i++) { | 8176 | for (i = 0, allocated = 0; allocated < context_size; i++) { |
| 8051 | bp->context[i].size = min(CDU_ILT_PAGE_SZ, | 8177 | bp->context[i].size = min(CDU_ILT_PAGE_SZ, |
| 8052 | (context_size - allocated)); | 8178 | (context_size - allocated)); |
| 8053 | BNX2X_PCI_ALLOC(bp->context[i].vcxt, | 8179 | bp->context[i].vcxt = BNX2X_PCI_ALLOC(&bp->context[i].cxt_mapping, |
| 8054 | &bp->context[i].cxt_mapping, | 8180 | bp->context[i].size); |
| 8055 | bp->context[i].size); | 8181 | if (!bp->context[i].vcxt) |
| 8182 | goto alloc_mem_err; | ||
| 8056 | allocated += bp->context[i].size; | 8183 | allocated += bp->context[i].size; |
| 8057 | } | 8184 | } |
| 8058 | BNX2X_ALLOC(bp->ilt->lines, sizeof(struct ilt_line) * ILT_MAX_LINES); | 8185 | bp->ilt->lines = kcalloc(ILT_MAX_LINES, sizeof(struct ilt_line), |
| 8186 | GFP_KERNEL); | ||
| 8187 | if (!bp->ilt->lines) | ||
| 8188 | goto alloc_mem_err; | ||
| 8059 | 8189 | ||
| 8060 | if (bnx2x_ilt_mem_op(bp, ILT_MEMOP_ALLOC)) | 8190 | if (bnx2x_ilt_mem_op(bp, ILT_MEMOP_ALLOC)) |
| 8061 | goto alloc_mem_err; | 8191 | goto alloc_mem_err; |
| @@ -8064,11 +8194,15 @@ int bnx2x_alloc_mem(struct bnx2x *bp) · 2 unmodified lines | |||
| 8064 | goto alloc_mem_err; | 8194 | goto alloc_mem_err; |
| 8065 | 8195 | ||
| 8066 | /* Slow path ring */ | 8196 | /* Slow path ring */ |
| 8067 | BNX2X_PCI_ALLOC(bp->spq, &bp->spq_mapping, BCM_PAGE_SIZE); | 8197 | bp->spq = BNX2X_PCI_ALLOC(&bp->spq_mapping, BCM_PAGE_SIZE); |
| 8198 | if (!bp->spq) | ||
| 8199 | goto alloc_mem_err; | ||
| 8068 | 8200 | ||
| 8069 | /* EQ */ | 8201 | /* EQ */ |
| 8070 | BNX2X_PCI_ALLOC(bp->eq_ring, &bp->eq_mapping, | 8202 | bp->eq_ring = BNX2X_PCI_ALLOC(&bp->eq_mapping, |
| 8071 | BCM_PAGE_SIZE * NUM_EQ_PAGES); | 8203 | BCM_PAGE_SIZE * NUM_EQ_PAGES); |
| 8204 | if (!bp->eq_ring) | ||
| 8205 | goto alloc_mem_err; | ||
| 8072 | 8206 | ||
| 8073 | return 0; | 8207 | return 0; |
| 8074 | 8208 | ||
| @@ -8849,6 +8983,7 @@ static int bnx2x_func_wait_started(struct bnx2x *bp) · 774 unmodified lines | |||
| 8849 | synchronize_irq(bp->pdev->irq); | 8983 | synchronize_irq(bp->pdev->irq); |
| 8850 | 8984 | ||
| 8851 | flush_workqueue(bnx2x_wq); | 8985 | flush_workqueue(bnx2x_wq); |
| 8986 | flush_workqueue(bnx2x_iov_wq); | ||
| 8852 | 8987 | ||
| 8853 | while (bnx2x_func_get_state(bp, &bp->func_obj) != | 8988 | while (bnx2x_func_get_state(bp, &bp->func_obj) != |
| 8854 | BNX2X_F_STATE_STARTED && tout--) | 8989 | BNX2X_F_STATE_STARTED && tout--) |
| @@ -9774,6 +9909,10 @@ sp_rtnl_not_reset: · 919 unmodified lines | |||
| 9774 | bnx2x_dcbx_resume_hw_tx(bp); | 9909 | bnx2x_dcbx_resume_hw_tx(bp); |
| 9775 | } | 9910 | } |
| 9776 | 9911 | ||
| 9912 | if (test_and_clear_bit(BNX2X_SP_RTNL_GET_DRV_VERSION, | ||
| 9913 | &bp->sp_rtnl_state)) | ||
| 9914 | bnx2x_update_mng_version(bp); | ||
| 9915 | |||
| 9777 | /* work which needs rtnl lock not-taken (as it takes the lock itself and | 9916 | /* work which needs rtnl lock not-taken (as it takes the lock itself and |
| 9778 | * can be called from other contexts as well) | 9917 | * can be called from other contexts as well) |
| 9779 | */ | 9918 | */ |
| @@ -11724,12 +11863,15 @@ static int bnx2x_init_bp(struct bnx2x *bp) · 1944 unmodified lines | |||
| 11724 | 11863 | ||
| 11725 | mutex_init(&bp->port.phy_mutex); | 11864 | mutex_init(&bp->port.phy_mutex); |
| 11726 | mutex_init(&bp->fw_mb_mutex); | 11865 | mutex_init(&bp->fw_mb_mutex); |
| 11866 | mutex_init(&bp->drv_info_mutex); | ||
| 11867 | bp->drv_info_mng_owner = false; | ||
| 11727 | spin_lock_init(&bp->stats_lock); | 11868 | spin_lock_init(&bp->stats_lock); |
| 11728 | sema_init(&bp->stats_sema, 1); | 11869 | sema_init(&bp->stats_sema, 1); |
| 11729 | 11870 | ||
| 11730 | INIT_DELAYED_WORK(&bp->sp_task, bnx2x_sp_task); | 11871 | INIT_DELAYED_WORK(&bp->sp_task, bnx2x_sp_task); |
| 11731 | INIT_DELAYED_WORK(&bp->sp_rtnl_task, bnx2x_sp_rtnl_task); | 11872 | INIT_DELAYED_WORK(&bp->sp_rtnl_task, bnx2x_sp_rtnl_task); |
| 11732 | INIT_DELAYED_WORK(&bp->period_task, bnx2x_period_task); | 11873 | INIT_DELAYED_WORK(&bp->period_task, bnx2x_period_task); |
| 11874 | INIT_DELAYED_WORK(&bp->iov_task, bnx2x_iov_task); | ||
| 11733 | if (IS_PF(bp)) { | 11875 | if (IS_PF(bp)) { |
| 11734 | rc = bnx2x_get_hwinfo(bp); | 11876 | rc = bnx2x_get_hwinfo(bp); |
| 11735 | if (rc) | 11877 | if (rc) |
| @@ -11771,6 +11913,8 @@ static int bnx2x_init_bp(struct bnx2x *bp) · 35 unmodified lines | |||
| 11771 | 11913 | ||
| 11772 | bp->disable_tpa = disable_tpa; | 11914 | bp->disable_tpa = disable_tpa; |
| 11773 | bp->disable_tpa |= IS_MF_STORAGE_SD(bp) || IS_MF_FCOE_AFEX(bp); | 11915 | bp->disable_tpa |= IS_MF_STORAGE_SD(bp) || IS_MF_FCOE_AFEX(bp); |
| 11916 | /* Reduce memory usage in kdump environment by disabling TPA */ | ||
| 11917 | bp->disable_tpa |= reset_devices; | ||
| 11774 | 11918 | ||
| 11775 | /* Set TPA flags */ | 11919 | /* Set TPA flags */ |
| 11776 | if (bp->disable_tpa) { | 11920 | if (bp->disable_tpa) { |
| @@ -11942,7 +12086,7 @@ static int bnx2x_init_mcast_macs_list(struct bnx2x *bp, · 165 unmodified lines | |||
| 11942 | { | 12086 | { |
| 11943 | int mc_count = netdev_mc_count(bp->dev); | 12087 | int mc_count = netdev_mc_count(bp->dev); |
| 11944 | struct bnx2x_mcast_list_elem *mc_mac = | 12088 | struct bnx2x_mcast_list_elem *mc_mac = |
| 11945 | kzalloc(sizeof(*mc_mac) * mc_count, GFP_ATOMIC); | 12089 | kcalloc(mc_count, sizeof(*mc_mac), GFP_ATOMIC); |
| 11946 | struct netdev_hw_addr *ha; | 12090 | struct netdev_hw_addr *ha; |
| 11947 | 12091 | ||
| 11948 | if (!mc_mac) | 12092 | if (!mc_mac) |
| @@ -12064,11 +12208,8 @@ static void bnx2x_set_rx_mode(struct net_device *dev) · 115 unmodified lines | |||
| 12064 | return; | 12208 | return; |
| 12065 | } else { | 12209 | } else { |
| 12066 | /* Schedule an SP task to handle rest of change */ | 12210 | /* Schedule an SP task to handle rest of change */ |
| 12067 | DP(NETIF_MSG_IFUP, "Scheduling an Rx mode change\n"); | 12211 | bnx2x_schedule_sp_rtnl(bp, BNX2X_SP_RTNL_RX_MODE, |
| 12068 | smp_mb__before_clear_bit(); | 12212 | NETIF_MSG_IFUP); |
| 12069 | set_bit(BNX2X_SP_RTNL_RX_MODE, &bp->sp_rtnl_state); | ||
| 12070 | smp_mb__after_clear_bit(); | ||
| 12071 | schedule_delayed_work(&bp->sp_rtnl_task, 0); | ||
| 12072 | } | 12213 | } |
| 12073 | } | 12214 | } |
| 12074 | 12215 | ||
| @@ -12101,11 +12242,8 @@ void bnx2x_set_rx_mode_inner(struct bnx2x *bp) · 26 unmodified lines | |||
| 12101 | /* configuring mcast to a vf involves sleeping (when we | 12242 | /* configuring mcast to a vf involves sleeping (when we |
| 12102 | * wait for the pf's response). | 12243 | * wait for the pf's response). |
| 12103 | */ | 12244 | */ |
| 12104 | smp_mb__before_clear_bit(); | 12245 | bnx2x_schedule_sp_rtnl(bp, |
| 12105 | set_bit(BNX2X_SP_RTNL_VFPF_MCAST, | 12246 | BNX2X_SP_RTNL_VFPF_MCAST, 0); |
| 12106 | &bp->sp_rtnl_state); | ||
| 12107 | smp_mb__after_clear_bit(); | ||
| 12108 | schedule_delayed_work(&bp->sp_rtnl_task, 0); | ||
| 12109 | } | 12247 | } |
| 12110 | } | 12248 | } |
| 12111 | 12249 | ||
| @@ -13356,11 +13494,18 @@ static int __init bnx2x_init(void) · 1244 unmodified lines | |||
| 13356 | pr_err("Cannot create workqueue\n"); | 13494 | pr_err("Cannot create workqueue\n"); |
| 13357 | return -ENOMEM; | 13495 | return -ENOMEM; |
| 13358 | } | 13496 | } |
| 13497 | bnx2x_iov_wq = create_singlethread_workqueue("bnx2x_iov"); | ||
| 13498 | if (!bnx2x_iov_wq) { | ||
| 13499 | pr_err("Cannot create iov workqueue\n"); | ||
| 13500 | destroy_workqueue(bnx2x_wq); | ||
| 13501 | return -ENOMEM; | ||
| 13502 | } | ||
| 13359 | 13503 | ||
| 13360 | ret = pci_register_driver(&bnx2x_pci_driver); | 13504 | ret = pci_register_driver(&bnx2x_pci_driver); |
| 13361 | if (ret) { | 13505 | if (ret) { |
| 13362 | pr_err("Cannot register driver\n"); | 13506 | pr_err("Cannot register driver\n"); |
| 13363 | destroy_workqueue(bnx2x_wq); | 13507 | destroy_workqueue(bnx2x_wq); |
| 13508 | destroy_workqueue(bnx2x_iov_wq); | ||
| 13364 | } | 13509 | } |
| 13365 | return ret; | 13510 | return ret; |
| 13366 | } | 13511 | } |
| @@ -13372,6 +13517,7 @@ static void __exit bnx2x_cleanup(void) · 5 unmodified lines | |||
| 13372 | pci_unregister_driver(&bnx2x_pci_driver); | 13517 | pci_unregister_driver(&bnx2x_pci_driver); |
| 13373 | 13518 | ||
| 13374 | destroy_workqueue(bnx2x_wq); | 13519 | destroy_workqueue(bnx2x_wq); |
| 13520 | destroy_workqueue(bnx2x_iov_wq); | ||
| 13375 | 13521 | ||
| 13376 | /* Free globally allocated resources */ | 13522 | /* Free globally allocated resources */ |
| 13377 | list_for_each_safe(pos, q, &bnx2x_prev_list) { | 13523 | list_for_each_safe(pos, q, &bnx2x_prev_list) { |
| @@ -13765,6 +13911,7 @@ static int bnx2x_drv_ctl(struct net_device *dev, struct drv_ctl_info *ctl) · 387 unmodified lines | |||
| 13765 | REG_WR(bp, scratch_offset + i, | 13911 | REG_WR(bp, scratch_offset + i, |
| 13766 | *(host_addr + i/4)); | 13912 | *(host_addr + i/4)); |
| 13767 | } | 13913 | } |
| 13914 | bnx2x_schedule_sp_rtnl(bp, BNX2X_SP_RTNL_GET_DRV_VERSION, 0); | ||
| 13768 | break; | 13915 | break; |
| 13769 | } | 13916 | } |
| 13770 | 13917 | ||
| @@ -13782,6 +13929,7 @@ static int bnx2x_drv_ctl(struct net_device *dev, struct drv_ctl_info *ctl) · 11 unmodified lines | |||
| 13782 | cap &= ~DRV_FLAGS_CAPABILITIES_LOADED_FCOE; | 13929 | cap &= ~DRV_FLAGS_CAPABILITIES_LOADED_FCOE; |
| 13783 | SHMEM2_WR(bp, drv_capabilities_flag[idx], cap); | 13930 | SHMEM2_WR(bp, drv_capabilities_flag[idx], cap); |
| 13784 | } | 13931 | } |
| 13932 | bnx2x_schedule_sp_rtnl(bp, BNX2X_SP_RTNL_GET_DRV_VERSION, 0); | ||
| 13785 | break; | 13933 | break; |
| 13786 | } | 13934 | } |
| 13787 | 13935 | ||
| @@ -13887,6 +14035,9 @@ static int bnx2x_register_cnic(struct net_device *dev, struct cnic_ops *ops, · 99 unmodified lines | |||
| 13887 | 14035 | ||
| 13888 | rcu_assign_pointer(bp->cnic_ops, ops); | 14036 | rcu_assign_pointer(bp->cnic_ops, ops); |
| 13889 | 14037 | ||
| 14038 | /* Schedule driver to read CNIC driver versions */ | ||
| 14039 | bnx2x_schedule_sp_rtnl(bp, BNX2X_SP_RTNL_GET_DRV_VERSION, 0); | ||
| 14040 | |||
| 13890 | return 0; | 14041 | return 0; |
| 13891 | } | 14042 | } |
| 13892 | 14043 | ||
| @@ -2277,11 +2277,11 @@ static int bnx2x_set_rx_mode_e2(struct bnx2x *bp, · 2276 unmodified lines | |||
| 2277 | data->header.rule_cnt, p->rx_accept_flags, | 2277 | data->header.rule_cnt, p->rx_accept_flags, |
| 2278 | p->tx_accept_flags); | 2278 | p->tx_accept_flags); |
| 2279 | 2279 | ||
| 2280 | /* No need for an explicit memory barrier here as long we would | 2280 | /* No need for an explicit memory barrier here as long as we |
| 2281 | * need to ensure the ordering of writing to the SPQ element | 2281 | * ensure the ordering of writing to the SPQ element |
| 2282 | * and updating of the SPQ producer which involves a memory | 2282 | * and updating of the SPQ producer which involves a memory |
| 2283 | * read and we will have to put a full memory barrier there | 2283 | * read. If the memory read is removed we will have to put a |
| 2284 | * (inside bnx2x_sp_post()). | 2284 | * full memory barrier there (inside bnx2x_sp_post()). |
| 2285 | */ | 2285 | */ |
| 2286 | 2286 | ||
| 2287 | /* Send a ramrod */ | 2287 | /* Send a ramrod */ |
| @@ -2982,11 +2982,11 @@ static int bnx2x_mcast_setup_e2(struct bnx2x *bp, · 694 unmodified lines | |||
| 2982 | raw->clear_pending(raw); | 2982 | raw->clear_pending(raw); |
| 2983 | return 0; | 2983 | return 0; |
| 2984 | } else { | 2984 | } else { |
| 2985 | /* No need for an explicit memory barrier here as long we would | 2985 | /* No need for an explicit memory barrier here as long as we |
| 2986 | * need to ensure the ordering of writing to the SPQ element | 2986 | * ensure the ordering of writing to the SPQ element |
| 2987 | * and updating of the SPQ producer which involves a memory | 2987 | * and updating of the SPQ producer which involves a memory |
| 2988 | * read and we will have to put a full memory barrier there | 2988 | * read. If the memory read is removed we will have to put a |
| 2989 | * (inside bnx2x_sp_post()). | 2989 | * full memory barrier there (inside bnx2x_sp_post()). |
| 2990 | */ | 2990 | */ |
| 2991 | 2991 | ||
| 2992 | /* Send a ramrod */ | 2992 | /* Send a ramrod */ |
| @@ -3466,11 +3466,11 @@ static int bnx2x_mcast_setup_e1(struct bnx2x *bp, · 473 unmodified lines | |||
| 3466 | raw->clear_pending(raw); | 3466 | raw->clear_pending(raw); |
| 3467 | return 0; | 3467 | return 0; |
| 3468 | } else { | 3468 | } else { |
| 3469 | /* No need for an explicit memory barrier here as long we would | 3469 | /* No need for an explicit memory barrier here as long as we |
| 3470 | * need to ensure the ordering of writing to the SPQ element | 3470 | * ensure the ordering of writing to the SPQ element |
| 3471 | * and updating of the SPQ producer which involves a memory | 3471 | * and updating of the SPQ producer which involves a memory |
| 3472 | * read and we will have to put a full memory barrier there | 3472 | * read. If the memory read is removed we will have to put a |
| 3473 | * (inside bnx2x_sp_post()). | 3473 | * full memory barrier there (inside bnx2x_sp_post()). |
| 3474 | */ | 3474 | */ |
| 3475 | 3475 | ||
| 3476 | /* Send a ramrod */ | 3476 | /* Send a ramrod */ |
| @@ -4091,11 +4091,11 @@ static int bnx2x_setup_rss(struct bnx2x *bp, · 614 unmodified lines | |||
| 4091 | data->capabilities |= ETH_RSS_UPDATE_RAMROD_DATA_UPDATE_RSS_KEY; | 4091 | data->capabilities |= ETH_RSS_UPDATE_RAMROD_DATA_UPDATE_RSS_KEY; |
| 4092 | } | 4092 | } |
| 4093 | 4093 | ||
| 4094 | /* No need for an explicit memory barrier here as long we would | 4094 | /* No need for an explicit memory barrier here as long as we |
| 4095 | * need to ensure the ordering of writing to the SPQ element | 4095 | * ensure the ordering of writing to the SPQ element |
| 4096 | * and updating of the SPQ producer which involves a memory | 4096 | * and updating of the SPQ producer which involves a memory |
| 4097 | * read and we will have to put a full memory barrier there | 4097 | * read. If the memory read is removed we will have to put a |
| 4098 | * (inside bnx2x_sp_post()). | 4098 | * full memory barrier there (inside bnx2x_sp_post()). |
| 4099 | */ | 4099 | */ |
| 4100 | 4100 | ||
| 4101 | /* Send a ramrod */ | 4101 | /* Send a ramrod */ |
| @@ -4158,16 +4158,6 @@ void bnx2x_init_rss_config_obj(struct bnx2x *bp, · 56 unmodified lines | |||
| 4158 | rss_obj->config_rss = bnx2x_setup_rss; | 4158 | rss_obj->config_rss = bnx2x_setup_rss; |
| 4159 | } | 4159 | } |
| 4160 | 4160 | ||
| 4161 | int validate_vlan_mac(struct bnx2x *bp, | ||
| 4162 | struct bnx2x_vlan_mac_obj *vlan_mac) | ||
| 4163 | { | ||
| 4164 | if (!vlan_mac->get_n_elements) { | ||
| 4165 | BNX2X_ERR("vlan mac object was not intialized\n"); | ||
| 4166 | return -EINVAL; | ||
| 4167 | } | ||
| 4168 | return 0; | ||
| 4169 | } | ||
| 4170 | |||
| 4171 | /********************** Queue state object ***********************************/ | 4161 | /********************** Queue state object ***********************************/ |
| 4172 | 4162 | ||
| 4173 | /** | 4163 | /** |
| @@ -4587,13 +4577,12 @@ static inline int bnx2x_q_send_setup_e1x(struct bnx2x *bp, · 413 unmodified lines | |||
| 4587 | /* Fill the ramrod data */ | 4577 | /* Fill the ramrod data */ |
| 4588 | bnx2x_q_fill_setup_data_cmn(bp, params, rdata); | 4578 | bnx2x_q_fill_setup_data_cmn(bp, params, rdata); |
| 4589 | 4579 | ||
| 4590 | /* No need for an explicit memory barrier here as long we would | 4580 | /* No need for an explicit memory barrier here as long as we |
| 4591 | * need to ensure the ordering of writing to the SPQ element | 4581 | * ensure the ordering of writing to the SPQ element |
| 4592 | * and updating of the SPQ producer which involves a memory | 4582 | * and updating of the SPQ producer which involves a memory |
| 4593 | * read and we will have to put a full memory barrier there | 4583 | * read. If the memory read is removed we will have to put a |
| 4594 | * (inside bnx2x_sp_post()). | 4584 | * full memory barrier there (inside bnx2x_sp_post()). |
| 4595 | */ | 4585 | */ |
| 4596 | |||
| 4597 | return bnx2x_sp_post(bp, ramrod, o->cids[BNX2X_PRIMARY_CID_INDEX], | 4586 | return bnx2x_sp_post(bp, ramrod, o->cids[BNX2X_PRIMARY_CID_INDEX], |
| 4598 | U64_HI(data_mapping), | 4587 | U64_HI(data_mapping), |
| 4599 | U64_LO(data_mapping), ETH_CONNECTION_TYPE); | 4588 | U64_LO(data_mapping), ETH_CONNECTION_TYPE); |
| @@ -4615,13 +4604,12 @@ static inline int bnx2x_q_send_setup_e2(struct bnx2x *bp, · 15 unmodified lines | |||
| 4615 | bnx2x_q_fill_setup_data_cmn(bp, params, rdata); | 4604 | bnx2x_q_fill_setup_data_cmn(bp, params, rdata); |
| 4616 | bnx2x_q_fill_setup_data_e2(bp, params, rdata); | 4605 | bnx2x_q_fill_setup_data_e2(bp, params, rdata); |
| 4617 | 4606 | ||
| 4618 | /* No need for an explicit memory barrier here as long we would | 4607 | /* No need for an explicit memory barrier here as long as we |
| 4619 | * need to ensure the ordering of writing to the SPQ element | 4608 | * ensure the ordering of writing to the SPQ element |
| 4620 | * and updating of the SPQ producer which involves a memory | 4609 | * and updating of the SPQ producer which involves a memory |
| 4621 | * read and we will have to put a full memory barrier there | 4610 | * read. If the memory read is removed we will have to put a |
| 4622 | * (inside bnx2x_sp_post()). | 4611 | * full memory barrier there (inside bnx2x_sp_post()). |
| 4623 | */ | 4612 | */ |
| 4624 | |||
| 4625 | return bnx2x_sp_post(bp, ramrod, o->cids[BNX2X_PRIMARY_CID_INDEX], | 4613 | return bnx2x_sp_post(bp, ramrod, o->cids[BNX2X_PRIMARY_CID_INDEX], |
| 4626 | U64_HI(data_mapping), | 4614 | U64_HI(data_mapping), |
| 4627 | U64_LO(data_mapping), ETH_CONNECTION_TYPE); | 4615 | U64_LO(data_mapping), ETH_CONNECTION_TYPE); |
| @@ -4659,13 +4647,12 @@ static inline int bnx2x_q_send_setup_tx_only(struct bnx2x *bp, · 31 unmodified lines | |||
| 4659 | o->cids[cid_index], rdata->general.client_id, | 4647 | o->cids[cid_index], rdata->general.client_id, |
| 4660 | rdata->general.sp_client_id, rdata->general.cos); | 4648 | rdata->general.sp_client_id, rdata->general.cos); |
| 4661 | 4649 | ||
| 4662 | /* No need for an explicit memory barrier here as long we would | 4650 | /* No need for an explicit memory barrier here as long as we |
| 4663 | * need to ensure the ordering of writing to the SPQ element | 4651 | * ensure the ordering of writing to the SPQ element |
| 4664 | * and updating of the SPQ producer which involves a memory | 4652 | * and updating of the SPQ producer which involves a memory |
| 4665 | * read and we will have to put a full memory barrier there | 4653 | * read. If the memory read is removed we will have to put a |
| 4666 | * (inside bnx2x_sp_post()). | 4654 | * full memory barrier there (inside bnx2x_sp_post()). |
| 4667 | */ | 4655 | */ |
| 4668 | |||
| 4669 | return bnx2x_sp_post(bp, ramrod, o->cids[cid_index], | 4656 | return bnx2x_sp_post(bp, ramrod, o->cids[cid_index], |
| 4670 | U64_HI(data_mapping), | 4657 | U64_HI(data_mapping), |
| 4671 | U64_LO(data_mapping), ETH_CONNECTION_TYPE); | 4658 | U64_LO(data_mapping), ETH_CONNECTION_TYPE); |
| @@ -4760,13 +4747,12 @@ static inline int bnx2x_q_send_update(struct bnx2x *bp, · 88 unmodified lines | |||
| 4760 | /* Fill the ramrod data */ | 4747 | /* Fill the ramrod data */ |
| 4761 | bnx2x_q_fill_update_data(bp, o, update_params, rdata); | 4748 | bnx2x_q_fill_update_data(bp, o, update_params, rdata); |
| 4762 | 4749 | ||
| 4763 | /* No need for an explicit memory barrier here as long we would | 4750 | /* No need for an explicit memory barrier here as long as we |
| 4764 | * need to ensure the ordering of writing to the SPQ element | 4751 | * ensure the ordering of writing to the SPQ element |
| 4765 | * and updating of the SPQ producer which involves a memory | 4752 | * and updating of the SPQ producer which involves a memory |
| 4766 | * read and we will have to put a full memory barrier there | 4753 | * read. If the memory read is removed we will have to put a |
| 4767 | * (inside bnx2x_sp_post()). | 4754 | * full memory barrier there (inside bnx2x_sp_post()). |
| 4768 | */ | 4755 | */ |
| 4769 | |||
| 4770 | return bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_CLIENT_UPDATE, | 4756 | return bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_CLIENT_UPDATE, |
| 4771 | o->cids[cid_index], U64_HI(data_mapping), | 4757 | o->cids[cid_index], U64_HI(data_mapping), |
| 4772 | U64_LO(data_mapping), ETH_CONNECTION_TYPE); | 4758 | U64_LO(data_mapping), ETH_CONNECTION_TYPE); |
| @@ -4813,11 +4799,62 @@ static inline int bnx2x_q_send_activate(struct bnx2x *bp, · 40 unmodified lines | |||
| 4813 | return bnx2x_q_send_update(bp, params); | 4799 | return bnx2x_q_send_update(bp, params); |
| 4814 | } | 4800 | } |
| 4815 | 4801 | ||
| 4802 | static void bnx2x_q_fill_update_tpa_data(struct bnx2x *bp, | ||
| 4803 | struct bnx2x_queue_sp_obj *obj, | ||
| 4804 | struct bnx2x_queue_update_tpa_params *params, | ||
| 4805 | struct tpa_update_ramrod_data *data) | ||
| 4806 | { | ||
| 4807 | data->client_id = obj->cl_id; | ||
| 4808 | data->complete_on_both_clients = params->complete_on_both_clients; | ||
| 4809 | data->dont_verify_rings_pause_thr_flg = | ||
| 4810 | params->dont_verify_thr; | ||
| 4811 | data->max_agg_size = cpu_to_le16(params->max_agg_sz); | ||
| 4812 | data->max_sges_for_packet = params->max_sges_pkt; | ||
| 4813 | data->max_tpa_queues = params->max_tpa_queues; | ||
| 4814 | data->sge_buff_size = cpu_to_le16(params->sge_buff_sz); | ||
| 4815 | data->sge_page_base_hi = cpu_to_le32(U64_HI(params->sge_map)); | ||
| 4816 | data->sge_page_base_lo = cpu_to_le32(U64_LO(params->sge_map)); | ||
| 4817 | data->sge_pause_thr_high = cpu_to_le16(params->sge_pause_thr_high); | ||
| 4818 | data->sge_pause_thr_low = cpu_to_le16(params->sge_pause_thr_low); | ||
| 4819 | data->tpa_mode = params->tpa_mode; | ||
| 4820 | data->update_ipv4 = params->update_ipv4; | ||
| 4821 | data->update_ipv6 = params->update_ipv6; | ||
| 4822 | } | ||
| 4823 | |||
| 4816 | static inline int bnx2x_q_send_update_tpa(struct bnx2x *bp, | 4824 | static inline int bnx2x_q_send_update_tpa(struct bnx2x *bp, |
| 4817 | struct bnx2x_queue_state_params *params) | 4825 | struct bnx2x_queue_state_params *params) |
| 4818 | { | 4826 | { |
| 4819 | /* TODO: Not implemented yet. */ | 4827 | struct bnx2x_queue_sp_obj *o = params->q_obj; |
| 4820 | return -1; | 4828 | struct tpa_update_ramrod_data *rdata = |
| 4829 | (struct tpa_update_ramrod_data *)o->rdata; | ||
| 4830 | dma_addr_t data_mapping = o->rdata_mapping; | ||
| 4831 | struct bnx2x_queue_update_tpa_params *update_tpa_params = | ||
| 4832 | ¶ms->params.update_tpa; | ||
| 4833 | u16 type; | ||
| 4834 | |||
| 4835 | /* Clear the ramrod data */ | ||
| 4836 | memset(rdata, 0, sizeof(*rdata)); | ||
| 4837 | |||
| 4838 | /* Fill the ramrod data */ | ||
| 4839 | bnx2x_q_fill_update_tpa_data(bp, o, update_tpa_params, rdata); | ||
| 4840 | |||
| 4841 | /* Add the function id inside the type, so that sp post function | ||
| 4842 | * doesn't automatically add the PF func-id, this is required | ||
| 4843 | * for operations done by PFs on behalf of their VFs | ||
| 4844 | */ | ||
| 4845 | type = ETH_CONNECTION_TYPE | | ||
| 4846 | ((o->func_id) << SPE_HDR_FUNCTION_ID_SHIFT); | ||
| 4847 | |||
| 4848 | /* No need for an explicit memory barrier here as long as we | ||
| 4849 | * ensure the ordering of writing to the SPQ element | ||
| 4850 | * and updating of the SPQ producer which involves a memory | ||
| 4851 | * read. If the memory read is removed we will have to put a | ||
| 4852 | * full memory barrier there (inside bnx2x_sp_post()). | ||
| 4853 | */ | ||
| 4854 | return bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_TPA_UPDATE, | ||
| 4855 | o->cids[BNX2X_PRIMARY_CID_INDEX], | ||
| 4856 | U64_HI(data_mapping), | ||
| 4857 | U64_LO(data_mapping), type); | ||
| 4821 | } | 4858 | } |
| 4822 | 4859 | ||
| 4823 | static inline int bnx2x_q_send_halt(struct bnx2x *bp, | 4860 | static inline int bnx2x_q_send_halt(struct bnx2x *bp, |
| @@ -5647,6 +5684,12 @@ static inline int bnx2x_func_send_switch_update(struct bnx2x *bp, · 823 unmodified lines | |||
| 5647 | rdata->tx_switch_suspend = switch_update_params->suspend; | 5684 | rdata->tx_switch_suspend = switch_update_params->suspend; |
| 5648 | rdata->echo = SWITCH_UPDATE; | 5685 | rdata->echo = SWITCH_UPDATE; |
| 5649 | 5686 | ||
| 5687 | /* No need for an explicit memory barrier here as long as we | ||
| 5688 | * ensure the ordering of writing to the SPQ element | ||
| 5689 | * and updating of the SPQ producer which involves a memory | ||
| 5690 | * read. If the memory read is removed we will have to put a | ||
| 5691 | * full memory barrier there (inside bnx2x_sp_post()). | ||
| 5692 | */ | ||
| 5650 | return bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_FUNCTION_UPDATE, 0, | 5693 | return bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_FUNCTION_UPDATE, 0, |
| 5651 | U64_HI(data_mapping), | 5694 | U64_HI(data_mapping), |
| 5652 | U64_LO(data_mapping), NONE_CONNECTION_TYPE); | 5695 | U64_LO(data_mapping), NONE_CONNECTION_TYPE); |
| @@ -5674,11 +5717,11 @@ static inline int bnx2x_func_send_afex_update(struct bnx2x *bp, · 21 unmodified lines | |||
| 5674 | rdata->allowed_priorities = afex_update_params->allowed_priorities; | 5717 | rdata->allowed_priorities = afex_update_params->allowed_priorities; |
| 5675 | rdata->echo = AFEX_UPDATE; | 5718 | rdata->echo = AFEX_UPDATE; |
| 5676 | 5719 | ||
| 5677 | /* No need for an explicit memory barrier here as long we would | 5720 | /* No need for an explicit memory barrier here as long as we |
| 5678 | * need to ensure the ordering of writing to the SPQ element | 5721 | * ensure the ordering of writing to the SPQ element |
| 5679 | * and updating of the SPQ producer which involves a memory | 5722 | * and updating of the SPQ producer which involves a memory |
| 5680 | * read and we will have to put a full memory barrier there | 5723 | * read. If the memory read is removed we will have to put a |
| 5681 | * (inside bnx2x_sp_post()). | 5724 | * full memory barrier there (inside bnx2x_sp_post()). |
| 5682 | */ | 5725 | */ |
| 5683 | DP(BNX2X_MSG_SP, | 5726 | DP(BNX2X_MSG_SP, |
| 5684 | "afex: sending func_update vif_id 0x%x dvlan 0x%x prio 0x%x\n", | 5727 | "afex: sending func_update vif_id 0x%x dvlan 0x%x prio 0x%x\n", |
| @@ -5763,6 +5806,12 @@ static inline int bnx2x_func_send_tx_start(struct bnx2x *bp, · 78 unmodified lines | |||
| 5763 | rdata->traffic_type_to_priority_cos[i] = | 5806 | rdata->traffic_type_to_priority_cos[i] = |
| 5764 | tx_start_params->traffic_type_to_priority_cos[i]; | 5807 | tx_start_params->traffic_type_to_priority_cos[i]; |
| 5765 | 5808 | ||
| 5809 | /* No need for an explicit memory barrier here as long as we | ||
| 5810 | * ensure the ordering of writing to the SPQ element | ||
| 5811 | * and updating of the SPQ producer which involves a memory | ||
| 5812 | * read. If the memory read is removed we will have to put a | ||
| 5813 | * full memory barrier there (inside bnx2x_sp_post()). | ||
| 5814 | */ | ||
| 5766 | return bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_START_TRAFFIC, 0, | 5815 | return bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_START_TRAFFIC, 0, |
| 5767 | U64_HI(data_mapping), | 5816 | U64_HI(data_mapping), |
| 5768 | U64_LO(data_mapping), NONE_CONNECTION_TYPE); | 5817 | U64_LO(data_mapping), NONE_CONNECTION_TYPE); |
| @@ -893,6 +893,24 @@ struct bnx2x_queue_update_params { · 892 unmodified lines | |||
| 893 | u8 cid_index; | 893 | u8 cid_index; |
| 894 | }; | 894 | }; |
| 895 | 895 | ||
| 896 | struct bnx2x_queue_update_tpa_params { | ||
| 897 | dma_addr_t sge_map; | ||
| 898 | u8 update_ipv4; | ||
| 899 | u8 update_ipv6; | ||
| 900 | u8 max_tpa_queues; | ||
| 901 | u8 max_sges_pkt; | ||
| 902 | u8 complete_on_both_clients; | ||
| 903 | u8 dont_verify_thr; | ||
| 904 | u8 tpa_mode; | ||
| 905 | u8 _pad; | ||
| 906 | |||
| 907 | u16 sge_buff_sz; | ||
| 908 | u16 max_agg_sz; | ||
| 909 | |||
| 910 | u16 sge_pause_thr_low; | ||
| 911 | u16 sge_pause_thr_high; | ||
| 912 | }; | ||
| 913 | |||
| 896 | struct rxq_pause_params { | 914 | struct rxq_pause_params { |
| 897 | u16 bd_th_lo; | 915 | u16 bd_th_lo; |
| 898 | u16 bd_th_hi; | 916 | u16 bd_th_hi; |
| @@ -987,6 +1005,7 @@ struct bnx2x_queue_state_params { · 88 unmodified lines | |||
| 987 | /* Params according to the current command */ | 1005 | /* Params according to the current command */ |
| 988 | union { | 1006 | union { |
| 989 | struct bnx2x_queue_update_params update; | 1007 | struct bnx2x_queue_update_params update; |
| 1008 | struct bnx2x_queue_update_tpa_params update_tpa; | ||
| 990 | struct bnx2x_queue_setup_params setup; | 1009 | struct bnx2x_queue_setup_params setup; |
| 991 | struct bnx2x_queue_init_params init; | 1010 | struct bnx2x_queue_init_params init; |
| 992 | struct bnx2x_queue_setup_tx_only_params tx_only; | 1011 | struct bnx2x_queue_setup_tx_only_params tx_only; |
| @@ -1403,6 +1422,4 @@ int bnx2x_config_rss(struct bnx2x *bp, · 410 unmodified lines | |||
| 1403 | void bnx2x_get_rss_ind_table(struct bnx2x_rss_config_obj *rss_obj, | 1422 | void bnx2x_get_rss_ind_table(struct bnx2x_rss_config_obj *rss_obj, |
| 1404 | u8 *ind_table); | 1423 | u8 *ind_table); |
| 1405 | 1424 | ||
| 1406 | int validate_vlan_mac(struct bnx2x *bp, | ||
| 1407 | struct bnx2x_vlan_mac_obj *vlan_mac); | ||
| 1408 | #endif /* BNX2X_SP_VERBS */ | 1425 | #endif /* BNX2X_SP_VERBS */ |
| @@ -102,82 +102,22 @@ static void bnx2x_vf_igu_ack_sb(struct bnx2x *bp, struct bnx2x_virtf *vf, · 101 unmodified lines | |||
| 102 | mmiowb(); | 102 | mmiowb(); |
| 103 | barrier(); | 103 | barrier(); |
| 104 | } | 104 | } |
| 105 | /* VFOP - VF slow-path operation support */ | ||
| 106 | 105 | ||
| 107 | #define BNX2X_VFOP_FILTER_ADD_CNT_MAX 0x10000 | 106 | static bool bnx2x_validate_vf_sp_objs(struct bnx2x *bp, |
| 107 | struct bnx2x_virtf *vf, | ||
| 108 | bool print_err) | ||
| 109 | { | ||
| 110 | if (!bnx2x_leading_vfq(vf, sp_initialized)) { | ||
| 111 | if (print_err) | ||
| 112 | BNX2X_ERR("Slowpath objects not yet initialized!\n"); | ||
| 113 | else | ||
| 114 | DP(BNX2X_MSG_IOV, "Slowpath objects not yet initialized!\n"); | ||
| 115 | return false; | ||
| 116 | } | ||
| 117 | return true; | ||
| 118 | } | ||
| 108 | 119 | ||
| 109 | /* VFOP operations states */ | 120 | /* VFOP operations states */ |
| 110 | enum bnx2x_vfop_qctor_state { | ||
| 111 | BNX2X_VFOP_QCTOR_INIT, | ||
| 112 | BNX2X_VFOP_QCTOR_SETUP, | ||
| 113 | BNX2X_VFOP_QCTOR_INT_EN | ||
| 114 | }; | ||
| 115 | |||
| 116 | enum bnx2x_vfop_qdtor_state { | ||
| 117 | BNX2X_VFOP_QDTOR_HALT, | ||
| 118 | BNX2X_VFOP_QDTOR_TERMINATE, | ||
| 119 | BNX2X_VFOP_QDTOR_CFCDEL, | ||
| 120 | BNX2X_VFOP_QDTOR_DONE | ||
| 121 | }; | ||
| 122 | |||
| 123 | enum bnx2x_vfop_vlan_mac_state { | ||
| 124 | BNX2X_VFOP_VLAN_MAC_CONFIG_SINGLE, | ||
| 125 | BNX2X_VFOP_VLAN_MAC_CLEAR, | ||
| 126 | BNX2X_VFOP_VLAN_MAC_CHK_DONE, | ||
| 127 | BNX2X_VFOP_MAC_CONFIG_LIST, | ||
| 128 | BNX2X_VFOP_VLAN_CONFIG_LIST, | ||
| 129 | BNX2X_VFOP_VLAN_CONFIG_LIST_0 | ||
| 130 | }; | ||
| 131 | |||
| 132 | enum bnx2x_vfop_qsetup_state { | ||
| 133 | BNX2X_VFOP_QSETUP_CTOR, | ||
| 134 | BNX2X_VFOP_QSETUP_VLAN0, | ||
| 135 | BNX2X_VFOP_QSETUP_DONE | ||
| 136 | }; | ||
| 137 | |||
| 138 | enum bnx2x_vfop_mcast_state { | ||
| 139 | BNX2X_VFOP_MCAST_DEL, | ||
| 140 | BNX2X_VFOP_MCAST_ADD, | ||
| 141 | BNX2X_VFOP_MCAST_CHK_DONE | ||
| 142 | }; | ||
| 143 | enum bnx2x_vfop_qflr_state { | ||
| 144 | BNX2X_VFOP_QFLR_CLR_VLAN, | ||
| 145 | BNX2X_VFOP_QFLR_CLR_MAC, | ||
| 146 | BNX2X_VFOP_QFLR_TERMINATE, | ||
| 147 | BNX2X_VFOP_QFLR_DONE | ||
| 148 | }; | ||
| 149 | |||
| 150 | enum bnx2x_vfop_flr_state { | ||
| 151 | BNX2X_VFOP_FLR_QUEUES, | ||
| 152 | BNX2X_VFOP_FLR_HW | ||
| 153 | }; | ||
| 154 | |||
| 155 | enum bnx2x_vfop_close_state { | ||
| 156 | BNX2X_VFOP_CLOSE_QUEUES, | ||
| 157 | BNX2X_VFOP_CLOSE_HW | ||
| 158 | }; | ||
| 159 | |||
| 160 | enum bnx2x_vfop_rxmode_state { | ||
| 161 | BNX2X_VFOP_RXMODE_CONFIG, | ||
| 162 | BNX2X_VFOP_RXMODE_DONE | ||
| 163 | }; | ||
| 164 | |||
| 165 | enum bnx2x_vfop_qteardown_state { | ||
| 166 | BNX2X_VFOP_QTEARDOWN_RXMODE, | ||
| 167 | BNX2X_VFOP_QTEARDOWN_CLR_VLAN, | ||
| 168 | BNX2X_VFOP_QTEARDOWN_CLR_MAC, | ||
| 169 | BNX2X_VFOP_QTEARDOWN_CLR_MCAST, | ||
| 170 | BNX2X_VFOP_QTEARDOWN_QDTOR, | ||
| 171 | BNX2X_VFOP_QTEARDOWN_DONE | ||
| 172 | }; | ||
| 173 | |||
| 174 | enum bnx2x_vfop_rss_state { | ||
| 175 | BNX2X_VFOP_RSS_CONFIG, | ||
| 176 | BNX2X_VFOP_RSS_DONE | ||
| 177 | }; | ||
| 178 | |||
| 179 | #define bnx2x_vfop_reset_wq(vf) atomic_set(&vf->op_in_progress, 0) | ||
| 180 | |||
| 181 | void bnx2x_vfop_qctor_dump_tx(struct bnx2x *bp, struct bnx2x_virtf *vf, | 121 | void bnx2x_vfop_qctor_dump_tx(struct bnx2x *bp, struct bnx2x_virtf *vf, |
| 182 | struct bnx2x_queue_init_params *init_params, | 122 | struct bnx2x_queue_init_params *init_params, |
| 183 | struct bnx2x_queue_setup_params *setup_params, | 123 | struct bnx2x_queue_setup_params *setup_params, |
| @@ -221,7 +161,7 @@ void bnx2x_vfop_qctor_dump_rx(struct bnx2x *bp, struct bnx2x_virtf *vf, · 37 unmodified lines | |||
| 221 | void bnx2x_vfop_qctor_prep(struct bnx2x *bp, | 161 | void bnx2x_vfop_qctor_prep(struct bnx2x *bp, |
| 222 | struct bnx2x_virtf *vf, | 162 | struct bnx2x_virtf *vf, |
| 223 | struct bnx2x_vf_queue *q, | 163 | struct bnx2x_vf_queue *q, |
| 224 | struct bnx2x_vfop_qctor_params *p, | 164 | struct bnx2x_vf_queue_construct_params *p, |
| 225 | unsigned long q_type) | 165 | unsigned long q_type) |
| 226 | { | 166 | { |
| 227 | struct bnx2x_queue_init_params *init_p = &p->qstate.params.init; | 167 | struct bnx2x_queue_init_params *init_p = &p->qstate.params.init; |
| @@ -290,191 +230,85 @@ void bnx2x_vfop_qctor_prep(struct bnx2x *bp, · 62 unmodified lines | |||
| 290 | } | 230 | } |
| 291 | } | 231 | } |
| 292 | 232 | ||
| 293 | /* VFOP queue construction */ | 233 | static int bnx2x_vf_queue_create(struct bnx2x *bp, |
| 294 | static void bnx2x_vfop_qctor(struct bnx2x *bp, struct bnx2x_virtf *vf) | 234 | struct bnx2x_virtf *vf, int qid, |
| 235 | struct bnx2x_vf_queue_construct_params *qctor) | ||
| 295 | { | 236 | { |
| 296 | struct bnx2x_vfop *vfop = bnx2x_vfop_cur(bp, vf); | 237 | struct bnx2x_queue_state_params *q_params; |
| 297 | struct bnx2x_vfop_args_qctor *args = &vfop->args.qctor; | 238 | int rc = 0; |
| 298 | struct bnx2x_queue_state_params *q_params = &vfop->op_p->qctor.qstate; | ||
| 299 | enum bnx2x_vfop_qctor_state state = vfop->state; | ||
| 300 | |||
| 301 | bnx2x_vfop_reset_wq(vf); | ||
| 302 | |||
| 303 | if (vfop->rc < 0) | ||
| 304 | goto op_err; | ||
| 305 | |||
| 306 | DP(BNX2X_MSG_IOV, "vf[%d] STATE: %d\n", vf->abs_vfid, state); | ||
| 307 | |||
| 308 | switch (state) { | ||
| 309 | case BNX2X_VFOP_QCTOR_INIT: | ||
| 310 | |||
| 311 | /* has this queue already been opened? */ | ||
| 312 | if (bnx2x_get_q_logical_state(bp, q_params->q_obj) == | ||
| 313 | BNX2X_Q_LOGICAL_STATE_ACTIVE) { | ||
| 314 | DP(BNX2X_MSG_IOV, | ||
| 315 | "Entered qctor but queue was already up. Aborting gracefully\n"); | ||
| 316 | goto op_done; | ||
| 317 | } | ||
| 318 | |||
| 319 | /* next state */ | ||
| 320 | vfop->state = BNX2X_VFOP_QCTOR_SETUP; | ||
| 321 | |||
| 322 | q_params->cmd = BNX2X_Q_CMD_INIT; | ||
| 323 | vfop->rc = bnx2x_queue_state_change(bp, q_params); | ||
| 324 | |||
| 325 | bnx2x_vfop_finalize(vf, vfop->rc, VFOP_CONT); | ||
| 326 | |||
| 327 | case BNX2X_VFOP_QCTOR_SETUP: | ||
| 328 | /* next state */ | ||
| 329 | vfop->state = BNX2X_VFOP_QCTOR_INT_EN; | ||
| 330 | |||
| 331 | /* copy pre-prepared setup params to the queue-state params */ | ||
| 332 | vfop->op_p->qctor.qstate.params.setup = | ||
| 333 | vfop->op_p->qctor.prep_qsetup; | ||
| 334 | |||
| 335 | q_params->cmd = BNX2X_Q_CMD_SETUP; | ||
| 336 | vfop->rc = bnx2x_queue_state_change(bp, q_params); | ||
| 337 | 239 | ||
| 338 | bnx2x_vfop_finalize(vf, vfop->rc, VFOP_CONT); | 240 | DP(BNX2X_MSG_IOV, "vf[%d:%d]\n", vf->abs_vfid, qid); |
| 339 | 241 | ||
| 340 | case BNX2X_VFOP_QCTOR_INT_EN: | 242 | /* Prepare ramrod information */ |
| 243 | q_params = &qctor->qstate; | ||
| 244 | q_params->q_obj = &bnx2x_vfq(vf, qid, sp_obj); | ||
| 245 | set_bit(RAMROD_COMP_WAIT, &q_params->ramrod_flags); | ||
| 341 | 246 | ||
| 342 | /* enable interrupts */ | 247 | if (bnx2x_get_q_logical_state(bp, q_params->q_obj) == |
| 343 | bnx2x_vf_igu_ack_sb(bp, vf, vf_igu_sb(vf, args->sb_idx), | 248 | BNX2X_Q_LOGICAL_STATE_ACTIVE) { |
| 344 | USTORM_ID, 0, IGU_INT_ENABLE, 0); | 249 | DP(BNX2X_MSG_IOV, "queue was already up. Aborting gracefully\n"); |
| 345 | goto op_done; | 250 | goto out; |
| 346 | default: | ||
| 347 | bnx2x_vfop_default(state); | ||
| 348 | } | 251 | } |
| 349 | op_err: | ||
| 350 | BNX2X_ERR("QCTOR[%d:%d] error: cmd %d, rc %d\n", | ||
| 351 | vf->abs_vfid, args->qid, q_params->cmd, vfop->rc); | ||
| 352 | op_done: | ||
| 353 | bnx2x_vfop_end(bp, vf, vfop); | ||
| 354 | op_pending: | ||
| 355 | return; | ||
| 356 | } | ||
| 357 | 252 | ||
| 358 | static int bnx2x_vfop_qctor_cmd(struct bnx2x *bp, | 253 | /* Run Queue 'construction' ramrods */ |
| 359 | struct bnx2x_virtf *vf, | 254 | q_params->cmd = BNX2X_Q_CMD_INIT; |
| 360 | struct bnx2x_vfop_cmd *cmd, | 255 | rc = bnx2x_queue_state_change(bp, q_params); |
| 361 | int qid) | 256 | if (rc) |
| 362 | { | 257 | goto out; |
| 363 | struct bnx2x_vfop *vfop = bnx2x_vfop_add(bp, vf); | ||
| 364 | |||
| 365 | if (vfop) { | ||
| 366 | vf->op_params.qctor.qstate.q_obj = &bnx2x_vfq(vf, qid, sp_obj); | ||
| 367 | 258 | ||
| 368 | vfop->args.qctor.qid = qid; | 259 | memcpy(&q_params->params.setup, &qctor->prep_qsetup, |
| 369 | vfop->args.qctor.sb_idx = bnx2x_vfq(vf, qid, sb_idx); | 260 | sizeof(struct bnx2x_queue_setup_params)); |
| 261 | q_params->cmd = BNX2X_Q_CMD_SETUP; | ||
| 262 | rc = bnx2x_queue_state_change(bp, q_params); | ||
| 263 | if (rc) | ||
| 264 | goto out; | ||
| 370 | 265 | ||
| 371 | bnx2x_vfop_opset(BNX2X_VFOP_QCTOR_INIT, | 266 | /* enable interrupts */ |
| 372 | bnx2x_vfop_qctor, cmd->done); | 267 | bnx2x_vf_igu_ack_sb(bp, vf, vf_igu_sb(vf, bnx2x_vfq(vf, qid, sb_idx)), |
| 373 | return bnx2x_vfop_transition(bp, vf, bnx2x_vfop_qctor, | 268 | USTORM_ID, 0, IGU_INT_ENABLE, 0); |
| 374 | cmd->block); | 269 | out: |
| 375 | } | 270 | return rc; |
| 376 | return -ENOMEM; | ||
| 377 | } | 271 | } |
| 378 | 272 | ||
| 379 | /* VFOP queue destruction */ | 273 | static int bnx2x_vf_queue_destroy(struct bnx2x *bp, struct bnx2x_virtf *vf, |
| 380 | static void bnx2x_vfop_qdtor(struct bnx2x *bp, struct bnx2x_virtf *vf) | 274 | int qid) |
| 381 | { | 275 | { |
| 382 | struct bnx2x_vfop *vfop = bnx2x_vfop_cur(bp, vf); | 276 | enum bnx2x_queue_cmd cmds[] = {BNX2X_Q_CMD_HALT, |
| 383 | struct bnx2x_vfop_args_qdtor *qdtor = &vfop->args.qdtor; | 277 | BNX2X_Q_CMD_TERMINATE, |
| 384 | struct bnx2x_queue_state_params *q_params = &vfop->op_p->qctor.qstate; | 278 | BNX2X_Q_CMD_CFC_DEL}; |
| 385 | enum bnx2x_vfop_qdtor_state state = vfop->state; | 279 | struct bnx2x_queue_state_params q_params; |
| 386 | 280 | int rc, i; | |
| 387 | bnx2x_vfop_reset_wq(vf); | ||
| 388 | |||
| 389 | if (vfop->rc < 0) | ||
| 390 | goto op_err; | ||
| 391 | |||
| 392 | DP(BNX2X_MSG_IOV, "vf[%d] STATE: %d\n", vf->abs_vfid, state); | ||
| 393 | |||
| 394 | switch (state) { | ||
| 395 | case BNX2X_VFOP_QDTOR_HALT: | ||
| 396 | |||
| 397 | /* has this queue already been stopped? */ | ||
| 398 | if (bnx2x_get_q_logical_state(bp, q_params->q_obj) == | ||
| 399 | BNX2X_Q_LOGICAL_STATE_STOPPED) { | ||
| 400 | DP(BNX2X_MSG_IOV, | ||
| 401 | "Entered qdtor but queue was already stopped. Aborting gracefully\n"); | ||
| 402 | |||
| 403 | /* next state */ | ||
| 404 | vfop->state = BNX2X_VFOP_QDTOR_DONE; | ||
| 405 | |||
| 406 | bnx2x_vfop_finalize(vf, vfop->rc, VFOP_CONT); | ||
| 407 | } | ||
| 408 | |||
| 409 | /* next state */ | ||
| 410 | vfop->state = BNX2X_VFOP_QDTOR_TERMINATE; | ||
| 411 | |||
| 412 | q_params->cmd = BNX2X_Q_CMD_HALT; | ||
| 413 | vfop->rc = bnx2x_queue_state_change(bp, q_params); | ||
| 414 | |||
| 415 | bnx2x_vfop_finalize(vf, vfop->rc, VFOP_CONT); | ||
| 416 | |||
| 417 | case BNX2X_VFOP_QDTOR_TERMINATE: | ||
| 418 | /* next state */ | ||
| 419 | vfop->state = BNX2X_VFOP_QDTOR_CFCDEL; | ||
| 420 | |||
| 421 | q_params->cmd = BNX2X_Q_CMD_TERMINATE; | ||
| 422 | vfop->rc = bnx2x_queue_state_change(bp, q_params); | ||
| 423 | 281 | ||
| 424 | bnx2x_vfop_finalize(vf, vfop->rc, VFOP_CONT); | 282 | DP(BNX2X_MSG_IOV, "vf[%d]\n", vf->abs_vfid); |
| 425 | 283 | ||
| 426 | case BNX2X_VFOP_QDTOR_CFCDEL: | 284 | /* Prepare ramrod information */ |
| 427 | /* next state */ | 285 | memset(&q_params, 0, sizeof(struct bnx2x_queue_state_params)); |
| 428 | vfop->state = BNX2X_VFOP_QDTOR_DONE; | 286 | q_params.q_obj = &bnx2x_vfq(vf, qid, sp_obj); |
| 287 | set_bit(RAMROD_COMP_WAIT, &q_params.ramrod_flags); | ||
| 429 | 288 | ||
| 430 | q_params->cmd = BNX2X_Q_CMD_CFC_DEL; | 289 | if (bnx2x_get_q_logical_state(bp, q_params.q_obj) == |
| 431 | vfop->rc = bnx2x_queue_state_change(bp, q_params); | 290 | BNX2X_Q_LOGICAL_STATE_STOPPED) { |
| 291 | DP(BNX2X_MSG_IOV, "queue was already stopped. Aborting gracefully\n"); | ||
| 292 | goto out; | ||
| 293 | } | ||
| 432 | 294 | ||
| 433 | bnx2x_vfop_finalize(vf, vfop->rc, VFOP_DONE); | 295 | /* Run Queue 'destruction' ramrods */ |
| 434 | op_err: | 296 | for (i = 0; i < ARRAY_SIZE(cmds); i++) { |
| 435 | BNX2X_ERR("QDTOR[%d:%d] error: cmd %d, rc %d\n", | 297 | q_params.cmd = cmds[i]; |
| 436 | vf->abs_vfid, qdtor->qid, q_params->cmd, vfop->rc); | 298 | rc = bnx2x_queue_state_change(bp, &q_params); |
| 437 | op_done: | 299 | if (rc) { |
| 438 | case BNX2X_VFOP_QDTOR_DONE: | 300 | BNX2X_ERR("Failed to run Queue command %d\n", cmds[i]); |
| 439 | /* invalidate the context */ | 301 | return rc; |
| 440 | if (qdtor->cxt) { | ||
| 441 | qdtor->cxt->ustorm_ag_context.cdu_usage = 0; | ||
| 442 | qdtor->cxt->xstorm_ag_context.cdu_reserved = 0; | ||
| 443 | } | 302 | } |
| 444 | bnx2x_vfop_end(bp, vf, vfop); | ||
| 445 | return; | ||
| 446 | default: | ||
| 447 | bnx2x_vfop_default(state); | ||
| 448 | } | 303 | } |
| 449 | op_pending: | 304 | out: |
| 450 | return; | 305 | /* Clean Context */ |
| 451 | } | 306 | if (bnx2x_vfq(vf, qid, cxt)) { |
| 452 | 307 | bnx2x_vfq(vf, qid, cxt)->ustorm_ag_context.cdu_usage = 0; | |
| 453 | static int bnx2x_vfop_qdtor_cmd(struct bnx2x *bp, | 308 | bnx2x_vfq(vf, qid, cxt)->xstorm_ag_context.cdu_reserved = 0; |
| 454 | struct bnx2x_virtf *vf, | ||
| 455 | struct bnx2x_vfop_cmd *cmd, | ||
| 456 | int qid) | ||
| 457 | { | ||
| 458 | struct bnx2x_vfop *vfop = bnx2x_vfop_add(bp, vf); | ||
| 459 | |||
| 460 | if (vfop) { | ||
| 461 | struct bnx2x_queue_state_params *qstate = | ||
| 462 | &vf->op_params.qctor.qstate; | ||
| 463 | |||
| 464 | memset(qstate, 0, sizeof(*qstate)); | ||
| 465 | qstate->q_obj = &bnx2x_vfq(vf, qid, sp_obj); | ||
| 466 | |||
| 467 | vfop->args.qdtor.qid = qid; | ||
| 468 | vfop->args.qdtor.cxt = bnx2x_vfq(vf, qid, cxt); | ||
| 469 | |||
| 470 | bnx2x_vfop_opset(BNX2X_VFOP_QDTOR_HALT, | ||
| 471 | bnx2x_vfop_qdtor, cmd->done); | ||
| 472 | return bnx2x_vfop_transition(bp, vf, bnx2x_vfop_qdtor, | ||
| 473 | cmd->block); | ||
| 474 | } else { | ||
| 475 | BNX2X_ERR("VF[%d] failed to add a vfop\n", vf->abs_vfid); | ||
| 476 | return -ENOMEM; | ||
| 477 | } | 309 | } |
| 310 | |||
| 311 | return 0; | ||
| 478 | } | 312 | } |
| 479 | 313 | ||
| 480 | static void | 314 | static void |
| @@ -496,751 +330,293 @@ bnx2x_vf_set_igu_info(struct bnx2x *bp, u8 igu_sb_id, u8 abs_vfid) · 15 unmodified lines | |||
| 496 | BP_VFDB(bp)->vf_sbs_pool++; | 330 | BP_VFDB(bp)->vf_sbs_pool++; |
| 497 | } | 331 | } |
| 498 | 332 | ||
| 499 | /* VFOP MAC/VLAN helpers */ | 333 | static inline void bnx2x_vf_vlan_credit(struct bnx2x *bp, |
| 500 | static inline void bnx2x_vfop_credit(struct bnx2x *bp, | 334 | struct bnx2x_vlan_mac_obj *obj, |
| 501 | struct bnx2x_vfop *vfop, | 335 | atomic_t *counter) |
| 502 | struct bnx2x_vlan_mac_obj *obj) | ||
| 503 | { | 336 | { |
| 504 | struct bnx2x_vfop_args_filters *args = &vfop->args.filters; | 337 | struct list_head *pos; |
| 505 | 338 | int read_lock; | |
| 506 | /* update credit only if there is no error | 339 | int cnt = 0; |
| 507 | * and a valid credit counter | ||
| 508 | */ | ||
| 509 | if (!vfop->rc && args->credit) { | ||
| 510 | struct list_head *pos; | ||
| 511 | int read_lock; | ||
| 512 | int cnt = 0; | ||
| 513 | |||
| 514 | read_lock = bnx2x_vlan_mac_h_read_lock(bp, obj); | ||
| 515 | if (read_lock) | ||
| 516 | DP(BNX2X_MSG_SP, "Failed to take vlan mac read head; continuing anyway\n"); | ||
| 517 | 340 | ||
| 518 | list_for_each(pos, &obj->head) | 341 | read_lock = bnx2x_vlan_mac_h_read_lock(bp, obj); |
| 519 | cnt++; | 342 | if (read_lock) |
| 343 | DP(BNX2X_MSG_SP, "Failed to take vlan mac read head; continuing anyway\n"); | ||
| 520 | 344 | ||
| 521 | if (!read_lock) | 345 | list_for_each(pos, &obj->head) |
| 522 | bnx2x_vlan_mac_h_read_unlock(bp, obj); | 346 | cnt++; |
| 523 | 347 | ||
| 524 | atomic_set(args->credit, cnt); | 348 | if (!read_lock) |
| 525 | } | 349 | bnx2x_vlan_mac_h_read_unlock(bp, obj); |
| 526 | } | ||
| 527 | |||
| 528 | static int bnx2x_vfop_set_user_req(struct bnx2x *bp, | ||
| 529 | struct bnx2x_vfop_filter *pos, | ||
| 530 | struct bnx2x_vlan_mac_data *user_req) | ||
| 531 | { | ||
| 532 | user_req->cmd = pos->add ? BNX2X_VLAN_MAC_ADD : | ||
| 533 | BNX2X_VLAN_MAC_DEL; | ||
| 534 | 350 | ||
| 535 | switch (pos->type) { | 351 | atomic_set(counter, cnt); |
| 536 | case BNX2X_VFOP_FILTER_MAC: | ||
| 537 | memcpy(user_req->u.mac.mac, pos->mac, ETH_ALEN); | ||
| 538 | break; | ||
| 539 | case BNX2X_VFOP_FILTER_VLAN: | ||
| 540 | user_req->u.vlan.vlan = pos->vid; | ||
| 541 | break; | ||
| 542 | default: | ||
| 543 | BNX2X_ERR("Invalid filter type, skipping\n"); | ||
| 544 | return 1; | ||
| 545 | } | ||
| 546 | return 0; | ||
| 547 | } | 352 | } |
| 548 | 353 | ||
| 549 | static int bnx2x_vfop_config_list(struct bnx2x *bp, | 354 | static int bnx2x_vf_vlan_mac_clear(struct bnx2x *bp, struct bnx2x_virtf *vf, |
| 550 | struct bnx2x_vfop_filters *filters, | 355 | int qid, bool drv_only, bool mac) |
| 551 | struct bnx2x_vlan_mac_ramrod_params *vlan_mac) | ||
| 552 | { | 356 | { |
| 553 | struct bnx2x_vfop_filter *pos, *tmp; | 357 | struct bnx2x_vlan_mac_ramrod_params ramrod; |
| 554 | struct list_head rollback_list, *filters_list = &filters->head; | 358 | int rc; |
| 555 | struct bnx2x_vlan_mac_data *user_req = &vlan_mac->user_req; | ||
| 556 | int rc = 0, cnt = 0; | ||
| 557 | |||
| 558 | INIT_LIST_HEAD(&rollback_list); | ||
| 559 | |||
| 560 | list_for_each_entry_safe(pos, tmp, filters_list, link) { | ||
| 561 | if (bnx2x_vfop_set_user_req(bp, pos, user_req)) | ||
| 562 | continue; | ||
| 563 | 359 | ||
| 564 | rc = bnx2x_config_vlan_mac(bp, vlan_mac); | 360 | DP(BNX2X_MSG_IOV, "vf[%d] - deleting all %s\n", vf->abs_vfid, |
| 565 | if (rc >= 0) { | 361 | mac ? "MACs" : "VLANs"); |
| 566 | cnt += pos->add ? 1 : -1; | ||
| 567 | list_move(&pos->link, &rollback_list); | ||
| 568 | rc = 0; | ||
| 569 | } else if (rc == -EEXIST) { | ||
| 570 | rc = 0; | ||
| 571 | } else { | ||
| 572 | BNX2X_ERR("Failed to add a new vlan_mac command\n"); | ||
| 573 | break; | ||
| 574 | } | ||
| 575 | } | ||
| 576 | 362 | ||
| 577 | /* rollback if error or too many rules added */ | 363 | /* Prepare ramrod params */ |
| 578 | if (rc || cnt > filters->add_cnt) { | 364 | memset(&ramrod, 0, sizeof(struct bnx2x_vlan_mac_ramrod_params)); |
| 579 | BNX2X_ERR("error or too many rules added. Performing rollback\n"); | 365 | if (mac) { |
| 580 | list_for_each_entry_safe(pos, tmp, &rollback_list, link) { | 366 | set_bit(BNX2X_ETH_MAC, &ramrod.user_req.vlan_mac_flags); |
| 581 | pos->add = !pos->add; /* reverse op */ | 367 | ramrod.vlan_mac_obj = &bnx2x_vfq(vf, qid, mac_obj); |
| 582 | bnx2x_vfop_set_user_req(bp, pos, user_req); | 368 | } else { |
| 583 | bnx2x_config_vlan_mac(bp, vlan_mac); | 369 | set_bit(BNX2X_DONT_CONSUME_CAM_CREDIT, |
| 584 | list_del(&pos->link); | 370 | &ramrod.user_req.vlan_mac_flags); |
| 585 | } | 371 | ramrod.vlan_mac_obj = &bnx2x_vfq(vf, qid, vlan_obj); |
| 586 | cnt = 0; | ||
| 587 | if (!rc) | ||
| 588 | rc = -EINVAL; | ||
| 589 | } | 372 | } |
| 590 | filters->add_cnt = cnt; | 373 | ramrod.user_req.cmd = BNX2X_VLAN_MAC_DEL; |
| 591 | return rc; | ||
| 592 | } | ||
| 593 | |||
| 594 | /* VFOP set VLAN/MAC */ | ||
| 595 | static void bnx2x_vfop_vlan_mac(struct bnx2x *bp, struct bnx2x_virtf *vf) | ||
| 596 | { | ||
| 597 | struct bnx2x_vfop *vfop = bnx2x_vfop_cur(bp, vf); | ||
| 598 | struct bnx2x_vlan_mac_ramrod_params *vlan_mac = &vfop->op_p->vlan_mac; | ||
| 599 | struct bnx2x_vlan_mac_obj *obj = vlan_mac->vlan_mac_obj; | ||
| 600 | struct bnx2x_vfop_filters *filters = vfop->args.filters.multi_filter; | ||
| 601 | |||
| 602 | enum bnx2x_vfop_vlan_mac_state state = vfop->state; | ||
| 603 | |||
| 604 | if (vfop->rc < 0) | ||
| 605 | goto op_err; | ||
| 606 | |||
| 607 | DP(BNX2X_MSG_IOV, "vf[%d] STATE: %d\n", vf->abs_vfid, state); | ||
| 608 | |||
| 609 | bnx2x_vfop_reset_wq(vf); | ||
| 610 | |||
| 611 | switch (state) { | ||
| 612 | case BNX2X_VFOP_VLAN_MAC_CLEAR: | ||
| 613 | /* next state */ | ||
| 614 | vfop->state = BNX2X_VFOP_VLAN_MAC_CHK_DONE; | ||
| 615 | |||
| 616 | /* do delete */ | ||
| 617 | vfop->rc = obj->delete_all(bp, obj, | ||
| 618 | &vlan_mac->user_req.vlan_mac_flags, | ||
| 619 | &vlan_mac->ramrod_flags); | ||
| 620 | |||
| 621 | bnx2x_vfop_finalize(vf, vfop->rc, VFOP_CONT); | ||
| 622 | |||
| 623 | case BNX2X_VFOP_VLAN_MAC_CONFIG_SINGLE: | ||
| 624 | /* next state */ | ||
| 625 | vfop->state = BNX2X_VFOP_VLAN_MAC_CHK_DONE; | ||
| 626 | |||
| 627 | /* do config */ | ||
| 628 | vfop->rc = bnx2x_config_vlan_mac(bp, vlan_mac); | ||
| 629 | if (vfop->rc == -EEXIST) | ||
| 630 | vfop->rc = 0; | ||
| 631 | 374 | ||
| 632 | bnx2x_vfop_finalize(vf, vfop->rc, VFOP_CONT); | 375 | set_bit(RAMROD_EXEC, &ramrod.ramrod_flags); |
| 633 | 376 | if (drv_only) | |
| 634 | case BNX2X_VFOP_VLAN_MAC_CHK_DONE: | 377 | set_bit(RAMROD_DRV_CLR_ONLY, &ramrod.ramrod_flags); |
| 635 | vfop->rc = !!obj->raw.check_pending(&obj->raw); | 378 | else |
| 636 | bnx2x_vfop_finalize(vf, vfop->rc, VFOP_DONE); | 379 | set_bit(RAMROD_COMP_WAIT, &ramrod.ramrod_flags); |
| 637 | |||
| 638 | case BNX2X_VFOP_MAC_CONFIG_LIST: | ||
| 639 | /* next state */ | ||
| 640 | vfop->state = BNX2X_VFOP_VLAN_MAC_CHK_DONE; | ||
| 641 | |||
| 642 | /* do list config */ | ||
| 643 | vfop->rc = bnx2x_vfop_config_list(bp, filters, vlan_mac); | ||
| 644 | if (vfop->rc) | ||
| 645 | goto op_err; | ||
| 646 | |||
| 647 | set_bit(RAMROD_CONT, &vlan_mac->ramrod_flags); | ||
| 648 | vfop->rc = bnx2x_config_vlan_mac(bp, vlan_mac); | ||
| 649 | bnx2x_vfop_finalize(vf, vfop->rc, VFOP_CONT); | ||
| 650 | |||
| 651 | case BNX2X_VFOP_VLAN_CONFIG_LIST: | ||
| 652 | /* next state */ | ||
| 653 | vfop->state = BNX2X_VFOP_VLAN_MAC_CHK_DONE; | ||
| 654 | |||
| 655 | /* do list config */ | ||
| 656 | vfop->rc = bnx2x_vfop_config_list(bp, filters, vlan_mac); | ||
| 657 | if (!vfop->rc) { | ||
| 658 | set_bit(RAMROD_CONT, &vlan_mac->ramrod_flags); | ||
| 659 | vfop->rc = bnx2x_config_vlan_mac(bp, vlan_mac); | ||
| 660 | } | ||
| 661 | bnx2x_vfop_finalize(vf, vfop->rc, VFOP_CONT); | ||
| 662 | 380 | ||
| 663 | default: | 381 | /* Start deleting */ |
| 664 | bnx2x_vfop_default(state); | 382 | rc = ramrod.vlan_mac_obj->delete_all(bp, |
| 383 | ramrod.vlan_mac_obj, | ||
| 384 | &ramrod.user_req.vlan_mac_flags, | ||
| 385 | &ramrod.ramrod_flags); | ||
| 386 | if (rc) { | ||
| 387 | BNX2X_ERR("Failed to delete all %s\n", | ||
| 388 | mac ? "MACs" : "VLANs"); | ||
| 389 | return rc; | ||
| 665 | } | 390 | } |
| 666 | op_err: | ||
| 667 | BNX2X_ERR("VLAN-MAC error: rc %d\n", vfop->rc); | ||
| 668 | op_done: | ||
| 669 | kfree(filters); | ||
| 670 | bnx2x_vfop_credit(bp, vfop, obj); | ||
| 671 | bnx2x_vfop_end(bp, vf, vfop); | ||
| 672 | op_pending: | ||
| 673 | return; | ||
| 674 | } | ||
| 675 | |||
| 676 | struct bnx2x_vfop_vlan_mac_flags { | ||
| 677 | bool drv_only; | ||
| 678 | bool dont_consume; | ||
| 679 | bool single_cmd; | ||
| 680 | bool add; | ||
| 681 | }; | ||
| 682 | |||
| 683 | static void | ||
| 684 | bnx2x_vfop_vlan_mac_prep_ramrod(struct bnx2x_vlan_mac_ramrod_params *ramrod, | ||
| 685 | struct bnx2x_vfop_vlan_mac_flags *flags) | ||
| 686 | { | ||
| 687 | struct bnx2x_vlan_mac_data *ureq = &ramrod->user_req; | ||
| 688 | |||
| 689 | memset(ramrod, 0, sizeof(*ramrod)); | ||
| 690 | 391 | ||
| 691 | /* ramrod flags */ | 392 | /* Clear the vlan counters */ |
| 692 | if (flags->drv_only) | 393 | if (!mac) |
| 693 | set_bit(RAMROD_DRV_CLR_ONLY, &ramrod->ramrod_flags); | 394 | atomic_set(&bnx2x_vfq(vf, qid, vlan_count), 0); |
| 694 | if (flags->single_cmd) | ||
| 695 | set_bit(RAMROD_EXEC, &ramrod->ramrod_flags); | ||
| 696 | 395 | ||
| 697 | /* mac_vlan flags */ | 396 | return 0; |
| 698 | if (flags->dont_consume) | ||
| 699 | set_bit(BNX2X_DONT_CONSUME_CAM_CREDIT, &ureq->vlan_mac_flags); | ||
| 700 | |||
| 701 | /* cmd */ | ||
| 702 | ureq->cmd = flags->add ? BNX2X_VLAN_MAC_ADD : BNX2X_VLAN_MAC_DEL; | ||
| 703 | } | ||
| 704 | |||
| 705 | static inline void | ||
| 706 | bnx2x_vfop_mac_prep_ramrod(struct bnx2x_vlan_mac_ramrod_params *ramrod, | ||
| 707 | struct bnx2x_vfop_vlan_mac_flags *flags) | ||
| 708 | { | ||
| 709 | bnx2x_vfop_vlan_mac_prep_ramrod(ramrod, flags); | ||
| 710 | set_bit(BNX2X_ETH_MAC, &ramrod->user_req.vlan_mac_flags); | ||
| 711 | } | 397 | } |
| 712 | 398 | ||
| 713 | static int bnx2x_vfop_mac_delall_cmd(struct bnx2x *bp, | 399 | static int bnx2x_vf_mac_vlan_config(struct bnx2x *bp, |
| 714 | struct bnx2x_virtf *vf, | 400 | struct bnx2x_virtf *vf, int qid, |
| 715 | struct bnx2x_vfop_cmd *cmd, | 401 | struct bnx2x_vf_mac_vlan_filter *filter, |
| 716 | int qid, bool drv_only) | 402 | bool drv_only) |
| 717 | { | 403 | { |
| 718 | struct bnx2x_vfop *vfop = bnx2x_vfop_add(bp, vf); | 404 | struct bnx2x_vlan_mac_ramrod_params ramrod; |
| 719 | int rc; | 405 | int rc; |
| 720 | 406 | ||
| 721 | if (vfop) { | 407 | DP(BNX2X_MSG_IOV, "vf[%d] - %s a %s filter\n", |
| 722 | struct bnx2x_vfop_args_filters filters = { | 408 | vf->abs_vfid, filter->add ? "Adding" : "Deleting", |
| 723 | .multi_filter = NULL, /* single */ | 409 | filter->type == BNX2X_VF_FILTER_MAC ? "MAC" : "VLAN"); |
| 724 | .credit = NULL, /* consume credit */ | 410 | |
| 725 | }; | 411 | /* Prepare ramrod params */ |
| 726 | struct bnx2x_vfop_vlan_mac_flags flags = { | 412 | memset(&ramrod, 0, sizeof(struct bnx2x_vlan_mac_ramrod_params)); |
| 727 | .drv_only = drv_only, | 413 | if (filter->type == BNX2X_VF_FILTER_VLAN) { |
| 728 | .dont_consume = (filters.credit != NULL), | 414 | set_bit(BNX2X_DONT_CONSUME_CAM_CREDIT, |
| 729 | .single_cmd = true, | 415 | &ramrod.user_req.vlan_mac_flags); |
| 730 | .add = false /* don't care */, | 416 | ramrod.vlan_mac_obj = &bnx2x_vfq(vf, qid, vlan_obj); |
| 731 | }; | 417 | ramrod.user_req.u.vlan.vlan = filter->vid; |
| 732 | struct bnx2x_vlan_mac_ramrod_params *ramrod = | 418 | } else { |
| 733 | &vf->op_params.vlan_mac; | 419 | set_bit(BNX2X_ETH_MAC, &ramrod.user_req.vlan_mac_flags); |
| 734 | 420 | ramrod.vlan_mac_obj = &bnx2x_vfq(vf, qid, mac_obj); | |
| 735 | /* set ramrod params */ | 421 | memcpy(&ramrod.user_req.u.mac.mac, filter->mac, ETH_ALEN); |
| 736 | bnx2x_vfop_mac_prep_ramrod(ramrod, &flags); | 422 | } |
| 737 | 423 | ramrod.user_req.cmd = filter->add ? BNX2X_VLAN_MAC_ADD : | |
| 738 | /* set object */ | 424 | BNX2X_VLAN_MAC_DEL; |
| 739 | rc = validate_vlan_mac(bp, &bnx2x_vfq(vf, qid, mac_obj)); | 425 | |
| 740 | if (rc) | 426 | /* Verify there are available vlan credits */ |
| 741 | return rc; | 427 | if (filter->add && filter->type == BNX2X_VF_FILTER_VLAN && |
| 742 | ramrod->vlan_mac_obj = &bnx2x_vfq(vf, qid, mac_obj); | 428 | (atomic_read(&bnx2x_vfq(vf, qid, vlan_count)) >= |
| 743 | 429 | vf_vlan_rules_cnt(vf))) { | |
| 744 | /* set extra args */ | 430 | BNX2X_ERR("No credits for vlan\n"); |
| 745 | vfop->args.filters = filters; | 431 | return -ENOMEM; |
| 746 | |||
| 747 | bnx2x_vfop_opset(BNX2X_VFOP_VLAN_MAC_CLEAR, | ||
| 748 | bnx2x_vfop_vlan_mac, cmd->done); | ||
| 749 | return bnx2x_vfop_transition(bp, vf, bnx2x_vfop_vlan_mac, | ||
| 750 | cmd->block); | ||
| 751 | } | 432 | } |
| 752 | return -ENOMEM; | ||
| 753 | } | ||
| 754 | |||
| 755 | int bnx2x_vfop_mac_list_cmd(struct bnx2x *bp, | ||
| 756 | struct bnx2x_virtf *vf, | ||
| 757 | struct bnx2x_vfop_cmd *cmd, | ||
| 758 | struct bnx2x_vfop_filters *macs, | ||
| 759 | int qid, bool drv_only) | ||
| 760 | { | ||
| 761 | struct bnx2x_vfop *vfop = bnx2x_vfop_add(bp, vf); | ||
| 762 | int rc; | ||
| 763 | 433 | ||
| 764 | if (vfop) { | 434 | set_bit(RAMROD_EXEC, &ramrod.ramrod_flags); |
| 765 | struct bnx2x_vfop_args_filters filters = { | 435 | if (drv_only) |
| 766 | .multi_filter = macs, | 436 | set_bit(RAMROD_DRV_CLR_ONLY, &ramrod.ramrod_flags); |
| 767 | .credit = NULL, /* consume credit */ | 437 | else |
| 768 | }; | 438 | set_bit(RAMROD_COMP_WAIT, &ramrod.ramrod_flags); |
| 769 | struct bnx2x_vfop_vlan_mac_flags flags = { | 439 | |
| 770 | .drv_only = drv_only, | 440 | /* Add/Remove the filter */ |
| 771 | .dont_consume = (filters.credit != NULL), | 441 | rc = bnx2x_config_vlan_mac(bp, &ramrod); |
| 772 | .single_cmd = false, | 442 | if (rc && rc != -EEXIST) { |
| 773 | .add = false, /* don't care since only the items in the | 443 | BNX2X_ERR("Failed to %s %s\n", |
| 774 | * filters list affect the sp operation, | 444 | filter->add ? "add" : "delete", |
| 775 | * not the list itself | 445 | filter->type == BNX2X_VF_FILTER_MAC ? "MAC" : |
| 776 | */ | 446 | "VLAN"); |
| 777 | }; | 447 | return rc; |
| 778 | struct bnx2x_vlan_mac_ramrod_params *ramrod = | 448 | } |
| 779 | &vf->op_params.vlan_mac; | ||
| 780 | |||
| 781 | /* set ramrod params */ | ||
| 782 | bnx2x_vfop_mac_prep_ramrod(ramrod, &flags); | ||
| 783 | |||
| 784 | /* set object */ | ||
| 785 | rc = validate_vlan_mac(bp, &bnx2x_vfq(vf, qid, mac_obj)); | ||
| 786 | if (rc) | ||
| 787 | return rc; | ||
| 788 | ramrod->vlan_mac_obj = &bnx2x_vfq(vf, qid, mac_obj); | ||
| 789 | 449 | ||
| 790 | /* set extra args */ | 450 | /* Update the vlan counters */ |
| 791 | filters.multi_filter->add_cnt = BNX2X_VFOP_FILTER_ADD_CNT_MAX; | 451 | if (filter->type == BNX2X_VF_FILTER_VLAN) |
| 792 | vfop->args.filters = filters; | 452 | bnx2x_vf_vlan_credit(bp, ramrod.vlan_mac_obj, |
| 453 | &bnx2x_vfq(vf, qid, vlan_count)); | ||
| 793 | 454 | ||
| 794 | bnx2x_vfop_opset(BNX2X_VFOP_MAC_CONFIG_LIST, | 455 | return 0; |
| 795 | bnx2x_vfop_vlan_mac, cmd->done); | ||
| 796 | return bnx2x_vfop_transition(bp, vf, bnx2x_vfop_vlan_mac, | ||
| 797 | cmd->block); | ||
| 798 | } | ||
| 799 | return -ENOMEM; | ||
| 800 | } | 456 | } |
| 801 | 457 | ||
| 802 | static int bnx2x_vfop_vlan_set_cmd(struct bnx2x *bp, | 458 | int bnx2x_vf_mac_vlan_config_list(struct bnx2x *bp, struct bnx2x_virtf *vf, |
| 803 | struct bnx2x_virtf *vf, | 459 | struct bnx2x_vf_mac_vlan_filters *filters, |
| 804 | struct bnx2x_vfop_cmd *cmd, | 460 | int qid, bool drv_only) |
| 805 | int qid, u16 vid, bool add) | ||
| 806 | { | 461 | { |
| 807 | struct bnx2x_vfop *vfop = bnx2x_vfop_add(bp, vf); | 462 | int rc = 0, i; |
| 808 | int rc; | ||
| 809 | 463 | ||
| 810 | if (vfop) { | 464 | DP(BNX2X_MSG_IOV, "vf[%d]\n", vf->abs_vfid); |
| 811 | struct bnx2x_vfop_args_filters filters = { | ||
| 812 | .multi_filter = NULL, /* single command */ | ||
| 813 | .credit = &bnx2x_vfq(vf, qid, vlan_count), | ||
| 814 | }; | ||
| 815 | struct bnx2x_vfop_vlan_mac_flags flags = { | ||
| 816 | .drv_only = false, | ||
| 817 | .dont_consume = (filters.credit != NULL), | ||
| 818 | .single_cmd = true, | ||
| 819 | .add = add, | ||
| 820 | }; | ||
| 821 | struct bnx2x_vlan_mac_ramrod_params *ramrod = | ||
| 822 | &vf->op_params.vlan_mac; | ||
| 823 | |||
| 824 | /* set ramrod params */ | ||
| 825 | bnx2x_vfop_vlan_mac_prep_ramrod(ramrod, &flags); | ||
| 826 | ramrod->user_req.u.vlan.vlan = vid; | ||
| 827 | |||
| 828 | /* set object */ | ||
| 829 | rc = validate_vlan_mac(bp, &bnx2x_vfq(vf, qid, vlan_obj)); | ||
| 830 | if (rc) | ||
| 831 | return rc; | ||
| 832 | ramrod->vlan_mac_obj = &bnx2x_vfq(vf, qid, vlan_obj); | ||
| 833 | 465 | ||
| 834 | /* set extra args */ | 466 | if (!bnx2x_validate_vf_sp_objs(bp, vf, true)) |
| 835 | vfop->args.filters = filters; | 467 | return -EINVAL; |
| 836 | 468 | ||
| 837 | bnx2x_vfop_opset(BNX2X_VFOP_VLAN_MAC_CONFIG_SINGLE, | 469 | /* Prepare ramrod params */ |
| 838 | bnx2x_vfop_vlan_mac, cmd->done); | 470 | for (i = 0; i < filters->count; i++) { |
| 839 | return bnx2x_vfop_transition(bp, vf, bnx2x_vfop_vlan_mac, | 471 | rc = bnx2x_vf_mac_vlan_config(bp, vf, qid, |
| 840 | cmd->block); | 472 | &filters->filters[i], drv_only); |
| 473 | if (rc) | ||
| 474 | break; | ||
| 841 | } | 475 | } |
| 842 | return -ENOMEM; | ||
| 843 | } | ||
| 844 | |||
| 845 | static int bnx2x_vfop_vlan_delall_cmd(struct bnx2x *bp, | ||
| 846 | struct bnx2x_virtf *vf, | ||
| 847 | struct bnx2x_vfop_cmd *cmd, | ||
| 848 | int qid, bool drv_only) | ||
| 849 | { | ||
| 850 | struct bnx2x_vfop *vfop = bnx2x_vfop_add(bp, vf); | ||
| 851 | int rc; | ||
| 852 | 476 | ||
| 853 | if (vfop) { | 477 | /* Rollback if needed */ |
| 854 | struct bnx2x_vfop_args_filters filters = { | 478 | if (i != filters->count) { |
| 855 | .multi_filter = NULL, /* single command */ | 479 | BNX2X_ERR("Managed only %d/%d filters - rolling back\n", |
| 856 | .credit = &bnx2x_vfq(vf, qid, vlan_count), | 480 | i, filters->count + 1); |
| 857 | }; | 481 | while (--i >= 0) { |
| 858 | struct bnx2x_vfop_vlan_mac_flags flags = { | 482 | filters->filters[i].add = !filters->filters[i].add; |
| 859 | .drv_only = drv_only, | 483 | bnx2x_vf_mac_vlan_config(bp, vf, qid, |
| 860 | .dont_consume = (filters.credit != NULL), | 484 | &filters->filters[i], |
| 861 | .single_cmd = true, | 485 | drv_only); |
| 862 | .add = false, /* don't care */ | 486 | } |
| 863 | }; | 487 | } |
| 864 | struct bnx2x_vlan_mac_ramrod_params *ramrod = | ||
| 865 | &vf->op_params.vlan_mac; | ||
| 866 | |||
| 867 | /* set ramrod params */ | ||
| 868 | bnx2x_vfop_vlan_mac_prep_ramrod(ramrod, &flags); | ||
| 869 | |||
| 870 | /* set object */ | ||
| 871 | rc = validate_vlan_mac(bp, &bnx2x_vfq(vf, qid, vlan_obj)); | ||
| 872 | if (rc) | ||
| 873 | return rc; | ||
| 874 | ramrod->vlan_mac_obj = &bnx2x_vfq(vf, qid, vlan_obj); | ||
| 875 | 488 | ||
| 876 | /* set extra args */ | 489 | /* It's our responsibility to free the filters */ |
| 877 | vfop->args.filters = filters; | 490 | kfree(filters); |
| 878 | 491 | ||
| 879 | bnx2x_vfop_opset(BNX2X_VFOP_VLAN_MAC_CLEAR, | 492 | return rc; |
| 880 | bnx2x_vfop_vlan_mac, cmd->done); | ||
| 881 | return bnx2x_vfop_transition(bp, vf, bnx2x_vfop_vlan_mac, | ||
| 882 | cmd->block); | ||
| 883 | } | ||
| 884 | return -ENOMEM; | ||
| 885 | } | 493 | } |
| 886 | 494 | ||
| 887 | int bnx2x_vfop_vlan_list_cmd(struct bnx2x *bp, | 495 | int bnx2x_vf_queue_setup(struct bnx2x *bp, struct bnx2x_virtf *vf, int qid, |
| 888 | struct bnx2x_virtf *vf, | 496 | struct bnx2x_vf_queue_construct_params *qctor) |
| 889 | struct bnx2x_vfop_cmd *cmd, | ||
| 890 | struct bnx2x_vfop_filters *vlans, | ||
| 891 | int qid, bool drv_only) | ||
| 892 | { | 497 | { |
| 893 | struct bnx2x_vfop *vfop = bnx2x_vfop_add(bp, vf); | ||
| 894 | int rc; | 498 | int rc; |
| 895 | 499 | ||
| 896 | if (vfop) { | 500 | DP(BNX2X_MSG_IOV, "vf[%d:%d]\n", vf->abs_vfid, qid); |
| 897 | struct bnx2x_vfop_args_filters filters = { | ||
| 898 | .multi_filter = vlans, | ||
| 899 | .credit = &bnx2x_vfq(vf, qid, vlan_count), | ||
| 900 | }; | ||
| 901 | struct bnx2x_vfop_vlan_mac_flags flags = { | ||
| 902 | .drv_only = drv_only, | ||
| 903 | .dont_consume = (filters.credit != NULL), | ||
| 904 | .single_cmd = false, | ||
| 905 | .add = false, /* don't care */ | ||
| 906 | }; | ||
| 907 | struct bnx2x_vlan_mac_ramrod_params *ramrod = | ||
| 908 | &vf->op_params.vlan_mac; | ||
| 909 | |||
| 910 | /* set ramrod params */ | ||
| 911 | bnx2x_vfop_vlan_mac_prep_ramrod(ramrod, &flags); | ||
| 912 | |||
| 913 | /* set object */ | ||
| 914 | rc = validate_vlan_mac(bp, &bnx2x_vfq(vf, qid, vlan_obj)); | ||
| 915 | if (rc) | ||
| 916 | return rc; | ||
| 917 | ramrod->vlan_mac_obj = &bnx2x_vfq(vf, qid, vlan_obj); | ||
| 918 | |||
| 919 | /* set extra args */ | ||
| 920 | filters.multi_filter->add_cnt = vf_vlan_rules_cnt(vf) - | ||
| 921 | atomic_read(filters.credit); | ||
| 922 | |||
| 923 | vfop->args.filters = filters; | ||
| 924 | 501 | ||
| 925 | bnx2x_vfop_opset(BNX2X_VFOP_VLAN_CONFIG_LIST, | 502 | rc = bnx2x_vf_queue_create(bp, vf, qid, qctor); |
| 926 | bnx2x_vfop_vlan_mac, cmd->done); | 503 | if (rc) |
| 927 | return bnx2x_vfop_transition(bp, vf, bnx2x_vfop_vlan_mac, | ||
| 928 | cmd->block); | ||
| 929 | } | ||
| 930 | return -ENOMEM; | ||
| 931 | } | ||
| 932 | |||
| 933 | /* VFOP queue setup (queue constructor + set vlan 0) */ | ||
| 934 | static void bnx2x_vfop_qsetup(struct bnx2x *bp, struct bnx2x_virtf *vf) | ||
| 935 | { | ||
| 936 | struct bnx2x_vfop *vfop = bnx2x_vfop_cur(bp, vf); | ||
| 937 | int qid = vfop->args.qctor.qid; | ||
| 938 | enum bnx2x_vfop_qsetup_state state = vfop->state; | ||
| 939 | struct bnx2x_vfop_cmd cmd = { | ||
| 940 | .done = bnx2x_vfop_qsetup, | ||
| 941 | .block = false, | ||
| 942 | }; | ||
| 943 | |||
| 944 | if (vfop->rc < 0) | ||
| 945 | goto op_err; | 504 | goto op_err; |
| 946 | 505 | ||
| 947 | DP(BNX2X_MSG_IOV, "vf[%d] STATE: %d\n", vf->abs_vfid, state); | 506 | /* Configure vlan0 for leading queue */ |
| 507 | if (!qid) { | ||
| 508 | struct bnx2x_vf_mac_vlan_filter filter; | ||
| 948 | 509 | ||
| 949 | switch (state) { | 510 | memset(&filter, 0, sizeof(struct bnx2x_vf_mac_vlan_filter)); |
| 950 | case BNX2X_VFOP_QSETUP_CTOR: | 511 | filter.type = BNX2X_VF_FILTER_VLAN; |
| 951 | /* init the queue ctor command */ | 512 | filter.add = true; |
| 952 | vfop->state = BNX2X_VFOP_QSETUP_VLAN0; | 513 | filter.vid = 0; |
| 953 | vfop->rc = bnx2x_vfop_qctor_cmd(bp, vf, &cmd, qid); | 514 | rc = bnx2x_vf_mac_vlan_config(bp, vf, qid, &filter, false); |
| 954 | if (vfop->rc) | 515 | if (rc) |
| 955 | goto op_err; | 516 | goto op_err; |
| 956 | return; | 517 | } |
| 957 | |||
| 958 | case BNX2X_VFOP_QSETUP_VLAN0: | ||
| 959 | /* skip if non-leading or FPGA/EMU*/ | ||
| 960 | if (qid) | ||
| 961 | goto op_done; | ||
| 962 | 518 | ||
| 963 | /* init the queue set-vlan command (for vlan 0) */ | 519 | /* Schedule the configuration of any pending vlan filters */ |
| 964 | vfop->state = BNX2X_VFOP_QSETUP_DONE; | 520 | vf->cfg_flags |= VF_CFG_VLAN; |
| 965 | vfop->rc = bnx2x_vfop_vlan_set_cmd(bp, vf, &cmd, qid, 0, true); | 521 | bnx2x_schedule_sp_rtnl(bp, BNX2X_SP_RTNL_HYPERVISOR_VLAN, |
| 966 | if (vfop->rc) | 522 | BNX2X_MSG_IOV); |
| 967 | goto op_err; | 523 | return 0; |
| 968 | return; | ||
| 969 | op_err: | 524 | op_err: |
| 970 | BNX2X_ERR("QSETUP[%d:%d] error: rc %d\n", vf->abs_vfid, qid, vfop->rc); | 525 | BNX2X_ERR("QSETUP[%d:%d] error: rc %d\n", vf->abs_vfid, qid, rc); |
| 971 | op_done: | 526 | return rc; |
| 972 | case BNX2X_VFOP_QSETUP_DONE: | ||
| 973 | vf->cfg_flags |= VF_CFG_VLAN; | ||
| 974 | smp_mb__before_clear_bit(); | ||
| 975 | set_bit(BNX2X_SP_RTNL_HYPERVISOR_VLAN, | ||
| 976 | &bp->sp_rtnl_state); | ||
| 977 | smp_mb__after_clear_bit(); | ||
| 978 | schedule_delayed_work(&bp->sp_rtnl_task, 0); | ||
| 979 | bnx2x_vfop_end(bp, vf, vfop); | ||
| 980 | return; | ||
| 981 | default: | ||
| 982 | bnx2x_vfop_default(state); | ||
| 983 | } | ||
| 984 | } | 527 | } |
| 985 | 528 | ||
| 986 | int bnx2x_vfop_qsetup_cmd(struct bnx2x *bp, | 529 | static int bnx2x_vf_queue_flr(struct bnx2x *bp, struct bnx2x_virtf *vf, |
| 987 | struct bnx2x_virtf *vf, | 530 | int qid) |
| 988 | struct bnx2x_vfop_cmd *cmd, | ||
| 989 | int qid) | ||
| 990 | { | 531 | { |
| 991 | struct bnx2x_vfop *vfop = bnx2x_vfop_add(bp, vf); | 532 | int rc; |
| 992 | 533 | ||
| 993 | if (vfop) { | 534 | DP(BNX2X_MSG_IOV, "vf[%d:%d]\n", vf->abs_vfid, qid); |
| 994 | vfop->args.qctor.qid = qid; | ||
| 995 | 535 | ||
| 996 | bnx2x_vfop_opset(BNX2X_VFOP_QSETUP_CTOR, | 536 | /* If needed, clean the filtering data base */ |
| 997 | bnx2x_vfop_qsetup, cmd->done); | 537 | if ((qid == LEADING_IDX) && |
| 998 | return bnx2x_vfop_transition(bp, vf, bnx2x_vfop_qsetup, | 538 | bnx2x_validate_vf_sp_objs(bp, vf, false)) { |
| 999 | cmd->block); | 539 | rc = bnx2x_vf_vlan_mac_clear(bp, vf, qid, true, false); |
| 540 | if (rc) | ||
| 541 | goto op_err; | ||
| 542 | rc = bnx2x_vf_vlan_mac_clear(bp, vf, qid, true, true); | ||
| 543 | if (rc) | ||
| 544 | goto op_err; | ||
| 1000 | } | 545 | } |
| 1001 | return -ENOMEM; | ||
| 1002 | } | ||
| 1003 | |||
| 1004 | /* VFOP queue FLR handling (clear vlans, clear macs, queue destructor) */ | ||
| 1005 | static void bnx2x_vfop_qflr(struct bnx2x *bp, struct bnx2x_virtf *vf) | ||
| 1006 | { | ||
| 1007 | struct bnx2x_vfop *vfop = bnx2x_vfop_cur(bp, vf); | ||
| 1008 | int qid = vfop->args.qx.qid; | ||
| 1009 | enum bnx2x_vfop_qflr_state state = vfop->state; | ||
| 1010 | struct bnx2x_queue_state_params *qstate; | ||
| 1011 | struct bnx2x_vfop_cmd cmd; | ||
| 1012 | |||
| 1013 | bnx2x_vfop_reset_wq(vf); | ||
| 1014 | |||
| 1015 | if (vfop->rc < 0) | ||
| 1016 | goto op_err; | ||
| 1017 | 546 | ||
| 1018 | DP(BNX2X_MSG_IOV, "VF[%d] STATE: %d\n", vf->abs_vfid, state); | 547 | /* Terminate queue */ |
| 548 | if (bnx2x_vfq(vf, qid, sp_obj).state != BNX2X_Q_STATE_RESET) { | ||
| 549 | struct bnx2x_queue_state_params qstate; | ||
| 1019 | 550 | ||
| 1020 | cmd.done = bnx2x_vfop_qflr; | 551 | memset(&qstate, 0, sizeof(struct bnx2x_queue_state_params)); |
| 1021 | cmd.block = false; | 552 | qstate.q_obj = &bnx2x_vfq(vf, qid, sp_obj); |
| 1022 | 553 | qstate.q_obj->state = BNX2X_Q_STATE_STOPPED; | |
| 1023 | switch (state) { | 554 | qstate.cmd = BNX2X_Q_CMD_TERMINATE; |
| 1024 | case BNX2X_VFOP_QFLR_CLR_VLAN: | 555 | set_bit(RAMROD_COMP_WAIT, &qstate.ramrod_flags); |
| 1025 | /* vlan-clear-all: driver-only, don't consume credit */ | 556 | rc = bnx2x_queue_state_change(bp, &qstate); |
| 1026 | vfop->state = BNX2X_VFOP_QFLR_CLR_MAC; | 557 | if (rc) |
| 1027 | 558 | goto op_err; | |
| 1028 | if (!validate_vlan_mac(bp, &bnx2x_vfq(vf, qid, vlan_obj))) { | ||
| 1029 | /* the vlan_mac vfop will re-schedule us */ | ||
| 1030 | vfop->rc = bnx2x_vfop_vlan_delall_cmd(bp, vf, &cmd, | ||
| 1031 | qid, true); | ||
| 1032 | if (vfop->rc) | ||
| 1033 | goto op_err; | ||
| 1034 | return; | ||
| 1035 | |||
| 1036 | } else { | ||
| 1037 | /* need to reschedule ourselves */ | ||
| 1038 | bnx2x_vfop_finalize(vf, vfop->rc, VFOP_CONT); | ||
| 1039 | } | ||
| 1040 | |||
| 1041 | case BNX2X_VFOP_QFLR_CLR_MAC: | ||
| 1042 | /* mac-clear-all: driver only consume credit */ | ||
| 1043 | vfop->state = BNX2X_VFOP_QFLR_TERMINATE; | ||
| 1044 | if (!validate_vlan_mac(bp, &bnx2x_vfq(vf, qid, mac_obj))) { | ||
| 1045 | /* the vlan_mac vfop will re-schedule us */ | ||
| 1046 | vfop->rc = bnx2x_vfop_mac_delall_cmd(bp, vf, &cmd, | ||
| 1047 | qid, true); | ||
| 1048 | if (vfop->rc) | ||
| 1049 | goto op_err; | ||
| 1050 | return; | ||
| 1051 | |||
| 1052 | } else { | ||
| 1053 | /* need to reschedule ourselves */ | ||
| 1054 | bnx2x_vfop_finalize(vf, vfop->rc, VFOP_CONT); | ||
| 1055 | } | ||
| 1056 | |||
| 1057 | case BNX2X_VFOP_QFLR_TERMINATE: | ||
| 1058 | qstate = &vfop->op_p->qctor.qstate; | ||
| 1059 | memset(qstate , 0, sizeof(*qstate)); | ||
| 1060 | qstate->q_obj = &bnx2x_vfq(vf, qid, sp_obj); | ||
| 1061 | vfop->state = BNX2X_VFOP_QFLR_DONE; | ||
| 1062 | |||
| 1063 | DP(BNX2X_MSG_IOV, "VF[%d] qstate during flr was %d\n", | ||
| 1064 | vf->abs_vfid, qstate->q_obj->state); | ||
| 1065 | |||
| 1066 | if (qstate->q_obj->state != BNX2X_Q_STATE_RESET) { | ||
| 1067 | qstate->q_obj->state = BNX2X_Q_STATE_STOPPED; | ||
| 1068 | qstate->cmd = BNX2X_Q_CMD_TERMINATE; | ||
| 1069 | vfop->rc = bnx2x_queue_state_change(bp, qstate); | ||
| 1070 | bnx2x_vfop_finalize(vf, vfop->rc, VFOP_VERIFY_PEND); | ||
| 1071 | } else { | ||
| 1072 | goto op_done; | ||
| 1073 | } | ||
| 1074 | |||
| 1075 | op_err: | ||
| 1076 | BNX2X_ERR("QFLR[%d:%d] error: rc %d\n", | ||
| 1077 | vf->abs_vfid, qid, vfop->rc); | ||
| 1078 | op_done: | ||
| 1079 | case BNX2X_VFOP_QFLR_DONE: | ||
| 1080 | bnx2x_vfop_end(bp, vf, vfop); | ||
| 1081 | return; | ||
| 1082 | default: | ||
| 1083 | bnx2x_vfop_default(state); | ||
| 1084 | } | 559 | } |
| 1085 | op_pending: | ||
| 1086 | return; | ||
| 1087 | } | ||
| 1088 | |||
| 1089 | static int bnx2x_vfop_qflr_cmd(struct bnx2x *bp, | ||
| 1090 | struct bnx2x_virtf *vf, | ||
| 1091 | struct bnx2x_vfop_cmd *cmd, | ||
| 1092 | int qid) | ||
| 1093 | { | ||
| 1094 | struct bnx2x_vfop *vfop = bnx2x_vfop_add(bp, vf); | ||
| 1095 | 560 | ||
| 1096 | if (vfop) { | 561 | return 0; |
| 1097 | vfop->args.qx.qid = qid; | 562 | op_err: |
| 1098 | bnx2x_vfop_opset(BNX2X_VFOP_QFLR_CLR_VLAN, | 563 | BNX2X_ERR("vf[%d:%d] error: rc %d\n", vf->abs_vfid, qid, rc); |
| 1099 | bnx2x_vfop_qflr, cmd->done); | 564 | return rc; |
| 1100 | return bnx2x_vfop_transition(bp, vf, bnx2x_vfop_qflr, | ||
| 1101 | cmd->block); | ||
| 1102 | } | ||
| 1103 | return -ENOMEM; | ||
| 1104 | } | 565 | } |
| 1105 | 566 | ||
| 1106 | /* VFOP multi-casts */ | 567 | int bnx2x_vf_mcast(struct bnx2x *bp, struct bnx2x_virtf *vf, |
| 1107 | static void bnx2x_vfop_mcast(struct bnx2x *bp, struct bnx2x_virtf *vf) | 568 | bnx2x_mac_addr_t *mcasts, int mc_num, bool drv_only) |
| 1108 | { | 569 | { |
| 1109 | struct bnx2x_vfop *vfop = bnx2x_vfop_cur(bp, vf); | 570 | struct bnx2x_mcast_list_elem *mc = NULL; |
| 1110 | struct bnx2x_mcast_ramrod_params *mcast = &vfop->op_p->mcast; | 571 | struct bnx2x_mcast_ramrod_params mcast; |
| 1111 | struct bnx2x_raw_obj *raw = &mcast->mcast_obj->raw; | 572 | int rc, i; |
| 1112 | struct bnx2x_vfop_args_mcast *args = &vfop->args.mc_list; | ||
| 1113 | enum bnx2x_vfop_mcast_state state = vfop->state; | ||
| 1114 | int i; | ||
| 1115 | |||
| 1116 | bnx2x_vfop_reset_wq(vf); | ||
| 1117 | |||
| 1118 | if (vfop->rc < 0) | ||
| 1119 | goto op_err; | ||
| 1120 | 573 | ||
| 1121 | DP(BNX2X_MSG_IOV, "vf[%d] STATE: %d\n", vf->abs_vfid, state); | 574 | DP(BNX2X_MSG_IOV, "vf[%d]\n", vf->abs_vfid); |
| 1122 | |||
| 1123 | switch (state) { | ||
| 1124 | case BNX2X_VFOP_MCAST_DEL: | ||
| 1125 | /* clear existing mcasts */ | ||
| 1126 | vfop->state = (args->mc_num) ? BNX2X_VFOP_MCAST_ADD | ||
| 1127 | : BNX2X_VFOP_MCAST_CHK_DONE; | ||
| 1128 | mcast->mcast_list_len = vf->mcast_list_len; | ||
| 1129 | vf->mcast_list_len = args->mc_num; | ||
| 1130 | vfop->rc = bnx2x_config_mcast(bp, mcast, BNX2X_MCAST_CMD_DEL); | ||
| 1131 | bnx2x_vfop_finalize(vf, vfop->rc, VFOP_CONT); | ||
| 1132 | |||
| 1133 | case BNX2X_VFOP_MCAST_ADD: | ||
| 1134 | if (raw->check_pending(raw)) | ||
| 1135 | goto op_pending; | ||
| 1136 | |||
| 1137 | /* update mcast list on the ramrod params */ | ||
| 1138 | INIT_LIST_HEAD(&mcast->mcast_list); | ||
| 1139 | for (i = 0; i < args->mc_num; i++) | ||
| 1140 | list_add_tail(&(args->mc[i].link), | ||
| 1141 | &mcast->mcast_list); | ||
| 1142 | mcast->mcast_list_len = args->mc_num; | ||
| 1143 | 575 | ||
| 1144 | /* add new mcasts */ | 576 | /* Prepare Multicast command */ |
| 1145 | vfop->state = BNX2X_VFOP_MCAST_CHK_DONE; | 577 | memset(&mcast, 0, sizeof(struct bnx2x_mcast_ramrod_params)); |
| 1146 | vfop->rc = bnx2x_config_mcast(bp, mcast, | 578 | mcast.mcast_obj = &vf->mcast_obj; |
| 1147 | BNX2X_MCAST_CMD_ADD); | 579 | if (drv_only) |
| 1148 | bnx2x_vfop_finalize(vf, vfop->rc, VFOP_DONE); | 580 | set_bit(RAMROD_DRV_CLR_ONLY, &mcast.ramrod_flags); |
| 1149 | 581 | else | |
| 1150 | case BNX2X_VFOP_MCAST_CHK_DONE: | 582 | set_bit(RAMROD_COMP_WAIT, &mcast.ramrod_flags); |
| 1151 | vfop->rc = raw->check_pending(raw) ? 1 : 0; | 583 | if (mc_num) { |
| 1152 | bnx2x_vfop_finalize(vf, vfop->rc, VFOP_DONE); | 584 | mc = kzalloc(mc_num * sizeof(struct bnx2x_mcast_list_elem), |
| 1153 | default: | 585 | GFP_KERNEL); |
| 1154 | bnx2x_vfop_default(state); | 586 | if (!mc) { |
| 587 | BNX2X_ERR("Cannot Configure mulicasts due to lack of memory\n"); | ||
| 588 | return -ENOMEM; | ||
| 589 | } | ||
| 1155 | } | 590 | } |
| 1156 | op_err: | ||
| 1157 | BNX2X_ERR("MCAST CONFIG error: rc %d\n", vfop->rc); | ||
| 1158 | op_done: | ||
| 1159 | kfree(args->mc); | ||
| 1160 | bnx2x_vfop_end(bp, vf, vfop); | ||
| 1161 | op_pending: | ||
| 1162 | return; | ||
| 1163 | } | ||
| 1164 | 591 | ||
| 1165 | int bnx2x_vfop_mcast_cmd(struct bnx2x *bp, | 592 | /* clear existing mcasts */ |
| 1166 | struct bnx2x_virtf *vf, | 593 | mcast.mcast_list_len = vf->mcast_list_len; |
| 1167 | struct bnx2x_vfop_cmd *cmd, | 594 | vf->mcast_list_len = mc_num; |
| 1168 | bnx2x_mac_addr_t *mcasts, | 595 | rc = bnx2x_config_mcast(bp, &mcast, BNX2X_MCAST_CMD_DEL); |
| 1169 | int mcast_num, bool drv_only) | 596 | if (rc) { |
| 1170 | { | 597 | BNX2X_ERR("Failed to remove multicasts\n"); |
| 1171 | struct bnx2x_vfop *vfop = NULL; | 598 | if (mc) |
| 1172 | size_t mc_sz = mcast_num * sizeof(struct bnx2x_mcast_list_elem); | ||
| 1173 | struct bnx2x_mcast_list_elem *mc = mc_sz ? kzalloc(mc_sz, GFP_KERNEL) : | ||
| 1174 | NULL; | ||
| 1175 | |||
| 1176 | if (!mc_sz || mc) { | ||
| 1177 | vfop = bnx2x_vfop_add(bp, vf); | ||
| 1178 | if (vfop) { | ||
| 1179 | int i; | ||
| 1180 | struct bnx2x_mcast_ramrod_params *ramrod = | ||
| 1181 | &vf->op_params.mcast; | ||
| 1182 | |||
| 1183 | /* set ramrod params */ | ||
| 1184 | memset(ramrod, 0, sizeof(*ramrod)); | ||
| 1185 | ramrod->mcast_obj = &vf->mcast_obj; | ||
| 1186 | if (drv_only) | ||
| 1187 | set_bit(RAMROD_DRV_CLR_ONLY, | ||
| 1188 | &ramrod->ramrod_flags); | ||
| 1189 | |||
| 1190 | /* copy mcasts pointers */ | ||
| 1191 | vfop->args.mc_list.mc_num = mcast_num; | ||
| 1192 | vfop->args.mc_list.mc = mc; | ||
| 1193 | for (i = 0; i < mcast_num; i++) | ||
| 1194 | mc[i].mac = mcasts[i]; | ||
| 1195 | |||
| 1196 | bnx2x_vfop_opset(BNX2X_VFOP_MCAST_DEL, | ||
| 1197 | bnx2x_vfop_mcast, cmd->done); | ||
| 1198 | return bnx2x_vfop_transition(bp, vf, bnx2x_vfop_mcast, | ||
| 1199 | cmd->block); | ||
| 1200 | } else { | ||
| 1201 | kfree(mc); | 599 | kfree(mc); |
| 1202 | } | 600 | return rc; |
| 1203 | } | 601 | } |
| 1204 | return -ENOMEM; | ||
| 1205 | } | ||
| 1206 | |||
| 1207 | /* VFOP rx-mode */ | ||
| 1208 | static void bnx2x_vfop_rxmode(struct bnx2x *bp, struct bnx2x_virtf *vf) | ||
| 1209 | { | ||
| 1210 | struct bnx2x_vfop *vfop = bnx2x_vfop_cur(bp, vf); | ||
| 1211 | struct bnx2x_rx_mode_ramrod_params *ramrod = &vfop->op_p->rx_mode; | ||
| 1212 | enum bnx2x_vfop_rxmode_state state = vfop->state; | ||
| 1213 | |||
| 1214 | bnx2x_vfop_reset_wq(vf); | ||
| 1215 | |||
| 1216 | if (vfop->rc < 0) | ||
| 1217 | goto op_err; | ||
| 1218 | 602 | ||
| 1219 | DP(BNX2X_MSG_IOV, "vf[%d] STATE: %d\n", vf->abs_vfid, state); | 603 | /* update mcast list on the ramrod params */ |
| 1220 | 604 | if (mc_num) { | |
| 1221 | switch (state) { | 605 | INIT_LIST_HEAD(&mcast.mcast_list); |
| 1222 | case BNX2X_VFOP_RXMODE_CONFIG: | 606 | for (i = 0; i < mc_num; i++) { |
| 1223 | /* next state */ | 607 | mc[i].mac = mcasts[i]; |
| 1224 | vfop->state = BNX2X_VFOP_RXMODE_DONE; | 608 | list_add_tail(&mc[i].link, |
| 609 | &mcast.mcast_list); | ||
| 610 | } | ||
| 1225 | 611 | ||
| 1226 | /* record the accept flags in vfdb so hypervisor can modify them | 612 | /* add new mcasts */ |
| 1227 | * if necessary | 613 | rc = bnx2x_config_mcast(bp, &mcast, BNX2X_MCAST_CMD_ADD); |
| 1228 | */ | 614 | if (rc) |
| 1229 | bnx2x_vfq(vf, ramrod->cl_id - vf->igu_base_id, accept_flags) = | 615 | BNX2X_ERR("Faled to add multicasts\n"); |
| 1230 | ramrod->rx_accept_flags; | 616 | kfree(mc); |
| 1231 | vfop->rc = bnx2x_config_rx_mode(bp, ramrod); | ||
| 1232 | bnx2x_vfop_finalize(vf, vfop->rc, VFOP_DONE); | ||
| 1233 | op_err: | ||
| 1234 | BNX2X_ERR("RXMODE error: rc %d\n", vfop->rc); | ||
| 1235 | op_done: | ||
| 1236 | case BNX2X_VFOP_RXMODE_DONE: | ||
| 1237 | bnx2x_vfop_end(bp, vf, vfop); | ||
| 1238 | return; | ||
| 1239 | default: | ||
| 1240 | bnx2x_vfop_default(state); | ||
| 1241 | } | 617 | } |
| 1242 | op_pending: | 618 | |
| 1243 | return; | 619 | return rc; |
| 1244 | } | 620 | } |
| 1245 | 621 | ||
| 1246 | static void bnx2x_vf_prep_rx_mode(struct bnx2x *bp, u8 qid, | 622 | static void bnx2x_vf_prep_rx_mode(struct bnx2x *bp, u8 qid, |
| @@ -1268,118 +644,56 @@ static void bnx2x_vf_prep_rx_mode(struct bnx2x *bp, u8 qid, · 21 unmodified lines | |||
| 1268 | ramrod->rdata_mapping = bnx2x_vf_sp_map(bp, vf, rx_mode_rdata.e2); | 644 | ramrod->rdata_mapping = bnx2x_vf_sp_map(bp, vf, rx_mode_rdata.e2); |
| 1269 | } | 645 | } |
| 1270 | 646 | ||
| 1271 | int bnx2x_vfop_rxmode_cmd(struct bnx2x *bp, | 647 | int bnx2x_vf_rxmode(struct bnx2x *bp, struct bnx2x_virtf *vf, |
| 1272 | struct bnx2x_virtf *vf, | 648 | int qid, unsigned long accept_flags) |
| 1273 | struct bnx2x_vfop_cmd *cmd, | ||
| 1274 | int qid, unsigned long accept_flags) | ||
| 1275 | { | 649 | { |
| 1276 | struct bnx2x_vfop *vfop = bnx2x_vfop_add(bp, vf); | 650 | struct bnx2x_rx_mode_ramrod_params ramrod; |
| 1277 | |||
| 1278 | if (vfop) { | ||
| 1279 | struct bnx2x_rx_mode_ramrod_params *ramrod = | ||
| 1280 | &vf->op_params.rx_mode; | ||
| 1281 | 651 | ||
| 1282 | bnx2x_vf_prep_rx_mode(bp, qid, ramrod, vf, accept_flags); | 652 | DP(BNX2X_MSG_IOV, "vf[%d]\n", vf->abs_vfid); |
| 1283 | 653 | ||
| 1284 | bnx2x_vfop_opset(BNX2X_VFOP_RXMODE_CONFIG, | 654 | bnx2x_vf_prep_rx_mode(bp, qid, &ramrod, vf, accept_flags); |
| 1285 | bnx2x_vfop_rxmode, cmd->done); | 655 | set_bit(RAMROD_COMP_WAIT, &ramrod.ramrod_flags); |
| 1286 | return bnx2x_vfop_transition(bp, vf, bnx2x_vfop_rxmode, | 656 | vfq_get(vf, qid)->accept_flags = ramrod.rx_accept_flags; |
| 1287 | cmd->block); | 657 | return bnx2x_config_rx_mode(bp, &ramrod); |
| 1288 | } | ||
| 1289 | return -ENOMEM; | ||
| 1290 | } | 658 | } |
| 1291 | 659 | ||
| 1292 | /* VFOP queue tear-down ('drop all' rx-mode, clear vlans, clear macs, | 660 | int bnx2x_vf_queue_teardown(struct bnx2x *bp, struct bnx2x_virtf *vf, int qid) |
| 1293 | * queue destructor) | ||
| 1294 | */ | ||
| 1295 | static void bnx2x_vfop_qdown(struct bnx2x *bp, struct bnx2x_virtf *vf) | ||
| 1296 | { | 661 | { |
| 1297 | struct bnx2x_vfop *vfop = bnx2x_vfop_cur(bp, vf); | 662 | int rc; |
| 1298 | int qid = vfop->args.qx.qid; | ||
| 1299 | enum bnx2x_vfop_qteardown_state state = vfop->state; | ||
| 1300 | struct bnx2x_vfop_cmd cmd; | ||
| 1301 | |||
| 1302 | if (vfop->rc < 0) | ||
| 1303 | goto op_err; | ||
| 1304 | |||
| 1305 | DP(BNX2X_MSG_IOV, "vf[%d] STATE: %d\n", vf->abs_vfid, state); | ||
| 1306 | |||
| 1307 | cmd.done = bnx2x_vfop_qdown; | ||
| 1308 | cmd.block = false; | ||
| 1309 | |||
| 1310 | switch (state) { | ||
| 1311 | case BNX2X_VFOP_QTEARDOWN_RXMODE: | ||
| 1312 | /* Drop all */ | ||
| 1313 | vfop->state = BNX2X_VFOP_QTEARDOWN_CLR_VLAN; | ||
| 1314 | vfop->rc = bnx2x_vfop_rxmode_cmd(bp, vf, &cmd, qid, 0); | ||
| 1315 | if (vfop->rc) | ||
| 1316 | goto op_err; | ||
| 1317 | return; | ||
| 1318 | |||
| 1319 | case BNX2X_VFOP_QTEARDOWN_CLR_VLAN: | ||
| 1320 | /* vlan-clear-all: don't consume credit */ | ||
| 1321 | vfop->state = BNX2X_VFOP_QTEARDOWN_CLR_MAC; | ||
| 1322 | vfop->rc = bnx2x_vfop_vlan_delall_cmd(bp, vf, &cmd, qid, false); | ||
| 1323 | if (vfop->rc) | ||
| 1324 | goto op_err; | ||
| 1325 | return; | ||
| 1326 | |||
| 1327 | case BNX2X_VFOP_QTEARDOWN_CLR_MAC: | ||
| 1328 | /* mac-clear-all: consume credit */ | ||
| 1329 | vfop->state = BNX2X_VFOP_QTEARDOWN_CLR_MCAST; | ||
| 1330 | vfop->rc = bnx2x_vfop_mac_delall_cmd(bp, vf, &cmd, qid, false); | ||
| 1331 | if (vfop->rc) | ||
| 1332 | goto op_err; | ||
| 1333 | return; | ||
| 1334 | 663 | ||
| 1335 | case BNX2X_VFOP_QTEARDOWN_CLR_MCAST: | 664 | DP(BNX2X_MSG_IOV, "vf[%d:%d]\n", vf->abs_vfid, qid); |
| 1336 | vfop->state = BNX2X_VFOP_QTEARDOWN_QDTOR; | ||
| 1337 | vfop->rc = bnx2x_vfop_mcast_cmd(bp, vf, &cmd, NULL, 0, false); | ||
| 1338 | if (vfop->rc) | ||
| 1339 | goto op_err; | ||
| 1340 | return; | ||
| 1341 | 665 | ||
| 1342 | case BNX2X_VFOP_QTEARDOWN_QDTOR: | 666 | /* Remove all classification configuration for leading queue */ |
| 1343 | /* run the queue destruction flow */ | 667 | if (qid == LEADING_IDX) { |
| 1344 | DP(BNX2X_MSG_IOV, "case: BNX2X_VFOP_QTEARDOWN_QDTOR\n"); | 668 | rc = bnx2x_vf_rxmode(bp, vf, qid, 0); |
| 1345 | vfop->state = BNX2X_VFOP_QTEARDOWN_DONE; | 669 | if (rc) |
| 1346 | DP(BNX2X_MSG_IOV, "new state: BNX2X_VFOP_QTEARDOWN_DONE\n"); | ||
| 1347 | vfop->rc = bnx2x_vfop_qdtor_cmd(bp, vf, &cmd, qid); | ||
| 1348 | DP(BNX2X_MSG_IOV, "returned from cmd\n"); | ||
| 1349 | if (vfop->rc) | ||
| 1350 | goto op_err; | 670 | goto op_err; |
| 1351 | return; | ||
| 1352 | op_err: | ||
| 1353 | BNX2X_ERR("QTEARDOWN[%d:%d] error: rc %d\n", | ||
| 1354 | vf->abs_vfid, qid, vfop->rc); | ||
| 1355 | |||
| 1356 | case BNX2X_VFOP_QTEARDOWN_DONE: | ||
| 1357 | bnx2x_vfop_end(bp, vf, vfop); | ||
| 1358 | return; | ||
| 1359 | default: | ||
| 1360 | bnx2x_vfop_default(state); | ||
| 1361 | } | ||
| 1362 | } | ||
| 1363 | 671 | ||
| 1364 | int bnx2x_vfop_qdown_cmd(struct bnx2x *bp, | 672 | /* Remove filtering if feasible */ |
| 1365 | struct bnx2x_virtf *vf, | 673 | if (bnx2x_validate_vf_sp_objs(bp, vf, true)) { |
| 1366 | struct bnx2x_vfop_cmd *cmd, | 674 | rc = bnx2x_vf_vlan_mac_clear(bp, vf, qid, |
| 1367 | int qid) | 675 | false, false); |
| 1368 | { | 676 | if (rc) |
| 1369 | struct bnx2x_vfop *vfop = bnx2x_vfop_add(bp, vf); | 677 | goto op_err; |
| 1370 | 678 | rc = bnx2x_vf_vlan_mac_clear(bp, vf, qid, | |
| 1371 | /* for non leading queues skip directly to qdown sate */ | 679 | false, true); |
| 1372 | if (vfop) { | 680 | if (rc) |
| 1373 | vfop->args.qx.qid = qid; | 681 | goto op_err; |
| 1374 | bnx2x_vfop_opset(qid == LEADING_IDX ? | 682 | rc = bnx2x_vf_mcast(bp, vf, NULL, 0, false); |
| 1375 | BNX2X_VFOP_QTEARDOWN_RXMODE : | 683 | if (rc) |
| 1376 | BNX2X_VFOP_QTEARDOWN_QDTOR, bnx2x_vfop_qdown, | 684 | goto op_err; |
| 1377 | cmd->done); | 685 | } |
| 1378 | return bnx2x_vfop_transition(bp, vf, bnx2x_vfop_qdown, | ||
| 1379 | cmd->block); | ||
| 1380 | } | 686 | } |
| 1381 | 687 | ||
| 1382 | return -ENOMEM; | 688 | /* Destroy queue */ |
| 689 | rc = bnx2x_vf_queue_destroy(bp, vf, qid); | ||
| 690 | if (rc) | ||
| 691 | goto op_err; | ||
| 692 | return rc; | ||
| 693 | op_err: | ||
| 694 | BNX2X_ERR("vf[%d:%d] error: rc %d\n", | ||
| 695 | vf->abs_vfid, qid, rc); | ||
| 696 | return rc; | ||
| 1383 | } | 697 | } |
| 1384 | 698 | ||
| 1385 | /* VF enable primitives | 699 | /* VF enable primitives |
| @@ -1579,120 +893,63 @@ static void bnx2x_vf_flr_clnup_hw(struct bnx2x *bp, struct bnx2x_virtf *vf) · 193 unmodified lines | |||
| 1579 | bnx2x_tx_hw_flushed(bp, poll_cnt); | 893 | bnx2x_tx_hw_flushed(bp, poll_cnt); |
| 1580 | } | 894 | } |
| 1581 | 895 | ||
| 1582 | static void bnx2x_vfop_flr(struct bnx2x *bp, struct bnx2x_virtf *vf) | 896 | static void bnx2x_vf_flr(struct bnx2x *bp, struct bnx2x_virtf *vf) |
| 1583 | { | 897 | { |
| 1584 | struct bnx2x_vfop *vfop = bnx2x_vfop_cur(bp, vf); | 898 | int rc, i; |
| 1585 | struct bnx2x_vfop_args_qx *qx = &vfop->args.qx; | ||
| 1586 | enum bnx2x_vfop_flr_state state = vfop->state; | ||
| 1587 | struct bnx2x_vfop_cmd cmd = { | ||
| 1588 | .done = bnx2x_vfop_flr, | ||
| 1589 | .block = false, | ||
| 1590 | }; | ||
| 1591 | |||
| 1592 | if (vfop->rc < 0) | ||
| 1593 | goto op_err; | ||
| 1594 | |||
| 1595 | DP(BNX2X_MSG_IOV, "vf[%d] STATE: %d\n", vf->abs_vfid, state); | ||
| 1596 | 899 | ||
| 1597 | switch (state) { | 900 | DP(BNX2X_MSG_IOV, "vf[%d]\n", vf->abs_vfid); |
| 1598 | case BNX2X_VFOP_FLR_QUEUES: | ||
| 1599 | /* the cleanup operations are valid if and only if the VF | ||
| 1600 | * was first acquired. | ||
| 1601 | */ | ||
| 1602 | if (++(qx->qid) < vf_rxq_count(vf)) { | ||
| 1603 | vfop->rc = bnx2x_vfop_qflr_cmd(bp, vf, &cmd, | ||
| 1604 | qx->qid); | ||
| 1605 | if (vfop->rc) | ||
| 1606 | goto op_err; | ||
| 1607 | return; | ||
| 1608 | } | ||
| 1609 | /* remove multicasts */ | ||
| 1610 | vfop->state = BNX2X_VFOP_FLR_HW; | ||
| 1611 | vfop->rc = bnx2x_vfop_mcast_cmd(bp, vf, &cmd, NULL, | ||
| 1612 | 0, true); | ||
| 1613 | if (vfop->rc) | ||
| 1614 | goto op_err; | ||
| 1615 | return; | ||
| 1616 | case BNX2X_VFOP_FLR_HW: | ||
| 1617 | 901 | ||
| 1618 | /* dispatch final cleanup and wait for HW queues to flush */ | 902 | /* the cleanup operations are valid if and only if the VF |
| 1619 | bnx2x_vf_flr_clnup_hw(bp, vf); | 903 | * was first acquired. |
| 904 | */ | ||
| 905 | for (i = 0; i < vf_rxq_count(vf); i++) { | ||
| 906 | rc = bnx2x_vf_queue_flr(bp, vf, i); | ||
| 907 | if (rc) | ||
| 908 | goto out; | ||
| 909 | } | ||
| 1620 | 910 | ||
| 1621 | /* release VF resources */ | 911 | /* remove multicasts */ |
| 1622 | bnx2x_vf_free_resc(bp, vf); | 912 | bnx2x_vf_mcast(bp, vf, NULL, 0, true); |
| 1623 | 913 | ||
| 1624 | /* re-open the mailbox */ | 914 | /* dispatch final cleanup and wait for HW queues to flush */ |
| 1625 | bnx2x_vf_enable_mbx(bp, vf->abs_vfid); | 915 | bnx2x_vf_flr_clnup_hw(bp, vf); |
| 1626 | 916 | ||
| 1627 | goto op_done; | 917 | /* release VF resources */ |
| 1628 | default: | 918 | bnx2x_vf_free_resc(bp, vf); |
| 1629 | bnx2x_vfop_default(state); | ||
| 1630 | } | ||
| 1631 | op_err: | ||
| 1632 | BNX2X_ERR("VF[%d] FLR error: rc %d\n", vf->abs_vfid, vfop->rc); | ||
| 1633 | op_done: | ||
| 1634 | vf->flr_clnup_stage = VF_FLR_ACK; | ||
| 1635 | bnx2x_vfop_end(bp, vf, vfop); | ||
| 1636 | bnx2x_unlock_vf_pf_channel(bp, vf, CHANNEL_TLV_FLR); | ||
| 1637 | } | ||
| 1638 | 919 | ||
| 1639 | static int bnx2x_vfop_flr_cmd(struct bnx2x *bp, | 920 | /* re-open the mailbox */ |
| 1640 | struct bnx2x_virtf *vf, | 921 | bnx2x_vf_enable_mbx(bp, vf->abs_vfid); |
| 1641 | vfop_handler_t done) | 922 | return; |
| 1642 | { | 923 | out: |
| 1643 | struct bnx2x_vfop *vfop = bnx2x_vfop_add(bp, vf); | 924 | BNX2X_ERR("vf[%d:%d] failed flr: rc %d\n", |
| 1644 | if (vfop) { | 925 | vf->abs_vfid, i, rc); |
| 1645 | vfop->args.qx.qid = -1; /* loop */ | ||
| 1646 | bnx2x_vfop_opset(BNX2X_VFOP_FLR_QUEUES, | ||
| 1647 | bnx2x_vfop_flr, done); | ||
| 1648 | return bnx2x_vfop_transition(bp, vf, bnx2x_vfop_flr, false); | ||
| 1649 | } | ||
| 1650 | return -ENOMEM; | ||
| 1651 | } | 926 | } |
| 1652 | 927 | ||
| 1653 | static void bnx2x_vf_flr_clnup(struct bnx2x *bp, struct bnx2x_virtf *prev_vf) | 928 | static void bnx2x_vf_flr_clnup(struct bnx2x *bp) |
| 1654 | { | 929 | { |
| 1655 | int i = prev_vf ? prev_vf->index + 1 : 0; | ||
| 1656 | struct bnx2x_virtf *vf; | 930 | struct bnx2x_virtf *vf; |
| 931 | int i; | ||
| 1657 | 932 | ||
| 1658 | /* find next VF to cleanup */ | 933 | for (i = 0; i < BNX2X_NR_VIRTFN(bp); i++) { |
| 1659 | next_vf_to_clean: | 934 | /* VF should be RESET & in FLR cleanup states */ |
| 1660 | for (; | 935 | if (bnx2x_vf(bp, i, state) != VF_RESET || |
| 1661 | i < BNX2X_NR_VIRTFN(bp) && | 936 | !bnx2x_vf(bp, i, flr_clnup_stage)) |
| 1662 | (bnx2x_vf(bp, i, state) != VF_RESET || | 937 | continue; |
| 1663 | bnx2x_vf(bp, i, flr_clnup_stage) != VF_FLR_CLN); | ||
| 1664 | i++) | ||
| 1665 | ; | ||
| 1666 | 938 | ||
| 1667 | DP(BNX2X_MSG_IOV, "next vf to cleanup: %d. Num of vfs: %d\n", i, | 939 | DP(BNX2X_MSG_IOV, "next vf to cleanup: %d. Num of vfs: %d\n", |
| 1668 | BNX2X_NR_VIRTFN(bp)); | 940 | i, BNX2X_NR_VIRTFN(bp)); |
| 1669 | 941 | ||
| 1670 | if (i < BNX2X_NR_VIRTFN(bp)) { | ||
| 1671 | vf = BP_VF(bp, i); | 942 | vf = BP_VF(bp, i); |
| 1672 | 943 | ||
| 1673 | /* lock the vf pf channel */ | 944 | /* lock the vf pf channel */ |
| 1674 | bnx2x_lock_vf_pf_channel(bp, vf, CHANNEL_TLV_FLR); | 945 | bnx2x_lock_vf_pf_channel(bp, vf, CHANNEL_TLV_FLR); |
| 1675 | 946 | ||
| 1676 | /* invoke the VF FLR SM */ | 947 | /* invoke the VF FLR SM */ |
| 1677 | if (bnx2x_vfop_flr_cmd(bp, vf, bnx2x_vf_flr_clnup)) { | 948 | bnx2x_vf_flr(bp, vf); |
| 1678 | BNX2X_ERR("VF[%d]: FLR cleanup failed -ENOMEM\n", | ||
| 1679 | vf->abs_vfid); | ||
| 1680 | 949 | ||
| 1681 | /* mark the VF to be ACKED and continue */ | 950 | /* mark the VF to be ACKED and continue */ |
| 1682 | vf->flr_clnup_stage = VF_FLR_ACK; | 951 | vf->flr_clnup_stage = false; |
| 1683 | goto next_vf_to_clean; | 952 | bnx2x_unlock_vf_pf_channel(bp, vf, CHANNEL_TLV_FLR); |
| 1684 | } | ||
| 1685 | return; | ||
| 1686 | } | ||
| 1687 | |||
| 1688 | /* we are done, update vf records */ | ||
| 1689 | for_each_vf(bp, i) { | ||
| 1690 | vf = BP_VF(bp, i); | ||
| 1691 | |||
| 1692 | if (vf->flr_clnup_stage != VF_FLR_ACK) | ||
| 1693 | continue; | ||
| 1694 | |||
| 1695 | vf->flr_clnup_stage = VF_FLR_EPILOG; | ||
| 1696 | } | 953 | } |
| 1697 | 954 | ||
| 1698 | /* Acknowledge the handled VFs. | 955 | /* Acknowledge the handled VFs. |
| @@ -1742,7 +999,7 @@ void bnx2x_vf_handle_flr_event(struct bnx2x *bp) · 43 unmodified lines | |||
| 1742 | if (reset) { | 999 | if (reset) { |
| 1743 | /* set as reset and ready for cleanup */ | 1000 | /* set as reset and ready for cleanup */ |
| 1744 | vf->state = VF_RESET; | 1001 | vf->state = VF_RESET; |
| 1745 | vf->flr_clnup_stage = VF_FLR_CLN; | 1002 | vf->flr_clnup_stage = true; |
| 1746 | 1003 | ||
| 1747 | DP(BNX2X_MSG_IOV, | 1004 | DP(BNX2X_MSG_IOV, |
| 1748 | "Initiating Final cleanup for VF %d\n", | 1005 | "Initiating Final cleanup for VF %d\n", |
| @@ -1751,7 +1008,7 @@ void bnx2x_vf_handle_flr_event(struct bnx2x *bp) · 2 unmodified lines | |||
| 1751 | } | 1008 | } |
| 1752 | 1009 | ||
| 1753 | /* do the FLR cleanup for all marked VFs*/ | 1010 | /* do the FLR cleanup for all marked VFs*/ |
| 1754 | bnx2x_vf_flr_clnup(bp, NULL); | 1011 | bnx2x_vf_flr_clnup(bp); |
| 1755 | } | 1012 | } |
| 1756 | 1013 | ||
| 1757 | /* IOV global initialization routines */ | 1014 | /* IOV global initialization routines */ |
| @@ -2018,7 +1275,6 @@ int bnx2x_iov_init_one(struct bnx2x *bp, int int_mode_param, · 260 unmodified lines | |||
| 2018 | bnx2x_vf(bp, i, index) = i; | 1275 | bnx2x_vf(bp, i, index) = i; |
| 2019 | bnx2x_vf(bp, i, abs_vfid) = iov->first_vf_in_pf + i; | 1276 | bnx2x_vf(bp, i, abs_vfid) = iov->first_vf_in_pf + i; |
| 2020 | bnx2x_vf(bp, i, state) = VF_FREE; | 1277 | bnx2x_vf(bp, i, state) = VF_FREE; |
| 2021 | INIT_LIST_HEAD(&bnx2x_vf(bp, i, op_list_head)); | ||
| 2022 | mutex_init(&bnx2x_vf(bp, i, op_mutex)); | 1278 | mutex_init(&bnx2x_vf(bp, i, op_mutex)); |
| 2023 | bnx2x_vf(bp, i, op_current) = CHANNEL_TLV_NONE; | 1279 | bnx2x_vf(bp, i, op_current) = CHANNEL_TLV_NONE; |
| 2024 | } | 1280 | } |
| @@ -2039,6 +1295,9 @@ int bnx2x_iov_init_one(struct bnx2x *bp, int int_mode_param, · 14 unmodified lines | |||
| 2039 | goto failed; | 1295 | goto failed; |
| 2040 | } | 1296 | } |
| 2041 | 1297 | ||
| 1298 | /* Prepare the VFs event synchronization mechanism */ | ||
| 1299 | mutex_init(&bp->vfdb->event_mutex); | ||
| 1300 | |||
| 2042 | return 0; | 1301 | return 0; |
| 2043 | failed: | 1302 | failed: |
| 2044 | DP(BNX2X_MSG_IOV, "Failed err=%d\n", err); | 1303 | DP(BNX2X_MSG_IOV, "Failed err=%d\n", err); |
| @@ -2117,7 +1376,9 @@ int bnx2x_iov_alloc_mem(struct bnx2x *bp) · 72 unmodified lines | |||
| 2117 | cxt->size = min_t(size_t, tot_size, CDU_ILT_PAGE_SZ); | 1376 | cxt->size = min_t(size_t, tot_size, CDU_ILT_PAGE_SZ); |
| 2118 | 1377 | ||
| 2119 | if (cxt->size) { | 1378 | if (cxt->size) { |
| 2120 | BNX2X_PCI_ALLOC(cxt->addr, &cxt->mapping, cxt->size); | 1379 | cxt->addr = BNX2X_PCI_ALLOC(&cxt->mapping, cxt->size); |
| 1380 | if (!cxt->addr) | ||
| 1381 | goto alloc_mem_err; | ||
| 2121 | } else { | 1382 | } else { |
| 2122 | cxt->addr = NULL; | 1383 | cxt->addr = NULL; |
| 2123 | cxt->mapping = 0; | 1384 | cxt->mapping = 0; |
| @@ -2127,20 +1388,28 @@ int bnx2x_iov_alloc_mem(struct bnx2x *bp) · 3 unmodified lines | |||
| 2127 | 1388 | ||
| 2128 | /* allocate vfs ramrods dma memory - client_init and set_mac */ | 1389 | /* allocate vfs ramrods dma memory - client_init and set_mac */ |
| 2129 | tot_size = BNX2X_NR_VIRTFN(bp) * sizeof(struct bnx2x_vf_sp); | 1390 | tot_size = BNX2X_NR_VIRTFN(bp) * sizeof(struct bnx2x_vf_sp); |
| 2130 | BNX2X_PCI_ALLOC(BP_VFDB(bp)->sp_dma.addr, &BP_VFDB(bp)->sp_dma.mapping, | 1391 | BP_VFDB(bp)->sp_dma.addr = BNX2X_PCI_ALLOC(&BP_VFDB(bp)->sp_dma.mapping, |
| 2131 | tot_size); | 1392 | tot_size); |
| 1393 | if (!BP_VFDB(bp)->sp_dma.addr) | ||
| 1394 | goto alloc_mem_err; | ||
| 2132 | BP_VFDB(bp)->sp_dma.size = tot_size; | 1395 | BP_VFDB(bp)->sp_dma.size = tot_size; |
| 2133 | 1396 | ||
| 2134 | /* allocate mailboxes */ | 1397 | /* allocate mailboxes */ |
| 2135 | tot_size = BNX2X_NR_VIRTFN(bp) * MBX_MSG_ALIGNED_SIZE; | 1398 | tot_size = BNX2X_NR_VIRTFN(bp) * MBX_MSG_ALIGNED_SIZE; |
| 2136 | BNX2X_PCI_ALLOC(BP_VF_MBX_DMA(bp)->addr, &BP_VF_MBX_DMA(bp)->mapping, | 1399 | BP_VF_MBX_DMA(bp)->addr = BNX2X_PCI_ALLOC(&BP_VF_MBX_DMA(bp)->mapping, |
| 2137 | tot_size); | 1400 | tot_size); |
| 1401 | if (!BP_VF_MBX_DMA(bp)->addr) | ||
| 1402 | goto alloc_mem_err; | ||
| 1403 | |||
| 2138 | BP_VF_MBX_DMA(bp)->size = tot_size; | 1404 | BP_VF_MBX_DMA(bp)->size = tot_size; |
| 2139 | 1405 | ||
| 2140 | /* allocate local bulletin boards */ | 1406 | /* allocate local bulletin boards */ |
| 2141 | tot_size = BNX2X_NR_VIRTFN(bp) * BULLETIN_CONTENT_SIZE; | 1407 | tot_size = BNX2X_NR_VIRTFN(bp) * BULLETIN_CONTENT_SIZE; |
| 2142 | BNX2X_PCI_ALLOC(BP_VF_BULLETIN_DMA(bp)->addr, | 1408 | BP_VF_BULLETIN_DMA(bp)->addr = BNX2X_PCI_ALLOC(&BP_VF_BULLETIN_DMA(bp)->mapping, |
| 2143 | &BP_VF_BULLETIN_DMA(bp)->mapping, tot_size); | 1409 | tot_size); |
| 1410 | if (!BP_VF_BULLETIN_DMA(bp)->addr) | ||
| 1411 | goto alloc_mem_err; | ||
| 1412 | |||
| 2144 | BP_VF_BULLETIN_DMA(bp)->size = tot_size; | 1413 | BP_VF_BULLETIN_DMA(bp)->size = tot_size; |
| 2145 | 1414 | ||
| 2146 | return 0; | 1415 | return 0; |
| @@ -2166,6 +1435,9 @@ static void bnx2x_vfq_init(struct bnx2x *bp, struct bnx2x_virtf *vf, · 19 unmodified lines | |||
| 2166 | bnx2x_vf_sp_map(bp, vf, q_data), | 1435 | bnx2x_vf_sp_map(bp, vf, q_data), |
| 2167 | q_type); | 1436 | q_type); |
| 2168 | 1437 | ||
| 1438 | /* sp indication is set only when vlan/mac/etc. are initialized */ | ||
| 1439 | q->sp_initialized = false; | ||
| 1440 | |||
| 2169 | DP(BNX2X_MSG_IOV, | 1441 | DP(BNX2X_MSG_IOV, |
| 2170 | "initialized vf %d's queue object. func id set to %d. cid set to 0x%x\n", | 1442 | "initialized vf %d's queue object. func id set to %d. cid set to 0x%x\n", |
| 2171 | vf->abs_vfid, q->sp_obj.func_id, q->cid); | 1443 | vf->abs_vfid, q->sp_obj.func_id, q->cid); |
| @@ -2269,7 +1541,7 @@ int bnx2x_iov_chip_cleanup(struct bnx2x *bp) · 97 unmodified lines | |||
| 2269 | 1541 | ||
| 2270 | /* release all the VFs */ | 1542 | /* release all the VFs */ |
| 2271 | for_each_vf(bp, i) | 1543 | for_each_vf(bp, i) |
| 2272 | bnx2x_vf_release(bp, BP_VF(bp, i), true); /* blocking */ | 1544 | bnx2x_vf_release(bp, BP_VF(bp, i)); |
| 2273 | 1545 | ||
| 2274 | return 0; | 1546 | return 0; |
| 2275 | } | 1547 | } |
| @@ -2359,6 +1631,12 @@ void bnx2x_vf_handle_filters_eqe(struct bnx2x *bp, · 83 unmodified lines | |||
| 2359 | smp_mb__after_clear_bit(); | 1631 | smp_mb__after_clear_bit(); |
| 2360 | } | 1632 | } |
| 2361 | 1633 | ||
| 1634 | static void bnx2x_vf_handle_rss_update_eqe(struct bnx2x *bp, | ||
| 1635 | struct bnx2x_virtf *vf) | ||
| 1636 | { | ||
| 1637 | vf->rss_conf_obj.raw.clear_pending(&vf->rss_conf_obj.raw); | ||
| 1638 | } | ||
| 1639 | |||
| 2362 | int bnx2x_iov_eq_sp_event(struct bnx2x *bp, union event_ring_elem *elem) | 1640 | int bnx2x_iov_eq_sp_event(struct bnx2x *bp, union event_ring_elem *elem) |
| 2363 | { | 1641 | { |
| 2364 | struct bnx2x_virtf *vf; | 1642 | struct bnx2x_virtf *vf; |
| @@ -2383,6 +1661,7 @@ int bnx2x_iov_eq_sp_event(struct bnx2x *bp, union event_ring_elem *elem) · 18 unmodified lines | |||
| 2383 | case EVENT_RING_OPCODE_CLASSIFICATION_RULES: | 1661 | case EVENT_RING_OPCODE_CLASSIFICATION_RULES: |
| 2384 | case EVENT_RING_OPCODE_MULTICAST_RULES: | 1662 | case EVENT_RING_OPCODE_MULTICAST_RULES: |
| 2385 | case EVENT_RING_OPCODE_FILTERS_RULES: | 1663 | case EVENT_RING_OPCODE_FILTERS_RULES: |
| 1664 | case EVENT_RING_OPCODE_RSS_UPDATE_RULES: | ||
| 2386 | cid = (elem->message.data.eth_event.echo & | 1665 | cid = (elem->message.data.eth_event.echo & |
| 2387 | BNX2X_SWCID_MASK); | 1666 | BNX2X_SWCID_MASK); |
| 2388 | DP(BNX2X_MSG_IOV, "checking filtering comp cid=%d\n", cid); | 1667 | DP(BNX2X_MSG_IOV, "checking filtering comp cid=%d\n", cid); |
| @@ -2447,13 +1726,15 @@ get_vf: · 58 unmodified lines | |||
| 2447 | vf->abs_vfid, qidx); | 1726 | vf->abs_vfid, qidx); |
| 2448 | bnx2x_vf_handle_filters_eqe(bp, vf); | 1727 | bnx2x_vf_handle_filters_eqe(bp, vf); |
| 2449 | break; | 1728 | break; |
| 1729 | case EVENT_RING_OPCODE_RSS_UPDATE_RULES: | ||
| 1730 | DP(BNX2X_MSG_IOV, "got VF [%d:%d] RSS update ramrod\n", | ||
| 1731 | vf->abs_vfid, qidx); | ||
| 1732 | bnx2x_vf_handle_rss_update_eqe(bp, vf); | ||
| 2450 | case EVENT_RING_OPCODE_VF_FLR: | 1733 | case EVENT_RING_OPCODE_VF_FLR: |
| 2451 | case EVENT_RING_OPCODE_MALICIOUS_VF: | 1734 | case EVENT_RING_OPCODE_MALICIOUS_VF: |
| 2452 | /* Do nothing for now */ | 1735 | /* Do nothing for now */ |
| 2453 | return 0; | 1736 | return 0; |
| 2454 | } | 1737 | } |
| 2455 | /* SRIOV: reschedule any 'in_progress' operations */ | ||
| 2456 | bnx2x_iov_sp_event(bp, cid, false); | ||
| 2457 | 1738 | ||
| 2458 | return 0; | 1739 | return 0; |
| 2459 | } | 1740 | } |
| @@ -2490,23 +1771,6 @@ void bnx2x_iov_set_queue_sp_obj(struct bnx2x *bp, int vf_cid, · 30 unmodified lines | |||
| 2490 | } | 1771 | } |
| 2491 | } | 1772 | } |
| 2492 | 1773 | ||
| 2493 | void bnx2x_iov_sp_event(struct bnx2x *bp, int vf_cid, bool queue_work) | ||
| 2494 | { | ||
| 2495 | struct bnx2x_virtf *vf; | ||
| 2496 | |||
| 2497 | /* check if the cid is the VF range */ | ||
| 2498 | if (!IS_SRIOV(bp) || !bnx2x_iov_is_vf_cid(bp, vf_cid)) | ||
| 2499 | return; | ||
| 2500 | |||
| 2501 | vf = bnx2x_vf_by_cid(bp, vf_cid); | ||
| 2502 | if (vf) { | ||
| 2503 | /* set in_progress flag */ | ||
| 2504 | atomic_set(&vf->op_in_progress, 1); | ||
| 2505 | if (queue_work) | ||
| 2506 | queue_delayed_work(bnx2x_wq, &bp->sp_task, 0); | ||
| 2507 | } | ||
| 2508 | } | ||
| 2509 | |||
| 2510 | void bnx2x_iov_adjust_stats_req(struct bnx2x *bp) | 1774 | void bnx2x_iov_adjust_stats_req(struct bnx2x *bp) |
| 2511 | { | 1775 | { |
| 2512 | int i; | 1776 | int i; |
| @@ -2527,10 +1791,10 @@ void bnx2x_iov_adjust_stats_req(struct bnx2x *bp) · 14 unmodified lines | |||
| 2527 | first_queue_query_index = BNX2X_FIRST_QUEUE_QUERY_IDX - | 1791 | first_queue_query_index = BNX2X_FIRST_QUEUE_QUERY_IDX - |
| 2528 | (is_fcoe ? 0 : 1); | 1792 | (is_fcoe ? 0 : 1); |
| 2529 | 1793 | ||
| 2530 | DP(BNX2X_MSG_IOV, | 1794 | DP_AND((BNX2X_MSG_IOV | BNX2X_MSG_STATS), |
| 2531 | "BNX2X_NUM_ETH_QUEUES %d, is_fcoe %d, first_queue_query_index %d => determined the last non virtual statistics query index is %d. Will add queries on top of that\n", | 1795 | "BNX2X_NUM_ETH_QUEUES %d, is_fcoe %d, first_queue_query_index %d => determined the last non virtual statistics query index is %d. Will add queries on top of that\n", |
| 2532 | BNX2X_NUM_ETH_QUEUES(bp), is_fcoe, first_queue_query_index, | 1796 | BNX2X_NUM_ETH_QUEUES(bp), is_fcoe, first_queue_query_index, |
| 2533 | first_queue_query_index + num_queues_req); | 1797 | first_queue_query_index + num_queues_req); |
| 2534 | 1798 | ||
| 2535 | cur_data_offset = bp->fw_stats_data_mapping + | 1799 | cur_data_offset = bp->fw_stats_data_mapping + |
| 2536 | offsetof(struct bnx2x_fw_stats_data, queue_stats) + | 1800 | offsetof(struct bnx2x_fw_stats_data, queue_stats) + |
| @@ -2544,9 +1808,9 @@ void bnx2x_iov_adjust_stats_req(struct bnx2x *bp) · 7 unmodified lines | |||
| 2544 | struct bnx2x_virtf *vf = BP_VF(bp, i); | 1808 | struct bnx2x_virtf *vf = BP_VF(bp, i); |
| 2545 | 1809 | ||
| 2546 | if (vf->state != VF_ENABLED) { | 1810 | if (vf->state != VF_ENABLED) { |
| 2547 | DP(BNX2X_MSG_IOV, | 1811 | DP_AND((BNX2X_MSG_IOV | BNX2X_MSG_STATS), |
| 2548 | "vf %d not enabled so no stats for it\n", | 1812 | "vf %d not enabled so no stats for it\n", |
| 2549 | vf->abs_vfid); | 1813 | vf->abs_vfid); |
| 2550 | continue; | 1814 | continue; |
| 2551 | } | 1815 | } |
| 2552 | 1816 | ||
| @@ -2588,32 +1852,6 @@ void bnx2x_iov_adjust_stats_req(struct bnx2x *bp) · 35 unmodified lines | |||
| 2588 | bp->fw_stats_req->hdr.cmd_num = bp->fw_stats_num + stats_count; | 1852 | bp->fw_stats_req->hdr.cmd_num = bp->fw_stats_num + stats_count; |
| 2589 | } | 1853 | } |
| 2590 | 1854 | ||
| 2591 | void bnx2x_iov_sp_task(struct bnx2x *bp) | ||
| 2592 | { | ||
| 2593 | int i; | ||
| 2594 | |||
| 2595 | if (!IS_SRIOV(bp)) | ||
| 2596 | return; | ||
| 2597 | /* Iterate over all VFs and invoke state transition for VFs with | ||
| 2598 | * 'in-progress' slow-path operations | ||
| 2599 | */ | ||
| 2600 | DP(BNX2X_MSG_IOV, "searching for pending vf operations\n"); | ||
| 2601 | for_each_vf(bp, i) { | ||
| 2602 | struct bnx2x_virtf *vf = BP_VF(bp, i); | ||
| 2603 | |||
| 2604 | if (!vf) { | ||
| 2605 | BNX2X_ERR("VF was null! skipping...\n"); | ||
| 2606 | continue; | ||
| 2607 | } | ||
| 2608 | |||
| 2609 | if (!list_empty(&vf->op_list_head) && | ||
| 2610 | atomic_read(&vf->op_in_progress)) { | ||
| 2611 | DP(BNX2X_MSG_IOV, "running pending op for vf %d\n", i); | ||
| 2612 | bnx2x_vfop_cur(bp, vf)->transition(bp, vf); | ||
| 2613 | } | ||
| 2614 | } | ||
| 2615 | } | ||
| 2616 | |||
| 2617 | static inline | 1855 | static inline |
| 2618 | struct bnx2x_virtf *__vf_from_stat_id(struct bnx2x *bp, u8 stat_id) | 1856 | struct bnx2x_virtf *__vf_from_stat_id(struct bnx2x *bp, u8 stat_id) |
| 2619 | { | 1857 | { |
| @@ -2849,52 +2087,26 @@ static void bnx2x_set_vf_state(void *cookie) · 229 unmodified lines | |||
| 2849 | p->vf->state = p->state; | 2087 | p->vf->state = p->state; |
| 2850 | } | 2088 | } |
| 2851 | 2089 | ||
| 2852 | /* VFOP close (teardown the queues, delete mcasts and close HW) */ | 2090 | int bnx2x_vf_close(struct bnx2x *bp, struct bnx2x_virtf *vf) |
| 2853 | static void bnx2x_vfop_close(struct bnx2x *bp, struct bnx2x_virtf *vf) | ||
| 2854 | { | 2091 | { |
| 2855 | struct bnx2x_vfop *vfop = bnx2x_vfop_cur(bp, vf); | 2092 | int rc = 0, i; |
| 2856 | struct bnx2x_vfop_args_qx *qx = &vfop->args.qx; | ||
| 2857 | enum bnx2x_vfop_close_state state = vfop->state; | ||
| 2858 | struct bnx2x_vfop_cmd cmd = { | ||
| 2859 | .done = bnx2x_vfop_close, | ||
| 2860 | .block = false, | ||
| 2861 | }; | ||
| 2862 | 2093 | ||
| 2863 | if (vfop->rc < 0) | 2094 | DP(BNX2X_MSG_IOV, "vf[%d]\n", vf->abs_vfid); |
| 2864 | goto op_err; | ||
| 2865 | |||
| 2866 | DP(BNX2X_MSG_IOV, "vf[%d] STATE: %d\n", vf->abs_vfid, state); | ||
| 2867 | |||
| 2868 | switch (state) { | ||
| 2869 | case BNX2X_VFOP_CLOSE_QUEUES: | ||
| 2870 | |||
| 2871 | if (++(qx->qid) < vf_rxq_count(vf)) { | ||
| 2872 | vfop->rc = bnx2x_vfop_qdown_cmd(bp, vf, &cmd, qx->qid); | ||
| 2873 | if (vfop->rc) | ||
| 2874 | goto op_err; | ||
| 2875 | return; | ||
| 2876 | } | ||
| 2877 | vfop->state = BNX2X_VFOP_CLOSE_HW; | ||
| 2878 | vfop->rc = 0; | ||
| 2879 | bnx2x_vfop_finalize(vf, vfop->rc, VFOP_CONT); | ||
| 2880 | 2095 | ||
| 2881 | case BNX2X_VFOP_CLOSE_HW: | 2096 | /* Close all queues */ |
| 2882 | 2097 | for (i = 0; i < vf_rxq_count(vf); i++) { | |
| 2883 | /* disable the interrupts */ | 2098 | rc = bnx2x_vf_queue_teardown(bp, vf, i); |
| 2884 | DP(BNX2X_MSG_IOV, "disabling igu\n"); | 2099 | if (rc) |
| 2885 | bnx2x_vf_igu_disable(bp, vf); | 2100 | goto op_err; |
| 2101 | } | ||
| 2886 | 2102 | ||
| 2887 | /* disable the VF */ | 2103 | /* disable the interrupts */ |
| 2888 | DP(BNX2X_MSG_IOV, "clearing qtbl\n"); | 2104 | DP(BNX2X_MSG_IOV, "disabling igu\n"); |
| 2889 | bnx2x_vf_clr_qtbl(bp, vf); | 2105 | bnx2x_vf_igu_disable(bp, vf); |
| 2890 | 2106 | ||
| 2891 | goto op_done; | 2107 | /* disable the VF */ |
| 2892 | default: | 2108 | DP(BNX2X_MSG_IOV, "clearing qtbl\n"); |
| 2893 | bnx2x_vfop_default(state); | 2109 | bnx2x_vf_clr_qtbl(bp, vf); |
| 2894 | } | ||
| 2895 | op_err: | ||
| 2896 | BNX2X_ERR("VF[%d] CLOSE error: rc %d\n", vf->abs_vfid, vfop->rc); | ||
| 2897 | op_done: | ||
| 2898 | 2110 | ||
| 2899 | /* need to make sure there are no outstanding stats ramrods which may | 2111 | /* need to make sure there are no outstanding stats ramrods which may |
| 2900 | * cause the device to access the VF's stats buffer which it will free | 2112 | * cause the device to access the VF's stats buffer which it will free |
| @@ -2909,43 +2121,20 @@ op_done: · 8 unmodified lines | |||
| 2909 | } | 2121 | } |
| 2910 | 2122 | ||
| 2911 | DP(BNX2X_MSG_IOV, "set state to acquired\n"); | 2123 | DP(BNX2X_MSG_IOV, "set state to acquired\n"); |
| 2912 | bnx2x_vfop_end(bp, vf, vfop); | ||
| 2913 | op_pending: | ||
| 2914 | /* Not supported at the moment; Exists for macros only */ | ||
| 2915 | return; | ||
| 2916 | } | ||
| 2917 | 2124 | ||
| 2918 | int bnx2x_vfop_close_cmd(struct bnx2x *bp, | 2125 | return 0; |
| 2919 | struct bnx2x_virtf *vf, | 2126 | op_err: |
| 2920 | struct bnx2x_vfop_cmd *cmd) | 2127 | BNX2X_ERR("vf[%d] CLOSE error: rc %d\n", vf->abs_vfid, rc); |
| 2921 | { | 2128 | return rc; |
| 2922 | struct bnx2x_vfop *vfop = bnx2x_vfop_add(bp, vf); | ||
| 2923 | if (vfop) { | ||
| 2924 | vfop->args.qx.qid = -1; /* loop */ | ||
| 2925 | bnx2x_vfop_opset(BNX2X_VFOP_CLOSE_QUEUES, | ||
| 2926 | bnx2x_vfop_close, cmd->done); | ||
| 2927 | return bnx2x_vfop_transition(bp, vf, bnx2x_vfop_close, | ||
| 2928 | cmd->block); | ||
| 2929 | } | ||
| 2930 | return -ENOMEM; | ||
| 2931 | } | 2129 | } |
| 2932 | 2130 | ||
| 2933 | /* VF release can be called either: 1. The VF was acquired but | 2131 | /* VF release can be called either: 1. The VF was acquired but |
| 2934 | * not enabled 2. the vf was enabled or in the process of being | 2132 | * not enabled 2. the vf was enabled or in the process of being |
| 2935 | * enabled | 2133 | * enabled |
| 2936 | */ | 2134 | */ |
| 2937 | static void bnx2x_vfop_release(struct bnx2x *bp, struct bnx2x_virtf *vf) | 2135 | int bnx2x_vf_free(struct bnx2x *bp, struct bnx2x_virtf *vf) |
| 2938 | { | 2136 | { |
| 2939 | struct bnx2x_vfop *vfop = bnx2x_vfop_cur(bp, vf); | 2137 | int rc; |
| 2940 | struct bnx2x_vfop_cmd cmd = { | ||
| 2941 | .done = bnx2x_vfop_release, | ||
| 2942 | .block = false, | ||
| 2943 | }; | ||
| 2944 | |||
| 2945 | DP(BNX2X_MSG_IOV, "vfop->rc %d\n", vfop->rc); | ||
| 2946 | |||
| 2947 | if (vfop->rc < 0) | ||
| 2948 | goto op_err; | ||
| 2949 | 2138 | ||
| 2950 | DP(BNX2X_MSG_IOV, "VF[%d] STATE: %s\n", vf->abs_vfid, | 2139 | DP(BNX2X_MSG_IOV, "VF[%d] STATE: %s\n", vf->abs_vfid, |
| 2951 | vf->state == VF_FREE ? "Free" : | 2140 | vf->state == VF_FREE ? "Free" : |
| @@ -2956,116 +2145,87 @@ static void bnx2x_vfop_release(struct bnx2x *bp, struct bnx2x_virtf *vf) · 4 unmodified lines | |||
| 2956 | 2145 | ||
| 2957 | switch (vf->state) { | 2146 | switch (vf->state) { |
| 2958 | case VF_ENABLED: | 2147 | case VF_ENABLED: |
| 2959 | vfop->rc = bnx2x_vfop_close_cmd(bp, vf, &cmd); | 2148 | rc = bnx2x_vf_close(bp, vf); |
| 2960 | if (vfop->rc) | 2149 | if (rc) |
| 2961 | goto op_err; | 2150 | goto op_err; |
| 2962 | return; | 2151 | /* Fallthrough to release resources */ |
| 2963 | |||
| 2964 | case VF_ACQUIRED: | 2152 | case VF_ACQUIRED: |
| 2965 | DP(BNX2X_MSG_IOV, "about to free resources\n"); | 2153 | DP(BNX2X_MSG_IOV, "about to free resources\n"); |
| 2966 | bnx2x_vf_free_resc(bp, vf); | 2154 | bnx2x_vf_free_resc(bp, vf); |
| 2967 | DP(BNX2X_MSG_IOV, "vfop->rc %d\n", vfop->rc); | 2155 | break; |
| 2968 | goto op_done; | ||
| 2969 | 2156 | ||
| 2970 | case VF_FREE: | 2157 | case VF_FREE: |
| 2971 | case VF_RESET: | 2158 | case VF_RESET: |
| 2972 | /* do nothing */ | ||
| 2973 | goto op_done; | ||
| 2974 | default: | 2159 | default: |
| 2975 | bnx2x_vfop_default(vf->state); | 2160 | break; |
| 2976 | } | 2161 | } |
| 2162 | return 0; | ||
| 2977 | op_err: | 2163 | op_err: |
| 2978 | BNX2X_ERR("VF[%d] RELEASE error: rc %d\n", vf->abs_vfid, vfop->rc); | 2164 | BNX2X_ERR("VF[%d] RELEASE error: rc %d\n", vf->abs_vfid, rc); |
| 2979 | op_done: | 2165 | return rc; |
| 2980 | bnx2x_vfop_end(bp, vf, vfop); | ||
| 2981 | } | 2166 | } |
| 2982 | 2167 | ||
| 2983 | static void bnx2x_vfop_rss(struct bnx2x *bp, struct bnx2x_virtf *vf) | 2168 | int bnx2x_vf_rss_update(struct bnx2x *bp, struct bnx2x_virtf *vf, |
| 2169 | struct bnx2x_config_rss_params *rss) | ||
| 2984 | { | 2170 | { |
| 2985 | struct bnx2x_vfop *vfop = bnx2x_vfop_cur(bp, vf); | 2171 | DP(BNX2X_MSG_IOV, "vf[%d]\n", vf->abs_vfid); |
| 2986 | enum bnx2x_vfop_rss_state state; | 2172 | set_bit(RAMROD_COMP_WAIT, &rss->ramrod_flags); |
| 2987 | 2173 | return bnx2x_config_rss(bp, rss); | |
| 2988 | if (!vfop) { | ||
| 2989 | BNX2X_ERR("vfop was null\n"); | ||
| 2990 | return; | ||
| 2991 | } | ||
| 2992 | |||
| 2993 | state = vfop->state; | ||
| 2994 | bnx2x_vfop_reset_wq(vf); | ||
| 2995 | |||
| 2996 | if (vfop->rc < 0) | ||
| 2997 | goto op_err; | ||
| 2998 | |||
| 2999 | DP(BNX2X_MSG_IOV, "vf[%d] STATE: %d\n", vf->abs_vfid, state); | ||
| 3000 | |||
| 3001 | switch (state) { | ||
| 3002 | case BNX2X_VFOP_RSS_CONFIG: | ||
| 3003 | /* next state */ | ||
| 3004 | vfop->state = BNX2X_VFOP_RSS_DONE; | ||
| 3005 | bnx2x_config_rss(bp, &vfop->op_p->rss); | ||
| 3006 | bnx2x_vfop_finalize(vf, vfop->rc, VFOP_DONE); | ||
| 3007 | op_err: | ||
| 3008 | BNX2X_ERR("RSS error: rc %d\n", vfop->rc); | ||
| 3009 | op_done: | ||
| 3010 | case BNX2X_VFOP_RSS_DONE: | ||
| 3011 | bnx2x_vfop_end(bp, vf, vfop); | ||
| 3012 | return; | ||
| 3013 | default: | ||
| 3014 | bnx2x_vfop_default(state); | ||
| 3015 | } | ||
| 3016 | op_pending: | ||
| 3017 | return; | ||
| 3018 | } | 2174 | } |
| 3019 | 2175 | ||
| 3020 | int bnx2x_vfop_release_cmd(struct bnx2x *bp, | 2176 | int bnx2x_vf_tpa_update(struct bnx2x *bp, struct bnx2x_virtf *vf, |
| 3021 | struct bnx2x_virtf *vf, | 2177 | struct vfpf_tpa_tlv *tlv, |
| 3022 | struct bnx2x_vfop_cmd *cmd) | 2178 | struct bnx2x_queue_update_tpa_params *params) |
| 3023 | { | 2179 | { |
| 3024 | struct bnx2x_vfop *vfop = bnx2x_vfop_add(bp, vf); | 2180 | aligned_u64 *sge_addr = tlv->tpa_client_info.sge_addr; |
| 3025 | if (vfop) { | 2181 | struct bnx2x_queue_state_params qstate; |
| 3026 | bnx2x_vfop_opset(-1, /* use vf->state */ | 2182 | int qid, rc = 0; |
| 3027 | bnx2x_vfop_release, cmd->done); | ||
| 3028 | return bnx2x_vfop_transition(bp, vf, bnx2x_vfop_release, | ||
| 3029 | cmd->block); | ||
| 3030 | } | ||
| 3031 | return -ENOMEM; | ||
| 3032 | } | ||
| 3033 | 2183 | ||
| 3034 | int bnx2x_vfop_rss_cmd(struct bnx2x *bp, | 2184 | DP(BNX2X_MSG_IOV, "vf[%d]\n", vf->abs_vfid); |
| 3035 | struct bnx2x_virtf *vf, | 2185 | |
| 3036 | struct bnx2x_vfop_cmd *cmd) | 2186 | /* Set ramrod params */ |
| 3037 | { | 2187 | memset(&qstate, 0, sizeof(struct bnx2x_queue_state_params)); |
| 3038 | struct bnx2x_vfop *vfop = bnx2x_vfop_add(bp, vf); | 2188 | memcpy(&qstate.params.update_tpa, params, |
| 2189 | sizeof(struct bnx2x_queue_update_tpa_params)); | ||
| 2190 | qstate.cmd = BNX2X_Q_CMD_UPDATE_TPA; | ||
| 2191 | set_bit(RAMROD_COMP_WAIT, &qstate.ramrod_flags); | ||
| 3039 | 2192 | ||
| 3040 | if (vfop) { | 2193 | for (qid = 0; qid < vf_rxq_count(vf); qid++) { |
| 3041 | bnx2x_vfop_opset(BNX2X_VFOP_RSS_CONFIG, bnx2x_vfop_rss, | 2194 | qstate.q_obj = &bnx2x_vfq(vf, qid, sp_obj); |
| 3042 | cmd->done); | 2195 | qstate.params.update_tpa.sge_map = sge_addr[qid]; |
| 3043 | return bnx2x_vfop_transition(bp, vf, bnx2x_vfop_rss, | 2196 | DP(BNX2X_MSG_IOV, "sge_addr[%d:%d] %08x:%08x\n", |
| 3044 | cmd->block); | 2197 | vf->abs_vfid, qid, U64_HI(sge_addr[qid]), |
| 2198 | U64_LO(sge_addr[qid])); | ||
| 2199 | rc = bnx2x_queue_state_change(bp, &qstate); | ||
| 2200 | if (rc) { | ||
| 2201 | BNX2X_ERR("Failed to configure sge_addr %08x:%08x for [%d:%d]\n", | ||
| 2202 | U64_HI(sge_addr[qid]), U64_LO(sge_addr[qid]), | ||
| 2203 | vf->abs_vfid, qid); | ||
| 2204 | return rc; | ||
| 2205 | } | ||
| 3045 | } | 2206 | } |
177 more lines aren’t shown here.
This diff is large: its 482 lines aren’t shown here.
This diff is large: its 950 lines aren’t shown here.
This diff is large: its 50 lines aren’t shown here.
This diff is large: its 3 lines aren’t shown here.
This diff is large: its 2585 lines aren’t shown here.
This diff is large: its 629 lines aren’t shown here.
This diff is large: its 465 lines aren’t shown here.
This diff is large: its 114 lines aren’t shown here.
This diff is large: its 170 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 63 lines aren’t shown here.
This diff is large: its 456 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 328 lines aren’t shown here.
This diff is large: its 203 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 66 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 76 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 101 lines aren’t shown here.
This diff is large: its 296 lines aren’t shown here.
This diff is large: its 182 lines aren’t shown here.
This diff is large: its 70 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 828 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 54 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 2003 lines aren’t shown here.
This diff is large: its 239 lines aren’t shown here.
This diff is large: its 269 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 341 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 51 lines aren’t shown here.
This diff is large: its 51 lines aren’t shown here.
This diff is large: its 51 lines aren’t shown here.
This diff is large: its 51 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 66 lines aren’t shown here.
This diff is large: its 84 lines aren’t shown here.
This diff is large: its 110 lines aren’t shown here.
This diff is large: its 72 lines aren’t shown here.
This diff is large: its 525 lines aren’t shown here.
This diff is large: its 124 lines aren’t shown here.
This diff is large: its 51 lines aren’t shown here.
This diff is large: its 51 lines aren’t shown here.
This diff is large: its 51 lines aren’t shown here.
This diff is large: its 51 lines aren’t shown here.
This diff is large: its 762 lines aren’t shown here.
This diff is large: its 51 lines aren’t shown here.
This diff is large: its 51 lines aren’t shown here.
This diff is large: its 64 lines aren’t shown here.
This diff is large: its 51 lines aren’t shown here.
This diff is large: its 51 lines aren’t shown here.
This diff is large: its 85 lines aren’t shown here.
This diff is large: its 59 lines aren’t shown here.
This diff is large: its 124 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 385 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 192 lines aren’t shown here.
This diff is large: its 608 lines aren’t shown here.
This diff is large: its 1169 lines aren’t shown here.
This diff is large: its 242 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 612 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.
This diff is large: its 226 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 383 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 199 lines aren’t shown here.
This diff is large: its 58 lines aren’t shown here.
This diff is large: its 139 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 588 lines aren’t shown here.
This diff is large: its 55 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 70 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.
This diff is large: its 111 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 95 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 97 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 83 lines aren’t shown here.
This diff is large: its 82 lines aren’t shown here.
This diff is large: its 188 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 387 lines aren’t shown here.
This diff is large: its 204 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 48 lines aren’t shown here.
This diff is large: its 94 lines aren’t shown here.
This diff is large: its 597 lines aren’t shown here.
This diff is large: its 359 lines aren’t shown here.
This diff is large: its 52 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 71 lines aren’t shown here.
This diff is large: its 41 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 39 lines aren’t shown here.
This diff is large: its 532 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 94 lines aren’t shown here.
This diff is large: its 43 lines aren’t shown here.
This diff is large: its 117 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 107 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 192 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.
This diff is large: its 419 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 47 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 56 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 79 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 243 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 75 lines aren’t shown here.
This diff is large: its 260 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 42 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 120 lines aren’t shown here.
This diff is large: its 123 lines aren’t shown here.
This diff is large: its 201 lines aren’t shown here.
This diff is large: its 283 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.
This diff is large: its 72 lines aren’t shown here.
This diff is large: its 327 lines aren’t shown here.
This diff is large: its 541 lines aren’t shown here.
This diff is large: its 39 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 70 lines aren’t shown here.
This diff is large: its 50 lines aren’t shown here.
This diff is large: its 115 lines aren’t shown here.
This diff is large: its 162 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 212 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 109 lines aren’t shown here.
This diff is large: its 65 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 271 lines aren’t shown here.
This diff is large: its 177 lines aren’t shown here.
This diff is large: its 380 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 215 lines aren’t shown here.
This diff is large: its 45 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 49 lines aren’t shown here.
This diff is large: its 586 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 6 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 5 lines aren’t shown here.
This diff is large: its 536 lines aren’t shown here.
This diff is large: its 263 lines aren’t shown here.
This diff is large: its 516 lines aren’t shown here.
This diff is large: its 299 lines aren’t shown here.
This diff is large: its 383 lines aren’t shown here.
This diff is large: its 51 lines aren’t shown here.
This diff is large: its 525 lines aren’t shown here.
This diff is large: its 2318 lines aren’t shown here.
This diff is large: its 245 lines aren’t shown here.
This diff is large: its 255 lines aren’t shown here.
This diff is large: its 105 lines aren’t shown here.
This diff is large: its 260 lines aren’t shown here.
This diff is large: its 489 lines aren’t shown here.
This diff is large: its 92 lines aren’t shown here.
This diff is large: its 39 lines aren’t shown here.
This diff is large: its 75 lines aren’t shown here.
This diff is large: its 75 lines aren’t shown here.
This diff is large: its 103 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 118 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 5 lines aren’t shown here.
This diff is large: its 210 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 48 lines aren’t shown here.
This diff is large: its 63 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 131 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 107 lines aren’t shown here.
This diff is large: its 39 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 45 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 57 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 298 lines aren’t shown here.
This diff is large: its 229 lines aren’t shown here.
This diff is large: its 403 lines aren’t shown here.
This diff is large: its 247 lines aren’t shown here.
This diff is large: its 48 lines aren’t shown here.
This diff is large: its 781 lines aren’t shown here.
This diff is large: its 63 lines aren’t shown here.
This diff is large: its 43 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 55 lines aren’t shown here.
This diff is large: its 42 lines aren’t shown here.
This diff is large: its 41 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 51 lines aren’t shown here.
This diff is large: its 360 lines aren’t shown here.
This diff is large: its 59 lines aren’t shown here.
This diff is large: its 216 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 92 lines aren’t shown here.
This diff is large: its 98 lines aren’t shown here.
This diff is large: its 114 lines aren’t shown here.
This diff is large: its 130 lines aren’t shown here.
This diff is large: its 95 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 1978 lines aren’t shown here.
This diff is large: its 55 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 160 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 52 lines aren’t shown here.
This diff is large: its 5 lines aren’t shown here.
This diff is large: its 62 lines aren’t shown here.
This diff is large: its 43 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 76 lines aren’t shown here.
This diff is large: its 162 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 47 lines aren’t shown here.
This diff is large: its 63 lines aren’t shown here.
This diff is large: its 54 lines aren’t shown here.
This diff is large: its 490 lines aren’t shown here.
This diff is large: its 301 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 1516 lines aren’t shown here.
This diff is large: its 736 lines aren’t shown here.
This diff is large: its 49 lines aren’t shown here.
This diff is large: its 91 lines aren’t shown here.
This diff is large: its 259 lines aren’t shown here.
This diff is large: its 76 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 70 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 39 lines aren’t shown here.
This diff is large: its 75 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 131 lines aren’t shown here.
This diff is large: its 381 lines aren’t shown here.
This diff is large: its 90 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 112 lines aren’t shown here.
This diff is large: its 330 lines aren’t shown here.
This diff is large: its 181 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 245 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 251 lines aren’t shown here.
This diff is large: its 49 lines aren’t shown here.
This diff is large: its 134 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 74 lines aren’t shown here.
This diff is large: its 387 lines aren’t shown here.
This diff is large: its 350 lines aren’t shown here.
This diff is large: its 188 lines aren’t shown here.
This diff is large: its 218 lines aren’t shown here.
This diff is large: its 50 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 342 lines aren’t shown here.
This diff is large: its 62 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 261 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 1496 lines aren’t shown here.
This diff is large: its 249 lines aren’t shown here.
This diff is large: its 304 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 89 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 45 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 114 lines aren’t shown here.
This diff is large: its 178 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 45 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 382 lines aren’t shown here.
This diff is large: its 257 lines aren’t shown here.
This diff is large: its 64 lines aren’t shown here.
This diff is large: its 394 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 67 lines aren’t shown here.
This diff is large: its 178 lines aren’t shown here.
This diff is large: its 556 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 275 lines aren’t shown here.
This diff is large: its 255 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 42 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 45 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 258 lines aren’t shown here.
This diff is large: its 1035 lines aren’t shown here.
This diff is large: its 92 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 1511 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 973 lines aren’t shown here.
This diff is large: its 232 lines aren’t shown here.
This diff is large: its 98 lines aren’t shown here.
This diff is large: its 625 lines aren’t shown here.
This diff is large: its 56 lines aren’t shown here.
This diff is large: its 41 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 114 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 85 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 104 lines aren’t shown here.
This diff is large: its 133 lines aren’t shown here.
This diff is large: its 54 lines aren’t shown here.
This diff is large: its 102 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 100 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 87 lines aren’t shown here.
This diff is large: its 39 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 403 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 82 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 88 lines aren’t shown here.
This diff is large: its 109 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 600 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 351 lines aren’t shown here.
This diff is large: its 189 lines aren’t shown here.
This diff is large: its 610 lines aren’t shown here.
This diff is large: its 44 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 77 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 63 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 197 lines aren’t shown here.
This diff is large: its 107 lines aren’t shown here.
This diff is large: its 131 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 105 lines aren’t shown here.
This diff is large: its 996 lines aren’t shown here.
This diff is large: its 522 lines aren’t shown here.
This diff is large: its 167 lines aren’t shown here.
This diff is large: its 216 lines aren’t shown here.
This diff is large: its 646 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 561 lines aren’t shown here.
This diff is large: its 320 lines aren’t shown here.
This diff is large: its 152 lines aren’t shown here.
This diff is large: its 498 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 86 lines aren’t shown here.
This diff is large: its 504 lines aren’t shown here.
This diff is large: its 400 lines aren’t shown here.
This diff is large: its 115 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 104 lines aren’t shown here.
This diff is large: its 199 lines aren’t shown here.
This diff is large: its 119 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 77 lines aren’t shown here.
This diff is large: its 551 lines aren’t shown here.
This diff is large: its 111 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 268 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 289 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 196 lines aren’t shown here.
This diff is large: its 79 lines aren’t shown here.
This diff is large: its 352 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 673 lines aren’t shown here.
This diff is large: its 249 lines aren’t shown here.
This diff is large: its 339 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 41 lines aren’t shown here.
This diff is large: its 415 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 43 lines aren’t shown here.
This diff is large: its 66 lines aren’t shown here.
This diff is large: its 154 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 273 lines aren’t shown here.
This diff is large: its 516 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 721 lines aren’t shown here.
This diff is large: its 53 lines aren’t shown here.
This diff is large: its 48 lines aren’t shown here.
This diff is large: its 617 lines aren’t shown here.
This diff is large: its 198 lines aren’t shown here.
This diff is large: its 120 lines aren’t shown here.
This diff is large: its 370 lines aren’t shown here.
This diff is large: its 58 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 1045 lines aren’t shown here.
This diff is large: its 45 lines aren’t shown here.
This diff is large: its 153 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 44 lines aren’t shown here.
This diff is large: its 143 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 247 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 275 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 343 lines aren’t shown here.
This diff is large: its 340 lines aren’t shown here.
This diff is large: its 1009 lines aren’t shown here.
This diff is large: its 296 lines aren’t shown here.
This diff is large: its 1305 lines aren’t shown here.
This diff is large: its 197 lines aren’t shown here.
This diff is large: its 851 lines aren’t shown here.
This diff is large: its 567 lines aren’t shown here.
This diff is large: its 576 lines aren’t shown here.
This diff is large: its 178 lines aren’t shown here.
This diff is large: its 127 lines aren’t shown here.
This diff is large: its 88 lines aren’t shown here.
This diff is large: its 49 lines aren’t shown here.
This diff is large: its 219 lines aren’t shown here.
This diff is large: its 286 lines aren’t shown here.
This diff is large: its 130 lines aren’t shown here.
This diff is large: its 69 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 6 lines aren’t shown here.
This diff is large: its 1448 lines aren’t shown here.
This diff is large: its 122 lines aren’t shown here.
This diff is large: its 49 lines aren’t shown here.
This diff is large: its 476 lines aren’t shown here.
This diff is large: its 62 lines aren’t shown here.
This diff is large: its 60 lines aren’t shown here.
This diff is large: its 331 lines aren’t shown here.
This diff is large: its 52 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 76 lines aren’t shown here.
This diff is large: its 3699 lines aren’t shown here.
This diff is large: its 174 lines aren’t shown here.
This diff is large: its 1012 lines aren’t shown here.
This diff is large: its 560 lines aren’t shown here.
This diff is large: its 219 lines aren’t shown here.
This diff is large: its 53 lines aren’t shown here.
This diff is large: its 207 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 251 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 179 lines aren’t shown here.
This diff is large: its 67 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 39 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 406 lines aren’t shown here.
This diff is large: its 112 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 48 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 109 lines aren’t shown here.
This diff is large: its 110 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 96 lines aren’t shown here.
This diff is large: its 110 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 155 lines aren’t shown here.
This diff is large: its 62 lines aren’t shown here.
This diff is large: its 1020 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 129 lines aren’t shown here.
This diff is large: its 130 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 98 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 285 lines aren’t shown here.
This diff is large: its 43 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 359 lines aren’t shown here.
This diff is large: its 727 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 41 lines aren’t shown here.
This diff is large: its 46 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 249 lines aren’t shown here.
This diff is large: its 1326 lines aren’t shown here.
This diff is large: its 311 lines aren’t shown here.
This diff is large: its 621 lines aren’t shown here.
This diff is large: its 249 lines aren’t shown here.
This diff is large: its 2524 lines aren’t shown here.
This diff is large: its 65 lines aren’t shown here.
This diff is large: its 154 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 2157 lines aren’t shown here.
This diff is large: its 218 lines aren’t shown here.
This diff is large: its 107 lines aren’t shown here.
This diff is large: its 305 lines aren’t shown here.
This diff is large: its 141 lines aren’t shown here.
This diff is large: its 96 lines aren’t shown here.
This diff is large: its 2278 lines aren’t shown here.
This diff is large: its 505 lines aren’t shown here.
This diff is large: its 44 lines aren’t shown here.
This diff is large: its 385 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 573 lines aren’t shown here.
This diff is large: its 44 lines aren’t shown here.
This diff is large: its 961 lines aren’t shown here.
This diff is large: its 618 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 66 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 330 lines aren’t shown here.
This diff is large: its 127 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 435 lines aren’t shown here.
This diff is large: its 90 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 903 lines aren’t shown here.
This diff is large: its 59 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 66 lines aren’t shown here.
This diff is large: its 130 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 110 lines aren’t shown here.
This diff is large: its 65 lines aren’t shown here.
This diff is large: its 139 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 85 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 66 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 477 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 58 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 125 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 93 lines aren’t shown here.
This diff is large: its 146 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 177 lines aren’t shown here.
This diff is large: its 255 lines aren’t shown here.
This diff is large: its 1272 lines aren’t shown here.
This diff is large: its 43 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 302 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 74 lines aren’t shown here.
This diff is large: its 1371 lines aren’t shown here.
This diff is large: its 41 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 161 lines aren’t shown here.
This diff is large: its 51 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 161 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 78 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 165 lines aren’t shown here.
This diff is large: its 343 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 102 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.
This diff is large: its 255 lines aren’t shown here.
This diff is large: its 60 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 124 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 97 lines aren’t shown here.
This diff is large: its 134 lines aren’t shown here.
This diff is large: its 67 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 205 lines aren’t shown here.
This diff is large: its 55 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 49 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 48 lines aren’t shown here.
This diff is large: its 129 lines aren’t shown here.
This diff is large: its 39 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 178 lines aren’t shown here.
This diff is large: its 425 lines aren’t shown here.
This diff is large: its 43 lines aren’t shown here.
This diff is large: its 105 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 307 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 47 lines aren’t shown here.
This diff is large: its 255 lines aren’t shown here.
This diff is large: its 41 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 265 lines aren’t shown here.
This diff is large: its 69 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 80 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 61 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 62 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.
This diff is large: its 243 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 39 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 601 lines aren’t shown here.
This diff is large: its 146 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 45 lines aren’t shown here.
This diff is large: its 215 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 60 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 208 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 68 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 140 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 5 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 140 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 45 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 64 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 749 lines aren’t shown here.
This diff is large: its 81 lines aren’t shown here.
This diff is large: its 79 lines aren’t shown here.
This diff is large: its 46 lines aren’t shown here.
This diff is large: its 86 lines aren’t shown here.
This diff is large: its 52 lines aren’t shown here.
This diff is large: its 96 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 129 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 331 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 216 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 55 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 405 lines aren’t shown here.
This diff is large: its 1933 lines aren’t shown here.
This diff is large: its 832 lines aren’t shown here.
This diff is large: its 55 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 1129 lines aren’t shown here.
This diff is large: its 192 lines aren’t shown here.
This diff is large: its 1454 lines aren’t shown here.
This diff is large: its 186 lines aren’t shown here.
This diff is large: its 98 lines aren’t shown here.
This diff is large: its 518 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 987 lines aren’t shown here.
This diff is large: its 53 lines aren’t shown here.
This diff is large: its 90 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.
This diff is large: its 369 lines aren’t shown here.
This diff is large: its 1706 lines aren’t shown here.
This diff is large: its 302 lines aren’t shown here.
This diff is large: its 88 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 60 lines aren’t shown here.
This diff is large: its 824 lines aren’t shown here.
This diff is large: its 60 lines aren’t shown here.
This diff is large: its 142 lines aren’t shown here.
This diff is large: its 6 lines aren’t shown here.
This diff is large: its 149 lines aren’t shown here.
This diff is large: its 218 lines aren’t shown here.
This diff is large: its 45 lines aren’t shown here.
This diff is large: its 58 lines aren’t shown here.
This diff is large: its 45 lines aren’t shown here.
This diff is large: its 74 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 604 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 54 lines aren’t shown here.
This diff is large: its 158 lines aren’t shown here.
This diff is large: its 288 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 347 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 49 lines aren’t shown here.
This diff is large: its 572 lines aren’t shown here.
This diff is large: its 42 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 6 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 191 lines aren’t shown here.
This diff is large: its 84 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 47 lines aren’t shown here.
This diff is large: its 42 lines aren’t shown here.
This diff is large: its 78 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 424 lines aren’t shown here.
This diff is large: its 85 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.
This diff is large: its 41 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 49 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 421 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 193 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 207 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 91 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 287 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 130 lines aren’t shown here.
This diff is large: its 189 lines aren’t shown here.
This diff is large: its 79 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 297 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 54 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 480 lines aren’t shown here.
This diff is large: its 78 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 48 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 105 lines aren’t shown here.
This diff is large: its 52 lines aren’t shown here.
This diff is large: its 178 lines aren’t shown here.
This diff is large: its 84 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 271 lines aren’t shown here.
This diff is large: its 57 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 78 lines aren’t shown here.
This diff is large: its 59 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 490 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 141 lines aren’t shown here.
This diff is large: its 59 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 206 lines aren’t shown here.
This diff is large: its 297 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 139 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 269 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 96 lines aren’t shown here.
This diff is large: its 91 lines aren’t shown here.
This diff is large: its 53 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 5 lines aren’t shown here.
This diff is large: its 132 lines aren’t shown here.
This diff is large: its 51 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 80 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 601 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 225 lines aren’t shown here.
This diff is large: its 106 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 322 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 55 lines aren’t shown here.
This diff is large: its 751 lines aren’t shown here.
This diff is large: its 117 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 103 lines aren’t shown here.
This diff is large: its 294 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 240 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 75 lines aren’t shown here.
This diff is large: its 374 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 50 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 449 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 59 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 136 lines aren’t shown here.
This diff is large: its 294 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 50 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 57 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 41 lines aren’t shown here.
This diff is large: its 109 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 96 lines aren’t shown here.
This diff is large: its 287 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 277 lines aren’t shown here.
This diff is large: its 110 lines aren’t shown here.
This diff is large: its 53 lines aren’t shown here.
This diff is large: its 39 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 147 lines aren’t shown here.
This diff is large: its 344 lines aren’t shown here.
This diff is large: its 88 lines aren’t shown here.
This diff is large: its 101 lines aren’t shown here.
This diff is large: its 163 lines aren’t shown here.
This diff is large: its 123 lines aren’t shown here.
This diff is large: its 95 lines aren’t shown here.
This diff is large: its 104 lines aren’t shown here.
This diff is large: its 66 lines aren’t shown here.
This diff is large: its 139 lines aren’t shown here.
This diff is large: its 94 lines aren’t shown here.
This diff is large: its 50 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 60 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 184 lines aren’t shown here.
This diff is large: its 83 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 6 lines aren’t shown here.
This diff is large: its 67 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 123 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 207 lines aren’t shown here.
This diff is large: its 51 lines aren’t shown here.
This diff is large: its 160 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 52 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 101 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 1184 lines aren’t shown here.
This diff is large: its 119 lines aren’t shown here.
This diff is large: its 50 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 61 lines aren’t shown here.
This diff is large: its 253 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 635 lines aren’t shown here.
This diff is large: its 209 lines aren’t shown here.
This diff is large: its 66 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.
This diff is large: its 1082 lines aren’t shown here.
This diff is large: its 73 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 132 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 66 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 95 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 542 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 556 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 112 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 76 lines aren’t shown here.
This diff is large: its 120 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 156 lines aren’t shown here.
This diff is large: its 97 lines aren’t shown here.
This diff is large: its 174 lines aren’t shown here.
This diff is large: its 80 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 231 lines aren’t shown here.